mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-22 20:11:44 +00:00
cl_clock 2; now gives a 12-hour clock.
fix configs not getting execed properly when not run from the automatically detected basedir. fix some silly bugs. qcc: remove deprecated %5 support without qccx syntax. qcc: added -Fembedsrc to embed the sourcecode into the progs in a form that can be read with various standard unzip programs. This works without breaking any engines. server: fix memory explosion issue with fitz666 clients. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5016 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
c08a0aa139
commit
57dfaea5fd
25 changed files with 2775 additions and 2529 deletions
|
@ -775,6 +775,7 @@ ifeq (,$(findstring NO_ZLIB,$(CFLAGS)))
|
||||||
SV_LDFLAGS+=-lz
|
SV_LDFLAGS+=-lz
|
||||||
GL_LDFLAGS+=-lz
|
GL_LDFLAGS+=-lz
|
||||||
M_LDFLAGS+=-lz
|
M_LDFLAGS+=-lz
|
||||||
|
QCC_LDFLAGS+=-lz
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -868,10 +869,12 @@ ifeq (win_SDL,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET)))
|
||||||
GL_LDFLAGS=$(GLLDFLAGS) -lmingw32 -lws2_32 `$(SDLCONFIG) --static-libs`
|
GL_LDFLAGS=$(GLLDFLAGS) -lmingw32 -lws2_32 `$(SDLCONFIG) --static-libs`
|
||||||
M_LDFLAGS=$(MLDFLAGS) -lmingw32 -lws2_32 `$(SDLCONFIG) --static-libs`
|
M_LDFLAGS=$(MLDFLAGS) -lmingw32 -lws2_32 `$(SDLCONFIG) --static-libs`
|
||||||
SV_LDFLAGS=$(MINGW_LIBS_DIR)/libz.a -lm -lmingw32 -lws2_32 -lwinmm `$(SDLCONFIG) --static-libs`
|
SV_LDFLAGS=$(MINGW_LIBS_DIR)/libz.a -lm -lmingw32 -lws2_32 -lwinmm `$(SDLCONFIG) --static-libs`
|
||||||
|
QCC_LDFLAGS=$(MINGW_LIBS_DIR)/libz.a
|
||||||
else
|
else
|
||||||
GL_LDFLAGS=$(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) -lws2_32 -lmingw32 $(SDL_LDFLAGS) -mwindows -ldxguid -lwinmm -lole32 $(GLLDFLAGS) `$(SDLCONFIG) --libs`
|
GL_LDFLAGS=$(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) -lws2_32 -lmingw32 $(SDL_LDFLAGS) -mwindows -ldxguid -lwinmm -lole32 $(GLLDFLAGS) `$(SDLCONFIG) --libs`
|
||||||
M_LDFLAGS=$(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) -lws2_32 -lmingw32 -mwindows -ldxguid -lwinmm -lole32 $(MLDFLAGS) `$(SDL_CONFIG) --libs` $(IMAGELDFLAGS)
|
M_LDFLAGS=$(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) -lws2_32 -lmingw32 -mwindows -ldxguid -lwinmm -lole32 $(MLDFLAGS) `$(SDL_CONFIG) --libs` $(IMAGELDFLAGS)
|
||||||
SV_LDFLAGS=$(MINGW_LIBS_DIR)/libz.a -lm -lmingw32 -lws2_32 -lwinmm `$(SDLCONFIG) --libs`
|
SV_LDFLAGS=$(MINGW_LIBS_DIR)/libz.a -lm -lmingw32 -lws2_32 -lwinmm `$(SDLCONFIG) --libs`
|
||||||
|
QCC_LDFLAGS=$(MINGW_LIBS_DIR)/libz.a
|
||||||
endif
|
endif
|
||||||
|
|
||||||
GL_CFLAGS=-DFTE_SDL -I$(MINGW_LIBS_DIR)/ -I$(MINGW_LIBS_DIR) -I$(LIBS_DIR) $(GLCFLAGS) -DLIBVORBISFILE_STATIC $(DX7SDK) $(SPEEXCFLAGS)
|
GL_CFLAGS=-DFTE_SDL -I$(MINGW_LIBS_DIR)/ -I$(MINGW_LIBS_DIR) -I$(LIBS_DIR) $(GLCFLAGS) -DLIBVORBISFILE_STATIC $(DX7SDK) $(SPEEXCFLAGS)
|
||||||
|
@ -1039,6 +1042,7 @@ ifeq (win,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET)))
|
||||||
BITS=64
|
BITS=64
|
||||||
endif
|
endif
|
||||||
QCC_DIR=winqcc$(BITS)
|
QCC_DIR=winqcc$(BITS)
|
||||||
|
QCC_LDFLAGS=$(MINGW_LIBS_DIR)/libz.a
|
||||||
|
|
||||||
BASELDFLAGS=
|
BASELDFLAGS=
|
||||||
|
|
||||||
|
@ -1625,7 +1629,7 @@ m-profile:
|
||||||
|
|
||||||
|
|
||||||
_qcc-tmp: $(REQDIR)
|
_qcc-tmp: $(REQDIR)
|
||||||
@$(MAKE) $(TYPE) EXE_NAME="$(EXE_NAME)$(EXEPOSTFIX)" PRECOMPHEADERS="" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(CLIENT_ONLY_CFLAGS) $(WCFLAGS)" LDFLAGS="$(LDFLAGS)" OBJS="QCC_OBJS SOBJS"
|
@$(MAKE) $(TYPE) EXE_NAME="$(EXE_NAME)$(EXEPOSTFIX)" PRECOMPHEADERS="" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(CLIENT_ONLY_CFLAGS) $(WCFLAGS)" LDFLAGS="$(LDFLAGS) $(QCC_LDFLAGS)" OBJS="QCC_OBJS SOBJS"
|
||||||
qcc-rel:
|
qcc-rel:
|
||||||
@$(MAKE) _qcc-tmp TYPE=_out-rel REQDIR=reldir EXE_NAME="../fteqcc$(BITS)" OUT_DIR="$(RELEASE_DIR)/$(QCC_DIR)" SOBJS="qcctui.o $(if $(findstring win,$(FTE_TARGET)),fteqcc.o)"
|
@$(MAKE) _qcc-tmp TYPE=_out-rel REQDIR=reldir EXE_NAME="../fteqcc$(BITS)" OUT_DIR="$(RELEASE_DIR)/$(QCC_DIR)" SOBJS="qcctui.o $(if $(findstring win,$(FTE_TARGET)),fteqcc.o)"
|
||||||
qccgui-rel:
|
qccgui-rel:
|
||||||
|
|
|
@ -2073,9 +2073,8 @@ void CL_CheckServerInfo(void)
|
||||||
|
|
||||||
if (cls.protocol == CP_NETQUAKE)
|
if (cls.protocol == CP_NETQUAKE)
|
||||||
{ //proquake likes spamming us with fixangles
|
{ //proquake likes spamming us with fixangles
|
||||||
float div = cls.proquake_angles_hack?65536:256;
|
//should be about 0.5/65536, but there's some precision issues with such small numbers around 80, so we need to bias it more than we ought
|
||||||
cl.maxpitch -= 1.0/2048;
|
cl.maxpitch -= 1.0/2048;
|
||||||
cl.minpitch -= 0.5/div;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -1552,6 +1552,9 @@ void SCR_DrawClock(void)
|
||||||
|
|
||||||
time( &long_time );
|
time( &long_time );
|
||||||
newtime = localtime( &long_time );
|
newtime = localtime( &long_time );
|
||||||
|
if (show_clock.ival == 2)
|
||||||
|
strftime( str, sizeof(str)-1, "%I:%M %p ", newtime);
|
||||||
|
else
|
||||||
strftime( str, sizeof(str)-1, "%H:%M ", newtime);
|
strftime( str, sizeof(str)-1, "%H:%M ", newtime);
|
||||||
|
|
||||||
SCR_StringXY(str, show_clock_x.value, show_clock_y.value);
|
SCR_StringXY(str, show_clock_x.value, show_clock_y.value);
|
||||||
|
|
|
@ -373,8 +373,8 @@ static qboolean PM_MergePackage(package_t *oldp, package_t *newp)
|
||||||
;
|
;
|
||||||
for (nm = 0; nm < countof(newp->mirror) && newp->mirror[nm]; nm++)
|
for (nm = 0; nm < countof(newp->mirror) && newp->mirror[nm]; nm++)
|
||||||
;
|
;
|
||||||
if (oldp->priority != newp->priority)
|
// if (oldp->priority != newp->priority)
|
||||||
return false;
|
// return false;
|
||||||
|
|
||||||
ignorefiles = (oldp->extract==EXTRACT_ZIP); //zips ignore the remote file list, its only important if its already installed (so just keep the old file list and its fine).
|
ignorefiles = (oldp->extract==EXTRACT_ZIP); //zips ignore the remote file list, its only important if its already installed (so just keep the old file list and its fine).
|
||||||
if (oldp->extract != newp->extract)
|
if (oldp->extract != newp->extract)
|
||||||
|
@ -415,6 +415,7 @@ static qboolean PM_MergePackage(package_t *oldp, package_t *newp)
|
||||||
if (newp->license){Z_Free(oldp->license); oldp->license = Z_StrDup(newp->license);}
|
if (newp->license){Z_Free(oldp->license); oldp->license = Z_StrDup(newp->license);}
|
||||||
if (newp->author){Z_Free(oldp->author); oldp->author = Z_StrDup(newp->author);}
|
if (newp->author){Z_Free(oldp->author); oldp->author = Z_StrDup(newp->author);}
|
||||||
if (newp->previewimage){Z_Free(oldp->previewimage); oldp->previewimage = Z_StrDup(newp->previewimage);}
|
if (newp->previewimage){Z_Free(oldp->previewimage); oldp->previewimage = Z_StrDup(newp->previewimage);}
|
||||||
|
oldp->priority = newp->priority;
|
||||||
|
|
||||||
if (nm)
|
if (nm)
|
||||||
{ //copy over the mirrors
|
{ //copy over the mirrors
|
||||||
|
|
|
@ -2110,25 +2110,19 @@ void M_Menu_Main_f (void)
|
||||||
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Multiplayer ", "menu_multi\n"); y += 20;
|
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Multiplayer ", "menu_multi\n"); y += 20;
|
||||||
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Options ", "menu_options\n"); y += 20;
|
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Options ", "menu_options\n"); y += 20;
|
||||||
if (m_helpismedia.value)
|
if (m_helpismedia.value)
|
||||||
{
|
{MC_AddConsoleCommandQBigFont(mainm, 72, y, "Media ", "menu_media\n"); y += 20;}
|
||||||
MC_AddConsoleCommandQBigFont(mainm, 72, y, "Media ", "menu_media\n"); y += 20;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{MC_AddConsoleCommandQBigFont(mainm, 72, y, "Help ", "help\n"); y += 20;}
|
||||||
MC_AddConsoleCommandQBigFont(mainm, 72, y, "Help ", "help\n"); y += 20;
|
|
||||||
}
|
|
||||||
if (Cmd_AliasExist("mod_menu", RESTRICT_LOCAL))
|
if (Cmd_AliasExist("mod_menu", RESTRICT_LOCAL))
|
||||||
{
|
{MC_AddConsoleCommandQBigFont(mainm, 72, y, va("%-14s", Cvar_Get("mod_menu", "Mod Menu", 0, NULL)->string), "mod_menu\n"); y += 20;}
|
||||||
MC_AddConsoleCommandQBigFont(mainm, 72, y, va("%-13s", Cvar_Get("mod_menu", "Mod Menu", 0, NULL)->string), "mod_menu\n"); y += 20;
|
|
||||||
}
|
|
||||||
if (Cmd_Exists("xmpp"))
|
if (Cmd_Exists("xmpp"))
|
||||||
{
|
{MC_AddConsoleCommandQBigFont(mainm, 72, y, "Social ", "xmpp\n"); y += 20;}
|
||||||
MC_AddConsoleCommandQBigFont(mainm, 72, y, "Social ", "xmpp\n"); y += 20;
|
|
||||||
}
|
|
||||||
if (Cmd_Exists("irc"))
|
if (Cmd_Exists("irc"))
|
||||||
{
|
{MC_AddConsoleCommandQBigFont(mainm, 72, y, "IRC ", "irc\n"); y += 20;}
|
||||||
MC_AddConsoleCommandQBigFont(mainm, 72, y, "IRC ", "irc\n"); y += 20;
|
if (Cmd_Exists("qi"))
|
||||||
}
|
{MC_AddConsoleCommandQBigFont(mainm, 72, y, "Quake Injector", "qi\n"); y += 20;}
|
||||||
|
if (Cmd_Exists("menu_download"))
|
||||||
|
{MC_AddConsoleCommandQBigFont(mainm, 72, y, "Updates ", "menu_download\n"); y += 20;}
|
||||||
#ifdef FTE_TARGET_WEB
|
#ifdef FTE_TARGET_WEB
|
||||||
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Save Settings ", "menu_quit\n"); y += 20;
|
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Save Settings ", "menu_quit\n"); y += 20;
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -3114,7 +3114,8 @@ static void Mods_Draw(int x, int y, struct menucustom_s *c, struct menu_s *m)
|
||||||
if (!mods->nummanifests)
|
if (!mods->nummanifests)
|
||||||
{
|
{
|
||||||
Draw_FunString(x, y+0, "No games or mods known");
|
Draw_FunString(x, y+0, "No games or mods known");
|
||||||
Draw_FunString(x, y+8, "Consider using -basedir $PATHTOGAME on the commandline");
|
Draw_FunString(x, y+8, "You may need to use -basedir $PATHTOGAME on the commandline");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; y+8 <= ym && i < mods->nummanifests; y+=8, i++)
|
for (i = 0; y+8 <= ym && i < mods->nummanifests; y+=8, i++)
|
||||||
|
@ -3132,18 +3133,27 @@ static qboolean Mods_Key(struct menucustom_s *c, struct menu_s *m, int key, unsi
|
||||||
ftemanifest_t *man;
|
ftemanifest_t *man;
|
||||||
if (key == K_MOUSE1)
|
if (key == K_MOUSE1)
|
||||||
{
|
{
|
||||||
|
qboolean wasgameless = !*FS_GetGamedir(false);
|
||||||
i = (mousecursor_y - mods->y)/8;
|
i = (mousecursor_y - mods->y)/8;
|
||||||
if (i < 0 || i > mods->nummanifests)
|
if (i < 0 || i > mods->nummanifests)
|
||||||
return false;
|
return false;
|
||||||
man = mods->manifests[i];
|
man = mods->manifests[i];
|
||||||
mods->manifests[i] = NULL;
|
mods->manifests[i] = NULL; //make sure the manifest survives the menu being closed.
|
||||||
M_RemoveMenu(m);
|
M_RemoveMenu(m);
|
||||||
FS_ChangeGame(man, true, true);
|
FS_ChangeGame(man, true, true);
|
||||||
|
|
||||||
//starting to a blank state generally means that the current config settings are utterly useless and windowed by default.
|
if (wasgameless && !!*FS_GetGamedir(false))
|
||||||
|
{
|
||||||
|
//starting to a blank state generally means that the current(engine-default) config settings are utterly useless and windowed by default.
|
||||||
//so generally when switching to a *real* game, we want to restart video just so things like fullscreen etc are saved+used properly.
|
//so generally when switching to a *real* game, we want to restart video just so things like fullscreen etc are saved+used properly.
|
||||||
//if we're already running a game, this should probably just be a vid_reload instead to ensure that the conback etc is reloaded.
|
|
||||||
Cbuf_AddText("\nvid_restart\n", RESTRICT_LOCAL);
|
Cbuf_AddText("\nvid_restart\n", RESTRICT_LOCAL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//if we're already running a game, this should probably just be a vid_reload instead to ensure that the conback etc is reloaded.
|
||||||
|
//(a full restart is annoying)
|
||||||
|
Cbuf_AddText("\nvid_reload\n", RESTRICT_LOCAL);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3184,13 +3194,6 @@ void M_Menu_Mods_f (void)
|
||||||
memset(&mods, 0, sizeof(mods));
|
memset(&mods, 0, sizeof(mods));
|
||||||
FS_EnumerateKnownGames(Mods_AddMod, &mods);
|
FS_EnumerateKnownGames(Mods_AddMod, &mods);
|
||||||
|
|
||||||
if (mods.nummanifests == 1)
|
|
||||||
{
|
|
||||||
FS_ChangeGame(mods.manifests[0], true, true);
|
|
||||||
Z_Free(mods.manifests);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Key_Dest_Add(kdm_emenu);
|
Key_Dest_Add(kdm_emenu);
|
||||||
|
|
||||||
menu = M_CreateMenu(sizeof(modmenu_t));
|
menu = M_CreateMenu(sizeof(modmenu_t));
|
||||||
|
@ -3207,7 +3210,6 @@ void M_Menu_Mods_f (void)
|
||||||
c->key = Mods_Key;
|
c->key = Mods_Key;
|
||||||
menu->remove = Mods_Remove;
|
menu->remove = Mods_Remove;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
extern ftemanifest_t *fs_manifest; //currently active manifest.
|
extern ftemanifest_t *fs_manifest; //currently active manifest.
|
||||||
|
|
|
@ -473,7 +473,7 @@ void M_Menu_SinglePlayer_f (void)
|
||||||
{
|
{
|
||||||
menu = M_CreateMenu(0);
|
menu = M_CreateMenu(0);
|
||||||
MC_AddPicture(menu, 16, 4, 32, 144, "gfx/qplaque.lmp");
|
MC_AddPicture(menu, 16, 4, 32, 144, "gfx/qplaque.lmp");
|
||||||
MC_AddCenterPicture(menu, 0, 24, "gfx/ttl_sgl.lmp");
|
MC_AddCenterPicture(menu, 4, 24, "gfx/ttl_sgl.lmp");
|
||||||
|
|
||||||
menu->selecteditem = (menuoption_t*)
|
menu->selecteditem = (menuoption_t*)
|
||||||
MC_AddConsoleCommandQBigFont (menu, 72, 32, "New Game", va("closemenu;disconnect;maxclients 1;deathmatch 0;coop %i;startmap_sp\n", cl_splitscreen.ival>0));
|
MC_AddConsoleCommandQBigFont (menu, 72, 32, "New Game", va("closemenu;disconnect;maxclients 1;deathmatch 0;coop %i;startmap_sp\n", cl_splitscreen.ival>0));
|
||||||
|
|
|
@ -2746,6 +2746,38 @@ static void QCBUILTIN PF_ReadAngle(pubprogfuncs_t *prinst, struct globalvars_s *
|
||||||
G_FLOAT(OFS_RETURN) = MSG_ReadAngle();
|
G_FLOAT(OFS_RETURN) = MSG_ReadAngle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//basically acts as a readstring, but with added precache (and download)
|
||||||
|
static void QCBUILTIN PF_ReadPicture(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||||
|
{
|
||||||
|
char *imagename;
|
||||||
|
unsigned short size;
|
||||||
|
if (!csqc_mayread)
|
||||||
|
{
|
||||||
|
CSQC_Abort("PF_ReadPicture is not valid at this time");
|
||||||
|
G_INT(OFS_RETURN) = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
imagename = MSG_ReadString();
|
||||||
|
size = MSG_ReadShort();
|
||||||
|
MSG_ReadSkip(size);
|
||||||
|
|
||||||
|
//do the precache+download thing
|
||||||
|
{
|
||||||
|
shader_t *pic = R2D_SafeCachePic(imagename);
|
||||||
|
char ext[8];
|
||||||
|
|
||||||
|
//fixme: probably shouldn't block here.
|
||||||
|
if ((!pic || !R_GetShaderSizes(pic, NULL, NULL, true)) && cls.state
|
||||||
|
#ifndef CLIENTONLY
|
||||||
|
&& !sv.active
|
||||||
|
#endif
|
||||||
|
&& *COM_FileExtension(imagename, ext, sizeof(ext))) //only try to download it if it looks as though it contains a path.
|
||||||
|
CL_CheckOrEnqueDownloadFile(imagename, imagename, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
RETURN_TSTRING(imagename);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void QCBUILTIN PF_objerror (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
static void QCBUILTIN PF_objerror (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||||
{
|
{
|
||||||
|
|
|
@ -99,6 +99,12 @@ static qboolean WASAPI_DetermineFormat(soundcardinfo_t *sc, IAudioClient *dev, q
|
||||||
{
|
{
|
||||||
Con_Printf("WASAPI: overriding channels\n");
|
Con_Printf("WASAPI: overriding channels\n");
|
||||||
|
|
||||||
|
if (sc->sn.numchannels >= 8)
|
||||||
|
{
|
||||||
|
pwfx->nChannels = 8;
|
||||||
|
if (pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
|
||||||
|
((WAVEFORMATEXTENSIBLE*)pwfx)->dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_FRONT_LEFT_OF_CENTER | SPEAKER_FRONT_RIGHT_OF_CENTER;
|
||||||
|
}
|
||||||
if (sc->sn.numchannels >= 6)
|
if (sc->sn.numchannels >= 6)
|
||||||
{
|
{
|
||||||
pwfx->nChannels = 6;
|
pwfx->nChannels = 6;
|
||||||
|
|
|
@ -4861,9 +4861,21 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs, qboolean
|
||||||
|
|
||||||
man = FS_ReadDefaultManifest(newbasedir, sizeof(newbasedir), fixedbasedir);
|
man = FS_ReadDefaultManifest(newbasedir, sizeof(newbasedir), fixedbasedir);
|
||||||
|
|
||||||
if (!man && isDedicated)
|
if (!man)
|
||||||
{ //dedicated servers have no menu code, so just pick the first fmf we could find.
|
{
|
||||||
FS_EnumerateKnownGames(FS_FoundManifest, &man);
|
int found = FS_EnumerateKnownGames(FS_FoundManifest, &man);
|
||||||
|
if (found != 1)
|
||||||
|
{
|
||||||
|
//we found more than 1 (or none)
|
||||||
|
//if we're a client, display a menu to pick between them (or display an error)
|
||||||
|
//servers can just use the first they find, they'd effectively just crash otherwise, but still give a warning.
|
||||||
|
if (!isDedicated)
|
||||||
|
man = NULL;
|
||||||
|
else if (found)
|
||||||
|
Con_Printf(CON_WARNING "Warning: found multiple possible games. Using the first found.\n");
|
||||||
|
else
|
||||||
|
Con_Printf(CON_ERROR "Error: unable to determine correct game/basedir.\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!man)
|
if (!man)
|
||||||
{
|
{
|
||||||
|
@ -5183,7 +5195,7 @@ static int QDECL FS_EnumerateFMFs(const char *fname, qofs_t fsize, time_t mtime,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FS_EnumerateKnownGames(qboolean (*callback)(void *usr, ftemanifest_t *man), void *usr)
|
int FS_EnumerateKnownGames(qboolean (*callback)(void *usr, ftemanifest_t *man), void *usr)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char basedir[MAX_OSPATH];
|
char basedir[MAX_OSPATH];
|
||||||
|
@ -5230,6 +5242,7 @@ void FS_EnumerateKnownGames(qboolean (*callback)(void *usr, ftemanifest_t *man),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return e.found;
|
||||||
}
|
}
|
||||||
|
|
||||||
//attempts to find a new basedir for 'input', changing to it as appropriate
|
//attempts to find a new basedir for 'input', changing to it as appropriate
|
||||||
|
|
|
@ -70,7 +70,7 @@ void FS_AddHashedPackage(searchpath_t **oldpaths, const char *parent_pure, const
|
||||||
void PM_LoadPackages(searchpath_t **oldpaths, const char *parent_pure, const char *parent_logical, searchpath_t *search, unsigned int loadstuff, int minpri, int maxpri);
|
void PM_LoadPackages(searchpath_t **oldpaths, const char *parent_pure, const char *parent_logical, searchpath_t *search, unsigned int loadstuff, int minpri, int maxpri);
|
||||||
void Menu_Download_Update(void);
|
void Menu_Download_Update(void);
|
||||||
|
|
||||||
void FS_EnumerateKnownGames(qboolean (*callback)(void *usr, ftemanifest_t *man), void *usr);
|
int FS_EnumerateKnownGames(qboolean (*callback)(void *usr, ftemanifest_t *man), void *usr);
|
||||||
|
|
||||||
#define SPF_REFERENCED 1 //something has been loaded from this path. should filter out client references...
|
#define SPF_REFERENCED 1 //something has been loaded from this path. should filter out client references...
|
||||||
#define SPF_COPYPROTECTED 2 //downloads are not allowed fom here.
|
#define SPF_COPYPROTECTED 2 //downloads are not allowed fom here.
|
||||||
|
|
|
@ -2655,7 +2655,9 @@ void QCBUILTIN PF_parseentitydata(pubprogfuncs_t *prinst, struct globalvars_s *p
|
||||||
|
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
if (offset)
|
if (offset < 0)
|
||||||
|
offset = 0;
|
||||||
|
else if (offset)
|
||||||
{
|
{
|
||||||
int boffset = offset;
|
int boffset = offset;
|
||||||
if (VMUTF8)
|
if (VMUTF8)
|
||||||
|
@ -2979,12 +2981,12 @@ void QCBUILTIN PF_strpad (pubprogfuncs_t *prinst, struct globalvars_s *pr_global
|
||||||
if (pad < 0)
|
if (pad < 0)
|
||||||
{ //pad left
|
{ //pad left
|
||||||
pad = -pad - strlen(src);
|
pad = -pad - strlen(src);
|
||||||
if (pad>=MAXTEMPBUFFERLEN)
|
if (pad>=sizeof(destbuf))
|
||||||
pad = MAXTEMPBUFFERLEN-1;
|
pad = sizeof(destbuf)-1;
|
||||||
if (pad < 0)
|
if (pad < 0)
|
||||||
pad = 0;
|
pad = 0;
|
||||||
|
|
||||||
Q_strncpyz(dest+pad, src, MAXTEMPBUFFERLEN-pad);
|
Q_strncpyz(dest+pad, src, sizeof(destbuf)-pad);
|
||||||
while(pad)
|
while(pad)
|
||||||
{
|
{
|
||||||
dest[--pad] = ' ';
|
dest[--pad] = ' ';
|
||||||
|
@ -2992,13 +2994,13 @@ void QCBUILTIN PF_strpad (pubprogfuncs_t *prinst, struct globalvars_s *pr_global
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ //pad right
|
{ //pad right
|
||||||
if (pad>=MAXTEMPBUFFERLEN)
|
if (pad>=sizeof(destbuf))
|
||||||
pad = MAXTEMPBUFFERLEN-1;
|
pad = sizeof(destbuf)-1;
|
||||||
pad -= strlen(src);
|
pad -= strlen(src);
|
||||||
if (pad < 0)
|
if (pad < 0)
|
||||||
pad = 0;
|
pad = 0;
|
||||||
|
|
||||||
Q_strncpyz(dest, src, MAXTEMPBUFFERLEN);
|
Q_strncpyz(dest, src, sizeof(destbuf));
|
||||||
dest+=strlen(dest);
|
dest+=strlen(dest);
|
||||||
|
|
||||||
while(pad-->0)
|
while(pad-->0)
|
||||||
|
@ -4115,8 +4117,12 @@ void QCBUILTIN PF_buf_writefile (pubprogfuncs_t *prinst, struct globalvars_s *p
|
||||||
idx = bound(0, idx, strbuflist[bufno].used);
|
idx = bound(0, idx, strbuflist[bufno].used);
|
||||||
midx = min(midx, strbuflist[bufno].used);
|
midx = min(midx, strbuflist[bufno].used);
|
||||||
for(strings = strbuflist[bufno].strings; idx < midx; idx++)
|
for(strings = strbuflist[bufno].strings; idx < midx; idx++)
|
||||||
|
{
|
||||||
|
if (strings[idx])
|
||||||
{
|
{
|
||||||
PF_fwrite_internal (prinst, fnum, strings[idx], strlen(strings[idx]));
|
PF_fwrite_internal (prinst, fnum, strings[idx], strlen(strings[idx]));
|
||||||
|
PF_fwrite_internal (prinst, fnum, "\n", 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
G_FLOAT(OFS_RETURN) = 1;
|
G_FLOAT(OFS_RETURN) = 1;
|
||||||
}
|
}
|
||||||
|
@ -4211,7 +4217,7 @@ void QCBUILTIN PF_uri_unescape (pubprogfuncs_t *prinst, struct globalvars_s *pr
|
||||||
unsigned char *i, *o;
|
unsigned char *i, *o;
|
||||||
unsigned char hex;
|
unsigned char hex;
|
||||||
i = s; o = resultbuf;
|
i = s; o = resultbuf;
|
||||||
while (*i)
|
while (*i && o < resultbuf+sizeof(resultbuf)-2)
|
||||||
{
|
{
|
||||||
if (*i == '%')
|
if (*i == '%')
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,9 +45,6 @@ struct wedict_s
|
||||||
|
|
||||||
#define PF_drawline PF_Fixme
|
#define PF_drawline PF_Fixme
|
||||||
|
|
||||||
#define PF_WritePicture PF_Fixme
|
|
||||||
#define PF_ReadPicture PF_Fixme
|
|
||||||
|
|
||||||
#define G_PROG G_FLOAT
|
#define G_PROG G_FLOAT
|
||||||
|
|
||||||
//the lh extension system asks for a name for the extension.
|
//the lh extension system asks for a name for the extension.
|
||||||
|
|
|
@ -947,7 +947,7 @@ static texid_t Font_LoadReplacementConchars(void)
|
||||||
{
|
{
|
||||||
texid_t tex;
|
texid_t tex;
|
||||||
//q1 replacement
|
//q1 replacement
|
||||||
tex = R_LoadReplacementTexture("gfx/conchars.lmp", NULL, IF_LOADNOW|IF_UIPIC|IF_NOMIPMAP|IF_NOGAMMA, NULL, 0, 0, TF_INVALID);
|
tex = R_LoadHiResTexture("gfx/conchars.lmp", NULL, IF_LOADNOW|IF_UIPIC|IF_NOMIPMAP|IF_NOGAMMA);//, NULL, 0, 0, TF_INVALID);
|
||||||
TEXDOWAIT(tex);
|
TEXDOWAIT(tex);
|
||||||
if (TEXLOADED(tex))
|
if (TEXLOADED(tex))
|
||||||
return tex;
|
return tex;
|
||||||
|
|
|
@ -5095,6 +5095,7 @@ static void * Mod_LoadSpriteGroup (model_t *mod, void * pin, void *pend, msprite
|
||||||
dspriteinterval_t *pin_intervals;
|
dspriteinterval_t *pin_intervals;
|
||||||
float *poutintervals;
|
float *poutintervals;
|
||||||
void *ptemp;
|
void *ptemp;
|
||||||
|
float prevtime;
|
||||||
|
|
||||||
pingroup = (dspritegroup_t *)pin;
|
pingroup = (dspritegroup_t *)pin;
|
||||||
|
|
||||||
|
@ -5112,7 +5113,7 @@ static void * Mod_LoadSpriteGroup (model_t *mod, void * pin, void *pend, msprite
|
||||||
|
|
||||||
pspritegroup->intervals = poutintervals;
|
pspritegroup->intervals = poutintervals;
|
||||||
|
|
||||||
for (i=0 ; i<numframes ; i++)
|
for (i=0, prevtime=0 ; i<numframes ; i++)
|
||||||
{
|
{
|
||||||
*poutintervals = LittleFloat (pin_intervals->interval);
|
*poutintervals = LittleFloat (pin_intervals->interval);
|
||||||
if (*poutintervals <= 0.0)
|
if (*poutintervals <= 0.0)
|
||||||
|
@ -5120,6 +5121,7 @@ static void * Mod_LoadSpriteGroup (model_t *mod, void * pin, void *pend, msprite
|
||||||
Con_Printf (CON_ERROR "Mod_LoadSpriteGroup: interval<=0\n");
|
Con_Printf (CON_ERROR "Mod_LoadSpriteGroup: interval<=0\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
prevtime = *poutintervals = prevtime+*poutintervals;
|
||||||
|
|
||||||
poutintervals++;
|
poutintervals++;
|
||||||
pin_intervals++;
|
pin_intervals++;
|
||||||
|
|
|
@ -595,6 +595,7 @@ extern pbool flag_brokenarrays;
|
||||||
extern pbool flag_rootconstructor;
|
extern pbool flag_rootconstructor;
|
||||||
extern pbool flag_guiannotate;
|
extern pbool flag_guiannotate;
|
||||||
extern pbool flag_qccx;
|
extern pbool flag_qccx;
|
||||||
|
extern pbool flag_embedsrc;
|
||||||
|
|
||||||
extern pbool opt_overlaptemps;
|
extern pbool opt_overlaptemps;
|
||||||
extern pbool opt_shortenifnots;
|
extern pbool opt_shortenifnots;
|
||||||
|
@ -1033,7 +1034,9 @@ int QCC_CopyStringLength (char *str, size_t length);
|
||||||
|
|
||||||
typedef struct qcc_cachedsourcefile_s {
|
typedef struct qcc_cachedsourcefile_s {
|
||||||
char filename[128];
|
char filename[128];
|
||||||
int size;
|
size_t size;
|
||||||
|
size_t zhdrofs;
|
||||||
|
int zcrc;
|
||||||
char *file;
|
char *file;
|
||||||
enum{FT_CODE, FT_DATA} type; //quakec source file or not.
|
enum{FT_CODE, FT_DATA} type; //quakec source file or not.
|
||||||
struct qcc_cachedsourcefile_s *next;
|
struct qcc_cachedsourcefile_s *next;
|
||||||
|
|
|
@ -108,6 +108,7 @@ pbool flag_guiannotate;
|
||||||
pbool flag_brokenarrays; //return array; returns array[0] instead of &array;
|
pbool flag_brokenarrays; //return array; returns array[0] instead of &array;
|
||||||
pbool flag_rootconstructor; //if true, class constructors are ordered to call the super constructor first, rather than the child constructor
|
pbool flag_rootconstructor; //if true, class constructors are ordered to call the super constructor first, rather than the child constructor
|
||||||
pbool flag_qccx;
|
pbool flag_qccx;
|
||||||
|
pbool flag_embedsrc;
|
||||||
|
|
||||||
pbool opt_overlaptemps; //reduce numpr_globals by reuse of temps. When they are not needed they are freed for reuse. The way this is implemented is better than frikqcc's. (This is the single most important optimisation)
|
pbool opt_overlaptemps; //reduce numpr_globals by reuse of temps. When they are not needed they are freed for reuse. The way this is implemented is better than frikqcc's. (This is the single most important optimisation)
|
||||||
pbool opt_assignments; //STORE_F isn't used if an operation wrote to a temp.
|
pbool opt_assignments; //STORE_F isn't used if an operation wrote to a temp.
|
||||||
|
@ -5054,6 +5055,7 @@ QCC_sref_t QCC_PR_GenerateFunctionCallRef (QCC_sref_t newself, QCC_sref_t func,
|
||||||
{
|
{
|
||||||
fparm.sym = &def_parms[parm+ofs/3];
|
fparm.sym = &def_parms[parm+ofs/3];
|
||||||
fparm.cast = type_vector;
|
fparm.cast = type_vector;
|
||||||
|
QCC_ForceUnFreeDef(fparm.sym);
|
||||||
}
|
}
|
||||||
fparm.ofs = ofs - (ofs%3);
|
fparm.ofs = ofs - (ofs%3);
|
||||||
if (!fparm.ofs)
|
if (!fparm.ofs)
|
||||||
|
@ -5122,6 +5124,7 @@ QCC_sref_t QCC_PR_GenerateFunctionCallRef (QCC_sref_t newself, QCC_sref_t func,
|
||||||
{
|
{
|
||||||
if (args[i].ref.sym != d.sym || args[i].ref.ofs != d.ofs)
|
if (args[i].ref.sym != d.sym || args[i].ref.ofs != d.ofs)
|
||||||
{
|
{
|
||||||
|
QCC_ForceUnFreeDef(d.sym);
|
||||||
if (args[i].ref.cast->size == 3)
|
if (args[i].ref.cast->size == 3)
|
||||||
QCC_FreeTemp(QCC_PR_StatementFlags (&pr_opcodes[OP_STORE_V], args[i].ref, d, NULL, 0));
|
QCC_FreeTemp(QCC_PR_StatementFlags (&pr_opcodes[OP_STORE_V], args[i].ref, d, NULL, 0));
|
||||||
else
|
else
|
||||||
|
@ -5238,6 +5241,7 @@ QCC_sref_t QCC_PR_GenerateFunctionCallRef (QCC_sref_t newself, QCC_sref_t func,
|
||||||
d.sym = &def_parms[parm];
|
d.sym = &def_parms[parm];
|
||||||
d.ofs = 0;
|
d.ofs = 0;
|
||||||
d.cast = type_vector;
|
d.cast = type_vector;
|
||||||
|
QCC_ForceUnFreeDef(d.sym);
|
||||||
}
|
}
|
||||||
d.cast = arglist[i]->cast;
|
d.cast = arglist[i]->cast;
|
||||||
|
|
||||||
|
@ -9545,6 +9549,145 @@ void PR_GenerateReturnOuts(void)
|
||||||
local = local->deftail->nextlocal;
|
local = local->deftail->nextlocal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
============
|
||||||
|
QCC_PR_ParseStatement_For
|
||||||
|
|
||||||
|
pulled out of QCC_PR_ParseStatement because of stack use.
|
||||||
|
============
|
||||||
|
*/
|
||||||
|
void QCC_PR_ParseStatement (void);
|
||||||
|
void QCC_PR_ParseStatement_For(void)
|
||||||
|
{
|
||||||
|
int continues;
|
||||||
|
int breaks;
|
||||||
|
int i;
|
||||||
|
QCC_sref_t e;
|
||||||
|
QCC_def_t *d;
|
||||||
|
QCC_statement_t *patch1, *patch2, *patch3, *patch4;
|
||||||
|
|
||||||
|
|
||||||
|
int old_numstatements;
|
||||||
|
int numtemp;
|
||||||
|
QCC_def_t *subscopestop;
|
||||||
|
QCC_def_t *subscopestart = pr.local_tail;
|
||||||
|
|
||||||
|
QCC_statement_t temp[256];
|
||||||
|
|
||||||
|
continues = num_continues;
|
||||||
|
breaks = num_breaks;
|
||||||
|
|
||||||
|
QCC_PR_Expect("(");
|
||||||
|
if (!QCC_PR_CheckToken(";"))
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
QCC_type_t *type = QCC_PR_ParseType (false, true);
|
||||||
|
if (type)
|
||||||
|
{
|
||||||
|
d = QCC_PR_GetDef (type, QCC_PR_ParseName(), pr_scope, true, 0, 0);
|
||||||
|
QCC_PR_Expect("=");
|
||||||
|
QCC_PR_ParseInitializerDef(d);
|
||||||
|
QCC_FreeDef(d);
|
||||||
|
QCC_FreeDef(d);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
QCC_PR_DiscardExpression(TOP_PRIORITY, EXPR_DISALLOW_COMMA);
|
||||||
|
} while(QCC_PR_CheckToken(","));
|
||||||
|
QCC_PR_Expect(";");
|
||||||
|
}
|
||||||
|
subscopestop = pr_subscopedlocals?NULL:pr.local_tail->nextlocal;
|
||||||
|
|
||||||
|
QCC_ClobberDef(NULL);
|
||||||
|
|
||||||
|
patch2 = &statements[numstatements]; //restart of the loop
|
||||||
|
if (!QCC_PR_CheckToken(";"))
|
||||||
|
{
|
||||||
|
conditional = 1;
|
||||||
|
e = QCC_PR_Expression(TOP_PRIORITY, 0);
|
||||||
|
conditional = 0;
|
||||||
|
QCC_PR_Expect(";");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
e = nullsref;
|
||||||
|
|
||||||
|
if (e.cast) //final condition+jump
|
||||||
|
QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_IFNOT_I], e, nullsref, &patch1, STFL_DISCARDRESULT));
|
||||||
|
else
|
||||||
|
patch1 = NULL;
|
||||||
|
|
||||||
|
if (!QCC_PR_CheckToken(")"))
|
||||||
|
{
|
||||||
|
old_numstatements = numstatements;
|
||||||
|
QCC_PR_DiscardExpression(TOP_PRIORITY, 0);
|
||||||
|
|
||||||
|
numtemp = numstatements - old_numstatements;
|
||||||
|
if (numtemp > sizeof(temp)/sizeof(temp[0]))
|
||||||
|
QCC_PR_ParseError(ERR_TOOCOMPLEX, "Update expression too large");
|
||||||
|
numstatements = old_numstatements;
|
||||||
|
for (i = 0 ; i < numtemp ; i++)
|
||||||
|
{
|
||||||
|
temp[i] = statements[numstatements + i];
|
||||||
|
}
|
||||||
|
|
||||||
|
QCC_PR_Expect(")");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
numtemp = 0;
|
||||||
|
|
||||||
|
//parse the statement block
|
||||||
|
if (!QCC_PR_CheckToken(";"))
|
||||||
|
QCC_PR_ParseStatement(); //don't give the hanging ';' warning.
|
||||||
|
patch3 = &statements[numstatements]; //location for continues
|
||||||
|
//reinsert the 'increment' statements. lets hope they didn't have any gotos...
|
||||||
|
for (i = 0 ; i < numtemp ; i++)
|
||||||
|
{
|
||||||
|
statements[numstatements] = temp[i];
|
||||||
|
statements[numstatements].linenum = pr_token_line_last;
|
||||||
|
numstatements++;
|
||||||
|
}
|
||||||
|
patch4 = QCC_Generate_OP_GOTO();
|
||||||
|
patch4->a.ofs = patch2 - patch4;
|
||||||
|
if (patch1)
|
||||||
|
patch1->b.ofs = &statements[numstatements] - patch1; //condition failure jumps here
|
||||||
|
|
||||||
|
//fix up breaks+continues
|
||||||
|
if (breaks != num_breaks)
|
||||||
|
{
|
||||||
|
for(i = breaks; i < num_breaks; i++)
|
||||||
|
{
|
||||||
|
patch1 = &statements[pr_breaks[i]];
|
||||||
|
statements[pr_breaks[i]].a.ofs = &statements[numstatements] - patch1;
|
||||||
|
}
|
||||||
|
num_breaks = breaks;
|
||||||
|
}
|
||||||
|
if (continues != num_continues)
|
||||||
|
{
|
||||||
|
for(i = continues; i < num_continues; i++)
|
||||||
|
{
|
||||||
|
patch1 = &statements[pr_continues[i]];
|
||||||
|
statements[pr_continues[i]].a.ofs = patch3 - patch1;
|
||||||
|
}
|
||||||
|
num_continues = continues;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//remove any new locals from the hashtable.
|
||||||
|
//typically this is just the stuff inside the for(here;;)
|
||||||
|
for (d = subscopestart->nextlocal; d != subscopestop; d = d->nextlocal)
|
||||||
|
{
|
||||||
|
if (!d->subscoped_away)
|
||||||
|
{
|
||||||
|
pHash_RemoveData(&localstable, d->name, d);
|
||||||
|
d->subscoped_away = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
============
|
============
|
||||||
PR_ParseStatement
|
PR_ParseStatement
|
||||||
|
@ -9559,7 +9702,7 @@ void QCC_PR_ParseStatement (void)
|
||||||
int i;
|
int i;
|
||||||
QCC_sref_t e, e2;
|
QCC_sref_t e, e2;
|
||||||
QCC_def_t *d;
|
QCC_def_t *d;
|
||||||
QCC_statement_t *patch1, *patch2, *patch3, *patch4;
|
QCC_statement_t *patch1, *patch2, *patch3;
|
||||||
int statementstart = pr_source_line;
|
int statementstart = pr_source_line;
|
||||||
pbool wasuntil;
|
pbool wasuntil;
|
||||||
|
|
||||||
|
@ -9733,122 +9876,7 @@ void QCC_PR_ParseStatement (void)
|
||||||
}
|
}
|
||||||
if (QCC_PR_CheckKeyword(keyword_for, "for"))
|
if (QCC_PR_CheckKeyword(keyword_for, "for"))
|
||||||
{
|
{
|
||||||
int old_numstatements;
|
QCC_PR_ParseStatement_For();
|
||||||
int numtemp, i;
|
|
||||||
QCC_def_t *subscopestop;
|
|
||||||
QCC_def_t *subscopestart = pr.local_tail;
|
|
||||||
|
|
||||||
QCC_statement_t temp[256];
|
|
||||||
|
|
||||||
continues = num_continues;
|
|
||||||
breaks = num_breaks;
|
|
||||||
|
|
||||||
QCC_PR_Expect("(");
|
|
||||||
if (!QCC_PR_CheckToken(";"))
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
QCC_type_t *type = QCC_PR_ParseType (false, true);
|
|
||||||
if (type)
|
|
||||||
{
|
|
||||||
d = QCC_PR_GetDef (type, QCC_PR_ParseName(), pr_scope, true, 0, 0);
|
|
||||||
QCC_PR_Expect("=");
|
|
||||||
QCC_PR_ParseInitializerDef(d);
|
|
||||||
QCC_FreeDef(d);
|
|
||||||
QCC_FreeDef(d);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
QCC_PR_DiscardExpression(TOP_PRIORITY, EXPR_DISALLOW_COMMA);
|
|
||||||
} while(QCC_PR_CheckToken(","));
|
|
||||||
QCC_PR_Expect(";");
|
|
||||||
}
|
|
||||||
subscopestop = pr_subscopedlocals?NULL:pr.local_tail->nextlocal;
|
|
||||||
|
|
||||||
QCC_ClobberDef(NULL);
|
|
||||||
|
|
||||||
patch2 = &statements[numstatements]; //restart of the loop
|
|
||||||
if (!QCC_PR_CheckToken(";"))
|
|
||||||
{
|
|
||||||
conditional = 1;
|
|
||||||
e = QCC_PR_Expression(TOP_PRIORITY, 0);
|
|
||||||
conditional = 0;
|
|
||||||
QCC_PR_Expect(";");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
e = nullsref;
|
|
||||||
|
|
||||||
if (e.cast) //final condition+jump
|
|
||||||
QCC_FreeTemp(QCC_PR_StatementFlags(&pr_opcodes[OP_IFNOT_I], e, nullsref, &patch1, STFL_DISCARDRESULT));
|
|
||||||
else
|
|
||||||
patch1 = NULL;
|
|
||||||
|
|
||||||
if (!QCC_PR_CheckToken(")"))
|
|
||||||
{
|
|
||||||
old_numstatements = numstatements;
|
|
||||||
QCC_PR_DiscardExpression(TOP_PRIORITY, 0);
|
|
||||||
|
|
||||||
numtemp = numstatements - old_numstatements;
|
|
||||||
if (numtemp > sizeof(temp)/sizeof(temp[0]))
|
|
||||||
QCC_PR_ParseError(ERR_TOOCOMPLEX, "Update expression too large");
|
|
||||||
numstatements = old_numstatements;
|
|
||||||
for (i = 0 ; i < numtemp ; i++)
|
|
||||||
{
|
|
||||||
temp[i] = statements[numstatements + i];
|
|
||||||
}
|
|
||||||
|
|
||||||
QCC_PR_Expect(")");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
numtemp = 0;
|
|
||||||
|
|
||||||
//parse the statement block
|
|
||||||
if (!QCC_PR_CheckToken(";"))
|
|
||||||
QCC_PR_ParseStatement(); //don't give the hanging ';' warning.
|
|
||||||
patch3 = &statements[numstatements]; //location for continues
|
|
||||||
//reinsert the 'increment' statements. lets hope they didn't have any gotos...
|
|
||||||
for (i = 0 ; i < numtemp ; i++)
|
|
||||||
{
|
|
||||||
statements[numstatements] = temp[i];
|
|
||||||
statements[numstatements].linenum = pr_token_line_last;
|
|
||||||
numstatements++;
|
|
||||||
}
|
|
||||||
patch4 = QCC_Generate_OP_GOTO();
|
|
||||||
patch4->a.ofs = patch2 - patch4;
|
|
||||||
if (patch1)
|
|
||||||
patch1->b.ofs = &statements[numstatements] - patch1; //condition failure jumps here
|
|
||||||
|
|
||||||
//fix up breaks+continues
|
|
||||||
if (breaks != num_breaks)
|
|
||||||
{
|
|
||||||
for(i = breaks; i < num_breaks; i++)
|
|
||||||
{
|
|
||||||
patch1 = &statements[pr_breaks[i]];
|
|
||||||
statements[pr_breaks[i]].a.ofs = &statements[numstatements] - patch1;
|
|
||||||
}
|
|
||||||
num_breaks = breaks;
|
|
||||||
}
|
|
||||||
if (continues != num_continues)
|
|
||||||
{
|
|
||||||
for(i = continues; i < num_continues; i++)
|
|
||||||
{
|
|
||||||
patch1 = &statements[pr_continues[i]];
|
|
||||||
statements[pr_continues[i]].a.ofs = patch3 - patch1;
|
|
||||||
}
|
|
||||||
num_continues = continues;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//remove any new locals from the hashtable.
|
|
||||||
//typically this is just the stuff inside the for(here;;)
|
|
||||||
for (d = subscopestart->nextlocal; d != subscopestop; d = d->nextlocal)
|
|
||||||
{
|
|
||||||
if (!d->subscoped_away)
|
|
||||||
{
|
|
||||||
pHash_RemoveData(&localstable, d->name, d);
|
|
||||||
d->subscoped_away = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (QCC_PR_CheckKeyword(keyword_do, "do"))
|
if (QCC_PR_CheckKeyword(keyword_do, "do"))
|
||||||
|
@ -14178,6 +14206,19 @@ pbool QCC_PR_CompileFile (char *string, char *filename)
|
||||||
{
|
{
|
||||||
QCC_def_t *d;
|
QCC_def_t *d;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
for (i = 0; i < MAX_PARMS; i++)
|
||||||
|
{
|
||||||
|
d = &def_parms[i];
|
||||||
|
if (d->refcount)
|
||||||
|
{
|
||||||
|
QCC_sref_t sr;
|
||||||
|
sr.sym = d;
|
||||||
|
sr.cast = d->type;
|
||||||
|
sr.ofs = 0;
|
||||||
|
QCC_PR_ParseWarning(WARN_DEBUGGING, "INTERNAL: %i references still held on %s (%s)", d->refcount, d->name, QCC_VarAtOffset(sr, 1));
|
||||||
|
d->refcount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
for (d = pr.def_head.next; d; d = d->next)
|
for (d = pr.def_head.next; d; d = d->next)
|
||||||
{
|
{
|
||||||
if (d->refcount)
|
if (d->refcount)
|
||||||
|
|
|
@ -3319,24 +3319,14 @@ void QCC_PR_Lex (void)
|
||||||
|
|
||||||
// if the first character is a valid identifier, parse until a non-id
|
// if the first character is a valid identifier, parse until a non-id
|
||||||
// character is reached
|
// character is reached
|
||||||
if ((c == '%') && (pr_file_p[1] == '-' || (pr_file_p[1] >= '0' && pr_file_p[1] <= '9')))
|
if ((c == '%') && flag_qccx && (pr_file_p[1] == '-' || (pr_file_p[1] >= '0' && pr_file_p[1] <= '9')))
|
||||||
{
|
{
|
||||||
if (flag_qccx)
|
//with qccx, %5 is a denormalized float.
|
||||||
{ //with qccx, %5 is a denormalized float.
|
|
||||||
pr_file_p++;
|
pr_file_p++;
|
||||||
pr_token_type = tt_immediate;
|
pr_token_type = tt_immediate;
|
||||||
pr_immediate_type = type_float;
|
pr_immediate_type = type_float;
|
||||||
QCC_PR_ParseWarning(WARN_DENORMAL, "denormalized immediate");
|
QCC_PR_ParseWarning(WARN_DENORMAL, "denormalized immediate");
|
||||||
pr_immediate._int = QCC_PR_LexInteger ();
|
pr_immediate._int = QCC_PR_LexInteger ();
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QCC_PR_ParseWarning(0, "%% prefixes to denote integers are deprecated. Please use a postfix of 'i'");
|
|
||||||
pr_file_p++;
|
|
||||||
pr_token_type = tt_immediate;
|
|
||||||
pr_immediate_type = type_integer;
|
|
||||||
pr_immediate._int = QCC_PR_LexInteger ();
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ( c == '0' && pr_file_p[1] == 'x')
|
if ( c == '0' && pr_file_p[1] == 'x')
|
||||||
|
|
|
@ -349,6 +349,7 @@ compiler_flag_t compiler_flag[] = {
|
||||||
{&flag_typeexplicit, FLAG_MIDCOMPILE,"typeexplicit", "Explicit types", "All type conversions must be explicit or directly supported by instruction set."},
|
{&flag_typeexplicit, FLAG_MIDCOMPILE,"typeexplicit", "Explicit types", "All type conversions must be explicit or directly supported by instruction set."},
|
||||||
{&flag_noboundchecks, FLAG_MIDCOMPILE,"noboundchecks","Disable Bound Checks", "Disable array index checks, speeding up array access but can result in your code misbehaving."},
|
{&flag_noboundchecks, FLAG_MIDCOMPILE,"noboundchecks","Disable Bound Checks", "Disable array index checks, speeding up array access but can result in your code misbehaving."},
|
||||||
{&flag_qccx, FLAG_MIDCOMPILE,"qccx", "QCCX syntax", "WARNING: This syntax makes mods inherantly engine specific.\nDo NOT use unless you know what you're doing.This is provided for compatibility only\nAny entity hacks will be unsupported in FTEQW, DP, and others, resulting in engine crashes if the code in question is executed."},
|
{&flag_qccx, FLAG_MIDCOMPILE,"qccx", "QCCX syntax", "WARNING: This syntax makes mods inherantly engine specific.\nDo NOT use unless you know what you're doing.This is provided for compatibility only\nAny entity hacks will be unsupported in FTEQW, DP, and others, resulting in engine crashes if the code in question is executed."},
|
||||||
|
{&flag_embedsrc, FLAG_MIDCOMPILE,"embedsrc", "Embed Sources", "Write the sourcecode into the output file."},
|
||||||
// {&flag_noreflection, FLAG_MIDCOMPILE,"omitinternals","Omit Reflection Info", "Keeps internal symbols private (equivelent to unix's hidden visibility). This has the effect of reducing filesize, thwarting debuggers, and breaking saved games. This allows you to use arrays without massively bloating the size of your progs.\nWARNING: The bit about breaking saved games was NOT a joke, but does not apply to menuqc or csqc. It also interferes with FTE_MULTIPROGS."},
|
// {&flag_noreflection, FLAG_MIDCOMPILE,"omitinternals","Omit Reflection Info", "Keeps internal symbols private (equivelent to unix's hidden visibility). This has the effect of reducing filesize, thwarting debuggers, and breaking saved games. This allows you to use arrays without massively bloating the size of your progs.\nWARNING: The bit about breaking saved games was NOT a joke, but does not apply to menuqc or csqc. It also interferes with FTE_MULTIPROGS."},
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
@ -657,7 +658,7 @@ void QCC_PrintFiles (void)
|
||||||
continue; //*-prefixed models are not real, and shouldn't be included in file lists.
|
continue; //*-prefixed models are not real, and shouldn't be included in file lists.
|
||||||
if (!header)
|
if (!header)
|
||||||
{
|
{
|
||||||
printf("pak%i:\n", b);
|
printf("pak%i:\n", b-1);
|
||||||
header=true;
|
header=true;
|
||||||
}
|
}
|
||||||
printf("%s\n", precaches[g].list[i].name);
|
printf("%s\n", precaches[g].list[i].name);
|
||||||
|
@ -670,44 +671,93 @@ void QCC_PrintFiles (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
int encode(int len, int method, char *in, int handle);
|
int encode(int len, int method, char *in, int handle);
|
||||||
int WriteSourceFiles(int h, dprograms_t *progs, pbool sourceaswell)
|
int WriteSourceFiles(int h, pbool sourceaswell, pbool legacyembed)
|
||||||
{
|
{
|
||||||
|
//helpers to deal with misaligned data. writes little-endian.
|
||||||
|
#define misbyte(ptr,ofs,data) ((unsigned char*)(ptr))[ofs] = (data)&0xff;
|
||||||
|
#define misshort(ptr,ofs,data) misbyte((ptr),(ofs),(data));misbyte((ptr),(ofs)+1,(data)>>8);
|
||||||
|
#define misint(ptr,ofs,data) misshort((ptr),(ofs),(data));misshort((ptr),(ofs)+2,(data)>>16);
|
||||||
includeddatafile_t *idf;
|
includeddatafile_t *idf;
|
||||||
qcc_cachedsourcefile_t *f;
|
qcc_cachedsourcefile_t *f;
|
||||||
int num=0;
|
int num=0;
|
||||||
int ofs;
|
int ofs;
|
||||||
|
pbool zipembed = true;
|
||||||
/*
|
int startofs;
|
||||||
for (f = qcc_sourcefile; f ; f=f->next)
|
sourceaswell |= flag_embedsrc;
|
||||||
{
|
|
||||||
if (f->type == FT_CODE && !sourceaswell)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
SafeWrite(h, f->filename, strlen(f->filename)+1);
|
|
||||||
i = PRLittleLong(f->size);
|
|
||||||
SafeWrite(h, &i, sizeof(int));
|
|
||||||
|
|
||||||
i = PRLittleLong(encrpytmode);
|
|
||||||
SafeWrite(h, &i, sizeof(int));
|
|
||||||
|
|
||||||
if (encrpytmode)
|
|
||||||
for (i = 0; i < f->size; i++)
|
|
||||||
f->file[i] ^= 0xA5;
|
|
||||||
|
|
||||||
SafeWrite(h, f->file, f->size);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
for (f = qcc_sourcefile,num=0; f ; f=f->next)
|
for (f = qcc_sourcefile,num=0; f ; f=f->next)
|
||||||
{
|
{
|
||||||
if (f->type == FT_CODE && !sourceaswell)
|
if (f->type == FT_CODE && !sourceaswell)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
num++;
|
num++;
|
||||||
}
|
}
|
||||||
if (!num)
|
if (!num)
|
||||||
|
{
|
||||||
|
if (zipembed)
|
||||||
|
{ //zips are found by scanning. so make sure something can be found so noone will erroneously find something
|
||||||
|
char centralheader[22];
|
||||||
|
int centraldirofs = SafeSeek(h, 0, SEEK_CUR);
|
||||||
|
misint (centralheader, 0, 0x06054b50);
|
||||||
|
misshort(centralheader, 4, 0); //this disk number
|
||||||
|
misshort(centralheader, 6, 0); //centraldir first disk
|
||||||
|
misshort(centralheader, 8, 0); //centraldir entries
|
||||||
|
misshort(centralheader, 10, 0); //total centraldir entries
|
||||||
|
misint (centralheader, 12, 0); //centraldir size
|
||||||
|
misint (centralheader, 16, centraldirofs); //centraldir offset
|
||||||
|
misshort(centralheader, 20, 0); //comment length
|
||||||
|
SafeWrite(h, centralheader, 22);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
startofs = SafeSeek(h, 0, SEEK_CUR);
|
||||||
idf = qccHunkAlloc(sizeof(includeddatafile_t)*num);
|
idf = qccHunkAlloc(sizeof(includeddatafile_t)*num);
|
||||||
for (f = qcc_sourcefile,num=0; f ; f=f->next)
|
for (f = qcc_sourcefile,num=0; f ; f=f->next)
|
||||||
|
{
|
||||||
|
if (f->type == FT_CODE && !sourceaswell)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (zipembed)
|
||||||
|
{
|
||||||
|
size_t end;
|
||||||
|
char header[32+sizeof(f->filename)];
|
||||||
|
size_t fnamelen = strlen(f->filename);
|
||||||
|
f->zcrc = QC_encodecrc(f->size, f->file);
|
||||||
|
misint (header, 0, 0x04034b50);
|
||||||
|
misshort(header, 4, 0);//minver
|
||||||
|
misshort(header, 6, 0);//general purpose flags
|
||||||
|
misshort(header, 8, 0);//compression method, 0=store, 8=deflate
|
||||||
|
misshort(header, 10, 0);//lastmodfiletime
|
||||||
|
misshort(header, 12, 0);//lastmodfiledate
|
||||||
|
misint (header, 14, f->zcrc);//crc32
|
||||||
|
misint (header, 18, f->size);//compressed size
|
||||||
|
misint (header, 22, f->size);//uncompressed size
|
||||||
|
misshort(header, 26, fnamelen);//filename length
|
||||||
|
misshort(header, 28, 0);//extradata length
|
||||||
|
strcpy(header+30, f->filename);
|
||||||
|
|
||||||
|
f->zhdrofs = SafeSeek(h, 0, SEEK_CUR);
|
||||||
|
SafeWrite(h, header, 30+fnamelen);
|
||||||
|
|
||||||
|
strcpy(idf[num].filename, f->filename);
|
||||||
|
idf[num].size = f->size;
|
||||||
|
idf[num].compmethod = 8; //must be 0(raw) or 8(raw deflate) for zips to work
|
||||||
|
idf[num].ofs = SafeSeek(h, 0, SEEK_CUR);
|
||||||
|
if (idf[num].compmethod==0)
|
||||||
|
SafeWrite(h, f->file, f->size);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
idf[num].compsize = QC_encode(progfuncs, f->size, idf[num].compmethod, f->file, h);
|
||||||
|
|
||||||
|
misshort(header, 8, idf[num].compmethod);//compression method, 0=store, 8=deflate
|
||||||
|
misint (header, 18, idf[num].compsize);
|
||||||
|
|
||||||
|
end = SafeSeek(h, 0, SEEK_CUR);
|
||||||
|
SafeSeek(h, f->zhdrofs, SEEK_SET);
|
||||||
|
SafeWrite(h, header, 30+strlen(f->filename));
|
||||||
|
SafeSeek(h, end, SEEK_SET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (f->type == FT_CODE && !sourceaswell)
|
if (f->type == FT_CODE && !sourceaswell)
|
||||||
continue;
|
continue;
|
||||||
|
@ -721,15 +771,69 @@ int WriteSourceFiles(int h, dprograms_t *progs, pbool sourceaswell)
|
||||||
#endif
|
#endif
|
||||||
idf[num].ofs = SafeSeek(h, 0, SEEK_CUR);
|
idf[num].ofs = SafeSeek(h, 0, SEEK_CUR);
|
||||||
idf[num].compsize = QC_encode(progfuncs, f->size, idf[num].compmethod, f->file, h);
|
idf[num].compsize = QC_encode(progfuncs, f->size, idf[num].compmethod, f->file, h);
|
||||||
|
}
|
||||||
num++;
|
num++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (zipembed)
|
||||||
|
{
|
||||||
|
char centralheader[46+sizeof(f->filename)];
|
||||||
|
int centraldirsize;
|
||||||
|
ofs = SafeSeek(h, 0, SEEK_CUR);
|
||||||
|
for (f = qcc_sourcefile,num=0; f ; f=f->next)
|
||||||
|
{
|
||||||
|
size_t fnamelen;
|
||||||
|
if (f->type == FT_CODE && !sourceaswell)
|
||||||
|
continue;
|
||||||
|
fnamelen = strlen(f->filename);
|
||||||
|
misint (centralheader, 0, 0x02014b50);
|
||||||
|
misshort(centralheader, 4, 0);//ourver
|
||||||
|
misshort(centralheader, 6, 0);//minver
|
||||||
|
misshort(centralheader, 8, 0);//general purpose flags
|
||||||
|
misshort(centralheader, 10, idf[num].compmethod);//compression method, 0=store, 8=deflate
|
||||||
|
misshort(centralheader, 12, 0);//lastmodfiletime
|
||||||
|
misshort(centralheader, 14, 0);//lastmodfiledate
|
||||||
|
misint (centralheader, 16, f->zcrc);//crc32
|
||||||
|
misint (centralheader, 20, idf[num].compsize);//compressed size
|
||||||
|
misint (centralheader, 24, f->size);//uncompressed size
|
||||||
|
misshort(centralheader, 28, fnamelen);//filename length
|
||||||
|
misshort(centralheader, 30, 0);//extradata length
|
||||||
|
misshort(centralheader, 32, 0);//comment length
|
||||||
|
misshort(centralheader, 34, 0);//first disk number
|
||||||
|
misshort(centralheader, 36, 0);//internal file attribs
|
||||||
|
misint (centralheader, 38, 0);//external file attribs
|
||||||
|
misint (centralheader, 42, f->zhdrofs);//local header offset
|
||||||
|
strcpy(centralheader+46, f->filename);
|
||||||
|
SafeWrite(h, centralheader, 46 + fnamelen);
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
centraldirsize = SafeSeek(h, 0, SEEK_CUR)-ofs;
|
||||||
|
misint (centralheader, 0, 0x06054b50);
|
||||||
|
misshort(centralheader, 4, 0); //this disk number
|
||||||
|
misshort(centralheader, 6, 0); //centraldir first disk
|
||||||
|
misshort(centralheader, 8, num); //centraldir entries
|
||||||
|
misshort(centralheader, 10, num); //total centraldir entries
|
||||||
|
misint (centralheader, 12, centraldirsize); //centraldir size
|
||||||
|
misint (centralheader, 16, ofs); //centraldir offset
|
||||||
|
misshort(centralheader, 20, 0); //comment length
|
||||||
|
SafeWrite(h, centralheader, 22);
|
||||||
|
|
||||||
|
ofs = 0;
|
||||||
|
}
|
||||||
|
else if (legacyembed)
|
||||||
|
{
|
||||||
ofs = SafeSeek(h, 0, SEEK_CUR);
|
ofs = SafeSeek(h, 0, SEEK_CUR);
|
||||||
SafeWrite(h, &num, sizeof(int));
|
SafeWrite(h, &num, sizeof(int));
|
||||||
SafeWrite(h, idf, sizeof(includeddatafile_t)*num);
|
SafeWrite(h, idf, sizeof(includeddatafile_t)*num);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ofs = 0;
|
||||||
|
|
||||||
qcc_sourcefile = NULL;
|
qcc_sourcefile = NULL;
|
||||||
|
|
||||||
|
printf("Embedded files take %u bytes\n", SafeSeek(h, 0, SEEK_CUR) - startofs);
|
||||||
|
|
||||||
return ofs;
|
return ofs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -760,6 +864,7 @@ void QCC_InitData (void)
|
||||||
def_ret.symbolheader = &def_ret;
|
def_ret.symbolheader = &def_ret;
|
||||||
for (i=0 ; i<MAX_PARMS ; i++)
|
for (i=0 ; i<MAX_PARMS ; i++)
|
||||||
{
|
{
|
||||||
|
def_parms[i].symbolheader = &def_parms[i];
|
||||||
def_parms[i].temp = NULL;
|
def_parms[i].temp = NULL;
|
||||||
def_parms[i].type = NULL;
|
def_parms[i].type = NULL;
|
||||||
def_parms[i].ofs = OFS_PARM0 + 3*i;
|
def_parms[i].ofs = OFS_PARM0 + 3*i;
|
||||||
|
@ -1044,6 +1149,8 @@ pbool QCC_WriteData (int crc)
|
||||||
|
|
||||||
extern char *basictypenames[];
|
extern char *basictypenames[];
|
||||||
|
|
||||||
|
memset(&progs, 0, sizeof(progs));
|
||||||
|
|
||||||
if (numstatements==1 && numfunctions==1 && numglobaldefs==1 && numfielddefs==1)
|
if (numstatements==1 && numfunctions==1 && numglobaldefs==1 && numfielddefs==1)
|
||||||
{
|
{
|
||||||
printf("nothing to write\n");
|
printf("nothing to write\n");
|
||||||
|
@ -1955,13 +2062,17 @@ strofs = (strofs+3)&~3;
|
||||||
{
|
{
|
||||||
case QCF_QTEST:
|
case QCF_QTEST:
|
||||||
progs.version = PROG_QTESTVERSION;
|
progs.version = PROG_QTESTVERSION;
|
||||||
|
progs.ofsfiles = WriteSourceFiles(h, debugtarget, false);
|
||||||
break;
|
break;
|
||||||
case QCF_KK7:
|
case QCF_KK7:
|
||||||
progs.version = PROG_KKQWSVVERSION;
|
progs.version = PROG_KKQWSVVERSION;
|
||||||
|
progs.ofsfiles = WriteSourceFiles(h, debugtarget, false);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
case QCF_STANDARD:
|
case QCF_STANDARD:
|
||||||
case QCF_HEXEN2: //urgh
|
case QCF_HEXEN2: //urgh
|
||||||
progs.version = PROG_VERSION;
|
progs.version = PROG_VERSION;
|
||||||
|
progs.ofsfiles = WriteSourceFiles(h, debugtarget, false);
|
||||||
break;
|
break;
|
||||||
case QCF_DARKPLACES:
|
case QCF_DARKPLACES:
|
||||||
case QCF_FTE:
|
case QCF_FTE:
|
||||||
|
@ -2017,7 +2128,7 @@ strofs = (strofs+3)&~3;
|
||||||
progs.numtypes = 0;
|
progs.numtypes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
progs.ofsfiles = WriteSourceFiles(h, &progs, debugtarget);
|
progs.ofsfiles = WriteSourceFiles(h, debugtarget, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
pbool QC_decodeMethodSupported(int method);
|
pbool QC_decodeMethodSupported(int method);
|
||||||
char *QC_decode(progfuncs_t *progfuncs, int complen, int len, int method, char *info, char *buffer);
|
char *QC_decode(progfuncs_t *progfuncs, int complen, int len, int method, char *info, char *buffer);
|
||||||
int QC_encode(progfuncs_t *progfuncs, int len, int method, char *in, int handle);
|
int QC_encode(progfuncs_t *progfuncs, int len, int method, char *in, int handle);
|
||||||
|
int QC_encodecrc(int len, char *in);
|
||||||
|
|
||||||
char *PDECL filefromprogs(pubprogfuncs_t *progfuncs, progsnum_t prnum, char *fname, size_t *size, char *buffer);
|
char *PDECL filefromprogs(pubprogfuncs_t *progfuncs, progsnum_t prnum, char *fname, size_t *size, char *buffer);
|
||||||
char *filefromnewprogs(pubprogfuncs_t *progfuncs, char *prname, char *fname, size_t *size, char *buffer);//fixme - remove parm 1
|
char *filefromnewprogs(pubprogfuncs_t *progfuncs, char *prname, char *fname, size_t *size, char *buffer);//fixme - remove parm 1
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#include "progsint.h"
|
#include "progsint.h"
|
||||||
//#include "qcc.h"
|
//#include "qcc.h"
|
||||||
|
|
||||||
//#define AVAIL_ZLIB
|
#ifndef NO_ZLIB
|
||||||
|
#define AVAIL_ZLIB
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef AVAIL_ZLIB
|
#ifdef AVAIL_ZLIB
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -86,6 +88,14 @@ char *QC_decode(progfuncs_t *progfuncs, int complen, int len, int method, char *
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(MINIMAL) && !defined(OMIT_QCC)
|
#if !defined(MINIMAL) && !defined(OMIT_QCC)
|
||||||
|
int QC_encodecrc(int len, char *in)
|
||||||
|
{
|
||||||
|
#ifdef AVAIL_ZLIB
|
||||||
|
return crc32(0, in, len);
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
void SafeWrite(int hand, void *buf, long count);
|
void SafeWrite(int hand, void *buf, long count);
|
||||||
int SafeSeek(int hand, int ofs, int mode);
|
int SafeSeek(int hand, int ofs, int mode);
|
||||||
//we are allowed to trash our input here.
|
//we are allowed to trash our input here.
|
||||||
|
@ -104,7 +114,7 @@ int QC_encode(progfuncs_t *progfuncs, int len, int method, char *in, int handle)
|
||||||
SafeWrite(handle, in, len);
|
SafeWrite(handle, in, len);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
else if (method == 2) //compression (ZLIB)
|
else if (method == 2 || method == 8) //compression (ZLIB)
|
||||||
{
|
{
|
||||||
#ifdef AVAIL_ZLIB
|
#ifdef AVAIL_ZLIB
|
||||||
char out[8192];
|
char out[8192];
|
||||||
|
@ -131,7 +141,10 @@ int QC_encode(progfuncs_t *progfuncs, int len, int method, char *in, int handle)
|
||||||
};
|
};
|
||||||
i=0;
|
i=0;
|
||||||
|
|
||||||
deflateInit(&strm, Z_BEST_COMPRESSION);
|
if (method == 8)
|
||||||
|
deflateInit2(&strm, 9, Z_DEFLATED, -MAX_WBITS, 9, Z_DEFAULT_STRATEGY); //zip deflate compression
|
||||||
|
else
|
||||||
|
deflateInit(&strm, Z_BEST_COMPRESSION); //zlib compression
|
||||||
while(deflate(&strm, Z_FINISH) == Z_OK)
|
while(deflate(&strm, Z_FINISH) == Z_OK)
|
||||||
{
|
{
|
||||||
SafeWrite(handle, out, sizeof(out) - strm.avail_out); //compress in chunks of 8192. Saves having to allocate a huge-mega-big buffer
|
SafeWrite(handle, out, sizeof(out) - strm.avail_out); //compress in chunks of 8192. Saves having to allocate a huge-mega-big buffer
|
||||||
|
|
|
@ -4944,6 +4944,22 @@ static void QCBUILTIN PF_WriteString (pubprogfuncs_t *prinst, struct globalvars_
|
||||||
PF_WriteString_Internal(G_FLOAT(OFS_PARM0), str);
|
PF_WriteString_Internal(G_FLOAT(OFS_PARM0), str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void QCBUILTIN PF_WritePicture (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||||
|
{
|
||||||
|
//name size data
|
||||||
|
//this is basically a stub, so we write a size of 0. the client will have to just deal with it.
|
||||||
|
int target = G_FLOAT(OFS_PARM0);
|
||||||
|
string_t o = G_INT(OFS_PARM1);
|
||||||
|
float sizelimit = G_INT(OFS_PARM2);
|
||||||
|
|
||||||
|
(void)sizelimit; //we don't use this, because we don't bother trying to re-compress the thing here.
|
||||||
|
|
||||||
|
PF_WriteString_Internal(target, PR_GetString(prinst, o));
|
||||||
|
G_FLOAT(OFS_PARM1) = 0;
|
||||||
|
PF_WriteShort(prinst, pr_globals);
|
||||||
|
|
||||||
|
G_INT(OFS_PARM1) = o;
|
||||||
|
}
|
||||||
|
|
||||||
void QCBUILTIN PF_WriteEntity (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
void QCBUILTIN PF_WriteEntity (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||||
{
|
{
|
||||||
|
@ -9783,7 +9799,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
||||||
{"mvdstrcpy", PF_MVDSV_strcpy, 0, 0, 0, 97, D("void(string dst, string src)",NULL), true},
|
{"mvdstrcpy", PF_MVDSV_strcpy, 0, 0, 0, 97, D("void(string dst, string src)",NULL), true},
|
||||||
{"strstr", PF_strstr, 0, 0, 0, 98, D("string(string str, string sub)",NULL), true},
|
{"strstr", PF_strstr, 0, 0, 0, 98, D("string(string str, string sub)",NULL), true},
|
||||||
{"mvdstrncpy", PF_MVDSV_strncpy, 0, 0, 0, 99, D("void(string dst, string src, float count)",NULL), true},
|
{"mvdstrncpy", PF_MVDSV_strncpy, 0, 0, 0, 99, D("void(string dst, string src, float count)",NULL), true},
|
||||||
{"log", PF_logtext, 0, 0, 0, 100, D("void(string name, float console, string text)",NULL), true},
|
{"logtext", PF_logtext, 0, 0, 0, 100, D("void(string name, float console, string text)",NULL), true},
|
||||||
// {"redirectcmd", PF_redirectcmd, 0, 0, 0, 101, D("void(entity to, string str)",NULL), true},
|
// {"redirectcmd", PF_redirectcmd, 0, 0, 0, 101, D("void(entity to, string str)",NULL), true},
|
||||||
{"mvdcalltimeofday",PF_calltimeofday, 0, 0, 0, 102, D("void()",NULL), true},
|
{"mvdcalltimeofday",PF_calltimeofday, 0, 0, 0, 102, D("void()",NULL), true},
|
||||||
{"forcedemoframe", PF_forcedemoframe, 0, 0, 0, 103, D("void(float now)",NULL), true},
|
{"forcedemoframe", PF_forcedemoframe, 0, 0, 0, 103, D("void(float now)",NULL), true},
|
||||||
|
@ -10404,7 +10420,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
||||||
{"precache_vwep_model",PF_precache_vwep_model,0,0, 0, 532, "float(string mname)"},
|
{"precache_vwep_model",PF_precache_vwep_model,0,0, 0, 532, "float(string mname)"},
|
||||||
//end mvdsv extras
|
//end mvdsv extras
|
||||||
//restart dp extras
|
//restart dp extras
|
||||||
// {"log", PF_Logarithm, 0, 0, 0, 532, "float(float v, float base)", true},
|
{"log", PF_Logarithm, 0, 0, 0, 532, D("float(float v, optional float base)", "Determines the logarithm of the input value according to the specified base. This can be used to calculate how much something was shifted by.")},
|
||||||
{"soundupdate", PF_Fixme, 0, 0, 0, 0, D("float(entity e, float channel, string newsample, float volume, float attenuation, float pitchpct, float flags, float timeoffset)", "Changes the properties of the current sound being played on the given entity channel. newsample may be empty, and will be ignored in this case. timeoffset is relative to the current position (subtract the result of getsoundtime for absolute positions). Negative volume can be used to stop the sound. Return value is a fractional value based upon the number of audio devices that could be updated - test against TRUE rather than non-zero.")},
|
{"soundupdate", PF_Fixme, 0, 0, 0, 0, D("float(entity e, float channel, string newsample, float volume, float attenuation, float pitchpct, float flags, float timeoffset)", "Changes the properties of the current sound being played on the given entity channel. newsample may be empty, and will be ignored in this case. timeoffset is relative to the current position (subtract the result of getsoundtime for absolute positions). Negative volume can be used to stop the sound. Return value is a fractional value based upon the number of audio devices that could be updated - test against TRUE rather than non-zero.")},
|
||||||
{"getsoundtime", PF_Ignore, 0, 0, 0, 533, D("float(entity e, float channel)", "Returns the current playback time of the sample on the given entity's channel. Beware CHAN_AUTO (in csqc, channels are not limited by network protocol).")},
|
{"getsoundtime", PF_Ignore, 0, 0, 0, 533, D("float(entity e, float channel)", "Returns the current playback time of the sample on the given entity's channel. Beware CHAN_AUTO (in csqc, channels are not limited by network protocol).")},
|
||||||
{"soundlength", PF_Ignore, 0, 0, 0, 534, D("float(string sample)", "Provides a way to query the duration of a sound sample, allowing you to set up a timer to chain samples.")},
|
{"soundlength", PF_Ignore, 0, 0, 0, 534, D("float(string sample)", "Provides a way to query the duration of a sound sample, allowing you to set up a timer to chain samples.")},
|
||||||
|
@ -10718,7 +10734,7 @@ void PR_ResetBuiltins(progstype_t type) //fix all nulls to PF_FIXME and add any
|
||||||
PR_EnableEBFSBuiltin("mvdstrcpy", 97) != 97 ||
|
PR_EnableEBFSBuiltin("mvdstrcpy", 97) != 97 ||
|
||||||
PR_EnableEBFSBuiltin("strstr", 98) != 98 ||
|
PR_EnableEBFSBuiltin("strstr", 98) != 98 ||
|
||||||
PR_EnableEBFSBuiltin("mvdstrncpy", 99) != 99 ||
|
PR_EnableEBFSBuiltin("mvdstrncpy", 99) != 99 ||
|
||||||
PR_EnableEBFSBuiltin("log", 100)!= 100 ||
|
PR_EnableEBFSBuiltin("logtext", 100)!= 100 ||
|
||||||
// PR_EnableEBFSBuiltin("redirectcmd", 101)!= 101 ||
|
// PR_EnableEBFSBuiltin("redirectcmd", 101)!= 101 ||
|
||||||
PR_EnableEBFSBuiltin("mvdcalltimeofday",102)!= 102 ||
|
PR_EnableEBFSBuiltin("mvdcalltimeofday",102)!= 102 ||
|
||||||
PR_EnableEBFSBuiltin("forcedemoframe", 103)!= 103)
|
PR_EnableEBFSBuiltin("forcedemoframe", 103)!= 103)
|
||||||
|
@ -11407,6 +11423,7 @@ void PR_DumpPlatform_f(void)
|
||||||
{"INFOKEY_P_ISLAGGED", "const string", QW|NQ, "1 if the player has the fakelag penalty and has an extra 200ms of lag.", 0, "\"*ismuted\""},
|
{"INFOKEY_P_ISLAGGED", "const string", QW|NQ, "1 if the player has the fakelag penalty and has an extra 200ms of lag.", 0, "\"*ismuted\""},
|
||||||
{"INFOKEY_P_PING", "const string", CS|QW|NQ, "The player's ping time, in milliseconds.", 0, "\"ping\""},
|
{"INFOKEY_P_PING", "const string", CS|QW|NQ, "The player's ping time, in milliseconds.", 0, "\"ping\""},
|
||||||
{"INFOKEY_P_NAME", "const string", CS|QW|NQ, "The player's name.", 0, "\"name\""},
|
{"INFOKEY_P_NAME", "const string", CS|QW|NQ, "The player's name.", 0, "\"name\""},
|
||||||
|
{"INFOKEY_P_SPECTATOR", "const string", CS|QW|NQ, "Whether the player is a spectator or not.", 0, "\"*spectator\""},
|
||||||
{"INFOKEY_P_TOPCOLOR", "const string", CS|QW|NQ, "The player's upper/shirt colour (palette index).", 0, "\"topcolor\""},
|
{"INFOKEY_P_TOPCOLOR", "const string", CS|QW|NQ, "The player's upper/shirt colour (palette index).", 0, "\"topcolor\""},
|
||||||
{"INFOKEY_P_BOTTOMCOLOR","const string", CS|QW|NQ, "The player's lower/pants/trouser colour (palette index).", 0, "\"bottomcolor\""},
|
{"INFOKEY_P_BOTTOMCOLOR","const string", CS|QW|NQ, "The player's lower/pants/trouser colour (palette index).", 0, "\"bottomcolor\""},
|
||||||
{"INFOKEY_P_TOPCOLOR_RGB","const string", CS, "The player's upper/shirt colour as an rgb value in a format usable with stov.", 0, "\"topcolor_rgb\""},
|
{"INFOKEY_P_TOPCOLOR_RGB","const string", CS, "The player's upper/shirt colour as an rgb value in a format usable with stov.", 0, "\"topcolor_rgb\""},
|
||||||
|
|
|
@ -3872,7 +3872,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
host_client = client;
|
host_client = client;
|
||||||
if (client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
|
if ((client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) || !frame->entities.entities)
|
||||||
{
|
{
|
||||||
pack = &svs.entstatebuffer;
|
pack = &svs.entstatebuffer;
|
||||||
if (pack->max_entities < client->max_net_ents)
|
if (pack->max_entities < client->max_net_ents)
|
||||||
|
|
|
@ -1688,6 +1688,7 @@ void SV_AcceptMessage(client_t *newcl)
|
||||||
{
|
{
|
||||||
MSG_WriteByte(&sb, 1/*MOD_PROQUAKE*/);
|
MSG_WriteByte(&sb, 1/*MOD_PROQUAKE*/);
|
||||||
MSG_WriteByte(&sb, 10 * 3.50/*MOD_PROQUAKE_VERSION*/);
|
MSG_WriteByte(&sb, 10 * 3.50/*MOD_PROQUAKE_VERSION*/);
|
||||||
|
MSG_WriteByte(&sb, 0/*flags*/);
|
||||||
}
|
}
|
||||||
*(int*)sb.data = BigLong(NETFLAG_CTL|sb.cursize);
|
*(int*)sb.data = BigLong(NETFLAG_CTL|sb.cursize);
|
||||||
NET_SendPacket(NS_SERVER, sb.cursize, sb.data, &net_from);
|
NET_SendPacket(NS_SERVER, sb.cursize, sb.data, &net_from);
|
||||||
|
@ -1796,7 +1797,7 @@ void SV_ClientProtocolExtensionsChanged(client_t *client)
|
||||||
client->max_net_clients = NQMAX_CLIENTS;
|
client->max_net_clients = NQMAX_CLIENTS;
|
||||||
client->max_net_ents = bound(512, pr_maxedicts.ival, 32768); //fitzquake supports 65535, but our writeentity builtin works differently, which causes problems.
|
client->max_net_ents = bound(512, pr_maxedicts.ival, 32768); //fitzquake supports 65535, but our writeentity builtin works differently, which causes problems.
|
||||||
client->maxmodels = MAX_PRECACHE_MODELS;
|
client->maxmodels = MAX_PRECACHE_MODELS;
|
||||||
maxpacketentities = 65535;
|
maxpacketentities = client->max_net_ents;
|
||||||
|
|
||||||
client->datagram.maxsize = sizeof(host_client->datagram_buf);
|
client->datagram.maxsize = sizeof(host_client->datagram_buf);
|
||||||
}
|
}
|
||||||
|
@ -1873,6 +1874,16 @@ void SV_ClientProtocolExtensionsChanged(client_t *client)
|
||||||
//make sure the reset is sent.
|
//make sure the reset is sent.
|
||||||
client->pendingdeltabits[0] = UF_REMOVE;
|
client->pendingdeltabits[0] = UF_REMOVE;
|
||||||
}
|
}
|
||||||
|
else if (ISNQCLIENT(client))
|
||||||
|
{
|
||||||
|
client->frameunion.frames = Z_Malloc((sizeof(client_frame_t))*UPDATE_BACKUP);
|
||||||
|
for (i = 0; i < UPDATE_BACKUP; i++)
|
||||||
|
{
|
||||||
|
client->frameunion.frames[i].entities.max_entities = 0;
|
||||||
|
client->frameunion.frames[i].entities.entities = NULL;
|
||||||
|
client->frameunion.frames[i].senttime = realtime;
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
client->frameunion.frames = Z_Malloc((sizeof(client_frame_t)+sizeof(entity_state_t)*maxpacketentities)*UPDATE_BACKUP);
|
client->frameunion.frames = Z_Malloc((sizeof(client_frame_t)+sizeof(entity_state_t)*maxpacketentities)*UPDATE_BACKUP);
|
||||||
|
|
|
@ -7391,7 +7391,7 @@ void SV_ExecuteClientMessage (client_t *cl)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if (!sv.paused)
|
if (!sv.paused && sv.world.worldmodel && sv.world.worldmodel->loadstate == MLS_LOADED)
|
||||||
{
|
{
|
||||||
if (sv_nqplayerphysics.ival || split->state < cs_spawned)
|
if (sv_nqplayerphysics.ival || split->state < cs_spawned)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue