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");
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);
}
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)
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;
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);
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)
//#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(&cmd_client, 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(&cmd_client, t, NULL, "console command created by QuakeC");
- }
- else
- Cmd_AddCommand(&cmd_client, PRVM_G_STRING(OFS_PARM0), NULL, "console command created by QuakeC");
-
+ Cmd_AddCommand(CF_CLIENT, PRVM_G_STRING(OFS_PARM0), NULL, "console command created by QuakeC");
}
//#360 float() readbyte (EXT_CSQC)
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);
}
// #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)
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)
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)
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);
}
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;
typedef struct vmparticletheme_s
{
unsigned short typeindex;
- qboolean initialized;
+ qbool initialized;
pblend_t blendmode;
porientation_t orientation;
int color1;
float liquidfriction;
float originjitter;
float velocityjitter;
- qboolean qualityreduction;
+ qbool qualityreduction;
float lifetime;
float stretch;
int staincolor1;
typedef struct vmparticlespawner_s
{
mempool_t *pool;
- qboolean initialized;
- qboolean verified;
+ qbool initialized;
+ qbool verified;
vmparticletheme_t *themes;
int max_themes;
}vmparticlespawner_t;
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");
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;
}
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;
}
{
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)
// --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);
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;
{
const char *texname;
int drawflags;
- qboolean draw2d;
+ qbool draw2d;
dp_model_t *mod;
VM_SAFEPARMCOUNTRANGE(2, 3, VM_CL_R_PolygonBegin);
}
// 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), false);
+ 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
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;
+ qbool hascolor;
+ qbool 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;
}
/*
=============
*/
-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;
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;
vec3_t move;
mfunction_t *oldf;
int oldself;
- qboolean settrace;
+ qbool settrace;
VM_SAFEPARMCOUNTRANGE(2, 3, VM_CL_walkmove);
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);
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;
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);
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)