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:
Spoike 2018-03-25 09:36:14 +00:00
parent 876eb0cf39
commit 8c02fb26b3
40 changed files with 410 additions and 332 deletions

View File

@ -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];

View File

@ -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;

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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))

View File

@ -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);

View File

@ -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);
}

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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
{

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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).

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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

View File

@ -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>

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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))

View File

@ -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

View File

@ -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));
}

View File

@ -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

View File

@ -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;

View File

@ -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)