mirror of
https://github.com/nzp-team/fteqw.git
synced 2025-01-19 06:51:11 +00:00
removed old scr_chatmode
splitscreen can now properly be configured via build configs, and potentially more than just 4 seats. fix splitscreen and enemycolour forcing. forcing now works, but only when all seats are on/spectating the same team. fix demo playback issue with http urls with webgl that don't allow streaming. srgb fixes for the scoreboard. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5229 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
876eb0cf39
commit
8c02fb26b3
40 changed files with 410 additions and 332 deletions
|
@ -538,7 +538,7 @@ qboolean Cam_DrawViewModel(playerview_t *pv)
|
|||
|
||||
int Cam_TrackNum(playerview_t *pv)
|
||||
{
|
||||
if (pv->spectator && pv->cam_state == CAM_EYECAM)
|
||||
if (pv->spectator && CAM_ISLOCKED(pv))
|
||||
return pv->cam_spec_track;
|
||||
return -1;
|
||||
}
|
||||
|
@ -659,6 +659,9 @@ static qboolean Cam_IsVisible(vec3_t playerorigin, vec3_t vec)
|
|||
vec3_t v;
|
||||
float d;
|
||||
|
||||
VectorClear(pmove.player_mins);
|
||||
VectorClear(pmove.player_maxs);
|
||||
|
||||
trace = Cam_DoTrace(playerorigin, vec);
|
||||
if (trace.fraction != 1 || /*trace.inopen ||*/ trace.inwater)
|
||||
return false;
|
||||
|
@ -850,6 +853,15 @@ void Cam_Track(playerview_t *pv, usercmd_t *cmd)
|
|||
|
||||
frame = &cl.inframes[cl.validsequence & UPDATE_MASK];
|
||||
player = frame->playerstate + pv->cam_spec_track;
|
||||
if (!cmd)
|
||||
{ //this is our fancy force-wallcam mode.
|
||||
if (pv->cam_state != CAM_WALLCAM || !Cam_IsVisible(player->origin, pv->cam_desired_position))
|
||||
{
|
||||
if (!InitFlyby(pv, pv->cam_desired_position, player->origin, player->viewangles, true))
|
||||
InitFlyby(pv, pv->cam_desired_position, player->origin, player->viewangles, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
self = frame->playerstate + pv->playernum;
|
||||
|
||||
if (!cl_chasecam.value && (pv->cam_state != CAM_WALLCAM || !Cam_IsVisible(player->origin, pv->cam_desired_position)))
|
||||
|
@ -873,7 +885,7 @@ void Cam_Track(playerview_t *pv, usercmd_t *cmd)
|
|||
return;
|
||||
|
||||
|
||||
if (cl_chasecam.value || scr_chatmode == 2)
|
||||
if (cl_chasecam.value)
|
||||
{
|
||||
float *neworg;
|
||||
// float *newang;
|
||||
|
@ -882,8 +894,7 @@ void Cam_Track(playerview_t *pv, usercmd_t *cmd)
|
|||
else
|
||||
neworg = player->origin;
|
||||
|
||||
if (scr_chatmode != 2)
|
||||
pv->cam_lastviewtime = realtime;
|
||||
pv->cam_lastviewtime = realtime;
|
||||
|
||||
// VectorCopy(newang, pv->viewangles);
|
||||
if (memcmp(neworg, &self->origin, sizeof(vec3_t)) != 0)
|
||||
|
@ -1145,7 +1156,7 @@ void Cam_FinishMove(playerview_t *pv, usercmd_t *cmd)
|
|||
|
||||
void Cam_Reset(void)
|
||||
{
|
||||
int pnum;
|
||||
unsigned int pnum;
|
||||
for (pnum = 0; pnum < MAX_SPLITS; pnum++)
|
||||
{
|
||||
playerview_t *pv = &cl.playerview[pnum];
|
||||
|
|
|
@ -1958,19 +1958,19 @@ void CL_Record_f (void)
|
|||
MSG_WriteByte (&buf, svc_setview);
|
||||
MSG_WriteEntity (&buf, cl.playerview[0].viewentity);
|
||||
|
||||
MSG_WriteByte (&buf, svc_signonnum);
|
||||
MSG_WriteByte (&buf, svcnq_signonnum);
|
||||
MSG_WriteByte (&buf, 1);
|
||||
CL_WriteRecordDemoMessage (&buf, seq++);
|
||||
|
||||
seq = CL_Record_ParticlesStaticsBaselines(&buf, seq);
|
||||
//fixme: brushes...
|
||||
MSG_WriteByte (&buf, svc_signonnum);
|
||||
MSG_WriteByte (&buf, svcnq_signonnum);
|
||||
MSG_WriteByte (&buf, 2);
|
||||
CL_WriteRecordDemoMessage (&buf, seq++);
|
||||
//fixme: clients
|
||||
seq = CL_Record_Lightstyles(&buf, seq);
|
||||
//fixme: stats
|
||||
MSG_WriteByte (&buf, svc_signonnum);
|
||||
MSG_WriteByte (&buf, svcnq_signonnum);
|
||||
MSG_WriteByte (&buf, 3);
|
||||
CL_WriteRecordDemoMessage (&buf, seq++);
|
||||
break;
|
||||
|
|
|
@ -4763,9 +4763,9 @@ qboolean Host_BeginFileDownload(struct dl_download *dl, char *mimetype)
|
|||
if (!(f->flags & HRF_FILETYPES))
|
||||
{
|
||||
if (mimetype)
|
||||
Con_Printf("mime type \"%s\" and file extension of \"%s\" not recognised\n", mimetype, f->fname);
|
||||
Con_Printf("mime type \"%s\" nor file extension of \"%s\" not known\n", mimetype, f->fname);
|
||||
else
|
||||
Con_Printf("file extension of \"%s\" not recognised\n", f->fname);
|
||||
Con_Printf("file extension of \"%s\" not known\n", f->fname);
|
||||
//file type not guessable from extension either.
|
||||
f->flags |= HRF_ABORT;
|
||||
Host_DoRunFile(f);
|
||||
|
@ -4891,33 +4891,33 @@ done:
|
|||
return;
|
||||
}
|
||||
|
||||
if (!(f->flags & HRF_FILETYPES))
|
||||
{
|
||||
#ifdef WEBCLIENT
|
||||
if (isurl(f->fname) && !f->srcfile)
|
||||
if (isurl(f->fname) && !f->srcfile)
|
||||
{
|
||||
if (!(f->flags & HRF_OPENED))
|
||||
{
|
||||
if (!(f->flags & HRF_OPENED))
|
||||
struct dl_download *dl;
|
||||
f->flags |= HRF_OPENED;
|
||||
dl = HTTP_CL_Get(f->fname, NULL, Host_RunFileDownloaded);
|
||||
if (dl)
|
||||
{
|
||||
struct dl_download *dl;
|
||||
f->flags |= HRF_OPENED;
|
||||
dl = HTTP_CL_Get(f->fname, NULL, Host_RunFileDownloaded);
|
||||
if (dl)
|
||||
{
|
||||
f->flags |= HRF_DOWNLOADED;
|
||||
dl->notifystarted = Host_BeginFileDownload;
|
||||
dl->user_ctx = f;
|
||||
f->flags |= HRF_DOWNLOADED;
|
||||
dl->notifystarted = Host_BeginFileDownload;
|
||||
dl->user_ctx = f;
|
||||
|
||||
if (!(f->flags & HRF_WAITING))
|
||||
{
|
||||
f->flags |= HRF_WAITING;
|
||||
waitingformanifest++;
|
||||
}
|
||||
return;
|
||||
if (!(f->flags & HRF_WAITING))
|
||||
{
|
||||
f->flags |= HRF_WAITING;
|
||||
waitingformanifest++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!(f->flags & HRF_FILETYPES))
|
||||
{
|
||||
f->flags |= Host_GuessFileType(NULL, f->fname);
|
||||
|
||||
//if we still don't know what it is, give up.
|
||||
|
@ -4939,10 +4939,29 @@ done:
|
|||
|
||||
if (f->flags & HRF_DEMO)
|
||||
{
|
||||
//play directly via system path, no prompts needed
|
||||
FS_FixupGamedirForExternalFile(f->fname, loadcommand, sizeof(loadcommand));
|
||||
Cbuf_AddText(va("playdemo \"%s\"\n", loadcommand), RESTRICT_LOCAL);
|
||||
|
||||
if (f->srcfile)
|
||||
{
|
||||
VFS_SEEK(f->srcfile, 0);
|
||||
if (f->flags & HRF_DEMO_QWD)
|
||||
CL_PlayDemoStream(f->srcfile, f->fname, true, DPB_QUAKEWORLD, 0);
|
||||
#ifdef Q2CLIENT
|
||||
else if (f->flags & HRF_DEMO_DM2)
|
||||
CL_PlayDemoStream(f->srcfile, f->fname, true, DPB_QUAKE2, 0);
|
||||
#endif
|
||||
#ifdef NQPROT
|
||||
else if (f->flags & HRF_DEMO_DEM)
|
||||
CL_PlayDemoStream(f->srcfile, f->fname, true, DPB_NETQUAKE, 0);
|
||||
#endif
|
||||
else //if (f->flags & HRF_DEMO_MVD)
|
||||
CL_PlayDemoStream(f->srcfile, f->fname, true, DPB_MVD, 0);
|
||||
f->srcfile = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
//play directly via system path, no prompts needed
|
||||
FS_FixupGamedirForExternalFile(f->fname, loadcommand, sizeof(loadcommand));
|
||||
Cbuf_AddText(va("playdemo \"%s\"\n", loadcommand), RESTRICT_LOCAL);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
else if (f->flags & HRF_BSP)
|
||||
|
@ -5206,7 +5225,7 @@ qboolean Host_RunFile(const char *fname, int nlen, vfsfile_t *file)
|
|||
}
|
||||
else
|
||||
#elif !defined(FTE_TARGET_WEB)
|
||||
//unix file urls are fairly consistant.
|
||||
//unix file urls are fairly consistant - must be an absolute path.
|
||||
if (nlen >= 8 && !strncmp(fname, "file:///", 8))
|
||||
{
|
||||
fname += 7;
|
||||
|
@ -5624,12 +5643,7 @@ double Host_Frame (double time)
|
|||
|
||||
if (SCR_UpdateScreen && !vid.isminimized)
|
||||
{
|
||||
extern cvar_t scr_chatmodecvar, r_stereo_method;
|
||||
|
||||
if (scr_chatmodecvar.ival && cl.intermissionmode == IM_NONE)
|
||||
scr_chatmode = (cl.playerview[0].spectator&&cl.splitclients<2&&cls.state == ca_active)?2:1;
|
||||
else
|
||||
scr_chatmode = 0;
|
||||
extern cvar_t r_stereo_method;
|
||||
|
||||
r_refdef.stereomethod = r_stereo_method.ival;
|
||||
#ifdef FTE_TARGET_WEB
|
||||
|
|
|
@ -3166,7 +3166,7 @@ static void CLQW_ParseServerData (void)
|
|||
}
|
||||
|
||||
/*parsing here is slightly different to allow us 255 max players instead of 127*/
|
||||
cl.splitclients = MSG_ReadByte();
|
||||
cl.splitclients = (qbyte)MSG_ReadByte();
|
||||
if (cl.splitclients & 128)
|
||||
{
|
||||
// spec = true;
|
||||
|
@ -3179,7 +3179,7 @@ static void CLQW_ParseServerData (void)
|
|||
cl.playerview[pnum].spectator = true;
|
||||
if (cls.z_ext & Z_EXT_VIEWHEIGHT)
|
||||
cl.playerview[pnum].viewheight = 0;
|
||||
cl.playerview[pnum].playernum = MSG_ReadByte();
|
||||
cl.playerview[pnum].playernum = (qbyte)MSG_ReadByte();
|
||||
if (cl.playerview[pnum].playernum >= cl.allocated_client_slots)
|
||||
Host_EndGame("unsupported local player slot\n");
|
||||
cl.playerview[pnum].viewentity = cl.playerview[pnum].playernum+1;
|
||||
|
@ -4921,6 +4921,13 @@ static int QDECL CLQ2_EnumeratedSkin(const char *name, qofs_t size, time_t mtime
|
|||
return true;
|
||||
}
|
||||
|
||||
//returns the player if they're not spectating.
|
||||
static int CL_TryTrackNum(playerview_t *pv)
|
||||
{
|
||||
if (pv->spectator && pv->cam_state != CAM_FREECAM && pv->cam_spec_track >= 0)
|
||||
return pv->cam_spec_track;
|
||||
return pv->playernum;
|
||||
}
|
||||
/*
|
||||
=====================
|
||||
CL_NewTranslation
|
||||
|
@ -4930,6 +4937,7 @@ void CL_NewTranslation (int slot)
|
|||
{
|
||||
int top, bottom;
|
||||
int local;
|
||||
qboolean mayforce;
|
||||
|
||||
char *s;
|
||||
player_info_t *player;
|
||||
|
@ -4974,6 +4982,24 @@ void CL_NewTranslation (int slot)
|
|||
return;
|
||||
}
|
||||
|
||||
mayforce = !(cl.fpd & FPD_NO_FORCE_COLOR);
|
||||
#if MAX_SPLITS > 1
|
||||
if (mayforce && cl.splitclients > 1 && cl.teamplay)
|
||||
{ //if we're using splitscreen, only allow team/enemy forcing if all split clients are on the same team
|
||||
char *needteam;
|
||||
int i;
|
||||
needteam = cl.players[CL_TryTrackNum(&cl.playerview[0])].team;
|
||||
for (i = 1; i < cl.splitclients; i++)
|
||||
{
|
||||
if (strcmp(needteam, cl.players[CL_TryTrackNum(&cl.playerview[i])].team))
|
||||
{
|
||||
mayforce = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
s = Skin_FindName (player);
|
||||
COM_StripExtension(s, s, MAX_QPATH);
|
||||
if (player->qwskin && !stricmp(s, player->qwskin->name))
|
||||
|
@ -4981,20 +5007,12 @@ void CL_NewTranslation (int slot)
|
|||
player->skinid = 0;
|
||||
player->model = NULL;
|
||||
|
||||
|
||||
|
||||
top = player->rtopcolor;
|
||||
bottom = player->rbottomcolor;
|
||||
if (cl.splitclients < 2 && !(cl.fpd & FPD_NO_FORCE_COLOR)) //no colour/skin forcing in splitscreen.
|
||||
|
||||
if (mayforce)
|
||||
{
|
||||
if (cl.teamplay && cl.playerview[0].spectator)
|
||||
{
|
||||
local = Cam_TrackNum(&cl.playerview[0]);
|
||||
if (local < 0)
|
||||
local = cl.playerview[0].playernum;
|
||||
}
|
||||
else
|
||||
local = cl.playerview[0].playernum;
|
||||
local = CL_TryTrackNum(&cl.playerview[0]);
|
||||
if ((cl.teamplay || cls.protocol == CP_NETQUAKE) && !strcmp(player->team, cl.players[local].team))
|
||||
{
|
||||
if (cl_teamtopcolor != ~0)
|
||||
|
@ -6676,9 +6694,9 @@ void CLQW_ParseServerMessage (void)
|
|||
Cbuf_Execute (); // make sure any stuffed commands are done
|
||||
CLQW_ParseServerData ();
|
||||
break;
|
||||
case svc_signonnum:
|
||||
case svcfte_splitscreenconfig:
|
||||
cl.splitclients = MSG_ReadByte();
|
||||
for (i = 0; i < cl.splitclients && i < 4; i++)
|
||||
for (i = 0; i < cl.splitclients && i < MAX_SPLITS; i++)
|
||||
{
|
||||
cl.playerview[i].playernum = MSG_ReadByte();
|
||||
cl.playerview[i].viewentity = cl.playerview[i].playernum+1;
|
||||
|
@ -7688,7 +7706,7 @@ void CLNQ_ParseServerMessage (void)
|
|||
cl.playerview[destsplit].viewentity = i;
|
||||
break;
|
||||
|
||||
case svc_signonnum:
|
||||
case svcnq_signonnum:
|
||||
i = MSG_ReadByte ();
|
||||
|
||||
if (i <= cls.signon)
|
||||
|
|
|
@ -527,7 +527,7 @@ static qintptr_t VARGS Plug_GetPlayerInfo(void *offset, quintptr_t mask, const q
|
|||
{
|
||||
if (i < 0)
|
||||
{
|
||||
if (i >= -MAX_SPLITS)
|
||||
if (i >= -(int)MAX_SPLITS)
|
||||
i = cl.playerview[-i-1].playernum;
|
||||
if (i < 0)
|
||||
{
|
||||
|
@ -1244,8 +1244,11 @@ qintptr_t VARGS Plug_Mod_GetPluginModelFuncs(void *offset, quintptr_t mask, cons
|
|||
GenMatrixPosQuat4Scale,
|
||||
COM_StripExtension,
|
||||
Alias_ForceConvertBoneData,
|
||||
|
||||
Terr_GetTerrainFuncs
|
||||
#ifdef TERRAIN
|
||||
Terr_GetTerrainFuncs,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
};
|
||||
if (VM_LONG(arg[0]) >= sizeof(funcs))
|
||||
return (qintptr_t)&funcs;
|
||||
|
|
|
@ -175,8 +175,6 @@ console is:
|
|||
|
||||
|
||||
|
||||
int scr_chatmode;
|
||||
extern cvar_t scr_chatmodecvar;
|
||||
|
||||
|
||||
float mousecursor_x, mousecursor_y;
|
||||
|
@ -2230,7 +2228,7 @@ void SCR_SetUpToDrawConsole (void)
|
|||
else
|
||||
scr_conlines = 0;
|
||||
}
|
||||
else if ((Key_Dest_Has(kdm_console) || scr_chatmode))
|
||||
else if (Key_Dest_Has(kdm_console))
|
||||
{
|
||||
//go half-screen if we're meant to have the console visible
|
||||
scr_conlines = vid.height*scr_consize.value; // half screen
|
||||
|
|
|
@ -697,7 +697,6 @@ struct playerview_s
|
|||
|
||||
vec3_t cam_desired_position; // where the camera wants to be
|
||||
int cam_oldbuttons; //
|
||||
vec3_t cam_viewangles; //
|
||||
double cam_lastviewtime; // timer for wallcam
|
||||
float cam_reautotrack; // timer to throttle tracking changes.
|
||||
int cam_spec_track; // player# of who we are tracking / want to track / might want to track
|
||||
|
@ -799,9 +798,9 @@ typedef struct
|
|||
lerpents_t lerpplayers[MAX_CLIENTS];
|
||||
|
||||
//when running splitscreen, we have multiple viewports all active at once
|
||||
int splitclients; //we are running this many clients split screen.
|
||||
unsigned int splitclients; //we are running this many clients split screen.
|
||||
playerview_t playerview[MAX_SPLITS];
|
||||
int defaultnetsplit;//which multiview splitscreen to parse the message for (set by mvd playback code)
|
||||
unsigned int defaultnetsplit;//which multiview splitscreen to parse the message for (set by mvd playback code)
|
||||
|
||||
// localized movement vars
|
||||
float bunnyspeedcap;
|
||||
|
|
|
@ -2988,7 +2988,10 @@ static struct pendingtextureinfo *Image_ReadKTXFile(unsigned int flags, char *fn
|
|||
mips->type = PTI_2D_ARRAY;
|
||||
}
|
||||
else
|
||||
{
|
||||
header->pixeldepth = 1;
|
||||
mips->type = PTI_2D;
|
||||
}
|
||||
}
|
||||
mips->extrafree = filedata;
|
||||
mips->encoding = encoding;
|
||||
|
|
|
@ -2542,7 +2542,9 @@ qboolean Media_PlayFilm(char *name, qboolean enqueue)
|
|||
|
||||
if (videoshader)
|
||||
{
|
||||
#ifdef HAVE_CDPLAYER
|
||||
CDAudio_Stop();
|
||||
#endif
|
||||
SCR_EndLoadingPlaque();
|
||||
|
||||
if (Key_Dest_Has(kdm_emenu))
|
||||
|
|
|
@ -995,14 +995,32 @@ void M_Menu_Teamplay_Items_Status_Location_Misc_f (void)
|
|||
|
||||
void M_Menu_Network_f (void)
|
||||
{
|
||||
#if MAX_SPLITS > 1
|
||||
extern cvar_t cl_splitscreen;
|
||||
static const char *splitopts[] = {
|
||||
"Disabled",
|
||||
"2 Screens",
|
||||
#if MAX_SPLITS > 2
|
||||
"3 Screens",
|
||||
#endif
|
||||
#if MAX_SPLITS > 3
|
||||
"4 Screens",
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
static const char *splitvalues[] = {"0", "1", "2", "3", NULL};
|
||||
static const char *splitvalues[] =
|
||||
{
|
||||
"0",
|
||||
"1",
|
||||
#if MAX_SPLITS > 2
|
||||
"2",
|
||||
#endif
|
||||
#if MAX_SPLITS > 3
|
||||
"3",
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
static const char *smoothingopts[] = {
|
||||
"Lower Latency",
|
||||
"Smoother",
|
||||
|
@ -1011,7 +1029,7 @@ void M_Menu_Network_f (void)
|
|||
};
|
||||
static const char *smoothingvalues[] = {"0", "1", "2", NULL};
|
||||
extern cvar_t cl_download_csprogs, cl_download_redirection, requiredownloads, cl_solid_players;
|
||||
extern cvar_t cl_splitscreen, cl_predict_players, cl_predict_smooth, cl_predict_extrapolate;
|
||||
extern cvar_t cl_predict_players, cl_predict_smooth, cl_predict_extrapolate;
|
||||
menu_t *menu;
|
||||
static menuresel_t resel;
|
||||
int y;
|
||||
|
@ -1031,7 +1049,9 @@ void M_Menu_Network_f (void)
|
|||
MB_CHECKBOXCVARTIP("Extrapolate Prediction", cl_predict_extrapolate, 0, "Extrapolate local player movement beyond the frames already sent to the server"),
|
||||
MB_CHECKBOXCVARTIP("Predict Other Players", cl_predict_players, 0, "Toggle player prediction"),
|
||||
MB_CHECKBOXCVARTIP("Solid Players", cl_solid_players, 0, "When running/clipping into other players, ON make it appear they are solid, OFF will make it appear like running into a marshmellon."),
|
||||
#if MAX_SPLITS > 1
|
||||
MB_COMBOCVAR("Split-screen", cl_splitscreen, splitopts, splitvalues, "Enables split screen with a number of clients. This feature requires server support."),
|
||||
#endif
|
||||
MB_END()
|
||||
};
|
||||
menu = M_Options_Title(&y, 0);
|
||||
|
|
|
@ -532,10 +532,12 @@ void M_Menu_SinglePlayer_f (void)
|
|||
b->common.width = width;
|
||||
b->common.height = 20;
|
||||
|
||||
#if MAX_SPLITS > 1
|
||||
b = (menubutton_t*)MC_AddCvarCombo(menu, 72, 72+width/2, 92, "", &cl_splitscreen, opts, vals);
|
||||
MC_AddWhiteText(menu, 72, 0, 92, "^aSplitscreen", false);
|
||||
b->common.height = 20;
|
||||
b->common.width = width;
|
||||
#endif
|
||||
|
||||
menu->cursoritem = (menuoption_t*)MC_AddCursor(menu, &resel, 54, 32);
|
||||
}
|
||||
|
|
|
@ -505,7 +505,9 @@ void M_Menu_Keys_f (void)
|
|||
int y;
|
||||
menu_t *menu;
|
||||
vfsfile_t *bindslist;
|
||||
#if MAX_SPLITS > 1
|
||||
extern cvar_t cl_splitscreen;
|
||||
#endif
|
||||
|
||||
Key_Dest_Add(kdm_emenu);
|
||||
|
||||
|
@ -533,6 +535,7 @@ void M_Menu_Keys_f (void)
|
|||
break;
|
||||
}
|
||||
|
||||
#if MAX_SPLITS > 1
|
||||
if (cl.splitclients || cl_splitscreen.ival || cl_forceseat.ival)
|
||||
{
|
||||
static char *texts[MAX_SPLITS+2] =
|
||||
|
@ -540,8 +543,12 @@ void M_Menu_Keys_f (void)
|
|||
"Depends on device",
|
||||
"Player 1",
|
||||
"Player 2",
|
||||
#if MAX_SPLITS >= 3
|
||||
"Player 3",
|
||||
#endif
|
||||
#if MAX_SPLITS >= 4
|
||||
"Player 4",
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
static char *values[MAX_SPLITS+1] =
|
||||
|
@ -549,12 +556,17 @@ void M_Menu_Keys_f (void)
|
|||
"0",
|
||||
"1",
|
||||
"2",
|
||||
#if MAX_SPLITS >= 3
|
||||
"3",
|
||||
#endif
|
||||
#if MAX_SPLITS >= 4
|
||||
"4"
|
||||
#endif
|
||||
};
|
||||
MC_AddCvarCombo(menu, 16, 170, y, "Force client", &cl_forceseat, (const char **)texts, (const char **)values);
|
||||
y+=8;
|
||||
}
|
||||
#endif
|
||||
|
||||
bindslist = FS_OpenVFS("bindlist.lst", "rb", FS_GAME);
|
||||
if (bindslist)
|
||||
|
|
|
@ -122,9 +122,9 @@ net_masterlist_t net_masterlist[] = {
|
|||
//engine-specified/maintained master lists (so users can be lazy and update the engine without having to rewrite all their configs).
|
||||
{MP_QUAKEWORLD, CVARFC("net_qwmasterextra1", "qwmaster.ocrana.de:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "Ocrana(2nd)"}, //german. admin unknown
|
||||
{MP_QUAKEWORLD, CVARFC("net_qwmasterextra2", ""/*"masterserver.exhale.de:27000" seems dead*/, CVAR_NOSAVE, Net_Masterlist_Callback)}, //german. admin unknown
|
||||
{MP_QUAKEWORLD, CVARFC("net_qwmasterextra3", "asgaard.morphos-team.net:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "Germany, admin: bigfoot"},
|
||||
// {MP_QUAKEWORLD, CVARFC("net_qwmasterextra3", "asgaard.morphos-team.net:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "Germany, admin: bigfoot"},
|
||||
{MP_QUAKEWORLD, CVARFC("net_qwmasterextra4", "master.quakeservers.net:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "Germany, admin: raz0?"},
|
||||
{MP_QUAKEWORLD, CVARFC("net_qwmasterextra5", "qwmaster.fodquake.net:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "admin: bigfoot"},
|
||||
// {MP_QUAKEWORLD, CVARFC("net_qwmasterextra5", "qwmaster.fodquake.net:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "admin: bigfoot"},
|
||||
// {MP_QUAKEWORLD, CVARFC("net_qwmasterextraHistoric", "satan.idsoftware.com:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "Official id Master"},
|
||||
// {MP_QUAKEWORLD, CVARFC("net_qwmasterextraHistoric", "satan.idsoftware.com:27002", CVAR_NOSAVE, Net_Masterlist_Callback), "Official id Master For CTF Servers"},
|
||||
// {MP_QUAKEWORLD, CVARFC("net_qwmasterextraHistoric", "satan.idsoftware.com:27003", CVAR_NOSAVE, Net_Masterlist_Callback), "Official id Master For TeamFortress Servers"},
|
||||
|
@ -890,8 +890,8 @@ qboolean Master_PassesMasks(serverinfo_t *a)
|
|||
// qboolean enabled;
|
||||
|
||||
//always filter out dead unresponsive servers.
|
||||
if (!a->ping)
|
||||
return false;
|
||||
// if (!(a->status & 1))
|
||||
// return false;
|
||||
|
||||
/* switch(a->special & SS_PROTOCOLMASK)
|
||||
{
|
||||
|
@ -1813,7 +1813,7 @@ qboolean NET_SendPollPacket(int len, void *data, netadr_t to)
|
|||
pollsocketsBCast[FIRSTIPXSOCKET+lastpollsockIPX] = false;
|
||||
}
|
||||
if (pollsocketsList[FIRSTIPXSOCKET+lastpollsockIPX]==INVALID_SOCKET)
|
||||
return; //bother
|
||||
return true; //bother
|
||||
|
||||
bcast = !memcmp(to.address.ipx, "\0\0\0\0\xff\xff\xff\xff\xff\xff", sizeof(to.address.ipx));
|
||||
if (pollsocketsBCast[FIRSTIPXSOCKET+lastpollsockIPX] != bcast)
|
||||
|
@ -2287,19 +2287,27 @@ void MasterInfo_ProcessHTTP(struct dl_download *dl)
|
|||
info->sends = 1;
|
||||
|
||||
info->special = 0;
|
||||
if (protocoltype == MP_DPMASTER)
|
||||
if (protocoltype == MP_QUAKEWORLD)
|
||||
info->special |= SS_QUAKEWORLD;
|
||||
else if (protocoltype == MP_DPMASTER)
|
||||
info->special |= SS_DARKPLACES;
|
||||
#if defined(Q2CLIENT) || defined(Q2SERVER)
|
||||
else if (protocoltype == MP_QUAKE2)
|
||||
info->special |= SS_QUAKE2;
|
||||
#endif
|
||||
#if defined(Q3CLIENT) || defined(Q3SERVER)
|
||||
else if (protocoltype == MP_QUAKE3)
|
||||
info->special |= SS_QUAKE3;
|
||||
#endif
|
||||
#ifdef NQPROT
|
||||
else if (protocoltype == MP_NETQUAKE)
|
||||
info->special |= SS_NETQUAKE;
|
||||
#endif
|
||||
|
||||
info->refreshtime = 0;
|
||||
info->ping = 0xffff;
|
||||
|
||||
snprintf(info->name, sizeof(info->name), "%s", NET_AdrToString(adrbuf, sizeof(adrbuf), &info->adr));
|
||||
snprintf(info->name, sizeof(info->name), "%s h", NET_AdrToString(adrbuf, sizeof(adrbuf), &info->adr));
|
||||
|
||||
info->next = firstserver;
|
||||
firstserver = info;
|
||||
|
@ -2398,6 +2406,7 @@ char *jsonnode(int level, char *node)
|
|||
else
|
||||
{
|
||||
info = Z_Malloc(sizeof(serverinfo_t));
|
||||
info->ping = 0xffff;
|
||||
info->adr = adr;
|
||||
info->sends = 1;
|
||||
info->special = flags;
|
||||
|
@ -2405,7 +2414,7 @@ char *jsonnode(int level, char *node)
|
|||
info->players = cp;
|
||||
info->maxplayers = mp;
|
||||
|
||||
snprintf(info->name, sizeof(info->name), "%s", *servername?servername:NET_AdrToString(servername, sizeof(servername), &info->adr));
|
||||
snprintf(info->name, sizeof(info->name), "%s j", *servername?servername:NET_AdrToString(servername, sizeof(servername), &info->adr));
|
||||
|
||||
info->next = firstserver;
|
||||
firstserver = info;
|
||||
|
@ -2963,7 +2972,7 @@ int CL_ReadServerInfo(char *msg, enum masterprotocol_e prototype, qboolean favor
|
|||
|
||||
info->adr = net_from;
|
||||
|
||||
snprintf(info->name, sizeof(info->name), "%s", NET_AdrToString(adr, sizeof(adr), &info->adr));
|
||||
snprintf(info->name, sizeof(info->name), "%s ?", NET_AdrToString(adr, sizeof(adr), &info->adr));
|
||||
|
||||
info->next = firstserver;
|
||||
firstserver = info;
|
||||
|
@ -3036,10 +3045,11 @@ int CL_ReadServerInfo(char *msg, enum masterprotocol_e prototype, qboolean favor
|
|||
peer->peer = Z_Malloc(sizeof(serverinfo_t));
|
||||
peer->peer->adr = pa;
|
||||
peer->peer->sends = 1;
|
||||
peer->peer->special = 0;
|
||||
peer->peer->special = SS_QUAKEWORLD;
|
||||
peer->peer->refreshtime = 0;
|
||||
peer->peer->ping = 0xffff;
|
||||
peer->peer->next = firstserver;
|
||||
snprintf(peer->peer->name, sizeof(peer->peer->name), "%s p", NET_AdrToString(adr, sizeof(adr), &pa));
|
||||
firstserver = peer->peer;
|
||||
}
|
||||
peer++;
|
||||
|
@ -3359,6 +3369,8 @@ void CL_MasterListParse(netadrtype_t adrtype, int type, qboolean slashpad)
|
|||
char adr[MAX_ADR_SIZE];
|
||||
int i;
|
||||
|
||||
char madr[MAX_ADR_SIZE];
|
||||
|
||||
switch(adrtype)
|
||||
{
|
||||
case NA_IP:
|
||||
|
@ -3374,6 +3386,8 @@ void CL_MasterListParse(netadrtype_t adrtype, int type, qboolean slashpad)
|
|||
return;
|
||||
}
|
||||
|
||||
NET_AdrToString(madr, sizeof(madr), &net_from);
|
||||
|
||||
MSG_ReadByte (); //should be \n
|
||||
|
||||
last = firstserver;
|
||||
|
@ -3412,6 +3426,7 @@ void CL_MasterListParse(netadrtype_t adrtype, int type, qboolean slashpad)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
info->ping = 0xffff;
|
||||
|
||||
p1 = MSG_ReadByte();
|
||||
p2 = MSG_ReadByte();
|
||||
|
@ -3431,10 +3446,11 @@ void CL_MasterListParse(netadrtype_t adrtype, int type, qboolean slashpad)
|
|||
else
|
||||
{
|
||||
info->sends = 1;
|
||||
|
||||
info->special = type;
|
||||
info->refreshtime = 0;
|
||||
|
||||
snprintf(info->name, sizeof(info->name), "%s", NET_AdrToString(adr, sizeof(adr), &info->adr));
|
||||
snprintf(info->name, sizeof(info->name), "%s (via %s)", NET_AdrToString(adr, sizeof(adr), &info->adr), madr);
|
||||
|
||||
info->next = last;
|
||||
last = info;
|
||||
|
|
|
@ -347,7 +347,7 @@ qboolean COM_HasWork(void);
|
|||
void COM_WorkerFullSync(void);
|
||||
void COM_DestroyWorkerThread(void);
|
||||
void COM_WorkerPartialSync(void *priorityctx, int *address, int value);
|
||||
void *com_resourcemutex; //random mutex to simplify resource creation type stuff.
|
||||
extern void *com_resourcemutex; //random mutex to simplify resource creation type stuff.
|
||||
void COM_WorkerAbort(char *message); //calls sys_error on the main thread, if running on a worker.
|
||||
#ifdef _DEBUG
|
||||
void COM_AssertMainThread(const char *msg);
|
||||
|
|
|
@ -578,9 +578,9 @@ void R2D_ImageColours(float r, float g, float b, float a)
|
|||
}
|
||||
void R2D_ImagePaletteColour(unsigned int i, float a)
|
||||
{
|
||||
draw_active_colour[0] = host_basepal[i*3+0]/255.0;
|
||||
draw_active_colour[1] = host_basepal[i*3+1]/255.0;
|
||||
draw_active_colour[2] = host_basepal[i*3+2]/255.0;
|
||||
draw_active_colour[0] = SRGBf(host_basepal[i*3+0]/255.0);
|
||||
draw_active_colour[1] = SRGBf(host_basepal[i*3+1]/255.0);
|
||||
draw_active_colour[2] = SRGBf(host_basepal[i*3+2]/255.0);
|
||||
draw_active_colour[3] = a;
|
||||
|
||||
Font_InvalidateColour(draw_active_colour);
|
||||
|
@ -888,11 +888,6 @@ void R2D_ConsoleBackground (int firstline, int lastline, qboolean forceopaque)
|
|||
a = scr_conalpha.value;
|
||||
}
|
||||
|
||||
if (scr_chatmode == 2)
|
||||
{
|
||||
h>>=1;
|
||||
w>>=1;
|
||||
}
|
||||
if (R_GetShaderSizes(conback, NULL, NULL, false) <= 0)
|
||||
{
|
||||
R2D_ImageColours(0, 0, 0, a);
|
||||
|
|
|
@ -222,7 +222,6 @@ cvar_t scr_allowsnap = CVARF ("scr_allowsnap", "1",
|
|||
cvar_t scr_centersbar = CVAR ("scr_centersbar", "2");
|
||||
cvar_t scr_centertime = CVAR ("scr_centertime", "2");
|
||||
cvar_t scr_logcenterprint = CVARD ("con_logcenterprint", "1", "Specifies whether to print centerprints on the console.\n0: never\n1: single-player or coop only.\n2: always.\n");
|
||||
cvar_t scr_chatmodecvar = CVAR ("scr_chatmode", "0");
|
||||
cvar_t scr_conalpha = CVARC ("scr_conalpha", "0.7",
|
||||
Cvar_Limiter_ZeroToOne_Callback);
|
||||
cvar_t scr_consize = CVAR ("scr_consize", "0.5");
|
||||
|
@ -890,7 +889,6 @@ void Renderer_Init(void)
|
|||
Cvar_Register(&scr_viewsize, SCREENOPTIONS);
|
||||
Cvar_Register(&scr_fov, SCREENOPTIONS);
|
||||
Cvar_Register(&scr_fov_viewmodel, SCREENOPTIONS);
|
||||
// Cvar_Register(&scr_chatmodecvar, SCREENOPTIONS);
|
||||
|
||||
Cvar_Register (&scr_sshot_type, SCREENOPTIONS);
|
||||
Cvar_Register (&scr_sshot_compression, SCREENOPTIONS);
|
||||
|
|
|
@ -1266,7 +1266,7 @@ void Sbar_FillPC (float x, float y, float w, float h, unsigned int pcolour)
|
|||
{
|
||||
if (pcolour >= 16)
|
||||
{
|
||||
R2D_ImageColours (((pcolour&0xff0000)>>16)/255.0f, ((pcolour&0xff00)>>8)/255.0f, (pcolour&0xff)/255.0f, 1.0);
|
||||
R2D_ImageColours (SRGBA(((pcolour&0xff0000)>>16)/255.0f, ((pcolour&0xff00)>>8)/255.0f, (pcolour&0xff)/255.0f, 1.0));
|
||||
R2D_FillBlock (x, y, w, h);
|
||||
}
|
||||
else
|
||||
|
@ -1279,7 +1279,7 @@ static void Sbar_FillPCDark (float x, float y, float w, float h, unsigned int pc
|
|||
{
|
||||
if (pcolour >= 16)
|
||||
{
|
||||
R2D_ImageColours (((pcolour&0xff0000)>>16)/1024.0f, ((pcolour&0xff00)>>8)/1024.0f, (pcolour&0xff)/1024.0f, alpha);
|
||||
R2D_ImageColours (SRGBA(((pcolour&0xff0000)>>16)/1024.0f, ((pcolour&0xff00)>>8)/1024.0f, (pcolour&0xff)/1024.0f, alpha));
|
||||
R2D_FillBlock (x, y, w, h);
|
||||
}
|
||||
else
|
||||
|
@ -2962,13 +2962,6 @@ void Sbar_Draw (playerview_t *pv)
|
|||
else
|
||||
Sbar_Voice(16);
|
||||
|
||||
{
|
||||
extern int scr_chatmode;
|
||||
if (scr_chatmode)
|
||||
Sbar_ChatModeOverlay(pv);
|
||||
}
|
||||
|
||||
|
||||
Sbar_DrawUPS (pv);
|
||||
SCR_DrawClock();
|
||||
SCR_DrawGameClock();
|
||||
|
@ -3598,100 +3591,6 @@ if (showcolumns & (1<<COLUMN##title)) \
|
|||
largegame = true;
|
||||
}
|
||||
|
||||
void Sbar_ChatModeOverlay(playerview_t *pv)
|
||||
{
|
||||
int start =0;
|
||||
int i, k, l;
|
||||
int top, bottom;
|
||||
int x, y;
|
||||
player_info_t *s;
|
||||
char team[5];
|
||||
int skip = 10;
|
||||
|
||||
if (largegame)
|
||||
skip = 8;
|
||||
|
||||
// request new ping times every two second
|
||||
if (realtime - cl.last_ping_request > 2 && cls.protocol == CP_QUAKEWORLD && cls.demoplayback != DPB_EZTV)
|
||||
{
|
||||
cl.last_ping_request = realtime;
|
||||
CL_SendClientCommand(true, "pings");
|
||||
}
|
||||
|
||||
// scores
|
||||
Sbar_SortFrags (true, false);
|
||||
|
||||
if (Cam_TrackNum(pv)>=0)
|
||||
Q_strncpyz (team, cl.players[Cam_TrackNum(pv)].team, sizeof(team));
|
||||
else if (pv->playernum>=0 && pv->playernum<MAX_CLIENTS)
|
||||
Q_strncpyz (team, cl.players[pv->playernum].team, sizeof(team));
|
||||
else
|
||||
*team = '\0';
|
||||
|
||||
// draw the text
|
||||
l = scoreboardlines;
|
||||
|
||||
if (start)
|
||||
y = start;
|
||||
else
|
||||
y = 24;
|
||||
y = vid.height/2;
|
||||
|
||||
x = 4;
|
||||
Draw_FunString ( x , y, "name");
|
||||
y += 8;
|
||||
Draw_FunString ( x , y, "\x1d\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1f");
|
||||
y += 8;
|
||||
|
||||
for (i=0 ; i<l && y <= vid.height-10 ; i++)
|
||||
{
|
||||
k = fragsort[i];
|
||||
s = &cl.players[k];
|
||||
if (!s->name[0])
|
||||
continue;
|
||||
|
||||
// draw background
|
||||
top = Sbar_TopColour(s);
|
||||
bottom = Sbar_BottomColour(s);
|
||||
|
||||
if (largegame)
|
||||
Sbar_FillPC ( x, y+1, 8*4, 3, top);
|
||||
else
|
||||
Sbar_FillPC ( x, y, 8*4, 4, top);
|
||||
Sbar_FillPC ( x, y+4, 8*4, 4, bottom);
|
||||
/*
|
||||
if (cl.spectator && k == Cam_TrackNum(pv))
|
||||
{
|
||||
Draw_Character ( x, y, 16);
|
||||
Draw_Character ( x+8*3, y, 17);
|
||||
}
|
||||
else if (!cl.spectator && k == pv->cl.playernum)
|
||||
{
|
||||
Draw_Character ( x, y, 16);
|
||||
Draw_Character ( x+8*3, y, 17);
|
||||
}
|
||||
else if (cl.teamplay)
|
||||
{
|
||||
if (!stricmp(s->team, team))
|
||||
{
|
||||
Draw_Character ( x, y, '[');
|
||||
Draw_Character ( x+8*3, y, ']');
|
||||
}
|
||||
}
|
||||
*/
|
||||
// draw name
|
||||
if (cl.teamplay)
|
||||
Draw_FunString (x+8*4, y, s->name);
|
||||
else
|
||||
Draw_FunString (x+8*4, y, s->name);
|
||||
|
||||
y += skip;
|
||||
}
|
||||
|
||||
if (y >= vid.height-10) // we ran over the screen size, squish
|
||||
largegame = true;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
Sbar_MiniDeathmatchOverlay
|
||||
|
|
|
@ -2697,6 +2697,7 @@ static void SND_Spatialize(soundcardinfo_t *sc, channel_t *ch)
|
|||
seat = 0;
|
||||
VectorSubtract(ch->origin, listener[seat].origin, world_vec);
|
||||
dist = DotProduct(world_vec,world_vec);
|
||||
#if MAX_SPLITS > 1
|
||||
for (i = 1; i < cl.splitclients; i++)
|
||||
{
|
||||
VectorSubtract(ch->origin, listener[i].origin, world_vec);
|
||||
|
@ -2707,6 +2708,7 @@ static void SND_Spatialize(soundcardinfo_t *sc, channel_t *ch)
|
|||
seat = i;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1300,7 +1300,7 @@ void V_ApplyRefdef (void)
|
|||
else
|
||||
sb_lines = 24+16+8;
|
||||
|
||||
if (scr_viewsize.value >= 100.0 || scr_chatmode)
|
||||
if (scr_viewsize.value >= 100.0)
|
||||
{
|
||||
full = true;
|
||||
size = 100.0;
|
||||
|
@ -1344,14 +1344,6 @@ void V_ApplyRefdef (void)
|
|||
else
|
||||
r_refdef.vrect.y = (h - r_refdef.vrect.height)/2;
|
||||
|
||||
if (scr_chatmode)
|
||||
{
|
||||
if (scr_chatmode != 2)
|
||||
r_refdef.vrect.height = r_refdef.vrect.y=r_refdef.grect.height/2;
|
||||
r_refdef.vrect.width = r_refdef.vrect.x=r_refdef.grect.width/2;
|
||||
if (r_refdef.vrect.width<320 || r_refdef.vrect.height<200) //disable hud if too small
|
||||
sb_lines=0;
|
||||
}
|
||||
r_refdef.vrect.x += r_refdef.grect.x;
|
||||
r_refdef.vrect.y += r_refdef.grect.y;
|
||||
#endif
|
||||
|
@ -1642,61 +1634,24 @@ entity_t *CL_EntityNum(int num)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
float CalcFov (float fov_x, float width, float height);
|
||||
static void SCR_VRectForPlayer(vrect_t *vrect, int pnum, unsigned maxseats)
|
||||
static qboolean SCR_VRectForPlayer(vrect_t *vrect, int pnum, unsigned maxseats)
|
||||
{
|
||||
#if MAX_SPLITS > 4
|
||||
#pragma warning "Please change this function to cope with the new MAX_SPLITS value"
|
||||
#endif
|
||||
switch(maxseats)
|
||||
int w = 1, h = 1;
|
||||
while (w*h < maxseats)
|
||||
{
|
||||
case 1:
|
||||
vrect->width = vid.fbvwidth;
|
||||
vrect->height = vid.fbvheight;
|
||||
vrect->x = 0;
|
||||
vrect->y = 0;
|
||||
|
||||
if (scr_chatmode == 2)
|
||||
{
|
||||
vrect->height/=2;
|
||||
vrect->y += vrect->height;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: //horizontal bands
|
||||
case 3:
|
||||
#ifdef GLQUAKE
|
||||
if (qrenderer == QR_OPENGL && vid.rotpixelwidth > vid.rotpixelheight * 2
|
||||
&& r_projection.ival == PROJ_PANORAMA /*panoramic view always stacks player views*/
|
||||
)
|
||||
{ //over twice as wide as high, assume dual moniter, horizontal.
|
||||
vrect->width = vid.fbvwidth/cl.splitclients;
|
||||
vrect->height = vid.fbvheight;
|
||||
vrect->x = 0 + vrect->width*pnum;
|
||||
vrect->y = 0;
|
||||
}
|
||||
//spread them out so they're all fair.
|
||||
//panorama always stacks vertically, using the full width, because we can.
|
||||
if (vid.fbvwidth/(w*16.0) > vid.fbvheight/(h*10.0) && r_projection.ival != PROJ_PANORAMA)
|
||||
w++;
|
||||
else
|
||||
#endif
|
||||
{
|
||||
//stack them vertically
|
||||
vrect->width = vid.fbvwidth;
|
||||
vrect->height = vid.fbvheight/cl.splitclients;
|
||||
vrect->x = 0;
|
||||
vrect->y = 0 + vrect->height*pnum;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 4: //4 squares
|
||||
vrect->width = vid.fbvwidth/2;
|
||||
vrect->height = vid.fbvheight/2;
|
||||
vrect->x = (pnum&1) * vrect->width;
|
||||
vrect->y = (pnum&2)/2 * vrect->height;
|
||||
break;
|
||||
|
||||
default:
|
||||
Sys_Error("cl.splitclients is invalid.");
|
||||
h++;
|
||||
}
|
||||
vrect->width = vid.fbvwidth/(float)w;
|
||||
vrect->height = vid.fbvheight/(float)h;
|
||||
vrect->x = (pnum%w) * vrect->width;
|
||||
vrect->y = (pnum/w) * vrect->height;
|
||||
|
||||
return pnum < w*h;
|
||||
}
|
||||
|
||||
void Draw_ExpandedString(float x, float y, conchar_t *str);
|
||||
|
@ -2159,23 +2114,8 @@ void V_RenderPlayerViews(playerview_t *pv)
|
|||
cl_numvisedicts = oldnuments;
|
||||
cl_numstris = oldstris;
|
||||
|
||||
if (scr_chatmode == 2)
|
||||
{
|
||||
vec3_t dir;
|
||||
|
||||
r_refdef.vrect.y -= r_refdef.vrect.height;
|
||||
r_secondaryview = 2;
|
||||
|
||||
VectorSubtract(r_refdef.vieworg, pv->cam_desired_position, dir);
|
||||
VectorAngles(dir, NULL, r_refdef.viewangles, false);
|
||||
|
||||
|
||||
VectorCopy(pv->cam_desired_position, r_refdef.vieworg);
|
||||
R_RenderView ();
|
||||
}
|
||||
r_secondaryview = true;
|
||||
|
||||
|
||||
#ifdef SIDEVIEWS
|
||||
/* //adjust main view height to strip off the rearviews at the top
|
||||
if (vsecwidth >= 1)
|
||||
|
@ -2278,10 +2218,11 @@ void V_RenderPlayerViews(playerview_t *pv)
|
|||
r_refdef.externalview = false;
|
||||
}
|
||||
|
||||
#include "shader.h"
|
||||
void V_RenderView (void)
|
||||
{
|
||||
int viewnum;
|
||||
int maxviews = cl.splitclients;
|
||||
int seatnum;
|
||||
int maxseats = cl.splitclients;
|
||||
|
||||
Surf_LessenStains();
|
||||
|
||||
|
@ -2289,18 +2230,18 @@ void V_RenderView (void)
|
|||
return;
|
||||
|
||||
if (cl.intermissionmode != IM_NONE)
|
||||
maxviews = 1;
|
||||
maxseats = 1;
|
||||
|
||||
R_PushDlights ();
|
||||
|
||||
r_secondaryview = 0;
|
||||
for (viewnum = 0; viewnum < maxviews; viewnum++)
|
||||
for (seatnum = 0; seatnum < cl.splitclients && seatnum < maxseats; seatnum++)
|
||||
{
|
||||
V_ClearRefdef(&cl.playerview[viewnum]);
|
||||
if (viewnum)
|
||||
V_ClearRefdef(&cl.playerview[seatnum]);
|
||||
if (seatnum)
|
||||
{
|
||||
//should be enough to just hack a few things.
|
||||
V_EditExternalModels(cl.playerview[viewnum].viewentity, NULL, 0);
|
||||
V_EditExternalModels(r_refdef.playerview->viewentity, NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2324,7 +2265,8 @@ void V_RenderView (void)
|
|||
}
|
||||
if (R2D_Flush)
|
||||
R2D_Flush();
|
||||
SCR_VRectForPlayer(&r_refdef.grect, viewnum, maxviews);
|
||||
|
||||
SCR_VRectForPlayer(&r_refdef.grect, seatnum, maxseats);
|
||||
V_RenderPlayerViews(r_refdef.playerview);
|
||||
|
||||
#ifdef PLUGINS
|
||||
|
@ -2340,6 +2282,82 @@ void V_RenderView (void)
|
|||
SCR_TileClear (0);
|
||||
#endif
|
||||
}
|
||||
if (seatnum > 1)
|
||||
{
|
||||
int extra = 0;
|
||||
for (; ; seatnum++, extra++)
|
||||
{
|
||||
if (!SCR_VRectForPlayer(&r_refdef.grect, seatnum, maxseats))
|
||||
break;
|
||||
|
||||
switch(extra)
|
||||
{
|
||||
#ifdef QUAKEHUD
|
||||
case 0: //show a mini-console.
|
||||
{
|
||||
console_t *con = &con_main;
|
||||
extern cvar_t gl_conback;
|
||||
shader_t *conback;
|
||||
if (*gl_conback.string && (conback = R_RegisterPic(gl_conback.string, NULL)) && R_GetShaderSizes(conback, NULL, NULL, true) > 0)
|
||||
R2D_Image(r_refdef.grect.x, r_refdef.grect.y, r_refdef.grect.width, r_refdef.grect.height, 0, 0, 1, 1, conback);
|
||||
else if ((conback = R_RegisterPic("gfx/conback.lmp", NULL)) && R_GetShaderSizes(conback, NULL, NULL, true) > 0)
|
||||
R2D_Image(r_refdef.grect.x, r_refdef.grect.y, r_refdef.grect.width, r_refdef.grect.height, 0, 0, 1, 1, conback);
|
||||
else
|
||||
R2D_TileClear (r_refdef.grect.x, r_refdef.grect.y, r_refdef.grect.width, r_refdef.grect.height);
|
||||
if (!scr_conlines)
|
||||
{
|
||||
int gah;
|
||||
Font_BeginString(font_console, 0, 0, &gah, &gah);
|
||||
Con_DrawOneConsole(con, con->flags & CONF_KEYFOCUSED, font_console, r_refdef.grect.x+8, r_refdef.grect.y, r_refdef.grect.width-16, r_refdef.grect.height-Font_CharHeight(), 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1: //show some scores, because we can.
|
||||
{ //FIXME: show ALL tracked players.
|
||||
int tmp;
|
||||
R2D_TileClear (r_refdef.grect.x, r_refdef.grect.y, r_refdef.grect.width, r_refdef.grect.height);
|
||||
r_refdef.playerview = &cl.playerview[0];
|
||||
tmp = r_refdef.playerview->sb_showscores;
|
||||
r_refdef.playerview->sb_showscores = true;
|
||||
Sbar_DrawScoreboard (r_refdef.playerview);
|
||||
r_refdef.playerview->sb_showscores = tmp;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
static playerview_t cam_view;
|
||||
vec3_t dir;
|
||||
int track = cl.playerview[0].cam_spec_track;
|
||||
if (track < 0)
|
||||
track = cl.playerview[0].playernum;
|
||||
|
||||
if (cam_view.cam_state == CAM_FREECAM || cam_view.cam_spec_track != track)
|
||||
cam_view.cam_state = CAM_PENDING;
|
||||
cam_view.playernum = -1;//cl.playerview[0].playernum;
|
||||
cam_view.cam_spec_track = track;
|
||||
cam_view.viewentity = 0;
|
||||
cam_view.nolocalplayer = true;
|
||||
cam_view.spectator = true;
|
||||
|
||||
Cam_Track(&cam_view, NULL);
|
||||
|
||||
VectorSubtract(cl.playerview[0].simorg, cam_view.cam_desired_position, dir);
|
||||
VectorAngles(dir, NULL, cam_view.simangles, false);
|
||||
|
||||
VectorCopy(cam_view.cam_desired_position, cam_view.simorg);
|
||||
|
||||
V_ClearRefdef(&cam_view);
|
||||
V_EditExternalModels(0, NULL, 0);
|
||||
V_RenderPlayerViews(r_refdef.playerview);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default: //wow, loads. nothing to show though.
|
||||
R2D_TileClear (r_refdef.grect.x, r_refdef.grect.y, r_refdef.grect.width, r_refdef.grect.height);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
r_refdef.playerview = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -87,7 +87,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#define CONFIG_FILE_NAME config.h
|
||||
#elif defined(NOLEGACY)
|
||||
#define CONFIG_FILE_NAME config_nolegacy.h
|
||||
#undef NOLEGACY
|
||||
#define CONFIG_FILE_NAME config_nocompat.h
|
||||
#elif defined(MINIMAL)
|
||||
#define CONFIG_FILE_NAME config_minimal.h
|
||||
#else
|
||||
|
@ -405,6 +406,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#undef AVAIL_XZDEC
|
||||
#undef AVAIL_GZDEC
|
||||
#endif
|
||||
#if (defined(_MSC_VER) && (_MSC_VER < 1500)) || defined(FTE_SDL)
|
||||
#undef AVAIL_WASAPI //wasapi is available in the vista sdk, while that's compatible with earlier versions, its not really expected until 2008
|
||||
#endif
|
||||
|
||||
//include a file to update the various configurations for game-specific configs (hopefully just names)
|
||||
#ifdef BRANDING_INC
|
||||
|
@ -1201,7 +1205,9 @@ STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION = 255, // DP
|
|||
|
||||
|
||||
//split screen stuff
|
||||
#define MAX_SPLITS 4
|
||||
#ifndef MAX_SPLITS
|
||||
#define MAX_SPLITS 1u //disabled, but must be defined for sanities sake.
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -5075,6 +5075,7 @@ cvar_t worker_sleeptime = CVARFD("worker_sleeptime", "0", CVAR_NOTFROMSERVER, "C
|
|||
|
||||
#define WORKERTHREADS 16 //max
|
||||
/*multithreading worker thread stuff*/
|
||||
void *com_resourcemutex;
|
||||
static int com_liveworkers[WG_COUNT];
|
||||
static void *com_workercondition[WG_COUNT];
|
||||
static volatile int com_workeracksequence;
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#define LOADERTHREAD //worker threads for loading misc stuff. falls back on main thread if not supported.
|
||||
#define AVAIL_DINPUT
|
||||
#define SIDEVIEWS 4 //enable secondary/reverse views.
|
||||
#define MAX_SPLITS 4u
|
||||
#define TEXTEDITOR //my funky text editor! its awesome!
|
||||
#define PLUGINS //support for external plugins (like huds or fancy menus or whatever)
|
||||
#define USE_SQLITE //sql-database-as-file support
|
||||
|
@ -63,7 +64,7 @@
|
|||
#define RFBSPS //qfusion's bsp format / jk2o etc.
|
||||
#define TERRAIN //FTE's terrain, as well as .map support
|
||||
//#define DOOMWADS //map support, filesystem support is separate.
|
||||
//#define MAP_PROC //doom3...
|
||||
//#define MAP_PROC //doom3...
|
||||
|
||||
//Model formats
|
||||
#define SPRMODELS //Quake's sprites
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// Build-Config file for FTE's minimal builds.
|
||||
// to use: make FTE_CONFIG=minimal
|
||||
// These builds are a compromise between true minimal and something that will actually work.
|
||||
// As such we allow pk3s, md3s, pngs, and built-in menus, but that's about it.
|
||||
|
||||
// Features should either be commented or not. If you change undefs to defines or vice versa then expect problems.
|
||||
// Later code will disable any features if they're not supported on the current platform, so don't worry about win/lin/mac/android/web/etc here - any such issues should be fixed elsewhere.
|
||||
|
@ -27,7 +29,7 @@
|
|||
//#undef D3D9QUAKE
|
||||
//#undef D3D11QUAKE
|
||||
//#undef VKQUAKE
|
||||
//#undef HEADLESSQUAKE //no-op renderer...
|
||||
#undef HEADLESSQUAKE //no-op renderer...
|
||||
//#undef WAYLANDQUAKE //linux only
|
||||
|
||||
//Misc Renderer stuff
|
||||
|
@ -43,17 +45,18 @@
|
|||
#define LOADERTHREAD //worker threads for loading misc stuff. falls back on main thread if not supported.
|
||||
#define AVAIL_DINPUT
|
||||
//#define SIDEVIEWS 4 //enable secondary/reverse views.
|
||||
//#define MAX_SPLITS 4u
|
||||
//#define TEXTEDITOR //my funky text editor! its awesome!
|
||||
//#define PLUGINS //support for external plugins (like huds or fancy menus or whatever)
|
||||
//#define USE_SQLITE //sql-database-as-file support
|
||||
|
||||
//Filesystem formats
|
||||
//#define PACKAGE_PK3
|
||||
#define PACKAGE_PK3
|
||||
#define PACKAGE_Q1PAK //also q2
|
||||
//#define PACKAGE_DOOMWAD //doom wad support (generates various file names, and adds support for doom's audio, sprites, etc)
|
||||
//#define AVAIL_XZDEC //.xz decompression
|
||||
//#define AVAIL_GZDEC //.gz decompression
|
||||
//#define AVAIL_ZLIB //whether pk3s can be compressed or not.
|
||||
#define AVAIL_ZLIB //whether pk3s can be compressed or not.
|
||||
//#define AVAIL_DZIP //.dzip support for smaller demos (which are actually more like pak files and can store ANY type of file)
|
||||
|
||||
//Map formats
|
||||
|
@ -63,15 +66,15 @@
|
|||
//#define RFBSPS //qfusion's bsp format / jk2o etc.
|
||||
//#define TERRAIN //FTE's terrain, as well as .map support
|
||||
//#define DOOMWADS //map support, filesystem support is separate.
|
||||
//#define MAP_PROC //doom3...
|
||||
//#define MAP_PROC //doom3...
|
||||
|
||||
//Model formats
|
||||
#define SPRMODELS //Quake's sprites
|
||||
//#define SP2MODELS //Quake2's models
|
||||
#define DSPMODELS //Doom sprites!
|
||||
//#define DSPMODELS //Doom sprites!
|
||||
#define MD1MODELS //Quake's models.
|
||||
//#define MD2MODELS //Quake2's models
|
||||
//#define MD3MODELS //Quake3's models, also often used for q1 etc too.
|
||||
#define MD3MODELS //Quake3's models, also often used for q1 etc too.
|
||||
//#define MD5MODELS //Doom3 models.
|
||||
//#define ZYMOTICMODELS //nexuiz uses these, for some reason.
|
||||
//#define DPMMODELS //these keep popping up, despite being a weak format.
|
||||
|
@ -86,7 +89,7 @@
|
|||
//#define IMAGEFMT_DDS //.dds files embed mipmaps and texture compression. faster to load.
|
||||
//#define IMAGEFMT_BLP //legacy crap
|
||||
#define PACKAGE_TEXWAD //quake's image wad support
|
||||
//#define AVAIL_PNGLIB //.png image format support (read+screenshots)
|
||||
#define AVAIL_PNGLIB //.png image format support (read+screenshots)
|
||||
//#define AVAIL_JPEGLIB //.jpeg image format support (read+screenshots)
|
||||
//#define AVAIL_FREETYPE //for truetype font rendering
|
||||
//#define DECOMPRESS_ETC2 //decompress etc2(core in gles3/gl4.3) if the graphics driver doesn't support it (eg d3d or crappy gpus with vulkan).
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
#define RFBSPS //qfusion's bsp format / jk2o etc.
|
||||
//#define TERRAIN //FTE's terrain, as well as .map support
|
||||
//#define DOOMWADS //map support, filesystem support is separate.
|
||||
//#define MAP_PROC //doom3...
|
||||
//#define MAP_PROC //doom3...
|
||||
|
||||
//Model formats
|
||||
#define SPRMODELS //Quake's sprites
|
||||
|
|
|
@ -132,6 +132,7 @@
|
|||
#undef HAVE_CDPLAYER //includes cd playback. actual cds. named/numbered tracks are supported regardless (though you need to use the 'music' command to play them without this).
|
||||
#undef QTERM
|
||||
#undef SIDEVIEWS
|
||||
#undef MAX_SPLITS
|
||||
#undef SUBSERVERS
|
||||
#undef SV_MASTER
|
||||
#undef HAVE_MIXER //openal only
|
||||
|
|
|
@ -204,8 +204,6 @@ extern int edit_line;
|
|||
extern int key_linepos;
|
||||
extern int history_line;
|
||||
|
||||
extern int scr_chatmode;
|
||||
|
||||
//extern int con_totallines;
|
||||
extern qboolean con_initialized;
|
||||
extern qbyte *con_chars;
|
||||
|
|
|
@ -153,7 +153,9 @@ unsigned int Net_PextMask(int maskset, qboolean fornq)
|
|||
#endif
|
||||
mask |= PEXT_SPAWNSTATIC2;
|
||||
mask |= PEXT_COLOURMOD;
|
||||
#if MAX_SPLITS > 1
|
||||
mask |= PEXT_SPLITSCREEN;
|
||||
#endif
|
||||
mask |= PEXT_HEXEN2;
|
||||
mask |= PEXT_CUSTOMTEMPEFFECTS;
|
||||
mask |= PEXT_256PACKETENTITIES;
|
||||
|
|
|
@ -966,14 +966,18 @@ qboolean SSL_InitGlobal(qboolean isserver)
|
|||
isserver = !!isserver;
|
||||
if (COM_CheckParm("-notls"))
|
||||
return false;
|
||||
#ifdef LOADERTHREAD
|
||||
if (com_resourcemutex)
|
||||
Sys_LockMutex(com_resourcemutex);
|
||||
#endif
|
||||
if (!initstatus[isserver])
|
||||
{
|
||||
if (!Init_GNUTLS())
|
||||
{
|
||||
#ifdef LOADERTHREAD
|
||||
if (com_resourcemutex)
|
||||
Sys_UnlockMutex(com_resourcemutex);
|
||||
#endif
|
||||
Con_Printf("GnuTLS "GNUTLS_VERSION" library not available.\n");
|
||||
return false;
|
||||
}
|
||||
|
@ -998,8 +1002,10 @@ qboolean SSL_InitGlobal(qboolean isserver)
|
|||
qgnutls_certificate_set_x509_trust_file (xcred[isserver], CAFILE, GNUTLS_X509_FMT_PEM);
|
||||
#endif
|
||||
|
||||
#ifdef LOADERTHREAD
|
||||
if (com_resourcemutex)
|
||||
Sys_UnlockMutex(com_resourcemutex);
|
||||
#endif
|
||||
if (isserver)
|
||||
{
|
||||
#if 1
|
||||
|
@ -1026,8 +1032,10 @@ qboolean SSL_InitGlobal(qboolean isserver)
|
|||
}
|
||||
else
|
||||
{
|
||||
#ifdef LOADERTHREAD
|
||||
if (com_resourcemutex)
|
||||
Sys_UnlockMutex(com_resourcemutex);
|
||||
Sys_UnlockMutex(com_resourcemutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (initstatus[isserver] < 0)
|
||||
|
|
|
@ -6805,7 +6805,7 @@ void NET_PrintConnectionsStatus(ftenet_connections_t *collection)
|
|||
int TCP_OpenStream (netadr_t *remoteaddr)
|
||||
{
|
||||
#ifndef HAVE_TCP
|
||||
return INVALID_SOCKET;
|
||||
return (int)INVALID_SOCKET;
|
||||
#else
|
||||
unsigned long _true = true;
|
||||
int newsocket;
|
||||
|
|
|
@ -195,7 +195,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#define svc_temp_entity 23 // variable
|
||||
#define svc_setpause 24 // [qbyte] on / off
|
||||
#define svc_signonnum 25 // [qbyte] used for the signon sequence
|
||||
#define svcnq_signonnum 25 // [qbyte] used for the signon sequence
|
||||
#define svcfte_splitscreenconfig 25 // [qbyte] seats, player[seat]. spectator flags passed via userinfo.
|
||||
|
||||
#define svc_centerprint 26 // [string] to put in center of the screen
|
||||
|
||||
|
|
|
@ -42179,6 +42179,26 @@
|
|||
RelativePath="..\common\zone.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="configs"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\common\config_fteqw.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\common\config_minimal.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\common\config_nocompat.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\common\config_wastes.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
|
|
|
@ -41,8 +41,6 @@ extern qboolean scr_initialized;
|
|||
extern float oldsbar;
|
||||
extern qboolean scr_drawloading;
|
||||
|
||||
extern int scr_chatmode;
|
||||
extern cvar_t scr_chatmodecvar;
|
||||
extern cvar_t vid_conautoscale;
|
||||
extern qboolean scr_con_forcedraw;
|
||||
extern qboolean depthcleared;
|
||||
|
|
|
@ -93,19 +93,19 @@ const char *EGL_GetErrorString(int error)
|
|||
{
|
||||
switch(error)
|
||||
{
|
||||
case EGL_BAD_ACCESS: return "BAD_ACCESS";
|
||||
case EGL_BAD_ALLOC: return "BAD_ALLOC";
|
||||
case EGL_BAD_ATTRIBUTE: return "BAD_ATTRIBUTE";
|
||||
case EGL_BAD_CONFIG: return "BAD_CONFIG";
|
||||
case EGL_BAD_CONTEXT: return "BAD_CONEXT";
|
||||
case EGL_BAD_ACCESS: return "BAD_ACCESS";
|
||||
case EGL_BAD_ALLOC: return "BAD_ALLOC";
|
||||
case EGL_BAD_ATTRIBUTE: return "BAD_ATTRIBUTE";
|
||||
case EGL_BAD_CONFIG: return "BAD_CONFIG";
|
||||
case EGL_BAD_CONTEXT: return "BAD_CONEXT";
|
||||
case EGL_BAD_CURRENT_SURFACE: return "BAD_CURRENT_SURFACE";
|
||||
case EGL_BAD_DISPLAY: return "BAD_DISPLAY";
|
||||
case EGL_BAD_MATCH: return "BAD_MATCH";
|
||||
case EGL_BAD_NATIVE_PIXMAP: return "BAD_NATIVE_PIXMAP";
|
||||
case EGL_BAD_NATIVE_WINDOW: return "BAD_NATIVE_WINDOW";
|
||||
case EGL_BAD_PARAMETER: return "BAD_PARAMETER";
|
||||
case EGL_BAD_SURFACE: return "BAD_SURFACE";
|
||||
default: return va("EGL:%#x", error);
|
||||
case EGL_BAD_DISPLAY: return "BAD_DISPLAY";
|
||||
case EGL_BAD_MATCH: return "BAD_MATCH";
|
||||
case EGL_BAD_NATIVE_PIXMAP: return "BAD_NATIVE_PIXMAP";
|
||||
case EGL_BAD_NATIVE_WINDOW: return "BAD_NATIVE_WINDOW";
|
||||
case EGL_BAD_PARAMETER: return "BAD_PARAMETER";
|
||||
case EGL_BAD_SURFACE: return "BAD_SURFACE";
|
||||
default: return va("EGL:%#x", error);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
#define EGL_PLATFORM_WAYLAND_KHR 0x31D8 //EGL_KHR_platform_wayland
|
||||
#endif
|
||||
|
||||
#ifndef EGL_PLATFORM_WIN32
|
||||
#define EGL_PLATFORM_WIN32 0 //no meaningful value.
|
||||
#endif
|
||||
|
||||
void *EGL_Proc(char *f);
|
||||
void EGL_UnloadLibrary(void);
|
||||
qboolean EGL_LoadLibrary(char *driver);
|
||||
|
|
|
@ -1522,7 +1522,7 @@ static int GLVID_SetMode (rendererstate_t *info, unsigned char *palette)
|
|||
if (stat)
|
||||
{
|
||||
maindc = GetDC(mainwindow);
|
||||
stat = EGL_Init (info, palette, mainwindow, maindc);
|
||||
stat = EGL_Init (info, palette, EGL_PLATFORM_WIN32, mainwindow, maindc, (EGLNativeWindowType)mainwindow, (EGLNativeDisplayType)maindc);
|
||||
|
||||
if (stat)
|
||||
if (!GL_Init(info, &EGL_Proc))
|
||||
|
|
|
@ -1155,7 +1155,7 @@ void SV_ExtractFromUserinfo (client_t *cl, qboolean verbose);
|
|||
|
||||
void SV_SaveInfos(vfsfile_t *f);
|
||||
|
||||
void SV_FixupName(char *in, char *out, unsigned int outlen);
|
||||
void SV_FixupName(const char *in, char *out, unsigned int outlen);
|
||||
|
||||
#ifdef SUBSERVERS
|
||||
//cluster stuff
|
||||
|
|
|
@ -2798,7 +2798,7 @@ static void SV_SendGameCommand_f(void)
|
|||
}
|
||||
else
|
||||
#endif
|
||||
Con_Printf("Mod-specific command not known\n");
|
||||
Con_Printf("Mod-specific command \"%s\" not known\n", Cmd_Argv(1));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1305,6 +1305,8 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents,
|
|||
i = QWMAX_CLIENTS;
|
||||
}
|
||||
}
|
||||
if (i > MAX_CLIENTS)
|
||||
i = MAX_CLIENTS;
|
||||
SV_UpdateMaxPlayers(i);
|
||||
|
||||
// leave slots at start for clients only
|
||||
|
|
|
@ -184,7 +184,6 @@ char cvargroup_servercontrol[] = "server control variables";
|
|||
|
||||
vfsfile_t *sv_fraglogfile;
|
||||
|
||||
void SV_FixupName(char *in, char *out, unsigned int outlen);
|
||||
void SV_AcceptClient (netadr_t *adr, int userid, char *userinfo);
|
||||
void PRH2_SetPlayerClass(client_t *cl, int classnum, qboolean fromqc);
|
||||
|
||||
|
@ -2091,10 +2090,12 @@ void SV_ClientProtocolExtensionsChanged(client_t *client)
|
|||
client_t *SV_AddSplit(client_t *controller, char *info, int id)
|
||||
{
|
||||
client_t *cl, *prev;
|
||||
int i;
|
||||
int i, j;
|
||||
int curclients;
|
||||
qboolean loadgame;
|
||||
const char *name;
|
||||
unsigned int clients = 0, spectators = 0;
|
||||
qboolean asspec;
|
||||
|
||||
if (!(controller->fteprotocolextensions & PEXT_SPLITSCREEN))
|
||||
{
|
||||
|
@ -2111,8 +2112,8 @@ client_t *SV_AddSplit(client_t *controller, char *info, int id)
|
|||
if (id && curclients != id)
|
||||
return NULL; //this would be weird.
|
||||
|
||||
if (curclients >= 16)
|
||||
return NULL; //protocol limit on stats.
|
||||
// if (curclients >= 16)
|
||||
// return NULL; //protocol limit on stats.
|
||||
if (curclients >= MAX_SPLITS)
|
||||
return NULL;
|
||||
//only allow splitscreen if its explicitly allowed. unless its the local client in which case its always allowed.
|
||||
|
@ -2168,9 +2169,26 @@ client_t *SV_AddSplit(client_t *controller, char *info, int id)
|
|||
}
|
||||
|
||||
loadgame = (cl->state == cs_loadzombie);
|
||||
if (loadgame)
|
||||
asspec = cl->spectator;
|
||||
else
|
||||
asspec = !!atoi(Info_ValueForKey(info, "spectator"));
|
||||
for (j=0 ; j<sv.allocated_client_slots ; j++)
|
||||
{
|
||||
if (svs.clients[j].state == cs_free)
|
||||
continue;
|
||||
if (svs.clients[j].spectator && svs.clients[j].spectator!=2)
|
||||
spectators++;
|
||||
else
|
||||
clients++;
|
||||
}
|
||||
if ((asspec?spectators:clients) >= (asspec?maxspectators.ival:maxclients.ival))
|
||||
{
|
||||
SV_PrintToClient(controller, PRINT_HIGH, "Server full, cannot add new seat\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!loadgame)
|
||||
cl->spectator = controller->spectator;
|
||||
cl->spectator = asspec;
|
||||
cl->netchan.remote_address = controller->netchan.remote_address;
|
||||
cl->netchan.message.prim = controller->netchan.message.prim;
|
||||
cl->zquake_extensions = controller->zquake_extensions;
|
||||
|
@ -2238,14 +2256,17 @@ client_t *SV_AddSplit(client_t *controller, char *info, int id)
|
|||
|
||||
Info_RemoveKey (cl->userinfo, "spectator");
|
||||
//this is a hint rather than a game breaker should it fail.
|
||||
Info_SetValueForStarKey (cl->userinfo, "*spectator", va("%i", cl->spectator), sizeof(cl->userinfo));
|
||||
if (cl->spectator)
|
||||
Info_SetValueForStarKey (cl->userinfo, "*spectator", va("%i", cl->spectator), sizeof(cl->userinfo));
|
||||
cl->state = controller->state;
|
||||
|
||||
// host_client = NULL;
|
||||
// sv_player = NULL;
|
||||
|
||||
SV_ExtractFromUserinfo (cl, true);
|
||||
if (!loadgame)
|
||||
SV_GetNewSpawnParms(cl);
|
||||
|
||||
cl->state = controller->state;
|
||||
|
||||
if (cl->state >= cs_connected)
|
||||
{
|
||||
cl->sendinfo = true;
|
||||
|
@ -2837,7 +2858,7 @@ client_t *SVC_DirectConnect(void)
|
|||
{
|
||||
if (cl->state == cs_free)
|
||||
continue;
|
||||
if (cl->spectator)
|
||||
if (cl->spectator && cl->spectator!=2)
|
||||
spectators++;
|
||||
else
|
||||
clients++;
|
||||
|
@ -5225,7 +5246,7 @@ void SV_InitLocal (void)
|
|||
//" is so mods that use player names in tokenizing/frik_files don't mess up. mods are still expected to be able to cope with space.
|
||||
|
||||
//is allowed to shorten, out must be as long as in and min of "unnamed"+1
|
||||
void SV_FixupName(char *in, char *out, unsigned int outlen)
|
||||
void SV_FixupName(const char *in, char *out, unsigned int outlen)
|
||||
{
|
||||
char *s, *p;
|
||||
unsigned int len;
|
||||
|
|
|
@ -750,7 +750,7 @@ void SVNQ_New_f (void)
|
|||
{ //old clients can't cope with reliables until they finish loading the models specified above.
|
||||
//we need to wait before sending any more
|
||||
//updated clients can wait a bit, and use signonnum 1 to tell them when to start loading stuff.
|
||||
MSG_WriteByte (&host_client->netchan.message, svc_signonnum);
|
||||
MSG_WriteByte (&host_client->netchan.message, svcnq_signonnum);
|
||||
MSG_WriteByte (&host_client->netchan.message, 1);
|
||||
host_client->netchan.nqunreliableonly = 2;
|
||||
}
|
||||
|
@ -1034,7 +1034,7 @@ void SV_SendClientPrespawnInfo(client_t *client)
|
|||
{
|
||||
if (ISNQCLIENT(client) && (client->fteprotocolextensions2 & PEXT2_PREDINFO))
|
||||
{
|
||||
ClientReliableWrite_Begin(client, svc_signonnum, 2);
|
||||
ClientReliableWrite_Begin(client, svcnq_signonnum, 2);
|
||||
ClientReliableWrite_Byte (client, 1);
|
||||
}
|
||||
}
|
||||
|
@ -1639,7 +1639,7 @@ void SV_SendClientPrespawnInfo(client_t *client)
|
|||
if (ISNQCLIENT(client))
|
||||
{
|
||||
//effectively a cmd spawn... but also causes the client to actually send the player's name too.
|
||||
ClientReliableWrite_Begin (client, svc_signonnum, 2);
|
||||
ClientReliableWrite_Begin (client, svcnq_signonnum, 2);
|
||||
ClientReliableWrite_Byte (client, 2);
|
||||
}
|
||||
else
|
||||
|
@ -1967,12 +1967,12 @@ void SV_Begin_Core(client_t *split)
|
|||
else
|
||||
{
|
||||
#ifndef NOLEGACY
|
||||
sv_player->xv->clientcolors = split->playercolor;
|
||||
split->edict->xv->clientcolors = split->playercolor;
|
||||
if (progstype != PROG_QW)
|
||||
{ //some redundant things, purely for dp compat
|
||||
eval_t *eval;
|
||||
edict_t *ent = split->edict;
|
||||
sv_player->v->team = split->playercolor&15;
|
||||
ent->v->team = split->playercolor&15;
|
||||
|
||||
eval = svprogfuncs->GetEdictFieldValue(svprogfuncs, ent, "playermodel", ev_string, NULL);
|
||||
if (eval)
|
||||
|
@ -2100,7 +2100,7 @@ void SV_Begin_Core(client_t *split)
|
|||
}
|
||||
SV_PostRunCmd();
|
||||
host_client = oh;
|
||||
sv_player = host_client->edict;
|
||||
sv_player = oh?oh->edict:NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2111,8 +2111,8 @@ void SV_Begin_Core(client_t *split)
|
|||
split->dp_pl = NULL;
|
||||
if (progstype == PROG_NQ)
|
||||
{
|
||||
split->dp_ping = (float*)sv.world.progs->GetEdictFieldValue(sv.world.progs, sv_player, "ping", ev_float, NULL);
|
||||
split->dp_pl = (float*)sv.world.progs->GetEdictFieldValue(sv.world.progs, sv_player, "ping_packetloss", ev_float, NULL);
|
||||
split->dp_ping = (float*)sv.world.progs->GetEdictFieldValue(sv.world.progs, split->edict, "ping", ev_float, NULL);
|
||||
split->dp_pl = (float*)sv.world.progs->GetEdictFieldValue(sv.world.progs, split->edict, "ping_packetloss", ev_float, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -4040,7 +4040,7 @@ static void SV_UpdateSeats(client_t *controller)
|
|||
for (curclients = 0, cl = controller; cl; cl = cl->controlled)
|
||||
curclients++;
|
||||
|
||||
ClientReliableWrite_Begin(controller, svc_signonnum, 2+curclients);
|
||||
ClientReliableWrite_Begin(controller, svcfte_splitscreenconfig, 2+curclients);
|
||||
ClientReliableWrite_Byte(controller, curclients);
|
||||
for (curclients = 0, cl = controller; cl; cl = cl->controlled, curclients++)
|
||||
{
|
||||
|
@ -4966,7 +4966,7 @@ static void Cmd_AddSeat_f(void)
|
|||
{
|
||||
client_t *cl, *prev;
|
||||
qboolean changed = false;
|
||||
//don't allow an altseat to add. paranoia.
|
||||
//don't allow an altseat to add or remove. that's not how this works.
|
||||
if (host_client->controller)
|
||||
return;
|
||||
|
||||
|
@ -5003,7 +5003,7 @@ static void Cmd_AddSeat_f(void)
|
|||
//okay, it can get lost now.
|
||||
cl->drop = true;
|
||||
}
|
||||
host_client->controller->joinobservelockeduntil = realtime + 3;
|
||||
host_client->joinobservelockeduntil = realtime + 3;
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
|
@ -5512,7 +5512,7 @@ static void SVNQ_Spawn_f (void)
|
|||
|
||||
//SV_Begin_Core(host_client);
|
||||
|
||||
ClientReliableWrite_Begin (host_client, svc_signonnum, 2);
|
||||
ClientReliableWrite_Begin (host_client, svcnq_signonnum, 2);
|
||||
ClientReliableWrite_Byte (host_client, 3);
|
||||
|
||||
host_client->send_message = true;
|
||||
|
@ -6110,8 +6110,10 @@ void SV_ExecuteUserCommand (const char *s, qboolean fromQC)
|
|||
{ //'cmd 2 say hi' should
|
||||
char *a=Cmd_Argv(0), *e;
|
||||
int pnum = strtoul(a, &e, 10);
|
||||
|
||||
if (e == a+1 && pnum >= 1 && pnum <= MAX_SPLITS)
|
||||
|
||||
//commands might be in the form of eg '2on2' so make sure that its fully numeric.
|
||||
//KTX uses eg 'cmd 231', so don't take it if it can't be a seat, but there may be race conditions so we don't want error messages when it might have been a seat.
|
||||
if (!*e && pnum >= 1 && pnum <= MAX_SPLITS)
|
||||
{
|
||||
client_t *sp;
|
||||
for (sp = host_client; sp; sp = sp->controlled)
|
||||
|
|
Loading…
Reference in a new issue