Try to fix up some q2 protocol/ice quirks.
Add r_imagelist_wad command to show lumps in the current map's wad list. Hide the gpu utilisation info unless developer. its misleading on account of power profiles. Make the menu not flash/animate so much when something else has focus. Add QTV streaming option when browsing servers (assuming servers are configured properly). Show people's health+armour+weapons on the scoreboard, if we have that information. "enemyskin solid; enemycolor 0x00ff00" will make enemies full green without needing any external texture files. Add ENGINE_HAS_ZIP build option, to have the engine look for concated(self-extracter style) zips for use in single-file games. Small speedup for hl2bsp load times. ftemaster now supports bad-word filters. Basic, probably easy enough to hack around, but at least we tried, admins can extra words as needed. People should at least realise they're being naughty. Misc fixes for ftemaster's html generation. Add support for a couple of quirky hlbsps. Don't attempt to auto-use setangles_delta when sv_nqplayerphysics is active, to avoid compat quirks with AD.
This commit is contained in:
parent
e82f61256a
commit
7e9d138d5f
42 changed files with 740 additions and 217 deletions
|
@ -955,7 +955,7 @@ void Cam_SetModAutoTrack(int userid)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Con_Printf("//at: invalid userid\n");
|
Con_Printf("//at: invalid userid %i\n", userid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static void Cam_TrackCrosshairedPlayer(playerview_t *pv)
|
/*static void Cam_TrackCrosshairedPlayer(playerview_t *pv)
|
||||||
|
|
|
@ -3037,7 +3037,7 @@ fail:
|
||||||
MC_AddCenterPicture(sourcesmenu, 4, 24, "gfx/p_option.lmp");
|
MC_AddCenterPicture(sourcesmenu, 4, 24, "gfx/p_option.lmp");
|
||||||
}
|
}
|
||||||
if (init_numplayers == true && init_numviewers == true)
|
if (init_numplayers == true && init_numviewers == true)
|
||||||
MC_AddConsoleCommand(sourcesmenu, 42, 170, (sourcenum++)*8 + 32, va("%s (p%i, v%i)", srchost, numplayers, numviewers), va("qtvplay %s@%s\n", streamid, qtv->hostname));
|
MC_AddConsoleCommand(sourcesmenu, 42, 170, (sourcenum++)*8 + 32, va("%s (p%i, v%i)", *srchost?srchost:streamid, numplayers, numviewers), va("qtvplay %s@%s\n", streamid, qtv->hostname));
|
||||||
//else
|
//else
|
||||||
// FIXME: add error message here
|
// FIXME: add error message here
|
||||||
#else
|
#else
|
||||||
|
@ -3060,7 +3060,7 @@ fail:
|
||||||
if (streamavailable)
|
if (streamavailable)
|
||||||
{
|
{
|
||||||
if (*streamavailable)
|
if (*streamavailable)
|
||||||
Con_Printf("streaming \"%s\" from qtv\n", streamavailable);
|
Con_Printf("streaming \"%s\" via \"%s\"\n", streamavailable, qtv->hostname);
|
||||||
else
|
else
|
||||||
Con_Printf("qtv connection established to %s\n", qtv->hostname);
|
Con_Printf("qtv connection established to %s\n", qtv->hostname);
|
||||||
CL_PlayDemoStream(qtv->stream, NULL, false, DPB_MVD, BUFFERTIME, iseztv);
|
CL_PlayDemoStream(qtv->stream, NULL, false, DPB_MVD, BUFFERTIME, iseztv);
|
||||||
|
@ -3138,6 +3138,7 @@ void CL_QTVPlay_Establish (const char *host, const char *password, const char *c
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Q_strncpyz(qtv->hostname, host, sizeof(qtv->hostname));
|
||||||
Q_strncpyz(qtv->password, password, sizeof(qtv->password));
|
Q_strncpyz(qtv->password, password, sizeof(qtv->password));
|
||||||
|
|
||||||
if (qtvcl_forceversion1.ival)
|
if (qtvcl_forceversion1.ival)
|
||||||
|
|
|
@ -736,8 +736,8 @@ static void CL_SendConnectPacket (netadr_t *to)
|
||||||
}
|
}
|
||||||
|
|
||||||
connectinfo.ext.fte1 &= (PEXT_MODELDBL|PEXT_SOUNDDBL|PEXT_SPLITSCREEN);
|
connectinfo.ext.fte1 &= (PEXT_MODELDBL|PEXT_SOUNDDBL|PEXT_SPLITSCREEN);
|
||||||
connectinfo.ext.fte2 = 0;
|
connectinfo.ext.fte2 &= PEXT2_STUNAWARE;
|
||||||
connectinfo.ext.ez1 = 0;
|
connectinfo.ext.ez1 &= 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
|
@ -5553,6 +5553,8 @@ void CL_Status_f(void)
|
||||||
}
|
}
|
||||||
Con_Printf("Server address : %s\n", NET_AdrToString(adr, sizeof(adr), &cls.netchan.remote_address)); //not relevent as a limit.
|
Con_Printf("Server address : %s\n", NET_AdrToString(adr, sizeof(adr), &cls.netchan.remote_address)); //not relevent as a limit.
|
||||||
Con_Printf("Server cert fp : %s\n", b64); //not relevent as a limit.
|
Con_Printf("Server cert fp : %s\n", b64); //not relevent as a limit.
|
||||||
|
|
||||||
|
Con_Printf("Network MTU : %u (max %u) %s\n", cls.netchan.mtu_cur, cls.netchan.mtu_max, (cls.netchan.flags&NCF_FRAGABLE)?"":" (strict)"); //not relevent as a limit.
|
||||||
switch(cls.protocol)
|
switch(cls.protocol)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
|
@ -5715,6 +5717,7 @@ static void CL_UserinfoChanged(void *ctx, const char *keyname)
|
||||||
|
|
||||||
|
|
||||||
void CL_Skygroup_f(void);
|
void CL_Skygroup_f(void);
|
||||||
|
void WAD_ImageList_f(void);
|
||||||
/*
|
/*
|
||||||
=================
|
=================
|
||||||
CL_Init
|
CL_Init
|
||||||
|
@ -6090,6 +6093,7 @@ void CL_Init (void)
|
||||||
Cmd_AddCommandD ("waterfog", CL_Fog_f, "waterfog <density> <red> <green> <blue> <alpha> <depthbias>");
|
Cmd_AddCommandD ("waterfog", CL_Fog_f, "waterfog <density> <red> <green> <blue> <alpha> <depthbias>");
|
||||||
Cmd_AddCommandD ("skyroomfog", CL_Fog_f, "skyroomfog <density> <red> <green> <blue> <alpha> <depthbias>");
|
Cmd_AddCommandD ("skyroomfog", CL_Fog_f, "skyroomfog <density> <red> <green> <blue> <alpha> <depthbias>");
|
||||||
Cmd_AddCommandD ("skygroup", CL_Skygroup_f, "Provides a way to associate a skybox name with a series of maps, so that the requested skybox will override on a per-map basis.");
|
Cmd_AddCommandD ("skygroup", CL_Skygroup_f, "Provides a way to associate a skybox name with a series of maps, so that the requested skybox will override on a per-map basis.");
|
||||||
|
Cmd_AddCommandD ("r_imagelist_wad", WAD_ImageList_f, "displays the available wad images.");
|
||||||
//
|
//
|
||||||
// Windows commands
|
// Windows commands
|
||||||
//
|
//
|
||||||
|
|
|
@ -37,7 +37,6 @@ static char *CLNQ_ParseProQuakeMessage (char *s);
|
||||||
static void DLC_Poll(qdownload_t *dl);
|
static void DLC_Poll(qdownload_t *dl);
|
||||||
static void CL_ProcessUserInfo (int slot, player_info_t *player);
|
static void CL_ProcessUserInfo (int slot, player_info_t *player);
|
||||||
static void CL_ParseStuffCmd(char *msg, int destsplit);
|
static void CL_ParseStuffCmd(char *msg, int destsplit);
|
||||||
void Con_HexDump(qbyte *packet, size_t len, size_t badoffset);
|
|
||||||
|
|
||||||
#define MSG_ReadBigIndex() ((cls.fteprotocolextensions2&PEXT2_LONGINDEXES)?(unsigned int)MSG_ReadUInt64():MSG_ReadByte ())
|
#define MSG_ReadBigIndex() ((cls.fteprotocolextensions2&PEXT2_LONGINDEXES)?(unsigned int)MSG_ReadUInt64():MSG_ReadByte ())
|
||||||
#define MSG_ReadPlayer() MSG_ReadBigIndex()
|
#define MSG_ReadPlayer() MSG_ReadBigIndex()
|
||||||
|
@ -7040,7 +7039,7 @@ static void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds
|
||||||
if (developer.ival)
|
if (developer.ival)
|
||||||
{
|
{
|
||||||
Con_DPrintf("Proquake Message:\n");
|
Con_DPrintf("Proquake Message:\n");
|
||||||
Con_HexDump(msg, strlen(msg), 1);
|
Con_HexDump(msg, strlen(msg), 1, 16);
|
||||||
}
|
}
|
||||||
msg = CLNQ_ParseProQuakeMessage(msg);
|
msg = CLNQ_ParseProQuakeMessage(msg);
|
||||||
}
|
}
|
||||||
|
@ -7378,7 +7377,7 @@ static void CL_ParsePrecache(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Con_HexDump(qbyte *packet, size_t len, size_t badoffset)
|
void Con_HexDump(qbyte *packet, size_t len, size_t badoffset, size_t stride)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int pos;
|
int pos;
|
||||||
|
@ -7387,7 +7386,7 @@ void Con_HexDump(qbyte *packet, size_t len, size_t badoffset)
|
||||||
while(pos < len)
|
while(pos < len)
|
||||||
{
|
{
|
||||||
Con_Printf("%5i ", pos);
|
Con_Printf("%5i ", pos);
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < stride; i++)
|
||||||
{
|
{
|
||||||
if (pos >= len)
|
if (pos >= len)
|
||||||
Con_Printf(" - ");
|
Con_Printf(" - ");
|
||||||
|
@ -7397,8 +7396,8 @@ void Con_HexDump(qbyte *packet, size_t len, size_t badoffset)
|
||||||
Con_Printf("%2x ", packet[pos]);
|
Con_Printf("%2x ", packet[pos]);
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
pos-=16;
|
pos-=stride;
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < stride; i++)
|
||||||
{
|
{
|
||||||
if (pos >= len)
|
if (pos >= len)
|
||||||
Con_Printf("X");
|
Con_Printf("X");
|
||||||
|
@ -7424,7 +7423,7 @@ void Con_HexDump(qbyte *packet, size_t len, size_t badoffset)
|
||||||
}
|
}
|
||||||
void CL_DumpPacket(void)
|
void CL_DumpPacket(void)
|
||||||
{
|
{
|
||||||
Con_HexDump(net_message.data, net_message.cursize, MSG_GetReadCount()-1);
|
Con_HexDump(net_message.data, net_message.cursize, MSG_GetReadCount()-1, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CL_ParsePortalState(void)
|
static void CL_ParsePortalState(void)
|
||||||
|
@ -7838,11 +7837,18 @@ void CLQW_ParseServerMessage (void)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
inframe_t *inf = &cl.inframes[cls.netchan.incoming_sequence&UPDATE_MASK];
|
inframe_t *inf = &cl.inframes[cls.netchan.incoming_sequence&UPDATE_MASK];
|
||||||
|
int fixtype = 2;
|
||||||
if (cls.ezprotocolextensions1 & EZPEXT1_SETANGLEREASON)
|
if (cls.ezprotocolextensions1 & EZPEXT1_SETANGLEREASON)
|
||||||
MSG_ReadByte(); //0=unknown, 1=tele, 2=spawn
|
fixtype = MSG_ReadByte(); //0=unknown, 1=tele, 2=spawn
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i=0 ; i<3 ; i++)
|
||||||
ang[i] = MSG_ReadAngle();
|
ang[i] = MSG_ReadAngle();
|
||||||
if (!CSQC_Parse_SetAngles(destsplit, ang, false))
|
if (fixtype == 1)
|
||||||
|
{ //relative
|
||||||
|
VectorAdd(ang, cl.playerview[destsplit].viewangles, ang);
|
||||||
|
VectorSubtract(ang, cl.outframes[cls.netchan.incoming_sequence&UPDATE_MASK].cmd->angles, ang);
|
||||||
|
}
|
||||||
|
else fixtype = 2; //snap
|
||||||
|
if (!CSQC_Parse_SetAngles(destsplit, ang, fixtype==1))
|
||||||
{
|
{
|
||||||
inf->packet_entities.fixangles[destsplit] = true;
|
inf->packet_entities.fixangles[destsplit] = true;
|
||||||
VectorCopy (ang, cl.playerview[destsplit].viewangles);
|
VectorCopy (ang, cl.playerview[destsplit].viewangles);
|
||||||
|
|
|
@ -2003,7 +2003,10 @@ void SCR_DrawFPS (void)
|
||||||
fps_count = 0;
|
fps_count = 0;
|
||||||
lastupdatetime = t;
|
lastupdatetime = t;
|
||||||
|
|
||||||
R_GetGPUUtilisation(&gpu, &gpumem); //not all that accurate, but oh well.
|
if (developer.ival)
|
||||||
|
R_GetGPUUtilisation(&gpu, &gpumem); //not all that accurate, but oh well.
|
||||||
|
else
|
||||||
|
gpu=gpumem=-1;
|
||||||
}
|
}
|
||||||
frametime = t - lastsystemtime;
|
frametime = t - lastsystemtime;
|
||||||
lastsystemtime = t;
|
lastsystemtime = t;
|
||||||
|
|
|
@ -1579,6 +1579,7 @@ int TP_CategorizeMessage (char *s, int *offset, player_info_t **plr);
|
||||||
void TP_ExecTrigger (char *s, qboolean indemos); //executes one of the user's f_foo aliases from some engine-defined event.
|
void TP_ExecTrigger (char *s, qboolean indemos); //executes one of the user's f_foo aliases from some engine-defined event.
|
||||||
qboolean TP_FilterMessage (char *s);
|
qboolean TP_FilterMessage (char *s);
|
||||||
void TP_Init(void);
|
void TP_Init(void);
|
||||||
|
qboolean TP_HaveLocations(void);
|
||||||
char* TP_LocationName (const vec3_t location);
|
char* TP_LocationName (const vec3_t location);
|
||||||
void TP_NewMap (void);
|
void TP_NewMap (void);
|
||||||
qboolean TP_CheckSoundTrigger (char *str); //plays sound files when some substring exists in chat.
|
qboolean TP_CheckSoundTrigger (char *str); //plays sound files when some substring exists in chat.
|
||||||
|
|
|
@ -239,7 +239,7 @@ void Draw_Hexen2BigFontString(int x, int y, const char *text)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mpic_t *QBigFontWorks(void)
|
void *QBigFontWorks(void)
|
||||||
{
|
{
|
||||||
mpic_t *p;
|
mpic_t *p;
|
||||||
int i;
|
int i;
|
||||||
|
@ -250,14 +250,15 @@ mpic_t *QBigFontWorks(void)
|
||||||
"textures/mcharset.lmp",
|
"textures/mcharset.lmp",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
if (font_menu)
|
||||||
|
return font_menu;
|
||||||
for (i = 0; names[i]; i++)
|
for (i = 0; names[i]; i++)
|
||||||
{
|
{
|
||||||
p = R2D_SafeCachePic (names[i]);
|
p = R2D_SafeCachePic (names[i]);
|
||||||
if (p && R_GetShaderSizes(p, NULL, NULL, true))
|
if (p && R_GetShaderSizes(p, NULL, NULL, true))
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
return NULL;
|
||||||
return (mpic_t*)font_menu;
|
|
||||||
}
|
}
|
||||||
void Draw_BigFontString(int x, int y, const char *text)
|
void Draw_BigFontString(int x, int y, const char *text)
|
||||||
{
|
{
|
||||||
|
@ -598,7 +599,7 @@ static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, emenu_t *men
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (&menu->menu == topmenu && menu->mouseitem == option && option->common.type != mt_frameend)
|
if (&menu->menu == topmenu && menu->mouseitem == option && option->common.type != mt_frameend && !Key_Dest_Has_Higher(kdm_menu))
|
||||||
{
|
{
|
||||||
float alphamax = 0.5, alphamin = 0.2;
|
float alphamax = 0.5, alphamin = 0.2;
|
||||||
R2D_ImageColours(.5,.4,0,(sin(realtime*2)+1)*0.5*(alphamax-alphamin)+alphamin);
|
R2D_ImageColours(.5,.4,0,(sin(realtime*2)+1)*0.5*(alphamax-alphamin)+alphamin);
|
||||||
|
@ -608,12 +609,16 @@ static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, emenu_t *men
|
||||||
switch(option->common.type)
|
switch(option->common.type)
|
||||||
{
|
{
|
||||||
case mt_menucursor:
|
case mt_menucursor:
|
||||||
|
if (Key_Dest_Has_Higher(kdm_menu))
|
||||||
|
break;
|
||||||
if ((int)(realtime*4)&1)
|
if ((int)(realtime*4)&1)
|
||||||
Draw_FunString(xpos+option->common.posx, ypos+option->common.posy, "^Ue00d");
|
Draw_FunString(xpos+option->common.posx, ypos+option->common.posy, "^Ue00d");
|
||||||
break;
|
break;
|
||||||
case mt_text:
|
case mt_text:
|
||||||
if (!option->text.text)
|
if (!option->text.text)
|
||||||
{ //blinking cursor image hack (FIXME)
|
{ //blinking cursor image hack (FIXME)
|
||||||
|
if (Key_Dest_Has_Higher(kdm_menu))
|
||||||
|
break;
|
||||||
if ((int)(realtime*4)&1)
|
if ((int)(realtime*4)&1)
|
||||||
Draw_FunString(xpos+option->common.posx, ypos+option->common.posy, "^Ue00d");
|
Draw_FunString(xpos+option->common.posx, ypos+option->common.posy, "^Ue00d");
|
||||||
}
|
}
|
||||||
|
@ -636,16 +641,18 @@ static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, emenu_t *men
|
||||||
Draw_BigFontString(xpos+option->common.posx, ypos+option->common.posy, option->button.text);
|
Draw_BigFontString(xpos+option->common.posx, ypos+option->common.posy, option->button.text);
|
||||||
break;
|
break;
|
||||||
case mt_menudot:
|
case mt_menudot:
|
||||||
|
if (Key_Dest_Has_Higher(kdm_menu))
|
||||||
|
break;
|
||||||
i = (int)(realtime * 10)%maxdots;
|
i = (int)(realtime * 10)%maxdots;
|
||||||
p = R2D_SafeCachePic(va(menudotstyle, i+mindot ));
|
p = R2D_SafeCachePic(va(menudotstyle, i+mindot ));
|
||||||
if (R_GetShaderSizes(p, NULL, NULL, false)>0)
|
if (R_GetShaderSizes(p, &pw, &ph, false)>0)
|
||||||
R2D_ScalePic(xpos+option->common.posx, ypos+option->common.posy+dotofs, option->common.width, option->common.height, p);
|
R2D_ScalePic(xpos+option->common.posx, ypos+option->common.posy+dotofs, (pw/(float)ph)*option->common.width, option->common.height, p);
|
||||||
else if ((int)(realtime*4)&1)
|
else if ((int)(realtime*4)&1)
|
||||||
Draw_FunString(xpos+option->common.posx, ypos+option->common.posy + (option->common.height-8)/2, "^a^Ue00d");
|
Draw_FunString(xpos+option->common.posx, ypos+option->common.posy + (option->common.height-8)/2, "^a^Ue00d");
|
||||||
break;
|
break;
|
||||||
case mt_picturesel:
|
case mt_picturesel:
|
||||||
p = NULL;
|
p = NULL;
|
||||||
if (menu->selecteditem && menu->selecteditem->common.posx == option->common.posx && menu->selecteditem->common.posy == option->common.posy)
|
if (menu->selecteditem && menu->selecteditem->common.posx == option->common.posx && menu->selecteditem->common.posy == option->common.posy && !Key_Dest_Has_Higher(kdm_menu))
|
||||||
{
|
{
|
||||||
char selname[MAX_QPATH];
|
char selname[MAX_QPATH];
|
||||||
Q_strncpyz(selname, option->picture.picturename, sizeof(selname));
|
Q_strncpyz(selname, option->picture.picturename, sizeof(selname));
|
||||||
|
@ -816,7 +823,7 @@ static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, emenu_t *men
|
||||||
Draw_ApproxTextBox(x, y, 16*8, 8);
|
Draw_ApproxTextBox(x, y, 16*8, 8);
|
||||||
Draw_FunString(x, y, option->edit.text);
|
Draw_FunString(x, y, option->edit.text);
|
||||||
|
|
||||||
if (menu->selecteditem == option && (int)(realtime*4) & 1)
|
if (menu->selecteditem == option && (int)(realtime*4) & 1 && !Key_Dest_Has_Higher(kdm_menu))
|
||||||
{
|
{
|
||||||
vid.ime_allow = true;
|
vid.ime_allow = true;
|
||||||
vid.ime_position[0] = x;
|
vid.ime_position[0] = x;
|
||||||
|
@ -904,7 +911,7 @@ static void MenuDraw(emenu_t *menu)
|
||||||
menu->menu.showosk = false;
|
menu->menu.showosk = false;
|
||||||
MenuDrawItems(menu->xpos, menu->ypos, menu->options, menu);
|
MenuDrawItems(menu->xpos, menu->ypos, menu->options, menu);
|
||||||
// draw tooltip
|
// draw tooltip
|
||||||
if (menu->mouseitem && menu->tooltip && realtime > menu->tooltiptime)
|
if (menu->mouseitem && menu->tooltip && realtime > menu->tooltiptime && !Key_Dest_Has_Higher(kdm_menu))
|
||||||
{
|
{
|
||||||
// menuoption_t *option = menu->mouseitem;
|
// menuoption_t *option = menu->mouseitem;
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ static cvar_t sb_showtimelimit = CVARF("sb_showtimelimit", "0", CVAR_ARCHIVE);
|
||||||
|
|
||||||
static cvar_t sb_alpha = CVARF("sb_alpha", "0.7", CVAR_ARCHIVE);
|
static cvar_t sb_alpha = CVARF("sb_alpha", "0.7", CVAR_ARCHIVE);
|
||||||
|
|
||||||
vrect_t joinbutton, specbutton;
|
vrect_t joinbutton, streambutton, specbutton;
|
||||||
static float refreshedtime;
|
static float refreshedtime;
|
||||||
static int isrefreshing;
|
static int isrefreshing;
|
||||||
static enum
|
static enum
|
||||||
|
@ -372,7 +372,7 @@ static qboolean SL_ServerKey (menucustom_t *ths, emenu_t *menu, int key, unsigne
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (oldselection == info->selectedpos)
|
if (oldselection == info->selectedpos)
|
||||||
serverpreview = 1;
|
serverpreview = (server->adr.prot>=NP_STREAM)?SVPV_RULES:1;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,6 +466,7 @@ static void SL_PostDraw (emenu_t *menu)
|
||||||
serverinfo_t *server = selectedserver.inuse?Master_InfoForServer(&selectedserver.adr, selectedserver.brokerid):NULL;
|
serverinfo_t *server = selectedserver.inuse?Master_InfoForServer(&selectedserver.adr, selectedserver.brokerid):NULL;
|
||||||
int h = 0;
|
int h = 0;
|
||||||
int w = 240;
|
int w = 240;
|
||||||
|
char *qtv;
|
||||||
#ifdef HAVE_PACKET
|
#ifdef HAVE_PACKET
|
||||||
if (server && selectedserver.refreshtime < realtime)
|
if (server && selectedserver.refreshtime < realtime)
|
||||||
{
|
{
|
||||||
|
@ -706,6 +707,35 @@ static void SL_PostDraw (emenu_t *menu)
|
||||||
Draw_FunStringWidth(lx, y + (bh-8)/2, localtext("Observe"), bw, 2, active);y+=8;
|
Draw_FunStringWidth(lx, y + (bh-8)/2, localtext("Observe"), bw, 2, active);y+=8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qtv = Info_ValueForKey(server->moreinfo->info, "qtvstream");
|
||||||
|
if (server && *qtv)
|
||||||
|
{
|
||||||
|
int lx = vid.width/2 - w/2;
|
||||||
|
int y = vid.height/2 - h/2 - 4 + h;
|
||||||
|
int bh, bw;
|
||||||
|
qboolean active = false;
|
||||||
|
bw = w+16+12;
|
||||||
|
bh = 24;
|
||||||
|
// lx += bw-12;
|
||||||
|
bw = strlen(localtext("Stream"))*8 + 24;
|
||||||
|
bw = ((bw+15)/16) * 16; //width must be a multiple of 16
|
||||||
|
// lx -= bw;
|
||||||
|
|
||||||
|
streambutton.x = lx;
|
||||||
|
streambutton.y = y;
|
||||||
|
streambutton.width = bw + 16;
|
||||||
|
streambutton.height = bh + 16;
|
||||||
|
R2D_ImageColours(1,1,1,1);
|
||||||
|
y += 8;
|
||||||
|
Draw_ApproxTextBox(lx, y, bw, bh);
|
||||||
|
|
||||||
|
if (mousecursor_x >= streambutton.x && mousecursor_x < streambutton.x+streambutton.width)
|
||||||
|
if (mousecursor_y >= streambutton.y && mousecursor_y < streambutton.y+streambutton.height)
|
||||||
|
active = true;
|
||||||
|
|
||||||
|
Draw_FunStringWidth(lx, y + (bh-8)/2, localtext("Stream"), bw, 2, active);y+=8;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
int lx = vid.width/2 - w/2;
|
int lx = vid.width/2 - w/2;
|
||||||
int y = vid.height/2 - h/2 - 4 + h;
|
int y = vid.height/2 - h/2 - 4 + h;
|
||||||
|
@ -794,6 +824,12 @@ static qboolean SL_Key (emenu_t *menu, int key, unsigned int unicode)
|
||||||
serverpreview = SVPV_NO;
|
serverpreview = SVPV_NO;
|
||||||
goto dospec;
|
goto dospec;
|
||||||
}
|
}
|
||||||
|
if (mousecursor_x >= streambutton.x && mousecursor_x < streambutton.x+streambutton.width)
|
||||||
|
if (mousecursor_y >= streambutton.y && mousecursor_y < streambutton.y+streambutton.height)
|
||||||
|
{
|
||||||
|
serverpreview = SVPV_NO;
|
||||||
|
goto dostream;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_PACKET
|
#ifdef HAVE_PACKET
|
||||||
|
@ -839,6 +875,13 @@ static qboolean SL_Key (emenu_t *menu, int key, unsigned int unicode)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
else if (key == 't')
|
||||||
|
{
|
||||||
|
dostream:
|
||||||
|
Cbuf_AddText(va("qtvplay \"%s\"\n", Info_ValueForKey(server->moreinfo->info, "qtvstream")), RESTRICT_LOCAL);
|
||||||
|
M_RemoveAllMenus(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
else if (key == 'b' || key == 'o' || key == 'j' || key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_GP_DIAMOND_ALTCONFIRM) //join
|
else if (key == 'b' || key == 'o' || key == 'j' || key == K_ENTER || key == K_KP_ENTER || key == K_GP_DIAMOND_CONFIRM || key == K_GP_DIAMOND_ALTCONFIRM) //join
|
||||||
{
|
{
|
||||||
if (key == 's' || key == 'o' || key == K_GP_DIAMOND_ALTCONFIRM)
|
if (key == 's' || key == 'o' || key == K_GP_DIAMOND_ALTCONFIRM)
|
||||||
|
|
|
@ -364,7 +364,7 @@ menucheck_t *MC_AddCheckBox(emenu_t *menu, int tx, int cx, int y, const char *te
|
||||||
menucheck_t *MC_AddCheckBoxFunc(emenu_t *menu, int tx, int cx, int y, const char *text, qboolean (*func) (menucheck_t *option, emenu_t *menu, chk_set_t set), int bits);
|
menucheck_t *MC_AddCheckBoxFunc(emenu_t *menu, int tx, int cx, int y, const char *text, qboolean (*func) (menucheck_t *option, emenu_t *menu, chk_set_t set), int bits);
|
||||||
menubutton_t *MC_AddConsoleCommand(emenu_t *menu, int lhs, int rhs, int y, const char *text, const char *command);
|
menubutton_t *MC_AddConsoleCommand(emenu_t *menu, int lhs, int rhs, int y, const char *text, const char *command);
|
||||||
menubutton_t *MC_AddConsoleCommandQBigFont(emenu_t *menu, int x, int y, const char *text, const char *command);
|
menubutton_t *MC_AddConsoleCommandQBigFont(emenu_t *menu, int x, int y, const char *text, const char *command);
|
||||||
mpic_t *QBigFontWorks(void);
|
void *QBigFontWorks(void); //treat as a boolean.
|
||||||
menubutton_t *MC_AddConsoleCommandHexen2BigFont(emenu_t *menu, int x, int y, const char *text, const char *command);
|
menubutton_t *MC_AddConsoleCommandHexen2BigFont(emenu_t *menu, int x, int y, const char *text, const char *command);
|
||||||
menubutton_t *VARGS MC_AddConsoleCommandf(emenu_t *menu, int lhs, int rhs, int y, int rightalign, const char *text, char *command, ...);
|
menubutton_t *VARGS MC_AddConsoleCommandf(emenu_t *menu, int lhs, int rhs, int y, int rightalign, const char *text, char *command, ...);
|
||||||
menubutton_t *MC_AddCommand(emenu_t *menu, int lhs, int rhs, int y, const char *text, qboolean (*command) (union menuoption_s *,struct emenu_s *,int));
|
menubutton_t *MC_AddCommand(emenu_t *menu, int lhs, int rhs, int y, const char *text, qboolean (*command) (union menuoption_s *,struct emenu_s *,int));
|
||||||
|
|
|
@ -2965,7 +2965,7 @@ static void MasterInfo_Request(master_t *mast)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case MP_QUAKEWORLD:
|
case MP_QUAKEWORLD:
|
||||||
NET_SendPollPacket (14, va("%c%c%c%cstatus 23\n", 255, 255, 255, 255), mast->adr);
|
NET_SendPollPacket (14, va("%c%c%c%cstatus %i\n", 255, 255, 255, 255, STATUS_QTVLIST|STATUS_SHOWTEAMS|STATUS_SPECTATORS|STATUS_PLAYERS|STATUS_SERVERINFO), mast->adr);
|
||||||
break;
|
break;
|
||||||
#ifdef NQPROT
|
#ifdef NQPROT
|
||||||
case MP_NETQUAKE:
|
case MP_NETQUAKE:
|
||||||
|
@ -3151,7 +3151,7 @@ void Master_QueryServer(serverinfo_t *server)
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
case SS_QUAKEWORLD:
|
case SS_QUAKEWORLD:
|
||||||
Q_snprintfz(data, sizeof(data), "%c%c%c%cstatus 23\n", 255, 255, 255, 255);
|
Q_snprintfz(data, sizeof(data), "%c%c%c%cstatus %i\n", 255, 255, 255, 255, STATUS_QTVLIST|STATUS_SHOWTEAMS|STATUS_SPECTATORS|STATUS_PLAYERS|STATUS_SERVERINFO);
|
||||||
break;
|
break;
|
||||||
case SS_QUAKE2:
|
case SS_QUAKE2:
|
||||||
Q_snprintfz(data, sizeof(data), "%c%c%c%cstatus\n", 255, 255, 255, 255);
|
Q_snprintfz(data, sizeof(data), "%c%c%c%cstatus\n", 255, 255, 255, 255);
|
||||||
|
@ -3577,13 +3577,35 @@ static int CL_ReadServerInfo(char *msg, enum masterprotocol_e prototype, qboolea
|
||||||
{
|
{
|
||||||
int clnum;
|
int clnum;
|
||||||
|
|
||||||
for (clnum=0; clnum < MAX_CLIENTS; clnum++)
|
for (clnum=0; ; clnum++)
|
||||||
{
|
{
|
||||||
nl = strchr(msg, '\n');
|
nl = strchr(msg, '\n');
|
||||||
if (!nl)
|
if (!nl)
|
||||||
break;
|
break;
|
||||||
*nl = '\0';
|
*nl = '\0';
|
||||||
|
|
||||||
|
if (!strncmp(msg, "qtv ", 4))
|
||||||
|
{ //qtv destnum "proxyname" "stream@host:port" viewercount
|
||||||
|
char proxstream[128];
|
||||||
|
char tokval[256];
|
||||||
|
token = msg+4;
|
||||||
|
|
||||||
|
token = COM_ParseOut(token, tokval,sizeof(tokval));
|
||||||
|
//destnum = atoi(tokval);
|
||||||
|
token = COM_ParseOut(token, tokval,sizeof(tokval));
|
||||||
|
//proxy name...
|
||||||
|
token = COM_ParseOut(token, proxstream,sizeof(proxstream));
|
||||||
|
token = COM_ParseOut(token, tokval,sizeof(tokval));
|
||||||
|
//viewercount = atoi(tokval);
|
||||||
|
|
||||||
|
if (*proxstream)
|
||||||
|
Info_SetValueForKey(details.info, "qtvstream", proxstream, sizeof(details.info));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clnum == MAX_CLIENTS)
|
||||||
|
break;
|
||||||
|
|
||||||
details.players[clnum].isspec = 0;
|
details.players[clnum].isspec = 0;
|
||||||
details.players[clnum].team[0] = 0;
|
details.players[clnum].team[0] = 0;
|
||||||
details.players[clnum].skin[0] = 0;
|
details.players[clnum].skin[0] = 0;
|
||||||
|
|
|
@ -36,6 +36,7 @@ int webo_blocklightmapupdates; //0 no webo, &1=using threadedworld, &2=already u
|
||||||
#ifdef BEF_PUSHDEPTH
|
#ifdef BEF_PUSHDEPTH
|
||||||
qboolean r_pushdepth;
|
qboolean r_pushdepth;
|
||||||
#endif
|
#endif
|
||||||
|
qboolean r_dlightlightmaps; //updated each frame, says whether to do lightmap hack dlights.
|
||||||
|
|
||||||
extern cvar_t r_ambient;
|
extern cvar_t r_ambient;
|
||||||
|
|
||||||
|
@ -2314,7 +2315,7 @@ void Surf_GenBrushBatches(batch_t **batches, entity_t *ent)
|
||||||
|
|
||||||
currententity = ent;
|
currententity = ent;
|
||||||
currentmodel = ent->model;
|
currentmodel = ent->model;
|
||||||
if (model->nummodelsurfaces != 0 && r_dynamic.ival > 0)
|
if (model->nummodelsurfaces != 0 && r_dlightlightmaps && model->funcs.MarkLights)
|
||||||
{
|
{
|
||||||
for (k=rtlights_first; k<RTL_FIRST; k++)
|
for (k=rtlights_first; k<RTL_FIRST; k++)
|
||||||
{
|
{
|
||||||
|
@ -2999,7 +3000,7 @@ void Surf_DrawWorld (void)
|
||||||
currentmodel = cl.worldmodel;
|
currentmodel = cl.worldmodel;
|
||||||
currententity = &r_worldentity;
|
currententity = &r_worldentity;
|
||||||
|
|
||||||
r_dynamic.ival = r_dynamic.value;
|
r_dlightlightmaps = !!r_dynamic.ival;
|
||||||
|
|
||||||
{
|
{
|
||||||
#ifdef THREADEDWORLD
|
#ifdef THREADEDWORLD
|
||||||
|
@ -3026,8 +3027,8 @@ void Surf_DrawWorld (void)
|
||||||
{
|
{
|
||||||
r_dynamic.modified = false;
|
r_dynamic.modified = false;
|
||||||
r_temporalscenecache.modified = false;
|
r_temporalscenecache.modified = false;
|
||||||
#ifdef RTLIGHT
|
#ifdef RTLIGHTS
|
||||||
Sh_CheckSettings(); //fiddle with r_dynamic vs r_shadow_realtime_dlight.
|
// Sh_CheckSettings(); //fiddle with r_dynamic vs r_shadow_realtime_dlight.
|
||||||
#endif
|
#endif
|
||||||
COM_WorkerPartialSync(webogenerating, &webogeneratingstate, true);
|
COM_WorkerPartialSync(webogenerating, &webogeneratingstate, true);
|
||||||
while (webostates)
|
while (webostates)
|
||||||
|
@ -3219,7 +3220,7 @@ void Surf_DrawWorld (void)
|
||||||
if (webostate->cluster[0] == r_viewcluster && webostate->cluster[1] == r_viewcluster2)
|
if (webostate->cluster[0] == r_viewcluster && webostate->cluster[1] == r_viewcluster2)
|
||||||
VectorCopy(r_refdef.vieworg, webostate->lastpos);
|
VectorCopy(r_refdef.vieworg, webostate->lastpos);
|
||||||
|
|
||||||
r_dynamic.ival = -1; //don't waste time on dlighting models.
|
r_dlightlightmaps = false; //don't waste time on dlighting bmodels.
|
||||||
|
|
||||||
RSpeedEnd(RSPEED_WORLDNODE);
|
RSpeedEnd(RSPEED_WORLDNODE);
|
||||||
|
|
||||||
|
@ -3242,9 +3243,9 @@ void Surf_DrawWorld (void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef RTLIGHT
|
#ifdef RTLIGHTS
|
||||||
if (r_shadow_realtime_dlight.ival || currentmodel->type != mod_brush || !(currentmodel->fromgame == fg_quake || currentmodel->fromgame == fg_halflife) || !currentmodel->funcs.MarkLights)
|
if (r_shadow_realtime_dlight.ival || currentmodel->type != mod_brush || !(currentmodel->fromgame == fg_quake || currentmodel->fromgame == fg_halflife) || !currentmodel->funcs.MarkLights)
|
||||||
r_dynamic.ival = -1;
|
r_dlightlightmaps = false; //don't do double lighting.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Surf_PushChains(currentmodel->batches);
|
Surf_PushChains(currentmodel->batches);
|
||||||
|
|
|
@ -688,6 +688,7 @@ extern cvar_t r_lavastyle;
|
||||||
extern cvar_t r_slimestyle;
|
extern cvar_t r_slimestyle;
|
||||||
extern cvar_t r_telestyle;
|
extern cvar_t r_telestyle;
|
||||||
extern cvar_t r_dynamic;
|
extern cvar_t r_dynamic;
|
||||||
|
extern qboolean r_dlightlightmaps;
|
||||||
extern cvar_t r_temporalscenecache;
|
extern cvar_t r_temporalscenecache;
|
||||||
extern cvar_t r_novis;
|
extern cvar_t r_novis;
|
||||||
extern cvar_t r_netgraph;
|
extern cvar_t r_netgraph;
|
||||||
|
|
|
@ -1802,7 +1802,7 @@ TRACE(("dbg: R_ApplyRenderer: starting on client state\n"));
|
||||||
memcpy(¤trendererstate, newr, sizeof(currentrendererstate));
|
memcpy(¤trendererstate, newr, sizeof(currentrendererstate));
|
||||||
|
|
||||||
TRACE(("dbg: R_ApplyRenderer: S_Restart_f\n"));
|
TRACE(("dbg: R_ApplyRenderer: S_Restart_f\n"));
|
||||||
if (!isDedicated)
|
if (!isDedicated && newr)
|
||||||
S_DoRestart(true);
|
S_DoRestart(true);
|
||||||
|
|
||||||
#ifdef VM_UI
|
#ifdef VM_UI
|
||||||
|
|
|
@ -33,6 +33,11 @@ static cvar_t scr_scoreboard_drawtitle = CVARD("scr_scoreboard_drawtitle", "1",
|
||||||
static cvar_t scr_scoreboard_forcecolors = CVARD("scr_scoreboard_forcecolors", "0", "Makes the scoreboard colours obey enemycolor/teamcolor rules."); //damn americans
|
static cvar_t scr_scoreboard_forcecolors = CVARD("scr_scoreboard_forcecolors", "0", "Makes the scoreboard colours obey enemycolor/teamcolor rules."); //damn americans
|
||||||
static cvar_t scr_scoreboard_newstyle = CVARD("scr_scoreboard_newstyle", "1", "Display team colours and stuff in a style popularised by Electro. Looks more modern, but might not quite fit classic huds."); // New scoreboard style ported from Electro, by Molgrum
|
static cvar_t scr_scoreboard_newstyle = CVARD("scr_scoreboard_newstyle", "1", "Display team colours and stuff in a style popularised by Electro. Looks more modern, but might not quite fit classic huds."); // New scoreboard style ported from Electro, by Molgrum
|
||||||
static cvar_t scr_scoreboard_showfrags = CVARD("scr_scoreboard_showfrags", "0", "Display kills+deaths+teamkills, as determined by fragfile.dat-based conprint parsing. These may be inaccurate if you join mid-game.");
|
static cvar_t scr_scoreboard_showfrags = CVARD("scr_scoreboard_showfrags", "0", "Display kills+deaths+teamkills, as determined by fragfile.dat-based conprint parsing. These may be inaccurate if you join mid-game.");
|
||||||
|
#ifdef QUAKESTATS
|
||||||
|
static cvar_t scr_scoreboard_showlocation = CVARD("scr_scoreboard_showlocation", "1", "Display player location names when playing mvd/qtv streams, if available.");
|
||||||
|
static cvar_t scr_scoreboard_showhealth = CVARD("scr_scoreboard_showhealth", "3", "Display health information when playing mvd/qtv streams.\n0: off\n1: on\n2: show armour too. 3: combined health ('+' says more armour than health allows).");
|
||||||
|
static cvar_t scr_scoreboard_showweapon = CVARD("scr_scoreboard_showweapon", "1", "Display weapon information when playing mvd/qtv streams.");
|
||||||
|
#endif
|
||||||
static cvar_t scr_scoreboard_showflags = CVARD("scr_scoreboard_showflags", "2", "Display flag caps+touches on the scoreboard, where our fragfile.dat supports them.\n0: off\n1: on\n2: on only if someone appears to have interacted with a flag.");
|
static cvar_t scr_scoreboard_showflags = CVARD("scr_scoreboard_showflags", "2", "Display flag caps+touches on the scoreboard, where our fragfile.dat supports them.\n0: off\n1: on\n2: on only if someone appears to have interacted with a flag.");
|
||||||
static cvar_t scr_scoreboard_fillalpha = CVARD("scr_scoreboard_fillalpha", "0.7", "Transparency amount for newstyle scoreboard.");
|
static cvar_t scr_scoreboard_fillalpha = CVARD("scr_scoreboard_fillalpha", "0.7", "Transparency amount for newstyle scoreboard.");
|
||||||
static cvar_t scr_scoreboard_backgroundalpha = CVARD("scr_scoreboard_backgroundalpha", "0.5", "Further multiplier for the background alphas.");
|
static cvar_t scr_scoreboard_backgroundalpha = CVARD("scr_scoreboard_backgroundalpha", "0.5", "Further multiplier for the background alphas.");
|
||||||
|
@ -1178,6 +1183,11 @@ void Sbar_Init (void)
|
||||||
Cvar_Register(&scr_scoreboard_forcecolors, "Scoreboard settings");
|
Cvar_Register(&scr_scoreboard_forcecolors, "Scoreboard settings");
|
||||||
Cvar_Register(&scr_scoreboard_newstyle, "Scoreboard settings");
|
Cvar_Register(&scr_scoreboard_newstyle, "Scoreboard settings");
|
||||||
Cvar_Register(&scr_scoreboard_showfrags, "Scoreboard settings");
|
Cvar_Register(&scr_scoreboard_showfrags, "Scoreboard settings");
|
||||||
|
#ifdef QUAKESTATS
|
||||||
|
Cvar_Register(&scr_scoreboard_showlocation, "Scoreboard settings");
|
||||||
|
Cvar_Register(&scr_scoreboard_showhealth, "Scoreboard settings");
|
||||||
|
Cvar_Register(&scr_scoreboard_showweapon, "Scoreboard settings");
|
||||||
|
#endif
|
||||||
Cvar_Register(&scr_scoreboard_showflags, "Scoreboard settings");
|
Cvar_Register(&scr_scoreboard_showflags, "Scoreboard settings");
|
||||||
Cvar_Register(&scr_scoreboard_showruleset, "Scoreboard settings");
|
Cvar_Register(&scr_scoreboard_showruleset, "Scoreboard settings");
|
||||||
Cvar_Register(&scr_scoreboard_afk, "Scoreboard settings");
|
Cvar_Register(&scr_scoreboard_afk, "Scoreboard settings");
|
||||||
|
@ -3619,6 +3629,12 @@ ping time frags name
|
||||||
code \
|
code \
|
||||||
} \
|
} \
|
||||||
}, fill)
|
}, fill)
|
||||||
|
#define COLUMN_STAT2(title, width, code, fill) COLUMN(title, width, { \
|
||||||
|
if (!s->spectator) \
|
||||||
|
{ \
|
||||||
|
code \
|
||||||
|
} \
|
||||||
|
}, fill)
|
||||||
#define COLUMN_RULESET COLUMN(ruleset, 8*8, {Draw_FunStringWidth(x, y, s->ruleset, 8*8+4, false, false);},NOFILL)
|
#define COLUMN_RULESET COLUMN(ruleset, 8*8, {Draw_FunStringWidth(x, y, s->ruleset, 8*8+4, false, false);},NOFILL)
|
||||||
#define COLUMN_NAME COLUMN(name, namesize, {Draw_FunStringWidth(x, y, s->name, namesize, false, highlight);},NOFILL)
|
#define COLUMN_NAME COLUMN(name, namesize, {Draw_FunStringWidth(x, y, s->name, namesize, false, highlight);},NOFILL)
|
||||||
#define COLUMN_KILLS COLUMN_STAT(kils, 4*8, {Draw_FunStringWidth(x, y, va("%4i", Stats_GetKills(k)), 4*8+4, false, false);},NOFILL)
|
#define COLUMN_KILLS COLUMN_STAT(kils, 4*8, {Draw_FunStringWidth(x, y, va("%4i", Stats_GetKills(k)), 4*8+4, false, false);},NOFILL)
|
||||||
|
@ -3626,11 +3642,46 @@ ping time frags name
|
||||||
#define COLUMN_DEATHS COLUMN_STAT(dths, 4*8, {Draw_FunStringWidth(x, y, va("%4i", Stats_GetDeaths(k)), 4*8+4, false, false);},NOFILL)
|
#define COLUMN_DEATHS COLUMN_STAT(dths, 4*8, {Draw_FunStringWidth(x, y, va("%4i", Stats_GetDeaths(k)), 4*8+4, false, false);},NOFILL)
|
||||||
#define COLUMN_TOUCHES COLUMN_STAT(tchs, 4*8, {Draw_FunStringWidth(x, y, va("%4i", Stats_GetTouches(k)), 4*8+4, false, false);},NOFILL)
|
#define COLUMN_TOUCHES COLUMN_STAT(tchs, 4*8, {Draw_FunStringWidth(x, y, va("%4i", Stats_GetTouches(k)), 4*8+4, false, false);},NOFILL)
|
||||||
#define COLUMN_CAPS COLUMN_STAT(caps, 4*8, {Draw_FunStringWidth(x, y, va("%4i", Stats_GetCaptures(k)), 4*8+4, false, false);},NOFILL)
|
#define COLUMN_CAPS COLUMN_STAT(caps, 4*8, {Draw_FunStringWidth(x, y, va("%4i", Stats_GetCaptures(k)), 4*8+4, false, false);},NOFILL)
|
||||||
|
#ifdef QUAKESTATS
|
||||||
|
#define COLUMN_HEALTH COLUMN_STAT2(hlth, (scr_scoreboard_showhealth.ival==2)?7*8:4*8, { \
|
||||||
|
float t;int c; \
|
||||||
|
int a = cl.players[k].stats[STAT_ARMOR]; \
|
||||||
|
int h = cl.players[k].stats[STAT_HEALTH]; \
|
||||||
|
if (cl.players[k].stats[STAT_ITEMS] & IT_ARMOR3) {c='1';t = 0.8f;}\
|
||||||
|
else if (cl.players[k].stats[STAT_ITEMS] & IT_ARMOR2) {c='3';t = 0.6f;}\
|
||||||
|
else if (cl.players[k].stats[STAT_ITEMS] & IT_ARMOR1) {c='2';t = 0.3f;}\
|
||||||
|
else {c='7';t = 0.f ;}\
|
||||||
|
if (h <= 0) /*draw nothing*/ ; \
|
||||||
|
else if (scr_scoreboard_showhealth.ival==3&&a>0) { int m = h/(1-t); Draw_FunStringWidth(x, y, va(a>m?"^%c%+4i":"^%c%4i", c,h + bound(0, m, a)), 4*8+4, false, false); } \
|
||||||
|
else if (scr_scoreboard_showhealth.ival==2) Draw_FunStringWidth(x, y, (a>0)?va("^%c%3i^7/%-3i", c,a,h):va("---/%-3i", h), 7*8+4, false, false); \
|
||||||
|
else Draw_FunStringWidth(x, y, va("%4i", h), 4*8+4, false, false); \
|
||||||
|
},NOFILL)
|
||||||
|
#define COLUMN_BESTWEAPON COLUMN_STAT2(wep, 4*8, { \
|
||||||
|
Draw_FunStringWidth(x, y, va("%s%s%s", \
|
||||||
|
(cl.players[k].stats[STAT_ITEMS] & IT_LIGHTNING)?"^5L":" ", \
|
||||||
|
(cl.players[k].stats[STAT_ITEMS] & IT_ROCKET_LAUNCHER)?"^1R":" ", \
|
||||||
|
(cl.players[k].stats[STAT_ITEMS] & IT_GRENADE_LAUNCHER)?"^2G":" " \
|
||||||
|
), 4*8+4, false, false); \
|
||||||
|
},NOFILL)
|
||||||
|
#define COLUMN_LOCATION COLUMN_STAT2(loc, 8*8, { \
|
||||||
|
lerpents_t *le; \
|
||||||
|
const char *loc; \
|
||||||
|
if (k+1 < cl.maxlerpents && cl.lerpentssequence && cl.lerpents[k+1].sequence == cl.lerpentssequence) le = &cl.lerpents[k+1]; \
|
||||||
|
else if (cl.lerpentssequence && cl.lerpplayers[k].sequence == cl.lerpentssequence) le = &cl.lerpplayers[k];\
|
||||||
|
else le = NULL;\
|
||||||
|
loc = le?TP_LocationName(le->origin):""; \
|
||||||
|
Draw_FunStringWidth(x, y, loc, 8*8+4, false, false); \
|
||||||
|
},NOFILL)
|
||||||
|
#else
|
||||||
|
#define COLUMN_HEALTH
|
||||||
|
#define COLUMN_BESTWEAPON
|
||||||
|
#define COLUMN_LOCATION
|
||||||
|
#endif
|
||||||
#define COLUMN_AFK COLUMN(afk, 0, {int cs = atoi(InfoBuf_ValueForKey(&s->userinfo, "chat")); if (cs)Draw_FunStringWidth(x+4, y, (cs&2)?"afk":"msg", 4*8, false, false);},NOFILL)
|
#define COLUMN_AFK COLUMN(afk, 0, {int cs = atoi(InfoBuf_ValueForKey(&s->userinfo, "chat")); if (cs)Draw_FunStringWidth(x+4, y, (cs&2)?"afk":"msg", 4*8, false, false);},NOFILL)
|
||||||
|
|
||||||
|
|
||||||
//columns are listed here in display order
|
//columns are listed here in display order
|
||||||
#define ALLCOLUMNS COLUMN_PING COLUMN_PL COLUMN_TIME COLUMN_RULESET COLUMN_FRAGS COLUMN_TEAMNAME COLUMN_NAME COLUMN_KILLS COLUMN_TKILLS COLUMN_DEATHS COLUMN_TOUCHES COLUMN_CAPS COLUMN_AFK
|
#define ALLCOLUMNS COLUMN_PING COLUMN_PL COLUMN_TIME COLUMN_RULESET COLUMN_FRAGS COLUMN_TEAMNAME COLUMN_NAME COLUMN_HEALTH COLUMN_BESTWEAPON COLUMN_LOCATION COLUMN_KILLS COLUMN_TKILLS COLUMN_DEATHS COLUMN_TOUCHES COLUMN_CAPS COLUMN_AFK
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -3768,6 +3819,20 @@ void Sbar_DeathmatchOverlay (playerview_t *pv, int start)
|
||||||
COLUMN_TKILLS
|
COLUMN_TKILLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef QUAKESTATS
|
||||||
|
if (scr_scoreboard_showhealth.ival && cls.demoplayback==DPB_MVD)
|
||||||
|
{
|
||||||
|
COLUMN_HEALTH
|
||||||
|
}
|
||||||
|
if (scr_scoreboard_showweapon.ival && cls.demoplayback==DPB_MVD)
|
||||||
|
{
|
||||||
|
COLUMN_BESTWEAPON
|
||||||
|
}
|
||||||
|
if (scr_scoreboard_showlocation.ival && cls.demoplayback==DPB_MVD && TP_HaveLocations())
|
||||||
|
{
|
||||||
|
COLUMN_LOCATION
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (scr_scoreboard_showflags.ival && cl.teamplay && Stats_HaveFlags(scr_scoreboard_showflags.ival&1))
|
if (scr_scoreboard_showflags.ival && cl.teamplay && Stats_HaveFlags(scr_scoreboard_showflags.ival&1))
|
||||||
{
|
{
|
||||||
COLUMN_TOUCHES
|
COLUMN_TOUCHES
|
||||||
|
|
|
@ -322,7 +322,7 @@ void Skin_WorkerLoad(void *skinptr, void *data, size_t a, size_t b)
|
||||||
{
|
{
|
||||||
qwskin_t *skin = skinptr;
|
qwskin_t *skin = skinptr;
|
||||||
char name[MAX_QPATH];
|
char name[MAX_QPATH];
|
||||||
qbyte *out;
|
qbyte *out = NULL;
|
||||||
int srcw = 0, srch = 0;
|
int srcw = 0, srch = 0;
|
||||||
|
|
||||||
size_t pcxsize = 0;
|
size_t pcxsize = 0;
|
||||||
|
@ -362,9 +362,14 @@ void Skin_WorkerLoad(void *skinptr, void *data, size_t a, size_t b)
|
||||||
Q_snprintfz (name, sizeof(name), "skins/%s.pcx", skin->name);
|
Q_snprintfz (name, sizeof(name), "skins/%s.pcx", skin->name);
|
||||||
pcxfiledata = FS_LoadMallocFileFlags (name, FSLF_IGNOREPURE, &pcxsize);
|
pcxfiledata = FS_LoadMallocFileFlags (name, FSLF_IGNOREPURE, &pcxsize);
|
||||||
if (!pcxfiledata)
|
if (!pcxfiledata)
|
||||||
{
|
{ //FIXME: use 24bit skins even if gl_load24bit is failed
|
||||||
//use 24bit skins even if gl_load24bit is failed
|
if (!strcmp(skin->name, "solid") || !strcmp(skin->name, "block"))
|
||||||
if (strcmp(skin->name, baseskin.string))
|
{ //allow block colour, even if the file isn't found.
|
||||||
|
srcw = srch = 1;
|
||||||
|
out = BZ_Malloc(srcw*srch);
|
||||||
|
memset(out, BOTTOM_DEFAULT | 15, srcw*srch);
|
||||||
|
}
|
||||||
|
else if (strcmp(skin->name, baseskin.string))
|
||||||
{
|
{
|
||||||
//if its not already the base skin, try the base (and warn if anything not base couldn't load).
|
//if its not already the base skin, try the base (and warn if anything not base couldn't load).
|
||||||
Con_Printf ("Couldn't load skin %s\n", name);
|
Con_Printf ("Couldn't load skin %s\n", name);
|
||||||
|
@ -374,15 +379,12 @@ void Skin_WorkerLoad(void *skinptr, void *data, size_t a, size_t b)
|
||||||
pcxfiledata = FS_LoadMallocFileFlags (name, FSLF_IGNOREPURE, &pcxsize);
|
pcxfiledata = FS_LoadMallocFileFlags (name, FSLF_IGNOREPURE, &pcxsize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!pcxfiledata)
|
|
||||||
{
|
|
||||||
Skin_WorkerDone(skin, NULL, 0, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pcxfiledata)
|
if (out)
|
||||||
|
;
|
||||||
|
else if (pcxfiledata)
|
||||||
{
|
{
|
||||||
out = Skin_ParsePCX(name, pcxfiledata, pcxsize, &srcw, &srch);
|
out = Skin_ParsePCX(name, pcxfiledata, pcxsize, &srcw, &srch);
|
||||||
FS_FreeFile(pcxfiledata);
|
FS_FreeFile(pcxfiledata);
|
||||||
|
|
|
@ -626,6 +626,24 @@ miptex_t *W_GetMipTex(const char *name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WAD_ImageList_f(void)
|
||||||
|
{
|
||||||
|
wadfile_t *wad;
|
||||||
|
int i;
|
||||||
|
char *match = Cmd_Argv(1);
|
||||||
|
Sys_LockMutex(wadmutex);
|
||||||
|
for (i = 0;i < numwadtextures;i++)
|
||||||
|
{
|
||||||
|
if (*match && !wildcmp(match, texwadlump[i].name))
|
||||||
|
continue;
|
||||||
|
for (wad = openwadfiles; wad; wad = wad->next)
|
||||||
|
if (wad->file == texwadlump[i].file)
|
||||||
|
break;
|
||||||
|
Con_Printf("^[\\img\\%s\\s\\%i\\tip\\From inside %s^] %s\n", texwadlump[i].name, 64, wad?wad->name:"<unknown>", texwadlump[i].name);
|
||||||
|
}
|
||||||
|
Sys_UnlockMutex(wadmutex);
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct mapgroup_s {
|
typedef struct mapgroup_s {
|
||||||
char *mapname;
|
char *mapname;
|
||||||
char *skyname;
|
char *skyname;
|
||||||
|
|
|
@ -1788,7 +1788,10 @@ static void TP_LoadLocFile_f (void)
|
||||||
|
|
||||||
TP_LoadLocFile (Cmd_Argv(1), false);
|
TP_LoadLocFile (Cmd_Argv(1), false);
|
||||||
}
|
}
|
||||||
|
qboolean TP_HaveLocations(void)
|
||||||
|
{
|
||||||
|
return loc_numentries>0;
|
||||||
|
}
|
||||||
char *TP_LocationName (const vec3_t location)
|
char *TP_LocationName (const vec3_t location)
|
||||||
{
|
{
|
||||||
int i, j, minnum;
|
int i, j, minnum;
|
||||||
|
|
|
@ -5970,6 +5970,7 @@ static void COM_Version_f (void)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_SERVER) || defined(HAVE_CLIENT)
|
||||||
Con_Printf("^3Games:^7");
|
Con_Printf("^3Games:^7");
|
||||||
#if defined(Q3SERVER) && defined(Q3CLIENT)
|
#if defined(Q3SERVER) && defined(Q3CLIENT)
|
||||||
#ifdef BOTLIB_STATIC
|
#ifdef BOTLIB_STATIC
|
||||||
|
@ -6030,6 +6031,7 @@ static void COM_Version_f (void)
|
||||||
Con_Printf(" ssqc");
|
Con_Printf(" ssqc");
|
||||||
#endif
|
#endif
|
||||||
Con_Printf("\n");
|
Con_Printf("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
Con_Printf("^3Networking:^7");
|
Con_Printf("^3Networking:^7");
|
||||||
#ifdef WEBCLIENT
|
#ifdef WEBCLIENT
|
||||||
|
@ -6043,14 +6045,16 @@ static void COM_Version_f (void)
|
||||||
#endif
|
#endif
|
||||||
#if (defined(SUPPORT_ICE)&&defined(HAVE_DTLS)) || defined(FTE_TARGET_WEB)
|
#if (defined(SUPPORT_ICE)&&defined(HAVE_DTLS)) || defined(FTE_TARGET_WEB)
|
||||||
Con_Printf(" WebRTC");
|
Con_Printf(" WebRTC");
|
||||||
|
#elif defined(SUPPORT_ICE)
|
||||||
|
Con_Printf(" ICE");
|
||||||
#endif
|
#endif
|
||||||
#ifdef FTE_TARGET_WEB
|
#ifdef FTE_TARGET_WEB
|
||||||
Con_Printf(" WebSocket/WSS");
|
Con_Printf(" WebSocket/WSS");
|
||||||
#else
|
#else
|
||||||
#if defined(HAVE_TCP)
|
#if defined(HAVE_TCP)
|
||||||
#ifdef TCPCONNECT
|
#ifdef TCPCONNECT
|
||||||
Con_Printf(" TCPConnect");
|
Con_Printf(" TCPConnect");
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
Con_Printf(" ^h(disabled: TCP)");
|
Con_Printf(" ^h(disabled: TCP)");
|
||||||
#endif
|
#endif
|
||||||
|
@ -6060,9 +6064,6 @@ static void COM_Version_f (void)
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_WINSSPI //on windows
|
#ifdef HAVE_WINSSPI //on windows
|
||||||
Con_Printf(" WINSSPI");
|
Con_Printf(" WINSSPI");
|
||||||
#endif
|
|
||||||
#ifdef SUPPORT_ICE
|
|
||||||
Con_Printf(" ICE");
|
|
||||||
#endif
|
#endif
|
||||||
Con_Printf("\n");
|
Con_Printf("\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,11 +201,11 @@ typedef enum {
|
||||||
} sbpacking_t;
|
} sbpacking_t;
|
||||||
typedef struct sizebuf_s
|
typedef struct sizebuf_s
|
||||||
{
|
{
|
||||||
qboolean allowoverflow; // if false, do a Sys_Error
|
|
||||||
qboolean overflowed; // set to true if the buffer size failed
|
|
||||||
qbyte *data;
|
qbyte *data;
|
||||||
int maxsize; //storage size of data
|
int maxsize; //storage size of data
|
||||||
int cursize; //assigned size of data
|
int cursize; //assigned size of data
|
||||||
|
qboolean allowoverflow; // if false, do a Sys_Error
|
||||||
|
qboolean overflowed; // set to true if the buffer size failed
|
||||||
sbpacking_t packing; //required for q3
|
sbpacking_t packing; //required for q3
|
||||||
int currentbit; //ignored for rawbytes
|
int currentbit; //ignored for rawbytes
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
//#define GAME_DOWNLOADSURL NULL //url for the package manger to update from
|
//#define GAME_DOWNLOADSURL NULL //url for the package manger to update from
|
||||||
//#define GAME_DEFAULTCMDS NULL //a string containing the things you want to exec in order to override default.cfg
|
//#define GAME_DEFAULTCMDS NULL //a string containing the things you want to exec in order to override default.cfg
|
||||||
|
|
||||||
|
//#define ENGINE_HAS_ZIP //when defined, the engine is effectively a self-extrating zip with the gamedata zipped onto the end (if it in turn contains nested packages then they should probably be STOREd pk3s)
|
||||||
|
|
||||||
// Allowed renderers... There should ONLY be undefs here (other C files won't be pulled in automatically)
|
// Allowed renderers... There should ONLY be undefs here (other C files won't be pulled in automatically)
|
||||||
//#undef GLQUAKE
|
//#undef GLQUAKE
|
||||||
|
|
|
@ -251,6 +251,9 @@ char *Con_CopyConsole(console_t *con, qboolean nomarkup, qboolean onlyiflink, qb
|
||||||
void Con_Print (const char *txt);
|
void Con_Print (const char *txt);
|
||||||
void Con_CenterPrint(const char *txt);
|
void Con_CenterPrint(const char *txt);
|
||||||
void Con_PrintFlags(const char *text, unsigned int setflags, unsigned int clearflags);
|
void Con_PrintFlags(const char *text, unsigned int setflags, unsigned int clearflags);
|
||||||
|
#ifdef HAVE_CLIENT
|
||||||
|
void Con_HexDump(qbyte *packet, size_t len, size_t badoffset, size_t stride);
|
||||||
|
#endif
|
||||||
void VARGS Con_Printf (const char *fmt, ...) LIKEPRINTF(1);
|
void VARGS Con_Printf (const char *fmt, ...) LIKEPRINTF(1);
|
||||||
void VARGS Con_TPrintf (translation_t text, ...);
|
void VARGS Con_TPrintf (translation_t text, ...);
|
||||||
void VARGS Con_DPrintf (const char *fmt, ...) LIKEPRINTF(1); //developer>=1, for stuff that's probably actually slightly useful
|
void VARGS Con_DPrintf (const char *fmt, ...) LIKEPRINTF(1); //developer>=1, for stuff that's probably actually slightly useful
|
||||||
|
|
|
@ -66,7 +66,7 @@ static char *vidfilenames[] = //list of filenames to check to see if graphics st
|
||||||
/*set some stuff so our regular qw client appears more like hexen2. sv_mintic must be 0.015 to 'fix' the ravenstaff so that its projectiles don't impact upon each other, or even 0.05 to exactly match the hardcoded assumptions in obj_push. There's maps that depend on a low framerate via waterjump framerate-dependance too.*/
|
/*set some stuff so our regular qw client appears more like hexen2. sv_mintic must be 0.015 to 'fix' the ravenstaff so that its projectiles don't impact upon each other, or even 0.05 to exactly match the hardcoded assumptions in obj_push. There's maps that depend on a low framerate via waterjump framerate-dependance too.*/
|
||||||
#define HEX2CFG "//schemes hexen2\n" "set v_gammainverted 1\nset com_parseutf8 -1\nset gl_font gfx/hexen2\nset in_builtinkeymap 0\nset_calc cl_playerclass int (random * 5) + 1\nset cl_forwardspeed 200\nset cl_backspeed 200\ncl_sidespeed 225\nset sv_maxspeed 640\ncl_run 0\nset watervis 1\nset r_lavaalpha 1\nset r_lavastyle -2\nset r_wateralpha 0.5\nset sv_pupglow 1\ngl_shaftlight 0.5\nsv_mintic 0.05\nset r_meshpitch -1\nset r_meshroll -1\nr_sprite_backfacing 1\nset mod_warnmodels 0\nset cl_model_bobbing 1\nsv_sound_watersplash \"misc/hith2o.wav\"\nsv_sound_land \"fx/thngland.wav\"\nset sv_walkpitch 0\n"
|
#define HEX2CFG "//schemes hexen2\n" "set v_gammainverted 1\nset com_parseutf8 -1\nset gl_font gfx/hexen2\nset in_builtinkeymap 0\nset_calc cl_playerclass int (random * 5) + 1\nset cl_forwardspeed 200\nset cl_backspeed 200\ncl_sidespeed 225\nset sv_maxspeed 640\ncl_run 0\nset watervis 1\nset r_lavaalpha 1\nset r_lavastyle -2\nset r_wateralpha 0.5\nset sv_pupglow 1\ngl_shaftlight 0.5\nsv_mintic 0.05\nset r_meshpitch -1\nset r_meshroll -1\nr_sprite_backfacing 1\nset mod_warnmodels 0\nset cl_model_bobbing 1\nsv_sound_watersplash \"misc/hith2o.wav\"\nsv_sound_land \"fx/thngland.wav\"\nset sv_walkpitch 0\n"
|
||||||
/*yay q2!*/
|
/*yay q2!*/
|
||||||
#define Q2CFG "//schemes quake2\n" "set v_gammainverted 1\nset com_parseutf8 0\ncom_gamedirnativecode 1\nset sv_bigcoords 0\nsv_port "STRINGIFY(PORT_Q2SERVER)" "STRINGIFY(PORT_Q2EXSERVER)"\ncl_defaultport "STRINGIFY(PORT_Q2SERVER)"\n" \
|
#define Q2CFG "//schemes quake2\n" "set com_protocolversion "STRINGIFY(PROTOCOL_VERSION_Q2)"\nset v_gammainverted 1\nset com_parseutf8 0\ncom_gamedirnativecode 1\nset sv_bigcoords 0\nsv_port "STRINGIFY(PORT_Q2SERVER)" "STRINGIFY(PORT_Q2EXSERVER)"\ncl_defaultport "STRINGIFY(PORT_Q2SERVER)"\n" \
|
||||||
"set r_replacemodels " IFMINIMAL("","md3 md5mesh")"\n" \
|
"set r_replacemodels " IFMINIMAL("","md3 md5mesh")"\n" \
|
||||||
"set r_glsl_emissive 0\n" /*work around the _glow textures not being meant to glow*/
|
"set r_glsl_emissive 0\n" /*work around the _glow textures not being meant to glow*/
|
||||||
/*Q3's ui doesn't like empty model/headmodel/handicap cvars, even if the gamecode copes*/
|
/*Q3's ui doesn't like empty model/headmodel/handicap cvars, even if the gamecode copes*/
|
||||||
|
@ -1918,6 +1918,51 @@ static void FS_FlushFSHashReally(qboolean domutexes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void QDECL FS_AddFileHashUnsafe(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle)
|
||||||
|
{
|
||||||
|
//threading stuff is fucked.
|
||||||
|
fsbucket_t *old;
|
||||||
|
|
||||||
|
old = Hash_GetInsensitiveBucket(&filesystemhash, fname);
|
||||||
|
|
||||||
|
if (old)
|
||||||
|
{
|
||||||
|
fs_hash_dups++;
|
||||||
|
if (depth >= old->depth)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//remove the old version
|
||||||
|
//FIXME: needs to be atomic. just live with multiple in there.
|
||||||
|
//Hash_RemoveBucket(&filesystemhash, fname, &old->buck);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!filehandle)
|
||||||
|
{
|
||||||
|
int nlen = strlen(fname)+1;
|
||||||
|
int plen = sizeof(*filehandle)+nlen;
|
||||||
|
plen = (plen+fte_alignof(fsbucket_t)-1) & ~(fte_alignof(fsbucket_t)-1);
|
||||||
|
if (!fs_hash_filebuckets || fs_hash_filebuckets->used+plen > fs_hash_filebuckets->total)
|
||||||
|
{
|
||||||
|
void *o = fs_hash_filebuckets;
|
||||||
|
fs_hash_filebuckets = Z_Malloc(65536);
|
||||||
|
fs_hash_filebuckets->total = 65536 - sizeof(*fs_hash_filebuckets);
|
||||||
|
fs_hash_filebuckets->prev = o;
|
||||||
|
}
|
||||||
|
filehandle = (fsbucket_t*)(fs_hash_filebuckets->data+fs_hash_filebuckets->used);
|
||||||
|
fs_hash_filebuckets->used += plen;
|
||||||
|
|
||||||
|
if (!filehandle)
|
||||||
|
return; //eep!
|
||||||
|
memcpy((char*)(filehandle+1), fname, nlen);
|
||||||
|
fname = (char*)(filehandle+1);
|
||||||
|
}
|
||||||
|
filehandle->depth = depth;
|
||||||
|
|
||||||
|
Hash_AddInsensitive(&filesystemhash, fname, pathhandle, &filehandle->buck);
|
||||||
|
fs_hash_files++;
|
||||||
|
}
|
||||||
static void QDECL FS_AddFileHash(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle)
|
static void QDECL FS_AddFileHash(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle)
|
||||||
{
|
{
|
||||||
fsbucket_t *old;
|
fsbucket_t *old;
|
||||||
|
@ -4255,20 +4300,35 @@ static searchpath_t *FS_AddPathHandle(searchpath_t **oldpaths, const char *purep
|
||||||
|
|
||||||
if (flags & (SPF_TEMPORARY|SPF_SERVER))
|
if (flags & (SPF_TEMPORARY|SPF_SERVER))
|
||||||
{
|
{
|
||||||
|
int depth = 1;
|
||||||
|
searchpath_t *s;
|
||||||
//add at end. pureness will reorder if needed.
|
//add at end. pureness will reorder if needed.
|
||||||
link = &com_searchpaths;
|
link = &com_searchpaths;
|
||||||
while(*link)
|
while(*link)
|
||||||
{
|
{
|
||||||
link = &(*link)->next;
|
link = &(*link)->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (com_purepaths)
|
||||||
|
{ //go for the pure paths first.
|
||||||
|
for (s = com_purepaths; s; s = s->nextpure)
|
||||||
|
depth++;
|
||||||
|
}
|
||||||
|
if (fs_puremode < 2)
|
||||||
|
{
|
||||||
|
for (s = com_searchpaths ; s ; s = s->next)
|
||||||
|
depth++;
|
||||||
|
}
|
||||||
*link = search;
|
*link = search;
|
||||||
|
search->handle->BuildHash(search->handle, depth, FS_AddFileHashUnsafe);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
search->next = com_searchpaths;
|
search->next = com_searchpaths;
|
||||||
com_searchpaths = search;
|
com_searchpaths = search;
|
||||||
|
|
||||||
|
com_fschanged = true; //depth values are screwy
|
||||||
}
|
}
|
||||||
com_fschanged = true;
|
|
||||||
|
|
||||||
return search;
|
return search;
|
||||||
}
|
}
|
||||||
|
@ -5190,6 +5250,19 @@ static void FS_ReloadPackFilesFlags(unsigned int reloadflags)
|
||||||
com_base_searchpaths = NULL;
|
com_base_searchpaths = NULL;
|
||||||
gameonly_gamedir = gameonly_homedir = NULL;
|
gameonly_gamedir = gameonly_homedir = NULL;
|
||||||
|
|
||||||
|
#if defined(ENGINE_HAS_ZIP) && defined(PACKAGE_PK3)
|
||||||
|
{
|
||||||
|
searchpathfuncs_t *pak;
|
||||||
|
vfsfile_t *vfs;
|
||||||
|
vfs = VFSOS_Open(com_argv[0], "rb");
|
||||||
|
pak = FSZIP_LoadArchive(vfs, NULL, com_argv[0], com_argv[0], "");
|
||||||
|
if (pak) //logically should have SPF_EXPLICIT set, but that would give it a worse gamedir depth
|
||||||
|
{
|
||||||
|
FS_AddPathHandle(&oldpaths, "", com_argv[0], pak, "", SPF_COPYPROTECTED, reloadflags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_LEGACY) && defined(PACKAGE_PK3)
|
#if defined(HAVE_LEGACY) && defined(PACKAGE_PK3)
|
||||||
{
|
{
|
||||||
searchpathfuncs_t *pak;
|
searchpathfuncs_t *pak;
|
||||||
|
@ -6514,6 +6587,41 @@ static ftemanifest_t *FS_ReadDefaultManifest(char *newbasedir, size_t newbasedir
|
||||||
man->security = MANIFEST_SECURITY_DEFAULT;
|
man->security = MANIFEST_SECURITY_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(ENGINE_HAS_ZIP) && defined(PACKAGE_PK3)
|
||||||
|
if (!man && game == -1)
|
||||||
|
{
|
||||||
|
searchpathfuncs_t *pak;
|
||||||
|
vfsfile_t *vfs;
|
||||||
|
vfs = VFSOS_Open(com_argv[0], "rb");
|
||||||
|
pak = FSZIP_LoadArchive(vfs, NULL, com_argv[0], com_argv[0], "");
|
||||||
|
if (pak)
|
||||||
|
{
|
||||||
|
flocation_t loc;
|
||||||
|
if (pak->FindFile(pak, &loc, "default.fmf", NULL))
|
||||||
|
{
|
||||||
|
f = pak->OpenVFS(pak, &loc, "rb");
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
size_t len = VFS_GETLEN(f);
|
||||||
|
char *fdata = BZ_Malloc(len+1);
|
||||||
|
if (fdata)
|
||||||
|
{
|
||||||
|
VFS_READ(f, fdata, len);
|
||||||
|
fdata[len] = 0;
|
||||||
|
man = FS_Manifest_ReadMem(NULL, NULL, fdata);
|
||||||
|
if (man)
|
||||||
|
man->security = MANIFEST_SECURITY_DEFAULT;
|
||||||
|
BZ_Free(fdata);
|
||||||
|
}
|
||||||
|
VFS_CLOSE(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pak->ClosePath(pak);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
//-basepack is primarily an android feature
|
//-basepack is primarily an android feature
|
||||||
i = COM_CheckParm ("-basepack");
|
i = COM_CheckParm ("-basepack");
|
||||||
while (!man && game == -1 && i && i < com_argc-1)
|
while (!man && game == -1 && i && i < com_argc-1)
|
||||||
|
|
|
@ -2197,7 +2197,7 @@ static qboolean FSZIP_FindEndCentralDirectory(zipfile_t *zip, struct zipinfo *in
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
Con_Printf("zip: unable to find end-of-central-directory\n");
|
Con_Printf("%s: unable to find end-of-central-directory (not a zip?)\n", zip->filename); //usually just not a zip.
|
||||||
else
|
else
|
||||||
|
|
||||||
//now look for a zip64 header.
|
//now look for a zip64 header.
|
||||||
|
@ -2249,13 +2249,13 @@ static qboolean FSZIP_FindEndCentralDirectory(zipfile_t *zip, struct zipinfo *in
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Con_Printf("zip: zip64 end-of-central directory at unknown offset.\n");
|
Con_Printf("%s: zip64 end-of-central directory at unknown offset.\n", zip->filename);
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->diskcount < 1 || info->zip64_centraldirend_disk != info->thisdisk)
|
if (info->diskcount < 1 || info->zip64_centraldirend_disk != info->thisdisk)
|
||||||
{
|
{ //must read the segment with the central directory.
|
||||||
Con_Printf("zip: archive is spanned\n");
|
Con_Printf("%s: archive is spanned\n", zip->filename);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2264,13 +2264,13 @@ static qboolean FSZIP_FindEndCentralDirectory(zipfile_t *zip, struct zipinfo *in
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->thisdisk != info->centraldir_startdisk || info->centraldir_numfiles_disk != info->centraldir_numfiles_all)
|
if (info->thisdisk != info->centraldir_startdisk || info->centraldir_numfiles_disk != info->centraldir_numfiles_all)
|
||||||
{
|
{ //must read the segment with the central directory.
|
||||||
Con_Printf("zip: archive is spanned\n");
|
Con_Printf("%s: archive is spanned\n", zip->filename);
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
if (info->centraldir_compressionmethod || info->centraldir_algid)
|
if (info->centraldir_compressionmethod || info->centraldir_algid)
|
||||||
{
|
{
|
||||||
Con_Printf("zip: encrypted centraldir\n");
|
Con_Printf("%s: encrypted centraldir\n", zip->filename);
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -416,8 +416,7 @@ void Netchan_Setup (unsigned int flags, netchan_t *chan, netadr_t *adr, int qpor
|
||||||
#endif
|
#endif
|
||||||
chan->incoming_unreliable = -1;
|
chan->incoming_unreliable = -1;
|
||||||
|
|
||||||
if (flags&NCF_CLIENT)
|
chan->outgoing_sequence = 1; //so the first one doesn't get dropped.
|
||||||
chan->outgoing_sequence = 1; //so the first one doesn't get dropped.
|
|
||||||
|
|
||||||
if (adr->prot == NP_KEXLAN)
|
if (adr->prot == NP_KEXLAN)
|
||||||
chan->qportsize = 0;
|
chan->qportsize = 0;
|
||||||
|
@ -472,7 +471,11 @@ void Netchan_Setup (unsigned int flags, netchan_t *chan, netadr_t *adr, int qpor
|
||||||
|
|
||||||
chan->message.data = chan->message_buf;
|
chan->message.data = chan->message_buf;
|
||||||
chan->message.allowoverflow = true;
|
chan->message.allowoverflow = true;
|
||||||
chan->message.maxsize = min(chan->mtu_cur, sizeof(chan->message_buf));
|
|
||||||
|
if ((flags&NCF_FRAGABLE) && NET_AddrIsReliable(adr))
|
||||||
|
chan->message.maxsize = sizeof(chan->message_buf); //something big. might as well if its all tcp anyway.
|
||||||
|
else
|
||||||
|
chan->message.maxsize = min(chan->mtu_cur, sizeof(chan->message_buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -504,7 +504,6 @@ static qboolean TURN_AddXorAddressAttrib(sizebuf_t *buf, unsigned int attr, neta
|
||||||
MSG_WriteByte(buf, ((qbyte*)&to->address)[aofs+i] ^ (buf->data+4)[i]);
|
MSG_WriteByte(buf, ((qbyte*)&to->address)[aofs+i] ^ (buf->data+4)[i]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
void Con_HexDump(qbyte *packet, size_t len, size_t badoffset);
|
|
||||||
static qboolean TURN_AddAuth(sizebuf_t *buf, struct iceserver_s *srv)
|
static qboolean TURN_AddAuth(sizebuf_t *buf, struct iceserver_s *srv)
|
||||||
{ //adds auth info to a stun packet
|
{ //adds auth info to a stun packet
|
||||||
unsigned short len;
|
unsigned short len;
|
||||||
|
|
|
@ -206,6 +206,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#define C2M_MASTER_REQUEST 'c'
|
#define C2M_MASTER_REQUEST 'c'
|
||||||
#define M2C_MASTER_REPLY 'd' // + \n + qw server port list
|
#define M2C_MASTER_REPLY 'd' // + \n + qw server port list
|
||||||
|
|
||||||
|
//for S2C 'status' packets.
|
||||||
|
#define STATUS_OLDSTYLE 0 //equivelent to STATUS_SERVERINFO|STATUS_PLAYERS
|
||||||
|
#define STATUS_SERVERINFO 1
|
||||||
|
#define STATUS_PLAYERS 2
|
||||||
|
#define STATUS_SPECTATORS 4
|
||||||
|
#define STATUS_SPECTATORS_AS_PLAYERS 8 //for ASE - change only frags: show as "S"
|
||||||
|
#define STATUS_SHOWTEAMS 16
|
||||||
|
#define STATUS_QTVLIST 32 //qtv destid "name" "streamid@host:port" numviewers
|
||||||
|
#define STATUS_LOGININFO 64
|
||||||
|
|
||||||
//==================
|
//==================
|
||||||
// note that there are some defs.qc that mirror to these numbers
|
// note that there are some defs.qc that mirror to these numbers
|
||||||
// also related to svc_strings[] in cl_parse
|
// also related to svc_strings[] in cl_parse
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "quakedef.h"
|
#include "quakedef.h"
|
||||||
|
#include <wctype.h>
|
||||||
|
|
||||||
//#define COLOURMISSINGSTRINGS //for english people to more easily see what's not translatable (text still white)
|
//#define COLOURMISSINGSTRINGS //for english people to more easily see what's not translatable (text still white)
|
||||||
//#define COLOURUNTRANSLATEDSTRINGS //show empty translations as alt-text versions of the original string
|
//#define COLOURUNTRANSLATEDSTRINGS //show empty translations as alt-text versions of the original string
|
||||||
|
@ -27,8 +28,9 @@ cvar_t language = CVARAFCD("lang", sys_language, "prvm_language", CVAR_USERINFO|
|
||||||
|
|
||||||
static void Filter_Reload_f(void)
|
static void Filter_Reload_f(void)
|
||||||
{
|
{
|
||||||
|
char *file = FS_MallocFile("filter.txt", FS_ROOT, NULL);
|
||||||
// FilterInit(
|
FilterInit(file?file:"");
|
||||||
|
FS_FreeFile(file);
|
||||||
}
|
}
|
||||||
void TranslateInit(void)
|
void TranslateInit(void)
|
||||||
{
|
{
|
||||||
|
@ -630,6 +632,7 @@ void TL_Reformat(int language, char *out, size_t outsize, size_t numargs, const
|
||||||
const char *fmt;
|
const char *fmt;
|
||||||
const char *a;
|
const char *a;
|
||||||
size_t alen;
|
size_t alen;
|
||||||
|
unsigned int lastindex = 0;
|
||||||
|
|
||||||
fmt = (numargs>0&&arg[0])?arg[0]:"";
|
fmt = (numargs>0&&arg[0])?arg[0]:"";
|
||||||
fmt = TL_Translate(language, fmt);
|
fmt = TL_Translate(language, fmt);
|
||||||
|
@ -645,8 +648,11 @@ void TL_Reformat(int language, char *out, size_t outsize, size_t numargs, const
|
||||||
*out++ = '}', fmt+=2, outsize--;
|
*out++ = '}', fmt+=2, outsize--;
|
||||||
else if (*fmt == '{')
|
else if (*fmt == '{')
|
||||||
{
|
{
|
||||||
unsigned int index = strtoul(fmt+1, (char**)&fmt, 10)+1;
|
const char *idxstr = fmt+1;
|
||||||
|
unsigned int index = strtoul(idxstr, (char**)&fmt, 10)+1;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
if (idxstr == fmt) //when no index value was specified, just go for the next one
|
||||||
|
index = lastindex+1;
|
||||||
if (*fmt == ',')
|
if (*fmt == ',')
|
||||||
size = strtol(fmt+1, (char**)&fmt, 10);
|
size = strtol(fmt+1, (char**)&fmt, 10);
|
||||||
if (*fmt == ':')
|
if (*fmt == ':')
|
||||||
|
@ -665,6 +671,8 @@ void TL_Reformat(int language, char *out, size_t outsize, size_t numargs, const
|
||||||
else
|
else
|
||||||
a = TL_Translate(language, arg[index]);
|
a = TL_Translate(language, arg[index]);
|
||||||
|
|
||||||
|
lastindex = index;
|
||||||
|
|
||||||
alen = strlen(a);
|
alen = strlen(a);
|
||||||
if (alen > outsize)
|
if (alen > outsize)
|
||||||
alen = outsize;
|
alen = outsize;
|
||||||
|
@ -708,8 +716,8 @@ static void FilterPurge(void)
|
||||||
}
|
}
|
||||||
static void FilterInit(const char *file)
|
static void FilterInit(const char *file)
|
||||||
{
|
{
|
||||||
qbyte *tempmem = malloc(strlen(file)+1);
|
qbyte *tempmemstart = malloc(strlen(file)+1);
|
||||||
qbyte *tempmemstart = tempmem;
|
qbyte *tempmem = tempmemstart;
|
||||||
const char **words;
|
const char **words;
|
||||||
size_t count = 1, i, l;
|
size_t count = 1, i, l;
|
||||||
size_t bytes;
|
size_t bytes;
|
||||||
|
@ -737,28 +745,29 @@ static void FilterInit(const char *file)
|
||||||
*tempmem++ = tolower(*c);
|
*tempmem++ = tolower(*c);
|
||||||
}
|
}
|
||||||
*tempmem++ = 0;
|
*tempmem++ = 0;
|
||||||
count++;
|
if (*words[count])
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
qsort(words, count, sizeof(words[0]), FilterCompareWords); //sort by lead byte... and longest first...
|
qsort(words, count, sizeof(words[0]), FilterCompareWords); //sort by lead byte... and longest first...
|
||||||
i = 0;
|
i = 0;
|
||||||
for (i = 0, bytes = 0; i < count; i++)
|
for (i = 0, bytes = 0; i < count; i++)
|
||||||
bytes += strlen(words[i]);
|
bytes += strlen(words[i])+1;
|
||||||
bytes += countof(filter);
|
bytes += countof(filter);
|
||||||
filtermem = malloc(bytes);
|
filtermem = tempmem = malloc(bytes);
|
||||||
|
|
||||||
for (l = countof(filter), i = 0; l-- > 0; )
|
for (l = countof(filter), i = 0; l-- > 0; )
|
||||||
{
|
{
|
||||||
if (i < count && words[i][0] == l)
|
if (i < count && words[i][0] == l)
|
||||||
{
|
{
|
||||||
filter[l] = filtermem;
|
filter[l] = tempmem;
|
||||||
while (i < count && *words[i] == l)
|
while (i < count && *words[i] == l)
|
||||||
{ //second copy... urgh. can forget the first char and replace with a length.
|
{ //second copy... urgh. can forget the first char and replace with a length.
|
||||||
*filtermem++ = strlen(words[i]+1);
|
*tempmem++ = strlen(words[i]+1);
|
||||||
memcpy(filtermem, words[i]+1, filtermem[-1]); //just the text, no null needed. tighly packed.
|
memcpy(tempmem, words[i]+1, tempmem[-1]); //just the text, no null needed. tighly packed.
|
||||||
filtermem += filtermem[-1];
|
tempmem += tempmem[-1];
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
*filtermem++ = 0;
|
*tempmem++ = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
filter[l] = NULL;
|
filter[l] = NULL;
|
||||||
|
@ -772,6 +781,8 @@ char *FilterObsceneString(const qbyte *in, char *outbuf, size_t bufsize)
|
||||||
char *ret = outbuf;
|
char *ret = outbuf;
|
||||||
if (strlen(in) >= bufsize)
|
if (strlen(in) >= bufsize)
|
||||||
Sys_Error("output buffer too small!");
|
Sys_Error("output buffer too small!");
|
||||||
|
if (!filtermem)
|
||||||
|
Filter_Reload_f();
|
||||||
restart:
|
restart:
|
||||||
while (*in)
|
while (*in)
|
||||||
{
|
{
|
||||||
|
@ -827,3 +838,70 @@ restart:
|
||||||
*outbuf++ = 0; //make sure its null terminated.
|
*outbuf++ = 0; //make sure its null terminated.
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
void TL_FilterObsceneCCStringInplace(conchar_t *in, conchar_t *end)
|
||||||
|
{ //FIXME: filters are meant to be utf-8, but our strings are not.
|
||||||
|
// conchar_t *start = in;
|
||||||
|
conchar_t *next;
|
||||||
|
if (!filtermem)
|
||||||
|
Filter_Reload_f();
|
||||||
|
restart:
|
||||||
|
while(in < end)
|
||||||
|
{
|
||||||
|
unsigned int c, cflags;
|
||||||
|
next = Font_Decode(in, &cflags, &c);
|
||||||
|
c = towlower(c);
|
||||||
|
if (c < 255 && filter[c])
|
||||||
|
{
|
||||||
|
qbyte *m = filter[c];
|
||||||
|
while (*m)
|
||||||
|
{ //for each word starting with this letter...
|
||||||
|
conchar_t *test = next;
|
||||||
|
qbyte len = *m;
|
||||||
|
const qbyte *match = m+1;
|
||||||
|
int err;
|
||||||
|
m += 1+len;
|
||||||
|
while(*match && test < end)
|
||||||
|
{ //don't let 'foo bar' through when 'foobar' is a bad word.
|
||||||
|
test = Font_Decode(test, &cflags, &c);
|
||||||
|
if (whiteish(c))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (towlower(c) == utf8_decode(&err, match, (char const**)&match))
|
||||||
|
{
|
||||||
|
if (--len == 0)
|
||||||
|
{ //a match.
|
||||||
|
|
||||||
|
//peek the next and reject it if we're still mid word
|
||||||
|
if (test < end)
|
||||||
|
Font_Decode(test, &cflags, &c);
|
||||||
|
else
|
||||||
|
c = 0;
|
||||||
|
if (c && !whiteish(c))
|
||||||
|
break; //assassinate!
|
||||||
|
|
||||||
|
//okay, not mid-word, obuscate the swears.
|
||||||
|
while (test > in)
|
||||||
|
{ //censor it.
|
||||||
|
if (*in & CON_LONGCHAR && !(*in & CON_RICHFORECOLOUR))
|
||||||
|
*in = CON_LONGCHAR; //no other flags here.
|
||||||
|
else
|
||||||
|
//*in = "#@*$"[(in-start)&3] | CON_WHITEMASK;
|
||||||
|
*in = 0x26a0 | CON_WHITEMASK | (*in&CON_HIDDEN);
|
||||||
|
in++;
|
||||||
|
}
|
||||||
|
goto restart; //double breaks suck
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(; next < end; next = Font_Decode(next, &cflags, &c))
|
||||||
|
{
|
||||||
|
if (whiteish(c))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
in = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -21,4 +21,6 @@ extern cvar_t language;
|
||||||
#define localtext(t) PO_GetText(languages[com_language].po, t)
|
#define localtext(t) PO_GetText(languages[com_language].po, t)
|
||||||
int TL_FindLanguage(const char *lang);
|
int TL_FindLanguage(const char *lang);
|
||||||
|
|
||||||
|
void TL_FilterObsceneCCStringInplace(conchar_t *in, conchar_t *end);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1453,7 +1453,7 @@ qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel)
|
||||||
// VectorMA(vec3_origin, 0.5, shadelight, ambientlight);
|
// VectorMA(vec3_origin, 0.5, shadelight, ambientlight);
|
||||||
// VectorCopy(ambientlight, shadelight);
|
// VectorCopy(ambientlight, shadelight);
|
||||||
|
|
||||||
if (!r_vertexdlights.ival && r_dynamic.ival > 0)
|
if (!r_vertexdlights.ival && r_dlightlightmaps)
|
||||||
{
|
{
|
||||||
float *org = e->origin;
|
float *org = e->origin;
|
||||||
if (e->flags & RF_WEAPONMODEL)
|
if (e->flags & RF_WEAPONMODEL)
|
||||||
|
@ -1500,7 +1500,7 @@ qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!r_vertexdlights.ival && r_dynamic.ival > 0)
|
if (!r_vertexdlights.ival && r_dlightlightmaps)
|
||||||
{
|
{
|
||||||
float *org = e->origin;
|
float *org = e->origin;
|
||||||
if (e->flags & RF_WEAPONMODEL)
|
if (e->flags & RF_WEAPONMODEL)
|
||||||
|
|
|
@ -387,13 +387,12 @@ void R_BloomBlend (texid_t source, int x, int y, int w, int h)
|
||||||
|
|
||||||
intex = pingtex[0][i];
|
intex = pingtex[0][i];
|
||||||
}
|
}
|
||||||
r_worldentity.glowmod[0] = 0;
|
|
||||||
r_worldentity.glowmod[1] = 0;
|
|
||||||
|
|
||||||
if (R2D_Flush)
|
if (R2D_Flush)
|
||||||
R2D_Flush();
|
R2D_Flush();
|
||||||
|
|
||||||
GL_Set2D(false);
|
r_worldentity.glowmod[0] = 0;
|
||||||
|
r_worldentity.glowmod[1] = 0;
|
||||||
|
|
||||||
bloomfinal->defaulttextures->base = intex;
|
bloomfinal->defaulttextures->base = intex;
|
||||||
bloomfinal->defaulttextures->loweroverlay = (i >= 2)?pingtex[0][i-2]:0;
|
bloomfinal->defaulttextures->loweroverlay = (i >= 2)?pingtex[0][i-2]:0;
|
||||||
|
@ -402,6 +401,7 @@ void R_BloomBlend (texid_t source, int x, int y, int w, int h)
|
||||||
/*combine them onto the screen*/
|
/*combine them onto the screen*/
|
||||||
GLBE_FBO_Pop(oldfbo);
|
GLBE_FBO_Pop(oldfbo);
|
||||||
GLBE_FBO_Sources(source, r_nulltex);
|
GLBE_FBO_Sources(source, r_nulltex);
|
||||||
|
GL_Set2D(false);
|
||||||
R2D_ScalePic(x, y + h, w, -h, bloomfinal);
|
R2D_ScalePic(x, y + h, w, -h, bloomfinal);
|
||||||
}
|
}
|
||||||
void R_BloomShutdown(void)
|
void R_BloomShutdown(void)
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
fmt=k -- quake-style raster font with koi8-u codepage (apparently its somewhat common in the quake community)
|
fmt=k -- quake-style raster font with koi8-u codepage (apparently its somewhat common in the quake community)
|
||||||
fmt=h -- halflife-style all-on-one-line raster font
|
fmt=h -- halflife-style all-on-one-line raster font
|
||||||
aspect=0.5 -- raster font is squished horizontally
|
aspect=0.5 -- raster font is squished horizontally
|
||||||
style -- list of modifiets for inexact family font matching for system fonts
|
style -- list of modifiers for inexact family font matching for system fonts
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void Font_Init(void);
|
void Font_Init(void);
|
||||||
|
|
|
@ -3596,8 +3596,8 @@ static void Mod_LoadMiptex(model_t *loadmodel, texture_t *tx, miptex_t *mt, int
|
||||||
mt->offsets[3] == mt->offsets[2]+(mt->width>>2)*(mt->height>>2))
|
mt->offsets[3] == mt->offsets[2]+(mt->width>>2)*(mt->height>>2))
|
||||||
{
|
{
|
||||||
extofs = mt->offsets[3]+(mt->width>>3)*(mt->height>>3);
|
extofs = mt->offsets[3]+(mt->width>>3)*(mt->height>>3);
|
||||||
if (loadmodel->fromgame == fg_halflife && *(short*)(ptr + mt->offsets[3] + (mt->width>>3)*(mt->height>>3)) == 256)
|
if (extofs + 2+256*3 <= miptexsize && *(short*)(ptr + extofs) == 256)
|
||||||
{
|
{ //space for a halflife paletted texture, with the right signature (note: usually padded).
|
||||||
pal = ptr + extofs+2;
|
pal = ptr + extofs+2;
|
||||||
extofs += 2+256*3;
|
extofs += 2+256*3;
|
||||||
}
|
}
|
||||||
|
@ -4314,6 +4314,59 @@ static qboolean Mod_LoadFaces (model_t *loadmodel, bspx_header_t *bspx, qbyte *m
|
||||||
loadmodel->surfaces = out;
|
loadmodel->surfaces = out;
|
||||||
loadmodel->numsurfaces = count;
|
loadmodel->numsurfaces = count;
|
||||||
|
|
||||||
|
//dodgy guesses time...
|
||||||
|
if (loadmodel->fromgame == fg_quake //some halflife maps are misidentified as quake...
|
||||||
|
&& loadmodel->submodels[0].headnode[3] /*these do have crouch hulls. this'll save a LOT of modulo expense*/
|
||||||
|
&& subbsp == sb_none/*don't bother with bsp2... maybe halflife will get a remaster that uses/supports it?*/
|
||||||
|
&& ins && count /*yeah... just in case*/
|
||||||
|
&& !overrides.shifts /*would break expectations. fix your maps.*/
|
||||||
|
&& lightlump->filelen%3==0 /*hlbsp has rgb lighting so MUST be a multiple of 3*/
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (surfnum=0; surfnum<count; surfnum++)
|
||||||
|
{
|
||||||
|
lofs = LittleLong(ins[surfnum].lightofs);
|
||||||
|
if (lofs%3)
|
||||||
|
break; //not a byte offset within rgb data
|
||||||
|
if (lofs != (unsigned int)-1 && ins[surfnum].styles[0]!=255)
|
||||||
|
{
|
||||||
|
//count styles
|
||||||
|
for (i = 0; i < countof(ins[surfnum].styles); i++)
|
||||||
|
if (ins[surfnum].styles[i] == 255)
|
||||||
|
break;
|
||||||
|
if (!i)
|
||||||
|
continue; //no lightmap data here...
|
||||||
|
|
||||||
|
tn = LittleShort (ins->texinfo);
|
||||||
|
if (tn < 0 || tn >= loadmodel->numtexinfo)
|
||||||
|
break;
|
||||||
|
out->texinfo = loadmodel->texinfo + tn;
|
||||||
|
out->firstedge = LittleLong(ins->firstedge);
|
||||||
|
out->numedges = LittleShort(ins->numedges);
|
||||||
|
out->lmshift = lmshift;
|
||||||
|
CalcSurfaceExtents (loadmodel, out);
|
||||||
|
i *= (out->extents[0]>>out->lmshift)+1; //width
|
||||||
|
i *= (out->extents[1]>>out->lmshift)+1; //height
|
||||||
|
i *= 3; //for rgb
|
||||||
|
//'i' is now the size of our lightmap data, in bytes. phew.
|
||||||
|
lend = lofs + i;
|
||||||
|
|
||||||
|
//we now have a reference surface.
|
||||||
|
for (surfnum++; surfnum<count; surfnum++)
|
||||||
|
{
|
||||||
|
unsigned int checklofs = LittleLong(ins[surfnum].lightofs);
|
||||||
|
if (checklofs%3)
|
||||||
|
break; //can't be hl
|
||||||
|
if (checklofs > lofs && checklofs < lend)
|
||||||
|
break; //started before reference surf ended... reference surface can't have been using RGB lighting. so not a mislabled hlbsp.
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (surfnum==count)
|
||||||
|
loadmodel->fromgame = fg_halflife;
|
||||||
|
}
|
||||||
|
|
||||||
Mod_LoadVertexNormals(loadmodel, bspx, mod_base, NULL);
|
Mod_LoadVertexNormals(loadmodel, bspx, mod_base, NULL);
|
||||||
Mod_LoadLighting (loadmodel, bspx, mod_base, lightlump, false, &overrides, subbsp);
|
Mod_LoadLighting (loadmodel, bspx, mod_base, lightlump, false, &overrides, subbsp);
|
||||||
|
|
||||||
|
|
|
@ -735,7 +735,7 @@ void R_PushDlights (void)
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (r_dynamic.ival <= 0|| !r_worldentity.model)
|
if (!r_dlightlightmaps || !r_worldentity.model)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (r_worldentity.model->loadstate != MLS_LOADED)
|
if (r_worldentity.model->loadstate != MLS_LOADED)
|
||||||
|
|
|
@ -2210,6 +2210,11 @@ static void Shader_LoadGeneric(sgeneric_t *g, int qrtype)
|
||||||
if (strchr(basicname, '/') || strchr(basicname, '.'))
|
if (strchr(basicname, '/') || strchr(basicname, '.'))
|
||||||
{ //explicit path
|
{ //explicit path
|
||||||
FS_LoadFile(basicname, &file);
|
FS_LoadFile(basicname, &file);
|
||||||
|
if (!file)
|
||||||
|
{ //well that failed. try fixing up the extension in case they omitted that.
|
||||||
|
Q_snprintfz(blobname, sizeof(blobname), COM_SkipPath(sh_config.progpath), basicname);
|
||||||
|
FS_LoadFile(blobname, &file);
|
||||||
|
}
|
||||||
*blobname = 0;
|
*blobname = 0;
|
||||||
}
|
}
|
||||||
else if (ruleset_allow_shaders.ival)
|
else if (ruleset_allow_shaders.ival)
|
||||||
|
|
|
@ -3847,7 +3847,7 @@ void Sh_PreGenerateLights(void)
|
||||||
{
|
{
|
||||||
r_shadow_realtime_world_lightmaps.value = 1;
|
r_shadow_realtime_world_lightmaps.value = 1;
|
||||||
if (!r_shadow_realtime_world_importlightentitiesfrommap.ival)
|
if (!r_shadow_realtime_world_importlightentitiesfrommap.ival)
|
||||||
Con_Printf(CON_WARNING "No lights detected in map.\n");
|
Con_Printf(CON_WARNING "No lights detected in map, ^[[and importing is disabled]\\type\\r_shadow_realtime_world_importlightentitiesfrommap 1^].\n");
|
||||||
else
|
else
|
||||||
Con_DPrintf("No lights detected in map.\n");
|
Con_DPrintf("No lights detected in map.\n");
|
||||||
}
|
}
|
||||||
|
@ -4098,7 +4098,8 @@ void Sh_DrawLights(qbyte *vis)
|
||||||
r_shadow_realtime_world_importlightentitiesfrommap.modified ||
|
r_shadow_realtime_world_importlightentitiesfrommap.modified ||
|
||||||
r_shadow_realtime_dlight.modified ||
|
r_shadow_realtime_dlight.modified ||
|
||||||
r_shadow_realtime_dlight_shadows.modified ||
|
r_shadow_realtime_dlight_shadows.modified ||
|
||||||
r_shadow_shadowmapping.modified || r_shadows.modified)
|
r_shadow_shadowmapping.modified || r_shadows.modified ||
|
||||||
|
r_shadow_raytrace.modified)
|
||||||
{
|
{
|
||||||
r_shadow_realtime_world.modified =
|
r_shadow_realtime_world.modified =
|
||||||
r_shadow_realtime_world_shadows.modified =
|
r_shadow_realtime_world_shadows.modified =
|
||||||
|
@ -4106,6 +4107,7 @@ void Sh_DrawLights(qbyte *vis)
|
||||||
r_shadow_realtime_dlight_shadows.modified =
|
r_shadow_realtime_dlight_shadows.modified =
|
||||||
r_shadow_shadowmapping.modified =
|
r_shadow_shadowmapping.modified =
|
||||||
r_shadows.modified =
|
r_shadows.modified =
|
||||||
|
r_shadow_raytrace.modified =
|
||||||
false;
|
false;
|
||||||
Sh_CheckSettings();
|
Sh_CheckSettings();
|
||||||
//make sure the lighting is reloaded
|
//make sure the lighting is reloaded
|
||||||
|
@ -4117,7 +4119,7 @@ void Sh_DrawLights(qbyte *vis)
|
||||||
|
|
||||||
ignoreflags = (r_shadow_realtime_world.ival?LFLAG_REALTIMEMODE:0)
|
ignoreflags = (r_shadow_realtime_world.ival?LFLAG_REALTIMEMODE:0)
|
||||||
| (r_shadow_realtime_dlight.ival?LFLAG_NORMALMODE:0);
|
| (r_shadow_realtime_dlight.ival?LFLAG_NORMALMODE:0);
|
||||||
if (r_dynamic.ival == -1 && r_dynamic.value > 0)
|
if (!r_dlightlightmaps)
|
||||||
ignoreflags |= LFLAG_LIGHTMAP; //if we're using scenecache then we cannot use lightmap hacks for dlights, so draw them via rtlight code instead.
|
ignoreflags |= LFLAG_LIGHTMAP; //if we're using scenecache then we cannot use lightmap hacks for dlights, so draw them via rtlight code instead.
|
||||||
if (!ignoreflags)
|
if (!ignoreflags)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -10842,10 +10842,10 @@ static void QCBUILTIN PF_setpause(pubprogfuncs_t *prinst, struct globalvars_s *p
|
||||||
G_FLOAT(OFS_RETURN) = !!(sv.paused&PAUSE_EXPLICIT);
|
G_FLOAT(OFS_RETURN) = !!(sv.paused&PAUSE_EXPLICIT);
|
||||||
if (sv.paused != pause)
|
if (sv.paused != pause)
|
||||||
{
|
{
|
||||||
if (pause&PAUSE_EXPLICIT)
|
// if (pause&PAUSE_EXPLICIT)
|
||||||
SV_BroadcastTPrintf (PRINT_HIGH, "game paused\n");
|
// SV_BroadcastTPrintf (PRINT_HIGH, "game paused\n");
|
||||||
else
|
// else
|
||||||
SV_BroadcastTPrintf (PRINT_HIGH, "game unpaused\n");
|
// SV_BroadcastTPrintf (PRINT_HIGH, "game unpaused\n");
|
||||||
|
|
||||||
sv.paused = pause;
|
sv.paused = pause;
|
||||||
sv.pausedstart = Sys_DoubleTime();
|
sv.pausedstart = Sys_DoubleTime();
|
||||||
|
@ -11336,20 +11336,22 @@ static BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
||||||
#ifdef QCGC
|
#ifdef QCGC
|
||||||
{"findradius_list", PF_findradius_list, 0, 0, 0, 0, D("entity*(vector org, float rad, __out int foundcount, int sort=0)", "Finds all entities linked with a bbox within a distance of the 'org' specified, returning the list as a temp-array (world signifies the end). Unlike findradius, sv_gameplayfix_blowupfallenzombies is ignored (use FL_FINDABLE_NONSOLID instead), while sv_gameplayfix_findradiusdistancetobox and dpcompat_findradiusarealinks are force-enabled. The resulting buffer will automatically be cleaned up by the engine and does not need to be freed.")},
|
{"findradius_list", PF_findradius_list, 0, 0, 0, 0, D("entity*(vector org, float rad, __out int foundcount, int sort=0)", "Finds all entities linked with a bbox within a distance of the 'org' specified, returning the list as a temp-array (world signifies the end). Unlike findradius, sv_gameplayfix_blowupfallenzombies is ignored (use FL_FINDABLE_NONSOLID instead), while sv_gameplayfix_findradiusdistancetobox and dpcompat_findradiusarealinks are force-enabled. The resulting buffer will automatically be cleaned up by the engine and does not need to be freed.")},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//both bprint and sprint accept different arguments in QW vs NQ/H2
|
//both bprint and sprint accept different arguments in QW vs NQ/H2
|
||||||
{"bprint", PF_bprint, 23, 0, 23, 0, D("void(string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7, optional string s8)", "NQ: Concatenates all arguments, and prints the messsage on the console of all connected clients.")},
|
{"bprint", PF_bprint, 23, 0, 23, 0, D("void(string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7, optional string s8)", "NQ: Concatenates all arguments, and prints the messsage on the console of all connected clients.")},
|
||||||
{"bprint", PF_bprint, 0, 23, 0, 0, D("void(float msglvl, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7)", "QW: Concatenates all string arguments, and prints the messsage on the console of only all clients who's 'msg' infokey is set lower or equal to the supplied 'msglvl' argument.")},
|
|
||||||
{"sprint", PF_sprint, 24, 0, 24, 0, D("void(entity client, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7)", "NQ: Concatenates all string arguments, and prints the messsage on the named client's console")},
|
{"sprint", PF_sprint, 24, 0, 24, 0, D("void(entity client, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7)", "NQ: Concatenates all string arguments, and prints the messsage on the named client's console")},
|
||||||
|
#ifdef HAVE_LEGACY //see below
|
||||||
|
{"dprint", PF_dprint, 25, 0, 25, 0, D("void(string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7, optional string s8)", "NQ: Prints the given message on the server's console, but only if the developer cvar is set. Arguments will be concatenated into a single message.")},
|
||||||
|
#endif
|
||||||
{"sprint", PF_sprint, 0, 24, 0, 0, D("void(entity client, float msglvl, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6)", "QW: Concatenates all string arguments, and prints the messsage on the named client's console, but only if that client's 'msg' infokey is set lower or equal to the supplied 'msglvl' argument.")},
|
{"sprint", PF_sprint, 0, 24, 0, 0, D("void(entity client, float msglvl, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6)", "QW: Concatenates all string arguments, and prints the messsage on the named client's console, but only if that client's 'msg' infokey is set lower or equal to the supplied 'msglvl' argument.")},
|
||||||
|
{"bprint", PF_bprint, 0, 23, 0, 0, D("void(float msglvl, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7)", "QW: Concatenates all string arguments, and prints the messsage on the console of only all clients who's 'msg' infokey is set lower or equal to the supplied 'msglvl' argument.")},
|
||||||
#ifdef HAVE_LEGACY
|
#ifdef HAVE_LEGACY //these have subtly different behaviour, and are implemented using different internal builtins, which is a bit weird in the extensions file. documentation is documentation.
|
||||||
//these have subtly different behaviour, and are implemented using different internal builtins, which is a bit weird in the extensions file. documentation is documentation.
|
{"dprint", PF_print, 0, 25, 0, 0, D("void(string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7, optional string s8)", "QW: Unconditionally prints the given message on the server's console. Arguments will be concatenated into a single message.")},
|
||||||
{"dprint", PF_dprint, 25, 0, 25, 0, D("void(string s, ...)", "NQ: Prints the given message on the server's console, but only if the developer cvar is set. Arguments will be concatenated into a single message.")},
|
|
||||||
{"dprint", PF_print, 0, 25, 0, 0, D("void(string s, ...)", "QW: Unconditionally prints the given message on the server's console. Arguments will be concatenated into a single message.")},
|
|
||||||
#else
|
#else
|
||||||
//going forward, we have print and dprint
|
//going forward, we have print and dprint
|
||||||
{"dprint", PF_dprint, 25, 25, 25, 0, D("void(string s, ...)", "NQ: Prints the given message on the server's console, but only if the developer cvar is set. Arguments will be concatenated into a single message.")},
|
{"dprint", PF_dprint, 25, 25, 25, 0, D("void(string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7, optional string s8)", "Prints the given message on the server's console, but only if the developer cvar is set. Additional arguments will be concatenated into a single message. Use the print builtin if you want to print regardless of the developer builtin.")},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{"ftos", PF_ftos, 26, 26, 26, 0, D("string(float val)", "Returns a tempstring containing a representation of the given float. Precision depends upon engine.")},
|
{"ftos", PF_ftos, 26, 26, 26, 0, D("string(float val)", "Returns a tempstring containing a representation of the given float. Precision depends upon engine.")},
|
||||||
{"vtos", PF_vtos, 27, 27, 27, 0, D("string(vector val)", "Returns a tempstring containing a representation of the given vector. Precision depends upon engine.")},
|
{"vtos", PF_vtos, 27, 27, 27, 0, D("string(vector val)", "Returns a tempstring containing a representation of the given vector. Precision depends upon engine.")},
|
||||||
{"coredump", PF_coredump, 28, 28, 28, 0, D("void()", "Writes out a coredump. This contains stack, globals, and field info for all ents. This can be handy for debugging.")},
|
{"coredump", PF_coredump, 28, 28, 28, 0, D("void()", "Writes out a coredump. This contains stack, globals, and field info for all ents. This can be handy for debugging.")},
|
||||||
|
@ -11408,9 +11410,9 @@ static BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
||||||
{"bwriteentity", PF_qtBroadcast_WriteEntity, 0, 0, 0, 0, D("void(entity val)", NULL), true}, //66
|
{"bwriteentity", PF_qtBroadcast_WriteEntity, 0, 0, 0, 0, D("void(entity val)", NULL), true}, //66
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{"sin", PF_Sin, 0, 0, 62, 60, D("float(float angle)", "Forgive me father, for I have trigonometry homework.")}, //60
|
{"sin", PF_Sin, 0, 0, 62, 60, D("float(float angle)", "Forgive me father, for I have trigonometry homework. Uses radians.")}, //60
|
||||||
{"cos", PF_Cos, 0, 0, 61, 61, D("float(float angle)", "Just cos.")}, //61
|
{"cos", PF_Cos, 0, 0, 61, 61, D("float(float angle)", "Just cos. Uses radians.")}, //61
|
||||||
{"sqrt", PF_Sqrt, 0, 0, 84, 62, D("float(float value)", "Square Root. Use pow")}, //62
|
{"sqrt", PF_Sqrt, 0, 0, 84, 62, D("float(float value)", "Square Root. Use pow for other exponents.")}, //62
|
||||||
{"modulo", PF_mod, 0, 0, 0, 0, D("float(float dividend, float divisor)", "Returns the remainder of a division, so divisor must not be 0. fractional values will give different results... Or just use the % operator.")},
|
{"modulo", PF_mod, 0, 0, 0, 0, D("float(float dividend, float divisor)", "Returns the remainder of a division, so divisor must not be 0. fractional values will give different results... Or just use the % operator.")},
|
||||||
|
|
||||||
{"changepitch", PF_changepitch, 0, 0, 0, 63, "void(entity ent)"},
|
{"changepitch", PF_changepitch, 0, 0, 0, 63, "void(entity ent)"},
|
||||||
|
|
|
@ -1087,6 +1087,7 @@ extern cvar_t sv_mintic, sv_maxtic, sv_limittics;
|
||||||
extern cvar_t sv_maxspeed;
|
extern cvar_t sv_maxspeed;
|
||||||
extern cvar_t sv_antilag;
|
extern cvar_t sv_antilag;
|
||||||
extern cvar_t sv_antilag_frac;
|
extern cvar_t sv_antilag_frac;
|
||||||
|
extern cvar_t sv_nqplayerphysics;
|
||||||
|
|
||||||
void SV_Master_ReResolve(void);
|
void SV_Master_ReResolve(void);
|
||||||
void SV_Master_Shutdown(void);
|
void SV_Master_Shutdown(void);
|
||||||
|
|
|
@ -1383,9 +1383,13 @@ void SSV_ReadFromControlServer(void)
|
||||||
|
|
||||||
case ccmd_setcvar:
|
case ccmd_setcvar:
|
||||||
{
|
{
|
||||||
cvar_t *var = Cvar_FindVar(MSG_ReadString());
|
char cvarname[256];
|
||||||
|
cvar_t *var = Cvar_FindVar(MSG_ReadStringBuffer(cvarname,sizeof(cvarname)));
|
||||||
const char *val = MSG_ReadString();
|
const char *val = MSG_ReadString();
|
||||||
Con_DPrintf("Setting cvar \"%s\" to \"%s\"\n", var?var->name:"UNKNOWN", val);
|
if (var)
|
||||||
|
Con_DPrintf("Setting cvar \"%s\" to \"%s\"\n", var->name, val);
|
||||||
|
else
|
||||||
|
Con_DPrintf("Ignoring undefined cvar \"%s\", which would be set to \"%s\"\n", cvarname, val);
|
||||||
Cvar_Set(var, val);
|
Cvar_Set(var, val);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1188,15 +1188,6 @@ char *SV_PlayerPublicAddress(client_t *cl)
|
||||||
return va("prot %s %s", prot, ver); //something so they can't confuse ip parsing so easily nor pass them off as some other protocol.
|
return va("prot %s %s", prot, ver); //something so they can't confuse ip parsing so easily nor pass them off as some other protocol.
|
||||||
}
|
}
|
||||||
|
|
||||||
#define STATUS_OLDSTYLE 0 //equivelent to STATUS_SERVERINFO|STATUS_PLAYERS
|
|
||||||
#define STATUS_SERVERINFO 1
|
|
||||||
#define STATUS_PLAYERS 2
|
|
||||||
#define STATUS_SPECTATORS 4
|
|
||||||
#define STATUS_SPECTATORS_AS_PLAYERS 8 //for ASE - change only frags: show as "S"
|
|
||||||
#define STATUS_SHOWTEAMS 16
|
|
||||||
#define STATUS_QTVLIST 32 //qtv destid "name" "streamid@host:port" numviewers
|
|
||||||
#define STATUS_LOGININFO 64
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
SVC_Status
|
SVC_Status
|
||||||
|
@ -1793,6 +1784,10 @@ qboolean SVC_GetChallenge (qboolean respond_dp)
|
||||||
memcpy(over, &lng, sizeof(lng));
|
memcpy(over, &lng, sizeof(lng));
|
||||||
over+=sizeof(lng);
|
over+=sizeof(lng);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (svs.gametype == GT_PROGS || svs.gametype == GT_Q1QVM || svs.gametype == GT_QUAKE2)
|
||||||
|
{
|
||||||
|
unsigned int mask;
|
||||||
//report the mtu
|
//report the mtu
|
||||||
if (*net_mtu.string)
|
if (*net_mtu.string)
|
||||||
mask = net_mtu.ival&~7;
|
mask = net_mtu.ival&~7;
|
||||||
|
|
|
@ -30,12 +30,6 @@
|
||||||
//queryresponse: "getservers[Ext]Response\\aaaapp/aaaaaaaaaaaapp\\EOF"
|
//queryresponse: "getservers[Ext]Response\\aaaapp/aaaaaaaaaaaapp\\EOF"
|
||||||
#define QUAKE3PROTOCOLNAME "Quake3"
|
#define QUAKE3PROTOCOLNAME "Quake3"
|
||||||
|
|
||||||
|
|
||||||
#define PREFIX_SECURE(srv) ((srv)->secure?"🛡":"⚠️")//shield, vs yellow warning
|
|
||||||
#define PREFIX_NEEDPASS(srv) (((srv)->needpass&1)?"🔒":"") //padlock, vs no indicator.
|
|
||||||
#define PREFIX_TYPE(srv) ( ((srv)->type&1)?"☮"/*coop: peace sign, deathmatch:no indicator. */ :\
|
|
||||||
((srv)->type&2)?"📺"/*tv symbol*/ :\
|
|
||||||
"")
|
|
||||||
enum gametypes_e
|
enum gametypes_e
|
||||||
{
|
{
|
||||||
GT_FFA=0,
|
GT_FFA=0,
|
||||||
|
@ -53,7 +47,12 @@ typedef struct svm_server_s {
|
||||||
unsigned int maxclients; //limit of bots+clients, but not necessarily spectators.
|
unsigned int maxclients; //limit of bots+clients, but not necessarily spectators.
|
||||||
unsigned int secure:1;
|
unsigned int secure:1;
|
||||||
unsigned int needpass:1;
|
unsigned int needpass:1;
|
||||||
unsigned int type:4;
|
unsigned int stype:5;
|
||||||
|
#define STYPE_COOP (1<<0)
|
||||||
|
#define STYPE_QTV (1<<1)
|
||||||
|
#define STYPE_QWFWD (1<<2)
|
||||||
|
#define STYPE_TURN (1<<3)
|
||||||
|
#define STYPE_NOMOUSE (1<<4)
|
||||||
char hostname[64]; //just for our own listings.
|
char hostname[64]; //just for our own listings.
|
||||||
char mapname[16]; //just for our own listings.
|
char mapname[16]; //just for our own listings.
|
||||||
char gamedir[16]; //again...
|
char gamedir[16]; //again...
|
||||||
|
@ -73,6 +72,7 @@ typedef struct svm_game_s {
|
||||||
svm_server_t *firstserver;
|
svm_server_t *firstserver;
|
||||||
size_t numservers;
|
size_t numservers;
|
||||||
qboolean persistent;
|
qboolean persistent;
|
||||||
|
char *levelshotsurl; //eg "https://somewhere/somegame/levelshots/" mapname.jpg will be appended.
|
||||||
char *aliases; //list of terminated names, terminated with a double-null
|
char *aliases; //list of terminated names, terminated with a double-null
|
||||||
char *scheme;
|
char *scheme;
|
||||||
char name[1]; //eg: Quake
|
char name[1]; //eg: Quake
|
||||||
|
@ -243,7 +243,7 @@ static svm_game_t *SVM_FindGame(const char *game, int create)
|
||||||
|
|
||||||
if (create)
|
if (create)
|
||||||
{
|
{
|
||||||
if (create != 2)
|
if (create < 2)
|
||||||
{
|
{
|
||||||
if (svm.numgames >= sv_maxgames.ival)
|
if (svm.numgames >= sv_maxgames.ival)
|
||||||
{
|
{
|
||||||
|
@ -295,6 +295,12 @@ static int QDECL SVM_SortOrder(const void *v1, const void *v2)
|
||||||
if (sv_sortlist.ival&8)
|
if (sv_sortlist.ival&8)
|
||||||
return s1->expiretime > s2->expiretime;
|
return s1->expiretime > s2->expiretime;
|
||||||
|
|
||||||
|
if (sv_sortlist.ival&64)
|
||||||
|
{ //make em sort downwards if they're weird types of servers
|
||||||
|
#define STYPE_SPECIAL(s) (!(s->stype&(STYPE_QTV|STYPE_QWFWD|STYPE_TURN)))
|
||||||
|
if ((t=(STYPE_SPECIAL(s2)-STYPE_SPECIAL(s1))))
|
||||||
|
return (t>0)?1:-1;
|
||||||
|
}
|
||||||
if (sv_sortlist.ival&1)
|
if (sv_sortlist.ival&1)
|
||||||
{
|
{
|
||||||
if ((t=(s2->clients-s1->clients)))
|
if ((t=(s2->clients-s1->clients)))
|
||||||
|
@ -483,6 +489,7 @@ static char *QuakeCharsToHTML(char *outhtml, size_t outsize, const char *quake,
|
||||||
return NULL; //no space for the null
|
return NULL; //no space for the null
|
||||||
|
|
||||||
end = COM_ParseFunString(oldflags, quake, chars, sizeof(chars), false);
|
end = COM_ParseFunString(oldflags, quake, chars, sizeof(chars), false);
|
||||||
|
TL_FilterObsceneCCStringInplace(chars, end); //strip the swears without breaking cullers.
|
||||||
while (c < end)
|
while (c < end)
|
||||||
{
|
{
|
||||||
c = Font_Decode(c, &codeflags, &codepoint);
|
c = Font_Decode(c, &codeflags, &codepoint);
|
||||||
|
@ -551,6 +558,13 @@ static char *QuakeCharsToHTML(char *outhtml, size_t outsize, const char *quake,
|
||||||
outsize -= b;
|
outsize -= b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (oldflags != CON_WHITEMASK)
|
||||||
|
{
|
||||||
|
Q_strncpyz(outhtml, "</span>", outsize);
|
||||||
|
b=strlen(outhtml);
|
||||||
|
outhtml += b;
|
||||||
|
outsize -= b;
|
||||||
|
}
|
||||||
*outhtml = 0;
|
*outhtml = 0;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -560,7 +574,7 @@ static void SVM_Init(void)
|
||||||
master_css = FS_MallocFile("master.css", FS_ROOT, NULL);
|
master_css = FS_MallocFile("master.css", FS_ROOT, NULL);
|
||||||
if (!master_css)
|
if (!master_css)
|
||||||
master_css = Z_StrDup(
|
master_css = Z_StrDup(
|
||||||
"<meta charset=\"UTF-8\">"
|
"<!DOCTYPE html><meta charset=\"UTF-8\"/>"
|
||||||
"<style type=\"text/css\">"
|
"<style type=\"text/css\">"
|
||||||
"body {"
|
"body {"
|
||||||
"background-color: #303030;"
|
"background-color: #303030;"
|
||||||
|
@ -637,6 +651,25 @@ vfsfile_t *SVM_Generate_Gamelist(const char **mimetype, const char *query)
|
||||||
*mimetype = "text/html";
|
*mimetype = "text/html";
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
static void SVM_PrintServerPrefixes(vfsfile_t *stream, svm_server_t *server)
|
||||||
|
{
|
||||||
|
if (server->secure)
|
||||||
|
VFS_PRINTF(stream, "%s", "🛡"); //'shield'
|
||||||
|
else
|
||||||
|
VFS_PRINTF(stream, "%s", "⚠️"); //(yellow) 'Warning'
|
||||||
|
if (server->needpass&1)
|
||||||
|
VFS_PRINTF(stream, "%s", "🔒"); //'Lock'
|
||||||
|
|
||||||
|
if (server->stype&STYPE_COOP)
|
||||||
|
VFS_PRINTF(stream, "%s", "☮"); //'Peace'
|
||||||
|
else if (server->stype&STYPE_QTV)
|
||||||
|
VFS_PRINTF(stream, "%s", "📺"); //'Television'
|
||||||
|
else if (server->stype&STYPE_QWFWD)
|
||||||
|
VFS_PRINTF(stream, "%s", "🛰"); //'Satellite'
|
||||||
|
|
||||||
|
if (server->stype&STYPE_NOMOUSE)
|
||||||
|
VFS_PRINTF(stream, "%s", "🎮"); //'Video Game'(Controller)
|
||||||
|
}
|
||||||
struct rulelist_s
|
struct rulelist_s
|
||||||
{
|
{
|
||||||
unsigned int lines;
|
unsigned int lines;
|
||||||
|
@ -647,13 +680,15 @@ struct rulelist_s
|
||||||
static void SVM_GatherServerRule(void *ctx, const char *key, const char *val)
|
static void SVM_GatherServerRule(void *ctx, const char *key, const char *val)
|
||||||
{
|
{
|
||||||
struct rulelist_s *rules = ctx;
|
struct rulelist_s *rules = ctx;
|
||||||
|
char nicekey[256];
|
||||||
char niceval[256];
|
char niceval[256];
|
||||||
if (rules->lines == countof(rules->line))
|
if (rules->lines == countof(rules->line))
|
||||||
return; //overflow
|
return; //overflow
|
||||||
if (*key == '_')
|
if (*key == '_')
|
||||||
val = "<PRIVATE>"; //was meant to be private... lets show that its there, just not what it is.
|
val = "<PRIVATE>"; //was meant to be private... lets show that its there, just not what it is.
|
||||||
|
QuakeCharsToHTML(nicekey, sizeof(nicekey), key, false);
|
||||||
QuakeCharsToHTML(niceval, sizeof(niceval), val, false);
|
QuakeCharsToHTML(niceval, sizeof(niceval), val, false);
|
||||||
if (!Q_snprintfz(rules->blob+rules->blobofs, sizeof(rules->blob)-rules->blobofs, "<tr><td>%s</td><td>%s</td></tr>\n", key, niceval))
|
if (!Q_snprintfz(rules->blob+rules->blobofs, sizeof(rules->blob)-rules->blobofs, "<tr><td>%s</td><td>%s</td></tr>\n", nicekey, niceval))
|
||||||
{
|
{
|
||||||
rules->line[rules->lines++] = rules->blob+rules->blobofs;
|
rules->line[rules->lines++] = rules->blob+rules->blobofs;
|
||||||
rules->blobofs += strlen(rules->blob+rules->blobofs)+1;
|
rules->blobofs += strlen(rules->blob+rules->blobofs)+1;
|
||||||
|
@ -663,20 +698,32 @@ static int QDECL SVM_SortServerRule(const void *r1, const void *r2)
|
||||||
{
|
{
|
||||||
return Q_strcasecmp(*(char*const*const)r1, *(char*const*const)r2);
|
return Q_strcasecmp(*(char*const*const)r1, *(char*const*const)r2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SVM_Generate_ServerinfoEntry(vfsfile_t *f, const char *masteraddr, svm_server_t *server, const char *query)
|
void SVM_Generate_ServerinfoEntry(vfsfile_t *f, const char *masteraddr, svm_server_t *server, const char *query)
|
||||||
{
|
{
|
||||||
char tmpbuf[512];
|
char tmpbuf[512];
|
||||||
char hostname[1024];
|
char hostname[1024];
|
||||||
|
char gamedir[256];
|
||||||
|
char mapname[256];
|
||||||
|
char qmapname[256];
|
||||||
size_t u;
|
size_t u;
|
||||||
const char *url, *fp;
|
const char *url, *fp;
|
||||||
|
|
||||||
VFS_PRINTF(f, "<table border=1>\n");
|
VFS_PRINTF(f, "<table border=1>\n");
|
||||||
VFS_PRINTF(f, "<tr><th>Game</th><th>Address</th><th>Hostname</th><th>Mod dir</th><th>Mapname</th><th>Players</th></tr>\n");
|
VFS_PRINTF(f, "<tr><th>Game</th><th>Address</th><th>Hostname</th><th>Mod dir</th><th>Mapname</th><th>Players</th></tr>\n");
|
||||||
QuakeCharsToHTML(hostname, sizeof(hostname), server->hostname, false);
|
QuakeCharsToHTML(hostname, sizeof(hostname), server->hostname, false);
|
||||||
|
QuakeCharsToHTML(gamedir, sizeof(gamedir), server->gamedir, false);
|
||||||
|
QuakeCharsToHTML(mapname, sizeof(mapname), server->mapname, false);
|
||||||
|
COM_QuotedString(server->mapname, qmapname,sizeof(qmapname), true);
|
||||||
|
|
||||||
if (server->brokerid)
|
if (server->brokerid)
|
||||||
url=tmpbuf, Q_snprintfz(tmpbuf, sizeof(tmpbuf), "rtc://%s/%s", masteraddr, server->brokerid);
|
{
|
||||||
|
char *bs = net_ice_broker.string;
|
||||||
|
if (!strncmp(bs, "tcp://", 6)||!strncmp(bs, "tls://", 6)||!strncmp(bs, "wss://", 6)) bs += 6;
|
||||||
|
if (!strcmp(masteraddr, bs))
|
||||||
|
url=tmpbuf, Q_snprintfz(tmpbuf, sizeof(tmpbuf), "/%s", server->brokerid);
|
||||||
|
else
|
||||||
|
url=tmpbuf, Q_snprintfz(tmpbuf, sizeof(tmpbuf), "rtc://%s/%s", masteraddr, server->brokerid);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
url = NET_AdrToString(tmpbuf, sizeof(tmpbuf), &server->adr);
|
url = NET_AdrToString(tmpbuf, sizeof(tmpbuf), &server->adr);
|
||||||
fp = Info_ValueForKey(server->rules, "*fp");
|
fp = Info_ValueForKey(server->rules, "*fp");
|
||||||
|
@ -685,11 +732,12 @@ void SVM_Generate_ServerinfoEntry(vfsfile_t *f, const char *masteraddr, svm_serv
|
||||||
if (server->game->scheme && !server->brokerid)
|
if (server->game->scheme && !server->brokerid)
|
||||||
url = va("<a href=\"%s://%s%s\">%s</a>", server->game->scheme, url,fp, url);
|
url = va("<a href=\"%s://%s%s\">%s</a>", server->game->scheme, url,fp, url);
|
||||||
|
|
||||||
VFS_PRINTF(f, "<tr><td><a href=\"/game/%s%s%s\">%s</a></td><td>%s</td><td>%s%s%s%s</td><td>%s</td><td>%s</td><td>%u/%u</td></tr>\n",
|
VFS_PRINTF(f, "<tr><td><a href=\"/game/%s%s%s\">%s</a></td><td>%s</td><td>",
|
||||||
server->game?server->game->name:"Unknown", query?"?":"", query?query:"", server->game?server->game->name:"Unknown", //game column
|
server->game?server->game->name:"Unknown", query?"?":"", query?query:"", server->game?server->game->name:"Unknown", //game column
|
||||||
url, //address column
|
url); //address column
|
||||||
PREFIX_SECURE(server), PREFIX_NEEDPASS(server), PREFIX_TYPE(server), hostname, //hostname column
|
SVM_PrintServerPrefixes(f, server);
|
||||||
server->gamedir, server->mapname, server->clients, server->maxclients);
|
VFS_PRINTF(f, "%s</td><td>%s</td><td>%s</td><td>%u/%u</td></tr>\n",
|
||||||
|
hostname, gamedir, mapname, server->clients, server->maxclients);
|
||||||
VFS_PRINTF(f, "</table>\n");
|
VFS_PRINTF(f, "</table>\n");
|
||||||
VFS_PRINTF(f, "<br/>\n");
|
VFS_PRINTF(f, "<br/>\n");
|
||||||
|
|
||||||
|
@ -700,18 +748,18 @@ void SVM_Generate_ServerinfoEntry(vfsfile_t *f, const char *masteraddr, svm_serv
|
||||||
Info_Enumerate(server->rules, &rules, SVM_GatherServerRule);
|
Info_Enumerate(server->rules, &rules, SVM_GatherServerRule);
|
||||||
qsort(rules.line, rules.lines, sizeof(rules.line[0]), SVM_SortServerRule);
|
qsort(rules.line, rules.lines, sizeof(rules.line[0]), SVM_SortServerRule);
|
||||||
|
|
||||||
//VFS_PRINTF(f, "<table border=0>\n");
|
VFS_PRINTF(f, "<table><tr style='background-color:#303030;'><td><table border=1>\n");
|
||||||
// VFS_PRINTF(f, "<td></td><td>");
|
VFS_PRINTF(f, "<tr><th>Rule</th><th>Value</th></tr>\n");
|
||||||
VFS_PRINTF(f, "<table border=1>\n");
|
for (u = 0; u < rules.lines; u++)
|
||||||
VFS_PRINTF(f, "</th><th>Rule</th><th>Value</th></tr>\n");
|
VFS_PUTS(f, rules.line[u]);
|
||||||
for (u = 0; u < rules.lines; u++)
|
VFS_PRINTF(f, "</table></td>");
|
||||||
VFS_PUTS(f, rules.line[u]);
|
if (*qmapname && server->game->levelshotsurl)
|
||||||
VFS_PRINTF(f, "</table>");
|
VFS_PRINTF(f, "<td style='width:1px;'><img src=\"%s%s.jpg\" alt=\"\"></td>", server->game->levelshotsurl, qmapname);
|
||||||
// VFS_PRINTF(f, "</td>");
|
VFS_PRINTF(f, "</tr></table>");
|
||||||
//VFS_PRINTF(f, "</table>\n");
|
|
||||||
VFS_PRINTF(f, "<br/>\n");
|
VFS_PRINTF(f, "<br/>\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void SVM_GenChallenge(char *out, size_t outsize, netadr_t *foradr);
|
||||||
static svm_server_t *SVM_FindBrokerHost(const char *brokerid);
|
static svm_server_t *SVM_FindBrokerHost(const char *brokerid);
|
||||||
static vfsfile_t *SVM_Generate_RoomServerinfo(const char **mimetype, const char *masteraddr, const char *serveraddr, const char *query)
|
static vfsfile_t *SVM_Generate_RoomServerinfo(const char **mimetype, const char *masteraddr, const char *serveraddr, const char *query)
|
||||||
{
|
{
|
||||||
|
@ -742,6 +790,7 @@ static vfsfile_t *SVM_Generate_AddrServerinfo(const char **mimetype, const char
|
||||||
svm_server_t *server;
|
svm_server_t *server;
|
||||||
netadr_t adr[64];
|
netadr_t adr[64];
|
||||||
size_t count;//, u;
|
size_t count;//, u;
|
||||||
|
static double nextquery;
|
||||||
// const char *url, *fp;
|
// const char *url, *fp;
|
||||||
|
|
||||||
VFS_PRINTF(f, "%s", master_css);
|
VFS_PRINTF(f, "%s", master_css);
|
||||||
|
@ -760,9 +809,42 @@ static vfsfile_t *SVM_Generate_AddrServerinfo(const char **mimetype, const char
|
||||||
SVM_Generate_ServerinfoEntry(f, masteraddr, server, query);
|
SVM_Generate_ServerinfoEntry(f, masteraddr, server, query);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
qboolean doingquery = false;
|
||||||
|
double time = Sys_DoubleTime();
|
||||||
|
if (time > nextquery)
|
||||||
|
{
|
||||||
|
sizebuf_t sb;
|
||||||
|
char ourchallenge[256];
|
||||||
|
SVM_GenChallenge(ourchallenge, sizeof(ourchallenge), &adr[count]);
|
||||||
|
svm.total.queries++;
|
||||||
|
|
||||||
|
memset(&sb, 0, sizeof(sb));
|
||||||
|
sb.maxsize = sizeof(net_message_buffer);
|
||||||
|
sb.data = net_message_buffer;
|
||||||
|
|
||||||
|
//send a qw request, in case the user is checking up on a poopy mvdsv server
|
||||||
|
MSG_WriteLong(&sb, -1);
|
||||||
|
MSG_WriteString(&sb, va("status %i\n", 15));
|
||||||
|
sb.cursize--;
|
||||||
|
NET_SendPacket(svm_sockets, sb.cursize, sb.data, &adr[count]);
|
||||||
|
|
||||||
|
sb.cursize = 0;
|
||||||
|
//send a proper request, one with a challenge that we can trust.
|
||||||
|
MSG_WriteLong(&sb, -1);
|
||||||
|
MSG_WriteString(&sb, va("getinfo %s\n", ourchallenge));
|
||||||
|
sb.cursize--;
|
||||||
|
NET_SendPacket(svm_sockets, sb.cursize, sb.data, &adr[count]);
|
||||||
|
|
||||||
|
doingquery = true;
|
||||||
|
nextquery = time + 10; //don't let people do this more than one time every 10 secs. don't abuse (dead) servers, don't be a DoS.
|
||||||
|
|
||||||
|
//try and get the browser to refresh once we have a response, hopefully.
|
||||||
|
VFS_PRINTF(f, "<meta http-equiv='refresh' content='5'>");
|
||||||
|
}
|
||||||
|
|
||||||
VFS_PRINTF(f, "<table border=1>\n");
|
VFS_PRINTF(f, "<table border=1>\n");
|
||||||
VFS_PRINTF(f, "<tr><th>Game</th><th>Address</th><th>Hostname</th><th>Gamedir</th><th>Mapname</th><th>Players</th></tr>\n");
|
VFS_PRINTF(f, "<tr><th>Game</th><th>Address</th><th>Hostname</th><th>Gamedir</th><th>Mapname</th><th>Players</th></tr>\n");
|
||||||
VFS_PRINTF(f, "<tr><td>?</td><td>%s</td><td>?</td><td>?</td><td>?</td><td>?/?</td></tr>\n", NET_AdrToString(tmpbuf, sizeof(tmpbuf), &adr[count]));
|
VFS_PRINTF(f, "<tr><td>?</td><td>%s</td><td>%s</td><td>?</td><td>?</td><td>?/?</td></tr>\n", NET_AdrToString(tmpbuf, sizeof(tmpbuf), &adr[count]), doingquery?"<QUERYING ...>":"?");
|
||||||
VFS_PRINTF(f, "</table>\n");
|
VFS_PRINTF(f, "</table>\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -829,7 +911,9 @@ vfsfile_t *SVM_Generate_Serverlist(const char **mimetype, const char *masteraddr
|
||||||
infourl = url = NET_AdrToString(tmpbuf, sizeof(tmpbuf), &server->adr);
|
infourl = url = NET_AdrToString(tmpbuf, sizeof(tmpbuf), &server->adr);
|
||||||
preurl = "/server/";
|
preurl = "/server/";
|
||||||
}
|
}
|
||||||
VFS_PRINTF(f, "<tr><td><a href=\"%s%s\">%s</a></td><td>%s%s%s%s</td><td>%s</td><td>%s</td><td>%u", preurl,infourl, url, PREFIX_SECURE(server), PREFIX_NEEDPASS(server), PREFIX_TYPE(server), hostname, server->gamedir, server->mapname, server->clients);
|
VFS_PRINTF(f, "<tr><td><a href=\"%s%s\">%s</a></td><td>", preurl,infourl, url);
|
||||||
|
SVM_PrintServerPrefixes(f, server);
|
||||||
|
VFS_PRINTF(f, "%s</td><td>%s</td><td>%s</td><td>%u", hostname, server->gamedir, server->mapname, server->clients);
|
||||||
if (server->bots)
|
if (server->bots)
|
||||||
VFS_PRINTF(f, "+%ub", server->bots);
|
VFS_PRINTF(f, "+%ub", server->bots);
|
||||||
VFS_PRINTF(f, "/%u", server->maxclients);
|
VFS_PRINTF(f, "/%u", server->maxclients);
|
||||||
|
@ -1012,20 +1096,22 @@ void SVM_AddBrokerGame(const char *brokerid, const char *info)
|
||||||
server->clients = atoi(Info_ValueForKey(info, "clients"));
|
server->clients = atoi(Info_ValueForKey(info, "clients"));
|
||||||
server->secure = !!*Info_ValueForKey(info, "*fp");
|
server->secure = !!*Info_ValueForKey(info, "*fp");
|
||||||
server->needpass = atoi(Info_ValueForKey(info, "needpass"));
|
server->needpass = atoi(Info_ValueForKey(info, "needpass"));
|
||||||
server->type = atoi(Info_ValueForKey(info, "coop"));
|
server->stype = atoi(Info_ValueForKey(info, "coop"))?STYPE_COOP:0;
|
||||||
if (!server->type)
|
if (!server->stype)
|
||||||
{ //deathmatch 0 also means coop 1... servers that report neither are probably annoying DP servers that report nothing useful and should default to DM.
|
{ //deathmatch 0 also means coop 1... servers that report neither are probably annoying DP servers that report nothing useful and should default to DM.
|
||||||
const char *v = Info_ValueForKey(info, "deathmatch");
|
const char *v = Info_ValueForKey(info, "deathmatch");
|
||||||
server->type = *v && !atoi(v);
|
server->stype = *v && !atoi(v);
|
||||||
}
|
}
|
||||||
server->protover = strtol(Info_ValueForKey(info, "protocol"), &s, 0);
|
server->protover = strtol(Info_ValueForKey(info, "protocol"), &s, 0);
|
||||||
for (; *s; s++)
|
for (; *s; s++)
|
||||||
{
|
{
|
||||||
if (*s == 't') //turn
|
if (*s == 't') //turn
|
||||||
server->type |= 2;
|
server->stype |= STYPE_TURN;
|
||||||
else if (*s == 'f') //usable for qwfwd
|
else if (*s == 'f') //usable for qwfwd
|
||||||
server->type |= 4;
|
server->stype |= STYPE_QWFWD;
|
||||||
}
|
}
|
||||||
|
if (strtol(Info_ValueForKey(info, "nomouse"), NULL, 0))
|
||||||
|
server->stype |= STYPE_NOMOUSE;
|
||||||
Q_strncpyz(server->hostname, Info_ValueForKey(info, "hostname"), sizeof(server->hostname));
|
Q_strncpyz(server->hostname, Info_ValueForKey(info, "hostname"), sizeof(server->hostname));
|
||||||
Q_strncpyz(server->gamedir, Info_ValueForKey(info, "modname"), sizeof(server->gamedir));
|
Q_strncpyz(server->gamedir, Info_ValueForKey(info, "modname"), sizeof(server->gamedir));
|
||||||
Q_strncpyz(server->mapname, Info_ValueForKey(info, "mapname"), sizeof(server->mapname));
|
Q_strncpyz(server->mapname, Info_ValueForKey(info, "mapname"), sizeof(server->mapname));
|
||||||
|
@ -1055,7 +1141,7 @@ void SVM_SelectRelay(netadr_t *benefitiary, const char *brokerid, char *out, siz
|
||||||
{
|
{
|
||||||
if (server->needpass)
|
if (server->needpass)
|
||||||
continue; //nope, not interested.
|
continue; //nope, not interested.
|
||||||
if (server->type & 8) //acting as a turn relay...
|
if (server->stype & STYPE_TURN) //acting as a turn relay...
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
if (!count)
|
if (!count)
|
||||||
|
@ -1067,7 +1153,7 @@ void SVM_SelectRelay(netadr_t *benefitiary, const char *brokerid, char *out, siz
|
||||||
{
|
{
|
||||||
if (server->needpass)
|
if (server->needpass)
|
||||||
continue; //nope, not interested.
|
continue; //nope, not interested.
|
||||||
if (server->type & 8) //acting as a turn relay...
|
if (server->stype & STYPE_TURN) //acting as a turn relay...
|
||||||
{
|
{
|
||||||
if (count-->0)
|
if (count-->0)
|
||||||
continue; //we didn't pick this one, keep going.
|
continue; //we didn't pick this one, keep going.
|
||||||
|
@ -1471,11 +1557,12 @@ static void SVM_ProcessUDPPacket(void)
|
||||||
srv->maxclients = atoi(Info_ValueForKey(s, "sv_maxclients"));
|
srv->maxclients = atoi(Info_ValueForKey(s, "sv_maxclients"));
|
||||||
srv->secure = !!*Info_ValueForKey(s, "*fp");
|
srv->secure = !!*Info_ValueForKey(s, "*fp");
|
||||||
srv->needpass = atoi(Info_ValueForKey(s, "needpass"));
|
srv->needpass = atoi(Info_ValueForKey(s, "needpass"));
|
||||||
srv->type = atoi(Info_ValueForKey(s, "coop"));
|
srv->stype = atoi(Info_ValueForKey(s, "coop"))?STYPE_COOP:0;
|
||||||
if (!srv->type)
|
if (!srv->stype)
|
||||||
{ //deathmatch 0 also means coop 1... servers that report neither are probably annoying DP servers that report nothing useful and should default to DM.
|
{ //deathmatch 0 also means coop 1... servers that report neither are probably annoying DP servers that report nothing useful and should default to DM.
|
||||||
const char *v = Info_ValueForKey(s, "deathmatch");
|
const char *v = Info_ValueForKey(s, "deathmatch");
|
||||||
srv->type = *v && !atoi(v);
|
if (*v && !atoi(v))
|
||||||
|
srv->stype |= STYPE_COOP;
|
||||||
}
|
}
|
||||||
Q_strncpyz(srv->hostname, Info_ValueForKey(s, "hostname"), sizeof(srv->hostname));
|
Q_strncpyz(srv->hostname, Info_ValueForKey(s, "hostname"), sizeof(srv->hostname));
|
||||||
Q_strncpyz(srv->gamedir, Info_ValueForKey(s, "modname"), sizeof(srv->gamedir));
|
Q_strncpyz(srv->gamedir, Info_ValueForKey(s, "modname"), sizeof(srv->gamedir));
|
||||||
|
@ -1489,12 +1576,14 @@ static void SVM_ProcessUDPPacket(void)
|
||||||
for (; *s; s++)
|
for (; *s; s++)
|
||||||
{
|
{
|
||||||
if (*s == 't')
|
if (*s == 't')
|
||||||
srv->type |= 2;
|
srv->stype |= STYPE_QTV;
|
||||||
else if (*s == 'f')
|
else if (*s == 'f')
|
||||||
srv->type |= 4;
|
srv->stype |= STYPE_QWFWD;
|
||||||
}
|
}
|
||||||
if (*Info_ValueForKey(srv->rules, "_turnkey"))
|
if (*Info_ValueForKey(srv->rules, "_turnkey"))
|
||||||
srv->type |= 8;
|
srv->stype |= STYPE_TURN;
|
||||||
|
if (atoi(Info_ValueForKey(srv->rules, "nomouse")))
|
||||||
|
srv->stype |= STYPE_NOMOUSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1643,37 +1732,41 @@ static void SVM_ProcessUDPPacket(void)
|
||||||
|
|
||||||
game = Info_ValueForKey(s, "gamename");
|
game = Info_ValueForKey(s, "gamename");
|
||||||
if (!*game)
|
if (!*game)
|
||||||
{
|
game = QUAKEWORLDPROTOCOLNAME;
|
||||||
game = Info_ValueForKey(s, "*version");
|
|
||||||
if (!strncmp(game, "QTV", 3))
|
|
||||||
game = "QTV";
|
|
||||||
else if (!strncmp(game, "qwfwd", 5))
|
|
||||||
game = "qwfwd";
|
|
||||||
else
|
|
||||||
game = QUAKEWORLDPROTOCOLNAME;
|
|
||||||
}
|
|
||||||
srv = SVM_Heartbeat(game, &net_from, clients,bots,specs, svm.time + sv_heartbeattimeout.ival);
|
srv = SVM_Heartbeat(game, &net_from, clients,bots,specs, svm.time + sv_heartbeattimeout.ival);
|
||||||
if (srv)
|
if (srv)
|
||||||
{
|
{
|
||||||
Q_strncpyz(srv->rules, s, sizeof(srv->rules));
|
Q_strncpyz(srv->rules, s, sizeof(srv->rules));
|
||||||
|
Info_RemoveKey(srv->rules, "*fp"); //we have no challenge and thus no way to protect against spoofing. don't allow it to report a dodgy fingerprint.
|
||||||
if (developer.ival)
|
if (developer.ival)
|
||||||
Info_Print(s, "\t");
|
Info_Print(s, "\t");
|
||||||
srv->protover = 3;//atoi(Info_ValueForKey(s, "protocol"));
|
srv->protover = 3;//atoi(Info_ValueForKey(s, "protocol"));
|
||||||
srv->maxclients = atoi(Info_ValueForKey(s, "maxclients"));
|
srv->maxclients = atoi(Info_ValueForKey(s, "maxclients"));
|
||||||
srv->secure = !!*Info_ValueForKey(s, "*fp");
|
srv->secure = !!*Info_ValueForKey(s, "*fp");
|
||||||
srv->needpass = atoi(Info_ValueForKey(s, "needpass"));
|
srv->needpass = atoi(Info_ValueForKey(s, "needpass"));
|
||||||
srv->type = atoi(Info_ValueForKey(s, "coop"));
|
srv->stype = atoi(Info_ValueForKey(s, "coop"))?STYPE_COOP:0;
|
||||||
if (!srv->type)
|
if (!srv->stype)
|
||||||
{ //deathmatch 0 also means coop 1... servers that report neither are probably annoying proxies servers that report nothing useful and should default to DM.
|
{ //deathmatch 0 also means coop 1... servers that report neither are probably annoying proxies servers that report nothing useful and should default to DM.
|
||||||
const char *v = Info_ValueForKey(s, "deathmatch");
|
const char *v = Info_ValueForKey(s, "deathmatch");
|
||||||
srv->type = *v && !atoi(v);
|
if (*v && !atoi(v))
|
||||||
|
srv->stype |= STYPE_COOP;
|
||||||
}
|
}
|
||||||
|
if (atoi(Info_ValueForKey(s, "nomouse")))
|
||||||
|
srv->stype |= STYPE_NOMOUSE;
|
||||||
Q_strncpyz(srv->hostname, Info_ValueForKey(s, "hostname"), sizeof(srv->hostname));
|
Q_strncpyz(srv->hostname, Info_ValueForKey(s, "hostname"), sizeof(srv->hostname));
|
||||||
Q_strncpyz(srv->gamedir, Info_ValueForKey(s, "*gamedir"), sizeof(srv->gamedir));
|
Q_strncpyz(srv->gamedir, Info_ValueForKey(s, "*gamedir"), sizeof(srv->gamedir));
|
||||||
Q_strncpyz(srv->mapname, Info_ValueForKey(s, "map"), sizeof(srv->mapname));
|
Q_strncpyz(srv->mapname, Info_ValueForKey(s, "map"), sizeof(srv->mapname));
|
||||||
Q_strncpyz(srv->version, Info_ValueForKey(s, "version"), sizeof(srv->version));
|
Q_strncpyz(srv->version, Info_ValueForKey(s, "version"), sizeof(srv->version));
|
||||||
if (!*srv->version)
|
if (!*srv->version)
|
||||||
Q_strncpyz(srv->version, Info_ValueForKey(s, "*version"), sizeof(srv->version));
|
{
|
||||||
|
game = Info_ValueForKey(s, "*version");
|
||||||
|
if (!strncmp(game, "QTV", 3))
|
||||||
|
srv->stype |= STYPE_QTV;
|
||||||
|
else if (!strncmp(game, "qwfwd", 5))
|
||||||
|
srv->stype |= STYPE_QWFWD;
|
||||||
|
Q_strncpyz(srv->version, game, sizeof(srv->version));
|
||||||
|
}
|
||||||
if (!*srv->version)
|
if (!*srv->version)
|
||||||
Q_strncpyz(srv->version, Info_ValueForKey(s, "ver"), sizeof(srv->version));
|
Q_strncpyz(srv->version, Info_ValueForKey(s, "ver"), sizeof(srv->version));
|
||||||
}
|
}
|
||||||
|
@ -1808,7 +1901,10 @@ static void SVM_RegisterAlias(svm_game_t *game, char *aliasname)
|
||||||
return; //already in there somehow.
|
return; //already in there somehow.
|
||||||
if (aliasgame)
|
if (aliasgame)
|
||||||
{
|
{
|
||||||
Con_Printf("game alias of %s is already registered\n", aliasname);
|
if (strcmp(aliasgame->name, aliasname))
|
||||||
|
Con_DPrintf("game alias of %s(aka %s) is already registered to %s\n", aliasname, game->name, aliasgame->name);
|
||||||
|
else
|
||||||
|
Con_DPrintf("game alias of %s is already registered\n", aliasname);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
game->persistent = true; //don't forget us!
|
game->persistent = true; //don't forget us!
|
||||||
|
@ -1834,6 +1930,16 @@ static void SVM_GameAlias_f(void)
|
||||||
}
|
}
|
||||||
SVM_RegisterAlias(game, Cmd_Argv(2));
|
SVM_RegisterAlias(game, Cmd_Argv(2));
|
||||||
}
|
}
|
||||||
|
static void SVM_GameLevelshots_f(void)
|
||||||
|
{
|
||||||
|
svm_game_t *game = SVM_FindGame(Cmd_Argv(1), 2);
|
||||||
|
if (!game)
|
||||||
|
{
|
||||||
|
Con_Printf("Unable to register game %s\n", Cmd_Argv(1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Z_StrDupPtr(&game->levelshotsurl, Cmd_Argv(2));
|
||||||
|
}
|
||||||
static void SVM_Register(void)
|
static void SVM_Register(void)
|
||||||
{
|
{
|
||||||
size_t u;
|
size_t u;
|
||||||
|
@ -1841,7 +1947,8 @@ static void SVM_Register(void)
|
||||||
svm_sockets = FTENET_CreateCollection(true, SVM_ProcessUDPPacket);
|
svm_sockets = FTENET_CreateCollection(true, SVM_ProcessUDPPacket);
|
||||||
Hash_InitTable(&svm.serverhash, 1024, Z_Malloc(Hash_BytesForBuckets(1024)));
|
Hash_InitTable(&svm.serverhash, 1024, Z_Malloc(Hash_BytesForBuckets(1024)));
|
||||||
|
|
||||||
Cmd_AddCommand ("gamealias", SVM_GameAlias_f);
|
Cmd_AddCommandD ("gamealias", SVM_GameAlias_f, "Set up alternative protocol names that should be considered part of a single game");
|
||||||
|
Cmd_AddCommandD ("gamelevelshotsurl", SVM_GameLevelshots_f, "Registers a per-game base url to use to form a prefix for where browsers should get their map images from.");
|
||||||
|
|
||||||
Cvar_Register(&sv_masterport, "server control variables");
|
Cvar_Register(&sv_masterport, "server control variables");
|
||||||
Cvar_Register(&sv_masterport_tcp, "server control variables");
|
Cvar_Register(&sv_masterport_tcp, "server control variables");
|
||||||
|
@ -1864,7 +1971,7 @@ static qboolean SVM_FoundManifest(void *usr, ftemanifest_t *man, enum modsourcet
|
||||||
g = man->protocolname;
|
g = man->protocolname;
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
game = SVM_FindGame(man->formalname, 2);
|
game = SVM_FindGame(man->formalname, 3);
|
||||||
#else
|
#else
|
||||||
g = COM_Parse(g);
|
g = COM_Parse(g);
|
||||||
game = SVM_FindGame(com_token, 2);
|
game = SVM_FindGame(com_token, 2);
|
||||||
|
|
|
@ -1538,7 +1538,7 @@ void SV_SendFixAngle(client_t *client, sizebuf_t *msg, int fixtype, qboolean rol
|
||||||
|
|
||||||
if (fixtype == FIXANGLE_AUTO)
|
if (fixtype == FIXANGLE_AUTO)
|
||||||
{
|
{
|
||||||
if (client->lockanglesseq<controller->netchan.incoming_acknowledged && controller->delta_sequence != -1 && !client->viewent)
|
if (client->lockanglesseq<controller->netchan.incoming_acknowledged && controller->delta_sequence != -1 && !client->viewent && !sv_nqplayerphysics.ival)
|
||||||
fixtype = FIXANGLE_DELTA;
|
fixtype = FIXANGLE_DELTA;
|
||||||
else
|
else
|
||||||
fixtype = FIXANGLE_FIXED;
|
fixtype = FIXANGLE_FIXED;
|
||||||
|
|
|
@ -6122,23 +6122,11 @@ qboolean VKBE_BeginShadowmap(qboolean isspot, uint32_t width, uint32_t height)
|
||||||
|
|
||||||
sbuf = shad->seq++%countof(shad->buf);
|
sbuf = shad->seq++%countof(shad->buf);
|
||||||
shaderstate.currentshadowmap = &shad->buf[sbuf].qimage;
|
shaderstate.currentshadowmap = &shad->buf[sbuf].qimage;
|
||||||
/*
|
|
||||||
{
|
/* set_image_layout(vk.rendertarg->cbuf, shaderstate.currentshadowmap->vkimage->image, VK_IMAGE_ASPECT_DEPTH_BIT,
|
||||||
VkImageMemoryBarrier imgbarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER};
|
shaderstate.currentshadowmap->vkimage->layout, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||||
imgbarrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT|VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
|
||||||
imgbarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
shaderstate.currentshadowmap->vkimage->layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
||||||
imgbarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; //we don't actually care because we'll be clearing it anyway, making this more of a no-op than anything else.
|
|
||||||
imgbarrier.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
|
||||||
imgbarrier.image = shad->buf[sbuf].vimage.image;
|
|
||||||
imgbarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
|
||||||
imgbarrier.subresourceRange.baseMipLevel = 0;
|
|
||||||
imgbarrier.subresourceRange.levelCount = 1;
|
|
||||||
imgbarrier.subresourceRange.baseArrayLayer = sbuf;
|
|
||||||
imgbarrier.subresourceRange.layerCount = 1;
|
|
||||||
imgbarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
||||||
imgbarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
||||||
vkCmdPipelineBarrier(vk.rendertarg->cbuf, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT|VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, NULL, 0, NULL, 1, &imgbarrier);
|
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
VkClearValue clearval;
|
VkClearValue clearval;
|
||||||
|
@ -6155,7 +6143,7 @@ qboolean VKBE_BeginShadowmap(qboolean isspot, uint32_t width, uint32_t height)
|
||||||
rpass.pClearValues = &clearval;
|
rpass.pClearValues = &clearval;
|
||||||
vkCmdBeginRenderPass(vk.rendertarg->cbuf, &rpass, VK_SUBPASS_CONTENTS_INLINE);
|
vkCmdBeginRenderPass(vk.rendertarg->cbuf, &rpass, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
}
|
}
|
||||||
shaderstate.currentshadowmap->vkimage->layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
shaderstate.currentshadowmap->vkimage->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; //renderpass should transition it for us.
|
||||||
|
|
||||||
//viewport+scissor will be done elsewhere
|
//viewport+scissor will be done elsewhere
|
||||||
//that wasn't too painful, was it?...
|
//that wasn't too painful, was it?...
|
||||||
|
@ -6183,26 +6171,10 @@ void VKBE_DoneShadows(void)
|
||||||
}
|
}
|
||||||
else*/
|
else*/
|
||||||
{
|
{
|
||||||
/*
|
set_image_layout(vk.rendertarg->cbuf, shaderstate.currentshadowmap->vkimage->image, VK_IMAGE_ASPECT_DEPTH_BIT,
|
||||||
set_image_layout(vk.frame->cbuf, shad->image, VK_IMAGE_ASPECT_DEPTH_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, VK_ACCESS_SHADER_READ_BIT);
|
shaderstate.currentshadowmap->vkimage->layout, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT|VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||||
|
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
|
||||||
{
|
shaderstate.currentshadowmap->vkimage->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
VkImageMemoryBarrier imgbarrier = {VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER};
|
|
||||||
imgbarrier.srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
|
|
||||||
imgbarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
|
|
||||||
imgbarrier.oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
|
|
||||||
imgbarrier.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL;
|
|
||||||
imgbarrier.image = image;
|
|
||||||
imgbarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
|
||||||
imgbarrier.subresourceRange.baseMipLevel = 0;
|
|
||||||
imgbarrier.subresourceRange.levelCount = 1;
|
|
||||||
imgbarrier.subresourceRange.baseArrayLayer = 0;
|
|
||||||
imgbarrier.subresourceRange.layerCount = 1;
|
|
||||||
imgbarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
||||||
imgbarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
|
||||||
vkCmdPipelineBarrier(cmd, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, NULL, 0, NULL, 1, &imgbarrier);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
vkCmdBeginRenderPass(vk.rendertarg->cbuf, &vk.rendertarg->restartinfo, VK_SUBPASS_CONTENTS_INLINE);
|
vkCmdBeginRenderPass(vk.rendertarg->cbuf, &vk.rendertarg->restartinfo, VK_SUBPASS_CONTENTS_INLINE);
|
||||||
|
|
||||||
|
@ -6214,7 +6186,6 @@ void VKBE_DoneShadows(void)
|
||||||
viewport.maxDepth = 1;
|
viewport.maxDepth = 1;
|
||||||
vkCmdSetViewport(vk.rendertarg->cbuf, 0, 1, &viewport);
|
vkCmdSetViewport(vk.rendertarg->cbuf, 0, 1, &viewport);
|
||||||
}
|
}
|
||||||
shaderstate.currentshadowmap->vkimage->layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
|
||||||
|
|
||||||
VKBE_SelectEntity(&r_worldentity);
|
VKBE_SelectEntity(&r_worldentity);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue