From e7c1f9a4902d5fd6af18db84e2c394c75129de28 Mon Sep 17 00:00:00 2001 From: Spoike Date: Sun, 19 Feb 2017 00:15:42 +0000 Subject: [PATCH] rework config.h stuff a little, fixing up numerous ifdefs etc. added some more for potentially smaller builds. make the 'identify' command assume that a single decimal number is not an address (allowing it to be handled as a user id). qcc: support default initialisers in function calls. tweak filesystem code to try to flush individual files instead of discarding the entire fs hash. fix 'snap' stuff. other tweaks... git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5058 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/Makefile | 332 ++-- engine/client/cl_demo.c | 2 +- engine/client/cl_ents.c | 2 + engine/client/cl_parse.c | 11 +- engine/client/cl_screen.c | 36 +- engine/client/cl_tent.c | 6 +- engine/client/in_win.c | 27 +- engine/client/m_multi.c | 2 +- engine/client/m_options.c | 6 +- engine/client/net_master.c | 22 +- engine/client/p_script.c | 8 +- engine/client/pr_csqc.c | 11 +- engine/client/quakedef.h | 2 - engine/client/r_2d.c | 4 - engine/client/r_part.c | 2 +- engine/client/r_partset.c | 2 + engine/client/r_partset.h | 2 + engine/client/r_surf.c | 26 +- engine/client/render.h | 2 +- engine/client/renderer.c | 25 +- engine/client/snd_dma.c | 4 + engine/client/snd_mem.c | 4 +- engine/client/sys_win.c | 5 + engine/client/vid_headless.c | 3 +- engine/client/wad.c | 288 ++-- engine/client/winquake.rc | 4 +- engine/common/bothdefs.h | 126 +- engine/common/bspfile.h | 6 +- engine/common/cmd.c | 1 - engine/common/com_mesh.c | 84 +- engine/common/com_mesh.h | 4 + engine/common/common.c | 6 - engine/common/common.h | 19 +- engine/common/config_wastes.h | 136 ++ engine/common/fs.c | 149 +- engine/common/fs_pak.c | 12 +- engine/common/fs_stdio.c | 4 +- engine/common/fs_win32.c | 6 +- engine/common/fs_zip.c | 146 +- engine/common/gl_q2bsp.c | 250 +-- engine/common/log.c | 8 +- engine/common/plugin.c | 11 +- engine/common/pr_common.h | 24 +- engine/common/world.h | 8 +- engine/d3d/d3d11_backend.c | 2 +- engine/d3d/d3d_backend.c | 18 +- engine/d3d/d3d_shader.c | 14 +- engine/d3d/vid_d3d.c | 6 +- engine/dotnet2005/ftequake.vcproj | 2 +- engine/gl/gl_alias.c | 6 + engine/gl/gl_backend.c | 3 + engine/gl/gl_font.c | 2 +- engine/gl/gl_heightmap.c | 11 +- engine/gl/gl_hlmdl.c | 5 +- engine/gl/gl_model.c | 2366 +++++++++++++------------- engine/gl/gl_model.h | 13 +- engine/gl/gl_shader.c | 100 +- engine/gl/gl_shadow.c | 3 + engine/gl/gl_vidcommon.c | 14 +- engine/gl/gl_vidnt.c | 2 +- engine/gl/glmod_doom.c | 2 +- engine/gl/r_bishaders.h | 46 +- engine/gl/shader.h | 53 +- engine/http/httpclient.c | 21 +- engine/partcfgs/generatebuiltin.c | 5 + engine/qclib/pr_exec.c | 4 +- engine/qclib/qcc.h | 5 + engine/qclib/qcc_pr_comp.c | 68 +- engine/qclib/qcc_pr_lex.c | 54 +- engine/qclib/qccgui.c | 18 +- engine/qclib/qccmain.c | 80 +- engine/server/pr_cmds.c | 565 +++--- engine/server/progdefs.h | 23 +- engine/server/progs.h | 2 - engine/server/savegame.c | 9 +- engine/server/server.h | 4 +- engine/server/sv_ents.c | 25 +- engine/server/sv_mvd.c | 50 +- engine/server/sv_phys.c | 2 +- engine/server/sv_send.c | 4 +- engine/server/world.c | 11 +- engine/shaders/glsl/altwater.glsl | 2 +- engine/shaders/glsl/defaultskin.glsl | 11 +- engine/shaders/glsl/defaultwall.glsl | 11 +- engine/shaders/glsl/defaultwarp.glsl | 1 + engine/shaders/glsl/depthonly.glsl | 10 +- engine/shaders/glsl/rtlight.glsl | 11 +- engine/vk/vk_backend.c | 11 +- engine/web/fs_web.c | 2 +- plugins/mpq/fs_mpq.c | 6 +- 90 files changed, 3126 insertions(+), 2395 deletions(-) create mode 100644 engine/common/config_wastes.h diff --git a/engine/Makefile b/engine/Makefile index c6156878..846d3ff1 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -52,11 +52,30 @@ NATIVE_BASE_DIR?=$(BASE_DIR) NATIVE_RELEASE_DIR?=$(RELEASE_DIR) NATIVE_DEBUG_DIR?=$(DEBUG_DIR) + #include the appropriate games. ifneq (,$(BRANDING)) BRANDFLAGS+=-DBRANDING_INC=../game_$(BRANDING).h -include game_$(BRANDING).mak endif +ifneq (,$(FTE_CONFIG)) + export FTE_CONFIG_EXTRA:=$(shell $(CC) -xc -E -P -DCOMPILE_OPTS common/config_$(FTE_CONFIG).h) + BRANDFLAGS+=-DCONFIG_FILE_NAME=config_$(FTE_CONFIG).h $(FTE_CONFIG_EXTRA) + EXE_NAME=$(FTE_CONFIG) +endif +ifeq (,$(findstring DNO_SPEEX,$(FTE_CONFIG_EXTRA))) + USE_SPEEX=1 +endif +ifeq (,$(findstring DNO_BOTLIB,$(FTE_CONFIG_EXTRA))) + USE_BOTLIB=1 +endif +ifeq (,$(findstring DNO_VORBISFILE,$(FTE_CONFIG_EXTRA))) + USE_VORBISFILE=1 +endif +ifneq (,$(findstring -Os,$(FTE_CONFIG_EXTRA))) + CPUOPTIMIZATIONS+=-Os + BRANDFLAGS:=$(filter-out -O%,$(BRANDFLAGS)) +endif ifeq ($(BITS),64) CC:=$(CC) -m64 @@ -337,7 +356,7 @@ ifneq ($(WPO),) endif #proper/consistant link-time optimisations (requires gcc 4.5+ or so) ifneq ($(LTO),) - LTO_CC=-flto + LTO_CC=-flto -fvisibility=hidden LTO_LD=-flto endif @@ -407,7 +426,6 @@ endif SDL_INCLUDES= #-I$(LIBS_DIR)/sdl/include -I/usr/include/SDL -I$(LIBS_DIR)/sdl/include/SDL -BOTLIB_CFLAGS=-I$(BOTLIB_DIR) -DBOTLIB -DBOTLIB_STATIC BASE_CFLAGS=$(WARNINGFLAGS) $(GNUC_FUNCS) -I$(CLIENT_DIR) -I$(SERVER_DIR) -I$(COMMON_DIR) -I$(GL_DIR) -I$(D3D_DIR) -I$(PROGS_DIR) -I. -I$(LIBS_DIR) -I$(LIBS_DIR)/dxsdk9/include -I$(LIBS_DIR)/dxsdk7/include $(SDL_INCLUDES) -I./libs/freetype2/include -I./libs/freetype2/include/freetype -I./libs/speex $(BOTLIB_CFLAGS) $(SVNREVISION) CLIENT_ONLY_CFLAGS=-DCLIENTONLY SERVER_ONLY_CFLAGS=-DSERVERONLY @@ -421,7 +439,6 @@ ifeq ($(shell LANG=c $(CC) -rdynamic 2>&1 | grep unrecognized),) DEBUG_CFLAGS+= -rdynamic endif -OBJS+=$(SPEEX_OBJS) PROFILE_CFLAGS=-pg DX7SDK=-I./libs/dxsdk7/include/ @@ -430,50 +447,53 @@ GLCFLAGS?=-DGLQUAKE D3DCFLAGS?=-DD3D9QUAKE -DD3D11QUAKE VKCFLAGS?=-DVKQUAKE NPFTECFLAGS=-DNPFTE -SPEEXCFLAGS=-DSPEEX_STATIC -I$(BASE_DIR)/libs/speex/include -DFIXED_POINT -DUSE_KISS_FFT -DEXPORT="" -SPEEX_OBJS = \ - bits.o \ - buffer.o \ - cb_search.o \ - exc_10_16_table.o \ - exc_10_32_table.o \ - exc_20_32_table.o \ - exc_5_256_table.o \ - exc_5_64_table.o \ - exc_8_128_table.o \ - fftwrap.o \ - filterbank.o \ - filters.o \ - gain_table.o \ - gain_table_lbr.o \ - hexc_10_32_table.o \ - hexc_table.o \ - high_lsp_tables.o \ - jitter.o \ - kiss_fft.o \ - kiss_fftr.o \ - lpc.o \ - lsp.o \ - lsp_tables_nb.o \ - ltp.o \ - mdf.o \ - modes.o \ - modes_wb.o \ - nb_celp.o \ - preprocess.o \ - quant_lsp.o \ - resample.o \ - sb_celp.o \ - scal.o \ - smallft.o \ - speex.o \ - speex_callbacks.o \ - speex_header.o \ - stereo.o \ - vbr.o \ - vq.o \ - window.o +ifeq (1,$(USE_SPEEX)) + SPEEXCFLAGS=-DSPEEX_STATIC -I$(BASE_DIR)/libs/speex/include -DFIXED_POINT -DUSE_KISS_FFT -DEXPORT="" + + SPEEX_OBJS = \ + bits.o \ + buffer.o \ + cb_search.o \ + exc_10_16_table.o \ + exc_10_32_table.o \ + exc_20_32_table.o \ + exc_5_256_table.o \ + exc_5_64_table.o \ + exc_8_128_table.o \ + fftwrap.o \ + filterbank.o \ + filters.o \ + gain_table.o \ + gain_table_lbr.o \ + hexc_10_32_table.o \ + hexc_table.o \ + high_lsp_tables.o \ + jitter.o \ + kiss_fft.o \ + kiss_fftr.o \ + lpc.o \ + lsp.o \ + lsp_tables_nb.o \ + ltp.o \ + mdf.o \ + modes.o \ + modes_wb.o \ + nb_celp.o \ + preprocess.o \ + quant_lsp.o \ + resample.o \ + sb_celp.o \ + scal.o \ + smallft.o \ + speex.o \ + speex_callbacks.o \ + speex_header.o \ + stereo.o \ + vbr.o \ + vq.o \ + window.o +endif CLIENT_OBJS = \ textedit.o \ @@ -526,6 +546,7 @@ CLIENT_OBJS = \ snd_mp3.o \ snd_ov.o \ valid.o \ + vid_headless.o \ view.o \ wad.o \ \ @@ -646,7 +667,6 @@ WINDOWS_OBJS = \ cd_win.o \ fs_win32.o \ in_win.o \ - vid_headless.o \ sys_win.o \ sys_win_threads.o \ net_ssl_winsspi.o \ @@ -695,36 +715,46 @@ COMMON_OBJS = \ plugin.o \ q1bsp.o \ q2pmove.o - -BOTLIB_OBJS = \ - be_aas_bspq3.o \ - be_aas_cluster.o \ - be_aas_debug.o \ - be_aas_entity.o \ - be_aas_file.o \ - be_aas_main.o \ - be_aas_move.o \ - be_aas_optimize.o \ - be_aas_reach.o \ - be_aas_route.o \ - be_aas_routealt.o \ - be_aas_sample.o \ - be_ai_char.o \ - be_ai_chat.o \ - be_ai_gen.o \ - be_ai_goal.o \ - be_ai_move.o \ - be_ai_weap.o \ - be_ai_weight.o \ - be_ea.o \ - be_interface.o \ - l_crc.o \ - l_libvar.o \ - l_log.o \ - l_memory.o \ - l_precomp.o \ - l_script.o \ - l_struct.o + +ifeq (1,$(USE_BOTLIB)) + BOTLIB_CFLAGS=-I$(BOTLIB_DIR) -DBOTLIB -DBOTLIB_STATIC + BOTLIB_OBJS = \ + be_aas_bspq3.o \ + be_aas_cluster.o \ + be_aas_debug.o \ + be_aas_entity.o \ + be_aas_file.o \ + be_aas_main.o \ + be_aas_move.o \ + be_aas_optimize.o \ + be_aas_reach.o \ + be_aas_route.o \ + be_aas_routealt.o \ + be_aas_sample.o \ + be_ai_char.o \ + be_ai_chat.o \ + be_ai_gen.o \ + be_ai_goal.o \ + be_ai_move.o \ + be_ai_weap.o \ + be_ai_weight.o \ + be_ea.o \ + be_interface.o \ + l_crc.o \ + l_libvar.o \ + l_log.o \ + l_memory.o \ + l_precomp.o \ + l_script.o \ + l_struct.o +endif + +ifeq (1,$(USE_VORBISFILE)) + LIBVORBISFILE_STATIC=-DLIBVORBISFILE_STATIC +else + OGGVORBISLDFLAGS= + LIBVORBISFILE_STATIC= +endif #the defaults for sdl come first #CC_MACHINE:=$(shell $(CC) -dumpmachine) @@ -743,8 +773,8 @@ SDLCONFIG?=sdl-config FTE_FULLTARGET?=sdl$(FTE_TARGET)$(BITS) GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o -GL_EXE_NAME=../fteqw-gl$(FTE_FULLTARGET) -GLCL_EXE_NAME=../fteqwcl-gl$(FTE_FULLTARGET) +GL_EXE_NAME=../$(EXE_NAME)-gl$(FTE_FULLTARGET) +GLCL_EXE_NAME=../$(EXE_NAME)cl-gl$(FTE_FULLTARGET) #SDLCONFIG:=libs/sdl2_mingw/$(CC_MACHINE)/bin/sdl2-config --prefix=libs/sdl2_mingw/$(CC_MACHINE) ifdef windir @@ -762,14 +792,14 @@ GLCL_DIR=glcl_$(FTE_FULLTARGET) SV_DIR?=sv_$(FTE_FULLTARGET) SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(SERVERONLY_OBJS) $(BOTLIB_OBJS) -SV_EXE_NAME=../fteqw-sv$(FTE_FULLTARGET) +SV_EXE_NAME=../$(EXE_NAME)-sv$(FTE_FULLTARGET) SV_CFLAGS=-DFTE_SDL `$(SDLCONFIG) --cflags` $(SERVER_ONLY_CFLAGS) MINGL_DIR=mingl_$(FTE_FULLTARGET) -MINGL_EXE_NAME=../fteqw-mingl$(FTE_FULLTARGET) +MINGL_EXE_NAME=../$(EXE_NAME)-mingl$(FTE_FULLTARGET) MB_DIR=m_$(FTE_FULLTARGET) -M_EXE_NAME=../fteqw-$(FTE_FULLTARGET) +M_EXE_NAME=../$(EXE_NAME)-$(FTE_FULLTARGET) MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(BOTLIB_OBJS) gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o M_CFLAGS=-DFTE_SDL $(GLCFLAGS) `$(SDLCONFIG) --cflags` @@ -840,13 +870,13 @@ ifeq ($(FTE_TARGET),nacl) GLB_DIR=gl_nacl_$(NARCH) MINGL_DIR=mingl_nacl_$(NARCH) ifeq ($(NARCH),pnacl) - GL_EXE_NAME=../fteqw.pexe - GLCL_EXE_NAME=../fteqw-cl.pexe - MINGL_EXE_NAME=../fteqw-mingl.pexe + GL_EXE_NAME=../$(EXE_NAME).pexe + GLCL_EXE_NAME=../$(EXE_NAME)-cl.pexe + MINGL_EXE_NAME=../$(EXE_NAME)-mingl.pexe else - GL_EXE_NAME=../fteqw-$(NARCH).nexe - GLCL_EXE_NAME=../fteqw-cl-$(NARCH).nexe - MINGL_EXE_NAME=../fteqw-mingl-$(NARCH).nexe + GL_EXE_NAME=../$(EXE_NAME)-$(NARCH).nexe + GLCL_EXE_NAME=../$(EXE_NAME)-cl-$(NARCH).nexe + MINGL_EXE_NAME=../$(EXE_NAME)-mingl-$(NARCH).nexe endif endif @@ -867,8 +897,8 @@ ifeq (win_SDL,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET))) #the defaults for sdl come first GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o snd_directx.o $(LTO_END) resources.o $(LTO_START) - GL_EXE_NAME=../fteqw-sdl-gl$(BITS)$(EXEPOSTFIX) - GLCL_EXE_NAME=../fteqw-sdl-glcl$(BITS)$(EXEPOSTFIX) + GL_EXE_NAME=../$(EXE_NAME)-sdl-gl$(BITS)$(EXEPOSTFIX) + GLCL_EXE_NAME=../$(EXE_NAME)-sdl-glcl$(BITS)$(EXEPOSTFIX) ifdef windir GL_LDFLAGS=$(GLLDFLAGS) -lmingw32 -lws2_32 `$(SDLCONFIG) --static-libs` M_LDFLAGS=$(MLDFLAGS) -lmingw32 -lws2_32 `$(SDLCONFIG) --static-libs` @@ -881,7 +911,7 @@ ifeq (win_SDL,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET))) QCC_LDFLAGS=$(MINGW_LIBS_DIR)/libz.a endif - GL_CFLAGS=-DFTE_SDL -I$(MINGW_LIBS_DIR)/ -I$(MINGW_LIBS_DIR) -I$(LIBS_DIR) $(GLCFLAGS) -DLIBVORBISFILE_STATIC $(DX7SDK) $(SPEEXCFLAGS) + GL_CFLAGS=-DFTE_SDL -I$(MINGW_LIBS_DIR)/ -I$(MINGW_LIBS_DIR) -I$(LIBS_DIR) $(GLCFLAGS) $(LIBVORBISFILE_STATIC) $(DX7SDK) $(SPEEXCFLAGS) ifeq ($(shell echo $(FTE_TARGET)|grep -E -i -v "win32.*sdl"),) GL_CFLAGS+= -D_MINGW_VFPRINTF endif @@ -890,16 +920,16 @@ ifeq (win_SDL,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET))) GLCL_DIR=glcl_mgw_sdl$(BITS) SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(WINDOWSSERVERONLY_OBJS) $(BOTLIB_OBJS) $(LTO_END) resources.o $(LTO_START) - SV_EXE_NAME=../fteqw-sdl-sv$(BITS)$(EXEPOSTFIX) + SV_EXE_NAME=../$(EXE_NAME)-sdl-sv$(BITS)$(EXEPOSTFIX) SV_CFLAGS=$(SERVER_ONLY_CFLAGS) -DFTE_SDL MINGL_DIR=mingl_sdlwin$(BITS) - MINGL_EXE_NAME=../fteqw-sdl-mingl$(BITS)$(EXEPOSTFIX) + MINGL_EXE_NAME=../$(EXE_NAME)-sdl-mingl$(BITS)$(EXEPOSTFIX) MB_DIR=m_mgw_sdl$(BITS) - M_EXE_NAME=../fteqw-sdl$(BITS)$(EXEPOSTFIX) + M_EXE_NAME=../$(EXE_NAME)-sdl$(BITS)$(EXEPOSTFIX) MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(D3DQUAKE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o snd_directx.o $(LTO_END) resources.o $(LTO_START) - M_CFLAGS=$(D3DCFLAGS) -DFTE_SDL -I$(LIBS_DIR) -I$(MINGW_LIBS_DIR)/ -I$(MINGW_LIBS_DIR) $(GLCFLAGS) -DLIBVORBISFILE_STATIC -D_MERGED_SDL $(DX7SDK) $(SPEEXCFLAGS) + M_CFLAGS=$(D3DCFLAGS) -DFTE_SDL -I$(LIBS_DIR) -I$(MINGW_LIBS_DIR)/ -I$(MINGW_LIBS_DIR) $(GLCFLAGS) $(LIBVORBISFILE_STATIC) -D_MERGED_SDL $(DX7SDK) $(SPEEXCFLAGS) ifeq ($(shell echo $(FTE_TARGET)|grep -E -i -v "win32.*sdl"),) M_CFLAGS+= -D_MINGW_VFPRINTF @@ -909,10 +939,10 @@ ifeq (win_SDL,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET))) D3DCL_OBJS=$(D3DQUAKE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o snd_directx.o $(D3DGL_OBJS) $(LTO_END) resources.o $(LTO_START) - D3D_EXE_NAME=../fteqw-sdl-d3d$(BITS)$(EXEPOSTFIX) - D3DCL_EXE_NAME=../fteqw-sdl-d3dcl$(BITS)$(EXEPOSTFIX) + D3D_EXE_NAME=../$(EXE_NAME)-sdl-d3d$(BITS)$(EXEPOSTFIX) + D3DCL_EXE_NAME=../$(EXE_NAME)-sdl-d3dcl$(BITS)$(EXEPOSTFIX) D3D_LDFLAGS=$(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) -lws2_32 -lmingw32 $(SDL_LDFLAGS) -mwindows -ldxguid -lwinmm -lole32 - D3D_CFLAGS=$(D3DCFLAGS) -DFTE_SDL -DNO_XFLIP -I$(LIBS_DIR) -I$(MINGW_LIBS_DIR)/ -I$(MINGW_LIBS_DIR) -DLIBVORBISFILE_STATIC $(DX7SDK) $(SPEEXCFLAGS) + D3D_CFLAGS=$(D3DCFLAGS) -DFTE_SDL -DNO_XFLIP -I$(LIBS_DIR) -I$(MINGW_LIBS_DIR)/ -I$(MINGW_LIBS_DIR) $(LIBVORBISFILE_STATIC) $(DX7SDK) $(SPEEXCFLAGS) ifeq ($(shell echo $(FTE_TARGET)|grep -E -i -v "win32.*sdl"),) D3D_CFLAGS+= -D_MINGW_VFPRINTF endif @@ -921,10 +951,10 @@ ifeq (win_SDL,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET))) VKCL_OBJS=$(D3DQUAKE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o snd_directx.o $(D3DGL_OBJS) $(LTO_END) resources.o $(LTO_START) - VK_EXE_NAME=../fteqw-sdl-vk$(BITS)$(EXEPOSTFIX) - VKCL_EXE_NAME=../fteqw-sdl-vkcl$(BITS)$(EXEPOSTFIX) + VK_EXE_NAME=../$(EXE_NAME)-sdl-vk$(BITS)$(EXEPOSTFIX) + VKCL_EXE_NAME=../$(EXE_NAME)-sdl-vkcl$(BITS)$(EXEPOSTFIX) VK_LDFLAGS=$(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) -lws2_32 -lmingw32 $(SDL_LDFLAGS) -mwindows -ldxguid -lwinmm -lole32 - VK_CFLAGS=$(VKCFLAGS) -DFTE_SDL -DNO_XFLIP -I$(LIBS_DIR) -I$(MINGW_LIBS_DIR)/ -I$(MINGW_LIBS_DIR) -DLIBVORBISFILE_STATIC $(DX7SDK) $(SPEEXCFLAGS) + VK_CFLAGS=$(VKCFLAGS) -DFTE_SDL -DNO_XFLIP -I$(LIBS_DIR) -I$(MINGW_LIBS_DIR)/ -I$(MINGW_LIBS_DIR) $(LIBVORBISFILE_STATIC) $(DX7SDK) $(SPEEXCFLAGS) ifeq ($(shell echo $(FTE_TARGET)|grep -E -i -v "win32.*sdl"),) VK_CFLAGS+= -D_MINGW_VFPRINTF endif @@ -1001,13 +1031,13 @@ ifeq ($(FTE_TARGET),vc) BASE_CFLAGS:=$(WARNINGFLAGS) $(GNUC_FUNCS) -I$(shell cygpath -m $(CLIENT_DIR)) -I$(shell cygpath -m $(SERVER_DIR)) -I$(shell cygpath -m $(COMMON_DIR)) -I$(shell cygpath -m $(GL_DIR)) -I$(shell cygpath -m $(D3D_DIR)) -I$(shell cygpath -m $(PROGS_DIR)) -I. -I$(LIBS_DIR) -I$(LIBS_DIR)/dxsdk9/include -I$(LIBS_DIR)/dxsdk7/include $(SDL_INCLUDES) -I./libs/freetype2/include -I./libs/freetype2/include/freetype -I./libs/speex $(BOTLIB_CFLAGS) $(SVNREVISION) SV_CFLAGS=$(SERVER_ONLY_CFLAGS) $(W32_CFLAGS) -DMULTITHREAD -DMSVCLIBPATH=libs/ - SV_EXE_NAME=../fteqw-sv$(BITS)$(EXEPOSTFIX) + SV_EXE_NAME=../$(EXE_NAME)-sv$(BITS)$(EXEPOSTFIX) SV_DIR=sv_vc$(BITS) SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(BOTLIB_OBJS) $(PROGS_OBJS) $(WINDOWSSERVERONLY_OBJS) fs_win32.o resources.o SV_LDFLAGS=/subsystem:console - GL_EXE_NAME=../fteqw-gl$(BITS)$(EXEPOSTFIX) - GLCL_EXE_NAME=../fteqw-mingl$(BITS) + GL_EXE_NAME=../$(EXE_NAME)-gl$(BITS)$(EXEPOSTFIX) + GLCL_EXE_NAME=../$(EXE_NAME)-mingl$(BITS) GLB_DIR=gl_vc$(BITS) GLCL_DIR=glcl_vc$(BITS) GL_LDFLAGS=$(GLLDFLAGS) $(JPEGLIB) libs/libpng$(BITS).lib uuid.lib gdi32.lib ole32.lib /subsystem:windows @@ -1016,17 +1046,17 @@ ifeq ($(FTE_TARGET),vc) GL_OBJS= MINGL_DIR=mingl_vc$(BITS) - MINGL_EXE_NAME=../fteqw-mingl$(BITS)$(EXEPOSTFIX) + MINGL_EXE_NAME=../$(EXE_NAME)-mingl$(BITS)$(EXEPOSTFIX) D3DCL_OBJS=$(D3DQUAKE_OBJS) $(D3DGL_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) $(WINDOWS_OBJS) - D3D_EXE_NAME=../fteqw-d3d$(BITS)$(EXEPOSTFIX) - D3DCL_EXE_NAME=../fteqw-d3dcl$(BITS)$(EXEPOSTFIX) + D3D_EXE_NAME=../$(EXE_NAME)-d3d$(BITS)$(EXEPOSTFIX) + D3DCL_EXE_NAME=../$(EXE_NAME)-d3dcl$(BITS)$(EXEPOSTFIX) D3D_LDFLAGS=$(JPEGLIB) libs/libpng$(BITS).lib uuid.lib gdi32.lib ole32.lib /subsystem:windows D3D_CFLAGS=$(D3DCFLAGS) $(W32_CFLAGS) $(DX7SDK) -DMULTITHREAD $(SPEEXCFLAGS) -DMSVCLIBPATH=libs/ D3DB_DIR=d3d_vc$(BITS) D3DCL_DIR=d3dcl_vc$(BITS) - M_EXE_NAME=../fteqw$(BITS)$(EXEPOSTFIX) + M_EXE_NAME=../$(EXE_NAME)$(BITS)$(EXEPOSTFIX) MCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(D3DQUAKE_OBJS) $(GLQUAKE_OBJS) gl_vidnt.o $(BOTLIB_OBJS) $(SPEEX_OBJS) $(WINDOWS_OBJS) M_CFLAGS=$(D3DCFLAGS) $(GLCFLAGS) $(W32_CFLAGS) $(D3DCFLAGS) -DMULTITHREAD $(SPEEXCFLAGS) -DMSVCLIBPATH=libs/ MB_DIR=m_vc$(BITS) @@ -1060,7 +1090,7 @@ ifeq (win,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET))) EXEPOSTFIX=.exe LIBS_DIR = $(BASE_DIR)/libs - SV_EXE_NAME=../fteqwsv$(BITS)$(EXEPOSTFIX) + SV_EXE_NAME=../$(EXE_NAME)sv$(BITS)$(EXEPOSTFIX) SV_LDFLAGS=$(MINGW_LIBS_DIR)/libz.a -lws2_32 -lwinmm SV_DIR=sv_mingw$(BITS) SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(WINDOWSSERVERONLY_OBJS) $(BOTLIB_OBJS) fs_win32.o $(LTO_END) resources.o $(LTO_START) @@ -1071,7 +1101,7 @@ ifeq (win,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET))) GL_EXE_NAME=../fteglqw$(BITS)$(EXEPOSTFIX) GLCL_EXE_NAME=../fteglqwcl$(BITS)$(EXEPOSTFIX) GL_LDFLAGS=$(GLLDFLAGS) $(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) -ldxguid -lws2_32 -lwinmm -lgdi32 -lole32 -Wl,--subsystem,windows - GL_CFLAGS=$(GLCFLAGS) $(W32_CFLAGS) $(DX7SDK) -DMULTITHREAD -DLIBVORBISFILE_STATIC $(SPEEXCFLAGS) + GL_CFLAGS=$(GLCFLAGS) $(W32_CFLAGS) $(DX7SDK) -DMULTITHREAD $(LIBVORBISFILE_STATIC) $(SPEEXCFLAGS) GLB_DIR=gl_mgw$(BITS) GLCL_DIR=glcl_mgw$(BITS) @@ -1082,10 +1112,10 @@ ifeq (win,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET))) NPFTEB_DIR=npfte_mgw$(BITS) MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(D3DQUAKE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) gl_vidnt.o gl_videgl.o $(WINDOWS_OBJS) - M_EXE_NAME=../fteqw$(BITS)$(EXEPOSTFIX) - MCL_EXE_NAME=../fteqwcl$(BITS)$(EXEPOSTFIX) + M_EXE_NAME=../$(EXE_NAME)$(BITS)$(EXEPOSTFIX) + MCL_EXE_NAME=../$(EXE_NAME)cl$(BITS)$(EXEPOSTFIX) M_LDFLAGS=$(GLLDFLAGS) $(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) -ldxguid -lws2_32 -lwinmm -lgdi32 -lole32 -Wl,--subsystem,windows - M_CFLAGS=$(GLCFLAGS) $(W32_CFLAGS) $(D3DCFLAGS) $(DX7SDK) $(VKCFLAGS) -DMULTITHREAD -DLIBVORBISFILE_STATIC $(SPEEXCFLAGS) + M_CFLAGS=$(GLCFLAGS) $(W32_CFLAGS) $(D3DCFLAGS) $(DX7SDK) $(VKCFLAGS) -DMULTITHREAD $(LIBVORBISFILE_STATIC) $(SPEEXCFLAGS) MB_DIR=m_mgw$(BITS) MCL_DIR=mcl_mgw$(BITS) @@ -1093,7 +1123,7 @@ ifeq (win,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET))) D3D_EXE_NAME=../fted3dqw$(BITS)$(EXEPOSTFIX) D3DCL_EXE_NAME=../fted3dclqw$(BITS)$(EXEPOSTFIX) D3D_LDFLAGS=$(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) -ldxguid -lws2_32 -lwinmm -lgdi32 -lole32 -Wl,--subsystem,windows - D3D_CFLAGS=$(D3DCFLAGS) $(W32_CFLAGS) $(DX7SDK) -DMULTITHREAD -DLIBVORBISFILE_STATIC $(SPEEXCFLAGS) + D3D_CFLAGS=$(D3DCFLAGS) $(W32_CFLAGS) $(DX7SDK) -DMULTITHREAD $(LIBVORBISFILE_STATIC) $(SPEEXCFLAGS) D3DB_DIR=d3d_mgw$(BITS) D3DCL_DIR=d3dcl_mgw$(BITS) @@ -1101,7 +1131,7 @@ ifeq (win,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET))) VK_EXE_NAME=../ftevkqw$(BITS)$(EXEPOSTFIX) VKCL_EXE_NAME=../ftevkclqw$(BITS)$(EXEPOSTFIX) VK_LDFLAGS=$(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) -ldxguid -lws2_32 -lwinmm -lgdi32 -lole32 -Wl,--subsystem,windows - VK_CFLAGS=$(VKCFLAGS) $(W32_CFLAGS) $(DX7SDK) -DMULTITHREAD -DLIBVORBISFILE_STATIC $(SPEEXCFLAGS) + VK_CFLAGS=$(VKCFLAGS) $(W32_CFLAGS) $(DX7SDK) -DMULTITHREAD $(LIBVORBISFILE_STATIC) $(SPEEXCFLAGS) VKB_DIR=vk_mgw$(BITS) VKCL_DIR=vkcl_mgw$(BITS) @@ -1127,29 +1157,29 @@ ifeq ($(FTE_TARGET),bsd) SV_CFLAGS=$(SERVER_ONLY_CFLAGS) GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o sys_linux_threads.o - GL_EXE_NAME=../fteqw-gl - GLCL_EXE_NAME=../fteqw-glcl + GL_EXE_NAME=../$(EXE_NAME)-gl + GLCL_EXE_NAME=../$(EXE_NAME)-glcl GL_LDFLAGS= -L/usr/local/lib $(GLLDFLAGS) $(XLDFLAGS) -lpthread GL_CFLAGS=$(GLCFLAGS) -I/usr/local/include -I/usr/X11R6/include GLB_DIR=gl_bsd GLCL_DIR=glcl_bsd MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(BOTLIB_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o sys_linux_threads.o - M_EXE_NAME=../fteqw - MCL_EXE_NAME=../fteqw-cl + M_EXE_NAME=../$(EXE_NAME) + MCL_EXE_NAME=../$(EXE_NAME)-cl M_LDFLAGS=$(GLLDFLAGS) $(XLDFLAGS) -lpthread M_CFLAGS=$(VKCFLAGS) $(GLCFLAGS) -I/usr/X11R6/include MB_DIR=m_bsd MCL_DIR=mcl_bsd - MINGL_EXE_NAME=../fteqw-mingl + MINGL_EXE_NAME=../$(EXE_NAME)-mingl MINGL_DIR=mingl_bsd endif ifneq (,$(findstring linux,$(FTE_TARGET))) OGGVORBISLDFLAGS= SV_DIR=sv_linux$(BITS) - SV_EXE_NAME=../fteqw-sv$(BITS) + SV_EXE_NAME=../$(EXE_NAME)-sv$(BITS) SV_LDFLAGS= SV_CFLAGS=$(SERVER_ONLY_CFLAGS) -DMULTITHREAD @@ -1161,25 +1191,25 @@ ifneq (,$(findstring linux,$(FTE_TARGET))) NPFTE_CFLAGS=$(NPFTECFLAGS) $(W32_CFLAGS) -DMULTITHREAD -fPIC -DDYNAMIC_LIBPNG -DDYNAMIC_LIBJPEG NPFTEB_DIR=npfte_linux$(BITS) - GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) vid_headless.o gl_vidlinuxglx.o gl_videgl.o snd_alsa.o snd_linux.o snd_sdl.o cd_linux.o sys_linux.o sys_linux_threads.o - GL_EXE_NAME=../fteqw-gl$(BITS) - GLCL_EXE_NAME=../fteqw-glcl$(BITS) + GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) gl_vidlinuxglx.o gl_videgl.o snd_alsa.o snd_linux.o snd_sdl.o cd_linux.o sys_linux.o sys_linux_threads.o + GL_EXE_NAME=../$(EXE_NAME)-gl$(BITS) + GLCL_EXE_NAME=../$(EXE_NAME)-glcl$(BITS) GL_LDFLAGS=$(GLLDFLAGS) $(XLDFLAGS) $(OGGVORBISLDFLAGS) GL_CFLAGS=$(GLCFLAGS) -I/usr/X11R6/include $(SPEEXCFLAGS) -DMULTITHREAD -DDYNAMIC_LIBPNG -DDYNAMIC_LIBJPEG -DDYNAMIC_SDL GLB_DIR=gl_linux$(BITS) GLCL_DIR=glcl_linux$(BITS) VKCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) gl_vidlinuxglx.o gl_videgl.o snd_alsa.o snd_linux.o snd_sdl.o cd_linux.o sys_linux.o sys_linux_threads.o - VK_EXE_NAME=../fteqw-vk$(BITS) - VKCL_EXE_NAME=../fteqw-vkcl$(BITS) + VK_EXE_NAME=../$(EXE_NAME)-vk$(BITS) + VKCL_EXE_NAME=../$(EXE_NAME)-vkcl$(BITS) VK_LDFLAGS=$(GLLDFLAGS) $(XLDFLAGS) $(OGGVORBISLDFLAGS) VK_CFLAGS=$(VKCFLAGS) -I/usr/X11R6/include $(SPEEXCFLAGS) -DMULTITHREAD -DDYNAMIC_LIBPNG -DDYNAMIC_LIBJPEG -DDYNAMIC_SDL VKB_DIR=vk_linux$(BITS) VKCL_DIR=vkcl_linux$(BITS) MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) gl_vidlinuxglx.o gl_videgl.o snd_linux.o snd_sdl.o snd_alsa.o cd_linux.o sys_linux.o sys_linux_threads.o - M_EXE_NAME=../fteqw$(BITS) - MCL_EXE_NAME=../fteqw-cl$(BITS) + M_EXE_NAME=../$(EXE_NAME)$(BITS) + MCL_EXE_NAME=../$(EXE_NAME)-cl$(BITS) M_LDFLAGS=$(GL_LDFLAGS) M_CFLAGS=$(VKCFLAGS) $(GL_CFLAGS) MB_DIR=m_linux$(BITS) @@ -1195,7 +1225,7 @@ ifneq (,$(findstring linux,$(FTE_TARGET))) endif - MINGL_EXE_NAME=../fteqw-mingl$(BITS) + MINGL_EXE_NAME=../$(EXE_NAME)-mingl$(BITS) MINGL_DIR=mingl_linux$(BITS) ifeq ($(NOCOMPAT),1) @@ -1241,15 +1271,15 @@ ifneq ($(shell echo $(FTE_TARGET)|grep macosx),) GL_LDFLAGS=-framework AGL -framework OpenGL -framework Cocoa -framework AudioUnit -lz -lpng -ljpeg GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) gl_vidcocoa.mo gl_vidmacos.o sys_linux.o cd_null.o snd_macos.o sys_linux_threads.o - GL_EXE_NAME=../fteqw-macosx-gl$(EXTENSION)$(BITS) - GLCL_EXE_NAME=../fteqwcl-macosx-gl$(EXTENSION)$(BITS) - M_EXE_NAME=../fteqw-macosx$(EXTENSION)$(BITS) - MCL_EXE_NAME=../fteqw-macosx-cl$(EXTENSION)$(BITS) - MINGL_EXE_NAME=../fteqw-macosx-mingl$(EXTENSION)$(BITS) + GL_EXE_NAME=../$(EXE_NAME)-macosx-gl$(EXTENSION)$(BITS) + GLCL_EXE_NAME=../$(EXE_NAME)cl-macosx-gl$(EXTENSION)$(BITS) + M_EXE_NAME=../$(EXE_NAME)-macosx$(EXTENSION)$(BITS) + MCL_EXE_NAME=../$(EXE_NAME)-macosx-cl$(EXTENSION)$(BITS) + MINGL_EXE_NAME=../$(EXE_NAME)-macosx-mingl$(EXTENSION)$(BITS) MINGL_DIR=mingl_macosx$(EXTENSION)$(BITS) SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(BOTLIB_OBJS) $(SERVERONLY_OBJS) - SV_EXE_NAME=../fteqw-macosx-sv$(EXTENSION)$(BITS) + SV_EXE_NAME=../$(EXE_NAME)-macosx-sv$(EXTENSION)$(BITS) SV_CFLAGS=$(SERVER_ONLY_CFLAGS) SV_LDFLAGS=-lz @@ -1267,26 +1297,26 @@ ifeq ($(FTE_TARGET),morphos) OGGVORBISLDFLAGS= GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) gl_vidmorphos.o in_morphos.o snd_morphos.o cd_null.o sys_morphos.o - GL_EXE_NAME=../fteqw-morphos-gl - GLCL_EXE_NAME=../fteqw-morphos-glcl + GL_EXE_NAME=../$(EXE_NAME)-morphos-gl + GLCL_EXE_NAME=../$(EXE_NAME)-morphos-glcl GL_LDFLAGS=$(GLLDFLAGS) -ldl $(IMAGELDFLAGS) -lz GL_CFLAGS=$(GLCFLAGS) -noixemul -I./libs/speex -I./ GLB_DIR=gl_morphos GLCL_DIR=glcl_morphos MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(BOTLIB_OBJS) gl_vidmorphos.o vid_morphos.o in_morphos.o snd_morphos.o cd_null.o sys_morphos.o - M_EXE_NAME=../fteqw-morphos - MCL_EXE_NAME=../fteqw-morphos-cl + M_EXE_NAME=../$(EXE_NAME)-morphos + MCL_EXE_NAME=../$(EXE_NAME)-morphos-cl M_LDFLAGS=$(GLLDFLAGS) M_CFLAGS=$(GLCFLAGS) MB_DIR=m_morphos MCL_DIR=mcl_morphos - MINGL_EXE_NAME=../fteqw-morphos-mingl + MINGL_EXE_NAME=../$(EXE_NAME)-morphos-mingl MINGL_DIR=mingl_morphos SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(SERVERONLY_OBJS) $(BOTLIB_OBJS) - SV_EXE_NAME=../fteqw-morphos-sv$(BITS) + SV_EXE_NAME=../$(EXE_NAME)-morphos-sv$(BITS) SV_CFLAGS=$(SERVER_ONLY_CFLAGS) endif @@ -1298,24 +1328,24 @@ ifeq ($(FTE_TARGET),cyg) EXEPOSTFIX=.exe GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o sys_linux_threads.o - GL_EXE_NAME=../fteqw-cyg-gl$(EXEPOSTFIX) - GLCL_EXE_NAME=../fteqw-cyg-glcl$(EXEPOSTFIX) + GL_EXE_NAME=../$(EXE_NAME)-cyg-gl$(EXEPOSTFIX) + GLCL_EXE_NAME=../$(EXE_NAME)-cyg-glcl$(EXEPOSTFIX) GL_LDFLAGS=$(GLLDFLAGS) $(XLDFLAGS) $(OGGVORBISLDFLAGS) -lz -lltdl - GL_CFLAGS=$(GLCFLAGS) -I/usr/X11R6/include $(SPEEXCFLAGS) -DLIBVORBISFILE_STATIC -DUSE_LIBTOOL + GL_CFLAGS=$(GLCFLAGS) -I/usr/X11R6/include $(SPEEXCFLAGS) $(LIBVORBISFILE_STATIC) -DUSE_LIBTOOL GLB_DIR=gl_cygwin GLCL_DIR=glcl_cygwin MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o sys_linux_threads.o - M_EXE_NAME=../fteqw-cyg$(EXEPOSTFIX) - MCL_EXE_NAME=../fteqw-cyg-cl$(EXEPOSTFIX) + M_EXE_NAME=../$(EXE_NAME)-cyg$(EXEPOSTFIX) + MCL_EXE_NAME=../$(EXE_NAME)-cyg-cl$(EXEPOSTFIX) M_LDFLAGS=$(GLLDFLAGS) $(XLDFLAGS) $(OGGVORBISLDFLAGS) -lz -lltdl - M_CFLAGS=$(GLCFLAGS) $(SPEEXCFLAGS) -DLIBVORBISFILE_STATIC -DUSE_LIBTOOL + M_CFLAGS=$(GLCFLAGS) $(SPEEXCFLAGS) $(LIBVORBISFILE_STATIC) -DUSE_LIBTOOL MB_DIR=m_cygwin MCL_DIR=mcl_cygwin LIBS_DIR = $(BASE_DIR)/libs - MINGL_EXE_NAME=../fteqw-cyg-mingl$(EXEPOSTFIX) + MINGL_EXE_NAME=../$(EXE_NAME)-cyg-mingl$(EXEPOSTFIX) MINGL_DIR=mingl_cygwin endif @@ -1962,7 +1992,7 @@ INSTALL ?= install INSTALL_PROGRAM ?= $(INSTALL) INSTALL_DATA ?= ${INSTALL} -m 644 install: sv-rel gl-rel mingl-rel qcc-rel - $(INSTALL_PROGRAM) $(RELEASE_DIR)/fteqw-gl $(DESTDIR)$(bindir)/fteqw-gl - $(INSTALL_PROGRAM) $(RELEASE_DIR)/fteqw-mingl $(DESTDIR)$(bindir)/fteqw-mingl - $(INSTALL_PROGRAM) $(RELEASE_DIR)/fteqw-sv $(DESTDIR)$(bindir)/fteqw-sv + $(INSTALL_PROGRAM) $(RELEASE_DIR)/$(EXE_NAME)-gl $(DESTDIR)$(bindir)/$(EXE_NAME)-gl + $(INSTALL_PROGRAM) $(RELEASE_DIR)/$(EXE_NAME)-mingl $(DESTDIR)$(bindir)/$(EXE_NAME)-mingl + $(INSTALL_PROGRAM) $(RELEASE_DIR)/$(EXE_NAME)-sv $(DESTDIR)$(bindir)/$(EXE_NAME)-sv $(INSTALL_PROGRAM) $(RELEASE_DIR)/fteqcc $(DESTDIR)$(bindir)/fteqcc diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index a39aabbe..449ec24a 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -979,7 +979,7 @@ void CL_Stop_f (void) cls.demorecording = false; Con_Printf ("Completed demo\n"); - FS_FlushFSHash(); + FS_FlushFSHashFull(); //FIXME: single name } void CL_WriteRecordQ2DemoMessage(sizebuf_t *msg) diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index 5107160d..64fad97e 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -3990,8 +3990,10 @@ void CL_LinkPacketEntities (void) // set skin ent->skinnum = state->skinnum; +#ifdef HEXEN2 ent->abslight = state->abslight; ent->drawflags = state->hexen2flags; +#endif CL_LerpNetFrameState(&ent->framestate, le); diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 823e0083..64224bc4 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -764,7 +764,7 @@ void CL_DownloadFinished(qdownload_t *dl) DL_Abort(dl, QDL_COMPLETED); - COM_RefreshFSCache_f(); + FS_FlushFSHashWritten(dl->tempname); COM_FileExtension(filename, ext, sizeof(ext)); @@ -1028,7 +1028,7 @@ qboolean CL_CheckHLBspWads(char *file) qboolean CL_CheckQ2BspWals(char *file) { qboolean gotone = false; - +#ifdef Q2BSPS q2dheader_t *dh; lump_t lump; q2texinfo_t *tinf; @@ -1063,6 +1063,7 @@ qboolean CL_CheckQ2BspWals(char *file) gotone = true; } } +#endif return gotone; } @@ -2530,7 +2531,7 @@ void CL_ParseDownload (qboolean zlib) if (zlib) { -#ifdef AVAIL_ZLIB +#if defined(AVAIL_ZLIB) && defined(Q2CLIENT) z_stream s; unsigned short clen = size; unsigned short ulen = MSG_ReadShort(); @@ -4410,7 +4411,10 @@ void CL_ParseStaticProt (int baselinetype) ent->framestate.g[FS_REG].frame[0] = ent->framestate.g[FS_REG].frame[1] = es.frame; ent->framestate.g[FS_REG].lerpweight[0] = 1; ent->skinnum = es.skinnum; +#ifdef HEXEN2 ent->drawflags = es.hexen2flags; + ent->abslight = es.abslight; +#endif #ifdef PEXT_SCALE ent->scale = es.scale/16.0; @@ -4420,7 +4424,6 @@ void CL_ParseStaticProt (int baselinetype) ent->shaderRGBAf[2] = (8.0f/256.0f)*es.colormod[2]; ent->fatness = es.fatness/16.0; - ent->abslight = es.abslight; ent->flags = 0; if (es.dpflags & RENDER_VIEWMODEL) diff --git a/engine/client/cl_screen.c b/engine/client/cl_screen.c index 2fed51bd..7a3c8249 100644 --- a/engine/client/cl_screen.c +++ b/engine/client/cl_screen.c @@ -2770,6 +2770,10 @@ qboolean SCR_RSShot (void) char st[80]; time_t now; enum uploadfmt fmt; + int src_size; + int src_red; + int src_green; + int src_blue; if (!scr_allowsnap.ival) return false; @@ -2794,8 +2798,23 @@ qboolean SCR_RSShot (void) if (fmt == TF_INVALID) return false; - if (fmt != TF_RGB24) + switch(fmt) { + case TF_RGB24: + case TF_RGBA32: + src_size = (fmt==TF_RGB24)?3:4; + src_red = 0; + src_green = 1; + src_blue = 2; + break; + case TF_BGR24: + case TF_BGRA32: + src_size = (fmt==TF_BGR24)?3:4; + src_red = 2; + src_green = 1; + src_blue = 0; + break; + default: BZ_Free(newbuf); return false; } @@ -2809,7 +2828,7 @@ qboolean SCR_RSShot (void) //scale down first. for (y = 0; y < h; y++) { - dest = newbuf + (w*3 * y); + dest = newbuf + (w*src_size * y); for (x = 0; x < w; x++) { r = g = b = 0; @@ -2823,11 +2842,12 @@ qboolean SCR_RSShot (void) count = 0; for (/* */; dy < dey; dy++) { - src = newbuf + (truewidth * 3 * dy) + dx * 3; + src = newbuf + (truewidth * src_size * dy) + dx * src_size; for (nx = dx; nx < dex; nx++) { - r += *src++; - g += *src++; - b += *src++; + r += src[src_red]; + g += src[src_green]; + b += src[src_blue]; + src += src_size; count++; } } @@ -2842,12 +2862,12 @@ qboolean SCR_RSShot (void) // convert to eight bit for (y = 0; y < h; y++) { - src = newbuf + (w * 3 * y); + src = newbuf + (w * src_size * y); dest = newbuf + (w * y); for (x = 0; x < w; x++) { *dest++ = MipColor(src[0], src[1], src[2]); - src += 3; + src += src_size; } } diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index cd53452d..fd5ebdbb 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -3685,8 +3685,10 @@ void CL_UpdateBeams (void) return; VectorCopy (org, ent->origin); ent->model = type->model; +#ifdef HEXEN2 ent->drawflags |= MLS_ABSLIGHT; ent->abslight = 64 + 128 * bound(0, cl_shaftlight.value, 1); +#endif ent->shaderRGBAf[3] = b->alpha; ent->flags = b->rflags; @@ -3832,7 +3834,9 @@ void CL_UpdateExplosions (void) ent->shaderRGBAf[3] = (1.0 - f/(numframes))*(ex->startalpha-ex->endalpha) + ex->endalpha; ent->flags = ex->flags; ent->scale = scale*ex->scale; - ent->drawflags = SCALE_ORIGIN_ORIGIN; +#ifdef HEXEN2 + ent->drawflags = SCALE_ORIGIN_ORIGIN; +#endif if (ex->traileffect != P_INVALID) pe->ParticleTrail(ent->oldorigin, ent->origin, ex->traileffect, 0, ent->axis, &(ex->trailstate)); diff --git a/engine/client/in_win.c b/engine/client/in_win.c index 79841b86..e28c292f 100644 --- a/engine/client/in_win.c +++ b/engine/client/in_win.c @@ -97,7 +97,7 @@ HRESULT (WINAPI *pDirectInputCreate)(HINSTANCE hinst, DWORD dwVersion, #define DINPUT_VERSION_DX7 0x0700 // mouse variables -static cvar_t in_dinput = CVARF("in_dinput","0", CVAR_ARCHIVE); +static cvar_t in_dinput = CVARFD("in_dinput","0", CVAR_ARCHIVE, "Enables the use of dinput for mouse movements"); static cvar_t in_xinput = CVARFD("in_xinput","0", CVAR_ARCHIVE, "Enables the use of xinput for controllers.\nNote that if you have a headset plugged in, that headset will be used for audio playback if no specific audio device is configured."); static cvar_t in_builtinkeymap = CVARF("in_builtinkeymap", "0", CVAR_ARCHIVE); static cvar_t in_simulatemultitouch = CVAR("in_simulatemultitouch", "0"); @@ -143,7 +143,6 @@ static int originalmouseparms[3], newmouseparms[3] = {0, 0, 0}; qboolean mouseinitialized; static qboolean mouseparmsvalid, mouseactivatetoggle; qboolean mouseshowtoggle = 1; -static qboolean dinput_acquired; unsigned int uiWheelMessage; qboolean mouseactive; @@ -160,7 +159,7 @@ qboolean mouseactive; // each time. this avoids any problems with getting back to a default usage // or when changing from one controller to another. this way at least something // works. -static cvar_t in_joystick = CVARF("joystick","0", CVAR_ARCHIVE); +static cvar_t in_joystick = CVARAF("joystick","0", "in_joystick", CVAR_ARCHIVE); static qboolean joy_advancedinit; static DWORD joy_flags; @@ -191,6 +190,7 @@ static const GUID fIID_IDirectInput7A = {0x9a4cb684, 0x236d, 0x11d3, {0x8e, 0x9 // devices static LPDIRECTINPUT g_pdi; static LPDIRECTINPUTDEVICE g_pMouse; +static qboolean dinput_acquired; static HINSTANCE hInstDI; @@ -659,7 +659,7 @@ INS_InitDInput */ int INS_InitDInput (void) { - HRESULT hr; + HRESULT hr; DIPROPDWORD dipdw = { { sizeof(DIPROPDWORD), // diph.dwSize @@ -1834,6 +1834,7 @@ void INS_Commands (void) K_JOY4, //XINPUT_GAMEPAD_B K_JOY1, //XINPUT_GAMEPAD_X K_JOY3, //XINPUT_GAMEPAD_Y + K_AUX9, //left trigger K_AUX10 //right trigger }; @@ -2113,6 +2114,7 @@ void INS_EnumerateDevices(void *ctx, void(*callback)(void *ctx, const char *type for (idx = 0; idx < rawmicecount; idx++) callback(ctx, "mouse", rawmice[idx].sysname?rawmice[idx].sysname:va("raw%i", idx), &rawmice[idx].qdeviceid); +#ifdef AVAIL_DINPUT #if (DIRECTINPUT_VERSION >= DINPUT_VERSION_DX7) if (dinput >= DINPUT_VERSION_DX7 && g_pMouse7) callback(ctx, "mouse", "di7", NULL); @@ -2120,6 +2122,7 @@ void INS_EnumerateDevices(void *ctx, void(*callback)(void *ctx, const char *type #endif if (dinput && g_pMouse) callback(ctx, "mouse", "di", NULL); +#endif callback(ctx, "mouse", "system", NULL); for (idx = 0; idx < joy_count; idx++) @@ -2136,8 +2139,8 @@ void INS_EnumerateDevices(void *ctx, void(*callback)(void *ctx, const char *type static qbyte scantokey[] = { -// 0 1 2 3 4 5 6 7 -// 8 9 A B C D E F +// 0 1 2 3 4 5 6 7 +// 8 9 A B C D E F 0, 27, '1', '2', '3', '4', '5', '6', // 0 '7', '8', '9', '0', '-', '=', K_BACKSPACE, 9, // 0 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', // 1 @@ -2154,8 +2157,8 @@ static qbyte scantokey[] = 0, 0, 0, 0, 0, 0, 0, 0, // 6 0, 0, 0, 0, 0, 0, 0, 0, // 7 0, 0, 0, 0, 0, 0, 0, 0, // 7 -// 0 1 2 3 4 5 6 7 -// 8 9 A B C D E F +// 0 1 2 3 4 5 6 7 +// 8 9 A B C D E F 0, 0, 0, 0, 0, 0, 0, 0, // 8 0, 0, 0, 0, 0, 0, 0, 0, // 8 0, 0, 0, 0, 0, 0, 0, 0, // 9 @@ -2172,8 +2175,8 @@ static qbyte scantokey[] = 0, 0, 0, 0, 0, 0, 0, 0, // e 0, 0, 0, 0, 0, 0, 0, 0, // f 0, 0, 0, 0, 0, 0, 0, 0, // f -// 0 1 2 3 4 5 6 7 -// 8 9 A B C D E F +// 0 1 2 3 4 5 6 7 +// 8 9 A B C D E F 0, 27, '1', '2', '3', '4', '5', '6', // 0 '7', '8', '9', '0', '-', '=', K_BACKSPACE, 9, // 0 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', // 1 @@ -2190,8 +2193,8 @@ static qbyte scantokey[] = 0, 0, 0, 0, 0, 0, 0, 0, // 6 0, 0, 0, 0, 0, 0, 0, 0, // 7 0, 0, 0, 0, 0, 0, 0, 0 // 7 -// 0 1 2 3 4 5 6 7 -// 8 9 A B C D E F +// 0 1 2 3 4 5 6 7 +// 8 9 A B C D E F }; /* diff --git a/engine/client/m_multi.c b/engine/client/m_multi.c index 681e9fc5..423f50ae 100644 --- a/engine/client/m_multi.c +++ b/engine/client/m_multi.c @@ -1019,7 +1019,7 @@ void M_Menu_Network_f (void) MB_EDITCVARSLIM("Rate", "rate", "Maximum bytes per second that the server should send to the client"), MB_EDITCVARSLIM("Download Rate", "drate", "Maximum bytes per second that the server should send maps and demos to the client"), MB_SPACING(4), - MB_CHECKBOXCVARTIP("Require Download", requiredownloads, 0, "Ignore downloaded content sent to the client and connect immediatly"), + MB_CHECKBOXCVARTIP("Require Download", requiredownloads, 0, "Ignore downloaded content sent to the client and connect immediately"), MB_CHECKBOXCVARTIP("Redirect Download", cl_download_redirection, 0, "Whether the client will ignore download redirection from servers"), MB_CHECKBOXCVARTIP("Download CSQC", cl_download_csprogs, 0, "Whether to allow the client to download CSQC (client-side QuakeC) progs from servers"), MB_SPACING(4), diff --git a/engine/client/m_options.c b/engine/client/m_options.c index 5834102f..14cd2d5d 100644 --- a/engine/client/m_options.c +++ b/engine/client/m_options.c @@ -1190,11 +1190,11 @@ void M_Menu_Textures_f (void) static const char *texturesizeoptions[] = { "128", - "196", +// "192", "256", - "384", +// "384", "512", - "768", +// "768", "1024", "2048", "4096", diff --git a/engine/client/net_master.c b/engine/client/net_master.c index a07e652a..205fa19e 100644 --- a/engine/client/net_master.c +++ b/engine/client/net_master.c @@ -78,6 +78,7 @@ typedef struct { #endif } net_masterlist_t; net_masterlist_t net_masterlist[] = { +#ifndef QUAKETC //user-specified master lists. {MP_QUAKEWORLD, CVARC("net_qwmaster1", "", Net_Masterlist_Callback)}, {MP_QUAKEWORLD, CVARC("net_qwmaster2", "", Net_Masterlist_Callback)}, @@ -87,6 +88,7 @@ net_masterlist_t net_masterlist[] = { {MP_QUAKEWORLD, CVARC("net_qwmaster6", "", Net_Masterlist_Callback)}, {MP_QUAKEWORLD, CVARC("net_qwmaster7", "", Net_Masterlist_Callback)}, {MP_QUAKEWORLD, CVARC("net_qwmaster8", "", Net_Masterlist_Callback)}, +#endif //dpmaster is the generic non-quake-specific master protocol that we use for custom stand-alone mods. {MP_DPMASTER, CVARAFC("net_master1", "", "sv_master1", 0, Net_Masterlist_Callback)}, @@ -98,16 +100,21 @@ net_masterlist_t net_masterlist[] = { {MP_DPMASTER, CVARAFC("net_master7", "", "sv_master7", 0, Net_Masterlist_Callback)}, {MP_DPMASTER, CVARAFC("net_master8", "", "sv_master8", 0, Net_Masterlist_Callback)}, +#ifdef Q2CLIENT {MP_QUAKE2, CVARC("net_q2master1", "", Net_Masterlist_Callback)}, {MP_QUAKE2, CVARC("net_q2master2", "", Net_Masterlist_Callback)}, {MP_QUAKE2, CVARC("net_q2master3", "", Net_Masterlist_Callback)}, {MP_QUAKE2, CVARC("net_q2master4", "", Net_Masterlist_Callback)}, +#endif +#ifdef Q3CLIENT {MP_QUAKE3, CVARC("net_q3master1", "", Net_Masterlist_Callback)}, {MP_QUAKE3, CVARC("net_q3master2", "", Net_Masterlist_Callback)}, {MP_QUAKE3, CVARC("net_q3master3", "", Net_Masterlist_Callback)}, {MP_QUAKE3, CVARC("net_q3master4", "", Net_Masterlist_Callback)}, +#endif +#ifndef QUAKETC //engine-specified/maintained master lists (so users can be lazy and update the engine without having to rewrite all their configs). {MP_QUAKEWORLD, CVARFC("net_qwmasterextra1", "qwmaster.ocrana.de:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "Ocrana(2nd)"}, //german. admin unknown {MP_QUAKEWORLD, CVARFC("net_qwmasterextra2", ""/*"masterserver.exhale.de:27000" seems dead*/, CVAR_NOSAVE, Net_Masterlist_Callback)}, //german. admin unknown @@ -129,18 +136,23 @@ net_masterlist_t net_masterlist[] = { // {MP_QUAKEWORLD, CVARFC("net_qwmasterextraHistoric", "kubus.rulez.pl:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "kubus.rulez.pl"}, // {MP_QUAKEWORLD, CVARFC("net_qwmasterextraHistoric", "telefrag.me:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "telefrag.me"}, // {MP_QUAKEWORLD, CVARFC("net_qwmasterextraHistoric", "master.teamdamage.com:27000", CVAR_NOSAVE, Net_Masterlist_Callback), "master.teamdamage.com"}, +#endif {MP_DPMASTER, CVARFC("net_masterextra1", "ghdigital.com:27950 207.55.114.154:27950", CVAR_NOSAVE, Net_Masterlist_Callback)}, //207.55.114.154 (was 69.59.212.88 (admin: LordHavoc) {MP_DPMASTER, CVARFC("net_masterextra2", "dpmaster.deathmask.net:27950 107.161.23.68:27950 [2604:180::4ac:98c1]:27950", CVAR_NOSAVE, Net_Masterlist_Callback)}, //107.161.23.68 (admin: Willis) {MP_DPMASTER, CVARFC("net_masterextra3", "dpmaster.tchr.no:27950 92.62.40.73:27950", CVAR_NOSAVE, Net_Masterlist_Callback)}, //92.62.40.73 (admin: tChr) +#ifdef Q2CLIENT // {MP_QUAKE2, CVARFC("net_q2masterextra1", "satan.idsoftware.com:27900", CVAR_NOSAVE, Net_Masterlist_Callback), "Official Quake2 master server"}, // {MP_QUAKE2, CVARFC("net_q2masterextra1", "master.planetgloom.com:27900", CVAR_NOSAVE, Net_Masterlist_Callback)}, //? // {MP_QUAKE2, CVARFC("net_q2masterextra1", "master.q2servers.com:27900", CVAR_NOSAVE, Net_Masterlist_Callback)}, //? {MP_QUAKE2, CVARFC("net_q2masterextra1", "netdome.biz:27900", CVAR_NOSAVE, Net_Masterlist_Callback)}, //? +#endif +#ifdef Q3CLIENT // {MP_QUAKE3, CVARFC("net_q3masterextra1", "masterserver.exhale.de:27950", CVAR_NOSAVE, Net_Masterlist_Callback), "Official Quake3 master server"}, {MP_QUAKE3, CVARFC("net_q3masterextra1", "master.quake3arena.com:27950", CVAR_NOSAVE, Net_Masterlist_Callback), "Official Quake3 master server"}, +#endif {MP_UNSPECIFIED, CVAR(NULL, NULL)} }; @@ -2549,17 +2561,25 @@ void MasterInfo_Refresh(void) int i; Master_LoadMasterList("servers.txt", false, MT_MASTERUDP, MP_QUAKEWORLD, 1); + Master_AddMaster("255.255.255.255:"STRINGIFY(PORT_QWSERVER), MT_BCAST, MP_QUAKEWORLD, "Nearby QuakeWorld UDP servers."); +#ifndef QUAKETC Master_AddMasterHTTP("http://www.gameaholic.com/servers/qspy-quakeworld", MT_MASTERHTTP, MP_QUAKEWORLD, "gameaholic's QW master"); Master_AddMasterHTTP("https://www.quakeservers.net/lists/servers/global.txt",MT_MASTERHTTP, MP_QUAKEWORLD, "QuakeServers.net (http)"); - Master_AddMaster("255.255.255.255:"STRINGIFY(PORT_QWSERVER), MT_BCAST, MP_QUAKEWORLD, "Nearby QuakeWorld UDP servers."); +#endif +#ifdef NQPROT Master_AddMasterHTTP("http://www.gameaholic.com/servers/qspy-quake", MT_MASTERHTTP, MP_NETQUAKE, "gameaholic's NQ master"); Master_AddMasterHTTP("http://servers.quakeone.com/index.php?format=json", MT_MASTERHTTPJSON, MP_NETQUAKE, "quakeone's server listing"); Master_AddMaster("255.255.255.255:"STRINGIFY(PORT_NQSERVER), MT_BCAST, MP_NETQUAKE, "Nearby Quake1 servers"); Master_AddMaster("255.255.255.255:"STRINGIFY(PORT_NQSERVER), MT_BCAST, MP_DPMASTER, "Nearby DarkPlaces servers"); +#endif +#ifdef Q2CLIENT Master_AddMasterHTTP("http://www.gameaholic.com/servers/qspy-quake2", MT_MASTERHTTP, MP_QUAKE2, "gameaholic's Q2 master"); Master_AddMaster("255.255.255.255:27910", MT_BCAST, MP_QUAKE2, "Nearby Quake2 UDP servers."); +#endif +#ifdef Q3CLIENT Master_AddMasterHTTP("http://www.gameaholic.com/servers/qspy-quake3", MT_MASTERHTTP, MP_QUAKE3, "gameaholic's Q3 master"); Master_AddMaster("255.255.255.255:"STRINGIFY(PORT_Q3SERVER), MT_BCAST, MP_QUAKE3, "Nearby Quake3 UDP servers."); +#endif for (i = 0; net_masterlist[i].cv.name; i++) { diff --git a/engine/client/p_script.c b/engine/client/p_script.c index 24d7c32b..1fcb34de 100644 --- a/engine/client/p_script.c +++ b/engine/client/p_script.c @@ -2223,6 +2223,7 @@ parsefluid: qboolean PScript_Query(int typenum, int body, char *outstr, int outstrlen) { +#ifndef QUAKETC int i; part_type_t *ptype = &part_type[typenum]; if (typenum < 0 || typenum >= numparticletypes) @@ -2529,7 +2530,7 @@ qboolean PScript_Query(int typenum, int body, char *outstr, int outstrlen) return true; } - +#endif return false; } @@ -3625,9 +3626,12 @@ static void QDECL R_ParticleDesc_Callback(struct cvar_s *var, char *oldvalue) } //if we didn't manage to load any, make sure SOMETHING got loaded... +#ifdef PSET_CLASSIC if (!count) P_LoadParticleSet("classic", true, true); - else if (failure) + else +#endif + if (failure) P_LoadParticleSet("high", true, true); if (cls.state) diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index 6b5ad332..e913b9c5 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -81,7 +81,7 @@ cvar_t pr_csqc_memsize = CVAR("pr_csqc_memsize", "-1"); cvar_t cl_csqcdebug = CVAR("cl_csqcdebug", "0"); //prints entity numbers which arrive (so I can tell people not to apply it to players...) cvar_t cl_nocsqc = CVAR("cl_nocsqc", "0"); cvar_t pr_csqc_coreonerror = CVAR("pr_csqc_coreonerror", "1"); -#ifdef NOLEGACY +#if defined(NOBUILTINMENUS) && !defined(MENU_DAT) cvar_t pr_csqc_formenus = CVARF("pr_csqc_formenus", "1", CVAR_NOSET); #else cvar_t pr_csqc_formenus = CVAR("pr_csqc_formenus", "0"); @@ -875,6 +875,10 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out) VectorCopy(in->xv->glowmod, out->glowmod); +#ifdef HEXEN2 + out->drawflags = in->xv->drawflags; + out->abslight = in->xv->abslight; +#endif out->skinnum = in->v->skin; out->fatness = in->xv->fatness; ival = in->xv->forceshader; @@ -4680,7 +4684,10 @@ void CSQC_EntStateToCSQC(unsigned int flags, float lerptime, entity_state_t *src ent->v->skin = src->skinnum; ent->xv->scale = src->scale/16.0f; ent->xv->fatness = src->fatness/16.0f; -// ent->xv->drawflags = src->hexen2flags; +#ifdef HEXEN2 + ent->xv->drawflags = src->hexen2flags; + ent->xv->abslight = src->abslight; +#endif // ent->xv->abslight = src->abslight; // ent->v->dpflags = src->dpflags; ent->xv->colormod[0] = src->colormod[0]*(8/256.0f); diff --git a/engine/client/quakedef.h b/engine/client/quakedef.h index 7ce8002d..7bc2f684 100644 --- a/engine/client/quakedef.h +++ b/engine/client/quakedef.h @@ -177,9 +177,7 @@ extern "C" { #include "progtype.h" #include "progdefs.h" -#ifndef CLIENTONLY #include "progs.h" -#endif #include "world.h" #include "q2game.h" #include "../http/iweb.h" diff --git a/engine/client/r_2d.c b/engine/client/r_2d.c index 203176d6..b2d4bc2a 100644 --- a/engine/client/r_2d.c +++ b/engine/client/r_2d.c @@ -202,10 +202,6 @@ void R2D_Init(void) } -#ifdef warningmsg -#pragma warningmsg("Fixme: move conwidth handling into here") -#endif - glossval = min(gl_specular_fallback.value*255, 255); glossval *= 0x10101; glossval |= 0x01000000 * bound(0, (int)(gl_specular_fallbackexp.value*255), 255); diff --git a/engine/client/r_part.c b/engine/client/r_part.c index 8aab13b5..6a0bf37f 100644 --- a/engine/client/r_part.c +++ b/engine/client/r_part.c @@ -598,7 +598,7 @@ static void QDECL R_ParticleSystem_Callback(struct cvar_s *var, char *oldvalue) cvar_t r_decal_noperpendicular = CVARD("r_decal_noperpendicular", "1", "When enabled, decals will not be generated on planes at a steep angle from clipped decal orientation."); cvar_t r_rockettrail = CVARFC("r_rockettrail", "1", CVAR_SEMICHEAT, R_Rockettrail_Callback); cvar_t r_grenadetrail = CVARFC("r_grenadetrail", "1", CVAR_SEMICHEAT, R_Grenadetrail_Callback); -#ifdef NOLEGACY +#ifndef PSET_CLASSIC cvar_t r_particlesystem = CVARFC("r_particlesystem", "script", CVAR_SEMICHEAT|CVAR_ARCHIVE|CVAR_NOSET, R_ParticleSystem_Callback); cvar_t r_particledesc = CVARAF("r_particledesc", "", "r_particlesdesc", CVAR_SEMICHEAT|CVAR_ARCHIVE); #else diff --git a/engine/client/r_partset.c b/engine/client/r_partset.c index 453d05b8..7c3670d5 100644 --- a/engine/client/r_partset.c +++ b/engine/client/r_partset.c @@ -4,6 +4,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND */ #include "bothdefs.h" +#ifndef QUAKETC #include "r_partset.h" @@ -4298,3 +4299,4 @@ char *particle_set_tsshaft = "assoc lflash\n" "}\n" ; +#endif diff --git a/engine/client/r_partset.h b/engine/client/r_partset.h index 0435cea1..614a030a 100644 --- a/engine/client/r_partset.h +++ b/engine/client/r_partset.h @@ -3,6 +3,7 @@ WARNING: THIS FILE IS GENERATED BY 'generatebuiltin.c'. YOU SHOULD NOT EDIT THIS FILE BY HAND */ +#ifndef QUAKETC extern char *particle_set_spikeset; #define R_PARTSET_BUILTINS_spikeset {"spikeset", &particle_set_spikeset}, extern char *particle_set_faithful; @@ -28,3 +29,4 @@ extern char *particle_set_q2part; extern char *particle_set_tsshaft; #define R_PARTSET_BUILTINS_tsshaft {"tsshaft", &particle_set_tsshaft}, #define R_PARTSET_BUILTINS R_PARTSET_BUILTINS_spikeset R_PARTSET_BUILTINS_faithful R_PARTSET_BUILTINS_highfps R_PARTSET_BUILTINS_high R_PARTSET_BUILTINS_minimal R_PARTSET_BUILTINS_h2part R_PARTSET_BUILTINS_q2part R_PARTSET_BUILTINS_tsshaft +#endif diff --git a/engine/client/r_surf.c b/engine/client/r_surf.c index 79680ff9..dc6b8c62 100644 --- a/engine/client/r_surf.c +++ b/engine/client/r_surf.c @@ -1170,7 +1170,7 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest, } } -#ifdef THREADEDWORLD +#if defined(THREADEDWORLD) && (defined(Q1BSPS)||defined(Q2BSPS)) static void Surf_BuildLightMap_Worker (model_t *wmodel, msurface_t *surf, qbyte *dest, qbyte *deluxdest, stmap *stainsrc, int shift, int ambient, unsigned int lmwidth, int *d_lightstylevalue) { int smax, tmax; @@ -1570,7 +1570,7 @@ dynamic: } } -#ifdef THREADEDWORLD +#if defined(THREADEDWORLD) && (defined(Q1BSPS)||defined(Q2BSPS)) static void Surf_RenderDynamicLightmaps_Worker (model_t *wmodel, msurface_t *fa, int *d_lightstylevalue) { qbyte *base, *luxbase; @@ -1805,6 +1805,8 @@ static qbyte *Surf_MaskVis(qbyte *src, qbyte *dest) } */ qbyte *frustumvis; + +#ifdef Q1BSPS /* ================ R_RecursiveWorldNode @@ -1987,6 +1989,7 @@ static void Surf_OrthoRecursiveWorldNode (mnode_t *node, unsigned int clipflags) } return; } +#endif #ifdef Q2BSPS static void Surf_RecursiveQ2WorldNode (mnode_t *node) @@ -2568,6 +2571,7 @@ void Surf_GenBrushBatches(batch_t **batches, entity_t *ent) } Surf_LightmapShift(model); +#ifdef HEXEN2 if ((ent->drawflags & MLS_MASK) == MLS_ABSLIGHT) { //update lightmaps. @@ -2581,6 +2585,7 @@ void Surf_GenBrushBatches(batch_t **batches, entity_t *ent) Surf_RenderAmbientLightmaps (s, 255); } else +#endif { //update lightmaps. for (s = model->surfaces+model->firstmodelsurface,i = 0; i < model->nummodelsurfaces; i++, s++) @@ -2592,11 +2597,13 @@ void Surf_GenBrushBatches(batch_t **batches, entity_t *ent) bef = BEF_PUSHDEPTH; if (ent->flags & RF_ADDITIVE) bef |= BEF_FORCEADDITIVE; +#ifdef HEXEN2 else if ((ent->drawflags & DRF_TRANSLUCENT) && r_wateralpha.value != 1) { bef |= BEF_FORCETRANSPARENT; ent->shaderRGBAf[3] = r_wateralpha.value; } +#endif else if ((ent->flags & RF_TRANSLUCENT) && cls.protocol != CP_QUAKE3) bef |= BEF_FORCETRANSPARENT; if (ent->flags & RF_NODEPTHTEST) @@ -2786,6 +2793,7 @@ void R_GeneratedWorldEBO(void *ctx, void *data, size_t a_, size_t b_) } } } +#ifdef Q1BSPS static void Surf_SimpleWorld_Q1BSP(struct webostate_s *es, qbyte *pvs) { mleaf_t *leaf; @@ -2826,7 +2834,8 @@ static void Surf_SimpleWorld_Q1BSP(struct webostate_s *es, qbyte *pvs) } } } -#if defined(Q2BSP) || defined(Q3BSP) +#endif +#if defined(Q2BSPS) || defined(Q3BSPS) static void Surf_SimpleWorld_Q3BSP(struct webostate_s *es, qbyte *pvs) { mleaf_t *leaf; @@ -2886,7 +2895,7 @@ void R_GenWorldEBO(void *ctx, void *data, size_t a, size_t b) es->batches[i].idxbuffer = NULL; } -#if defined(Q2BSP) || defined(Q3BSP) +#if defined(Q2BSPS) || defined(Q3BSPS) if (es->wmodel->fromgame == fg_quake2 || es->wmodel->fromgame == fg_quake3) { if (es->cluster[1] != -1 && es->cluster[0] != es->cluster[1]) @@ -3094,7 +3103,7 @@ void Surf_DrawWorld (void) } else #endif -#ifdef Q2BSPS +#if defined(Q2BSPS) || defined(Q3BSPS) if (currentmodel->fromgame == fg_quake2 || currentmodel->fromgame == fg_quake3) { frustumvis = frustumvis_; @@ -3116,11 +3125,18 @@ void Surf_DrawWorld (void) } else #endif +#ifdef Q2BSPS + if (currentmodel->fromgame == fg_quake2) { entvis = surfvis = R_MarkLeaves_Q2 (); VectorCopy (r_refdef.vieworg, modelorg); Surf_RecursiveQ2WorldNode (currentmodel->nodes); } + else +#endif + { + entvis = surfvis = NULL; + } surfvis = frustumvis; } diff --git a/engine/client/render.h b/engine/client/render.h index a9d9f5a7..ecb2e87c 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -148,7 +148,7 @@ typedef struct entity_s #ifdef PEXT_FATNESS float fatness; #endif -#ifdef PEXT_HEXEN2 +#ifdef HEXEN2 int drawflags; int abslight; #endif diff --git a/engine/client/renderer.c b/engine/client/renderer.c index edcffa1b..7c3afbdd 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -1030,27 +1030,30 @@ rendererinfo_t dedicatedrendererinfo = { "" }; -rendererinfo_t *pdedicatedrendererinfo = &dedicatedrendererinfo; #ifdef GLQUAKE extern rendererinfo_t openglrendererinfo; -rendererinfo_t eglrendererinfo; +#ifdef USE_EGL +extern rendererinfo_t eglrendererinfo; +#endif extern rendererinfo_t rpirendererinfo; rendererinfo_t waylandrendererinfo; rendererinfo_t fbdevrendererinfo; #endif #ifdef D3DQUAKE -rendererinfo_t d3d9rendererinfo; -rendererinfo_t d3d11rendererinfo; +extern rendererinfo_t d3d9rendererinfo; +extern rendererinfo_t d3d11rendererinfo; #endif #ifdef SWQUAKE -rendererinfo_t swrendererinfo; +extern rendererinfo_t swrendererinfo; #endif #ifdef VKQUAKE -rendererinfo_t vkrendererinfo; +extern rendererinfo_t vkrendererinfo; //rendererinfo_t headlessvkrendererinfo; #endif -rendererinfo_t headlessrenderer; +#ifdef HEADLESSQUAKE +extern rendererinfo_t headlessrenderer; +#endif rendererinfo_t *rendererinfo[] = { @@ -1059,12 +1062,16 @@ rendererinfo_t *rendererinfo[] = &rpirendererinfo, #endif &openglrendererinfo, +#ifdef USE_EGL &eglrendererinfo, +#endif &waylandrendererinfo, &fbdevrendererinfo, #endif -#ifdef D3DQUAKE +#ifdef D3D9QUAKE &d3d9rendererinfo, +#endif +#ifdef D3D11QUAKE &d3d11rendererinfo, #endif #ifdef SWQUAKE @@ -1076,10 +1083,12 @@ rendererinfo_t *rendererinfo[] = #ifndef NPQTV &dedicatedrendererinfo, #endif +#ifdef HEADLESSQUAKE &headlessrenderer, #ifdef VKQUAKE //&headlessvkrendererinfo, #endif +#endif }; diff --git a/engine/client/snd_dma.c b/engine/client/snd_dma.c index 1396d187..8bef9927 100644 --- a/engine/client/snd_dma.c +++ b/engine/client/snd_dma.c @@ -905,7 +905,9 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf) unsigned int encpos;//in bytes short *start; unsigned int initseq;//in frames +#ifdef SUPPORT_ICE unsigned int inittimestamp;//in samples +#endif unsigned int samps; float level; int len; @@ -1128,7 +1130,9 @@ void S_Voip_Transmit(unsigned char clc, sizebuf_t *buf) } initseq = s_voip.encsequence; +#ifdef SUPPORT_ICE inittimestamp = s_voip.enctimestamp; +#endif level = 0; samps=0; //*2 for 16bit audio input. diff --git a/engine/client/snd_mem.c b/engine/client/snd_mem.c index a03eca85..a0626cc2 100644 --- a/engine/client/snd_mem.c +++ b/engine/client/snd_mem.c @@ -606,7 +606,7 @@ static qboolean ResampleSfx (sfx_t *sfx, int inrate, int inchannels, int inwidth } //============================================================================= -#ifdef DOOMWADS +#ifdef PACKAGE_DOOMWAD #define DSPK_RATE 140 #define DSPK_BASE 170.0 #define DSPK_EXP 0.0433 @@ -771,7 +771,7 @@ static S_LoadSound_t AudioInputPlugins[10] = S_LoadOVSound, #endif S_LoadWavSound, -#ifdef DOOMWADS +#ifdef PACKAGE_DOOMWAD S_LoadDoomSound, // S_LoadDoomSpeakerSound, #endif diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index a2613f95..e8fd6031 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -3625,6 +3625,9 @@ static void Sys_MakeInstaller(const char *name) #if defined(_MSC_VER) && defined(_AMD64_) #pragma optimize( "", off) //64bit msvc sucks and falls over when trying to inline Host_Frame #endif +#ifdef __GNUC__ +__attribute__((visibility("default"))) +#endif int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // MSG msg; @@ -4045,6 +4048,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin #pragma optimize( "", on) //revert back to default optimisations again. #endif +#if 0 //define this if you're somehow getting windows' consle subsystem instead of the proper windows one int __cdecl main(void) { char *cmdline; @@ -4067,6 +4071,7 @@ int __cdecl main(void) } return WinMain(GetModuleHandle(NULL), NULL, cmdline, SW_NORMAL); } +#endif //now queries at startup and then caches, to avoid mode changes from giving weird results. qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refreshrate) diff --git a/engine/client/vid_headless.c b/engine/client/vid_headless.c index c8f80577..33b72e91 100644 --- a/engine/client/vid_headless.c +++ b/engine/client/vid_headless.c @@ -1,4 +1,5 @@ #include "quakedef.h" +#ifdef HEADLESSQUAKE #ifndef SERVERONLY #include "gl_draw.h" #include "shader.h" @@ -388,5 +389,5 @@ rendererinfo_t headlessvkrendererinfo = "no more" }; #endif - +#endif #endif diff --git a/engine/client/wad.c b/engine/client/wad.c index 61ad5e81..1cc8f580 100644 --- a/engine/client/wad.c +++ b/engine/client/wad.c @@ -21,10 +21,24 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" +void *wadmutex; + +#ifndef PACKAGE_WAD +void Wads_Flush (void){} +qboolean Wad_NextDownload (void){return true;} +void *W_SafeGetLumpName (const char *name, size_t *size) {return NULL;} +qbyte *W_GetTexture(const char *name, int *width, int *height, qboolean *usesalpha){return NULL;} +void W_LoadWadFile (char *filename){} +void W_Shutdown (void){} +void CL_Skygroup_f(void){} +#else + int wad_numlumps; lumpinfo_t *wad_lumps; qbyte *wad_base; +static char wads[4096]; + void SwapPic (qpic_t *pic); /* @@ -267,7 +281,6 @@ typedef struct } texwadlump_t; int numwadtextures; static texwadlump_t texwadlump[TEXWAD_MAXIMAGES]; -void *wadmutex; wadfile_t *openwadfiles; @@ -698,141 +711,6 @@ void CL_Skygroup_f(void) } } -char wads[4096]; -void Mod_ParseInfoFromEntityLump(model_t *wmodel) //actually, this should be in the model code. -{ - char token[4096]; - char key[128]; - const char *data = Mod_GetEntitiesString(wmodel); - mapskys_t *msky; - - cl.skyrotate = 0; - VectorClear(cl.skyaxis); - - wads[0] = '\0'; - -#ifndef CLIENTONLY - if (isDedicated) //don't bother - return; -#endif - - // this hack is necessary to ensure Quake 2 maps get their default skybox, without breaking q1 etc - if (wmodel->fromgame == fg_quake2) - strcpy(cl.skyname, "unit1_"); - else - cl.skyname[0] = '\0'; - - if (data) - if ((data=COM_ParseOut(data, token, sizeof(token)))) //read the map info. - if (token[0] == '{') - while (1) - { - if (!(data=COM_ParseOut(data, token, sizeof(token)))) - break; // error - if (token[0] == '}') - break; // end of worldspawn - if (token[0] == '_') - Q_strncpyz(key, token + 1, sizeof(key)); //_ vars are for comments/utility stuff that arn't visible to progs. Ignore them. - else - Q_strncpyz(key, token, sizeof(key)); - if (!((data=COM_ParseOut(data, token, sizeof(token))))) - break; // error - if (!strcmp("wad", key)) // for HalfLife maps - { - if (1) - { - Q_strncatz(wads, ";", sizeof(wads)); //cache it for later (so that we don't play with any temp memory yet) - Q_strncatz(wads, token, sizeof(wads)); //cache it for later (so that we don't play with any temp memory yet) - } - } - else if (!strcmp("skyname", key)) // for HalfLife maps - { - Q_strncpyz(cl.skyname, token, sizeof(cl.skyname)); - } - else if (!strcmp("fog", key)) //q1 extension. FIXME: should be made temporary. - { - key[0] = 'f'; - key[1] = 'o'; - key[2] = 'g'; - key[3] = ' '; - Q_strncpyz(key+4, token, sizeof(key)-4); - Cbuf_AddText(key, RESTRICT_INSECURE); - Cbuf_AddText("\n", RESTRICT_INSECURE); - } - else if (!strcmp("waterfog", key)) //q1 extension. FIXME: should be made temporary. - { - memcpy(key, "waterfog ", 9); - Q_strncpyz(key+9, token, sizeof(key)-9); - Cbuf_AddText(key, RESTRICT_INSECURE); - Cbuf_AddText("\n", RESTRICT_INSECURE); - } - else if (!strncmp("cvar_", key, 5)) //override cvars so mappers don't end up hacking cvars and fucking over configs (at least in other engines). - { - cvar_t *var = Cvar_FindVar(key+5); - if (var && !(var->flags & CVAR_NOTFROMSERVER)) - Cvar_LockFromServer(var, com_token); - } - else if (!strcmp("wateralpha", key)) //override cvars so mappers don't end up hacking cvars and fucking over configs (at least in other engines). - { - Cvar_LockFromServer(&r_wateralpha, com_token); - Cvar_LockFromServer(&r_waterstyle, "1"); //force vanilla-style water too. - } - else if (!strcmp("slimealpha", key)) - { - Cvar_LockFromServer(&r_slimealpha, com_token); - Cvar_LockFromServer(&r_slimestyle, "1"); - } - else if (!strcmp("lavaalpha", key)) - { - Cvar_LockFromServer(&r_lavaalpha, com_token); - Cvar_LockFromServer(&r_lavastyle, "1"); - } - else if (!strcmp("telealpha", key)) - { - Cvar_LockFromServer(&r_telealpha, com_token); - Cvar_LockFromServer(&r_telestyle, "1"); - } - else if (!strcmp("sky", key)) // for Quake2 maps - { - Q_strncpyz(cl.skyname, token, sizeof(cl.skyname)); - } - else if (!strcmp("skyrotate", key)) //q2 feature - { - cl.skyrotate = atof(token); - } - else if (!strcmp("skyaxis", key)) //q2 feature - { - char *s; - Q_strncpyz(key, token, sizeof(key)); - s = COM_ParseOut(key, token, sizeof(token)); - if (s) - { - cl.skyaxis[0] = atof(s); - s = COM_ParseOut(s, token, sizeof(token)); - if (s) - { - cl.skyaxis[1] = atof(s); - COM_ParseOut(s, token, sizeof(token)); - if (s) - cl.skyaxis[2] = atof(s); - } - } - } - } - - COM_FileBase (wmodel->name, token, sizeof(token)); - - //map-specific sky override feature - for (msky = mapskies; msky; msky = msky->next) - { - if (!strcmp(msky->mapname, token)) - { - Q_strncpyz(cl.skyname, msky->skyname, sizeof(cl.skyname)); - break; - } - } -} - //textures/fred.wad is the DP standard - I wanna go for that one. //textures/halfline/fred.wad is what fuhquake can use (yuck). //fred.wad is what half-life supports. @@ -915,3 +793,141 @@ qboolean Wad_NextDownload (void) } return true; } +#endif + +void Mod_ParseInfoFromEntityLump(model_t *wmodel) //actually, this should be in the model code. +{ + char token[4096]; + char key[128]; + const char *data = Mod_GetEntitiesString(wmodel); +#ifdef PACKAGE_WAD + mapskys_t *msky; + + wads[0] = '\0'; +#endif + + cl.skyrotate = 0; + VectorClear(cl.skyaxis); + +#ifndef CLIENTONLY + if (isDedicated) //don't bother + return; +#endif + + // this hack is necessary to ensure Quake 2 maps get their default skybox, without breaking q1 etc + if (wmodel->fromgame == fg_quake2) + strcpy(cl.skyname, "unit1_"); + else + cl.skyname[0] = '\0'; + + if (data) + if ((data=COM_ParseOut(data, token, sizeof(token)))) //read the map info. + if (token[0] == '{') + while (1) + { + if (!(data=COM_ParseOut(data, token, sizeof(token)))) + break; // error + if (token[0] == '}') + break; // end of worldspawn + if (token[0] == '_') + Q_strncpyz(key, token + 1, sizeof(key)); //_ vars are for comments/utility stuff that arn't visible to progs. Ignore them. + else + Q_strncpyz(key, token, sizeof(key)); + if (!((data=COM_ParseOut(data, token, sizeof(token))))) + break; // error + if (!strcmp("wad", key)) // for HalfLife maps + { +#ifdef PACKAGE_WAD + Q_strncatz(wads, ";", sizeof(wads)); //cache it for later (so that we don't play with any temp memory yet) + Q_strncatz(wads, token, sizeof(wads)); //cache it for later (so that we don't play with any temp memory yet) +#endif + } + else if (!strcmp("skyname", key)) // for HalfLife maps + { + Q_strncpyz(cl.skyname, token, sizeof(cl.skyname)); + } + else if (!strcmp("fog", key)) //q1 extension. FIXME: should be made temporary. + { + key[0] = 'f'; + key[1] = 'o'; + key[2] = 'g'; + key[3] = ' '; + Q_strncpyz(key+4, token, sizeof(key)-4); + Cbuf_AddText(key, RESTRICT_INSECURE); + Cbuf_AddText("\n", RESTRICT_INSECURE); + } + else if (!strcmp("waterfog", key)) //q1 extension. FIXME: should be made temporary. + { + memcpy(key, "waterfog ", 9); + Q_strncpyz(key+9, token, sizeof(key)-9); + Cbuf_AddText(key, RESTRICT_INSECURE); + Cbuf_AddText("\n", RESTRICT_INSECURE); + } + else if (!strncmp("cvar_", key, 5)) //override cvars so mappers don't end up hacking cvars and fucking over configs (at least in other engines). + { + cvar_t *var = Cvar_FindVar(key+5); + if (var && !(var->flags & CVAR_NOTFROMSERVER)) + Cvar_LockFromServer(var, com_token); + } + else if (!strcmp("wateralpha", key)) //override cvars so mappers don't end up hacking cvars and fucking over configs (at least in other engines). + { + Cvar_LockFromServer(&r_wateralpha, com_token); + Cvar_LockFromServer(&r_waterstyle, "1"); //force vanilla-style water too. + } + else if (!strcmp("slimealpha", key)) + { + Cvar_LockFromServer(&r_slimealpha, com_token); + Cvar_LockFromServer(&r_slimestyle, "1"); + } + else if (!strcmp("lavaalpha", key)) + { + Cvar_LockFromServer(&r_lavaalpha, com_token); + Cvar_LockFromServer(&r_lavastyle, "1"); + } + else if (!strcmp("telealpha", key)) + { + Cvar_LockFromServer(&r_telealpha, com_token); + Cvar_LockFromServer(&r_telestyle, "1"); + } + else if (!strcmp("sky", key)) // for Quake2 maps + { + Q_strncpyz(cl.skyname, token, sizeof(cl.skyname)); + } + else if (!strcmp("skyrotate", key)) //q2 feature + { + cl.skyrotate = atof(token); + } + else if (!strcmp("skyaxis", key)) //q2 feature + { + char *s; + Q_strncpyz(key, token, sizeof(key)); + s = COM_ParseOut(key, token, sizeof(token)); + if (s) + { + cl.skyaxis[0] = atof(s); + s = COM_ParseOut(s, token, sizeof(token)); + if (s) + { + cl.skyaxis[1] = atof(s); + COM_ParseOut(s, token, sizeof(token)); + if (s) + cl.skyaxis[2] = atof(s); + } + } + } + } + + COM_FileBase (wmodel->name, token, sizeof(token)); + +#ifdef PACKAGE_WAD + //map-specific sky override feature + for (msky = mapskies; msky; msky = msky->next) + { + if (!strcmp(msky->mapname, token)) + { + Q_strncpyz(cl.skyname, msky->skyname, sizeof(cl.skyname)); + break; + } + } +#endif +} diff --git a/engine/client/winquake.rc b/engine/client/winquake.rc index 989bc9cc..589b43d0 100644 --- a/engine/client/winquake.rc +++ b/engine/client/winquake.rc @@ -84,7 +84,9 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. -#ifdef BRANDING_ICON +#ifdef CONFIG_FILE_NAME +IDI_ICON1 ICON BRANDING_ICON +#elif defined(BRANDING_ICON) IDI_ICON1 ICON BRANDING_ICON IDI_ICON2 ICON "bymorphed.ico" IDI_ICON3 ICON "q2.ico" diff --git a/engine/common/bothdefs.h b/engine/common/bothdefs.h index edc9b635..87952706 100644 --- a/engine/common/bothdefs.h +++ b/engine/common/bothdefs.h @@ -49,6 +49,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define NO_ZLIB #endif +#ifndef MULTITHREAD +#define NO_MULTITHREAD +#endif + #ifdef FTE_TARGET_WEB //no Sys_LoadLibrary support, so we might as well kill this stuff off. #define NO_PNG @@ -58,19 +62,21 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define NO_FREETYPE #endif -#ifdef HAVE_CONFIG_H //if it was configured properly, then we have a more correct list of features we want to use. +#ifdef D3DQUAKE +#define D3D9QUAKE +//#define D3D11QUAKE +#undef D3DQUAKE +#endif + +#define STRINGIFY2(s) #s +#define STRINGIFY(s) STRINGIFY2(s) + +#ifdef CONFIG_FILE_NAME + //yup, C89 allows this. + #include STRINGIFY(CONFIG_FILE_NAME) +#elif defined(HAVE_CONFIG_H) //if it was configured properly, then we have a more correct list of features we want to use. #include "config.h" #else - #ifndef MSVCLIBSPATH - #ifdef MSVCLIBPATH - #define MSVCLIBSPATH STRINGIFY(MSVCLIBPATH) - #elif _MSC_VER == 1200 - #define MSVCLIBSPATH "../libs/vc6-libs/" - #else - #define MSVCLIBSPATH "../libs/" - #endif - #endif - #ifdef NO_LIBRARIES #define NO_DIRECTX #define NO_PNG @@ -94,9 +100,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #if !defined(NO_DIRECTX) && !defined(NODIRECTX) && defined(_WIN32) #define AVAIL_DINPUT - #define AVAIL_DDRAW #define AVAIL_DSOUND - #define AVAIL_D3D #define AVAIL_WASAPI #endif #ifdef WINRT @@ -123,14 +127,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //#define LIBVORBISFILE_STATIC //#define SPEEX_STATIC -#ifdef D3DQUAKE -#define D3D9QUAKE -//#define D3D11QUAKE -#endif - -#if (defined(D3D9QUAKE) || defined(D3D11QUAKE)) && !defined(D3DQUAKE) -#define D3DQUAKE -#endif #if defined(_WIN32) && defined(GLQUAKE) //#define USE_EGL #endif @@ -149,10 +145,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef NO_JPEG #undef AVAIL_JPEGLIB #endif -#ifdef NO_ZLIB - #undef AVAIL_ZLIB - #undef AVAIL_XZDEC -#endif #ifdef NO_OGG #undef AVAIL_OGGVORBIS #endif @@ -167,6 +159,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //set any additional defines or libs in win32 #define LOADERTHREAD + #define PACKAGE_Q1PAK + #define PACKAGE_PK3 + #define AVAIL_GZDEC + #define PACKAGE_WAD //quake's image wad support + + #ifdef GLQUAKE + #define HEADLESSQUAKE + #endif + #ifdef NOLEGACY //these are only the features that really make sense in a more modern engine #define QUAKETC //skip some legacy stuff @@ -177,7 +178,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define Q2BSPS //quake 2 bsp support (a dependancy of q3bsp) #define Q3BSPS //quake 3 bsp support // #define TERRAIN //heightmap support - #define ZLIB //zip/pk3 support #define WEBCLIENT //http/ftp clients. #define IMAGEFMT_DDS //a sort of image file format. #define PSET_SCRIPT @@ -200,12 +200,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #undef AVAIL_JPEGLIB //no jpeg support #undef AVAIL_PNGLIB //no png support #undef AVAIL_OPENAL //just bloat... + #undef AVAIL_GZDEC #define NOMEDIA //NO playing of avis/cins/roqs #define Q1BSPS #define SPRMODELS //quake1 sprite models + #define MD1MODELS //quake ain't much use without this #define MD3MODELS //we DO want to use quake3 alias models. This might be a minimal build, but we still want this. #define PLUGINS + #define NOQCDESCRIPTIONS //trim space from no fteextensions.qc info #define PSET_CLASSIC @@ -255,6 +258,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define Q1BSPS //quake 1 bsp support, because we're still a quake engine #define Q2BSPS //quake 2 bsp support #define Q3BSPS //quake 3 bsp support + #define RFBSPS //rogue(sof+jk2o)+qfusion bsp support #define TERRAIN //heightmap support // #define SV_MASTER //starts up a master server #define SVCHAT //serverside npc chatting. see sv_chat.c @@ -266,7 +270,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // #define HLCLIENT 7 //we can run HL gamecode (not protocol compatible, set to 6 or 7) // #define HLSERVER 140 //we can run HL gamecode (not protocol compatible, set to 138 or 140) #define NQPROT //server and client are capable of using quake1/netquake protocols. (qw is still prefered. uses the command 'nqconnect') - #define ZLIB //zip/pk3 support #define WEBSERVER //http/ftp servers #define WEBCLIENT //http/ftp clients. #define RUNTIMELIGHTING //calculate lit/lux files the first time the map is loaded and doesn't have a loadable lit. @@ -303,19 +306,47 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #endif #endif + + + #ifdef QUAKETC + #define NOBUILTINMENUS //kill engine menus (should be replaced with ewither csqc or menuqc) + #undef Q2CLIENT //not useful + #undef Q2SERVER //not useful + #undef Q3CLIENT //not useful + #undef Q3SERVER //not useful + #undef HLCLIENT //not useful + #undef HLSERVER //not useful + #undef VM_Q1 //not useful + #undef VM_LUA //not useful + #undef HALFLIFEMODELS //yuck + #undef RUNTIMELIGHTING //presumably not useful + #undef HEXEN2 + #endif + #endif + #ifndef MSVCLIBSPATH + #ifdef MSVCLIBPATH + #define MSVCLIBSPATH STRINGIFY(MSVCLIBPATH) + #elif _MSC_VER == 1200 + #define MSVCLIBSPATH "../libs/vc6-libs/" + #else + #define MSVCLIBSPATH "../libs/" + #endif + #endif + //software rendering is just too glitchy, don't use it. #if defined(SWQUAKE) && !defined(_DEBUG) #undef SWQUAKE #endif +#if (defined(D3D9QUAKE) || defined(D3D11QUAKE)) && !defined(D3DQUAKE) +#define D3DQUAKE +#endif //include a file to update the various configurations for game-specific configs (hopefully just names) #ifdef BRANDING_INC - #define STRINGIFY2(s) #s - #define STRINGIFY(s) STRINGIFY2(s) #include STRINGIFY(BRANDING_INC) #endif #ifndef DISTRIBUTION @@ -331,23 +362,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define ENGINEWEBSITE "http://fte.triptohell.info" //url for program #endif -#ifdef QUAKETC - #define NOBUILTINMENUS //kill engine menus (should be replaced with ewither csqc or menuqc) - #undef Q2CLIENT //not useful - #undef Q2SERVER //not useful - #undef Q3CLIENT //not useful - #undef Q3SERVER //not useful - #undef HLCLIENT //not useful - #undef HLSERVER //not useful - #undef VM_Q1 //not useful - #undef VM_LUA //not useful - #undef HALFLIFEMODELS //yuck - #undef RUNTIMELIGHTING //presumably not useful - #undef HEXEN2 -#endif - //#define QUAKESPYAPI //define this if you want the engine to be usable via gamespy/quakespy, which has been dead for a long time now. +#ifdef NO_ZLIB //compile-time option. + #undef AVAIL_ZLIB + #undef AVAIL_XZDEC + #undef AVAIL_GZDEC +#endif + #ifdef FTE_TARGET_WEB //try to trim the fat #undef VOICECHAT //too lazy to compile speex @@ -420,6 +442,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define SQL #endif +#if (defined(AVAIL_GZDEC) && !defined(ZLIB)) || !defined(NPFTE) + //gzip needs zlib to work (pk3s can still contain non-compressed files) + #undef AVAIL_GZDEC +#endif + +#if defined(RFBSPS) && !defined(Q3BSPS) + #define Q3BSPS //rbsp might as well depend upon q3bsp - its the same thing but with more lightstyles (support for which can bog down the renderer a little). +#endif + //fix things a little... #ifdef NPQTV #define NPFTE @@ -442,6 +473,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #undef QTERM //not supported - FIXME: move to native plugin #endif +#if defined(Q3BSPS) && !defined(Q2BSPS) +// #define Q2BSPS //FIXME: silently enable that as a dependancy, for now +#endif + #if (defined(Q2CLIENT) || defined(Q2SERVER)) #ifndef Q2BSPS #error "Q2 game support without Q2BSP support. doesn't make sense" @@ -490,6 +525,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define USERBE #endif +#if defined(MD1MODELS) || defined(MD2MODELS) || defined(MD3MODELS) + #define NONSKELETALMODELS +#endif #if defined(ZYMOTICMODELS) || defined(MD5MODELS) || defined(DPMMODELS) || defined(PSKMODELS) || defined(INTERQUAKEMODELS) #define SKELETALMODELS //defined if we have a skeletal model. #endif diff --git a/engine/common/bspfile.h b/engine/common/bspfile.h index 04b7db73..b934a2ba 100644 --- a/engine/common/bspfile.h +++ b/engine/common/bspfile.h @@ -230,7 +230,7 @@ typedef struct unsigned int v[2]; // vertex numbers } dledge_t; -#ifdef Q3BSPS +#ifdef RFBSPS #define MAXRLIGHTMAPS 4 //max lightmaps mixed by the renderer (rbsp=4, otherwise 1) #else #define MAXRLIGHTMAPS 1 //max lightmaps mixed by the renderer (rbsp=4, otherwise 1) @@ -434,7 +434,9 @@ enum Q3LUMP Q3LUMP_LIGHTMAPS =14, Q3LUMP_LIGHTGRID =15, Q3LUMP_VISIBILITY =16, +#ifdef RFBSPS RBSPLUMP_LIGHTINDEXES=17, +#endif Q3LUMPS_TOTAL }; @@ -873,7 +875,7 @@ typedef struct pvscache_s { int num_leafs; unsigned short leafnums[MAX_ENT_LEAFS]; -#if defined(Q2BSPS) || defined(TERRAIN) +#if defined(Q2BSPS) || defined(Q3BSPS) || defined(TERRAIN) int areanum; //q2bsp int areanum2; //q2bsp int headnode; //q2bsp diff --git a/engine/common/cmd.c b/engine/common/cmd.c index 6e007c76..16ac9c5e 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -3696,7 +3696,6 @@ void Cmd_Init (void) Cmd_AddCommandD ("cvarwatch", Cvar_Watch_f, "Prints a notification when the named cvar is changed. Also displays the start/end of configs. Alternatively, use '-watch foo' on the commandline."); Cmd_AddCommand ("cvar_lockdefaults", Cvar_LockDefaults_f); Cmd_AddCommand ("cvar_purgedefaults", Cvar_PurgeDefaults_f); - Cmd_AddCommand ("fs_flush", COM_RefreshFSCache_f); Cmd_AddCommandD ("apropos", Cmd_Apropos_f, "Lists all cvars or commands with the specified substring somewhere in their name or descrition."); diff --git a/engine/common/com_mesh.c b/engine/common/com_mesh.c index e9a329bb..cb52cc63 100644 --- a/engine/common/com_mesh.c +++ b/engine/common/com_mesh.c @@ -721,6 +721,7 @@ struct #endif #ifndef SERVERONLY +#ifdef D3DQUAKE void R_LightArraysByte_BGR(const entity_t *entity, vecV_t *coords, byte_vec4_t *colours, int vertcount, vec3_t *normals) { int i; @@ -766,6 +767,7 @@ void R_LightArraysByte_BGR(const entity_t *entity, vecV_t *coords, byte_vec4_t * } } } +#endif void R_LightArrays(const entity_t *entity, vecV_t *coords, avec4_t *colours, int vertcount, vec3_t *normals, float scale) { @@ -856,6 +858,7 @@ void R_LightArrays(const entity_t *entity, vecV_t *coords, avec4_t *colours, int } } } +#ifdef NONSKELETALMODELS static void R_LerpFrames(mesh_t *mesh, galiaspose_t *p1, galiaspose_t *p2, float lerp, float expand, float lerpcutoff) { extern cvar_t r_nolerp; // r_nolightdir is unused @@ -952,6 +955,7 @@ static void R_LerpFrames(mesh_t *mesh, galiaspose_t *p1, galiaspose_t *p2, float } #endif #endif +#endif #ifdef SKELETALMODELS /* @@ -1515,17 +1519,10 @@ void Alias_Shutdown(void) qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, int surfnum, entity_t *e, qboolean usebones) { - galiasanimation_t *g1, *g2; #ifndef SERVERONLY extern cvar_t r_nolerp; - float lerpcutoff; #endif - int frame1; - int frame2; - float lerp; - float fg1time; -// float fg2time; #ifdef SKELETALMODELS qboolean bytecolours = false; #endif @@ -1749,6 +1746,21 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, in else #endif { +#ifndef NONSKELETALMODELS + memset(mesh, 0, sizeof(*mesh)); + *vbop = NULL; + return false; +#else +#ifndef SERVERONLY + float lerpcutoff; +#endif + galiasanimation_t *g1, *g2; + int frame1; + int frame2; + float lerp; + float fg1time; + //float fg2time; + //FIXME: replace most of this logic with Alias_BuildSkelLerps frame1 = e->framestate.g[FS_REG].frame[0]; @@ -1883,6 +1895,7 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, in if (vbop && meshcache.vbo.indicies.sysptr) *vbop = meshcache.vbop = &meshcache.vbo; } +#endif } meshcache.vbo.vao = 0; @@ -1916,8 +1929,6 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, in void Mod_AddSingleSurface(entity_t *ent, int surfaceidx, shader_t *shader) { galiasinfo_t *mod; - galiasanimation_t *group; - galiaspose_t *pose; scenetris_t *t; vecV_t *posedata = NULL; int surfnum = 0, i; @@ -1955,11 +1966,15 @@ void Mod_AddSingleSurface(entity_t *ent, int surfaceidx, shader_t *shader) } else #endif +#ifndef NONSKELETALMODELS + continue; +#else if (!mod->numanimations) continue; else { - group = mod->ofsanimations; + galiaspose_t *pose; + galiasanimation_t *group = mod->ofsanimations; group += ent->framestate.g[FS_REG].frame[0] % mod->numanimations; //FIXME: no support for frame blending. if (!group->numposes || !group->poseofs) @@ -1968,6 +1983,7 @@ void Mod_AddSingleSurface(entity_t *ent, int surfaceidx, shader_t *shader) pose += (int)(ent->framestate.g[FS_REG].frametime[0] * group->rate)%group->numposes; posedata = pose->ofsverts; } +#endif if (cl_numstris == cl_maxstris) { @@ -2227,8 +2243,6 @@ qboolean Mod_Trace_Trisoup(vecV_t *posedata, index_t *indexes, int numindexes, v qboolean Mod_Trace(model_t *model, int forcehullnum, framestate_t *framestate, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int contentsmask, trace_t *trace) { galiasinfo_t *mod = Mod_Extradata(model); - galiasanimation_t *group; - galiaspose_t *pose; // float temp; @@ -2287,11 +2301,15 @@ qboolean Mod_Trace(model_t *model, int forcehullnum, framestate_t *framestate, v } else #endif +#ifndef NONSKELETALMODELS + continue; +#else if (!mod->numanimations) continue; else { - group = mod->ofsanimations; + galiaspose_t *pose; + galiasanimation_t *group = mod->ofsanimations; if (framestate) group += framestate->g[FS_REG].frame[0] % mod->numanimations; //FIXME: no support for frame blending. @@ -2302,6 +2320,7 @@ qboolean Mod_Trace(model_t *model, int forcehullnum, framestate_t *framestate, v pose += (int)(framestate->g[FS_REG].frametime[0] * group->rate)%group->numposes; posedata = pose->ofsverts; } +#endif if (Mod_Trace_Trisoup(posedata, indexes, mod->numindexes, start_l, end_l, mins, maxs, trace)) { @@ -2614,9 +2633,10 @@ void Mod_GenerateMeshVBO(galiasinfo_t *galias) //vec3_t *vc, vec2_t *tc, vec3_t *nv, vec3_t *sv, vec3_t *tv, index_t *idx, int numidx, int numverts) { #ifndef SERVERONLY +#ifdef NONSKELETALMODELS int i, p; - galiasanimation_t *group; - galiaspose_t *pose; + galiasanimation_t *group = galias->ofsanimations; +#endif int vbospace = 0; vbobctx_t vboctx; @@ -2624,8 +2644,6 @@ void Mod_GenerateMeshVBO(galiasinfo_t *galias) if (!BE_VBO_Begin || !galias->numverts) return; - group = galias->ofsanimations; - //determine the amount of space we need for our vbos. if (galias->ofs_st_array) vbospace += sizeof(*galias->ofs_st_array) * galias->numverts; @@ -2647,11 +2665,14 @@ void Mod_GenerateMeshVBO(galiasinfo_t *galias) if (galias->ofs_skel_weight) vbospace += sizeof(*galias->ofs_skel_weight) * galias->numverts; #endif +#ifdef NONSKELETALMODELS for (i = 0; i < galias->numanimations; i++) { - if (group->poseofs) + if (group[i].poseofs) vbospace += group[i].numposes * galias->numverts * (sizeof(vecV_t)+sizeof(vec3_t)*3); } +#endif + BE_VBO_Begin(&vboctx, vbospace); if (galias->ofs_st_array) BE_VBO_Data(&vboctx, galias->ofs_st_array, sizeof(*galias->ofs_st_array) * galias->numverts, &galias->vbotexcoords); @@ -2673,26 +2694,28 @@ void Mod_GenerateMeshVBO(galiasinfo_t *galias) if (galias->ofs_skel_weight) BE_VBO_Data(&vboctx, galias->ofs_skel_weight, sizeof(*galias->ofs_skel_weight) * galias->numverts, &galias->vbo_skel_bweight); #endif - - for (i = 0; i < galias->numanimations; i++, group++) +#ifdef NONSKELETALMODELS + for (i = 0; i < galias->numanimations; i++) { - pose = group->poseofs; + galiaspose_t *pose = group[i].poseofs; if (pose) - for (p = 0; p < group->numposes; p++, pose++) - { - BE_VBO_Data(&vboctx, pose->ofsverts, sizeof(*pose->ofsverts) * galias->numverts, &pose->vboverts); - BE_VBO_Data(&vboctx, pose->ofsnormals, sizeof(*pose->ofsnormals) * galias->numverts, &pose->vbonormals); - if (pose->ofssvector) - BE_VBO_Data(&vboctx, pose->ofssvector, sizeof(*pose->ofssvector) * galias->numverts, &pose->vbosvector); - if (pose->ofstvector) - BE_VBO_Data(&vboctx, pose->ofstvector, sizeof(*pose->ofstvector) * galias->numverts, &pose->vbotvector); - } + for (p = 0; p < group[i].numposes; p++, pose++) + { + BE_VBO_Data(&vboctx, pose->ofsverts, sizeof(*pose->ofsverts) * galias->numverts, &pose->vboverts); + BE_VBO_Data(&vboctx, pose->ofsnormals, sizeof(*pose->ofsnormals) * galias->numverts, &pose->vbonormals); + if (pose->ofssvector) + BE_VBO_Data(&vboctx, pose->ofssvector, sizeof(*pose->ofssvector) * galias->numverts, &pose->vbosvector); + if (pose->ofstvector) + BE_VBO_Data(&vboctx, pose->ofstvector, sizeof(*pose->ofstvector) * galias->numverts, &pose->vbotvector); + } } +#endif BE_VBO_Finish(&vboctx, galias->ofs_indexes, sizeof(*galias->ofs_indexes) * galias->numindexes, &galias->vboindicies, &galias->vbomem, &galias->ebomem); #endif } +#ifdef NONSKELETALMODELS //called for non-skeletal model formats. void Mod_BuildTextureVectors(galiasinfo_t *galias) //vec3_t *vc, vec2_t *tc, vec3_t *nv, vec3_t *sv, vec3_t *tv, index_t *idx, int numidx, int numverts) @@ -2733,6 +2756,7 @@ void Mod_BuildTextureVectors(galiasinfo_t *galias) } #endif } +#endif #ifndef SERVERONLY //looks for foo.md3_0.skin files, for dp compat diff --git a/engine/common/com_mesh.h b/engine/common/com_mesh.h index 5653e975..8e82ca8d 100644 --- a/engine/common/com_mesh.h +++ b/engine/common/com_mesh.h @@ -13,6 +13,7 @@ extern "C" { #include "model_hl.h" #endif +#ifdef NONSKELETALMODELS //a single pose within an animation (note: always refered to via a framegroup, even if there's only one frame in that group). typedef struct { @@ -31,6 +32,7 @@ typedef struct vec3_t scale; vec3_t scale_origin; } galiaspose_t; +#endif typedef struct galiasevent_s { @@ -51,7 +53,9 @@ typedef struct qboolean loop; int numposes; float rate; +#ifdef NONSKELETALMODELS galiaspose_t *poseofs; +#endif galiasevent_t *events; char name[64]; } galiasanimation_t; diff --git a/engine/common/common.c b/engine/common/common.c index fb42c869..17fbf77a 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -4861,12 +4861,6 @@ void COM_Version_f (void) #ifndef AVAIL_DSOUND Con_Printf("DirectSound disabled\n"); #endif - #ifndef AVAIL_D3D - Con_Printf("Direct3D disabled\n"); - #endif - #ifndef AVAIL_DDRAW - Con_Printf("DirectDraw disabled\n"); - #endif #endif Con_Printf("Games:"); diff --git a/engine/common/common.h b/engine/common/common.h index 59ff66f1..e34dd742 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -469,7 +469,7 @@ typedef struct searchpath_s } searchpath_t; typedef struct { struct searchpath_s *search; //used to say which filesystem driver to open the file from - int index; //used by the filesystem driver as a simple reference to the file + void *fhandle; //used by the filesystem driver as a simple reference to the file char rawname[MAX_OSPATH]; //blank means not readable directly qofs_t offset; //only usable if rawname is set. qofs_t len; //uncompressed length @@ -529,23 +529,23 @@ char *VFS_GETS(vfsfile_t *vf, char *buffer, int buflen); void VARGS VFS_PRINTF(vfsfile_t *vf, char *fmt, ...) LIKEPRINTF(2); enum fs_relative{ - FS_GAME, //standard search (not generally valid for save/rename/delete/etc) FS_BINARYPATH, //for dlls and stuff FS_ROOT, //./ (the root basepath or root homepath.) + FS_SYSTEM, //a system path. absolute paths are explicitly allowed and expected, but not required. + + //after this point, all types must be relative to a gamedir + FS_GAME, //standard search (not generally valid for writing/save/rename/delete/etc) FS_GAMEONLY, //$gamedir/ - FS_GAMEDOWNLOADCACHE, //typically the same as FS_GAMEONLY FS_BASEGAMEONLY, //fte/ FS_PUBGAMEONLY, //$gamedir/ or qw/ but not fte/ - FS_PUBBASEGAMEONLY, //qw/ (fixme: should be the last non-private basedir) - FS_SYSTEM //a system path. absolute paths are explicitly allowed and expected, but not required. + FS_PUBBASEGAMEONLY //qw/ (fixme: should be the last non-private basedir) }; void COM_WriteFile (const char *filename, enum fs_relative fsroot, const void *data, int len); -void FS_FlushFSHashReally(qboolean domutexes); -void FS_FlushFSHashWritten(void); -void FS_FlushFSHashRemoved(void); -void FS_FlushFSHash(void); +void FS_FlushFSHashWritten(const char *fname); +void FS_FlushFSHashRemoved(const char *fname); +void FS_FlushFSHashFull(void); //too much/unknown changed... void FS_CreatePath(const char *pname, enum fs_relative relativeto); qboolean FS_Rename(const char *oldf, const char *newf, enum fs_relative relativeto); //0 on success, non-0 on error qboolean FS_Rename2(const char *oldf, const char *newf, enum fs_relative oldrelativeto, enum fs_relative newrelativeto); @@ -589,7 +589,6 @@ qbyte *COM_LoadTempMoreFile (const char *path, size_t *fsize); //allocates a lit searchpathfuncs_t *COM_IteratePaths (void **iterator, char *pathbuffer, int pathbuffersize, char *dirname, int dirnamesize); void COM_FlushFSCache(qboolean purge, qboolean domutex); //a file was written using fopen -void COM_RefreshFSCache_f(void); qboolean FS_Restarted(unsigned int *since); enum manifestdeptype_e diff --git a/engine/common/config_wastes.h b/engine/common/config_wastes.h new file mode 100644 index 00000000..570bbd06 --- /dev/null +++ b/engine/common/config_wastes.h @@ -0,0 +1,136 @@ +// The Wastes' config.h +// We support both GL and D3D9. If Vulkan matures yeahsurewhynot +// I want to get this mostly running on all systems. +// Possibly Xbox. Yes, the original one. Sue me. + +//general rebranding +#define DISTRIBUTION "VTW" +#define DISTRIBUTIONLONG "Vera Visions" +#define FULLENGINENAME "The Wastes" +#define ENGINEWEBSITE "http://www.vera-visions.com/" +#define BRANDING_ICON "wastes.ico" + +//filesystem rebranding +#define GAME_SHORTNAME "wastes" //short alphanumeric description +#define GAME_FULLNAME FULLENGINENAME //full name of the game we're playing +#define GAME_BASEGAMES GAME_SHORTNAME //comma-separate list of basegame strings to use +#define GAME_PROTOCOL "FTE-Wastes" //so other games won't show up in the server browser +//#define GAME_IDENTIFYINGFILES NULL //with multiple games, this string-list gives verification that the basedir is actually valid. if null, will just be assumed correct. +//#define GAME_DOWNLOADSURL NULL //url for the package manger to update from +//#define GAME_DEFAULTCMDS NULL //a string containing the things you want to + + +// What do we use +//#define D3D9QUAKE +//#define GLQUAKE +#undef D3D11QUAKE +#undef VKQUAKE +#undef HEADLESSQUAKE + +#define QUAKETC +#define AVAIL_OPENAL +#define AVAIL_ZLIB +#define AVAIL_OGGVORBIS +#define NOMEDIA +#define CL_MASTER +#define CSQC_DAT +#define MENU_DAT +#define PSET_SCRIPT +#define VOICECHAT +#define RTLIGHTS +#ifndef MULTITHREAD +#define MULTITHREAD //misc basic multithreading - dsound, downloads, basic stuff that's unlikely to have race conditions. +#endif +#define LOADERTHREAD //worker threads for loading misc stuff. falls back on main thread if not supported. + +#define NOBUILTINMENUS +#define NOLEGACY //just spike trying to kill off crappy crap... +#define AVAIL_DINPUT +#ifndef DEBUG +#define NOQCDESCRIPTIONS 2 //if 2, disables writing fteextensions.qc completely. +#endif + + +//map formats +#define Q3BSPS +#undef Q1BSPS +#undef Q2BSPS +#undef RFBSPS //qfusion's bsp format / jk2o etc. +#undef TERRAIN +#undef DOOMWADS +#undef MAP_PROC + +//model formats +#define INTERQUAKEMODELS +#undef SPRMODELS +#undef SP2MODELS +#undef MD1MODELS +#undef MD2MODELS +#undef MD3MODELS +#undef MD5MODELS +#undef ZYMOTICMODELS +#undef DPMMODELS +#undef PSKMODELS +#undef HALFLIFEMODELS + +// What do we NOT want to use +#undef AVAIL_FREETYPE //for truetype font rendering +#undef AVAIL_WASAPI //windows advanced sound api +#undef BOTLIB_STATIC //q3 botlib +#undef AVAIL_XZDEC //.xz decompression +#undef AVAIL_GZDEC //.gz decompression +#undef AVAIL_PNGLIB //.png image format support (read+screenshots) +#undef AVAIL_JPEGLIB //.jpeg image format support (read+screenshots) +#undef IMAGEFMT_DDS //.dds files embed mipmaps and texture compression. faster to load. +#undef IMAGEFMT_BLP //legacy crap +#undef NETPREPARSE //allows for running both nq+qw on the same server (if not, protocol used must match gamecode). +#undef USE_SQLITE //sql-database-as-file support +#undef QUAKESTATS //defines STAT_HEALTH etc. if omitted, you'll need to provide that functionality yourself. +#undef QUAKEHUD //support for drawing the vanilla hud. +#undef SVRANKING //legacy server-side ranking system. +#undef RAGDOLL //ragdoll support. requires RBE support. +#undef HUFFNETWORK //crappy network compression. probably needs reseeding. +#undef SVCHAT //ancient lame builtin to support NPC-style chat... +#undef VM_Q1 //q1qvm implementation, to support ktx. +#undef Q2SERVER //q2 server+gamecode. +#undef Q2CLIENT //q2 client. file formats enabled separately. +#undef Q3CLIENT //q3 client stuff. +#undef Q3SERVER //q3 server stuff. +#undef HEXEN2 //runs hexen2 gamecode, supports hexen2 file formats. +#undef NQPROT //act as an nq client/server, with nq gamecode. +#undef WEBSERVER //sv_ftp + sv_http cvars. +#undef WEBCLIENT //uri_get+any internal downloads etc +#undef RUNTIMELIGHTING //automatic generation of .lit files +#undef R_XFLIP //old silly thing +#undef TEXTEDITOR //my funky text editor! its awesome! +#undef TCPCONNECT //support for playing over tcp sockets, instead of just udp. compatible with qizmo. +#undef IRCCONNECT //lame support for routing game packets via irc server. not a good idea. +#undef PLUGINS //support for external plugins (like huds or fancy menus or whatever) +#undef SUPPORT_ICE //Internet Connectivity Establishment, for use by plugins to establish voice or game connections. +#undef PSET_CLASSIC //support the 'classic' particle system, for that classic quake feel. + +//various package formats +#define PACKAGE_PK3 +#undef PACKAGE_Q1PAK //also q2 +#undef PACKAGE_DOOMWAD //doom wad support (generates various file names, and adds support for doom's audio, sprites, etc) +#undef PACKAGE_WAD //quake's image wad support + + + +#ifdef COMPILE_OPTS +//things to configure qclib, which annoyingly doesn't include this file itself +-DOMIT_QCC //disable the built-in qcc +-DSIMPLE_QCVM //disable qc debugging and 32bit opcodes +#ifndef AVAIL_ZLIB +-DNO_ZLIB //disable zlib +#endif + + +-DNO_SPEEX //disable static speex +#ifndef BOTLIB_STATIC +-DNO_BOTLIB //disable static botlib +#endif +-DNO_VORBISFILE //disable static vorbisfile + +-Os //optimise for size instead of speed. less cpu cache needed means that its sometimes faster anyway. +#endif diff --git a/engine/common/fs.c b/engine/common/fs.c index 8d18ca0f..9fc2c168 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -874,9 +874,12 @@ void COM_WriteFile (const char *filename, enum fs_relative fsroot, const void *d { VFS_WRITE(vfs, data, len); VFS_CLOSE(vfs); - } - com_fschanged=true; + if (fsroot >= FS_GAME) + FS_FlushFSHashWritten(filename); + else + com_fschanged=true; + } } /* @@ -957,7 +960,7 @@ struct fsbucketblock }; static struct fsbucketblock *fs_hash_filebuckets; -void FS_FlushFSHashReally(qboolean domutexes) +static void FS_FlushFSHashReally(qboolean domutexes) { COM_AssertMainThread("FS_FlushFSHashReally"); if (!domutexes || Sys_LockMutex(fs_thread_mutex)) @@ -982,19 +985,6 @@ void FS_FlushFSHashReally(qboolean domutexes) Sys_UnlockMutex(fs_thread_mutex); } } -void FS_FlushFSHashWritten(void) -{ - /*SHOULD be handled automatically, but really isn't*/ - FS_FlushFSHashReally(true); -} -void FS_FlushFSHashRemoved(void) -{ - FS_FlushFSHashReally(true); -} -void FS_FlushFSHash(void) -{ - FS_FlushFSHashReally(true); -} static void QDECL FS_AddFileHash(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle) { @@ -1038,7 +1028,7 @@ static void QDECL FS_AddFileHash(int depth, const char *fname, fsbucket_t *fileh fs_hash_files++; } -void FS_RebuildFSHash(qboolean domutex) +static void FS_RebuildFSHash(qboolean domutex) { int depth = 1; searchpath_t *search; @@ -1087,6 +1077,73 @@ void FS_RebuildFSHash(qboolean domutex) Con_DPrintf("%i unique files, %i duplicates\n", fs_hash_files, fs_hash_dups); } +static void FS_RebuildFSHash_Update(const char *fname) +{ + flocation_t loc; + searchpath_t *search; + int depth = 0; + fsbucket_t *old; + + if (com_fschanged) + return; + + COM_WorkerFullSync(); + if (!Sys_LockMutex(fs_thread_mutex)) + return; //amg! + + old = Hash_GetInsensitiveBucket(&filesystemhash, fname); + if (old) + { + Hash_RemoveBucket(&filesystemhash, fname, &old->buck); + fs_hash_files--; + } + + if (com_purepaths) + { //go for the pure paths first. + for (search = com_purepaths; search; search = search->nextpure) + { + if (search->handle->FindFile(search->handle, &loc, fname, NULL)) + { + FS_AddFileHash(depth, fname, NULL, loc.fhandle); + return; + } + depth++; + } + } + if (fs_puremode < 2) + { + for (search = com_searchpaths ; search ; search = search->next) + { + if (search->handle->FindFile(search->handle, &loc, fname, NULL)) + { + FS_AddFileHash(depth, fname, NULL, loc.fhandle); + return; + } + depth++; + } + } + + Sys_UnlockMutex(fs_thread_mutex); +} + +void FS_FlushFSHashWritten(const char *fname) +{ + FS_RebuildFSHash_Update(fname); +} +void FS_FlushFSHashRemoved(const char *fname) +{ + FS_RebuildFSHash_Update(fname); +} +void FS_FlushFSHashFull(void) +{ //any calls to this are typically a bug... + //that said, figuring out if the file was actually within quake's filesystem isn't easy. + com_fschanged = true; + + //for safety we would need to sync with all threads, so lets just not bother. + //FS_FlushFSHashReally(true); +} + + /* =========== COM_FindFile @@ -1110,7 +1167,7 @@ int FS_FLocateFile(const char *filename, unsigned int lflags, flocation_t *loc) if (!loc) loc = &allownoloc; - loc->index = 0; + loc->fhandle = NULL; loc->offset = 0; *loc->rawname = 0; loc->search = NULL; @@ -1559,7 +1616,7 @@ vfsfile_t *VFS_Filter(const char *filename, vfsfile_t *handle) if (!handle || handle->WriteBytes || handle->seekingisabadplan) //only on readonly files return handle; // ext = COM_FileExtension (filename); -#ifdef AVAIL_ZLIB +#ifdef AVAIL_GZDEC // if (!Q_strcasecmp(ext, ".gz")) { return FS_DecompressGZip(handle, NULL); @@ -1799,6 +1856,7 @@ vfsfile_t *FS_OpenVFS(const char *filename, const char *mode, enum fs_relative r switch (relativeto) { case FS_GAMEONLY: //OS access only, no paks + vfs = NULL; if (com_homepathenabled) { if (!try_snprintf(fullname, sizeof(fullname), "%s%s/%s", com_homepath, gamedirfile, filename)) @@ -1806,18 +1864,18 @@ vfsfile_t *FS_OpenVFS(const char *filename, const char *mode, enum fs_relative r if (*mode == 'w') COM_CreatePath(fullname); vfs = VFSOS_Open(fullname, mode); - if (vfs) - return vfs; } - if (*gamedirfile) + if (!vfs && *gamedirfile) { if (!try_snprintf(fullname, sizeof(fullname), "%s%s/%s", com_gamepath, gamedirfile, filename)) return NULL; if (*mode == 'w') COM_CreatePath(fullname); - return VFSOS_Open(fullname, mode); + vfs = VFSOS_Open(fullname, mode); } - return NULL; + if (vfs && !strcmp(mode, "wb")) + + return vfs; case FS_PUBGAMEONLY: if (!FS_NativePath(filename, relativeto, fullname, sizeof(fullname))) return NULL; @@ -2590,7 +2648,7 @@ static searchpath_t *FS_AddPathHandle(searchpath_t **oldpaths, const char *purep return search; } -void COM_RefreshFSCache_f(void) +static void COM_RefreshFSCache_f(void) { com_fschanged=true; } @@ -2955,13 +3013,35 @@ typedef struct { const char *manifestfile; } gamemode_info_t; const gamemode_info_t gamemode_info[] = { +#ifdef GAME_SHORTNAME + #ifndef GAME_PROTOCOL + #define GAME_PROTOCOL DISTRIBUTION + #endif + #ifndef GAME_IDENTIFYINGFILES + #define GAME_IDENTIFYINGFILES NULL // + #endif + #ifndef GAME_DEFAULTCMDS + #define GAME_DEFAULTCMDS NULL //doesn't need anything + #endif + #ifndef GAME_BASEGAMES + #define GAME_BASEGAMES "data" + #endif + #ifndef GAME_FULLNAME + #define GAME_FULLNAME FULLENGINENAME + #endif + #ifndef GAME_MANIFESTUPDATE + #define GAME_MANIFESTUPDATE NULL + #endif + + {"-"GAME_SHORTNAME, GAME_SHORTNAME, GAME_PROTOCOL, {GAME_IDENTIFYINGFILES}, GAME_DEFAULTCMDS, {GAME_BASEGAMES}, GAME_FULLNAME, GAME_MANIFESTUPDATE}, +#endif //note that there is no basic 'fte' gamemode, this is because we aim for network compatability. Darkplaces-Quake is the closest we get. //this is to avoid having too many gamemodes anyway. //mission packs should generally come after the main game to avoid prefering the main game. we violate this for hexen2 as the mission pack is mostly a superset. //whereas the quake mission packs replace start.bsp making the original episodes unreachable. //for quake, we also allow extracting all files from paks. some people think it loads faster that way or something. - +#ifndef NOLEGACY //cmdline switch exename protocol name(dpmaster) identifying file exec dir1 dir2 dir3 dir(fte) full name {"-quake", "q1", "FTE-Quake DarkPlaces-Quake", {"id1/pak0.pak", "id1/quake.rc"},QCFG, {"id1", "qw", "*fte"}, "Quake", "https://fte.triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/}, //quake's mission packs should not be favoured over the base game nor autodetected @@ -3014,6 +3094,7 @@ const gamemode_info_t gamemode_info[] = { #if defined(HLSERVER) || defined(HLCLIENT) //can run in windows, needs hl gamecode enabled. maps can always be viewed, but meh. {"-halflife", "halflife", "FTE-HalfLife", {"valve/liblist.gam"}, NULL, {"valve", "*ftehl"}, "Half-Life"}, +#endif #endif {NULL} @@ -4007,6 +4088,11 @@ static qboolean FS_DirHasGame(const char *basedir, int gameidx) { int j; vfsfile_t *f; + + //none listed, just assume its correct. + if (!gamemode_info[gameidx].auniquefile[0]) + return true; + for (j = 0; j < 4; j++) { if (!gamemode_info[gameidx].auniquefile[j]) @@ -4588,7 +4674,7 @@ static qboolean FS_BeginPackageDownload(struct manpack_s *pack, char *baseurl, q #endif break; case X_GZ: -#ifdef AVAIL_ZLIB +#ifdef AVAIL_GZDEC tmpf = FS_GZ_DecompressWriteFilter(tmpf, true); #else VFS_CLOSE(tmpf); @@ -5549,6 +5635,7 @@ void COM_InitFilesystem (void) Cmd_AddCommandD("fs_changegame", FS_ChangeGame_f, "Switch between different manifests (or registered games)"); Cmd_AddCommandD("fs_changemod", FS_ChangeMod_f, "Provides the backend functionality of a transient online installer. Eg, for quaddicted's map/mod database."); Cmd_AddCommand("fs_showmanifest", FS_ShowManifest_f); + Cmd_AddCommand ("fs_flush", COM_RefreshFSCache_f); // // -basedir @@ -5709,24 +5796,26 @@ extern searchpathfuncs_t *(QDECL VFSOS_OpenPath) (vfsfile_t *file, const char *d extern searchpathfuncs_t *(QDECL FSZIP_LoadArchive) (vfsfile_t *packhandle, const char *desc, const char *prefix); #endif extern searchpathfuncs_t *(QDECL FSPAK_LoadArchive) (vfsfile_t *packhandle, const char *desc, const char *prefix); -#ifdef DOOMWADS +#ifdef PACKAGE_DOOMWAD extern searchpathfuncs_t *(QDECL FSDWD_LoadArchive) (vfsfile_t *packhandle, const char *desc, const char *prefix); #endif void FS_RegisterDefaultFileSystems(void) { +#ifdef PACKAGE_Q1PAK FS_RegisterFileSystemType(NULL, "pak", FSPAK_LoadArchive, true); #if !defined(_WIN32) && !defined(ANDROID) /*for systems that have case sensitive paths, also include *.PAK */ FS_RegisterFileSystemType(NULL, "PAK", FSPAK_LoadArchive, true); +#endif #endif FS_RegisterFileSystemType(NULL, "pk3dir", VFSOS_OpenPath, true); -#if 1//def AVAIL_ZLIB +#ifdef PACKAGE_PK3 FS_RegisterFileSystemType(NULL, "pk3", FSZIP_LoadArchive, true); FS_RegisterFileSystemType(NULL, "pk4", FSZIP_LoadArchive, true); FS_RegisterFileSystemType(NULL, "apk", FSZIP_LoadArchive, false); FS_RegisterFileSystemType(NULL, "zip", FSZIP_LoadArchive, false); #endif -#ifdef DOOMWADS +#ifdef PACKAGE_DOOMWAD FS_RegisterFileSystemType(NULL, "wad", FSDWD_LoadArchive, true); #endif } diff --git a/engine/common/fs_pak.c b/engine/common/fs_pak.c index c60b2870..f667f93c 100644 --- a/engine/common/fs_pak.c +++ b/engine/common/fs_pak.c @@ -1,6 +1,8 @@ #include "quakedef.h" #include "fs.h" +#ifdef PACKAGE_Q1PAK + // // in memory // @@ -124,7 +126,7 @@ static unsigned int QDECL FSPAK_FLocate(searchpathfuncs_t *handle, flocation_t * { if (loc) { - loc->index = pf - pak->files; + loc->fhandle = pf; snprintf(loc->rawname, sizeof(loc->rawname), "%s", pak->descname); loc->offset = pf->filepos; loc->len = pf->filelen; @@ -271,7 +273,10 @@ static vfsfile_t *QDECL FSPAK_OpenVFS(searchpathfuncs_t *handle, flocation_t *lo vfs->currentpos = vfs->startpos; #ifdef _DEBUG - Q_strncpyz(vfs->funcs.dbgname, pack->files[loc->index].name, sizeof(vfs->funcs.dbgname)); + { + mpackfile_t *pf = loc->fhandle; + Q_strncpyz(vfs->funcs.dbgname, pf->name, sizeof(vfs->funcs.dbgname)); + } #endif vfs->funcs.Close = VFSPAK_Close; vfs->funcs.GetLen = VFSPAK_GetLen; @@ -404,7 +409,7 @@ searchpathfuncs_t *QDECL FSPAK_LoadArchive (vfsfile_t *file, const char *desc, c return &pack->pub; } -#ifdef DOOMWADS +#ifdef PACKAGE_DOOMWAD searchpathfuncs_t *QDECL FSDWD_LoadArchive (vfsfile_t *packhandle, const char *desc, const char *prefix) { dwadheader_t header; @@ -592,3 +597,4 @@ newsection: return &pack->pub; } #endif +#endif diff --git a/engine/common/fs_stdio.c b/engine/common/fs_stdio.c index 254b9cc2..97b932dc 100644 --- a/engine/common/fs_stdio.c +++ b/engine/common/fs_stdio.c @@ -203,7 +203,7 @@ vfsfile_t *VFSOS_Open(const char *osname, const char *mode) qboolean needsflush; f = VFSSTDIO_Open(osname, mode, &needsflush); if (needsflush) - FS_FlushFSHashReally(true); + FS_FlushFSHashFull(); return f; } #endif @@ -294,7 +294,7 @@ static unsigned int QDECL FSSTDIO_FLocate(searchpathfuncs_t *handle, flocation_t { loc->len = len; loc->offset = 0; - loc->index = 0; + loc->fhandle = handle; Q_strncpyz(loc->rawname, netpath, sizeof(loc->rawname)); } return FF_FOUND; diff --git a/engine/common/fs_win32.c b/engine/common/fs_win32.c index 317bbc13..b1b2eebf 100644 --- a/engine/common/fs_win32.c +++ b/engine/common/fs_win32.c @@ -370,10 +370,10 @@ static vfsfile_t *QDECL VFSW32_OpenInternal(vfsw32path_t *handle, const char *qu if (!didexist) { - if (handle && handle->AddFileHash) + if (handle && quakename && handle->AddFileHash) handle->AddFileHash(handle->hashdepth, quakename, NULL, handle); else - COM_RefreshFSCache_f(); //no idea where this path is. if its inside a quake path, make sure it gets flushed properly. FIXME: his shouldn't be needed if we have change notifications working properly. + FS_FlushFSHashFull(); //FIXME: no idea where this path is. if its inside a quake path, make sure it gets flushed properly. FIXME: his shouldn't be needed if we have change notifications working properly. } @@ -553,7 +553,7 @@ static unsigned int QDECL VFSW32_FLocate(searchpathfuncs_t *handle, flocation_t } loc->len = len; loc->offset = 0; - loc->index = 0; + loc->fhandle = handle; Q_strncpyz(loc->rawname, netpath, sizeof(loc->rawname)); } if (attr & FILE_ATTRIBUTE_DIRECTORY) diff --git a/engine/common/fs_zip.c b/engine/common/fs_zip.c index b773097c..9a55c7b9 100644 --- a/engine/common/fs_zip.c +++ b/engine/common/fs_zip.c @@ -2,55 +2,30 @@ #include "fs.h" #ifdef AVAIL_ZLIB -#define ZIPCRYPT +# define ZIPCRYPT -#ifndef ZEXPORT +# ifndef ZEXPORT #define ZEXPORT VARGS -#endif -#include - -typedef struct { - unsigned char ident1; - unsigned char ident2; - unsigned char cm; - unsigned char flags; - unsigned int mtime; - unsigned char xflags; - unsigned char os; - //unsigned short xlen; - //unsigned char xdata[xlen]; - //unsigned char fname[]; - //unsigned char fcomment[]; - //unsigned short fhcrc; - //unsigned char compresseddata[]; - //unsigned int crc32; - //unsigned int isize; -} gzheader_t; -#define sizeofgzheader_t 10 - -#define GZ_FTEXT 1 -#define GZ_FHCRC 2 -#define GZ_FEXTRA 4 -#define GZ_FNAME 8 -#define GZ_FCOMMENT 16 -#define GZ_RESERVED (32|64|128) - -#ifdef DYNAMIC_ZLIB -#define ZLIB_LOADED() (zlib_handle!=NULL) -void *zlib_handle; -#define ZSTATIC(n) -#else -#define ZLIB_LOADED() 1 -#define ZSTATIC(n) = &n - -#ifdef _MSC_VER -# ifdef _WIN64 -# pragma comment(lib, MSVCLIBSPATH "zlib64.lib") -# else -# pragma comment(lib, MSVCLIBSPATH "zlib.lib") # endif -#endif -#endif +# include + +# ifdef _MSC_VER +# ifdef _WIN64 +# pragma comment(lib, MSVCLIBSPATH "zlib64.lib") +# else +# pragma comment(lib, MSVCLIBSPATH "zlib.lib") +# endif +# endif + +# ifdef DYNAMIC_ZLIB +# define ZLIB_LOADED() (zlib_handle!=NULL) +void *zlib_handle; +# define ZSTATIC(n) +# else +# define ZLIB_LOADED() 1 +# define ZSTATIC(n) = &n + +# endif #ifndef Z_U4 #define z_crc_t uLongf @@ -58,13 +33,20 @@ void *zlib_handle; //#pragma comment(lib, MSVCLIBSPATH "zlib.lib") -static int (ZEXPORT *qinflateEnd) (z_streamp strm) ZSTATIC(inflateEnd); -static int (ZEXPORT *qinflate) (z_streamp strm, int flush) ZSTATIC(inflate); -static int (ZEXPORT *qinflateInit2_) (z_streamp strm, int windowBits, - const char *version, int stream_size) ZSTATIC(inflateInit2_); -//static z_crc_t (ZEXPORT *qcrc32) (uLong crc, const Bytef *buf, uInt len) ZSTATIC(crc32); -#ifdef ZIPCRYPT -static const z_crc_t *(ZEXPORT *qget_crc_table) (void) ZSTATIC(get_crc_table); +#ifdef DYNAMIC_ZLIB + static int (ZEXPORT *qinflateEnd) (z_streamp strm) ZSTATIC(inflateEnd); + static int (ZEXPORT *qinflate) (z_streamp strm, int flush) ZSTATIC(inflate); + static int (ZEXPORT *qinflateInit2_) (z_streamp strm, int windowBits, + const char *version, int stream_size) ZSTATIC(inflateInit2_); + //static z_crc_t (ZEXPORT *qcrc32) (uLong crc, const Bytef *buf, uInt len) ZSTATIC(crc32); + #ifdef ZIPCRYPT + static const z_crc_t *(ZEXPORT *qget_crc_table) (void) ZSTATIC(get_crc_table); + #endif +#else + #define qinflateEnd inflateEnd + #define qinflate inflate + #define qinflateInit2_ inflateInit2_ + #define qget_crc_table get_crc_table #endif #define qinflateInit2(strm, windowBits) \ @@ -90,6 +72,32 @@ qboolean LibZ_Init(void) return ZLIB_LOADED(); } +#ifdef AVAIL_GZDEC +typedef struct { + unsigned char ident1; + unsigned char ident2; + unsigned char cm; + unsigned char flags; + unsigned int mtime; + unsigned char xflags; + unsigned char os; + //unsigned short xlen; + //unsigned char xdata[xlen]; + //unsigned char fname[]; + //unsigned char fcomment[]; + //unsigned short fhcrc; + //unsigned char compresseddata[]; + //unsigned int crc32; + //unsigned int isize; +} gzheader_t; +#define sizeofgzheader_t 10 + +#define GZ_FTEXT 1 +#define GZ_FHCRC 2 +#define GZ_FEXTRA 4 +#define GZ_FNAME 8 +#define GZ_FCOMMENT 16 +#define GZ_RESERVED (32|64|128) //outfile may be null vfsfile_t *FS_DecompressGZip(vfsfile_t *infile, vfsfile_t *outfile) { @@ -457,7 +465,7 @@ vfsfile_t *FS_GZ_DecompressWriteFilter(vfsfile_t *outfile, qboolean autoclosefil return &n->vf; } - +#endif #endif @@ -467,12 +475,7 @@ vfsfile_t *FS_GZ_DecompressWriteFilter(vfsfile_t *outfile, qboolean autoclosefil - - - - - - +#ifdef PACKAGE_PK3 typedef struct { @@ -581,7 +584,7 @@ static unsigned int QDECL FSZIP_FLocate(searchpathfuncs_t *handle, flocation_t * ret = FF_FOUND; if (loc) { - loc->index = pf - zip->files; + loc->fhandle = pf; *loc->rawname = 0; loc->offset = (qofs_t)-1; loc->len = pf->filelen; @@ -893,14 +896,7 @@ static vfsfile_t *FSZIP_Decompress_ToTempFile(struct decompressstate *decompress #else struct decompressstate { -// zipfile_t *source; -// qofs_t cstart; //position of start of data -// qofs_t cofs; //current read offset -// qofs_t cend; //compressed data ends at this point. -// qofs_t usize; //data remaining. refuse to read more bytes than this. -// unsigned char inbuffer[16384]; -// unsigned char outbuffer[16384]; -// unsigned int readoffset; + int nothing; }; struct decompressstate *FSZIP_Decompress_Init(zipfile_t *source, qofs_t start, qofs_t csize, qofs_t usize, char *filename, char *password, unsigned int crc) { @@ -1027,6 +1023,7 @@ static vfsfile_t *QDECL FSZIP_OpenVFS(searchpathfuncs_t *handle, flocation_t *lo vfszip_t *vfsz; unsigned int flags; qofs_t datasize = 0; + zpackfile_t *pf = loc->fhandle; if (strcmp(mode, "rb")) return NULL; //urm, unable to write/append @@ -1034,7 +1031,7 @@ static vfsfile_t *QDECL FSZIP_OpenVFS(searchpathfuncs_t *handle, flocation_t *lo if (qofs_Error(loc->len)) return NULL; - flags = zip->files[loc->index].flags; + flags = pf->flags; if (flags & ZFL_CORRUPT) return NULL; @@ -1044,7 +1041,7 @@ static vfsfile_t *QDECL FSZIP_OpenVFS(searchpathfuncs_t *handle, flocation_t *lo vfsz->length = loc->len; #ifdef _DEBUG - Q_strncpyz(vfsz->funcs.dbgname, zip->files[loc->index].name, sizeof(vfsz->funcs.dbgname)); + Q_strncpyz(vfsz->funcs.dbgname, pf->name, sizeof(vfsz->funcs.dbgname)); #endif vfsz->funcs.Close = VFSZIP_Close; vfsz->funcs.GetLen = VFSZIP_GetLen; @@ -1055,7 +1052,7 @@ static vfsfile_t *QDECL FSZIP_OpenVFS(searchpathfuncs_t *handle, flocation_t *lo vfsz->funcs.WriteBytes = NULL; vfsz->funcs.seekingisabadplan = true; - if (!FSZIP_ValidateLocalHeader(zip, &zip->files[loc->index], &vfsz->startpos, &datasize)) + if (!FSZIP_ValidateLocalHeader(zip, pf, &vfsz->startpos, &datasize)) { Z_Free(vfsz); return NULL; @@ -1069,7 +1066,7 @@ static vfsfile_t *QDECL FSZIP_OpenVFS(searchpathfuncs_t *handle, flocation_t *lo #else char *password = NULL; #endif - vfsz->decompress = FSZIP_Decompress_Init(zip, vfsz->startpos, datasize, vfsz->length, zip->files[loc->index].name, password, zip->files[loc->index].crc); + vfsz->decompress = FSZIP_Decompress_Init(zip, vfsz->startpos, datasize, vfsz->length, pf->name, password, pf->crc); if (!vfsz->decompress) { /* @@ -1693,7 +1690,7 @@ static qboolean FSZIP_FindEndCentralDirectory(zipfile_t *zip, struct zipinfo *in Con_Printf("zip: zip64 end-of-central directory at unknown offset.\n"); result = false; } - + break; } } @@ -1921,4 +1918,5 @@ struct archivedeltafuncs_s *FSZIP_OpenDeltaZip(qdownload_t *dl) return &za->pub; } #endif +#endif diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index e6cb06a9..2f0dfb93 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -60,7 +60,7 @@ void Mod_LoadEntities (model_t *loadmodel, qbyte *mod_base, lump_t *l); extern void BuildLightMapGammaTable (float g, float c); -#ifdef Q2BSPS +#if defined(Q2BSPS) || defined(Q3BSPS) static qboolean CM_NativeTrace(model_t *model, int forcehullnum, framestate_t *framestate, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int contents, trace_t *trace); static unsigned int CM_NativeContents(struct model_s *model, int hulloverride, framestate_t *framestate, vec3_t axis[3], vec3_t p, vec3_t mins, vec3_t maxs); static unsigned int Q2BSP_PointContents(model_t *mod, vec3_t axis[3], vec3_t p); @@ -178,7 +178,7 @@ void Mod_SortShaders(model_t *mod) -#ifdef Q2BSPS +#if defined(Q2BSPS) || defined(Q3BSPS) qbyte *ReadPCXPalette(qbyte *buf, int len, qbyte *out); @@ -398,6 +398,13 @@ void CM_InitBoxHull (void); static void CM_FinalizeBrush(q2cbrush_t *brush); static void FloodAreaConnections (cminfo_t *prv); +qboolean BoundsIntersect (vec3_t mins1, vec3_t maxs1, vec3_t mins2, vec3_t maxs2) +{ + return (mins1[0] <= maxs2[0] && mins1[1] <= maxs2[1] && mins1[2] <= maxs2[2] && + maxs1[0] >= mins2[0] && maxs1[1] >= mins2[1] && maxs1[2] >= mins2[2]); +} + +#ifdef Q3BSPS static int numvertexes; static vecV_t *map_verts; //3points static vec2_t *map_vertstmexcoords; @@ -408,13 +415,11 @@ static vec3_t *map_normals_array; //static vec3_t *map_tvector_array; static index_t *map_surfindexes; -static int map_numsurfindexes; +//static int map_numsurfindexes; -q3cface_t *map_faces; +static q3cface_t *map_faces; static int numfaces; - - int PlaneTypeForNormal ( vec3_t normal ) { vec_t ax, ay, az; @@ -465,12 +470,6 @@ void PlaneFromPoints ( vec3_t verts[3], mplane_t *plane ) plane->dist = DotProduct( verts[0], plane->normal ); } -qboolean BoundsIntersect (vec3_t mins1, vec3_t maxs1, vec3_t mins2, vec3_t maxs2) -{ - return (mins1[0] <= maxs2[0] && mins1[1] <= maxs2[1] && mins1[2] <= maxs2[2] && - maxs1[0] >= mins2[0] && maxs1[1] >= mins2[1] && maxs1[2] >= mins2[2]); -} - /* =============== Patch_FlatnessTest @@ -508,7 +507,7 @@ static int Patch_FlatnessTest( float maxflat2, const float *point0, const float Patch_GetFlatness =============== */ -void Patch_GetFlatness( float maxflat, const float *points, int comp, const int *patch_cp, int *flat ) +static void Patch_GetFlatness( float maxflat, const float *points, int comp, const int *patch_cp, int *flat ) { int i, p, u, v; float maxflat2 = maxflat * maxflat; @@ -560,7 +559,7 @@ static void Patch_Evaluate_QuadricBezier( float t, const vec_t *point0, const ve Patch_Evaluate =============== */ -void Patch_Evaluate( const vec_t *p, const int *numcp, const int *tess, vec_t *dest, int comp ) +static void Patch_Evaluate( const vec_t *p, const int *numcp, const int *tess, vec_t *dest, int comp ) { int num_patches[2], num_tess[2]; int index[3], dstpitch, i, u, v, x, y; @@ -953,7 +952,7 @@ static void CM_CreatePatch(model_t *loadmodel, q3cpatch_t *patch, q2mapsurface_t CM_CreatePatchesForLeafs ================= */ -qboolean CM_CreatePatchesForLeafs (model_t *loadmodel, cminfo_t *prv) +static qboolean CM_CreatePatchesForLeafs (model_t *loadmodel, cminfo_t *prv) { int i, j, k; mleaf_t *leaf; @@ -1112,7 +1111,7 @@ qboolean CM_CreatePatchesForLeafs (model_t *loadmodel, cminfo_t *prv) return true; } - +#endif /* @@ -1123,12 +1122,22 @@ qboolean CM_CreatePatchesForLeafs (model_t *loadmodel, cminfo_t *prv) =============================================================================== */ +static void CMod_SetParent (mnode_t *node, mnode_t *parent) +{ + node->parent = parent; + if (node->contents != -1) + return; + CMod_SetParent (node->children[0], node); + CMod_SetParent (node->children[1], node); +} + +#ifdef Q2BSPS /* ================= CMod_LoadSubmodels ================= */ -qboolean CModQ2_LoadSubmodels (model_t *loadmodel, qbyte *mod_base, lump_t *l) +static qboolean CModQ2_LoadSubmodels (model_t *loadmodel, qbyte *mod_base, lump_t *l) { cminfo_t *prv = (cminfo_t*)loadmodel->meshinfo; q2dmodel_t *in; @@ -1182,7 +1191,7 @@ qboolean CModQ2_LoadSubmodels (model_t *loadmodel, qbyte *mod_base, lump_t *l) CMod_LoadSurfaces ================= */ -qboolean CModQ2_LoadSurfaces (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ2_LoadSurfaces (model_t *mod, qbyte *mod_base, lump_t *l) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; q2texinfo_t *in; @@ -1218,7 +1227,7 @@ qboolean CModQ2_LoadSurfaces (model_t *mod, qbyte *mod_base, lump_t *l) return true; } #ifndef SERVERONLY -texture_t *Mod_LoadWall(model_t *loadmodel, char *mapname, char *texname, char *shadername, unsigned int imageflags) +static texture_t *Mod_LoadWall(model_t *loadmodel, char *mapname, char *texname, char *shadername, unsigned int imageflags) { char name[MAX_QPATH]; q2miptex_t replacementwal; @@ -1304,7 +1313,7 @@ texture_t *Mod_LoadWall(model_t *loadmodel, char *mapname, char *texname, char * return tex; } -qboolean CModQ2_LoadTexInfo (model_t *mod, qbyte *mod_base, lump_t *l, char *mapname) //yes I know these load from the same place +static qboolean CModQ2_LoadTexInfo (model_t *mod, qbyte *mod_base, lump_t *l, char *mapname) //yes I know these load from the same place { q2texinfo_t *in; mtexinfo_t *out; @@ -1434,7 +1443,7 @@ qboolean CModQ2_LoadTexInfo (model_t *mod, qbyte *mod_base, lump_t *l, char *map } #endif /* -void CalcSurfaceExtents (msurface_t *s) +static void CalcSurfaceExtents (msurface_t *s) { float mins[2], maxs[2], val; int i,j, e; @@ -1487,7 +1496,7 @@ Mod_LoadFaces ================= */ #ifndef SERVERONLY -qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l, qboolean lightofsisdouble) +static qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l, qboolean lightofsisdouble) { dsface_t *in; msurface_t *out; @@ -1584,22 +1593,13 @@ qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l, qboolean li } #endif -void CMod_SetParent (mnode_t *node, mnode_t *parent) -{ - node->parent = parent; - if (node->contents != -1) - return; - CMod_SetParent (node->children[0], node); - CMod_SetParent (node->children[1], node); -} - /* ================= CMod_LoadNodes ================= */ -qboolean CModQ2_LoadNodes (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ2_LoadNodes (model_t *mod, qbyte *mod_base, lump_t *l) { q2dnode_t *in; int child; @@ -1668,7 +1668,7 @@ CMod_LoadBrushes ================= */ -qboolean CModQ2_LoadBrushes (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ2_LoadBrushes (model_t *mod, qbyte *mod_base, lump_t *l) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; q2dbrush_t *in; @@ -1712,7 +1712,7 @@ qboolean CModQ2_LoadBrushes (model_t *mod, qbyte *mod_base, lump_t *l) CMod_LoadLeafs ================= */ -qboolean CModQ2_LoadLeafs (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ2_LoadLeafs (model_t *mod, qbyte *mod_base, lump_t *l) { int i, j; mleaf_t *out; @@ -1787,7 +1787,7 @@ qboolean CModQ2_LoadLeafs (model_t *mod, qbyte *mod_base, lump_t *l) CMod_LoadPlanes ================= */ -qboolean CModQ2_LoadPlanes (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ2_LoadPlanes (model_t *mod, qbyte *mod_base, lump_t *l) { int i, j; mplane_t *out; @@ -1841,7 +1841,7 @@ qboolean CModQ2_LoadPlanes (model_t *mod, qbyte *mod_base, lump_t *l) CMod_LoadLeafBrushes ================= */ -qboolean CModQ2_LoadLeafBrushes (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ2_LoadLeafBrushes (model_t *mod, qbyte *mod_base, lump_t *l) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; int i; @@ -1883,7 +1883,7 @@ qboolean CModQ2_LoadLeafBrushes (model_t *mod, qbyte *mod_base, lump_t *l) CMod_LoadBrushSides ================= */ -qboolean CModQ2_LoadBrushSides (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ2_LoadBrushSides (model_t *mod, qbyte *mod_base, lump_t *l) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; unsigned int i, j; @@ -1929,7 +1929,7 @@ qboolean CModQ2_LoadBrushSides (model_t *mod, qbyte *mod_base, lump_t *l) CMod_LoadAreas ================= */ -qboolean CModQ2_LoadAreas (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ2_LoadAreas (model_t *mod, qbyte *mod_base, lump_t *l) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; int i; @@ -1970,7 +1970,7 @@ qboolean CModQ2_LoadAreas (model_t *mod, qbyte *mod_base, lump_t *l) CMod_LoadAreaPortals ================= */ -qboolean CModQ2_LoadAreaPortals (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ2_LoadAreaPortals (model_t *mod, qbyte *mod_base, lump_t *l) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; int i; @@ -2009,7 +2009,7 @@ qboolean CModQ2_LoadAreaPortals (model_t *mod, qbyte *mod_base, lump_t *l) CMod_LoadVisibility ================= */ -qboolean CModQ2_LoadVisibility (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ2_LoadVisibility (model_t *mod, qbyte *mod_base, lump_t *l) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; int i; @@ -2036,9 +2036,10 @@ qboolean CModQ2_LoadVisibility (model_t *mod, qbyte *mod_base, lump_t *l) return true; } +#endif //q2bsps #ifdef Q3BSPS -qboolean CModQ3_LoadMarksurfaces (model_t *loadmodel, qbyte *mod_base, lump_t *l) +static qboolean CModQ3_LoadMarksurfaces (model_t *loadmodel, qbyte *mod_base, lump_t *l) { int i, j, count; int *in; @@ -2070,7 +2071,7 @@ qboolean CModQ3_LoadMarksurfaces (model_t *loadmodel, qbyte *mod_base, lump_t *l return true; } -qboolean CModQ3_LoadSubmodels (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ3_LoadSubmodels (model_t *mod, qbyte *mod_base, lump_t *l) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; q3dmodel_t *in; @@ -2154,7 +2155,7 @@ qboolean CModQ3_LoadSubmodels (model_t *mod, qbyte *mod_base, lump_t *l) return true; } -qboolean CModQ3_LoadShaders (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ3_LoadShaders (model_t *mod, qbyte *mod_base, lump_t *l) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; dq3shader_t *in; @@ -2213,7 +2214,7 @@ qboolean CModQ3_LoadShaders (model_t *mod, qbyte *mod_base, lump_t *l) return true; } -qboolean CModQ3_LoadVertexes (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ3_LoadVertexes (model_t *mod, qbyte *mod_base, lump_t *l) { q3dvertex_t *in; vecV_t *out; @@ -2281,7 +2282,8 @@ qboolean CModQ3_LoadVertexes (model_t *mod, qbyte *mod_base, lump_t *l) return true; } -qboolean CModRBSP_LoadVertexes (model_t *mod, qbyte *mod_base, lump_t *l) +#ifdef RFBSPS +static qboolean CModRBSP_LoadVertexes (model_t *mod, qbyte *mod_base, lump_t *l) { rbspvertex_t *in; vecV_t *out; @@ -2349,9 +2351,10 @@ qboolean CModRBSP_LoadVertexes (model_t *mod, qbyte *mod_base, lump_t *l) return true; } +#endif - -qboolean CModQ3_LoadIndexes (model_t *loadmodel, qbyte *mod_base, lump_t *l) +#ifndef SERVERONLY +static qboolean CModQ3_LoadIndexes (model_t *loadmodel, qbyte *mod_base, lump_t *l) { int i, count; int *in; @@ -2374,20 +2377,21 @@ qboolean CModQ3_LoadIndexes (model_t *loadmodel, qbyte *mod_base, lump_t *l) out = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*out)); map_surfindexes = out; - map_numsurfindexes = count; +// map_numsurfindexes = count; for ( i=0 ; inumsurfaces = i; return true; } +#endif #ifndef SERVERONLY @@ -2491,7 +2497,7 @@ qboolean CModRBSP_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l) Mod_LoadFogs ================= */ -qboolean CModQ3_LoadFogs (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ3_LoadFogs (model_t *mod, qbyte *mod_base, lump_t *l) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; dfog_t *in; @@ -2569,9 +2575,9 @@ mfog_t *Mod_FogForOrigin(model_t *wmodel, vec3_t org) #define MAX_ARRAY_VERTS 65535 -index_t tempIndexesArray[MAX_ARRAY_VERTS*6]; +static index_t tempIndexesArray[MAX_ARRAY_VERTS*6]; -void GL_SizePatch(mesh_t *mesh, int patchwidth, int patchheight, int numverts, int firstvert) +static void GL_SizePatch(mesh_t *mesh, int patchwidth, int patchheight, int numverts, int firstvert) { int patch_cp[2], step[2], size[2], flat[2]; float subdivlevel; @@ -2604,9 +2610,9 @@ void GL_SizePatch(mesh_t *mesh, int patchwidth, int patchheight, int numverts, i } //mesh_t *GL_CreateMeshForPatch ( model_t *mod, q3dface_t *surf ) -void GL_CreateMeshForPatch (model_t *mod, mesh_t *mesh, int patchwidth, int patchheight, int numverts, int firstvert) +static void GL_CreateMeshForPatch (model_t *mod, mesh_t *mesh, int patchwidth, int patchheight, int numverts, int firstvert) { - int numindexes, patch_cp[2], step[2], size[2], flat[2], i, u, v, p; + int numindexes, patch_cp[2], step[2], size[2], flat[2], i, u, v, p; index_t *indexes; float subdivlevel; int sty; @@ -2706,7 +2712,8 @@ void GL_CreateMeshForPatch (model_t *mod, mesh_t *mesh, int patchwidth, int patc memcpy (mesh->indexes, tempIndexesArray, numindexes * sizeof(index_t) ); } -void CModRBSP_BuildSurfMesh(model_t *mod, msurface_t *out, builddata_t *bd) +#ifdef RFBSPS +static void CModRBSP_BuildSurfMesh(model_t *mod, msurface_t *out, builddata_t *bd) { rbspface_t *in = (rbspface_t*)(bd+1); int idx = (out - mod->surfaces) - mod->firstmodelsurface; @@ -2778,8 +2785,9 @@ void CModRBSP_BuildSurfMesh(model_t *mod, msurface_t *out, builddata_t *bd) Mod_AccumulateMeshTextureVectors(out->mesh); Mod_NormaliseTextureVectors(out->mesh->normals_array, out->mesh->snormals_array, out->mesh->tnormals_array, out->mesh->numvertexes, false); } +#endif -void CModQ3_BuildSurfMesh(model_t *mod, msurface_t *out, builddata_t *bd) +static void CModQ3_BuildSurfMesh(model_t *mod, msurface_t *out, builddata_t *bd) { q3dface_t *in = (q3dface_t*)(bd+1); int idx = (out - mod->surfaces) - mod->firstmodelsurface; @@ -2848,7 +2856,7 @@ void CModQ3_BuildSurfMesh(model_t *mod, msurface_t *out, builddata_t *bd) Mod_NormaliseTextureVectors(out->mesh->normals_array, out->mesh->snormals_array, out->mesh->tnormals_array, out->mesh->numvertexes, false); } -qboolean CModQ3_LoadRFaces (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ3_LoadRFaces (model_t *mod, qbyte *mod_base, lump_t *l) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; extern cvar_t r_vertexlight; @@ -2962,7 +2970,8 @@ qboolean CModQ3_LoadRFaces (model_t *mod, qbyte *mod_base, lump_t *l) return true; } -qboolean CModRBSP_LoadRFaces (model_t *mod, qbyte *mod_base, lump_t *l) +#ifdef RFBSPS +static qboolean CModRBSP_LoadRFaces (model_t *mod, qbyte *mod_base, lump_t *l) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; extern cvar_t r_vertexlight; @@ -3072,8 +3081,9 @@ qboolean CModRBSP_LoadRFaces (model_t *mod, qbyte *mod_base, lump_t *l) return true; } #endif +#endif -qboolean CModQ3_LoadNodes (model_t *loadmodel, qbyte *mod_base, lump_t *l) +static qboolean CModQ3_LoadNodes (model_t *loadmodel, qbyte *mod_base, lump_t *l) { int i, j, count, p; q3dnode_t *in; @@ -3134,7 +3144,7 @@ qboolean CModQ3_LoadNodes (model_t *loadmodel, qbyte *mod_base, lump_t *l) return true; } -qboolean CModQ3_LoadBrushes (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ3_LoadBrushes (model_t *mod, qbyte *mod_base, lump_t *l) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; q3dbrush_t *in; @@ -3174,7 +3184,7 @@ qboolean CModQ3_LoadBrushes (model_t *mod, qbyte *mod_base, lump_t *l) return true; } -qboolean CModQ3_LoadLeafs (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ3_LoadLeafs (model_t *mod, qbyte *mod_base, lump_t *l) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; int i, j; @@ -3248,7 +3258,7 @@ qboolean CModQ3_LoadLeafs (model_t *mod, qbyte *mod_base, lump_t *l) return true; } -qboolean CModQ3_LoadPlanes (model_t *loadmodel, qbyte *mod_base, lump_t *l) +static qboolean CModQ3_LoadPlanes (model_t *loadmodel, qbyte *mod_base, lump_t *l) { int i, j; mplane_t *out; @@ -3286,7 +3296,7 @@ qboolean CModQ3_LoadPlanes (model_t *loadmodel, qbyte *mod_base, lump_t *l) return true; } -qboolean CModQ3_LoadLeafBrushes (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ3_LoadLeafBrushes (model_t *mod, qbyte *mod_base, lump_t *l) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; int i; @@ -3323,7 +3333,7 @@ qboolean CModQ3_LoadLeafBrushes (model_t *mod, qbyte *mod_base, lump_t *l) return true; } -qboolean CModQ3_LoadBrushSides (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ3_LoadBrushSides (model_t *mod, qbyte *mod_base, lump_t *l) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; int i, j; @@ -3366,7 +3376,8 @@ qboolean CModQ3_LoadBrushSides (model_t *mod, qbyte *mod_base, lump_t *l) return true; } -qboolean CModRBSP_LoadBrushSides (model_t *mod, qbyte *mod_base, lump_t *l) +#ifdef RFBSPS +static qboolean CModRBSP_LoadBrushSides (model_t *mod, qbyte *mod_base, lump_t *l) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; int i, j; @@ -3408,8 +3419,9 @@ qboolean CModRBSP_LoadBrushSides (model_t *mod, qbyte *mod_base, lump_t *l) return true; } +#endif -qboolean CModQ3_LoadVisibility (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ3_LoadVisibility (model_t *mod, qbyte *mod_base, lump_t *l) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; unsigned int numclusters; @@ -3446,7 +3458,7 @@ qboolean CModQ3_LoadVisibility (model_t *mod, qbyte *mod_base, lump_t *l) } #ifndef SERVERONLY -void CModQ3_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l) +static void CModQ3_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l) { qbyte *in = mod_base + l->fileofs; qbyte *out; @@ -3512,7 +3524,7 @@ void CModQ3_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l) } } -qboolean CModQ3_LoadLightgrid (model_t *loadmodel, qbyte *mod_base, lump_t *l) +static qboolean CModQ3_LoadLightgrid (model_t *loadmodel, qbyte *mod_base, lump_t *l) { dq3gridlight_t *in; dq3gridlight_t *out; @@ -3538,7 +3550,9 @@ qboolean CModQ3_LoadLightgrid (model_t *loadmodel, qbyte *mod_base, lump_t *l) return true; } -qboolean CModRBSP_LoadLightgrid (model_t *loadmodel, qbyte *mod_base, lump_t *elements, lump_t *indexes) + +#ifdef RFBSPS +static qboolean CModRBSP_LoadLightgrid (model_t *loadmodel, qbyte *mod_base, lump_t *elements, lump_t *indexes) { unsigned short *iin; rbspgridlight_t *ein; @@ -3580,10 +3594,11 @@ qboolean CModRBSP_LoadLightgrid (model_t *loadmodel, qbyte *mod_base, lump_t *el } #endif #endif +#endif -#ifndef SERVERONLY +#if !defined(SERVERONLY) && defined(Q2BSPS) qbyte *ReadPCXPalette(qbyte *buf, int len, qbyte *out); -int CM_GetQ2Palette (void) +static int CM_GetQ2Palette (void) { char *f; size_t sz; @@ -3628,7 +3643,8 @@ int CM_GetQ2Palette (void) } #endif -void CM_OpenAllPortals(model_t *mod, char *ents) //this is a compleate hack. About as compleate as possible. +#if 0 +static void CM_OpenAllPortals(model_t *mod, char *ents) //this is a compleate hack. About as compleate as possible. { //q2 levels contain a thingie called area portals. Basically, doors can seperate two areas and //the engine knows when this portal is open, and weather to send ents from both sides of the door //or not. It's not just ents, but also walls. We want to just open them by default and hope the @@ -3675,10 +3691,11 @@ void CM_OpenAllPortals(model_t *mod, char *ents) //this is a compleate hack. Abo ents++; } } +#endif -#ifndef CLIENTONLY -void CMQ3_CalcPHS (model_t *mod) +#if !defined(CLIENTONLY) && defined(Q3BSPS) +static void CMQ3_CalcPHS (model_t *mod) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; int rowbytes, rowwords; @@ -3888,7 +3905,9 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole model_t *wmod = mod; char loadname[32]; qbyte *mod_base = (qbyte *)filein; +#ifdef Q3BSPS extern cvar_t gl_overbright; +#endif #ifndef SERVERONLY void (*buildmeshes)(model_t *mod, msurface_t *surf, builddata_t *cookie) = NULL; @@ -3945,15 +3964,19 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole return NULL; break; #ifdef Q3BSPS +#ifdef RFBSPS case BSPVERSION_RBSP: //rbsp/fbsp +#endif case BSPVERSION_RTCW: //rtcw case BSPVERSION_Q3: +#ifdef RFBSPS if (header.ident == (('F'<<0)+('B'<<8)+('S'<<16)+('P'<<24))) { mod->lightmaps.width = 512; mod->lightmaps.height = 512; } else +#endif { mod->lightmaps.width = 128; mod->lightmaps.height = 128; @@ -3963,12 +3986,14 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole mod->fromgame = fg_quake3; for (i=0 ; imapisq3 = true; noerrors = noerrors && CModQ3_LoadShaders (mod, mod_base, &header.lumps[Q3LUMP_SHADERS]); noerrors = noerrors && CModQ3_LoadPlanes (mod, mod_base, &header.lumps[Q3LUMP_PLANES]); +#ifdef RFBSPS if (header.version == BSPVERSION_RBSP) { noerrors = noerrors && CModRBSP_LoadBrushSides (mod, mod_base, &header.lumps[Q3LUMP_BRUSHSIDES]); noerrors = noerrors && CModRBSP_LoadVertexes (mod, mod_base, &header.lumps[Q3LUMP_DRAWVERTS]); } else +#endif { noerrors = noerrors && CModQ3_LoadBrushSides (mod, mod_base, &header.lumps[Q3LUMP_BRUSHSIDES]); noerrors = noerrors && CModQ3_LoadVertexes (mod, mod_base, &header.lumps[Q3LUMP_DRAWVERTS]); } noerrors = noerrors && CModQ3_LoadBrushes (mod, mod_base, &header.lumps[Q3LUMP_BRUSHES]); noerrors = noerrors && CModQ3_LoadLeafBrushes (mod, mod_base, &header.lumps[Q3LUMP_LEAFBRUSHES]); - if (header.version == 1) +#ifdef RFBSPS + if (header.version == BSPVERSION_RBSP) noerrors = noerrors && CModRBSP_LoadFaces (mod, mod_base, &header.lumps[Q3LUMP_SURFACES]); else +#endif noerrors = noerrors && CModQ3_LoadFaces (mod, mod_base, &header.lumps[Q3LUMP_SURFACES]); #ifndef SERVERONLY if (qrenderer != QR_NONE) { +#ifdef RFBSPS if (header.version == BSPVERSION_RBSP) noerrors = noerrors && CModRBSP_LoadLightgrid (mod, mod_base, &header.lumps[Q3LUMP_LIGHTGRID], &header.lumps[RBSPLUMP_LIGHTINDEXES]); else +#endif noerrors = noerrors && CModQ3_LoadLightgrid (mod, mod_base, &header.lumps[Q3LUMP_LIGHTGRID]); noerrors = noerrors && CModQ3_LoadIndexes (mod, mod_base, &header.lumps[Q3LUMP_DRAWINDEXES]); @@ -4052,6 +4083,7 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole mod->numfogs = 0; facedata = (void *)(mod_base + header.lumps[Q3LUMP_SURFACES].fileofs); +#ifdef RFBSPS if (header.version == BSPVERSION_RBSP) { noerrors = noerrors && CModRBSP_LoadRFaces (mod, mod_base, &header.lumps[Q3LUMP_SURFACES]); @@ -4060,6 +4092,7 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole mod->lightmaps.surfstyles = 4; } else +#endif { noerrors = noerrors && CModQ3_LoadRFaces (mod, mod_base, &header.lumps[Q3LUMP_SURFACES]); buildmeshes = CModQ3_BuildSurfMesh; @@ -4098,9 +4131,9 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole } #ifndef CLIENTONLY - mod->funcs.FatPVS = Q2BSP_FatPVS; - mod->funcs.EdictInFatPVS = Q2BSP_EdictInFatPVS; - mod->funcs.FindTouchedLeafs = Q2BSP_FindTouchedLeafs; + mod->funcs.FatPVS = Q23BSP_FatPVS; + mod->funcs.EdictInFatPVS = Q23BSP_EdictInFatPVS; + mod->funcs.FindTouchedLeafs = Q23BSP_FindTouchedLeafs; #endif mod->funcs.ClusterPVS = CM_ClusterPVS; mod->funcs.ClusterForPoint = CM_PointCluster; @@ -4161,6 +4194,7 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole BZ_Free(map_faces); break; #endif +#ifdef Q2BSPS case BSPVERSION_Q2: case BSPVERSION_Q2W: mod->lightmaps.width = LMBLOCK_SIZE_MAX; @@ -4204,9 +4238,9 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole Mod_LoadEntities (mod, mod_base, &header.lumps[Q2LUMP_ENTITIES]); #ifndef CLIENTONLY - mod->funcs.FatPVS = Q2BSP_FatPVS; - mod->funcs.EdictInFatPVS = Q2BSP_EdictInFatPVS; - mod->funcs.FindTouchedLeafs = Q2BSP_FindTouchedLeafs; + mod->funcs.FatPVS = Q23BSP_FatPVS; + mod->funcs.EdictInFatPVS = Q23BSP_EdictInFatPVS; + mod->funcs.FindTouchedLeafs = Q23BSP_FindTouchedLeafs; #endif mod->funcs.LightPointValues = NULL; mod->funcs.StainNode = NULL; @@ -4250,9 +4284,9 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole return NULL; } #ifndef CLIENTONLY - mod->funcs.FatPVS = Q2BSP_FatPVS; - mod->funcs.EdictInFatPVS = Q2BSP_EdictInFatPVS; - mod->funcs.FindTouchedLeafs = Q2BSP_FindTouchedLeafs; + mod->funcs.FatPVS = Q23BSP_FatPVS; + mod->funcs.EdictInFatPVS = Q23BSP_EdictInFatPVS; + mod->funcs.FindTouchedLeafs = Q23BSP_FindTouchedLeafs; #endif mod->funcs.LightPointValues = GLQ2BSP_LightPointValues; mod->funcs.StainNode = GLR_Q2BSP_StainNode; @@ -4265,6 +4299,7 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole break; #endif } +#endif } if (map_autoopenportals.value) @@ -4388,15 +4423,17 @@ static cmodel_t *CM_InlineModel (model_t *model, char *name) return &prv->cmodels[num]; } -int CM_NumClusters (model_t *model) +int CM_ClusterBytes (model_t *model) { - return model->numclusters; -} - -int CM_ClusterSize (model_t *model) -{ - cminfo_t *prv = (cminfo_t*)model->meshinfo; - return prv->q3pvs->rowsize ? prv->q3pvs->rowsize : MAX_MAP_LEAFS / 8; +#ifdef Q3BSPS + if (model->fromgame == fg_quake3) + { + cminfo_t *prv = (cminfo_t*)model->meshinfo; + return prv->q3pvs->rowsize ? prv->q3pvs->rowsize : MAX_MAP_LEAFS / 8; + } + else +#endif + return (model->numclusters+7)/8; } static int CM_NumInlineModels (model_t *model) @@ -4465,7 +4502,7 @@ void CM_InitBoxHull (void) #ifndef CLIENTONLY box_model.funcs.FatPVS = Q2BSP_FatPVS; box_model.funcs.EdictInFatPVS = Q2BSP_EdictInFatPVS; - box_model.funcs.FindTouchedLeafs = Q2BSP_FindTouchedLeafs; + box_model.funcs.FindTouchedLeafs = Q23BSP_FindTouchedLeafs; #endif #ifndef SERVERONLY @@ -4960,6 +4997,7 @@ static void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, } } +#ifdef Q3BSPS static void CM_ClipBoxToPlanes (vec3_t trmins, vec3_t trmaxs, vec3_t p1, vec3_t p2, trace_t *trace, vec3_t plmins, vec3_t plmaxs, mplane_t *plane, int numplanes, q2csurface_t *surf) { int i, j; @@ -5128,6 +5166,7 @@ static void CM_ClipBoxToPlanes (vec3_t trmins, vec3_t trmaxs, vec3_t p1, vec3_t } } } + static void Mod_Trace_Trisoup_(vecV_t *posedata, index_t *indexes, size_t numindexes, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace, q2csurface_t *surf) { size_t i; @@ -5309,7 +5348,7 @@ static void CM_ClipBoxToPatch (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, leavefrac=0; } } - +#endif /* ================ @@ -5370,6 +5409,7 @@ static void CM_TestBoxInBrush (vec3_t mins, vec3_t maxs, vec3_t p1, trace->contents |= brush->contents; } +#ifdef Q3BSPS static void CM_TestBoxInPatch (vec3_t mins, vec3_t maxs, vec3_t p1, trace_t *trace, q2cbrush_t *brush) { @@ -5434,7 +5474,7 @@ static void CM_TestBoxInPatch (vec3_t mins, vec3_t maxs, vec3_t p1, trace->startsolid = trace->allsolid = true; trace->contents = brush->contents; } - +#endif /* ================ @@ -5443,12 +5483,14 @@ CM_TraceToLeaf */ static void CM_TraceToLeaf (cminfo_t *prv, mleaf_t *leaf) { - int k, j; + int k; q2cbrush_t *b; - int patchnum; +#ifdef Q3BSPS + int patchnum, j; q3cpatch_t *patch; q3cmesh_t *cmesh; +#endif if ( !(leaf->contents & trace_contents)) return; @@ -5469,6 +5511,7 @@ static void CM_TraceToLeaf (cminfo_t *prv, mleaf_t *leaf) return; } +#ifdef Q3BSPS if (!prv->mapisq3 || map_noCurves.value) return; @@ -5509,6 +5552,7 @@ static void CM_TraceToLeaf (cminfo_t *prv, mleaf_t *leaf) if (trace_nearfraction<=0) return; } +#endif } @@ -5519,11 +5563,13 @@ CM_TestInLeaf */ static void CM_TestInLeaf (cminfo_t *prv, mleaf_t *leaf) { - int k, j; - int patchnum; + int k; q2cbrush_t *b; +#ifdef Q3BSPS + int patchnum, j; q3cmesh_t *cmesh; q3cpatch_t *patch; +#endif if ( !(leaf->contents & trace_contents)) return; @@ -5544,10 +5590,11 @@ static void CM_TestInLeaf (cminfo_t *prv, mleaf_t *leaf) return; } +#ifdef Q3BSPS if (!prv->mapisq3 || map_noCurves.value) return; - // trace line against all patches in the leaf + // trace line against all patches in the leaf for (k = 0; k < leaf->numleafpatches; k++) { patchnum = prv->leafpatches[leaf->firstleafpatch+k]; @@ -5584,6 +5631,7 @@ static void CM_TestInLeaf (cminfo_t *prv, mleaf_t *leaf) if (trace_nearfraction<=0) return; } +#endif } diff --git a/engine/common/log.c b/engine/common/log.c index d89d70a2..ee43ff6d 100644 --- a/engine/common/log.c +++ b/engine/common/log.c @@ -497,9 +497,11 @@ static void IPLog_Identify_f(void) const char *nameorip = Cmd_Argv(1); netadr_t adr, mask; char clean[256]; - //if *, use a mask that includes all ips - if (NET_StringToAdrMasked (nameorip, false, &adr, &mask)) - { //try to parse as an ip + char *endofnum; + strtoul(nameorip, &endofnum, 10); + + if (*endofnum && NET_StringToAdrMasked (nameorip, false, &adr, &mask)) + { //if not a single number, try to parse as an ip //treading carefully here, to avoid dns name lookups weirding everything out. IPLog_Identify(&adr, &mask, "Identity of %s", NET_AdrToStringMasked(clean, sizeof(clean), &adr, &mask)); } diff --git a/engine/common/plugin.c b/engine/common/plugin.c index d2246f93..98e1ff98 100644 --- a/engine/common/plugin.c +++ b/engine/common/plugin.c @@ -876,10 +876,10 @@ typedef struct { struct dl_download *dl; struct { char filename[MAX_QPATH]; - qbyte *buffer; - int buflen; - int curlen; - int curpos; +// qbyte *buffer; +// int buflen; +// int curlen; +// int curpos; } file; } pluginstream_t; pluginstream_t *pluginstreamarray; @@ -903,7 +903,6 @@ static int Plug_NewStreamHandle(plugstream_e type) pluginstreamarray[i].plugin = currentplug; pluginstreamarray[i].type = type; pluginstreamarray[i].socket = -1; - pluginstreamarray[i].file.buffer = NULL; *pluginstreamarray[i].file.filename = '\0'; return i; @@ -1297,7 +1296,7 @@ void Plug_Net_Close_Internal(int handle) if (!pluginstreamarray[handle].vfs->seekingisabadplan && pluginstreamarray[handle].vfs->WriteBytes) { VFS_CLOSE(pluginstreamarray[handle].vfs); - FS_FlushFSHashWritten(); + FS_FlushFSHashWritten(pluginstreamarray[handle].file.filename); } else VFS_CLOSE(pluginstreamarray[handle].vfs); diff --git a/engine/common/pr_common.h b/engine/common/pr_common.h index 11a8fa11..90bd713a 100644 --- a/engine/common/pr_common.h +++ b/engine/common/pr_common.h @@ -4,17 +4,6 @@ extern "C" { #include "progtype.h" #include "progslib.h" -#ifdef CLIENTONLY -typedef struct edict_s { - enum ereftype_e ereftype; - float freetime; // realtime when the object was freed - unsigned int entnum; - unsigned int fieldsize; - pbool readonly; //causes error when QC tries writing to it. (quake's world entity) - void *v; -} edict_t; -#endif - struct wedict_s { enum ereftype_e ereftype; @@ -221,6 +210,7 @@ void QCBUILTIN PF_setattachment(pubprogfuncs_t *prinst, struct globalvars_s *pr_ #define PF_skel_mmap PF_Fixme #define PF_skel_ragedit PF_Fixme #define PF_frameduration PF_Fixme + #define PF_modelframecount PF_Fixme #define PF_frameforname PF_Fixme #define PF_skel_delete PF_Fixme #define PF_skel_copybones PF_Fixme @@ -236,6 +226,10 @@ void QCBUILTIN PF_setattachment(pubprogfuncs_t *prinst, struct globalvars_s *pr_ #define PF_skel_build PF_Fixme #define PF_skel_create PF_Fixme #define PF_skinforname PF_Fixme + + #define PF_processmodelevents PF_Fixme + #define PF_getnextmodelevent PF_Fixme + #define PF_getmodeleventidx PF_Fixme #else void QCBUILTIN PF_skel_set_bone_world (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_skel_mmap(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); @@ -261,11 +255,11 @@ void QCBUILTIN PF_setattachment(pubprogfuncs_t *prinst, struct globalvars_s *pr_ void QCBUILTIN PF_skinforname (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_gettaginfo (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_gettagindex (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); -#endif -void QCBUILTIN PF_processmodelevents (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_getnextmodelevent (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); -void QCBUILTIN PF_getmodeleventidx (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_processmodelevents (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_getnextmodelevent (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); + void QCBUILTIN PF_getmodeleventidx (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); +#endif #if defined(SKELETALOBJECTS) || defined(RAGDOLL) void skel_lookup(world_t *prinst, int skelidx, framestate_t *out); diff --git a/engine/common/world.h b/engine/common/world.h index 463cbe79..733a4b04 100644 --- a/engine/common/world.h +++ b/engine/common/world.h @@ -311,10 +311,10 @@ int VARGS WorldQ2_AreaEdicts (world_t *w, vec3_t mins, vec3_t maxs, q2edict_t ** int maxcount, int areatype); trace_t WorldQ2_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int hitcontentsmask, q2edict_t *passedict); #endif -#ifdef Q2BSPS -unsigned int Q2BSP_FatPVS (model_t *mod, vec3_t org, qbyte *buffer, unsigned int buffersize, qboolean add); -qboolean Q2BSP_EdictInFatPVS(model_t *mod, struct pvscache_s *ent, qbyte *pvs); -void Q2BSP_FindTouchedLeafs(model_t *mod, struct pvscache_s *ent, float *mins, float *maxs); +#if defined(Q2BSPS) || defined(Q3BSPS) +unsigned int Q23BSP_FatPVS (model_t *mod, vec3_t org, qbyte *buffer, unsigned int buffersize, qboolean add); +qboolean Q23BSP_EdictInFatPVS(model_t *mod, struct pvscache_s *ent, qbyte *pvs); +void Q23BSP_FindTouchedLeafs(model_t *mod, struct pvscache_s *ent, float *mins, float *maxs); #endif diff --git a/engine/d3d/d3d11_backend.c b/engine/d3d/d3d11_backend.c index 0c8994c7..db4aa3e8 100644 --- a/engine/d3d/d3d11_backend.c +++ b/engine/d3d/d3d11_backend.c @@ -1602,7 +1602,7 @@ static void tcmod(const tcmod_t *tcmod, int cnt, const float *src, float *dst, c t1 = src[0]; t2 = src[1]; dst[0] = t1 * tcmod->args[0] + t2 * tcmod->args[2] + tcmod->args[4]; - dst[1] = t2 * tcmod->args[1] + t1 * tcmod->args[3] + tcmod->args[5]; + dst[1] = t1 * tcmod->args[1] + t2 * tcmod->args[3] + tcmod->args[5]; } break; diff --git a/engine/d3d/d3d_backend.c b/engine/d3d/d3d_backend.c index e9b0b15a..7c92d916 100644 --- a/engine/d3d/d3d_backend.c +++ b/engine/d3d/d3d_backend.c @@ -671,6 +671,12 @@ void D3D9BE_Init(void) R_InitFlashblends(); } +void D3DBE_Set2D(void) +{ //start of some 2d rendering code. + r_refdef.time = realtime; + shaderstate.curtime = r_refdef.time; +} + static void allocvertexbuffer(IDirect3DVertexBuffer9 *buff, unsigned int bmaxsize, unsigned int *offset, void **data, unsigned int bytes) { unsigned int boff; @@ -770,7 +776,11 @@ static void SelectPassTexture(unsigned int tu, shaderpass_t *pass) FIXME: no code to grab the current screen and convert to a texture break;*/ case T_GEN_VIDEOMAP: +#ifdef NOMEDIA + BindTexture(tu, missing_texture); +#else BindTexture(tu, Media_UpdateForShader(pass->cin)); +#endif break; } @@ -1346,7 +1356,7 @@ static void tcmod(const tcmod_t *tcmod, int cnt, const float *src, float *dst, c t1 = src[0]; t2 = src[1]; dst[0] = t1 * tcmod->args[0] + t2 * tcmod->args[2] + tcmod->args[4]; - dst[1] = t2 * tcmod->args[1] + t1 * tcmod->args[3] + tcmod->args[5]; + dst[1] = t1 * tcmod->args[1] + t2 * tcmod->args[3] + tcmod->args[5]; } break; @@ -1925,6 +1935,7 @@ static void BE_RenderMeshProgram(shader_t *s, unsigned int vertbase, unsigned in program_t *p = s->prog; +#ifdef SKELETALMODELS if (shaderstate.batchvbo && shaderstate.batchvbo->numbones) { if (p->permu[perm|PERMUTATION_SKELETAL].h.loaded) @@ -1932,6 +1943,7 @@ static void BE_RenderMeshProgram(shader_t *s, unsigned int vertbase, unsigned in else return; } +#endif if (TEXVALID(shaderstate.curtexnums->bump) && p->permu[perm|PERMUTATION_BUMPMAP].h.loaded) perm |= PERMUTATION_BUMPMAP; if (TEXVALID(shaderstate.curtexnums->fullbright) && p->permu[perm|PERMUTATION_FULLBRIGHT].h.loaded) @@ -1940,15 +1952,19 @@ static void BE_RenderMeshProgram(shader_t *s, unsigned int vertbase, unsigned in perm |= PERMUTATION_UPPERLOWER; if (r_refdef.globalfog.density && p->permu[perm|PERMUTATION_FOG].h.loaded) perm |= PERMUTATION_FOG; +#ifdef NONSKELETALMODELS if (p->permu[perm|PERMUTATION_FRAMEBLEND].h.loaded && shaderstate.batchvbo && shaderstate.batchvbo->coord2.d3d.buff) { perm |= PERMUTATION_FRAMEBLEND; vdec |= D3D_VDEC_POS2; } +#endif // if (p->permu[perm|PERMUTATION_DELUXE].h.loaded && TEXVALID(shaderstate.curtexnums->bump) && shaderstate.curbatch->lightmap[0] >= 0 && lightmap[shaderstate.curbatch->lightmap[0]]->hasdeluxe) // perm |= PERMUTATION_DELUXE; +#if MAXRLIGHTMAPS > 1 if (shaderstate.curbatch->lightmap[1] >= 0 && p->permu[perm|PERMUTATION_LIGHTSTYLES].h.loaded) perm |= PERMUTATION_LIGHTSTYLES; +#endif BE_ApplyUniforms(p, perm); diff --git a/engine/d3d/d3d_shader.c b/engine/d3d/d3d_shader.c index d0ea3ad3..4111dce6 100644 --- a/engine/d3d/d3d_shader.c +++ b/engine/d3d/d3d_shader.c @@ -359,14 +359,14 @@ static void D3D9Shader_ProgAutoFields(program_t *prog, const char *progname, cva } } - for (i = 0; sh_defaultsamplers[i]; i++) + for (i = 0; sh_defaultsamplers[i].name; i++) { //figure out which ones are needed. - if (prog->defaulttextures & (1u<defaulttextures & sh_defaultsamplers[i].defaulttexbits) continue; //don't spam - uniformloc = D3D9Shader_FindUniform(&pp->h, 2, sh_defaultsamplers[i]); + uniformloc = D3D9Shader_FindUniform(&pp->h, 2, sh_defaultsamplers[i].name); if (uniformloc != -1) - prog->defaulttextures |= (1u<defaulttextures |= sh_defaultsamplers[i].defaulttexbits; } } @@ -385,11 +385,11 @@ static void D3D9Shader_ProgAutoFields(program_t *prog, const char *progname, cva if (!prog->permu[p].h.loaded) continue; sampnum = prog->numsamplers; - for (i = 0; sh_defaultsamplers[i]; i++) + for (i = 0; sh_defaultsamplers[i].name; i++) { - if (prog->defaulttextures & (1u<defaulttextures & sh_defaultsamplers[i].defaulttexbits) { - uniformloc = D3D9Shader_FindUniform(&prog->permu[p].h, 2, sh_defaultsamplers[i]); + uniformloc = D3D9Shader_FindUniform(&prog->permu[p].h, 2, sh_defaultsamplers[i].name); if (uniformloc != -1) { int v[4] = {sampnum}; diff --git a/engine/d3d/vid_d3d.c b/engine/d3d/vid_d3d.c index 3143dcb3..ab727455 100644 --- a/engine/d3d/vid_d3d.c +++ b/engine/d3d/vid_d3d.c @@ -64,7 +64,7 @@ extern qboolean scr_drawloading; extern qboolean scr_con_forcedraw; static qboolean d3d_resized; -cvar_t vid_hardwaregamma; +extern cvar_t vid_hardwaregamma; //sound/error code needs this @@ -895,6 +895,8 @@ void D3D9_Set2D (void) r_refdef.pxrect.y = 0; r_refdef.pxrect.width = vid.fbpwidth; r_refdef.pxrect.height = vid.fbpheight; + + D3DBE_Set2D(); } static int d3d9error(int i) @@ -981,6 +983,8 @@ static qboolean (D3D9_SCR_UpdateScreen) (void) scr_drawloading = true; SCR_DrawLoading (true); scr_drawloading = false; + if (R2D_Flush) + R2D_Flush(); IDirect3DDevice9_EndScene(pD3DDev9); IDirect3DDevice9_Present(pD3DDev9, NULL, NULL, NULL, NULL); return true; diff --git a/engine/dotnet2005/ftequake.vcproj b/engine/dotnet2005/ftequake.vcproj index c45bc830..6cc128fe 100644 --- a/engine/dotnet2005/ftequake.vcproj +++ b/engine/dotnet2005/ftequake.vcproj @@ -662,7 +662,7 @@ light_known = 2; return e->light_known-1; } +#ifdef HEXEN2 if ((e->drawflags & MLS_MASK) == MLS_FULLBRIGHT || (e->flags & Q2RF_FULLBRIGHT)) { e->light_avg[0] = e->light_avg[1] = e->light_avg[2] = 1; @@ -1241,6 +1242,7 @@ qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel) e->light_known = 2; return e->light_known-1; } +#endif if (r_fb_models.ival == 1 && ruleset_allow_fbmodels.ival && (clmodel->engineflags & MDLF_EZQUAKEFBCHEAT) && cls.protocol == CP_QUAKEWORLD && cl.deathmatch) { e->light_avg[0] = e->light_avg[1] = e->light_avg[2] = 1; @@ -1385,11 +1387,13 @@ qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel) shadelight[0] = shadelight[1] = shadelight[2] = ambientlight[0] = ambientlight[1] = ambientlight[2] = 128+sin(cl.servertime*4)*64; } +#ifdef HEXEN2 if ((e->drawflags & MLS_MASK) == MLS_ABSLIGHT) { shadelight[0] = shadelight[1] = shadelight[2] = e->abslight; ambientlight[0] = ambientlight[1] = ambientlight[2] = e->abslight; } +#endif if (e->flags & RF_WEAPONMODEL) { @@ -1571,6 +1575,7 @@ void R_GAlias_GenerateBatches(entity_t *e, batch_t **batches) if (SHADER_SORT_PORTAL < sort && sort < SHADER_SORT_BLEND) sort = SHADER_SORT_BLEND; } +#ifdef HEXEN2 else if (e->drawflags & DRF_TRANSLUCENT) { b->flags |= BEF_FORCETRANSPARENT; @@ -1578,6 +1583,7 @@ void R_GAlias_GenerateBatches(entity_t *e, batch_t **batches) sort = SHADER_SORT_BLEND; e->shaderRGBAf[3] = r_wateralpha.value; } +#endif if (e->flags & RF_NODEPTHTEST) { b->flags |= BEF_FORCENODEPTH; diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index f4f79ef7..85746cd7 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -3448,8 +3448,11 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas else return; } + +#ifdef NONSKELETALMODELS if (p->permu[perm|PERMUTATION_FRAMEBLEND].h.loaded && shaderstate.sourcevbo->coord2.gl.addr) perm |= PERMUTATION_FRAMEBLEND; +#endif if (TEXLOADED(shaderstate.curtexnums->bump) && p->permu[perm|PERMUTATION_BUMPMAP].h.loaded) perm |= PERMUTATION_BUMPMAP; if (TEXLOADED(shaderstate.curtexnums->fullbright) && p->permu[perm|PERMUTATION_FULLBRIGHT].h.loaded) diff --git a/engine/gl/gl_font.c b/engine/gl/gl_font.c index 25ec47f5..3a10c443 100644 --- a/engine/gl/gl_font.c +++ b/engine/gl/gl_font.c @@ -1255,7 +1255,7 @@ struct font_s *Font_LoadFont(float vheight, const char *fontfilename) } } -#ifdef DOOMWADS +#ifdef PACKAGE_DOOMWAD if (!*fontfilename) { unsigned char buf[PLANEWIDTH*PLANEHEIGHT]; diff --git a/engine/gl/gl_heightmap.c b/engine/gl/gl_heightmap.c index f58f0aff..89e0fdc1 100644 --- a/engine/gl/gl_heightmap.c +++ b/engine/gl/gl_heightmap.c @@ -1725,6 +1725,7 @@ static qboolean Terr_SaveSection(heightmap_t *hm, hmsection_t *s, int sx, int sy VFS_SEEK(f, 0); VFS_WRITE(f, &dbh, sizeof(dbh)); VFS_CLOSE(f); + FS_FlushFSHashWritten(fname); } else #endif @@ -1752,6 +1753,7 @@ static qboolean Terr_SaveSection(heightmap_t *hm, hmsection_t *s, int sx, int sy VFS_WRITE(f, &dsh, sizeof(dsh)); Terr_Save(hm, s, f, sx, sy, writever); VFS_CLOSE(f); + FS_FlushFSHashWritten(fname); } return true; #endif @@ -4908,8 +4910,8 @@ void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_g return; case ter_ent_add: { - int idx = G_INT(OFS_PARM1); - const char *news = PR_GetStringOfs(prinst, OFS_PARM2); +// int idx = G_INT(OFS_PARM1); +// const char *news = PR_GetStringOfs(prinst, OFS_PARM2); G_INT(OFS_RETURN) = mod->numentityinfo; } @@ -6959,6 +6961,7 @@ void Mod_Terrain_Save_f(void) const char *s = Mod_GetEntitiesString(mod); VFS_WRITE(file, s, strlen(s)); VFS_CLOSE(file); + FS_FlushFSHashWritten(fname); } } else @@ -6971,9 +6974,9 @@ void Mod_Terrain_Save_f(void) { Terr_WriteMapFile(file, mod); VFS_CLOSE(file); + FS_FlushFSHashWritten(fname); } } - FS_FlushFSHash(); } qboolean Terr_ReformEntitiesLump(model_t *mod, heightmap_t *hm, char *entities) { @@ -7564,7 +7567,7 @@ void Mod_Terrain_Create_f(void) Terr_WriteMapFile(file, &mod); VFS_CLOSE(file); Con_Printf("Wrote %s\n", mname); - FS_FlushFSHashWritten(); + FS_FlushFSHashWritten(mname); } Mod_SetEntitiesString(&mod, NULL, false); Terr_FreeModel(&mod); diff --git a/engine/gl/gl_hlmdl.c b/engine/gl/gl_hlmdl.c index 1f0ced04..991146ae 100644 --- a/engine/gl/gl_hlmdl.c +++ b/engine/gl/gl_hlmdl.c @@ -240,12 +240,12 @@ qboolean QDECL Mod_LoadHLModel (model_t *mod, void *buffer, size_t fsize) int i; int body; struct hlmodelshaders_s *shaders; + hlmdl_tex_t *tex; #endif hlmodel_t *model; hlmdl_header_t *header; hlmdl_header_t *texheader; - hlmdl_tex_t *tex; hlmdl_bone_t *bones; hlmdl_bonecontroller_t *bonectls; void *texmem = NULL; @@ -305,7 +305,6 @@ qboolean QDECL Mod_LoadHLModel (model_t *mod, void *buffer, size_t fsize) else header->numtextures = texheader->numtextures; - tex = (hlmdl_tex_t *) ((qbyte *) texheader + texheader->textures); bones = (hlmdl_bone_t *) ((qbyte *) header + header->boneindex); bonectls = (hlmdl_bonecontroller_t *) ((qbyte *) header + header->controllerindex); @@ -314,6 +313,8 @@ qboolean QDECL Mod_LoadHLModel (model_t *mod, void *buffer, size_t fsize) model->bonectls = bonectls; #ifndef SERVERONLY + tex = (hlmdl_tex_t *) ((qbyte *) texheader + texheader->textures); + shaders = ZG_Malloc(&mod->memgroup, texheader->numtextures*sizeof(shader_t)); model->shaders = shaders; for(i = 0; i < texheader->numtextures; i++) diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index 02b0d126..0374a82b 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -55,7 +55,7 @@ qboolean QDECL Mod_LoadSprite2Model (model_t *mod, void *buffer, size_t fsize); #ifdef Q1BSPS static qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsize); #endif -#ifdef Q2BSPS +#if defined(Q2BSPS) || defined(Q3BSPS) qboolean QDECL Mod_LoadQ2BrushModel (model_t *mod, void *buffer, size_t fsize); #endif model_t *Mod_LoadModel (model_t *mod, enum mlverbosity_e verbose); @@ -264,7 +264,7 @@ static void Mod_BlockTextureColour_f (void) #endif -#if defined(RUNTIMELIGHTING) +#ifdef RUNTIMELIGHTING #if defined(MULTITHREAD) static void *relightthread[8]; static unsigned int relightthreads; @@ -291,9 +291,10 @@ static int RelightThread(void *arg) free(threadctx); return 0; } -#endif +#else static void *lightmainthreadctx; #endif +#endif void Mod_Think (void) { @@ -746,10 +747,10 @@ void Mod_Init (qboolean initial) #endif //q2/q3bsps -#ifdef Q2BSPS - Mod_RegisterModelFormatMagic(NULL, "Quake2/Quake2 Map (bsp)", IDBSPHEADER, Mod_LoadQ2BrushModel); +#if defined(Q2BSPS) || defined(Q3BSPS) + Mod_RegisterModelFormatMagic(NULL, "Quake2/Quake3 Map (bsp)", IDBSPHEADER, Mod_LoadQ2BrushModel); #endif -#ifdef Q3BSPS +#ifdef RFBSPS Mod_RegisterModelFormatMagic(NULL, "Raven Map (bsp)", ('R'<<0)+('B'<<8)+('S'<<16)+('P'<<24), Mod_LoadQ2BrushModel); Mod_RegisterModelFormatMagic(NULL, "QFusion Map (bsp)", ('F'<<0)+('B'<<8)+('S'<<16)+('P'<<24), Mod_LoadQ2BrushModel); #endif @@ -1394,7 +1395,8 @@ model_t *Mod_ForName (const char *name, enum mlverbosity_e verbosity) =============================================================================== */ -#ifndef SERVERONLY + +#if !defined(SERVERONLY) static const struct { const char *oldname; @@ -1442,9 +1444,7 @@ static const char *Mod_RemapBuggyTexture(const char *name, const qbyte *data, un } return NULL; } -#endif -#ifndef SERVERONLY static void Mod_FinishTexture(texture_t *tx, const char *loadname, qboolean safetoloadfromwads) { extern cvar_t gl_shadeq1_name; @@ -1528,235 +1528,12 @@ static void Mod_FinishTexture(texture_t *tx, const char *loadname, qboolean safe } BZ_Free(tx->mips[0]); } -static void Mod_LoadMiptex(model_t *loadmodel, texture_t *tx, miptex_t *mt) -{ - unsigned int size = - (mt->width>>0)*(mt->height>>0) + - (mt->width>>1)*(mt->height>>1) + - (mt->width>>2)*(mt->height>>2) + - (mt->width>>3)*(mt->height>>3); - - if (loadmodel->fromgame == fg_halflife && *(short*)((qbyte *)mt + mt->offsets[3] + (mt->width>>3)*(mt->height>>3)) == 256) - { //mostly identical, just a specific palette hidden at the end. handle fences elsewhere. - tx->mips[0] = BZ_Malloc(size + 768); - tx->palette = tx->mips[0] + size; - memcpy(tx->palette, (qbyte *)mt + mt->offsets[3] + (mt->width>>3)*(mt->height>>3) + 2, 768); - } - else - { - tx->mips[0] = BZ_Malloc(size); - tx->palette = NULL; - } - - tx->mips[1] = tx->mips[0] + (mt->width>>0)*(mt->height>>0); - tx->mips[2] = tx->mips[1] + (mt->width>>1)*(mt->height>>1); - tx->mips[3] = tx->mips[2] + (mt->width>>2)*(mt->height>>2); - memcpy(tx->mips[0], (qbyte *)mt + mt->offsets[0], (mt->width>>0)*(mt->height>>0)); - memcpy(tx->mips[1], (qbyte *)mt + mt->offsets[1], (mt->width>>1)*(mt->height>>1)); - memcpy(tx->mips[2], (qbyte *)mt + mt->offsets[2], (mt->width>>2)*(mt->height>>2)); - memcpy(tx->mips[3], (qbyte *)mt + mt->offsets[3], (mt->width>>3)*(mt->height>>3)); - -} #endif -/* -================= -Mod_LoadTextures -================= -*/ -static qboolean Mod_LoadTextures (model_t *loadmodel, qbyte *mod_base, lump_t *l) -{ - int i, j, num, max, altmax; - miptex_t *mt; - texture_t *tx, *tx2; - texture_t *anims[10]; - texture_t *altanims[10]; - dmiptexlump_t *m; - -TRACE(("dbg: Mod_LoadTextures: inittexturedescs\n")); - -// Mod_InitTextureDescs(loadname); - - if (!l->filelen) - { - Con_Printf(CON_WARNING "warning: %s contains no texture data\n", loadmodel->name); - - loadmodel->numtextures = 1; - loadmodel->textures = ZG_Malloc(&loadmodel->memgroup, 1 * sizeof(*loadmodel->textures)); - - i = 0; - tx = ZG_Malloc(&loadmodel->memgroup, sizeof(texture_t)); - memcpy(tx, r_notexture_mip, sizeof(texture_t)); - sprintf(tx->name, "unnamed%i", i); - loadmodel->textures[i] = tx; - - return true; - } - m = (dmiptexlump_t *)(mod_base + l->fileofs); - - m->nummiptex = LittleLong (m->nummiptex); - - loadmodel->numtextures = m->nummiptex; - loadmodel->textures = ZG_Malloc(&loadmodel->memgroup, m->nummiptex * sizeof(*loadmodel->textures)); - - for (i=0 ; inummiptex ; i++) - { - m->dataofs[i] = LittleLong(m->dataofs[i]); - if (m->dataofs[i] == -1) //e1m2, this happens - { - tx = ZG_Malloc(&loadmodel->memgroup, sizeof(texture_t)); - memcpy(tx, r_notexture_mip, sizeof(texture_t)); - sprintf(tx->name, "unnamed%i", i); - loadmodel->textures[i] = tx; - continue; - } - mt = (miptex_t *)((qbyte *)m + m->dataofs[i]); - - TRACE(("dbg: Mod_LoadTextures: texture %s\n", loadname)); - - if (!*mt->name) //I HATE MAPPERS! - { - sprintf(mt->name, "unnamed%i", i); - Con_DPrintf(CON_WARNING "warning: unnamed texture in %s, renaming to %s\n", loadmodel->name, mt->name); - } - - mt->width = LittleLong (mt->width); - mt->height = LittleLong (mt->height); - for (j=0 ; joffsets[j] = LittleLong (mt->offsets[j]); - - if ( (mt->width & 15) || (mt->height & 15) ) - Con_Printf (CON_WARNING "Warning: Texture %s is not 16 aligned", mt->name); - if (mt->width < 1 || mt->height < 1) - Con_Printf (CON_WARNING "Warning: Texture %s has no size", mt->name); - tx = ZG_Malloc(&loadmodel->memgroup, sizeof(texture_t)); - loadmodel->textures[i] = tx; - - memcpy (tx->name, mt->name, sizeof(tx->name)); - tx->width = mt->width; - tx->height = mt->height; - - if (!mt->offsets[0]) //this is a hl external style texture, load it a little later (from a wad) - { - continue; - } - -#ifndef SERVERONLY - Mod_LoadMiptex(loadmodel, tx, mt); -#endif - } -// -// sequence the animations -// - for (i=0 ; inummiptex ; i++) - { - tx = loadmodel->textures[i]; - if (!tx || tx->name[0] != '+') - continue; - if (tx->anim_next) - continue; // already sequenced - - // find the number of frames in the animation - memset (anims, 0, sizeof(anims)); - memset (altanims, 0, sizeof(altanims)); - - max = tx->name[1]; - altmax = 0; - if (max >= 'a' && max <= 'z') - max -= 'a' - 'A'; - if (max >= '0' && max <= '9') - { - max -= '0'; - altmax = 0; - anims[max] = tx; - max++; - } - else if (max >= 'A' && max <= 'J') - { - altmax = max - 'A'; - max = 0; - altanims[altmax] = tx; - altmax++; - } - else - { - Con_Printf (CON_ERROR "Bad animating texture %s\n", tx->name); - return false; - } - - for (j=i+1 ; jnummiptex ; j++) - { - tx2 = loadmodel->textures[j]; - if (!tx2 || tx2->name[0] != '+') - continue; - if (strcmp (tx2->name+2, tx->name+2)) - continue; - - num = tx2->name[1]; - if (num >= 'a' && num <= 'z') - num -= 'a' - 'A'; - if (num >= '0' && num <= '9') - { - num -= '0'; - anims[num] = tx2; - if (num+1 > max) - max = num + 1; - } - else if (num >= 'A' && num <= 'J') - { - num = num - 'A'; - altanims[num] = tx2; - if (num+1 > altmax) - altmax = num+1; - } - else - { - Con_Printf (CON_ERROR "Bad animating texture %s\n", tx->name); - return false; - } - } - -#define ANIM_CYCLE 2 - // link them all together - for (j=0 ; jname); - return false; - } - tx2->anim_total = max * ANIM_CYCLE; - tx2->anim_min = j * ANIM_CYCLE; - tx2->anim_max = (j+1) * ANIM_CYCLE; - tx2->anim_next = anims[ (j+1)%max ]; - if (altmax) - tx2->alternate_anims = altanims[0]; - } - for (j=0 ; jname); - return false; - } - tx2->anim_total = altmax * ANIM_CYCLE; - tx2->anim_min = j * ANIM_CYCLE; - tx2->anim_max = (j+1) * ANIM_CYCLE; - tx2->anim_next = altanims[ (j+1)%altmax ]; - if (max) - tx2->alternate_anims = anims[0]; - } - } - - return true; -} - void Mod_NowLoadExternal(model_t *loadmodel) { //for halflife bsps where wads are loaded after the map. -#ifndef SERVERONLY +#if !defined(SERVERONLY) int i; texture_t *tx; char loadname[32]; @@ -2224,27 +2001,6 @@ void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean #endif } -/* -================= -Mod_LoadVisibility -================= -*/ -static void Mod_LoadVisibility (model_t *loadmodel, qbyte *mod_base, lump_t *l, qbyte *ptr, size_t len) -{ - if (!ptr) - { - ptr = mod_base + l->fileofs; - len = l->filelen; - } - if (!len) - { - loadmodel->visdata = NULL; - return; - } - loadmodel->visdata = ZG_Malloc(&loadmodel->memgroup, len); - memcpy (loadmodel->visdata, ptr, len); -} - //scans through the worldspawn for a single specific key. const char *Mod_ParseWorldspawnKey(model_t *mod, const char *key, char *buffer, size_t sizeofbuffer) { @@ -2462,6 +2218,1194 @@ qboolean Mod_LoadVertexNormals (model_t *loadmodel, qbyte *mod_base, lump_t *l) return true; } +#if defined(Q1BSPS) || defined(Q2BSPS) +void ModQ1_Batches_BuildQ1Q2Poly(model_t *mod, msurface_t *surf, builddata_t *cookie) +{ + unsigned int vertidx; + int i, lindex, edgevert; + mesh_t *mesh = surf->mesh; + float *vec; + float s, t, d; + int sty; +// int w,h; + + if (!mesh) + { + mesh = surf->mesh = ZG_Malloc(&mod->memgroup, sizeof(mesh_t) + (sizeof(vecV_t)+sizeof(vec2_t)*(1+1)+sizeof(vec3_t)*3+sizeof(vec4_t)*1)* surf->numedges + sizeof(index_t)*(surf->numedges-2)*3); + mesh->numvertexes = surf->numedges; + mesh->numindexes = (mesh->numvertexes-2)*3; + mesh->xyz_array = (vecV_t*)(mesh+1); + mesh->st_array = (vec2_t*)(mesh->xyz_array+mesh->numvertexes); + mesh->lmst_array[0] = (vec2_t*)(mesh->st_array+mesh->numvertexes); + mesh->normals_array = (vec3_t*)(mesh->lmst_array[0]+mesh->numvertexes); + mesh->snormals_array = (vec3_t*)(mesh->normals_array+mesh->numvertexes); + mesh->tnormals_array = (vec3_t*)(mesh->snormals_array+mesh->numvertexes); + mesh->colors4f_array[0] = (vec4_t*)(mesh->tnormals_array+mesh->numvertexes); + mesh->indexes = (index_t*)(mesh->colors4f_array[0]+mesh->numvertexes); + } + mesh->istrifan = true; + + //output the mesh's indicies + for (i=0 ; inumvertexes-2 ; i++) + { + mesh->indexes[i*3] = 0; + mesh->indexes[i*3+1] = i+1; + mesh->indexes[i*3+2] = i+2; + } + //output the renderable verticies + for (i=0 ; inumvertexes ; i++) + { + lindex = mod->surfedges[surf->firstedge + i]; + edgevert = lindex <= 0; + if (edgevert) + lindex = -lindex; + if (lindex < 0 || lindex >= mod->numedges) + vertidx = 0; + else + vertidx = mod->edges[lindex].v[edgevert]; + vec = mod->vertexes[vertidx].position; + + s = DotProduct (vec, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3]; + t = DotProduct (vec, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3]; + + VectorCopy (vec, mesh->xyz_array[i]); + +/* if (R_GetShaderSizes(surf->texinfo->texture->shader, &w, &h, false) > 0) + { + mesh->st_array[i][0] = s/w; + mesh->st_array[i][1] = t/h; + } + else +*/ + { + mesh->st_array[i][0] = s; + mesh->st_array[i][1] = t; + if (surf->texinfo->texture->width) + mesh->st_array[i][0] /= surf->texinfo->texture->width; + if (surf->texinfo->texture->height) + mesh->st_array[i][1] /= surf->texinfo->texture->height; + } + +#ifndef SERVERONLY + if (gl_lightmap_average.ival) + { + for (sty = 0; sty < 1; sty++) + { + mesh->lmst_array[sty][i][0] = (surf->extents[0]*0.5 + (surf->light_s[sty]<lmshift) + (1<lmshift)*0.5) / (mod->lightmaps.width<lmshift); + mesh->lmst_array[sty][i][1] = (surf->extents[1]*0.5 + (surf->light_t[sty]<lmshift) + (1<lmshift)*0.5) / (mod->lightmaps.height<lmshift); + } + } + else +#endif + { + for (sty = 0; sty < 1; sty++) + { + mesh->lmst_array[sty][i][0] = (s - surf->texturemins[0] + (surf->light_s[sty]<lmshift) + (1<lmshift)*0.5) / (mod->lightmaps.width<lmshift); + mesh->lmst_array[sty][i][1] = (t - surf->texturemins[1] + (surf->light_t[sty]<lmshift) + (1<lmshift)*0.5) / (mod->lightmaps.height<lmshift); + } + } + + //figure out the texture directions, for bumpmapping and stuff + if (mod->normals && (surf->texinfo->flags & 0x800) && (mod->normals[vertidx][0] || mod->normals[vertidx][1] || mod->normals[vertidx][2])) + { + //per-vertex normals - used for smoothing groups and stuff. + VectorCopy(mod->normals[vertidx], mesh->normals_array[i]); + } + else + { + if (surf->flags & SURF_PLANEBACK) + VectorNegate(surf->plane->normal, mesh->normals_array[i]); + else + VectorCopy(surf->plane->normal, mesh->normals_array[i]); + } + VectorCopy(surf->texinfo->vecs[0], mesh->snormals_array[i]); + VectorNegate(surf->texinfo->vecs[1], mesh->tnormals_array[i]); + //the s+t vectors are axis-aligned, so fiddle them so they're normal aligned instead + d = -DotProduct(mesh->normals_array[i], mesh->snormals_array[i]); + VectorMA(mesh->snormals_array[i], d, mesh->normals_array[i], mesh->snormals_array[i]); + d = -DotProduct(mesh->normals_array[i], mesh->tnormals_array[i]); + VectorMA(mesh->tnormals_array[i], d, mesh->normals_array[i], mesh->tnormals_array[i]); + VectorNormalize(mesh->snormals_array[i]); + VectorNormalize(mesh->tnormals_array[i]); + + //q1bsp has no colour information (fixme: sample from the lightmap?) + for (sty = 0; sty < 1; sty++) + { + mesh->colors4f_array[sty][i][0] = 1; + mesh->colors4f_array[sty][i][1] = 1; + mesh->colors4f_array[sty][i][2] = 1; + mesh->colors4f_array[sty][i][3] = 1; + } + } +} +#endif + +#ifndef SERVERONLY +static void Mod_Batches_BuildModelMeshes(model_t *mod, int maxverts, int maxindicies, void (*build)(model_t *mod, msurface_t *surf, builddata_t *bd), builddata_t *bd, int lmmerge) +{ + batch_t *batch; + msurface_t *surf; + mesh_t *mesh; + int numverts = 0; + int numindicies = 0; + int j, i; + int sortid; + int sty; + vbo_t vbo; + int styles = mod->lightmaps.surfstyles; + char *ptr; + + memset(&vbo, 0, sizeof(vbo)); + vbo.indicies.sysptr = ZG_Malloc(&mod->memgroup, sizeof(index_t) * maxindicies); + ptr = ZG_Malloc(&mod->memgroup, (sizeof(vecV_t)+sizeof(vec2_t)*(1+styles)+sizeof(vec3_t)*3+sizeof(vec4_t)*styles)* maxverts); + + vbo.coord.sysptr = ptr; + ptr += sizeof(vecV_t)*maxverts; + for (sty = 0; sty < styles; sty++) + { + vbo.colours[sty].sysptr = ptr; + ptr += sizeof(vec4_t)*maxverts; + } + for (; sty < MAXRLIGHTMAPS; sty++) + vbo.colours[sty].sysptr = NULL; + vbo.texcoord.sysptr = ptr; + ptr += sizeof(vec2_t)*maxverts; + sty = 0; + for (; sty < styles; sty++) + { + vbo.lmcoord[sty].sysptr = ptr; + ptr += sizeof(vec2_t)*maxverts; + } + for (; sty < MAXRLIGHTMAPS; sty++) + vbo.lmcoord[sty].sysptr = NULL; + vbo.normals.sysptr = ptr; + ptr += sizeof(vec3_t)*maxverts; + vbo.svector.sysptr = ptr; + ptr += sizeof(vec3_t)*maxverts; + vbo.tvector.sysptr = ptr; + ptr += sizeof(vec3_t)*maxverts; + + numindicies = 0; + numverts = 0; + + //build each mesh + for (sortid=0; sortidbatches[sortid]; batch; batch = batch->next) + { + for (j = 0; j < batch->maxmeshes; j++) + { + surf = (msurface_t*)batch->mesh[j]; + mesh = surf->mesh; + batch->mesh[j] = mesh; + + mesh->vbofirstvert = numverts; + mesh->vbofirstelement = numindicies; + numverts += mesh->numvertexes; + numindicies += mesh->numindexes; + + //set up the arrays. the arrangement is required for the backend to optimise vbos + mesh->xyz_array = (vecV_t*)vbo.coord.sysptr + mesh->vbofirstvert; + mesh->st_array = (vec2_t*)vbo.texcoord.sysptr + mesh->vbofirstvert; + for (sty = 0; sty < MAXRLIGHTMAPS; sty++) + { + if (vbo.lmcoord[sty].sysptr) + mesh->lmst_array[sty] = (vec2_t*)vbo.lmcoord[sty].sysptr + mesh->vbofirstvert; + else + mesh->lmst_array[sty] = NULL; + if (vbo.colours[sty].sysptr) + mesh->colors4f_array[sty] = (vec4_t*)vbo.colours[sty].sysptr + mesh->vbofirstvert; + else + mesh->colors4f_array[sty] = NULL; + } + mesh->normals_array = (vec3_t*)vbo.normals.sysptr + mesh->vbofirstvert; + mesh->snormals_array = (vec3_t*)vbo.svector.sysptr + mesh->vbofirstvert; + mesh->tnormals_array = (vec3_t*)vbo.tvector.sysptr + mesh->vbofirstvert; + mesh->indexes = (index_t*)vbo.indicies.sysptr + mesh->vbofirstelement; + + mesh->vbofirstvert = 0; + mesh->vbofirstelement = 0; + + build(mod, surf, bd); + + if (lmmerge != 1) + for (sty = 0; sty < MAXRLIGHTMAPS; sty++) + { + if (surf->lightmaptexturenums[sty] >= 0) + { + if (mesh->lmst_array[sty]) + { + for (i = 0; i < mesh->numvertexes; i++) + { + mesh->lmst_array[sty][i][1] += surf->lightmaptexturenums[sty] % lmmerge; + mesh->lmst_array[sty][i][1] /= lmmerge; + } + } + surf->lightmaptexturenums[sty] /= lmmerge; + } + } + } + batch->meshes = 0; + batch->firstmesh = 0; + } + } +} + +#ifdef Q1BSPS +//q1 autoanimates. if the frame is set, it uses the alternate animation. +static void Mod_UpdateBatchShader_Q1 (struct batch_s *batch) +{ + texture_t *base = batch->texture; + int reletive; + int count; + + if (batch->ent->framestate.g[FS_REG].frame[0]) + { + if (base->alternate_anims) + base = base->alternate_anims; + } + + if (base->anim_total) + { + reletive = (int)(cl.time*10) % base->anim_total; + + count = 0; + while (base->anim_min > reletive || base->anim_max <= reletive) + { + base = base->anim_next; + if (!base) + Sys_Error ("R_TextureAnimation: broken cycle"); + if (++count > 100) + Sys_Error ("R_TextureAnimation: infinite cycle"); + } + } + + batch->shader = base->shader; +} +#endif + +#ifdef Q2BSPS +//q2 has direct control over the texture frames used, but typically has the client generate the frame (different flags autogenerate different ranges). +static void Mod_UpdateBatchShader_Q2 (struct batch_s *batch) +{ + texture_t *base = batch->texture; + int reletive; + int frame = batch->ent->framestate.g[FS_REG].frame[0]; + if (batch->ent == &r_worldentity) + frame = cl.time*2; + + if (base->anim_total) + { + reletive = frame % base->anim_total; + while (reletive --> 0) + { + base = base->anim_next; + if (!base) + Sys_Error ("R_TextureAnimation: broken cycle"); + } + } + + batch->shader = base->shader; +} +#endif + +#define lmmerge(i) ((i>=0)?i/merge:i) +/* +batch->firstmesh is set only in and for this function, its cleared out elsewhere +*/ +static int Mod_Batches_Generate(model_t *mod) +{ + int i; + msurface_t *surf; + shader_t *shader; + int sortid; + batch_t *batch, *lbatch = NULL; + vec4_t plane; + + int merge = mod->lightmaps.merge; + if (!merge) + merge = 1; + + mod->lightmaps.count = (mod->lightmaps.count+merge-1) & ~(merge-1); + mod->lightmaps.count /= merge; + mod->lightmaps.height *= merge; + + mod->numbatches = 0; + + //for each surface, find a suitable batch to insert it into. + //we use 'firstmesh' to avoid chucking out too many verts in a single vbo (gl2 hardware tends to have a 16bit limit) + for (i=0; inummodelsurfaces; i++) + { + surf = mod->surfaces + mod->firstmodelsurface + i; + shader = surf->texinfo->texture->shader; + + if (surf->flags & SURF_NODRAW) + { + shader = R_RegisterShader("nodraw", SUF_NONE, "{\nsurfaceparm nodraw\n}"); + sortid = shader->sort; + VectorClear(plane); + plane[3] = 0; + } + else if (shader) + { + sortid = shader->sort; + + //shaders that are portals need to be split into separate batches to have the same surface planes + if (sortid == SHADER_SORT_PORTAL || (shader->flags & (SHADER_HASREFLECT | SHADER_HASREFRACT))) + { + if (surf->flags & SURF_PLANEBACK) + { + VectorNegate(surf->plane->normal, plane); + plane[3] = -surf->plane->dist; + } + else + { + VectorCopy(surf->plane->normal, plane); + plane[3] = surf->plane->dist; + } + } + else + { + VectorClear(plane); + plane[3] = 0; + } + } + else + { + sortid = SHADER_SORT_OPAQUE; + VectorClear(plane); + plane[3] = 0; + } + + if (lbatch && ( + lbatch->texture == surf->texinfo->texture && + lbatch->shader == shader && + lbatch->lightmap[0] == lmmerge(surf->lightmaptexturenums[0]) && + Vector4Compare(plane, lbatch->plane) && + lbatch->firstmesh + surf->mesh->numvertexes <= MAX_INDICIES) && +#if MAXRLIGHTMAPS > 1 + lbatch->lightmap[1] == lmmerge(surf->lightmaptexturenums[1]) && + lbatch->lightmap[2] == lmmerge(surf->lightmaptexturenums[2]) && + lbatch->lightmap[3] == lmmerge(surf->lightmaptexturenums[3]) && +#endif + lbatch->fog == surf->fog) + batch = lbatch; + else + { + for (batch = mod->batches[sortid]; batch; batch = batch->next) + { + if ( + batch->texture == surf->texinfo->texture && + batch->shader == shader && + batch->lightmap[0] == lmmerge(surf->lightmaptexturenums[0]) && + Vector4Compare(plane, batch->plane) && + batch->firstmesh + surf->mesh->numvertexes <= MAX_INDICIES && +#if MAXRLIGHTMAPS > 1 + batch->lightmap[1] == lmmerge(surf->lightmaptexturenums[1]) && + batch->lightmap[2] == lmmerge(surf->lightmaptexturenums[2]) && + batch->lightmap[3] == lmmerge(surf->lightmaptexturenums[3]) && +#endif + batch->fog == surf->fog) + break; + } + } + if (!batch) + { + batch = ZG_Malloc(&mod->memgroup, sizeof(*batch)); + batch->lightmap[0] = lmmerge(surf->lightmaptexturenums[0]); +#if MAXRLIGHTMAPS > 1 + batch->lightmap[1] = lmmerge(surf->lightmaptexturenums[1]); + batch->lightmap[2] = lmmerge(surf->lightmaptexturenums[2]); + batch->lightmap[3] = lmmerge(surf->lightmaptexturenums[3]); +#endif + batch->texture = surf->texinfo->texture; + batch->shader = shader; + if (surf->texinfo->texture->alternate_anims || surf->texinfo->texture->anim_total) + { + switch (mod->fromgame) + { +#ifdef Q2BSPS + case fg_quake2: + batch->buildmeshes = Mod_UpdateBatchShader_Q2; + break; +#endif +#ifdef Q1BSPS + case fg_quake: + case fg_halflife: + batch->buildmeshes = Mod_UpdateBatchShader_Q1; + break; +#endif + default: + break; + } + } + batch->next = mod->batches[sortid]; + batch->ent = &r_worldentity; + batch->fog = surf->fog; + Vector4Copy(plane, batch->plane); + + mod->batches[sortid] = batch; + } + + surf->sbatch = batch; //let the surface know which batch its in + batch->maxmeshes++; + batch->firstmesh += surf->mesh->numvertexes; + + lbatch = batch; + } + + return merge; +#undef lmmerge +} + +void Mod_LightmapAllocInit(lmalloc_t *lmallocator, qboolean hasdeluxe, unsigned int width, unsigned int height, int firstlm) +{ + memset(lmallocator, 0, sizeof(*lmallocator)); + lmallocator->deluxe = hasdeluxe; + lmallocator->lmnum = firstlm; + lmallocator->firstlm = firstlm; + + lmallocator->width = width; + lmallocator->height = height; +} +void Mod_LightmapAllocDone(lmalloc_t *lmallocator, model_t *mod) +{ + mod->lightmaps.first = lmallocator->firstlm; + mod->lightmaps.count = (lmallocator->lmnum - lmallocator->firstlm); + if (lmallocator->allocated[0]) //lmnum was only *COMPLETE* lightmaps that we allocated, and does not include the one we're currently building. + mod->lightmaps.count++; + + if (lmallocator->deluxe) + { + mod->lightmaps.first*=2; + mod->lightmaps.count*=2; + mod->lightmaps.deluxemapping = true; + } + else + mod->lightmaps.deluxemapping = false; +} +void Mod_LightmapAllocBlock(lmalloc_t *lmallocator, int w, int h, unsigned short *x, unsigned short *y, int *tnum) +{ + int best, best2; + int i, j; + + for(;;) + { + best = lmallocator->height; + + for (i = 0; i <= lmallocator->width - w; i++) + { + best2 = 0; + + for (j=0; j < w; j++) + { + if (lmallocator->allocated[i+j] >= best) + break; + if (lmallocator->allocated[i+j] > best2) + best2 = lmallocator->allocated[i+j]; + } + if (j == w) + { // this is a valid spot + *x = i; + *y = best = best2; + } + } + + if (best + h > lmallocator->height) + { + memset(lmallocator->allocated, 0, sizeof(lmallocator->allocated)); + lmallocator->lmnum++; + continue; + } + + for (i=0; i < w; i++) + lmallocator->allocated[*x + i] = best + h; + + if (lmallocator->deluxe) + *tnum = lmallocator->lmnum*2; + else + *tnum = lmallocator->lmnum; + break; + } +} + +#ifdef Q3BSPS +static void Mod_Batches_SplitLightmaps(model_t *mod, int lmmerge) +{ + batch_t *batch; + batch_t *nb; + int i, j, sortid; + msurface_t *surf; + int sty; + + for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++) + for (batch = mod->batches[sortid]; batch != NULL; batch = batch->next) + { + surf = (msurface_t*)batch->mesh[0]; + for (sty = 0; sty < MAXRLIGHTMAPS; sty++) + { + batch->lightmap[sty] = (surf->lightmaptexturenums[sty]>=0)?surf->lightmaptexturenums[sty]/lmmerge:surf->lightmaptexturenums[sty]; + batch->lmlightstyle[sty] = surf->styles[sty]; + } + + for (j = 1; j < batch->maxmeshes; j++) + { + surf = (msurface_t*)batch->mesh[j]; + for (sty = 0; sty < MAXRLIGHTMAPS; sty++) + { + int lm = (surf->lightmaptexturenums[sty]>=0)?surf->lightmaptexturenums[sty]/lmmerge:surf->lightmaptexturenums[sty]; + if (lm != batch->lightmap[sty] || + //fixme: we should merge later (reverted matching) surfaces into the prior batch + surf->styles[sty] != batch->lmlightstyle[sty] || + surf->vlstyles[sty] != batch->vtlightstyle[sty]) + break; + } + if (sty < MAXRLIGHTMAPS) + { + nb = ZG_Malloc(&mod->memgroup, sizeof(*batch)); + *nb = *batch; + batch->next = nb; + + nb->mesh = batch->mesh + j*2; + nb->maxmeshes = batch->maxmeshes - j; + batch->maxmeshes = j; + for (sty = 0; sty < MAXRLIGHTMAPS; sty++) + { + int lm = (surf->lightmaptexturenums[sty]>=0)?surf->lightmaptexturenums[sty]/lmmerge:surf->lightmaptexturenums[sty]; + nb->lightmap[sty] = lm; + nb->lmlightstyle[sty] = surf->styles[sty]; + nb->vtlightstyle[sty] = surf->vlstyles[sty]; + } + + memmove(nb->mesh, batch->mesh+j, sizeof(msurface_t*)*nb->maxmeshes); + + for (i = 0; i < nb->maxmeshes; i++) + { + surf = (msurface_t*)nb->mesh[i]; + surf->sbatch = nb; + } + + batch = nb; + j = 1; + } + } + } +} +#endif + +#if defined(Q1BSPS) || defined(Q2BSPS) +static void Mod_LightmapAllocSurf(lmalloc_t *lmallocator, msurface_t *surf, int surfstyle) +{ + int smax, tmax; + smax = (surf->extents[0]>>surf->lmshift)+1; + tmax = (surf->extents[1]>>surf->lmshift)+1; + + if (isDedicated || + (surf->texinfo->texture->shader && !(surf->texinfo->texture->shader->flags & SHADER_HASLIGHTMAP)) || //fte + (surf->flags & (SURF_DRAWSKY|SURF_DRAWTURB)) || //q1 + (surf->texinfo->flags & TEX_SPECIAL) || //the original 'no lightmap' + (surf->texinfo->flags & (TI_SKY|TI_TRANS33|TI_TRANS66|TI_WARP)) || //q2 surfaces + smax > lmallocator->width || tmax > lmallocator->height || smax < 0 || tmax < 0) //bugs/bounds/etc + { + surf->lightmaptexturenums[surfstyle] = -1; + return; + } + + Mod_LightmapAllocBlock (lmallocator, smax, tmax, &surf->light_s[surfstyle], &surf->light_t[surfstyle], &surf->lightmaptexturenums[surfstyle]); +} + +/* +allocates lightmaps and splits batches upon lightmap boundaries +*/ +static void Mod_Batches_AllocLightmaps(model_t *mod) +{ + batch_t *batch; + batch_t *nb; + lmalloc_t lmallocator; + int i, j, sortid; + msurface_t *surf; + int sty; + + size_t samps = 0; + + //small models don't have many surfaces, don't allocate a smegging huge lightmap that simply won't be used. + for (i=0, j=0; inummodelsurfaces; i++) + { + surf = mod->surfaces + mod->firstmodelsurface + i; + if (surf->texinfo->flags & TEX_SPECIAL) + continue; //surfaces with no lightmap should not count torwards anything. + samps += ((surf->extents[0]>>surf->lmshift)+1) * ((surf->extents[1]>>surf->lmshift)+1); + + if (j < (surf->extents[0]>>surf->lmshift)+1) + j = (surf->extents[0]>>surf->lmshift)+1; + if (j < (surf->extents[1]>>surf->lmshift)+1) + j = (surf->extents[1]>>surf->lmshift)+1; + } + samps /= 4; + samps = sqrt(samps); + if (j > 128 || r_dynamic.ival <= 0) + samps *= 2; + mod->lightmaps.width = bound(j, samps, LMBLOCK_SIZE_MAX); + mod->lightmaps.height = bound(j, samps, LMBLOCK_SIZE_MAX); + for (i = 0; (1<lightmaps.width; i++); + mod->lightmaps.width = 1<lightmaps.height; i++); + mod->lightmaps.height = 1<lightmaps.width = bound(64, mod->lightmaps.width, sh_config.texture_maxsize); + mod->lightmaps.height = bound(64, mod->lightmaps.height, sh_config.texture_maxsize); + + Mod_LightmapAllocInit(&lmallocator, mod->deluxdata != NULL, mod->lightmaps.width, mod->lightmaps.height, 0x50); + + for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++) + for (batch = mod->batches[sortid]; batch != NULL; batch = batch->next) + { + surf = (msurface_t*)batch->mesh[0]; + Mod_LightmapAllocSurf (&lmallocator, surf, 0); + for (sty = 1; sty < MAXRLIGHTMAPS; sty++) + surf->lightmaptexturenums[sty] = -1; + for (sty = 0; sty < MAXRLIGHTMAPS; sty++) + { + batch->lightmap[sty] = surf->lightmaptexturenums[sty]; + batch->lmlightstyle[sty] = 255;//don't do special backend rendering of lightstyles. + batch->vtlightstyle[sty] = 255;//don't do special backend rendering of lightstyles. + } + + for (j = 1; j < batch->maxmeshes; j++) + { + surf = (msurface_t*)batch->mesh[j]; + Mod_LightmapAllocSurf (&lmallocator, surf, 0); + for (sty = 1; sty < MAXRLIGHTMAPS; sty++) + surf->lightmaptexturenums[sty] = -1; + if (surf->lightmaptexturenums[0] != batch->lightmap[0]) + { + nb = ZG_Malloc(&mod->memgroup, sizeof(*batch)); + *nb = *batch; + batch->next = nb; + + nb->mesh = batch->mesh + j*2; + nb->maxmeshes = batch->maxmeshes - j; + batch->maxmeshes = j; + for (sty = 0; sty < MAXRLIGHTMAPS; sty++) + nb->lightmap[sty] = surf->lightmaptexturenums[sty]; + + memmove(nb->mesh, batch->mesh+j, sizeof(msurface_t*)*nb->maxmeshes); + + for (i = 0; i < nb->maxmeshes; i++) + { + surf = (msurface_t*)nb->mesh[i]; + surf->sbatch = nb; + } + + batch = nb; + j = 0; + } + } + } + + Mod_LightmapAllocDone(&lmallocator, mod); +} +#endif + +extern void Surf_CreateSurfaceLightmap (msurface_t *surf, int shift); +//if build is NULL, uses q1/q2 surf generation, and allocates lightmaps +static void Mod_Batches_Build(model_t *mod, builddata_t *bd) +{ + int i; + int numverts = 0, numindicies=0; + msurface_t *surf; + mesh_t *mesh; + mesh_t **bmeshes; + int sortid; + batch_t *batch; + mesh_t *meshlist; + int merge = 1; + + currentmodel = mod; + + if (!mod->textures) + return; + + if (mod->firstmodelsurface + mod->nummodelsurfaces > mod->numsurfaces) + Sys_Error("submodel %s surface range is out of bounds\n", mod->name); + + if (bd) + meshlist = NULL; + else + meshlist = ZG_Malloc(&mod->memgroup, sizeof(mesh_t) * mod->nummodelsurfaces); + + for (i=0; inummodelsurfaces; i++) + { + surf = mod->surfaces + i + mod->firstmodelsurface; + if (meshlist) + { + mesh = surf->mesh = &meshlist[i]; + mesh->numvertexes = surf->numedges; + mesh->numindexes = (surf->numedges-2)*3; + } + else + mesh = surf->mesh; + + numverts += mesh->numvertexes; + numindicies += mesh->numindexes; +// surf->lightmaptexturenum = -1; + } + + /*assign each mesh to a batch, generating as needed*/ + merge = Mod_Batches_Generate(mod); + + bmeshes = ZG_Malloc(&mod->memgroup, sizeof(*bmeshes)*mod->nummodelsurfaces*R_MAX_RECURSE); + + //we now know which batch each surface is in, and how many meshes there are in each batch. + //allocate the mesh-pointer-lists for each batch. *2 for recursion. + for (i = 0, sortid = 0; sortid < SHADER_SORT_COUNT; sortid++) + for (batch = mod->batches[sortid]; batch != NULL; batch = batch->next) + { + batch->mesh = bmeshes + i; + i += batch->maxmeshes*R_MAX_RECURSE; + } + //store the *surface* into the batch's mesh list (yes, this is an evil cast hack, but at least both are pointers) + for (i=0; inummodelsurfaces; i++) + { + surf = mod->surfaces + mod->firstmodelsurface + i; + surf->sbatch->mesh[surf->sbatch->meshes++] = (mesh_t*)surf; + } + +#if defined(Q1BSPS) || defined(Q2BSPS) + if (!bd) + { + Mod_Batches_AllocLightmaps(mod); + + mod->lightmaps.surfstyles = 1; + Mod_Batches_BuildModelMeshes(mod, numverts, numindicies, ModQ1_Batches_BuildQ1Q2Poly, bd, merge); + } +#endif +#if defined(Q3BSPS) + if (bd) + { + Mod_Batches_SplitLightmaps(mod, merge); + Mod_Batches_BuildModelMeshes(mod, numverts, numindicies, bd->buildfunc, bd, merge); + } +#endif + + if (BE_GenBrushModelVBO) + BE_GenBrushModelVBO(mod); +} +#endif + + +/* +================= +Mod_SetParent +================= +*/ +void Mod_SetParent (mnode_t *node, mnode_t *parent) +{ + if (!node) + return; + node->parent = parent; + if (node->contents < 0) + return; + Mod_SetParent (node->children[0], node); + Mod_SetParent (node->children[1], node); +} + +#if defined(Q1BSPS) || defined(Q2BSPS) +/* +================= +Mod_LoadEdges +================= +*/ +qboolean Mod_LoadEdges (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean lm) +{ + medge_t *out; + int i, count; + + if (lm) + { + dledge_t *in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + { + Con_Printf ("MOD_LoadBmodel: funny lump size in %s\n", loadmodel->name); + return false; + } + count = l->filelen / sizeof(*in); + out = ZG_Malloc(&loadmodel->memgroup, (count + 1) * sizeof(*out)); + + loadmodel->edges = out; + loadmodel->numedges = count; + + for ( i=0 ; iv[0] = LittleLong(in->v[0]); + out->v[1] = LittleLong(in->v[1]); + } + } + else + { + dsedge_t *in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + { + Con_Printf ("MOD_LoadBmodel: funny lump size in %s\n", loadmodel->name); + return false; + } + count = l->filelen / sizeof(*in); + out = ZG_Malloc(&loadmodel->memgroup, (count + 1) * sizeof(*out)); + + loadmodel->edges = out; + loadmodel->numedges = count; + + for ( i=0 ; iv[0] = (unsigned short)LittleShort(in->v[0]); + out->v[1] = (unsigned short)LittleShort(in->v[1]); + } + } + + return true; +} + +/* +================= +Mod_LoadMarksurfaces +================= +*/ +qboolean Mod_LoadMarksurfaces (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean lm) +{ + int i, j, count; + msurface_t **out; + + if (lm) + { + int *inl; + inl = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*inl)) + { + Con_Printf (CON_ERROR "MOD_LoadBmodel: funny lump size in %s\n",loadmodel->name); + return false; + } + count = l->filelen / sizeof(*inl); + out = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*out)); + + loadmodel->marksurfaces = out; + loadmodel->nummarksurfaces = count; + + for ( i=0 ; i= loadmodel->numsurfaces) + { + Con_Printf (CON_ERROR "Mod_ParseMarksurfaces: bad surface number\n"); + return false; + } + out[i] = loadmodel->surfaces + j; + } + } + else + { + short *ins; + ins = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*ins)) + { + Con_Printf (CON_ERROR "MOD_LoadBmodel: funny lump size in %s\n",loadmodel->name); + return false; + } + count = l->filelen / sizeof(*ins); + out = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*out)); + + loadmodel->marksurfaces = out; + loadmodel->nummarksurfaces = count; + + for ( i=0 ; i= loadmodel->numsurfaces) + { + Con_Printf (CON_ERROR "Mod_ParseMarksurfaces: bad surface number\n"); + return false; + } + out[i] = loadmodel->surfaces + j; + } + } + + return true; +} + +/* +================= +Mod_LoadSurfedges +================= +*/ +qboolean Mod_LoadSurfedges (model_t *loadmodel, qbyte *mod_base, lump_t *l) +{ + int i, count; + int *in, *out; + + in = (void *)(mod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + { + Con_Printf (CON_ERROR "MOD_LoadBmodel: funny lump size in %s\n",loadmodel->name); + return false; + } + count = l->filelen / sizeof(*in); + out = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*out)); + + loadmodel->surfedges = out; + loadmodel->numsurfedges = count; + + for ( i=0 ; ifileofs; + len = l->filelen; + } + if (!len) + { + loadmodel->visdata = NULL; + return; + } + loadmodel->visdata = ZG_Malloc(&loadmodel->memgroup, len); + memcpy (loadmodel->visdata, ptr, len); +} + +#ifndef SERVERONLY +static void Mod_LoadMiptex(model_t *loadmodel, texture_t *tx, miptex_t *mt) +{ + unsigned int size = + (mt->width>>0)*(mt->height>>0) + + (mt->width>>1)*(mt->height>>1) + + (mt->width>>2)*(mt->height>>2) + + (mt->width>>3)*(mt->height>>3); + + if (loadmodel->fromgame == fg_halflife && *(short*)((qbyte *)mt + mt->offsets[3] + (mt->width>>3)*(mt->height>>3)) == 256) + { //mostly identical, just a specific palette hidden at the end. handle fences elsewhere. + tx->mips[0] = BZ_Malloc(size + 768); + tx->palette = tx->mips[0] + size; + memcpy(tx->palette, (qbyte *)mt + mt->offsets[3] + (mt->width>>3)*(mt->height>>3) + 2, 768); + } + else + { + tx->mips[0] = BZ_Malloc(size); + tx->palette = NULL; + } + + tx->mips[1] = tx->mips[0] + (mt->width>>0)*(mt->height>>0); + tx->mips[2] = tx->mips[1] + (mt->width>>1)*(mt->height>>1); + tx->mips[3] = tx->mips[2] + (mt->width>>2)*(mt->height>>2); + memcpy(tx->mips[0], (qbyte *)mt + mt->offsets[0], (mt->width>>0)*(mt->height>>0)); + memcpy(tx->mips[1], (qbyte *)mt + mt->offsets[1], (mt->width>>1)*(mt->height>>1)); + memcpy(tx->mips[2], (qbyte *)mt + mt->offsets[2], (mt->width>>2)*(mt->height>>2)); + memcpy(tx->mips[3], (qbyte *)mt + mt->offsets[3], (mt->width>>3)*(mt->height>>3)); + +} +#endif + +/* +================= +Mod_LoadTextures +================= +*/ +static qboolean Mod_LoadTextures (model_t *loadmodel, qbyte *mod_base, lump_t *l) +{ + int i, j, num, max, altmax; + miptex_t *mt; + texture_t *tx, *tx2; + texture_t *anims[10]; + texture_t *altanims[10]; + dmiptexlump_t *m; + +TRACE(("dbg: Mod_LoadTextures: inittexturedescs\n")); + +// Mod_InitTextureDescs(loadname); + + if (!l->filelen) + { + Con_Printf(CON_WARNING "warning: %s contains no texture data\n", loadmodel->name); + + loadmodel->numtextures = 1; + loadmodel->textures = ZG_Malloc(&loadmodel->memgroup, 1 * sizeof(*loadmodel->textures)); + + i = 0; + tx = ZG_Malloc(&loadmodel->memgroup, sizeof(texture_t)); + memcpy(tx, r_notexture_mip, sizeof(texture_t)); + sprintf(tx->name, "unnamed%i", i); + loadmodel->textures[i] = tx; + + return true; + } + m = (dmiptexlump_t *)(mod_base + l->fileofs); + + m->nummiptex = LittleLong (m->nummiptex); + + loadmodel->numtextures = m->nummiptex; + loadmodel->textures = ZG_Malloc(&loadmodel->memgroup, m->nummiptex * sizeof(*loadmodel->textures)); + + for (i=0 ; inummiptex ; i++) + { + m->dataofs[i] = LittleLong(m->dataofs[i]); + if (m->dataofs[i] == -1) //e1m2, this happens + { + tx = ZG_Malloc(&loadmodel->memgroup, sizeof(texture_t)); + memcpy(tx, r_notexture_mip, sizeof(texture_t)); + sprintf(tx->name, "unnamed%i", i); + loadmodel->textures[i] = tx; + continue; + } + mt = (miptex_t *)((qbyte *)m + m->dataofs[i]); + + TRACE(("dbg: Mod_LoadTextures: texture %s\n", loadname)); + + if (!*mt->name) //I HATE MAPPERS! + { + sprintf(mt->name, "unnamed%i", i); + Con_DPrintf(CON_WARNING "warning: unnamed texture in %s, renaming to %s\n", loadmodel->name, mt->name); + } + + mt->width = LittleLong (mt->width); + mt->height = LittleLong (mt->height); + for (j=0 ; joffsets[j] = LittleLong (mt->offsets[j]); + + if ( (mt->width & 15) || (mt->height & 15) ) + Con_Printf (CON_WARNING "Warning: Texture %s is not 16 aligned", mt->name); + if (mt->width < 1 || mt->height < 1) + Con_Printf (CON_WARNING "Warning: Texture %s has no size", mt->name); + tx = ZG_Malloc(&loadmodel->memgroup, sizeof(texture_t)); + loadmodel->textures[i] = tx; + + memcpy (tx->name, mt->name, sizeof(tx->name)); + tx->width = mt->width; + tx->height = mt->height; + + if (!mt->offsets[0]) //this is a hl external style texture, load it a little later (from a wad) + { + continue; + } + +#ifndef SERVERONLY + Mod_LoadMiptex(loadmodel, tx, mt); +#endif + } +// +// sequence the animations +// + for (i=0 ; inummiptex ; i++) + { + tx = loadmodel->textures[i]; + if (!tx || tx->name[0] != '+') + continue; + if (tx->anim_next) + continue; // already sequenced + + // find the number of frames in the animation + memset (anims, 0, sizeof(anims)); + memset (altanims, 0, sizeof(altanims)); + + max = tx->name[1]; + altmax = 0; + if (max >= 'a' && max <= 'z') + max -= 'a' - 'A'; + if (max >= '0' && max <= '9') + { + max -= '0'; + altmax = 0; + anims[max] = tx; + max++; + } + else if (max >= 'A' && max <= 'J') + { + altmax = max - 'A'; + max = 0; + altanims[altmax] = tx; + altmax++; + } + else + { + Con_Printf (CON_ERROR "Bad animating texture %s\n", tx->name); + return false; + } + + for (j=i+1 ; jnummiptex ; j++) + { + tx2 = loadmodel->textures[j]; + if (!tx2 || tx2->name[0] != '+') + continue; + if (strcmp (tx2->name+2, tx->name+2)) + continue; + + num = tx2->name[1]; + if (num >= 'a' && num <= 'z') + num -= 'a' - 'A'; + if (num >= '0' && num <= '9') + { + num -= '0'; + anims[num] = tx2; + if (num+1 > max) + max = num + 1; + } + else if (num >= 'A' && num <= 'J') + { + num = num - 'A'; + altanims[num] = tx2; + if (num+1 > altmax) + altmax = num+1; + } + else + { + Con_Printf (CON_ERROR "Bad animating texture %s\n", tx->name); + return false; + } + } + +#define ANIM_CYCLE 2 + // link them all together + for (j=0 ; jname); + return false; + } + tx2->anim_total = max * ANIM_CYCLE; + tx2->anim_min = j * ANIM_CYCLE; + tx2->anim_max = (j+1) * ANIM_CYCLE; + tx2->anim_next = anims[ (j+1)%max ]; + if (altmax) + tx2->alternate_anims = altanims[0]; + } + for (j=0 ; jname); + return false; + } + tx2->anim_total = altmax * ANIM_CYCLE; + tx2->anim_min = j * ANIM_CYCLE; + tx2->anim_max = (j+1) * ANIM_CYCLE; + tx2->anim_next = altanims[ (j+1)%altmax ]; + if (max) + tx2->alternate_anims = anims[0]; + } + } + + return true; +} + /* ================= Mod_LoadSubmodels @@ -2557,60 +3501,6 @@ static qboolean Mod_LoadSubmodels (model_t *loadmodel, qbyte *mod_base, lump_t * return true; } -/* -================= -Mod_LoadEdges -================= -*/ -qboolean Mod_LoadEdges (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean lm) -{ - medge_t *out; - int i, count; - - if (lm) - { - dledge_t *in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - { - Con_Printf ("MOD_LoadBmodel: funny lump size in %s\n", loadmodel->name); - return false; - } - count = l->filelen / sizeof(*in); - out = ZG_Malloc(&loadmodel->memgroup, (count + 1) * sizeof(*out)); - - loadmodel->edges = out; - loadmodel->numedges = count; - - for ( i=0 ; iv[0] = LittleLong(in->v[0]); - out->v[1] = LittleLong(in->v[1]); - } - } - else - { - dsedge_t *in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - { - Con_Printf ("MOD_LoadBmodel: funny lump size in %s\n", loadmodel->name); - return false; - } - count = l->filelen / sizeof(*in); - out = ZG_Malloc(&loadmodel->memgroup, (count + 1) * sizeof(*out)); - - loadmodel->edges = out; - loadmodel->numedges = count; - - for ( i=0 ; iv[0] = (unsigned short)LittleShort(in->v[0]); - out->v[1] = (unsigned short)LittleShort(in->v[1]); - } - } - - return true; -} - /* ================= Mod_LoadTexinfo @@ -2886,769 +3776,6 @@ static qboolean Mod_LoadFaces (model_t *loadmodel, qbyte *mod_base, lump_t *l, l return true; } -void ModQ1_Batches_BuildQ1Q2Poly(model_t *mod, msurface_t *surf, builddata_t *cookie) -{ - unsigned int vertidx; - int i, lindex, edgevert; - mesh_t *mesh = surf->mesh; - float *vec; - float s, t, d; - int sty; -// int w,h; - - if (!mesh) - { - mesh = surf->mesh = ZG_Malloc(&mod->memgroup, sizeof(mesh_t) + (sizeof(vecV_t)+sizeof(vec2_t)*(1+1)+sizeof(vec3_t)*3+sizeof(vec4_t)*1)* surf->numedges + sizeof(index_t)*(surf->numedges-2)*3); - mesh->numvertexes = surf->numedges; - mesh->numindexes = (mesh->numvertexes-2)*3; - mesh->xyz_array = (vecV_t*)(mesh+1); - mesh->st_array = (vec2_t*)(mesh->xyz_array+mesh->numvertexes); - mesh->lmst_array[0] = (vec2_t*)(mesh->st_array+mesh->numvertexes); - mesh->normals_array = (vec3_t*)(mesh->lmst_array[0]+mesh->numvertexes); - mesh->snormals_array = (vec3_t*)(mesh->normals_array+mesh->numvertexes); - mesh->tnormals_array = (vec3_t*)(mesh->snormals_array+mesh->numvertexes); - mesh->colors4f_array[0] = (vec4_t*)(mesh->tnormals_array+mesh->numvertexes); - mesh->indexes = (index_t*)(mesh->colors4f_array[0]+mesh->numvertexes); - } - mesh->istrifan = true; - - //output the mesh's indicies - for (i=0 ; inumvertexes-2 ; i++) - { - mesh->indexes[i*3] = 0; - mesh->indexes[i*3+1] = i+1; - mesh->indexes[i*3+2] = i+2; - } - //output the renderable verticies - for (i=0 ; inumvertexes ; i++) - { - lindex = mod->surfedges[surf->firstedge + i]; - edgevert = lindex <= 0; - if (edgevert) - lindex = -lindex; - if (lindex < 0 || lindex >= mod->numedges) - vertidx = 0; - else - vertidx = mod->edges[lindex].v[edgevert]; - vec = mod->vertexes[vertidx].position; - - s = DotProduct (vec, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3]; - t = DotProduct (vec, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3]; - - VectorCopy (vec, mesh->xyz_array[i]); - -/* if (R_GetShaderSizes(surf->texinfo->texture->shader, &w, &h, false) > 0) - { - mesh->st_array[i][0] = s/w; - mesh->st_array[i][1] = t/h; - } - else -*/ - { - mesh->st_array[i][0] = s; - mesh->st_array[i][1] = t; - if (surf->texinfo->texture->width) - mesh->st_array[i][0] /= surf->texinfo->texture->width; - if (surf->texinfo->texture->height) - mesh->st_array[i][1] /= surf->texinfo->texture->height; - } - -#ifndef SERVERONLY - if (gl_lightmap_average.ival) - { - for (sty = 0; sty < 1; sty++) - { - mesh->lmst_array[sty][i][0] = (surf->extents[0]*0.5 + (surf->light_s[sty]<lmshift) + (1<lmshift)*0.5) / (mod->lightmaps.width<lmshift); - mesh->lmst_array[sty][i][1] = (surf->extents[1]*0.5 + (surf->light_t[sty]<lmshift) + (1<lmshift)*0.5) / (mod->lightmaps.height<lmshift); - } - } - else -#endif - { - for (sty = 0; sty < 1; sty++) - { - mesh->lmst_array[sty][i][0] = (s - surf->texturemins[0] + (surf->light_s[sty]<lmshift) + (1<lmshift)*0.5) / (mod->lightmaps.width<lmshift); - mesh->lmst_array[sty][i][1] = (t - surf->texturemins[1] + (surf->light_t[sty]<lmshift) + (1<lmshift)*0.5) / (mod->lightmaps.height<lmshift); - } - } - - //figure out the texture directions, for bumpmapping and stuff - if (mod->normals && (surf->texinfo->flags & 0x800) && (mod->normals[vertidx][0] || mod->normals[vertidx][1] || mod->normals[vertidx][2])) - { - //per-vertex normals - used for smoothing groups and stuff. - VectorCopy(mod->normals[vertidx], mesh->normals_array[i]); - } - else - { - if (surf->flags & SURF_PLANEBACK) - VectorNegate(surf->plane->normal, mesh->normals_array[i]); - else - VectorCopy(surf->plane->normal, mesh->normals_array[i]); - } - VectorCopy(surf->texinfo->vecs[0], mesh->snormals_array[i]); - VectorNegate(surf->texinfo->vecs[1], mesh->tnormals_array[i]); - //the s+t vectors are axis-aligned, so fiddle them so they're normal aligned instead - d = -DotProduct(mesh->normals_array[i], mesh->snormals_array[i]); - VectorMA(mesh->snormals_array[i], d, mesh->normals_array[i], mesh->snormals_array[i]); - d = -DotProduct(mesh->normals_array[i], mesh->tnormals_array[i]); - VectorMA(mesh->tnormals_array[i], d, mesh->normals_array[i], mesh->tnormals_array[i]); - VectorNormalize(mesh->snormals_array[i]); - VectorNormalize(mesh->tnormals_array[i]); - - //q1bsp has no colour information (fixme: sample from the lightmap?) - for (sty = 0; sty < 1; sty++) - { - mesh->colors4f_array[sty][i][0] = 1; - mesh->colors4f_array[sty][i][1] = 1; - mesh->colors4f_array[sty][i][2] = 1; - mesh->colors4f_array[sty][i][3] = 1; - } - } -} - -#ifndef SERVERONLY -static void Mod_Batches_BuildModelMeshes(model_t *mod, int maxverts, int maxindicies, void (*build)(model_t *mod, msurface_t *surf, builddata_t *bd), builddata_t *bd, int lmmerge) -{ - batch_t *batch; - msurface_t *surf; - mesh_t *mesh; - int numverts = 0; - int numindicies = 0; - int j, i; - int sortid; - int sty; - vbo_t vbo; - int styles = mod->lightmaps.surfstyles; - char *ptr; - - memset(&vbo, 0, sizeof(vbo)); - vbo.indicies.sysptr = ZG_Malloc(&mod->memgroup, sizeof(index_t) * maxindicies); - ptr = ZG_Malloc(&mod->memgroup, (sizeof(vecV_t)+sizeof(vec2_t)*(1+styles)+sizeof(vec3_t)*3+sizeof(vec4_t)*styles)* maxverts); - - vbo.coord.sysptr = ptr; - ptr += sizeof(vecV_t)*maxverts; - for (sty = 0; sty < styles; sty++) - { - vbo.colours[sty].sysptr = ptr; - ptr += sizeof(vec4_t)*maxverts; - } - for (; sty < MAXRLIGHTMAPS; sty++) - vbo.colours[sty].sysptr = NULL; - vbo.texcoord.sysptr = ptr; - ptr += sizeof(vec2_t)*maxverts; - sty = 0; - for (; sty < styles; sty++) - { - vbo.lmcoord[sty].sysptr = ptr; - ptr += sizeof(vec2_t)*maxverts; - } - for (; sty < MAXRLIGHTMAPS; sty++) - vbo.lmcoord[sty].sysptr = NULL; - vbo.normals.sysptr = ptr; - ptr += sizeof(vec3_t)*maxverts; - vbo.svector.sysptr = ptr; - ptr += sizeof(vec3_t)*maxverts; - vbo.tvector.sysptr = ptr; - ptr += sizeof(vec3_t)*maxverts; - - numindicies = 0; - numverts = 0; - - //build each mesh - for (sortid=0; sortidbatches[sortid]; batch; batch = batch->next) - { - for (j = 0; j < batch->maxmeshes; j++) - { - surf = (msurface_t*)batch->mesh[j]; - mesh = surf->mesh; - batch->mesh[j] = mesh; - - mesh->vbofirstvert = numverts; - mesh->vbofirstelement = numindicies; - numverts += mesh->numvertexes; - numindicies += mesh->numindexes; - - //set up the arrays. the arrangement is required for the backend to optimise vbos - mesh->xyz_array = (vecV_t*)vbo.coord.sysptr + mesh->vbofirstvert; - mesh->st_array = (vec2_t*)vbo.texcoord.sysptr + mesh->vbofirstvert; - for (sty = 0; sty < MAXRLIGHTMAPS; sty++) - { - if (vbo.lmcoord[sty].sysptr) - mesh->lmst_array[sty] = (vec2_t*)vbo.lmcoord[sty].sysptr + mesh->vbofirstvert; - else - mesh->lmst_array[sty] = NULL; - if (vbo.colours[sty].sysptr) - mesh->colors4f_array[sty] = (vec4_t*)vbo.colours[sty].sysptr + mesh->vbofirstvert; - else - mesh->colors4f_array[sty] = NULL; - } - mesh->normals_array = (vec3_t*)vbo.normals.sysptr + mesh->vbofirstvert; - mesh->snormals_array = (vec3_t*)vbo.svector.sysptr + mesh->vbofirstvert; - mesh->tnormals_array = (vec3_t*)vbo.tvector.sysptr + mesh->vbofirstvert; - mesh->indexes = (index_t*)vbo.indicies.sysptr + mesh->vbofirstelement; - - mesh->vbofirstvert = 0; - mesh->vbofirstelement = 0; - - build(mod, surf, bd); - - if (lmmerge != 1) - for (sty = 0; sty < MAXRLIGHTMAPS; sty++) - { - if (surf->lightmaptexturenums[sty] >= 0) - { - if (mesh->lmst_array[sty]) - { - for (i = 0; i < mesh->numvertexes; i++) - { - mesh->lmst_array[sty][i][1] += surf->lightmaptexturenums[sty] % lmmerge; - mesh->lmst_array[sty][i][1] /= lmmerge; - } - } - surf->lightmaptexturenums[sty] /= lmmerge; - } - } - } - batch->meshes = 0; - batch->firstmesh = 0; - } - } -} - -//q1 autoanimates. if the frame is set, it uses the alternate animation. -static void Mod_UpdateBatchShader_Q1 (struct batch_s *batch) -{ - texture_t *base = batch->texture; - int reletive; - int count; - - if (batch->ent->framestate.g[FS_REG].frame[0]) - { - if (base->alternate_anims) - base = base->alternate_anims; - } - - if (base->anim_total) - { - reletive = (int)(cl.time*10) % base->anim_total; - - count = 0; - while (base->anim_min > reletive || base->anim_max <= reletive) - { - base = base->anim_next; - if (!base) - Sys_Error ("R_TextureAnimation: broken cycle"); - if (++count > 100) - Sys_Error ("R_TextureAnimation: infinite cycle"); - } - } - - batch->shader = base->shader; -} - -//q2 has direct control over the texture frames used, but typically has the client generate the frame (different flags autogenerate different ranges). -static void Mod_UpdateBatchShader_Q2 (struct batch_s *batch) -{ - texture_t *base = batch->texture; - int reletive; - int frame = batch->ent->framestate.g[FS_REG].frame[0]; - if (batch->ent == &r_worldentity) - frame = cl.time*2; - - if (base->anim_total) - { - reletive = frame % base->anim_total; - while (reletive --> 0) - { - base = base->anim_next; - if (!base) - Sys_Error ("R_TextureAnimation: broken cycle"); - } - } - - batch->shader = base->shader; -} - -#define lmmerge(i) ((i>=0)?i/merge:i) -/* -batch->firstmesh is set only in and for this function, its cleared out elsewhere -*/ -static int Mod_Batches_Generate(model_t *mod) -{ - int i; - msurface_t *surf; - shader_t *shader; - int sortid; - batch_t *batch, *lbatch = NULL; - vec4_t plane; - - int merge = mod->lightmaps.merge; - if (!merge) - merge = 1; - - mod->lightmaps.count = (mod->lightmaps.count+merge-1) & ~(merge-1); - mod->lightmaps.count /= merge; - mod->lightmaps.height *= merge; - - mod->numbatches = 0; - - //for each surface, find a suitable batch to insert it into. - //we use 'firstmesh' to avoid chucking out too many verts in a single vbo (gl2 hardware tends to have a 16bit limit) - for (i=0; inummodelsurfaces; i++) - { - surf = mod->surfaces + mod->firstmodelsurface + i; - shader = surf->texinfo->texture->shader; - - if (surf->flags & SURF_NODRAW) - { - shader = R_RegisterShader("nodraw", SUF_NONE, "{\nsurfaceparm nodraw\n}"); - sortid = shader->sort; - VectorClear(plane); - plane[3] = 0; - } - else if (shader) - { - sortid = shader->sort; - - //shaders that are portals need to be split into separate batches to have the same surface planes - if (sortid == SHADER_SORT_PORTAL || (shader->flags & (SHADER_HASREFLECT | SHADER_HASREFRACT))) - { - if (surf->flags & SURF_PLANEBACK) - { - VectorNegate(surf->plane->normal, plane); - plane[3] = -surf->plane->dist; - } - else - { - VectorCopy(surf->plane->normal, plane); - plane[3] = surf->plane->dist; - } - } - else - { - VectorClear(plane); - plane[3] = 0; - } - } - else - { - sortid = SHADER_SORT_OPAQUE; - VectorClear(plane); - plane[3] = 0; - } - - if (lbatch && ( - lbatch->texture == surf->texinfo->texture && - lbatch->shader == shader && - lbatch->lightmap[0] == lmmerge(surf->lightmaptexturenums[0]) && - Vector4Compare(plane, lbatch->plane) && - lbatch->firstmesh + surf->mesh->numvertexes <= MAX_INDICIES) && -#if MAXRLIGHTMAPS > 1 - lbatch->lightmap[1] == lmmerge(surf->lightmaptexturenums[1]) && - lbatch->lightmap[2] == lmmerge(surf->lightmaptexturenums[2]) && - lbatch->lightmap[3] == lmmerge(surf->lightmaptexturenums[3]) && -#endif - lbatch->fog == surf->fog) - batch = lbatch; - else - { - for (batch = mod->batches[sortid]; batch; batch = batch->next) - { - if ( - batch->texture == surf->texinfo->texture && - batch->shader == shader && - batch->lightmap[0] == lmmerge(surf->lightmaptexturenums[0]) && - Vector4Compare(plane, batch->plane) && - batch->firstmesh + surf->mesh->numvertexes <= MAX_INDICIES && -#if MAXRLIGHTMAPS > 1 - batch->lightmap[1] == lmmerge(surf->lightmaptexturenums[1]) && - batch->lightmap[2] == lmmerge(surf->lightmaptexturenums[2]) && - batch->lightmap[3] == lmmerge(surf->lightmaptexturenums[3]) && -#endif - batch->fog == surf->fog) - break; - } - } - if (!batch) - { - batch = ZG_Malloc(&mod->memgroup, sizeof(*batch)); - batch->lightmap[0] = lmmerge(surf->lightmaptexturenums[0]); -#if MAXRLIGHTMAPS > 1 - batch->lightmap[1] = lmmerge(surf->lightmaptexturenums[1]); - batch->lightmap[2] = lmmerge(surf->lightmaptexturenums[2]); - batch->lightmap[3] = lmmerge(surf->lightmaptexturenums[3]); -#endif - batch->texture = surf->texinfo->texture; - batch->shader = shader; - if (surf->texinfo->texture->alternate_anims || surf->texinfo->texture->anim_total) - { - if (mod->fromgame == fg_quake2) - batch->buildmeshes = Mod_UpdateBatchShader_Q2; - else - batch->buildmeshes = Mod_UpdateBatchShader_Q1; - } - batch->next = mod->batches[sortid]; - batch->ent = &r_worldentity; - batch->fog = surf->fog; - Vector4Copy(plane, batch->plane); - - mod->batches[sortid] = batch; - } - - surf->sbatch = batch; //let the surface know which batch its in - batch->maxmeshes++; - batch->firstmesh += surf->mesh->numvertexes; - - lbatch = batch; - } - - return merge; -#undef lmmerge -} - -void Mod_LightmapAllocInit(lmalloc_t *lmallocator, qboolean hasdeluxe, unsigned int width, unsigned int height, int firstlm) -{ - memset(lmallocator, 0, sizeof(*lmallocator)); - lmallocator->deluxe = hasdeluxe; - lmallocator->lmnum = firstlm; - lmallocator->firstlm = firstlm; - - lmallocator->width = width; - lmallocator->height = height; -} -void Mod_LightmapAllocDone(lmalloc_t *lmallocator, model_t *mod) -{ - mod->lightmaps.first = lmallocator->firstlm; - mod->lightmaps.count = (lmallocator->lmnum - lmallocator->firstlm); - if (lmallocator->allocated[0]) //lmnum was only *COMPLETE* lightmaps that we allocated, and does not include the one we're currently building. - mod->lightmaps.count++; - - if (lmallocator->deluxe) - { - mod->lightmaps.first*=2; - mod->lightmaps.count*=2; - mod->lightmaps.deluxemapping = true; - } - else - mod->lightmaps.deluxemapping = false; -} -void Mod_LightmapAllocBlock(lmalloc_t *lmallocator, int w, int h, unsigned short *x, unsigned short *y, int *tnum) -{ - int best, best2; - int i, j; - - for(;;) - { - best = lmallocator->height; - - for (i = 0; i <= lmallocator->width - w; i++) - { - best2 = 0; - - for (j=0; j < w; j++) - { - if (lmallocator->allocated[i+j] >= best) - break; - if (lmallocator->allocated[i+j] > best2) - best2 = lmallocator->allocated[i+j]; - } - if (j == w) - { // this is a valid spot - *x = i; - *y = best = best2; - } - } - - if (best + h > lmallocator->height) - { - memset(lmallocator->allocated, 0, sizeof(lmallocator->allocated)); - lmallocator->lmnum++; - continue; - } - - for (i=0; i < w; i++) - lmallocator->allocated[*x + i] = best + h; - - if (lmallocator->deluxe) - *tnum = lmallocator->lmnum*2; - else - *tnum = lmallocator->lmnum; - break; - } -} - -static void Mod_LightmapAllocSurf(lmalloc_t *lmallocator, msurface_t *surf, int surfstyle) -{ - int smax, tmax; - smax = (surf->extents[0]>>surf->lmshift)+1; - tmax = (surf->extents[1]>>surf->lmshift)+1; - - if (isDedicated || - (surf->texinfo->texture->shader && !(surf->texinfo->texture->shader->flags & SHADER_HASLIGHTMAP)) || //fte - (surf->flags & (SURF_DRAWSKY|SURF_DRAWTURB)) || //q1 - (surf->texinfo->flags & TEX_SPECIAL) || //the original 'no lightmap' - (surf->texinfo->flags & (TI_SKY|TI_TRANS33|TI_TRANS66|TI_WARP)) || //q2 surfaces - smax > lmallocator->width || tmax > lmallocator->height || smax < 0 || tmax < 0) //bugs/bounds/etc - { - surf->lightmaptexturenums[surfstyle] = -1; - return; - } - - Mod_LightmapAllocBlock (lmallocator, smax, tmax, &surf->light_s[surfstyle], &surf->light_t[surfstyle], &surf->lightmaptexturenums[surfstyle]); -} - -static void Mod_Batches_SplitLightmaps(model_t *mod, int lmmerge) -{ - batch_t *batch; - batch_t *nb; - int i, j, sortid; - msurface_t *surf; - int sty; - - for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++) - for (batch = mod->batches[sortid]; batch != NULL; batch = batch->next) - { - surf = (msurface_t*)batch->mesh[0]; - for (sty = 0; sty < MAXRLIGHTMAPS; sty++) - { - batch->lightmap[sty] = (surf->lightmaptexturenums[sty]>=0)?surf->lightmaptexturenums[sty]/lmmerge:surf->lightmaptexturenums[sty]; - batch->lmlightstyle[sty] = surf->styles[sty]; - } - - for (j = 1; j < batch->maxmeshes; j++) - { - surf = (msurface_t*)batch->mesh[j]; - for (sty = 0; sty < MAXRLIGHTMAPS; sty++) - { - int lm = (surf->lightmaptexturenums[sty]>=0)?surf->lightmaptexturenums[sty]/lmmerge:surf->lightmaptexturenums[sty]; - if (lm != batch->lightmap[sty] || - //fixme: we should merge later (reverted matching) surfaces into the prior batch - surf->styles[sty] != batch->lmlightstyle[sty] || - surf->vlstyles[sty] != batch->vtlightstyle[sty]) - break; - } - if (sty < MAXRLIGHTMAPS) - { - nb = ZG_Malloc(&mod->memgroup, sizeof(*batch)); - *nb = *batch; - batch->next = nb; - - nb->mesh = batch->mesh + j*2; - nb->maxmeshes = batch->maxmeshes - j; - batch->maxmeshes = j; - for (sty = 0; sty < MAXRLIGHTMAPS; sty++) - { - int lm = (surf->lightmaptexturenums[sty]>=0)?surf->lightmaptexturenums[sty]/lmmerge:surf->lightmaptexturenums[sty]; - nb->lightmap[sty] = lm; - nb->lmlightstyle[sty] = surf->styles[sty]; - nb->vtlightstyle[sty] = surf->vlstyles[sty]; - } - - memmove(nb->mesh, batch->mesh+j, sizeof(msurface_t*)*nb->maxmeshes); - - for (i = 0; i < nb->maxmeshes; i++) - { - surf = (msurface_t*)nb->mesh[i]; - surf->sbatch = nb; - } - - batch = nb; - j = 1; - } - } - } -} - -/* -allocates lightmaps and splits batches upon lightmap boundaries -*/ -static void Mod_Batches_AllocLightmaps(model_t *mod) -{ - batch_t *batch; - batch_t *nb; - lmalloc_t lmallocator; - int i, j, sortid; - msurface_t *surf; - int sty; - - size_t samps = 0; - - //small models don't have many surfaces, don't allocate a smegging huge lightmap that simply won't be used. - for (i=0, j=0; inummodelsurfaces; i++) - { - surf = mod->surfaces + mod->firstmodelsurface + i; - if (surf->texinfo->flags & TEX_SPECIAL) - continue; //surfaces with no lightmap should not count torwards anything. - samps += ((surf->extents[0]>>surf->lmshift)+1) * ((surf->extents[1]>>surf->lmshift)+1); - - if (j < (surf->extents[0]>>surf->lmshift)+1) - j = (surf->extents[0]>>surf->lmshift)+1; - if (j < (surf->extents[1]>>surf->lmshift)+1) - j = (surf->extents[1]>>surf->lmshift)+1; - } - samps /= 4; - samps = sqrt(samps); - if (j > 128 || r_dynamic.ival <= 0) - samps *= 2; - mod->lightmaps.width = bound(j, samps, LMBLOCK_SIZE_MAX); - mod->lightmaps.height = bound(j, samps, LMBLOCK_SIZE_MAX); - for (i = 0; (1<lightmaps.width; i++); - mod->lightmaps.width = 1<lightmaps.height; i++); - mod->lightmaps.height = 1<lightmaps.width = bound(64, mod->lightmaps.width, sh_config.texture_maxsize); - mod->lightmaps.height = bound(64, mod->lightmaps.height, sh_config.texture_maxsize); - - Mod_LightmapAllocInit(&lmallocator, mod->deluxdata != NULL, mod->lightmaps.width, mod->lightmaps.height, 0x50); - - for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++) - for (batch = mod->batches[sortid]; batch != NULL; batch = batch->next) - { - surf = (msurface_t*)batch->mesh[0]; - Mod_LightmapAllocSurf (&lmallocator, surf, 0); - for (sty = 1; sty < MAXRLIGHTMAPS; sty++) - surf->lightmaptexturenums[sty] = -1; - for (sty = 0; sty < MAXRLIGHTMAPS; sty++) - { - batch->lightmap[sty] = surf->lightmaptexturenums[sty]; - batch->lmlightstyle[sty] = 255;//don't do special backend rendering of lightstyles. - batch->vtlightstyle[sty] = 255;//don't do special backend rendering of lightstyles. - } - - for (j = 1; j < batch->maxmeshes; j++) - { - surf = (msurface_t*)batch->mesh[j]; - Mod_LightmapAllocSurf (&lmallocator, surf, 0); - for (sty = 1; sty < MAXRLIGHTMAPS; sty++) - surf->lightmaptexturenums[sty] = -1; - if (surf->lightmaptexturenums[0] != batch->lightmap[0]) - { - nb = ZG_Malloc(&mod->memgroup, sizeof(*batch)); - *nb = *batch; - batch->next = nb; - - nb->mesh = batch->mesh + j*2; - nb->maxmeshes = batch->maxmeshes - j; - batch->maxmeshes = j; - for (sty = 0; sty < MAXRLIGHTMAPS; sty++) - nb->lightmap[sty] = surf->lightmaptexturenums[sty]; - - memmove(nb->mesh, batch->mesh+j, sizeof(msurface_t*)*nb->maxmeshes); - - for (i = 0; i < nb->maxmeshes; i++) - { - surf = (msurface_t*)nb->mesh[i]; - surf->sbatch = nb; - } - - batch = nb; - j = 0; - } - } - } - - Mod_LightmapAllocDone(&lmallocator, mod); -} - -extern void Surf_CreateSurfaceLightmap (msurface_t *surf, int shift); -//if build is NULL, uses q1/q2 surf generation, and allocates lightmaps -static void Mod_Batches_Build(model_t *mod, builddata_t *bd) -{ - int i; - int numverts = 0, numindicies=0; - msurface_t *surf; - mesh_t *mesh; - mesh_t **bmeshes; - int sortid; - batch_t *batch; - mesh_t *meshlist; - int merge = 1; - - currentmodel = mod; - - if (!mod->textures) - return; - - if (mod->firstmodelsurface + mod->nummodelsurfaces > mod->numsurfaces) - Sys_Error("submodel %s surface range is out of bounds\n", mod->name); - - if (bd) - meshlist = NULL; - else - meshlist = ZG_Malloc(&mod->memgroup, sizeof(mesh_t) * mod->nummodelsurfaces); - - for (i=0; inummodelsurfaces; i++) - { - surf = mod->surfaces + i + mod->firstmodelsurface; - if (meshlist) - { - mesh = surf->mesh = &meshlist[i]; - mesh->numvertexes = surf->numedges; - mesh->numindexes = (surf->numedges-2)*3; - } - else - mesh = surf->mesh; - - numverts += mesh->numvertexes; - numindicies += mesh->numindexes; -// surf->lightmaptexturenum = -1; - } - - /*assign each mesh to a batch, generating as needed*/ - merge = Mod_Batches_Generate(mod); - - bmeshes = ZG_Malloc(&mod->memgroup, sizeof(*bmeshes)*mod->nummodelsurfaces*R_MAX_RECURSE); - - //we now know which batch each surface is in, and how many meshes there are in each batch. - //allocate the mesh-pointer-lists for each batch. *2 for recursion. - for (i = 0, sortid = 0; sortid < SHADER_SORT_COUNT; sortid++) - for (batch = mod->batches[sortid]; batch != NULL; batch = batch->next) - { - batch->mesh = bmeshes + i; - i += batch->maxmeshes*R_MAX_RECURSE; - } - //store the *surface* into the batch's mesh list (yes, this is an evil cast hack, but at least both are pointers) - for (i=0; inummodelsurfaces; i++) - { - surf = mod->surfaces + mod->firstmodelsurface + i; - surf->sbatch->mesh[surf->sbatch->meshes++] = (mesh_t*)surf; - } - if (bd) //q3 - Mod_Batches_SplitLightmaps(mod, merge); - else - Mod_Batches_AllocLightmaps(mod); - - if (!bd) - { - mod->lightmaps.surfstyles = 1; - Mod_Batches_BuildModelMeshes(mod, numverts, numindicies, ModQ1_Batches_BuildQ1Q2Poly, bd, merge); - } - else - Mod_Batches_BuildModelMeshes(mod, numverts, numindicies, bd->buildfunc, bd, merge); - - if (BE_GenBrushModelVBO) - BE_GenBrushModelVBO(mod); -} -#endif - -/* -================= -Mod_SetParent -================= -*/ -void Mod_SetParent (mnode_t *node, mnode_t *parent) -{ - if (!node) - return; - node->parent = parent; - if (node->contents < 0) - return; - Mod_SetParent (node->children[0], node); - Mod_SetParent (node->children[1], node); -} - /* ================= Mod_LoadNodes @@ -4357,101 +4484,6 @@ static void Mod_MakeHull0 (model_t *loadmodel) } } -/* -================= -Mod_LoadMarksurfaces -================= -*/ -qboolean Mod_LoadMarksurfaces (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean lm) -{ - int i, j, count; - msurface_t **out; - - if (lm) - { - int *inl; - inl = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*inl)) - { - Con_Printf (CON_ERROR "MOD_LoadBmodel: funny lump size in %s\n",loadmodel->name); - return false; - } - count = l->filelen / sizeof(*inl); - out = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*out)); - - loadmodel->marksurfaces = out; - loadmodel->nummarksurfaces = count; - - for ( i=0 ; i= loadmodel->numsurfaces) - { - Con_Printf (CON_ERROR "Mod_ParseMarksurfaces: bad surface number\n"); - return false; - } - out[i] = loadmodel->surfaces + j; - } - } - else - { - short *ins; - ins = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*ins)) - { - Con_Printf (CON_ERROR "MOD_LoadBmodel: funny lump size in %s\n",loadmodel->name); - return false; - } - count = l->filelen / sizeof(*ins); - out = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*out)); - - loadmodel->marksurfaces = out; - loadmodel->nummarksurfaces = count; - - for ( i=0 ; i= loadmodel->numsurfaces) - { - Con_Printf (CON_ERROR "Mod_ParseMarksurfaces: bad surface number\n"); - return false; - } - out[i] = loadmodel->surfaces + j; - } - } - - return true; -} - -/* -================= -Mod_LoadSurfedges -================= -*/ -qboolean Mod_LoadSurfedges (model_t *loadmodel, qbyte *mod_base, lump_t *l) -{ - int i, count; - int *in, *out; - - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - { - Con_Printf (CON_ERROR "MOD_LoadBmodel: funny lump size in %s\n",loadmodel->name); - return false; - } - count = l->filelen / sizeof(*in); - out = ZG_Malloc(&loadmodel->memgroup, count*sizeof(*out)); - - loadmodel->surfedges = out; - loadmodel->numsurfedges = count; - - for ( i=0 ; inodes, NULL); // sets nodes and leafs } +#endif + void ModBrush_LoadGLStuff(void *ctx, void *data, size_t a, size_t b) { #ifndef SERVERONLY diff --git a/engine/gl/gl_model.h b/engine/gl/gl_model.h index 9b38b8c0..001b860b 100644 --- a/engine/gl/gl_model.h +++ b/engine/gl/gl_model.h @@ -436,7 +436,7 @@ typedef struct mnode_s // node specific mplane_t *plane; struct mnode_s *children[2]; -#if defined(Q2BSPS) || defined(MAP_PROC) +#if defined(Q2BSPS) || defined(Q3BSPS) || defined(MAP_PROC) int childnum[2]; #endif @@ -467,13 +467,11 @@ typedef struct mleaf_s #if defined(Q2BSPS) || defined(Q3BSPS) int cluster; -// struct mleaf_s *vischain; -#endif -#ifdef Q2BSPS - //it's a q2 thing int area; unsigned int firstleafbrush; unsigned int numleafbrushes; +#endif +#ifdef Q3BSPS unsigned int firstleafcmesh; unsigned int numleafcmeshes; unsigned int firstleafpatch; @@ -1043,7 +1041,7 @@ qboolean SV_Prespawn_Brushes(sizebuf_t *msg, unsigned int *modelindex, unsigned qboolean Heightmap_Edit(model_t *mod, int action, float *pos, float radius, float quant); -#ifdef Q2BSPS +#if defined(Q2BSPS) || defined(Q3BSPS) void CM_InitBoxHull (void); @@ -1056,8 +1054,7 @@ void CM_Init(void); qboolean CM_SetAreaPortalState (struct model_s *mod, int portalnum, qboolean open); qboolean CM_HeadnodeVisible (struct model_s *mod, int nodenum, qbyte *visbits); qboolean VARGS CM_AreasConnected (struct model_s *mod, unsigned int area1, unsigned int area2); -int CM_NumClusters (struct model_s *mod); -int CM_ClusterSize (struct model_s *mod); +int CM_ClusterBytes (struct model_s *mod); int CM_LeafContents (struct model_s *mod, int leafnum); int CM_LeafCluster (struct model_s *mod, int leafnum); int CM_LeafArea (struct model_s *mod, int leafnum); diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index 117785e6..191bb7ae 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -1068,53 +1068,61 @@ static qboolean Shader_ParseProgramCvar(char *script, cvar_t **cvarrefs, char ** } #endif -const char *sh_defaultsamplers[] = +const struct sh_defaultsamplers_s sh_defaultsamplers[] = { - "s_shadowmap", - "s_projectionmap", - "s_diffuse", - "s_normalmap", - "s_specular", - "s_upper", - "s_lower", - "s_fullbright", - "s_paletted", - "s_reflectcube", - "s_reflectmask", - "s_lightmap", - "s_deluxmap", + {"s_shadowmap", 1u<<0}, + {"s_projectionmap", 1u<<1}, + {"s_diffuse", 1u<<2}, + {"s_normalmap", 1u<<3}, + {"s_specular", 1u<<4}, + {"s_upper", 1u<<5}, + {"s_lower", 1u<<6}, + {"s_fullbright", 1u<<7}, + {"s_paletted", 1u<<8}, + {"s_reflectcube", 1u<<9}, + {"s_reflectmask", 1u<<10}, + {"s_lightmap", 1u<<11}, + {"s_deluxmap", 1u<<12}, #if MAXRLIGHTMAPS > 1 - "s_lightmap1", - "s_lightmap2", - "s_lightmap3", - "s_deluxmap1", - "s_deluxmap2", - "s_deluxmap3", + {"s_lightmap1", 1u<<13}, + {"s_lightmap2", 1u<<14}, + {"s_lightmap3", 1u<<15}, + {"s_deluxmap1", 1u<<16}, + {"s_deluxmap2", 1u<<17}, + {"s_deluxmap3", 1u<<18}, +#else + {"s_lightmap1", 0}, + {"s_lightmap2", 0}, + {"s_lightmap3", 0}, + {"s_deluxmap1", 0}, + {"s_deluxmap2", 0}, + {"s_deluxmap3", 0}, #endif - NULL + {NULL} }; /*program text is already loaded, this function parses the 'header' of it to see which permutations it provides, and how many times we need to recompile it*/ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *script, int qrtype, int ver, char *blobfilename) { #if defined(GLQUAKE) || defined(D3DQUAKE) - static char *permutationname[] = + static struct { - "#define BUMP\n", - "#define FULLBRIGHT\n", - "#define UPPERLOWER\n", - "#define REFLECTCUBEMASK\n", - "#define SKELETAL\n", - "#define FOG\n", - "#define FRAMEBLEND\n", -#if MAXRLIGHTMAPS > 1 - "#define LIGHTSTYLED\n", -#endif - NULL + char *name; + unsigned int bitmask; + } permutations[] = + { + {"#define BUMP\n", PERMUTATION_BUMPMAP}, + {"#define FULLBRIGHT\n", PERMUTATION_FULLBRIGHT}, + {"#define UPPERLOWER\n", PERMUTATION_UPPERLOWER}, + {"#define REFLECTCUBEMASK\n", PERMUTATION_REFLECTCUBEMASK}, + {"#define SKELETAL\n", PERMUTATION_SKELETAL}, + {"#define FOG\n", PERMUTATION_FOG}, + {"#define FRAMEBLEND\n", PERMUTATION_FRAMEBLEND}, + {"#define LIGHTSTYLED\n", PERMUTATION_LIGHTSTYLES} }; #define MAXMODIFIERS 64 - const char *permutationdefines[sizeof(permutationname)/sizeof(permutationname[0]) + MAXMODIFIERS + 1]; - unsigned int nopermutation = ~0u; + const char *permutationdefines[countof(permutations) + MAXMODIFIERS + 1]; + unsigned int nopermutation = PERMUTATIONS-1; int nummodifiers = 0; int p, n, pn; char *end; @@ -1191,15 +1199,15 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip while (*script != ' ' && *script != '\t' && *script != '\r' && *script != '\n') script++; - for (i = 0; sh_defaultsamplers[i]; i++) + for (i = 0; sh_defaultsamplers[i].name; i++) { - if (!strncmp(start, sh_defaultsamplers[i]+2, script-start) && sh_defaultsamplers[i][2+script-start] == 0) + if (!strncmp(start, sh_defaultsamplers[i].name+2, script-start) && sh_defaultsamplers[i].name[2+script-start] == 0) { - prog->defaulttextures |= (1u<defaulttextures |= sh_defaultsamplers[i].defaulttexbits; break; } } - if (!sh_defaultsamplers[i]) + if (!sh_defaultsamplers[i].name) { i = atoi(start); if (i) @@ -1331,15 +1339,15 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip end = script; while ((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') || (*end >= '0' && *end <= '9') || *end == '_') end++; - for (p = 0; permutationname[p]; p++) + for (p = 0; p < countof(permutations); p++) { - if (!strncmp(permutationname[p]+8, script, end - script) && permutationname[p][8+end-script] == '\n') + if (!strncmp(permutations[p].name+8, script, end - script) && permutations[p].name[8+end-script] == '\n') { - nopermutation &= ~(1u<numsamplers = i+1; } } - for (i = 0; sh_defaultsamplers[i]; i++) + for (i = 0; sh_defaultsamplers[i].name; i++) { //figure out which ones are needed. - if (prog->defaulttextures & (1u<defaulttextures & sh_defaultsamplers[i].defaulttexbits) continue; //don't spam - uniformloc = qglGetUniformLocationARB(pp->h.glsl.handle, sh_defaultsamplers[i]); + uniformloc = qglGetUniformLocationARB(pp->h.glsl.handle, sh_defaultsamplers[i].name); if (uniformloc != -1) - prog->defaulttextures |= (1u<defaulttextures |= sh_defaultsamplers[i].defaulttexbits; } } @@ -2564,11 +2564,11 @@ static void GLSlang_ProgAutoFields(program_t *prog, const char *progname, cvar_t continue; sampnum = prog->numsamplers; GLSlang_UseProgram(prog->permu[p].h.glsl.handle); - for (i = 0; sh_defaultsamplers[i]; i++) + for (i = 0; sh_defaultsamplers[i].name; i++) { - if (prog->defaulttextures & (1u<defaulttextures & sh_defaultsamplers[i].defaulttexbits) { - uniformloc = qglGetUniformLocationARB(prog->permu[p].h.glsl.handle, sh_defaultsamplers[i]); + uniformloc = qglGetUniformLocationARB(prog->permu[p].h.glsl.handle, sh_defaultsamplers[i].name); if (uniformloc != -1) qglUniform1iARB(uniformloc, sampnum); sampnum++; diff --git a/engine/gl/gl_vidnt.c b/engine/gl/gl_vidnt.c index b2c7066d..d8efa76f 100644 --- a/engine/gl/gl_vidnt.c +++ b/engine/gl/gl_vidnt.c @@ -196,6 +196,7 @@ static const char *wgl_extensions; static qboolean VID_AttachGL (rendererstate_t *info); static BOOL bSetupPixelFormat(HDC hDC, rendererstate_t *info); +static BOOL CheckForcePixelFormat(rendererstate_t *info); extern cvar_t vid_gl_context_version; extern cvar_t vid_gl_context_debug; @@ -1317,7 +1318,6 @@ static qboolean CreateMainWindow(rendererstate_t *info, qboolean withthread) return stat; } -static BOOL CheckForcePixelFormat(rendererstate_t *info); static void VID_UnSetMode (void); static int GLVID_SetMode (rendererstate_t *info, unsigned char *palette) { diff --git a/engine/gl/glmod_doom.c b/engine/gl/glmod_doom.c index 19414a2e..895ea90e 100644 --- a/engine/gl/glmod_doom.c +++ b/engine/gl/glmod_doom.c @@ -299,7 +299,7 @@ fixme: use q2-style bsp collision using the trisoup for flats collisions. use blockmap for walls */ -qboolean Doom_Trace(model_t *model, int hulloverride, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean iscapsule, unsigned int contentstype, trace_t *trace) +qboolean Doom_Trace(model_t *model, int hulloverride, framestate_t *framestate, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean iscapsule, unsigned int contentstype, trace_t *trace) { #if 0 #define TRACESTEP 16 diff --git a/engine/gl/r_bishaders.h b/engine/gl/r_bishaders.h index 2005ce14..123d2550 100644 --- a/engine/gl/r_bishaders.h +++ b/engine/gl/r_bishaders.h @@ -354,7 +354,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND {QR_OPENGL, 110, "altwater", "!!cvardf r_glsl_turbscale_reflect=1 //simpler scaler\n" "!!cvardf r_glsl_turbscale_refract=1 //simpler scaler\n" -"!!samps 4 diffuse\n" +"!!samps 4 diffuse normalmap\n" "#include \"sys/defs.h\"\n" @@ -1853,7 +1853,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "!!permu TESS\n" "!!permu FRAMEBLEND\n" "!!permu SKELETAL\n" -"!!cvardf r_tessellation=0\n" +"!!cvardf r_tessellation_level=5\n" "#include \"sys/defs.h\"\n" @@ -1895,10 +1895,10 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "#define id gl_InvocationID\n" "t_vertex[id] = vertex[id];\n" "t_normal[id] = normal[id];\n" -"gl_TessLevelOuter[0] = float(r_tessellation)+1.0;\n" -"gl_TessLevelOuter[1] = float(r_tessellation)+1.0;\n" -"gl_TessLevelOuter[2] = float(r_tessellation)+1.0;\n" -"gl_TessLevelInner[0] = float(r_tessellation)+1.0;\n" +"gl_TessLevelOuter[0] = float(r_tessellation_level);\n" +"gl_TessLevelOuter[1] = float(r_tessellation_level);\n" +"gl_TessLevelOuter[2] = float(r_tessellation_level);\n" +"gl_TessLevelInner[0] = float(r_tessellation_level);\n" "}\n" "#endif\n" @@ -2332,7 +2332,8 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "!!cvarf r_glsl_offsetmapping_scale\n" "!!cvarf gl_specular\n" "!!cvardf gl_affinemodels=0\n" -"!!cvardf r_tessellation=0\n" +"!!cvardf r_tessellation_level=5\n" +"!!samps diffuse normalmap specular fullbright upper lower paletted\n" "#include \"sys/defs.h\"\n" @@ -2430,10 +2431,10 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "t_eyevector[id] = eyevector[id];\n" "#endif\n" -"gl_TessLevelOuter[0] = float(r_tessellation)+1.0;\n" -"gl_TessLevelOuter[1] = float(r_tessellation)+1.0;\n" -"gl_TessLevelOuter[2] = float(r_tessellation)+1.0;\n" -"gl_TessLevelInner[0] = float(r_tessellation)+1.0;\n" +"gl_TessLevelOuter[0] = float(r_tessellation_level);\n" +"gl_TessLevelOuter[1] = float(r_tessellation_level);\n" +"gl_TessLevelOuter[2] = float(r_tessellation_level);\n" +"gl_TessLevelInner[0] = float(r_tessellation_level);\n" "}\n" "#endif\n" @@ -4685,7 +4686,8 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "!!permu REFLECTCUBEMASK\n" "!!cvarf r_glsl_offsetmapping_scale\n" "!!cvarf gl_specular\n" -"!!cvardf r_tessellation=0\n" +"!!cvardf r_tessellation_level=5\n" +"!!samps diffuse lightmap specular normalmap fullbright reflectmask reflectcube paletted lightmap1 lightmap2 lightmap3\n" "#include \"sys/defs.h\"\n" @@ -4813,10 +4815,10 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "t_eyevector[id] = eyevector[id];\n" "#endif\n" -"gl_TessLevelOuter[0] = float(r_tessellation)+1.0;\n" -"gl_TessLevelOuter[1] = float(r_tessellation)+1.0;\n" -"gl_TessLevelOuter[2] = float(r_tessellation)+1.0;\n" -"gl_TessLevelInner[0] = float(r_tessellation)+1.0;\n" +"gl_TessLevelOuter[0] = float(r_tessellation_level);\n" +"gl_TessLevelOuter[1] = float(r_tessellation_level);\n" +"gl_TessLevelOuter[2] = float(r_tessellation_level);\n" +"gl_TessLevelInner[0] = float(r_tessellation_level);\n" "}\n" "#endif\n" @@ -5823,6 +5825,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND {QR_OPENGL, 110, "defaultwarp", "!!permu FOG\n" "!!cvarf r_wateralpha\n" +"!!samps diffuse\n" "#include \"sys/defs.h\"\n" @@ -9646,7 +9649,8 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "!!permu REFLECTCUBEMASK\n" "!!cvarf r_glsl_offsetmapping_scale\n" "!!cvardf r_glsl_pcf\n" -"!!cvardf r_tessellation=0\n" +"!!cvardf r_tessellation_level=5\n" +"!!samps shadowmap diffuse normalmap specular upper lower reflectcube reflectmask\n" "#include \"sys/defs.h\"\n" @@ -9780,10 +9784,10 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND "t_eyevector[id] = eyevector[id];\n" "#endif\n" -"gl_TessLevelOuter[0] = float(r_tessellation)+1.0;\n" -"gl_TessLevelOuter[1] = float(r_tessellation)+1.0;\n" -"gl_TessLevelOuter[2] = float(r_tessellation)+1.0;\n" -"gl_TessLevelInner[0] = float(r_tessellation)+1.0;\n" +"gl_TessLevelOuter[0] = float(r_tessellation_level);\n" +"gl_TessLevelOuter[1] = float(r_tessellation_level);\n" +"gl_TessLevelOuter[2] = float(r_tessellation_level);\n" +"gl_TessLevelInner[0] = float(r_tessellation_level);\n" "}\n" "#endif\n" diff --git a/engine/gl/shader.h b/engine/gl/shader.h index 7296f3ab..a2883f16 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -319,21 +319,39 @@ typedef struct } skydome_t; enum{ - PERMUTATION_GENERIC = 0, - PERMUTATION_BUMPMAP = 1, //FIXME: make argument somehow - PERMUTATION_FULLBRIGHT = 2, //FIXME: make argument somehow - PERMUTATION_UPPERLOWER = 4, //FIXME: make argument somehow - PERMUTATION_REFLECTCUBEMASK = 8, //FIXME: make argument somehow - PERMUTATION_SKELETAL = 16, - PERMUTATION_FOG = 32, //FIXME: remove. - PERMUTATION_FRAMEBLEND = 64, -#if MAXRLIGHTMAPS > 1 - PERMUTATION_LIGHTSTYLES = 128, //FIXME: make argument - PERMUTATIONS = 256 -#else - PERMUTATIONS = 128 -#endif + #define PERMUTATION_GENERIC 0 + #define PERMUTATION_BUMPMAP (1u< 1 + #define PERMUTATION_LIGHTSTYLES (1u<gzip) { -#if !defined(NPFTE) && defined(AVAIL_ZLIB) -#if 1 +#ifdef AVAIL_GZDEC con->file = FS_GZ_DecompressWriteFilter(dl->file, false); -#else - con->file = FS_OpenTemp(); -#endif #else Con_Printf("HTTP: no support for gzipped files \"%s\"\n", dl->localname); dl->status = DL_FAILED; @@ -929,21 +925,12 @@ static qboolean HTTP_DL_Work(struct dl_download *dl) dl->status = DL_FAILED; else { -#if !defined(NPFTE) && defined(AVAIL_ZLIB) -#if 1 +#if AVAIL_GZDEC if (con->gzip && con->file) { VFS_CLOSE(con->file); con->file = NULL; } -#else - if (con->gzip && con->file) - { - VFS_SEEK(con->file, 0); - dl->file = FS_DecompressGZip(con->file, dl->file); - con->file = NULL; - } -#endif #endif if (con->contentlength != -1 && con->totalreceived != con->contentlength) dl->status = DL_FAILED; //file was truncated @@ -1099,7 +1086,7 @@ void HTTPDL_Establish(struct dl_download *dl) "Content-Length: %u\r\n" "Content-Type: %s\r\n" "Connection: close\r\n" -#if !defined(NPFTE) && defined(AVAIL_ZLIB) +#ifdef AVAIL_GZDEC "Accept-Encoding: gzip\r\n" #endif "User-Agent: "FULLENGINENAME"\r\n" @@ -1116,7 +1103,7 @@ void HTTPDL_Establish(struct dl_download *dl) "Host: %s\r\n" /*Cookie:*/ "%s" "Connection: close\r\n" //theoretically, this is not needed. but as our code will basically do it anyway, it might as well be here FIXME: implement connection reuse. -#if !defined(NPFTE) && defined(AVAIL_ZLIB) +#ifdef AVAIL_GZDEC "Accept-Encoding: gzip\r\n" #endif "User-Agent: "FULLENGINENAME"\r\n" diff --git a/engine/partcfgs/generatebuiltin.c b/engine/partcfgs/generatebuiltin.c index 17d19593..066737bb 100644 --- a/engine/partcfgs/generatebuiltin.c +++ b/engine/partcfgs/generatebuiltin.c @@ -36,6 +36,8 @@ int main(void) fprintf(h, "/*\nWARNING: THIS FILE IS GENERATED BY '"__FILE__"'.\nYOU SHOULD NOT EDIT THIS FILE BY HAND\n*/\n\n"); fprintf(c, "/*\nWARNING: THIS FILE IS GENERATED BY '"__FILE__"'.\nYOU SHOULD NOT EDIT THIS FILE BY HAND\n*/\n\n"); fprintf(c, "#include \"bothdefs.h\"\n"); + fprintf(c, "#ifndef QUAKETC\n"); + fprintf(h, "#ifndef QUAKETC\n"); fprintf(c, "#include \"r_partset.h\"\n\n\n"); for (i = 0; *effects[i].filename; i++) @@ -107,6 +109,9 @@ int main(void) } fputs("\n", h); + fprintf(c, "#endif\n"); + fprintf(h, "#endif\n"); + fclose(h); fclose(c); } diff --git a/engine/qclib/pr_exec.c b/engine/qclib/pr_exec.c index fbb92def..7100ddf6 100644 --- a/engine/qclib/pr_exec.c +++ b/engine/qclib/pr_exec.c @@ -1548,7 +1548,7 @@ static int PR_ExecuteCode16 (progfuncs_t *fte_restrict progfuncs, int s, int *ft st = &pr_statements16[s]; while (progfuncs->funcs.debug_trace || prinst.watch_ptr || prinst.profiling) { -#ifdef FTE_TARGET_WEB +#if defined(FTE_TARGET_WEB) || defined(SIMPLE_QCVM) reeval16: //this can generate huge functions, so disable it on systems that can't realiably cope with such things (IE initiates an unwanted denial-of-service attack when pointed our javascript, and firefox prints a warning too) pr_xstatement = st-pr_statements16; @@ -1580,7 +1580,7 @@ static int PR_ExecuteCode16 (progfuncs_t *fte_restrict progfuncs, int s, int *ft static int PR_ExecuteCode32 (progfuncs_t *fte_restrict progfuncs, int s, int *fte_restrict runaway) { -#ifdef FTE_TARGET_WEB +#if defined(FTE_TARGET_WEB) ||defined(SIMPLE_QCVM) //this can generate huge functions, so disable it on systems that can't realiably cope with such things (IE initiates an unwanted denial-of-service attack when pointed our javascript, and firefox prints a warning too) pr_xstatement = s; PR_RunError (&progfuncs->funcs, "32bit qc statement support was disabled for this platform.\n"); diff --git a/engine/qclib/qcc.h b/engine/qclib/qcc.h index 2d12d291..c60a6693 100644 --- a/engine/qclib/qcc.h +++ b/engine/qclib/qcc.h @@ -658,6 +658,7 @@ void QCC_PR_Lex (void); QCC_type_t *QCC_PR_NewType (char *name, int basictype, pbool typedefed); QCC_type_t *QCC_PointerTypeTo(QCC_type_t *type); QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail); +QCC_sref_t QCC_PR_ParseDefaultInitialiser(QCC_type_t *type); extern pbool type_inlinefunction; QCC_type_t *QCC_TypeForName(char *name); QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype); @@ -665,6 +666,8 @@ QCC_type_t *QCC_PR_ParseFunctionTypeReacc (int newtype, QCC_type_t *returntype); char *QCC_PR_ParseName (void); CompilerConstant_t *QCC_PR_DefineName(char *name); +const char *QCC_VarAtOffset(QCC_sref_t ref); + int QCC_PR_IntConstExpr(void); #ifndef COMMONINLINES @@ -692,6 +695,8 @@ char *QCC_NameForWarning(int idx); enum { WARN_DEBUGGING, WARN_ERROR, + WARN_WRITTENNOTREAD, + WARN_READNOTWRITTEN, WARN_NOTREFERENCED, WARN_NOTREFERENCEDCONST, WARN_CONFLICTINGRETURNS, diff --git a/engine/qclib/qcc_pr_comp.c b/engine/qclib/qcc_pr_comp.c index 9e82c140..032a8b81 100644 --- a/engine/qclib/qcc_pr_comp.c +++ b/engine/qclib/qcc_pr_comp.c @@ -191,7 +191,7 @@ QCC_sref_t QCC_StoreSRefToRef(QCC_ref_t *dest, QCC_sref_t source, pbool readable QCC_sref_t QCC_StoreRefToRef(QCC_ref_t *dest, QCC_ref_t *source, pbool readable, pbool preservedest); void QCC_PR_DiscardRef(QCC_ref_t *ref); QCC_function_t *QCC_PR_ParseImmediateStatements (QCC_def_t *def, QCC_type_t *type, pbool dowrap); -const char *QCC_VarAtOffset(QCC_sref_t ref, unsigned int size); +const char *QCC_VarAtOffset(QCC_sref_t ref); QCC_sref_t QCC_EvaluateCast(QCC_sref_t src, QCC_type_t *cast, pbool implicit); void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t def, unsigned int flags); @@ -2083,7 +2083,7 @@ static void QCC_fprintfLocals(FILE *f, QCC_def_t *locals) #ifdef WRITEASM void QCC_WriteAsmFunction(QCC_function_t *sc, unsigned int firststatement, QCC_def_t *firstlocal); -const char *QCC_VarAtOffset(QCC_sref_t ref, unsigned int size) +const char *QCC_VarAtOffset(QCC_sref_t ref) { //for debugging, we don't need to preserve the cast. static char message[1024]; //check the temps @@ -2238,7 +2238,7 @@ pbool QCC_Temp_Describe(QCC_def_t *def, char *buffer, int buffersize) switch(s->op) { default: - QC_snprintfz(buffer, buffersize, "%s %s %s", QCC_VarAtOffset(s->a, 1), pr_opcodes[s->op].name, QCC_VarAtOffset(s->b, 1)); + QC_snprintfz(buffer, buffersize, "%s %s %s", QCC_VarAtOffset(s->a), pr_opcodes[s->op].name, QCC_VarAtOffset(s->b)); break; } return true; @@ -5863,6 +5863,12 @@ QCC_sref_t QCC_PR_ParseFunctionCall (QCC_ref_t *funcref) //warning, the func cou { e = QCC_PR_BuildRef(¶mbuf[arg], REF_GLOBAL, QCC_MakeSRef(&def_parms[arg], 0, p?p:type_variant), nullsref, p?p:type_variant, true); } + else if (arg < t->num_parms && (QCC_PR_PeekToken (",") || QCC_PR_PeekToken (")"))) + { + if (!func.cast->params[arg].defltvalue.cast) + QCC_PR_ParseErrorPrintSRef (ERR_NOTDEFINED, func, "Default value not specified for implicit argument %i", arg+1); + e = QCC_DefToRef(¶mbuf[arg], func.cast->params[arg].defltvalue); + } else //with vectorcalls, we store the vector into the args as individual floats @@ -5949,8 +5955,13 @@ QCC_sref_t QCC_PR_ParseFunctionCall (QCC_ref_t *funcref) //warning, the func cou } //don't warn if we omited optional arguments - while (np > arg && func.cast->params[np-1].optional) - np--; + while (arg < np && func.cast->params[arg].defltvalue.cast && !func.cast->params[arg].optional) + { + param[arg] = QCC_DefToRef(¶mbuf[arg], func.cast->params[arg].defltvalue); + arg++; + } + if (arg < np && func.cast->params[arg].optional) + np = arg; if (arg < np) { /*if (arg+1==np && !strcmp(QCC_GetSRefName(func), "makestatic")) @@ -7088,7 +7099,11 @@ QCC_ref_t *QCC_PR_ParseRefValue (QCC_ref_t *refbuf, QCC_type_t *assumeclass, pbo // if the token is an immediate, allocate a constant for it if (pr_token_type == tt_immediate) - return QCC_DefToRef(refbuf, QCC_PR_ParseImmediate ()); + { + d = QCC_PR_ParseImmediate (); + d.sym->referenced = true; + return QCC_DefToRef(refbuf, d); + } if (QCC_PR_CheckToken("[")) { @@ -7123,7 +7138,9 @@ QCC_ref_t *QCC_PR_ParseRefValue (QCC_ref_t *refbuf, QCC_type_t *assumeclass, pbo QCC_PR_Expect("]"); - return QCC_DefToRef(refbuf, QCC_PR_GenerateVector(x,y,z)); + d = QCC_PR_GenerateVector(x,y,z); + d.sym->referenced = true; + return QCC_DefToRef(refbuf, d); } if (QCC_PR_CheckToken("::")) @@ -9248,7 +9265,7 @@ QCC_ref_t *QCC_PR_RefExpression (QCC_ref_t *retbuf, int priority, int exprflags) } else lhsd = QCC_RefToDef(lhsr, true); - + rhsr = QCC_PR_RefExpression (&rhsbuf, priority-1, exprflags | EXPR_DISALLOW_ARRAYASSIGN); if (op->associative!=ASSOC_LEFT) @@ -9259,7 +9276,7 @@ QCC_ref_t *QCC_PR_RefExpression (QCC_ref_t *retbuf, int priority, int exprflags) { rhsd = QCC_RefToDef(rhsr, true); op = QCC_PR_ChooseOpcode(lhsd, rhsd, &opcodeprioritized[priority][opnum]); - + if (logicjump) //logic shortcut jumps to just before the if. the rhs is uninitialised if the jump was taken, but the lhs makes it deterministic. { logicjump->b.ofs = &statements[numstatements] - logicjump; @@ -11496,21 +11513,21 @@ void QCC_WriteGUIAsmFunction(QCC_function_t *sc, unsigned int firststatement) // if (strlen(pr_opcodes[statements[i].op].opname)<6) // QC_strlcat(line, " ", sizeof(line)); if (pr_opcodes[statements[i].op].type_a) - QC_snprintfz(typebuf, sizeof(typebuf), " %s", QCC_VarAtOffset(statements[i].a, (*pr_opcodes[statements[i].op].type_a)->size)); + QC_snprintfz(typebuf, sizeof(typebuf), " %s", QCC_VarAtOffset(statements[i].a)); else QC_snprintfz(typebuf, sizeof(typebuf), " %i", statements[i].a.ofs); QC_strlcat(line, typebuf, sizeof(line)); if (pr_opcodes[statements[i].op].type_b != &type_void) { if (pr_opcodes[statements[i].op].type_b) - QC_snprintfz(typebuf, sizeof(typebuf), ", %s", QCC_VarAtOffset(statements[i].b, (*pr_opcodes[statements[i].op].type_b)->size)); + QC_snprintfz(typebuf, sizeof(typebuf), ", %s", QCC_VarAtOffset(statements[i].b)); else QC_snprintfz(typebuf, sizeof(typebuf), ", %i", statements[i].b.ofs); QC_strlcat(line, typebuf, sizeof(line)); if (pr_opcodes[statements[i].op].type_c != &type_void && (pr_opcodes[statements[i].op].associative==ASSOC_LEFT || statements[i].c.cast)) { if (pr_opcodes[statements[i].op].type_c) - QC_snprintfz(typebuf, sizeof(typebuf), ", %s", QCC_VarAtOffset(statements[i].c, (*pr_opcodes[statements[i].op].type_c)->size)); + QC_snprintfz(typebuf, sizeof(typebuf), ", %s", QCC_VarAtOffset(statements[i].c)); else QC_snprintfz(typebuf, sizeof(typebuf), ", %i", statements[i].c.ofs); QC_strlcat(line, typebuf, sizeof(line)); @@ -11521,7 +11538,7 @@ void QCC_WriteGUIAsmFunction(QCC_function_t *sc, unsigned int firststatement) if (pr_opcodes[statements[i].op].type_c != &type_void) { if (pr_opcodes[statements[i].op].type_c) - QC_snprintfz(typebuf, sizeof(typebuf), ", %s", QCC_VarAtOffset(statements[i].c, (*pr_opcodes[statements[i].op].type_c)->size)); + QC_snprintfz(typebuf, sizeof(typebuf), ", %s", QCC_VarAtOffset(statements[i].c)); else QC_snprintfz(typebuf, sizeof(typebuf), ", %i", statements[i].c.ofs); QC_strlcat(line, typebuf, sizeof(line)); @@ -11533,7 +11550,7 @@ void QCC_WriteGUIAsmFunction(QCC_function_t *sc, unsigned int firststatement) if (pr_opcodes[statements[i].op].type_c != &type_void) { if (pr_opcodes[statements[i].op].type_c) - QC_snprintfz(typebuf, sizeof(typebuf), " %s", QCC_VarAtOffset(statements[i].c, (*pr_opcodes[statements[i].op].type_c)->size)); + QC_snprintfz(typebuf, sizeof(typebuf), " %s", QCC_VarAtOffset(statements[i].c)); else QC_snprintfz(typebuf, sizeof(typebuf), " %i", statements[i].c.ofs); QC_strlcat(line, typebuf, sizeof(line)); @@ -11590,19 +11607,19 @@ void QCC_WriteAsmFunction(QCC_function_t *sc, unsigned int firststatement, QCC_d if (strlen(pr_opcodes[statements[i].op].opname)<6) fprintf(asmfile, "\t"); if (pr_opcodes[statements[i].op].type_a) - fprintf(asmfile, "\t%s", QCC_VarAtOffset(statements[i].a, (*pr_opcodes[statements[i].op].type_a)->size)); + fprintf(asmfile, "\t%s", QCC_VarAtOffset(statements[i].a)); else fprintf(asmfile, "\t%i", statements[i].a.ofs); if (pr_opcodes[statements[i].op].type_b != &type_void) { if (pr_opcodes[statements[i].op].type_b) - fprintf(asmfile, ",\t%s", QCC_VarAtOffset(statements[i].b, (*pr_opcodes[statements[i].op].type_b)->size)); + fprintf(asmfile, ",\t%s", QCC_VarAtOffset(statements[i].b)); else fprintf(asmfile, ",\t%i", statements[i].b.ofs); if (pr_opcodes[statements[i].op].type_c != &type_void && (pr_opcodes[statements[i].op].associative==ASSOC_LEFT || statements[i].c.sym)) { if (pr_opcodes[statements[i].op].type_c) - fprintf(asmfile, ",\t%s", QCC_VarAtOffset(statements[i].c, (*pr_opcodes[statements[i].op].type_c)->size)); + fprintf(asmfile, ",\t%s", QCC_VarAtOffset(statements[i].c)); else fprintf(asmfile, ",\t%i", statements[i].c.ofs); } @@ -11612,7 +11629,7 @@ void QCC_WriteAsmFunction(QCC_function_t *sc, unsigned int firststatement, QCC_d if (pr_opcodes[statements[i].op].type_c != &type_void) { if (pr_opcodes[statements[i].op].type_c) - fprintf(asmfile, ",\t%s", QCC_VarAtOffset(statements[i].c, (*pr_opcodes[statements[i].op].type_c)->size)); + fprintf(asmfile, ",\t%s", QCC_VarAtOffset(statements[i].c)); else fprintf(asmfile, ",\t%i", statements[i].c.ofs); } @@ -11623,7 +11640,7 @@ void QCC_WriteAsmFunction(QCC_function_t *sc, unsigned int firststatement, QCC_d if (pr_opcodes[statements[i].op].type_c != &type_void) { if (pr_opcodes[statements[i].op].type_c) - fprintf(asmfile, "\t%s", QCC_VarAtOffset(statements[i].c, (*pr_opcodes[statements[i].op].type_c)->size)); + fprintf(asmfile, "\t%s", QCC_VarAtOffset(statements[i].c)); else fprintf(asmfile, "\t%i", statements[i].c.ofs); } @@ -13416,6 +13433,13 @@ void QCC_PR_ParseInitializerDef(QCC_def_t *def, unsigned int flags) if (!def->initialized || def->initialized == 3) def->initialized = 1; } +QCC_sref_t QCC_PR_ParseDefaultInitialiser(QCC_type_t *type) +{ + QCC_sref_t ref = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA); + if (!ref.sym->constant) + QCC_PR_ParseError(0, "Default value not a constant\n"); + return QCC_EvaluateCast(ref, type, true); +} int accglobalsblock; //0 = error, 1 = var, 2 = function, 3 = objdata @@ -14324,7 +14348,7 @@ pbool QCC_PR_CompileFile (char *string, char *filename) sr.sym = d; sr.cast = d->type; sr.ofs = 0; - QCC_PR_ParseWarning(WARN_DEBUGGING, "INTERNAL: %i references still held on %s (%s)", d->refcount, d->name, QCC_VarAtOffset(sr, 1)); + QCC_PR_ParseWarning(WARN_DEBUGGING, "INTERNAL: %i references still held on %s (%s)", d->refcount, d->name, QCC_VarAtOffset(sr)); d->refcount = 0; } } @@ -14336,7 +14360,7 @@ pbool QCC_PR_CompileFile (char *string, char *filename) sr.sym = d; sr.cast = d->type; sr.ofs = 0; - QCC_PR_ParseWarning(WARN_DEBUGGING, "INTERNAL: %i references still held on %s (%s)", d->refcount, d->name, QCC_VarAtOffset(sr, d->type->size)); + QCC_PR_ParseWarning(WARN_DEBUGGING, "INTERNAL: %i references still held on %s (%s)", d->refcount, d->name, QCC_VarAtOffset(sr)); d->refcount = 0; } } @@ -14349,7 +14373,7 @@ pbool QCC_PR_CompileFile (char *string, char *filename) sr.sym = d; sr.cast = d->type; sr.ofs = 0; - QCC_PR_ParseWarning(WARN_DEBUGGING, "INTERNAL: %i references still held on %s (%s)", d->refcount, d->name, QCC_VarAtOffset(sr, d->type->size)); + QCC_PR_ParseWarning(WARN_DEBUGGING, "INTERNAL: %i references still held on %s (%s)", d->refcount, d->name, QCC_VarAtOffset(sr)); d->refcount = 0; } } diff --git a/engine/qclib/qcc_pr_lex.c b/engine/qclib/qcc_pr_lex.c index 33cfc9b4..6ebb82de 100644 --- a/engine/qclib/qcc_pr_lex.c +++ b/engine/qclib/qcc_pr_lex.c @@ -4032,6 +4032,13 @@ static int typecmp_strict(QCC_type_t *a, QCC_type_t *b) return 1; if (typecmp_strict(a->params[i].type, b->params[i].type)) return 1; + if (a->params[i].defltvalue.cast || b->params[i].defltvalue.cast) + { + if (typecmp_strict(a->params[i].defltvalue.cast, b->params[i].defltvalue.cast) || + a->params[i].defltvalue.sym != b->params[i].defltvalue.sym || + a->params[i].defltvalue.ofs != b->params[i].defltvalue.ofs) + return 1; + } } return 0; @@ -4074,6 +4081,13 @@ int typecmp(QCC_type_t *a, QCC_type_t *b) return 1; if (typecmp(a->params[i].type, b->params[i].type)) return 1; + if (a->params[i].defltvalue.cast || b->params[i].defltvalue.cast) + { + if (typecmp(a->params[i].defltvalue.cast, b->params[i].defltvalue.cast) || + a->params[i].defltvalue.sym != b->params[i].defltvalue.sym || + a->params[i].defltvalue.ofs != b->params[i].defltvalue.ofs) + return 1; + } } return 0; @@ -4142,6 +4156,14 @@ int typecmp_lax(QCC_type_t *a, QCC_type_t *b) if (typecmp_lax(a->params[t].type, b->params[t].type)) return 1; } + + if (a->params[t].defltvalue.cast || b->params[t].defltvalue.cast) + { + if (typecmp(a->params[t].defltvalue.cast, b->params[t].defltvalue.cast) || + a->params[t].defltvalue.sym != b->params[t].defltvalue.sym || + a->params[t].defltvalue.ofs != b->params[t].defltvalue.ofs) + return 1; + } } if (a->num_parms > minargs) { @@ -4246,6 +4268,12 @@ char *TypeName(QCC_type_t *type, char *buffer, int buffersize) Q_strlcat(buffer, type->params[i].paramname, buffersize); } + if (type->params[i].defltvalue.cast) + { + Q_strlcat(buffer, " = ", buffersize); + Q_strlcat(buffer, QCC_VarAtOffset(type->params[i].defltvalue), buffersize); + } + if (++i < type->num_parms || vargs) Q_strlcat(buffer, ", ", buffersize); } @@ -4383,7 +4411,6 @@ QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype) QCC_type_t *ftype; char *name; int definenames = !recursivefunctiontype; - int optional = 0; int numparms = 0; struct QCC_typeparam_s paramlist[MAX_PARMS+MAX_EXTRA_PARMS]; @@ -4419,22 +4446,9 @@ QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype) else paramlist[numparms].out = false; //the default - if (QCC_PR_CheckKeyword(keyword_optional, "optional")) - { - paramlist[numparms].optional = true; - optional = true; - } - else - { - if (optional) - { - QCC_PR_ParseWarning(WARN_MISSINGOPTIONAL, "optional not specified on all optional args\n"); - paramlist[numparms].optional = true; - } - else - paramlist[numparms].optional = false; - } + paramlist[numparms].optional = QCC_PR_CheckKeyword(keyword_optional, "optional"); + paramlist[numparms].defltvalue.cast = NULL; paramlist[numparms].ofs = 0; paramlist[numparms].arraysize = 0; paramlist[numparms].type = QCC_PR_ParseType(false, false); @@ -4442,7 +4456,7 @@ QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype) QCC_PR_ParseError(0, "Expected type\n"); if (paramlist[numparms].type->type == ev_void) - break; + break; //float(void) has no actual args // type->name = "FUNC PARAMETER"; @@ -4463,6 +4477,9 @@ QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype) } else if (definenames) strcpy (pr_parm_names[numparms], ""); + + if (QCC_PR_CheckToken("=")) + paramlist[numparms].defltvalue = QCC_PR_ParseDefaultInitialiser(paramlist[numparms].type); numparms++; } while (QCC_PR_CheckToken (",")); @@ -4626,6 +4643,7 @@ QCC_type_t *QCC_PR_GenFunctionType (QCC_type_t *rettype, struct QCC_typeparam_s p->optional = args[i].optional; p->ofs = args[i].ofs; p->arraysize = args[i].arraysize; + p->defltvalue.cast = NULL; } return QCC_PR_FindType (ftype); } @@ -5216,6 +5234,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail) parms[numparms].paramname = parmname; parms[numparms].arraysize = arraysize; parms[numparms].type = newparm; + parms[numparms].defltvalue.cast = NULL; basicindex = 0; found = false; @@ -5430,6 +5449,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail) parms[numparms].optional = false; parms[numparms].paramname = parmname; parms[numparms].type = newparm; + parms[numparms].defltvalue.cast = NULL; numparms++; } if (!numparms) diff --git a/engine/qclib/qccgui.c b/engine/qclib/qccgui.c index 5ec4c86b..0210db7a 100644 --- a/engine/qclib/qccgui.c +++ b/engine/qclib/qccgui.c @@ -12,6 +12,9 @@ #include "qcc.h" #include "gui.h" +//#define AVAIL_PNGLIB +//#define AVAIL_ZLIB + #define EMBEDDEBUG #define IDI_ICON_FTEQCC MAKEINTRESOURCE(101) @@ -2409,12 +2412,14 @@ static LRESULT CALLBACK EditorWndProc(HWND hWnd,UINT message, static void EditorReload(editor_t *editor) { struct stat sbuf; - size_t flen; + size_t flensz; char *rawfile; char *file; + unsigned int flen; pbool dofree; - rawfile = QCC_ReadFile(editor->filename, NULL, 0, &flen); + rawfile = QCC_ReadFile(editor->filename, NULL, 0, &flensz); + flen = flensz; file = QCC_SanitizeCharSet(rawfile, &flen, &dofree, &editor->savefmt); @@ -3953,6 +3958,7 @@ typedef struct #pragma pack(pop) +#ifdef AVAIL_PNGLIB static void Image_ResampleTexture (unsigned *in, int inwidth, int inheight, unsigned *out, int outwidth, int outheight) { int i, j; @@ -3991,9 +3997,8 @@ static void Image_ResampleTexture (unsigned *in, int inwidth, int inheight, unsi } } } +#endif -//#define AVAIL_PNGLIB -//#define AVAIL_ZLIB #ifndef MSVCLIBSPATH #ifdef MSVCLIBPATH #define MSVCLIBSPATH STRINGIFY(MSVCLIBPATH) @@ -4347,11 +4352,10 @@ static void GUI_CreateInstaller_Windows(void) { #define RESLANG MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_UK) unsigned char *mandata = NULL; - unsigned int manlen; + size_t manlen; unsigned char *pngdata = NULL; - unsigned int pnglen; + size_t pnglen; char *error = NULL; - char *warn = NULL; HANDLE bin; char ourname[MAX_PATH]; char *basedir = enginebasedir; diff --git a/engine/qclib/qccmain.c b/engine/qclib/qccmain.c index 7734d161..9cef0f2d 100644 --- a/engine/qclib/qccmain.c +++ b/engine/qclib/qccmain.c @@ -10,6 +10,8 @@ #include "errno.h" +//#define TODO_READWRITETRACK + //#define DEBUG_DUMP //#define DISASM "M_Preset" @@ -34,7 +36,6 @@ void QCC_PR_LexWhitespace (pbool inhibitpreprocessor); void *FS_ReadToMem(char *fname, void *membuf, int *len); void FS_CloseFromMem(void *mem); -const char *QCC_VarAtOffset(QCC_sref_t ref, unsigned int size); unsigned int MAX_REGS; unsigned int MAX_LOCALS = 0x10000; @@ -976,6 +977,56 @@ void QCC_FinaliseDef(QCC_def_t *def) for (prev = def, sub = prev->next; prev != def->deftail; sub = (prev=sub)->next) sub->referenced |= def->referenced; } + +#ifdef TODO_READWRITETRACK + if (!def->read) + { + pbool ignoreone = true; + //touch all but one child + for (prev = def, sub = prev->next; prev != def->deftail; sub = (prev=sub)->next) + { + if (sub->read) + def->read=true; //if one child is referenced, the composite is referenced + else if (!sub->read && ignoreone) + ignoreone = false; //this is the one we're going to warn about + else + sub->read |= def->read; + } + if (!def->read) //no child defs were referenced at all. if we're going to be warning about this then at least mute warnings for any other fields + for (prev = def, sub = prev->next; prev != def->deftail; sub = (prev=sub)->next) + sub->read = true; + } + else + { + //touch children + for (prev = def, sub = prev->next; prev != def->deftail; sub = (prev=sub)->next) + sub->read |= def->read; + } + + if (!def->written) + { + pbool ignoreone = true; + //touch all but one child + for (prev = def, sub = prev->next; prev != def->deftail; sub = (prev=sub)->next) + { + if (sub->written) + def->written=true; //if one child is referenced, the composite is referenced + else if (!sub->written && ignoreone) + ignoreone = false; //this is the one we're going to warn about + else + sub->written |= def->written; + } + if (!def->written) //no child defs were referenced at all. if we're going to be warning about this then at least mute warnings for any other fields + for (prev = def, sub = prev->next; prev != def->deftail; sub = (prev=sub)->next) + sub->written = true; + } + else + { + //touch children + for (prev = def, sub = prev->next; prev != def->deftail; sub = (prev=sub)->next) + sub->written |= def->written; + } +#endif } // else if (def->symbolheader) //if a child symbol is referenced, mark the entire parent as referenced too. this avoids vec_x+vec_y with no vec or vec_z from generating warnings about vec being unreferenced // def->symbolheader->referenced |= def->referenced; @@ -1464,7 +1515,21 @@ pbool QCC_WriteData (int crc) } } */ - if (!def->symbolheader->used) +#ifdef TODO_READWRITETRACK + if (def->symbolheader->read && !def->symbolheader->written && !def->symbolheader->referenced) + { + char typestr[256]; + QCC_sref_t sr = {def, def->ofs, def->type}; + QCC_PR_Warning(WARN_READNOTWRITTEN, def->filen, def->s_line, "%s %s = %s read, but not writte.", TypeName(def->type, typestr, sizeof(typestr)), def->name, QCC_VarAtOffset(sr)); + } + if (def->symbolheader->written && !def->symbolheader->read && !def->symbolheader->referenced) + { + char typestr[256]; + QCC_sref_t sr = {def, def->ofs, def->type}; + QCC_PR_Warning(WARN_WRITTENNOTREAD, def->filen, def->s_line, "%s %s = %s written, but not read.", TypeName(def->type, typestr, sizeof(typestr)), def->name, QCC_VarAtOffset(sr)); + } +#endif + if (!def->symbolheader->read && !def->symbolheader->written && !def->symbolheader->referenced) { int wt = def->constant?WARN_NOTREFERENCEDCONST:WARN_NOTREFERENCED; pr_scope = def->scope; @@ -1485,14 +1550,20 @@ pbool QCC_WriteData (int crc) } pr_scope = NULL; - if (opt_unreferenced && def->type->type != ev_field) + if (def->symbolheader->used) + { + char typestr[256]; + QCC_sref_t sr = {def, def->ofs, def->type}; + QCC_PR_Warning(WARN_NOTREFERENCED, def->filen, def->s_line, "%s %s = %s used, but not referenced.", TypeName(def->type, typestr, sizeof(typestr)), def->name, QCC_VarAtOffset(sr)); + } + /*if (opt_unreferenced && def->type->type != ev_field) { optres_unreferenced++; #ifdef DEBUG_DUMP printf("code: %s:%i: strip noref %s %s@%i;\n", def->filen, def->s_line, def->type->name, def->name, def->ofs); #endif continue; - } + }*/ } if ((def->type->type == ev_struct || def->type->type == ev_union || def->arraysize) && def->deftail) { @@ -1505,6 +1576,7 @@ pbool QCC_WriteData (int crc) if (def->strip || !def->symbolheader->used) { + optres_unreferenced++; #ifdef DEBUG_DUMP printf("code: %s:%i: strip %s %s@%i;\n", def->filen, def->s_line, def->type->name, def->name, def->ofs); #endif diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 355b9aef..b1c90869 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -223,8 +223,10 @@ void PDECL ED_Spawned (struct edict_s *ent, int loading) ent->xv->dimension_ghost = 0; ent->xv->dimension_solid = pr_global_struct->dimension_default; ent->xv->dimension_hit = pr_global_struct->dimension_default; +#ifdef HEXEN2 if (progstype != PROG_H2) ent->xv->drawflags = SCALE_ORIGIN_ORIGIN; //if not running hexen2, default the scale origin to the actual origin. +#endif #ifndef NOLEGACY ent->xv->Version = sv.csqcentversion[ent->entnum]; @@ -9797,7 +9799,7 @@ static void QCBUILTIN PF_setpause(pubprogfuncs_t *prinst, struct globalvars_s *p #else #define NYI ,true #endif -#ifdef MINIMAL +#ifdef NOQCDESCRIPTIONS #define D(p,d) NULL,NULL #else #define D(p,d) p,d @@ -10722,7 +10724,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"gethostcachevalue",PF_Fixme, 0, 0, 0, 611, "float(float type)"}, {"gethostcachestring",PF_Fixme, 0, 0, 0, 612, "string(float type, float hostnr)"}, {"parseentitydata", PF_parseentitydata, 0, 0, 0, 613, D("float(entity e, string s, optional float offset)", "Reads a single entity's fields into an already-spawned entity. s should contain field pairs like in a saved game: {\"foo1\" \"bar\" \"foo2\" \"5\"}. Returns <=0 on failure, otherwise returns the offset in the string that was read to.")}, - {"generateentitydata",PF_generateentitydata,0, 0, 0, 0, D("string(entity e)", "Dumps the entities fields into a string which can later be parsed with parseentitydata."}), + {"generateentitydata",PF_generateentitydata,0, 0, 0, 0, D("string(entity e)", "Dumps the entities fields into a string which can later be parsed with parseentitydata.")}, {"stringtokeynum", PF_Fixme, 0, 0, 0, 614, D("float(string key)", "Returns the qscancode of a key from its name. Names are identical to the bind command. ctrl/shift/alt modifiers are ignored.")}, {"stringtokeynum_menu", PF_Fixme, 0, 0, 0, 614, "float(string key)"}, {"resethostcachemasks",PF_Fixme, 0, 0, 0, 615, "void()"}, @@ -11225,6 +11227,8 @@ void PR_DumpPlatform_f(void) { #ifdef SERVERONLY Con_Printf("This command is not available in dedicated servers, sorry.\n"); +#elif defined(NOQCDESCRIPTIONS) && NOQCDESCRIPTIONS > 1 + Con_Printf("This command is not available in this build, sorry.\n"); #else //eg: pr_dumpplatform -FFTE -TCS -O csplat @@ -11259,23 +11263,30 @@ void PR_DumpPlatform_f(void) qboolean accessors = false; char *comment; +#undef D +#ifdef NOQCDESCRIPTIONS + #define D(d) NULL +#else + #define D(d) d +#endif + /*this list is here to ensure that the file can be used as a valid initial qc file (ignoring precompiler options)*/ knowndef_t knowndefs[] = { - {"self", "entity", QW|NQ|CS|MENU, "The magic me"}, - {"other", "entity", QW|NQ|CS, "Valid in touch functions, this is the entity that we touched."}, - {"world", "entity", QW|NQ|CS, "The null entity. Hurrah. Readonly after map spawn time."}, - {"time", "float", QW|NQ|CS, "The current game time. Stops when paused."}, - {"cltime", "float", CS, "A local timer that ticks relative to local time regardless of latency, packetloss, or pause."}, - {"frametime", "float", QW|NQ|CS, "The time since the last physics/render/input frame."}, - {"player_localentnum", "float", CS, "This is entity number the player is seeing from/spectating, or the player themself, can change mid-map."}, - {"player_localnum", "float", CS, "The 0-based player index, valid for getplayerkeyvalue calls."}, - {"maxclients", "float", CS, "Maximum number of player slots on the server."}, - {"clientcommandframe", "float", CS, "This is the input-frame sequence. frames < clientcommandframe have been sent to the server. frame==clientcommandframe is still being generated and can still change."}, - {"servercommandframe", "float", CS, "This is the input-frame that was last acknowledged by the server. Input frames greater than this should be applied to the player's entity."}, - {"newmis", "entity", QW, "A named entity that should be run soon, to reduce the effects of latency."}, - {"force_retouch", "float", QW|NQ, "If positive, causes all entities to check for triggers."}, - {"mapname", "string", QW|NQ|CS, "The short name of the map."}, + {"self", "entity", QW|NQ|CS|MENU, D("The magic me")}, + {"other", "entity", QW|NQ|CS, D("Valid in touch functions, this is the entity that we touched.")}, + {"world", "entity", QW|NQ|CS, D("The null entity. Hurrah. Readonly after map spawn time.")}, + {"time", "float", QW|NQ|CS, D("The current game time. Stops when paused.")}, + {"cltime", "float", CS, D("A local timer that ticks relative to local time regardless of latency, packetloss, or pause.")}, + {"frametime", "float", QW|NQ|CS, D("The time since the last physics/render/input frame.")}, + {"player_localentnum", "float", CS, D("This is entity number the player is seeing from/spectating, or the player themself, can change mid-map.")}, + {"player_localnum", "float", CS, D("The 0-based player index, valid for getplayerkeyvalue calls.")}, + {"maxclients", "float", CS, D("Maximum number of player slots on the server.")}, + {"clientcommandframe", "float", CS, D("This is the input-frame sequence. frames < clientcommandframe have been sent to the server. frame==clientcommandframe is still being generated and can still change.")}, + {"servercommandframe", "float", CS, D("This is the input-frame that was last acknowledged by the server. Input frames greater than this should be applied to the player's entity.")}, + {"newmis", "entity", QW, D("A named entity that should be run soon, to reduce the effects of latency.")}, + {"force_retouch", "float", QW|NQ, D("If positive, causes all entities to check for triggers.")}, + {"mapname", "string", QW|NQ|CS, D("The short name of the map.")}, {"deathmatch", "float", NQ}, {"coop", "float", NQ}, {"teamplay", "float", NQ}, @@ -11287,7 +11298,7 @@ void PR_DumpPlatform_f(void) {"parm1, parm2, parm3, parm4, parm5, parm6, parm7, parm8, parm9, parm10, parm11, parm12, parm13, parm14, parm15, parm16", "float", QW|NQ}, {"intermission", "float", CS}, {"v_forward, v_up, v_right", "vector", QW|NQ|CS}, - {"view_angles", "vector", CS, "+x=DOWN"}, + {"view_angles", "vector", CS, D("+x=DOWN")}, {"trace_allsolid, trace_startsolid, trace_fraction", "float", QW|NQ|CS}, {"trace_endpos, trace_plane_normal", "vector", QW|NQ|CS}, {"trace_plane_dist", "float", QW|NQ|CS}, @@ -11295,7 +11306,7 @@ void PR_DumpPlatform_f(void) {"trace_inopen", "float", QW|NQ|CS}, {"trace_inwater", "float", QW|NQ|CS}, {"input_timelength", "float", CS}, - {"input_angles", "vector", CS, "+x=DOWN"}, + {"input_angles", "vector", CS, D("+x=DOWN")}, {"input_movevalues", "vector", CS}, {"input_buttons", "float", CS}, {"input_impulse", "float", CS}, @@ -11313,41 +11324,41 @@ void PR_DumpPlatform_f(void) {"end_sys_globals", "void", QW|NQ|CS|MENU}, - {"modelindex", ".float", QW|NQ|CS, "This is the model precache index for the model that was set on the entity, instead of having to look up the model according to the .model field. Use setmodel to change it."}, - {"absmin", ".vector", QW|NQ|CS, "Set by the engine when the entity is relinked (by setorigin, setsize, or setmodel). This is in world coordinates."}, - {"absmax", ".vector", QW|NQ|CS, "Set by the engine when the entity is relinked (by setorigin, setsize, or setmodel). This is in world coordinates."}, - {"ltime", ".float", QW|NQ, "On MOVETYPE_PUSH entities, this is used as an alternative to the 'time' global, and .nextthink is synced to this instead of time. This allows time to effectively freeze if the entity is blocked, ensuring the think happens when the entity reaches the target point instead of randomly."}, - {"entnum", ".float", CS, "The entity number as its known on the server."}, - {"drawmask", ".float", CS, "Acts as a filter in the addentities call."}, - {"predraw", ".float()", CS, "Called by addentities after the filter and before the entity is actually drawn. Do your interpolation and animation in here. Should return one of the PREDRAW_* constants."}, - {"lastruntime", ".float", QW, "This field used to be used to avoid running an entity multiple times in a single frame due to quakeworld's out-of-order thinks. It is no longer used by FTE due to precision issues, but may still be updated for compatibility reasons."}, - {"movetype", ".float", QW|NQ|CS, "Describes how the entity moves. One of the MOVETYPE_ constants."}, - {"solid", ".float", QW|NQ|CS, "Describes whether the entity is solid or not, and any special properties infered by that. Must be one of the SOLID_ constants"}, - {"origin", ".vector", QW|NQ|CS, "The current location of the entity in world space. Inline bsp entities (ie: ones placed by a mapper) will typically have a value of '0 0 0' in their neutral pose, as the geometry is offset from that. It is the reference point of the entity rather than the center of its geometry, for non-bsp models, this is often not a significant distinction."}, - {"oldorigin", ".vector", QW|NQ|CS, "This is often used on players to reset the player back to where they were last frame if they somehow got stuck inside something due to fpu precision. Never change a player's oldorigin field to inside a solid, because that might cause them to become pemanently stuck."}, - {"velocity", ".vector", QW|NQ|CS, "The direction and speed that the entity is moving in world space."}, - {"angles", ".vector", QW|NQ|CS, "The eular angles the entity is facing in, in pitch, yaw, roll order. Due to a legacy bug, mdl/iqm/etc formats use +x=UP, bsp/spr/etc formats use +x=DOWN."}, - {"avelocity", ".vector", QW|NQ|CS, "The amount the entity's angles change by each frame. Note that this is direct eular angles, and thus the angular change is non-linear and often just looks buggy."}, + {"modelindex", ".float", QW|NQ|CS, D("This is the model precache index for the model that was set on the entity, instead of having to look up the model according to the .model field. Use setmodel to change it.")}, + {"absmin", ".vector", QW|NQ|CS, D("Set by the engine when the entity is relinked (by setorigin, setsize, or setmodel). This is in world coordinates.")}, + {"absmax", ".vector", QW|NQ|CS, D("Set by the engine when the entity is relinked (by setorigin, setsize, or setmodel). This is in world coordinates.")}, + {"ltime", ".float", QW|NQ, D("On MOVETYPE_PUSH entities, this is used as an alternative to the 'time' global, and .nextthink is synced to this instead of time. This allows time to effectively freeze if the entity is blocked, ensuring the think happens when the entity reaches the target point instead of randomly.")}, + {"entnum", ".float", CS, D("The entity number as its known on the server.")}, + {"drawmask", ".float", CS, D("Acts as a filter in the addentities call.")}, + {"predraw", ".float()", CS, D("Called by addentities after the filter and before the entity is actually drawn. Do your interpolation and animation in here. Should return one of the PREDRAW_* constants.")}, + {"lastruntime", ".float", QW, D("This field used to be used to avoid running an entity multiple times in a single frame due to quakeworld's out-of-order thinks. It is no longer used by FTE due to precision issues, but may still be updated for compatibility reasons.")}, + {"movetype", ".float", QW|NQ|CS, D("Describes how the entity moves. One of the MOVETYPE_ constants.")}, + {"solid", ".float", QW|NQ|CS, D("Describes whether the entity is solid or not, and any special properties infered by that. Must be one of the SOLID_ constants")}, + {"origin", ".vector", QW|NQ|CS, D("The current location of the entity in world space. Inline bsp entities (ie: ones placed by a mapper) will typically have a value of '0 0 0' in their neutral pose, as the geometry is offset from that. It is the reference point of the entity rather than the center of its geometry, for non-bsp models, this is often not a significant distinction.")}, + {"oldorigin", ".vector", QW|NQ|CS, D("This is often used on players to reset the player back to where they were last frame if they somehow got stuck inside something due to fpu precision. Never change a player's oldorigin field to inside a solid, because that might cause them to become pemanently stuck.")}, + {"velocity", ".vector", QW|NQ|CS, D("The direction and speed that the entity is moving in world space.")}, + {"angles", ".vector", QW|NQ|CS, D("The eular angles the entity is facing in, in pitch, yaw, roll order. Due to a legacy bug, mdl/iqm/etc formats use +x=UP, bsp/spr/etc formats use +x=DOWN.")}, + {"avelocity", ".vector", QW|NQ|CS, D("The amount the entity's angles change by each frame. Note that this is direct eular angles, and thus the angular change is non-linear and often just looks buggy.")}, {"pmove_flags", ".float", CS}, {"punchangle", ".vector", NQ}, - {"classname", ".string", QW|NQ|CS, "Identifies the class/type of the entity. Useful for debugging, also used for loading, but its value is not otherwise significant to the engine, this leaves the mod free to set it to whatever it wants and randomly test strings for values in whatever inefficient way it chooses fit."}, + {"classname", ".string", QW|NQ|CS, D("Identifies the class/type of the entity. Useful for debugging, also used for loading, but its value is not otherwise significant to the engine, this leaves the mod free to set it to whatever it wants and randomly test strings for values in whatever inefficient way it chooses fit.")}, {"renderflags", ".float", CS}, - {"model", ".string", QW|NQ|CS, "The model name that was set via setmodel, in theory. Often, this is cleared to null to prevent the engine from being seen by clients while not changing modelindex. This behaviour allows inline models to remain solid yet be invisible."}, - {"frame", ".float", QW|NQ|CS, "The current frame the entity is meant to be displayed in. In CSQC, note the lerpfrac and frame2 fields as well. if it specifies a framegroup, the framegroup will autoanimate in ssqc, but not in csqc."}, - {"frame1time", ".float", CS, "The absolute time into the animation/framegroup specified by .frame."}, - {"frame2", ".float", CS, "The alternative frame. Visible only when lerpfrac is set to 1."}, - {"frame2time", ".float", CS, "The absolute time into the animation/framegroup specified by .frame2."}, - {"lerpfrac", ".float", CS, "If 0, use frame1 only. If 1, use frame2 only. Mix them together for values between."}, - {"skin", ".float", QW|NQ|CS, "The skin index to use. on a bsp entity, setting this to 1 will switch to the 'activated' texture instead. A negative value will be understood as a replacement contents value, so setting it to CONTENTS_WATER will make a movable pool of water."}, - {"effects", ".float", QW|NQ|CS, "Lots of random flags that change random effects. See EF_* constants."}, - {"mins", ".vector", QW|NQ|CS, "The minimum extent of the model (ie: the bottom-left coordinate relative to the entity's origin). Change via setsize. May also be changed by setmodel."}, - {"maxs", ".vector", QW|NQ|CS, "like mins, but in the other direction."}, - {"size", ".vector", QW|NQ|CS, "maxs-mins. Updated when the entity is relinked (by setorigin, setsize, setmodel)"}, + {"model", ".string", QW|NQ|CS, D("The model name that was set via setmodel, in theory. Often, this is cleared to null to prevent the engine from being seen by clients while not changing modelindex. This behaviour allows inline models to remain solid yet be invisible.")}, + {"frame", ".float", QW|NQ|CS, D("The current frame the entity is meant to be displayed in. In CSQC, note the lerpfrac and frame2 fields as well. if it specifies a framegroup, the framegroup will autoanimate in ssqc, but not in csqc.")}, + {"frame1time", ".float", CS, D("The absolute time into the animation/framegroup specified by .frame.")}, + {"frame2", ".float", CS, D("The alternative frame. Visible only when lerpfrac is set to 1.")}, + {"frame2time", ".float", CS, D("The absolute time into the animation/framegroup specified by .frame2.")}, + {"lerpfrac", ".float", CS, D("If 0, use frame1 only. If 1, use frame2 only. Mix them together for values between.")}, + {"skin", ".float", QW|NQ|CS, D("The skin index to use. on a bsp entity, setting this to 1 will switch to the 'activated' texture instead. A negative value will be understood as a replacement contents value, so setting it to CONTENTS_WATER will make a movable pool of water.")}, + {"effects", ".float", QW|NQ|CS, D("Lots of random flags that change random effects. See EF_* constants.")}, + {"mins", ".vector", QW|NQ|CS, D("The minimum extent of the model (ie: the bottom-left coordinate relative to the entity's origin). Change via setsize. May also be changed by setmodel.")}, + {"maxs", ".vector", QW|NQ|CS, D("like mins, but in the other direction.")}, + {"size", ".vector", QW|NQ|CS, D("maxs-mins. Updated when the entity is relinked (by setorigin, setsize, setmodel)")}, {"touch", ".void()", QW|NQ|CS}, {"use", ".void()", QW|NQ}, {"think", ".void()", QW|NQ|CS}, {"blocked", ".void()", QW|NQ|CS}, - {"nextthink", ".float", QW|NQ|CS, "The time at which the entity is next scheduled to fire its think event. For MOVETYPE_PUSH entities, this is relative to that entity's ltime field, for all other entities it is relative to the time gloal."}, + {"nextthink", ".float", QW|NQ|CS, D("The time at which the entity is next scheduled to fire its think event. For MOVETYPE_PUSH entities, this is relative to that entity's ltime field, for all other entities it is relative to the time gloal.")}, {"groundentity", ".entity", QW|NQ}, {"health", ".float", QW|NQ}, @@ -11379,7 +11390,7 @@ void PR_DumpPlatform_f(void) {"colormap", ".float", QW|NQ|CS}, {"team", ".float", QW|NQ}, {"max_health", ".float", QW|NQ}, - {"teleport_time", ".float", QW|NQ, "While active, prevents the player from using the +back command, also blocks waterjumping."}, + {"teleport_time", ".float", QW|NQ, D("While active, prevents the player from using the +back command, also blocks waterjumping.")}, {"armortype", ".float", QW|NQ}, {"armorvalue", ".float", QW|NQ}, {"waterlevel", ".float", QW|NQ}, @@ -11404,9 +11415,9 @@ void PR_DumpPlatform_f(void) {"noise3", ".string", QW|NQ}, {"end_sys_fields", "void", QW|NQ|CS|MENU}, - {"time", "float", MENU, "The current local time. Increases while paused."}, + {"time", "float", MENU, D("The current local time. Increases while paused.")}, {"input_timelength", "float", QW|NQ}, - {"input_angles", "vector", QW|NQ, "+x=DOWN"}, + {"input_angles", "vector", QW|NQ, D("+x=DOWN")}, {"input_movevalues", "vector", QW|NQ}, {"input_buttons", "float", QW|NQ}, {"input_impulse", "float", QW|NQ}, @@ -11421,19 +11432,19 @@ void PR_DumpPlatform_f(void) // {"trace_surfacename", "string", QW|NQ|CS}, {"trace_brush_id", "int", QW|NQ|CS}, {"trace_brush_faceid", "int", QW|NQ|CS}, - {"trace_surface_id", "int", QW|NQ|CS, "1-based. 0 if not known."}, - {"trace_bone_id", "int", QW|NQ|CS, "1-based. 0 if not known. typically needs MOVE_HITMODEL."}, - {"trace_triangle_id", "int", QW|NQ|CS, "1-based. 0 if not known."}, + {"trace_surface_id", "int", QW|NQ|CS, D("1-based. 0 if not known.")}, + {"trace_bone_id", "int", QW|NQ|CS, D("1-based. 0 if not known. typically needs MOVE_HITMODEL.")}, + {"trace_triangle_id", "int", QW|NQ|CS, D("1-based. 0 if not known.")}, - {"global_gravitydir", "vector", QW|NQ|CS, "The direction gravity should act in if not otherwise specified per entity.", 0,"'0 0 -1'"}, - {"serverid", "int", QW|NQ|CS, "The unique id of this server within the server cluster."}, + {"global_gravitydir", "vector", QW|NQ|CS, D("The direction gravity should act in if not otherwise specified per entity."), 0,"'0 0 -1'"}, + {"serverid", "int", QW|NQ|CS, D("The unique id of this server within the server cluster.")}, -#define comfieldfloat(name,desc) {#name, ".float", FL, desc}, -#define comfieldint(name,desc) {#name, ".int", FL, desc}, -#define comfieldvector(name,desc) {#name, ".vector", FL, desc}, -#define comfieldentity(name,desc) {#name, ".entity", FL, desc}, -#define comfieldstring(name,desc) {#name, ".string", FL, desc}, -#define comfieldfunction(name,typestr,desc) {#name, typestr, FL, desc}, +#define comfieldfloat(name,desc) {#name, ".float", FL, D(desc)}, +#define comfieldint(name,desc) {#name, ".int", FL, D(desc)}, +#define comfieldvector(name,desc) {#name, ".vector", FL, D(desc)}, +#define comfieldentity(name,desc) {#name, ".entity", FL, D(desc)}, +#define comfieldstring(name,desc) {#name, ".string", FL, D(desc)}, +#define comfieldfunction(name,typestr,desc) {#name, typestr, FL, D(desc)}, #define FL QW|NQ comqcfields #undef FL @@ -11541,20 +11552,20 @@ void PR_DumpPlatform_f(void) {"MOVETYPE_BOUNCE", "const float", QW|NQ|CS, NULL, MOVETYPE_BOUNCE}, {"MOVETYPE_BOUNCEMISSILE", "const float", QW|NQ|CS, NULL, MOVETYPE_BOUNCEMISSILE}, {"MOVETYPE_FOLLOW", "const float", QW|NQ|CS, NULL, MOVETYPE_FOLLOW}, - {"MOVETYPE_PUSHPULL", "const float", H2, NULL, MOVETYPE_H2PUSHPULL, "Identical to MOVETYPE_STEP. QC may treat the entity differently (typically with movechains)."}, - {"MOVETYPE_SWIM", "const float", H2, NULL, MOVETYPE_H2SWIM, "Equivelent to MOVETYPE_STEP, but additionally walkmove/movetogoal will not allow a movetype_swim entity to move out of water."}, - {"MOVETYPE_6DOF", "const float", QW|NQ|CS, "A glorified MOVETYPE_FLY. Players using this movetype will get some flightsim-like physics, with fully independant rotations (order-dependant transforms).", MOVETYPE_6DOF}, - {"MOVETYPE_WALLWALK", "const float", QW|NQ|CS, "Players using this movetype will be able to orient themselves to walls, and then run up them.", MOVETYPE_WALLWALK}, - {"MOVETYPE_PHYSICS", "const float", QW|NQ|CS, "Enable the use of ODE physics upon this entity.", MOVETYPE_PHYSICS}, + {"MOVETYPE_PUSHPULL", "const float", H2, D("Identical to MOVETYPE_STEP. QC may treat the entity differently (typically with movechains)."), MOVETYPE_H2PUSHPULL}, + {"MOVETYPE_SWIM", "const float", H2, D("Equivelent to MOVETYPE_STEP, but additionally walkmove/movetogoal will not allow a movetype_swim entity to move out of water."), MOVETYPE_H2SWIM}, + {"MOVETYPE_6DOF", "const float", QW|NQ|CS, D("A glorified MOVETYPE_FLY. Players using this movetype will get some flightsim-like physics, with fully independant rotations (order-dependant transforms)."), MOVETYPE_6DOF}, + {"MOVETYPE_WALLWALK", "const float", QW|NQ|CS, D("Players using this movetype will be able to orient themselves to walls, and then run up them."), MOVETYPE_WALLWALK}, + {"MOVETYPE_PHYSICS", "const float", QW|NQ|CS, D("Enable the use of ODE physics upon this entity."), MOVETYPE_PHYSICS}, {"SOLID_NOT", "const float", QW|NQ|CS, NULL, SOLID_NOT}, {"SOLID_TRIGGER", "const float", QW|NQ|CS, NULL, SOLID_TRIGGER}, {"SOLID_BBOX", "const float", QW|NQ|CS, NULL, SOLID_BBOX}, {"SOLID_SLIDEBOX", "const float", QW|NQ|CS, NULL, SOLID_SLIDEBOX}, - {"SOLID_BSP", "const float", QW|NQ|CS, "Does not collide against other SOLID_BSP entities. Normally paired with MOVETYPE_PUSH.", SOLID_BSP}, - {"SOLID_CORPSE", "const float", QW|NQ|CS, "Non-solid to SOLID_SLIDEBOX or other SOLID_CORPSE entities. For hitscan weapons to hit corpses, change the player's .solid value to SOLID_BBOX or so, perform the traceline, then revert the player's .solid value.", SOLID_CORPSE}, - {"SOLID_LADDER", "const float", QW|NQ|CS, "Obsolete and may be removed at some point. Use skin=CONTENT_LADDER and solid_bsp or solid_trigger instead.", SOLID_LADDER}, - {"SOLID_PORTAL", "const float", QW|NQ|CS, "CSG subtraction volume combined with entity transformations on impact.", SOLID_PORTAL}, + {"SOLID_BSP", "const float", QW|NQ|CS, D("Does not collide against other SOLID_BSP entities. Normally paired with MOVETYPE_PUSH."), SOLID_BSP}, + {"SOLID_CORPSE", "const float", QW|NQ|CS, D("Non-solid to SOLID_SLIDEBOX or other SOLID_CORPSE entities. For hitscan weapons to hit corpses, change the player's .solid value to SOLID_BBOX or so, perform the traceline, then revert the player's .solid value."), SOLID_CORPSE}, + {"SOLID_LADDER", "const float", QW|NQ|CS, D("Obsolete and may be removed at some point. Use skin=CONTENT_LADDER and solid_bsp or solid_trigger instead."), SOLID_LADDER}, + {"SOLID_PORTAL", "const float", QW|NQ|CS, D("CSG subtraction volume combined with entity transformations on impact."), SOLID_PORTAL}, {"SOLID_PHYSICS_BOX", "const float", QW|NQ|CS, NULL, SOLID_PHYSICS_BOX}, {"SOLID_PHYSICS_SPHERE", "const float", QW|NQ|CS, NULL, SOLID_PHYSICS_SPHERE}, {"SOLID_PHYSICS_CAPSULE", "const float", QW|NQ|CS, NULL, SOLID_PHYSICS_CAPSULE}, @@ -11601,25 +11612,25 @@ void PR_DumpPlatform_f(void) {"GE_ABSMAX", "const float", CS, "Valid for getentity. Guesses the entity's .absmax vector.", GE_ABSMAX}, // {"GE_LIGHT", "const float", CS, NULL, GE_LIGHT}, - {"GE_MODELINDEX", "const float", CS, "Valid for getentity. Guesses the entity's .modelindex float.", GE_MODELINDEX}, - {"GE_MODELINDEX2", "const float", CS, "Valid for getentity. Guesses the entity's .vw_index float.", GE_MODELINDEX2}, - {"GE_EFFECTS", "const float", CS, "Valid for getentity. Guesses the entity's .effects float.", GE_EFFECTS}, - {"GE_FRAME", "const float", CS, "Valid for getentity. Guesses the entity's .frame float.", GE_FRAME}, - {"GE_ANGLES", "const float", CS, "Valid for getentity. Guesses the entity's .angles vector.", GE_ANGLES}, - {"GE_FATNESS", "const float", CS, "Valid for getentity. Guesses the entity's .fatness float.", GE_FATNESS}, - {"GE_DRAWFLAGS", "const float", CS, "Valid for getentity. Guesses the entity's .drawflags float.", GE_DRAWFLAGS}, - {"GE_ABSLIGHT", "const float", CS, "Valid for getentity. Guesses the entity's .abslight float.", GE_ABSLIGHT}, - {"GE_GLOWMOD", "const float", CS, "Valid for getentity. Guesses the entity's .glowmod vector.", GE_GLOWMOD}, - {"GE_GLOWSIZE", "const float", CS, "Valid for getentity. Guesses the entity's .glowsize float.", GE_GLOWSIZE}, - {"GE_GLOWCOLOUR", "const float", CS, "Valid for getentity. Guesses the entity's .glowcolor float.", GE_GLOWCOLOUR}, - {"GE_RTSTYLE", "const float", CS, "Valid for getentity. Guesses the entity's .style float.", GE_RTSTYLE}, - {"GE_RTPFLAGS", "const float", CS, "Valid for getentity. Guesses the entity's .pflags float.", GE_RTPFLAGS}, - {"GE_RTCOLOUR", "const float", CS, "Valid for getentity. Guesses the entity's .color vector.", GE_RTCOLOUR}, - {"GE_RTRADIUS", "const float", CS, "Valid for getentity. Guesses the entity's .light_lev float.", GE_RTRADIUS}, - {"GE_TAGENTITY", "const float", CS, "Valid for getentity. Guesses the entity's .tag_entity float.", GE_TAGENTITY}, - {"GE_TAGINDEX", "const float", CS, "Valid for getentity. Guesses the entity's .tag_index float.", GE_TAGINDEX}, - {"GE_GRAVITYDIR", "const float", CS, "Valid for getentity. Guesses the entity's .gravitydir vector.", GE_GRAVITYDIR}, - {"GE_TRAILEFFECTNUM","const float",CS, "Valid for getentity. Guesses the entity's .traileffectnum float.", GE_TRAILEFFECTNUM}, + {"GE_MODELINDEX", "const float", CS, D("Valid for getentity. Guesses the entity's .modelindex float."), GE_MODELINDEX}, + {"GE_MODELINDEX2", "const float", CS, D("Valid for getentity. Guesses the entity's .vw_index float."), GE_MODELINDEX2}, + {"GE_EFFECTS", "const float", CS, D("Valid for getentity. Guesses the entity's .effects float."), GE_EFFECTS}, + {"GE_FRAME", "const float", CS, D("Valid for getentity. Guesses the entity's .frame float."), GE_FRAME}, + {"GE_ANGLES", "const float", CS, D("Valid for getentity. Guesses the entity's .angles vector."), GE_ANGLES}, + {"GE_FATNESS", "const float", CS, D("Valid for getentity. Guesses the entity's .fatness float."), GE_FATNESS}, + {"GE_DRAWFLAGS", "const float", CS, D("Valid for getentity. Guesses the entity's .drawflags float."), GE_DRAWFLAGS}, + {"GE_ABSLIGHT", "const float", CS, D("Valid for getentity. Guesses the entity's .abslight float."), GE_ABSLIGHT}, + {"GE_GLOWMOD", "const float", CS, D("Valid for getentity. Guesses the entity's .glowmod vector."), GE_GLOWMOD}, + {"GE_GLOWSIZE", "const float", CS, D("Valid for getentity. Guesses the entity's .glowsize float."), GE_GLOWSIZE}, + {"GE_GLOWCOLOUR", "const float", CS, D("Valid for getentity. Guesses the entity's .glowcolor float."), GE_GLOWCOLOUR}, + {"GE_RTSTYLE", "const float", CS, D("Valid for getentity. Guesses the entity's .style float."), GE_RTSTYLE}, + {"GE_RTPFLAGS", "const float", CS, D("Valid for getentity. Guesses the entity's .pflags float."), GE_RTPFLAGS}, + {"GE_RTCOLOUR", "const float", CS, D("Valid for getentity. Guesses the entity's .color vector."), GE_RTCOLOUR}, + {"GE_RTRADIUS", "const float", CS, D("Valid for getentity. Guesses the entity's .light_lev float."), GE_RTRADIUS}, + {"GE_TAGENTITY", "const float", CS, D("Valid for getentity. Guesses the entity's .tag_entity float."), GE_TAGENTITY}, + {"GE_TAGINDEX", "const float", CS, D("Valid for getentity. Guesses the entity's .tag_index float."), GE_TAGINDEX}, + {"GE_GRAVITYDIR", "const float", CS, D("Valid for getentity. Guesses the entity's .gravitydir vector."), GE_GRAVITYDIR}, + {"GE_TRAILEFFECTNUM","const float",CS, D("Valid for getentity. Guesses the entity's .traileffectnum float."), GE_TRAILEFFECTNUM}, {"DAMAGE_NO", "const float", QW|NQ, NULL, DAMAGE_NO}, {"DAMAGE_YES", "const float", QW|NQ, NULL, DAMAGE_YES}, @@ -11631,7 +11642,7 @@ void PR_DumpPlatform_f(void) {"CONTENT_SLIME", "const float", QW|NQ|CS, NULL, Q1CONTENTS_SLIME}, {"CONTENT_LAVA", "const float", QW|NQ|CS, NULL, Q1CONTENTS_LAVA}, {"CONTENT_SKY", "const float", QW|NQ|CS, NULL, Q1CONTENTS_SKY}, - {"CONTENT_LADDER", "const float", QW|NQ|CS, "If this value is assigned to a solid_bsp's .skin field, the entity will become a ladder volume.", Q1CONTENTS_LADDER}, + {"CONTENT_LADDER", "const float", QW|NQ|CS, D("If this value is assigned to a solid_bsp's .skin field, the entity will become a ladder volume."), Q1CONTENTS_LADDER}, {"CONTENTBIT_NONE", "const int", QW|NQ|CS, NULL, 0,STRINGIFY(FTECONTENTS_EMPTY)}, {"CONTENTBIT_SOLID", "const int", QW|NQ|CS, NULL, 0,STRINGIFY(FTECONTENTS_SOLID)}, @@ -11643,122 +11654,122 @@ void PR_DumpPlatform_f(void) {"CONTENTBIT_MONSTERCLIP", "const int", QW|NQ|CS, NULL, 0,STRINGIFY(FTECONTENTS_MONSTERCLIP)}, {"CONTENTBIT_BODY", "const int", QW|NQ|CS, NULL, 0,STRINGIFY(FTECONTENTS_BODY)}, {"CONTENTBIT_CORPSE", "const int", QW|NQ|CS, NULL, 0,STRINGIFY(FTECONTENTS_CORPSE)}, - {"CONTENTBIT_Q2LADDER", "const int", QW|NQ|CS, "Content bit specific to q2bsp", 0,STRINGIFY(Q2CONTENTS_LADDER)}, + {"CONTENTBIT_Q2LADDER", "const int", QW|NQ|CS, D("Content bit specific to q2bsp"), 0,STRINGIFY(Q2CONTENTS_LADDER)}, {"CONTENTBIT_SKY", "const int", QW|NQ|CS, NULL, 0,STRINGIFY(FTECONTENTS_SKY)"i"}, - {"CONTENTBITS_POINTSOLID", "const int", QW|NQ|CS, "Bits that traceline would normally consider solid", 0,"CONTENTBIT_SOLID|"STRINGIFY(Q2CONTENTS_WINDOW)"|CONTENTBIT_BODY"}, - {"CONTENTBITS_BOXSOLID", "const int", QW|NQ|CS, "Bits that tracebox would normally consider solid", 0,"CONTENTBIT_SOLID|"STRINGIFY(Q2CONTENTS_WINDOW)"|CONTENTBIT_BODY|CONTENTBIT_PLAYERCLIP"}, + {"CONTENTBITS_POINTSOLID", "const int", QW|NQ|CS, D("Bits that traceline would normally consider solid"), 0,"CONTENTBIT_SOLID|"STRINGIFY(Q2CONTENTS_WINDOW)"|CONTENTBIT_BODY"}, + {"CONTENTBITS_BOXSOLID", "const int", QW|NQ|CS, D("Bits that tracebox would normally consider solid"), 0,"CONTENTBIT_SOLID|"STRINGIFY(Q2CONTENTS_WINDOW)"|CONTENTBIT_BODY|CONTENTBIT_PLAYERCLIP"}, {"CONTENTBITS_FLUID", "const int", QW|NQ|CS, NULL, 0,"CONTENTBIT_WATER|CONTENTBIT_SLIME|CONTENTBIT_LAVA|CONTENTBIT_SKY"}, - {"SPA_POSITION", "const int", QW|NQ|CS, "These SPA_* constants are to specify which attribute is returned by the getsurfacepointattribute builtin", 0}, + {"SPA_POSITION", "const int", QW|NQ|CS, D("These SPA_* constants are to specify which attribute is returned by the getsurfacepointattribute builtin"), 0}, {"SPA_S_AXIS", "const int", QW|NQ|CS, NULL, 1}, {"SPA_T_AXIS", "const int", QW|NQ|CS, NULL, 2}, - {"SPA_R_AXIS", "const int", QW|NQ|CS, "aka: SPA_NORMAL", 3}, + {"SPA_R_AXIS", "const int", QW|NQ|CS, D("aka: SPA_NORMAL"), 3}, {"SPA_TEXCOORDS0", "const int", QW|NQ|CS, NULL, 4}, {"SPA_LIGHTMAP0_TEXCOORDS", "const int", QW|NQ|CS, NULL, 5}, {"SPA_LIGHTMAP0_COLOR", "const int", QW|NQ|CS, NULL, 6}, - {"CHAN_AUTO", "const float", QW|NQ|CS, "The automatic channel, play as many sounds on this channel as you want, and they'll all play, however the other channels will replace each other.", CHAN_AUTO}, + {"CHAN_AUTO", "const float", QW|NQ|CS, D("The automatic channel, play as many sounds on this channel as you want, and they'll all play, however the other channels will replace each other."), CHAN_AUTO}, {"CHAN_WEAPON", "const float", QW|NQ|CS, NULL, CHAN_WEAPON}, {"CHAN_VOICE", "const float", QW|NQ|CS, NULL, CHAN_VOICE}, {"CHAN_ITEM", "const float", QW|NQ|CS, NULL, CHAN_ITEM}, {"CHAN_BODY", "const float", QW|NQ|CS, NULL, CHAN_BODY}, - {"CHANF_RELIABLE", "const float", QW, "Only valid if the flags argument is not specified. The sound will be sent reliably, which is important if it is intended to replace looping sounds on doors etc.", 8}, + {"CHANF_RELIABLE", "const float", QW, D("Only valid if the flags argument is not specified. The sound will be sent reliably, which is important if it is intended to replace looping sounds on doors etc."), 8}, - {"SOUNDFLAG_RELIABLE", "const float", QW|NQ, "The sound will be sent reliably, and without regard to phs.", CF_RELIABLE}, - {"SOUNDFLAG_ABSVOLUME", "const float", /*QW|NQ|*/CS,"The sample's volume is not scaled by the volume cvar. Use with caution", CF_ABSVOLUME}, - {"SOUNDFLAG_FORCELOOP", "const float", QW|NQ|CS, "The sound will restart once it reaches the end of the sample.", CF_FORCELOOP}, - {"SOUNDFLAG_NOSPACIALISE", "const float", /*QW|NQ|*/CS,"The different audio channels are played at the same volume regardless of which way the player is facing, without needing to use 0 attenuation.", CF_NOSPACIALISE}, - {"SOUNDFLAG_NOREVERB", "const float", QW|NQ|CS, "Disables the use of underwater/reverb effects on this sound effect.", CF_NOREVERB}, - {"SOUNDFLAG_UNICAST", "const float", QW|NQ, "The sound will be heard only by the player specified by msg_entity.", CF_UNICAST}, - {"SOUNDFLAG_FOLLOW", "const float", QW|NQ|CS, "The sound's origin will updated to follow the emitting entity.", CF_FOLLOW}, - {"SOUNDFLAG_SENDVELOCITY", "const float", QW|NQ, "The entity's current velocity will be sent to the client, only useful if doppler is enabled.", CF_SENDVELOCITY}, + {"SOUNDFLAG_RELIABLE", "const float", QW|NQ, D("The sound will be sent reliably, and without regard to phs."), CF_RELIABLE}, + {"SOUNDFLAG_ABSVOLUME", "const float", /*QW|NQ|*/CS,D("The sample's volume is not scaled by the volume cvar. Use with caution"), CF_ABSVOLUME}, + {"SOUNDFLAG_FORCELOOP", "const float", QW|NQ|CS, D("The sound will restart once it reaches the end of the sample."), CF_FORCELOOP}, + {"SOUNDFLAG_NOSPACIALISE", "const float", /*QW|NQ|*/CS,D("The different audio channels are played at the same volume regardless of which way the player is facing, without needing to use 0 attenuation."), CF_NOSPACIALISE}, + {"SOUNDFLAG_NOREVERB", "const float", QW|NQ|CS, D("Disables the use of underwater/reverb effects on this sound effect."), CF_NOREVERB}, + {"SOUNDFLAG_UNICAST", "const float", QW|NQ, D("The sound will be heard only by the player specified by msg_entity."), CF_UNICAST}, + {"SOUNDFLAG_FOLLOW", "const float", QW|NQ|CS, D("The sound's origin will updated to follow the emitting entity."), CF_FOLLOW}, + {"SOUNDFLAG_SENDVELOCITY", "const float", QW|NQ, D("The entity's current velocity will be sent to the client, only useful if doppler is enabled."), CF_SENDVELOCITY}, - {"ATTN_NONE", "const float", QW|NQ|CS, "Sounds with this attenuation can be heard throughout the map", ATTN_NONE}, - {"ATTN_NORM", "const float", QW|NQ|CS, "Standard attenuation", ATTN_NORM}, - {"ATTN_IDLE", "const float", QW|NQ|CS, "Extra attenuation so that sounds don't travel too far.", 2}, //including these for completeness, despite them being defined by the gamecode rather than the engine api. - {"ATTN_STATIC", "const float", QW|NQ|CS, "Even more attenuation to avoid torches drowing out everything else throughout the map.", 3}, + {"ATTN_NONE", "const float", QW|NQ|CS, D("Sounds with this attenuation can be heard throughout the map"), ATTN_NONE}, + {"ATTN_NORM", "const float", QW|NQ|CS, D("Standard attenuation"), ATTN_NORM}, + {"ATTN_IDLE", "const float", QW|NQ|CS, D("Extra attenuation so that sounds don't travel too far."), 2}, //including these for completeness, despite them being defined by the gamecode rather than the engine api. + {"ATTN_STATIC", "const float", QW|NQ|CS, D("Even more attenuation to avoid torches drowing out everything else throughout the map."), 3}, //not putting other svcs here, qc shouldn't otherwise need to generate svcs directly. - {"SVC_CGAMEPACKET", "const float", QW|NQ, "Direct ssqc->csqc message. Must only be multicast. The data triggers a CSQC_Parse_Event call in the csqc for the csqc to read the contents. The server *may* insert length information for clients connected via proxies which are not able to cope with custom csqc payloads. This should only ever be used in conjunction with the MSG_MULTICAST destination.", svcfte_cgamepacket}, + {"SVC_CGAMEPACKET", "const float", QW|NQ, D("Direct ssqc->csqc message. Must only be multicast. The data triggers a CSQC_Parse_Event call in the csqc for the csqc to read the contents. The server *may* insert length information for clients connected via proxies which are not able to cope with custom csqc payloads. This should only ever be used in conjunction with the MSG_MULTICAST destination."), svcfte_cgamepacket}, #ifndef QUAKETC - {"MSG_BROADCAST", "const float", QW|NQ, "The byte(s) will be unreliably sent to all players. MSG_ constants are valid arguments to the Write* builtin family.", MSG_BROADCAST}, - {"MSG_ONE", "const float", QW|NQ, "The byte(s) will be reliably sent to the player specified in the msg_entity global. WARNING: in quakeworld servers without network preparsing enabled, this can result in illegible server messages (due to individual reliable messages being split between multiple backbuffers/packets). NQ has larger reliable buffers which avoids this issue, but still kicks the client.", MSG_ONE}, - {"MSG_ALL", "const float", QW|NQ, "The byte(s) will be reliably sent to all players.", MSG_ALL}, - {"MSG_INIT", "const float", QW|NQ, "The byte(s) will be written into the signon buffer. Clients will see these messages when they connect later. This buffer is only flushed on map changes, so spamming it _WILL_ result in overflows.", MSG_INIT}, + {"MSG_BROADCAST", "const float", QW|NQ, D("The byte(s) will be unreliably sent to all players. MSG_ constants are valid arguments to the Write* builtin family."), MSG_BROADCAST}, + {"MSG_ONE", "const float", QW|NQ, D("The byte(s) will be reliably sent to the player specified in the msg_entity global. WARNING: in quakeworld servers without network preparsing enabled, this can result in illegible server messages (due to individual reliable messages being split between multiple backbuffers/packets). NQ has larger reliable buffers which avoids this issue, but still kicks the client."), MSG_ONE}, + {"MSG_ALL", "const float", QW|NQ, D("The byte(s) will be reliably sent to all players."), MSG_ALL}, + {"MSG_INIT", "const float", QW|NQ, D("The byte(s) will be written into the signon buffer. Clients will see these messages when they connect later. This buffer is only flushed on map changes, so spamming it _WILL_ result in overflows."), MSG_INIT}, #endif - {"MSG_MULTICAST", "const float", QW|NQ, "The byte(s) will be written into the multicast buffer for more selective sending. Messages sent this way will never be split across packets, and using this for csqc-only messages will not break protocol translation.", MSG_MULTICAST}, - {"MSG_ENTITY", "const float", QW|NQ, "The byte(s) will be written into the entity buffer. This is a special value used only inside 'SendEntity' functions.", MSG_CSQC}, + {"MSG_MULTICAST", "const float", QW|NQ, D("The byte(s) will be written into the multicast buffer for more selective sending. Messages sent this way will never be split across packets, and using this for csqc-only messages will not break protocol translation."), MSG_MULTICAST}, + {"MSG_ENTITY", "const float", QW|NQ, D("The byte(s) will be written into the entity buffer. This is a special value used only inside 'SendEntity' functions."), MSG_CSQC}, - {"MULTICAST_ALL", "const float", QW|NQ, "The multicast message is unreliably sent to all players. MULTICAST_ constants are valid arguments for the multicast builtin, which ignores the specified origin when given this constant.", MULTICAST_ALL}, - {"MULTICAST_PHS", "const float", QW|NQ, "The multicast message is unreliably sent to only players that can potentially hear the specified origin. Its quite loose.", MULTICAST_PHS}, - {"MULTICAST_PVS", "const float", QW|NQ, "The multicast message is unreliably sent to only players that can potentially see the specified origin.", MULTICAST_PVS}, - {"MULTICAST_ONE", "const float", QW|NQ, "The multicast message is unreliably sent to the player specified in the msg_entity global. The specified origin is ignored.", MULTICAST_ONE}, - {"MULTICAST_ALL_R", "const float", QW|NQ, "The multicast message is reliably sent to all players. The specified origin is ignored.", MULTICAST_ALL_R}, - {"MULTICAST_PHS_R", "const float", QW|NQ, "The multicast message is reliably sent to only players that can potentially hear the specified origin. Players might still not receive it if they are out of range.", MULTICAST_PHS_R}, - {"MULTICAST_PVS_R", "const float", QW|NQ, "The multicast message is reliably sent to only players that can potentially see the specified origin. Players might still not receive it if they cannot see the event.", MULTICAST_PVS_R}, - {"MULTICAST_ONE_R", "const float", QW|NQ, "The multicast message is reliably sent to the player specified in the msg_entity global. The specified origin is ignored", MULTICAST_ONE_R}, + {"MULTICAST_ALL", "const float", QW|NQ, D("The multicast message is unreliably sent to all players. MULTICAST_ constants are valid arguments for the multicast builtin, which ignores the specified origin when given this constant."), MULTICAST_ALL}, + {"MULTICAST_PHS", "const float", QW|NQ, D("The multicast message is unreliably sent to only players that can potentially hear the specified origin. Its quite loose."), MULTICAST_PHS}, + {"MULTICAST_PVS", "const float", QW|NQ, D("The multicast message is unreliably sent to only players that can potentially see the specified origin."), MULTICAST_PVS}, + {"MULTICAST_ONE", "const float", QW|NQ, D("The multicast message is unreliably sent to the player specified in the msg_entity global. The specified origin is ignored."), MULTICAST_ONE}, + {"MULTICAST_ALL_R", "const float", QW|NQ, D("The multicast message is reliably sent to all players. The specified origin is ignored."), MULTICAST_ALL_R}, + {"MULTICAST_PHS_R", "const float", QW|NQ, D("The multicast message is reliably sent to only players that can potentially hear the specified origin. Players might still not receive it if they are out of range."), MULTICAST_PHS_R}, + {"MULTICAST_PVS_R", "const float", QW|NQ, D("The multicast message is reliably sent to only players that can potentially see the specified origin. Players might still not receive it if they cannot see the event."), MULTICAST_PVS_R}, + {"MULTICAST_ONE_R", "const float", QW|NQ, D("The multicast message is reliably sent to the player specified in the msg_entity global. The specified origin is ignored"), MULTICAST_ONE_R}, {"PRINT_LOW", "const float", QW, NULL, PRINT_LOW}, {"PRINT_MEDIUM", "const float", QW, NULL, PRINT_MEDIUM}, {"PRINT_HIGH", "const float", QW, NULL, PRINT_HIGH}, {"PRINT_CHAT", "const float", QW, NULL, PRINT_CHAT}, - {"PVSF_NORMALPVS", "const float", QW|NQ, "Filter first by PVS, then filter this entity using tracelines if sv_cullentities is enabled.", PVSF_NORMALPVS}, - {"PVSF_NOTRACECHECK", "const float", QW|NQ, "Filter strictly by PVS.", PVSF_NOTRACECHECK}, - {"PVSF_USEPHS", "const float", QW|NQ, "Send if we're close enough to be able to hear this entity.", PVSF_USEPHS}, - {"PVSF_IGNOREPVS", "const float", QW|NQ, "Ignores pvs. This entity is visible whereever you are on the map.", PVSF_IGNOREPVS}, - {"PVSF_NOREMOVE", "const float", QW|NQ, "Once visible to a client, this entity will remain visible. This can be useful for csqc and corpses.", PVSF_NOREMOVE}, + {"PVSF_NORMALPVS", "const float", QW|NQ, D("Filter first by PVS, then filter this entity using tracelines if sv_cullentities is enabled."), PVSF_NORMALPVS}, + {"PVSF_NOTRACECHECK", "const float", QW|NQ, D("Filter strictly by PVS."), PVSF_NOTRACECHECK}, + {"PVSF_USEPHS", "const float", QW|NQ, D("Send if we're close enough to be able to hear this entity."), PVSF_USEPHS}, + {"PVSF_IGNOREPVS", "const float", QW|NQ, D("Ignores pvs. This entity is visible whereever you are on the map."), PVSF_IGNOREPVS}, + {"PVSF_NOREMOVE", "const float", QW|NQ, D("Once visible to a client, this entity will remain visible. This can be useful for csqc and corpses."), PVSF_NOREMOVE}, //most of these are there for documentation rather than anything else. - {"INFOKEY_P_IP", "const string", QW|NQ, "The apparent ip address of the client. This may be a proxy's ip address.", 0, "\"ip\""}, - {"INFOKEY_P_REALIP", "const string", QW|NQ, "If sv_getrealip is set, this gives the ip as determine using that algorithm.", 0, "\"realip\""}, - {"INFOKEY_P_CSQCACTIVE","const string", QW|NQ, "Client has csqc enabled. CSQC ents etc will be sent to this player.", 0, "\"csqcactive\""}, + {"INFOKEY_P_IP", "const string", QW|NQ, D("The apparent ip address of the client. This may be a proxy's ip address."), 0, "\"ip\""}, + {"INFOKEY_P_REALIP", "const string", QW|NQ, D("If sv_getrealip is set, this gives the ip as determine using that algorithm."), 0, "\"realip\""}, + {"INFOKEY_P_CSQCACTIVE","const string", QW|NQ, D("Client has csqc enabled. CSQC ents etc will be sent to this player."), 0, "\"csqcactive\""}, {"INFOKEY_P_SVPING", "const string", QW|NQ, NULL, 0, "\"svping\""}, - {"INFOKEY_P_GUID", "const string", QW|NQ, "Some hash string which should be reasonably unique to this player's quake installation.", 0, "\"guid\""}, + {"INFOKEY_P_GUID", "const string", QW|NQ, D("Some hash string which should be reasonably unique to this player's quake installation."), 0, "\"guid\""}, {"INFOKEY_P_CHALLENGE", "const string", QW|NQ, NULL, 0, "\"challenge\""}, {"INFOKEY_P_USERID", "const string", QW|NQ, NULL, 0, "\"*userid\""}, - {"INFOKEY_P_DOWNLOADPCT","const string",QW|NQ, "The client's download percentage for the current file. Additional files are not known.", 0, "\"download\""}, + {"INFOKEY_P_DOWNLOADPCT","const string",QW|NQ, D("The client's download percentage for the current file. Additional files are not known."), 0, "\"download\""}, {"INFOKEY_P_TRUSTLEVEL","const string", QW|NQ, NULL, 0, "\"trustlevel\""}, - {"INFOKEY_P_PROTOCOL", "const string", QW|NQ, "The network protocol the client is using to connect to the server.", 0, "\"protocol\""}, - {"INFOKEY_P_VIP", "const string", QW|NQ, "1 if the player has the VIP 'penalty'.", 0, "\"*VIP\""}, - {"INFOKEY_P_ISMUTED", "const string", QW|NQ, "1 if the player has the 'mute' penalty and is not allowed to use the say/say_team commands.", 0, "\"*ismuted\""}, - {"INFOKEY_P_ISDEAF", "const string", QW|NQ, "1 if the player has the 'deaf' penalty and cannot see other people's say/say_team commands.", 0, "\"*isdeaf\""}, - {"INFOKEY_P_ISCRIPPLED","const string", QW|NQ, "1 if the player has the cripple penalty, and their movement values are ignored (.movement is locked to 0).", 0, "\"*ismuted\""}, - {"INFOKEY_P_ISCUFFED", "const string", QW|NQ, "1 if the player has the cuff penalty, and is unable to attack or use impulses(.button0 and .impulse fields are locked to 0).", 0, "\"*ismuted\""}, - {"INFOKEY_P_ISLAGGED", "const string", QW|NQ, "1 if the player has the fakelag penalty and has an extra 200ms of lag.", 0, "\"*ismuted\""}, - {"INFOKEY_P_PING", "const string", CS|QW|NQ, "The player's ping time, in milliseconds.", 0, "\"ping\""}, - {"INFOKEY_P_NAME", "const string", CS|QW|NQ, "The player's name.", 0, "\"name\""}, - {"INFOKEY_P_SPECTATOR", "const string", CS|QW|NQ, "Whether the player is a spectator or not.", 0, "\"*spectator\""}, - {"INFOKEY_P_TOPCOLOR", "const string", CS|QW|NQ, "The player's upper/shirt colour (palette index).", 0, "\"topcolor\""}, - {"INFOKEY_P_BOTTOMCOLOR","const string", CS|QW|NQ, "The player's lower/pants/trouser colour (palette index).", 0, "\"bottomcolor\""}, - {"INFOKEY_P_TOPCOLOR_RGB","const string", CS, "The player's upper/shirt colour as an rgb value in a format usable with stov.", 0, "\"topcolor_rgb\""}, - {"INFOKEY_P_BOTTOMCOLOR_RGB","const string", CS, "The player's lower/pants/trouser colour as an rgb value in a format usable with stov.", 0, "\"bottomcolor_rgb\""}, - {"INFOKEY_P_MUTED", "const string", CS, "0: we can see the result of the player's say/say_team commands. 1: we see no say/say_team messages from this player. Use the ignore command to toggle this value.", 0, "\"ignored\""}, - {"INFOKEY_P_VOIP_MUTED","const string", CS, "0: we can hear this player when they speak (assuming voip is generally enabled). 1: we ignore everything this player says. Use cl_voip_mute to change the values.", 0, "\"vignored\""}, - {"INFOKEY_P_ENTERTIME", "const string", CS, "Reads the timestamp at which the player entered the game, in terms of csqc's time global.", 0, "\"entertime\""}, - {"INFOKEY_P_FRAGS", "const string", CS, "Reads a player's frag count.", 0, "\"frags\""}, - {"INFOKEY_P_PACKETLOSS","const string", CS, "Reads a player's packetloss, as a percentage.", 0, "\"pl\""}, - {"INFOKEY_P_VOIPSPEAKING","const string", CS, "Boolean value that says whether the given player is currently sending voice information.", 0, "\"voipspeaking\""}, - {"INFOKEY_P_VOIPLOUDNESS","const string", CS, "Only valid for the local player. Gives a value between 0 and 1 to indicate to the user how loud their mic is.", 0, "\"voiploudness\""}, + {"INFOKEY_P_PROTOCOL", "const string", QW|NQ, D("The network protocol the client is using to connect to the server."), 0, "\"protocol\""}, + {"INFOKEY_P_VIP", "const string", QW|NQ, D("1 if the player has the VIP 'penalty'."), 0, "\"*VIP\""}, + {"INFOKEY_P_ISMUTED", "const string", QW|NQ, D("1 if the player has the 'mute' penalty and is not allowed to use the say/say_team commands."), 0, "\"*ismuted\""}, + {"INFOKEY_P_ISDEAF", "const string", QW|NQ, D("1 if the player has the 'deaf' penalty and cannot see other people's say/say_team commands."), 0, "\"*isdeaf\""}, + {"INFOKEY_P_ISCRIPPLED","const string", QW|NQ, D("1 if the player has the cripple penalty, and their movement values are ignored (.movement is locked to 0)."), 0, "\"*ismuted\""}, + {"INFOKEY_P_ISCUFFED", "const string", QW|NQ, D("1 if the player has the cuff penalty, and is unable to attack or use impulses(.button0 and .impulse fields are locked to 0)."), 0, "\"*ismuted\""}, + {"INFOKEY_P_ISLAGGED", "const string", QW|NQ, D("1 if the player has the fakelag penalty and has an extra 200ms of lag."), 0, "\"*ismuted\""}, + {"INFOKEY_P_PING", "const string", CS|QW|NQ, D("The player's ping time, in milliseconds."), 0, "\"ping\""}, + {"INFOKEY_P_NAME", "const string", CS|QW|NQ, D("The player's name."), 0, "\"name\""}, + {"INFOKEY_P_SPECTATOR", "const string", CS|QW|NQ, D("Whether the player is a spectator or not."), 0, "\"*spectator\""}, + {"INFOKEY_P_TOPCOLOR", "const string", CS|QW|NQ, D("The player's upper/shirt colour (palette index)."), 0, "\"topcolor\""}, + {"INFOKEY_P_BOTTOMCOLOR","const string", CS|QW|NQ, D("The player's lower/pants/trouser colour (palette index)."), 0, "\"bottomcolor\""}, + {"INFOKEY_P_TOPCOLOR_RGB","const string", CS, D("The player's upper/shirt colour as an rgb value in a format usable with stov."), 0, "\"topcolor_rgb\""}, + {"INFOKEY_P_BOTTOMCOLOR_RGB","const string", CS, D("The player's lower/pants/trouser colour as an rgb value in a format usable with stov."), 0, "\"bottomcolor_rgb\""}, + {"INFOKEY_P_MUTED", "const string", CS, D("0: we can see the result of the player's say/say_team commands. 1: we see no say/say_team messages from this player. Use the ignore command to toggle this value."), 0, "\"ignored\""}, + {"INFOKEY_P_VOIP_MUTED","const string", CS, D("0: we can hear this player when they speak (assuming voip is generally enabled). 1: we ignore everything this player says. Use cl_voip_mute to change the values."), 0, "\"vignored\""}, + {"INFOKEY_P_ENTERTIME", "const string", CS, D("Reads the timestamp at which the player entered the game, in terms of csqc's time global."), 0, "\"entertime\""}, + {"INFOKEY_P_FRAGS", "const string", CS, D("Reads a player's frag count."), 0, "\"frags\""}, + {"INFOKEY_P_PACKETLOSS","const string", CS, D("Reads a player's packetloss, as a percentage."), 0, "\"pl\""}, + {"INFOKEY_P_VOIPSPEAKING","const string", CS, D("Boolean value that says whether the given player is currently sending voice information."), 0, "\"voipspeaking\""}, + {"INFOKEY_P_VOIPLOUDNESS","const string", CS, D("Only valid for the local player. Gives a value between 0 and 1 to indicate to the user how loud their mic is."), 0, "\"voiploudness\""}, - {"SERVERKEY_IP", "const string", CS,"The address of the server we connected to.", 0, "\"ip\""}, - {"SERVERKEY_SERVERNAME","const string", CS,"The hostname that was last passed to the connect command.", 0, "\"servername\""}, - {"SERVERKEY_CONSTATE", "const string", CS,"The current connection state. Will be set to one of: disconnected (menu-only mode), active (gamestate received and loaded), connecting(connecting, downloading, or precaching content, aka: loading screen).", 0, "\"constate\""}, - {"SERVERKEY_TRANSFERRING","const string",CS,"Set to the hostname of the server that we are attempting to connect or transfer to.", 0, "\"transferring\""}, - {"SERVERKEY_LOADSTATE", "const string", CS, "loadstage, loading image name, current step, max steps\nStages are: 1=connecting, 2=serverside, 3=clientside\nKey will be empty if we are not loading.", 0, "\"loadstate\""}, - {"SERVERKEY_PAUSESTATE","const string", CS, "1 if the server claimed to be paused. 0 otherwise", 0, "\"pausestate\""}, - {"SERVERKEY_DLSTATE", "const string", CS, "The progress of any current downloads. Empty string if no download is active, otherwise a tokenizable string containing this info:\nfiles-remaining, total-size, unknown-sizes-flag, file-localname, file-remotename, file-percent, file-rate, file-received-bytes, file-total-bytes\nIf the current file info is omitted, then we are waiting for a download to start.", 0, "\"dlstate\""}, - {"SERVERKEY_PROTOCOL", "const string", CS, "The protocol we are connected to the server with.", 0, "\"protocol\""}, - {"SERVERKEY_MAXPLAYERS","const string", CS, "The protocol we are connected to the server with.", 0, "\"maxplayers\""}, + {"SERVERKEY_IP", "const string", CS,D("The address of the server we connected to."), 0, "\"ip\""}, + {"SERVERKEY_SERVERNAME","const string", CS,D("The hostname that was last passed to the connect command."), 0, "\"servername\""}, + {"SERVERKEY_CONSTATE", "const string", CS,D("The current connection state. Will be set to one of: disconnected (menu-only mode), active (gamestate received and loaded), connecting(connecting, downloading, or precaching content, aka: loading screen)."), 0, "\"constate\""}, + {"SERVERKEY_TRANSFERRING","const string",CS,D("Set to the hostname of the server that we are attempting to connect or transfer to."), 0, "\"transferring\""}, + {"SERVERKEY_LOADSTATE", "const string", CS, D("loadstage, loading image name, current step, max steps\nStages are: 1=connecting, 2=serverside, 3=clientside\nKey will be empty if we are not loading."), 0, "\"loadstate\""}, + {"SERVERKEY_PAUSESTATE","const string", CS, D("1 if the server claimed to be paused. 0 otherwise"), 0, "\"pausestate\""}, + {"SERVERKEY_DLSTATE", "const string", CS, D("The progress of any current downloads. Empty string if no download is active, otherwise a tokenizable string containing this info:\nfiles-remaining, total-size, unknown-sizes-flag, file-localname, file-remotename, file-percent, file-rate, file-received-bytes, file-total-bytes\nIf the current file info is omitted, then we are waiting for a download to start."), 0, "\"dlstate\""}, + {"SERVERKEY_PROTOCOL", "const string", CS, D("The protocol we are connected to the server with."), 0, "\"protocol\""}, + {"SERVERKEY_MAXPLAYERS","const string", CS, D("The protocol we are connected to the server with."), 0, "\"maxplayers\""}, - {"STUFFCMD_IGNOREINDEMO","const float", QW|NQ, "The protocol we are connected to the server with.", STUFFCMD_IGNOREINDEMO}, - {"STUFFCMD_DEMOONLY", "const float", QW|NQ, "The protocol we are connected to the server with.", STUFFCMD_DEMOONLY}, + {"STUFFCMD_IGNOREINDEMO","const float", QW|NQ, D("The protocol we are connected to the server with."), STUFFCMD_IGNOREINDEMO}, + {"STUFFCMD_DEMOONLY", "const float", QW|NQ, D("The protocol we are connected to the server with."), STUFFCMD_DEMOONLY}, -/* {"SOUND_RELIABLE", "const float", QW|NQ, "The sound will be sent reliably, and without regard to phs.", CF_RELIABLE}, - {"SOUND_FORCELOOP", "const float", QW|NQ|CS,"The sound will restart once it reaches the end of the sample.", CF_FORCELOOP}, - {"SOUND_NOSPACIALISE", "const float", QW|NQ|CS,"The different audio channels are played at the same volume regardless of which way the player is facing, without needing to use 0 attenuation.", CF_NOSPACIALISE}, - {"SOUND_ABSVOLUME", "const float", QW|NQ|CS,"The sample's volume is not scaled by the volume cvar. Use with caution", CF_ABSVOLUME}, +/* {"SOUND_RELIABLE", "const float", QW|NQ, D("The sound will be sent reliably, and without regard to phs."), CF_RELIABLE}, + {"SOUND_FORCELOOP", "const float", QW|NQ|CS,D("The sound will restart once it reaches the end of the sample."), CF_FORCELOOP}, + {"SOUND_NOSPACIALISE", "const float", QW|NQ|CS,D("The different audio channels are played at the same volume regardless of which way the player is facing, without needing to use 0 attenuation."), CF_NOSPACIALISE}, + {"SOUND_ABSVOLUME", "const float", QW|NQ|CS,D("The sample's volume is not scaled by the volume cvar. Use with caution"), CF_ABSVOLUME}, */ // edict.flags {"FL_FLY", "const float", QW|NQ|CS, NULL, FL_FLY}, @@ -11773,32 +11784,32 @@ void PR_DumpPlatform_f(void) {"FL_PARTIALGROUND", "const float", QW|NQ|CS, NULL, FL_PARTIALGROUND}, {"FL_WATERJUMP", "const float", QW|NQ|CS, NULL, FL_WATERJUMP}, {"FL_JUMPRELEASED", "const float", NQ|CS, NULL, FL_JUMPRELEASED}, - {"FL_FINDABLE_NONSOLID","const float", QW|NQ|CS, "Allows this entity to be found with findradius", FL_FINDABLE_NONSOLID}, + {"FL_FINDABLE_NONSOLID","const float", QW|NQ|CS, D("Allows this entity to be found with findradius"), FL_FINDABLE_NONSOLID}, {"FL_MOVECHAIN_ANGLE", "const float", H2, NULL, FL_MOVECHAIN_ANGLE}, - {"FL_LAGGEDMOVE", "const float", QW|NQ, "Enables anti-lag on rockets etc.", FLQW_LAGGEDMOVE}, + {"FL_LAGGEDMOVE", "const float", QW|NQ, D("Enables anti-lag on rockets etc."), FLQW_LAGGEDMOVE}, {"FL_CLASS_DEPENDENT", "const float", H2, NULL, FL_CLASS_DEPENDENT}, {"MOVE_NORMAL", "const float", QW|NQ|CS, NULL, MOVE_NORMAL}, - {"MOVE_NOMONSTERS", "const float", QW|NQ|CS, "The trace will ignore all non-solid_bsp entities.", MOVE_NOMONSTERS}, - {"MOVE_MISSILE", "const float", QW|NQ|CS, "The trace will use a bbox size of +/- 15 against entities with FL_MONSTER set.", MOVE_MISSILE}, - {"MOVE_HITMODEL", "const float", QW|NQ|CS, "Traces will impact the actual mesh of the model instead of merely their bounding box. Should generally only be used for tracelines. Note that this flag is unreliable as an object can animate through projectiles. The bounding box MUST be set to completely encompass the entity or those extra areas will be non-solid (leaving a hole for things to go through).", MOVE_HITMODEL}, - {"MOVE_TRIGGERS", "const float", QW|NQ|CS, "This trace type will impact only triggers. It will ignore non-solid entities.", MOVE_TRIGGERS}, - {"MOVE_EVERYTHING", "const float", QW|NQ|CS, "This type of trace will hit solids and triggers alike. Even non-solid entities.", MOVE_EVERYTHING}, - {"MOVE_LAGGED", "const float", QW|NQ, "Will use antilag based upon the player's latency. Traces will be performed against old positions for entities instead of their current origin.", MOVE_LAGGED}, - {"MOVE_ENTCHAIN", "const float", QW|NQ|CS, "Returns a list of entities impacted via the trace_ent.chain field", MOVE_ENTCHAIN}, - {"MOVE_OTHERONLY", "const float", QW|NQ|CS, "Traces that use this trace type will collide against *only* the entity specified via the 'other' global, and will ignore all owner/solid_not/dimension etc rules, they will still adhere to contents and bsp/bbox rules though.", MOVE_OTHERONLY}, + {"MOVE_NOMONSTERS", "const float", QW|NQ|CS, D("The trace will ignore all non-solid_bsp entities."), MOVE_NOMONSTERS}, + {"MOVE_MISSILE", "const float", QW|NQ|CS, D("The trace will use a bbox size of +/- 15 against entities with FL_MONSTER set."), MOVE_MISSILE}, + {"MOVE_HITMODEL", "const float", QW|NQ|CS, D("Traces will impact the actual mesh of the model instead of merely their bounding box. Should generally only be used for tracelines. Note that this flag is unreliable as an object can animate through projectiles. The bounding box MUST be set to completely encompass the entity or those extra areas will be non-solid (leaving a hole for things to go through)."), MOVE_HITMODEL}, + {"MOVE_TRIGGERS", "const float", QW|NQ|CS, D("This trace type will impact only triggers. It will ignore non-solid entities."), MOVE_TRIGGERS}, + {"MOVE_EVERYTHING", "const float", QW|NQ|CS, D("This type of trace will hit solids and triggers alike. Even non-solid entities."), MOVE_EVERYTHING}, + {"MOVE_LAGGED", "const float", QW|NQ, D("Will use antilag based upon the player's latency. Traces will be performed against old positions for entities instead of their current origin."), MOVE_LAGGED}, + {"MOVE_ENTCHAIN", "const float", QW|NQ|CS, D("Returns a list of entities impacted via the trace_ent.chain field"), MOVE_ENTCHAIN}, + {"MOVE_OTHERONLY", "const float", QW|NQ|CS, D("Traces that use this trace type will collide against *only* the entity specified via the 'other' global, and will ignore all owner/solid_not/dimension etc rules, they will still adhere to contents and bsp/bbox rules though."), MOVE_OTHERONLY}, - {"RESTYPE_MODEL", "const float", ALL, "RESTYPE_* constants are used as arguments with the resourcestatus builtin.", RESTYPE_MODEL}, - {"RESTYPE_SOUND", "const float", ALL, "precache_sound", RESTYPE_SOUND}, - {"RESTYPE_PARTICLE", "const float", ALL, "particleeffectnum", RESTYPE_PARTICLE}, - {"RESTYPE_PIC", "const float", CS|MENU, "precache_pic. Status results are an amalgomation of the textures used by the named shader.", RESTYPE_SHADER}, - {"RESTYPE_SKIN", "const float", CS|MENU, "setcustomskin", RESTYPE_SKIN}, - {"RESTYPE_TEXTURE", "const float", CS|MENU, "Individual textures within shaders. These are not directly usable, but may be named as part of a skin file, or a shader.", RESTYPE_TEXTURE}, - {"RESSTATE_NOTKNOWN", "const float", ALL, "RESSTATE_* constants are return values from the resourcestatus builtin. The engine doesn't know about the resource if it is in this state. This means you will need to precache it. Attempting to use it anyway may result in warnings, errors, or silently succeed, depending on engine version and resource type.", RESSTATE_NOTKNOWN}, - {"RESSTATE_NOTLOADED", "const float", ALL, "The resource was precached, but has been flushed and there has not been an attempt to reload it. If you use the resource normally, chances are it'll be loaded but at the cost of a stall.", RESSTATE_NOTLOADED}, - {"RESSTATE_LOADING", "const float", ALL, "Resources in this this state are queued for loading, and will be loaded at the engine's convienience. If you attempt to query the resource now, the engine will stall until the result is available. sounds in this state may be delayed, while models/pics/shaders may be invisible.", RESSTATE_LOADING}, - {"RESSTATE_FAILED", "const float", ALL, "Resources in this state are unusable/could not be loaded. You will get placeholders or dummy results. Queries will not stall the engine. The engine may display placeholder content.", RESSTATE_FAILED}, - {"RESSTATE_LOADED", "const float", ALL, "Resources in this state are finally usable, everything will work okay. Hurrah. Queries will not stall the engine.", RESSTATE_LOADED}, + {"RESTYPE_MODEL", "const float", ALL, D("RESTYPE_* constants are used as arguments with the resourcestatus builtin."), RESTYPE_MODEL}, + {"RESTYPE_SOUND", "const float", ALL, D("precache_sound"), RESTYPE_SOUND}, + {"RESTYPE_PARTICLE", "const float", ALL, D("particleeffectnum"), RESTYPE_PARTICLE}, + {"RESTYPE_PIC", "const float", CS|MENU, D("precache_pic. Status results are an amalgomation of the textures used by the named shader."), RESTYPE_SHADER}, + {"RESTYPE_SKIN", "const float", CS|MENU, D("setcustomskin"), RESTYPE_SKIN}, + {"RESTYPE_TEXTURE", "const float", CS|MENU, D("Individual textures within shaders. These are not directly usable, but may be named as part of a skin file, or a shader."), RESTYPE_TEXTURE}, + {"RESSTATE_NOTKNOWN", "const float", ALL, D("RESSTATE_* constants are return values from the resourcestatus builtin. The engine doesn't know about the resource if it is in this state. This means you will need to precache it. Attempting to use it anyway may result in warnings, errors, or silently succeed, depending on engine version and resource type."), RESSTATE_NOTKNOWN}, + {"RESSTATE_NOTLOADED", "const float", ALL, D("The resource was precached, but has been flushed and there has not been an attempt to reload it. If you use the resource normally, chances are it'll be loaded but at the cost of a stall."), RESSTATE_NOTLOADED}, + {"RESSTATE_LOADING", "const float", ALL, D("Resources in this this state are queued for loading, and will be loaded at the engine's convienience. If you attempt to query the resource now, the engine will stall until the result is available. sounds in this state may be delayed, while models/pics/shaders may be invisible."), RESSTATE_LOADING}, + {"RESSTATE_FAILED", "const float", ALL, D("Resources in this state are unusable/could not be loaded. You will get placeholders or dummy results. Queries will not stall the engine. The engine may display placeholder content."), RESSTATE_FAILED}, + {"RESSTATE_LOADED", "const float", ALL, D("Resources in this state are finally usable, everything will work okay. Hurrah. Queries will not stall the engine."), RESSTATE_LOADED}, {"EF_BRIGHTFIELD", "const float", QW|NQ|CS, NULL, EF_BRIGHTFIELD}, {"EF_MUZZLEFLASH", "const float", NQ|CS, NULL, EF_MUZZLEFLASH}, {"EF_BRIGHTLIGHT", "const float", QW|NQ|CS, NULL, EF_BRIGHTLIGHT}, @@ -11806,27 +11817,27 @@ void PR_DumpPlatform_f(void) {"EF_FLAG1", "const float", QW , NULL, QWEF_FLAG1}, {"EF_FLAG2", "const float", QW , NULL, QWEF_FLAG2}, {"EF_NODRAW", "const float", NQ|CS, NULL, NQEF_NODRAW}, - {"EF_ADDITIVE", "const float", NQ|CS, "The entity will be drawn with an additive blend.", NQEF_ADDITIVE}, - {"EF_BLUE", "const float", QW|NQ|CS, "A blue glow", EF_BLUE}, - {"EF_RED", "const float", QW|NQ|CS, "A red glow", EF_RED}, - {"EF_GREEN", "const float", QW|NQ|CS, "A green glow", EF_GREEN}, - {"EF_FULLBRIGHT", "const float", QW|NQ|CS, "This entity will ignore lighting", EF_FULLBRIGHT}, - {"EF_NOSHADOW", "const float", QW|NQ|CS, "This entity will not cast shadows", EF_NOSHADOW}, - {"EF_NODEPTHTEST", "const float", QW|NQ|CS, "This entity will be drawn over the top of other things that are closer.", EF_NODEPTHTEST}, + {"EF_ADDITIVE", "const float", NQ|CS, D("The entity will be drawn with an additive blend."), NQEF_ADDITIVE}, + {"EF_BLUE", "const float", QW|NQ|CS, D("A blue glow"), EF_BLUE}, + {"EF_RED", "const float", QW|NQ|CS, D("A red glow"), EF_RED}, + {"EF_GREEN", "const float", QW|NQ|CS, D("A green glow"), EF_GREEN}, + {"EF_FULLBRIGHT", "const float", QW|NQ|CS, D("This entity will ignore lighting"), EF_FULLBRIGHT}, + {"EF_NOSHADOW", "const float", QW|NQ|CS, D("This entity will not cast shadows"), EF_NOSHADOW}, + {"EF_NODEPTHTEST", "const float", QW|NQ|CS, D("This entity will be drawn over the top of other things that are closer."), EF_NODEPTHTEST}, - {"EF_NOMODELFLAGS", "const float", QW|NQ, "Surpresses the normal flags specified in the model.", EF_NOMODELFLAGS}, + {"EF_NOMODELFLAGS", "const float", QW|NQ, D("Surpresses the normal flags specified in the model."), EF_NOMODELFLAGS}, {"MF_ROCKET", "const float", QW|NQ|CS, NULL, EF_MF_ROCKET>>24}, {"MF_GRENADE", "const float", QW|NQ|CS, NULL, EF_MF_GRENADE>>24}, - {"MF_GIB", "const float", QW|NQ|CS, "Regular blood trail", EF_MF_GIB>>24}, + {"MF_GIB", "const float", QW|NQ|CS, D("Regular blood trail"), EF_MF_GIB>>24}, {"MF_ROTATE", "const float", QW|NQ|CS, NULL, EF_MF_ROTATE>>24}, - {"MF_TRACER", "const float", QW|NQ|CS, "AKA: green scrag trail", EF_MF_TRACER>>24}, - {"MF_ZOMGIB", "const float", QW|NQ|CS, "Dark blood trail", EF_MF_ZOMGIB>>24}, - {"MF_TRACER2", "const float", QW|NQ|CS, "AKA: hellknight projectile trail", EF_MF_TRACER2>>24}, - {"MF_TRACER3", "const float", QW|NQ|CS, "AKA: purple vore trail", EF_MF_TRACER3>>24}, + {"MF_TRACER", "const float", QW|NQ|CS, D("AKA: green scrag trail"), EF_MF_TRACER>>24}, + {"MF_ZOMGIB", "const float", QW|NQ|CS, D("Dark blood trail"), EF_MF_ZOMGIB>>24}, + {"MF_TRACER2", "const float", QW|NQ|CS, D("AKA: hellknight projectile trail"), EF_MF_TRACER2>>24}, + {"MF_TRACER3", "const float", QW|NQ|CS, D("AKA: purple vore trail"), EF_MF_TRACER3>>24}, - {"SL_ORG_TL", "const float", QW|NQ, "Used with showpic etc, specifies that the x+y values are relative to the top-left of the screen", SL_ORG_TL}, + {"SL_ORG_TL", "const float", QW|NQ, D("Used with showpic etc, specifies that the x+y values are relative to the top-left of the screen"), SL_ORG_TL}, {"SL_ORG_TR", "const float", QW|NQ, NULL, SL_ORG_TR}, {"SL_ORG_BL", "const float", QW|NQ, NULL, SL_ORG_BL}, {"SL_ORG_BR", "const float", QW|NQ, NULL, SL_ORG_BR}, @@ -11836,9 +11847,9 @@ void PR_DumpPlatform_f(void) {"SL_ORG_ML", "const float", QW|NQ, NULL, SL_ORG_ML}, {"SL_ORG_MR", "const float", QW|NQ, NULL, SL_ORG_MR}, - {"PFLAGS_NOSHADOW", "const float", QW|NQ|CS, "Associated RT lights attached will not cast shadows, making them significantly faster to draw.", PFLAGS_NOSHADOW}, - {"PFLAGS_CORONA", "const float", QW|NQ|CS, "Enables support of coronas on the associated rtlights.", PFLAGS_CORONA}, - {"PFLAGS_FULLDYNAMIC", "const float", QW|NQ, "When set in self.pflags, enables fully-customised dynamic lights. Custom rtlight information is not otherwise used.", PFLAGS_FULLDYNAMIC}, + {"PFLAGS_NOSHADOW", "const float", QW|NQ|CS, D("Associated RT lights attached will not cast shadows, making them significantly faster to draw."), PFLAGS_NOSHADOW}, + {"PFLAGS_CORONA", "const float", QW|NQ|CS, D("Enables support of coronas on the associated rtlights."), PFLAGS_CORONA}, + {"PFLAGS_FULLDYNAMIC", "const float", QW|NQ, D("When set in self.pflags, enables fully-customised dynamic lights. Custom rtlight information is not otherwise used."), PFLAGS_FULLDYNAMIC}, //including these for csqc stat types. // {"EV_VOID", "const float", QW|NQ|CS, NULL, ev_void}, @@ -11854,116 +11865,116 @@ void PR_DumpPlatform_f(void) // {"EV_STRUCT", "const float", QW|NQ|CS, NULL, ev_struct}, // {"EV_UNION", "const float", QW|NQ|CS, NULL, ev_union}, - {"gamestate", "hashtable", ALL, "Special hash table index for hash_add and hash_get. Entries in this table will persist over map changes (and doesn't need to be created/deleted).", 0}, - {"HASH_REPLACE", "const float", ALL, "Used with hash_add. Attempts to remove the old value instead of adding two values for a single key.", 256}, - {"HASH_ADD", "const float", ALL, "Used with hash_add. The new entry will be inserted in addition to the existing entry.", 512}, + {"gamestate", "hashtable", ALL, D("Special hash table index for hash_add and hash_get. Entries in this table will persist over map changes (and doesn't need to be created/deleted)."), 0}, + {"HASH_REPLACE", "const float", ALL, D("Used with hash_add. Attempts to remove the old value instead of adding two values for a single key."), 256}, + {"HASH_ADD", "const float", ALL, D("Used with hash_add. The new entry will be inserted in addition to the existing entry."), 512}, #ifdef QUAKESTATS - {"STAT_HEALTH", "const float", CS, "Player's health.", STAT_HEALTH}, - {"STAT_WEAPONMODELI", "const float", CS, "This is the modelindex of the current viewmodel (renamed from the original name 'STAT_WEAPON' due to confusions).", STAT_WEAPONMODELI}, - {"STAT_AMMO", "const float", CS, "player.currentammo", STAT_AMMO}, + {"STAT_HEALTH", "const float", CS, D("Player's health."), STAT_HEALTH}, + {"STAT_WEAPONMODELI", "const float", CS, D("This is the modelindex of the current viewmodel (renamed from the original name 'STAT_WEAPON' due to confusions)."), STAT_WEAPONMODELI}, + {"STAT_AMMO", "const float", CS, D("player.currentammo"), STAT_AMMO}, {"STAT_ARMOR", "const float", CS, NULL, STAT_ARMOR}, {"STAT_WEAPONFRAME", "const float", CS, NULL, STAT_WEAPONFRAME}, {"STAT_SHELLS", "const float", CS, NULL, STAT_SHELLS}, {"STAT_NAILS", "const float", CS, NULL, STAT_NAILS}, {"STAT_ROCKETS", "const float", CS, NULL, STAT_ROCKETS}, {"STAT_CELLS", "const float", CS, NULL, STAT_CELLS}, - {"STAT_ACTIVEWEAPON", "const float", CS, "player.weapon", STAT_ACTIVEWEAPON}, + {"STAT_ACTIVEWEAPON", "const float", CS, D("player.weapon"), STAT_ACTIVEWEAPON}, {"STAT_TOTALSECRETS", "const float", CS, NULL, STAT_TOTALSECRETS}, {"STAT_TOTALMONSTERS", "const float", CS, NULL, STAT_TOTALMONSTERS}, {"STAT_FOUNDSECRETS", "const float", CS, NULL, STAT_SECRETS}, {"STAT_KILLEDMONSTERS", "const float", CS, NULL, STAT_MONSTERS}, - {"STAT_ITEMS", "const float", CS, "self.items | (self.items2<<23). In order to decode this stat properly, you need to use getstatbits(STAT_ITEMS,0,23) to read self.items, and getstatbits(STAT_ITEMS,23,11) to read self.items2 or getstatbits(STAT_ITEMS,28,4) to read the visible part of serverflags, whichever is applicable.", STAT_ITEMS}, - {"STAT_VIEWHEIGHT", "const float", CS, "player.view_ofs_z", STAT_VIEWHEIGHT}, - {"STAT_VIEW2", "const float", CS, "This stat contains the number of the entity in the server's .view2 field.", STAT_VIEW2}, - {"STAT_VIEWZOOM", "const float", CS, "Scales fov and sensitiity. Part of DP_VIEWZOOM.", STAT_VIEWZOOM}, + {"STAT_ITEMS", "const float", CS, D("self.items | (self.items2<<23). In order to decode this stat properly, you need to use getstatbits(STAT_ITEMS,0,23) to read self.items, and getstatbits(STAT_ITEMS,23,11) to read self.items2 or getstatbits(STAT_ITEMS,28,4) to read the visible part of serverflags, whichever is applicable."), STAT_ITEMS}, + {"STAT_VIEWHEIGHT", "const float", CS, D("player.view_ofs_z"), STAT_VIEWHEIGHT}, + {"STAT_VIEW2", "const float", CS, D("This stat contains the number of the entity in the server's .view2 field."), STAT_VIEW2}, + {"STAT_VIEWZOOM", "const float", CS, D("Scales fov and sensitiity. Part of DP_VIEWZOOM."), STAT_VIEWZOOM}, - {"STAT_USER", "const float", QW|NQ|CS, "Custom user stats start here (lower values are reserved for engine use).", 32}, + {"STAT_USER", "const float", QW|NQ|CS, D("Custom user stats start here (lower values are reserved for engine use)."), 32}, #endif - {"VF_MIN", "const float", CS|MENU, "The top-left of the 3d viewport in screenspace. The VF_ values are used via the setviewprop/getviewprop builtins.", VF_MIN}, + {"VF_MIN", "const float", CS|MENU, D("The top-left of the 3d viewport in screenspace. The VF_ values are used via the setviewprop/getviewprop builtins."), VF_MIN}, {"VF_MIN_X", "const float", CS|MENU, NULL, VF_MIN_X}, {"VF_MIN_Y", "const float", CS|MENU, NULL, VF_MIN_Y}, - {"VF_SIZE", "const float", CS|MENU, "The width+height of the 3d viewport in screenspace.", VF_SIZE}, + {"VF_SIZE", "const float", CS|MENU, D("The width+height of the 3d viewport in screenspace."), VF_SIZE}, {"VF_SIZE_X", "const float", CS|MENU, NULL, VF_SIZE_X}, {"VF_SIZE_Y", "const float", CS|MENU, NULL, VF_SIZE_Y}, - {"VF_VIEWPORT", "const float", CS|MENU, "vector+vector. Two argument shortcut for VF_MIN and VF_SIZE", VF_VIEWPORT}, - {"VF_FOV", "const float", CS|MENU, "sets both fovx and fovy. consider using afov instead.", VF_FOV}, - {"VF_FOVX", "const float", CS|MENU, "horizontal field of view. does not consider aspect at all.", VF_FOVX}, - {"VF_FOVY", "const float", CS|MENU, "vertical field of view. does not consider aspect at all.", VF_FOVY}, - {"VF_ORIGIN", "const float", CS|MENU, "The origin of the view. Not of the player.", VF_ORIGIN}, + {"VF_VIEWPORT", "const float", CS|MENU, D("vector+vector. Two argument shortcut for VF_MIN and VF_SIZE"), VF_VIEWPORT}, + {"VF_FOV", "const float", CS|MENU, D("sets both fovx and fovy. consider using afov instead."), VF_FOV}, + {"VF_FOVX", "const float", CS|MENU, D("horizontal field of view. does not consider aspect at all."), VF_FOVX}, + {"VF_FOVY", "const float", CS|MENU, D("vertical field of view. does not consider aspect at all."), VF_FOVY}, + {"VF_ORIGIN", "const float", CS|MENU, D("The origin of the view. Not of the player."), VF_ORIGIN}, {"VF_ORIGIN_X", "const float", CS|MENU, NULL, VF_ORIGIN_X}, {"VF_ORIGIN_Y", "const float", CS|MENU, NULL, VF_ORIGIN_Y}, {"VF_ORIGIN_Z", "const float", CS|MENU, NULL, VF_ORIGIN_Z}, - {"VF_ANGLES", "const float", CS|MENU, "The angles the view will be drawn at. Not the angle the client reports to the server.", VF_ANGLES}, + {"VF_ANGLES", "const float", CS|MENU, D("The angles the view will be drawn at. Not the angle the client reports to the server."), VF_ANGLES}, {"VF_ANGLES_X", "const float", CS|MENU, NULL, VF_ANGLES_X}, {"VF_ANGLES_Y", "const float", CS|MENU, NULL, VF_ANGLES_Y}, {"VF_ANGLES_Z", "const float", CS|MENU, NULL, VF_ANGLES_Z}, - {"VF_DRAWWORLD", "const float", CS, "boolean. If set to 1, the engine will draw the world and static/persistant rtlights. If 0, the world will be skipped and everything will be fullbright.", VF_DRAWWORLD}, - {"VF_DRAWENGINESBAR", "const float", CS, "boolean. If set to 1, the sbar will be drawn, and viewsize will be honoured automatically.", VF_ENGINESBAR}, - {"VF_DRAWCROSSHAIR", "const float", CS, "boolean. If set to 1, the engine will draw its default crosshair.", VF_DRAWCROSSHAIR}, + {"VF_DRAWWORLD", "const float", CS, D("boolean. If set to 1, the engine will draw the world and static/persistant rtlights. If 0, the world will be skipped and everything will be fullbright."), VF_DRAWWORLD}, + {"VF_DRAWENGINESBAR", "const float", CS, D("boolean. If set to 1, the sbar will be drawn, and viewsize will be honoured automatically."), VF_ENGINESBAR}, + {"VF_DRAWCROSSHAIR", "const float", CS, D("boolean. If set to 1, the engine will draw its default crosshair."), VF_DRAWCROSSHAIR}, - {"VF_MINDIST", "const float", CS|MENU, "The distance of the near clip plane from the view position. Should generally not be <=0, as this would introduce NANs.", VF_MINDIST}, - {"VF_MAXDIST", "const float", CS|MENU, "The distance of the far clip plane from the view position. If 0, will be considered infinite.", VF_MAXDIST}, + {"VF_MINDIST", "const float", CS|MENU, D("The distance of the near clip plane from the view position. Should generally not be <=0, as this would introduce NANs."), VF_MINDIST}, + {"VF_MAXDIST", "const float", CS|MENU, D("The distance of the far clip plane from the view position. If 0, will be considered infinite."), VF_MAXDIST}, {"VF_CL_VIEWANGLES", "const float", CS, NULL, VF_CL_VIEWANGLES_V}, {"VF_CL_VIEWANGLES_X", "const float", CS, NULL, VF_CL_VIEWANGLES_X}, {"VF_CL_VIEWANGLES_Y", "const float", CS, NULL, VF_CL_VIEWANGLES_Y}, {"VF_CL_VIEWANGLES_Z", "const float", CS, NULL, VF_CL_VIEWANGLES_Z}, - {"VF_PERSPECTIVE", "const float", CS|MENU, "1: regular rendering. Fov specifies the angle. 0: isometric-style. Fov specifies the number of Quake Units each side of the viewport, and mindist restrictions are removed, pvs culling should be disabled.", VF_PERSPECTIVE}, - {"VF_ACTIVESEAT", "#define VF_LPLAYER VF_ACTIVESEAT\nconst float", CS, "The 'seat' number, used when running splitscreen.", VF_ACTIVESEAT}, - {"VF_AFOV", "const float", CS|MENU, "Aproximate fov. Matches the 'fov' cvar. The engine handles the aspect ratio for you.", VF_AFOV}, - {"VF_SCREENVSIZE", "const float", CS|MENU, "Provides a reliable way to retrieve the current virtual screen size (even if the screen is automatically scaled to retain aspect).", VF_SCREENVSIZE}, - {"VF_SCREENPSIZE", "const float", CS|MENU, "Provides a reliable way to retrieve the current physical screen size (cvars need vid_restart for them to take effect).", VF_SCREENPSIZE}, - {"VF_VIEWENTITY", "const float", CS, "Changes the RF_EXTERNALMODEL flag on entities to match the new selection, and removes entities flaged with RF_VIEWENTITY. Requires cunning use of .entnum and typically requires calling addentities(MASK_VIEWMODEL) too.", VF_VIEWENTITY}, + {"VF_PERSPECTIVE", "const float", CS|MENU, D("1: regular rendering. Fov specifies the angle. 0: isometric-style. Fov specifies the number of Quake Units each side of the viewport, and mindist restrictions are removed, pvs culling should be disabled."), VF_PERSPECTIVE}, + {"VF_ACTIVESEAT", "#define VF_LPLAYER VF_ACTIVESEAT\nconst float", CS, D("The 'seat' number, used when running splitscreen."), VF_ACTIVESEAT}, + {"VF_AFOV", "const float", CS|MENU, D("Aproximate fov. Matches the 'fov' cvar. The engine handles the aspect ratio for you."), VF_AFOV}, + {"VF_SCREENVSIZE", "const float", CS|MENU, D("Provides a reliable way to retrieve the current virtual screen size (even if the screen is automatically scaled to retain aspect)."), VF_SCREENVSIZE}, + {"VF_SCREENPSIZE", "const float", CS|MENU, D("Provides a reliable way to retrieve the current physical screen size (cvars need vid_restart for them to take effect)."), VF_SCREENPSIZE}, + {"VF_VIEWENTITY", "const float", CS, D("Changes the RF_EXTERNALMODEL flag on entities to match the new selection, and removes entities flaged with RF_VIEWENTITY. Requires cunning use of .entnum and typically requires calling addentities(MASK_VIEWMODEL) too."), VF_VIEWENTITY}, - {"VF_RT_DESTCOLOUR", "const float", CS|MENU, "The texture name to write colour info into, this includes both 3d and 2d drawing.\nAdditional arguments are: format (rgba8=1,rgba16f=2,rgba32f=3), sizexy.\nWritten to by both 3d and 2d rendering.\nNote that any rendertarget textures may be destroyed on video mode changes or so. Shaders can name render targets by prefixing texture names with '$rt:', or $sourcecolour.", VF_RT_DESTCOLOUR0}, -// {"VF_RT_DESTCOLOUR1", "const float", CS|MENU, "Like VF_RT_DESTCOLOUR, for multiple render targets.", VF_RT_DESTCOLOUR1}, -// {"VF_RT_DESTCOLOUR2", "const float", CS|MENU, "Like VF_RT_DESTCOLOUR, for multiple render targets.", VF_RT_DESTCOLOUR2}, -// {"VF_RT_DESTCOLOUR3", "const float", CS|MENU, "Like VF_RT_DESTCOLOUR, for multiple render targets.", VF_RT_DESTCOLOUR3}, -// {"VF_RT_DESTCOLOUR4", "const float", CS|MENU, "Like VF_RT_DESTCOLOUR, for multiple render targets.", VF_RT_DESTCOLOUR4}, -// {"VF_RT_DESTCOLOUR5", "const float", CS|MENU, "Like VF_RT_DESTCOLOUR, for multiple render targets.", VF_RT_DESTCOLOUR5}, -// {"VF_RT_DESTCOLOUR6", "const float", CS|MENU, "Like VF_RT_DESTCOLOUR, for multiple render targets.", VF_RT_DESTCOLOUR6}, -// {"VF_RT_DESTCOLOUR7", "const float", CS|MENU, "Like VF_RT_DESTCOLOUR, for multiple render targets.", VF_RT_DESTCOLOUR7}, - {"VF_RT_SOURCECOLOUR", "const float", CS|MENU, "The texture name to use with shaders that specify a $sourcecolour map.", VF_RT_SOURCECOLOUR}, - {"VF_RT_DEPTH", "const float", CS|MENU, "The texture name to use as a depth buffer. Also used for shaders that specify $sourcedepth. 1-based. Additional arguments are: format (16bit=4,24bit=5,32bit=6), sizexy.", VF_RT_DEPTH}, - {"VF_RT_RIPPLE", "const float", CS|MENU, "The texture name to use as a ripplemap (target for shaders with 'sort ripple'). Also used for shaders that specify $ripplemap. 1-based. Additional arguments are: format, sizexy.", VF_RT_RIPPLE}, - {"VF_ENVMAP", "const float", CS|MENU, "The cubemap name to use as a fallback for $reflectcube, if a shader was unable to load one. Note that this doesn't automatically change shader permutations or anything.", VF_ENVMAP}, + {"VF_RT_DESTCOLOUR", "const float", CS|MENU, D("The texture name to write colour info into, this includes both 3d and 2d drawing.\nAdditional arguments are: format (rgba8=1,rgba16f=2,rgba32f=3), sizexy.\nWritten to by both 3d and 2d rendering.\nNote that any rendertarget textures may be destroyed on video mode changes or so. Shaders can name render targets by prefixing texture names with '$rt:', or $sourcecolour."), VF_RT_DESTCOLOUR0}, +// {"VF_RT_DESTCOLOUR1", "const float", CS|MENU, D("Like VF_RT_DESTCOLOUR, for multiple render targets."), VF_RT_DESTCOLOUR1}, +// {"VF_RT_DESTCOLOUR2", "const float", CS|MENU, D("Like VF_RT_DESTCOLOUR, for multiple render targets."), VF_RT_DESTCOLOUR2}, +// {"VF_RT_DESTCOLOUR3", "const float", CS|MENU, D("Like VF_RT_DESTCOLOUR, for multiple render targets."), VF_RT_DESTCOLOUR3}, +// {"VF_RT_DESTCOLOUR4", "const float", CS|MENU, D("Like VF_RT_DESTCOLOUR, for multiple render targets."), VF_RT_DESTCOLOUR4}, +// {"VF_RT_DESTCOLOUR5", "const float", CS|MENU, D("Like VF_RT_DESTCOLOUR, for multiple render targets."), VF_RT_DESTCOLOUR5}, +// {"VF_RT_DESTCOLOUR6", "const float", CS|MENU, D("Like VF_RT_DESTCOLOUR, for multiple render targets."), VF_RT_DESTCOLOUR6}, +// {"VF_RT_DESTCOLOUR7", "const float", CS|MENU, D("Like VF_RT_DESTCOLOUR, for multiple render targets."), VF_RT_DESTCOLOUR7}, + {"VF_RT_SOURCECOLOUR", "const float", CS|MENU, D("The texture name to use with shaders that specify a $sourcecolour map."), VF_RT_SOURCECOLOUR}, + {"VF_RT_DEPTH", "const float", CS|MENU, D("The texture name to use as a depth buffer. Also used for shaders that specify $sourcedepth. 1-based. Additional arguments are: format (16bit=4,24bit=5,32bit=6), sizexy."), VF_RT_DEPTH}, + {"VF_RT_RIPPLE", "const float", CS|MENU, D("The texture name to use as a ripplemap (target for shaders with 'sort ripple'). Also used for shaders that specify $ripplemap. 1-based. Additional arguments are: format, sizexy."), VF_RT_RIPPLE}, + {"VF_ENVMAP", "const float", CS|MENU, D("The cubemap name to use as a fallback for $reflectcube, if a shader was unable to load one. Note that this doesn't automatically change shader permutations or anything."), VF_ENVMAP}, - {"RF_VIEWMODEL", "const float", CS, "Specifies that the entity is a view model, and that its origin is relative to the current view position. These entities are also subject to viewweapon bob.", CSQCRF_VIEWMODEL}, - {"RF_EXTERNALMODEL", "const float", CS, "Specifies that this entity should be displayed in mirrors (and may still cast shadows), but will not otherwise be visible.", CSQCRF_EXTERNALMODEL}, - {"RF_DEPTHHACK", "const float", CS|MENU, "Hacks the depth values such that the entity uses depth values as if it were closer to the screen. This is useful when combined with viewmodels to avoid weapons poking in to walls.", CSQCRF_DEPTHHACK}, - {"RF_ADDITIVE", "const float", CS|MENU, "Shaders from this entity will temporarily be hacked to use an additive blend mode instead of their normal blend mode.", CSQCRF_ADDITIVE}, - {"RF_USEAXIS", "const float", CS, "The entity will be oriented according to the current v_forward+v_right+v_up vector values instead of the entity's .angles field.", CSQCRF_USEAXIS}, - {"RF_NOSHADOW", "const float", CS, "This entity will not cast shadows. Often useful on view models.", CSQCRF_NOSHADOW}, - {"RF_FRAMETIMESARESTARTTIMES","const float", CS, "Specifies that the frame1time, frame2time field are timestamps (denoting the start of the animation) rather than time into the animation.", CSQCRF_FRAMETIMESARESTARTTIMES}, + {"RF_VIEWMODEL", "const float", CS, D("Specifies that the entity is a view model, and that its origin is relative to the current view position. These entities are also subject to viewweapon bob."), CSQCRF_VIEWMODEL}, + {"RF_EXTERNALMODEL", "const float", CS, D("Specifies that this entity should be displayed in mirrors (and may still cast shadows), but will not otherwise be visible."), CSQCRF_EXTERNALMODEL}, + {"RF_DEPTHHACK", "const float", CS|MENU, D("Hacks the depth values such that the entity uses depth values as if it were closer to the screen. This is useful when combined with viewmodels to avoid weapons poking in to walls."), CSQCRF_DEPTHHACK}, + {"RF_ADDITIVE", "const float", CS|MENU, D("Shaders from this entity will temporarily be hacked to use an additive blend mode instead of their normal blend mode."), CSQCRF_ADDITIVE}, + {"RF_USEAXIS", "const float", CS, D("The entity will be oriented according to the current v_forward+v_right+v_up vector values instead of the entity's .angles field."), CSQCRF_USEAXIS}, + {"RF_NOSHADOW", "const float", CS, D("This entity will not cast shadows. Often useful on view models."), CSQCRF_NOSHADOW}, + {"RF_FRAMETIMESARESTARTTIMES","const float", CS, D("Specifies that the frame1time, frame2time field are timestamps (denoting the start of the animation) rather than time into the animation."), CSQCRF_FRAMETIMESARESTARTTIMES}, - {"IE_KEYDOWN", "const float", CS, "Specifies that a key was pressed. Second argument is the scan code. Third argument is the unicode (printable) char value. Fourth argument denotes which keyboard(or mouse, if its a mouse 'scan' key) the event came from. Note that some systems may completely separate scan codes and unicode values, with a 0 value for the unspecified argument.", CSIE_KEYDOWN}, - {"IE_KEYUP", "const float", CS, "Specifies that a key was released. Arguments are the same as IE_KEYDOWN. On some systems, this may be fired instantly after IE_KEYDOWN was fired.", CSIE_KEYUP}, - {"IE_MOUSEDELTA", "const float", CS, "Specifies that a mouse was moved (touch screens and tablets typically give IE_MOUSEABS events instead, use _windowed_mouse 0 to test code to cope with either). Second argument is the X displacement, third argument is the Y displacement. Fourth argument is which mouse or touch event triggered the event.", CSIE_MOUSEDELTA}, - {"IE_MOUSEABS", "const float", CS, "Specifies that a mouse cursor or touch event was moved to a specific location relative to the virtual screen space. Second argument is the new X position, third argument is the new Y position. Fourth argument is which mouse or touch event triggered the event.", CSIE_MOUSEABS}, + {"IE_KEYDOWN", "const float", CS, D("Specifies that a key was pressed. Second argument is the scan code. Third argument is the unicode (printable) char value. Fourth argument denotes which keyboard(or mouse, if its a mouse 'scan' key) the event came from. Note that some systems may completely separate scan codes and unicode values, with a 0 value for the unspecified argument."), CSIE_KEYDOWN}, + {"IE_KEYUP", "const float", CS, D("Specifies that a key was released. Arguments are the same as IE_KEYDOWN. On some systems, this may be fired instantly after IE_KEYDOWN was fired."), CSIE_KEYUP}, + {"IE_MOUSEDELTA", "const float", CS, D("Specifies that a mouse was moved (touch screens and tablets typically give IE_MOUSEABS events instead, use _windowed_mouse 0 to test code to cope with either). Second argument is the X displacement, third argument is the Y displacement. Fourth argument is which mouse or touch event triggered the event."), CSIE_MOUSEDELTA}, + {"IE_MOUSEABS", "const float", CS, D("Specifies that a mouse cursor or touch event was moved to a specific location relative to the virtual screen space. Second argument is the new X position, third argument is the new Y position. Fourth argument is which mouse or touch event triggered the event."), CSIE_MOUSEABS}, {"IE_ACCELEROMETER", "const float", CS, NULL, CSIE_ACCELEROMETER}, - {"IE_FOCUS", "const float", CS, "Specifies that input focus was given. parama says mouse focus, paramb says keyboard focus. If either are -1, then it is unchanged.", CSIE_FOCUS}, - {"IE_JOYAXIS", "const float", CS, "Specifies that what value a joystick/controller axis currently specifies. x=axis, y=value. Will be called multiple times, once for each axis of each active controller.", CSIE_JOYAXIS}, + {"IE_FOCUS", "const float", CS, D("Specifies that input focus was given. parama says mouse focus, paramb says keyboard focus. If either are -1, then it is unchanged."), CSIE_FOCUS}, + {"IE_JOYAXIS", "const float", CS, D("Specifies that what value a joystick/controller axis currently specifies. x=axis, y=value. Will be called multiple times, once for each axis of each active controller."), CSIE_JOYAXIS}, {"IE_GYROSCOPE", "const float", CS, NULL, CSIE_GYROSCOPE}, - {"CLIENTTYPE_DISCONNECTED","const float", QW|NQ, "Return value from clienttype() builtin. This entity is a player slot that is currently empty.", CLIENTTYPE_DISCONNECTED}, - {"CLIENTTYPE_REAL", "const float", QW|NQ, "This is a real player, and not a bot.", CLIENTTYPE_REAL}, - {"CLIENTTYPE_BOT", "const float", QW|NQ, "This player slot does not correlate to a real player, any messages sent to this client will be ignored.", CLIENTTYPE_BOT}, - {"CLIENTTYPE_NOTACLIENT","const float",QW|NQ, "This entity is not even a player slot. This is typically an error condition.", CLIENTTYPE_NOTACLIENT}, + {"CLIENTTYPE_DISCONNECTED","const float", QW|NQ, D("Return value from clienttype() builtin. This entity is a player slot that is currently empty."), CLIENTTYPE_DISCONNECTED}, + {"CLIENTTYPE_REAL", "const float", QW|NQ, D("This is a real player, and not a bot."), CLIENTTYPE_REAL}, + {"CLIENTTYPE_BOT", "const float", QW|NQ, D("This player slot does not correlate to a real player, any messages sent to this client will be ignored."), CLIENTTYPE_BOT}, + {"CLIENTTYPE_NOTACLIENT","const float",QW|NQ, D("This entity is not even a player slot. This is typically an error condition."), CLIENTTYPE_NOTACLIENT}, - {"FILE_READ", "const float", ALL, "The file may be read via fgets to read a single line at a time.", FRIK_FILE_READ}, - {"FILE_APPEND", "const float", ALL, "Like FILE_WRITE, but writing starts at the end of the file.", FRIK_FILE_APPEND}, - {"FILE_WRITE", "const float", ALL, "fputs will be used to write to the file.", FRIK_FILE_WRITE}, - {"FILE_READNL", "const float", QW|NQ|CS, "Like FILE_READ, except newlines are not special. fgets reads the entire file into a tempstring.", FRIK_FILE_READNL}, - {"FILE_MMAP_READ", "const float", QW|NQ|CS, "The file will be loaded into memory. fgets returns a pointer to the first byte (and will always return the same value for this file). Cast this to your datatype.", FRIK_FILE_MMAP_READ}, - {"FILE_MMAP_RW", "const float", QW|NQ|CS, "Like FILE_MMAP_READ, except any changes to the data will be written back to disk once the file is closed.", FRIK_FILE_MMAP_RW}, + {"FILE_READ", "const float", ALL, D("The file may be read via fgets to read a single line at a time."), FRIK_FILE_READ}, + {"FILE_APPEND", "const float", ALL, D("Like FILE_WRITE, but writing starts at the end of the file."), FRIK_FILE_APPEND}, + {"FILE_WRITE", "const float", ALL, D("fputs will be used to write to the file."), FRIK_FILE_WRITE}, + {"FILE_READNL", "const float", QW|NQ|CS, D("Like FILE_READ, except newlines are not special. fgets reads the entire file into a tempstring."), FRIK_FILE_READNL}, + {"FILE_MMAP_READ", "const float", QW|NQ|CS, D("The file will be loaded into memory. fgets returns a pointer to the first byte (and will always return the same value for this file). Cast this to your datatype."), FRIK_FILE_MMAP_READ}, + {"FILE_MMAP_RW", "const float", QW|NQ|CS, D("Like FILE_MMAP_READ, except any changes to the data will be written back to disk once the file is closed."), FRIK_FILE_MMAP_RW}, - {"MASK_ENGINE", "const float", CS, "Valid as an argument for addentities. If specified, all non-csqc entities will be added to the scene.", MASK_DELTA}, - {"MASK_VIEWMODEL", "const float", CS, "Valid as an argument for addentities. If specified, the regular engine viewmodel will be added to the scene.", MASK_STDVIEWMODEL}, - {"PREDRAW_AUTOADD", "const float", CS, "Valid as a return value from the predraw function. Returning this will cause the engine to automatically invoke addentity(self) for you.", false}, - {"PREDRAW_NEXT", "const float", CS, "Valid as a return value from the predraw function. Returning this will simply move on to the next entity without the autoadd behaviour, so can be used for particle/invisible/special entites, or entities that were explicitly drawn with addentity.", true}, + {"MASK_ENGINE", "const float", CS, D("Valid as an argument for addentities. If specified, all non-csqc entities will be added to the scene."), MASK_DELTA}, + {"MASK_VIEWMODEL", "const float", CS, D("Valid as an argument for addentities. If specified, the regular engine viewmodel will be added to the scene."), MASK_STDVIEWMODEL}, + {"PREDRAW_AUTOADD", "const float", CS, D("Valid as a return value from the predraw function. Returning this will cause the engine to automatically invoke addentity(self) for you."), false}, + {"PREDRAW_NEXT", "const float", CS, D("Valid as a return value from the predraw function. Returning this will simply move on to the next entity without the autoadd behaviour, so can be used for particle/invisible/special entites, or entities that were explicitly drawn with addentity."), true}, {"LFIELD_ORIGIN", "const float", CS, NULL, lfield_origin}, {"LFIELD_COLOUR", "const float", CS, NULL, lfield_colour}, diff --git a/engine/server/progdefs.h b/engine/server/progdefs.h index 3cddfb16..64fc67eb 100644 --- a/engine/server/progdefs.h +++ b/engine/server/progdefs.h @@ -204,6 +204,21 @@ and the extension fields are added on the end and can have extra vm-specific stu comfieldstring(noise3,NULL) /*DO NOT ADD TO THE ABOVE STRUCTURE*/ +#ifdef HEXEN2 +#define comextqcfieldshexen2 \ + comfieldfloat(drawflags,"Various flags that affect lighting values and scaling. Typically set to 96 in quake for proper compatibility with DP_QC_SCALE.")/*hexen2*/\ + comfieldfloat(abslight,"Allows overriding light levels. Use drawflags to state that this field should actually be used.")/*hexen2's force a lightlevel*/\ + +#define svextqcfieldshexen2 \ + comfieldfloat(playerclass,NULL)/*hexen2 requirements*/\ + comfieldfloat(hasted,NULL)/*hexen2 uses this AS WELL as maxspeed*/\ + comfieldfloat(light_level,"Used by hexen2 to indicate the light level where the player is standing.")\ + +#else +#define comextqcfieldshexen2 +#define svextqcfieldshexen2 +#endif + #define comextqcfields \ comfieldvector(punchangle,NULL) /*std in nq*/\ comfieldfloat(gravity,NULL) /*added in quake 1.09 (for hipnotic)*/\ @@ -240,17 +255,13 @@ and the extension fields are added on the end and can have extra vm-specific stu comfieldfloat(bouncestop,NULL)/*DP_...PHYSICS*/\ comfieldfloat(idealpitch,NULL)/*DP_QC_CHANGEPITCH (inconsistant naming)*/\ comfieldfloat(pitch_speed,NULL)/*DP_QC_CHANGEPITCH*/\ + comextqcfieldshexen2 \ comfieldvector(color,"This affects the colour of realtime lights that were enabled via the pflags field.")/*Hexen2 has a .float color, the warnings should be benign*/ \ comfieldfloat(light_lev,"This is the radius of an entity's light. This is not normally used by the engine, but is used for realtime lights (ones that are enabled with the pflags field).")\ comfieldfloat(style,"Used by the light util to decide how an entity's light should animate. On an entity with pflags set, this also affects realtime lights.")\ comfieldfloat(pflags,"Realtime lighting flags") #ifdef HEXEN2 -#define svextqcfieldshexen2 \ - comfieldfloat(playerclass,NULL)/*hexen2 requirements*/\ - comfieldfloat(hasted,NULL)/*hexen2 uses this AS WELL as maxspeed*/\ - comfieldfloat(light_level,"Used by hexen2 to indicate the light level where the player is standing.")\ - #else #define svextqcfieldshexen2 #endif @@ -281,8 +292,6 @@ and the extension fields are added on the end and can have extra vm-specific stu comfieldfloat(dimension_seen,"This is the dimension mask (bitfield) that the client is visible within. Clients that cannot see this dimension mask will not see this entity.")/*EXT_DIMENSION_VISIBLE*/\ comfieldfloat(dimension_ghost,"If this entity is visible only within these dimensions, it will become transparent, as if a ghost.")/*EXT_DIMENSION_GHOST*/\ comfieldfloat(dimension_ghost_alpha,"If this entity is subject to dimension_ghost, this is the scaler for its alpha value. If 0, 0.5 will be used instead.")/*EXT_DIMENSION_GHOST*/\ - comfieldfloat(drawflags,"Various flags that affect lighting values and scaling. Typically set to 96 in quake for proper compatibility with DP_QC_SCALE.")/*hexen2*/\ - comfieldfloat(abslight,"Allows overriding light levels. Use drawflags to state that this field should actually be used.")/*hexen2's force a lightlevel*/\ comfieldfunction(SendEntity, ".float(entity playerent, float changedflags)","Called by the engine whenever an entity needs to be (re)sent to a client's csprogs, either because SendFlags was set or because data was lost. Must write its data to the MSG_ENTITY buffer. Will be called at the engine's leasure.")/*EXT_CSQC*/\ comfieldfloat(SendFlags,"Indicates that something in the entity has been changed, and that it needs to be updated to all players that can see it. The engine will clear it at some point, with the cleared bits appearing in the 'changedflags' argument of the SendEntity method.")/*EXT_CSQC_1 (one of the DP guys came up with it)*/\ comfieldfloat_legacy(Version,"Obsolete, set a SendFlags bit instead.")/*EXT_CSQC (obsolete)*/\ diff --git a/engine/server/progs.h b/engine/server/progs.h index 7188a898..e5ccc00f 100644 --- a/engine/server/progs.h +++ b/engine/server/progs.h @@ -18,8 +18,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#define QCLIB //as opposed to standard qc stuff. One or other. All references+changes were by DMW unless specified otherwise. Starting 1/10/02 - struct client_s; struct edict_s; diff --git a/engine/server/savegame.c b/engine/server/savegame.c index b9e83354..82333c42 100644 --- a/engine/server/savegame.c +++ b/engine/server/savegame.c @@ -933,7 +933,7 @@ void SV_SaveLevelCache(const char *savedir, qboolean dontharmgame) if (!FS_NativePath(name, FS_GAMEONLY, syspath, sizeof(syspath))) return; ge->WriteLevel(syspath); - FS_FlushFSHashReally(true); + FS_FlushFSHashFull(); return; } #endif @@ -942,6 +942,7 @@ void SV_SaveLevelCache(const char *savedir, qboolean dontharmgame) if (svs.gametype == GT_HALFLIFE) { SVHL_SaveLevelCache(name); + FS_FlushFSHashFull(); return; } #endif @@ -1092,6 +1093,8 @@ void SV_SaveLevelCache(const char *savedir, qboolean dontharmgame) ed->ereftype = ER_ENTITY; } } + + FS_FlushFSHashFull(); } #define FTESAVEGAME_VERSION 25000 @@ -1301,13 +1304,13 @@ void SV_Savegame (const char *savename, qboolean mapchange) if (!FS_NativePath(va("saves/%s/game.gsv", savename), FS_GAMEONLY, syspath, sizeof(syspath))) return; ge->WriteGame(syspath, mapchange); - FS_FlushFSHashReally(true); + FS_FlushFSHashFull(); } else #endif { //fixme - FS_FlushFSHashReally(true); + FS_FlushFSHashFull(); } } diff --git a/engine/server/server.h b/engine/server/server.h index a59823f4..1aa35b64 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -1442,8 +1442,8 @@ typedef struct mvddest_s { #endif vfsfile_t *file; - char name[MAX_QPATH]; - char path[MAX_QPATH]; + char filename[MAX_QPATH]; //demos/foo.mvd + char simplename[MAX_QPATH]; //foo.mvd int flushing; //worker has a cache (used as a sync point) char *cache; diff --git a/engine/server/sv_ents.c b/engine/server/sv_ents.c index e0259c15..6d6b2e07 100644 --- a/engine/server/sv_ents.c +++ b/engine/server/sv_ents.c @@ -67,10 +67,10 @@ int needcleanup; //int fatbytes; -#ifdef Q2BSPS +#if defined(Q2BSPS) || defined(Q3BSPS) unsigned int SV_Q2BSP_FatPVS (model_t *mod, vec3_t org, qbyte *resultbuf, unsigned int buffersize, qboolean add) { - int leafs[64]; + int leafs[64]; int i, j, count; unsigned int longs; qbyte *src; @@ -82,15 +82,12 @@ unsigned int SV_Q2BSP_FatPVS (model_t *mod, vec3_t org, qbyte *resultbuf, unsig maxs[i] = org[i] + 8; } - count = CM_BoxLeafnums (mod, mins, maxs, leafs, 64, NULL); + count = CM_BoxLeafnums (mod, mins, maxs, leafs, countof(leafs), NULL); if (count < 1) Sys_Error ("SV_Q2FatPVS: count < 1"); - if (mod->fromgame == fg_quake3) - longs = CM_ClusterSize(mod); - else - longs = (CM_NumClusters(mod)+7)/8; - longs = (longs+(sizeof(long)-1))/sizeof(long); + longs = CM_ClusterBytes(mod); + longs = (longs+(sizeof(longs)-1))/sizeof(longs); // convert leafs to clusters for (i=0 ; ifromgame == fg_quake2)?0:-1; @@ -3262,8 +3259,10 @@ void SV_Snapshot_BuildStateQ1(entity_state_t *state, edict_t *ent, client_t *cli state->skinnum = ent->v->skin; state->effects = ent->v->effects; state->effects |= (int)ent->xv->modelflags<<24; +#ifdef HEXEN2 state->hexen2flags = ent->xv->drawflags; state->abslight = (int)(ent->xv->abslight*255) & 255; +#endif state->tagentity = ent->xv->tag_entity; state->tagindex = ent->xv->tag_index; diff --git a/engine/server/sv_mvd.c b/engine/server/sv_mvd.c index 250e06ba..f031b6b9 100644 --- a/engine/server/sv_mvd.c +++ b/engine/server/sv_mvd.c @@ -76,8 +76,6 @@ extern cvar_t qtv_password; //does not unlink. static void DestClose(mvddest_t *d, enum mvdclosereason_e reason) { - char path[MAX_OSPATH]; - if (d->desttype == DEST_THREADEDFILE) { while(d->flushing == true) @@ -87,7 +85,10 @@ static void DestClose(mvddest_t *d, enum mvdclosereason_e reason) if (d->cache) BZ_Free(d->cache); if (d->file) + { VFS_CLOSE(d->file); + FS_FlushFSHashWritten(d->filename); + } #ifdef HAVE_TCP if (d->socket != INVALID_SOCKET) closesocket(d->socket); @@ -95,17 +96,16 @@ static void DestClose(mvddest_t *d, enum mvdclosereason_e reason) if (reason == MVD_CLOSE_CANCEL) { - snprintf(path, MAX_OSPATH, "%s/%s", d->path, d->name); - FS_Remove(path, FS_GAMEONLY); + FS_Remove(d->filename, FS_GAMEONLY); - FS_Remove(SV_MVDName2Txt(path), FS_GAMEONLY); + FS_Remove(SV_MVDName2Txt(d->filename), FS_GAMEONLY); //SV_BroadcastPrintf (PRINT_CHAT, "Server recording canceled, demo removed\n"); } else if (d->desttype != DEST_STREAM) { char buf[512]; - SV_BroadcastPrintf (PRINT_CHAT, "Server recording complete\n^[/download %s^]\n", COM_QuotedString(va("demos/%s",d->name), buf, sizeof(buf), false)); + SV_BroadcastPrintf (PRINT_CHAT, "Server recording complete\n^[/download %s^]\n", COM_QuotedString(va("demos/%s",d->simplename), buf, sizeof(buf), false)); } Z_Free(d); @@ -1324,7 +1324,7 @@ mvddest_t *SV_FindRecordFile(char *match, mvddest_t ***link_out) f = *link; if (f->desttype == DEST_FILE || f->desttype == DEST_BUFFEREDFILE || f->desttype == DEST_THREADEDFILE) { - if (!match || !strcmp(match, f->name)) + if (!match || !strcmp(match, f->simplename)) { if (link_out) *link_out = link; @@ -1348,6 +1348,12 @@ mvddest_t *SV_MVD_InitRecordFile (char *name) char path[MAX_OSPATH]; + if (strlen(name) >= countof(dst->filename)) + { + Con_Printf ("ERROR: couldn't open \"%s\". Too long.\n", name); + return NULL; + } + file = FS_OpenVFS (name, "wb", FS_GAMEONLY); if (!file) { @@ -1357,6 +1363,7 @@ mvddest_t *SV_MVD_InitRecordFile (char *name) dst = Z_Malloc(sizeof(mvddest_t)); dst->socket = INVALID_SOCKET; + strcpy(dst->filename, name); #ifdef LOADERTHREAD if (!*sv_demoUseCache.string) @@ -1391,11 +1398,7 @@ mvddest_t *SV_MVD_InitRecordFile (char *name) s = name + strlen(name); while (*s != '/') s--; - Q_strncpyz(dst->name, s+1, sizeof(dst->name)); - Q_strncpyz(dst->path, sv_demoDir.string, sizeof(dst->path)); - - if (!*dst->path) - Q_strncpyz(dst->path, ".", MAX_OSPATH); + Q_strncpyz(dst->simplename, s+1, sizeof(dst->simplename)); switch(dst->desttype) { @@ -1442,7 +1445,7 @@ mvddest_t *SV_MVD_InitRecordFile (char *name) else { FS_Remove(path, FS_GAMEONLY); - FS_FlushFSHashRemoved(); + FS_FlushFSHashRemoved(path); } return dst; @@ -1454,7 +1457,7 @@ char *SV_Demo_CurrentOutput(void) for (d = demo.dest; d; d = d->nextdest) { if (d->desttype == DEST_FILE || d->desttype == DEST_BUFFEREDFILE || d->desttype == DEST_THREADEDFILE) - return d->name; + return d->simplename; } return "QTV"; } @@ -2394,7 +2397,7 @@ void SV_MVDList_f (void) { for (d = demo.dest; d; d = d->nextdest) { - if (!strcmp(list->name, d->name)) + if (!strcmp(list->name, d->simplename)) Con_Printf("*%d: ^[^7%s\\demo\\%s/%s^] %dk\n", i, list->name, sv_demoDir.string, list->name, d->totalsize/1024); } if (!d) @@ -2444,7 +2447,7 @@ void SV_UserCmdMVDList_f (void) { for (d = demo.dest; d; d = d->nextdest) { - if (!strcmp(list->name, d->name)) + if (!strcmp(list->name, d->simplename)) SV_ClientPrintf(host_client, PRINT_HIGH, "*%d: %s %dk\n", i, list->name, d->totalsize/1024); } if (!d) @@ -2649,7 +2652,7 @@ void SV_MVDInfoAdd_f (void) return; } - snprintf(path, MAX_OSPATH, "%s/%s", active->path, SV_MVDName2Txt(active->name)); + Q_strncpyz(path, SV_MVDName2Txt(active->filename), sizeof(path)); } else { @@ -2701,7 +2704,7 @@ void SV_MVDInfoRemove_f (void) return; } - snprintf(path, MAX_OSPATH, "%s/%s", active->path, SV_MVDName2Txt(active->name)); + snprintf(path, MAX_OSPATH, "%s", SV_MVDName2Txt(active->filename)); } else { @@ -2716,9 +2719,14 @@ void SV_MVDInfoRemove_f (void) snprintf(path, MAX_OSPATH, "%s/%s", sv_demoDir.string, name); } - if (!FS_Remove(path, FS_GAMEONLY)) + if (FS_Remove(path, FS_GAMEONLY)) + { + FS_FlushFSHashRemoved(path); + Con_Printf("file removed\n"); + } + else Con_Printf("failed to remove the file\n"); - else Con_Printf("file removed\n"); + } void SV_MVDInfo_f (void) @@ -2743,7 +2751,7 @@ void SV_MVDInfo_f (void) return; } - snprintf(path, MAX_OSPATH, "%s/%s", active->path, SV_MVDName2Txt(active->name)); + Q_strncpyz(path, SV_MVDName2Txt(active->filename), sizeof(path)); } else { diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index cee75d55..65e6051a 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -2128,7 +2128,7 @@ void WPhys_RunEntity (world_t *w, wedict_t *ent) if (ent->xv->customphysics) { - *w->g.time = sv.world.physicstime; + *w->g.time = w->physicstime; *w->g.self = EDICT_TO_PROG(w->progs, ent); PR_ExecuteProgram (w->progs, ent->xv->customphysics); } diff --git a/engine/server/sv_send.c b/engine/server/sv_send.c index 9828887f..7bc66135 100644 --- a/engine/server/sv_send.c +++ b/engine/server/sv_send.c @@ -635,7 +635,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int } } -#ifdef Q2BSPS +#if defined(Q2BSPS) || defined(Q3BSPS) //in theory, this q2/q3 path is only still different thanks to areas, but it also supports q2 gamecode properly. if (sv.world.worldmodel->fromgame == fg_quake2 || sv.world.worldmodel->fromgame == fg_quake3) { @@ -1395,7 +1395,7 @@ void SV_StartSound (int ent, vec3_t origin, float *velocity, int seenmask, int c if (!strcmp(sample, sv.strings.sound_precache[ctx.sampleidx])) break; - if ( ctx.sampleidx == MAX_PRECACHE_SOUNDS || !sv.strings.sound_precache[ctx.sampleidx] ) + if ( ctx.sampleidx >= MAX_PRECACHE_SOUNDS || !sv.strings.sound_precache[ctx.sampleidx] ) { if (ctx.sampleidx < MAX_PRECACHE_SOUNDS) { diff --git a/engine/server/world.c b/engine/server/world.c index f5475e6b..99a26d54 100644 --- a/engine/server/world.c +++ b/engine/server/world.c @@ -388,8 +388,8 @@ void World_TouchLinks (world_t *w, wedict_t *ent, areanode_t *node) World_TouchLinks (w, ent, node->children[1]); } -#ifdef Q2BSPS -void Q2BSP_FindTouchedLeafs(model_t *model, struct pvscache_s *ent, float *mins, float *maxs) +#if defined(Q2BSPS) || defined(Q3BSPS) +void Q23BSP_FindTouchedLeafs(model_t *model, struct pvscache_s *ent, float *mins, float *maxs) { #define MAX_TOTAL_ENT_LEAFS 128 int leafs[MAX_TOTAL_ENT_LEAFS]; @@ -541,13 +541,16 @@ void QDECL World_LinkEdict (world_t *w, wedict_t *ent, qboolean touch_triggers) VectorAdd (ent->v->origin, ent->v->maxs, ent->v->absmax); } + if (ent->v->modelindex) { - unsigned int mdl = ent->v->modelindex; - if (mdl < MAX_PRECACHE_MODELS && sv.models[mdl] && sv.models[mdl]->type == mod_brush) + model_t *mod = w->Get_CModel(w, ent->v->modelindex); + if (mod && mod->type == mod_brush) ent->solidsize = ES_SOLID_BSP; else ent->solidsize = COM_EncodeSize(ent->v->mins, ent->v->maxs); } + else + ent->solidsize = ES_SOLID_BSP; // // to make items easier to pick up and allow them to be grabbed off diff --git a/engine/shaders/glsl/altwater.glsl b/engine/shaders/glsl/altwater.glsl index ee72c3ba..04f2dec3 100644 --- a/engine/shaders/glsl/altwater.glsl +++ b/engine/shaders/glsl/altwater.glsl @@ -1,6 +1,6 @@ !!cvardf r_glsl_turbscale_reflect=1 //simpler scaler !!cvardf r_glsl_turbscale_refract=1 //simpler scaler -!!samps 4 diffuse +!!samps 4 diffuse normalmap #include "sys/defs.h" diff --git a/engine/shaders/glsl/defaultskin.glsl b/engine/shaders/glsl/defaultskin.glsl index 57f72600..98e65457 100644 --- a/engine/shaders/glsl/defaultskin.glsl +++ b/engine/shaders/glsl/defaultskin.glsl @@ -9,7 +9,8 @@ !!cvarf r_glsl_offsetmapping_scale !!cvarf gl_specular !!cvardf gl_affinemodels=0 -!!cvardf r_tessellation=0 +!!cvardf r_tessellation_level=5 +!!samps diffuse normalmap specular fullbright upper lower paletted #include "sys/defs.h" @@ -107,10 +108,10 @@ void main() t_eyevector[id] = eyevector[id]; #endif - gl_TessLevelOuter[0] = float(r_tessellation)+1.0; - gl_TessLevelOuter[1] = float(r_tessellation)+1.0; - gl_TessLevelOuter[2] = float(r_tessellation)+1.0; - gl_TessLevelInner[0] = float(r_tessellation)+1.0; + gl_TessLevelOuter[0] = float(r_tessellation_level); + gl_TessLevelOuter[1] = float(r_tessellation_level); + gl_TessLevelOuter[2] = float(r_tessellation_level); + gl_TessLevelInner[0] = float(r_tessellation_level); } #endif diff --git a/engine/shaders/glsl/defaultwall.glsl b/engine/shaders/glsl/defaultwall.glsl index ca65bbb7..bb3da20e 100644 --- a/engine/shaders/glsl/defaultwall.glsl +++ b/engine/shaders/glsl/defaultwall.glsl @@ -9,7 +9,8 @@ !!permu REFLECTCUBEMASK !!cvarf r_glsl_offsetmapping_scale !!cvarf gl_specular -!!cvardf r_tessellation=0 +!!cvardf r_tessellation_level=5 +!!samps diffuse lightmap specular normalmap fullbright reflectmask reflectcube paletted lightmap1 lightmap2 lightmap3 #include "sys/defs.h" @@ -137,10 +138,10 @@ void main() t_eyevector[id] = eyevector[id]; #endif - gl_TessLevelOuter[0] = float(r_tessellation)+1.0; - gl_TessLevelOuter[1] = float(r_tessellation)+1.0; - gl_TessLevelOuter[2] = float(r_tessellation)+1.0; - gl_TessLevelInner[0] = float(r_tessellation)+1.0; + gl_TessLevelOuter[0] = float(r_tessellation_level); + gl_TessLevelOuter[1] = float(r_tessellation_level); + gl_TessLevelOuter[2] = float(r_tessellation_level); + gl_TessLevelInner[0] = float(r_tessellation_level); } #endif diff --git a/engine/shaders/glsl/defaultwarp.glsl b/engine/shaders/glsl/defaultwarp.glsl index e835a1e0..7b6c153d 100644 --- a/engine/shaders/glsl/defaultwarp.glsl +++ b/engine/shaders/glsl/defaultwarp.glsl @@ -1,5 +1,6 @@ !!permu FOG !!cvarf r_wateralpha +!!samps diffuse #include "sys/defs.h" diff --git a/engine/shaders/glsl/depthonly.glsl b/engine/shaders/glsl/depthonly.glsl index 7a478034..0f8b6bb4 100644 --- a/engine/shaders/glsl/depthonly.glsl +++ b/engine/shaders/glsl/depthonly.glsl @@ -2,7 +2,7 @@ !!permu TESS !!permu FRAMEBLEND !!permu SKELETAL -!!cvardf r_tessellation=0 +!!cvardf r_tessellation_level=5 #include "sys/defs.h" @@ -44,10 +44,10 @@ void main() #define id gl_InvocationID t_vertex[id] = vertex[id]; t_normal[id] = normal[id]; - gl_TessLevelOuter[0] = float(r_tessellation)+1.0; - gl_TessLevelOuter[1] = float(r_tessellation)+1.0; - gl_TessLevelOuter[2] = float(r_tessellation)+1.0; - gl_TessLevelInner[0] = float(r_tessellation)+1.0; + gl_TessLevelOuter[0] = float(r_tessellation_level); + gl_TessLevelOuter[1] = float(r_tessellation_level); + gl_TessLevelOuter[2] = float(r_tessellation_level); + gl_TessLevelInner[0] = float(r_tessellation_level); } #endif diff --git a/engine/shaders/glsl/rtlight.glsl b/engine/shaders/glsl/rtlight.glsl index ceb7b4c3..830d7948 100644 --- a/engine/shaders/glsl/rtlight.glsl +++ b/engine/shaders/glsl/rtlight.glsl @@ -8,7 +8,8 @@ !!permu REFLECTCUBEMASK !!cvarf r_glsl_offsetmapping_scale !!cvardf r_glsl_pcf -!!cvardf r_tessellation=0 +!!cvardf r_tessellation_level=5 +!!samps shadowmap diffuse normalmap specular upper lower reflectcube reflectmask #include "sys/defs.h" @@ -142,10 +143,10 @@ void main() t_eyevector[id] = eyevector[id]; #endif - gl_TessLevelOuter[0] = float(r_tessellation)+1.0; - gl_TessLevelOuter[1] = float(r_tessellation)+1.0; - gl_TessLevelOuter[2] = float(r_tessellation)+1.0; - gl_TessLevelInner[0] = float(r_tessellation)+1.0; + gl_TessLevelOuter[0] = float(r_tessellation_level); + gl_TessLevelOuter[1] = float(r_tessellation_level); + gl_TessLevelOuter[2] = float(r_tessellation_level); + gl_TessLevelInner[0] = float(r_tessellation_level); } #endif diff --git a/engine/vk/vk_backend.c b/engine/vk/vk_backend.c index c077e6ae..0138124d 100644 --- a/engine/vk/vk_backend.c +++ b/engine/vk/vk_backend.c @@ -1537,6 +1537,7 @@ void VKBE_Set2D(qboolean twodee) shaderstate.forcebeflags = BEF_FORCENODEPTH; else shaderstate.forcebeflags = 0; + shaderstate.curtime = realtime; } //called at the start of each frame @@ -1815,26 +1816,24 @@ static void colourgen(const shaderpass_t *pass, int cnt, byte_vec4_t *srcb, avec } break; case RGB_GEN_VERTEX_LIGHTING: +#if MAXRLIGHTMAPS > 1 if (mesh->colors4f_array[1]) { float lm[MAXRLIGHTMAPS]; lm[0] = d_lightstylevalue[shaderstate.curbatch->vtlightstyle[0]]/256.0f*shaderstate.identitylighting; -#if MAXRLIGHTMAPS > 1 lm[1] = d_lightstylevalue[shaderstate.curbatch->vtlightstyle[1]]/256.0f*shaderstate.identitylighting; lm[2] = d_lightstylevalue[shaderstate.curbatch->vtlightstyle[2]]/256.0f*shaderstate.identitylighting; lm[3] = d_lightstylevalue[shaderstate.curbatch->vtlightstyle[3]]/256.0f*shaderstate.identitylighting; -#endif while((cnt)--) { VectorScale( mesh->colors4f_array[0][cnt], lm[0], dst[cnt]); -#if MAXRLIGHTMAPS > 1 VectorMA(dst[cnt], lm[1], mesh->colors4f_array[1][cnt], dst[cnt]); VectorMA(dst[cnt], lm[2], mesh->colors4f_array[2][cnt], dst[cnt]); VectorMA(dst[cnt], lm[3], mesh->colors4f_array[3][cnt], dst[cnt]); -#endif } break; } +#endif if (shaderstate.identitylighting != 1) { @@ -2339,7 +2338,7 @@ static void tcmod(const tcmod_t *tcmod, int cnt, const float *src, float *dst, c t1 = src[0]; t2 = src[1]; dst[0] = t1 * tcmod->args[0] + t2 * tcmod->args[2] + tcmod->args[4]; - dst[1] = t2 * tcmod->args[1] + t1 * tcmod->args[3] + tcmod->args[5]; + dst[1] = t1 * tcmod->args[1] + t1 * tcmod->args[3] + tcmod->args[5]; } break; @@ -3113,6 +3112,7 @@ static qboolean BE_SetupMeshProgram(program_t *p, shaderpass_t *pass, unsigned i delux = lightmap[lmi+1]->lightmap_texture; BE_SetupTextureDescriptor(delux, r_whiteimage, set, descs, desc++, img++); } +#if MAXRLIGHTMAPS > 1 if (p->defaulttextures & ((1u<<13)|(1u<<14)|(1u<<15))) { int lmi = shaderstate.curbatch->lightmap[1]; @@ -3140,6 +3140,7 @@ static qboolean BE_SetupMeshProgram(program_t *p, shaderpass_t *pass, unsigned i BE_SetupTextureDescriptor(NULL, r_whiteimage, set, descs, desc++, img++); } } +#endif //shader / pass for (i = 0; i < p->numsamplers; i++) diff --git a/engine/web/fs_web.c b/engine/web/fs_web.c index 9a25e843..f16ce125 100644 --- a/engine/web/fs_web.c +++ b/engine/web/fs_web.c @@ -155,7 +155,7 @@ vfsfile_t *VFSOS_Open(const char *osname, const char *mode) qboolean needsflush; f = VFSWEB_Open(osname, mode, &needsflush); if (needsflush) - FS_FlushFSHashReally(true); + FS_FlushFSHash(); return f; } diff --git a/plugins/mpq/fs_mpq.c b/plugins/mpq/fs_mpq.c index 655f8daf..e3c3bcce 100644 --- a/plugins/mpq/fs_mpq.c +++ b/plugins/mpq/fs_mpq.c @@ -298,7 +298,7 @@ static unsigned int MPQ_FindFile(searchpathfuncs_t *handle, flocation_t *loc, co } if (loc) { - loc->index = blockentry; + loc->fhandle = &mpq->blockdata[blockentry]; loc->offset = 0; *loc->rawname = 0; loc->len = mpq->blockdata[blockentry].size; @@ -428,7 +428,7 @@ static void MPQ_BuildHash(searchpathfuncs_t *handle, int depth, void (QDECL *Add //precompute the name->block lookup. fte normally does the hashing outside the archive code. //however, its possible multiple hash tables point to a single block, so we need to pass null for the third arg (or allocate fsbucket_ts one per hash instead of buckets). if (MPQ_FindFile(&mpq->pub, &loc, name, NULL)) - AddFileHash(depth, name, NULL, &mpq->blockdata[loc.index]); + AddFileHash(depth, name, NULL, loc.fhandle); } } } @@ -851,7 +851,7 @@ static qboolean MPQF_GetKey(unsigned int flags, unsigned int blockoffset, unsign static vfsfile_t *MPQ_OpenVFS(searchpathfuncs_t *handle, flocation_t *loc, const char *mode) { mpqarchive_t *mpq = (void*)handle; - mpqblock_t *block = &mpq->blockdata[loc->index]; + mpqblock_t *block = loc->fhandle; mpqfile_t *f; if (block->flags & MPQFilePatch)