added sys_priority cvar to the windows build.

rewrote tab completion logic. should no longer consume so much cpu time.
added tab-completion for the connect command. server lists must have been requested previously (like the connectbr command requires).
fix q1bsp fencetexture+fog combo.
fix wateralpha/lavaalpha/slimealpha/telealpha worldspawn fields.
added a couple of extra cvars to some rulesets.
fix d3d9 mipmap-size issue.
fix vid_reload issue (was crashing, but its also possible that it could have been the cause of VBO corruption).
made pausable default to empty, allowing for smarter defaults like pausing SP but not DM.
attempt to compensate for NQ's framerate-dependant waterjumps by making QW waterjumps slightly more permissive.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5241 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2018-04-15 02:48:23 +00:00
parent eb89084603
commit c4132347eb
38 changed files with 1233 additions and 438 deletions

View File

@ -1986,7 +1986,7 @@ void CL_Record_f (void)
static int QDECL CompleteDemoList (const char *name, qofs_t flags, time_t mtime, void *parm, searchpathfuncs_t *spath)
{
struct xcommandargcompletioncb_s *ctx = parm;
ctx->cb(name, ctx);
ctx->cb(name, NULL, NULL, ctx);
return true;
}
void CL_DemoList_c(int argn, const char *partial, struct xcommandargcompletioncb_s *ctx)

View File

@ -1233,6 +1233,7 @@ CL_Connect_f
================
*/
void CL_Connect_c(int argn, const char *partial, struct xcommandargcompletioncb_s *ctx);
void CL_Connect_f (void)
{
char *server;
@ -1492,9 +1493,9 @@ void CL_ResetFog(int ftype)
memset(&cl.fog[ftype], 0, sizeof(cl.fog[ftype]));
cl.fog[ftype].time = realtime;
cl.fog[ftype].density = 0;
cl.fog[ftype].colour[0] = 0.3;
cl.fog[ftype].colour[1] = 0.3;
cl.fog[ftype].colour[2] = 0.3;
cl.fog[ftype].colour[0] = //SRGBf(0.3);
cl.fog[ftype].colour[1] = //SRGBf(0.3);
cl.fog[ftype].colour[2] = SRGBf(0.3);
cl.fog[ftype].alpha = 1;
cl.fog[ftype].depthbias = 0;
/*
@ -3962,20 +3963,20 @@ void CL_Fog_f(void)
break;
case 3:
cl.fog[ftype].density = atof(Cmd_Argv(1));
cl.fog[ftype].colour[0] = cl.fog[ftype].colour[1] = cl.fog[ftype].colour[2] = atof(Cmd_Argv(2));
cl.fog[ftype].colour[0] = cl.fog[ftype].colour[1] = cl.fog[ftype].colour[2] = SRGBf(atof(Cmd_Argv(2)));
break;
case 4:
cl.fog[ftype].density = 0.05; //make something up for vauge compat with fitzquake, so it doesn't get the default of 0
cl.fog[ftype].colour[0] = atof(Cmd_Argv(1));
cl.fog[ftype].colour[1] = atof(Cmd_Argv(2));
cl.fog[ftype].colour[2] = atof(Cmd_Argv(3));
cl.fog[ftype].colour[0] = SRGBf(atof(Cmd_Argv(1)));
cl.fog[ftype].colour[1] = SRGBf(atof(Cmd_Argv(2)));
cl.fog[ftype].colour[2] = SRGBf(atof(Cmd_Argv(3)));
break;
case 5:
default:
cl.fog[ftype].density = atof(Cmd_Argv(1));
cl.fog[ftype].colour[0] = atof(Cmd_Argv(2));
cl.fog[ftype].colour[1] = atof(Cmd_Argv(3));
cl.fog[ftype].colour[2] = atof(Cmd_Argv(4));
cl.fog[ftype].colour[0] = SRGBf(atof(Cmd_Argv(2)));
cl.fog[ftype].colour[1] = SRGBf(atof(Cmd_Argv(3)));
cl.fog[ftype].colour[2] = SRGBf(atof(Cmd_Argv(4)));
break;
}
@ -4357,13 +4358,22 @@ void CL_Init (void)
Cmd_AddCommandD ("quit", CL_Quit_f, "Use this command when you get angry. Does not save any cvars. Use cfg_save to save settings, or use the menu for a prompt.");
#if defined(CL_MASTER)
Cmd_AddCommandD ("connectbr", CL_ConnectBestRoute_f, "connect address:port\nConnect to a qw server using the best route we can detect.");
Cmd_AddCommandAD ("connectbr", CL_ConnectBestRoute_f, CL_Connect_c, "connect address:port\nConnect to a qw server using the best route we can detect.");
#endif
Cmd_AddCommandD ("connect", CL_Connect_f, "connect scheme://address:port\nConnect to a server. "
Cmd_AddCommandAD("connect", CL_Connect_f, CL_Connect_c, "connect scheme://address:port\nConnect to a server. "
#if defined(FTE_TARGET_WEB)
"Use a scheme of ws:// or wss:// to connect via using websockets."
#else
"Use a scheme of rtc[s]://broker/gamename to connect via a webrtc broker."
"Use a scheme of ws[s]://server to connect via websockets."
#elif defined(TCPCONNECT)
"Use a scheme of tcp:// or tls:// to connect via non-udp protocols."
// "Use a scheme of ws[s]://server to connect via websockets."
#endif
#ifdef HAVE_DTLS
"Use a scheme of dtls://server to connect securely."
#endif
#if defined(IRCCONNECT)
"Use irc://network:6667/user[@channel] to connect via an irc server. Not recommended."
#endif
#if defined(NQPROT) || defined(Q2CLIENT) || defined(Q3CLIENT)
"\nDefault port is port "STRINGIFY(PORT_DEFAULTSERVER)"."
@ -4383,17 +4393,17 @@ void CL_Init (void)
);
Cmd_AddCommandD ("cl_transfer", CL_Transfer_f, "Connect to a different server, disconnecting from the current server only when the new server replies.");
#ifdef TCPCONNECT
Cmd_AddCommandD ("tcpconnect", CL_TCPConnect_f, "Connect to a server using the tcp:// prefix");
Cmd_AddCommandAD ("tcpconnect", CL_TCPConnect_f, CL_Connect_c, "Connect to a server using the tcp:// prefix");
#endif
#ifdef IRCCONNECT
Cmd_AddCommand ("ircconnect", CL_IRCConnect_f);
#endif
#ifdef NQPROT
Cmd_AddCommandD ("nqconnect", CLNQ_Connect_f, "Connects to the specified server, defaulting to port "STRINGIFY(PORT_NQSERVER)".");
Cmd_AddCommandD ("nqconnect", CLNQ_Connect_f, "Connects to the specified server, defaulting to port "STRINGIFY(PORT_NQSERVER)". Otherwise identical to the connect command.");
#endif
Cmd_AddCommand ("reconnect", CL_Reconnect_f);
Cmd_AddCommand ("join", CL_Join_f);
Cmd_AddCommand ("observe", CL_Observe_f);
Cmd_AddCommandAD ("join", CL_Join_f, CL_Connect_c, "Switches away from spectator mode, optionally connecting to a different server.");
Cmd_AddCommandAD ("observe", CL_Observe_f, CL_Connect_c, "Switches to spectator mode, optionally connecting to a different server.");
Cmd_AddCommand ("rcon", CL_Rcon_f);
Cmd_AddCommand ("packet", CL_Packet_f);
@ -4405,10 +4415,9 @@ void CL_Init (void)
Cmd_AddCommand ("color", CL_Color_f);
Cmd_AddCommand ("download", CL_Download_f);
Cmd_AddCommand ("dlsize", CL_DownloadSize_f);
Cmd_AddCommand ("nextul", CL_NextUpload);
Cmd_AddCommand ("stopul", CL_StopUpload);
Cmd_AddCommandD ("dlsize", CL_DownloadSize_f, "For internal use");
Cmd_AddCommandD ("nextul", CL_NextUpload, "For internal use");
Cmd_AddCommandD ("stopul", CL_StopUpload, "For internal use");
Cmd_AddCommand ("skipdl", CL_SkipDownload_f);
Cmd_AddCommand ("finishdl", CL_FinishDownload_f);
@ -4427,8 +4436,6 @@ void CL_Init (void)
Cmd_AddCommand ("topten", NULL);
Cmd_AddCommandD ("fog", CL_Fog_f, "fog <density> <red> <green> <blue> <alpha> <depthbias>");
Cmd_AddCommandD ("waterfog", CL_Fog_f, "waterfog <density> <red> <green> <blue> <alpha> <depthbias>");
Cmd_AddCommand ("kill", NULL);
Cmd_AddCommand ("pause", NULL);
Cmd_AddCommand ("say", CL_Say_f);
@ -4441,6 +4448,8 @@ void CL_Init (void)
Cmd_AddCommand ("serverinfo", CL_ServerInfo_f);
#endif
Cmd_AddCommandD ("fog", CL_Fog_f, "fog <density> <red> <green> <blue> <alpha> <depthbias>");
Cmd_AddCommandD ("waterfog", CL_Fog_f, "waterfog <density> <red> <green> <blue> <alpha> <depthbias>");
Cmd_AddCommand ("skygroup", CL_Skygroup_f);
//
// Windows commands

View File

@ -31,6 +31,9 @@ enum masterprotocol_e
#define SS_KEEPINFO (1<<6u)
#define SS_PROXY (1<<7u)
#define PING_DEAD 0xffff //default ping value to denote servers that are not responding.
#define PING_MAX 0xfffe //default ping value to denote servers that are not responding.
//despite not supporting nq or q2, we still load them. We just filter them. This is to make sure we properly write the listing files.
enum mastertype_e

View File

@ -1610,6 +1610,21 @@ void CL_RequestNextDownload (void)
stage = CL_LoadSounds(stage, true);
total_loading_size = stage;
cl.contentstage = 0;
//might be safer to do it later, but kinder to do it before wasting time.
if (!FS_PureOkay())
{
#ifdef HAVE_MEDIA_ENCODER
if (cls.demoplayback && Media_Capturing())
{
Con_Printf(CON_ERROR "Aborting capture\n");
CL_StopPlayback();
}
#endif
SCR_SetLoadingStage(LS_NONE);
CL_Disconnect();
return;
}
}
stage = 0;
@ -8038,9 +8053,9 @@ void CLNQ_ParseServerMessage (void)
case svcfitz_fog:
CL_ResetFog(0);
cl.fog[0].density = MSG_ReadByte()/255.0f;
cl.fog[0].colour[0] = MSG_ReadByte()/255.0f;
cl.fog[0].colour[1] = MSG_ReadByte()/255.0f;
cl.fog[0].colour[2] = MSG_ReadByte()/255.0f;
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 += ((unsigned short)MSG_ReadShort()) / 100.0;
cl.fog_locked = !!cl.fog[0].density;
break;

View File

@ -483,12 +483,14 @@ void CL_CalcCrouch (playerview_t *pv)
return;
}
//check if we moved in the x/y axis. if we didn't then we're on a moving platform and shouldn't be crouching.
/* VectorMA(pv->oldorigin, pv->oldz-orgz, pv->gravitydir, pv->oldorigin);
/*fixme: this helps lifts with cl_nopred, but seems to harm ramps slightly, might just be my imagination. I guess we need to check last frame too.
//check if we moved in the x/y axis. if we didn't then we're on a vertically moving platform and shouldn't be crouching.
VectorMA(pv->oldorigin, pv->oldz-orgz, pv->gravitydir, pv->oldorigin);
VectorSubtract(pv->simorg, pv->oldorigin, delta);
if (Length(delta)<0.001)
pv->oldz = orgz;
*/
VectorCopy (pv->simorg, pv->oldorigin);

View File

@ -65,6 +65,7 @@ cvar_t con_notify_y = CVAR("con_notify_y","0");
cvar_t con_notify_w = CVAR("con_notify_w","1");
cvar_t con_centernotify = CVAR("con_centernotify", "0");
cvar_t con_displaypossibilities = CVAR("con_displaypossibilities", "1");
cvar_t con_showcompletion = CVAR("con_showcompletion", "1");
cvar_t con_maxlines = CVAR("con_maxlines", "1024");
cvar_t cl_chatmode = CVARD("cl_chatmode", "2", "0(nq) - everything is assumed to be a console command. prefix with 'say', or just use a messagemode bind\n1(q3) - everything is assumed to be chat, unless its prefixed with a /\n2(qw) - anything explicitly recognised as a command will be used as a command, anything unrecognised will be a chat message.\n/ prefix is supported in all cases.\nctrl held when pressing enter always makes any implicit chat into team chat instead.");
cvar_t con_numnotifylines_chat = CVAR("con_numnotifylines_chat", "8");
@ -1293,7 +1294,7 @@ int Con_DrawInput (console_t *con, qboolean focused, int left, int right, int y,
i = 0;
x = left;
if (con->commandcompletion)
if (con->commandcompletion && con_)
{
if (cl_chatmode.ival && (text[0] == '/' || (cl_chatmode.ival == 2 && Cmd_IsCommand(text))))
{ //color the first token yellow, it's a valid command
@ -1310,7 +1311,7 @@ int Con_DrawInput (console_t *con, qboolean focused, int left, int right, int y,
fname = Cmd_CompleteCommand(text+cmdstart, true, true, con_commandmatch, NULL);
if (fname && strlen(fname) < 256) //we can compleate it to:
{
for (p = min(strlen(fname), key_linepos-cmdstart); fname[p]>' '; p++)
for (p = min(strlen(fname), key_linepos-cmdstart); fname[p]>0; p++)
textstart[p+cmdstart] = (unsigned int)fname[p] | (COLOR_GREEN<<CON_FGSHIFT);
if (p < key_linepos-cmdstart)
p = key_linepos-cmdstart;
@ -1389,9 +1390,10 @@ int Con_DrawInput (console_t *con, qboolean focused, int left, int right, int y,
if (con_commandmatch && con_displaypossibilities.value)
{
conchar_t *end, *s;
char *cmd;//, *desc;
const char *cmd;//, *desc;
int cmdstart;
size_t newlen;
cmd_completion_t *c;
cmdstart = text[0] == '/'?1:0;
end = maskedtext;
@ -1405,31 +1407,26 @@ int Con_DrawInput (console_t *con, qboolean focused, int left, int right, int y,
}
con->completionline->length = 0;
for (i = 1; ; i++)
c = Cmd_Complete(text+cmdstart, true);
for (i = 0; i < c->num; i++)
{
cmd = Cmd_CompleteCommand (text+cmdstart, true, true, i, NULL);//&desc);
if (!cmd)
{
if (i <= 2)
con_commandmatch = 0;
break;
}
if (i == 50)
{
s = (conchar_t*)(con->completionline+1);
end = COM_ParseFunString((COLOR_WHITE<<CON_FGSHIFT), va("MORE"), s+con->completionline->length, (con->completionline->maxlength-con->completionline->length)*sizeof(maskedtext[0]), true);
con->completionline->length = end - s;
break;
}
s = (conchar_t*)(con->completionline+1);
cmd = c->completions[i].text;
// desc = c->completions[i].desc;
// if (desc)
// end = COM_ParseFunString((COLOR_GREEN<<CON_FGSHIFT), va("^[^2/%s\\tip\\%s^]\t", cmd, desc), s+con->completionline->length, (con->completionline->maxlength-con->completionline->length)*sizeof(maskedtext[0]), true);
// else
end = COM_ParseFunString((COLOR_GREEN<<CON_FGSHIFT), va("^[^2/%s^]\t", cmd), s+con->completionline->length, (con->completionline->maxlength-con->completionline->length)*sizeof(maskedtext[0]), true);
con->completionline->length = end - s;
}
if (c->extra)
{
s = (conchar_t*)(con->completionline+1);
end = COM_ParseFunString((COLOR_WHITE<<CON_FGSHIFT), va("%u MORE", (unsigned)c->extra), s+con->completionline->length, (con->completionline->maxlength-con->completionline->length)*sizeof(maskedtext[0]), true);
con->completionline->length = end - s;
}
if (con->completionline->length)
y = Con_DrawConsoleLines(con, con->completionline, left, right, y, 0, selactive, selsx, selex, selsy, seley, 0);

View File

@ -337,12 +337,11 @@ int PaddedPrint (char *s, int x)
}
int con_commandmatch;
void CompleteCommand (qboolean force)
void Key_UpdateCompletionDesc(void)
{
char *cmd, *s;
const char *desc;
s = key_lines[edit_line];
cmd_completion_t *c;
const char *s = key_lines[edit_line];
if (*s == ' ' || *s == '\t')
s++;
if (*s == '\\' || *s == '/')
@ -350,68 +349,20 @@ void CompleteCommand (qboolean force)
if (*s == ' ' || *s == '\t')
s++;
//check for singular matches and complete if found
cmd = force?NULL:Cmd_CompleteCommand (s, true, true, 2, NULL);
if (!cmd)
{
if (!force)
cmd = Cmd_CompleteCommand (s, false, true, 1, &desc);
else
cmd = Cmd_CompleteCommand (s, true, true, con_commandmatch, &desc);
if (cmd)
{
if (strlen(cmd) < strlen(s))
return;
//complete to that (maybe partial) cmd.
Key_ClearTyping();
Key_ConsoleInsert("/");
Key_ConsoleInsert(cmd);
s = key_lines[edit_line]+1;
//if its the only match, add a space ready for arguments.
cmd = Cmd_CompleteCommand (s, true, true, 0, NULL);
if (cmd && !strcmp(s, cmd))
{
Key_ConsoleInsert(" ");
}
if (!con_commandmatch)
con_commandmatch = 1;
if (desc)
Con_Footerf(NULL, false, "%s: %s", cmd, desc);
else
Con_Footerf(NULL, false, "");
return;
}
}
//complete to a partial match.
cmd = Cmd_CompleteCommand (s, false, true, 0, &desc);
if (cmd)
{
int i = key_lines[edit_line][0] == '/'?1:0;
if (i != 1 || strcmp(key_lines[edit_line]+i, cmd))
{ //if successful, use that instead.
Key_ClearTyping();
Key_ConsoleInsert("/");
Key_ConsoleInsert(cmd);
s = key_lines[edit_line]; //readjust to cope with the insertion of a /
if (*s == '\\' || *s == '/')
s++;
}
}
con_commandmatch++;
cmd = Cmd_CompleteCommand(s, true, true, con_commandmatch, &desc);
if (!cmd)
{
c = Cmd_Complete(s, true);
if (!con_commandmatch || con_commandmatch > c->num)
con_commandmatch = 1;
cmd = Cmd_CompleteCommand(s, true, true, con_commandmatch, &desc);
}
if (cmd)
if (con_commandmatch <= c->num)
{
cvar_t *var = Cvar_FindVar(cmd);
const char *cmd;
cvar_t *var;
if (c->completions[con_commandmatch-1].repl)
cmd = c->completions[con_commandmatch-1].repl;
else
cmd = c->completions[con_commandmatch-1].text;
desc = c->completions[con_commandmatch-1].desc;
var = Cvar_FindVar(cmd);
if (var)
{
if (desc)
@ -434,6 +385,88 @@ void CompleteCommand (qboolean force)
}
}
void CompleteCommand (qboolean force)
{
const char *cmd, *s;
const char *desc;
cmd_completion_t *c;
s = key_lines[edit_line];
if (*s == ' ' || *s == '\t')
s++;
if (*s == '\\' || *s == '/')
s++;
if (*s == ' ' || *s == '\t')
s++;
//check for singular matches and complete if found
c = Cmd_Complete(s, true);
if (c->num == 1 || force)
{
desc = NULL;
if (!force && c->num != 1)
cmd = c->guessed;
else if (c->num)
{
int idx = max(0, con_commandmatch-1);
if (c->completions[idx].repl)
cmd = c->completions[idx].repl;
else
cmd = c->completions[idx].text;
}
else
cmd = NULL;
if (cmd)
{
if (strlen(cmd) < strlen(s))
return;
//complete to that (maybe partial) cmd.
Key_ClearTyping();
Key_ConsoleInsert("/");
Key_ConsoleInsert(cmd);
s = key_lines[edit_line];
if (*s == '/')
s++;
//if its the only match, add a space ready for arguments.
c = Cmd_Complete(s, true);
cmd = ((c->num >= 1)?(c->completions[0].repl?c->completions[0].repl:c->completions[0].text):NULL);
desc = ((c->num >= 1)?c->completions[0].desc:NULL);
if (c->num == 1)
Key_ConsoleInsert(" ");
if (!con_commandmatch)
con_commandmatch = 1;
if (desc)
Con_Footerf(NULL, false, "%s: %s", cmd, desc);
else
Con_Footerf(NULL, false, "");
return;
}
}
//complete to a partial match.
cmd = c->guessed;
if (cmd)
{
int i = key_lines[edit_line][0] == '/'?1:0;
if (i != 1 || strcmp(key_lines[edit_line]+i, cmd))
{ //if successful, use that instead.
Key_ClearTyping();
Key_ConsoleInsert("/");
Key_ConsoleInsert(cmd);
s = key_lines[edit_line]; //readjust to cope with the insertion of a /
if (*s == '\\' || *s == '/')
s++;
}
}
con_commandmatch++;
Key_UpdateCompletionDesc();
}
int Con_Navigate(console_t *con, char *line)
{
if (con->backshader)
@ -1266,8 +1299,12 @@ qboolean Key_EntryLine(unsigned char **line, int lineoffset, int *linepos, int k
memmove((*line)+*linepos-charlen, (*line)+*linepos, strlen((*line)+*linepos)+1);
*linepos -= charlen;
}
if (!(*line)[lineoffset]) //oops?
con_commandmatch = 0;
if (con_commandmatch)
{
Con_Footerf(NULL, false, "");
con_commandmatch = 1;
}
return true;
}
@ -1579,14 +1616,16 @@ qboolean Key_Console (console_t *con, unsigned int unicode, int key)
if (con_commandmatch)
{ //if that isn't actually a command, and we can actually complete it to something, then lets try to complete it.
char *txt = key_lines[edit_line]+1;
char *txt = key_lines[edit_line];
if (*txt == '/')
txt++;
if (!Cmd_IsCommand(txt) && !Cmd_CompleteCommand(txt, true, true, con_commandmatch, NULL))
if (!Cmd_IsCommand(txt) && Cmd_CompleteCommand(txt, true, true, con_commandmatch, NULL))
{
CompleteCommand (true);
return true;
}
Con_Footerf(con, false, "");
con_commandmatch = 0;
}
@ -1598,7 +1637,6 @@ qboolean Key_Console (console_t *con, unsigned int unicode, int key)
history_line = edit_line;
}
}
con_commandmatch = 0;
Z_Free(key_lines[edit_line]);
key_lines[edit_line] = BZ_Malloc(1);
@ -1609,7 +1647,7 @@ qboolean Key_Console (console_t *con, unsigned int unicode, int key)
if (key == K_SPACE && ctrl && con->commandcompletion)
{
char *txt = key_lines[edit_line]+1;
char *txt = key_lines[edit_line];
if (*txt == '/')
txt++;
if (Cmd_CompleteCommand(txt, true, true, con->commandcompletion, NULL))
@ -2003,7 +2041,7 @@ void Key_Bind_c(int argn, const char *partial, struct xcommandargcompletioncb_s
for (kn=keynames ; kn->name ; kn++)
{
if (!Q_strncasecmp(partial,kn->name, len))
ctx->cb(kn->name, ctx);
ctx->cb(kn->name, NULL, NULL, ctx);
}
}
/*

View File

@ -890,8 +890,8 @@ qboolean Master_PassesMasks(serverinfo_t *a)
// qboolean enabled;
//always filter out dead unresponsive servers.
// if (!(a->status & 1))
// return false;
if (!(a->status & 1))
return false;
/* switch(a->special & SS_PROTOCOLMASK)
{
@ -1309,7 +1309,7 @@ static void Master_FloodRoute(serverinfo_t *node)
struct peers_s *peer = node->peers;
for (i = 0; i < node->numpeers; i++, peer++)
{
if (peer->ping)
if (peer->ping && peer->ping != PING_DEAD)
if ((unsigned int)(peer->peer->cost) > (unsigned int)(node->cost + peer->ping))
{ //we found a shorter route. flood into it.
peer->peer->prevpeer = node;
@ -2305,7 +2305,7 @@ void MasterInfo_ProcessHTTP(struct dl_download *dl)
#endif
info->refreshtime = 0;
info->ping = 0xffff;
info->ping = PING_DEAD;
snprintf(info->name, sizeof(info->name), "%s h", NET_AdrToString(adrbuf, sizeof(adrbuf), &info->adr));
@ -2406,7 +2406,7 @@ char *jsonnode(int level, char *node)
else
{
info = Z_Malloc(sizeof(serverinfo_t));
info->ping = 0xffff;
info->ping = PING_DEAD;
info->adr = adr;
info->sends = 1;
info->special = flags;
@ -2644,7 +2644,7 @@ void MasterInfo_Refresh(void)
#endif
#ifdef NQPROT
Master_AddMasterHTTP("http://www.gameaholic.com/servers/qspy-quake", MT_MASTERHTTP, MP_NETQUAKE, "gameaholic's NQ master");
Master_AddMasterHTTP("http://servers.quakeone.com/index.php?format=json", MT_MASTERHTTPJSON, MP_NETQUAKE, "quakeone's server listing");
// Master_AddMasterHTTP("http://servers.quakeone.com/index.php?format=json", MT_MASTERHTTPJSON, MP_NETQUAKE, "quakeone's server listing");
Master_AddMaster("255.255.255.255:"STRINGIFY(PORT_NQSERVER), MT_BCAST, MP_NETQUAKE, "Nearby Quake1 servers");
Master_AddMaster("255.255.255.255:"STRINGIFY(PORT_NQSERVER), MT_BCAST, MP_DPMASTER, "Nearby DarkPlaces servers");
#endif
@ -2980,7 +2980,7 @@ int CL_ReadServerInfo(char *msg, enum masterprotocol_e prototype, qboolean favor
//server replied from a broadcast message, make sure we ping it to retrieve its actual ping
info->sends = 1;
info->ping = 0xffff; //not known
info->ping = PING_DEAD; //not known
info->special |= SS_LOCAL;
}
else
@ -2989,8 +2989,8 @@ int CL_ReadServerInfo(char *msg, enum masterprotocol_e prototype, qboolean favor
if (info->refreshtime)
{
ping = (Sys_DoubleTime() - info->refreshtime)*1000;
if (ping > 0xfffe)
info->ping = 0xfffe; //highest (that is known)
if (ping > PING_MAX)
info->ping = PING_MAX; //highest (that is known)
else
info->ping = ping;
}
@ -3048,7 +3048,7 @@ int CL_ReadServerInfo(char *msg, enum masterprotocol_e prototype, qboolean favor
peer->peer->sends = 1;
peer->peer->special = SS_QUAKEWORLD;
peer->peer->refreshtime = 0;
peer->peer->ping = 0xffff;
peer->peer->ping = PING_DEAD;
peer->peer->next = firstserver;
snprintf(peer->peer->name, sizeof(peer->peer->name), "%s p", NET_AdrToString(adr, sizeof(adr), &pa));
firstserver = peer->peer;
@ -3427,7 +3427,7 @@ void CL_MasterListParse(netadrtype_t adrtype, int type, qboolean slashpad)
default:
break;
}
info->ping = 0xffff;
info->ping = PING_DEAD;
p1 = MSG_ReadByte();
p2 = MSG_ReadByte();
@ -3463,5 +3463,41 @@ void CL_MasterListParse(netadrtype_t adrtype, int type, qboolean slashpad)
firstserver = last;
}
void CL_Connect_c(int argn, const char *partial, struct xcommandargcompletioncb_s *ctx)
{
serverinfo_t *info;
char buf[512];
int len;
if (argn == 1)
{
len = strlen(partial);
if (len > 1 && partial[len-1] == '\"')
len--;
for (info = firstserver; info; info = info->next)
{
if (info->ping != PING_DEAD)
{
if (len && !Q_strncasecmp(partial, info->name, len))
{
ctx->cb(info->name, va("^[%s^], %i players, %i ping", info->name, info->players, info->ping), NET_AdrToString(buf, sizeof(buf), &info->adr), ctx);
continue;
}
NET_AdrToString(buf, sizeof(buf), &info->adr);
//there are too many meaningless servers out there, so only suggest IP addresses if those servers are actually significant (ie: active, or favourite)
if (!strncmp(partial, buf, len))
{
if (info->players || (info->special & SS_FAVORITE) || NET_ClassifyAddress(&info->adr, NULL)<=ASCOPE_LAN || len == strlen(buf))
{
ctx->cb(buf, va("^[%s^], %i players, %i ping", info->name, info->players, info->ping), NULL, ctx);
continue;
}
}
}
}
}
}
#endif

View File

@ -3683,6 +3683,9 @@ void Surf_LightmapMode(void)
}
if (cl.worldmodel->deluxdata)
rgb = true;
if (cl.worldmodel->terrain) //the terrain code can't deal with extended lightmap formats.
hdr = false;
}
if (sh_config.texfmt[PTI_E5BGR9] && hdr)

View File

@ -1494,6 +1494,28 @@ void Sys_Register_File_Associations_f(void)
{
Sys_DoFileAssociations(0);
}
static void QDECL Sys_Priority_Changed(cvar_t *var, char *oldval)
{
HANDLE h = GetCurrentProcess();
DWORD pc;
if (var->ival >= 3)
pc = REALTIME_PRIORITY_CLASS;
else if (var->ival >= 2)
pc = HIGH_PRIORITY_CLASS;
else if (var->ival >= 1)
pc = ABOVE_NORMAL_PRIORITY_CLASS;
else if (var->ival >= 0)
pc = NORMAL_PRIORITY_CLASS;
else if (var->ival >= -1)
pc = BELOW_NORMAL_PRIORITY_CLASS;
else
pc = IDLE_PRIORITY_CLASS;
SetPriorityClass(h, pc);
}
static cvar_t sys_priority = CVARFCD("sys_highpriority", "0", CVAR_NOTFROMSERVER, Sys_Priority_Changed, "Controls the process priority");
/*
================
Sys_Init
@ -1507,6 +1529,8 @@ void Sys_Init (void)
Sys_QueryDesktopParameters();
Cvar_Register(&sys_priority, "System vars");
#ifndef SERVERONLY
Cvar_Register(&sys_disableWinKeys, "System vars");
Cvar_Register(&sys_disableTaskSwitch, "System vars");

View File

@ -391,11 +391,13 @@ rulesetrule_t rulesetrules_strict[] = {
{"ruleset_allow_in", "0"},
{"r_projection", "0"},
{"gl_shadeq1_name", "*"},
{"cl_iDrive", "0"},
{NULL}
};
rulesetrule_t rulesetrules_nqr[] = {
{"ruleset_allow_larger_models", "0"},
{"ruleset_allow_watervis", "0"}, /*block seeing through turbs, as well as all our cool graphics stuff. apparently we're not allowed.*/
{"ruleset_allow_overlong_sounds", "0"},
{"ruleset_allow_particle_lightning", "0"},
{"ruleset_allow_packet", "0"},
@ -411,6 +413,7 @@ rulesetrule_t rulesetrules_nqr[] = {
{"ruleset_allow_in", "0"},
{"r_projection", "0"},
{"gl_shadeq1_name", "*"},
{"cl_iDrive", "0"},
{NULL}
};

View File

@ -851,26 +851,26 @@ void Mod_ParseInfoFromEntityLump(model_t *wmodel) //actually, this should be in
{
cvar_t *var = Cvar_FindVar(key+5);
if (var && !(var->flags & CVAR_NOTFROMSERVER))
Cvar_LockFromServer(var, com_token);
Cvar_LockFromServer(var, token);
}
else if (!strcmp("wateralpha", key)) //override cvars so mappers don't end up hacking cvars and fucking over configs (at least in other engines).
{
Cvar_LockFromServer(&r_wateralpha, com_token);
Cvar_LockFromServer(&r_wateralpha, token);
Cvar_LockFromServer(&r_waterstyle, "1"); //force vanilla-style water too.
}
else if (!strcmp("slimealpha", key))
{
Cvar_LockFromServer(&r_slimealpha, com_token);
Cvar_LockFromServer(&r_slimealpha, token);
Cvar_LockFromServer(&r_slimestyle, "1");
}
else if (!strcmp("lavaalpha", key))
{
Cvar_LockFromServer(&r_lavaalpha, com_token);
Cvar_LockFromServer(&r_lavaalpha, token);
Cvar_LockFromServer(&r_lavastyle, "1");
}
else if (!strcmp("telealpha", key))
{
Cvar_LockFromServer(&r_telealpha, com_token);
Cvar_LockFromServer(&r_telealpha, token);
Cvar_LockFromServer(&r_telestyle, "1");
}
else if (!strcmp("skyname", key)) // for HalfLife maps

View File

@ -811,7 +811,7 @@ void Cmd_Exec_f (void)
static int QDECL CompleteExecList (const char *name, qofs_t flags, time_t mtime, void *parm, searchpathfuncs_t *spath)
{
struct xcommandargcompletioncb_s *ctx = parm;
ctx->cb(name, ctx);
ctx->cb(name, NULL, NULL, ctx);
return true;
}
void Cmd_Exec_c(int argn, const char *partial, struct xcommandargcompletioncb_s *ctx)
@ -868,7 +868,7 @@ static void Key_Alias_c(int argn, const char *partial, struct xcommandargcomplet
for (a = cmd_alias ; a ; a=a->next)
{
if (!Q_strncasecmp(partial,a->name, len))
ctx->cb(a->name, ctx);
ctx->cb(a->name, a->value, NULL, ctx);
}
}
static void Cmd_ShowAlias_f (void)
@ -2183,107 +2183,193 @@ const char *Cmd_Describe (const char *cmd_name)
Cmd_CompleteCommand
============
*/
typedef struct {
int matchnum;
qboolean allowcutdown;
qboolean cutdown;
char result[256];
const char *desc;
} match_t;
void Cmd_CompleteCheck(const char *check, match_t *match, const char *desc) //compare cumulative strings and join the result
{
if (*match->result)
{
char *r;
if (match->allowcutdown)
{
for(r = match->result; *r == *check && *r; r++, check++)
;
*r = '\0';
match->cutdown = true;
if (match->matchnum > 0)
match->matchnum--;
}
else if (match->matchnum > 0)
{
strcpy(match->result, check);
match->desc = desc;
match->matchnum--;
}
}
else
{
if (match->matchnum > 0)
match->matchnum--;
strcpy(match->result, check);
match->desc = desc;
}
}
struct cmdargcompletionctx_s
struct cmdargcompletion_ctx_s
{
struct xcommandargcompletioncb_s cb;
cmd_function_t *cmd;
const char *prefix;
size_t prefixlen;
match_t *match;
qboolean quoted;
cmd_completion_t *res;
const char *desc;
};
void Cmd_CompleteCheckArg(const char *value, struct xcommandargcompletioncb_s *vctx) //compare cumulative strings and join the result
static fte_inline int Q_tolower(char c)
{
struct cmdargcompletionctx_s *ctx = (struct cmdargcompletionctx_s*)vctx;
match_t *match = ctx->match;
const char *desc = ctx->desc;
if (c >= 'a' && c <= 'z')
c -= ('a' - 'A');
return c;
}
void Cmd_Complete_CheckArg(const char *value, const char *desc, const char *repl, struct xcommandargcompletioncb_s *vctx) //compare cumulative strings and join the result
{
struct cmdargcompletion_ctx_s *ctx = (struct cmdargcompletion_ctx_s*)vctx;
cmd_completion_t *res = ctx->res;
char *text;
if (ctx->prefixlen >= countof(match->result)-1)
return; //don't allow overflows.
const char *c;
char *p;
char quoted[8192];
if (*match->result)
if (!desc) //if no arg desc, use the command's.
desc = ctx->desc;
if (strchr(value, ' ') || strchr(value, '\t') || strchr(value, '\"') || strchr(value, '\r') || strchr(value, '\n'))
{
char *r;
const char *check;
if (match->allowcutdown)
{
for(r = match->result, check=ctx->prefix; check < ctx->prefix+ctx->prefixlen && *r == *check && *r; r++, check++)
;
if (check == ctx->prefix+ctx->prefixlen)
{
for(check=value; *r == *check && *r; r++, check++)
;
}
*r = '\0';
match->cutdown = true;
if (match->matchnum > 0)
match->matchnum--;
}
else if (match->matchnum > 0)
{
memcpy(match->result, ctx->prefix, ctx->prefixlen);
Q_strncpyz(match->result+ctx->prefixlen, value, sizeof(match->result)-ctx->prefixlen);
match->desc = desc;
match->matchnum--;
}
if (/*ctx->prefix[ctx->prefixlen] &&*/ !ctx->quoted) //FIXME... Figure out some way to insert quotes earlier in the completion without it bugging out
return;
}
if (ctx->quoted)
{
value = COM_QuotedString(value, quoted, sizeof(quoted), false);
value++;
}
if (!res->guessed)
{
text = BZ_Malloc(ctx->prefixlen + strlen(value) + 1);
memcpy(text, ctx->prefix, ctx->prefixlen);
strcpy(text+ctx->prefixlen, value);
res->guessed = text;
}
else
{
if (match->matchnum > 0)
match->matchnum--;
memcpy(match->result, ctx->prefix, ctx->prefixlen);
Q_strncpyz(match->result+ctx->prefixlen, value, sizeof(match->result)-ctx->prefixlen);
match->desc = desc;
for (p = res->guessed, c = ctx->prefix; *p && c < ctx->prefix+ctx->prefixlen; p++, c++)
{
if (Q_tolower(*p) != Q_tolower(*c))
{
*p = 0;
break;
}
}
if (c == ctx->prefix+ctx->prefixlen)
for (c = value; *p; p++, c++)
{
if (Q_tolower(*p) != Q_tolower(*c))
{
*p = 0;
break;
}
if (!*c)
break;
}
}
if (res->num == countof(res->completions))
{
res->extra++;
return; //no more space for more options
}
text = BZ_Malloc(ctx->prefixlen + strlen(value) + 1);
memcpy(text, ctx->prefix, ctx->prefixlen);
strcpy(text+ctx->prefixlen, value);
if (repl)
{
p = BZ_Malloc(ctx->prefixlen + strlen(repl) + 2);
memcpy(p, ctx->prefix, ctx->prefixlen);
strcpy(p+ctx->prefixlen, repl);
if (value == quoted+1)
Q_strcat(p, "\"");
repl = p;
}
res->completions[res->num].text_alloced = true;
res->completions[res->num].text = text;
res->completions[res->num].desc_alloced = true;
res->completions[res->num].desc = Z_StrDup(desc);
res->completions[res->num].repl = repl;
res->num++;
}
char *Cmd_CompleteCommand (const char *partial, qboolean fullonly, qboolean caseinsens, int matchnum, const char **descptr)
void Cmd_Complete_Check(const char *check, cmd_completion_t *res, const char *desc) //compare cumulative strings and join the result
{
const char *c;
char *p;
if (!res->guessed)
res->guessed = Z_StrDup(check);
else for (p = res->guessed, c = check; *p; p++, c++)
{ //we need to do this stuff here because we're not always tracking all of them.
if (Q_tolower(*p) != Q_tolower(*c))
{
*p = 0;
break;
}
if (!*c)
break;
}
if (res->num == countof(res->completions))
{
res->extra++;
return; //no more space for more options
}
res->completions[res->num].text_alloced = false;
res->completions[res->num].text = check;
res->completions[res->num].desc_alloced = false;
res->completions[res->num].desc = desc;
res->completions[res->num].repl = NULL;
res->num++;
}
void Cmd_Complete_End(cmd_completion_t *c)
{
size_t u;
for (u = 0; u < c->num; u++)
{
if (c->completions[u].text_alloced)
Z_Free((char*)c->completions[u].text);
c->completions[u].text_alloced = false;
c->completions[u].text = NULL;
if (c->completions[u].desc_alloced)
Z_Free((char*)c->completions[u].desc);
c->completions[u].desc_alloced = false;
c->completions[u].desc = NULL;
c->completions[u].repl = NULL;
}
c->num = 0;
c->extra = 0;
Z_Free(c->guessed);
c->guessed = NULL;
Z_Free(c->partial);
c->partial = NULL;
}
int QDECL Cmd_Complete_Sort(const void *a, const void *b)
{ //FIXME: its possible that they're equal (eg: filesystem searches). we should strip one in that case, but gah.
const struct cmd_completion_opt_s *c1 = a, *c2 = b;
return strcmp(c1->text, c2->text);
}
cmd_completion_t *Cmd_Complete(const char *partial, qboolean caseinsens)
{
extern cvar_group_t *cvar_groups;
cmd_function_t *cmd;
int len;
cmdalias_t *a;
static match_t match;
cvar_group_t *grp;
cvar_t *cvar;
const char *sp;
qboolean quoted = false;
static cmd_completion_t c;
if (!partial)
{
Cmd_Complete_End(&c);
return NULL;
}
if ((c.partial && !strcmp(partial, c.partial)) && c.caseinsens == caseinsens)
return &c; //still valid.
Cmd_Complete_End(&c);
c.partial = Z_StrDup(partial);
c.caseinsens = caseinsens;
for (sp = partial; *sp; sp++)
{
@ -2295,89 +2381,118 @@ char *Cmd_CompleteCommand (const char *partial, qboolean fullonly, qboolean case
{
while (*sp == ' ' || *sp == '\t')
sp++;
//try to handle quotes
if (*sp == '\\' && sp[1] == '\"')
{
sp+=2;
quoted = true;
}
else if (*sp == '\"')
{
sp++;
quoted = true;
}
}
else
sp = NULL;
if (descptr)
*descptr = NULL;
if (!len)
return NULL;
if (matchnum == -1)
len++;
match.allowcutdown = !fullonly?true:false;
match.cutdown = false;
match.desc = NULL;
if (matchnum)
match.matchnum = matchnum;
else
match.matchnum = 0;
strcpy(match.result, "");
// check for partial match
if (caseinsens)
if (len)
{
for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
if (!Q_strncasecmp (partial,cmd->name, len) && (matchnum == -1 || !partial[len] || strlen(cmd->name) == len))
{
if (sp && cmd->argcompletion)
if (caseinsens)
{
for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
if (!Q_strncasecmp (partial,cmd->name, len) && (!partial[len] || strlen(cmd->name) == len))
{
struct cmdargcompletionctx_s ctx;
ctx.cb.cb = Cmd_CompleteCheckArg;
ctx.cmd = cmd;
ctx.prefix = partial;
ctx.prefixlen = sp-partial;
ctx.match = &match;
ctx.desc = cmd->description;
cmd->argcompletion(1, sp, &ctx.cb);
if (sp && cmd->argcompletion)
{
struct cmdargcompletion_ctx_s ctx;
ctx.cb.cb = Cmd_Complete_CheckArg;
ctx.cmd = cmd;
ctx.prefix = partial;
ctx.prefixlen = sp-partial;
ctx.res = &c;
ctx.desc = cmd->description;
ctx.quoted = quoted;
cmd->argcompletion(1, sp, &ctx.cb);
}
else
Cmd_Complete_Check(cmd->name, &c, cmd->description);
}
else
Cmd_CompleteCheck(cmd->name, &match, cmd->description);
for (a=cmd_alias ; a ; a=a->next)
if (!Q_strncasecmp (partial, a->name, len) && (!partial[len] || strlen(a->name) == len))
Cmd_Complete_Check(a->name, &c, a->value);
for (grp=cvar_groups ; grp ; grp=grp->next)
for (cvar=grp->cvars ; cvar ; cvar=cvar->next)
{
if (!Q_strncasecmp (partial,cvar->name, len) && (!partial[len] || strlen(cvar->name) == len))
Cmd_Complete_Check(cvar->name, &c, cvar->description);
if (cvar->name2 && !Q_strncasecmp (partial,cvar->name2, len) && (!partial[len] || strlen(cvar->name2) == len))
Cmd_Complete_Check(cvar->name2, &c, cvar->description);
}
for (a=cmd_alias ; a ; a=a->next)
if (!Q_strncasecmp (partial, a->name, len) && (matchnum == -1 || !partial[len] || strlen(a->name) == len))
Cmd_CompleteCheck(a->name, &match, a->value);
for (grp=cvar_groups ; grp ; grp=grp->next)
for (cvar=grp->cvars ; cvar ; cvar=cvar->next)
{
if (!Q_strncasecmp (partial,cvar->name, len) && (matchnum == -1 || !partial[len] || strlen(cvar->name) == len))
Cmd_CompleteCheck(cvar->name, &match, cvar->description);
if (cvar->name2 && !Q_strncasecmp (partial,cvar->name2, len) && (matchnum == -1 || !partial[len] || strlen(cvar->name2) == len))
Cmd_CompleteCheck(cvar->name2, &match, cvar->description);
}
}
else
{
for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
if (!Q_strncmp (partial,cmd->name, len) && (!partial[len] || strlen(cmd->name) == len))
Cmd_Complete_Check(cmd->name, &c, cmd->description);
for (a=cmd_alias ; a ; a=a->next)
if (!Q_strncmp (partial, a->name, len) && (!partial[len] || strlen(a->name) == len))
Cmd_Complete_Check(a->name, &c, "");
for (grp=cvar_groups ; grp ; grp=grp->next)
for (cvar=grp->cvars ; cvar ; cvar=cvar->next)
{
if (!Q_strncmp (partial,cvar->name, len) && (!partial[len] || strlen(cvar->name) == len))
Cmd_Complete_Check(cvar->name, &c, cvar->description);
if (cvar->name2 && !Q_strncmp (partial,cvar->name2, len) && (!partial[len] || strlen(cvar->name2) == len))
Cmd_Complete_Check(cvar->name2, &c, cvar->description);
}
}
}
//quickly sort the completions. this is primarily so that the first item is the shortest, but whatever.
qsort(c.completions, c.num, sizeof(c.completions[0]), Cmd_Complete_Sort);
return &c;
}
char *Cmd_CompleteCommand (const char *partial, qboolean fullonly, qboolean caseinsens, int matchnum, const char **descptr)
{
cmd_completion_t *c = Cmd_Complete(partial, caseinsens);
const char *text = NULL, *desc = NULL;
if (matchnum < 0)
{ //completes only if there's an EXACT match.
for (matchnum = 0; matchnum < c->num; matchnum++)
{
if (!strcmp(partial, c->completions[matchnum].text))
{
text = c->completions[matchnum].text;
desc = c->completions[matchnum].desc;
break;
}
}
}
else if (!matchnum)
{ //returns the longest-common-denominator of all the matches
text = c->guessed;
desc = ((c->num==1)?c->completions[matchnum].desc:NULL);
}
else
{
for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
if (!Q_strncmp (partial,cmd->name, len) && (matchnum == -1 || !partial[len] || strlen(cmd->name) == len))
Cmd_CompleteCheck(cmd->name, &match, cmd->description);
for (a=cmd_alias ; a ; a=a->next)
if (!Q_strncmp (partial, a->name, len) && (matchnum == -1 || !partial[len] || strlen(a->name) == len))
Cmd_CompleteCheck(a->name, &match, "");
for (grp=cvar_groups ; grp ; grp=grp->next)
for (cvar=grp->cvars ; cvar ; cvar=cvar->next)
matchnum--;
if (matchnum < c->num)
{
if (!Q_strncmp (partial,cvar->name, len) && (matchnum == -1 || !partial[len] || strlen(cvar->name) == len))
Cmd_CompleteCheck(cvar->name, &match, cvar->description);
if (cvar->name2 && !Q_strncmp (partial,cvar->name2, len) && (matchnum == -1 || !partial[len] || strlen(cvar->name2) == len))
Cmd_CompleteCheck(cvar->name2, &match, cvar->description);
text = c->completions[matchnum].text;
desc = c->completions[matchnum].desc;
}
}
if (match.matchnum>0)
return NULL;
if (!*match.result)
return NULL;
if (descptr)
*descptr = match.desc;
return match.result;
*descptr = desc;
return (char*)text;
}
//lists commands, also prints restriction level
void Cmd_List_f (void)
{

View File

@ -73,7 +73,8 @@ then searches for a command or variable that matches the first token.
typedef void (*xcommand_t) (void);
struct xcommandargcompletioncb_s
{
void(*cb)(const char *arg, struct xcommandargcompletioncb_s *ctx);
//if repl is specified, then that is the text that will be used if this is the sole autocomplete, to complete using strings that are not actually valid.
void(*cb)(const char *arg, const char *desc, const char *repl, struct xcommandargcompletioncb_s *ctx);
//private stuff follows.
};
typedef void (*xcommandargcompletion_t)(int argn, const char *partial, struct xcommandargcompletioncb_s *ctx);
@ -102,6 +103,23 @@ char *Cmd_AliasExist(const char *name, int restrictionlevel);
const char *Cmd_Describe (const char *cmd_name);
typedef struct
{
char *guessed; //this is the COMPLETED partial.
char *partial; //the requested string that we completed
qboolean caseinsens;
size_t num, extra; //valid count, and ommitted count (if we were too lazy to find more)
struct cmd_completion_opt_s {
qboolean text_alloced:1;
qboolean desc_alloced:1;
const char *text;
const char *repl; //used for sole matches
const char *desc;
} completions[50];
} cmd_completion_t;
cmd_completion_t *Cmd_Complete(const char *partial, qboolean caseinsens); //calculates and caches info.
//these should probably be removed some time
char *Cmd_CompleteCommand (const char *partial, qboolean fullonly, qboolean caseinsens, int matchnum, const char **descptr);
qboolean Cmd_IsCommand (const char *line);
// attempts to match a partial command for automatic command line completion

View File

@ -480,6 +480,12 @@ char *Q_strlwr(char *s)
return ret;
}
static char fte_inline Q_tolower(char c)
{
if (c >= 'A' && c <= 'Z')
return c-'A'+'a';
return c;
}
int wildcmp(const char *wild, const char *string)
{
/*
@ -507,7 +513,7 @@ int wildcmp(const char *wild, const char *string)
return true;
string++;
}
else if ((*wild == *string) || (*wild == '?'))
else if ((Q_tolower(*wild) == Q_tolower(*string)) || (*wild == '?'))
{
//this char matches
wild++;

View File

@ -611,6 +611,7 @@ void FS_UnloadPackFiles(void);
void FS_ReloadPackFiles(void);
char *FSQ3_GenerateClientPacksList(char *buffer, int maxlen, int basechecksum);
void FS_PureMode(int mode, char *purenamelist, char *purecrclist, char *refnamelist, char *refcrclist, int seed); //implies an fs_restart. ref package names are optional, for q3 where pure names don't contain usable paths
qboolean FS_PureOkay(void);
//recursively tries to open files until it can get a zip.
vfsfile_t *CL_OpenFileInPackage(searchpathfuncs_t *search, char *name);

View File

@ -3524,6 +3524,79 @@ void FS_PureMode(int puremode, char *purenamelist, char *purecrclist, char *refn
}
}
qboolean FS_PureOkay(void)
{
//returns true if all pure packages that we're meant to need could load.
//if they couldn't then they won't override things, or the game will just be completely screwed due to having absolutely no game data
if (fs_puremode == 1 && fs_purenames && *fs_purenames && fs_purecrcs && *fs_purecrcs)
{
char crctok[64];
char nametok[MAX_QPATH];
char nametok2[MAX_QPATH];
searchpath_t *sp = com_purepaths;
char *names = fs_purenames, *pname;
char *crcs = fs_purecrcs;
int crc;
qboolean required;
while(names && crcs)
{
crcs = COM_ParseOut(crcs, crctok, sizeof(crctok));
names = COM_ParseOut(names, nametok, sizeof(nametok));
crc = strtoul(crctok, NULL, 0);
if (!crc)
continue;
pname = nametok;
if (fs_refnames && fs_refcrcs)
{ //q3 is annoying as hell
int crc2;
char *rc = fs_refcrcs;
char *rn = fs_refnames;
pname = "";
for (; rc && rn; )
{
rc = COM_ParseOut(rc, crctok, sizeof(crctok));
rn = COM_ParseOut(rn, nametok2, sizeof(nametok2));
crc2 = strtoul(crctok, NULL, 0);
if (crc2 == crc)
{
COM_DefaultExtension(nametok2, ".pk3", sizeof(nametok2));
pname = nametok2;
break;
}
}
}
required = *pname == '*';
if (*pname == '*') // * means that its 'referenced' (read: actually useful) thus should be downloaded, which is not relevent here.
{
required = true;
pname++;
}
else
required = false;
if (sp && sp->crc_check == crc)
{
sp = sp->nextpure;
continue;
}
else if (!required) //if its not referenced, then its not needed, and we probably didn't bother to download it. this might be an issue with sv_pure 1, but that has its own issues.
continue;
else //if (!sp)
{
Con_Printf("Pure package %s:%i missing\n", pname, crc);
return false;
}
}
return true;
}
return true;
}
char *FSQ3_GenerateClientPacksList(char *buffer, int maxlen, int basechecksum)
{ //this is for q3 compatibility.
@ -3854,7 +3927,7 @@ void FS_ReloadPackFilesFlags(unsigned int reloadflags)
}
if (!sp)
Con_DPrintf("Pure crc %i wasn't found\n", crc);
Con_DPrintf("Pure package %s:%i wasn't found\n", pname, crc);
}
}
}

View File

@ -1168,7 +1168,6 @@ size_t NET_StringToAdr2 (const char *s, int defaultport, netadr_t *a, size_t num
if (!strncmp (s, "tcp://", 6))
{
//make sure that the rest of the address is a valid ip address (4 or 6)
if (!NET_StringToSockaddr (s+6, defaultport, &sadr[0], NULL, NULL))
{
a->type = NA_INVALID;
@ -1182,7 +1181,6 @@ size_t NET_StringToAdr2 (const char *s, int defaultport, netadr_t *a, size_t num
if (!strncmp (s, "ws://", 5))
{
//make sure that the rest of the address is a valid ip address (4 or 6)
if (!NET_StringToSockaddr (s+5, defaultport, &sadr[0], NULL, NULL))
{
a->type = NA_INVALID;
@ -1195,8 +1193,10 @@ size_t NET_StringToAdr2 (const char *s, int defaultport, netadr_t *a, size_t num
}
if (!strncmp (s, "wss://", 6))
{
#ifndef HAVE_SSL
return false;
#else
//make sure that the rest of the address is a valid ip address (4 or 6)
if (!NET_StringToSockaddr (s+6, defaultport, &sadr[0], NULL, NULL))
{
a->type = NA_INVALID;
@ -1206,29 +1206,14 @@ size_t NET_StringToAdr2 (const char *s, int defaultport, netadr_t *a, size_t num
SockadrToNetadr (&sadr[0], a);
a->prot = NP_WSS;
return true;
}
if (!strncmp (s, "dtls://", 7))
{
#ifdef HAVE_DTLS
//make sure that the rest of the address is a valid ip address (4 or 6)
if (!NET_StringToSockaddr (s+7, defaultport, &sadr[0], NULL, NULL))
{
a->type = NA_INVALID;
return false;
}
SockadrToNetadr (&sadr[0], a);
a->prot = NP_DTLS;
return true;
#else
return false;
#endif
}
if (!strncmp (s, "tls://", 6))
{
#ifndef HAVE_SSL
return false;
#else
//make sure that the rest of the address is a valid ip address (4 or 6)
if (!NET_StringToSockaddr (s+6, defaultport, &sadr[0], NULL, NULL))
{
a->type = NA_INVALID;
@ -1238,8 +1223,26 @@ size_t NET_StringToAdr2 (const char *s, int defaultport, netadr_t *a, size_t num
SockadrToNetadr (&sadr[0], a);
a->prot = NP_TLS;
return true;
#endif
}
#endif
if (!strncmp (s, "dtls://", 7))
{
#ifndef HAVE_DTLS
return false;
#else
//make sure that the rest of the address is a valid ip address (4 or 6)
if (!NET_StringToSockaddr (s+7, defaultport, &sadr[0], NULL, NULL))
{
a->type = NA_INVALID;
return false;
}
SockadrToNetadr (&sadr[0], a);
a->prot = NP_DTLS;
return true;
#endif
}
#ifdef IRCCONNECT
if (!strncmp (s, "irc://", 6))
{

View File

@ -1132,9 +1132,11 @@ PM_CheckWaterJump
*/
void PM_CheckWaterJump (void)
{
vec3_t spot;
int cont;
vec3_t spot, spot2;
// int cont;
vec3_t flatforward;
trace_t tr;
vec3_t oldmin, oldmax;
if (pmove.waterjumptime>0)
return;
@ -1151,6 +1153,37 @@ void PM_CheckWaterJump (void)
flatforward[2] = 0;
VectorNormalize (flatforward);
#if 1 //NQ does a traceline, which gives more permissive results. This is required for various maps that have awkward water jumps.
VectorCopy(pmove.player_mins, oldmin);
VectorCopy(pmove.player_maxs, oldmax);
VectorCopy(pmove.origin, spot);
spot[2] += 8 + 24+pmove.player_mins[2]; //hexen2 fix. calculated from the normal bottom of bbox
VectorMA (spot, 24, flatforward, spot2);
tr = PM_TraceLine(spot, spot2);
VectorCopy(oldmin, pmove.player_mins);
VectorCopy(oldmax, pmove.player_maxs);
if (tr.fraction == 1) //(possibly) give up if open at waist
{ //NQ bug workaround: NQ does waterjump checks inside prethink, and THEN sets waterlevel after.
//The player then moves to where waterlevel SHOULD be 3, except you're still allowed to waterjump because of last frame.
//Which is horrible buggy framerate-dependant behaviour...
//so lets just try again 2qu up.
//This'll cause slight prediction issues with other qw engines, and maybe some newly bugged maps, but those maps were probably already buggy with a low enough nq framerate.
spot[2] += 2;
spot2[2] += 2;
tr = PM_TraceLine(spot, spot2);
VectorCopy(oldmin, pmove.player_mins);
VectorCopy(oldmax, pmove.player_maxs);
if (tr.fraction == 1) //give up if open at waist
return;
}
spot[2] += 24;
spot2[2] += 24;
tr = PM_TraceLine(spot, spot2);
VectorCopy(oldmin, pmove.player_mins);
VectorCopy(oldmax, pmove.player_maxs);
if (tr.fraction < 1) //give up if blocked at eye
return;
#else
VectorMA (pmove.origin, 24, flatforward, spot);
spot[2] += 8 + 24+pmove.player_mins[2]; //hexen2 fix. calculated from the normal bottom of bbox
cont = PM_PointContents (spot);
@ -1160,6 +1193,7 @@ void PM_CheckWaterJump (void)
cont = PM_PointContents (spot);
if (cont != FTECONTENTS_EMPTY)
return;
#endif
// jump out of water
VectorScale (flatforward, 50, pmove.velocity);
pmove.velocity[2] = 310;

View File

@ -818,7 +818,7 @@ static void SelectPassTexture(unsigned int tu, shaderpass_t *pass)
{
default:
case T_GEN_DIFFUSE:
if (shaderstate.curtexnums->base)
if (TEXLOADED(shaderstate.curtexnums->base))
BindTexture(tu, shaderstate.curtexnums->base);
else
BindTexture(tu, missing_texture);
@ -2049,6 +2049,13 @@ static void BE_ApplyUniforms(program_t *prog, int permu)
IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, h, mvp, 4);
}
break;
case SP_M_MODELVIEW:
{
float mv[16];
Matrix4_Multiply(r_refdef.m_view, shaderstate.m_model, mv);
IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, h, mv, 4);
}
break;
case SP_LIGHTPOSITION:
{
@ -2130,7 +2137,6 @@ static void BE_ApplyUniforms(program_t *prog, int permu)
break;
case SP_M_ENTBONES:
case SP_M_MODELVIEW:
case SP_E_VLSCALE:
case SP_E_ORIGIN:
case SP_E_GLOWMOD:
@ -2177,9 +2183,9 @@ static void BE_RenderMeshProgram(shader_t *s, unsigned int vertbase, unsigned in
return;
}
#endif
if (TEXVALID(shaderstate.curtexnums->bump) && p->permu[perm|PERMUTATION_BUMPMAP].h.loaded)
if (TEXLOADED(shaderstate.curtexnums->bump) && p->permu[perm|PERMUTATION_BUMPMAP].h.loaded)
perm |= PERMUTATION_BUMPMAP;
if (TEXVALID(shaderstate.curtexnums->fullbright) && p->permu[perm|PERMUTATION_FULLBRIGHT].h.loaded)
if (TEXLOADED(shaderstate.curtexnums->fullbright) && p->permu[perm|PERMUTATION_FULLBRIGHT].h.loaded)
perm |= PERMUTATION_FULLBRIGHT;
if (p->permu[perm|PERMUTATION_UPPERLOWER].h.loaded && (TEXLOADED(shaderstate.curtexnums->upperoverlay) || TEXLOADED(shaderstate.curtexnums->loweroverlay)))
perm |= PERMUTATION_UPPERLOWER;

View File

@ -146,16 +146,29 @@ qboolean D3D9_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mip
else if (mips->type == PTI_2D)
{
IDirect3DTexture9 *dt;
if (FAILED(IDirect3DDevice9_CreateTexture(pD3DDev9, mips->mip[0].width, mips->mip[0].height, mips->mipcount, 0, fmt, D3DPOOL_MANAGED, &dt, NULL)))
int mipcount = mips->mipcount;
for (i = 1; i < mipcount; i++)
{ //OpenGL and Direct3D have different interpretations of mipmap sizes.
//OpenGL rounds up, direct3D rounds down. (d3d:3->1, gl:3->2)
//so if the mips are incompatible, just drop the smaller ones.
if (mips->mip[i].width != max(1,(mips->mip[i-1].width)>>1) ||
mips->mip[i].height != max(1,(mips->mip[i-1].height)>>1))
{
mipcount = i;
break;
}
}
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;
for (i = 0; i < mips->mipcount; i++)
for (i = 0; i < mipcount; i++)
{
IDirect3DTexture9_GetLevelDesc(dt, i, &desc);
if (mips->mip[i].height != desc.Height || mips->mip[i].width != desc.Width)
{
{ //we got the above mipcount clamping wrong!
IDirect3DTexture9_Release(dt);
return false;
}

View File

@ -180,7 +180,7 @@ static HRESULT STDMETHODCALLTYPE myID3DXIncludeVtbl_Open(myID3DXInclude *cls, D3
"float3 fog3(float3 regularcolour, float distance)"
"{"
"float z = w_fogdensity * -distance;\n"
"float z = w_fogdensity * distance;\n"
"z = max(0.0,z-w_fogdepthbias);\n"
"if (r_fog_exp2)\n"
"z *= z;\n"
@ -190,7 +190,7 @@ static HRESULT STDMETHODCALLTYPE myID3DXIncludeVtbl_Open(myID3DXInclude *cls, D3
"}\n"
"float3 fog3additive(float3 regularcolour, float distance)"
"{"
"float z = w_fogdensity * -distance;\n"
"float z = w_fogdensity * distance;\n"
"z = max(0.0,z-w_fogdepthbias);\n"
"if (r_fog_exp2)\n"
"z *= z;\n"
@ -204,7 +204,7 @@ static HRESULT STDMETHODCALLTYPE myID3DXIncludeVtbl_Open(myID3DXInclude *cls, D3
"}\n"
"float4 fog4additive(float4 regularcolour, float distance)"
"{"
"float z = w_fogdensity * -distance;\n"
"float z = w_fogdensity * distance;\n"
"z = max(0.0,z-w_fogdepthbias);\n"
"if (r_fog_exp2)\n"
"z *= z;\n"
@ -214,7 +214,7 @@ static HRESULT STDMETHODCALLTYPE myID3DXIncludeVtbl_Open(myID3DXInclude *cls, D3
"}\n"
"float4 fog4blend(float4 regularcolour, float distance)"
"{"
"float z = w_fogdensity * -distance;\n"
"float z = w_fogdensity * distance;\n"
"z = max(0.0,z-w_fogdepthbias);\n"
"if (r_fog_exp2)\n"
"z *= z;\n"
@ -223,12 +223,11 @@ static HRESULT STDMETHODCALLTYPE myID3DXIncludeVtbl_Open(myID3DXInclude *cls, D3
"return regularcolour * float4(1.0, 1.0, 1.0, fac);\n"
"}\n"
"#else\n"
/*don't use macros for this - mesa bugs out*/
"float3 fog3(float3 regularcolour, float4 fragcoord) { return regularcolour; }\n"
"float3 fog3additive(float3 regularcolour, float4 fragcoord) { return regularcolour; }\n"
"float4 fog4(float4 regularcolour, float4 fragcoord) { return regularcolour; }\n"
"float4 fog4additive(float4 regularcolour, float4 fragcoord) { return regularcolour; }\n"
"float4 fog4blend(float4 regularcolour, float4 fragcoord) { return regularcolour; }\n"
"float3 fog3(float3 regularcolour, float distance) { return regularcolour; }\n"
"float3 fog3additive(float3 regularcolour, float distance) { return regularcolour; }\n"
"float4 fog4(float4 regularcolour, float distance) { return regularcolour; }\n"
"float4 fog4additive(float4 regularcolour, float distance) { return regularcolour; }\n"
"float4 fog4blend(float4 regularcolour, float distance) { return regularcolour; }\n"
"#endif\n"
"#endif\n"
;
@ -580,7 +579,7 @@ void D3D9Shader_Init(void)
sh_config.progpath = shaderlib?"hlsl/%s.hlsl":NULL;
sh_config.shadernamefmt = "%s_hlsl9";
sh_config.progs_supported = !!shaderlib;
sh_config.progs_supported = !!shaderlib && d3d9_hlsl.ival;
sh_config.progs_required = false;
sh_config.pDeleteProg = D3D9Shader_DeleteProg;

View File

@ -1525,6 +1525,30 @@ void GLBE_Shutdown(void)
BZ_Free(shaderstate.wbatches);
shaderstate.wbatches = NULL;
shaderstate.maxwbatches = 0;
//on vid_reload, the gl drivers might have various things bound that have since been destroyed/etc
//so reset that state to avoid any issues with state
/*shaderstate.sourcevbo = &shaderstate.dummyvbo;
memset(shaderstate.sourcevbo, 0, sizeof(*shaderstate.sourcevbo));
shaderstate.pendingcolourvbo = 0;
shaderstate.pendingcolourpointer = NULL;
shaderstate.pendingvertexvbo = 0;
shaderstate.pendingvertexpointer = NULL;
for (u = 0; u < SHADER_TMU_MAX; u++)
{
shaderstate.pendingtexcoordparts[u] = 0;
shaderstate.pendingtexcoordvbo[u] = 0;
shaderstate.pendingtexcoordpointer[u] = NULL;
}*/
if (sh_config.progs_supported)
BE_ApplyAttributes(0, (1u<<VATTR_LEG_FIRST)-1u);
if (!sh_config.progs_required)
BE_ApplyAttributes(0, (1u<<VATTR_LEG_VERTEX)|
(1u<<VATTR_LEG_COLOUR)|
(1u<<VATTR_LEG_ELEMENTS)|
((1u<<(VATTR_LEG_TMU0+be_maxpasses))-1));
GL_SelectVBO(0);
GL_SelectEBO(0);
}
void GLBE_Init(void)
@ -1538,6 +1562,7 @@ void GLBE_Init(void)
shaderstate.curentity = &r_worldentity;
be_maxpasses = gl_config_nofixedfunc?1:gl_mtexarbable;
be_maxpasses = min(SHADER_TMU_MAX, min(be_maxpasses, 32-VATTR_LEG_TMU0));
gl_stencilbits = 0;
#ifndef GLESONLY
if (!gl_config_gles && gl_config.glversion >= 3.0 && gl_config_nofixedfunc)

View File

@ -5643,7 +5643,8 @@ void Terr_Brush_Draw(heightmap_t *hm, batch_t **batches, entity_t *e)
default:
Sys_Error("Bad lightmap_fmt\n");
break;
case TF_BGRA32:
case PTI_BGRA8:
case PTI_BGRX8:
for (t = 0; t < br->faces[j].lmextents[1]; t++)
{
for (s = 0; s < br->faces[j].lmextents[0]; s++)
@ -5657,7 +5658,8 @@ void Terr_Brush_Draw(heightmap_t *hm, batch_t **batches, entity_t *e)
out += (lm->width - br->faces[j].lmextents[0]) * 4;
}
break;
/*case TF_RGBA32:
case PTI_RGBA8:
case PTI_RGBX8:
for (t = 0; t < br->faces[j].lmextents[1]; t++)
{
for (s = 0; s < br->faces[j].lmextents[0]; s++)
@ -5670,8 +5672,8 @@ void Terr_Brush_Draw(heightmap_t *hm, batch_t **batches, entity_t *e)
}
out += (lm->width - br->faces[j].lmextents[0]) * 4;
}
break;*/
/*case TF_BGR24:
break;
case PTI_BGR8:
for (t = 0; t < br->faces[j].lmextents[1]; t++)
{
for (s = 0; s < br->faces[j].lmextents[0]; s++)
@ -5683,8 +5685,8 @@ void Terr_Brush_Draw(heightmap_t *hm, batch_t **batches, entity_t *e)
}
out += (lm->width - br->faces[j].lmextents[0]) * 3;
}
break;*/
case TF_RGB24:
break;
case PTI_RGB8:
for (t = 0; t < br->faces[j].lmextents[1]; t++)
{
for (s = 0; s < br->faces[j].lmextents[0]; s++)
@ -5697,6 +5699,51 @@ void Terr_Brush_Draw(heightmap_t *hm, batch_t **batches, entity_t *e)
out += (lm->width - br->faces[j].lmextents[0]) * 3;
}
break;
case PTI_A2BGR10:
for (t = 0; t < br->faces[j].lmextents[1]; t++)
{
for (s = 0; s < br->faces[j].lmextents[0]; s++)
{
*(unsigned int*)out = (0x3<<30) | (in[2]<<22) | (in[1]<<12) | (in[0]<<2);
out+=4;
in+=3;
}
out += (lm->width - br->faces[j].lmextents[0]) * 4;
}
break;
/*case PTI_E5BGR9:
for (t = 0; t < br->faces[j].lmextents[1]; t++)
{
for (s = 0; s < br->faces[j].lmextents[0]; s++)
{
*(unsigned int*)out = Surf_PackE5BRG9(in[0], in[1], in[2], 8);
out+=4;
in+=3;
}
out += (lm->width - br->faces[j].lmextents[0]) * 4;
}
break;*/
case PTI_L8:
for (t = 0; t < br->faces[j].lmextents[1]; t++)
{
for (s = 0; s < br->faces[j].lmextents[0]; s++)
{
*out++ = max(max(in[0], in[1]), in[2]);
in+=3;
}
out += (lm->width - br->faces[j].lmextents[0]);
}
break;
case PTI_RGBA16F:
case PTI_RGBA32F:
case PTI_RGB565:
case PTI_RGBA4444:
case PTI_RGBA5551:
case PTI_ARGB4444:
case PTI_ARGB1555:
break;
}
}
}
@ -5966,6 +6013,7 @@ static brushes_t *Terr_Brush_Insert(model_t *model, heightmap_t *hm, brushes_t *
out->selected = false;
out->contents = brush->contents;
out->axialplanes = 0;
out->patch = NULL;
out->planes = BZ_Malloc((sizeof(*out->planes)+sizeof(*out->faces)) * brush->numplanes);
out->faces = (void*)(out->planes+brush->numplanes);

View File

@ -1014,6 +1014,22 @@ static void Shader_SurfaceParm ( shader_t *shader, shaderpass_t *pass, char **pt
shader->flags |= SHADER_NOMARKS; //wrong, but whatever.
else if ( !Q_stricmp( token, "nomarks" ) )
shader->flags |= SHADER_NOMARKS;
//forceshader type things inherit certain textures from the original material
//however, that original material might not need those textures and thus won't have them loaded, which breaks replacement.
//these provide a way to override that.
else if (!Q_stricmp( token, "hasdiffuse"))
shader->flags |= SHADER_HASDIFFUSE;
else if (!Q_stricmp( token, "hasnormalmap"))
shader->flags |= SHADER_HASNORMALMAP;
else if (!Q_stricmp( token, "hasgloss"))
shader->flags |= SHADER_HASGLOSS;
else if (!Q_stricmp( token, "hasfullbright"))
shader->flags |= SHADER_HASFULLBRIGHT;
else if (!Q_stricmp( token, "haspaletted"))
shader->flags |= SHADER_HASPALETTED;
else if (!Q_stricmp(token, "hastop") || !Q_stricmp(token, "hasbottom") || !Q_stricmp(token, "hastopbottom"))
shader->flags |= SHADER_HASTOPBOTTOM;
}
static void Shader_Sort ( shader_t *shader, shaderpass_t *pass, char **ptr )
@ -5918,7 +5934,7 @@ void Shader_DefaultBSPLM(const char *shortname, shader_t *s, const void *args)
"}\n"
);
}
if (!builtin && ((sh_config.progs_supported && qrenderer == QR_OPENGL) || sh_config.progs_required))
if (!builtin && ((sh_config.progs_supported && (qrenderer == QR_OPENGL||qrenderer == QR_DIRECT3D9)) || sh_config.progs_required))
{
builtin = (
"{\n"
@ -6111,38 +6127,43 @@ char *Shader_DefaultBSPWater(shader_t *s, const char *shortname, char *buffer, s
"surfaceparm nodraw\n"
"surfaceparm nodlight\n"
"surfaceparm nomarks\n"
"surfaceparm hasdiffuse\n"
"}\n"
);
case -2: //regular with r_wateralpha forced off.
return (
"{\n"
"program defaultwarp\n"
"{\n"
"program defaultwarp\n"
"map $diffuse\n"
"tcmod turb 0.02 0.1 0.5 0.1\n"
"}\n"
"surfaceparm nodlight\n"
"surfaceparm nomarks\n"
"surfaceparm hasdiffuse\n"
"}\n"
);
case 0: //fastturb
return (
"{\n"
// "program defaultfill\n"
"{\n"
// "program defaultfill\n"
"map $whiteimage\n"
"rgbgen srgb $r_fastturbcolour\n"
"}\n"
"surfaceparm nodlight\n"
"surfaceparm nomarks\n"
"surfaceparm hasdiffuse\n"
"}\n"
);
default:
case 1: //vanilla style
Q_snprintfz(buffer, buffersize,
"{\n"
"program defaultwarp%s\n"
"surfaceparm nodlight\n"
"surfaceparm nomarks\n"
"{\n"
"program defaultwarp%s\n"
"map $diffuse\n"
"tcmod turb 0.02 0.1 0.5 0.1\n"
"if %g < 1\n"
@ -6150,8 +6171,7 @@ char *Shader_DefaultBSPWater(shader_t *s, const char *shortname, char *buffer, s
"blendfunc gl_src_alpha gl_one_minus_src_alpha\n"
"endif\n"
"}\n"
"surfaceparm nodlight\n"
"surfaceparm nomarks\n"
"surfaceparm hasdiffuse\n"
"}\n"
, explicitalpha?"":va("#ALPHA=%g",alpha), alpha, alpha);
return buffer;
@ -6161,18 +6181,13 @@ char *Shader_DefaultBSPWater(shader_t *s, const char *shortname, char *buffer, s
"surfaceparm nodlight\n"
"surfaceparm nomarks\n"
"{\n"
"program altwater#FRESNEL=4\n"
"map $refraction\n"
"}\n"
"{\n"
"map $null\n"//$reflection
"}\n"
"{\n"
"map $null\n"//$ripplemap
"}\n"
"{\n"
"map $null\n"//$refractiondepth
"}\n"
"program altwater#FRESNEL=4\n"
"surfaceparm hasdiffuse\n"
"}\n"
);
case 3: //reflections
@ -6181,18 +6196,13 @@ char *Shader_DefaultBSPWater(shader_t *s, const char *shortname, char *buffer, s
"surfaceparm nodlight\n"
"surfaceparm nomarks\n"
"{\n"
"program altwater#REFLECT#FRESNEL=4\n"
"map $refraction\n"
"}\n"
"{\n"
"map $reflection\n"
"}\n"
"{\n"
"map $null\n"//$ripplemap
"}\n"
"{\n"
"map $null\n"//$refractiondepth
"}\n"
"program altwater#REFLECT#FRESNEL=4\n"
"surfaceparm hasdiffuse\n"
"}\n"
);
case 4: //ripples
@ -6201,18 +6211,13 @@ char *Shader_DefaultBSPWater(shader_t *s, const char *shortname, char *buffer, s
"surfaceparm nodlight\n"
"surfaceparm nomarks\n"
"{\n"
"program altwater#RIPPLEMAP#FRESNEL=4\n"
"map $refraction\n"
"}\n"
"{\n"
"map $null\n"//$reflection
"}\n"
"{\n"
"map $ripplemap\n"
"}\n"
"{\n"
"map $null\n"//$refractiondepth
"}\n"
"program altwater#RIPPLEMAP#FRESNEL=4\n"
"surfaceparm hasdiffuse\n"
"}\n"
);
case 5: //ripples+reflections
@ -6221,18 +6226,13 @@ char *Shader_DefaultBSPWater(shader_t *s, const char *shortname, char *buffer, s
"surfaceparm nodlight\n"
"surfaceparm nomarks\n"
"{\n"
"program altwater#REFLECT#RIPPLEMAP#FRESNEL=4\n"
"map $refraction\n"
"}\n"
"{\n"
"map $reflection\n"
"}\n"
"{\n"
"map $ripplemap\n"
"}\n"
"{\n"
"map $null\n"//$refractiondepth
"}\n"
"program altwater#REFLECT#RIPPLEMAP#FRESNEL=4\n"
"surfaceparm hasdiffuse\n"
"}\n"
);
}
@ -6377,42 +6377,48 @@ void Shader_DefaultBSPQ1(const char *shortname, shader_t *s, const void *args)
if (!builtin && *shortname == '{')
{
/*alpha test*/
/*FIXME: use defaultwall#ALPHA=0.666 or so*/
builtin = (
"{\n"
/* "if $deluxmap\n"
"{\n"
"map $normalmap\n"
"tcgen base\n"
"}\n"
"{\n"
"map $deluxmap\n"
"tcgen lightmap\n"
"}\n"
"endif\n"*/
if (sh_config.progs_supported)
builtin = (
"{\n"
"map $diffuse\n"
"tcgen base\n"
"alphafunc ge128\n"
"fte_program defaultwall#MASK=0.666#MASKLT\n"
"}\n"
// "if $lightmap\n"
);
else
builtin = (
"{\n"
/* "if $deluxmap\n"
"{\n"
"map $normalmap\n"
"tcgen base\n"
"}\n"
"{\n"
"map $deluxmap\n"
"tcgen lightmap\n"
"}\n"
"endif\n"*/
"{\n"
"map $lightmap\n"
"if gl_overbright > 1\n"
"blendfunc gl_dst_color gl_src_color\n" //scale it up twice. will probably still get clamped, but what can you do
"else\n"
"blendfunc gl_dst_color gl_zero\n"
"endif\n"
"map $diffuse\n"
"tcgen base\n"
"alphafunc ge128\n"
"}\n"
// "if $lightmap\n"
"{\n"
"map $lightmap\n"
"if gl_overbright > 1\n"
"blendfunc gl_dst_color gl_src_color\n" //scale it up twice. will probably still get clamped, but what can you do
"else\n"
"blendfunc gl_dst_color gl_zero\n"
"endif\n"
"depthfunc equal\n"
"}\n"
// "endif\n"
"{\n"
"map $fullbright\n"
"blendfunc add\n"
"depthfunc equal\n"
"}\n"
// "endif\n"
"{\n"
"map $fullbright\n"
"blendfunc add\n"
"depthfunc equal\n"
"}\n"
"}\n"
);
);
}
/*Hack: note that halflife would normally expect you to use rendermode/renderampt*/
@ -6610,7 +6616,7 @@ void Shader_Default2D(const char *shortname, shader_t *s, const void *genargs)
"nomipmaps\n"
"program default2d#PREMUL\n"
"{\n"
"map $diffuse\n"
"clampmap $diffuse\n"
"blendfunc gl_one gl_one_minus_src_alpha\n"
"}\n"
"sort additive\n"

View File

@ -6048,6 +6048,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"if (gl_FragColor.a >= MASK)\n"
"discard;\n"
"#endif\n"
"gl_FragColor.a = 1.0; //alpha blending AND alpha testing usually looks stupid, plus it screws up our fog.\n"
"#endif\n"
//and finally hide it all if we're fogged.
@ -6062,7 +6063,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
#ifdef VKQUAKE
{QR_VULKAN, -1, "defaultwall",
"\xFF\x53\x50\x56\x01\x00\x00\x00\x9C\x1F\x00\x00\x01\x00\x00\x00\x2B\x00\x00\x00\x2C\x00\x00\x00\xA6\x00\x00\x00\xD4\x00\x00\x00"
"\x10\x15\x00\x00\xE4\x15\x00\x00\x18\x48\x00\x00\x01\x00\x66\x31\x72\x5F\x67\x6C\x73\x6C\x5F\x6F\x66\x66\x73\x65\x74\x6D\x61\x70"
"\x10\x15\x00\x00\xE4\x15\x00\x00\x38\x48\x00\x00\x01\x00\x66\x31\x72\x5F\x67\x6C\x73\x6C\x5F\x6F\x66\x66\x73\x65\x74\x6D\x61\x70"
"\x70\x69\x6E\x67\x00\x00\x00\x00\x00\x01\x01\x66\x31\x72\x5F\x67\x6C\x73\x6C\x5F\x6F\x66\x66\x73\x65\x74\x6D\x61\x70\x70\x69\x6E"
"\x67\x5F\x73\x63\x61\x6C\x65\x00\x3D\x23\xD7\x0A\x01\x02\x66\x31\x67\x6C\x5F\x73\x70\x65\x63\x75\x6C\x61\x72\x00\x3E\x99\x99\x9A"
"\x01\x03\x62\x31\x72\x5F\x66\x6F\x67\x5F\x65\x78\x70\x32\x00\x00\x00\x00\x00\x01\x04\x42\x31\x76\x65\x72\x74\x65\x78\x6C\x69\x74"
@ -6236,7 +6237,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"\x81\x00\x05\x00\x06\x00\x00\x00\x31\x00\x00\x00\x2D\x00\x00\x00\x30\x00\x00\x00\x88\x00\x05\x00\x06\x00\x00\x00\x33\x00\x00\x00"
"\x31\x00\x00\x00\x32\x00\x00\x00\x41\x00\x05\x00\x26\x00\x00\x00\x34\x00\x00\x00\x0C\x00\x00\x00\x2B\x00\x00\x00\x3E\x00\x03\x00"
"\x34\x00\x00\x00\x33\x00\x00\x00\x3D\x00\x04\x00\x07\x00\x00\x00\x35\x00\x00\x00\x0C\x00\x00\x00\xFE\x00\x02\x00\x35\x00\x00\x00"
"\x38\x00\x01\x00\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00\xDD\x02\x00\x00\x00\x00\x00\x00\x11\x00\x02\x00\x01\x00\x00\x00"
"\x38\x00\x01\x00\x03\x02\x23\x07\x00\x00\x01\x00\x01\x00\x08\x00\xDE\x02\x00\x00\x00\x00\x00\x00\x11\x00\x02\x00\x01\x00\x00\x00"
"\x0B\x00\x06\x00\x01\x00\x00\x00\x47\x4C\x53\x4C\x2E\x73\x74\x64\x2E\x34\x35\x30\x00\x00\x00\x00\x0E\x00\x03\x00\x00\x00\x00\x00"
"\x01\x00\x00\x00\x0F\x00\x0C\x00\x04\x00\x00\x00\x04\x00\x00\x00\x6D\x61\x69\x6E\x00\x00\x00\x00\x3F\x00\x00\x00\x97\x01\x00\x00"
"\x9F\x01\x00\x00\xA8\x01\x00\x00\xCF\x01\x00\x00\xDD\x01\x00\x00\x4C\x02\x00\x00\x10\x00\x03\x00\x04\x00\x00\x00\x07\x00\x00\x00"
@ -6292,16 +6293,16 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"\x66\x6C\x65\x63\x74\x6D\x61\x73\x6B\x00\x00\x00\x05\x00\x06\x00\x71\x02\x00\x00\x73\x5F\x72\x65\x66\x6C\x65\x63\x74\x63\x75\x62"
"\x65\x00\x00\x00\x05\x00\x03\x00\x81\x02\x00\x00\x70\x61\x6C\x00\x05\x00\x05\x00\x82\x02\x00\x00\x73\x5F\x70\x61\x6C\x65\x74\x74"
"\x65\x64\x00\x00\x05\x00\x04\x00\x8B\x02\x00\x00\x73\x5F\x74\x30\x00\x00\x00\x00\x05\x00\x06\x00\xB3\x02\x00\x00\x73\x5F\x66\x75"
"\x6C\x6C\x62\x72\x69\x67\x68\x74\x00\x00\x00\x00\x05\x00\x04\x00\xD7\x02\x00\x00\x70\x61\x72\x61\x6D\x00\x00\x00\x05\x00\x05\x00"
"\xDA\x02\x00\x00\x6C\x69\x67\x68\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00\xDA\x02\x00\x00\x00\x00\x00\x00\x6C\x5F\x63\x75"
"\x62\x65\x6D\x61\x74\x72\x69\x78\x00\x00\x00\x00\x06\x00\x07\x00\xDA\x02\x00\x00\x01\x00\x00\x00\x6C\x5F\x6C\x69\x67\x68\x74\x70"
"\x6F\x73\x69\x74\x69\x6F\x6E\x00\x06\x00\x05\x00\xDA\x02\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64\x31\x00\x00\x00\x06\x00\x07\x00"
"\xDA\x02\x00\x00\x03\x00\x00\x00\x6C\x5F\x6C\x69\x67\x68\x74\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x06\x00\x05\x00\xDA\x02\x00\x00"
"\x04\x00\x00\x00\x6C\x70\x61\x64\x32\x00\x00\x00\x06\x00\x08\x00\xDA\x02\x00\x00\x05\x00\x00\x00\x6C\x5F\x6C\x69\x67\x68\x74\x63"
"\x6F\x6C\x6F\x75\x72\x73\x63\x61\x6C\x65\x00\x00\x06\x00\x07\x00\xDA\x02\x00\x00\x06\x00\x00\x00\x6C\x5F\x6C\x69\x67\x68\x74\x72"
"\x61\x64\x69\x75\x73\x00\x00\x00\x06\x00\x07\x00\xDA\x02\x00\x00\x07\x00\x00\x00\x6C\x5F\x73\x68\x61\x64\x6F\x77\x6D\x61\x70\x70"
"\x72\x6F\x6A\x00\x06\x00\x08\x00\xDA\x02\x00\x00\x08\x00\x00\x00\x6C\x5F\x73\x68\x61\x64\x6F\x77\x6D\x61\x70\x73\x63\x61\x6C\x65"
"\x00\x00\x00\x00\x06\x00\x05\x00\xDA\x02\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00\x05\x00\x03\x00\xDC\x02\x00\x00"
"\x6C\x6C\x62\x72\x69\x67\x68\x74\x00\x00\x00\x00\x05\x00\x04\x00\xD8\x02\x00\x00\x70\x61\x72\x61\x6D\x00\x00\x00\x05\x00\x05\x00"
"\xDB\x02\x00\x00\x6C\x69\x67\x68\x74\x62\x6C\x6F\x63\x6B\x00\x00\x06\x00\x07\x00\xDB\x02\x00\x00\x00\x00\x00\x00\x6C\x5F\x63\x75"
"\x62\x65\x6D\x61\x74\x72\x69\x78\x00\x00\x00\x00\x06\x00\x07\x00\xDB\x02\x00\x00\x01\x00\x00\x00\x6C\x5F\x6C\x69\x67\x68\x74\x70"
"\x6F\x73\x69\x74\x69\x6F\x6E\x00\x06\x00\x05\x00\xDB\x02\x00\x00\x02\x00\x00\x00\x6C\x70\x61\x64\x31\x00\x00\x00\x06\x00\x07\x00"
"\xDB\x02\x00\x00\x03\x00\x00\x00\x6C\x5F\x6C\x69\x67\x68\x74\x63\x6F\x6C\x6F\x75\x72\x00\x00\x00\x06\x00\x05\x00\xDB\x02\x00\x00"
"\x04\x00\x00\x00\x6C\x70\x61\x64\x32\x00\x00\x00\x06\x00\x08\x00\xDB\x02\x00\x00\x05\x00\x00\x00\x6C\x5F\x6C\x69\x67\x68\x74\x63"
"\x6F\x6C\x6F\x75\x72\x73\x63\x61\x6C\x65\x00\x00\x06\x00\x07\x00\xDB\x02\x00\x00\x06\x00\x00\x00\x6C\x5F\x6C\x69\x67\x68\x74\x72"
"\x61\x64\x69\x75\x73\x00\x00\x00\x06\x00\x07\x00\xDB\x02\x00\x00\x07\x00\x00\x00\x6C\x5F\x73\x68\x61\x64\x6F\x77\x6D\x61\x70\x70"
"\x72\x6F\x6A\x00\x06\x00\x08\x00\xDB\x02\x00\x00\x08\x00\x00\x00\x6C\x5F\x73\x68\x61\x64\x6F\x77\x6D\x61\x70\x73\x63\x61\x6C\x65"
"\x00\x00\x00\x00\x06\x00\x05\x00\xDB\x02\x00\x00\x09\x00\x00\x00\x6C\x70\x61\x64\x33\x00\x00\x00\x05\x00\x03\x00\xDD\x02\x00\x00"
"\x00\x00\x00\x00\x47\x00\x04\x00\x28\x00\x00\x00\x01\x00\x00\x00\x15\x00\x00\x00\x47\x00\x04\x00\x36\x00\x00\x00\x06\x00\x00\x00"
"\x10\x00\x00\x00\x48\x00\x04\x00\x37\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\x37\x00\x00\x00\x00\x00\x00\x00"
"\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\x37\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00\x48\x00\x04\x00"
@ -6341,15 +6342,15 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\x8B\x02\x00\x00\x21\x00\x00\x00\x0B\x00\x00\x00\x47\x00\x04\x00\xAF\x02\x00\x00"
"\x01\x00\x00\x00\x11\x00\x00\x00\x47\x00\x04\x00\xB3\x02\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\xB3\x02\x00\x00"
"\x21\x00\x00\x00\x05\x00\x00\x00\x47\x00\x04\x00\xC2\x02\x00\x00\x01\x00\x00\x00\x06\x01\x00\x00\x47\x00\x04\x00\xC6\x02\x00\x00"
"\x01\x00\x00\x00\x07\x01\x00\x00\x48\x00\x04\x00\xDA\x02\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\xDA\x02\x00\x00"
"\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\xDA\x02\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00"
"\x48\x00\x05\x00\xDA\x02\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\xDA\x02\x00\x00\x02\x00\x00\x00"
"\x23\x00\x00\x00\x4C\x00\x00\x00\x48\x00\x05\x00\xDA\x02\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00\x50\x00\x00\x00\x48\x00\x05\x00"
"\xDA\x02\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\x5C\x00\x00\x00\x48\x00\x05\x00\xDA\x02\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00"
"\x60\x00\x00\x00\x48\x00\x05\x00\xDA\x02\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00\x6C\x00\x00\x00\x48\x00\x05\x00\xDA\x02\x00\x00"
"\x07\x00\x00\x00\x23\x00\x00\x00\x70\x00\x00\x00\x48\x00\x05\x00\xDA\x02\x00\x00\x08\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00"
"\x48\x00\x05\x00\xDA\x02\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\x88\x00\x00\x00\x47\x00\x03\x00\xDA\x02\x00\x00\x02\x00\x00\x00"
"\x47\x00\x04\x00\xDC\x02\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\xDC\x02\x00\x00\x21\x00\x00\x00\x01\x00\x00\x00"
"\x01\x00\x00\x00\x07\x01\x00\x00\x48\x00\x04\x00\xDB\x02\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x48\x00\x05\x00\xDB\x02\x00\x00"
"\x00\x00\x00\x00\x23\x00\x00\x00\x00\x00\x00\x00\x48\x00\x05\x00\xDB\x02\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x10\x00\x00\x00"
"\x48\x00\x05\x00\xDB\x02\x00\x00\x01\x00\x00\x00\x23\x00\x00\x00\x40\x00\x00\x00\x48\x00\x05\x00\xDB\x02\x00\x00\x02\x00\x00\x00"
"\x23\x00\x00\x00\x4C\x00\x00\x00\x48\x00\x05\x00\xDB\x02\x00\x00\x03\x00\x00\x00\x23\x00\x00\x00\x50\x00\x00\x00\x48\x00\x05\x00"
"\xDB\x02\x00\x00\x04\x00\x00\x00\x23\x00\x00\x00\x5C\x00\x00\x00\x48\x00\x05\x00\xDB\x02\x00\x00\x05\x00\x00\x00\x23\x00\x00\x00"
"\x60\x00\x00\x00\x48\x00\x05\x00\xDB\x02\x00\x00\x06\x00\x00\x00\x23\x00\x00\x00\x6C\x00\x00\x00\x48\x00\x05\x00\xDB\x02\x00\x00"
"\x07\x00\x00\x00\x23\x00\x00\x00\x70\x00\x00\x00\x48\x00\x05\x00\xDB\x02\x00\x00\x08\x00\x00\x00\x23\x00\x00\x00\x80\x00\x00\x00"
"\x48\x00\x05\x00\xDB\x02\x00\x00\x09\x00\x00\x00\x23\x00\x00\x00\x88\x00\x00\x00\x47\x00\x03\x00\xDB\x02\x00\x00\x02\x00\x00\x00"
"\x47\x00\x04\x00\xDD\x02\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x47\x00\x04\x00\xDD\x02\x00\x00\x21\x00\x00\x00\x01\x00\x00\x00"
"\x13\x00\x02\x00\x02\x00\x00\x00\x21\x00\x03\x00\x03\x00\x00\x00\x02\x00\x00\x00\x16\x00\x03\x00\x06\x00\x00\x00\x20\x00\x00\x00"
"\x17\x00\x04\x00\x07\x00\x00\x00\x06\x00\x00\x00\x03\x00\x00\x00\x20\x00\x04\x00\x08\x00\x00\x00\x07\x00\x00\x00\x07\x00\x00\x00"
"\x21\x00\x04\x00\x09\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\x17\x00\x04\x00\x10\x00\x00\x00\x06\x00\x00\x00\x04\x00\x00\x00"
@ -6403,9 +6404,9 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"\x94\x02\x00\x00\x03\x00\x00\x00\x06\x00\x00\x00\x32\x00\x04\x00\x27\x00\x00\x00\xAF\x02\x00\x00\x11\x00\x00\x00\x3B\x00\x04\x00"
"\x9C\x01\x00\x00\xB3\x02\x00\x00\x00\x00\x00\x00\x2B\x00\x04\x00\x27\x00\x00\x00\xBE\x02\x00\x00\x12\x00\x00\x00\x32\x00\x04\x00"
"\x06\x00\x00\x00\xC2\x02\x00\x00\x00\x00\x83\x43\x32\x00\x04\x00\x27\x00\x00\x00\xC6\x02\x00\x00\x07\x01\x00\x00\x1E\x00\x0C\x00"
"\xDA\x02\x00\x00\x33\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00"
"\x10\x00\x00\x00\x1F\x00\x00\x00\x1F\x00\x00\x00\x20\x00\x04\x00\xDB\x02\x00\x00\x02\x00\x00\x00\xDA\x02\x00\x00\x3B\x00\x04\x00"
"\xDB\x02\x00\x00\xDC\x02\x00\x00\x02\x00\x00\x00\x36\x00\x05\x00\x02\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00"
"\xDB\x02\x00\x00\x33\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x06\x00\x00\x00"
"\x10\x00\x00\x00\x1F\x00\x00\x00\x1F\x00\x00\x00\x20\x00\x04\x00\xDC\x02\x00\x00\x02\x00\x00\x00\xDB\x02\x00\x00\x3B\x00\x04\x00"
"\xDC\x02\x00\x00\xDD\x02\x00\x00\x02\x00\x00\x00\x36\x00\x05\x00\x02\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00"
"\xF8\x00\x02\x00\x05\x00\x00\x00\x3B\x00\x04\x00\x20\x00\x00\x00\x95\x01\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x1E\x00\x00\x00"
"\xA0\x01\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x20\x00\x00\x00\xA2\x01\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x08\x00\x00\x00"
"\xA4\x01\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x08\x00\x00\x00\xBA\x01\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x08\x00\x00\x00"
@ -6413,7 +6414,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"\xF9\x01\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x11\x00\x00\x00\x12\x02\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x08\x00\x00\x00"
"\x19\x02\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x31\x00\x00\x00\x2A\x02\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x08\x00\x00\x00"
"\x42\x02\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x31\x00\x00\x00\x81\x02\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x11\x00\x00\x00"
"\xD7\x02\x00\x00\x07\x00\x00\x00\x3D\x00\x04\x00\x1F\x00\x00\x00\x98\x01\x00\x00\x97\x01\x00\x00\x3E\x00\x03\x00\x95\x01\x00\x00"
"\xD8\x02\x00\x00\x07\x00\x00\x00\x3D\x00\x04\x00\x1F\x00\x00\x00\x98\x01\x00\x00\x97\x01\x00\x00\x3E\x00\x03\x00\x95\x01\x00\x00"
"\x98\x01\x00\x00\xBA\x00\x05\x00\x2A\x00\x00\x00\x99\x01\x00\x00\x65\x01\x00\x00\x49\x00\x00\x00\xF7\x00\x03\x00\x9B\x01\x00\x00"
"\x00\x00\x00\x00\xFA\x00\x04\x00\x99\x01\x00\x00\x9A\x01\x00\x00\x9B\x01\x00\x00\xF8\x00\x02\x00\x9A\x01\x00\x00\x3D\x00\x04\x00"
"\x1D\x00\x00\x00\xA1\x01\x00\x00\x9D\x01\x00\x00\x3E\x00\x03\x00\xA0\x01\x00\x00\xA1\x01\x00\x00\x3D\x00\x04\x00\x1F\x00\x00\x00"
@ -6593,9 +6594,10 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"\x45\x00\x00\x00\x3D\x00\x04\x00\x06\x00\x00\x00\xD2\x02\x00\x00\xD1\x02\x00\x00\xBE\x00\x05\x00\x2A\x00\x00\x00\xD3\x02\x00\x00"
"\xD2\x02\x00\x00\xC2\x02\x00\x00\xF7\x00\x03\x00\xD5\x02\x00\x00\x00\x00\x00\x00\xFA\x00\x04\x00\xD3\x02\x00\x00\xD4\x02\x00\x00"
"\xD5\x02\x00\x00\xF8\x00\x02\x00\xD4\x02\x00\x00\xFC\x00\x01\x00\xF8\x00\x02\x00\xD5\x02\x00\x00\xF9\x00\x02\x00\xC9\x02\x00\x00"
"\xF8\x00\x02\x00\xC9\x02\x00\x00\xF9\x00\x02\x00\xC5\x02\x00\x00\xF8\x00\x02\x00\xC5\x02\x00\x00\x3D\x00\x04\x00\x10\x00\x00\x00"
"\xD8\x02\x00\x00\xA8\x01\x00\x00\x3E\x00\x03\x00\xD7\x02\x00\x00\xD8\x02\x00\x00\x39\x00\x05\x00\x10\x00\x00\x00\xD9\x02\x00\x00"
"\x14\x00\x00\x00\xD7\x02\x00\x00\x3E\x00\x03\x00\xA8\x01\x00\x00\xD9\x02\x00\x00\xFD\x00\x01\x00\x38\x00\x01\x00\x36\x00\x05\x00"
"\xF8\x00\x02\x00\xC9\x02\x00\x00\x41\x00\x05\x00\x94\x02\x00\x00\xD7\x02\x00\x00\xA8\x01\x00\x00\x45\x00\x00\x00\x3E\x00\x03\x00"
"\xD7\x02\x00\x00\x5D\x00\x00\x00\xF9\x00\x02\x00\xC5\x02\x00\x00\xF8\x00\x02\x00\xC5\x02\x00\x00\x3D\x00\x04\x00\x10\x00\x00\x00"
"\xD9\x02\x00\x00\xA8\x01\x00\x00\x3E\x00\x03\x00\xD8\x02\x00\x00\xD9\x02\x00\x00\x39\x00\x05\x00\x10\x00\x00\x00\xDA\x02\x00\x00"
"\x14\x00\x00\x00\xD8\x02\x00\x00\x3E\x00\x03\x00\xA8\x01\x00\x00\xDA\x02\x00\x00\xFD\x00\x01\x00\x38\x00\x01\x00\x36\x00\x05\x00"
"\x07\x00\x00\x00\x0B\x00\x00\x00\x00\x00\x00\x00\x09\x00\x00\x00\x37\x00\x03\x00\x08\x00\x00\x00\x0A\x00\x00\x00\xF8\x00\x02\x00"
"\x0C\x00\x00\x00\x3B\x00\x04\x00\x31\x00\x00\x00\x32\x00\x00\x00\x07\x00\x00\x00\x3B\x00\x04\x00\x31\x00\x00\x00\x57\x00\x00\x00"
"\x07\x00\x00\x00\xAB\x00\x05\x00\x2A\x00\x00\x00\x2B\x00\x00\x00\x28\x00\x00\x00\x29\x00\x00\x00\xA8\x00\x04\x00\x2A\x00\x00\x00"
@ -6814,6 +6816,288 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"\xFE\x00\x02\x00\x90\x01\x00\x00\xF8\x00\x02\x00\x68\x01\x00\x00\xF9\x00\x02\x00\x12\x01\x00\x00\xF8\x00\x02\x00\x12\x01\x00\x00"
"\x3D\x00\x04\x00\x1F\x00\x00\x00\x92\x01\x00\x00\x23\x00\x00\x00\xFE\x00\x02\x00\x92\x01\x00\x00\x38\x00\x01\x00"},
#endif
#ifdef D3D9QUAKE
{QR_DIRECT3D9, 9, "defaultwall",
//!!ver 100 150
//!!permu DELUXE
"!!permu FULLBRIGHT\n"
"!!permu FOG\n"
//!!permu LIGHTSTYLED
//!!permu BUMP
//!!permu SPECULAR
//!!permu REFLECTCUBEMASK
//!!cvarf r_glsl_offsetmapping_scale
//!!cvardf r_tessellation_level=5
//!!samps diffuse lightmap specular normalmap fullbright reflectmask reflectcube paletted lightmap1 lightmap2 lightmap3
"!!samps diffuse fullbright lightmap\n"
//#include "sys/defs.h"
"#define vec4 float4\n"
"#define vec3 float3\n"
"#define vec2 float2\n"
"#define texture2D tex2D\n"
"#define mat3 float3x3\n"
"#define mat4 float4x4\n"
"struct a2v\n"
"{\n"
"vec4 v_position : POSITION;\n"
"vec2 v_texcoord : TEXCOORD0;\n"
"vec2 v_lmcoord : TEXCOORD1;\n"
"};\n"
"struct v2f\n"
"{\n"
"#ifndef FRAGMENT_SHADER\n"
"vec4 pos: POSITION;\n"
"#endif\n"
"#if defined(OFFSETMAPPING) || defined(SPECULAR) || defined(REFLECTCUBEMASK) || defined(FOG)\n"
"vec3 eyevector : TEXCOORD4;\n"
"#endif\n"
"#if defined(REFLECTCUBEMASK) || defined(BUMPMODELSPACE)\n"
"mat3 invsurface : TEXCOORD5;\n"
"#endif\n"
"vec4 tclm : TEXCOORD0;\n"
"vec4 vc : COLOR0;\n"
"#ifndef VERTEXLIT\n"
"#ifdef LIGHTSTYLED\n"
//we could use an offset, but that would still need to be per-surface which would break batches
//fixme: merge attributes?
"vec2 lm1 : TEXCOORD1, lm2 : TEXCOORD2, lm3 : TEXCOORD3;\n"
"#endif\n"
"#endif\n"
"};\n"
//this is what normally draws all of your walls, even with rtlights disabled
//note that the '286' preset uses drawflat_walls instead.
"#include \"sys/fog.h\"\n"
"#ifdef VERTEX_SHADER\n"
"float4x4 m_modelviewprojection;\n"
"float4x4 m_modelview;\n"
"vec3 e_eyepos;\n"
"vec4 e_lmscale;\n"
"v2f main (a2v inp)\n"
"{\n"
"v2f outp;\n"
"#if defined(OFFSETMAPPING) || defined(SPECULAR) || defined(REFLECTCUBEMASK)\n"
"vec3 eyeminusvertex = e_eyepos - inp.v_position.xyz;\n"
"outp.eyevector.x = dot(eyeminusvertex, inp.v_svector.xyz);\n"
"outp.eyevector.y = dot(eyeminusvertex, inp.v_tvector.xyz);\n"
"outp.eyevector.z = dot(eyeminusvertex, inp.v_normal.xyz);\n"
"#elif defined(FOG)\n"
"outp.eyevector = mul(m_modelview, inp.v_position);\n"
"#endif\n"
"#if defined(REFLECTCUBEMASK) || defined(BUMPMODELSPACE)\n"
"outp.invsurface[0] = inp.v_svector;\n"
"outp.invsurface[1] = inp.v_tvector;\n"
"outp.invsurface[2] = inp.v_normal;\n"
"#endif\n"
"outp.tclm.xy = inp.v_texcoord;\n"
"#ifdef FLOW\n"
// outp.tclm.x += e_time * -0.5;
"#endif\n"
"#ifdef VERTEXLIT\n"
"#ifdef LIGHTSTYLED\n"
//FIXME, only one colour.
"outp.vc = inp.v_colour * e_lmscale[0];\n"
"#else\n"
"outp.vc = inp.v_colour * e_lmscale;\n"
"#endif\n"
"#else\n"
"outp.vc = e_lmscale;\n"
"outp.tclm.zw = inp.v_lmcoord;\n"
"#ifdef LIGHTSTYLED\n"
"outp.lm1 = inp.v_lmcoord2;\n"
"outp.lm2 = inp.v_lmcoord3;\n"
"outp.lm3 = inp.v_lmcoord4;\n"
"#endif\n"
"#endif\n"
"outp.pos = mul(m_modelviewprojection, inp.v_position);\n"
"return outp;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"sampler s_diffuse : register(s0);\n"
//sampler s_normalmap;
//sampler s_specular;
//sampler s_upper;
//sampler s_lower;
"sampler s_fullbright : register(s1);\n"
//sampler s_paletted;
//sampler s_reflectcube;
//sampler s_reflectmask;
"sampler s_lightmap : register(s2);\n"
//sampler s_deluxmap;
//samplers
"#define s_colourmap s_t0\n"
//sampler2D s_colourmap;
//vec4 e_lmscale;
"vec4 e_colourident;\n"
"#ifdef OFFSETMAPPING\n"
"#include \"sys/offsetmapping.h\"\n"
"#endif\n"
"vec4 main (v2f inp) : COLOR0\n"
"{\n"
"vec4 gl_FragColor;\n"
"#define tc (inp.tclm.xy)\n"
"#define lm0 (inp.tclm.zw)\n"
//adjust texture coords for offsetmapping
"#ifdef OFFSETMAPPING\n"
"vec2 tcoffsetmap = offsetmap(s_normalmap, tc, eyevector);\n"
"#define tc tcoffsetmap\n"
"#endif\n"
"#if defined(EIGHTBIT) && !defined(LIGHTSTYLED)\n"
//optional: round the lightmap coords to ensure all pixels within a texel have different lighting values either. it just looks wrong otherwise.
//don't bother if its lightstyled, such cases will have unpredictable correlations anyway.
//FIXME: this rounding is likely not correct with respect to software rendering. oh well.
"#if __VERSION__ >= 130\n"
"vec2 lmsize = vec2(textureSize(s_lightmap0, 0));\n"
"#else\n"
"#define lmsize vec2(128.0,2048.0)\n"
"#endif\n"
"#define texelstolightmap (16.0)\n"
"vec2 lmcoord0 = floor(lm0 * lmsize*texelstolightmap)/(lmsize*texelstolightmap);\n"
"#define lm0 lmcoord0\n"
"#endif\n"
//yay, regular texture!
"gl_FragColor = texture2D(s_diffuse, tc);\n"
"#if defined(BUMP) && (defined(DELUXE) || defined(SPECULAR) || defined(REFLECTCUBEMASK))\n"
"vec3 norm = normalize(texture2D(s_normalmap, tc).rgb - 0.5);\n"
"#elif defined(SPECULAR) || defined(DELUXE) || defined(REFLECTCUBEMASK)\n"
"vec3 norm = vec3(0, 0, 1); //specular lighting expects this to exist.\n"
"#endif\n"
//modulate that by the lightmap(s) including deluxemap(s)
"#ifdef VERTEXLIT\n"
"#error foobar\n"
"#ifdef LIGHTSTYLED\n"
"vec3 lightmaps = vc.rgb;\n"
"#else\n"
"vec3 lightmaps = vc.rgb;\n"
"#endif\n"
"#define delux vec3(0.0,0.0,1.0)\n"
"#else\n"
"#ifdef LIGHTSTYLED\n"
"#error foobar\n"
"#define delux vec3(0.0,0.0,1.0)\n"
"vec3 lightmaps;\n"
"#ifdef DELUXE\n"
"lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb * dot(norm, 2.0*texture2D(s_deluxmap0, lm0).rgb-0.5);\n"
"lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb * dot(norm, 2.0*texture2D(s_deluxmap1, lm1).rgb-0.5);\n"
"lightmaps += texture2D(s_lightmap2, lm2).rgb * e_lmscale[2].rgb * dot(norm, 2.0*texture2D(s_deluxmap2, lm2).rgb-0.5);\n"
"lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb * dot(norm, 2.0*texture2D(s_deluxmap3, lm3).rgb-0.5);\n"
"#else\n"
"lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb;\n"
"lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb;\n"
"lightmaps += texture2D(s_lightmap2, lm2).rgb * e_lmscale[2].rgb;\n"
"lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb;\n"
"#endif\n"
"#else\n"
"vec3 lightmaps = texture2D(s_lightmap, lm0).rgb;\n"
//modulate by the bumpmap dot light
"#ifdef DELUXE\n"
"#error foobar\n"
"vec3 delux = (texture2D(s_deluxmap, lm0).rgb-0.5);\n"
"#ifdef BUMPMODELSPACE\n"
"delux = normalize(delux*invsurface);\n"
"#else\n"
"lightmaps *= 2.0 / max(0.25, delux.z); //counter the darkening from deluxmaps\n"
"#endif\n"
"lightmaps *= dot(norm, delux);\n"
"#else\n"
"#define delux vec3(0.0,0.0,1.0)\n"
"#endif\n"
"#endif\n"
"lightmaps *= inp.vc.rgb;\n"
"#endif\n"
//add in specular, if applicable.
"#ifdef SPECULAR\n"
"vec4 specs = texture2D(s_specular, tc);\n"
"vec3 halfdir = normalize(normalize(eyevector) + delux); //this norm should be the deluxemap info instead\n"
"float spec = pow(max(dot(halfdir, norm), 0.0), FTE_SPECULAR_EXPONENT * specs.a);\n"
"spec *= FTE_SPECULAR_MULTIPLIER;\n"
//NOTE: rtlights tend to have a *4 scaler here to over-emphasise the effect because it looks cool.
//As not all maps will have deluxemapping, and the double-cos from the light util makes everything far too dark anyway,
//we default to something that is not garish when the light value is directly infront of every single pixel.
//we can justify this difference due to the rtlight editor etc showing the *4.
"gl_FragColor.rgb += spec * specs.rgb;\n"
"#endif\n"
"#ifdef REFLECTCUBEMASK\n"
"vec3 rtc = reflect(normalize(-eyevector), norm);\n"
"rtc = rtc.x*invsurface[0] + rtc.y*invsurface[1] + rtc.z*invsurface[2];\n"
"rtc = (m_model * vec4(rtc.xyz,0.0)).xyz;\n"
"gl_FragColor.rgb += texture2D(s_reflectmask, tc).rgb * textureCube(s_reflectcube, rtc).rgb;\n"
"#endif\n"
"#ifdef EIGHTBIT //FIXME: with this extra flag, half the permutations are redundant.\n"
"lightmaps *= 0.5; //counter the fact that the colourmap contains overbright values and logically ranges from 0 to 2 intead of to 1.\n"
"float pal = texture2D(s_paletted, tc).r; //the palette index. hopefully not interpolated.\n"
"lightmaps -= 1.0 / 128.0; //software rendering appears to round down, so make sure we favour the lower values instead of rounding to the nearest\n"
"gl_FragColor.r = texture2D(s_colourmap, vec2(pal, 1.0-lightmaps.r)).r; //do 3 lookups. this is to cope with lit files, would be a waste to not support those.\n"
"gl_FragColor.g = texture2D(s_colourmap, vec2(pal, 1.0-lightmaps.g)).g; //its not very softwarey, but re-palettizing is ugly.\n"
"gl_FragColor.b = texture2D(s_colourmap, vec2(pal, 1.0-lightmaps.b)).b; //without lits, it should be identical.\n"
"#else\n"
//now we have our diffuse+specular terms, modulate by lightmap values.
"gl_FragColor.rgb *= lightmaps.rgb;\n"
//add on the fullbright
"#ifdef FULLBRIGHT\n"
"vec4 fb = texture2D(s_fullbright, tc);\n"
"gl_FragColor.rgb += fb.rgb*fb.a;\n"
"#endif\n"
"#endif\n"
//entity modifiers
"gl_FragColor = gl_FragColor * e_colourident;\n"
"#if defined(MASK)\n"
"#if defined(MASKLT)\n"
"if (gl_FragColor.a < MASK)\n"
"discard;\n"
"#else\n"
"if (gl_FragColor.a >= MASK)\n"
"discard;\n"
"#endif\n"
"gl_FragColor.a = 1.0; //alpha blending AND alpha testing usually looks stupid, plus it screws up our fog.\n"
"#endif\n"
//and finally hide it all if we're fogged.
"#ifdef FOG\n"
"gl_FragColor = fog4(gl_FragColor, length(inp.eyevector));\n"
"#endif\n"
"return gl_FragColor;\n"
"}\n"
"#endif\n"
},
#endif
#ifdef D3D11QUAKE
{QR_DIRECT3D11, 11, "defaultwall",
"!!samps diffuse fullbright lightmap\n"

View File

@ -774,6 +774,7 @@ enum {
WARN_IMPLICITCONVERSION,
WARN_EXTRAPRECACHE,
WARN_NOTPRECACHED,
WARN_NONPORTABLEFILENAME,
WARN_DEADCODE,
WARN_UNREACHABLECODE,
WARN_NOTSTANDARDBEHAVIOUR,

View File

@ -4384,6 +4384,8 @@ void QCC_PrecacheSound (const char *n, int ch)
precache_sound[i].block = ch;
return;
}
if (strchr(n, '\\'))
QCC_PR_ParseWarning(WARN_NONPORTABLEFILENAME, "backslashes in path names are non-portable - %s", n);
if (numsounds == QCC_MAX_SOUNDS)
return;
// QCC_Error ("PrecacheSound: numsounds == MAX_SOUNDS");
@ -4412,6 +4414,8 @@ void QCC_PrecacheModel (const char *n, int ch)
}
return;
}
if (strchr(n, '\\'))
QCC_PR_ParseWarning(WARN_NONPORTABLEFILENAME, "backslashes in path names are non-portable - %s", n);
if (nummodels == QCC_MAX_MODELS)
return;
// QCC_Error ("PrecacheModels: nummodels == MAX_MODELS");
@ -4437,6 +4441,8 @@ void QCC_SetModel (const char *n)
precache_model[i].used++;
return;
}
if (strchr(n, '\\'))
QCC_PR_ParseWarning(WARN_NONPORTABLEFILENAME, "backslashes in path names are non-portable - %s", n);
if (nummodels == QCC_MAX_MODELS)
return;
strcpy (precache_model[i].name, n);
@ -4459,6 +4465,8 @@ void QCC_SoundUsed (const char *n)
precache_sound[i].used++;
return;
}
if (strchr(n, '\\'))
QCC_PR_ParseWarning(WARN_NONPORTABLEFILENAME, "backslashes in path names are non-portable - %s", n);
if (numsounds == QCC_MAX_SOUNDS)
return;
strcpy (precache_sound[i].name, n);
@ -4479,6 +4487,8 @@ void QCC_PrecacheTexture (const char *n, int ch)
for (i=0 ; i<numtextures ; i++)
if (!STRCMP(n, precache_texture[i].name))
return;
if (strchr(n, '\\'))
QCC_PR_ParseWarning(WARN_NONPORTABLEFILENAME, "backslashes in path names are non-portable - %s", n);
if (nummodels == QCC_MAX_MODELS)
return;
// QCC_Error ("PrecacheTextures: numtextures == MAX_TEXTURES");
@ -4499,6 +4509,8 @@ void QCC_PrecacheFile (const char *n, int ch)
for (i=0 ; i<numfiles ; i++)
if (!STRCMP(n, precache_file[i].name))
return;
if (strchr(n, '\\'))
QCC_PR_ParseWarning(WARN_NONPORTABLEFILENAME, "backslashes in path names are non-portable - %s", n);
if (numfiles == QCC_MAX_FILES)
return;
// QCC_Error ("PrecacheFile: numfiles == MAX_FILES");

View File

@ -786,6 +786,8 @@ void PR_LoadGlabalStruct(qboolean muted)
int i;
int *v;
globalptrs_t *pr_globals = pr_global_ptrs;
memset(pr_global_ptrs, 0, sizeof(*pr_global_ptrs));
#define globalfloat(need,name) (pr_globals)->name = (float *)PR_FindGlobal(svprogfuncs, #name, 0, NULL); if (need && !(pr_globals)->name) {static float fallback##name; (pr_globals)->name = &fallback##name; if (!muted) Con_DPrintf("Could not find \""#name"\" export in progs\n");}
#define globalint(need,name) (pr_globals)->name = (int *)PR_FindGlobal(svprogfuncs, #name, 0, NULL); if (need && !(pr_globals)->name) {static int fallback##name; (pr_globals)->name = &fallback##name; if (!muted) Con_DPrintf("Could not find \""#name"\" export in progs\n");}
#define globalstring(need,name) (pr_globals)->name = (int *)PR_FindGlobal(svprogfuncs, #name, 0, NULL); if (need && !(pr_globals)->name) {static string_t fallback##name; (pr_globals)->name = &fallback##name; if (!muted) Con_DPrintf("Could not find \""#name"\" export in progs\n");}

View File

@ -5,6 +5,8 @@
#include "pr_common.h"
#include "hash.h"
#define LUA_MALLOC_TAG 0x55780128
#define luagloballist \
globalentity (true, self) \
globalentity (true, other) \
@ -83,7 +85,7 @@ luaextragloballist
typedef struct
{
int type;
quintptr_t offset;
qintptr_t offset;
char *name;
bucket_t buck;
} luafld_t;
@ -2218,7 +2220,7 @@ static int bi_lua_pairs (lua_State *L) {
static int bi_lua_objerror (lua_State *L)
{
SV_Error("objerror: %s\n", lua_tostring(L, 1));
Con_Printf("\n");
lua_pushedict(L, lua.edicttable[lua.globals.self]);
lua_pushnil(L);
@ -2230,11 +2232,11 @@ static int bi_lua_objerror (lua_State *L)
{
int i;
const void *ud = lua_topointer(L, -2);
for (i = 0; i < countof(lua.entflds); i++)
if (lua.entflds[i].offset == (quintptr_t)ud)
for (i = 0; i < lua.numflds; i++)
if (lua.entflds[i].offset == (qintptr_t)ud)
break;
if (i == countof(lua.entflds))
if (i == lua.numflds)
Con_Printf("%21s:", lua_typename(L, lua_type(L, -2)));
else
Con_Printf("%21s:", lua.entflds[i].name);
@ -2260,6 +2262,8 @@ static int bi_lua_objerror (lua_State *L)
}
lua_pop(L, 1);
Con_Printf("objerror: %s\n", lua_tostring(L, 1));
return 0;
}
static int bi_lua_error (lua_State *L)
@ -2788,7 +2792,6 @@ static const char *Lua_ParseEdict (pubprogfuncs_t *progfuncs, const char *data,
}
*/
cont:
fld = Hash_GetInsensitive(&lua.entityfields, keyname);
if (fld && fld->type == ev_float)
lua_pushnumber(L, atof(token));
@ -2809,6 +2812,13 @@ cont:
e++;
lua_pushvector(L, x, y, z);
}
else if (fld && fld->type == ev_function)
lua_getglobal(L, token); //functions are nameless, except for how they're invoked. so this is only for evil mods...
else if (fld && fld->type == ev_entity)
{
int num = atoi(token);
lua_pushedict(L, EDICT_NUM_UB((&lua.progfuncs), num));
}
else
lua_pushstring(L, token);
lua_setfield(L, -2, keyname);
@ -2942,7 +2952,7 @@ char *QDECL Lua_AddString(pubprogfuncs_t *prinst, const char *val, int minlength
int len = strlen(val)+1;
if (len < minlength)
len = minlength;
ptr = Z_TagMalloc(len, 0x55780128);
ptr = Z_TagMalloc(len, LUA_MALLOC_TAG);
strcpy(ptr, val);
return ptr;
}
@ -3215,6 +3225,8 @@ void PDECL Lua_CloseProgs(pubprogfuncs_t *inst)
lua.maxedicts = 0;
memset(&lua, 0, sizeof(lua));
Z_FreeTags(LUA_MALLOC_TAG);
}
static void QDECL Lua_Get_FrameState(world_t *w, wedict_t *ent, framestate_t *fstate)

View File

@ -1413,7 +1413,7 @@ static int QDECL CompleteSaveList (const char *name, qofs_t flags, time_t mtime,
if (l >= 9 && !Q_strcasecmp(trimmed+l-9, "/info.fsv"))
{
trimmed[l-9] = 0;
ctx->cb(trimmed, ctx);
ctx->cb(trimmed, NULL, NULL, ctx);
}
return true;
}
@ -1422,7 +1422,7 @@ static int QDECL CompleteSaveListLegacy (const char *name, qofs_t flags, time_t
struct xcommandargcompletioncb_s *ctx = parm;
char stripped[64];
COM_StripExtension(name, stripped, sizeof(stripped));
ctx->cb(stripped, ctx);
ctx->cb(stripped, NULL, NULL, ctx);
return true;
}
void SV_Savegame_c(int argn, const char *partial, struct xcommandargcompletioncb_s *ctx)

View File

@ -411,7 +411,7 @@ static int QDECL CompleteMapList (const char *name, qofs_t flags, time_t mtime,
return true;
COM_StripExtension(name+5, stripped, sizeof(stripped));
ctx->cb(stripped, ctx);
ctx->cb(stripped, NULL, NULL, ctx);
return true;
}
static int QDECL CompleteMapListExt (const char *name, qofs_t flags, time_t mtime, void *parm, searchpathfuncs_t *spath)
@ -420,7 +420,7 @@ static int QDECL CompleteMapListExt (const char *name, qofs_t flags, time_t mtim
if (name[5] == 'b' && name[6] == '_') //skip box models
return true;
ctx->cb(name+5, ctx);
ctx->cb(name+5, NULL, NULL, ctx);
return true;
}
static void SV_Map_c(int argn, const char *partial, struct xcommandargcompletioncb_s *ctx)

View File

@ -132,7 +132,7 @@ cvar_t pext_ezquake_nochunks = CVARD("pext_ezquake_nochunks", "0", "Prevents ezq
cvar_t sv_gamespeed = CVARAF("sv_gamespeed", "1", "slowmo", 0);
cvar_t sv_csqcdebug = CVAR("sv_csqcdebug", "0");
cvar_t sv_csqc_progname = CVAR("sv_csqc_progname", "csprogs.dat");
cvar_t pausable = CVAR("pausable", "1");
cvar_t pausable = CVAR("pausable", "");
cvar_t sv_banproxies = CVARD("sv_banproxies", "0", "If enabled, anyone connecting via known proxy software will be refused entry. This should aid with blocking aimbots, but is only reliable for certain public proxies.");
cvar_t sv_specprint = CVARD("sv_specprint", "3", "Bitfield that controls which player events spectators see when tracking that player.\n&1: spectators will see centerprints.\n&2: spectators will see sprints (pickup messages etc).\n&4: spectators will receive console commands, this is potentially risky.\nIndividual spectators can use 'setinfo sp foo' to limit this setting.");

View File

@ -2225,7 +2225,7 @@ void WPhys_RunEntity (world_t *w, wedict_t *ent)
else
gravitydir = w->g.defaultgravitydir;
if (!WPhys_CheckWater (w, ent) && ! ((int)ent->v->flags & FL_WATERJUMP) )
if (!WPhys_CheckWater (w, ent) && ! ((int)ent->v->flags & FL_WATERJUMP) ) //Vanilla Bug: the QC checks waterlevel inside PlayerPreThink, with waterlevel from a different position from the origin.
WPhys_AddGravity (w, ent, gravitydir);
WPhys_CheckStuck (w, ent);

View File

@ -728,7 +728,7 @@ static int Sys_CheckChRoot(void)
const char *newhome;
getresuid(&ruid, &euid, &suid);
printf("ruid %u, euid %u, suid %u\n", ruid, euid, suid);
// printf("ruid %u, euid %u, suid %u\n", ruid, euid, suid);
if (!euid && ruid != euid)
{ //if we're running SUID-root then assume the admin set it up that way in order to use chroot without making any libraries available inside the jail.
//however, chroot needs a certain level of sandboxing to prevent somehow running suid programs with eg a custom /etc/passwd, etc.
@ -775,7 +775,7 @@ static int Sys_CheckChRoot(void)
//SSL_InitGlobal(true); //make sure we load our public cert from outside the sandbox. an exploit might still be able to find it in memory though. FIXME: disabled in case this reads from somewhere bad - we're still root.
#endif
printf("Changing to root: \"%s\"\n", newroot);
printf("Changing root dir to \"%s\"\n", newroot);
if (chroot(newroot))
{
printf("chroot call failed\n");

View File

@ -4007,7 +4007,12 @@ SV_Pause_f
*/
void SV_Pause_f (void)
{
if (!pausable.value)
int maypause;
if (!*pausable.string)
maypause = !deathmatch.ival;
else
maypause = pausable.ival;
if (!maypause)
{
SV_ClientTPrintf (host_client, PRINT_HIGH, "Can't pause. Not allowed\n");
return;

View File

@ -352,6 +352,7 @@ void main ()
if (gl_FragColor.a >= MASK)
discard;
#endif
gl_FragColor.a = 1.0; //alpha blending AND alpha testing usually looks stupid, plus it screws up our fog.
#endif
//and finally hide it all if we're fogged.

View File

@ -200,6 +200,7 @@ void main ()
if (gl_FragColor.a >= arg_mask)
discard;
}
gl_FragColor.a = 1.0;
}
//and finally hide it all if we're fogged.