From bfea433dff616a2b526f93cf803b991ad722a711 Mon Sep 17 00:00:00 2001 From: Spoike Date: Thu, 9 Jan 2020 15:35:40 +0000 Subject: [PATCH] Attempt to fix some nondeterministic build variations. fix GPD_LIMIT_PITCH not properly limiting +lookdown. fix plugins not auto-loading properly (when previously enabled, obviously). engine updates now try to replace the 'launcher' binary, instead of chaining from it. this should make firewalls (and other shady special-case gldriver hacks) more consistent at the cost of not being able to revert to your initial revision. imgtool can now extract from wads. imgtool now compiles+works on windows (GoaLitiuM's code). update ffmpeg plugin to handle more recent ffmpeg versions properly. fix somewhat recent audio streaming bug with openal output. fix sleep+abort qc builtins. gltf2 plugin will now work better with blenders no-material files. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5598 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/Makefile | 41 ++++---- engine/client/cl_input.c | 20 ++-- engine/client/cl_main.c | 11 ++- engine/client/client.h | 2 +- engine/client/image.c | 29 +++++- engine/client/m_download.c | 163 ++++++++++++++++++++++---------- engine/client/m_mp3.c | 42 ++++++-- engine/client/m_options.c | 13 ++- engine/client/pr_csqc.c | 5 +- engine/client/render.h | 2 +- engine/client/snd_dma.c | 43 +++++++-- engine/client/sys_win.c | 76 +++++++++++++-- engine/client/textedit.c | 8 +- engine/common/com_mesh.c | 2 +- engine/common/common.c | 2 +- engine/common/fs_pak.c | 4 +- engine/common/net_ssl_gnutls.c | 1 + engine/common/pr_bgcmd.c | 10 +- engine/common/sys.h | 12 +-- engine/common/sys_win_threads.c | 6 +- engine/common/zone.c | 4 +- engine/common/zone.h | 2 +- engine/gl/gl_heightmap.c | 7 +- engine/gl/gl_model.c | 6 +- engine/gl/gl_vidcommon.c | 14 ++- engine/gl/gl_vidlinuxglx.c | 6 +- engine/qclib/execloop.h | 105 ++++++++++---------- engine/qclib/pr_edict.c | 6 +- engine/qclib/pr_exec.c | 90 ++++++++++-------- engine/qclib/progsint.h | 2 - engine/qclib/progslib.h | 3 +- engine/server/pr_cmds.c | 17 +++- engine/server/sv_ents.c | 7 +- 33 files changed, 506 insertions(+), 255 deletions(-) diff --git a/engine/Makefile b/engine/Makefile index 9c6234a44..2eed1e469 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -579,13 +579,6 @@ ifeq (win,$(findstring cyg,$(FTE_TARGET))$(findstring win,$(FTE_TARGET))) # OGGVORBISLDFLAGS=$(MINGW_LIBS_DIR)/libvorbisfile.a $(MINGW_LIBS_DIR)/libvorbis.a $(MINGW_LIBS_DIR)/libogg.a endif -#try to statically link -ifeq ($(COMPILE_SYS),Darwin) - ifneq (,$(findstring SDL,$(FTE_TARGET))) - IMAGELDFLAGS = $(shell pkg-config libpng --variable=libdir)/libpng.a $(shell pkg-config libjpeg --variable=libdir)/libjpeg.a - OGGVORBISLDFLAGS = $(shell pkg-config vorbisfile --variable=libdir)/libvorbisfile.a $(shell pkg-config vorbis --variable=libdir)/libvorbis.a $(shell pkg-config ogg --variable=libdir)/libogg.a - endif -endif OGGVORBISLDFLAGS ?= -lvorbisfile -lvorbis -logg VISIBILITY_FLAGS?= @@ -642,6 +635,18 @@ ifeq ($(shell LANG=c $(CC) -rdynamic 2>&1 | grep unrecognized),) DEBUG_CFLAGS+= -rdynamic endif +PKGCONFIG=$(ARCH)-pkg-config +ifeq ($(shell which $(PKGCONFIG) 2> /dev/null),) + PKGCONFIG=/bin/true #don't end up using eg /usr/include when cross-compiling. makelibs is a valid workaround. +endif +#try to statically link +ifeq ($(COMPILE_SYS),Darwin) + ifneq (,$(findstring SDL,$(FTE_TARGET))) + IMAGELDFLAGS := $(shell $(PKGCONFIG) libpng --variable=libdir)/libpng.a $(shell $(PKGCONFIG) libjpeg --variable=libdir)/libjpeg.a + OGGVORBISLDFLAGS := $(shell $(PKGCONFIG) vorbisfile --variable=libdir)/libvorbisfile.a $(shell $(PKGCONFIG) vorbis --variable=libdir)/libvorbis.a $(shell $(PKGCONFIG) ogg --variable=libdir)/libogg.a + endif +endif + PROFILE_CFLAGS=-pg DX7SDK=-I./libs/dxsdk7/include/ @@ -935,6 +940,8 @@ ifeq (1,$(LINK_FREETYPE)) CLIENTLIBFLAGS+=-DFREETYPE_STATIC CLIENTLDDEPS+=-lfreetype endif +FREETYPE_CFLAGS:=$(shell $(PKGCONFIG) freetype --cflags --silence-errors) +ALL_CFLAGS+=$(FREETYPE_CFLAGS) ifeq (1,$(LINK_PNG)) CLIENTLIBFLAGS+=-DLIBPNG_STATIC CLIENTLDDEPS+=-lpng @@ -2264,13 +2271,13 @@ libs-$(ARCH)/libjpeg.a: test -f jpegsrc.v$(JPEGVER).tar.gz || wget http://www.ijg.org/files/jpegsrc.v$(JPEGVER).tar.gz -test -f libs-$(ARCH)/libjpeg.a || (mkdir -p libs-$(ARCH) && cd libs-$(ARCH) && tar -xvzf ../jpegsrc.v$(JPEGVER).tar.gz && cd jpeg-$(JPEGVER) && $(TOOLOVERRIDES) ./configure $(CONFIGARGS) && $(TOOLOVERRIDES) $(MAKE) && cp .libs/libjpeg.a ../ && $(TOOLOVERRIDES) $(AR) -s ../libjpeg.a && cp jconfig.h jerror.h jmorecfg.h jpeglib.h jversion.h ../ ) -libs-$(ARCH)/libz.a: +libs-$(ARCH)/libz.a libs-$(ARCH)/libz.pc: test -f zlib-$(ZLIBVER).tar.gz || wget http://zlib.net/zlib-$(ZLIBVER).tar.gz - -test -f libs-$(ARCH)/libz.a || (mkdir -p libs-$(ARCH) && cd libs-$(ARCH) && tar -xvzf ../zlib-$(ZLIBVER).tar.gz && cd zlib-$(ZLIBVER) && $(TOOLOVERRIDES) ./configure --static && $(TOOLOVERRIDES) $(MAKE) libz.a CC="$(CC) $(W32_CFLAGS) -fPIC" && cp libz.a ../ && $(TOOLOVERRIDES) $(AR) -s ../libz.a && cp zlib.h zconf.h zutil.h ../ ) + -test -f libs-$(ARCH)/libz.a || (mkdir -p libs-$(ARCH) && cd libs-$(ARCH) && tar -xvzf ../zlib-$(ZLIBVER).tar.gz && cd zlib-$(ZLIBVER) && $(TOOLOVERRIDES) ./configure --static && $(TOOLOVERRIDES) $(MAKE) libz.a CC="$(CC) $(W32_CFLAGS) -fPIC" && cp libz.a ../ && $(TOOLOVERRIDES) $(AR) -s ../libz.a && cp zlib.h zconf.h zutil.h zlib.pc ../ ) -libs-$(ARCH)/libpng.a: libs-$(ARCH)/libz.a +libs-$(ARCH)/libpng.a libs-$(ARCH)/libpng.pc: libs-$(ARCH)/libz.a libs-$(ARCH)/libz.pc test -f libpng-$(PNGVER).tar.gz || wget http://prdownloads.sourceforge.net/libpng/libpng-$(PNGVER).tar.gz?download -O libpng-$(PNGVER).tar.gz - -test -f libs-$(ARCH)/libpng.a || (mkdir -p libs-$(ARCH) && cd libs-$(ARCH) && tar -xvzf ../libpng-$(PNGVER).tar.gz && cd libpng-$(PNGVER) && $(TOOLOVERRIDES) ./configure CPPFLAGS=-I$(NATIVE_ABSBASE_DIR)/libs-$(ARCH)/ LDFLAGS=-L$(NATIVE_ABSBASE_DIR)/libs-$(ARCH)/ $(CONFIGARGS) --enable-static && $(TOOLOVERRIDES) $(MAKE) && cp .libs/libpng16.a ../libpng.a && cp png*.h ../ ) + -test -f libs-$(ARCH)/libpng.a || (mkdir -p libs-$(ARCH) && cd libs-$(ARCH) && tar -xvzf ../libpng-$(PNGVER).tar.gz && cd libpng-$(PNGVER) && $(TOOLOVERRIDES) ./configure CPPFLAGS=-I$(NATIVE_ABSBASE_DIR)/libs-$(ARCH)/ LDFLAGS=-L$(NATIVE_ABSBASE_DIR)/libs-$(ARCH)/ $(CONFIGARGS) --enable-static && $(TOOLOVERRIDES) $(MAKE) && cp .libs/libpng16.a ../libpng.a && cp libpng.pc png*.h ../ ) libs-$(ARCH)/libogg.a: test -f libogg-$(OGGVER).tar.gz || wget http://downloads.xiph.org/releases/ogg/libogg-$(OGGVER).tar.gz @@ -2292,9 +2299,9 @@ libs-$(ARCH)/libspeexdsp.a: test -f speexdsp-$(SPEEXDSPVER).tar.gz || wget http://downloads.xiph.org/releases/speex/speexdsp-$(SPEEXDSPVER).tar.gz -test -f libs-$(ARCH)/libspeexdsp.a || (mkdir -p libs-$(ARCH)/speex && cd libs-$(ARCH) && tar -xvzf ../speexdsp-$(SPEEXDSPVER).tar.gz && cd speexdsp-$(SPEEXDSPVER) && CFLAGS="$(CFLAGS) -Os" $(TOOLOVERRIDES) ./configure $(CONFIGARGS) && $(TOOLOVERRIDES) $(MAKE) && cp libspeexdsp/.libs/libspeexdsp.a ../ && cp -r include/speex/*.h ../speex/) -libs-$(ARCH)/libfreetype.a libs-$(ARCH)/ft2build.h: libs-$(ARCH)/libpng.a +libs-$(ARCH)/libfreetype.a libs-$(ARCH)/ft2build.h: libs-$(ARCH)/libpng.a libs-$(ARCH)/libpng.pc test -f freetype-$(FREETYPEVER).tar.gz || wget https://download.savannah.gnu.org/releases/freetype/freetype-$(FREETYPEVER).tar.gz - -test -f libs-$(ARCH)/libfreetype.a || (mkdir -p libs-$(ARCH) && cd libs-$(ARCH) && tar -xvzf ../freetype-$(FREETYPEVER).tar.gz && cd freetype-$(FREETYPEVER) && CFLAGS="$(CFLAGS) -Os" $(TOOLOVERRIDES) ./configure CPPFLAGS=-I$(NATIVE_ABSBASE_DIR)/libs-$(ARCH)/ LDFLAGS=-L$(NATIVE_ABSBASE_DIR)/libs-$(ARCH)/ $(CONFIGARGS) --with-bzip2=no --with-harfbuzz=no && $(TOOLOVERRIDES) $(MAKE) && cp objs/.libs/libfreetype.a ../ && cp -r include/* ../) + -test -f libs-$(ARCH)/libfreetype.a || (mkdir -p libs-$(ARCH) && cd libs-$(ARCH) && tar -xvzf ../freetype-$(FREETYPEVER).tar.gz && cd freetype-$(FREETYPEVER) && PKG_CONFIG_LIBDIR=$(NATIVE_ABSBASE_DIR)/libs-$(ARCH) CFLAGS="$(CFLAGS) -Os" $(TOOLOVERRIDES) ./configure CPPFLAGS=-I$(NATIVE_ABSBASE_DIR)/libs-$(ARCH)/ LDFLAGS=-L$(NATIVE_ABSBASE_DIR)/libs-$(ARCH)/ $(CONFIGARGS) --with-zlib=yes --with-png=yes --with-bzip2=no --with-harfbuzz=no && $(TOOLOVERRIDES) $(MAKE) && cp objs/.libs/libfreetype.a ../ && cp -r include/* ../) libs-$(ARCH)/libBulletDynamics.a: test -f bullet3-$(BULLETVER).tar.gz || wget https://github.com/bulletphysics/bullet3/archive/$(BULLETVER).tar.gz -O bullet3-$(BULLETVER).tar.gz @@ -2309,13 +2316,15 @@ httpserver: $(RELEASE_DIR)/httpserver$(BITS)$(EXEPOSTFIX) IQM_OBJECTS=../iqm/iqm.cpp $(RELEASE_DIR)/iqm$(BITS)$(EXEPOSTFIX): $(IQM_OBJECTS) - $(CC) -o $@ $(IQM_OBJECTS) -lstdc++ -lm -Os + $(CC) -o $@ $(IQM_OBJECTS) -static -lstdc++ -lm -Os iqm-rel: $(RELEASE_DIR)/iqm$(BITS)$(EXEPOSTFIX) iqm: iqm-rel +iqmtool: iqm-rel IMGTOOL_OBJECTS=../imgtool.c client/image.c -$(RELEASE_DIR)/imgtool$(BITS)$(EXEPOSTFIX): $(IQM_OBJECTS) - $(CC) -o $@ $(IMGTOOL_OBJECTS) -lstdc++ -lm -Os $(ALL_CFLAGS) -DIMGTOOL $(BASELDFLAGS) +$(RELEASE_DIR)/imgtool$(BITS)$(EXEPOSTFIX): $(IMGTOOL_OBJECTS) + $(CC) -o $@ $(IMGTOOL_OBJECTS) -lstdc++ -lm -Os $(ALL_CFLAGS) $(CLIENTLIBFLAGS) -DIMGTOOL $(BASELDFLAGS) $(CLIENTLDDEPS) + imgtool-rel: $(RELEASE_DIR)/imgtool$(BITS)$(EXEPOSTFIX) imgtool: imgtool-rel diff --git a/engine/client/cl_input.c b/engine/client/cl_input.c index 259e706d2..e43344e97 100644 --- a/engine/client/cl_input.c +++ b/engine/client/cl_input.c @@ -860,9 +860,9 @@ void CL_AdjustAngles (int pnum, double frametime) if (in_speed.state[pnum] & 1) { if (ruleset_allow_frj.ival) - speed = frametime * cl_anglespeedkey.ival; + speed = frametime * cl_anglespeedkey.value; else - speed = frametime * bound(-2, cl_anglespeedkey.ival, 2); + speed = frametime * bound(-2, cl_anglespeedkey.value, 2); } else speed = frametime; @@ -879,8 +879,8 @@ void CL_AdjustAngles (int pnum, double frametime) if (!(in_strafe.state[pnum] & 1)) { - quant = cl_yawspeed.ival; - if (cl.fpd & FPD_LIMIT_YAW || !ruleset_allow_frj.ival) + quant = cl_yawspeed.value; + if ((cl.fpd & FPD_LIMIT_YAW) || !ruleset_allow_frj.ival) quant = bound(-900, quant, 900); cl.playerview[pnum].viewanglechange[YAW] -= speed*quant * CL_KeyState (&in_right, pnum, false); cl.playerview[pnum].viewanglechange[YAW] += speed*quant * CL_KeyState (&in_left, pnum, false); @@ -888,23 +888,23 @@ void CL_AdjustAngles (int pnum, double frametime) if (in_klook.state[pnum] & 1) { V_StopPitchDrift (&cl.playerview[pnum]); - quant = cl_pitchspeed.ival; - if (cl.fpd & FPD_LIMIT_PITCH || !ruleset_allow_frj.ival) + quant = cl_pitchspeed.value; + if ((cl.fpd & FPD_LIMIT_PITCH) || !ruleset_allow_frj.ival) quant = bound(-700, quant, 700); cl.playerview[pnum].viewanglechange[PITCH] -= speed*quant * CL_KeyState (&in_forward, pnum, false); cl.playerview[pnum].viewanglechange[PITCH] += speed*quant * CL_KeyState (&in_back, pnum, false); } - quant = cl_rollspeed.ival; + quant = cl_rollspeed.value; cl.playerview[pnum].viewanglechange[ROLL] -= speed*quant * CL_KeyState (&in_rollleft, pnum, false); cl.playerview[pnum].viewanglechange[ROLL] += speed*quant * CL_KeyState (&in_rollright, pnum, false); up = CL_KeyState (&in_lookup, pnum, false); down = CL_KeyState(&in_lookdown, pnum, false); - quant = cl_pitchspeed.ival; - if (!ruleset_allow_frj.ival) - quant = bound(-700, quant, 700); + quant = cl_pitchspeed.value; + if ((cl.fpd & FPD_LIMIT_PITCH) || !ruleset_allow_frj.ival) + quant = bound(-700, quant, 700); cl.playerview[pnum].viewanglechange[PITCH] -= speed*cl_pitchspeed.ival * up; cl.playerview[pnum].viewanglechange[PITCH] += speed*cl_pitchspeed.ival * down; diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 25aaa5e15..01343a6c5 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -6522,6 +6522,8 @@ void Host_FinishLoading(void) return; } + Plug_Initialise(true); + Con_History_Load(); Cmd_StuffCmds(); @@ -6588,9 +6590,9 @@ Host_Init */ void Host_Init (quakeparms_t *parms) { -#ifdef PACKAGEMANAGER +/*#ifdef PACKAGEMANAGER char engineupdated[MAX_OSPATH]; -#endif +#endif*/ int man; com_parseutf8.ival = 1; //enable utf8 parsing even before cvars are registered. @@ -6616,6 +6618,7 @@ void Host_Init (quakeparms_t *parms) Cmd_Init (); COM_Init (); +/*this may be tripping some bullshit huristic in microsoft's insecurity mafia software(tbh I really don't know what they're detecting), plus causes firewall issues on updates. #ifdef PACKAGEMANAGER //we have enough of the filesystem inited now that we can read the package list and figure out which engine was last installed. if (PM_FindUpdatedEngine(engineupdated, sizeof(engineupdated))) @@ -6635,6 +6638,7 @@ void Host_Init (quakeparms_t *parms) PM_Shutdown(); //will restart later as needed, but we need to be sure that no files are open or anything. } #endif +*/ V_Init (); NET_Init (); @@ -6676,9 +6680,6 @@ void Host_Init (quakeparms_t *parms) Editor_Init(); #endif -#ifdef PLUGINS - Plug_Initialise(true); -#endif #ifdef VM_UI UI_Init(); #endif diff --git a/engine/client/client.h b/engine/client/client.h index 64dac4115..d351d702f 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -1793,7 +1793,7 @@ typedef struct size_t structsize; const char *drivername; const char *description; - const char *defaultextension; + const char *extensions; void *(VARGS *capture_begin) (char *streamname, int videorate, int width, int height, int *sndkhz, int *sndchannels, int *sndbits); void (VARGS *capture_video) (void *ctx, int frame, void *data, int stride, int width, int height, enum uploadfmt fmt); void (VARGS *capture_audio) (void *ctx, void *data, int bytes); diff --git a/engine/client/image.c b/engine/client/image.c index caf3c5e8c..0f1d6661e 100644 --- a/engine/client/image.c +++ b/engine/client/image.c @@ -1833,7 +1833,7 @@ err: qpng_set_bgr(png_ptr); qpng_set_IHDR(png_ptr, info_ptr, outwidth, height, chanbits, colourtype, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); -#ifdef PNG_TEXT_SUPPORTED +#if defined(PNG_TEXT_SUPPORTED) && defined(PNG_ITXT_COMPRESSION_NONE) if (writemetadata) { char blob[8192]; @@ -7838,6 +7838,32 @@ static void Image_Tr_NoTransform(struct pendingtextureinfo *mips, int dummy) { } +static void Image_Tr_PalettedtoRGBX8(struct pendingtextureinfo *mips, int dummy) +{ + unsigned int mip; + for (mip = 0; mip < mips->mipcount; mip++) + { + qbyte *in = mips->mip[mip].data; + unsigned int p = mips->mip[mip].width*mips->mip[mip].height*mips->mip[mip].depth; + qbyte *out = BZ_Malloc(sizeof(*out)*4*p); + void *newdata = out; + + while(p-->0) + { + unsigned int l = *in++; + *out++ = host_basepal[l*3+0]; + *out++ = host_basepal[l*3+1]; + *out++ = host_basepal[l*3+2]; + *out++ = (l==255)?255:0; + } + if (mips->mip[mip].needfree) + BZ_Free(mips->mip[mip].data); + mips->mip[mip].needfree = true; + mips->mip[mip].data = newdata; + mips->mip[mip].datasize = sizeof(*out)*4*p; + } +} + //may operate in place static void Image_Tr_RGBX8toPaletted(struct pendingtextureinfo *mips, int dummy) { @@ -10941,6 +10967,7 @@ static struct {PTI_RG8, PTI_RGBX8, Image_Tr_RG8ToRGXX8}, {PTI_RGBX8, PTI_P8, Image_Tr_RGBX8toPaletted}, + {PTI_P8, PTI_RGBX8, Image_Tr_PalettedtoRGBX8}, }; void Image_ChangeFormat(struct pendingtextureinfo *mips, qboolean *allowedformats, uploadfmt_t origfmt, const char *imagename) { diff --git a/engine/client/m_download.c b/engine/client/m_download.c index 07eda6897..e7f56f3bc 100644 --- a/engine/client/m_download.c +++ b/engine/client/m_download.c @@ -191,6 +191,7 @@ static struct static int downloadablessequence; //bumped any time any package is purged static void PM_WriteInstalledPackages(void); +static void PM_PreparePackageList(void); static void PM_FreePackage(package_t *p) { @@ -651,9 +652,10 @@ static void PM_RemSubList(const char *url) } #endif -static qboolean PM_ParsePackageList(vfsfile_t *f, int parseflags, const char *url, const char *prefix) +static qboolean PM_ParsePackageList(const char *f, int parseflags, const char *url, const char *prefix) { char line[65536]; + size_t l; package_t *p; struct packagedep_s *dep; char *sl; @@ -681,14 +683,25 @@ static qboolean PM_ParsePackageList(vfsfile_t *f, int parseflags, const char *ur do { - if (!VFS_GETS(f, line, sizeof(line)-1)) - break; - while((sl=strchr(line, '\n'))) - *sl = '\0'; - while((sl=strchr(line, '\r'))) - *sl = '\0'; + for (l = 0;*f;) + { + if (*f == '\r' || *f == '\n') + { + if (f[0] == '\r' && f[1] == '\n') + f++; + f++; + break; + } + if (l < sizeof(line)-1) + line[l++] = *f; + else + line[0] = 0; + f++; + } + line[l] = 0; + Cmd_TokenizeString (line, false, false); - } while (!Cmd_Argc()); + } while (!Cmd_Argc() && *f); if (strcmp(Cmd_Argv(0), "version")) return forcewrite; //it's not the right format. @@ -700,14 +713,24 @@ static qboolean PM_ParsePackageList(vfsfile_t *f, int parseflags, const char *ur return forcewrite; //it's not the right version. } - while(1) + while(*f) { - if (!VFS_GETS(f, line, sizeof(line)-1)) - break; - while((sl=strchr(line, '\n'))) - *sl = '\0'; - while((sl=strchr(line, '\r'))) - *sl = '\0'; + for (l = 0;*f;) + { + if (*f == '\r' || *f == '\n') + { + if (f[0] == '\r' && f[1] == '\n') + f++; + f++; + break; + } + if (l < sizeof(line)-1) + line[l++] = *f; + else + line[0] = 0; + f++; + } + line[l] = 0; tokstart = COM_StringParse (line, com_token, sizeof(com_token), false, false); if (*com_token) @@ -1038,7 +1061,7 @@ static qboolean PM_ParsePackageList(vfsfile_t *f, int parseflags, const char *ur { if (!Q_strcasecmp(p->arch, THISENGINE)) { - if (!Sys_EngineCanUpdate()) + if (!Sys_EngineMayUpdate()) p->flags |= DPF_HIDDEN; else p->flags |= DPF_ENGINE; @@ -1084,6 +1107,9 @@ void PM_EnumeratePlugins(void (*callback)(const char *name)) { package_t *p; struct packagedep_s *d; + + PM_PreparePackageList(); + for (p = availablepackages; p; p = p->next) { if ((p->flags & DPF_ENABLED) && (p->flags & DPF_PLUGIN)) @@ -1213,13 +1239,14 @@ static void PM_PreparePackageList(void) //figure out what we've previously installed. if (!loadedinstalled) { - vfsfile_t *f = FS_OpenVFS(INSTALLEDFILES, "rb", FS_ROOT); + size_t sz = 0; + char *f = FS_MallocFile(INSTALLEDFILES, FS_ROOT, &sz); loadedinstalled = true; if (f) { if (PM_ParsePackageList(f, DPF_FORGETONUNINSTALL|DPF_ENABLED, NULL, "")) PM_WriteInstalledPackages(); - VFS_CLOSE(f); + BZ_Free(f); } #ifdef PLUGINS @@ -1490,6 +1517,8 @@ static void PM_MarkPackage(package_t *package, unsigned int markflag) o->flags &= ~DPF_MARKED; replacing = true; } + else if (o->flags & DPF_ENGINE) + PM_UnmarkPackage(o, DPF_MARKED); //engine updates are mutually exclusive, unmark the existing one (you might have old ones cached, but they shouldn't be enabled). else { //two packages with the same filename are always mutually incompatible, but with totally separate dependancies etc. qboolean remove = false; @@ -1733,35 +1762,55 @@ static void PM_PrintChanges(void) #ifdef WEBCLIENT static void PM_ListDownloaded(struct dl_download *dl) { - int i; - vfsfile_t *f; - f = dl->file; - dl->file = NULL; + size_t listidx = dl->user_num; + size_t sz = 0; + char *f = NULL; + if (dl->file) + { + sz = VFS_GETLEN(dl->file); + f = BZ_Malloc(sz+1); + if (f) + { + f[sz] = 0; + if (sz != VFS_READ(dl->file, f, sz)) + { //err... weird... + BZ_Free(f); + f = NULL; + } + if (strlen(f) != sz) + { //don't allow mid-file nulls. + BZ_Free(f); + f = NULL; + } + } + } - i = dl->user_num; - - if (dl != downloadablelist[i].curdl) + if (dl != downloadablelist[listidx].curdl) { //this request looks stale. - VFS_CLOSE(f); + BZ_Free(f); return; } - downloadablelist[i].curdl = NULL; + downloadablelist[listidx].curdl = NULL; + + //FIXME: validate a signature! if (f) { - downloadablelist[i].received = 1; - PM_ParsePackageList(f, 0, dl->url, downloadablelist[i].prefix); - VFS_CLOSE(f); + downloadablelist[listidx].received = 1; + PM_ParsePackageList(f, 0, dl->url, downloadablelist[listidx].prefix); + BZ_Free(f); } else - downloadablelist[i].received = -1; + downloadablelist[listidx].received = -1; if (!doautoupdate && !domanifestinstall) return; //don't spam this. - for (i = 0; i < numdownloadablelists; i++) + + //check if we're still waiting + for (listidx = 0; listidx < numdownloadablelists; listidx++) { - if (!downloadablelist[i].received) + if (!downloadablelist[listidx].received) break; } /* @@ -1798,7 +1847,9 @@ static void PM_ListDownloaded(struct dl_download *dl) } } */ - if ((doautoupdate || domanifestinstall == MANIFEST_SECURITY_DEFAULT) && i == numdownloadablelists) + + //if our downloads finished and we want to shove it in the user's face then do so now. + if ((doautoupdate || domanifestinstall == MANIFEST_SECURITY_DEFAULT) && listidx == numdownloadablelists) { if (PM_MarkUpdates()) { @@ -1937,8 +1988,8 @@ static void PM_WriteInstalledPackages(void) char buf[65536]; int i; char *s; - package_t *p, *e = NULL; - struct packagedep_s *dep, *ef = NULL; + package_t *p; + struct packagedep_s *dep; vfsfile_t *f = FS_OpenVFS(INSTALLEDFILES, "wb", FS_ROOT); if (!f) { @@ -2048,11 +2099,6 @@ static void PM_WriteInstalledPackages(void) { Q_strncatz(buf, " ", sizeof(buf)); COM_QuotedConcat(va("file=%s", dep->name), buf, sizeof(buf)); - if ((p->flags & DPF_ENABLED) && (p->flags & DPF_ENGINE) && (!e || strcmp(e->version, p->version) < 0)) - { - e = p; - ef = dep; - } } else if (dep->dtype == DEP_REQUIRE) { @@ -2100,13 +2146,6 @@ static void PM_WriteInstalledPackages(void) } VFS_CLOSE(f); - - if (ef) - { - char native[MAX_OSPATH]; - FS_NativePath(ef->name, e->fsroot, native, sizeof(native)); - Sys_SetUpdatedBinary(native); - } } //package has been downloaded and installed, but some packages need to be enabled @@ -2115,6 +2154,9 @@ static void PM_PackageEnabled(package_t *p) { char ext[8]; struct packagedep_s *dep; +#ifdef HAVEAUTOUPDATE + struct packagedep_s *ef = NULL; +#endif FS_FlushFSHashFull(); for (dep = p->deps; dep; dep = dep->next) { @@ -2130,8 +2172,33 @@ static void PM_PackageEnabled(package_t *p) #ifdef MENU_DAT if (!Q_strcasecmp(dep->name, "menu.dat")) Cmd_ExecuteString("menu_restart\n", RESTRICT_LOCAL); +#endif +#ifdef HAVEAUTOUPDATE + if (p->flags & DPF_ENGINE) + ef = dep; #endif } + +#ifdef HAVEAUTOUPDATE + //this is an engine update (with installed file) and marked. + if (ef && (p->flags & DPF_MARKED)) + { + char native[MAX_OSPATH]; + package_t *othr; + //make sure there's no more recent build that's also enabled... + for (othr = availablepackages; othr ; othr=othr->next) + { + if ((othr->flags & DPF_ENGINE) && (othr->flags & DPF_MARKED) && othr->flags & (DPF_PRESENT|DPF_ENABLED) && othr != p) + if (strcmp(p->version, othr->version) >= 0) + return; + } + + if (FS_NativePath(ef->name, p->fsroot, native, sizeof(native)) && Sys_SetUpdatedBinary(native)) + Menu_Prompt(NULL, NULL, "Engine binary updated.\nRestart to use.", NULL, NULL, NULL); + else + Menu_Prompt(NULL, NULL, "Engine update failed.\nManual update required.", NULL, NULL, NULL); + } +#endif } #ifdef WEBCLIENT diff --git a/engine/client/m_mp3.c b/engine/client/m_mp3.c index b415de4dd..36dd75fb5 100644 --- a/engine/client/m_mp3.c +++ b/engine/client/m_mp3.c @@ -3974,16 +3974,43 @@ static void Media_RecordFilm (char *recordingname, qboolean demo) currentcapture_funcs = pluginencodersfunc[i]; } if (!currentcapture_funcs) - { + { //try to find one based upon the explicit extension given. + char captext[8]; + const char *outext = COM_GetFileExtension(recordingname, NULL); + for (i = 0; i < countof(pluginencodersfunc); i++) { - if (pluginencodersfunc[i]) + if (pluginencodersfunc[i] && pluginencodersfunc[i]->extensions) { - currentcapture_funcs = pluginencodersfunc[i]; -// break; + const char *t = pluginencodersfunc[i]->extensions; + while (*t) + { + t = COM_ParseStringSetSep (t, ';', captext, sizeof(captext)); + if (wildcmp(captext, outext)) + { //matches the wildcard... + currentcapture_funcs = pluginencodersfunc[i]; + break; + } + } } } } + if (!currentcapture_funcs) + { //otherwise just find the first valid one that's in a plugin. + for (i = 0; i < countof(pluginencodersfunc); i++) + { + if (pluginencodersfunc[i] && pluginencodersfunc[i]->extensions && pluginencodersplugin[i]) + currentcapture_funcs = pluginencodersfunc[i]; + } + } + if (!currentcapture_funcs) + { //otherwise just find the first valid one that's from anywhere... + for (i = 0; i < countof(pluginencodersfunc); i++) + { + if (pluginencodersfunc[i] && pluginencodersfunc[i]->extensions) + currentcapture_funcs = pluginencodersfunc[i]; + } + } if (capturesound.ival) { sndkhz = snd_speed?snd_speed:48000; @@ -4042,8 +4069,11 @@ static void Media_RecordFilm (char *recordingname, qboolean demo) { //extensions are evil, but whatever. //make sure there is actually an extension there, and don't break if they try overwriting a known demo format... COM_StripExtension(recordingname, fname, sizeof(fname)); - if (currentcapture_funcs->defaultextension) - Q_strncatz(fname, currentcapture_funcs->defaultextension, sizeof(fname)); + if (currentcapture_funcs->extensions) + { + COM_ParseStringSetSep (currentcapture_funcs->extensions, ';', ext, sizeof(ext)); + Q_strncatz(fname, ext, sizeof(fname)); + } recordingname = fname; } diff --git a/engine/client/m_options.c b/engine/client/m_options.c index 0891c1ebd..b1e6cab4d 100644 --- a/engine/client/m_options.c +++ b/engine/client/m_options.c @@ -4279,9 +4279,9 @@ static qboolean Installer_Go(menuoption_t *opt, menu_t *menu, int key) FS_CreateBasedir(path); #ifdef _WIN32 - GetModuleFileName(NULL, exepath, sizeof(exepath)); + GetModuleFileNameW(NULL, exepath, sizeof(exepath)); FS_NativePath(va("%s.exe", fs_manifest->installation), FS_ROOT, newexepath, sizeof(newexepath)); - CopyFile(exepath, newexepath, FALSE); + CopyFileW(exepath, newexepath, FALSE); // SetHookState(false); Host_Shutdown (); @@ -4290,8 +4290,13 @@ static qboolean Installer_Go(menuoption_t *opt, menu_t *menu, int key) // _execv(newexepath, host_parms.argv); { PROCESS_INFORMATION childinfo; - STARTUPINFO startinfo = {sizeof(startinfo)}; - CreateProcess(newexepath, va("\"%s\" +sys_register_file_associations %s", newexepath, COM_Parse(GetCommandLineA())), NULL, NULL, FALSE, 0, NULL, path, &startinfo, &childinfo); + STARTUPINFOW startinfo = {sizeof(startinfo)}; + memset(&childinfo, 0, sizeof(childinfo)); + if (CreateProcessW(newexepath, va("\"%s\" +sys_register_file_associations %s", newexepath, COM_Parse(GetCommandLineW())), NULL, NULL, FALSE, 0, NULL, path, &startinfo, &childinfo)) + { + CloseHandle(childinfo.hProcess); + CloseHandle(childinfo.hThread); + } } exit(1); #elif 0 diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index 1941c18b2..a9b6798a9 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -7066,7 +7066,8 @@ static int PDECL PR_CSQC_MapNamedBuiltin(pubprogfuncs_t *progfuncs, int headercr break; } } - Con_DPrintf("Unknown csqc builtin: %s\n", builtinname); + if (!csqc_nogameaccess) + Con_DPrintf("Unknown csqc builtin: %s\n", builtinname); return 0; } @@ -7890,7 +7891,7 @@ void CSQC_RendererRestarted(void) if (csqcg.rendererrestarted) { void *pr_globals = PR_globals(csqcprogs, PR_CURRENT); - (((string_t *)pr_globals)[OFS_PARM1] = PR_TempString(csqcprogs, rf->description)); + (((string_t *)pr_globals)[OFS_PARM0] = PR_TempString(csqcprogs, rf->description)); PR_ExecuteProgram(csqcprogs, csqcg.rendererrestarted); } //in case it drew to any render targets. diff --git a/engine/client/render.h b/engine/client/render.h index 3051d3bbe..7ce167558 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -43,7 +43,7 @@ static const texid_t r_nulltex = NULL; //desktop-gl will generally cope with ints, but expect a performance hit from that with old gpus (so we don't bother) //vulkan+dx10 can cope with ints, but might be 24bit //either way, all renderers in the same build need to use the same thing. -#if (defined(GLQUAKE) && defined(HAVE_LEGACY)) || defined(MINIMAL) || defined(D3D8QUAKE) || defined(D3D9QUAKE) || defined(ANDROID) +#if (defined(GLQUAKE) && defined(HAVE_LEGACY)) || defined(MINIMAL) || defined(D3D8QUAKE) || defined(D3D9QUAKE) || defined(ANDROID) || defined(FTE_TARGET_WEB) #define sizeof_index_t 2 #endif #if sizeof_index_t == 2 diff --git a/engine/client/snd_dma.c b/engine/client/snd_dma.c index 98dc2bdb3..f8060461e 100644 --- a/engine/client/snd_dma.c +++ b/engine/client/snd_dma.c @@ -4156,7 +4156,7 @@ typedef struct { qboolean inuse; int id; - sfx_t sfx; + sfx_t *sfx; int numchannels; int width; @@ -4184,8 +4184,26 @@ sfxcache_t *QDECL S_Raw_Locate(sfx_t *sfx, sfxcache_t *buf, ssamplepos_t start, buf->speed = snd_speed; buf->width = s->width; } + if (start >= s->length) + return NULL; //eof... return buf; } +void QDECL S_Raw_Ended(sfx_t *sfx) +{ //no longer playing anywhere... + streaming_t *s = sfx->decoder.buf; + s->inuse = false; //let it get reused now. +} +void QDECL S_Raw_Purge(sfx_t *sfx) +{ //flush all caches, will be re-read from disk (or not, because this is streamed) + streaming_t *s = sfx->decoder.buf; + s->length = 0; + s->numchannels = 0; + BZ_Free(s->data); + s->data = NULL; + s->inuse = false; + + memset(&sfx->decoder, 0, sizeof(sfx->decoder)); +} //streaming audio. //this is useful when there is one source, and the sound is to be played with no attenuation void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels, int width, float volume) @@ -4219,12 +4237,13 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels, S_LockMixer(); for (si = sndcardinfo; si; si=si->next) for (i = 0; i < si->total_chans; i++) - if (si->channel[i].sfx == &s->sfx) + if (si->channel[i].sfx == s->sfx) { si->channel[i].sfx = NULL; break; } BZ_Free(s->data); + s->data = NULL; S_UnlockMixer(); return; } @@ -4239,9 +4258,16 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels, } s = free; } - s->sfx.decoder.buf = s; - s->sfx.decoder.decodedata = S_Raw_Locate; - s->sfx.loadstate = SLS_LOADED; + + if (!s->sfx) + s->sfx = S_FindName(va("***stream_%i***", i), true, false); + s->sfx->decoder.buf = s; + s->sfx->decoder.decodedata = S_Raw_Locate; + s->sfx->decoder.ended = S_Raw_Ended; + s->sfx->decoder.purge = S_Raw_Purge; + s->sfx->loopstart = -1; //non-looping... + s->sfx->loadstate = SLS_LOADED; + s->numchannels = channels; s->width = width; s->data = NULL; @@ -4249,7 +4275,6 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels, s->id = sourceid; s->inuse = true; - strcpy(s->sfx.name, "raw stream"); // Con_Printf("Added new raw stream\n"); } S_LockMixer(); @@ -4269,7 +4294,7 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels, for (si = sndcardinfo; si; si=si->next) //make sure all cards are playing, and that we still get a prepad if just one is. { for (i = 0; i < si->total_chans; i++) - if (si->channel[i].sfx == &s->sfx) + if (si->channel[i].sfx == s->sfx) { if (prepadl > (si->channel[i].pos>>PITCHSHIFT)) prepadl = (si->channel[i].pos>>PITCHSHIFT); @@ -4330,7 +4355,7 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels, for (si = sndcardinfo; si; si=si->next) { for (i = 0; i < si->total_chans; i++) - if (si->channel[i].sfx == &s->sfx) + if (si->channel[i].sfx == s->sfx) { si->channel[i].pos -= prepadl*si->channel[i].rate; @@ -4353,7 +4378,7 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels, c->master_vol = 255 * volume; c->pos = 0; c->rate = 1<sfx = &s->sfx; + c->sfx = s->sfx; SND_Spatialize(si, c); if (si->ChannelUpdate) diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index 474627ed5..8922621e2 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -2756,7 +2756,7 @@ void Win7_TaskListInit(void) #endif #define SVNREVISIONSTR STRINGIFY(SVNREVISION) -#ifndef NOLEGACY +#if 0//ndef NOLEGACY #if defined(SVNREVISION) && !defined(MINIMAL) #if defined(OFFICIAL_RELEASE) #define UPD_BUILDTYPE "rel" @@ -2806,14 +2806,63 @@ void Win7_TaskListInit(void) #ifdef HAVEAUTOUPDATE //this is for legacy reasons. old builds stored a 'pending' name in the registry for the 'frontend' to rename+use -void Sys_SetUpdatedBinary(const char *binary) +qboolean Sys_SetUpdatedBinary(const char *newbinary) { +/* //legacy crap, completely redundant when we're replacing the original binary #ifdef UPD_BUILDTYPE //downloads menu has provided a new binary to use - MyRegSetValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, "pending" UPD_BUILDTYPE EXETYPE, REG_SZ, binary, strlen(binary)+1); + MyRegSetValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, "pending" UPD_BUILDTYPE EXETYPE, REG_SZ, newbinary, strlen(newbinary)+1); #endif +*/ + wchar_t newbinaryw[MAX_OSPATH]; + wchar_t enginebinary[MAX_OSPATH]; + wchar_t enginebinarybackup[MAX_OSPATH+4]; + size_t len; + static qboolean alreadymoved = false; + + //windows is annoying. we can't delete a file that's in use (no orphaning) + //we can normally rename it to something else before writing a new file with the original name. + //then delete the old file later (sadly only on reboot) + + //because microsoft suck. + widen(newbinaryw, sizeof(newbinaryw), newbinary); + //get the binary name + GetModuleFileNameW(NULL, enginebinary, countof(enginebinary)-1); +#ifdef HAVE_LEGACY + //--fromfrontend was removed for r5596. + //it had two args - launcher version and launcher filename, so that if the user manually updated then it'd use the more recent build. + //replace the original launcher instead. + { + int arg = COM_CheckParm("--fromfrontend"); + if (arg) + widen(enginebinary, sizeof(enginebinary), com_argv[arg+2]); + } +#endif + //generate the temp name + memcpy(enginebinarybackup, enginebinary, sizeof(enginebinary)); + len = wcslen(enginebinarybackup); + if (len > 4 && !_wcsicmp(enginebinarybackup+len-4, L".exe")) + len -= 4; //swap its extension over, if we can. + wcscpy(enginebinarybackup+len, L".bak"); + + //can fail if we don't have write access. can fail for a few other reasons. + if (alreadymoved || MoveFileExW(enginebinary, enginebinarybackup, MOVEFILE_REPLACE_EXISTING)) + { + //can fail if windows is bugging out again + if (CopyFileW(newbinaryw, enginebinary, FALSE)) + { //delete the old one eventually, when we can. + if (!DeleteFileW(enginebinarybackup)) //if we can directly delete it... sadly this will normally fail but lets try it anyway. maybe it'll get opened with SHARE_DELETE some time! + MoveFileExW(enginebinarybackup, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); //schedule it to delete if we can't do it from the start. + alreadymoved = true; //if we already moved it, don't try to delete-by-overwrite the current binary, just delete it... + return true; //yay! it worked! + } + if (!alreadymoved) + MoveFileExW(enginebinarybackup, enginebinary, 0); + } + alreadymoved = false; + return false; } -qboolean Sys_EngineCanUpdate(void) +qboolean Sys_EngineMayUpdate(void) { char *e; @@ -2833,11 +2882,13 @@ qboolean Sys_EngineCanUpdate(void) return true; } +/* qboolean Sys_EngineWasUpdated(char *newbinary) { - wchar_t wide1[2048]; - wchar_t widefe[MAX_OSPATH]; + wchar_t launchbinary[2048]; + wchar_t launcherbinary[MAX_OSPATH]; wchar_t wargs[8192]; + wchar_t rev[2048]; PROCESS_INFORMATION childinfo; STARTUPINFOW startinfo = {sizeof(startinfo)}; @@ -2848,18 +2899,25 @@ qboolean Sys_EngineWasUpdated(char *newbinary) if (!Sys_EngineCanUpdate()) return false; + memset(&childinfo, 0, sizeof(childinfo)); startinfo.dwFlags = STARTF_USESTDHANDLES; startinfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE); startinfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); startinfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); - GetModuleFileNameW(NULL, widefe, countof(widefe)-1); - _snwprintf(wargs, countof(wargs), L"%s --fromfrontend \"%s\" \"%s\"", GetCommandLineW(), widen(wide1, sizeof(wide1), SVNREVISIONSTR), widefe); - if (CreateProcessW(widen(wide1, sizeof(wide1), newbinary), wargs, NULL, NULL, TRUE, 0, NULL, NULL, &startinfo, &childinfo)) + GetModuleFileNameW(NULL, launcherbinary, countof(launcherbinary)-1); + widen(launchbinary, sizeof(launchbinary), newbinary); + _snwprintf(wargs, countof(wargs), L"%s --fromfrontend \"%s\" \"%s\"", GetCommandLineW(), widen(rev, sizeof(rev), SVNREVISIONSTR), launcherbinary); + if (CreateProcessW(launchbinary, wargs, NULL, NULL, TRUE, 0, NULL, NULL, &startinfo, &childinfo)) + { + CloseHandle(childinfo.hProcess); + CloseHandle(childinfo.hThread); return true; //it started up, we need to die now. + } return false; //failure! } +*/ #endif #include "shellapi.h" diff --git a/engine/client/textedit.c b/engine/client/textedit.c index 9a4df1839..989a96b97 100644 --- a/engine/client/textedit.c +++ b/engine/client/textedit.c @@ -1070,7 +1070,7 @@ int QCLibEditor(pubprogfuncs_t *prfncs, const char *filename, int *line, int *st if (editormodal || (stepasm && !statement)) { if (fatal) - return DEBUG_TRACE_ABORT; + return DEBUG_TRACE_ABORTERROR; return DEBUG_TRACE_OFF; //whoops } @@ -1082,7 +1082,7 @@ int QCLibEditor(pubprogfuncs_t *prfncs, const char *filename, int *line, int *st if (!stepasm && *filename) Con_Printf("Set %s to trace\n", pr_debugger.name); if (fatal) - return DEBUG_TRACE_ABORT; + return DEBUG_TRACE_ABORTERROR; return DEBUG_TRACE_OFF; //get lost } @@ -1103,7 +1103,7 @@ int QCLibEditor(pubprogfuncs_t *prfncs, const char *filename, int *line, int *st if (!line) { //please don't crash if (fatal) - return DEBUG_TRACE_ABORT; + return DEBUG_TRACE_ABORTERROR; return DEBUG_TRACE_OFF; //whoops } @@ -1185,7 +1185,7 @@ int QCLibEditor(pubprogfuncs_t *prfncs, const char *filename, int *line, int *st else { if (fatal) - return DEBUG_TRACE_ABORT; + return DEBUG_TRACE_ABORTERROR; return DEBUG_TRACE_OFF; //whoops } } diff --git a/engine/common/com_mesh.c b/engine/common/com_mesh.c index 69875b620..ec5a99fd5 100644 --- a/engine/common/com_mesh.c +++ b/engine/common/com_mesh.c @@ -5870,7 +5870,7 @@ static qboolean QDECL Mod_LoadQ3Model(model_t *mod, void *buffer, size_t fsize) char lodname[MAX_QPATH]; memcpy(basename, mod->name, ext-mod->name); basename[ext-mod->name] = 0; - Q_snprintfz(lodname, sizeof(lodname), "%s_%i.%s", basename, lod, ext); + Q_snprintfz(lodname, sizeof(lodname), "%s_%i%s", basename, lod, ext); f = FS_LoadMallocFile(lodname, &s); if (!f) break; diff --git a/engine/common/common.c b/engine/common/common.c index 62cfc17e2..423c0f151 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -3049,7 +3049,7 @@ char *COM_ParseStringSetSep (const char *data, char sep, char *out, size_t outsi return (char*)data; } c = *data++; - if (c == ';') + if (c == sep) break; out[len++] = c; } diff --git a/engine/common/fs_pak.c b/engine/common/fs_pak.c index e639ba4ab..336d1e08f 100644 --- a/engine/common/fs_pak.c +++ b/engine/common/fs_pak.c @@ -374,8 +374,8 @@ searchpathfuncs_t *QDECL FSPAK_LoadArchive (vfsfile_t *file, searchpathfuncs_t * for (j=0 ; j= 2) { if (wantquit) - return DEBUG_TRACE_ABORT; + return DEBUG_TRACE_ABORTERROR; if (!*filename || !line || !*line) //don't try editing an empty line, it won't work { if (!*filename) @@ -398,7 +398,7 @@ int QDECL QCEditor (pubprogfuncs_t *prinst, const char *filename, int *line, int else Con_Printf("Unable to debug, please provide line number info\n"); if (fatal) - return DEBUG_TRACE_ABORT; + return DEBUG_TRACE_ABORTERROR; return DEBUG_TRACE_OFF; } #ifdef SERVERONLY @@ -475,7 +475,7 @@ int QDECL QCEditor (pubprogfuncs_t *prinst, const char *filename, int *line, int debuggerinstance = NULL; debuggerfile = NULL; if (wantquit) - return DEBUG_TRACE_ABORT; + return DEBUG_TRACE_ABORTERROR; return debuggerresume; } //#endif @@ -484,7 +484,7 @@ int QDECL QCEditor (pubprogfuncs_t *prinst, const char *filename, int *line, int return QCLibEditor(prinst, filename, line, statement, firststatement, reason, fatal); #else if (fatal) - return DEBUG_TRACE_ABORT; + return DEBUG_TRACE_ABORTERROR; return DEBUG_TRACE_OFF; //get lost #endif } diff --git a/engine/common/sys.h b/engine/common/sys.h index 1e5f7d092..c2c05b024 100644 --- a/engine/common/sys.h +++ b/engine/common/sys.h @@ -186,13 +186,13 @@ void NPQTV_Sys_MainLoop(void); int StartLocalServer(int close); #define HAVEAUTOUPDATE -void Sys_SetUpdatedBinary(const char *fname); //legacy, so old build can still deal with updates properly -qboolean Sys_EngineCanUpdate(void); //says whether the system code is able to invoke new binaries properly -qboolean Sys_EngineWasUpdated(char *newbinary); //invoke the given system-path binary +qboolean Sys_SetUpdatedBinary(const char *fname); //legacy, so old build can still deal with updates properly +qboolean Sys_EngineMayUpdate(void); //says whether the system code is able to invoke new binaries properly +//qboolean Sys_EngineWasUpdated(char *newbinary); //invoke the given system-path binary #else -#define Sys_EngineCanUpdate() false -#define Sys_SetUpdatedBinary(n) -#define Sys_EngineWasUpdated(n) false +#define Sys_EngineMayUpdate() false +#define Sys_SetUpdatedBinary(n) false +//#define Sys_EngineWasUpdated(n) false #endif void Sys_Init (void); diff --git a/engine/common/sys_win_threads.c b/engine/common/sys_win_threads.c index 4d1964440..0ede67b23 100644 --- a/engine/common/sys_win_threads.c +++ b/engine/common/sys_win_threads.c @@ -536,9 +536,9 @@ pubsubserver_t *Sys_ForkServer(void) memset(&startinfo, 0, sizeof(startinfo)); startinfo.cb = sizeof(startinfo); - startinfo.hStdInput = NULL; - startinfo.hStdError = NULL; - startinfo.hStdOutput = NULL; + startinfo.hStdInput = INVALID_HANDLE_VALUE; + startinfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); + startinfo.hStdOutput = INVALID_HANDLE_VALUE; startinfo.dwFlags |= STARTF_USESTDHANDLES; //create pipes for the stdin/stdout. diff --git a/engine/common/zone.c b/engine/common/zone.c index c9331b1d9..471119da0 100644 --- a/engine/common/zone.c +++ b/engine/common/zone.c @@ -520,7 +520,7 @@ void *QDECL ZG_Malloc(zonegroup_t *ctx, size_t size) #endif newm->next = ctx->first; ctx->first = newm; - ctx->bytes += size; + ctx->totalbytes += size; return(void*)(newm+1); } void ZG_FreeGroup(zonegroup_t *ctx) @@ -532,7 +532,7 @@ void ZG_FreeGroup(zonegroup_t *ctx) ctx->first = old->next; BZ_Free(old); } - ctx->bytes = 0; + ctx->totalbytes = 0; } //============================================================================ diff --git a/engine/common/zone.h b/engine/common/zone.h index ae1747097..8832422d6 100644 --- a/engine/common/zone.h +++ b/engine/common/zone.h @@ -122,7 +122,7 @@ void BZ_Free(void *ptr); typedef struct zonegroup_s { void *first; - int bytes; + int totalbytes; //combined size of all mallocs in this group } zonegroup_t; void *QDECL ZG_Malloc(zonegroup_t *ctx, size_t size); void *ZG_MallocNamed(zonegroup_t *ctx, size_t size, char *file, int line); diff --git a/engine/gl/gl_heightmap.c b/engine/gl/gl_heightmap.c index c3a3382b6..bfa19a29f 100644 --- a/engine/gl/gl_heightmap.c +++ b/engine/gl/gl_heightmap.c @@ -7145,7 +7145,7 @@ void Terr_WriteBrushInfo(vfsfile_t *file, brushes_t *br) { float *point[3]; int i, x, y; - qboolean valve220 = true; + const qboolean valve220 = true; VFS_PRINTF(file, "\n{"); if (br->patch) @@ -7646,8 +7646,9 @@ qboolean Terr_ReformEntitiesLump(model_t *mod, heightmap_t *hm, char *entities) //hexen2:( -0 -0 16 ) ( -0 -0 32 ) ( 64 -0 16 ) texname soffset toffset rotation sscale tscale utterlypointless //Valve: ( -0 -0 16 ) ( -0 -0 32 ) ( 64 -0 16 ) texname [x y z d] [x y z d] rotation sscale tscale //fte : ( px py pz pd ) texname [sx sy sz sd] [tx ty tz td] 0 1 1 - //q3 : ( -0 -0 16 ) ( -0 -0 32 ) ( 64 -0 16 ) common/caulk common/caulk rotation sscale tscale detailcontents unused unused - //doom3: brushdef3 { ( px py pz pd ) ( ( x y z ) ( x y z ) ) texture detailcontents unused unused } + //q3 : ( -0 -0 16 ) ( -0 -0 32 ) ( 64 -0 16 ) texname common/caulk rotation sscale tscale detailcontents unused unused + //q3bp : brushDef { ( -0 -0 16 ) ( -0 -0 32 ) ( 64 -0 16 ) ( ( x y o ) ( x y o ) ) texname detailcontents unused unused } //generate tangent+bitangent from the normal to generate base texcoords, then transform by the given 2*3 matrix. I prefer valve's way - it rotates more cleanly. + //doom3: brushDef3 { ( px py pz pd ) ( ( x y z ) ( x y z ) ) texname detailcontents unused unused } brushtex_t *bt; vec3_t d1,d2; vec3_t points[3]; diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index 93cc9a222..a4b947a27 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -118,9 +118,9 @@ static void Mod_MemList_f(void) int total = 0; for (m=0 , mod=mod_known ; mmemgroup.bytes) - Con_Printf("%s: %i bytes\n", mod->name, mod->memgroup.bytes); - total += mod->memgroup.bytes; + if (mod->memgroup.totalbytes) + Con_Printf("%s: %i bytes\n", mod->name, mod->memgroup.totalbytes); + total += mod->memgroup.totalbytes; } Con_Printf("Total: %i bytes\n", total); } diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index f64fd26bd..a7405e291 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -468,7 +468,7 @@ void APIENTRY GL_ClientActiveTextureStub(GLenum texid) #define getglcore getglfunction #define getglext(name) getglfunction(name) -void GL_CheckExtensions (void *(*getglfunction) (char *name)) +static qboolean GL_CheckExtensions (void *(*getglfunction) (char *name)) { qboolean webgl = false; unsigned int gl_major_version = 0; @@ -534,6 +534,14 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) //yes, I know, this can't cope with minor versions of 10+... I don't care yet. gl_config.glversion += gl_major_version + (gl_minor_version/10.f); +#if GL_INDEX_TYPE == GL_UNSIGNED_INT + if (gl_config_gles && gl_config.glversion < 3.0) + { //opengles 1 and 2 do NOT support 32bit indexes. desktop gl always does but es supports it starting with gles3.0 + Con_Printf ("Support for OpenGL ES 3.0 is required.\n"); + return false; + } +#endif + /*gl3 adds glGetStringi instead, as core, with the old form require GL_ARB_compatibility*/ if (gl_major_version >= 3 && qglGetStringi) /*warning: wine fails to export qglGetStringi*/ { @@ -1355,6 +1363,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) qglGenVertexArrays = NULL; qglBindVertexArray = NULL; } + return true; //all okay. } static const char *glsl_hdrs[] = @@ -3367,7 +3376,8 @@ qboolean GL_Init(rendererstate_t *info, void *(*getglfunction) (char *name)) memset(&sh_config, 0, sizeof(sh_config)); - GL_CheckExtensions (getglfunction); + if (!GL_CheckExtensions (getglfunction)) + return false; #ifndef FTE_TARGET_WEB if (!gl_config.gles) diff --git a/engine/gl/gl_vidlinuxglx.c b/engine/gl/gl_vidlinuxglx.c index eb41fbc13..18c55c35e 100644 --- a/engine/gl/gl_vidlinuxglx.c +++ b/engine/gl/gl_vidlinuxglx.c @@ -80,7 +80,9 @@ static qboolean XVK_SetupSurface_XCB(void); #endif #define USE_VMODE -#define USE_XRANDR +#ifndef NO_X11_RANDR + #define USE_XRANDR +#endif #include #include @@ -4214,7 +4216,7 @@ static qboolean X11VID_Init (rendererstate_t *info, unsigned char *palette, int else #endif #ifdef USE_VMODE - if (!xrandr.origgamma && vm.pXF86VidModeGetGammaRampSize) + if (vm.pXF86VidModeGetGammaRampSize) { int rampsize = 256; vm.pXF86VidModeGetGammaRampSize(vid_dpy, scrnum, &rampsize); diff --git a/engine/qclib/execloop.h b/engine/qclib/execloop.h index 2a532ce33..2afd6f205 100644 --- a/engine/qclib/execloop.h +++ b/engine/qclib/execloop.h @@ -57,9 +57,9 @@ //this will fire on the next instruction after the variable got changed. prinst.pr_xstatement = s; if (current_progstate->linenums) - externs->Printf("Watch point hit in %s:%u, \"%s\" changed", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), current_progstate->linenums[s-1], prinst.watch_name); + externs->Printf("Watch point hit in %s:%u, \"%s\" changed", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), current_progstate->linenums[s-1], prinst.watch_name); else - externs->Printf("Watch point hit in %s, \"%s\" changed", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), prinst.watch_name); + externs->Printf("Watch point hit in %s, \"%s\" changed", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), prinst.watch_name); switch(prinst.watch_type) { case ev_float: @@ -89,7 +89,7 @@ else if (progfuncs->funcs.debug_trace) s=ShowStep(progfuncs, s, NULL, false); st = pr_statements + s; - pr_xfunction->profile+=1; + prinst.pr_xfunction->profile+=1; op = (progfuncs->funcs.debug_trace?(st->op & ~0x8000):st->op); reeval: @@ -143,7 +143,7 @@ reeval: /* errorif (OPB->_float == 0) { prinst.pr_xstatement = st-pr_statements; - externs->Printf ("Division by 0 in %s\n", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); + externs->Printf ("Division by 0 in %s\n", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)); PR_StackTrace (&progfuncs->funcs, 1); OPC->_float = 0.0; } @@ -155,7 +155,7 @@ reeval: /* errorif (!tmpf) { prinst.pr_xstatement = st-pr_statements; - externs->Printf ("Division by 0 in %s\n", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); + externs->Printf ("Division by 0 in %s\n", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)); PR_StackTrace (&progfuncs->funcs, 1); } */ @@ -361,7 +361,7 @@ reeval: { if (i == -1) break; - QCFAULT(&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); + QCFAULT(&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)); } ptr = QCPOINTERM(i); ptr->_float = (float)OPA->_int; @@ -372,7 +372,7 @@ reeval: { if (i == -1) break; - QCFAULT(&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); + QCFAULT(&progfuncs->funcs, "bad pointer write in %s", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)); } ptr = QCPOINTERM(i); ptr->_int = (int)OPA->_float; @@ -389,9 +389,9 @@ reeval: if (i == -1) break; if (i == 0) - QCFAULT(&progfuncs->funcs, "bad pointer write in %s (null pointer)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); + QCFAULT(&progfuncs->funcs, "bad pointer write in %s (null pointer)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)); else - QCFAULT(&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), i, prinst.addressableused); + QCFAULT(&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, prinst.addressableused); } ptr = QCPOINTERM(i); ptr->_int = OPA->_int; @@ -402,7 +402,7 @@ reeval: { if (i == -1) break; - QCFAULT(&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), i, prinst.addressableused); + QCFAULT(&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, prinst.addressableused); } ptr = QCPOINTERM(i); ptr->_vector[0] = OPA->_vector[0]; @@ -416,7 +416,7 @@ reeval: { if (i == -1) break; - QCFAULT(&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), i, prinst.addressableused); + QCFAULT(&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, prinst.addressableused); } ptr = QCPOINTERM(i); *(unsigned char *)ptr = (char)OPA->_float; @@ -426,7 +426,7 @@ reeval: case OP_ADDRESS: errorif ((unsigned)OPA->edict >= (unsigned)num_edicts) { - if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_ADDRESS references invalid entity in %s\n", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name))) + if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_ADDRESS references invalid entity in %s\n", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name))) return prinst.pr_xstatement; break; } @@ -445,7 +445,7 @@ reeval: ddef32_t *d = ED_GlobalAtOfs32(progfuncs, st->a); #endif fdef_t *f = ED_FieldAtOfs(progfuncs, OPB->_int + progfuncs->funcs.fieldadjust); - if (PR_ExecRunWarning(&progfuncs->funcs, st-pr_statements, "assignment to read-only entity %i in %s (%s.%s)\n", OPA->edict, PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), d?PR_StringToNative(&progfuncs->funcs, d->s_name):"??", f?f->name:"??")) + if (PR_ExecRunWarning(&progfuncs->funcs, st-pr_statements, "assignment to read-only entity %i in %s (%s.%s)\n", OPA->edict, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), d?PR_StringToNative(&progfuncs->funcs, d->s_name):"??", f?f->name:"??")) return prinst.pr_xstatement; OPC->_int = ~0; break; @@ -456,7 +456,7 @@ reeval: #ifdef NOLEGACY errorif (ed->ereftype == ER_FREE) { - if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "assignment to free entity in %s", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name))) + if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "assignment to free entity in %s", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name))) return prinst.pr_xstatement; break; } @@ -466,7 +466,7 @@ reeval: #ifdef PARANOID errorif ((unsigned int)i*4 >= ed->fieldsize) //FIXME:lazy size check { - if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_ADDRESS references invalid field %i in %s\n", OPB->_int, PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name))) + if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_ADDRESS references invalid field %i in %s\n", OPB->_int, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name))) return prinst.pr_xstatement; OPC->_int = 0; break; @@ -486,7 +486,7 @@ reeval: case OP_LOAD_FNC: errorif ((unsigned)OPA->edict >= (unsigned)num_edicts) { - if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_LOAD references invalid entity %i in %s\n", OPA->edict, PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name))) + if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_LOAD references invalid entity %i in %s\n", OPA->edict, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name))) return prinst.pr_xstatement; OPC->_int = 0; break; @@ -498,7 +498,7 @@ reeval: #ifdef NOLEGACY if (ed->ereftype == ER_FREE) { - if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_LOAD references free entity %i in %s\n", OPA->edict, PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name))) + if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_LOAD references free entity %i in %s\n", OPA->edict, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name))) return prinst.pr_xstatement; OPC->_int = 0; } @@ -508,7 +508,7 @@ reeval: i = OPB->_int + progfuncs->funcs.fieldadjust; errorif ((unsigned int)i*4 >= ed->fieldsize) //FIXME:lazy size check { - if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_LOAD references invalid field %i in %s\n", OPB->_int, PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name))) + if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_LOAD references invalid field %i in %s\n", OPB->_int, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name))) return prinst.pr_xstatement; OPC->_int = 0; break; @@ -521,7 +521,7 @@ reeval: case OP_LOAD_V: errorif ((unsigned)OPA->edict >= (unsigned)num_edicts) { - if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_LOAD_V references invalid entity %i in %s\n", OPA->edict, PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name))) + if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_LOAD_V references invalid entity %i in %s\n", OPA->edict, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name))) return prinst.pr_xstatement; OPC->_vector[0] = 0; OPC->_vector[1] = 0; @@ -535,7 +535,7 @@ reeval: #ifdef NOLEGACY if (ed->ereftype == ER_FREE) { - if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_LOAD references free entity %i in %s\n", OPA->edict, PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name))) + if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_LOAD references free entity %i in %s\n", OPA->edict, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name))) return prinst.pr_xstatement; OPC->_vector[0] = 0; OPC->_vector[1] = 0; @@ -547,7 +547,7 @@ reeval: i = OPB->_int + progfuncs->funcs.fieldadjust; errorif ((unsigned int)i*4 >= ed->fieldsize) //FIXME:lazy size check { - if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_LOAD references invalid field %i in %s\n", OPB->_int, PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name))) + if (PR_ExecRunWarning (&progfuncs->funcs, st-pr_statements, "OP_LOAD references invalid field %i in %s\n", OPB->_int, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name))) return prinst.pr_xstatement; OPC->_int = 0; break; @@ -655,11 +655,11 @@ reeval: glob = pr_globals; if (!progfuncs->funcs.debug_trace) - QCFAULT(&progfuncs->funcs, msg, PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); + QCFAULT(&progfuncs->funcs, msg, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)); //skip the instruction if they just try stepping over it anyway. PR_StackTrace(&progfuncs->funcs, 0); - externs->Printf(msg, PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); + externs->Printf(msg, PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)); pr_globals[OFS_RETURN] = 0; pr_globals[OFS_RETURN+1] = 0; @@ -689,14 +689,6 @@ reeval: //in case ed_alloc was called num_edicts = sv_num_edicts; - - if (prinst.continuestatement!=-1) - { - st=&pr_statements[prinst.continuestatement]; - prinst.continuestatement=-1; - glob = pr_globals; - break; - } } else { @@ -709,8 +701,7 @@ reeval: PR_SwitchProgsParms(progfuncs, (progsnum_t)callerprogs); //decide weather non debugger wants to start debugging. - s = st-pr_statements; - return s; + return prinst.pr_xstatement; } // PR_SwitchProgsParms((OPA->function & 0xff000000)>>24); s = PR_EnterFunction (progfuncs, newf, callerprogs); @@ -780,7 +771,7 @@ reeval: i = OPA->_int; errorif (QCPOINTERREADFAIL(i, sizeof(char))) { - QCFAULT(&progfuncs->funcs, "bad pointer read in %s (%#x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPA->_int); + QCFAULT(&progfuncs->funcs, "bad pointer read in %s (%#x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), OPA->_int); } ptr = QCPOINTERM(i); OPC->_float = (float)ptr->_int; @@ -790,7 +781,7 @@ reeval: i = OPA->_int; errorif (QCPOINTERREADFAIL(i, sizeof(char))) { - QCFAULT(&progfuncs->funcs, "bad pointer read in %s (%#x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPA->_int); + QCFAULT(&progfuncs->funcs, "bad pointer read in %s (%#x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), OPA->_int); } ptr = QCPOINTERM(i); OPC->_int = (int)ptr->_float; @@ -838,7 +829,7 @@ reeval: i = st->a + OPB->_int; if ((size_t)(i<<2) >= (size_t)current_progstate->globals_size) { - QCFAULT(&progfuncs->funcs, "bad array read in %s (index %i)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int); + QCFAULT(&progfuncs->funcs, "bad array read in %s (index %i)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), OPB->_int); } else OPC->_int = ((eval_t *)&glob[i])->_int; @@ -848,7 +839,7 @@ reeval: i = st->a + OPB->_int; if ((size_t)(i<<2) >= (size_t)current_progstate->globals_size) { - QCFAULT(&progfuncs->funcs, "bad array read in %s (index %i)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int); + QCFAULT(&progfuncs->funcs, "bad array read in %s (index %i)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), OPB->_int); } else { @@ -877,7 +868,7 @@ reeval: OPC->_int = 0; break; } - QCFAULT(&progfuncs->funcs, "bad pointer read in %s (%i bytes into %s)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), i, ptr); + QCFAULT(&progfuncs->funcs, "bad pointer read in %s (%i bytes into %s)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, ptr); } } else @@ -900,7 +891,7 @@ reeval: OPC->_int = 0; break; } - QCFAULT(&progfuncs->funcs, "bad pointer read in %s (from %#x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), i); + QCFAULT(&progfuncs->funcs, "bad pointer read in %s (from %#x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i); } } else @@ -921,7 +912,7 @@ reeval: OPC->_vector[2] = 0; break; } - QCFAULT(&progfuncs->funcs, "bad pointer read in %s (from %#x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), i); + QCFAULT(&progfuncs->funcs, "bad pointer read in %s (from %#x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i); } } else @@ -969,11 +960,11 @@ reeval: break; case OP_CSTATE: - externs->cstateop(&progfuncs->funcs, OPA->_float, OPB->_float, pr_xfunction - pr_cp_functions); + externs->cstateop(&progfuncs->funcs, OPA->_float, OPB->_float, prinst.pr_xfunction - pr_cp_functions); break; case OP_CWSTATE: - externs->cwstateop(&progfuncs->funcs, OPA->_float, OPB->_float, pr_xfunction - pr_cp_functions); + externs->cwstateop(&progfuncs->funcs, OPA->_float, OPB->_float, prinst.pr_xfunction - pr_cp_functions); break; case OP_THINKTIME: @@ -994,7 +985,7 @@ reeval: errorif (QCPOINTERWRITEFAIL(i, sizeof(float))) { prinst.pr_xstatement = st-pr_statements; - PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), i, (unsigned)prinst.addressableused); + PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, (unsigned)prinst.addressableused); } ptr = QCPOINTERM(i); OPC->_float = ptr->_float *= OPA->_float; @@ -1004,7 +995,7 @@ reeval: errorif (QCPOINTERWRITEFAIL(i, sizeof(float))) { prinst.pr_xstatement = st-pr_statements; - PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), i, (unsigned)prinst.addressableused); + PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, (unsigned)prinst.addressableused); } ptr = QCPOINTERM(i); tmpf = OPA->_float; //don't break on vec*=vec_x; @@ -1020,7 +1011,7 @@ reeval: errorif (QCPOINTERWRITEFAIL(i, sizeof(float))) { prinst.pr_xstatement = st-pr_statements; - PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), i, (unsigned)prinst.addressableused); + PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, (unsigned)prinst.addressableused); } ptr = QCPOINTERM(i); OPC->_float = ptr->_float /= OPA->_float; @@ -1038,7 +1029,7 @@ reeval: errorif (QCPOINTERWRITEFAIL(i, sizeof(float))) { prinst.pr_xstatement = st-pr_statements; - PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), i, (unsigned)prinst.addressableused); + PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, (unsigned)prinst.addressableused); } ptr = QCPOINTERM(i); OPC->_float = ptr->_float += OPA->_float; @@ -1048,7 +1039,7 @@ reeval: errorif (QCPOINTERWRITEFAIL(i, sizeof(float))) { prinst.pr_xstatement = st-pr_statements; - PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), i, (unsigned)prinst.addressableused); + PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, (unsigned)prinst.addressableused); } ptr = QCPOINTERM(i); OPC->_vector[0] = ptr->_vector[0] += OPA->_vector[0]; @@ -1068,7 +1059,7 @@ reeval: errorif (QCPOINTERWRITEFAIL(i, sizeof(float))) { prinst.pr_xstatement = st-pr_statements; - PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), i, (unsigned)prinst.addressableused); + PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, (unsigned)prinst.addressableused); } ptr = QCPOINTERM(i); OPC->_float = ptr->_float -= OPA->_float; @@ -1078,7 +1069,7 @@ reeval: errorif (QCPOINTERWRITEFAIL(i, sizeof(float))) { prinst.pr_xstatement = st-pr_statements; - PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), i, (unsigned)prinst.addressableused); + PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, (unsigned)prinst.addressableused); } ptr = QCPOINTERM(i); OPC->_vector[0] = ptr->_vector[0] -= OPA->_vector[0]; @@ -1093,7 +1084,7 @@ reeval: errorif (QCPOINTERWRITEFAIL(i, sizeof(float))) { prinst.pr_xstatement = st-pr_statements; - PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), i, (unsigned)prinst.addressableused); + PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, (unsigned)prinst.addressableused); } ptr = QCPOINTERM(i); ptr->_float = (int)ptr->_float | (int)OPA->_float; @@ -1106,7 +1097,7 @@ reeval: errorif (QCPOINTERWRITEFAIL(i, sizeof(float))) { prinst.pr_xstatement = st-pr_statements; - PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), i, (unsigned)prinst.addressableused); + PR_RunError (&progfuncs->funcs, "bad pointer write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), i, (unsigned)prinst.addressableused); } ptr = QCPOINTERM(i); ptr->_float = (int)ptr->_float & ~(int)OPA->_float; @@ -1267,7 +1258,7 @@ reeval: //its theoretically a more powerful load... but untyped? //or is it meant to be an LEA instruction (that could simply be switched with OP_GLOAD_I) prinst.pr_xstatement = st-pr_statements; - PR_RunError (&progfuncs->funcs, "OP_GADDRESS not implemented (found in %s)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); + PR_RunError (&progfuncs->funcs, "OP_GADDRESS not implemented (found in %s)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)); break; case OP_GLOAD_I: case OP_GLOAD_F: @@ -1278,7 +1269,7 @@ reeval: errorif (OPA->_int < 0 || OPA->_int*4 >= current_progstate->globals_size) { prinst.pr_xstatement = st-pr_statements; - PR_RunError (&progfuncs->funcs, "bad indexed global read in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPA->_int, current_progstate->globals_size); + PR_RunError (&progfuncs->funcs, "bad indexed global read in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), OPA->_int, current_progstate->globals_size); } ptr = ((eval_t *)&glob[OPA->_int]); OPC->_int = ptr->_int; @@ -1287,7 +1278,7 @@ reeval: errorif (OPA->_int < 0 || (OPA->_int+2)*4 >= current_progstate->globals_size) { prinst.pr_xstatement = st-pr_statements; - PR_RunError (&progfuncs->funcs, "bad indexed global read in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPA->_int, current_progstate->globals_size); + PR_RunError (&progfuncs->funcs, "bad indexed global read in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), OPA->_int, current_progstate->globals_size); } ptr = ((eval_t *)&glob[OPA->_int]); OPC->_vector[0] = ptr->_vector[0]; @@ -1303,7 +1294,7 @@ reeval: errorif (OPB->_int < 0 || OPB->_int*4 >= current_progstate->globals_size) { prinst.pr_xstatement = st-pr_statements; - PR_RunError (&progfuncs->funcs, "bad indexed global write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, (unsigned)prinst.addressableused); + PR_RunError (&progfuncs->funcs, "bad indexed global write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), OPB->_int, (unsigned)prinst.addressableused); } ptr = ((eval_t *)&glob[OPB->_int]); ptr->_int = OPA->_int; @@ -1312,7 +1303,7 @@ reeval: errorif (OPB->_int < 0 || (OPB->_int+2)*4 >= current_progstate->globals_size) { prinst.pr_xstatement = st-pr_statements; - PR_RunError (&progfuncs->funcs, "bad indexed global write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), OPB->_int, (unsigned)prinst.addressableused); + PR_RunError (&progfuncs->funcs, "bad indexed global write in %s (%x >= %x)", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name), OPB->_int, (unsigned)prinst.addressableused); } ptr = ((eval_t *)&glob[OPB->_int]); ptr->_vector[0] = OPA->_vector[0]; @@ -1360,7 +1351,7 @@ reeval: if (prinst.pr_xstatement != s) { prinst.pr_xstatement = s; - externs->Printf("Break point hit in %s.\n", PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name)); + externs->Printf("Break point hit in %s.\n", PR_StringToNative(&progfuncs->funcs, prinst.pr_xfunction->s_name)); s = ShowStep(progfuncs, s, NULL, false); st = &pr_statements[s]; //let the user move execution prinst.pr_xstatement = s = st-pr_statements; diff --git a/engine/qclib/pr_edict.c b/engine/qclib/pr_edict.c index 53da99f15..fab95875b 100644 --- a/engine/qclib/pr_edict.c +++ b/engine/qclib/pr_edict.c @@ -188,7 +188,7 @@ void PDECL ED_Free (pubprogfuncs_t *ppf, struct edict_s *ed) if (e->ereftype == ER_FREE) //this happens on start.bsp where an onlyregistered trigger killtargets itself (when all of this sort die after 1 trigger anyway). { if (prinst.pr_depth) - externs->Printf("Tried to free free entity within %s\n", pr_xfunction->s_name+progfuncs->funcs.stringtable); + externs->Printf("Tried to free free entity within %s\n", prinst.pr_xfunction->s_name+progfuncs->funcs.stringtable); else externs->Printf("Engine tried to free free entity\n"); // if (developer.value == 1) @@ -1705,9 +1705,9 @@ char *PR_SaveCallStack (progfuncs_t *progfuncs, char *buf, size_t *bufofs, size_ return buf; } - globalbase = (int *)pr_globals + pr_xfunction->parm_start + pr_xfunction->locals; + globalbase = (int *)pr_globals + prinst.pr_xfunction->parm_start + prinst.pr_xfunction->locals; - prinst.pr_stack[prinst.pr_depth].f = pr_xfunction; + prinst.pr_stack[prinst.pr_depth].f = prinst.pr_xfunction; for (i=prinst.pr_depth ; i>0 ; i--) { f = prinst.pr_stack[i].f; diff --git a/engine/qclib/pr_exec.c b/engine/qclib/pr_exec.c index 704782fd0..a48fbc1e5 100644 --- a/engine/qclib/pr_exec.c +++ b/engine/qclib/pr_exec.c @@ -295,7 +295,7 @@ static void PDECL PR_PrintRelevantLocals(progfuncs_t *progfuncs) return; line = current_progstate->linenums[prinst.pr_xstatement]; - for (st = pr_xfunction->first_statement; st16[st].op != OP_DONE; st++) + for (st = prinst.pr_xfunction->first_statement; st16[st].op != OP_DONE; st++) { if (current_progstate->linenums[st] < line - 2 || current_progstate->linenums[st] > line + 2) continue; //don't go crazy with this. @@ -314,7 +314,7 @@ static void PDECL PR_PrintRelevantLocals(progfuncs_t *progfuncs) if (!ent || !fld) continue; //all this extra code to avoid printing dupes... - for (st2 = st-1; st2 >= pr_xfunction->first_statement; st2--) + for (st2 = st-1; st2 >= prinst.pr_xfunction->first_statement; st2--) { if (current_progstate->linenums[st2] < line - 2 || current_progstate->linenums[st2] > line + 2) continue; @@ -384,13 +384,13 @@ void PDECL PR_StackTrace (pubprogfuncs_t *ppf, int showlocals) progfuncs->funcs.debug_trace = -10; //PR_StringToNative(+via PR_ValueString) has various error conditions that we want to mute instead of causing recursive errors. //point this to the function's locals - globalbase = (int *)pr_globals + pr_xfunction->parm_start + pr_xfunction->locals; + globalbase = (int *)pr_globals + prinst.pr_xfunction->parm_start + prinst.pr_xfunction->locals; for (i=prinst.pr_depth ; i>0 ; i--) { if (i == prinst.pr_depth) { - f = pr_xfunction; + f = prinst.pr_xfunction; st = prinst.pr_xstatement; prnum = prinst.pr_typecurrent; } @@ -511,7 +511,7 @@ int ASMCALL PR_EnterFunction (progfuncs_t *progfuncs, mfunction_t *f, int progsn } st = &prinst.pr_stack[prinst.pr_depth++]; st->s = prinst.pr_xstatement; - st->f = pr_xfunction; + st->f = prinst.pr_xfunction; st->progsnum = progsnum; st->pushed = prinst.spushed; st->stepping = progfuncs->funcs.debug_trace; @@ -548,7 +548,7 @@ int ASMCALL PR_EnterFunction (progfuncs_t *progfuncs, mfunction_t *f, int progsn } } - pr_xfunction = f; + prinst.pr_xfunction = f; return f->first_statement - 1; // offset the s++ } @@ -569,13 +569,13 @@ int ASMCALL PR_LeaveFunction (progfuncs_t *progfuncs) st = &prinst.pr_stack[--prinst.pr_depth]; // restore locals from the stack - c = pr_xfunction->locals; + c = prinst.pr_xfunction->locals; prinst.localstack_used -= c; if (prinst.localstack_used < 0) PR_RunError (&progfuncs->funcs, "PR_ExecuteProgram: locals stack underflow\n"); for (i=0 ; i < c ; i++) - ((int *)pr_globals)[pr_xfunction->parm_start + i] = prinst.localstack[prinst.localstack_used+i]; + ((int *)pr_globals)[prinst.pr_xfunction->parm_start + i] = prinst.localstack[prinst.localstack_used+i]; PR_SwitchProgsParms(progfuncs, st->progsnum); prinst.spushed = st->pushed; @@ -588,14 +588,14 @@ int ASMCALL PR_LeaveFunction (progfuncs_t *progfuncs) prclocks_t cycles; cycles = Sys_GetClock() - st->timestamp; if (cycles > prinst.profilingalert) - externs->Printf("QC call to %s took over a second\n", PR_StringToNative(&progfuncs->funcs,pr_xfunction->s_name)); - pr_xfunction->profiletime += cycles; - pr_xfunction = st->f; + externs->Printf("QC call to %s took over a second\n", PR_StringToNative(&progfuncs->funcs,prinst.pr_xfunction->s_name)); + prinst.pr_xfunction->profiletime += cycles; + prinst.pr_xfunction = st->f; if (prinst.pr_depth) - pr_xfunction->profilechildtime += cycles; + prinst.pr_xfunction->profilechildtime += cycles; } else - pr_xfunction = st->f; + prinst.pr_xfunction = st->f; prinst.localstack_used -= prinst.spushed; return st->s; @@ -617,15 +617,15 @@ ddef32_t *ED_FindLocalOrGlobal(progfuncs_t *progfuncs, const char *name, eval_t case PST_DEFAULT: case PST_KKQWSV: //this gets parms fine, but not locals - if (pr_xfunction) - for (i = 0; i < pr_xfunction->locals; i++) + if (prinst.pr_xfunction) + for (i = 0; i < prinst.pr_xfunction->locals; i++) { - def16 = ED_GlobalAtOfs16(progfuncs, pr_xfunction->parm_start+i); + def16 = ED_GlobalAtOfs16(progfuncs, prinst.pr_xfunction->parm_start+i); if (!def16) continue; if (!strcmp(def16->s_name+progfuncs->funcs.stringtable, name)) { - *val = (eval_t *)&cp->globals[pr_xfunction->parm_start+i]; + *val = (eval_t *)&cp->globals[prinst.pr_xfunction->parm_start+i]; //we need something like this for functions that are not the top layer // *val = (eval_t *)&localstack[localstack_used-pr_xfunction->numparms*4]; @@ -646,15 +646,15 @@ ddef32_t *ED_FindLocalOrGlobal(progfuncs_t *progfuncs, const char *name, eval_t case PST_QTEST: case PST_FTE32: //this gets parms fine, but not locals - if (pr_xfunction) - for (i = 0; i < pr_xfunction->numparms; i++) + if (prinst.pr_xfunction) + for (i = 0; i < prinst.pr_xfunction->numparms; i++) { - def32 = ED_GlobalAtOfs32(progfuncs, pr_xfunction->parm_start+i); + def32 = ED_GlobalAtOfs32(progfuncs, prinst.pr_xfunction->parm_start+i); if (!def32) continue; if (!strcmp(def32->s_name+progfuncs->funcs.stringtable, name)) { - *val = (eval_t *)&cp->globals[pr_xfunction->parm_start+i]; + *val = (eval_t *)&cp->globals[prinst.pr_xfunction->parm_start+i]; //we need something like this for functions that are not the top layer // *val = (eval_t *)&localstack[localstack_used-pr_xfunction->numparms*4]; @@ -1081,7 +1081,7 @@ void SetExecutionToLine(progfuncs_t *progfuncs, int linenum) { int pn = prinst.pr_typecurrent; int snum; - const mfunction_t *f = pr_xfunction; + const mfunction_t *f = prinst.pr_xfunction; switch(current_progstate->structtype) { @@ -1333,7 +1333,7 @@ static const char *lastfile = NULL; int pn = prinst.pr_typecurrent; int i; - const mfunction_t *f = pr_xfunction; + const mfunction_t *f = prinst.pr_xfunction; int faultline; int debugaction; prinst.pr_xstatement = statement; @@ -1342,7 +1342,7 @@ static const char *lastfile = NULL; { PR_PrintStatement(progfuncs, statement); if (fatal) - progfuncs->funcs.debug_trace = DEBUG_TRACE_ABORT; + progfuncs->funcs.debug_trace = DEBUG_TRACE_ABORTERROR; return statement; } @@ -1418,7 +1418,7 @@ static const char *lastfile = NULL; if (debugaction == DEBUG_TRACE_NORESUME) continue; - else if(debugaction == DEBUG_TRACE_ABORT) + else if(debugaction == DEBUG_TRACE_ABORTERROR) progfuncs->funcs.parms->Abort ("%s", fault?fault:"Debugger Abort"); else if (debugaction == DEBUG_TRACE_OFF) { @@ -1464,7 +1464,7 @@ int PR_HandleFault (pubprogfuncs_t *ppf, char *error, ...) if (resumestatement == 0) { PR_AbortStack(ppf); - return prinst.continuestatement; + return -1; // ppf->parms->Abort ("%s", string); } return resumestatement; @@ -1754,7 +1754,6 @@ static void PR_ExecuteCode (progfuncs_t *progfuncs, int s) // prinst->watch_ptr = NULL; } - prinst.continuestatement = -1; #ifdef QCJIT if (current_progstate->jit) { @@ -1913,7 +1912,7 @@ struct qcthread_s *PDECL PR_ForkStack(pubprogfuncs_t *ppf) for (i = 0,localsoffset=0; i < ed; i++) { if (i+1 == prinst.pr_depth) - f = pr_xfunction; + f = prinst.pr_xfunction; else f = prinst.pr_stack[i+1].f; localsoffset += f->locals; //this is where it crashes @@ -1926,7 +1925,7 @@ struct qcthread_s *PDECL PR_ForkStack(pubprogfuncs_t *ppf) thread->fstack[i-ed].statement = prinst.pr_stack[i].s; if (i+1 == prinst.pr_depth) - f = pr_xfunction; + f = prinst.pr_xfunction; else f = prinst.pr_stack[i+1].f; localsoffset += f->locals; @@ -1936,7 +1935,7 @@ struct qcthread_s *PDECL PR_ForkStack(pubprogfuncs_t *ppf) for (i = prinst.pr_depth - 1; i >= ed ; i--) { if (i+1 == prinst.pr_depth) - f = pr_xfunction; + f = prinst.pr_xfunction; else f = prinst.pr_stack[i+1].f; localsoffset -= f->locals; @@ -1950,7 +1949,7 @@ struct qcthread_s *PDECL PR_ForkStack(pubprogfuncs_t *ppf) for (i = ed; i < prinst.pr_depth ; i++) //we need to get the locals back to how they were. { if (i+1 == prinst.pr_depth) - f = pr_xfunction; + f = prinst.pr_xfunction; else f = prinst.pr_stack[i+1].f; @@ -1963,7 +1962,7 @@ struct qcthread_s *PDECL PR_ForkStack(pubprogfuncs_t *ppf) thread->lstackused = localsoffset - baselocalsoffset; thread->xstatement = prinst.pr_xstatement; - thread->xfunction = pr_xfunction - current_progstate->functions; + thread->xfunction = prinst.pr_xfunction - current_progstate->functions; thread->xprogs = prinst.pr_typecurrent; return thread; @@ -1973,9 +1972,10 @@ void PDECL PR_ResumeThread (pubprogfuncs_t *ppf, struct qcthread_s *thread) { progfuncs_t *progfuncs = (progfuncs_t*)ppf; mfunction_t *f, *oldf; - int i,l,ls; + int i,l,ls, olds; progsnum_t initial_progs; int oldexitdepth; + int *glob; int s; #ifndef QCGC @@ -2006,7 +2006,7 @@ void PDECL PR_ResumeThread (pubprogfuncs_t *ppf, struct qcthread_s *thread) { if (prinst.pr_depth == prinst.exitdepth) { - prinst.pr_stack[prinst.pr_depth].f = pr_xfunction; + prinst.pr_stack[prinst.pr_depth].f = prinst.pr_xfunction; prinst.pr_stack[prinst.pr_depth].s = prinst.pr_xstatement; prinst.pr_stack[prinst.pr_depth].progsnum = initial_progs; } @@ -2018,13 +2018,19 @@ void PDECL PR_ResumeThread (pubprogfuncs_t *ppf, struct qcthread_s *thread) } if (i+1 == thread->fstackdepth) + { f = &pr_cp_functions[fnum]; + glob = (int*)pr_globals; + } else + { f = pr_progstate[thread->fstack[i+1].progsnum].functions + thread->fstack[i+1].fnum; + glob = (int*)pr_progstate[thread->fstack[i+1].progsnum].globals; + } for (l = 0; l < f->locals; l++) { - prinst.localstack[prinst.localstack_used++] = ((int *)pr_globals)[f->parm_start + l]; - ((int *)pr_globals)[f->parm_start + l] = thread->lstack[ls++]; + prinst.localstack[prinst.localstack_used++] = glob[f->parm_start + l]; + glob[f->parm_start + l] = thread->lstack[ls++]; } prinst.pr_depth++; @@ -2048,8 +2054,9 @@ void PDECL PR_ResumeThread (pubprogfuncs_t *ppf, struct qcthread_s *thread) // PR_EnterFunction (progfuncs, f, initial_progs); - oldf = pr_xfunction; - pr_xfunction = f; + oldf = prinst.pr_xfunction; + olds = prinst.pr_xstatement; + prinst.pr_xfunction = f; s = thread->xstatement; #ifndef QCGC @@ -2065,15 +2072,16 @@ void PDECL PR_ResumeThread (pubprogfuncs_t *ppf, struct qcthread_s *thread) #endif prinst.exitdepth = oldexitdepth; - pr_xfunction = oldf; + prinst.pr_xfunction = oldf; + prinst.pr_xstatement = olds; } void PDECL PR_AbortStack (pubprogfuncs_t *ppf) { progfuncs_t *progfuncs = (progfuncs_t*)ppf; - while(prinst.pr_depth > prinst.exitdepth+1) + while(prinst.pr_depth > prinst.exitdepth) PR_LeaveFunction(progfuncs); - prinst.continuestatement = 0; + prinst.pr_xstatement = -1; //should make the loop abort. } pbool PDECL PR_GetBuiltinCallInfo (pubprogfuncs_t *ppf, int *builtinnum, char *function, size_t sizeoffunction) diff --git a/engine/qclib/progsint.h b/engine/qclib/progsint.h index ee3ee4f42..5b424c572 100644 --- a/engine/qclib/progsint.h +++ b/engine/qclib/progsint.h @@ -160,13 +160,11 @@ typedef struct prinst_s //step-by-step debug state int debugstatement; - int continuestatement; int exitdepth; pbool profiling; prclocks_t profilingalert; //one second, in cpu clocks mfunction_t *pr_xfunction; //active function -#define pr_xfunction prinst.pr_xfunction int pr_xstatement; //active statement //pr_edict.c diff --git a/engine/qclib/progslib.h b/engine/qclib/progslib.h index 8ad0c525d..774170cf1 100644 --- a/engine/qclib/progslib.h +++ b/engine/qclib/progslib.h @@ -73,7 +73,8 @@ enum { DEBUG_TRACE_INTO, //debug into functions DEBUG_TRACE_OVER, //switch debugging off while executing child functions (and back on afterwards) DEBUG_TRACE_OUT, //keep running until the end of the current function (trigger single-stepping again at that point) - DEBUG_TRACE_ABORT, //give up with an endgame. + DEBUG_TRACE_ABORTERROR, //give up with an endgame. +// DEBUG_TRACE_ABORTSTACK, //stop executing, without any errors. DEBUG_TRACE_NORESUME //line number or something changed, but we should still be sitting at the debugger. }; diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 453603a6d..f877f4dbd 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -8859,6 +8859,7 @@ void QCBUILTIN PF_sv_pointparticles(pubprogfuncs_t *prinst, struct globalvars_s void PRSV_RunThreads(void) { struct globalvars_s *pr_globals; + edict_t *ed; qcstate_t *state = qcthreads, *next; qcthreads = NULL; @@ -8875,9 +8876,19 @@ void PRSV_RunThreads(void) { //call it and forget it ever happened. The Sleep biltin will recreate if needed. pr_globals = PR_globals(svprogfuncs, PR_CURRENT); - pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, EDICT_NUM_UB(svprogfuncs, state->self)); - pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, EDICT_NUM_UB(svprogfuncs, state->other)); - G_FLOAT(OFS_RETURN) = state->returnval; + //restore the thread's self variable, if applicable. + ed = PROG_TO_EDICT(svprogfuncs, state->self); + if (ed->xv->uniquespawnid != state->selfid) + ed = svprogfuncs->edicttable[0]; + pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ed); + + //restore the thread's other variable, if applicable + ed = PROG_TO_EDICT(svprogfuncs, state->other); + if (ed->xv->uniquespawnid != state->otherid) + ed = svprogfuncs->edicttable[0]; + pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, ed); + + G_FLOAT(OFS_RETURN) = state->returnval; //return value of fork or sleep svprogfuncs->RunThread(svprogfuncs, state->thread); svprogfuncs->parms->memfree(state->thread); diff --git a/engine/server/sv_ents.c b/engine/server/sv_ents.c index 8a5bdb619..2812bf4a1 100644 --- a/engine/server/sv_ents.c +++ b/engine/server/sv_ents.c @@ -289,7 +289,8 @@ static void SV_EmitDeltaEntIndex(sizebuf_t *msg, unsigned int entnum, qboolean r void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber) { #ifdef PEXT_CSQC - qbyte messagebuffer[MAX_DATAGRAM]; + static float throttle; + qbyte messagebuffer[MAX_OVERALLMSGLEN]; int en; int currentsequence = client->netchan.outgoing_sequence; globalvars_t *pr_globals; @@ -388,8 +389,12 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber) PR_ExecuteProgram(svprogfuncs, ent->xv->SendEntity); if (G_INT(OFS_RETURN)) //0 means not to tell the client about it. { + //FIXME: don't overflow MAX_DATAGRAM... unless its too big anyway... if (msg->cursize + csqcmsgbuffer.cursize+5 >= msg->maxsize) { + //warn when the message is larger than the user's max size.. + if (csqcmsgbuffer.cursize+5 > msg->maxsize) + Con_ThrottlePrintf(&throttle, 0, "CSQC update of entity %i(%s) is larger than user %s's maximum datagram size (%u > %u).\n", entnum, PR_GetString(svprogfuncs, ent->v->classname), client->name, csqcmsgbuffer.cursize, msg->maxsize-5); if (csqcmsgbuffer.cursize < 32) break; continue;