mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-24 12:51:46 +00:00
added demo_nudge command.
attempt to fix an issue with bc formats being rejected by d3d if they're not a multiple of 4. added doreset argument to refreshhostcache builtin, for mods to forget all servers when rescanning. stop fteqcc from reporting uninitialised locals etc inside the wrong file. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5251 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
23afe95b70
commit
8c4d39268e
32 changed files with 323 additions and 52 deletions
|
@ -378,6 +378,10 @@ void CL_ProgressDemoTime(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (cl.demopausedtilltime >= realtime)
|
||||
return;
|
||||
cl.demopausedtilltime = 0;
|
||||
cl.demonudge = 0;
|
||||
if (cl_demospeed.value >= 0 && cls.state == ca_active)
|
||||
demtime += host_frametime*cl_demospeed.value;
|
||||
else
|
||||
|
@ -448,6 +452,51 @@ void CL_DemoJump_f(void)
|
|||
cls.demoseeking = true;
|
||||
}
|
||||
|
||||
void CL_DemoNudge_f(void)
|
||||
{
|
||||
extern cvar_t cl_demospeed;
|
||||
int move = atoi(Cmd_Argv(1));
|
||||
int newnudge;
|
||||
|
||||
if (!cls.demoplayback)
|
||||
{
|
||||
Con_Printf("not playing a demo, cannot nudge.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!move)
|
||||
move = 1;
|
||||
|
||||
newnudge = cl.demonudge + move;
|
||||
if (newnudge <= -(int)countof(cl.inframes))
|
||||
newnudge = 1-(int)countof(cl.inframes);
|
||||
|
||||
if (newnudge < 0)
|
||||
{ //if we're nudging to a past frame, make sure that its actually valid.
|
||||
for(;-(int)countof(cl.inframes) < newnudge && newnudge < 0;)
|
||||
{
|
||||
int i = cls.netchan.incoming_sequence+newnudge;
|
||||
if (i < 0)
|
||||
break;
|
||||
if (cl.inframes[i&UPDATE_MASK].frameid == i && !cl.inframes[i&UPDATE_MASK].invalid)
|
||||
{
|
||||
cl.demonudge = newnudge;
|
||||
break;
|
||||
}
|
||||
if (move < 0)
|
||||
newnudge--;
|
||||
else
|
||||
newnudge++;
|
||||
}
|
||||
if (!newnudge)
|
||||
cl.demonudge = newnudge;
|
||||
}
|
||||
else
|
||||
cl.demonudge = newnudge;
|
||||
|
||||
cl.demopausedtilltime = realtime + 3;
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_GetDemoMessage
|
||||
|
@ -537,13 +586,13 @@ qboolean CL_GetDemoMessage (void)
|
|||
#endif
|
||||
if (cls.demoplayback == DPB_NETQUAKE && cls.signon == 4/*SIGNONS*/)
|
||||
{
|
||||
if (!demtime)
|
||||
/*if (!demtime)
|
||||
{
|
||||
cl.gametime = 0;
|
||||
cl.gametimemark = demtime;
|
||||
olddemotime = 0;
|
||||
return 0;
|
||||
}
|
||||
}*/
|
||||
cls.netchan.last_received = realtime;
|
||||
if (cls.demoseeking)
|
||||
{
|
||||
|
@ -553,6 +602,8 @@ qboolean CL_GetDemoMessage (void)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
else if (cl.demonudge > 0)
|
||||
cl.demonudge--;
|
||||
else if ((cls.timedemo && host_framecount == demoframe) || (!cls.timedemo && demtime < cl.gametime && cl.gametime))// > dem_lasttime+demtime)
|
||||
{
|
||||
if (demtime <= cl.gametime-1)
|
||||
|
@ -688,6 +739,11 @@ readnext:
|
|||
cls.td_starttime = Sys_DoubleTime();
|
||||
demtime = demotime; // warp
|
||||
}
|
||||
else if (cl.demonudge > 0)
|
||||
{
|
||||
cl.demonudge--;
|
||||
demtime = demotime; // warp
|
||||
}
|
||||
else if (!(cl.paused&~4) && cls.state >= ca_onserver)
|
||||
{ // always grab until fully connected
|
||||
if (demtime + 1.0 < demotime)
|
||||
|
|
|
@ -3680,7 +3680,12 @@ void CL_TransitionEntities (void)
|
|||
}
|
||||
|
||||
//force our emulated time to as late as we can, if we're not using interpolation, which has the effect of disabling all interpolation
|
||||
if (nolerp)
|
||||
if (cl.demonudge < 0)
|
||||
{
|
||||
servertime = cl.inframes[(cls.netchan.incoming_sequence+cl.demonudge)&UPDATE_MASK].packet_entities.servertime;
|
||||
nolerp = true;
|
||||
}
|
||||
else if (nolerp)
|
||||
servertime = cl.inframes[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities.servertime;
|
||||
else
|
||||
servertime = cl.servertime;
|
||||
|
@ -4969,6 +4974,7 @@ void CL_LinkPlayers (void)
|
|||
float predictmsmult = 1000*cl_predict_players_frac.value;
|
||||
int modelindex2;
|
||||
extern cvar_t cl_demospeed;
|
||||
int displayseq;
|
||||
|
||||
if (!cl.worldmodel || cl.worldmodel->loadstate != MLS_LOADED)
|
||||
return;
|
||||
|
@ -4982,7 +4988,11 @@ void CL_LinkPlayers (void)
|
|||
if (playertime > realtime)
|
||||
playertime = realtime;
|
||||
|
||||
frame = &cl.inframes[cl.validsequence&UPDATE_MASK];
|
||||
if (cl.demonudge < 0)
|
||||
displayseq = cl.lerpentssequence;
|
||||
else
|
||||
displayseq = cl.validsequence;
|
||||
frame = &cl.inframes[displayseq&UPDATE_MASK];
|
||||
|
||||
predictplayers = cl_predict_players.ival;
|
||||
if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
|
||||
|
@ -4993,7 +5003,7 @@ void CL_LinkPlayers (void)
|
|||
{
|
||||
nametagseen[j] = false;
|
||||
|
||||
if (state->messagenum != cl.validsequence)
|
||||
if (state->messagenum != displayseq)
|
||||
{
|
||||
#ifdef CSQC_DAT
|
||||
CSQC_DeltaPlayer(j, NULL);
|
||||
|
|
|
@ -4340,6 +4340,7 @@ void CL_Init (void)
|
|||
Cmd_AddCommand ("qtvlist", CL_QTVList_f);
|
||||
Cmd_AddCommand ("qtvdemos", CL_QTVDemos_f);
|
||||
Cmd_AddCommandD ("demo_jump", CL_DemoJump_f, "Jump to a specified time in a demo. Prefix with a + or - for a relative offset. Seeking backwards will restart the demo and the fast forward, which can take some time in long demos.");
|
||||
Cmd_AddCommandD ("demo_nudge", CL_DemoNudge_f, "Nudge the demo by one frame. Argument should be +1 or -1. Nudging backwards is limited.");
|
||||
Cmd_AddCommandAD ("timedemo", CL_TimeDemo_f, CL_DemoList_c, NULL);
|
||||
Cmd_AddCommand ("crashme_endgame", CL_CrashMeEndgame_f);
|
||||
|
||||
|
|
|
@ -222,7 +222,7 @@ unsigned int Master_TotalCount(void);
|
|||
unsigned int Master_NumPolled(void); //progress indicator
|
||||
unsigned int Master_NumAlive(void);
|
||||
void Master_SetupSockets(void);
|
||||
void MasterInfo_Refresh(void);
|
||||
void MasterInfo_Refresh(qboolean doreset);
|
||||
void Master_QueryServer(serverinfo_t *server);
|
||||
void MasterInfo_WriteServers(void);
|
||||
|
||||
|
|
|
@ -1461,8 +1461,9 @@ static int CL_LoadSounds(int stage, qboolean dontactuallyload)
|
|||
|
||||
void Sound_CheckDownload(const char *s)
|
||||
{
|
||||
#ifndef QUAKETC
|
||||
char mangled[512];
|
||||
|
||||
#endif
|
||||
if (*s == '*') //q2 sexed sound
|
||||
return;
|
||||
|
||||
|
@ -1473,11 +1474,13 @@ void Sound_CheckDownload(const char *s)
|
|||
if (CL_CheckFile(s))
|
||||
return; //we have it already
|
||||
|
||||
#if !defined(QUAKETC) && defined(AVAIL_OGGVORBIS)
|
||||
//the things I do for nexuiz... *sigh*
|
||||
COM_StripExtension(s, mangled, sizeof(mangled));
|
||||
COM_DefaultExtension(mangled, ".ogg", sizeof(mangled));
|
||||
if (CL_CheckFile(mangled))
|
||||
return;
|
||||
#endif
|
||||
|
||||
//check with the sound/ prefix
|
||||
s = va("sound/%s",s);
|
||||
|
@ -1485,12 +1488,13 @@ void Sound_CheckDownload(const char *s)
|
|||
if (CL_CheckFile(s))
|
||||
return; //we have it already
|
||||
|
||||
#if !defined(QUAKETC) && defined(AVAIL_OGGVORBIS)
|
||||
//the things I do for nexuiz... *sigh*
|
||||
COM_StripExtension(s, mangled, sizeof(mangled));
|
||||
COM_DefaultExtension(mangled, ".ogg", sizeof(mangled));
|
||||
if (CL_CheckFile(mangled))
|
||||
return;
|
||||
|
||||
#endif
|
||||
//download the one the server said.
|
||||
CL_CheckOrEnqueDownloadFile(s, NULL, 0);
|
||||
}
|
||||
|
@ -7932,9 +7936,26 @@ void CLNQ_ParseServerMessage (void)
|
|||
CL_SetStatNumeric (0, i, j, j);
|
||||
break;
|
||||
case svcdp_updatestatbyte:
|
||||
i = MSG_ReadByte ();
|
||||
j = MSG_ReadByte ();
|
||||
CL_SetStatNumeric (0, i, j, j);
|
||||
//case svcneh_fog:
|
||||
if (CPNQ_IS_BJP || cls.protocol_nq == PROTOCOL_VERSION_NEHD)
|
||||
{
|
||||
CL_ResetFog(0);
|
||||
if (MSG_ReadByte())
|
||||
{
|
||||
cl.fog[0].density = MSG_ReadFloat();
|
||||
cl.fog[0].colour[0] = SRGBf(MSG_ReadByte()/255.0f);
|
||||
cl.fog[0].colour[1] = SRGBf(MSG_ReadByte()/255.0f);
|
||||
cl.fog[0].colour[2] = SRGBf(MSG_ReadByte()/255.0f);
|
||||
cl.fog[0].time += 0.25; //change fairly fast, but not instantly
|
||||
}
|
||||
cl.fog_locked = !!cl.fog[0].density;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = MSG_ReadByte ();
|
||||
j = MSG_ReadByte ();
|
||||
CL_SetStatNumeric (0, i, j, j);
|
||||
}
|
||||
break;
|
||||
case svcfte_updatestatstring:
|
||||
i = MSG_ReadByte();
|
||||
|
@ -8086,7 +8107,7 @@ void CLNQ_ParseServerMessage (void)
|
|||
cls.signon = 4;
|
||||
CLNQ_SignonReply ();
|
||||
}
|
||||
//well, it's really any protocol, but we're only going to support version 5.
|
||||
//well, it's really any protocol, but we're only going to support version 5 (through 7).
|
||||
CLDP_ParseDarkPlaces5Entities();
|
||||
break;
|
||||
case svcdp_spawnbaseline2:
|
||||
|
|
|
@ -651,7 +651,7 @@ void CL_CalcClientTime(void)
|
|||
if (max)
|
||||
{
|
||||
extern cvar_t cl_demospeed;
|
||||
if (cls.demoplayback && cl_demospeed.value >= 0 && cls.state == ca_active)
|
||||
if (cls.demoplayback && cl_demospeed.value > 0 && cls.state == ca_active)
|
||||
cl.servertime += host_frametime*cl_demospeed.value;
|
||||
else
|
||||
cl.servertime += host_frametime;
|
||||
|
|
|
@ -419,9 +419,12 @@ void SCR_CenterPrint (int pnum, const char *str, qboolean skipgamecode)
|
|||
cvar_t *var;
|
||||
var = Cvar_FindVar ("scr_centerprinttext");
|
||||
if (!var)
|
||||
Cvar_Get("scr_centerprinttext", "", 0, "Script Notifications");
|
||||
Cvar_Set(var, str);
|
||||
Cbuf_AddText("f_centerprint\n", RESTRICT_LOCAL);
|
||||
var = Cvar_Get("scr_centerprinttext", "", 0, "Script Notifications");
|
||||
if (var)
|
||||
{
|
||||
Cvar_Set(var, str);
|
||||
Cbuf_AddText("f_centerprint\n", RESTRICT_LOCAL);
|
||||
}
|
||||
}
|
||||
|
||||
p = &scr_centerprint[pnum];
|
||||
|
@ -550,7 +553,10 @@ void SCR_CenterPrint (int pnum, const char *str, qboolean skipgamecode)
|
|||
for (i = 0; i < p->charcount; i++)
|
||||
{
|
||||
if (p->string[i] == CON_LINKSTART)
|
||||
{
|
||||
p->flags |= CPRINT_CURSOR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -836,7 +836,7 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
|
|||
{
|
||||
extern qboolean NET_SendPollPacket(int len, void *data, netadr_t to);
|
||||
netadr_t na;
|
||||
MasterInfo_Refresh();
|
||||
MasterInfo_Refresh(false);
|
||||
|
||||
if (NET_StringToAdr("255.255.255.255", PORT_Q3SERVER, &na))
|
||||
NET_SendPollPacket (14, va("%c%c%c%cgetstatus\n", 255, 255, 255, 255), na);
|
||||
|
|
|
@ -818,6 +818,8 @@ typedef struct
|
|||
float oldgametime; //used as the old time to lerp cl.time from.
|
||||
float oldgametimemark; //if it's 0, cl.time will casually increase.
|
||||
float demogametimebias; //mvd timings are weird.
|
||||
int demonudge; //
|
||||
float demopausedtilltime;//demo is paused until realtime>this
|
||||
|
||||
float minpitch;
|
||||
float maxpitch;
|
||||
|
@ -1229,6 +1231,7 @@ void CL_QTVPoll (void);
|
|||
void CL_QTVList_f (void);
|
||||
void CL_QTVDemos_f (void);
|
||||
void CL_DemoJump_f(void);
|
||||
void CL_DemoNudge_f(void);
|
||||
void CL_ProgressDemoTime(void);
|
||||
void CL_TimeDemo_f (void);
|
||||
typedef struct
|
||||
|
|
|
@ -4433,6 +4433,7 @@ typedef union
|
|||
byte_vec4_t v;
|
||||
unsigned int u;
|
||||
} pixel32_t;
|
||||
#define etc_expandv(p,x,y,z) p.v[0]|=p.v[0]>>x,p.v[1]|=p.v[1]>>y,p.v[2]|=p.v[2]>>z
|
||||
#ifdef DECOMPRESS_ETC2
|
||||
//FIXME: this is littleendian only...
|
||||
static void Image_Decode_ETC2_Block_TH_Internal(qbyte *fte_restrict in, pixel32_t *fte_restrict out, int w, pixel32_t base1, pixel32_t base2, int d, qboolean tmode)
|
||||
|
@ -4507,8 +4508,6 @@ static void Image_Decode_ETC2_Block_Internal(qbyte *fte_restrict in, pixel32_t *
|
|||
unsigned char R1,G1,B1;
|
||||
pixel32_t *out1, *out2, *out3;
|
||||
|
||||
#define etc_expandv(p,x,y,z) p.v[0]|=p.v[0]>>x,p.v[1]|=p.v[1]>>y,p.v[2]|=p.v[2]>>z
|
||||
|
||||
qboolean opaque;
|
||||
|
||||
if (alphamode)
|
||||
|
@ -4757,15 +4756,15 @@ static void Image_Decode_S3TC_Block_Internal(qbyte *fte_restrict in, pixel32_t *
|
|||
}
|
||||
static void Image_Decode_BC1_Block(qbyte *fte_restrict in, pixel32_t *fte_restrict out, int w)
|
||||
{
|
||||
Image_S3TC_Decode_Block_Internal(in, out, w, 0xff);
|
||||
Image_Decode_S3TC_Block_Internal(in, out, w, 0xff);
|
||||
}
|
||||
static void Image_Decode_BC1A_Block(qbyte *fte_restrict in, pixel32_t *fte_restrict out, int w)
|
||||
{
|
||||
Image_S3TC_Decode_Block_Internal(in, out, w, 0);
|
||||
Image_Decode_S3TC_Block_Internal(in, out, w, 0);
|
||||
}
|
||||
static void Image_Decode_BC2_Block(qbyte *fte_restrict in, pixel32_t *fte_restrict out, int w)
|
||||
{
|
||||
Image_S3TC_Decode_Block_Internal(in+8, out, w, 0xff);
|
||||
Image_Decode_S3TC_Block_Internal(in+8, out, w, 0xff);
|
||||
|
||||
//BC2 has straight 4-bit alpha.
|
||||
#define BC2_AlphaRow() \
|
||||
|
@ -4849,8 +4848,8 @@ static void Image_Decode_RGTC_Block_Internal(qbyte *fte_restrict in, qbyte *fte_
|
|||
//s3tc rgb channel, with an rgtc alpha channel that depends upon both encodings (really the origin of rgtc, but mneh).
|
||||
static void Image_Decode_BC3_Block(qbyte *fte_restrict in, pixel32_t *fte_restrict out, int w)
|
||||
{
|
||||
Image_S3TC_Decode_Block_Internal(in+8, out, w, 0xff);
|
||||
Image_RGTC_Decode_Block_Internal(in, out->v+3, w*4, false);
|
||||
Image_Decode_S3TC_Block_Internal(in+8, out, w, 0xff);
|
||||
Image_Decode_RGTC_Block_Internal(in, out->v+3, w*4, false);
|
||||
}
|
||||
#endif
|
||||
static void Image_Decode_BC4U_Block(qbyte *fte_restrict in, pixel32_t *fte_restrict out, int w)
|
||||
|
@ -5241,7 +5240,20 @@ static void Image_ChangeFormat(struct pendingtextureinfo *mips, unsigned int fla
|
|||
|
||||
//if that format isn't supported/desired, try converting it.
|
||||
if (sh_config.texfmt[mips->encoding])
|
||||
return;
|
||||
{
|
||||
if (sh_config.texture_allow_block_padding && mips->mipcount)
|
||||
{ //direct3d is annoying, and will reject any block-compressed format with a base mip size that is not a multiple of the block size.
|
||||
//its fine with weirdly sized mips though. I have no idea why there's this restriction, but whatever.
|
||||
//we need to de
|
||||
int blockbytes, blockwidth, blockheight;
|
||||
Image_BlockSizeForEncoding(mips->encoding, &blockbytes, &blockwidth, &blockheight);
|
||||
if (!(mips->mip[0].width % blockwidth) && !(mips->mip[0].height % blockheight))
|
||||
return;
|
||||
//else encoding isn't supported for this size. fall through.
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
{ //various compressed formats might not be supported.
|
||||
void *decodefunc = NULL;
|
||||
|
|
|
@ -2745,7 +2745,8 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down
|
|||
default:
|
||||
dc = keybindings[key][modifierstate];
|
||||
//toggleconsole or +showFOO keys should do their regular bind action
|
||||
if (!dc || (strcmp(dc, "toggleconsole") && strncmp(dc, "+show", 5)))
|
||||
//demo_jump/demo_setspeed/demo_nudge should be allowed too.
|
||||
if (!dc || (strcmp(dc, "toggleconsole") && strncmp(dc, "+show", 5) && strncmp(dc, "demo_", 5)))
|
||||
{
|
||||
M_ToggleMenu_f ();
|
||||
return;
|
||||
|
|
|
@ -1110,9 +1110,13 @@ static void SL_Remove (menu_t *menu)
|
|||
|
||||
static qboolean SL_DoRefresh (menuoption_t *opt, menu_t *menu, int key)
|
||||
{
|
||||
MasterInfo_Refresh();
|
||||
isrefreshing = true;
|
||||
return true;
|
||||
if (key == K_MOUSE1 || key == K_MOUSE1 || key == K_ENTER || key == K_KP_ENTER)
|
||||
{
|
||||
MasterInfo_Refresh(false);
|
||||
isrefreshing = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void M_Menu_ServerList2_f(void)
|
||||
|
@ -1249,7 +1253,7 @@ void M_Menu_ServerList2_f(void)
|
|||
|
||||
if (!Master_TotalCount())
|
||||
{
|
||||
MasterInfo_Refresh();
|
||||
MasterInfo_Refresh(true);
|
||||
isrefreshing = true;
|
||||
}
|
||||
|
||||
|
@ -1309,7 +1313,7 @@ static void M_QuickConnect_PreDraw(menu_t *menu)
|
|||
}
|
||||
|
||||
//retry
|
||||
MasterInfo_Refresh();
|
||||
MasterInfo_Refresh(false);
|
||||
isrefreshing = true;
|
||||
}
|
||||
}
|
||||
|
@ -1340,7 +1344,7 @@ void M_QuickConnect_f(void)
|
|||
|
||||
Key_Dest_Add(kdm_emenu);
|
||||
|
||||
MasterInfo_Refresh();
|
||||
MasterInfo_Refresh(false);
|
||||
isrefreshing = true;
|
||||
|
||||
quickconnecttimeout = Sys_DoubleTime() + 5;
|
||||
|
|
|
@ -351,7 +351,10 @@ qboolean Media_NamedTrack(const char *track, const char *looptrack)
|
|||
static char *ext[] =
|
||||
{
|
||||
"",
|
||||
#ifdef AVAIL_OGGVORBIS
|
||||
#if defined(AVAIL_OGGOPUS) || defined(FTE_TARGET_WEB)
|
||||
".opus",
|
||||
#endif
|
||||
#if defined(AVAIL_OGGVORBIS) || defined(FTE_TARGET_WEB)
|
||||
".ogg",
|
||||
#endif
|
||||
#if defined(AVAIL_MP3_ACM) || defined(FTE_TARGET_WEB)
|
||||
|
|
|
@ -1106,8 +1106,13 @@ void M_Menu_MediaFiles_f (void)
|
|||
info->ext[info->numext] = ".wav";
|
||||
info->command[info->numext] = "media_add";
|
||||
info->numext++;
|
||||
#if defined(AVAIL_OGGOPUS) || defined(FTE_TARGET_WEB)
|
||||
info->ext[info->numext] = ".opus";
|
||||
info->command[info->numext] = "media_add";
|
||||
info->numext++;
|
||||
#endif
|
||||
#if defined(AVAIL_OGGVORBIS) || defined(FTE_TARGET_WEB)
|
||||
info->ext[info->numext] = ".ogg"; //will this ever be added properly?
|
||||
info->ext[info->numext] = ".ogg";
|
||||
info->command[info->numext] = "media_add";
|
||||
info->numext++;
|
||||
#endif
|
||||
|
|
|
@ -1468,7 +1468,7 @@ void M_Keydown (int key, int unicode)
|
|||
if (key == K_MOUSE1) //mouse clicks are deferred until the release event. this is for touch screens and aiming.
|
||||
menu_mousedown = true;
|
||||
else if (key == K_LSHIFT || key == K_RSHIFT || key == K_LALT || key == K_RALT || key == K_LCTRL || key == K_RCTRL)
|
||||
;
|
||||
; //modifiers are sent on up events instead.
|
||||
else
|
||||
M_Complex_Key (key, unicode);
|
||||
return;
|
||||
|
|
|
@ -2618,11 +2618,18 @@ void MasterInfo_WriteServers(void)
|
|||
}
|
||||
|
||||
//poll master servers for server lists.
|
||||
void MasterInfo_Refresh(void)
|
||||
void MasterInfo_Refresh(qboolean doreset)
|
||||
{
|
||||
master_t *mast;
|
||||
serverinfo_t *info;
|
||||
qboolean loadedone;
|
||||
|
||||
if (doreset)
|
||||
{
|
||||
for (info = firstserver; info; info = info->next)
|
||||
info->status &= ~1; //hide until we get a new response from it.
|
||||
}
|
||||
|
||||
loadedone = false;
|
||||
loadedone |= Master_LoadMasterList("masters.txt", false, MT_MASTERUDP, MP_QUAKEWORLD, 5); //fte listing
|
||||
|
||||
|
|
|
@ -376,7 +376,6 @@ void QCBUILTIN PF_cl_findkeysforcommand (pubprogfuncs_t *prinst, struct globalva
|
|||
|
||||
RETURN_TSTRING(keyname);
|
||||
}
|
||||
|
||||
void QCBUILTIN PF_cl_findkeysforcommandex (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
const char *cmdname = PR_GetStringOfs(prinst, OFS_PARM0);
|
||||
|
@ -384,9 +383,7 @@ void QCBUILTIN PF_cl_findkeysforcommandex (pubprogfuncs_t *prinst, struct global
|
|||
int keynums[256];
|
||||
int keymods[countof(keynums)];
|
||||
char keyname[512];
|
||||
int i, count;
|
||||
|
||||
count = M_FindKeysForBind(bindmap, cmdname, keynums, keymods, countof(keynums));
|
||||
int i, count = M_FindKeysForBind(bindmap, cmdname, keynums, keymods, countof(keynums));
|
||||
|
||||
keyname[0] = '\0';
|
||||
|
||||
|
@ -797,7 +794,8 @@ void QCBUILTIN PF_cl_sethostcachesort(pubprogfuncs_t *prinst, struct globalvars_
|
|||
//void refreshhostcache(void) = #620;
|
||||
void QCBUILTIN PF_cl_refreshhostcache(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
MasterInfo_Refresh();
|
||||
qboolean doreset = (prinst->callargc>=1)?G_FLOAT(OFS_PARM0):false;
|
||||
MasterInfo_Refresh(doreset);
|
||||
}
|
||||
//float gethostcachenumber(float fld, float hostnr) = #621;
|
||||
void QCBUILTIN PF_cl_gethostcachenumber(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
|
|
|
@ -873,7 +873,15 @@ static void S_LoadSoundWorker (void *ctx, void *ctxdata, size_t a, size_t b)
|
|||
//Con_Printf ("S_LoadSound: %x\n", (int)stackbuf);
|
||||
// load it in
|
||||
const char *prefixes[] = {"sound/", ""};
|
||||
const char *extensions[] = {".wav", ".ogg"};
|
||||
const char *extensions[] = {
|
||||
".wav",
|
||||
#ifdef AVAIL_OGGOPUS
|
||||
".opus",
|
||||
#endif
|
||||
#ifdef AVAIL_OGGVORBIS
|
||||
".ogg",
|
||||
#endif
|
||||
};
|
||||
char altname[sizeof(namebuffer)];
|
||||
char orig[16];
|
||||
size_t pre, ex;
|
||||
|
|
|
@ -772,7 +772,7 @@ void V_CalcBlend (float *hw_blend)
|
|||
a2 = pv->cshifts[j].percent / 255.0; //don't allow modification of this one.
|
||||
}
|
||||
|
||||
if (!a2)
|
||||
if (a2 <= 0)
|
||||
continue;
|
||||
|
||||
if (j == CSHIFT_SERVER)
|
||||
|
|
|
@ -318,6 +318,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define svcfitz_spawnstatic2 43
|
||||
#define svcfitz_spawnstaticsound2 44
|
||||
|
||||
//nehahra svcs
|
||||
#define svcneh_skyboxsize 50 // [coord] size (default is 4096)
|
||||
#define svcneh_fog 51 // [byte] enable <optional past this point, only included if enable is true> [float] density [byte] red [byte] green [byte] blue
|
||||
|
||||
//DP extended svcs
|
||||
#define svcdp_downloaddata 50
|
||||
#define svcdp_updatestatbyte 51
|
||||
|
|
|
@ -35,12 +35,12 @@ qboolean D3D9_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mip
|
|||
fmt = D3DFMT_R5G6B5;
|
||||
break;
|
||||
case PTI_RGBA4444://not supported on d3d9
|
||||
return false;
|
||||
break;
|
||||
case PTI_ARGB4444:
|
||||
fmt = D3DFMT_A4R4G4B4;
|
||||
break;
|
||||
case PTI_RGBA5551://not supported on d3d9
|
||||
return false;
|
||||
break;
|
||||
case PTI_ARGB1555:
|
||||
fmt = D3DFMT_A1R5G5B5;
|
||||
break;
|
||||
|
@ -159,6 +159,8 @@ qboolean D3D9_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mip
|
|||
}
|
||||
}
|
||||
|
||||
//Microsoft's code will reject any dxt texture with a mip[0] width/height that is not a multiple of 4.
|
||||
|
||||
if (FAILED(IDirect3DDevice9_CreateTexture(pD3DDev9, mips->mip[0].width, mips->mip[0].height, mipcount, 0, fmt, D3DPOOL_MANAGED, &dt, NULL)))
|
||||
return false;
|
||||
dbt = (IDirect3DBaseTexture9*)dt;
|
||||
|
|
|
@ -597,6 +597,7 @@ void D3D9Shader_Init(void)
|
|||
|
||||
IDirect3DDevice9_GetDeviceCaps(pD3DDev9, &caps);
|
||||
|
||||
sh_config.texture_allow_block_padding = false; //microsoft blocks this.
|
||||
if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
|
||||
{ //this flag is a LIMITATION, not a capability.
|
||||
sh_config.texture_non_power_of_two = false;
|
||||
|
|
|
@ -856,6 +856,7 @@ static qboolean initD3D11Device(HWND hWnd, rendererstate_t *info, PFN_D3D11_CREA
|
|||
memset(&sh_config, 0, sizeof(sh_config));
|
||||
sh_config.texture_non_power_of_two = flevel>=D3D_FEATURE_LEVEL_10_0; //npot MUST be supported on all d3d10+ cards.
|
||||
sh_config.texture_non_power_of_two_pic = true; //always supported in d3d11, supposedly, even with d3d9 devices.
|
||||
sh_config.texture_allow_block_padding = false; //microsoft blocks this.
|
||||
sh_config.npot_rounddown = false;
|
||||
if (flevel>=D3D_FEATURE_LEVEL_11_0)
|
||||
sh_config.texture2d_maxsize = 16384;
|
||||
|
|
|
@ -504,6 +504,7 @@ void D3D8Shader_Init(void)
|
|||
|
||||
IDirect3DDevice8_GetDeviceCaps(pD3DDev8, &caps);
|
||||
|
||||
sh_config.texture_allow_block_padding = false; //microsoft blocks this.
|
||||
if (caps.TextureCaps & D3DPTEXTURECAPS_POW2)
|
||||
{ //this flag is a LIMITATION, not a capability.
|
||||
sh_config.texture_non_power_of_two = false;
|
||||
|
|
|
@ -668,6 +668,11 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
|
|||
Con_DPrintf("Anisotropic filter extension found (%dx max).\n",gl_config.ext_texture_filter_anisotropic);
|
||||
}
|
||||
|
||||
if ((!gl_config.gles && gl_config.glversion >= 2) || GL_CheckExtension("GL_ARB_texture_non_power_of_two"))
|
||||
sh_config.texture_allow_block_padding = true; //gl2/npot explicitly relaxes this restriction
|
||||
else
|
||||
sh_config.texture_allow_block_padding = false; //gles does not support padded sizes, even with gles3. This is especially true if we're running atop d3d-via-webgl.
|
||||
|
||||
if (!gl_config.gles && gl_config.glversion >= 3)
|
||||
{ //GL_ARB_texture_non_power_of_two is supposed to be mandatory in gl2+ and thus checking for it is redundant and not forwards-compatible
|
||||
//geforcefx apparently software emulates it, so only activate it unconditionally on gl3+ hardware.
|
||||
|
|
|
@ -767,6 +767,7 @@ typedef struct
|
|||
unsigned int texturecube_maxsize;
|
||||
qboolean texture_non_power_of_two; //full support for npot
|
||||
qboolean texture_non_power_of_two_pic; //npot only works with clamp-to-edge mipless images.
|
||||
qboolean texture_allow_block_padding; //mip 0 of compressed formats can be any size, with implicit padding.
|
||||
qboolean npot_rounddown; //memory limited systems can say that they want to use less ram.
|
||||
qboolean tex_env_combine;
|
||||
qboolean nv_tex_env_combine4;
|
||||
|
|
|
@ -1206,6 +1206,8 @@ pbool PDECL ED_ParseEval (pubprogfuncs_t *ppf, eval_t *eval, int type, const cha
|
|||
break;
|
||||
|
||||
case ev_entity:
|
||||
if (!strncmp(s, "entity ", 7)) //cope with etos weirdness.
|
||||
s += 7;
|
||||
eval->edict = atoi (s);
|
||||
break;
|
||||
|
||||
|
|
|
@ -10156,12 +10156,12 @@ void QCC_PR_ParseStatement (void)
|
|||
|
||||
if (QCC_PR_CheckKeyword(keyword_return, "return"))
|
||||
{
|
||||
/*if (pr_classtype)
|
||||
{
|
||||
e = QCC_PR_GetDef(NULL, "__oself", pr_scope, false, 0);
|
||||
e2 = QCC_PR_GetDef(NULL, "self", NULL, false, 0);
|
||||
QCC_FreeTemp(QCC_PR_Statement(&pr_opcodes[OP_STORE_ENT], e, QCC_PR_DummyDef(pr_classtype, "self", pr_scope, 0, e2->ofs, false), NULL));
|
||||
}*/
|
||||
/*
|
||||
accumulate behaviour requires the ability to just run code without explicit returns.
|
||||
return = foo; sets the value that will be returned when the function finally exits, without returning now.
|
||||
return; returns that value now, without execing later accumulations.
|
||||
return 5; also returns now.
|
||||
*/
|
||||
|
||||
if (QCC_PR_CheckToken (";"))
|
||||
{
|
||||
|
@ -10186,6 +10186,9 @@ void QCC_PR_ParseStatement (void)
|
|||
// if (opt_return_only)
|
||||
// QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_DONE], nullsref, nullsref, NULL));
|
||||
// else
|
||||
if (pr_scope->type->aux_type->type == ev_vector) //make sure bad returns don't return junk in the y+z members.
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_RETURN], QCC_MakeVectorConst(0,0,0), nullsref, NULL));
|
||||
else
|
||||
QCC_FreeTemp(QCC_PR_Statement (&pr_opcodes[OP_RETURN], nullsref, nullsref, NULL));
|
||||
return;
|
||||
}
|
||||
|
@ -12252,6 +12255,7 @@ void QCC_PR_FinaliseFunction(QCC_function_t *f)
|
|||
QCC_PR_ResumeFunction(f);
|
||||
|
||||
pr_token_line_last = f->line_end;
|
||||
s_filen = f->filen;
|
||||
|
||||
if (f->returndef.cast)
|
||||
{
|
||||
|
|
|
@ -10849,7 +10849,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"sethostcachemasknumber",PF_Fixme, 0, 0, 0, 617, "void(float mask, float fld, float num, float op)"},
|
||||
{"resorthostcache", PF_Fixme, 0, 0, 0, 618, "void()"},
|
||||
{"sethostcachesort",PF_Fixme, 0, 0, 0, 619, "void(float fld, float descending)"},
|
||||
{"refreshhostcache",PF_Fixme, 0, 0, 0, 620, "void()"},
|
||||
{"refreshhostcache",PF_Fixme, 0, 0, 0, 620, "void(optional float dopurge)"},
|
||||
{"gethostcachenumber",PF_Fixme, 0, 0, 0, 621, "float(float fld, float hostnr)"},
|
||||
{"gethostcacheindexforkey",PF_Fixme, 0, 0, 0, 622, "float(string key)"},
|
||||
{"addwantedhostcachekey",PF_Fixme, 0, 0, 0, 623, "void(string key)"},
|
||||
|
|
|
@ -4304,6 +4304,7 @@ qboolean VK_Init(rendererstate_t *info, const char **sysextnames, qboolean (*cre
|
|||
sh_config.minver = -1;
|
||||
sh_config.maxver = -1;
|
||||
|
||||
sh_config.texture_allow_block_padding = true;
|
||||
sh_config.texture_non_power_of_two = true; //is this always true?
|
||||
sh_config.texture_non_power_of_two_pic = true; //probably true...
|
||||
sh_config.npot_rounddown = false;
|
||||
|
|
109
specs/bspx.txt
Normal file
109
specs/bspx.txt
Normal file
|
@ -0,0 +1,109 @@
|
|||
BSPX is a format originally invented by Tonik, I believe, and is already implemented in both ezQuake and FTE.
|
||||
It is not so much a format itself, but more of an extensible way to shove additional lumps within an existing BSP.
|
||||
Typically these additional lumps will provide supplemental information or replace existing info.
|
||||
BSPX itself can logically be applied to the BSP file format of Quake, Quake II, or Quake III.
|
||||
|
||||
BSPX itself can be defined in just the following two structures:
|
||||
typedef struct {
|
||||
char lumpname[24]; // up to 23 chars, zero-padded
|
||||
int fileofs; // from file start
|
||||
int filelen;
|
||||
} bspx_lump_t;
|
||||
typedef struct {
|
||||
char id[4]; // 'BSPX'
|
||||
int numlumps;
|
||||
bspx_lump_t lumps[1];
|
||||
} bspx_header_t;
|
||||
|
||||
The bspx_header_t struct can be found immediately following the BSP's standard header. It is only valid if the standard header specifies no lump as starting at that location, and if the magic id matches.
|
||||
The engine can then walk the lump list looking for lumps that it recognises. Unknown lumps MUST be ignored.
|
||||
|
||||
|
||||
|
||||
These lumps are currently defined:
|
||||
|
||||
RGBLIGHTING:
|
||||
(applies to fte, ezquake, qss)
|
||||
This is equivelent to the information stored in a .lit file (sans header), and must contain the same number of samples as the lightmap lump would normally contain, because it doesn't make much sense otherwise.
|
||||
Presence of this lump permits omitting the regular mono lightmap to save space, but doing so will harm compatibility.
|
||||
|
||||
LIGHTING_E5BGR9:
|
||||
(applies to fte)
|
||||
This is a more advanced alternative to RGBLIGHTING.
|
||||
Each luxel is a E5BGR9 int32 packed value (ie: on little-endian machines, the exponent is the high 5 bits), resulting in what is effectively a memory-efficient floating point rgb value.
|
||||
This lightmap format virtually removes all oversaturation limits, and promises greater precision in dark areas too.
|
||||
This format is directly supported on ALL OpenGL[ES] 3.0+ gpus (aka: GL_EXT_texture_shared_exponent).
|
||||
As a floating point format, a logical value of 1.0 is considered as identity (instead of 255 being an [overbright] multiplier of 2.0).
|
||||
Lighting values are always assumed to be linear.
|
||||
|
||||
LIGHTINGDIR:
|
||||
(applies to fte)
|
||||
This lump contains surface-space light directions (read: deluxemap), equivelent to fte's .lux file, or dp's .dlit files (sans header).
|
||||
(as unorm values, these need to be biased before use).
|
||||
If bumpmaps or specular maps are not available then the effects of this may not be significant/noticable.
|
||||
|
||||
LMSHIFT:
|
||||
(applies to fte, qss)
|
||||
This is a series of per-surface bytes. Each byte provides the (1<<shift) ratio of texels-per-luxel of the corresponding surface.
|
||||
Note that the engine's per-surface lightmap size limit still applies, but any engine that supports LMSHIFT must support up to 256 luxels in either axis (note that 1 luxel is reserved for edges, so a shift of 0 requires that surfaces be subdivided to at least a 255qu boundary while a shift of 4 reduces the required subdivisions on an infinitely sized surface by a factor of 256, or to a max extent of 4080qu).
|
||||
As a result, the subdivide size argument of qbsp can limit the minimum shift value (maximum lightmap scale).
|
||||
|
||||
LMOFFSET:
|
||||
(applies to fte, qss)
|
||||
This replaces the lightmap offset value of the surface lumps. Should only be used in conjunction with LMSHIFT.
|
||||
This allows a bsp to contain both scaled surfaces and unscaled ones, without looking broken in engines that use either mode.
|
||||
|
||||
LMSTYLE:
|
||||
(applies to fte, qss)
|
||||
This replaces the four lightstyle indexes of each surface lump entry. Should only be used in conjunction with LMSHIFT.
|
||||
|
||||
VERTEXNORMALS:
|
||||
(applies to fte)
|
||||
This lump contains a series of vec3_t values. One per vertex lump entry.
|
||||
Surfaces with a texinfo flag of 0x800 will use this lump in order to determine vertex normals, otherwise they will use their plane's normal.
|
||||
These normals allow rtlights to respond to curved forms, while the flag prevents the need for excessive vertex+edge counts.
|
||||
Verticies that are not part of any 0x800 surface will not be read, and will usually hold values of 0 (if only because it compresses better).
|
||||
|
||||
BRUSHLIST:
|
||||
(applies to fte)
|
||||
Engines that utilise this lump will no longer need to use hull-based collisions.
|
||||
struct {
|
||||
unsigned int ver = 1;
|
||||
unsigned int modelnum; //inline model number. 0 for world, obviously.
|
||||
unsigned int numbrushes; //size of following array.
|
||||
unsigned int numplanes; //total count. for validation.
|
||||
struct
|
||||
{
|
||||
vec_t mins;
|
||||
vec_t maxs;
|
||||
signed short contents;
|
||||
unsigned short numplanes;
|
||||
{
|
||||
vec3_t normal;
|
||||
float dist;
|
||||
} planes[numplanes];
|
||||
} brush[numbrushes];
|
||||
} permodel[];
|
||||
A submodel could be an illusionary model with no solid surfaces. Such a model will become non-solid if there is a BRUSHLIST lump that does not name the submodel.
|
||||
Axial planes MUST NOT be written - they will be inferred from the brush's mins+maxs. This guarentees that brush expansion does not extend points beyond the brush itself, and saves size on maps made by lazy people.
|
||||
Contents values are equal to Quake's normal CONTENT_FOO values. This outbreak of lack of imagination is brought to you by a desire to avoid politics about content masks.
|
||||
CONTENTS_EMPTY = -1 //an error. pointless.
|
||||
CONTENTS_SOLID = -2 //regular solidity
|
||||
CONTENTS_WATER = -3 //required for pointcontents to work properly.
|
||||
CONTENTS_SLIME = -4 //really I'm only listing these for completeness. only the last two are 'new'.
|
||||
CONTENTS_LAVA = -5 //it burns!
|
||||
CONTENTS_SKY = -6 //nothing explodes here!
|
||||
CONTENTS_CLIP = -8 //borrowed from halflife, blocks only entities with size.
|
||||
CONTENTS_LADDER = -16 //borrowed from halflife
|
||||
Presence of this lump permits hulls 1 and 2 to be entirely omitted from the BSP (0 is still used for rendering), but doing so will harm compatibility with engines that do not understand this (presumably a solid-but-valid tree should be written, just in case). This could boost load times.
|
||||
The engine is expected to insert the brushes into the bsp's various nodes. Inserting them into the leafs is suboptimal as leaf 0 will end up containing every brush...
|
||||
|
||||
|
||||
|
||||
Other features:
|
||||
FTE supports mipmaps with all four offsets set to 0 as external textures. Such texture will ignore gl_load24bit, treating it as always enabled. This saves space and simplifies copyright ownership without resulting in untextured maps (when the textures are actually available, anyway).
|
||||
|
||||
Misc Compatibility Concerns:
|
||||
mipmap lump - mipmaps with all four offsets set to 0 are external textures and contain no actual data. Note that vanilla quake will glitch out if given such a texture, although its unlikely to crash.
|
||||
hulls - presence of BRUSHLIST allows hulls 1 and 2 to be ommitted. This will crash vanilla glquake but not winquake, and can be reproduced with the vanilla tools too.
|
||||
lightmap sizes - winquake is limited to 18*18 lightmaps. Many quake engines support up to 256*256 now (AFTER lmscale). Note that such large lightmaps are not recommended due to all the resulting texture switches.
|
|
@ -265,6 +265,7 @@ ramp <red> <green> <blue> [alpha] [scale]
|
|||
Specifies a ramp index in rgb terms, regardless of palette.
|
||||
|
||||
stains <value>
|
||||
(Not supported in QSS)
|
||||
How much the effect discolours the wall upon impact.
|
||||
The stained colour is based upon the colour of the particle upon impact.
|
||||
|
||||
|
@ -359,6 +360,7 @@ spawnvel <horiz> [vert]
|
|||
obsolete
|
||||
|
||||
viewspace [frac]
|
||||
(Not supported in QSS)
|
||||
Specifies that this particle type should move relative to the camera.
|
||||
Not compatible with splitscreen.
|
||||
Should not normally be used in combination with clipping/bouncing.
|
||||
|
@ -412,6 +414,7 @@ lightshadows <castshadows>
|
|||
lightcorona <intensity> <scale>
|
||||
|
||||
model <name> [options]
|
||||
(Not supported in QSS)
|
||||
options are:
|
||||
frame=
|
||||
framestart=
|
||||
|
@ -442,6 +445,8 @@ sound <name> [options]
|
|||
Plays a sound when the effect is spawned. Only ONE sound will be used, picked randomly from the included sounds according to their weights.
|
||||
|
||||
spawnstain <radius> <r> <g> <b>
|
||||
(Not supported in QSS)
|
||||
Controls whether a stain will be created at the same time as any particles (instead of depending upon impacts).
|
||||
|
||||
rainfrequency <multiplier>
|
||||
Specifies the interval between spawning new particle puffs on surfaces.
|
||||
|
|
Loading…
Reference in a new issue