//4 feature darkplaces csqc: add builtins to clientside qc for gl calls
sfx_t *S_FindName(const char *name);
-int Sbar_GetPlayer (int index);
+int Sbar_GetSortedPlayerIndex (int index);
void Sbar_SortFrags (void);
void CL_FindNonSolidLocation(const vec3_t in, vec3_t out, vec_t radius);
void CSQC_RelinkAllEntities (int drawmask);
CL_LinkEdict(e);
}
+static void SetMinMaxSize (prvm_edict_t *e, float *min, float *max)
+{
+ int i;
+
+ for (i=0 ; i<3 ; i++)
+ if (min[i] > max[i])
+ PRVM_ERROR("SetMinMaxSize: backwards mins/maxs");
+
+ // set derived values
+ VectorCopy (min, e->fields.client->mins);
+ VectorCopy (max, e->fields.client->maxs);
+ VectorSubtract (max, min, e->fields.client->size);
+
+ CL_LinkEdict (e);
+}
+
// #3 void(entity e, string m) setmodel
void VM_CL_setmodel (void)
{
prvm_edict_t *e;
const char *m;
- struct model_s *mod;
+ model_t *mod;
int i;
VM_SAFEPARMCOUNT(2, VM_CL_setmodel);
e = PRVM_G_EDICT(OFS_PARM0);
+ e->fields.client->modelindex = 0;
+ e->fields.client->model = 0;
+
m = PRVM_G_STRING(OFS_PARM1);
+ mod = NULL;
for (i = 0;i < MAX_MODELS && cl.csqc_model_precache[i];i++)
{
if (!strcmp(cl.csqc_model_precache[i]->name, m))
{
- e->fields.client->model = PRVM_SetEngineString(cl.csqc_model_precache[i]->name);
+ mod = cl.csqc_model_precache[i];
+ e->fields.client->model = PRVM_SetEngineString(mod->name);
e->fields.client->modelindex = -(i+1);
- return;
+ break;
}
}
- for (i = 0;i < MAX_MODELS;i++)
- {
- mod = cl.model_precache[i];
- if (mod && !strcmp(mod->name, m))
+ if( !mod ) {
+ for (i = 0;i < MAX_MODELS;i++)
{
- e->fields.client->model = PRVM_SetEngineString(mod->name);
- e->fields.client->modelindex = i;
- return;
+ mod = cl.model_precache[i];
+ if (mod && !strcmp(mod->name, m))
+ {
+ e->fields.client->model = PRVM_SetEngineString(mod->name);
+ e->fields.client->modelindex = i;
+ break;
+ }
}
}
- e->fields.client->modelindex = 0;
- e->fields.client->model = 0;
- VM_Warning ("setmodel: model '%s' not precached\n", m);
+ if( mod ) {
+ // TODO: check if this breaks needed consistency and maybe add a cvar for it too?? [1/10/2008 Black]
+ //SetMinMaxSize (e, mod->normalmins, mod->normalmaxs);
+ }
+ else
+ {
+ SetMinMaxSize (e, vec3_origin, vec3_origin);
+ VM_Warning ("setmodel: model '%s' not precached\n", m);
+ }
}
// #4 void(entity e, vector min, vector max) setsize
min = PRVM_G_VECTOR(OFS_PARM1);
max = PRVM_G_VECTOR(OFS_PARM2);
- VectorCopy (min, e->fields.client->mins);
- VectorCopy (max, e->fields.client->maxs);
- VectorSubtract (max, min, e->fields.client->size);
+ SetMinMaxSize( e, min, max );
CL_LinkEdict(e);
}
{
prvm_edict_t *ed;
ed = PRVM_ED_Alloc();
- // FIXME: WTF.. this should be removed imo.. entnum points to the server.. [12/17/2007 Black]
- ed->fields.client->entnum = PRVM_NUM_FOR_EDICT(ed); //[515]: not needed any more ?
VM_RETURN_EDICT(ed);
}
r_refdef.view.frustum_y *= r_refdef.frustumscale_y;
r_refdef.view.ortho_x = scr_fov.value * (3.0 / 4.0) * (float)r_refdef.view.width / (float)r_refdef.view.height / vid_pixelheight.value;
r_refdef.view.ortho_y = scr_fov.value * (3.0 / 4.0);
+ r_refdef.view.clear = true;
+ r_refdef.view.isoverlay = false;
// FIXME: restore cl.csqc_origin
// FIXME: restore cl.csqc_angles
cl.csqc_vidvars.drawworld = true;
r_refdef.view.width = (int)(f[0] * vid.width / vid_conwidth.value);
r_refdef.view.height = (int)(f[1] * vid.height / vid_conheight.value);
break;
- case VF_SIZE_Y:
+ case VF_SIZE_X:
r_refdef.view.width = (int)(k * vid.width / vid_conwidth.value);
break;
- case VF_SIZE_X:
+ case VF_SIZE_Y:
r_refdef.view.height = (int)(k * vid.height / vid_conheight.value);
break;
case VF_VIEWPORT:
case VF_PERSPECTIVE:
r_refdef.view.useperspective = k != 0;
break;
+ case VF_CLEARSCREEN:
+ r_refdef.view.isoverlay = !k;
+ break;
default:
PRVM_G_FLOAT(OFS_RETURN) = 0;
VM_Warning("VM_CL_R_SetView : unknown parm %i\n", c);
PRVM_G_FLOAT(OFS_RETURN) = 1;
}
-//#304 void() renderscene (EXT_CSQC)
-void VM_CL_R_RenderScene (void)
-{
- VM_SAFEPARMCOUNT(0, VM_CL_R_RenderScene);
- // we need to update any RENDER_VIEWMODEL entities at this point because
- // csqc supplies its own view matrix
- CL_UpdateViewEntities();
- // now draw stuff!
- R_RenderView();
-}
-
-//#305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
+//#305 void(vector org, float radius, vector lightcolours[, float style, string cubemapname, float pflags]) adddynamiclight (EXT_CSQC)
void VM_CL_R_AddDynamicLight (void)
{
- float *pos, *col;
- matrix4x4_t matrix;
- VM_SAFEPARMCOUNTRANGE(3, 3, VM_CL_R_AddDynamicLight);
+ vec_t *org;
+ float radius = 300;
+ vec_t *col;
+ int style = -1;
+ const char *cubemapname = NULL;
+ int pflags = PFLAGS_CORONA | PFLAGS_FULLDYNAMIC;
+ float coronaintensity = 1;
+ float coronasizescale = 0.25;
+ qboolean castshadow = true;
+ float ambientscale = 0;
+ float diffusescale = 1;
+ float specularscale = 1;
+ matrix4x4_t matrix;
+ vec3_t forward, left, up;
+ VM_SAFEPARMCOUNTRANGE(3, 8, VM_CL_R_AddDynamicLight);
// if we've run out of dlights, just return
if (r_refdef.scene.numlights >= MAX_DLIGHTS)
return;
- pos = PRVM_G_VECTOR(OFS_PARM0);
+ org = PRVM_G_VECTOR(OFS_PARM0);
+ radius = PRVM_G_FLOAT(OFS_PARM1);
col = PRVM_G_VECTOR(OFS_PARM2);
- Matrix4x4_CreateFromQuakeEntity(&matrix, pos[0], pos[1], pos[2], 0, 0, 0, PRVM_G_FLOAT(OFS_PARM1));
- R_RTLight_Update(&r_refdef.scene.lights[r_refdef.scene.numlights++], false, &matrix, col, -1, NULL, true, 1, 0.25, 0, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
+ if (prog->argc >= 4)
+ {
+ style = (int)PRVM_G_FLOAT(OFS_PARM3);
+ if (style >= MAX_LIGHTSTYLES)
+ {
+ Con_DPrintf("VM_CL_R_AddDynamicLight: out of bounds lightstyle index %i\n", style);
+ style = -1;
+ }
+ }
+ if (prog->argc >= 5)
+ cubemapname = PRVM_G_STRING(OFS_PARM4);
+ if (prog->argc >= 6)
+ pflags = (int)PRVM_G_FLOAT(OFS_PARM5);
+ coronaintensity = (pflags & PFLAGS_CORONA) != 0;
+ castshadow = (pflags & PFLAGS_NOSHADOW) == 0;
+
+ VectorScale(prog->globals.client->v_forward, radius, forward);
+ VectorScale(prog->globals.client->v_right, -radius, left);
+ VectorScale(prog->globals.client->v_up, radius, up);
+ Matrix4x4_FromVectors(&matrix, forward, left, up, org);
+
+ R_RTLight_Update(&r_refdef.scene.lights[r_refdef.scene.numlights++], false, &matrix, col, style, cubemapname, castshadow, coronaintensity, coronasizescale, ambientscale, diffusescale, specularscale, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
}
//============================================================================
}
t->fields.client->model = PRVM_SetEngineString(model->name);
t->fields.client->modelindex = i;
+
+ // TODO: check if this breaks needed consistency and maybe add a cvar for it too?? [1/10/2008 Black]
+ if (model)
+ {
+ SetMinMaxSize (t, model->normalmins, model->normalmaxs);
+ }
+ else
+ SetMinMaxSize (t, vec3_origin, vec3_origin);
}
//#334 string(float mdlindex) modelnameforindex (EXT_CSQC)
int i, frame;
VM_SAFEPARMCOUNT(1, VM_CL_getinputstate);
frame = (int)PRVM_G_FLOAT(OFS_PARM0);
- for (i = 0;i < cl.movement_numqueue;i++)
- if (cl.movement_queue[i].sequence == frame)
+ for (i = 0;i < CL_MAX_USERCMDS;i++)
+ {
+ if (cl.movecmd[i].sequence == frame)
{
- VectorCopy(cl.movement_queue[i].viewangles, prog->globals.client->input_angles);
- //prog->globals.client->input_buttons = cl.movement_queue[i].//FIXME
- VectorCopy(cl.movement_queue[i].move, prog->globals.client->input_movevalues);
- prog->globals.client->input_timelength = cl.movement_queue[i].frametime;
- if(cl.movement_queue[i].crouch)
+ VectorCopy(cl.movecmd[i].viewangles, prog->globals.client->input_angles);
+ prog->globals.client->input_buttons = cl.movecmd[i].buttons; // FIXME: this should not be directly exposed to csqc (translation layer needed?)
+ prog->globals.client->input_movevalues[0] = cl.movecmd[i].forwardmove;
+ prog->globals.client->input_movevalues[1] = cl.movecmd[i].sidemove;
+ prog->globals.client->input_movevalues[2] = cl.movecmd[i].upmove;
+ prog->globals.client->input_timelength = cl.movecmd[i].frametime;
+ if(cl.movecmd[i].crouch)
{
VectorCopy(cl.playercrouchmins, prog->globals.client->pmove_mins);
VectorCopy(cl.playercrouchmaxs, prog->globals.client->pmove_maxs);
VectorCopy(cl.playerstandmaxs, prog->globals.client->pmove_maxs);
}
}
+ }
}
//#346 void(float sens) setsensitivityscaler (EXT_CSQC)
PRVM_G_INT(OFS_RETURN) = OFS_NULL;
Sbar_SortFrags();
- i = Sbar_GetPlayer(i);
- if(i < 0)
+ if (i < 0)
+ i = Sbar_GetSortedPlayerIndex(-1-i);
+ if(i < 0 || i >= cl.maxclients)
return;
t[0] = 0;
//PF_getsurfacepointattribute, // #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
// float SPA_POSITION = 0;
// float SPA_S_AXIS = 1;
-// float SPA_R_AXIS = 2;
-// float SPA_T_AXIS = 3; // same as SPA_NORMAL
+// float SPA_T_AXIS = 2;
+// float SPA_R_AXIS = 3; // same as SPA_NORMAL
// float SPA_TEXCOORDS0 = 4;
// float SPA_LIGHTMAP0_TEXCOORDS = 5;
// float SPA_LIGHTMAP0_COLOR = 6;
int pointnum;
int attributetype;
- VM_SAFEPARMCOUNT(3, VM_CL_getsurfacenumpoints);
+ VM_SAFEPARMCOUNT(4, VM_CL_getsurfacenumpoints);
VectorClear(PRVM_G_VECTOR(OFS_RETURN));
ed = PRVM_G_EDICT(OFS_PARM0);
if (!(model = CL_GetModelFromEdict(ed)) || !(surface = cl_getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
switch( attributetype ) {
// float SPA_POSITION = 0;
case 0:
- VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.server->origin, PRVM_G_VECTOR(OFS_RETURN));
+ VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.client->origin, PRVM_G_VECTOR(OFS_RETURN));
break;
// float SPA_S_AXIS = 1;
case 1:
VectorCopy(&(model->surfmesh.data_svector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
break;
- // float SPA_R_AXIS = 2;
+ // float SPA_T_AXIS = 2;
case 2:
VectorCopy(&(model->surfmesh.data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
break;
- // float SPA_T_AXIS = 3; // same as SPA_NORMAL
+ // float SPA_R_AXIS = 3; // same as SPA_NORMAL
case 3:
VectorCopy(&(model->surfmesh.data_normal3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN));
break;
// float SPA_LIGHTMAP0_COLOR = 6;
case 6:
// ignore alpha for now..
- VectorCopy( &(model->surfmesh.data_normal3f + 4 * surface->num_firstvertex)[pointnum * 4], PRVM_G_VECTOR(OFS_RETURN));
+ VectorCopy( &(model->surfmesh.data_lightmapcolor4f + 4 * surface->num_firstvertex)[pointnum * 4], PRVM_G_VECTOR(OFS_RETURN));
break;
default:
VectorSet( PRVM_G_VECTOR(OFS_RETURN), 0.0f, 0.0f, 0.0f );
}
// #443 void(entity e, entity tagentity, string tagname) setattachment
-static void VM_CL_setattachment (void)
+void VM_CL_setattachment (void)
{
prvm_edict_t *e;
prvm_edict_t *tagentity;
}
// #451 float(entity ent, string tagname) gettagindex (DP_QC_GETTAGINFO)
-static void VM_CL_gettagindex (void)
+void VM_CL_gettagindex (void)
{
prvm_edict_t *ent;
const char *tag_name;
}
// #452 vector(entity ent, float tagindex) gettaginfo (DP_QC_GETTAGINFO)
-static void VM_CL_gettaginfo (void)
+void VM_CL_gettaginfo (void)
{
prvm_edict_t *e;
int tagindex;
//QC POLYGON functions
//====================
-typedef struct
+#define VMPOLYGONS_MAXPOINTS 64
+
+typedef struct vmpolygons_triangle_s
{
- rtexture_t *tex;
- float data[36]; //[515]: enough for polygons
- unsigned char flags; //[515]: + VM_POLYGON_2D and VM_POLYGON_FL4V flags
-}vm_polygon_t;
+ rtexture_t *texture;
+ int drawflag;
+ int element3i[3];
+}vmpolygons_triangle_t;
typedef struct vmpolygons_s
{
- //static float vm_polygon_linewidth = 1;
mempool_t *pool;
- unsigned char current_vertices;
qboolean initialized;
- vm_polygon_t *polygons;
- unsigned long polygons_num, drawpolygons_num; //[515]: ok long on 64bit ?
- qboolean polygonbegin; //[515]: for "no-crap-on-the-screen" check
+
+ int max_vertices;
+ int num_vertices;
+ float *data_vertex3f;
+ float *data_color4f;
+ float *data_texcoord2f;
+
+ int max_triangles;
+ int num_triangles;
+ vmpolygons_triangle_t *data_triangles;
+ int *data_sortedelement3i;
+
+ qboolean begin_active;
+ rtexture_t *begin_texture;
+ int begin_drawflag;
+ int begin_vertices;
+ float begin_vertex[VMPOLYGONS_MAXPOINTS][3];
+ float begin_color[VMPOLYGONS_MAXPOINTS][4];
+ float begin_texcoord[VMPOLYGONS_MAXPOINTS][2];
} vmpolygons_t;
+
+// FIXME: make VM_CL_R_Polygon functions use Debug_Polygon functions?
vmpolygons_t vmpolygons[PRVM_MAXPROGS];
-#define VM_DEFPOLYNUM 64 //[515]: enough for default ?
-#define VM_POLYGON_FL3V 16 //more than 2 vertices (used only for lines)
-#define VM_POLYGON_FLLINES 32
-#define VM_POLYGON_FL2D 64
-#define VM_POLYGON_FL4V 128 //4 vertices
+//#304 void() renderscene (EXT_CSQC)
+// moved that here to reset the polygons,
+// resetting them earlier causes R_Mesh_Draw to be called with numvertices = 0
+// --blub
+void VM_CL_R_RenderScene (void)
+{
+ vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
+ VM_SAFEPARMCOUNT(0, VM_CL_R_RenderScene);
+ // we need to update any RENDER_VIEWMODEL entities at this point because
+ // csqc supplies its own view matrix
+ CL_UpdateViewEntities();
+ // now draw stuff!
+ R_RenderView();
+
+ polys->num_vertices = polys->num_triangles = 0;
+}
+
+static void VM_ResizePolygons(vmpolygons_t *polys)
+{
+ float *oldvertex3f = polys->data_vertex3f;
+ float *oldcolor4f = polys->data_color4f;
+ float *oldtexcoord2f = polys->data_texcoord2f;
+ vmpolygons_triangle_t *oldtriangles = polys->data_triangles;
+ int *oldsortedelement3i = polys->data_sortedelement3i;
+ polys->max_vertices = polys->max_triangles*3;
+ polys->data_vertex3f = (float *)Mem_Alloc(polys->pool, polys->max_vertices*sizeof(float[3]));
+ polys->data_color4f = (float *)Mem_Alloc(polys->pool, polys->max_vertices*sizeof(float[4]));
+ polys->data_texcoord2f = (float *)Mem_Alloc(polys->pool, polys->max_vertices*sizeof(float[2]));
+ polys->data_triangles = (vmpolygons_triangle_t *)Mem_Alloc(polys->pool, polys->max_triangles*sizeof(vmpolygons_triangle_t));
+ polys->data_sortedelement3i = (int *)Mem_Alloc(polys->pool, polys->max_triangles*sizeof(int[3]));
+ if (polys->num_vertices)
+ {
+ memcpy(polys->data_vertex3f, oldvertex3f, polys->num_vertices*sizeof(float[3]));
+ memcpy(polys->data_color4f, oldcolor4f, polys->num_vertices*sizeof(float[4]));
+ memcpy(polys->data_texcoord2f, oldtexcoord2f, polys->num_vertices*sizeof(float[2]));
+ }
+ if (polys->num_triangles)
+ {
+ memcpy(polys->data_triangles, oldtriangles, polys->num_triangles*sizeof(vmpolygons_triangle_t));
+ memcpy(polys->data_sortedelement3i, oldsortedelement3i, polys->num_triangles*sizeof(int[3]));
+ }
+ if (oldvertex3f)
+ Mem_Free(oldvertex3f);
+ if (oldcolor4f)
+ Mem_Free(oldcolor4f);
+ if (oldtexcoord2f)
+ Mem_Free(oldtexcoord2f);
+ if (oldtriangles)
+ Mem_Free(oldtriangles);
+ if (oldsortedelement3i)
+ Mem_Free(oldsortedelement3i);
+}
static void VM_InitPolygons (vmpolygons_t* polys)
{
+ memset(polys, 0, sizeof(*polys));
polys->pool = Mem_AllocPool("VMPOLY", 0, NULL);
- polys->polygons = (vm_polygon_t *)Mem_Alloc(polys->pool, VM_DEFPOLYNUM*sizeof(vm_polygon_t));
- memset(polys->polygons, 0, VM_DEFPOLYNUM*sizeof(vm_polygon_t));
- polys->polygons_num = VM_DEFPOLYNUM;
- polys->drawpolygons_num = 0;
- polys->polygonbegin = false;
+ polys->max_triangles = 1024;
+ VM_ResizePolygons(polys);
polys->initialized = true;
}
{
int surfacelistindex;
vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
-
- // LordHavoc: FIXME: this is stupid code
- for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++)
- {
- const vm_polygon_t *p = &polys->polygons[surfacelist[surfacelistindex]];
- int flags = p->flags & 0x0f;
-
- if(flags == DRAWFLAG_ADDITIVE)
+ R_Mesh_Matrix(&identitymatrix);
+ GL_CullFace(GL_NONE);
+ R_Mesh_VertexPointer(polys->data_vertex3f, 0, 0);
+ R_Mesh_ColorPointer(polys->data_color4f, 0, 0);
+ R_Mesh_TexCoordPointer(0, 2, polys->data_texcoord2f, 0, 0);
+ R_SetupGenericShader(true);
+ for (surfacelistindex = 0;surfacelistindex < numsurfaces;)
+ {
+ int numtriangles = 0;
+ rtexture_t *tex = polys->data_triangles[surfacelist[surfacelistindex]].texture;
+ int drawflag = polys->data_triangles[surfacelist[surfacelistindex]].drawflag;
+ if(drawflag == DRAWFLAG_ADDITIVE)
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
- else if(flags == DRAWFLAG_MODULATE)
+ else if(drawflag == DRAWFLAG_MODULATE)
GL_BlendFunc(GL_DST_COLOR, GL_ZERO);
- else if(flags == DRAWFLAG_2XMODULATE)
+ else if(drawflag == DRAWFLAG_2XMODULATE)
GL_BlendFunc(GL_DST_COLOR,GL_SRC_COLOR);
else
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- R_Mesh_TexBind(0, R_GetTexture(p->tex));
-
- CHECKGLERROR
- //[515]: is speed is max ?
- if(p->flags & VM_POLYGON_FLLINES) //[515]: lines
+ R_Mesh_TexBind(0, R_GetTexture(tex));
+ numtriangles = 0;
+ for (;surfacelistindex < numsurfaces;surfacelistindex++)
{
- qglLineWidth(p->data[13]);CHECKGLERROR
- qglBegin(GL_LINE_LOOP);
- qglTexCoord1f (p->data[12]);
- qglColor4f (p->data[20], p->data[21], p->data[22], p->data[23]);
- qglVertex3f (p->data[0] , p->data[1], p->data[2]);
-
- qglTexCoord1f (p->data[14]);
- qglColor4f (p->data[24], p->data[25], p->data[26], p->data[27]);
- qglVertex3f (p->data[3] , p->data[4], p->data[5]);
-
- if(p->flags & VM_POLYGON_FL3V)
- {
- qglTexCoord1f (p->data[16]);
- qglColor4f (p->data[28], p->data[29], p->data[30], p->data[31]);
- qglVertex3f (p->data[6] , p->data[7], p->data[8]);
-
- if(p->flags & VM_POLYGON_FL4V)
- {
- qglTexCoord1f (p->data[18]);
- qglColor4f (p->data[32], p->data[33], p->data[34], p->data[35]);
- qglVertex3f (p->data[9] , p->data[10], p->data[11]);
- }
- }
- qglEnd();
- CHECKGLERROR
- }
- else
- {
- qglBegin(GL_POLYGON);
- qglTexCoord2f (p->data[12], p->data[13]);
- qglColor4f (p->data[20], p->data[21], p->data[22], p->data[23]);
- qglVertex3f (p->data[0] , p->data[1], p->data[2]);
-
- qglTexCoord2f (p->data[14], p->data[15]);
- qglColor4f (p->data[24], p->data[25], p->data[26], p->data[27]);
- qglVertex3f (p->data[3] , p->data[4], p->data[5]);
-
- qglTexCoord2f (p->data[16], p->data[17]);
- qglColor4f (p->data[28], p->data[29], p->data[30], p->data[31]);
- qglVertex3f (p->data[6] , p->data[7], p->data[8]);
-
- if(p->flags & VM_POLYGON_FL4V)
- {
- qglTexCoord2f (p->data[18], p->data[19]);
- qglColor4f (p->data[32], p->data[33], p->data[34], p->data[35]);
- qglVertex3f (p->data[9] , p->data[10], p->data[11]);
- }
- qglEnd();
- CHECKGLERROR
+ if (polys->data_triangles[surfacelist[surfacelistindex]].texture != tex || polys->data_triangles[surfacelist[surfacelistindex]].drawflag != drawflag)
+ break;
+ VectorCopy(polys->data_triangles[surfacelist[surfacelistindex]].element3i, polys->data_sortedelement3i + 3*numtriangles);
+ numtriangles++;
}
+ R_Mesh_Draw(0, polys->num_vertices, numtriangles, polys->data_sortedelement3i, 0, 0);
}
}
-static void VM_CL_AddPolygonTo2DScene (vm_polygon_t *p)
+void VMPolygons_Store(vmpolygons_t *polys)
{
- drawqueuemesh_t mesh;
- static int picelements[6] = {0, 1, 2, 0, 2, 3};
- mesh.texture = p->tex;
- mesh.data_element3i = picelements;
- mesh.data_vertex3f = p->data;
- mesh.data_texcoord2f = p->data + 12;
- mesh.data_color4f = p->data + 20;
- if(p->flags & VM_POLYGON_FL4V)
+ if (r_refdef.draw2dstage)
{
- mesh.num_vertices = 4;
- mesh.num_triangles = 2;
+ // draw the polygon as 2D immediately
+ drawqueuemesh_t mesh;
+ mesh.texture = polys->begin_texture;
+ mesh.num_vertices = polys->begin_vertices;
+ mesh.num_triangles = polys->begin_vertices-2;
+ mesh.data_element3i = polygonelements;
+ mesh.data_vertex3f = polys->begin_vertex[0];
+ mesh.data_color4f = polys->begin_color[0];
+ mesh.data_texcoord2f = polys->begin_texcoord[0];
+ DrawQ_Mesh(&mesh, polys->begin_drawflag);
}
else
{
- mesh.num_vertices = 3;
- mesh.num_triangles = 1;
+ // queue the polygon as 3D for sorted transparent rendering later
+ int i;
+ if (polys->max_triangles < polys->num_triangles + polys->begin_vertices-2)
+ {
+ polys->max_triangles *= 2;
+ VM_ResizePolygons(polys);
+ }
+ // needle in a haystack!
+ // polys->num_vertices was used for copying where we actually want to copy begin_vertices
+ // that also caused it to not render the first polygon that is added
+ // --blub
+ memcpy(polys->data_vertex3f + polys->num_vertices * 3, polys->begin_vertex[0], polys->begin_vertices * sizeof(float[3]));
+ memcpy(polys->data_color4f + polys->num_vertices * 4, polys->begin_color[0], polys->begin_vertices * sizeof(float[4]));
+ memcpy(polys->data_texcoord2f + polys->num_vertices * 2, polys->begin_texcoord[0], polys->begin_vertices * sizeof(float[2]));
+ for (i = 0;i < polys->begin_vertices-2;i++)
+ {
+ polys->data_triangles[polys->num_triangles].texture = polys->begin_texture;
+ polys->data_triangles[polys->num_triangles].drawflag = polys->begin_drawflag;
+ polys->data_triangles[polys->num_triangles].element3i[0] = polys->num_vertices;
+ polys->data_triangles[polys->num_triangles].element3i[1] = polys->num_vertices + i+1;
+ polys->data_triangles[polys->num_triangles].element3i[2] = polys->num_vertices + i+2;
+ polys->num_triangles++;
+ }
+ polys->num_vertices += polys->begin_vertices;
}
- if(p->flags & VM_POLYGON_FLLINES) //[515]: lines
- DrawQ_LineLoop (&mesh, (p->flags&0x0f));
- else
- DrawQ_Mesh (&mesh, (p->flags&0x0f));
+ polys->begin_active = false;
}
// TODO: move this into the client code and clean-up everything else, too! [1/6/2008 Black]
+// LordHavoc: agreed, this is a mess
void VM_CL_AddPolygonsToMeshQueue (void)
{
int i;
vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
+ vec3_t center;
// only add polygons of the currently active prog to the queue - if there is none, we're done
if( !prog )
return;
- if(!polys->drawpolygons_num)
+ if (!polys->num_triangles)
return;
- R_Mesh_Matrix(&identitymatrix);
- GL_CullFace(GL_NONE);
- for(i = 0;i < (int)polys->drawpolygons_num;i++)
- VM_DrawPolygonCallback(NULL, NULL, 1, &i);
- polys->drawpolygons_num = 0;
+
+ for (i = 0;i < polys->num_triangles;i++)
+ {
+ VectorMAMAM(1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].element3i[0], 1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].element3i[1], 1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].element3i[2], center);
+ R_MeshQueue_AddTransparent(center, VM_DrawPolygonCallback, NULL, i, NULL);
+ }
+
+ /*polys->num_triangles = 0; // now done after rendering the scene,
+ polys->num_vertices = 0; // otherwise it's not rendered at all and prints an error message --blub */
}
-//void(string texturename, float flag[, float 2d[, float lines]]) R_BeginPolygon
+//void(string texturename, float flag) R_BeginPolygon
void VM_CL_R_PolygonBegin (void)
{
- vm_polygon_t *p;
const char *picname;
vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
- VM_SAFEPARMCOUNTRANGE(2, 4, VM_CL_R_PolygonBegin);
+ VM_SAFEPARMCOUNT(2, VM_CL_R_PolygonBegin);
- if(!polys->initialized)
+ if (!polys->initialized)
VM_InitPolygons(polys);
- if(polys->polygonbegin)
+ if (polys->begin_active)
{
- VM_Warning("VM_CL_R_PolygonBegin: called twice without VM_CL_R_PolygonEnd after first\n");
+ VM_Warning("VM_CL_R_PolygonBegin: called twice without VM_CL_R_PolygonBegin after first\n");
return;
}
- if(polys->drawpolygons_num >= polys->polygons_num)
- {
- p = (vm_polygon_t *)Mem_Alloc(polys->pool, 2 * polys->polygons_num * sizeof(vm_polygon_t));
- memset(p, 0, 2 * polys->polygons_num * sizeof(vm_polygon_t));
- memcpy(p, polys->polygons, polys->polygons_num * sizeof(vm_polygon_t));
- Mem_Free(polys->polygons);
- polys->polygons = p;
- polys->polygons_num *= 2;
- }
- p = &polys->polygons[polys->drawpolygons_num];
picname = PRVM_G_STRING(OFS_PARM0);
- if(picname[0])
- p->tex = Draw_CachePic(picname, true)->tex;
- else
- p->tex = r_texture_white;
- p->flags = (unsigned char)PRVM_G_FLOAT(OFS_PARM1);
- polys->current_vertices = 0;
- polys->polygonbegin = true;
- if(prog->argc >= 3)
- {
- if(PRVM_G_FLOAT(OFS_PARM2))
- p->flags |= VM_POLYGON_FL2D;
- if(prog->argc >= 4 && PRVM_G_FLOAT(OFS_PARM3))
- {
- p->data[13] = PRVM_G_FLOAT(OFS_PARM3); //[515]: linewidth
- p->flags |= VM_POLYGON_FLLINES;
- }
- }
+ polys->begin_texture = picname[0] ? Draw_CachePic (picname)->tex : r_texture_white;
+ polys->begin_drawflag = (int)PRVM_G_FLOAT(OFS_PARM1);
+ polys->begin_vertices = 0;
+ polys->begin_active = true;
}
//void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
void VM_CL_R_PolygonVertex (void)
{
- float *coords, *tx, *rgb, alpha;
- vm_polygon_t *p;
vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
VM_SAFEPARMCOUNT(4, VM_CL_R_PolygonVertex);
- if(!polys->polygonbegin)
+ if (!polys->begin_active)
{
VM_Warning("VM_CL_R_PolygonVertex: VM_CL_R_PolygonBegin wasn't called\n");
return;
}
- coords = PRVM_G_VECTOR(OFS_PARM0);
- tx = PRVM_G_VECTOR(OFS_PARM1);
- rgb = PRVM_G_VECTOR(OFS_PARM2);
- alpha = PRVM_G_FLOAT(OFS_PARM3);
- p = &polys->polygons[polys->drawpolygons_num];
- if(polys->current_vertices > 4)
+ if (polys->begin_vertices >= VMPOLYGONS_MAXPOINTS)
{
- VM_Warning("VM_CL_R_PolygonVertex: may have 4 vertices max\n");
+ VM_Warning("VM_CL_R_PolygonVertex: may have %i vertices max\n", VMPOLYGONS_MAXPOINTS);
return;
}
- p->data[polys->current_vertices*3] = coords[0];
- p->data[1+polys->current_vertices*3] = coords[1];
- p->data[2+polys->current_vertices*3] = coords[2];
-
- p->data[12+polys->current_vertices*2] = tx[0];
- if(!(p->flags & VM_POLYGON_FLLINES))
- p->data[13+polys->current_vertices*2] = tx[1];
-
- p->data[20+polys->current_vertices*4] = rgb[0];
- p->data[21+polys->current_vertices*4] = rgb[1];
- p->data[22+polys->current_vertices*4] = rgb[2];
- p->data[23+polys->current_vertices*4] = alpha;
-
- polys->current_vertices++;
- if(polys->current_vertices == 4)
- p->flags |= VM_POLYGON_FL4V;
- else
- if(polys->current_vertices == 3)
- p->flags |= VM_POLYGON_FL3V;
+ polys->begin_vertex[polys->begin_vertices][0] = PRVM_G_VECTOR(OFS_PARM0)[0];
+ polys->begin_vertex[polys->begin_vertices][1] = PRVM_G_VECTOR(OFS_PARM0)[1];
+ polys->begin_vertex[polys->begin_vertices][2] = PRVM_G_VECTOR(OFS_PARM0)[2];
+ polys->begin_texcoord[polys->begin_vertices][0] = PRVM_G_VECTOR(OFS_PARM1)[0];
+ polys->begin_texcoord[polys->begin_vertices][1] = PRVM_G_VECTOR(OFS_PARM1)[1];
+ polys->begin_color[polys->begin_vertices][0] = PRVM_G_VECTOR(OFS_PARM2)[0];
+ polys->begin_color[polys->begin_vertices][1] = PRVM_G_VECTOR(OFS_PARM2)[1];
+ polys->begin_color[polys->begin_vertices][2] = PRVM_G_VECTOR(OFS_PARM2)[2];
+ polys->begin_color[polys->begin_vertices][3] = PRVM_G_FLOAT(OFS_PARM3);
+ polys->begin_vertices++;
}
//void() R_EndPolygon
vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
VM_SAFEPARMCOUNT(0, VM_CL_R_PolygonEnd);
- if(!polys->polygonbegin)
+ if (!polys->begin_active)
{
VM_Warning("VM_CL_R_PolygonEnd: VM_CL_R_PolygonBegin wasn't called\n");
return;
}
- polys->polygonbegin = false;
- if(polys->current_vertices > 2 || (polys->current_vertices >= 2 && polys->polygons[polys->drawpolygons_num].flags & VM_POLYGON_FLLINES))
- {
- if(polys->polygons[polys->drawpolygons_num].flags & VM_POLYGON_FL2D) //[515]: don't use qcpolygons memory if 2D
- VM_CL_AddPolygonTo2DScene(&polys->polygons[polys->drawpolygons_num]);
- else
- polys->drawpolygons_num++;
- }
+ polys->begin_active = false;
+ if (polys->begin_vertices >= 3)
+ VMPolygons_Store(polys);
else
- VM_Warning("VM_CL_R_PolygonEnd: %i vertices isn't a good choice\n", polys->current_vertices);
+ VM_Warning("VM_CL_R_PolygonEnd: %i vertices isn't a good choice\n", polys->begin_vertices);
}
static vmpolygons_t debugPolys;
-void Debug_PolygonBegin(const char *picname, int flags, qboolean draw2d, float linewidth)
+void Debug_PolygonBegin(const char *picname, int drawflag)
{
- vm_polygon_t *p;
-
if(!debugPolys.initialized)
VM_InitPolygons(&debugPolys);
- if(debugPolys.polygonbegin)
+ if(debugPolys.begin_active)
{
Con_Printf("Debug_PolygonBegin: called twice without Debug_PolygonEnd after first\n");
return;
}
- // limit polygons to a vaguely sane amount, beyond this each one just
- // replaces the last one
- debugPolys.drawpolygons_num = min(debugPolys.drawpolygons_num, (1<<20)-1);
- if(debugPolys.drawpolygons_num >= debugPolys.polygons_num)
- {
- p = (vm_polygon_t *)Mem_Alloc(debugPolys.pool, 2 * debugPolys.polygons_num * sizeof(vm_polygon_t));
- memset(p, 0, 2 * debugPolys.polygons_num * sizeof(vm_polygon_t));
- memcpy(p, debugPolys.polygons, debugPolys.polygons_num * sizeof(vm_polygon_t));
- Mem_Free(debugPolys.polygons);
- debugPolys.polygons = p;
- debugPolys.polygons_num *= 2;
- }
- p = &debugPolys.polygons[debugPolys.drawpolygons_num];
- if(picname && picname[0])
- p->tex = Draw_CachePic(picname, true)->tex;
- else
- p->tex = r_texture_white;
- p->flags = flags;
- debugPolys.current_vertices = 0;
- debugPolys.polygonbegin = true;
- if(draw2d)
- p->flags |= VM_POLYGON_FL2D;
- if(linewidth)
- {
- p->data[13] = linewidth; //[515]: linewidth
- p->flags |= VM_POLYGON_FLLINES;
- }
+ debugPolys.begin_texture = picname[0] ? Draw_CachePic (picname)->tex : r_texture_white;
+ debugPolys.begin_drawflag = drawflag;
+ debugPolys.begin_vertices = 0;
+ debugPolys.begin_active = true;
}
void Debug_PolygonVertex(float x, float y, float z, float s, float t, float r, float g, float b, float a)
{
- vm_polygon_t *p;
-
- if(!debugPolys.polygonbegin)
+ if(!debugPolys.begin_active)
{
Con_Printf("Debug_PolygonVertex: Debug_PolygonBegin wasn't called\n");
return;
}
- p = &debugPolys.polygons[debugPolys.drawpolygons_num];
- if(debugPolys.current_vertices > 4)
+ if(debugPolys.begin_vertices > VMPOLYGONS_MAXPOINTS)
{
- Con_Printf("Debug_PolygonVertex: may have 4 vertices max\n");
+ Con_Printf("Debug_PolygonVertex: may have %i vertices max\n", VMPOLYGONS_MAXPOINTS);
return;
}
- p->data[debugPolys.current_vertices*3] = x;
- p->data[1+debugPolys.current_vertices*3] = y;
- p->data[2+debugPolys.current_vertices*3] = z;
-
- p->data[12+debugPolys.current_vertices*2] = s;
- if(!(p->flags & VM_POLYGON_FLLINES))
- p->data[13+debugPolys.current_vertices*2] = t;
-
- p->data[20+debugPolys.current_vertices*4] = r;
- p->data[21+debugPolys.current_vertices*4] = g;
- p->data[22+debugPolys.current_vertices*4] = b;
- p->data[23+debugPolys.current_vertices*4] = a;
-
- debugPolys.current_vertices++;
- if(debugPolys.current_vertices == 4)
- p->flags |= VM_POLYGON_FL4V;
- else
- if(debugPolys.current_vertices == 3)
- p->flags |= VM_POLYGON_FL3V;
+ debugPolys.begin_vertex[debugPolys.begin_vertices][0] = x;
+ debugPolys.begin_vertex[debugPolys.begin_vertices][1] = y;
+ debugPolys.begin_vertex[debugPolys.begin_vertices][2] = z;
+ debugPolys.begin_texcoord[debugPolys.begin_vertices][0] = s;
+ debugPolys.begin_texcoord[debugPolys.begin_vertices][1] = t;
+ debugPolys.begin_color[debugPolys.begin_vertices][0] = r;
+ debugPolys.begin_color[debugPolys.begin_vertices][1] = g;
+ debugPolys.begin_color[debugPolys.begin_vertices][2] = b;
+ debugPolys.begin_color[debugPolys.begin_vertices][3] = a;
+ debugPolys.begin_vertices++;
}
void Debug_PolygonEnd(void)
{
- if(!debugPolys.polygonbegin)
+ if (!debugPolys.begin_active)
{
Con_Printf("Debug_PolygonEnd: Debug_PolygonBegin wasn't called\n");
return;
}
- debugPolys.polygonbegin = false;
- if(debugPolys.current_vertices > 2 || (debugPolys.current_vertices >= 2 && debugPolys.polygons[debugPolys.drawpolygons_num].flags & VM_POLYGON_FLLINES))
- {
- if(debugPolys.polygons[debugPolys.drawpolygons_num].flags & VM_POLYGON_FL2D) //[515]: don't use qcpolygons memory if 2D
- VM_CL_AddPolygonTo2DScene(&debugPolys.polygons[debugPolys.drawpolygons_num]);
- else
- debugPolys.drawpolygons_num++;
- }
+ debugPolys.begin_active = false;
+ if (debugPolys.begin_vertices >= 3)
+ VMPolygons_Store(&debugPolys);
else
- Con_Printf("Debug_PolygonEnd: %i vertices isn't a good choice\n", debugPolys.current_vertices);
+ Con_Printf("Debug_PolygonEnd: %i vertices isn't a good choice\n", debugPolys.begin_vertices);
}
/*
//============================================================================
+// To create a almost working builtin file from this replace:
+// "^NULL.*" with ""
+// "^{.*//.*}:Wh\(.*\)" with "\1"
+// "\:" with "//"
+// "^.*//:Wh{\#:d*}:Wh{.*}" with "\2 = \1;"
+// "\n\n+" with "\n\n"
+
prvm_builtin_t vm_cl_builtins[] = {
NULL, // #0 NULL function (not callable) (QUAKE)
VM_CL_makevectors, // #1 void(vector ang) makevectors (QUAKE)
VM_vectoyaw, // #13 float(vector v) vectoyaw (QUAKE)
VM_CL_spawn, // #14 entity() spawn (QUAKE)
VM_remove, // #15 void(entity e) remove (QUAKE)
-VM_CL_traceline, // #16 float(vector v1, vector v2, float tryents) traceline (QUAKE)
+VM_CL_traceline, // #16 float(vector v1, vector v2, float tryents, entity ignoreentity) traceline (QUAKE)
NULL, // #17 entity() checkclient (QUAKE)
VM_find, // #18 entity(entity start, .string fld, string match) find (QUAKE)
VM_precache_sound, // #19 void(string s) precache_sound (QUAKE)
VM_traceon, // #29 void() traceon (QUAKE)
VM_traceoff, // #30 void() traceoff (QUAKE)
VM_eprint, // #31 void(entity e) eprint (QUAKE)
-VM_CL_walkmove, // #32 float(float yaw, float dist) walkmove (QUAKE)
+VM_CL_walkmove, // #32 float(float yaw, float dist[, float settrace]) walkmove (QUAKE)
NULL, // #33 (QUAKE)
VM_CL_droptofloor, // #34 float() droptofloor (QUAKE)
VM_CL_lightstyle, // #35 void(float style, string value) lightstyle (QUAKE)
VM_CL_setcursormode, // #343 void(float usecursor) setcursormode (EXT_CSQC)
VM_getmousepos, // #344 vector() getmousepos (EXT_CSQC)
VM_CL_getinputstate, // #345 float(float framenum) getinputstate (EXT_CSQC)
-VM_CL_setsensitivityscale, // #346 void(float sens) setsensitivityscaler (EXT_CSQC)
+VM_CL_setsensitivityscale, // #346 void(float sens) setsensitivityscale (EXT_CSQC)
VM_CL_runplayerphysics, // #347 void() runstandardplayerphysics (EXT_CSQC)
VM_CL_getplayerkey, // #348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
VM_CL_isdemo, // #349 float() isdemo (EXT_CSQC)
NULL, // #454 entity() spawnclient (DP_SV_BOTCLIENT)
NULL, // #455 float(entity clent) clienttype (DP_SV_BOTCLIENT)
NULL, // #456 void(float to, string s) WriteUnterminatedString (DP_SV_WRITEUNTERMINATEDSTRING)
-VM_CL_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet = #457 (DP_TE_FLAMEJET)
+VM_CL_te_flamejet, // #457 void(vector org, vector vel, float howmany) te_flamejet (DP_TE_FLAMEJET)
NULL, // #458
VM_ftoe, // #459 entity(float num) entitybyindex (DP_QC_EDICT_NUM)
VM_buf_create, // #460 float() buf_create (DP_QC_STRINGBUFFERS)
VM_strtolower, // #480 string(string s) VM_strtolower (DP_QC_STRING_CASE_FUNCTIONS)
VM_strtoupper, // #481 string(string s) VM_strtoupper (DP_QC_STRING_CASE_FUNCTIONS)
VM_cvar_defstring, // #482 string(string s) cvar_defstring (DP_QC_CVAR_DEFSTRING)
-VM_CL_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) (DP_SV_POINTSOUND)
+VM_CL_pointsound, // #483 void(vector origin, string sample, float volume, float attenuation) pointsound (DP_SV_POINTSOUND)
VM_strreplace, // #484 string(string search, string replace, string subject) strreplace (DP_QC_STRREPLACE)
VM_strireplace, // #485 string(string search, string replace, string subject) strireplace (DP_QC_STRREPLACE)
-VM_CL_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
-#ifdef SUPPORT_GECKO
+VM_CL_getsurfacepointattribute,// #486 vector(entity e, float s, float n, float a) getsurfacepointattribute
VM_gecko_create, // #487 float gecko_create( string name )
VM_gecko_destroy, // #488 void gecko_destroy( string name )
VM_gecko_navigate, // #489 void gecko_navigate( string name, string URI )
VM_gecko_movemouse, // #491 void gecko_mousemove( string name, float x, float y )
VM_gecko_resize, // #492 void gecko_resize( string name, float w, float h )
VM_gecko_get_texture_extent, // #493 vector gecko_get_texture_extent( string name )
-#else
-NULL, // #487
-NULL, // #488
-NULL, // #489
-NULL, // #490
-NULL, // #491
-NULL, // #492
-NULL, // #493
-#endif
-NULL, // #494
-NULL, // #495
+VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16)
+VM_cvar_type, // #495 float(string name) cvar_type = #495; (DP_QC_CVAR_TYPE)
NULL, // #496
NULL, // #497
NULL, // #498
NULL, // #499
+NULL, // #500
+NULL, // #501
+NULL, // #502
+NULL, // #503
+NULL, // #504
+NULL, // #505
+NULL, // #506
+NULL, // #507
+NULL, // #508
+NULL, // #509
+VM_uri_escape, // #510 string(string in) uri_escape = #510;
+VM_uri_unescape, // #511 string(string in) uri_unescape = #511;
+VM_etof, // #512 float(entity ent) num_for_edict = #512 (DP_QC_NUM_FOR_EDICT)
+NULL, // #513
+NULL, // #514
+NULL, // #515
+NULL, // #516
+NULL, // #517
+NULL, // #518
+NULL, // #519
};
const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t);