X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=clvm_cmds.c;h=aec8cbee452d0aa553f6321d8ab4bd97d0eca6d5;hb=d5ea21772f2ee1609671ebd393a10f71892db483;hp=268222d127c9f647a715fb93c002b78f1c7418f5;hpb=c29fd080ff5ad128d4cd9f04cbe9e3e5cafde03c;p=xonotic%2Fdarkplaces.git diff --git a/clvm_cmds.c b/clvm_cmds.c index 268222d1..aec8cbee 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -1,3 +1,5 @@ +#include "quakedef.h" + #include "prvm_cmds.h" #include "csprogs.h" #include "cl_collision.h" @@ -22,12 +24,7 @@ void Sbar_SortFrags (void); void CL_FindNonSolidLocation(const vec3_t in, vec3_t out, vec_t radius); void CSQC_RelinkAllEntities (int drawmask); void CSQC_RelinkCSQCEntities (void); -char *Key_GetBind (int key); - - - - - +const char *Key_GetBind (int key); // #1 void(vector ang) makevectors static void VM_CL_makevectors (void) @@ -37,7 +34,7 @@ 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; @@ -59,12 +56,28 @@ static void VM_CL_setorigin (void) 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 -static void VM_CL_setmodel (void) +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); @@ -94,6 +107,15 @@ static void VM_CL_setmodel (void) e->fields.client->modelindex = 0; e->fields.client->model = 0; + VM_Warning ("setmodel: model '%s' not precached\n", m); + + // TODO: check if this breaks needed consistency and maybe add a cvar for it too?? [1/10/2008 Black] + if (mod) + { + SetMinMaxSize (e, mod->normalmins, mod->normalmaxs); + } + else + SetMinMaxSize (e, vec3_origin, vec3_origin); } // #4 void(entity e, vector min, vector max) setsize @@ -117,9 +139,7 @@ static void VM_CL_setsize (void) 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); } @@ -130,7 +150,7 @@ static void VM_CL_sound (void) const char *sample; int channel; prvm_edict_t *entity; - int volume; + float volume; float attenuation; VM_SAFEPARMCOUNT(5, VM_CL_sound); @@ -138,10 +158,10 @@ static void VM_CL_sound (void) entity = PRVM_G_EDICT(OFS_PARM0); channel = (int)PRVM_G_FLOAT(OFS_PARM1); sample = PRVM_G_STRING(OFS_PARM2); - volume = (int)(PRVM_G_FLOAT(OFS_PARM3)*255.0f); + volume = PRVM_G_FLOAT(OFS_PARM3); attenuation = PRVM_G_FLOAT(OFS_PARM4); - if (volume < 0 || volume > 255) + if (volume < 0 || volume > 1) { VM_Warning("VM_CL_sound: volume must be in range 0-1\n"); return; @@ -162,12 +182,42 @@ static void VM_CL_sound (void) S_StartSound(32768 + PRVM_NUM_FOR_EDICT(entity), channel, S_FindName(sample), entity->fields.client->origin, volume, attenuation); } +// #483 void(vector origin, string sample, float volume, float attenuation) pointsound +static void VM_CL_pointsound(void) +{ + const char *sample; + float volume; + float attenuation; + vec3_t org; + + VM_SAFEPARMCOUNT(4, VM_CL_pointsound); + + VectorCopy( PRVM_G_VECTOR(OFS_PARM0), org); + sample = PRVM_G_STRING(OFS_PARM1); + volume = PRVM_G_FLOAT(OFS_PARM2); + attenuation = PRVM_G_FLOAT(OFS_PARM3); + + if (volume < 0 || volume > 1) + { + VM_Warning("VM_CL_pointsound: volume must be in range 0-1\n"); + return; + } + + if (attenuation < 0 || attenuation > 4) + { + VM_Warning("VM_CL_pointsound: attenuation must be in range 0-4\n"); + return; + } + + // Send World Entity as Entity to Play Sound (for CSQC, that is 32768) + S_StartSound(32768, 0, S_FindName(sample), org, volume, attenuation); +} + // #14 entity() spawn static void VM_CL_spawn (void) { prvm_edict_t *ed; ed = PRVM_ED_Alloc(); - ed->fields.client->entnum = PRVM_NUM_FOR_EDICT(ed); //[515]: not needed any more ? VM_RETURN_EDICT(ed); } @@ -179,7 +229,7 @@ static void VM_CL_traceline (void) int move; prvm_edict_t *ent; - VM_SAFEPARMCOUNTRANGE(4, 8, VM_CL_traceline); // allow more parameters for future expansion + VM_SAFEPARMCOUNTRANGE(4, 4, VM_CL_traceline); prog->xfunction->builtinsprofile += 30; @@ -304,7 +354,7 @@ static void VM_CL_tracetoss (void) // #20 void(string s) precache_model -static void VM_CL_precache_model (void) +void VM_CL_precache_model (void) { const char *name; int i; @@ -313,7 +363,7 @@ static void VM_CL_precache_model (void) VM_SAFEPARMCOUNT(1, VM_CL_precache_model); name = PRVM_G_STRING(OFS_PARM0); - for (i = 1;i < MAX_MODELS && cl.csqc_model_precache[i];i++) + for (i = 0;i < MAX_MODELS && cl.csqc_model_precache[i];i++) { if(!strcmp(cl.csqc_model_precache[i]->name, name)) { @@ -325,7 +375,7 @@ static void VM_CL_precache_model (void) m = Mod_ForName(name, false, false, false); if(m && m->loaded) { - for (i = 1;i < MAX_MODELS;i++) + for (i = 0;i < MAX_MODELS;i++) { if (!cl.csqc_model_precache[i]) { @@ -606,33 +656,33 @@ extern qboolean CSQC_AddRenderEdict (prvm_edict_t *ed);//csprogs.c static void CSQC_R_RecalcView (void) { extern matrix4x4_t viewmodelmatrix; - Matrix4x4_CreateFromQuakeEntity(&r_view.matrix, cl.csqc_origin[0], cl.csqc_origin[1], cl.csqc_origin[2], cl.csqc_angles[0], cl.csqc_angles[1], cl.csqc_angles[2], 1); + Matrix4x4_CreateFromQuakeEntity(&r_refdef.view.matrix, cl.csqc_origin[0], cl.csqc_origin[1], cl.csqc_origin[2], cl.csqc_angles[0], cl.csqc_angles[1], cl.csqc_angles[2], 1); Matrix4x4_CreateFromQuakeEntity(&viewmodelmatrix, cl.csqc_origin[0], cl.csqc_origin[1], cl.csqc_origin[2], cl.csqc_angles[0], cl.csqc_angles[1], cl.csqc_angles[2], cl_viewmodel_scale.value); } 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 - r_refdef.numentities = 0; - r_refdef.numlights = 0; + r_refdef.scene.numentities = 0; + r_refdef.scene.numlights = 0; // FIXME: restore these to the values from VM_CL_UpdateView - r_view.x = 0; - r_view.y = 0; - r_view.z = 0; - r_view.width = vid.width; - r_view.height = vid.height; - r_view.depth = 1; + r_refdef.view.x = 0; + r_refdef.view.y = 0; + r_refdef.view.z = 0; + r_refdef.view.width = vid.width; + r_refdef.view.height = vid.height; + r_refdef.view.depth = 1; // FIXME: restore frustum_x/frustum_y - r_view.useperspective = true; - r_view.frustum_y = tan(scr_fov.value * M_PI / 360.0) * (3.0/4.0) * cl.viewzoom; - r_view.frustum_x = r_view.frustum_y * (float)r_view.width / (float)r_view.height / vid_pixelheight.value; - r_view.frustum_x *= r_refdef.frustumscale_x; - r_view.frustum_y *= r_refdef.frustumscale_y; - r_view.ortho_x = scr_fov.value * (3.0 / 4.0) * (float)r_view.width / (float)r_view.height / vid_pixelheight.value; - r_view.ortho_y = scr_fov.value * (3.0 / 4.0); + r_refdef.view.useperspective = true; + r_refdef.view.frustum_y = tan(scr_fov.value * M_PI / 360.0) * (3.0/4.0) * cl.viewzoom; + r_refdef.view.frustum_x = r_refdef.view.frustum_y * (float)r_refdef.view.width / (float)r_refdef.view.height / vid_pixelheight.value; + r_refdef.view.frustum_x *= r_refdef.frustumscale_x; + 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); // FIXME: restore cl.csqc_origin // FIXME: restore cl.csqc_angles cl.csqc_vidvars.drawworld = true; @@ -643,7 +693,7 @@ static void VM_CL_R_ClearScene (void) //#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; @@ -672,14 +722,14 @@ static void VM_CL_R_AddEntities (void) } //#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; @@ -693,85 +743,109 @@ static void VM_CL_R_SetView (void) switch(c) { - case VF_MIN: r_view.x = (int)(f[0] * vid.width / vid_conwidth.value); - r_view.y = (int)(f[1] * vid.height / vid_conheight.value); - break; - case VF_MIN_X: r_view.x = (int)(k * vid.width / vid_conwidth.value); - break; - case VF_MIN_Y: r_view.y = (int)(k * vid.height / vid_conheight.value); - break; - case VF_SIZE: r_view.width = (int)(f[0] * vid.width / vid_conwidth.value); - r_view.height = (int)(f[1] * vid.height / vid_conheight.value); - break; - case VF_SIZE_Y: r_view.width = (int)(k * vid.width / vid_conwidth.value); - break; - case VF_SIZE_X: r_view.height = (int)(k * vid.height / vid_conheight.value); - break; - case VF_VIEWPORT: r_view.x = (int)(f[0] * vid.width / vid_conwidth.value); - r_view.y = (int)(f[1] * vid.height / vid_conheight.value); - f = PRVM_G_VECTOR(OFS_PARM2); - r_view.width = (int)(f[0] * vid.width / vid_conwidth.value); - r_view.height = (int)(f[1] * vid.height / vid_conheight.value); - break; - case VF_FOV: r_view.frustum_x = tan(f[0] * M_PI / 360.0);r_view.ortho_x = f[0]; - r_view.frustum_y = tan(f[1] * M_PI / 360.0);r_view.ortho_y = f[1]; - break; - case VF_FOVX: r_view.frustum_x = tan(k * M_PI / 360.0);r_view.ortho_x = k; - break; - case VF_FOVY: r_view.frustum_y = tan(k * M_PI / 360.0);r_view.ortho_y = k; - break; - case VF_ORIGIN: VectorCopy(f, cl.csqc_origin); - CSQC_R_RecalcView(); - break; - case VF_ORIGIN_X: cl.csqc_origin[0] = k; - CSQC_R_RecalcView(); - break; - case VF_ORIGIN_Y: cl.csqc_origin[1] = k; - CSQC_R_RecalcView(); - break; - case VF_ORIGIN_Z: cl.csqc_origin[2] = k; - CSQC_R_RecalcView(); - break; - case VF_ANGLES: VectorCopy(f, cl.csqc_angles); - CSQC_R_RecalcView(); - break; - case VF_ANGLES_X: cl.csqc_angles[0] = k; - CSQC_R_RecalcView(); - break; - case VF_ANGLES_Y: cl.csqc_angles[1] = k; - CSQC_R_RecalcView(); - break; - case VF_ANGLES_Z: cl.csqc_angles[2] = k; - CSQC_R_RecalcView(); - break; - case VF_DRAWWORLD: cl.csqc_vidvars.drawworld = k; - break; - case VF_DRAWENGINESBAR: cl.csqc_vidvars.drawenginesbar = k; - break; - case VF_DRAWCROSSHAIR: cl.csqc_vidvars.drawcrosshair = k; - break; - - case VF_CL_VIEWANGLES: VectorCopy(f, cl.viewangles); - break; - case VF_CL_VIEWANGLES_X:cl.viewangles[0] = k; - break; - case VF_CL_VIEWANGLES_Y:cl.viewangles[1] = k; - break; - case VF_CL_VIEWANGLES_Z:cl.viewangles[2] = k; - break; - - case VF_PERSPECTIVE: r_view.useperspective = k != 0; - break; - - default: PRVM_G_FLOAT(OFS_RETURN) = 0; - VM_Warning("VM_CL_R_SetView : unknown parm %i\n", c); - return; + case VF_MIN: + r_refdef.view.x = (int)(f[0] * vid.width / vid_conwidth.value); + r_refdef.view.y = (int)(f[1] * vid.height / vid_conheight.value); + break; + case VF_MIN_X: + r_refdef.view.x = (int)(k * vid.width / vid_conwidth.value); + break; + case VF_MIN_Y: + r_refdef.view.y = (int)(k * vid.height / vid_conheight.value); + break; + case VF_SIZE: + 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: + r_refdef.view.width = (int)(k * vid.width / vid_conwidth.value); + break; + case VF_SIZE_X: + r_refdef.view.height = (int)(k * vid.height / vid_conheight.value); + break; + case VF_VIEWPORT: + r_refdef.view.x = (int)(f[0] * vid.width / vid_conwidth.value); + r_refdef.view.y = (int)(f[1] * vid.height / vid_conheight.value); + f = PRVM_G_VECTOR(OFS_PARM2); + 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_FOV: + r_refdef.view.frustum_x = tan(f[0] * M_PI / 360.0);r_refdef.view.ortho_x = f[0]; + r_refdef.view.frustum_y = tan(f[1] * M_PI / 360.0);r_refdef.view.ortho_y = f[1]; + break; + case VF_FOVX: + r_refdef.view.frustum_x = tan(k * M_PI / 360.0);r_refdef.view.ortho_x = k; + break; + case VF_FOVY: + r_refdef.view.frustum_y = tan(k * M_PI / 360.0);r_refdef.view.ortho_y = k; + break; + case VF_ORIGIN: + VectorCopy(f, cl.csqc_origin); + CSQC_R_RecalcView(); + break; + case VF_ORIGIN_X: + cl.csqc_origin[0] = k; + CSQC_R_RecalcView(); + break; + case VF_ORIGIN_Y: + cl.csqc_origin[1] = k; + CSQC_R_RecalcView(); + break; + case VF_ORIGIN_Z: + cl.csqc_origin[2] = k; + CSQC_R_RecalcView(); + break; + case VF_ANGLES: + VectorCopy(f, cl.csqc_angles); + CSQC_R_RecalcView(); + break; + case VF_ANGLES_X: + cl.csqc_angles[0] = k; + CSQC_R_RecalcView(); + break; + case VF_ANGLES_Y: + cl.csqc_angles[1] = k; + CSQC_R_RecalcView(); + break; + case VF_ANGLES_Z: + cl.csqc_angles[2] = k; + CSQC_R_RecalcView(); + break; + case VF_DRAWWORLD: + cl.csqc_vidvars.drawworld = k; + break; + case VF_DRAWENGINESBAR: + cl.csqc_vidvars.drawenginesbar = k; + break; + case VF_DRAWCROSSHAIR: + cl.csqc_vidvars.drawcrosshair = k; + break; + case VF_CL_VIEWANGLES: + VectorCopy(f, cl.viewangles); + break; + case VF_CL_VIEWANGLES_X: + cl.viewangles[0] = k; + break; + case VF_CL_VIEWANGLES_Y: + cl.viewangles[1] = k; + break; + case VF_CL_VIEWANGLES_Z: + cl.viewangles[2] = k; + break; + case VF_PERSPECTIVE: + r_refdef.view.useperspective = k != 0; + break; + default: + PRVM_G_FLOAT(OFS_RETURN) = 0; + VM_Warning("VM_CL_R_SetView : unknown parm %i\n", c); + return; } PRVM_G_FLOAT(OFS_RETURN) = 1; } //#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 @@ -782,20 +856,20 @@ static void VM_CL_R_RenderScene (void) } //#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; - VM_SAFEPARMCOUNTRANGE(3, 8, VM_CL_R_AddDynamicLight); // allow more than 3 because we may extend this in the future + VM_SAFEPARMCOUNTRANGE(3, 3, VM_CL_R_AddDynamicLight); // if we've run out of dlights, just return - if (r_refdef.numlights >= MAX_DLIGHTS) + if (r_refdef.scene.numlights >= MAX_DLIGHTS) return; pos = PRVM_G_VECTOR(OFS_PARM0); 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.lights[r_refdef.numlights++], false, &matrix, col, -1, NULL, true, 1, 0.25, 0, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE); + 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); } //============================================================================ @@ -808,8 +882,8 @@ static void VM_CL_unproject (void) VM_SAFEPARMCOUNT(1, VM_CL_unproject); f = PRVM_G_VECTOR(OFS_PARM0); - VectorSet(temp, f[2], f[0] * f[2] * -r_view.frustum_x * 2.0 / r_view.width, f[1] * f[2] * -r_view.frustum_y * 2.0 / r_view.height); - Matrix4x4_Transform(&r_view.matrix, temp, PRVM_G_VECTOR(OFS_RETURN)); + VectorSet(temp, f[2], f[0] * f[2] * -r_refdef.view.frustum_x * 2.0 / r_refdef.view.width, f[1] * f[2] * -r_refdef.view.frustum_y * 2.0 / r_refdef.view.height); + Matrix4x4_Transform(&r_refdef.view.matrix, temp, PRVM_G_VECTOR(OFS_RETURN)); } //#311 vector (vector v) cs_project (EXT_CSQC) @@ -821,9 +895,9 @@ static void VM_CL_project (void) VM_SAFEPARMCOUNT(1, VM_CL_project); f = PRVM_G_VECTOR(OFS_PARM0); - Matrix4x4_Invert_Simple(&m, &r_view.matrix); + Matrix4x4_Invert_Simple(&m, &r_refdef.view.matrix); Matrix4x4_Transform(&m, f, v); - VectorSet(PRVM_G_VECTOR(OFS_RETURN), v[1]/v[0]/-r_view.frustum_x*0.5*r_view.width, v[2]/v[0]/-r_view.frustum_y*r_view.height*0.5, v[0]); + VectorSet(PRVM_G_VECTOR(OFS_RETURN), v[1]/v[0]/-r_refdef.view.frustum_x*0.5*r_refdef.view.width, v[2]/v[0]/-r_refdef.view.frustum_y*r_refdef.view.height*0.5, v[0]); } //#330 float(float stnum) getstatf (EXT_CSQC) @@ -924,6 +998,14 @@ static void VM_CL_setmodelindex (void) } 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) @@ -990,7 +1072,7 @@ static void VM_CL_setcursormode (void) { VM_SAFEPARMCOUNT(1, VM_CL_setcursormode); cl.csqc_wantsmousemove = PRVM_G_FLOAT(OFS_PARM0); - cl_ignoremousemove = true; + cl_ignoremousemoves = 2; } //#345 float(float framenum) getinputstate (EXT_CSQC) @@ -1059,6 +1141,9 @@ static void VM_CL_getplayerkey (void) else if(!strcasecmp(c, "ping")) sprintf(t, "%i", cl.scores[i].qw_ping); + else + if(!strcasecmp(c, "pl")) + sprintf(t, "%i", cl.scores[i].qw_packetloss); else if(!strcasecmp(c, "entertime")) sprintf(t, "%f", cl.scores[i].qw_entertime); @@ -1196,12 +1281,12 @@ static void VM_CL_makestatic (void) entity_t *staticent = &cl.static_entities[cl.num_static_entities++]; // copy it to the current state + memset(staticent, 0, sizeof(*staticent)); staticent->render.model = CL_GetModelByIndex((int)ent->fields.client->modelindex); staticent->render.frame1 = staticent->render.frame2 = (int)ent->fields.client->frame; staticent->render.framelerp = 0; // make torchs play out of sync staticent->render.frame1time = staticent->render.frame2time = lhrandom(-10, -1); - staticent->render.colormap = (int)ent->fields.client->colormap; // no special coloring staticent->render.skinnum = (int)ent->fields.client->skin; staticent->render.effects = (int)ent->fields.client->effects; staticent->render.alpha = 1; @@ -1221,7 +1306,6 @@ static void VM_CL_makestatic (void) } else Matrix4x4_CreateFromQuakeEntity(&staticent->render.matrix, ent->fields.client->origin[0], ent->fields.client->origin[1], ent->fields.client->origin[2], ent->fields.client->angles[0], ent->fields.client->angles[1], ent->fields.client->angles[2], staticent->render.scale); - CL_UpdateRenderEntity(&staticent->render); // either fullbright or lit if (!(staticent->render.effects & EF_FULLBRIGHT) && !r_fullbright.integer) @@ -1229,6 +1313,8 @@ static void VM_CL_makestatic (void) // turn off shadows from transparent objects if (!(staticent->render.effects & (EF_NOSHADOW | EF_ADDITIVE | EF_NODEPTHTEST)) && (staticent->render.alpha >= 1)) staticent->render.flags |= RENDER_SHADOW; + + CL_UpdateRenderEntity(&staticent->render); } else Con_Printf("Too many static entities"); @@ -1618,7 +1704,7 @@ static void VM_CL_te_explosion2 (void) colorLength = (int)PRVM_G_FLOAT(OFS_PARM2); CL_FindNonSolidLocation(pos, pos2, 10); CL_ParticleExplosion2(pos2, colorStart, colorLength); - tempcolor = (unsigned char *)&palette_complete[(rand()%colorLength) + colorStart]; + tempcolor = palette_rgb[(rand()%colorLength) + colorStart]; color[0] = tempcolor[0] * (2.0f / 255.0f); color[1] = tempcolor[1] * (2.0f / 255.0f); color[2] = tempcolor[2] * (2.0f / 255.0f); @@ -1730,7 +1816,81 @@ static void VM_CL_getsurfacepoint(void) // FIXME: implement rotation/scaling VectorAdd(&(model->surfmesh.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed->fields.client->origin, PRVM_G_VECTOR(OFS_RETURN)); } +//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_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; +// TODO: add some wrapper code and merge VM_CL/SV_getsurface* [12/16/2007 Black] +static void VM_CL_getsurfacepointattribute(void) +{ + prvm_edict_t *ed; + model_t *model; + msurface_t *surface; + int pointnum; + int attributetype; + 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)))) + return; + // note: this (incorrectly) assumes it is a simple polygon + pointnum = (int)PRVM_G_FLOAT(OFS_PARM2); + if (pointnum < 0 || pointnum >= surface->num_vertices) + return; + + // FIXME: implement rotation/scaling + attributetype = (int) PRVM_G_FLOAT(OFS_PARM3); + + 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)); + 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_T_AXIS = 2; + case 2: + VectorCopy(&(model->surfmesh.data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], PRVM_G_VECTOR(OFS_RETURN)); + break; + // 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_TEXCOORDS0 = 4; + case 4: { + float *ret = PRVM_G_VECTOR(OFS_RETURN); + float *texcoord = &(model->surfmesh.data_texcoordtexture2f + 2 * surface->num_firstvertex)[pointnum * 2]; + ret[0] = texcoord[0]; + ret[1] = texcoord[1]; + ret[2] = 0.0f; + break; + } + // float SPA_LIGHTMAP0_TEXCOORDS = 5; + case 5: { + float *ret = PRVM_G_VECTOR(OFS_RETURN); + float *texcoord = &(model->surfmesh.data_texcoordlightmap2f + 2 * surface->num_firstvertex)[pointnum * 2]; + ret[0] = texcoord[0]; + ret[1] = texcoord[1]; + ret[2] = 0.0f; + break; + } + // float SPA_LIGHTMAP0_COLOR = 6; + case 6: + // ignore alpha for now.. + 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 ); + break; + } +} // #436 vector(entity e, float s) getsurfacenormal static void VM_CL_getsurfacenormal(void) { @@ -1907,6 +2067,7 @@ int CL_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex) matrix4x4_t entitymatrix, tagmatrix, attachmatrix; prvm_edict_t *attachent; model_t *model; + float scale; *out = identitymatrix; // warnings and errors return identical matrix @@ -1951,10 +2112,11 @@ int CL_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex) attachmatrix = identitymatrix; // apply transformation by child entity matrix + scale = 1; val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale); - if (val->_float == 0) - val->_float = 1; - Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->fields.client->origin[0], ent->fields.client->origin[1], ent->fields.client->origin[2], -ent->fields.client->angles[0], ent->fields.client->angles[1], ent->fields.client->angles[2], val->_float); + if (val && val->_float != 0) + scale = val->_float; + Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->fields.client->origin[0], ent->fields.client->origin[1], ent->fields.client->origin[2], -ent->fields.client->angles[0], ent->fields.client->angles[1], ent->fields.client->angles[2], scale); Matrix4x4_Concat(out, &entitymatrix, &tagmatrix); Matrix4x4_Copy(&tagmatrix, out); @@ -1971,22 +2133,24 @@ int CL_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex) } // normal or RENDER_VIEWMODEL entity (or main parent entity on attach chain) + scale = 1; val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale); - if (val->_float == 0) - val->_float = 1; + if (val && val->_float != 0) + scale = val->_float; // Alias models have inverse pitch, bmodels can't have tags, so don't check for modeltype... - Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->fields.client->origin[0], ent->fields.client->origin[1], ent->fields.client->origin[2], -ent->fields.client->angles[0], ent->fields.client->angles[1], ent->fields.client->angles[2], val->_float); + Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->fields.client->origin[0], ent->fields.client->origin[1], ent->fields.client->origin[2], -ent->fields.client->angles[0], ent->fields.client->angles[1], ent->fields.client->angles[2], scale); Matrix4x4_Concat(out, &entitymatrix, &tagmatrix); if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.renderflags)) && (RF_VIEWMODEL & (int)val->_float)) {// RENDER_VIEWMODEL magic Matrix4x4_Copy(&tagmatrix, out); + scale = 1; val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale); - if (val->_float == 0) - val->_float = 1; + if (val && val->_float != 0) + scale = val->_float; - Matrix4x4_CreateFromQuakeEntity(&entitymatrix, cl.csqc_origin[0], cl.csqc_origin[1], cl.csqc_origin[2], cl.csqc_angles[0], cl.csqc_angles[1], cl.csqc_angles[2], val->_float); + Matrix4x4_CreateFromQuakeEntity(&entitymatrix, cl.csqc_origin[0], cl.csqc_origin[1], cl.csqc_origin[2], cl.csqc_angles[0], cl.csqc_angles[1], cl.csqc_angles[2], scale); Matrix4x4_Concat(out, &entitymatrix, &tagmatrix); /* @@ -2038,10 +2202,8 @@ static void VM_CL_gettagindex (void) } modelindex = (int)ent->fields.client->modelindex; - if(modelindex < 0) - modelindex = -(modelindex+1); tag_index = 0; - if (modelindex <= 0 || modelindex >= MAX_MODELS) + if (modelindex >= MAX_MODELS || (modelindex <= -MAX_MODELS /* client models */)) Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent)); else { @@ -2100,13 +2262,17 @@ typedef struct 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) @@ -2114,24 +2280,26 @@ static qboolean vm_polygonbegin = false; //[515]: for "no-crap-on-the-screen" #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) @@ -2206,7 +2374,6 @@ static void VM_CL_AddPolygonTo2DScene (vm_polygon_t *p) { 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; @@ -2228,50 +2395,59 @@ static void VM_CL_AddPolygonTo2DScene (vm_polygon_t *p) DrawQ_Mesh (&mesh, (p->flags&0x0f)); } +// TODO: move this into the client code and clean-up everything else, too! [1/6/2008 Black] void VM_CL_AddPolygonsToMeshQueue (void) { int i; - if(!vm_drawpolygons_num) + vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr(); + + // 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) 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)) @@ -2285,13 +2461,15 @@ static void VM_CL_R_PolygonBegin (void) } //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; @@ -2301,86 +2479,90 @@ static void VM_CL_R_PolygonVertex (void) 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) @@ -2394,57 +2576,57 @@ void Debug_PolygonVertex(float x, float y, float z, float s, float t, float r, f { 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); } /* @@ -2711,6 +2893,13 @@ void VM_CL_serverkey(void) //============================================================================ +// 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) @@ -2728,7 +2917,7 @@ VM_vlen, // #12 float(vector v) vlen (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) @@ -2744,7 +2933,7 @@ VM_coredump, // #28 void() coredump (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) @@ -3024,7 +3213,7 @@ VM_CL_R_AddDynamicLight, // #305 void(vector org, float radius, vector lightcol 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 @@ -3041,9 +3230,9 @@ VM_drawpic, // #322 float(vector position, string pic, vector size, vector VM_drawfill, // #323 float(vector position, vector size, vector rgb, float alpha, float flag) drawfill (EXT_CSQC) VM_drawsetcliparea, // #324 void(float x, float y, float width, float height) drawsetcliparea VM_drawresetcliparea, // #325 void(void) drawresetcliparea -NULL, // #326 -NULL, // #327 -NULL, // #328 +VM_drawcolorcodedstring, // #326 float drawcolorcodedstring(vector position, string text, vector scale, vector rgb, float alpha, float flag) (EXT_CSQC) +NULL, // #327 // FIXME add stringwidth() here? +NULL, // #328 // FIXME add drawsubpic() here? NULL, // #329 VM_CL_getstatf, // #330 float(float stnum) getstatf (EXT_CSQC) VM_CL_getstati, // #331 float(float stnum) getstati (EXT_CSQC) @@ -3061,7 +3250,7 @@ VM_CL_getkeybind, // #342 string(float keynum) getkeybind (EXT_CSQC) 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) @@ -3083,7 +3272,7 @@ VM_CL_ReadCoord, // #364 float() readcoord (EXT_CSQC) VM_CL_ReadAngle, // #365 float() readangle (EXT_CSQC) VM_CL_ReadString, // #366 string() readstring (EXT_CSQC) VM_CL_ReadFloat, // #367 float() readfloat (EXT_CSQC) -NULL, // #368 +NULL, // #368 NULL, // #369 NULL, // #370 NULL, // #371 @@ -3173,7 +3362,7 @@ NULL, // #453 void(entity clent) dropclient (DP_SV_DROPCLIENT) 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) @@ -3199,18 +3388,18 @@ VM_tokenizebyseparator, // #479 float(string s) tokenizebyseparator (DP_QC_TOK 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) -NULL, // #483 -NULL, // #484 -NULL, // #485 -NULL, // #486 -NULL, // #487 -NULL, // #488 -NULL, // #489 -NULL, // #490 -NULL, // #491 -NULL, // #492 -NULL, // #493 -NULL, // #494 +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 +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_keyevent, // #490 float gecko_keyevent( string name, float key, float eventtype ) +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 ) +VM_crc16, // #494 float(float caseinsensitive, string s, ...) crc16 = #494 (DP_QC_CRC16) NULL, // #495 NULL, // #496 NULL, // #497 @@ -3220,22 +3409,28 @@ NULL, // #499 const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t); -void VM_CL_Cmd_Init(void) +void VM_Polygons_Reset(void) { + 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) { - if(vm_polygons_initialized) - { - Mem_FreePool(&vm_polygons_pool); - vm_polygons_initialized = false; - } + VM_Cmd_Reset(); + VM_Polygons_Reset(); } +