add support for symlinks in zips.

try to fix normalmaps on q3bsps. could do with verification, but at least I'm not the only one with a bug if its still buggy.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4578 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2014-01-13 02:42:25 +00:00
parent 705e9ac9e8
commit 38a9770253
55 changed files with 856 additions and 602 deletions

View File

@ -133,9 +133,6 @@ trace_t Cam_DoTrace(vec3_t vec1, vec3_t vec2)
return PM_PlayerTrace(pmove.origin, vec2, MASK_PLAYERSOLID); return PM_PlayerTrace(pmove.origin, vec2, MASK_PLAYERSOLID);
} }
extern vec3_t player_mins;
extern vec3_t player_maxs;
// Returns distance or 9999 if invalid for some reason // Returns distance or 9999 if invalid for some reason
static float Cam_TryFlyby(vec3_t selforigin, vec3_t playerorigin, vec3_t vec, qboolean checkvis) static float Cam_TryFlyby(vec3_t selforigin, vec3_t playerorigin, vec3_t vec, qboolean checkvis)
{ {
@ -143,10 +140,10 @@ static float Cam_TryFlyby(vec3_t selforigin, vec3_t playerorigin, vec3_t vec, qb
trace_t trace; trace_t trace;
float len; float len;
player_mins[0] = player_mins[1] = -16; pmove.player_mins[0] = pmove.player_mins[1] = -16;
player_mins[2] = -24; pmove.player_mins[2] = -24;
player_maxs[0] = player_maxs[1] = 16; pmove.player_maxs[0] = pmove.player_maxs[1] = 16;
player_maxs[2] = 32; pmove.player_maxs[2] = 32;
VectorAngles(vec, NULL, v); VectorAngles(vec, NULL, v);
// v[0] = -v[0]; // v[0] = -v[0];

View File

@ -4205,6 +4205,9 @@ void CL_LinkPlayers (void)
if (!cl.worldmodel || cl.worldmodel->needload) if (!cl.worldmodel || cl.worldmodel->needload)
return; return;
if (cl.paused)
predictmsmult = 0;
playertime = realtime - cls.latency + 0.02; playertime = realtime - cls.latency + 0.02;
if (playertime > realtime) if (playertime > realtime)
playertime = realtime; playertime = realtime;
@ -4445,16 +4448,15 @@ void CL_LinkPlayers (void)
if ((r_showbboxes.ival & 3) == 3) if ((r_showbboxes.ival & 3) == 3)
{ {
vec3_t min, max; vec3_t min, max;
extern vec3_t player_mins, player_maxs;
shader_t *s = R_RegisterShader("bboxshader", SUF_NONE, NULL); shader_t *s = R_RegisterShader("bboxshader", SUF_NONE, NULL);
if (s) if (s)
{ {
VectorAdd(state->origin, player_mins, min); VectorAdd(state->origin, pmove.player_mins, min);
VectorAdd(state->origin, player_maxs, max); VectorAdd(state->origin, pmove.player_maxs, max);
CLQ1_AddOrientedCube(s, min, max, NULL, 0.1, 0, 0, 1); CLQ1_AddOrientedCube(s, min, max, NULL, 0.1, 0, 0, 1);
VectorAdd(ent->origin, player_mins, min); VectorAdd(ent->origin, pmove.player_mins, min);
VectorAdd(ent->origin, player_maxs, max); VectorAdd(ent->origin, pmove.player_maxs, max);
CLQ1_AddOrientedCube(s, min, max, NULL, 0, 0, 0.1, 1); CLQ1_AddOrientedCube(s, min, max, NULL, 0, 0, 0.1, 1);
} }
} }
@ -4821,8 +4823,6 @@ pmove must be setup with world and solid entity hulls before calling
void CL_SetSolidPlayers (void) void CL_SetSolidPlayers (void)
{ {
int j; int j;
extern vec3_t player_mins;
extern vec3_t player_maxs;
struct predicted_player *pplayer; struct predicted_player *pplayer;
physent_t *pent; physent_t *pent;
@ -4845,8 +4845,8 @@ void CL_SetSolidPlayers (void)
memset(pent, 0, sizeof(physent_t)); memset(pent, 0, sizeof(physent_t));
VectorCopy(pplayer->origin, pent->origin); VectorCopy(pplayer->origin, pent->origin);
pent->info = j+1; pent->info = j+1;
VectorCopy(player_mins, pent->mins); VectorCopy(pmove.player_mins, pent->mins);
VectorCopy(player_maxs, pent->maxs); VectorCopy(pmove.player_maxs, pent->maxs);
if (++pmove.numphysent == MAX_PHYSENTS) //we just hit 88 miles per hour. if (++pmove.numphysent == MAX_PHYSENTS) //we just hit 88 miles per hour.
break; break;
pent++; pent++;

View File

@ -719,12 +719,12 @@ void CL_ClampPitch (int pnum)
vang[ROLL] = 0; vang[ROLL] = 0;
else if (vang[ROLL] > 0) else if (vang[ROLL] > 0)
{ {
Con_Printf("Roll %f\n", vang[ROLL]); // Con_Printf("Roll %f\n", vang[ROLL]);
vang[ROLL] -= host_frametime*180; vang[ROLL] -= host_frametime*180;
} }
else else
{ {
Con_Printf("Roll %f\n", vang[ROLL]); // Con_Printf("Roll %f\n", vang[ROLL]);
vang[ROLL] += host_frametime*180; vang[ROLL] += host_frametime*180;
} }
} }

View File

@ -88,7 +88,7 @@ cvar_t qtvcl_eztvextensions = CVAR("qtvcl_eztvextensions", "0");
cvar_t cl_demospeed = CVARAF("cl_demospeed", "1", "demo_setspeed", 0); cvar_t cl_demospeed = CVARAF("cl_demospeed", "1", "demo_setspeed", 0);
cvar_t cl_loopbackprotocol = CVARD("cl_loopbackprotocol", "qw", "Which protocol to use for single-player/the internal client. Should be one of: qw, nqid, nq, fitz, dp6, dp7."); cvar_t cl_loopbackprotocol = CVARD("cl_loopbackprotocol", "", "Which protocol to use for single-player/the internal client. Should be one of: qw, nqid, nq, fitz, dp6, dp7. If empty, will use qw protocols for qw mods, and nq protocols for nq mods.");
cvar_t cl_threadedphysics = CVAR("cl_threadedphysics", "0"); cvar_t cl_threadedphysics = CVAR("cl_threadedphysics", "0");
@ -661,7 +661,7 @@ void CL_CheckForResend (void)
default: default:
cl.movesequence = 0; cl.movesequence = 0;
if (!strcmp(cl_loopbackprotocol.string, "qw")) if (!strcmp(cl_loopbackprotocol.string, "qw"))
{ { //qw with all supported extensions -default
pext1 = Net_PextMask(1, false); pext1 = Net_PextMask(1, false);
pext2 = Net_PextMask(2, false); pext2 = Net_PextMask(2, false);
cls.protocol = CP_QUAKEWORLD; cls.protocol = CP_QUAKEWORLD;
@ -695,14 +695,17 @@ void CL_CheckForResend (void)
cls.protocol = CP_NETQUAKE; cls.protocol = CP_NETQUAKE;
cls.protocol_nq = CPNQ_DP7; cls.protocol_nq = CPNQ_DP7;
} }
else if (progstype == PROG_QW) else if (progstype == PROG_QW || progstype == PROG_H2) //h2 depends on various extensions and doesn't really match either protocol.
{ {
cls.protocol = CP_QUAKEWORLD; cls.protocol = CP_QUAKEWORLD;
pext1 = Net_PextMask(1, false); pext1 = Net_PextMask(1, false);
pext2 = Net_PextMask(2, false); pext2 = Net_PextMask(2, false);
} }
else else
{
cls.protocol = CP_NETQUAKE; cls.protocol = CP_NETQUAKE;
cls.protocol_nq = CPNQ_FITZ666;
}
//make sure the protocol within demos is actually correct/sane //make sure the protocol within demos is actually correct/sane
if (cls.demorecording == 1 && cls.protocol != CP_QUAKEWORLD) if (cls.demorecording == 1 && cls.protocol != CP_QUAKEWORLD)
@ -715,6 +718,7 @@ void CL_CheckForResend (void)
{ {
cls.protocol = CP_NETQUAKE; cls.protocol = CP_NETQUAKE;
cls.protocol_nq = CPNQ_FITZ666; cls.protocol_nq = CPNQ_FITZ666;
//FIXME: use pext.
} }
break; break;
} }

View File

@ -364,8 +364,6 @@ CL_PredictUsercmd
*/ */
void CL_PredictUsercmd (int pnum, int entnum, player_state_t *from, player_state_t *to, usercmd_t *u) void CL_PredictUsercmd (int pnum, int entnum, player_state_t *from, player_state_t *to, usercmd_t *u)
{ {
extern vec3_t player_mins;
extern vec3_t player_maxs;
// split up very long moves // split up very long moves
if (u->msec > 50) if (u->msec > 50)
{ {
@ -408,8 +406,8 @@ void CL_PredictUsercmd (int pnum, int entnum, player_state_t *from, player_state
movevars.bunnyspeedcap = cl.bunnyspeedcap; movevars.bunnyspeedcap = cl.bunnyspeedcap;
pmove.onladder = false; pmove.onladder = false;
VectorCopy(from->szmins, player_mins); VectorCopy(from->szmins, pmove.player_mins);
VectorCopy(from->szmaxs, player_maxs); VectorCopy(from->szmaxs, pmove.player_maxs);
PM_PlayerMove (cl.gamespeed); PM_PlayerMove (cl.gamespeed);
@ -427,8 +425,8 @@ void CL_PredictUsercmd (int pnum, int entnum, player_state_t *from, player_state
to->weaponframe = from->weaponframe; to->weaponframe = from->weaponframe;
to->pm_type = from->pm_type; to->pm_type = from->pm_type;
VectorCopy(player_mins, to->szmins); VectorCopy(pmove.player_mins, to->szmins);
VectorCopy(player_maxs, to->szmaxs); VectorCopy(pmove.player_maxs, to->szmaxs);
} }

View File

@ -1675,7 +1675,7 @@ static int Con_DrawConsoleLines(console_t *con, conline_t *l, int sx, int ex, in
} }
break; break;
} }
linkinfolen += unicode_encode(linkinfo+linkinfolen, (*e & CON_CHARMASK), sizeof(linkinfo)-1-linkinfolen); linkinfolen += unicode_encode(linkinfo+linkinfolen, (*e & CON_CHARMASK), sizeof(linkinfo)-1-linkinfolen, true);
} }
} }

View File

@ -22,6 +22,26 @@ cvar_t r_dodgytgafiles = SCVAR("r_dodgytgafiles", "0"); //Certain tgas are upsid
cvar_t r_dodgypcxfiles = SCVAR("r_dodgypcxfiles", "0"); //Quake 2's PCX loading isn't complete, cvar_t r_dodgypcxfiles = SCVAR("r_dodgypcxfiles", "0"); //Quake 2's PCX loading isn't complete,
//and some Q2 mods include PCX files //and some Q2 mods include PCX files
//that only work with this assumption //that only work with this assumption
char *r_defaultimageextensions =
#ifdef IMAGEFMT_DDS
"dds " //compressed or something
#endif
"tga" //fairly fast to load
#ifdef AVAIL_PNGLIB
" png" //pngs, fairly common, but slow
#endif
//" bmp" //wtf? at least not lossy
#ifdef AVAIL_JPEGLIB
" jpg" //q3 uses some jpegs, for some reason
#endif
#ifdef IMAGEFMT_BLP
//" blp" //blizzard picture, for the luls
#endif
" pcx" //pcxes are the original gamedata of q2. So we don't want them to override pngs.
;
void R_ImageExtensions_Callback(struct cvar_s *var, char *oldvalue);
cvar_t r_imageexensions = CVARC("r_imageexensions", NULL, R_ImageExtensions_Callback);
#endif #endif
#ifndef _WIN32 #ifndef _WIN32
@ -2482,6 +2502,26 @@ qbyte *Read32BitImageFile(qbyte *buf, int len, int *width, int *height, qboolean
return data; return data;
} }
if (len >= 8) //.lmp has no magic id. guess at it.
{
int w = LittleLong(((int*)buf)[0]);
int h = LittleLong(((int*)buf)[1]);
int i;
if (w >= 4 && h >= 4 && w*h+sizeof(int)*2 == com_filesize)
{
unsigned int *in = (unsigned int*)buf+2;
data = BZ_Malloc(w * h * sizeof(int));
for (i = 0; i < w * h; i++)
{
((unsigned int*)data)[i] = d_8to24rgbtable[in[i]];
}
*width = w;
*height = h;
*hasalpha = false;
return data;
}
}
TRACE(("dbg: Read32BitImageFile: life sucks\n")); TRACE(("dbg: Read32BitImageFile: life sucks\n"));
return NULL; return NULL;
@ -2544,29 +2584,32 @@ static void *R_FlipImage32(void *in, int *inoutwidth, int *inoutheight, qboolean
return out; return out;
} }
int tex_extensions_count;
#define tex_extensions_max 15
static struct static struct
{ {
char *name; char name[6];
int enabled; } tex_extensions[tex_extensions_max];
} tex_extensions[] = void R_ImageExtensions_Callback(struct cvar_s *var, char *oldvalue)
{//reverse order of preference - (match commas with optional file types) {
{".pcx", 1}, //pcxes are the original gamedata of q2. So we don't want them to override pngs. char *v = var->string;
#ifdef AVAIL_JPEGLIB tex_extensions_count = 0;
{".jpg", 1}, //q3 uses some jpegs, for some reason
#endif while (tex_extensions_count < tex_extensions_max)
{".bmp", 0}, //wtf? at least not lossy {
#ifdef AVAIL_PNGLIB v = COM_Parse(v);
{".png", 1}, //pngs, fairly common, but slow if (!v)
#endif break;
{".tga", 1}, //fairly fast to load Q_snprintfz(tex_extensions[tex_extensions_count].name, sizeof(tex_extensions[tex_extensions_count].name), ".%s", com_token);
#ifdef IMAGEFMT_BLP tex_extensions_count++;
{".blp", 1}, //blizzard picture, for the luls }
#endif
#ifdef IMAGEFMT_DDS if (tex_extensions_count < tex_extensions_max)
{".dds", 1}, //compressed or something {
#endif Q_snprintfz(tex_extensions[tex_extensions_count].name, sizeof(tex_extensions[tex_extensions_count].name), "");
{"", 1} //someone forgot an extension tex_extensions_count++;
}; }
}
static struct static struct
{ {
@ -2675,11 +2718,8 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags)
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
{ {
tex = r_nulltex; tex = r_nulltex;
for (e = (flags & IF_EXACTEXTENSION)?0:sizeof(tex_extensions)/sizeof(tex_extensions[0])-1; e >=0 ; e--) for (e = (flags & IF_EXACTEXTENSION)?tex_extensions_count-1:0; e < tex_extensions_count; e++)
{ {
if (!tex_extensions[e].enabled)
continue;
buf = NULL; buf = NULL;
for (j = 0; j < sizeof(cmscheme)/sizeof(cmscheme[0])/6; j++) for (j = 0; j < sizeof(cmscheme)/sizeof(cmscheme[0])/6; j++)
{ {
@ -2737,6 +2777,7 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags)
BZ_Free(buf); BZ_Free(buf);
return tex; return tex;
} }
Con_Printf("%s is not a dds file\n", fname);
BZ_Free(buf); BZ_Free(buf);
} }
#endif #endif
@ -2751,11 +2792,8 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags)
{ {
if (!tex_path[i].enabled) if (!tex_path[i].enabled)
continue; continue;
for (e = (flags & IF_EXACTEXTENSION)?0:sizeof(tex_extensions)/sizeof(tex_extensions[0])-1; e >=0 ; e--) for (e = (flags & IF_EXACTEXTENSION)?tex_extensions_count-1:0; e < tex_extensions_count; e++)
{ {
if (!tex_extensions[e].enabled)
continue;
if (tex_path[i].args >= 3) if (tex_path[i].args >= 3)
{ {
if (!subpath) if (!subpath)
@ -2771,6 +2809,7 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags)
TRACE(("dbg: Mod_LoadHiResTexture: trying %s\n", fname)); TRACE(("dbg: Mod_LoadHiResTexture: trying %s\n", fname));
if ((buf = COM_LoadFile (fname, 5))) if ((buf = COM_LoadFile (fname, 5)))
{ {
//these formats have special handling, because they cannot be implemented via Read32BitImageFile - they don't result in rgba images.
#ifdef IMAGEFMT_DDS #ifdef IMAGEFMT_DDS
tex = GL_ReadTextureDDS(name, buf, com_filesize); tex = GL_ReadTextureDDS(name, buf, com_filesize);
if (TEXVALID(tex)) if (TEXVALID(tex))

View File

@ -385,10 +385,7 @@ void Con_ExecuteLine(console_t *con, char *line)
while(*line) while(*line)
{ {
unicode = utf8_decode(&err, line, &line); unicode = utf8_decode(&err, line, &line);
if (com_parseutf8.ival < 0) len += unicode_encode(deutf8+len, unicode, sizeof(deutf8)-1 - len, true);
len += iso88591_encode(deutf8+len, unicode, sizeof(deutf8)-1 - len);
else
len += qchar_encode(deutf8+len, unicode, sizeof(deutf8)-1 - len);
} }
deutf8[len] = 0; deutf8[len] = 0;
line = deutf8; line = deutf8;
@ -1366,10 +1363,7 @@ void Key_Message (int key, int unicode)
while(*line) while(*line)
{ {
unicode = utf8_decode(&err, line, &line); unicode = utf8_decode(&err, line, &line);
if (com_parseutf8.ival < 0) len += unicode_encode(deutf8+len, unicode, sizeof(deutf8)-1 - len, true);
len += iso88591_encode(deutf8+len, unicode, sizeof(deutf8)-1 - len);
else
len += qchar_encode(deutf8+len, unicode, sizeof(deutf8)-1 - len);
} }
deutf8[len] = 0; deutf8[len] = 0;
line = deutf8; line = deutf8;

View File

@ -555,6 +555,7 @@ const char *presetexec[] =
"r_part_density 0.25;" "r_part_density 0.25;"
"cl_nolerp 1;" "cl_nolerp 1;"
"r_lerpmuzzlehack 0;" "r_lerpmuzzlehack 0;"
"v_gunkick 0;"
, // fast options , // fast options
"gl_texturemode ln;" "gl_texturemode ln;"
@ -587,6 +588,7 @@ const char *presetexec[] =
"r_coronas 1;" "r_coronas 1;"
"cl_nolerp 0;" "cl_nolerp 0;"
"r_lerpmuzzlehack 1;" "r_lerpmuzzlehack 1;"
"v_gunkick 1;"
, // nice options , // nice options
"r_stains 0.75;" "r_stains 0.75;"

View File

@ -621,7 +621,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
"}\n" "}\n"
; ;
break; break;
case BM_ADD: case BM_ADDA:
namepostfix = "_add"; namepostfix = "_add";
defaultshader = defaultshader =
"{\n" "{\n"
@ -637,6 +637,22 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
"}\n" "}\n"
; ;
break; break;
case BM_ADDC:
namepostfix = "_add";
defaultshader =
"{\n"
"program defaultsprite\n"
"nomipmaps\n"
"{\n"
"map $diffuse\n"
"blendfunc GL_SRC_COLOR GL_ONE\n"
"rgbgen vertex\n"
"alphagen vertex\n"
"}\n"
"polygonoffset\n"
"}\n"
;
break;
case BM_INVMODA: case BM_INVMODA:
namepostfix = "_invmoda"; namepostfix = "_invmoda";
defaultshader = defaultshader =
@ -1255,8 +1271,10 @@ static void P_ParticleEffect_f(void)
ptype->stainonimpact = atof(value); ptype->stainonimpact = atof(value);
else if (!strcmp(var, "blend")) else if (!strcmp(var, "blend"))
{ {
if (!strcmp(value, "add")) if (!strcmp(value, "adda") || !strcmp(value, "add"))
ptype->looks.blendmode = BM_ADD; ptype->looks.blendmode = BM_ADDA;
else if (!strcmp(value, "addc"))
ptype->looks.blendmode = BM_ADDC;
else if (!strcmp(value, "subtract")) else if (!strcmp(value, "subtract"))
ptype->looks.blendmode = BM_SUBTRACT; ptype->looks.blendmode = BM_SUBTRACT;
else if (!strcmp(value, "invmoda") || !strcmp(value, "invmod")) else if (!strcmp(value, "invmoda") || !strcmp(value, "invmod"))
@ -2005,6 +2023,7 @@ static void P_ImportEffectInfo_f(void)
ptype->spawnmode = SM_BOX; ptype->spawnmode = SM_BOX;
ptype->colorindex = -1;
ptype->spawnchance = 1; ptype->spawnchance = 1;
ptype->randsmax = 1; ptype->randsmax = 1;
ptype->looks.scalefactor = 2; ptype->looks.scalefactor = 2;
@ -2044,22 +2063,22 @@ static void P_ImportEffectInfo_f(void)
else if (!strcmp(arg[1], "static")) else if (!strcmp(arg[1], "static"))
{ {
ptype->looks.type = PT_NORMAL; ptype->looks.type = PT_NORMAL;
ptype->looks.blendmode = BM_ADD; ptype->looks.blendmode = BM_ADDA;
} }
else if (!strcmp(arg[1], "smoke")) else if (!strcmp(arg[1], "smoke"))
{ {
ptype->looks.type = PT_NORMAL; ptype->looks.type = PT_NORMAL;
ptype->looks.blendmode = BM_ADD; ptype->looks.blendmode = BM_ADDA;
} }
else if (!strcmp(arg[1], "spark")) else if (!strcmp(arg[1], "spark"))
{ {
ptype->looks.type = PT_TEXTUREDSPARK; ptype->looks.type = PT_TEXTUREDSPARK;
ptype->looks.blendmode = BM_ADD; ptype->looks.blendmode = BM_ADDA;
} }
else if (!strcmp(arg[1], "bubble")) else if (!strcmp(arg[1], "bubble"))
{ {
ptype->looks.type = PT_NORMAL; ptype->looks.type = PT_NORMAL;
ptype->looks.blendmode = BM_ADD; ptype->looks.blendmode = BM_ADDA;
} }
else if (!strcmp(arg[1], "blood")) else if (!strcmp(arg[1], "blood"))
{ {
@ -2070,12 +2089,12 @@ static void P_ImportEffectInfo_f(void)
else if (!strcmp(arg[1], "beam")) else if (!strcmp(arg[1], "beam"))
{ {
ptype->looks.type = PT_BEAM; ptype->looks.type = PT_BEAM;
ptype->looks.blendmode = BM_ADD; ptype->looks.blendmode = BM_ADDA;
} }
else if (!strcmp(arg[1], "snow")) else if (!strcmp(arg[1], "snow"))
{ {
ptype->looks.type = PT_NORMAL; ptype->looks.type = PT_NORMAL;
ptype->looks.blendmode = BM_ADD; ptype->looks.blendmode = BM_ADDA;
//should have some sort of wind/flutter with it //should have some sort of wind/flutter with it
} }
else else
@ -2181,7 +2200,7 @@ static void P_ImportEffectInfo_f(void)
else if (!strcmp(arg[1], "alpha")) else if (!strcmp(arg[1], "alpha"))
ptype->looks.blendmode = BM_BLEND; ptype->looks.blendmode = BM_BLEND;
else if (!strcmp(arg[1], "add")) else if (!strcmp(arg[1], "add"))
ptype->looks.blendmode = BM_ADD; ptype->looks.blendmode = BM_ADDA;
else else
Con_Printf("effectinfo 'blend %s' not supported\n", arg[1]); Con_Printf("effectinfo 'blend %s' not supported\n", arg[1]);
} }

View File

@ -2397,8 +2397,6 @@ static void QCBUILTIN PF_cs_getinputstate (pubprogfuncs_t *prinst, struct global
static void QCBUILTIN PF_cs_runplayerphysics (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) static void QCBUILTIN PF_cs_runplayerphysics (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
unsigned int msecs; unsigned int msecs;
extern vec3_t player_mins;
extern vec3_t player_maxs;
csqcedict_t *ent; csqcedict_t *ent;
if (prinst->callargc >= 1) if (prinst->callargc >= 1)
@ -2435,8 +2433,8 @@ static void QCBUILTIN PF_cs_runplayerphysics (pubprogfuncs_t *prinst, struct glo
pmove.waterjumptime = 0; pmove.waterjumptime = 0;
VectorCopy(ent->v->origin, pmove.origin); VectorCopy(ent->v->origin, pmove.origin);
VectorCopy(ent->v->velocity, pmove.velocity); VectorCopy(ent->v->velocity, pmove.velocity);
VectorCopy(ent->v->maxs, player_maxs); VectorCopy(ent->v->maxs, pmove.player_maxs);
VectorCopy(ent->v->mins, player_mins); VectorCopy(ent->v->mins, pmove.player_mins);
} }
else else
{ {
@ -2448,8 +2446,8 @@ static void QCBUILTIN PF_cs_runplayerphysics (pubprogfuncs_t *prinst, struct glo
pmove.waterjumptime = *csqcg.pmove_waterjumptime; pmove.waterjumptime = *csqcg.pmove_waterjumptime;
VectorCopy(csqcg.pmove_org, pmove.origin); VectorCopy(csqcg.pmove_org, pmove.origin);
VectorCopy(csqcg.pmove_vel, pmove.velocity); VectorCopy(csqcg.pmove_vel, pmove.velocity);
VectorCopy(csqcg.pmove_maxs, player_maxs); VectorCopy(csqcg.pmove_maxs, pmove.player_maxs);
VectorCopy(csqcg.pmove_mins, player_mins); VectorCopy(csqcg.pmove_mins, pmove.player_mins);
} }
CL_SetSolidEntities(); CL_SetSolidEntities();
@ -2931,79 +2929,6 @@ static void QCBUILTIN PF_cs_lightstyle (pubprogfuncs_t *prinst, struct globalvar
cl_lightstyle[stnum].length = Q_strlen(cl_lightstyle[stnum].map); cl_lightstyle[stnum].length = Q_strlen(cl_lightstyle[stnum].map);
} }
static void QCBUILTIN PF_cs_changeyaw (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
csqcedict_t *ent;
float ideal, current, move, speed;
ent = (void*)PROG_TO_EDICT(prinst, *csqcg.self);
current = anglemod( ent->v->angles[1] );
ideal = ent->v->ideal_yaw;
speed = ent->v->yaw_speed;
if (current == ideal)
return;
move = ideal - current;
if (ideal > current)
{
if (move >= 180)
move = move - 360;
}
else
{
if (move <= -180)
move = move + 360;
}
if (move > 0)
{
if (move > speed)
move = speed;
}
else
{
if (move < -speed)
move = -speed;
}
ent->v->angles[1] = anglemod (current + move);
}
static void QCBUILTIN PF_cs_changepitch (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
csqcedict_t *ent;
float ideal, current, move, speed;
ent = (void*)PROG_TO_EDICT(prinst, *csqcg.self);
current = anglemod( ent->v->angles[0] );
ideal = ent->xv->ideal_pitch;
speed = ent->xv->pitch_speed;
if (current == ideal)
return;
move = ideal - current;
if (ideal > current)
{
if (move >= 180)
move = move - 360;
}
else
{
if (move <= -180)
move = move + 360;
}
if (move > 0)
{
if (move > speed)
move = speed;
}
else
{
if (move < -speed)
move = -speed;
}
ent->v->angles[0] = anglemod (current + move);
}
static void QCBUILTIN PF_cs_findradius (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) static void QCBUILTIN PF_cs_findradius (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
csqcedict_t *ent, *chain; csqcedict_t *ent, *chain;
@ -4387,7 +4312,7 @@ static struct {
{"localcmd", PF_localcmd, 46}, // #46 void(string str) localcmd (QUAKE) {"localcmd", PF_localcmd, 46}, // #46 void(string str) localcmd (QUAKE)
{"nextent", PF_nextent, 47}, // #47 entity(entity e) nextent (QUAKE) {"nextent", PF_nextent, 47}, // #47 entity(entity e) nextent (QUAKE)
{"particle", PF_cs_particle, 48}, // #48 void(vector org, vector dir, float colour, float count) particle (QUAKE) {"particle", PF_cs_particle, 48}, // #48 void(vector org, vector dir, float colour, float count) particle (QUAKE)
{"changeyaw", PF_cs_changeyaw, 49}, // #49 void() changeyaw (QUAKE) {"changeyaw", PF_changeyaw, 49}, // #49 void() changeyaw (QUAKE)
//50 //50
// {"?", PF_Fixme, 50}, // #50 // {"?", PF_Fixme, 50}, // #50
{"vectoangles", PF_vectoangles, 51}, // #51 vector(vector v) vectoangles (QUAKE) {"vectoangles", PF_vectoangles, 51}, // #51 vector(vector v) vectoangles (QUAKE)
@ -4405,7 +4330,7 @@ static struct {
{"sin", PF_Sin, 60}, // #60 float(float angle) sin (DP_QC_SINCOSSQRTPOW) {"sin", PF_Sin, 60}, // #60 float(float angle) sin (DP_QC_SINCOSSQRTPOW)
{"cos", PF_Cos, 61}, // #61 float(float angle) cos (DP_QC_SINCOSSQRTPOW) {"cos", PF_Cos, 61}, // #61 float(float angle) cos (DP_QC_SINCOSSQRTPOW)
{"sqrt", PF_Sqrt, 62}, // #62 float(float value) sqrt (DP_QC_SINCOSSQRTPOW) {"sqrt", PF_Sqrt, 62}, // #62 float(float value) sqrt (DP_QC_SINCOSSQRTPOW)
{"changepitch", PF_cs_changepitch, 63}, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH) {"changepitch", PF_changepitch, 63}, // #63 void(entity ent) changepitch (DP_QC_CHANGEPITCH)
{"tracetoss", PF_cs_tracetoss, 64}, // #64 void(entity ent, entity ignore) tracetoss (DP_QC_TRACETOSS) {"tracetoss", PF_cs_tracetoss, 64}, // #64 void(entity ent, entity ignore) tracetoss (DP_QC_TRACETOSS)
{"etos", PF_etos, 65}, // #65 string(entity ent) etos (DP_QC_ETOS) {"etos", PF_etos, 65}, // #65 string(entity ent) etos (DP_QC_ETOS)
@ -4897,7 +4822,7 @@ static struct {
{"gethostcachevalue", PF_cl_gethostcachevalue, 611}, {"gethostcachevalue", PF_cl_gethostcachevalue, 611},
{"gethostcachestring", PF_cl_gethostcachestring, 612}, {"gethostcachestring", PF_cl_gethostcachestring, 612},
{"parseentitydata", PF_parseentitydata, 613}, {"parseentitydata", PF_parseentitydata, 613},
{"stringtokeynum", PF_cl_stringtokeynum, 614}, {"stringtokeynum_menu", PF_cl_stringtokeynum, 614},
{"resethostcachemasks", PF_cl_resethostcachemasks, 615}, {"resethostcachemasks", PF_cl_resethostcachemasks, 615},
{"sethostcachemaskstring", PF_cl_sethostcachemaskstring,616}, {"sethostcachemaskstring", PF_cl_sethostcachemaskstring,616},

View File

@ -588,7 +588,7 @@ void QCBUILTIN PF_CL_drawrawstring (pubprogfuncs_t *prinst, struct globalvars_s
while(*text) while(*text)
{ {
if (1)//VMUTF8) if (1)//VMUTF8)
c = unicode_decode(&error, text, &text); c = unicode_decode(&error, text, &text, false);
else else
{ {
//FIXME: which charset is this meant to be using? //FIXME: which charset is this meant to be using?
@ -1616,7 +1616,7 @@ static struct {
//gap //gap
{"print_csqc", PF_print, 339}, {"print_csqc", PF_print, 339},
{"keynumtostring_csqc", PF_cl_keynumtostring, 340}, {"keynumtostring_csqc", PF_cl_keynumtostring, 340},
{"stringtokeynum", PF_cl_stringtokeynum, 341}, {"stringtokeynum_csqc", PF_cl_stringtokeynum, 341},
{"getkeybind", PF_cl_getkeybind, 342}, {"getkeybind", PF_cl_getkeybind, 342},
//gap //gap
{"isdemo", PF_isdemo, 349}, {"isdemo", PF_isdemo, 349},

View File

@ -2101,15 +2101,14 @@ void Surf_SetupFrame(void)
/*pick up any extra water entities*/ /*pick up any extra water entities*/
{ {
extern vec3_t player_maxs, player_mins;
vec3_t t1,t2; vec3_t t1,t2;
VectorCopy(player_mins, t1); VectorCopy(pmove.player_mins, t1);
VectorCopy(player_maxs, t2); VectorCopy(pmove.player_maxs, t2);
VectorClear(player_maxs); VectorClear(pmove.player_maxs);
VectorClear(player_mins); VectorClear(pmove.player_mins);
r_viewcontents |= PM_ExtraBoxContents(r_origin); r_viewcontents |= PM_ExtraBoxContents(r_origin);
VectorCopy(t1, player_mins); VectorCopy(t1, pmove.player_mins);
VectorCopy(t2, player_maxs); VectorCopy(t2, pmove.player_maxs);
} }
V_SetContentsColor (r_viewcontents); V_SetContentsColor (r_viewcontents);

View File

@ -217,6 +217,8 @@ cvar_t r_stereo_method = CVARD("r_stereo_method", "0", "Value 0 = Off.\nVal
extern cvar_t r_dodgytgafiles; extern cvar_t r_dodgytgafiles;
extern cvar_t r_dodgypcxfiles; extern cvar_t r_dodgypcxfiles;
extern char *r_defaultimageextensions;
extern cvar_t r_imageexensions;
extern cvar_t r_drawentities; extern cvar_t r_drawentities;
extern cvar_t r_drawviewmodel; extern cvar_t r_drawviewmodel;
extern cvar_t r_drawworld; extern cvar_t r_drawworld;
@ -599,6 +601,9 @@ void Renderer_Init(void)
Cvar_Register(&r_dodgytgafiles, "Bug fixes"); Cvar_Register(&r_dodgytgafiles, "Bug fixes");
Cvar_Register(&r_dodgypcxfiles, "Bug fixes"); Cvar_Register(&r_dodgypcxfiles, "Bug fixes");
r_imageexensions.enginevalue = r_defaultimageextensions;
Cvar_Register(&r_imageexensions, GRAPHICALNICETIES);
r_imageexensions.callback(&r_imageexensions, NULL);
Cvar_Register(&r_loadlits, GRAPHICALNICETIES); Cvar_Register(&r_loadlits, GRAPHICALNICETIES);
Cvar_Register(&r_lightstylesmooth, GRAPHICALNICETIES); Cvar_Register(&r_lightstylesmooth, GRAPHICALNICETIES);
Cvar_Register(&r_lightstylesmooth_limit, GRAPHICALNICETIES); Cvar_Register(&r_lightstylesmooth_limit, GRAPHICALNICETIES);
@ -2211,9 +2216,6 @@ void R_SetFrustum (float projmat[16], float viewmat[16])
r_refdef.frustum_numplanes = 4; r_refdef.frustum_numplanes = 4;
if (r_refdef.recurse)
return;
r_refdef.frustum[r_refdef.frustum_numplanes].normal[0] = mvp[3] - mvp[2]; r_refdef.frustum[r_refdef.frustum_numplanes].normal[0] = mvp[3] - mvp[2];
r_refdef.frustum[r_refdef.frustum_numplanes].normal[1] = mvp[7] - mvp[6]; r_refdef.frustum[r_refdef.frustum_numplanes].normal[1] = mvp[7] - mvp[6];
r_refdef.frustum[r_refdef.frustum_numplanes].normal[2] = mvp[11] - mvp[10]; r_refdef.frustum[r_refdef.frustum_numplanes].normal[2] = mvp[11] - mvp[10];

View File

@ -1276,7 +1276,7 @@ void V_CalcRefdef (playerview_t *pv)
if (v_gunkick.value) if (v_gunkick.value)
r_refdef.viewangles[PITCH] += pv->punchangle*v_gunkick.value; r_refdef.viewangles[PITCH] += pv->punchangle*v_gunkick.value;
r_refdef.time = realtime; r_refdef.time = cl.servertime;
// smooth out stair step ups // smooth out stair step ups

View File

@ -197,6 +197,11 @@ void Mod_NormaliseTextureVectors(vec3_t *n, vec3_t *s, vec3_t *t, int v)
for (i = 0; i < v; i++) for (i = 0; i < v; i++)
{ {
//hack stuff to match dp/tenebrae
// VectorNegate(s[1], s[i]);
VectorNegate(t[i], t[i]);
//strip away any variance against the normal to keep it perpendicular, then normalize
f = -DotProduct(s[i], n[i]); f = -DotProduct(s[i], n[i]);
VectorMA(s[i], f, n[i], tmp); VectorMA(s[i], f, n[i], tmp);
VectorNormalize2(tmp, s[i]); VectorNormalize2(tmp, s[i]);
@ -4308,7 +4313,7 @@ qboolean QDECL Mod_LoadQ3Model(model_t *mod, void *buffer)
R_BuildDefaultTexnums(NULL, shaders[i]); R_BuildDefaultTexnums(NULL, shaders[i]);
if (shaders[i]->flags & SHADER_NOIMAGE) if (shaders[i]->flags & SHADER_NOIMAGE)
Con_Printf("Unable to load texture for shader \"%s\" for model \"%s\"\n", shaders[i]->name, loadmodel->name); Con_Printf("Unable to load texture for shader \"%s\" on mesh \"%s\" for model \"%s\"\n", shaders[i]->name, surf->name, loadmodel->name);
} }
inshader++; inshader++;
@ -6174,7 +6179,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
shaders[i] = R_RegisterSkin(skin[i].name, mod->name); shaders[i] = R_RegisterSkin(skin[i].name, mod->name);
R_BuildDefaultTexnums(NULL, shaders[i]); R_BuildDefaultTexnums(NULL, shaders[i]);
if (shaders[i]->flags & SHADER_NOIMAGE) if (shaders[i]->flags & SHADER_NOIMAGE)
Con_Printf("Unable to load texture for shader \"%s\" for model \"%s\"\n", shaders[i]->name, loadmodel->name); Con_Printf("Unable to load texture for shader \"%s\" on polyset \"%s\" for model \"%s\"\n", shaders[i]->name, strings+mesh[i].name, loadmodel->name);
gai[i].ofs_st_array = (otcoords+offset); gai[i].ofs_st_array = (otcoords+offset);
#endif #endif

View File

@ -2082,15 +2082,15 @@ unsigned int utf8_decode(int *error, const void *in, char **out)
return uc; return uc;
} }
unsigned int unicode_decode(int *error, const void *in, char **out) unsigned int unicode_decode(int *error, const void *in, char **out, qboolean markup)
{ {
unsigned int charcode; unsigned int charcode;
if (((char*)in)[0] == '^' && ((char*)in)[1] == 'U' && ishexcode(((char*)in)[2]) && ishexcode(((char*)in)[3]) && ishexcode(((char*)in)[4]) && ishexcode(((char*)in)[5])) if (markup && ((char*)in)[0] == '^' && ((char*)in)[1] == 'U' && ishexcode(((char*)in)[2]) && ishexcode(((char*)in)[3]) && ishexcode(((char*)in)[4]) && ishexcode(((char*)in)[5]))
{ {
*out = (char*)in + 6; *out = (char*)in + 6;
charcode = (dehex(((char*)in)[2]) << 12) | (dehex(((char*)in)[2]) << 8) | (dehex(((char*)in)[2]) << 4) | (dehex(((char*)in)[2]) << 0); charcode = (dehex(((char*)in)[2]) << 12) | (dehex(((char*)in)[2]) << 8) | (dehex(((char*)in)[2]) << 4) | (dehex(((char*)in)[2]) << 0);
} }
else if (((char*)in)[0] == '^' && ((char*)in)[1] == '{') else if (markup && ((char*)in)[0] == '^' && ((char*)in)[1] == '{')
{ {
*out = (char*)in + 2; *out = (char*)in + 2;
charcode = 0; charcode = 0;
@ -2173,9 +2173,10 @@ unsigned int utf8_encode(void *out, unsigned int unicode, int maxlen)
return bcount; return bcount;
} }
unsigned int qchar_encode(char *out, unsigned int unicode, int maxlen) unsigned int qchar_encode(char *out, unsigned int unicode, int maxlen, qboolean markup)
{ {
static const char hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; static const char hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
//FIXME: is it a bug that we can't distinguish between true ascii and 0xe0XX ?
if (((unicode >= 32 || unicode == '\n' || unicode == '\t' || unicode == '\r') && unicode < 128) || (unicode >= 0xe000 && unicode <= 0xe0ff)) if (((unicode >= 32 || unicode == '\n' || unicode == '\t' || unicode == '\r') && unicode < 128) || (unicode >= 0xe000 && unicode <= 0xe0ff))
{ //quake compatible chars { //quake compatible chars
if (maxlen < 1) if (maxlen < 1)
@ -2183,54 +2184,11 @@ unsigned int qchar_encode(char *out, unsigned int unicode, int maxlen)
*out++ = unicode; *out++ = unicode;
return 1; return 1;
} }
else if (unicode > 0xffff) else if (!markup)
{ //chars longer than 16 bits
char *o = out;
if (maxlen < 11)
return 0;
*out++ = '^';
*out++ = '{';
if (unicode > 0xfffffff)
*out++ = hex[(unicode>>28)&15];
if (unicode > 0xffffff)
*out++ = hex[(unicode>>24)&15];
if (unicode > 0xfffff)
*out++ = hex[(unicode>>20)&15];
if (unicode > 0xffff)
*out++ = hex[(unicode>>16)&15];
if (unicode > 0xfff)
*out++ = hex[(unicode>>12)&15];
if (unicode > 0xff)
*out++ = hex[(unicode>>8)&15];
if (unicode > 0xf)
*out++ = hex[(unicode>>4)&15];
if (unicode > 0x0)
*out++ = hex[(unicode>>0)&15];
*out++ = '}';
return out - o;
}
else
{ //16bit chars
if (maxlen < 6)
return 0;
*out++ = '^';
*out++ = 'U';
*out++ = hex[(unicode>>12)&15];
*out++ = hex[(unicode>>8)&15];
*out++ = hex[(unicode>>4)&15];
*out++ = hex[(unicode>>0)&15];
return 6;
}
}
unsigned int iso88591_encode(char *out, unsigned int unicode, int maxlen)
{ {
static const char hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
if (unicode < 256)
{ //iso8859-1 compatible chars
if (maxlen < 1) if (maxlen < 1)
return 0; return 0;
*out++ = unicode; *out++ = '?';
return 1; return 1;
} }
else if (unicode > 0xffff) else if (unicode > 0xffff)
@ -2273,25 +2231,82 @@ unsigned int iso88591_encode(char *out, unsigned int unicode, int maxlen)
} }
} }
unsigned int unicode_encode(char *out, unsigned int unicode, int maxlen) unsigned int iso88591_encode(char *out, unsigned int unicode, int maxlen, qboolean markup)
{
static const char hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
if (unicode < 256 || (unicode >= 0xe020 && unicode < 0xe080))
{ //iso8859-1 compatible chars
if (maxlen < 1)
return 0;
*out++ = unicode;
return 1;
}
else if (!markup)
{
if (maxlen < 1)
return 0;
*out++ = '?';
return 1;
}
else if (unicode > 0xffff)
{ //chars longer than 16 bits
char *o = out;
if (maxlen < 11)
return 0;
*out++ = '^';
*out++ = '{';
if (unicode > 0xfffffff)
*out++ = hex[(unicode>>28)&15];
if (unicode > 0xffffff)
*out++ = hex[(unicode>>24)&15];
if (unicode > 0xfffff)
*out++ = hex[(unicode>>20)&15];
if (unicode > 0xffff)
*out++ = hex[(unicode>>16)&15];
if (unicode > 0xfff)
*out++ = hex[(unicode>>12)&15];
if (unicode > 0xff)
*out++ = hex[(unicode>>8)&15];
if (unicode > 0xf)
*out++ = hex[(unicode>>4)&15];
if (unicode > 0x0)
*out++ = hex[(unicode>>0)&15];
*out++ = '}';
return out - o;
}
else
{ //16bit chars
if (maxlen < 6)
return 0;
*out++ = '^';
*out++ = 'U';
*out++ = hex[(unicode>>12)&15];
*out++ = hex[(unicode>>8)&15];
*out++ = hex[(unicode>>4)&15];
*out++ = hex[(unicode>>0)&15];
return 6;
}
}
unsigned int unicode_encode(char *out, unsigned int unicode, int maxlen, qboolean markup)
{ {
if (com_parseutf8.ival > 0) if (com_parseutf8.ival > 0)
return utf8_encode(out, unicode, maxlen); return utf8_encode(out, unicode, maxlen);
else if (com_parseutf8.ival) else if (com_parseutf8.ival)
return iso88591_encode(out, unicode, maxlen); return iso88591_encode(out, unicode, maxlen, markup);
else else
return qchar_encode(out, unicode, maxlen); return qchar_encode(out, unicode, maxlen, markup);
} }
//char-based strlen. //char-based strlen.
unsigned int unicode_charcount(char *in, size_t buffersize) unsigned int unicode_charcount(char *in, size_t buffersize, qboolean markup)
{ {
int error; int error;
char *end = in + buffersize; char *end = in + buffersize;
int chars = 0; int chars = 0;
for(chars = 0; in < end && *in; chars+=1) for(chars = 0; in < end && *in; chars+=1)
{ {
unicode_decode(&error, in, &in); unicode_decode(&error, in, &in, markup);
if (in > end) if (in > end)
break; //exceeded buffer size uncleanly break; //exceeded buffer size uncleanly
@ -2300,7 +2315,7 @@ unsigned int unicode_charcount(char *in, size_t buffersize)
} }
//handy hacky function. //handy hacky function.
unsigned int unicode_byteofsfromcharofs(char *str, unsigned int charofs) unsigned int unicode_byteofsfromcharofs(char *str, unsigned int charofs, qboolean markup)
{ {
char *in = str; char *in = str;
int error; int error;
@ -2310,19 +2325,19 @@ unsigned int unicode_byteofsfromcharofs(char *str, unsigned int charofs)
if (chars >= charofs) if (chars >= charofs)
return in - str; return in - str;
unicode_decode(&error, in, &in); unicode_decode(&error, in, &in, markup);
} }
return in - str; return in - str;
} }
//handy hacky function. //handy hacky function.
unsigned int unicode_charofsfrombyteofs(char *str, unsigned int byteofs) unsigned int unicode_charofsfrombyteofs(char *str, unsigned int byteofs, qboolean markup)
{ {
int error; int error;
char *end = str + byteofs; char *end = str + byteofs;
int chars = 0; int chars = 0;
for(chars = 0; str < end && *str; chars+=1) for(chars = 0; str < end && *str; chars+=1)
{ {
unicode_decode(&error, str, &str); unicode_decode(&error, str, &str, markup);
if (str > end) if (str > end)
break; //exceeded buffer size uncleanly break; //exceeded buffer size uncleanly
@ -2348,7 +2363,7 @@ int towlower(int c)
} }
#endif #endif
size_t unicode_strtoupper(char *in, char *out, size_t outsize) size_t unicode_strtoupper(char *in, char *out, size_t outsize, qboolean markup)
{ {
//warning: towupper is locale-specific (eg: turkish has both I and dotted-I and thus i should transform to dotted-I rather than to I). //warning: towupper is locale-specific (eg: turkish has both I and dotted-I and thus i should transform to dotted-I rather than to I).
//also it can't easily cope with accent prefixes. //also it can't easily cope with accent prefixes.
@ -2359,12 +2374,12 @@ size_t unicode_strtoupper(char *in, char *out, size_t outsize)
while(*in) while(*in)
{ {
c = unicode_decode(&error, in, &in); c = unicode_decode(&error, in, &in, markup);
if (c >= 0xe020 && c <= 0xe07f) //quake-char-aware. if (c >= 0xe020 && c <= 0xe07f) //quake-char-aware.
c = towupper(c & 0x7f) + (c & 0xff80); c = towupper(c & 0x7f) + (c & 0xff80);
else else
c = towupper(c); c = towupper(c);
l = unicode_encode(out, c, outsize - l); l = unicode_encode(out, c, outsize - l, markup);
out += l; out += l;
} }
*out = 0; *out = 0;
@ -2372,7 +2387,7 @@ size_t unicode_strtoupper(char *in, char *out, size_t outsize)
return l; return l;
} }
size_t unicode_strtolower(char *in, char *out, size_t outsize) size_t unicode_strtolower(char *in, char *out, size_t outsize, qboolean markup)
{ {
//warning: towlower is locale-specific (eg: turkish has both i and dotless-i and thus I should transform to dotless-i rather than to i). //warning: towlower is locale-specific (eg: turkish has both i and dotless-i and thus I should transform to dotless-i rather than to i).
//also it can't easily cope with accent prefixes. //also it can't easily cope with accent prefixes.
@ -2383,12 +2398,12 @@ size_t unicode_strtolower(char *in, char *out, size_t outsize)
while(*in) while(*in)
{ {
c = unicode_decode(&error, in, &in); c = unicode_decode(&error, in, &in, markup);
if (c >= 0xe020 && c <= 0xe07f) //quake-char-aware. if (c >= 0xe020 && c <= 0xe07f) //quake-char-aware.
c = towlower(c & 0x7f) + (c & 0xff80); c = towlower(c & 0x7f) + (c & 0xff80);
else else
c = towlower(c); c = towlower(c);
l = unicode_encode(out, c, outsize - l); l = unicode_encode(out, c, outsize - l, markup);
out += l; out += l;
} }
*out = 0; *out = 0;
@ -2573,7 +2588,7 @@ char *COM_DeFunString(conchar_t *str, conchar_t *stop, char *out, int outsize, q
if (ignoreflags && (*str & CON_HIDDEN)) if (ignoreflags && (*str & CON_HIDDEN))
continue; continue;
c = unicode_encode(out, (*str++ & CON_CHARMASK), outsize-1); c = unicode_encode(out, (*str++ & CON_CHARMASK), outsize-1, !ignoreflags);
if (!c) if (!c)
break; break;
outsize -= c; outsize -= c;

View File

@ -299,18 +299,18 @@ char *COM_DeFunString(conchar_t *str, conchar_t *stop, char *out, int outsize, q
conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t *out, int outsize, int keepmarkup); //ext is usually CON_WHITEMASK, returns its null terminator conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t *out, int outsize, int keepmarkup); //ext is usually CON_WHITEMASK, returns its null terminator
unsigned int utf8_decode(int *error, const void *in, char **out); unsigned int utf8_decode(int *error, const void *in, char **out);
unsigned int utf8_encode(void *out, unsigned int unicode, int maxlen); unsigned int utf8_encode(void *out, unsigned int unicode, int maxlen);
unsigned int iso88591_encode(char *out, unsigned int unicode, int maxlen); unsigned int iso88591_encode(char *out, unsigned int unicode, int maxlen, qboolean markup);
unsigned int qchar_encode(char *out, unsigned int unicode, int maxlen); unsigned int qchar_encode(char *out, unsigned int unicode, int maxlen, qboolean markup);
unsigned int COM_DeQuake(conchar_t chr); unsigned int COM_DeQuake(conchar_t chr);
//handles whatever charset is active, including ^U stuff. //handles whatever charset is active, including ^U stuff.
unsigned int unicode_byteofsfromcharofs(char *str, unsigned int charofs); unsigned int unicode_byteofsfromcharofs(char *str, unsigned int charofs, qboolean markup);
unsigned int unicode_charofsfrombyteofs(char *str, unsigned int byteofs); unsigned int unicode_charofsfrombyteofs(char *str, unsigned int byteofs, qboolean markup);
unsigned int unicode_encode(char *out, unsigned int unicode, int maxlen); unsigned int unicode_encode(char *out, unsigned int unicode, int maxlen, qboolean markup);
unsigned int unicode_decode(int *error, const void *in, char **out); unsigned int unicode_decode(int *error, const void *in, char **out, qboolean markup);
size_t unicode_strtolower(char *in, char *out, size_t outsize); size_t unicode_strtolower(char *in, char *out, size_t outsize, qboolean markup);
size_t unicode_strtoupper(char *in, char *out, size_t outsize); size_t unicode_strtoupper(char *in, char *out, size_t outsize, qboolean markup);
unsigned int unicode_charcount(char *in, size_t buffersize); unsigned int unicode_charcount(char *in, size_t buffersize, qboolean markup);
char *COM_SkipPath (const char *pathname); char *COM_SkipPath (const char *pathname);
void COM_StripExtension (const char *in, char *out, int outlen); void COM_StripExtension (const char *in, char *out, int outlen);

View File

@ -786,11 +786,22 @@ Sets com_filesize and one of handle or file
//returns -1 if couldn't find. //returns -1 if couldn't find.
int FS_FLocateFile(const char *filename, FSLF_ReturnType_e returntype, flocation_t *loc) int FS_FLocateFile(const char *filename, FSLF_ReturnType_e returntype, flocation_t *loc)
{ {
int depth=0, len; int depth=0;
searchpath_t *search; searchpath_t *search;
char cleanpath[MAX_QPATH]; char cleanpath[MAX_QPATH];
flocation_t allownoloc;
void *pf; void *pf;
unsigned int found = FF_NOTFOUND;
if (!loc)
loc = &allownoloc;
loc->index = 0;
loc->offset = 0;
*loc->rawname = 0;
loc->search = NULL;
loc->len = -1;
filename = FS_GetCleanPath(filename, cleanpath, sizeof(cleanpath)); filename = FS_GetCleanPath(filename, cleanpath, sizeof(cleanpath));
if (!filename) if (!filename)
@ -810,60 +821,98 @@ int FS_FLocateFile(const char *filename, FSLF_ReturnType_e returntype, flocation
else else
pf = NULL; pf = NULL;
if (com_purepaths) if (com_purepaths && found == FF_NOTFOUND)
{ {
//check if its in one of the 'pure' packages. these override the default ones.
for (search = com_purepaths ; search ; search = search->nextpure) for (search = com_purepaths ; search ; search = search->nextpure)
{ {
depth += ((search->flags & SPF_EXPLICIT) || returntype == FSLFRT_DEPTH_ANYPATH); depth += ((search->flags & SPF_EXPLICIT) || returntype == FSLFRT_DEPTH_ANYPATH);
fs_finds++; fs_finds++;
if (search->handle->FindFile(search->handle, loc, filename, pf)) found = search->handle->FindFile(search->handle, loc, filename, pf);
{ if (found)
if (loc)
{ {
search->flags |= fs_referencetype; search->flags |= fs_referencetype;
loc->search = search; loc->search = search;
len = loc->len;
}
else
len = 0;
com_file_copyprotected = !!(search->flags & SPF_COPYPROTECTED); com_file_copyprotected = !!(search->flags & SPF_COPYPROTECTED);
com_file_untrusted = !!(search->flags & SPF_UNTRUSTED); com_file_untrusted = !!(search->flags & SPF_UNTRUSTED);
goto out; break;
} }
} }
} }
if (fs_puremode < 2) if (fs_puremode < 2 && found == FF_NOTFOUND)
{ {
// // optionally check the non-pure paths too.
// search through the path, one element at a time
//
for (search = com_searchpaths ; search ; search = search->next) for (search = com_searchpaths ; search ; search = search->next)
{ {
depth += ((search->flags & SPF_EXPLICIT) || returntype == FSLFRT_DEPTH_ANYPATH); depth += ((search->flags & SPF_EXPLICIT) || returntype == FSLFRT_DEPTH_ANYPATH);
fs_finds++; fs_finds++;
if (search->handle->FindFile(search->handle, loc, filename, pf)) found = search->handle->FindFile(search->handle, loc, filename, pf);
if (found)
{ {
search->flags |= fs_referencetype; search->flags |= fs_referencetype;
if (loc)
{
loc->search = search; loc->search = search;
len = loc->len;
}
else
len = 1;
com_file_copyprotected = !!(search->flags & SPF_COPYPROTECTED); com_file_copyprotected = !!(search->flags & SPF_COPYPROTECTED);
com_file_untrusted = !!(search->flags & SPF_UNTRUSTED); com_file_untrusted = !!(search->flags & SPF_UNTRUSTED);
goto out; break;
} }
} }
} }
fail: fail:
if (loc) if (found == FF_SYMLINK)
loc->search = NULL; {
depth = 0x7fffffff; static int blocklink;
len = -1; if (blocklink < 4 && loc->len < MAX_QPATH)
out: {
//read the link target
char *s, *b;
char targname[MAX_QPATH];
char mergedname[MAX_QPATH];
targname[loc->len] = 0;
loc->search->handle->ReadFile(loc->search->handle, loc, targname);
//properlyish unixify
while(s = strchr(targname, '\\'))
*s = '/';
if (*targname == '/')
Q_strncpyz(mergedname, targname+1, sizeof(mergedname));
else
{
Q_strncpyz(mergedname, filename, sizeof(mergedname));
while(s = strchr(mergedname, '\\'))
*s = '/';
b = COM_SkipPath(mergedname);
*b = 0;
for (s = targname; !strncmp(s, "../", 3) && b > mergedname; )
{
s += 3;
if (b[-1] == '/')
*--b = 0;
*b = 0;
b = strrchr(mergedname, '/');
if (b)
*++b = 0;
else
{
//no prefix left.
*mergedname = 0;
break;
}
}
b = mergedname + strlen(mergedname);
Q_strncpyz(b, s, sizeof(mergedname) - (b - mergedname));
}
//and locate that instead.
blocklink++;
depth = FS_FLocateFile(mergedname, returntype, loc);
blocklink--;
if (!loc->search)
Con_Printf("Symlink %s -> %s (%s) is dead\n", filename, targname, mergedname);
return depth;
}
}
/* if (len>=0) /* if (len>=0)
{ {
@ -876,12 +925,20 @@ out:
Con_Printf("Failed\n"); Con_Printf("Failed\n");
*/ */
if (returntype == FSLFRT_IFFOUND) if (returntype == FSLFRT_IFFOUND)
return len != -1; return (found != FF_NOTFOUND) && (loc->len != -1);
else if (returntype == FSLFRT_LENGTH) else if (returntype == FSLFRT_LENGTH)
return len; {
if (found == FF_NOTFOUND)
return -1;
return loc->len;
}
else else
{
if (found == FF_NOTFOUND)
return 0x7fffffff;
return depth; return depth;
} }
}
char *FS_WhichPackForLocation(flocation_t *loc, qboolean makereferenced) char *FS_WhichPackForLocation(flocation_t *loc, qboolean makereferenced)
{ {

View File

@ -2,6 +2,10 @@
#define FSVER 2 #define FSVER 2
#define FF_NOTFOUND 0 //file wasn't found
#define FF_FOUND 1 //file was found
#define FF_SYMLINK 2 //file contents are the name of a different file (symlink). do a recursive lookup on the name
typedef struct typedef struct
{ {
bucket_t buck; bucket_t buck;
@ -19,7 +23,7 @@ struct searchpathfuncs_s
void (QDECL *GetPathDetails)(searchpathfuncs_t *handle, char *outdetails, unsigned int sizeofdetails); void (QDECL *GetPathDetails)(searchpathfuncs_t *handle, char *outdetails, unsigned int sizeofdetails);
void (QDECL *BuildHash)(searchpathfuncs_t *handle, int depth, void (QDECL *FS_AddFileHash)(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle)); void (QDECL *BuildHash)(searchpathfuncs_t *handle, int depth, void (QDECL *FS_AddFileHash)(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle));
qboolean (QDECL *FindFile)(searchpathfuncs_t *handle, flocation_t *loc, const char *name, void *hashedresult); //true if found (hashedresult can be NULL) unsigned int (QDECL *FindFile)(searchpathfuncs_t *handle, flocation_t *loc, const char *name, void *hashedresult); //true if found (hashedresult can be NULL)
//note that if rawfile and offset are set, many Com_FileOpens will read the raw file //note that if rawfile and offset are set, many Com_FileOpens will read the raw file
//otherwise ReadFile will be called instead. //otherwise ReadFile will be called instead.
void (QDECL *ReadFile)(searchpathfuncs_t *handle, flocation_t *loc, char *buffer); //reads the entire file in one go (size comes from loc, so make sure the loc is valid, this is for performance with compressed archives) void (QDECL *ReadFile)(searchpathfuncs_t *handle, flocation_t *loc, char *buffer); //reads the entire file in one go (size comes from loc, so make sure the loc is valid, this is for performance with compressed archives)

View File

@ -77,7 +77,7 @@ static void QDECL FSPAK_ClosePath(searchpathfuncs_t *handle)
Z_Free(pak->files); Z_Free(pak->files);
Z_Free(pak); Z_Free(pak);
} }
void QDECL FSPAK_BuildHash(searchpathfuncs_t *handle, int depth, void (QDECL *AddFileHash)(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle)) static void QDECL FSPAK_BuildHash(searchpathfuncs_t *handle, int depth, void (QDECL *AddFileHash)(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle))
{ {
pack_t *pak = (void*)handle; pack_t *pak = (void*)handle;
int i; int i;
@ -87,7 +87,7 @@ void QDECL FSPAK_BuildHash(searchpathfuncs_t *handle, int depth, void (QDECL *Ad
AddFileHash(depth, pak->files[i].name, &pak->files[i].bucket, &pak->files[i]); AddFileHash(depth, pak->files[i].name, &pak->files[i].bucket, &pak->files[i]);
} }
} }
qboolean QDECL FSPAK_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const char *filename, void *hashedresult) static int QDECL FSPAK_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const char *filename, void *hashedresult)
{ {
mpackfile_t *pf = hashedresult; mpackfile_t *pf = hashedresult;
int i; int i;
@ -98,7 +98,7 @@ qboolean QDECL FSPAK_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const
if (pf) if (pf)
{ //is this a pointer to a file in this pak? { //is this a pointer to a file in this pak?
if (pf < pak->files || pf > pak->files + pak->numfiles) if (pf < pak->files || pf > pak->files + pak->numfiles)
return false; //was found in a different path return FF_NOTFOUND; //was found in a different path
} }
else else
{ {
@ -121,9 +121,9 @@ qboolean QDECL FSPAK_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const
loc->offset = pf->filepos; loc->offset = pf->filepos;
loc->len = pf->filelen; loc->len = pf->filelen;
} }
return true; return FF_FOUND;
} }
return false; return FF_NOTFOUND;
} }
static int QDECL FSPAK_EnumerateFiles (searchpathfuncs_t *handle, const char *match, int (QDECL *func)(const char *, int, void *, searchpathfuncs_t *spath), void *parm) static int QDECL FSPAK_EnumerateFiles (searchpathfuncs_t *handle, const char *match, int (QDECL *func)(const char *, int, void *, searchpathfuncs_t *spath), void *parm)
{ {
@ -142,7 +142,7 @@ static int QDECL FSPAK_EnumerateFiles (searchpathfuncs_t *handle, const char *ma
return true; return true;
} }
int QDECL FSPAK_GeneratePureCRC(searchpathfuncs_t *handle, int seed, int crctype) static int QDECL FSPAK_GeneratePureCRC(searchpathfuncs_t *handle, int seed, int crctype)
{ {
pack_t *pak = (void*)handle; pack_t *pak = (void*)handle;
@ -178,7 +178,7 @@ typedef struct {
unsigned long length; unsigned long length;
unsigned long currentpos; unsigned long currentpos;
} vfspack_t; } vfspack_t;
int QDECL VFSPAK_ReadBytes (struct vfsfile_s *vfs, void *buffer, int bytestoread) static int QDECL VFSPAK_ReadBytes (struct vfsfile_s *vfs, void *buffer, int bytestoread)
{ {
vfspack_t *vfsp = (vfspack_t*)vfs; vfspack_t *vfsp = (vfspack_t*)vfs;
int read; int read;
@ -201,12 +201,12 @@ int QDECL VFSPAK_ReadBytes (struct vfsfile_s *vfs, void *buffer, int bytestoread
return read; return read;
} }
int QDECL VFSPAK_WriteBytes (struct vfsfile_s *vfs, const void *buffer, int bytestoread) static int QDECL VFSPAK_WriteBytes (struct vfsfile_s *vfs, const void *buffer, int bytestoread)
{ //not supported. { //not supported.
Sys_Error("Cannot write to pak files\n"); Sys_Error("Cannot write to pak files\n");
return 0; return 0;
} }
qboolean QDECL VFSPAK_Seek (struct vfsfile_s *vfs, unsigned long pos) static qboolean QDECL VFSPAK_Seek (struct vfsfile_s *vfs, unsigned long pos)
{ {
vfspack_t *vfsp = (vfspack_t*)vfs; vfspack_t *vfsp = (vfspack_t*)vfs;
if (pos < 0 || pos > vfsp->length) if (pos < 0 || pos > vfsp->length)
@ -215,23 +215,23 @@ qboolean QDECL VFSPAK_Seek (struct vfsfile_s *vfs, unsigned long pos)
return true; return true;
} }
unsigned long QDECL VFSPAK_Tell (struct vfsfile_s *vfs) static unsigned long QDECL VFSPAK_Tell (struct vfsfile_s *vfs)
{ {
vfspack_t *vfsp = (vfspack_t*)vfs; vfspack_t *vfsp = (vfspack_t*)vfs;
return vfsp->currentpos - vfsp->startpos; return vfsp->currentpos - vfsp->startpos;
} }
unsigned long QDECL VFSPAK_GetLen (struct vfsfile_s *vfs) static unsigned long QDECL VFSPAK_GetLen (struct vfsfile_s *vfs)
{ {
vfspack_t *vfsp = (vfspack_t*)vfs; vfspack_t *vfsp = (vfspack_t*)vfs;
return vfsp->length; return vfsp->length;
} }
void QDECL VFSPAK_Close(vfsfile_t *vfs) static void QDECL VFSPAK_Close(vfsfile_t *vfs)
{ {
vfspack_t *vfsp = (vfspack_t*)vfs; vfspack_t *vfsp = (vfspack_t*)vfs;
FSPAK_ClosePath(&vfsp->parentpak->pub); //tell the parent that we don't need it open any more (reference counts) FSPAK_ClosePath(&vfsp->parentpak->pub); //tell the parent that we don't need it open any more (reference counts)
Z_Free(vfsp); //free ourselves. Z_Free(vfsp); //free ourselves.
} }
vfsfile_t *QDECL FSPAK_OpenVFS(searchpathfuncs_t *handle, flocation_t *loc, const char *mode) static vfsfile_t *QDECL FSPAK_OpenVFS(searchpathfuncs_t *handle, flocation_t *loc, const char *mode)
{ {
pack_t *pack = (pack_t*)handle; pack_t *pack = (pack_t*)handle;
vfspack_t *vfs; vfspack_t *vfs;
@ -261,7 +261,7 @@ vfsfile_t *QDECL FSPAK_OpenVFS(searchpathfuncs_t *handle, flocation_t *loc, cons
return (vfsfile_t *)vfs; return (vfsfile_t *)vfs;
} }
void QDECL FSPAK_ReadFile(searchpathfuncs_t *handle, flocation_t *loc, char *buffer) static void QDECL FSPAK_ReadFile(searchpathfuncs_t *handle, flocation_t *loc, char *buffer)
{ {
vfsfile_t *f; vfsfile_t *f;
f = FSPAK_OpenVFS(handle, loc, "rb"); f = FSPAK_OpenVFS(handle, loc, "rb");

View File

@ -240,14 +240,14 @@ static void QDECL FSSTDIO_BuildHash(searchpathfuncs_t *handle, int depth, void (
sp->AddFileHash = AddFileHash; sp->AddFileHash = AddFileHash;
Sys_EnumerateFiles(sp->rootpath, "*", FSSTDIO_RebuildFSHash, AddFileHash, handle); Sys_EnumerateFiles(sp->rootpath, "*", FSSTDIO_RebuildFSHash, AddFileHash, handle);
} }
static qboolean QDECL FSSTDIO_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const char *filename, void *hashedresult) static int QDECL FSSTDIO_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const char *filename, void *hashedresult)
{ {
stdiopath_t *sp = (void*)handle; stdiopath_t *sp = (void*)handle;
int len; int len;
char netpath[MAX_OSPATH]; char netpath[MAX_OSPATH];
if (hashedresult && (void *)hashedresult != handle) if (hashedresult && (void *)hashedresult != handle)
return false; return FF_NOTFOUND;
/* /*
if (!static_registered) if (!static_registered)
@ -272,7 +272,7 @@ static qboolean QDECL FSSTDIO_FLocate(searchpathfuncs_t *handle, flocation_t *lo
{ {
FILE *f = fopen(netpath, "rb"); FILE *f = fopen(netpath, "rb");
if (!f) if (!f)
return false; return FF_NOTFOUND;
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
len = ftell(f); len = ftell(f);
@ -286,7 +286,7 @@ static qboolean QDECL FSSTDIO_FLocate(searchpathfuncs_t *handle, flocation_t *lo
loc->index = 0; loc->index = 0;
Q_strncpyz(loc->rawname, netpath, sizeof(loc->rawname)); Q_strncpyz(loc->rawname, netpath, sizeof(loc->rawname));
} }
return true; return FF_FOUND;
} }
static void QDECL FSSTDIO_ReadFile(searchpathfuncs_t *handle, flocation_t *loc, char *buffer) static void QDECL FSSTDIO_ReadFile(searchpathfuncs_t *handle, flocation_t *loc, char *buffer)
{ {

View File

@ -333,7 +333,7 @@ static void QDECL VFSW32_BuildHash(searchpathfuncs_t *handle, int hashdepth, voi
wp->hashdepth = hashdepth; wp->hashdepth = hashdepth;
Sys_EnumerateFiles(wp->rootpath, "*", VFSW32_RebuildFSHash, AddFileHash, handle); Sys_EnumerateFiles(wp->rootpath, "*", VFSW32_RebuildFSHash, AddFileHash, handle);
} }
static qboolean QDECL VFSW32_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const char *filename, void *hashedresult) static int QDECL VFSW32_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const char *filename, void *hashedresult)
{ {
vfsw32path_t *wp = (void*)handle; vfsw32path_t *wp = (void*)handle;
FILE *f; FILE *f;
@ -343,7 +343,7 @@ static qboolean QDECL VFSW32_FLocate(searchpathfuncs_t *handle, flocation_t *loc
if (hashedresult && (void *)hashedresult != wp) if (hashedresult && (void *)hashedresult != wp)
return false; return FF_NOTFOUND;
/* /*
if (!static_registered) if (!static_registered)
@ -361,7 +361,7 @@ static qboolean QDECL VFSW32_FLocate(searchpathfuncs_t *handle, flocation_t *loc
else else
f = _wfopen(widen(wide, sizeof(wide), netpath), L"rb"); f = _wfopen(widen(wide, sizeof(wide), netpath), L"rb");
if (!f) if (!f)
return false; return FF_NOTFOUND;
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
len = ftell(f); len = ftell(f);
@ -374,7 +374,7 @@ static qboolean QDECL VFSW32_FLocate(searchpathfuncs_t *handle, flocation_t *loc
snprintf(loc->rawname, sizeof(loc->rawname), "%s/%s", wp->rootpath, filename); snprintf(loc->rawname, sizeof(loc->rawname), "%s/%s", wp->rootpath, filename);
} }
return true; return FF_FOUND;
} }
static void QDECL VFSW32_ReadFile(searchpathfuncs_t *handle, flocation_t *loc, char *buffer) static void QDECL VFSW32_ReadFile(searchpathfuncs_t *handle, flocation_t *loc, char *buffer)
{ {
@ -398,7 +398,7 @@ static int QDECL VFSW32_EnumerateFiles (searchpathfuncs_t *handle, const char *m
return Sys_EnumerateFiles(wp->rootpath, match, func, parm, handle); return Sys_EnumerateFiles(wp->rootpath, match, func, parm, handle);
} }
qboolean QDECL VFSW32_RenameFile(searchpathfuncs_t *handle, const char *oldfname, const char *newfname) static qboolean QDECL VFSW32_RenameFile(searchpathfuncs_t *handle, const char *oldfname, const char *newfname)
{ {
vfsw32path_t *wp = (vfsw32path_t*)handle; vfsw32path_t *wp = (vfsw32path_t*)handle;
char oldsyspath[MAX_OSPATH]; char oldsyspath[MAX_OSPATH];
@ -407,14 +407,14 @@ qboolean QDECL VFSW32_RenameFile(searchpathfuncs_t *handle, const char *oldfname
snprintf (newsyspath, sizeof(newsyspath)-1, "%s/%s", wp->rootpath, newfname); snprintf (newsyspath, sizeof(newsyspath)-1, "%s/%s", wp->rootpath, newfname);
return Sys_Rename(oldsyspath, newsyspath); return Sys_Rename(oldsyspath, newsyspath);
} }
qboolean QDECL VFSW32_RemoveFile(searchpathfuncs_t *handle, const char *filename) static qboolean QDECL VFSW32_RemoveFile(searchpathfuncs_t *handle, const char *filename)
{ {
vfsw32path_t *wp = (vfsw32path_t*)handle; vfsw32path_t *wp = (vfsw32path_t*)handle;
char syspath[MAX_OSPATH]; char syspath[MAX_OSPATH];
snprintf (syspath, sizeof(syspath)-1, "%s/%s", wp->rootpath, filename); snprintf (syspath, sizeof(syspath)-1, "%s/%s", wp->rootpath, filename);
return Sys_remove(syspath); return Sys_remove(syspath);
} }
qboolean QDECL VFSW32_MkDir(searchpathfuncs_t *handle, const char *filename) static qboolean QDECL VFSW32_MkDir(searchpathfuncs_t *handle, const char *filename)
{ {
vfsw32path_t *wp = (vfsw32path_t*)handle; vfsw32path_t *wp = (vfsw32path_t*)handle;
char syspath[MAX_OSPATH]; char syspath[MAX_OSPATH];

View File

@ -287,18 +287,19 @@ static void QDECL FSZIP_BuildHash(searchpathfuncs_t *handle, int depth, void (QD
AddFileHash(depth, zip->files[i].name, &zip->files[i].bucket, &zip->files[i]); AddFileHash(depth, zip->files[i].name, &zip->files[i].bucket, &zip->files[i]);
} }
} }
static qboolean QDECL FSZIP_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const char *filename, void *hashedresult) static int QDECL FSZIP_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const char *filename, void *hashedresult)
{ {
zpackfile_t *pf = hashedresult; zpackfile_t *pf = hashedresult;
int i; int i;
zipfile_t *zip = (void*)handle; zipfile_t *zip = (void*)handle;
int ret = FF_NOTFOUND;
// look through all the pak file elements // look through all the pak file elements
if (pf) if (pf)
{ //is this a pointer to a file in this pak? { //is this a pointer to a file in this pak?
if (pf < zip->files || pf >= zip->files + zip->numfiles) if (pf < zip->files || pf >= zip->files + zip->numfiles)
return false; //was found in a different path return FF_NOTFOUND; //was found in a different path
} }
else else
{ {
@ -314,6 +315,7 @@ static qboolean QDECL FSZIP_FLocate(searchpathfuncs_t *handle, flocation_t *loc,
if (pf) if (pf)
{ {
ret = FF_FOUND;
if (loc) if (loc)
{ {
loc->index = pf - zip->files; loc->index = pf - zip->files;
@ -321,7 +323,8 @@ static qboolean QDECL FSZIP_FLocate(searchpathfuncs_t *handle, flocation_t *loc,
loc->offset = pf->filepos; loc->offset = pf->filepos;
loc->len = pf->filelen; loc->len = pf->filelen;
unzLocateFileMy (zip->handle, loc->index, zip->files[loc->index].filepos); if (unzLocateFileMy (zip->handle, loc->index, zip->files[loc->index].filepos) == 2)
ret = FF_SYMLINK;
loc->offset = unzGetCurrentFileUncompressedPos(zip->handle); loc->offset = unzGetCurrentFileUncompressedPos(zip->handle);
// if (loc->offset<0) // if (loc->offset<0)
// { //file not found, or is compressed. // { //file not found, or is compressed.
@ -329,9 +332,11 @@ static qboolean QDECL FSZIP_FLocate(searchpathfuncs_t *handle, flocation_t *loc,
// loc->offset=0; // loc->offset=0;
// } // }
} }
return true; else
ret = FF_FOUND;
return ret;
} }
return false; return FF_NOTFOUND;
} }
static void QDECL FSZIP_ReadFile(searchpathfuncs_t *handle, flocation_t *loc, char *buffer) static void QDECL FSZIP_ReadFile(searchpathfuncs_t *handle, flocation_t *loc, char *buffer)

View File

@ -360,8 +360,8 @@ static vec2_t *map_vertstmexcoords;
static vec2_t *map_vertlstmexcoords[MAXRLIGHTMAPS]; static vec2_t *map_vertlstmexcoords[MAXRLIGHTMAPS];
static vec4_t *map_colors4f_array[MAXRLIGHTMAPS]; static vec4_t *map_colors4f_array[MAXRLIGHTMAPS];
static vec3_t *map_normals_array; static vec3_t *map_normals_array;
static vec3_t *map_svector_array; //static vec3_t *map_svector_array;
static vec3_t *map_tvector_array; //static vec3_t *map_tvector_array;
q3cface_t *map_faces; q3cface_t *map_faces;
static int numfaces; static int numfaces;
@ -2085,7 +2085,8 @@ qboolean CModQ3_LoadVertexes (lump_t *l)
{ {
q3dvertex_t *in; q3dvertex_t *in;
vecV_t *out; vecV_t *out;
vec3_t *nout, *sout, *tout; vec3_t *nout;
//, *sout, *tout;
int i, count, j; int i, count, j;
vec2_t *lmout, *stout; vec2_t *lmout, *stout;
vec4_t *cout; vec4_t *cout;
@ -2109,8 +2110,8 @@ qboolean CModQ3_LoadVertexes (lump_t *l)
lmout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*lmout)); lmout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*lmout));
cout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*cout)); cout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*cout));
nout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*nout)); nout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*nout));
sout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*nout)); // sout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*nout));
tout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*nout)); // tout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*nout));
map_verts = out; map_verts = out;
map_vertstmexcoords = stout; map_vertstmexcoords = stout;
for (i = 0; i < MAXRLIGHTMAPS; i++) for (i = 0; i < MAXRLIGHTMAPS; i++)
@ -2119,8 +2120,8 @@ qboolean CModQ3_LoadVertexes (lump_t *l)
map_colors4f_array[i] = cout; map_colors4f_array[i] = cout;
} }
map_normals_array = nout; map_normals_array = nout;
map_svector_array = sout; // map_svector_array = sout;
map_tvector_array = tout; // map_tvector_array = tout;
numvertexes = count; numvertexes = count;
for ( i=0 ; i<count ; i++, in++) for ( i=0 ; i<count ; i++, in++)
@ -2148,7 +2149,8 @@ qboolean CModRBSP_LoadVertexes (lump_t *l)
{ {
rbspvertex_t *in; rbspvertex_t *in;
vecV_t *out; vecV_t *out;
vec3_t *nout, *sout, *tout; vec3_t *nout;
//, *sout, *tout;
int i, count, j; int i, count, j;
vec2_t *lmout, *stout; vec2_t *lmout, *stout;
vec4_t *cout; vec4_t *cout;
@ -2173,8 +2175,8 @@ qboolean CModRBSP_LoadVertexes (lump_t *l)
lmout = ZG_Malloc(&loadmodel->memgroup, MAXRLIGHTMAPS*count*sizeof(*lmout)); lmout = ZG_Malloc(&loadmodel->memgroup, MAXRLIGHTMAPS*count*sizeof(*lmout));
cout = ZG_Malloc(&loadmodel->memgroup, MAXRLIGHTMAPS*count*sizeof(*cout)); cout = ZG_Malloc(&loadmodel->memgroup, MAXRLIGHTMAPS*count*sizeof(*cout));
nout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*nout)); nout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*nout));
sout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*sout)); // sout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*sout));
tout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*tout)); // tout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*tout));
map_verts = out; map_verts = out;
map_vertstmexcoords = stout; map_vertstmexcoords = stout;
for (sty = 0; sty < MAXRLIGHTMAPS; sty++) for (sty = 0; sty < MAXRLIGHTMAPS; sty++)
@ -2183,8 +2185,8 @@ qboolean CModRBSP_LoadVertexes (lump_t *l)
map_colors4f_array[sty] = cout + sty*count; map_colors4f_array[sty] = cout + sty*count;
} }
map_normals_array = nout; map_normals_array = nout;
map_svector_array = sout; // map_svector_array = sout;
map_tvector_array = tout; // map_tvector_array = tout;
numvertexes = count; numvertexes = count;
for ( i=0 ; i<count ; i++, in++) for ( i=0 ; i<count ; i++, in++)

View File

@ -77,7 +77,7 @@ typedef struct trailstate_s {
#define PARTICLE_Z_CLIP 8.0 #define PARTICLE_Z_CLIP 8.0
typedef enum { BM_BLEND, BM_BLENDCOLOUR, BM_ADD, BM_SUBTRACT, BM_INVMODA, BM_INVMODC } blendmode_t; typedef enum { BM_BLEND, BM_BLENDCOLOUR, BM_ADDA, BM_ADDC, BM_SUBTRACT, BM_INVMODA, BM_INVMODC } blendmode_t;
#define frandom() (rand()*(1.0f/RAND_MAX)) #define frandom() (rand()*(1.0f/RAND_MAX))
#define crandom() (rand()*(2.0f/RAND_MAX)-1.0f) #define crandom() (rand()*(2.0f/RAND_MAX)-1.0f)

View File

@ -27,10 +27,6 @@ float frametime;
vec3_t forward, right, up; vec3_t forward, right, up;
vec3_t player_mins = {-16, -16, -24};
vec3_t player_maxs = {16, 16, 32};
void PM_Init (void) void PM_Init (void)
{ {
PM_InitBoxHull(); PM_InitBoxHull();
@ -89,6 +85,50 @@ void PM_ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce)
} }
} }
#include "pr_common.h"
static qboolean PM_PortalTransform(world_t *w, int portalnum, vec3_t org, vec3_t move)
{
qboolean okay = true;
wedict_t *portal = WEDICT_NUM(w->progs, portalnum);
int oself = *w->g.self;
void *pr_globals = PR_globals(w->progs, PR_CURRENT);
*w->g.self = EDICT_TO_PROG(w->progs, portal);
//transform origin+velocity etc
VectorCopy(org, G_VECTOR(OFS_PARM0));
VectorCopy(pmove.angles, G_VECTOR(OFS_PARM1));
VectorCopy(pmove.velocity, w->g.v_forward);
VectorCopy(move, w->g.v_right);
VectorCopy(pmove.gravitydir, w->g.v_up);
if (!DotProduct(w->g.v_up, w->g.v_up))
w->g.v_up[2] = -1;
PR_ExecuteProgram (w->progs, portal->xv->camera_transform);
//make sure the new origin is okay for the player. back out if its invalid.
if (!PM_TestPlayerPosition(G_VECTOR(OFS_RETURN)))
okay = false;
else
{
VectorCopy(G_VECTOR(OFS_RETURN), org);
VectorCopy(w->g.v_forward, pmove.velocity);
VectorCopy(w->g.v_right, move);
VectorCopy(w->g.v_up, pmove.gravitydir);
//transform the angles too
VectorCopy(org, G_VECTOR(OFS_PARM0));
pmove.angles[0] *= -1;
VectorCopy(pmove.angles, G_VECTOR(OFS_PARM1));
AngleVectors(pmove.angles, w->g.v_forward, w->g.v_right, w->g.v_up);
PR_ExecuteProgram (w->progs, portal->xv->camera_transform);
VectorAngles(w->g.v_forward, w->g.v_up, pmove.angles);
pmove.angles[0] *= -1;
}
*w->g.self = oself;
return okay;
}
/* /*
============ ============
@ -131,6 +171,33 @@ int PM_SlideMove (void)
trace = PM_PlayerTrace (pmove.origin, end, MASK_PLAYERSOLID); trace = PM_PlayerTrace (pmove.origin, end, MASK_PLAYERSOLID);
if (trace.entnum >= 0 && pmove.world)
{
physent_t *impact = &pmove.physents[trace.entnum];
if (impact->isportal)
{
vec3_t move;
vec3_t from;
float firstfrac = trace.fraction;
VectorCopy(trace.endpos, from); //just in case
VectorSubtract(end, trace.endpos, move);
if (PM_PortalTransform(pmove.world, impact->info, from, move))
{
VectorAdd(from, move, end);
//if we follow the portal, then we basically need to restart from the other side.
time_left -= time_left * trace.fraction;
VectorCopy (pmove.velocity, primal_velocity);
VectorCopy (pmove.velocity, original_velocity);
numplanes = 0;
trace = PM_PlayerTrace (from, end, MASK_PLAYERSOLID);
}
}
}
if (trace.startsolid || trace.allsolid) if (trace.startsolid || trace.allsolid)
{ // entity is trapped in another solid { // entity is trapped in another solid
VectorClear (pmove.velocity); VectorClear (pmove.velocity);
@ -394,7 +461,7 @@ void PM_Friction (void)
// if the leading edge is over a dropoff, increase friction // if the leading edge is over a dropoff, increase friction
start[0] = stop[0] = pmove.origin[0] + pmove.velocity[0]/speed*16; start[0] = stop[0] = pmove.origin[0] + pmove.velocity[0]/speed*16;
start[1] = stop[1] = pmove.origin[1] + pmove.velocity[1]/speed*16; start[1] = stop[1] = pmove.origin[1] + pmove.velocity[1]/speed*16;
start[2] = pmove.origin[2] + player_mins[2]; start[2] = pmove.origin[2] + pmove.player_mins[2];
stop[2] = start[2] - 34; stop[2] = start[2] - 34;
trace = PM_PlayerTrace (start, stop, MASK_PLAYERSOLID); trace = PM_PlayerTrace (start, stop, MASK_PLAYERSOLID);
if (trace.fraction == 1) if (trace.fraction == 1)
@ -725,12 +792,12 @@ void PM_CategorizePosition (void)
if (pmove.pm_type == PM_WALLWALK) if (pmove.pm_type == PM_WALLWALK)
{ {
vec3_t tmin,tmax; vec3_t tmin,tmax;
VectorCopy(player_mins, tmin); VectorCopy(pmove.player_mins, tmin);
VectorCopy(player_maxs, tmax); VectorCopy(pmove.player_maxs, tmax);
VectorMA(pmove.origin, -48, up, point); VectorMA(pmove.origin, -48, up, point);
trace = PM_TraceLine(pmove.origin, point); trace = PM_TraceLine(pmove.origin, point);
VectorCopy(tmin, player_mins); VectorCopy(tmin, pmove.player_mins);
VectorCopy(tmax, player_maxs); VectorCopy(tmax, pmove.player_maxs);
if (trace.fraction < 1) if (trace.fraction < 1)
VectorNegate(trace.plane.normal, pmove.gravitydir); VectorNegate(trace.plane.normal, pmove.gravitydir);
@ -771,19 +838,19 @@ void PM_CategorizePosition (void)
pmove.waterlevel = 0; pmove.waterlevel = 0;
pmove.watertype = FTECONTENTS_EMPTY; pmove.watertype = FTECONTENTS_EMPTY;
point[2] = pmove.origin[2] + player_mins[2] + 1; point[2] = pmove.origin[2] + pmove.player_mins[2] + 1;
cont = PM_PointContents (point); cont = PM_PointContents (point);
if (cont & FTECONTENTS_FLUID) if (cont & FTECONTENTS_FLUID)
{ {
pmove.watertype = cont; pmove.watertype = cont;
pmove.waterlevel = 1; pmove.waterlevel = 1;
point[2] = pmove.origin[2] + (player_mins[2] + player_maxs[2])*0.5; point[2] = pmove.origin[2] + (pmove.player_mins[2] + pmove.player_maxs[2])*0.5;
cont = PM_PointContents (point); cont = PM_PointContents (point);
if (cont & FTECONTENTS_FLUID) if (cont & FTECONTENTS_FLUID)
{ {
pmove.waterlevel = 2; pmove.waterlevel = 2;
point[2] = pmove.origin[2] + player_mins[2]+24+DEFAULT_VIEWHEIGHT; point[2] = pmove.origin[2] + pmove.player_mins[2]+24+DEFAULT_VIEWHEIGHT;
cont = PM_PointContents (point); cont = PM_PointContents (point);
if (cont & FTECONTENTS_FLUID) if (cont & FTECONTENTS_FLUID)
pmove.waterlevel = 3; pmove.waterlevel = 3;
@ -807,7 +874,7 @@ void PM_CategorizePosition (void)
VectorMA (pmove.origin, 24, flatforward, fwd1); VectorMA (pmove.origin, 24, flatforward, fwd1);
t = CM_BoxTrace(pmove.physents[0].model, pmove.origin, fwd1, player_mins, player_maxs, MASK_PLAYERSOLID); t = CM_BoxTrace(pmove.physents[0].model, pmove.origin, fwd1, pmove.player_mins, pmove.player_maxs, MASK_PLAYERSOLID);
if (t.surface->flags & Q3SURF_LADDER) if (t.surface->flags & Q3SURF_LADDER)
{ {
pmove.onladder = true; pmove.onladder = true;
@ -945,7 +1012,7 @@ void PM_CheckWaterJump (void)
VectorNormalize (flatforward); VectorNormalize (flatforward);
VectorMA (pmove.origin, 24, flatforward, spot); VectorMA (pmove.origin, 24, flatforward, spot);
spot[2] += 8 + 24+player_mins[2]; //hexen2 fix. calculated from the normal bottom of bbox spot[2] += 8 + 24+pmove.player_mins[2]; //hexen2 fix. calculated from the normal bottom of bbox
cont = PM_PointContents (spot); cont = PM_PointContents (spot);
if (!(cont & FTECONTENTS_SOLID)) if (!(cont & FTECONTENTS_SOLID))
return; return;

View File

@ -42,9 +42,10 @@ typedef struct
vec3_t angles; vec3_t angles;
model_t *model; // only for bsp models model_t *model; // only for bsp models
vec3_t mins, maxs; // only for non-bsp models vec3_t mins, maxs; // only for non-bsp models
unsigned short info; // for client or server to identify unsigned int info; // for client or server to identify
qbyte nonsolid; qbyte nonsolid; //contributes to contents, but does not block. FIXME: why not just use the contentsmask directly?
qbyte notouch; qbyte notouch; //don't trigger touch events. FIXME: why are these entities even in the list?
qbyte isportal; //special portal traversion required
unsigned int forcecontentsmask; unsigned int forcecontentsmask;
} physent_t; } physent_t;
@ -62,6 +63,8 @@ typedef struct
int jump_msec; // msec since last jump int jump_msec; // msec since last jump
float waterjumptime; float waterjumptime;
int pm_type; int pm_type;
vec3_t player_mins;
vec3_t player_maxs;
// world state // world state
int numphysent; int numphysent;
@ -82,6 +85,8 @@ typedef struct
// when onground is true // when onground is true
int waterlevel; int waterlevel;
int watertype; int watertype;
struct world_s *world;
} playermove_t; } playermove_t;
typedef struct { typedef struct {

View File

@ -19,15 +19,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include "quakedef.h" #include "quakedef.h"
static qboolean PM_TransformedHullCheck (model_t *model, vec3_t start, vec3_t end, trace_t *trace, vec3_t origin, vec3_t angles); static qboolean PM_TransformedHullCheck (model_t *model, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace, vec3_t origin, vec3_t angles);
int Q1BSP_HullPointContents(hull_t *hull, vec3_t p); int Q1BSP_HullPointContents(hull_t *hull, vec3_t p);
static hull_t box_hull; static hull_t box_hull;
static mclipnode_t box_clipnodes[6]; static mclipnode_t box_clipnodes[6];
static mplane_t box_planes[6]; static mplane_t box_planes[6];
extern vec3_t player_mins;
extern vec3_t player_maxs;
/* /*
=================== ===================
PM_InitBoxHull PM_InitBoxHull
@ -185,7 +182,7 @@ int PM_ExtraBoxContents (vec3_t p)
{ {
if (pe->forcecontentsmask) if (pe->forcecontentsmask)
{ {
if (!PM_TransformedHullCheck(pm, p, p, &tr, pe->origin, pe->angles)) if (!PM_TransformedHullCheck(pm, p, p, pmove.player_mins, pmove.player_maxs, &tr, pe->origin, pe->angles))
continue; continue;
if (tr.startsolid) if (tr.startsolid)
pc |= pe->forcecontentsmask; pc |= pe->forcecontentsmask;
@ -193,9 +190,9 @@ int PM_ExtraBoxContents (vec3_t p)
} }
else if (pe->forcecontentsmask) else if (pe->forcecontentsmask)
{ {
if (p[0]+player_maxs[0] >= pe->origin[0]+pe->mins[0] && p[0]+player_mins[0] <= pe->origin[0]+pe->maxs[0] && if (p[0]+pmove.player_maxs[0] >= pe->origin[0]+pe->mins[0] && p[0]+pmove.player_mins[0] <= pe->origin[0]+pe->maxs[0] &&
p[1]+player_maxs[1] >= pe->origin[1]+pe->mins[1] && p[1]+player_mins[1] <= pe->origin[1]+pe->maxs[1] && p[1]+pmove.player_maxs[1] >= pe->origin[1]+pe->mins[1] && p[1]+pmove.player_mins[1] <= pe->origin[1]+pe->maxs[1] &&
p[2]+player_maxs[2] >= pe->origin[2]+pe->mins[2] && p[2]+player_mins[2] <= pe->origin[2]+pe->maxs[2]) p[2]+pmove.player_maxs[2] >= pe->origin[2]+pe->mins[2] && p[2]+pmove.player_mins[2] <= pe->origin[2]+pe->maxs[2])
pc |= pe->forcecontentsmask; pc |= pe->forcecontentsmask;
} }
} }
@ -212,7 +209,7 @@ LINE TESTING IN HULLS
*/ */
/*returns if it actually did a trace*/ /*returns if it actually did a trace*/
static qboolean PM_TransformedHullCheck (model_t *model, vec3_t start, vec3_t end, trace_t *trace, vec3_t origin, vec3_t angles) static qboolean PM_TransformedHullCheck (model_t *model, vec3_t start, vec3_t end, vec3_t player_mins, vec3_t player_maxs, trace_t *trace, vec3_t origin, vec3_t angles)
{ {
vec3_t start_l, end_l; vec3_t start_l, end_l;
int i; int i;
@ -284,7 +281,7 @@ qboolean PM_TestPlayerPosition (vec3_t pos)
if (pe->info == pmove.skipent) if (pe->info == pmove.skipent)
continue; continue;
if (pe->nonsolid) if (pe->nonsolid || pe->isportal)
continue; continue;
if (pe->forcecontentsmask && !(pe->forcecontentsmask & MASK_PLAYERSOLID)) if (pe->forcecontentsmask && !(pe->forcecontentsmask & MASK_PLAYERSOLID))
@ -293,15 +290,15 @@ qboolean PM_TestPlayerPosition (vec3_t pos)
// get the clipping hull // get the clipping hull
if (pe->model) if (pe->model)
{ {
if (!PM_TransformedHullCheck (pe->model, pos, pos, &trace, pe->origin, pe->angles)) if (!PM_TransformedHullCheck (pe->model, pos, pos, pmove.player_mins, pmove.player_maxs, &trace, pe->origin, pe->angles))
continue; continue;
if (trace.allsolid) if (trace.allsolid)
return false; //solid return false; //solid
} }
else else
{ {
VectorSubtract (pe->mins, player_maxs, mins); VectorSubtract (pe->mins, pmove.player_maxs, mins);
VectorSubtract (pe->maxs, player_mins, maxs); VectorSubtract (pe->maxs, pmove.player_mins, maxs);
hull = PM_HullForBox (mins, maxs); hull = PM_HullForBox (mins, maxs);
VectorSubtract(pos, pe->origin, mins); VectorSubtract(pos, pe->origin, mins);
@ -345,23 +342,33 @@ trace_t PM_PlayerTrace (vec3_t start, vec3_t end, unsigned int solidmask)
{ {
vec3_t mins, maxs; vec3_t mins, maxs;
VectorSubtract (pe->mins, player_maxs, mins); VectorSubtract (pe->mins, pmove.player_maxs, mins);
VectorSubtract (pe->maxs, player_mins, maxs); VectorSubtract (pe->maxs, pmove.player_mins, maxs);
PM_HullForBox (mins, maxs); PM_HullForBox (mins, maxs);
// trace a line through the apropriate clipping hull // trace a line through the apropriate clipping hull
if (!PM_TransformedHullCheck (NULL, start, end, &trace, pe->origin, pe->angles)) if (!PM_TransformedHullCheck (NULL, start, end, pmove.player_mins, pmove.player_maxs, &trace, pe->origin, pe->angles))
continue;
}
else if (pe->isportal)
{
// trace a line through the apropriate clipping hull
if (!PM_TransformedHullCheck (pe->model, start, end, vec3_origin, vec3_origin, &trace, pe->origin, pe->angles))
continue; continue;
} }
else else
{ {
// trace a line through the apropriate clipping hull // trace a line through the apropriate clipping hull
if (!PM_TransformedHullCheck (pe->model, start, end, &trace, pe->origin, pe->angles)) if (!PM_TransformedHullCheck (pe->model, start, end, pmove.player_mins, pmove.player_maxs, &trace, pe->origin, pe->angles))
continue; continue;
} }
if (trace.allsolid) if (trace.allsolid)
trace.startsolid = true; trace.startsolid = true;
if (trace.startsolid && pe->isportal)
continue;
if (trace.startsolid) if (trace.startsolid)
{ {
// if (!pmove.physents[i].model) //caught inside annother model // if (!pmove.physents[i].model) //caught inside annother model
@ -385,7 +392,7 @@ trace_t PM_PlayerTrace (vec3_t start, vec3_t end, unsigned int solidmask)
//for use outside the pmove code. lame, but works. //for use outside the pmove code. lame, but works.
trace_t PM_TraceLine (vec3_t start, vec3_t end) trace_t PM_TraceLine (vec3_t start, vec3_t end)
{ {
VectorClear(player_mins); VectorClear(pmove.player_mins);
VectorClear(player_maxs); VectorClear(pmove.player_maxs);
return PM_PlayerTrace(start, end, MASK_PLAYERSOLID); return PM_PlayerTrace(start, end, MASK_PLAYERSOLID);
} }

View File

@ -9,6 +9,8 @@
#include <ctype.h> #include <ctype.h>
#define VMUTF8 0 #define VMUTF8 0
#define VMUTF8MARKUP false
static char *cvargroup_progs = "Progs variables"; static char *cvargroup_progs = "Progs variables";
@ -2017,9 +2019,9 @@ void QCBUILTIN PF_strncasecmp (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
if (VMUTF8) if (VMUTF8)
{ {
aofs = aofs?unicode_byteofsfromcharofs(a, aofs):0; aofs = aofs?unicode_byteofsfromcharofs(a, aofs, VMUTF8MARKUP):0;
bofs = bofs?unicode_byteofsfromcharofs(b, bofs):0; bofs = bofs?unicode_byteofsfromcharofs(b, bofs, VMUTF8MARKUP):0;
len = max(unicode_byteofsfromcharofs(a+aofs, len), unicode_byteofsfromcharofs(b+bofs, len)); len = max(unicode_byteofsfromcharofs(a+aofs, len, VMUTF8MARKUP), unicode_byteofsfromcharofs(b+bofs, len, VMUTF8MARKUP));
} }
else else
{ {
@ -2050,9 +2052,9 @@ void QCBUILTIN PF_strncmp (pubprogfuncs_t *prinst, struct globalvars_s *pr_globa
if (VMUTF8) if (VMUTF8)
{ {
aofs = aofs?unicode_byteofsfromcharofs(a, aofs):0; aofs = aofs?unicode_byteofsfromcharofs(a, aofs, VMUTF8MARKUP):0;
bofs = bofs?unicode_byteofsfromcharofs(b, bofs):0; bofs = bofs?unicode_byteofsfromcharofs(b, bofs, VMUTF8MARKUP):0;
len = max(unicode_byteofsfromcharofs(a+aofs, len), unicode_byteofsfromcharofs(b+bofs, len)); len = max(unicode_byteofsfromcharofs(a+aofs, len, VMUTF8MARKUP), unicode_byteofsfromcharofs(b+bofs, len, VMUTF8MARKUP));
} }
else else
{ {
@ -2280,7 +2282,7 @@ void QCBUILTIN PF_chr2str (pubprogfuncs_t *prinst, struct globalvars_s *pr_globa
{ {
ch = G_FLOAT(OFS_PARM0 + i*3); ch = G_FLOAT(OFS_PARM0 + i*3);
if (VMUTF8 || ch > 0xff) if (VMUTF8 || ch > 0xff)
s += unicode_encode(s, ch, (string+sizeof(string)-1)-s); s += unicode_encode(s, ch, (string+sizeof(string)-1)-s, VMUTF8MARKUP);
else else
*s++ = G_FLOAT(OFS_PARM0 + i*3); *s++ = G_FLOAT(OFS_PARM0 + i*3);
} }
@ -2300,8 +2302,8 @@ void QCBUILTIN PF_str2chr (pubprogfuncs_t *prinst, struct globalvars_s *pr_globa
if (VMUTF8) if (VMUTF8)
{ {
if (ofs < 0) if (ofs < 0)
ofs = unicode_charcount(instr, 1<<30)+ofs; ofs = unicode_charcount(instr, 1<<30, VMUTF8MARKUP)+ofs;
ofs = unicode_byteofsfromcharofs(instr, ofs); ofs = unicode_byteofsfromcharofs(instr, ofs, VMUTF8MARKUP);
} }
else else
{ {
@ -2312,7 +2314,7 @@ void QCBUILTIN PF_str2chr (pubprogfuncs_t *prinst, struct globalvars_s *pr_globa
if (ofs && (ofs < 0 || ofs > strlen(instr))) if (ofs && (ofs < 0 || ofs > strlen(instr)))
G_FLOAT(OFS_RETURN) = '\0'; G_FLOAT(OFS_RETURN) = '\0';
else else
G_FLOAT(OFS_RETURN) = VMUTF8?unicode_decode(&err, instr+ofs, &next):(unsigned char)instr[ofs]; G_FLOAT(OFS_RETURN) = VMUTF8?unicode_decode(&err, instr+ofs, &next, VMUTF8MARKUP):(unsigned char)instr[ofs];
} }
//FTE_STRINGS //FTE_STRINGS
@ -2325,7 +2327,7 @@ void QCBUILTIN PF_strstrofs (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
int firstofs = (prinst->callargc>2)?G_FLOAT(OFS_PARM2):0; int firstofs = (prinst->callargc>2)?G_FLOAT(OFS_PARM2):0;
if (VMUTF8) if (VMUTF8)
firstofs = unicode_byteofsfromcharofs(instr, firstofs); firstofs = unicode_byteofsfromcharofs(instr, firstofs, VMUTF8MARKUP);
if (firstofs && (firstofs < 0 || firstofs > strlen(instr))) if (firstofs && (firstofs < 0 || firstofs > strlen(instr)))
{ {
@ -2337,7 +2339,7 @@ void QCBUILTIN PF_strstrofs (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
if (!match) if (!match)
G_FLOAT(OFS_RETURN) = -1; G_FLOAT(OFS_RETURN) = -1;
else else
G_FLOAT(OFS_RETURN) = VMUTF8?unicode_charofsfrombyteofs(instr, match-instr):(match - instr); G_FLOAT(OFS_RETURN) = VMUTF8?unicode_charofsfrombyteofs(instr, match-instr, VMUTF8MARKUP):(match - instr);
} }
//float(string input) stof //float(string input) stof
@ -2519,7 +2521,7 @@ void QCBUILTIN PF_substring (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
//UTF-8-FIXME: start+length are chars not bytes... //UTF-8-FIXME: start+length are chars not bytes...
if (VMUTF8) if (VMUTF8)
slen = unicode_charcount(s, 1<<30); slen = unicode_charcount(s, 1<<30, VMUTF8MARKUP);
else else
slen = strlen(s); slen = strlen(s);
@ -2545,8 +2547,8 @@ void QCBUILTIN PF_substring (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
if (VMUTF8) if (VMUTF8)
{ {
start = unicode_byteofsfromcharofs(s, start); start = unicode_byteofsfromcharofs(s, start, VMUTF8MARKUP);
length = unicode_byteofsfromcharofs(s+start, length); length = unicode_byteofsfromcharofs(s+start, length, VMUTF8MARKUP);
} }
s += start; s += start;
@ -2559,7 +2561,7 @@ void QCBUILTIN PF_substring (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
void QCBUILTIN PF_strlen(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) void QCBUILTIN PF_strlen(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
if (VMUTF8) if (VMUTF8)
G_FLOAT(OFS_RETURN) = unicode_charcount(PR_GetStringOfs(prinst, OFS_PARM0), 1<<30); G_FLOAT(OFS_RETURN) = unicode_charcount(PR_GetStringOfs(prinst, OFS_PARM0), 1<<30, VMUTF8MARKUP);
else else
G_FLOAT(OFS_RETURN) = strlen(PR_GetStringOfs(prinst, OFS_PARM0)); G_FLOAT(OFS_RETURN) = strlen(PR_GetStringOfs(prinst, OFS_PARM0));
} }
@ -2691,7 +2693,7 @@ void QCBUILTIN PF_strtolower (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
char *in = PR_GetStringOfs(prinst, OFS_PARM0); char *in = PR_GetStringOfs(prinst, OFS_PARM0);
char result[8192]; char result[8192];
unicode_strtolower(in, result, sizeof(result)); unicode_strtolower(in, result, sizeof(result), VMUTF8MARKUP);
RETURN_TSTRING(result); RETURN_TSTRING(result);
} }
@ -2702,7 +2704,7 @@ void QCBUILTIN PF_strtoupper (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
char *in = PR_GetStringOfs(prinst, OFS_PARM0); char *in = PR_GetStringOfs(prinst, OFS_PARM0);
char result[8192]; char result[8192];
unicode_strtoupper(in, result, sizeof(result)); unicode_strtoupper(in, result, sizeof(result), VMUTF8MARKUP);
RETURN_TSTRING(result); RETURN_TSTRING(result);
} }
@ -2724,7 +2726,7 @@ void QCBUILTIN PF_strftime (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
else else
tm = gmtime(&ctime); tm = gmtime(&ctime);
strftime(result, sizeof(result), in, tm); strftime(result, sizeof(result), in, tm);
unicode_strtoupper(result, uresult, sizeof(uresult)); unicode_strtoupper(result, uresult, sizeof(uresult), VMUTF8MARKUP);
RETURN_TSTRING(uresult); RETURN_TSTRING(uresult);
} }
@ -3762,7 +3764,94 @@ void QCBUILTIN PF_randomvector (pubprogfuncs_t *prinst, struct globalvars_s *pr_
VectorCopy (temp, G_VECTOR(OFS_RETURN)); VectorCopy (temp, G_VECTOR(OFS_RETURN));
} }
/*
==============
PF_changeyaw
This was a major timewaster in progs, so it was converted to C
FIXME: add gravitydir support
==============
*/
void QCBUILTIN PF_changeyaw (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
edict_t *ent;
float ideal, current, move, speed;
ent = PROG_TO_EDICT(prinst, pr_global_struct->self);
current = anglemod( ent->v->angles[1] );
ideal = ent->v->ideal_yaw;
speed = ent->v->yaw_speed;
if (current == ideal)
return;
move = ideal - current;
if (ideal > current)
{
if (move >= 180)
move = move - 360;
}
else
{
if (move <= -180)
move = move + 360;
}
if (move > 0)
{
if (move > speed)
move = speed;
}
else
{
if (move < -speed)
move = -speed;
}
ent->v->angles[1] = anglemod (current + move);
}
//void() changepitch = #63;
//FIXME: support gravitydir
void QCBUILTIN PF_changepitch (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
edict_t *ent;
float ideal, current, move, speed;
ent = PROG_TO_EDICT(prinst, pr_global_struct->self);
current = anglemod( ent->v->angles[1] );
ideal = ent->xv->idealpitch;
speed = ent->xv->pitch_speed;
if (current == ideal)
return;
move = ideal - current;
if (ideal > current)
{
if (move >= 180)
move = move - 360;
}
else
{
if (move <= -180)
move = move + 360;
}
if (move > 0)
{
if (move > speed)
move = speed;
}
else
{
if (move < -speed)
move = -speed;
}
ent->v->angles[1] = anglemod (current + move);
}
//float vectoyaw(vector) //float vectoyaw(vector)
//FIXME: support gravitydir
void QCBUILTIN PF_vectoyaw (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) void QCBUILTIN PF_vectoyaw (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
float *value1; float *value1;

View File

@ -141,6 +141,8 @@ void QCBUILTIN PF_fputs (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals
void QCBUILTIN PF_fgets (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_fgets (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_normalize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_normalize (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_vlen (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_vlen (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_changeyaw (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_changepitch (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_vectoyaw (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_vectoyaw (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_vectoangles (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_vectoangles (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_rotatevectorsbyangles (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_rotatevectorsbyangles (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);

View File

@ -388,16 +388,20 @@ struct traceinfo_s
#if 0 #if 0
#include "shader.h" #include "shader.h"
void TestDrawPlane(float *normal, float dist, float r, float g, float b) void BE_GenPolyBatches(batch_t **batches);
void TestDrawPlane(float *normal, float dist, float r, float g, float b, qboolean enqueue)
{ {
scenetris_t *t; scenetris_t *t;
if (!enqueue)
cl_numstris = 0;
if (cl_numstris == cl_maxstris) if (cl_numstris == cl_maxstris)
{ {
cl_maxstris+=8; cl_maxstris+=8;
cl_stris = BZ_Realloc(cl_stris, sizeof(*cl_stris)*cl_maxstris); cl_stris = BZ_Realloc(cl_stris, sizeof(*cl_stris)*cl_maxstris);
} }
t = &cl_stris[cl_numstris++]; t = &cl_stris[cl_numstris++];
t->shader = R_RegisterShader("testplane", "{\n{\nmap $whiteimage\nrgbgen vertex\nalphagen vertex\nblendfunc add\nnodepth\n}\n}\n"); t->shader = R_RegisterShader("testplane", SUF_NONE, "{\n{\nmap $whiteimage\nrgbgen vertex\nalphagen vertex\nblendfunc add\nnodepth\n}\n}\n");
t->firstidx = cl_numstrisidx; t->firstidx = cl_numstrisidx;
t->firstvert = cl_numstrisvert; t->firstvert = cl_numstrisvert;
t->numvert = 0; t->numvert = 0;
@ -464,6 +468,15 @@ void TestDrawPlane(float *normal, float dist, float r, float g, float b)
t->numidx = cl_numstrisidx - t->firstidx; t->numidx = cl_numstrisidx - t->firstidx;
t->numvert += 4; t->numvert += 4;
if (!enqueue)
{
// int oldents = cl_numvisedicts;
// cl_numvisedicts = 0;
BE_DrawWorld(false, NULL);
cl_numstris = 0;
// cl_numvisedicts = oldents;
}
} }
#endif #endif

View File

@ -345,23 +345,13 @@ extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info *pglobal_info
/* /*
Get Info about the current file in the zipfile, with internal only info Get Info about the current file in the zipfile, with internal only info
*/ */
local int unzlocal_GetCurrentFileInfoInternal (unzFile file,
unz_file_info *pfile_info,
unz_file_info_internal
*pfile_info_internal,
char *szFileName,
unsigned long fileNameBufferSize,
void *extraField,
unsigned long extraFieldBufferSize,
char *szComment,
unsigned long commentBufferSize);
local int unzlocal_GetCurrentFileInfoInternal (unzFile file, local int unzlocal_GetCurrentFileInfoInternal (unzFile file,
unz_file_info *pfile_info, unz_file_info *pfile_info,
unz_file_info_internal *pfile_info_internal, unz_file_info_internal *pfile_info_internal,
char *szFileName, unsigned long fileNameBufferSize, char *szFileName, unsigned long fileNameBufferSize,
void *extraField, unsigned long extraFieldBufferSize, void *extraField, unsigned long extraFieldBufferSize,
char *szComment, unsigned long commentBufferSize) { char *szComment, unsigned long commentBufferSize,
int *issymlink) {
unz_s* s; unz_s* s;
unz_file_info file_info; unz_file_info file_info;
unz_file_info_internal file_info_internal = {0}; unz_file_info_internal file_info_internal = {0};
@ -369,6 +359,9 @@ local int unzlocal_GetCurrentFileInfoInternal (unzFile file,
unsigned long uMagic = 0; unsigned long uMagic = 0;
long lSeek=0; long lSeek=0;
if (issymlink)
*issymlink = 0;
if (!file) return UNZ_PARAMERROR; if (!file) return UNZ_PARAMERROR;
s=(unz_s*)file; s=(unz_s*)file;
if (!VFS_SEEK(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile)) err=UNZ_ERRNO; if (!VFS_SEEK(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile)) err=UNZ_ERRNO;
@ -474,6 +467,21 @@ local int unzlocal_GetCurrentFileInfoInternal (unzFile file,
if ((err==UNZ_OK) && (pfile_info_internal)) *pfile_info_internal=file_info_internal; if ((err==UNZ_OK) && (pfile_info_internal)) *pfile_info_internal=file_info_internal;
if (issymlink)
{
int madeby = file_info.version>>8;
//vms, unix, or beos file attributes includes a symlink attribute.
//symlinks mean the file contents is just the name of another file.
if (madeby == 2 || madeby == 3 || madeby == 16)
{
unsigned short unixattr = file_info.external_fa>>16;
if ((unixattr & 0xF000) == 0xA000)//fa&S_IFMT==S_IFLNK
*issymlink = 1;
else if ((unixattr & 0xA000) == 0xA000)//fa&S_IFMT==S_IFLNK
*issymlink = 1;
}
}
return err; return err;
} }
@ -492,7 +500,8 @@ extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
szFileName,fileNameBufferSize, szFileName,fileNameBufferSize,
extraField,extraFieldBufferSize, extraField,extraFieldBufferSize,
szComment,commentBufferSize); szComment,commentBufferSize,
NULL);
} }
/* /*
@ -508,7 +517,7 @@ extern int ZEXPORT unzGoToFirstFile (unzFile file) {
s->num_file=0; s->num_file=0;
err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
&s->cur_file_info_internal, &s->cur_file_info_internal,
NULL,0,NULL,0,NULL,0); NULL,0,NULL,0,NULL,0,NULL);
s->current_file_ok = (err == UNZ_OK); s->current_file_ok = (err == UNZ_OK);
return err; return err;
} }
@ -533,19 +542,20 @@ extern int ZEXPORT unzGoToNextFile (unzFile file) {
s->num_file++; s->num_file++;
err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
&s->cur_file_info_internal, &s->cur_file_info_internal,
NULL,0,NULL,0,NULL,0); NULL,0,NULL,0,NULL,0, NULL);
s->current_file_ok = (err == UNZ_OK); s->current_file_ok = (err == UNZ_OK);
return err; return err;
} }
extern int ZEXPORT unzLocateFileMy (unzFile file, unsigned long num, unsigned long pos) { extern int ZEXPORT unzLocateFileMy (unzFile file, unsigned long num, unsigned long pos) {
int islink;
unz_s* s; unz_s* s;
s = (unz_s *)file; s = (unz_s *)file;
s->pos_in_central_dir = pos; s->pos_in_central_dir = pos;
s->num_file = num; s->num_file = num;
unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,&s->cur_file_info_internal,NULL,0,NULL,0,NULL,0); unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,&s->cur_file_info_internal,NULL,0,NULL,0,NULL,0,&islink);
return 1; return islink?2:1;
} }

View File

@ -326,10 +326,10 @@ void GL_SetShaderState2D(qboolean is2d)
BE_SelectMode(BEM_STANDARD); BE_SelectMode(BEM_STANDARD);
if (cl.paused || cls.state < ca_active) // if (cl.paused || cls.state < ca_active)
shaderstate.updatetime = r_refdef.time; shaderstate.updatetime = r_refdef.time;
else // else
shaderstate.updatetime = cl.servertime; // shaderstate.updatetime = cl.servertime;
BE_SelectEntity(&r_worldentity); BE_SelectEntity(&r_worldentity);
shaderstate.curtime = shaderstate.updatetime - shaderstate.curentity->shaderTime; shaderstate.curtime = shaderstate.updatetime - shaderstate.curentity->shaderTime;
} }
@ -4731,10 +4731,10 @@ void GLBE_DrawWorld (qboolean drawworld, qbyte *vis)
BE_GenModelBatches(batches, shaderstate.curdlight, BEM_STANDARD); BE_GenModelBatches(batches, shaderstate.curdlight, BEM_STANDARD);
R_GenDlightBatches(batches); R_GenDlightBatches(batches);
shaderstate.curentity = &r_worldentity; shaderstate.curentity = &r_worldentity;
if (cl.paused || cls.state < ca_active) // if (cl.paused || cls.state < ca_active)
shaderstate.updatetime = r_refdef.time; shaderstate.updatetime = r_refdef.time;
else // else
shaderstate.updatetime = cl.servertime; // shaderstate.updatetime = cl.servertime;
GLBE_SelectEntity(&r_worldentity); GLBE_SelectEntity(&r_worldentity);
@ -4831,7 +4831,7 @@ void GLBE_DrawWorld (qboolean drawworld, qbyte *vis)
} }
GLBE_SelectEntity(&r_worldentity); GLBE_SelectEntity(&r_worldentity);
shaderstate.curtime = shaderstate.updatetime = realtime; // shaderstate.curtime = shaderstate.updatetime = realtime;
shaderstate.identitylighting = 1; shaderstate.identitylighting = 1;

View File

@ -2511,7 +2511,7 @@ void ModQ1_Batches_BuildQ1Q2Poly(model_t *mod, msurface_t *surf, void *cookie)
VectorNegate(surf->plane->normal, mesh->normals_array[i]); VectorNegate(surf->plane->normal, mesh->normals_array[i]);
else else
VectorCopy(surf->plane->normal, mesh->normals_array[i]); VectorCopy(surf->plane->normal, mesh->normals_array[i]);
VectorNegate(surf->texinfo->vecs[0], mesh->snormals_array[i]); VectorCopy(surf->texinfo->vecs[0], mesh->snormals_array[i]);
VectorNegate(surf->texinfo->vecs[1], mesh->tnormals_array[i]); VectorNegate(surf->texinfo->vecs[1], mesh->tnormals_array[i]);
//the s+t vectors are axis-aligned, so fiddle them so they're normal aligned instead //the s+t vectors are axis-aligned, so fiddle them so they're normal aligned instead
d = -DotProduct(mesh->normals_array[i], mesh->snormals_array[i]); d = -DotProduct(mesh->normals_array[i], mesh->snormals_array[i]);

View File

@ -565,6 +565,7 @@ void R_RenderScene (void)
R_SetupGL (stereooffset[i]); R_SetupGL (stereooffset[i]);
TRACE(("dbg: calling R_SetFrustrum\n")); TRACE(("dbg: calling R_SetFrustrum\n"));
if (!r_refdef.recurse)
R_SetFrustum (r_refdef.m_projection, r_refdef.m_view); R_SetFrustum (r_refdef.m_projection, r_refdef.m_view);
RQ_BeginFrame(); RQ_BeginFrame();
@ -776,6 +777,7 @@ void R_ObliqueNearClip(float *viewmat, mplane_t *wplane)
r_refdef.m_projection[10] = c[2] + 1.0F; r_refdef.m_projection[10] = c[2] + 1.0F;
r_refdef.m_projection[14] = c[3]; r_refdef.m_projection[14] = c[3];
} }
//void TestDrawPlane(float *normal, float dist, float r, float g, float b, qboolean enqueue);
void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2], int portaltype) void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2], int portaltype)
{ {
entity_t *view; entity_t *view;
@ -783,6 +785,8 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2],
plane_t plane; plane_t plane;
float vmat[16]; float vmat[16];
refdef_t oldrefdef; refdef_t oldrefdef;
vec3_t r;
int i;
mesh_t *mesh = batch->mesh[batch->firstmesh]; mesh_t *mesh = batch->mesh[batch->firstmesh];
qbyte newvis[(MAX_MAP_LEAFS+7)/8]; qbyte newvis[(MAX_MAP_LEAFS+7)/8];
@ -821,9 +825,14 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2],
{ {
case 1: /*fbo explicit mirror (fucked depth, working clip plane)*/ case 1: /*fbo explicit mirror (fucked depth, working clip plane)*/
//fixme: pvs is surely wrong? //fixme: pvs is surely wrong?
r_refdef.flipcull ^= SHADER_CULL_FLIP; // r_refdef.flipcull ^= SHADER_CULL_FLIP;
R_MirrorMatrix(&plane); R_MirrorMatrix(&plane);
Matrix4x4_CM_ModelViewMatrixFromAxis(vmat, vpn, vright, vup, r_refdef.vieworg); Matrix4x4_CM_ModelViewMatrixFromAxis(vmat, vpn, vright, vup, r_refdef.vieworg);
VectorCopy(mesh->xyz_array[0], r_refdef.pvsorigin);
for (i = 1; i < mesh->numvertexes; i++)
VectorAdd(r_refdef.pvsorigin, mesh->xyz_array[i], r_refdef.pvsorigin);
VectorScale(r_refdef.pvsorigin, 1.0/mesh->numvertexes, r_refdef.pvsorigin);
break; break;
case 2: /*fbo refraction (fucked depth, working clip plane)*/ case 2: /*fbo refraction (fucked depth, working clip plane)*/
@ -896,7 +905,6 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2],
plane.normal[2] = (oplane.normal[0] * trmat[2] + oplane.normal[1] * trmat[6] + oplane.normal[2] * trmat[10]); plane.normal[2] = (oplane.normal[0] * trmat[2] + oplane.normal[1] * trmat[6] + oplane.normal[2] * trmat[10]);
plane.dist = -oplane.dist + trmat[12]*oplane.normal[0] + trmat[13]*oplane.normal[1] + trmat[14]*oplane.normal[2]; plane.dist = -oplane.dist + trmat[12]*oplane.normal[0] + trmat[13]*oplane.normal[1] + trmat[14]*oplane.normal[2];
VectorNegate(plane.normal, plane.normal);
if (Cvar_Get("temp_useplaneclip", "1", 0, "temp")->ival) if (Cvar_Get("temp_useplaneclip", "1", 0, "temp")->ival)
portaltype = 1; //make sure the near clipplane is used. portaltype = 1; //make sure the near clipplane is used.
} }
@ -912,9 +920,15 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2],
} }
else if (!(view = R_NearestPortal(&plane)) || VectorCompare(view->origin, view->oldorigin)) else if (!(view = R_NearestPortal(&plane)) || VectorCompare(view->origin, view->oldorigin))
{ {
r_refdef.flipcull ^= SHADER_CULL_FLIP; //a portal with no portal entity, or a portal rentity with an origin equal to its oldorigin, is a mirror.
// r_refdef.flipcull ^= SHADER_CULL_FLIP;
R_MirrorMatrix(&plane); R_MirrorMatrix(&plane);
Matrix4x4_CM_ModelViewMatrixFromAxis(vmat, vpn, vright, vup, r_refdef.vieworg); Matrix4x4_CM_ModelViewMatrixFromAxis(vmat, vpn, vright, vup, r_refdef.vieworg);
VectorCopy(mesh->xyz_array[0], r_refdef.pvsorigin);
for (i = 1; i < mesh->numvertexes; i++)
VectorAdd(r_refdef.pvsorigin, mesh->xyz_array[i], r_refdef.pvsorigin);
VectorScale(r_refdef.pvsorigin, 1.0/mesh->numvertexes, r_refdef.pvsorigin);
} }
else else
{ {
@ -962,19 +976,33 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2],
qglClipPlane(GL_CLIP_PLANE0, glplane); qglClipPlane(GL_CLIP_PLANE0, glplane);
qglEnable(GL_CLIP_PLANE0); qglEnable(GL_CLIP_PLANE0);
}*/ }*/
R_SetFrustum (r_refdef.m_projection, vmat);
if (r_refdef.frustum_numplanes < MAXFRUSTUMPLANES) if (r_refdef.frustum_numplanes < MAXFRUSTUMPLANES)
{ {
r_refdef.frustum[r_refdef.frustum_numplanes].normal[0] = plane.normal[0]; extern int SignbitsForPlane (mplane_t *out);
r_refdef.frustum[r_refdef.frustum_numplanes].normal[1] = plane.normal[1]; mplane_t fp;
r_refdef.frustum[r_refdef.frustum_numplanes].normal[2] = plane.normal[2]; VectorCopy(plane.normal, fp.normal);
r_refdef.frustum[r_refdef.frustum_numplanes].dist = plane.dist + 0.01; fp.dist = plane.dist;
if (portaltype == 1 || portaltype == 2) if (DotProduct(fp.normal, vpn) < 0)
R_ObliqueNearClip(vmat, &r_refdef.frustum[r_refdef.frustum_numplanes]); {
r_refdef.frustum_numplanes++; VectorNegate(fp.normal, fp.normal);
fp.dist *= -1;
} }
GL_CullFace(0); fp.type = PLANE_ANYZ;
fp.signbits = SignbitsForPlane (&fp);
if (portaltype == 1 || portaltype == 2)
R_ObliqueNearClip(vmat, &fp);
//our own culling should be an epsilon forwards so we don't still draw things behind the line due to precision issues.
fp.dist += 0.01;
r_refdef.frustum[r_refdef.frustum_numplanes++] = fp;
}
//force culling to update to match the new front face.
// memcpy(r_refdef.m_view, vmat, sizeof(float)*16);
if (depthmasklist) if (depthmasklist)
{ {
/*draw already-drawn portals as depth-only, to ensure that their contents are not harmed*/ /*draw already-drawn portals as depth-only, to ensure that their contents are not harmed*/
@ -985,10 +1013,14 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2],
{ {
qglMatrixMode(GL_PROJECTION); qglMatrixMode(GL_PROJECTION);
qglLoadMatrixf(r_refdef.m_projection); qglLoadMatrixf(r_refdef.m_projection);
//portals to mask are relative to the old view still.
qglMatrixMode(GL_MODELVIEW);
qglLoadMatrixf(r_refdef.m_view);
} }
currententity = NULL; currententity = NULL;
if (gl_config.arb_depth_clamp) if (gl_config.arb_depth_clamp)
qglEnable(GL_DEPTH_CLAMP_ARB); qglEnable(GL_DEPTH_CLAMP_ARB); //ignore the near clip plane(ish), this means nearer portals can still mask further ones.
GL_ForceDepthWritable(); GL_ForceDepthWritable();
GLBE_SelectMode(BEM_DEPTHONLY); GLBE_SelectMode(BEM_DEPTHONLY);
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
@ -1015,11 +1047,29 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2],
r_refdef.viewangles[0] *= -1; r_refdef.viewangles[0] *= -1;
VectorCopy(r_refdef.vieworg, r_origin); VectorCopy(r_refdef.vieworg, r_origin);
//FIXME: R_RenderScene is currently overriding r_refdef.frustum_numplanes and discarding our new near plane, resulting in wasted draw calls. //determine r_refdef.flipcull & SHADER_CULL_FLIP based upon whether right is right or not.
CrossProduct(vpn, vup, r);
if (DotProduct(r, vright) < 0)
r_refdef.flipcull |= SHADER_CULL_FLIP;
else
r_refdef.flipcull &= ~SHADER_CULL_FLIP;
GL_CullFace(0);//make sure flipcull takes effect
//FIXME: just call Surf_DrawWorld instead?
R_RenderScene(); R_RenderScene();
// if (qglClipPlane) // if (qglClipPlane)
// qglDisable(GL_CLIP_PLANE0); // qglDisable(GL_CLIP_PLANE0);
//the front of the plane should generally point away from the camera, and will be drawn in bright green. woo
// TestDrawPlane(plane.normal, plane.dist+0.01, 0.0, 0.5, 0.0, false);
// TestDrawPlane(plane.normal, plane.dist-0.01, 0.0, 0.5, 0.0, false);
//the back of the plane points towards the camera, and will be drawn in blue, for the luls
// VectorNegate(plane.normal, plane.normal);
// plane.dist *= -1;
// TestDrawPlane(plane.normal, plane.dist+0.01, 0.0, 0.0, 0.2, false);
// TestDrawPlane(plane.normal, plane.dist-0.01, 0.0, 0.0, 0.2, false);
r_refdef = oldrefdef; r_refdef = oldrefdef;
/*broken stuff*/ /*broken stuff*/
@ -1036,7 +1086,7 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2],
qglLoadMatrixf(r_refdef.m_view); qglLoadMatrixf(r_refdef.m_view);
} }
GL_CullFace(0); GL_CullFace(0);//make sure flipcull reversion takes effect
TRACE(("GLR_DrawPortal: portal drawn\n")); TRACE(("GLR_DrawPortal: portal drawn\n"));

View File

@ -4887,6 +4887,8 @@ void Shader_DefaultSkin(char *shortname, shader_t *s, const void *args)
"endif\n" "endif\n"
"}\n" "}\n"
); );
s->flags |= SHADER_NOIMAGE;
} }
void Shader_DefaultSkinShell(char *shortname, shader_t *s, const void *args) void Shader_DefaultSkinShell(char *shortname, shader_t *s, const void *args)
{ {

View File

@ -612,7 +612,7 @@ void flushCocoa(void)
void cocoaGamma(unsigned short *r,unsigned short *g,unsigned short *b) void cocoaGamma(unsigned short *r,unsigned short *g,unsigned short *b)
{ {
CGByteValue gammatable[3*256]; uint8_t gammatable[3*256];
int i; int i;
// convert the gamma values // convert the gamma values

View File

@ -1117,7 +1117,7 @@ static const char *glsl_hdrs[] =
"{\n" "{\n"
"#if defined(RELIEFMAPPING) && !defined(GL_ES)\n" "#if defined(RELIEFMAPPING) && !defined(GL_ES)\n"
"float i, f;\n" "float i, f;\n"
"vec3 OffsetVector = vec3(normalize(eyevector.xyz).xy * cvar_r_glsl_offsetmapping_scale * vec2(-1.0, 1.0), -1.0);\n" "vec3 OffsetVector = vec3(normalize(eyevector.xyz).xy * cvar_r_glsl_offsetmapping_scale * vec2(-1.0, -1.0), -1.0);\n"
"vec3 RT = vec3(vec2(base.xy"/* - OffsetVector.xy*OffsetMapping_Bias*/"), 1.0);\n" "vec3 RT = vec3(vec2(base.xy"/* - OffsetVector.xy*OffsetMapping_Bias*/"), 1.0);\n"
"OffsetVector /= 10.0;\n" "OffsetVector /= 10.0;\n"
"for(i = 1.0; i < 10.0; ++i)\n" "for(i = 1.0; i < 10.0; ++i)\n"
@ -1126,7 +1126,7 @@ static const char *glsl_hdrs[] =
"RT += OffsetVector * (step(texture2D(normtex, RT.xy).a, RT.z) * f - 0.5 * f);\n" "RT += OffsetVector * (step(texture2D(normtex, RT.xy).a, RT.z) * f - 0.5 * f);\n"
"return RT.xy;\n" "return RT.xy;\n"
"#elif defined(OFFSETMAPPING)\n" "#elif defined(OFFSETMAPPING)\n"
"vec2 OffsetVector = normalize(eyevector).xy * cvar_r_glsl_offsetmapping_scale * vec2(1.0, -1.0);\n" "vec2 OffsetVector = normalize(eyevector).xy * cvar_r_glsl_offsetmapping_scale * vec2(-1.0, -1.0);\n"
"vec2 tc = base;\n" "vec2 tc = base;\n"
"tc += OffsetVector;\n" "tc += OffsetVector;\n"
"OffsetVector *= 0.333;\n" "OffsetVector *= 0.333;\n"

View File

@ -555,7 +555,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"vec3 n, s, t, w;\n" "vec3 n, s, t, w;\n"
"gl_Position = skeletaltransform_wnst(w,n,s,t);\n" "gl_Position = skeletaltransform_wnst(w,n,s,t);\n"
"vec3 eyeminusvertex = e_eyepos - w.xyz;\n" "vec3 eyeminusvertex = e_eyepos - w.xyz;\n"
"eyevector.x = -dot(eyeminusvertex, s.xyz);\n" "eyevector.x = dot(eyeminusvertex, s.xyz);\n"
"eyevector.y = dot(eyeminusvertex, t.xyz);\n" "eyevector.y = dot(eyeminusvertex, t.xyz);\n"
"eyevector.z = dot(eyeminusvertex, n.xyz);\n" "eyevector.z = dot(eyeminusvertex, n.xyz);\n"
"#else\n" "#else\n"
@ -923,7 +923,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"{\n" "{\n"
"vec4 col = texture2D(s_t0, tc);\n" "vec4 col = texture2D(s_t0, tc);\n"
"#ifdef MASK\n" "#ifdef MASK\n"
"if (col.a < 0.5)\n" "if (col.a < float(MASK))\n"
"discard;\n" "discard;\n"
"#endif\n" "#endif\n"
"gl_FragColor = fog4blend(col * vc * e_colourident);\n" "gl_FragColor = fog4blend(col * vc * e_colourident);\n"
@ -1017,7 +1017,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"{\n" "{\n"
"#if defined(OFFSETMAPPING) || defined(SPECULAR)\n" "#if defined(OFFSETMAPPING) || defined(SPECULAR)\n"
"vec3 eyeminusvertex = e_eyepos - v_position.xyz;\n" "vec3 eyeminusvertex = e_eyepos - v_position.xyz;\n"
"eyevector.x = -dot(eyeminusvertex, v_svector.xyz);\n" "eyevector.x = dot(eyeminusvertex, v_svector.xyz);\n"
"eyevector.y = dot(eyeminusvertex, v_tvector.xyz);\n" "eyevector.y = dot(eyeminusvertex, v_tvector.xyz);\n"
"eyevector.z = dot(eyeminusvertex, v_normal.xyz);\n" "eyevector.z = dot(eyeminusvertex, v_normal.xyz);\n"
"#endif\n" "#endif\n"
@ -1683,12 +1683,12 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"gl_Position = skeletaltransform_wnst(w,n,s,t);\n" "gl_Position = skeletaltransform_wnst(w,n,s,t);\n"
"tcbase = v_texcoord; //pass the texture coords straight through\n" "tcbase = v_texcoord; //pass the texture coords straight through\n"
"vec3 lightminusvertex = l_lightposition - w.xyz;\n" "vec3 lightminusvertex = l_lightposition - w.xyz;\n"
"lightvector.x = -dot(lightminusvertex, s.xyz);\n" "lightvector.x = dot(lightminusvertex, s.xyz);\n"
"lightvector.y = dot(lightminusvertex, t.xyz);\n" "lightvector.y = dot(lightminusvertex, t.xyz);\n"
"lightvector.z = dot(lightminusvertex, n.xyz);\n" "lightvector.z = dot(lightminusvertex, n.xyz);\n"
"#if defined(SPECULAR)||defined(OFFSETMAPPING)\n" "#if defined(SPECULAR)||defined(OFFSETMAPPING)\n"
"vec3 eyeminusvertex = e_eyepos - w.xyz;\n" "vec3 eyeminusvertex = e_eyepos - w.xyz;\n"
"eyevector.x = -dot(eyeminusvertex, s.xyz);\n" "eyevector.x = dot(eyeminusvertex, s.xyz);\n"
"eyevector.y = dot(eyeminusvertex, t.xyz);\n" "eyevector.y = dot(eyeminusvertex, t.xyz);\n"
"eyevector.z = dot(eyeminusvertex, n.xyz);\n" "eyevector.z = dot(eyeminusvertex, n.xyz);\n"
"#endif\n" "#endif\n"
@ -2343,13 +2343,13 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
//no bumpmapping, so we can just use distance without regard for actual surface direction. we still do scalecos stuff. you might notice it on steep slopes. //no bumpmapping, so we can just use distance without regard for actual surface direction. we still do scalecos stuff. you might notice it on steep slopes.
"lightvector = lightminusvertex;\n" "lightvector = lightminusvertex;\n"
// lightvector.x = -dot(lightminusvertex, v_svector.xyz); // lightvector.x = dot(lightminusvertex, v_svector.xyz);
// lightvector.y = dot(lightminusvertex, v_tvector.xyz); // lightvector.y = dot(lightminusvertex, v_tvector.xyz);
// lightvector.z = dot(lightminusvertex, v_normal.xyz); // lightvector.z = dot(lightminusvertex, v_normal.xyz);
// #if defined(SPECULAR)||defined(OFFSETMAPPING) // #if defined(SPECULAR)||defined(OFFSETMAPPING)
// vec3 eyeminusvertex = e_eyepos - v_position.xyz; // vec3 eyeminusvertex = e_eyepos - v_position.xyz;
// eyevector.x = -dot(eyeminusvertex, v_svector.xyz); // eyevector.x = dot(eyeminusvertex, v_svector.xyz);
// eyevector.y = dot(eyeminusvertex, v_tvector.xyz); // eyevector.y = dot(eyeminusvertex, v_tvector.xyz);
// eyevector.z = dot(eyeminusvertex, v_normal.xyz); // eyevector.z = dot(eyeminusvertex, v_normal.xyz);
// #endif // #endif

View File

@ -665,9 +665,6 @@ void D3D11BE_VBO_Destroy(vboarray_t *vearray);
void D3D11BE_Scissor(srect_t *rect); void D3D11BE_Scissor(srect_t *rect);
#endif #endif
//Asks the backend to invoke DrawMeshChain for each surface, and to upload lightmaps as required
void BE_DrawNonWorld (void);
//Builds a hardware shader from the software representation //Builds a hardware shader from the software representation
void BE_GenerateProgram(shader_t *shader); void BE_GenerateProgram(shader_t *shader);

View File

@ -4347,97 +4347,6 @@ static void QCBUILTIN PF_aim (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
} }
} }
/*
==============
PF_changeyaw
This was a major timewaster in progs, so it was converted to C
==============
*/
static void QCBUILTIN PF_changeyaw (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
edict_t *ent;
float ideal, current, move, speed;
ent = PROG_TO_EDICT(prinst, pr_global_struct->self);
current = anglemod( ent->v->angles[1] );
ideal = ent->v->ideal_yaw;
speed = ent->v->yaw_speed;
if (current == ideal)
return;
move = ideal - current;
if (ideal > current)
{
if (move >= 180)
move = move - 360;
}
else
{
if (move <= -180)
move = move + 360;
}
if (move > 0)
{
if (move > speed)
move = speed;
}
else
{
if (move < -speed)
move = -speed;
}
ent->v->angles[1] = anglemod (current + move);
}
//void() changepitch = #63;
static void QCBUILTIN PF_changepitch (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
edict_t *ent;
float ideal, current, move, speed;
eval_t *eval;
ent = PROG_TO_EDICT(prinst, pr_global_struct->self);
current = anglemod( ent->v->angles[1] );
eval = prinst->GetEdictFieldValue(prinst, ent, "idealpitch", &evalc_idealpitch);
if (eval)
ideal = eval->_float;
else
ideal = 0;
eval = prinst->GetEdictFieldValue(prinst, ent, "pitch_speed", &evalc_pitch_speed);
if (eval)
speed = eval->_float;
else
speed = 0;
if (current == ideal)
return;
move = ideal - current;
if (ideal > current)
{
if (move >= 180)
move = move - 360;
}
else
{
if (move <= -180)
move = move + 360;
}
if (move > 0)
{
if (move > speed)
move = speed;
}
else
{
if (move < -speed)
move = -speed;
}
ent->v->angles[1] = anglemod (current + move);
}
/* /*
=============================================================================== ===============================================================================
@ -8690,7 +8599,6 @@ static void QCBUILTIN PF_globalstat(pubprogfuncs_t *prinst, struct globalvars_s
static void QCBUILTIN PF_runclientphys(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) static void QCBUILTIN PF_runclientphys(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{ {
unsigned int i, n; unsigned int i, n;
extern vec3_t player_maxs, player_mins;
extern qbyte playertouch[]; extern qbyte playertouch[];
unsigned int msecs; unsigned int msecs;
edict_t *ent = G_EDICT(prinst, OFS_PARM0); edict_t *ent = G_EDICT(prinst, OFS_PARM0);
@ -8724,8 +8632,8 @@ static void QCBUILTIN PF_runclientphys(pubprogfuncs_t *prinst, struct globalvars
VectorCopy(ent->v->origin, pmove.origin); VectorCopy(ent->v->origin, pmove.origin);
VectorCopy(ent->v->velocity, pmove.velocity); VectorCopy(ent->v->velocity, pmove.velocity);
VectorCopy(ent->v->maxs, player_maxs); VectorCopy(ent->v->maxs, pmove.player_maxs);
VectorCopy(ent->v->mins, player_mins); VectorCopy(ent->v->mins, pmove.player_mins);
pmove.numphysent = 1; pmove.numphysent = 1;
pmove.physents[0].model = sv.world.worldmodel; pmove.physents[0].model = sv.world.worldmodel;
@ -8797,6 +8705,7 @@ static void QCBUILTIN PF_runclientphys(pubprogfuncs_t *prinst, struct globalvars
sv.world.Event_Touch(&sv.world, (wedict_t*)touched, (wedict_t*)ent); sv.world.Event_Touch(&sv.world, (wedict_t*)touched, (wedict_t*)ent);
playertouch[n/8] |= 1 << (n%8); playertouch[n/8] |= 1 << (n%8);
} }
pmove.numtouch = 0;
} }
} }
@ -9503,6 +9412,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"keynumtostring", PF_Fixme, 0, 0, 0, 340, D("string(float keynum)", "Returns a hunam-readable name for the given keycode, as a tempstring.")},// (EXT_CSQC) {"keynumtostring", PF_Fixme, 0, 0, 0, 340, D("string(float keynum)", "Returns a hunam-readable name for the given keycode, as a tempstring.")},// (EXT_CSQC)
{"keynumtostring_csqc",PF_Fixme,0, 0, 0, 340, D("string(float keynum)", "Returns a hunam-readable name for the given keycode, as a tempstring.")},// (found in menuqc) {"keynumtostring_csqc",PF_Fixme,0, 0, 0, 340, D("string(float keynum)", "Returns a hunam-readable name for the given keycode, as a tempstring.")},// (found in menuqc)
{"stringtokeynum", PF_Fixme, 0, 0, 0, 341, D("float(string keyname)", "Looks up the key name in the same way that the bind command would, returning the keycode for that key.")},// (EXT_CSQC) {"stringtokeynum", PF_Fixme, 0, 0, 0, 341, D("float(string keyname)", "Looks up the key name in the same way that the bind command would, returning the keycode for that key.")},// (EXT_CSQC)
{"stringtokeynum_csqc", PF_Fixme,0, 0, 0, 341, D("float(string keyname)", "Looks up the key name in the same way that the bind command would, returning the keycode for that key.")},// (found in menuqc)
{"getkeybind", PF_Fixme, 0, 0, 0, 342, D("string(float keynum)", "Finds the current binding for the given key (ignores modifiers like shift/alt/ctrl).")},// (EXT_CSQC) {"getkeybind", PF_Fixme, 0, 0, 0, 342, D("string(float keynum)", "Finds the current binding for the given key (ignores modifiers like shift/alt/ctrl).")},// (EXT_CSQC)
{"setcursormode", PF_Fixme, 0, 0, 0, 343, D("void(float usecursor)", "Pass TRUE if you want the engine to release the mouse cursor (absolute input events + touchscreen mode). Pass FALSE if you want the engine to grab the cursor (relative input events + standard looking)")}, // #343 This is a DP extension {"setcursormode", PF_Fixme, 0, 0, 0, 343, D("void(float usecursor)", "Pass TRUE if you want the engine to release the mouse cursor (absolute input events + touchscreen mode). Pass FALSE if you want the engine to grab the cursor (relative input events + standard looking)")}, // #343 This is a DP extension
@ -9785,6 +9695,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"gethostcachestring",PF_Fixme, 0, 0, 0, 612, "string(float type, float hostnr)"}, {"gethostcachestring",PF_Fixme, 0, 0, 0, 612, "string(float type, float hostnr)"},
{"parseentitydata", PF_parseentitydata, 0, 0, 0, 613, "void(entity e, string s)"}, {"parseentitydata", PF_parseentitydata, 0, 0, 0, 613, "void(entity e, string s)"},
{"stringtokeynum", PF_Fixme, 0, 0, 0, 614, "float(string key)"}, {"stringtokeynum", PF_Fixme, 0, 0, 0, 614, "float(string key)"},
{"stringtokeynum_menu", PF_Fixme, 0, 0, 0, 614, "float(string key)"},
{"resethostcachemasks",PF_Fixme, 0, 0, 0, 615, "void()"}, {"resethostcachemasks",PF_Fixme, 0, 0, 0, 615, "void()"},
{"sethostcachemaskstring",PF_Fixme, 0, 0, 0, 616, "void(float mask, float fld, string str, float op)"}, {"sethostcachemaskstring",PF_Fixme, 0, 0, 0, 616, "void(float mask, float fld, string str, float op)"},
{"sethostcachemasknumber",PF_Fixme, 0, 0, 0, 617, "void(float mask, float fld, float num, float op)"}, {"sethostcachemasknumber",PF_Fixme, 0, 0, 0, 617, "void(float mask, float fld, float num, float op)"},

View File

@ -212,7 +212,9 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldfloat(jointtype,NULL)/*DP_...PHYSICS*/\ comfieldfloat(jointtype,NULL)/*DP_...PHYSICS*/\
comfieldfloat(mass,NULL)/*DP_...PHYSICS*/\ comfieldfloat(mass,NULL)/*DP_...PHYSICS*/\
comfieldfloat(bouncefactor,NULL)/*DP_...PHYSICS*/\ comfieldfloat(bouncefactor,NULL)/*DP_...PHYSICS*/\
comfieldfloat(bouncestop,NULL)/*DP_...PHYSICS*/ comfieldfloat(bouncestop,NULL)/*DP_...PHYSICS*/\
comfieldfloat(idealpitch,NULL)/*DP_QC_CHANGEPITCH (inconsistant naming)*/\
comfieldfloat(pitch_speed,NULL)/*DP_QC_CHANGEPITCH*/
#define svextqcfields \ #define svextqcfields \
comfieldfloat(maxspeed,NULL)/*added in quake 1.09*/\ comfieldfloat(maxspeed,NULL)/*added in quake 1.09*/\
@ -284,10 +286,7 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldfloat(basesubblendfrac,NULL) /*FTE_CSQC_HALFLIFE_MODELS+FTE_CSQC_BASEFRAME*/\ comfieldfloat(basesubblendfrac,NULL) /*FTE_CSQC_HALFLIFE_MODELS+FTE_CSQC_BASEFRAME*/\
\ \
comfieldfloat(drawmask,NULL) /*So that the qc can specify all rockets at once or all bannanas at once*/ \ comfieldfloat(drawmask,NULL) /*So that the qc can specify all rockets at once or all bannanas at once*/ \
comfieldfunction(predraw, ".void()",NULL) /*If present, is called just before it's drawn.*/ \ comfieldfunction(predraw, ".void()",NULL) /*If present, is called just before it's drawn.*/
\
comfieldfloat(ideal_pitch,NULL)\
comfieldfloat(pitch_speed,NULL)
typedef struct stdentvars_s //standard = standard for qw typedef struct stdentvars_s //standard = standard for qw
{ {

View File

@ -27,6 +27,7 @@ void SV_CleanupEnts(void);
extern cvar_t sv_nailhack; extern cvar_t sv_nailhack;
extern cvar_t sv_cullentities_trace; extern cvar_t sv_cullentities_trace;
extern cvar_t sv_cullplayers_trace; extern cvar_t sv_cullplayers_trace;
extern cvar_t sv_nopvs;
/* /*
============================================================================= =============================================================================
@ -2300,7 +2301,7 @@ void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, edict_t *
continue; continue;
// ignore if not touching a PV leaf // ignore if not touching a PV leaf
if (!sv.world.worldmodel->funcs.EdictInFatPVS(sv.world.worldmodel, &ent->pvsinfo, pvs)) if (pvs && !sv.world.worldmodel->funcs.EdictInFatPVS(sv.world.worldmodel, &ent->pvsinfo, pvs))
continue; continue;
if (!((int)clent->xv->dimension_see & ((int)ent->xv->dimension_seen | (int)ent->xv->dimension_ghost))) if (!((int)clent->xv->dimension_see & ((int)ent->xv->dimension_seen | (int)ent->xv->dimension_ghost)))
@ -3404,7 +3405,6 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
client_frame_t *frame; client_frame_t *frame;
qbyte pvsbuffer[(MAX_MAP_LEAFS+7)/8]; qbyte pvsbuffer[(MAX_MAP_LEAFS+7)/8];
// this is the frame we are creating // this is the frame we are creating
frame = &client->frameunion.frames[client->netchan.incoming_sequence & UPDATE_MASK]; frame = &client->frameunion.frames[client->netchan.incoming_sequence & UPDATE_MASK];
if (!sv.paused) if (!sv.paused)
@ -3419,11 +3419,13 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
else else
{ {
clent = client->edict; clent = client->edict;
if (sv_nopvs.ival)
pvs = NULL;
#ifdef HLSERVER #ifdef HLSERVER
if (svs.gametype == GT_HALFLIFE) else if (svs.gametype == GT_HALFLIFE)
pvs = SVHL_Snapshot_SetupPVS(client, pvsbuffer, sizeof(pvsbuffer)); pvs = SVHL_Snapshot_SetupPVS(client, pvsbuffer, sizeof(pvsbuffer));
else
#endif #endif
else
pvs = SV_Snapshot_SetupPVS(client, pvsbuffer, sizeof(pvsbuffer)); pvs = SV_Snapshot_SetupPVS(client, pvsbuffer, sizeof(pvsbuffer));
} }

View File

@ -90,6 +90,7 @@ cvar_t sv_maxtic = SCVAR("sv_maxtic","0.1");//never run a tick slower than this
cvar_t sv_limittics = SCVAR("sv_limittics","3");// cvar_t sv_limittics = SCVAR("sv_limittics","3");//
cvar_t sv_nailhack = SCVAR("sv_nailhack","0"); cvar_t sv_nailhack = SCVAR("sv_nailhack","0");
cvar_t sv_nopvs = CVARD("sv_nopvs", "0", "Set to 1 to ignore pvs on the server. This can make wallhacks more dangerous, so should only be used for debugging.");
cvar_t timeout = SCVAR("timeout","65"); // seconds without any message cvar_t timeout = SCVAR("timeout","65"); // seconds without any message
@ -4383,6 +4384,7 @@ void SV_InitLocal (void)
Cvar_Register (&sv_minping, cvargroup_servercontrol); Cvar_Register (&sv_minping, cvargroup_servercontrol);
Cvar_Register (&sv_nailhack, cvargroup_servercontrol); Cvar_Register (&sv_nailhack, cvargroup_servercontrol);
Cvar_Register (&sv_nopvs, cvargroup_servercontrol);
Cvar_Register (&pext_ezquake_nochunks, cvargroup_servercontrol); Cvar_Register (&pext_ezquake_nochunks, cvargroup_servercontrol);
Cmd_AddCommand ("sv_impulse", SV_Impulse_f); Cmd_AddCommand ("sv_impulse", SV_Impulse_f);

View File

@ -255,6 +255,8 @@ void World_changeyaw (wedict_t *ent)
{ {
float ideal, current, move, speed; float ideal, current, move, speed;
//FIXME: gravitydir. reorient the angles to change the yaw with respect to the current ground surface.
current = anglemod( ent->v->angles[1] ); current = anglemod( ent->v->angles[1] );
ideal = ent->v->ideal_yaw; ideal = ent->v->ideal_yaw;
speed = ent->v->yaw_speed; speed = ent->v->yaw_speed;
@ -305,6 +307,7 @@ qboolean World_StepDirection (world_t *world, wedict_t *ent, float yaw, float di
World_changeyaw(ent); World_changeyaw(ent);
yaw = yaw*M_PI*2 / 360; yaw = yaw*M_PI*2 / 360;
//FIXME: gravitydir
move[0] = cos(yaw)*dist; move[0] = cos(yaw)*dist;
move[1] = sin(yaw)*dist; move[1] = sin(yaw)*dist;
move[2] = 0; move[2] = 0;

View File

@ -55,17 +55,17 @@ cvar_t sv_friction = SCVAR( "sv_friction", "4");
cvar_t sv_waterfriction = SCVAR( "sv_waterfriction", "4"); cvar_t sv_waterfriction = SCVAR( "sv_waterfriction", "4");
cvar_t sv_gameplayfix_noairborncorpse = SCVAR( "sv_gameplayfix_noairborncorpse", "0"); cvar_t sv_gameplayfix_noairborncorpse = SCVAR( "sv_gameplayfix_noairborncorpse", "0");
cvar_t sv_gameplayfix_multiplethinks = CVARD( "sv_gameplayfix_multiplethinks", "1", "Enables multiple thinks per entity per frame so small nextthink times are accurate. QuakeWorld mods expect a value of 1."); cvar_t sv_gameplayfix_multiplethinks = CVARD( "sv_gameplayfix_multiplethinks", "1", "Enables multiple thinks per entity per frame so small nextthink times are accurate. QuakeWorld mods expect a value of 1.");
cvar_t sv_gameplayfix_stepdown = CVARD( "sv_gameplayfix_stepdown", "0", "Attempt to step down steps, instead of only up them. Affects non-predicted movetype_walk.");
cvar_t sv_sound_watersplash = CVAR( "sv_sound_watersplash", "misc/h2ohit1.wav"); cvar_t sv_sound_watersplash = CVAR( "sv_sound_watersplash", "misc/h2ohit1.wav");
cvar_t sv_sound_land = CVAR( "sv_sound_land", "demon/dland2.wav"); cvar_t sv_sound_land = CVAR( "sv_sound_land", "demon/dland2.wav");
cvar_t sv_stepheight = CVARAFD("pm_stepheight", "", cvar_t sv_stepheight = CVARAFD("pm_stepheight", "", "sv_stepheight", CVAR_SERVERINFO, "If empty, the value 18 will be used instead. This is the size of the step you can step up or down.");
"sv_stepheight", CVAR_SERVERINFO, "If empty, the value 18 will be used instead.");
cvar_t pm_ktjump = SCVARF("pm_ktjump", "", CVAR_SERVERINFO); cvar_t pm_ktjump = CVARF("pm_ktjump", "", CVAR_SERVERINFO);
cvar_t pm_bunnyspeedcap = SCVARF("pm_bunnyspeedcap", "", CVAR_SERVERINFO); cvar_t pm_bunnyspeedcap = CVARFD("pm_bunnyspeedcap", "", CVAR_SERVERINFO, "0 or 1, ish. If the player is traveling faster than this speed while turning, their velocity will be gracefully reduced to match their current maxspeed. You can still rocket-jump to gain high velocity, but turning will reduce your speed back to the max. This can be used to disable bunny hopping.");
cvar_t pm_slidefix = SCVARF("pm_slidefix", "", CVAR_SERVERINFO); cvar_t pm_slidefix = CVARF("pm_slidefix", "", CVAR_SERVERINFO);
cvar_t pm_slidyslopes = SCVARF("pm_slidyslopes", "", CVAR_SERVERINFO); cvar_t pm_slidyslopes = CVARF("pm_slidyslopes", "", CVAR_SERVERINFO);
cvar_t pm_airstep = SCVARF("pm_airstep", "", CVAR_SERVERINFO); cvar_t pm_airstep = CVARF("pm_airstep", "", CVAR_SERVERINFO);
cvar_t pm_walljump = SCVARF("pm_walljump", "", CVAR_SERVERINFO); cvar_t pm_walljump = CVARF("pm_walljump", "", CVAR_SERVERINFO);
#define cvargroup_serverphysics "server physics variables" #define cvargroup_serverphysics "server physics variables"
void WPhys_Init(void) void WPhys_Init(void)
@ -86,6 +86,7 @@ void WPhys_Init(void)
Cvar_Register (&sv_gameplayfix_noairborncorpse, cvargroup_serverphysics); Cvar_Register (&sv_gameplayfix_noairborncorpse, cvargroup_serverphysics);
Cvar_Register (&sv_gameplayfix_multiplethinks, cvargroup_serverphysics); Cvar_Register (&sv_gameplayfix_multiplethinks, cvargroup_serverphysics);
Cvar_Register (&sv_gameplayfix_stepdown, cvargroup_serverphysics);
} }
#define MOVE_EPSILON 0.01 #define MOVE_EPSILON 0.01
@ -265,7 +266,7 @@ static void WPhys_PortalTransform(world_t *w, wedict_t *ent, wedict_t *portal, v
*w->g.self = EDICT_TO_PROG(w->progs, portal); *w->g.self = EDICT_TO_PROG(w->progs, portal);
//transform origin+velocity etc //transform origin+velocity etc
VectorCopy(org, G_VECTOR(OFS_PARM0)); VectorCopy(org, G_VECTOR(OFS_PARM0));
VectorAngles(ent->v->angles, vup, G_VECTOR(OFS_PARM1)); VectorCopy(ent->v->angles, G_VECTOR(OFS_PARM1));
VectorCopy(ent->v->velocity, w->g.v_forward); VectorCopy(ent->v->velocity, w->g.v_forward);
VectorCopy(move, w->g.v_right); VectorCopy(move, w->g.v_right);
VectorCopy(ent->xv->gravitydir, w->g.v_up); VectorCopy(ent->xv->gravitydir, w->g.v_up);
@ -275,9 +276,9 @@ static void WPhys_PortalTransform(world_t *w, wedict_t *ent, wedict_t *portal, v
PR_ExecuteProgram (w->progs, portal->xv->camera_transform); PR_ExecuteProgram (w->progs, portal->xv->camera_transform);
VectorCopy(G_VECTOR(OFS_RETURN), org); VectorCopy(G_VECTOR(OFS_RETURN), org);
// VectorCopy(w->g.v_forward, ent->v->velocity); VectorCopy(w->g.v_forward, ent->v->velocity);
VectorCopy(w->g.v_right, move); VectorCopy(w->g.v_right, move);
// VectorCopy(w->g.v_up, ent->xv->gravitydir); VectorCopy(w->g.v_up, ent->xv->gravitydir);
//transform the angles too //transform the angles too
@ -289,7 +290,7 @@ static void WPhys_PortalTransform(world_t *w, wedict_t *ent, wedict_t *portal, v
} }
else else
ent->v->angles[0] *= -1; ent->v->angles[0] *= -1;
VectorAngles(ent->v->angles, vup, 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);
@ -364,17 +365,19 @@ static int WPhys_FlyMove (world_t *w, wedict_t *ent, const vec3_t gravitydir, fl
vec3_t move; vec3_t move;
vec3_t from; vec3_t from;
float firstfrac = trace.fraction; float firstfrac = trace.fraction;
Con_Printf("Player hit portal %i\n", impact->entnum);
VectorCopy(trace.endpos, from); //just in case VectorCopy(trace.endpos, from); //just in case
VectorSubtract(end, trace.endpos, move); VectorSubtract(end, trace.endpos, move);
WPhys_PortalTransform(w, ent, impact, trace.endpos, move); WPhys_PortalTransform(w, ent, impact, from, move);
VectorAdd(trace.endpos, move, end); VectorAdd(from, move, end);
trace = World_Move (w, from, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, (wedict_t*)ent);
trace.fraction = firstfrac + (1-firstfrac)*trace.fraction;
//if we follow the portal, then we need to fix up some velocities. //if we follow the portal, then we basically need to restart from the other side.
if (trace.fraction > 0) time_left -= time_left * trace.fraction;
VectorCopy (ent->v->velocity, primal_velocity); VectorCopy (ent->v->velocity, primal_velocity);
VectorCopy (ent->v->velocity, original_velocity);
numplanes = 0;
trace = World_Move (w, from, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, (wedict_t*)ent);
} }
if (trace.startsolid) if (trace.startsolid)
@ -1092,12 +1095,30 @@ A moving object that doesn't obey physics
*/ */
static void WPhys_Physics_Noclip (world_t *w, wedict_t *ent) static void WPhys_Physics_Noclip (world_t *w, wedict_t *ent)
{ {
vec3_t end;
trace_t trace;
wedict_t *impact;
// regular thinking // regular thinking
if (!WPhys_RunThink (w, ent)) if (!WPhys_RunThink (w, ent))
return; return;
VectorMA (ent->v->angles, host_frametime, ent->v->avelocity, ent->v->angles); VectorMA (ent->v->angles, host_frametime, ent->v->avelocity, ent->v->angles);
VectorMA (ent->v->origin, host_frametime, ent->v->velocity, ent->v->origin); VectorMA (ent->v->origin, host_frametime, ent->v->velocity, end);
trace = World_Move (w, ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NOMONSTERS, (wedict_t*)ent);
impact = trace.ent;
if (impact && impact->v->solid == SOLID_PORTAL)
{
vec3_t move;
vec3_t from;
float firstfrac = trace.fraction;
VectorCopy(trace.endpos, from); //just in case
VectorSubtract(end, trace.endpos, move);
WPhys_PortalTransform(w, ent, impact, from, move);
VectorAdd(from, move, end);
}
VectorCopy(end, ent->v->origin);
World_LinkEdict (w, (wedict_t*)ent, false); World_LinkEdict (w, (wedict_t*)ent, false);
} }
@ -1846,7 +1867,7 @@ static void WPhys_WalkMove (world_t *w, wedict_t *ent, const float *gravitydir)
WPhys_WallFriction (ent, &steptrace); WPhys_WallFriction (ent, &steptrace);
} }
} }
else if (/*!sv_gameplayfix_stepdown.integer || */!oldonground || start_velocity[2] > 0 || ((int)ent->v->flags & FL_ONGROUND) || ent->v->waterlevel >= 2) else if (!sv_gameplayfix_stepdown.ival || !oldonground || start_velocity[2] > 0 || ((int)ent->v->flags & FL_ONGROUND) || ent->v->waterlevel >= 2)
return; return;
// move down // move down

View File

@ -112,8 +112,6 @@ extern char cvargroup_serverinfo[];
extern char cvargroup_serverphysics[]; extern char cvargroup_serverphysics[];
extern char cvargroup_servercontrol[]; extern char cvargroup_servercontrol[];
extern vec3_t player_mins, player_maxs;
extern cvar_t pausable; extern cvar_t pausable;
@ -4822,6 +4820,8 @@ void SV_Pext_f(void)
return; return;
host_client->pextknown = true; host_client->pextknown = true;
host_client->fteprotocolextensions = 0;
host_client->fteprotocolextensions2 = 0;
for (i = 1; i < Cmd_Argc(); ) for (i = 1; i < Cmd_Argc(); )
{ {
tag = Cmd_Argv(i++); tag = Cmd_Argv(i++);
@ -5300,6 +5300,7 @@ void AddLinksToPmove ( edict_t *player, areanode_t *node )
edict_t *check; edict_t *check;
int pl; int pl;
int i; int i;
int solid;
physent_t *pe; physent_t *pe;
model_t *model; model_t *model;
@ -5316,10 +5317,14 @@ void AddLinksToPmove ( edict_t *player, areanode_t *node )
continue; // player's own missile continue; // player's own missile
if (check == player) if (check == player)
continue; continue;
if ((check->v->solid == SOLID_TRIGGER && check->v->skin < 0) || check->v->solid == SOLID_BSP solid = check->v->solid;
|| check->v->solid == SOLID_BBOX if (
|| check->v->solid == SOLID_SLIDEBOX (solid == SOLID_TRIGGER && check->v->skin < 0)
//|| (check->v->solid == SOLID_PHASEH2 && progstype == PROG_H2) //logically matches hexen2, but I hate it || solid == SOLID_BSP
|| solid == SOLID_PORTAL
|| solid == SOLID_BBOX
|| solid == SOLID_SLIDEBOX
//|| (solid == SOLID_PHASEH2 && progstype == PROG_H2) //logically matches hexen2, but I hate it
) )
{ {
@ -5342,7 +5347,8 @@ void AddLinksToPmove ( edict_t *player, areanode_t *node )
VectorCopy (check->v->origin, pe->origin); VectorCopy (check->v->origin, pe->origin);
pe->info = NUM_FOR_EDICT(svprogfuncs, check); pe->info = NUM_FOR_EDICT(svprogfuncs, check);
pe->nonsolid = check->v->solid == SOLID_TRIGGER; pe->nonsolid = solid == SOLID_TRIGGER;
pe->isportal = solid == SOLID_PORTAL;
switch((int)check->v->skin) switch((int)check->v->skin)
{ {
case Q1CONTENTS_WATER: case Q1CONTENTS_WATER:
@ -5369,7 +5375,7 @@ void AddLinksToPmove ( edict_t *player, areanode_t *node )
pe->forcecontentsmask = 0; pe->forcecontentsmask = 0;
break; break;
} }
if (check->v->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]*=-1; //quake is wierd. I guess someone fixed it hexen2... or my code is buggy or something...
@ -5827,13 +5833,13 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
// memset(&pmove, 0, sizeof(pmove)); // memset(&pmove, 0, sizeof(pmove));
// memset(&movevars, 0, sizeof(movevars)); // memset(&movevars, 0, sizeof(movevars));
player_mins[0] = sv_player->v->mins[0]; pmove.player_mins[0] = sv_player->v->mins[0];
player_mins[1] = sv_player->v->mins[1]; pmove.player_mins[1] = sv_player->v->mins[1];
player_mins[2] = sv_player->v->mins[2]; pmove.player_mins[2] = sv_player->v->mins[2];
player_maxs[0] = sv_player->v->maxs[0]; pmove.player_maxs[0] = sv_player->v->maxs[0];
player_maxs[1] = sv_player->v->maxs[1]; pmove.player_maxs[1] = sv_player->v->maxs[1];
player_maxs[2] = sv_player->v->maxs[2]; pmove.player_maxs[2] = sv_player->v->maxs[2];
VectorCopy(sv_player->xv->gravitydir, pmove.gravitydir); VectorCopy(sv_player->xv->gravitydir, pmove.gravitydir);
@ -5884,6 +5890,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
else else
pmove.onladder = false; pmove.onladder = false;
pmove.world = &sv.world;
#if 0 #if 0
{ {
int before, after; int before, after;
@ -5898,6 +5905,7 @@ if (sv_player->v->health > 0 && before && !after )
#else #else
PM_PlayerMove (sv.gamespeed); PM_PlayerMove (sv.gamespeed);
#endif #endif
pmove.world = NULL;
host_client->jump_held = pmove.jump_held; host_client->jump_held = pmove.jump_held;
if (progstype != PROG_QW) //this is just annoying. if (progstype != PROG_QW) //this is just annoying.
@ -5933,7 +5941,8 @@ if (sv_player->v->health > 0 && before && !after )
VectorCopy (pmove.origin, sv_player->v->origin); VectorCopy (pmove.origin, sv_player->v->origin);
VectorCopy (pmove.angles, sv_player->v->v_angle); VectorCopy (pmove.angles, sv_player->v->v_angle);
if (pmove.gravitydir[0] || pmove.gravitydir[1] || pmove.gravitydir[2] != -1) VectorCopy (pmove.gravitydir, sv_player->xv->gravitydir);
if (pmove.gravitydir[0] || pmove.gravitydir[1] || (pmove.gravitydir[2] && pmove.gravitydir[2] != -1))
{ {
if (!sv_player->v->fixangle) if (!sv_player->v->fixangle)
{ {
@ -5955,13 +5964,13 @@ if (sv_player->v->health > 0 && before && !after )
} }
} }
player_mins[0] = -16; pmove.player_mins[0] = -16;
player_mins[1] = -16; pmove.player_mins[1] = -16;
player_mins[2] = -24; pmove.player_mins[2] = -24;
player_maxs[0] = 16; pmove.player_maxs[0] = 16;
player_maxs[1] = 16; pmove.player_maxs[1] = 16;
player_maxs[2] = 32; pmove.player_maxs[2] = 32;
VectorCopy(sv_player->v->velocity, old_vel); VectorCopy(sv_player->v->velocity, old_vel);
VectorCopy(pmove.velocity, new_vel); VectorCopy(pmove.velocity, new_vel);

View File

@ -1627,8 +1627,6 @@ static void SVHL_RunCmdR(hledict_t *ed, usercmd_t *ucmd)
int i; int i;
hledict_t *other; hledict_t *other;
extern cvar_t temp1; extern cvar_t temp1;
extern vec3_t player_mins;
extern vec3_t player_maxs;
// chop up very long commands // chop up very long commands
if (ucmd->msec > 50) if (ucmd->msec > 50)

View File

@ -1494,7 +1494,7 @@ static void World_ClipToLinks (world_t *w, areanode_t *node, moveclip_t *clip)
continue; continue;
} }
if (clip->type & MOVE_NOMONSTERS && touch->v->solid != SOLID_BSP) if ((clip->type & MOVE_NOMONSTERS) && (touch->v->solid != SOLID_BSP && touch->v->solid != SOLID_PORTAL))
continue; continue;
if (clip->passedict) if (clip->passedict)

View File

@ -35,7 +35,7 @@ void main ()
vec3 n, s, t, w; vec3 n, s, t, w;
gl_Position = skeletaltransform_wnst(w,n,s,t); gl_Position = skeletaltransform_wnst(w,n,s,t);
vec3 eyeminusvertex = e_eyepos - w.xyz; vec3 eyeminusvertex = e_eyepos - w.xyz;
eyevector.x = -dot(eyeminusvertex, s.xyz); eyevector.x = dot(eyeminusvertex, s.xyz);
eyevector.y = dot(eyeminusvertex, t.xyz); eyevector.y = dot(eyeminusvertex, t.xyz);
eyevector.z = dot(eyeminusvertex, n.xyz); eyevector.z = dot(eyeminusvertex, n.xyz);
#else #else

View File

@ -24,7 +24,7 @@ void main ()
{ {
vec4 col = texture2D(s_t0, tc); vec4 col = texture2D(s_t0, tc);
#ifdef MASK #ifdef MASK
if (col.a < 0.5) if (col.a < float(MASK))
discard; discard;
#endif #endif
gl_FragColor = fog4blend(col * vc * e_colourident); gl_FragColor = fog4blend(col * vc * e_colourident);

View File

@ -42,7 +42,7 @@ void main ()
{ {
#if defined(OFFSETMAPPING) || defined(SPECULAR) #if defined(OFFSETMAPPING) || defined(SPECULAR)
vec3 eyeminusvertex = e_eyepos - v_position.xyz; vec3 eyeminusvertex = e_eyepos - v_position.xyz;
eyevector.x = -dot(eyeminusvertex, v_svector.xyz); eyevector.x = dot(eyeminusvertex, v_svector.xyz);
eyevector.y = dot(eyeminusvertex, v_tvector.xyz); eyevector.y = dot(eyeminusvertex, v_tvector.xyz);
eyevector.z = dot(eyeminusvertex, v_normal.xyz); eyevector.z = dot(eyeminusvertex, v_normal.xyz);
#endif #endif

View File

@ -58,12 +58,12 @@ void main ()
gl_Position = skeletaltransform_wnst(w,n,s,t); gl_Position = skeletaltransform_wnst(w,n,s,t);
tcbase = v_texcoord; //pass the texture coords straight through tcbase = v_texcoord; //pass the texture coords straight through
vec3 lightminusvertex = l_lightposition - w.xyz; vec3 lightminusvertex = l_lightposition - w.xyz;
lightvector.x = -dot(lightminusvertex, s.xyz); lightvector.x = dot(lightminusvertex, s.xyz);
lightvector.y = dot(lightminusvertex, t.xyz); lightvector.y = dot(lightminusvertex, t.xyz);
lightvector.z = dot(lightminusvertex, n.xyz); lightvector.z = dot(lightminusvertex, n.xyz);
#if defined(SPECULAR)||defined(OFFSETMAPPING) #if defined(SPECULAR)||defined(OFFSETMAPPING)
vec3 eyeminusvertex = e_eyepos - w.xyz; vec3 eyeminusvertex = e_eyepos - w.xyz;
eyevector.x = -dot(eyeminusvertex, s.xyz); eyevector.x = dot(eyeminusvertex, s.xyz);
eyevector.y = dot(eyeminusvertex, t.xyz); eyevector.y = dot(eyeminusvertex, t.xyz);
eyevector.z = dot(eyeminusvertex, n.xyz); eyevector.z = dot(eyeminusvertex, n.xyz);
#endif #endif

View File

@ -50,13 +50,13 @@ void main (void)
//no bumpmapping, so we can just use distance without regard for actual surface direction. we still do scalecos stuff. you might notice it on steep slopes. //no bumpmapping, so we can just use distance without regard for actual surface direction. we still do scalecos stuff. you might notice it on steep slopes.
lightvector = lightminusvertex; lightvector = lightminusvertex;
// lightvector.x = -dot(lightminusvertex, v_svector.xyz); // lightvector.x = dot(lightminusvertex, v_svector.xyz);
// lightvector.y = dot(lightminusvertex, v_tvector.xyz); // lightvector.y = dot(lightminusvertex, v_tvector.xyz);
// lightvector.z = dot(lightminusvertex, v_normal.xyz); // lightvector.z = dot(lightminusvertex, v_normal.xyz);
// #if defined(SPECULAR)||defined(OFFSETMAPPING) // #if defined(SPECULAR)||defined(OFFSETMAPPING)
// vec3 eyeminusvertex = e_eyepos - v_position.xyz; // vec3 eyeminusvertex = e_eyepos - v_position.xyz;
// eyevector.x = -dot(eyeminusvertex, v_svector.xyz); // eyevector.x = dot(eyeminusvertex, v_svector.xyz);
// eyevector.y = dot(eyeminusvertex, v_tvector.xyz); // eyevector.y = dot(eyeminusvertex, v_tvector.xyz);
// eyevector.z = dot(eyeminusvertex, v_normal.xyz); // eyevector.z = dot(eyeminusvertex, v_normal.xyz);
// #endif // #endif