//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;
// #1 void(vector ang) makevectors
static void VM_CL_makevectors (prvm_prog_t *prog)
{
+ vec3_t angles, forward, right, up;
VM_SAFEPARMCOUNT(1, VM_CL_makevectors);
- AngleVectors (PRVM_G_VECTOR(OFS_PARM0), PRVM_clientglobalvector(v_forward), PRVM_clientglobalvector(v_right), PRVM_clientglobalvector(v_up));
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), angles);
+ AngleVectors(angles, forward, right, up);
+ VectorCopy(forward, PRVM_clientglobalvector(v_forward));
+ VectorCopy(right, PRVM_clientglobalvector(v_right));
+ VectorCopy(up, PRVM_clientglobalvector(v_up));
}
// #2 void(entity e, vector o) setorigin
static void VM_CL_setorigin (prvm_prog_t *prog)
{
prvm_edict_t *e;
- float *org;
+ prvm_vec_t *org;
VM_SAFEPARMCOUNT(2, VM_CL_setorigin);
e = PRVM_G_EDICT(OFS_PARM0);
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;
CL_LinkEdict(e);
}
-static void SetMinMaxSize (prvm_prog_t *prog, prvm_edict_t *e, float *min, float *max)
+static void SetMinMaxSizePRVM (prvm_prog_t *prog, prvm_edict_t *e, prvm_vec_t *min, prvm_vec_t *max)
{
int i;
CL_LinkEdict (e);
}
+static void SetMinMaxSize (prvm_prog_t *prog, prvm_edict_t *e, const vec_t *min, const vec_t *max)
+{
+ prvm_vec3_t mins, maxs;
+ VectorCopy(min, mins);
+ VectorCopy(max, maxs);
+ SetMinMaxSizePRVM(prog, e, mins, maxs);
+}
+
// #3 void(entity e, string m) setmodel
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);
if( mod ) {
// TODO: check if this breaks needed consistency and maybe add a cvar for it too?? [1/10/2008 Black]
- //SetMinMaxSize (e, mod->normalmins, mod->normalmaxs);
+ // 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
{
static void VM_CL_setsize (prvm_prog_t *prog)
{
prvm_edict_t *e;
- float *min, *max;
+ vec3_t mins, maxs;
VM_SAFEPARMCOUNT(3, VM_CL_setsize);
e = PRVM_G_EDICT(OFS_PARM0);
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;
}
- min = PRVM_G_VECTOR(OFS_PARM1);
- max = PRVM_G_VECTOR(OFS_PARM2);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), mins);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM2), maxs);
- SetMinMaxSize( prog, e, min, max );
+ SetMinMaxSize( prog, e, mins, maxs );
CL_LinkEdict(e);
}
-// #8 void(entity e, float chan, string samp, float volume, float atten) sound
+// #8 void(entity e, float chan, string samp, float volume, float atten[, float pitchchange[, float flags]]) sound
static void VM_CL_sound (prvm_prog_t *prog)
{
const char *sample;
int channel;
prvm_edict_t *entity;
- float volume;
+ float fvolume;
float attenuation;
float pitchchange;
+ float startposition;
int flags;
vec3_t org;
entity = PRVM_G_EDICT(OFS_PARM0);
channel = (int)PRVM_G_FLOAT(OFS_PARM1);
sample = PRVM_G_STRING(OFS_PARM2);
- volume = PRVM_G_FLOAT(OFS_PARM3);
+ fvolume = PRVM_G_FLOAT(OFS_PARM3);
attenuation = PRVM_G_FLOAT(OFS_PARM4);
- if (volume < 0 || volume > 1)
+ if (fvolume < 0 || fvolume > 1)
{
VM_Warning(prog, "VM_CL_sound: volume must be in range 0-1\n");
return;
pitchchange = 0;
else
pitchchange = PRVM_G_FLOAT(OFS_PARM5);
- // ignoring prog->argc < 7 for now (no flags supported yet)
if (prog->argc < 7)
flags = 0;
else
- flags = PRVM_G_FLOAT(OFS_PARM6);
+ {
+ // 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);
+ }
- channel = CHAN_USER2ENGINE(channel);
+ // sound_starttime exists instead of sound_startposition because in a
+ // networking sense you might not know when something is being received,
+ // so making sounds match up in sync would be impossible if relative
+ // position was sent
+ if (PRVM_clientglobalfloat(sound_starttime))
+ startposition = cl.time - PRVM_clientglobalfloat(sound_starttime);
+ else
+ startposition = 0;
if (!IS_CHAN(channel))
{
}
CL_VM_GetEntitySoundOrigin(MAX_EDICTS + PRVM_NUM_FOR_EDICT(entity), org);
- S_StartSound_StartPosition_Flags(MAX_EDICTS + PRVM_NUM_FOR_EDICT(entity), channel, S_FindName(sample), org, volume, attenuation, 0, flags, pitchchange > 0.0f ? pitchchange * 0.01f : 1.0f);
+ S_StartSound_StartPosition_Flags(MAX_EDICTS + PRVM_NUM_FOR_EDICT(entity), channel, S_FindName(sample), org, fvolume, attenuation, startposition, flags, pitchchange > 0.0f ? pitchchange * 0.01f : 1.0f);
}
// #483 void(vector origin, string sample, float volume, float attenuation) pointsound
static void VM_CL_pointsound(prvm_prog_t *prog)
{
const char *sample;
- float volume;
+ float fvolume;
float attenuation;
vec3_t org;
VectorCopy( PRVM_G_VECTOR(OFS_PARM0), org);
sample = PRVM_G_STRING(OFS_PARM1);
- volume = PRVM_G_FLOAT(OFS_PARM2);
+ fvolume = PRVM_G_FLOAT(OFS_PARM2);
attenuation = PRVM_G_FLOAT(OFS_PARM3);
- if (volume < 0 || volume > 1)
+ if (fvolume < 0 || fvolume > 1)
{
VM_Warning(prog, "VM_CL_pointsound: volume must be in range 0-1\n");
return;
}
// Send World Entity as Entity to Play Sound (for CSQC, that is MAX_EDICTS)
- S_StartSound(MAX_EDICTS, 0, S_FindName(sample), org, volume, attenuation);
+ S_StartSound(MAX_EDICTS, 0, S_FindName(sample), org, fvolume, attenuation);
}
// #14 entity() spawn
// #16 void(vector v1, vector v2, float movetype, entity ignore) traceline
static void VM_CL_traceline (prvm_prog_t *prog)
{
- float *v1, *v2;
+ vec3_t v1, v2;
trace_t trace;
int move, svent;
prvm_edict_t *ent;
prog->xfunction->builtinsprofile += 30;
- v1 = PRVM_G_VECTOR(OFS_PARM0);
- v2 = PRVM_G_VECTOR(OFS_PARM1);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), v1);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), v2);
move = (int)PRVM_G_FLOAT(OFS_PARM2);
ent = PRVM_G_EDICT(OFS_PARM3);
- if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v2[1]) || IS_NAN(v2[2]))
+ if (VEC_IS_NAN(v1[0]) || VEC_IS_NAN(v1[1]) || VEC_IS_NAN(v1[2]) || VEC_IS_NAN(v2[0]) || VEC_IS_NAN(v2[1]) || VEC_IS_NAN(v2[2]))
prog->error_cmd("%s: NAN errors detected in traceline('%f %f %f', '%f %f %f', %i, entity %i)\n", prog->name, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
- trace = CL_TraceLine(v1, v2, move, ent, CL_GenericHitSuperContentsMask(ent), CL_HitNetworkBrushModels(move), CL_HitNetworkPlayers(move), &svent, true, false);
+ trace = CL_TraceLine(v1, v2, move, ent, CL_GenericHitSuperContentsMask(ent), 0, 0, collision_extendtracelinelength.value, CL_HitNetworkBrushModels(move), CL_HitNetworkPlayers(move), &svent, true, false);
CL_VM_SetTraceGlobals(prog, &trace, svent);
// R_TimeReport("traceline");
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)
{
- float *v1, *v2, *m1, *m2;
+ vec3_t v1, v2, m1, m2;
trace_t trace;
int move, svent;
prvm_edict_t *ent;
prog->xfunction->builtinsprofile += 30;
- v1 = PRVM_G_VECTOR(OFS_PARM0);
- m1 = PRVM_G_VECTOR(OFS_PARM1);
- m2 = PRVM_G_VECTOR(OFS_PARM2);
- v2 = PRVM_G_VECTOR(OFS_PARM3);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), v1);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), m1);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM2), m2);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM3), v2);
move = (int)PRVM_G_FLOAT(OFS_PARM4);
ent = PRVM_G_EDICT(OFS_PARM5);
- if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v2[1]) || IS_NAN(v2[2]))
+ if (VEC_IS_NAN(v1[0]) || VEC_IS_NAN(v1[1]) || VEC_IS_NAN(v1[2]) || VEC_IS_NAN(v2[0]) || VEC_IS_NAN(v2[1]) || VEC_IS_NAN(v2[2]))
prog->error_cmd("%s: NAN errors detected in tracebox('%f %f %f', '%f %f %f', '%f %f %f', '%f %f %f', %i, entity %i)\n", prog->name, v1[0], v1[1], v1[2], m1[0], m1[1], m1[2], m2[0], m2[1], m2[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
- trace = CL_TraceBox(v1, m1, m2, v2, move, ent, CL_GenericHitSuperContentsMask(ent), CL_HitNetworkBrushModels(move), CL_HitNetworkPlayers(move), &svent, true);
+ trace = CL_TraceBox(v1, m1, m2, v2, move, ent, CL_GenericHitSuperContentsMask(ent), 0, 0, collision_extendtraceboxlength.value, CL_HitNetworkBrushModels(move), CL_HitNetworkPlayers(move), &svent, true);
CL_VM_SetTraceGlobals(prog, &trace, svent);
// R_TimeReport("tracebox");
{
int i;
float gravity;
- vec3_t move, end;
+ vec3_t start, end, mins, maxs, move;
vec3_t original_origin;
vec3_t original_velocity;
vec3_t original_angles;
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));
VectorScale (PRVM_clientedictvector(tossent, velocity), 0.05, move);
VectorAdd (PRVM_clientedictvector(tossent, origin), move, end);
- trace = CL_TraceBox(PRVM_clientedictvector(tossent, origin), PRVM_clientedictvector(tossent, mins), PRVM_clientedictvector(tossent, maxs), end, MOVE_NORMAL, tossent, CL_GenericHitSuperContentsMask(tossent), true, true, NULL, true);
+ VectorCopy(PRVM_clientedictvector(tossent, origin), start);
+ VectorCopy(PRVM_clientedictvector(tossent, mins), mins);
+ VectorCopy(PRVM_clientedictvector(tossent, maxs), maxs);
+ trace = CL_TraceBox(start, mins, maxs, end, MOVE_NORMAL, tossent, CL_GenericHitSuperContentsMask(tossent), 0, 0, collision_extendmovelength.value, true, true, NULL, true);
VectorCopy (trace.endpos, PRVM_clientedictvector(tossent, origin));
if (trace.fraction < 1)
{
const char *name;
int i;
- dp_model_t *m;
+ model_t *m;
VM_SAFEPARMCOUNT(1, VM_CL_precache_model);
{
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;
}
VM_Warning(prog, "VM_CL_precache_model: model \"%s\" not found\n", name);
}
-static int CSQC_EntitiesInBox (prvm_prog_t *prog, vec3_t mins, vec3_t maxs, int maxlist, prvm_edict_t **list)
-{
- prvm_edict_t *ent;
- int i, k;
-
- ent = PRVM_NEXT_EDICT(prog->edicts);
- for(k=0,i=1; i<prog->num_edicts ;i++, ent = PRVM_NEXT_EDICT(ent))
- {
- if (ent->priv.required->free)
- continue;
- if(BoxesOverlap(mins, maxs, PRVM_clientedictvector(ent, absmin), PRVM_clientedictvector(ent, absmax)))
- list[k++] = ent;
- }
- return k;
-}
-
// #22 entity(vector org, float rad) findradius
static void VM_CL_findradius (prvm_prog_t *prog)
{
else
chainfield = prog->fieldoffsets.chain;
if(chainfield < 0)
- prog->error_cmd("VM_findchain: %s doesnt have the specified chain field !", prog->name);
+ prog->error_cmd("VM_CL_findradius: %s doesnt have the specified chain field !", prog->name);
chain = (prvm_edict_t *)prog->edicts;
maxs[0] = org[0] + (radius + 1);
maxs[1] = org[1] + (radius + 1);
maxs[2] = org[2] + (radius + 1);
- numtouchedicts = CSQC_EntitiesInBox(prog, mins, maxs, MAX_EDICTS, touchedicts);
+ numtouchedicts = World_EntitiesInBox(&cl.world, mins, maxs, MAX_EDICTS, touchedicts);
if (numtouchedicts > MAX_EDICTS)
{
// this never happens //[515]: for what then ?
// (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);
VM_RETURN_EDICT(chain);
}
+// #566 entity(vector mins, vector maxs) findbox
+// #566 entity(vector mins, vector maxs, .entity tofield) findbox_tofield
+static void VM_CL_findbox (prvm_prog_t *prog)
+{
+ prvm_edict_t *chain;
+ int i, numtouchedicts;
+ static prvm_edict_t *touchedicts[MAX_EDICTS];
+ int chainfield;
+
+ VM_SAFEPARMCOUNTRANGE(2, 3, VM_CL_findbox);
+
+ if(prog->argc == 3)
+ chainfield = PRVM_G_INT(OFS_PARM2);
+ else
+ chainfield = prog->fieldoffsets.chain;
+ if(chainfield < 0)
+ prog->error_cmd("VM_CL_findbox: %s doesnt have the specified chain field !", prog->name);
+
+ chain = (prvm_edict_t *)prog->edicts;
+
+ numtouchedicts = World_EntitiesInBox(&cl.world, PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), MAX_EDICTS, touchedicts);
+ if (numtouchedicts > MAX_EDICTS)
+ {
+ // this never happens //[515]: for what then ?
+ Con_Printf("World_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
+ numtouchedicts = MAX_EDICTS;
+ }
+ for (i = 0; i < numtouchedicts; ++i)
+ {
+ PRVM_EDICTFIELDEDICT(touchedicts[i], chainfield) = PRVM_EDICT_TO_PROG(chain);
+ chain = touchedicts[i];
+ }
+
+ VM_RETURN_EDICT(chain);
+}
+
// #34 float() droptofloor
static void VM_CL_droptofloor (prvm_prog_t *prog)
{
prvm_edict_t *ent;
- vec3_t end;
+ vec3_t start, end, mins, maxs;
trace_t trace;
VM_SAFEPARMCOUNTRANGE(0, 2, VM_CL_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
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;
}
- VectorCopy (PRVM_clientedictvector(ent, origin), end);
- end[2] -= 256;
+ VectorCopy(PRVM_clientedictvector(ent, origin), start);
+ VectorCopy(PRVM_clientedictvector(ent, mins), mins);
+ VectorCopy(PRVM_clientedictvector(ent, maxs), maxs);
+ VectorCopy(PRVM_clientedictvector(ent, origin), end);
+ if (cl.worldmodel->brush.isq3bsp)
+ end[2] -= 4096;
+ else if (cl.worldmodel->brush.isq2bsp)
+ end[2] -= 128;
+ else
+ end[2] -= 256; // Quake, QuakeWorld
- trace = CL_TraceBox(PRVM_clientedictvector(ent, origin), PRVM_clientedictvector(ent, mins), PRVM_clientedictvector(ent, maxs), end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, NULL, true);
+ trace = CL_TraceBox(start, mins, maxs, end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value, true, true, NULL, true);
if (trace.fraction != 1)
{
start[0] = stop[0] = (mins[0] + maxs[0])*0.5;
start[1] = stop[1] = (mins[1] + maxs[1])*0.5;
stop[2] = start[2] - 2*sv_stepheight.value;
- trace = CL_TraceLine(start, stop, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, NULL, true, false);
+ trace = CL_TraceLine(start, stop, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value, true, true, NULL, true, false);
if (trace.fraction == 1.0)
return;
start[0] = stop[0] = x ? maxs[0] : mins[0];
start[1] = stop[1] = y ? maxs[1] : mins[1];
- trace = CL_TraceLine(start, stop, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, NULL, true, false);
+ trace = CL_TraceLine(start, stop, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value, true, true, NULL, true, false);
if (trace.fraction != 1.0 && trace.endpos[2] > bottom)
bottom = trace.endpos[2];
// #41 float(vector v) pointcontents
static void VM_CL_pointcontents (prvm_prog_t *prog)
{
+ vec3_t point;
VM_SAFEPARMCOUNT(1, VM_CL_pointcontents);
- PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, CL_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), point);
+ PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(CL_PointSuperContents(point));
}
// #48 void(vector o, vector d, float color, float count) particle
static void VM_CL_particle (prvm_prog_t *prog)
{
- float *org, *dir;
+ vec3_t org, dir;
int count;
unsigned char color;
VM_SAFEPARMCOUNT(4, VM_CL_particle);
- org = PRVM_G_VECTOR(OFS_PARM0);
- dir = PRVM_G_VECTOR(OFS_PARM1);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), dir);
color = (int)PRVM_G_FLOAT(OFS_PARM2);
count = (int)PRVM_G_FLOAT(OFS_PARM3);
CL_ParticleEffect(EFFECT_SVC_PARTICLE, count, org, org, dir, dir, NULL, color);
// #74 void(vector pos, string samp, float vol, float atten) ambientsound
static void VM_CL_ambientsound (prvm_prog_t *prog)
{
- float *f;
+ vec3_t f;
sfx_t *s;
VM_SAFEPARMCOUNT(4, VM_CL_ambientsound);
- s = S_FindName(PRVM_G_STRING(OFS_PARM0));
- f = PRVM_G_VECTOR(OFS_PARM1);
+ 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);
}
static void VM_CL_getlight (prvm_prog_t *prog)
{
vec3_t ambientcolor, diffusecolor, diffusenormal;
- vec_t *p;
+ vec3_t p;
+ int flags = prog->argc >= 2 ? PRVM_G_FLOAT(OFS_PARM1) : LP_LIGHTMAP;
VM_SAFEPARMCOUNTRANGE(1, 3, VM_CL_getlight);
- p = PRVM_G_VECTOR(OFS_PARM0);
- VectorClear(ambientcolor);
- VectorClear(diffusecolor);
- VectorClear(diffusenormal);
- if (prog->argc >= 2)
- R_CompleteLightPoint(ambientcolor, diffusecolor, diffusenormal, p, PRVM_G_FLOAT(OFS_PARM1));
- else if (cl.worldmodel && cl.worldmodel->brush.LightPoint)
- cl.worldmodel->brush.LightPoint(cl.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), p);
+ R_CompleteLightPoint(ambientcolor, diffusecolor, diffusenormal, p, flags, r_refdef.scene.lightmapintensity, r_refdef.scene.ambientintensity);
VectorMA(ambientcolor, 0.5, diffusecolor, PRVM_G_VECTOR(OFS_RETURN));
if (PRVM_clientglobalvector(getlight_ambient))
VectorCopy(ambientcolor, PRVM_clientglobalvector(getlight_ambient));
//============================================================================
//[515]: SCENE MANAGER builtins
+extern cvar_t v_yshearing;
void CSQC_R_RecalcView (void)
{
extern matrix4x4_t viewmodelmatrix_nobob;
extern matrix4x4_t viewmodelmatrix_withbob;
Matrix4x4_CreateFromQuakeEntity(&r_refdef.view.matrix, cl.csqc_vieworigin[0], cl.csqc_vieworigin[1], cl.csqc_vieworigin[2], cl.csqc_viewangles[0], cl.csqc_viewangles[1], cl.csqc_viewangles[2], 1);
+ if (v_yshearing.value > 0)
+ Matrix4x4_QuakeToDuke3D(&r_refdef.view.matrix, &r_refdef.view.matrix, v_yshearing.value);
Matrix4x4_Copy(&viewmodelmatrix_nobob, &r_refdef.view.matrix);
Matrix4x4_ConcatScale(&viewmodelmatrix_nobob, cl_viewmodel_scale.value);
Matrix4x4_Concat(&viewmodelmatrix_withbob, &r_refdef.view.matrix, &cl.csqc_viewmodelmatrixfromengine);
r_refdef.scene.numlights = 0;
// restore the view settings to the values that VM_CL_UpdateView received from the client code
r_refdef.view = csqc_original_r_refdef_view;
+ // polygonbegin without draw2d arg has to guess
+ prog->polygonbegin_guess2d = false;
VectorCopy(cl.csqc_vieworiginfromengine, cl.csqc_vieworigin);
VectorCopy(cl.csqc_viewanglesfromengine, cl.csqc_viewangles);
cl.csqc_vidvars.drawworld = r_drawworld.integer != 0;
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)
VM_SAFEPARMCOUNT(1, VM_CL_R_AddEntities);
drawmask = (int)PRVM_G_FLOAT(OFS_PARM0);
CSQC_RelinkAllEntities(drawmask);
- CL_RelinkLightFlashes();
PRVM_clientglobalfloat(time) = cl.time;
for(i=1;i<prog->num_edicts;i++)
// 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;
static void VM_CL_R_SetView (prvm_prog_t *prog)
{
int c;
- float *f;
+ prvm_vec_t *f;
float k;
VM_SAFEPARMCOUNTRANGE(1, 3, VM_CL_R_SetView);
static void VM_CL_R_AddDynamicLight (prvm_prog_t *prog)
{
double t = Sys_DirtyTime();
- vec_t *org;
+ vec3_t org;
float radius = 300;
- vec_t *col;
+ vec3_t col;
int style = -1;
const char *cubemapname = NULL;
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 forward, left, up;
VM_SAFEPARMCOUNTRANGE(3, 8, VM_CL_R_AddDynamicLight);
- // if we've run out of dlights, just return
- if (r_refdef.scene.numlights >= MAX_DLIGHTS)
- return;
+ // if we've run out of dlights, just return
+ if (r_refdef.scene.numlights >= MAX_DLIGHTS)
+ return;
+
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
+ radius = PRVM_G_FLOAT(OFS_PARM1);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM2), col);
+ if (prog->argc >= 4)
+ {
+ style = (int)PRVM_G_FLOAT(OFS_PARM3);
+ if (style >= MAX_LIGHTSTYLES)
+ {
+ Con_DPrintf("VM_CL_R_AddDynamicLight: out of bounds lightstyle index %i\n", style);
+ style = -1;
+ }
+ }
+ if (prog->argc >= 5)
+ cubemapname = PRVM_G_STRING(OFS_PARM4);
+ if (prog->argc >= 6)
+ pflags = (int)PRVM_G_FLOAT(OFS_PARM5);
+ coronaintensity = (pflags & PFLAGS_CORONA) != 0;
+ castshadow = (pflags & PFLAGS_NOSHADOW) == 0;
+
+ VectorScale(PRVM_clientglobalvector(v_forward), radius, forward);
+ VectorScale(PRVM_clientglobalvector(v_right), -radius, left);
+ VectorScale(PRVM_clientglobalvector(v_up), radius, up);
+ Matrix4x4_FromVectors(&matrix, forward, left, up, org);
+
+ R_RTLight_Update(&r_refdef.scene.templights[r_refdef.scene.numlights], false, &matrix, col, style, cubemapname, castshadow, coronaintensity, coronasizescale, ambientscale, diffusescale, specularscale, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
+ r_refdef.scene.lights[r_refdef.scene.numlights] = &r_refdef.scene.templights[r_refdef.scene.numlights];r_refdef.scene.numlights++;
+ t = Sys_DirtyTime() - t;if (t < 0 || t >= 1800) t = 0;
+ prog->functions[PRVM_clientfunction(CSQC_UpdateView)].totaltime -= t;
+}
+
+//============================================================================
+
+//#310 vector (vector v) cs_unproject (EXT_CSQC)
+static void VM_CL_unproject (prvm_prog_t *prog)
+{
+ vec3_t f;
+ vec3_t temp;
+ vec3_t result;
+
+ VM_SAFEPARMCOUNT(1, VM_CL_unproject);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), f);
+ VectorSet(temp,
+ f[2],
+ (-1.0 + 2.0 * (f[0] / vid_conwidth.integer)) * f[2] * -r_refdef.view.frustum_x,
+ (-1.0 + 2.0 * (f[1] / vid_conheight.integer)) * f[2] * -r_refdef.view.frustum_y);
+ if(v_flipped.integer)
+ temp[1] = -temp[1];
+ Matrix4x4_Transform(&r_refdef.view.matrix, temp, result);
+ VectorCopy(result, PRVM_G_VECTOR(OFS_RETURN));
+}
+
+//#311 vector (vector v) cs_project (EXT_CSQC)
+static void VM_CL_project (prvm_prog_t *prog)
+{
+ vec3_t f;
+ vec3_t v;
+ matrix4x4_t m;
+
+ VM_SAFEPARMCOUNT(1, VM_CL_project);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), f);
+ Matrix4x4_Invert_Full(&m, &r_refdef.view.matrix);
+ Matrix4x4_Transform(&m, f, v);
+ if(v_flipped.integer)
+ v[1] = -v[1];
+ VectorSet(PRVM_G_VECTOR(OFS_RETURN),
+ vid_conwidth.integer * (0.5*(1.0+v[1]/v[0]/-r_refdef.view.frustum_x)),
+ vid_conheight.integer * (0.5*(1.0+v[2]/v[0]/-r_refdef.view.frustum_y)),
+ v[0]);
+ // explanation:
+ // after transforming, relative position to viewport (0..1) = 0.5 * (1 + v[2]/v[0]/-frustum_{x \or y})
+ // 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;
- org = PRVM_G_VECTOR(OFS_PARM0);
- radius = PRVM_G_FLOAT(OFS_PARM1);
- col = PRVM_G_VECTOR(OFS_PARM2);
- if (prog->argc >= 4)
+ 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)
{
- style = (int)PRVM_G_FLOAT(OFS_PARM3);
- if (style >= MAX_LIGHTSTYLES)
- {
- Con_DPrintf("VM_CL_R_AddDynamicLight: out of bounds lightstyle index %i\n", style);
- style = -1;
- }
+ PRVM_G_FLOAT(OFS_RETURN) = -2;
+ VM_Warning(prog, "VM_drawfill: %s: wrong DRAWFLAG %i !\n",prog->name,flag);
+ return;
}
- if (prog->argc >= 5)
- cubemapname = PRVM_G_STRING(OFS_PARM4);
- if (prog->argc >= 6)
- pflags = (int)PRVM_G_FLOAT(OFS_PARM5);
- coronaintensity = (pflags & PFLAGS_CORONA) != 0;
- castshadow = (pflags & PFLAGS_NOSHADOW) == 0;
- VectorScale(PRVM_clientglobalvector(v_forward), radius, forward);
- VectorScale(PRVM_clientglobalvector(v_right), -radius, left);
- VectorScale(PRVM_clientglobalvector(v_up), radius, up);
- Matrix4x4_FromVectors(&matrix, forward, left, up, org);
+ 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")));
- R_RTLight_Update(&r_refdef.scene.templights[r_refdef.scene.numlights], false, &matrix, col, style, cubemapname, castshadow, coronaintensity, coronasizescale, ambientscale, diffusescale, specularscale, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
- r_refdef.scene.lights[r_refdef.scene.numlights] = &r_refdef.scene.templights[r_refdef.scene.numlights];r_refdef.scene.numlights++;
- t = Sys_DirtyTime() - t;if (t < 0 || t >= 1800) t = 0;
- prog->functions[PRVM_clientfunction(CSQC_UpdateView)].totaltime -= t;
+ 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
-//#310 vector (vector v) cs_unproject (EXT_CSQC)
-static void VM_CL_unproject (prvm_prog_t *prog)
+drawsetcliparea(float x, float y, float width, float height)
+=========
+*/
+void VM_drawsetcliparea(prvm_prog_t *prog)
{
- float *f;
- vec3_t temp;
+ float x,y,w,h;
+ VM_SAFEPARMCOUNT(4,VM_drawsetcliparea);
- VM_SAFEPARMCOUNT(1, VM_CL_unproject);
- f = PRVM_G_VECTOR(OFS_PARM0);
- VectorSet(temp,
- f[2],
- (-1.0 + 2.0 * (f[0] / vid_conwidth.integer)) * f[2] * -r_refdef.view.frustum_x,
- (-1.0 + 2.0 * (f[1] / vid_conheight.integer)) * f[2] * -r_refdef.view.frustum_y);
- if(v_flipped.integer)
- temp[1] = -temp[1];
- Matrix4x4_Transform(&r_refdef.view.matrix, temp, PRVM_G_VECTOR(OFS_RETURN));
+ // 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);
}
-//#311 vector (vector v) cs_project (EXT_CSQC)
-static void VM_CL_project (prvm_prog_t *prog)
+/*
+=========
+VM_drawresetcliparea
+
+drawresetcliparea()
+=========
+*/
+void VM_drawresetcliparea(prvm_prog_t *prog)
{
- float *f;
- vec3_t v;
- matrix4x4_t m;
+ VM_SAFEPARMCOUNT(0,VM_drawresetcliparea);
- VM_SAFEPARMCOUNT(1, VM_CL_project);
- f = PRVM_G_VECTOR(OFS_PARM0);
- Matrix4x4_Invert_Simple(&m, &r_refdef.view.matrix);
- Matrix4x4_Transform(&m, f, v);
- if(v_flipped.integer)
- v[1] = -v[1];
- VectorSet(PRVM_G_VECTOR(OFS_RETURN),
- vid_conwidth.integer * (0.5*(1.0+v[1]/v[0]/-r_refdef.view.frustum_x)),
- vid_conheight.integer * (0.5*(1.0+v[2]/v[0]/-r_refdef.view.frustum_y)),
- v[0]);
- // explanation:
- // after transforming, relative position to viewport (0..1) = 0.5 * (1 + v[2]/v[0]/-frustum_{x \or y})
- // as 2D drawing honors the viewport too, to get the same pixel, we simply multiply this by conwidth/height
+ // 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)
//#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);
static void VM_CL_trailparticles (prvm_prog_t *prog)
{
int i;
- float *start, *end;
+ vec3_t start, end, velocity;
prvm_edict_t *t;
VM_SAFEPARMCOUNTRANGE(4, 5, VM_CL_trailparticles);
t = PRVM_G_EDICT(OFS_PARM0);
i = (int)PRVM_G_FLOAT(OFS_PARM1);
- start = PRVM_G_VECTOR(OFS_PARM2);
- end = PRVM_G_VECTOR(OFS_PARM3);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM2), start);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM3), end);
+ VectorCopy(PRVM_clientedictvector(t, velocity), velocity);
if (i < 0)
return;
- CL_ParticleEffect(i, 1, start, end, PRVM_clientedictvector(t, velocity), PRVM_clientedictvector(t, velocity), NULL, prog->argc >= 5 ? (int)PRVM_G_FLOAT(OFS_PARM4) : 0);
+ CL_ParticleTrail(i, 1, start, end, velocity, velocity, NULL, prog->argc >= 5 ? (int)PRVM_G_FLOAT(OFS_PARM4) : 0, true, true, NULL, NULL, 1);
}
//#337 void(float effectnum, vector origin, vector dir, float count[, float color]) pointparticles (EXT_CSQC)
{
int i;
float n;
- float *f, *v;
+ vec3_t f, v;
VM_SAFEPARMCOUNTRANGE(4, 5, VM_CL_pointparticles);
i = (int)PRVM_G_FLOAT(OFS_PARM0);
- f = PRVM_G_VECTOR(OFS_PARM1);
- v = PRVM_G_VECTOR(OFS_PARM2);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), f);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM2), v);
n = PRVM_G_FLOAT(OFS_PARM3);
if (i < 0)
return;
{
int effectnum;
// prvm_edict_t *own;
- float *origin_from, *origin_to, *dir_from, *dir_to;
+ vec3_t origin_from, origin_to, dir_from, dir_to;
float count;
int flags;
- float tintmins[4], tintmaxs[4];
+ qbool istrail;
+ float tintmins[4], tintmaxs[4], fade;
VM_SAFEPARMCOUNTRANGE(7, 8, VM_CL_boxparticles);
effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
+ if (effectnum < 0)
+ return;
// own = PRVM_G_EDICT(OFS_PARM1); // TODO find use for this
- origin_from = PRVM_G_VECTOR(OFS_PARM2);
- origin_to = PRVM_G_VECTOR(OFS_PARM3);
- dir_from = PRVM_G_VECTOR(OFS_PARM4);
- dir_to = PRVM_G_VECTOR(OFS_PARM5);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin_from);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM3), origin_to );
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM4), dir_from );
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM5), dir_to );
count = PRVM_G_FLOAT(OFS_PARM6);
if(prog->argc >= 8)
flags = PRVM_G_FLOAT(OFS_PARM7);
else
flags = 0;
+
Vector4Set(tintmins, 1, 1, 1, 1);
Vector4Set(tintmaxs, 1, 1, 1, 1);
+ fade = 1;
+ istrail = false;
+
if(flags & 1) // read alpha
{
tintmins[3] = PRVM_clientglobalfloat(particles_alphamin);
VectorCopy(PRVM_clientglobalvector(particles_colormin), tintmins);
VectorCopy(PRVM_clientglobalvector(particles_colormax), tintmaxs);
}
- if (effectnum < 0)
- return;
- CL_ParticleTrail(effectnum, count, origin_from, origin_to, dir_from, dir_to, NULL, 0, true, true, tintmins, tintmaxs);
+ if(flags & 4) // read fade
+ {
+ fade = PRVM_clientglobalfloat(particles_fade);
+ }
+ if(flags & 128) // draw as trail
+ {
+ istrail = true;
+ }
+
+ if (istrail)
+ CL_ParticleTrail(effectnum, count, origin_from, origin_to, dir_from, dir_to, NULL, 0, true, true, tintmins, tintmaxs, fade);
+ else
+ CL_ParticleBox(effectnum, count, origin_from, origin_to, dir_from, dir_to, NULL, 0, true, true, tintmins, tintmaxs, fade);
}
//#531 void(float pause) setpause
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)
//#345 float(float framenum) getinputstate (EXT_CSQC)
static void VM_CL_getinputstate (prvm_prog_t *prog)
{
- int i, frame;
+ unsigned int i, frame;
VM_SAFEPARMCOUNT(1, VM_CL_getinputstate);
- frame = (int)PRVM_G_FLOAT(OFS_PARM0);
+ frame = (unsigned int)PRVM_G_FLOAT(OFS_PARM0);
PRVM_G_FLOAT(OFS_RETURN) = false;
for (i = 0;i < CL_MAX_USERCMDS;i++)
{
cl_clientmovement_state_t s;
prvm_edict_t *ent;
+ memset(&s, 0, sizeof(s));
+
VM_SAFEPARMCOUNTRANGE(0, 1, VM_CL_runplayerphysics);
ent = (prog->argc == 1 ? PRVM_G_EDICT(OFS_PARM0) : prog->edicts);
if(ent == prog->edicts)
{
// deprecated use
+ s.self = NULL;
VectorCopy(PRVM_clientglobalvector(pmove_org), s.origin);
VectorCopy(PRVM_clientglobalvector(pmove_vel), s.velocity);
VectorCopy(PRVM_clientglobalvector(pmove_mins), s.mins);
else
{
// new use
+ s.self = ent;
VectorCopy(PRVM_clientedictvector(ent, origin), s.origin);
VectorCopy(PRVM_clientedictvector(ent, velocity), s.velocity);
VectorCopy(PRVM_clientedictvector(ent, mins), s.mins);
else
if(!strcasecmp(c, "viewentity"))
dpsnprintf(t, sizeof(t), "%i", i+1);
- else
- if(gamemode == GAME_XONOTIC && !strcasecmp(c, "TEMPHACK_origin"))
- {
- // PLEASE REMOVE THIS once deltalisten() of EXT_CSQC_1
- // is implemented, or Xonotic uses CSQC-networked
- // players, whichever comes first
- entity_t *e = cl.entities + (i+1);
- if(e->state_current.active)
- {
- vec3_t origin;
- Matrix4x4_OriginFromMatrix(&e->render.matrix, origin);
- dpsnprintf(t, sizeof(t), "%.9g %.9g %.9g", origin[0], origin[1], origin[2]);
- }
- }
if(!t[0])
return;
PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, t);
//#351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
static void VM_CL_setlistener (prvm_prog_t *prog)
{
+ vec3_t origin, forward, left, up;
VM_SAFEPARMCOUNT(4, VM_CL_setlistener);
- Matrix4x4_FromVectors(&cl.csqc_listenermatrix, PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), PRVM_G_VECTOR(OFS_PARM3), PRVM_G_VECTOR(OFS_PARM0));
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), origin);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), forward);
+ VectorNegate(PRVM_G_VECTOR(OFS_PARM2), left);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM3), up);
+ Matrix4x4_FromVectors(&cl.csqc_listenermatrix, forward, left, up, origin);
cl.csqc_usecsqclistener = true; //use csqc listener at this frame
}
//#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");
-
+ Cmd_AddCommand(CF_CLIENT, PRVM_G_STRING(OFS_PARM0), NULL, "console command created by QuakeC");
}
//#360 float() readbyte (EXT_CSQC)
const char *name;
unsigned char *data;
unsigned char *buf;
- int size;
+ unsigned short size;
int i;
cachepic_t *pic;
VM_SAFEPARMCOUNT(0, VM_CL_ReadPicture);
name = MSG_ReadString(&cl_message, cl_readstring, sizeof(cl_readstring));
- size = MSG_ReadShort(&cl_message);
+ size = (unsigned short) MSG_ReadShort(&cl_message);
// check if a texture of that name exists
// if yes, it is used and the data is discarded
// if not, the (low quality) data is used to build a new texture, whose name will get returned
- pic = Draw_CachePic_Flags (name, CACHEPICFLAG_NOTPERSISTENT);
+ pic = Draw_CachePic_Flags(name, CACHEPICFLAG_NOTPERSISTENT | CACHEPICFLAG_FAILONMISSING);
if(size)
{
- if(pic->tex == r_texture_notexture)
- pic->tex = NULL; // don't overwrite the notexture by Draw_NewPic
- if(pic->tex && !cl_readpicture_force.integer)
+ if (Draw_IsPicLoaded(pic) && !cl_readpicture_force.integer)
{
// texture found and loaded
// skip over the jpeg as we don't need it
MSG_ReadBytes(&cl_message, size, buf);
data = JPEG_LoadImage_BGRA(buf, size, NULL);
Mem_Free(buf);
- Draw_NewPic(name, image_width, image_height, false, data);
+ Draw_NewPic(name, image_width, image_height, data, TEXTYPE_BGRA, TEXF_CLAMP);
Mem_Free(data);
}
}
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;
renderflags = (int)PRVM_clientedictfloat(ent, renderflags);
if (renderflags & RF_USEAXIS)
{
- vec3_t left;
+ vec3_t forward, left, up, origin;
+ VectorCopy(PRVM_clientglobalvector(v_forward), forward);
VectorNegate(PRVM_clientglobalvector(v_right), left);
- Matrix4x4_FromVectors(&staticent->render.matrix, PRVM_clientglobalvector(v_forward), left, PRVM_clientglobalvector(v_up), PRVM_clientedictvector(ent, origin));
+ VectorCopy(PRVM_clientglobalvector(v_up), up);
+ VectorCopy(PRVM_clientedictvector(ent, origin), origin);
+ Matrix4x4_FromVectors(&staticent->render.matrix, forward, left, up, origin);
Matrix4x4_Scale(&staticent->render.matrix, staticent->render.scale, 1);
}
else
{
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))
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;
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.vp, in->fields.vp, prog->entityfields * 4);
+ memcpy(out->fields.fp, in->fields.fp, prog->entityfields * sizeof(prvm_vec_t));
+
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)
{
+ model_t *model;
+ vec3_t org;
VM_SAFEPARMCOUNT(5, VM_CL_effect);
- CL_Effect(PRVM_G_VECTOR(OFS_PARM0), (int)PRVM_G_FLOAT(OFS_PARM1), (int)PRVM_G_FLOAT(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), PRVM_G_FLOAT(OFS_PARM4));
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
+
+ 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)
static void VM_CL_te_blood (prvm_prog_t *prog)
{
- float *pos;
- vec3_t pos2;
+ vec3_t pos, vel, pos2;
VM_SAFEPARMCOUNT(3, VM_CL_te_blood);
if (PRVM_G_FLOAT(OFS_PARM2) < 1)
return;
- pos = PRVM_G_VECTOR(OFS_PARM0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), vel);
CL_FindNonSolidLocation(pos, pos2, 4);
- CL_ParticleEffect(EFFECT_TE_BLOOD, PRVM_G_FLOAT(OFS_PARM2), pos2, pos2, PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM1), NULL, 0);
+ CL_ParticleEffect(EFFECT_TE_BLOOD, PRVM_G_FLOAT(OFS_PARM2), pos2, pos2, vel, vel, NULL, 0);
}
// #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
static void VM_CL_te_bloodshower (prvm_prog_t *prog)
{
vec_t speed;
- vec3_t vel1, vel2;
+ vec3_t mincorner, maxcorner, vel1, vel2;
VM_SAFEPARMCOUNT(4, VM_CL_te_bloodshower);
if (PRVM_G_FLOAT(OFS_PARM3) < 1)
return;
vel2[0] = speed;
vel2[1] = speed;
vel2[2] = speed;
- CL_ParticleEffect(EFFECT_TE_BLOOD, PRVM_G_FLOAT(OFS_PARM3), PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), vel1, vel2, NULL, 0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), mincorner);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), maxcorner);
+ CL_ParticleEffect(EFFECT_TE_BLOOD, PRVM_G_FLOAT(OFS_PARM3), mincorner, maxcorner, vel1, vel2, NULL, 0);
}
// #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
static void VM_CL_te_explosionrgb (prvm_prog_t *prog)
{
- float *pos;
+ vec3_t pos;
vec3_t pos2;
matrix4x4_t tempmatrix;
VM_SAFEPARMCOUNT(2, VM_CL_te_explosionrgb);
- pos = PRVM_G_VECTOR(OFS_PARM0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
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)
static void VM_CL_te_particlecube (prvm_prog_t *prog)
{
+ vec3_t mincorner, maxcorner, vel;
VM_SAFEPARMCOUNT(7, VM_CL_te_particlecube);
- CL_ParticleCube(PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4), PRVM_G_FLOAT(OFS_PARM5), PRVM_G_FLOAT(OFS_PARM6));
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), mincorner);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), maxcorner);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
+ CL_ParticleCube(mincorner, maxcorner, vel, (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4), PRVM_G_FLOAT(OFS_PARM5), PRVM_G_FLOAT(OFS_PARM6));
}
// #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
static void VM_CL_te_particlerain (prvm_prog_t *prog)
{
+ vec3_t mincorner, maxcorner, vel;
VM_SAFEPARMCOUNT(5, VM_CL_te_particlerain);
- CL_ParticleRain(PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4), 0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), mincorner);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), maxcorner);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
+ CL_ParticleRain(mincorner, maxcorner, vel, (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4), 0);
}
// #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
static void VM_CL_te_particlesnow (prvm_prog_t *prog)
{
+ vec3_t mincorner, maxcorner, vel;
VM_SAFEPARMCOUNT(5, VM_CL_te_particlesnow);
- CL_ParticleRain(PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4), 1);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), mincorner);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), maxcorner);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
+ CL_ParticleRain(mincorner, maxcorner, vel, (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4), 1);
}
// #411 void(vector org, vector vel, float howmany) te_spark
static void VM_CL_te_spark (prvm_prog_t *prog)
{
- float *pos;
- vec3_t pos2;
+ vec3_t pos, pos2, vel;
VM_SAFEPARMCOUNT(3, VM_CL_te_spark);
- pos = PRVM_G_VECTOR(OFS_PARM0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), vel);
CL_FindNonSolidLocation(pos, pos2, 4);
- CL_ParticleEffect(EFFECT_TE_SPARK, PRVM_G_FLOAT(OFS_PARM2), pos2, pos2, PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM1), NULL, 0);
+ CL_ParticleEffect(EFFECT_TE_SPARK, PRVM_G_FLOAT(OFS_PARM2), pos2, pos2, vel, vel, NULL, 0);
}
extern cvar_t cl_sound_ric_gunshot;
// #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
static void VM_CL_te_gunshotquad (prvm_prog_t *prog)
{
- float *pos;
- vec3_t pos2;
+ vec3_t pos, pos2;
int rnd;
VM_SAFEPARMCOUNT(1, VM_CL_te_gunshotquad);
- pos = PRVM_G_VECTOR(OFS_PARM0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
CL_FindNonSolidLocation(pos, pos2, 4);
CL_ParticleEffect(EFFECT_TE_GUNSHOTQUAD, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
if(cl_sound_ric_gunshot.integer >= 2)
// #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
static void VM_CL_te_spikequad (prvm_prog_t *prog)
{
- float *pos;
- vec3_t pos2;
+ vec3_t pos, pos2;
int rnd;
VM_SAFEPARMCOUNT(1, VM_CL_te_spikequad);
- pos = PRVM_G_VECTOR(OFS_PARM0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
CL_FindNonSolidLocation(pos, pos2, 4);
CL_ParticleEffect(EFFECT_TE_SPIKEQUAD, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
if (rand() % 5) S_StartSound(-1, 0, cl.sfx_tink1, pos2, 1, 1);
// #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
static void VM_CL_te_superspikequad (prvm_prog_t *prog)
{
- float *pos;
- vec3_t pos2;
+ vec3_t pos, pos2;
int rnd;
VM_SAFEPARMCOUNT(1, VM_CL_te_superspikequad);
- pos = PRVM_G_VECTOR(OFS_PARM0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
CL_FindNonSolidLocation(pos, pos2, 4);
CL_ParticleEffect(EFFECT_TE_SUPERSPIKEQUAD, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
if (rand() % 5) S_StartSound(-1, 0, cl.sfx_tink1, pos, 1, 1);
// #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
static void VM_CL_te_explosionquad (prvm_prog_t *prog)
{
- float *pos;
- vec3_t pos2;
+ vec3_t pos, pos2;
VM_SAFEPARMCOUNT(1, VM_CL_te_explosionquad);
- pos = PRVM_G_VECTOR(OFS_PARM0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
CL_FindNonSolidLocation(pos, pos2, 10);
CL_ParticleEffect(EFFECT_TE_EXPLOSIONQUAD, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
S_StartSound(-1, 0, cl.sfx_r_exp3, pos2, 1, 1);
// #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
static void VM_CL_te_smallflash (prvm_prog_t *prog)
{
- float *pos;
- vec3_t pos2;
+ vec3_t pos, pos2;
VM_SAFEPARMCOUNT(1, VM_CL_te_smallflash);
- pos = PRVM_G_VECTOR(OFS_PARM0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
CL_FindNonSolidLocation(pos, pos2, 10);
CL_ParticleEffect(EFFECT_TE_SMALLFLASH, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
}
// #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
static void VM_CL_te_customflash (prvm_prog_t *prog)
{
- float *pos;
- vec3_t pos2;
+ vec3_t pos, pos2;
matrix4x4_t tempmatrix;
VM_SAFEPARMCOUNT(4, VM_CL_te_customflash);
- pos = PRVM_G_VECTOR(OFS_PARM0);
+ 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)
static void VM_CL_te_gunshot (prvm_prog_t *prog)
{
- float *pos;
- vec3_t pos2;
+ vec3_t pos, pos2;
int rnd;
VM_SAFEPARMCOUNT(1, VM_CL_te_gunshot);
- pos = PRVM_G_VECTOR(OFS_PARM0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
CL_FindNonSolidLocation(pos, pos2, 4);
CL_ParticleEffect(EFFECT_TE_GUNSHOT, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
if(cl_sound_ric_gunshot.integer == 1 || cl_sound_ric_gunshot.integer == 3)
// #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
static void VM_CL_te_spike (prvm_prog_t *prog)
{
- float *pos;
- vec3_t pos2;
+ vec3_t pos, pos2;
int rnd;
VM_SAFEPARMCOUNT(1, VM_CL_te_spike);
- pos = PRVM_G_VECTOR(OFS_PARM0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
CL_FindNonSolidLocation(pos, pos2, 4);
CL_ParticleEffect(EFFECT_TE_SPIKE, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
if (rand() % 5) S_StartSound(-1, 0, cl.sfx_tink1, pos2, 1, 1);
// #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
static void VM_CL_te_superspike (prvm_prog_t *prog)
{
- float *pos;
- vec3_t pos2;
+ vec3_t pos, pos2;
int rnd;
VM_SAFEPARMCOUNT(1, VM_CL_te_superspike);
- pos = PRVM_G_VECTOR(OFS_PARM0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
CL_FindNonSolidLocation(pos, pos2, 4);
CL_ParticleEffect(EFFECT_TE_SUPERSPIKE, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
if (rand() % 5) S_StartSound(-1, 0, cl.sfx_tink1, pos2, 1, 1);
// #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
static void VM_CL_te_explosion (prvm_prog_t *prog)
{
- float *pos;
- vec3_t pos2;
+ vec3_t pos, pos2;
VM_SAFEPARMCOUNT(1, VM_CL_te_explosion);
- pos = PRVM_G_VECTOR(OFS_PARM0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
CL_FindNonSolidLocation(pos, pos2, 10);
CL_ParticleEffect(EFFECT_TE_EXPLOSION, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
S_StartSound(-1, 0, cl.sfx_r_exp3, pos2, 1, 1);
// #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
static void VM_CL_te_tarexplosion (prvm_prog_t *prog)
{
- float *pos;
- vec3_t pos2;
+ vec3_t pos, pos2;
VM_SAFEPARMCOUNT(1, VM_CL_te_tarexplosion);
- pos = PRVM_G_VECTOR(OFS_PARM0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
CL_FindNonSolidLocation(pos, pos2, 10);
CL_ParticleEffect(EFFECT_TE_TAREXPLOSION, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
S_StartSound(-1, 0, cl.sfx_r_exp3, pos2, 1, 1);
// #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
static void VM_CL_te_wizspike (prvm_prog_t *prog)
{
- float *pos;
- vec3_t pos2;
+ vec3_t pos, pos2;
VM_SAFEPARMCOUNT(1, VM_CL_te_wizspike);
- pos = PRVM_G_VECTOR(OFS_PARM0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
CL_FindNonSolidLocation(pos, pos2, 4);
CL_ParticleEffect(EFFECT_TE_WIZSPIKE, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
S_StartSound(-1, 0, cl.sfx_wizhit, pos2, 1, 1);
// #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
static void VM_CL_te_knightspike (prvm_prog_t *prog)
{
- float *pos;
- vec3_t pos2;
+ vec3_t pos, pos2;
VM_SAFEPARMCOUNT(1, VM_CL_te_knightspike);
- pos = PRVM_G_VECTOR(OFS_PARM0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
CL_FindNonSolidLocation(pos, pos2, 4);
CL_ParticleEffect(EFFECT_TE_KNIGHTSPIKE, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
S_StartSound(-1, 0, cl.sfx_knighthit, pos2, 1, 1);
// #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
static void VM_CL_te_lavasplash (prvm_prog_t *prog)
{
+ vec3_t pos;
VM_SAFEPARMCOUNT(1, VM_CL_te_lavasplash);
- CL_ParticleEffect(EFFECT_TE_LAVASPLASH, 1, PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM0), vec3_origin, vec3_origin, NULL, 0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
+ CL_ParticleEffect(EFFECT_TE_LAVASPLASH, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
}
// #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
static void VM_CL_te_teleport (prvm_prog_t *prog)
{
+ vec3_t pos;
VM_SAFEPARMCOUNT(1, VM_CL_te_teleport);
- CL_ParticleEffect(EFFECT_TE_TELEPORT, 1, PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM0), vec3_origin, vec3_origin, NULL, 0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
+ CL_ParticleEffect(EFFECT_TE_TELEPORT, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
}
// #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
static void VM_CL_te_explosion2 (prvm_prog_t *prog)
{
- float *pos;
- vec3_t pos2, color;
+ vec3_t pos, pos2, color;
matrix4x4_t tempmatrix;
int colorStart, colorLength;
unsigned char *tempcolor;
VM_SAFEPARMCOUNT(3, VM_CL_te_explosion2);
- pos = PRVM_G_VECTOR(OFS_PARM0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
colorStart = (int)PRVM_G_FLOAT(OFS_PARM1);
colorLength = (int)PRVM_G_FLOAT(OFS_PARM2);
CL_FindNonSolidLocation(pos, pos2, 10);
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);
}
// #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
static void VM_CL_te_lightning1 (prvm_prog_t *prog)
{
+ vec3_t start, end;
VM_SAFEPARMCOUNT(3, VM_CL_te_lightning1);
- CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_bolt, true);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), start);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM2), end);
+ CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), start, end, cl.model_bolt, true);
}
// #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
static void VM_CL_te_lightning2 (prvm_prog_t *prog)
{
+ vec3_t start, end;
VM_SAFEPARMCOUNT(3, VM_CL_te_lightning2);
- CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_bolt2, true);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), start);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM2), end);
+ CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), start, end, cl.model_bolt2, true);
}
// #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
static void VM_CL_te_lightning3 (prvm_prog_t *prog)
{
+ vec3_t start, end;
VM_SAFEPARMCOUNT(3, VM_CL_te_lightning3);
- CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_bolt3, false);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), start);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM2), end);
+ CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), start, end, cl.model_bolt3, false);
}
// #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
static void VM_CL_te_beam (prvm_prog_t *prog)
{
+ vec3_t start, end;
VM_SAFEPARMCOUNT(3, VM_CL_te_beam);
- CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_beam, false);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), start);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM2), end);
+ CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), start, end, cl.model_beam, false);
}
// #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
static void VM_CL_te_plasmaburn (prvm_prog_t *prog)
{
- float *pos;
- vec3_t pos2;
+ vec3_t pos, pos2;
VM_SAFEPARMCOUNT(1, VM_CL_te_plasmaburn);
- pos = PRVM_G_VECTOR(OFS_PARM0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
CL_FindNonSolidLocation(pos, pos2, 4);
CL_ParticleEffect(EFFECT_TE_PLASMABURN, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
}
// #457 void(vector org, vector velocity, float howmany) te_flamejet (DP_TE_FLAMEJET)
static void VM_CL_te_flamejet (prvm_prog_t *prog)
{
- float *pos;
- vec3_t pos2;
+ vec3_t pos, pos2, vel;
VM_SAFEPARMCOUNT(3, VM_CL_te_flamejet);
if (PRVM_G_FLOAT(OFS_PARM2) < 1)
return;
- pos = PRVM_G_VECTOR(OFS_PARM0);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), vel);
CL_FindNonSolidLocation(pos, pos2, 4);
- CL_ParticleEffect(EFFECT_TE_FLAMEJET, PRVM_G_FLOAT(OFS_PARM2), pos2, pos2, PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM1), NULL, 0);
+ CL_ParticleEffect(EFFECT_TE_FLAMEJET, PRVM_G_FLOAT(OFS_PARM2), pos2, pos2, vel, vel, NULL, 0);
}
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);
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;
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
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;
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;
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)
{
VM_GenerateFrameGroupBlend(prog, ent->priv.server->framegroupblend, ent);
- VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
+ VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model, cl.time);
VM_UpdateEdictSkeleton(prog, ent, model, ent->priv.server->frameblend);
return Mod_Alias_GetTagMatrix(model, ent->priv.server->frameblend, &ent->priv.server->skeleton, tagindex, out);
}
extern cvar_t cl_bob;
extern cvar_t cl_bobcycle;
extern cvar_t cl_bobup;
-int CL_GetTagMatrix (prvm_prog_t *prog, matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
+int CL_GetTagMatrix (prvm_prog_t *prog, matrix4x4_t *out, prvm_edict_t *ent, int tagindex, prvm_vec_t *returnshadingorigin)
{
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);
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;
Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
}
*/
+
+ // return the origin of the view
+ Matrix4x4_OriginFromMatrix(&r_refdef.view.matrix, shadingorigin);
+ }
+ else
+ {
+ // return the origin of the root entity in the chain
+ Matrix4x4_OriginFromMatrix(out, shadingorigin);
}
+ if (returnshadingorigin)
+ VectorCopy(shadingorigin, returnshadingorigin);
return 0;
}
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;
int parentindex;
const char *tagname;
int returncode;
- vec3_t fo, le, up, trans;
- const dp_model_t *model;
+ vec3_t forward, left, up, origin;
+ const model_t *model;
VM_SAFEPARMCOUNT(2, VM_CL_gettaginfo);
e = PRVM_G_EDICT(OFS_PARM0);
tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
- returncode = CL_GetTagMatrix(prog, &tag_matrix, e, tagindex);
- Matrix4x4_ToVectors(&tag_matrix, PRVM_clientglobalvector(v_forward), le, PRVM_clientglobalvector(v_up), PRVM_G_VECTOR(OFS_RETURN));
- VectorScale(le, -1, PRVM_clientglobalvector(v_right));
+ returncode = CL_GetTagMatrix(prog, &tag_matrix, e, tagindex, NULL);
+ Matrix4x4_ToVectors(&tag_matrix, forward, left, up, origin);
+ VectorCopy(forward, PRVM_clientglobalvector(v_forward));
+ VectorScale(left, -1, PRVM_clientglobalvector(v_right));
+ VectorCopy(up, PRVM_clientglobalvector(v_up));
+ VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
model = CL_GetModelFromEdict(e);
VM_GenerateFrameGroupBlend(prog, e->priv.server->framegroupblend, e);
- VM_FrameBlendFromFrameGroupBlend(e->priv.server->frameblend, e->priv.server->framegroupblend, model);
+ VM_FrameBlendFromFrameGroupBlend(e->priv.server->frameblend, e->priv.server->framegroupblend, model, cl.time);
VM_UpdateEdictSkeleton(prog, e, model, e->priv.server->frameblend);
CL_GetExtendedTagInfo(prog, e, tagindex, &parentindex, &tagname, &tag_localmatrix);
- Matrix4x4_ToVectors(&tag_localmatrix, fo, le, up, trans);
+ Matrix4x4_ToVectors(&tag_localmatrix, forward, left, up, origin);
PRVM_clientglobalfloat(gettaginfo_parent) = parentindex;
PRVM_clientglobalstring(gettaginfo_name) = tagname ? PRVM_SetTempString(prog, tagname) : 0;
- VectorCopy(trans, PRVM_clientglobalvector(gettaginfo_offset));
- VectorCopy(fo, PRVM_clientglobalvector(gettaginfo_forward));
- VectorScale(le, -1, PRVM_clientglobalvector(gettaginfo_right));
+ VectorCopy(forward, PRVM_clientglobalvector(gettaginfo_forward));
+ VectorScale(left, -1, PRVM_clientglobalvector(gettaginfo_right));
VectorCopy(up, PRVM_clientglobalvector(gettaginfo_up));
+ VectorCopy(origin, PRVM_clientglobalvector(gettaginfo_offset));
switch(returncode)
{
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;
- // global addresses
- float *particle_type;
- float *particle_blendmode;
- float *particle_orientation;
- float *particle_color1;
- float *particle_color2;
- float *particle_tex;
- float *particle_size;
- float *particle_sizeincrease;
- float *particle_alpha;
- float *particle_alphafade;
- float *particle_time;
- float *particle_gravity;
- float *particle_bounce;
- float *particle_airfriction;
- float *particle_liquidfriction;
- float *particle_originjitter;
- float *particle_velocityjitter;
- float *particle_qualityreduction;
- float *particle_stretch;
- float *particle_staincolor1;
- float *particle_staincolor2;
- float *particle_stainalpha;
- float *particle_stainsize;
- float *particle_staintex;
- float *particle_delayspawn;
- float *particle_delaycollision;
- float *particle_angle;
- float *particle_spin;
}vmparticlespawner_t;
vmparticlespawner_t vmpartspawner;
vmpartspawner.max_themes = maxthemes;
vmpartspawner.initialized = true;
vmpartspawner.verified = true;
- // get field addresses for fast querying (we can do 1000 calls of spawnparticle in a frame)
- vmpartspawner.particle_type = &PRVM_clientglobalfloat(particle_type);
- vmpartspawner.particle_blendmode = &PRVM_clientglobalfloat(particle_blendmode);
- vmpartspawner.particle_orientation = &PRVM_clientglobalfloat(particle_orientation);
- vmpartspawner.particle_color1 = PRVM_clientglobalvector(particle_color1);
- vmpartspawner.particle_color2 = PRVM_clientglobalvector(particle_color2);
- vmpartspawner.particle_tex = &PRVM_clientglobalfloat(particle_tex);
- vmpartspawner.particle_size = &PRVM_clientglobalfloat(particle_size);
- vmpartspawner.particle_sizeincrease = &PRVM_clientglobalfloat(particle_sizeincrease);
- vmpartspawner.particle_alpha = &PRVM_clientglobalfloat(particle_alpha);
- vmpartspawner.particle_alphafade = &PRVM_clientglobalfloat(particle_alphafade);
- vmpartspawner.particle_time = &PRVM_clientglobalfloat(particle_time);
- vmpartspawner.particle_gravity = &PRVM_clientglobalfloat(particle_gravity);
- vmpartspawner.particle_bounce = &PRVM_clientglobalfloat(particle_bounce);
- vmpartspawner.particle_airfriction = &PRVM_clientglobalfloat(particle_airfriction);
- vmpartspawner.particle_liquidfriction = &PRVM_clientglobalfloat(particle_liquidfriction);
- vmpartspawner.particle_originjitter = &PRVM_clientglobalfloat(particle_originjitter);
- vmpartspawner.particle_velocityjitter = &PRVM_clientglobalfloat(particle_velocityjitter);
- vmpartspawner.particle_qualityreduction = &PRVM_clientglobalfloat(particle_qualityreduction);
- vmpartspawner.particle_stretch = &PRVM_clientglobalfloat(particle_stretch);
- vmpartspawner.particle_staincolor1 = PRVM_clientglobalvector(particle_staincolor1);
- vmpartspawner.particle_staincolor2 = PRVM_clientglobalvector(particle_staincolor2);
- vmpartspawner.particle_stainalpha = &PRVM_clientglobalfloat(particle_stainalpha);
- vmpartspawner.particle_stainsize = &PRVM_clientglobalfloat(particle_stainsize);
- vmpartspawner.particle_staintex = &PRVM_clientglobalfloat(particle_staintex);
- vmpartspawner.particle_staintex = &PRVM_clientglobalfloat(particle_staintex);
- vmpartspawner.particle_delayspawn = &PRVM_clientglobalfloat(particle_delayspawn);
- vmpartspawner.particle_delaycollision = &PRVM_clientglobalfloat(particle_delaycollision);
- vmpartspawner.particle_angle = &PRVM_clientglobalfloat(particle_angle);
- vmpartspawner.particle_spin = &PRVM_clientglobalfloat(particle_spin);
- #undef getglobal
- #undef getglobalvector
}
// reset particle theme to default values
}
// particle theme -> QC globals
-static void VM_CL_ParticleThemeToGlobals(vmparticletheme_t *theme)
-{
- *vmpartspawner.particle_type = theme->typeindex;
- *vmpartspawner.particle_blendmode = theme->blendmode;
- *vmpartspawner.particle_orientation = theme->orientation;
- vmpartspawner.particle_color1[0] = (theme->color1 >> 16) & 0xFF; // VorteX: int only can store 0-255, not 0-256 which means 0 - 0,99609375...
- vmpartspawner.particle_color1[1] = (theme->color1 >> 8) & 0xFF;
- vmpartspawner.particle_color1[2] = (theme->color1 >> 0) & 0xFF;
- vmpartspawner.particle_color2[0] = (theme->color2 >> 16) & 0xFF;
- vmpartspawner.particle_color2[1] = (theme->color2 >> 8) & 0xFF;
- vmpartspawner.particle_color2[2] = (theme->color2 >> 0) & 0xFF;
- *vmpartspawner.particle_tex = (float)theme->tex;
- *vmpartspawner.particle_size = theme->size;
- *vmpartspawner.particle_sizeincrease = theme->sizeincrease;
- *vmpartspawner.particle_alpha = theme->alpha/256;
- *vmpartspawner.particle_alphafade = theme->alphafade/256;
- *vmpartspawner.particle_time = theme->lifetime;
- *vmpartspawner.particle_gravity = theme->gravity;
- *vmpartspawner.particle_bounce = theme->bounce;
- *vmpartspawner.particle_airfriction = theme->airfriction;
- *vmpartspawner.particle_liquidfriction = theme->liquidfriction;
- *vmpartspawner.particle_originjitter = theme->originjitter;
- *vmpartspawner.particle_velocityjitter = theme->velocityjitter;
- *vmpartspawner.particle_qualityreduction = theme->qualityreduction;
- *vmpartspawner.particle_stretch = theme->stretch;
- vmpartspawner.particle_staincolor1[0] = ((int)theme->staincolor1 >> 16) & 0xFF;
- vmpartspawner.particle_staincolor1[1] = ((int)theme->staincolor1 >> 8) & 0xFF;
- vmpartspawner.particle_staincolor1[2] = ((int)theme->staincolor1 >> 0) & 0xFF;
- vmpartspawner.particle_staincolor2[0] = ((int)theme->staincolor2 >> 16) & 0xFF;
- vmpartspawner.particle_staincolor2[1] = ((int)theme->staincolor2 >> 8) & 0xFF;
- vmpartspawner.particle_staincolor2[2] = ((int)theme->staincolor2 >> 0) & 0xFF;
- *vmpartspawner.particle_staintex = (float)theme->staintex;
- *vmpartspawner.particle_stainalpha = (float)theme->stainalpha/256;
- *vmpartspawner.particle_stainsize = (float)theme->stainsize;
- *vmpartspawner.particle_delayspawn = theme->delayspawn;
- *vmpartspawner.particle_delaycollision = theme->delaycollision;
- *vmpartspawner.particle_angle = theme->angle;
- *vmpartspawner.particle_spin = theme->spin;
+static void VM_CL_ParticleThemeToGlobals(vmparticletheme_t *theme, prvm_prog_t *prog)
+{
+ PRVM_clientglobalfloat(particle_type) = theme->typeindex;
+ PRVM_clientglobalfloat(particle_blendmode) = theme->blendmode;
+ PRVM_clientglobalfloat(particle_orientation) = theme->orientation;
+ // VorteX: int only can store 0-255, not 0-256 which means 0 - 0,99609375...
+ VectorSet(PRVM_clientglobalvector(particle_color1), (theme->color1 >> 16) & 0xFF, (theme->color1 >> 8) & 0xFF, (theme->color1 >> 0) & 0xFF);
+ VectorSet(PRVM_clientglobalvector(particle_color2), (theme->color2 >> 16) & 0xFF, (theme->color2 >> 8) & 0xFF, (theme->color2 >> 0) & 0xFF);
+ PRVM_clientglobalfloat(particle_tex) = (prvm_vec_t)theme->tex;
+ PRVM_clientglobalfloat(particle_size) = theme->size;
+ PRVM_clientglobalfloat(particle_sizeincrease) = theme->sizeincrease;
+ PRVM_clientglobalfloat(particle_alpha) = theme->alpha/256;
+ PRVM_clientglobalfloat(particle_alphafade) = theme->alphafade/256;
+ PRVM_clientglobalfloat(particle_time) = theme->lifetime;
+ PRVM_clientglobalfloat(particle_gravity) = theme->gravity;
+ PRVM_clientglobalfloat(particle_bounce) = theme->bounce;
+ PRVM_clientglobalfloat(particle_airfriction) = theme->airfriction;
+ PRVM_clientglobalfloat(particle_liquidfriction) = theme->liquidfriction;
+ PRVM_clientglobalfloat(particle_originjitter) = theme->originjitter;
+ PRVM_clientglobalfloat(particle_velocityjitter) = theme->velocityjitter;
+ PRVM_clientglobalfloat(particle_qualityreduction) = theme->qualityreduction;
+ PRVM_clientglobalfloat(particle_stretch) = theme->stretch;
+ VectorSet(PRVM_clientglobalvector(particle_staincolor1), ((int)theme->staincolor1 >> 16) & 0xFF, ((int)theme->staincolor1 >> 8) & 0xFF, ((int)theme->staincolor1 >> 0) & 0xFF);
+ VectorSet(PRVM_clientglobalvector(particle_staincolor2), ((int)theme->staincolor2 >> 16) & 0xFF, ((int)theme->staincolor2 >> 8) & 0xFF, ((int)theme->staincolor2 >> 0) & 0xFF);
+ PRVM_clientglobalfloat(particle_staintex) = (prvm_vec_t)theme->staintex;
+ PRVM_clientglobalfloat(particle_stainalpha) = (prvm_vec_t)theme->stainalpha/256;
+ PRVM_clientglobalfloat(particle_stainsize) = (prvm_vec_t)theme->stainsize;
+ PRVM_clientglobalfloat(particle_delayspawn) = theme->delayspawn;
+ PRVM_clientglobalfloat(particle_delaycollision) = theme->delaycollision;
+ PRVM_clientglobalfloat(particle_angle) = theme->angle;
+ PRVM_clientglobalfloat(particle_spin) = theme->spin;
}
// QC globals -> particle theme
-static void VM_CL_ParticleThemeFromGlobals(vmparticletheme_t *theme)
-{
- theme->typeindex = (unsigned short)*vmpartspawner.particle_type;
- theme->blendmode = (pblend_t)(int)*vmpartspawner.particle_blendmode;
- theme->orientation = (porientation_t)(int)*vmpartspawner.particle_orientation;
- theme->color1 = ((int)vmpartspawner.particle_color1[0] << 16) + ((int)vmpartspawner.particle_color1[1] << 8) + ((int)vmpartspawner.particle_color1[2]);
- theme->color2 = ((int)vmpartspawner.particle_color2[0] << 16) + ((int)vmpartspawner.particle_color2[1] << 8) + ((int)vmpartspawner.particle_color2[2]);
- theme->tex = (int)*vmpartspawner.particle_tex;
- theme->size = *vmpartspawner.particle_size;
- theme->sizeincrease = *vmpartspawner.particle_sizeincrease;
- theme->alpha = *vmpartspawner.particle_alpha*256;
- theme->alphafade = *vmpartspawner.particle_alphafade*256;
- theme->lifetime = *vmpartspawner.particle_time;
- theme->gravity = *vmpartspawner.particle_gravity;
- theme->bounce = *vmpartspawner.particle_bounce;
- theme->airfriction = *vmpartspawner.particle_airfriction;
- theme->liquidfriction = *vmpartspawner.particle_liquidfriction;
- theme->originjitter = *vmpartspawner.particle_originjitter;
- theme->velocityjitter = *vmpartspawner.particle_velocityjitter;
- theme->qualityreduction = (*vmpartspawner.particle_qualityreduction) ? true : false;
- theme->stretch = *vmpartspawner.particle_stretch;
- theme->staincolor1 = ((int)vmpartspawner.particle_staincolor1[0])*65536 + (int)(vmpartspawner.particle_staincolor1[1])*256 + (int)(vmpartspawner.particle_staincolor1[2]);
- theme->staincolor2 = (int)(vmpartspawner.particle_staincolor2[0])*65536 + (int)(vmpartspawner.particle_staincolor2[1])*256 + (int)(vmpartspawner.particle_staincolor2[2]);
- theme->staintex =(int)*vmpartspawner.particle_staintex;
- theme->stainalpha = *vmpartspawner.particle_stainalpha*256;
- theme->stainsize = *vmpartspawner.particle_stainsize;
- theme->delayspawn = *vmpartspawner.particle_delayspawn;
- theme->delaycollision = *vmpartspawner.particle_delaycollision;
- theme->angle = *vmpartspawner.particle_angle;
- theme->spin = *vmpartspawner.particle_spin;
+static void VM_CL_ParticleThemeFromGlobals(vmparticletheme_t *theme, prvm_prog_t *prog)
+{
+ theme->typeindex = (unsigned short)PRVM_clientglobalfloat(particle_type);
+ theme->blendmode = (pblend_t)(int)PRVM_clientglobalfloat(particle_blendmode);
+ theme->orientation = (porientation_t)(int)PRVM_clientglobalfloat(particle_orientation);
+ theme->color1 = ((int)PRVM_clientglobalvector(particle_color1)[0] << 16) + ((int)PRVM_clientglobalvector(particle_color1)[1] << 8) + ((int)PRVM_clientglobalvector(particle_color1)[2]);
+ theme->color2 = ((int)PRVM_clientglobalvector(particle_color2)[0] << 16) + ((int)PRVM_clientglobalvector(particle_color2)[1] << 8) + ((int)PRVM_clientglobalvector(particle_color2)[2]);
+ theme->tex = (int)PRVM_clientglobalfloat(particle_tex);
+ theme->size = PRVM_clientglobalfloat(particle_size);
+ theme->sizeincrease = PRVM_clientglobalfloat(particle_sizeincrease);
+ theme->alpha = PRVM_clientglobalfloat(particle_alpha)*256;
+ theme->alphafade = PRVM_clientglobalfloat(particle_alphafade)*256;
+ theme->lifetime = PRVM_clientglobalfloat(particle_time);
+ theme->gravity = PRVM_clientglobalfloat(particle_gravity);
+ theme->bounce = PRVM_clientglobalfloat(particle_bounce);
+ theme->airfriction = PRVM_clientglobalfloat(particle_airfriction);
+ theme->liquidfriction = PRVM_clientglobalfloat(particle_liquidfriction);
+ theme->originjitter = PRVM_clientglobalfloat(particle_originjitter);
+ theme->velocityjitter = PRVM_clientglobalfloat(particle_velocityjitter);
+ theme->qualityreduction = PRVM_clientglobalfloat(particle_qualityreduction) != 0 ? true : false;
+ theme->stretch = PRVM_clientglobalfloat(particle_stretch);
+ theme->staincolor1 = ((int)PRVM_clientglobalvector(particle_staincolor1)[0])*65536 + (int)(PRVM_clientglobalvector(particle_staincolor1)[1])*256 + (int)(PRVM_clientglobalvector(particle_staincolor1)[2]);
+ theme->staincolor2 = (int)(PRVM_clientglobalvector(particle_staincolor2)[0])*65536 + (int)(PRVM_clientglobalvector(particle_staincolor2)[1])*256 + (int)(PRVM_clientglobalvector(particle_staincolor2)[2]);
+ theme->staintex =(int)PRVM_clientglobalfloat(particle_staintex);
+ theme->stainalpha = PRVM_clientglobalfloat(particle_stainalpha)*256;
+ theme->stainsize = PRVM_clientglobalfloat(particle_stainsize);
+ theme->delayspawn = PRVM_clientglobalfloat(particle_delayspawn);
+ theme->delaycollision = PRVM_clientglobalfloat(particle_delaycollision);
+ theme->angle = PRVM_clientglobalfloat(particle_angle);
+ theme->spin = PRVM_clientglobalfloat(particle_spin);
}
// init particle spawner interface
VM_Warning(prog, "VM_CL_ResetParticle: particle spawner not initialized\n");
return;
}
- VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[0]);
+ VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[0], prog);
}
// void(float themenum) particletheme
if (themenum < 0 || themenum >= vmpartspawner.max_themes)
{
VM_Warning(prog, "VM_CL_ParticleTheme: bad theme number %i\n", themenum);
- VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[0]);
+ VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[0], prog);
return;
}
if (vmpartspawner.themes[themenum].initialized == false)
{
VM_Warning(prog, "VM_CL_ParticleTheme: theme #%i not exists\n", themenum);
- VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[0]);
+ VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[0], prog);
return;
}
// load particle theme into globals
- VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[themenum]);
+ VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[themenum], prog);
}
// float() saveparticletheme
return;
}
vmpartspawner.themes[themenum].initialized = true;
- VM_CL_ParticleThemeFromGlobals(&vmpartspawner.themes[themenum]);
+ VM_CL_ParticleThemeFromGlobals(&vmpartspawner.themes[themenum], prog);
PRVM_G_FLOAT(OFS_RETURN) = themenum;
return;
}
return;
}
vmpartspawner.themes[themenum].initialized = true;
- VM_CL_ParticleThemeFromGlobals(&vmpartspawner.themes[themenum]);
+ VM_CL_ParticleThemeFromGlobals(&vmpartspawner.themes[themenum], prog);
}
// void(float themenum) freeparticletheme
if (vmpartspawner.themes[themenum].initialized == false)
{
VM_Warning(prog, "VM_CL_ParticleThemeFree: theme #%i already freed\n", themenum);
- VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[0]);
+ VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[0], prog);
return;
}
// free theme
// returns 0 if failed, 1 if succesful
static void VM_CL_SpawnParticle (prvm_prog_t *prog)
{
- float *org, *dir;
+ vec3_t org, dir;
vmparticletheme_t *theme;
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;
}
- org = PRVM_G_VECTOR(OFS_PARM0);
- dir = PRVM_G_VECTOR(OFS_PARM1);
-
+ 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, (unsigned short)*vmpartspawner.particle_type, ((int)(vmpartspawner.particle_color1[0]) << 16) + ((int)(vmpartspawner.particle_color1[1]) << 8) + ((int)(vmpartspawner.particle_color1[2])), ((int)vmpartspawner.particle_color2[0] << 16) + ((int)vmpartspawner.particle_color2[1] << 8) + ((int)vmpartspawner.particle_color2[2]), (int)*vmpartspawner.particle_tex, *vmpartspawner.particle_size, *vmpartspawner.particle_sizeincrease, *vmpartspawner.particle_alpha*256, *vmpartspawner.particle_alphafade*256, *vmpartspawner.particle_gravity, *vmpartspawner.particle_bounce, org[0], org[1], org[2], dir[0], dir[1], dir[2], *vmpartspawner.particle_airfriction, *vmpartspawner.particle_liquidfriction, *vmpartspawner.particle_originjitter, *vmpartspawner.particle_velocityjitter, (*vmpartspawner.particle_qualityreduction) ? true : false, *vmpartspawner.particle_time, *vmpartspawner.particle_stretch, (pblend_t)(int)*vmpartspawner.particle_blendmode, (porientation_t)(int)*vmpartspawner.particle_orientation, (int)(vmpartspawner.particle_staincolor1[0])*65536 + (int)(vmpartspawner.particle_staincolor1[1])*256 + (int)(vmpartspawner.particle_staincolor1[2]), (int)(vmpartspawner.particle_staincolor2[0])*65536 + (int)(vmpartspawner.particle_staincolor2[1])*256 + (int)(vmpartspawner.particle_staincolor2[2]), (int)*vmpartspawner.particle_staintex, *vmpartspawner.particle_stainalpha*256, *vmpartspawner.particle_stainsize, *vmpartspawner.particle_angle, *vmpartspawner.particle_spin, NULL);
+ part = CL_NewParticle(org,
+ (unsigned short)PRVM_clientglobalfloat(particle_type),
+ ((int)PRVM_clientglobalvector(particle_color1)[0] << 16) + ((int)PRVM_clientglobalvector(particle_color1)[1] << 8) + ((int)PRVM_clientglobalvector(particle_color1)[2]),
+ ((int)PRVM_clientglobalvector(particle_color2)[0] << 16) + ((int)PRVM_clientglobalvector(particle_color2)[1] << 8) + ((int)PRVM_clientglobalvector(particle_color2)[2]),
+ (int)PRVM_clientglobalfloat(particle_tex),
+ PRVM_clientglobalfloat(particle_size),
+ PRVM_clientglobalfloat(particle_sizeincrease),
+ PRVM_clientglobalfloat(particle_alpha)*256,
+ PRVM_clientglobalfloat(particle_alphafade)*256,
+ PRVM_clientglobalfloat(particle_gravity),
+ PRVM_clientglobalfloat(particle_bounce),
+ org[0],
+ org[1],
+ org[2],
+ dir[0],
+ dir[1],
+ dir[2],
+ PRVM_clientglobalfloat(particle_airfriction),
+ PRVM_clientglobalfloat(particle_liquidfriction),
+ PRVM_clientglobalfloat(particle_originjitter),
+ PRVM_clientglobalfloat(particle_velocityjitter),
+ (PRVM_clientglobalfloat(particle_qualityreduction)) ? true : false,
+ PRVM_clientglobalfloat(particle_time),
+ PRVM_clientglobalfloat(particle_stretch),
+ (pblend_t)(int)PRVM_clientglobalfloat(particle_blendmode),
+ (porientation_t)(int)PRVM_clientglobalfloat(particle_orientation),
+ (int)(PRVM_clientglobalvector(particle_staincolor1)[0])*65536 + (int)(PRVM_clientglobalvector(particle_staincolor1)[1])*256 + (int)(PRVM_clientglobalvector(particle_staincolor1)[2]),
+ (int)(PRVM_clientglobalvector(particle_staincolor2)[0])*65536 + (int)(PRVM_clientglobalvector(particle_staincolor2)[1])*256 + (int)(PRVM_clientglobalvector(particle_staincolor2)[2]),
+ (int)PRVM_clientglobalfloat(particle_staintex),
+ PRVM_clientglobalfloat(particle_stainalpha)*256,
+ PRVM_clientglobalfloat(particle_stainsize),
+ PRVM_clientglobalfloat(particle_angle),
+ PRVM_clientglobalfloat(particle_spin),
+ NULL);
if (!part)
{
- PRVM_G_FLOAT(OFS_RETURN) = 0;
+ PRVM_G_FLOAT(OFS_RETURN) = 0;
return;
}
- if (*vmpartspawner.particle_delayspawn)
- part->delayedspawn = cl.time + *vmpartspawner.particle_delayspawn;
- //if (*vmpartspawner.particle_delaycollision)
- // part->delayedcollisions = cl.time + *vmpartspawner.particle_delaycollision;
+ if (PRVM_clientglobalfloat(particle_delayspawn))
+ part->delayedspawn = cl.time + PRVM_clientglobalfloat(particle_delayspawn);
+ //if (PRVM_clientglobalfloat(particle_delaycollision))
+ // part->delayedcollisions = cl.time + PRVM_clientglobalfloat(particle_delaycollision);
}
else // quick themed particle
{
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];
- part = CL_NewParticle(org, theme->typeindex, theme->color1, theme->color2, theme->tex, theme->size, theme->sizeincrease, theme->alpha, theme->alphafade, theme->gravity, theme->bounce, org[0], org[1], org[2], dir[0], dir[1], dir[2], theme->airfriction, theme->liquidfriction, theme->originjitter, theme->velocityjitter, theme->qualityreduction, theme->lifetime, theme->stretch, theme->blendmode, theme->orientation, theme->staincolor1, theme->staincolor2, theme->staintex, theme->stainalpha, theme->stainsize, theme->angle, theme->spin, NULL);
+ part = CL_NewParticle(org,
+ theme->typeindex,
+ theme->color1,
+ theme->color2,
+ theme->tex,
+ theme->size,
+ theme->sizeincrease,
+ theme->alpha,
+ theme->alphafade,
+ theme->gravity,
+ theme->bounce,
+ org[0],
+ org[1],
+ org[2],
+ dir[0],
+ dir[1],
+ dir[2],
+ theme->airfriction,
+ theme->liquidfriction,
+ theme->originjitter,
+ theme->velocityjitter,
+ theme->qualityreduction,
+ theme->lifetime,
+ theme->stretch,
+ theme->blendmode,
+ theme->orientation,
+ theme->staincolor1,
+ theme->staincolor2,
+ theme->staintex,
+ theme->stainalpha,
+ theme->stainsize,
+ theme->angle,
+ theme->spin,
+ NULL);
if (!part)
{
- PRVM_G_FLOAT(OFS_RETURN) = 0;
+ PRVM_G_FLOAT(OFS_RETURN) = 0;
return;
}
if (theme->delayspawn)
//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
// returns 0 if failed, 1 if success
static void VM_CL_SpawnParticleDelayed (prvm_prog_t *prog)
{
- float *org, *dir;
+ vec3_t org, dir;
vmparticletheme_t *theme;
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;
}
- org = PRVM_G_VECTOR(OFS_PARM0);
- dir = PRVM_G_VECTOR(OFS_PARM1);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM1), dir);
if (prog->argc < 5) // global-set particle
- part = CL_NewParticle(org, (unsigned short)*vmpartspawner.particle_type, ((int)vmpartspawner.particle_color1[0] << 16) + ((int)vmpartspawner.particle_color1[1] << 8) + ((int)vmpartspawner.particle_color1[2]), ((int)vmpartspawner.particle_color2[0] << 16) + ((int)vmpartspawner.particle_color2[1] << 8) + ((int)vmpartspawner.particle_color2[2]), (int)*vmpartspawner.particle_tex, *vmpartspawner.particle_size, *vmpartspawner.particle_sizeincrease, *vmpartspawner.particle_alpha*256, *vmpartspawner.particle_alphafade*256, *vmpartspawner.particle_gravity, *vmpartspawner.particle_bounce, org[0], org[1], org[2], dir[0], dir[1], dir[2], *vmpartspawner.particle_airfriction, *vmpartspawner.particle_liquidfriction, *vmpartspawner.particle_originjitter, *vmpartspawner.particle_velocityjitter, (*vmpartspawner.particle_qualityreduction) ? true : false, *vmpartspawner.particle_time, *vmpartspawner.particle_stretch, (pblend_t)(int)*vmpartspawner.particle_blendmode, (porientation_t)(int)*vmpartspawner.particle_orientation, ((int)vmpartspawner.particle_staincolor1[0] << 16) + ((int)vmpartspawner.particle_staincolor1[1] << 8) + ((int)vmpartspawner.particle_staincolor1[2]), ((int)vmpartspawner.particle_staincolor2[0] << 16) + ((int)vmpartspawner.particle_staincolor2[1] << 8) + ((int)vmpartspawner.particle_staincolor2[2]), (int)*vmpartspawner.particle_staintex, *vmpartspawner.particle_stainalpha*256, *vmpartspawner.particle_stainsize, *vmpartspawner.particle_angle, *vmpartspawner.particle_spin, NULL);
+ part = CL_NewParticle(org,
+ (unsigned short)PRVM_clientglobalfloat(particle_type),
+ ((int)PRVM_clientglobalvector(particle_color1)[0] << 16) + ((int)PRVM_clientglobalvector(particle_color1)[1] << 8) + ((int)PRVM_clientglobalvector(particle_color1)[2]),
+ ((int)PRVM_clientglobalvector(particle_color2)[0] << 16) + ((int)PRVM_clientglobalvector(particle_color2)[1] << 8) + ((int)PRVM_clientglobalvector(particle_color2)[2]),
+ (int)PRVM_clientglobalfloat(particle_tex),
+ PRVM_clientglobalfloat(particle_size),
+ PRVM_clientglobalfloat(particle_sizeincrease),
+ PRVM_clientglobalfloat(particle_alpha)*256,
+ PRVM_clientglobalfloat(particle_alphafade)*256,
+ PRVM_clientglobalfloat(particle_gravity),
+ PRVM_clientglobalfloat(particle_bounce),
+ org[0],
+ org[1],
+ org[2],
+ dir[0],
+ dir[1],
+ dir[2],
+ PRVM_clientglobalfloat(particle_airfriction),
+ PRVM_clientglobalfloat(particle_liquidfriction),
+ PRVM_clientglobalfloat(particle_originjitter),
+ PRVM_clientglobalfloat(particle_velocityjitter),
+ (PRVM_clientglobalfloat(particle_qualityreduction)) ? true : false,
+ PRVM_clientglobalfloat(particle_time),
+ PRVM_clientglobalfloat(particle_stretch),
+ (pblend_t)(int)PRVM_clientglobalfloat(particle_blendmode),
+ (porientation_t)(int)PRVM_clientglobalfloat(particle_orientation),
+ ((int)PRVM_clientglobalvector(particle_staincolor1)[0] << 16) + ((int)PRVM_clientglobalvector(particle_staincolor1)[1] << 8) + ((int)PRVM_clientglobalvector(particle_staincolor1)[2]),
+ ((int)PRVM_clientglobalvector(particle_staincolor2)[0] << 16) + ((int)PRVM_clientglobalvector(particle_staincolor2)[1] << 8) + ((int)PRVM_clientglobalvector(particle_staincolor2)[2]),
+ (int)PRVM_clientglobalfloat(particle_staintex),
+ PRVM_clientglobalfloat(particle_stainalpha)*256,
+ PRVM_clientglobalfloat(particle_stainsize),
+ PRVM_clientglobalfloat(particle_angle),
+ PRVM_clientglobalfloat(particle_spin),
+ NULL);
else // themed particle
{
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];
- part = CL_NewParticle(org, theme->typeindex, theme->color1, theme->color2, theme->tex, theme->size, theme->sizeincrease, theme->alpha, theme->alphafade, theme->gravity, theme->bounce, org[0], org[1], org[2], dir[0], dir[1], dir[2], theme->airfriction, theme->liquidfriction, theme->originjitter, theme->velocityjitter, theme->qualityreduction, theme->lifetime, theme->stretch, theme->blendmode, theme->orientation, theme->staincolor1, theme->staincolor2, theme->staintex, theme->stainalpha, theme->stainsize, theme->angle, theme->spin, NULL);
+ part = CL_NewParticle(org,
+ theme->typeindex,
+ theme->color1,
+ theme->color2,
+ theme->tex,
+ theme->size,
+ theme->sizeincrease,
+ theme->alpha,
+ theme->alphafade,
+ theme->gravity,
+ theme->bounce,
+ org[0],
+ org[1],
+ org[2],
+ dir[0],
+ dir[1],
+ dir[2],
+ theme->airfriction,
+ theme->liquidfriction,
+ theme->originjitter,
+ theme->velocityjitter,
+ theme->qualityreduction,
+ theme->lifetime,
+ theme->stretch,
+ theme->blendmode,
+ theme->orientation,
+ theme->staincolor1,
+ theme->staincolor2,
+ theme->staintex,
+ theme->stainalpha,
+ theme->stainsize,
+ theme->angle,
+ 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);
static void VM_CL_GetEntity (prvm_prog_t *prog)
{
int entnum, fieldnum;
- float org[3], v1[3], v2[3];
- VM_SAFEPARMCOUNT(2, VM_CL_GetEntityVec);
+ vec3_t forward, left, up, org;
+ VM_SAFEPARMCOUNT(2, VM_CL_GetEntity);
entnum = PRVM_G_FLOAT(OFS_PARM0);
if (entnum < 0 || entnum >= cl.num_entities)
PRVM_G_FLOAT(OFS_RETURN) = cl.entities_active[entnum];
break;
case 1: // origin
- Matrix4x4_OriginFromMatrix(&cl.entities[entnum].render.matrix, PRVM_G_VECTOR(OFS_RETURN));
- break;
+ Matrix4x4_OriginFromMatrix(&cl.entities[entnum].render.matrix, org);
+ VectorCopy(org, PRVM_G_VECTOR(OFS_RETURN));
+ break;
case 2: // forward
- Matrix4x4_ToVectors(&cl.entities[entnum].render.matrix, PRVM_G_VECTOR(OFS_RETURN), v1, v2, org);
+ Matrix4x4_ToVectors(&cl.entities[entnum].render.matrix, forward, left, up, org);
+ VectorCopy(forward, PRVM_G_VECTOR(OFS_RETURN));
break;
case 3: // right
- Matrix4x4_ToVectors(&cl.entities[entnum].render.matrix, v1, PRVM_G_VECTOR(OFS_RETURN), v2, org);
+ Matrix4x4_ToVectors(&cl.entities[entnum].render.matrix, forward, left, up, org);
+ VectorNegate(left, PRVM_G_VECTOR(OFS_RETURN));
break;
case 4: // up
- Matrix4x4_ToVectors(&cl.entities[entnum].render.matrix, v1, v2, PRVM_G_VECTOR(OFS_RETURN), org);
+ Matrix4x4_ToVectors(&cl.entities[entnum].render.matrix, forward, left, up, org);
+ VectorCopy(up, PRVM_G_VECTOR(OFS_RETURN));
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, PRVM_clientglobalvector(v_forward), PRVM_clientglobalvector(v_right), PRVM_clientglobalvector(v_up), PRVM_G_VECTOR(OFS_RETURN));
- break;
+ 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;
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;
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.modellight_ambient, 0.5, cl.entities[entnum].render.modellight_diffuse, PRVM_G_VECTOR(OFS_RETURN));
- break;
+ VectorMA(cl.entities[entnum].render.render_modellight_ambient, 0.5, cl.entities[entnum].render.render_modellight_diffuse, PRVM_G_VECTOR(OFS_RETURN));
+ break;
default:
PRVM_G_FLOAT(OFS_RETURN) = 0;
break;
// --blub
static void VM_CL_R_RenderScene (prvm_prog_t *prog)
{
+ qbool ismain = r_refdef.view.ismain;
double t = Sys_DirtyTime();
- vmpolygons_t *polys = &prog->vmpolygons;
VM_SAFEPARMCOUNT(0, VM_CL_R_RenderScene);
// update the views
- if(r_refdef.view.ismain)
+ if(ismain)
{
// set the main view
csqc_main_r_refdef_view = r_refdef.view;
-
- // clear the flags so no other view becomes "main" unless CSQC sets VF_MAINVIEW
- r_refdef.view.ismain = false;
- csqc_original_r_refdef_view.ismain = false;
}
+ // 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_UpdateEntityShading();
// now draw stuff!
- R_RenderView();
-
- polys->num_vertices = polys->num_triangles = 0;
+ R_RenderView(0, NULL, NULL, r_refdef.view.x, r_refdef.view.y, r_refdef.view.width, r_refdef.view.height);
// 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;
-}
-
-static void VM_ResizePolygons(vmpolygons_t *polys)
-{
- float *oldvertex3f = polys->data_vertex3f;
- float *oldcolor4f = polys->data_color4f;
- float *oldtexcoord2f = polys->data_texcoord2f;
- vmpolygons_triangle_t *oldtriangles = polys->data_triangles;
- unsigned short *oldsortedelement3s = polys->data_sortedelement3s;
- polys->max_vertices = min(polys->max_triangles*3, 65536);
- polys->data_vertex3f = (float *)Mem_Alloc(polys->pool, polys->max_vertices*sizeof(float[3]));
- polys->data_color4f = (float *)Mem_Alloc(polys->pool, polys->max_vertices*sizeof(float[4]));
- polys->data_texcoord2f = (float *)Mem_Alloc(polys->pool, polys->max_vertices*sizeof(float[2]));
- polys->data_triangles = (vmpolygons_triangle_t *)Mem_Alloc(polys->pool, polys->max_triangles*sizeof(vmpolygons_triangle_t));
- polys->data_sortedelement3s = (unsigned short *)Mem_Alloc(polys->pool, polys->max_triangles*sizeof(unsigned short[3]));
- if (polys->num_vertices)
- {
- memcpy(polys->data_vertex3f, oldvertex3f, polys->num_vertices*sizeof(float[3]));
- memcpy(polys->data_color4f, oldcolor4f, polys->num_vertices*sizeof(float[4]));
- memcpy(polys->data_texcoord2f, oldtexcoord2f, polys->num_vertices*sizeof(float[2]));
- }
- if (polys->num_triangles)
- {
- memcpy(polys->data_triangles, oldtriangles, polys->num_triangles*sizeof(vmpolygons_triangle_t));
- memcpy(polys->data_sortedelement3s, oldsortedelement3s, polys->num_triangles*sizeof(unsigned short[3]));
- }
- if (oldvertex3f)
- Mem_Free(oldvertex3f);
- if (oldcolor4f)
- Mem_Free(oldcolor4f);
- if (oldtexcoord2f)
- Mem_Free(oldtexcoord2f);
- if (oldtriangles)
- Mem_Free(oldtriangles);
- if (oldsortedelement3s)
- Mem_Free(oldsortedelement3s);
-}
-
-static void VM_InitPolygons (vmpolygons_t* polys)
-{
- memset(polys, 0, sizeof(*polys));
- polys->pool = Mem_AllocPool("VMPOLY", 0, NULL);
- polys->max_triangles = 1024;
- VM_ResizePolygons(polys);
- 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_t *)ent;
-// R_Mesh_ResetTextureState();
- R_EntityMatrix(&identitymatrix);
- GL_CullFace(GL_NONE);
- GL_DepthTest(true); // polys in 3D space shall always have depth test
- GL_DepthRange(0, 1);
- R_Mesh_PrepareVertices_Generic_Arrays(polys->num_vertices, polys->data_vertex3f, polys->data_color4f, polys->data_texcoord2f);
-
- for (surfacelistindex = 0;surfacelistindex < numsurfaces;)
- {
- int numtriangles = 0;
- rtexture_t *tex = polys->data_triangles[surfacelist[surfacelistindex]].texture;
- int drawflag = polys->data_triangles[surfacelist[surfacelistindex]].drawflag;
- DrawQ_ProcessDrawFlag(drawflag, polys->data_triangles[surfacelist[surfacelistindex]].hasalpha);
- R_SetupShader_Generic(tex, NULL, GL_MODULATE, 1, false, false, false);
- numtriangles = 0;
- for (;surfacelistindex < numsurfaces;surfacelistindex++)
- {
- if (polys->data_triangles[surfacelist[surfacelistindex]].texture != tex || polys->data_triangles[surfacelist[surfacelistindex]].drawflag != drawflag)
- break;
- VectorCopy(polys->data_triangles[surfacelist[surfacelistindex]].elements, polys->data_sortedelement3s + 3*numtriangles);
- numtriangles++;
- }
- R_Mesh_Draw(0, polys->num_vertices, 0, numtriangles, NULL, NULL, 0, polys->data_sortedelement3s, NULL, 0);
- }
-}
-
-static void VMPolygons_Store(vmpolygons_t *polys)
-{
- qboolean hasalpha;
- int i;
-
- // detect if we have alpha
- hasalpha = polys->begin_texture_hasalpha;
- for(i = 0; !hasalpha && (i < polys->begin_vertices); ++i)
- if(polys->begin_color[i][3] < 1)
- hasalpha = true;
-
- if (polys->begin_draw2d)
- {
- // draw the polygon as 2D immediately
- drawqueuemesh_t mesh;
- mesh.texture = polys->begin_texture;
- mesh.num_vertices = polys->begin_vertices;
- mesh.num_triangles = polys->begin_vertices-2;
- mesh.data_element3i = polygonelement3i;
- mesh.data_element3s = polygonelement3s;
- mesh.data_vertex3f = polys->begin_vertex[0];
- mesh.data_color4f = polys->begin_color[0];
- mesh.data_texcoord2f = polys->begin_texcoord[0];
- DrawQ_Mesh(&mesh, polys->begin_drawflag, hasalpha);
- }
- else
- {
- // queue the polygon as 3D for sorted transparent rendering later
- int i;
- if (polys->max_triangles < polys->num_triangles + polys->begin_vertices-2)
- {
- while (polys->max_triangles < polys->num_triangles + polys->begin_vertices-2)
- polys->max_triangles *= 2;
- VM_ResizePolygons(polys);
- }
- if (polys->num_vertices + polys->begin_vertices <= polys->max_vertices)
- {
- // needle in a haystack!
- // polys->num_vertices was used for copying where we actually want to copy begin_vertices
- // that also caused it to not render the first polygon that is added
- // --blub
- memcpy(polys->data_vertex3f + polys->num_vertices * 3, polys->begin_vertex[0], polys->begin_vertices * sizeof(float[3]));
- memcpy(polys->data_color4f + polys->num_vertices * 4, polys->begin_color[0], polys->begin_vertices * sizeof(float[4]));
- memcpy(polys->data_texcoord2f + polys->num_vertices * 2, polys->begin_texcoord[0], polys->begin_vertices * sizeof(float[2]));
- for (i = 0;i < polys->begin_vertices-2;i++)
- {
- polys->data_triangles[polys->num_triangles].texture = polys->begin_texture;
- polys->data_triangles[polys->num_triangles].drawflag = polys->begin_drawflag;
- polys->data_triangles[polys->num_triangles].elements[0] = polys->num_vertices;
- polys->data_triangles[polys->num_triangles].elements[1] = polys->num_vertices + i+1;
- polys->data_triangles[polys->num_triangles].elements[2] = polys->num_vertices + i+2;
- polys->data_triangles[polys->num_triangles].hasalpha = hasalpha;
- polys->num_triangles++;
- }
- polys->num_vertices += polys->begin_vertices;
- }
- }
- polys->begin_active = false;
-}
-
-// TODO: move this into the client code and clean-up everything else, too! [1/6/2008 Black]
-// LordHavoc: agreed, this is a mess
-void VM_CL_AddPolygonsToMeshQueue (prvm_prog_t *prog)
-{
- int i;
- vmpolygons_t *polys = &prog->vmpolygons;
- vec3_t center;
-
- // only add polygons of the currently active prog to the queue - if there is none, we're done
- if( !prog )
- return;
- if (!polys->num_triangles)
- return;
+ // polygonbegin without draw2d arg has to guess
+ prog->polygonbegin_guess2d = false;
- for (i = 0;i < polys->num_triangles;i++)
+ // update the views
+ if (ismain)
{
- VectorMAMAM(1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].elements[0], 1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].elements[1], 1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].elements[2], center);
- R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, center, VM_DrawPolygonCallback, (entity_render_t *)polys, i, NULL);
+ // clear the flags so no other view becomes "main" unless CSQC sets VF_MAINVIEW
+ r_refdef.view.ismain = false;
+ csqc_original_r_refdef_view.ismain = false;
}
-
- /*polys->num_triangles = 0; // now done after rendering the scene,
- polys->num_vertices = 0; // otherwise it's not rendered at all and prints an error message --blub */
}
//void(string texturename, float flag[, float is2d]) R_BeginPolygon
static void VM_CL_R_PolygonBegin (prvm_prog_t *prog)
{
- const char *picname;
- skinframe_t *sf;
- vmpolygons_t *polys = &prog->vmpolygons;
- int tf;
-
- // TODO instead of using skinframes here (which provides the benefit of
- // better management of flags, and is more suited for 3D rendering), what
- // about supporting Q3 shaders?
+ const char *texname;
+ int drawflags;
+ qbool draw2d;
+ model_t *mod;
VM_SAFEPARMCOUNTRANGE(2, 3, VM_CL_R_PolygonBegin);
- if (!polys->initialized)
- VM_InitPolygons(polys);
- if (polys->begin_active)
- {
- VM_Warning(prog, "VM_CL_R_PolygonBegin: called twice without VM_CL_R_PolygonBegin after first\n");
- return;
- }
- picname = PRVM_G_STRING(OFS_PARM0);
-
- sf = NULL;
- if(*picname)
+ texname = PRVM_G_STRING(OFS_PARM0);
+ drawflags = (int)PRVM_G_FLOAT(OFS_PARM1);
+ if (prog->argc >= 3)
+ draw2d = PRVM_G_FLOAT(OFS_PARM2) != 0;
+ else
{
- tf = TEXF_ALPHA;
- if((int)PRVM_G_FLOAT(OFS_PARM1) & DRAWFLAG_MIPMAP)
- tf |= TEXF_MIPMAP;
-
- do
- {
- sf = R_SkinFrame_FindNextByName(sf, picname);
- }
- while(sf && sf->textureflags != tf);
-
- if(!sf || !sf->base)
- sf = R_SkinFrame_LoadExternal(picname, tf, true);
-
- if(sf)
- R_SkinFrame_MarkUsed(sf);
+ // weird hacky way to figure out if this is a 2D HUD polygon or a scene
+ // polygon, for compatibility with mods aimed at old darkplaces versions
+ // - polygonbegin_guess2d is 0 if the most recent major call was
+ // clearscene, 1 if the most recent major call was drawpic (and similar)
+ // or renderscene
+ draw2d = prog->polygonbegin_guess2d;
}
- polys->begin_texture = (sf && sf->base) ? sf->base : r_texture_white;
- polys->begin_texture_hasalpha = (sf && sf->base) ? sf->hasalpha : false;
- polys->begin_drawflag = (int)PRVM_G_FLOAT(OFS_PARM1) & DRAWFLAG_MASK;
- polys->begin_vertices = 0;
- polys->begin_active = true;
- polys->begin_draw2d = (prog->argc >= 3 ? (int)PRVM_G_FLOAT(OFS_PARM2) : r_refdef.draw2dstage);
+ // we need to remember whether this is a 2D or 3D mesh we're adding to
+ mod = draw2d ? CL_Mesh_UI() : CL_Mesh_Scene();
+ prog->polygonbegin_model = mod;
+ 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
static void VM_CL_R_PolygonVertex (prvm_prog_t *prog)
{
- vmpolygons_t *polys = &prog->vmpolygons;
+ const prvm_vec_t *v = PRVM_G_VECTOR(OFS_PARM0);
+ 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;
+ model_t *mod = prog->polygonbegin_model;
VM_SAFEPARMCOUNT(4, VM_CL_R_PolygonVertex);
- if (!polys->begin_active)
+ if (!mod)
{
VM_Warning(prog, "VM_CL_R_PolygonVertex: VM_CL_R_PolygonBegin wasn't called\n");
return;
}
- if (polys->begin_vertices >= VMPOLYGONS_MAXPOINTS)
+ if (prog->polygonbegin_maxvertices <= prog->polygonbegin_numvertices)
{
- VM_Warning(prog, "VM_CL_R_PolygonVertex: may have %i vertices max\n", VMPOLYGONS_MAXPOINTS);
- return;
+ 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;
- polys->begin_vertex[polys->begin_vertices][0] = PRVM_G_VECTOR(OFS_PARM0)[0];
- polys->begin_vertex[polys->begin_vertices][1] = PRVM_G_VECTOR(OFS_PARM0)[1];
- polys->begin_vertex[polys->begin_vertices][2] = PRVM_G_VECTOR(OFS_PARM0)[2];
- polys->begin_texcoord[polys->begin_vertices][0] = PRVM_G_VECTOR(OFS_PARM1)[0];
- polys->begin_texcoord[polys->begin_vertices][1] = PRVM_G_VECTOR(OFS_PARM1)[1];
- polys->begin_color[polys->begin_vertices][0] = PRVM_G_VECTOR(OFS_PARM2)[0];
- polys->begin_color[polys->begin_vertices][1] = PRVM_G_VECTOR(OFS_PARM2)[1];
- polys->begin_color[polys->begin_vertices][2] = PRVM_G_VECTOR(OFS_PARM2)[2];
- polys->begin_color[polys->begin_vertices][3] = PRVM_G_FLOAT(OFS_PARM3);
- polys->begin_vertices++;
+ 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)
{
- vmpolygons_t *polys = &prog->vmpolygons;
+ 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 (!polys->begin_active)
+ if (!mod)
{
VM_Warning(prog, "VM_CL_R_PolygonEnd: VM_CL_R_PolygonBegin wasn't called\n");
return;
}
- polys->begin_active = false;
- if (polys->begin_vertices >= 3)
- VMPolygons_Store(polys);
- else
- VM_Warning(prog, "VM_CL_R_PolygonEnd: %i vertices isn't a good choice\n", polys->begin_vertices);
-}
-
-static vmpolygons_t debugPolys;
-
-void Debug_PolygonBegin(const char *picname, int drawflag)
-{
- if(!debugPolys.initialized)
- VM_InitPolygons(&debugPolys);
- if(debugPolys.begin_active)
- {
- Con_Printf("Debug_PolygonBegin: called twice without Debug_PolygonEnd after first\n");
- return;
- }
- debugPolys.begin_texture = picname[0] ? Draw_CachePic_Flags (picname, CACHEPICFLAG_NOTPERSISTENT)->tex : r_texture_white;
- debugPolys.begin_drawflag = drawflag;
- debugPolys.begin_vertices = 0;
- debugPolys.begin_active = true;
-}
-void Debug_PolygonVertex(float x, float y, float z, float s, float t, float r, float g, float b, float a)
-{
- if(!debugPolys.begin_active)
+ // 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++)
{
- Con_Printf("Debug_PolygonVertex: Debug_PolygonBegin wasn't called\n");
- return;
+ 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;
}
- if(debugPolys.begin_vertices > VMPOLYGONS_MAXPOINTS)
+ // 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++)
{
- Con_Printf("Debug_PolygonVertex: may have %i vertices max\n", VMPOLYGONS_MAXPOINTS);
- return;
+ 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);
- debugPolys.begin_vertex[debugPolys.begin_vertices][0] = x;
- debugPolys.begin_vertex[debugPolys.begin_vertices][1] = y;
- debugPolys.begin_vertex[debugPolys.begin_vertices][2] = z;
- debugPolys.begin_texcoord[debugPolys.begin_vertices][0] = s;
- debugPolys.begin_texcoord[debugPolys.begin_vertices][1] = t;
- debugPolys.begin_color[debugPolys.begin_vertices][0] = r;
- debugPolys.begin_color[debugPolys.begin_vertices][1] = g;
- debugPolys.begin_color[debugPolys.begin_vertices][2] = b;
- debugPolys.begin_color[debugPolys.begin_vertices][3] = a;
- debugPolys.begin_vertices++;
-}
-
-void Debug_PolygonEnd(void)
-{
- if (!debugPolys.begin_active)
- {
- Con_Printf("Debug_PolygonEnd: Debug_PolygonBegin wasn't called\n");
- return;
- }
- debugPolys.begin_active = false;
- if (debugPolys.begin_vertices >= 3)
- VMPolygons_Store(&debugPolys);
- else
- Con_Printf("Debug_PolygonEnd: %i vertices isn't a good choice\n", debugPolys.begin_vertices);
+ // 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;
start[0] = stop[0] = (mins[0] + maxs[0])*0.5;
start[1] = stop[1] = (mins[1] + maxs[1])*0.5;
stop[2] = start[2] - 2*sv_stepheight.value;
- trace = CL_TraceLine(start, stop, MOVE_NOMONSTERS, ent, CL_GenericHitSuperContentsMask(ent), true, false, NULL, true, false);
+ trace = CL_TraceLine(start, stop, MOVE_NOMONSTERS, ent, CL_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value, true, false, NULL, true, false);
if (trace.fraction == 1.0)
return false;
start[0] = stop[0] = x ? maxs[0] : mins[0];
start[1] = stop[1] = y ? maxs[1] : mins[1];
- trace = CL_TraceLine(start, stop, MOVE_NOMONSTERS, ent, CL_GenericHitSuperContentsMask(ent), true, false, NULL, true, false);
+ trace = CL_TraceLine(start, stop, MOVE_NOMONSTERS, ent, CL_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value, true, false, NULL, true, false);
if (trace.fraction != 1.0 && trace.endpos[2] > bottom)
bottom = trace.endpos[2];
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 oldorg, neworg, end, traceendpos;
+ vec3_t mins, maxs, start;
trace_t trace;
int i, svent;
prvm_edict_t *enemy;
// try the move
+ VectorCopy(PRVM_clientedictvector(ent, mins), mins);
+ VectorCopy(PRVM_clientedictvector(ent, maxs), maxs);
VectorCopy (PRVM_clientedictvector(ent, origin), oldorg);
VectorAdd (PRVM_clientedictvector(ent, origin), move, neworg);
if (dz < 30)
neworg[2] += 8;
}
- trace = CL_TraceBox(PRVM_clientedictvector(ent, origin), PRVM_clientedictvector(ent, mins), PRVM_clientedictvector(ent, maxs), neworg, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, &svent, true);
+ VectorCopy(PRVM_clientedictvector(ent, origin), start);
+ trace = CL_TraceBox(start, mins, maxs, neworg, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value, true, true, &svent, true);
if (settrace)
CL_VM_SetTraceGlobals(prog, &trace, svent);
VectorCopy (neworg, end);
end[2] -= sv_stepheight.value*2;
- trace = CL_TraceBox(neworg, PRVM_clientedictvector(ent, mins), PRVM_clientedictvector(ent, maxs), end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, &svent, true);
+ trace = CL_TraceBox(neworg, mins, maxs, end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value, true, true, &svent, true);
if (settrace)
CL_VM_SetTraceGlobals(prog, &trace, svent);
if (trace.startsolid)
{
neworg[2] -= sv_stepheight.value;
- trace = CL_TraceBox(neworg, PRVM_clientedictvector(ent, mins), PRVM_clientedictvector(ent, maxs), end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, &svent, true);
+ trace = CL_TraceBox(neworg, mins, maxs, end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value, true, true, &svent, true);
if (settrace)
CL_VM_SetTraceGlobals(prog, &trace, svent);
if (trace.startsolid)
vec3_t move;
mfunction_t *oldf;
int oldself;
- qboolean settrace;
+ qbool settrace;
VM_SAFEPARMCOUNTRANGE(2, 3, VM_CL_walkmove);
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;
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;
VectorAdd(PRVM_serveredictvector(viewee, origin), PRVM_serveredictvector(viewee, maxs), ma);
#if 1
- if(!sv.worldmodel->brush.GetPVS || !sv.worldmodel->brush.BoxTouchingPVS)
+ if(!cl.worldmodel || !cl.worldmodel->brush.GetPVS || !cl.worldmodel->brush.BoxTouchingPVS)
{
// no PVS support on this worldmodel... darn
PRVM_G_FLOAT(OFS_RETURN) = 3;
return;
}
- pvs = sv.worldmodel->brush.GetPVS(sv.worldmodel, viewpos);
+ pvs = cl.worldmodel->brush.GetPVS(cl.worldmodel, viewpos);
if(!pvs)
{
// viewpos isn't in any PVS... darn
PRVM_G_FLOAT(OFS_RETURN) = 2;
return;
}
- PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, pvs, mi, ma);
+ PRVM_G_FLOAT(OFS_RETURN) = cl.worldmodel->brush.BoxTouchingPVS(cl.worldmodel, pvs, mi, ma);
#else
// using fat PVS like FTEQW does (slow)
- if(!sv.worldmodel->brush.FatPVS || !sv.worldmodel->brush.BoxTouchingPVS)
+ if(!cl.worldmodel || !cl.worldmodel->brush.FatPVS || !cl.worldmodel->brush.BoxTouchingPVS)
{
// no PVS support on this worldmodel... darn
PRVM_G_FLOAT(OFS_RETURN) = 3;
return;
}
- fatpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, viewpos, 8, fatpvs, sizeof(fatpvs), false);
+ fatpvsbytes = cl.worldmodel->brush.FatPVS(cl.worldmodel, viewpos, 8, fatpvs, sizeof(fatpvs), false);
if(!fatpvsbytes)
{
// viewpos isn't in any PVS... darn
PRVM_G_FLOAT(OFS_RETURN) = 2;
return;
}
- PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, fatpvs, mi, ma);
+ PRVM_G_FLOAT(OFS_RETURN) = cl.worldmodel->brush.BoxTouchingPVS(cl.worldmodel, fatpvs, mi, ma);
#endif
}
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;
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);
- float blendfrac;
+ model_t *model = CL_GetModelByIndex(modelindex);
int numblends;
int bonenum;
int blendindex;
framegroupblend_t framegroupblend[MAX_FRAMEGROUPBLENDS];
frameblend_t frameblend[MAX_FRAMEBLENDS];
- matrix4x4_t blendedmatrix;
+ matrix4x4_t bonematrix;
matrix4x4_t matrix;
PRVM_G_FLOAT(OFS_RETURN) = 0;
if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
lastbone = min(lastbone, model->num_bones - 1);
lastbone = min(lastbone, skeleton->model->num_bones - 1);
VM_GenerateFrameGroupBlend(prog, framegroupblend, ed);
- VM_FrameBlendFromFrameGroupBlend(frameblend, framegroupblend, model);
- blendfrac = 1.0f - retainfrac;
+ VM_FrameBlendFromFrameGroupBlend(frameblend, framegroupblend, model, cl.time);
for (numblends = 0;numblends < MAX_FRAMEBLENDS && frameblend[numblends].lerp;numblends++)
- frameblend[numblends].lerp *= blendfrac;
+ ;
for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
{
- memset(&blendedmatrix, 0, sizeof(blendedmatrix));
- Matrix4x4_Accumulate(&blendedmatrix, &skeleton->relativetransforms[bonenum], retainfrac);
+ memset(&bonematrix, 0, sizeof(bonematrix));
for (blendindex = 0;blendindex < numblends;blendindex++)
{
- Matrix4x4_FromBonePose6s(&matrix, model->num_posescale, model->data_poses6s + 6 * (frameblend[blendindex].subframe * model->num_bones + bonenum));
- Matrix4x4_Accumulate(&blendedmatrix, &matrix, frameblend[blendindex].lerp);
+ Matrix4x4_FromBonePose7s(&matrix, model->num_posescale, model->data_poses7s + 7 * (frameblend[blendindex].subframe * model->num_bones + bonenum));
+ Matrix4x4_Accumulate(&bonematrix, &matrix, frameblend[blendindex].lerp);
}
- skeleton->relativetransforms[bonenum] = blendedmatrix;
+ Matrix4x4_Normalize3(&bonematrix, &bonematrix);
+ Matrix4x4_Interpolate(&skeleton->relativetransforms[bonenum], &bonematrix, &skeleton->relativetransforms[bonenum], retainfrac);
}
PRVM_G_FLOAT(OFS_RETURN) = skeletonindex + 1;
}
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;
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)
*/
matrix4x4_t m;
vec3_t v = {0, 0, 0};
- vec3_t x, y, z;
+ vec3_t a, x, y, z;
VM_SAFEPARMCOUNT(1, VM_CL_RotateMoves);
- AngleVectorsFLU(PRVM_G_VECTOR(OFS_PARM0), x, y, z);
+ VectorCopy(PRVM_G_VECTOR(OFS_PARM0), a);
+ AngleVectorsFLU(a, x, y, z);
Matrix4x4_FromVectors(&m, x, y, z, v);
CL_RotateMoves(&m);
}
{
matrix4x4_t entrendermatrix;
vec3_t clviewangles;
- qboolean teleported;
- qboolean clonground;
- qboolean clcmdjump;
- qboolean cldead;
- qboolean clintermission;
+ vec3_t clvelocity;
+ qbool teleported;
+ qbool clonground;
+ qbool clcmdjump;
+ qbool cldead;
float clstatsviewheight;
prvm_edict_t *ent;
int flags;
flags = PRVM_G_FLOAT(OFS_PARM1);
// use the CL_GetTagMatrix function on self to ensure consistent behavior (duplicate code would be bad)
- CL_GetTagMatrix(prog, &entrendermatrix, ent, 0);
+ CL_GetTagMatrix(prog, &entrendermatrix, ent, 0, NULL);
VectorCopy(cl.csqc_viewangles, clviewangles);
teleported = (flags & REFDEFFLAG_TELEPORTED) != 0;
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);
+ 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)
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)
VM_fgets, // #112 string(float fhandle) fgets (FRIK_FILE)
VM_fputs, // #113 void(float fhandle, string s) fputs (FRIK_FILE)
VM_strlen, // #114 float(string s) strlen (FRIK_FILE)
-VM_strcat, // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
+VM_strcat, // #115 string(string s, string...) strcat (FRIK_FILE)
VM_substring, // #116 string(string s, float start, float length) substring (FRIK_FILE)
VM_stov, // #117 vector(string) stov (FRIK_FILE)
VM_strzone, // #118 string(string s) strzone (FRIK_FILE)
NULL, // #174
NULL, // #175
NULL, // #176
-NULL, // #177
+VM_localsound, // #177
NULL, // #178
NULL, // #179
NULL, // #180
NULL, // #242
NULL, // #243
NULL, // #244
-NULL, // #245
+VM_modulo, // #245
NULL, // #246
NULL, // #247
NULL, // #248
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)
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)
VM_log, // #532
VM_getsoundtime, // #533 float(entity e, float channel) getsoundtime = #533; (DP_SND_GETSOUNDTIME)
VM_soundlength, // #534 float(string sample) soundlength = #534; (DP_SND_GETSOUNDTIME)
-NULL, // #535
-NULL, // #536
-NULL, // #537
-NULL, // #538
+VM_buf_loadfile, // #535 float(string filename, float bufhandle) buf_loadfile (DP_QC_STRINGBUFFERS_EXT_WIP)
+VM_buf_writefile, // #536 float(float filehandle, float bufhandle, float startpos, float numstrings) buf_writefile (DP_QC_STRINGBUFFERS_EXT_WIP)
+VM_bufstr_find, // #537 float(float bufhandle, string match, float matchrule, float startpos) bufstr_find (DP_QC_STRINGBUFFERS_EXT_WIP)
+VM_matchpattern, // #538 float(string s, string pattern, float matchrule) matchpattern (DP_QC_STRINGBUFFERS_EXT_WIP)
NULL, // #539
VM_physics_enable, // #540 void(entity e, float physics_enabled) physics_enable = #540; (DP_PHYSICS_ODE)
VM_physics_addforce, // #541 void(entity e, vector force, vector relative_ofs) physics_addforce = #541; (DP_PHYSICS_ODE)
NULL, // #563
NULL, // #564
NULL, // #565
-NULL, // #566
-NULL, // #567
+VM_CL_findbox, // #566 entity(vector mins, vector maxs) findbox = #566; (DP_QC_FINDBOX)
+VM_nudgeoutofsolid, // #567 float(entity ent) nudgeoutofsolid = #567; (DP_QC_NUDGEOUTOFSOLID)
NULL, // #568
NULL, // #569
NULL, // #570
VM_digest_hex, // #639
VM_CL_V_CalcRefdef, // #640 void(entity e) V_CalcRefdef (DP_CSQC_V_CALCREFDEF)
NULL, // #641
+VM_coverage, // #642
+NULL
};
const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t);
-void VM_Polygons_Reset(prvm_prog_t *prog)
-{
- vmpolygons_t *polys = &prog->vmpolygons;
-
- // TODO: replace vm_polygons stuff with a more general debugging polygon system, and make vm_polygons functions use that system
- if(polys->initialized)
- {
- Mem_FreePool(&polys->pool);
- polys->initialized = false;
- }
-}
-
void CLVM_init_cmd(prvm_prog_t *prog)
{
VM_Cmd_Init(prog);
- VM_Polygons_Reset(prog);
+ prog->polygonbegin_model = NULL;
+ prog->polygonbegin_guess2d = 0;
}
void CLVM_reset_cmd(prvm_prog_t *prog)
{
World_End(&cl.world);
VM_Cmd_Reset(prog);
- VM_Polygons_Reset(prog);
+ prog->polygonbegin_model = NULL;
+ prog->polygonbegin_guess2d = 0;
}