diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index 91586d2e5..6522eb1d2 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -33,6 +33,7 @@ extern cvar_t r_lightflicker; extern cvar_t cl_r2g; extern cvar_t r_powerupglow; extern cvar_t v_powerupshell; +extern cvar_t cl_nolerp; extern cvar_t cl_gibfilter, cl_deadbodyfilter; extern int cl_playerindex; @@ -367,13 +368,26 @@ void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int bits, qboolean } if (to->frame != from->frame || move[0] || move[1] || move[2]) { - cl.lerpents[to->number].origin[0] = from->origin[0]; - cl.lerpents[to->number].origin[1] = from->origin[1]; - cl.lerpents[to->number].origin[2] = from->origin[2]; + if (new) //lerp from the new position instead of old, so no lerp + { + cl.lerpents[to->number].origin[0] = to->origin[0]; + cl.lerpents[to->number].origin[1] = to->origin[1]; + cl.lerpents[to->number].origin[2] = to->origin[2]; - cl.lerpents[to->number].angles[0] = from->angles[0]; - cl.lerpents[to->number].angles[1] = from->angles[1]; - cl.lerpents[to->number].angles[2] = from->angles[2]; + cl.lerpents[to->number].angles[0] = to->angles[0]; + cl.lerpents[to->number].angles[1] = to->angles[1]; + cl.lerpents[to->number].angles[2] = to->angles[2]; + } + else + { + cl.lerpents[to->number].origin[0] = from->origin[0]; + cl.lerpents[to->number].origin[1] = from->origin[1]; + cl.lerpents[to->number].origin[2] = from->origin[2]; + + cl.lerpents[to->number].angles[0] = from->angles[0]; + cl.lerpents[to->number].angles[1] = from->angles[1]; + cl.lerpents[to->number].angles[2] = from->angles[2]; + } //we have three sorts of movement. //1: stepping monsters. These have frames and tick at 10fps. //2: physics. Objects moving acording to gravity. @@ -1376,8 +1390,8 @@ void CL_LinkPacketEntities (void) ent->lerpfrac=1; f = 1-ent->lerpfrac; -// if (cl_nolerp.value) -// f = 1; + if (cl_nolerp.value) + f = 1; // calculate origin for (i=0 ; i<3 ; i++) @@ -1759,7 +1773,7 @@ static int MVD_TranslateFlags(int src) CL_ParsePlayerinfo =================== */ -extern int parsecountmod; +extern int parsecountmod, oldparsecountmod; extern double parsecounttime; int lastplayerinfo; void CL_ParsePlayerinfo (void) @@ -1767,7 +1781,7 @@ void CL_ParsePlayerinfo (void) int msec; unsigned int flags; player_info_t *info; - player_state_t *state; + player_state_t *state, *oldstate; int num; int i; int new; @@ -1779,6 +1793,7 @@ void CL_ParsePlayerinfo (void) info = &cl.players[num]; + oldstate = &cl.frames[oldparsecountmod].playerstate[num]; state = &cl.frames[parsecountmod].playerstate[num]; if (cls.demoplayback == DPB_MVD) @@ -1850,6 +1865,7 @@ void CL_ParsePlayerinfo (void) state->pm_type = PM_NORMAL; + TP_ParsePlayerInfo(oldstate, state, info); return; } @@ -2024,6 +2040,8 @@ guess_pm_type: state->pm_type = PM_DEAD; else state->pm_type = PM_NORMAL; + + TP_ParsePlayerInfo(oldstate, state, info); } } @@ -2386,6 +2404,8 @@ void CL_LinkViewModel(void) if (cl.stats[r_refdef.currentplayernum][STAT_ITEMS] & IT_QUAD) ent.flags |= Q2RF_SHELL_BLUE; + if (cl.stats[r_refdef.currentplayernum][STAT_ITEMS] & IT_INVULNERABILITY) + ent.flags |= Q2RF_SHELL_RED; if (!(ent.flags & (Q2RF_SHELL_RED|Q2RF_SHELL_GREEN|Q2RF_SHELL_BLUE))) return; diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 0b4d8607e..684144ad3 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -52,6 +52,7 @@ cvar_t cl_sbar = {"cl_sbar", "0", NULL, CVAR_ARCHIVE}; cvar_t cl_hudswap = {"cl_hudswap", "0", NULL, CVAR_ARCHIVE}; cvar_t cl_maxfps = {"cl_maxfps", "-1", NULL, CVAR_ARCHIVE}; cvar_t cl_nopext = {"cl_nopext", "0", NULL, CVAR_ARCHIVE}; +cvar_t cl_nolerp = {"cl_nolerp", "1"}; cvar_t cfg_save_name = {"cfg_save_name", "fte", NULL, CVAR_ARCHIVE}; @@ -2310,11 +2311,13 @@ void CL_Init (void) Cvar_Register (&r_lightflicker, "Item effects"); Cvar_Register (&cl_r2g, "Item effects"); Cvar_Register (&r_powerupglow, "Item effects"); - Cvar_Register (&r_powerupglow, "v_powerupshell"); + Cvar_Register (&v_powerupshell, "Item effects"); Cvar_Register (&cl_gibfilter, "Item effects"); Cvar_Register (&cl_deadbodyfilter, "Item effects"); + Cvar_Register (&cl_nolerp, "Item effects"); + // // info mirrors // @@ -2421,7 +2424,7 @@ void CL_Init (void) #ifdef _WINDOWS Cmd_AddCommand ("windows", CL_Windows_f); #endif -} +} /* @@ -2902,6 +2905,8 @@ void Host_Init (quakeparms_t *parms) // Con_Printf ("Exe: "__TIME__" "__DATE__"\n"); Con_TPrintf (TL_HEAPSIZE, parms->memsize/ (1024*1024.0)); + Cbuf_AddText ("cl_warncmd 0\n", RESTRICT_LOCAL); + Cbuf_AddText ("+mlook\n", RESTRICT_LOCAL); //fixme: this is bulky, only exec one of these. //who should we imitate? @@ -2976,10 +2981,20 @@ void Host_Init (quakeparms_t *parms) #ifndef NOMEDIA if (!cls.demofile && !cls.state && !media_filmtype) { - if (COM_FDepthFile("video/idlogo.roq", true) > COM_FDepthFile("video/idlog.cin", true)) - Media_PlayFilm("video/idlog.cin"); - else + int ol_depth; + int idcin_depth; + int idroq_depth; + + idcin_depth = COM_FDepthFile("video/idlog.cin", true); //q2 + idroq_depth = COM_FDepthFile("video/idlogo.roq", true); //q2 + ol_depth = COM_FDepthFile("video/openinglogos.roq", true); //jk2 + + if (ol_depth <= idroq_depth || ol_depth <= idcin_depth) + Media_PlayFilm("video/openinglogos.roq"); + else if (idroq_depth <= idcin_depth) Media_PlayFilm("video/idlogo.roq"); + else if (idcin_depth) + Media_PlayFilm("video/idlog.cin"); } #endif diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 6b57c4117..928ce47d1 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -582,8 +582,10 @@ void Model_NextDownload (void) Mod_NowLoadExternal(); } + // all done R_NewMap (); + Hunk_Check (); // make sure nothing is hurt #ifdef Q2CLIENT if (cls.q2server) @@ -2946,7 +2948,7 @@ extern cvar_t cl_chatsound, cl_nofake; return true; } -char printtext[2048]; +char printtext[4096]; void CL_ParsePrint(char *msg, int level) { if (strlen(printtext) + strlen(msg) >= sizeof(printtext)) @@ -3014,13 +3016,10 @@ int getplayerid(char *msg) return -1; } -int getplayerchatcolour(char *msg) +int CL_PlayerChatColour(int id) { - int id; + char *msg; int c; - id = getplayerid(msg); - if (id == -1) //not a user/server - return 1; //primary override. msg = Info_ValueForKey(cl.players[id].userinfo, "tc"); @@ -3045,6 +3044,16 @@ int getplayerchatcolour(char *msg) return cl.players[id].userid; } +int getplayerchatcolour(char *msg) +{ + int id; + id = getplayerid(msg); + if (id == -1) //not a user/server + return 1; + + return CL_PlayerChatColour(id); +} + #define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x); #define SHOWNET2(x, y) if(cl_shownet.value==2)Con_Printf ("%3i:%3i:%s\n", msg_readcount-1, y, x); /* @@ -3142,6 +3151,9 @@ void CL_ParseServerMessage (void) s = MSG_ReadString (); if (i == PRINT_CHAT) { + if (TP_SuppressMessage(s)) + break; //if this was unseen-sent from us, ignore it. + if (CL_ParseChat(s)) { CL_ParsePrint(s, i); diff --git a/engine/client/cl_screen.c b/engine/client/cl_screen.c index 7e0e5d0eb..ae96a9cbc 100644 --- a/engine/client/cl_screen.c +++ b/engine/client/cl_screen.c @@ -1828,6 +1828,7 @@ void SCR_TileClear (void) void SCR_DrawTwoDimensional(int uimenu, qboolean nohud) { RSpeedMark(); + // // draw any areas not covered by the refresh // diff --git a/engine/client/console.c b/engine/client/console.c index 07c6dcda5..78c168466 100644 --- a/engine/client/console.c +++ b/engine/client/console.c @@ -1115,6 +1115,7 @@ breakout: } } +#include "glquake.h" /* ================ Con_DrawConsole @@ -1149,10 +1150,15 @@ void Con_DrawConsole (int lines, qboolean noback) QT_Update(); #endif + if (qglGetError()) + return; + // draw the background if (!noback) Draw_ConsoleBackground (lines); + if (qglGetError()) + return; // draw the text con_current->vislines = lines; @@ -1172,6 +1178,9 @@ void Con_DrawConsole (int lines, qboolean noback) rows--; } + if (qglGetError()) + return; + row = curcon->display; for (i=0 ; iname, -1) #define fieldvector(name) PR_RegisterFieldVar(csqcprogs, ev_vector, #name, (int)&((csqcentvars_t*)0)->name, -1) @@ -156,12 +188,12 @@ csqcfields #undef fieldfunction } -csqcedict_t *csqcent[MAX_EDICTS]; +static csqcedict_t *csqcent[MAX_EDICTS]; #define RETURN_SSTRING(s) (*(char **)&((int *)pr_globals)[OFS_RETURN] = PR_SetString(prinst, s)) //static - exe will not change it. char *PF_TempStr(void); -int csqcentsize; +static int csqcentsize; //pr_cmds.c builtins that need to be moved to a common. void VARGS PR_BIError(progfuncs_t *progfuncs, char *format, ...); @@ -218,6 +250,8 @@ void PF_traceon (progfuncs_t *prinst, struct globalvars_s *pr_globals); void PF_traceoff (progfuncs_t *prinst, struct globalvars_s *pr_globals); void PF_eprint (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_registercvar (progfuncs_t *prinst, struct globalvars_s *pr_globals); + void PF_strstrofs (progfuncs_t *prinst, struct globalvars_s *pr_globals); void PF_str2chr (progfuncs_t *prinst, struct globalvars_s *pr_globals); void PF_chr2str (progfuncs_t *prinst, struct globalvars_s *pr_globals); @@ -240,6 +274,7 @@ void PF_CL_drawsetcliparea (progfuncs_t *prinst, struct globalvars_s *pr_globals void PF_CL_drawresetcliparea (progfuncs_t *prinst, struct globalvars_s *pr_globals); void PF_CL_drawgetimagesize (progfuncs_t *prinst, struct globalvars_s *pr_globals); + #define MAXTEMPBUFFERLEN 1024 void PF_fclose_progs (progfuncs_t *prinst); @@ -415,8 +450,8 @@ static void PF_R_ClearScene (progfuncs_t *prinst, struct globalvars_s *pr_global CL_SwapEntityLists(); - view_frame = &cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK]; - view_message = &view_frame->playerstate[cl.playernum[0]]; + view_frame = NULL;//&cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK]; + view_message = NULL;//&view_frame->playerstate[cl.playernum[plnum]]; V_CalcRefdef(0); //set up the defaults (for player 0) /* VectorCopy(cl.simangles[0], r_refdef.viewangles); @@ -553,6 +588,12 @@ static void PF_R_RenderScene(progfuncs_t *prinst, struct globalvars_s *pr_global { if (cl.worldmodel) R_PushDlights (); +/* + if (cl_csqcdebug.value) + Con_Printf("%f %f %f\n", r_refdef.vieworg[0], + r_refdef.vieworg[1], + r_refdef.vieworg[2]); + */ #ifdef RGLQUAKE if (qrenderer == QR_OPENGL) @@ -562,6 +603,10 @@ static void PF_R_RenderScene(progfuncs_t *prinst, struct globalvars_s *pr_global qglDisable(GL_BLEND); } #endif + + VectorCopy (r_refdef.vieworg, cl.viewent[0].origin); + CalcGunAngle(0); + R_RenderView(); #ifdef RGLQUAKE if (qrenderer == QR_OPENGL) @@ -587,14 +632,14 @@ static void PF_R_RenderScene(progfuncs_t *prinst, struct globalvars_s *pr_global static void PF_cs_getstatf(progfuncs_t *prinst, struct globalvars_s *pr_globals) { int stnum = G_FLOAT(OFS_PARM0); - float val = *(float*)&cl.stats[0][stnum]; //copy float into the stat + float val = *(float*)&cl.stats[plnum][stnum]; //copy float into the stat G_FLOAT(OFS_RETURN) = val; } static void PF_cs_getstati(progfuncs_t *prinst, struct globalvars_s *pr_globals) { //convert an int stat into a qc float. int stnum = G_FLOAT(OFS_PARM0); - int val = cl.stats[0][stnum]; + int val = cl.stats[plnum][stnum]; if (*prinst->callargc > 1) { int first, count; @@ -911,10 +956,221 @@ static void PF_cs_particlesloaded (progfuncs_t *prinst, struct globalvars_s *pr_ G_FLOAT(OFS_RETURN) = P_DescriptionIsLoaded(effectname); } +//get the input commands, and stuff them into some globals. +static void PF_cs_getinputstate (progfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + int f; + usercmd_t *cmd; + + f = G_FLOAT(OFS_PARM0); + if (f > cls.netchan.outgoing_sequence) + { + G_FLOAT(OFS_RETURN) = false; + return; + } + if (f < cls.netchan.outgoing_sequence - UPDATE_MASK || f < 0) + { + G_FLOAT(OFS_RETURN) = false; + return; + } + + // save this command off for prediction + cmd = &cl.frames[f&UPDATE_MASK].cmd[plnum]; + + if (csqcg.input_timelength) + *csqcg.input_timelength = cmd->msec/1000.0f; + if (csqcg.input_angles) + { + csqcg.input_angles[0] = SHORT2ANGLE(cmd->angles[0]); + csqcg.input_angles[1] = SHORT2ANGLE(cmd->angles[1]); + csqcg.input_angles[2] = SHORT2ANGLE(cmd->angles[2]); + } + if (csqcg.input_movevalues) + { + csqcg.input_movevalues[0] = cmd->forwardmove; + csqcg.input_movevalues[1] = cmd->sidemove; + csqcg.input_movevalues[2] = cmd->upmove; + } + if (csqcg.input_buttons) + *csqcg.input_buttons = cmd->buttons; + + G_FLOAT(OFS_RETURN) = true; +} +#define ANGLE2SHORT(x) ((x/360.0)*65535) +//read lots of globals, run the default player physics, write lots of globals. +static void PF_cs_runplayerphysics (progfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + int msecs; + extern vec3_t player_mins; + extern vec3_t player_maxs; +/* + int sequence; // just for debugging prints + + // player state + vec3_t origin; + vec3_t angles; + vec3_t velocity; + qboolean jump_held; + int jump_msec; // msec since last jump + float waterjumptime; + int pm_type; + int hullnum; + + // world state + int numphysent; + physent_t physents[MAX_PHYSENTS]; // 0 should be the world + + // input + usercmd_t cmd; + + qboolean onladder; + + // results + int numtouch; + int touchindex[MAX_PHYSENTS]; + qboolean onground; + int groundent; // index in physents array, only valid + // when onground is true + int waterlevel; + int watertype; +} playermove_t; + +typedef struct { + float gravity; + float stopspeed; + float maxspeed; + float spectatormaxspeed; + float accelerate; + float airaccelerate; + float wateraccelerate; + float friction; + float waterfriction; + float entgravity; + float bunnyspeedcap; + float ktjump; + qboolean slidefix; + qboolean airstep; + qboolean walljump; + + + */ + + pmove.sequence = *csqcg.clientcommandframe; + pmove.pm_type = PM_NORMAL; + +//set up the movement command + msecs = *csqcg.input_timelength*1000 + 0.5f; + //precision inaccuracies. :( + pmove.angles[0] = ANGLE2SHORT(csqcg.input_angles[0]); + pmove.angles[1] = ANGLE2SHORT(csqcg.input_angles[1]); + pmove.angles[2] = ANGLE2SHORT(csqcg.input_angles[2]); + pmove.cmd.forwardmove = csqcg.input_movevalues[0]; + pmove.cmd.sidemove = csqcg.input_movevalues[1]; + pmove.cmd.upmove = csqcg.input_movevalues[2]; + + VectorCopy(csqcg.pmove_org, pmove.origin); + VectorCopy(csqcg.pmove_vel, pmove.velocity); + VectorCopy(csqcg.pmove_maxs, player_maxs); + VectorCopy(csqcg.pmove_mins, player_mins); + pmove.hullnum = 1; + + + while(msecs) + { + pmove.cmd.msec = msecs; + if (pmove.cmd.msec > 50) + pmove.cmd.msec = 50; + msecs -= pmove.cmd.msec; + PM_PlayerMove(1); + } + + + VectorCopy(pmove.origin, csqcg.pmove_org); + VectorCopy(pmove.velocity, csqcg.pmove_vel); +} + +static void CheckSendPings(void) +{ //quakeworld sends a 'pings' client command to retrieve the frequently updating stuff + if (realtime - cl.last_ping_request > 2) + { + cl.last_ping_request = realtime; + CL_SendClientCommand(false, "pings"); + } +} + +//string(float pnum, string keyname) +static void PF_cs_getplayerkey (progfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + char *ret; + int pnum = G_FLOAT(OFS_PARM0); + char *keyname = PR_GetStringOfs(prinst, OFS_PARM1); + if (pnum < 0) + { + Sbar_SortFrags(false); + if (pnum >= -scoreboardlines) + {//sort by + pnum = fragsort[-(pnum+1)]; + } + } + + if (pnum < 0 || pnum >= MAX_CLIENTS) + ret = ""; + else if (!*cl.players[pnum].userinfo) + ret = ""; + else if (!strcmp(keyname, "ping")) + { + CheckSendPings(); + + ret = PF_TempStr(); + sprintf(ret, "%i", cl.players[pnum].ping); + } + else if (!strcmp(keyname, "frags")) + { + ret = PF_TempStr(); + sprintf(ret, "%i", cl.players[pnum].frags); + } + else if (!strcmp(keyname, "pl")) //packet loss + { + CheckSendPings(); + + ret = PF_TempStr(); + sprintf(ret, "%i", cl.players[pnum].pl); + } + else if (!strcmp(keyname, "entertime")) //packet loss + { + ret = PF_TempStr(); + sprintf(ret, "%i", cl.players[pnum].entertime); + } + else + { + ret = Info_ValueForKey(cl.players[pnum].userinfo, keyname); + } + if (*ret) + G_INT(OFS_RETURN) = 0; + else + RETURN_SSTRING(ret); +} + +extern int mouseusedforgui, mousecursor_x, mousecursor_y; +static void PF_cs_setwantskeys (progfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + qboolean wants = G_FLOAT(OFS_PARM0); + csqcwantskeys = wants; + mouseusedforgui = wants; +} + +static void PF_cs_getmousepos (progfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + G_FLOAT(OFS_RETURN+0) = mousecursor_x; + G_FLOAT(OFS_RETURN+1) = mousecursor_y; + G_FLOAT(OFS_RETURN+2) = 0; +} + + #define PF_FixTen PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme,PF_Fixme //warning: functions that depend on globals are bad, mkay? -builtin_t csqc_builtins[] = { +static builtin_t csqc_builtins[] = { //0 PF_Fixme, PF_makevectors, @@ -1025,7 +1281,7 @@ PF_Fixme, PF_Fixme, PF_Fixme, PF_Fixme, -PF_Fixme, +PF_registercvar, PF_Fixme, PF_Fixme, @@ -1111,7 +1367,17 @@ PF_cs_pointparticles, PF_cs_particlesloaded, //160 -PF_FixTen, +PF_cs_getinputstate, +PF_cs_runplayerphysics, +PF_cs_getplayerkey, +PF_cs_setwantskeys, +PF_cs_getmousepos, + +PF_Fixme, +PF_Fixme, +PF_Fixme, +PF_Fixme, +PF_Fixme, //170 PF_FixTen, @@ -1217,15 +1483,15 @@ PF_Fixme, PF_Fixme, PF_Fixme, }; -int csqc_numbuiltins = sizeof(csqc_builtins)/sizeof(csqc_builtins[0]); +static int csqc_numbuiltins = sizeof(csqc_builtins)/sizeof(csqc_builtins[0]); -jmp_buf csqc_abort; -progparms_t csqcprogparms; -int num_csqc_edicts; +static jmp_buf csqc_abort; +static progparms_t csqcprogparms; +static int num_csqc_edicts; @@ -1391,6 +1657,11 @@ qboolean CSQC_DrawView(void) if (cl.worldmodel) R_LessenStains(); + if (csqcg.clientcommandframe) + *csqcg.clientcommandframe = cls.netchan.outgoing_sequence; + if (csqcg.servercommandframe) + *csqcg.servercommandframe = cls.netchan.incoming_sequence; + if (csqcg.time) *csqcg.time = Sys_DoubleTime(); @@ -1399,6 +1670,23 @@ qboolean CSQC_DrawView(void) return true; } +qboolean CSQC_KeyPress(int key, qboolean down) +{ + void *pr_globals; + + if (!csqcprogs || !csqcwantskeys) + return false; + + pr_globals = PR_globals(csqcprogs, PR_CURRENT); + G_FLOAT(OFS_PARM0) = key; + G_FLOAT(OFS_PARM1) = !down; + G_FLOAT(OFS_PARM2) = 0; + + PR_ExecuteProgram (csqcprogs, csqcg.input_event); + + return true; +} + qboolean CSQC_StuffCmd(char *cmd) { void *pr_globals; @@ -1445,13 +1733,15 @@ void CSQC_ParseEntities(void) if (!csqcprogs) Host_EndGame("CSQC needs to be initialized for this server.\n"); - if (!csqcg.ent_update) + if (!csqcg.ent_update || !csqcg.self) Host_EndGame("CSQC is unable to parse entities\n"); pr_globals = PR_globals(csqcprogs, PR_CURRENT); if (csqcg.time) *csqcg.time = Sys_DoubleTime(); + if (csqcg.servercommandframe) + *csqcg.servercommandframe = cls.netchan.incoming_sequence; for(;;) { @@ -1471,13 +1761,13 @@ void CSQC_ParseEntities(void) Con_Printf("Remove %i\n", entnum); ent = csqcent[entnum]; + csqcent[entnum] = NULL; if (!ent) //hrm. continue; *csqcg.self = EDICT_TO_PROG(csqcprogs, (void*)ent); PR_ExecuteProgram(csqcprogs, csqcg.ent_remove); - csqcent[entnum] = NULL; //the csqc is expected to call the remove builtin. } else @@ -1496,6 +1786,7 @@ void CSQC_ParseEntities(void) { ent = (csqcedict_t*)ED_Alloc(csqcprogs); csqcent[entnum] = ent; + ent->v->entnum = entnum; G_FLOAT(OFS_PARM0) = true; if (cl_csqcdebug.value) diff --git a/engine/client/r_part.c b/engine/client/r_part.c index 7224d24ac..cfe08aa18 100644 --- a/engine/client/r_part.c +++ b/engine/client/r_part.c @@ -214,6 +214,11 @@ typedef struct part_type_s { particle_t *particles; beamseg_t *beams; skytris_t *skytris; + + unsigned int flags; +#define PT_VELOCITY 1 +#define PT_FRICTION 2 +#define PT_CHANGESCOLOUR 4 } part_type_t; int numparticletypes; part_type_t *part_type; @@ -788,6 +793,14 @@ void P_ParticleEffect_f(void) if (ptype->clipcount < 1) ptype->clipcount = 1; + ptype->flags = 0; + //if there is a chance that it moves + if (ptype->randomvel || ptype->gravity || ptype->veladd || ptype->offsetspread || ptype->offsetspreadvert) + ptype->flags |= PT_VELOCITY; + //if it has friction + if (ptype->friction) + ptype->flags |= PT_FRICTION; + if (ptype->rampmode && !ptype->ramp) { ptype->rampmode = RAMP_NONE; @@ -803,7 +816,7 @@ void P_ParticleEffect_f(void) { if (strcmp(ptype->texname, "default")) { - ptype->texturenum = Mod_LoadHiResTexture(ptype->texname, true, true, true); + ptype->texturenum = Mod_LoadHiResTexture(ptype->texname, "particles", true, true, true); if (!ptype->texturenum) { @@ -1151,7 +1164,7 @@ void P_ClearParticles (void) { if (*part_type[i].texname) { - part_type[i].texturenum = Mod_LoadHiResTexture(part_type[i].texname, true, true, true); + part_type[i].texturenum = Mod_LoadHiResTexture(part_type[i].texname, "particles", true, true, true); if (!part_type[i].texturenum) part_type[i].texturenum = explosiontexture; } @@ -3133,9 +3146,8 @@ void DrawParticleTypes (void texturedparticles(particle_t *,part_type_t*), void kill_list = kill_first = NULL; - for (i = 0; i < numparticletypes; i++) + for (i = 0, type = &part_type[i]; i < numparticletypes; i++, type++) { - type = &part_type[i]; if (!type->particles) continue; @@ -3262,13 +3274,19 @@ void DrawParticleTypes (void texturedparticles(particle_t *,part_type_t*), void break; } VectorCopy(p->org, oldorg); - p->org[0] += p->vel[0]*pframetime; - p->org[1] += p->vel[1]*pframetime; - p->org[2] += p->vel[2]*pframetime; - p->vel[0] -= friction[0]*p->vel[0]; - p->vel[1] -= friction[1]*p->vel[1]; - p->vel[2] -= friction[2]*p->vel[2]; - p->vel[2] -= grav; + if (type->flags & PT_VELOCITY) + { + p->org[0] += p->vel[0]*pframetime; + p->org[1] += p->vel[1]*pframetime; + p->org[2] += p->vel[2]*pframetime; + if (type->flags & PT_FRICTION) + { + p->vel[0] -= friction[0]*p->vel[0]; + p->vel[1] -= friction[1]*p->vel[1]; + p->vel[2] -= friction[2]*p->vel[2]; + } + p->vel[2] -= grav; + } p->angle += p->rotationspeed*pframetime; diff --git a/engine/client/r_partset.c b/engine/client/r_partset.c index 04519c279..02d59363b 100644 --- a/engine/client/r_partset.c +++ b/engine/client/r_partset.c @@ -2,7 +2,79 @@ char *particle_set_spikeset = -#if 0 +#if 1 +///////////////////////////////////////////////// +//rocket trails (derived from purplehaze's, with only minor tweeks) + +"r_part rockettrail\n" +"{\n" +" texture \"particles/smoke.tga\"\n" +" count 0.25\n" +" scale 30\n" +" alpha 0.3\n" +" die 1.4\n" +" diesubrand 0.7\n" +" randomvel 1\n" +" veladd 0\n" +" red 255\n" +" green 50 \n" +" blue 10\n" +" reddelta -255\n" +" greendelta -25\n" +" bluedelta -5\n" +" gravity -25\n" +" scalefactor 1\n" +" assoc rocketsmoke\n" +"}\n" + +"r_part t_rocket\n" +"{\n" +" texture \"particles/rfire\"\n" +" count 0.5\n" +" scale 10\n" +" alpha 0.6\n" +" die 0.25\n" +" randomvel 0\n" +" veladd 0\n" +" red 255\n" +" green 192\n" +" blue 128\n" +" reddelta -14\n" +" greendelta -300\n" +" bluedelta -300\n" +" blend add\n" +" assoc rockettrail\n" +" gravity 0\n" +" scalefactor 0.8\n" +" scaledelta -10\n" +"}\n" + +"r_part rocketsmoke\n" +"{\n" +" texture \"particles/rtrail\"\n" +" step 8\n" +" scale 7.5\n" +" alpha 0.8\n" +" die 2\n" +" diesubrand 0\n" +" randomvel 3\n" +" veladd 0\n" +" red 10\n" +" green 10\n" +" blue 10\n" +" reddelta 0\n" +" greendelta 0\n" +" reddelta 0\n" +" gravity 1\n" +" blend modulate\n" +" spawnmode spiral\n" +" scalefactor 1\n" +" offsetspread 10\n" +" offsetspreadvert 10\n" +" areaspread 0\n" +" areaspreadvert 0\n" +"}\n" +#elif 0 "r_part rockettail\n" "{\n" " texture \"particles/rtrail\"\n" @@ -186,6 +258,110 @@ char *particle_set_spikeset = "friction 1\n" " stains 1\n" "}\n" + +#if 1 +///////////////////////////////////////////////// +//rocket explosions + +"r_part randomspark\n" +"{\n" +" count 1\n" +" texture \"\"\n" +" red 255\n" +" green 128\n" +" blue 76\n" +" gravity 400\n" +" spawnmode ball\n" +" die 2\n" +" blend add\n" +" randomvel 128\n" +" veladd 0\n" +" cliptype randomspark\n" +"}\n" + +"r_part insaneshrapnal\n" +"{\n" +" count 24\n" +" texture \"\"\n" +" red 255\n" +" green 128\n" +" blue 76\n" +" gravity 400\n" +" die 2\n" +" blend add\n" +" randomvel 512\n" +" veladd 1\n" +" cliptype randomspark\n" +" clipcount 5\n" +"}\n" + +"r_part ember\n" +"{\n" +" count 1\n" +" texture \"particles/explosion\"\n" +" red 255\n" +" green 128\n" +" blue 76\n" +" alpha 0\n" +" scale 15\n" +" scalefactor 1\n" +" friction 8\n" +" gravity 50\n" +" die 1\n" +" blend add\n" +" randomvel 5\n" +" veladd 1\n" +" rampmode delta\n" //fade it in then out. +" ramp 0 0 0 -0.5 0\n" +" ramp 0 0 0 0.1 0\n" +" ramp 0 0 0 0.1 0\n" +" ramp 0 0 0 0.1 0\n" +" ramp 0 0 0 0.1 0\n" +" ramp 0 0 0 0.1 0\n" +"}\n" + +//the bits that fly off +"r_part expgib\n" +"{\n" +" cliptype expgib\n" +" texture \"particles/explosion\"\n" +" count 16\n" +" scale 0\n" +" die 1\n" +" randomvel 128\n" +" veladd 64\n" +" veladd 0\n" +" gravity 50\n" +" friction 2\n" +" emit ember\n" +" emitinterval 0.01\n" +" spawnmode circle\n" +" assoc insaneshrapnal\n" +"}\n" + +//the heart of the explosion +"r_part te_explosion\n" +"{\n" +" texture \"particles/explosion\"\n" +" count 1\n" +" scale 200\n" +" scalefactor 1\n" +" alpha 1\n" +" die 1\n" +" veladd 0\n" +" red 255\n" +" green 128\n" +" blue 76\n" +" reddelta 0\n" +" greendelta -32\n" +" reddelta -32\n" +" gravity 0\n" +" friction 1\n" +" stains 0\n" +" blend add\n" +" assoc expgib\n" +"}\n" +#else "r_part sparks\n" "{\n" " texture \"\"\n" @@ -313,7 +489,8 @@ char *particle_set_spikeset = " assoc shrapnal\n" " scalefactor 1\n" "}\n" -"\n" + +#endif "r_part empcentral\n" "{\n" diff --git a/engine/client/view.c b/engine/client/view.c index d708619f7..ebaba0138 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -1176,7 +1176,7 @@ void V_CalcRefdef (int pnum) view->model = NULL; else #endif - if (view_message && view_message->flags & (PF_GIB|PF_DEAD) ) + if (!view_message || view_message->flags & (PF_GIB|PF_DEAD) ) view->model = NULL; else view->model = cl.model_precache[cl.stats[pnum][STAT_WEAPON]]; diff --git a/engine/client/zqtp.c b/engine/client/zqtp.c index eabe8aebe..042b2a3b0 100644 --- a/engine/client/zqtp.c +++ b/engine/client/zqtp.c @@ -48,6 +48,17 @@ typedef qboolean qbool; #define Q_stricmp stricmp #define Q_strnicmp strnicmp + +extern int cl_spikeindex, cl_playerindex, cl_h_playerindex, cl_flagindex, cl_rocketindex, cl_grenadeindex, cl_gib1index, cl_gib2index, cl_gib3index; +extern cvar_t v_viewheight; +trace_t PM_TraceLine (vec3_t start, vec3_t end); +#define ISDEAD(i) ( (i) >= 41 && (i) <= 102 ) + +qboolean suppress; + +//note: csqc obsoletes and even breaks much of this stuff. +//cl.simorg is no longer valid, cl.viewangles isn't terribly valid either. + /*#define isalpha(x) (((x) >= 'a' && (x) <= 'z') || ((x) >= 'A' && (x) <= 'Z')) #define isdigit(x) ((x) >= '0' && (x) <= '9') #define isxdigit(x) (isdigit(x) || ((x) >= 'a' && (x) <= 'f')) @@ -146,18 +157,38 @@ static void VARGS Q_snprintfz (char *dest, size_t size, char *fmt, ...) TP_CVAR(tp_need_cells, "20"); \ TP_CVAR(tp_need_nails, "40"); \ TP_CVAR(tp_need_shells, "10"); \ - TP_CVAR(tp_name_disp, "dispenser"); \ - TP_CVAR(tp_name_sentry, "sentry gun"); \ - TP_CVAR(tp_name_rune_1, "resistance rune"); \ - TP_CVAR(tp_name_rune_2, "strength rune"); \ - TP_CVAR(tp_name_rune_3, "haste rune"); \ - TP_CVAR(tp_name_rune_4, "regeneration rune") + TP_CVAR(tp_name_disp, "dispenser"); \ + TP_CVAR(tp_name_sentry, "sentry gun"); \ + TP_CVAR(tp_name_rune_1, "resistance rune"); \ + TP_CVAR(tp_name_rune_2, "strength rune"); \ + TP_CVAR(tp_name_rune_3, "haste rune"); \ + TP_CVAR(tp_name_rune_4, "regeneration rune"); \ + \ + TP_CVAR(tp_name_status_red, "$R"); \ + TP_CVAR(tp_name_status_green, "$G"); \ + TP_CVAR(tp_name_status_yellow, "$Y"); \ + TP_CVAR(tp_name_status_blue, "$B"); \ + \ + TP_CVAR(tp_name_armortype_ga, "g"); \ + TP_CVAR(tp_name_armortype_ya, "y"); \ + TP_CVAR(tp_name_armortype_ra, "r"); \ + TP_CVAR(tp_name_armor, "armor"); \ + TP_CVAR(tp_name_weapon, "weapon"); \ + TP_CVAR(tp_weapon_order, "78654321"); \ + \ + TP_CVAR(tp_name_quaded, "quaded"); \ + TP_CVAR(tp_name_pented, "pented"); \ + TP_CVAR(tp_name_separator, "/"); \ + \ + TP_CVAR(tp_name_enemy, "enemy"); \ + TP_CVAR(tp_name_teammate, ""); \ + TP_CVAR(tp_name_eyes, "eyes") //create the globals for all the TP cvars. #define TP_CVAR(name,def) cvar_t name = {#name, def} TP_CVARS; #undef TP_CVAR - + extern cvar_t host_mapname; @@ -188,10 +219,50 @@ typedef struct tvars_s { vec3_t pointorg; char pointloc[MAX_LOC_NAME]; int droppedweapon; + char lastdroploc[MAX_LOC_NAME]; + + int last_numenemies; + int numenemies; + + int last_numfriendlies; + int numfriendlies; + + int enemy_powerups; + float enemy_powerups_time; + + float lastdrop_time; + + enum { + POINT_TYPE_ENEMY, + POINT_TYPE_TEAMMATE, + POINT_TYPE_POWERUP, + POINT_TYPE_ITEM + } pointtype; + float pointtime; } tvars_t; tvars_t vars; + +typedef struct item_vis_s { + vec3_t vieworg; + vec3_t forward; + vec3_t right; + vec3_t up; + vec3_t entorg; + float radius; + vec3_t dir; + float dist; +} item_vis_t; + + +#define TP_TOOK_EXPIRE_TIME 15 +#define TP_POINT_EXPIRE_TIME TP_TOOK_EXPIRE_TIME + + + + + //=========================================================================== // TRIGGERS //=========================================================================== @@ -380,24 +451,26 @@ static char *Macro_WeaponNum (void) static int _Macro_BestWeapon (void) { - if (cl.stats[SP][STAT_ITEMS] & IT_ROCKET_LAUNCHER) - return IT_ROCKET_LAUNCHER; - else if (cl.stats[SP][STAT_ITEMS] & IT_LIGHTNING) - return IT_LIGHTNING; - else if (cl.stats[SP][STAT_ITEMS] & IT_GRENADE_LAUNCHER) - return IT_GRENADE_LAUNCHER; - else if (cl.stats[SP][STAT_ITEMS] & IT_SUPER_NAILGUN) - return IT_SUPER_NAILGUN; - else if (cl.stats[SP][STAT_ITEMS] & IT_NAILGUN) - return IT_NAILGUN; - else if (cl.stats[SP][STAT_ITEMS] & IT_SUPER_SHOTGUN) - return IT_SUPER_SHOTGUN; - else if (cl.stats[SP][STAT_ITEMS] & IT_SHOTGUN) - return IT_SHOTGUN; - else if (cl.stats[SP][STAT_ITEMS] & IT_AXE) - return IT_AXE; - else - return 0; + int i; + char *t[] = {tp_weapon_order.string, "78654321", NULL}, **s; + + for (s = t; *s; s++) + { + for (i = 0 ; i < strlen(*s) ; i++) + { + switch ((*s)[i]) { + case '1': if (cl.stats[SP][STAT_ITEMS] & IT_AXE) return IT_AXE; break; + case '2': if (cl.stats[SP][STAT_ITEMS] & IT_SHOTGUN) return IT_SHOTGUN; break; + case '3': if (cl.stats[SP][STAT_ITEMS] & IT_SUPER_SHOTGUN) return IT_SUPER_SHOTGUN; break; + case '4': if (cl.stats[SP][STAT_ITEMS] & IT_NAILGUN) return IT_NAILGUN; break; + case '5': if (cl.stats[SP][STAT_ITEMS] & IT_SUPER_NAILGUN) return IT_SUPER_NAILGUN; break; + case '6': if (cl.stats[SP][STAT_ITEMS] & IT_GRENADE_LAUNCHER) return IT_GRENADE_LAUNCHER; break; + case '7': if (cl.stats[SP][STAT_ITEMS] & IT_ROCKET_LAUNCHER) return IT_ROCKET_LAUNCHER; break; + case '8': if (cl.stats[SP][STAT_ITEMS] & IT_LIGHTNING) return IT_LIGHTNING; break; + } + } + } + return 0; } static char *Macro_BestWeapon (void) @@ -442,13 +515,13 @@ static char *Macro_BestWeaponAndAmmo (void) static char *Macro_ArmorType (void) { if (cl.stats[SP][STAT_ITEMS] & IT_ARMOR1) - return "g"; + return tp_name_armortype_ga.string; else if (cl.stats[SP][STAT_ITEMS] & IT_ARMOR2) - return "y"; + return tp_name_armortype_ya.string; else if (cl.stats[SP][STAT_ITEMS] & IT_ARMOR3) - return "r"; + return tp_name_armortype_ra.string; else - return ""; // no armor at all + return tp_name_none.string; // no armor at all } static char *Macro_Powerups (void) @@ -506,7 +579,7 @@ static char *Macro_Mapname (void) } -static char *Macro_Location2 (void) +static char *Macro_Last_Location (void) { if (vars.deathtrigger_time && realtime - vars.deathtrigger_time <= 5) return vars.lastdeathloc; @@ -617,11 +690,11 @@ static char *Macro_Need (void) || ((cl.stats[SP][STAT_ITEMS] & IT_ARMOR3) && cl.stats[SP][STAT_ARMOR] < tp_need_ra.value) || (!(cl.stats[SP][STAT_ITEMS] & (IT_ARMOR1|IT_ARMOR2|IT_ARMOR3)) && (tp_need_ga.value || tp_need_ya.value || tp_need_ra.value))) - strcpy (macro_buf, "armor"); + strcpy (macro_buf, tp_name_armor.string); // check health if (tp_need_health.value && cl.stats[SP][STAT_HEALTH] < tp_need_health.value) { - MacroBuf_strcat_with_separator ("health"); + MacroBuf_strcat_with_separator (tp_name_health.string); } if (cl.teamfortress) @@ -629,13 +702,13 @@ static char *Macro_Need (void) // in TF, we have all weapons from the start, // and ammo is checked differently if (cl.stats[SP][STAT_ROCKETS] < tp_need_rockets.value) - MacroBuf_strcat_with_separator ("rockets"); + MacroBuf_strcat_with_separator (tp_name_rockets.string); if (cl.stats[SP][STAT_SHELLS] < tp_need_shells.value) - MacroBuf_strcat_with_separator ("shells"); + MacroBuf_strcat_with_separator (tp_name_shells.string); if (cl.stats[SP][STAT_NAILS] < tp_need_nails.value) - MacroBuf_strcat_with_separator ("nails"); + MacroBuf_strcat_with_separator (tp_name_nails.string); if (cl.stats[SP][STAT_CELLS] < tp_need_cells.value) - MacroBuf_strcat_with_separator ("cells"); + MacroBuf_strcat_with_separator (tp_name_cells.string); goto done; } @@ -656,17 +729,17 @@ static char *Macro_Need (void) } if (!weapon) { - MacroBuf_strcat_with_separator ("weapon"); + MacroBuf_strcat_with_separator (tp_name_weapon.string); } else { if (tp_need_rl.value && !(cl.stats[SP][STAT_ITEMS] & IT_ROCKET_LAUNCHER)) { - MacroBuf_strcat_with_separator ("rl"); + MacroBuf_strcat_with_separator (tp_name_rl.string); } switch (weapon) { - case 2: case 3: if (cl.stats[SP][STAT_SHELLS] < tp_need_shells.value) needammo = "shells"; break; - case 4: case 5: if (cl.stats[SP][STAT_NAILS] < tp_need_nails.value) needammo = "nails"; break; - case 6: case 7: if (cl.stats[SP][STAT_ROCKETS] < tp_need_rockets.value) needammo = "rockets"; break; - case 8: if (cl.stats[SP][STAT_CELLS] < tp_need_cells.value) needammo = "cells"; break; + case 2: case 3: if (cl.stats[SP][STAT_SHELLS] < tp_need_shells.value) needammo = tp_name_shells.string; break; + case 4: case 5: if (cl.stats[SP][STAT_NAILS] < tp_need_nails.value) needammo = tp_name_nails.string; break; + case 6: case 7: if (cl.stats[SP][STAT_ROCKETS] < tp_need_rockets.value) needammo = tp_name_rockets.string; break; + case 8: if (cl.stats[SP][STAT_CELLS] < tp_need_cells.value) needammo = tp_name_cells.string; break; } if (needammo) { MacroBuf_strcat_with_separator (needammo); @@ -680,40 +753,32 @@ done: return macro_buf; } -static char *Macro_TF_Skin (void) +static char *Skin_To_TFSkin (char *myskin) { - char *myskin; - - myskin = Info_ValueForKey(cl.players[cl.playernum[SP]].userinfo, "skin"); - if (!cl.teamfortress) - strcpy(macro_buf, myskin); + if (!cl.teamfortress || cl.spectator || Q_strncasecmp(myskin, "tf_", 3)) + { + Q_strncpyz(macro_buf, myskin, sizeof(macro_buf)); + } else { - if (!Q_stricmp(myskin, "tf_demo")) - strcpy(macro_buf, "demoman"); - else if (!Q_stricmp(myskin, "tf_eng")) - strcpy (macro_buf, "engineer"); - else if (!Q_stricmp(myskin, "tf_hwguy")) - strcpy(macro_buf, "hwguy"); - else if (!Q_stricmp(myskin, "tf_medic")) - strcpy(macro_buf, "medic"); - else if (!Q_stricmp(myskin, "tf_pyro")) - strcpy(macro_buf, "pyro"); - else if (!Q_stricmp(myskin, "tf_scout")) - strcpy(macro_buf, "scout"); - else if (!Q_stricmp(myskin, "tf_snipe")) - strcpy(macro_buf, "sniper"); - else if (!Q_stricmp(myskin, "tf_sold")) - strcpy(macro_buf, "soldier"); - else if (!Q_stricmp(myskin, "tf_spy")) - strcpy(macro_buf, "spy"); + if (!Q_strcasecmp(myskin, "tf_demo")) + Q_strncpyz(macro_buf, "demoman", sizeof(macro_buf)); + else if (!Q_strcasecmp(myskin, "tf_eng")) + Q_strncpyz(macro_buf, "engineer", sizeof(macro_buf)); + else if (!Q_strcasecmp(myskin, "tf_snipe")) + Q_strncpyz(macro_buf, "sniper", sizeof(macro_buf)); + else if (!Q_strcasecmp(myskin, "tf_sold")) + Q_strncpyz(macro_buf, "soldier", sizeof(macro_buf)); else - strcpy(macro_buf, myskin); + Q_strncpyz(macro_buf, myskin + 3, sizeof(macro_buf)); } return macro_buf; } - +static char *Macro_TF_Skin (void) +{ + return Skin_To_TFSkin(Info_ValueForKey(cl.players[cl.playernum[0]].userinfo, "skin")); +} //Spike: added these: static char *Macro_ConnectionType (void) @@ -812,29 +877,219 @@ static char *Macro_Version (void) return va("%.2f "DISTRIBUTION" ["__DATE__"] (%i)", VERSION, build_number()); } + +static char *Macro_Point_LED(void) +{ + TP_FindPoint(); + + if (vars.pointtype == POINT_TYPE_ENEMY) + return tp_name_status_red.string; + else if (vars.pointtype == POINT_TYPE_TEAMMATE) + return tp_name_status_green.string; + else if (vars.pointtype == POINT_TYPE_POWERUP) + return tp_name_status_yellow.string; + else // POINT_TYPE_ITEM + return tp_name_status_blue.string; + + return macro_buf; +} + +static char *Macro_MyStatus_LED(void) +{ + int count; + float save_need_rl; + char *s, *save_separator; + static char separator[] = {'/', '\0'}; + + save_need_rl = tp_need_rl.value; + save_separator = tp_name_separator.string; + tp_need_rl.value = 0; + tp_name_separator.string = separator; + s = Macro_Need(); + tp_need_rl.value = save_need_rl; + tp_name_separator.string = save_separator; + + if (!strcmp(s, tp_name_nothing.string)) { + count = 0; + } else { + for (count = 1; *s; s++) + if (*s == separator[0]) + count++; + } + + if (count == 0) + Q_snprintfz(macro_buf, sizeof(macro_buf), "%s", tp_name_status_green.string); + else if (count <= 1) + Q_snprintfz(macro_buf, sizeof(macro_buf), "%s", tp_name_status_yellow.string); + else + Q_snprintfz(macro_buf, sizeof(macro_buf), "%s", tp_name_status_red.string); + + return macro_buf; +} + +static void CountNearbyPlayers(qboolean dead) +{ + int i; + player_state_t *state; + player_info_t *info; + static int lastframecount = -1; + + if (cls.framecount == lastframecount) + return; + lastframecount = cls.framecount; + + vars.numenemies = vars.numfriendlies = 0; + + if (!cl.spectator && !dead) + vars.numfriendlies++; + + if (!cl.oldparsecount || !cl.parsecount || cls.state < ca_active) + return; + + state = cl.frames[cl.oldparsecount & UPDATE_MASK].playerstate; + info = cl.players; + for (i = 0; i < MAX_CLIENTS; i++, info++, state++) { + if (i != cl.playernum[0] && state->messagenum == cl.oldparsecount && !info->spectator && !ISDEAD(state->frame)) { + if (cl.teamplay && !strcmp(info->team, TP_PlayerTeam())) + vars.numfriendlies++; + else + vars.numenemies++; + } + } +} + +static char *Macro_CountNearbyEnemyPlayers (void) +{ + CountNearbyPlayers(false); + sprintf(macro_buf, "\xffz%d\xff", vars.numenemies); + suppress = true; + return macro_buf; +} + + +static char *Macro_Count_Last_NearbyEnemyPlayers (void) +{ + if (vars.deathtrigger_time && realtime - vars.deathtrigger_time <= 5) + { + sprintf(macro_buf, "\xffz%d\xff", vars.last_numenemies); + } + else + { + CountNearbyPlayers(false); + sprintf(macro_buf, "\xffz%d\xff", vars.numenemies); + } + suppress = true; + return macro_buf; +} + + +static char *Macro_CountNearbyFriendlyPlayers (void) +{ + CountNearbyPlayers(false); + sprintf(macro_buf, "\xffz%d\xff", vars.numfriendlies); + suppress = true; + return macro_buf; +} + + +static char *Macro_Count_Last_NearbyFriendlyPlayers (void) +{ + if (vars.deathtrigger_time && realtime - vars.deathtrigger_time <= 5) + { + sprintf(macro_buf, "\xffz%d\xff", vars.last_numfriendlies); + } + else + { + CountNearbyPlayers(false); + sprintf(macro_buf, "\xffz%d\xff", vars.numfriendlies); + } + suppress = true; + return macro_buf; +} + +static char *Macro_EnemyStatus_LED(void) +{ + CountNearbyPlayers(false); + if (vars.numenemies == 0) + Q_snprintfz(macro_buf, sizeof(macro_buf), "\xffl%s\xff", tp_name_status_green.string); + else if (vars.numenemies <= vars.numfriendlies) + Q_snprintfz(macro_buf, sizeof(macro_buf), "\xffl%s\xff", tp_name_status_yellow.string); + else + Q_snprintfz(macro_buf, sizeof(macro_buf), "\xffl%s\xff", tp_name_status_red.string); + + suppress = true; + return macro_buf; +} + +static char *Macro_LastPointAtLoc (void) +{ + if (!vars.pointtime || realtime - vars.pointtime > TP_POINT_EXPIRE_TIME) + Q_strncpyz (macro_buf, tp_name_nothing.string, sizeof(macro_buf)); + else + Q_snprintfz (macro_buf, sizeof(macro_buf), "%s %s %s", vars.pointname, tp_name_at.string, vars.pointloc[0] ? vars.pointloc : Macro_Location()); + return macro_buf; +} + +static char *Macro_LastTookOrPointed (void) +{ + if (vars.tooktime && vars.tooktime > vars.pointtime && realtime - vars.tooktime < 5) + return Macro_TookAtLoc(); + else if (vars.pointtime && vars.tooktime <= vars.pointtime && realtime - vars.pointtime < 5) + return Macro_LastPointAtLoc(); + + Q_snprintfz(macro_buf, sizeof(macro_buf), "%s %s %s", tp_name_nothing.string, tp_name_at.string, tp_name_someplace.string); + return macro_buf; +} + +#define TP_PENT 1 +#define TP_QUAD 2 +#define TP_RING 4 + +static char *Macro_LastSeenPowerup(void) +{ +/* if (!vars.enemy_powerups_time || realtime - vars.enemy_powerups_time > 5) + { + Q_strncpyz(macro_buf, tp_name_quad.string, sizeof(macro_buf)); + } + else*/ + { + macro_buf[0] = 0; + if (vars.enemy_powerups & TP_QUAD) + Q_strncatz(macro_buf, tp_name_quad.string); + if (vars.enemy_powerups & TP_PENT) + { + if (macro_buf[0]) + Q_strncatz(macro_buf, tp_name_separator.string); + Q_strncatz(macro_buf, tp_name_pent.string); + } + if (vars.enemy_powerups & TP_RING) + { + if (macro_buf[0]) + Q_strncatz(macro_buf, tp_name_separator.string); + Q_strncatz(macro_buf, tp_name_ring.string); + } + } + return macro_buf; +} + +char *Macro_LastDrop (void) +{ + if (vars.lastdrop_time) + return vars.lastdroploc; + else + return tp_name_someplace.string; +} + +char *Macro_LastDropTime (void) +{ + if (vars.lastdrop_time) + Q_snprintfz (macro_buf, 32, "%d", (int) (realtime - vars.lastdrop_time)); + else + Q_snprintfz (macro_buf, 32, "%d", -1); + return macro_buf; +} + /* -$droploc -Tells location of the dropped flag. -Note: This will tell only if you have dropped the flag (CTF/TF). - -$droptime -Tells how many seconds gone of dropped flag. - -$ledpoint -This reports the type of the pointed object as a LED according to the -following rules: -If teammate then green. -If enemy then red. -If powerup then yellow. -if item then blue. - -$ledstatus -This checks your current status (health, armor and best weapon) and -reports a LED according to the following rules: -if all of the above is ok then green. -if there is one thing low then yellow. -if there are two or over things low then red. - $matchname you can use to get the name of the match manually (echo $matchname). @@ -900,10 +1155,11 @@ static void TP_InitMacros(void) Cmd_AddMacro("matchtype", Macro_Match_Type, false); Cmd_AddMacro("mapname", Macro_Mapname, false); -// Cmd_AddMacro("droploc", Macro_LastDrop, true); -// Cmd_AddMacro("droptime", Macro_LastDropTime, true); -// Cmd_AddMacro("ledpoint", Macro_Point_LED, true); -// Cmd_AddMacro("ledstatus", Macro_MyStatus_LED, true); + Cmd_AddMacro("ledpoint", Macro_Point_LED, true); + Cmd_AddMacro("ledstatus", Macro_MyStatus_LED, true); + + Cmd_AddMacro("droploc", Macro_LastDrop, true); + Cmd_AddMacro("droptime", Macro_LastDropTime, true); // Cmd_AddMacro("matchstatus", Macro_Match_Status, false); // Cmd_AddMacro("mp3info", , false); // Cmd_AddMacro("triggermatch", Macro_LastTrigger_Match, false); @@ -982,24 +1238,37 @@ static char *TP_ParseMacroString (char *s) { switch (s[1]) { - case 'a': macro_string = Macro_Armor(); break; - case 'A': macro_string = Macro_ArmorType(); break; - case 'b': macro_string = Macro_BestWeaponAndAmmo(); break; - case 'c': macro_string = Macro_Cells(); break; - case 'd': macro_string = Macro_LastDeath(); break; - case 'h': macro_string = Macro_Health(); break; - case 'i': macro_string = Macro_TookAtLoc(); break; - case 'l': macro_string = Macro_Location(); break; - case 'L': macro_string = Macro_Location2(); break; - case 'P': - case 'p': macro_string = Macro_Powerups(); break; - case 'r': macro_string = Macro_Rockets(); break; - case 'u': macro_string = Macro_Need(); break; - case 'w': macro_string = Macro_WeaponAndAmmo(); break; - case 'x': macro_string = Macro_PointName(); break; - case 'y': macro_string = Macro_PointLocation(); break; - case 't': macro_string = Macro_PointNameAtLocation(); break; - case 'S': macro_string = Macro_TF_Skin(); break; + case 'a': macro_string = Macro_Armor(); break; + case 'A': macro_string = Macro_ArmorType(); break; + case 'b': macro_string = Macro_BestWeaponAndAmmo(); break; + case 'c': macro_string = Macro_Cells(); break; + case 'd': macro_string = Macro_LastDeath(); break; + case 'h': macro_string = Macro_Health(); break; + case 'i': macro_string = Macro_TookAtLoc(); break; + case 'j': macro_string = Macro_LastPointAtLoc(); break; + case 'k': macro_string = Macro_LastTookOrPointed(); break; + case 'l': macro_string = Macro_Location(); break; + case 'L': macro_string = Macro_Last_Location(); break; + case 'm': macro_string = Macro_LastTookOrPointed(); break; + + case 'o': macro_string = Macro_CountNearbyFriendlyPlayers(); break; + case 'e': macro_string = Macro_CountNearbyEnemyPlayers(); break; + case 'O': macro_string = Macro_Count_Last_NearbyFriendlyPlayers(); break; + case 'E': macro_string = Macro_Count_Last_NearbyEnemyPlayers(); break; + + case 'P': + case 'p': macro_string = Macro_Powerups(); break; + case 'q': macro_string = Macro_LastSeenPowerup(); break; +// case 'r': macro_string = Macro_LastReportedLoc(); break; + case 's': macro_string = Macro_EnemyStatus_LED(); break; + case 'S': macro_string = Macro_TF_Skin(); break; + case 't': macro_string = Macro_PointNameAtLocation(); break; + case 'u': macro_string = Macro_Need(); break; + case 'w': macro_string = Macro_WeaponAndAmmo(); break; + case 'x': macro_string = Macro_PointName(); break; + case 'X': macro_string = Macro_Took(); break; + case 'y': macro_string = Macro_PointLocation(); break; + case 'Y': macro_string = Macro_TookLoc(); break; default: buf[i++] = *s++; continue; @@ -1221,7 +1490,7 @@ static char *TP_LocationName (vec3_t location) float dist, mindist; vec3_t vec; static qbool recursive; - static char buf[1024]; + static char buf[MAX_LOC_NAME]; if (!loc_numentries || (cls.state != ca_active)) return tp_name_someplace.string; @@ -1690,85 +1959,86 @@ int TP_CategorizeMessage (char *s, int *offset) // // symbolic names used in tp_took, tp_pickup, tp_point commands -static char *pknames[] = {"quad", "pent", "ring", "suit", "ra", "ya", "ga", +char *pknames[] = {"quad", "pent", "ring", "suit", "ra", "ya", "ga", "mh", "health", "lg", "rl", "gl", "sng", "ng", "ssg", "pack", -"cells", "rockets", "nails", "shells", "flag", "pointed", -"sentry", "disp", "runes"}; +"cells", "rockets", "nails", "shells", "flag", +"teammate", "enemy", "eyes", "sentry", "disp", "runes"}; -#define it_quad (1<<0) -#define it_pent (1<<1) -#define it_ring (1<<2) -#define it_suit (1<<3) -#define it_ra (1<<4) -#define it_ya (1<<5) -#define it_ga (1<<6) -#define it_mh (1<<7) -#define it_health (1<<8) -#define it_lg (1<<9) -#define it_rl (1<<10) -#define it_gl (1<<11) -#define it_sng (1<<12) -#define it_ng (1<<13) -#define it_ssg (1<<14) -#define it_pack (1<<15) -#define it_cells (1<<16) -#define it_rockets (1<<17) -#define it_nails (1<<18) -#define it_shells (1<<19) -#define it_flag (1<<20) -#define it_pointed (1<<21) // only valid for tp_took -#define it_sentry (1 << 22) -#define it_disp (1 << 23) -#define it_runes (1 << 24) -#define NUM_ITEMFLAGS 25 +#define it_quad (1 << 0) +#define it_pent (1 << 1) +#define it_ring (1 << 2) +#define it_suit (1 << 3) +#define it_ra (1 << 4) +#define it_ya (1 << 5) +#define it_ga (1 << 6) +#define it_mh (1 << 7) +#define it_health (1 << 8) +#define it_lg (1 << 9) +#define it_rl (1 << 10) +#define it_gl (1 << 11) +#define it_sng (1 << 12) +#define it_ng (1 << 13) +#define it_ssg (1 << 14) +#define it_pack (1 << 15) +#define it_cells (1 << 16) +#define it_rockets (1 << 17) +#define it_nails (1 << 18) +#define it_shells (1 << 19) +#define it_flag (1 << 20) +#define it_teammate (1 << 21) +#define it_enemy (1 << 22) +#define it_eyes (1 << 23) +#define it_sentry (1 << 24) +#define it_disp (1 << 25) +#define it_runes (1 << 26) +#define NUM_ITEMFLAGS 27 #define it_powerups (it_quad|it_pent|it_ring) #define it_weapons (it_lg|it_rl|it_gl|it_sng|it_ng|it_ssg) #define it_armor (it_ra|it_ya|it_ga) #define it_ammo (it_cells|it_rockets|it_nails|it_shells) +#define it_players (it_teammate|it_enemy|it_eyes) #define default_pkflags (it_powerups|it_suit|it_armor|it_weapons|it_mh| \ it_rockets|it_pack|it_flag) -#define default_tookflags (it_powerups|it_ra|it_ya|it_lg|it_rl|it_mh|it_flag|it_pointed) +#define default_tookflags (it_powerups|it_ra|it_ya|it_lg|it_rl|it_mh|it_flag) #define default_pointflags (it_powerups|it_suit|it_armor|it_mh| \ - it_lg|it_rl|it_gl|it_sng|it_rockets|it_pack|it_flag) + it_lg|it_rl|it_gl|it_sng|it_rockets|it_pack|it_flag|it_players) -static int pkflags = default_pkflags; -static int tookflags = default_tookflags; -static int pointflags = default_pointflags; +int pkflags = default_pkflags; +int tookflags = default_tookflags; +int pointflags = default_pointflags; +static void FlagCommand (int *flags, int defaultflags) { + int i, j, c, flag; + char *p, str[255] = {0}; + qboolean removeflag = false; -static void FlagCommand (int *flags, int defaultflags) -{ - int i, j, c; - char *p; - char str[255] = ""; - qbool removeflag = false; - int flag; - c = Cmd_Argc (); - if (c == 1) - { + if (c == 1) { if (!*flags) - strcpy (str, "nothing"); - for (i=0 ; iname[0] && !player->spectator && i != cl.playernum[0] && !strcmp(player->team, myteam)) + count++; + } + + return count; +} + static void ExecTookTrigger (char *s, int flag, vec3_t org) { - qbool report; + int pkflags_dmm, tookflags_dmm; - // decide whether this pickup should be reported - if ( !((pkflags|tookflags) & flag) ) - return; + pkflags_dmm = pkflags; + tookflags_dmm = tookflags; + + if (!cl.teamfortress && cl.deathmatch >= 1 && cl.deathmatch <= 4) { + if (cl.deathmatch == 4) { + pkflags_dmm &= ~(it_ammo|it_weapons); + tookflags_dmm &= ~(it_ammo|it_weapons); + } + } + if (!((pkflags_dmm|tookflags_dmm) & flag)) + return; vars.tooktime = realtime; strncpy (vars.tookname, s, sizeof(vars.tookname)-1); strncpy (vars.tookloc, TP_LocationName (org), sizeof(vars.tookloc)-1); - if (flag & it_weapons) { - if (cl.deathmatch == 2 || cl.deathmatch == 3) - return; - } - - report = (tookflags & flag) ? true : false; - - if (!report) { - if ((tookflags & it_pointed) && !strcmp(vars.pointname, s)) { - vec3_t dist; - VectorSubtract (org, vars.pointorg, dist); - //Com_DPrintf ("dist: %f\n", VectorLength(dist)); - if (VectorLength(dist) < 80) { // tune this! - // ok, this looks like the item we have pointed at - report = true; - } - } - } - - if (report && CountTeammates()) { + if ((tookflags_dmm & flag) && CheckTrigger()) TP_ExecTrigger ("f_took"); - } } +void TP_ParsePlayerInfo(player_state_t *oldstate, player_state_t *state, player_info_t *info) +{ +// if (TP_NeedRefreshSkins()) +// { +// if ((state->effects & (EF_BLUE|EF_RED) ) != (oldstate->effects & (EF_BLUE|EF_RED))) +// TP_RefreshSkin(info - cl.players); +// } + + if (!cl.spectator && cl.teamplay && strcmp(info->team, TP_PlayerTeam())) + { + qboolean eyes; + + eyes = state->modelindex && cl.model_precache[state->modelindex] && !strcmp(cl.model_precache[state->modelindex]->name, "progs/eyes.mdl"); + + if (state->effects & (EF_BLUE | EF_RED) || eyes) + { + vars.enemy_powerups = 0; + vars.enemy_powerups_time = realtime; + + if (state->effects & EF_BLUE) + vars.enemy_powerups |= TP_QUAD; + if (state->effects & EF_RED) + vars.enemy_powerups |= TP_PENT; + if (eyes) + vars.enemy_powerups |= TP_RING; + } + } + if (!cl.spectator && !cl.teamfortress && info - cl.players == cl.playernum[SP]) + { + if ((state->effects & (QWEF_FLAG1|QWEF_FLAG2)) && !(oldstate->effects & (QWEF_FLAG1|QWEF_FLAG2))) + { + ExecTookTrigger (tp_name_flag.string, it_flag, cl.frames[cl.validsequence & UPDATE_MASK].playerstate[cl.playernum[SP]].origin); + } + else if (!(state->effects & (QWEF_FLAG1|QWEF_FLAG2)) && (oldstate->effects & (QWEF_FLAG1|QWEF_FLAG2))) + { + vars.lastdrop_time = realtime; + strcpy (vars.lastdroploc, Macro_Location()); + } + } +} void TP_CheckPickupSound (char *s, vec3_t org) { @@ -2212,137 +2536,276 @@ more: } } +static qboolean TP_IsItemVisible(item_vis_t *visitem) { + vec3_t end, v; + trace_t trace; -static void TP_FindPoint (void) -{ - packet_entities_t *pak; - entity_state_t *ent; - int i; - vec3_t forward, right, up; - float best = 0.0; - entity_state_t *bestent = NULL; - vec3_t ang; - vec3_t vieworg, entorg; - item_t *item = NULL, *bestitem = NULL; + if (visitem->dist <= visitem->radius) + return true; - ang[0] = cl.viewangles[SP][0]; - ang[1] = cl.viewangles[SP][1]; - ang[2] = 0; - AngleVectors (ang, forward, right, up); - VectorCopy (cl.simorg[SP], vieworg); - vieworg[2] += 22; // adjust for view height + VectorNegate (visitem->dir, v); + VectorNormalize (v); + VectorMA (visitem->entorg, visitem->radius, v, end); + trace = PM_TraceLine (visitem->vieworg, end); + if (trace.fraction == 1) + return true; + + VectorMA (visitem->entorg, visitem->radius, visitem->right, end); + VectorSubtract (visitem->vieworg, end, v); + VectorNormalize (v); + VectorMA (end, visitem->radius, v, end); + trace = PM_TraceLine (visitem->vieworg, end); + if (trace.fraction == 1) + return true; + + VectorMA(visitem->entorg, -visitem->radius, visitem->right, end); + VectorSubtract(visitem->vieworg, end, v); + VectorNormalize(v); + VectorMA(end, visitem->radius, v, end); + trace = PM_TraceLine(visitem->vieworg, end); + if (trace.fraction == 1) + return true; + + VectorMA(visitem->entorg, visitem->radius, visitem->up, end); + VectorSubtract(visitem->vieworg, end, v); + VectorNormalize(v); + VectorMA (end, visitem->radius, v, end); + trace = PM_TraceLine(visitem->vieworg, end); + if (trace.fraction == 1) + return true; + + // use half the radius, otherwise it's possible to see through floor in some places + VectorMA(visitem->entorg, -visitem->radius / 2, visitem->up, end); + VectorSubtract(visitem->vieworg, end, v); + VectorNormalize(v); + VectorMA(end, visitem->radius, v, end); + trace = PM_TraceLine(visitem->vieworg, end); + if (trace.fraction == 1) + return true; + + return false; +} + +static float TP_RankPoint(item_vis_t *visitem) { + vec3_t v2, v3; + float miss; + + if (visitem->dist < 10) + return -1; + + VectorScale (visitem->forward, visitem->dist, v2); + VectorSubtract (v2, visitem->dir, v3); + miss = VectorLength (v3); + if (miss > 300) + return -1; + if (miss > visitem->dist * 1.7) + return -1; // over 60 degrees off + + return (visitem->dist < 3000.0 / 8.0) ? miss * (visitem->dist * 8.0 * 0.0002f + 0.3f) : miss; +} + +static char *Utils_TF_ColorToTeam_Failsafe(int color) { + int i, j, teamcounts[8], numteamsseen = 0, best = -1; + char *teams[MAX_CLIENTS]; + + memset(teams, 0, sizeof(teams)); + memset(teamcounts, 0, sizeof(teamcounts)); + + for (i = 0; i < MAX_CLIENTS; i++) { + if (!cl.players[i].name[0] || cl.players[i].spectator) + continue; + if (cl.players[i].bottomcolor != color) + continue; + for (j = 0; j < numteamsseen; j++) { + if (!strcmp(cl.players[i].team, teams[j])) + break; + } + if (j == numteamsseen) { + teams[numteamsseen] = cl.players[i].team; + teamcounts[numteamsseen] = 1; + numteamsseen++; + } else { + teamcounts[j]++; + } + } + for (i = 0; i < numteamsseen; i++) { + if (best == -1 || teamcounts[i] > teamcounts[best]) + best = i; + } + return (best == -1) ? "" : teams[best]; +} + +char *Utils_TF_ColorToTeam(int color) { + char *s; + + switch (color) { + case 13: + if (*(s = Info_ValueForKey(cl.serverinfo, "team1")) || *(s = Info_ValueForKey(cl.serverinfo, "t1"))) + return s; + break; + case 4: + if (*(s = Info_ValueForKey(cl.serverinfo, "team2")) || *(s = Info_ValueForKey(cl.serverinfo, "t2"))) + return s; + break; + case 12: + if (*(s = Info_ValueForKey(cl.serverinfo, "team3")) || *(s = Info_ValueForKey(cl.serverinfo, "t3"))) + return s; + break; + case 11: + if (*(s = Info_ValueForKey(cl.serverinfo, "team4")) || *(s = Info_ValueForKey(cl.serverinfo, "t4"))) + return s; + break; + default: + return ""; + } + return Utils_TF_ColorToTeam_Failsafe(color); +} + + +static void TP_FindPoint (void) { + packet_entities_t *pak; + entity_state_t *ent; + int i, j, pointflags_dmm; + float best = -1, rank; + entity_state_t *bestent=NULL; + vec3_t ang; + item_t *item, *bestitem = NULL; + player_state_t *state, *beststate = NULL; + player_info_t *info, *bestinfo = NULL; + item_vis_t visitem; + extern cvar_t v_viewheight; + + if (vars.pointtime == realtime) + return; if (!cl.validsequence) goto nothing; - best = -1; + ang[0] = cl.viewangles[0][0]; ang[1] = cl.viewangles[0][1]; ang[2] = 0; + AngleVectors (ang, visitem.forward, visitem.right, visitem.up); + VectorCopy (cl.simorg[0], visitem.vieworg); + visitem.vieworg[2] += 22 + (v_viewheight.value ? bound (-7, v_viewheight.value, 4) : 0); - pak = &cl.frames[cl.validsequence&UPDATE_MASK].packet_entities; - for (i=0,ent=pak->entities ; inum_entities ; i++,ent++) - { - vec3_t v, v2, v3; - float dist, miss, rank; + pointflags_dmm = pointflags; + if (!cl.teamfortress && cl.deathmatch >= 1 && cl.deathmatch <= 4) { + if (cl.deathmatch == 4) + pointflags_dmm &= ~it_ammo; + if (cl.deathmatch != 1) + pointflags_dmm &= ~it_weapons; + } + pak = &cl.frames[cl.validsequence & UPDATE_MASK].packet_entities; + for (i = 0,ent = pak->entities; i < pak->num_entities; i++, ent++) { item = model2item[ent->modelindex]; - if (!item) - continue; - if (! (item->itemflag & pointflags) ) + if (!item || !(item->itemflag & pointflags_dmm)) continue; // special check for armors if (item->itemflag == (it_ra|it_ya|it_ga)) { switch (ent->skinnum) { - case 0: if (!(pointflags & it_ga)) continue; break; - case 1: if (!(pointflags & it_ya)) continue; break; - default: if (!(pointflags & it_ra)) continue; + case 0: if (!(pointflags_dmm & it_ga)) continue; + case 1: if (!(pointflags_dmm & it_ya)) continue; + default: if (!(pointflags_dmm & it_ra)) continue; } } - VectorCopy(ent->origin, entorg); - VectorAdd (entorg, item->offset, entorg); - VectorSubtract (entorg, vieworg, v); + VectorAdd (ent->origin, item->offset, visitem.entorg); + VectorSubtract (visitem.entorg, visitem.vieworg, visitem.dir); + visitem.dist = DotProduct (visitem.dir, visitem.forward); + visitem.radius = ent->effects & (EF_BLUE|EF_RED|EF_DIMLIGHT|EF_BRIGHTLIGHT) ? 200 : item->radius; - dist = DotProduct (v, forward); - if (dist < 10) + if ((rank = TP_RankPoint(&visitem)) < 0) continue; - VectorScale (forward, dist, v2); - VectorSubtract (v2, v, v3); - miss = VectorLength (v3); - if (miss > 300) - continue; - if (miss > dist*1.7) - continue; // over 60 degrees off - if (dist < 3000.0/8.0) - rank = miss * (dist*8.0*0.0002f + 0.3f); - else - rank = miss; - - if (rank < best || best < 0) { - // check if we can actually see the object - vec3_t end; - trace_t trace; - float radius; - radius = item->radius; - if (ent->effects & (EF_BLUE|EF_RED|EF_DIMLIGHT|EF_BRIGHTLIGHT)) - radius = 200; - - if (dist <= radius) - goto ok; - - // FIXME: is it ok to use PM_TraceLine here? - // physent list might not have been built yet... - - VectorSubtract (vieworg, entorg, v); - VectorNormalize (v); - VectorMA (entorg, radius, v, end); - trace = PM_PlayerTrace (vieworg, end); - if (trace.fraction == 1) - goto ok; - - VectorMA (entorg, radius, right, end); - VectorSubtract (vieworg, end, v); - VectorNormalize (v); - VectorMA (end, radius, v, end); - trace = PM_PlayerTrace (vieworg, end); - if (trace.fraction == 1) - goto ok; - - VectorMA (entorg, -radius, right, end); - VectorSubtract (vieworg, end, v); - VectorNormalize (v); - VectorMA (end, radius, v, end); - trace = PM_PlayerTrace (vieworg, end); - if (trace.fraction == 1) - goto ok; - - VectorMA (entorg, radius, up, end); - VectorSubtract (vieworg, end, v); - VectorNormalize (v); - VectorMA (end, radius, v, end); - trace = PM_PlayerTrace (vieworg, end); - if (trace.fraction == 1) - goto ok; - - // use half the radius, otherwise it's possible to see - // through floor in some places - VectorMA (entorg, -radius/2, up, end); - VectorSubtract (vieworg, end, v); - VectorNormalize (v); - VectorMA (end, radius, v, end); - trace = PM_PlayerTrace (vieworg, end); - if (trace.fraction == 1) - goto ok; - - continue; // not visible -ok: + // check if we can actually see the object + if ((rank < best || best < 0) && TP_IsItemVisible(&visitem)) { best = rank; bestent = ent; bestitem = item; } } - if (best >= 0) { + state = cl.frames[cl.parsecount & UPDATE_MASK].playerstate; + info = cl.players; + for (j = 0; j < MAX_CLIENTS; j++, info++, state++) { + if (state->messagenum != cl.parsecount || j == cl.playernum[0] || info->spectator) + continue; + + if ( + state->modelindex == cl_playerindex && ISDEAD(state->frame) || + state->modelindex == cl_h_playerindex + ) + continue; + + VectorCopy (state->origin, visitem.entorg); + visitem.entorg[2] += 30; + VectorSubtract (visitem.entorg, visitem.vieworg, visitem.dir); + visitem.dist = DotProduct (visitem.dir, visitem.forward); + visitem.radius = (state->effects & (EF_BLUE|EF_RED|EF_DIMLIGHT|EF_BRIGHTLIGHT) ) ? 200 : 27; + + if ((rank = TP_RankPoint(&visitem)) < 0) + continue; + + // check if we can actually see the object + if ((rank < best || best < 0) && TP_IsItemVisible(&visitem)) { + qboolean teammate, eyes = false; + + eyes = state->modelindex && cl.model_precache[state->modelindex] && !strcmp(cl.model_precache[state->modelindex]->name, "progs/eyes.mdl"); + teammate = !!(cl.teamplay && !strcmp(info->team, TP_PlayerTeam())); + + if (eyes && !(pointflags_dmm & it_eyes)) + continue; + else if (teammate && !(pointflags_dmm & it_teammate)) + continue; + else if (!(pointflags_dmm & it_enemy)) + continue; + + best = rank; + bestinfo = info; + beststate = state; + } + } + + if (best >= 0 && bestinfo) { + qboolean teammate, eyes; + char *name, buf[256] = {0}; + + eyes = beststate->modelindex && cl.model_precache[beststate->modelindex] && !strcmp(cl.model_precache[beststate->modelindex]->name, "progs/eyes.mdl"); + if (cl.teamfortress) { + teammate = !strcmp(Utils_TF_ColorToTeam(bestinfo->bottomcolor), TP_PlayerTeam()); + + if (eyes) + name = tp_name_eyes.string; //duck on 2night2 + else if (cl.spectator) + name = bestinfo->name; + else if (teammate) + name = tp_name_teammate.string[0] ? tp_name_teammate.string : "teammate"; + else + name = tp_name_enemy.string; + + if (!eyes) + name = va("%s%s%s", name, name[0] ? " " : "", Skin_To_TFSkin(Info_ValueForKey(bestinfo->userinfo, "skin"))); + } else { + teammate = !!(cl.teamplay && !strcmp(bestinfo->team, TP_PlayerTeam())); + + if (eyes) + name = tp_name_eyes.string; + else if (cl.spectator || (teammate && !tp_name_teammate.string[0])) + name = bestinfo->name; + else + name = teammate ? tp_name_teammate.string : tp_name_enemy.string; + } + if (beststate->effects & EF_BLUE) + Q_strncatz(buf, tp_name_quaded.string); + if (beststate->effects & EF_RED) + Q_strncatz(buf, va("%s%s", buf[0] ? " " : "", tp_name_pented.string)); + Q_strncatz(buf, va("%s%s", buf[0] ? " " : "", name)); + Q_strncpyz (vars.pointname, buf, sizeof(vars.pointname)); + Q_strncpyz (vars.pointloc, TP_LocationName (beststate->origin), sizeof(vars.pointloc)); + + vars.pointtype = (teammate && !eyes) ? POINT_TYPE_TEAMMATE : POINT_TYPE_ENEMY; + } else if (best >= 0) { char *p; + if (!bestitem->cvar) { // armors are special switch (bestent->skinnum) { @@ -2350,21 +2813,21 @@ ok: case 1: p = tp_name_ya.string; break; default: p = tp_name_ra.string; } - } else + } else { p = bestitem->cvar->string; + } - strlcpy (vars.pointname, p, sizeof(vars.pointname)); - VectorCopy (bestent->origin, entorg); - strlcpy (vars.pointloc, TP_LocationName (entorg), sizeof(vars.pointloc)); - VectorCopy (entorg, vars.pointorg); + vars.pointtype = (bestitem->itemflag & (it_powerups|it_flag)) ? POINT_TYPE_POWERUP : POINT_TYPE_ITEM; + Q_strncpyz (vars.pointname, p, sizeof(vars.pointname)); + Q_strncpyz (vars.pointloc, TP_LocationName (bestent->origin), sizeof(vars.pointloc)); } else { nothing: - strlcpy (vars.pointname, tp_name_nothing.string, sizeof(vars.pointname)); + Q_strncpyz (vars.pointname, tp_name_nothing.string, sizeof(vars.pointname)); vars.pointloc[0] = 0; + vars.pointtype = POINT_TYPE_ITEM; } - - vars.pointframe = cls.framecount; + vars.pointtime = realtime; } @@ -2395,6 +2858,10 @@ void TP_StatChanged (int stat, int value) vars.deathtrigger_time = realtime; strcpy (vars.lastdeathloc, Macro_Location()); + CountNearbyPlayers(true); + vars.last_numenemies = vars.numenemies; + vars.last_numfriendlies = vars.numfriendlies; + if (!cl.spectator && CountTeammates()) { if (cl.teamfortress && (cl.stats[SP][STAT_ITEMS] & (IT_KEY1|IT_KEY2)) @@ -2636,14 +3103,25 @@ void TP_Init (void) +qboolean TP_SuppressMessage(char *buf) { + char *s; + for (s = buf; *s && *s != 0x7f; s++) + ; + if (*s == 0x7f && *(s + 1) == '!') { + *s++ = '\n'; + *s++ = 0; + return (!cls.demoplayback && !cl.spectator && *s - 'A' == cl.playernum[0]); + } + return false; +} static void CL_Say (qboolean team, char *extra) { extern cvar_t cl_fakename; - char text[1024], sendtext[1024], *s; + char text[2048], sendtext[2048], *s; if (Cmd_Argc() < 2) { @@ -2658,6 +3136,8 @@ static void CL_Say (qboolean team, char *extra) return; } + suppress = false; + s = TP_ParseMacroString (Cmd_Args()); Q_strncpyz (text, TP_ParseFunChars (s, true), sizeof(text)); @@ -2672,14 +3152,92 @@ static void CL_Say (qboolean team, char *extra) } strlcat (sendtext, text, sizeof(sendtext)); + if (suppress) + { + extern cvar_t cl_standardchat; + //print it locally: + char *d; + char colouration; + for (s = sendtext, d = text; *s; s++, d++) + { + if (*s == '\xff') //text that is hidden to us + { // + s++; + *d++ = '^'; + *d++ = '1'; + if (*s == 'z') + *d++ = 'x'; + else + *d++ = 139; + + *d++ = '^'; + *d++ = '1'; + d--; + + while(*s != '\xff') + { + if (!*s) + break; + s++; + } + if (!*s) + break; + } + else + *d = *s; + } + *d = '\0'; + + + if (!cl_standardchat.value) + colouration = CL_PlayerChatColour(cl.playernum[SP])%6+'1'; //don't ever print it in white. + else + { + con_ormask = CON_STANDARDMASK; + colouration = '7'; + } + + if (team) + Con_Printf("^%c(%s): %s\n", colouration, cl.players[cl.playernum[SP]].name, text); + else + Con_Printf("^%c%s: %s\n", colouration, cl.players[cl.playernum[SP]].name, text); + + con_ormask = 0; + + //strip out the extra markup + for (s = sendtext, d = sendtext; *s; s++, d++) + { + if (*s == '\xff') //text that is hidden to us + { // + s++; + if (*s == 'z') + s++; + while(*s != '\xff') + { + if (!*s) + break; + *d++ = *s++; + } + if (!*s) + break; + d--; + } + + else + *d = *s; + } + *d = '\0'; + + //mark the message so that we ignore it when we get the echo. + strlcat (sendtext, va("\x7f!%c", 'A'+cl.playernum[0]), sizeof(sendtext)); + } + #ifdef Q3CLIENT if (cls.q2server==2) - { CLQ3_SendClientCommand("%s %s%s", team ? "say_team " : "say ", extra?extra:"", sendtext); - return; - } + else #endif - CL_SendClientCommand(true, "%s \"%s%s\"", team ? "say_team " : "say ", extra?extra:"", sendtext); + CL_SendClientCommand(true, "%s \"%s%s\"", team ? "say_team " : "say ", extra?extra:"", sendtext); } diff --git a/engine/common/cmd.c b/engine/common/cmd.c index d46fe3e36..155a011cf 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -2135,7 +2135,7 @@ skipws: for (ws = end + strlen(end)-1; ws >= end && *ws <= ' '; ws--) //skip trailing *ws = '\0'; - if (!strcmp(end, "then")) //sigh... trying to make fuhquake's ifs work. + if (!strncmp(end, "then", 4)) //sigh... trying to make fuhquake's ifs work. { end+=4; goto skipws; diff --git a/engine/common/common.c b/engine/common/common.c index f76bc9297..048447fa7 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -2388,7 +2388,10 @@ typedef struct #define MAX_FILES_IN_PACK 2048 char com_gamedir[MAX_OSPATH]; -char com_basedir[MAX_OSPATH]; +char *com_basedir; + +char com_quakedir[MAX_OSPATH]; +char com_homedir[MAX_OSPATH]; #define ZEXPORT VARGS @@ -2792,258 +2795,7 @@ Sets com_filesize and one of handle or file =========== */ int file_from_pak; // global indicating file came from pack file ZOID -#if 0 -/* -int COM_FOpenFile2 (char *sensativename, FILE **file, qboolean compressedokay) -{ - searchpath_t *search; - char netpath[MAX_OSPATH]; - int findtime; - char filename[MAX_QPATH]; - Q_strncpyz(filename, sensativename, sizeof(filename)); - Q_strlwr(filename); - - if (filename[strlen(filename)-1] == '/') - { - *file = NULL; - com_filesize = -1; -#ifdef ZLIB - com_pathforfile=NULL; -#endif - return -1; - } - - if (com_fs_cache.value && !developer.value) - { - if (com_fschanged) - FS_RebuildFSHash(); - - if (filesystemhash.numbuckets) - { - void *value; - value = Hash_Get(&filesystemhash, filename); - - if (!value) //we don't know about a file by this name - { - Con_DPrintf ("FindFile: don't know %s\n", filename); - - *file = NULL; - com_filesize = -1; -#ifdef ZLIB - com_pathforfile=NULL; -#endif - return -1; - } - - for (search = com_searchpaths ; search ; search = search->next) - { - switch (search->type) - { - case SPT_PACK: - { - pack_t *pak; - packfile_t *pf = value; - pak = search->u.pack; - if (pf >= pak->files && pf < pak->files+pak->numfiles) //is the range right? - { - //is in this pack file - Con_DPrintf ("PackFile: %s : %s\n",pak->filename, filename); - - // open a new file on the pakfile - *file = fopen (pak->filename, "rb"); - if (!*file) - Sys_Error ("Couldn't reopen %s", pak->filename); - fseek (*file, pf->filepos, SEEK_SET); - com_filesize = pf->filelen; - - file_from_pak = 1; -#ifdef ZLIB - com_pathforfile=NULL; -#endif - return com_filesize; - } - } - break; -#ifdef ZLIB - case SPT_ZIP: - { - zipfile_t *zip; - packfile_t *pfile = value; - zip = search->u.zip; - if (pfile >= zip->files && pfile < zip->files+zip->numfiles) //is the pointer to within the list? - { - Con_DPrintf ("ZipFile: %s : %s\n",zip->filename, filename); - - file_from_pak = 2; - com_filenum = pfile - zip->files; - com_filesize = pfile->filelen ; - if (!compressedokay) - { - unzLocateFileMy (zip->handle, com_filenum, zip->files[com_filenum].filepos); - if ((*file = unzOpenCurrentFileFile(zip->handle, search->filename))) //phew! - { - com_pathforfile = NULL; - return pfile->filelen; - } - Con_TPrintf(TL_COMPRESSEDFILEOPENFAILED, filename); - break; - } - else - { - *file = NULL; - com_pathforfile = search; - return pfile->filelen; - } - } - } - break; -#endif - case SPT_OS: - if (value == search) //hash tables refer to the searchpath. - { - sprintf (netpath, "%s/%s",search->filename, filename); - - findtime = Sys_FileTime (netpath); - if (findtime == -1) - break; - - Con_DPrintf ("FindFile: %s\n",netpath); - - *file = fopen (netpath, "rb"); - file_from_pak = 0; -#ifdef ZLIB - com_pathforfile=NULL; -#endif - return COM_filelength (*file); - } - break; - } - } - - Con_Printf ("FindFile: can't find %s\n", filename); - - *file = NULL; - com_filesize = -1; - return -1; - } - } - -// -// search through the path, one element at a time -// - for (search = com_searchpaths ; search ; search = search->next) - { - // is the element a pak file? - switch (search->type) - { - case SPT_PACK: - { - int i; - pack_t *pak; - - // look through all the pak file elements - pak = search->u.pack; - for (i=0 ; inumfiles ; i++) - { - if (!strcmp (pak->files[i].name, filename)) - { // found it! - Con_DPrintf ("PackFile: %s : %s\n",pak->filename, filename); - - // open a new file on the pakfile - *file = fopen (pak->filename, "rb"); - if (!*file) - Sys_Error ("Couldn't reopen %s", pak->filename); - fseek (*file, pak->files[i].filepos, SEEK_SET); - com_filesize = pak->files[i].filelen; - file_from_pak = 1; - #ifdef ZLIB - com_pathforfile=NULL; - #endif - return com_filesize; - } - } - } - break; -#ifdef ZLIB - case SPT_ZIP: - { - packfile_t *pfile; - zipfile_t *zip = search->u.zip; - if ((pfile = Com_FileInZip(zip, filename))) - { - file_from_pak = 2; - com_filenum = pfile - zip->files; - com_filesize = pfile->filelen ; - if (!compressedokay) - { - unzLocateFileMy (zip->handle, com_filenum, zip->files[com_filenum].filepos); - if ((*file = unzOpenCurrentFileFile(zip->handle, search->filename))) //phew! - { - com_pathforfile = NULL; - return pfile->filelen; - } - - //this code copies it to a temp file for ultimate hackage. - { - char *buf; - FILE *f = tmpfile(); - buf = BZ_Malloc(pfile->filelen); - Com_ReadFileInZip(zip, buf); - fwrite(buf, 1, pfile->filelen, f); - fseek(f, 0, SEEK_SET); - - *file = f; - com_pathforfile = search; - return pfile->filelen; - } - Con_TPrintf(TL_COMPRESSEDFILEOPENFAILED, filename); - continue; - } - *file = NULL; - com_pathforfile = search; - return pfile->filelen; - } - } - break; -#endif - case SPT_OS: - // check a file in the directory tree - if (!static_registered) - { // if not a registered version, don't ever go beyond base - if ( strchr (filename, '/') || strchr (filename,'\\')) - continue; - } - - _snprintf (netpath, sizeof(netpath)-1, "%s/%s",search->filename, filename); - - findtime = Sys_FileTime (netpath); - if (findtime == -1) - continue; - - Con_DPrintf ("FindFile: %s\n",netpath); - - *file = fopen (netpath, "rb"); - file_from_pak = 0; -#ifdef ZLIB - com_pathforfile=NULL; -#endif - return COM_filelength (*file); - default: - Sys_Error("COM_FOpenFile2: bad searchpath type\n"); - break; - } - - } - - //Con_DPrintf ("FindFile: can't find %s\n", filename); - - *file = NULL; - com_filesize = -1; - return -1; -} -*/ -#endif //if loc is valid, loc->search is always filled in, the others are filled on success. //returns -1 if couldn't find. int FS_FLocateFile(char *filename, FSLF_ReturnType_e returntype, flocation_t *loc) @@ -4265,6 +4017,8 @@ void COM_AddGameDirectory (char *dir) Sys_EnumerateFiles(com_gamedir, "*.pk3", COM_AddZipsWild, NULL); //don't do zips. we could, but don't. it's not a great idea. #endif + + com_fschanged = true; } char *COM_NextPath (char *prevpath) @@ -4332,7 +4086,7 @@ Sets the gamedir and path to a different directory. */ void COM_Gamedir (char *dir) { - searchpath_t *search, *next; + searchpath_t *next; if (strstr(dir, "..") || strstr(dir, "/") || strstr(dir, "\\") || strstr(dir, ":") ) @@ -4399,46 +4153,10 @@ void COM_Gamedir (char *dir) // Cache_Flush (); - sprintf (com_gamedir, "%s/%s", com_basedir, dir); + COM_AddGameDirectory(va("%s/%s", com_quakedir, dir)); + if (*com_homedir) + COM_AddGameDirectory(va("%s/%s", com_homedir, dir)); - for (search = com_searchpaths; search; search = search->next) //see if it's already loaded (base paths) - { - if (!strcmp(search->filename, com_gamedir)) - break; - } - - if (!search) //was already part of the basic. - { - // - // add the directory to the search path - // - search = (searchpath_t*)Z_Malloc (sizeof(searchpath_t)); - search->type = SPT_OS; - strcpy (search->filename, com_gamedir); - search->next = com_searchpaths; - com_searchpaths = search; - - COM_AddPacks("%s/pak%i.pak"); - -#ifdef ZLIB - COM_AddZips("%s/pak%i.zip"); - COM_AddZips("%s/pak%i.pk3"); -#endif - -#ifdef DOOMWADS - COM_AddWad("doom.wad"); - COM_AddWad("doom2.wad"); - COM_AddWad("dv.wad"); -#endif - - Sys_EnumerateFiles(com_gamedir, "*.pak", COM_AddPacksWild, NULL); -#ifdef ZLIB - Sys_EnumerateFiles(com_gamedir, "*.pk3", COM_AddZipsWild, NULL); - //don't do zips. we could, but don't. it's not a great idea. -#endif - - com_fschanged = true; - } #ifndef SERVERONLY { @@ -4452,11 +4170,11 @@ void COM_Gamedir (char *dir) if ((f = fopen(fn, "r")) != NULL) { fclose(f); - Cbuf_InsertText("cl_warncmd 1\n", RESTRICT_LOCAL); - Cbuf_InsertText("exec frontend.cfg\n", RESTRICT_LOCAL); - Cbuf_InsertText("exec fte.cfg\n", RESTRICT_LOCAL); - Cbuf_InsertText("exec config.cfg\n", RESTRICT_LOCAL); - Cbuf_InsertText("cl_warncmd 0\n", RESTRICT_LOCAL); + Cbuf_InsertText("cl_warncmd 0\n" + "exec config.cfg\n" + "exec fte.cfg\n" + "exec frontend.cfg\n" + "cl_warncmd 1\n", RESTRICT_LOCAL); } } @@ -4474,6 +4192,18 @@ void COM_Gamedir (char *dir) #endif } +typedef struct { + char *file; + char *path; +} potentialgamepath_t; + +potentialgamepath_t pgp[] = { + {"%s/id1/pak0.pak", "%s/id1"}, //quake1 + {"%s/baseq2/pak0.pak", "%s/baseq2"}, //quake2 + {"%s/data1/pak0.pak", "%s/data1"}, //hexen2 + {"%s/baseq3/pak0.pk3", "%s/baseq3"}, //quake3 + {"%s/base/assets0.pk3", "%s/base"} //jk2 +}; /* ================ COM_InitFilesystem @@ -4484,15 +4214,55 @@ void COM_InitFilesystem (void) FILE *f; int i; + char *ev; + + // // -basedir // Overrides the system supplied base directory (under id1) // i = COM_CheckParm ("-basedir"); if (i && i < com_argc-1) - strcpy (com_basedir, com_argv[i+1]); + strcpy (com_quakedir, com_argv[i+1]); else - strcpy (com_basedir, host_parms.basedir); + strcpy (com_quakedir, host_parms.basedir); + +#ifdef _WIN32 + { //win32 sucks. + ev = getenv("HOMEDRIVE"); + if (ev) + strcpy(com_homedir, ev); + else + strcpy(com_homedir, ""); + ev = getenv("HOMEPATH"); + if (ev) + strcat(com_homedir, ev); + else + strcat(com_homedir, "/"); + } +#else + if (!ev) + { //yay for unix!. + ev = getenv("HOME"); + if (ev) + Q_strncpyz(com_homedir, ev, sizeof(com_homedir)); + else + *com_homedir = *""; + } +#endif + + if (!COM_CheckParm("-usehome")) + *com_homedir = '\0'; + + if (*com_homedir) + { + strcat(com_homedir, "/.fte/"); + com_basedir = com_homedir; + } + else + { + com_basedir = com_quakedir; + } // // start up with id1 by default @@ -4502,7 +4272,7 @@ void COM_InitFilesystem (void) { do //use multiple -basegames { - COM_AddGameDirectory (va("%s/%s", com_basedir, com_argv[i+1]) ); + COM_AddGameDirectory (va("%s/%s", com_quakedir, com_argv[i+1]) ); i = COM_CheckNextParm ("-basegame", i); } @@ -4510,53 +4280,25 @@ void COM_InitFilesystem (void) } else { - //if there is no pak0.pak file in id1, and baseq2 has one, use that instead. - f = fopen(va("%s/id1/pak0.pak", com_basedir), "rb"); - if (f) + for (i = 0; i < sizeof(pgp)/sizeof(pgp[0]); i++) { - fclose(f); - COM_AddGameDirectory (va("%s/id1", com_basedir) ); - } - else - { - f = fopen(va("%s/baseq2/pak0.pak", com_basedir), "rb"); + f = fopen(va(pgp[i].file, com_quakedir), "rb"); if (f) { fclose(f); - COM_AddGameDirectory (va("%s/baseq2", com_basedir) ); - } - else - { //hexen2. - f = fopen(va("%s/data1/pak0.pak", com_basedir), "rb"); - if (f) - { - fclose(f); - COM_AddGameDirectory (va("%s/data1", com_basedir) ); - } - else - {//quake3, we don't have full support for this, so... - f = fopen(va("%s/baseq3/pak0.pk3", com_basedir), "rb"); - if (f) - { - fclose(f); - COM_AddGameDirectory (va("%s/baseq3", com_basedir) ); - } - else - { - f = fopen(va("%s/base/assets0.pk3", com_basedir), "rb"); - if (f) - { - fclose(f); - COM_AddGameDirectory (va("%s/base", com_basedir) ); - } - else - COM_AddGameDirectory (va("%s/id1", com_basedir) ); //ah well, id1 it is, they mustve unpacked it. - } - } + COM_AddGameDirectory (va(pgp[i].path, com_quakedir)); + break; } } + if (i == sizeof(pgp)/sizeof(pgp[0])) + COM_AddGameDirectory (va(pgp[0].path, com_quakedir)); //just use the first. The assumption is that they unpacked thier data and deleted the pak files. } - COM_AddGameDirectory (va("%s/qw", com_basedir) ); + + COM_AddGameDirectory (va("%s/qw", com_quakedir) ); + COM_AddGameDirectory (va("%s/fte", com_quakedir) ); + + if (*com_homedir) + COM_AddGameDirectory (va("%s/fte", com_homedir) ); // any set gamedirs will be freed up to here com_base_searchpaths = com_searchpaths; @@ -4564,7 +4306,7 @@ void COM_InitFilesystem (void) i = COM_CheckParm ("-game"); //effectivly replace with +gamedir x (But overridable) if (i && i < com_argc-1) { - COM_AddGameDirectory (va("%s/%s", com_basedir, com_argv[i+1]) ); + COM_AddGameDirectory (va("%s/%s", com_quakedir, com_argv[i+1]) ); #ifndef CLIENTONLY Info_SetValueForStarKey (svs.info, "*gamedir", com_argv[i+1], MAX_SERVERINFO_STRING); diff --git a/engine/common/common.h b/engine/common/common.h index ca9750fa0..fb5b0232a 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -187,6 +187,12 @@ int wildcmp(char *wild, char *string); //1 if match #define Q_strncpyz(d, s, n) Q_strncpyN(d, s, (n)-1) #else void Q_strncpyz(char*d, const char*s, int n); +#define Q_strncatz(dest, src, sizeofdest) \ + do { \ + strncat(dest, src, sizeofdest - strlen(dest) - 1); \ + dest[sizeofdest - 1] = 0; \ + } while (0) +#define Q_strncatz2(dest, src) Q_strncatz(dest, src, sizeof(dest)) #endif //#define Q_strncpy Please remove all strncpys /*#ifndef strncpy diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index d03a950e2..d351aadac 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -988,8 +988,9 @@ void *Mod_LoadWall(char *name) tex->height = height; texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; - if (!(tex->gl_texturenum = Mod_LoadReplacementTexture(name, true, false, true))) - tex->gl_texturenum = GL_LoadTexture32 (name, width, height, (unsigned int *)in, true, false); + if (!(tex->gl_texturenum = Mod_LoadReplacementTexture(name, loadname, true, false, true))) + if (!(tex->gl_texturenum = Mod_LoadReplacementTexture(name, "bmodels", true, false, true))) + tex->gl_texturenum = GL_LoadTexture32 (name, width, height, (unsigned int *)in, true, false); texture_mode = GL_LINEAR; } else @@ -1070,8 +1071,9 @@ void *Mod_LoadWall(char *name) tex->height = wal->height; texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; - if (!(tex->gl_texturenum = Mod_LoadReplacementTexture(wal->name, true, false, true))) - tex->gl_texturenum = GL_LoadTexture8Pal24 (wal->name, tex->width, tex->height, (qbyte *)wal+wal->offsets[0], d_q28to24table, true, false); + if (!(tex->gl_texturenum = Mod_LoadReplacementTexture(wal->name, loadname, true, false, true))) + if (!(tex->gl_texturenum = Mod_LoadReplacementTexture(wal->name, "bmodels", true, false, true))) + tex->gl_texturenum = GL_LoadTexture8Pal24 (wal->name, tex->width, tex->height, (qbyte *)wal+wal->offsets[0], d_q28to24table, true, false); in = Hunk_TempAllocMore(wal->width*wal->height); oin = (qbyte *)wal+wal->offsets[0]; @@ -1887,12 +1889,16 @@ void CModQ3_LoadShaders (lump_t *l) loadmodel->texinfo[i].texture = Hunk_Alloc(sizeof(texture_t)); Q_strncpyz(loadmodel->texinfo[i].texture->name, in->shadername, sizeof(loadmodel->texinfo[i].texture->name)); #ifdef RGLQUAKE +#ifndef Q3SHADERS if (qrenderer == QR_OPENGL) { - loadmodel->texinfo[i].texture->gl_texturenum = Mod_LoadHiResTexture(in->shadername, true, false, true); + loadmodel->texinfo[i].texture->gl_texturenum = Mod_LoadHiResTexture(in->shadername, loadname, true, false, true); + if (!loadmodel->texinfo[i].texture->gl_texturenum) + loadmodel->texinfo[i].texture->gl_texturenum = Mod_LoadHiResTexture(in->shadername, "bmodels", true, false, true); loadmodel->texinfo[i].texture->gl_texturenumfb = 0; loadmodel->texinfo[i].texture->gl_texturenumbumpmap = 0; } +#endif #endif loadmodel->textures[i] = loadmodel->texinfo[i].texture; @@ -2551,7 +2557,7 @@ continue; out->texinfo->texture->shader = R_RegisterShader(out->texinfo->texture->name); } - if (in->fognum == -1 || !map_numfogs) + if (in->fognum < 0 || in->fognum >= map_numfogs) out->fog = NULL; else out->fog = map_fogs + in->fognum; diff --git a/engine/common/pmovetst.c b/engine/common/pmovetst.c index 49b4a5635..d28c912f8 100644 --- a/engine/common/pmovetst.c +++ b/engine/common/pmovetst.c @@ -345,4 +345,9 @@ trace_t PM_PlayerTrace (vec3_t start, vec3_t end) return total; } - +//for use outside the pmove code. lame, but works. +trace_t PM_TraceLine (vec3_t start, vec3_t end) +{ + pmove.hullnum = 0; + return PM_PlayerTrace(start, end); +} \ No newline at end of file diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index 1d7abad6a..0a6f1e152 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -1066,7 +1066,7 @@ void GL_DrawAliasMesh (mesh_t *mesh, int texnum) qglDepthFunc(gldepthfunc); qglDepthMask(1); - + GL_Bind(texnum); if (gldepthmin == 0.5) qglCullFace ( GL_BACK ); @@ -2001,27 +2001,26 @@ static void *Q1_LoadSkins (daliasskintype_t *pskintype, qboolean alpha) outskin->skinwidth = pq1inmodel->skinwidth; outskin->skinheight = pq1inmodel->skinheight; - sprintf(skinname, "%s_%i", loadname, i); - texture = Mod_LoadReplacementTexture(skinname, true, false, true); - if (!texture) + //LH's naming scheme ("models" is likly to be ignored) + _snprintf(skinname, sizeof(skinname), "%s_%i", loadmodel->name, i); + texture = Mod_LoadReplacementTexture(skinname, "models", true, false, true); + if (texture) { - sprintf(skinname, "textures/models/%s_%i", loadname, i); - texture = Mod_LoadReplacementTexture(skinname, true, false, true); + _snprintf(skinname, sizeof(skinname), "%s_%i_luma", loadmodel->name, i); + texture = Mod_LoadReplacementTexture(skinname, "models", true, false, true); + } + else + { + sprintf(skinname, "%s_%i", loadname, i); + texture = Mod_LoadReplacementTexture(skinname, "models", true, false, true); if (texture && r_fb_models.value) { - sprintf(skinname, "textures/models/%s_%i_luma", loadname, i); - fbtexture = Mod_LoadReplacementTexture(skinname, true, true, true); + sprintf(skinname, "%s_%i_luma", loadname, i); + fbtexture = Mod_LoadReplacementTexture(skinname, "models", true, true, true); } else fbtexture = 0; } - else if (texture && r_fb_models.value) - { - sprintf(skinname, "%s_%i_luma", loadname, i); - fbtexture = Mod_LoadReplacementTexture(skinname, true, true, true); - } - else - fbtexture = 0; if (!texture) { @@ -2065,18 +2064,34 @@ static void *Q1_LoadSkins (daliasskintype_t *pskintype, qboolean alpha) outskin->ofstexels = 0; for (t = 0; t < outskin->texnums; t++,data+=s, texnums++) { - sprintf(skinname, "%s_%i%c", loadname, i, t+'a'); - texture = Mod_LoadReplacementTexture(skinname, true, false, true); - if (texture) + texture = 0; + fbtexture = 0; + + //LH naming scheme + if (!texture) { - texnums->base = texture; - if (r_fb_models.value) - { - sprintf(skinname, "%s_%i%c_luma", loadname, i, t+'a'); - texnums->fullbright = Mod_LoadReplacementTexture(skinname, true, true, true); - } + sprintf(skinname, "%s_%i_%i", loadmodel->name, i, t); + texture = Mod_LoadReplacementTexture(skinname, "models", true, false, true); } - else + if (!fbtexture && r_fb_models.value) + { + sprintf(skinname, "%s_%i_%i_luma", loadmodel->name, i, t); + fbtexture = Mod_LoadReplacementTexture(skinname, "models", true, true, true); + } + + //Fuhquake naming scheme + if (!texture) + { + sprintf(skinname, "%s_%i_%i", loadname, i, t); + texture = Mod_LoadReplacementTexture(skinname, "models", true, false, true); + } + if (!fbtexture && r_fb_models.value) + { + sprintf(skinname, "%s_%i_%i_luma", loadname, i, t); + fbtexture = Mod_LoadReplacementTexture(skinname, "models", true, true, true); + } + + if (!texture || (!fbtexture && r_fb_models.value)) { if (t == 0) { @@ -2087,47 +2102,24 @@ static void *Q1_LoadSkins (daliasskintype_t *pskintype, qboolean alpha) saved = BZ_Malloc(s); memcpy(saved, pskintype+1, s); GLMod_FloodFillSkin(saved, outskin->skinwidth, outskin->skinheight); - sprintf(skinname, "%s_%i%c", loadname, i, t+'a'); - texnums->base = GL_LoadTexture(skinname, outskin->skinwidth, outskin->skinheight, saved, true, alpha); - - if (gl_bumpmappingpossible) + if (!texture) { - char name[MAX_QPATH]; - COM_StripExtension(skinname, name); //go for the normalmap - strcat(name, "_norm"); - texnums->bump = Mod_LoadHiResTexture(name, true, true, false); - if (!texnums->bump) - { - strcpy(name, loadmodel->name); - COM_StripExtension(COM_SkipPath(skinname), COM_SkipPath(name)); - strcat(name, "_norm"); - texnums->bump = Mod_LoadHiResTexture(name, true, true, false); - if (!texnums->bump) - { - COM_StripExtension(skinname, name); //bother, go for heightmap and convert - strcat(name, "_bump"); - texnums->bump = Mod_LoadBumpmapTexture(name); - if (!texnums->bump) - { - strcpy(name, loadmodel->name); - strcpy(COM_SkipPath(name), COM_SkipPath(skinname)); //eviile eh? - COM_StripExtension(name, name); - strcat(name, "_bump"); - texnums->bump = Mod_LoadBumpmapTexture(name); - } - } - } + sprintf(skinname, "%s_%i_%i", loadname, i, t); + texture = GL_LoadTexture(skinname, outskin->skinwidth, outskin->skinheight, saved, true, alpha); } - if (r_fb_models.value) + + if (!fbtexture && r_fb_models.value) { - sprintf(skinname, "%s_%i%c_luma", loadname, i, t+'a'); - texnums->fullbright = GL_LoadTextureFB(skinname, outskin->skinwidth, outskin->skinheight, saved, true, true); + sprintf(skinname, "%s_%i_%i_luma", loadname, i, t); + fbtexture = GL_LoadTextureFB(skinname, outskin->skinwidth, outskin->skinheight, saved, true, true); } if (t != 0) //only keep the first. BZ_Free(saved); } + texnums->base = texture; + texnums->fullbright = fbtexture; } pskintype = (daliasskintype_t *)data; break; @@ -2360,7 +2352,7 @@ static void Q2_LoadSkins(char *skins) outskin->texnums=1; COM_CleanUpPath(skins); //blooming tanks. - texnums->base = Mod_LoadReplacementTexture(skins, true, false, true); + texnums->base = Mod_LoadReplacementTexture(skins, "models", true, false, true); outskin->skinwidth = 0; outskin->skinheight = 0; outskin->skinspeed = 0; @@ -3251,7 +3243,7 @@ void GLMod_LoadZymoticModel(model_t *mod, void *buffer) root[i].numskins = 1; skin->ofstexnums = (char *)texnums - (char *)skin; skin->texnums = 1; - texnums->base = Mod_LoadHiResTexture(shadername, true, true, true); + texnums->base = Mod_LoadHiResTexture(shadername, "models", true, true, true); } diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index c743d45e2..69b8827ea 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -1516,6 +1516,8 @@ void R_ModifyColor ( meshbuffer_t *mb, shaderpass_t *pass ) vec3_t diff, viewtofog, fog_vpn; fogplane = mb->fog->visibleplane; + if (!fogplane) + return; dist = PlaneDiff ( r_origin, fogplane ); if ( shader->flags & SHADER_SKY ) diff --git a/engine/gl/gl_draw.c b/engine/gl/gl_draw.c index 6bd824ee2..4521d81b6 100644 --- a/engine/gl/gl_draw.c +++ b/engine/gl/gl_draw.c @@ -31,10 +31,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. int glx, gly, glwidth, glheight; mesh_t draw_mesh; -vec4_t draw_mesh_xyz[4]; -vec3_t draw_mesh_normals[4]; +vec4_t draw_mesh_xyz[4]; vec2_t draw_mesh_st[4]; -vec2_t draw_mesh_lmst[4]; byte_vec4_t draw_mesh_colors[4]; qbyte *uploadmemorybuffer; @@ -236,11 +234,11 @@ qboolean Draw_RealPicFromWad (mpic_t *out, char *name) } //standard names substitution - texnum = Mod_LoadReplacementTexture(name, false, true, false); + texnum = Mod_LoadReplacementTexture(name, "wad", false, true, false); if (!in && !texnum) //try a q2 texture { sprintf(name2, "pics/%s", name); - texnum = Mod_LoadHiResTexture(name2, false, true, false); + texnum = Mod_LoadHiResTexture(name2, NULL, false, true, false); qglDisable(GL_ALPHA_TEST); qglEnable(GL_BLEND); //make sure. } @@ -365,7 +363,7 @@ mpic_t *GLDraw_SafeCachePic (char *path) { pic->pic.height = height; gl = (glpic_t *)pic->pic.data; - if (!(gl->texnum = Mod_LoadReplacementTexture(alternatename, false, true, false))) + if (!(gl->texnum = Mod_LoadReplacementTexture(alternatename, "pics", false, true, false))) gl->texnum = GL_LoadTexture32(path, pic->pic.width, pic->pic.height, (unsigned *)mem, false, false); gl->sl = 0; gl->sh = 1; @@ -406,7 +404,7 @@ mpic_t *GLDraw_SafeCachePic (char *path) if (mem) { gl = (glpic_t *)pic->pic.data; - if (!(gl->texnum = Mod_LoadReplacementTexture(alternatename, false, true, false))) + if (!(gl->texnum = Mod_LoadReplacementTexture(alternatename, NULL, false, true, false))) gl->texnum = GL_LoadTexture32(path, pic->pic.width, pic->pic.height, (unsigned *)mem, false, true); gl->sl = 0; gl->sh = 1; @@ -435,7 +433,7 @@ mpic_t *GLDraw_SafeCachePic (char *path) { pic->pic.height = height; gl = (glpic_t *)pic->pic.data; - if (!(gl->texnum = Mod_LoadReplacementTexture(alternatename, false, true, false))) + if (!(gl->texnum = Mod_LoadReplacementTexture(alternatename, NULL, false, true, false))) gl->texnum = GL_LoadTexture32(path, pic->pic.width, pic->pic.height, (unsigned *)mem, false, false); gl->sl = 0; gl->sh = 1; @@ -510,7 +508,7 @@ mpic_t *GLDraw_SafeCachePic (char *path) pic->pic.height = qpic->height; gl = (glpic_t *)pic->pic.data; - if (!(gl->texnum = Mod_LoadReplacementTexture(path, false, true, false))) + if (!(gl->texnum = Mod_LoadReplacementTexture(path, NULL, false, true, false))) gl->texnum = GL_LoadPicTexture (qpic); gl->sl = 0; gl->sh = 1; @@ -744,12 +742,12 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n")); image_width = 0; image_height = 0; TRACE(("dbg: GLDraw_ReInit: looking for conchars\n")); - if (!(char_texture=Mod_LoadReplacementTexture("gfx/conchars.lmp", false, true, false))) //no high res + if (!(char_texture=Mod_LoadReplacementTexture("gfx/conchars.lmp", NULL, false, true, false))) //no high res { if (!draw_chars) //or low res. { - if (!(char_texture=Mod_LoadHiResTexture("pics/conchars.pcx", false, true, false))) //try low res q2 path - if (!(char_texture=Mod_LoadHiResTexture("gfx/2d/bigchars.tga", false, true, false))) //try low res q2 path + if (!(char_texture=Mod_LoadHiResTexture("pics/conchars.pcx", NULL, false, true, false))) //try low res q2 path + if (!(char_texture=Mod_LoadHiResTexture("gfx/2d/bigchars.tga", NULL, false, true, false))) //try low res q2 path { //gulp... so it's come to this has it? rework the hexen2 conchars into the q1 system. @@ -911,7 +909,7 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n")); TRACE(("dbg: GLDraw_ReInit: gfx/conchars2.lmp\n")); - if (!(char_tex2=Mod_LoadReplacementTexture("gfx/conchars2.lmp", false, true, false))) + if (!(char_tex2=Mod_LoadReplacementTexture("gfx/conchars2.lmp", NULL, false, true, false))) { if (!draw_chars) char_tex2 = char_texture; @@ -996,13 +994,13 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n")); qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gl = (glpic_t *)conback->data; - if (!(gl->texnum=Mod_LoadReplacementTexture("gfx/conback.lmp", false, true, false))) + if (!(gl->texnum=Mod_LoadReplacementTexture("gfx/conback.lmp", NULL, false, true, false))) { if (!ncdata) //no fallback { - if (!(gl->texnum=Mod_LoadHiResTexture("pics/conback.pcx", false, true, false))) - if (!(gl->texnum=Mod_LoadReplacementTexture("gfx/menu/conback.lmp", false, true, false))) - if (!(gl->texnum=Mod_LoadReplacementTexture("textures/sfx/logo512.jpg", false, false, false))) + if (!(gl->texnum=Mod_LoadHiResTexture("pics/conback.pcx", NULL, false, true, false))) + if (!(gl->texnum=Mod_LoadReplacementTexture("gfx/menu/conback.lmp", NULL, false, true, false))) + if (!(gl->texnum=Mod_LoadReplacementTexture("textures/sfx/logo512.jpg", NULL, false, false, false))) { int data = 0; gl->texnum = GL_LoadTexture32("gfx/conback.lmp", 1, 1, (unsigned int *)&data, false, false); @@ -1054,7 +1052,7 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n")); if (!draw_backtile) draw_backtile = Draw_SafeCachePic ("gfx/menu/backtile.lmp"); - detailtexture = Mod_LoadReplacementTexture("textures/detail", true, false, false); + detailtexture = Mod_LoadReplacementTexture("textures/detail", NULL, true, false, false); inited15to8 = false; @@ -1087,9 +1085,9 @@ void GLDraw_Init (void) draw_mesh.numvertexes = 4; draw_mesh.xyz_array = draw_mesh_xyz; - draw_mesh.normals_array = draw_mesh_normals; + draw_mesh.normals_array = NULL; draw_mesh.st_array = draw_mesh_st; - draw_mesh.lmst_array = draw_mesh_lmst; + draw_mesh.lmst_array = NULL; } void GLDraw_DeInit (void) @@ -1287,9 +1285,7 @@ void GLDraw_Crosshair(void) if (crosshairimage.modified) { crosshairimage.modified = false; - externalhair = Mod_LoadHiResTexture (va("crosshairs/%s", crosshairimage.string), false, true, true); - if (!externalhair) - externalhair = Mod_LoadHiResTexture (crosshairimage.string, false, true, true); + externalhair = Mod_LoadHiResTexture (crosshairimage.string, "crosshairs", false, true, true); } GL_Bind (externalhair); @@ -1874,7 +1870,7 @@ void GL_Set2D (void) if (gl_font.modified) { gl_font.modified = 0; - if (!*gl_font.string || !(char_texture=Mod_LoadHiResTexture(va("fonts/%s", gl_font.string), false, true, true))) + if (!*gl_font.string || !(char_texture=Mod_LoadHiResTexture(gl_font.string, "fonts", false, true, true))) { char_texture = default_char_texture; custom_char_instep = default_char_instep; @@ -1889,7 +1885,7 @@ void GL_Set2D (void) { int newtex = 0; gl_conback.modified = 0; - if (!*gl_conback.string || !(newtex=Mod_LoadHiResTexture(va("conbacks/%s", gl_conback.string), false, true, true))) + if (!*gl_conback.string || !(newtex=Mod_LoadHiResTexture(gl_conback.string, "conbacks", false, true, true))) conback = default_conback; else { diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index a7b732e68..2a82eb43b 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -861,12 +861,12 @@ TRACE(("dbg: GLMod_LoadAdvancedTextureSection: %s\n", name)); *base = 0; *norm = 0; if (!*norm && *normname) - *norm = Mod_LoadHiResTexture(normname, true, false, false); + *norm = Mod_LoadHiResTexture(normname, NULL, true, false, false); if (!*norm && *bumpname) - *norm = Mod_LoadBumpmapTexture(bumpname); + *norm = Mod_LoadBumpmapTexture(bumpname, NULL); if (*norm && *flatname) - *base = Mod_LoadHiResTexture(flatname, true, false, true); + *base = Mod_LoadHiResTexture(flatname, NULL, true, false, true); } else { @@ -875,14 +875,14 @@ TRACE(("dbg: GLMod_LoadAdvancedTextureSection: %s\n", name)); *norm = 0; } if (!*base && *stdname) - *base = Mod_LoadHiResTexture(stdname, true, false, true); + *base = Mod_LoadHiResTexture(stdname, NULL, true, false, true); if (!*base && *flatname) - *base = Mod_LoadHiResTexture(flatname, true, false, true); + *base = Mod_LoadHiResTexture(flatname, NULL, true, false, true); if (luma && *lumaname) - *luma = Mod_LoadHiResTexture(lumaname, true, true, true); + *luma = Mod_LoadHiResTexture(lumaname, NULL, true, true, true); if (*norm && gloss && *glossname && gl_specular.value) - *gloss = Mod_LoadHiResTexture(glossname, true, false, true); + *gloss = Mod_LoadHiResTexture(glossname, NULL, true, false, true); } void GLMod_LoadAdvancedTexture(char *name, int *base, int *norm, int *luma, int *gloss, int *alphamode, qboolean *cull) //fixme: add gloss @@ -1000,8 +1000,9 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n")); base = W_ConvertWAD3Texture(mt, &mt->width, &mt->height, &alphaed); //convert texture to 32 bit. tx->alphaed = alphaed; texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; - if (!(tx->gl_texturenum = Mod_LoadReplacementTexture(mt->name, true, alphaed, true))) - tx->gl_texturenum = GL_LoadTexture32 (mt->name, tx->width, tx->height, (unsigned int *)base, true, alphaed); + if (!(tx->gl_texturenum = Mod_LoadReplacementTexture(mt->name, loadname, true, alphaed, true))) + if (!(tx->gl_texturenum = Mod_LoadReplacementTexture(mt->name, "bmodels", true, alphaed, true))) + tx->gl_texturenum = GL_LoadTexture32 (mt->name, tx->width, tx->height, (unsigned int *)base, true, alphaed); *tx->name = *mt->name; texture_mode = GL_LINEAR; @@ -1009,16 +1010,19 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n")); else { texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; - if (!(tx->gl_texturenum = Mod_LoadReplacementTexture(mt->name, true, false, true))) - tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, base, true, false); + if (!(tx->gl_texturenum = Mod_LoadReplacementTexture(mt->name, loadname, true, false, true))) + if (!(tx->gl_texturenum = Mod_LoadReplacementTexture(mt->name, "bmodels", true, false, true))) + tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, base, true, false); texture_mode = GL_LINEAR; if (r_fb_bmodels.value) { _snprintf(altname, sizeof(altname)-1, "%s_luma", mt->name); - if (gl_load24bit.value && r_fb_bmodels.value) + if (gl_load24bit.value) { - tx->gl_texturenumfb = Mod_LoadReplacementTexture(altname, true, false, true); + tx->gl_texturenumfb = Mod_LoadReplacementTexture(altname, loadname, true, false, true); + if (!tx->gl_texturenumfb) + tx->gl_texturenumfb = Mod_LoadReplacementTexture(altname, "bmodels", true, false, true); } if (!tx->gl_texturenumfb) //generate one (if possible). tx->gl_texturenumfb = GL_LoadTextureFB(altname, tx->width, tx->height, base, true, true); @@ -1032,14 +1036,18 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n")); if (gl_bump.value<2) //set to 2 to have faster loading. { _snprintf(altname, sizeof(altname)-1, "%s_norm", mt->name); - tx->gl_texturenumbumpmap = Mod_LoadHiResTexture(altname, true, false, false); + tx->gl_texturenumbumpmap = Mod_LoadHiResTexture(altname, loadname, true, false, false); + if (!tx->gl_texturenumbumpmap) + tx->gl_texturenumbumpmap = Mod_LoadHiResTexture(altname, "bmodels", true, false, false); } if (!tx->gl_texturenumbumpmap) { if (gl_load24bit.value) { _snprintf(altname, sizeof(altname)-1, "%s_bump", mt->name); - tx->gl_texturenumbumpmap = Mod_LoadBumpmapTexture(altname); + tx->gl_texturenumbumpmap = Mod_LoadBumpmapTexture(altname, loadname); + if (!tx->gl_texturenumbumpmap) + tx->gl_texturenumbumpmap = Mod_LoadBumpmapTexture(altname, "bmodels"); } else _snprintf(altname, sizeof(altname)-1, "%s_bump", mt->name); @@ -1058,7 +1066,9 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n")); if (gl_specular.value && gl_load24bit.value) { _snprintf(altname, sizeof(altname)-1, "%s_gloss", mt->name); - tx->gl_texturenumspec = Mod_LoadHiResTexture(altname, true, false, false); + tx->gl_texturenumspec = Mod_LoadHiResTexture(altname, loadname, true, false, false); + if (!tx->gl_texturenumspec) + tx->gl_texturenumspec = Mod_LoadHiResTexture(altname, "bmodels", true, false, false); } } } @@ -1208,14 +1218,17 @@ void GLMod_NowLoadExternal(void) tx->alphaed = alphaed; } - if (!(tx->gl_texturenum = Mod_LoadHiResTexture(tx->name, true, false, true))) - tx->gl_texturenum = Mod_LoadReplacementTexture("light1_4", true, false, true); + if (!(tx->gl_texturenum = Mod_LoadHiResTexture(tx->name, loadname, true, false, true))) + if (!(tx->gl_texturenum = Mod_LoadHiResTexture(tx->name, "bmodels", true, false, true))) + tx->gl_texturenum = Mod_LoadReplacementTexture("light1_4", NULL, true, false, true); //a fallback. :/ texture_mode = GL_LINEAR; } } if (!tx->gl_texturenumbumpmap && *tx->name != '{' && gl_bumpmappingpossible && cls.allow_bump) { - tx->gl_texturenumbumpmap = Mod_LoadBumpmapTexture(va("%s_bump", tx->name)); + tx->gl_texturenumbumpmap = Mod_LoadBumpmapTexture(va("%s_bump", tx->name), loadname); + if (!tx->gl_texturenumbumpmap) + tx->gl_texturenumbumpmap = Mod_LoadBumpmapTexture(va("%s_bump", tx->name), "bmodels"); if (!tx->gl_texturenumbumpmap) { qbyte *data; @@ -2824,7 +2837,7 @@ void * GLMod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum COM_StripExtension(loadmodel->name, name); strcat(name, va("_%i", framenum)); - pspriteframe->gl_texturenum = Mod_LoadReplacementTexture(name, true, true, true); + pspriteframe->gl_texturenum = Mod_LoadReplacementTexture(name, "sprites", true, true, true); if (version == SPRITE32_VERSION) { size *= 4; @@ -3023,7 +3036,7 @@ void GLMod_LoadSprite2Model (model_t *mod, void *buffer) frame = psprite->frames[i].frameptr = Hunk_AllocName(sizeof(mspriteframe_t), loadname); - frame->gl_texturenum = Mod_LoadHiResTexture(pframetype->name, true, true, true); + frame->gl_texturenum = Mod_LoadHiResTexture(pframetype->name, NULL, true, true, true); frame->width = LittleLong(pframetype->width); frame->height = LittleLong(pframetype->height); origin[0] = LittleLong (pframetype->origin_x); diff --git a/engine/gl/gl_ppl.c b/engine/gl/gl_ppl.c index 1ee001074..7aa8250f8 100644 --- a/engine/gl/gl_ppl.c +++ b/engine/gl/gl_ppl.c @@ -990,7 +990,7 @@ static void PPL_BaseChain_NPR_Sketch(msurface_t *first) r_drawflat.modified = false; for (i = 0; i < sizeof(textures)/sizeof(textures[0]); i++) { - textures[i] = Mod_LoadHiResTexture(va("sketch%i", i+1), true, false, false); + textures[i] = Mod_LoadHiResTexture(va("sketch%i", i+1), "sketch", true, false, false); if (!textures[i]) { int data[128*128]; @@ -1714,7 +1714,7 @@ void PPL_CreateLightTexturesProgram(void) char *frag = "uniform sampler2D baset;\n" - "#ifdef BUMP\n" + "#if defined(BUMP) || defined(SPECULAR)\n" "uniform sampler2D bumpt;\n" "#endif\n" "#ifdef SPECULAR\n" @@ -1736,10 +1736,12 @@ void PPL_CreateLightTexturesProgram(void) "{\n" "#ifdef BUMP\n" " vec3 bases = vec3(texture2D(baset, tcbase));\n" - " vec3 bumps = vec3(texture2D(bumpt, tcbase)) * 2.0 - 1.0;\n" "#else\n" " vec3 diff = vec3(texture2D(baset, tcbase));\n" "#endif\n" + "#if defined(BUMP) || defined(SPECULAR)\n" + " vec3 bumps = vec3(texture2D(bumpt, tcbase)) * 2.0 - 1.0;\n" + "#endif\n" "#ifdef SPECULAR\n" " vec3 specs = vec3(texture2D(speculart, tcbase));\n" "#endif\n" diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index 0f3ebccee..3ed6704b8 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -1532,7 +1532,7 @@ void R_RenderScene (void) R_Clear ============= */ -int gldepthfunc; +int gldepthfunc = GL_LEQUAL; void R_Clear (void) { if (r_mirroralpha.value != 1.0) @@ -1543,7 +1543,7 @@ void R_Clear (void) qglClear (GL_DEPTH_BUFFER_BIT); gldepthmin = 0; gldepthmax = 0.5; - qglDepthFunc (gldepthfunc=GL_LEQUAL); + gldepthfunc=GL_LEQUAL; } #ifdef SIDEVIEWS else if (gl_ztrick.value && !gl_ztrickdisabled) @@ -1561,13 +1561,13 @@ void R_Clear (void) { gldepthmin = 0; gldepthmax = 0.49999; - qglDepthFunc (gldepthfunc=GL_LEQUAL); + gldepthfunc=GL_LEQUAL; } else { gldepthmin = 1; gldepthmax = 0.5; - qglDepthFunc (gldepthfunc=GL_GEQUAL); + gldepthfunc=GL_GEQUAL; } } else @@ -1578,9 +1578,10 @@ void R_Clear (void) qglClear (GL_DEPTH_BUFFER_BIT); gldepthmin = 0; gldepthmax = 1; - qglDepthFunc (gldepthfunc=GL_GEQUAL); + gldepthfunc=GL_LEQUAL; } + qglDepthFunc (gldepthfunc); qglDepthRange (gldepthmin, gldepthmax); } @@ -1873,6 +1874,9 @@ void GLR_RenderView (void) extern msurface_t *r_alpha_surfaces; double time1 = 0, time2; + if (qglGetError()) + Con_Printf("GL Error before drawing scene\n"); + if (r_norefresh.value || !glwidth || !glheight) { GL_DoSwap(); @@ -2004,6 +2008,9 @@ void GLR_RenderView (void) // Con_Printf ("%3i ms %4i wpoly %4i epoly\n", (int)((time2-time1)*1000), c_brush_polys, c_alias_polys); } + if (qglGetError()) + Con_Printf("GL Error drawing scene\n"); + if (!scenepp_ww_program) return; @@ -2024,9 +2031,6 @@ void GLR_RenderView (void) vheight *= 2; } - if (qglGetError()) - Con_Printf("GL Error before drawing with shaderobjects\n"); - // get the maxtexcoords while we're at it vs = glwidth / vwidth; vt = glheight / vheight; diff --git a/engine/gl/gl_rmisc.c b/engine/gl/gl_rmisc.c index fc0a88c10..40971091e 100644 --- a/engine/gl/gl_rmisc.c +++ b/engine/gl/gl_rmisc.c @@ -942,8 +942,10 @@ R_NewMap */ void GLR_NewMap (void) { + char namebuf[MAX_QPATH]; extern cvar_t host_mapname; int i; + /* if (cl.worldmodel->fromgame == fg_quake3 && cls.netchan.remote_address.type != NA_LOOPBACK) { @@ -965,7 +967,9 @@ void GLR_NewMap (void) VectorInverse(r_worldentity.axis[1]); r_worldentity.model = cl.worldmodel; - Cvar_Set(&host_mapname, cl.worldmodel->name); + + COM_StripExtension(COM_SkipPath(cl.worldmodel->name), namebuf); + Cvar_Set(&host_mapname, namebuf); // clear out efrags in case the level hasn't been reloaded // FIXME: is this one short? diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index 8f6a4623c..9a0e4bf09 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -281,7 +281,7 @@ static void Shader_ParseSkySides ( char **ptr, int *images ) images[i] = 0; } else { Com_sprintf ( path, sizeof(path), "%s_%s", token, suf[i] ); - images[i] = Mod_LoadHiResTexture ( path, true, false, true);//|IT_SKY ); + images[i] = Mod_LoadHiResTexture ( path, NULL, true, false, true);//|IT_SKY ); } } } @@ -342,7 +342,7 @@ static int Shader_FindImage ( char *name, int flags ) if ( !Q_stricmp (name, "$whiteimage") ) { return 0; } else { - return Mod_LoadHiResTexture(name, !!(flags & IT_NOMIPMAP), true, true);//GL_FindImage ( name, flags ); + return Mod_LoadHiResTexture(name, NULL, !!(flags & IT_NOMIPMAP), true, true);//GL_FindImage ( name, flags ); } } @@ -896,7 +896,6 @@ static shaderkey_t shaderpasskeys[] = int Shader_InitCallback (char *name, int size, void *param) { - name+=8; //skip the scripts/ part strcpy(shaderbuf+shaderbuflen, name); Shader_MakeCache(shaderbuf+shaderbuflen); shaderbuflen += strlen(name)+1; @@ -947,7 +946,7 @@ static void Shader_MakeCache ( char *path ) shadercache_t *cache; int size; - Com_sprintf( filename, sizeof(filename), "scripts/%s", path ); + Com_sprintf( filename, sizeof(filename), "%s", path ); Con_DPrintf ( "...loading '%s'\n", filename ); size = FS_LoadFile ( filename, (void **)&buf ); @@ -1722,7 +1721,7 @@ void Shader_DefaultBSP(char *shortname, shader_t *s) pass = &s->passes[1]; pass->flags = SHADER_PASS_BLEND | SHADER_PASS_NOCOLORARRAY; pass->tcgen = TC_GEN_BASE; - pass->anim_frames[0] = Mod_LoadHiResTexture(shortname, true, false, true);//GL_FindImage (shortname, 0); + pass->anim_frames[0] = Mod_LoadHiResTexture(shortname, NULL, true, false, true);//GL_FindImage (shortname, 0); pass->blendsrc = GL_ZERO; pass->blenddst = GL_SRC_COLOR; pass->blendmode = GL_MODULATE; @@ -1751,7 +1750,7 @@ void Shader_DefaultBSPVertex(char *shortname, shader_t *s) shaderpass_t *pass; pass = &s->passes[0]; pass->tcgen = TC_GEN_BASE; - pass->anim_frames[0] = Mod_LoadHiResTexture(shortname, true, false, true);//GL_FindImage (shortname, 0); + pass->anim_frames[0] = Mod_LoadHiResTexture(shortname, NULL, true, false, true);//GL_FindImage (shortname, 0); pass->depthfunc = GL_LEQUAL; pass->flags = SHADER_PASS_DEPTHWRITE; pass->rgbgen = RGB_GEN_VERTEX; @@ -1780,7 +1779,7 @@ void Shader_DefaultBSPFlare(char *shortname, shader_t *s) pass->blendsrc = GL_ONE; pass->blenddst = GL_ONE; pass->blendmode = GL_MODULATE; - pass->anim_frames[0] = Mod_LoadHiResTexture(shortname, true, true, true);//GL_FindImage (shortname, 0); + pass->anim_frames[0] = Mod_LoadHiResTexture(shortname, NULL, true, true, true);//GL_FindImage (shortname, 0); pass->depthfunc = GL_LEQUAL; pass->rgbgen = RGB_GEN_VERTEX; pass->alphagen = ALPHA_GEN_IDENTITY; @@ -1806,7 +1805,7 @@ void Shader_DefaultSkin(char *shortname, shader_t *s) shaderpass_t *pass; pass = &s->passes[0]; pass->flags = SHADER_PASS_DEPTHWRITE; - pass->anim_frames[0] = Mod_LoadHiResTexture(shortname, true, true, true);//GL_FindImage (shortname, 0); + pass->anim_frames[0] = Mod_LoadHiResTexture(shortname, NULL, true, true, true);//GL_FindImage (shortname, 0); pass->depthfunc = GL_LEQUAL; pass->rgbgen = RGB_GEN_LIGHTING_DIFFUSE; pass->numtcmods = 0; @@ -1832,7 +1831,7 @@ void Shader_DefaultSkinShell(char *shortname, shader_t *s) shaderpass_t *pass; pass = &s->passes[0]; pass->flags = SHADER_PASS_DEPTHWRITE | SHADER_PASS_BLEND; - pass->anim_frames[0] = Mod_LoadHiResTexture(shortname, true, true, true);//GL_FindImage (shortname, 0); + pass->anim_frames[0] = Mod_LoadHiResTexture(shortname, NULL, true, true, true);//GL_FindImage (shortname, 0); pass->depthfunc = GL_LEQUAL; pass->rgbgen = RGB_GEN_ENTITY; pass->alphagen = ALPHA_GEN_ENTITY; @@ -1864,7 +1863,7 @@ void Shader_Default2D(char *shortname, shader_t *s) pass->blendsrc = GL_SRC_ALPHA; pass->blenddst = GL_ONE_MINUS_SRC_ALPHA; pass->blendmode = GL_MODULATE; - pass->anim_frames[0] = Mod_LoadHiResTexture(shortname, false, true, true);//GL_FindImage (shortname, IT_NOPICMIP|IT_NOMIPMAP); + pass->anim_frames[0] = Mod_LoadHiResTexture(shortname, NULL, false, true, true);//GL_FindImage (shortname, IT_NOPICMIP|IT_NOMIPMAP); pass->depthfunc = GL_LEQUAL; pass->rgbgen = RGB_GEN_VERTEX; pass->alphagen = ALPHA_GEN_VERTEX; @@ -1927,7 +1926,7 @@ int R_LoadShader ( char *name, void(*defaultgen)(char *name, shader_t*)) Shader_GetPathAndOffset( shortname, &ts, &offset ); if ( ts ) { - Com_sprintf ( path, sizeof(path), "scripts/%s", ts ); + Com_sprintf ( path, sizeof(path), "%s", ts ); length = FS_LoadFile ( path, (void **)&buf ); } diff --git a/engine/gl/gl_vidnt.c b/engine/gl/gl_vidnt.c index a542603ff..b10bcde68 100644 --- a/engine/gl/gl_vidnt.c +++ b/engine/gl/gl_vidnt.c @@ -209,16 +209,36 @@ qboolean GLInitialise (char *renderer) strcpy(opengldllname, renderer); - Con_Printf ("Loading renderer dll %s\n", renderer); - hInstGL = LoadLibrary(opengldllname); + if (*renderer) + { + Con_DPrintf ("Loading renderer dll \"%s\"", renderer); + hInstGL = LoadLibrary(opengldllname); + + if (hInstGL) + Con_DPrintf (" Success\n"); + else + Con_DPrintf (" Failed\n"); + } + else + hInstGL = NULL; if (!hInstGL) { - hInstGL = LoadLibrary("opengl32"); + strcpy(opengldllname, "opengl32"); + Con_DPrintf ("Loading renderer dll \"%s\"", opengldllname); + hInstGL = LoadLibrary(opengldllname); + + if (hInstGL) + Con_DPrintf (" Success\n"); + else + Con_DPrintf (" Failed\n"); } if (!hInstGL) { - Con_Printf ("Couldn't load %s\n", opengldllname); + if (*renderer) + Con_Printf ("Couldn't load %s or %s\n", renderer, opengldllname); + else + Con_Printf ("Couldn't load %s\n", opengldllname); return false; } diff --git a/engine/gl/gl_warp.c b/engine/gl/gl_warp.c index 7a3d7b8cb..1a4fd8f24 100644 --- a/engine/gl/gl_warp.c +++ b/engine/gl/gl_warp.c @@ -265,13 +265,26 @@ void R_DrawSkyChain (msurface_t *s) R_LoadSkys ================== */ -static char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"}; +static char *skyname_suffix[][6] = { + {"px", "py", "nx", "ny", "pz", "nz"}, + {"posx", "posy", "negx", "negy", "posz", "negz"}, + {"rt", "bk", "lf", "ft", "up", "dn"} +}; + +static char *skyname_pattern[] = { + "%s_%s", + "%s%s", + "env/%s%s", + "gfx/env/%s%s" +}; + int skyboxtex[6]; void R_LoadSkys (void) { int i; char name[MAX_QPATH]; char *boxname; + int p, s; if (*gl_skyboxname.string) boxname = gl_skyboxname.string; //user forced @@ -288,10 +301,15 @@ void R_LoadSkys (void) for(;;) { for (i=0 ; i<6 ; i++) - { - _snprintf (name, sizeof(name), "env/%s%s.tga", boxname, suf[i]); - - skyboxtex[i] = Mod_LoadHiResTexture(name, false, false, true); + { + for (p = 0; p < sizeof(skyname_pattern)/sizeof(skyname_pattern[0]); p++) + { + for (s = 0; s < sizeof(skyname_suffix)/sizeof(skyname_suffix[0]); s++) + { + _snprintf (name, sizeof(name), skyname_pattern[p], boxname, skyname_suffix[s][i]); + skyboxtex[i] = Mod_LoadHiResTexture(name, NULL, false, false, true); + } + } if (!skyboxtex[i]) break; @@ -876,7 +894,7 @@ void GLR_InitSky (texture_t *mt) sprintf(name, "%s_solid", mt->name); Q_strlwr(name); - solidskytexture = Mod_LoadReplacementTexture(name, true, false, true); + solidskytexture = Mod_LoadReplacementTexture(name, NULL, true, false, true); if (!solidskytexture) solidskytexture = GL_LoadTexture32(name, 128, 128, trans, true, false); /* @@ -901,7 +919,7 @@ void GLR_InitSky (texture_t *mt) sprintf(name, "%s_trans", mt->name); Q_strlwr(name); - alphaskytexture = Mod_LoadReplacementTexture(name, true, true, true); + alphaskytexture = Mod_LoadReplacementTexture(name, NULL, true, true, true); if (!alphaskytexture) alphaskytexture = GL_LoadTexture32(name, 128, 128, trans, true, true); /* diff --git a/engine/gl/glmod_doom.c b/engine/gl/glmod_doom.c index 87870a2ef..62dfa29a7 100644 --- a/engine/gl/glmod_doom.c +++ b/engine/gl/glmod_doom.c @@ -275,7 +275,7 @@ int Doom_LoadFlat(char *name) sprintf(texname, "flat-%-.8s", name); Q_strlwr(texname); - tex = Mod_LoadReplacementTexture(texname, true, false, true); + tex = Mod_LoadReplacementTexture(texname, "flats", true, false, true); if (tex) return tex; @@ -1173,7 +1173,7 @@ static int Doom_LoadPatch(char *name) return texnum; } //all else failed. - gldoomtextures[texnum].gltexture = Mod_LoadHiResTexture(name, true, false, true); + gldoomtextures[texnum].gltexture = Mod_LoadHiResTexture(name, "patches", true, false, true); gldoomtextures[texnum].width = image_width; gldoomtextures[texnum].height = image_height; return texnum; diff --git a/engine/gl/glquake.h b/engine/gl/glquake.h index 77146ca6a..cf6486d8f 100644 --- a/engine/gl/glquake.h +++ b/engine/gl/glquake.h @@ -321,10 +321,10 @@ void R_DrawWorld (void); void GL_BuildLightmaps (void); void GL_LoadShaders(void); -int Mod_LoadReplacementTexture(char *name, qboolean mipmap, qboolean alpha, qboolean gammaadjust); +int Mod_LoadReplacementTexture(char *name, char *subpath, qboolean mipmap, qboolean alpha, qboolean gammaadjust); extern int image_width, image_height; -int Mod_LoadHiResTexture(char *name, qboolean mipmap, qboolean alpha, qboolean gammaadjust); -int Mod_LoadBumpmapTexture(char *name); +int Mod_LoadHiResTexture(char *name, char *subpath, qboolean mipmap, qboolean alpha, qboolean gammaadjust); +int Mod_LoadBumpmapTexture(char *name, char *subpath); #define LMBLOCK_WIDTH 128 #define LMBLOCK_HEIGHT 128 diff --git a/engine/libs/libmad/CHANGES b/engine/libs/libmad/CHANGES deleted file mode 100644 index 3fa57ef0c..000000000 --- a/engine/libs/libmad/CHANGES +++ /dev/null @@ -1,338 +0,0 @@ - - libmad - MPEG audio decoder library - Copyright (C) 2000-2004 Underbit Technologies, Inc. - - $Id$ - -=============================================================================== - -Version 0.15.1 (beta) - - * Updated to autoconf 2.59, automake 1.8.2, libtool 1.5.2. - - * Replaced Layer III IMDCT routine with one based on a faster algorithm, - improving both speed and accuracy. - - * Improved portability of the Huffman table initialization. - - * Fixed a problem that could result in an assertion failure in layer3.c - due to an invalid Layer III free format bitrate. - - * Improved the robustness of Layer II bitrate/mode combinations, and added - a new MAD_ERROR_BADMODE error enum. The allowability of low-bitrate - stereo streams is influenced by the --enable-strict-iso option to - `configure'. - -Version 0.15.0 (beta) - - * Updated to autoconf 2.57, automake 1.7.5, libtool 1.4.3. - - * Added new mad_f_div() API routine. - - * Added a 64th entry to the Layer I/Layer II scalefactor table, for better - compatibility with existing streams. The --enable-strict-iso option to - `configure' can be used to disable use of this entry. - - * Modified the header decoding routine to allow the reserved emphasis - value, for better compatibility with existing streams. The - --enable-strict-iso option to `configure' can be used to restore the - previous behavior of reporting this value as an error. - - * Added new MAD_EMPHASIS_RESERVED enumeration constant. - - * Fixed a bug in the ARM version of mad_f_scale64() discovered by Andre - McCurdy. - - * Rewrote PowerPC assembly for minor gains. - - * Modified mad_timer_fraction() to avoid the possibility of division by - zero when 0 is passed as the second argument. - - * Fixed a non-fatal problem caused by attempting to designate ancillary - bits in Layer III after a decoding error. - - * Changed to build a shared library by default. - - * Changed to use native Cygwin build by default; give --host=mingw32 to - `configure' to use MinGW (and avoid a dependency on the Cygwin DLL). - -Version 0.14.2 (beta) - - * Changed Cygwin builds to use MinGW; resulting Win32 executables no - longer have a dependency on Cygwin DLLs. - - * Added a new mad_stream_errorstr() API function to libmad for retrieving - a string description of the current error condition. - -Version 0.14.1 (beta) - - * Updated config.guess and config.sub to latest upstream versions. - - * Enabled libtool versioning rather than release numbering. - - * Improved the documentation in minimad.c. - - * Several other small fixes. - -Version 0.14.0 (beta) - - * Added a 64-bit FPM negation operation to improve performance of subband - synthesis on some platforms. - - * Improved MSVC++ portability and added MSVC++ project files. - - * Added rounding to Layer III requantization for slightly better accuracy. - -Version 0.13.0 (beta) - - * Ancillary data is now properly extracted from Layer III streams. - - * Rewrote the Layer III joint stereo decoding routine to correct a major - MPEG-2 problem and a minor MPEG-1 problem decoding intensity stereo. - - * Eliminated the dependency on sign-extending right shifts for Layer I and - Layer II. - - * Renamed `private' field to `private_bits' for better C++ compatibility. - - * Gratuitously renamed `sfreq' field to `samplerate' and - MAD_ERROR_BADSAMPLEFREQ constant to MAD_ERROR_BADSAMPLERATE. - - * Added `samplerate' and `channels' fields to synth.pcm struct to allow - these to be different from the decoded frame, and for simpler access. - - * Added new mad_stream_options() and mad_decoder_options() API entries for - special runtime decoding options. - - * Added new MAD_OPTION_IGNORECRC and MAD_OPTION_HALFSAMPLERATE options. - - * Added new MAD_FLAG_FREEFORMAT indicator flag. - - * Fixed some bugs in the async decoder. - - * Added a new mad_timer_multiply() API routine. - - * Eliminated `+' from asm constraints under Intel for better compatibility - with some compilers. - - * Fixed a PIC-related problem in imdct_l_arm.S. - - * Eliminated a static variable to make libmad thread-safe. - -Version 0.12.5 (beta) - - * Modified Layer III requantization to occur during Huffman decoding for - significant performance gains. - - * Optimized short block IMDCT by eliminating redundant calculations. - - * Made several other Layer III performance improvements; added - ASO_INTERLEAVE1, ASO_INTERLEAVE2, and ASO_ZEROCHECK - architecture-specific options for best performance on various - architectures. - - * Optimized synthesis DCT to store result values as soon as they are - calculated. - -Version 0.12.4 (beta) - - * New PowerPC fixed-point assembly courtesy of David Blythe. - - * Reorganized fixed-point assembly routines for easier maintenance and - better performance. - - * Improved performance of subband synthesis through better indexing and - fewer local variables. - - * Added alias reduction for the lower two subbands of mixed short blocks, - per a report of ambiguity with ISO/IEC 11172-3 and for uniformity with - most other implementations. Also improved alias reduction performance - using multiply/accumulate. - - * Added --enable-strict-iso option to `configure' to override best - accepted practices such as the alias reduction for mixed short blocks. - - * Improved performance of Layer III IMDCT by using longer - multiply/accumulate runs where possible. - -Version 0.12.3 (beta) - - * Added MPEG 2.5 support. - - * Added preliminary support for parameterizing the binary point position - in the fixed-point representation. - - * Added multiply/accumulate optimization to the Layer III IMDCT for long - blocks. - - * Fixed a bug in the handling of Layer III mixed_block_flag. - - * Fixed a configure problem when multiple -O CFLAGS are present. - -Version 0.12.2 (beta) - - * Rearranged the synthesis polyphase filterbank memory vector for better - locality of reference, and rewrote mad_synth_frame() to accommodate, - resulting in improved performance. - - * Discovered a combination of compiler optimization flags that further - improve performance. - - * Changed some array references in layer3.c to pointer derefs. - -Version 0.12.1 (beta) - - * Resolved the intensity + MS joint stereo issue (a simple bug). - OPT_ISKLUGE is no longer considered to be a kluge. - - * Fixed another, hopefully last main_data memory bug. - - * Split part of struct mad_frame into struct mad_header for convenience - and size. - -Version 0.12.0 (alpha) - - * Changed the build environment to use automake and libtool. A libmad - shared library can now be built using the --enable-shared option to - `configure'. - - * Added another callback to MAD's high-level decoder API after the frame - header has been read but before the frame's audio data is decoded. - - * Streamlined header processing so that mad_frame_decode() can be called - with or without having already called mad_frame_header(). - - * Fixed some other header reading miscellany, including CRC handling and - free bitrate detection, and frame length verification with free - bitrates. - - * Fixed a problem with Layer III free bitrates > 320 kbps. The main_data - buffer size should now be large enough to handle any size frame, by - virtue of the maximum possible part2_3_length. - - * Further developed the async API; arbitrary messages can now be passed to - the subsidiary decoding process. - - * Streamlined timer.c and extended its interface. It now has support for - video frame/field lengths, including output support for drop-frame - encoding. - - * Replaced many constant integer preprocessor defines with enums. - -Version 0.11.4 (beta) - - * Fixed free format bitrate discovery. - - * Changed the timer implementation and extended its interface. - - * Integrated Nicolas Pitre's patch for pre-shifting at compile-time and - for better multiply/accumulate code output. - - * Applied Simon Burge's patch to imdct_l_arm.S for a.out compatibility. - - * Added -mtune=strongarm for all ARM targets. - -Version 0.11.3 (beta) - - * Added new --enable-speed and --enable-accuracy options for `configure' - to automatically select appropriate SSO/ASO options, et al. - - * Modified subband synthesis to use multiply/accumulate optimization (if - available) for better speed and/or accuracy. - - * Incorporated Andre McCurdy's changes for further rounding optimizations - in the rest of his code. - -Version 0.11.2 (beta) - - * Incorporated Nicolas Pitre's ARM assembly and parameterized scaling - changes. - - * Incorporated Andre McCurdy's ARM assembly optimization (used only if - --enable-aso is given to `configure' to enable architecture-specific - optimizations.) - - * Reduced FPM_INTEL assembly to two instructions. - - * Fixed accuracy problems with certain FPM modes in synth.c. - - * Improved the accuracy of FPM_APPROX. - - * Improved the accuracy of SSO. - - * Improved sync discovery by checking for a sync word in the following - frame. - - * Minor code clean-up. - - * Added experimental rules for generating a libmad.so shared library. - -Version 0.11.1 (beta) - - * Moved libmad code into a separate directory. - - * Changed SSO to be disabled by default, as output accuracy is deemed to - be more important than speed in the general case. - - * Fixed a bug in Layer III sanity checking that could cause a crash on - certain random data input. - - * Extended the Layer III requantization table from 8191 to 8206 as some - encoders are known to use these values, even though ISO/IEC 11172-3 - suggests the maximum should be 8191. - -Version 0.11.0 (beta) - - * Implemented MPEG-2 extension to Lower Sampling Frequencies. - - * Improved Layer III performance by avoiding IMDCT calculation when all - input samples are zero. - - * Significantly reduced size of Layer II tables. - -Version 0.10.3 (beta) - - * Improved SSO output quality. - - * Made portable to cygwin. - - * Localized memory references in III_huffdecode() for better performance. - -Version 0.10.2 (beta) - - * Rewrote Layer III long block 36-point IMDCT routine for better - performance. - - * Improved subband synthesis fixed-point games somewhat. - -Version 0.10.1 (beta) - - * Added a subband synthesis optimization (SSO) which involves modifying - the fixed-point multiplication method during windowing. This produces - subtle differences in the output but improves performance greatly. - - * Added I_STEREO and MS_STEREO flags to frame struct. - - * Eliminated privately-used CRCFAILED flag. - - * Fixed a bug where Layer III decoding could crash on some badly-formatted - (e.g. non-MPEG) bitstreams. - - * Miscellaneous code clean-up. - -Version 0.10.0 (beta) - - * Added SPARC fixed-point math support. - - * Revamped libmad API for better high- and low-level support. - - * Documented more of the code. - - * Changed sync semantics such that new stream buffers are assumed to be - sync-aligned. - - * Changed Layer III to dynamically allocate static memory so as not to - waste it (about 6.4K) when only decoding Layer I or Layer II. - -=============================================================================== - diff --git a/engine/qclib/qccgui.c b/engine/qclib/qccgui.c index 67055c05e..14b182b44 100644 --- a/engine/qclib/qccgui.c +++ b/engine/qclib/qccgui.c @@ -1503,7 +1503,7 @@ static LONG CALLBACK MainWndProc(HWND hWnd,UINT message, if (projecttree) { gotodefbox = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", (LPCTSTR) NULL, - WS_CHILD | WS_CLIPCHILDREN | ES_WANTRETURN, + WS_CHILD | WS_CLIPCHILDREN, 0, 0, 320, 200, hWnd, (HMENU) 0xCAC, ghInstance, (LPSTR) NULL); ShowWindow(gotodefbox, SW_SHOW); diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index e6d429dfe..a722bafd8 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -1783,10 +1783,13 @@ void PF_setmodel (progfuncs_t *prinst, struct globalvars_s *pr_globals) if (m[0] == '*' || (*m&&progstype == PROG_H2)) { mod = Mod_ForName (m, true); - VectorCopy (mod->mins, e->v->mins); - VectorCopy (mod->maxs, e->v->maxs); - VectorSubtract (mod->maxs, mod->mins, e->v->size); - SV_LinkEdict (e, false); + if (mod) + { + VectorCopy (mod->mins, e->v->mins); + VectorCopy (mod->maxs, e->v->maxs); + VectorSubtract (mod->maxs, mod->mins, e->v->size); + SV_LinkEdict (e, false); + } return; } @@ -1815,10 +1818,13 @@ void PF_setmodel (progfuncs_t *prinst, struct globalvars_s *pr_globals) if (mod) { mod = Mod_ForName (m, false); - VectorCopy (mod->mins, e->v->mins); - VectorCopy (mod->maxs, e->v->maxs); - VectorSubtract (mod->maxs, mod->mins, e->v->size); - SV_LinkEdict (e, false); + if (mod) + { + VectorCopy (mod->mins, e->v->mins); + VectorCopy (mod->maxs, e->v->maxs); + VectorSubtract (mod->maxs, mod->mins, e->v->size); + SV_LinkEdict (e, false); + } } else { @@ -1841,10 +1847,13 @@ void PF_setmodel (progfuncs_t *prinst, struct globalvars_s *pr_globals) if (sv.models[i]) { mod = Mod_ForName (m, false); - VectorCopy (mod->mins, e->v->mins); - VectorCopy (mod->maxs, e->v->maxs); - VectorSubtract (mod->maxs, mod->mins, e->v->size); - SV_LinkEdict (e, false); + if (mod) + { + VectorCopy (mod->mins, e->v->mins); + VectorCopy (mod->maxs, e->v->maxs); + VectorSubtract (mod->maxs, mod->mins, e->v->size); + SV_LinkEdict (e, false); + } } //qw was fixed - it never sets the size of an alias model. } @@ -3002,9 +3011,9 @@ void PF_localcmd (progfuncs_t *prinst, struct globalvars_s *pr_globals) str = PR_GetStringOfs(prinst, OFS_PARM0); if (!strcmp(str, "host_framerate 0\n")) - Cbuf_AddText ("sv_mintic 0\n", RESTRICT_SERVER); //hmm... do this better... + Cbuf_AddText ("sv_mintic 0\n", RESTRICT_INSECURE); //hmm... do this better... else - Cbuf_AddText (str, RESTRICT_SERVER); + Cbuf_AddText (str, RESTRICT_INSECURE); } /* diff --git a/engine/server/sv_ents.c b/engine/server/sv_ents.c index 643a6f5a5..dd49bf2c1 100644 --- a/engine/server/sv_ents.c +++ b/engine/server/sv_ents.c @@ -111,8 +111,8 @@ int numlight; extern int sv_lightningmodel; #endif -edict_t *csqcent[MAX_EDICTS]; -int csqcnuments; +static edict_t *csqcent[MAX_EDICTS]; +static int csqcnuments; qboolean SV_AddNailUpdate (edict_t *ent) { diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 451fc08d6..2c8c04711 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -47,9 +47,14 @@ netadr_t master_adr[MAX_MASTERS]; // address of group servers client_t *host_client; // current client -cvar_t sv_mintic = {"sv_mintic","0.03"}; // bound the size of the -cvar_t sv_maxtic = {"sv_maxtic","0.1"}; // physics time tic -cvar_t sv_nailhack = {"sv_nailhack","0"}; // physics time tic +// bound the size of the physics time tic +#ifdef SERVERONLY +cvar_t sv_mintic = {"sv_mintic","0.03"}; +#else +cvar_t sv_mintic = {"sv_mintic","0"}; //client builds can think as often as they want. +#endif +cvar_t sv_maxtic = {"sv_maxtic","0.1"}; +cvar_t sv_nailhack = {"sv_nailhack","0"}; cvar_t timeout = {"timeout","65"}; // seconds without any message diff --git a/engine/server/sv_mvd.c b/engine/server/sv_mvd.c index 2c8259f08..b257f3a20 100644 --- a/engine/server/sv_mvd.c +++ b/engine/server/sv_mvd.c @@ -22,8 +22,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef CLIENTONLY #include "winquake.h" -#define Q_strncatz strncat - void SV_MVDStop_f (void); #define demo_size_padding 0x1000 @@ -1931,9 +1929,7 @@ void SV_MVDEasyRecord_f (void) int MVD_StreamStartListening(int port) { - char name[256]; int sock; - struct hostent *hent; struct sockaddr_in address; // int fromlen; diff --git a/engine/server/sv_sys_win.c b/engine/server/sv_sys_win.c index 3607e4539..2a7c26f4f 100644 --- a/engine/server/sv_sys_win.c +++ b/engine/server/sv_sys_win.c @@ -637,7 +637,7 @@ void StartQuakeServer(void) parms.argc = com_argc; parms.argv = com_argv; - parms.memsize = 12*1024*1024; + parms.memsize = 32*1024*1024; if ((t = COM_CheckParm ("-heapsize")) != 0 && t + 1 < com_argc) diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index 557f8efe8..de32c1573 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -3826,6 +3826,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse) if (progstype == PROG_H2) sv_player->v->light_level = 128; //hmm... HACK!!! + sv_player->v->Version++; sv_player->v->button0 = ucmd->buttons & 1; sv_player->v->button2 = (ucmd->buttons >> 1) & 1; if (pr_allowbutton1.value) //many mods use button1 - it's just a wasted field to many mods. So only work it if the cvar allows.