diff --git a/engine/Makefile b/engine/Makefile index 062f327f1..b029bd78c 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -60,6 +60,8 @@ ifeq ($(FTE_TARGET),win32_sdl) FTE_TARGET=win32_SDL endif +USER_TARGET:=$(FTE_TARGET) + DROID_NDK_PATH?=~/droid/android-ndk-r6b DROID_SDK_PATH?=~/droid/android-sdk-linux_x86 ANT?=ant @@ -672,24 +674,56 @@ endif ifeq ($(FTE_TARGET),nacl) OGGVORBISLDFLAGS= + NARCH ?= x86_32 ifeq ($(shell uname -o 2>&1 | grep Cygwin),) - CC=$(NACL_SDK_ROOT)/toolchain/linux_x86_newlib/bin/i686-nacl-gcc -DNACL -m$(BITS) - STRIP=$(NACL_SDK_ROOT)/toolchain/linux_x86_newlib/bin/i686-nacl-strip + MYOS=linux else - CC=$(NACL_SDK_ROOT)/toolchain/win_x86_newlib/bin/i686-nacl-gcc -DNACL -m$(BITS) - STRIP=$(NACL_SDK_ROOT)/toolchain/win_x86_newlib/bin/i686-nacl-strip + MYOS=win + endif + + CC= + STRIP= + ifeq ($(NARCH),x86_32) + CC=$(NACL_SDK_ROOT)/toolchain/$(MYOS)_x86_newlib/bin/i686-nacl-gcc -DNACL -m32 + STRIP=$(NACL_SDK_ROOT)/toolchain/$(MYOS)_x86_newlib/bin/i686-nacl-strip + BITS= + endif + ifeq ($(NARCH),x86_64) + CC=$(NACL_SDK_ROOT)/toolchain/$(MYOS)_x86_newlib/bin/i686-nacl-gcc -DNACL -m64 + STRIP=$(NACL_SDK_ROOT)/toolchain/$(MYOS)_x86_newlib/bin/i686-nacl-strip + BITS= + endif + ifeq ($(NARCH),arm) + CC=$(NACL_SDK_ROOT)/toolchain/$(MYOS)_arm_newlib/bin/arm-nacl-gcc -DNACL + STRIP=$(NACL_SDK_ROOT)/toolchain/$(MYOS)_arm_newlib/bin/arm-nacl-strip + BITS= + endif + ifeq ($(NARCH),pnacl) + CC=$(NACL_SDK_ROOT)/toolchain/$(MYOS)_x86_pnacl/newlib/bin/pnacl-clang -DNACL + STRIP=$(NACL_SDK_ROOT)/toolchain/$(MYOS)_x86_pnacl/newlib/bin/pnacl-strip + STRIPFLAGS= + DO_LD =/cygdrive/c/Windows/system32/cmd /C $(NACL_SDK_ROOT)/toolchain/$(MYOS)_x86_pnacl/newlib/bin/pnacl-clang -o $@ $(LTO_LD) $(WCFLAGS) $(CFLAGS) + BITS= endif BASELDFLAGS = -lm -lppapi_gles2 -lnosys -lppapi IMAGELDFLAGS = - GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) sys_ppapi.o cd_null.o gl_vidppapi.o fs_ppapi.o snd_ppapi.o + GL_CFLAGS+=$(SPEEXCFLAGS) - GLB_DIR=gl_nacl_x86_$(BITS) - GL_EXE_NAME=../fteqw_x86_$(BITS).nexe - GLCL_EXE_NAME=../fteqwcl_x86_$(BITS).nexe - MINGL_DIR=mingl_nacl_x86_$(BITS) - MINGL_EXE_NAME=../fteqw_mingl_x86_$(BITS).nexe + GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SPEEX_OBJS) sys_ppapi.o cd_null.o gl_vidppapi.o fs_ppapi.o snd_ppapi.o + + GLB_DIR=gl_nacl_$(NARCH) + MINGL_DIR=mingl_nacl_$(NARCH) + ifeq ($(NARCH),pnacl) + GL_EXE_NAME=../fteqw.pexe + GLCL_EXE_NAME=../fteqwcl.pexe + MINGL_EXE_NAME=../fteqw_mingl.pexe + else + GL_EXE_NAME=../fteqw_$(NARCH).nexe + GLCL_EXE_NAME=../fteqwcl_$(NARCH).nexe + MINGL_EXE_NAME=../fteqw_mingl_$(NARCH).nexe + endif endif #FTE_TARGET=win32_SDL | FTE_TARGET=win64_SDL (MinGW32 + SDL | MinGW64 + SDL) @@ -1241,32 +1275,6 @@ d3d-profile: @$(MAKE) d3d-tmp TYPE=_clsv-profile OUT_DIR="$(PROFILE_DIR)/$(D3DB_DIR)" - -npfte-tmprel: reldir - @$(MAKE) $(OUT_DIR)/$(EXE_NAME) OUT_DIR="$(OUT_DIR)" WCFLAGS="$(NPFTE_CFLAGS) $(RELEASE_CFLAGS)" LDFLAGS="$(BASELDFLAGS) $(NPFTE_LDFLAGS) $(LDFLAGS) $(RELEASE_LDFLAGS)" OBJS="NPFTE_OBJS" -npfte-tmpdbg: debugdir - @$(MAKE) $(OUT_DIR)/$(EXE_NAME) OUT_DIR="$(OUT_DIR)" WCFLAGS="$(NPFTE_CFLAGS) $(DEBUG_CFLAGS)" LDFLAGS="$(BASELDFLAGS) $(NPFTE_LDFLAGS) $(LDFLAGS) $(DEBUG_LDFLAGS)" OBJS="NPFTE_OBJS" -npfte-rel: - @$(MAKE) npfte-tmprel OUT_DIR="$(RELEASE_DIR)/$(NPFTEB_DIR)w32" EXE_NAME="../npfte.dll" PRECOMPHEADERS="" FTE_TARGET=win32 - @$(MAKE) npfte-tmprel OUT_DIR="$(RELEASE_DIR)/$(NPFTEB_DIR)l32" EXE_NAME="../npfte32.so" PRECOMPHEADERS="" FTE_TARGET=linux32 - @$(MAKE) npfte-tmprel OUT_DIR="$(RELEASE_DIR)/$(NPFTEB_DIR)l64" EXE_NAME="../npfte64.so" PRECOMPHEADERS="" FTE_TARGET=linux64 - cp $(RELEASE_DIR)/npfte.dll npfte/plugins - cp $(RELEASE_DIR)/npfte32.so npfte/plugins - cp $(RELEASE_DIR)/npfte64.so npfte/plugins - cd npfte && zip $(abspath $(RELEASE_DIR)/npfte.xpi) install.rdf plugins/npfte.dll plugins/npfte32.so plugins/npfte64.so - rm -rf /tmp/npfte - mkdir /tmp/npfte - cp $(RELEASE_DIR)/npfte.dll /tmp/npfte - cp ./npfte/manifest.json /tmp/npfte - -cd $(RELEASE_DIR)/ && ../npfte/crxmake.sh /tmp/npfte ../npfte/chrome.pem - rm -rf /tmp/npfte -npfte-dbg: - @$(MAKE) npfte-tmpdbg OUT_DIR="$(DEBUG_DIR)/$(NPFTEB_DIR)w32" EXE_NAME="../npfte.dll" PRECOMPHEADERS="" FTE_TARGET=win32 - @$(MAKE) npfte-tmpdbg OUT_DIR="$(DEBUG_DIR)/$(NPFTEB_DIR)l32" EXE_NAME="../npfte32.so" PRECOMPHEADERS="" FTE_TARGET=linux32 - @$(MAKE) npfte-tmpdbg OUT_DIR="$(DEBUG_DIR)/$(NPFTEB_DIR)l64" EXE_NAME="../npfte64.so" PRECOMPHEADERS="" FTE_TARGET=linux64 -npfte-profile: - @$(MAKE) npfte-tmp TYPE=_npfte-profile OUT_DIR="$(PROFILE_DIR)/$(NPFTEB_DIR)" - glcl-tmp: @$(MAKE) $(TYPE) OUT_DIR="$(OUT_DIR)" EXE_NAME="$(GLCL_EXE_NAME)" WCFLAGS="$(GL_CFLAGS)" LDFLAGS="$(GL_LDFLAGS) $(LDFLAGS)" SOBJS="$(GLCL_OBJS)" gl-tmp: @@ -1314,6 +1322,7 @@ m-profile: .PHONY: m-tmp mcl-tmp mingl-tmp glcl-tmp gl-tmp sv-tmp _clsv-dbg _clsv-rel _cl-dbg _cl-rel _out-rel _out-dbg + ifdef windir debugdir: @-mkdir -p $(subst /,\, $(OUT_DIR)) @@ -1350,18 +1359,19 @@ help: @-echo "'gl-???' (OpenGL rendering + Built-in Server)" @-echo "'m-???' (Merged client, OpenGL & D3D rendering + Dedicated server)" @-echo "'mingl-???' (Minimal featured OpenGL render)" - @-echo "'npfte-???' (FTE_TARGET=win32 only, for now) (QuakeTV Firefox/Netscape browser plugin)" @-echo "'d3d-???' (for windows builds)" @-echo "'mcl-???' (currently broken)" @-echo "'glcl-???' (currently broken)" - @-echo "'droid-???' (build Android package)" + @-echo "'droid-???' (cross compiles Android package)" + @-echo "'npfte-???' (cross compiles QuakeTV Firefox/Netscape browser plugin)" + @-echo "'nacl-???' (cross compiles QuakeTV Firefox/Netscape browser plugin)" @-echo "" @-echo "Cross targets can be specified with FTE_TARGET=blah" @-echo "linux32, linux64 specify specific x86 archs" @-echo "SDL - Attempt to use sdl for the current target" @-echo "win32 - Mingw compile for win32" @-echo "vc - Attempts to use msvc8+ to compile. Note: uses profile guided optimisations. You must build+run the relevent profile target before a release target will compile properly. Debug doesn't care." - @-echo "android is different - use 'make droid-help' for explicit help." + @-echo "android, npfte, nacl targets explicitly cross compile, and should generally not be given an FTE_TARGET." install: -cp debug/*.* /opt/quake/ @@ -1383,6 +1393,54 @@ clean: distclean: clean -rm -f droid/ftekeystore + +################################################# +#npfte + +npfte-tmprel: reldir + @$(MAKE) $(OUT_DIR)/$(EXE_NAME) OUT_DIR="$(OUT_DIR)" WCFLAGS="$(NPFTE_CFLAGS) $(RELEASE_CFLAGS)" LDFLAGS="$(NPFTE_LDFLAGS) $(LDFLAGS) $(RELEASE_LDFLAGS)" OBJS="NPFTE_OBJS" +npfte-tmpdbg: debugdir + @$(MAKE) $(OUT_DIR)/$(EXE_NAME) OUT_DIR="$(OUT_DIR)" WCFLAGS="$(NPFTE_CFLAGS) $(DEBUG_CFLAGS)" LDFLAGS="$(NPFTE_LDFLAGS) $(LDFLAGS) $(DEBUG_LDFLAGS)" OBJS="NPFTE_OBJS" +npfte-rel: + ifeq ($(USER_TARGET),) + @$(MAKE) npfte-tmprel OUT_DIR="$(RELEASE_DIR)/$(NPFTEB_DIR)w32" EXE_NAME="../npfte.dll" PRECOMPHEADERS="" FTE_TARGET=win32 + @$(MAKE) npfte-tmprel OUT_DIR="$(RELEASE_DIR)/$(NPFTEB_DIR)l32" EXE_NAME="../npfte32.so" PRECOMPHEADERS="" FTE_TARGET=linux32 + @$(MAKE) npfte-tmprel OUT_DIR="$(RELEASE_DIR)/$(NPFTEB_DIR)l64" EXE_NAME="../npfte64.so" PRECOMPHEADERS="" FTE_TARGET=linux64 + -cp $(RELEASE_DIR)/npfte.dll npfte/plugins + -cp $(RELEASE_DIR)/npfte32.so npfte/plugins + -cp $(RELEASE_DIR)/npfte64.so npfte/plugins + cd npfte && zip $(abspath $(RELEASE_DIR)/npfte.xpi) install.rdf plugins/npfte.dll plugins/npfte32.so plugins/npfte64.so + rm -rf /tmp/npfte + mkdir /tmp/npfte + cp $(RELEASE_DIR)/npfte.dll /tmp/npfte + cp ./npfte/manifest.json /tmp/npfte + -cd $(RELEASE_DIR)/ && ../npfte/crxmake.sh /tmp/npfte ../npfte/chrome.pem + rm -rf /tmp/npfte +npfte-dbg: + @$(MAKE) npfte-tmpdbg OUT_DIR="$(DEBUG_DIR)/$(NPFTEB_DIR)w32" EXE_NAME="../npfte.dll" PRECOMPHEADERS="" FTE_TARGET=win32 + @$(MAKE) npfte-tmpdbg OUT_DIR="$(DEBUG_DIR)/$(NPFTEB_DIR)l32" EXE_NAME="../npfte32.so" PRECOMPHEADERS="" FTE_TARGET=linux32 + @$(MAKE) npfte-tmpdbg OUT_DIR="$(DEBUG_DIR)/$(NPFTEB_DIR)l64" EXE_NAME="../npfte64.so" PRECOMPHEADERS="" FTE_TARGET=linux64 +npfte-profile: + @$(MAKE) npfte-tmp TYPE=_npfte-profile OUT_DIR="$(PROFILE_DIR)/$(NPFTEB_DIR)" + + +################################################# +#nacl shortcut + +nacl-rel: + @$(MAKE) gl-rel FTE_TARGET=nacl NARCH=x86_32 + @$(MAKE) gl-rel FTE_TARGET=nacl NARCH=x86_64 + @$(MAKE) gl-rel FTE_TARGET=nacl NARCH=arm + @$(MAKE) gl-rel FTE_TARGET=nacl NARCH=pnacl +nacl-dbg: + @$(MAKE) gl-dbg FTE_TARGET=nacl NARCH=x86_32 + @$(MAKE) gl-dbg FTE_TARGET=nacl NARCH=x86_64 + @$(MAKE) gl-dbg FTE_TARGET=nacl NARCH=arm + @$(MAKE) gl-dbg FTE_TARGET=nacl NARCH=pnacl + +################################################# +#android + #building for android will require: #download android sdk+ndk #ant installed diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index 4fec0e7f2..5fb5bc05d 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -1141,7 +1141,6 @@ entity_state_t *CL_FindOldPacketEntity(int num) } #ifdef NQPROT -entity_state_t defaultstate; void DP5_ParseDelta(entity_state_t *s) { int bits; @@ -1166,7 +1165,7 @@ void DP5_ParseDelta(entity_state_t *s) { int num; num = s->number; - *s = defaultstate; + *s = nullentitystate; s->trans = 255; s->scale = 16; s->number = num; @@ -1317,7 +1316,7 @@ void CLDP_ParseDarkPlaces5Entities(void) //the things I do.. :o( if (read >= MAX_EDICTS) Host_EndGame("Too many entities.\n"); - from = &defaultstate; + from = &nullentitystate; for (oldi=0 ; oldistatus == DL_FINISHED) - zip = zipfilefuncs.OpenNew(dl->file, dl->url); - else - zip = NULL; - /*the zip code will have eaten the file handle*/ - dl->file = NULL; - if (zip) + char *q = strchr(dl->url, '?'); + char *ext; + if (dl->file && dl->status == DL_FINISHED) { - if (dl->user_ctx) + if (q) *q = '0'; + ext = COM_FileExtension(dl->url); + if (q) *q = '?'; + if (!stricmp(ext, "zip")) { - vfsfile_t *in, *out; - flocation_t loc; - qboolean found = false; - int crc; - - found = zipfilefuncs.FindFile(zip, &loc, dl->user_ctx, NULL); - if (!found) +#ifdef AVAIL_ZLIB + if (dl->status == DL_FINISHED) + zip = zipfilefuncs.OpenNew(dl->file, dl->url); + else + zip = NULL; + if (zip) { - char *s = COM_SkipPath(dl->user_ctx); - if (s != dl->user_ctx) - found = zipfilefuncs.FindFile(zip, &loc, s, NULL); - } - - if (found) - { - in = zipfilefuncs.OpenVFS(zip, &loc, "rb"); - if (in) + dl->file = NULL; //file is now owned by the zip context. + if (dl->user_ctx) { - char local[MAX_OSPATH]; - FS_GenCachedPakName(dl->user_ctx, va("%i", dl->user_num), local, sizeof(local)); - FS_CreatePath(local, FS_ROOT); - out = FS_OpenVFS(local, "wb", FS_ROOT); - if (out) + vfsfile_t *in, *out; + flocation_t loc; + qboolean found = false; + int crc; + + found = zipfilefuncs.FindFile(zip, &loc, dl->user_ctx, NULL); + if (!found) { - char buffer[8192]; - int read; - for(;;) + char *s = COM_SkipPath(dl->user_ctx); + if (s != dl->user_ctx) + found = zipfilefuncs.FindFile(zip, &loc, s, NULL); + } + + if (found) + { + in = zipfilefuncs.OpenVFS(zip, &loc, "rb"); + if (in) { - read = VFS_READ(in, buffer, sizeof(buffer)); - if (read <= 0) - break; - if (VFS_WRITE(out, buffer, read) != read) + char local[MAX_OSPATH]; + FS_GenCachedPakName(dl->user_ctx, va("%i", dl->user_num), local, sizeof(local)); + FS_CreatePath(local, FS_ROOT); + out = FS_OpenVFS(local, "wb", FS_ROOT); + if (out) { - Con_Printf("write failed writing %s. disk full?\n", local); - break; + char buffer[8192]; + int read; + for(;;) + { + read = VFS_READ(in, buffer, sizeof(buffer)); + if (read <= 0) + break; + if (VFS_WRITE(out, buffer, read) != read) + { + Con_Printf("write failed writing %s. disk full?\n", local); + break; + } + } + VFS_CLOSE(out); + out = FS_OpenVFS(local, "rb", FS_ROOT); + crc = dl->user_num; + if (!FS_LoadPackageFromFile(out, dl->user_ctx, local, &crc, true, false, true)) + { + if (crc == dl->user_num) + Con_Printf(CON_WARNING "Manifest package \"%s\" is unusable.\n", (char*)dl->user_ctx); + else + Con_Printf(CON_WARNING "Manifest package \"%s\" is unusable or has invalid crc. Stated crc %#x is not calculated crc %#x\n", (char*)dl->user_ctx, dl->user_num, crc); + FS_Remove(local, FS_ROOT); + } } } - VFS_CLOSE(out); - out = FS_OpenVFS(local, "rb", FS_ROOT); - crc = dl->user_num; - if (!FS_LoadPackageFromFile(out, dl->user_ctx, local, &crc, true, false, true)) - { - if (crc == dl->user_num) - Con_Printf(CON_WARNING "Manifest package \"%s\" is unusable.\n", dl->user_ctx); - else - Con_Printf(CON_WARNING "Manifest package \"%s\" is unusable or has invalid crc. Stated crc %#x is not calculated crc %#x\n", dl->user_ctx, dl->user_num, crc); - FS_Remove(local, FS_ROOT); - } + VFS_CLOSE(in); } - } - VFS_CLOSE(in); - } - free(dl->user_ctx); + free(dl->user_ctx); + } + else + { + /*scan it to extract its contents*/ + zipfilefuncs.EnumerateFiles(zip, "*/*.pk3", CL_BootDownload_Extract, zip); + zipfilefuncs.EnumerateFiles(zip, "*/*.pak", CL_BootDownload_Extract, zip); + zipfilefuncs.EnumerateFiles(zip, "*/*/*.pk3", CL_BootDownload_Extract, zip); + zipfilefuncs.EnumerateFiles(zip, "*/*/*.pak", CL_BootDownload_Extract, zip); + } + + /*close it, delete the temp file from disk, etc*/ + zipfilefuncs.ClosePath(zip); + + /*restart the filesystem so those new files can be found*/ + Cmd_ExecuteString("fs_restart\n", RESTRICT_LOCAL); + } +#endif } else { - /*scan it to extract its contents*/ - zipfilefuncs.EnumerateFiles(zip, "*/*.pk3", CL_BootDownload_Extract, zip); - zipfilefuncs.EnumerateFiles(zip, "*/*.pak", CL_BootDownload_Extract, zip); - zipfilefuncs.EnumerateFiles(zip, "*/*/*.pk3", CL_BootDownload_Extract, zip); - zipfilefuncs.EnumerateFiles(zip, "*/*/*.pak", CL_BootDownload_Extract, zip); + //okay, its named directly, write it out as it is + vfsfile_t *out; + int crc, *crcptr = &crc; + char local[MAX_OSPATH]; + + qboolean ispackage = (!stricmp(ext, "pak") || !stricmp(ext, "pk3")); +#ifndef NACL + if (ispackage) + { + FS_GenCachedPakName(dl->user_ctx, va("%i", dl->user_num), local, sizeof(local)); +#else + //nacl permits any files to be listed in the manifest file, as there's no prior files to override/conflict, so don't mess about with crcs etc + crcptr = NULL; + Q_strncpyz(local, dl->user_ctx, sizeof(local)); + if (1) + { +#endif + FS_CreatePath(local, FS_ROOT); + + //write it out + out = FS_OpenVFS(local, "wb", FS_ROOT); + if (!out) + Con_Printf("Unable to open %s for writing\n", local); + else + { + char buffer[65535]; + int read; + for(;;) + { + read = VFS_READ(dl->file, buffer, sizeof(buffer)); + if (read <= 0) + break; + if (VFS_WRITE(out, buffer, read) != read) + { + Con_Printf("write failed writing %s. disk full?\n", local); + break; + } + } + VFS_CLOSE(out); + + if (ispackage) + { + if (crcptr) + { + //load it as a package + out = FS_OpenVFS(local, "rb", FS_ROOT); + if (out) + { + crc = dl->user_num; + if (!FS_LoadPackageFromFile(out, dl->user_ctx, local, crcptr, true, false, true)) + { + if (crc == dl->user_num) + Con_Printf(CON_WARNING "Manifest package \"%s\" is unusable.\n", (char*)dl->user_ctx); + else + Con_Printf(CON_WARNING "Manifest package \"%s\" is unusable or has invalid crc. Stated crc %#x is not calculated crc %#x\n", (char*)dl->user_ctx, dl->user_num, crc); + FS_Remove(local, FS_ROOT); + } + Cmd_ExecuteString("fs_restart\n", RESTRICT_LOCAL); + } + } + else + Cmd_ExecuteString("fs_restart\n", RESTRICT_LOCAL); + } + } + } + else + Con_Printf("File %s isn't a recognised package!\n", (char*)dl->user_ctx); } - - /*close it, delete the temp file from disk, etc*/ - zipfilefuncs.ClosePath(zip); - - /*restart the filesystem so those new files can be found*/ - Cmd_ExecuteString("fs_restart\n", RESTRICT_LOCAL); } if (!--numbootdownloads) @@ -963,7 +1047,9 @@ static void CL_BootDownload_Complete(struct dl_download *dl) static void CL_Manifest_Complete(struct dl_download *dl) { - if (dl->file) + if (!dl->file) + Con_Printf("Unable to load manifest from %s\n", dl->url); + else { vfsfile_t *f; char buffer[1024]; @@ -1002,16 +1088,30 @@ static void CL_Manifest_Complete(struct dl_download *dl) } else { - Con_Printf("Downloading %s from %s\n", fname, Cmd_Argv(2)); - dl = HTTP_CL_Get(Cmd_Argv(2), "", CL_BootDownload_Complete); - if (dl) + int args = Cmd_Argc() - 2; + if (!args) + Con_Printf("No mirrors for \"%s\"\n", fname); + else { - dl->user_ctx = strdup(fname); - dl->user_num = crc; - #ifdef MULTITHREAD - DL_CreateThread(dl, FS_OpenTemp(), CL_BootDownload_Complete); - #endif - numbootdownloads++; + struct dl_download *ndl; +#ifdef NACL + args = 0; //nacl currently depends upon the browser's download cache for all file persistance, which means we want the same file every time. + //there's only one way to do that, sadly. +#else + args = rand() % args; +#endif + Con_Printf("Downloading \"%s\" from \"%s\"\n", fname, Cmd_Argv(2 + args)); + ndl = HTTP_CL_Get(Cmd_Argv(2), "", CL_BootDownload_Complete); + + if (ndl) + { + ndl->user_ctx = strdup(fname); + ndl->user_num = crc; + #ifdef MULTITHREAD + DL_CreateThread(ndl, FS_OpenTemp(), CL_BootDownload_Complete); + #endif + numbootdownloads++; + } } } } @@ -1040,16 +1140,18 @@ qboolean CL_CheckBootDownloads(void) if (man) { const char *fname = com_argv[man+1]; - - Con_Printf("Checking manifest from \"%s\"\n", fname); - - dl = HTTP_CL_Get(fname, token, CL_Manifest_Complete); - if (dl) + if (*fname) { -#ifdef MULTITHREAD - DL_CreateThread(dl, FS_OpenTemp(), CL_Manifest_Complete); -#endif - numbootdownloads++; + Con_Printf("Checking manifest from \"%s\"\n", fname); + + dl = HTTP_CL_Get(fname, "", CL_Manifest_Complete); + if (dl) + { + #ifdef MULTITHREAD + DL_CreateThread(dl, FS_OpenTemp(), CL_Manifest_Complete); + #endif + numbootdownloads++; + } } } @@ -1092,7 +1194,7 @@ qboolean CL_CheckBootDownloads(void) Con_Printf("Attempting to download %s\n", c); - dl = HTTP_CL_Get(c, token, CL_BootDownload_Complete); + dl = HTTP_CL_Get(c, "", CL_BootDownload_Complete); if (dl) { #ifdef MULTITHREAD @@ -1107,6 +1209,8 @@ qboolean CL_CheckBootDownloads(void) #else qboolean CL_CheckBootDownloads(void) { + if (COM_CheckParm("-manifest")) + Con_Printf("download manifests not supported in this build\n"); return true; } #endif diff --git a/engine/client/m_items.c b/engine/client/m_items.c index 7910befbc..12049f0bc 100644 --- a/engine/client/m_items.c +++ b/engine/client/m_items.c @@ -1636,6 +1636,10 @@ void M_Complex_Key(int key, int unicode) { if (bindingactive) { + //don't let key 0 be bound here. unicode-only keys are also not bindable. + if (key == 0) + return; + if (mgt == MGT_HEXEN2) S_LocalSound ("raven/menu1.wav"); else diff --git a/engine/client/m_options.c b/engine/client/m_options.c index 634f88c3d..9c9c65864 100644 --- a/engine/client/m_options.c +++ b/engine/client/m_options.c @@ -516,19 +516,18 @@ typedef struct fpsmenuinfo_s static void ApplyPreset (int presetnum) { int i; - // TODO: work backwards and only set cvars once - for (i = 0; i <= presetnum; i++) - { - Cbuf_AddText(presetexec[i], RESTRICT_LOCAL); - Cbuf_AddText("\n", RESTRICT_LOCAL); - Cbuf_Execute(); // hack - } + //this function is written backwards, to ensure things work properly in configs etc. //make sure the presets always set up particles correctly for certain other game modes. if (M_GameType() == MGT_HEXEN2) { - Cbuf_AddText("r_particledesc $r_particledesc h2part\n", RESTRICT_LOCAL); - Cbuf_Execute(); + Cbuf_InsertText("r_particledesc $r_particledesc h2part\n", RESTRICT_LOCAL, false); + } + + // TODO: work backwards and only set cvars once + for (i = presetnum; i >= 0; i--) + { + Cbuf_InsertText(presetexec[i], RESTRICT_LOCAL, true); } forcesaveprompt = true; } diff --git a/engine/client/merged.h b/engine/client/merged.h index 7290911b2..0514695ef 100644 --- a/engine/client/merged.h +++ b/engine/client/merged.h @@ -150,7 +150,7 @@ void Draw_FunString(int x, int y, const void *str); void Draw_AltFunString(int x, int y, const void *str); void Draw_FunStringWidth(int x, int y, const void *str, int width); -int r_regsequence; +extern int r_regsequence; #ifdef SERVERONLY #define Mod_Q1LeafPVS Mod_LeafPVS diff --git a/engine/client/net_master.c b/engine/client/net_master.c index d7b2d0ba0..598216095 100644 --- a/engine/client/net_master.c +++ b/engine/client/net_master.c @@ -45,6 +45,7 @@ void MasterInfo_RemoveAllPlayers(void); master_t *master; player_t *mplayers; serverinfo_t *firstserver; +struct selectedserver_s selectedserver; static serverinfo_t **visibleservers; static int numvisibleservers; diff --git a/engine/client/p_script.c b/engine/client/p_script.c index b9ec71b5b..e1720cd65 100644 --- a/engine/client/p_script.c +++ b/engine/client/p_script.c @@ -2201,9 +2201,6 @@ static qboolean PScript_InitParticles (void) pscripttmesh.st_array = pscripttexcoords; pscripttmesh.colors4f_array = pscriptcolours; pscripttmesh.indexes = pscripttriindexes; - - if (fallback) - fallback->InitParticles(); return true; } @@ -2237,6 +2234,7 @@ static void PScript_Shutdown (void) BZ_Free (part_type); part_type = NULL; part_run_list = NULL; + fallback = NULL; BZ_Free (particles); BZ_Free (beams); diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index 2245e7bc3..fc26abc80 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -4602,7 +4602,9 @@ static struct { {"gethostcachenumber", PF_cl_gethostcachenumber, 621}, {"gethostcacheindexforkey", PF_cl_gethostcacheindexforkey,622}, {"addwantedhostcachekey", PF_cl_addwantedhostcachekey, 623}, +#ifdef CL_MASTER {"getextresponse", PF_cl_getextresponse, 624}, +#endif {"netaddress_resolve", PF_netaddress_resolve, 625}, {"sprintf", PF_sprintf, 627}, @@ -5402,7 +5404,7 @@ qboolean CSQC_DrawView(void) if (!csqcg.draw_function || !csqcprogs) return false; - if (cls.state < (csqcg.loadresource?ca_active:ca_onserver) && !CSQC_UnconnectedOkay(false)) + if (cls.state < ca_active && !CSQC_UnconnectedOkay(false)) return false; r_secondaryview = 0; diff --git a/engine/client/pr_menu.c b/engine/client/pr_menu.c index 977099d0c..d471a686c 100644 --- a/engine/client/pr_menu.c +++ b/engine/client/pr_menu.c @@ -1422,7 +1422,9 @@ static struct { {"gethostcachenumber", PF_cl_gethostcachenumber, 621}, {"gethostcacheindexforkey", PF_cl_gethostcacheindexforkey,622}, {"addwantedhostcachekey", PF_cl_addwantedhostcachekey,623}, +#ifdef CL_MASTER {"getextresponse", PF_cl_getextresponse, 624}, +#endif {"netaddress_resolve", PF_netaddress_resolve, 625}, //gap {"sprintf", PF_sprintf, 627}, diff --git a/engine/client/r_2d.c b/engine/client/r_2d.c index f591e3dc1..af0f98cfb 100644 --- a/engine/client/r_2d.c +++ b/engine/client/r_2d.c @@ -312,7 +312,6 @@ mpic_t *R2D_SafeCachePic (char *path) } -char *failedpic; //easier this way mpic_t *R2D_SafePicFromWad (char *name) { char newnamewad[32]; @@ -330,7 +329,6 @@ mpic_t *R2D_SafePicFromWad (char *name) if (!(s->flags & SHADER_NOIMAGE)) return s; - failedpic = name; return NULL; } diff --git a/engine/client/r_part.c b/engine/client/r_part.c index a29d6b008..ca3e02007 100644 --- a/engine/client/r_part.c +++ b/engine/client/r_part.c @@ -61,18 +61,26 @@ void R_Grenadetrail_Callback(struct cvar_s *var, char *oldvalue) } } -particleengine_t pe_null; -particleengine_t pe_classic; +extern particleengine_t pe_null; +#ifdef PSET_CLASSIC +extern particleengine_t pe_classic; +#endif particleengine_t pe_darkplaces; particleengine_t pe_qmb; -particleengine_t pe_script; +#ifdef PSET_SCRIPT +extern particleengine_t pe_script; +#endif particleengine_t *particlesystem[] = { +#ifdef PSET_SCRIPT &pe_script, +#endif &pe_darkplaces, &pe_qmb, +#ifdef PSET_CLASSIC &pe_classic, +#endif &pe_null, NULL, }; diff --git a/engine/client/r_surf.c b/engine/client/r_surf.c index 82a7aa159..e5addd10e 100644 --- a/engine/client/r_surf.c +++ b/engine/client/r_surf.c @@ -45,7 +45,7 @@ unsigned blocklights[3*MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE]; lightmapinfo_t **lightmap; int numlightmaps; -mleaf_t *r_vischain; // linked list of visible leafs +extern mleaf_t *r_vischain; // linked list of visible leafs extern cvar_t r_stains; extern cvar_t r_loadlits; @@ -2430,6 +2430,12 @@ int Surf_NewLightmaps(int count, int width, int height, qboolean deluxe) if (!count) return -1; + if (deluxe && (count & 1)) + { + deluxe = false; + Con_Print("WARNING: Deluxemapping with odd number of lightmaps\n"); + } + i = numlightmaps + count; lightmap = BZ_Realloc(lightmap, sizeof(*lightmap)*(i)); while(i > first) diff --git a/engine/client/render.h b/engine/client/render.h index 72f78b5cd..2616ccada 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -490,7 +490,7 @@ enum { RSPEED_MAX }; -int rspeeds[RSPEED_MAX]; +extern int rspeeds[RSPEED_MAX]; enum { RQUANT_MSECS, //old r_speeds @@ -506,7 +506,7 @@ enum { RQUANT_MAX }; -int rquant[RQUANT_MAX]; +extern int rquant[RQUANT_MAX]; #define RQuantAdd(type,quant) rquant[type] += quant diff --git a/engine/client/renderer.c b/engine/client/renderer.c index f05d8c9ec..6401632a5 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -11,14 +11,16 @@ refdef_t r_refdef; vec3_t r_origin, vpn, vright, vup; entity_t r_worldentity; entity_t *currententity; //nnggh -model_t *currentmodel; //fixme: remove? or fix. -int sh_shadowframe; //index for msurf->shadowframe int r_framecount; struct texture_s *r_notexture_mip; r_config_t r_config; qboolean r_blockvidrestart; +int r_regsequence; + +int rspeeds[RSPEED_MAX]; +int rquant[RQUANT_MAX]; void R_InitParticleTexture (void); @@ -187,14 +189,15 @@ cvar_t vid_bpp = CVARF ("vid_bpp", "32", CVAR_ARCHIVE | CVAR_RENDERERLATCH); cvar_t vid_desktopsettings = CVARF ("vid_desktopsettings", "0", CVAR_ARCHIVE | CVAR_RENDERERLATCH); -#ifdef NPQTV -cvar_t vid_fullscreen_npqtv = CVARF ("vid_fullscreen", "1", - CVAR_ARCHIVE | CVAR_RENDERERLATCH); -cvar_t vid_fullscreen = CVARF ("vid_fullscreen_embedded", "0", - CVAR_ARCHIVE | CVAR_RENDERERLATCH); +#ifdef NACL +cvar_t vid_fullscreen = CVARF ("vid_fullscreen", "0", + CVAR_ARCHIVE); #else -cvar_t vid_fullscreen = CVARF ("vid_fullscreen", "1", +//these cvars will be given their names when they're registered, based upon whether -plugin was used. this means code can always use vid_fullscreen without caring, but gets saved properly. +cvar_t vid_fullscreen = CVARAF (NULL, "1", "vid_fullscreen", CVAR_ARCHIVE | CVAR_RENDERERLATCH); +cvar_t vid_fullscreen_alternative = CVARF (NULL, "1", + CVAR_ARCHIVE); #endif cvar_t vid_height = CVARF ("vid_height", "0", CVAR_ARCHIVE | CVAR_RENDERERLATCH); @@ -575,8 +578,18 @@ void Renderer_Init(void) Cvar_Register (&vid_renderer, VIDCOMMANDGROUP); Cvar_Register (&vid_wndalpha, VIDCOMMANDGROUP); -#ifdef NPQTV - Cvar_Register (&vid_fullscreen_npqtv, VIDCOMMANDGROUP); +#ifndef NACL + if (COM_CheckParm("-plugin")) + { + vid_fullscreen.name = "vid_fullscreen_embedded"; + vid_fullscreen_alternative.name = "vid_fullscreen_standalone"; + } + else + { + vid_fullscreen.name = "vid_fullscreen_standalone"; + vid_fullscreen_alternative.name = "vid_fullscreen_embedded"; + } + Cvar_Register (&vid_fullscreen_alternative, VIDCOMMANDGROUP); #endif Cvar_Register (&vid_fullscreen, VIDCOMMANDGROUP); Cvar_Register (&vid_bpp, VIDCOMMANDGROUP); @@ -871,11 +884,17 @@ rendererinfo_t dedicatedrendererinfo = { }; rendererinfo_t *pdedicatedrendererinfo = &dedicatedrendererinfo; -rendererinfo_t openglrendererinfo; +#ifdef GLQUAKE +extern rendererinfo_t openglrendererinfo; rendererinfo_t eglrendererinfo; +#endif +#ifdef D3DQUAKE rendererinfo_t d3d9rendererinfo; rendererinfo_t d3d11rendererinfo; +#endif +#ifdef SWQUAKE rendererinfo_t swrendererinfo; +#endif rendererinfo_t *rendererinfo[] = { diff --git a/engine/client/screen.h b/engine/client/screen.h index 7e3c31328..ca40e458d 100644 --- a/engine/client/screen.h +++ b/engine/client/screen.h @@ -31,10 +31,6 @@ extern qboolean scr_disabled_for_loading; extern cvar_t scr_fov; extern cvar_t scr_viewsize; -extern cvar_t scr_viewsize; - -qboolean scr_skipupdate; - qboolean SCR_RSShot (void); //void SCR_DrawConsole (qboolean noback); diff --git a/engine/client/snd_directx.c b/engine/client/snd_directx.c index e239b5a89..df7608bf3 100644 --- a/engine/client/snd_directx.c +++ b/engine/client/snd_directx.c @@ -728,10 +728,7 @@ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum) dsbuf.lpwfxFormat = NULL; #ifdef DSBCAPS_GLOBALFOCUS - if (snd_inactive.ival -#ifdef NPQTV - || sys_parentwindow -#endif + if (snd_inactive.ival || sys_parentwindow ) /*always inactive if we have a parent window, because we can't tell properly otherwise*/ { dsbuf.dwFlags |= DSBCAPS_GLOBALFOCUS; diff --git a/engine/client/snd_dma.c b/engine/client/snd_dma.c index 0671e0604..e28944176 100644 --- a/engine/client/snd_dma.c +++ b/engine/client/snd_dma.c @@ -666,7 +666,9 @@ sounddriver pSDL_InitCard; sounddriver pWAV_InitCard; sounddriver pDroid_InitCard; sounddriver pAHI_InitCard; -sounddriver pPPAPI_InitCard; +#ifdef NACL +extern sounddriver pPPAPI_InitCard; +#endif typedef struct { char *name; @@ -680,7 +682,9 @@ sdriver_t drivers[] = { {"MacOS", &pMacOS_InitCard}, //prefered on mac {"Droid", &pDroid_InitCard}, //prefered on android (java thread) {"AHI", &pAHI_InitCard}, //prefered on morphos +#ifdef NACL {"PPAPI", &pPPAPI_InitCard}, //google's native client +#endif {"SNDIO", &pSNDIO_InitCard}, //prefered on OpenBSD {"SDL", &pSDL_InitCard}, //prefered on linux diff --git a/engine/client/sys_plugfte.c b/engine/client/sys_plugfte.c index ca507d2fd..17289b0d2 100644 --- a/engine/client/sys_plugfte.c +++ b/engine/client/sys_plugfte.c @@ -913,7 +913,7 @@ char *cleanarg(char *arg) { unsigned char *c; //skip over any leading spaces. - while (*arg <= ' ') + while (*arg && *arg <= ' ') arg++; //reject anything with a leading + or - @@ -945,8 +945,13 @@ qboolean Plug_GetBinaryName(char *exe, int exelen, char *basedir, int basedirlen *exe = 0; *basedir = 0; -// Q_strncpyz(exe, "C:/Games/Quake/fte_trunk/fteglqw_dbg.exe", exelen); -// Q_strncpyz(exe, "/home/david/quake/fte_trunk/engine/debug/fteqw.gl", exelen); +#ifdef _DEBUG +#ifdef _WIN32 + Q_strncpyz(exe, "C:/Games/Quake/fte_trunk/fteglqw_dbg.exe", exelen); +#else + Q_strncpyz(exe, "/home/david/quake/fte_trunk/engine/debug/fteqw.gl", exelen); +#endif +#endif /* Q_snprintfz(buffer, sizeof(buffer), "%s%s", binarypath, "npfte.txt"); @@ -1089,7 +1094,7 @@ qboolean Plug_GenCommandlineString(struct context *ctx, char *cmdline, int cmdli for (i = 0; i < argc; i++) { //add quotes for any arguments with spaces - if (strchr(argv[i], ' ') || strchr(argv[i], '\t')) + if (!*argv[i] || strchr(argv[i], ' ') || strchr(argv[i], '\t')) { Q_strncatz(cmdline, "\"", cmdlinelen); Q_strncatz(cmdline, argv[i], cmdlinelen); diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index 307989ede..0dc9de8e7 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -1509,8 +1509,6 @@ void Sys_SendKeyEvents (void) while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) { // we always update if there are any event, even if we're paused - scr_skipupdate = 0; - //if (!GetMessage (&msg, NULL, 0, 0)) // break; // Sys_Quit (); diff --git a/engine/common/bothdefs.h b/engine/common/bothdefs.h index f115d5c46..1ed2d2f8e 100644 --- a/engine/common/bothdefs.h +++ b/engine/common/bothdefs.h @@ -257,9 +257,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef NACL #undef CL_MASTER //no sockets support #undef SV_MASTER //noone uses this anyway -#undef VOICECHAT //not going to compile a speex library - I'm too lazy, but it can be done. #undef WEBSERVER //no sockets support (certainly no servers) -#undef WEBCLIENT //no sockets support (could use a different method, but that is non-trivial) #undef TCPCONNECT #undef IRCCONNECT #endif @@ -555,6 +553,7 @@ STAT_MONSTERS = 14, // bumped by svc_killedmonster STAT_ITEMS = 15, STAT_VIEWHEIGHT = 16, //same as zquake STAT_TIME = 17, //zquake +STAT_MATCHSTARTTIME = 18, #ifdef SIDEVIEWS STAT_VIEW2 = 20, #endif diff --git a/engine/common/common.h b/engine/common/common.h index b849455fb..45e4c2916 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -181,7 +181,7 @@ void MSG_WriteDir (sizebuf_t *sb, float *dir); extern int msg_readcount; extern qboolean msg_badread; // set if a read goes beyond end of message -struct netprim_s msg_nullnetprim; +extern struct netprim_s msg_nullnetprim; void MSG_BeginReading (struct netprim_s prim); void MSG_ChangePrimitives(struct netprim_s prim); diff --git a/engine/common/fs.c b/engine/common/fs.c index 340625558..bef9d1380 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -1882,7 +1882,10 @@ qboolean FS_LoadPackageFromFile(vfsfile_t *vfs, char *pname, char *localname, in { handle = searchpathformats[i].funcs->OpenNew (vfs, localname); if (!handle) + { + Con_Printf("file %s isn't a %s after all\n", pname, searchpathformats[i].extension); break; + } if (crc) { int truecrc = searchpathformats[i].funcs->GeneratePureCRC(handle, 0, false); @@ -2583,9 +2586,13 @@ void FS_StartupWithGame(int gamenum) i = COM_CheckParm ("-addbasegame"); while (i && i < com_argc-1) //use multiple -addbasegames (this is so the basic dirs don't die) { - FS_AddGameDirectory (com_argv[i+1], va("%s%s", com_quakedir, com_argv[i+1]), ~0); - if (*com_homedir) - FS_AddGameDirectory (com_argv[i+1], va("%s%s", com_homedir, com_argv[i+1]), ~0); + //reject various evil path arguments. + if (*com_argv[i+1] && !(strchr(com_argv[i+1], '.') || strchr(com_argv[i+1], ':') || strchr(com_argv[i+1], '?') || strchr(com_argv[i+1], '*') || strchr(com_argv[i+1], '/') || strchr(com_argv[i+1], '\\') || strchr(com_argv[i+1], '$'))) + { + FS_AddGameDirectory (com_argv[i+1], va("%s%s", com_quakedir, com_argv[i+1]), ~0); + if (*com_homedir) + FS_AddGameDirectory (com_argv[i+1], va("%s%s", com_homedir, com_argv[i+1]), ~0); + } i = COM_CheckNextParm ("-addbasegame", i); } diff --git a/engine/common/fs_pak.c b/engine/common/fs_pak.c index 2b62a0b02..a511856ef 100644 --- a/engine/common/fs_pak.c +++ b/engine/common/fs_pak.c @@ -203,9 +203,8 @@ void *FSPAK_LoadPackFile (vfsfile_t *file, const char *desc) if (header.id[0] != 'P' || header.id[1] != 'A' || header.id[2] != 'C' || header.id[3] != 'K') { - VFS_CLOSE(packhandle); + Con_Printf("%s is not a pak - %c%c%c%c\n", desc, header.id[0], header.id[1], header.id[2], header.id[3]); return NULL; -// Sys_Error ("%s is not a packfile", packfile); } header.dirofs = LittleLong (header.dirofs); header.dirlen = LittleLong (header.dirlen); diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index 2f3cc2335..07a939d13 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -3334,6 +3334,58 @@ qboolean CModQ3_LoadVisibility (lump_t *l) } #ifndef SERVERONLY +void CModQ3_LoadLighting (lump_t *l) +{ + qbyte *in = mod_base + l->fileofs; + qbyte *out; + unsigned int samples = l->filelen; + int m, s; + int mapsize = loadmodel->lightmaps.width*loadmodel->lightmaps.height*3; + int maps; + + extern cvar_t gl_overbright; + extern qbyte lmgamma[256]; + extern void BuildLightMapGammaTable (float g, float c); + loadmodel->engineflags &= ~MDLF_RGBLIGHTING; + + //round up the samples, in case the last one is partial. + maps = ((samples+mapsize-1)&~(mapsize-1)) / mapsize; + + //q3 maps have built in 4-fold overbright. + //if we're not rendering with that, we need to brighten the lightmaps in order to keep the darker parts the same brightness. we loose the 2 upper bits. those bright areas become uniform and indistinct. + gl_overbright.flags |= CVAR_LATCH; + BuildLightMapGammaTable(1, (1<<(2-gl_overbright.ival))); + + loadmodel->engineflags |= MDLF_RGBLIGHTING; + loadmodel->lightdata = out = Hunk_AllocName(samples, "lit data"); + + //be careful here, q3bsp deluxemapping is done using interleaving. we want to unoverbright ONLY lightmaps and not deluxemaps. + for (m = 0; m < maps; m++) + { + if (loadmodel->lightmaps.deluxemapping && (m & 1)) + { + //no gamma for deluxemap + for(s = 0; s < mapsize; s+=3) + { + *out++ = in[0]; + *out++ = in[1]; + *out++ = in[2]; + in += 3; + } + } + else + { + for(s = 0; s < mapsize; s++) + { + *out++ = lmgamma[*in++]; + } + + if (r_lightmap_saturation.value != 1.0f) + SaturateR8G8B8(out - mapsize, mapsize, r_lightmap_saturation.value); + } + } +} + qboolean CModQ3_LoadLightgrid (lump_t *l) { dq3gridlight_t *in; @@ -3849,8 +3901,6 @@ cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned *c #ifndef SERVERONLY if (qrenderer != QR_NONE) { - if (noerrors) - RMod_LoadLighting (&header.lumps[Q3LUMP_LIGHTMAPS]); //fixme: duplicated loading. if (header.version == 1) noerrors = noerrors && CModRBSP_LoadLightgrid (&header.lumps[Q3LUMP_LIGHTGRID], &header.lumps[RBSPLUMP_LIGHTINDEXES]); else @@ -3881,6 +3931,22 @@ cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned *c if (!loadmodel->textures[i]->shader) loadmodel->textures[i]->shader = R_RegisterShader_Lightmap(loadmodel->textures[i]->name); } + + if (loadmodel->fromgame == fg_quake3) + { + i = header.lumps[Q3LUMP_LIGHTMAPS].filelen / (loadmodel->lightmaps.width*loadmodel->lightmaps.height*3); + loadmodel->lightmaps.deluxemapping = !(i&1); + loadmodel->lightmaps.count = max(loadmodel->lightmaps.count, i); + + for (i = 0; i < loadmodel->numsurfaces && loadmodel->lightmaps.deluxemapping; i++) + { + if (loadmodel->surfaces[i].lightmaptexturenums[0] >= 0 && (loadmodel->surfaces[i].lightmaptexturenums[0] & 1)) + loadmodel->lightmaps.deluxemapping = false; + } + } + + if (noerrors) + CModQ3_LoadLighting (&header.lumps[Q3LUMP_LIGHTMAPS]); //fixme: duplicated loading. } #endif noerrors = noerrors && CModQ3_LoadLeafFaces (&header.lumps[Q3LUMP_LEAFSURFACES]); diff --git a/engine/common/net_wins.c b/engine/common/net_wins.c index ed1eeb5fd..915629aab 100644 --- a/engine/common/net_wins.c +++ b/engine/common/net_wins.c @@ -880,11 +880,11 @@ qboolean NET_StringToAdr (const char *s, int defaultport, netadr_t *a) else { /*code for convienience - no other protocols work anyway*/ - static qboolean warned; - if (!warned) + static float warned; + if (warned < realtime) { - Con_Printf("Note: Native client builds can only connect to websocket servers.\n"); - warned = true; + Con_Printf("Note: Assuming ws:// prefix\n"); + warned = realtime + 1; } memset (a, 0, sizeof(*a)); a->type = NA_WEBSOCKET; @@ -2447,9 +2447,53 @@ closesvstream: { memmove(st->inbuffer, st->inbuffer+i, st->inlen - (i)); st->inlen -= i; - resp = va( "HTTP/1.1 426 Upgrade Required\r\n" - "Sec-WebSocket-Version: 13\r\n" - "\r\n"); + if (!strcmp(arg[WCATTR_URL], "/live.html")) + { + resp = va( "HTTP/1.1 200 Ok\r\n" + "Connection: Close\r\n" + "Content-Type: text/html\r\n" + "\r\n" + "" + "" + "" + "
" + "" + "" + "" + "" + "Please install a plugin first.
" + "
" + "
" + "
" + "" + ); + } + /*else if (!strcmp(arg[WCATTR_URL], "/index.html") || !strcmp(arg[WCATTR_URL], "/")) + { + resp = va( "HTTP/1.1 200 Ok\r\n" + "Connection: Close\r\n" + "Content-Type: text/html\r\n" + "\r\n" + + "This is a Quake WebSocket server, not an http server.
\r\n" + ""FULLENGINENAME"" + ); + }*/ + else + { + resp = va( "HTTP/1.1 404 Ok\r\n" + "Connection: Close\r\n" + "Content-Type: text/html\r\n" + "\r\n" + + "This is a Quake WebSocket server, not an http server.
\r\n" + ""FULLENGINENAME"" + ); + } + //send the websocket handshake rejection. send(st->socketnum, resp, strlen(resp), 0); @@ -3675,9 +3719,9 @@ static qboolean FTENET_WebSocket_SendPacket(ftenet_generic_connection_t *gcon, i while(length-->0) { - /*FIXME: do we need this code?*/ if (!*in) { + //sends 256 instead of 0 *out++ = 0xc0 | (0x100 >> 6); *out++ = 0x80 | (0x100 & 0x3f); } @@ -3711,7 +3755,7 @@ static ftenet_generic_connection_t *FTENET_WebSocket_EstablishConnection(qboolea { return NULL; } - if (!NET_StringToAdr(address, &adr)) + if (!NET_StringToAdr(address, 80, &adr)) return NULL; //couldn't resolve the name newcon = Z_Malloc(sizeof(*newcon)); if (newcon) diff --git a/engine/dotnet2005/npfte.vcproj b/engine/dotnet2005/npfte.vcproj index c129cf6b0..d805cc711 100644 --- a/engine/dotnet2005/npfte.vcproj +++ b/engine/dotnet2005/npfte.vcproj @@ -53,7 +53,7 @@ shader->flags & SHADER_HASREFLECT) + if ((batch->shader->flags & SHADER_HASREFLECT) && gl_config.ext_framebuffer_objects) { vrect_t orect = r_refdef.vrect; if (!shaderstate.tex_reflection.num) @@ -3941,9 +3943,9 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist) r_refdef.vrect = orect; } else - GLR_DrawPortal(batch, cl.worldmodel->batches, 2); + GLR_DrawPortal(batch, cl.worldmodel->batches, 3); } - if (batch->shader->flags & SHADER_HASRIPPLEMAP) + if ((batch->shader->flags & SHADER_HASRIPPLEMAP) && gl_config.ext_framebuffer_objects) { vrect_t orect; if (!shaderstate.tex_ripplemap.num) diff --git a/engine/gl/gl_draw.c b/engine/gl/gl_draw.c index 9323e9148..b90edbb70 100644 --- a/engine/gl/gl_draw.c +++ b/engine/gl/gl_draw.c @@ -148,8 +148,6 @@ extern cvar_t gl_texturemode, gl_texture_anisotropic_filtering; extern cvar_t gl_savecompressedtex; -texid_t missing_texture; //texture used when one is missing. - int gl_anisotropy_factor; mpic_t *conback; @@ -269,6 +267,9 @@ void GL_Mipcap_Callback (struct cvar_s *var, char *oldvalue) gltexture_t *glt; char *s = var->string; + if (gl_config.gles) + return; + s = COM_Parse(s); gl_mipcap_min = *com_token?atoi(com_token):0; if (gl_mipcap_min > 3) /*cap it to 3, so no 16*16 textures get bugged*/ diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index 0a8ad4a0d..ca3326f95 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -37,11 +37,9 @@ extern int gl_stencilbits; FTEPFNGLCOMPRESSEDTEXIMAGE2DARBPROC qglCompressedTexImage2DARB; FTEPFNGLGETCOMPRESSEDTEXIMAGEARBPROC qglGetCompressedTexImageARB; -entity_t r_worldentity; - vec3_t modelorg, r_entorigin; -int r_visframecount; // bumped when going to a new PVS +extern int r_visframecount; // bumped when going to a new PVS extern int r_framecount; // used for dlight push checking float r_wateralphaval; //allowed or not... @@ -53,12 +51,10 @@ int c_brush_polys, c_alias_polys; // // view origin // -vec3_t vup; -vec3_t vpn; -vec3_t vright; -vec3_t r_origin; - -texture_t *r_notexture_mip; +//vec3_t vup; +//vec3_t vpn; +//vec3_t vright; +//vec3_t r_origin; cvar_t r_norefresh = SCVAR("r_norefresh","0"); @@ -426,7 +422,7 @@ void R_SetupGL (float stereooffset) stencilshadows |= r_shadow_realtime_world.ival && r_shadow_realtime_world_shadows.ival; #endif - if (1)//(!stencilshadows || !gl_stencilbits) && gl_maxdist.value>=100)//gl_nv_range_clamp) + if ((!stencilshadows || !gl_stencilbits) && gl_maxdist.value>=100)//gl_nv_range_clamp) { // yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*180/M_PI; // yfov = (2.0 * tan (scr_fov.value/360*M_PI)) / screenaspect; @@ -807,14 +803,15 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, int portaltype) r_refdef.externalview = true; - if (portaltype == 1) + switch(portaltype) { - /*explicit mirror*/ + case 1: /*fbo explicit mirror (fucked depth, working clip plane)*/ r_refdef.flipcull ^= true; R_MirrorMatrix(&plane); - } - else if (portaltype == 2) - { + break; + + case 2: /*fbo refraction (fucked depth, working clip plane)*/ + case 3: /*screen copy refraction (screen depth, fucked clip planes)*/ /*refraction image (same view, just with things culled*/ r_refdef.externalview = oldrefdef.externalview; VectorNegate(plane.normal, plane.normal); @@ -864,50 +861,54 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, int portaltype) } // memset(newvis, 0xff, pvsbytes); } - } - else if (batch->ent != &r_worldentity) - { - float d; - view = batch->ent; - d = DotProduct(r_refdef.vieworg, plane.normal) - plane.dist; - d-= 0.1; //nudge it past. - VectorAdd(r_refdef.vieworg, view->oldorigin, r_refdef.vieworg); //trivial offset for the warpzone. - VectorMA(r_refdef.vieworg, -d, plane.normal, r_refdef.pvsorigin); //clip the pvs origin to the plane. - } - else if (!(view = R_NearestPortal(&plane)) || VectorCompare(view->origin, view->oldorigin)) - { - r_refdef.flipcull ^= true; - R_MirrorMatrix(&plane); - } - else - { - float d; - vec3_t paxis[3], porigin, vaxis[3], vorg; - void PerpendicularVector( vec3_t dst, const vec3_t src ); + break; - /*calculate where the surface is meant to be*/ - VectorCopy(mesh->normals_array[0], paxis[0]); - PerpendicularVector(paxis[1], paxis[0]); - CrossProduct(paxis[0], paxis[1], paxis[2]); - d = DotProduct(view->origin, plane.normal) - plane.dist; - VectorMA(view->origin, -d, paxis[0], porigin); + default: /*q3 portal*/ + if (batch->ent != &r_worldentity) + { + float d; + view = batch->ent; + d = DotProduct(r_refdef.vieworg, plane.normal) - plane.dist; + d-= 0.1; //nudge it past. + VectorAdd(r_refdef.vieworg, view->oldorigin, r_refdef.vieworg); //trivial offset for the warpzone. + VectorMA(r_refdef.vieworg, -d, plane.normal, r_refdef.pvsorigin); //clip the pvs origin to the plane. + } + else if (!(view = R_NearestPortal(&plane)) || VectorCompare(view->origin, view->oldorigin)) + { + r_refdef.flipcull ^= true; + R_MirrorMatrix(&plane); + } + else + { + float d; + vec3_t paxis[3], porigin, vaxis[3], vorg; + void PerpendicularVector( vec3_t dst, const vec3_t src ); - /*grab the camera origin*/ - VectorNegate(view->axis[0], vaxis[0]); - VectorNegate(view->axis[1], vaxis[1]); - VectorCopy(view->axis[2], vaxis[2]); - VectorCopy(view->oldorigin, vorg); + /*calculate where the surface is meant to be*/ + VectorCopy(mesh->normals_array[0], paxis[0]); + PerpendicularVector(paxis[1], paxis[0]); + CrossProduct(paxis[0], paxis[1], paxis[2]); + d = DotProduct(view->origin, plane.normal) - plane.dist; + VectorMA(view->origin, -d, paxis[0], porigin); - VectorCopy(vorg, r_refdef.pvsorigin); + /*grab the camera origin*/ + VectorNegate(view->axis[0], vaxis[0]); + VectorNegate(view->axis[1], vaxis[1]); + VectorCopy(view->axis[2], vaxis[2]); + VectorCopy(view->oldorigin, vorg); - /*rotate it a bit*/ - RotatePointAroundVector(vaxis[1], vaxis[0], view->axis[1], sin(realtime)*4); - CrossProduct(vaxis[0], vaxis[1], vaxis[2]); + VectorCopy(vorg, r_refdef.pvsorigin); - TransformCoord(oldrefdef.vieworg, paxis, porigin, vaxis, vorg, r_refdef.vieworg); - TransformDir(vpn, paxis, vaxis, vpn); - TransformDir(vright, paxis, vaxis, vright); - TransformDir(vup, paxis, vaxis, vup); + /*rotate it a bit*/ + RotatePointAroundVector(vaxis[1], vaxis[0], view->axis[1], sin(realtime)*4); + CrossProduct(vaxis[0], vaxis[1], vaxis[2]); + + TransformCoord(oldrefdef.vieworg, paxis, porigin, vaxis, vorg, r_refdef.vieworg); + TransformDir(vpn, paxis, vaxis, vpn); + TransformDir(vright, paxis, vaxis, vright); + TransformDir(vup, paxis, vaxis, vup); + } + break; } Matrix4x4_CM_ModelViewMatrixFromAxis(r_refdef.m_view, vpn, vright, vup, r_refdef.vieworg); VectorAngles(vpn, vup, r_refdef.viewangles); @@ -939,7 +940,8 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, int portaltype) frustum[4].normal[1] = plane.normal[1]; frustum[4].normal[2] = plane.normal[2]; frustum[4].dist = plane.dist + 0.01; - R_ObliqueNearClip(&frustum[4]); + if (portaltype == 1 || portaltype == 2) + R_ObliqueNearClip(&frustum[4]); R_RenderScene(); // if (qglClipPlane) // qglDisable(GL_CLIP_PLANE0); diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index 24154e34a..1487ca216 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -4185,6 +4185,10 @@ char *Shader_DefaultBSPWater(char *shortname) wstyle = 1; { +#ifdef GLQUAKE + if (wstyle > 2 && !gl_config.ext_framebuffer_objects) + wstyle = 2; +#endif switch(wstyle) { case -1: //invisible diff --git a/engine/gl/gl_shadow.c b/engine/gl/gl_shadow.c index ff6690802..7e734fc38 100644 --- a/engine/gl/gl_shadow.c +++ b/engine/gl/gl_shadow.c @@ -44,7 +44,7 @@ shader_t *crepuscular_shader; static void Sh_DrawEntLighting(dlight_t *light, vec3_t colour); -struct { +static struct { int numlights; int shadowsurfcount; @@ -202,6 +202,7 @@ static void SHM_TriangleFan(int numverts, vecV_t *verts, vec3_t lightorg, float v = (sh_shmesh->numverts+numverts*2 + inc)&~(inc-1); //and a bit of padding if (sh_shmesh->maxverts < v) { + v += 1024; sh_shmesh->maxverts = v; sh_shmesh->verts = BZ_Realloc(sh_shmesh->verts, v * sizeof(*sh_shmesh->verts)); } @@ -226,6 +227,7 @@ static void SHM_TriangleFan(int numverts, vecV_t *verts, vec3_t lightorg, float v = (sh_shmesh->numindicies+idxs*2+inc)&~(inc-1); //and a bit of padding if (sh_shmesh->maxindicies < v) { + v += 1024; sh_shmesh->maxindicies = v; sh_shmesh->indicies = BZ_Realloc(sh_shmesh->indicies, v * sizeof(*sh_shmesh->indicies)); } @@ -2141,9 +2143,13 @@ void Sh_GenShadowMap (dlight_t *l, qbyte *lvis) else { Matrix4x4_CM_Projection_Far(r_refdef.m_projection, 90, 90, nearplane, l->radius); - qglMatrixMode(GL_PROJECTION); - qglLoadMatrixf(r_refdef.m_projection); - qglMatrixMode(GL_MODELVIEW); + + if (!gl_config.nofixedfunc) + { + qglMatrixMode(GL_PROJECTION); + qglLoadMatrixf(r_refdef.m_projection); + qglMatrixMode(GL_MODELVIEW); + } /*generate faces*/ for (f = 0; f < 6; f++) @@ -2159,11 +2165,13 @@ void Sh_GenShadowMap (dlight_t *l, qbyte *lvis) qglDisable(GL_POLYGON_OFFSET_FILL); - qglMatrixMode(GL_PROJECTION); - qglLoadMatrixf(r_refdef.m_projection); - - qglMatrixMode(GL_MODELVIEW); - qglLoadMatrixf(r_refdef.m_view); + if (!gl_config.nofixedfunc) + { + qglMatrixMode(GL_PROJECTION); + qglLoadMatrixf(r_refdef.m_projection); + qglMatrixMode(GL_MODELVIEW); + qglLoadMatrixf(r_refdef.m_view); + } qglViewport(r_refdef.pxrect.x, vid.pixelheight - r_refdef.pxrect.y, r_refdef.pxrect.width, r_refdef.pxrect.height); @@ -2601,7 +2609,7 @@ static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, qbyte *vvis) if (gl_config.ext_stencil_wrap) { //minimise damage... sbackfail = GL_INCR_WRAP_EXT; - sdecrw = GL_DECR_WRAP_EXT; + sfrontfail = GL_DECR_WRAP_EXT; } #else sref = (1<color[0], dl->color[1], dl->color[2]); qglDisable(GL_STENCIL_TEST); - qglEnable(GL_POLYGON_OFFSET_FILL); - qglPolygonOffset(-1, -1); +// qglEnable(GL_POLYGON_OFFSET_FILL); +// qglPolygonOffset(-1, -1); // qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE); Sh_DrawStencilLightShadows(dl, lvis, vvis, false); - qglDisable(GL_POLYGON_OFFSET_FILL); - qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +// qglDisable(GL_POLYGON_OFFSET_FILL); +// qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } #endif if (qglStencilOpSeparateATI) { + //ATI/GLES/ARB method sref/=2; qglClearStencil(sref); qglClear(GL_STENCIL_BUFFER_BIT); @@ -2653,8 +2662,8 @@ static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, qbyte *vvis) } else if (qglActiveStencilFaceEXT) { + //Nvidia-specific method. sref/=2; - /*personally I prefer the ATI way (nvidia method)*/ qglClearStencil(sref); qglClear(GL_STENCIL_BUFFER_BIT); GL_CullFace(0); diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index be5b000d6..533cd1ff0 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -131,6 +131,7 @@ void (APIENTRY *qglFramebufferTexture2DEXT)(GLenum target, GLenum attachmentPoin void (APIENTRY *qglFramebufferRenderbufferEXT)(GLenum target, GLenum attachmentPoint, GLenum textureTarget, GLuint textureId); GLenum (APIENTRY *qglCheckFramebufferStatusEXT)(GLenum target); +void (APIENTRY *qglDepthBoundsEXT) (GLclampd zmin, GLclampd zmax); /* PFNGLPROGRAMSTRINGARBPROC qglProgramStringARB; PFNGLGETPROGRAMIVARBPROC qglGetProgramivARB; @@ -860,7 +861,22 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) qglFramebufferRenderbufferEXT = (void *)getglext("glFramebufferRenderbufferEXT"); qglCheckFramebufferStatusEXT = (void *)getglext("glCheckFramebufferStatusEXT"); } - +/* //I don't think we care about the differences, so this code should be safe, but I have no way to test that theory right now + else if (GL_CheckExtension("GL_OES_framebuffer_object")) + { + gl_config.ext_framebuffer_objects = true; + qglGenFramebuffersEXT = (void *)getglext("glGenFramebuffersOES"); + qglDeleteFramebuffersEXT = (void *)getglext("glDeleteFramebuffersOES"); + qglBindFramebufferEXT = (void *)getglext("glBindFramebufferOES"); + qglGenRenderbuffersEXT = (void *)getglext("glGenRenderbuffersOES"); + qglDeleteRenderbuffersEXT = (void *)getglext("glDeleteRenderbuffersOES"); + qglBindRenderbufferEXT = (void *)getglext("glBindRenderbufferOES"); + qglRenderbufferStorageEXT = (void *)getglext("glRenderbufferStorageOES"); + qglFramebufferTexture2DEXT = (void *)getglext("glFramebufferTexture2DOES"); + qglFramebufferRenderbufferEXT = (void *)getglext("glFramebufferRenderbufferOES"); + qglCheckFramebufferStatusEXT = (void *)getglext("glCheckFramebufferStatusOES"); + } +*/ #ifdef DEBUG if (GL_CheckExtension("GL_ARB_debug_output")) { @@ -1581,8 +1597,6 @@ void GL_Init(void *(*getglfunction) (char *name)) #endif } -unsigned int d_8to24rgbtable[256]; - diff --git a/engine/gl/gl_vidlinuxglx.c b/engine/gl/gl_vidlinuxglx.c index 6e3bd5574..15540d0e0 100644 --- a/engine/gl/gl_vidlinuxglx.c +++ b/engine/gl/gl_vidlinuxglx.c @@ -1652,8 +1652,6 @@ qboolean X11VID_Init (rendererstate_t *info, unsigned char *palette, int psl) GLVID_SetPalette(palette); GLVID_ShiftPalette(palette); - qglGetIntegerv(GL_STENCIL_BITS, &gl_stencilbits); - InitSig(); // trap evil signals //probably going to be resized in the event handler diff --git a/engine/gl/gl_vidnt.c b/engine/gl/gl_vidnt.c index 823526138..180e8d2f4 100644 --- a/engine/gl/gl_vidnt.c +++ b/engine/gl/gl_vidnt.c @@ -580,6 +580,9 @@ qboolean VID_SetWindowedMode (rendererstate_t *info) ptop = sys_parenttop; pwidth = sys_parentwidth; pheight = sys_parentheight; + + WindowRect.right = sys_parentwidth; + WindowRect.bottom = sys_parentheight; } else #endif @@ -1337,7 +1340,7 @@ void GLVID_Recenter_f(void) if (sys_parentwindow && modestate==MS_WINDOWED) { - WindowRect = centerrect(sys_parentleft, sys_parenttop, sys_parentwidth, sys_parentheight, vid_width.value, vid_height.value); + WindowRect = centerrect(sys_parentleft, sys_parenttop, sys_parentwidth, sys_parentheight, sys_parentwidth, sys_parentheight); MoveWindow(mainwindow, WindowRect.left, WindowRect.top, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top, FALSE); VID_UpdateWindowStatus (mainwindow); @@ -1386,8 +1389,7 @@ void GL_DoSwap (void) return; screenflush = 0; - if (!scr_skipupdate) - qSwapBuffers(maindc); + qSwapBuffers(maindc); // handle the mouse state when windowed if that's changed @@ -1706,7 +1708,6 @@ BOOL bSetupPixelFormat(HDC hDC, rendererstate_t *info) TRACE(("dbg: bSetupPixelFormat: we can use the stencil buffer. woot\n")); qDescribePixelFormat(hDC, pixelformat, sizeof(pfd), &pfd); FixPaletteInDescriptor(hDC, &pfd); - gl_stencilbits = pfd.cStencilBits; if ((pfd.dwFlags & PFD_GENERIC_FORMAT) && !(pfd.dwFlags & PFD_GENERIC_ACCELERATED)) { @@ -1718,7 +1719,6 @@ BOOL bSetupPixelFormat(HDC hDC, rendererstate_t *info) TRACE(("dbg: ChoosePixelFormat 1: no stencil buffer for us\n")); pfd.cStencilBits = 0; - gl_stencilbits = 0; if ( (pixelformat = qChoosePixelFormat(hDC, &pfd)) == 0 ) { diff --git a/engine/gl/glquake.h b/engine/gl/glquake.h index f86c8e88c..47e9719c9 100644 --- a/engine/gl/glquake.h +++ b/engine/gl/glquake.h @@ -817,7 +817,7 @@ extern void (APIENTRY *qglFramebufferTexture2DEXT)(GLenum target, GLenum attachm extern void (APIENTRY *qglFramebufferRenderbufferEXT)(GLenum target, GLenum attachmentPoint, GLenum textureTarget, GLuint textureId); extern GLenum (APIENTRY *qglCheckFramebufferStatusEXT)(GLenum target); -void (APIENTRY *qglDepthBoundsEXT) (GLclampd zmin, GLclampd zmax); +extern void (APIENTRY *qglDepthBoundsEXT) (GLclampd zmin, GLclampd zmax); /* extern qboolean gl_arb_fragment_program; diff --git a/engine/gl/r_bishaders.h b/engine/gl/r_bishaders.h index 938c3ab94..5b0b4cbd3 100644 --- a/engine/gl/r_bishaders.h +++ b/engine/gl/r_bishaders.h @@ -732,6 +732,61 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND }, #endif #ifdef GLQUAKE +{QR_OPENGL, 110, "defaultfill", +"#ifdef VERTEX_SHADER\n" +"attribute vec4 v_colour;\n" +"varying vec4 vc;\n" + +"void main ()\n" +"{\n" +"vc = v_colour;\n" +"gl_Position = ftetransform();\n" +"}\n" +"#endif\n" + +"#ifdef FRAGMENT_SHADER\n" +"varying vec4 vc;\n" +"void main ()\n" +"{\n" +"gl_FragColor = vc;\n" +"}\n" +"#endif\n" +}, +#endif +#ifdef D3D11QUAKE +{QR_DIRECT3D11, 11, "defaultfill", +"struct a2v\n" +"{\n" +"float4 pos: POSITION;\n" +"float4 vcol: COLOR0;\n" +"};\n" +"struct v2f\n" +"{\n" +"float4 pos: SV_POSITION;\n" +"float4 vcol: COLOR0;\n" +"};\n" + +"#include \n" + +"#ifdef VERTEX_SHADER\n" +"v2f main (a2v inp)\n" +"{\n" +"v2f outp;\n" +"outp.pos = mul(m_projection, inp.pos);\n" +"outp.vcol = inp.vcol;\n" +"return outp;\n" +"}\n" +"#endif\n" + +"#ifdef FRAGMENT_SHADER\n" +"float4 main (v2f inp) : SV_TARGET\n" +"{\n" +"return inp.vcol;\n" +"}\n" +"#endif\n" +}, +#endif +#ifdef GLQUAKE {QR_OPENGL, 110, "defaultsprite", "!!permu FOG\n" //used by both particles and sprites. diff --git a/engine/http/httpclient.c b/engine/http/httpclient.c index 1b814a106..fda100e00 100644 --- a/engine/http/httpclient.c +++ b/engine/http/httpclient.c @@ -4,8 +4,150 @@ #include "netinc.h" -#ifdef WEBCLIENT +#if defined(WEBCLIENT) +#if defined(NACL) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +extern PPB_Core *ppb_core; +extern PPB_URLRequestInfo *urlrequestinfo; +extern PPB_URLLoader *urlloader; +extern PP_Instance pp_instance; +extern PPB_Var *ppb_var_interface; + +struct nacl_dl { + char buffer[65536]; + PP_Resource req; +}; + +static void readfinished(void* user_data, int32_t result) +{ + struct dl_download *f = user_data; + struct nacl_dl *ctx = f->ctx; + struct PP_CompletionCallback ccb = {readfinished, f, PP_COMPLETIONCALLBACK_FLAG_NONE}; + + //trying to clean up + if (!ctx) + return; + +// Sys_Printf("lastresult: %i\n", result); + + if (result == PP_OK) + { +// Sys_Printf("%s completed\n", f->url); + ppb_core->ReleaseResource(ctx->req); + ctx->req = 0; + + f->status = DL_FINISHED; + return; + } + + for (; result > 0; result = urlloader->ReadResponseBody(ctx->req, ctx->buffer, sizeof(ctx->buffer), ccb)) + { + //make sure the file is 'open'. + if (!f->file) + { + if (*f->localname) + { + FS_CreatePath(f->localname, FS_GAME); + f->file = FS_OpenVFS(f->localname, "w+b", FS_GAME); + } + else + f->file = FS_OpenTemp(); + } + +// Sys_Printf("write: %i\n", result); + VFS_WRITE(f->file, ctx->buffer, result); + + f->completed += result; + } + +// Sys_Printf("result: %i\n", result); + if (result != PP_OK_COMPLETIONPENDING) + { + Sys_Printf("file %s failed or something\n", f->url); + ppb_core->ReleaseResource(ctx->req); + ctx->req = 0; + f->status = DL_FAILED; + } +} +//urloader->open completed +static void dlstarted(void* user_data, int32_t result) +{ + struct dl_download *f = user_data; + struct nacl_dl *ctx = f->ctx; + + struct PP_CompletionCallback ccb = {readfinished, f, PP_COMPLETIONCALLBACK_FLAG_NONE}; + readfinished(user_data, urlloader->ReadResponseBody(ctx->req, ctx->buffer, sizeof(ctx->buffer), ccb)); +} + +static void nadl_cleanup(void* user_data, int32_t result) +{ + struct nacl_dl *ctx = user_data; + + if (ctx->req) + ppb_core->ReleaseResource(ctx->req); + free(ctx); +} + +void NADL_Cleanup(struct dl_download *dl) +{ + struct nacl_dl *ctx = dl->ctx; + + //we can't free the ctx memory etc, in case the browser still has requests pending on it before it handles our close. + //so set up a callback to do it later + + dl->ctx = NULL; //orphan + struct PP_CompletionCallback ccb = {nadl_cleanup, ctx, PP_COMPLETIONCALLBACK_FLAG_NONE}; + ppb_core->CallOnMainThread(1000, ccb, 0); +} + +qboolean HTTPDL_Decide(struct dl_download *dl) +{ + const char *url = dl->redir; + struct nacl_dl *ctx; + if (!*url) + url = dl->url; + + if (dl->ctx) + { + if (dl->status == DL_FAILED || dl->status == DL_FINISHED) + { + NADL_Cleanup(dl); + return false; //safe to destroy it now + } + } + else + { + PP_Resource dlri; + + dl->status = DL_ACTIVE; + dl->abort = NADL_Cleanup; + dl->ctx = ctx = Z_Malloc(sizeof(*ctx)); + + /*everything goes via nacl, so we might as well just init that here*/ + ctx->req = urlloader->Create(pp_instance); + dlri = urlrequestinfo->Create(pp_instance); + urlrequestinfo->SetProperty(dlri, PP_URLREQUESTPROPERTY_ALLOWCROSSORIGINREQUESTS, ppb_var_interface->VarFromUtf8(url, strlen(url))); + urlrequestinfo->SetProperty(dlri, PP_URLREQUESTPROPERTY_URL, ppb_var_interface->VarFromUtf8(url, strlen(url))); + + struct PP_CompletionCallback ccb = {dlstarted, dl, PP_COMPLETIONCALLBACK_FLAG_NONE}; + urlloader->Open(ctx->req, dlri, ccb); + ppb_core->ReleaseResource(dlri); + } + + return true; +} +#else qboolean HTTPDL_Decide(struct dl_download *dl); /* @@ -477,6 +619,7 @@ qboolean HTTPDL_Decide(struct dl_download *dl) } return true; } +#endif /*!defined(NACL)*/ #ifdef MULTITHREAD static int DL_Thread_Work(void *arg) @@ -539,9 +682,23 @@ struct dl_download *DL_Create(const char *url) return newdl; } +static struct dl_download *showndownload; + /*destroys an entire download context*/ void DL_Close(struct dl_download *dl) { +#ifndef NPFTE + if (showndownload == dl) + { + if (cls.downloadmethod == DL_HTTP) + { + cls.downloadmethod = DL_NONE; + *cls.downloadlocalname = *cls.downloadremotename = 0; + } + showndownload = NULL; + } +#endif + #ifdef MULTITHREAD dl->threaddie = true; if (dl->threadctx) @@ -559,7 +716,6 @@ void DL_Close(struct dl_download *dl) #ifndef NPFTE static struct dl_download *activedownloads; -static struct dl_download *showndownload; unsigned int shownbytestart; /*create a download context and add it to the list, for lazy people*/ struct dl_download *HTTP_CL_Get(const char *url, const char *localfile, void (*NotifyFunction)(struct dl_download *dl)) @@ -580,69 +736,63 @@ struct dl_download *HTTP_CL_Get(const char *url, const char *localfile, void (*N void HTTP_CL_Think(void) { - struct dl_download *con = activedownloads; + struct dl_download *dl = activedownloads; struct dl_download **link = NULL; link = &activedownloads; while (*link) { - con = *link; + dl = *link; #ifdef MULTITHREAD - if (con->threadctx) + if (dl->threadctx) { - if (con->status == DL_FINISHED || con->status == DL_FAILED) + if (dl->status == DL_FINISHED || dl->status == DL_FAILED) { - Sys_WaitOnThread(con->threadctx); - con->threadctx = NULL; + Sys_WaitOnThread(dl->threadctx); + dl->threadctx = NULL; continue; } } else #endif - if (!con->poll(con)) + if (!dl->poll(dl)) { - *link = con->next; - if (con->file) - VFS_SEEK(con->file, 0); - if (con->notify) - con->notify(con); - DL_Close(con); - - if (cls.downloadmethod == DL_HTTP) - { - if (showndownload == con) - { - cls.downloadmethod = DL_NONE; - *cls.downloadlocalname = *cls.downloadremotename = 0; - } - } + *link = dl->next; + if (dl->file) + VFS_SEEK(dl->file, 0); + if (dl->notify) + dl->notify(dl); + DL_Close(dl); continue; } - link = &con->next; + link = &dl->next; - if (!cls.downloadmethod && *con->localname) + if (!cls.downloadmethod) { cls.downloadmethod = DL_HTTP; - showndownload = con; - strcpy(cls.downloadlocalname, con->localname); - strcpy(cls.downloadremotename, con->url); + showndownload = dl; + if (*dl->localname) + strcpy(cls.downloadlocalname, dl->localname); + else + strcpy(cls.downloadlocalname, dl->url); + strcpy(cls.downloadremotename, dl->url); cls.downloadstarttime = Sys_DoubleTime(); cls.downloadedbytes = 0; - shownbytestart = con->completed; + shownbytestart = dl->completed; } if (cls.downloadmethod == DL_HTTP) { - if (showndownload == con) + if (showndownload == dl) { - if (con->status == DL_FINISHED) + if (dl->status == DL_FINISHED) cls.downloadpercent = 100; - else if (con->status != DL_ACTIVE) + else if (dl->status != DL_ACTIVE) cls.downloadpercent = 0; - else if (con->totalsize <= 0) + else if (dl->totalsize <= 0) cls.downloadpercent = 50; else - cls.downloadpercent = con->completed*100.0f/con->totalsize; - cls.downloadedbytes = con->completed; + cls.downloadpercent = dl->completed*100.0f/dl->totalsize; + cls.downloadedbytes = dl->completed; } } } diff --git a/engine/nacl/fs_ppapi.c b/engine/nacl/fs_ppapi.c index b477b610e..f66536649 100644 --- a/engine/nacl/fs_ppapi.c +++ b/engine/nacl/fs_ppapi.c @@ -70,111 +70,9 @@ typedef struct mfchunk_t *cchunk; } vfsmfile_t; -typedef struct -{ - PP_Resource dl; - char buffer[65536]; - char *fname; - vfsfile_t *out; -} dlfile_t; - -static int activedls; -static int availdlslots = 2; -void readfinished(void* user_data, int32_t result) -{ - dlfile_t *f = user_data; - /*if there was a prior request that didn't finish yet...*/ - struct PP_CompletionCallback ccb = {readfinished, f, PP_COMPLETIONCALLBACK_FLAG_OPTIONAL}; - -// Sys_Printf("lastresult: %i\n", result); - - if (result == PP_OK) - { - Sys_Printf("%s completed\n", f->fname); - if (f->out) - VFS_CLOSE(f->out); - //ppb_core->ReleaseResource(f->dl); - activedls--; - availdlslots++; - free(f); - return; - } - - for (; result > 0; result = urlloader->ReadResponseBody(f->dl, f->buffer, sizeof(f->buffer), ccb)) - { - if (!f->out) - { - Sys_Printf("Downloading %s\n", f->fname); - f->out = VFSOS_Open(f->fname, "wb"); - } - -// Sys_Printf("write: %i\n", result); - VFS_WRITE(f->out, f->buffer, result); - } - -// Sys_Printf("result: %i\n", result); - if (result != PP_OK_COMPLETIONPENDING) - { - Sys_Printf("file %s failed or something\n", f->fname); - if (f->out) - VFS_CLOSE(f->out); - ppb_core->ReleaseResource(f->dl); - activedls--; - availdlslots++; - free(f); - } -} -void dlstarted(void* user_data, int32_t result) -{ - dlfile_t *f = user_data; - - struct PP_CompletionCallback ccb = {readfinished, f, PP_COMPLETIONCALLBACK_FLAG_OPTIONAL}; - readfinished(user_data, urlloader->ReadResponseBody(f->dl, f->buffer, sizeof(f->buffer), ccb)); -} qboolean FSPPAPI_Init(int *fileid) { - dlfile_t *dlf; - PP_Resource dlri; - static char *dlnames[] = - { - "id1/pak0.pak", -// "id1/gfx/conback.tga", -// "id1/gfx/conchars.tga", - "id1/pak1.pak", -// "id1/bigass1.dem", -// "id1/overkill.qwd", - "id1/pak2.pak", - "id1/pak3.pak", - "id1/pak4.pak", - NULL - }; - if (availdlslots) - { - if (!dlnames[*fileid]) - { - if (!activedls) - return true; /*engine has all the content it needs*/ - return false; /*still downloading something, don't let it continue just yet*/ - } - - dlf = malloc(sizeof(*dlf)); - if (!dlf) - return false; - dlf->out = NULL; - - activedls++; - availdlslots--; - dlf->fname = dlnames[*fileid]; - *fileid+=1; - dlf->dl = urlloader->Create(pp_instance); - dlri = urlrequestinfo->Create(pp_instance); - urlrequestinfo->SetProperty(dlri, PP_URLREQUESTPROPERTY_URL, ppb_var_interface->VarFromUtf8(dlf->fname, strlen(dlf->fname))); - - struct PP_CompletionCallback ccb = {dlstarted, dlf, PP_COMPLETIONCALLBACK_FLAG_NONE}; - urlloader->Open(dlf->dl, dlri, ccb); - ppb_core->ReleaseResource(dlri); - } - return false; + return true; /*engine has all the content it needs*/ } static int preparechunk(vfsmfile_t *f, int bytes, void **data) @@ -438,14 +336,43 @@ static vfsfile_t *FSPPAPI_OpenVFS(void *handle, flocation_t *loc, const char *mo return VFSPPAPI_Open(diskname, mode); } -static void FSPPAPI_PrintPath(void *handle) +static void FSPPAPI_GetDisplayPath(void *handle, char *outpath, unsigned int pathsize) { - Con_Printf("%s\n", (char*)handle); + Q_strncpyz(outpath, (char*)handle, pathsize); } static void FSPPAPI_ClosePath(void *handle) { Z_Free(handle); } + +int Sys_EnumerateFiles (const char *rootpath, const char *match, int (*func)(const char *, int, void *), void *parm) +{ + int rootlen = strlen(rootpath); + char *sub; + mfile_t *f; + if (*match == '/') + match++; + for (f = mfiles; f; f = f->next) + { + sub = f->name; + if (strncmp(sub, rootpath, rootlen)) + continue; + sub += rootlen; + if (*sub == '/') + sub++; + if (wildcmp(match, sub)) + { + if (!func(sub, f->length, parm)) + return false; + } + } + return true; +} +static int FSPPAPI_EnumerateFiles (void *handle, const char *match, int (*func)(const char *, int, void *), void *parm) +{ + return Sys_EnumerateFiles((char*)handle, match, func, parm); +} + static int FSPPAPI_RebuildFSHash(const char *filename, int filesize, void *data) { if (filename[strlen(filename)-1] == '/') @@ -456,22 +383,10 @@ static int FSPPAPI_RebuildFSHash(const char *filename, int filesize, void *data) Sys_EnumerateFiles((char*)data, childpath, FSPPAPI_RebuildFSHash, data); return true; } - if (!Hash_GetInsensative(&filesystemhash, filename)) - { - bucket_t *bucket = (bucket_t*)BZ_Malloc(sizeof(bucket_t) + strlen(filename)+1); - strcpy((char *)(bucket+1), filename); -//#ifdef _WIN32 -// Q_strlwr((char *)(bucket+1)); -//#endif - Hash_AddInsensative(&filesystemhash, (char *)(bucket+1), data, bucket); - - fs_hash_files++; - } - else - fs_hash_dups++; + FS_AddFileHash(0, filename, NULL, data); return true; } -static void FSPPAPI_BuildHash(void *handle) +static void FSPPAPI_BuildHash(void *handle, int depth) { Sys_EnumerateFiles(handle, "*", FSPPAPI_RebuildFSHash, handle); } @@ -554,19 +469,29 @@ static void FSPPAPI_ReadFile(void *handle, flocation_t *loc, char *buffer) VFS_CLOSE(f); } -static int FSPPAPI_EnumerateFiles (void *handle, const char *match, int (*func)(const char *, int, void *), void *parm) + +static void *FSPPAPI_OpenPath(vfsfile_t *mustbenull, const char *desc) { - return Sys_EnumerateFiles(handle, match, func, parm); + char *np; + int dlen = strlen(desc); + if (mustbenull) + return NULL; + np = Z_Malloc(dlen+1); + if (np) + { + memcpy(np, desc, dlen+1); + } + return np; } searchpathfuncs_t osfilefuncs = { - FSPPAPI_PrintPath, + FSPPAPI_GetDisplayPath, FSPPAPI_ClosePath, FSPPAPI_BuildHash, FSPPAPI_FLocate, FSPPAPI_ReadFile, FSPPAPI_EnumerateFiles, - NULL, + FSPPAPI_OpenPath, NULL, FSPPAPI_OpenVFS }; diff --git a/engine/nacl/gl_vidppapi.c b/engine/nacl/gl_vidppapi.c index 8813c0a27..c383aa167 100644 --- a/engine/nacl/gl_vidppapi.c +++ b/engine/nacl/gl_vidppapi.c @@ -6,6 +6,7 @@ #include #include #include +#include extern PPB_Core *ppb_core; extern PPB_GetInterface sys_gbi; @@ -14,10 +15,23 @@ extern PP_Instance pp_instance; static PP_Resource glcontext; extern PPB_Instance* instance_interface; int delayedswap = false; +qboolean swappending; +extern cvar_t _vid_wait_override; + +void FrameEvent(void* user_data, int32_t result); +qboolean NAGL_SwapPending(void) +{ + return swappending; +} void swap_callback(void* user_data, int32_t result) { -// printf("swap result: %d\n", result); + if (swappending) + { + swappending = false; + + FrameEvent(NULL, 0); + } } void GL_BeginRendering (void) { @@ -26,16 +40,34 @@ void GL_EndRendering (void) { delayedswap = true; glFlush(); + +// if (!gl_lateswap.value) +// GL_DoSwap(); } void GL_DoSwap(void) { if (delayedswap) { - struct PP_CompletionCallback ccb = { swap_callback, NULL, PP_COMPLETIONCALLBACK_FLAG_OPTIONAL}; + qboolean vsync = _vid_wait_override.ival || !*_vid_wait_override.string; + struct PP_CompletionCallback ccb = { swap_callback, NULL, vsync?PP_COMPLETIONCALLBACK_FLAG_NONE:PP_COMPLETIONCALLBACK_FLAG_OPTIONAL}; glFlush(); - graphics3d_interface->SwapBuffers(glcontext, ccb); delayedswap = false; + + switch(graphics3d_interface->SwapBuffers(glcontext, ccb)) + { + case PP_OK_COMPLETIONPENDING: + swappending |= vsync; + break; + case PP_OK: + break; + case PP_ERROR_INPROGRESS: + Con_DPrintf("chrome can't handle vid_wait 0\n"); + break; + default: + Con_DPrintf("unknown error on SwapBuffers call\n"); + break; + } } } @@ -227,23 +259,33 @@ void *PPAPI_GetGLSymbol(char *symname) void GL_Resized(int width, int height) { extern cvar_t vid_conautoscale, vid_conwidth; + + vid.pixelwidth = width; + vid.pixelheight = height; if (glcontext) { graphics3d_interface->ResizeBuffers(glcontext, width, height); - vid.pixelwidth = width; - vid.pixelheight = height; - Cvar_ForceCallback(&vid_conautoscale); Cvar_ForceCallback(&vid_conwidth); } } qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette) -{ - int32_t attribs[] = {PP_GRAPHICS3DATTRIB_WIDTH, info->width, - PP_GRAPHICS3DATTRIB_HEIGHT, info->height, +{ + if (!vid.pixelwidth) + vid.pixelwidth = info->width; + if (!vid.pixelheight) + vid.pixelheight = info->height; + if (vid.pixelwidth < 320) + vid.pixelwidth = 320; + if (vid.pixelheight < 200) + vid.pixelheight = 200; + + int32_t attribs[] = {PP_GRAPHICS3DATTRIB_WIDTH, vid.pixelwidth, + PP_GRAPHICS3DATTRIB_HEIGHT, vid.pixelheight, PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 24, PP_GRAPHICS3DATTRIB_STENCIL_SIZE, 8, + PP_GRAPHICS3DATTRIB_SWAP_BEHAVIOR, PP_GRAPHICS3DATTRIB_BUFFER_DESTROYED, PP_GRAPHICS3DATTRIB_NONE}; glcontext = graphics3d_interface->Create(pp_instance, 0, attribs); @@ -261,8 +303,8 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette) GL_EndRendering(); GL_DoSwap(); - vid.pixelwidth = info->width; - vid.pixelheight = info->height; +// vid.pixelwidth = info->width; +// vid.pixelheight = info->height; GLVID_SetPalette (palette); GL_Init(PPAPI_GetGLSymbol); diff --git a/engine/nacl/snd_ppapi.c b/engine/nacl/snd_ppapi.c index f78395492..8eb3988f1 100644 --- a/engine/nacl/snd_ppapi.c +++ b/engine/nacl/snd_ppapi.c @@ -80,7 +80,11 @@ int PPAPI_InitCard (soundcardinfo_t *sc, int cardnum) sc->sn.samplebits = 16; sc->sn.numchannels = 2; +#ifdef PPB_AUDIO_CONFIG_INTERFACE_1_1 + framecount = audioconfig_interface->RecommendSampleFrameCount(pp_instance, sc->sn.speed, 2048); +#else framecount = audioconfig_interface->RecommendSampleFrameCount(sc->sn.speed, 2048); +#endif /*the callback paints directly into the caller's buffer, so we don't need a separate 'dma' buffer*/ sc->selfpainting = true; diff --git a/engine/nacl/sys_ppapi.c b/engine/nacl/sys_ppapi.c index 29ba3ff29..10a9b3fa4 100644 --- a/engine/nacl/sys_ppapi.c +++ b/engine/nacl/sys_ppapi.c @@ -57,6 +57,7 @@ static qboolean mouselocked; static qboolean shuttingdown; qboolean FSPPAPI_Init(int *filenocookie); +qboolean NAGL_SwapPending(void); unsigned short htons(unsigned short a) { @@ -177,11 +178,13 @@ void INS_Shutdown(void) { } +/* //nacl supposedly has no way to implement this (other than us writing a listfile in each directory) int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, int, void *), void *parm) { return 0; } +*/ qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refreshrate) { @@ -204,8 +207,7 @@ NORETURN void VARGS Sys_Error (const char *error, ...) vsnprintf (string, sizeof(string)-1, error, argptr); va_end (argptr); - Sys_Printf("Sys_Error: "); - Sys_Printf("%s", string); + Sys_Printf("Sys_Error: %s", string); exit(1); } @@ -305,30 +307,38 @@ void FrameEvent(void* user_data, int32_t result) } if (pp_instance) { - double newtime = Sys_DoubleTime(); - Host_Frame(newtime - lasttime); - lasttime = newtime; + if (!NAGL_SwapPending()) + { + double newtime = Sys_DoubleTime(); +// Sys_Printf("Frame %f\n", newtime); + Host_Frame(newtime - lasttime); + lasttime = newtime; + } -// Sys_Printf("Frame %f\n", newtime); - - struct PP_CompletionCallback ccb = {FrameEvent, user_data, PP_COMPLETIONCALLBACK_FLAG_NONE}; - ppb_core->CallOnMainThread(0, ccb, 0); + if (!NAGL_SwapPending()) + { + struct PP_CompletionCallback ccb = {FrameEvent, user_data, PP_COMPLETIONCALLBACK_FLAG_NONE}; + ppb_core->CallOnMainThread(0, ccb, 0); + } } } -void startquake(void) +void startquake(char *manif) { - const char *args [] = - { - "ftedroid", - "", - "" - }; + static char *args[16]; quakeparms_t parms; memset(&parms, 0, sizeof(parms)); parms.basedir = ""; /*filled in later*/ - parms.argc = 1; + parms.argc = 0; parms.argv = args; -//FIXME: do something with the embed arguments + + //FIXME: generate some sort of commandline properly. + args[parms.argc++] = "ftedroid"; + if (manif) + { + args[parms.argc++] = "-manifest"; + args[parms.argc++] = manif; + } + parms.memsize = 16*1024*1024; parms.membase = malloc(parms.memsize); if (!parms.membase) @@ -355,7 +365,7 @@ void startquake(void) void trystartquake(void* user_data, int32_t result) { if (FSPPAPI_Init(&result)) - startquake(); + startquake(user_data); else { struct PP_CompletionCallback ccb = {trystartquake, user_data, PP_COMPLETIONCALLBACK_FLAG_NONE}; @@ -368,13 +378,20 @@ static PP_Bool Instance_DidCreate(PP_Instance instance, const char* argn[], const char* argv[]) { + int i; pp_instance = instance; + char *manif = NULL; //FIXME: do something with the embed arguments + for (i = 0; i < argc; i++) + { + if (!strcasecmp(argn[i], "ftemanifest")) + manif = strdup(argv[i]); + } ppb_inputevent_interface->RequestInputEvents(pp_instance, PP_INPUTEVENT_CLASS_MOUSE | PP_INPUTEVENT_CLASS_KEYBOARD | PP_INPUTEVENT_CLASS_WHEEL); - trystartquake(NULL, 0); + trystartquake(manif, 0); return PP_TRUE; } @@ -421,10 +438,24 @@ unsigned int domkeytoquake(unsigned int code) } if (!tab[code]) Con_DPrintf("You just pressed key %u, but I don't know what its meant to be\n", code); + + Con_DPrintf("You just pressed dom key %u, which is quake key %u\n", code, tab[code]); return tab[code]; } -PP_Bool InputEvent_HandleEvent(PP_Instance pp_instance, PP_Resource resource) +static int QuakeButtonForNACLButton(int but) +{ + switch(but) + { + case 1: + return K_MOUSE3; + case 2: + return K_MOUSE2; + default: + return K_MOUSE1 + but; + } +} +static PP_Bool InputEvent_HandleEvent(PP_Instance pp_instance, PP_Resource resource) { extern cvar_t vid_fullscreen; if (!pp_instance || !host_initialized) @@ -448,10 +479,10 @@ PP_Bool InputEvent_HandleEvent(PP_Instance pp_instance, PP_Resource resource) return PP_TRUE; } } - IN_KeyEvent(0, true, K_MOUSE1 + ppb_mouseinputevent_interface->GetButton(resource), 0); + IN_KeyEvent(0, true, QuakeButtonForNACLButton(ppb_mouseinputevent_interface->GetButton(resource)), 0); return PP_TRUE; case PP_INPUTEVENT_TYPE_MOUSEUP: - IN_KeyEvent(0, false, K_MOUSE1 + ppb_mouseinputevent_interface->GetButton(resource), 0); + IN_KeyEvent(0, false, QuakeButtonForNACLButton(ppb_mouseinputevent_interface->GetButton(resource)), 0); return PP_TRUE; case PP_INPUTEVENT_TYPE_MOUSEMOVE: { @@ -478,20 +509,23 @@ PP_Bool InputEvent_HandleEvent(PP_Instance pp_instance, PP_Resource resource) return PP_TRUE; case PP_INPUTEVENT_TYPE_WHEEL: { + static float wheelticks; struct PP_FloatPoint p; p = ppb_wheelinputevent_interface->GetTicks(resource); - //BUG: the value is fractional. - while (p.x >= 1) + + //the value is fractional, so we need some persistant value to track it on high-precision mice. + wheelticks += p.y; + while (wheelticks > 1) { IN_KeyEvent(0, 1, K_MWHEELUP, 0); IN_KeyEvent(0, 0, K_MWHEELUP, 0); - p.x--; + wheelticks--; } - while (p.x <= -1) + while (wheelticks < 0) { IN_KeyEvent(0, 1, K_MWHEELDOWN, 0); IN_KeyEvent(0, 0, K_MWHEELDOWN, 0); - p.x++; + wheelticks++; } } return PP_TRUE; @@ -576,8 +610,6 @@ static void Instance_DidDestroy(PP_Instance instance) void GL_Resized(int width, int height); static void Instance_DidChangeView(PP_Instance instance, PP_Resource view_resource) { - int newwidth; - int newheight; struct PP_Rect rect; ppb_view_instance->GetRect(view_resource, &rect); GL_Resized(rect.size.width, rect.size.height); diff --git a/engine/qclib/pr_edict.c b/engine/qclib/pr_edict.c index 71a6c744c..6b92522c7 100644 --- a/engine/qclib/pr_edict.c +++ b/engine/qclib/pr_edict.c @@ -11,8 +11,6 @@ struct edict_s; #endif -vec3_t vec3_origin; - fdef_t *ED_FieldAtOfs (progfuncs_t *progfuncs, unsigned int ofs); pbool ED_ParseEpair (progfuncs_t *progfuncs, int qcptr, unsigned int fldofs, int fldtype, char *s); diff --git a/engine/server/sv_ents.c b/engine/server/sv_ents.c index 7240bdb5b..be0b4d7ce 100644 --- a/engine/server/sv_ents.c +++ b/engine/server/sv_ents.c @@ -1613,7 +1613,6 @@ void SVDP_EmitEntityDelta(entity_state_t *from, entity_state_t *to, sizebuf_t *m } } -entity_state_t defaultstate; void SVDP_EmitEntitiesUpdate (client_t *client, packet_entities_t *to, sizebuf_t *msg) { edict_t *ent; @@ -1661,7 +1660,7 @@ void SVDP_EmitEntitiesUpdate (client_t *client, packet_entities_t *to, sizebuf_t { // this is a new entity, send it from the baseline... as far as dp understands it... ent = EDICT_NUM(svprogfuncs, newnum); //Con_Printf ("baseline %i\n", newnum); - SVDP_EmitEntityDelta (&defaultstate, &to->entities[newindex], msg, true); + SVDP_EmitEntityDelta (&nullentitystate, &to->entities[newindex], msg, true); newindex++; continue; } diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index ccd8f2ad8..3cba05c40 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -29,14 +29,13 @@ void SV_Loadgame_f (void); #define INVIS_CHAR2 (char)138 #define INVIS_CHAR3 (char)160 -quakeparms_t host_parms; - -qboolean host_initialized; // true if into command execution (compatability) - +#ifdef SERVERONLY double host_frametime; double realtime; // without any filtering or bounding - +qboolean host_initialized; // true if into command execution (compatability) +quakeparms_t host_parms; int host_hunklevel; +#endif // callbacks void SV_Masterlist_Callback(struct cvar_s *var, char *oldvalue); diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index c82c3f4c6..c96c365e0 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -3392,7 +3392,7 @@ void SV_Pause_f (void) if (SV_TogglePause(host_client)) { - if (sv.paused) + if (sv.paused & 1) SV_BroadcastTPrintf (PRINT_HIGH, STL_CLIENTPAUSED, host_client->name); else SV_BroadcastTPrintf (PRINT_HIGH, STL_CLIENTUNPAUSED, host_client->name); diff --git a/engine/shaders/generatebuiltinsl.c b/engine/shaders/generatebuiltinsl.c index 8a9d96fa3..faec07d4e 100644 --- a/engine/shaders/generatebuiltinsl.c +++ b/engine/shaders/generatebuiltinsl.c @@ -15,6 +15,7 @@ char shaders[][64] = "defaultadditivesprite", "defaultskin", "defaultsky", + "defaultfill", "defaultsprite", "defaultwall", "defaultwarp",