update qccgui debugging to show current values on mouse-over, for more friendly debugging.

update gl_maxdist to use 0 again. might be more z-fighting, but at least people will stop complaining about far clip planes.
don't try loading skin "".
significantly reduce spam about missing spawn functions.
win64: if win64 q2 gamecode is missing, but win32 gamecode can be found, print out a specific warning to drive home the point that q2 needs gamecode to match the exe arch.
don't try autocompiling, noone cares, its just spam and distracts from the real issue.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4815 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2015-01-02 05:20:56 +00:00
parent dd57aa60aa
commit f8e247f1c4
19 changed files with 496 additions and 234 deletions

View file

@ -1760,12 +1760,12 @@ void Key_WriteBindings (vfsfile_t *f)
s = va("%s%s", prefix, Key_KeynumToString(i));
//quote it as required
if (i == ';' || i <= ' ' || i == '\"')
s = COM_QuotedString(s, keybuf, sizeof(keybuf));
s = COM_QuotedString(s, keybuf, sizeof(keybuf), false);
if (bindcmdlevel[i][m] != bindcmdlevel[i][0])
s = va("bindlevel %s %i %s\n", s, bindcmdlevel[i][m], COM_QuotedString(binding, commandbuf, sizeof(commandbuf)));
s = va("bindlevel %s %i %s\n", s, bindcmdlevel[i][m], COM_QuotedString(binding, commandbuf, sizeof(commandbuf), false));
else
s = va("bind %s %s\n", s, COM_QuotedString(binding, commandbuf, sizeof(commandbuf)));
s = va("bind %s %s\n", s, COM_QuotedString(binding, commandbuf, sizeof(commandbuf), false));
VFS_WRITE(f, s, strlen(s));
}
}

View file

@ -824,7 +824,7 @@ void FPS_Preset_f (void)
if (COM_FCheckExists(presetfname))
{
char buffer[MAX_OSPATH];
COM_QuotedString(presetfname, buffer, sizeof(buffer));
COM_QuotedString(presetfname, buffer, sizeof(buffer), false);
Cbuf_AddText(va("\nexec %s\n", buffer), RESTRICT_LOCAL);
return;
}

View file

@ -14,7 +14,7 @@ void M_Script_Option (menu_t *menu, char *optionvalue)
char buf[8192];
//update the option
Cbuf_AddText(va("set option %s\n", COM_QuotedString(optionvalue, buf, sizeof(buf))), RESTRICT_LOCAL);
Cbuf_AddText(va("set option %s\n", COM_QuotedString(optionvalue, buf, sizeof(buf), false)), RESTRICT_LOCAL);
//expand private arguments
for (mo = menu->options, *buf = 0; mo; mo = mo->common.next)

View file

@ -320,7 +320,7 @@ cvar_t gl_savecompressedtex = CVARD ("gl_savecompressedtex", "0", "Write ou
//cvar_t gl_schematics = CVARD ("gl_schematics", "0", "Gimmick rendering mode that draws the length of various world edges.");
cvar_t gl_skyboxdist = CVARD ("gl_skyboxdist", "0", "The distance of the skybox. If 0, the engine will determine it based upon the far clip plane distance."); //0 = guess.
cvar_t gl_smoothcrosshair = SCVAR ("gl_smoothcrosshair", "1");
cvar_t gl_maxdist = CVARD ("gl_maxdist", "8192", "The distance of the far clip plane. If set to 0, some fancy maths will be used to place it at an infinite distance.");
cvar_t gl_maxdist = CVARD ("gl_maxdist", "0", "The distance of the far clip plane. If set to 0, some fancy maths will be used to place it at an infinite distance.");
#ifdef SPECULAR
cvar_t gl_specular = CVARF ("gl_specular", "1", CVAR_ARCHIVE);

View file

@ -219,9 +219,12 @@ void Skin_WorkerLoad(void *skinptr, void *data, size_t a, size_t b)
{
//if its not already the base skin, try the base (and warn if anything not base couldn't load).
Con_Printf ("Couldn't load skin %s\n", name);
if (*baseskin.string)
{
Q_snprintfz (name, sizeof(name), "skins/%s.pcx", baseskin.string);
raw = COM_LoadTempFile (name, &pcxsize);
}
}
if (!raw)
{
Skin_WorkerDone(skin, NULL, 0, 0);

View file

@ -1376,7 +1376,7 @@ void QDECL S_Voip_EnumeratedCaptureDevice(const char *driver, const char *device
else
fullintname = driver;
Q_snprintfz(opts, sizeof(opts), "%s%s%s %s", snd_voip_capturedevice_opts.string, *snd_voip_capturedevice_opts.string?" ":"", COM_QuotedString(fullintname, nbuf, sizeof(nbuf)), COM_QuotedString(readabledevice, dbuf, sizeof(dbuf)));
Q_snprintfz(opts, sizeof(opts), "%s%s%s %s", snd_voip_capturedevice_opts.string, *snd_voip_capturedevice_opts.string?" ":"", COM_QuotedString(fullintname, nbuf, sizeof(nbuf), false), COM_QuotedString(readabledevice, dbuf, sizeof(dbuf), false));
Cvar_ForceSet(&snd_voip_capturedevice_opts, opts);
}
void S_Voip_Init(void)
@ -1670,7 +1670,7 @@ void QDECL S_EnumeratedOutDevice(const char *driver, const char *devicecode, con
else
fullintname = driver;
Q_snprintfz(opts, sizeof(opts), "%s%s%s %s", snd_device_opts.string, *snd_device_opts.string?" ":"", COM_QuotedString(fullintname, nbuf, sizeof(nbuf)), COM_QuotedString(readabledevice, dbuf, sizeof(dbuf)));
Q_snprintfz(opts, sizeof(opts), "%s%s%s %s", snd_device_opts.string, *snd_device_opts.string?" ":"", COM_QuotedString(fullintname, nbuf, sizeof(nbuf), false), COM_QuotedString(readabledevice, dbuf, sizeof(dbuf), false));
Cvar_ForceSet(&snd_device_opts, opts);
}
void S_EnumerateDevices(void)

View file

@ -1987,8 +1987,7 @@ void Sys_CloseTerminal (void)
//
////////////////////////////
int debuggerresume;
int debuggerresumeline;
qboolean QCExternalDebuggerCommand(char *text);
void Sys_SendKeyEvents (void)
{
MSG msg;
@ -2033,46 +2032,8 @@ void Sys_SendKeyEvents (void)
sys_parentheight = strtoul(Cmd_Argv(4), NULL, 0);
sys_parentwindow = (HWND)(intptr_t)strtoull(Cmd_Argv(5), NULL, 16);
}
else if ((!strncmp(text, "qcstep", 6) && (text[6] == 0 || text[6] == ' ')) || (!strncmp(text, "qcresume", 8) && (text[8] == 0 || text[8] == ' ')))
{
int l;
if (text[2] == 's')
{
debuggerresume = true;
l = atoi(text+7);
}
else
{
l = atoi(text+9);
debuggerresume = 2;
}
if (l)
debuggerresumeline = l;
}
else if (!strncmp(text, "qcbreakpoint ", 13))
{
extern world_t csqc_world, menu_world;
int mode;
char *filename;
int line;
Cmd_TokenizeString(text, false, false);
mode = strtoul(Cmd_Argv(1), NULL, 0);
filename = Cmd_Argv(2);
line = strtoul(Cmd_Argv(3), NULL, 0);
//togglebreakpoint just finds the first statement (via the function table for file names) with the specified line number, and sets some unused high bit that causes it to be an invalid opcode.
#ifdef CSQC_DAT
if (csqc_world.progs && csqc_world.progs->ToggleBreak)
csqc_world.progs->ToggleBreak(csqc_world.progs, filename, line, mode);
#endif
#ifdef MENU_DAT
if (menu_world.progs && menu_world.progs->ToggleBreak)
menu_world.progs->ToggleBreak(menu_world.progs, filename, line, mode);
#endif
#ifndef CLIENTONLY
if (sv.world.progs && sv.world.progs->ToggleBreak)
sv.world.progs->ToggleBreak(sv.world.progs, filename, line, mode);
#endif
}
else if (QCExternalDebuggerCommand(text))
/*handled elsewhere*/;
else
{
Cbuf_AddText(text, RESTRICT_LOCAL);

View file

@ -1003,7 +1003,7 @@ void Alias_WriteAliases (vfsfile_t *f)
s = va("\n//////////////////\n//Aliases\n");
VFS_WRITE(f, s, strlen(s));
}
s = va("alias %s %s\n", cmd->name, COM_QuotedString(cmd->value, buf, sizeof(buf)));
s = va("alias %s %s\n", cmd->name, COM_QuotedString(cmd->value, buf, sizeof(buf), false));
VFS_WRITE(f, s, strlen(s));
if (cmd->restriction != 1) //1 is default
{
@ -1913,11 +1913,11 @@ void Cmd_Apropos_f (void)
else
continue;
COM_QuotedString(var->string, escapedvalue, sizeof(escapedvalue));
COM_QuotedString(var->string, escapedvalue, sizeof(escapedvalue), false);
if (var->latched_string)
{
COM_QuotedString(var->latched_string, latchedvalue, sizeof(latchedvalue));
COM_QuotedString(var->latched_string, latchedvalue, sizeof(latchedvalue), false);
Con_Printf("cvar ^2%s^7: %s (effective %s): %s\n", name, latchedvalue, escapedvalue, var->description?var->description:"no description");
}
else

View file

@ -3948,13 +3948,16 @@ skipwhite:
return (char*)data;
}
const char *COM_QuotedString(const char *string, char *buf, int buflen)
const char *COM_QuotedString(const char *string, char *buf, int buflen, qboolean omitquotes)
{
const char *result = buf;
if (strchr(string, '\r') || strchr(string, '\n') || strchr(string, '\"'))
{
if (!omitquotes)
{
*buf++ = '\\'; //prefix so the reader knows its a quoted string.
*buf++ = '\"'; //opening quote
}
buflen -= 4;
while(*string && buflen >= 2)
{
@ -3994,18 +3997,21 @@ const char *COM_QuotedString(const char *string, char *buf, int buflen)
}
string++;
}
if (!omitquotes)
*buf++ = '\"'; //closing quote
*buf++ = 0;
return result;
}
else
{
if (!omitquotes)
*buf++ = '\"'; //opening quote
buflen -= 3;
while(*string && buflen >= 0)
{
*buf++ = *string++;
}
if (!omitquotes)
*buf++ = '\"'; //closing quote
*buf++ = 0;
return result;

View file

@ -280,7 +280,7 @@ char *COM_ParseCString (const char *data, char *out, size_t maxoutlen, size_t *w
char *COM_StringParse (const char *data, char *token, unsigned int tokenlen, qboolean expandmacros, qboolean qctokenize);
char *COM_ParseToken (const char *data, const char *punctuation);
char *COM_TrimString(char *str, char *buffer, int buffersize);
const char *COM_QuotedString(const char *string, char *buf, int buflen); //inverse of COM_StringParse
const char *COM_QuotedString(const char *string, char *buf, int buflen, qboolean omitquotes); //inverse of COM_StringParse
extern int com_argc;

View file

@ -1225,31 +1225,31 @@ qboolean Cvar_Command (int level)
{
if (v->flags & CVAR_LATCH)
{
Con_Printf ("\"%s\" is currently %s\n", v->name, COM_QuotedString(v->string, buffer, sizeof(buffer)));
Con_Printf ("Will be changed to %s on the next map\n", COM_QuotedString(v->latched_string, buffer, sizeof(buffer)));
Con_Printf ("\"%s\" is currently %s\n", v->name, COM_QuotedString(v->string, buffer, sizeof(buffer), false));
Con_Printf ("Will be changed to %s on the next map\n", COM_QuotedString(v->latched_string, buffer, sizeof(buffer), false));
}
else if (v->flags & CVAR_RENDERERLATCH)
{
Con_Printf ("\"%s\" is %s\n", v->name, COM_QuotedString(v->string, buffer, sizeof(buffer)));
Con_Printf ("Will be changed to %s on vid_restart\n", COM_QuotedString(v->latched_string, buffer, sizeof(buffer)));
Con_Printf ("\"%s\" is %s\n", v->name, COM_QuotedString(v->string, buffer, sizeof(buffer), false));
Con_Printf ("Will be changed to %s on vid_restart\n", COM_QuotedString(v->latched_string, buffer, sizeof(buffer), false));
}
else
{
Con_Printf ("\"%s\" is %s\n", v->name, COM_QuotedString(v->latched_string, buffer, sizeof(buffer)));
Con_Printf ("Effective value is %s\n", COM_QuotedString(v->string, buffer, sizeof(buffer)));
Con_Printf ("\"%s\" is %s\n", v->name, COM_QuotedString(v->latched_string, buffer, sizeof(buffer), false));
Con_Printf ("Effective value is %s\n", COM_QuotedString(v->string, buffer, sizeof(buffer), false));
}
if (v->defaultstr)
Con_Printf("Default: \"%s\"\n", COM_QuotedString(v->defaultstr, buffer, sizeof(buffer)));
Con_Printf("Default: \"%s\"\n", COM_QuotedString(v->defaultstr, buffer, sizeof(buffer), false));
}
else
{
if (v->defaultstr && !strcmp(v->string, v->defaultstr))
Con_Printf ("\"%s\" is %s (default)\n", v->name, COM_QuotedString(v->string, buffer, sizeof(buffer)));
Con_Printf ("\"%s\" is %s (default)\n", v->name, COM_QuotedString(v->string, buffer, sizeof(buffer), false));
else
{
Con_Printf ("\"%s\" is %s\n", v->name, COM_QuotedString(v->string, buffer, sizeof(buffer)));
Con_Printf ("\"%s\" is %s\n", v->name, COM_QuotedString(v->string, buffer, sizeof(buffer), false));
if (v->defaultstr)
Con_Printf("Default: %s\n", COM_QuotedString(v->defaultstr, buffer, sizeof(buffer)));
Con_Printf("Default: %s\n", COM_QuotedString(v->defaultstr, buffer, sizeof(buffer), false));
}
}
return true;
@ -1269,7 +1269,7 @@ qboolean Cvar_Command (int level)
#ifndef SERVERONLY
if (Cmd_ExecLevel > RESTRICT_SERVER)
{ //directed at a secondary player.
CL_SendClientCommand(true, "%i setinfo %s %s", Cmd_ExecLevel - RESTRICT_SERVER-1, v->name, COM_QuotedString(str, buffer, sizeof(buffer)));
CL_SendClientCommand(true, "%i setinfo %s %s", Cmd_ExecLevel - RESTRICT_SERVER-1, v->name, COM_QuotedString(str, buffer, sizeof(buffer), false));
return true;
}
@ -1346,12 +1346,12 @@ void Cvar_WriteVariables (vfsfile_t *f, qboolean all)
if (var->flags & CVAR_USERCREATED)
{
if (var->flags & CVAR_ARCHIVE)
s = va("seta %s %s\n", var->name, COM_QuotedString(val, buffer, sizeof(buffer)));
s = va("seta %s %s\n", var->name, COM_QuotedString(val, buffer, sizeof(buffer), false));
else
s = va("set %s %s\n", var->name, COM_QuotedString(val, buffer, sizeof(buffer)));
s = va("set %s %s\n", var->name, COM_QuotedString(val, buffer, sizeof(buffer), false));
}
else
s = va("%s %s\n", var->name, COM_QuotedString(val, buffer, sizeof(buffer)));
s = va("%s %s\n", var->name, COM_QuotedString(val, buffer, sizeof(buffer), false));
VFS_WRITE(f, s, strlen(s));
}
}

View file

@ -38,7 +38,7 @@ static void fs_game_callback(cvar_t *var, char *oldvalue)
if (runaway)
return; //ignore that
runaway = true;
Cmd_ExecuteString(va("gamedir %s\n", COM_QuotedString(var->string, buf, sizeof(buf))), Cmd_ExecLevel);
Cmd_ExecuteString(va("gamedir %s\n", COM_QuotedString(var->string, buf, sizeof(buf), false)), Cmd_ExecLevel);
runaway = false;
}
@ -258,24 +258,24 @@ void FS_Manifest_Print(ftemanifest_t *man)
char buffer[1024];
int i, j;
if (man->updateurl)
Con_Printf("updateurl %s\n", COM_QuotedString(man->updateurl, buffer, sizeof(buffer)));
Con_Printf("updateurl %s\n", COM_QuotedString(man->updateurl, buffer, sizeof(buffer), false));
if (man->installation)
Con_Printf("game %s\n", COM_QuotedString(man->installation, buffer, sizeof(buffer)));
Con_Printf("game %s\n", COM_QuotedString(man->installation, buffer, sizeof(buffer), false));
if (man->formalname)
Con_Printf("name %s\n", COM_QuotedString(man->formalname, buffer, sizeof(buffer)));
Con_Printf("name %s\n", COM_QuotedString(man->formalname, buffer, sizeof(buffer), false));
if (man->protocolname)
Con_Printf("protocolname %s\n", COM_QuotedString(man->protocolname, buffer, sizeof(buffer)));
Con_Printf("protocolname %s\n", COM_QuotedString(man->protocolname, buffer, sizeof(buffer), false));
if (man->defaultexec)
Con_Printf("defaultexec %s\n", COM_QuotedString(man->defaultexec, buffer, sizeof(buffer)));
Con_Printf("defaultexec %s\n", COM_QuotedString(man->defaultexec, buffer, sizeof(buffer), false));
for (i = 0; i < sizeof(man->gamepath) / sizeof(man->gamepath[0]); i++)
{
if (man->gamepath[i].path)
{
if (man->gamepath[i].base)
Con_Printf("basegame %s\n", COM_QuotedString(man->gamepath[i].path, buffer, sizeof(buffer)));
Con_Printf("basegame %s\n", COM_QuotedString(man->gamepath[i].path, buffer, sizeof(buffer), false));
else
Con_Printf("gamedir %s\n", COM_QuotedString(man->gamepath[i].path, buffer, sizeof(buffer)));
Con_Printf("gamedir %s\n", COM_QuotedString(man->gamepath[i].path, buffer, sizeof(buffer), false));
}
}
@ -286,14 +286,14 @@ void FS_Manifest_Print(ftemanifest_t *man)
if (man->package[i].extractname)
Con_Printf("achived");
if (man->package[i].crcknown)
Con_Printf("package %s 0x%x", COM_QuotedString(man->package[i].path, buffer, sizeof(buffer)), man->package[i].crc);
Con_Printf("package %s 0x%x", COM_QuotedString(man->package[i].path, buffer, sizeof(buffer), false), man->package[i].crc);
else
Con_Printf("package %s -", COM_QuotedString(man->package[i].path, buffer, sizeof(buffer)));
Con_Printf("package %s -", COM_QuotedString(man->package[i].path, buffer, sizeof(buffer), false));
if (man->package[i].extractname)
Con_Printf(" %s", COM_QuotedString(man->package[i].extractname, buffer, sizeof(buffer)));
Con_Printf(" %s", COM_QuotedString(man->package[i].extractname, buffer, sizeof(buffer), false));
for (j = 0; j < sizeof(man->package[i].mirrors) / sizeof(man->package[i].mirrors[0]); j++)
if (man->package[i].mirrors[j])
Con_Printf(" %s", COM_QuotedString(man->package[i].mirrors[j], buffer, sizeof(buffer)));
Con_Printf(" %s", COM_QuotedString(man->package[i].mirrors[j], buffer, sizeof(buffer), false));
Con_Printf("\n");
}
}

View file

@ -89,8 +89,8 @@ char *PF_VarString (pubprogfuncs_t *prinst, int first, struct globalvars_s *pr_g
return out;
}
extern int debuggerresume;
extern int debuggerresumeline;
static int debuggerresume;
static int debuggerresumeline;
extern int isPlugin; //if 2, we were invoked by a debugger, and we need to give it debug locations (and it'll feed us continue/steps/breakpoints)
static int debuggerstacky;
@ -119,6 +119,111 @@ void QCLoadBreakpoints(const char *vmname, const char *progsname)
#endif
}
extern cvar_t pr_sourcedir;
pubprogfuncs_t *debuggerinstance;
qboolean QCExternalDebuggerCommand(char *text)
{
if ((!strncmp(text, "qcstep", 6) && (text[6] == 0 || text[6] == ' ')) || (!strncmp(text, "qcresume", 8) && (text[8] == 0 || text[8] == ' ')))
{
int l;
if (text[2] == 's')
{
debuggerresume = true;
l = atoi(text+7);
}
else
{
l = atoi(text+9);
debuggerresume = 2;
}
if (l)
debuggerresumeline = l;
}
else if (!strncmp(text, "qcinspect ", 10))
{
//called on mouse-over events in the gui
extern world_t csqc_world, menu_world;
char *variable;
char *function;
char resultbuffer[8192], tmpbuffer[8192];
char *vmnames[4] = {"cur: ", "ssqc: ", "csqc: ", "menu: "};
char *values[4] = {NULL, NULL, NULL, NULL};
int i;
Cmd_TokenizeString(text, false, false);
variable = Cmd_Argv(1);
function = Cmd_Argv(2);
//togglebreakpoint just finds the first statement (via the function table for file names) with the specified line number, and sets some unused high bit that causes it to be an invalid opcode.
if (debuggerinstance)
{
if (debuggerinstance->EvaluateDebugString)
values[0] = debuggerinstance->EvaluateDebugString(debuggerinstance, variable);
}
else
{
#ifndef CLIENTONLY
if (sv.world.progs && sv.world.progs->EvaluateDebugString)
values[1] = sv.world.progs->EvaluateDebugString(sv.world.progs, variable);
#endif
#ifdef CSQC_DAT
if (csqc_world.progs && csqc_world.progs->EvaluateDebugString)
values[2] = csqc_world.progs->EvaluateDebugString(csqc_world.progs, variable);
#endif
#ifdef MENU_DAT
if (menu_world.progs && menu_world.progs->EvaluateDebugString)
values[3] = menu_world.progs->EvaluateDebugString(menu_world.progs, variable);
#endif
}
for (i = 0, *resultbuffer = 0; i < 4; i++)
{
if (!values[i])
continue;
if (!strcmp(values[i], "(unable to evaluate)"))
continue;
if (*resultbuffer || !debuggerinstance)
Q_strncatz(resultbuffer, "\n", sizeof(resultbuffer));
if (!debuggerinstance)
{
Q_strncatz(resultbuffer, vmnames[i], sizeof(resultbuffer));
}
Q_strncatz(resultbuffer, COM_QuotedString(values[i], tmpbuffer, sizeof(tmpbuffer), true), sizeof(resultbuffer));
}
Con_Printf("lookup %s\n", variable);
printf("qcvalue \"%s\" %s\n", variable, COM_QuotedString(resultbuffer, tmpbuffer, sizeof(tmpbuffer), false));
fflush(stdout);
}
else if (!strncmp(text, "qcbreakpoint ", 13))
{
extern world_t csqc_world, menu_world;
int mode;
char *filename;
int line;
Cmd_TokenizeString(text, false, false);
mode = strtoul(Cmd_Argv(1), NULL, 0);
filename = Cmd_Argv(2);
line = strtoul(Cmd_Argv(3), NULL, 0);
//togglebreakpoint just finds the first statement (via the function table for file names) with the specified line number, and sets some unused high bit that causes it to be an invalid opcode.
#ifdef CSQC_DAT
if (csqc_world.progs && csqc_world.progs->ToggleBreak)
csqc_world.progs->ToggleBreak(csqc_world.progs, filename, line, mode);
#endif
#ifdef MENU_DAT
if (menu_world.progs && menu_world.progs->ToggleBreak)
menu_world.progs->ToggleBreak(menu_world.progs, filename, line, mode);
#endif
#ifndef CLIENTONLY
if (sv.world.progs && sv.world.progs->ToggleBreak)
sv.world.progs->ToggleBreak(sv.world.progs, filename, line, mode);
#endif
}
else
return false;
return true;
}
int QDECL QCEditor (pubprogfuncs_t *prinst, char *filename, int line, int statement, int nump, char **parms)
{
#if defined(_WIN32) && !defined(SERVERONLY) && !defined(FTE_SDL)
@ -132,6 +237,7 @@ int QDECL QCEditor (pubprogfuncs_t *prinst, char *filename, int line, int statem
printf("qcstep \"%s\":%i\n", filename, line);
fflush(stdout);
INS_UpdateGrabs(false, false);
debuggerinstance = prinst;
while(!debuggerresume)
{
Sleep(10);
@ -147,6 +253,7 @@ int QDECL QCEditor (pubprogfuncs_t *prinst, char *filename, int line, int statem
debuggerstacky = 0;
VID_SwapBuffers();
}
debuggerinstance = NULL;
if (debuggerresume == 2)
prinst->pr_trace = false;
return debuggerresumeline;
@ -3697,8 +3804,8 @@ void QCBUILTIN PF_uri_get (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
float id = G_FLOAT(OFS_PARM1);
const char *mimetype = (prinst->callargc >= 3)?PR_GetStringOfs(prinst, OFS_PARM2):"";
const char *dataorsep = PR_GetStringOfs(prinst, OFS_PARM3);
int strbufid = G_FLOAT(OFS_PARM4);
//float cryptokey = G_FLOAT(OFS_PARM5); //DP feature, not supported in FTE.
int strbufid = (prinst->callargc >= 5)?G_FLOAT(OFS_PARM4):0;
//float cryptokey = (prinst->callargc >= 5)?G_FLOAT(OFS_PARM5):0; //DP feature, not supported in FTE.
if (!pr_enable_uriget.ival)
{
@ -3716,6 +3823,7 @@ void QCBUILTIN PF_uri_get (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
//convert the string buffer into a simple string using dataorsep as a separator
//not supported at this time
dl = NULL;
Con_DPrintf("PF_uri_post: stringbuffers not supported\n");
}
else
{
@ -3929,7 +4037,7 @@ void QCBUILTIN PF_argescape(pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
{
char temp[8192];
const char *str = PR_GetStringOfs(prinst, OFS_PARM0);
RETURN_TSTRING(COM_QuotedString(str, temp, sizeof(temp)));
RETURN_TSTRING(COM_QuotedString(str, temp, sizeof(temp), false));
}
//Console functions

View file

@ -570,9 +570,9 @@ char *PR_ValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val, pbool v
case ev_field:
fielddef = ED_FieldAtOfs (progfuncs, val->_int + progfuncs->funcs.fieldadjust);
if (!fielddef)
QC_snprintfz (line, sizeof(line), ".??? (%i)", val->_int);
QC_snprintfz (line, sizeof(line), ".??? (#%i)", val->_int);
else
QC_snprintfz (line, sizeof(line), ".%s (%i)", fielddef->name, val->_int);
QC_snprintfz (line, sizeof(line), ".%s (#%i)", fielddef->name, val->_int);
break;
case ev_void:
QC_snprintfz (line, sizeof(line), "void type");
@ -1819,6 +1819,7 @@ int PDECL PR_LoadEnts(pubprogfuncs_t *ppf, const char *file, float killonspawnfl
eval_t *selfvar = NULL;
eval_t *var;
const char *spawnwarned[20] = {NULL};
char filename[128];
int num;
@ -2294,7 +2295,21 @@ int PDECL PR_LoadEnts(pubprogfuncs_t *ppf, const char *file, float killonspawnfl
}
else
{
printf("Couldn't find spawn function %s\n", PR_StringToNative(&progfuncs->funcs, var->string));
//only warn on the first occurence of the classname, don't spam.
int i;
const char *fnc = PR_StringToNative(&progfuncs->funcs, var->string);
if (pr_typecurrent >= 0)
for (i = 0; i < sizeof(spawnwarned)/sizeof(spawnwarned[0]); i++)
{
if (!spawnwarned[i])
{
printf("Couldn't find spawn function %s\n", fnc);
spawnwarned[i] = fnc;
break;
}
else if (!strcmp(spawnwarned[i], fnc))
break;
}
ED_Free(&progfuncs->funcs, (struct edict_s *)ed);
}
}

View file

@ -177,28 +177,7 @@ typedef struct
HANDLE pipefromengine;
HANDLE pipetoengine;
} enginewindow_t;
void EngineCommand(enginewindow_t *ctx, char *message, ...)
{
//qcresume - resume running
//qcinto - singlestep. execute-with-debugging child functions
//qcover - singlestep. execute-without-debugging child functions
//qcout - singlestep. leave current function and enter parent.
//qcbreak "$loc" - set breakpoint
//qcwatch "$var" - set watchpoint
//qcstack - force-report stack trace
va_list va;
char finalmessage[1024];
va_start (va, message);
vsnprintf (finalmessage, sizeof(finalmessage)-1, message, va);
va_end (va);
if (ctx->pipetoengine)
{
DWORD written = 0;
WriteFile(ctx->pipetoengine, finalmessage, strlen(finalmessage), &written, NULL);
}
}
static pbool EngineCommandf(char *message, ...);
static pbool QCC_RegGetStringValue(HKEY base, char *keyname, char *valuename, void *data, int datalen)
{
@ -562,12 +541,7 @@ LRESULT CALLBACK MySubclassWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
}
if (wParam == VK_F5)
{
if (gamewindow)
{
enginewindow_t *e = (enginewindow_t*)(LONG_PTR)GetWindowLongPtr(gamewindow, GWLP_USERDATA);
EngineCommand(e, "qcresume\n");
}
else
if (!EngineCommandf("qcresume\n"))
RunEngine();
return 0;
}
@ -588,20 +562,12 @@ LRESULT CALLBACK MySubclassWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
else
mode = 2;
if (gamewindow)
{
enginewindow_t *e = (enginewindow_t*)(LONG_PTR)GetWindowLongPtr(gamewindow, GWLP_USERDATA);
EngineCommand(e, "qcbreakpoint %i \"%s\" %i\n", mode, editor->filename, editor->curline+1);
}
EngineCommandf("qcbreakpoint %i \"%s\" %i\n", mode, editor->filename, editor->curline+1);
return 0;
}
if (wParam == VK_F11)
{
if (gamewindow)
{
enginewindow_t *e = (enginewindow_t*)(LONG_PTR)GetWindowLongPtr(gamewindow, GWLP_USERDATA);
EngineCommand(e, "qcstep\n");
}
EngineCommandf("qcstep\n");
return 0;
}
}
@ -945,7 +911,7 @@ void EditorMenu(editor_t *editor, WPARAM wParam)
}
}
char *WordUnderCursor(editor_t *editor, char *buffer, int buffersize, int position)
char *WordUnderCursor(editor_t *editor, char *word, int wordsize, char *term, int termsize, int position)
{
unsigned char linebuf[1024];
DWORD charidx;
@ -979,35 +945,68 @@ char *WordUnderCursor(editor_t *editor, char *buffer, int buffersize, int positi
Edit_GetLine(editor->editpane, lineidx, linebuf, sizeof(linebuf));
}
if (word)
{
//skip back to the start of the word
while(charidx > 0 && (
(linebuf[charidx-1] >= 'a' && linebuf[charidx-1] <= 'z') ||
(linebuf[charidx-1] >= 'A' && linebuf[charidx-1] <= 'Z') ||
(linebuf[charidx-1] >= '0' && linebuf[charidx-1] <= '9') ||
linebuf[charidx-1] == '_' ||
linebuf[charidx-1] == '_' || linebuf[charidx-1] == ':' ||
linebuf[charidx-1] >= 128
))
{
charidx--;
}
//copy the result out
lineidx = 0;
buffersize--;
while (buffersize &&
wordsize--;
while (wordsize &&
(linebuf[charidx] >= 'a' && linebuf[charidx] <= 'z') ||
(linebuf[charidx] >= 'A' && linebuf[charidx] <= 'Z') ||
(linebuf[charidx] >= '0' && linebuf[charidx] <= '9') ||
linebuf[charidx] == '_' ||
linebuf[charidx] == '_' || linebuf[charidx] == ':' ||
linebuf[charidx] >= 128
)
{
buffer[lineidx++] = linebuf[charidx++];
buffersize--;
word[lineidx++] = linebuf[charidx++];
wordsize--;
}
word[lineidx++] = 0;
}
buffer[lineidx++] = 0;
return buffer;
if (term)
{
//skip back to the start of the word
while(charidx > 0 && (
(linebuf[charidx-1] >= 'a' && linebuf[charidx-1] <= 'z') ||
(linebuf[charidx-1] >= 'A' && linebuf[charidx-1] <= 'Z') ||
(linebuf[charidx-1] >= '0' && linebuf[charidx-1] <= '9') ||
linebuf[charidx-1] == '_' || linebuf[charidx-1] == ':' || || linebuf[charidx-1] == '.' ||
linebuf[charidx-1] == '[' || linebuf[charidx-1] == ']' ||
linebuf[charidx-1] >= 128
))
{
charidx--;
}
//copy the result out
lineidx = 0;
termsize--;
while (termsize &&
(linebuf[charidx] >= 'a' && linebuf[charidx] <= 'z') ||
(linebuf[charidx] >= 'A' && linebuf[charidx] <= 'Z') ||
(linebuf[charidx] >= '0' && linebuf[charidx] <= '9') ||
linebuf[charidx] == '_' || linebuf[charidx] == ':' || linebuf[charidx] == '.' ||
linebuf[charidx] == '[' || linebuf[charidx] == ']' ||
linebuf[charidx] >= 128
)
{
term[lineidx++] = linebuf[charidx++];
termsize--;
}
term[lineidx++] = 0;
}
return word;
}
pbool GenAutoCompleteList(char *prefix, char *buffer, int buffersize)
@ -1039,21 +1038,32 @@ pbool GenAutoCompleteList(char *prefix, char *buffer, int buffersize)
buffer[usedbuffer] = 0;
return usedbuffer>0;
}
char *GetTooltipText(editor_t *editor, int pos)
editor_t *tooltip_editor = NULL;
char tooltip_variable[256];
char tooltip_type[256];
char tooltip_comment[2048];
size_t tooltip_position;
char *GetTooltipText(editor_t *editor, int pos, pbool dwell)
{
static char buffer[1024];
char wordbuf[256];
char wordbuf[256], *text;
char term[256];
char *defname;
defname = WordUnderCursor(editor, wordbuf, sizeof(wordbuf), pos);
defname = WordUnderCursor(editor, wordbuf, sizeof(wordbuf), term, sizeof(term), pos);
if (!*defname)
return NULL;
else if (globalstable.numbuckets)
{
char *funcname;
QCC_def_t *def;
char *macro = QCC_PR_CheckCompConstTooltip(defname, buffer, buffer + sizeof(buffer));
if (macro && *macro)
return macro;
funcname = ""; //FIXME
def = QCC_PR_GetDef(NULL, defname, NULL, false, 0, GDF_SILENT);
if (def)
{
@ -1063,9 +1073,31 @@ char *GetTooltipText(editor_t *editor, int pos)
_snprintf(buffer, sizeof(buffer)-1, "%s %s\r\n%s", TypeName(def->type, typebuf, sizeof(typebuf)), def->name, def->comment);
else
_snprintf(buffer, sizeof(buffer)-1, "%s %s", TypeName(def->type, typebuf, sizeof(typebuf)), def->name);
return buffer;
if (dwell)
{
strncpy(tooltip_type, TypeName(def->type, typebuf, sizeof(typebuf)), sizeof(tooltip_type)-1);
if (def->comment)
strncpy(tooltip_comment, def->comment, sizeof(tooltip_comment)-1);
}
return NULL;
text = buffer;
}
if (dwell)
{
tooltip_editor = editor;
strncpy(tooltip_variable, term, sizeof(tooltip_variable)-1);
tooltip_position = pos;
*tooltip_type = 0;
*tooltip_comment = 0;
EngineCommandf("qcinspect \"%s\" \"%s\"\n", term, funcname);
SendMessage(editor->editpane, SCI_CALLTIPSHOW, (WPARAM)pos, (LPARAM)text);
}
return text;
}
else
return NULL;//"Type info not available. Compile first.";
@ -1172,7 +1204,7 @@ static LRESULT CALLBACK EditorWndProc(HWND hWnd,UINT message,
toolInfo.hwnd = hWnd;
toolInfo.uFlags = TTF_IDISHWND | TTF_SUBCLASS | TTF_TRACK | TTF_ABSOLUTE;
toolInfo.uId = (UINT_PTR)editor->editpane;
newtext = GetTooltipText(editor, -1);
newtext = GetTooltipText(editor, -1, FALSE);
toolInfo.lpszText = editor->tooltiptext;
if (!newtext)
newtext = "";
@ -1229,7 +1261,6 @@ static LRESULT CALLBACK EditorWndProc(HWND hWnd,UINT message,
{
NMHDR *nmhdr;
char title[2048];
char *s;
nmhdr = (NMHDR *)lParam;
if (editor->scintilla)
{
@ -1246,16 +1277,13 @@ static LRESULT CALLBACK EditorWndProc(HWND hWnd,UINT message,
l = SendMessage(editor->editpane, SCI_LINEFROMPOSITION, not->position, 0);
mode = !(SendMessage(editor->editpane, SCI_MARKERGET, l, 0) & 1);
SendMessage(editor->editpane, mode?SCI_MARKERADD:SCI_MARKERDELETE, l, 0);
if (gamewindow)
{
enginewindow_t *e = (enginewindow_t*)(LONG_PTR)GetWindowLongPtr(gamewindow, GWLP_USERDATA);
EngineCommand(e, "qcbreakpoint %i \"%s\" %i\n", mode, editor->filename, l+1);
}
EngineCommandf("qcbreakpoint %i \"%s\" %i\n", mode, editor->filename, l+1);
break;
case SCN_CHARADDED:
if (not->ch == '(')
{
char *s = GetTooltipText(editor, pos-1);
char *s = GetTooltipText(editor, pos-1, FALSE);
tooltip_editor = NULL;
if (s)
SendMessage(editor->editpane, SCI_CALLTIPSHOW, (WPARAM)pos, (LPARAM)s);
}
@ -1263,7 +1291,7 @@ static LRESULT CALLBACK EditorWndProc(HWND hWnd,UINT message,
{
char buffer[65536];
char prefixbuffer[128];
char *pre = WordUnderCursor(editor, prefixbuffer, sizeof(prefixbuffer), SendMessage(editor->editpane, SCI_GETCURRENTPOS, 0, 0));
char *pre = WordUnderCursor(editor, prefixbuffer, sizeof(prefixbuffer), NULL, 0, SendMessage(editor->editpane, SCI_GETCURRENTPOS, 0, 0));
if (pre && *pre)
if (GenAutoCompleteList(pre, buffer, sizeof(buffer)))
SendMessage(editor->editpane, SCI_AUTOCSHOW, strlen(pre), (LPARAM)buffer);
@ -1299,12 +1327,11 @@ static LRESULT CALLBACK EditorWndProc(HWND hWnd,UINT message,
}
break;
case SCN_DWELLSTART:
s = GetTooltipText(editor, not->position);
if (s)
SendMessage(editor->editpane, SCI_CALLTIPSHOW, (WPARAM)not->position, (LPARAM)s);
GetTooltipText(editor, not->position, TRUE);
break;
case SCN_DWELLEND:
case SCN_FOCUSOUT:
tooltip_editor = NULL;
SendMessage(editor->editpane, SCI_CALLTIPCANCEL, 0, 0);
break;
}
@ -2038,7 +2065,68 @@ skipwhite:
goto skipwhite;
}
// handle quoted strings specially
// handle marked up quoted strings specially (c-style, but with leading \ before normal opening ")
if (c == '\\' && data[1] == '\"')
{
data+=2;
while (1)
{
if (len >= outlen-2)
{
out[len] = '\0';
return (char*)data;
}
c = *data++;
if (!c)
{
out[len] = 0;
return (char*)data-1;
}
if (c == '\\')
{
c = *data++;
switch(c)
{
case '\r':
if (*data == '\n')
data++;
case '\n':
continue;
case 'n':
c = '\n';
break;
case 't':
c = '\t';
break;
case 'r':
c = '\r';
break;
case '$':
case '\\':
case '\'':
break;
case '"':
c = '"';
out[len] = c;
len++;
continue;
default:
c = '?';
break;
}
}
if (c=='\"' || !c)
{
out[len] = 0;
return (char*)data;
}
out[len] = c;
len++;
}
}
// handle legacy quoted strings specially
if (c == '\"')
{
data++;
@ -2080,6 +2168,50 @@ skipwhite:
return (char*)data;
}
static pbool EngineCommandWnd(HWND wnd, char *message)
{
//qcresume - resume running
//qcinto - singlestep. execute-with-debugging child functions
//qcover - singlestep. execute-without-debugging child functions
//qcout - singlestep. leave current function and enter parent.
//qcbreak "$loc" - set breakpoint
//qcwatch "$var" - set watchpoint
//qcstack - force-report stack trace
enginewindow_t *ctx;
if (wnd)
{
ctx = (enginewindow_t*)(LONG_PTR)GetWindowLongPtr(gamewindow, GWLP_USERDATA);
if (ctx)
{
if (ctx->pipetoengine)
{
DWORD written = 0;
WriteFile(ctx->pipetoengine, message, strlen(message), &written, NULL);
return TRUE;
}
}
}
return FALSE;
}
static pbool EngineCommandf(char *message, ...)
{
va_list va;
char finalmessage[1024];
va_start (va, message);
vsnprintf (finalmessage, sizeof(finalmessage)-1, message, va);
va_end (va);
return EngineCommandWnd(gamewindow, finalmessage);
}
static pbool EngineCommandWndf(HWND wnd, char *message, ...)
{
va_list va;
char finalmessage[1024];
va_start (va, message);
vsnprintf (finalmessage, sizeof(finalmessage)-1, message, va);
va_end (va);
return EngineCommandWnd(wnd, finalmessage);
}
unsigned int WINAPI threadwrapper(void *args)
{
static char filenamebuffer[256];
@ -2169,9 +2301,11 @@ unsigned int WINAPI threadwrapper(void *args)
l++;
PostMessage(ctx->window, WM_USER, atoi(l), (LPARAM)filenamebuffer); //and tell the owning window to try to close it again
}
else if (!strncmp(buffer, "qcvalue ", 6))
else if (!strncmp(buffer, "qcvalue ", 8))
{
//qcvalue "$variableformula" "$value"
//update tooltip to show engine's current value
PostMessage(ctx->window, WM_USER+2, 0, (LPARAM)strdup(buffer+8)); //and tell the owning window to try to close it again
}
else if (!strncmp(buffer, "qcreloaded ", 10))
{
@ -2191,8 +2325,11 @@ unsigned int WINAPI threadwrapper(void *args)
else
break;
}
}
CloseHandle(ctx->pipefromengine);
ctx->pipefromengine = NULL;
CloseHandle(ctx->pipetoengine);
ctx->pipetoengine = NULL;
}
ctx->pipeclosed = true;
@ -2203,41 +2340,44 @@ unsigned int WINAPI threadwrapper(void *args)
static LRESULT CALLBACK EngineWndProc(HWND hWnd,UINT message,
WPARAM wParam,LPARAM lParam)
{
enginewindow_t *e;
enginewindow_t *ctx;
editor_t *editor;
switch (message)
{
case WM_CREATE:
e = malloc(sizeof(*e));
memset(e, 0, sizeof(*e));
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)e);
e->window = hWnd;
e->thread = (HANDLE)CreateThread(NULL, 0, threadwrapper, e, 0, &e->tid);
ctx = malloc(sizeof(*ctx));
memset(ctx, 0, sizeof(*ctx));
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)ctx);
ctx->window = hWnd;
ctx->thread = (HANDLE)CreateThread(NULL, 0, threadwrapper, ctx, 0, &ctx->tid);
break;
case WM_SIZE:
ctx = (enginewindow_t*)(LONG_PTR)GetWindowLongPtr(gamewindow, GWLP_USERDATA);
if (ctx)
{
RECT r;
e = (enginewindow_t*)(LONG_PTR)GetWindowLongPtr(hWnd, GWLP_USERDATA);
GetClientRect(hWnd, &r);
EngineCommand(e, "vid_recenter %i %i %i %i %#p\n", r.left, r.top, r.right-r.left, r.bottom - r.top, (void*)e->window);
EngineCommandWndf(hWnd, "vid_recenter %i %i %i %i %#p\n", r.left, r.top, r.right-r.left, r.bottom - r.top, (void*)ctx->window);
}
goto gdefault;
case WM_CLOSE:
e = (enginewindow_t*)(LONG_PTR)GetWindowLongPtr(hWnd, GWLP_USERDATA);
if (e->pipeclosed)
{
DestroyWindow(hWnd);
return 0;
}
//ask the engine to quit
EngineCommand(e, "quit force\n");
ctx = (enginewindow_t*)(LONG_PTR)GetWindowLongPtr(gamewindow, GWLP_USERDATA);
if (ctx && !ctx->pipeclosed)
{
EngineCommandWnd(hWnd, "quit force\n");
break;
}
goto gdefault;
case WM_DESTROY:
e = (enginewindow_t*)(LONG_PTR)GetWindowLongPtr(hWnd, GWLP_USERDATA);
EngineCommand(e, "quit force\n"); //just in case
WaitForSingleObject(e->thread, INFINITE);
CloseHandle(e->thread);
free(e);
EngineCommandWnd(hWnd, "quit force\n"); //just in case
ctx = (enginewindow_t*)(LONG_PTR)GetWindowLongPtr(gamewindow, GWLP_USERDATA);
if (ctx)
{
WaitForSingleObject(ctx->thread, INFINITE);
CloseHandle(ctx->thread);
free(ctx);
}
if (hWnd == gamewindow)
gamewindow = NULL;
break;
@ -2247,7 +2387,6 @@ static LRESULT CALLBACK EngineWndProc(HWND hWnd,UINT message,
break;
case WM_USER+1:
//engine loaded a progs, reset breakpoints.
e = (enginewindow_t*)(LONG_PTR)GetWindowLongPtr(gamewindow, GWLP_USERDATA);
for (editor = editors; editor; editor = editor->next)
{
int line = -1;
@ -2261,11 +2400,31 @@ static LRESULT CALLBACK EngineWndProc(HWND hWnd,UINT message,
break; //no more.
line++;
EngineCommand(e, "qcbreakpoint 1 \"%s\" %i\n", editor->filename, line);
EngineCommandWndf(hWnd, "qcbreakpoint 1 \"%s\" %i\n", editor->filename, line);
}
}
//and now let the engine continue
EngineCommand(e, "qcresume\n");
EngineCommandWnd(hWnd, "qcresume\n");
break;
case WM_USER+2:
{
char varname[1024];
char varvalue[1024];
char *line = (char*)lParam;
line = COM_ParseOut(line, varname, sizeof(varname));
line = COM_ParseOut(line, varvalue, sizeof(varvalue));
if (tooltip_editor && !strcmp(varname, tooltip_variable))
{
char tip[2048];
if (*tooltip_comment)
_snprintf(tip, sizeof(tip)-1, "%s %s = %s\r\n%s", tooltip_type, tooltip_variable, varvalue, tooltip_comment);
else
_snprintf(tip, sizeof(tip)-1, "%s %s = %s", tooltip_type, tooltip_variable, varvalue);
SendMessage(tooltip_editor->editpane, SCI_CALLTIPSHOW, (WPARAM)tooltip_position, (LPARAM)tip);
}
free(lParam);
}
break;
default:
@ -3315,11 +3474,7 @@ void RunCompiler(char *args)
if (CompileParams(&funcs, true, argc, argv))
{
if (gamewindow)
{
enginewindow_t *e = (enginewindow_t*)(LONG_PTR)GetWindowLongPtr(gamewindow, GWLP_USERDATA);
EngineCommand(e, "qcresume\nmenu_restart\nrestart\n");
}
EngineCommandf("qcresume\nmenu_restart\nrestart\n");
}
if (logfile)

View file

@ -582,7 +582,7 @@ void Q_SetProgsParms(qboolean forcompiler)
svprogparms.globalbuiltins = pr_builtin;//builtin_t *globalbuiltins; //these are available to all progs
svprogparms.numglobalbuiltins = pr_numbuiltins;
svprogparms.autocompile = PR_COMPILECHANGED;//enum {PR_NOCOMPILE, PR_COMPILENEXIST, PR_COMPILECHANGED, PR_COMPILEALWAYS} autocompile;
svprogparms.autocompile = PR_COMPILEIGNORE;//PR_COMPILECHANGED;//enum {PR_NOCOMPILE, PR_COMPILENEXIST, PR_COMPILECHANGED, PR_COMPILEALWAYS} autocompile;
svprogparms.gametime = &sv.time;
@ -662,7 +662,7 @@ void PR_Shutdown(void)
#endif
}
void PR_LoadGlabalStruct(void)
void PR_LoadGlabalStruct(qboolean muted)
{
static float svphysicsmode = 2;
static float writeonly;
@ -676,11 +676,11 @@ void PR_LoadGlabalStruct(void)
int i;
int *v;
globalptrs_t *pr_globals = 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; Con_Printf("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; Con_Printf("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; Con_Printf("Could not find \""#name"\" export in progs\n");}
#define globalvec(need,name) (pr_globals)->name = (vec3_t *)PR_FindGlobal(svprogfuncs, #name, 0, NULL); if (need && !(pr_globals)->name) {static vec3_t fallback##name; (pr_globals)->name = &fallback##name; Con_Printf("Could not find \""#name"\" export in progs\n");}
#define globalfunc(need,name) (pr_globals)->name = (func_t *)PR_FindGlobal(svprogfuncs, #name, 0, NULL); if (!(pr_globals)->name) {static func_t stripped##name; stripped##name = PR_FindFunction(svprogfuncs, #name, 0); if (stripped##name) (pr_globals)->name = &stripped##name; else if (need) Con_Printf("Could not find function \""#name"\" in progs\n"); }
#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_Printf("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_Printf("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_Printf("Could not find \""#name"\" export in progs\n");}
#define globalvec(need,name) (pr_globals)->name = (vec3_t *)PR_FindGlobal(svprogfuncs, #name, 0, NULL); if (need && !(pr_globals)->name) {static vec3_t fallback##name; (pr_globals)->name = &fallback##name; if (!muted) Con_Printf("Could not find \""#name"\" export in progs\n");}
#define globalfunc(need,name) (pr_globals)->name = (func_t *)PR_FindGlobal(svprogfuncs, #name, 0, NULL); if (!(pr_globals)->name) {static func_t stripped##name; stripped##name = PR_FindFunction(svprogfuncs, #name, 0); if (stripped##name) (pr_globals)->name = &stripped##name; else if (need && !muted) Con_Printf("Could not find function \""#name"\" in progs\n"); }
// globalint(pad);
globalint (true, self); //we need the qw ones, but any in standard quake and not quakeworld, we don't really care about.
globalint (true, other);
@ -765,6 +765,7 @@ void PR_LoadGlabalStruct(void)
{
static vec3_t fallback_trace_plane_normal;
(pr_globals)->trace_plane_normal = &fallback_trace_plane_normal;
if (!muted)
Con_Printf("Could not find export trace_plane_normal in progs\n");
}
}
@ -775,6 +776,7 @@ void PR_LoadGlabalStruct(void)
{
static vec3_t fallback_trace_endpos;
(pr_globals)->trace_endpos = &fallback_trace_endpos;
if (!muted)
Con_Printf("Could not find export trace_endpos in progs\n");
}
}
@ -785,6 +787,7 @@ void PR_LoadGlabalStruct(void)
{
static float fallback_trace_fraction;
(pr_globals)->trace_fraction = &fallback_trace_fraction;
if (!muted)
Con_Printf("Could not find export trace_fraction in progs\n");
}
}
@ -934,7 +937,7 @@ progsnum_t AddProgs(const char *name)
if (svs.numprogs >= MAX_PROGS)
return -1;
svprogparms.autocompile = PR_COMPILECHANGED;
// svprogparms.autocompile = PR_COMPILECHANGED;
num = PR_LoadProgs (svprogfuncs, name, NULL, 0);
sv.world.usesolidcorpse = (progstype != PROG_H2);
@ -959,7 +962,7 @@ progsnum_t AddProgs(const char *name)
break;
}
}
svprogparms.autocompile = PR_COMPILECHANGED;
// svprogparms.autocompile = PR_COMPILECHANGED;
if (num == -1)
{
Con_Printf("Failed to load %s\n", name);
@ -967,7 +970,7 @@ progsnum_t AddProgs(const char *name)
}
if (num == 0)
PR_LoadGlabalStruct();
PR_LoadGlabalStruct(false);
Con_TPrintf("Loaded progs %s\n", name);
@ -1098,7 +1101,7 @@ void PR_ApplyCompilation_f (void)
sv.world.edict_size=svprogfuncs->load_ents(svprogfuncs, s, 0);
PR_LoadGlabalStruct();
PR_LoadGlabalStruct(false);
pr_global_struct->time = sv.world.physicstime;
@ -1418,15 +1421,19 @@ void Q_InitProgs(void)
}
if (oldprnum < 0)
{
PR_LoadGlabalStruct();
PR_LoadGlabalStruct(true);
// SV_Error("Couldn't open or compile progs\n");
Con_Printf(CON_ERROR"Running without gamecode\n");
}
#ifdef SQL
SQL_KillServers(); // TODO: is this the best placement for this?
#endif
if (oldprnum >= 0)
f = PR_FindFunction (svprogfuncs, "AddAddonProgs", oldprnum);
else
f = 0;
/* if (num)
{
//restore progs
@ -5083,28 +5090,28 @@ void QCBUILTIN PF_changelevel (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
#ifdef HEXEN2
if (progstype == PROG_H2)
{
COM_QuotedString(PR_GetStringOfs(prinst, OFS_PARM1), startspot, sizeof(startspot));
COM_QuotedString(PR_GetStringOfs(prinst, OFS_PARM1), startspot, sizeof(startspot), false);
//these flags disable the whole levelcache thing. the spawnspot is meant to still and always be specified.
//hexen2 ALWAYS specifies two arguments, and it seems that raven left it blank in some single-player maps too.
//if we don't want to be stupid/broken in deathmatch, we might as well do the fully compatible thing
if ((int)pr_global_struct->serverflags & (16|32))
{
COM_QuotedString(va("*%s", PR_GetStringOfs(prinst, OFS_PARM0)), newmap, sizeof(newmap));
COM_QuotedString(va("*%s", PR_GetStringOfs(prinst, OFS_PARM0)), newmap, sizeof(newmap), false);
Cbuf_AddText (va("\nchangelevel %s %s\n", newmap, startspot), RESTRICT_LOCAL);
}
else
{
COM_QuotedString(PR_GetStringOfs(prinst, OFS_PARM0), newmap, sizeof(newmap));
COM_QuotedString(PR_GetStringOfs(prinst, OFS_PARM0), newmap, sizeof(newmap), false);
Cbuf_AddText (va("\nchangelevel %s %s\n", newmap, startspot), RESTRICT_LOCAL);
}
}
else
#endif
{
COM_QuotedString(PR_GetStringOfs(prinst, OFS_PARM0), newmap, sizeof(newmap));
COM_QuotedString(PR_GetStringOfs(prinst, OFS_PARM0), newmap, sizeof(newmap), false);
if (svprogfuncs->callargc == 2)
{
COM_QuotedString(PR_GetStringOfs(prinst, OFS_PARM1), startspot, sizeof(startspot));
COM_QuotedString(PR_GetStringOfs(prinst, OFS_PARM1), startspot, sizeof(startspot), false);
Cbuf_AddText (va("\nchangelevel %s %s\n", newmap, startspot), RESTRICT_LOCAL);
}
else

View file

@ -31,7 +31,7 @@ void SVQ1_CvarChanged(cvar_t *var);
void Q_SetProgsParms(qboolean forcompiler);
void PR_Deinit(void); //server shutting down
void PR_Shutdown(void); //server quitting
void PR_LoadGlabalStruct(void);
void PR_LoadGlabalStruct(qboolean muted);
void Q_InitProgs(void);
void PR_RegisterFields(void);
void PR_Init(void);

View file

@ -286,7 +286,7 @@ void SV_Loadgame_Legacy(char *filename, vfsfile_t *f, int version)
sv.world.edict_size=svprogfuncs->load_ents(svprogfuncs, file, 0);
BZ_Free(file);
PR_LoadGlabalStruct();
PR_LoadGlabalStruct(false);
pr_global_struct->time = sv.world.physicstime = sv.time = time;
sv.starttime = Sys_DoubleTime() - sv.time;
@ -717,7 +717,7 @@ qboolean SV_LoadLevelCache(char *savename, char *level, char *startspot, qboolea
progstype = pt;
PR_LoadGlabalStruct();
PR_LoadGlabalStruct(false);
pr_global_struct->time = sv.time = sv.world.physicstime = time;
sv.starttime = Sys_DoubleTime() - sv.time;

View file

@ -92,6 +92,13 @@ void *SVQ2_GetGameAPI (void *parms)
}
}
#ifdef _WIN64
//if we found 32bit q2 gamecode that cannot be loaded, print out a warning about it.
//this should make it a little obvious when people try using 64bit builds to run q2.
if (COM_FCheckExists("gamex86.dll"))
Con_Printf(CON_ERROR "WARNING: 32bit q2 gamecode found, but it cannot be used in a 64bit process.\nIf you wish to run this q2 mod, you will need to use a 32bit engine build.\n");
#endif
return NULL;
}