mirror of
https://github.com/nzp-team/fteqw.git
synced 2025-01-19 15:01:13 +00:00
qccgui: reworked compile prints to split the screen instead of being some other window that's hidden when fullscreened etc.
splitscreen: split spectator setting into a per-seat setting. scoreboards are now also per-seat. added parm_string global for richer map change stuff. dpp7: fixed and reinstated. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5110 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
0fad8fe37d
commit
025aeff8a4
50 changed files with 1150 additions and 813 deletions
|
@ -520,7 +520,7 @@ static float vlen(vec3_t v)
|
|||
// returns true if weapon model should be drawn in camera mode
|
||||
qboolean Cam_DrawViewModel(playerview_t *pv)
|
||||
{
|
||||
if (cl.spectator)
|
||||
if (pv->spectator)
|
||||
{
|
||||
if (pv->cam_state == CAM_EYECAM && cl_chasecam.ival)
|
||||
return true;
|
||||
|
@ -536,7 +536,7 @@ qboolean Cam_DrawViewModel(playerview_t *pv)
|
|||
|
||||
int Cam_TrackNum(playerview_t *pv)
|
||||
{
|
||||
if (cl.spectator && pv->cam_state == CAM_EYECAM)
|
||||
if (pv->spectator && pv->cam_state == CAM_EYECAM)
|
||||
return pv->cam_spec_track;
|
||||
return -1;
|
||||
}
|
||||
|
@ -822,7 +822,7 @@ void Cam_Track(playerview_t *pv, usercmd_t *cmd)
|
|||
vec3_t vec;
|
||||
float len;
|
||||
|
||||
if (!cl.spectator || !cl.worldmodel) //can happen when the server changes level
|
||||
if (!pv->spectator || !cl.worldmodel) //can happen when the server changes level
|
||||
return;
|
||||
|
||||
if (autotrackmode != TM_USER && pv->cam_state == CAM_FREECAM)
|
||||
|
@ -976,7 +976,7 @@ void Cam_FinishMove(playerview_t *pv, usercmd_t *cmd)
|
|||
if (cls.state != ca_active)
|
||||
return;
|
||||
|
||||
if (!cl.spectator && (cls.demoplayback != DPB_MVD && cls.demoplayback != DPB_EZTV)) // only in spectator mode
|
||||
if (!pv->spectator && (cls.demoplayback != DPB_MVD && cls.demoplayback != DPB_EZTV)) // only in spectator mode
|
||||
return;
|
||||
|
||||
if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
|
||||
|
@ -1197,7 +1197,7 @@ void Cam_TrackPlayer(int seat, char *cmdname, char *plrarg)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!cl.spectator)
|
||||
if (!pv->spectator)
|
||||
{
|
||||
Con_Printf("Not spectating.\n");
|
||||
return;
|
||||
|
|
|
@ -1159,7 +1159,7 @@ static void CLQW_RecordServerData(sizebuf_t *buf)
|
|||
if (cls.fteprotocolextensions2 & PEXT2_MAXPLAYERS)
|
||||
{
|
||||
MSG_WriteByte (buf, cl.allocated_client_slots);
|
||||
MSG_WriteByte (buf, cl.splitclients | (cl.spectator?128:0));
|
||||
MSG_WriteByte (buf, cl.splitclients);
|
||||
for (i = 0; i < cl.splitclients; i++)
|
||||
MSG_WriteByte (buf, cl.playerview[i].playernum);
|
||||
}
|
||||
|
@ -1167,7 +1167,7 @@ static void CLQW_RecordServerData(sizebuf_t *buf)
|
|||
{
|
||||
for (i = 0; i < cl.splitclients; i++)
|
||||
{
|
||||
if (cl.spectator)
|
||||
if (cl.playerview[i].spectator)
|
||||
MSG_WriteByte (buf, cl.playerview[i].playernum | 128);
|
||||
else
|
||||
MSG_WriteByte (buf, cl.playerview[i].playernum);
|
||||
|
@ -1544,7 +1544,7 @@ void CL_Record_f (void)
|
|||
}
|
||||
else
|
||||
{ //automagically generate a name
|
||||
if (cl.spectator)
|
||||
if (cl.playerview[0].spectator)
|
||||
{ // FIXME: if tracking a player, use his name
|
||||
fname = va ("spec_%s_%s",
|
||||
TP_PlayerName(),
|
||||
|
|
|
@ -1658,7 +1658,8 @@ void CLDP_ParseDarkPlaces5Entities(void) //the things I do.. :o(
|
|||
}
|
||||
else
|
||||
{
|
||||
// Con_Printf("Update %i\n", read);
|
||||
if (cl_shownet.ival > 3)
|
||||
Con_Printf("Update %i\n", read);
|
||||
DP5_ParseDelta(to, newpack);
|
||||
to->sequence = cls.netchan.incoming_sequence;
|
||||
to->inactiveflag = 0;
|
||||
|
@ -3780,6 +3781,7 @@ void CL_LinkPacketEntities (void)
|
|||
le = &cl.lerpents[timer->entnum];
|
||||
if (le->sequence != cl.lerpentssequence)
|
||||
continue;
|
||||
// VectorCopy(le->origin, timer->origin);
|
||||
}
|
||||
R_AddItemTimer(timer->origin, cl.time*90 + timer->origin[0] + timer->origin[1] + timer->origin[2], timer->radius, (cl.time - timer->start) / timer->duration, timer->rgb);
|
||||
}
|
||||
|
@ -4716,7 +4718,7 @@ guess_pm_type:
|
|||
for (i = 0; i < cl.splitclients; i++)
|
||||
{
|
||||
playerview_t *pv = &cl.playerview[i];
|
||||
if ((cl.spectator?pv->cam_spec_track:pv->playernum) == num)
|
||||
if ((pv->spectator?pv->cam_spec_track:pv->playernum) == num)
|
||||
{
|
||||
pv->stats[STAT_WEAPONFRAME] = state->weaponframe;
|
||||
pv->statsf[STAT_WEAPONFRAME] = state->weaponframe;
|
||||
|
@ -5290,7 +5292,7 @@ void CL_LinkViewModel(void)
|
|||
ent.flags |= RF_WEAPONMODEL|RF_DEPTHHACK|RF_NOSHADOW;
|
||||
|
||||
plnum = -1;
|
||||
if (cl.spectator)
|
||||
if (pv->spectator)
|
||||
plnum = Cam_TrackNum(pv);
|
||||
if (plnum == -1)
|
||||
plnum = r_refdef.playerview->playernum;
|
||||
|
@ -5520,13 +5522,6 @@ void CL_SetUpPlayerPrediction(qboolean dopred)
|
|||
CL_PredictUsercmd (0, j+1, state, &exact, &state->command);
|
||||
VectorCopy (exact.origin, pplayer->origin);
|
||||
}
|
||||
|
||||
if (cl.spectator)
|
||||
{
|
||||
// if (!Cam_DrawPlayer(0, j))
|
||||
// VectorCopy(pplayer->origin, cl.simorg[0]);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -120,6 +120,7 @@ static void Display_Ignorelist(void)
|
|||
int i;
|
||||
int x;
|
||||
qboolean foundone;
|
||||
playerview_t *pv = &cl.playerview[0];
|
||||
|
||||
x = 0;
|
||||
foundone = false;
|
||||
|
@ -172,7 +173,7 @@ static void Display_Ignorelist(void)
|
|||
if (ignore_opponents.ival)
|
||||
Con_Printf("\x02" "Opponents are Ignored\n");
|
||||
|
||||
if (ignore_spec.ival == 2 || (ignore_spec.ival == 1 && !cl.spectator))
|
||||
if (ignore_spec.ival == 2 || (ignore_spec.ival == 1 && !pv->spectator))
|
||||
Con_Printf ("\x02" "Spectators are Ignored\n");
|
||||
|
||||
if (ignore_qizmo_spec.ival)
|
||||
|
@ -573,7 +574,8 @@ void Ignore_Flood_Add(player_info_t *sender, const char *s)
|
|||
|
||||
qboolean Ignore_Message(const char *sendername, const char *s, int flags)
|
||||
{
|
||||
int slot, i;
|
||||
int slot, i;
|
||||
playerview_t *pv = &cl.playerview[0];
|
||||
|
||||
if (!ignore_mode.ival && (flags & 2))
|
||||
return false;
|
||||
|
@ -581,7 +583,7 @@ qboolean Ignore_Message(const char *sendername, const char *s, int flags)
|
|||
|
||||
if (ignore_spec.ival == 2 && (flags == 4 || (flags == 8 && ignore_mode.ival)))
|
||||
return true;
|
||||
else if (ignore_spec.ival == 1 && (flags == 4) && !cl.spectator)
|
||||
else if (ignore_spec.ival == 1 && (flags == 4) && !pv->spectator)
|
||||
return true;
|
||||
|
||||
if (!sendername)
|
||||
|
@ -595,10 +597,10 @@ qboolean Ignore_Message(const char *sendername, const char *s, int flags)
|
|||
|
||||
if (ignore_opponents.ival && (
|
||||
(int) ignore_opponents.ival == 1 ||
|
||||
(cls.state >= ca_connected && /*!cl.standby &&*/ !cls.demoplayback && !cl.spectator) // match?
|
||||
(cls.state >= ca_connected && /*!cl.standby &&*/ !cls.demoplayback && !pv->spectator) // match?
|
||||
) &&
|
||||
flags == 1 && !cl.spectator && slot != cl.playerview[0].playernum &&
|
||||
(!cl.teamplay || strcmp(cl.players[slot].team, cl.players[cl.playerview[0].playernum].team))
|
||||
flags == 1 && !pv->spectator && slot != pv->playernum &&
|
||||
(!cl.teamplay || strcmp(cl.players[slot].team, cl.players[pv->playernum].team))
|
||||
)
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -273,7 +273,7 @@ void IN_JumpDown (void)
|
|||
|
||||
|
||||
int pnum = CL_TargettedSplit(false);
|
||||
|
||||
playerview_t *pv = &cl.playerview[pnum];
|
||||
|
||||
|
||||
condition = (cls.state == ca_active && cl_smartjump.ival && !prox_inmenu.ival);
|
||||
|
@ -283,14 +283,14 @@ void IN_JumpDown (void)
|
|||
else
|
||||
#endif
|
||||
#ifdef QUAKESTATS
|
||||
if (condition && cl.playerview[pnum].stats[STAT_HEALTH] > 0 && !cls.demoplayback && !cl.spectator &&
|
||||
(cls.protocol==CP_NETQUAKE || cl.inframes[cl.validsequence&UPDATE_MASK].playerstate[cl.playerview[pnum].playernum].messagenum == cl.validsequence)
|
||||
if (condition && cl.playerview[pnum].stats[STAT_HEALTH] > 0 && !cls.demoplayback && !pv->spectator &&
|
||||
(cls.protocol==CP_NETQUAKE || cl.inframes[cl.validsequence&UPDATE_MASK].playerstate[pv->playernum].messagenum == cl.validsequence)
|
||||
&& cl.playerview[pnum].waterlevel >= 2 && (!cl.teamfortress || !(in_forward.state[pnum] & 1))
|
||||
)
|
||||
KeyDown(&in_up);
|
||||
else
|
||||
#endif
|
||||
if (condition && cl.spectator && cl.playerview[pnum].cam_state == CAM_FREECAM)
|
||||
if (condition && pv->spectator && pv->cam_state == CAM_FREECAM)
|
||||
KeyDown(&in_up);
|
||||
else
|
||||
KeyDown(&in_jump);
|
||||
|
@ -1404,6 +1404,7 @@ void CL_UpdateSeats(void)
|
|||
targ = MAX_SPLITS;
|
||||
if (cl.splitclients < targ)
|
||||
{
|
||||
char *ver;
|
||||
char buffer[2048];
|
||||
char newinfo[2048];
|
||||
Q_strncpyz(newinfo, cls.userinfo[cl.splitclients], sizeof(newinfo));
|
||||
|
@ -1423,6 +1424,14 @@ void CL_UpdateSeats(void)
|
|||
if (!*Info_ValueForKey(newinfo, "skin")) //give players the same skin by default, because we can. q2 cares for teams. qw might as well (its not like anyone actually uses them thanks to enemy-skin forcing).
|
||||
Info_SetValueForKey(newinfo, "skin", Info_ValueForKey(cls.userinfo[0], "skin"), sizeof(newinfo));
|
||||
|
||||
#ifdef SVNREVISION
|
||||
if (strcmp(STRINGIFY(SVNREVISION), "-"))
|
||||
ver = va("%s v%i.%02i %s", DISTRIBUTION, FTE_VER_MAJOR, FTE_VER_MINOR, STRINGIFY(SVNREVISION));
|
||||
else
|
||||
#endif
|
||||
ver = va("%s v%i.%02i", DISTRIBUTION, FTE_VER_MAJOR, FTE_VER_MINOR);
|
||||
Info_SetValueForKey(newinfo, "*ver", ver, sizeof(newinfo));
|
||||
|
||||
CL_SendClientCommand(true, "addseat %i %s", cl.splitclients, COM_QuotedString(newinfo, buffer, sizeof(buffer), false));
|
||||
}
|
||||
else if (cl.splitclients > targ)
|
||||
|
@ -1736,6 +1745,7 @@ void CL_SendCmd (double frametime, qboolean mainloop)
|
|||
}
|
||||
for (plnum = 0; plnum < cl.splitclients; plnum++)
|
||||
{
|
||||
playerview_t *pv = &cl.playerview[plnum];
|
||||
cmd = &cl.outframes[i].cmd[plnum];
|
||||
|
||||
memset(cmd, 0, sizeof(*cmd));
|
||||
|
@ -1758,12 +1768,12 @@ void CL_SendCmd (double frametime, qboolean mainloop)
|
|||
VectorClear(mousemovements[plnum]);
|
||||
|
||||
// if we are spectator, try autocam
|
||||
if (cl.spectator)
|
||||
Cam_Track(&cl.playerview[plnum], cmd);
|
||||
if (pv->spectator)
|
||||
Cam_Track(pv, cmd);
|
||||
|
||||
CL_FinishMove(cmd, cmd->msec, plnum);
|
||||
|
||||
Cam_FinishMove(&cl.playerview[plnum], cmd);
|
||||
Cam_FinishMove(pv, cmd);
|
||||
|
||||
#ifdef CSQC_DAT
|
||||
CSQC_Input_Frame(plnum, cmd);
|
||||
|
@ -1772,7 +1782,6 @@ void CL_SendCmd (double frametime, qboolean mainloop)
|
|||
if (cls.state == ca_active)
|
||||
{
|
||||
player_state_t *from, *to;
|
||||
playerview_t *pv = &cl.playerview[plnum];
|
||||
from = &cl.inframes[cl.ackedmovesequence & UPDATE_MASK].playerstate[pv->playernum];
|
||||
to = &cl.inframes[cl.movesequence & UPDATE_MASK].playerstate[pv->playernum];
|
||||
CL_PredictUsercmd(pv->playernum, pv->viewentity, from, to, &cl.outframes[cl.ackedmovesequence & UPDATE_MASK].cmd[plnum]);
|
||||
|
|
|
@ -1657,6 +1657,7 @@ This is also called on Host_Error, so it shouldn't cause any errors
|
|||
void CL_Disconnect (void)
|
||||
{
|
||||
qbyte final[12];
|
||||
int i;
|
||||
|
||||
connectinfo.trying = false;
|
||||
|
||||
|
@ -1741,7 +1742,8 @@ void CL_Disconnect (void)
|
|||
COM_FlushTempoaryPacks();
|
||||
|
||||
r_worldentity.model = NULL;
|
||||
cl.spectator = 0;
|
||||
for (i = 0; i < cl.splitclients; i++)
|
||||
cl.playerview[i].spectator = 0;
|
||||
cl.sendprespawn = false;
|
||||
cl.intermissionmode = IM_NONE;
|
||||
cl.oldgametime = 0;
|
||||
|
@ -2033,9 +2035,18 @@ void CL_CheckServerInfo(void)
|
|||
unsigned int allowed;
|
||||
#ifdef QUAKESTATS
|
||||
int oldstate;
|
||||
#endif
|
||||
#ifndef CLIENTONLY
|
||||
extern cvar_t sv_cheats;
|
||||
#endif
|
||||
int oldteamplay;
|
||||
qboolean spectating = cl.spectator && cl.spectator != 2; //spectator 2 = spectator-with-scores, considered to be players. this means we don't want to allow spec cheats while they're inactive, because that would be weird.
|
||||
qboolean spectating = true;
|
||||
int i;
|
||||
|
||||
//spectator 2 = spectator-with-scores, considered to be players. this means we don't want to allow spec cheats while they're inactive, because that would be weird.
|
||||
for (i = 0; i < cl.splitclients; i++)
|
||||
if (cl.playerview[i].spectator != 1)
|
||||
spectating = false;
|
||||
|
||||
oldteamplay = cl.teamplay;
|
||||
cl.teamplay = atoi(Info_ValueForKey(cl.serverinfo, "teamplay"));
|
||||
|
@ -2073,7 +2084,8 @@ void CL_CheckServerInfo(void)
|
|||
|
||||
#ifndef CLIENTONLY
|
||||
//allow cheats in single player regardless of sv_cheats.
|
||||
if (sv.state == ss_active && sv.allocated_client_slots == 1)
|
||||
//(also directly read the sv_cheats cvar to avoid issues with nq protocols that don't support serverinfo.
|
||||
if ((sv.state == ss_active && sv.allocated_client_slots == 1) || sv_cheats.ival)
|
||||
cls.allow_cheats = true;
|
||||
#endif
|
||||
|
||||
|
@ -3074,6 +3086,7 @@ void CL_ConnectionlessPacket (void)
|
|||
COM_Parse(s);
|
||||
if (!strcmp(com_token, "ccept"))
|
||||
{
|
||||
/*this is a DP server... but we don't know which version nor nq protocol*/
|
||||
Con_Printf ("accept\n");
|
||||
if (cls.state == ca_connected)
|
||||
return; //we're already connected. don't do it again!
|
||||
|
@ -3090,10 +3103,9 @@ void CL_ConnectionlessPacket (void)
|
|||
CL_ParseEstablished();
|
||||
Con_DPrintf ("CL_EstablishConnection: connected to %s\n", cls.servername);
|
||||
|
||||
/*this is a DP server... but we don't know which version*/
|
||||
cls.netchan.isnqprotocol = true;
|
||||
cls.protocol = CP_NETQUAKE;
|
||||
cls.protocol_nq = CPNQ_ID;
|
||||
cls.protocol_nq = CPNQ_ID; //assume vanilla protocol until we know better.
|
||||
cls.proquake_angles_hack = false;
|
||||
cls.challenge = connectinfo.challenge;
|
||||
connectinfo.trying = false;
|
||||
|
@ -3846,14 +3858,12 @@ void CL_ServerInfo_f(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
#ifdef WEBCLIENT
|
||||
#ifdef FTPCLIENT
|
||||
void CL_FTP_f(void)
|
||||
{
|
||||
FTP_Client_Command(Cmd_Args(), NULL);
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
|
||||
//fixme: make a cvar
|
||||
void CL_Fog_f(void)
|
||||
|
@ -3930,6 +3940,7 @@ void CL_Status_f(void)
|
|||
|
||||
switch(cls.protocol)
|
||||
{
|
||||
default:
|
||||
case CP_UNKNOWN:
|
||||
Con_Printf("Unknown protocol\n");
|
||||
break;
|
||||
|
@ -4230,9 +4241,9 @@ void CL_Init (void)
|
|||
|
||||
Cvar_Register (&qtvcl_forceversion1, cl_controlgroup);
|
||||
Cvar_Register (&qtvcl_eztvextensions, cl_controlgroup);
|
||||
//#ifdef WEBCLIENT
|
||||
// Cmd_AddCommand ("ftp", CL_FTP_f);
|
||||
//#endif
|
||||
#ifdef FTPCLIENT
|
||||
Cmd_AddCommand ("ftp", CL_FTP_f);
|
||||
#endif
|
||||
|
||||
Cmd_AddCommandD ("changing", CL_Changing_f, "Part of network protocols. This command should not be used manually.");
|
||||
Cmd_AddCommand ("disconnect", CL_Disconnect_f);
|
||||
|
@ -5538,7 +5549,7 @@ double Host_Frame (double time)
|
|||
extern cvar_t scr_chatmodecvar, r_stereo_method;
|
||||
|
||||
if (scr_chatmodecvar.ival && cl.intermissionmode == IM_NONE)
|
||||
scr_chatmode = (cl.spectator&&cl.splitclients<2&&cls.state == ca_active)?2:1;
|
||||
scr_chatmode = (cl.playerview[0].spectator&&cl.splitclients<2&&cls.state == ca_active)?2:1;
|
||||
else
|
||||
scr_chatmode = 0;
|
||||
|
||||
|
|
|
@ -3086,18 +3086,19 @@ static void CLQW_ParseServerData (void)
|
|||
{
|
||||
cl.playerview[j].playernum = cl.allocated_client_slots + j;
|
||||
cl.playerview[j].viewentity = 0; //free floating.
|
||||
cl.playerview[j].spectator = true;
|
||||
for (i = 0; i < UPDATE_BACKUP; i++)
|
||||
{
|
||||
cl.inframes[i].playerstate[cl.playerview[j].playernum].pm_type = PM_SPECTATOR;
|
||||
cl.inframes[i].playerstate[cl.playerview[j].playernum].messagenum = 1;
|
||||
}
|
||||
}
|
||||
cl.spectator = true;
|
||||
|
||||
cl.splitclients = 1;
|
||||
}
|
||||
else if (cls.fteprotocolextensions2 & PEXT2_MAXPLAYERS)
|
||||
{
|
||||
qboolean spec = false;
|
||||
cl.allocated_client_slots = MSG_ReadByte();
|
||||
if (cl.allocated_client_slots > MAX_CLIENTS)
|
||||
{
|
||||
|
@ -3109,13 +3110,14 @@ static void CLQW_ParseServerData (void)
|
|||
cl.splitclients = MSG_ReadByte();
|
||||
if (cl.splitclients & 128)
|
||||
{
|
||||
cl.spectator = true;
|
||||
spec = true;
|
||||
cl.splitclients &= ~128;
|
||||
}
|
||||
if (cl.splitclients > MAX_SPLITS)
|
||||
Host_EndGame("Server sent us too many alternate clients\n");
|
||||
for (pnum = 0; pnum < cl.splitclients; pnum++)
|
||||
{
|
||||
cl.playerview[pnum].spectator = true;
|
||||
if (cls.z_ext & Z_EXT_VIEWHEIGHT)
|
||||
cl.playerview[pnum].viewheight = 0;
|
||||
cl.playerview[pnum].playernum = MSG_ReadByte();
|
||||
|
@ -3137,9 +3139,11 @@ static void CLQW_ParseServerData (void)
|
|||
cl.playerview[clnum].playernum = pnum;
|
||||
if (cl.playerview[clnum].playernum & 128)
|
||||
{
|
||||
cl.spectator = true;
|
||||
cl.playerview[clnum].spectator = true;
|
||||
cl.playerview[clnum].playernum &= ~128;
|
||||
}
|
||||
else
|
||||
cl.playerview[clnum].spectator = false;
|
||||
|
||||
if (cl.playerview[clnum].playernum >= cl.allocated_client_slots)
|
||||
Host_EndGame("unsupported local player slot\n");
|
||||
|
@ -3309,8 +3313,8 @@ static void CLQ2_ParseServerData (void)
|
|||
// parse player entity number
|
||||
cl.playerview[0].playernum = MSG_ReadShort ();
|
||||
cl.playerview[0].viewentity = cl.playerview[0].playernum+1;
|
||||
cl.playerview[0].spectator = false;
|
||||
cl.splitclients = 1;
|
||||
cl.spectator = false;
|
||||
|
||||
cl.numq2visibleweapons = 1; //give it a default.
|
||||
cl.q2visibleweapons[0] = "weapon.md2";
|
||||
|
@ -4884,7 +4888,7 @@ void CL_NewTranslation (int slot)
|
|||
bottom = player->rbottomcolor;
|
||||
if (cl.splitclients < 2 && !(cl.fpd & FPD_NO_FORCE_COLOR)) //no colour/skin forcing in splitscreen.
|
||||
{
|
||||
if (cl.teamplay && cl.spectator)
|
||||
if (cl.teamplay && cl.playerview[0].spectator)
|
||||
{
|
||||
local = Cam_TrackNum(&cl.playerview[0]);
|
||||
if (local < 0)
|
||||
|
@ -4977,11 +4981,14 @@ static void CL_ProcessUserInfo (int slot, player_info_t *player)
|
|||
player->colourised = TP_FindColours(player->name);
|
||||
|
||||
// If it's us
|
||||
if (slot == cl.playerview[0].playernum && player->name[0])
|
||||
for (i = 0; i < cl.splitclients; i++)
|
||||
if (slot == cl.playerview[i].playernum)
|
||||
break;
|
||||
if (i < cl.splitclients && player->name[0])
|
||||
{
|
||||
if (cl.spectator != player->spectator)
|
||||
if (cl.playerview[i].spectator != player->spectator)
|
||||
{
|
||||
cl.spectator = player->spectator;
|
||||
cl.playerview[i].spectator = player->spectator;
|
||||
for (i = 0; i < cl.splitclients; i++)
|
||||
{
|
||||
Cam_Unlock(&cl.playerview[i]);
|
||||
|
@ -4993,7 +5000,7 @@ static void CL_ProcessUserInfo (int slot, player_info_t *player)
|
|||
|
||||
Skin_FlushPlayers();
|
||||
}
|
||||
else if (cl.teamplay && cl.spectator && slot == Cam_TrackNum(&cl.playerview[0])) //skin forcing cares about the team of the guy we're tracking.
|
||||
else if (cl.teamplay && cl.playerview[0].spectator && slot == Cam_TrackNum(&cl.playerview[0])) //skin forcing cares about the team of the guy we're tracking.
|
||||
Skin_FlushPlayers();
|
||||
else if (cls.state == ca_active)
|
||||
Skin_Find (player);
|
||||
|
@ -6104,7 +6111,8 @@ static void CL_ParseWeaponStats(void)
|
|||
|
||||
static void CL_ParseItemTimer(void)
|
||||
{
|
||||
float timeout = atof(Cmd_Argv(0));
|
||||
//it [cur/]duration x y z radius 0xRRGGBB "timername" owningent
|
||||
float timeout;// = atof(Cmd_Argv(0));
|
||||
vec3_t org = { atof(Cmd_Argv(1)),
|
||||
atof(Cmd_Argv(2)),
|
||||
atof(Cmd_Argv(3))};
|
||||
|
@ -6113,6 +6121,15 @@ static void CL_ParseItemTimer(void)
|
|||
// char *timername = Cmd_Argv(6);
|
||||
unsigned int entnum = strtoul(Cmd_Argv(7), NULL, 0);
|
||||
struct itemtimer_s *timer;
|
||||
float start = cl.time;
|
||||
char *e;
|
||||
timeout = strtod(Cmd_Argv(0), &e);
|
||||
if (*e == '/')
|
||||
{
|
||||
start += timeout;
|
||||
timeout = atof(e+1);
|
||||
start -= timeout;
|
||||
}
|
||||
|
||||
if (!timeout)
|
||||
timeout = FLT_MAX;
|
||||
|
@ -6121,7 +6138,12 @@ static void CL_ParseItemTimer(void)
|
|||
|
||||
for (timer = cl.itemtimers; timer; timer = timer->next)
|
||||
{
|
||||
if (VectorCompare(timer->origin, org) && timer->entnum == entnum && entnum)
|
||||
if (entnum)
|
||||
{
|
||||
if (timer->entnum == entnum)
|
||||
break;
|
||||
}
|
||||
else if (VectorCompare(timer->origin, org))
|
||||
break;
|
||||
}
|
||||
if (!timer)
|
||||
|
@ -6137,8 +6159,8 @@ static void CL_ParseItemTimer(void)
|
|||
timer->radius = radius;
|
||||
timer->duration = timeout;
|
||||
timer->entnum = entnum;
|
||||
timer->start = cl.time;
|
||||
timer->end = cl.time + timer->duration;
|
||||
timer->start = start;
|
||||
timer->end = start + timer->duration;
|
||||
timer->rgb[0] = ((rgb>>16)&0xff)/255.0;
|
||||
timer->rgb[1] = ((rgb>> 8)&0xff)/255.0;
|
||||
timer->rgb[2] = ((rgb )&0xff)/255.0;
|
||||
|
@ -6931,7 +6953,7 @@ void CLQW_ParseServerMessage (void)
|
|||
if (cl.intermissionmode == IM_NONE)
|
||||
{
|
||||
TP_ExecTrigger ("f_mapend", false);
|
||||
if (cl.spectator)
|
||||
if (cl.playerview[destsplit].spectator)
|
||||
TP_ExecTrigger ("f_specmapend", true);
|
||||
cl.completed_time = cl.gametime;
|
||||
}
|
||||
|
|
|
@ -449,7 +449,7 @@ void CL_PredictUsercmd (int pnum, int entnum, player_state_t *from, player_state
|
|||
void CL_CatagorizePosition (playerview_t *pv, float *org)
|
||||
{
|
||||
//fixme: in nq, we are told by the server and should skip this, which avoids needing to know the player's size.
|
||||
if (cl.spectator)
|
||||
if (pv->spectator)
|
||||
{
|
||||
pv->onground = false; // in air
|
||||
return;
|
||||
|
@ -912,7 +912,7 @@ void CL_PredictMovePNum (int seat)
|
|||
|
||||
pv->nolocalplayer = !!(cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) || (cls.protocol != CP_QUAKEWORLD);
|
||||
|
||||
if (!cl.spectator && (pv->cam_state != CAM_FREECAM || pv->cam_spec_track != -1)) //just in case
|
||||
if (!pv->spectator && (pv->cam_state != CAM_FREECAM || pv->cam_spec_track != -1)) //just in case
|
||||
{
|
||||
if (pv->cam_state != CAM_FREECAM)
|
||||
pv->viewentity = (cls.demoplayback)?0:(pv->playernum+1);
|
||||
|
|
|
@ -712,9 +712,6 @@ void SCR_DrawCenterString (vrect_t *rect, cprint_t *p, struct font_s *font)
|
|||
|
||||
void SCR_CheckDrawCenterString (void)
|
||||
{
|
||||
#ifdef QUAKEHUD
|
||||
extern qboolean sb_showscores;
|
||||
#endif
|
||||
int pnum;
|
||||
cprint_t *p;
|
||||
|
||||
|
@ -731,7 +728,7 @@ void SCR_CheckDrawCenterString (void)
|
|||
continue; //should probably allow the console with a scissor region or something.
|
||||
|
||||
#ifdef QUAKEHUD
|
||||
if (sb_showscores) //this was annoying
|
||||
if (cl.playerview[pnum].sb_showscores) //this was annoying
|
||||
continue;
|
||||
#endif
|
||||
|
||||
|
@ -3066,7 +3063,7 @@ void SCR_DrawTwoDimensional(int uimenu, qboolean nohud)
|
|||
}
|
||||
else if (cl.intermissionmode != IM_NONE)
|
||||
{
|
||||
Sbar_IntermissionOverlay ();
|
||||
Sbar_IntermissionOverlay (r_refdef.playerview);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -599,6 +599,7 @@ struct playerview_s
|
|||
{
|
||||
int playernum; //cl.players index for this player.
|
||||
qboolean nolocalplayer; //inhibit use of qw-style players, predict based on entities.
|
||||
qboolean spectator;
|
||||
#ifdef PEXT_SETVIEW
|
||||
int viewentity; //view is attached to this entity.
|
||||
#endif
|
||||
|
@ -610,12 +611,16 @@ struct playerview_s
|
|||
float item_gettime[32]; // cl.time of aquiring item, for blinking
|
||||
float faceanimtime; // use anim frame if cl.time < this
|
||||
|
||||
#ifdef QUAKEHUD
|
||||
qboolean sb_showscores;
|
||||
qboolean sb_showteamscores;
|
||||
#ifdef HEXEN2
|
||||
int sb_hexen2_cur_item;//hexen2 hud
|
||||
float sb_hexen2_item_time;
|
||||
qboolean sb_hexen2_extra_info;//show the extra stuff
|
||||
qboolean sb_hexen2_infoplaque;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
// the client maintains its own idea of view angles, which are
|
||||
|
@ -752,7 +757,7 @@ typedef struct
|
|||
// render a frame yet
|
||||
int movesequence; // client->server frames
|
||||
|
||||
int spectator;
|
||||
// int spectator;
|
||||
int autotrack_hint; //the latest hint from the mod, might be negative for invalid.
|
||||
int autotrack_killer; //if someone kills the guy we're tracking, this is the guy we should switch to.
|
||||
|
||||
|
|
|
@ -768,7 +768,7 @@ void Key_DefaultLinkClicked(console_t *con, char *text, char *info)
|
|||
if (*cl.players[player].ip)
|
||||
Con_Footerf(con, true, "\n%s", cl.players[player].ip);
|
||||
|
||||
if (cl.spectator || cls.demoplayback)
|
||||
if (cl.playerview[0].spectator || cls.demoplayback)
|
||||
{
|
||||
//we're spectating, or an mvd
|
||||
Con_Footerf(con, true, " ^[Spectate\\player\\%i\\action\\spec^]", player);
|
||||
|
@ -803,7 +803,7 @@ void Key_DefaultLinkClicked(console_t *con, char *text, char *info)
|
|||
|
||||
//hey look! its you!
|
||||
|
||||
if (cl.spectator || cls.demoplayback)
|
||||
if (cl.playerview[i].spectator || cls.demoplayback)
|
||||
{
|
||||
//need join option here or something
|
||||
}
|
||||
|
|
|
@ -246,7 +246,7 @@ static void CSQC_ChangeLocalPlayer(int seat)
|
|||
{
|
||||
if (csqc_playerview->viewentity)
|
||||
*csqcg.player_localentnum = csqc_playerview->viewentity;
|
||||
else if (cl.spectator && Cam_TrackNum(csqc_playerview) >= 0)
|
||||
else if (csqc_playerview->spectator && Cam_TrackNum(csqc_playerview) >= 0)
|
||||
*csqcg.player_localentnum = Cam_TrackNum(csqc_playerview) + 1;
|
||||
else if (csqc_playerview == &csqc_nullview)
|
||||
*csqcg.player_localentnum = 0;
|
||||
|
@ -2185,7 +2185,7 @@ static void QCBUILTIN PF_R_RenderScene(pubprogfuncs_t *prinst, struct globalvars
|
|||
#ifdef PLUGINS
|
||||
Plug_SBar (r_refdef.playerview);
|
||||
#else
|
||||
if (Sbar_ShouldDraw())
|
||||
if (Sbar_ShouldDraw(r_refdef.playerview))
|
||||
{
|
||||
SCR_TileClear (sb_lines);
|
||||
Sbar_Draw (r_refdef.playerview);
|
||||
|
@ -2203,7 +2203,7 @@ static void QCBUILTIN PF_R_RenderScene(pubprogfuncs_t *prinst, struct globalvars
|
|||
}
|
||||
else if (cl.intermissionmode != IM_NONE)
|
||||
{
|
||||
Sbar_IntermissionOverlay ();
|
||||
Sbar_IntermissionOverlay (r_refdef.playerview);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,6 @@ model_t *currentmodel;
|
|||
|
||||
uploadfmt_t lightmap_fmt; //bgra32, rgba32, rgb24, lum8
|
||||
int lightmap_bytes; // 1, 3 or 4
|
||||
qboolean lightmap_bgra;
|
||||
|
||||
size_t maxblocksize;
|
||||
vec3_t *blocknormals;
|
||||
|
@ -903,8 +902,7 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
|
|||
if (currentmodel->deluxdata)
|
||||
Surf_BuildDeluxMap(currentmodel, surf, deluxdest, lmwidth, blocknormals);
|
||||
|
||||
#ifdef PEXT_LIGHTSTYLECOL
|
||||
if (lightmap_bytes == 4 || lightmap_bytes == 3)
|
||||
if (lightmap_fmt != TF_LUM8)
|
||||
{
|
||||
// set to full bright if no light data
|
||||
if (ambient < 0)
|
||||
|
@ -1078,40 +1076,22 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
|
|||
if (!r_stains.value || !surf->stained)
|
||||
stainsrc = NULL;
|
||||
|
||||
if (lightmap_bytes == 4)
|
||||
switch(lightmap_fmt)
|
||||
{
|
||||
if (lightmap_bgra)
|
||||
{
|
||||
Surf_StoreLightmap(dest, blocklights, smax, tmax, shift, bgra4_os, stainsrc, lmwidth);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*if (!r_stains.value || !surf->stained)
|
||||
Surf_StoreLightmap(dest, blocklights, smax, tmax, shift, rgba4, NULL);
|
||||
else
|
||||
Surf_StoreLightmap(dest, blocklights, smax, tmax, shift, rgba4, stainsrc);
|
||||
*/
|
||||
}
|
||||
}
|
||||
else if (lightmap_bytes == 3)
|
||||
{
|
||||
if (lightmap_bgra)
|
||||
{
|
||||
/*
|
||||
if (!r_stains.value || !surf->stained)
|
||||
Surf_StoreLightmap(dest, blocklights, smax, tmax, shift, bgr3, NULL);
|
||||
else
|
||||
Surf_StoreLightmap(dest, blocklights, smax, tmax, shift, bgr3, stainsrc);
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
Surf_StoreLightmap(dest, blocklights, smax, tmax, shift, rgb3_os, stainsrc, lmwidth);
|
||||
}
|
||||
default:
|
||||
Sys_Error("Bad lightmap_fmt\n");
|
||||
case TF_BGRA32:
|
||||
Surf_StoreLightmap(dest, blocklights, smax, tmax, shift, bgra4_os, stainsrc, lmwidth);
|
||||
break;
|
||||
// case TF_RGBA32:
|
||||
// Surf_StoreLightmap(dest, blocklights, smax, tmax, shift, rgba4, stainsrc, lmwidth);
|
||||
// break;
|
||||
case TF_RGB24:
|
||||
Surf_StoreLightmap(dest, blocklights, smax, tmax, shift, rgb3_os, stainsrc, lmwidth);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// set to full bright if no light data
|
||||
if (!surf->samples || !currentmodel->lightdata)
|
||||
|
@ -1206,8 +1186,7 @@ static void Surf_BuildLightMap_Worker (model_t *wmodel, msurface_t *surf, qbyte
|
|||
if (wmodel->deluxdata)
|
||||
Surf_BuildDeluxMap(wmodel, surf, deluxdest, lmwidth, blocknormals);
|
||||
|
||||
#ifdef PEXT_LIGHTSTYLECOL
|
||||
if (lightmap_bytes == 4 || lightmap_bytes == 3)
|
||||
if (lightmap_fmt != TF_LUM8)
|
||||
{
|
||||
// set to full bright if no light data
|
||||
if (ambient < 0)
|
||||
|
@ -1377,40 +1356,20 @@ static void Surf_BuildLightMap_Worker (model_t *wmodel, msurface_t *surf, qbyte
|
|||
if (!r_stains.value || !surf->stained)
|
||||
stainsrc = NULL;
|
||||
|
||||
if (lightmap_bytes == 4)
|
||||
switch(lightmap_fmt)
|
||||
{
|
||||
if (lightmap_bgra)
|
||||
{
|
||||
Surf_StoreLightmap(dest, blocklights, smax, tmax, shift, bgra4_os, stainsrc, lmwidth);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*if (!r_stains.value || !surf->stained)
|
||||
Surf_StoreLightmap(dest, blocklights, smax, tmax, shift, rgba4, NULL);
|
||||
else
|
||||
Surf_StoreLightmap(dest, blocklights, smax, tmax, shift, rgba4, stainsrc);
|
||||
*/
|
||||
}
|
||||
}
|
||||
else if (lightmap_bytes == 3)
|
||||
{
|
||||
if (lightmap_bgra)
|
||||
{
|
||||
/*
|
||||
if (!r_stains.value || !surf->stained)
|
||||
Surf_StoreLightmap(dest, blocklights, smax, tmax, shift, bgr3, NULL);
|
||||
else
|
||||
Surf_StoreLightmap(dest, blocklights, smax, tmax, shift, bgr3, stainsrc);
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
Surf_StoreLightmap(dest, blocklights, smax, tmax, shift, rgb3_os, stainsrc, lmwidth);
|
||||
}
|
||||
default:
|
||||
Sys_Error("Bad lightmap_fmt\n");
|
||||
break;
|
||||
case TF_BGRA32:
|
||||
Surf_StoreLightmap(dest, blocklights, smax, tmax, shift, bgra4_os, stainsrc, lmwidth);
|
||||
break;
|
||||
case TF_RGB24:
|
||||
Surf_StoreLightmap(dest, blocklights, smax, tmax, shift, rgb3_os, stainsrc, lmwidth);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
// set to full bright if no light data
|
||||
if (!surf->samples || !wmodel->lightdata)
|
||||
|
@ -3305,58 +3264,44 @@ void Surf_Clear(model_t *mod)
|
|||
//pick fastest mode for lightmap data
|
||||
void Surf_LightmapMode(void)
|
||||
{
|
||||
lightmap_bgra = true;
|
||||
|
||||
switch(qrenderer)
|
||||
{
|
||||
default:
|
||||
case QR_SOFTWARE:
|
||||
// case QR_VULKAN:
|
||||
// case QR_SOFTWARE:
|
||||
// case QR_DIRECT3D8:
|
||||
// case QR_DIRECT3D9:
|
||||
// case QR_DIRECT3D11:
|
||||
lightmap_fmt = TF_BGRA32;
|
||||
lightmap_bytes = 4;
|
||||
lightmap_bgra = true;
|
||||
break;
|
||||
#ifdef D3DQUAKE
|
||||
case QR_DIRECT3D8:
|
||||
case QR_DIRECT3D9:
|
||||
case QR_DIRECT3D11:
|
||||
/*always bgra, hope your card supports it*/
|
||||
lightmap_fmt = TF_BGRA32;
|
||||
lightmap_bytes = 4;
|
||||
lightmap_bgra = true;
|
||||
break;
|
||||
#endif
|
||||
#ifdef GLQUAKE
|
||||
case QR_OPENGL:
|
||||
/*favour bgra if the gpu supports it, otherwise use rgb only if it'll be used*/
|
||||
lightmap_bgra = false;
|
||||
if (gl_config.gles)
|
||||
{
|
||||
//rgb is a supported format, where bgr or rgbx are not.
|
||||
lightmap_fmt = TF_RGB24;
|
||||
lightmap_bytes = 3;
|
||||
lightmap_bgra = false;
|
||||
}
|
||||
lightmap_fmt = TF_RGB24; //rgb24 is a guarenteed supported format, where bgr24 or rgbx32 are not.
|
||||
else if (gl_config.glversion >= 1.2)
|
||||
{
|
||||
/*the more common case*/
|
||||
lightmap_fmt = TF_BGRA32;
|
||||
lightmap_bytes = 4;
|
||||
lightmap_bgra = true;
|
||||
}
|
||||
lightmap_fmt = TF_BGRA32; //the more common case
|
||||
else if (cl.worldmodel->fromgame == fg_quake3 || (cl.worldmodel->engineflags & MDLF_RGBLIGHTING) || cl.worldmodel->deluxdata || r_loadlits.value)
|
||||
{
|
||||
lightmap_fmt = TF_RGB24;
|
||||
lightmap_bgra = false;
|
||||
lightmap_bytes = 3;
|
||||
}
|
||||
lightmap_fmt = TF_RGB24; //ooold gl driver, but we need rgb lighting
|
||||
else
|
||||
{
|
||||
lightmap_fmt = TF_LUM8;
|
||||
lightmap_bytes = 1;
|
||||
}
|
||||
lightmap_fmt = TF_LUM8; //oldskool!
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
switch(lightmap_fmt)
|
||||
{
|
||||
default:
|
||||
case TF_BGRA32:
|
||||
lightmap_bytes = 4;
|
||||
break;
|
||||
case TF_RGB24:
|
||||
lightmap_bytes = 3;
|
||||
break;
|
||||
case TF_LUM8:
|
||||
lightmap_bytes = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//needs to be followed by a BE_UploadAllLightmaps at some point
|
||||
|
@ -3374,6 +3319,8 @@ int Surf_NewLightmaps(int count, int width, int height, qboolean deluxe)
|
|||
Con_Print("WARNING: Deluxemapping with odd number of lightmaps\n");
|
||||
}
|
||||
|
||||
Sys_LockMutex(com_resourcemutex);
|
||||
|
||||
i = numlightmaps + count;
|
||||
lightmap = BZ_Realloc(lightmap, sizeof(*lightmap)*(i));
|
||||
while(i > first)
|
||||
|
@ -3416,6 +3363,8 @@ int Surf_NewLightmaps(int count, int width, int height, qboolean deluxe)
|
|||
|
||||
numlightmaps += count;
|
||||
|
||||
Sys_UnlockMutex(com_resourcemutex);
|
||||
|
||||
return first;
|
||||
}
|
||||
int Surf_NewExternalLightmaps(int count, char *filepattern, qboolean deluxe)
|
||||
|
@ -3549,45 +3498,45 @@ void Surf_BuildModelLightmaps (model_t *m)
|
|||
src = m->lightdata + i*m->lightmaps.width*m->lightmaps.height*3;
|
||||
if (m->lightdata)
|
||||
{
|
||||
if (lightmap_bgra && lightmap_bytes == 4)
|
||||
switch(lightmap_fmt)
|
||||
{
|
||||
default:
|
||||
Sys_Error("Bad lightmap_fmt\n");
|
||||
break;
|
||||
case TF_BGRA32:
|
||||
for (j = min((m->lightdatasize-i*m->lightmaps.width*m->lightmaps.height*3)/3,m->lightmaps.width*m->lightmaps.height); j > 0; j--, dst += 4, src += 3)
|
||||
//for (j = 0; j < m->lightmaps.width*m->lightmaps.height; j++, dst += 4, src += 3)
|
||||
{
|
||||
dst[0] = src[2];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[0];
|
||||
dst[3] = 255;
|
||||
}
|
||||
}
|
||||
else if (!lightmap_bgra && lightmap_bytes == 4)
|
||||
{
|
||||
break;
|
||||
/*case TF_RGBA32:
|
||||
for (j = min((m->lightdatasize-i*m->lightmaps.width*m->lightmaps.height*3)/3,m->lightmaps.width*m->lightmaps.height); j > 0; j--, dst += 4, src += 3)
|
||||
//for (j = 0; j < m->lightmaps.width*m->lightmaps.height; j++, dst += 4, src += 3)
|
||||
{
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[2];
|
||||
dst[3] = 255;
|
||||
}
|
||||
}
|
||||
else if (lightmap_bgra && lightmap_bytes == 3)
|
||||
{
|
||||
break;
|
||||
case TF_BGR24:
|
||||
for (j = 0; j < m->lightmaps.width*m->lightmaps.height; j++, dst += 3, src += 3)
|
||||
{
|
||||
dst[0] = src[2];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[0];
|
||||
}
|
||||
}
|
||||
else if (!lightmap_bgra && lightmap_bytes == 3)
|
||||
{
|
||||
break;*/
|
||||
case TF_RGB24:
|
||||
for (j = 0; j < m->lightmaps.width*m->lightmaps.height; j++, dst += 3, src += 3)
|
||||
{
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[1];
|
||||
dst[2] = src[2];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -360,8 +360,8 @@ extern lightmapinfo_t **lightmap;
|
|||
extern int numlightmaps;
|
||||
//extern texid_t *lightmap_textures;
|
||||
//extern texid_t *deluxmap_textures;
|
||||
extern int lightmap_bytes; // 1, 3, or 4
|
||||
extern qboolean lightmap_bgra; /*true=bgra, false=rgba*/
|
||||
extern int lightmap_bytes; // 1, 3, or 4
|
||||
extern uploadfmt_t lightmap_fmt; //bgra32, rgba32, rgb24, lum8
|
||||
|
||||
void QDECL Surf_RebuildLightmap_Callback (struct cvar_s *var, char *oldvalue);
|
||||
|
||||
|
|
|
@ -118,9 +118,6 @@ static int hipweapons[4] = {HIT_LASER_CANNON_BIT,HIT_MJOLNIR_BIT,4,HIT_P
|
|||
static apic_t *hsb_items[2];
|
||||
//end hipnotic
|
||||
|
||||
qboolean sb_showscores;
|
||||
qboolean sb_showteamscores;
|
||||
|
||||
static qboolean sbarfailed;
|
||||
#ifdef HEXEN2
|
||||
static qboolean sbar_hexen2;
|
||||
|
@ -131,15 +128,15 @@ float sbar_rect_left;
|
|||
|
||||
int sb_lines; // scan lines to draw
|
||||
|
||||
void Sbar_DeathmatchOverlay (int start);
|
||||
void Sbar_TeamOverlay (void);
|
||||
void Sbar_DeathmatchOverlay (playerview_t *pv, int start);
|
||||
void Sbar_TeamOverlay (playerview_t *pv);
|
||||
static void Sbar_MiniDeathmatchOverlay (playerview_t *pv);
|
||||
void Sbar_ChatModeOverlay(playerview_t *pv);
|
||||
|
||||
static int Sbar_PlayerNum(playerview_t *pv)
|
||||
{
|
||||
int num;
|
||||
num = cl.spectator?Cam_TrackNum(pv):-1;
|
||||
num = pv->spectator?Cam_TrackNum(pv):-1;
|
||||
if (num < 0)
|
||||
num = pv->playernum;
|
||||
return num;
|
||||
|
@ -716,7 +713,8 @@ Tab key down
|
|||
*/
|
||||
void Sbar_ShowTeamScores (void)
|
||||
{
|
||||
if (sb_showteamscores)
|
||||
int seat = CL_TargettedSplit(false);
|
||||
if (cl.playerview[seat].sb_showteamscores)
|
||||
return;
|
||||
|
||||
#ifdef CSQC_DAT
|
||||
|
@ -724,7 +722,7 @@ void Sbar_ShowTeamScores (void)
|
|||
return;
|
||||
#endif
|
||||
|
||||
sb_showteamscores = true;
|
||||
cl.playerview[seat].sb_showteamscores = true;
|
||||
sb_updates = 0;
|
||||
}
|
||||
|
||||
|
@ -737,7 +735,8 @@ Tab key up
|
|||
*/
|
||||
void Sbar_DontShowTeamScores (void)
|
||||
{
|
||||
sb_showteamscores = false;
|
||||
int seat = CL_TargettedSplit(false);
|
||||
cl.playerview[seat].sb_showteamscores = false;
|
||||
sb_updates = 0;
|
||||
|
||||
#ifdef CSQC_DAT
|
||||
|
@ -755,13 +754,14 @@ Tab key down
|
|||
*/
|
||||
void Sbar_ShowScores (void)
|
||||
{
|
||||
int seat = CL_TargettedSplit(false);
|
||||
if (scr_scoreboard_teamscores.ival)
|
||||
{
|
||||
Sbar_ShowTeamScores();
|
||||
return;
|
||||
}
|
||||
|
||||
if (sb_showscores)
|
||||
if (cl.playerview[seat].sb_showscores)
|
||||
return;
|
||||
|
||||
#ifdef CSQC_DAT
|
||||
|
@ -769,7 +769,7 @@ void Sbar_ShowScores (void)
|
|||
return;
|
||||
#endif
|
||||
|
||||
sb_showscores = true;
|
||||
cl.playerview[seat].sb_showscores = true;
|
||||
sb_updates = 0;
|
||||
}
|
||||
|
||||
|
@ -893,13 +893,14 @@ Tab key up
|
|||
*/
|
||||
void Sbar_DontShowScores (void)
|
||||
{
|
||||
int seat = CL_TargettedSplit(false);
|
||||
if (scr_scoreboard_teamscores.ival)
|
||||
{
|
||||
Sbar_DontShowTeamScores();
|
||||
return;
|
||||
}
|
||||
|
||||
sb_showscores = false;
|
||||
cl.playerview[seat].sb_showscores = false;
|
||||
sb_updates = 0;
|
||||
|
||||
#ifdef CSQC_DAT
|
||||
|
@ -2166,7 +2167,7 @@ void Sbar_DrawNormal (playerview_t *pv)
|
|||
, pv->stats[STAT_AMMO] <= 10);
|
||||
}
|
||||
|
||||
qboolean Sbar_ShouldDraw (void)
|
||||
qboolean Sbar_ShouldDraw (playerview_t *pv)
|
||||
{
|
||||
#ifdef TEXTEDITOR
|
||||
extern qboolean editoractive;
|
||||
|
@ -2182,7 +2183,7 @@ qboolean Sbar_ShouldDraw (void)
|
|||
#endif
|
||||
|
||||
#ifdef VM_UI
|
||||
if (UI_DrawStatusBar((sb_showscores?1:0) + (sb_showteamscores?2:0))>0)
|
||||
if (UI_DrawStatusBar((pv->sb_showscores?1:0) + (pv->sb_showteamscores?2:0))>0)
|
||||
return false;
|
||||
if (UI_MenuState())
|
||||
return false;
|
||||
|
@ -2195,10 +2196,9 @@ qboolean Sbar_ShouldDraw (void)
|
|||
return true;
|
||||
}
|
||||
|
||||
void Sbar_DrawScoreboard (void)
|
||||
void Sbar_DrawScoreboard (playerview_t *pv)
|
||||
{
|
||||
int pnum;
|
||||
int deadcount=0;
|
||||
qboolean isdead;
|
||||
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
return;
|
||||
|
@ -2214,31 +2214,27 @@ void Sbar_DrawScoreboard (void)
|
|||
}
|
||||
#endif
|
||||
|
||||
for (pnum = 0; pnum < cl.splitclients; pnum++)
|
||||
isdead = false;
|
||||
if (pv->spectator && (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV))
|
||||
{
|
||||
if (cl.spectator && (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV))
|
||||
{
|
||||
int t = cl.playerview[pnum].cam_spec_track;
|
||||
if (t < 0 || !CAM_ISLOCKED(&cl.playerview[pnum]))
|
||||
continue;
|
||||
if (cl.players[t].statsf[STAT_HEALTH] <= 0)
|
||||
deadcount++;
|
||||
}
|
||||
else if (!cl.spectator && cl.playerview[pnum].statsf[STAT_HEALTH] <= 0)
|
||||
deadcount++;
|
||||
int t = pv->cam_spec_track;
|
||||
if (t >= 0 && CAM_ISLOCKED(pv) && cl.players[t].statsf[STAT_HEALTH] <= 0)
|
||||
isdead = true;
|
||||
}
|
||||
else if (!pv->spectator && pv->statsf[STAT_HEALTH] <= 0)
|
||||
isdead = true;
|
||||
|
||||
if (deadcount == cl.splitclients)// && !cl.spectator)
|
||||
if (isdead)// && !cl.spectator)
|
||||
{
|
||||
if (cl.teamplay > 0 && !sb_showscores)
|
||||
Sbar_TeamOverlay();
|
||||
if (cl.teamplay > 0 && !pv->sb_showscores)
|
||||
Sbar_TeamOverlay(pv);
|
||||
else
|
||||
Sbar_DeathmatchOverlay (0);
|
||||
Sbar_DeathmatchOverlay (pv, 0);
|
||||
}
|
||||
else if (sb_showscores)
|
||||
Sbar_DeathmatchOverlay (0);
|
||||
else if (sb_showteamscores)
|
||||
Sbar_TeamOverlay();
|
||||
else if (pv->sb_showscores)
|
||||
Sbar_DeathmatchOverlay (pv, 0);
|
||||
else if (pv->sb_showteamscores)
|
||||
Sbar_TeamOverlay(pv);
|
||||
else
|
||||
return;
|
||||
|
||||
|
@ -2563,7 +2559,7 @@ static void Sbar_DrawTeamStatus(playerview_t *pv)
|
|||
y = -32;
|
||||
|
||||
track = Cam_TrackNum(pv);
|
||||
if (track == -1 || !cl.spectator)
|
||||
if (track == -1 || !pv->spectator)
|
||||
track = pv->playernum;
|
||||
|
||||
for (p = 0; p < cl.allocated_client_slots; p++)
|
||||
|
@ -2730,7 +2726,7 @@ extern cvar_t show_speed_y;
|
|||
t = Sys_DoubleTime();
|
||||
if ((t - lastupstime) >= 1.0/20)
|
||||
{
|
||||
if (cl.spectator)
|
||||
if (pv->spectator)
|
||||
track = Cam_TrackNum(pv);
|
||||
else
|
||||
track = -1;
|
||||
|
@ -2865,7 +2861,7 @@ void Sbar_Draw (playerview_t *pv)
|
|||
// main area
|
||||
if (sb_lines > 0)
|
||||
{
|
||||
if (cl.spectator)
|
||||
if (pv->spectator)
|
||||
{
|
||||
if (pv->cam_state == CAM_FREECAM || pv->cam_state == CAM_PENDING)
|
||||
{
|
||||
|
@ -2879,7 +2875,7 @@ void Sbar_Draw (playerview_t *pv)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (sb_showscores || sb_showteamscores || pv->stats[STAT_HEALTH] <= 0)
|
||||
if (pv->sb_showscores || pv->sb_showteamscores || pv->stats[STAT_HEALTH] <= 0)
|
||||
Sbar_SoloScoreboard ();
|
||||
// else if (cls.gamemode != GAME_DEATHMATCH)
|
||||
// Sbar_CoopScoreboard ();
|
||||
|
@ -2894,7 +2890,7 @@ void Sbar_Draw (playerview_t *pv)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (sb_showscores || sb_showteamscores || (pv->stats[STAT_HEALTH] <= 0 && cl.splitclients == 1))
|
||||
else if (pv->sb_showscores || pv->sb_showteamscores || (pv->stats[STAT_HEALTH] <= 0 && cl.splitclients == 1))
|
||||
{
|
||||
if (pv == cl.playerview)
|
||||
{
|
||||
|
@ -2915,7 +2911,7 @@ void Sbar_Draw (playerview_t *pv)
|
|||
// top line
|
||||
if (sb_lines > 24)
|
||||
{
|
||||
if (!cl.spectator || pv->cam_state == CAM_WALLCAM || pv->cam_state == CAM_EYECAM)
|
||||
if (!pv->spectator || pv->cam_state == CAM_WALLCAM || pv->cam_state == CAM_EYECAM)
|
||||
Sbar_DrawInventory (pv);
|
||||
else if (cl_sbar.ival)
|
||||
Sbar_DrawPic (0, -24, 320, 24, sb_scorebar); //make sure we don't get HoM
|
||||
|
@ -3006,7 +3002,7 @@ team frags
|
|||
added by Zoid
|
||||
==================
|
||||
*/
|
||||
void Sbar_TeamOverlay (void)
|
||||
void Sbar_TeamOverlay (playerview_t *pv)
|
||||
{
|
||||
mpic_t *pic;
|
||||
int i, k;
|
||||
|
@ -3015,8 +3011,8 @@ void Sbar_TeamOverlay (void)
|
|||
team_t *tm;
|
||||
int plow, phigh, pavg;
|
||||
int pw,ph;
|
||||
playerview_t *pv = r_refdef.playerview;
|
||||
|
||||
vrect_t gr = r_refdef.grect;
|
||||
int rank_width = 320-32*2;
|
||||
int startx;
|
||||
int trackplayer;
|
||||
|
@ -3027,11 +3023,11 @@ void Sbar_TeamOverlay (void)
|
|||
// request new ping times every two second
|
||||
if (!cl.teamplay)
|
||||
{
|
||||
Sbar_DeathmatchOverlay(0);
|
||||
Sbar_DeathmatchOverlay(pv, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
y = 0;
|
||||
y = gr.y;
|
||||
|
||||
if (scr_scoreboard_drawtitle.ival)
|
||||
{
|
||||
|
@ -3039,12 +3035,12 @@ void Sbar_TeamOverlay (void)
|
|||
if (pic && R_GetShaderSizes(pic, &pw, &ph, false)>0)
|
||||
{
|
||||
k = (pw * 24) / ph;
|
||||
R2D_ScalePic ((vid.width-k)/2, 0, k, 24, pic);
|
||||
R2D_ScalePic (gr.x+(gr.width-k)/2, y, k, 24, pic);
|
||||
}
|
||||
y += 24;
|
||||
}
|
||||
|
||||
x = l = (vid.width - 320)/2 + 36;
|
||||
x = l = gr.x + (gr.width - 320)/2 + 36;
|
||||
|
||||
startx = x;
|
||||
|
||||
|
@ -3099,7 +3095,7 @@ void Sbar_TeamOverlay (void)
|
|||
// sort the teams
|
||||
Sbar_SortTeams(pv);
|
||||
|
||||
if (cl.spectator)
|
||||
if (pv->spectator)
|
||||
trackplayer = Cam_TrackNum(pv);
|
||||
else
|
||||
trackplayer = pv->playernum;
|
||||
|
@ -3184,7 +3180,7 @@ void Sbar_TeamOverlay (void)
|
|||
}
|
||||
else
|
||||
y += 8;
|
||||
Sbar_DeathmatchOverlay(y);
|
||||
Sbar_DeathmatchOverlay(pv, y-gr.y);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3287,7 +3283,7 @@ enum
|
|||
};
|
||||
|
||||
#define ADDCOLUMN(id) showcolumns |= (1<<id)
|
||||
void Sbar_DeathmatchOverlay (int start)
|
||||
void Sbar_DeathmatchOverlay (playerview_t *pv, int start)
|
||||
{
|
||||
mpic_t *pic;
|
||||
int i, k;
|
||||
|
@ -3299,7 +3295,6 @@ void Sbar_DeathmatchOverlay (int start)
|
|||
int skip = 10;
|
||||
int showcolumns;
|
||||
int startx, rank_width;
|
||||
playerview_t *pv = r_refdef.playerview;
|
||||
|
||||
vrect_t gr = r_refdef.grect;
|
||||
int namesize = (cl.teamplay ? 12*8 : 16*8);
|
||||
|
@ -3753,8 +3748,8 @@ static void Sbar_MiniDeathmatchOverlay (playerview_t *pv)
|
|||
Font_BeginString(font_default, x+24, y, &px, &py);
|
||||
Font_DrawChar ( px, py, CON_WHITEMASK, num[2] | 0xe000);
|
||||
|
||||
if ((cl.spectator && k == pv->cam_spec_track && pv->cam_state != CAM_FREECAM) ||
|
||||
(!cl.spectator && k == pv->playernum))
|
||||
if ((pv->spectator && k == pv->cam_spec_track && pv->cam_state != CAM_FREECAM) ||
|
||||
(!pv->spectator && k == pv->playernum))
|
||||
{
|
||||
Font_BeginString(font_default, x, y, &px, &py);
|
||||
Font_DrawChar ( px, py, CON_WHITEMASK, 16 | 0xe000);
|
||||
|
@ -3812,12 +3807,11 @@ static void Sbar_MiniDeathmatchOverlay (playerview_t *pv)
|
|||
|
||||
}
|
||||
|
||||
void Sbar_CoopIntermission (void)
|
||||
void Sbar_CoopIntermission (playerview_t *pv)
|
||||
{
|
||||
mpic_t *pic;
|
||||
int dig;
|
||||
int num;
|
||||
int pnum = 0; //should be the same for all players.
|
||||
|
||||
sbar_rect.width = vid.width;
|
||||
sbar_rect.height = vid.height;
|
||||
|
@ -3842,13 +3836,13 @@ void Sbar_CoopIntermission (void)
|
|||
R2D_ScalePicAtlas ((sbar_rect.width - 320)/2 + 278,(sbar_rect.height - 200)/2 + 64, 16, 24, sb_nums[0][num%10]);
|
||||
|
||||
//it is assumed that secrits/monsters are going to be constant for any player...
|
||||
Sbar_IntermissionNumber ((sbar_rect.width - 320)/2 + 230 - 24*4, (sbar_rect.height - 200)/2 + 104, cl.playerview[pnum].stats[STAT_SECRETS], 4, 0, false);
|
||||
Sbar_IntermissionNumber ((sbar_rect.width - 320)/2 + 230 - 24*4, (sbar_rect.height - 200)/2 + 104, pv->stats[STAT_SECRETS], 4, 0, false);
|
||||
R2D_ScalePicAtlas ((sbar_rect.width - 320)/2 + 230, (sbar_rect.height - 200)/2 + 104, 16, 24, sb_slash);
|
||||
Sbar_IntermissionNumber ((sbar_rect.width - 320)/2 + 254, (sbar_rect.height - 200)/2 + 104, cl.playerview[pnum].stats[STAT_TOTALSECRETS], 4, 0, true);
|
||||
Sbar_IntermissionNumber ((sbar_rect.width - 320)/2 + 254, (sbar_rect.height - 200)/2 + 104, pv->stats[STAT_TOTALSECRETS], 4, 0, true);
|
||||
|
||||
Sbar_IntermissionNumber ((sbar_rect.width - 320)/2 + 230 - 24*4, (sbar_rect.height - 200)/2 + 144, cl.playerview[pnum].stats[STAT_MONSTERS], 4, 0, false);
|
||||
Sbar_IntermissionNumber ((sbar_rect.width - 320)/2 + 230 - 24*4, (sbar_rect.height - 200)/2 + 144, pv->stats[STAT_MONSTERS], 4, 0, false);
|
||||
R2D_ScalePicAtlas ((sbar_rect.width - 320)/2 + 230,(sbar_rect.height - 200)/2 + 144, 16, 24, sb_slash);
|
||||
Sbar_IntermissionNumber ((sbar_rect.width - 320)/2 + 254, (sbar_rect.height - 200)/2 + 144, cl.playerview[pnum].stats[STAT_TOTALMONSTERS], 4, 0, true);
|
||||
Sbar_IntermissionNumber ((sbar_rect.width - 320)/2 + 254, (sbar_rect.height - 200)/2 + 144, pv->stats[STAT_TOTALMONSTERS], 4, 0, true);
|
||||
}
|
||||
/*
|
||||
==================
|
||||
|
@ -3856,7 +3850,7 @@ Sbar_IntermissionOverlay
|
|||
|
||||
==================
|
||||
*/
|
||||
void Sbar_IntermissionOverlay (void)
|
||||
void Sbar_IntermissionOverlay (playerview_t *pv)
|
||||
{
|
||||
#ifdef VM_UI
|
||||
if (UI_DrawIntermission()>0)
|
||||
|
@ -3866,10 +3860,10 @@ void Sbar_IntermissionOverlay (void)
|
|||
Sbar_Start();
|
||||
|
||||
if (!cls.deathmatch)
|
||||
Sbar_CoopIntermission();
|
||||
else if (cl.teamplay > 0 && !sb_showscores)
|
||||
Sbar_TeamOverlay ();
|
||||
Sbar_CoopIntermission(pv);
|
||||
else if (cl.teamplay > 0 && !pv->sb_showscores)
|
||||
Sbar_TeamOverlay (pv);
|
||||
else
|
||||
Sbar_DeathmatchOverlay (0);
|
||||
Sbar_DeathmatchOverlay (pv, 0);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -33,12 +33,12 @@ qboolean Sbar_UpdateTeamStatus(struct player_info_s *player, char *status);
|
|||
void Sbar_Changed (void);
|
||||
// call whenever any of the client stats represented on the sbar changes
|
||||
|
||||
qboolean Sbar_ShouldDraw(void);
|
||||
qboolean Sbar_ShouldDraw(playerview_t *pv);
|
||||
void Sbar_Draw (playerview_t *pv); //uses the current r_refdef.grect
|
||||
void Sbar_DrawScoreboard (void);
|
||||
void Sbar_DrawScoreboard (playerview_t *pv);
|
||||
// called every frame by screen
|
||||
|
||||
void Sbar_IntermissionOverlay (void);
|
||||
void Sbar_IntermissionOverlay (playerview_t *pv);
|
||||
// called each frame after the level has been completed
|
||||
|
||||
void Sbar_FinaleOverlay (void);
|
||||
|
|
|
@ -4,10 +4,9 @@
|
|||
This is based on Jogi's OpenAL support.
|
||||
Much of it is stripped, to try and get it clean/compliant.
|
||||
|
||||
Missing features:
|
||||
FIXME: listener velocity calculations (currently ugly).
|
||||
FIXME: does not track entity velocities, so no dopler (awkward, quake doesn't move playing sounds at all).
|
||||
FIXME: a capture device would be useful (voice chat).
|
||||
Emscripten/WebAudio is buggy or limited.
|
||||
This means we force distance models and use hacks to avoid bugs in browsers.
|
||||
We also have no doppler with WebAudio.
|
||||
*/
|
||||
|
||||
#ifdef AVAIL_OPENAL
|
||||
|
|
|
@ -627,7 +627,7 @@ void Validation_Auto_Response(int playernum, char *s)
|
|||
Validation_Version();
|
||||
versionresponsetime = Sys_DoubleTime() + 5;
|
||||
}
|
||||
else if (cl.spectator)
|
||||
else if (cl.playerview[0].spectator)
|
||||
return;
|
||||
else if (!strncmp(s, "server", 6) && serverresponsetime < Sys_DoubleTime()) //respond to it.
|
||||
{
|
||||
|
|
|
@ -160,7 +160,7 @@ float V_CalcBob (playerview_t *pv, qboolean queryold)
|
|||
float hspeed, bob;
|
||||
vec3_t hvel;
|
||||
|
||||
if (cl.spectator)
|
||||
if (pv->spectator)
|
||||
return 0;
|
||||
|
||||
if (cl_bobcycle.value <= 0 || cl.intermissionmode != IM_NONE)
|
||||
|
@ -1477,9 +1477,9 @@ void V_CalcRefdef (playerview_t *pv)
|
|||
}
|
||||
|
||||
#ifdef QUAKESTATS
|
||||
if (pv->stats[STAT_HEALTH] < 0 && (!cl.spectator || pv->cam_state == CAM_EYECAM) && v_deathtilt.value) // PF_GIB will also set PF_DEAD
|
||||
if (pv->stats[STAT_HEALTH] < 0 && (!pv->spectator || pv->cam_state == CAM_EYECAM) && v_deathtilt.value) // PF_GIB will also set PF_DEAD
|
||||
{
|
||||
if (!cl.spectator || cl_chasecam.ival)
|
||||
if (!pv->spectator || cl_chasecam.ival)
|
||||
r_refdef.viewangles[ROLL] = 80*v_deathtilt.value; // dead view angle
|
||||
}
|
||||
else
|
||||
|
@ -1980,7 +1980,7 @@ void R_DrawNameTags(void)
|
|||
}
|
||||
}
|
||||
|
||||
if (((!cl.spectator && !cls.demoplayback) || !scr_autoid.ival) && (!cl.teamplay || !scr_autoid_team.ival))
|
||||
if (((!r_refdef.playerview->spectator && !cls.demoplayback) || !scr_autoid.ival) && (!cl.teamplay || !scr_autoid_team.ival))
|
||||
return;
|
||||
if (cls.state != ca_active || !cl.validsequence || cl.intermissionmode != IM_NONE)
|
||||
return;
|
||||
|
@ -2029,13 +2029,13 @@ void R_DrawNameTags(void)
|
|||
|
||||
if (!cl.teamplay || !scr_autoid_team.ival)
|
||||
isteam = false;
|
||||
else if ((cl.teamfortress && !cl.spectator) || cls.protocol == CP_NETQUAKE) //teamfortress should go by their colours instead, because spies. primarily this is to allow enemy spies to appear through walls as well as your own team (note that the qc will also need tinfo stuff for tf, to avoid issues with just checking player names).
|
||||
else if ((cl.teamfortress && !r_refdef.playerview->spectator) || cls.protocol == CP_NETQUAKE) //teamfortress should go by their colours instead, because spies. primarily this is to allow enemy spies to appear through walls as well as your own team (note that the qc will also need tinfo stuff for tf, to avoid issues with just checking player names).
|
||||
isteam = cl.players[i].rbottomcolor == ourcolour;
|
||||
else
|
||||
isteam = !strcmp(cl.players[i].team, ourteam);
|
||||
|
||||
if (!isteam)
|
||||
if ((!cl.spectator && !cls.demoplayback) || !scr_autoid.ival)
|
||||
if ((!r_refdef.playerview->spectator && !cls.demoplayback) || !scr_autoid.ival)
|
||||
continue; //only show our team when playing, too cheaty otherwise.
|
||||
|
||||
SCR_DrawAutoID(nametagorg[i], &cl.players[i], isteam);
|
||||
|
|
|
@ -704,7 +704,8 @@ done:
|
|||
|
||||
static char *Skin_To_TFSkin (char *myskin)
|
||||
{
|
||||
if (!cl.teamfortress || cl.spectator || Q_strncasecmp(myskin, "tf_", 3))
|
||||
playerview_t *pv = &cl.playerview[SP];
|
||||
if (!cl.teamfortress || pv->spectator || Q_strncasecmp(myskin, "tf_", 3))
|
||||
{
|
||||
Q_strncpyz(macro_buf, myskin, sizeof(macro_buf));
|
||||
}
|
||||
|
@ -732,9 +733,10 @@ static char *Macro_TF_Skin (void)
|
|||
//Spike: added these:
|
||||
static char *Macro_ConnectionType (void)
|
||||
{
|
||||
playerview_t *pv = &cl.playerview[SP];
|
||||
if (!cls.state)
|
||||
return "disconnected";
|
||||
if (cl.spectator)
|
||||
if (pv->spectator)
|
||||
return "spectator";
|
||||
return "connected";
|
||||
}
|
||||
|
@ -878,6 +880,7 @@ static void CountNearbyPlayers(qboolean dead)
|
|||
player_state_t *state;
|
||||
player_info_t *info;
|
||||
static int lastframecount = -1;
|
||||
playerview_t *pv = &cl.playerview[SP];
|
||||
|
||||
if (cls.framecount == lastframecount)
|
||||
return;
|
||||
|
@ -885,7 +888,7 @@ static void CountNearbyPlayers(qboolean dead)
|
|||
|
||||
vars.numenemies = vars.numfriendlies = 0;
|
||||
|
||||
if (!cl.spectator && !dead)
|
||||
if (!pv->spectator && !dead)
|
||||
vars.numfriendlies++;
|
||||
|
||||
if (!cl.oldparsecount || !cl.parsecount || cls.state < ca_active)
|
||||
|
@ -894,7 +897,7 @@ static void CountNearbyPlayers(qboolean dead)
|
|||
state = cl.inframes[cl.oldparsecount & UPDATE_MASK].playerstate;
|
||||
info = cl.players;
|
||||
for (i = 0; i < cl.allocated_client_slots; i++, info++, state++) {
|
||||
if (i != cl.playerview[SP].playernum && state->messagenum == cl.oldparsecount && !info->spectator && !ISDEAD(state->frame)) {
|
||||
if (i != pv->playernum && state->messagenum == cl.oldparsecount && !info->spectator && !ISDEAD(state->frame)) {
|
||||
if (cl.teamplay && !strcmp(info->team, TP_PlayerTeam()))
|
||||
vars.numfriendlies++;
|
||||
else
|
||||
|
@ -2183,6 +2186,7 @@ int TP_CategorizeMessage (char *s, int *offset, player_info_t **plr)
|
|||
int flags;
|
||||
player_info_t *player;
|
||||
char *name;
|
||||
playerview_t *pv = &cl.playerview[SP];
|
||||
|
||||
*offset = 0;
|
||||
*plr = NULL;
|
||||
|
@ -2275,9 +2279,9 @@ int TP_CategorizeMessage (char *s, int *offset, player_info_t **plr)
|
|||
!strncmp(name, s+1, len))
|
||||
{
|
||||
// no team messages in teamplay 0, except for our own
|
||||
if (cl.spectator)
|
||||
if (pv->spectator)
|
||||
{
|
||||
unsigned int track = Cam_TrackNum(&cl.playerview[SP]);
|
||||
unsigned int track = Cam_TrackNum(pv);
|
||||
if (i == track || ( cl.teamplay &&
|
||||
!strcmp(cl.players[track].team, player->team)) )
|
||||
{
|
||||
|
@ -2286,8 +2290,8 @@ int TP_CategorizeMessage (char *s, int *offset, player_info_t **plr)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (i == cl.playerview[SP].playernum || ( cl.teamplay &&
|
||||
!strcmp(cl.players[cl.playerview[SP].playernum].team, player->team)) )
|
||||
if (i == pv->playernum || ( cl.teamplay &&
|
||||
!strcmp(cl.players[pv->playernum].team, player->team)) )
|
||||
{
|
||||
flags |= TPM_TEAM;
|
||||
}
|
||||
|
@ -2814,8 +2818,9 @@ static qboolean CheckTrigger (void)
|
|||
int i, count;
|
||||
player_info_t *player;
|
||||
char *myteam;
|
||||
playerview_t *pv = &cl.playerview[SP];
|
||||
|
||||
if (cl.spectator)
|
||||
if (pv->spectator)
|
||||
return false;
|
||||
|
||||
if (tp_forceTriggers.ival)
|
||||
|
@ -2825,9 +2830,9 @@ static qboolean CheckTrigger (void)
|
|||
return false;
|
||||
|
||||
count = 0;
|
||||
myteam = cl.players[cl.playerview[SP].playernum].team;
|
||||
myteam = cl.players[pv->playernum].team;
|
||||
for (i = 0, player= cl.players; i < cl.allocated_client_slots; i++, player++) {
|
||||
if (player->name[0] && !player->spectator && i != cl.playerview[SP].playernum && !strcmp(player->team, myteam))
|
||||
if (player->name[0] && !player->spectator && i != pv->playernum && !strcmp(player->team, myteam))
|
||||
count++;
|
||||
}
|
||||
|
||||
|
@ -2890,13 +2895,14 @@ static void TP_ItemTaken (char *s, int flag, vec3_t org, int entnum, item_t *ite
|
|||
void TP_ParsePlayerInfo(player_state_t *oldstate, player_state_t *state, player_info_t *info)
|
||||
{
|
||||
#ifndef QUAKETC
|
||||
playerview_t *pv = &cl.playerview[SP];
|
||||
// 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()))
|
||||
if (!pv->spectator && cl.teamplay && strcmp(info->team, TP_PlayerTeam()))
|
||||
{
|
||||
qboolean eyes;
|
||||
|
||||
|
@ -2915,11 +2921,11 @@ void TP_ParsePlayerInfo(player_state_t *oldstate, player_state_t *state, player_
|
|||
vars.enemy_powerups |= TP_RING;
|
||||
}
|
||||
}
|
||||
if (!cl.spectator && !cl.teamfortress && info - cl.players == cl.playerview[SP].playernum)
|
||||
if (!pv->spectator && !cl.teamfortress && info - cl.players == pv->playernum)
|
||||
{
|
||||
if ((state->effects & (QWEF_FLAG1|QWEF_FLAG2)) && !(oldstate->effects & (QWEF_FLAG1|QWEF_FLAG2)))
|
||||
{
|
||||
ExecTookTrigger_ (tp_name_flag.string, it_flag, cl.inframes[cl.validsequence & UPDATE_MASK].playerstate[cl.playerview[SP].playernum].origin);
|
||||
ExecTookTrigger_ (tp_name_flag.string, it_flag, cl.inframes[cl.validsequence & UPDATE_MASK].playerstate[pv->playernum].origin);
|
||||
}
|
||||
else if (!(state->effects & (QWEF_FLAG1|QWEF_FLAG2)) && (oldstate->effects & (QWEF_FLAG1|QWEF_FLAG2)))
|
||||
{
|
||||
|
@ -2935,8 +2941,9 @@ void TP_CheckPickupSound (char *s, vec3_t org, int seat)
|
|||
#ifndef QUAKETC
|
||||
int entnum;
|
||||
item_t *item;
|
||||
playerview_t *pv = &cl.playerview[seat];
|
||||
//if we're spectating, we don't want to do any actual triggers, so pretend it was someone else.
|
||||
if (cl.spectator)
|
||||
if (pv->spectator)
|
||||
seat = -1;
|
||||
|
||||
//FIXME: on items/itembk2.wav kill relevant item timer.
|
||||
|
@ -2992,17 +2999,17 @@ more:
|
|||
if (vars.stat_framecounts[STAT_ITEMS] == cls.framecount)
|
||||
{
|
||||
if (vars.items & ~vars.olditems & IT_LIGHTNING)
|
||||
TP_ItemTaken (tp_name_lg.string, it_lg, cl.playerview[SP].simorg, entnum, item, seat);
|
||||
TP_ItemTaken (tp_name_lg.string, it_lg, pv->simorg, entnum, item, seat);
|
||||
else if (vars.items & ~vars.olditems & IT_ROCKET_LAUNCHER)
|
||||
TP_ItemTaken (tp_name_rl.string, it_rl, cl.playerview[SP].simorg, entnum, item, seat);
|
||||
TP_ItemTaken (tp_name_rl.string, it_rl, pv->simorg, entnum, item, seat);
|
||||
else if (vars.items & ~vars.olditems & IT_GRENADE_LAUNCHER)
|
||||
TP_ItemTaken (tp_name_gl.string, it_gl, cl.playerview[SP].simorg, entnum, item, seat);
|
||||
TP_ItemTaken (tp_name_gl.string, it_gl, pv->simorg, entnum, item, seat);
|
||||
else if (vars.items & ~vars.olditems & IT_SUPER_NAILGUN)
|
||||
TP_ItemTaken (tp_name_sng.string, it_sng, cl.playerview[SP].simorg, entnum, item, seat);
|
||||
TP_ItemTaken (tp_name_sng.string, it_sng, pv->simorg, entnum, item, seat);
|
||||
else if (vars.items & ~vars.olditems & IT_NAILGUN)
|
||||
TP_ItemTaken (tp_name_ng.string, it_ng, cl.playerview[SP].simorg, entnum, item, seat);
|
||||
TP_ItemTaken (tp_name_ng.string, it_ng, pv->simorg, entnum, item, seat);
|
||||
else if (vars.items & ~vars.olditems & IT_SUPER_SHOTGUN)
|
||||
TP_ItemTaken (tp_name_ssg.string, it_ssg, cl.playerview[SP].simorg, entnum, item, seat);
|
||||
TP_ItemTaken (tp_name_ssg.string, it_ssg, pv->simorg, entnum, item, seat);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -3020,11 +3027,11 @@ more:
|
|||
TP_ItemTaken (item->cvar->string, item->itemflag, org, entnum, item, seat);
|
||||
else if (seat >= 0)
|
||||
{
|
||||
if (armor_updated && cl.playerview[SP].stats[STAT_ARMOR] == 100)
|
||||
if (armor_updated && pv->stats[STAT_ARMOR] == 100)
|
||||
TP_ItemTaken (tp_name_ga.string, it_ga, org, entnum, NULL, seat);
|
||||
else if (armor_updated && cl.playerview[SP].stats[STAT_ARMOR] == 150)
|
||||
else if (armor_updated && pv->stats[STAT_ARMOR] == 150)
|
||||
TP_ItemTaken (tp_name_ya.string, it_ya, org, entnum, NULL, seat);
|
||||
else if (armor_updated && cl.playerview[SP].stats[STAT_ARMOR] == 200)
|
||||
else if (armor_updated && pv->stats[STAT_ARMOR] == 200)
|
||||
TP_ItemTaken (tp_name_ra.string, it_ra, org, entnum, NULL, seat);
|
||||
}
|
||||
return;
|
||||
|
@ -3216,6 +3223,7 @@ static void TP_FindPoint (void)
|
|||
item_vis_t visitem;
|
||||
extern cvar_t v_viewheight;
|
||||
int oldskip = pmove.skipent;
|
||||
playerview_t *pv = &cl.playerview[SP];
|
||||
|
||||
if (vars.pointtime == realtime)
|
||||
return;
|
||||
|
@ -3223,11 +3231,11 @@ static void TP_FindPoint (void)
|
|||
if (!cl.validsequence)
|
||||
goto nothing;
|
||||
|
||||
pmove.skipent = cl.playerview[SP].viewentity;
|
||||
pmove.skipent = pv->viewentity;
|
||||
|
||||
ang[0] = cl.playerview[SP].viewangles[0]; ang[1] = cl.playerview[SP].viewangles[1]; ang[2] = 0;
|
||||
ang[0] = pv->viewangles[0]; ang[1] = pv->viewangles[1]; ang[2] = 0;
|
||||
AngleVectors (ang, visitem.forward, visitem.right, visitem.up);
|
||||
VectorCopy (cl.playerview[SP].simorg, visitem.vieworg);
|
||||
VectorCopy (pv->simorg, visitem.vieworg);
|
||||
visitem.vieworg[2] += 22 + (v_viewheight.value ? bound (-7, v_viewheight.value, 4) : 0);
|
||||
|
||||
pointflags_dmm = pointflags;
|
||||
|
@ -3274,7 +3282,7 @@ static void TP_FindPoint (void)
|
|||
info = cl.players;
|
||||
for (j = 0; j < cl.allocated_client_slots; j++, info++, state++)
|
||||
{
|
||||
if (state->messagenum != cl.parsecount || j == cl.playerview[SP].playernum || info->spectator)
|
||||
if (state->messagenum != cl.parsecount || j == pv->playernum || info->spectator)
|
||||
continue;
|
||||
|
||||
if (
|
||||
|
@ -3325,7 +3333,7 @@ static void TP_FindPoint (void)
|
|||
|
||||
if (eyes)
|
||||
name = tp_name_eyes.string; //duck on 2night2
|
||||
else if (cl.spectator)
|
||||
else if (pv->spectator)
|
||||
name = bestinfo->name;
|
||||
else if (teammate)
|
||||
name = tp_name_teammate.string[0] ? tp_name_teammate.string : "teammate";
|
||||
|
@ -3341,7 +3349,7 @@ static void TP_FindPoint (void)
|
|||
|
||||
if (eyes)
|
||||
name = tp_name_eyes.string;
|
||||
else if (cl.spectator || (teammate && !tp_name_teammate.string[0]))
|
||||
else if (pv->spectator || (teammate && !tp_name_teammate.string[0]))
|
||||
name = bestinfo->name;
|
||||
else
|
||||
name = teammate ? tp_name_teammate.string : tp_name_enemy.string;
|
||||
|
@ -3390,6 +3398,7 @@ void TP_UpdateAutoStatus(void)
|
|||
char newstatusbuf[sizeof(vars.autoteamstatus)];
|
||||
char *newstatus;
|
||||
int level;
|
||||
playerview_t *pv = &cl.playerview[SP];
|
||||
|
||||
if (vars.autoteamstatus_time > realtime || !*tp_autostatus.string)
|
||||
return;
|
||||
|
@ -3415,7 +3424,7 @@ void TP_UpdateAutoStatus(void)
|
|||
if (tp_autostatus.latched_string)
|
||||
return;
|
||||
|
||||
if (cl.spectator) //don't spam as spectators, that's just silly
|
||||
if (pv->spectator) //don't spam as spectators, that's just silly
|
||||
return;
|
||||
if (!cl.teamplay) //don't spam in deathmatch, that's just pointless
|
||||
return;
|
||||
|
@ -3427,6 +3436,7 @@ void TP_UpdateAutoStatus(void)
|
|||
void TP_StatChanged (int stat, int value)
|
||||
{
|
||||
#ifdef QUAKESTATS
|
||||
playerview_t *pv = &cl.playerview[SP];
|
||||
int i;
|
||||
if (stat == STAT_HEALTH)
|
||||
{
|
||||
|
@ -3437,14 +3447,14 @@ void TP_StatChanged (int stat, int value)
|
|||
// we just respawned
|
||||
vars.respawntrigger_time = realtime;
|
||||
|
||||
if (!cl.spectator && CountTeammates())
|
||||
if (!pv->spectator && CountTeammates())
|
||||
TP_ExecTrigger ("f_respawn", false);
|
||||
}
|
||||
}
|
||||
else if (vars.health > 0)
|
||||
{ // We have just died
|
||||
|
||||
vars.droppedweapon = cl.playerview[SP].stats[STAT_ACTIVEWEAPON];
|
||||
vars.droppedweapon = pv->stats[STAT_ACTIVEWEAPON];
|
||||
|
||||
vars.deathtrigger_time = realtime;
|
||||
strcpy (vars.lastdeathloc, Macro_Location());
|
||||
|
@ -3453,9 +3463,9 @@ void TP_StatChanged (int stat, int value)
|
|||
vars.last_numenemies = vars.numenemies;
|
||||
vars.last_numfriendlies = vars.numfriendlies;
|
||||
|
||||
if (!cl.spectator && CountTeammates())
|
||||
if (!pv->spectator && CountTeammates())
|
||||
{
|
||||
if (cl.teamfortress && (cl.playerview[SP].stats[STAT_ITEMS] & (IT_KEY1|IT_KEY2))
|
||||
if (cl.teamfortress && (pv->stats[STAT_ITEMS] & (IT_KEY1|IT_KEY2))
|
||||
&& Cmd_AliasExist("f_flagdeath", RESTRICT_LOCAL))
|
||||
TP_ExecTrigger ("f_flagdeath", false);
|
||||
else
|
||||
|
@ -3469,14 +3479,14 @@ void TP_StatChanged (int stat, int value)
|
|||
i = value &~ vars.items;
|
||||
|
||||
if (i & (IT_KEY1|IT_KEY2)) {
|
||||
if (cl.teamfortress && !cl.spectator)
|
||||
if (cl.teamfortress && !pv->spectator)
|
||||
{
|
||||
ExecTookTrigger_ (tp_name_flag.string, it_flag,
|
||||
cl.inframes[cl.validsequence&UPDATE_MASK].playerstate[cl.playerview[SP].playernum].origin);
|
||||
cl.inframes[cl.validsequence&UPDATE_MASK].playerstate[pv->playernum].origin);
|
||||
}
|
||||
}
|
||||
|
||||
if (!cl.spectator && cl.teamfortress && ~value & vars.items & (IT_KEY1|IT_KEY2))
|
||||
if (!pv->spectator && cl.teamfortress && ~value & vars.items & (IT_KEY1|IT_KEY2))
|
||||
{
|
||||
vars.lastdrop_time = realtime;
|
||||
strcpy (vars.lastdroploc, Macro_Location());
|
||||
|
@ -3487,9 +3497,9 @@ void TP_StatChanged (int stat, int value)
|
|||
}
|
||||
else if (stat == STAT_ACTIVEWEAPON)
|
||||
{
|
||||
if (cl.playerview[SP].stats[STAT_ACTIVEWEAPON] != vars.activeweapon)
|
||||
if (pv->stats[STAT_ACTIVEWEAPON] != vars.activeweapon)
|
||||
TP_ExecTrigger ("f_weaponchange", false);
|
||||
vars.activeweapon = cl.playerview[SP].stats[STAT_ACTIVEWEAPON];
|
||||
vars.activeweapon = pv->stats[STAT_ACTIVEWEAPON];
|
||||
}
|
||||
#endif
|
||||
vars.stat_framecounts[stat] = cls.framecount;
|
||||
|
@ -3709,6 +3719,7 @@ void TP_Init (void)
|
|||
|
||||
qboolean TP_SuppressMessage(char *buf) {
|
||||
char *s;
|
||||
playerview_t *pv = &cl.playerview[SP];
|
||||
|
||||
for (s = buf; *s && *s != 0x7f; s++)
|
||||
;
|
||||
|
@ -3717,7 +3728,7 @@ qboolean TP_SuppressMessage(char *buf) {
|
|||
*s++ = '\n';
|
||||
*s++ = 0;
|
||||
|
||||
return (!cls.demoplayback && !cl.spectator && *s - 'A' == cl.playerview[SP].playernum);
|
||||
return (!cls.demoplayback && !pv->spectator && *s - 'A' == pv->playernum);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -3728,6 +3739,7 @@ void CL_Say (qboolean team, char *extra)
|
|||
{
|
||||
extern cvar_t cl_fakename;
|
||||
char text[2048], sendtext[2048], *s;
|
||||
playerview_t *pv = &cl.playerview[SP];
|
||||
|
||||
if (Cmd_Argc() < 2)
|
||||
{
|
||||
|
@ -3748,7 +3760,7 @@ void CL_Say (qboolean team, char *extra)
|
|||
Q_strncpyz (text, TP_ParseFunChars (s), sizeof(text));
|
||||
|
||||
sendtext[0] = 0;
|
||||
if (team && !cl.spectator && cl_fakename.string[0] &&
|
||||
if (team && !pv->spectator && cl_fakename.string[0] &&
|
||||
!strchr(s, '\x0d') /* explicit $\ in message overrides cl_fakename */)
|
||||
{
|
||||
char buf[1024];
|
||||
|
@ -3803,7 +3815,7 @@ void CL_Say (qboolean team, char *extra)
|
|||
if (team)
|
||||
plrflags |= 2;
|
||||
|
||||
CL_PrintChat(&cl.players[cl.playerview[SP].playernum], text, plrflags);
|
||||
CL_PrintChat(&cl.players[pv->playernum], text, plrflags);
|
||||
}
|
||||
|
||||
//strip out the extra markup
|
||||
|
@ -3831,7 +3843,7 @@ void CL_Say (qboolean team, char *extra)
|
|||
*d = '\0';
|
||||
|
||||
//mark the message so that we ignore it when we get the echo.
|
||||
strlcat (sendtext, va("\x7f!%c", 'A'+cl.playerview[SP].playernum), sizeof(sendtext));
|
||||
strlcat (sendtext, va("\x7f!%c", 'A'+pv->playernum), sizeof(sendtext));
|
||||
}
|
||||
|
||||
#ifdef Q3CLIENT
|
||||
|
|
|
@ -23,7 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
// release version
|
||||
#define FTE_VER_MAJOR 1
|
||||
#define FTE_VER_MINOR 5
|
||||
#define FTE_VER_MINOR 6
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
#define MACOSX
|
||||
|
@ -281,8 +281,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
// #define HLCLIENT 7 //we can run HL gamecode (not protocol compatible, set to 6 or 7)
|
||||
// #define HLSERVER 140 //we can run HL gamecode (not protocol compatible, set to 138 or 140)
|
||||
#define NQPROT //server and client are capable of using quake1/netquake protocols. (qw is still prefered. uses the command 'nqconnect')
|
||||
#define WEBSERVER //http/ftp servers
|
||||
#define WEBCLIENT //http/ftp clients.
|
||||
// #define WEBSERVER //http server
|
||||
#define FTPSERVER //ftp server
|
||||
#define WEBCLIENT //http clients.
|
||||
#define RUNTIMELIGHTING //calculate lit/lux files the first time the map is loaded and doesn't have a loadable lit.
|
||||
// #define QTERM //qterm... adds a console command that allows running programs from within quake - bit like xterm.
|
||||
#define CL_MASTER //query master servers and stuff for a dynamic server listing.
|
||||
|
|
|
@ -1100,7 +1100,7 @@ static vfsfile_t *QDECL FSZIP_OpenVFS(searchpathfuncs_t *handle, flocation_t *lo
|
|||
if (flags & ZFL_DEFLATED)
|
||||
{
|
||||
#ifdef ZIPCRYPT
|
||||
//FIXME: Cvar_Get is not threadsafe.
|
||||
//FIXME: Cvar_Get is not threadsafe, and nor is accessing the cvar...
|
||||
char *password = (flags & ZFL_WEAKENCRYPT)?Cvar_Get("fs_zip_password", "thisispublic", 0, "Filesystem")->string:NULL;
|
||||
#else
|
||||
char *password = NULL;
|
||||
|
|
|
@ -95,9 +95,9 @@ typedef int (VARGS gnutls_certificate_verify_function)(gnutls_session_t session)
|
|||
#else
|
||||
#include <gnutls/gnutls.h>
|
||||
#if GNUTLS_VERSION_MAJOR >= 3 && defined(HAVE_DTLS)
|
||||
#include <gnutls/dtls.h>
|
||||
#include <gnutls/dtls.h>
|
||||
#else
|
||||
#undef HAVE_DTLS
|
||||
#undef HAVE_DTLS
|
||||
#endif
|
||||
#define gnutls_connection_end_t unsigned int
|
||||
|
||||
|
|
|
@ -1866,10 +1866,11 @@ int Plug_ConnectionlessClientPacket(char *buffer, int size)
|
|||
void Plug_SBar(playerview_t *pv)
|
||||
{
|
||||
#ifdef QUAKEHUD
|
||||
extern qboolean sb_showscores, sb_showteamscores;
|
||||
#define sb_showscores pv->sb_showscores
|
||||
#define sb_showteamscores pv->sb_showteamscores
|
||||
#else
|
||||
#define sb_showscores 0
|
||||
#define sb_showteamscores 0
|
||||
#define sb_showscores 0
|
||||
#define sb_showteamscores 0
|
||||
#endif
|
||||
|
||||
plugin_t *oc=currentplug;
|
||||
|
@ -1877,7 +1878,7 @@ void Plug_SBar(playerview_t *pv)
|
|||
int cleared = false;
|
||||
int hudmode;
|
||||
|
||||
if (!Sbar_ShouldDraw())
|
||||
if (!Sbar_ShouldDraw(pv))
|
||||
{
|
||||
SCR_TileClear (0);
|
||||
return;
|
||||
|
@ -1935,9 +1936,9 @@ void Plug_SBar(playerview_t *pv)
|
|||
}
|
||||
}
|
||||
|
||||
if (!(ret & 2) && pv == cl.playerview)
|
||||
if (!(ret & 2))
|
||||
{
|
||||
Sbar_DrawScoreboard();
|
||||
Sbar_DrawScoreboard(pv);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -279,10 +279,15 @@ void D3D11_UploadLightmap(lightmapinfo_t *lm)
|
|||
mips.mip[0].width = lm->width;
|
||||
mips.mip[0].height = lm->height;
|
||||
mips.mip[0].datasize = lm->width*lm->height*4;
|
||||
if (lightmap_bgra)
|
||||
switch (lightmap_fmt)
|
||||
{
|
||||
case TF_BGRA32:
|
||||
mips.encoding = PTI_BGRX8;
|
||||
else
|
||||
mips.encoding = PTI_RGBX8;
|
||||
break;
|
||||
case TF_RGBA32:
|
||||
mips.encoding = PTI_RGBX8;
|
||||
break;
|
||||
}
|
||||
mips.mipcount = 1;
|
||||
D3D11_LoadTextureMips(tex, &mips);
|
||||
tex->width = lm->width;
|
||||
|
|
|
@ -886,7 +886,7 @@ qboolean D3D8_VID_ApplyGammaRamps (unsigned int gammarampsize, unsigned short *
|
|||
IDirect3DDevice8_SetGammaRamp(pD3DDev8, D3DSGR_NO_CALIBRATION, (D3DGAMMARAMP *)ramps);
|
||||
return true;
|
||||
}
|
||||
static char *(D3D8_VID_GetRGBInfo) (int *truevidwidth, int *truevidheight, enum uploadfmt *fmt)
|
||||
static char *(D3D8_VID_GetRGBInfo) (int *bytestride, int *truevidwidth, int *truevidheight, enum uploadfmt *fmt)
|
||||
{
|
||||
//FIXME: no screenshots
|
||||
return NULL;
|
||||
|
@ -921,6 +921,7 @@ static char *(D3D8_VID_GetRGBInfo) (int *truevidwidth, int *truevidheight, enu
|
|||
*fmt = TF_RGB24;
|
||||
|
||||
// read surface rect and convert 32 bgra to 24 rgb and flip
|
||||
//FIXME: shouldn't need to convert+flip any more. just return it as upside-down bgra or whatever
|
||||
c = desc.Width*desc.Height*3;
|
||||
p = (qbyte *)rect.pBits;
|
||||
|
||||
|
@ -935,6 +936,7 @@ static char *(D3D8_VID_GetRGBInfo) (int *truevidwidth, int *truevidheight, enu
|
|||
p += rect.Pitch;
|
||||
}
|
||||
|
||||
*bytestride = desc.Width*3;
|
||||
*truevidwidth = desc.Width;
|
||||
*truevidheight = desc.Height;
|
||||
}
|
||||
|
|
|
@ -67,6 +67,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iqm", "..\..\iqm\iqm.vcproj
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gmake", "gmake.vcproj", "{0B1B2549-24DE-4FF2-844B-7A93ED5CF919}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "terrorgen", "..\..\plugins\terrorgen\terrorgen.vcproj", "{1E65A0D3-3371-4602-A69C-53BA389FFBD9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
D3DDebug|Win32 = D3DDebug|Win32
|
||||
|
@ -1094,6 +1096,48 @@ Global
|
|||
{0B1B2549-24DE-4FF2-844B-7A93ED5CF919}.VkRelease|Win32.ActiveCfg = Release|Win32
|
||||
{0B1B2549-24DE-4FF2-844B-7A93ED5CF919}.VkRelease|Win32.Build.0 = Release|Win32
|
||||
{0B1B2549-24DE-4FF2-844B-7A93ED5CF919}.VkRelease|x64.ActiveCfg = Release|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.D3DDebug|Win32.ActiveCfg = Debug|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.D3DDebug|Win32.Build.0 = Debug|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.D3DDebug|x64.ActiveCfg = Debug|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.D3DRelease|Win32.ActiveCfg = Release|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.D3DRelease|Win32.Build.0 = Release|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.D3DRelease|x64.ActiveCfg = Release|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.Debug Dedicated Server|Win32.Build.0 = Debug|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.GLDebug|Win32.ActiveCfg = Debug|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.GLDebug|Win32.Build.0 = Debug|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.GLDebug|x64.ActiveCfg = Debug|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.GLRelease|Win32.ActiveCfg = Release|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.GLRelease|Win32.Build.0 = Release|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.GLRelease|x64.ActiveCfg = Release|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.MDebug|Win32.ActiveCfg = Debug|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.MDebug|Win32.Build.0 = Debug|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.MDebug|x64.ActiveCfg = Debug|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.MinGLDebug|Win32.ActiveCfg = Debug|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.MinGLDebug|Win32.Build.0 = Debug|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.MinGLDebug|x64.ActiveCfg = Debug|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.MinGLRelease|Win32.ActiveCfg = Release|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.MinGLRelease|Win32.Build.0 = Release|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.MinGLRelease|x64.ActiveCfg = Release|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.MRelease|Win32.ActiveCfg = Release|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.MRelease|Win32.Build.0 = Release|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.MRelease|x64.ActiveCfg = Release|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.Release Dedicated Server|Win32.ActiveCfg = Release|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.Release Dedicated Server|Win32.Build.0 = Release|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.Release Dedicated Server|x64.ActiveCfg = Release|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.Release|Win32.Build.0 = Release|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.Release|x64.ActiveCfg = Release|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.VkDebug|Win32.ActiveCfg = Debug|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.VkDebug|Win32.Build.0 = Debug|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.VkDebug|x64.ActiveCfg = Debug|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.VkRelease|Win32.ActiveCfg = Release|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.VkRelease|Win32.Build.0 = Release|Win32
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9}.VkRelease|x64.ActiveCfg = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -1118,6 +1162,7 @@ Global
|
|||
{F756A3D2-025A-43D4-9829-4074753B774B} = {8CED01C6-2C61-4EC5-90B6-574D9756D773}
|
||||
{909E9AE0-0617-469C-954E-1ED09367F90E} = {8CED01C6-2C61-4EC5-90B6-574D9756D773}
|
||||
{E6CDA919-628B-45BF-A5DB-FB55179D6443} = {8CED01C6-2C61-4EC5-90B6-574D9756D773}
|
||||
{1E65A0D3-3371-4602-A69C-53BA389FFBD9} = {8CED01C6-2C61-4EC5-90B6-574D9756D773}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
AMDCaProjectFile = C:\Games\Quake\wip\engine\dotnet2005\CodeAnalyst\ftequake.caw
|
||||
|
|
|
@ -4985,20 +4985,15 @@ static void BE_UpdateLightmaps(void)
|
|||
int lmidx;
|
||||
int glformat, gltype;
|
||||
int internalformat = GL_RGBA;
|
||||
switch (lightmap_bytes)
|
||||
switch (lightmap_fmt)
|
||||
{
|
||||
case 4:
|
||||
glformat = lightmap_bgra?GL_BGRA_EXT:GL_RGBA;
|
||||
gltype = GL_UNSIGNED_INT_8_8_8_8_REV;
|
||||
break;
|
||||
case 3:
|
||||
glformat = lightmap_bgra?GL_BGR_EXT:GL_RGB;
|
||||
gltype = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
default:
|
||||
glformat = GL_LUMINANCE;
|
||||
gltype = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
case TF_INVALID: return;
|
||||
default: Sys_Error("Bad lightmap_fmt\n"); return;
|
||||
case TF_BGRA32: glformat = GL_BGRA_EXT; gltype = GL_UNSIGNED_INT_8_8_8_8_REV; break;
|
||||
// case TF_RGBA32: glformat = GL_RGBA; gltype = GL_UNSIGNED_INT_8_8_8_8_REV; break;
|
||||
// case TF_BGR24: glformat = GL_BGR_EXT; gltype = GL_UNSIGNED_BYTE; break;
|
||||
case TF_RGB24: glformat = GL_RGB; gltype = GL_UNSIGNED_BYTE; break;
|
||||
case TF_LUM8: glformat = GL_LUMINANCE;gltype = GL_UNSIGNED_BYTE; break;
|
||||
}
|
||||
if (gl_config.gles)
|
||||
internalformat = glformat;
|
||||
|
@ -5025,16 +5020,12 @@ static void BE_UpdateLightmaps(void)
|
|||
GL_MTBind(0, GL_TEXTURE_2D, lm->lightmap_texture);
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
qglTexImage2D(GL_TEXTURE_2D, 0, internalformat,
|
||||
lm->width, lm->height, 0, glformat, gltype,
|
||||
lm->lightmaps);
|
||||
qglTexImage2D(GL_TEXTURE_2D, 0, internalformat, lm->width, lm->height, 0, glformat, gltype, lm->lightmaps);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_MTBind(0, GL_TEXTURE_2D, lm->lightmap_texture);
|
||||
qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, t,
|
||||
lm->width, b-t, glformat, gltype,
|
||||
lm->lightmaps+t *lm->width*lightmap_bytes);
|
||||
qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, t, lm->width, b-t, glformat, gltype, lm->lightmaps+t*lm->width*lightmap_bytes);
|
||||
}
|
||||
lm->modified = false;
|
||||
lm->rectchange.l = lm->width;
|
||||
|
|
|
@ -158,11 +158,14 @@ static qboolean QDECL Terr_InitLightmap(hmsection_t *s, qboolean initialise)
|
|||
if (s->lightmap < 0)
|
||||
{
|
||||
struct lmsect_s *lms;
|
||||
if (!hm->unusedlmsects)
|
||||
Sys_LockMutex(com_resourcemutex);
|
||||
while (!hm->unusedlmsects)
|
||||
{
|
||||
int lm;
|
||||
int i;
|
||||
Sys_UnlockMutex(com_resourcemutex);
|
||||
lm = Surf_NewLightmaps(1, SECTTEXSIZE*LMCHUNKS, SECTTEXSIZE*LMCHUNKS, false);
|
||||
Sys_LockMutex(com_resourcemutex);
|
||||
for (i = 0; i < LMCHUNKS*LMCHUNKS; i++)
|
||||
{
|
||||
lms = BZ_Malloc(sizeof(*lms));
|
||||
|
@ -184,6 +187,7 @@ static qboolean QDECL Terr_InitLightmap(hmsection_t *s, qboolean initialise)
|
|||
|
||||
hm->numunusedlmsects--;
|
||||
hm->numusedlmsects++;
|
||||
Sys_UnlockMutex(com_resourcemutex);
|
||||
|
||||
Z_Free(lms);
|
||||
initialise = true;
|
||||
|
@ -2070,6 +2074,9 @@ void Terr_PurgeTerrainModel(model_t *mod, qboolean lightmapsonly, qboolean light
|
|||
int cx, cy;
|
||||
int sx, sy;
|
||||
|
||||
COM_WorkerFullSync(); //should probably be inside the caller or something. make sure there's no loaders still loading lightmaps when lightmaps are going to be nuked.
|
||||
|
||||
|
||||
validatelinks(&hm->recycle);
|
||||
|
||||
// Con_Printf("PrePurge: %i lm chunks used, %i unused\n", hm->numusedlmsects, hm->numunusedlmsects);
|
||||
|
@ -2177,6 +2184,7 @@ void Terr_FreeModel(model_t *mod)
|
|||
hm->entities = n;
|
||||
}
|
||||
Sys_DestroyMutex(hm->entitylock);
|
||||
Z_Free(hm->seed);
|
||||
Z_Free(hm);
|
||||
mod->terrain = NULL;
|
||||
}
|
||||
|
@ -3015,6 +3023,8 @@ void Terr_DrawTerrainModel (batch_t **batches, entity_t *e)
|
|||
else
|
||||
culldist = 999999999999999.f;
|
||||
|
||||
if (culldist < hm->maxdrawdist)
|
||||
culldist = hm->maxdrawdist;
|
||||
if (culldist > r_refdef.maxdist && r_refdef.maxdist>0)
|
||||
culldist = r_refdef.maxdist;
|
||||
|
||||
|
@ -4828,9 +4838,11 @@ void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
|
||||
G_FLOAT(OFS_RETURN) = 0;
|
||||
|
||||
if (!mod || !mod->terrain)
|
||||
if (!mod)
|
||||
return;
|
||||
if (!mod->terrain)
|
||||
{
|
||||
if (mod && mod->loadstate == MLS_LOADING)
|
||||
if (mod->loadstate == MLS_LOADING)
|
||||
COM_WorkerPartialSync(mod, &mod->loadstate, MLS_LOADING);
|
||||
}
|
||||
if (mod->loadstate != MLS_LOADED)
|
||||
|
@ -5258,6 +5270,25 @@ void Terr_ParseEntityLump(model_t *mod, heightmap_t *heightmap)
|
|||
heightmap->culldistance = atof(value);
|
||||
heightmap->culldistance *= heightmap->culldistance;
|
||||
}
|
||||
else if (!strcmp("drawdist", key))
|
||||
heightmap->maxdrawdist = atof(value);
|
||||
else if (!strcmp("seed", key))
|
||||
{
|
||||
Z_Free(heightmap->seed);
|
||||
heightmap->seed = Z_StrDup(value);
|
||||
}
|
||||
else if (!strcmp("exterior", key))
|
||||
{
|
||||
heightmap->legacyterrain = false;
|
||||
if (!strcmp(value, "empty") || !strcmp(value, ""))
|
||||
heightmap->exteriorcontents = FTECONTENTS_EMPTY;
|
||||
else if (!strcmp(value, "sky"))
|
||||
heightmap->exteriorcontents = FTECONTENTS_SKY;
|
||||
else if (!strcmp(value, "lava"))
|
||||
heightmap->exteriorcontents = FTECONTENTS_LAVA;
|
||||
else //if (!strcmp(value, "solid"))
|
||||
heightmap->exteriorcontents = FTECONTENTS_SOLID;
|
||||
}
|
||||
else if (!strcmp("skybox", key))
|
||||
Q_strncpyz(heightmap->skyname, value, sizeof(heightmap->skyname));
|
||||
else if (!strcmp("tiles", key))
|
||||
|
@ -5569,69 +5600,65 @@ void Terr_Brush_Draw(heightmap_t *hm, batch_t **batches, entity_t *e)
|
|||
|
||||
in = br->faces[j].lightdata;
|
||||
out = lm->lightmaps + (br->faces[j].lmbase[1] * lm->width + br->faces[j].lmbase[0]) * lightmap_bytes;
|
||||
if (lightmap_bytes == 4)
|
||||
switch(lightmap_fmt)
|
||||
{
|
||||
if (lightmap_bgra)
|
||||
default:
|
||||
Sys_Error("Bad lightmap_fmt\n");
|
||||
break;
|
||||
case TF_BGRA32:
|
||||
for (t = 0; t < br->faces[j].lmextents[1]; t++)
|
||||
{
|
||||
for (t = 0; t < br->faces[j].lmextents[1]; t++)
|
||||
for (s = 0; s < br->faces[j].lmextents[0]; s++)
|
||||
{
|
||||
for (s = 0; s < br->faces[j].lmextents[0]; s++)
|
||||
{
|
||||
*out++ = in[2];
|
||||
*out++ = in[1];
|
||||
*out++ = in[0];
|
||||
*out++ = 0xff;
|
||||
in+=3;
|
||||
}
|
||||
out += (lm->width - br->faces[j].lmextents[0]) * 4;
|
||||
*out++ = in[2];
|
||||
*out++ = in[1];
|
||||
*out++ = in[0];
|
||||
*out++ = 0xff;
|
||||
in+=3;
|
||||
}
|
||||
out += (lm->width - br->faces[j].lmextents[0]) * 4;
|
||||
}
|
||||
else
|
||||
break;
|
||||
/*case TF_RGBA32:
|
||||
for (t = 0; t < br->faces[j].lmextents[1]; t++)
|
||||
{
|
||||
for (t = 0; t < br->faces[j].lmextents[1]; t++)
|
||||
for (s = 0; s < br->faces[j].lmextents[0]; s++)
|
||||
{
|
||||
for (s = 0; s < br->faces[j].lmextents[0]; s++)
|
||||
{
|
||||
*out++ = in[0];
|
||||
*out++ = in[1];
|
||||
*out++ = in[2];
|
||||
*out++ = 0xff;
|
||||
in+=3;
|
||||
}
|
||||
out += (lm->width - br->faces[j].lmextents[0]) * 4;
|
||||
*out++ = in[0];
|
||||
*out++ = in[1];
|
||||
*out++ = in[2];
|
||||
*out++ = 0xff;
|
||||
in+=3;
|
||||
}
|
||||
out += (lm->width - br->faces[j].lmextents[0]) * 4;
|
||||
}
|
||||
}
|
||||
else if (lightmap_bytes == 3)
|
||||
{
|
||||
if (lightmap_bgra)
|
||||
break;*/
|
||||
/*case TF_BGR24:
|
||||
for (t = 0; t < br->faces[j].lmextents[1]; t++)
|
||||
{
|
||||
for (t = 0; t < br->faces[j].lmextents[1]; t++)
|
||||
for (s = 0; s < br->faces[j].lmextents[0]; s++)
|
||||
{
|
||||
for (s = 0; s < br->faces[j].lmextents[0]; s++)
|
||||
{
|
||||
*out++ = in[2];
|
||||
*out++ = in[1];
|
||||
*out++ = in[0];
|
||||
in+=3;
|
||||
}
|
||||
out += (lm->width - br->faces[j].lmextents[0]) * 3;
|
||||
*out++ = in[2];
|
||||
*out++ = in[1];
|
||||
*out++ = in[0];
|
||||
in+=3;
|
||||
}
|
||||
out += (lm->width - br->faces[j].lmextents[0]) * 3;
|
||||
}
|
||||
else
|
||||
break;*/
|
||||
case TF_RGB24:
|
||||
for (t = 0; t < br->faces[j].lmextents[1]; t++)
|
||||
{
|
||||
for (t = 0; t < br->faces[j].lmextents[1]; t++)
|
||||
for (s = 0; s < br->faces[j].lmextents[0]; s++)
|
||||
{
|
||||
for (s = 0; s < br->faces[j].lmextents[0]; s++)
|
||||
{
|
||||
*out++ = in[0];
|
||||
*out++ = in[1];
|
||||
*out++ = in[2];
|
||||
in+=3;
|
||||
}
|
||||
out += (lm->width - br->faces[j].lmextents[0]) * 3;
|
||||
*out++ = in[0];
|
||||
*out++ = in[1];
|
||||
*out++ = in[2];
|
||||
in+=3;
|
||||
}
|
||||
out += (lm->width - br->faces[j].lmextents[0]) * 3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6884,7 +6911,7 @@ void Terr_WriteMapFile(vfsfile_t *file, model_t *mod)
|
|||
heightmap_t *hm;
|
||||
|
||||
hm = mod->terrain;
|
||||
if (hm && hm->exteriorcontents != FTECONTENTS_EMPTY)
|
||||
if (hm && hm->legacyterrain)
|
||||
VFS_WRITE(file, "terrain\n", 8);
|
||||
|
||||
start = entities;
|
||||
|
@ -7355,7 +7382,7 @@ qboolean Terr_ReformEntitiesLump(model_t *mod, heightmap_t *hm, char *entities)
|
|||
|
||||
qboolean QDECL Terr_LoadTerrainModel (model_t *mod, void *buffer, size_t bufsize)
|
||||
{
|
||||
int exterior = FTECONTENTS_SOLID;
|
||||
int legacyterrain;
|
||||
heightmap_t *hm;
|
||||
|
||||
char token[MAX_QPATH];
|
||||
|
@ -7364,9 +7391,12 @@ qboolean QDECL Terr_LoadTerrainModel (model_t *mod, void *buffer, size_t bufsize
|
|||
|
||||
src = COM_ParseOut(buffer, token, sizeof(token));
|
||||
if (!strcmp(token, "terrain"))
|
||||
{
|
||||
legacyterrain = true;
|
||||
buffer = src;
|
||||
}
|
||||
else if (!strcmp(token, "{"))
|
||||
exterior = FTECONTENTS_EMPTY;
|
||||
legacyterrain = false;
|
||||
else
|
||||
{
|
||||
Con_Printf(CON_ERROR "%s wasn't terrain map\n", mod->name); //shouldn't happen
|
||||
|
@ -7390,7 +7420,7 @@ qboolean QDECL Terr_LoadTerrainModel (model_t *mod, void *buffer, size_t bufsize
|
|||
|
||||
hm->entitylock = Sys_CreateMutex();
|
||||
hm->sectionsize = sectsize;
|
||||
if (exterior)
|
||||
if (legacyterrain)
|
||||
{
|
||||
hm->firstsegx = -1;
|
||||
hm->firstsegy = -1;
|
||||
|
@ -7404,7 +7434,9 @@ qboolean QDECL Terr_LoadTerrainModel (model_t *mod, void *buffer, size_t bufsize
|
|||
hm->maxsegx = 0;
|
||||
hm->maxsegy = 0;
|
||||
}
|
||||
hm->exteriorcontents = exterior; //sky outside the map
|
||||
hm->legacyterrain = legacyterrain;
|
||||
if (legacyterrain)
|
||||
hm->exteriorcontents = FTECONTENTS_SOLID; //sky outside the map
|
||||
|
||||
Terr_ParseEntityLump(mod, hm);
|
||||
|
||||
|
@ -7528,44 +7560,56 @@ void Mod_Terrain_Create_f(void)
|
|||
char *watername;
|
||||
char *groundheight;
|
||||
char *waterheight;
|
||||
char *seed;
|
||||
vfsfile_t *file;
|
||||
model_t mod;
|
||||
memset(&mod, 0, sizeof(mod));
|
||||
if (Cmd_Argc() < 2)
|
||||
{
|
||||
Con_Printf("%s: NAME \"DESCRIPTION\" SKYNAME DEFAULTGROUNDTEX DEFAULTHEIGHT DEFAULTWATER DEFAULTWATERHEIGHT\nGenerates a fresh maps/foo.hmp file. You may wish to edit it with notepad later to customise it. You will need csaddon.dat in order to edit the actual terrain.\n", Cmd_Argv(0));
|
||||
Con_Printf("%s: NAME \"DESCRIPTION\" SKYNAME DEFAULTGROUNDTEX DEFAULTHEIGHT DEFAULTWATER DEFAULTWATERHEIGHT seed\nGenerates a fresh maps/foo.hmp file. You may wish to edit it with notepad later to customise it. You will need csaddon.dat in order to edit the actual terrain.\n", Cmd_Argv(0));
|
||||
return;
|
||||
}
|
||||
mname = va("maps/%s.hmp", Cmd_Argv(1));
|
||||
|
||||
mapdesc = Cmd_Argv(2); if (!*mapdesc) mapdesc = Cmd_Argv(1);
|
||||
skyname = Cmd_Argv(3); if (!*skyname) skyname = "sky1";
|
||||
groundname = Cmd_Argv(4); if (!*groundname) groundname = "default";
|
||||
groundheight = Cmd_Argv(5); if (!*groundheight) groundheight = "0";
|
||||
watername = Cmd_Argv(6); if (!*watername) watername = "";
|
||||
waterheight = Cmd_Argv(7); if (!*waterheight) waterheight = "1024";
|
||||
skyname = Cmd_Argv(3);
|
||||
groundname = Cmd_Argv(4);
|
||||
groundheight = Cmd_Argv(5);
|
||||
watername = Cmd_Argv(6);
|
||||
waterheight = Cmd_Argv(7);
|
||||
seed = Cmd_Argv(7);
|
||||
Mod_SetEntitiesString(&mod, va(
|
||||
"{\n"
|
||||
"classname \"worldspawn\"\n"
|
||||
"message \"%s\"\n"
|
||||
"_sky sky1\n"
|
||||
"_sky \"%s\"\n"
|
||||
"_fog 0.02\n"
|
||||
"_segmentsize 1024\n"
|
||||
"_maxdrawdist 0 /*overrides fog distance (if greater)*/\n"
|
||||
"_segmentsize 1024 /*how big each section is. this affects texturing and resolutions*/\n"
|
||||
"_minxsegment -2048\n"
|
||||
"_minysegment -2048\n"
|
||||
"_maxxsegment 2048\n"
|
||||
"_maxysegment 2048\n"
|
||||
"//_defaultgroundtexture \"city4_2\"\n"
|
||||
"//_defaultwatertexture \"*water2\"\n"
|
||||
"//_defaultgroundheight -1024\n"
|
||||
"//_defaultwaterheight 0\n" //hurrah, sea level.
|
||||
"_seed \"%s\" /*for auto-gen plugins*/\n"
|
||||
"_exterior solid\n"
|
||||
"_defaultgroundtexture \"%s\"\n"
|
||||
"_defaultgroundheight \"%s\"\n"
|
||||
"_defaultwatertexture \"%s\"\n"
|
||||
"_defaultwaterheight \"%s\"\n" //hurrah, sea level.
|
||||
// "_tiles 64 64 8 8\n"
|
||||
"}\n"
|
||||
"{\n"
|
||||
"classname info_player_start\n"
|
||||
"origin \"0 0 1024\"\n"
|
||||
"origin \"0 0 1024\" /*EDITME*/\n"
|
||||
"}\n"
|
||||
, Cmd_Argv(2)), true);
|
||||
"/*ADD EXTRA ENTITIES!*/\n"
|
||||
, mapdesc
|
||||
,*skyname?skyname:"terrsky1", seed
|
||||
,*groundname?groundname:"ground1_1"
|
||||
,*groundheight?groundheight:"-1024"
|
||||
,*watername?watername:"*water2"
|
||||
,*waterheight?waterheight:"0"
|
||||
), true);
|
||||
|
||||
mod.type = mod_heightmap;
|
||||
mod.terrain = hm = Z_Malloc(sizeof(*hm));
|
||||
|
@ -7724,7 +7768,11 @@ void Mod_Terrain_Reload_f(void)
|
|||
|
||||
terrainfuncs_t *QDECL Terr_GetTerrainFuncs(void)
|
||||
{
|
||||
#ifdef SERVERONLY
|
||||
return NULL; //dedicated server builds have all the visual stuff stripped, which makes APIs too inconsistent. Generate then save. Or fix up the API...
|
||||
#else
|
||||
return &terrainfuncs;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Terr_Init(void)
|
||||
|
|
|
@ -1422,7 +1422,8 @@ model_t *Mod_LoadModel (model_t *mod, enum mlverbosity_e verbose)
|
|||
// Mod_LoadModelWorker(mod, MLV_WARN, 0);
|
||||
// else
|
||||
if (verbose == MLV_ERROR || verbose == MLV_WARNSYNC)
|
||||
COM_AddWork(WG_MAIN, Mod_LoadModelWorker, mod, NULL, verbose, 0);
|
||||
Mod_LoadModelWorker(mod, NULL, verbose, 0);
|
||||
// COM_AddWork(WG_MAIN, Mod_LoadModelWorker, mod, NULL, verbose, 0);
|
||||
else
|
||||
COM_AddWork(WG_LOADER, Mod_LoadModelWorker, mod, NULL, verbose, 0);
|
||||
}
|
||||
|
|
|
@ -546,23 +546,14 @@ void GLBE_UploadAllLightmaps(void)
|
|||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
}
|
||||
switch (lightmap_bytes)
|
||||
switch(lightmap_fmt) //bgra32, rgba32, rgb24, lum8
|
||||
{
|
||||
case 4:
|
||||
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
|
||||
lm->width, lm->height, 0, (lightmap_bgra?GL_BGRA_EXT:GL_RGBA), GL_UNSIGNED_INT_8_8_8_8_REV,
|
||||
lightmap[i]->lightmaps);
|
||||
break;
|
||||
case 3:
|
||||
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
|
||||
lm->width, lm->height, 0, (lightmap_bgra?GL_BGR_EXT:GL_RGB), GL_UNSIGNED_BYTE,
|
||||
lightmap[i]->lightmaps);
|
||||
break;
|
||||
case 1:
|
||||
qglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
|
||||
lm->width, lm->height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
|
||||
lightmap[i]->lightmaps);
|
||||
break;
|
||||
default: Sys_Error("Bad lightmap_fmt\n"); break;
|
||||
case TF_BGRA32: qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lm->width, lm->height, 0, GL_BGRA_EXT, GL_UNSIGNED_INT_8_8_8_8_REV,lightmap[i]->lightmaps); break;
|
||||
// case TF_RGBA32: qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, lm->width, lm->height, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV,lightmap[i]->lightmaps); break;
|
||||
// case TF_BGR24: qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, lm->width, lm->height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, lightmap[i]->lightmaps); break;
|
||||
case TF_RGB24: qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, lm->width, lm->height, 0, GL_RGB, GL_UNSIGNED_BYTE, lightmap[i]->lightmaps); break;
|
||||
case TF_LUM8: qglTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, lm->width, lm->height, 0, GL_LUMINANCE,GL_UNSIGNED_BYTE, lightmap[i]->lightmaps); break;
|
||||
}
|
||||
//for completeness.
|
||||
lm->lightmap_texture->width = lm->width;
|
||||
|
|
|
@ -287,23 +287,28 @@ typedef struct
|
|||
typedef struct heightmap_s
|
||||
{
|
||||
char path[MAX_QPATH];
|
||||
char skyname[MAX_QPATH];
|
||||
char groundshadername[MAX_QPATH];
|
||||
char defaultwatershader[MAX_QPATH]; //typically the name of the ocean or whatever.
|
||||
unsigned int culldistance;
|
||||
qboolean forcedefault;
|
||||
float defaultwaterheight;
|
||||
float defaultgroundheight;
|
||||
char defaultgroundtexture[MAX_QPATH];
|
||||
int firstsegx, firstsegy;
|
||||
int maxsegx, maxsegy; //tex/cull sections
|
||||
char skyname[MAX_QPATH]; //name of the skybox
|
||||
char groundshadername[MAX_QPATH]; //this is the shader we're using to draw the terrain itself. you could use other shaders here, for eg debugging or stylised weirdness.
|
||||
unsigned int culldistance; //entities will be culled if they're this far away (squared distance
|
||||
float maxdrawdist; //maximum view distance. extends view if larger than fog implies.
|
||||
|
||||
unsigned char *seed; //used by whatever terrain generator.
|
||||
qboolean forcedefault; //sections that cannot be loaded/generated will receive default values for stuff.
|
||||
char defaultgroundtexture[MAX_QPATH];//texture used for defaulted sections
|
||||
char defaultwatershader[MAX_QPATH]; //shader used for defaulted sections that have heights beneath defaultwaterheight.
|
||||
float defaultwaterheight; //water height. if you want your islands to be surrounded by water.
|
||||
float defaultgroundheight; //defaulted sections will have a z plane this high
|
||||
|
||||
int firstsegx, firstsegy; //min bounds of the terrain, in sections
|
||||
int maxsegx, maxsegy; //max bounds of the terrain, in sections
|
||||
float sectionsize; //each section is this big, in world coords
|
||||
hmcluster_t *cluster[MAXCLUSTERS*MAXCLUSTERS];
|
||||
shader_t *skyshader;
|
||||
shader_t *shader;
|
||||
mesh_t skymesh;
|
||||
mesh_t *askymesh;
|
||||
unsigned int exteriorcontents;
|
||||
qboolean legacyterrain; //forced exterior=SOLID
|
||||
unsigned int exteriorcontents; //contents type outside of the terrain sections area (.map should be empty, while terrain will usually block).
|
||||
unsigned int loadingsections; //number of sections currently being loaded. avoid loading extras while non-zero.
|
||||
size_t traceseq;
|
||||
size_t drawnframe;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "quakedef.h"
|
||||
|
||||
#if 0//def WEBCLIENT
|
||||
#ifdef FTPCLIENT
|
||||
|
||||
#include "iweb.h"
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WEBSERVER
|
||||
#ifdef FTPSERVER
|
||||
|
||||
#include "iweb.h"
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#ifndef IWEB_H__
|
||||
#define IWEB_H__
|
||||
|
||||
#ifdef WEBSERVER
|
||||
qboolean SV_AllowDownload (const char *name);
|
||||
|
||||
#if defined(WEBSERVER) || defined(FTPSERVER)
|
||||
|
||||
#ifdef WEBSVONLY
|
||||
//When running standalone
|
||||
|
@ -34,8 +36,6 @@ struct sockaddr;
|
|||
struct sockaddr_qstorage;
|
||||
int NetadrToSockadr (netadr_t *a, struct sockaddr_qstorage *s);
|
||||
|
||||
qboolean SV_AllowDownload (const char *name);
|
||||
|
||||
|
||||
typedef qboolean iwboolean;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "quakedef.h"
|
||||
|
||||
#ifdef WEBSERVER
|
||||
#if defined(WEBSERVER) || defined(FTPSERVER)
|
||||
|
||||
#include "iweb.h"
|
||||
#include "netinc.h"
|
||||
|
@ -503,15 +503,18 @@ IWEBFILE *IWebFOpenRead(char *name) //fread(name, "rb");
|
|||
|
||||
#else
|
||||
|
||||
#if defined(WEBSERVER) || defined(FTPSERVER)
|
||||
static cvar_t sv_readlevel = CVAR("sv_readlevel", "0"); //default to allow anyone
|
||||
static cvar_t sv_writelevel = CVARD("sv_writelevel", "35", "Specifies the required trust level at which user accounts may write to the user-specific subdir of /uploads/USERNAME/*. If blank, then no uploads are permitted"); //allowed to write to uploads/uname
|
||||
static cvar_t sv_fulllevel = CVARD("sv_fulllevel", "51", "User accounts with an access level greater than this may write anywhere, including the gamedir. Note that setting this low is increadibly risky. An empty value will be understood to never give this permission."); //allowed to write anywhere, replace any file...
|
||||
#ifdef WEBSERVER
|
||||
cvar_t ftpserver = CVAR("sv_ftp", "0");
|
||||
cvar_t ftpserver_port = CVAR("sv_ftp_port", "21");
|
||||
cvar_t httpserver = CVAR("sv_http", "0");
|
||||
cvar_t httpserver_port = CVAR("sv_http_port", "80");
|
||||
cvar_t sv_readlevel = CVAR("sv_readlevel", "0"); //default to allow anyone
|
||||
cvar_t sv_writelevel = CVAR("sv_writelevel", "35"); //allowed to write to uploads/uname
|
||||
cvar_t sv_fulllevel = CVAR("sv_fulllevel", "51"); //allowed to write anywhere, replace any file...
|
||||
cvar_t sv_ftp_port_range = CVARD("sv_ftp_port_range", "0", "Specifies the port range for the server to create listening sockets for 'active' ftp connections, to work around NAT/firewall issues.\nMost FTP clients should use passive connections, but there's still some holdouts like windows.");
|
||||
static cvar_t httpserver = CVAR("sv_http", "0");
|
||||
static cvar_t httpserver_port = CVAR("sv_http_port", "80");
|
||||
#endif
|
||||
#ifdef FTPSERVER
|
||||
static cvar_t ftpserver = CVAR("sv_ftp", "0");
|
||||
static cvar_t ftpserver_port = CVAR("sv_ftp_port", "21");
|
||||
static cvar_t sv_ftp_port_range = CVARD("sv_ftp_port_range", "0", "Specifies the port range for the server to create listening sockets for 'active' ftp connections, to work around NAT/firewall issues.\nMost FTP clients should use passive connections, but there's still some holdouts like windows.");
|
||||
|
||||
int IWebGetSafeListeningPort(void)
|
||||
{
|
||||
|
@ -533,6 +536,7 @@ int IWebGetSafeListeningPort(void)
|
|||
return base + (sequence++ % (range+1-base));
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//this file contains functions called from each side.
|
||||
|
||||
|
@ -680,9 +684,9 @@ int IWebAuthorize(const char *name, const char *password)
|
|||
|
||||
Rank_GetPlayerInfo(id, &info);
|
||||
|
||||
if (info.s.trustlevel >= sv_fulllevel.value)
|
||||
if (*sv_fulllevel.string && info.s.trustlevel >= sv_fulllevel.value)
|
||||
return IWEBACC_READ | IWEBACC_WRITE | IWEBACC_FULL; //allowed to read and write anywhere to the quake filesystem
|
||||
if (info.s.trustlevel >= sv_writelevel.value)
|
||||
if (*sv_writelevel.string && info.s.trustlevel >= sv_writelevel.value)
|
||||
return IWEBACC_READ | IWEBACC_WRITE; //allowed to read anywhere write to specific places
|
||||
if (info.s.trustlevel >= sv_readlevel.value)
|
||||
return IWEBACC_READ; //read only anywhere
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#include "quakedef.h"
|
||||
|
||||
#ifdef WEBSERVER
|
||||
#if defined(WEBSERVER) || defined(FTPSERVER)
|
||||
|
||||
#include "iweb.h"
|
||||
|
||||
#ifdef CLIENTONLY
|
||||
vfsfile_t *IWebGenerateFile(char *name)
|
||||
#if defined(CLIENTONLY) || !defined(WEBSERVER)
|
||||
vfsfile_t *IWebGenerateFile(const char *name, const char *content, int contentlength)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -703,13 +703,11 @@ HMODULE scintilla;
|
|||
|
||||
pbool resetprogssrc; //progs.src was changed, reload project info.
|
||||
|
||||
|
||||
HWND mainwindow;
|
||||
HWND gamewindow;
|
||||
HWND mdibox;
|
||||
HWND watches;
|
||||
HWND optionsmenu;
|
||||
HWND outputwindow;
|
||||
HWND outputbox;
|
||||
HWND projecttree;
|
||||
HWND search_name;
|
||||
|
@ -717,6 +715,240 @@ HWND search_gotodef;
|
|||
HWND search_grep;
|
||||
HACCEL accelerators;
|
||||
|
||||
|
||||
//our splitter...
|
||||
#define SPLITTER_SIZE 4
|
||||
static struct splits_s
|
||||
{
|
||||
HWND wnd;
|
||||
HWND splitter;
|
||||
int minsize;
|
||||
int cury;
|
||||
int cursize;
|
||||
float frac;
|
||||
|
||||
} *splits;
|
||||
static size_t numsplits;
|
||||
static RECT splitterrect;
|
||||
|
||||
static struct splits_s *SplitterGet(HWND id)
|
||||
{
|
||||
size_t s;
|
||||
for (s = 0; s < numsplits; s++)
|
||||
{
|
||||
if (splits[s].wnd == id)
|
||||
return &splits[s];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
static int SplitterShrinkPrior(size_t s, int px)
|
||||
{
|
||||
int found = 0;
|
||||
int avail;
|
||||
for (; px && s > 0; s--)
|
||||
{
|
||||
avail = splits[s].cursize - splits[s].minsize;
|
||||
if (avail > px)
|
||||
avail = px;
|
||||
|
||||
splits[s].cursize -= avail;
|
||||
found += avail;
|
||||
px -= avail;
|
||||
}
|
||||
|
||||
if (px)
|
||||
{
|
||||
avail = splits[0].cursize - splits[0].minsize;
|
||||
if (avail > px)
|
||||
avail = px;
|
||||
|
||||
splits[0].cursize -= avail;
|
||||
found += avail;
|
||||
px -= avail;
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
static SplitterShrinkNext(size_t s, int px)
|
||||
{
|
||||
int found = 0;
|
||||
int avail;
|
||||
for (; px && s < numsplits; s++)
|
||||
{
|
||||
avail = splits[s].cursize - splits[s].minsize;
|
||||
if (avail > px)
|
||||
avail = px;
|
||||
|
||||
splits[s].cursize -= avail;
|
||||
found += avail;
|
||||
px -= avail;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
static void SplitterUpdate(void);
|
||||
static LRESULT CALLBACK SplitterWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
size_t s;
|
||||
PAINTSTRUCT ps;
|
||||
RECT rect;
|
||||
int y;
|
||||
int cascade;
|
||||
switch(message)
|
||||
{
|
||||
case WM_LBUTTONDOWN:
|
||||
SetCapture(hWnd);
|
||||
return TRUE;
|
||||
case WM_MOUSEMOVE:
|
||||
if (wParam & MK_LBUTTON)
|
||||
if (GetCapture() == hWnd)
|
||||
goto doresize;
|
||||
return true;
|
||||
case WM_LBUTTONUP:
|
||||
ReleaseCapture();
|
||||
doresize:
|
||||
y = GET_Y_LPARAM(lParam);
|
||||
GetClientRect(hWnd, &rect);
|
||||
y = y - rect.top - SPLITTER_SIZE/2;
|
||||
for (s = 1; s < numsplits; s++)
|
||||
{
|
||||
if (splits[s].splitter == hWnd)
|
||||
{
|
||||
cascade = 0;
|
||||
if (y < 0)
|
||||
splits[s].cursize += SplitterShrinkPrior(s-1, -y);
|
||||
else
|
||||
splits[s-1].cursize += SplitterShrinkNext(s, y);
|
||||
SplitterUpdate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
case WM_PAINT:
|
||||
BeginPaint(hWnd,(LPPAINTSTRUCT)&ps);
|
||||
EndPaint(hWnd,(LPPAINTSTRUCT)&ps);
|
||||
return TRUE;
|
||||
default:
|
||||
return DefWindowProc(hWnd,message,wParam,lParam);
|
||||
}
|
||||
}
|
||||
static void SplitterUpdate(void)
|
||||
{
|
||||
int y = 0;
|
||||
size_t s;
|
||||
if (!numsplits)
|
||||
return;
|
||||
|
||||
//figure out the total height
|
||||
for (s = numsplits; s-- > 0; )
|
||||
{
|
||||
y += splits[s].cursize;
|
||||
}
|
||||
y = splitterrect.bottom-splitterrect.top;
|
||||
|
||||
//now figure out their positions relative to that
|
||||
for (s = numsplits; s-- > 1; )
|
||||
{
|
||||
y -= splits[s].cursize;
|
||||
splits[s].cury = y;
|
||||
y -= SPLITTER_SIZE;
|
||||
}
|
||||
|
||||
splits[0].cursize = y;
|
||||
splits[0].cury = 0;
|
||||
if (splits[0].cursize < splits[0].minsize)
|
||||
splits[0].cursize += SplitterShrinkNext(1, splits[0].minsize-splits[0].cursize);
|
||||
|
||||
for (s = 0; s < numsplits; s++)
|
||||
{
|
||||
if (s)
|
||||
{
|
||||
if (!splits[s].splitter)
|
||||
{
|
||||
WNDCLASSA wclass;
|
||||
wclass.style = 0;
|
||||
wclass.lpfnWndProc = SplitterWndProc;
|
||||
wclass.cbClsExtra = 0;
|
||||
wclass.cbWndExtra = 0;
|
||||
wclass.hInstance = ghInstance;
|
||||
wclass.hIcon = NULL;
|
||||
wclass.hCursor = LoadCursor(0, IDC_SIZENS);
|
||||
wclass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1);
|
||||
wclass.lpszMenuName = NULL;
|
||||
wclass.lpszClassName = "splitter";
|
||||
RegisterClassA(&wclass);
|
||||
splits[s].splitter = CreateWindowExA(0, wclass.lpszClassName, "", WS_CHILD|WS_VISIBLE, splitterrect.left, splitterrect.top+splits[s].cury-SPLITTER_SIZE, splitterrect.right-splitterrect.left, SPLITTER_SIZE, mainwindow, NULL, ghInstance, NULL);
|
||||
}
|
||||
else
|
||||
SetWindowPos(splits[s].splitter, HWND_TOP, splitterrect.left, splitterrect.top+splits[s].cury-SPLITTER_SIZE, splitterrect.right-splitterrect.left, SPLITTER_SIZE, SWP_NOZORDER);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (splits[s].splitter)
|
||||
{
|
||||
DestroyWindow(splits[s].splitter);
|
||||
splits[s].splitter = NULL;
|
||||
}
|
||||
}
|
||||
SetWindowPos(splits[s].wnd, HWND_TOP, splitterrect.left, splitterrect.top+splits[s].cury, splitterrect.right-splitterrect.left, splits[s].cursize, SWP_NOZORDER);
|
||||
}
|
||||
}
|
||||
static void SplitterFocus(HWND w, int minsize)
|
||||
{
|
||||
struct splits_s *s = SplitterGet(w);
|
||||
if (s)
|
||||
{
|
||||
if (s->cursize < minsize)
|
||||
{
|
||||
s->cursize += SplitterShrinkPrior(s-splits-1, (minsize-s->cursize)/2);
|
||||
if (s->cursize < minsize)
|
||||
s->cursize += SplitterShrinkNext(s-splits+1, minsize-s->cursize);
|
||||
if (s->cursize < minsize)
|
||||
s->cursize += SplitterShrinkPrior(s-splits-1, minsize-s->cursize);
|
||||
SplitterUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
SetFocus(w);
|
||||
}
|
||||
static void SplitterAdd(HWND w, int minsize)
|
||||
{
|
||||
struct splits_s *n = malloc(sizeof(*n)*(numsplits+1));
|
||||
memcpy(n, splits, sizeof(*n)*numsplits);
|
||||
free(splits);
|
||||
splits = n;
|
||||
n += numsplits;
|
||||
|
||||
n->wnd = w;
|
||||
n->splitter = NULL;
|
||||
n->minsize = minsize;
|
||||
n->cursize = minsize;
|
||||
n->cury = 0;
|
||||
|
||||
numsplits++;
|
||||
|
||||
SplitterUpdate();
|
||||
ShowWindow(w, SW_SHOW);
|
||||
}
|
||||
static void SplitterRemove(HWND w)
|
||||
{
|
||||
struct splits_s *s = SplitterGet(w);
|
||||
size_t idx;
|
||||
if (!s)
|
||||
return;
|
||||
if (s->splitter)
|
||||
DestroyWindow(s->splitter);
|
||||
idx = s-splits;
|
||||
numsplits--;
|
||||
memmove(splits+idx, splits+idx+1, sizeof(*s)*(numsplits-idx));
|
||||
|
||||
ShowWindow(w, SW_HIDE);
|
||||
|
||||
SplitterUpdate();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
FILE *logfile;
|
||||
|
||||
void GrepAllFiles(char *string);
|
||||
|
@ -855,21 +1087,21 @@ LRESULT CALLBACK MySubclassWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
|
|||
{
|
||||
*colon1 = '\0';
|
||||
*colon2 = '\0';
|
||||
EditFile(line, atoi(colon1+1)-1, false);
|
||||
EditFile(line, atoi(colon1+1)-1, 2);
|
||||
}
|
||||
else if (!strncmp(line, "Source file: ", 13))
|
||||
EditFile(line+13, -1, false);
|
||||
EditFile(line+13, -1, 2);
|
||||
else if (!strncmp(line, "Including: ", 11))
|
||||
EditFile(line+11, -1, false);
|
||||
EditFile(line+11, -1, 2);
|
||||
}
|
||||
else if (!strncmp(line, "including ", 10))
|
||||
EditFile(line+10, -1, false);
|
||||
EditFile(line+10, -1, 2);
|
||||
else if (!strncmp(line, "compiling ", 10))
|
||||
EditFile(line+10, -1, false);
|
||||
EditFile(line+10, -1, 2);
|
||||
else if (!strncmp(line, "prototyping ", 12))
|
||||
EditFile(line+12, -1, false);
|
||||
EditFile(line+12, -1, 2);
|
||||
else if (!strncmp(line, "Couldn't open file ", 19))
|
||||
EditFile(line+19, -1, false);
|
||||
EditFile(line+19, -1, 2);
|
||||
Edit_SetSel(hWnd, selrange.cpMin, selrange.cpMin); //deselect it.
|
||||
}
|
||||
}
|
||||
|
@ -1385,11 +1617,7 @@ void GenericMenu(WPARAM wParam)
|
|||
|
||||
|
||||
case IDM_OUTPUT_WINDOW:
|
||||
if (outputwindow && outputbox)
|
||||
{
|
||||
SetFocus(outputwindow);
|
||||
SetFocus(outputbox);
|
||||
}
|
||||
SplitterFocus(outputbox, 128);
|
||||
break;
|
||||
case IDM_SHOWLINENUMBERS:
|
||||
{
|
||||
|
@ -2267,6 +2495,8 @@ static LRESULT CALLBACK EditorWndProc(HWND hWnd,UINT message,
|
|||
GetClientRect(hWnd, &rect);
|
||||
SetWindowPos(editor->editpane, NULL, 0, 0, rect.right-rect.left, rect.bottom-rect.top, 0);
|
||||
goto gdefault;
|
||||
case WM_ERASEBKGND:
|
||||
return TRUE;
|
||||
case WM_PAINT:
|
||||
BeginPaint(hWnd,(LPPAINTSTRUCT)&ps);
|
||||
|
||||
|
@ -2547,6 +2777,10 @@ static void EditorReload(editor_t *editor)
|
|||
}
|
||||
|
||||
//line is 0-based. use -1 for no reselection
|
||||
//setcontrol is the reason we're opening it.
|
||||
//0: just load and go to the line.
|
||||
//1: show the line as the executing one
|
||||
//2: draw extra focus to it
|
||||
void EditFile(const char *name, int line, pbool setcontrol)
|
||||
{
|
||||
char title[1024];
|
||||
|
@ -2574,7 +2808,10 @@ void EditFile(const char *name, int line, pbool setcontrol)
|
|||
{
|
||||
if (line >= 0)
|
||||
{
|
||||
Edit_SetSel(neweditor->editpane, Edit_LineIndex(neweditor->editpane, line), Edit_LineIndex(neweditor->editpane, line+1)-1);
|
||||
if (setcontrol)
|
||||
Edit_SetSel(neweditor->editpane, Edit_LineIndex(neweditor->editpane, line+1)-1, Edit_LineIndex(neweditor->editpane, line+1)-1);
|
||||
else
|
||||
Edit_SetSel(neweditor->editpane, Edit_LineIndex(neweditor->editpane, line), Edit_LineIndex(neweditor->editpane, line+1)-1);
|
||||
Edit_ScrollCaret(neweditor->editpane);
|
||||
|
||||
if (setcontrol && neweditor->scintilla)
|
||||
|
@ -2635,15 +2872,15 @@ void EditFile(const char *name, int line, pbool setcontrol)
|
|||
|
||||
|
||||
wndclass.style = 0;
|
||||
wndclass.lpfnWndProc = EditorWndProc;
|
||||
wndclass.cbClsExtra = 0;
|
||||
wndclass.cbWndExtra = 0;
|
||||
wndclass.hInstance = ghInstance;
|
||||
wndclass.lpfnWndProc = EditorWndProc;
|
||||
wndclass.cbClsExtra = 0;
|
||||
wndclass.cbWndExtra = 0;
|
||||
wndclass.hInstance = ghInstance;
|
||||
wndclass.hIcon = LoadIcon(ghInstance, IDI_ICON_FTEQCC);
|
||||
wndclass.hCursor = LoadCursor (NULL,IDC_ARROW);
|
||||
wndclass.hCursor = LoadCursor (NULL,IDC_ARROW);
|
||||
wndclass.hbrBackground = (void *)COLOR_WINDOW;
|
||||
wndclass.lpszMenuName = 0;
|
||||
wndclass.lpszClassName = EDIT_WINDOW_CLASS_NAME;
|
||||
wndclass.lpszMenuName = 0;
|
||||
wndclass.lpszClassName = EDIT_WINDOW_CLASS_NAME;
|
||||
RegisterClass(&wndclass);
|
||||
|
||||
neweditor->window = NULL;
|
||||
|
@ -2658,7 +2895,7 @@ void EditFile(const char *name, int line, pbool setcontrol)
|
|||
mcs.hOwner = ghInstance;
|
||||
mcs.x = mcs.cx = CW_USEDEFAULT;
|
||||
mcs.y = mcs.cy = CW_USEDEFAULT;
|
||||
mcs.style = WS_OVERLAPPEDWINDOW;
|
||||
mcs.style = WS_OVERLAPPEDWINDOW|WS_MAXIMIZE;
|
||||
mcs.lParam = 0;
|
||||
|
||||
neweditor->window = (HWND) SendMessage (mdibox, WM_MDICREATE, 0,
|
||||
|
@ -2685,7 +2922,12 @@ void EditFile(const char *name, int line, pbool setcontrol)
|
|||
EditorReload(neweditor);
|
||||
|
||||
if (line >= 0)
|
||||
Edit_SetSel(neweditor->editpane, Edit_LineIndex(neweditor->editpane, line), Edit_LineIndex(neweditor->editpane, line+1));
|
||||
{
|
||||
if (setcontrol)
|
||||
Edit_SetSel(neweditor->editpane, Edit_LineIndex(neweditor->editpane, line+1)-1, Edit_LineIndex(neweditor->editpane, line+1)-1);
|
||||
else
|
||||
Edit_SetSel(neweditor->editpane, Edit_LineIndex(neweditor->editpane, line), Edit_LineIndex(neweditor->editpane, line+1)-1);
|
||||
}
|
||||
else
|
||||
Edit_SetSel(neweditor->editpane, Edit_LineIndex(neweditor->editpane, 0), Edit_LineIndex(neweditor->editpane, 0));
|
||||
|
||||
|
@ -3417,8 +3659,8 @@ static LRESULT CALLBACK EngineWndProc(HWND hWnd,UINT message,
|
|||
}
|
||||
if (hWnd == gamewindow)
|
||||
{
|
||||
SplitterRemove(watches);
|
||||
gamewindow = NULL;
|
||||
PostMessage(mainwindow, WM_SIZE, 0, 0);
|
||||
}
|
||||
break;
|
||||
case WM_USER:
|
||||
|
@ -3724,6 +3966,8 @@ void RunEngine(void)
|
|||
|
||||
gamewindow = (HWND) SendMessage (mdibox, WM_MDICREATE, 0, (LONG_PTR) (LPMDICREATESTRUCT) &mcs);
|
||||
}
|
||||
SplitterAdd(watches, 0);
|
||||
SplitterFocus(watches, 64);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5398,12 +5642,14 @@ static LRESULT CALLBACK MainWndProc(HWND hWnd,UINT message,
|
|||
watches = CreateWindow(WC_LISTVIEW, (LPCTSTR) NULL,
|
||||
WS_CHILD | WS_VSCROLL | WS_HSCROLL | LVS_REPORT | LVS_EDITLABELS,
|
||||
0, 0, 320, 200, hWnd, (HMENU) 0xCAD, ghInstance, NULL);
|
||||
ShowWindow(watches, SW_SHOW);
|
||||
|
||||
SplitterAdd(mdibox, 32);
|
||||
|
||||
if (watches)
|
||||
{
|
||||
LVCOLUMN col;
|
||||
LVITEM newi;
|
||||
|
||||
// ListView_SetUnicodeFormat(watches, TRUE);
|
||||
ListView_SetExtendedListViewStyle(watches, LVS_EX_GRIDLINES);
|
||||
memset(&col, 0, sizeof(col));
|
||||
|
@ -5481,40 +5727,37 @@ static LRESULT CALLBACK MainWndProc(HWND hWnd,UINT message,
|
|||
GetClientRect(mainwindow, &rect);
|
||||
if (projecttree)
|
||||
{
|
||||
int mdiheight, watchheight;
|
||||
SetWindowPos(projecttree, NULL, 0, 0, 192, rect.bottom-rect.top - 34 - 48, 0);
|
||||
SetWindowPos(projecttree, NULL, 0, 0, 192, rect.bottom-rect.top - 48, SWP_NOZORDER);
|
||||
|
||||
SetWindowPos(search_name, NULL, 0, rect.bottom-rect.top - 33 - 48, 192, 24, 0);
|
||||
SetWindowPos(search_gotodef, NULL, 0, rect.bottom-rect.top - 33 - 24, 192/2, 24, 0);
|
||||
SetWindowPos(search_grep, NULL, 192/2, rect.bottom-rect.top - 33 - 24, 192/2, 24, 0);
|
||||
SetWindowPos(search_name, NULL, 0, rect.bottom-rect.top - 48, 192, 24, SWP_NOZORDER);
|
||||
SetWindowPos(search_gotodef, NULL, 0, rect.bottom-rect.top - 24, 192/2, 24, SWP_NOZORDER);
|
||||
SetWindowPos(search_grep, NULL, 192/2, rect.bottom-rect.top - 24, 192/2, 24, SWP_NOZORDER);
|
||||
|
||||
if (gamewindow)
|
||||
watchheight = (ListView_GetItemCount(watches) + 2) * 16;
|
||||
else
|
||||
watchheight = 0;
|
||||
mdiheight = (rect.bottom-rect.top) - 32;
|
||||
if (watchheight > mdiheight/2)
|
||||
watchheight = mdiheight/2;
|
||||
mdiheight -= watchheight;
|
||||
SetWindowPos(watches, NULL, 192, mdiheight, rect.right-rect.left-192, watchheight, 0);
|
||||
SetWindowPos(mdibox?mdibox:outputbox, NULL, 192, 0, rect.right-rect.left-192, mdiheight, 0);
|
||||
splitterrect.left = 192;
|
||||
}
|
||||
else
|
||||
SetWindowPos(mdibox?mdibox:outputbox, NULL, 0, 0, rect.right-rect.left, rect.bottom-rect.top - 32, 0);
|
||||
width = (rect.right-rect.left);
|
||||
width/=NUMBUTTONS;
|
||||
{
|
||||
splitterrect.left = 0;
|
||||
}
|
||||
splitterrect.right = rect.right-rect.left;
|
||||
splitterrect.bottom = rect.bottom-rect.top-32;
|
||||
SplitterUpdate();
|
||||
width = (rect.right-rect.left)-splitterrect.left;
|
||||
for (i = 0; i < NUMBUTTONS; i++)
|
||||
{
|
||||
SetWindowPos(buttons[i].hwnd, NULL, width*i, rect.bottom-rect.top - 32, width, 32, 0);
|
||||
int l = splitterrect.left+(width*i)/(NUMBUTTONS);
|
||||
int r = splitterrect.left+(width*(i+1))/(NUMBUTTONS);
|
||||
SetWindowPos(buttons[i].hwnd, NULL, l, rect.bottom-rect.top - 32, r-l, 32, SWP_NOZORDER);
|
||||
}
|
||||
break;
|
||||
// goto gdefault;
|
||||
case WM_ERASEBKGND:
|
||||
return TRUE; //background is clear... or doesn't need clearing (if its fully obscured)
|
||||
case WM_PAINT:
|
||||
BeginPaint(hWnd,(LPPAINTSTRUCT)&ps);
|
||||
|
||||
EndPaint(hWnd,(LPPAINTSTRUCT)&ps);
|
||||
return TRUE;
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
i = LOWORD(wParam);
|
||||
if (i == 0x4403)
|
||||
|
@ -5722,27 +5965,6 @@ static void DoTranslateMessage(MSG *msg)
|
|||
}
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK OutputWindowProc(HWND hWnd,UINT message,
|
||||
WPARAM wParam,LPARAM lParam)
|
||||
{
|
||||
RECT rect;
|
||||
switch (message)
|
||||
{
|
||||
case WM_DESTROY:
|
||||
outputwindow = NULL;
|
||||
outputbox = NULL;
|
||||
break;
|
||||
case WM_CREATE:
|
||||
outputbox = CreateAnEditControl(hWnd, NULL);
|
||||
case WM_SIZE:
|
||||
GetClientRect(hWnd, &rect);
|
||||
SetWindowPos(outputbox, NULL, 0, 0, rect.right-rect.left, rect.bottom-rect.top, 0);
|
||||
default:
|
||||
return DefMDIChildProc(hWnd,message,wParam,lParam);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GUIPrint(HWND wnd, char *msg)
|
||||
{
|
||||
// MSG wmsg;
|
||||
|
@ -6031,8 +6253,7 @@ int GUIprintf(const char *msg, ...)
|
|||
outlen = 0;
|
||||
|
||||
/*make sure its active so we can actually scroll. stupid windows*/
|
||||
SetFocus(outputwindow);
|
||||
SetFocus(outputbox);
|
||||
SplitterFocus(outputbox, 0);
|
||||
|
||||
/*colour background to default*/
|
||||
TreeView_SetBkColor(projecttree, -1);
|
||||
|
@ -6274,45 +6495,14 @@ void RunCompiler(char *args, pbool quick)
|
|||
|
||||
void CreateOutputWindow(pbool doannoates)
|
||||
{
|
||||
WNDCLASS wndclass;
|
||||
MDICREATESTRUCT mcs;
|
||||
|
||||
gui_doannotates = doannoates;
|
||||
|
||||
if (!mdibox) //should already be created
|
||||
return;
|
||||
|
||||
if (!outputwindow)
|
||||
if (!outputbox)
|
||||
{
|
||||
wndclass.style = 0;
|
||||
wndclass.lpfnWndProc = OutputWindowProc;
|
||||
wndclass.cbClsExtra = 0;
|
||||
wndclass.cbWndExtra = 0;
|
||||
wndclass.hInstance = ghInstance;
|
||||
wndclass.hIcon = LoadIcon(ghInstance, IDI_ICON_FTEQCC);
|
||||
wndclass.hCursor = LoadCursor (NULL,IDC_ARROW);
|
||||
wndclass.hbrBackground = (void *)COLOR_WINDOW;
|
||||
wndclass.lpszMenuName = 0;
|
||||
wndclass.lpszClassName = MAIN_WINDOW_CLASS_NAME;
|
||||
RegisterClass(&wndclass);
|
||||
|
||||
|
||||
|
||||
mcs.szClass = MAIN_WINDOW_CLASS_NAME;
|
||||
mcs.szTitle = "Compiler output";
|
||||
mcs.hOwner = ghInstance;
|
||||
mcs.x = mcs.cx = CW_USEDEFAULT;
|
||||
mcs.y = mcs.cy = CW_USEDEFAULT;
|
||||
mcs.style = WS_OVERLAPPEDWINDOW;
|
||||
mcs.lParam = 0;
|
||||
|
||||
outputwindow = (HWND) SendMessage (mdibox, WM_MDICREATE, 0, (LONG_PTR) (LPMDICREATESTRUCT) &mcs);
|
||||
|
||||
ShowWindow(outputwindow, SW_SHOW);
|
||||
outputbox = CreateAnEditControl(mainwindow, NULL);
|
||||
SplitterAdd(outputbox, 64);
|
||||
}
|
||||
|
||||
//bring it to the front.
|
||||
SendMessage(mdibox, WM_MDIACTIVATE, (WPARAM)outputwindow, 0);
|
||||
SplitterFocus(outputbox, 128);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -820,6 +820,7 @@ void PR_LoadGlabalStruct(qboolean muted)
|
|||
globalfloat (false, input_buttons);
|
||||
globalint (false, serverid);
|
||||
globalvec (false, global_gravitydir);
|
||||
globalstring (false, parm_string);
|
||||
|
||||
memset(&evalc_idealpitch, 0, sizeof(evalc_idealpitch));
|
||||
memset(&evalc_pitch_speed, 0, sizeof(evalc_pitch_speed));
|
||||
|
@ -2664,15 +2665,25 @@ void PF_setmodel_Internal (pubprogfuncs_t *prinst, edict_t *e, const char *m)
|
|||
|
||||
if (sv.state != ss_loading)
|
||||
{
|
||||
int j;
|
||||
Con_DPrintf("Delayed model precache: %s\n", m);
|
||||
MSG_WriteByte(&sv.reliable_datagram, svcfte_precache);
|
||||
MSG_WriteShort(&sv.reliable_datagram, i);
|
||||
MSG_WriteString(&sv.reliable_datagram, m);
|
||||
#ifdef NQPROT
|
||||
MSG_WriteByte(&sv.nqreliable_datagram, svcdp_precache);
|
||||
MSG_WriteShort(&sv.nqreliable_datagram, i);
|
||||
MSG_WriteString(&sv.nqreliable_datagram, m);
|
||||
#endif
|
||||
|
||||
for (j = 0; j < sv.allocated_client_slots; j++)
|
||||
{
|
||||
if (svs.clients[j].state < cs_connected)
|
||||
continue;
|
||||
if (ISDPCLIENT(&svs.clients[j]) || (svs.clients[j].fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS))
|
||||
{
|
||||
ClientReliableWrite_Begin (&svs.clients[j], ISNQCLIENT(&svs.clients[j])?svcdp_precache:svcfte_precache, strlen(m)+4);
|
||||
ClientReliableWrite_Short (&svs.clients[j], i);
|
||||
ClientReliableWrite_String (&svs.clients[j], m);
|
||||
}
|
||||
else
|
||||
{
|
||||
//client doesn't support this... reset the connection so they're forced to reload everything.
|
||||
//SV_StuffcmdToClient(&svs.clients[j], "cmd new\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -3677,6 +3688,25 @@ void PF_stuffcmd_Internal(int entnum, const char *str, unsigned int flags)
|
|||
{
|
||||
client_t *cl;
|
||||
int slen;
|
||||
unsigned int i;
|
||||
|
||||
if (flags & STUFFCMD_BROADCAST)
|
||||
{
|
||||
for (i = 0, cl = svs.clients; i < sv.allocated_client_slots; i++, cl++)
|
||||
{
|
||||
if (cl->state != cs_spawned || cl->controller == cl)
|
||||
continue;
|
||||
SV_StuffcmdToClient(cl, str);
|
||||
}
|
||||
if (!(flags & STUFFCMD_IGNOREINDEMO))
|
||||
if (sv.mvdrecording)
|
||||
{
|
||||
sizebuf_t *msg = MVDWrite_Begin (dem_all, 0, 2 + strlen(str));
|
||||
MSG_WriteByte (msg, svc_stufftext);
|
||||
MSG_WriteString (msg, str);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (entnum < 1 || entnum > sv.allocated_client_slots)
|
||||
return;
|
||||
|
@ -5529,9 +5559,7 @@ void QCBUILTIN PF_setspawnparms (pubprogfuncs_t *prinst, struct globalvars_s *pr
|
|||
// copy spawn parms out of the client_t
|
||||
client = svs.clients + (i-1);
|
||||
|
||||
for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
|
||||
if (pr_global_ptrs->spawnparamglobals[i])
|
||||
*pr_global_ptrs->spawnparamglobals[i] = client->spawn_parms[i];
|
||||
SV_SpawnParmsToQC(client);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -5744,7 +5772,7 @@ char *PF_infokey_Internal (int entnum, const char *key)
|
|||
value = ""; //could be a writebyted bot...
|
||||
break;
|
||||
case SCP_QUAKEWORLD:
|
||||
if (!svs.clients[entnum-1].fteprotocolextensions && !svs.clients[entnum-1].fteprotocolextensions)
|
||||
if (!svs.clients[entnum-1].fteprotocolextensions && !svs.clients[entnum-1].fteprotocolextensions2)
|
||||
value = "quakeworld";
|
||||
else
|
||||
value = "quakeworld+";
|
||||
|
@ -8550,29 +8578,44 @@ static void QCBUILTIN PF_te_teleport(pubprogfuncs_t *prinst, struct globalvars_s
|
|||
//void(vector org, float color, float length) te_explosion2 = #427;
|
||||
static void QCBUILTIN PF_te_explosion2(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
qboolean old = false;
|
||||
float *org = G_VECTOR(OFS_PARM0);
|
||||
int start = G_FLOAT(OFS_PARM1);
|
||||
int length = G_FLOAT(OFS_PARM2);
|
||||
start = bound(0, start, 255);
|
||||
length = bound(0, length, 255-start);
|
||||
|
||||
MSG_WriteByte (&sv.multicast, svc_temp_entity);
|
||||
MSG_WriteByte (&sv.multicast, TEQW_EXPLOSION2);
|
||||
MSG_WriteCoord (&sv.multicast, org[0]);
|
||||
MSG_WriteCoord (&sv.multicast, org[1]);
|
||||
MSG_WriteCoord (&sv.multicast, org[2]);
|
||||
MSG_WriteByte (&sv.multicast, start);
|
||||
MSG_WriteByte (&sv.multicast, length);
|
||||
#ifdef NQPROT
|
||||
MSG_WriteByte (&sv.nqmulticast, svc_temp_entity);
|
||||
MSG_WriteByte (&sv.nqmulticast, TENQ_EXPLOSION2);
|
||||
MSG_WriteCoord (&sv.nqmulticast, org[0]);
|
||||
MSG_WriteCoord (&sv.nqmulticast, org[1]);
|
||||
MSG_WriteCoord (&sv.nqmulticast, org[2]);
|
||||
MSG_WriteByte (&sv.nqmulticast, start);
|
||||
MSG_WriteByte (&sv.nqmulticast, length);
|
||||
#endif
|
||||
SV_MulticastProtExt(org, MULTICAST_PHS, pr_global_struct->dimension_send, 0, 0);
|
||||
for(;;)
|
||||
{
|
||||
MSG_WriteByte (&sv.multicast, svc_temp_entity);
|
||||
MSG_WriteByte (&sv.multicast, old?TE_EXPLOSION:TEQW_EXPLOSION2);
|
||||
MSG_WriteCoord (&sv.multicast, org[0]);
|
||||
MSG_WriteCoord (&sv.multicast, org[1]);
|
||||
MSG_WriteCoord (&sv.multicast, org[2]);
|
||||
if (!old)
|
||||
{
|
||||
MSG_WriteByte (&sv.multicast, start);
|
||||
MSG_WriteByte (&sv.multicast, length);
|
||||
}
|
||||
#ifdef NQPROT
|
||||
MSG_WriteByte (&sv.nqmulticast, svc_temp_entity);
|
||||
MSG_WriteByte (&sv.nqmulticast, TENQ_EXPLOSION2);
|
||||
MSG_WriteCoord (&sv.nqmulticast, org[0]);
|
||||
MSG_WriteCoord (&sv.nqmulticast, org[1]);
|
||||
MSG_WriteCoord (&sv.nqmulticast, org[2]);
|
||||
MSG_WriteByte (&sv.nqmulticast, start);
|
||||
MSG_WriteByte (&sv.nqmulticast, length);
|
||||
#endif
|
||||
|
||||
if (old)
|
||||
{
|
||||
SV_MulticastProtExt(org, MULTICAST_PHS, pr_global_struct->dimension_send, 0, PEXT_TE_BULLET);
|
||||
break;
|
||||
}
|
||||
else
|
||||
SV_MulticastProtExt(org, MULTICAST_PHS, pr_global_struct->dimension_send, PEXT_TE_BULLET, 0);
|
||||
old = true;
|
||||
}
|
||||
}
|
||||
|
||||
//DP_TE_FLAMEJET
|
||||
|
|
|
@ -2097,6 +2097,7 @@ qboolean PR_LoadQ1QVM(void)
|
|||
pr_global_ptrs->spawnparamglobals[i] = (float*)((char*)VM_MemoryBase(q1qvm)+(qintptr_t)(&global->parm1 + i));
|
||||
for (; i < NUM_SPAWN_PARMS; i++)
|
||||
pr_global_ptrs->spawnparamglobals[i] = NULL;
|
||||
pr_global_ptrs->parm_string = NULL;
|
||||
|
||||
#define emufield(n,t) if (field[i].type == t && !strcmp(#n, fname)) {fofs.n = (field[i].ofs - WASTED_EDICT_T_SIZE)/sizeof(float); continue;}
|
||||
if (VM_NonNative(q1qvm))
|
||||
|
|
|
@ -100,6 +100,7 @@ typedef struct nqglobalvars_s
|
|||
float *input_buttons;
|
||||
vec3_t *global_gravitydir;
|
||||
float *spawnparamglobals[NUM_SPAWN_PARMS];
|
||||
string_t *parm_string;
|
||||
int *serverid;
|
||||
} globalptrs_t;
|
||||
|
||||
|
|
|
@ -803,11 +803,7 @@ qboolean SV_LoadLevelCache(const char *savename, const char *level, const char *
|
|||
e2 = svprogfuncs->GetEdictFieldValue(svprogfuncs, ent, "stats_restored", ev_float, NULL);
|
||||
if (e2)
|
||||
e2->_float = 1;
|
||||
for (j=0 ; j< NUM_SPAWN_PARMS ; j++)
|
||||
{
|
||||
if (pr_global_ptrs->spawnparamglobals[j])
|
||||
*pr_global_ptrs->spawnparamglobals[j] = host_client->spawn_parms[j];
|
||||
}
|
||||
SV_SpawnParmsToQC(host_client);
|
||||
pr_global_struct->time = sv.world.physicstime;
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
|
||||
ent->area.next = ent->area.prev = NULL;
|
||||
|
|
|
@ -333,13 +333,18 @@ typedef struct
|
|||
float move_msecs; //
|
||||
int packetsizein; //amount of data received for this frame
|
||||
int packetsizeout; //amount of data that was sent in the frame
|
||||
packet_entities_t entities; //package containing entity states that were sent in this frame, for deltaing
|
||||
|
||||
packet_entities_t qwentities; //package containing entity states that were sent in this frame, for deltaing
|
||||
|
||||
struct resendinfo_s
|
||||
{
|
||||
unsigned int entnum;
|
||||
unsigned int bits; //delta
|
||||
unsigned int bits; //delta (fte or dpp5+)
|
||||
unsigned int flags; //csqc
|
||||
} *resend;
|
||||
unsigned int numresend;
|
||||
unsigned int maxresend;
|
||||
|
||||
unsigned short resendstats[32];//the number of each entity that was sent in this frame
|
||||
unsigned int numresendstats; //the bits of each entity that were sent in this frame
|
||||
|
||||
|
@ -396,7 +401,7 @@ typedef struct //merge?
|
|||
enum
|
||||
{
|
||||
PRESPAWN_INVALID=0,
|
||||
PRESPAWN_PROTOCOLSWITCH, //nq drops unreliables until reliables are acked
|
||||
PRESPAWN_PROTOCOLSWITCH, //nq drops unreliables until reliables are acked. this gives us a chance to drop any clc_move packets with formats from the previous map
|
||||
PRESPAWN_SERVERINFO,
|
||||
PRESPAWN_SOUNDLIST, //nq skips these
|
||||
PRESPAWN_VWEPMODELLIST, //qw ugly extension.
|
||||
|
@ -504,7 +509,8 @@ typedef struct client_s
|
|||
|
||||
// spawn parms are carried from level to level
|
||||
float spawn_parms[NUM_SPAWN_PARMS];
|
||||
char *spawninfo;
|
||||
char *spawn_parmstring; //qc-specified data.
|
||||
char *spawninfo; //entity-formatted data (for hexen2's ClientReEnter)
|
||||
float spawninfotime;
|
||||
float nextservertimeupdate; //next time to send STAT_TIME
|
||||
float lastoutgoingphysicstime;//sv.world.physicstime of the last outgoing message.
|
||||
|
@ -1119,6 +1125,8 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg);
|
|||
void SVQW_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qboolean force, unsigned int protext);
|
||||
|
||||
client_t *SV_AddSplit(client_t *controller, char *info, int id);
|
||||
void SV_SpawnParmsToQC(client_t *client);
|
||||
void SV_SpawnParmsToClient(client_t *client);
|
||||
void SV_GetNewSpawnParms(client_t *cl);
|
||||
void SV_SaveSpawnparms (void);
|
||||
void SV_SaveSpawnparmsClient(client_t *client, float *transferparms); //if transferparms, calls SetTransferParms instead, and does not modify the player.
|
||||
|
|
|
@ -759,7 +759,8 @@ void SV_Map_f (void)
|
|||
Z_Free(host_client->spawninfo);
|
||||
host_client->spawninfo = NULL;
|
||||
memset(host_client->spawn_parms, 0, sizeof(host_client->spawn_parms));
|
||||
SV_GetNewSpawnParms(host_client);
|
||||
if (host_client->state > cs_zombie)
|
||||
SV_GetNewSpawnParms(host_client);
|
||||
}
|
||||
|
||||
if (preserveplayers && svprogfuncs && host_client->state == cs_spawned && host_client->spawninfo)
|
||||
|
@ -2855,16 +2856,14 @@ void SV_MemInfo_f(void)
|
|||
sz += lp->length;
|
||||
|
||||
fr = 0;
|
||||
fr += sizeof(client_frame_t)*UPDATE_BACKUP;
|
||||
if (cl->pendingdeltabits)
|
||||
{
|
||||
int maxents = cl->frameunion.frames[0].entities.max_entities; /*this is the max number of ents updated per frame. we can't track more, so...*/
|
||||
fr = sizeof(cl)*UPDATE_BACKUP+
|
||||
sizeof(*cl->pendingdeltabits)*cl->max_net_ents+
|
||||
sizeof(unsigned int)*maxents*UPDATE_BACKUP+
|
||||
sizeof(unsigned int)*maxents*UPDATE_BACKUP;
|
||||
fr += sizeof(cl)*UPDATE_BACKUP+
|
||||
sizeof(*cl->pendingdeltabits)*cl->max_net_ents;
|
||||
}
|
||||
else
|
||||
fr = (sizeof(client_frame_t)+sizeof(entity_state_t)*cl->frameunion.frames[0].entities.max_entities)*UPDATE_BACKUP;
|
||||
fr += sizeof(*cl->frameunion.frames[0].resend)*cl->frameunion.frames[0].maxresend*UPDATE_BACKUP;
|
||||
fr += sizeof(entity_state_t)*cl->frameunion.frames[0].qwentities.max_entities*UPDATE_BACKUP;
|
||||
fr += sizeof(*cl->sentents.entities) * cl->sentents.max_entities;
|
||||
|
||||
csfr = sizeof(*cl->pendingcsqcbits) * cl->max_net_ents;
|
||||
|
@ -2873,7 +2872,8 @@ void SV_MemInfo_f(void)
|
|||
}
|
||||
}
|
||||
|
||||
//FIXME: report vm memory
|
||||
if (sv.world.progs)
|
||||
Con_Printf("ssqc: %u (used) / %u (reserved)\n", sv.world.progs->stringtablesize, sv.world.progs->stringtablemaxsize);
|
||||
}
|
||||
|
||||
void SV_Download_f (void)
|
||||
|
|
|
@ -125,18 +125,18 @@ unsigned int SV_Q2BSP_FatPVS (model_t *mod, vec3_t org, qbyte *resultbuf, unsig
|
|||
#endif
|
||||
|
||||
|
||||
void SVFTE_ExpandFrames(client_t *client, int require)
|
||||
void SV_ExpandNackFrames(client_t *client, int require)
|
||||
{
|
||||
client_frame_t *newframes;
|
||||
char *ptr;
|
||||
int i;
|
||||
int maxents = require * 2; /*this is the max number of ents updated per frame. we can't track more, so...*/
|
||||
if (maxents > client->max_net_ents)
|
||||
maxents = client->max_net_ents;
|
||||
int maxlog = require * 2; /*this is the max number of ents updated per frame. we can't track more, so...*/
|
||||
if (maxlog > client->max_net_ents)
|
||||
maxlog = client->max_net_ents;
|
||||
ptr = Z_Malloc( sizeof(client_frame_t)*UPDATE_BACKUP+
|
||||
sizeof(*client->pendingdeltabits)*client->max_net_ents+
|
||||
sizeof(*client->pendingcsqcbits)*client->max_net_ents+
|
||||
sizeof(newframes[i].resend)*maxents*UPDATE_BACKUP);
|
||||
sizeof(newframes[i].resend)*maxlog*UPDATE_BACKUP);
|
||||
newframes = (void*)ptr;
|
||||
memcpy(newframes, client->frameunion.frames, sizeof(client_frame_t)*UPDATE_BACKUP);
|
||||
ptr += sizeof(client_frame_t)*UPDATE_BACKUP;
|
||||
|
@ -148,9 +148,11 @@ void SVFTE_ExpandFrames(client_t *client, int require)
|
|||
ptr += sizeof(*client->pendingcsqcbits)*client->max_net_ents;
|
||||
for (i = 0; i < UPDATE_BACKUP; i++)
|
||||
{
|
||||
newframes[i].entities.max_entities = maxents;
|
||||
newframes[i].maxresend = maxlog;
|
||||
newframes[i].qwentities.max_entities = 0;
|
||||
newframes[i].resend = (void*)ptr;
|
||||
memcpy(newframes[i].resend, client->frameunion.frames[i].resend, sizeof(newframes[i].resend)*client->frameunion.frames[i].entities.num_entities);
|
||||
newframes[i].numresend = client->frameunion.frames[i].numresend;
|
||||
memcpy(newframes[i].resend, client->frameunion.frames[i].resend, sizeof(newframes[i].resend)*newframes[i].numresend);
|
||||
newframes[i].senttime = realtime;
|
||||
}
|
||||
Z_Free(client->frameunion.frames);
|
||||
|
@ -348,10 +350,11 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber)
|
|||
qboolean writtenheader = false;
|
||||
int viewerent;
|
||||
int entnum;
|
||||
int lognum = client->frameunion.frames[currentsequence & UPDATE_MASK].entities.num_entities;
|
||||
client_frame_t *frame = &client->frameunion.frames[currentsequence & UPDATE_MASK];
|
||||
int lognum = frame->numresend;
|
||||
|
||||
struct resendinfo_s *resend = client->frameunion.frames[currentsequence & UPDATE_MASK].resend;
|
||||
int maxlog = client->frameunion.frames[currentsequence & UPDATE_MASK].entities.max_entities;
|
||||
struct resendinfo_s *resend = frame->resend;
|
||||
int maxlog = frame->maxresend;
|
||||
|
||||
//we don't check that we got some already - because this is delta compressed!
|
||||
|
||||
|
@ -391,7 +394,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber)
|
|||
|
||||
if (lognum > maxlog)
|
||||
{
|
||||
SVFTE_ExpandFrames(client, lognum+1);
|
||||
SV_ExpandNackFrames(client, lognum+1);
|
||||
break;
|
||||
}
|
||||
resend[lognum].entnum = entnum;
|
||||
|
@ -444,7 +447,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber)
|
|||
|
||||
if (lognum > maxlog)
|
||||
{
|
||||
SVFTE_ExpandFrames(client, lognum+1);
|
||||
SV_ExpandNackFrames(client, lognum+1);
|
||||
break;
|
||||
}
|
||||
resend[lognum].entnum = entnum;
|
||||
|
@ -478,7 +481,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber)
|
|||
|
||||
if (lognum > maxlog)
|
||||
{
|
||||
SVFTE_ExpandFrames(client, lognum+1);
|
||||
SV_ExpandNackFrames(client, lognum+1);
|
||||
break;
|
||||
}
|
||||
resend[lognum].entnum = entnum;
|
||||
|
@ -514,7 +517,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber)
|
|||
|
||||
if (lognum > maxlog)
|
||||
{
|
||||
SVFTE_ExpandFrames(client, lognum+1);
|
||||
SV_ExpandNackFrames(client, lognum+1);
|
||||
break;
|
||||
}
|
||||
resend[lognum].entnum = entnum;
|
||||
|
@ -540,7 +543,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber)
|
|||
|
||||
csqcnuments = 0;
|
||||
|
||||
client->frameunion.frames[currentsequence & UPDATE_MASK].entities.num_entities = lognum;
|
||||
frame->numresend = lognum;
|
||||
|
||||
//prevent the qc from trying to use it at inopertune times.
|
||||
csqcmsgbuffer.maxsize = 0;
|
||||
|
@ -551,6 +554,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber)
|
|||
void SV_CSQC_DroppedPacket(client_t *client, int sequence)
|
||||
{
|
||||
int i;
|
||||
client_frame_t *frame;
|
||||
if (!ISQWCLIENT(client) && !ISNQCLIENT(client))
|
||||
return;
|
||||
|
||||
|
@ -559,39 +563,35 @@ void SV_CSQC_DroppedPacket(client_t *client, int sequence)
|
|||
Con_Printf("Server bug: No frames!\n");
|
||||
return;
|
||||
}
|
||||
frame = &client->frameunion.frames[sequence & UPDATE_MASK];
|
||||
|
||||
//skip it if we never generated that frame, to avoid pulling in stale data
|
||||
if (client->frameunion.frames[sequence & UPDATE_MASK].sequence != sequence)
|
||||
if (frame->sequence != sequence)
|
||||
{
|
||||
// Con_Printf("SV: Stale %i\n", sequence);
|
||||
return;
|
||||
}
|
||||
|
||||
//lost entities need flagging for a resend
|
||||
if (client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
|
||||
if (frame->numresend)
|
||||
{
|
||||
struct resendinfo_s *resend = client->frameunion.frames[sequence & UPDATE_MASK].resend;
|
||||
struct resendinfo_s *resend = frame->resend;
|
||||
// Con_Printf("SV: Resend %i\n", sequence);
|
||||
i = client->frameunion.frames[sequence & UPDATE_MASK].entities.num_entities;
|
||||
i = frame->numresend;
|
||||
while (i > 0)
|
||||
{
|
||||
i--;
|
||||
|
||||
// if (f[i] & UF_RESET)
|
||||
// Con_Printf("Resend %i @ %i\n", i, sequence);
|
||||
// if (f[i] & UF_REMOVE)
|
||||
// Con_Printf("Remove %i @ %i\n", i, sequence);
|
||||
client->pendingdeltabits[resend[i].entnum] |= resend[i].bits;
|
||||
client->pendingcsqcbits[resend[i].entnum] |= resend[i].flags;
|
||||
}
|
||||
client->frameunion.frames[sequence & UPDATE_MASK].entities.num_entities = 0;
|
||||
frame->numresend = 0; //don't resend the same info twice!
|
||||
}
|
||||
//lost stats do too
|
||||
if (client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
|
||||
if (frame->numresendstats)
|
||||
{
|
||||
client_t *sp;
|
||||
unsigned short *n = client->frameunion.frames[sequence & UPDATE_MASK].resendstats;
|
||||
i = client->frameunion.frames[sequence & UPDATE_MASK].numresendstats;
|
||||
unsigned short *n = frame->resendstats;
|
||||
i = frame->numresendstats;
|
||||
while(i-->0)
|
||||
{
|
||||
unsigned short s = n[i];
|
||||
|
@ -608,7 +608,7 @@ void SV_CSQC_DroppedPacket(client_t *client, int sequence)
|
|||
else
|
||||
client->pendingstats[s>>5u] |= 1u << (s & 0x1fu);
|
||||
}
|
||||
client->frameunion.frames[sequence & UPDATE_MASK].numresendstats = 0;
|
||||
frame->numresendstats = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1532,7 +1532,7 @@ qboolean SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizeb
|
|||
/*cache frame info*/
|
||||
resend = client->frameunion.frames[sequence & UPDATE_MASK].resend;
|
||||
outno = 0;
|
||||
outmax = client->frameunion.frames[sequence & UPDATE_MASK].entities.max_entities;
|
||||
outmax = client->frameunion.frames[sequence & UPDATE_MASK].maxresend;
|
||||
|
||||
/*start writing the packet*/
|
||||
MSG_WriteByte (msg, svcfte_updateentities);
|
||||
|
@ -1564,7 +1564,7 @@ qboolean SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizeb
|
|||
}
|
||||
if (outno >= outmax)
|
||||
{ //expand the frames. may need some copying...
|
||||
SVFTE_ExpandFrames(client, outno+1);
|
||||
SV_ExpandNackFrames(client, outno+1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1615,7 +1615,7 @@ qboolean SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizeb
|
|||
else
|
||||
client->nextdeltaindex = j; //we overflowed or something, start going round-robin
|
||||
|
||||
client->frameunion.frames[sequence & UPDATE_MASK].entities.num_entities = outno;
|
||||
client->frameunion.frames[sequence & UPDATE_MASK].numresend = outno;
|
||||
client->frameunion.frames[sequence & UPDATE_MASK].sequence = sequence;
|
||||
return overflow;
|
||||
}
|
||||
|
@ -1642,7 +1642,7 @@ void SVQW_EmitPacketEntities (client_t *client, packet_entities_t *to, sizebuf_t
|
|||
if (client->delta_sequence != -1)
|
||||
{
|
||||
fromframe = &client->frameunion.frames[client->delta_sequence & UPDATE_MASK];
|
||||
from = &fromframe->entities;
|
||||
from = &fromframe->qwentities;
|
||||
oldmax = from->num_entities;
|
||||
|
||||
MSG_WriteByte (msg, svc_deltapacketentities);
|
||||
|
@ -1916,122 +1916,148 @@ void SVDP_EmitEntityDelta(unsigned int bits, entity_state_t *to, sizebuf_t *msg,
|
|||
MSG_WriteShort(msg, to->u.q1.traileffectnum);
|
||||
}
|
||||
|
||||
void SVDP_EmitEntitiesUpdate (client_t *client, packet_entities_t *to, sizebuf_t *msg)
|
||||
void SVDP_EmitEntitiesUpdate (client_t *client, client_frame_t *frame, packet_entities_t *to, sizebuf_t *msg)
|
||||
{
|
||||
packet_entities_t *from;
|
||||
int oldindex, newindex;
|
||||
int oldnum, newnum;
|
||||
int oldmax;
|
||||
packet_entities_t *cur;
|
||||
int newindex;
|
||||
int curnum, newnum;
|
||||
int j;
|
||||
int sequence = client->netchan.incoming_sequence;
|
||||
|
||||
// this is the frame that we are going to delta update from
|
||||
cur = &client->sentents;
|
||||
if (!client->netchan.incoming_sequence)
|
||||
{
|
||||
oldmax = 0;
|
||||
from = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
from = &client->sentents;
|
||||
oldmax = from->num_entities;
|
||||
{ //first packet deltas from nothing.
|
||||
//so make sure we start with nothing
|
||||
cur->num_entities = 0;
|
||||
}
|
||||
|
||||
if (to->num_entities)
|
||||
{
|
||||
j = to->entities[to->num_entities-1].number+1;
|
||||
if (j > from->max_entities)
|
||||
if (j > cur->max_entities)
|
||||
{
|
||||
from->entities = BZ_Realloc(from->entities, sizeof(*from->entities) * j);
|
||||
memset(&from->entities[from->max_entities], 0, sizeof(from->entities[0]) * (j - from->max_entities));
|
||||
from->max_entities = j;
|
||||
cur->entities = BZ_Realloc(cur->entities, sizeof(*cur->entities) * j);
|
||||
memset(&cur->entities[cur->max_entities], 0, sizeof(cur->entities[0]) * (j - cur->max_entities));
|
||||
cur->max_entities = j;
|
||||
}
|
||||
while(j > client->sentents.num_entities)
|
||||
while(j > cur->num_entities)
|
||||
{
|
||||
from->entities[from->num_entities].number = 0;
|
||||
from->num_entities++;
|
||||
cur->entities[cur->num_entities].number = 0;
|
||||
cur->num_entities++;
|
||||
}
|
||||
}
|
||||
|
||||
//diff the from+to states, flagging any changed state (which is combined with any state from previous packet loss
|
||||
newindex = 0;
|
||||
oldindex = 0;
|
||||
while (newindex < to->num_entities || oldindex < oldmax)
|
||||
curnum = 0;
|
||||
while (newindex < to->num_entities || curnum < cur->num_entities)
|
||||
{
|
||||
newnum = newindex >= to->num_entities ? 0x7fff : to->entities[newindex].number;
|
||||
oldnum = oldindex >= oldmax ? 0x7fff : from->entities[oldindex].number;
|
||||
newnum = newindex >= to->num_entities ? 0x8000 : to->entities[newindex].number;
|
||||
|
||||
if (newnum < oldnum)
|
||||
{ // this is a new entity, send it from the baseline... as far as dp understands it...
|
||||
client->pendingdeltabits[newnum] |= E5_FULLUPDATE | SVDP_CalcDelta(&nullentitystate, NULL, &to->entities[oldindex], to->bonedata);
|
||||
newindex++;
|
||||
}
|
||||
else if (newnum > oldnum)
|
||||
{ // the old entity isn't present in the new message
|
||||
client->pendingdeltabits[oldnum] = E5_SERVERREMOVE;
|
||||
oldindex++;
|
||||
}
|
||||
else
|
||||
{ // delta update from old position
|
||||
client->pendingdeltabits[newnum] |= SVDP_CalcDelta(&from->entities[oldindex], NULL/*from->bonedata*/, &to->entities[oldindex], to->bonedata);
|
||||
if (client->pendingdeltabits[newnum] & E5_SERVERREMOVE)
|
||||
{ //if it got flagged for removal, but its actually a valid entity, then assume that its an outdated remove and just flag it for a full update in case stuff got lost.
|
||||
client->pendingdeltabits[newnum] &= ~E5_SERVERREMOVE;
|
||||
client->pendingdeltabits[newnum] |= E5_FULLUPDATE;
|
||||
if (newnum == curnum)
|
||||
{
|
||||
if (cur->entities[curnum].number)
|
||||
{ //regular update
|
||||
client->pendingdeltabits[newnum] |= SVDP_CalcDelta(&cur->entities[curnum], NULL/*cur->bonedata*/, &to->entities[newindex], to->bonedata);
|
||||
if (client->pendingdeltabits[newnum] & E5_SERVERREMOVE)
|
||||
{ //if it got flagged for removal, but its actually a valid entity, then assume that its an outdated remove and just flag it for a full update in case stuff got lost.
|
||||
client->pendingdeltabits[newnum] &= ~E5_SERVERREMOVE;
|
||||
client->pendingdeltabits[newnum] |= E5_FULLUPDATE;
|
||||
}
|
||||
}
|
||||
oldindex++;
|
||||
else
|
||||
{ //this ent is new
|
||||
//dpp5+ does not use baselines. it just resets from default state.
|
||||
client->pendingdeltabits[newnum] = E5_FULLUPDATE | SVDP_CalcDelta(&nullentitystate, NULL, &to->entities[newindex], to->bonedata);
|
||||
}
|
||||
cur->entities[curnum] = to->entities[newindex];
|
||||
newindex++;
|
||||
}
|
||||
else if (cur->entities[curnum].number)
|
||||
{ //this entity was apparently removed since last time.
|
||||
cur->entities[curnum].number = 0;
|
||||
client->pendingdeltabits[curnum] = E5_SERVERREMOVE;
|
||||
}
|
||||
curnum++;
|
||||
}
|
||||
|
||||
to = cur;
|
||||
|
||||
//loop through all ents and send them as required
|
||||
|
||||
// Con_Printf ("frame %i\n", client->netchan.incoming_sequence);
|
||||
|
||||
MSG_WriteByte(msg, svcdp_entities);
|
||||
MSG_WriteLong(msg, client->netchan.incoming_sequence); //sequence for the client to ack (any bits sent in unacked frames will be re-queued)
|
||||
if (client->protocol == SCP_DARKPLACES7)
|
||||
MSG_WriteLong(msg, client->last_sequence); //movement sequence that we are acking.
|
||||
|
||||
client->netchan.incoming_sequence++;
|
||||
|
||||
//add in the bitmasks of dropped packets.
|
||||
|
||||
/* newindex = 0;
|
||||
oldindex = 0;
|
||||
//Con_Printf ("---%i to %i ----\n", client->delta_sequence & UPDATE_MASK
|
||||
// , client->netchan.outgoing_sequence & UPDATE_MASK);
|
||||
while (newindex < to->num_entities || oldindex < oldmax)
|
||||
{
|
||||
newnum = newindex >= to->num_entities ? 0x7fff : to->entities[newindex].number;
|
||||
oldnum = oldindex >= oldmax ? 0x7fff : from->entities[oldindex].number;
|
||||
unsigned int bits;
|
||||
int outno, outmax = frame->maxresend;
|
||||
qboolean overflow = false;
|
||||
struct resendinfo_s *resend = frame->resend;
|
||||
|
||||
if (newnum == oldnum)
|
||||
{ // delta update from old position
|
||||
//Con_Printf ("delta %i\n", newnum);
|
||||
SVDP_EmitEntityDelta (&from->entities[oldindex], &to->entities[newindex], msg, false, to->bonedata);
|
||||
oldindex++;
|
||||
newindex++;
|
||||
continue;
|
||||
}
|
||||
MSG_WriteByte(msg, svcdp_entities);
|
||||
MSG_WriteLong(msg, sequence); //sequence for the client to ack (any bits sent in unacked frames will be re-queued)
|
||||
if (client->protocol == SCP_DARKPLACES7)
|
||||
MSG_WriteLong(msg, client->last_sequence); //movement sequence that we are acking.
|
||||
|
||||
if (newnum < oldnum)
|
||||
{ // this is a new entity, send it from the baseline... as far as dp understands it...
|
||||
//Con_Printf ("baseline %i\n", newnum);
|
||||
SVDP_EmitEntityDelta (&nullentitystate, &to->entities[newindex], msg, true, to->bonedata);
|
||||
newindex++;
|
||||
continue;
|
||||
}
|
||||
client->netchan.incoming_sequence++;
|
||||
|
||||
if (newnum > oldnum)
|
||||
{ // the old entity isn't present in the new message
|
||||
// Con_Printf("sRemove %i\n", oldnum);
|
||||
MSG_WriteShort(msg, oldnum | 0x8000);
|
||||
oldindex++;
|
||||
continue;
|
||||
//add in the bitmasks of dropped packets.
|
||||
for(outno = 0, j = 1; j < to->num_entities; j++)
|
||||
{
|
||||
bits = client->pendingdeltabits[j];
|
||||
if (!bits)
|
||||
continue;
|
||||
if (msg->cursize + 50 > msg->maxsize)
|
||||
{
|
||||
overflow = true;
|
||||
break; /*give up if it gets full. FIXME: bone data is HUGE.*/
|
||||
}
|
||||
if (outno >= outmax)
|
||||
{ //expand the frames. may need some copying...
|
||||
SV_ExpandNackFrames(client, outno+1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (bits & E5_SERVERREMOVE)
|
||||
{ //if reset is set, then reset was set eroneously.
|
||||
MSG_WriteShort(msg, j | 0x8000);
|
||||
resend[outno].bits = E5_SERVERREMOVE;
|
||||
// Con_Printf("REMOVE %i @ %i\n", j, sequence);
|
||||
}
|
||||
else if (to->entities[j].number) /*only send a new copy of the ent if they actually have one already*/
|
||||
{
|
||||
//if we didn't reach the end in the last packet, start at that point to avoid spam
|
||||
//player slots are exempt from this, so they are in every packet (strictly speaking only the local player 'needs' this, but its nice to have it for high-priority targets too)
|
||||
if (j < client->nextdeltaindex && j > svs.allocated_client_slots)
|
||||
continue;
|
||||
|
||||
if (bits & E5_FULLUPDATE)
|
||||
{
|
||||
/*flag the entity for the next packet, so we always get two resets when it appears, to reduce the effects of packetloss on seeing rockets etc*/
|
||||
bits = E5_FULLUPDATE | SVDP_CalcDelta(&nullentitystate, NULL, &to->entities[j], to->bonedata);
|
||||
resend[outno].bits = E5_FULLUPDATE;
|
||||
// Con_Printf("RESET %i @ %i\n", j, sequence);
|
||||
}
|
||||
else
|
||||
resend[outno].bits = bits;
|
||||
|
||||
SVDP_EmitEntityDelta (bits, &to->entities[j], msg, to->bonedata);
|
||||
}
|
||||
|
||||
client->pendingdeltabits[j] = 0;
|
||||
|
||||
resend[outno].flags = 0;
|
||||
resend[outno++].entnum = j;
|
||||
}
|
||||
MSG_WriteShort(msg, 0x8000); //dp5+ uses 'remove world' as a terminator.
|
||||
frame->numresend = outno;
|
||||
frame->sequence = sequence;
|
||||
|
||||
if (j == to->num_entities) //looks like we sent them all
|
||||
client->nextdeltaindex = 0; //start afresh with the next packet.
|
||||
else
|
||||
client->nextdeltaindex = j; //we overflowed or something, start going round-robin
|
||||
}
|
||||
*/
|
||||
MSG_WriteShort(msg, 0x8000);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -3965,7 +3991,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
|
|||
}
|
||||
|
||||
host_client = client;
|
||||
if ((client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) || !frame->entities.entities)
|
||||
if ((client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) || !frame->qwentities.entities || ISNQCLIENT(client))
|
||||
{
|
||||
pack = &svs.entstatebuffer;
|
||||
if (pack->max_entities < client->max_net_ents)
|
||||
|
@ -3976,7 +4002,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
|
|||
}
|
||||
}
|
||||
else
|
||||
pack = &frame->entities;
|
||||
pack = &frame->qwentities;
|
||||
SV_Snapshot_Clear(pack);
|
||||
|
||||
if (!pack->entities)
|
||||
|
@ -4024,7 +4050,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
|
|||
}
|
||||
}
|
||||
else if (client->protocol == SCP_DARKPLACES6 || client->protocol == SCP_DARKPLACES7)
|
||||
SVDP_EmitEntitiesUpdate(client, pack, msg);
|
||||
SVDP_EmitEntitiesUpdate(client, frame, pack, msg);
|
||||
else
|
||||
{
|
||||
for (e = 0; e < pack->num_entities; e++)
|
||||
|
|
|
@ -271,14 +271,40 @@ void SVQ1_CreateBaseline (void)
|
|||
}
|
||||
}
|
||||
|
||||
void SV_SpawnParmsToQC(client_t *client)
|
||||
{
|
||||
int i;
|
||||
// copy spawn parms out of the client_t
|
||||
for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
|
||||
{
|
||||
if (pr_global_ptrs->spawnparamglobals[i])
|
||||
*pr_global_ptrs->spawnparamglobals[i] = client->spawn_parms[i];
|
||||
}
|
||||
if (pr_global_ptrs->parm_string)
|
||||
*pr_global_ptrs->parm_string = client->spawn_parmstring?PR_TempString(sv.world.progs, client->spawn_parmstring):0;
|
||||
}
|
||||
|
||||
void SV_SpawnParmsToClient(client_t *client)
|
||||
{
|
||||
int i;
|
||||
for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
|
||||
{
|
||||
if (pr_global_ptrs->spawnparamglobals[i])
|
||||
client->spawn_parms[i] = *pr_global_ptrs->spawnparamglobals[i];
|
||||
else
|
||||
client->spawn_parms[i] = 0;
|
||||
}
|
||||
Z_Free(client->spawn_parmstring);
|
||||
if (pr_global_ptrs->parm_string)
|
||||
client->spawn_parmstring = Z_StrDup(PR_GetString(sv.world.progs, *pr_global_ptrs->parm_string));
|
||||
else
|
||||
client->spawn_parmstring = NULL;
|
||||
}
|
||||
|
||||
void SV_SaveSpawnparmsClient(client_t *client, float *transferparms)
|
||||
{
|
||||
int j;
|
||||
for (j=0 ; j<NUM_SPAWN_PARMS ; j++)
|
||||
{
|
||||
if (pr_global_ptrs->spawnparamglobals[j])
|
||||
*pr_global_ptrs->spawnparamglobals[j] = client->spawn_parms[j];
|
||||
}
|
||||
SV_SpawnParmsToQC(client);
|
||||
|
||||
#ifdef VM_Q1
|
||||
if (svs.gametype == GT_Q1QVM)
|
||||
|
@ -314,11 +340,7 @@ void SV_SaveSpawnparmsClient(client_t *client, float *transferparms)
|
|||
}
|
||||
else
|
||||
{
|
||||
for (j=0 ; j<NUM_SPAWN_PARMS ; j++)
|
||||
{
|
||||
if (pr_global_ptrs->spawnparamglobals[j])
|
||||
client->spawn_parms[j] = *pr_global_ptrs->spawnparamglobals[j];
|
||||
}
|
||||
SV_SpawnParmsToClient(client);
|
||||
}
|
||||
|
||||
// call the progs to get default spawn parms for the new client
|
||||
|
@ -394,8 +416,6 @@ void SV_SaveSpawnparms (void)
|
|||
|
||||
void SV_GetNewSpawnParms(client_t *cl)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (svprogfuncs) //q2 dlls don't use parms in this manner. It's all internal to the dll.
|
||||
{
|
||||
// call the progs to get default spawn parms for the new client
|
||||
|
@ -408,13 +428,8 @@ void SV_GetNewSpawnParms(client_t *cl)
|
|||
if (pr_global_ptrs->SetNewParms)
|
||||
PR_ExecuteProgram (svprogfuncs, pr_global_struct->SetNewParms);
|
||||
}
|
||||
for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
|
||||
{
|
||||
if (pr_global_ptrs->spawnparamglobals[i])
|
||||
cl->spawn_parms[i] = *pr_global_ptrs->spawnparamglobals[i];
|
||||
else
|
||||
cl->spawn_parms[i] = 0;
|
||||
}
|
||||
|
||||
SV_SpawnParmsToClient(cl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1645,14 +1660,7 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents,
|
|||
{
|
||||
sv_player = host_client->edict;
|
||||
SV_ExtractFromUserinfo(host_client, true);
|
||||
|
||||
// copy spawn parms out of the client_t
|
||||
for (j=0 ; j< NUM_SPAWN_PARMS ; j++)
|
||||
{
|
||||
if (pr_global_ptrs->spawnparamglobals[j])
|
||||
*pr_global_ptrs->spawnparamglobals[j] = host_client->spawn_parms[j];
|
||||
}
|
||||
|
||||
SV_SpawnParmsToQC(host_client);
|
||||
SV_SetUpClientEdict(host_client, sv_player);
|
||||
#ifndef NOLEGACY
|
||||
sv_player->xv->clientcolors = atoi(Info_ValueForKey(host_client->userinfo, "topcolor"))*16 + atoi(Info_ValueForKey(host_client->userinfo, "bottomcolor"));
|
||||
|
|
|
@ -1968,7 +1968,7 @@ void SV_ClientProtocolExtensionsChanged(client_t *client)
|
|||
ptr += sizeof(*client->pendingcsqcbits)*client->max_net_ents;
|
||||
for (i = 0; i < UPDATE_BACKUP; i++)
|
||||
{
|
||||
client->frameunion.frames[i].entities.max_entities = maxents;
|
||||
client->frameunion.frames[i].maxresend = maxents;
|
||||
client->frameunion.frames[i].resend = (void*)ptr;
|
||||
ptr += sizeof(*client->frameunion.frames[i].resend)*maxents;
|
||||
client->frameunion.frames[i].senttime = realtime;
|
||||
|
@ -1982,8 +1982,8 @@ void SV_ClientProtocolExtensionsChanged(client_t *client)
|
|||
client->frameunion.frames = Z_Malloc((sizeof(client_frame_t))*UPDATE_BACKUP);
|
||||
for (i = 0; i < UPDATE_BACKUP; i++)
|
||||
{
|
||||
client->frameunion.frames[i].entities.max_entities = 0;
|
||||
client->frameunion.frames[i].entities.entities = NULL;
|
||||
client->frameunion.frames[i].qwentities.max_entities = 0;
|
||||
client->frameunion.frames[i].qwentities.entities = NULL;
|
||||
client->frameunion.frames[i].senttime = realtime;
|
||||
}
|
||||
}
|
||||
|
@ -1992,8 +1992,8 @@ void SV_ClientProtocolExtensionsChanged(client_t *client)
|
|||
client->frameunion.frames = Z_Malloc((sizeof(client_frame_t)+sizeof(entity_state_t)*maxpacketentities)*UPDATE_BACKUP);
|
||||
for (i = 0; i < UPDATE_BACKUP; i++)
|
||||
{
|
||||
client->frameunion.frames[i].entities.max_entities = maxpacketentities;
|
||||
client->frameunion.frames[i].entities.entities = (entity_state_t*)(client->frameunion.frames+UPDATE_BACKUP) + i*client->frameunion.frames[i].entities.max_entities;
|
||||
client->frameunion.frames[i].qwentities.max_entities = maxpacketentities;
|
||||
client->frameunion.frames[i].qwentities.entities = (entity_state_t*)(client->frameunion.frames+UPDATE_BACKUP) + i*client->frameunion.frames[i].qwentities.max_entities;
|
||||
client->frameunion.frames[i].senttime = realtime;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1569,10 +1569,13 @@ void SV_WriteEntityDataToMessage (client_t *client, sizebuf_t *msg, int pnum)
|
|||
edict_t *ent;
|
||||
int i;
|
||||
float newa;
|
||||
client_t *controller;
|
||||
|
||||
ent = client->edict;
|
||||
if (client->controller)
|
||||
client = client->controller;
|
||||
controller = client->controller;
|
||||
else
|
||||
controller = client;
|
||||
|
||||
if (!ent)
|
||||
return;
|
||||
|
@ -1613,8 +1616,8 @@ void SV_WriteEntityDataToMessage (client_t *client, sizebuf_t *msg, int pnum)
|
|||
if (!client->lockangles)
|
||||
{
|
||||
//try to keep them vaugely reliable.
|
||||
if (client->netchan.message.cursize < client->netchan.message.maxsize/2)
|
||||
msg = &client->netchan.message;
|
||||
if (controller->netchan.message.cursize < controller->netchan.message.maxsize/2)
|
||||
msg = &controller->netchan.message;
|
||||
}
|
||||
|
||||
if (pnum)
|
||||
|
@ -1622,7 +1625,7 @@ void SV_WriteEntityDataToMessage (client_t *client, sizebuf_t *msg, int pnum)
|
|||
MSG_WriteByte(msg, svcfte_choosesplitclient);
|
||||
MSG_WriteByte(msg, pnum);
|
||||
}
|
||||
if (!client->lockangles && (client->fteprotocolextensions2 & PEXT2_SETANGLEDELTA) && client->delta_sequence != -1 && !client->viewent)
|
||||
if (!client->lockangles && (controller->fteprotocolextensions2 & PEXT2_SETANGLEDELTA) && controller->delta_sequence != -1 && !client->viewent)
|
||||
{
|
||||
MSG_WriteByte (msg, svcfte_setangledelta);
|
||||
for (i=0 ; i < 3 ; i++)
|
||||
|
|
|
@ -528,8 +528,8 @@ void SVNQ_New_f (void)
|
|||
qboolean big; //used as a filter to exclude protocols that don't match our coord+angles mode
|
||||
} preferedprot[] =
|
||||
{
|
||||
// {SCP_DARKPLACES7, true},
|
||||
// {SCP_DARKPLACES6, true},
|
||||
{SCP_DARKPLACES7, true},
|
||||
{SCP_DARKPLACES6, true},
|
||||
{SCP_FITZ666, true}, //actually 999... shh...
|
||||
{SCP_FITZ666, false},
|
||||
{SCP_BJP3, false}
|
||||
|
@ -604,7 +604,7 @@ void SVNQ_New_f (void)
|
|||
protoname = "NQ";
|
||||
}
|
||||
break;
|
||||
/*case SCP_DARKPLACES6:
|
||||
case SCP_DARKPLACES6:
|
||||
SV_LogPlayer(host_client, "new (DP6)");
|
||||
protmain = PROTOCOL_VERSION_DP6;
|
||||
protext1 &= ~PEXT_FLOATCOORDS; //always enabled, try not to break things
|
||||
|
@ -615,7 +615,7 @@ void SVNQ_New_f (void)
|
|||
protmain = PROTOCOL_VERSION_DP7;
|
||||
protext1 &= ~PEXT_FLOATCOORDS; //always enabled, try not to break things
|
||||
protoname = "DPP7";
|
||||
break;*/
|
||||
break;
|
||||
default:
|
||||
host_client->drop = true;
|
||||
protoname = "?""?""?";
|
||||
|
@ -1824,14 +1824,12 @@ void SV_SpawnSpectator (void)
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SV_Begin_Core(client_t *split)
|
||||
{ //this is the client-protocol-independant core, for q1/q2 gamecode
|
||||
|
||||
client_t *oh;
|
||||
int i;
|
||||
#ifdef HEXEN2
|
||||
if (progstype == PROG_H2 && split->playerclass)
|
||||
split->edict->xv->playerclass = split->playerclass; //make sure it's set the same as the userinfo
|
||||
|
@ -1878,11 +1876,7 @@ void SV_Begin_Core(client_t *split)
|
|||
|
||||
|
||||
// copy spawn parms out of the client_t
|
||||
for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
|
||||
{
|
||||
if (pr_global_ptrs->spawnparamglobals[i])
|
||||
*pr_global_ptrs->spawnparamglobals[i] = split->spawn_parms[i];
|
||||
}
|
||||
SV_SpawnParmsToQC(split);
|
||||
|
||||
// call the spawn function
|
||||
pr_global_struct->time = sv.world.physicstime;
|
||||
|
@ -1912,11 +1906,7 @@ void SV_Begin_Core(client_t *split)
|
|||
eval2 = svprogfuncs->GetEdictFieldValue(svprogfuncs, ent, "stats_restored", ev_float, NULL);
|
||||
if (eval2)
|
||||
eval2->_float = 1;
|
||||
for (j=0 ; j< NUM_SPAWN_PARMS ; j++)
|
||||
{
|
||||
if (pr_global_ptrs->spawnparamglobals[j])
|
||||
*pr_global_ptrs->spawnparamglobals[j] = split->spawn_parms[j];
|
||||
}
|
||||
SV_SpawnParmsToQC(split);
|
||||
pr_global_struct->time = sv.world.physicstime;
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
|
||||
G_FLOAT(OFS_PARM0) = sv.time - split->spawninfotime;
|
||||
|
@ -1925,11 +1915,7 @@ void SV_Begin_Core(client_t *split)
|
|||
else
|
||||
{
|
||||
// copy spawn parms out of the client_t
|
||||
for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
|
||||
{
|
||||
if (pr_global_ptrs->spawnparamglobals[i])
|
||||
*pr_global_ptrs->spawnparamglobals[i] = split->spawn_parms[i];
|
||||
}
|
||||
SV_SpawnParmsToQC(split);
|
||||
|
||||
// call the spawn function
|
||||
#ifdef VM_Q1
|
||||
|
@ -4991,13 +4977,8 @@ void Cmd_Join_f (void)
|
|||
#endif
|
||||
if (pr_global_ptrs->SetNewParms)
|
||||
PR_ExecuteProgram (svprogfuncs, pr_global_struct->SetNewParms);
|
||||
for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
|
||||
{
|
||||
if (pr_global_ptrs->spawnparamglobals[i])
|
||||
host_client->spawn_parms[i] = *pr_global_ptrs->spawnparamglobals[i];
|
||||
else
|
||||
host_client->spawn_parms[i] = 0;
|
||||
}
|
||||
|
||||
SV_SpawnParmsToClient(host_client);
|
||||
|
||||
#ifdef VM_Q1
|
||||
if (svs.gametype == GT_Q1QVM)
|
||||
|
@ -5131,14 +5112,8 @@ void Cmd_Observe_f (void)
|
|||
#endif
|
||||
if (pr_global_ptrs->SetNewParms)
|
||||
PR_ExecuteProgram (svprogfuncs, pr_global_struct->SetNewParms);
|
||||
for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
|
||||
{
|
||||
if (pr_global_ptrs->spawnparamglobals[i])
|
||||
host_client->spawn_parms[i] = *pr_global_ptrs->spawnparamglobals[i];
|
||||
else
|
||||
host_client->spawn_parms[i] = 0;
|
||||
}
|
||||
|
||||
SV_SpawnParmsToClient(host_client);
|
||||
SV_SpawnSpectator ();
|
||||
|
||||
// call the spawn function
|
||||
|
@ -5372,7 +5347,6 @@ static void SVNQ_Spawn_f (void)
|
|||
static void SVNQ_Begin_f (void)
|
||||
{
|
||||
unsigned pmodel = 0, emodel = 0;
|
||||
int i;
|
||||
qboolean sendangles=false;
|
||||
|
||||
if (host_client->state == cs_spawned)
|
||||
|
@ -5394,11 +5368,7 @@ static void SVNQ_Begin_f (void)
|
|||
if (SpectatorConnect)
|
||||
{
|
||||
// copy spawn parms out of the client_t
|
||||
for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
|
||||
{
|
||||
if (pr_global_ptrs->spawnparamglobals[i])
|
||||
*pr_global_ptrs->spawnparamglobals[i] = host_client->spawn_parms[i];
|
||||
}
|
||||
SV_SpawnParmsToQC(host_client);
|
||||
|
||||
// call the spawn function
|
||||
pr_global_struct->time = sv.world.physicstime;
|
||||
|
@ -5412,11 +5382,7 @@ static void SVNQ_Begin_f (void)
|
|||
sv.spawned_client_slots++;
|
||||
|
||||
// copy spawn parms out of the client_t
|
||||
for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
|
||||
{
|
||||
if (pr_global_ptrs->spawnparamglobals[i])
|
||||
*pr_global_ptrs->spawnparamglobals[i] = host_client->spawn_parms[i];
|
||||
}
|
||||
SV_SpawnParmsToQC(host_client);
|
||||
|
||||
sv.skipbprintclient = host_client;
|
||||
#ifdef VM_Q1
|
||||
|
@ -5951,6 +5917,7 @@ ucmd_t nqucmds[] =
|
|||
{"playermodel", NULL},
|
||||
{"playerskin", NULL},
|
||||
{"rate", SV_Rate_f},
|
||||
{"rate_burstsize", NULL},
|
||||
|
||||
#ifdef SVRANKING
|
||||
{"topten", Rank_ListTop10_f},
|
||||
|
|
|
@ -3977,10 +3977,15 @@ void VK_UploadLightmap(lightmapinfo_t *lm)
|
|||
mips.mip[0].needfree = false;
|
||||
mips.mip[0].width = lm->width;
|
||||
mips.mip[0].height = lm->height;
|
||||
if (lightmap_bgra)
|
||||
switch(lightmap_fmt)
|
||||
{
|
||||
case TF_BGRA32:
|
||||
mips.encoding = PTI_BGRX8;
|
||||
else
|
||||
mips.encoding = PTI_RGBX8;
|
||||
break;
|
||||
default:
|
||||
Sys_Error("Unsupported encoding\n");
|
||||
break;
|
||||
}
|
||||
mips.mipcount = 1;
|
||||
VK_LoadTextureMips(tex, &mips);
|
||||
tex->status = TEX_LOADED;
|
||||
|
|
Loading…
Reference in a new issue