cl.num_entities = 0;
cl.num_static_entities = 0;
- cl.num_temp_entities = 0;
cl.num_brushmodel_entities = 0;
// tweak these if the game runs out
cl.max_entities = 256;
cl.max_static_entities = 256;
- cl.max_temp_entities = 512;
cl.max_effects = 256;
cl.max_beams = 256;
cl.max_dlights = MAX_DLIGHTS;
cl.entities = (entity_t *)Mem_Alloc(cls.levelmempool, cl.max_entities * sizeof(entity_t));
cl.entities_active = (unsigned char *)Mem_Alloc(cls.levelmempool, cl.max_brushmodel_entities * sizeof(unsigned char));
cl.static_entities = (entity_t *)Mem_Alloc(cls.levelmempool, cl.max_static_entities * sizeof(entity_t));
- cl.temp_entities = (entity_t *)Mem_Alloc(cls.levelmempool, cl.max_temp_entities * sizeof(entity_t));
cl.effects = (cl_effect_t *)Mem_Alloc(cls.levelmempool, cl.max_effects * sizeof(cl_effect_t));
cl.beams = (beam_t *)Mem_Alloc(cls.levelmempool, cl.max_beams * sizeof(beam_t));
cl.dlights = (dlight_t *)Mem_Alloc(cls.levelmempool, cl.max_dlights * sizeof(dlight_t));
void CL_ClearTempEntities (void)
{
- cl.num_temp_entities = 0;
+ r_refdef.numtempentities = 0;
}
-entity_t *CL_NewTempEntity(void)
+entity_render_t *CL_NewTempEntity(void)
{
- entity_t *ent;
+ entity_render_t *render;
if (r_refdef.numentities >= r_refdef.maxentities)
return NULL;
- if (cl.num_temp_entities >= cl.max_temp_entities)
+ if (r_refdef.numtempentities >= r_refdef.maxtempentities)
return NULL;
- ent = &cl.temp_entities[cl.num_temp_entities++];
- memset (ent, 0, sizeof(*ent));
- r_refdef.entities[r_refdef.numentities++] = &ent->render;
+ render = &r_refdef.tempentities[r_refdef.numtempentities++];
+ memset (render, 0, sizeof(*render));
+ r_refdef.entities[r_refdef.numentities++] = render;
- ent->render.alpha = 1;
- VectorSet(ent->render.colormod, 1, 1, 1);
- return ent;
+ render->alpha = 1;
+ VectorSet(render->colormod, 1, 1, 1);
+ return render;
}
void CL_Effect(vec3_t org, int modelindex, int startframe, int framecount, float framerate)
void CL_AddQWCTFFlagModel(entity_t *player, int skin)
{
float f;
- entity_t *flag;
+ entity_render_t *flagrender;
matrix4x4_t flagmatrix;
// this code taken from QuakeWorld
}
// end of code taken from QuakeWorld
- flag = CL_NewTempEntity();
- if (!flag)
+ flagrender = CL_NewTempEntity();
+ if (!flagrender)
return;
- flag->render.model = cl.model_precache[cl.qw_modelindex_flag];
- flag->render.skinnum = skin;
- flag->render.alpha = 1;
- VectorSet(flag->render.colormod, 1, 1, 1);
+ flagrender->model = cl.model_precache[cl.qw_modelindex_flag];
+ flagrender->skinnum = skin;
+ flagrender->alpha = 1;
+ VectorSet(flagrender->colormod, 1, 1, 1);
// attach the flag to the player matrix
Matrix4x4_CreateFromQuakeEntity(&flagmatrix, -f, -22, 0, 0, 0, -45, 1);
- Matrix4x4_Concat(&flag->render.matrix, &player->render.matrix, &flagmatrix);
- CL_UpdateRenderEntity(&flag->render);
+ Matrix4x4_Concat(&flagrender->matrix, &player->render.matrix, &flagmatrix);
+ CL_UpdateRenderEntity(flagrender);
}
matrix4x4_t viewmodelmatrix;
{
int i, intframe;
cl_effect_t *e;
- entity_t *ent;
+ entity_render_t *entrender;
float frame;
for (i = 0, e = cl.effects;i < cl.num_effects;i++, e++)
// if we're drawing effects, get a new temp entity
// (NewTempEntity adds it to the render entities list for us)
- if (r_draweffects.integer && (ent = CL_NewTempEntity()))
+ if (r_draweffects.integer && (entrender = CL_NewTempEntity()))
{
// interpolation stuff
- ent->render.frame1 = intframe;
- ent->render.frame2 = intframe + 1;
- if (ent->render.frame2 >= e->endframe)
- ent->render.frame2 = -1; // disappear
- ent->render.framelerp = frame - intframe;
- ent->render.frame1time = e->frame1time;
- ent->render.frame2time = e->frame2time;
+ entrender->frame1 = intframe;
+ entrender->frame2 = intframe + 1;
+ if (entrender->frame2 >= e->endframe)
+ entrender->frame2 = -1; // disappear
+ entrender->framelerp = frame - intframe;
+ entrender->frame1time = e->frame1time;
+ entrender->frame2time = e->frame2time;
// normal stuff
if(e->modelindex < MAX_MODELS)
- ent->render.model = cl.model_precache[e->modelindex];
+ entrender->model = cl.model_precache[e->modelindex];
else
- ent->render.model = cl.csqc_model_precache[-(e->modelindex+1)];
- ent->render.alpha = 1;
- VectorSet(ent->render.colormod, 1, 1, 1);
+ entrender->model = cl.csqc_model_precache[-(e->modelindex+1)];
+ entrender->alpha = 1;
+ VectorSet(entrender->colormod, 1, 1, 1);
- Matrix4x4_CreateFromQuakeEntity(&ent->render.matrix, e->origin[0], e->origin[1], e->origin[2], 0, 0, 0, 1);
- CL_UpdateRenderEntity(&ent->render);
+ Matrix4x4_CreateFromQuakeEntity(&entrender->matrix, e->origin[0], e->origin[1], e->origin[2], 0, 0, 0, 1);
+ CL_UpdateRenderEntity(entrender);
}
}
}
beam_t *b;
vec3_t dist, org, start, end;
float d;
- entity_t *ent;
+ entity_render_t *entrender;
double yaw, pitch;
float forward;
matrix4x4_t tempmatrix;
d = VectorNormalizeLength(dist);
while (d > 0)
{
- ent = CL_NewTempEntity ();
- if (!ent)
+ entrender = CL_NewTempEntity ();
+ if (!entrender)
return;
//VectorCopy (org, ent->render.origin);
- ent->render.model = b->model;
+ entrender->model = b->model;
//ent->render.effects = EF_FULLBRIGHT;
//ent->render.angles[0] = pitch;
//ent->render.angles[1] = yaw;
//ent->render.angles[2] = rand()%360;
- Matrix4x4_CreateFromQuakeEntity(&ent->render.matrix, org[0], org[1], org[2], -pitch, yaw, lhrandom(0, 360), 1);
- CL_UpdateRenderEntity(&ent->render);
+ Matrix4x4_CreateFromQuakeEntity(&entrender->matrix, org[0], org[1], org[2], -pitch, yaw, lhrandom(0, 360), 1);
+ CL_UpdateRenderEntity(entrender);
VectorMA(org, 30, dist, org);
d -= 30;
}
{
int i;
vec_t *v;
- entity_t *ent;
+ entity_render_t *entrender;
for (i = 0;i < cl.qw_num_nails;i++)
{
// if we're drawing effects, get a new temp entity
// (NewTempEntity adds it to the render entities list for us)
- if (!(ent = CL_NewTempEntity()))
+ if (!(entrender = CL_NewTempEntity()))
continue;
// normal stuff
- ent->render.model = cl.model_precache[cl.qw_modelindex_spike];
- ent->render.alpha = 1;
- VectorSet(ent->render.colormod, 1, 1, 1);
+ entrender->model = cl.model_precache[cl.qw_modelindex_spike];
+ entrender->alpha = 1;
+ VectorSet(entrender->colormod, 1, 1, 1);
- Matrix4x4_CreateFromQuakeEntity(&ent->render.matrix, v[0], v[1], v[2], v[3], v[4], v[5], 1);
- CL_UpdateRenderEntity(&ent->render);
+ Matrix4x4_CreateFromQuakeEntity(&entrender->matrix, v[0], v[1], v[2], v[3], v[4], v[5], 1);
+ CL_UpdateRenderEntity(entrender);
}
}
r_refdef.maxentities = MAX_EDICTS + 256 + 512;
r_refdef.entities = (entity_render_t **)Mem_Alloc(cls.permanentmempool, sizeof(entity_render_t *) * r_refdef.maxentities);
+ r_refdef.maxtempentities = 512;
+ r_refdef.tempentities = (entity_render_t *)Mem_Alloc(cls.permanentmempool, sizeof(entity_render_t) * r_refdef.maxtempentities);
+
CL_InitInput ();
//
int max_entities;
int max_static_entities;
- int max_temp_entities;
int max_effects;
int max_beams;
int max_dlights;
entity_t *entities;
unsigned char *entities_active;
entity_t *static_entities;
- entity_t *temp_entities;
cl_effect_t *effects;
beam_t *beams;
dlight_t *dlights;
int num_entities;
int num_static_entities;
- int num_temp_entities;
int num_brushmodel_entities;
int num_effects;
int num_beams;
void CL_ClientMovement_Replay(void);
void CL_ClearTempEntities (void);
-entity_t *CL_NewTempEntity (void);
+entity_render_t *CL_NewTempEntity (void);
void CL_Effect(vec3_t org, int modelindex, int startframe, int framecount, float framerate);
int numentities;
int maxentities;
+ // field of temporary entities that is reset each (client) frame
+ entity_render_t *tempentities;
+ int numtempentities;
+ int maxtempentities;
+
// renderable dynamic lights
rtlight_t lights[MAX_DLIGHTS];
int numlights;
void CSQC_RelinkCSQCEntities (void);
const char *Key_GetBind (int key);
-
-
-
-
-
// #1 void(vector ang) makevectors
static void VM_CL_makevectors (void)
{
}
// #2 void(entity e, vector o) setorigin
-static void VM_CL_setorigin (void)
+void VM_CL_setorigin (void)
{
prvm_edict_t *e;
float *org;
}
// #3 void(entity e, string m) setmodel
-static void VM_CL_setmodel (void)
+void VM_CL_setmodel (void)
{
prvm_edict_t *e;
const char *m;
// #20 void(string s) precache_model
-static void VM_CL_precache_model (void)
+void VM_CL_precache_model (void)
{
const char *name;
int i;
void CL_RelinkLightFlashes(void);
//#300 void() clearscene (EXT_CSQC)
-static void VM_CL_R_ClearScene (void)
+void VM_CL_R_ClearScene (void)
{
VM_SAFEPARMCOUNT(0, VM_CL_R_ClearScene);
// clear renderable entity and light lists
//#301 void(float mask) addentities (EXT_CSQC)
extern void CSQC_Predraw (prvm_edict_t *ed);//csprogs.c
extern void CSQC_Think (prvm_edict_t *ed);//csprogs.c
-static void VM_CL_R_AddEntities (void)
+void VM_CL_R_AddEntities (void)
{
int i, drawmask;
prvm_edict_t *ed;
}
//#302 void(entity ent) addentity (EXT_CSQC)
-static void VM_CL_R_AddEntity (void)
+void VM_CL_R_AddEntity (void)
{
VM_SAFEPARMCOUNT(1, VM_CL_R_AddEntity);
CSQC_AddRenderEdict(PRVM_G_EDICT(OFS_PARM0));
}
//#303 float(float property, ...) setproperty (EXT_CSQC)
-static void VM_CL_R_SetView (void)
+void VM_CL_R_SetView (void)
{
int c;
float *f;
}
//#304 void() renderscene (EXT_CSQC)
-static void VM_CL_R_RenderScene (void)
+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
}
//#305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
-static void VM_CL_R_AddDynamicLight (void)
+void VM_CL_R_AddDynamicLight (void)
{
float *pos, *col;
matrix4x4_t matrix;
unsigned char flags; //[515]: + VM_POLYGON_2D and VM_POLYGON_FL4V flags
}vm_polygon_t;
-//static float vm_polygon_linewidth = 1;
-static mempool_t *vm_polygons_pool = NULL;
-static unsigned char vm_current_vertices = 0;
-static qboolean vm_polygons_initialized = false;
-static vm_polygon_t *vm_polygons = NULL;
-static unsigned long vm_polygons_num = 0, vm_drawpolygons_num = 0; //[515]: ok long on 64bit ?
-static qboolean vm_polygonbegin = false; //[515]: for "no-crap-on-the-screen" check
+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
+} vmpolygons_t;
+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_FL2D 64
#define VM_POLYGON_FL4V 128 //4 vertices
-static void VM_InitPolygons (void)
+static void VM_InitPolygons (vmpolygons_t* polys)
{
- vm_polygons_pool = Mem_AllocPool("VMPOLY", 0, NULL);
- vm_polygons = (vm_polygon_t *)Mem_Alloc(vm_polygons_pool, VM_DEFPOLYNUM*sizeof(vm_polygon_t));
- memset(vm_polygons, 0, VM_DEFPOLYNUM*sizeof(vm_polygon_t));
- vm_polygons_num = VM_DEFPOLYNUM;
- vm_drawpolygons_num = 0;
- vm_polygonbegin = false;
- vm_polygons_initialized = true;
+ 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->initialized = true;
}
static void VM_DrawPolygonCallback (const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
{
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 = &vm_polygons[surfacelist[surfacelistindex]];
+ const vm_polygon_t *p = &polys->polygons[surfacelist[surfacelistindex]];
int flags = p->flags & 0x0f;
if(flags == DRAWFLAG_ADDITIVE)
{
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;
void VM_CL_AddPolygonsToMeshQueue (void)
{
int i;
- if(!vm_drawpolygons_num)
+ vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
+
+ if(!polys->drawpolygons_num)
return;
R_Mesh_Matrix(&identitymatrix);
GL_CullFace(GL_NONE);
- for(i = 0;i < (int)vm_drawpolygons_num;i++)
+ for(i = 0;i < (int)polys->drawpolygons_num;i++)
VM_DrawPolygonCallback(NULL, NULL, 1, &i);
- vm_drawpolygons_num = 0;
+ polys->drawpolygons_num = 0;
}
//void(string texturename, float flag[, float 2d[, float lines]]) R_BeginPolygon
-static void VM_CL_R_PolygonBegin (void)
+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);
- if(!vm_polygons_initialized)
- VM_InitPolygons();
- if(vm_polygonbegin)
+ if(!polys->initialized)
+ VM_InitPolygons(polys);
+ if(polys->polygonbegin)
{
VM_Warning("VM_CL_R_PolygonBegin: called twice without VM_CL_R_PolygonEnd after first\n");
return;
}
- if(vm_drawpolygons_num >= vm_polygons_num)
+ if(polys->drawpolygons_num >= polys->polygons_num)
{
- p = (vm_polygon_t *)Mem_Alloc(vm_polygons_pool, 2 * vm_polygons_num * sizeof(vm_polygon_t));
- memset(p, 0, 2 * vm_polygons_num * sizeof(vm_polygon_t));
- memcpy(p, vm_polygons, vm_polygons_num * sizeof(vm_polygon_t));
- Mem_Free(vm_polygons);
- vm_polygons = p;
- vm_polygons_num *= 2;
+ 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 = &vm_polygons[vm_drawpolygons_num];
+ 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);
- vm_current_vertices = 0;
- vm_polygonbegin = true;
+ polys->current_vertices = 0;
+ polys->polygonbegin = true;
if(prog->argc >= 3)
{
if(PRVM_G_FLOAT(OFS_PARM2))
}
//void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
-static void VM_CL_R_PolygonVertex (void)
+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(!vm_polygonbegin)
+ if(!polys->polygonbegin)
{
VM_Warning("VM_CL_R_PolygonVertex: VM_CL_R_PolygonBegin wasn't called\n");
return;
rgb = PRVM_G_VECTOR(OFS_PARM2);
alpha = PRVM_G_FLOAT(OFS_PARM3);
- p = &vm_polygons[vm_drawpolygons_num];
- if(vm_current_vertices > 4)
+ p = &polys->polygons[polys->drawpolygons_num];
+ if(polys->current_vertices > 4)
{
VM_Warning("VM_CL_R_PolygonVertex: may have 4 vertices max\n");
return;
}
- p->data[vm_current_vertices*3] = coords[0];
- p->data[1+vm_current_vertices*3] = coords[1];
- p->data[2+vm_current_vertices*3] = coords[2];
+ 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+vm_current_vertices*2] = tx[0];
+ p->data[12+polys->current_vertices*2] = tx[0];
if(!(p->flags & VM_POLYGON_FLLINES))
- p->data[13+vm_current_vertices*2] = tx[1];
+ p->data[13+polys->current_vertices*2] = tx[1];
- p->data[20+vm_current_vertices*4] = rgb[0];
- p->data[21+vm_current_vertices*4] = rgb[1];
- p->data[22+vm_current_vertices*4] = rgb[2];
- p->data[23+vm_current_vertices*4] = alpha;
+ 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;
- vm_current_vertices++;
- if(vm_current_vertices == 4)
+ polys->current_vertices++;
+ if(polys->current_vertices == 4)
p->flags |= VM_POLYGON_FL4V;
else
- if(vm_current_vertices == 3)
+ if(polys->current_vertices == 3)
p->flags |= VM_POLYGON_FL3V;
}
//void() R_EndPolygon
-static void VM_CL_R_PolygonEnd (void)
+void VM_CL_R_PolygonEnd (void)
{
+ vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
+
VM_SAFEPARMCOUNT(0, VM_CL_R_PolygonEnd);
- if(!vm_polygonbegin)
+ if(!polys->polygonbegin)
{
VM_Warning("VM_CL_R_PolygonEnd: VM_CL_R_PolygonBegin wasn't called\n");
return;
}
- vm_polygonbegin = false;
- if(vm_current_vertices > 2 || (vm_current_vertices >= 2 && vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FLLINES))
+ polys->polygonbegin = false;
+ if(polys->current_vertices > 2 || (polys->current_vertices >= 2 && polys->polygons[polys->drawpolygons_num].flags & VM_POLYGON_FLLINES))
{
- if(vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FL2D) //[515]: don't use qcpolygons memory if 2D
- VM_CL_AddPolygonTo2DScene(&vm_polygons[vm_drawpolygons_num]);
+ 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
- vm_drawpolygons_num++;
+ polys->drawpolygons_num++;
}
else
- VM_Warning("VM_CL_R_PolygonEnd: %i vertices isn't a good choice\n", vm_current_vertices);
+ VM_Warning("VM_CL_R_PolygonEnd: %i vertices isn't a good choice\n", polys->current_vertices);
}
+static vmpolygons_t debugPolys;
+
void Debug_PolygonBegin(const char *picname, int flags, qboolean draw2d, float linewidth)
{
vm_polygon_t *p;
- if(!vm_polygons_initialized)
- VM_InitPolygons();
- if(vm_polygonbegin)
+ if(!debugPolys.initialized)
+ VM_InitPolygons(&debugPolys);
+ if(debugPolys.polygonbegin)
{
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
- vm_drawpolygons_num = min(vm_drawpolygons_num, (1<<20)-1);
- if(vm_drawpolygons_num >= vm_polygons_num)
+ debugPolys.drawpolygons_num = min(debugPolys.drawpolygons_num, (1<<20)-1);
+ if(debugPolys.drawpolygons_num >= debugPolys.polygons_num)
{
- p = (vm_polygon_t *)Mem_Alloc(vm_polygons_pool, 2 * vm_polygons_num * sizeof(vm_polygon_t));
- memset(p, 0, 2 * vm_polygons_num * sizeof(vm_polygon_t));
- memcpy(p, vm_polygons, vm_polygons_num * sizeof(vm_polygon_t));
- Mem_Free(vm_polygons);
- vm_polygons = p;
- vm_polygons_num *= 2;
+ 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 = &vm_polygons[vm_drawpolygons_num];
+ 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;
- vm_current_vertices = 0;
- vm_polygonbegin = true;
+ debugPolys.current_vertices = 0;
+ debugPolys.polygonbegin = true;
if(draw2d)
p->flags |= VM_POLYGON_FL2D;
if(linewidth)
{
vm_polygon_t *p;
- if(!vm_polygonbegin)
+ if(!debugPolys.polygonbegin)
{
Con_Printf("Debug_PolygonVertex: Debug_PolygonBegin wasn't called\n");
return;
}
- p = &vm_polygons[vm_drawpolygons_num];
- if(vm_current_vertices > 4)
+ p = &debugPolys.polygons[debugPolys.drawpolygons_num];
+ if(debugPolys.current_vertices > 4)
{
Con_Printf("Debug_PolygonVertex: may have 4 vertices max\n");
return;
}
- p->data[vm_current_vertices*3] = x;
- p->data[1+vm_current_vertices*3] = y;
- p->data[2+vm_current_vertices*3] = z;
+ 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+vm_current_vertices*2] = s;
+ p->data[12+debugPolys.current_vertices*2] = s;
if(!(p->flags & VM_POLYGON_FLLINES))
- p->data[13+vm_current_vertices*2] = t;
+ p->data[13+debugPolys.current_vertices*2] = t;
- p->data[20+vm_current_vertices*4] = r;
- p->data[21+vm_current_vertices*4] = g;
- p->data[22+vm_current_vertices*4] = b;
- p->data[23+vm_current_vertices*4] = a;
+ 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;
- vm_current_vertices++;
- if(vm_current_vertices == 4)
+ debugPolys.current_vertices++;
+ if(debugPolys.current_vertices == 4)
p->flags |= VM_POLYGON_FL4V;
else
- if(vm_current_vertices == 3)
+ if(debugPolys.current_vertices == 3)
p->flags |= VM_POLYGON_FL3V;
}
void Debug_PolygonEnd(void)
{
- if(!vm_polygonbegin)
+ if(!debugPolys.polygonbegin)
{
Con_Printf("Debug_PolygonEnd: Debug_PolygonBegin wasn't called\n");
return;
}
- vm_polygonbegin = false;
- if(vm_current_vertices > 2 || (vm_current_vertices >= 2 && vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FLLINES))
+ debugPolys.polygonbegin = false;
+ if(debugPolys.current_vertices > 2 || (debugPolys.current_vertices >= 2 && debugPolys.polygons[debugPolys.drawpolygons_num].flags & VM_POLYGON_FLLINES))
{
- if(vm_polygons[vm_drawpolygons_num].flags & VM_POLYGON_FL2D) //[515]: don't use qcpolygons memory if 2D
- VM_CL_AddPolygonTo2DScene(&vm_polygons[vm_drawpolygons_num]);
+ 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
- vm_drawpolygons_num++;
+ debugPolys.drawpolygons_num++;
}
else
- Con_Printf("Debug_PolygonEnd: %i vertices isn't a good choice\n", vm_current_vertices);
+ Con_Printf("Debug_PolygonEnd: %i vertices isn't a good choice\n", debugPolys.current_vertices);
}
/*
VM_CL_R_PolygonBegin, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
VM_CL_R_PolygonVertex, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
VM_CL_R_PolygonEnd, // #308 void() R_EndPolygon
-NULL, // #309
+NULL /* R_LoadWorldModel in menu VM, should stay unassigned in client*/, // #309
VM_CL_unproject, // #310 vector (vector v) cs_unproject (EXT_CSQC)
VM_CL_project, // #311 vector (vector v) cs_project (EXT_CSQC)
NULL, // #312
const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t);
-void VM_CL_Cmd_Init(void)
+void VM_Polygons_Reset(void)
{
- VM_Cmd_Init();
+ vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
+
// TODO: replace vm_polygons stuff with a more general debugging polygon system, and make vm_polygons functions use that system
- if(vm_polygons_initialized)
+ if(polys->initialized)
{
- Mem_FreePool(&vm_polygons_pool);
- vm_polygons_initialized = false;
+ Mem_FreePool(&polys->pool);
+ polys->initialized = false;
}
}
+void VM_CL_Cmd_Init(void)
+{
+ VM_Cmd_Init();
+ VM_Polygons_Reset();
+}
+
void VM_CL_Cmd_Reset(void)
{
VM_Cmd_Reset();
- if(vm_polygons_initialized)
- {
- Mem_FreePool(&vm_polygons_pool);
- vm_polygons_initialized = false;
- }
+ VM_Polygons_Reset();
}
+
int CL_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex);
+/* These are VM built-ins that originate in the client-side programs support
+ but are reused by the other programs (usually the menu). */
+
+void VM_CL_setmodel (void);
+void VM_CL_precache_model (void);
+void VM_CL_setorigin (void);
+
+void VM_CL_R_AddDynamicLight (void);
+void VM_CL_R_ClearScene (void);
+void VM_CL_R_AddEntities (void);
+void VM_CL_R_AddEntity (void);
+void VM_CL_R_SetView (void);
+void VM_CL_R_RenderScene (void);
+void VM_CL_R_LoadWorldModel (void);
+
+void VM_CL_R_PolygonBegin (void);
+void VM_CL_R_PolygonVertex (void);
+void VM_CL_R_PolygonEnd (void);
+/* VMs exposing the polygon calls must call this on Init/Reset */
+void VM_Polygons_Reset();
+
#endif /* __CLVM_CMDS_H__ */
int c;
float scale;
prvm_eval_t *val;
- entity_t *e;
+ entity_render_t *entrender;
model_t *model;
matrix4x4_t tagmatrix, matrix2;
if (!model)
return false;
- e = CL_NewTempEntity();
- if (!e)
+ entrender = CL_NewTempEntity();
+ if (!entrender)
return false;
- e->render.model = model;
- e->render.skinnum = (int)ed->fields.client->skin;
- e->render.effects |= e->render.model->effects;
+ entrender->model = model;
+ entrender->skinnum = (int)ed->fields.client->skin;
+ entrender->effects |= entrender->model->effects;
scale = 1;
renderflags = 0;
if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.renderflags)) && val->_float) renderflags = (int)val->_float;
- if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.alpha)) && val->_float) e->render.alpha = val->_float;
- if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.scale)) && val->_float) e->render.scale = scale = val->_float;
- if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.colormod)) && VectorLength2(val->vector)) VectorCopy(val->vector, e->render.colormod);
- if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.effects)) && val->_float) e->render.effects |= (int)val->_float;
+ if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.alpha)) && val->_float) entrender->alpha = val->_float;
+ if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.scale)) && val->_float) entrender->scale = scale = val->_float;
+ if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.colormod)) && VectorLength2(val->vector)) VectorCopy(val->vector, entrender->colormod);
+ if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.effects)) && val->_float) entrender->effects |= (int)val->_float;
if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.tag_entity)) && val->edict)
{
int tagentity;
vec3_t angles;
VectorCopy(ed->fields.client->angles, angles);
// if model is alias, reverse pitch direction
- if (e->render.model->type == mod_alias)
+ if (entrender->model->type == mod_alias)
angles[0] = -angles[0];
// set up the render matrix
// self.frame1time is the animation base time for the interpolation target
// self.frame2 is the interpolation start (previous frame)
// self.frame2time is the animation base time for the interpolation start
- e->render.frame1 = e->render.frame2 = ed->fields.client->frame;
- if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame2))) e->render.frame2 = val->_float;
- if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame1time))) e->render.frame2time = val->_float;
- if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame2time))) e->render.frame1time = val->_float;
- if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.lerpfrac))) e->render.framelerp = val->_float;
+ entrender->frame1 = entrender->frame2 = ed->fields.client->frame;
+ if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame2))) entrender->frame2 = val->_float;
+ if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame1time))) entrender->frame2time = val->_float;
+ if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame2time))) entrender->frame1time = val->_float;
+ if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.lerpfrac))) entrender->framelerp = val->_float;
// concat the matrices to make the entity relative to its tag
- Matrix4x4_Concat(&e->render.matrix, &tagmatrix, &matrix2);
+ Matrix4x4_Concat(&entrender->matrix, &tagmatrix, &matrix2);
if(renderflags)
{
- if(renderflags & RF_VIEWMODEL) e->render.flags |= RENDER_VIEWMODEL;
- if(renderflags & RF_EXTERNALMODEL)e->render.flags |= RENDER_EXTERIORMODEL;
- if(renderflags & RF_DEPTHHACK) e->render.effects |= EF_NODEPTHTEST;
- if(renderflags & RF_ADDITIVE) e->render.effects |= EF_ADDITIVE;
+ if(renderflags & RF_VIEWMODEL) entrender->flags |= RENDER_VIEWMODEL;
+ if(renderflags & RF_EXTERNALMODEL)entrender->flags |= RENDER_EXTERIORMODEL;
+ if(renderflags & RF_DEPTHHACK) entrender->effects |= EF_NODEPTHTEST;
+ if(renderflags & RF_ADDITIVE) entrender->effects |= EF_ADDITIVE;
}
c = (int)ed->fields.client->colormap;
if (c <= 0)
- CL_SetEntityColormapColors(&e->render, -1);
+ CL_SetEntityColormapColors(entrender, -1);
else if (c <= cl.maxclients && cl.scores != NULL)
- CL_SetEntityColormapColors(&e->render, cl.scores[c-1].colors);
+ CL_SetEntityColormapColors(entrender, cl.scores[c-1].colors);
else
- CL_SetEntityColormapColors(&e->render, c);
+ CL_SetEntityColormapColors(entrender, c);
// either fullbright or lit
- if (!(e->render.effects & EF_FULLBRIGHT) && !r_fullbright.integer)
- e->render.flags |= RENDER_LIGHT;
+ if (!(entrender->effects & EF_FULLBRIGHT) && !r_fullbright.integer)
+ entrender->flags |= RENDER_LIGHT;
// hide player shadow during intermission or nehahra movie
- if (!(e->render.effects & (EF_NOSHADOW | EF_ADDITIVE | EF_NODEPTHTEST))
- && (e->render.alpha >= 1)
- && !(e->render.flags & RENDER_VIEWMODEL)
- && (!(e->render.flags & RENDER_EXTERIORMODEL) || (!cl.intermission && cls.protocol != PROTOCOL_NEHAHRAMOVIE && !cl_noplayershadow.integer)))
- e->render.flags |= RENDER_SHADOW;
- if (e->render.flags & RENDER_VIEWMODEL)
- e->render.flags |= RENDER_NOSELFSHADOW;
+ if (!(entrender->effects & (EF_NOSHADOW | EF_ADDITIVE | EF_NODEPTHTEST))
+ && (entrender->alpha >= 1)
+ && !(entrender->flags & RENDER_VIEWMODEL)
+ && (!(entrender->flags & RENDER_EXTERIORMODEL) || (!cl.intermission && cls.protocol != PROTOCOL_NEHAHRAMOVIE && !cl_noplayershadow.integer)))
+ entrender->flags |= RENDER_SHADOW;
+ if (entrender->flags & RENDER_VIEWMODEL)
+ entrender->flags |= RENDER_NOSELFSHADOW;
// make the other useful stuff
- CL_UpdateRenderEntity(&e->render);
+ CL_UpdateRenderEntity(entrender);
return true;
}
void MP_Draw (void)
{
+ extern r_refdef_t menu_refdef;
+
+ static r_refdef_t clientrefdef;
+ clientrefdef = r_refdef;
+ r_refdef = menu_refdef;
+
+ // reset the temp entities each frame
+ r_refdef.numtempentities = 0;
+
+ R_UpdateVariables();
+
PRVM_Begin;
PRVM_SetProg(PRVM_MENUPROG);
+ // FIXME: this really shouldnt error out lest we have a very broken refdef state...?
+ // or does it kill the server too?
PRVM_ExecuteProgram(prog->funcoffsets.m_draw,"m_draw() required");
PRVM_End;
+
+ menu_refdef = r_refdef;
+ r_refdef = clientrefdef;
}
void MP_ToggleMenu_f (void)
//
// menu router
//
+
void MR_Init_Commands (void);
void MR_Init (void);
void MR_Restart (void);
#include "quakedef.h"
#include "prvm_cmds.h"
+#include "clvm_cmds.h"
#include "menu.h"
//============================================================================
#ifdef SUPPORT_GECKO
"DP_GECKO_SUPPORT "
#endif
+"DP_QC_RENDER_SCENE"
;
/*
VM_findflags, // #87
VM_findchainflags, // #88
VM_cvar_defstring, // #89
-NULL, // #90
-NULL, // #91
-NULL, // #92
+VM_CL_setmodel, // #90 void(entity e, string m) setmodel (QUAKE)
+VM_CL_precache_model, // #91 void(string s) precache_model (QUAKE)
+VM_CL_setorigin, // #92 void(entity e, vector o) setorigin (QUAKE)
NULL, // #93
NULL, // #94
NULL, // #95
NULL, // #297
NULL, // #298
NULL, // #299
-NULL, // #300
-NULL, // #301
-NULL, // #302
-NULL, // #303
-NULL, // #304
-NULL, // #305
-NULL, // #306
-NULL, // #307
-NULL, // #308
-NULL, // #309
+// CSQC range #300-#399
+VM_CL_R_ClearScene, // #300 void() clearscene (DP_QC_RENDER_SCENE)
+VM_CL_R_AddEntities, // #301 void(float mask) addentities (DP_QC_RENDER_SCENE)
+VM_CL_R_AddEntity, // #302 void(entity ent) addentity (DP_QC_RENDER_SCENE)
+VM_CL_R_SetView, // #303 float(float property, ...) setproperty (DP_QC_RENDER_SCENE)
+VM_CL_R_RenderScene, // #304 void() renderscene (DP_QC_RENDER_SCENE)
+VM_CL_R_AddDynamicLight, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (DP_QC_RENDER_SCENE)
+VM_CL_R_PolygonBegin, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
+VM_CL_R_PolygonVertex, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
+VM_CL_R_PolygonEnd, // #308 void() R_EndPolygon
+NULL/*VM_CL_R_LoadWorldModel*/, // #309 void(string modelname) R_LoadWorldModel
NULL, // #310
NULL, // #311
NULL, // #312
const int vm_m_numbuiltins = sizeof(vm_m_builtins) / sizeof(prvm_builtin_t);
+r_refdef_t menu_refdef;
+
void VM_M_Cmd_Init(void)
{
VM_Cmd_Init();
+ VM_Polygons_Reset();
+
+ memset (&menu_refdef, 0, sizeof (r_refdef_t));
+
+ menu_refdef.maxtempentities = 128;
+ menu_refdef.tempentities = (entity_render_t*) Mem_Alloc(prog->progs_mempool, sizeof(entity_render_t) * menu_refdef.maxtempentities);
+
+ menu_refdef.frustumscale_x = 1;
+ menu_refdef.frustumscale_y = 1;
+ menu_refdef.maxentities = MAX_EDICTS + 256 + 512;
+ menu_refdef.entities = (entity_render_t **)Mem_Alloc(cls.permanentmempool, sizeof(entity_render_t *) * menu_refdef.maxentities);
+
+ menu_refdef.view.width = vid.width;
+ menu_refdef.view.height = vid.height;
+ menu_refdef.view.depth = 1;
+ menu_refdef.view.x = 0;
+ menu_refdef.view.y = 0;
+ menu_refdef.view.z = 0;
+ menu_refdef.view.colormask[0] = true;
+ menu_refdef.view.colormask[1] = true;
+ menu_refdef.view.colormask[2] = true;
+ menu_refdef.view.colormask[3] = true;
+
+ menu_refdef.view.useperspective = true;
+ menu_refdef.view.frustum_y = tan(scr_fov.value * M_PI / 360.0) * (3.0/4.0);
+ menu_refdef.view.frustum_x = menu_refdef.view.frustum_y * (float)menu_refdef.view.width / (float)menu_refdef.view.height / vid_pixelheight.value;
}
void VM_M_Cmd_Reset(void)
{
//VM_Cmd_Init();
VM_Cmd_Reset();
+ VM_Polygons_Reset();
}