added r_meshpitch cvar that allows for fixing the unfixable mesh pitch bug from vanilla... needs a better name... do note that this will break pretty much any mod, so this is really only for TCs designed to use it. Its likely that I missed places.

nqsv: added support for spectators with nq clients. the angles are a bit rough, but hey. need to do something about frags so nq clients know who's a spectator. use 'cmd observe' to get an nq client to spectate on an fte server (then attack/jump behave the same as in qw clients).
nqsv: rewrote EF_MUZZLEFLASH handling, so svc_muzzleflash is now translated properly to EF_MUZZLEFLASH, and vice versa. No more missing muzzleflashes!
added screenshot_cubemap, so you can actually pre-generate cubemaps with fte (which can be used for reflections or whatever).
misc fixes (server crash, a couple of other less important ones).
external files based on a model's name will now obey r_replacemodels properly, instead of needing to use foo.mdl_0.skin for foo.md3.
identify <playernum> should now use the correct masked ip, instead of abrubtly failing (reported by kt)
vid_toggle console command should now obey vid_width and vid_height when switching to fullscreen, but only if vid_fullscreen is actually set, which should make it seem better behaved (reported by kt).
qcc: cleaned up sym->symboldata[sym->ofs] to be more consistent at all stages.
qcc: typedef float vec4[4]; now works to define a float array with 4 elements (however, it will be passed by-value rather than by-reference).
qcc: cleaned up optional vs __out ordering issues.
qccgui: shift+f3 searches backwards

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5064 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2017-02-27 09:34:35 +00:00
parent 217f3ce569
commit cf0e8fd923
63 changed files with 794 additions and 498 deletions

View file

@ -29,7 +29,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* *
*****************************************************************************/ *****************************************************************************/
#define Vector2Angles(v,a) vectoangles(v,a) void QDECL VectorAngles(float *forward, float *up, float *result, qboolean meshpitch);
#define Vector2Angles(v,a) VectorAngles(v,NULL,a,qfalse)
#ifndef MAX_PATH #ifndef MAX_PATH
#define MAX_PATH MAX_QPATH #define MAX_PATH MAX_QPATH
#endif #endif

View file

@ -652,7 +652,6 @@ float Q_crandom( int *seed );
#define random() ((rand () & 0x7fff) / ((float)0x7fff)) #define random() ((rand () & 0x7fff) / ((float)0x7fff))
#define crandom() (2.0 * (random() - 0.5)) #define crandom() (2.0 * (random() - 0.5))
void vectoangles( const vec3_t value1, vec3_t angles);
void AnglesToAxis( const vec3_t angles, vec3_t axis[3] ); void AnglesToAxis( const vec3_t angles, vec3_t axis[3] );
void AxisClear( vec3_t axis[3] ); void AxisClear( vec3_t axis[3] );

View file

@ -621,8 +621,7 @@ static float Cam_TryFlyby(vec3_t selforigin, vec3_t playerorigin, vec3_t vec, qb
pmove.player_maxs[0] = pmove.player_maxs[1] = 16; pmove.player_maxs[0] = pmove.player_maxs[1] = 16;
pmove.player_maxs[2] = 32; pmove.player_maxs[2] = 32;
VectorAngles(vec, NULL, v); VectorAngles(vec, NULL, v, true);
// v[0] = -v[0];
VectorCopy (v, pmove.angles); VectorCopy (v, pmove.angles);
VectorNormalize(vec); VectorNormalize(vec);
VectorMA(playerorigin, 800, vec, v); VectorMA(playerorigin, 800, vec, v);
@ -791,8 +790,7 @@ void Cam_SelfTrack(playerview_t *pv)
VectorCopy(pv->cam_desired_position, r_refdef.vieworg); VectorCopy(pv->cam_desired_position, r_refdef.vieworg);
VectorSubtract(pv->simorg, pv->cam_desired_position, vec); VectorSubtract(pv->simorg, pv->cam_desired_position, vec);
VectorAngles(vec, NULL, r_refdef.viewangles); VectorAngles(vec, NULL, r_refdef.viewangles, false);
r_refdef.viewangles[0] = -r_refdef.viewangles[0];
} }
} }

View file

@ -1945,9 +1945,9 @@ void CL_RotateAroundTag(entity_t *ent, int entnum, int parenttagent, int parentt
model = NULL; model = NULL;
if (model && model->type == mod_alias) if (model && model->type == mod_alias)
{ {
ang[0]*=-1; ang[0]*=r_meshpitch.value;
AngleVectors(ang, axis[0], axis[1], axis[2]); AngleVectors(ang, axis[0], axis[1], axis[2]);
ang[0]*=-1; ang[0]*=r_meshpitch.value;
} }
else else
AngleVectors(ang, axis[0], axis[1], axis[2]); AngleVectors(ang, axis[0], axis[1], axis[2]);
@ -2090,10 +2090,10 @@ entity_t *V_AddEntity(entity_t *in)
*ent = *in; *ent = *in;
ent->angles[0]*=-1; ent->angles[0]*=r_meshpitch.value;
AngleVectors(ent->angles, ent->axis[0], ent->axis[1], ent->axis[2]); AngleVectors(ent->angles, ent->axis[0], ent->axis[1], ent->axis[2]);
VectorInverse(ent->axis[1]); VectorInverse(ent->axis[1]);
ent->angles[0]*=-1; ent->angles[0]*=r_meshpitch.value;
return ent; return ent;
} }
@ -2120,10 +2120,10 @@ void VQ2_AddLerpEntity(entity_t *in) //a convienience function
ent->framestate.g[FS_REG].lerpfrac = back; ent->framestate.g[FS_REG].lerpfrac = back;
ent->angles[0]*=-1; ent->angles[0]*=r_meshpitch.value;
AngleVectors(ent->angles, ent->axis[0], ent->axis[1], ent->axis[2]); AngleVectors(ent->angles, ent->axis[0], ent->axis[1], ent->axis[2]);
VectorInverse(ent->axis[1]); VectorInverse(ent->axis[1]);
ent->angles[0]*=-1; ent->angles[0]*=r_meshpitch.value;
} }
*/ */
int V_AddLight (int entsource, vec3_t org, float quant, float r, float g, float b) int V_AddLight (int entsource, vec3_t org, float quant, float r, float g, float b)
@ -3094,7 +3094,7 @@ void CLQ1_AddPowerupShell(entity_t *ent, qboolean viewweap, unsigned int effects
); );
} }
shell->shaderRGBAf[0] *= (effects & EF_RED)?1:0; shell->shaderRGBAf[0] *= (effects & EF_RED)?1:0;
shell->shaderRGBAf[1] *= 0;//(effects & EF_GREEN)?1:0; shell->shaderRGBAf[1] *= (effects & EF_GREEN)?1:0;
shell->shaderRGBAf[2] *= (effects & EF_BLUE)?1:0; shell->shaderRGBAf[2] *= (effects & EF_BLUE)?1:0;
shell->shaderRGBAf[3] *= v_powerupshell.value; shell->shaderRGBAf[3] *= v_powerupshell.value;
/*let the shader do all the work*/ /*let the shader do all the work*/
@ -3129,12 +3129,11 @@ static void CL_UpdateNetFrameLerpState(qboolean force, int curframe, int curbase
curbaseframe = curframe; curbaseframe = curframe;
else if (curbasebone == 255) else if (curbasebone == 255)
curframe = curbaseframe; curframe = curbaseframe;
else le->basebone = curbasebone;
le->basebone = curbasebone;
} }
for (fst = 0; fst < FS_COUNT; fst++) for (fst = 0; fst < FS_COUNT; fst++)
{ {
frame = fst?curframe:curbaseframe; frame = (fst==FST_BASE)?curbaseframe:curframe;
if (force || frame != le->newframe[fst]) if (force || frame != le->newframe[fst])
{ {
le->framelerpdeltatime[fst] = bound(0, cl.servertime - le->newframestarttime[fst], 0.1); //clamp to 10 tics per second le->framelerpdeltatime[fst] = bound(0, cl.servertime - le->newframestarttime[fst], 0.1); //clamp to 10 tics per second
@ -3216,10 +3215,10 @@ void CL_LinkStaticEntities(void *pvs)
//figure out the correct axis for the model //figure out the correct axis for the model
if (clmodel && clmodel->type == mod_alias && (cls.protocol == CP_QUAKEWORLD || cls.protocol == CP_NETQUAKE)) if (clmodel && clmodel->type == mod_alias && (cls.protocol == CP_QUAKEWORLD || cls.protocol == CP_NETQUAKE))
{ { //q2 is fixed, but q1 pitches the wrong way
stat->state.angles[0]*=-1; stat->state.angles[0]*=r_meshpitch.value;
AngleVectors(stat->state.angles, stat->ent.axis[0], stat->ent.axis[1], stat->ent.axis[2]); AngleVectors(stat->state.angles, stat->ent.axis[0], stat->ent.axis[1], stat->ent.axis[2]);
stat->state.angles[0]*=-1; stat->state.angles[0]*=r_meshpitch.value;
} }
else else
AngleVectors(stat->state.angles, stat->ent.axis[0], stat->ent.axis[1], stat->ent.axis[2]); AngleVectors(stat->state.angles, stat->ent.axis[0], stat->ent.axis[1], stat->ent.axis[2]);
@ -3905,7 +3904,7 @@ void CL_LinkPacketEntities (void)
{ {
VectorCopy(le->angles, angles); VectorCopy(le->angles, angles);
//if (model && model->type == mod_alias) //if (model && model->type == mod_alias)
angles[0]*=-1; //pflags matches alias models. angles[0]*=r_meshpitch.value; //pflags matches alias models.
AngleVectors(angles, dl->axis[0], dl->axis[1], dl->axis[2]); AngleVectors(angles, dl->axis[0], dl->axis[1], dl->axis[2]);
VectorInverse(dl->axis[1]); VectorInverse(dl->axis[1]);
R_LoadNumberedLightTexture(dl, state->skinnum); R_LoadNumberedLightTexture(dl, state->skinnum);
@ -4096,7 +4095,7 @@ void CL_LinkPacketEntities (void)
} }
if (model && model->type == mod_alias) if (model && model->type == mod_alias)
angles[0]*=-1; //carmack screwed up when he added alias models - they pitch the wrong way. angles[0]*=r_meshpitch.value; //carmack screwed up when he added alias models - they pitch the wrong way.
VectorCopy(angles, ent->angles); VectorCopy(angles, ent->angles);
AngleVectors(angles, ent->axis[0], ent->axis[1], ent->axis[2]); AngleVectors(angles, ent->axis[0], ent->axis[1], ent->axis[2]);
VectorInverse(ent->axis[1]); VectorInverse(ent->axis[1]);
@ -4319,10 +4318,10 @@ void CL_LinkProjectiles (void)
VectorCopy (pr->origin, ent->origin); VectorCopy (pr->origin, ent->origin);
VectorCopy (pr->angles, ent->angles); VectorCopy (pr->angles, ent->angles);
ent->angles[0]*=-1; ent->angles[0]*=r_meshpitch.value;
AngleVectors(ent->angles, ent->axis[0], ent->axis[1], ent->axis[2]); AngleVectors(ent->angles, ent->axis[0], ent->axis[1], ent->axis[2]);
VectorInverse(ent->axis[1]); VectorInverse(ent->axis[1]);
ent->angles[0]*=-1; ent->angles[0]*=r_meshpitch.value;
} }
} }
@ -4821,7 +4820,7 @@ void CL_AddFlagModels (entity_t *ent, int team)
newent->angles[2] -= 45; newent->angles[2] -= 45;
VectorCopy(newent->angles, angles); VectorCopy(newent->angles, angles);
angles[0]*=-1; angles[0]*=r_meshpitch.value;
AngleVectors(angles, newent->axis[0], newent->axis[1], newent->axis[2]); AngleVectors(angles, newent->axis[0], newent->axis[1], newent->axis[2]);
VectorInverse(newent->axis[1]); VectorInverse(newent->axis[1]);
} }
@ -5071,7 +5070,7 @@ void CL_LinkPlayers (void)
} }
if (model && model->type == mod_alias) if (model && model->type == mod_alias)
angles[0]*=-1; //carmack screwed up when he added alias models - they pitch the wrong way. angles[0]*=r_meshpitch.value; //carmack screwed up when he added alias models - they pitch the wrong way.
VectorCopy(angles, ent->angles); VectorCopy(angles, ent->angles);
AngleVectors(angles, ent->axis[0], ent->axis[1], ent->axis[2]); AngleVectors(angles, ent->axis[0], ent->axis[1], ent->axis[2]);
VectorInverse(ent->axis[1]); VectorInverse(ent->axis[1]);
@ -5162,7 +5161,7 @@ void CL_LinkViewModel(void)
entity_t ent; entity_t ent;
unsigned int plnum; unsigned int plnum;
player_state_t *plstate; unsigned int playereffects;
float alpha; float alpha;
playerview_t *pv = r_refdef.playerview; playerview_t *pv = r_refdef.playerview;
@ -5295,16 +5294,27 @@ void CL_LinkViewModel(void)
plnum = Cam_TrackNum(pv); plnum = Cam_TrackNum(pv);
if (plnum == -1) if (plnum == -1)
plnum = r_refdef.playerview->playernum; plnum = r_refdef.playerview->playernum;
plstate = &cl.inframes[parsecountmod].playerstate[plnum]; playereffects = 0;
if (r_refdef.playerview->nolocalplayer && plnum >= 0 && plnum < cl.maxlerpents)
{
if (plnum+1 < cl.maxlerpents)
{
lerpents_t *le = &cl.lerpents[plnum+1];
if (le->entstate)
playereffects = le->entstate->effects;
}
}
else if (plnum >= 0 && plnum < cl.allocated_client_slots)
playereffects = cl.inframes[parsecountmod].playerstate[plnum].effects;
if (plstate->effects & DPEF_NOGUNBOB) if (playereffects & DPEF_NOGUNBOB)
ent.flags |= RF_WEAPONMODELNOBOB; ent.flags |= RF_WEAPONMODELNOBOB;
/* ent.topcolour = TOP_DEFAULT;//cl.players[plnum].ttopcolor; /* ent.topcolour = TOP_DEFAULT;//cl.players[plnum].ttopcolor;
ent.bottomcolour = cl.players[plnum].tbottomcolor; ent.bottomcolour = cl.players[plnum].tbottomcolor;
ent.h2playerclass = cl.players[plnum].h2playerclass; ent.h2playerclass = cl.players[plnum].h2playerclass;
*/ */
CLQ1_AddPowerupShell(V_AddEntity(&ent), true, plstate?plstate->effects:0); CLQ1_AddPowerupShell(V_AddEntity(&ent), true, playereffects);
//small hack to mask depth so only the front faces of the weaponmodel appear (no glitchy intra faces). //small hack to mask depth so only the front faces of the weaponmodel appear (no glitchy intra faces).
if (alpha < 1 && qrenderer == QR_OPENGL) if (alpha < 1 && qrenderer == QR_OPENGL)
@ -5382,7 +5392,7 @@ void CL_SetSolidEntities (void)
if (pent->model->loadstate != MLS_LOADED) if (pent->model->loadstate != MLS_LOADED)
continue; continue;
VectorCopy (state->angles, pent->angles); VectorCopy (state->angles, pent->angles);
pent->angles[0]*=-1; pent->angles[0]*=r_meshpitch.value;
} }
else else
{ {

View file

@ -739,8 +739,7 @@ void CL_ClampPitch (int pnum)
Matrix4_Multiply(Matrix4x4_CM_NewRotation(roll, 1, 0, 0), mat, mat2); Matrix4_Multiply(Matrix4x4_CM_NewRotation(roll, 1, 0, 0), mat, mat2);
#endif #endif
Matrix3x4_RM_ToVectors(mat2, view[0], view[1], view[2], view[3]); Matrix3x4_RM_ToVectors(mat2, view[0], view[1], view[2], view[3]);
VectorAngles(view[0], view[2], pv->viewangles); VectorAngles(view[0], view[2], pv->viewangles, false);
pv->viewangles[PITCH]=360 - pv->viewangles[PITCH];
VectorClear(pv->viewanglechange); VectorClear(pv->viewanglechange);
return; return;
@ -782,8 +781,7 @@ void CL_ClampPitch (int pnum)
Matrix4_Multiply(viewm, invsurfm, mat); Matrix4_Multiply(viewm, invsurfm, mat);
/*convert that back to angles*/ /*convert that back to angles*/
Matrix3x4_RM_ToVectors(mat, view[0], view[1], view[2], view[3]); Matrix3x4_RM_ToVectors(mat, view[0], view[1], view[2], view[3]);
VectorAngles(view[0], view[2], vang); VectorAngles(view[0], view[2], vang, false);
vang[PITCH] *= -1;
/*edit it*/ /*edit it*/
vang[PITCH] += pv->viewanglechange[PITCH]; vang[PITCH] += pv->viewanglechange[PITCH];
@ -833,8 +831,7 @@ void CL_ClampPitch (int pnum)
Matrix4_Multiply(mat, surfm, viewm); Matrix4_Multiply(mat, surfm, viewm);
/*and figure out the final result*/ /*and figure out the final result*/
Matrix3x4_RM_ToVectors(viewm, view[0], view[1], view[2], view[3]); Matrix3x4_RM_ToVectors(viewm, view[0], view[1], view[2], view[3]);
VectorAngles(view[0], view[2], cl.playerview[pnum].viewangles); VectorAngles(view[0], view[2], cl.playerview[pnum].viewangles, false);
cl.playerview[pnum].viewangles[PITCH] *= -1;
if (pv->viewangles[ROLL] >= 360) if (pv->viewangles[ROLL] >= 360)
pv->viewangles[ROLL] -= 360; pv->viewangles[ROLL] -= 360;

View file

@ -4931,7 +4931,7 @@ void CL_UpdateHeadAngles(void)
AngleVectorsFLU(pv->viewangles, tmp[0], tmp[1], tmp[2]); AngleVectorsFLU(pv->viewangles, tmp[0], tmp[1], tmp[2]);
R_ConcatRotations(headchange, tmp, tmp2); R_ConcatRotations(headchange, tmp, tmp2);
VectorAngles(tmp2[0], tmp2[2], pv->viewangles); VectorAngles(tmp2[0], tmp2[2], pv->viewangles);
pv->viewangles[0] *= -1; pv->viewangles[0] *= r_meshpitch.value;
//fall through //fall through
default: default:

View file

@ -4448,9 +4448,9 @@ void CL_ParseStaticProt (int baselinetype)
VectorCopy (es.angles, ent->angles); VectorCopy (es.angles, ent->angles);
if (ent->model && ent->model->type == mod_alias) if (ent->model && ent->model->type == mod_alias)
{ {
es.angles[0]*=-1; es.angles[0]*=r_meshpitch.value;
AngleVectors(es.angles, ent->axis[0], ent->axis[1], ent->axis[2]); AngleVectors(es.angles, ent->axis[0], ent->axis[1], ent->axis[2]);
es.angles[0]*=-1; es.angles[0]*=r_meshpitch.value;
} }
else else
AngleVectors(es.angles, ent->axis[0], ent->axis[1], ent->axis[2]); AngleVectors(es.angles, ent->axis[0], ent->axis[1], ent->axis[2]);

View file

@ -776,7 +776,7 @@ static void CL_EntStateToPlayerState(player_state_t *plstate, entity_state_t *st
VectorSet(plstate->gravitydir, 0, 0, -1); VectorSet(plstate->gravitydir, 0, 0, -1);
else else
{ {
a[0] = ((-192-state->u.q1.gravitydir[0])/256.0f) * 360; a[0] = ((192+state->u.q1.gravitydir[0])/256.0f) * 360;
a[1] = (state->u.q1.gravitydir[1]/256.0f) * 360; a[1] = (state->u.q1.gravitydir[1]/256.0f) * 360;
a[2] = 0; a[2] = 0;
AngleVectors(a, plstate->gravitydir, NULL, NULL); AngleVectors(a, plstate->gravitydir, NULL, NULL);
@ -1302,10 +1302,9 @@ void CL_PredictMovePNum (int seat)
#endif #endif
{ {
VectorScale(pv->simangles, 1, le->angles); VectorScale(pv->simangles, 1, le->angles);
if (pv->pmovetype == PM_6DOF) if (pv->pmovetype != PM_6DOF)
le->angles[0] *= -1; le->angles[0] *= 0.333;
else le->angles[0] *= r_meshpitch.value;
le->angles[0] *= -0.333;
} }
} }
@ -1316,8 +1315,7 @@ void CL_PredictMovePNum (int seat)
vec3_t dir; vec3_t dir;
VectorSubtract(pv->simorg, pv->cam_desired_position, dir); VectorSubtract(pv->simorg, pv->cam_desired_position, dir);
VectorAngles(dir, NULL, pv->simangles); VectorAngles(dir, NULL, pv->simangles, false);
pv->simangles[0] *= -1;
VectorCopy(pv->simangles, pv->viewangles); VectorCopy(pv->simangles, pv->viewangles);
pv->viewangles[0] = anglemod(pv->viewangles[0]); pv->viewangles[0] = anglemod(pv->viewangles[0]);
if (pv->viewangles[0] > 180) if (pv->viewangles[0] > 180)

View file

@ -481,8 +481,15 @@ void SCR_CenterPrint (int pnum, char *str, qboolean skipgamecode)
} }
else if (str[1] == 'I') else if (str[1] == 'I')
{ {
char *e = strchr(str+=2, ':'); char *e;
int l = e - str; int l;
str+=2;
e = strchr(str, ':');
if (!e)
e = strchr(str, ' '); //probably an error
if (!e)
e = str + strlen(str)-1; //error
l = e - str;
if (l >= sizeof(p->titleimage)) if (l >= sizeof(p->titleimage))
l = sizeof(p->titleimage)-1; l = sizeof(p->titleimage)-1;
strncpy(p->titleimage, str, l); strncpy(p->titleimage, str, l);
@ -2384,7 +2391,7 @@ static void SCR_ScreenShot_f (void)
Con_Printf (CON_ERROR "Couldn't write %s\n", sysname); Con_Printf (CON_ERROR "Couldn't write %s\n", sysname);
} }
void *SCR_ScreenShot_Capture(int fbwidth, int fbheight, enum uploadfmt *fmt) static void *SCR_ScreenShot_Capture(int fbwidth, int fbheight, enum uploadfmt *fmt)
{ {
int width, height; int width, height;
void *buf; void *buf;
@ -2468,10 +2475,10 @@ static void SCR_ScreenShot_Mega_f(void)
if (!fbwidth) if (!fbwidth)
fbwidth = sh_config.texture_maxsize; fbwidth = sh_config.texture_maxsize;
fbwidth = bound(0, fbwidth, sh_config.texture_maxsize); fbwidth = bound(1, fbwidth, sh_config.texture_maxsize);
if (!fbheight) if (!fbheight)
fbheight = (fbwidth * 3)/4; fbheight = (fbwidth * 3)/4;
fbheight = bound(0, fbheight, sh_config.texture_maxsize); fbheight = bound(1, fbheight, sh_config.texture_maxsize);
if (strstr (screenyname, "..") || strchr(screenyname, ':') || *screenyname == '.' || *screenyname == '/') if (strstr (screenyname, "..") || strchr(screenyname, ':') || *screenyname == '.' || *screenyname == '/')
screenyname = ""; screenyname = "";
@ -2567,6 +2574,8 @@ static void SCR_ScreenShot_VR_f(void)
if (width <= 2) if (width <= 2)
width = 2048; width = 2048;
if (width > sh_config.texture_maxsize)
width = sh_config.texture_maxsize;
height = width/2; height = width/2;
if (step <= 0) if (step <= 0)
step = 5; step = 5;
@ -2693,9 +2702,57 @@ static void SCR_ScreenShot_VR_f(void)
VectorClear(r_refdef.eyeoffset); VectorClear(r_refdef.eyeoffset);
} }
void SCR_ScreenShot_EnvMap_f(void) void SCR_ScreenShot_Cubemap_f(void)
{ {
Con_Printf("Not implemented\n"); void *buffer;
int fbwidth, fbheight;
uploadfmt_t fmt;
char filename[MAX_QPATH];
char *fname = Cmd_Argv(1);
int i;
const struct
{
vec3_t angle;
const char *postfix;
} sides[] =
{
{{0, 0, 0}, "_px"},
{{0, 180, 0}, "_nx"},
{{0, 90, 0}, "_py"},
{{0, 270, 0}, "_ny"},
{{90, 0, 0}, "_pz"},
{{-90, 0, 0}, "_nz"}
};
r_refdef.stereomethod = STEREO_OFF;
fbheight = atoi(Cmd_Argv(2));
if (fbheight < 1)
fbheight = 512;
fbwidth = fbheight;
for (i = 0; i < countof(sides); i++)
{
Q_snprintfz(filename, sizeof(filename), "cubemaps/%s%s", fname, sides[i].postfix);
COM_DefaultExtension (filename, scr_sshot_type.string, sizeof(filename));
buffer = SCR_ScreenShot_Capture(fbwidth, fbheight, &fmt);
if (buffer)
{
char sysname[1024];
if (SCR_ScreenShot(filename, FS_GAMEONLY, &buffer, 1, fbwidth, fbheight, fmt))
{
FS_NativePath(filename, FS_GAMEONLY, sysname, sizeof(sysname));
Con_Printf ("Wrote %s\n", sysname);
}
else
{
FS_NativePath(filename, FS_GAMEONLY, sysname, sizeof(sysname));
Con_Printf ("Failed to write %s\n", sysname);
}
BZ_Free(buffer);
}
}
} }
@ -3035,7 +3092,8 @@ void SCR_Init (void)
Cmd_AddCommandD ("screenshot_mega",SCR_ScreenShot_Mega_f, "screenshot_mega <name> [width] [height]\nTakes a screenshot with explicit sizes that are not tied to the size of your monitor, allowing for true monstrosities."); Cmd_AddCommandD ("screenshot_mega",SCR_ScreenShot_Mega_f, "screenshot_mega <name> [width] [height]\nTakes a screenshot with explicit sizes that are not tied to the size of your monitor, allowing for true monstrosities.");
Cmd_AddCommandD ("screenshot_stereo",SCR_ScreenShot_Mega_f, "screenshot_stereo <name> [width] [height]\nTakes a simple stereo screenshot."); Cmd_AddCommandD ("screenshot_stereo",SCR_ScreenShot_Mega_f, "screenshot_stereo <name> [width] [height]\nTakes a simple stereo screenshot.");
Cmd_AddCommandD ("screenshot_vr",SCR_ScreenShot_VR_f, "screenshot_vr <name> [width]\nTakes a spherical stereoscopic panorama image, for viewing with VR displays."); Cmd_AddCommandD ("screenshot_vr",SCR_ScreenShot_VR_f, "screenshot_vr <name> [width]\nTakes a spherical stereoscopic panorama image, for viewing with VR displays.");
Cmd_AddCommand ("envmap",SCR_ScreenShot_EnvMap_f); Cmd_AddCommandD ("screenshot_cubemap",SCR_ScreenShot_Cubemap_f, "screenshot_cubemap <name> [size]\nTakes 6 screenshots forming a single cubemap.");
Cmd_AddCommandD ("envmap",SCR_ScreenShot_Cubemap_f, "Legacy name for the screenshot_cubemap command."); //legacy
Cmd_AddCommand ("screenshot",SCR_ScreenShot_f); Cmd_AddCommand ("screenshot",SCR_ScreenShot_f);
Cmd_AddCommand ("sizeup",SCR_SizeUp_f); Cmd_AddCommand ("sizeup",SCR_SizeUp_f);
Cmd_AddCommand ("sizedown",SCR_SizeDown_f); Cmd_AddCommand ("sizedown",SCR_SizeDown_f);

View file

@ -1378,6 +1378,7 @@ void CL_ParseTEnt (void)
explosion_t *ex = CL_AllocExplosion (pos); explosion_t *ex = CL_AllocExplosion (pos);
ex->start = cl.time; ex->start = cl.time;
ex->model = Mod_ForName ("progs/s_explod.spr", MLV_WARN); ex->model = Mod_ForName ("progs/s_explod.spr", MLV_WARN);
ex->endalpha = ex->startalpha; //don't fade out
} }
break; break;
@ -2369,7 +2370,7 @@ void CL_SpawnSpriteEffect(vec3_t org, vec3_t dir, vec3_t orientationup, model_t
ex->angles[1] = 270; ex->angles[1] = 270;
else else
ex->angles[1] = 0; ex->angles[1] = 0;
ex->angles[0]*=-1; ex->angles[0]*=r_meshpitch.value;
} }
@ -2789,7 +2790,7 @@ fixme:
ex->angles[1] = 270; ex->angles[1] = 270;
else else
ex->angles[1] = 0; ex->angles[1] = 0;
ex->angles[0]*=-1; ex->angles[0]*=r_meshpitch.value;
S_StartSound (0, 0, S_PrecacheSound ("weapons/lashit.wav"), pos, NULL, 1, 1, 0, 0, 0); S_StartSound (0, 0, S_PrecacheSound ("weapons/lashit.wav"), pos, NULL, 1, 1, 0, 0, 0);
@ -3116,7 +3117,7 @@ fixme:
ex->angles[1] = 270; ex->angles[1] = 270;
else else
ex->angles[1] = 0; ex->angles[1] = 0;
ex->angles[0]*=-1; ex->angles[0]*=r_meshpitch.value;
S_StartSound (0, 0, S_PrecacheSound ("weapons/lashit.wav"), pos, NULL, 1, 1, 0, 0, 0); S_StartSound (0, 0, S_PrecacheSound ("weapons/lashit.wav"), pos, NULL, 1, 1, 0, 0, 0);
@ -3165,7 +3166,7 @@ fixme:
ex->angles[1] = 270; ex->angles[1] = 270;
else else
ex->angles[1] = 0; ex->angles[1] = 0;
ex->angles[0]*=-1; ex->angles[0]*=r_meshpitch.value;
S_StartSound (0, 0, S_PrecacheSound ("weapons/lashit.wav"), pos, NULL, 1, 1, 0, 0, 0); S_StartSound (0, 0, S_PrecacheSound ("weapons/lashit.wav"), pos, NULL, 1, 1, 0, 0, 0);
@ -3569,10 +3570,9 @@ void CL_UpdateBeams (void)
VectorSubtract (playerbeam_end[j], vieworg, org); VectorSubtract (playerbeam_end[j], vieworg, org);
len = VectorLength(org); len = VectorLength(org);
org[2] -= 22; // adjust for view height org[2] -= 22; // adjust for view height
VectorAngles (org, NULL, ang); VectorAngles (org, NULL, ang, false);
// lerp pitch // lerp pitch
ang[0] = -ang[0];
if (ang[0] < -180) if (ang[0] < -180)
ang[0] += 360; ang[0] += 360;
ang[0] += (viewang[0] - ang[0]) * f; ang[0] += (viewang[0] - ang[0]) * f;
@ -3823,7 +3823,7 @@ void CL_UpdateExplosions (void)
VectorCopy (ex->oldorigin, ent->oldorigin); VectorCopy (ex->oldorigin, ent->oldorigin);
VectorCopy (ex->angles, ent->angles); VectorCopy (ex->angles, ent->angles);
ent->skinnum = ex->skinnum; ent->skinnum = ex->skinnum;
ent->angles[0]*=-1; ent->angles[0]*=r_meshpitch.value;
AngleVectors(ent->angles, ent->axis[0], ent->axis[1], ent->axis[2]); AngleVectors(ent->angles, ent->axis[0], ent->axis[1], ent->axis[2]);
VectorInverse(ent->axis[1]); VectorInverse(ent->axis[1]);
ent->model = ex->model; ent->model = ex->model;

View file

@ -1430,8 +1430,6 @@ void Cam_TrackPlayer(int seat, char *cmdname, char *plrarg);
void CL_InitCam(void); void CL_InitCam(void);
void Cam_AutoTrack_Update(const char *mode); //reset autotrack setting (because we started a new map or whatever) void Cam_AutoTrack_Update(const char *mode); //reset autotrack setting (because we started a new map or whatever)
void QDECL vectoangles(vec3_t fwd, vec3_t ang);
// //
//zqtp.c //zqtp.c
// //

View file

@ -1762,7 +1762,7 @@ static void CLQ2_AddPacketEntities (q2frame_t *frame)
} }
} }
ent.angles[0]*=-1; //q2 has it fixed. ent.angles[0]*=r_meshpitch.value; //q2 has it fixed.
if (s1->number == cl.playerview[0].playernum+1) //woo! this is us! if (s1->number == cl.playerview[0].playernum+1) //woo! this is us!
{ {

View file

@ -348,7 +348,7 @@ void PM_ValidatePackage(package_t *p)
} }
} }
} }
if (o && o->qhash && p->qhash && (o->flags & DPF_CACHED) && fl == DPF_CACHED) if (o && o->qhash && p->qhash && (o->flags & DPF_CACHED) || fl == DPF_CACHED)
p->flags |= DPF_CACHED; p->flags |= DPF_CACHED;
else if (!o) else if (!o)
{ {
@ -2547,13 +2547,13 @@ static qboolean MD_Key (struct menucustom_s *c, struct menu_s *m, int key, unsig
case DPF_MARKED: case DPF_MARKED:
p->flags |= DPF_PURGE; p->flags |= DPF_PURGE;
//now: re-get despite already having it. //now: re-get despite already having it.
if ((p->flags & DPF_PRESENT) && !PM_PurgeOnDisable(p)) if ((p->flags & DPF_CORRUPT) || ((p->flags & DPF_PRESENT) && !PM_PurgeOnDisable(p)))
break; //only makes sense if we already have a cached copy that we're not going to use. break; //only makes sense if we already have a cached copy that we're not going to use.
//fallthrough //fallthrough
case DPF_MARKED|DPF_PURGE: case DPF_MARKED|DPF_PURGE:
PM_UnmarkPackage(p); PM_UnmarkPackage(p);
//now: delete //now: delete
if ((p->flags & DPF_PRESENT) && !PM_PurgeOnDisable(p)) if ((p->flags & DPF_CORRUPT) || ((p->flags & DPF_PRESENT) && !PM_PurgeOnDisable(p)))
break; //only makes sense if we have a cached/corrupt copy of it already break; //only makes sense if we have a cached/corrupt copy of it already
//fallthrough //fallthrough
case DPF_PURGE: case DPF_PURGE:

View file

@ -2933,10 +2933,10 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_
ent.light_known = 2; ent.light_known = 2;
// ent.angles[0]*=-1; // ent.angles[0]*=r_meshpitch.value;
AngleVectors(ent.angles, ent.axis[0], ent.axis[1], ent.axis[2]); AngleVectors(ent.angles, ent.axis[0], ent.axis[1], ent.axis[2]);
VectorInverse(ent.axis[1]); VectorInverse(ent.axis[1]);
// ent.angles[0]*=-1; // ent.angles[0]*=r_meshpitch.value;
if (ent.model->type == mod_dummy) if (ent.model->type == mod_dummy)
{ {

View file

@ -557,17 +557,25 @@ static void cs_getframestate(csqcedict_t *in, unsigned int rflags, framestate_t
out->g[FST_BASE].frame[0] = in->xv->baseframe; out->g[FST_BASE].frame[0] = in->xv->baseframe;
out->g[FST_BASE].frame[1] = in->xv->baseframe2; out->g[FST_BASE].frame[1] = in->xv->baseframe2;
//out->g[FST_BASE].frame[2] = in->xv->baseframe3;
//out->g[FST_BASE].frame[3] = in->xv->baseframe4;
out->g[FST_BASE].lerpweight[1] = in->xv->baselerpfrac; out->g[FST_BASE].lerpweight[1] = in->xv->baselerpfrac;
out->g[FST_BASE].lerpweight[0] = 1-out->g[FST_BASE].lerpweight[1]; // out->g[FST_BASE].lerpweight[2] = in->xv->baselerpfrac3;
// out->g[FST_BASE].lerpweight[3] = in->xv->baselerpfrac4;
out->g[FST_BASE].lerpweight[0] = 1-(out->g[FST_BASE].lerpweight[1]);
if (rflags & CSQCRF_FRAMETIMESARESTARTTIMES) if (rflags & CSQCRF_FRAMETIMESARESTARTTIMES)
{ {
out->g[FST_BASE].frametime[0] = *csqcg.simtime - in->xv->baseframe1time; out->g[FST_BASE].frametime[0] = *csqcg.simtime - in->xv->baseframe1time;
out->g[FST_BASE].frametime[1] = *csqcg.simtime - in->xv->baseframe2time; out->g[FST_BASE].frametime[1] = *csqcg.simtime - in->xv->baseframe2time;
//out->g[FST_BASE].frametime[2] = *csqcg.simtime - in->xv->baseframe3time;
//out->g[FST_BASE].frametime[3] = *csqcg.simtime - in->xv->baseframe4time;
} }
else else
{ {
out->g[FST_BASE].frametime[0] = in->xv->baseframe1time; out->g[FST_BASE].frametime[0] = in->xv->baseframe1time;
out->g[FST_BASE].frametime[1] = in->xv->baseframe2time; out->g[FST_BASE].frametime[1] = in->xv->baseframe2time;
//out->g[FST_BASE].frametime[2] = in->xv->baseframe3time;
//out->g[FST_BASE].frametime[3] = in->xv->baseframe4time;
} }
} }
@ -820,7 +828,7 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out)
{ {
VectorCopy(in->v->angles, out->angles); VectorCopy(in->v->angles, out->angles);
if (model->type == mod_alias) if (model->type == mod_alias)
out->angles[0]*=-1; out->angles[0] *= r_meshpitch.value;
AngleVectors(out->angles, out->axis[0], out->axis[1], out->axis[2]); AngleVectors(out->angles, out->axis[0], out->axis[1], out->axis[2]);
VectorInverse(out->axis[1]); VectorInverse(out->axis[1]);
@ -1083,10 +1091,10 @@ static void QCBUILTIN PF_R_DynamicLight_Get(pubprogfuncs_t *prinst, struct globa
G_FLOAT(OFS_RETURN) = l->style-1; G_FLOAT(OFS_RETURN) = l->style-1;
break; break;
case lfield_angles: case lfield_angles:
VectorAngles(l->axis[0], l->axis[2], v); VectorAngles(l->axis[0], l->axis[2], v, false);
G_FLOAT(OFS_RETURN+0) = anglemod(v[0]?-v[0]:0); G_FLOAT(OFS_RETURN+0) = anglemod(v[0]);
G_FLOAT(OFS_RETURN+1) = v[1]?v[1]:0; G_FLOAT(OFS_RETURN+1) = v[1];
G_FLOAT(OFS_RETURN+2) = v[2]?v[2]:0; G_FLOAT(OFS_RETURN+2) = v[2];
break; break;
case lfield_fov: case lfield_fov:
G_FLOAT(OFS_RETURN) = l->fov; G_FLOAT(OFS_RETURN) = l->fov;
@ -1542,20 +1550,20 @@ void QCBUILTIN PF_R_AddTrisoup(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
//validates the pointer. //validates the pointer.
numverts = (prinst->stringtablesize - vertsptr) / sizeof(qcvertex_t); numverts = (prinst->stringtablesize - vertsptr) / sizeof(qcvertex_t);
if (numverts < 1 || vertsptr <= 0 || vertsptr+numverts*sizeof(qcvertex_t) >= prinst->stringtablesize) if (numverts < 1 || vertsptr <= 0 || vertsptr+numverts*sizeof(qcvertex_t) > prinst->stringtablesize)
{ {
PR_BIError(prinst, "PF_R_AddTrisoup: invalid vertexes pointer\n"); PR_BIError(prinst, "PF_R_AddTrisoup: invalid vertexes pointer\n");
return; return;
} }
vert = (qcvertex_t*)(prinst->stringtable + vertsptr); vert = (qcvertex_t*)(prinst->stringtable + vertsptr);
if (indexesptr <= 0 || indexesptr+numindexes*sizeof(int) >= prinst->stringtablesize) if (indexesptr <= 0 || indexesptr+numindexes*sizeof(int) > prinst->stringtablesize)
{ {
PR_BIError(prinst, "PF_R_AddTrisoup: invalid indexes pointer\n"); PR_BIError(prinst, "PF_R_AddTrisoup: invalid indexes pointer\n");
return; return;
} }
idx = (int*)(prinst->stringtable + indexesptr); idx = (int*)(prinst->stringtable + indexesptr);
first = csqc_poly_startvert - csqc_poly_origvert; first = cl_numstrisvert - csqc_poly_origvert;
if (first + numindexes > MAX_INDICIES) if (first + numindexes > MAX_INDICIES)
{ {
if (numindexes > MAX_INDICIES) if (numindexes > MAX_INDICIES)
@ -1603,7 +1611,8 @@ void QCBUILTIN PF_R_AddTrisoup(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
cl_strisidx[cl_numstrisidx++] = first++; cl_strisidx[cl_numstrisidx++] = first++;
} }
//this is where our current poly starts, so verts+end can still work properly afterwards.
//in case someone calls polygonvertex+end without beginpolygon
csqc_poly_startvert = cl_numstrisvert; csqc_poly_startvert = cl_numstrisvert;
csqc_poly_startidx = cl_numstrisidx; csqc_poly_startidx = cl_numstrisidx;
} }
@ -2504,7 +2513,7 @@ static model_t *csqc_setmodel(pubprogfuncs_t *prinst, csqcedict_t *ent, int mode
return NULL; return NULL;
prinst->SetStringField(prinst, (void*)ent, &ent->v->model, cl.model_csqcname[-modelindex], true); prinst->SetStringField(prinst, (void*)ent, &ent->v->model, cl.model_csqcname[-modelindex], true);
if (!cl.model_csqcprecache[-modelindex]) if (!cl.model_csqcprecache[-modelindex])
cl.model_csqcprecache[-modelindex] = Mod_ForName(Mod_FixName(cl.model_csqcname[-modelindex], csqc_world.worldmodel->name), MLV_WARN); cl.model_csqcprecache[-modelindex] = Mod_ForName(Mod_FixName(cl.model_csqcname[-modelindex], csqc_world.worldmodel->publicname), MLV_WARN);
model = cl.model_csqcprecache[-modelindex]; model = cl.model_csqcprecache[-modelindex];
} }
else else
@ -2587,7 +2596,7 @@ static void QCBUILTIN PF_cs_PrecacheModel(pubprogfuncs_t *prinst, struct globalv
return; return;
} }
fixedname = Mod_FixName(modelname, csqc_world.worldmodel->name); fixedname = Mod_FixName(modelname, csqc_world.worldmodel->publicname);
for (i = 1; i < MAX_PRECACHE_MODELS; i++) //Make sure that the server specified model is loaded.. for (i = 1; i < MAX_PRECACHE_MODELS; i++) //Make sure that the server specified model is loaded..
{ {
@ -2607,7 +2616,7 @@ static void QCBUILTIN PF_cs_PrecacheModel(pubprogfuncs_t *prinst, struct globalv
{ {
if (!freei) if (!freei)
Host_EndGame("CSQC ran out of model slots\n"); Host_EndGame("CSQC ran out of model slots\n");
fixedname = Mod_FixName(modelname, csqc_world.worldmodel->name); fixedname = Mod_FixName(modelname, csqc_world.worldmodel->publicname);
Q_strncpyz(cl.model_csqcname[-freei], fixedname, sizeof(cl.model_csqcname[-freei])); //allocate a slot now Q_strncpyz(cl.model_csqcname[-freei], fixedname, sizeof(cl.model_csqcname[-freei])); //allocate a slot now
modelindex = freei; modelindex = freei;
@ -3233,7 +3242,7 @@ static void QCBUILTIN PF_cs_runplayerphysics (pubprogfuncs_t *prinst, struct glo
} }
VectorCopy(pmove.angles, ent->v->angles); VectorCopy(pmove.angles, ent->v->angles);
ent->v->angles[0] *= -1/3.0f; //FIXME ent->v->angles[0] *= r_meshpitch.value * 1/3.0f; //FIXME
VectorCopy(pmove.origin, ent->v->origin); VectorCopy(pmove.origin, ent->v->origin);
VectorCopy(pmove.velocity, ent->v->velocity); VectorCopy(pmove.velocity, ent->v->velocity);
ent->xv->pmove_flags = 0; ent->xv->pmove_flags = 0;
@ -4757,7 +4766,7 @@ void CSQC_PlayerStateToCSQC(int pnum, player_state_t *srcp, csqcedict_t *ent)
VectorCopy(srcp->viewangles, ent->v->angles); VectorCopy(srcp->viewangles, ent->v->angles);
VectorCopy(srcp->velocity, ent->v->velocity); VectorCopy(srcp->velocity, ent->v->velocity);
ent->v->angles[0] *= -0.333; ent->v->angles[0] *= r_meshpitch.value * 0.333;
ent->v->colormap = pnum+1; ent->v->colormap = pnum+1;
ent->xv->scale = srcp->scale; ent->xv->scale = srcp->scale;
//ent->v->fatness = srcp->fatness; //ent->v->fatness = srcp->fatness;
@ -5133,7 +5142,7 @@ static void QCBUILTIN PF_getentity(pubprogfuncs_t *prinst, struct globalvars_s *
case GE_GRAVITYDIR: case GE_GRAVITYDIR:
{ {
vec3_t a; vec3_t a;
a[0] = ((-192-es->u.q1.gravitydir[0])/256.0f) * 360; a[0] = ((192+es->u.q1.gravitydir[0])/256.0f) * 360;
a[1] = (es->u.q1.gravitydir[1]/256.0f) * 360; a[1] = (es->u.q1.gravitydir[1]/256.0f) * 360;
a[2] = 0; a[2] = 0;
AngleVectors(a, G_VECTOR(OFS_RETURN), NULL, NULL); AngleVectors(a, G_VECTOR(OFS_RETURN), NULL, NULL);
@ -6856,7 +6865,7 @@ qboolean CSQC_Init (qboolean anycsqc, qboolean csdatenabled, unsigned int checks
csqc_world.Get_CModel = CSQC_World_ModelForIndex; csqc_world.Get_CModel = CSQC_World_ModelForIndex;
csqc_world.Get_FrameState = CSQC_World_GetFrameState; csqc_world.Get_FrameState = CSQC_World_GetFrameState;
csqc_world.defaultgravityscale = 1; csqc_world.defaultgravityscale = 1;
World_ClearWorld(&csqc_world); World_ClearWorld(&csqc_world, false);
CSQC_InitFields(); //let the qclib know the field order that the engine needs. CSQC_InitFields(); //let the qclib know the field order that the engine needs.
if (setjmp(csqc_abort)) if (setjmp(csqc_abort))
@ -7033,6 +7042,8 @@ void CSQC_WorldLoaded(void)
worldent->readonly = false; //just in case worldent->readonly = false; //just in case
World_ClearWorld(&csqc_world, true);
if (csqc_isdarkplaces) if (csqc_isdarkplaces)
{ {
if (csqcg.init_function) if (csqcg.init_function)
@ -7290,7 +7301,7 @@ qboolean CSQC_SetupToRenderPortal(int entkeynum)
*csqcg.self = EDICT_TO_PROG(csqcprogs, e); *csqcg.self = EDICT_TO_PROG(csqcprogs, e);
VectorCopy(r_refdef.vieworg, G_VECTOR(OFS_PARM0)); VectorCopy(r_refdef.vieworg, G_VECTOR(OFS_PARM0));
VectorAngles(vpn, vup, G_VECTOR(OFS_PARM1)); VectorAngles(vpn, vup, G_VECTOR(OFS_PARM1), true/*FIXME*/);
VectorCopy(vpn, csqcg.forward); VectorCopy(vpn, csqcg.forward);
VectorCopy(vright, csqcg.right); VectorCopy(vright, csqcg.right);
VectorCopy(vup, csqcg.up); VectorCopy(vup, csqcg.up);

View file

@ -220,12 +220,11 @@ static void bonemat_fromentity(world_t *w, wedict_t *ed, float *trans)
vec3_t d[3], a; vec3_t d[3], a;
model_t *mod; model_t *mod;
mod = w->Get_CModel(w, ed->v->modelindex); mod = w->Get_CModel(w, ed->v->modelindex);
if (!mod || mod->type == mod_alias) a[0] = ed->v->angles[0];
a[0] = -ed->v->angles[0];
else
a[0] = ed->v->angles[0];
a[1] = ed->v->angles[1]; a[1] = ed->v->angles[1];
a[2] = ed->v->angles[2]; a[2] = ed->v->angles[2];
if (!mod || mod->type == mod_alias)
a[0] *= r_meshpitch.value;
AngleVectors(a, d[0], d[1], d[2]); AngleVectors(a, d[0], d[1], d[2]);
bonemat_fromqcvectors(trans, d[0], d[1], d[2], ed->v->origin); bonemat_fromqcvectors(trans, d[0], d[1], d[2], ed->v->origin);
} }
@ -1610,7 +1609,7 @@ void QCBUILTIN PF_skel_ragedit(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
vec3_t d[3], a; vec3_t d[3], a;
//fixme: respond to renderflags&USEAXIS? scale? //fixme: respond to renderflags&USEAXIS? scale?
a[0] = wed->v->angles[0] * -1; /*mod_alias bug*/ a[0] = wed->v->angles[0] * r_meshpitch.value; /*mod_alias bug*/
a[1] = wed->v->angles[1]; a[1] = wed->v->angles[1];
a[2] = wed->v->angles[2]; a[2] = wed->v->angles[2];
AngleVectors(a, d[0], d[1], d[2]); AngleVectors(a, d[0], d[1], d[2]);
@ -2056,7 +2055,7 @@ void QCBUILTIN PF_skel_set_bone_world (pubprogfuncs_t *prinst, struct globalvars
if (prinst->callargc == 4) if (prinst->callargc == 4)
{ {
vec3_t d[3], a; vec3_t d[3], a;
a[0] = G_VECTOR(OFS_PARM3)[0] * -1; /*mod_alias bug*/ a[0] = G_VECTOR(OFS_PARM3)[0] * r_meshpitch.value; /*mod_alias bug*/
a[1] = G_VECTOR(OFS_PARM3)[1]; a[1] = G_VECTOR(OFS_PARM3)[1];
a[2] = G_VECTOR(OFS_PARM3)[2]; a[2] = G_VECTOR(OFS_PARM3)[2];
AngleVectors(a, d[0], d[1], d[2]); AngleVectors(a, d[0], d[1], d[2]);

View file

@ -628,6 +628,8 @@ extern cvar_t gl_playermip;
extern cvar_t r_lightmap_saturation; extern cvar_t r_lightmap_saturation;
extern cvar_t r_meshpitch;
enum { enum {
RSPEED_TOTALREFRESH, RSPEED_TOTALREFRESH,
RSPEED_LINKENTITIES, RSPEED_LINKENTITIES,

View file

@ -611,7 +611,12 @@ void R_ToggleFullscreen_f(void)
Cvar_ApplyLatches(CVAR_RENDERERLATCH); Cvar_ApplyLatches(CVAR_RENDERERLATCH);
newr = currentrendererstate; newr = currentrendererstate;
newr.fullscreen = newr.fullscreen?0:2; if (newr.fullscreen)
newr.fullscreen = 0; //if we're currently any sort of fullscreen then go windowed
else if (vid_fullscreen.ival)
newr.fullscreen = vid_fullscreen.ival; //if we're normally meant to be fullscreen, use that
else
newr.fullscreen = 2; //otherwise use native resolution
if (newr.fullscreen) if (newr.fullscreen)
{ {
int dbpp, dheight, dwidth, drate; int dbpp, dheight, dwidth, drate;
@ -623,8 +628,14 @@ void R_ToggleFullscreen_f(void)
drate = 0; drate = 0;
} }
newr.width = dwidth; if (newr.fullscreen == 1 && vid_width.ival>0)
newr.height = dheight; newr.width = vid_width.ival;
else
newr.width = dwidth;
if (newr.fullscreen == 1 && vid_height.ival>0)
newr.height = vid_height.ival;
else
newr.height = dheight;
} }
else else
{ {
@ -1392,7 +1403,6 @@ TRACE(("dbg: R_ApplyRenderer: initing mods\n"));
#ifndef CLIENTONLY #ifndef CLIENTONLY
if (sv.world.worldmodel) if (sv.world.worldmodel)
{ {
wedict_t *ent;
#ifdef Q2SERVER #ifdef Q2SERVER
q2edict_t *q2ent; q2edict_t *q2ent;
#endif #endif
@ -1419,23 +1429,9 @@ TRACE(("dbg: R_ApplyRenderer: clearing world\n"));
sv.models[i] = NULL; sv.models[i] = NULL;
} }
World_ClearWorld (&sv.world); World_ClearWorld (&sv.world, true);
ent = sv.world.edicts; // ent = sv.world.edicts;
// ent->v->model = PR_NewString(svprogfuncs, sv.worldmodel->name); //FIXME: is this a problem for normal ents? // ent->v->model = PR_NewString(svprogfuncs, sv.worldmodel->name); //FIXME: is this a problem for normal ents?
for (i=0 ; i<sv.world.num_edicts ; i++)
{
ent = (wedict_t*)EDICT_NUM(svprogfuncs, i);
if (!ent)
continue;
if (ED_ISFREE(ent))
continue;
if (ent->area.prev)
{
ent->area.prev = ent->area.next = NULL;
World_LinkEdict (&sv.world, ent, false); // relink ents so touch functions continue to work.
}
}
} }
#ifdef Q2SERVER #ifdef Q2SERVER
else if (svs.gametype == GT_QUAKE2) else if (svs.gametype == GT_QUAKE2)
@ -1455,7 +1451,7 @@ TRACE(("dbg: R_ApplyRenderer: clearing world\n"));
sv.models[i] = NULL; sv.models[i] = NULL;
} }
World_ClearWorld (&sv.world); World_ClearWorld (&sv.world, false);
q2ent = ge->edicts; q2ent = ge->edicts;
for (i=0 ; i<ge->num_edicts ; i++, q2ent = (q2edict_t *)((char *)q2ent + ge->edict_size)) for (i=0 ; i<ge->num_edicts ; i++, q2ent = (q2edict_t *)((char *)q2ent + ge->edict_size))
{ {

View file

@ -2089,8 +2089,7 @@ void V_RenderPlayerViews(playerview_t *pv)
r_secondaryview = 2; r_secondaryview = 2;
VectorSubtract(r_refdef.vieworg, pv->cam_desired_position, dir); VectorSubtract(r_refdef.vieworg, pv->cam_desired_position, dir);
VectorAngles(dir, NULL, r_refdef.viewangles); VectorAngles(dir, NULL, r_refdef.viewangles, false);
r_refdef.viewangles[0] = -r_refdef.viewangles[0]; //flip the pitch. :(
VectorCopy(pv->cam_desired_position, r_refdef.vieworg); VectorCopy(pv->cam_desired_position, r_refdef.vieworg);

View file

@ -524,9 +524,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#undef VM_CG #undef VM_CG
#undef TEXTEDITOR #undef TEXTEDITOR
#undef RUNTIMELIGHTING #undef RUNTIMELIGHTING
#undef DSPMODELS
#undef SPRMODELS
#undef SP2MODELS
#undef PSET_SCRIPT #undef PSET_SCRIPT
#undef PSET_CLASSIC #undef PSET_CLASSIC

View file

@ -14,6 +14,20 @@ qboolean r_loadbumpmapping;
extern cvar_t dpcompat_psa_ungroup; extern cvar_t dpcompat_psa_ungroup;
extern cvar_t r_noframegrouplerp; extern cvar_t r_noframegrouplerp;
cvar_t r_lerpmuzzlehack = CVARF ("r_lerpmuzzlehack", "1", CVAR_ARCHIVE); cvar_t r_lerpmuzzlehack = CVARF ("r_lerpmuzzlehack", "1", CVAR_ARCHIVE);
static void QDECL r_meshpitch_callback(cvar_t *var, char *oldvalue)
{
if (!strcmp(var->string, "-1") || !strcmp(var->string, "1"))
return;
if (var->value <= 0)
Cvar_ForceSet(var, "-1");
else
Cvar_ForceSet(var, "1");
}
#ifdef NOLEGACY
cvar_t r_meshpitch = CVARCD ("r_meshpitch", "1", r_meshpitch_callback, "Specifies the direction of the pitch angle on mesh models formats, also affects gamecode, so do not change from its default.");
#else
cvar_t r_meshpitch = CVARCD ("r_meshpitch", "-1", r_meshpitch_callback, "Specifies the direction of the pitch angle on mesh models formats, Quake compatibility requires -1.");
#endif
#ifndef SERVERONLY #ifndef SERVERONLY
void Mod_UpdateCRC(void *ctx, void *data, size_t a, size_t b) void Mod_UpdateCRC(void *ctx, void *data, size_t a, size_t b)
@ -2761,10 +2775,11 @@ void Mod_BuildTextureVectors(galiasinfo_t *galias)
#ifndef SERVERONLY #ifndef SERVERONLY
//looks for foo.md3_0.skin files, for dp compat //looks for foo.md3_0.skin files, for dp compat
//also try foo_0.skin, because people appear to use that too. *sigh*. //also try foo_0.skin, because people appear to use that too. *sigh*.
int Mod_CountSkinFiles(char *modelname) int Mod_CountSkinFiles(model_t *mod)
{ {
int i; int i;
char skinfilename[MAX_QPATH]; char skinfilename[MAX_QPATH];
char *modelname = mod->name;
//try and add numbered skins, and then try fixed names. //try and add numbered skins, and then try fixed names.
for (i = 0; ; i++) for (i = 0; ; i++)
{ {
@ -2781,7 +2796,7 @@ int Mod_CountSkinFiles(char *modelname)
} }
//support for foo.md3_0.skin //support for foo.md3_0.skin
shader_t *Mod_ShaderFromQ3SkinFile(galiasinfo_t *surf, char *modelname, int skinnum) shader_t *Mod_ShaderFromQ3SkinFile(galiasinfo_t *surf, model_t *mod, int skinnum)
{ {
shader_t *result = NULL; shader_t *result = NULL;
skinid_t skinid; skinid_t skinid;
@ -2789,6 +2804,7 @@ shader_t *Mod_ShaderFromQ3SkinFile(galiasinfo_t *surf, char *modelname, int skin
int i; int i;
char *filedata; char *filedata;
char skinfilename[MAX_QPATH]; char skinfilename[MAX_QPATH];
char *modelname = mod->name;
if (qrenderer == QR_NONE) if (qrenderer == QR_NONE)
return NULL; return NULL;
@ -2888,7 +2904,7 @@ void Mod_LoadAliasShaders(model_t *mod)
for (j = 0, f = s->frame; j < s->numframes; j++, f++) for (j = 0, f = s->frame; j < s->numframes; j++, f++)
{ {
if (j == 0) if (j == 0)
f->shader = Mod_ShaderFromQ3SkinFile(ai, mod->name, i); f->shader = Mod_ShaderFromQ3SkinFile(ai, mod, i);
else else
f->shader = NULL; f->shader = NULL;
if (!f->shader) if (!f->shader)
@ -4909,7 +4925,7 @@ qboolean QDECL Mod_LoadQ3Model(model_t *mod, void *buffer, size_t fsize)
root = NULL; root = NULL;
#ifndef SERVERONLY #ifndef SERVERONLY
externalskins = Mod_CountSkinFiles(mod->name); externalskins = Mod_CountSkinFiles(mod);
#endif #endif
min[0] = min[1] = min[2] = 0; min[0] = min[1] = min[2] = 0;
@ -5335,7 +5351,7 @@ qboolean QDECL Mod_LoadZymoticModel(model_t *mod, void *buffer, size_t fsize)
} }
#ifndef SERVERONLY #ifndef SERVERONLY
skinfiles = Mod_CountSkinFiles(mod->name); skinfiles = Mod_CountSkinFiles(mod);
if (skinfiles < 1) if (skinfiles < 1)
skinfiles = 1; skinfiles = 1;
@ -6297,7 +6313,7 @@ qboolean QDECL Mod_LoadDarkPlacesModel(model_t *mod, void *buffer, size_t fsize)
} }
#ifndef SERVERONLY #ifndef SERVERONLY
skinfiles = Mod_CountSkinFiles(mod->name); skinfiles = Mod_CountSkinFiles(mod);
if (skinfiles < 1) if (skinfiles < 1)
skinfiles = 1; skinfiles = 1;
#endif #endif
@ -7054,7 +7070,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, size_t fsi
mesh = (struct iqmmesh*)(buffer + h->ofs_meshes); mesh = (struct iqmmesh*)(buffer + h->ofs_meshes);
#ifndef SERVERONLY #ifndef SERVERONLY
skinfiles = Mod_CountSkinFiles(mod->name); skinfiles = Mod_CountSkinFiles(mod);
if (skinfiles < 1) if (skinfiles < 1)
skinfiles = 1; //iqms have 1 skin and one skin only and always. make sure its loaded. skinfiles = 1; //iqms have 1 skin and one skin only and always. make sure its loaded.
#endif #endif

View file

@ -216,7 +216,7 @@ typedef struct modplugfuncs_s
void (QDECL *ConcatTransforms) (float in1[3][4], float in2[3][4], float out[3][4]); void (QDECL *ConcatTransforms) (float in1[3][4], float in2[3][4], float out[3][4]);
void (QDECL *M3x4_Invert) (const float *in1, float *out); void (QDECL *M3x4_Invert) (const float *in1, float *out);
void (QDECL *VectorAngles)(float *forward, float *up, float *result); void (QDECL *VectorAngles)(float *forward, float *up, float *result, qboolean meshpitch);
void (QDECL *AngleVectors)(const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up); void (QDECL *AngleVectors)(const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
void (QDECL *GenMatrixPosQuat4Scale)(const vec3_t pos, const vec4_t quat, const vec3_t scale, float result[12]); void (QDECL *GenMatrixPosQuat4Scale)(const vec3_t pos, const vec4_t quat, const vec3_t scale, float result[12]);

View file

@ -259,7 +259,7 @@ static void World_Bullet_Frame_BodyToEntity(world_t *world, wedict_t *ed)
foo Matrix3x4_RM_ToVectors(entitymatrix, forward, left, up, origin); foo Matrix3x4_RM_ToVectors(entitymatrix, forward, left, up, origin);
VectorAngles(forward, up, angles); VectorAngles(forward, up, angles);
angles[0]*=-1; angles[0]*=r_meshpitch.value;
avelocity[PITCH] = RAD2DEG(spinvelocity[PITCH]); avelocity[PITCH] = RAD2DEG(spinvelocity[PITCH]);
avelocity[YAW] = RAD2DEG(spinvelocity[ROLL]); avelocity[YAW] = RAD2DEG(spinvelocity[ROLL]);
@ -270,8 +270,8 @@ static void World_Bullet_Frame_BodyToEntity(world_t *world, wedict_t *ed)
model = world->Get_CModel(world, ed->v->modelindex); model = world->Get_CModel(world, ed->v->modelindex);
if (!model || model->type == mod_alias) if (!model || model->type == mod_alias)
{ {
angles[PITCH] *= -1; angles[PITCH] *= r_meshpitch.value;
avelocity[PITCH] *= -1; avelocity[PITCH] *= r_meshpitch.value;
} }
} }
@ -856,7 +856,7 @@ public:
if (!model || model->type == mod_alias) if (!model || model->type == mod_alias)
; ;
else else
edict->v->angles[PITCH] *= -1; edict->v->angles[PITCH] *= r_meshpitch.value;
} }
//so it doesn't get rebuilt //so it doesn't get rebuilt
@ -1219,8 +1219,8 @@ static void World_Bullet_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
model = world->Get_CModel(world, ed->v->modelindex); model = world->Get_CModel(world, ed->v->modelindex);
if (!model || model->type == mod_alias) if (!model || model->type == mod_alias)
{ {
qangles[PITCH] *= -1; qangles[PITCH] *= r_meshpitch.value;
qavelocity[PITCH] *= -1; qavelocity[PITCH] *= r_meshpitch.value;
} }
} }

View file

@ -82,6 +82,7 @@ static BUILTINR(cvar_t*, Cvar_GetNVFDG, (const char *name, const char *defaultva
#undef ARGNAMES #undef ARGNAMES
static rbeplugfuncs_t *rbefuncs; static rbeplugfuncs_t *rbefuncs;
cvar_t r_meshpitch;
//============================================================================ //============================================================================
// physics engine support // physics engine support
@ -1484,8 +1485,7 @@ static void World_ODE_Frame_BodyToEntity(world_t *world, wedict_t *ed)
Matrix4_Multiply(ed->ode.ode_offsetimatrix, bodymatrix, entitymatrix); Matrix4_Multiply(ed->ode.ode_offsetimatrix, bodymatrix, entitymatrix);
Matrix3x4_RM_ToVectors(entitymatrix, forward, left, up, origin); Matrix3x4_RM_ToVectors(entitymatrix, forward, left, up, origin);
VectorAngles(forward, up, angles); VectorAngles(forward, up, angles, false);
angles[0]*=-1;
avelocity[PITCH] = RAD2DEG(spinvelocity[PITCH]); avelocity[PITCH] = RAD2DEG(spinvelocity[PITCH]);
avelocity[YAW] = RAD2DEG(spinvelocity[ROLL]); avelocity[YAW] = RAD2DEG(spinvelocity[ROLL]);
avelocity[ROLL] = RAD2DEG(spinvelocity[YAW]); avelocity[ROLL] = RAD2DEG(spinvelocity[YAW]);
@ -1495,8 +1495,8 @@ static void World_ODE_Frame_BodyToEntity(world_t *world, wedict_t *ed)
model = world->Get_CModel(world, ed->v->modelindex); model = world->Get_CModel(world, ed->v->modelindex);
if (!model || model->type == mod_alias) if (!model || model->type == mod_alias)
{ {
angles[PITCH] *= -1; angles[PITCH] *= r_meshpitch.value;
avelocity[PITCH] *= -1; avelocity[PITCH] *= r_meshpitch.value;
} }
} }
@ -2321,8 +2321,8 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
model = world->Get_CModel(world, ed->v->modelindex); model = world->Get_CModel(world, ed->v->modelindex);
if (!model || model->type == mod_alias) if (!model || model->type == mod_alias)
{ {
qangles[PITCH] *= -1; qangles[PITCH] *= r_meshpitch.value;
qavelocity[PITCH] *= -1; qavelocity[PITCH] *= r_meshpitch.value;
} }
} }
@ -2737,6 +2737,8 @@ static void QDECL World_ODE_Start(world_t *world)
memset(ctx, 0, sizeof(*ctx)); memset(ctx, 0, sizeof(*ctx));
world->rbe = &ctx->pub; world->rbe = &ctx->pub;
r_meshpitch.value = pCvar_GetFloat("physics_ode_quadtree_depth");
VectorAvg(world->worldmodel->mins, world->worldmodel->maxs, center); VectorAvg(world->worldmodel->mins, world->worldmodel->maxs, center);
VectorSubtract(world->worldmodel->maxs, center, extents); VectorSubtract(world->worldmodel->maxs, center, extents);
ctx->dworld = dWorldCreate(); ctx->dworld = dWorldCreate();

View file

@ -5531,6 +5531,8 @@ void COM_Init (void)
Cvar_Register (&com_highlightcolor, "Internationalisation"); Cvar_Register (&com_highlightcolor, "Internationalisation");
com_parseutf8.ival = 1; com_parseutf8.ival = 1;
Cvar_Register (&r_meshpitch, "Gamecode");
TranslateInit(); TranslateInit();
COM_BiDi_Setup(); COM_BiDi_Setup();

View file

@ -1083,10 +1083,37 @@ static void FS_RebuildFSHash_Update(const char *fname)
searchpath_t *search; searchpath_t *search;
int depth = 0; int depth = 0;
fsbucket_t *old; fsbucket_t *old;
void *filehandle = NULL;
if (com_fschanged) if (com_fschanged)
return; return;
if (!filehandle && com_purepaths)
{ //go for the pure paths first.
for (search = com_purepaths; search; search = search->nextpure)
{
if (search->handle->FindFile(search->handle, &loc, fname, NULL))
{
filehandle = loc.fhandle;
break;
}
depth++;
}
}
if (!filehandle && fs_puremode < 2)
{
for (search = com_searchpaths ; search ; search = search->next)
{
if (search->handle->FindFile(search->handle, &loc, fname, NULL))
{
filehandle = loc.fhandle;
break;
}
depth++;
}
}
COM_WorkerFullSync(); COM_WorkerFullSync();
if (!Sys_LockMutex(fs_thread_mutex)) if (!Sys_LockMutex(fs_thread_mutex))
return; //amg! return; //amg!
@ -1098,30 +1125,8 @@ static void FS_RebuildFSHash_Update(const char *fname)
fs_hash_files--; fs_hash_files--;
} }
if (com_purepaths) if (filehandle)
{ //go for the pure paths first. FS_AddFileHash(depth, fname, NULL, filehandle);
for (search = com_purepaths; search; search = search->nextpure)
{
if (search->handle->FindFile(search->handle, &loc, fname, NULL))
{
FS_AddFileHash(depth, fname, NULL, loc.fhandle);
return;
}
depth++;
}
}
if (fs_puremode < 2)
{
for (search = com_searchpaths ; search ; search = search->next)
{
if (search->handle->FindFile(search->handle, &loc, fname, NULL))
{
FS_AddFileHash(depth, fname, NULL, loc.fhandle);
return;
}
depth++;
}
}
Sys_UnlockMutex(fs_thread_mutex); Sys_UnlockMutex(fs_thread_mutex);
} }

View file

@ -533,8 +533,10 @@ static void IPLog_Identify_f(void)
Con_Printf("%s: ip address of %s is not known\n", Cmd_Argv(0), cl.players[slot].name); Con_Printf("%s: ip address of %s is not known\n", Cmd_Argv(0), cl.players[slot].name);
else else
{ {
NET_StringToAdr(cl.players[slot].ip, 0, &adr); if (NET_StringToAdrMasked(cl.players[slot].ip, false, &adr, &mask))
IPLog_Identify(&adr, NULL, "Identity of %s [%s]", cl.players[slot].name, cl.players[slot].ip); IPLog_Identify(&adr, &mask, "Identity of %s [%s]", cl.players[slot].name, cl.players[slot].ip);
else
Con_Printf("ip address of %s not known, cannot identify\n", cl.players[slot].name);
} }
} }
#endif #endif

View file

@ -291,7 +291,7 @@ void VectorVectors(const vec3_t forward, vec3_t right, vec3_t up)
CrossProduct(right, forward, up); CrossProduct(right, forward, up);
} }
void QDECL VectorAngles(float *forward, float *up, float *result) //up may be NULL void QDECL VectorAngles(float *forward, float *up, float *result, qboolean meshpitch) //up may be NULL
{ {
float yaw, pitch, roll; float yaw, pitch, roll;
@ -331,9 +331,11 @@ void QDECL VectorAngles(float *forward, float *up, float *result) //up may be NU
roll = 0; roll = 0;
} }
pitch *= -180 / M_PI; pitch *= 180 / M_PI;
yaw *= 180 / M_PI; yaw *= 180 / M_PI;
roll *= 180 / M_PI; roll *= 180 / M_PI;
if (meshpitch)
pitch *= r_meshpitch.value;
if (pitch < 0) if (pitch < 0)
pitch += 360; pitch += 360;
if (yaw < 0) if (yaw < 0)
@ -381,11 +383,6 @@ void QDECL AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3
} }
} }
void QDECL vectoangles(vec3_t fwd, vec3_t ang)
{
VectorAngles(fwd, NULL, ang);
}
int VectorCompare (const vec3_t v1, const vec3_t v2) int VectorCompare (const vec3_t v1, const vec3_t v2)
{ {
int i; int i;

View file

@ -114,8 +114,6 @@ typedef struct {
float m[4][4]; float m[4][4];
} matrix4x4_t; } matrix4x4_t;
//vec_t _DotProduct (vec3_t v1, vec3_t v2); //vec_t _DotProduct (vec3_t v1, vec3_t v2);
//void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out); //void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out);
//void _VectorCopy (vec3_t in, vec3_t out); //void _VectorCopy (vec3_t in, vec3_t out);
@ -123,7 +121,7 @@ typedef struct {
void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs); void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs);
float anglemod (float a); float anglemod (float a);
void QDECL AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up); void QDECL AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
void QDECL VectorAngles (float *forward, float *up, float *angles); //up may be NULL void QDECL VectorAngles (float *forward, float *up, float *angles, qboolean meshpitch); //up may be NULL
void VARGS BOPS_Error (void); void VARGS BOPS_Error (void);
int VARGS BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *plane); int VARGS BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *plane);
void ClearBounds (vec3_t mins, vec3_t maxs); void ClearBounds (vec3_t mins, vec3_t maxs);

View file

@ -138,8 +138,7 @@ static qboolean PM_PortalTransform(world_t *w, int portalnum, vec3_t org, vec3_t
VectorCopy(pmove.angles, G_VECTOR(OFS_PARM1)); VectorCopy(pmove.angles, G_VECTOR(OFS_PARM1));
AngleVectors(pmove.angles, w->g.v_forward, w->g.v_right, w->g.v_up); AngleVectors(pmove.angles, w->g.v_forward, w->g.v_right, w->g.v_up);
PR_ExecuteProgram (w->progs, portal->xv->camera_transform); PR_ExecuteProgram (w->progs, portal->xv->camera_transform);
VectorAngles(w->g.v_forward, w->g.v_up, newang); VectorAngles(w->g.v_forward, w->g.v_up, newang, false);
newang[0] *= -1;
} }
*w->g.self = oself; *w->g.self = oself;
@ -1155,11 +1154,11 @@ void PM_NudgePosition (void)
if (PM_TestPlayerPosition (pmove.origin, false)) if (PM_TestPlayerPosition (pmove.origin, false))
return; return;
for (z=0 ; z<sizeof(sign)/sizeof(sign[0]) ; z++) for (z=0 ; z<countof(sign) ; z++)
{ {
for (x=0 ; x<sizeof(sign)/sizeof(sign[0]) ; x++) for (x=0 ; x<countof(sign) ; x++)
{ {
for (y=0 ; y<sizeof(sign)/sizeof(sign[0]) ; y++) for (y=0 ; y<countof(sign) ; y++)
{ {
pmove.origin[0] = base[0] + (sign[x] * 1.0/8); pmove.origin[0] = base[0] + (sign[x] * 1.0/8);
pmove.origin[1] = base[1] + (sign[y] * 1.0/8); pmove.origin[1] = base[1] + (sign[y] * 1.0/8);

View file

@ -5043,7 +5043,7 @@ void QCBUILTIN PF_vectoangles (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
else else
up = NULL; up = NULL;
VectorAngles(value1, up, G_VECTOR(OFS_RETURN)); VectorAngles(value1, up, G_VECTOR(OFS_RETURN), true);
} }
//vector normalize(vector) //vector normalize(vector)
@ -5077,9 +5077,9 @@ void QCBUILTIN PF_rotatevectorsbyangles (pubprogfuncs_t *prinst, struct globalva
float *ang = G_VECTOR(OFS_PARM0); float *ang = G_VECTOR(OFS_PARM0);
vec3_t src[3], trans[3], res[3]; vec3_t src[3], trans[3], res[3];
ang[0]*=-1; ang[0]*=r_meshpitch.value;
AngleVectors(ang, trans[0], trans[1], trans[2]); AngleVectors(ang, trans[0], trans[1], trans[2]);
ang[0]*=-1; ang[0]*=r_meshpitch.value;
VectorInverse(trans[1]); VectorInverse(trans[1]);
VectorCopy(w->g.v_forward, src[0]); VectorCopy(w->g.v_forward, src[0]);

View file

@ -577,7 +577,7 @@ typedef struct
void (QDECL *ReleaseCollisionMesh) (wedict_t *ed); void (QDECL *ReleaseCollisionMesh) (wedict_t *ed);
void (QDECL *LinkEdict)(world_t *w, wedict_t *ed, qboolean touchtriggers); void (QDECL *LinkEdict)(world_t *w, wedict_t *ed, qboolean touchtriggers);
void (QDECL *VectorAngles)(float *forward, float *up, float *result); void (QDECL *VectorAngles)(float *forward, float *up, float *result, qboolean meshpitch);
void (QDECL *AngleVectors)(const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up); void (QDECL *AngleVectors)(const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
} rbeplugfuncs_t; } rbeplugfuncs_t;
#define RBEPLUGFUNCS_VERSION 1 #define RBEPLUGFUNCS_VERSION 1

View file

@ -261,7 +261,7 @@ void World_RBE_Start(world_t *world);
void World_RBE_Shutdown(world_t *world); void World_RBE_Shutdown(world_t *world);
void World_ClearWorld (world_t *w); void World_ClearWorld (world_t *w, qboolean relink);
// called after the world model has been loaded, before linking any entities // called after the world model has been loaded, before linking any entities
void World_UnlinkEdict (wedict_t *ent); void World_UnlinkEdict (wedict_t *ent);

View file

@ -363,7 +363,7 @@ skinid_t Mod_ReadSkinFile(const char *skinname, const char *skintext)
Q_strncpyz(skin->mappings[skin->nummappings].surface, com_token, sizeof(skin->mappings[skin->nummappings].surface)); Q_strncpyz(skin->mappings[skin->nummappings].surface, com_token, sizeof(skin->mappings[skin->nummappings].surface));
skintext = COM_ParseToken(skintext+1, NULL); skintext = COM_ParseToken(skintext+1, NULL);
Q_strncpyz(shadername, com_token, sizeof(shadername)); Q_strncpyz(shadername, com_token, sizeof(shadername));
skin->mappings[skin->nummappings].shader = R_RegisterSkin(shadername, skin->skinname); skin->mappings[skin->nummappings].shader = R_RegisterCustom (shadername, 0, Shader_DefaultSkin, NULL);
R_BuildDefaultTexnums(NULL, skin->mappings[skin->nummappings].shader); R_BuildDefaultTexnums(NULL, skin->mappings[skin->nummappings].shader);
skin->mappings[skin->nummappings].texnums = *skin->mappings[skin->nummappings].shader->defaulttextures; skin->mappings[skin->nummappings].texnums = *skin->mappings[skin->nummappings].shader->defaulttextures;
skin->nummappings++; skin->nummappings++;

View file

@ -4591,7 +4591,7 @@ void GLBE_DrawMesh_List(shader_t *shader, int nummeshes, mesh_t **meshlist, vbo_
void GLBE_DrawMesh_Single(shader_t *shader, mesh_t *mesh, vbo_t *vbo, unsigned int beflags) void GLBE_DrawMesh_Single(shader_t *shader, mesh_t *mesh, vbo_t *vbo, unsigned int beflags)
{ {
shader->next = NULL; shader->next = NULL;
BE_DrawMesh_List(shader, 1, &mesh, NULL, NULL, beflags); GLBE_DrawMesh_List(shader, 1, &mesh, NULL, NULL, beflags);
} }
void GLBE_SubmitBatch(batch_t *batch) void GLBE_SubmitBatch(batch_t *batch)

View file

@ -635,6 +635,9 @@ void Mod_Purge(enum mod_purge_e ptype)
{ {
unused = mod->datasequence != mod_datasequence; unused = mod->datasequence != mod_datasequence;
if (mod->loadstate == MLS_NOTLOADED)
continue;
//this model isn't active any more. //this model isn't active any more.
if (unused || ptype != MP_MAPCHANGED) if (unused || ptype != MP_MAPCHANGED)
{ {
@ -904,7 +907,7 @@ model_t *Mod_FindName (const char *name)
// search the currently loaded models // search the currently loaded models
// //
for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++) for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
if (!strcmp (mod->name, name) ) if (!strcmp (mod->publicname, name) )
break; break;
if (i == mod_numknown) if (i == mod_numknown)
@ -912,16 +915,17 @@ model_t *Mod_FindName (const char *name)
#ifdef LOADERTHREAD #ifdef LOADERTHREAD
Sys_LockMutex(com_resourcemutex); Sys_LockMutex(com_resourcemutex);
for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++) for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
if (!strcmp (mod->name, name) ) if (!strcmp (mod->publicname, name) )
break; break;
if (i == mod_numknown) if (i == mod_numknown)
{ {
#endif #endif
if (mod_numknown == MAX_MOD_KNOWN) if (mod_numknown == MAX_MOD_KNOWN)
Sys_Error ("mod_numknown == MAX_MOD_KNOWN"); Sys_Error ("mod_numknown == MAX_MOD_KNOWN");
if (strlen(name) >= sizeof(mod->name)) if (strlen(name) >= sizeof(mod->publicname))
Sys_Error ("model name is too long: %s", name); Sys_Error ("model name is too long: %s", name);
memset(mod, 0, sizeof(model_t)); //clear the old model as the renderers use the same globals memset(mod, 0, sizeof(model_t)); //clear the old model as the renderers use the same globals
Q_strncpyz (mod->publicname, name, sizeof(mod->publicname));
Q_strncpyz (mod->name, name, sizeof(mod->name)); Q_strncpyz (mod->name, name, sizeof(mod->name));
mod->loadstate = MLS_NOTLOADED; mod->loadstate = MLS_NOTLOADED;
mod_numknown++; mod_numknown++;
@ -1143,7 +1147,7 @@ static void Mod_LoadModelWorker (void *ctx, void *data, size_t a, size_t b)
size_t filesize; size_t filesize;
char ext[8]; char ext[8];
if (!*mod->name) if (!*mod->publicname)
{ {
mod->type = mod_dummy; mod->type = mod_dummy;
mod->mins[0] = -16; mod->mins[0] = -16;
@ -1172,43 +1176,43 @@ static void Mod_LoadModelWorker (void *ctx, void *data, size_t a, size_t b)
// load the file // load the file
// //
// set necessary engine flags for loading purposes // set necessary engine flags for loading purposes
if (!strcmp(mod->name, "progs/player.mdl")) if (!strcmp(mod->publicname, "progs/player.mdl"))
mod->engineflags |= MDLF_PLAYER | MDLF_DOCRC; mod->engineflags |= MDLF_PLAYER | MDLF_DOCRC;
else if (!strcmp(mod->name, "progs/flame.mdl") || else if (!strcmp(mod->publicname, "progs/flame.mdl") ||
!strcmp(mod->name, "progs/flame2.mdl") || !strcmp(mod->publicname, "progs/flame2.mdl") ||
!strcmp(mod->name, "models/flame1.mdl") || //hexen2 small standing flame !strcmp(mod->publicname, "models/flame1.mdl") || //hexen2 small standing flame
!strcmp(mod->name, "models/flame2.mdl") || //hexen2 large standing flame !strcmp(mod->publicname, "models/flame2.mdl") || //hexen2 large standing flame
!strcmp(mod->name, "models/cflmtrch.mdl")) //hexen2 wall torch !strcmp(mod->publicname, "models/cflmtrch.mdl")) //hexen2 wall torch
mod->engineflags |= MDLF_FLAME; mod->engineflags |= MDLF_FLAME;
else if (!strcmp(mod->name, "progs/bolt.mdl") || else if (!strcmp(mod->publicname, "progs/bolt.mdl") ||
!strcmp(mod->name, "progs/bolt2.mdl") || !strcmp(mod->publicname, "progs/bolt2.mdl") ||
!strcmp(mod->name, "progs/bolt3.mdl") || !strcmp(mod->publicname, "progs/bolt3.mdl") ||
!strcmp(mod->name, "progs/beam.mdl") || !strcmp(mod->publicname, "progs/beam.mdl") ||
!strcmp(mod->name, "models/stsunsf2.mdl") || !strcmp(mod->publicname, "models/stsunsf2.mdl") ||
!strcmp(mod->name, "models/stsunsf1.mdl") || !strcmp(mod->publicname, "models/stsunsf1.mdl") ||
!strcmp(mod->name, "models/stice.mdl")) !strcmp(mod->publicname, "models/stice.mdl"))
mod->engineflags |= MDLF_BOLT; mod->engineflags |= MDLF_BOLT;
else if (!strcmp(mod->name, "progs/backpack.mdl")) else if (!strcmp(mod->publicname, "progs/backpack.mdl"))
mod->engineflags |= MDLF_NOTREPLACEMENTS; mod->engineflags |= MDLF_NOTREPLACEMENTS;
else if (!strcmp(mod->name, "progs/eyes.mdl")) else if (!strcmp(mod->publicname, "progs/eyes.mdl"))
mod->engineflags |= MDLF_NOTREPLACEMENTS|MDLF_DOCRC; mod->engineflags |= MDLF_NOTREPLACEMENTS|MDLF_DOCRC;
/*handle ezquake-originated cheats that would feck over fte users if fte didn't support /*handle ezquake-originated cheats that would feck over fte users if fte didn't support
these are the conditions required for r_fb_models on non-players*/ these are the conditions required for r_fb_models on non-players*/
mod->engineflags |= MDLF_EZQUAKEFBCHEAT; mod->engineflags |= MDLF_EZQUAKEFBCHEAT;
if ((mod->engineflags & MDLF_DOCRC) || if ((mod->engineflags & MDLF_DOCRC) ||
!strcmp(mod->name, "progs/backpack.mdl") || !strcmp(mod->publicname, "progs/backpack.mdl") ||
!strcmp(mod->name, "progs/gib1.mdl") || !strcmp(mod->publicname, "progs/gib1.mdl") ||
!strcmp(mod->name, "progs/gib2.mdl") || !strcmp(mod->publicname, "progs/gib2.mdl") ||
!strcmp(mod->name, "progs/gib3.mdl") || !strcmp(mod->publicname, "progs/gib3.mdl") ||
!strcmp(mod->name, "progs/h_player.mdl") || !strcmp(mod->publicname, "progs/h_player.mdl") ||
!strncmp(mod->name, "progs/v_", 8)) !strncmp(mod->publicname, "progs/v_", 8))
mod->engineflags &= ~MDLF_EZQUAKEFBCHEAT; mod->engineflags &= ~MDLF_EZQUAKEFBCHEAT;
mod->engineflags |= MDLF_RECALCULATERAIN; mod->engineflags |= MDLF_RECALCULATERAIN;
// get string used for replacement tokens // get string used for replacement tokens
COM_FileExtension(mod->name, ext, sizeof(ext)); COM_FileExtension(mod->publicname, ext, sizeof(ext));
if (!Q_strcasecmp(ext, "spr") || !Q_strcasecmp(ext, "sp2")) if (!Q_strcasecmp(ext, "spr") || !Q_strcasecmp(ext, "sp2"))
replstr = ""; // sprite replstr = ""; // sprite
#ifdef DSPMODELS #ifdef DSPMODELS
@ -1225,7 +1229,7 @@ static void Mod_LoadModelWorker (void *ctx, void *data, size_t a, size_t b)
if (!gl_load24bit.value) if (!gl_load24bit.value)
replstr = ""; replstr = "";
COM_StripExtension(mod->name, mdlbase, sizeof(mdlbase)); COM_StripExtension(mod->publicname, mdlbase, sizeof(mdlbase));
while (replstr) while (replstr)
{ {
@ -1238,12 +1242,17 @@ static void Mod_LoadModelWorker (void *ctx, void *data, size_t a, size_t b)
Q_snprintfz(altname, sizeof(altname), "%s.%s", mdlbase, token); Q_snprintfz(altname, sizeof(altname), "%s.%s", mdlbase, token);
TRACE(("Mod_LoadModel: Trying to load (replacement) model \"%s\"\n", altname)); TRACE(("Mod_LoadModel: Trying to load (replacement) model \"%s\"\n", altname));
buf = (unsigned *)COM_LoadFile (altname, 5, &filesize); buf = (unsigned *)COM_LoadFile (altname, 5, &filesize);
if (buf)
Q_strncpyz(mod->name, altname, sizeof(mod->name));
} }
else else
{ {
TRACE(("Mod_LoadModel: Trying to load model \"%s\"\n", mod->name)); TRACE(("Mod_LoadModel: Trying to load model \"%s\"\n", mod->publicname));
buf = (unsigned *)COM_LoadFile (mod->name, 5, &filesize); buf = (unsigned *)COM_LoadFile (mod->publicname, 5, &filesize);
if (!buf) if (buf)
Q_strncpyz(mod->name, mod->publicname, sizeof(mod->name));
else if (!buf)
{ {
#ifdef DSPMODELS #ifdef DSPMODELS
if (doomsprite) // special case needed for doom sprites if (doomsprite) // special case needed for doom sprites
@ -5119,14 +5128,12 @@ TRACE(("LoadBrushModel %i\n", __LINE__));
char name[MAX_QPATH]; char name[MAX_QPATH];
model_t *nextmod; model_t *nextmod;
// if (isnotmap) Q_snprintfz (name, sizeof(name), "*%i:%s", i+1, mod->publicname);
Q_snprintfz (name, sizeof(name), "*%i:%s", i+1, mod->name);
// else//FIXME: this can bug out if we've still got one of these queued from a previous map change
// Q_snprintfz (name, sizeof(name), "*%i", i+1);
nextmod = Mod_FindName (name); nextmod = Mod_FindName (name);
*nextmod = *submod; *nextmod = *submod;
nextmod->submodelof = mod; nextmod->submodelof = mod;
Q_strncpyz(nextmod->name, name, sizeof(nextmod->name)); Q_strncpyz(nextmod->publicname, name, sizeof(nextmod->publicname));
Q_snprintfz (nextmod->name, sizeof(nextmod->publicname), "*%i:%s", i+1, mod->publicname);
submod = nextmod; submod = nextmod;
memset(&submod->memgroup, 0, sizeof(submod->memgroup)); memset(&submod->memgroup, 0, sizeof(submod->memgroup));
} }
@ -5162,6 +5169,26 @@ SPRITES
//========================================================= //=========================================================
#ifdef SERVERONLY
//dedicated servers should not need to load sprites.
//dedicated servers need *.bsp to be loaded for setmodel to get the correct size (or all model types with sv_gameplayfix_setmodelrealbox).
//otherwise other model types(actually: names) only need to be loaded once reflection or hitmodel is used.
//for sprites we don't really care ever.
qboolean QDECL Mod_LoadSpriteModel (model_t *mod, void *buffer, size_t fsize)
{
mod->type = mod_dummy;
return true;
}
qboolean QDECL Mod_LoadSprite2Model (model_t *mod, void *buffer, size_t fsize)
{
return Mod_LoadSpriteModel(mod, buffer, fsize);
}
void Mod_LoadDoomSprite (model_t *mod)
{
mod->type = mod_dummy;
}
#else
//we need to override the rtlight shader for sprites so they get lit properly ignoring n+s+t dirs //we need to override the rtlight shader for sprites so they get lit properly ignoring n+s+t dirs
//so lets split the shader into parts to avoid too many dupes //so lets split the shader into parts to avoid too many dupes
#define SPRITE_SHADER_MAIN \ #define SPRITE_SHADER_MAIN \
@ -5211,7 +5238,7 @@ void Mod_LoadSpriteFrameShader(model_t *spr, int frame, int subframe, mspritefra
else else
Q_snprintfz(name, sizeof(name), "%s_%i_%i.tga", spr->name, frame, subframe); Q_snprintfz(name, sizeof(name), "%s_%i_%i.tga", spr->name, frame, subframe);
if (mod_litsprites_force.ival || strchr(spr->name, '!')) if (mod_litsprites_force.ival || strchr(spr->publicname, '!'))
litsprite = true; litsprite = true;
#ifndef NOLEGACY #ifndef NOLEGACY
else else
@ -5231,7 +5258,7 @@ void Mod_LoadSpriteFrameShader(model_t *spr, int frame, int subframe, mspritefra
}; };
for (i = 0; forcelitsprites[i]; i++) for (i = 0; forcelitsprites[i]; i++)
if (!strcmp(spr->name, forcelitsprites[i])) if (!strcmp(spr->publicname, forcelitsprites[i]))
{ {
litsprite = true; litsprite = true;
break; break;
@ -5867,6 +5894,8 @@ void Mod_LoadDoomSprite (model_t *mod)
} }
#endif #endif
#endif
//============================================================================= //=============================================================================
/* /*

View file

@ -855,7 +855,8 @@ enum
}; };
typedef struct model_s typedef struct model_s
{ {
char name[MAX_QPATH]; char name[MAX_QPATH]; //actual name on disk
char publicname[MAX_QPATH]; //name that the gamecode etc sees
int datasequence; int datasequence;
int loadstate;//MLS_ int loadstate;//MLS_
qboolean tainted; qboolean tainted;

View file

@ -1179,7 +1179,7 @@ void R_SaveRTLights_f(void)
continue; continue;
if (!light->radius) if (!light->radius)
continue; continue;
VectorAngles(light->axis[0], light->axis[2], ang); VectorAngles(light->axis[0], light->axis[2], ang, false);
VFS_PUTS(f, va( VFS_PUTS(f, va(
"%s%f %f %f " "%s%f %f %f "
"%f %f %f %f " "%f %f %f %f "
@ -1194,7 +1194,7 @@ void R_SaveRTLights_f(void)
light->radius, light->color[0], light->color[1], light->color[2], light->radius, light->color[0], light->color[1], light->color[2],
light->style-1, light->style-1,
light->cubemapname, light->corona, light->cubemapname, light->corona,
anglemod(-ang[0]), ang[1], ang[2], ang[0], ang[1], ang[2],
light->coronascale, light->lightcolourscales[0], light->lightcolourscales[1], light->lightcolourscales[2], light->flags&(LFLAG_NORMALMODE|LFLAG_REALTIMEMODE|LFLAG_CREPUSCULAR), light->coronascale, light->lightcolourscales[0], light->lightcolourscales[1], light->lightcolourscales[2], light->flags&(LFLAG_NORMALMODE|LFLAG_REALTIMEMODE|LFLAG_CREPUSCULAR),
light->rotation[0],light->rotation[1],light->rotation[2],light->fov light->rotation[0],light->rotation[1],light->rotation[2],light->fov
)); ));

View file

@ -1229,8 +1229,7 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2],
//now determine the stuff the backend will use. //now determine the stuff the backend will use.
memcpy(r_refdef.m_view, vmat, sizeof(float)*16); memcpy(r_refdef.m_view, vmat, sizeof(float)*16);
VectorAngles(vpn, vup, r_refdef.viewangles); VectorAngles(vpn, vup, r_refdef.viewangles, false);
r_refdef.viewangles[0] *= -1;
VectorCopy(r_refdef.vieworg, r_origin); VectorCopy(r_refdef.vieworg, r_origin);
//determine r_refdef.flipcull & SHADER_CULL_FLIP based upon whether right is right or not. //determine r_refdef.flipcull & SHADER_CULL_FLIP based upon whether right is right or not.

View file

@ -2261,6 +2261,8 @@ static void Shader_DiffuseMap(shader_t *shader, shaderpass_t *pass, char **ptr)
char *token = Shader_ParseString(ptr); char *token = Shader_ParseString(ptr);
unsigned int flags = Shader_SetImageFlags (shader, NULL, &token); unsigned int flags = Shader_SetImageFlags (shader, NULL, &token);
shader->defaulttextures->base = Shader_FindImage(token, flags); shader->defaulttextures->base = Shader_FindImage(token, flags);
Q_strncpyz(shader->defaulttextures->mapname, token, sizeof(shader->defaulttextures->mapname));
} }
static void Shader_SpecularMap(shader_t *shader, shaderpass_t *pass, char **ptr) static void Shader_SpecularMap(shader_t *shader, shaderpass_t *pass, char **ptr)
{ {
@ -2272,7 +2274,7 @@ static void Shader_NormalMap(shader_t *shader, shaderpass_t *pass, char **ptr)
{ {
char *token = Shader_ParseString(ptr); char *token = Shader_ParseString(ptr);
unsigned int flags = Shader_SetImageFlags (shader, NULL, &token); unsigned int flags = Shader_SetImageFlags (shader, NULL, &token);
shader->defaulttextures->bump = Shader_FindImage(token, flags); shader->defaulttextures->bump = Shader_FindImage(token, flags|IF_TRYBUMP);
} }
static void Shader_FullbrightMap(shader_t *shader, shaderpass_t *pass, char **ptr) static void Shader_FullbrightMap(shader_t *shader, shaderpass_t *pass, char **ptr)
{ {
@ -3889,6 +3891,7 @@ void Shader_FixupProgPasses(shader_t *shader, shaderpass_t *pass)
parsestate.droppass = true; parsestate.droppass = true;
break; break;
} }
pass[pass->numMergedPasses].flags |= SHADER_PASS_NOCOLORARRAY;
pass[pass->numMergedPasses].flags &= ~SHADER_PASS_DEPTHCMP; pass[pass->numMergedPasses].flags &= ~SHADER_PASS_DEPTHCMP;
if (defaulttgen[i].gen == T_GEN_SHADOWMAP) if (defaulttgen[i].gen == T_GEN_SHADOWMAP)
pass[pass->numMergedPasses].flags |= SHADER_PASS_DEPTHCMP; pass[pass->numMergedPasses].flags |= SHADER_PASS_DEPTHCMP;

View file

@ -652,6 +652,7 @@ cin_t *R_ShaderGetCinematic(shader_t *s);
cin_t *R_ShaderFindCinematic(const char *name); cin_t *R_ShaderFindCinematic(const char *name);
shader_t *R_ShaderFind(const char *name); //does NOT increase the shader refcount. shader_t *R_ShaderFind(const char *name); //does NOT increase the shader refcount.
void Shader_DefaultSkin(const char *shortname, shader_t *s, const void *args);
void Shader_DefaultSkinShell(const char *shortname, shader_t *s, const void *args); void Shader_DefaultSkinShell(const char *shortname, shader_t *s, const void *args);
void Shader_DefaultBSPLM(const char *shortname, shader_t *s, const void *args); void Shader_DefaultBSPLM(const char *shortname, shader_t *s, const void *args);
void Shader_DefaultBSPQ1(const char *shortname, shader_t *s, const void *args); void Shader_DefaultBSPQ1(const char *shortname, shader_t *s, const void *args);

View file

@ -53,7 +53,7 @@ static void PPAPI_UnlockBuffer(soundcardinfo_t *sc, void *buffer)
static void *PPAPI_LockBuffer(soundcardinfo_t *sc, unsigned int *sampidx) static void *PPAPI_LockBuffer(soundcardinfo_t *sc, unsigned int *sampidx)
{ {
*sampidx = 0; *sampidx = 0;
return sc->sn.buffer; return sc->sn.buffer;
} }
static void PPAPI_Submit(soundcardinfo_t *sc, int start, int end) static void PPAPI_Submit(soundcardinfo_t *sc, int start, int end)

View file

@ -2450,6 +2450,7 @@ void PR_CleanUpStatements16(progfuncs_t *progfuncs, dstatement16_t *st, pbool he
if (!st[i].c) if (!st[i].c)
st[i].c = OFS_RETURN; st[i].c = OFS_RETURN;
//sanitise inputs
if (st[i].a >= numglob) if (st[i].a >= numglob)
if (st[i].op != OP_GOTO) if (st[i].op != OP_GOTO)
st[i].op = ~0; st[i].op = ~0;
@ -2477,6 +2478,7 @@ void PR_CleanUpStatements32(progfuncs_t *progfuncs, dstatement32_t *st, pbool he
if (!st[i].c) if (!st[i].c)
st[i].c = OFS_RETURN; st[i].c = OFS_RETURN;
//sanitise inputs
if (st[i].a >= numglob) if (st[i].a >= numglob)
if (st[i].op != OP_GOTO) if (st[i].op != OP_GOTO)
st[i].op = ~0; st[i].op = ~0;
@ -2484,10 +2486,10 @@ void PR_CleanUpStatements32(progfuncs_t *progfuncs, dstatement32_t *st, pbool he
if (st[i].op != OP_IFNOT_I && st[i].op != OP_IF_I && if (st[i].op != OP_IFNOT_I && st[i].op != OP_IF_I &&
st[i].op != OP_IFNOT_F && st[i].op != OP_IF_F && st[i].op != OP_IFNOT_F && st[i].op != OP_IF_F &&
st[i].op != OP_IFNOT_S && st[i].op != OP_IF_S && st[i].op != OP_IFNOT_S && st[i].op != OP_IF_S &&
st[i].op != OP_BOUNDCHECK) st[i].op != OP_BOUNDCHECK && st[i].op != OP_CASE)
st[i].op = ~0; st[i].op = ~0;
if (st[i].c >= numglob) if (st[i].c >= numglob)
if (st[i].op != OP_BOUNDCHECK) if (st[i].op != OP_BOUNDCHECK && st[i].op != OP_CASERANGE)
st[i].op = ~0; st[i].op = ~0;
} }
} }
@ -3300,12 +3302,6 @@ retry:
((int *)glob)[d16->ofs] = PR_FindFunc(&progfuncs->funcs, s, PR_ANY); ((int *)glob)[d16->ofs] = PR_FindFunc(&progfuncs->funcs, s, PR_ANY);
if (!((int *)glob)[d16->ofs]) if (!((int *)glob)[d16->ofs])
printf("Warning: Runtime-linked function %s could not be found (loading %s)\n", s, filename); printf("Warning: Runtime-linked function %s could not be found (loading %s)\n", s, filename);
/*
d2 = ED_FindGlobalOfsFromProgs(progfuncs, s, 0, ev_function);
if (!d2)
Sys_Error("Runtime-linked function %s was not found in primary progs (loading %s)", s, filename);
((int *)glob)[d16->ofs] = (*(func_t *)&pr_progstate[0].globals[*d2]);
*/
s+=strlen(s)+1; s+=strlen(s)+1;
} }
} }
@ -3320,18 +3316,17 @@ retry:
for (i = 0; i < pr_progs->numbodylessfuncs; i++) for (i = 0; i < pr_progs->numbodylessfuncs; i++)
{ {
d32 = ED_FindGlobal32(progfuncs, s); d32 = ED_FindGlobal32(progfuncs, s);
d2 = ED_FindGlobalOfsFromProgs(progfuncs, s, 0, ev_function);
if (!d2)
printf("Warning: Runtime-linked function %s was not found in existing progs", s);
if (!d32) if (!d32)
{ {
printf("Couldn't find def for \"%s\"", s); printf("\"%s\" requires the external function \"%s\", but the definition was stripped\n", filename, s);
PRHunkFree(progfuncs, hmark); PRHunkFree(progfuncs, hmark);
pr_progs=NULL; pr_progs=NULL;
return false; return false;
} }
((int *)glob)[d32->ofs] = (*(func_t *)&pr_progstate[0].globals[*d2]);
((int *)glob)[d32->ofs] = PR_FindFunc(&progfuncs->funcs, s, PR_ANY);
if (!((int *)glob)[d32->ofs])
printf("Warning: Runtime-linked function %s could not be found (loading %s)\n", s, filename);
s+=strlen(s)+1; s+=strlen(s)+1;
} }
} }

View file

@ -349,14 +349,14 @@ typedef struct QCC_type_s
unsigned int size; unsigned int size;
pbool typedefed:1; pbool typedefed:1;
pbool vargs:1; pbool vargs:1; //function has vargs
pbool vargcount:1; pbool vargcount:1; //function has special varg count param
char *name; char *name;
char *aname; char *aname;
struct accessor_s *accessors; struct accessor_s *accessors;
struct QCC_type_s *ptrto; //this points to a type that is a pointer back to this type. yeah, weird. struct QCC_type_s *ptrto; //(cache) this points to a type that is a pointer back to this type. yeah, weird.
} QCC_type_t; } QCC_type_t;
int typecmp(QCC_type_t *a, QCC_type_t *b); int typecmp(QCC_type_t *a, QCC_type_t *b);
int typecmp_lax(QCC_type_t *a, QCC_type_t *b); int typecmp_lax(QCC_type_t *a, QCC_type_t *b);

View file

@ -1521,7 +1521,7 @@ const QCC_eval_t *QCC_SRef_EvalConst(QCC_sref_t ref)
if (ref.sym && ref.sym->initialized && ref.sym->constant) if (ref.sym && ref.sym->initialized && ref.sym->constant)
{ {
ref.sym->referenced = true; ref.sym->referenced = true;
return &ref.sym->symboldata[/*ref.sym->ofs +*/ ref.ofs]; return &ref.sym->symboldata[ref.ofs];
} }
return NULL; return NULL;
} }
@ -1707,6 +1707,7 @@ static void QCC_ClobberDef(QCC_def_t *def)
if (statements[st].c.sym == a) if (statements[st].c.sym == a)
statements[st].c.sym = a->generatedfor; statements[st].c.sym = a->generatedfor;
} }
tmp.sym->refcount = a->symbolheader->refcount;
a->symbolheader = tmp.sym; a->symbolheader = tmp.sym;
from = QCC_MakeSRefForce(a->generatedfor, 0, a->type); from = QCC_MakeSRefForce(a->generatedfor, 0, a->type);
a->generatedfor = tmp.sym; a->generatedfor = tmp.sym;
@ -1714,7 +1715,6 @@ static void QCC_ClobberDef(QCC_def_t *def)
a->temp = tmp.sym->temp; a->temp = tmp.sym->temp;
a->ofs = tmp.sym->ofs; a->ofs = tmp.sym->ofs;
tmp.sym = a; tmp.sym = a;
tmp.sym->refcount = a->refcount;
if (a->type->type==ev_variant || a->type->type == ev_vector) if (a->type->type==ev_variant || a->type->type == ev_vector)
QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_V], from, tmp, NULL, STFL_PRESERVEB)); QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_STORE_V], from, tmp, NULL, STFL_PRESERVEB));
else else
@ -5236,7 +5236,10 @@ QCC_sref_t QCC_PR_GenerateFunctionCallRef (QCC_sref_t newself, QCC_sref_t func,
if (callconvention == OP_CALL1H) if (callconvention == OP_CALL1H)
{ {
for (i = 0; i < parm && i < 2; i++) for (i = 0; i < parm && i < 2; i++)
{
args[i].ref.sym->referenced=true;
QCC_FreeTemp(args[i].ref); QCC_FreeTemp(args[i].ref);
}
} }
//we dont need to lock the local containing the function index because its thrown away after the call anyway //we dont need to lock the local containing the function index because its thrown away after the call anyway
@ -6099,7 +6102,7 @@ QCC_sref_t QCC_MakeIntConst(int value)
continue; continue;
typechecks++; typechecks++;
if ( cn->symboldata[cn->ofs]._int == value ) if ( cn->symboldata[0]._int == value )
{ {
return QCC_MakeSRefForce(cn, 0, type_integer); return QCC_MakeSRefForce(cn, 0, type_integer);
} }
@ -6526,7 +6529,7 @@ void QCC_PR_EmitClassFromFunction(QCC_def_t *scope, QCC_type_t *basetype)
pr.local_tail = &pr.local_head; pr.local_tail = &pr.local_head;
scope->initialized = true; scope->initialized = true;
scope->symboldata[scope->ofs].function = pr_scope - functions; scope->symboldata[0].function = pr_scope - functions;
ed = QCC_PR_GetSRef(type_entity, "self", NULL, true, 0, false); ed = QCC_PR_GetSRef(type_entity, "self", NULL, true, 0, false);
@ -6760,7 +6763,8 @@ QCC_ref_t *QCC_PR_ParseRefArrayPointer (QCC_ref_t *retbuf, QCC_ref_t *r, pbool a
if (idx.cast) if (idx.cast)
allowarray = arraysize>0 || allowarray = arraysize>0 ||
(t->type == ev_vector) || (t->type == ev_vector) ||
(t->type == ev_field && t->aux_type->type == ev_vector); (t->type == ev_field && t->aux_type->type == ev_vector) ||
(t->type == ev_union && t->num_parms == 1 && !t->params[0].paramname && !arraysize);
else if (!idx.cast) else if (!idx.cast)
{ {
allowarray = arraysize>0 || allowarray = arraysize>0 ||
@ -6792,6 +6796,11 @@ QCC_ref_t *QCC_PR_ParseRefArrayPointer (QCC_ref_t *retbuf, QCC_ref_t *r, pbool a
/*if its a pointer that got dereferenced, follow the type*/ /*if its a pointer that got dereferenced, follow the type*/
if (!idx.cast && t->type == ev_pointer && !arraysize) if (!idx.cast && t->type == ev_pointer && !arraysize)
t = t->aux_type; t = t->aux_type;
else if (idx.cast && (t->type == ev_union && t->num_parms == 1 && !t->params[0].paramname && !arraysize))
{
arraysize = t->params[0].arraysize;
t = t->params[0].type;
}
if (!idx.cast && r->cast->type == ev_pointer && !arraysize) if (!idx.cast && r->cast->type == ev_pointer && !arraysize)
{ {
@ -7757,6 +7766,7 @@ QCC_ref_t *QCC_PR_RefTerm (QCC_ref_t *retbuf, unsigned int exprflags)
QCC_PR_Expect ("]"); QCC_PR_Expect ("]");
QCC_PR_Expect(")"); QCC_PR_Expect(")");
QCC_PR_Expect("{"); QCC_PR_Expect("{");
QCC_PR_Expect ("}"); QCC_PR_Expect ("}");
return array; return array;
}*/ }*/
@ -10213,6 +10223,7 @@ void QCC_PR_ParseStatement (void)
conditional = 1; conditional = 1;
e = QCC_PR_Expression (TOP_PRIORITY, 0); e = QCC_PR_Expression (TOP_PRIORITY, 0);
conditional = 0; conditional = 0;
e.sym->referenced = true;
//expands //expands
@ -11512,7 +11523,7 @@ void QCC_Marshal_Locals(int firststatement, int laststatement)
{ {
//FIXME: check for uninitialised locals. //FIXME: check for uninitialised locals.
//these matter when the function goes recursive (and locals marshalling counts as recursive every time). //these matter when the function goes recursive (and locals marshalling counts as recursive every time).
if (local->symboldata[local->ofs]._int) if (local->symboldata[0]._int)
{ {
QCC_PR_Note(ERR_INTERNAL, local->filen, local->s_line, "Marshaling non-const initialised %s", local->name); QCC_PR_Note(ERR_INTERNAL, local->filen, local->s_line, "Marshaling non-const initialised %s", local->name);
error = true; error = true;
@ -11712,7 +11723,7 @@ void QCC_WriteAsmFunction(QCC_function_t *sc, unsigned int firststatement, QCC_d
} }
#endif #endif
QCC_function_t *QCC_PR_GenerateBuiltinFunction (QCC_def_t *def, int builtinnum) QCC_function_t *QCC_PR_GenerateBuiltinFunction (QCC_def_t *def, int builtinnum, char *builtinname)
{ {
QCC_function_t *func; QCC_function_t *func;
if (numfunctions >= MAX_FUNCTIONS) if (numfunctions >= MAX_FUNCTIONS)
@ -11721,7 +11732,13 @@ QCC_function_t *QCC_PR_GenerateBuiltinFunction (QCC_def_t *def, int builtinnum)
func->filen = s_filen; func->filen = s_filen;
func->s_filed = s_filed; func->s_filed = s_filed;
func->line = def->s_line; //FIXME func->line = def->s_line; //FIXME
func->name = def->name; if (builtinname==def->name)
func->name = builtinname;
else
{
func->name = qccHunkAlloc(strlen(builtinname)+1);
strcpy(func->name, builtinname);
}
func->builtin = builtinnum; func->builtin = builtinnum;
func->code = -1; func->code = -1;
func->type = def->type; func->type = def->type;
@ -11806,7 +11823,7 @@ QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_def_t *def, QCC_type_t *typ
binum = pr_immediate._int; binum = pr_immediate._int;
else else
QCC_PR_ParseError (ERR_BADBUILTINIMMEDIATE, "Bad builtin immediate"); QCC_PR_ParseError (ERR_BADBUILTINIMMEDIATE, "Bad builtin immediate");
f = QCC_PR_GenerateBuiltinFunction(def, binum); f = QCC_PR_GenerateBuiltinFunction(def, binum, def->name);
QCC_PR_Lex (); QCC_PR_Lex ();
return f; return f;
@ -11817,7 +11834,7 @@ QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_def_t *def, QCC_type_t *typ
|| pr_immediate_type != type_float || pr_immediate_type != type_float
|| pr_immediate._float != (int)pr_immediate._float) || pr_immediate._float != (int)pr_immediate._float)
QCC_PR_ParseError (ERR_BADBUILTINIMMEDIATE, "Bad builtin immediate"); QCC_PR_ParseError (ERR_BADBUILTINIMMEDIATE, "Bad builtin immediate");
f = QCC_PR_GenerateBuiltinFunction(def, (int)-pr_immediate._float); f = QCC_PR_GenerateBuiltinFunction(def, (int)-pr_immediate._float, def->name);
QCC_PR_Lex (); QCC_PR_Lex ();
QCC_PR_Expect(";"); QCC_PR_Expect(";");
@ -11949,6 +11966,7 @@ QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_def_t *def, QCC_type_t *typ
{ {
a.sym = &def_parms[u]; a.sym = &def_parms[u];
a.ofs = 0; a.ofs = 0;
QCC_ForceUnFreeDef(a.sym);
} }
a.cast = type_vector; a.cast = type_vector;
QCC_UnFreeTemp(va_list); QCC_UnFreeTemp(va_list);
@ -12210,7 +12228,7 @@ QCC_def_t *QCC_PR_EmitArrayGetVector(QCC_sref_t array)
pr_source_line = pr_token_line_last = pr_scope->line = array.sym->s_line; //thankfully these functions are emitted after compilation. pr_source_line = pr_token_line_last = pr_scope->line = array.sym->s_line; //thankfully these functions are emitted after compilation.
pr_scope->filen = array.sym->filen; pr_scope->filen = array.sym->filen;
pr_scope->s_filed = array.sym->s_filed; pr_scope->s_filed = array.sym->s_filed;
func->symboldata[func->ofs]._int = pr_scope - functions; func->symboldata[0]._int = pr_scope - functions;
index = QCC_PR_GetSRef(type_float, "index___", pr_scope, true, 0, false); index = QCC_PR_GetSRef(type_float, "index___", pr_scope, true, 0, false);
index.sym->referenced = true; index.sym->referenced = true;
@ -12271,7 +12289,7 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *scope, QCC_def_t *arraydef, char *ar
index = QCC_PR_GetSRef(type_float, "__indexg", pr_scope, true, 0, false); index = QCC_PR_GetSRef(type_float, "__indexg", pr_scope, true, 0, false);
scope->initialized = true; scope->initialized = true;
scope->symboldata[scope->ofs]._int = pr_scope - functions; scope->symboldata[0]._int = pr_scope - functions;
/* if (fasttrackpossible) /* if (fasttrackpossible)
{ {
@ -12457,7 +12475,7 @@ void QCC_PR_EmitArraySetFunction(QCC_def_t *scope, QCC_def_t *arraydef, char *ar
value = QCC_PR_GetSRef(thearray.cast, "value___", pr_scope, true, 0, false); value = QCC_PR_GetSRef(thearray.cast, "value___", pr_scope, true, 0, false);
scope->initialized = true; scope->initialized = true;
scope->symboldata[scope->ofs]._int = pr_scope - functions; scope->symboldata[0]._int = pr_scope - functions;
if (fasttrackpossible.cast) if (fasttrackpossible.cast)
{ {
@ -12620,7 +12638,10 @@ QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_function_t *scope,
} }
if (flags & GDF_USED) if (flags & GDF_USED)
{
def->used = true; def->used = true;
def->referenced = true;
}
def->ofs = ofs + ((a>0)?type->size*a:0); def->ofs = ofs + ((a>0)?type->size*a:0);
if (!first) if (!first)
@ -13066,7 +13087,7 @@ QCC_def_t *QCC_PR_DummyFieldDef(QCC_type_t *type, QCC_function_t *scope, int arr
def = QCC_PR_GetDef(ftype, newname, scope, true, 0, saved); def = QCC_PR_GetDef(ftype, newname, scope, true, 0, saved);
if (parttype->type == ev_function) if (parttype->type == ev_function)
def->initialized = true; def->initialized = true;
def->symboldata[def->ofs]._int = *fieldofs; def->symboldata[0]._int = *fieldofs;
*fieldofs += parttype->size; *fieldofs += parttype->size;
} }
else else
@ -13191,9 +13212,7 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t d
{ {
if (functions[i].code == -1 && functions[i].builtin == binum) if (functions[i].code == -1 && functions[i].builtin == binum)
{ {
if (!*functions[i].name) if (!*functions[i].name || !strcmp(functions[i].name, defname))
functions[i].name = (char*)defname;
if (!strcmp(functions[i].name, defname))
{ {
tmp = QCC_MakeIntConst(i); tmp = QCC_MakeIntConst(i);
break; break;
@ -13204,7 +13223,7 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t d
} }
if (!tmp.cast) if (!tmp.cast)
f = QCC_PR_GenerateBuiltinFunction(def.sym, binum); f = QCC_PR_GenerateBuiltinFunction(def.sym, binum, *fname?fname:def.sym->name);
else else
f = NULL; f = NULL;
} }
@ -13313,7 +13332,7 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t d
QCC_PR_Lex(); QCC_PR_Lex();
QCC_PR_Expect(")"); QCC_PR_Expect(")");
} }
else if ((type->type == ev_struct || type->type == ev_union) && QCC_PR_CheckToken("{")) else if ((type->type == ev_struct && QCC_PR_CheckToken("{")) || (type->type == ev_union && ((type->num_parms == 1 && !type->params->paramname) || QCC_PR_CheckToken("{"))))
{ {
//structs go recursive //structs go recursive
unsigned int partnum; unsigned int partnum;
@ -13332,12 +13351,55 @@ void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t d
QCC_PR_ParseInitializerType((type)->params[partnum].arraysize, basedef, def, flags); QCC_PR_ParseInitializerType((type)->params[partnum].arraysize, basedef, def, flags);
if (isunion || !QCC_PR_CheckToken(",")) if (isunion || !QCC_PR_CheckToken(","))
{ {
if (isunion && (type->num_parms == 1 && !type->params->paramname))
break;
QCC_PR_Expect("}"); QCC_PR_Expect("}");
break; break;
} }
} }
return; return;
} }
else if (type->type == ev_pointer && QCC_PR_CheckToken("{"))
{
//generate a temp array
QCC_ref_t buf, buf2;
tmp.sym = QCC_PR_DummyDef(type->aux_type, NULL, pr_scope, 0, NULL, 0, false, GDF_STRIP|(pr_scope?GDF_STATIC:0));
tmp.ofs = 0;
tmp.cast = tmp.sym->type;
tmp.sym->refcount+=1;
//fill up the array
do
{
//expand the array
int newsize = tmp.sym->arraysize * tmp.cast->size;
if (tmp.sym->symbolsize < newsize)
{
void *newdata;
newsize += 64 * tmp.cast->size;
newdata = qccHunkAlloc (newsize * sizeof(float));
memcpy(newdata, tmp.sym->symboldata, tmp.sym->symbolsize*sizeof(float));
tmp.sym->symboldata = newdata;
tmp.sym->symbolsize = newsize;
}
tmp.sym->arraysize++;
//generate the def...
QCC_PR_DummyDef(tmp.cast, NULL, pr_scope, 0, tmp.sym, tmp.ofs, false, GDF_STRIP|(pr_scope?GDF_STATIC:0));
//and fill it in.
QCC_PR_ParseInitializerType(0, tmp.sym, tmp, flags);
tmp.ofs += type->aux_type->size;
} while(QCC_PR_CheckToken(","));
QCC_PR_Expect("}");
//drop the size back down to something sane
tmp.sym->symbolsize = tmp.ofs*sizeof(float);
//grab the address of it.
tmp.ofs = 0;
tmp = QCC_RefToDef(QCC_PR_GenerateAddressOf(&buf, QCC_DefToRef(&buf2, tmp)), true);
}
else else
{ {
tmp = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA); tmp = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA);
@ -13652,24 +13714,40 @@ void QCC_PR_ParseDefs (char *classname)
if (QCC_PR_CheckKeyword (keyword_typedef, "typedef")) if (QCC_PR_CheckKeyword (keyword_typedef, "typedef"))
{ {
type = QCC_PR_ParseType(true, false); type = QCC_PR_ParseType(false, false);
if (!type) if (!type)
{ {
QCC_PR_ParseError(ERR_NOTANAME, "typedef found unexpected tokens"); QCC_PR_ParseError(ERR_NOTANAME, "typedef found unexpected tokens");
} }
if (QCC_PR_CheckToken("*")) do
{ {
QCC_type_t *ptr; char *name;
ptr = QCC_PR_NewType(QCC_CopyString(pr_token)+strings, ev_pointer, false); if (QCC_PR_CheckToken(";"))
ptr->aux_type = type; return;
type = ptr;
} if (QCC_PR_CheckToken("*"))
else type = QCC_PointerTypeTo(type);
{
type->name = QCC_CopyString(pr_token)+strings; name = QCC_PR_ParseName();
}
type->typedefed = true; if (QCC_PR_CheckToken("["))
QCC_PR_Lex(); {
struct QCC_typeparam_s *param = qccHunkAlloc(sizeof(*param));
param->type = type;
param->arraysize = QCC_PR_IntConstExpr();
type = QCC_PR_NewType(name, ev_union, true);
type->params = param;
type->num_parms = 1;
type->size = param->type->size * param->arraysize;
QCC_PR_Expect("]");
}
else
{
type = QCC_PR_DuplicateType(type, false);
type->name = name;
type->typedefed = true;
}
} while(QCC_PR_CheckToken(","));
QCC_PR_Expect(";"); QCC_PR_Expect(";");
return; return;
} }
@ -13745,7 +13823,7 @@ void QCC_PR_ParseDefs (char *classname)
def = QCC_PR_GetDef(type_float, name, NULL, true, 0, true); def = QCC_PR_GetDef(type_float, name, NULL, true, 0, true);
if (QCC_PR_CheckToken("=")) if (QCC_PR_CheckToken("="))
{ {
def->symboldata[def->ofs]._float = pr_immediate._float; def->symboldata[0]._float = pr_immediate._float;
QCC_PR_Lex(); QCC_PR_Lex();
} }
} }
@ -13755,11 +13833,11 @@ void QCC_PR_ParseDefs (char *classname)
if (QCC_PR_CheckToken("=")) if (QCC_PR_CheckToken("="))
{ {
QCC_PR_Expect("["); QCC_PR_Expect("[");
def->symboldata[def->ofs].vector[0] = pr_immediate._float; def->symboldata[0].vector[0] = pr_immediate._float;
QCC_PR_Lex(); QCC_PR_Lex();
def->symboldata[def->ofs].vector[1] = pr_immediate._float; def->symboldata[0].vector[1] = pr_immediate._float;
QCC_PR_Lex(); QCC_PR_Lex();
def->symboldata[def->ofs].vector[2] = pr_immediate._float; def->symboldata[0].vector[2] = pr_immediate._float;
QCC_PR_Lex(); QCC_PR_Lex();
QCC_PR_Expect("]"); QCC_PR_Expect("]");
} }
@ -13814,12 +13892,12 @@ void QCC_PR_ParseDefs (char *classname)
def->initialized = 1; def->initialized = 1;
for (u = 0; u < def->type->size*(def->arraysize?def->arraysize:1); u++) //make arrays of fields work. for (u = 0; u < def->type->size*(def->arraysize?def->arraysize:1); u++) //make arrays of fields work.
{ {
if (*(int *)&def->symboldata[def->ofs+u]) if (*(int *)&def->symboldata[u])
{ {
QCC_PR_ParseWarning(0, "Field def already has a value:"); QCC_PR_ParseWarning(0, "Field def already has a value:");
QCC_PR_ParsePrintDef(0, def); QCC_PR_ParsePrintDef(0, def);
} }
*(int *)&def->symboldata[def->ofs+u] = pr.size_fields+u; *(int *)&def->symboldata[u] = pr.size_fields+u;
} }
pr.size_fields += u; pr.size_fields += u;
@ -13936,7 +14014,7 @@ void QCC_PR_ParseDefs (char *classname)
def->initialized = 1; def->initialized = 1;
def->isstatic = isstatic; def->isstatic = isstatic;
def->symboldata[def->ofs].function = numfunctions; def->symboldata[0].function = numfunctions;
f->def = def; f->def = def;
// if (pr_dumpasm) // if (pr_dumpasm)
// PR_PrintFunction (def); // PR_PrintFunction (def);
@ -14162,7 +14240,7 @@ void QCC_PR_ParseDefs (char *classname)
{ {
d = d->next; d = d->next;
d->initialized = 1; //fake function d->initialized = 1; //fake function
d->symboldata[d->ofs].function = 0; d->symboldata[0].function = 0;
} }
continue; continue;
@ -14277,11 +14355,11 @@ void QCC_PR_ParseDefs (char *classname)
def->initialized = true; def->initialized = true;
//if the field already has a value, don't allocate new field space for it as that would confuse things. //if the field already has a value, don't allocate new field space for it as that would confuse things.
//otherwise allocate new space. //otherwise allocate new space.
if (def->symboldata[def->ofs]._int) if (def->symboldata[0]._int)
{ {
for (i = 0; i < type->size*(arraysize?arraysize:1); i++) //make arrays of fields work. for (i = 0; i < type->size*(arraysize?arraysize:1); i++) //make arrays of fields work.
{ {
if (def->symboldata[def->ofs+i]._int != i + def->symboldata[def->ofs]._int) if (def->symboldata[i]._int != i + def->symboldata[0]._int)
{ {
QCC_PR_ParseWarning(0, "Inconsistant field def:"); QCC_PR_ParseWarning(0, "Inconsistant field def:");
QCC_PR_ParsePrintDef(0, def); QCC_PR_ParsePrintDef(0, def);
@ -14293,12 +14371,12 @@ void QCC_PR_ParseDefs (char *classname)
{ {
for (i = 0; i < type->size*(arraysize?arraysize:1); i++) //make arrays of fields work. for (i = 0; i < type->size*(arraysize?arraysize:1); i++) //make arrays of fields work.
{ {
if (def->symboldata[def->ofs+i]._int) if (def->symboldata[i]._int)
{ {
QCC_PR_ParseWarning(0, "Field def already has a value:"); QCC_PR_ParseWarning(0, "Field def already has a value:");
QCC_PR_ParsePrintDef(0, def); QCC_PR_ParsePrintDef(0, def);
} }
def->symboldata[def->ofs+i]._int = pr.size_fields+i; def->symboldata[i]._int = pr.size_fields+i;
} }
pr.size_fields += i; pr.size_fields += i;

View file

@ -4428,6 +4428,7 @@ QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype)
{ {
do do
{ {
pbool foundinout;
if (ftype->num_parms>=MAX_PARMS+MAX_EXTRA_PARMS) if (ftype->num_parms>=MAX_PARMS+MAX_EXTRA_PARMS)
QCC_PR_ParseError(ERR_TOOMANYTOTALPARAMETERS, "Too many parameters. Sorry. (limit is %i)\n", MAX_PARMS+MAX_EXTRA_PARMS); QCC_PR_ParseError(ERR_TOOMANYTOTALPARAMETERS, "Too many parameters. Sorry. (limit is %i)\n", MAX_PARMS+MAX_EXTRA_PARMS);
@ -4437,16 +4438,30 @@ QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype)
break; break;
} }
if (QCC_PR_CheckKeyword(keyword_inout, "inout")) foundinout = false;
paramlist[numparms].out = true; paramlist[numparms].optional = false;
else if (QCC_PR_CheckKeyword(keyword_inout, "out")) paramlist[numparms].out = false;
paramlist[numparms].out = 2; //not really supported, but parsed for readability.
else if (QCC_PR_CheckKeyword(keyword_inout, "in"))
paramlist[numparms].out = false;
else
paramlist[numparms].out = false; //the default
paramlist[numparms].optional = QCC_PR_CheckKeyword(keyword_optional, "optional"); while(1)
{
if (!paramlist[numparms].optional && QCC_PR_CheckKeyword(keyword_optional, "optional"))
paramlist[numparms].optional = true;
if (!foundinout && QCC_PR_CheckKeyword(keyword_inout, "inout"))
{
paramlist[numparms].out = true;
foundinout = true;
}
if (!foundinout && QCC_PR_CheckKeyword(keyword_inout, "out"))
{
paramlist[numparms].out = 2; //not really supported, but parsed for readability.
foundinout = true;
}
if (!foundinout && QCC_PR_CheckKeyword(keyword_inout, "in"))
{
paramlist[numparms].out = false;
foundinout = true;
}
}
paramlist[numparms].defltvalue.cast = NULL; paramlist[numparms].defltvalue.cast = NULL;
paramlist[numparms].ofs = 0; paramlist[numparms].ofs = 0;
@ -4455,6 +4470,9 @@ QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype)
if (!paramlist[numparms].type) if (!paramlist[numparms].type)
QCC_PR_ParseError(0, "Expected type\n"); QCC_PR_ParseError(0, "Expected type\n");
while (QCC_PR_CheckToken("*"))
paramlist[numparms].type = QCC_PointerTypeTo(paramlist[numparms].type);
if (paramlist[numparms].type->type == ev_void) if (paramlist[numparms].type->type == ev_void)
break; //float(void) has no actual args break; //float(void) has no actual args
@ -4474,6 +4492,12 @@ QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype)
strcpy(paramlist[numparms].paramname, name); strcpy(paramlist[numparms].paramname, name);
if (definenames) if (definenames)
strcpy (pr_parm_names[numparms], name); strcpy (pr_parm_names[numparms], name);
if (QCC_PR_CheckToken("["))
{
QCC_PR_ParseError(0, "Array arguments are not supported\n");
QCC_PR_Expect("]");
}
} }
else if (definenames) else if (definenames)
strcpy (pr_parm_names[numparms], ""); strcpy (pr_parm_names[numparms], "");

View file

@ -99,6 +99,7 @@ void AddSourceFile(const char *parentsrc, const char *filename);
#define SCI_BACKTAB 2328 #define SCI_BACKTAB 2328
#define SCI_SEARCHANCHOR 2366 #define SCI_SEARCHANCHOR 2366
#define SCI_SEARCHNEXT 2367 #define SCI_SEARCHNEXT 2367
#define SCI_SEARCHPREV 2368
#define SCI_STYLEGETFORE 2481 #define SCI_STYLEGETFORE 2481
#define SCI_STYLEGETBACK 2482 #define SCI_STYLEGETBACK 2482
#define SCI_STYLEGETBOLD 2483 #define SCI_STYLEGETBOLD 2483
@ -748,12 +749,12 @@ void GUI_DialogPrint(char *title, char *text)
MessageBox(mainwindow, text, title, 0); MessageBox(mainwindow, text, title, 0);
} }
static void FindNextScintilla(editor_t *editor, char *findtext) static void FindNextScintilla(editor_t *editor, char *findtext, pbool next)
{ {
int pos = SendMessage(editor->editpane, SCI_GETCURRENTPOS, 0, 0); int pos = SendMessage(editor->editpane, SCI_GETCURRENTPOS, 0, 0);
Edit_SetSel(editor->editpane, pos+1, pos+1); Edit_SetSel(editor->editpane, pos+1, pos+1);
SendMessage(editor->editpane, SCI_SEARCHANCHOR, 0, 0); SendMessage(editor->editpane, SCI_SEARCHANCHOR, 0, 0);
if (SendMessage(editor->editpane, SCI_SEARCHNEXT, 0, (LPARAM)findtext) != -1) if (SendMessage(editor->editpane, next?SCI_SEARCHNEXT:SCI_SEARCHPREV, 0, (LPARAM)findtext) != -1)
Edit_ScrollCaret(editor->editpane); //make sure its focused Edit_ScrollCaret(editor->editpane); //make sure its focused
else else
{ {
@ -807,33 +808,6 @@ LRESULT CALLBACK MySubclassWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
break; break;
} }
} }
if (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN)
{
switch(wParam)
{
case VK_F3:
{
char buffer[128];
GetWindowText(search_name, buffer, sizeof(buffer));
if (*buffer == 0)
SetFocus(search_name);
else
{
editor_t *editor;
for (editor = editors; editor; editor = editor->next)
{
if (editor->editpane == hWnd)
break;
}
if (editor && editor->scintilla)
{
FindNextScintilla(editor, buffer);
}
}
}
return 0;
}
}
if (uMsg == WM_LBUTTONDBLCLK && hWnd == outputbox) if (uMsg == WM_LBUTTONDBLCLK && hWnd == outputbox)
{ {
CHARRANGE selrange = {0}; CHARRANGE selrange = {0};
@ -1303,6 +1277,8 @@ enum {
IDM_SAVE, IDM_SAVE,
IDM_RECOMPILE, IDM_RECOMPILE,
IDM_FIND, IDM_FIND,
IDM_FINDNEXT,
IDM_FINDPREV,
IDM_QUIT, IDM_QUIT,
IDM_UNDO, IDM_UNDO,
IDM_REDO, IDM_REDO,
@ -1726,6 +1702,29 @@ void EditorMenu(editor_t *editor, WPARAM wParam)
case IDM_FIND: case IDM_FIND:
SetFocus(search_name); SetFocus(search_name);
break; break;
case IDM_FINDNEXT:
case IDM_FINDPREV:
{
char buffer[128];
GetWindowText(search_name, buffer, sizeof(buffer));
if (*buffer != 0)
{
HWND ew = (HWND)SendMessage(mdibox, WM_MDIGETACTIVE, 0, 0);
editor_t *editor;
for (editor = editors; editor; editor = editor->next)
{
if (editor->window == ew)
break;
}
if (editor && editor->scintilla)
{
FindNextScintilla(editor, buffer, LOWORD(wParam) == IDM_FINDNEXT);
SetFocus(editor->window);
SetFocus(editor->editpane);
}
}
}
break;
case IDM_GREP: case IDM_GREP:
{ {
char buffer[1024]; char buffer[1024];
@ -5253,33 +5252,11 @@ static LRESULT CALLBACK SearchComboSubClass(HWND hWnd,UINT message,
{ {
case WM_KEYDOWN: case WM_KEYDOWN:
switch (wParam) switch (wParam)
{ {
case VK_RETURN: case VK_RETURN:
PostMessage(mainwindow, WM_COMMAND, 0x4404, (LPARAM)search_gotodef); PostMessage(mainwindow, WM_COMMAND, 0x4404, (LPARAM)search_gotodef);
return true; return true;
case VK_F3: }
{
char buffer[128];
GetWindowText(search_name, buffer, sizeof(buffer));
if (*buffer != 0)
{
HWND ew = (HWND)SendMessage(mdibox, WM_MDIGETACTIVE, 0, 0);
editor_t *editor;
for (editor = editors; editor; editor = editor->next)
{
if (editor->window == ew)
break;
}
if (editor && editor->scintilla)
{
FindNextScintilla(editor, buffer);
SetFocus(editor->window);
SetFocus(editor->editpane);
}
}
}
}
break;
} }
return CallWindowProc(combosubclassproc, hWnd, message, wParam, lParam); return CallWindowProc(combosubclassproc, hWnd, message, wParam, lParam);
} }
@ -6488,6 +6465,8 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
{FCONTROL|FVIRTKEY, 'F', IDM_FIND}, {FCONTROL|FVIRTKEY, 'F', IDM_FIND},
{FCONTROL|FVIRTKEY, 'G', IDM_GREP}, {FCONTROL|FVIRTKEY, 'G', IDM_GREP},
{FCONTROL|FVIRTKEY, 'R', IDM_RECOMPILE}, {FCONTROL|FVIRTKEY, 'R', IDM_RECOMPILE},
{FVIRTKEY, VK_F3, IDM_FINDNEXT},
{FSHIFT|FVIRTKEY, VK_F3, IDM_FINDPREV},
// {FVIRTKEY, VK_F4, IDM_NEXTERROR}, // {FVIRTKEY, VK_F4, IDM_NEXTERROR},
{FVIRTKEY, VK_F5, IDM_DEBUG_RUN}, {FVIRTKEY, VK_F5, IDM_DEBUG_RUN},
{FVIRTKEY, VK_F6, IDM_OUTPUT_WINDOW}, {FVIRTKEY, VK_F6, IDM_OUTPUT_WINDOW},

View file

@ -923,11 +923,14 @@ void QCC_DetermineNeededSymbols(QCC_def_t *endsyssym)
for (; sym; sym = sym->next) for (; sym; sym = sym->next)
{ {
if (sym->constant && sym->type->type == ev_field && !opt_stripunusedfields) if (sym->constant && sym->type->type == ev_field && !opt_stripunusedfields)
{
sym->symbolheader->used = true; //fields should always be present, annoyingly enough, as they're often used to silence map warnings. sym->symbolheader->used = true; //fields should always be present, annoyingly enough, as they're often used to silence map warnings.
//FIXME: we want to strip these. fte/dp extensions.qc have a LOT of fields that could be stripped. //FIXME: we want to strip these. fte/dp extensions.qc have a LOT of fields that could be stripped.
sym->referenced = true; //FIXME
}
else if (sym->constant && sym->type->type == ev_function) else if (sym->constant && sym->type->type == ev_function)
{ //non-builtins must be present, because of spawn functions and other entrypoints. { //non-builtins must be present, because of spawn functions and other entrypoints.
unsigned int fnum = sym->symboldata[sym->ofs]._int; unsigned int fnum = sym->symboldata[0]._int;
if (fnum < numfunctions && functions[fnum].code == -1) if (fnum < numfunctions && functions[fnum].code == -1)
sym->symbolheader->used = true; sym->symbolheader->used = true;
} }
@ -1074,8 +1077,8 @@ void QCC_FinaliseDef(QCC_def_t *def)
else else
memset(qcc_pr_globals+def->ofs, 0, def->symbolsize*sizeof(float)); memset(qcc_pr_globals+def->ofs, 0, def->symbolsize*sizeof(float));
} }
def->symboldata = qcc_pr_globals; def->symboldata = qcc_pr_globals + def->ofs;
def->symbolsize = numpr_globals; def->symbolsize = numpr_globals - def->ofs;
#ifdef DEBUG_DUMP #ifdef DEBUG_DUMP
if (!def->referenced) if (!def->referenced)
@ -1187,7 +1190,7 @@ static void QCC_GenerateFieldDefs(QCC_def_t *def, char *fieldname, int ofs, QCC_
dd = &qcc_globals[numglobaldefs]; dd = &qcc_globals[numglobaldefs];
numglobaldefs++; numglobaldefs++;
dd->type = ev_field; dd->type = ev_field;
dd->ofs = ofs; dd->ofs = def->ofs+ofs;
dd->s_name = sname; dd->s_name = sname;
} }
@ -1519,13 +1522,13 @@ pbool QCC_WriteData (int crc)
if (def->symbolheader->read && !def->symbolheader->written && !def->symbolheader->referenced) if (def->symbolheader->read && !def->symbolheader->written && !def->symbolheader->referenced)
{ {
char typestr[256]; char typestr[256];
QCC_sref_t sr = {def, def->ofs, def->type}; QCC_sref_t sr = {def, 0, def->type};
QCC_PR_Warning(WARN_READNOTWRITTEN, def->filen, def->s_line, "%s %s = %s read, but not writte.", TypeName(def->type, typestr, sizeof(typestr)), def->name, QCC_VarAtOffset(sr)); QCC_PR_Warning(WARN_READNOTWRITTEN, def->filen, def->s_line, "%s %s = %s read, but not writte.", TypeName(def->type, typestr, sizeof(typestr)), def->name, QCC_VarAtOffset(sr));
} }
if (def->symbolheader->written && !def->symbolheader->read && !def->symbolheader->referenced) if (def->symbolheader->written && !def->symbolheader->read && !def->symbolheader->referenced)
{ {
char typestr[256]; char typestr[256];
QCC_sref_t sr = {def, def->ofs, def->type}; QCC_sref_t sr = {def, 0, def->type};
QCC_PR_Warning(WARN_WRITTENNOTREAD, def->filen, def->s_line, "%s %s = %s written, but not read.", TypeName(def->type, typestr, sizeof(typestr)), def->name, QCC_VarAtOffset(sr)); QCC_PR_Warning(WARN_WRITTENNOTREAD, def->filen, def->s_line, "%s %s = %s written, but not read.", TypeName(def->type, typestr, sizeof(typestr)), def->name, QCC_VarAtOffset(sr));
} }
#endif #endif
@ -1553,7 +1556,7 @@ pbool QCC_WriteData (int crc)
if (def->symbolheader->used) if (def->symbolheader->used)
{ {
char typestr[256]; char typestr[256];
QCC_sref_t sr = {def, def->ofs, def->type}; QCC_sref_t sr = {def, 0, def->type};
QCC_PR_Warning(WARN_NOTREFERENCED, def->filen, def->s_line, "%s %s = %s used, but not referenced.", TypeName(def->type, typestr, sizeof(typestr)), def->name, QCC_VarAtOffset(sr)); QCC_PR_Warning(WARN_NOTREFERENCED, def->filen, def->s_line, "%s %s = %s used, but not referenced.", TypeName(def->type, typestr, sizeof(typestr)), def->name, QCC_VarAtOffset(sr));
} }
/*if (opt_unreferenced && def->type->type != ev_field) /*if (opt_unreferenced && def->type->type != ev_field)
@ -1585,7 +1588,7 @@ pbool QCC_WriteData (int crc)
if (def->type->type == ev_function) if (def->type->type == ev_function)
{ {
if (opt_function_names && def->initialized && functions[def->symboldata[def->ofs].function].code<0) if (opt_function_names && def->initialized && functions[def->symboldata[0].function].code<0)
{ {
optres_function_names++; optres_function_names++;
def->name = ""; def->name = "";
@ -1610,7 +1613,7 @@ pbool QCC_WriteData (int crc)
} }
else if (def->type->type == ev_field && def->constant && (!def->scope || def->isstatic || def->initialized)) else if (def->type->type == ev_field && def->constant && (!def->scope || def->isstatic || def->initialized))
{ {
QCC_GenerateFieldDefs(def, def->name, def->ofs, def->type->aux_type); QCC_GenerateFieldDefs(def, def->name, 0, def->type->aux_type);
continue; continue;
} }
else if ((def->scope||def->constant) && (def->type->type != ev_string || (strncmp(def->name, "dotranslate_", 12) && opt_constant_names_strings))) else if ((def->scope||def->constant) && (def->type->type != ev_string || (strncmp(def->name, "dotranslate_", 12) && opt_constant_names_strings)))
@ -1664,17 +1667,17 @@ pbool QCC_WriteData (int crc)
#ifdef DEBUG_DUMP #ifdef DEBUG_DUMP
if ((dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)) == ev_string) if ((dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)) == ev_string)
printf("code: %s:%i: %s%s%s %s@%i = \"%s\"\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, ((unsigned)def->symboldata[def->ofs].string>=(unsigned)strofs)?"???":(strings + def->symboldata[def->ofs].string)); printf("code: %s:%i: %s%s%s %s@%i = \"%s\"\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, ((unsigned)def->symboldata[0].string>=(unsigned)strofs)?"???":(strings + def->symboldata[0].string));
else if ((dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)) == ev_float) else if ((dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)) == ev_float)
printf("code: %s:%i: %s%s%s %s@%i = %g\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, def->symboldata[def->ofs]._float); printf("code: %s:%i: %s%s%s %s@%i = %g\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, def->symboldata[0]._float);
else if ((dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)) == ev_integer) else if ((dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)) == ev_integer)
printf("code: %s:%i: %s%s%s %s@%i = %i\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, def->symboldata[def->ofs]._int); printf("code: %s:%i: %s%s%s %s@%i = %i\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, def->symboldata[0]._int);
else if ((dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)) == ev_vector) else if ((dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)) == ev_vector)
printf("code: %s:%i: %s%s%s %s@%i = '%g %g %g'\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, def->symboldata[def->ofs].vector[0], def->symboldata[def->ofs].vector[1], def->symboldata[def->ofs].vector[2]); printf("code: %s:%i: %s%s%s %s@%i = '%g %g %g'\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, def->symboldata[0].vector[0], def->symboldata[0].vector[1], def->symboldata[0].vector[2]);
else if ((dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)) == ev_function) else if ((dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)) == ev_function)
printf("code: %s:%i: %s%s%s %s@%i = %i(%s)\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, def->symboldata[def->ofs].function, def->symboldata[def->ofs].function >= numfunctions?"???":functions[def->symboldata[def->ofs].function].name); printf("code: %s:%i: %s%s%s %s@%i = %i(%s)\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, def->symboldata[0].function, def->symboldata[0].function >= numfunctions?"???":functions[def->symboldata[0].function].name);
else if ((dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)) == ev_field) else if ((dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)) == ev_field)
printf("code: %s:%i: %s%s%s %s@%i = @%i\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, def->symboldata[def->ofs]._int); printf("code: %s:%i: %s%s%s %s@%i = @%i\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs, def->symboldata[0]._int);
else else
printf("code: %s:%i: %s%s%s %s@%i\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs); printf("code: %s:%i: %s%s%s %s@%i\n", def->filen, def->s_line, dd->type&DEF_SAVEGLOBAL?"save ":"nosave ", dd->type&DEF_SHARED?"shared ":"", basictypenames[dd->type&~(DEF_SHARED|DEF_SAVEGLOBAL)], strings+dd->s_name, dd->ofs);
#endif #endif
@ -2471,7 +2474,7 @@ static void QCC_MergeUnstrip(dfunction_t *in, unsigned int num)
if (!def) if (!def)
{ {
def = QCC_PR_GetDef(type_function, name, NULL, true, 0, GDF_BASICTYPE); def = QCC_PR_GetDef(type_function, name, NULL, true, 0, GDF_BASICTYPE);
def->symboldata[def->ofs].function = i; def->symboldata[0].function = i;
def->initialized = true; def->initialized = true;
def->referenced = true; def->referenced = true;
def->assumedtype = true; def->assumedtype = true;

View file

@ -1793,7 +1793,7 @@ void NPP_QWFlush(void)
//move nq players to origin + angle //move nq players to origin + angle
VectorCopy(org, cl->edict->v->origin); VectorCopy(org, cl->edict->v->origin);
VectorCopy(ang, cl->edict->v->angles); VectorCopy(ang, cl->edict->v->angles);
cl->edict->v->angles[0]*=-1; cl->edict->v->angles[0]*=r_meshpitch.value;
} }
} }
} }
@ -1815,6 +1815,7 @@ void NPP_QWFlush(void)
short data; short data;
float org[3]; float org[3];
edict_t *ent = EDICT_NUM(svprogfuncs, LittleShort((*(short*)&buffer[1]))); edict_t *ent = EDICT_NUM(svprogfuncs, LittleShort((*(short*)&buffer[1])));
ent->muzzletime = sv.world.physicstime+host_frametime; //flag the entity as needing an EF_MUZZLEFLASH
VectorCopy(ent->v->origin, org); VectorCopy(ent->v->origin, org);
//we need to make a fake muzzleflash position for multicast to work properly. //we need to make a fake muzzleflash position for multicast to work properly.

View file

@ -1229,9 +1229,6 @@ void PR_ApplyCompilation_f (void)
pr_global_struct->time = sv.world.physicstime; pr_global_struct->time = sv.world.physicstime;
World_ClearWorld (&sv.world);
for (i=0 ; i<sv.allocated_client_slots ; i++) for (i=0 ; i<sv.allocated_client_slots ; i++)
{ {
ent = EDICT_NUM(svprogfuncs, i+1); ent = EDICT_NUM(svprogfuncs, i+1);
@ -1239,15 +1236,7 @@ void PR_ApplyCompilation_f (void)
svs.clients[i].edict = ent; svs.clients[i].edict = ent;
} }
ent = (edict_t*)sv.world.edicts; World_ClearWorld (&sv.world, true);
for (i=0 ; i<sv.world.num_edicts ; i++)
{
ent = EDICT_NUM(svprogfuncs, i);
if (ED_ISFREE(ent))
continue;
World_LinkEdict (&sv.world, (wedict_t*)ent, false); // force retouch even for stationary
}
svprogfuncs->parms->memfree(s); svprogfuncs->parms->memfree(s);
} }
@ -7503,7 +7492,7 @@ static void QCBUILTIN PF_h2matchAngleToSlope(pubprogfuncs_t *prinst, struct glob
AngleVectors(actor->v->angles, old_forward, old_right, P_VEC(v_up)); AngleVectors(actor->v->angles, old_forward, old_right, P_VEC(v_up));
VectorAngles(G_VECTOR(OFS_PARM0), NULL, G_VECTOR(OFS_RETURN)); VectorAngles(G_VECTOR(OFS_PARM0), NULL, G_VECTOR(OFS_RETURN), true/*FIXME*/);
pitch = G_FLOAT(OFS_RETURN) - 90; pitch = G_FLOAT(OFS_RETURN) - 90;
@ -9548,7 +9537,7 @@ qboolean SV_RunFullQCMovement(client_t *client, usercmd_t *ucmd)
{ {
if (!sv_player->v->fixangle) if (!sv_player->v->fixangle)
{ {
sv_player->v->angles[PITCH] = -sv_player->v->v_angle[PITCH]/3; sv_player->v->angles[PITCH] = r_meshpitch.value * sv_player->v->v_angle[PITCH]/3;
sv_player->v->angles[YAW] = sv_player->v->v_angle[YAW]; sv_player->v->angles[YAW] = sv_player->v->v_angle[YAW];
} }
sv_player->v->angles[ROLL] = sv_player->v->angles[ROLL] =
@ -11338,7 +11327,7 @@ void PR_DumpPlatform_f(void)
{"oldorigin", ".vector", QW|NQ|CS, D("This is often used on players to reset the player back to where they were last frame if they somehow got stuck inside something due to fpu precision. Never change a player's oldorigin field to inside a solid, because that might cause them to become pemanently stuck.")}, {"oldorigin", ".vector", QW|NQ|CS, D("This is often used on players to reset the player back to where they were last frame if they somehow got stuck inside something due to fpu precision. Never change a player's oldorigin field to inside a solid, because that might cause them to become pemanently stuck.")},
{"velocity", ".vector", QW|NQ|CS, D("The direction and speed that the entity is moving in world space.")}, {"velocity", ".vector", QW|NQ|CS, D("The direction and speed that the entity is moving in world space.")},
{"angles", ".vector", QW|NQ|CS, D("The eular angles the entity is facing in, in pitch, yaw, roll order. Due to a legacy bug, mdl/iqm/etc formats use +x=UP, bsp/spr/etc formats use +x=DOWN.")}, {"angles", ".vector", QW|NQ|CS, D("The eular angles the entity is facing in, in pitch, yaw, roll order. Due to a legacy bug, mdl/iqm/etc formats use +x=UP, bsp/spr/etc formats use +x=DOWN.")},
{"avelocity", ".vector", QW|NQ|CS, D("The amount the entity's angles change by each frame. Note that this is direct eular angles, and thus the angular change is non-linear and often just looks buggy.")}, {"avelocity", ".vector", QW|NQ|CS, D("The amount the entity's angles change by per second. Note that this is direct eular angles, and thus the angular change is non-linear and often just looks buggy if you're changing more than one angle at a time.")},
{"pmove_flags", ".float", CS}, {"pmove_flags", ".float", CS},
{"punchangle", ".vector", NQ}, {"punchangle", ".vector", NQ},
{"classname", ".string", QW|NQ|CS, D("Identifies the class/type of the entity. Useful for debugging, also used for loading, but its value is not otherwise significant to the engine, this leaves the mod free to set it to whatever it wants and randomly test strings for values in whatever inefficient way it chooses fit.")}, {"classname", ".string", QW|NQ|CS, D("Identifies the class/type of the entity. Useful for debugging, also used for loading, but its value is not otherwise significant to the engine, this leaves the mod free to set it to whatever it wants and randomly test strings for values in whatever inefficient way it chooses fit.")},

View file

@ -83,10 +83,13 @@ typedef struct edict_s
#endif #endif
/*csqc doesn't reference the rest*/ /*csqc doesn't reference the rest*/
#ifdef NQPROT
float muzzletime; //nq clients need special handling to retain EF_MUZZLEFLASH while not breaking qw clients running nq mods.
#endif
entity_state_t baseline; entity_state_t baseline;
// other fields from progs come immediately after // other fields from progs come immediately after
} edict_t; } edict_t;

View file

@ -329,19 +329,7 @@ void SV_Loadgame_Legacy(char *filename, vfsfile_t *f, int version)
//FIXME: DP saved games have some / *\nkey values\nkey values\n* / thing in them to save precaches and stuff //FIXME: DP saved games have some / *\nkey values\nkey values\n* / thing in them to save precaches and stuff
World_ClearWorld(&sv.world); World_ClearWorld(&sv.world, true);
for (i=0 ; i<sv.world.num_edicts ; i++)
{
ent = EDICT_NUM(svprogfuncs, i);
if (!ent)
break;
if (ED_ISFREE(ent))
continue;
World_LinkEdict (&sv.world, (wedict_t*)ent, false);
}
sv.spawned_client_slots = 0; sv.spawned_client_slots = 0;
for (i=0 ; i<svs.allocated_client_slots ; i++) for (i=0 ; i<svs.allocated_client_slots ; i++)
@ -622,7 +610,7 @@ qboolean SV_LoadLevelCache(const char *savename, const char *level, const char *
flocation_t loc; flocation_t loc;
SV_SpawnServer (level, startspot, false, false); SV_SpawnServer (level, startspot, false, false);
World_ClearWorld(&sv.world); World_ClearWorld(&sv.world, false);
if (!ge) if (!ge)
{ {
Con_Printf("Incorrect gamecode type.\n"); Con_Printf("Incorrect gamecode type.\n");
@ -774,7 +762,7 @@ qboolean SV_LoadLevelCache(const char *savename, const char *level, const char *
PF_InitTempStrings(svprogfuncs); PF_InitTempStrings(svprogfuncs);
World_ClearWorld (&sv.world); World_ClearWorld (&sv.world, true);
for (i=0 ; i<svs.allocated_client_slots ; i++) for (i=0 ; i<svs.allocated_client_slots ; i++)
{ {
@ -836,14 +824,7 @@ qboolean SV_LoadLevelCache(const char *savename, const char *level, const char *
} }
pr_global_struct->time = sv.world.physicstime; pr_global_struct->time = sv.world.physicstime;
for (i=0 ; i<sv.world.num_edicts ; i++)
{
ent = EDICT_NUM(svprogfuncs, i);
if (ED_ISFREE(ent))
continue;
World_LinkEdict (&sv.world, (wedict_t*)ent, false);
}
for (i=0 ; i<sv.world.num_edicts ; i++) for (i=0 ; i<sv.world.num_edicts ; i++)
{ {
ent = EDICT_NUM(svprogfuncs, i); ent = EDICT_NUM(svprogfuncs, i);

View file

@ -480,7 +480,8 @@ typedef struct client_s
float spawn_parms[NUM_SPAWN_PARMS]; float spawn_parms[NUM_SPAWN_PARMS];
char *spawninfo; char *spawninfo;
float spawninfotime; float spawninfotime;
float nextservertimeupdate; float nextservertimeupdate; //next time to send STAT_TIME
float lastoutgoingphysicstime;//sv.world.physicstime of the last outgoing message.
// client known data for deltas // client known data for deltas
int old_frags; int old_frags;
@ -667,11 +668,19 @@ typedef struct client_s
laggedpacket_t *laggedpacket_last; laggedpacket_t *laggedpacket_last;
} client_t; } client_t;
#if defined(NQPROT) || defined(Q2SERVER) || defined(Q3SERVER)
#define ISQWCLIENT(cl) ((cl)->protocol == SCP_QUAKEWORLD) #define ISQWCLIENT(cl) ((cl)->protocol == SCP_QUAKEWORLD)
#define ISQ2CLIENT(cl) ((cl)->protocol == SCP_QUAKE2) #define ISQ2CLIENT(cl) ((cl)->protocol == SCP_QUAKE2)
#define ISQ3CLIENT(cl) ((cl)->protocol == SCP_QUAKE3) #define ISQ3CLIENT(cl) ((cl)->protocol == SCP_QUAKE3)
#define ISNQCLIENT(cl) ((cl)->protocol >= SCP_NETQUAKE) #define ISNQCLIENT(cl) ((cl)->protocol >= SCP_NETQUAKE)
#define ISDPCLIENT(cl) ((cl)->protocol >= SCP_DARKPLACES6) #define ISDPCLIENT(cl) ((cl)->protocol >= SCP_DARKPLACES6)
#else
#define ISQWCLIENT(cl) ((cl)->protocol != SCP_BAD)
#define ISQ2CLIENT(cl) false
#define ISQ3CLIENT(cl) false
#define ISNQCLIENT(cl) false
#define ISDPCLIENT(cl) false
#endif
// a client can leave the server in one of four ways: // a client can leave the server in one of four ways:
// dropping properly by quiting or disconnecting // dropping properly by quiting or disconnecting

View file

@ -2340,16 +2340,19 @@ void SV_WritePlayersToMVD (client_t *client, client_frame_t *frame, sizebuf_t *m
ent = cl->edict; ent = cl->edict;
vent = ent; vent = ent;
#ifdef NQPROT
if (progstype != PROG_QW) if (progstype != PROG_QW)
{ {
if ((int)ent->v->effects & EF_MUZZLEFLASH) if ((int)ent->v->effects & EF_MUZZLEFLASH)
{ {
if (needcleanup < (j+1)) ent->v->effects = (int)ent->v->effects & ~EF_MUZZLEFLASH;
{ ent->muzzletime = sv.world.physicstime;
needcleanup = (j+1); MSG_WriteByte (&sv.multicast, svc_muzzleflash);
} MSG_WriteEntity (&sv.multicast, NUM_FOR_EDICT(svprogfuncs, ent));
SV_MulticastProtExt (ent->v->origin, MULTICAST_PHS, pr_global_struct->dimension_send, 0, 0);
} }
} }
#endif
if (SV_AddCSQCUpdate(client, ent)) if (SV_AddCSQCUpdate(client, ent))
continue; continue;
@ -2579,7 +2582,7 @@ void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, edict_t *
#ifdef NQPROT
if (progstype != PROG_QW) if (progstype != PROG_QW)
{ {
if (progstype == PROG_H2 && (int)ent->v->effects & H2EF_NODRAW && ent != clent) if (progstype == PROG_H2 && (int)ent->v->effects & H2EF_NODRAW && ent != clent)
@ -2587,12 +2590,14 @@ void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, edict_t *
if ((int)ent->v->effects & EF_MUZZLEFLASH) if ((int)ent->v->effects & EF_MUZZLEFLASH)
{ {
if (needcleanup < (j+1)) ent->v->effects = (int)ent->v->effects & ~EF_MUZZLEFLASH;
{ ent->muzzletime = sv.world.physicstime;
needcleanup = (j+1); MSG_WriteByte (&sv.multicast, svc_muzzleflash);
} MSG_WriteEntity (&sv.multicast, NUM_FOR_EDICT(svprogfuncs, ent));
SV_MulticastProtExt (ent->v->origin, MULTICAST_PHS, pr_global_struct->dimension_send, 0, 0);
} }
} }
#endif
// ZOID visibility tracking // ZOID visibility tracking
if (ent != clent && if (ent != clent &&
@ -3290,7 +3295,7 @@ void SV_Snapshot_BuildStateQ1(entity_state_t *state, edict_t *ent, client_t *cli
} }
else else
{ {
vectoangles(sv.world.g.defaultgravitydir, ang); VectorAngles(sv.world.g.defaultgravitydir, NULL, ang, false);
state->u.q1.gravitydir[0] = ((ang[0]/360) * 256) - 192; state->u.q1.gravitydir[0] = ((ang[0]/360) * 256) - 192;
state->u.q1.gravitydir[1] = (ang[1]/360) * 256; state->u.q1.gravitydir[1] = (ang[1]/360) * 256;
} }
@ -3298,7 +3303,7 @@ void SV_Snapshot_BuildStateQ1(entity_state_t *state, edict_t *ent, client_t *cli
else else
{ {
vec3_t ang; vec3_t ang;
vectoangles(ent->xv->gravitydir, ang); VectorAngles(ent->xv->gravitydir, NULL, ang, false);
state->u.q1.gravitydir[0] = ((ang[0]/360) * 256) - 192; state->u.q1.gravitydir[0] = ((ang[0]/360) * 256) - 192;
state->u.q1.gravitydir[1] = (ang[1]/360) * 256; state->u.q1.gravitydir[1] = (ang[1]/360) * 256;
} }
@ -3321,6 +3326,15 @@ void SV_Snapshot_BuildStateQ1(entity_state_t *state, edict_t *ent, client_t *cli
state->hexen2flags |= MLS_FULLBRIGHT; state->hexen2flags |= MLS_FULLBRIGHT;
#ifdef NQPROT #ifdef NQPROT
if (client && !ISQWCLIENT(client))
{
if (ent->muzzletime > client->lastoutgoingphysicstime && ent->muzzletime <= (float)sv.world.physicstime)
state->effects |= EF_MUZZLEFLASH;
if (client->spectator && !client->spec_track && ent == client->edict)
state->modelindex = sv_playermodel;
}
if (progstype != PROG_QW) if (progstype != PROG_QW)
{ {
if (progstype == PROG_TENEBRAE) if (progstype == PROG_TENEBRAE)
@ -3561,19 +3575,19 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, pvscamera_t
continue; continue;
} }
#ifdef NQPROT
if (progstype != PROG_QW) if (progstype != PROG_QW)
{ {
// if (progstype == PROG_H2)
// if (ent->v->effects == H2EF_NODRAW)
// continue;
if ((int)ent->v->effects & EF_MUZZLEFLASH) if ((int)ent->v->effects & EF_MUZZLEFLASH)
{ {
if (needcleanup < e) ent->v->effects = (int)ent->v->effects & ~EF_MUZZLEFLASH;
{ ent->muzzletime = sv.world.physicstime;
needcleanup = e; MSG_WriteByte (&sv.multicast, svc_muzzleflash);
} MSG_WriteEntity (&sv.multicast, NUM_FOR_EDICT(svprogfuncs, ent));
SV_MulticastProtExt (ent->v->origin, MULTICAST_PHS, pr_global_struct->dimension_send, 0, 0);
} }
} }
#endif
pvsflags = ent->xv->pvsflags; pvsflags = ent->xv->pvsflags;
for (c = 0; c < maxc; c++) for (c = 0; c < maxc; c++)
@ -4050,7 +4064,6 @@ void SV_CleanupEnts(void)
{ {
int e; int e;
edict_t *ent; edict_t *ent;
vec3_t org;
if (!needcleanup) if (!needcleanup)
return; return;
@ -4058,17 +4071,6 @@ void SV_CleanupEnts(void)
for (e=1 ; e<=needcleanup ; e++) for (e=1 ; e<=needcleanup ; e++)
{ {
ent = EDICT_NUM(svprogfuncs, e); ent = EDICT_NUM(svprogfuncs, e);
if ((int)ent->v->effects & EF_MUZZLEFLASH)
{
ent->v->effects = (int)ent->v->effects & ~EF_MUZZLEFLASH;
MSG_WriteByte(&sv.multicast, svc_muzzleflash);
MSG_WriteEntity(&sv.multicast, e);
VectorCopy(ent->v->origin, org);
if (progstype == PROG_H2)
org[2] += 24;
SV_Multicast(org, MULTICAST_PVS);
}
ent->xv->SendFlags = 0; ent->xv->SendFlags = 0;
#ifndef NOLEGACY #ifndef NOLEGACY

View file

@ -1011,7 +1011,7 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents,
// //
// init physics interaction links // init physics interaction links
// //
World_ClearWorld (&sv.world); World_ClearWorld (&sv.world, false);
//do we allow csprogs? //do we allow csprogs?
#ifdef PEXT_CSQC #ifdef PEXT_CSQC

View file

@ -324,7 +324,7 @@ float World_changeyaw (wedict_t *ent)
vec3_t vang; vec3_t vang;
/*calc current view matrix relative to the surface*/ /*calc current view matrix relative to the surface*/
ent->v->angles[PITCH] *= -1; ent->v->angles[PITCH] *= r_meshpitch.value;
AngleVectors(ent->v->angles, view[0], view[1], view[2]); AngleVectors(ent->v->angles, view[0], view[1], view[2]);
VectorNegate(view[1], view[1]); VectorNegate(view[1], view[1]);
@ -338,7 +338,7 @@ float World_changeyaw (wedict_t *ent)
Matrix4_Multiply(viewm, invsurfm, mat); Matrix4_Multiply(viewm, invsurfm, mat);
/*convert that back to angles*/ /*convert that back to angles*/
Matrix3x4_RM_ToVectors(mat, view[0], view[1], view[2], view[3]); Matrix3x4_RM_ToVectors(mat, view[0], view[1], view[2], view[3]);
VectorAngles(view[0], view[2], vang); VectorAngles(view[0], view[2], vang, true);
/*edit it*/ /*edit it*/
@ -375,7 +375,7 @@ float World_changeyaw (wedict_t *ent)
Matrix4_Multiply(mat, surfm, viewm); Matrix4_Multiply(mat, surfm, viewm);
/*and figure out the final result*/ /*and figure out the final result*/
Matrix3x4_RM_ToVectors(viewm, view[0], view[1], view[2], view[3]); Matrix3x4_RM_ToVectors(viewm, view[0], view[1], view[2], view[3]);
VectorAngles(view[0], view[2], ent->v->angles); VectorAngles(view[0], view[2], ent->v->angles, true);
//make sure everything is sane //make sure everything is sane
ent->v->angles[PITCH] = anglemod(ent->v->angles[PITCH]); ent->v->angles[PITCH] = anglemod(ent->v->angles[PITCH]);

View file

@ -305,18 +305,18 @@ static void WPhys_PortalTransform(world_t *w, wedict_t *ent, wedict_t *portal, v
} }
else else
#endif #endif
ent->v->angles[0] *= -1; ent->v->angles[0] *= r_meshpitch.value;
VectorCopy(ent->v->angles, G_VECTOR(OFS_PARM1)); VectorCopy(ent->v->angles, G_VECTOR(OFS_PARM1));
AngleVectors(ent->v->angles, w->g.v_forward, w->g.v_right, w->g.v_up); AngleVectors(ent->v->angles, w->g.v_forward, w->g.v_right, w->g.v_up);
PR_ExecuteProgram (w->progs, portal->xv->camera_transform); PR_ExecuteProgram (w->progs, portal->xv->camera_transform);
VectorAngles(w->g.v_forward, w->g.v_up, ent->v->angles); VectorAngles(w->g.v_forward, w->g.v_up, ent->v->angles, true);
#ifndef CLIENTONLY #ifndef CLIENTONLY
if (ent->entnum > 0 && ent->entnum <= svs.allocated_client_slots) if (ent->entnum > 0 && ent->entnum <= svs.allocated_client_slots)
{ {
client_t *cl = &svs.clients[ent->entnum-1]; client_t *cl = &svs.clients[ent->entnum-1];
int i; int i;
vec3_t delta; vec3_t delta;
ent->v->angles[0] *= -1; ent->v->angles[0] *= r_meshpitch.value;
if (!cl->lockangles && (cl->fteprotocolextensions2 & PEXT2_SETANGLEDELTA)) if (!cl->lockangles && (cl->fteprotocolextensions2 & PEXT2_SETANGLEDELTA))
{ {
cl = ClientReliableWrite_BeginSplit(cl, svcfte_setangledelta, 7); cl = ClientReliableWrite_BeginSplit(cl, svcfte_setangledelta, 7);
@ -339,7 +339,7 @@ static void WPhys_PortalTransform(world_t *w, wedict_t *ent, wedict_t *portal, v
ClientReliableWrite_Angle (cl, ent->v->angles[i]); ClientReliableWrite_Angle (cl, ent->v->angles[i]);
} }
VectorCopy(ent->v->angles, ent->v->v_angle); VectorCopy(ent->v->angles, ent->v->v_angle);
ent->v->angles[0] *= -1; ent->v->angles[0] *= r_meshpitch.value;
} }
#endif #endif
@ -347,11 +347,11 @@ static void WPhys_PortalTransform(world_t *w, wedict_t *ent, wedict_t *portal, v
avelocity is horribly dependant upon eular angles. trying to treat it as a matrix is folly. avelocity is horribly dependant upon eular angles. trying to treat it as a matrix is folly.
if (DotProduct(ent->v->avelocity, ent->v->avelocity)) if (DotProduct(ent->v->avelocity, ent->v->avelocity))
{ {
ent->v->avelocity[0] *= -1; ent->v->avelocity[0] *= r_meshpitch.value;
AngleVectors(ent->v->avelocity, w->g.v_forward, w->g.v_right, w->g.v_up); AngleVectors(ent->v->avelocity, w->g.v_forward, w->g.v_right, w->g.v_up);
PR_ExecuteProgram (w->progs, portal->xv->camera_transform); PR_ExecuteProgram (w->progs, portal->xv->camera_transform);
VectorAngles(w->g.v_forward, w->g.v_up, ent->v->avelocity); VectorAngles(w->g.v_forward, w->g.v_up, ent->v->avelocity);
ent->v->avelocity[0] *= -1; ent->v->avelocity[0] *= r_meshpitch.value;
} }
*/ */

View file

@ -1561,7 +1561,16 @@ void SV_WriteEntityDataToMessage (client_t *client, sizebuf_t *msg, int pnum)
} }
// a fixangle might get lost in a dropped packet. Oh well. // a fixangle might get lost in a dropped packet. Oh well.
if (ent->v->fixangle) if (client->spectator && ISNQCLIENT(client) && client->spec_track > 0)
{
edict_t *ed = EDICT_NUM(svprogfuncs, client->spec_track);
MSG_WriteByte(msg, svc_setangle);
MSG_WriteAngle(msg, ed->v->v_angle[0]);
MSG_WriteAngle(msg, ed->v->v_angle[1]);
MSG_WriteAngle(msg, ed->v->v_angle[2]);
VectorCopy(ed->v->origin, client->edict->v->origin);
}
else if (ent->v->fixangle)
{ {
if (!client->lockangles) if (!client->lockangles)
{ {
@ -1683,6 +1692,8 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg)
#ifdef NQPROT #ifdef NQPROT
ent = client->edict; ent = client->edict;
if (client->spectator && client->spec_track)
ent = EDICT_NUM(svprogfuncs, client->spec_track);
if (progstype != PROG_QW) if (progstype != PROG_QW)
{ {
if (ISQWCLIENT(client) && !(client->fteprotocolextensions2 & PEXT2_PREDINFO)) if (ISQWCLIENT(client) && !(client->fteprotocolextensions2 & PEXT2_PREDINFO))
@ -1871,7 +1882,10 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg)
if (nqjunk) if (nqjunk)
{ {
MSG_WriteShort (msg, ent->v->health); if (client->spectator && !client->spec_track)
MSG_WriteShort (msg, 1000);
else
MSG_WriteShort (msg, ent->v->health);
if (client->protocol == SCP_FITZ666) if (client->protocol == SCP_FITZ666)
{ {
MSG_WriteByte (msg, (int)ent->v->currentammo & 0xff); MSG_WriteByte (msg, (int)ent->v->currentammo & 0xff);
@ -2098,26 +2112,35 @@ void SV_CalcClientStats(client_t *client, int statsi[MAX_CL_STATS], float statsf
#endif #endif
{ {
#ifdef QUAKESTATS #ifdef QUAKESTATS
statsf[STAT_HEALTH] = ent->v->health; //sorry, but mneh if (client->spectator && !client->spec_track && ISNQCLIENT(client))
statsi[STAT_WEAPONMODELI] = SV_ModelIndex(PR_GetString(svprogfuncs, ent->v->weaponmodel)); {
if ((unsigned)statsi[STAT_WEAPONMODELI] >= client->maxmodels) statsf[STAT_HEALTH] = 1000;
statsi[STAT_WEAPONMODELI] = 0; //play it safe, try not to crash unsuspecting clients statsf[STAT_ARMOR] = 1000;
statsf[STAT_AMMO] = ent->v->currentammo; statsf[STAT_AMMO] = 1000;
statsf[STAT_ARMOR] = ent->v->armorvalue; }
statsf[STAT_SHELLS] = ent->v->ammo_shells;
statsf[STAT_NAILS] = ent->v->ammo_nails;
statsf[STAT_ROCKETS] = ent->v->ammo_rockets;
statsf[STAT_CELLS] = ent->v->ammo_cells;
statsf[STAT_ACTIVEWEAPON] = ent->v->weapon;
if ((client->csqcactive && !(client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)) || client->protocol != SCP_QUAKEWORLD || (client->fteprotocolextensions2 & PEXT2_PREDINFO))
// if ((client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) || client->protocol != SCP_QUAKEWORLD)
statsf[STAT_WEAPONFRAME] = ent->v->weaponframe; //weapon frame is sent differently with classic quakeworld protocols.
// stuff the sigil bits into the high bits of items for sbar
if (sv.haveitems2)
statsi[STAT_ITEMS] = (int)ent->v->items | ((int)ent->xv->items2 << 23);
else else
statsi[STAT_ITEMS] = (int)ent->v->items | ((int)pr_global_struct->serverflags << 28); {
statsf[STAT_HEALTH] = ent->v->health; //sorry, but mneh
statsi[STAT_WEAPONMODELI] = SV_ModelIndex(PR_GetString(svprogfuncs, ent->v->weaponmodel));
if ((unsigned)statsi[STAT_WEAPONMODELI] >= client->maxmodels)
statsi[STAT_WEAPONMODELI] = 0; //play it safe, try not to crash unsuspecting clients
statsf[STAT_AMMO] = ent->v->currentammo;
statsf[STAT_ARMOR] = ent->v->armorvalue;
statsf[STAT_SHELLS] = ent->v->ammo_shells;
statsf[STAT_NAILS] = ent->v->ammo_nails;
statsf[STAT_ROCKETS] = ent->v->ammo_rockets;
statsf[STAT_CELLS] = ent->v->ammo_cells;
statsf[STAT_ACTIVEWEAPON] = ent->v->weapon;
if ((client->csqcactive && !(client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)) || client->protocol != SCP_QUAKEWORLD || (client->fteprotocolextensions2 & PEXT2_PREDINFO))
// if ((client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) || client->protocol != SCP_QUAKEWORLD)
statsf[STAT_WEAPONFRAME] = ent->v->weaponframe; //weapon frame is sent differently with classic quakeworld protocols.
// stuff the sigil bits into the high bits of items for sbar
if (sv.haveitems2)
statsi[STAT_ITEMS] = (int)ent->v->items | ((int)ent->xv->items2 << 23);
else
statsi[STAT_ITEMS] = (int)ent->v->items | ((int)pr_global_struct->serverflags << 28);
}
statsf[STAT_VIEWHEIGHT] = ent->v->view_ofs[2]; statsf[STAT_VIEWHEIGHT] = ent->v->view_ofs[2];
@ -2484,7 +2507,7 @@ void SV_UpdateClientStats (client_t *client, int pnum, sizebuf_t *msg, client_fr
qboolean SV_CanTrack(client_t *client, int entity) qboolean SV_CanTrack(client_t *client, int entity)
{ {
if (entity < 0 || entity >= sv.allocated_client_slots) if (entity <= 0 || entity > sv.allocated_client_slots)
return false; return false;
if (svs.clients[entity-1].spectator) if (svs.clients[entity-1].spectator)
return false; return false;
@ -3217,7 +3240,7 @@ void SV_SendClientMessages (void)
c->frameunion.frames[fnum & UPDATE_MASK].packetsizeout += sentbytes; c->frameunion.frames[fnum & UPDATE_MASK].packetsizeout += sentbytes;
c->datagram.cursize = 0; c->datagram.cursize = 0;
} }
c->lastoutgoingphysicstime = sv.world.physicstime;
} }
SV_CleanupEnts(); SV_CleanupEnts();

View file

@ -3956,6 +3956,12 @@ void SV_PTrack_f (void)
ent = EDICT_NUM(svprogfuncs, host_client - svs.clients + 1); ent = EDICT_NUM(svprogfuncs, host_client - svs.clients + 1);
tent = EDICT_NUM(svprogfuncs, 0); tent = EDICT_NUM(svprogfuncs, 0);
ent->v->goalentity = EDICT_TO_PROG(svprogfuncs, tent); ent->v->goalentity = EDICT_TO_PROG(svprogfuncs, tent);
if (ISNQCLIENT(host_client))
{
ClientReliableWrite_Begin(host_client, svc_setview, 4);
ClientReliableWrite_Entity(host_client, host_client - svs.clients + 1);
}
return; return;
} }
@ -3975,6 +3981,12 @@ void SV_PTrack_f (void)
ent = EDICT_NUM(svprogfuncs, host_client - svs.clients + 1); ent = EDICT_NUM(svprogfuncs, host_client - svs.clients + 1);
tent = EDICT_NUM(svprogfuncs, 0); tent = EDICT_NUM(svprogfuncs, 0);
ent->v->goalentity = EDICT_TO_PROG(svprogfuncs, tent); ent->v->goalentity = EDICT_TO_PROG(svprogfuncs, tent);
if (ISNQCLIENT(host_client))
{
ClientReliableWrite_Begin(host_client, svc_setview, 4);
ClientReliableWrite_Entity(host_client, host_client - svs.clients + 1);
}
return; return;
} }
host_client->spec_track = i + 1; // now tracking host_client->spec_track = i + 1; // now tracking
@ -3982,6 +3994,12 @@ void SV_PTrack_f (void)
ent = EDICT_NUM(svprogfuncs, host_client - svs.clients + 1); ent = EDICT_NUM(svprogfuncs, host_client - svs.clients + 1);
tent = EDICT_NUM(svprogfuncs, i + 1); tent = EDICT_NUM(svprogfuncs, i + 1);
ent->v->goalentity = EDICT_TO_PROG(svprogfuncs, tent); ent->v->goalentity = EDICT_TO_PROG(svprogfuncs, tent);
if (ISNQCLIENT(host_client))
{
ClientReliableWrite_Begin(host_client, svc_setview, 4);
ClientReliableWrite_Entity(host_client, i + 1);
}
} }
@ -4877,7 +4895,7 @@ void Cmd_Join_f (void)
return; return;
} }
if (!(host_client->zquake_extensions & Z_EXT_JOIN_OBSERVE)) if (!ISNQCLIENT(host_client) && !(host_client->zquake_extensions & Z_EXT_JOIN_OBSERVE))
{ {
SV_TPrintToClient(host_client, PRINT_HIGH, "Your game client doesn't support this command\n"); SV_TPrintToClient(host_client, PRINT_HIGH, "Your game client doesn't support this command\n");
return; return;
@ -4923,6 +4941,12 @@ void Cmd_Join_f (void)
return; return;
} }
if (ISNQCLIENT(host_client))
{ //make sure the nq client is viewing from its own player entity again
ClientReliableWrite_Begin(host_client, svc_setview, 4);
ClientReliableWrite_Entity(host_client, host_client - svs.clients + 1);
}
for (; host_client; host_client = host_client->controlled) for (; host_client; host_client = host_client->controlled)
{ {
sv_player = host_client->edict; sv_player = host_client->edict;
@ -5022,7 +5046,7 @@ void Cmd_Observe_f (void)
return; return;
} }
if (!(host_client->zquake_extensions & Z_EXT_JOIN_OBSERVE)) if (!ISNQCLIENT(host_client) && !(host_client->zquake_extensions & Z_EXT_JOIN_OBSERVE))
{ {
SV_TPrintToClient(host_client, PRINT_HIGH, "Your game client doesn't support this command\n"); SV_TPrintToClient(host_client, PRINT_HIGH, "Your game client doesn't support this command\n");
return; return;
@ -5808,11 +5832,11 @@ ucmd_t ucmds[] =
{"nextdl", SV_NextDownload_f, true}, {"nextdl", SV_NextDownload_f, true},
/*quakeworld specific things*/ /*quakeworld specific things*/
{"addseat", Cmd_AddSeat_f}, {"addseat", Cmd_AddSeat_f}, //splitscreen
{"join", Cmd_Join_f}, {"join", Cmd_Join_f},
{"observe", Cmd_Observe_f}, {"observe", Cmd_Observe_f},
{"snap", SV_NoSnap_f},
{"ptrack", SV_PTrack_f}, //ZOID - used with autocam {"ptrack", SV_PTrack_f}, //ZOID - used with autocam
{"snap", SV_NoSnap_f}, //cheat detection
{"enablecsqc", SV_EnableClientsCSQC, true}, {"enablecsqc", SV_EnableClientsCSQC, true},
{"disablecsqc", SV_DisableClientsCSQC, true}, {"disablecsqc", SV_DisableClientsCSQC, true},
@ -5938,6 +5962,11 @@ ucmd_t nqucmds[] =
{"disablecsqc", SV_DisableClientsCSQC}, {"disablecsqc", SV_DisableClientsCSQC},
{"challengeconnect", NULL}, {"challengeconnect", NULL},
/*spectating, this should be fun...*/
{"join", Cmd_Join_f},
{"observe", Cmd_Observe_f},
{"ptrack", SV_PTrack_f}, //ZOID - used with autocam
#ifdef VOICECHAT #ifdef VOICECHAT
{"voicetarg", SV_Voice_Target_f}, {"voicetarg", SV_Voice_Target_f},
{"vignore", SV_Voice_Ignore_f}, /*ignore/mute specific player*/ {"vignore", SV_Voice_Ignore_f}, /*ignore/mute specific player*/
@ -6228,7 +6257,7 @@ static qboolean AddEntityToPmove(edict_t *player, edict_t *check)
if (solid == SOLID_PORTAL || solid == SOLID_BSP) if (solid == SOLID_PORTAL || solid == SOLID_BSP)
{ {
if(progstype != PROG_H2) if(progstype != PROG_H2)
pe->angles[0]*=-1; //quake is wierd. I guess someone fixed it hexen2... or my code is buggy or something... pe->angles[0]*=r_meshpitch.value; //quake is wierd. I guess someone fixed it hexen2... or my code is buggy or something...
pe->model = sv.models[(int)(check->v->modelindex)]; pe->model = sv.models[(int)(check->v->modelindex)];
VectorCopy (check->v->angles, pe->angles); VectorCopy (check->v->angles, pe->angles);
} }
@ -6712,7 +6741,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
{ {
if (sv_player->v->movetype == MOVETYPE_6DOF) if (sv_player->v->movetype == MOVETYPE_6DOF)
{ {
sv_player->v->angles[PITCH] = -sv_player->v->v_angle[PITCH]; sv_player->v->angles[PITCH] = r_meshpitch.value * sv_player->v->v_angle[PITCH];
sv_player->v->angles[YAW] = sv_player->v->v_angle[YAW]; sv_player->v->angles[YAW] = sv_player->v->v_angle[YAW];
sv_player->v->angles[ROLL] = sv_player->v->v_angle[ROLL]; sv_player->v->angles[ROLL] = sv_player->v->v_angle[ROLL];
} }
@ -6720,7 +6749,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
{ {
if (!sv_player->v->fixangle) if (!sv_player->v->fixangle)
{ {
sv_player->v->angles[PITCH] = -sv_player->v->v_angle[PITCH]/3; sv_player->v->angles[PITCH] = r_meshpitch.value * sv_player->v->v_angle[PITCH]/3;
sv_player->v->angles[YAW] = sv_player->v->v_angle[YAW]; sv_player->v->angles[YAW] = sv_player->v->v_angle[YAW];
} }
sv_player->v->angles[ROLL] = sv_player->v->angles[ROLL] =
@ -6996,7 +7025,7 @@ if (sv_player->v->health > 0 && before && !after )
VectorInterpolate(surf[0], 0.333, view[0], fwd); VectorInterpolate(surf[0], 0.333, view[0], fwd);
CrossProduct(surf[1], fwd, up); CrossProduct(surf[1], fwd, up);
/*we have our player's new axis*/ /*we have our player's new axis*/
VectorAngles(fwd, up, sv_player->v->angles); VectorAngles(fwd, up, sv_player->v->angles, true);
} }
} }
@ -7870,6 +7899,52 @@ void SVNQ_ReadClientMove (usercmd_t *move)
bits = MSG_ReadLong(); bits = MSG_ReadLong();
else else
bits = MSG_ReadByte (); bits = MSG_ReadByte ();
if (host_client->spectator)
{
qboolean tracknext = false;
if (bits & (move->buttons ^ bits) & BUTTON_ATTACK)
{ //enable/disable tracking
if (host_client->spec_track)
{ //disable tracking
host_client->spec_track = 0;
host_client->edict->v->goalentity = EDICT_TO_PROG(svprogfuncs, EDICT_NUM(svprogfuncs, 0));
ClientReliableWrite_Begin(host_client, svc_setview, 4);
ClientReliableWrite_Entity(host_client, host_client - svs.clients + 1);
}
else //otherwise track the next person, if we can
tracknext = true;
}
if ((bits & (move->buttons ^ bits) & BUTTON_JUMP) && host_client->spec_track)
tracknext = true;
if (tracknext)
{ //track the next player
for (i = host_client->spec_track+1; i < sv.allocated_client_slots; i++)
{
if (SV_CanTrack(host_client, i))
break;
}
//try a previous one instead of disabling
if (i == sv.allocated_client_slots)
{
for (i = 1; i < host_client->spec_track; i++)
{
if (SV_CanTrack(host_client, i))
break;
}
if (i == host_client->spec_track)
i = 0;
}
host_client->spec_track = i;
host_client->edict->v->goalentity = EDICT_TO_PROG(svprogfuncs, EDICT_NUM(svprogfuncs, i));
ClientReliableWrite_Begin(host_client, svc_setview, 4);
ClientReliableWrite_Entity(host_client, i?i:(host_client - svs.clients + 1));
if (i)
SV_ClientTPrintf (host_client, PRINT_HIGH, "tracking %s\n", svs.clients[i-1].name);
}
}
move->buttons = bits; move->buttons = bits;
i = MSG_ReadByte (); i = MSG_ReadByte ();

View file

@ -379,9 +379,9 @@ trace_t SVHL_ClipMoveToEntity (hledict_t *ent, vec3_t start, vec3_t mins, vec3_t
// trace a line through the apropriate clipping hull // trace a line through the apropriate clipping hull
if (ent->v.solid != SOLID_BSP) if (ent->v.solid != SOLID_BSP)
{ {
ent->v.angles[0]*=-1; //carmack made bsp models rotate wrongly. ent->v.angles[0]*=r_meshpitch.value; //carmack made bsp models rotate wrongly.
World_TransformedTrace(model, hullnum, ent->v.frame, start, end, mins, maxs, false, &trace, ent->v.origin, ent->v.angles, clipmask); World_TransformedTrace(model, hullnum, ent->v.frame, start, end, mins, maxs, false, &trace, ent->v.origin, ent->v.angles, clipmask);
ent->v.angles[0]*=-1; ent->v.angles[0]*=r_meshpitch.value;
} }
else else
{ {

View file

@ -1801,7 +1801,7 @@ qboolean SVQ3_InitGame(void)
SV_InitBotLib(); SV_InitBotLib();
World_ClearWorld(&sv.world); World_ClearWorld(&sv.world, false);
q3_sentities = Z_Malloc(sizeof(q3serverEntity_t)*MAX_GENTITIES); q3_sentities = Z_Malloc(sizeof(q3serverEntity_t)*MAX_GENTITIES);

View file

@ -224,28 +224,29 @@ static areanode_t *World_CreateAreaNode (world_t *w, int depth, vec3_t mins, vec
w->numareanodes++; w->numareanodes++;
ClearLink (&anode->edicts); ClearLink (&anode->edicts);
if (depth == w->areanodedepth) VectorSubtract (maxs, mins, size);
if (depth == w->areanodedepth || (size[0] < 512 && size[1] < 512))
{ {
anode->axis = -1; anode->axis = -1;
anode->children[0] = anode->children[1] = NULL; anode->children[0] = anode->children[1] = NULL;
return anode; return anode;
} }
VectorSubtract (maxs, mins, size);
if (size[0] > size[1]) if (size[0] > size[1])
anode->axis = 0; anode->axis = 0;
else else
anode->axis = 1; anode->axis = 1;
anode->dist = 0.5 * (maxs[anode->axis] + mins[anode->axis]); anode->dist = 0.5 * (maxs[anode->axis] + mins[anode->axis]);
VectorCopy (mins, mins1); VectorCopy (mins, mins1);
VectorCopy (mins, mins2); VectorCopy (mins, mins2);
VectorCopy (maxs, maxs1); VectorCopy (maxs, maxs1);
VectorCopy (maxs, maxs2); VectorCopy (maxs, maxs2);
maxs1[anode->axis] = mins2[anode->axis] = anode->dist; maxs1[anode->axis] = mins2[anode->axis] = anode->dist;
anode->children[0] = World_CreateAreaNode (w, depth+1, mins2, maxs2); anode->children[0] = World_CreateAreaNode (w, depth+1, mins2, maxs2);
anode->children[1] = World_CreateAreaNode (w, depth+1, mins1, maxs1); anode->children[1] = World_CreateAreaNode (w, depth+1, mins1, maxs1);
@ -258,8 +259,10 @@ SV_ClearWorld
=============== ===============
*/ */
void World_ClearWorld (world_t *w) void World_ClearWorld (world_t *w, qboolean relink)
{ {
int i;
wedict_t *ent;
int maxdepth; int maxdepth;
vec3_t mins, maxs; vec3_t mins, maxs;
if (w->worldmodel) if (w->worldmodel)
@ -279,18 +282,33 @@ void World_ClearWorld (world_t *w)
ClearLink (&w->portallist.edicts); ClearLink (&w->portallist.edicts);
w->portallist.axis = -1; w->portallist.axis = -1;
maxdepth = 4; maxdepth = 8;
if (!w->areanodes || w->areanodedepth != maxdepth) if (!w->areanodes || w->areanodedepth != maxdepth)
{ {
Z_Free(w->areanodes); Z_Free(w->areanodes);
w->areanodedepth = maxdepth; w->areanodedepth = maxdepth;
w->areanodes = Z_Malloc(sizeof(*w->areanodes) * pow(2, w->areanodedepth+1)); w->areanodes = Z_Malloc(sizeof(*w->areanodes) * (pow(2, w->areanodedepth+1)-1));
} }
else else
memset (w->areanodes, 0, sizeof(*w->areanodes)*w->numareanodes); memset (w->areanodes, 0, sizeof(*w->areanodes)*w->numareanodes);
w->numareanodes = 0; w->numareanodes = 0;
World_CreateAreaNode (w, 0, mins, maxs); World_CreateAreaNode (w, 0, mins, maxs);
if (relink)
{
for (i=0 ; i<w->num_edicts ; i++)
{
ent = WEDICT_NUM(w->progs, i);
if (!ent)
continue;
ent->area.prev = ent->area.next = NULL;
if (ED_ISFREE(ent))
continue;
World_LinkEdict (w, ent, false); // relink ents so touch functions continue to work.
}
}
} }
@ -1126,9 +1144,9 @@ static trace_t World_ClipMoveToEntity (world_t *w, wedict_t *ent, vec3_t eorg, v
} }
else if (ent->v->solid != SOLID_BSP) else if (ent->v->solid != SOLID_BSP)
{ {
ent->v->angles[0]*=-1; //carmack made bsp models rotate wrongly. ent->v->angles[0]*=r_meshpitch.value; //carmack made bsp models rotate wrongly.
World_TransformedTrace(model, hullnum, &framestate, start, end, mins, maxs, capsule, &trace, eorg, ent->v->angles, hitcontentsmask); World_TransformedTrace(model, hullnum, &framestate, start, end, mins, maxs, capsule, &trace, eorg, ent->v->angles, hitcontentsmask);
ent->v->angles[0]*=-1; ent->v->angles[0]*=r_meshpitch.value;
} }
else else
{ {
@ -1275,7 +1293,7 @@ static void WorldQ2_AreaEdicts_r (areanode_t *node)
if (!l) if (!l)
{ {
int i; int i;
World_ClearWorld(&sv.world); World_ClearWorld(&sv.world, false);
check = ge->edicts; check = ge->edicts;
for (i = 0; i < ge->num_edicts; i++, check = (q2edict_t *)((char *)check + ge->edict_size)) for (i = 0; i < ge->num_edicts; i++, check = (q2edict_t *)((char *)check + ge->edict_size))
memset(&check->area, 0, sizeof(check->area)); memset(&check->area, 0, sizeof(check->area));

View file

@ -5468,8 +5468,7 @@ static void R_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist
//now determine the stuff the backend will use. //now determine the stuff the backend will use.
memcpy(r_refdef.m_view, vmat, sizeof(float)*16); memcpy(r_refdef.m_view, vmat, sizeof(float)*16);
VectorAngles(vpn, vup, r_refdef.viewangles); VectorAngles(vpn, vup, r_refdef.viewangles, false);
r_refdef.viewangles[0] *= -1;
VectorCopy(r_refdef.vieworg, r_origin); VectorCopy(r_refdef.vieworg, r_origin);
//determine r_refdef.flipcull & SHADER_CULL_FLIP based upon whether right is right or not. //determine r_refdef.flipcull & SHADER_CULL_FLIP based upon whether right is right or not.