X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=clvm_cmds.c;h=a216cf7ffbaad02da24a5d08d70472ec35cfef3a;hb=6e82b529dceb0bf5f4277fa6fd499dc4f720d2ca;hp=e0ac5e74679b4ad1c0a3bcac1ce761e7a40f77c5;hpb=4d192dbaa2ce64ddb0f1fd687c44e79ea152a6af;p=xonotic%2Fdarkplaces.git diff --git a/clvm_cmds.c b/clvm_cmds.c index e0ac5e74..a216cf7f 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -128,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 @@ -206,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); } @@ -219,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"); @@ -318,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; @@ -368,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)); @@ -499,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); @@ -685,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); } @@ -743,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) @@ -1414,10 +1414,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) @@ -1623,20 +1626,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_client, PRVM_G_STRING(OFS_PARM0))) + Cmd_AddCommand(CMD_CLIENT, PRVM_G_STRING(OFS_PARM0), NULL, "console command created by QuakeC"); } //#360 float() readbyte (EXT_CSQC) @@ -1869,6 +1861,9 @@ static void VM_CL_copyentity (prvm_prog_t *prog) 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); } @@ -1877,14 +1872,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 + dp_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) @@ -1931,7 +1928,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) @@ -2076,7 +2073,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) @@ -2227,7 +2224,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); } @@ -2502,9 +2499,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; @@ -2930,7 +2927,7 @@ 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"); @@ -3052,10 +3049,10 @@ 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"); + VM_Warning(prog, "VM_CL_SpawnParticleDelayed: particle spawner not initialized\n"); PRVM_G_FLOAT(OFS_RETURN) = 0; return; } @@ -3101,7 +3098,7 @@ 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); + VM_Warning(prog, "VM_CL_SpawnParticleDelayed: bad theme number %i\n", themenum); PRVM_G_FLOAT(OFS_RETURN) = 0; return; } @@ -3163,7 +3160,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) @@ -3262,17 +3259,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; @@ -3314,9 +3311,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_WALL | MATERIALFLAG_VERTEXCOLOR | MATERIALFLAG_ALPHAGEN_VERTEX), 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 @@ -3326,47 +3327,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); + float *o; dp_model_t *mod = prog->polygonbegin_model; - int e0, e1, e2; - msurface_t *surf; 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) { + int i; + qboolean hascolor; + qboolean hasalpha; + int e0 = 0, e1 = 0, e2 = 0; + float *o; dp_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; } /* @@ -3657,7 +3708,7 @@ 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); @@ -4157,7 +4208,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_client, // #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) @@ -4514,7 +4565,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)