From 38a9770253fe42dfbf80f36af5337c8503840baa Mon Sep 17 00:00:00 2001 From: Spoike Date: Mon, 13 Jan 2014 02:42:25 +0000 Subject: [PATCH] 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 --- engine/client/cl_cam.c | 11 +- engine/client/cl_ents.c | 18 +-- engine/client/cl_input.c | 4 +- engine/client/cl_main.c | 10 +- engine/client/cl_pred.c | 10 +- engine/client/console.c | 2 +- engine/client/image.c | 97 +++++++++++----- engine/client/keys.c | 10 +- engine/client/m_options.c | 2 + engine/client/p_script.c | 39 +++++-- engine/client/pr_csqc.c | 89 ++------------- engine/client/pr_menu.c | 4 +- engine/client/r_surf.c | 13 +-- engine/client/renderer.c | 8 +- engine/client/view.c | 2 +- engine/common/com_mesh.c | 9 +- engine/common/common.c | 147 ++++++++++++++----------- engine/common/common.h | 18 +-- engine/common/fs.c | 121 ++++++++++++++------ engine/common/fs.h | 30 ++--- engine/common/fs_pak.c | 28 ++--- engine/common/fs_stdio.c | 8 +- engine/common/fs_win32.c | 14 +-- engine/common/fs_zip.c | 15 ++- engine/common/gl_q2bsp.c | 26 +++-- engine/common/particles.h | 2 +- engine/common/pmove.c | 95 +++++++++++++--- engine/common/pmove.h | 11 +- engine/common/pmovetst.c | 45 ++++---- engine/common/pr_bgcmd.c | 127 +++++++++++++++++---- engine/common/pr_common.h | 2 + engine/common/q1bsp.c | 17 ++- engine/common/unzip.c | 44 +++++--- engine/gl/gl_backend.c | 14 +-- engine/gl/gl_model.c | 2 +- engine/gl/gl_rmain.c | 78 ++++++++++--- engine/gl/gl_shader.c | 2 + engine/gl/gl_vidcocoa.m | 2 +- engine/gl/gl_vidcommon.c | 4 +- engine/gl/r_bishaders.h | 14 +-- engine/gl/shader.h | 3 - engine/server/pr_cmds.c | 99 +---------------- engine/server/progdefs.h | 9 +- engine/server/sv_ents.c | 10 +- engine/server/sv_main.c | 2 + engine/server/sv_move.c | 3 + engine/server/sv_phys.c | 69 ++++++++---- engine/server/sv_user.c | 51 +++++---- engine/server/svhl_game.c | 2 - engine/server/world.c | 2 +- engine/shaders/glsl/defaultskin.glsl | 2 +- engine/shaders/glsl/defaultsprite.glsl | 2 +- engine/shaders/glsl/defaultwall.glsl | 2 +- engine/shaders/glsl/rtlight.glsl | 4 +- engine/shaders/glsl/terrain.glsl | 4 +- 55 files changed, 856 insertions(+), 602 deletions(-) diff --git a/engine/client/cl_cam.c b/engine/client/cl_cam.c index d2b89d8b..431f94d3 100644 --- a/engine/client/cl_cam.c +++ b/engine/client/cl_cam.c @@ -132,9 +132,6 @@ trace_t Cam_DoTrace(vec3_t vec1, vec3_t vec2) VectorCopy (vec1, pmove.origin); 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 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; float len; - player_mins[0] = player_mins[1] = -16; - player_mins[2] = -24; - player_maxs[0] = player_maxs[1] = 16; - player_maxs[2] = 32; + pmove.player_mins[0] = pmove.player_mins[1] = -16; + pmove.player_mins[2] = -24; + pmove.player_maxs[0] = pmove.player_maxs[1] = 16; + pmove.player_maxs[2] = 32; VectorAngles(vec, NULL, v); // v[0] = -v[0]; diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index a3374e7f..42ee1b19 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -4205,6 +4205,9 @@ void CL_LinkPlayers (void) if (!cl.worldmodel || cl.worldmodel->needload) return; + if (cl.paused) + predictmsmult = 0; + playertime = realtime - cls.latency + 0.02; if (playertime > realtime) playertime = realtime; @@ -4445,16 +4448,15 @@ void CL_LinkPlayers (void) if ((r_showbboxes.ival & 3) == 3) { vec3_t min, max; - extern vec3_t player_mins, player_maxs; shader_t *s = R_RegisterShader("bboxshader", SUF_NONE, NULL); if (s) { - VectorAdd(state->origin, player_mins, min); - VectorAdd(state->origin, player_maxs, max); + VectorAdd(state->origin, pmove.player_mins, min); + VectorAdd(state->origin, pmove.player_maxs, max); CLQ1_AddOrientedCube(s, min, max, NULL, 0.1, 0, 0, 1); - VectorAdd(ent->origin, player_mins, min); - VectorAdd(ent->origin, player_maxs, max); + VectorAdd(ent->origin, pmove.player_mins, min); + VectorAdd(ent->origin, pmove.player_maxs, max); 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) { int j; - extern vec3_t player_mins; - extern vec3_t player_maxs; struct predicted_player *pplayer; physent_t *pent; @@ -4845,8 +4845,8 @@ void CL_SetSolidPlayers (void) memset(pent, 0, sizeof(physent_t)); VectorCopy(pplayer->origin, pent->origin); pent->info = j+1; - VectorCopy(player_mins, pent->mins); - VectorCopy(player_maxs, pent->maxs); + VectorCopy(pmove.player_mins, pent->mins); + VectorCopy(pmove.player_maxs, pent->maxs); if (++pmove.numphysent == MAX_PHYSENTS) //we just hit 88 miles per hour. break; pent++; diff --git a/engine/client/cl_input.c b/engine/client/cl_input.c index a20c34f5..e1f3c01d 100644 --- a/engine/client/cl_input.c +++ b/engine/client/cl_input.c @@ -719,12 +719,12 @@ void CL_ClampPitch (int pnum) 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; } else { - Con_Printf("Roll %f\n", vang[ROLL]); +// Con_Printf("Roll %f\n", vang[ROLL]); vang[ROLL] += host_frametime*180; } } diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 2f7d898a..75d94b5d 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -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_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"); @@ -661,7 +661,7 @@ void CL_CheckForResend (void) default: cl.movesequence = 0; if (!strcmp(cl_loopbackprotocol.string, "qw")) - { + { //qw with all supported extensions -default pext1 = Net_PextMask(1, false); pext2 = Net_PextMask(2, false); cls.protocol = CP_QUAKEWORLD; @@ -695,14 +695,17 @@ void CL_CheckForResend (void) cls.protocol = CP_NETQUAKE; 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; pext1 = Net_PextMask(1, false); pext2 = Net_PextMask(2, false); } else + { cls.protocol = CP_NETQUAKE; + cls.protocol_nq = CPNQ_FITZ666; + } //make sure the protocol within demos is actually correct/sane if (cls.demorecording == 1 && cls.protocol != CP_QUAKEWORLD) @@ -715,6 +718,7 @@ void CL_CheckForResend (void) { cls.protocol = CP_NETQUAKE; cls.protocol_nq = CPNQ_FITZ666; + //FIXME: use pext. } break; } diff --git a/engine/client/cl_pred.c b/engine/client/cl_pred.c index 362a94e6..b677b2b4 100644 --- a/engine/client/cl_pred.c +++ b/engine/client/cl_pred.c @@ -364,8 +364,6 @@ CL_PredictUsercmd */ 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 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; pmove.onladder = false; - VectorCopy(from->szmins, player_mins); - VectorCopy(from->szmaxs, player_maxs); + VectorCopy(from->szmins, pmove.player_mins); + VectorCopy(from->szmaxs, pmove.player_maxs); 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->pm_type = from->pm_type; - VectorCopy(player_mins, to->szmins); - VectorCopy(player_maxs, to->szmaxs); + VectorCopy(pmove.player_mins, to->szmins); + VectorCopy(pmove.player_maxs, to->szmaxs); } diff --git a/engine/client/console.c b/engine/client/console.c index fdcc70e7..2c88dad1 100644 --- a/engine/client/console.c +++ b/engine/client/console.c @@ -1675,7 +1675,7 @@ static int Con_DrawConsoleLines(console_t *con, conline_t *l, int sx, int ex, in } 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); } } diff --git a/engine/client/image.c b/engine/client/image.c index de51c515..d1541911 100644 --- a/engine/client/image.c +++ b/engine/client/image.c @@ -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, //and some Q2 mods include PCX files //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 #ifndef _WIN32 @@ -2482,6 +2502,26 @@ qbyte *Read32BitImageFile(qbyte *buf, int len, int *width, int *height, qboolean 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")); return NULL; @@ -2544,29 +2584,32 @@ static void *R_FlipImage32(void *in, int *inoutwidth, int *inoutheight, qboolean return out; } +int tex_extensions_count; +#define tex_extensions_max 15 static struct { - char *name; - int enabled; -} tex_extensions[] = -{//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. -#ifdef AVAIL_JPEGLIB - {".jpg", 1}, //q3 uses some jpegs, for some reason -#endif - {".bmp", 0}, //wtf? at least not lossy -#ifdef AVAIL_PNGLIB - {".png", 1}, //pngs, fairly common, but slow -#endif - {".tga", 1}, //fairly fast to load -#ifdef IMAGEFMT_BLP - {".blp", 1}, //blizzard picture, for the luls -#endif -#ifdef IMAGEFMT_DDS - {".dds", 1}, //compressed or something -#endif - {"", 1} //someone forgot an extension -}; + char name[6]; +} tex_extensions[tex_extensions_max]; +void R_ImageExtensions_Callback(struct cvar_s *var, char *oldvalue) +{ + char *v = var->string; + tex_extensions_count = 0; + + while (tex_extensions_count < tex_extensions_max) + { + v = COM_Parse(v); + if (!v) + break; + Q_snprintfz(tex_extensions[tex_extensions_count].name, sizeof(tex_extensions[tex_extensions_count].name), ".%s", com_token); + tex_extensions_count++; + } + + if (tex_extensions_count < tex_extensions_max) + { + Q_snprintfz(tex_extensions[tex_extensions_count].name, sizeof(tex_extensions[tex_extensions_count].name), ""); + tex_extensions_count++; + } +} static struct { @@ -2675,11 +2718,8 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags) for (i = 0; i < 6; i++) { 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; 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); return tex; } + Con_Printf("%s is not a dds file\n", fname); BZ_Free(buf); } #endif @@ -2751,11 +2792,8 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags) { if (!tex_path[i].enabled) 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 (!subpath) @@ -2771,6 +2809,7 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags) TRACE(("dbg: Mod_LoadHiResTexture: trying %s\n", fname)); 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 tex = GL_ReadTextureDDS(name, buf, com_filesize); if (TEXVALID(tex)) diff --git a/engine/client/keys.c b/engine/client/keys.c index 2dc55477..03a15e34 100644 --- a/engine/client/keys.c +++ b/engine/client/keys.c @@ -385,10 +385,7 @@ void Con_ExecuteLine(console_t *con, char *line) while(*line) { unicode = utf8_decode(&err, line, &line); - if (com_parseutf8.ival < 0) - len += iso88591_encode(deutf8+len, unicode, sizeof(deutf8)-1 - len); - else - len += qchar_encode(deutf8+len, unicode, sizeof(deutf8)-1 - len); + len += unicode_encode(deutf8+len, unicode, sizeof(deutf8)-1 - len, true); } deutf8[len] = 0; line = deutf8; @@ -1366,10 +1363,7 @@ void Key_Message (int key, int unicode) while(*line) { unicode = utf8_decode(&err, line, &line); - if (com_parseutf8.ival < 0) - len += iso88591_encode(deutf8+len, unicode, sizeof(deutf8)-1 - len); - else - len += qchar_encode(deutf8+len, unicode, sizeof(deutf8)-1 - len); + len += unicode_encode(deutf8+len, unicode, sizeof(deutf8)-1 - len, true); } deutf8[len] = 0; line = deutf8; diff --git a/engine/client/m_options.c b/engine/client/m_options.c index 0a76b589..d33631b8 100644 --- a/engine/client/m_options.c +++ b/engine/client/m_options.c @@ -555,6 +555,7 @@ const char *presetexec[] = "r_part_density 0.25;" "cl_nolerp 1;" "r_lerpmuzzlehack 0;" + "v_gunkick 0;" , // fast options "gl_texturemode ln;" @@ -587,6 +588,7 @@ const char *presetexec[] = "r_coronas 1;" "cl_nolerp 0;" "r_lerpmuzzlehack 1;" + "v_gunkick 1;" , // nice options "r_stains 0.75;" diff --git a/engine/client/p_script.c b/engine/client/p_script.c index 296a124c..b2be6f88 100644 --- a/engine/client/p_script.c +++ b/engine/client/p_script.c @@ -621,7 +621,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn) "}\n" ; break; - case BM_ADD: + case BM_ADDA: namepostfix = "_add"; defaultshader = "{\n" @@ -637,6 +637,22 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn) "}\n" ; 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: namepostfix = "_invmoda"; defaultshader = @@ -1255,8 +1271,10 @@ static void P_ParticleEffect_f(void) ptype->stainonimpact = atof(value); else if (!strcmp(var, "blend")) { - if (!strcmp(value, "add")) - ptype->looks.blendmode = BM_ADD; + if (!strcmp(value, "adda") || !strcmp(value, "add")) + ptype->looks.blendmode = BM_ADDA; + else if (!strcmp(value, "addc")) + ptype->looks.blendmode = BM_ADDC; else if (!strcmp(value, "subtract")) ptype->looks.blendmode = BM_SUBTRACT; else if (!strcmp(value, "invmoda") || !strcmp(value, "invmod")) @@ -2005,6 +2023,7 @@ static void P_ImportEffectInfo_f(void) ptype->spawnmode = SM_BOX; + ptype->colorindex = -1; ptype->spawnchance = 1; ptype->randsmax = 1; ptype->looks.scalefactor = 2; @@ -2044,22 +2063,22 @@ static void P_ImportEffectInfo_f(void) else if (!strcmp(arg[1], "static")) { ptype->looks.type = PT_NORMAL; - ptype->looks.blendmode = BM_ADD; + ptype->looks.blendmode = BM_ADDA; } else if (!strcmp(arg[1], "smoke")) { ptype->looks.type = PT_NORMAL; - ptype->looks.blendmode = BM_ADD; + ptype->looks.blendmode = BM_ADDA; } else if (!strcmp(arg[1], "spark")) { ptype->looks.type = PT_TEXTUREDSPARK; - ptype->looks.blendmode = BM_ADD; + ptype->looks.blendmode = BM_ADDA; } else if (!strcmp(arg[1], "bubble")) { ptype->looks.type = PT_NORMAL; - ptype->looks.blendmode = BM_ADD; + ptype->looks.blendmode = BM_ADDA; } else if (!strcmp(arg[1], "blood")) { @@ -2070,12 +2089,12 @@ static void P_ImportEffectInfo_f(void) else if (!strcmp(arg[1], "beam")) { ptype->looks.type = PT_BEAM; - ptype->looks.blendmode = BM_ADD; + ptype->looks.blendmode = BM_ADDA; } else if (!strcmp(arg[1], "snow")) { ptype->looks.type = PT_NORMAL; - ptype->looks.blendmode = BM_ADD; + ptype->looks.blendmode = BM_ADDA; //should have some sort of wind/flutter with it } else @@ -2181,7 +2200,7 @@ static void P_ImportEffectInfo_f(void) else if (!strcmp(arg[1], "alpha")) ptype->looks.blendmode = BM_BLEND; else if (!strcmp(arg[1], "add")) - ptype->looks.blendmode = BM_ADD; + ptype->looks.blendmode = BM_ADDA; else Con_Printf("effectinfo 'blend %s' not supported\n", arg[1]); } diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index b9f0121e..7629c56c 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -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) { unsigned int msecs; - extern vec3_t player_mins; - extern vec3_t player_maxs; csqcedict_t *ent; if (prinst->callargc >= 1) @@ -2435,8 +2433,8 @@ static void QCBUILTIN PF_cs_runplayerphysics (pubprogfuncs_t *prinst, struct glo pmove.waterjumptime = 0; VectorCopy(ent->v->origin, pmove.origin); VectorCopy(ent->v->velocity, pmove.velocity); - VectorCopy(ent->v->maxs, player_maxs); - VectorCopy(ent->v->mins, player_mins); + VectorCopy(ent->v->maxs, pmove.player_maxs); + VectorCopy(ent->v->mins, pmove.player_mins); } else { @@ -2448,8 +2446,8 @@ static void QCBUILTIN PF_cs_runplayerphysics (pubprogfuncs_t *prinst, struct glo pmove.waterjumptime = *csqcg.pmove_waterjumptime; VectorCopy(csqcg.pmove_org, pmove.origin); VectorCopy(csqcg.pmove_vel, pmove.velocity); - VectorCopy(csqcg.pmove_maxs, player_maxs); - VectorCopy(csqcg.pmove_mins, player_mins); + VectorCopy(csqcg.pmove_maxs, pmove.player_maxs); + VectorCopy(csqcg.pmove_mins, pmove.player_mins); } 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); } -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) { csqcedict_t *ent, *chain; @@ -4387,7 +4312,7 @@ static struct { {"localcmd", PF_localcmd, 46}, // #46 void(string str) localcmd (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) - {"changeyaw", PF_cs_changeyaw, 49}, // #49 void() changeyaw (QUAKE) + {"changeyaw", PF_changeyaw, 49}, // #49 void() changeyaw (QUAKE) //50 // {"?", PF_Fixme, 50}, // #50 {"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) {"cos", PF_Cos, 61}, // #61 float(float angle) cos (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) {"etos", PF_etos, 65}, // #65 string(entity ent) etos (DP_QC_ETOS) @@ -4897,7 +4822,7 @@ static struct { {"gethostcachevalue", PF_cl_gethostcachevalue, 611}, {"gethostcachestring", PF_cl_gethostcachestring, 612}, {"parseentitydata", PF_parseentitydata, 613}, - {"stringtokeynum", PF_cl_stringtokeynum, 614}, + {"stringtokeynum_menu", PF_cl_stringtokeynum, 614}, {"resethostcachemasks", PF_cl_resethostcachemasks, 615}, {"sethostcachemaskstring", PF_cl_sethostcachemaskstring,616}, diff --git a/engine/client/pr_menu.c b/engine/client/pr_menu.c index 004b7070..f0f99f93 100644 --- a/engine/client/pr_menu.c +++ b/engine/client/pr_menu.c @@ -588,7 +588,7 @@ void QCBUILTIN PF_CL_drawrawstring (pubprogfuncs_t *prinst, struct globalvars_s while(*text) { if (1)//VMUTF8) - c = unicode_decode(&error, text, &text); + c = unicode_decode(&error, text, &text, false); else { //FIXME: which charset is this meant to be using? @@ -1616,7 +1616,7 @@ static struct { //gap {"print_csqc", PF_print, 339}, {"keynumtostring_csqc", PF_cl_keynumtostring, 340}, - {"stringtokeynum", PF_cl_stringtokeynum, 341}, + {"stringtokeynum_csqc", PF_cl_stringtokeynum, 341}, {"getkeybind", PF_cl_getkeybind, 342}, //gap {"isdemo", PF_isdemo, 349}, diff --git a/engine/client/r_surf.c b/engine/client/r_surf.c index 3960d83a..9605311a 100644 --- a/engine/client/r_surf.c +++ b/engine/client/r_surf.c @@ -2101,15 +2101,14 @@ void Surf_SetupFrame(void) /*pick up any extra water entities*/ { - extern vec3_t player_maxs, player_mins; vec3_t t1,t2; - VectorCopy(player_mins, t1); - VectorCopy(player_maxs, t2); - VectorClear(player_maxs); - VectorClear(player_mins); + VectorCopy(pmove.player_mins, t1); + VectorCopy(pmove.player_maxs, t2); + VectorClear(pmove.player_maxs); + VectorClear(pmove.player_mins); r_viewcontents |= PM_ExtraBoxContents(r_origin); - VectorCopy(t1, player_mins); - VectorCopy(t2, player_maxs); + VectorCopy(t1, pmove.player_mins); + VectorCopy(t2, pmove.player_maxs); } V_SetContentsColor (r_viewcontents); diff --git a/engine/client/renderer.c b/engine/client/renderer.c index 5e49a2bb..fb2c9ef2 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -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_dodgypcxfiles; +extern char *r_defaultimageextensions; +extern cvar_t r_imageexensions; extern cvar_t r_drawentities; extern cvar_t r_drawviewmodel; extern cvar_t r_drawworld; @@ -599,6 +601,9 @@ void Renderer_Init(void) Cvar_Register(&r_dodgytgafiles, "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_lightstylesmooth, 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; - 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[1] = mvp[7] - mvp[6]; r_refdef.frustum[r_refdef.frustum_numplanes].normal[2] = mvp[11] - mvp[10]; diff --git a/engine/client/view.c b/engine/client/view.c index 6168060e..44e72642 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -1276,7 +1276,7 @@ void V_CalcRefdef (playerview_t *pv) if (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 diff --git a/engine/common/com_mesh.c b/engine/common/com_mesh.c index 52c5328a..7225db74 100644 --- a/engine/common/com_mesh.c +++ b/engine/common/com_mesh.c @@ -197,6 +197,11 @@ void Mod_NormaliseTextureVectors(vec3_t *n, vec3_t *s, vec3_t *t, int v) 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]); VectorMA(s[i], f, n[i], tmp); VectorNormalize2(tmp, s[i]); @@ -4308,7 +4313,7 @@ qboolean QDECL Mod_LoadQ3Model(model_t *mod, void *buffer) R_BuildDefaultTexnums(NULL, shaders[i]); 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++; @@ -6174,7 +6179,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer) shaders[i] = R_RegisterSkin(skin[i].name, mod->name); R_BuildDefaultTexnums(NULL, shaders[i]); 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); #endif diff --git a/engine/common/common.c b/engine/common/common.c index c2967c06..7bb90899 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -2082,15 +2082,15 @@ unsigned int utf8_decode(int *error, const void *in, char **out) 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; - 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; 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; charcode = 0; @@ -2173,9 +2173,10 @@ unsigned int utf8_encode(void *out, unsigned int unicode, int maxlen) 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'}; + //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)) { //quake compatible chars if (maxlen < 1) @@ -2183,54 +2184,11 @@ unsigned int qchar_encode(char *out, unsigned int unicode, int maxlen) *out++ = unicode; 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 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 + else if (!markup) + { if (maxlen < 1) return 0; - *out++ = unicode; + *out++ = '?'; return 1; } 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) return utf8_encode(out, unicode, maxlen); else if (com_parseutf8.ival) - return iso88591_encode(out, unicode, maxlen); + return iso88591_encode(out, unicode, maxlen, markup); else - return qchar_encode(out, unicode, maxlen); + return qchar_encode(out, unicode, maxlen, markup); } //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; char *end = in + buffersize; int chars = 0; for(chars = 0; in < end && *in; chars+=1) { - unicode_decode(&error, in, &in); + unicode_decode(&error, in, &in, markup); if (in > end) break; //exceeded buffer size uncleanly @@ -2300,7 +2315,7 @@ unsigned int unicode_charcount(char *in, size_t buffersize) } //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; int error; @@ -2310,19 +2325,19 @@ unsigned int unicode_byteofsfromcharofs(char *str, unsigned int charofs) if (chars >= charofs) return in - str; - unicode_decode(&error, in, &in); + unicode_decode(&error, in, &in, markup); } return in - str; } //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; char *end = str + byteofs; int chars = 0; for(chars = 0; str < end && *str; chars+=1) { - unicode_decode(&error, str, &str); + unicode_decode(&error, str, &str, markup); if (str > end) break; //exceeded buffer size uncleanly @@ -2348,7 +2363,7 @@ int towlower(int c) } #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). //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) { - c = unicode_decode(&error, in, &in); + c = unicode_decode(&error, in, &in, markup); if (c >= 0xe020 && c <= 0xe07f) //quake-char-aware. c = towupper(c & 0x7f) + (c & 0xff80); else c = towupper(c); - l = unicode_encode(out, c, outsize - l); + l = unicode_encode(out, c, outsize - l, markup); out += l; } *out = 0; @@ -2372,7 +2387,7 @@ size_t unicode_strtoupper(char *in, char *out, size_t outsize) 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). //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) { - c = unicode_decode(&error, in, &in); + c = unicode_decode(&error, in, &in, markup); if (c >= 0xe020 && c <= 0xe07f) //quake-char-aware. c = towlower(c & 0x7f) + (c & 0xff80); else c = towlower(c); - l = unicode_encode(out, c, outsize - l); + l = unicode_encode(out, c, outsize - l, markup); out += l; } *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)) continue; - c = unicode_encode(out, (*str++ & CON_CHARMASK), outsize-1); + c = unicode_encode(out, (*str++ & CON_CHARMASK), outsize-1, !ignoreflags); if (!c) break; outsize -= c; diff --git a/engine/common/common.h b/engine/common/common.h index 81972cc9..9fa6e434 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -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 unsigned int utf8_decode(int *error, const void *in, char **out); unsigned int utf8_encode(void *out, unsigned int unicode, int maxlen); -unsigned int iso88591_encode(char *out, unsigned int unicode, int maxlen); -unsigned int qchar_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, qboolean markup); unsigned int COM_DeQuake(conchar_t chr); //handles whatever charset is active, including ^U stuff. -unsigned int unicode_byteofsfromcharofs(char *str, unsigned int charofs); -unsigned int unicode_charofsfrombyteofs(char *str, unsigned int byteofs); -unsigned int unicode_encode(char *out, unsigned int unicode, int maxlen); -unsigned int unicode_decode(int *error, const void *in, char **out); -size_t unicode_strtolower(char *in, char *out, size_t outsize); -size_t unicode_strtoupper(char *in, char *out, size_t outsize); -unsigned int unicode_charcount(char *in, size_t buffersize); +unsigned int unicode_byteofsfromcharofs(char *str, unsigned int charofs, qboolean markup); +unsigned int unicode_charofsfrombyteofs(char *str, unsigned int byteofs, qboolean markup); +unsigned int unicode_encode(char *out, unsigned int unicode, int maxlen, qboolean markup); +unsigned int unicode_decode(int *error, const void *in, char **out, qboolean markup); +size_t unicode_strtolower(char *in, char *out, size_t outsize, qboolean markup); +size_t unicode_strtoupper(char *in, char *out, size_t outsize, qboolean markup); +unsigned int unicode_charcount(char *in, size_t buffersize, qboolean markup); char *COM_SkipPath (const char *pathname); void COM_StripExtension (const char *in, char *out, int outlen); diff --git a/engine/common/fs.c b/engine/common/fs.c index d2509921..5f554543 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -786,11 +786,22 @@ Sets com_filesize and one of handle or file //returns -1 if couldn't find. int FS_FLocateFile(const char *filename, FSLF_ReturnType_e returntype, flocation_t *loc) { - int depth=0, len; + int depth=0; searchpath_t *search; char cleanpath[MAX_QPATH]; + flocation_t allownoloc; 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)); if (!filename) @@ -810,60 +821,98 @@ int FS_FLocateFile(const char *filename, FSLF_ReturnType_e returntype, flocation else 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) { depth += ((search->flags & SPF_EXPLICIT) || returntype == FSLFRT_DEPTH_ANYPATH); 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; - loc->search = search; - len = loc->len; - } - else - len = 0; + search->flags |= fs_referencetype; + loc->search = search; + com_file_copyprotected = !!(search->flags & SPF_COPYPROTECTED); com_file_untrusted = !!(search->flags & SPF_UNTRUSTED); - goto out; + break; } } } - if (fs_puremode < 2) + if (fs_puremode < 2 && found == FF_NOTFOUND) { -// -// search through the path, one element at a time -// + // optionally check the non-pure paths too. for (search = com_searchpaths ; search ; search = search->next) { depth += ((search->flags & SPF_EXPLICIT) || returntype == FSLFRT_DEPTH_ANYPATH); 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; - if (loc) - { - loc->search = search; - len = loc->len; - } - else - len = 1; + loc->search = search; com_file_copyprotected = !!(search->flags & SPF_COPYPROTECTED); com_file_untrusted = !!(search->flags & SPF_UNTRUSTED); - goto out; + break; } } } fail: - if (loc) - loc->search = NULL; - depth = 0x7fffffff; - len = -1; -out: + if (found == FF_SYMLINK) + { + static int blocklink; + if (blocklink < 4 && loc->len < MAX_QPATH) + { + //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) { @@ -876,11 +925,19 @@ out: Con_Printf("Failed\n"); */ if (returntype == FSLFRT_IFFOUND) - return len != -1; + return (found != FF_NOTFOUND) && (loc->len != -1); else if (returntype == FSLFRT_LENGTH) - return len; + { + if (found == FF_NOTFOUND) + return -1; + return loc->len; + } else + { + if (found == FF_NOTFOUND) + return 0x7fffffff; return depth; + } } char *FS_WhichPackForLocation(flocation_t *loc, qboolean makereferenced) diff --git a/engine/common/fs.h b/engine/common/fs.h index 896117a8..8b43a77e 100644 --- a/engine/common/fs.h +++ b/engine/common/fs.h @@ -2,6 +2,10 @@ #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 { bucket_t buck; @@ -14,26 +18,26 @@ extern int fs_hash_files; //for tracking efficiency. no functional use. struct searchpath_s; struct searchpathfuncs_s { - int fsver; - void (QDECL *ClosePath)(searchpathfuncs_t *handle); + int fsver; + void (QDECL *ClosePath)(searchpathfuncs_t *handle); - 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)); - qboolean (QDECL *FindFile)(searchpathfuncs_t *handle, flocation_t *loc, const char *name, void *hashedresult); //true if found (hashedresult can be NULL) + 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)); + 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 //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) - int (QDECL *EnumerateFiles)(searchpathfuncs_t *handle, const char *match, int (QDECL *func)(const char *fname, int fsize, void *parm, searchpathfuncs_t *spath), void *parm); + 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) + int (QDECL *EnumerateFiles)(searchpathfuncs_t *handle, const char *match, int (QDECL *func)(const char *fname, int fsize, void *parm, searchpathfuncs_t *spath), void *parm); - int (QDECL *GeneratePureCRC) (searchpathfuncs_t *handle, int seed, int usepure); + int (QDECL *GeneratePureCRC) (searchpathfuncs_t *handle, int seed, int usepure); - vfsfile_t *(QDECL *OpenVFS)(searchpathfuncs_t *handle, flocation_t *loc, const char *mode); + vfsfile_t * (QDECL *OpenVFS)(searchpathfuncs_t *handle, flocation_t *loc, const char *mode); - qboolean (QDECL *PollChanges)(searchpathfuncs_t *handle); //returns true if there were changes + qboolean (QDECL *PollChanges)(searchpathfuncs_t *handle); //returns true if there were changes - qboolean (QDECL *RenameFile)(searchpathfuncs_t *handle, const char *oldname, const char *newname); //returns true on success, false if source doesn't exist, or if dest does. - qboolean (QDECL *RemoveFile)(searchpathfuncs_t *handle, const char *filename); //returns true on success, false if it wasn't found or is readonly. - qboolean (QDECL *MkDir)(searchpathfuncs_t *handle, const char *filename); //is this really needed? + qboolean (QDECL *RenameFile)(searchpathfuncs_t *handle, const char *oldname, const char *newname); //returns true on success, false if source doesn't exist, or if dest does. + qboolean (QDECL *RemoveFile)(searchpathfuncs_t *handle, const char *filename); //returns true on success, false if it wasn't found or is readonly. + qboolean (QDECL *MkDir)(searchpathfuncs_t *handle, const char *filename); //is this really needed? }; //searchpathfuncs_t *(QDECL *OpenNew)(vfsfile_t *file, const char *desc); //returns a handle to a new pak/path diff --git a/engine/common/fs_pak.c b/engine/common/fs_pak.c index a415a195..b74ec6ad 100644 --- a/engine/common/fs_pak.c +++ b/engine/common/fs_pak.c @@ -77,7 +77,7 @@ static void QDECL FSPAK_ClosePath(searchpathfuncs_t *handle) Z_Free(pak->files); 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; 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]); } } -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; int i; @@ -98,7 +98,7 @@ qboolean QDECL FSPAK_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const if (pf) { //is this a pointer to a file in this pak? 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 { @@ -121,9 +121,9 @@ qboolean QDECL FSPAK_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const loc->offset = pf->filepos; 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) { @@ -142,7 +142,7 @@ static int QDECL FSPAK_EnumerateFiles (searchpathfuncs_t *handle, const char *ma 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; @@ -178,7 +178,7 @@ typedef struct { unsigned long length; unsigned long currentpos; } 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; int read; @@ -201,12 +201,12 @@ int QDECL VFSPAK_ReadBytes (struct vfsfile_s *vfs, void *buffer, int bytestoread 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. Sys_Error("Cannot write to pak files\n"); 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; if (pos < 0 || pos > vfsp->length) @@ -215,23 +215,23 @@ qboolean QDECL VFSPAK_Seek (struct vfsfile_s *vfs, unsigned long pos) 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; 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; return vfsp->length; } -void QDECL VFSPAK_Close(vfsfile_t *vfs) +static void QDECL VFSPAK_Close(vfsfile_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) 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; vfspack_t *vfs; @@ -261,7 +261,7 @@ vfsfile_t *QDECL FSPAK_OpenVFS(searchpathfuncs_t *handle, flocation_t *loc, cons 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; f = FSPAK_OpenVFS(handle, loc, "rb"); diff --git a/engine/common/fs_stdio.c b/engine/common/fs_stdio.c index 74ef9ce2..c86f74de 100644 --- a/engine/common/fs_stdio.c +++ b/engine/common/fs_stdio.c @@ -240,14 +240,14 @@ static void QDECL FSSTDIO_BuildHash(searchpathfuncs_t *handle, int depth, void ( sp->AddFileHash = AddFileHash; 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; int len; char netpath[MAX_OSPATH]; if (hashedresult && (void *)hashedresult != handle) - return false; + return FF_NOTFOUND; /* if (!static_registered) @@ -272,7 +272,7 @@ static qboolean QDECL FSSTDIO_FLocate(searchpathfuncs_t *handle, flocation_t *lo { FILE *f = fopen(netpath, "rb"); if (!f) - return false; + return FF_NOTFOUND; fseek(f, 0, SEEK_END); len = ftell(f); @@ -286,7 +286,7 @@ static qboolean QDECL FSSTDIO_FLocate(searchpathfuncs_t *handle, flocation_t *lo loc->index = 0; 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) { diff --git a/engine/common/fs_win32.c b/engine/common/fs_win32.c index 632f765f..8fc9c6d0 100644 --- a/engine/common/fs_win32.c +++ b/engine/common/fs_win32.c @@ -333,7 +333,7 @@ static void QDECL VFSW32_BuildHash(searchpathfuncs_t *handle, int hashdepth, voi wp->hashdepth = hashdepth; 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; FILE *f; @@ -343,7 +343,7 @@ static qboolean QDECL VFSW32_FLocate(searchpathfuncs_t *handle, flocation_t *loc if (hashedresult && (void *)hashedresult != wp) - return false; + return FF_NOTFOUND; /* if (!static_registered) @@ -361,7 +361,7 @@ static qboolean QDECL VFSW32_FLocate(searchpathfuncs_t *handle, flocation_t *loc else f = _wfopen(widen(wide, sizeof(wide), netpath), L"rb"); if (!f) - return false; + return FF_NOTFOUND; fseek(f, 0, SEEK_END); 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); } - return true; + return FF_FOUND; } 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); } -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; 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); 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; char syspath[MAX_OSPATH]; snprintf (syspath, sizeof(syspath)-1, "%s/%s", wp->rootpath, filename); 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; char syspath[MAX_OSPATH]; diff --git a/engine/common/fs_zip.c b/engine/common/fs_zip.c index 449cc7bc..986e7ff0 100644 --- a/engine/common/fs_zip.c +++ b/engine/common/fs_zip.c @@ -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]); } } -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; int i; zipfile_t *zip = (void*)handle; + int ret = FF_NOTFOUND; // look through all the pak file elements if (pf) { //is this a pointer to a file in this pak? 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 { @@ -314,6 +315,7 @@ static qboolean QDECL FSZIP_FLocate(searchpathfuncs_t *handle, flocation_t *loc, if (pf) { + ret = FF_FOUND; if (loc) { 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->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); // if (loc->offset<0) // { //file not found, or is compressed. @@ -329,9 +332,11 @@ static qboolean QDECL FSZIP_FLocate(searchpathfuncs_t *handle, flocation_t *loc, // 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) diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index 981b2d74..35dbf086 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -360,8 +360,8 @@ static vec2_t *map_vertstmexcoords; static vec2_t *map_vertlstmexcoords[MAXRLIGHTMAPS]; static vec4_t *map_colors4f_array[MAXRLIGHTMAPS]; static vec3_t *map_normals_array; -static vec3_t *map_svector_array; -static vec3_t *map_tvector_array; +//static vec3_t *map_svector_array; +//static vec3_t *map_tvector_array; q3cface_t *map_faces; static int numfaces; @@ -2085,7 +2085,8 @@ qboolean CModQ3_LoadVertexes (lump_t *l) { q3dvertex_t *in; vecV_t *out; - vec3_t *nout, *sout, *tout; + vec3_t *nout; + //, *sout, *tout; int i, count, j; vec2_t *lmout, *stout; vec4_t *cout; @@ -2109,8 +2110,8 @@ qboolean CModQ3_LoadVertexes (lump_t *l) lmout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*lmout)); cout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*cout)); nout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*nout)); - sout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*nout)); - tout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*nout)); +// sout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*nout)); +// tout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*nout)); map_verts = out; map_vertstmexcoords = stout; for (i = 0; i < MAXRLIGHTMAPS; i++) @@ -2119,8 +2120,8 @@ qboolean CModQ3_LoadVertexes (lump_t *l) map_colors4f_array[i] = cout; } map_normals_array = nout; - map_svector_array = sout; - map_tvector_array = tout; +// map_svector_array = sout; +// map_tvector_array = tout; numvertexes = count; for ( i=0 ; imemgroup, MAXRLIGHTMAPS*count*sizeof(*lmout)); cout = ZG_Malloc(&loadmodel->memgroup, MAXRLIGHTMAPS*count*sizeof(*cout)); nout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*nout)); - sout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*sout)); - tout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*tout)); +// sout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*sout)); +// tout = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*tout)); map_verts = out; map_vertstmexcoords = stout; for (sty = 0; sty < MAXRLIGHTMAPS; sty++) @@ -2183,8 +2185,8 @@ qboolean CModRBSP_LoadVertexes (lump_t *l) map_colors4f_array[sty] = cout + sty*count; } map_normals_array = nout; - map_svector_array = sout; - map_tvector_array = tout; +// map_svector_array = sout; +// map_tvector_array = tout; numvertexes = count; for ( i=0 ; iprogs, 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); + 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) { // entity is trapped in another solid VectorClear (pmove.velocity); @@ -394,7 +461,7 @@ void PM_Friction (void) // if the leading edge is over a dropoff, increase friction 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[2] = pmove.origin[2] + player_mins[2]; + start[2] = pmove.origin[2] + pmove.player_mins[2]; stop[2] = start[2] - 34; trace = PM_PlayerTrace (start, stop, MASK_PLAYERSOLID); if (trace.fraction == 1) @@ -725,12 +792,12 @@ void PM_CategorizePosition (void) if (pmove.pm_type == PM_WALLWALK) { vec3_t tmin,tmax; - VectorCopy(player_mins, tmin); - VectorCopy(player_maxs, tmax); + VectorCopy(pmove.player_mins, tmin); + VectorCopy(pmove.player_maxs, tmax); VectorMA(pmove.origin, -48, up, point); trace = PM_TraceLine(pmove.origin, point); - VectorCopy(tmin, player_mins); - VectorCopy(tmax, player_maxs); + VectorCopy(tmin, pmove.player_mins); + VectorCopy(tmax, pmove.player_maxs); if (trace.fraction < 1) VectorNegate(trace.plane.normal, pmove.gravitydir); @@ -771,19 +838,19 @@ void PM_CategorizePosition (void) pmove.waterlevel = 0; 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); if (cont & FTECONTENTS_FLUID) { pmove.watertype = cont; 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); if (cont & FTECONTENTS_FLUID) { 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); if (cont & FTECONTENTS_FLUID) pmove.waterlevel = 3; @@ -807,7 +874,7 @@ void PM_CategorizePosition (void) 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) { pmove.onladder = true; @@ -945,7 +1012,7 @@ void PM_CheckWaterJump (void) VectorNormalize (flatforward); 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); if (!(cont & FTECONTENTS_SOLID)) return; diff --git a/engine/common/pmove.h b/engine/common/pmove.h index bc6d562c..3556097a 100644 --- a/engine/common/pmove.h +++ b/engine/common/pmove.h @@ -42,9 +42,10 @@ typedef struct vec3_t angles; model_t *model; // only for bsp models vec3_t mins, maxs; // only for non-bsp models - unsigned short info; // for client or server to identify - qbyte nonsolid; - qbyte notouch; + unsigned int info; // for client or server to identify + qbyte nonsolid; //contributes to contents, but does not block. FIXME: why not just use the contentsmask directly? + 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; } physent_t; @@ -62,6 +63,8 @@ typedef struct int jump_msec; // msec since last jump float waterjumptime; int pm_type; + vec3_t player_mins; + vec3_t player_maxs; // world state int numphysent; @@ -82,6 +85,8 @@ typedef struct // when onground is true int waterlevel; int watertype; + + struct world_s *world; } playermove_t; typedef struct { diff --git a/engine/common/pmovetst.c b/engine/common/pmovetst.c index 52dabe85..c91ab0e9 100644 --- a/engine/common/pmovetst.c +++ b/engine/common/pmovetst.c @@ -19,15 +19,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #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); static hull_t box_hull; static mclipnode_t box_clipnodes[6]; static mplane_t box_planes[6]; -extern vec3_t player_mins; -extern vec3_t player_maxs; - /* =================== PM_InitBoxHull @@ -185,7 +182,7 @@ int PM_ExtraBoxContents (vec3_t p) { 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; if (tr.startsolid) pc |= pe->forcecontentsmask; @@ -193,9 +190,9 @@ int PM_ExtraBoxContents (vec3_t p) } 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] && - p[1]+player_maxs[1] >= pe->origin[1]+pe->mins[1] && p[1]+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]) + 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]+pmove.player_maxs[1] >= pe->origin[1]+pe->mins[1] && p[1]+pmove.player_mins[1] <= pe->origin[1]+pe->maxs[1] && + 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; } } @@ -212,7 +209,7 @@ LINE TESTING IN HULLS */ /*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; int i; @@ -284,7 +281,7 @@ qboolean PM_TestPlayerPosition (vec3_t pos) if (pe->info == pmove.skipent) continue; - if (pe->nonsolid) + if (pe->nonsolid || pe->isportal) continue; if (pe->forcecontentsmask && !(pe->forcecontentsmask & MASK_PLAYERSOLID)) @@ -293,15 +290,15 @@ qboolean PM_TestPlayerPosition (vec3_t pos) // get the clipping hull 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; if (trace.allsolid) return false; //solid } else { - VectorSubtract (pe->mins, player_maxs, mins); - VectorSubtract (pe->maxs, player_mins, maxs); + VectorSubtract (pe->mins, pmove.player_maxs, mins); + VectorSubtract (pe->maxs, pmove.player_mins, maxs); hull = PM_HullForBox (mins, maxs); 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; - VectorSubtract (pe->mins, player_maxs, mins); - VectorSubtract (pe->maxs, player_mins, maxs); + VectorSubtract (pe->mins, pmove.player_maxs, mins); + VectorSubtract (pe->maxs, pmove.player_mins, maxs); PM_HullForBox (mins, maxs); // 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; } else { // 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; } if (trace.allsolid) trace.startsolid = true; + + if (trace.startsolid && pe->isportal) + continue; + if (trace.startsolid) { // 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. trace_t PM_TraceLine (vec3_t start, vec3_t end) { - VectorClear(player_mins); - VectorClear(player_maxs); + VectorClear(pmove.player_mins); + VectorClear(pmove.player_maxs); return PM_PlayerTrace(start, end, MASK_PLAYERSOLID); } diff --git a/engine/common/pr_bgcmd.c b/engine/common/pr_bgcmd.c index 6a21e9cc..252cb838 100644 --- a/engine/common/pr_bgcmd.c +++ b/engine/common/pr_bgcmd.c @@ -9,6 +9,8 @@ #include #define VMUTF8 0 +#define VMUTF8MARKUP false + static char *cvargroup_progs = "Progs variables"; @@ -2017,9 +2019,9 @@ void QCBUILTIN PF_strncasecmp (pubprogfuncs_t *prinst, struct globalvars_s *pr_g if (VMUTF8) { - aofs = aofs?unicode_byteofsfromcharofs(a, aofs):0; - bofs = bofs?unicode_byteofsfromcharofs(b, bofs):0; - len = max(unicode_byteofsfromcharofs(a+aofs, len), unicode_byteofsfromcharofs(b+bofs, len)); + aofs = aofs?unicode_byteofsfromcharofs(a, aofs, VMUTF8MARKUP):0; + bofs = bofs?unicode_byteofsfromcharofs(b, bofs, VMUTF8MARKUP):0; + len = max(unicode_byteofsfromcharofs(a+aofs, len, VMUTF8MARKUP), unicode_byteofsfromcharofs(b+bofs, len, VMUTF8MARKUP)); } else { @@ -2050,9 +2052,9 @@ void QCBUILTIN PF_strncmp (pubprogfuncs_t *prinst, struct globalvars_s *pr_globa if (VMUTF8) { - aofs = aofs?unicode_byteofsfromcharofs(a, aofs):0; - bofs = bofs?unicode_byteofsfromcharofs(b, bofs):0; - len = max(unicode_byteofsfromcharofs(a+aofs, len), unicode_byteofsfromcharofs(b+bofs, len)); + aofs = aofs?unicode_byteofsfromcharofs(a, aofs, VMUTF8MARKUP):0; + bofs = bofs?unicode_byteofsfromcharofs(b, bofs, VMUTF8MARKUP):0; + len = max(unicode_byteofsfromcharofs(a+aofs, len, VMUTF8MARKUP), unicode_byteofsfromcharofs(b+bofs, len, VMUTF8MARKUP)); } else { @@ -2280,7 +2282,7 @@ void QCBUILTIN PF_chr2str (pubprogfuncs_t *prinst, struct globalvars_s *pr_globa { ch = G_FLOAT(OFS_PARM0 + i*3); 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 *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 (ofs < 0) - ofs = unicode_charcount(instr, 1<<30)+ofs; - ofs = unicode_byteofsfromcharofs(instr, ofs); + ofs = unicode_charcount(instr, 1<<30, VMUTF8MARKUP)+ofs; + ofs = unicode_byteofsfromcharofs(instr, ofs, VMUTF8MARKUP); } else { @@ -2312,7 +2314,7 @@ void QCBUILTIN PF_str2chr (pubprogfuncs_t *prinst, struct globalvars_s *pr_globa if (ofs && (ofs < 0 || ofs > strlen(instr))) G_FLOAT(OFS_RETURN) = '\0'; 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 @@ -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; if (VMUTF8) - firstofs = unicode_byteofsfromcharofs(instr, firstofs); + firstofs = unicode_byteofsfromcharofs(instr, firstofs, VMUTF8MARKUP); 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) G_FLOAT(OFS_RETURN) = -1; 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 @@ -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... if (VMUTF8) - slen = unicode_charcount(s, 1<<30); + slen = unicode_charcount(s, 1<<30, VMUTF8MARKUP); else slen = strlen(s); @@ -2545,8 +2547,8 @@ void QCBUILTIN PF_substring (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo if (VMUTF8) { - start = unicode_byteofsfromcharofs(s, start); - length = unicode_byteofsfromcharofs(s+start, length); + start = unicode_byteofsfromcharofs(s, start, VMUTF8MARKUP); + length = unicode_byteofsfromcharofs(s+start, length, VMUTF8MARKUP); } 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) { 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 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 result[8192]; - unicode_strtolower(in, result, sizeof(result)); + unicode_strtolower(in, result, sizeof(result), VMUTF8MARKUP); 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 result[8192]; - unicode_strtoupper(in, result, sizeof(result)); + unicode_strtoupper(in, result, sizeof(result), VMUTF8MARKUP); RETURN_TSTRING(result); } @@ -2724,7 +2726,7 @@ void QCBUILTIN PF_strftime (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob else tm = gmtime(&ctime); strftime(result, sizeof(result), in, tm); - unicode_strtoupper(result, uresult, sizeof(uresult)); + unicode_strtoupper(result, uresult, sizeof(uresult), VMUTF8MARKUP); RETURN_TSTRING(uresult); } @@ -3762,7 +3764,94 @@ void QCBUILTIN PF_randomvector (pubprogfuncs_t *prinst, struct globalvars_s *pr_ 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) +//FIXME: support gravitydir void QCBUILTIN PF_vectoyaw (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { float *value1; diff --git a/engine/common/pr_common.h b/engine/common/pr_common.h index 78c127e6..cf072749 100644 --- a/engine/common/pr_common.h +++ b/engine/common/pr_common.h @@ -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_normalize (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_vectoangles (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_rotatevectorsbyangles (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); diff --git a/engine/common/q1bsp.c b/engine/common/q1bsp.c index 13924acb..99b22e01 100644 --- a/engine/common/q1bsp.c +++ b/engine/common/q1bsp.c @@ -388,16 +388,20 @@ struct traceinfo_s #if 0 #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; + if (!enqueue) + cl_numstris = 0; + if (cl_numstris == cl_maxstris) { cl_maxstris+=8; cl_stris = BZ_Realloc(cl_stris, sizeof(*cl_stris)*cl_maxstris); } 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->firstvert = cl_numstrisvert; 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->numvert += 4; + + if (!enqueue) + { +// int oldents = cl_numvisedicts; +// cl_numvisedicts = 0; + BE_DrawWorld(false, NULL); + cl_numstris = 0; +// cl_numvisedicts = oldents; + } } #endif diff --git a/engine/common/unzip.c b/engine/common/unzip.c index 7bccdd83..a7937b51 100644 --- a/engine/common/unzip.c +++ b/engine/common/unzip.c @@ -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 */ -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, 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) { + char *szComment, unsigned long commentBufferSize, + int *issymlink) { unz_s* s; unz_file_info file_info; unz_file_info_internal file_info_internal = {0}; @@ -369,6 +359,9 @@ local int unzlocal_GetCurrentFileInfoInternal (unzFile file, unsigned long uMagic = 0; long lSeek=0; + if (issymlink) + *issymlink = 0; + if (!file) return UNZ_PARAMERROR; s=(unz_s*)file; 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 (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; } @@ -492,7 +500,8 @@ extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, szFileName,fileNameBufferSize, extraField,extraFieldBufferSize, - szComment,commentBufferSize); + szComment,commentBufferSize, + NULL); } /* @@ -508,7 +517,7 @@ extern int ZEXPORT unzGoToFirstFile (unzFile file) { s->num_file=0; err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, &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); return err; } @@ -533,19 +542,20 @@ extern int ZEXPORT unzGoToNextFile (unzFile file) { s->num_file++; err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, &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); return err; } extern int ZEXPORT unzLocateFileMy (unzFile file, unsigned long num, unsigned long pos) { + int islink; unz_s* s; s = (unz_s *)file; s->pos_in_central_dir = pos; s->num_file = num; - unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,&s->cur_file_info_internal,NULL,0,NULL,0,NULL,0); - return 1; + unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,&s->cur_file_info_internal,NULL,0,NULL,0,NULL,0,&islink); + return islink?2:1; } diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index 2baccd7a..cd6e5c57 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -326,10 +326,10 @@ void GL_SetShaderState2D(qboolean is2d) BE_SelectMode(BEM_STANDARD); - if (cl.paused || cls.state < ca_active) +// if (cl.paused || cls.state < ca_active) shaderstate.updatetime = r_refdef.time; - else - shaderstate.updatetime = cl.servertime; +// else +// shaderstate.updatetime = cl.servertime; BE_SelectEntity(&r_worldentity); 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); R_GenDlightBatches(batches); shaderstate.curentity = &r_worldentity; - if (cl.paused || cls.state < ca_active) +// if (cl.paused || cls.state < ca_active) shaderstate.updatetime = r_refdef.time; - else - shaderstate.updatetime = cl.servertime; +// else +// shaderstate.updatetime = cl.servertime; GLBE_SelectEntity(&r_worldentity); @@ -4831,7 +4831,7 @@ void GLBE_DrawWorld (qboolean drawworld, qbyte *vis) } GLBE_SelectEntity(&r_worldentity); - shaderstate.curtime = shaderstate.updatetime = realtime; +// shaderstate.curtime = shaderstate.updatetime = realtime; shaderstate.identitylighting = 1; diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index 3f459f7b..9437f70e 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -2511,7 +2511,7 @@ void ModQ1_Batches_BuildQ1Q2Poly(model_t *mod, msurface_t *surf, void *cookie) VectorNegate(surf->plane->normal, mesh->normals_array[i]); else 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]); //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]); diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index 33d55656..adc5faa0 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -565,7 +565,8 @@ void R_RenderScene (void) R_SetupGL (stereooffset[i]); TRACE(("dbg: calling R_SetFrustrum\n")); - R_SetFrustum (r_refdef.m_projection, r_refdef.m_view); + if (!r_refdef.recurse) + R_SetFrustum (r_refdef.m_projection, r_refdef.m_view); 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[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) { entity_t *view; @@ -783,6 +785,8 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2], plane_t plane; float vmat[16]; refdef_t oldrefdef; + vec3_t r; + int i; mesh_t *mesh = batch->mesh[batch->firstmesh]; 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)*/ //fixme: pvs is surely wrong? - r_refdef.flipcull ^= SHADER_CULL_FLIP; +// r_refdef.flipcull ^= SHADER_CULL_FLIP; R_MirrorMatrix(&plane); 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; 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.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) 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)) { - 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); 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 { @@ -962,19 +976,33 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2], qglClipPlane(GL_CLIP_PLANE0, glplane); qglEnable(GL_CLIP_PLANE0); }*/ + R_SetFrustum (r_refdef.m_projection, vmat); if (r_refdef.frustum_numplanes < MAXFRUSTUMPLANES) { - r_refdef.frustum[r_refdef.frustum_numplanes].normal[0] = plane.normal[0]; - r_refdef.frustum[r_refdef.frustum_numplanes].normal[1] = plane.normal[1]; - r_refdef.frustum[r_refdef.frustum_numplanes].normal[2] = plane.normal[2]; - r_refdef.frustum[r_refdef.frustum_numplanes].dist = plane.dist + 0.01; + extern int SignbitsForPlane (mplane_t *out); + mplane_t fp; + VectorCopy(plane.normal, fp.normal); + fp.dist = plane.dist; + + if (DotProduct(fp.normal, vpn) < 0) + { + VectorNegate(fp.normal, fp.normal); + fp.dist *= -1; + } + + fp.type = PLANE_ANYZ; + fp.signbits = SignbitsForPlane (&fp); if (portaltype == 1 || portaltype == 2) - R_ObliqueNearClip(vmat, &r_refdef.frustum[r_refdef.frustum_numplanes]); - r_refdef.frustum_numplanes++; + 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; } - GL_CullFace(0); + //force culling to update to match the new front face. +// memcpy(r_refdef.m_view, vmat, sizeof(float)*16); if (depthmasklist) { /*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); 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; 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(); GLBE_SelectMode(BEM_DEPTHONLY); 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; 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(); // if (qglClipPlane) // 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; /*broken stuff*/ @@ -1036,7 +1086,7 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2], qglLoadMatrixf(r_refdef.m_view); } - GL_CullFace(0); + GL_CullFace(0);//make sure flipcull reversion takes effect TRACE(("GLR_DrawPortal: portal drawn\n")); diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index 95677422..79211033 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -4887,6 +4887,8 @@ void Shader_DefaultSkin(char *shortname, shader_t *s, const void *args) "endif\n" "}\n" ); + + s->flags |= SHADER_NOIMAGE; } void Shader_DefaultSkinShell(char *shortname, shader_t *s, const void *args) { diff --git a/engine/gl/gl_vidcocoa.m b/engine/gl/gl_vidcocoa.m index 37485984..18f1fdea 100644 --- a/engine/gl/gl_vidcocoa.m +++ b/engine/gl/gl_vidcocoa.m @@ -612,7 +612,7 @@ void flushCocoa(void) void cocoaGamma(unsigned short *r,unsigned short *g,unsigned short *b) { - CGByteValue gammatable[3*256]; + uint8_t gammatable[3*256]; int i; // convert the gamma values diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index 0ecc687c..dde2af76 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -1117,7 +1117,7 @@ static const char *glsl_hdrs[] = "{\n" "#if defined(RELIEFMAPPING) && !defined(GL_ES)\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" "OffsetVector /= 10.0;\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" "return RT.xy;\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" "tc += OffsetVector;\n" "OffsetVector *= 0.333;\n" diff --git a/engine/gl/r_bishaders.h b/engine/gl/r_bishaders.h index fbe57853..e1dfc263 100644 --- a/engine/gl/r_bishaders.h +++ b/engine/gl/r_bishaders.h @@ -555,7 +555,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "vec3 n, s, t, w;\n" "gl_Position = skeletaltransform_wnst(w,n,s,t);\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.z = dot(eyeminusvertex, n.xyz);\n" "#else\n" @@ -923,7 +923,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "{\n" "vec4 col = texture2D(s_t0, tc);\n" "#ifdef MASK\n" -"if (col.a < 0.5)\n" +"if (col.a < float(MASK))\n" "discard;\n" "#endif\n" "gl_FragColor = fog4blend(col * vc * e_colourident);\n" @@ -1017,7 +1017,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "{\n" "#if defined(OFFSETMAPPING) || defined(SPECULAR)\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.z = dot(eyeminusvertex, v_normal.xyz);\n" "#endif\n" @@ -1683,12 +1683,12 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "gl_Position = skeletaltransform_wnst(w,n,s,t);\n" "tcbase = v_texcoord; //pass the texture coords straight through\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.z = dot(lightminusvertex, n.xyz);\n" "#if defined(SPECULAR)||defined(OFFSETMAPPING)\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.z = dot(eyeminusvertex, n.xyz);\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. "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.z = dot(lightminusvertex, v_normal.xyz); // #if defined(SPECULAR)||defined(OFFSETMAPPING) // 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.z = dot(eyeminusvertex, v_normal.xyz); // #endif diff --git a/engine/gl/shader.h b/engine/gl/shader.h index 57023d9a..d0e8ab61 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -665,9 +665,6 @@ void D3D11BE_VBO_Destroy(vboarray_t *vearray); void D3D11BE_Scissor(srect_t *rect); #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 void BE_GenerateProgram(shader_t *shader); diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 2d46badd..a33d4a76 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -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) { unsigned int i, n; - extern vec3_t player_maxs, player_mins; extern qbyte playertouch[]; unsigned int msecs; 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->velocity, pmove.velocity); - VectorCopy(ent->v->maxs, player_maxs); - VectorCopy(ent->v->mins, player_mins); + VectorCopy(ent->v->maxs, pmove.player_maxs); + VectorCopy(ent->v->mins, pmove.player_mins); pmove.numphysent = 1; 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); 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_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_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) {"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)"}, {"parseentitydata", PF_parseentitydata, 0, 0, 0, 613, "void(entity e, string s)"}, {"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()"}, {"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)"}, diff --git a/engine/server/progdefs.h b/engine/server/progdefs.h index d0a7a0b6..8b235914 100644 --- a/engine/server/progdefs.h +++ b/engine/server/progdefs.h @@ -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(mass,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 \ 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(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.*/ \ - \ - comfieldfloat(ideal_pitch,NULL)\ - comfieldfloat(pitch_speed,NULL) + comfieldfunction(predraw, ".void()",NULL) /*If present, is called just before it's drawn.*/ typedef struct stdentvars_s //standard = standard for qw { diff --git a/engine/server/sv_ents.c b/engine/server/sv_ents.c index 3d2a7282..d4473a03 100644 --- a/engine/server/sv_ents.c +++ b/engine/server/sv_ents.c @@ -27,6 +27,7 @@ void SV_CleanupEnts(void); extern cvar_t sv_nailhack; extern cvar_t sv_cullentities_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; // 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; 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; qbyte pvsbuffer[(MAX_MAP_LEAFS+7)/8]; - // this is the frame we are creating frame = &client->frameunion.frames[client->netchan.incoming_sequence & UPDATE_MASK]; if (!sv.paused) @@ -3419,11 +3419,13 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore else { clent = client->edict; + if (sv_nopvs.ival) + pvs = NULL; #ifdef HLSERVER - if (svs.gametype == GT_HALFLIFE) + else if (svs.gametype == GT_HALFLIFE) pvs = SVHL_Snapshot_SetupPVS(client, pvsbuffer, sizeof(pvsbuffer)); - else #endif + else pvs = SV_Snapshot_SetupPVS(client, pvsbuffer, sizeof(pvsbuffer)); } diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index b4cc0707..80b1a1b0 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -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_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 @@ -4383,6 +4384,7 @@ void SV_InitLocal (void) Cvar_Register (&sv_minping, cvargroup_servercontrol); Cvar_Register (&sv_nailhack, cvargroup_servercontrol); + Cvar_Register (&sv_nopvs, cvargroup_servercontrol); Cvar_Register (&pext_ezquake_nochunks, cvargroup_servercontrol); Cmd_AddCommand ("sv_impulse", SV_Impulse_f); diff --git a/engine/server/sv_move.c b/engine/server/sv_move.c index bb1bbfa9..a4c69655 100644 --- a/engine/server/sv_move.c +++ b/engine/server/sv_move.c @@ -255,6 +255,8 @@ void World_changeyaw (wedict_t *ent) { 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] ); ideal = ent->v->ideal_yaw; 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); yaw = yaw*M_PI*2 / 360; + //FIXME: gravitydir move[0] = cos(yaw)*dist; move[1] = sin(yaw)*dist; move[2] = 0; diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index 3bd3847f..e0535874 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -53,19 +53,19 @@ cvar_t sv_airaccelerate = SCVAR( "sv_airaccelerate", "0.7"); cvar_t sv_wateraccelerate = SCVAR( "sv_wateraccelerate", "10"); cvar_t sv_friction = SCVAR( "sv_friction", "4"); cvar_t sv_waterfriction = SCVAR( "sv_waterfriction", "4"); -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_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_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_land = CVAR( "sv_sound_land", "demon/dland2.wav"); -cvar_t sv_stepheight = CVARAFD("pm_stepheight", "", - "sv_stepheight", CVAR_SERVERINFO, "If empty, the value 18 will be used instead."); +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."); -cvar_t pm_ktjump = SCVARF("pm_ktjump", "", CVAR_SERVERINFO); -cvar_t pm_bunnyspeedcap = SCVARF("pm_bunnyspeedcap", "", CVAR_SERVERINFO); -cvar_t pm_slidefix = SCVARF("pm_slidefix", "", CVAR_SERVERINFO); -cvar_t pm_slidyslopes = SCVARF("pm_slidyslopes", "", CVAR_SERVERINFO); -cvar_t pm_airstep = SCVARF("pm_airstep", "", CVAR_SERVERINFO); -cvar_t pm_walljump = SCVARF("pm_walljump", "", CVAR_SERVERINFO); +cvar_t pm_ktjump = CVARF("pm_ktjump", "", 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 = CVARF("pm_slidefix", "", CVAR_SERVERINFO); +cvar_t pm_slidyslopes = CVARF("pm_slidyslopes", "", CVAR_SERVERINFO); +cvar_t pm_airstep = CVARF("pm_airstep", "", CVAR_SERVERINFO); +cvar_t pm_walljump = CVARF("pm_walljump", "", CVAR_SERVERINFO); #define cvargroup_serverphysics "server physics variables" void WPhys_Init(void) @@ -86,6 +86,7 @@ void WPhys_Init(void) Cvar_Register (&sv_gameplayfix_noairborncorpse, cvargroup_serverphysics); Cvar_Register (&sv_gameplayfix_multiplethinks, cvargroup_serverphysics); + Cvar_Register (&sv_gameplayfix_stepdown, cvargroup_serverphysics); } #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); //transform origin+velocity etc 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(move, w->g.v_right); 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); 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_up, ent->xv->gravitydir); + VectorCopy(w->g.v_up, ent->xv->gravitydir); //transform the angles too @@ -289,7 +290,7 @@ static void WPhys_PortalTransform(world_t *w, wedict_t *ent, wedict_t *portal, v } else 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); PR_ExecuteProgram (w->progs, portal->xv->camera_transform); 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 from; float firstfrac = trace.fraction; -Con_Printf("Player hit portal %i\n", impact->entnum); + VectorCopy(trace.endpos, from); //just in case VectorSubtract(end, trace.endpos, move); - WPhys_PortalTransform(w, ent, impact, trace.endpos, move); - VectorAdd(trace.endpos, move, end); + WPhys_PortalTransform(w, ent, impact, 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 (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); - trace.fraction = firstfrac + (1-firstfrac)*trace.fraction; - - //if we follow the portal, then we need to fix up some velocities. - if (trace.fraction > 0) - VectorCopy (ent->v->velocity, primal_velocity); } 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) { + vec3_t end; + trace_t trace; + wedict_t *impact; + // regular thinking if (!WPhys_RunThink (w, ent)) return; 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); } @@ -1846,7 +1867,7 @@ static void WPhys_WalkMove (world_t *w, wedict_t *ent, const float *gravitydir) 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; // move down diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index 2c7b914d..ea6a577f 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -112,8 +112,6 @@ extern char cvargroup_serverinfo[]; extern char cvargroup_serverphysics[]; extern char cvargroup_servercontrol[]; -extern vec3_t player_mins, player_maxs; - extern cvar_t pausable; @@ -4822,6 +4820,8 @@ void SV_Pext_f(void) return; host_client->pextknown = true; + host_client->fteprotocolextensions = 0; + host_client->fteprotocolextensions2 = 0; for (i = 1; i < Cmd_Argc(); ) { tag = Cmd_Argv(i++); @@ -5300,6 +5300,7 @@ void AddLinksToPmove ( edict_t *player, areanode_t *node ) edict_t *check; int pl; int i; + int solid; physent_t *pe; model_t *model; @@ -5316,10 +5317,14 @@ void AddLinksToPmove ( edict_t *player, areanode_t *node ) continue; // player's own missile if (check == player) continue; - if ((check->v->solid == SOLID_TRIGGER && check->v->skin < 0) || check->v->solid == SOLID_BSP - || check->v->solid == SOLID_BBOX - || check->v->solid == SOLID_SLIDEBOX - //|| (check->v->solid == SOLID_PHASEH2 && progstype == PROG_H2) //logically matches hexen2, but I hate it + solid = check->v->solid; + if ( + (solid == SOLID_TRIGGER && check->v->skin < 0) + || 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); 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) { case Q1CONTENTS_WATER: @@ -5369,7 +5375,7 @@ void AddLinksToPmove ( edict_t *player, areanode_t *node ) pe->forcecontentsmask = 0; break; } - if (check->v->solid == SOLID_BSP) + if (solid == SOLID_PORTAL || solid == SOLID_BSP) { if(progstype != PROG_H2) 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(&movevars, 0, sizeof(movevars)); - player_mins[0] = sv_player->v->mins[0]; - player_mins[1] = sv_player->v->mins[1]; - player_mins[2] = sv_player->v->mins[2]; + pmove.player_mins[0] = sv_player->v->mins[0]; + pmove.player_mins[1] = sv_player->v->mins[1]; + pmove.player_mins[2] = sv_player->v->mins[2]; - player_maxs[0] = sv_player->v->maxs[0]; - player_maxs[1] = sv_player->v->maxs[1]; - player_maxs[2] = sv_player->v->maxs[2]; + pmove.player_maxs[0] = sv_player->v->maxs[0]; + pmove.player_maxs[1] = sv_player->v->maxs[1]; + pmove.player_maxs[2] = sv_player->v->maxs[2]; VectorCopy(sv_player->xv->gravitydir, pmove.gravitydir); @@ -5884,6 +5890,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse) else pmove.onladder = false; + pmove.world = &sv.world; #if 0 { int before, after; @@ -5898,6 +5905,7 @@ if (sv_player->v->health > 0 && before && !after ) #else PM_PlayerMove (sv.gamespeed); #endif + pmove.world = NULL; host_client->jump_held = pmove.jump_held; 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.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) { @@ -5955,13 +5964,13 @@ if (sv_player->v->health > 0 && before && !after ) } } - player_mins[0] = -16; - player_mins[1] = -16; - player_mins[2] = -24; + pmove.player_mins[0] = -16; + pmove.player_mins[1] = -16; + pmove.player_mins[2] = -24; - player_maxs[0] = 16; - player_maxs[1] = 16; - player_maxs[2] = 32; + pmove.player_maxs[0] = 16; + pmove.player_maxs[1] = 16; + pmove.player_maxs[2] = 32; VectorCopy(sv_player->v->velocity, old_vel); VectorCopy(pmove.velocity, new_vel); diff --git a/engine/server/svhl_game.c b/engine/server/svhl_game.c index d28dda73..b341611f 100644 --- a/engine/server/svhl_game.c +++ b/engine/server/svhl_game.c @@ -1627,8 +1627,6 @@ static void SVHL_RunCmdR(hledict_t *ed, usercmd_t *ucmd) int i; hledict_t *other; extern cvar_t temp1; -extern vec3_t player_mins; -extern vec3_t player_maxs; // chop up very long commands if (ucmd->msec > 50) diff --git a/engine/server/world.c b/engine/server/world.c index c01d1462..3565a6a5 100644 --- a/engine/server/world.c +++ b/engine/server/world.c @@ -1494,7 +1494,7 @@ static void World_ClipToLinks (world_t *w, areanode_t *node, moveclip_t *clip) 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; if (clip->passedict) diff --git a/engine/shaders/glsl/defaultskin.glsl b/engine/shaders/glsl/defaultskin.glsl index 0486e50b..0e78c7f0 100644 --- a/engine/shaders/glsl/defaultskin.glsl +++ b/engine/shaders/glsl/defaultskin.glsl @@ -35,7 +35,7 @@ void main () vec3 n, s, t, w; gl_Position = skeletaltransform_wnst(w,n,s,t); 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.z = dot(eyeminusvertex, n.xyz); #else diff --git a/engine/shaders/glsl/defaultsprite.glsl b/engine/shaders/glsl/defaultsprite.glsl index f2adb6d2..85007fe3 100644 --- a/engine/shaders/glsl/defaultsprite.glsl +++ b/engine/shaders/glsl/defaultsprite.glsl @@ -24,7 +24,7 @@ void main () { vec4 col = texture2D(s_t0, tc); #ifdef MASK - if (col.a < 0.5) + if (col.a < float(MASK)) discard; #endif gl_FragColor = fog4blend(col * vc * e_colourident); diff --git a/engine/shaders/glsl/defaultwall.glsl b/engine/shaders/glsl/defaultwall.glsl index 64d3460a..211d401e 100644 --- a/engine/shaders/glsl/defaultwall.glsl +++ b/engine/shaders/glsl/defaultwall.glsl @@ -42,7 +42,7 @@ void main () { #if defined(OFFSETMAPPING) || defined(SPECULAR) 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.z = dot(eyeminusvertex, v_normal.xyz); #endif diff --git a/engine/shaders/glsl/rtlight.glsl b/engine/shaders/glsl/rtlight.glsl index 165c7691..fa4a1155 100644 --- a/engine/shaders/glsl/rtlight.glsl +++ b/engine/shaders/glsl/rtlight.glsl @@ -58,12 +58,12 @@ void main () gl_Position = skeletaltransform_wnst(w,n,s,t); tcbase = v_texcoord; //pass the texture coords straight through 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.z = dot(lightminusvertex, n.xyz); #if defined(SPECULAR)||defined(OFFSETMAPPING) 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.z = dot(eyeminusvertex, n.xyz); #endif diff --git a/engine/shaders/glsl/terrain.glsl b/engine/shaders/glsl/terrain.glsl index 296524a7..5421be09 100644 --- a/engine/shaders/glsl/terrain.glsl +++ b/engine/shaders/glsl/terrain.glsl @@ -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. lightvector = lightminusvertex; -// lightvector.x = -dot(lightminusvertex, v_svector.xyz); +// lightvector.x = dot(lightminusvertex, v_svector.xyz); // lightvector.y = dot(lightminusvertex, v_tvector.xyz); // lightvector.z = dot(lightminusvertex, v_normal.xyz); // #if defined(SPECULAR)||defined(OFFSETMAPPING) // 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.z = dot(eyeminusvertex, v_normal.xyz); // #endif