X-Git-Url: http://git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=clvm_cmds.c;h=2a2cefa68a67f07024856b4f513eae87c56bbb55;hp=e218878e200f86578cb4309304aeac5c6390291e;hb=7ea07939bef0cbe85c54d9f68cb924198b0b1f64;hpb=9d6f77621de650ffaaecb65a3485d51378632925 diff --git a/clvm_cmds.c b/clvm_cmds.c index e218878e..2a2cefa6 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -21,7 +21,6 @@ //4 feature darkplaces csqc: add builtins to clientside qc for gl calls extern cvar_t v_flipped; -extern cvar_t r_equalize_entities_fullbright; r_refdef_view_t csqc_original_r_refdef_view; r_refdef_view_t csqc_main_r_refdef_view; @@ -51,7 +50,7 @@ static void VM_CL_setorigin (prvm_prog_t *prog) VM_Warning(prog, "setorigin: can not modify world entity\n"); return; } - if (e->priv.required->free) + if (e->free) { VM_Warning(prog, "setorigin: can not modify free entity\n"); return; @@ -92,7 +91,7 @@ static void VM_CL_setmodel (prvm_prog_t *prog) { prvm_edict_t *e; const char *m; - dp_model_t *mod; + model_t *mod; int i; VM_SAFEPARMCOUNT(2, VM_CL_setmodel); @@ -129,7 +128,7 @@ static void VM_CL_setmodel (prvm_prog_t *prog) if( mod ) { // TODO: check if this breaks needed consistency and maybe add a cvar for it too?? [1/10/2008 Black] - // LordHavoc: erm you broke it by commenting this out - setmodel must do setsize or else the qc can't find out the model size, and ssqc does this by necessity, consistency. + // LadyHavoc: erm you broke it by commenting this out - setmodel must do setsize or else the qc can't find out the model size, and ssqc does this by necessity, consistency. SetMinMaxSize (prog, e, mod->normalmins, mod->normalmaxs); } else @@ -152,7 +151,7 @@ static void VM_CL_setsize (prvm_prog_t *prog) VM_Warning(prog, "setsize: can not modify world entity\n"); return; } - if (e->priv.server->free) + if (e->free) { VM_Warning(prog, "setsize: can not modify free entity\n"); return; @@ -207,7 +206,7 @@ static void VM_CL_sound (prvm_prog_t *prog) flags = 0; else { - // LordHavoc: we only let the qc set certain flags, others are off-limits + // LadyHavoc: we only let the qc set certain flags, others are off-limits flags = (int)PRVM_G_FLOAT(OFS_PARM6) & (CHANNELFLAG_RELIABLE | CHANNELFLAG_FORCELOOP | CHANNELFLAG_PAUSED | CHANNELFLAG_FULLVOLUME); } @@ -220,8 +219,6 @@ static void VM_CL_sound (prvm_prog_t *prog) else startposition = 0; - channel = CHAN_USER2ENGINE(channel); - if (!IS_CHAN(channel)) { VM_Warning(prog, "VM_CL_sound: channel must be in range 0-127\n"); @@ -319,7 +316,7 @@ if the tryents flag is set. tracebox (vector1, vector mins, vector maxs, vector2, tryents) ================= */ -// LordHavoc: added this for my own use, VERY useful, similar to traceline +// LadyHavoc: added this for my own use, VERY useful, similar to traceline static void VM_CL_tracebox (prvm_prog_t *prog) { vec3_t v1, v2, m1, m2; @@ -369,7 +366,7 @@ static trace_t CL_Trace_Toss (prvm_prog_t *prog, prvm_edict_t *tossent, prvm_edi gravity = 1.0f; gravity *= cl.movevars_gravity * 0.05; - for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds + for (i = 0;i < 200;i++) // LadyHavoc: sanity check; never trace more than 10 seconds { PRVM_clientedictvector(tossent, velocity)[2] -= gravity; VectorMA (PRVM_clientedictvector(tossent, angles), 0.05, PRVM_clientedictvector(tossent, avelocity), PRVM_clientedictvector(tossent, angles)); @@ -423,7 +420,7 @@ static void VM_CL_precache_model (prvm_prog_t *prog) { const char *name; int i; - dp_model_t *m; + model_t *m; VM_SAFEPARMCOUNT(1, VM_CL_precache_model); @@ -444,7 +441,7 @@ static void VM_CL_precache_model (prvm_prog_t *prog) { if (!cl.csqc_model_precache[i]) { - cl.csqc_model_precache[i] = (dp_model_t*)m; + cl.csqc_model_precache[i] = (model_t*)m; PRVM_G_FLOAT(OFS_RETURN) = -(i+1); return; } @@ -500,7 +497,7 @@ static void VM_CL_findradius (prvm_prog_t *prog) // (note: this is the reason you can't blow up fallen zombies) if (PRVM_clientedictfloat(ent, solid) == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer) continue; - // LordHavoc: compare against bounding box rather than center so it + // LadyHavoc: compare against bounding box rather than center so it // doesn't miss large objects, and use DotProduct instead of Length // for a major speedup VectorSubtract(org, PRVM_clientedictvector(ent, origin), eorg); @@ -540,7 +537,7 @@ static void VM_CL_droptofloor (prvm_prog_t *prog) VM_Warning(prog, "droptofloor: can not modify world entity\n"); return; } - if (ent->priv.server->free) + if (ent->free) { VM_Warning(prog, "droptofloor: can not modify free entity\n"); return; @@ -686,8 +683,8 @@ static void VM_CL_ambientsound (prvm_prog_t *prog) vec3_t f; sfx_t *s; VM_SAFEPARMCOUNT(4, VM_CL_ambientsound); - s = S_FindName(PRVM_G_STRING(OFS_PARM0)); - VectorCopy(PRVM_G_VECTOR(OFS_PARM1), f); + VectorCopy(PRVM_G_VECTOR(OFS_PARM0), f); + s = S_FindName(PRVM_G_STRING(OFS_PARM1)); S_StaticSound (s, f, PRVM_G_FLOAT(OFS_PARM2), PRVM_G_FLOAT(OFS_PARM3)*64); } @@ -744,6 +741,8 @@ static void VM_CL_R_ClearScene (prvm_prog_t *prog) cl.csqc_vidvars.drawenginesbar = false; cl.csqc_vidvars.drawcrosshair = false; CSQC_R_RecalcView(); + // clear the CL_Mesh_Scene() used for CSQC polygons and engine effects, they will be added by CSQC_RelinkAllEntities and manually created by CSQC + CL_MeshEntities_Scene_Clear(); } //#301 void(float mask) addentities (EXT_CSQC) @@ -762,14 +761,14 @@ static void VM_CL_R_AddEntities (prvm_prog_t *prog) // so we can easily check if CSQC entity #edictnum is currently drawn cl.csqcrenderentities[i].entitynumber = 0; ed = &prog->edicts[i]; - if(ed->priv.required->free) + if(ed->free) continue; CSQC_Think(ed); - if(ed->priv.required->free) + if(ed->free) continue; // note that for RF_USEAXIS entities, Predraw sets v_forward/v_right/v_up globals that are read by CSQC_AddRenderEdict CSQC_Predraw(ed); - if(ed->priv.required->free) + if(ed->free) continue; if(!((int)PRVM_clientedictfloat(ed, drawmask) & drawmask)) continue; @@ -1104,7 +1103,7 @@ static void VM_CL_R_AddDynamicLight (prvm_prog_t *prog) int pflags = PFLAGS_CORONA | PFLAGS_FULLDYNAMIC; float coronaintensity = 1; float coronasizescale = 0.25; - qboolean castshadow = true; + qbool castshadow = true; float ambientscale = 0; float diffusescale = 1; float specularscale = 1; @@ -1189,6 +1188,781 @@ static void VM_CL_project (prvm_prog_t *prog) // as 2D drawing honors the viewport too, to get the same pixel, we simply multiply this by conwidth/height } +//============================================================================= +// Draw builtins (client & menu) + +/* +======================== +VM_drawline + +void drawline(float width, vector pos1, vector pos2, vector rgb, float alpha, float flags) +======================== +*/ +void VM_drawline (prvm_prog_t *prog) +{ + prvm_vec_t *c1, *c2, *rgb; + float alpha, width; + unsigned char flags; + + VM_SAFEPARMCOUNT(6, VM_drawline); + + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + + width = PRVM_G_FLOAT(OFS_PARM0); + c1 = PRVM_G_VECTOR(OFS_PARM1); + c2 = PRVM_G_VECTOR(OFS_PARM2); + rgb = PRVM_G_VECTOR(OFS_PARM3); + alpha = PRVM_G_FLOAT(OFS_PARM4); + flags = (int)PRVM_G_FLOAT(OFS_PARM5); + DrawQ_Line(width, c1[0], c1[1], c2[0], c2[1], rgb[0], rgb[1], rgb[2], alpha, flags); +} + +/* +========= +VM_iscachedpic + +float iscachedpic(string pic) +========= +*/ +void VM_iscachedpic(prvm_prog_t *prog) +{ + VM_SAFEPARMCOUNT(1,VM_iscachedpic); + + // drawq hasnt such a function, thus always return true + PRVM_G_FLOAT(OFS_RETURN) = false; +} + +/* +========= +VM_precache_pic + +string precache_pic(string pic) +========= +*/ +#define PRECACHE_PIC_FROMWAD 1 /* FTEQW, not supported here */ +#define PRECACHE_PIC_NOTPERSISTENT 2 +//#define PRECACHE_PIC_NOCLAMP 4 +#define PRECACHE_PIC_MIPMAP 8 +void VM_precache_pic(prvm_prog_t *prog) +{ + const char *s; + int flags = CACHEPICFLAG_FAILONMISSING; + + VM_SAFEPARMCOUNTRANGE(1, 2, VM_precache_pic); + + s = PRVM_G_STRING(OFS_PARM0); + PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0); + VM_CheckEmptyString(prog, s); + + if(prog->argc >= 2) + { + int f = PRVM_G_FLOAT(OFS_PARM1); + if(f & PRECACHE_PIC_NOTPERSISTENT) + flags |= CACHEPICFLAG_NOTPERSISTENT; + //if(f & PRECACHE_PIC_NOCLAMP) + // flags |= CACHEPICFLAG_NOCLAMP; + if(f & PRECACHE_PIC_MIPMAP) + flags |= CACHEPICFLAG_MIPMAP; + } + + if( !Draw_IsPicLoaded(Draw_CachePic_Flags(s, flags | CACHEPICFLAG_QUIET)) ) + PRVM_G_INT(OFS_RETURN) = OFS_NULL; +} + +/* +========= +VM_freepic + +freepic(string s) +========= +*/ +void VM_freepic(prvm_prog_t *prog) +{ + const char *s; + + VM_SAFEPARMCOUNT(1,VM_freepic); + + s = PRVM_G_STRING(OFS_PARM0); + VM_CheckEmptyString(prog, s); + + Draw_FreePic(s); +} + +static void getdrawfontscale(prvm_prog_t *prog, float *sx, float *sy) +{ + vec3_t v; + *sx = *sy = 1; + VectorCopy(PRVM_drawglobalvector(drawfontscale), v); + if(VectorLength2(v) > 0) + { + *sx = v[0]; + *sy = v[1]; + } +} + +static dp_font_t *getdrawfont(prvm_prog_t *prog) +{ + int f = (int) PRVM_drawglobalfloat(drawfont); + if(f < 0 || f >= dp_fonts.maxsize) + return FONT_DEFAULT; + return &dp_fonts.f[f]; +} + +/* +========= +VM_drawcharacter + +float drawcharacter(vector position, float character, vector scale, vector rgb, float alpha, float flag) +========= +*/ +void VM_drawcharacter(prvm_prog_t *prog) +{ + prvm_vec_t *pos,*scale,*rgb; + char character; + int flag; + float sx, sy; + VM_SAFEPARMCOUNT(6,VM_drawcharacter); + + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + + character = (char) PRVM_G_FLOAT(OFS_PARM1); + if(character == 0) + { + PRVM_G_FLOAT(OFS_RETURN) = -1; + VM_Warning(prog, "VM_drawcharacter: %s passed null character !\n",prog->name); + return; + } + + pos = PRVM_G_VECTOR(OFS_PARM0); + scale = PRVM_G_VECTOR(OFS_PARM2); + rgb = PRVM_G_VECTOR(OFS_PARM3); + flag = (int)PRVM_G_FLOAT(OFS_PARM5); + + if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS) + { + PRVM_G_FLOAT(OFS_RETURN) = -2; + VM_Warning(prog, "VM_drawcharacter: %s: wrong DRAWFLAG %i !\n",prog->name,flag); + return; + } + + if(pos[2] || scale[2]) + VM_Warning(prog, "VM_drawcharacter: z value%c from %s discarded\n",(pos[2] && scale[2]) ? 's' : 0,((pos[2] && scale[2]) ? "pos and scale" : (pos[2] ? "pos" : "scale"))); + + if(!scale[0] || !scale[1]) + { + PRVM_G_FLOAT(OFS_RETURN) = -3; + VM_Warning(prog, "VM_drawcharacter: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y"); + return; + } + + getdrawfontscale(prog, &sx, &sy); + DrawQ_String_Scale(pos[0], pos[1], &character, 1, scale[0], scale[1], sx, sy, rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag, NULL, true, getdrawfont(prog)); + PRVM_G_FLOAT(OFS_RETURN) = 1; +} + +/* +========= +VM_drawstring + +float drawstring(vector position, string text, vector scale, vector rgb, float alpha[, float flag]) +========= +*/ +void VM_drawstring(prvm_prog_t *prog) +{ + prvm_vec_t *pos,*scale,*rgb; + const char *string; + int flag = 0; + float sx, sy; + VM_SAFEPARMCOUNTRANGE(5,6,VM_drawstring); + + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + + string = PRVM_G_STRING(OFS_PARM1); + pos = PRVM_G_VECTOR(OFS_PARM0); + scale = PRVM_G_VECTOR(OFS_PARM2); + rgb = PRVM_G_VECTOR(OFS_PARM3); + if (prog->argc >= 6) + flag = (int)PRVM_G_FLOAT(OFS_PARM5); + + if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS) + { + PRVM_G_FLOAT(OFS_RETURN) = -2; + VM_Warning(prog, "VM_drawstring: %s: wrong DRAWFLAG %i !\n",prog->name,flag); + return; + } + + if(!scale[0] || !scale[1]) + { + PRVM_G_FLOAT(OFS_RETURN) = -3; + VM_Warning(prog, "VM_drawstring: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y"); + return; + } + + if(pos[2] || scale[2]) + VM_Warning(prog, "VM_drawstring: z value%s from %s discarded\n",(pos[2] && scale[2]) ? "s" : " ",((pos[2] && scale[2]) ? "pos and scale" : (pos[2] ? "pos" : "scale"))); + + getdrawfontscale(prog, &sx, &sy); + DrawQ_String_Scale(pos[0], pos[1], string, 0, scale[0], scale[1], sx, sy, rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag, NULL, true, getdrawfont(prog)); + //Font_DrawString(pos[0], pos[1], string, 0, scale[0], scale[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag, NULL, true); + PRVM_G_FLOAT(OFS_RETURN) = 1; +} + +/* +========= +VM_drawcolorcodedstring + +float drawcolorcodedstring(vector position, string text, vector scale, float alpha, float flag) +/ +float drawcolorcodedstring(vector position, string text, vector scale, vector rgb, float alpha, float flag) +========= +*/ +void VM_drawcolorcodedstring(prvm_prog_t *prog) +{ + prvm_vec_t *pos, *scale; + const char *string; + int flag; + vec3_t rgb; + float sx, sy, alpha; + + VM_SAFEPARMCOUNTRANGE(5,6,VM_drawcolorcodedstring); + + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + + if (prog->argc == 6) // full 6 parms, like normal drawstring + { + pos = PRVM_G_VECTOR(OFS_PARM0); + string = PRVM_G_STRING(OFS_PARM1); + scale = PRVM_G_VECTOR(OFS_PARM2); + VectorCopy(PRVM_G_VECTOR(OFS_PARM3), rgb); + alpha = PRVM_G_FLOAT(OFS_PARM4); + flag = (int)PRVM_G_FLOAT(OFS_PARM5); + } + else + { + pos = PRVM_G_VECTOR(OFS_PARM0); + string = PRVM_G_STRING(OFS_PARM1); + scale = PRVM_G_VECTOR(OFS_PARM2); + rgb[0] = 1.0; + rgb[1] = 1.0; + rgb[2] = 1.0; + alpha = PRVM_G_FLOAT(OFS_PARM3); + flag = (int)PRVM_G_FLOAT(OFS_PARM4); + } + + if(flag < DRAWFLAG_NORMAL || flag >= DRAWFLAG_NUMFLAGS) + { + PRVM_G_FLOAT(OFS_RETURN) = -2; + VM_Warning(prog, "VM_drawcolorcodedstring: %s: wrong DRAWFLAG %i !\n",prog->name,flag); + return; + } + + if(!scale[0] || !scale[1]) + { + PRVM_G_FLOAT(OFS_RETURN) = -3; + VM_Warning(prog, "VM_drawcolorcodedstring: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y"); + return; + } + + if(pos[2] || scale[2]) + VM_Warning(prog, "VM_drawcolorcodedstring: z value%s from %s discarded\n",(pos[2] && scale[2]) ? "s" : " ",((pos[2] && scale[2]) ? "pos and scale" : (pos[2] ? "pos" : "scale"))); + + getdrawfontscale(prog, &sx, &sy); + DrawQ_String_Scale(pos[0], pos[1], string, 0, scale[0], scale[1], sx, sy, rgb[0], rgb[1], rgb[2], alpha, flag, NULL, false, getdrawfont(prog)); + if (prog->argc == 6) // also return vector of last color + VectorCopy(DrawQ_Color, PRVM_G_VECTOR(OFS_RETURN)); + else + PRVM_G_FLOAT(OFS_RETURN) = 1; +} +/* +========= +VM_stringwidth + +float stringwidth(string text, float allowColorCodes, float size) +========= +*/ +void VM_stringwidth(prvm_prog_t *prog) +{ + const char *string; + vec2_t szv; + float mult; // sz is intended font size so we can later add freetype support, mult is font size multiplier in pixels per character cell + int colors; + float sx, sy; + size_t maxlen = 0; + VM_SAFEPARMCOUNTRANGE(2, 3, VM_stringwidth); + + getdrawfontscale(prog, &sx, &sy); + if(prog->argc == 3) + { + Vector2Copy(PRVM_G_VECTOR(OFS_PARM2), szv); + mult = 1; + } + else + { + // we want the width for 8x8 font size, divided by 8 + Vector2Set(szv, 8, 8); + mult = 0.125; + // to make sure snapping is turned off, ALWAYS use a nontrivial scale in this case + if(sx >= 0.9 && sx <= 1.1) + { + mult *= 2; + sx /= 2; + sy /= 2; + } + } + + string = PRVM_G_STRING(OFS_PARM0); + colors = (int)PRVM_G_FLOAT(OFS_PARM1); + + PRVM_G_FLOAT(OFS_RETURN) = DrawQ_TextWidth_UntilWidth_TrackColors_Scale(string, &maxlen, szv[0], szv[1], sx, sy, NULL, !colors, getdrawfont(prog), 1000000000) * mult; +/* + if(prog->argc == 3) + { + mult = sz = PRVM_G_FLOAT(OFS_PARM2); + } + else + { + sz = 8; + mult = 1; + } + + string = PRVM_G_STRING(OFS_PARM0); + colors = (int)PRVM_G_FLOAT(OFS_PARM1); + + PRVM_G_FLOAT(OFS_RETURN) = DrawQ_TextWidth(string, 0, !colors, getdrawfont()) * mult; // 1x1 characters, don't actually draw +*/ +} + +/* +========= +VM_findfont + +float findfont(string s) +========= +*/ + +static float getdrawfontnum(const char *fontname) +{ + int i; + + for(i = 0; i < dp_fonts.maxsize; ++i) + if(!strcmp(dp_fonts.f[i].title, fontname)) + return i; + return -1; +} + +void VM_findfont(prvm_prog_t *prog) +{ + VM_SAFEPARMCOUNT(1,VM_findfont); + PRVM_G_FLOAT(OFS_RETURN) = getdrawfontnum(PRVM_G_STRING(OFS_PARM0)); +} + +/* +========= +VM_loadfont + +float loadfont(string fontname, string fontmaps, string sizes, float slot) +========= +*/ + +void VM_loadfont(prvm_prog_t *prog) +{ + const char *fontname, *filelist, *sizes, *c, *cm; + char mainfont[MAX_QPATH]; + int i, numsizes; + float sz, scale, voffset; + dp_font_t *f; + + VM_SAFEPARMCOUNTRANGE(3,6,VM_loadfont); + + fontname = PRVM_G_STRING(OFS_PARM0); + if (!fontname[0]) + fontname = "default"; + + filelist = PRVM_G_STRING(OFS_PARM1); + if (!filelist[0]) + filelist = "gfx/conchars"; + + sizes = PRVM_G_STRING(OFS_PARM2); + if (!sizes[0]) + sizes = "10"; + + // find a font + f = NULL; + if (prog->argc >= 4) + { + i = PRVM_G_FLOAT(OFS_PARM3); + if (i >= 0 && i < dp_fonts.maxsize) + { + f = &dp_fonts.f[i]; + strlcpy(f->title, fontname, sizeof(f->title)); // replace name + } + } + if (!f) + f = FindFont(fontname, true); + if (!f) + { + PRVM_G_FLOAT(OFS_RETURN) = -1; + return; // something go wrong + } + + memset(f->fallbacks, 0, sizeof(f->fallbacks)); + memset(f->fallback_faces, 0, sizeof(f->fallback_faces)); + + // first font is handled "normally" + c = strchr(filelist, ':'); + cm = strchr(filelist, ','); + if(c && (!cm || c < cm)) + f->req_face = atoi(c+1); + else + { + f->req_face = 0; + c = cm; + } + if(!c || (c - filelist) > MAX_QPATH) + strlcpy(mainfont, filelist, sizeof(mainfont)); + else + { + memcpy(mainfont, filelist, c - filelist); + mainfont[c - filelist] = 0; + } + + // handle fallbacks + for(i = 0; i < MAX_FONT_FALLBACKS; ++i) + { + c = strchr(filelist, ','); + if(!c) + break; + filelist = c + 1; + if(!*filelist) + break; + c = strchr(filelist, ':'); + cm = strchr(filelist, ','); + if(c && (!cm || c < cm)) + f->fallback_faces[i] = atoi(c+1); + else + { + f->fallback_faces[i] = 0; // f->req_face; could make it stick to the default-font's face index + c = cm; + } + if(!c || (c-filelist) > MAX_QPATH) + { + strlcpy(f->fallbacks[i], filelist, sizeof(mainfont)); + } + else + { + memcpy(f->fallbacks[i], filelist, c - filelist); + f->fallbacks[i][c - filelist] = 0; + } + } + + // handle sizes + for(i = 0; i < MAX_FONT_SIZES; ++i) + f->req_sizes[i] = -1; + for (numsizes = 0,c = sizes;;) + { + if (!COM_ParseToken_VM_Tokenize(&c, 0)) + break; + sz = atof(com_token); + // detect crap size + if (sz < 0.001f || sz > 1000.0f) + { + VM_Warning(prog, "VM_loadfont: crap size %s", com_token); + continue; + } + // check overflow + if (numsizes == MAX_FONT_SIZES) + { + VM_Warning(prog, "VM_loadfont: MAX_FONT_SIZES = %i exceeded", MAX_FONT_SIZES); + break; + } + f->req_sizes[numsizes] = sz; + numsizes++; + } + + // additional scale/hoffset parms + scale = 1; + voffset = 0; + if (prog->argc >= 5) + { + scale = PRVM_G_FLOAT(OFS_PARM4); + if (scale <= 0) + scale = 1; + } + if (prog->argc >= 6) + voffset = PRVM_G_FLOAT(OFS_PARM5); + + // load + LoadFont(true, mainfont, f, scale, voffset); + + // return index of loaded font + PRVM_G_FLOAT(OFS_RETURN) = (f - dp_fonts.f); +} + +/* +========= +VM_drawpic + +float drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag) +========= +*/ +void VM_drawpic(prvm_prog_t *prog) +{ + const char *picname; + prvm_vec_t *size, *pos, *rgb; + int flag = 0; + + VM_SAFEPARMCOUNTRANGE(5,6,VM_drawpic); + + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + + picname = PRVM_G_STRING(OFS_PARM1); + VM_CheckEmptyString(prog, picname); + + // is pic cached ? no function yet for that + if(!1) + { + PRVM_G_FLOAT(OFS_RETURN) = -4; + VM_Warning(prog, "VM_drawpic: %s: %s not cached !\n", prog->name, picname); + return; + } + + pos = PRVM_G_VECTOR(OFS_PARM0); + size = PRVM_G_VECTOR(OFS_PARM2); + rgb = PRVM_G_VECTOR(OFS_PARM3); + if (prog->argc >= 6) + flag = (int) PRVM_G_FLOAT(OFS_PARM5); + + if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS) + { + PRVM_G_FLOAT(OFS_RETURN) = -2; + VM_Warning(prog, "VM_drawpic: %s: wrong DRAWFLAG %i !\n",prog->name,flag); + return; + } + + if(pos[2] || size[2]) + VM_Warning(prog, "VM_drawpic: z value%s from %s discarded\n",(pos[2] && size[2]) ? "s" : " ",((pos[2] && size[2]) ? "pos and size" : (pos[2] ? "pos" : "size"))); + + DrawQ_Pic(pos[0], pos[1], Draw_CachePic_Flags (picname, CACHEPICFLAG_NOTPERSISTENT), size[0], size[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag); + PRVM_G_FLOAT(OFS_RETURN) = 1; +} +/* +========= +VM_drawrotpic + +float drawrotpic(vector position, string pic, vector size, vector org, float angle, vector rgb, float alpha, float flag) +========= +*/ +void VM_drawrotpic(prvm_prog_t *prog) +{ + const char *picname; + prvm_vec_t *size, *pos, *org, *rgb; + int flag; + + VM_SAFEPARMCOUNT(8,VM_drawrotpic); + + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + + picname = PRVM_G_STRING(OFS_PARM1); + VM_CheckEmptyString(prog, picname); + + // is pic cached ? no function yet for that + if(!1) + { + PRVM_G_FLOAT(OFS_RETURN) = -4; + VM_Warning(prog, "VM_drawrotpic: %s: %s not cached !\n", prog->name, picname); + return; + } + + pos = PRVM_G_VECTOR(OFS_PARM0); + size = PRVM_G_VECTOR(OFS_PARM2); + org = PRVM_G_VECTOR(OFS_PARM3); + rgb = PRVM_G_VECTOR(OFS_PARM5); + flag = (int) PRVM_G_FLOAT(OFS_PARM7); + + if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS) + { + PRVM_G_FLOAT(OFS_RETURN) = -2; + VM_Warning(prog, "VM_drawrotpic: %s: wrong DRAWFLAG %i !\n",prog->name,flag); + return; + } + + if(pos[2] || size[2] || org[2]) + VM_Warning(prog, "VM_drawrotpic: z value from pos/size/org discarded\n"); + + DrawQ_RotPic(pos[0], pos[1], Draw_CachePic_Flags(picname, CACHEPICFLAG_NOTPERSISTENT), size[0], size[1], org[0], org[1], PRVM_G_FLOAT(OFS_PARM4), rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM6), flag); + PRVM_G_FLOAT(OFS_RETURN) = 1; +} +/* +========= +VM_drawsubpic + +float drawsubpic(vector position, vector size, string pic, vector srcPos, vector srcSize, vector rgb, float alpha, float flag) + +========= +*/ +void VM_drawsubpic(prvm_prog_t *prog) +{ + const char *picname; + prvm_vec_t *size, *pos, *rgb, *srcPos, *srcSize, alpha; + int flag; + + VM_SAFEPARMCOUNT(8,VM_drawsubpic); + + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + + picname = PRVM_G_STRING(OFS_PARM2); + VM_CheckEmptyString(prog, picname); + + // is pic cached ? no function yet for that + if(!1) + { + PRVM_G_FLOAT(OFS_RETURN) = -4; + VM_Warning(prog, "VM_drawsubpic: %s: %s not cached !\n", prog->name, picname); + return; + } + + pos = PRVM_G_VECTOR(OFS_PARM0); + size = PRVM_G_VECTOR(OFS_PARM1); + srcPos = PRVM_G_VECTOR(OFS_PARM3); + srcSize = PRVM_G_VECTOR(OFS_PARM4); + rgb = PRVM_G_VECTOR(OFS_PARM5); + alpha = PRVM_G_FLOAT(OFS_PARM6); + flag = (int) PRVM_G_FLOAT(OFS_PARM7); + + if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS) + { + PRVM_G_FLOAT(OFS_RETURN) = -2; + VM_Warning(prog, "VM_drawsubpic: %s: wrong DRAWFLAG %i !\n",prog->name,flag); + return; + } + + if(pos[2] || size[2]) + VM_Warning(prog, "VM_drawsubpic: z value%s from %s discarded\n",(pos[2] && size[2]) ? "s" : " ",((pos[2] && size[2]) ? "pos and size" : (pos[2] ? "pos" : "size"))); + + DrawQ_SuperPic(pos[0], pos[1], Draw_CachePic_Flags (picname, CACHEPICFLAG_NOTPERSISTENT), + size[0], size[1], + srcPos[0], srcPos[1], rgb[0], rgb[1], rgb[2], alpha, + srcPos[0] + srcSize[0], srcPos[1], rgb[0], rgb[1], rgb[2], alpha, + srcPos[0], srcPos[1] + srcSize[1], rgb[0], rgb[1], rgb[2], alpha, + srcPos[0] + srcSize[0], srcPos[1] + srcSize[1], rgb[0], rgb[1], rgb[2], alpha, + flag); + PRVM_G_FLOAT(OFS_RETURN) = 1; +} + +/* +========= +VM_drawfill + +float drawfill(vector position, vector size, vector rgb, float alpha, float flag) +========= +*/ +void VM_drawfill(prvm_prog_t *prog) +{ + prvm_vec_t *size, *pos, *rgb; + int flag; + + VM_SAFEPARMCOUNT(5,VM_drawfill); + + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + + pos = PRVM_G_VECTOR(OFS_PARM0); + size = PRVM_G_VECTOR(OFS_PARM1); + rgb = PRVM_G_VECTOR(OFS_PARM2); + flag = (int) PRVM_G_FLOAT(OFS_PARM4); + + if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS) + { + PRVM_G_FLOAT(OFS_RETURN) = -2; + VM_Warning(prog, "VM_drawfill: %s: wrong DRAWFLAG %i !\n",prog->name,flag); + return; + } + + if(pos[2] || size[2]) + VM_Warning(prog, "VM_drawfill: z value%s from %s discarded\n",(pos[2] && size[2]) ? "s" : " ",((pos[2] && size[2]) ? "pos and size" : (pos[2] ? "pos" : "size"))); + + DrawQ_Fill(pos[0], pos[1], size[0], size[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM3), flag); + PRVM_G_FLOAT(OFS_RETURN) = 1; +} + +/* +========= +VM_drawsetcliparea + +drawsetcliparea(float x, float y, float width, float height) +========= +*/ +void VM_drawsetcliparea(prvm_prog_t *prog) +{ + float x,y,w,h; + VM_SAFEPARMCOUNT(4,VM_drawsetcliparea); + + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + + x = bound(0, PRVM_G_FLOAT(OFS_PARM0), vid_conwidth.integer); + y = bound(0, PRVM_G_FLOAT(OFS_PARM1), vid_conheight.integer); + w = bound(0, PRVM_G_FLOAT(OFS_PARM2) + PRVM_G_FLOAT(OFS_PARM0) - x, (vid_conwidth.integer - x)); + h = bound(0, PRVM_G_FLOAT(OFS_PARM3) + PRVM_G_FLOAT(OFS_PARM1) - y, (vid_conheight.integer - y)); + + DrawQ_SetClipArea(x, y, w, h); +} + +/* +========= +VM_drawresetcliparea + +drawresetcliparea() +========= +*/ +void VM_drawresetcliparea(prvm_prog_t *prog) +{ + VM_SAFEPARMCOUNT(0,VM_drawresetcliparea); + + // polygonbegin without draw2d arg has to guess + prog->polygonbegin_guess2d = true; + + DrawQ_ResetClipArea(); +} + +/* +========= +VM_getimagesize + +vector getimagesize(string pic) +========= +*/ +void VM_getimagesize(prvm_prog_t *prog) +{ + const char *p; + cachepic_t *pic; + + VM_SAFEPARMCOUNT(1,VM_getimagesize); + + p = PRVM_G_STRING(OFS_PARM0); + VM_CheckEmptyString(prog, p); + + pic = Draw_CachePic_Flags (p, CACHEPICFLAG_QUIET | CACHEPICFLAG_NOTPERSISTENT); + if (!Draw_IsPicLoaded(pic)) + { + PRVM_G_VECTOR(OFS_RETURN)[0] = 0; + PRVM_G_VECTOR(OFS_RETURN)[1] = 0; + } + else + { + PRVM_G_VECTOR(OFS_RETURN)[0] = Draw_GetPicWidth(pic); + PRVM_G_VECTOR(OFS_RETURN)[1] = Draw_GetPicHeight(pic); + } + PRVM_G_VECTOR(OFS_RETURN)[2] = 0; +} + //#330 float(float stnum) getstatf (EXT_CSQC) static void VM_CL_getstatf (prvm_prog_t *prog) { @@ -1300,7 +2074,7 @@ static void VM_CL_setmodelindex (prvm_prog_t *prog) //#334 string(float mdlindex) modelnameforindex (EXT_CSQC) static void VM_CL_modelnameforindex (prvm_prog_t *prog) { - dp_model_t *model; + model_t *model; VM_SAFEPARMCOUNT(1, VM_CL_modelnameforindex); @@ -1363,7 +2137,7 @@ static void VM_CL_boxparticles (prvm_prog_t *prog) vec3_t origin_from, origin_to, dir_from, dir_to; float count; int flags; - qboolean istrail; + qbool istrail; float tintmins[4], tintmaxs[4], fade; VM_SAFEPARMCOUNTRANGE(7, 8, VM_CL_boxparticles); @@ -1415,10 +2189,13 @@ static void VM_CL_boxparticles (prvm_prog_t *prog) static void VM_CL_setpause(prvm_prog_t *prog) { VM_SAFEPARMCOUNT(1, VM_CL_setpause); - if ((int)PRVM_G_FLOAT(OFS_PARM0) != 0) - cl.csqc_paused = true; - else - cl.csqc_paused = false; + if(cl.islocalgame) + { + if ((int)PRVM_G_FLOAT(OFS_PARM0) != 0) + host.paused = true; + else + host.paused = false; + } } //#343 void(float usecursor) setcursormode (DP_CSQC) @@ -1624,20 +2401,9 @@ static void VM_CL_setlistener (prvm_prog_t *prog) //#352 void(string cmdname) registercommand (EXT_CSQC) static void VM_CL_registercmd (prvm_prog_t *prog) { - char *t; VM_SAFEPARMCOUNT(1, VM_CL_registercmd); - if(!Cmd_Exists(PRVM_G_STRING(OFS_PARM0))) - { - size_t alloclen; - - alloclen = strlen(PRVM_G_STRING(OFS_PARM0)) + 1; - t = (char *)Z_Malloc(alloclen); - memcpy(t, PRVM_G_STRING(OFS_PARM0), alloclen); - Cmd_AddCommand(t, NULL, "console command created by QuakeC"); - } - else - Cmd_AddCommand(PRVM_G_STRING(OFS_PARM0), NULL, "console command created by QuakeC"); - + if(!Cmd_Exists(cmd_local, PRVM_G_STRING(OFS_PARM0))) + Cmd_AddCommand(CF_CLIENT, PRVM_G_STRING(OFS_PARM0), NULL, "console command created by QuakeC"); } //#360 float() readbyte (EXT_CSQC) @@ -1757,7 +2523,7 @@ static void VM_CL_makestatic (prvm_prog_t *prog) VM_Warning(prog, "makestatic: can not modify world entity\n"); return; } - if (ent->priv.server->free) + if (ent->free) { VM_Warning(prog, "makestatic: can not modify free entity\n"); return; @@ -1811,8 +2577,6 @@ static void VM_CL_makestatic (prvm_prog_t *prog) { if (!(staticent->render.effects & EF_FULLBRIGHT)) staticent->render.flags |= RENDER_LIGHT; - else if(r_equalize_entities_fullbright.integer) - staticent->render.flags |= RENDER_LIGHT | RENDER_EQUALIZE; } // turn off shadows from transparent objects if (!(staticent->render.effects & (EF_NOSHADOW | EF_ADDITIVE | EF_NODEPTHTEST)) && (staticent->render.alpha >= 1)) @@ -1855,7 +2619,7 @@ static void VM_CL_copyentity (prvm_prog_t *prog) VM_Warning(prog, "copyentity: can not read world entity\n"); return; } - if (in->priv.server->free) + if (in->free) { VM_Warning(prog, "copyentity: can not read free entity\n"); return; @@ -1866,12 +2630,15 @@ static void VM_CL_copyentity (prvm_prog_t *prog) VM_Warning(prog, "copyentity: can not modify world entity\n"); return; } - if (out->priv.server->free) + if (out->free) { VM_Warning(prog, "copyentity: can not modify free entity\n"); return; } memcpy(out->fields.fp, in->fields.fp, prog->entityfields * sizeof(prvm_vec_t)); + + if (VectorCompare(PRVM_clientedictvector(out, absmin), PRVM_clientedictvector(out, absmax))) + return; CL_LinkEdict(out); } @@ -1880,14 +2647,16 @@ static void VM_CL_copyentity (prvm_prog_t *prog) // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT) static void VM_CL_effect (prvm_prog_t *prog) { -#if 1 - Con_Printf("WARNING: VM_CL_effect not implemented\n"); // FIXME: this needs to take modelname not modelindex, the csqc defs has it as string and so it shall be -#else + model_t *model; vec3_t org; VM_SAFEPARMCOUNT(5, VM_CL_effect); VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org); - CL_Effect(org, (int)PRVM_G_FLOAT(OFS_PARM1), (int)PRVM_G_FLOAT(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), PRVM_G_FLOAT(OFS_PARM4)); -#endif + + model = Mod_FindName(PRVM_G_STRING(OFS_PARM1), NULL); + if(model->loaded) + CL_Effect(org, model, (int)PRVM_G_FLOAT(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), PRVM_G_FLOAT(OFS_PARM4)); + else + Con_Printf(CON_ERROR "VM_CL_effect: Could not load model '%s'\n", PRVM_G_STRING(OFS_PARM1)); } // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD) @@ -1934,7 +2703,7 @@ static void VM_CL_te_explosionrgb (prvm_prog_t *prog) CL_FindNonSolidLocation(pos, pos2, 10); CL_ParticleExplosion(pos2); Matrix4x4_CreateTranslate(&tempmatrix, pos2[0], pos2[1], pos2[2]); - CL_AllocLightFlash(NULL, &tempmatrix, 350, PRVM_G_VECTOR(OFS_PARM1)[0], PRVM_G_VECTOR(OFS_PARM1)[1], PRVM_G_VECTOR(OFS_PARM1)[2], 700, 0.5, 0, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE); + CL_AllocLightFlash(NULL, &tempmatrix, 350, PRVM_G_VECTOR(OFS_PARM1)[0], PRVM_G_VECTOR(OFS_PARM1)[1], PRVM_G_VECTOR(OFS_PARM1)[2], 700, 0.5, NULL, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE); } // #408 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube (DP_TE_PARTICLECUBE) @@ -2079,7 +2848,7 @@ static void VM_CL_te_customflash (prvm_prog_t *prog) VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos); CL_FindNonSolidLocation(pos, pos2, 4); Matrix4x4_CreateTranslate(&tempmatrix, pos2[0], pos2[1], pos2[2]); - CL_AllocLightFlash(NULL, &tempmatrix, PRVM_G_FLOAT(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM3)[0], PRVM_G_VECTOR(OFS_PARM3)[1], PRVM_G_VECTOR(OFS_PARM3)[2], PRVM_G_FLOAT(OFS_PARM1) / PRVM_G_FLOAT(OFS_PARM2), PRVM_G_FLOAT(OFS_PARM2), 0, -1, true, 1, 0.25, 1, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE); + CL_AllocLightFlash(NULL, &tempmatrix, PRVM_G_FLOAT(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM3)[0], PRVM_G_VECTOR(OFS_PARM3)[1], PRVM_G_VECTOR(OFS_PARM3)[2], PRVM_G_FLOAT(OFS_PARM1) / PRVM_G_FLOAT(OFS_PARM2), PRVM_G_FLOAT(OFS_PARM2), NULL, -1, true, 1, 0.25, 1, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE); } // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS) @@ -2230,7 +2999,7 @@ static void VM_CL_te_explosion2 (prvm_prog_t *prog) color[1] = tempcolor[1] * (2.0f / 255.0f); color[2] = tempcolor[2] * (2.0f / 255.0f); Matrix4x4_CreateTranslate(&tempmatrix, pos2[0], pos2[1], pos2[2]); - CL_AllocLightFlash(NULL, &tempmatrix, 350, color[0], color[1], color[2], 700, 0.5, 0, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE); + CL_AllocLightFlash(NULL, &tempmatrix, 350, color[0], color[1], color[2], 700, 0.5, NULL, -1, true, 1, 0.25, 0.25, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE); S_StartSound(-1, 0, cl.sfx_r_exp3, pos2, 1, 1); } @@ -2308,7 +3077,7 @@ static void VM_CL_setattachment (prvm_prog_t *prog) const char *tagname; int modelindex; int tagindex; - dp_model_t *model; + model_t *model; VM_SAFEPARMCOUNT(3, VM_CL_setattachment); e = PRVM_G_EDICT(OFS_PARM0); @@ -2320,7 +3089,7 @@ static void VM_CL_setattachment (prvm_prog_t *prog) VM_Warning(prog, "setattachment: can not modify world entity\n"); return; } - if (e->priv.server->free) + if (e->free) { VM_Warning(prog, "setattachment: can not modify free entity\n"); return; @@ -2353,7 +3122,7 @@ static void VM_CL_setattachment (prvm_prog_t *prog) static int CL_GetTagIndex (prvm_prog_t *prog, prvm_edict_t *e, const char *tagname) { - dp_model_t *model = CL_GetModelFromEdict(e); + model_t *model = CL_GetModelFromEdict(e); if (model) return Mod_Alias_GetTagIndexForName(model, (int)PRVM_clientedictfloat(e, skin), tagname); else @@ -2363,7 +3132,7 @@ static int CL_GetTagIndex (prvm_prog_t *prog, prvm_edict_t *e, const char *tagna static int CL_GetExtendedTagInfo (prvm_prog_t *prog, prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix) { int r; - dp_model_t *model; + model_t *model; *tagname = NULL; *parentindex = 0; @@ -2386,13 +3155,13 @@ static int CL_GetExtendedTagInfo (prvm_prog_t *prog, prvm_edict_t *e, int tagind int CL_GetPitchSign(prvm_prog_t *prog, prvm_edict_t *ent) { - dp_model_t *model; + model_t *model; if ((model = CL_GetModelFromEdict(ent)) && model->type == mod_alias) return -1; return 1; } -void CL_GetEntityMatrix (prvm_prog_t *prog, prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix) +void CL_GetEntityMatrix (prvm_prog_t *prog, prvm_edict_t *ent, matrix4x4_t *out, qbool viewmatrix) { float scale; float pitchsign = 1; @@ -2424,7 +3193,7 @@ void CL_GetEntityMatrix (prvm_prog_t *prog, prvm_edict_t *ent, matrix4x4_t *out, static int CL_GetEntityLocalTagMatrix(prvm_prog_t *prog, prvm_edict_t *ent, int tagindex, matrix4x4_t *out) { - dp_model_t *model; + model_t *model; if (tagindex >= 0 && (model = CL_GetModelFromEdict(ent)) && model->animscenes) @@ -2453,14 +3222,14 @@ int CL_GetTagMatrix (prvm_prog_t *prog, matrix4x4_t *out, prvm_edict_t *ent, int int ret; int attachloop; matrix4x4_t entitymatrix, tagmatrix, attachmatrix; - dp_model_t *model; + model_t *model; vec3_t shadingorigin; *out = identitymatrix; // warnings and errors return identical matrix if (ent == prog->edicts) return 1; - if (ent->priv.server->free) + if (ent->free) return 2; model = CL_GetModelFromEdict(ent); @@ -2505,9 +3274,9 @@ int CL_GetTagMatrix (prvm_prog_t *prog, matrix4x4_t *out, prvm_edict_t *ent, int if (PRVM_clientedictfloat(ent, health) > 0 && cl_bob.value && cl_bobcycle.value) { double bob, cycle; - // LordHavoc: this code is *weird*, but not replacable (I think it + // LadyHavoc: this code is *weird*, but not replacable (I think it // should be done in QC on the server, but oh well, quake is quake) - // LordHavoc: figured out bobup: the time at which the sin is at 180 + // LadyHavoc: figured out bobup: the time at which the sin is at 180 // degrees (which allows lengthening or squishing the peak or valley) cycle = cl.time/cl_bobcycle.value; cycle -= (int)cycle; @@ -2552,7 +3321,7 @@ static void VM_CL_gettagindex (prvm_prog_t *prog) VM_Warning(prog, "VM_CL_gettagindex(entity #%i): can't affect world entity\n", PRVM_NUM_FOR_EDICT(ent)); return; } - if (ent->priv.server->free) + if (ent->free) { VM_Warning(prog, "VM_CL_gettagindex(entity #%i): can't affect free entity\n", PRVM_NUM_FOR_EDICT(ent)); return; @@ -2582,7 +3351,7 @@ static void VM_CL_gettaginfo (prvm_prog_t *prog) const char *tagname; int returncode; vec3_t forward, left, up, origin; - const dp_model_t *model; + const model_t *model; VM_SAFEPARMCOUNT(2, VM_CL_gettaginfo); @@ -2639,7 +3408,7 @@ static void VM_CL_gettaginfo (prvm_prog_t *prog) typedef struct vmparticletheme_s { unsigned short typeindex; - qboolean initialized; + qbool initialized; pblend_t blendmode; porientation_t orientation; int color1; @@ -2655,7 +3424,7 @@ typedef struct vmparticletheme_s float liquidfriction; float originjitter; float velocityjitter; - qboolean qualityreduction; + qbool qualityreduction; float lifetime; float stretch; int staincolor1; @@ -2673,8 +3442,8 @@ typedef struct vmparticletheme_s typedef struct vmparticlespawner_s { mempool_t *pool; - qboolean initialized; - qboolean verified; + qbool initialized; + qbool verified; vmparticletheme_t *themes; int max_themes; }vmparticlespawner_t; @@ -2933,16 +3702,16 @@ static void VM_CL_SpawnParticle (prvm_prog_t *prog) particle_t *part; int themenum; - VM_SAFEPARMCOUNTRANGE(2, 3, VM_CL_SpawnParticle2); + VM_SAFEPARMCOUNTRANGE(2, 3, VM_CL_SpawnParticle); if (vmpartspawner.verified == false) { VM_Warning(prog, "VM_CL_SpawnParticle: particle spawner not initialized\n"); - PRVM_G_FLOAT(OFS_RETURN) = 0; + PRVM_G_FLOAT(OFS_RETURN) = 0; return; } VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org); VectorCopy(PRVM_G_VECTOR(OFS_PARM1), dir); - + if (prog->argc < 3) // global-set particle { part = CL_NewParticle(org, @@ -2981,7 +3750,7 @@ static void VM_CL_SpawnParticle (prvm_prog_t *prog) NULL); if (!part) { - PRVM_G_FLOAT(OFS_RETURN) = 0; + PRVM_G_FLOAT(OFS_RETURN) = 0; return; } if (PRVM_clientglobalfloat(particle_delayspawn)) @@ -2995,7 +3764,7 @@ static void VM_CL_SpawnParticle (prvm_prog_t *prog) if (themenum <= 0 || themenum >= vmpartspawner.max_themes) { VM_Warning(prog, "VM_CL_SpawnParticle: bad theme number %i\n", themenum); - PRVM_G_FLOAT(OFS_RETURN) = 0; + PRVM_G_FLOAT(OFS_RETURN) = 0; return; } theme = &vmpartspawner.themes[themenum]; @@ -3035,7 +3804,7 @@ static void VM_CL_SpawnParticle (prvm_prog_t *prog) NULL); if (!part) { - PRVM_G_FLOAT(OFS_RETURN) = 0; + PRVM_G_FLOAT(OFS_RETURN) = 0; return; } if (theme->delayspawn) @@ -3043,7 +3812,7 @@ static void VM_CL_SpawnParticle (prvm_prog_t *prog) //if (theme->delaycollision) // part->delayedcollisions = cl.time + theme->delaycollision; } - PRVM_G_FLOAT(OFS_RETURN) = 1; + PRVM_G_FLOAT(OFS_RETURN) = 1; } // float(vector org, vector dir, float spawndelay, float collisiondelay, [float theme]) delayedparticle @@ -3055,11 +3824,11 @@ static void VM_CL_SpawnParticleDelayed (prvm_prog_t *prog) particle_t *part; int themenum; - VM_SAFEPARMCOUNTRANGE(4, 5, VM_CL_SpawnParticle2); + VM_SAFEPARMCOUNTRANGE(4, 5, VM_CL_SpawnParticleDelayed); if (vmpartspawner.verified == false) { - VM_Warning(prog, "VM_CL_SpawnParticle: particle spawner not initialized\n"); - PRVM_G_FLOAT(OFS_RETURN) = 0; + VM_Warning(prog, "VM_CL_SpawnParticleDelayed: particle spawner not initialized\n"); + PRVM_G_FLOAT(OFS_RETURN) = 0; return; } VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org); @@ -3104,8 +3873,8 @@ static void VM_CL_SpawnParticleDelayed (prvm_prog_t *prog) themenum = (int)PRVM_G_FLOAT(OFS_PARM4); if (themenum <= 0 || themenum >= vmpartspawner.max_themes) { - VM_Warning(prog, "VM_CL_SpawnParticle: bad theme number %i\n", themenum); - PRVM_G_FLOAT(OFS_RETURN) = 0; + VM_Warning(prog, "VM_CL_SpawnParticleDelayed: bad theme number %i\n", themenum); + PRVM_G_FLOAT(OFS_RETURN) = 0; return; } theme = &vmpartspawner.themes[themenum]; @@ -3144,10 +3913,10 @@ static void VM_CL_SpawnParticleDelayed (prvm_prog_t *prog) theme->spin, NULL); } - if (!part) - { - PRVM_G_FLOAT(OFS_RETURN) = 0; - return; + if (!part) + { + PRVM_G_FLOAT(OFS_RETURN) = 0; + return; } part->delayedspawn = cl.time + PRVM_G_FLOAT(OFS_PARM2); //part->delayedcollisions = cl.time + PRVM_G_FLOAT(OFS_PARM3); @@ -3166,7 +3935,7 @@ static void VM_CL_GetEntity (prvm_prog_t *prog) { int entnum, fieldnum; vec3_t forward, left, up, org; - VM_SAFEPARMCOUNT(2, VM_CL_GetEntityVec); + VM_SAFEPARMCOUNT(2, VM_CL_GetEntity); entnum = PRVM_G_FLOAT(OFS_PARM0); if (entnum < 0 || entnum >= cl.num_entities) @@ -3183,7 +3952,7 @@ static void VM_CL_GetEntity (prvm_prog_t *prog) case 1: // origin Matrix4x4_OriginFromMatrix(&cl.entities[entnum].render.matrix, org); VectorCopy(org, PRVM_G_VECTOR(OFS_RETURN)); - break; + break; case 2: // forward Matrix4x4_ToVectors(&cl.entities[entnum].render.matrix, forward, left, up, org); VectorCopy(forward, PRVM_G_VECTOR(OFS_RETURN)); @@ -3198,17 +3967,17 @@ static void VM_CL_GetEntity (prvm_prog_t *prog) break; case 5: // scale PRVM_G_FLOAT(OFS_RETURN) = Matrix4x4_ScaleFromMatrix(&cl.entities[entnum].render.matrix); - break; + break; case 6: // origin + v_forward, v_right, v_up Matrix4x4_ToVectors(&cl.entities[entnum].render.matrix, forward, left, up, org); VectorCopy(forward, PRVM_clientglobalvector(v_forward)); VectorNegate(left, PRVM_clientglobalvector(v_right)); VectorCopy(up, PRVM_clientglobalvector(v_up)); VectorCopy(org, PRVM_G_VECTOR(OFS_RETURN)); - break; + break; case 7: // alpha PRVM_G_FLOAT(OFS_RETURN) = cl.entities[entnum].render.alpha; - break; + break; case 8: // colormor VectorCopy(cl.entities[entnum].render.colormod, PRVM_G_VECTOR(OFS_RETURN)); break; @@ -3220,24 +3989,24 @@ static void VM_CL_GetEntity (prvm_prog_t *prog) break; case 11: // skinnum PRVM_G_FLOAT(OFS_RETURN) = cl.entities[entnum].render.skinnum; - break; + break; case 12: // mins - VectorCopy(cl.entities[entnum].render.mins, PRVM_G_VECTOR(OFS_RETURN)); - break; + VectorCopy(cl.entities[entnum].render.mins, PRVM_G_VECTOR(OFS_RETURN)); + break; case 13: // maxs - VectorCopy(cl.entities[entnum].render.maxs, PRVM_G_VECTOR(OFS_RETURN)); - break; + VectorCopy(cl.entities[entnum].render.maxs, PRVM_G_VECTOR(OFS_RETURN)); + break; case 14: // absmin Matrix4x4_OriginFromMatrix(&cl.entities[entnum].render.matrix, org); - VectorAdd(cl.entities[entnum].render.mins, org, PRVM_G_VECTOR(OFS_RETURN)); - break; + VectorAdd(cl.entities[entnum].render.mins, org, PRVM_G_VECTOR(OFS_RETURN)); + break; case 15: // absmax Matrix4x4_OriginFromMatrix(&cl.entities[entnum].render.matrix, org); - VectorAdd(cl.entities[entnum].render.maxs, org, PRVM_G_VECTOR(OFS_RETURN)); + VectorAdd(cl.entities[entnum].render.maxs, org, PRVM_G_VECTOR(OFS_RETURN)); break; case 16: // light VectorMA(cl.entities[entnum].render.render_modellight_ambient, 0.5, cl.entities[entnum].render.render_modellight_diffuse, PRVM_G_VECTOR(OFS_RETURN)); - break; + break; default: PRVM_G_FLOAT(OFS_RETURN) = 0; break; @@ -3254,7 +4023,7 @@ static void VM_CL_GetEntity (prvm_prog_t *prog) // --blub static void VM_CL_R_RenderScene (prvm_prog_t *prog) { - qboolean ismain = r_refdef.view.ismain; + qbool ismain = r_refdef.view.ismain; double t = Sys_DirtyTime(); VM_SAFEPARMCOUNT(0, VM_CL_R_RenderScene); @@ -3265,17 +4034,17 @@ static void VM_CL_R_RenderScene (prvm_prog_t *prog) csqc_main_r_refdef_view = r_refdef.view; } + // now after all of the predraw we know the geometry in the scene mesh and can finalize it for rendering + CL_MeshEntities_Scene_FinalizeRenderEntity(); + // we need to update any RENDER_VIEWMODEL entities at this point because // csqc supplies its own view matrix CL_UpdateViewEntities(); - CL_MeshEntities_AddToScene(); CL_UpdateEntityShading(); // now draw stuff! R_RenderView(0, NULL, NULL, r_refdef.view.x, r_refdef.view.y, r_refdef.view.width, r_refdef.view.height); - Mod_Mesh_Reset(CL_Mesh_CSQC()); - // callprofile fixing hack: do not include this time in what is counted for CSQC_UpdateView t = Sys_DirtyTime() - t;if (t < 0 || t >= 1800) t = 0; prog->functions[PRVM_clientfunction(CSQC_UpdateView)].totaltime -= t; @@ -3297,8 +4066,8 @@ static void VM_CL_R_PolygonBegin (prvm_prog_t *prog) { const char *texname; int drawflags; - qboolean draw2d; - dp_model_t *mod; + qbool draw2d; + model_t *mod; VM_SAFEPARMCOUNTRANGE(2, 3, VM_CL_R_PolygonBegin); @@ -3317,9 +4086,13 @@ static void VM_CL_R_PolygonBegin (prvm_prog_t *prog) } // we need to remember whether this is a 2D or 3D mesh we're adding to - mod = draw2d ? CL_Mesh_UI() : CL_Mesh_CSQC(); + mod = draw2d ? CL_Mesh_UI() : CL_Mesh_Scene(); prog->polygonbegin_model = mod; - Mod_Mesh_AddSurface(mod, Mod_Mesh_GetTexture(mod, texname, drawflags, TEXF_ALPHA, MATERIALFLAG_VERTEXCOLOR), draw2d); + if (texname == NULL || texname[0] == 0) + texname = "$whiteimage"; + strlcpy(prog->polygonbegin_texname, texname, sizeof(prog->polygonbegin_texname)); + prog->polygonbegin_drawflags = drawflags; + prog->polygonbegin_numvertices = 0; } //void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex @@ -3329,47 +4102,97 @@ static void VM_CL_R_PolygonVertex (prvm_prog_t *prog) const prvm_vec_t *tc = PRVM_G_VECTOR(OFS_PARM1); const prvm_vec_t *c = PRVM_G_VECTOR(OFS_PARM2); const prvm_vec_t a = PRVM_G_FLOAT(OFS_PARM3); - dp_model_t *mod = prog->polygonbegin_model; - int e0, e1, e2; - msurface_t *surf; + float *o; + model_t *mod = prog->polygonbegin_model; VM_SAFEPARMCOUNT(4, VM_CL_R_PolygonVertex); - if (!mod || mod->num_surfaces == 0) + if (!mod) { VM_Warning(prog, "VM_CL_R_PolygonVertex: VM_CL_R_PolygonBegin wasn't called\n"); return; } - surf = &mod->data_surfaces[mod->num_surfaces - 1]; - e2 = Mod_Mesh_IndexForVertex(mod, surf, v[0], v[1], v[2], 0, 0, 0, tc[0], tc[1], 0, 0, c[0], c[1], c[2], a); - if (surf->num_vertices >= 3) + if (prog->polygonbegin_maxvertices <= prog->polygonbegin_numvertices) { - // the first element is the start of the triangle fan - e0 = surf->num_firstvertex; - // the second element is the previous vertex - e1 = e0 + 1; - if (surf->num_triangles > 0) - e1 = mod->surfmesh.data_element3i[(surf->num_firsttriangle + surf->num_triangles) * 3 - 1]; - Mod_Mesh_AddTriangle(mod, surf, e0, e1, e2); + prog->polygonbegin_maxvertices = max(16, prog->polygonbegin_maxvertices * 2); + prog->polygonbegin_vertexdata = (float *)Mem_Realloc(prog->progs_mempool, prog->polygonbegin_vertexdata, prog->polygonbegin_maxvertices * sizeof(float[10])); } + o = prog->polygonbegin_vertexdata + prog->polygonbegin_numvertices++ * 10; + + o[0] = v[0]; + o[1] = v[1]; + o[2] = v[2]; + o[3] = tc[0]; + o[4] = tc[1]; + o[5] = tc[2]; + o[6] = c[0]; + o[7] = c[1]; + o[8] = c[2]; + o[9] = a; } //void() R_EndPolygon static void VM_CL_R_PolygonEnd (prvm_prog_t *prog) { - dp_model_t *mod = prog->polygonbegin_model; + int i; + qbool hascolor; + qbool hasalpha; + int e0 = 0, e1 = 0, e2 = 0; + float *o; + model_t *mod = prog->polygonbegin_model; msurface_t *surf; + texture_t *tex; + int materialflags; VM_SAFEPARMCOUNT(0, VM_CL_R_PolygonEnd); - if (!mod || mod->num_surfaces == 0) + if (!mod) { VM_Warning(prog, "VM_CL_R_PolygonEnd: VM_CL_R_PolygonBegin wasn't called\n"); return; } - surf = &mod->data_surfaces[mod->num_surfaces - 1]; + + // determine if vertex alpha is being used so we can provide that hint to GetTexture... + hascolor = false; + hasalpha = false; + for (i = 0; i < prog->polygonbegin_numvertices; i++) + { + o = prog->polygonbegin_vertexdata + 10 * i; + if (o[6] != 1.0f || o[7] != 1.0f || o[8] != 1.0f) + hascolor = true; + if (o[9] != 1.0f) + hasalpha = true; + } + + // create the surface, looking up the best matching texture/shader + materialflags = MATERIALFLAG_WALL; + if (csqc_polygons_defaultmaterial_nocullface.integer) + materialflags |= MATERIALFLAG_NOCULLFACE; + if (hascolor) + materialflags |= MATERIALFLAG_VERTEXCOLOR; + if (hasalpha) + materialflags |= MATERIALFLAG_ALPHAGEN_VERTEX | MATERIALFLAG_ALPHA | MATERIALFLAG_BLENDED | MATERIALFLAG_NOSHADOW; + tex = Mod_Mesh_GetTexture(mod, prog->polygonbegin_texname, prog->polygonbegin_drawflags, TEXF_ALPHA, materialflags); + surf = Mod_Mesh_AddSurface(mod, tex, false); + // create triangle fan + for (i = 0; i < prog->polygonbegin_numvertices; i++) + { + o = prog->polygonbegin_vertexdata + 10 * i; + e2 = Mod_Mesh_IndexForVertex(mod, surf, o[0], o[1], o[2], 0, 0, 0, o[3], o[4], 0, 0, o[6], o[7], o[8], o[9]); + if (i >= 2) + Mod_Mesh_AddTriangle(mod, surf, e0, e1, e2); + else if (i == 0) + e0 = e2; + e1 = e2; + } + // build normals (since they are not provided) Mod_BuildNormals(surf->num_firstvertex, surf->num_vertices, surf->num_triangles, mod->surfmesh.data_vertex3f, mod->surfmesh.data_element3i + 3 * surf->num_firsttriangle, mod->surfmesh.data_normal3f, true); + + // reset state prog->polygonbegin_model = NULL; + prog->polygonbegin_texname[0] = 0; + prog->polygonbegin_drawflags = 0; + prog->polygonbegin_numvertices = 0; } /* @@ -3381,7 +4204,7 @@ is not a staircase. ============= */ -static qboolean CL_CheckBottom (prvm_edict_t *ent) +static qbool CL_CheckBottom (prvm_edict_t *ent) { prvm_prog_t *prog = CLVM_prog; vec3_t mins, maxs, start, stop; @@ -3450,7 +4273,7 @@ The move will be adjusted for slopes and stairs, but if the move isn't possible, no move is done and false is returned ============= */ -static qboolean CL_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qboolean noenemy, qboolean settrace) +static qbool CL_movestep (prvm_edict_t *ent, vec3_t move, qbool relink, qbool noenemy, qbool settrace) { prvm_prog_t *prog = CLVM_prog; float dz; @@ -3580,7 +4403,7 @@ static void VM_CL_walkmove (prvm_prog_t *prog) vec3_t move; mfunction_t *oldf; int oldself; - qboolean settrace; + qbool settrace; VM_SAFEPARMCOUNTRANGE(2, 3, VM_CL_walkmove); @@ -3593,7 +4416,7 @@ static void VM_CL_walkmove (prvm_prog_t *prog) VM_Warning(prog, "walkmove: can not modify world entity\n"); return; } - if (ent->priv.server->free) + if (ent->free) { VM_Warning(prog, "walkmove: can not modify free entity\n"); return; @@ -3660,11 +4483,11 @@ static void VM_CL_checkpvs (prvm_prog_t *prog) unsigned char fatpvs[MAX_MAP_LEAFS/8]; #endif - VM_SAFEPARMCOUNT(2, VM_SV_checkpvs); + VM_SAFEPARMCOUNT(2, VM_CL_checkpvs); VectorCopy(PRVM_G_VECTOR(OFS_PARM0), viewpos); viewee = PRVM_G_EDICT(OFS_PARM1); - if(viewee->priv.required->free) + if(viewee->free) { VM_Warning(prog, "checkpvs: can not check free entity\n"); PRVM_G_FLOAT(OFS_RETURN) = 4; @@ -3712,7 +4535,7 @@ static void VM_CL_checkpvs (prvm_prog_t *prog) static void VM_CL_skel_create(prvm_prog_t *prog) { int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0); - dp_model_t *model = CL_GetModelByIndex(modelindex); + model_t *model = CL_GetModelByIndex(modelindex); skeleton_t *skeleton; int i; PRVM_G_FLOAT(OFS_RETURN) = 0; @@ -3742,7 +4565,7 @@ static void VM_CL_skel_build(prvm_prog_t *prog) float retainfrac = PRVM_G_FLOAT(OFS_PARM3); int firstbone = PRVM_G_FLOAT(OFS_PARM4) - 1; int lastbone = PRVM_G_FLOAT(OFS_PARM5) - 1; - dp_model_t *model = CL_GetModelByIndex(modelindex); + model_t *model = CL_GetModelByIndex(modelindex); int numblends; int bonenum; int blendindex; @@ -3985,7 +4808,7 @@ static void VM_CL_skel_delete(prvm_prog_t *prog) static void VM_CL_frameforname(prvm_prog_t *prog) { int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0); - dp_model_t *model = CL_GetModelByIndex(modelindex); + model_t *model = CL_GetModelByIndex(modelindex); const char *name = PRVM_G_STRING(OFS_PARM1); int i; PRVM_G_FLOAT(OFS_RETURN) = -1; @@ -4005,7 +4828,7 @@ static void VM_CL_frameforname(prvm_prog_t *prog) static void VM_CL_frameduration(prvm_prog_t *prog) { int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0); - dp_model_t *model = CL_GetModelByIndex(modelindex); + model_t *model = CL_GetModelByIndex(modelindex); int framenum = (int)PRVM_G_FLOAT(OFS_PARM1); PRVM_G_FLOAT(OFS_RETURN) = 0; if (!model || !model->animscenes || framenum < 0 || framenum >= model->numframes) @@ -4072,11 +4895,10 @@ static void VM_CL_V_CalcRefdef(prvm_prog_t *prog) matrix4x4_t entrendermatrix; vec3_t clviewangles; vec3_t clvelocity; - qboolean teleported; - qboolean clonground; - qboolean clcmdjump; - qboolean cldead; - qboolean clintermission; + qbool teleported; + qbool clonground; + qbool clcmdjump; + qbool cldead; float clstatsviewheight; prvm_edict_t *ent; int flags; @@ -4094,10 +4916,10 @@ static void VM_CL_V_CalcRefdef(prvm_prog_t *prog) clcmdjump = (flags & REFDEFFLAG_JUMPING) != 0; clstatsviewheight = PRVM_clientedictvector(ent, view_ofs)[2]; cldead = (flags & REFDEFFLAG_DEAD) != 0; - clintermission = (flags & REFDEFFLAG_INTERMISSION) != 0; + cl.intermission = (flags & REFDEFFLAG_INTERMISSION) != 0; VectorCopy(PRVM_clientedictvector(ent, velocity), clvelocity); - V_CalcRefdefUsing(&entrendermatrix, clviewangles, teleported, clonground, clcmdjump, clstatsviewheight, cldead, clintermission, clvelocity); + V_CalcRefdefUsing(&entrendermatrix, clviewangles, teleported, clonground, clcmdjump, clstatsviewheight, cldead, clvelocity); VectorCopy(cl.csqc_vieworiginfromengine, cl.csqc_vieworigin); VectorCopy(cl.csqc_viewanglesfromengine, cl.csqc_viewangles); @@ -4122,7 +4944,7 @@ VM_CL_setsize, // #4 void(entity e, vector min, vector max) setsize (QUAKE) NULL, // #5 void(entity e, vector min, vector max) setabssize (QUAKE) VM_break, // #6 void() break (QUAKE) VM_random, // #7 float() random (QUAKE) -VM_CL_sound, // #8 void(entity e, float chan, string samp) sound (QUAKE) +VM_CL_sound, // #8 void(entity e, float chan, string samp, float volume, float atten[, float pitchchange[, float flags]]) sound (QUAKE) VM_normalize, // #9 vector(vector v) normalize (QUAKE) VM_error, // #10 void(string e) error (QUAKE) VM_objerror, // #11 void(string e) objerror (QUAKE) @@ -4160,7 +4982,7 @@ NULL, // #42 (QUAKE) VM_fabs, // #43 float(float f) fabs (QUAKE) NULL, // #44 vector(entity e, float speed) aim (QUAKE) VM_cvar, // #45 float(string s) cvar (QUAKE) -VM_localcmd, // #46 void(string s) localcmd (QUAKE) +VM_localcmd_local, // #46 void(string s) localcmd (QUAKE) VM_nextent, // #47 entity(entity e) nextent (QUAKE) VM_CL_particle, // #48 void(vector o, vector d, float color, float count) particle (QUAKE) VM_changeyaw, // #49 void() ChangeYaw (QUAKE) @@ -4292,7 +5114,7 @@ NULL, // #173 NULL, // #174 NULL, // #175 NULL, // #176 -NULL, // #177 +VM_localsound, // #177 NULL, // #178 NULL, // #179 NULL, // #180 @@ -4361,7 +5183,7 @@ NULL, // #241 NULL, // #242 NULL, // #243 NULL, // #244 -NULL, // #245 +VM_modulo, // #245 NULL, // #246 NULL, // #247 NULL, // #248 @@ -4444,7 +5266,7 @@ VM_drawfill, // #323 float(vector position, vector size, vector rgb, float a VM_drawsetcliparea, // #324 void(float x, float y, float width, float height) drawsetcliparea VM_drawresetcliparea, // #325 void(void) drawresetcliparea VM_drawcolorcodedstring, // #326 float drawcolorcodedstring(vector position, string text, vector scale, vector rgb, float alpha, float flag) (EXT_CSQC) -VM_stringwidth, // #327 // FIXME is this okay? +VM_stringwidth, // #327 // FIXME is this okay? VM_drawsubpic, // #328 // FIXME is this okay? VM_drawrotpic, // #329 // FIXME is this okay? VM_CL_getstatf, // #330 float(float stnum) getstatf (EXT_CSQC) @@ -4517,7 +5339,7 @@ NULL, // #396 NULL, // #397 NULL, // #398 NULL, // #399 -// LordHavoc's range #400-#499 +// LadyHavoc's range #400-#499 VM_CL_copyentity, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY) NULL, // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR) VM_findchain, // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)