From 66b78c0b11297a9d321f282178c5ea19905e1024 Mon Sep 17 00:00:00 2001 From: Spoike Date: Wed, 4 Nov 2009 21:16:50 +0000 Subject: [PATCH] Work In Progress branch. In this version: replacement GL backend. Replacement D3D backend sharing code with GL. Lots of code reorganisation. git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3401 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/Makefile | 72 +- engine/client/bymorphed.ico | Bin 3310 -> 3310 bytes engine/client/cl_cam.c | 4 +- engine/client/cl_cg.c | 102 +- engine/client/cl_demo.c | 44 +- engine/client/cl_ents.c | 315 +- engine/client/cl_ignore.c | 16 +- engine/client/cl_input.c | 176 +- engine/client/cl_main.c | 149 +- engine/client/cl_parse.c | 63 +- engine/client/cl_plugin.inc | 9 +- engine/client/cl_pred.c | 24 +- engine/client/cl_screen.c | 555 ++- engine/client/cl_tent.c | 29 +- engine/client/cl_ui.c | 184 +- engine/client/clhl_game.c | 437 +- engine/client/client.h | 100 +- engine/client/clq2_ents.c | 56 +- engine/client/clq3_parse.c | 5 - engine/client/clq3defs.h | 10 + engine/client/console.c | 117 +- engine/client/fragstats.c | 4 +- engine/client/image.c | 141 +- engine/client/in_win.c | 57 +- engine/client/keys.h | 2 +- engine/client/m_download.c | 20 +- engine/client/m_items.c | 247 +- engine/client/m_master.c | 87 +- engine/client/m_mp3.c | 124 +- engine/client/m_multi.c | 33 +- engine/client/m_options.c | 70 +- engine/client/m_script.c | 10 +- engine/client/m_single.c | 72 +- engine/client/menu.c | 243 +- engine/client/menu.h | 21 +- engine/client/merged.h | 42 +- engine/client/net_master.c | 2 +- engine/client/p_classic.c | 262 +- engine/client/p_null.c | 9 +- engine/client/p_script.c | 946 ++--- engine/client/pr_csqc.c | 667 +-- engine/client/pr_menu.c | 162 +- engine/client/q2.ico | Bin 2734 -> 2734 bytes engine/client/quakedef.h | 32 +- engine/client/r_2d.c | 278 ++ engine/client/r_bulleten.c | 6 +- engine/client/r_bulleten.h | 4 - engine/client/r_efrag.c | 4 +- engine/client/r_part.c | 2 - engine/client/render.h | 194 +- engine/client/renderer.c | 724 ++-- engine/client/resource.h | 11 +- engine/client/sbar.c | 606 ++- engine/client/sbar.h | 5 +- engine/client/screen.h | 20 +- engine/client/skin.c | 23 +- engine/client/snd_directx.c | 16 +- engine/client/snd_dma.c | 58 +- engine/client/snd_mem.c | 4 +- engine/client/snd_mp3.c | 5 - engine/client/snd_ov.c | 10 +- engine/client/sound.h | 1 + engine/client/sys_win.c | 630 +-- engine/client/textedit.c | 24 +- engine/client/valid.c | 45 +- engine/client/vid.h | 23 +- engine/client/view.c | 32 +- engine/client/view.h | 2 +- engine/client/wad.c | 39 +- engine/client/wad.h | 14 +- engine/client/zqtp.c | 22 +- engine/common/bothdefs.h | 46 +- engine/common/bspfile.h | 23 +- engine/common/cmd.c | 50 +- engine/common/cmd.h | 7 +- engine/common/com_mesh.c | 624 +-- engine/common/com_mesh.h | 23 +- engine/common/common.c | 76 +- engine/common/common.h | 18 +- engine/common/console.h | 8 +- engine/common/cvar.c | 13 +- engine/common/cvar.h | 1 + engine/common/fs.c | 43 +- engine/common/fs_stdio.c | 10 +- engine/common/fs_zip.c | 4 - engine/common/gl_q2bsp.c | 435 +- engine/common/mathlib.c | 79 +- engine/common/mathlib.h | 36 +- engine/common/net.h | 8 +- engine/common/net_wins.c | 2 +- engine/common/particles.h | 2 - engine/common/plugin.c | 4 +- engine/common/pmove.h | 1 + engine/common/pr_bgcmd.c | 11 +- engine/common/pr_common.h | 113 +- engine/common/protocol.h | 13 +- engine/common/q1bsp.c | 52 +- engine/common/q2pmove.c | 2 +- engine/common/q3common.c | 4 +- engine/common/sys.h | 10 +- engine/common/translate.c | 4 +- engine/common/vm.h | 3 +- engine/common/world.h | 83 +- engine/{d3d/d3d_draw.c => d3d7/d3d7_draw.c} | 0 engine/{d3d/d3d_mesh.c => d3d7/d3d7_mesh.c} | 0 engine/{d3d/d3d_rmain.c => d3d7/d3d7_rmain.c} | 3 - engine/{d3d/d3d_rsurf.c => d3d7/d3d7_rsurf.c} | 0 engine/{d3d/d3dquake.h => d3d7/d3d7quake.h} | 0 engine/{d3d/vid_d3d.c => d3d7/vid_d3d7.c} | 11 +- engine/d3d9/d3d9_draw.c | 22 +- engine/d3d9/d3d9_rmain.c | 3725 ++++++++-------- engine/d3d9/d3d9quake.h | 392 +- engine/d3d9/vid_d3d9.c | 6 +- engine/dotnet2005/ftequake.sln | 71 +- engine/dotnet2005/ftequake.vcproj | 2796 ++++-------- engine/dotnet2005/npqtv.vcproj | 28 + engine/dotnet2005/resource.h | 8 +- engine/ftequake/ftequake.dsp | 3754 +---------------- engine/ftequake/ftequake.dsw | 27 + engine/gl/gl_alias.c | 1073 ++--- engine/gl/gl_backend.c | 2791 +++++++++++- engine/gl/gl_bloom.c | 64 +- engine/gl/gl_draw.c | 2042 ++------- engine/gl/gl_draw.h | 32 +- engine/gl/gl_font.c | 869 ++-- engine/gl/gl_heightmap.c | 51 +- engine/gl/gl_hlmdl.c | 10 +- engine/gl/gl_model.c | 747 ++-- engine/gl/gl_model.h | 125 +- engine/gl/gl_ngraph.c | 20 +- engine/gl/gl_ppl.c | 182 +- engine/gl/gl_rlight.c | 46 +- engine/gl/gl_rmain.c | 625 +-- engine/gl/gl_rmisc.c | 339 +- engine/gl/gl_rsurf.c | 687 +-- engine/gl/gl_screen.c | 57 +- engine/gl/gl_shader.c | 2180 +++++----- engine/gl/gl_shadow.c | 2321 ++++++++++ engine/gl/gl_vidcommon.c | 274 +- engine/gl/gl_vidlinuxglx.c | 18 +- engine/gl/gl_vidnt.c | 132 +- engine/gl/gl_warp.c | 1008 +---- engine/gl/glmod_doom.c | 12 +- engine/gl/glquake.h | 176 +- engine/gl/glsupp.h | 67 + engine/gl/gltod3d/gl_fakegl.cpp | 4 +- engine/gl/ltface.c | 23 +- engine/gl/model_hl.h | 6 +- engine/gl/shader.h | 242 +- engine/http/ftpclient.c | 12 +- engine/http/ftpserver.c | 48 +- engine/http/httpserver.c | 18 +- engine/http/iweb.h | 40 +- engine/http/iwebiface.c | 82 +- engine/http/webgen.c | 4 +- engine/libs/vorbis/vorbisfile.h | 8 +- engine/qclib/cmdlib.h | 11 +- engine/qclib/initlib.c | 5 +- engine/qclib/pr_edict.c | 17 +- engine/qclib/pr_x86.c | 62 +- engine/qclib/progsint.h | 16 +- engine/qclib/progslib.h | 31 +- engine/qclib/qcc.h | 1 + engine/qclib/qcc_pr_comp.c | 1 + engine/qclib/qcc_pr_lex.c | 36 +- engine/qclib/qccmain.c | 186 +- engine/server/net_preparse.c | 4 +- engine/server/pr_cmds.c | 498 +-- engine/server/pr_q1qvm.c | 118 +- engine/server/progdefs.h | 360 +- engine/server/progs.h | 96 +- engine/server/q2game.h | 11 +- engine/server/qwsvdef.h | 6 +- engine/server/savegame.c | 16 +- engine/server/server.h | 118 +- engine/server/sv_ccmds.c | 12 +- engine/server/sv_demo.c | 3 +- engine/server/sv_ents.c | 60 +- engine/server/sv_init.c | 64 +- engine/server/sv_main.c | 124 +- engine/server/sv_move.c | 36 +- engine/server/sv_mvd.c | 10 +- engine/server/sv_phys.c | 193 +- engine/server/sv_send.c | 64 +- engine/server/sv_sys_unix.c | 4 +- engine/server/sv_sys_win.c | 4 +- engine/server/sv_user.c | 153 +- engine/server/svhl_game.c | 330 +- engine/server/svhl_gcapi.h | 446 +- engine/server/svq2_ents.c | 25 +- engine/server/svq2_game.c | 57 +- engine/server/svq3_game.c | 461 +- engine/server/world.c | 486 +-- plugins/paths.bat | 4 +- plugins/plugins.dsw | 14 +- plugins/xsv/m_x.c | 2 + plugins/xsv/x_reqs.c | 4 +- specs/antilag.txt | 14 + specs/distort.pk3 | Bin 0 -> 880 bytes specs/distort.txt | 13 + specs/example.shader | 4 +- specs/ext_csqc_1.txt | 15 +- specs/rtlights.txt | 22 + specs/videocapture.txt | 64 + 204 files changed, 20477 insertions(+), 21412 deletions(-) create mode 100644 engine/client/r_2d.c rename engine/{d3d/d3d_draw.c => d3d7/d3d7_draw.c} (100%) rename engine/{d3d/d3d_mesh.c => d3d7/d3d7_mesh.c} (100%) rename engine/{d3d/d3d_rmain.c => d3d7/d3d7_rmain.c} (96%) rename engine/{d3d/d3d_rsurf.c => d3d7/d3d7_rsurf.c} (100%) rename engine/{d3d/d3dquake.h => d3d7/d3d7quake.h} (100%) rename engine/{d3d/vid_d3d.c => d3d7/vid_d3d7.c} (95%) create mode 100644 engine/gl/gl_shadow.c create mode 100644 specs/antilag.txt create mode 100644 specs/distort.pk3 create mode 100644 specs/distort.txt create mode 100644 specs/rtlights.txt create mode 100644 specs/videocapture.txt diff --git a/engine/Makefile b/engine/Makefile index 250df18c..b0708ec4 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -168,7 +168,7 @@ PROFILE_DIR=$(BASE_DIR)/profile ALL_CFLAGS=$(HAVECONFIG) $(CFLAGS) $(BASE_CFLAGS) $(WCFLAGS) -DO_CC=$(CC) $(ALL_CFLAGS) -o $@ -c $< +DO_CC=@echo $< && $(CC) $(ALL_CFLAGS) -o $@ -c $< ifeq ($(USEASM),true) ifdef windir DO_AS=$(CC) $(BASE_CFLAGS) $(WCFLAGS) -x assembler-with-cpp -o $@ -c $< $(CFLAGS) @@ -177,6 +177,9 @@ ifeq ($(USEASM),true) endif endif +ifeq ($(FTE_TARGET),vc) + BASELDFLAGS= +endif ifeq ($(FTE_TARGET),win32) BASELDFLAGS=-lm endif @@ -236,7 +239,16 @@ else BASE_ASM_CFLAGS = -DNOASM endif -BASE_CFLAGS=$(BASE_ASM_CFLAGS) -Wall -Dstrnicmp=strncasecmp -Dstricmp=strcasecmp -I$(CLIENT_DIR) -I$(SERVER_DIR) -I$(COMMON_DIR) -I$(GL_DIR) -I$(D3D9_DIR) -I$(D3D7_DIR) -I$(PROGS_DIR) -I$(LIBS_DIR) -I$(LIBS_DIR)/dxsdk7/include -I$(LIBS_DIR)/sdl/include -I$(LIBS_DIR)/sdl/include/SDL -I./libs/freetype2/include -I./libs/freetype2/include/freetype -D_vsnprintf=vsnprintf -D_snprintf=snprintf $(SVNREVISION) +ifeq ($(FTE_TARGET),vc) + WARNINGFLAGS=-W3 -D_CRT_SECURE_NO_WARNINGS + GNUC_FUNCS= +else + WARNINGFLAGS=-Wall + + GNUC_FUNCS= -Dstrnicmp=strncasecmp -Dstricmp=strcasecmp -D_vsnprintf=vsnprintf -D_snprintf=snprintf +endif + +BASE_CFLAGS=$(BASE_ASM_CFLAGS) $(WARNINGFLAGS) $(GNUC_FUNCS) -I$(CLIENT_DIR) -I$(SERVER_DIR) -I$(COMMON_DIR) -I$(GL_DIR) -I$(D3D9_DIR) -I$(D3D7_DIR) -I$(PROGS_DIR) -I$(LIBS_DIR) -I$(LIBS_DIR)/dxsdk7/include -I$(LIBS_DIR)/sdl/include -I$(LIBS_DIR)/sdl/include/SDL -I./libs/freetype2/include -I./libs/freetype2/include/freetype $(SVNREVISION) CLIENT_ONLY_CFLAGS=-DCLIENTONLY SERVER_ONLY_CFLAGS=-DSERVERONLY JOINT_CFLAGS= @@ -341,7 +353,8 @@ GLQUAKE_OBJS = \ ltface.o \ gl_screen.o \ gl_bloom.o \ - gl_backend.o \ + gl_vbo.o \ + gl_shadow.o \ gl_shader.o \ gl_warp.o \ gl_ppl.o \ @@ -478,7 +491,7 @@ GLCL_DIR=glcl_sdl$(BITS) SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(SERVERONLY_OBJS) SV_EXE_NAME=../fteqw_sdl.sv$(BITS) -SV_CFLAGS=$(SERVER_ONLY_CFLAGS) -lz +SV_CFLAGS=$(SERVER_ONLY_CFLAGS) MINGL_DIR=mingl_sdl$(BITS) MINGL_EXE_NAME=../fteqw_sdl.mingl$(BITS) @@ -537,6 +550,35 @@ ifeq ($(FTE_TARGET),win32_SDL) endif endif +ifeq ($(FTE_TARGET),vc) + CC=cl + DEBUG_CFLAGS ?= -Od $(CPUOPTIMIZATIONS) /fp:fast + PROFILE_CFLAGS = -O2 -Ot -Ox -GL $(CPUOPTIMISATIONS) /fp:fast + PROFILE_LDFLAGS = /LTCG:PGINSTRUMENT + RELEASE_CFLAGS = -O2 -Ot -Ox -GL $(CPUOPTIMIZATIONS) /fp:fast + RELEASE_LDFLAGS = /LTCG:PGOPTIMIZE + + + DO_CC=@$(CC) /nologo $(ALL_CFLAGS) -Fo$@ -c $< + DO_LD=link /nologo /out:$@ wsock32.lib user32.lib advapi32.lib winmm.lib libs/zlib.lib shell32.lib /nodefaultlib:libc.lib /nodefaultlib:MSVCRT /manifest:no /OPT:REF + PRECOMPHEADERS = + NODEPS = 1 + + LIBS_DIR=./libs/ + + SV_CFLAGS=$(SERVER_ONLY_CFLAGS) $(W32_CFLAGS) + SV_EXE_NAME=../fteqwsv.exe + SV_DIR=sv_vc + SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(WINDOWSSERVERONLY_OBJS) fs_win32.o resources.o + SV_LDFLAGS=/subsystem:console + + M_EXE_NAME=../fteqw.exe + MCL_OBJS=$(GL_OBJS) $(GLQUAKE_OBJS) fs_win32.o gl_vidnt.o snd_win.o snd_directx.o cd_win.o in_win.o sys_win.o resources.o + M_CFLAGS=$(GLCFLAGS) $(W32_CFLAGS) + MB_DIR=m_vc + M_LDFLAGS=$(GLLDFLAGS) libs/jpeg.lib libs/libpng.lib libs/zlib.lib uuid.lib gdi32.lib ole32.lib libs/dxsdk7/lib/dxguid.lib /subsystem:windows +endif + ifeq ($(FTE_TARGET),win32) # The extra object file called resources.o is specific for MinGW to link the icon in @@ -808,17 +850,21 @@ $(OUT_DIR)/npplug.o : ftequake/npplug.rc # rm -f $@.$$$$ $(OUT_DIR)/%.o $(OUT_DIR)/%.d : %.c +ifeq ($(NODEPS),) @set -e; rm -f $@.d; \ $(CC) -MM $(ALL_CFLAGS) $< > $@.d.$$$$; \ sed 's,\($*\)\.o[ :]*,\1.o $@.d : ,g' < $@.d.$$$$ > $@.d; \ rm -f $@.d.$$$$ +endif $(DO_CC) -I$(OUT_DIR) $(OUT_DIR)/%.oo $(OUT_DIR)/%.d : %.c +ifeq ($(NODEPS),) @set -e; rm -f $@.d; \ $(CC) -MM $(ALL_CFLAGS) $< > $@.d.$$$$; \ sed 's,\($*\)\.oo[ :]*,\1.oo $@.d : ,g' < $@.d.$$$$ > $@.d; \ rm -f $@.d.$$$$ +endif $(DO_CC) -I$(OUT_DIR) $(OUT_DIR)/%.mo $(OUT_DIR)/%.d : %.m @@ -831,6 +877,7 @@ $(OUT_DIR)/%.mo $(OUT_DIR)/%.d : %.m #enables use of precompiled headers in gcc 3.4 onwards. $(OUT_DIR)/quakedef.h.gch : quakedef.h $(CC) -x c $(BASE_CFLAGS) $(WCFLAGS) -o $@ -c $< $(CFLAGS) +PRECOMPHEADERS ?= $(OUT_DIR)/quakedef.h.gch #addprefix is to add the ./release/server/ part of the object name #foreach is needed as the OBJS is a list of variable names containing object lists. @@ -838,18 +885,19 @@ $(OUT_DIR)/quakedef.h.gch : quakedef.h #god knows how gcc loads the list properly. #or at least I hope he does. It makes no sence to mortals. -$(OUT_DIR)/$(EXE_NAME): $(OUT_DIR)/quakedef.h.gch $(addprefix $(OUT_DIR)/, $(CUSTOMOBJS) $(foreach ol, $(OBJS), $($(ol)))) - $(CC) $(WCFLAGS) -o $@ $(addprefix $(OUT_DIR)/, $(CUSTOMOBJS) $(foreach ol, $(OBJS), $($(ol)))) $(LDFLAGS) $(CFLAGS) +DO_LD ?= $(CC) -o $@ $(WCFLAGS) $(CFLAGS) +$(OUT_DIR)/$(EXE_NAME): $(PRECOMPHEADERS) $(addprefix $(OUT_DIR)/, $(CUSTOMOBJS) $(foreach ol, $(OBJS), $($(ol)))) + $(DO_LD) $(addprefix $(OUT_DIR)/, $(CUSTOMOBJS) $(foreach ol, $(OBJS), $($(ol)))) $(LDFLAGS) _out-rel: - $(MAKE) $(OUT_DIR)/$(EXE_NAME) EXE_NAME="$(EXE_NAME)" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(WCFLAGS) $(RELEASE_CFLAGS)" LDFLAGS="$(BASELDFLAGS) $(LDFLAGS)" OBJS="$(OBJS)" + $(MAKE) $(OUT_DIR)/$(EXE_NAME) EXE_NAME="$(EXE_NAME)" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(WCFLAGS) $(RELEASE_CFLAGS)" LDFLAGS="$(BASELDFLAGS) $(LDFLAGS) $(RELEASE_LDFLAGS)" OBJS="$(OBJS)" $(STRIP) $(STRIPFLAGS) $(OUT_DIR)/$(EXE_NAME) _out-dbg: - $(MAKE) $(OUT_DIR)/$(EXE_NAME) EXE_NAME="$(EXE_NAME)" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(WCFLAGS) $(DEBUG_CFLAGS)" LDFLAGS="$(BASELDFLAGS) $(LDFLAGS)" OBJS="$(OBJS)" + $(MAKE) $(OUT_DIR)/$(EXE_NAME) EXE_NAME="$(EXE_NAME)" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(WCFLAGS) $(DEBUG_CFLAGS)" LDFLAGS="$(BASELDFLAGS) $(LDFLAGS) $(DEBUG_LDFLAGS)" OBJS="$(OBJS)" _out-profile: - $(MAKE) $(OUT_DIR)/$(EXE_NAME) EXE_NAME="$(EXE_NAME)" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(WCFLAGS) $(PROFILE_CFLAGS)" LDFLAGS="$(BASELDFLAGS) $(LDFLAGS)" OBJS="$(OBJS)" + $(MAKE) $(OUT_DIR)/$(EXE_NAME) EXE_NAME="$(EXE_NAME)" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(WCFLAGS) $(PROFILE_CFLAGS)" LDFLAGS="$(BASELDFLAGS) $(LDFLAGS) $(PROFILE_LDFLAGS)" OBJS="$(OBJS)" _cl-rel: reldir $(MAKE) _out-rel EXE_NAME="$(EXE_NAME)" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(CLIENT_ONLY_CFLAGS) $(WCFLAGS)" LDFLAGS="$(LDFLAGS)" SOBJS="$(SOBJS)" OBJS="SOBJS COMMON_OBJS CLIENT_OBJS PROGS_OBJS" @@ -1003,6 +1051,12 @@ help: @-echo "'d3d-???' (for windows builds)" @-echo "'mcl-???' (currently broken)" @-echo "'glcl-???' (currently broken)" + @-echo "" + @-echo "Cross targets can be specified with FTE_TARGET=blah" + @-echo "linux32, linux64 specify specific x86 archs" + @-echo "SDL - Attempt to use sdl for the current target" + @-echo "win32 - Mingw compile for win32" + @-echo "vc - Attempts to use msvc8+ to compile. Note: uses profile guided optimisations. You must build+run the relevent profile target before a release target will compile properly. Debug doesn't care." install: -cp debug/*.* /opt/quake/ diff --git a/engine/client/bymorphed.ico b/engine/client/bymorphed.ico index 1092b755735a7a0d74f1bcc0a4fe68273aef8607..0209e9fafffd10008d7ff677d0b975943b961acd 100644 GIT binary patch delta 81 zcmaDS`A$-ofq{{MnL$B8fPsO5h2aGg1A`fmrJw*L7&sVKa4;~)F*7g-2!Q1`>asEm U0hJ*DBaq2BF-B=~8gmCH0CpJ&y8r+H delta 69 zcmaDS`A$-ofq{{MnL$B8fB^(vFflNg0ciyV5RZXj1qTCz95VxhfB;y2qb@5mQv=K7 Qi%b#|Q=~ShF?VnR07A+NmjD0& diff --git a/engine/client/cl_cam.c b/engine/client/cl_cam.c index 9d43141e..428701fd 100644 --- a/engine/client/cl_cam.c +++ b/engine/client/cl_cam.c @@ -100,7 +100,7 @@ qboolean Cam_DrawViewModel(int pnum) { if (cl.spectator) { - if (autocam[pnum] && locked[pnum] && cl_chasecam.value) + if (autocam[pnum] && locked[pnum] && cl_chasecam.ival) return true; return false; } @@ -624,7 +624,7 @@ void Cam_FinishMove(int pnum, usercmd_t *cmd) } } - if (autocam[pnum] && cl_hightrack.value) + if (autocam[pnum] && cl_hightrack.ival) { Cam_CheckHighTarget(pnum); return; diff --git a/engine/client/cl_cg.c b/engine/client/cl_cg.c index a0d3e4b1..049b5252 100644 --- a/engine/client/cl_cg.c +++ b/engine/client/cl_cg.c @@ -2,7 +2,7 @@ //#include "cg_public.h" #ifdef VM_CG -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "shader.h" @@ -15,14 +15,8 @@ typedef float m3by3_t[3][3]; #include "clq3defs.h" //cl_ui.c -typedef struct q3refEntity_s q3refEntity_t; -void VQ3_AddEntity(const q3refEntity_t *q3); -typedef struct q3refdef_s q3refdef_t; -void VQ3_RenderView(const q3refdef_t *ref); void CG_Command_f(void); -void GLDraw_ShaderImage (int x, int y, int w, int h, float s1, float t1, float s2, float t2, shader_t *pic); - #define CGAME_IMPORT_API_VERSION 4 #define CGTAGNUM 5423 @@ -268,6 +262,12 @@ void CG_InsertIntoGameState(int num, char *str) Con_DPrintf("%i: %s", num, str); } + if (num == CFGSTR_SYSINFO) + { + //check some things. + cl.servercount = atoi(Info_ValueForKey(str, "sv_serverid")); + } + if (cggamestate.dataCount + strlen(str)+1 > MAX_GAMESTATE_CHARS) { char oldstringData[MAX_GAMESTATE_CHARS]; @@ -378,16 +378,15 @@ typedef struct { int numPoints; } markFragment_t; int CG_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projection, - int maxPoints, vec3_t pointBuffer, int maxFragments, markFragment_t *fragmentBuffer ) + int maxPoints, float *pointBuffer, int maxFragments, markFragment_t *fragmentBuffer ) { -#if 1 //FIXME: make work - return 0; -#else vec3_t center; vec3_t axis[3]; vec3_t p[4]; int i; + float *clippedpoints; float radius; + int numtris; if (numPoints != 4) return 0; @@ -407,10 +406,10 @@ int CG_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projecti */ VectorClear(center); - VectorAdd(center, points[0], center); - VectorAdd(center, points[1], center); - VectorAdd(center, points[2], center); - VectorAdd(center, points[3], center); + VectorMA(center, 0.25, points[0], center); + VectorMA(center, 0.25, points[1], center); + VectorMA(center, 0.25, points[2], center); + VectorMA(center, 0.25, points[3], center); VectorSubtract(points[0], center, p[0]); VectorSubtract(points[1], center, p[1]); @@ -419,23 +418,35 @@ int CG_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projecti for (i = 0; i < 3; i++) { - axis[1][i] = (p[2][i]+p[1][i])/2; - axis[2][i] = (p[2][i]+p[3][i])/2; + axis[1][i] = (p[2][i]-p[1][i]); + axis[2][i] = (p[3][i]-p[2][i]); } radius = VectorNormalize(axis[1]); VectorNormalize(axis[2]); - VectorNormalize(projection); + VectorNormalize2(projection, axis[0]); - + numtris = Q1BSP_ClipDecal(center, axis[0], axis[1], axis[2], radius, &clippedpoints); + if (numtris > maxFragments) + numtris = maxFragments; + if (numtris > maxPoints/3) + numtris = maxPoints/3; + for (i = 0; i < numtris; i++) + { + fragmentBuffer[i].numPoints = 3; + fragmentBuffer[i].firstPoint = i*3; - - Q1BSP_ClipDecal(center, axis[0], axis[1], axis[2], radius, pointBuffer, maxPoints); - fragmentBuffer->firstPoint = 0; - fragmentBuffer->numPoints = 0; - - return 1; -#endif + pointBuffer[i*9+0] = clippedpoints[i*9+0]; + pointBuffer[i*9+1] = clippedpoints[i*9+1]; + pointBuffer[i*9+2] = clippedpoints[i*9+2]; + pointBuffer[i*9+3] = clippedpoints[i*9+3]; + pointBuffer[i*9+4] = clippedpoints[i*9+4]; + pointBuffer[i*9+5] = clippedpoints[i*9+5]; + pointBuffer[i*9+6] = clippedpoints[i*9+6]; + pointBuffer[i*9+7] = clippedpoints[i*9+7]; + pointBuffer[i*9+8] = clippedpoints[i*9+8]; + } + return numtris; } @@ -462,10 +473,10 @@ static int CG_SystemCallsEx(void *offset, unsigned int mask, int fn, const int * switch(fn) { case CG_PRINT: - Con_Printf("%s", VM_POINTER(arg[0])); + Con_Printf("%s", (char*)VM_POINTER(arg[0])); break; case CG_ERROR: - Host_EndGame("cgame: %s", VM_POINTER(arg[0])); + Host_EndGame("cgame: %s", (char*)VM_POINTER(arg[0])); break; case CG_ARGC: @@ -518,23 +529,21 @@ static int CG_SystemCallsEx(void *offset, unsigned int mask, int fn, const int * break; case CG_SENDCONSOLECOMMAND: - Con_DPrintf("CG_SENDCONSOLECOMMAND: %s", VM_POINTER(arg[0])); + Con_DPrintf("CG_SENDCONSOLECOMMAND: %s", (char*)VM_POINTER(arg[0])); Cbuf_AddText(VM_POINTER(arg[0]), RESTRICT_SERVER); break; case CG_ADDCOMMAND: Cmd_AddRemCommand(VM_POINTER(arg[0]), NULL); break; case CG_SENDCLIENTCOMMAND: - Con_DPrintf("CG_SENDCLIENTCOMMAND: %s", VM_POINTER(arg[0])); - CL_SendClientCommand(true, "%s", VM_POINTER(arg[0])); + Con_DPrintf("CG_SENDCLIENTCOMMAND: %s", (char*)VM_POINTER(arg[0])); + CL_SendClientCommand(true, "%s", (char*)VM_POINTER(arg[0])); break; case CG_UPDATESCREEN: //force a buffer swap cos loading won't refresh it soon. SCR_BeginLoadingPlaque(); SCR_UpdateScreen(); SCR_EndLoadingPlaque(); -// GL_EndRendering(); -// GL_DoSwap(); break; case CG_FS_FOPENFILE: //fopen @@ -776,13 +785,15 @@ static int CG_SystemCallsEx(void *offset, unsigned int mask, int fn, const int * // VM_LONG(ret) = VM_TOHANDLE(Draw_SafeCachePic(VM_POINTER(arg[0]))); break; - case CG_R_CLEARSCENE: //clear scene - cl_numvisedicts=0; - dlights_running=0; - dlights_software=0; + case CG_R_CLEARSCENE: //clear scene (not rtlights, only dynamic ones) + cl_numvisedicts = 0; + cl_numstrisidx = 0; + cl_numstrisvert = 0; + cl_numstris = 0; + rtlights_first = RTL_FIRST; break; case CG_R_ADDPOLYTOSCENE: - // ... + VQ3_AddPoly(VM_FROMSHANDLE(arg[0]), VM_LONG(arg[1]), VM_POINTER(arg[2])); break; case CG_R_ADDREFENTITYTOSCENE: //add ent to scene VQ3_AddEntity(VM_POINTER(arg[0])); @@ -791,7 +802,7 @@ static int CG_SystemCallsEx(void *offset, unsigned int mask, int fn, const int * case CG_R_ADDLIGHTTOSCENE: //add light to scene. { float *org = VM_POINTER(arg[0]); - CL_NewDlightRGB(-1, org[0], org[1], org[2], VM_FLOAT(arg[1]), 0, VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4])); + CL_NewDlightRGB(-1, org, VM_FLOAT(arg[1]), 0, VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4])); } break; case CG_R_RENDERSCENE: //render scene @@ -810,10 +821,7 @@ static int CG_SystemCallsEx(void *offset, unsigned int mask, int fn, const int * break; case CG_R_DRAWSTRETCHPIC: - if (qrenderer == QR_OPENGL) - GLDraw_ShaderImage(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), VM_FROMSHANDLE(arg[8])); -// else -// Draw_Image(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), (mpic_t *)VM_LONG(arg[8])); + Draw_Image(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), (mpic_t *)VM_LONG(arg[8])); break; case CG_R_LERPTAG: //Lerp tag... @@ -1081,7 +1089,7 @@ static int EXPORT_FN CG_SystemCalls(int arg, ...) int CG_Refresh(void) { -#ifdef RGLQUAKE +#ifdef GLQUAKE int time; if (!cgvm) return false; @@ -1101,7 +1109,7 @@ int CG_Refresh(void) void CG_Stop (void) { -#ifdef RGLQUAKE +#ifdef GLQUAKE keycatcher &= ~2; if (cgvm) { @@ -1122,7 +1130,7 @@ void CG_Start (void) return; } -#if defined(RGLQUAKE) || defined(DIRECT3D) +#if defined(GLQUAKE) || defined(DIRECT3D) if (!Draw_SafeCachePic) //no renderer loaded { CG_Stop(); @@ -1157,7 +1165,7 @@ void CG_Start (void) qboolean CG_Command(void) { -#ifdef RGLQUAKE +#ifdef GLQUAKE if (!cgvm) return false; Con_DPrintf("CG_Command: %s %s\n", Cmd_Argv(0), Cmd_Args()); diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index 533d03ef..176d30fb 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -1055,6 +1055,11 @@ void CL_Record_f (void) MSG_WriteLong (&buf, PROTOCOL_VERSION_FTE); MSG_WriteLong (&buf, cls.fteprotocolextensions); } + if (cls.fteprotocolextensions2) //maintain demo compatability + { + MSG_WriteLong (&buf, PROTOCOL_VERSION_FTE2); + MSG_WriteLong (&buf, cls.fteprotocolextensions2); + } #endif MSG_WriteLong (&buf, PROTOCOL_VERSION_QW); MSG_WriteLong (&buf, cl.servercount); @@ -1424,18 +1429,27 @@ void CL_PlayDemo(char *demoname) // Q_strncpyz (name, demoname, sizeof(name)); COM_DefaultExtension (name, ".qwd", sizeof(name)); - cls.demofile = FS_OpenVFS(name, "rb", FS_GAME); + if (*name == '#') + cls.demofile = VFSOS_Open(name+1, "rb"); + else + cls.demofile = FS_OpenVFS(name, "rb", FS_GAME); if (!cls.demofile) { Q_strncpyz (name, demoname, sizeof(name)); COM_DefaultExtension (name, ".dem", sizeof(name)); - cls.demofile = FS_OpenVFS(name, "rb", FS_GAME); + if (*name == '#') + cls.demofile = VFSOS_Open(name+1, "rb"); + else + cls.demofile = FS_OpenVFS(name, "rb", FS_GAME); } if (!cls.demofile) { Q_strncpyz (name, demoname, sizeof(name)); COM_DefaultExtension (name, ".mvd", sizeof(name)); - cls.demofile = FS_OpenVFS(name, "rb", FS_GAME); + if (*name == '#') + cls.demofile = VFSOS_Open(name+1, "rb"); + else + cls.demofile = FS_OpenVFS(name, "rb", FS_GAME); } if (!cls.demofile) { @@ -1679,7 +1693,7 @@ void CL_QTVPoll (void) if (*colon) Con_Printf("streaming \"%s\" from qtv\n", colon); else - Con_Printf("qtv connection established\n", colon); + Con_Printf("qtv connection established to %s\n", colon); streamavailable = true; } @@ -1723,8 +1737,8 @@ void CL_QTVPoll (void) key_dest = key_menu; sourcesmenu = M_CreateMenu(0); - MC_AddPicture(sourcesmenu, 16, 4, "gfx/qplaque.lmp"); - MC_AddCenterPicture(sourcesmenu, 4, "gfx/p_option.lmp"); + MC_AddPicture(sourcesmenu, 16, 4, 32, 144, "gfx/qplaque.lmp"); + MC_AddCenterPicture(sourcesmenu, 4, 24, "gfx/p_option.lmp"); } if (init_numplayers == true && init_numviewers == true) MC_AddConsoleCommand(sourcesmenu, 42, (sourcenum++)*8 + 32, va("%s (p%i, v%i)", srchost, numplayers, numviewers), va("qtvplay %i@%s\n", streamid, qtvhostname)); @@ -1769,12 +1783,12 @@ void CL_ParseQTVFile(vfsfile_t *f, const char *fname, qtvfile_t *result) memset(result, 0, sizeof(*result)); if (!f) { - Con_Printf("Couldn't open QTV file: %s\n", name); + Con_Printf("Couldn't open QTV file: %s\n", fname); return; } if (!VFS_GETS(f, buffer, sizeof(buffer)-1)) { - Con_Printf("Empty QTV file: %s\n", name); + Con_Printf("Empty QTV file: %s\n", fname); VFS_CLOSE(f); return; } @@ -1783,7 +1797,7 @@ void CL_ParseQTVFile(vfsfile_t *f, const char *fname, qtvfile_t *result) s++; if (*s != '[') { - Con_Printf("Bad QTV file: %s\n", name); + Con_Printf("Bad QTV file: %s\n", fname); VFS_CLOSE(f); return; } @@ -1792,7 +1806,7 @@ void CL_ParseQTVFile(vfsfile_t *f, const char *fname, qtvfile_t *result) s++; if (strnicmp(s, "QTV", 3)) { - Con_Printf("Bad QTV file: %s\n", name); + Con_Printf("Bad QTV file: %s\n", fname); VFS_CLOSE(f); return; } @@ -1801,7 +1815,7 @@ void CL_ParseQTVFile(vfsfile_t *f, const char *fname, qtvfile_t *result) s++; if (*s != ']') { - Con_Printf("Bad QTV file: %s\n", name); + Con_Printf("Bad QTV file: %s\n", fname); VFS_CLOSE(f); return; } @@ -1810,7 +1824,7 @@ void CL_ParseQTVFile(vfsfile_t *f, const char *fname, qtvfile_t *result) s++; if (*s) { - Con_Printf("Bad QTV file: %s\n", name); + Con_Printf("Bad QTV file: %s\n", fname); VFS_CLOSE(f); return; } @@ -1972,7 +1986,7 @@ void CL_QTVPlay_f (void) else host = NULL; - if (qtvcl_forceversion1.value) + if (qtvcl_forceversion1.ival) { connrequest = "QTV\n" "VERSION: 1.0\n"; @@ -1985,7 +1999,7 @@ void CL_QTVPlay_f (void) VFS_WRITE(newf, connrequest, strlen(connrequest)); - if (qtvcl_eztvextensions.value) + if (qtvcl_eztvextensions.ival) { connrequest = "QTV_EZQUAKE_EXT: 3\n"; VFS_WRITE(newf, connrequest, strlen(connrequest)); @@ -2039,7 +2053,7 @@ void CL_QTVList_f (void) return; } - if (qtvcl_forceversion1.value) + if (qtvcl_forceversion1.ival) { connrequest = "QTV\n" "VERSION: 1.0\n"; diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index 8fc908d3..4bd5719b 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" #include "particles.h" +#include "shader.h" extern cvar_t cl_predict_players; extern cvar_t cl_predict_players2; @@ -34,6 +35,7 @@ extern cvar_t r_powerupglow; extern cvar_t v_powerupshell; extern cvar_t cl_nolerp; extern cvar_t cl_nolerp_netquake; +extern cvar_t r_torch; extern cvar_t cl_gibfilter, cl_deadbodyfilter; extern int cl_playerindex; @@ -58,19 +60,19 @@ qboolean CL_FilterModelindex(int modelindex, int frame) { if (modelindex == cl_playerindex) { - if (cl_deadbodyfilter.value == 2) + if (cl_deadbodyfilter.ival == 2) { if (frame >= 41 && frame <= 102) return true; } - else if (cl_deadbodyfilter.value) + else if (cl_deadbodyfilter.ival) { if (frame == 49 || frame == 60 || frame == 69 || frame == 84 || frame == 93 || frame == 102) return true; } } - if (cl_gibfilter.value && ( + if (cl_gibfilter.ival && ( modelindex == cl_h_playerindex || modelindex == cl_gib1index || modelindex == cl_gib2index || @@ -81,9 +83,16 @@ qboolean CL_FilterModelindex(int modelindex, int frame) //============================================================ +void CL_InitDlights(void) +{ + rtlights_max = cl_maxdlights = RTL_FIRST; + cl_dlights = BZ_Realloc(NULL, sizeof(*cl_dlights)*cl_maxdlights); + memset(cl_dlights, 0, sizeof(*cl_dlights)*cl_maxdlights); +} + static void CL_ClearDlight(dlight_t *dl, int key) { - int st; + texid_t st; st = dl->stexture; memset (dl, 0, sizeof(*dl)); dl->stexture = st; @@ -92,6 +101,23 @@ static void CL_ClearDlight(dlight_t *dl, int key) dl->axis[2][2] = 1; dl->key = key; dl->flags = LFLAG_DYNAMIC; +// if (r_shadow_realtime_dlight_shadowmap.value) +// dl->flags |= LFLAG_SHADOWMAP; +} + +dlight_t *CL_AllocSlight(void) +{ + dlight_t *dl; + if (rtlights_max == cl_maxdlights) + { + cl_maxdlights = rtlights_max+8; + cl_dlights = BZ_Realloc(cl_dlights, sizeof(*cl_dlights)*cl_maxdlights); + memset(&cl_dlights[rtlights_max], 0, sizeof(*cl_dlights)*(cl_maxdlights-rtlights_max)); + } + dl = &cl_dlights[rtlights_max++]; + + CL_ClearDlight(dl, 0); + return dl; } /* @@ -108,8 +134,8 @@ dlight_t *CL_AllocDlight (int key) // first look for an exact key match if (key) { - dl = cl_dlights; - for (i=0 ; ikey == key) { @@ -119,18 +145,21 @@ dlight_t *CL_AllocDlight (int key) } } -// then look for anything else - if (dlights_running < MAX_DLIGHTS) + //default to the first + dl = &cl_dlights[rtlights_first?rtlights_first-1:0]; + //try and find one that is free + for (i=RTL_FIRST; i > rtlights_first && i > 0; ) { - dl = &cl_dlights[dlights_running]; - CL_ClearDlight(dl, key); - dlights_running++; - if (dlights_software < MAX_SWLIGHTS) - dlights_software++; - return dl; + i--; + if (!cl_dlights[i].radius) + { + dl = &cl_dlights[i]; + break; + } } + if (rtlights_first > dl - cl_dlights) + rtlights_first = dl - cl_dlights; - dl = &cl_dlights[0]; CL_ClearDlight(dl, key); return dl; } @@ -140,46 +169,33 @@ dlight_t *CL_AllocDlight (int key) CL_NewDlight =============== */ -dlight_t *CL_NewDlight (int key, float x, float y, float z, float radius, float time, - int type) +dlight_t *CL_NewDlight (int key, const vec3_t org, float radius, float time, int type) { + static const vec3_t lightcolour[] = + { + {0.2, 0.1, 0.05}, + {0.05, 0.05, 0.3}, + {0.5, 0.05, 0.05}, + {0.5, 0.05, 0.4} + }; dlight_t *dl; + if (type >= sizeof(lightcolour)/sizeof(lightcolour[0])) + type = 0; dl = CL_AllocDlight (key); - dl->origin[0] = x; - dl->origin[1] = y; - dl->origin[2] = z; + VectorCopy(org, dl->origin); dl->radius = radius; dl->die = (float)cl.time + time; - if (type == 0) { - dl->color[0] = 0.2; - dl->color[1] = 0.1; - dl->color[2] = 0.05; - } else if (type == 1) { - dl->color[0] = 0.05; - dl->color[1] = 0.05; - dl->color[2] = 0.3; - } else if (type == 2) { - dl->color[0] = 0.5; - dl->color[1] = 0.05; - dl->color[2] = 0.05; - } else if (type == 3) { - dl->color[0]=0.5; - dl->color[1] = 0.05; - dl->color[2] = 0.4; - } - + VectorCopy(lightcolour[type], dl->color); return dl; } -dlight_t *CL_NewDlightRGB (int key, float x, float y, float z, float radius, float time, +dlight_t *CL_NewDlightRGB (int key, const vec3_t org, float radius, float time, float r, float g, float b) { dlight_t *dl; dl = CL_AllocDlight (key); - dl->origin[0] = x; - dl->origin[1] = y; - dl->origin[2] = z; + VectorCopy(org, dl->origin); dl->radius = radius; dl->die = cl.time + time; dl->color[0] = r; @@ -199,26 +215,28 @@ CL_DecayLights void CL_DecayLights (void) { int i; - int lastrunning = -1; dlight_t *dl; if (cl.paused) //DON'T DO IT!!! return; - dl = cl_dlights; - for (i=0 ; iradius) + { continue; + } if (!dl->die) { - lastrunning = i; continue; } if (dl->die < (float)cl.time) { + if (i==rtlights_first) + rtlights_first++; dl->radius = 0; continue; } @@ -226,10 +244,11 @@ void CL_DecayLights (void) dl->radius -= host_frametime*dl->decay; if (dl->radius < 0) { + if (i==rtlights_first) + rtlights_first++; dl->radius = 0; continue; } - lastrunning = i; if (dl->channelfade[0]) { @@ -252,10 +271,6 @@ void CL_DecayLights (void) dl->color[2] = 0; } } - dlights_running = lastrunning+1; - dlights_software = dlights_running; - if (dlights_software > MAX_SWLIGHTS) - dlights_software = MAX_SWLIGHTS; } @@ -300,7 +315,7 @@ void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int bits, qboolean bitcounts[i]++; #ifdef PROTOCOLEXTENSIONS - if (bits & U_EVENMORE && cls.fteprotocolextensions) + if (bits & U_EVENMORE && (cls.fteprotocolextensions & (PEXT_SCALE|PEXT_TRANS|PEXT_FATNESS|PEXT_HEXEN2|PEXT_COLOURMOD|PEXT_DPFLAGS|PEXT_MODELDBL|PEXT_ENTITYDBL|PEXT_ENTITYDBL2))) morebits = MSG_ReadByte (); if (morebits & U_YETMORE) morebits |= MSG_ReadByte()<<8; @@ -369,11 +384,11 @@ void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int bits, qboolean to->colormod[2] = MSG_ReadByte(); } - if (morebits & U_ENTITYDBL) + if (morebits & U_ENTITYDBL && cls.fteprotocolextensions & PEXT_ENTITYDBL) to->number += 512; - if (morebits & U_ENTITYDBL2) + if (morebits & U_ENTITYDBL2 && cls.fteprotocolextensions & PEXT_ENTITYDBL2) to->number += 1024; - if (morebits & U_MODELDBL) + if (morebits & U_MODELDBL && cls.fteprotocolextensions & PEXT_MODELDBL) to->modelindex += 256; if (morebits & U_DPFLAGS)// && cls.fteprotocolextensions & PEXT_DPFLAGS) @@ -459,19 +474,21 @@ void CL_ParsePacketEntities (qboolean delta) qboolean full; int from; - if (!(cls.fteprotocolextensions & PEXT_ACCURATETIMINGS)) + newpacket = cls.netchan.incoming_sequence&UPDATE_MASK; + newp = &cl.frames[newpacket].packet_entities; + cl.frames[newpacket].invalid = false; + + if (!(cls.fteprotocolextensions & PEXT_ACCURATETIMINGS) && cls.protocol == CP_QUAKEWORLD) { cl.oldgametime = cl.gametime; cl.oldgametimemark = cl.gametimemark; cl.gametime = realtime; cl.gametimemark = realtime; + + newp->servertime = realtime; } - - newpacket = cls.netchan.incoming_sequence&UPDATE_MASK; - newp = &cl.frames[newpacket].packet_entities; - cl.frames[newpacket].invalid = false; - - newp->servertime = cl.gametime; + else + newp->servertime = cl.gametime; if (delta) { @@ -1369,9 +1386,9 @@ void VQ2_AddLerpEntity(entity_t *in) //a convienience function ent->angles[0]*=-1; } -void V_AddLight (vec3_t org, float quant, float r, float g, float b) +int V_AddLight (int entsource, vec3_t org, float quant, float r, float g, float b) { - CL_NewDlightRGB (0, org[0], org[1], org[2], quant, -0.1, r, g, b); + return CL_NewDlightRGB (entsource, org, quant, -0.1, r, g, b) - cl_dlights; } static void CL_LerpNetFrameState(int fsanim, framestate_t *fs, lerpents_t *le) @@ -1638,13 +1655,15 @@ void CL_LinkPacketEntities (void) //, spnum; dlight_t *dl; vec3_t angles; - int flicker; qboolean nolerp; float servertime; CL_CalcClientTime(); - servertime = cl.servertime; + if ((cls.fteprotocolextensions & PEXT_ACCURATETIMINGS) || cls.protocol != CP_QUAKEWORLD) + servertime = cl.servertime; + else + servertime = realtime; nolerp = !CL_MayLerp() && cls.demoplayback != DPB_MVD && cls.demoplayback != DPB_EZTV; #ifdef NQPROT @@ -1654,7 +1673,10 @@ void CL_LinkPacketEntities (void) if (!pack) return; - servertime = cl.servertime; + if ((cls.fteprotocolextensions & PEXT_ACCURATETIMINGS) || cls.protocol != CP_QUAKEWORLD) + servertime = cl.servertime; + else + servertime = realtime; autorotate = anglemod(100*servertime); @@ -1681,9 +1703,7 @@ void CL_LinkPacketEntities (void) #endif ent = &cl_visedicts[cl_numvisedicts]; -#ifdef Q3SHADERS ent->forcedshader = NULL; -#endif le = &cl.lerpents[state->number]; @@ -1691,25 +1711,58 @@ void CL_LinkPacketEntities (void) VectorCopy(le->origin, ent->origin); - //bots or powerup glows. items always glow, powerups can be disabled - if (state->modelindex != cl_playerindex || r_powerupglow.value) + //bots or powerup glows. items always glow, bots can be disabled + if (state->modelindex != cl_playerindex || r_powerupglow.ival) + if (state->effects & (EF_BLUE | EF_RED | EF_BRIGHTLIGHT | EF_DIMLIGHT) || state->light[3]) { - flicker = r_lightflicker.value?(rand()&31):0; - // spawn light flashes, even ones coming from invisible objects - if ((state->effects & (EF_BLUE | EF_RED)) == (EF_BLUE | EF_RED)) - CL_NewDlight (state->number, state->origin[0], state->origin[1], state->origin[2], 200 + flicker, 0, 3); - else if (state->effects & EF_BLUE) - CL_NewDlight (state->number, state->origin[0], state->origin[1], state->origin[2], 200 + flicker, 0, 1); - else if (state->effects & EF_RED) - CL_NewDlight (state->number, state->origin[0], state->origin[1], state->origin[2], 200 + flicker, 0, 2); - else if (state->effects & EF_BRIGHTLIGHT) - CL_NewDlight (state->number, state->origin[0], state->origin[1], state->origin[2] + 16, 400 + flicker, 0, 0); - else if (state->effects & EF_DIMLIGHT) - CL_NewDlight (state->number, state->origin[0], state->origin[1], state->origin[2], 200 + flicker, 0, 0); - } - if (state->light[3]) - { - CL_NewDlightRGB (state->number, state->origin[0], state->origin[1], state->origin[2], state->light[3], 0, state->light[0]/1024.0f, state->light[1]/1024.0f, state->light[2]/1024.0f); + vec3_t colour; + float radius; + colour[0] = 0; + colour[1] = 0; + colour[2] = 0; + radius = 0; + + if (state->effects & EF_BRIGHTLIGHT) + { + radius = max(radius,400); + colour[0] += 0.2; + colour[1] += 0.1; + colour[2] += 0.05; + } + if (state->effects & EF_DIMLIGHT) + { + radius = max(radius,200); + colour[0] += 0.2; + colour[1] += 0.1; + colour[2] += 0.05; + } + if (state->effects & EF_BLUE) + { + radius = max(radius,200); + colour[0] += 0.05; + colour[1] += 0.05; + colour[2] += 0.3; + } + if (state->effects & EF_RED) + { + radius = max(radius,200); + colour[0] += 0.5; + colour[1] += 0.05; + colour[2] += 0.05; + } + if (state->light[3]) + { + radius = max(radius,state->light[3]); + colour[0] += state->light[0]/1024.0f; + colour[1] += state->light[1]/1024.0f; + colour[2] += state->light[2]/1024.0f; + } + + if (radius) + { + radius += r_lightflicker.value?(rand()&31):0; + CL_NewDlightRGB(state->number, state->origin, radius, 0.1, colour[0], colour[1], colour[2]); + } } // if set to invisible, skip @@ -1732,10 +1785,7 @@ void CL_LinkPacketEntities (void) cl_numvisedicts++; -#ifdef Q3SHADERS ent->forcedshader = NULL; -#endif - ent->visframe = 0; ent->keynum = state->number; @@ -1746,8 +1796,8 @@ void CL_LinkPacketEntities (void) ent->model = model; ent->flags = state->flags; - if (state->effects & NQEF_ADDATIVE) - ent->flags |= Q2RF_ADDATIVE; + if (state->effects & NQEF_ADDITIVE) + ent->flags |= Q2RF_ADDITIVE; if (state->effects & EF_NODEPTHTEST) ent->flags |= RF_NODEPTHTEST; @@ -1884,7 +1934,7 @@ void CL_LinkPacketEntities (void) { extern cvar_t gl_part_flame; - if (cls.allow_anyparticles && gl_part_flame.value) + if (cls.allow_anyparticles && gl_part_flame.ival) { P_EmitEffect (ent->origin, model->particleeffect, &(le->emitstate)); } @@ -1902,6 +1952,7 @@ void CL_LinkPacketEntities (void) if (model->flags & EF_ROCKET) { +#pragma message("Replace this flag on load for hexen2 models") if (strncmp(model->name, "models/sflesh", 13)) { //hmm. hexen spider gibs... rad = 200; @@ -2002,7 +2053,7 @@ void CL_ParseProjectiles (int modelindex, qboolean nails2) pr->origin[0] = ( ( bits[0] + ((bits[1]&15)<<8) ) <<1) - 4096; pr->origin[1] = ( ( (bits[1]>>4) + (bits[2]<<4) ) <<1) - 4096; pr->origin[2] = ( ( bits[3] + ((bits[4]&15)<<8) ) <<1) - 4096; - pr->angles[0] = 360*((int)bits[4]>>4)/16.0f; + pr->angles[0] = 360*(((int)bits[4]>>4)/16.0f + 1/32.0f); pr->angles[1] = 360*(int)bits[5]/256.0f; } } @@ -2030,9 +2081,8 @@ void CL_LinkProjectiles (void) if (pr->modelindex < 1) continue; -#ifdef Q3SHADERS + ent->forcedshader = NULL; -#endif ent->model = cl.model_precache[pr->modelindex]; ent->skinnum = 0; memset(&ent->framestate, 0, sizeof(ent->framestate)); @@ -2553,6 +2603,9 @@ void CL_LinkPlayers (void) continue; #endif + if (info->spectator) + continue; + // spawn light flashes, even ones coming from invisible objects if (r_powerupglow.value && !(r_powerupglow.value == 2 && j == cl.playernum[0]) && (state->effects & (EF_BLUE|EF_RED|EF_BRIGHTLIGHT|EF_DIMLIGHT))) @@ -2597,7 +2650,7 @@ void CL_LinkPlayers (void) if (radius) { radius += r_lightflicker.value?(rand()&31):0; - CL_NewDlightRGB(j+1, org[0], org[1], org[2], radius, 0.1, colour[0], colour[1], colour[2])->flags &= ~LFLAG_ALLOW_FLASH; + CL_NewDlightRGB(j+1, org, radius, 0.1, colour[0], colour[1], colour[2])->flags &= ~LFLAG_ALLOW_FLASH; } } @@ -2617,10 +2670,7 @@ void CL_LinkPlayers (void) cl_numvisedicts++; ent->keynum = j+1; ent->flags = 0; - -#ifdef Q3SHADERS ent->forcedshader = NULL; -#endif //the extra modelindex check is to stop lame mods from using vweps with rings if (state->command.impulse && cl.model_precache_vwep[0] && state->modelindex == cl_playerindex) @@ -2705,7 +2755,7 @@ void CL_LinkPlayers (void) if (pnum < cl.splitclients) { //this is a local player } - else if (msec <= 0 || (!cl_predict_players.value && !cl_predict_players2.value)) + else if (msec <= 0 || (!cl_predict_players.ival && !cl_predict_players2.ival)) { VectorCopy (state->origin, ent->origin); //Con_DPrintf ("nopredict\n"); @@ -2737,23 +2787,23 @@ void CL_LinkPlayers (void) else if (state->command.impulse) CL_AddVWeapModel (ent, cl.model_precache_vwep[state->command.impulse]); + if (r_torch.ival) + { + dlight_t *dl; + dl = CL_NewDlightRGB(j+1, ent->origin, 300, r_torch.ival, 0.05, 0.05, 0.02); + dl->flags |= LFLAG_SHADOWMAP|LFLAG_ALLOW_FLASH; + dl->fov = 60; + angles[0] *= 3; + angles[1] += sin(realtime)*8; + angles[0] += cos(realtime*1.13)*5; + AngleVectors(angles, dl->axis[0], dl->axis[1], dl->axis[2]); + } } } -#ifdef Q3SHADERS //fixme: do better. -#include "shader.h" -#endif - void CL_LinkViewModel(void) { entity_t ent; -// float ambient[4], diffuse[4]; -// int j; -// int lnum; -// vec3_t dist; -// float add; -// dlight_t *dl; -// int ambientlight, shadelight; static struct model_s *oldmodel[MAX_SPLITS]; static float lerptime[MAX_SPLITS]; @@ -2779,7 +2829,7 @@ void CL_LinkViewModel(void) return; #endif - if (!r_drawentities.value) + if (!r_drawentities.ival) return; if ((cl.stats[r_refdef.currentplayernum][STAT_ITEMS] & IT_INVISIBILITY) && r_drawviewmodelinvis.value <= 0) @@ -2851,40 +2901,33 @@ void CL_LinkViewModel(void) ent.framestate.g[FS_REG].lerpfrac = 1-(realtime-lerptime[r_refdef.currentplayernum])/frameduration[r_refdef.currentplayernum]; ent.framestate.g[FS_REG].lerpfrac = bound(0, ent.framestate.g[FS_REG].lerpfrac, 1); } -#define Q2RF_VIEWERMODEL 2 // don't draw through eyes, only mirrors -#define Q2RF_WEAPONMODEL 4 // only draw through eyes -#define Q2RF_DEPTHHACK 16 // for view weapon Z crunching - ent.flags = Q2RF_WEAPONMODEL|Q2RF_DEPTHHACK; + ent.flags = Q2RF_WEAPONMODEL|Q2RF_DEPTHHACK|RF_NOSHADOW; V_AddEntity(&ent); - if (!v_powerupshell.value) + if (!v_powerupshell.ival) return; if (cl.stats[r_refdef.currentplayernum][STAT_ITEMS] & IT_QUAD) { -#ifdef Q3SHADERS - if (v_powerupshell.value == 2) + if (v_powerupshell.ival == 2) { ent.forcedshader = R_RegisterCustom("powerups/quadWeapon", Shader_DefaultSkinShell, NULL); V_AddEntity(&ent); } else -#endif ent.flags |= Q2RF_SHELL_BLUE; } if (cl.stats[r_refdef.currentplayernum][STAT_ITEMS] & IT_INVULNERABILITY) { -#ifdef Q3SHADERS - if (v_powerupshell.value == 2) + if (v_powerupshell.ival == 2) { ent.forcedshader = R_RegisterCustom("powerups/regen", Shader_DefaultSkinShell, NULL); ent.fatness = -2.5; V_AddEntity(&ent); } else -#endif ent.flags |= Q2RF_SHELL_RED; } @@ -2893,16 +2936,11 @@ void CL_LinkViewModel(void) ent.fatness = 0.5; ent.shaderRGBAf[3] /= 10; -#ifdef Q3SHADERS //fixme: do better. - //fixme: this is woefully gl specific. :( - if (qrenderer == QR_OPENGL) - { - ent.shaderRGBAf[0] = (!!(ent.flags & Q2RF_SHELL_RED)); - ent.shaderRGBAf[1] = (!!(ent.flags & Q2RF_SHELL_GREEN)); - ent.shaderRGBAf[2] = (!!(ent.flags & Q2RF_SHELL_BLUE)); - ent.forcedshader = R_RegisterCustom("q2/shell", Shader_DefaultSkinShell, NULL); - } -#endif + + ent.shaderRGBAf[0] = (!!(ent.flags & Q2RF_SHELL_RED)); + ent.shaderRGBAf[1] = (!!(ent.flags & Q2RF_SHELL_GREEN)); + ent.shaderRGBAf[2] = (!!(ent.flags & Q2RF_SHELL_BLUE)); + ent.forcedshader = R_RegisterCustom("q2/shell", Shader_DefaultSkinShell, NULL); V_AddEntity(&ent); } @@ -2983,7 +3021,7 @@ void CL_SetUpPlayerPrediction(qboolean dopred) if (playertime > realtime) playertime = realtime; - if (cl_nopred.value || cls.demoplayback) + if (cl_nopred.value || cls.demoplayback || cl.paused) return; frame = &cl.frames[cl.parsecount&UPDATE_MASK]; @@ -3034,7 +3072,7 @@ void CL_SetUpPlayerPrediction(qboolean dopred) // only predict half the move to minimize overruns msec = 500*(playertime - state->state_time); if (msec <= 0 || - (!cl_predict_players.value && !cl_predict_players2.value) || + (!cl_predict_players.ival && !cl_predict_players2.ival) || !dopred) { VectorCopy (state->origin, pplayer->origin); @@ -3080,7 +3118,7 @@ void CL_SetSolidPlayers (int playernum) struct predicted_player *pplayer; physent_t *pent; - if (!cl_solid_players.value) + if (!cl_solid_players.ival) return; pent = pmove.physents + pmove.numphysent; @@ -3131,6 +3169,9 @@ void CL_SwapEntityLists(void) // cl_visedicts = cl_visedicts_list[cls.netchan.incoming_sequence&1]; cl_numvisedicts = 0; + cl_numstrisidx = 0; + cl_numstrisvert = 0; + cl_numstris = 0; } void CL_EmitEntities (void) diff --git a/engine/client/cl_ignore.c b/engine/client/cl_ignore.c index 54cdc1e6..137d7338 100644 --- a/engine/client/cl_ignore.c +++ b/engine/client/cl_ignore.c @@ -127,13 +127,13 @@ static void Display_Ignorelist(void) { if (x) Con_Printf ("\n"); - if (ignore_opponents.value) + if (ignore_opponents.ival) Con_Printf("\x02" "Opponents are Ignored\n"); - if (ignore_spec.value == 2 || (ignore_spec.value == 1 && !cl.spectator)) + if (ignore_spec.ival == 2 || (ignore_spec.ival == 1 && !cl.spectator)) Con_Printf ("\x02" "Spectators are Ignored\n"); - if (ignore_qizmo_spec.value) + if (ignore_qizmo_spec.ival) Con_Printf("\x02" "Qizmo spectators are Ignored\n"); Con_Printf("\n"); @@ -399,13 +399,13 @@ qboolean Ignore_Message(char *s, int flags, int offset) { int slot, i, p, q, len; char name[MAX_SCOREBOARDNAME]; - if (!ignore_mode.value && (flags & 2)) + if (!ignore_mode.ival && (flags & 2)) return false; - if (ignore_spec.value == 2 && (flags == 4 || (flags == 8 && ignore_mode.value))) + if (ignore_spec.ival == 2 && (flags == 4 || (flags == 8 && ignore_mode.ival))) return true; - else if (ignore_spec.value == 1 && (flags == 4) && !cl.spectator) + else if (ignore_spec.ival == 1 && (flags == 4) && !cl.spectator) return true; if (flags == 1 || flags == 4) { @@ -431,8 +431,8 @@ qboolean Ignore_Message(char *s, int flags, int offset) { return true; - if (ignore_opponents.value && ( - (int) ignore_opponents.value == 1 || + if (ignore_opponents.ival && ( + (int) ignore_opponents.ival == 1 || (cls.state >= ca_connected && /*!cl.standby &&*/ !cls.demoplayback && !cl.spectator) // match? ) && flags == 1 && !cl.spectator && slot != cl.playernum[0] && diff --git a/engine/client/cl_input.c b/engine/client/cl_input.c index 9a540014..dfc83e26 100644 --- a/engine/client/cl_input.c +++ b/engine/client/cl_input.c @@ -38,7 +38,7 @@ cvar_t cl_sparemsec = SCVARC("cl_sparemsec", "10", CL_SpareMsec_Callback); cvar_t cl_queueimpulses = SCVAR("cl_queueimpulses", "0"); cvar_t cl_smartjump = SCVAR("cl_smartjump", "1"); -cvar_t cl_prydoncursor = SCVAR("cl_prydoncursor", "0"); //for dp protocol +cvar_t cl_prydoncursor = SCVAR("cl_prydoncursor", ""); //for dp protocol cvar_t cl_instantrotate = SCVARF("cl_instantrotate", "1", CVAR_SEMICHEAT); cvar_t prox_inmenu = SCVAR("prox_inmenu", "0"); @@ -81,6 +81,9 @@ int in_impulse[MAX_SPLITS][IN_IMPULSECACHE]; int in_nextimpulse[MAX_SPLITS]; int in_impulsespending[MAX_SPLITS]; +float cursor_screen[2]; +qboolean cursor_active; + void KeyDown (kbutton_t *b) { @@ -165,7 +168,7 @@ void IN_MLookUp (void) { pnum = atoi(c+strlen(c)-1); if (pnum)pnum--; KeyUp(&in_mlook); -if ( !(in_mlook.state[pnum]&1) && lookspring.value) +if ( !(in_mlook.state[pnum]&1) && lookspring.ival) V_StartPitchDrift(pnum); } void IN_UpDown(void) {KeyDown(&in_up);} @@ -212,7 +215,7 @@ void IN_JumpDown (void) - condition = (cls.state == ca_active && cl_smartjump.value && !prox_inmenu.value); + condition = (cls.state == ca_active && cl_smartjump.ival && !prox_inmenu.ival); #ifdef Q2CLIENT if (condition && cls.protocol == CP_QUAKE2) KeyDown(&in_up); @@ -229,7 +232,7 @@ void IN_JumpDown (void) } void IN_JumpUp (void) { - if (cl_smartjump.value) + if (cl_smartjump.ival) KeyUp(&in_up); KeyUp(&in_jump); } @@ -328,7 +331,7 @@ void IN_Impulse (void) return; } - if (cl_queueimpulses.value) + if (cl_queueimpulses.ival) { in_impulse[pnum][(in_nextimpulse[pnum]+in_impulsespending[pnum])%IN_IMPULSECACHE] = newimp; in_impulsespending[pnum]++; @@ -412,7 +415,7 @@ void CL_ProxyMenuHook(char *command, kbutton_t *key) void CL_ProxyMenuHooks(void) { - if (!prox_inmenu.value) + if (!prox_inmenu.ival) return; CL_ProxyMenuHook("say proxy:menu down\n", &in_back); @@ -456,10 +459,10 @@ void CL_AdjustAngles (int pnum, double frametime) if (in_speed.state[pnum] & 1) { - if (ruleset_allow_frj.value) - speed = frametime * cl_anglespeedkey.value; + if (ruleset_allow_frj.ival) + speed = frametime * cl_anglespeedkey.ival; else - speed = frametime * bound(-2, cl_anglespeedkey.value, 2); + speed = frametime * bound(-2, cl_anglespeedkey.ival, 2); } else speed = frametime; @@ -467,17 +470,17 @@ void CL_AdjustAngles (int pnum, double frametime) if (in_rotate && pnum==0 && !(cl.fpd & FPD_LIMIT_YAW)) { quant = in_rotate; - if (!cl_instantrotate.value) + if (!cl_instantrotate.ival) quant *= speed; in_rotate -= quant; - if (ruleset_allow_frj.value) + if (ruleset_allow_frj.ival) cl.viewangles[pnum][YAW] += quant; } if (!(in_strafe.state[pnum] & 1)) { - quant = cl_yawspeed.value; - if (cl.fpd & FPD_LIMIT_YAW || !ruleset_allow_frj.value) + quant = cl_yawspeed.ival; + if (cl.fpd & FPD_LIMIT_YAW || !ruleset_allow_frj.ival) quant = bound(-900, quant, 900); cl.viewangles[pnum][YAW] -= speed*quant * CL_KeyState (&in_right, pnum); cl.viewangles[pnum][YAW] += speed*quant * CL_KeyState (&in_left, pnum); @@ -486,8 +489,8 @@ void CL_AdjustAngles (int pnum, double frametime) if (in_klook.state[pnum] & 1) { V_StopPitchDrift (pnum); - quant = cl_pitchspeed.value; - if (cl.fpd & FPD_LIMIT_PITCH || !ruleset_allow_frj.value) + quant = cl_pitchspeed.ival; + if (cl.fpd & FPD_LIMIT_PITCH || !ruleset_allow_frj.ival) quant = bound(-700, quant, 700); cl.viewangles[pnum][PITCH] -= speed*quant * CL_KeyState (&in_forward, pnum); cl.viewangles[pnum][PITCH] += speed*quant * CL_KeyState (&in_back, pnum); @@ -496,11 +499,11 @@ void CL_AdjustAngles (int pnum, double frametime) up = CL_KeyState (&in_lookup, pnum); down = CL_KeyState(&in_lookdown, pnum); - quant = cl_pitchspeed.value; - if (!ruleset_allow_frj.value) + quant = cl_pitchspeed.ival; + if (!ruleset_allow_frj.ival) quant = bound(-700, quant, 700); - cl.viewangles[pnum][PITCH] -= speed*cl_pitchspeed.value * up; - cl.viewangles[pnum][PITCH] += speed*cl_pitchspeed.value * down; + cl.viewangles[pnum][PITCH] -= speed*cl_pitchspeed.ival * up; + cl.viewangles[pnum][PITCH] += speed*cl_pitchspeed.ival * down; if (up || down) V_StopPitchDrift (pnum); @@ -541,7 +544,7 @@ void CL_BaseMove (usercmd_t *cmd, int pnum, float extra, float wantfps) cmd->sidemove -= scale*cl_sidespeed.value * CL_KeyState (&in_moveleft, pnum); #ifdef IN_XFLIP - if(in_xflip.value) cmd->sidemove *= -1; + if(in_xflip.ival) cmd->sidemove *= -1; #endif @@ -587,7 +590,7 @@ void CL_ClampPitch (int pnum) else #endif #ifdef Q3CLIENT - if (cls.gamemode == CP_QUAKE3) //q3 expects the cgame to do it + if (cls.protocol == CP_QUAKE3) //q3 expects the cgame to do it { //no-op } @@ -598,7 +601,7 @@ void CL_ClampPitch (int pnum) cl.viewangles[pnum][PITCH] = cl.maxpitch; if (cl.viewangles[pnum][PITCH] < cl.minpitch) cl.viewangles[pnum][PITCH] = cl.minpitch; - } + } } /* @@ -652,19 +655,12 @@ void CL_FinishMove (usercmd_t *cmd, int msecs, int pnum) cmd->impulse = 0; } -float cursor_screen[2]; - void CL_DrawPrydonCursor(void) { - if (cls.protocol == CP_NETQUAKE) - if (nq_dp_protocol >= 6) - if (cl_prydoncursor.value) + if (cursor_active && cl_prydoncursor.ival) { - mpic_t *pic = Draw_SafeCachePic(va("gfx/prydoncursor%03i.lmp", (int)cl_prydoncursor.value)); - if (pic) - Draw_Pic((int)((cursor_screen[0] + 1) * 0.5 * vid.width), (int)((cursor_screen[1] + 1) * 0.5 * vid.height), pic); - else - Draw_Character((int)((cursor_screen[0] + 1) * 0.5 * vid.width), (int)((cursor_screen[1] + 1) * 0.5 * vid.height), '+'); + SCR_DrawCursor(cl_prydoncursor.ival); + V_StopPitchDrift (0); } } @@ -675,15 +671,19 @@ void CL_UpdatePrydonCursor(usercmd_t *from, float cursor_screen[2], vec3_t curso vec3_t temp; vec3_t cursor_impact_normal; - if (!cl_prydoncursor.value) + extern int mousecursor_x, mousecursor_y; + + cursor_active = true; + + if (!cl_prydoncursor.ival) { //center the cursor cursor_screen[0] = 0; cursor_screen[1] = 0; } else { - cursor_screen[0] += from->sidemove/10000.0f; - cursor_screen[1] -= from->forwardmove/10000.0f; + cursor_screen[0] = mousecursor_x/(vid.width/2.0f) - 1; + cursor_screen[1] = mousecursor_y/(vid.height/2.0f) - 1; if (cursor_screen[0] < -1) cursor_screen[0] = -1; if (cursor_screen[1] < -1) @@ -717,23 +717,16 @@ void CL_UpdatePrydonCursor(usercmd_t *from, float cursor_screen[2], vec3_t curso cl.cmd.cursor_screen[1] = 1; } */ -// cursor_screen[0] = bound(-1, cursor_screen[0], 1); -// cursor_screen[1] = bound(-1, cursor_screen[1], 1); VectorClear(cursor_start); temp[0] = (cursor_screen[0]+1)/2; temp[1] = (-cursor_screen[1]+1)/2; temp[2] = 1; - Matrix4_UnProject(temp, cursor_end, cl.viewangles[0], vec3_origin, scr_fov.value*(float)vid.width/vid.height, scr_fov.value ); + VectorCopy(r_origin, cursor_start); + Matrix4_UnProject(temp, cursor_end, cl.viewangles[0], cursor_start, r_refdef.fov_x, r_refdef.fov_y); VectorScale(cursor_end, 100000, cursor_end); - VectorAdd(cursor_start, cl.simorg[0], cursor_start); - VectorAdd(cursor_end, cl.simorg[0], cursor_end); - cursor_start[2]+=cl.viewheight[0]; - cursor_end[2]+=cl.viewheight[0]; - - CL_SetSolidEntities(); //don't bother with players, they don't exist in NQ... @@ -1005,20 +998,20 @@ unsigned long _stdcall CL_IndepPhysicsThread(void *param) { int sleeptime; float fps; - float time, lasttime; + unsigned int time, lasttime; float spare; - lasttime = Sys_DoubleTime(); + lasttime = Sys_Milliseconds(); while(1) { - time = Sys_DoubleTime(); - spare = CL_FilterTime((time - lasttime)*1000, cl_netfps.value); + time = Sys_Milliseconds(); + spare = CL_FilterTime((time - lasttime), cl_netfps.value); if (spare) { //don't let them bank too much and get sudden bursts if (spare > 15) spare = 15; - time -= spare/1000.0f; + time -= spare; EnterCriticalSection(&indepcriticialsection); if (cls.state) { @@ -1210,20 +1203,20 @@ qboolean CL_WriteDeltas (int plnum, sizebuf_t *buf) i = (cls.netchan.outgoing_sequence-2) & UPDATE_MASK; cmd = &cl.frames[i].cmd[plnum]; - if (cl_c2sImpulseBackup.value >= 2) + if (cl_c2sImpulseBackup.ival >= 2) dontdrop = dontdrop || cmd->impulse; MSG_WriteDeltaUsercmd (buf, &nullcmd, cmd); oldcmd = cmd; i = (cls.netchan.outgoing_sequence-1) & UPDATE_MASK; - if (cl_c2sImpulseBackup.value >= 3) + if (cl_c2sImpulseBackup.ival >= 3) dontdrop = dontdrop || cmd->impulse; cmd = &cl.frames[i].cmd[plnum]; MSG_WriteDeltaUsercmd (buf, oldcmd, cmd); oldcmd = cmd; i = (cls.netchan.outgoing_sequence) & UPDATE_MASK; - if (cl_c2sImpulseBackup.value >= 1) + if (cl_c2sImpulseBackup.ival >= 1) dontdrop = dontdrop || cmd->impulse; cmd = &cl.frames[i].cmd[plnum]; MSG_WriteDeltaUsercmd (buf, oldcmd, cmd); @@ -1261,7 +1254,7 @@ qboolean CL_SendCmdQ2 (sizebuf_t *buf) checksumIndex = buf->cursize; MSG_WriteByte (buf, 0); - if (!cl.q2frame.valid || cl_nodelta.value) + if (!cl.q2frame.valid || cl_nodelta.ival) MSG_WriteLong (buf, -1); // no compression else MSG_WriteLong (buf, cl.q2frame.serverframe); @@ -1307,8 +1300,9 @@ qboolean CL_SendCmdQW (sizebuf_t *buf) int seq_hash; qboolean dontdrop = false; usercmd_t *cmd; - int checksumIndex, firstsize, i, plnum; + int checksumIndex, firstsize, plnum; int clientcount, lost; + int curframe = cls.netchan.outgoing_sequence & UPDATE_MASK; seq_hash = cls.netchan.outgoing_sequence; @@ -1319,6 +1313,42 @@ qboolean CL_SendCmdQW (sizebuf_t *buf) if (!clientcount) clientcount = 1; + + for (plnum = 0; plnumlightlevel = 0; +#ifdef CSQC_DAT + CSQC_Input_Frame(plnum, cmd); +#endif + memset(&independantphysics[plnum], 0, sizeof(independantphysics[plnum])); + } + cl.frames[curframe].senttime = realtime; + cl.frames[curframe].receivedtime = -1; // we haven't gotten a reply yet + + + if ((cls.fteprotocolextensions2 & PEXT2_PRYDONCURSOR) && *cl_prydoncursor.string) + { + vec3_t cursor_start, cursor_impact; + int cursor_entitynumber = 0; + cmd = &cl.frames[curframe].cmd[0]; + CL_UpdatePrydonCursor(cmd, cursor_screen, cursor_start, cursor_impact, &cursor_entitynumber); + MSG_WriteByte (buf, clc_prydoncursor); + MSG_WriteShort(buf, cursor_screen[0] * 32767.0f); + MSG_WriteShort(buf, cursor_screen[1] * 32767.0f); + MSG_WriteFloat(buf, cursor_start[0]); + MSG_WriteFloat(buf, cursor_start[1]); + MSG_WriteFloat(buf, cursor_start[2]); + MSG_WriteFloat(buf, cursor_impact[0]); + MSG_WriteFloat(buf, cursor_impact[1]); + MSG_WriteFloat(buf, cursor_impact[2]); + MSG_WriteShort(buf, cursor_entitynumber); + } + else + cursor_active = false; + MSG_WriteByte (buf, clc_move); // save the position for a checksum qbyte @@ -1332,18 +1362,7 @@ qboolean CL_SendCmdQW (sizebuf_t *buf) firstsize=0; for (plnum = 0; plnumlightlevel = 0; -#ifdef CSQC_DAT - CSQC_Input_Frame(plnum, cmd); -#endif - - cl.frames[i].senttime = realtime; - cl.frames[i].receivedtime = -1; // we haven't gotten a reply yet - memset(&independantphysics[plnum], 0, sizeof(independantphysics[plnum])); + cmd = &cl.frames[curframe].cmd[plnum]; if (plnum) MSG_WriteByte (buf, clc_move); @@ -1364,7 +1383,7 @@ qboolean CL_SendCmdQW (sizebuf_t *buf) if (cls.netchan.outgoing_sequence - cl.validsequence >= UPDATE_BACKUP-1) cl.validsequence = 0; - if (cl.validsequence && !cl_nodelta.value && cls.state == ca_active && !cls.demorecording) + if (cl.validsequence && !cl_nodelta.ival && cls.state == ca_active && !cls.demorecording) { cl.frames[cls.netchan.outgoing_sequence&UPDATE_MASK].delta_sequence = cl.validsequence; MSG_WriteByte (buf, clc_delta); @@ -1382,7 +1401,6 @@ qboolean CL_SendCmdQW (sizebuf_t *buf) void CL_SendCmd (double frametime, qboolean mainloop) { - extern cvar_t cl_indepphysics; sizebuf_t buf; qbyte data[512]; int i, plnum; @@ -1427,9 +1445,9 @@ void CL_SendCmd (double frametime, qboolean mainloop) cl.frames[i].senttime = realtime; // we haven't gotten a reply yet cl.frames[i].receivedtime = -1; // we haven't gotten a reply yet - if (cl.splitclients > cl_splitscreen.value+1) + if (cl.splitclients > cl_splitscreen.ival+1) { - cl.splitclients = cl_splitscreen.value+1; + cl.splitclients = cl_splitscreen.ival+1; if (cl.splitclients < 1) cl.splitclients = 1; } @@ -1533,8 +1551,8 @@ void CL_SendCmd (double frametime, qboolean mainloop) #endif )) fullsend = false; - if (spare > cl_sparemsec.value) - spare = cl_sparemsec.value; + if (spare > cl_sparemsec.ival) + spare = cl_sparemsec.ival; if (spare > 0) msecstouse -= spare; } @@ -1680,7 +1698,7 @@ void CL_SendCmd (double frametime, qboolean mainloop) else #endif //shamelessly stolen from fuhquake - if (cl_c2spps.value>0) + if (cl_c2spps.ival>0) { pps_balance += frametime; // never drop more than 2 messages in a row -- that'll cause PL @@ -1688,7 +1706,7 @@ void CL_SendCmd (double frametime, qboolean mainloop) if (pps_balance > 0 || dropcount >= 2 || dontdrop) { float pps; - pps = cl_c2spps.value; + pps = cl_c2spps.ival; if (pps < 10) pps = 10; if (pps > 72) pps = 72; pps_balance -= 1 / pps; @@ -1914,13 +1932,3 @@ void CL_InitInput (void) Cvar_Register (&cl_prydoncursor, inputnetworkcvargroup); Cvar_Register (&cl_instantrotate, inputnetworkcvargroup); } - -/* -============ -CL_ClearStates -============ -*/ -void CL_ClearStates (void) -{ -} - diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index afbcd0b1..9133292f 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -118,6 +118,7 @@ cvar_t cl_chatsound = SCVAR("cl_chatsound","1"); cvar_t cl_enemychatsound = SCVAR("cl_enemychatsound", "misc/talk.wav"); cvar_t cl_teamchatsound = SCVAR("cl_teamchatsound", "misc/talk.wav"); +cvar_t r_torch = SCVARF("r_torch", "0", CVAR_CHEAT); cvar_t r_rocketlight = SCVARC("r_rocketlight", "1", Cvar_Limiter_ZeroToOne_Callback); cvar_t r_lightflicker = SCVAR("r_lightflicker", "1"); cvar_t cl_r2g = SCVAR("cl_r2g", "0"); @@ -162,6 +163,7 @@ cvar_t ruleset_allow_larger_models = SCVAR("ruleset_allow_larger_models", "1"); cvar_t ruleset_allow_modified_eyes = SCVAR("ruleset_allow_modified_eyes", "0"); cvar_t ruleset_allow_sensative_texture_replacements = SCVAR("ruleset_allow_sensative_texture_replacements", "1"); cvar_t ruleset_allow_localvolume = SCVAR("ruleset_allow_localvolume", "1"); +cvar_t ruleset_allow_shaders = SCVAR("ruleset_allow_shaders", "1"); extern cvar_t cl_hightrack; extern cvar_t vid_renderer; @@ -182,10 +184,11 @@ entity_t cl_static_entities[MAX_STATIC_ENTITIES]; trailstate_t *cl_static_emit[MAX_STATIC_ENTITIES]; lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES]; //lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES]; -dlight_t cl_dlights[MAX_DLIGHTS]; +dlight_t *cl_dlights; +unsigned int cl_maxdlights; /*size of cl_dlights array*/ int cl_baselines_count; -int dlights_running, dlights_software; +int rtlights_first, rtlights_max; // refresh list // this is double buffered so the last frame @@ -194,6 +197,18 @@ int cl_numvisedicts, cl_oldnumvisedicts; entity_t *cl_visedicts, *cl_oldvisedicts; entity_t cl_visedicts_list[2][MAX_VISEDICTS]; +scenetris_t *cl_stris; +vecV_t *cl_strisvertv; +vec4_t *cl_strisvertc; +vec2_t *cl_strisvertt; +index_t *cl_strisidx; +unsigned int cl_numstrisidx; +unsigned int cl_maxstrisidx; +unsigned int cl_numstrisvert; +unsigned int cl_maxstrisvert; +unsigned int cl_numstris; +unsigned int cl_maxstris; + double connect_time = -1; // for connection retransmits int connect_type = 0; int connect_tries = 0; //increased each try, every fourth trys nq connect packets. @@ -279,6 +294,7 @@ void CL_ConnectToDarkPlaces(char *challenge, netadr_t adr) { char data[2048]; cls.fteprotocolextensions = 0; + cls.fteprotocolextensions2 = 0; cls.resendinfo = false; @@ -292,9 +308,10 @@ void CL_ConnectToDarkPlaces(char *challenge, netadr_t adr) } #ifdef PROTOCOL_VERSION_FTE -unsigned int CL_SupportedFTEExtensions(void) +void CL_SupportedFTEExtensions(int *pext1, int *pext2) { unsigned int fteprotextsupported = 0; + unsigned int fteprotextsupported2 = 0; #ifdef PEXT_SCALE //dmw - protocol extensions fteprotextsupported |= PEXT_SCALE; @@ -373,12 +390,19 @@ unsigned int CL_SupportedFTEExtensions(void) fteprotextsupported |= PEXT_DPFLAGS; #endif + fteprotextsupported2 |= PEXT2_PRYDONCURSOR; + fteprotextsupported &= strtoul(cl_pext_mask.string, NULL, 16); +// fteprotextsupported2 &= strtoul(cl_pext2_mask.string, NULL, 16); - if (cl_nopext.value) + if (cl_nopext.ival) + { fteprotextsupported = 0; + fteprotextsupported2 = 0; + } - return fteprotextsupported; + *pext1 = fteprotextsupported; + *pext2 = fteprotextsupported2; } #endif @@ -391,7 +415,7 @@ called by CL_Connect_f and CL_CheckResend */ void CL_SendConnectPacket ( #ifdef PROTOCOL_VERSION_FTE - int ftepext, + int ftepext, int ftepext2, #endif int compressioncrc /*, ...*/) //dmw new parms @@ -403,6 +427,7 @@ void CL_SendConnectPacket ( double t1, t2; #ifdef PROTOCOL_VERSION_FTE int fteprotextsupported=0; + int fteprotextsupported2=0; #endif int clients; int c; @@ -414,15 +439,16 @@ void CL_SendConnectPacket ( if (cls.state != ca_disconnected) return; - if (cl_nopext.value) //imagine it's an unenhanced server + if (cl_nopext.ival) //imagine it's an unenhanced server { compressioncrc = 0; } #ifdef PROTOCOL_VERSION_FTE - fteprotextsupported = CL_SupportedFTEExtensions(); + CL_SupportedFTEExtensions(&fteprotextsupported, &fteprotextsupported2); fteprotextsupported &= ftepext; + fteprotextsupported2 &= ftepext2; #ifdef Q2CLIENT if (cls.protocol != CP_QUAKEWORLD) @@ -430,6 +456,7 @@ void CL_SendConnectPacket ( #endif cls.fteprotocolextensions = fteprotextsupported; + cls.fteprotocolextensions2 = fteprotextsupported2; #endif t1 = Sys_DoubleTime (); @@ -526,6 +553,10 @@ void CL_SendConnectPacket ( if (ftepext) Q_strncatz(data, va("0x%x 0x%x\n", PROTOCOL_VERSION_FTE, fteprotextsupported), sizeof(data)); #endif +#ifdef PROTOCOL_VERSION_FTE2 + if (ftepext2) + Q_strncatz(data, va("0x%x 0x%x\n", PROTOCOL_VERSION_FTE2, fteprotextsupported2), sizeof(data)); +#endif #ifdef HUFFNETWORK if (compressioncrc && Huff_CompressionCRC(compressioncrc)) @@ -616,7 +647,7 @@ void CL_CheckForResend (void) CL_ConnectToDarkPlaces("", adr); } else - CL_SendConnectPacket (svs.fteprotocolextensions, false); + CL_SendConnectPacket (svs.fteprotocolextensions, svs.fteprotocolextensions2, false); return; } #endif @@ -839,7 +870,6 @@ void CLNQ_Connect_f (void) #endif #ifdef IRCCONNECT -struct ftenet_generic_connection_s *FTENET_IRCConnect_EstablishConnection(qboolean isserver, char *address); void CL_IRCConnect_f (void) { CL_Disconnect_f (); @@ -1025,7 +1055,7 @@ void CL_ClearState (void) // memset (cl_dlights, 0, sizeof(cl_dlights)); memset (cl_lightstyle, 0, sizeof(cl_lightstyle)); - dlights_running = 0; + rtlights_first = rtlights_max = RTL_FIRST; if (cl_baselines) { @@ -1144,7 +1174,7 @@ void CL_Disconnect (void) if (cl.worldmodel) { -#if defined(RUNTIMELIGHTING) && defined(RGLQUAKE) +#if defined(RUNTIMELIGHTING) && defined(GLQUAKE) extern model_t *lightmodel; lightmodel = NULL; #endif @@ -1374,9 +1404,6 @@ void CL_CheckServerInfo(void) unsigned int allowed; int oldstate; int oldteamplay; - qboolean oldallowshaders; - - oldallowshaders = cls.allow_shaders; oldteamplay = cl.teamplay; cl.teamplay = atoi(Info_ValueForKey(cl.serverinfo, "teamplay")); @@ -1388,7 +1415,6 @@ void CL_CheckServerInfo(void) cls.allow_watervis=false; cls.allow_skyboxes=false; cls.allow_mirrors=false; - cls.allow_shaders=false; cls.allow_luma=false; cls.allow_bump=false; #ifdef FISH @@ -1435,18 +1461,12 @@ void CL_CheckServerInfo(void) cls.allow_cheats = true; s = Info_ValueForKey(cl.serverinfo, "strict"); - if ((!cl.spectator && !cls.demoplayback && *s && strcmp(s, "0")) || !ruleset_allow_semicheats.value) + if ((!cl.spectator && !cls.demoplayback && *s && strcmp(s, "0")) || !ruleset_allow_semicheats.ival) { cls.allow_semicheats = false; cls.allow_cheats = false; } - cls.allow_shaders = cls.allow_cheats; - - if (cl.spectator || cls.demoplayback || atoi(Info_ValueForKey(cl.serverinfo, "allow_shaders"))) - cls.allow_shaders=true; - - cls.maxfps = atof(Info_ValueForKey(cl.serverinfo, "maxfps")); if (cls.maxfps < 20) cls.maxfps = 72; @@ -1471,10 +1491,18 @@ void CL_CheckServerInfo(void) movevars.stepheight = PM_DEFAULTSTEPHEIGHT; // Initialize cl.maxpitch & cl.minpitch - s = (cls.z_ext & Z_EXT_PITCHLIMITS) ? Info_ValueForKey (cl.serverinfo, "maxpitch") : ""; - cl.maxpitch = *s ? Q_atof(s) : 80.0f; - s = (cls.z_ext & Z_EXT_PITCHLIMITS) ? Info_ValueForKey (cl.serverinfo, "minpitch") : ""; - cl.minpitch = *s ? Q_atof(s) : -70.0f; + if (cls.protocol == CP_QUAKEWORLD || cls.protocol == CP_NETQUAKE) + { + s = (cls.z_ext & Z_EXT_PITCHLIMITS) ? Info_ValueForKey (cl.serverinfo, "maxpitch") : ""; + cl.maxpitch = *s ? Q_atof(s) : 80.0f; + s = (cls.z_ext & Z_EXT_PITCHLIMITS) ? Info_ValueForKey (cl.serverinfo, "minpitch") : ""; + cl.minpitch = *s ? Q_atof(s) : -70.0f; + } + else + { + cl.maxpitch = 89.9; + cl.minpitch = -89.9; + } allowed = atoi(Info_ValueForKey(cl.serverinfo, "allow")); if (allowed & 1) @@ -1485,8 +1513,7 @@ void CL_CheckServerInfo(void) cls.allow_skyboxes = true; if (allowed & 8) cls.allow_mirrors = true; - if (allowed & 16) - cls.allow_shaders = true; + //16 if (allowed & 32) cls.allow_luma = true; if (allowed & 64) @@ -1526,8 +1553,6 @@ void CL_CheckServerInfo(void) Cvar_ForceCheatVars(cls.allow_semicheats, cls.allow_cheats); Validation_Apply_Ruleset(); - if (oldallowshaders != cls.allow_shaders) - Cache_Flush(); //this will cause all models to be reloaded. if (oldteamplay != cl.teamplay) Skin_FlushPlayers(); } @@ -1622,7 +1647,7 @@ void CL_FullInfo_f (void) if (!stricmp(key, pmodel_name) || !stricmp(key, emodel_name)) continue; - Info_SetValueForKey (cls.userinfo, key, value, MAX_INFO_STRING); + Info_SetValueForKey (cls.userinfo, key, value, sizeof(cls.userinfo)); } } @@ -1636,7 +1661,7 @@ void CL_SetInfo (char *key, char *value) return; } - Info_SetValueForStarKey (cls.userinfo, key, value, MAX_INFO_STRING); + Info_SetValueForStarKey (cls.userinfo, key, value, sizeof(cls.userinfo)); if (cls.state >= ca_connected) { #ifdef Q2CLIENT @@ -1755,7 +1780,7 @@ void CL_Packet_f (void) cls.realserverip = adr; Con_DPrintf ("Sending realip packet\n"); } - else if (!ruleset_allow_packet.value) + else if (!ruleset_allow_packet.ival) { Con_Printf("Sorry, the %s command is disallowed\n", Cmd_Argv(0)); return; @@ -1818,7 +1843,10 @@ void CL_NextDemo (void) } } - sprintf (str,"playdemo %s\n", cls.demos[cls.demonum]); + if (!strcmp(cls.demos[cls.demonum], "quit")) + sprintf (str,"quit\n"); + else + sprintf (str,"playdemo %s\n", cls.demos[cls.demonum]); Cbuf_InsertText (str, RESTRICT_LOCAL, false); cls.demonum++; } @@ -2060,7 +2088,7 @@ void CL_ConnectionlessPacket (void) if (c == S2C_CHALLENGE) { - unsigned long pext = 0, huffcrc=0; + unsigned long pext = 0, pext2 = 0, huffcrc=0; Con_TPrintf (TLC_S2C_CHALLENGE); s = MSG_ReadString (); @@ -2072,7 +2100,7 @@ void CL_ConnectionlessPacket (void) { cls.protocol = CP_QUAKE3; cls.challenge = atoi(s+17); - CL_SendConnectPacket (0, 0/*, ...*/); + CL_SendConnectPacket (0, 0, 0/*, ...*/); } else { @@ -2150,6 +2178,8 @@ void CL_ConnectionlessPacket (void) break; if (c == PROTOCOL_VERSION_FTE) pext = MSG_ReadLong (); + else if (c == PROTOCOL_VERSION_FTE2) + pext2 = MSG_ReadLong (); #ifdef HUFFNETWORK else if (c == (('H'<<0) + ('U'<<8) + ('F'<<16) + ('F' << 24))) huffcrc = MSG_ReadLong (); @@ -2158,7 +2188,7 @@ void CL_ConnectionlessPacket (void) else MSG_ReadLong (); } - CL_SendConnectPacket (pext, huffcrc/*, ...*/); + CL_SendConnectPacket (pext, pext2, huffcrc/*, ...*/); return; } #ifdef Q2CLIENT @@ -2558,7 +2588,6 @@ void CL_ReadPackets (void) CLQ3_ParseServerMessage(); #endif break; - break; case CP_QUAKEWORLD: if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV) { @@ -2691,7 +2720,7 @@ void CL_DownloadSize_f(void) dl = CL_DownloadFailed(rname); - if (allow_download_redirection.value) + if (allow_download_redirection.ival) { Con_DPrintf("Download of \"%s\" redirected to \"%s\".\n", rname, redirection); CL_CheckOrEnqueDownloadFile(redirection, NULL, dl->flags); @@ -2836,7 +2865,7 @@ void CL_Init (void) cls.state = ca_disconnected; sprintf (st, "%s %i", DISTRIBUTION, build_number()); - Info_SetValueForStarKey (cls.userinfo, "*ver", st, MAX_INFO_STRING); + Info_SetValueForStarKey (cls.userinfo, "*ver", st, sizeof(cls.userinfo)); InitValidation(); @@ -2844,6 +2873,7 @@ void CL_Init (void) CL_InitTEnts (); CL_InitPrediction (); CL_InitCam (); + CL_InitDlights(); PM_Init (); TP_Init(); @@ -2908,6 +2938,7 @@ void CL_Init (void) Cvar_Register (&cl_staticsounds, "Item effects"); + Cvar_Register (&r_torch, "Item effects"); Cvar_Register (&r_rocketlight, "Item effects"); Cvar_Register (&r_lightflicker, "Item effects"); Cvar_Register (&cl_r2g, "Item effects"); @@ -2987,6 +3018,7 @@ void CL_Init (void) Cvar_Register (&ruleset_allow_modified_eyes, cl_controlgroup); Cvar_Register (&ruleset_allow_sensative_texture_replacements, cl_controlgroup); Cvar_Register (&ruleset_allow_localvolume, cl_controlgroup); + Cvar_Register (&ruleset_allow_shaders, cl_controlgroup); Cvar_Register (&qtvcl_forceversion1, cl_controlgroup); Cvar_Register (&qtvcl_eztvextensions, cl_controlgroup); @@ -3006,6 +3038,10 @@ void CL_Init (void) Cmd_AddCommand ("demo_jump", CL_DemoJump_f); Cmd_AddCommand ("timedemo", CL_TimeDemo_f); +#ifdef _DEBUG + Cmd_AddCommand ("crashme", (void*)~0); +#endif + Cmd_AddCommand ("showpic", SCR_ShowPic_Script_f); Cmd_AddCommand ("startdemos", CL_Startdemos_f); @@ -3244,9 +3280,12 @@ void Host_Frame (double time) // realframetime *= cl_demospeed.value; // this probably screws up other timings #ifndef CLIENTONLY - RSpeedRemark(); - SV_Frame(); - RSpeedEnd(RSPEED_SERVER); + if (sv.state) + { + RSpeedRemark(); + SV_Frame(); + RSpeedEnd(RSPEED_SERVER); + } #endif if (cl.gamespeed<0.1) @@ -3286,22 +3325,22 @@ void Host_Frame (double time) */ Mod_Think(); //think even on idle (which means small walls and a fast cpu can get more surfaces done. - if ((cl_netfps.value>0 || cls.demoplayback || cl_indepphysics.value)) + if ((cl_netfps.value>0 || cls.demoplayback || cl_indepphysics.ival)) { //limit the fps freely, and expect the netfps to cope. - if (cl_maxfps.value > 0) + if (cl_maxfps.ival > 0) if ((realtime - oldrealtime) < 1/cl_maxfps.value) return; } else { realtime += spare/1000; //don't use it all! - spare = CL_FilterTime((realtime - oldrealtime)*1000, (cl_maxfps.value>0||cls.protocol!=CP_QUAKEWORLD)?cl_maxfps.value:cl_netfps.value); + spare = CL_FilterTime((realtime - oldrealtime)*1000, (cl_maxfps.ival>0||cls.protocol!=CP_QUAKEWORLD)?cl_maxfps.value:cl_netfps.value); if (!spare) return; if (spare < 0 || cls.state < ca_onserver) spare = 0; //uncapped. - if (spare > cl_sparemsec.value) - spare = cl_sparemsec.value; + if (spare > cl_sparemsec.ival) + spare = cl_sparemsec.ival; realtime -= spare/1000; //don't use it all! } @@ -3343,7 +3382,7 @@ void Host_Frame (double time) RSpeedRemark(); - CL_UseIndepPhysics(!!cl_indepphysics.value); + CL_UseIndepPhysics(!!cl_indepphysics.ival); CL_AllowIndependantSendCmd(false); @@ -3359,7 +3398,7 @@ void Host_Frame (double time) } else { - CL_SendCmd (host_frametime/cl.gamespeed, true); + CL_SendCmd (cl.gamespeed?host_frametime/cl.gamespeed:host_frametime, true); if (cls.state == ca_onserver && cl.validsequence && cl.worldmodel) { // first update is the final signon stage @@ -3371,7 +3410,7 @@ void Host_Frame (double time) RSpeedEnd(RSPEED_PROTOCOL); // update video - if (host_speeds.value) + if (host_speeds.ival) time1 = Sys_DoubleTime (); if (SCR_UpdateScreen) @@ -3379,7 +3418,7 @@ void Host_Frame (double time) extern mleaf_t *r_viewleaf; extern cvar_t scr_chatmodecvar; - if (scr_chatmodecvar.value && !cl.intermission) + if (scr_chatmodecvar.ival && !cl.intermission) scr_chatmode = (cl.spectator&&cl.splitclients<2&&cls.state == ca_active)?2:1; else scr_chatmode = 0; @@ -3391,7 +3430,7 @@ void Host_Frame (double time) SNDDMA_SetUnderWater(false); } - if (host_speeds.value) + if (host_speeds.ival) time2 = Sys_DoubleTime (); // update audio @@ -3412,7 +3451,7 @@ void Host_Frame (double time) CDAudio_Update(); - if (host_speeds.value) + if (host_speeds.ival) { pass1 = (time1 - time3)*1000; time3 = Sys_DoubleTime (); diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 40674e35..8562d97a 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -253,7 +253,7 @@ int CL_CalcNet (void) lost++; } - if (!cl_countpendingpl.value) + if (!cl_countpendingpl.ival) { pending = cls.netchan.outgoing_sequence - cls.netchan.incoming_sequence - 1; lost -= pending; @@ -770,7 +770,7 @@ void Model_CheckDownloads (void) #ifdef Q2CLIENT if (cls.protocol == CP_QUAKE2) { - R_SetSky(cl.skyname, cl.skyrotate, cl.skyaxis); +// R_SetSky(cl.skyname); for (i = 0; i < Q2MAX_IMAGES; i++) { char picname[256]; @@ -837,7 +837,7 @@ int CL_LoadModels(int stage, qboolean dontactuallyload) { extern cvar_t allow_download_csprogs; unsigned int chksum = strtoul(s, NULL, 0); - if (allow_download_csprogs.value) + if (allow_download_csprogs.ival) { char *str = va("csprogsvers/%x.dat", chksum); if (CL_CheckOrEnqueDownloadFile("csprogs.dat", str, DLLF_REQUIRED)) @@ -865,12 +865,16 @@ int CL_LoadModels(int stage, qboolean dontactuallyload) if (atstage()) { char *s; - s = Info_ValueForKey(cl.serverinfo, "*csprogs"); -#ifndef FTE_DEBUG - if (*s || cls.demoplayback) //only allow csqc if the server says so, and the 'checksum' matches. + qboolean anycsqc; +#if 0//ndef FTE_DEBUG + anycsqc = true; +#else + anycsqc = atoi(Info_ValueForKey(cl.serverinfo, "anycsqc")); #endif + s = Info_ValueForKey(cl.serverinfo, "*csprogs"); + if (anycsqc || *s || cls.demoplayback) //only allow csqc if the server says so, and the 'checksum' matches. { - unsigned int chksum = strtoul(s, NULL, 0); + unsigned int chksum = anycsqc?0:strtoul(s, NULL, 0); if (CSQC_Init(chksum)) { CL_SendClientCommand(true, "enablecsqc"); @@ -965,8 +969,6 @@ int CL_LoadModels(int stage, qboolean dontactuallyload) else cl.hexen2pickups = false; - R_CheckSky(); - #ifdef CSQC_DAT CSQC_WorldLoaded(); #endif @@ -1079,7 +1081,7 @@ void Sound_CheckDownloads (void) { extern cvar_t allow_download_csprogs; unsigned int chksum = strtoul(s, NULL, 0); - if (allow_download_csprogs.value) + if (allow_download_csprogs.ival) { char *str = va("csprogsvers/%x.dat", chksum); CL_CheckOrEnqueDownloadFile("csprogs.dat", str, DLLF_REQUIRED); @@ -1222,7 +1224,7 @@ void CL_RequestNextDownload (void) { if (CL_RemoveClientCommands("qtvspawn")) Con_Printf("Multiple prespawns\n"); - CL_SendClientCommand(true, "qtvspawn %i 0 %i", cl.servercount, cl.worldmodel->checksum2); + CL_SendClientCommand(true, "qtvspawn %i 0 %i", cl.servercount, COM_RemapMapChecksum(LittleLong(cl.worldmodel->checksum2))); SCR_SetLoadingStage(LS_NONE); } else @@ -1231,7 +1233,7 @@ void CL_RequestNextDownload (void) if (CL_RemoveClientCommands("prespawn")) Con_Printf("Multiple prespawns\n"); // CL_SendClientCommand("prespawn %i 0 %i", cl.servercount, cl.worldmodel->checksum2); - CL_SendClientCommand(true, prespawn_name, cl.servercount, LittleLong(cl.worldmodel->checksum2)); + CL_SendClientCommand(true, prespawn_name, cl.servercount, COM_RemapMapChecksum(LittleLong(cl.worldmodel->checksum2))); } } @@ -1676,7 +1678,7 @@ void CL_ParseDownload (void) if (cls.downloadmethod == DL_QWPENDING) cls.downloadmethod = DL_QW; - if (percent != 100 && size == 0 && cl_dlemptyterminate.value) + if (percent != 100 && size == 0 && cl_dlemptyterminate.ival) { Con_Printf(CON_WARNING "WARNING: Client received empty svc_download, assuming EOF\n"); percent = 100; @@ -2012,14 +2014,18 @@ void CL_ParseServerData (void) // allow 2.2 and 2.29 demos to play #ifdef PROTOCOL_VERSION_FTE cls.fteprotocolextensions=0; + cls.fteprotocolextensions2=0; for(;;) { protover = MSG_ReadLong (); if (protover == PROTOCOL_VERSION_FTE) { cls.fteprotocolextensions = MSG_ReadLong(); - if (developer.value || cl_shownet.value) - Con_TPrintf (TL_FTEEXTENSIONS, cls.fteprotocolextensions); + continue; + } + if (protover == PROTOCOL_VERSION_FTE2) + { + cls.fteprotocolextensions2 = MSG_ReadLong(); continue; } if (protover == PROTOCOL_VERSION_QW) //this ends the version info @@ -2035,6 +2041,10 @@ void CL_ParseServerData (void) Host_EndGame ("Server returned version %i, not %i\n", protover, PROTOCOL_VERSION_QW); #endif + if (cls.fteprotocolextensions2||cls.fteprotocolextensions) + if (developer.ival || cl_shownet.ival) + Con_TPrintf (TL_FTEEXTENSIONS, cls.fteprotocolextensions2, cls.fteprotocolextensions); + if (cls.fteprotocolextensions & PEXT_FLOATCOORDS) { sizeofcoord = 4; @@ -2323,7 +2333,7 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution. char *str; int gametype; int protover; - if (developer.value) + if (developer.ival) Con_TPrintf (TLC_GOTSVDATAPACKET); SCR_SetLoadingStage(LS_CLIENT); CL_ClearState (); @@ -2453,7 +2463,7 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution. { Info_SetValueForStarKey(cl.serverinfo, "*csprogs", va("%i", cl_dp_csqc_progscrc), sizeof(cl.serverinfo)); Info_SetValueForStarKey(cl.serverinfo, "*csprogssize", va("%i", cl_dp_csqc_progssize), sizeof(cl.serverinfo)); - Info_SetValueForStarKey(cl.serverinfo, "*csprogsname", va("%i", cl_dp_csqc_progsname), sizeof(cl.serverinfo)); + Info_SetValueForStarKey(cl.serverinfo, "*csprogsname", va("%s", cl_dp_csqc_progsname), sizeof(cl.serverinfo)); } //update gamemode @@ -2494,7 +2504,7 @@ Con_DPrintf ("CL_SignonReply: %i\n", cls.signon); case 2: CL_SendClientCommand(true, "name \"%s\"\n", name.string); - CL_SendClientCommand(true, "color %i %i\n", (int)topcolor.value, (int)bottomcolor.value); + CL_SendClientCommand(true, "color %i %i\n", topcolor.ival, bottomcolor.ival); CL_SendClientCommand(true, "spawn %s", ""); @@ -3160,7 +3170,8 @@ void CL_ParseStaticSound (void) vol = MSG_ReadByte (); atten = MSG_ReadByte (); - if (!cl_staticsounds.value) + vol *= cl_staticsounds.value; + if (vol < 0) return; S_StaticSound (cl.sound_precache[sound_num], org, vol, atten); @@ -3739,7 +3750,7 @@ void CL_MuzzleFlash (int destsplit) i = MSG_ReadShort (); //was it us? - if (!cl_muzzleflash.value) // remove all muzzleflashes + if (!cl_muzzleflash.ival) // remove all muzzleflashes return; if (i-1 == cl.playernum[destsplit] && cl_muzzleflash.value == 2) @@ -4241,7 +4252,7 @@ void CL_PrintChat(player_info_t *plr, char *rawmsg, char *msg, int plrflags) if (plr) // use special formatting with a real chat message name = plr->name; // use player's name - if (cl_standardchat.value) + if (cl_standardchat.ival) { name_coloured = true; c = 7; @@ -4288,7 +4299,7 @@ void CL_PrintChat(player_info_t *plr, char *rawmsg, char *msg, int plrflags) Q_strncatz(fullchatmessage, va("%s%s^d", name_coloured?"^m":"", name), sizeof(fullchatmessage)); Q_strncatz(fullchatmessage, va("%s^%c)", name_coloured?"^m":"", c), sizeof(fullchatmessage)); } - else if (cl_standardchat.value) + else if (cl_standardchat.ival) { Q_strncatz(fullchatmessage, va("\1%s", name), sizeof(fullchatmessage)); } @@ -4403,7 +4414,7 @@ void CL_PrintStandardMessage(char *msg, int printlevel) msg = v + len; // update search point // get name color - if (p->spectator || cl_standardmsg.value) + if (p->spectator || cl_standardmsg.ival) { coloured = false; c = '7'; @@ -5147,7 +5158,7 @@ void CLQ2_ParseServerMessage (void) switch (cmd) { default: - Host_EndGame ("CL_ParseServerMessage: Illegible server message"); + Host_EndGame ("CLQ2_ParseServerMessage: Illegible server message (%i)", cmd); return; //known to game @@ -5523,8 +5534,8 @@ void CLNQ_ParseServerMessage (void) cl.playernum[0] = (cl.viewentity[0] = MSG_ReadShort())-1; if (cl.playernum[0] >= MAX_CLIENTS) { - cl.playernum[0] = 32; //pretend it's an mvd (we have that spare slot) - Con_Printf(CON_WARNING "WARNING: Server put us in slot %i. We are not on the scoreboard.\n"); + Con_Printf(CON_WARNING "WARNING: Server put us in slot %i. We are not on the scoreboard.\n", cl.playernum[0]); + cl.playernum[0] = MAX_CLIENTS; //pretend it's an mvd (we have that spare slot) } } else diff --git a/engine/client/cl_plugin.inc b/engine/client/cl_plugin.inc index 331ed3d5..955d3478 100644 --- a/engine/client/cl_plugin.inc +++ b/engine/client/cl_plugin.inc @@ -215,7 +215,7 @@ qintptr_t VARGS Plug_Draw_Line(void *offset, quintptr_t mask, const qintptr_t *a { switch(qrenderer) //FIXME: I don't want qrenderer seen outside the refresh { -#ifdef RGLQUAKE +#ifdef GLQUAKE case QR_OPENGL: qglDisable(GL_TEXTURE_2D); qglBegin(GL_LINES); @@ -232,9 +232,12 @@ qintptr_t VARGS Plug_Draw_Line(void *offset, quintptr_t mask, const qintptr_t *a } qintptr_t VARGS Plug_Draw_Character(void *offset, quintptr_t mask, const qintptr_t *arg) { + int x, y; if (qrenderer <= 0) return 0; - Draw_Character(arg[0], arg[1], (unsigned int)arg[2]); + Font_BeginString(font_conchar, arg[0], arg[1], &x, &y); + Font_DrawChar(x, y, CON_WHITEMASK | 0xe000 | (unsigned int)arg[2]); + Font_EndString(font_conchar); return 0; } void (D3D_Draw_Fill_Colours) (int x, int y, int w, int h); @@ -249,7 +252,7 @@ qintptr_t VARGS Plug_Draw_Fill(void *offset, quintptr_t mask, const qintptr_t *a height = VM_FLOAT(arg[3]); switch(qrenderer) //FIXME: I don't want qrenderer seen outside the refresh { -#ifdef RGLQUAKE +#ifdef GLQUAKE case QR_OPENGL: qglDisable(GL_TEXTURE_2D); qglBegin(GL_QUADS); diff --git a/engine/client/cl_pred.c b/engine/client/cl_pred.c index f9133ce1..415bc891 100644 --- a/engine/client/cl_pred.c +++ b/engine/client/cl_pred.c @@ -644,17 +644,21 @@ void CL_CalcClientTime(void) { float want; - float oldst = cl.servertime; + float oldst = realtime; - want = cl.oldgametime + (realtime - cl.gametimemark); - if (want>cl.servertime) - cl.servertime = want; - - if (cl.servertime > cl.gametime) - cl.servertime = cl.gametime; - if (cl.servertime < cl.oldgametime) - cl.servertime = cl.oldgametime; + if (!(cls.fteprotocolextensions & PEXT_ACCURATETIMINGS) && cls.protocol == CP_QUAKEWORLD) + cl.servertime = cl.time; + else + { + want = cl.oldgametime + (realtime - cl.gametimemark); + if (want>cl.servertime) + cl.servertime = want; + if (cl.servertime > cl.gametime) + cl.servertime = cl.gametime; + if (cl.servertime < cl.oldgametime) + cl.servertime = cl.oldgametime; + } if (oldst == 0) { int i; @@ -806,7 +810,7 @@ void CL_PredictMovePNum (int pnum) f = 1-f; // Con_Printf("%f\n", f); -// if (cl_nolerp.value) +// if (cl_nolerp.ival) // f = 1; diff --git a/engine/client/cl_screen.c b/engine/client/cl_screen.c index 7f4a37f2..6dfb8da0 100644 --- a/engine/client/cl_screen.c +++ b/engine/client/cl_screen.c @@ -21,9 +21,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // cl_screen.c -- master for refresh, status bar, console, chat, notify, etc #include "quakedef.h" -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h"//would prefer not to have this #endif +#include "shader.h" //name of the current backdrop for the loading screen char levelshotname[MAX_QPATH]; @@ -39,7 +40,7 @@ void RSpeedShow(void) char *s; static int framecount; - if (!r_speeds.value) + if (!r_speeds.ival) return; memset(RSpNames, 0, sizeof(RSpNames)); @@ -49,7 +50,7 @@ void RSpeedShow(void) RSpNames[RSPEED_WORLDNODE] = "World walking"; RSpNames[RSPEED_WORLD] = "World rendering"; RSpNames[RSPEED_DYNAMIC] = "Lightmap updates"; - RSpNames[RSPEED_PARTICLES] = "Particle physics and sorting"; + RSpNames[RSPEED_PARTICLES] = "Particle phys/sort"; RSpNames[RSPEED_PARTICLESDRAW] = "Particle drawing"; RSpNames[RSPEED_2D] = "2d elements"; RSpNames[RSPEED_SERVER] = "Server"; @@ -61,7 +62,7 @@ void RSpeedShow(void) RSpNames[RSPEED_FULLBRIGHTS] = "World fullbrights"; - RSpNames[RSPEED_FINISH] = "Waiting for card to catch up"; + RSpNames[RSPEED_FINISH] = "glFinish"; RQntNames[RQUANT_MSECS] = "Microseconds"; RQntNames[RQUANT_EPOLYS] = "Entity Polys"; @@ -72,16 +73,16 @@ void RSpeedShow(void) for (i = 0; i < RSPEED_MAX; i++) { - s = va("%i %-30s", samplerspeeds[i], RSpNames[i]); - Draw_String(vid.width-strlen(s)*8, i*8, s); + s = va("%i %-20s", samplerspeeds[i], RSpNames[i]); + Draw_FunString(vid.width-strlen(s)*8, i*8, s); } for (i = 0; i < RQUANT_MAX; i++) { - s = va("%i %-30s", samplerquant[i], RQntNames[i]); - Draw_String(vid.width-strlen(s)*8, (i+RSPEED_MAX)*8, s); + s = va("%i %-20s", samplerquant[i], RQntNames[i]); + Draw_FunString(vid.width-strlen(s)*8, (i+RSPEED_MAX)*8, s); } - s = va("%f %-30s", 100000000.0f/samplerspeeds[RSPEED_TOTALREFRESH], "Framerate"); - Draw_String(vid.width-strlen(s)*8, (i+RSPEED_MAX)*8, s); + s = va("%f %-20s", 100000000.0f/samplerspeeds[RSPEED_TOTALREFRESH], "Framerate"); + Draw_FunString(vid.width-strlen(s)*8, (i+RSPEED_MAX)*8, s); if (framecount++>=100) { @@ -240,12 +241,26 @@ CENTER PRINTING =============================================================================== */ -conchar_t scr_centerstring[MAX_SPLITS][1024]; -float scr_centertime_start[MAX_SPLITS]; // for slow victory printing -float scr_centertime_off[MAX_SPLITS]; -int scr_center_lines[MAX_SPLITS]; -int scr_erase_lines[MAX_SPLITS]; -int scr_erase_center[MAX_SPLITS]; +typedef struct { + unsigned int flags; +#define CPRINT_BALIGN (1<<0) //B +#define CPRINT_OBITUARTY (1<<1) //O +#define CPRINT_TALIGN (1<<2) //T +#define CPRINT_LALIGN (1<<3) //L +#define CPRINT_RALIGN (1<<4) //R +#define CPRINT_PERSIST (1<<5) //P +#define CPRINT_BACKGROUND (1<<6) //P +#define CPRINT_TYPEWRITER (1<<7) // + + conchar_t string[1024]; + unsigned int charcount; + float time_start; // for slow victory printing + float time_off; + int erase_lines; + int erase_center; +} cprint_t; + +cprint_t scr_centerprint[MAX_SPLITS]; // SCR_StringToRGB: takes in "" or " " and converts to an RGB vector void SCR_StringToRGB (char *rgbstring, float *rgb, float rgbinputscale) @@ -332,6 +347,7 @@ for a few moments */ void SCR_CenterPrint (int pnum, char *str, qboolean skipgamecode) { + cprint_t *p; if (!skipgamecode) { #ifdef CSQC_DAT @@ -350,18 +366,38 @@ void SCR_CenterPrint (int pnum, char *str, qboolean skipgamecode) Cbuf_AddText("f_centerprint\n", RESTRICT_LOCAL); } - COM_ParseFunString(CON_WHITEMASK, str, scr_centerstring[pnum], sizeof(scr_centerstring[pnum]), false); - scr_centertime_off[pnum] = scr_centertime.value; - scr_centertime_start[pnum] = cl.time; + p = &scr_centerprint[pnum]; + p->flags = 0; + if (cl.intermission) + p->flags |= CPRINT_TYPEWRITER | CPRINT_PERSIST; -// count the number of lines for centering - scr_center_lines[pnum] = 1; - while (*str) + while (*str == '/') { - if (*str == '\n') - scr_center_lines[pnum]++; - str++; + if (str[1] == '.') + { +/* /. means text actually starts after, no more flags */ + str+=2; + break; + } + else if (str[1] == 'P') + p->flags |= CPRINT_PERSIST | CPRINT_BACKGROUND; + else if (str[1] == 'O') + p->flags = CPRINT_OBITUARTY; + else if (str[1] == 'B') + p->flags |= CPRINT_BALIGN; //Note: you probably want to add some blank lines... + else if (str[1] == 'T') + p->flags |= CPRINT_TALIGN; + else if (str[1] == 'L') + p->flags |= CPRINT_LALIGN; + else if (str[1] == 'R') + p->flags |= CPRINT_RALIGN; + else + break; + str += 2; } + p->charcount = COM_ParseFunString(CON_WHITEMASK, str, p->string, sizeof(p->string), false) - p->string; + p->time_off = scr_centertime.value; + p->time_start = cl.time; } void SCR_CPrint_f(void) @@ -371,6 +407,7 @@ void SCR_CPrint_f(void) void SCR_EraseCenterString (void) { + cprint_t *p; int pnum; int y; @@ -379,161 +416,121 @@ void SCR_EraseCenterString (void) for (pnum = 0; pnum < cl.splitclients; pnum++) { - if (scr_erase_center[pnum]++ > vid.numpages) + p = &scr_centerprint[pnum]; + + if (p->erase_center++ > vid.numpages) { - scr_erase_lines[pnum] = 0; + p->erase_lines = 0; continue; } - if (scr_center_lines[pnum] <= 4) - y = vid.height*0.35; - else - y = 48; - - Draw_TileClear (0, y, vid.width, min(8*scr_erase_lines[pnum], vid.height - y - 1)); + y = vid.height>>1; + Draw_TileClear (0, y, vid.width, min(8*p->erase_lines, vid.height - y - 1)); } } -void SCR_CenterPrintBreaks(conchar_t *start, int *lines, int *maxlength) +#define MAX_CPRINT_LINES 128 +void SCR_DrawCenterString (vrect_t *rect, cprint_t *p) { - int l; - *lines = 0; - *maxlength = 0; - do - { - // scan the width of the line - for (l=0 ; l<40 ; l++) - if ((start[l]&CON_CHARMASK) == '\n' || !(start[l]&CON_CHARMASK)) - break; - if (l == 40) - { - while(l > 0 && (start[l-1]&CON_CHARMASK)>' ') - { - l--; - } - } - - (*lines)++; - if (*maxlength < l) - *maxlength = l; - - start+=l; -// for (l=0 ; l<40 && *start && *start != '\n'; l++) - // start++; - - if (!(*start&CON_CHARMASK)) - break; - else if ((*start&CON_CHARMASK) == '\n'||!l) - start++; // skip the \n - } while (1); -} - -void SCR_DrawCenterString (int pnum) -{ - conchar_t *start; int l; - int j; - int x, y; + int y, x; + int left; + int right; + int top; + int bottom; int remaining; - int hd = 1; - int screenwidth; - vrect_t rect; + conchar_t *str; + conchar_t *line_start[MAX_CPRINT_LINES]; + conchar_t *line_end[MAX_CPRINT_LINES]; + int linecount; - int telejanostyle = 0; - - if (cl.splitclients) - hd = cl.splitclients; // the finale prints the characters one at a time - if (cl.intermission) - remaining = scr_printspeed.value * (cl.time - scr_centertime_start[pnum]); + if (p->flags & CPRINT_TYPEWRITER) + remaining = scr_printspeed.value * (cl.time - p->time_start); else remaining = 9999; - scr_erase_center[pnum] = 0; - start = scr_centerstring[pnum]; + p->erase_center = 0; - if (scr_center_lines[pnum] <= 4) - y = vid.height/hd*0.35; - else - y = 48; + Font_BeginString(font_conchar, rect->x, rect->y, &left, &top); + Font_BeginString(font_conchar, rect->x+rect->width, rect->y+rect->height, &right, &bottom); + linecount = Font_LineBreaks(p->string, p->string + p->charcount, right - left, MAX_CPRINT_LINES, line_start, line_end); - SCR_VRectForPlayer(&rect, pnum); - - y += rect.y; - - screenwidth = 40;//vid.width/8; - - if ((start[0]&CON_CHARMASK) == '/') - { - if ((start[1]&CON_CHARMASK) == 'O') - { - telejanostyle = (start[1]&CON_CHARMASK); - start+=2; - } - else if ((start[1]&CON_CHARMASK) == 'P') - { //hexen2 style plaque. - int lines, len; - start+=2; - SCR_CenterPrintBreaks(start, &lines, &len); - x = rect.x+(rect.width-len*8)/2; - Draw_TextBox(x-6, y-8, len-1, lines); - } + if (p->flags & CPRINT_BACKGROUND) + { //hexen2 style plaque. +// int lines, len; +// SCR_CenterPrintBreaks(start, &lines, &len); +// x = rect.x+(rect.width-len*8)/2; +// Draw_TextBox(x-6, y-8, len-1, lines); } - do + if (p->flags & CPRINT_TALIGN) + y = top; + else if (p->flags & CPRINT_BALIGN) + y = bottom - Font_CharHeight()*linecount; + else if (p->flags & CPRINT_OBITUARTY) + //'obituary' messages appear at the bottom of the screen + y = (bottom-top - Font_CharHeight()*linecount) * 0.65 + top; + else if (p->flags & CPRINT_TYPEWRITER) + Font_BeginString(font_conchar, 48, rect->y, &y, &top); + else { - // scan the width of the line - for (l=0 ; l<=screenwidth ; l++) - if ((start[l]&CON_CHARMASK) == '\n' || !(start[l]&CON_CHARMASK)) - break; - if (l == screenwidth+1) - { - while(l > 0 && (start[l-1]&CON_CHARMASK)>' ' && (start[l-1]&CON_CHARMASK) != ' '+128) - { - l--; - } + if (linecount <= 4) + { + //small messages appear above and away from the crosshair + y = (bottom-top - Font_CharHeight()*linecount) * 0.35 + top; } - x = rect.x + (rect.width - l*8)/2+4; - for (j=0 ; jflags & CPRINT_RALIGN) + { + x = right; + for (str = line_start[l]; str < line_end[l]; str++) + x -= Font_CharWidth(*str); + } + else if (p->flags & CPRINT_LALIGN) + x = left; + else + { + x = 0; + for (str = line_start[l]; str < line_end[l]; str++) + x += Font_CharWidth(*str); + x = (right + left - x)/2; + } + + for (str = line_start[l]; str < line_end[l]; str++) { - switch(telejanostyle) - { - case 'O': - Draw_ColouredCharacter (x, y+vid.height/2, start[j]); - break; - default: - Draw_ColouredCharacter (x, y, start[j]); - } if (!remaining--) - return; + { + l = linecount-1; + break; + } + x = Font_DrawChar(x, y, *str); } - - y += 8; - - start+=l; -// for (l=0 ; l<40 && *start && *start != '\n'; l++) - // start++; - - if (!(*start&CON_CHARMASK)) - break; - else if ((*start&CON_CHARMASK) == '\n'||!l) - start++; // skip the \n - } while (1); + } + Font_EndString(font_conchar); } void SCR_CheckDrawCenterString (void) { extern qboolean sb_showscores; int pnum; + cprint_t *p; + vrect_t rect; for (pnum = 0; pnum < cl.splitclients; pnum++) { - if (scr_center_lines[pnum] > scr_erase_lines[pnum]) - scr_erase_lines[pnum] = scr_center_lines[pnum]; + p = &scr_centerprint[pnum]; - scr_centertime_off[pnum] -= host_frametime; + p->time_off -= host_frametime; if (key_dest != key_game) //don't let progs guis/centerprints interfere with the game menu continue; @@ -541,13 +538,40 @@ extern qboolean sb_showscores; if (sb_showscores) //this was annoying continue; - if (scr_centertime_off[pnum] <= 0 && !cl.intermission && (scr_centerstring[pnum][0]&255) != '/' && (scr_centerstring[pnum][1]&255) != 'P') + if (p->time_off <= 0 && !cl.intermission && !(p->flags & CPRINT_PERSIST)) continue; //'/P' prefix doesn't time out - SCR_DrawCenterString (pnum); + SCR_VRectForPlayer(&rect, pnum); + SCR_DrawCenterString(&rect, p); } } +void SCR_DrawCursor(int prydoncursornum) +{ + extern cvar_t cl_cursor, cl_cursorbias, cl_cursorsize; + extern int mousecursor_x, mousecursor_y; + mpic_t *p; + if (!*cl_cursor.string || prydoncursornum>1) + p = Draw_SafeCachePic(va("gfx/prydoncursor%03i.lmp", prydoncursornum)); + else + p = Draw_SafeCachePic(cl_cursor.string); + if (p) + { + Draw_ImageColours(1, 1, 1, 1); + Draw_Image(mousecursor_x-cl_cursorbias.value, mousecursor_y-cl_cursorbias.value, cl_cursorsize.value, cl_cursorsize.value, 0, 0, 1, 1, p); +// Draw_TransPic(mousecursor_x-4, mousecursor_y-4, p); + } + else + { + int x, y; + Font_BeginString(font_conchar, mousecursor_x, mousecursor_y, &x, &y); + x -= Font_CharWidth('+' | 0xe000 | CON_WHITEMASK)/2; + y -= Font_CharHeight()/2; + Font_DrawChar(x, y, '+' | 0xe000 | CON_WHITEMASK); + Font_EndString(font_conchar); + } + +} //////////////////////////////////////////////////////////////// //TEI_SHOWLMP2 (not 3) @@ -637,7 +661,7 @@ void SCR_ShowPics_Draw(void) p = Draw_SafeCachePic(sp->picname); if (!p) continue; - Draw_Pic(x, y, p); + Draw_ScalePic(x, y, p->width, p->height, p); } } @@ -647,7 +671,7 @@ void SCR_ShowPic_Clear(void) int pnum; for (pnum = 0; pnum < MAX_SPLITS; pnum++) - *scr_centerstring[pnum] = '\0'; + scr_centerprint[pnum].charcount = 0; while((sp = showpics)) { @@ -975,7 +999,7 @@ void SCR_CrosshairPosition(int pnum, int *x, int *y) vrect_t rect; SCR_VRectForPlayer(&rect, pnum); - if (cl.worldmodel && crosshaircorrect.value) + if (cl.worldmodel && crosshaircorrect.ival) { float adj; trace_t tr; @@ -1093,7 +1117,7 @@ void SCR_DrawTurtle (void) { static int count; - if (!scr_showturtle.value || !scr_turtle) + if (!scr_showturtle.ival || !scr_turtle) return; if (host_frametime <= 1.0/scr_turtlefps.value) @@ -1106,7 +1130,7 @@ void SCR_DrawTurtle (void) if (count < 3) return; - Draw_Pic (scr_vrect.x, scr_vrect.y, scr_turtle); + Draw_ScalePic (scr_vrect.x, scr_vrect.y, 64, 64, scr_turtle); } /* @@ -1121,17 +1145,28 @@ void SCR_DrawNet (void) if (cls.demoplayback || !scr_net) return; - Draw_Pic (scr_vrect.x+64, scr_vrect.y, scr_net); + Draw_ScalePic (scr_vrect.x+64, scr_vrect.y, 64, 64, scr_net); } void SCR_StringXY(char *str, float x, float y) { - if (x < 0) - x = vid.width + x*strlen(str)*8; - if (y < 0) - y = vid.height - sb_lines + y*8; + char *s2; + int px, py; - Draw_String(x, y, str); + Font_BeginString(font_conchar, ((x<0)?vid.width:x), ((y<0)?vid.height - sb_lines:y), &px, &py); + + if (x < 0) + { + for (s2 = str; *s2; s2++) + px -= Font_CharWidth(*s2); + } + + if (y < 0) + py += y*Font_CharHeight(); + + while (*str) + px = Font_DrawChar(px, py, CON_WHITEMASK|*str++); + Font_EndString(font_conchar); } void SCR_DrawFPS (void) @@ -1141,11 +1176,13 @@ void SCR_DrawFPS (void) double t; extern int fps_count; static float lastfps; + static float deviationtimes[64]; + static int deviationframe; char str[80]; - int sfps; + int sfps, frame; qboolean usemsecs = false; - if (!show_fps.value) + if (!show_fps.ival) return; t = Sys_DoubleTime(); @@ -1156,7 +1193,7 @@ void SCR_DrawFPS (void) lastframetime = t; } - sfps = show_fps.value; + sfps = show_fps.ival; if (sfps < 0) { sfps = -sfps; @@ -1185,12 +1222,34 @@ void SCR_DrawFPS (void) lastfps = 1/host_frametime; lastframetime = t; break; -#ifdef RGLQUAKE +#ifdef GLQUAKE case 5: if (qrenderer == QR_OPENGL) - GLR_FrameTimeGraph((int)(1000.0*host_frametime)); + GLR_FrameTimeGraph((int)(1000.0*1.5*host_frametime)); break; #endif + case 6: + { + float mean, deviation; + deviationtimes[deviationframe++&63] = host_frametime*1000; + mean = 0; + for (frame = 0; frame < 64; frame++) + { + mean += deviationtimes[frame]; + } + mean /= 64; + deviation = 0; + for (frame = 0; frame < 64; frame++) + { + deviation += (deviationtimes[frame] - mean)*(deviationtimes[frame] - mean); + } + deviation /= 64; + deviation = sqrt(deviation); + + + SCR_StringXY(va("%f deviation", deviation), show_fps_x.value, show_fps_y.value-8); + } + break; } if (usemsecs) @@ -1207,14 +1266,24 @@ void SCR_DrawUPS (void) double t; static float lastups; char str[80]; + float *vel; + int track; - if (!show_speed.value) + if (!show_speed.ival) return; t = Sys_DoubleTime(); if ((t - lastupstime) >= 1.0/20) { - lastups = sqrt((cl.simvel[0][0]*cl.simvel[0][0]) + (cl.simvel[0][1]*cl.simvel[0][1])); + if (cl.spectator) + track = Cam_TrackNum(0); + else + track = -1; + if (track != -1) + vel = cl.frames[cl.validsequence&UPDATE_MASK].playerstate[track].velocity; + else + vel = cl.simvel[0]; + lastups = sqrt((vel[0]*vel[0]) + (vel[1]*vel[1])); lastupstime = t; } @@ -1228,7 +1297,7 @@ void SCR_DrawClock(void) time_t long_time; char str[16]; - if (!show_clock.value) + if (!show_clock.ival) return; time( &long_time ); @@ -1247,7 +1316,7 @@ void SCR_DrawGameClock(void) int flags; float timelimit; - if (!show_gameclock.value) + if (!show_gameclock.ival) return; flags = (show_gameclock.value-1); @@ -1285,7 +1354,7 @@ void SCR_DrawPause (void) { mpic_t *pic; - if (!scr_showpause.value) // turn off for screenshots + if (!scr_showpause.ival) // turn off for screenshots return; if (!cl.paused) @@ -1294,11 +1363,11 @@ void SCR_DrawPause (void) pic = Draw_SafeCachePic ("gfx/pause.lmp"); if (pic) { - Draw_Pic ( (vid.width - pic->width)/2, - (vid.height - 48 - pic->height)/2, pic); + Draw_ScalePic ( (vid.width - pic->width)/2, + (vid.height - 48 - pic->height)/2, pic->width, pic->height, pic); } else - Draw_String((vid.width-strlen("Paused")*8)/2, (vid.height-8)/2, "Paused"); + Draw_FunString((vid.width-strlen("Paused")*8)/2, (vid.height-8)/2, "Paused"); } @@ -1342,7 +1411,7 @@ void SCR_DrawLoading (void) { x = (vid.width - pic->width)/2; y = (vid.height - 48 - pic->height)/2; - Draw_Pic (x, y, pic); + Draw_ScalePic (x, y, pic->width, pic->height, pic); x = (vid.width/2) - 96; y += pic->height + 8; } @@ -1351,7 +1420,7 @@ void SCR_DrawLoading (void) x = (vid.width/2) - 96; y = (vid.height/2) - 8; - Draw_String((vid.width-7*8)/2, y-16, "Loading"); + Draw_FunString((vid.width-7*8)/2, y-16, "Loading"); } if (!total_loading_size) @@ -1370,7 +1439,7 @@ void SCR_DrawLoading (void) Draw_FillRGB(x+sizex, y, 192-sizex, 16, 1.0, 0.0, 0.0); } - Draw_String(x+8, y+4, va("Loading %s... %i%%", + Draw_FunString(x+8, y+4, va("Loading %s... %i%%", (loading_stage == LS_SERVER) ? "server" : "client", current_loading_size * 100 / total_loading_size)); @@ -1388,7 +1457,7 @@ void SCR_DrawLoading (void) return; offset = (vid.width - pic->width)/2; - Draw_TransPic (offset , 0, pic); + Draw_ScalePic (offset, 0, pic->width, pic->height, pic); if (loading_stage == LS_NONE) return; @@ -1431,13 +1500,13 @@ void SCR_DrawLoading (void) CL_GetDownloadSizes(&fcount, &tsize, &sizeextra); //downloading files? if (cls.downloadmethod) - Draw_String(x+8, y+4, va("Downloading %s... %i%%", + Draw_FunString(x+8, y+4, va("Downloading %s... %i%%", cls.downloadlocalname, cls.downloadpercent)); if (tsize > 1024*1024*16) { - Draw_String(x+8, y+8+4, va("%5ukbps %8umb%s remaining (%i files)", + Draw_FunString(x+8, y+8+4, va("%5ukbps %8umb%s remaining (%i files)", (unsigned int)(CL_DownloadRate()/1000.0f), tsize/(1024*1024), sizeextra?"+":"", @@ -1445,7 +1514,7 @@ void SCR_DrawLoading (void) } else { - Draw_String(x+8, y+8+4, va("%5ukbps %8ukb%s remaining (%i files)", + Draw_FunString(x+8, y+8+4, va("%5ukbps %8ukb%s remaining (%i files)", (unsigned int)(CL_DownloadRate()/1000.0f), tsize/1024, sizeextra?"+":"", @@ -1464,7 +1533,7 @@ void SCR_DrawLoading (void) dots[1] = '.'; dots[2] = '.'; dots[(int)realtime & 3] = 0; - Draw_String(x, y+4, va("Connecting to: %s%s", s, dots)); + Draw_FunString(x, y+4, va("Connecting to: %s%s", s, dots)); } } @@ -1496,6 +1565,8 @@ void SCR_EndLoadingPlaque (void) scr_disabled_for_loading = false; *levelshotname = '\0'; + scr_drawloading = false; + loading_stage = 0; } void SCR_ImageName (char *mapname) @@ -1503,7 +1574,7 @@ void SCR_ImageName (char *mapname) strcpy(levelshotname, "levelshots/"); COM_FileBase(mapname, levelshotname + strlen(levelshotname), sizeof(levelshotname)-strlen(levelshotname)); -#ifdef RGLQUAKE +#ifdef GLQUAKE if (qrenderer == QR_OPENGL) { if (!Draw_SafeCachePic (levelshotname)) @@ -1520,7 +1591,7 @@ void SCR_ImageName (char *mapname) scr_disabled_for_loading = false; scr_drawloading = true; - GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + GL_BeginRendering (); SCR_DrawLoading(); SCR_SetUpToDrawConsole(); SCR_DrawConsole(!!*levelshotname); @@ -1549,29 +1620,12 @@ void SCR_SetUpToDrawConsole (void) #endif Con_CheckResize (); - scr_con_forcedraw = false; - if (scr_drawloading) return; // never a console with loading plaque // decide on the height of the console if (!scr_disabled_for_loading) { - /*if (cls.state != ca_active && !Media_PlayingFullScreen() - #ifdef TEXTEDITOR - && !editoractive - #endif - #ifdef VM_UI - && !UI_MenuState() - #endif - ) - { - scr_conlines = vid.height; // full screen - scr_con_current = scr_conlines; - scr_con_forcedraw = true; - } - else */ - scr_con_forcedraw = false; if ((key_dest == key_console || key_dest == key_game) && !cl.sendprespawn && cl.worldmodel && cl.worldmodel->needload) Con_ForceActiveNow(); else if (key_dest == key_console || scr_chatmode) @@ -1707,6 +1761,7 @@ qboolean SCR_ScreenShot (char *filename) ext = COM_FileExtension(filename); buffer = VID_GetRGBInfo(MAX_PREPAD, &truewidth, &trueheight); +#pragma message("Need to ensure that the various image writing routines can cope with ((width|height)&3") if (!buffer) return false; @@ -1900,7 +1955,7 @@ qboolean SCR_RSShot (void) char st[80]; time_t now; - if (!scr_allowsnap.value) + if (!scr_allowsnap.ival) return false; if (CL_IsUploading()) @@ -1995,74 +2050,6 @@ qboolean SCR_RSShot (void) //============================================================================= -//============================================================================= - -char *scr_notifystring; -qboolean scr_drawdialog; - -void SCR_DrawNotifyString (void) -{ - char *start; - int l; - int j; - int x, y; - - start = scr_notifystring; - - y = vid.height*0.35; - - do - { - // scan the width of the line - for (l=0 ; l<40 ; l++) - if (start[l] == '\n' || !start[l]) - break; - x = (vid.width - l*8)/2; - for (j=0 ; j 0) { @@ -2159,30 +2146,12 @@ void SCR_DrawTwoDimensional(int uimenu, qboolean nohud) // // draw any areas not covered by the refresh // -#ifdef RGLQUAKE +#ifdef GLQUAKE if (r_netgraph.value && qrenderer == QR_OPENGL) GLR_NetGraph (); #endif - if (scr_drawdialog) - { - if (!nohud) - { -#ifdef PLUGINS - Plug_SBar (); -#else - if (Sbar_ShouldDraw()) - { - Sbar_Draw (); - Sbar_DrawScoreboard (); - } -#endif - } - SCR_ShowPics_Draw(); - Draw_FadeScreen (); - SCR_DrawNotifyString (); - } - else if (scr_drawloading || loading_stage) + if (scr_drawloading || loading_stage) { SCR_DrawLoading(); @@ -2241,10 +2210,6 @@ void SCR_DrawTwoDimensional(int uimenu, qboolean nohud) else SCR_DrawFPS (); SCR_CheckDrawCenterString (); -#ifdef RGLQUAKE - if (qrenderer == QR_OPENGL) - qglTexEnvi ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); -#endif } #ifdef TEXTEDITOR @@ -2252,12 +2217,16 @@ void SCR_DrawTwoDimensional(int uimenu, qboolean nohud) Editor_Draw(); #endif - SCR_DrawConsole (false); + if (key_dest != key_console) + SCR_DrawConsole (false); M_Draw (uimenu); #ifdef MENU_DAT MP_Draw(); #endif + + if (key_dest == key_console) + SCR_DrawConsole (false); RSpeedEnd(RSPEED_2D); } diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index 26f0eb8a..ed4437ac 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -548,7 +548,7 @@ void CL_AddBeam (int tent, int ent, vec3_t start, vec3_t end) //fixme: use TE_ n if (etype >= 0 && cls.state == ca_active && etype != P_INVALID) { - if (cl_beam_trace.value) + if (cl_beam_trace.ival) { VectorSubtract(end, start, normal); VectorNormalize(normal); @@ -933,7 +933,7 @@ void CL_ParseTEnt (void) S_StartSound (-2, 0, cl_sfx_r_exp3, pos, 1, 1); // sprite - if (cl_expsprite.value) // temp hopefully + if (cl_expsprite.ival) // temp hopefully { explosion_t *ex = CL_AllocExplosion (); VectorCopy (pos, ex->origin); @@ -973,7 +973,7 @@ void CL_ParseTEnt (void) S_StartSound (-2, 0, cl_sfx_r_exp3, pos, 1, 1); // sprite - if (cl_expsprite.value && !nqprot) // temp hopefully + if (cl_expsprite.ival && !nqprot) // temp hopefully { explosion_t *ex = CL_AllocExplosion (); VectorCopy (pos, ex->origin); @@ -2532,7 +2532,7 @@ void CLQ2_ParseTEnt (void) VectorCopy (pos, ex->origin); ex->flags = Q2RF_FULLBRIGHT; ex->start = cl.q2frame.servertime - 100; - CL_NewDlightRGB(0, pos[0], pos[1], pos[2], 350, 0.5, 0.2, 0.1, 0); + CL_NewDlightRGB(0, pos, 350, 0.5, 0.2, 0.1, 0); P_RunParticleEffectTypeString(pos, NULL, 1, "te_muzzleflash"); break; case CRTE_BLUE_MUZZLEFLASH: @@ -2541,7 +2541,7 @@ void CLQ2_ParseTEnt (void) VectorCopy (pos, ex->origin); ex->flags = Q2RF_FULLBRIGHT; ex->start = cl.q2frame.servertime - 100; - CL_NewDlightRGB(0, pos[0], pos[1], pos[2], 350, 0.5, 0.2, 0.1, 0); + CL_NewDlightRGB(0, pos, 350, 0.5, 0.2, 0.1, 0); P_RunParticleEffectTypeString(pos, NULL, 1, "te_blue_muzzleflash"); break; case CRTE_SMART_MUZZLEFLASH: @@ -2550,7 +2550,7 @@ void CLQ2_ParseTEnt (void) VectorCopy (pos, ex->origin); ex->flags = Q2RF_FULLBRIGHT; ex->start = cl.q2frame.servertime - 100; - CL_NewDlightRGB(0, pos[0], pos[1], pos[2], 350, 0.5, 0.2, 0, 0.2); + CL_NewDlightRGB(0, pos, 350, 0.5, 0.2, 0, 0.2); P_RunParticleEffectTypeString(pos, NULL, 1, "te_smart_muzzleflash"); break; case CRTE_LEADERFIELD: @@ -2561,7 +2561,7 @@ void CLQ2_ParseTEnt (void) VectorCopy (pos, ex->origin); ex->flags = Q2RF_FULLBRIGHT; ex->start = cl.q2frame.servertime - 100; - CL_NewDlightRGB(0, pos[0], pos[1], pos[2], 350, 0.5, 0.2, 0, 0.2); + CL_NewDlightRGB(0, pos, 350, 0.5, 0.2, 0, 0.2); P_RunParticleEffectTypeString(pos, NULL, 1, "te_deathfield"); break; case CRTE_BLASTERBEAM: @@ -2642,10 +2642,13 @@ void CL_UpdateBeams (void) if (b->endtime < cl.time) { - P_DelinkTrailstate(&b->trailstate); - P_DelinkTrailstate(&b->emitstate); - b->model = NULL; - continue; + if (!sv.paused) + { /*don't let lightning decay while paused*/ + P_DelinkTrailstate(&b->trailstate); + P_DelinkTrailstate(&b->emitstate); + b->model = NULL; + continue; + } } lastrunningbeam = bnum; @@ -2709,7 +2712,7 @@ void CL_UpdateBeams (void) org[2] += 16; VectorAdd (org, fwd, b->end); - if (cl_beam_trace.value) + if (cl_beam_trace.ival) { vec3_t normal; VectorMA(org, len+4, ang, fwd); @@ -2760,7 +2763,7 @@ void CL_UpdateBeams (void) pitch += 360; } - if (ruleset_allow_particle_lightning.value) + if (ruleset_allow_particle_lightning.ival) if (b->particleeffect >= 0 && !P_ParticleTrail(b->start, b->end, b->particleeffect, &b->trailstate)) continue; diff --git a/engine/client/cl_ui.c b/engine/client/cl_ui.c index 3ee6240a..ec82d515 100644 --- a/engine/client/cl_ui.c +++ b/engine/client/cl_ui.c @@ -7,9 +7,6 @@ int keycatcher; - -void GLDraw_ShaderImage (int x, int y, int w, int h, float s1, float t1, float s2, float t2, struct shader_s *pic); - #define MAX_TOKENLENGTH 1024 typedef struct pc_token_s { @@ -38,8 +35,8 @@ typedef struct { char *defines; int numdefines; } script_t; -script_t *scripts; -int maxscripts; +static script_t *scripts; +static int maxscripts; #define Q3SCRIPTPUNCTUATION "(,{})(\':;=!><&|+-\"" void StripCSyntax (char *s) { @@ -123,7 +120,7 @@ int Script_Read(int handle, struct pc_token_s *token) if (sc->originalfilestack[sc->stackdepth]) BZ_Free(sc->originalfilestack[sc->stackdepth]); - sc->filestack[sc->stackdepth] = sc->originalfilestack[sc->stackdepth] = COM_LoadMallocFile(com_token); + sc->filestack[sc->stackdepth] = sc->originalfilestack[sc->stackdepth] = FS_LoadMallocFile(com_token); Q_strncpyz(sc->filename[sc->stackdepth], com_token, MAX_QPATH); sc->stackdepth++; continue; @@ -217,7 +214,7 @@ int Script_LoadFile(char *filename) sc = scripts+i; memset(sc, 0, sizeof(*sc)); - sc->filestack[0] = sc->originalfilestack[0] = COM_LoadMallocFile(filename); + sc->filestack[0] = sc->originalfilestack[0] = FS_LoadMallocFile(filename); Q_strncpyz(sc->filename[sc->stackdepth], filename, MAX_QPATH); sc->stackdepth = 1; @@ -274,7 +271,7 @@ void Script_Get_File_And_Line(int handle, char *filename, int *line) -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h"//hack #else typedef float m3by3_t[3][3]; @@ -284,8 +281,6 @@ static vm_t *uivm; static char *scr_centerstring; -static int ox, oy; - void GLDraw_Image(float x, float y, float w, float h, float s1, float t1, float s2, float t2, qpic_t *pic); void SWDraw_Image (float xp, float yp, float wp, float hp, float s1, float t1, float s2, float t2, qpic_t *pic); char *Get_Q2ConfigString(int i); @@ -307,7 +302,7 @@ extern shader_t r_shaders[]; #define VM_TOSHANDLE(a) (a?a-r_shaders+1:0) -typedef struct q3refEntity_s { +struct q3refEntity_s { refEntityType_t reType; int renderfx; @@ -340,12 +335,14 @@ typedef struct q3refEntity_s { // extra sprite information float radius; float rotation; -} q3refEntity_t; - -#define Q2RF_VIEWERMODEL 2 // don't draw through eyes, only mirrors -#define Q2RF_WEAPONMODEL 4 // only draw through eyes -#define Q2RF_DEPTHHACK 16 // for view weapon Z crunching +}; +struct q3polyvert_s +{ + vec3_t org; + vec2_t tcoord; + qbyte colours[4]; +}; #define Q3RF_MINLIGHT 1 #define Q3RF_THIRD_PERSON 2 // don't draw through eyes, only mirrors (player bodies, chat sprites) @@ -416,21 +413,76 @@ void VQ3_AddEntity(const q3refEntity_t *q3) // if (ent.shaderRGBAf[3] <= 0) // return; -#ifdef Q3SHADERS ent.forcedshader = VM_FROMSHANDLE(q3->customShader); ent.shaderTime = q3->shaderTime; -#endif if (q3->renderfx & Q3RF_FIRST_PERSON) ent.flags |= Q2RF_WEAPONMODEL; if (q3->renderfx & Q3RF_DEPTHHACK) ent.flags |= Q2RF_DEPTHHACK; if (q3->renderfx & Q3RF_THIRD_PERSON) - ent.flags |= Q2RF_VIEWERMODEL; + ent.flags |= Q2RF_EXTERNALMODEL; + if (q3->renderfx & Q3RF_NOSHADOW) + ent.flags |= RF_NOSHADOW; + VectorCopy(q3->origin, ent.origin); VectorCopy(q3->oldorigin, ent.oldorigin); V_AddAxisEntity(&ent); } +void VQ3_AddPoly(shader_t *s, int num, q3polyvert_t *verts) +{ + unsigned int v; + scenetris_t *t; + /*reuse the previous trigroup if its the same shader*/ + if (cl_numstris && cl_stris[cl_numstris-1].shader == s) + t = &cl_stris[cl_numstris-1]; + else + { + if (cl_numstris == cl_maxstris) + { + cl_maxstris += 8; + cl_stris = BZ_Realloc(cl_stris, sizeof(*cl_stris)*cl_maxstris); + } + t = &cl_stris[cl_numstris++]; + t->shader = s; + t->numidx = 0; + t->numvert = 0; + t->firstidx = cl_numstrisidx; + t->firstvert = cl_numstrisvert; + } + + if (cl_maxstrisvert < cl_numstrisvert+num) + { + cl_maxstrisvert = cl_numstrisvert+num + 64; + cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(vec3_t)*cl_maxstrisvert); + cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(vec2_t)*cl_maxstrisvert); + cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(vec4_t)*cl_maxstrisvert); + } + if (cl_maxstrisidx < cl_numstrisidx+(num-2)*3) + { + cl_maxstrisidx = cl_numstrisidx+(num-2)*3 + 64; + cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx); + } + + for (v = 0; v < num; v++) + { + VectorCopy(verts[v].org, cl_strisvertv[cl_numstrisvert+v]); + Vector2Copy(verts[v].tcoord, cl_strisvertt[cl_numstrisvert+v]); + Vector4Scale(verts[v].colours, (1/255.0f), cl_strisvertc[cl_numstrisvert+v]); + } + for (v = 2; v < num; v++) + { + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+(v-1) - t->firstvert; + cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+v - t->firstvert; + } + + t->numvert += num; + t->numidx += (num-2)*3; + cl_numstrisvert += num; + //we already increased idx +} + int VM_LerpTag(void *out, model_t *model, int f1, int f2, float l2, char *tagname) { int tagnum; @@ -496,7 +548,7 @@ int VM_LerpTag(void *out, model_t *model, int f1, int f2, float l2, char *tagnam #define MAX_RENDER_STRINGS 8 #define MAX_RENDER_STRING_LENGTH 32 -typedef struct q3refdef_s { +struct q3refdef_s { int x, y, width, height; float fov_x, fov_y; vec3_t vieworg; @@ -512,10 +564,11 @@ typedef struct q3refdef_s { // text messages for deform text shaders char text[MAX_RENDER_STRINGS][MAX_RENDER_STRING_LENGTH]; -} q3refdef_t; +}; void VQ3_RenderView(const q3refdef_t *ref) { + extern cvar_t r_torch; VectorCopy(ref->vieworg, r_refdef.vieworg); r_refdef.viewangles[0] = -(atan2(ref->viewaxis[0][2], sqrt(ref->viewaxis[0][1]*ref->viewaxis[0][1]+ref->viewaxis[0][0]*ref->viewaxis[0][0])) * 180 / M_PI); r_refdef.viewangles[1] = (atan2(ref->viewaxis[0][1], ref->viewaxis[0][0]) * 180 / M_PI); @@ -534,8 +587,19 @@ void VQ3_RenderView(const q3refdef_t *ref) r_refdef.useperspective = true; r_refdef.currentplayernum = -1; + if (r_torch.ival) + { + dlight_t *dl; + dl = CL_NewDlightRGB(0, ref->vieworg, 300, r_torch.ival, 0.05, 0.05, 0.02); + dl->flags |= LFLAG_SHADOWMAP|LFLAG_ALLOW_FLASH; + dl->fov = 60; + VectorCopy(ref->viewaxis[0], dl->axis[0]); + VectorCopy(ref->viewaxis[1], dl->axis[1]); + VectorCopy(ref->viewaxis[2], dl->axis[2]); + } + memcpy(cl.q2frame.areabits, ref->areamask, sizeof(cl.q2frame.areabits)); -#ifdef RGLQUAKE +#ifdef GLQUAKE if (qrenderer == QR_OPENGL) { gl_ztrickdisabled|=16; @@ -544,7 +608,7 @@ void VQ3_RenderView(const q3refdef_t *ref) } #endif R_RenderView(); -#ifdef RGLQUAKE +#ifdef GLQUAKE if (qrenderer == QR_OPENGL) { gl_ztrickdisabled&=~16; @@ -554,7 +618,7 @@ void VQ3_RenderView(const q3refdef_t *ref) } #endif -#ifdef RGLQUAKE +#ifdef GLQUAKE if (qrenderer == QR_OPENGL) { qglDisable(GL_ALPHA_TEST); @@ -641,10 +705,10 @@ int UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const int *arg) switch((uiImport_t)fn) { case UI_ERROR: - Con_Printf("%s", VM_POINTER(arg[0])); + Con_Printf("%s", (char*)VM_POINTER(arg[0])); break; case UI_PRINT: - Con_Printf("%s", VM_POINTER(arg[0])); + Con_Printf("%s", (char*)VM_POINTER(arg[0])); break; case UI_MILLISECONDS: @@ -669,7 +733,7 @@ int UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const int *arg) cvar_t *var; if (!strcmp(VM_POINTER(arg[0]), "fs_game")) { - Cbuf_AddText(va("gamedir %s\nui_restart\n", VM_POINTER(arg[1])), RESTRICT_SERVER); + Cbuf_AddText(va("gamedir %s\nui_restart\n", (char*)VM_POINTER(arg[1])), RESTRICT_SERVER); } else { @@ -726,7 +790,7 @@ int UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const int *arg) break; case UI_CMD_EXECUTETEXT: - if (!strncmp(VM_POINTER(arg[1]), "ping ", 5)) + if (!strncmp((char*)VM_POINTER(arg[1]), "ping ", 5)) { int i; for (i = 0; i < MAX_PINGREQUESTS; i++) @@ -821,7 +885,10 @@ int UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const int *arg) break; case UI_R_CLEARSCENE: //clear scene - cl_numvisedicts=0; + cl_numvisedicts = 0; + cl_numstrisidx = 0; + cl_numstrisvert = 0; + cl_numstris = 0; break; case UI_R_ADDREFENTITYTOSCENE: //add ent to scene VQ3_AddEntity(VM_POINTER(arg[0])); @@ -833,7 +900,6 @@ int UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const int *arg) break; case UI_R_SETCOLOR: //setcolour float* - if (Draw_ImageColours) { float *fl =VM_POINTER(arg[0]); if (!fl) @@ -844,13 +910,7 @@ int UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const int *arg) break; case UI_R_DRAWSTRETCHPIC: -// qglDisable(GL_ALPHA_TEST); -// qglEnable(GL_BLEND); -// GL_TexEnv(GL_MODULATE); - if (qrenderer == QR_OPENGL) - GLDraw_ShaderImage(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), VM_FROMSHANDLE(arg[8])); -// else -// Draw_Image(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), (mpic_t *)VM_LONG(arg[8])); + Draw_Image(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), (mpic_t *)VM_LONG(arg[8])); break; case UI_CM_LERPTAG: //Lerp tag... @@ -863,7 +923,7 @@ int UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const int *arg) case UI_S_REGISTERSOUND: { sfx_t *sfx; - sfx = S_PrecacheSound(va("../%s", VM_POINTER(arg[0]))); + sfx = S_PrecacheSound(va("../%s", (char*)VM_POINTER(arg[0]))); if (sfx) VM_LONG(ret) = VM_TOSTRCACHE(arg[0]); //return handle is the parameter they just gave else @@ -936,6 +996,7 @@ int UI_SystemCallsEx(void *offset, unsigned int mask, int fn, const int *arg) case UI_GETCLIENTSTATE: //get client state //fixme: we need to fill in a structure. + Con_Printf("ui_getclientstate\n"); break; case UI_GETCONFIGSTRING: @@ -1429,10 +1490,7 @@ qboolean UI_KeyPress(int key, int unicode, qboolean down) Media_PlayFilm(""); } - if (cls.state) - VM_Call(uivm, UI_SET_ACTIVE_MENU, 2); - else - VM_Call(uivm, UI_SET_ACTIVE_MENU, 1); + UI_OpenMenu(); scr_conlines = 0; return true; @@ -1458,26 +1516,14 @@ qboolean UI_KeyPress(int key, int unicode, qboolean down) // return result; } -void UI_MousePosition(int xpos, int ypos) +qboolean UI_MousePosition(int xpos, int ypos) { - if (uivm && (ox != xpos || oy != ypos)) + if (uivm && (keycatcher&2)) { - if (xpos < 0) - xpos = 0; - if (ypos < 0) - ypos = 0; - if (xpos > vid.width) - xpos = vid.width; - if (ypos > vid.height) - ypos = vid.height; - ox=0;oy=0; - //force a cap - VM_Call(uivm, UI_MOUSE_EVENT, -32767, -32767); - VM_Call(uivm, UI_MOUSE_EVENT, (xpos-ox)*640/vid.width, (ypos-oy)*480/vid.height); - ox = xpos; - oy = ypos; - + VM_Call(uivm, UI_MOUSE_EVENT, (xpos)*640/(int)vid.width, (ypos)*480/(int)vid.height); + return true; } + return false; } void UI_Stop (void) @@ -1515,11 +1561,7 @@ void UI_Start (void) } VM_Call(uivm, UI_INIT); - VM_Call(uivm, UI_MOUSE_EVENT, -32767, -32767); - ox = 0; - oy = 0; - - VM_Call(uivm, UI_SET_ACTIVE_MENU, 1); + UI_OpenMenu(); } } @@ -1537,6 +1579,20 @@ void UI_Restart_f(void) } } +qboolean UI_OpenMenu(void) +{ + if (uivm) + { + if (cls.state) + VM_Call(uivm, UI_SET_ACTIVE_MENU, 2); + else + VM_Call(uivm, UI_SET_ACTIVE_MENU, 1); + key_dest = key_game; + return true; + } + return false; +} + qboolean UI_Command(void) { if (uivm) diff --git a/engine/client/clhl_game.c b/engine/client/clhl_game.c index 650af27b..43a6a67f 100644 --- a/engine/client/clhl_game.c +++ b/engine/client/clhl_game.c @@ -3,15 +3,27 @@ #ifdef HLCLIENT +//make shared +#ifndef QDECL + #ifdef _MSC_VER + #define QDECL _cdecl + #else + #define QDECL + #endif +#endif +struct hlcvar_s *QDECL GHL_CVarGetPointer(char *varname); + + + #define notimp(l) Con_Printf("halflife cl builtin not implemented on line %i\n", l) -//#define HLCL_API_VERSION 6 +#if HLCLIENT >= 1 +#define HLCL_API_VERSION HLCLIENT +#else #define HLCL_API_VERSION 7 +#endif -//make shared -struct hlcvar_s *GHL_CVarGetPointer(char *varname); - #define HLPIC model_t* @@ -111,104 +123,104 @@ typedef struct typedef struct { - HLPIC (*pic_load) (char *picname); - int (*pic_getnumframes) (HLPIC pic); - int (*pic_getheight) (HLPIC pic, int frame); - int (*pic_getwidth) (HLPIC pic, int frame); - void (*pic_select) (HLPIC pic, int r, int g, int b); - void (*pic_drawcuropaque) (int frame, int x, int y, void *loc); - void (*pic_drawcuralphatest) (int frame, int x, int y, void *loc); - void (*pic_drawcuradditive) (int frame, int x, int y, void *loc); - void (*pic_enablescissor) (int x, int y, int width, int height); - void (*pic_disablescissor) (void); - hlspriteinf_t *(*pic_parsepiclist) (char *filename, int *numparsed); + HLPIC (QDECL *pic_load) (char *picname); + int (QDECL *pic_getnumframes) (HLPIC pic); + int (QDECL *pic_getheight) (HLPIC pic, int frame); + int (QDECL *pic_getwidth) (HLPIC pic, int frame); + void (QDECL *pic_select) (HLPIC pic, int r, int g, int b); + void (QDECL *pic_drawcuropaque) (int frame, int x, int y, void *loc); + void (QDECL *pic_drawcuralphatest) (int frame, int x, int y, void *loc); + void (QDECL *pic_drawcuradditive) (int frame, int x, int y, void *loc); + void (QDECL *pic_enablescissor) (int x, int y, int width, int height); + void (QDECL *pic_disablescissor) (void); + hlspriteinf_t *(QDECL *pic_parsepiclist) (char *filename, int *numparsed); - void (*fillrgba) (int x, int y, int width, int height, int r, int g, int b, int a); - int (*getscreeninfo) (hlscreeninfo_t *info); - void (*setcrosshair) (HLPIC pic, hlsubrect_t rect, int r, int g, int b); //I worry about stuff like this + void (QDECL *fillrgba) (int x, int y, int width, int height, int r, int g, int b, int a); + int (QDECL *getscreeninfo) (hlscreeninfo_t *info); + void (QDECL *setcrosshair) (HLPIC pic, hlsubrect_t rect, int r, int g, int b); //I worry about stuff like this - int (*cvar_register) (char *name, char *defvalue, int flags); - float (*cvar_getfloat) (char *name); - char *(*cvar_getstring) (char *name); + struct hlcvar_s *(QDECL *cvar_register) (char *name, char *defvalue, int flags); + float (QDECL *cvar_getfloat) (char *name); + char *(QDECL *cvar_getstring) (char *name); - void (*cmd_register) (char *name, void (*func) (void)); - void (*hooknetmsg) (char *msgname, void *func); - void (*forwardcmd) (char *command); - void (*localcmd) (char *command); + void (QDECL *cmd_register) (char *name, void (*func) (void)); + void (QDECL *hooknetmsg) (char *msgname, void *func); + void (QDECL *forwardcmd) (char *command); + void (QDECL *localcmd) (char *command); - void (*getplayerinfo) (int entnum, hlplayerinfo_t *result); + void (QDECL *getplayerinfo) (int entnum, hlplayerinfo_t *result); - void (*startsound_name) (char *name, float vol); - void (*startsound_idx) (int idx, float vol); + void (QDECL *startsound_name) (char *name, float vol); + void (QDECL *startsound_idx) (int idx, float vol); - void (*anglevectors) (float *ina, float *outf, float *outr, float *outu); + void (QDECL *anglevectors) (float *ina, float *outf, float *outr, float *outu); - hlmsginfo_t *(*get_message_info) (char *name); //translated+scaled+etc intro stuff - int (*drawchar) (int x, int y, int charnum, int r, int g, int b); - int (*drawstring) (int x, int y, char *string); + hlmsginfo_t *(QDECL *get_message_info) (char *name); //translated+scaled+etc intro stuff + int (QDECL *drawchar) (int x, int y, int charnum, int r, int g, int b); + int (QDECL *drawstring) (int x, int y, char *string); #if HLCL_API_VERSION >= 7 - void (*settextcolour) (float r, float b, float g); + void (QDECL *settextcolour) (float r, float b, float g); #endif - void (*drawstring_getlen) (char *string, int *outlen, int *outheight); - void (*consoleprint) (char *str); - void (*centerprint) (char *str); + void (QDECL *drawstring_getlen) (char *string, int *outlen, int *outheight); + void (QDECL *consoleprint) (char *str); + void (QDECL *centerprint) (char *str); #if HLCL_API_VERSION >= 7 - int (*getwindowcenterx)(void); //yes, really, window center. for use with Get/SetCursorPos, the windows function. - int (*getwindowcentery)(void); //yes, really, window center. for use with Get/SetCursorPos, the windows function. - void (*getviewnangles)(float*ang); - void (*setviewnangles)(float*ang); - void (*getmaxclients)(float*ang); - void (*cvar_setvalue)(char *cvarname, char *value); + int (QDECL *getwindowcenterx)(void); //yes, really, window center. for use with Get/SetCursorPos, the windows function. + int (QDECL *getwindowcentery)(void); //yes, really, window center. for use with Get/SetCursorPos, the windows function. + void (QDECL *getviewnangles)(float*ang); + void (QDECL *setviewnangles)(float*ang); + void (QDECL *getmaxclients)(float*ang); + void (QDECL *cvar_setvalue)(char *cvarname, char *value); - int (*cmd_argc)(void); - char *(*cmd_argv)(int i); - void (*con_printf)(char *fmt, ...); - void (*con_dprintf)(char *fmt, ...); - void (*con_notificationprintf)(int pos, char *fmt, ...); - void (*con_notificationprintfex)(void *info, char *fmt, ...); //arg1 is of specific type - char *(*physkey)(char *key); - char *(*serverkey)(char *key); - float (*getclientmaxspeed)(void); - int (*checkparm)(char *str, char **next); - int (*keyevent)(int key, int down); - void (*getmousepos)(int *outx, int *outy); - int (*movetypeisnoclip)(void); - struct hlclent_s *(*getlocalplayer)(void); - struct hlclent_s *(*getviewent)(void); - struct hlclent_s *(*getentidx)(void); - float (*getlocaltime)(void); - void (*calcshake)(void); - void (*applyshake)(void); - int (*pointcontents)(float *point, float *truecon); - int (*waterentity)(float *point); - void (*traceline) (float *start, float *end, int flags, int hull, int forprediction); + int (QDECL *cmd_argc)(void); + char *(QDECL *cmd_argv)(int i); + void (QDECL *con_printf)(char *fmt, ...); + void (QDECL *con_dprintf)(char *fmt, ...); + void (QDECL *con_notificationprintf)(int pos, char *fmt, ...); + void (QDECL *con_notificationprintfex)(void *info, char *fmt, ...); //arg1 is of specific type + char *(QDECL *physkey)(char *key); + char *(QDECL *serverkey)(char *key); + float (QDECL *getclientmaxspeed)(void); + int (QDECL *checkparm)(char *str, char **next); + int (QDECL *keyevent)(int key, int down); + void (QDECL *getmousepos)(int *outx, int *outy); + int (QDECL *movetypeisnoclip)(void); + struct hlclent_s *(QDECL *getlocalplayer)(void); + struct hlclent_s *(QDECL *getviewent)(void); + struct hlclent_s *(QDECL *getentidx)(void); + float (QDECL *getlocaltime)(void); + void (QDECL *calcshake)(void); + void (QDECL *applyshake)(float *,float *,float); + int (QDECL *pointcontents)(float *point, float *truecon); + int (QDECL *waterentity)(float *point); + void (QDECL *traceline) (float *start, float *end, int flags, int hull, int forprediction); - model_t *(*loadmodel)(char *modelname, int *mdlindex); - int (*addrentity)(int type, void *ent); + model_t *(QDECL *loadmodel)(char *modelname, int *mdlindex); + int (QDECL *addrentity)(int type, void *ent); - model_t *(*modelfrompic) (HLPIC pic); - void (*soundatloc)(char*sound, float volume, float *org); + model_t *(QDECL *modelfrompic) (HLPIC pic); + void (QDECL *soundatloc)(char*sound, float volume, float *org); - unsigned short (*precacheevent)(int evtype, char *name); - void (*playevent)(int flags, struct hledict_s *ent, unsigned short evindex, float delay, float *origin, float *angles, float f1, float f2, int i1, int i2, int b1, int b2); - void (*weaponanimate)(int anim, int body); - float (*randfloat) (float minv, float maxv); - long (*randlong) (long minv, long maxv); - void (*hookevent) (char *name, void (*func)(struct hlevent_s *event)); - int (*con_isshown) (void); - char *(*getgamedir) (void); - struct hlcvar_s *(*cvar_find) (char *name); - char *(*lookupbinding) (char *command); - char *(*getlevelname) (void); - void (*getscreenfade) (struct hlsfade_s *fade); - void (*setscreenfade) (struct hlsfade_s *fade); - void *(*vgui_getpanel) (void); - void (*vgui_paintback) (int extents[4]); + unsigned short (QDECL *precacheevent)(int evtype, char *name); + void (QDECL *playevent)(int flags, struct hledict_s *ent, unsigned short evindex, float delay, float *origin, float *angles, float f1, float f2, int i1, int i2, int b1, int b2); + void (QDECL *weaponanimate)(int anim, int body); + float (QDECL *randfloat) (float minv, float maxv); + long (QDECL *randlong) (long minv, long maxv); + void (QDECL *hookevent) (char *name, void (*func)(struct hlevent_s *event)); + int (QDECL *con_isshown) (void); + char *(QDECL *getgamedir) (void); + struct hlcvar_s *(QDECL *cvar_find) (char *name); + char *(QDECL *lookupbinding) (char *command); + char *(QDECL *getlevelname) (void); + void (QDECL *getscreenfade) (struct hlsfade_s *fade); + void (QDECL *setscreenfade) (struct hlsfade_s *fade); + void *(QDECL *vgui_getpanel) (void); + void (QDECL *vgui_paintback) (int extents[4]); - void *(*loadfile) (char *path, int onhunk, int *length); - char *(*parsefile) (char *data, char *token); - void (*freefile) (void *file); + void *(QDECL *loadfile) (char *path, int onhunk, int *length); + char *(QDECL *parsefile) (char *data, char *token); + void (QDECL *freefile) (void *file); struct hl_tri_api_s { @@ -227,10 +239,10 @@ typedef struct } *eventapi; struct hl_demo_api_s { - int (*isrecording)(void); - int (*isplaying)(void); - int (*istimedemo)(void); - void (*writedata)(int size, void *data); + int (QDECL *isrecording)(void); + int (QDECL *isplaying)(void); + int (QDECL *istimedemo)(void); + void (QDECL *writedata)(int size, void *data); int sentinal; } *demoapi; @@ -245,22 +257,22 @@ typedef struct int sentinal; } *voiceapi; - int (*forcedspectator) (void); - model_t *(*loadmapsprite) (char *name); + int (QDECL *forcedspectator) (void); + model_t *(QDECL *loadmapsprite) (char *name); - void (*fs_addgamedir) (char *basedir, char *appname); - int (*expandfilename) (char *filename, char *outbuff, int outsize); + void (QDECL *fs_addgamedir) (char *basedir, char *appname); + int (QDECL *expandfilename) (char *filename, char *outbuff, int outsize); - char *(*player_key) (int pnum, char *key); - void (*player_setkey) (char *key, char *value); //wait, no pnum? + char *(QDECL *player_key) (int pnum, char *key); + void (QDECL *player_setkey) (char *key, char *value); //wait, no pnum? - qboolean (*getcdkey) (int playernum, char key[16]); + qboolean (QDECL *getcdkey) (int playernum, char key[16]); int trackerfromplayer; int playerfromtracker; - int (*sendcmd_unreliable) (char *cmd); - void (*getsysmousepos) (long *xandy); - void (*setsysmousepos) (int x, int y); - void (*setmouseenable) (qboolean enable); + int (QDECL *sendcmd_unreliable) (char *cmd); + void (QDECL *getsysmousepos) (long *xandy); + void (QDECL *setsysmousepos) (int x, int y); + void (QDECL *setmouseenable) (qboolean enable); #endif int sentinal; @@ -269,17 +281,17 @@ typedef struct typedef struct { - int (*HUD_VidInit) (void); - int (*HUD_Init) (void); - int (*HUD_Shutdown) (void); - int (*HUD_Redraw) (float maptime, int inintermission); - int (*HUD_UpdateClientData) (hllocalclientdata_t *localclientdata, float maptime); - int (*HUD_Reset) (void); + int (QDECL *HUD_VidInit) (void); + int (QDECL *HUD_Init) (void); + int (QDECL *HUD_Shutdown) (void); + int (QDECL *HUD_Redraw) (float maptime, int inintermission); + int (QDECL *HUD_UpdateClientData) (hllocalclientdata_t *localclientdata, float maptime); + int (QDECL *HUD_Reset) (void); #if HLCL_API_VERSION >= 7 - void (*CL_CreateMove) (float frametime, hlusercmd_t *cmd, int isplaying); - void (*IN_ActivateMouse) (void); - void (*IN_DeactivateMouse) (void); - void (*IN_MouseEvent) (int buttonmask); + void (QDECL *CL_CreateMove) (float frametime, hlusercmd_t *cmd, int isplaying); + void (QDECL *IN_ActivateMouse) (void); + void (QDECL *IN_DeactivateMouse) (void); + void (QDECL *IN_MouseEvent) (int buttonmask); #endif } CLHL_cgamefuncs_t; @@ -311,7 +323,7 @@ typedef struct typedef struct { char name[64]; - int (*hook) (char *name, int bufsize, void *bufdata); + int (QDECL *hook) (char *name, int bufsize, void *bufdata); } CLHL_UserMessages_t; CLHL_UserMessages_t usermsgs[256]; @@ -329,12 +341,12 @@ int hl_viewmodelsequencebody; -HLPIC CLGHL_pic_load (char *picname) +HLPIC QDECL CLGHL_pic_load (char *picname) { return Mod_ForName(picname, false); // return Draw_SafeCachePic(picname); } -int CLGHL_pic_getnumframes (HLPIC pic) +int QDECL CLGHL_pic_getnumframes (HLPIC pic) { if (pic) return pic->numframes; @@ -369,7 +381,7 @@ static mpic_t *getspritepic(HLPIC pic, int frame) return NULL; } -int CLGHL_pic_getheight (HLPIC pic, int frame) +int QDECL CLGHL_pic_getheight (HLPIC pic, int frame) { mspriteframe_t *pframe; @@ -379,7 +391,7 @@ int CLGHL_pic_getheight (HLPIC pic, int frame) return pframe->p.width; } -int CLGHL_pic_getwidth (HLPIC pic, int frame) +int QDECL CLGHL_pic_getwidth (HLPIC pic, int frame) { mspriteframe_t *pframe; @@ -389,12 +401,12 @@ int CLGHL_pic_getwidth (HLPIC pic, int frame) return pframe->p.height; } -void CLGHL_pic_select (HLPIC pic, int r, int g, int b) +void QDECL CLGHL_pic_select (HLPIC pic, int r, int g, int b) { selectedpic = pic; Draw_ImageColours(r/255.0f, g/255.0f, b/255.0f, 1); } -void CLGHL_pic_drawcuropaque (int frame, int x, int y, hlsubrect_t *loc) +void QDECL CLGHL_pic_drawcuropaque (int frame, int x, int y, hlsubrect_t *loc) { mpic_t *pic = getspritepic(selectedpic, frame); if (!pic) @@ -409,7 +421,7 @@ void CLGHL_pic_drawcuropaque (int frame, int x, int y, hlsubrect_t *loc) (float)loc->r/pic->width, (float)loc->b/pic->height, pic); } -void CLGHL_pic_drawcuralphtest (int frame, int x, int y, hlsubrect_t *loc) +void QDECL CLGHL_pic_drawcuralphtest (int frame, int x, int y, hlsubrect_t *loc) { mpic_t *pic = getspritepic(selectedpic, frame); if (!pic) @@ -423,7 +435,7 @@ void CLGHL_pic_drawcuralphtest (int frame, int x, int y, hlsubrect_t *loc) (float)loc->r/pic->width, (float)loc->b/pic->height, pic); } -void CLGHL_pic_drawcuradditive (int frame, int x, int y, hlsubrect_t *loc) +void QDECL CLGHL_pic_drawcuradditive (int frame, int x, int y, hlsubrect_t *loc) { mpic_t *pic = getspritepic(selectedpic, frame); if (!pic) @@ -452,13 +464,13 @@ void CLGHL_pic_drawcuradditive (int frame, int x, int y, hlsubrect_t *loc) } qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } -void CLGHL_pic_enablescissor (int x, int y, int width, int height) +void QDECL CLGHL_pic_enablescissor (int x, int y, int width, int height) { } -void CLGHL_pic_disablescissor (void) +void QDECL CLGHL_pic_disablescissor (void) { } -hlspriteinf_t *CLGHL_pic_parsepiclist (char *filename, int *numparsed) +hlspriteinf_t *QDECL CLGHL_pic_parsepiclist (char *filename, int *numparsed) { hlspriteinf_t *result; int entry; @@ -514,10 +526,10 @@ hlspriteinf_t *CLGHL_pic_parsepiclist (char *filename, int *numparsed) return result; } -void CLGHL_fillrgba (int x, int y, int width, int height, int r, int g, int b, int a) +void QDECL CLGHL_fillrgba (int x, int y, int width, int height, int r, int g, int b, int a) { } -int CLGHL_getscreeninfo (hlscreeninfo_t *info) +int QDECL CLGHL_getscreeninfo (hlscreeninfo_t *info) { int i; if (info->size != sizeof(*info)) @@ -532,25 +544,25 @@ int CLGHL_getscreeninfo (hlscreeninfo_t *info) return true; } -void CLGHL_setcrosshair (HLPIC pic, hlsubrect_t rect, int r, int g, int b) +void QDECL CLGHL_setcrosshair (HLPIC pic, hlsubrect_t rect, int r, int g, int b) { } -struct hlcvar_s *CLGHL_cvar_register (char *name, char *defvalue, int flags) +struct hlcvar_s *QDECL CLGHL_cvar_register (char *name, char *defvalue, int flags) { if (Cvar_Get(name, defvalue, 0, "Halflife cvars")) return GHL_CVarGetPointer(name); else return NULL; } -float CLGHL_cvar_getfloat (char *name) +float QDECL CLGHL_cvar_getfloat (char *name) { cvar_t *var = Cvar_FindVar(name); if (var) return var->value; return 0; } -char *CLGHL_cvar_getstring (char *name) +char *QDECL CLGHL_cvar_getstring (char *name) { cvar_t *var = Cvar_FindVar(name); if (var) @@ -558,11 +570,11 @@ char *CLGHL_cvar_getstring (char *name) return ""; } -void CLGHL_cmd_register (char *name, xcommand_t func) +void QDECL CLGHL_cmd_register (char *name, xcommand_t func) { Cmd_AddRemCommand(name, func); } -void CLGHL_hooknetmsg (char *msgname, void *func) +void QDECL CLGHL_hooknetmsg (char *msgname, void *func) { int i; //update the current list now. @@ -589,16 +601,16 @@ void CLGHL_hooknetmsg (char *msgname, void *func) pendingusermsgs[numnewhooks].hook = func; numnewhooks++; } -void CLGHL_forwardcmd (char *command) +void QDECL CLGHL_forwardcmd (char *command) { CL_SendClientCommand(true, "%s", command); } -void CLGHL_localcmd (char *command) +void QDECL CLGHL_localcmd (char *command) { Cbuf_AddText(command, RESTRICT_SERVER); } -void CLGHL_getplayerinfo (int entnum, hlplayerinfo_t *result) +void QDECL CLGHL_getplayerinfo (int entnum, hlplayerinfo_t *result) { player_info_t *player; entnum--; @@ -619,7 +631,7 @@ void CLGHL_getplayerinfo (int entnum, hlplayerinfo_t *result) result->model = ""; } -void CLGHL_startsound_name (char *name, float vol) +void QDECL CLGHL_startsound_name (char *name, float vol) { sfx_t *sfx = S_PrecacheSound (name); if (!sfx) @@ -629,7 +641,7 @@ void CLGHL_startsound_name (char *name, float vol) } S_StartSound (-1, -1, sfx, vec3_origin, vol, 1); } -void CLGHL_startsound_idx (int idx, float vol) +void QDECL CLGHL_startsound_idx (int idx, float vol) { sfx_t *sfx = cl.sound_precache[idx]; if (!sfx) @@ -640,12 +652,12 @@ void CLGHL_startsound_idx (int idx, float vol) S_StartSound (-1, -1, sfx, vec3_origin, vol, 1); } -void CLGHL_anglevectors (float *ina, float *outf, float *outr, float *outu) +void QDECL CLGHL_anglevectors (float *ina, float *outf, float *outr, float *outu) { AngleVectors(ina, outf, outr, outu); } -hlmsginfo_t *CLGHL_get_message_info (char *name) +hlmsginfo_t *QDECL CLGHL_get_message_info (char *name) { //fixme: add parser hlmsginfo_t *ret; @@ -664,70 +676,70 @@ hlmsginfo_t *CLGHL_get_message_info (char *name) ret->holdtime = 1000; return ret; } -int CLGHL_drawchar (int x, int y, int charnum, int r, int g, int b) +int QDECL CLGHL_drawchar (int x, int y, int charnum, int r, int g, int b) { return 0; } -int CLGHL_drawstring (int x, int y, char *string) +int QDECL CLGHL_drawstring (int x, int y, char *string) { return 0; } -void CLGHL_settextcolour(float r, float g, float b) +void QDECL CLGHL_settextcolour(float r, float g, float b) { } -void CLGHL_drawstring_getlen (char *string, int *outlen, int *outheight) +void QDECL CLGHL_drawstring_getlen (char *string, int *outlen, int *outheight) { *outlen = strlen(string)*8; *outheight = 8; } -void CLGHL_consoleprint (char *str) +void QDECL CLGHL_consoleprint (char *str) { Con_Printf("%s", str); } -void CLGHL_centerprint (char *str) +void QDECL CLGHL_centerprint (char *str) { SCR_CenterPrint(0, str, true); } -int CLGHL_getwindowcenterx(void) +int QDECL CLGHL_getwindowcenterx(void) { return window_center_x; } -int CLGHL_getwindowcentery(void) +int QDECL CLGHL_getwindowcentery(void) { return window_center_y; } -void CLGHL_getviewnangles(float*ang) +void QDECL CLGHL_getviewnangles(float*ang) { VectorCopy(cl.viewangles[0], ang); } -void CLGHL_setviewnangles(float*ang) +void QDECL CLGHL_setviewnangles(float*ang) { VectorCopy(ang, cl.viewangles[0]); } -void CLGHL_getmaxclients(float*ang){notimp(__LINE__);} -void CLGHL_cvar_setvalue(char *cvarname, char *value){notimp(__LINE__);} +void QDECL CLGHL_getmaxclients(float*ang){notimp(__LINE__);} +void QDECL CLGHL_cvar_setvalue(char *cvarname, char *value){notimp(__LINE__);} -int CLGHL_cmd_argc(void) +int QDECL CLGHL_cmd_argc(void) { return Cmd_Argc(); } -char *CLGHL_cmd_argv(int i) +char *QDECL CLGHL_cmd_argv(int i) { return Cmd_Argv(i); } #define CLGHL_con_printf Con_Printf//void CLGHL_con_printf(char *fmt, ...){notimp(__LINE__);} #define CLGHL_con_dprintf Con_DPrintf//void CLGHL_con_dprintf(char *fmt, ...){notimp(__LINE__);} -void CLGHL_con_notificationprintf(int pos, char *fmt, ...){notimp(__LINE__);} -void CLGHL_con_notificationprintfex(void *info, char *fmt, ...){notimp(__LINE__);} -char *CLGHL_physkey(char *key){notimp(__LINE__);return NULL;} -char *CLGHL_serverkey(char *key){notimp(__LINE__);return NULL;} -float CLGHL_getclientmaxspeed(void) +void QDECL CLGHL_con_notificationprintf(int pos, char *fmt, ...){notimp(__LINE__);} +void QDECL CLGHL_con_notificationprintfex(void *info, char *fmt, ...){notimp(__LINE__);} +char *QDECL CLGHL_physkey(char *key){notimp(__LINE__);return NULL;} +char *QDECL CLGHL_serverkey(char *key){notimp(__LINE__);return NULL;} +float QDECL CLGHL_getclientmaxspeed(void) { return 320; } -int CLGHL_checkparm(char *str, const char **next) +int QDECL CLGHL_checkparm(char *str, const char **next) { int i; i = COM_CheckParm(str); @@ -740,7 +752,7 @@ int CLGHL_checkparm(char *str, const char **next) } return i; } -int CLGHL_keyevent(int key, int down) +int QDECL CLGHL_keyevent(int key, int down) { if (key >= 241 && key <= 241+5) Key_Event(K_MOUSE1+key-241, 0, down); @@ -748,62 +760,62 @@ int CLGHL_keyevent(int key, int down) Con_Printf("CLGHL_keyevent: Unrecognised HL key code\n"); return true; //fixme: check the return type } -void CLGHL_getmousepos(int *outx, int *outy){notimp(__LINE__);} -int CLGHL_movetypeisnoclip(void){notimp(__LINE__);return 0;} -struct hlclent_s *CLGHL_getlocalplayer(void){notimp(__LINE__);return NULL;} -struct hlclent_s *CLGHL_getviewent(void){notimp(__LINE__);return NULL;} -struct hlclent_s *CLGHL_getentidx(void){notimp(__LINE__);return NULL;} -float CLGHL_getlocaltime(void){return cl.time;} -void CLGHL_calcshake(void){notimp(__LINE__);} -void CLGHL_applyshake(float *origin, float *angles, float factor){notimp(__LINE__);} -int CLGHL_pointcontents(float *point, float *truecon){notimp(__LINE__);return 0;} -int CLGHL_entcontents(float *point){notimp(__LINE__);return 0;} -void CLGHL_traceline(float *start, float *end, int flags, int hull, int forprediction){notimp(__LINE__);} +void QDECL CLGHL_getmousepos(int *outx, int *outy){notimp(__LINE__);} +int QDECL CLGHL_movetypeisnoclip(void){notimp(__LINE__);return 0;} +struct hlclent_s *QDECL CLGHL_getlocalplayer(void){notimp(__LINE__);return NULL;} +struct hlclent_s *QDECL CLGHL_getviewent(void){notimp(__LINE__);return NULL;} +struct hlclent_s *QDECL CLGHL_getentidx(void){notimp(__LINE__);return NULL;} +float QDECL CLGHL_getlocaltime(void){return cl.time;} +void QDECL CLGHL_calcshake(void){notimp(__LINE__);} +void QDECL CLGHL_applyshake(float *origin, float *angles, float factor){notimp(__LINE__);} +int QDECL CLGHL_pointcontents(float *point, float *truecon){notimp(__LINE__);return 0;} +int QDECL CLGHL_entcontents(float *point){notimp(__LINE__);return 0;} +void QDECL CLGHL_traceline(float *start, float *end, int flags, int hull, int forprediction){notimp(__LINE__);} -model_t *CLGHL_loadmodel(char *modelname, int *mdlindex){notimp(__LINE__);return Mod_ForName(modelname, false);} -int CLGHL_addrentity(int type, void *ent){notimp(__LINE__);return 0;} +model_t *QDECL CLGHL_loadmodel(char *modelname, int *mdlindex){notimp(__LINE__);return Mod_ForName(modelname, false);} +int QDECL CLGHL_addrentity(int type, void *ent){notimp(__LINE__);return 0;} -model_t *CLGHL_modelfrompic(HLPIC pic){notimp(__LINE__);return NULL;} -void CLGHL_soundatloc(char*sound, float volume, float *org){notimp(__LINE__);} +model_t *QDECL CLGHL_modelfrompic(HLPIC pic){notimp(__LINE__);return NULL;} +void QDECL CLGHL_soundatloc(char*sound, float volume, float *org){notimp(__LINE__);} -unsigned short CLGHL_precacheevent(int evtype, char *name){notimp(__LINE__);return 0;} -void CLGHL_playevent(int flags, struct hledict_s *ent, unsigned short evindex, float delay, float *origin, float *angles, float f1, float f2, int i1, int i2, int b1, int b2){notimp(__LINE__);} -void CLGHL_weaponanimate(int newsequence, int body) +unsigned short QDECL CLGHL_precacheevent(int evtype, char *name){notimp(__LINE__);return 0;} +void QDECL CLGHL_playevent(int flags, struct hledict_s *ent, unsigned short evindex, float delay, float *origin, float *angles, float f1, float f2, int i1, int i2, int b1, int b2){notimp(__LINE__);} +void QDECL CLGHL_weaponanimate(int newsequence, int body) { hl_viewmodelsequencetime = cl.time; hl_viewmodelsequencecur = newsequence; hl_viewmodelsequencebody = body; } -float CLGHL_randfloat(float minv, float maxv){notimp(__LINE__);return minv;} -long CLGHL_randlong(long minv, long maxv){notimp(__LINE__);return minv;} -void CLGHL_hookevent(char *name, void (*func)(struct hlevent_s *event)){notimp(__LINE__);} -int CLGHL_con_isshown(void) +float QDECL CLGHL_randfloat(float minv, float maxv){notimp(__LINE__);return minv;} +long QDECL CLGHL_randlong(long minv, long maxv){notimp(__LINE__);return minv;} +void QDECL CLGHL_hookevent(char *name, void (*func)(struct hlevent_s *event)){notimp(__LINE__);} +int QDECL CLGHL_con_isshown(void) { return scr_con_current > 0; } -char *CLGHL_getgamedir(void) +char *QDECL CLGHL_getgamedir(void) { extern char gamedirfile[]; return gamedirfile; } -struct hlcvar_s *CLGHL_cvar_find(char *name) +struct hlcvar_s *QDECL CLGHL_cvar_find(char *name) { return GHL_CVarGetPointer(name); } -char *CLGHL_lookupbinding(char *command) +char *QDECL CLGHL_lookupbinding(char *command) { return NULL; } -char *CLGHL_getlevelname(void) +char *QDECL CLGHL_getlevelname(void) { return cl.levelname; } -void CLGHL_getscreenfade(struct hlsfade_s *fade){notimp(__LINE__);} -void CLGHL_setscreenfade(struct hlsfade_s *fade){notimp(__LINE__);} -void *CLGHL_vgui_getpanel(void){notimp(__LINE__);return NULL;} -void CLGHL_vgui_paintback(int extents[4]){notimp(__LINE__);} +void QDECL CLGHL_getscreenfade(struct hlsfade_s *fade){notimp(__LINE__);} +void QDECL CLGHL_setscreenfade(struct hlsfade_s *fade){notimp(__LINE__);} +void *QDECL CLGHL_vgui_getpanel(void){notimp(__LINE__);return NULL;} +void QDECL CLGHL_vgui_paintback(int extents[4]){notimp(__LINE__);} -void *CLGHL_loadfile(char *path, int alloctype, int *length) +void *QDECL CLGHL_loadfile(char *path, int alloctype, int *length) { void *ptr = NULL; int flen = -1; @@ -819,49 +831,49 @@ void *CLGHL_loadfile(char *path, int alloctype, int *length) return ptr; } -char *CLGHL_parsefile(char *data, char *token) +char *QDECL CLGHL_parsefile(char *data, char *token) { return COM_ParseOut(data, token, 1024); } -void CLGHL_freefile(void *file) +void QDECL CLGHL_freefile(void *file) { //only valid for alloc type 5 FS_FreeFile(file); } -int CLGHL_forcedspectator(void) +int QDECL CLGHL_forcedspectator(void) { return cls.demoplayback; } -model_t *CLGHL_loadmapsprite(char *name) +model_t *QDECL CLGHL_loadmapsprite(char *name) { notimp(__LINE__);return NULL; } -void CLGHL_fs_addgamedir(char *basedir, char *appname){notimp(__LINE__);} -int CLGHL_expandfilename(char *filename, char *outbuff, int outsize){notimp(__LINE__);return false;} +void QDECL CLGHL_fs_addgamedir(char *basedir, char *appname){notimp(__LINE__);} +int QDECL CLGHL_expandfilename(char *filename, char *outbuff, int outsize){notimp(__LINE__);return false;} -char *CLGHL_player_key(int pnum, char *key){notimp(__LINE__);return NULL;} -void CLGHL_player_setkey(char *key, char *value){notimp(__LINE__);return NULL;} +char *QDECL CLGHL_player_key(int pnum, char *key){notimp(__LINE__);return NULL;} +void QDECL CLGHL_player_setkey(char *key, char *value){notimp(__LINE__);return;} -qboolean CLGHL_getcdkey(int playernum, char key[16]){notimp(__LINE__);return false;} -int CLGHL_trackerfromplayer(int pslot){notimp(__LINE__);return 0;} -int CLGHL_playerfromtracker(int tracker){notimp(__LINE__);return 0;} -int CLGHL_sendcmd_unreliable(char *cmd){notimp(__LINE__);return 0;} -void CLGHL_getsysmousepos(long *xandy) +qboolean QDECL CLGHL_getcdkey(int playernum, char key[16]){notimp(__LINE__);return false;} +int QDECL CLGHL_trackerfromplayer(int pslot){notimp(__LINE__);return 0;} +int QDECL CLGHL_playerfromtracker(int tracker){notimp(__LINE__);return 0;} +int QDECL CLGHL_sendcmd_unreliable(char *cmd){notimp(__LINE__);return 0;} +void QDECL CLGHL_getsysmousepos(long *xandy) { #ifdef _WIN32 GetCursorPos((LPPOINT)xandy); #endif } -void CLGHL_setsysmousepos(int x, int y) +void QDECL CLGHL_setsysmousepos(int x, int y) { #ifdef _WIN32 SetCursorPos(x, y); #endif } -void CLGHL_setmouseenable(qboolean enable) +void QDECL CLGHL_setmouseenable(qboolean enable) { extern cvar_t _windowed_mouse; Cvar_Set(&_windowed_mouse, enable?"1":"0"); @@ -870,19 +882,19 @@ void CLGHL_setmouseenable(qboolean enable) #if HLCL_API_VERSION >= 7 -int CLGHL_demo_isrecording(void) +int QDECL CLGHL_demo_isrecording(void) { return cls.demorecording; } -int CLGHL_demo_isplaying(void) +int QDECL CLGHL_demo_isplaying(void) { return cls.demoplayback; } -int CLGHL_demo_istimedemo(void) +int QDECL CLGHL_demo_istimedemo(void) { return cls.timedemo; } -void CLGHL_demo_writedata(int size, void *data) +void QDECL CLGHL_demo_writedata(int size, void *data) { notimp(__LINE__); } @@ -1100,7 +1112,7 @@ void CLHL_LoadClientGame(void) char fullname[MAX_OSPATH]; char *path; - int (*initfunc)(CLHL_enginecgamefuncs_t *funcs, int version); + int (QDECL *initfunc)(CLHL_enginecgamefuncs_t *funcs, int version); dllfunction_t funcs[] = { {(void*)&initfunc, "Initialize"}, @@ -1115,7 +1127,7 @@ void CLHL_LoadClientGame(void) while((path = COM_NextPath (path))) { if (!path) - return NULL; // couldn't find one anywhere + return; // couldn't find one anywhere snprintf (fullname, sizeof(fullname), "%s/%s", path, "cl_dlls/client"); clg = Sys_LoadLibrary(fullname, funcs); if (clg) @@ -1127,6 +1139,7 @@ void CLHL_LoadClientGame(void) if (!initfunc(&CLHL_enginecgamefuncs, HLCL_API_VERSION)) { + Con_Printf("HalfLife cldll is not version %i\n", HLCL_API_VERSION); Sys_CloseLibrary(clg); clg = NULL; return; @@ -1284,7 +1297,7 @@ int CLHL_ParseGamePacket(void) if (!(flags & 4)) S_StartSound(0, 0, S_PrecacheSound("explosion"), startp, 1, 1); if (!(flags & 2)) - CL_NewDlightRGB(0, startp[0], startp[1], startp[2], 200, 1, 0.2,0.2,0.2); + CL_NewDlightRGB(0, startp, 200, 1, 0.2,0.2,0.2); ef = CL_AllocExplosion(); VectorCopy(startp, ef->origin); diff --git a/engine/client/client.h b/engine/client/client.h index 3f65c1a4..0ecb56c9 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -28,9 +28,9 @@ typedef struct int height; //for hardware 32bit texture overrides - int tex_base; - int tex_lower; - int tex_upper; + texid_t tex_base; + texid_t tex_lower; + texid_t tex_upper; qboolean failedload; // the name isn't a valid skin cache_user_t cache; @@ -231,19 +231,11 @@ typedef struct // // client_state_t should hold all pieces of the client state // -#define MAX_SWLIGHTS 32 //sw lighting, aka: r_dynamic, uses unsigned ints as a mask for cached lit flags. We could increase this on 64bit platforms or by just using more fields. - -#ifdef RGLQUAKE -#define MAX_RTLIGHTS 256 //r_shadow_realtime_world needs a LOT of lights. -#else -#define MAX_RTLIGHTS 0 //but sw rendering doesn't have that. -#endif - -#if MAX_SWLIGHTS > MAX_RTLIGHTS -#define MAX_DLIGHTS MAX_SWLIGHTS -#else -#define MAX_DLIGHTS MAX_RTLIGHTS -#endif +//the light array works thusly: +//dlights are allocated DL_LAST downwards to 0, static wlights are allocated DL_LAST+1 to MAX_RTLIGHTS. +//thus to clear the dlights but not rtlights, set the first light to RTL_FIRST +#define DL_LAST (sizeof(unsigned int)*8-1) +#define RTL_FIRST (sizeof(unsigned int)*8) #define LFLAG_NORMALMODE (1<<0) #define LFLAG_REALTIMEMODE (1<<1) @@ -252,6 +244,7 @@ typedef struct #define LFLAG_ALLOW_LMHACK (1<<16) #define LFLAG_ALLOW_FLASH (1<<17) #define LFLAG_ALLOW_PPL (1<<18) +#define LFLAG_SHADOWMAP (1<<19) #define LFLAG_DYNAMIC (LFLAG_ALLOW_PPL | LFLAG_ALLOW_LMHACK | LFLAG_ALLOW_FLASH | LFLAG_NORMALMODE | LFLAG_REALTIMEMODE) @@ -271,11 +264,13 @@ typedef struct dlight_s //the following are used for rendering (client code should clear on create) struct shadowmesh_s *worldshadowmesh; - int stexture; + texid_t stexture; struct { float updatetime; } face [6]; int style; //multiply by style values if > 0 + float fov; //spotlight + int refresh; float dist; struct dlight_s *next; } dlight_t; @@ -343,7 +338,7 @@ typedef struct float lastarbiatarypackettime; //used to mark when packets were sent to prevent mvdsv servers from causing us to disconnect. // private userinfo for sending to masterless servers - char userinfo[MAX_INFO_STRING]; + char userinfo[EXTENDED_INFO_STRING]; char servername[MAX_OSPATH]; // name of server from original connect @@ -390,7 +385,6 @@ typedef struct qboolean allow_skyboxes; qboolean allow_mirrors; qboolean allow_watervis; - qboolean allow_shaders; qboolean allow_luma; qboolean allow_bump; float allow_fbskins; //fraction of allowance @@ -404,6 +398,7 @@ typedef struct #ifdef PROTOCOLEXTENSIONS unsigned long fteprotocolextensions; + unsigned long fteprotocolextensions2; #endif unsigned long z_ext; #ifdef NQPROT @@ -699,6 +694,7 @@ extern cvar_t ruleset_allow_larger_models; extern cvar_t ruleset_allow_modified_eyes; extern cvar_t ruleset_allow_sensative_texture_replacements; extern cvar_t ruleset_allow_localvolume; +extern cvar_t ruleset_allow_shaders; #define MAX_STATIC_ENTITIES 256 // torches, etc @@ -710,9 +706,10 @@ extern efrag_t cl_efrags[MAX_EFRAGS]; extern entity_t cl_static_entities[MAX_STATIC_ENTITIES]; extern trailstate_t *cl_static_emit[MAX_STATIC_ENTITIES]; extern lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES]; -extern dlight_t cl_dlights[MAX_DLIGHTS]; +extern dlight_t *cl_dlights; +extern unsigned int cl_maxdlights; -extern int dlights_running, dlights_software; +extern int rtlights_first, rtlights_max; extern int cl_baselines_count; extern qboolean nomaster; @@ -724,10 +721,14 @@ extern float server_version; // version of server we connected to // // cl_main // +void CL_InitDlights(void); dlight_t *CL_AllocDlight (int key); -dlight_t *CL_NewDlight (int key, float x, float y, float z, float radius, float time, int type); -dlight_t *CL_NewDlightRGB (int key, float x, float y, float z, float radius, float time, float r, float g, float b); +dlight_t *CL_AllocSlight (void); //allocates a static light +dlight_t *CL_NewDlight (int key, const vec3_t origin, float radius, float time, int type); +dlight_t *CL_NewDlightRGB (int key, const vec3_t origin, float radius, float time, float r, float g, float b); +dlight_t *CL_NewDlightCube (int key, const vec3_t origin, vec3_t angles, float radius, float time, vec3_t colours); void CL_DecayLights (void); + void CL_ParseDelta (struct entity_state_s *from, struct entity_state_s *to, int bits, qboolean); void CL_Init (void); @@ -752,12 +753,33 @@ void CL_SetInfo (char *key, char *value); void CL_BeginServerConnect(void); void CLNQ_BeginServerConnect(void); +char *CL_TryingToConnect(void); #define MAX_VISEDICTS 1024 extern int cl_numvisedicts, cl_oldnumvisedicts; extern entity_t *cl_visedicts, *cl_oldvisedicts; extern entity_t cl_visedicts_list[2][MAX_VISEDICTS]; +/*these are for q3 really*/ +typedef struct { + struct shader_s *shader; + int firstvert; + int firstidx; + int numvert; + int numidx; +} scenetris_t; +extern scenetris_t *cl_stris; +extern vecV_t *cl_strisvertv; +extern vec4_t *cl_strisvertc; +extern vec2_t *cl_strisvertt; +extern index_t *cl_strisidx; +extern unsigned int cl_numstrisidx; +extern unsigned int cl_maxstrisidx; +extern unsigned int cl_numstrisvert; +extern unsigned int cl_maxstrisvert; +extern unsigned int cl_numstris; +extern unsigned int cl_maxstris; + extern char emodel_name[], pmodel_name[], prespawn_name[], modellist_name[], soundlist_name[]; qboolean TraceLineN (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal); @@ -810,7 +832,7 @@ char *Key_GetBinding(int keynum); void CL_UseIndepPhysics(qboolean allow); void CL_FlushClientCommands(void); -void VARGS CL_SendClientCommand(qboolean reliable, char *format, ...); +void VARGS CL_SendClientCommand(qboolean reliable, char *format, ...) LIKEPRINTF(2); int CL_RemoveClientCommands(char *command); void CL_AllowIndependantSendCmd(qboolean allow); @@ -822,6 +844,7 @@ void CL_DrawPrydonCursor(void); void CL_StopPlayback (void); qboolean CL_GetMessage (void); void CL_WriteDemoCmd (usercmd_t *pcmd); +void CL_Demo_ClientCommand(char *commandtext); //for QTV. void CL_Stop_f (void); void CL_Record_f (void); @@ -865,25 +888,31 @@ void CL_ParseQTVFile(vfsfile_t *f, const char *fname, qtvfile_t *result); #define NET_TIMINGSMASK 255 extern int packet_latency[NET_TIMINGS]; int CL_CalcNet (void); -void CL_ParseServerMessage (void); +void CL_ClearParseState(void); void CL_DumpPacket(void); void CL_ParseEstablished(void); +void CL_ParseServerMessage (void); void CLNQ_ParseServerMessage (void); #ifdef Q2CLIENT void CLQ2_ParseServerMessage (void); #endif void CL_NewTranslation (int slot); + qboolean CL_CheckOrEnqueDownloadFile (char *filename, char *localname, unsigned int flags); qboolean CL_EnqueDownload(char *filename, char *localname, unsigned int flags); downloadlist_t *CL_DownloadFailed(char *name); +int CL_DownloadRate(void); +void CL_GetDownloadSizes(unsigned int *filecount, unsigned int *totalsize, qboolean *somesizesunknown); +qboolean CL_ParseOOBDownload(void); +void CL_DownloadFinished(void); +void CL_RequestNextDownload (void); +void CL_SendDownloadReq(sizebuf_t *msg); + qboolean CL_IsUploading(void); void CL_NextUpload(void); void CL_StartUpload (qbyte *data, int size); void CL_StopUpload(void); -void CL_RequestNextDownload (void); -void CL_SendDownloadReq(sizebuf_t *msg); - qboolean CL_CheckBaselines (int size); // @@ -946,7 +975,7 @@ qboolean CL_MayLerp(void); //clq3_parse.c // #ifdef Q3CLIENT -void VARGS CLQ3_SendClientCommand(const char *fmt, ...); +void VARGS CLQ3_SendClientCommand(const char *fmt, ...) LIKEPRINTF(1); void CLQ3_SendAuthPacket(netadr_t gameserver); void CLQ3_SendConnectPacket(netadr_t to); void CLQ3_SendCmd(usercmd_t *cmd); @@ -971,6 +1000,8 @@ qboolean CSQC_DrawView(void); void CSQC_Shutdown(void); qboolean CSQC_StuffCmd(int lplayernum, char *cmd); qboolean CSQC_LoadResource(char *resname, char *restype); +qboolean CSQC_ParsePrint(char *message, int printlevel); +qboolean CSQC_ParseGamePacket(void); qboolean CSQC_CenterPrint(int lplayernum, char *cmd); void CSQC_Input_Frame(int lplayernum, usercmd_t *cmd); void CSQC_WorldLoaded(void); @@ -1015,6 +1046,7 @@ void Cam_Lock(int pnum, int playernum); void Cam_SelfTrack(int pnum); void Cam_Track(int pnum, usercmd_t *cmd); void Cam_TrackCrosshairedPlayer(int pnum); +void Cam_SetAutoTrack(int userid); void Cam_FinishMove(int pnum, usercmd_t *cmd); void Cam_Reset(void); void Cam_TrackPlayer(int pnum, char *cmdname, char *plrarg); @@ -1047,6 +1079,7 @@ char* TP_LocationName (vec3_t location); char* TP_MapName (void); void TP_NewMap (void); void TP_ParsePlayerInfo(player_state_t *oldstate, player_state_t *state, player_info_t *info); +qboolean TP_IsPlayerVisible(vec3_t origin); char* TP_PlayerName (void); char* TP_PlayerTeam (void); void TP_SearchForMsgTriggers (char *s, int level); @@ -1054,6 +1087,7 @@ qboolean TP_SoundTrigger(char *message); void TP_StatChanged (int stat, int value); qboolean TP_SuppressMessage(char *buf); colourised_t *TP_FindColours(char *name); +void TP_UpdateAutoStatus(void); // // skin.c @@ -1117,15 +1151,17 @@ void CLQ2_AddEntities (void); void CLQ2_ParseBaseline (void); void CLQ2_ParseFrame (void); void CLQ2_RunMuzzleFlash2 (int ent, int flash_number); -void CLNQ_ParseEntity(unsigned int bits); int CLQ2_RegisterTEntModels (void); #endif +#ifdef NQPROT +void CLNQ_ParseEntity(unsigned int bits); void NQ_P_ParseParticleEffect (void); void CLNQ_SignonReply (void); void NQ_BeginConnect(char *to); void NQ_ContinueConnect(char *to); int CLNQ_GetMessage (void); +#endif void CL_BeginServerReconnect(void); @@ -1159,7 +1195,7 @@ qboolean CIN_RunCinematic (void); typedef struct cin_s cin_t; struct cin_s *Media_StartCin(char *name); -int Media_UpdateForShader(int texnum, cin_t *cin); +texid_t Media_UpdateForShader(cin_t *cin); void Media_ShutdownCin(cin_t *cin); //these accept NULL for cin to mean the current fullscreen video @@ -1179,7 +1215,7 @@ int Stats_GetTouches(int playernum); int Stats_GetCaptures(int playernum); qboolean Stats_HaveFlags(void); qboolean Stats_HaveKills(void); -void VARGS Stats_Message(char *msg, ...); +void VARGS Stats_Message(char *msg, ...) LIKEPRINTF(1); int qm_strcmp(char *s1, char *s2); int qm_stricmp(char *s1, char *s2); void Stats_ParsePrintLine(char *line); diff --git a/engine/client/clq2_ents.c b/engine/client/clq2_ents.c index af7ceddb..a329d503 100644 --- a/engine/client/clq2_ents.c +++ b/engine/client/clq2_ents.c @@ -1511,7 +1511,7 @@ void CLQ2_AddPacketEntities (q2frame_t *frame) AngleVectors (ent.angles, forward, NULL, NULL); VectorMA (ent.origin, 64, forward, start); - V_AddLight (start, 100, 0.2, 0, 0); + V_AddLight (ent.keynum, start, 100, 0.2, 0, 0); } } else @@ -1535,13 +1535,13 @@ void CLQ2_AddPacketEntities (q2frame_t *frame) // ent.flags |= Q2RF_EXTERNALMODEL; // only draw from mirrors if (effects & Q2EF_FLAG1) - V_AddLight (ent.origin, 225, 0.2, 0.05, 0.05); + V_AddLight (ent.keynum, ent.origin, 225, 0.2, 0.05, 0.05); else if (effects & Q2EF_FLAG2) - V_AddLight (ent.origin, 225, 0.05, 0.05, 0.2); + V_AddLight (ent.keynum, ent.origin, 225, 0.05, 0.05, 0.2); else if (effects & Q2EF_TAGTRAIL) //PGM - V_AddLight (ent.origin, 225, 0.2, 0.2, 0.0); //PGM + V_AddLight (ent.keynum, ent.origin, 225, 0.2, 0.2, 0.0); //PGM else if (effects & Q2EF_TRACKERTRAIL) //PGM - V_AddLight (ent.origin, 225, -0.2, -0.2, -0.2); //PGM + V_AddLight (ent.keynum, ent.origin, 225, -0.2, -0.2, -0.2); //PGM } // if set to invisible, skip @@ -1623,18 +1623,11 @@ void CLQ2_AddPacketEntities (q2frame_t *frame) ent.shaderRGBAf[0] = (!!(renderfx & Q2RF_SHELL_RED)); ent.shaderRGBAf[1] = (!!(renderfx & Q2RF_SHELL_GREEN)); ent.shaderRGBAf[2] = (!!(renderfx & Q2RF_SHELL_BLUE)); -#ifdef Q3SHADERS //fixme: do better. - //fixme: this is woefully gl specific. :( - if (qrenderer == QR_OPENGL) - { - ent.forcedshader = R_RegisterCustom("q2/shell", Shader_DefaultSkinShell, NULL); - } -#endif + ent.forcedshader = R_RegisterCustom("q2/shell", Shader_DefaultSkinShell, NULL); + VQ2_AddLerpEntity (&ent); } -#ifdef Q3SHADERS ent.forcedshader = NULL; -#endif // ent.skin = NULL; // never use a custom skin on others ent.skinnum = 0; @@ -1723,7 +1716,7 @@ void CLQ2_AddPacketEntities (q2frame_t *frame) if (P_ParticleTrail(cent->lerp_origin, ent.origin, rt_rocket, ¢->trailstate)) P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 0xdc, 4, ¢->trailstate); - V_AddLight (ent.origin, 200, 0.2, 0.2, 0); + V_AddLight (ent.keynum, ent.origin, 200, 0.2, 0.2, 0); } // PGM - Do not reorder EF_BLASTER and EF_HYPERBLASTER. // EF_BLASTER | EF_TRACKER is a special case for EF_BLASTER2... Cheese! @@ -1733,22 +1726,22 @@ void CLQ2_AddPacketEntities (q2frame_t *frame) if (effects & Q2EF_TRACKER) // lame... problematic? { CLQ2_BlasterTrail2 (cent->lerp_origin, ent.origin); - V_AddLight (ent.origin, 200, 0, 0.2, 0); + V_AddLight (ent.keynum, ent.origin, 200, 0, 0.2, 0); } else { if (P_ParticleTrail(cent->lerp_origin, ent.origin, rtq2_blastertrail, ¢->trailstate)) P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 0xe0, 1, ¢->trailstate); - V_AddLight (ent.origin, 200, 0.2, 0.2, 0); + V_AddLight (ent.keynum, ent.origin, 200, 0.2, 0.2, 0); } //PGM } else if (effects & Q2EF_HYPERBLASTER) { if (effects & Q2EF_TRACKER) // PGM overloaded for blaster2. - V_AddLight (ent.origin, 200, 0, 0.2, 0); // PGM + V_AddLight (ent.keynum, ent.origin, 200, 0, 0.2, 0); // PGM else // PGM - V_AddLight (ent.origin, 200, 0.2, 0.2, 0); + V_AddLight (ent.keynum, ent.origin, 200, 0.2, 0.2, 0); } else if (effects & Q2EF_GIB) { @@ -1779,7 +1772,7 @@ void CLQ2_AddPacketEntities (q2frame_t *frame) { i = bfg_lightramp[s1->frame]; } - V_AddLight (ent.origin, i, 0, 0.2, 0); + V_AddLight (ent.keynum, ent.origin, i, 0, 0.2, 0); } // RAFAEL else if (effects & Q2EF_TRAP) @@ -1787,19 +1780,19 @@ void CLQ2_AddPacketEntities (q2frame_t *frame) ent.origin[2] += 32; CLQ2_TrapParticles (&ent); i = (rand()%100) + 100; - V_AddLight (ent.origin, i, 0.2, 0.16, 0.05); + V_AddLight (ent.keynum, ent.origin, i, 0.2, 0.16, 0.05); } else if (effects & Q2EF_FLAG1) { if (P_ParticleTrail(cent->lerp_origin, ent.origin, P_FindParticleType("ef_flag1"), ¢->trailstate)) P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 242, 1, ¢->trailstate); - V_AddLight (ent.origin, 225, 0.2, 0.05, 0.05); + V_AddLight (ent.keynum, ent.origin, 225, 0.2, 0.05, 0.05); } else if (effects & Q2EF_FLAG2) { if (P_ParticleTrail(cent->lerp_origin, ent.origin, P_FindParticleType("ef_flag2"), ¢->trailstate)) P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 115, 1, ¢->trailstate); - V_AddLight (ent.origin, 225, 0.05, 0.05, 0.2); + V_AddLight (ent.keynum, ent.origin, 225, 0.05, 0.05, 0.2); } //====== //ROGUE @@ -1807,7 +1800,7 @@ void CLQ2_AddPacketEntities (q2frame_t *frame) { if (P_ParticleTrail(cent->lerp_origin, ent.origin, P_FindParticleType("ef_tagtrail"), ¢->trailstate)) P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 220, 1, ¢->trailstate); - V_AddLight (ent.origin, 225, 0.2, 0.2, 0.0); + V_AddLight (ent.keynum, ent.origin, 225, 0.2, 0.2, 0.0); } else if (effects & Q2EF_TRACKERTRAIL) { @@ -1818,19 +1811,19 @@ void CLQ2_AddPacketEntities (q2frame_t *frame) intensity = 50 + (500 * (sin(cl.time/500.0) + 1.0)); // FIXME - check out this effect in rendition - V_AddLight (ent.origin, intensity, -0.2, -0.2, -0.2); + V_AddLight (ent.keynum, ent.origin, intensity, -0.2, -0.2, -0.2); } else { CLQ2_Tracker_Shell (cent->lerp_origin); - V_AddLight (ent.origin, 155, -0.2, -0.2, -0.2); + V_AddLight (ent.keynum, ent.origin, 155, -0.2, -0.2, -0.2); } } else if (effects & Q2EF_TRACKER) { if (P_ParticleTrail(cent->lerp_origin, ent.origin, P_FindParticleType("ef_tracker"), ¢->trailstate)) P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 0, 1, ¢->trailstate); - V_AddLight (ent.origin, 200, -0.2, -0.2, -0.2); + V_AddLight (ent.keynum, ent.origin, 200, -0.2, -0.2, -0.2); } //ROGUE //====== @@ -1845,12 +1838,12 @@ void CLQ2_AddPacketEntities (q2frame_t *frame) { if (P_ParticleTrail(cent->lerp_origin, ent.origin, P_FindParticleType("ef_ionripper"), ¢->trailstate)) P_ParticleTrailIndex(cent->lerp_origin, ent.origin, 228, 4, ¢->trailstate); - V_AddLight (ent.origin, 100, 0.2, 0.1, 0.1); + V_AddLight (ent.keynum, ent.origin, 100, 0.2, 0.1, 0.1); } // RAFAEL else if (effects & Q2EF_BLUEHYPERBLASTER) { - V_AddLight (ent.origin, 200, 0, 0, 0.2); + V_AddLight (ent.keynum, ent.origin, 200, 0, 0, 0.2); } // RAFAEL else if (effects & Q2EF_PLASMA) @@ -1859,7 +1852,7 @@ void CLQ2_AddPacketEntities (q2frame_t *frame) { P_ParticleTrail(cent->lerp_origin, ent.origin, rtq2_blastertrail, ¢->trailstate); } - V_AddLight (ent.origin, 130, 0.2, 0.1, 0.1); + V_AddLight (ent.keynum, ent.origin, 130, 0.2, 0.1, 0.1); } } @@ -2056,6 +2049,9 @@ void CLQ2_AddEntities (void) cl_visedicts = cl_visedicts_list[cls.netchan.incoming_sequence&1]; cl_numvisedicts = 0; + cl_numstrisidx = 0; + cl_numstrisvert = 0; + cl_numstris = 0; if (cl.time*1000 > cl.q2frame.servertime) { diff --git a/engine/client/clq3_parse.c b/engine/client/clq3_parse.c index 4485ece6..3e44844b 100644 --- a/engine/client/clq3_parse.c +++ b/engine/client/clq3_parse.c @@ -559,11 +559,6 @@ void CLQ3_ParseGameState(void) Host_EndGame("CLQ3_ParseGameState: configString index %i out of range", index); } configString = MSG_ReadString(); - if (index == CFGSTR_SYSINFO) - { - //check some things. - cl.servercount = atoi(Info_ValueForKey(configString, "sv_serverid")); - } CG_InsertIntoGameState(index, configString); break; diff --git a/engine/client/clq3defs.h b/engine/client/clq3defs.h index 51e7930d..73cc0d0c 100644 --- a/engine/client/clq3defs.h +++ b/engine/client/clq3defs.h @@ -321,4 +321,14 @@ void MSG_Q3_ReadDeltaUsercmd(int key, const usercmd_t *from, usercmd_t *to); void MSG_WriteBits(sizebuf_t *msg, int value, int bits); + + + +typedef struct q3refEntity_s q3refEntity_t; +void VQ3_AddEntity(const q3refEntity_t *q3); +typedef struct q3polyvert_s q3polyvert_t; +void VQ3_AddPoly(shader_t *s, int num, q3polyvert_t *verts); +typedef struct q3refdef_s q3refdef_t; +void VQ3_RenderView(const q3refdef_t *ref); + #endif diff --git a/engine/client/console.c b/engine/client/console.c index afb1ee67..cba96699 100644 --- a/engine/client/console.c +++ b/engine/client/console.c @@ -24,29 +24,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. console_t con_main; console_t *con_current; // point to either con_main -#ifdef AVAIL_FREETYPE - extern struct font_s *conchar_font; - int GLFont_DrawChar(struct font_s *font, int px, int py, unsigned int charcode); - void GLFont_BeginString(struct font_s *font, int vx, int vy, int *px, int *py); - //void GLFont_EndString(struct font_s *font); - #define GLFont_EndString(f) +#define Font_ScreenWidth() (vid.pixelwidth) - #define Font_DrawChar(x,y,c) (conchar_font?GLFont_DrawChar(conchar_font, x, y, c):(Draw_ColouredCharacter(x, y, c),(x)+8)) - - #define Font_CharWidth(c) (conchar_font?GLFont_CharWidth(conchar_font, c):8) - #define Font_CharHeight() (conchar_font?GLFont_CharHeight(conchar_font):8) - #define Font_ScreenWidth() (conchar_font?glwidth:vid.width) - extern int glwidth; -#else - #define GLFont_BeginString(f, vx, vy, px, py) *px = vx; *py = vy; - #define GLFont_EndString(f) - #define Font_DrawChar(x,y,c) (Draw_ColouredCharacter(x, y, c),(x)+8) - #define Font_CharWidth(c) 8 - #define Font_CharHeight() 8 - #define Font_ScreenWidth() vid.width -#endif - -static int Con_LineBreaks(conchar_t *start, conchar_t *end, int scrwidth, int maxlines, conchar_t **starts, conchar_t **ends); static int Con_DrawProgress(int left, int right, int y); #ifdef QTERM @@ -915,6 +894,8 @@ void Con_DrawNotify (void) int maxlines; float t; + Font_BeginString(font_conchar, x, y, &x, &y); + maxlines = con_numnotifylines.value; if (maxlines < 0) maxlines = 0; @@ -935,7 +916,7 @@ void Con_DrawNotify (void) if (t > con_notifytime.value) break; - line = Con_LineBreaks((conchar_t*)(l+1), (conchar_t*)(l+1)+l->length, Font_ScreenWidth(), lines, starts, ends); + line = Font_LineBreaks((conchar_t*)(l+1), (conchar_t*)(l+1)+l->length, Font_ScreenWidth(), lines, starts, ends); if (!line && lines > 0) { lines--; @@ -983,7 +964,7 @@ void Con_DrawNotify (void) int lines, i; c = COM_ParseFunString(CON_WHITEMASK, va(chat_team?"say_team: %s":"say: %s", chat_buffer), markup, sizeof(markup), true); *c++ = (0xe00a+((int)(realtime*con_cursorspeed)&1))|CON_WHITEMASK; - lines = Con_LineBreaks(markup, c, Font_ScreenWidth(), 8, starts, ends); + lines = Font_LineBreaks(markup, c, Font_ScreenWidth(), 8, starts, ends); for (i = 0; i < lines; i++) { c = starts[i]; @@ -998,6 +979,8 @@ void Con_DrawNotify (void) if (y > con_notifylines) con_notifylines = y; + + Font_EndString(font_conchar); } //send all the stuff that was con_printed to sys_print. @@ -1018,53 +1001,6 @@ void Con_PrintToSys(void) } } -static int Con_LineBreaks(conchar_t *start, conchar_t *end, int scrwidth, int maxlines, conchar_t **starts, conchar_t **ends) -{ - int l, bt; - int px; - int foundlines = 0; - - while (start < end) - { - // scan the width of the line - for (px=0, l=0 ; px <= scrwidth;) - { - if (start+l >= end || (start[l]&CON_CHARMASK) == '\n') - break; - l++; - px += Font_CharWidth(start[l]); - } - //if we did get to the end - if (px > scrwidth) - { - bt = l; - //backtrack until we find a space - while(l > 0 && (start[l-1]&CON_CHARMASK)>' ') - { - l--; - } - if (l == 0 && bt>0) - l = bt-1; - px -= Font_CharWidth(start[l]); - } - - starts[foundlines] = start; - ends[foundlines] = start+l; - foundlines++; - if (foundlines == maxlines) - break; - - start+=l; -// for (l=0 ; l<40 && *start && *start != '\n'; l++) - // start++; - - if ((*start&CON_CHARMASK) == '\n'||!l) - start++; // skip the \n - } - - return foundlines; -} - //returns the bottom of the progress bar static int Con_DrawProgress(int left, int right, int y) { @@ -1253,7 +1189,7 @@ void Con_DrawConsole (int lines, qboolean noback) int top; conchar_t *starts[64], *ends[sizeof(starts)/sizeof(starts[0])]; int i; - extern int glwidth; + qboolean haveprogress; if (lines <= 0) return; @@ -1276,20 +1212,15 @@ void Con_DrawConsole (int lines, qboolean noback) selactive = Key_GetConsoleSelectionBox(&selsx, &selsy, &selex, &seley); -#ifdef AVAIL_FREETYPE - if (conchar_font) - { - GLFont_BeginString(conchar_font, x, y, &x, &y); - GLFont_BeginString(conchar_font, selsx, selsy, &selsx, &selsy); - GLFont_BeginString(conchar_font, selex, seley, &selex, &seley); - } -#endif + Font_BeginString(font_conchar, x, y, &x, &y); + Font_BeginString(font_conchar, selsx, selsy, &selsx, &selsy); + Font_BeginString(font_conchar, selex, seley, &selex, &seley); ex = Font_ScreenWidth(); sx = x; ex -= sx; y -= Font_CharHeight(); - Con_DrawProgress(x, ex - x, y); + haveprogress = Con_DrawProgress(x, ex - x, y) != y; y -= Font_CharHeight(); Con_DrawInput (x, ex - x, y); @@ -1358,7 +1289,7 @@ void Con_DrawConsole (int lines, qboolean noback) { s = (conchar_t*)(l+1); - linecount = Con_LineBreaks(s, s+l->length, ex-sx, sizeof(starts)/sizeof(starts[0]), starts, ends); + linecount = Font_LineBreaks(s, s+l->length, ex-sx, sizeof(starts)/sizeof(starts[0]), starts, ends); //if Con_LineBreaks didn't find any lines at all, then it was an empty line, and we need to ensure that its still drawn if (linecount == 0) @@ -1386,7 +1317,9 @@ void Con_DrawConsole (int lines, qboolean noback) int sstart; int send; sstart = sx; - send = sstart+linelength*8; + send = sstart; + for (i = 0; i < linelength; i++) + send += Font_CharWidth(s[i]); //show something on blank lines if (send == sstart) @@ -1426,7 +1359,7 @@ void Con_DrawConsole (int lines, qboolean noback) selstartoffset = 0; } - Draw_Fill(sstart, y, send - sstart, Font_CharHeight(), 0); + Draw_Fill((sstart*vid.width)/vid.pixelwidth, (y*vid.height)/vid.pixelheight, ((send - sstart)*vid.width)/vid.pixelwidth, (Font_CharHeight()*vid.height)/vid.pixelheight, 0); } } } @@ -1444,10 +1377,22 @@ void Con_DrawConsole (int lines, qboolean noback) break; } - GLFont_EndString(conchar_font); + if (!haveprogress && lines == vid.height) + { + char *version = va(DISTRIBUTION " Quake %i", build_number()); + int i; + Font_BeginString(font_conchar, vid.width, lines, &x, &y); + y -= Font_CharHeight(); + for (i = 0; version[i]; i++) + x -= Font_CharWidth(version[i] | CON_WHITEMASK|CON_HALFALPHA); + for (i = 0; version[i]; i++) + x = Font_DrawChar(x, y, version[i] | CON_WHITEMASK|CON_HALFALPHA); + } + + Font_EndString(font_conchar); // draw the input prompt, user text, and cursor if desired - DrawCursor(); + SCR_DrawCursor(0); } diff --git a/engine/client/fragstats.c b/engine/client/fragstats.c index 680fdfe9..3f20371d 100644 --- a/engine/client/fragstats.c +++ b/engine/client/fragstats.c @@ -216,7 +216,7 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2) { fragstats.weapontotals[wid].owndeaths++; Stats_Message("%s killed you\n", cl.players[p2].name); - Stats_Message("%s deaths: %i (%i/%i)\n", fragstats.weapontotals[wid].fullname, fragstats.clienttotals[p2].kills, fragstats.weapontotals[wid].kills); + Stats_Message("%s deaths: %i (%i/%i)\n", fragstats.weapontotals[wid].fullname, fragstats.clienttotals[p2].owndeaths, fragstats.weapontotals[wid].owndeaths, fragstats.totaldeaths); } fragstats.clienttotals[p2].kills++; @@ -225,7 +225,7 @@ void Stats_Evaluate(fragfilemsgtypes_t mt, int wid, int p1, int p2) { fragstats.weapontotals[wid].ownkills++; Stats_Message("You killed %s\n", cl.players[p1].name); - Stats_Message("%s kills: %i (%i/%i)\n", fragstats.weapontotals[wid].fullname, fragstats.clienttotals[p2].kills, fragstats.weapontotals[wid].kills); + Stats_Message("%s kills: %i (%i/%i)\n", fragstats.weapontotals[wid].fullname, fragstats.clienttotals[p2].kills, fragstats.weapontotals[wid].kills, fragstats.totalkills); } break; case ff_tkdeath: diff --git a/engine/client/image.c b/engine/client/image.c index 5620629c..43cfcd36 100644 --- a/engine/client/image.c +++ b/engine/client/image.c @@ -1,10 +1,10 @@ #include "quakedef.h" -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h" #endif #ifdef D3DQUAKE -#include "d3dquake.h" +//#include "d3dquake.h" #endif cvar_t r_dodgytgafiles = SCVAR("r_dodgytgafiles", "0"); //Certain tgas are upside down. @@ -545,15 +545,17 @@ return NULL; #ifndef PNG_SUCKS_WITH_SETJMP #if defined(MINGW) #include "./mingw-libs/png.h" - #pragma comment(lib, "../libs/libpng.a") #elif defined(_WIN32) #include "png.h" - #pragma comment(lib, "../libs/libpng.lib") #else #include #endif #endif + #ifdef _MSC_VER + #pragma comment(lib, MSVCLIBSPATH "libpng.lib") + #endif + #if defined(MINGW) //hehehe... add annother symbol so the statically linked cygwin libpng can link #undef setjmp @@ -761,18 +763,20 @@ int Image_WritePNG (char *filename, int compression, qbyte *pixels, int width, i #define JPEG_API VARGS #include "./mingw-libs/jpeglib.h" #include "./mingw-libs/jerror.h" - #pragma comment(lib, "../libs/jpeg.a") #elif defined(_WIN32) #define JPEG_API VARGS #include "jpeglib.h" #include "jerror.h" - #pragma comment(lib, "../libs/jpeg.lib") #else // #include #include #include #endif +#ifdef _MSC_VER + #pragma comment(lib, MSVCLIBSPATH "jpeg.lib") +#endif + #ifndef JPEG_FALSE #define JPEG_BOOL boolean #endif @@ -1761,7 +1765,7 @@ void SaturateR8G8B8(qbyte *data, int size, float sat) void BoostGamma(qbyte *rgba, int width, int height) { -#if defined(RGLQUAKE) +#if defined(GLQUAKE) int i; extern qbyte gammatable[256]; @@ -1784,7 +1788,7 @@ void BoostGamma(qbyte *rgba, int width, int height) -#if defined(RGLQUAKE) || defined(D3DQUAKE) +#if defined(GLQUAKE) || defined(D3DQUAKE) #ifdef DDS #ifndef GL_COMPRESSED_RGB_S3TC_DXT1_EXT @@ -1817,11 +1821,11 @@ typedef struct { } ddsheader; -int GL_LoadTextureDDS(unsigned char *buffer, int filesize) +texid_t GL_LoadTextureDDS(unsigned char *buffer, int filesize) { extern int gl_filter_min; extern int gl_filter_max; - int texnum; + texid_t texnum; int nummips; int mipnum; int datasize; @@ -1831,12 +1835,12 @@ int GL_LoadTextureDDS(unsigned char *buffer, int filesize) ddsheader fmtheader; if (*(int*)buffer != *(int*)"DDS ") - return 0; + return r_nulltex; buffer+=4; memcpy(&fmtheader, buffer, sizeof(fmtheader)); if (fmtheader.dwSize != sizeof(fmtheader)) - return 0; //corrupt/different version + return r_nulltex; //corrupt/different version buffer += fmtheader.dwSize; @@ -1860,10 +1864,10 @@ int GL_LoadTextureDDS(unsigned char *buffer, int filesize) pad = 8; } else - return 0; + return r_nulltex; if (!qglCompressedTexImage2DARB) - return 0; + return r_nulltex; texnum = GL_AllocNewTexture(); GL_Bind(texnum); @@ -1892,13 +1896,13 @@ int GL_LoadTextureDDS(unsigned char *buffer, int filesize) if (nummips>1) { - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); } else { - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); } return texnum; @@ -1950,15 +1954,16 @@ qbyte *Read32BitImageFile(qbyte *buf, int len, int *width, int *height, char *fn int image_width, image_height; qbyte *COM_LoadFile (char *path, int usehunk); //fixme: should probably get rid of the 'Mod' prefix, and use something more suitable. -int Mod_LoadHiResTexture(char *name, char *subpath, qboolean mipmap, qboolean alpha, qboolean colouradjust) +texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags) { qboolean alphaed; char *buf, *data; - int len; + texid_t tex; // int h; char fname[MAX_QPATH], nicename[MAX_QPATH]; - static char *extensions[] = {//reverse order of preference - (match commas with optional file types) + static char *extensions[] = + {//reverse order of preference - (match commas with optional file types) ".pcx", //pcxes are the original gamedata of q2. So we don't want them to override pngs. #ifdef AVAIL_JPEGLIB ".jpg", @@ -1971,9 +1976,12 @@ int Mod_LoadHiResTexture(char *name, char *subpath, qboolean mipmap, qboolean al "" }; - static char *path[] ={ + static char *path[] = + { + /*if three args, first is the subpath*/ + /*the last two args are texturename then extension*/ "2%s%s", - "3textures/%s/%s%s", //this is special... It uses the subpath parameter. Note references to (i == 1) + "3textures/%s/%s%s", "3%s/%s%s", "2textures/%s%s", "2override/%s%s" @@ -1981,6 +1989,9 @@ int Mod_LoadHiResTexture(char *name, char *subpath, qboolean mipmap, qboolean al int i, e; + image_width = 0; + image_height = 0; + COM_StripAllExtensions(name, nicename, sizeof(nicename)); while((data = strchr(nicename, '*'))) @@ -1988,17 +1999,20 @@ int Mod_LoadHiResTexture(char *name, char *subpath, qboolean mipmap, qboolean al *data = '#'; } - if ((len = R_FindTexture(name))!=-1) //don't bother if it already exists. - return len; + tex = R_FindTexture(name); + if (TEXVALID(tex)) //don't bother if it already exists. + return tex; if (subpath && *subpath) { snprintf(fname, sizeof(fname)-1, "%s/%s", subpath, name); - if ((len = R_FindTexture(fname))!=-1) //don't bother if it already exists. - return len; + tex = R_FindTexture(fname); + if (TEXVALID(tex)) //don't bother if it already exists. + return tex; } - if ((len = R_LoadCompressed(name))) - return len; + tex = R_LoadCompressed(name); + if (TEXVALID(tex)) + return tex; if (strchr(name, '/')) //never look in a root dir for the pic i = 0; @@ -2019,10 +2033,10 @@ int Mod_LoadHiResTexture(char *name, char *subpath, qboolean mipmap, qboolean al snprintf(fname, sizeof(fname)-1, path[i]+1, nicename, ".dds"); if ((buf = COM_LoadFile (fname, 5))) { - len = GL_LoadTextureDDS(buf, com_filesize); + tex = GL_LoadTextureDDS(buf, com_filesize); BZ_Free(buf); - if (len) - return len; + if (TEXVALID(tex)) + return tex; } #endif @@ -2042,22 +2056,22 @@ int Mod_LoadHiResTexture(char *name, char *subpath, qboolean mipmap, qboolean al if ((data = Read32BitImageFile(buf, com_filesize, &image_width, &image_height, fname))) { extern cvar_t vid_hardwaregamma; - if (colouradjust && !vid_hardwaregamma.value) + if (!(flags&IF_NOGAMMA) && !vid_hardwaregamma.value) BoostGamma(data, image_width, image_height); TRACE(("dbg: Mod_LoadHiResTexture: %s loaded\n", name)); if (i == 1) { //if it came from a special subpath (eg: map specific), upload it using the subpath prefix snprintf(fname, sizeof(fname)-1, "%s/%s", subpath, name); - len = R_LoadTexture32 (fname, image_width, image_height, (unsigned*)data, mipmap, alpha); + tex = R_LoadTexture32 (fname, image_width, image_height, data, flags); } else - len = R_LoadTexture32 (name, image_width, image_height, (unsigned*)data, mipmap, alpha); + tex = R_LoadTexture32 (name, image_width, image_height, data, flags); BZ_Free(data); BZ_Free(buf); - return len; + return tex; } else { @@ -2068,33 +2082,54 @@ int Mod_LoadHiResTexture(char *name, char *subpath, qboolean mipmap, qboolean al } } + /*still failed? attempt to load quake lmp files, which have no real format id*/ + snprintf(fname, sizeof(fname)-1, "%s%s", nicename, ".lmp"); + if ((buf = COM_LoadFile (fname, 5))) + { + extern cvar_t vid_hardwaregamma; + tex = r_nulltex; + if (com_filesize >= 8) + { + image_width = LittleLong(((int*)buf)[0]); + image_height = LittleLong(((int*)buf)[1]); + if (image_width*image_height+8 == com_filesize) + { + tex = R_LoadTexture8(name, image_width, image_height, buf+8, flags, 1); + } + } + BZ_Free(buf); + return tex; + } + //now look in wad files. (halflife compatability) data = W_GetTexture(name, &image_width, &image_height, &alphaed); if (data) - return R_LoadTexture32 (name, image_width, image_height, (unsigned*)data, mipmap, alphaed); - return 0; + return R_LoadTexture32 (name, image_width, image_height, (unsigned*)data, flags); + return r_nulltex; } -int Mod_LoadReplacementTexture(char *name, char *subpath, qboolean mipmap, qboolean alpha, qboolean gammaadjust) +texid_t R_LoadReplacementTexture(char *name, char *subpath, unsigned int flags) { if (!gl_load24bit.value) - return 0; - return Mod_LoadHiResTexture(name, subpath, mipmap, alpha, gammaadjust); + return r_nulltex; + return R_LoadHiResTexture(name, subpath, flags); } extern cvar_t r_shadow_bumpscale_bumpmap; -int Mod_LoadBumpmapTexture(char *name, char *subpath) +texid_t R_LoadBumpmapTexture(char *name, char *subpath) { char *buf, *data; - int len; + texid_t tex; // int h; char fname[MAX_QPATH], nicename[MAX_QPATH]; - static char *extensions[] = {//reverse order of preference - (match commas with optional file types) + static char *extensions[] = + {//reverse order of preference - (match commas with optional file types) ".tga", "" }; - static char *path[] ={ + static char *path[] = + { "%s%s", "textures/%s/%s%s", //this is special... It's special name is Mr Ben Ian Graham Hacksworth. "textures/%s%s", @@ -2107,11 +2142,13 @@ int Mod_LoadBumpmapTexture(char *name, char *subpath) COM_StripExtension(name, nicename, sizeof(nicename)); - if ((len = R_FindTexture(name))!=-1) //don't bother if it already exists. - return len; + tex = R_FindTexture(name); + if (TEXVALID(tex)) //don't bother if it already exists. + return tex; - if ((len = R_LoadCompressed(name))) - return len; + tex = R_LoadCompressed(name); + if (TEXVALID(tex)) + return tex; if (strchr(name, '/')) //never look in a root dir for the pic i = 0; @@ -2144,7 +2181,7 @@ int Mod_LoadBumpmapTexture(char *name, char *subpath) if ((data = ReadTargaFile(buf, com_filesize, &image_width, &image_height, 2))) //Only load a greyscale image. { TRACE(("dbg: Mod_LoadBumpmapTexture: tga %s loaded\n", name)); - len = R_LoadTexture8Bump(name, image_width, image_height, data, true, r_shadow_bumpscale_bumpmap.value); + tex = R_LoadTexture8Bump(name, image_width, image_height, data, IF_NOALPHA|IF_NOGAMMA); BZ_Free(data); } else @@ -2155,11 +2192,11 @@ int Mod_LoadBumpmapTexture(char *name, char *subpath) BZ_Free(buf); - return len; + return tex; } } } - return 0; + return r_nulltex; } #endif diff --git a/engine/client/in_win.c b/engine/client/in_win.c index 0256694b..e4c80f3a 100644 --- a/engine/client/in_win.c +++ b/engine/client/in_win.c @@ -32,9 +32,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef AVAIL_DINPUT -#ifdef _MSC_VER -#pragma comment (lib, "dxguid.lib") -#else +#ifndef _MSC_VER #define DIRECTINPUT_VERSION 0x0500 #endif @@ -173,6 +171,14 @@ DWORD joy_flags; DWORD joy_numbuttons; #ifdef AVAIL_DINPUT +static const GUID fGUID_XAxis = {0xA36D02E0, 0xC9F3, 0x11CF, {0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}; +static const GUID fGUID_YAxis = {0xA36D02E1, 0xC9F3, 0x11CF, {0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}; +static const GUID fGUID_ZAxis = {0xA36D02E2, 0xC9F3, 0x11CF, {0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}; +static const GUID fGUID_SysMouse = {0x6F1D2B60, 0xD5A0, 0x11CF, {0xBF, 0xC7, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}; + +static const GUID fIID_IDirectInputDevice7A = {0x57d7c6bc, 0x2356, 0x11d3, {0x8e, 0x9d, 0x00, 0xC0, 0x4f, 0x68, 0x44, 0xae}}; +static const GUID fIID_IDirectInput7A = {0x9a4cb684, 0x236d, 0x11d3, {0x8e, 0x9d, 0x00, 0xc0, 0x4f, 0x68, 0x44, 0xae}}; + // devices LPDIRECTINPUT g_pdi; LPDIRECTINPUTDEVICE g_pMouse; @@ -199,9 +205,9 @@ typedef struct MYDATA { } MYDATA; static DIOBJECTDATAFORMAT rgodf[] = { - { &GUID_XAxis, FIELD_OFFSET(MYDATA, lX), DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,}, - { &GUID_YAxis, FIELD_OFFSET(MYDATA, lY), DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,}, - { &GUID_ZAxis, FIELD_OFFSET(MYDATA, lZ), 0x80000000 | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,}, + { &fGUID_XAxis, FIELD_OFFSET(MYDATA, lX), DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,}, + { &fGUID_YAxis, FIELD_OFFSET(MYDATA, lY), DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,}, + { &fGUID_ZAxis, FIELD_OFFSET(MYDATA, lZ), 0x80000000 | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,}, { 0, FIELD_OFFSET(MYDATA, bButtonA), DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,}, { 0, FIELD_OFFSET(MYDATA, bButtonB), DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,}, { 0, FIELD_OFFSET(MYDATA, bButtonC), 0x80000000 | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,}, @@ -697,7 +703,7 @@ int IN_InitDInput (void) if (pDirectInputCreateEx) // use DirectInput 7 { // register with DirectInput and get an IDirectInput to play with. - hr = iDirectInputCreateEx(global_hInstance, DINPUT_VERSION_DX7, &IID_IDirectInput7, &g_pdi7, NULL); + hr = iDirectInputCreateEx(global_hInstance, DINPUT_VERSION_DX7, &fIID_IDirectInput7A, &g_pdi7, NULL); if (FAILED(hr)) return 0; @@ -705,7 +711,7 @@ int IN_InitDInput (void) IDirectInput7_EnumDevices(g_pdi7, 0, &IN_EnumerateDevices, NULL, DIEDFL_ATTACHEDONLY); // obtain an interface to the system mouse device. - hr = IDirectInput7_CreateDeviceEx(g_pdi7, &GUID_SysMouse, &IID_IDirectInputDevice7, &g_pMouse7, NULL); + hr = IDirectInput7_CreateDeviceEx(g_pdi7, &fGUID_SysMouse, &fIID_IDirectInputDevice7A, &g_pMouse7, NULL); if (FAILED(hr)) { Con_SafePrintf ("Couldn't open DI7 mouse device\n"); @@ -763,7 +769,7 @@ int IN_InitDInput (void) IDirectInput_EnumDevices(g_pdi, 0, &IN_EnumerateDevices, NULL, DIEDFL_ATTACHEDONLY); // obtain an interface to the system mouse device. - hr = IDirectInput_CreateDevice(g_pdi, &GUID_SysMouse, &g_pMouse, NULL); + hr = IDirectInput_CreateDevice(g_pdi, &fGUID_SysMouse, &g_pMouse, NULL); if (FAILED(hr)) { @@ -1487,11 +1493,17 @@ static void ProcessMouse(mouse_t *mouse, float *movements, int pnum) if (mousecursor_y >= vid.height) mousecursor_y = vid.height - 1; mx=my=0; - -#ifdef VM_UI - UI_MousePosition(mousecursor_x, mousecursor_y); -#endif } +#ifdef VM_UI + else + { + if (UI_MousePosition(mx, my)) + { + mx = 0; + my = 0; + } + } +#endif #ifdef PEXT_CSQC if (CSQC_MouseMove(mx, my)) @@ -1537,8 +1549,8 @@ static void ProcessMouse(mouse_t *mouse, float *movements, int pnum) return; } - if (cl.paused) - return; +// if (cl.paused) +// return; // add mouse X/Y movement to cmd if ( (in_strafe.state[pnum] & 1) || (lookstrafe.value && (in_mlook.state[pnum] & 1) )) @@ -1577,9 +1589,6 @@ IN_MouseMove */ void IN_MouseMove (float *movements, int pnum) { -#ifdef RGLQUAKE - extern int glwidth, glheight; -#endif POINT current_pos; extern int mousecursor_x, mousecursor_y; @@ -1591,16 +1600,12 @@ void IN_MouseMove (float *movements, int pnum) mousecursor_x = current_pos.x-window_x; mousecursor_y = current_pos.y-window_y; -#ifdef RGLQUAKE - if (qrenderer == QR_OPENGL) //2d res scaling. - { - mousecursor_x *= vid.width/(float)glwidth; - mousecursor_y *= vid.height/(float)glheight; - } -#endif + mousecursor_x *= vid.width/(float)vid.pixelwidth; + mousecursor_y *= vid.height/(float)vid.pixelheight; #ifdef VM_UI - UI_MousePosition(mousecursor_x, mousecursor_y); + if (!Key_MouseShouldBeFree()) + UI_MousePosition(mousecursor_x, mousecursor_y); #endif return; diff --git a/engine/client/keys.h b/engine/client/keys.h index cf308d6c..55e8738c 100644 --- a/engine/client/keys.h +++ b/engine/client/keys.h @@ -182,7 +182,7 @@ void Key_WriteBindings (vfsfile_t *f); void Key_SetBinding (int keynum, int modifier, char *binding, int cmdlevel); void Key_ClearStates (void); -void Key_ConsoleDrawSelectionBox(void); +qboolean Key_GetConsoleSelectionBox(int *sx, int *sy, int *ex, int *ey); #endif diff --git a/engine/client/m_download.c b/engine/client/m_download.c index f33a6401..197472c2 100644 --- a/engine/client/m_download.c +++ b/engine/client/m_download.c @@ -267,31 +267,29 @@ static void MD_Draw (int x, int y, struct menucustom_s *c, struct menu_s *m) p = c->data; if (p) { - Draw_Character (x+4, y, 128); - Draw_Character (x+12, y, 130); - Draw_Character (x+24, y, 128); - Draw_Character (x+32, y, 130); + Draw_FunString (x+4, y, "^Ue080^Ue082"); + Draw_FunString (x+24, y, "^Ue080^Ue082"); if (p->flags&DPF_WANTTOINSTALL) - Draw_Character (x+8, y, 131); + Draw_FunString (x+8, y, "^Ue083"); else - Draw_Character (x+8, y, 129); + Draw_FunString (x+8, y, "^Ue081"); //if you have it already if (p->flags&(DPF_HAVEAVERSION | ((((int)(realtime*4))&1)?(DPF_DOWNLOADING|DPF_ENQUED):0) )) - Draw_Character (x+28, y, 131); + Draw_FunString (x+28, y, "^Ue083"); else - Draw_Character (x+28, y, 129); + Draw_FunString (x+28, y, "^Ue081"); if (&m->selecteditem->common == &c->common) - Draw_Alt_String (x+48, y, p->name); + Draw_AltFunString (x+48, y, p->name); else - Draw_String(x+48, y, p->name); + Draw_FunString(x+48, y, p->name); if (p->flags & DPF_DISPLAYVERSION) { - Draw_String(x+48+strlen(p->name)*8, y, va(" (%i.%i)", p->version/1000, p->version%1000)); + Draw_FunString(x+48+strlen(p->name)*8, y, va(" (%i.%i)", p->version/1000, p->version%1000)); } } } diff --git a/engine/client/m_items.c b/engine/client/m_items.c index 062f794d..d70e7759 100644 --- a/engine/client/m_items.c +++ b/engine/client/m_items.c @@ -1,6 +1,7 @@ //read menu.h #include "quakedef.h" +#include "shader.h" int omousex; int omousey; @@ -28,17 +29,17 @@ void Draw_TextBox (int x, int y, int width, int lines) } if (p) - Draw_TransPic (cx, cy, p); + Draw_ScalePic (cx, cy, 8, 8, p); p = Draw_SafeCachePic ("gfx/box_ml.lmp"); for (n = 0; n < lines; n++) { cy += 8; if (p) - Draw_TransPic (cx, cy, p); + Draw_ScalePic (cx, cy, 8, 8, p); } p = Draw_SafeCachePic ("gfx/box_bl.lmp"); if (p) - Draw_TransPic (cx, cy+8, p); + Draw_ScalePic (cx, cy+8, 8, 8, p); // draw middle cx += 8; @@ -47,7 +48,7 @@ void Draw_TextBox (int x, int y, int width, int lines) cy = y; p = Draw_SafeCachePic ("gfx/box_tm.lmp"); if (p) - Draw_TransPic (cx, cy, p); + Draw_ScalePic (cx, cy, 16, 8, p); p = Draw_SafeCachePic ("gfx/box_mm.lmp"); for (n = 0; n < lines; n++) { @@ -55,11 +56,11 @@ void Draw_TextBox (int x, int y, int width, int lines) if (n == 1) p = Draw_SafeCachePic ("gfx/box_mm2.lmp"); if (p) - Draw_TransPic (cx, cy, p); + Draw_ScalePic (cx, cy, 16, 8, p); } p = Draw_SafeCachePic ("gfx/box_bm.lmp"); if (p) - Draw_TransPic (cx, cy+8, p); + Draw_ScalePic (cx, cy+8, 16, 8, p); width -= 2; cx += 16; } @@ -68,17 +69,17 @@ void Draw_TextBox (int x, int y, int width, int lines) cy = y; p = Draw_SafeCachePic ("gfx/box_tr.lmp"); if (p) - Draw_TransPic (cx, cy, p); + Draw_ScalePic (cx, cy, 8, 8, p); p = Draw_SafeCachePic ("gfx/box_mr.lmp"); for (n = 0; n < lines; n++) { cy += 8; if (p) - Draw_TransPic (cx, cy, p); + Draw_ScalePic (cx, cy, 8, 8, p); } p = Draw_SafeCachePic ("gfx/box_br.lmp"); if (p) - Draw_TransPic (cx, cy+8, p); + Draw_ScalePic (cx, cy+8, 8, 8, p); } void Draw_Hexen2BigFontString(int x, int y, const char *text) @@ -105,7 +106,7 @@ void Draw_Hexen2BigFontString(int x, int y, const char *text) sy=-1; } if(sx>=0) - Draw_SubPic(x, y, p, sx, sy, 20, 20); + Draw_SubPic(x, y, 20, 20, p, sx, sy, 20*8, 20*8); x+=20; text++; } @@ -175,7 +176,7 @@ void Draw_BigFontString(int x, int y, const char *text) sy=-1; } if(sx>=0) - Draw_SubPic(x, y, p, sx, sy, (p->width>>3), (p->height>>3)); + Draw_SubPic(x, y, 20, 20, p, sx, sy, 20*8, 20*8); x+=(p->width>>3); text++; } @@ -286,6 +287,45 @@ void MenuTooltipSplit(menu_t *menu, const char *text) menu->tooltip = mtt; } +qboolean MI_Selectable(menuoption_t *op) +{ + switch(op->common.type) + { + case mt_text: + return false; + case mt_button: + return true; + case mt_hexen2buttonbigfont: + return true; + case mt_qbuttonbigfont: + return true; + case mt_menudot: + return false; + case mt_picturesel: + return true; + case mt_picture: + return false; + case mt_childwindow: + return true; + case mt_box: + return false; + case mt_slider: + return true; + case mt_checkbox: + return true; + case mt_edit: + return true; + case mt_bind: + return true; + case mt_combo: + return true; + case mt_custom: + return true; + default: + return false; + } +} + void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu) { int i; @@ -297,16 +337,19 @@ void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu) if (omousex > xpos+option->common.posx && omousex < xpos+option->common.posx+option->common.width) if (omousey > ypos+option->common.posy && omousey < ypos+option->common.posy+option->common.height) { - if (menu->selecteditem != option) + if (MI_Selectable(option)) { - if (!option->common.noselectionsound) - S_LocalSound ("misc/menu1.wav"); - menu->selecteditem = option; - menu->tooltiptime = realtime + 1; - MenuTooltipSplit(menu, menu->selecteditem->common.tooltip); + if (menu->selecteditem != option) + { + if (!option->common.noselectionsound) + S_LocalSound ("misc/menu1.wav"); + menu->selecteditem = option; + menu->tooltiptime = realtime + 1; + MenuTooltipSplit(menu, menu->selecteditem->common.tooltip); + } + if (menu->cursoritem) + menu->cursoritem->common.posy = menu->selecteditem->common.posy; } - if (menu->cursoritem) - menu->cursoritem->common.posy = menu->selecteditem->common.posy; } } if (!option->common.ishidden) @@ -314,17 +357,20 @@ void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu) { case mt_text: if (!option->text.text) - Draw_Character (xpos+option->common.posx, ypos+option->common.posy, 12+((int)(realtime*4)&1)); + { + if ((int)(realtime*4)&1) + Draw_FunString(xpos+option->common.posx, ypos+option->common.posy, "^Ue00d"); + } else if (option->text.isred) - Draw_Alt_String(xpos+option->common.posx, ypos+option->common.posy, option->text.text); + Draw_AltFunString(xpos+option->common.posx, ypos+option->common.posy, option->text.text); else - Draw_String(xpos+option->common.posx, ypos+option->common.posy, option->text.text); + Draw_FunString(xpos+option->common.posx, ypos+option->common.posy, option->text.text); break; case mt_button: if (!menu->cursoritem && menu->selecteditem == option) - Draw_Alt_String(xpos+option->common.posx, ypos+option->common.posy, option->button.text); + Draw_AltFunString(xpos+option->common.posx, ypos+option->common.posy, option->button.text); else - Draw_String(xpos+option->common.posx, ypos+option->common.posy, option->button.text); + Draw_FunString(xpos+option->common.posx, ypos+option->common.posy, option->button.text); break; case mt_hexen2buttonbigfont: Draw_Hexen2BigFontString(xpos+option->common.posx, ypos+option->common.posy, option->button.text); @@ -335,7 +381,7 @@ void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu) case mt_menudot: i = (int)(realtime * 10)%maxdots; p = Draw_SafeCachePic(va(menudotstyle, i+mindot )); - Draw_TransPic(xpos+option->common.posx, ypos+option->common.posy+dotofs, p); + Draw_ScalePic(xpos+option->common.posx, ypos+option->common.posy+dotofs, 20, 20, p); break; case mt_picturesel: p = NULL; @@ -350,13 +396,9 @@ void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu) if (!p) p = Draw_SafeCachePic(option->picture.picturename); - Draw_TransPic (xpos+option->common.posx, ypos+option->common.posy, p); + Draw_ScalePic(xpos+option->common.posx, ypos+option->common.posy, option->common.width, option->common.height, p); break; case mt_picture: - p = Draw_SafeCachePic(option->picture.picturename); - Draw_TransPic (xpos+option->common.posx, ypos+option->common.posy, p); - break; - case mt_strechpic: p = Draw_SafeCachePic(option->picture.picturename); if (p) Draw_ScalePic(xpos+option->common.posx, ypos+option->common.posy, option->common.width, option->common.height, p); break; @@ -374,15 +416,16 @@ void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu) int i; int x = xpos+option->common.posx; int y = ypos+option->common.posy; + int s; range = (option->slider.current - option->slider.min)/(option->slider.max-option->slider.min); if (option->slider.text) { if (!menu->cursoritem && menu->selecteditem == option) - Draw_Alt_String(x, y, option->slider.text); + Draw_AltFunString(x, y, option->slider.text); else - Draw_String(x, y, option->slider.text); + Draw_FunString(x, y, option->slider.text); x += strlen(option->slider.text)*8+28; } @@ -390,11 +433,15 @@ void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu) range = 0; if (range > 1) range = 1; - Draw_Character (x-8, y, 128); + x -= 8; + Font_BeginString(font_conchar, x, y, &x, &y); + x = Font_DrawChar(x, y, 0xe080 | CON_WHITEMASK); + s = x; for (i=0 ; icheck.text) { if (!menu->cursoritem && menu->selecteditem == option) - Draw_Alt_String(x, y, option->check.text); + Draw_AltFunString(x, y, option->check.text); else - Draw_String(x, y, option->check.text); + Draw_FunString(x, y, option->check.text); x += strlen(option->check.text)*8+28; } #if 0 @@ -436,9 +483,9 @@ void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu) Draw_Character (x, y, 129); #endif if (!menu->cursoritem && menu->selecteditem == option) - Draw_Alt_String (x, y, on ? "on" : "off"); + Draw_AltFunString (x, y, on ? "on" : "off"); else - Draw_String (x, y, on ? "on" : "off"); + Draw_FunString (x, y, on ? "on" : "off"); } break; case mt_edit: @@ -446,18 +493,19 @@ void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu) int x = xpos+option->common.posx; int y = ypos+option->common.posy; + //Fixme: variable width fonts if (!menu->cursoritem && menu->selecteditem == option) - Draw_Alt_String(x, y, option->edit.caption); + Draw_AltFunString(x, y, option->edit.caption); else - Draw_String(x, y, option->edit.caption); + Draw_FunString(x, y, option->edit.caption); x+=strlen(option->edit.caption)*8+8; Draw_TextBox(x-8, y-8, 16, 1); - Draw_String(x, y, option->edit.text); + Draw_FunString(x, y, option->edit.text); if (menu->selecteditem == option && (int)(realtime*4) & 1) { x += strlen(option->edit.text)*8; - Draw_Character(x, y, 11); + Draw_FunString(x, y, "^Ue00b"); } } break; @@ -470,9 +518,9 @@ void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu) char *keyname; if (!menu->cursoritem && menu->selecteditem == option) - Draw_Alt_String(x, y, option->bind.caption); + Draw_AltFunString(x, y, option->bind.caption); else - Draw_String(x, y, option->bind.caption); + Draw_FunString(x, y, option->bind.caption); x += strlen(option->bind.caption)*8+28; { l = strlen (option->bind.command); @@ -481,21 +529,21 @@ void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu) if (bindingactive && menu->selecteditem == option) { - Draw_String (x, y, "Press key"); + Draw_FunString (x, y, "Press key"); } else if (keys[0] == -1) { - Draw_String (x, y, "???"); + Draw_FunString (x, y, "???"); } else { keyname = Key_KeynumToString (keys[0]); - Draw_String (x, y, keyname); + Draw_FunString (x, y, keyname); x += strlen(keyname) * 8; if (keys[1] != -1) - { - Draw_String (x + 8, y, "or"); - Draw_String (x + 32, y, Key_KeynumToString (keys[1])); + { /*these offsets are wrong*/ + Draw_FunString (x + 8, y, "or"); + Draw_FunString (x + 32, y, Key_KeynumToString (keys[1])); } } } @@ -508,16 +556,16 @@ void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu) int y = ypos+option->common.posy; if (!menu->cursoritem && menu->selecteditem == option) - Draw_Alt_String(x, y, option->combo.caption); + Draw_AltFunString(x, y, option->combo.caption); else - Draw_String(x, y, option->combo.caption); + Draw_FunString(x, y, option->combo.caption); x += strlen(option->combo.caption)*8+24; if (option->combo.numoptions) { if (!menu->cursoritem && menu->selecteditem == option) - Draw_Alt_String(x, y, option->combo.options[option->combo.selectedoption]); + Draw_AltFunString(x, y, option->combo.options[option->combo.selectedoption]); else - Draw_String(x, y, option->combo.options[option->combo.selectedoption]); + Draw_FunString(x, y, option->combo.options[option->combo.selectedoption]); } } break; @@ -565,7 +613,7 @@ void MenuDraw(menu_t *menu) y += 8; for (l = 0; l < lines; l++) { - Draw_String(x, y, menu->tooltip->lines[l]); + Draw_FunString(x, y, menu->tooltip->lines[l]); y += 8; } } @@ -664,7 +712,7 @@ menupicture_t *MC_AddSelectablePicture(menu_t *menu, int x, int y, char *picname return n; } -menupicture_t *MC_AddPicture(menu_t *menu, int x, int y, char *picname) +menupicture_t *MC_AddPicture(menu_t *menu, int x, int y, int width, int height, char *picname) { menupicture_t *n; if (!qrenderer) @@ -677,27 +725,6 @@ menupicture_t *MC_AddPicture(menu_t *menu, int x, int y, char *picname) n->common.iszone = true; n->common.posx = x; n->common.posy = y; - n->picturename = (char *)(n+1); - strcpy(n->picturename, picname); - - n->common.next = menu->options; - menu->options = (menuoption_t *)n; - return n; -} - -menupicture_t *MC_AddStrechPicture(menu_t *menu, int x, int y, int width, int height, char *picname) -{ - menupicture_t *n; - if (!qrenderer) - return NULL; - - Draw_SafeCachePic(picname); - - n = Z_Malloc(sizeof(menupicture_t) + strlen(picname)+1); - n->common.type = mt_strechpic; - n->common.iszone = true; - n->common.posx = x; - n->common.posy = y; n->common.width = width; n->common.height = height; n->picturename = (char *)(n+1); @@ -708,20 +735,27 @@ menupicture_t *MC_AddStrechPicture(menu_t *menu, int x, int y, int width, int he return n; } -menupicture_t *MC_AddCenterPicture(menu_t *menu, int y, char *picname) +menupicture_t *MC_AddCenterPicture(menu_t *menu, int y, int height, char *picname) { int x; + int width; mpic_t *p; if (!qrenderer) return NULL; p = Draw_SafeCachePic(picname); if (!p) + { x = 320/2; + width = 64; + } else - x = (320-p->width)/2; + { + width = (p->width * (float)height) / p->height; + x = (320-(int)width)/2; + } - return MC_AddPicture(menu, x, y, picname); + return MC_AddPicture(menu, x, y, width, height, picname); } menupicture_t *MC_AddCursor(menu_t *menu, int x, int y) @@ -1216,7 +1250,7 @@ void MC_CheckBox_Key(menucheck_t *option, menu_t *menu, int key) } } -void MC_EditBox_Key(menuedit_t *edit, int key) +void MC_EditBox_Key(menuedit_t *edit, int key, unsigned int unicode) { int len = strlen(edit->text); if (key == K_DEL || key == K_BACKSPACE) @@ -1225,12 +1259,18 @@ void MC_EditBox_Key(menuedit_t *edit, int key) return; edit->text[len-1] = '\0'; } - else if (key < 32 || key > 127) + else if (!unicode) return; else { - edit->text[len] = key; - edit->text[len+1] = '\0'; + if (unicode < 128) + { + if (len < sizeof(edit->text)) + { + edit->text[len] = unicode; + edit->text[len+1] = '\0'; + } + } } edit->modified = true; @@ -1378,7 +1418,7 @@ void M_RemoveAllMenus (void) } -void DrawCursor(void) +void DrawCursor(int prydoncursornum) { extern int mousecursor_x, mousecursor_y; mpic_t *p; @@ -1393,7 +1433,14 @@ void DrawCursor(void) // Draw_TransPic(mousecursor_x-4, mousecursor_y-4, p); } else - Draw_Character(mousecursor_x-4, mousecursor_y-4, '+'); + { + int x, y; + Font_BeginString(font_conchar, mousecursor_x, mousecursor_y, &x, &y); + x -= Font_CharWidth('+' | 0xe000 | CON_WHITEMASK)/2; + y -= Font_CharHeight()/2; + Font_DrawChar(x, y, '+' | 0xe000 | CON_WHITEMASK); + Font_EndString(font_conchar); + } } @@ -1431,7 +1478,7 @@ void M_Complex_Draw(void) MenuDraw(cmenu); } - DrawCursor(); + SCR_DrawCursor(0); } menuoption_t *M_NextItem(menu_t *m, menuoption_t *old) @@ -1504,7 +1551,7 @@ menuoption_t *M_PrevSelectableItem(menu_t *m, menuoption_t *old) } } -void M_Complex_Key(int key) +void M_Complex_Key(int key, int unicode) { if (!currentmenu) return; //erm... @@ -1593,7 +1640,7 @@ void M_Complex_Key(int key) currentmenu->selecteditem->custom.key(¤tmenu->selecteditem->custom, currentmenu, key); break; case mt_edit: - MC_EditBox_Key(¤tmenu->selecteditem->edit, key); + MC_EditBox_Key(¤tmenu->selecteditem->edit, key, unicode); break; case mt_combo: MC_Combo_Key(¤tmenu->selecteditem->combo, key); @@ -1777,11 +1824,11 @@ void M_Menu_Main_f (void) mainm = M_CreateMenu(0); mainm->key = MC_Main_Key; - MC_AddPicture(mainm, 0, 4, "pics/m_main_plaque"); + MC_AddPicture(mainm, 0, 4, 38, 166, "pics/m_main_plaque"); p = Draw_SafeCachePic("pics/m_main_logo"); if (!p) return; - MC_AddPicture(mainm, 0, 173, "pics/m_main_logo"); + MC_AddPicture(mainm, 0, 173, 36, 42, "pics/m_main_logo"); #ifndef CLIENTONLY MC_AddSelectablePicture(mainm, 68, 13, "pics/m_main_game"); #endif @@ -1823,11 +1870,11 @@ void M_Menu_Main_f (void) mainm = M_CreateMenu(0); mainm->key = MC_Main_Key; - MC_AddPicture(mainm, 16, 0, "gfx/menu/hplaque.lmp"); + MC_AddPicture(mainm, 16, 0, 35, 176, "gfx/menu/hplaque.lmp"); p = Draw_SafeCachePic("gfx/menu/title0.lmp"); if (!p) return; - MC_AddPicture(mainm, (320-p->width)/2, 0, "gfx/menu/title0.lmp"); + MC_AddCenterPicture(mainm, 0, 60, "gfx/menu/title0.lmp"); b=MC_AddConsoleCommandHexen2BigFont (mainm, 80, 64, "Single Player", "menu_single\n"); b->common.width = 12*20; @@ -1868,9 +1915,9 @@ void M_Menu_Main_f (void) return; } mainm->key = MC_Main_Key; - MC_AddPicture(mainm, 16, 4, "gfx/qplaque.lmp"); + MC_AddPicture(mainm, 16, 4, 32, 144, "gfx/qplaque.lmp"); - MC_AddPicture(mainm, (320-p->width)/2, 4, "gfx/ttl_main.lmp"); + MC_AddCenterPicture(mainm, 4, 24, "gfx/ttl_main.lmp"); mainm->selecteditem = (menuoption_t *) MC_AddConsoleCommandQBigFont (mainm, 72, 32, "Single ", "menu_single\n"); @@ -1902,10 +1949,10 @@ void M_Menu_Main_f (void) return; } mainm->key = MC_Main_Key; - MC_AddPicture(mainm, 16, 4, "gfx/qplaque.lmp"); + MC_AddPicture(mainm, 16, 4, 32, 144, "gfx/qplaque.lmp"); - MC_AddPicture(mainm, (320-p->width)/2, 4, "gfx/ttl_main.lmp"); - MC_AddPicture(mainm, 72, 32, "gfx/mainmenu.lmp"); + MC_AddCenterPicture(mainm, 4, 24, "gfx/ttl_main.lmp"); + MC_AddPicture(mainm, 72, 32, 240, 112, "gfx/mainmenu.lmp"); p = Draw_SafeCachePic("gfx/mainmenu.lmp"); diff --git a/engine/client/m_master.c b/engine/client/m_master.c index 18094c1f..bcec18ca 100644 --- a/engine/client/m_master.c +++ b/engine/client/m_master.c @@ -73,48 +73,40 @@ int slist_type; -static void NM_DrawColouredCharacter (int cx, int line, unsigned int num) -{ - Draw_ColouredCharacter(cx, line, num); -} static void NM_Print (int cx, int cy, qbyte *str) { - while (*str) - { - Draw_ColouredCharacter (cx, cy, (*str)|CON_HIGHCHARSMASK|CON_WHITEMASK); - str++; - cx += 8; - } + Draw_AltFunString(cx, cy, str); } static void NM_PrintWhite (int cx, int cy, qbyte *str) { - while (*str) - { - Draw_ColouredCharacter (cx, cy, (*str)|CON_WHITEMASK); - str++; - cx += 8; - } + Draw_FunString(cx, cy, str); } static void NM_PrintColoured (int cx, int cy, int colour, qbyte *str) { +#pragma message("needs reimplementing") +/* while (*str) { NM_DrawColouredCharacter (cx, cy, (*str) | (colour<= 0) { while (*text && maxchars>0) @@ -286,6 +280,7 @@ int M_AddColumn (int right, int y, char *text, int maxchars, int colour, int hig maxchars--; } } +*/ return left; } void M_DrawServerList(void) @@ -418,11 +413,7 @@ void M_DrawServerList(void) // make sure we have a highlighted background if (highlight >= 0) - { - int i = 8; - for (; i < vid.width - 8; i += 8) - Draw_ColouredCharacter(i, y, ' ' | CON_NONCLEARBG | (COLOR_WHITE << CON_FGSHIFT) | (highlight << CON_BGSHIFT)); - } + Draw_FillRGB(8, y, vid.width-16, 8, consolecolours[highlight].fr, consolecolours[highlight].fg, consolecolours[highlight].fb); if (sb_showtimelimit.value) x = M_AddColumn(x, y, va("%i", server->tl), 3, colour, highlight); //time limit @@ -918,19 +909,19 @@ void SL_DrawColumnTitle (int *x, int y, int xlen, int mx, char *str, qboolean re if (mx >= xmin && !(*filldraw)) { *filldraw = true; - Draw_FillRGB(xmin*8, y, xlen*8, 8, (sin(realtime*4.4)*0.25)+0.5, (sin(realtime*4.4)*0.25)+0.5, 0.08); + Draw_FillRGB(xmin, y, xlen, 8, (sin(realtime*4.4)*0.25)+0.5, (sin(realtime*4.4)*0.25)+0.5, 0.08); } - Draw_FunStringLen(xmin*8, y, str, xlen); + Draw_FunStringWidth(xmin, y, str, xlen); if (x != NULL) - *x -= xlen + 1; + *x -= xlen + 8; } void SL_TitlesDraw (int x, int y, menucustom_t *ths, menu_t *menu) { int sf = Master_GetSortField(); extern int mousecursor_x, mousecursor_y; - int mx = mousecursor_x/8; + int mx = mousecursor_x; qboolean filldraw = false; qbyte clr; @@ -938,17 +929,17 @@ void SL_TitlesDraw (int x, int y, menucustom_t *ths, menu_t *menu) clr = 'D'; else clr = 'B'; - x = ths->common.width/8; + x = ths->common.width; if (mx > x || mousecursor_y < y || mousecursor_y >= y+8) filldraw = true; - if (sb_showtimelimit.value) {SL_DrawColumnTitle(&x, y, 3, mx, "tl", (sf==SLKEY_TIMELIMIT), clr, &filldraw);} - if (sb_showfraglimit.value) {SL_DrawColumnTitle(&x, y, 3, mx, "fl", (sf==SLKEY_FRAGLIMIT), clr, &filldraw);} - if (sb_showplayers.value) {SL_DrawColumnTitle(&x, y, 5, mx, "plyrs", (sf==SLKEY_NUMPLAYERS), clr, &filldraw);} - if (sb_showmap.value) {SL_DrawColumnTitle(&x, y, 8, mx, "map", (sf==SLKEY_MAP), clr, &filldraw);} - if (sb_showgamedir.value) {SL_DrawColumnTitle(&x, y, 8, mx, "gamedir", (sf==SLKEY_GAMEDIR), clr, &filldraw);} - if (sb_showping.value) {SL_DrawColumnTitle(&x, y, 3, mx, "png", (sf==SLKEY_PING), clr, &filldraw);} - if (sb_showaddress.value) {SL_DrawColumnTitle(&x, y, 21, mx, "address", (sf==SLKEY_ADDRESS), clr, &filldraw);} - SL_DrawColumnTitle(NULL, y, x, mx, "hostname^7 ", (sf==SLKEY_NAME), clr, &filldraw); + if (sb_showtimelimit.value) {SL_DrawColumnTitle(&x, y, 3*8, mx, "tl", (sf==SLKEY_TIMELIMIT), clr, &filldraw);} + if (sb_showfraglimit.value) {SL_DrawColumnTitle(&x, y, 3*8, mx, "fl", (sf==SLKEY_FRAGLIMIT), clr, &filldraw);} + if (sb_showplayers.value) {SL_DrawColumnTitle(&x, y, 5*8, mx, "plyrs", (sf==SLKEY_NUMPLAYERS), clr, &filldraw);} + if (sb_showmap.value) {SL_DrawColumnTitle(&x, y, 8*8, mx, "map", (sf==SLKEY_MAP), clr, &filldraw);} + if (sb_showgamedir.value) {SL_DrawColumnTitle(&x, y, 8*8, mx, "gamedir", (sf==SLKEY_GAMEDIR), clr, &filldraw);} + if (sb_showping.value) {SL_DrawColumnTitle(&x, y, 3*8, mx, "png", (sf==SLKEY_PING), clr, &filldraw);} + if (sb_showaddress.value) {SL_DrawColumnTitle(&x, y, 21*8, mx, "address", (sf==SLKEY_ADDRESS), clr, &filldraw);} + SL_DrawColumnTitle(NULL, y, x, mx, "hostname ", (sf==SLKEY_NAME), clr, &filldraw); } qboolean SL_TitlesKey (menucustom_t *ths, menu_t *menu, int key) @@ -1083,16 +1074,14 @@ void SL_ServerDraw (int x, int y, menucustom_t *ths, menu_t *menu) serverbackcolor[(int)stype * 2 + (thisone & 1)][2]); } - x /= 8; - - if (sb_showtimelimit.value) {Draw_FunStringLen((x-3)*8, y, va("%i", si->tl), 3); x-=4;} - if (sb_showfraglimit.value) {Draw_FunStringLen((x-3)*8, y, va("%i", si->fl), 3); x-=4;} - if (sb_showplayers.value) {Draw_FunStringLen((x-5)*8, y, va("%2i/%2i", si->players, si->maxplayers), 5); x-=6;} - if (sb_showmap.value) {Draw_FunStringLen((x-8)*8, y, si->map, 8); x-=9;} - if (sb_showgamedir.value) {Draw_FunStringLen((x-8)*8, y, si->gamedir, 8); x-=9;} - if (sb_showping.value) {Draw_FunStringLen((x-3)*8, y, va("%i", si->ping), 3); x-=4;} - if (sb_showaddress.value) {Draw_FunStringLen((x-21)*8, y, NET_AdrToString(adr, sizeof(adr), si->adr), 21); x-=22;} - Draw_FunStringLen(0, y, si->name, x); + if (sb_showtimelimit.value) {Draw_FunStringWidth((x-3*8), y, va("%i", si->tl), 3*8); x-=4*8;} + if (sb_showfraglimit.value) {Draw_FunStringWidth((x-3*8), y, va("%i", si->fl), 3*8); x-=4*8;} + if (sb_showplayers.value) {Draw_FunStringWidth((x-5*8), y, va("%2i/%2i", si->players, si->maxplayers), 5*8); x-=6*8;} + if (sb_showmap.value) {Draw_FunStringWidth((x-8*8), y, si->map, 8*8); x-=9*8;} + if (sb_showgamedir.value) {Draw_FunStringWidth((x-8*8), y, si->gamedir, 8*8); x-=9*8;} + if (sb_showping.value) {Draw_FunStringWidth((x-3*8), y, va("%i", si->ping), 3*8); x-=4*8;} + if (sb_showaddress.value) {Draw_FunStringWidth((x-21*8), y, NET_AdrToString(adr, sizeof(adr), si->adr), 21*8); x-=22*8;} + Draw_FunStringWidth(0, y, si->name, x); } } qboolean SL_ServerKey (menucustom_t *ths, menu_t *menu, int key) @@ -1111,8 +1100,8 @@ qboolean SL_ServerKey (menucustom_t *ths, menu_t *menu, int key) info->selectedpos = info->scrollpos + (mousecursor_y-16)/8; server = Master_SortedServer(info->selectedpos); -// selectedserver.inuse = true; -// SListOptionChanged(server); + selectedserver.inuse = true; + SListOptionChanged(server); if (server) { @@ -1253,7 +1242,7 @@ void SL_ServerPlayer (int x, int y, menucustom_t *ths, menu_t *menu) Draw_Fill (x, y+4, 28, 4, Sbar_ColorForMap(selectedserver.detail->players[i].botc)); NM_PrintWhite (x, y, va("%3i", selectedserver.detail->players[i].frags)); - Draw_FunStringLen (x+28, y, selectedserver.detail->players[i].name, 12); + Draw_FunStringWidth (x+28, y, selectedserver.detail->players[i].name, 12*8); } } } @@ -1501,7 +1490,7 @@ void M_Menu_ServerList2_f(void) info->filter[6] = !!sb_hideempty.value; info->filter[7] = !!sb_hidefull.value; - info->mappic = (menupicture_t *)MC_AddStrechPicture(menu, vid.width - 64, vid.height - 64, 64, 64, "012345678901234567890123456789012"); + info->mappic = (menupicture_t *)MC_AddPicture(menu, vid.width - 64, vid.height - 64, 64, 64, "012345678901234567890123456789012"); CalcFilters(menu); @@ -1577,7 +1566,7 @@ qboolean M_QuickConnect_Cancel (menuoption_t *opt, menu_t *menu, int key) void M_QuickConnect_DrawStatus (int x, int y, menucustom_t *ths, menu_t *menu) { - Draw_String(x, y, va("Polling, %i secs\n", (int)(quickconnecttimeout - Sys_DoubleTime() + 0.9))); + Draw_FunString(x, y, va("Polling, %i secs\n", (int)(quickconnecttimeout - Sys_DoubleTime() + 0.9))); } void M_QuickConnect_f(void) diff --git a/engine/client/m_mp3.c b/engine/client/m_mp3.c index 63ffbb46..18454eb0 100644 --- a/engine/client/m_mp3.c +++ b/engine/client/m_mp3.c @@ -2,9 +2,10 @@ //was origonally an mp3 track selector, now handles lots of media specific stuff - like q3 films! //should rename to m_media.c #include "quakedef.h" -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h"//fixme #endif +#include "shader.h" #if !defined(NOMEDIA) @@ -289,7 +290,7 @@ void M_Media_Draw (void) p = Draw_SafeCachePic ("gfx/p_option.lmp"); if (p) - M_DrawPic ( (320-p->width)/2, 4, p); + M_DrawScalePic ( (320-p->width)/2, 4, 144, 24, p); if (!bgmvolume.value) M_Print (12, 32, "Not playing - no volume"); else if (!*currenttrack.nicename) @@ -791,24 +792,18 @@ typedef enum { MFT_OFSGECKO } media_filmtype_t; -typedef enum { - MOT_NONE, - MOT_PALETTE, - MOT_RGBA, - MOT_BGRA, - MOT_BGR_FLIP -} media_outputtype_t; - struct cin_s { //these are the outputs (not always power of two!) - media_outputtype_t outtype; + enum uploadfmt outtype; int outwidth; int outheight; qbyte *outdata; qbyte *outpalette; int outunchanged; + texid_t texture; + qboolean (*decodeframe)(cin_t *cin, qboolean nosound); void (*doneframe)(cin_t *cin); void (*shutdown)(cin_t *cin); //warning: don't free cin_t @@ -915,11 +910,11 @@ qboolean Media_WinAvi_DecodeFrame(cin_t *cin, qboolean nosound) { SCR_SetUpToDrawConsole(); Draw_ConsoleBackground(0, vid.height, true); - Draw_String(0, 0, "Video stream is corrupt\n"); + Draw_FunString(0, 0, "Video stream is corrupt\n"); } else { - cin->outtype = MOT_BGR_FLIP; + cin->outtype = TF_BGR24_FLIP; cin->outwidth = lpbi->biWidth; cin->outheight = lpbi->biHeight; cin->outdata = (char*)lpbi+lpbi->biSize; @@ -1053,6 +1048,7 @@ cin_t *Media_WinAvi_TryLoad(char *name) ////////////////////////////////////////////////////////////////////////////////// //Quake3 RoQ Support +#ifdef Q3CLIENT void Media_Roq_Shutdown(struct cin_s *cin) { roq_close(cin->roq.roqfilm); @@ -1131,7 +1127,7 @@ qboolean Media_Roq_DecodeFrame (cin_t *cin, qboolean nosound) } cin->outunchanged = false; - cin->outtype = MOT_RGBA; + cin->outtype = TF_RGBA32; cin->outwidth = cin->roq.roqfilm->width; cin->outheight = cin->roq.roqfilm->height; cin->outdata = cin->framedata; @@ -1190,11 +1186,13 @@ cin_t *Media_RoQ_TryLoad(char *name) } return NULL; } +#endif //Quake3 RoQ Support ////////////////////////////////////////////////////////////////////////////////// //Static Image Support +#ifndef MINIMAL void Media_Static_Shutdown(struct cin_s *cin) { BZ_Free(cin->image.filmimage); @@ -1203,8 +1201,8 @@ void Media_Static_Shutdown(struct cin_s *cin) qboolean Media_Static_DecodeFrame(cin_t *cin, qboolean nosound) { - cin->outunchanged = cin->outtype==MOT_RGBA?true:false;//handy - cin->outtype = MOT_RGBA; + cin->outunchanged = cin->outtype==TF_RGBA32?true:false;//handy + cin->outtype = TF_RGBA32; cin->outwidth = cin->image.imagewidth; cin->outheight = cin->image.imageheight; cin->outdata = cin->image.filmimage; @@ -1268,11 +1266,13 @@ cin_t *Media_Static_TryLoad(char *name) } return NULL; } +#endif //Static Image Support ////////////////////////////////////////////////////////////////////////////////// //Quake2 CIN Support +#ifdef Q2CLIENT void Media_Cin_Shutdown(struct cin_s *cin) { CIN_FinishCinematic(); @@ -1308,6 +1308,7 @@ cin_t *Media_Cin_TryLoad(char *name) return NULL; } +#endif //Quake2 CIN Support ////////////////////////////////////////////////////////////////////////////////// @@ -1605,6 +1606,9 @@ void Media_ShutdownCin(cin_t *cin) if (cin->shutdown) cin->shutdown(cin); + if (TEXVALID(cin->texture)) + R_DestroyTexture(cin->texture); + if (cin->framedata) { BZ_Free(cin->framedata); @@ -1621,20 +1625,26 @@ cin_t *Media_StartCin(char *name) if (!name || !*name) //clear only. return NULL; +#ifdef OFFSCREENGECKO if (!cin) cin = Media_Gecko_TryLoad(name); +#endif if (!cin) cin = Media_Static_TryLoad(name); +#ifdef Q2CLIENT if (!cin) cin = Media_Cin_TryLoad(name); - +#endif +#ifdef Q3CLIENT if (!cin) cin = Media_RoQ_TryLoad(name); - +#endif +#ifdef WINAVI if (!cin) cin = Media_WinAvi_TryLoad(name); +#endif return cin; } @@ -1677,16 +1687,17 @@ qboolean Media_ShowFilm(void) switch(fullscreenvid->outtype) { - case MOT_RGBA: + case TF_RGBA32: Media_ShowFrameRGBA_32(fullscreenvid->outdata, fullscreenvid->outwidth, fullscreenvid->outheight); break; - case MOT_PALETTE: + case TF_TRANS8: + case TF_SOLID8: Media_ShowFrame8bit(fullscreenvid->outdata, fullscreenvid->outwidth, fullscreenvid->outheight, fullscreenvid->outpalette); break; - case MOT_BGR_FLIP: + case TF_BGR24_FLIP: Media_ShowFrameBGR_24_Flip(fullscreenvid->outdata, fullscreenvid->outwidth, fullscreenvid->outheight); break; - case MOT_BGRA: + case TF_BGRA32: #pragma message("Media_ShowFilm: BGRA comes out as RGBA") // Media_ShowFrameBGRA_32 Media_ShowFrameRGBA_32(fullscreenvid->outdata, fullscreenvid->outwidth, fullscreenvid->outheight); @@ -1699,41 +1710,28 @@ qboolean Media_ShowFilm(void) return true; } -#ifdef RGLQUAKE -int Media_UpdateForShader(int texnum, cin_t *cin) +#ifdef GLQUAKE +texid_t Media_UpdateForShader(cin_t *cin) { if (!cin) - return 0; + return r_nulltex; if (!Media_DecodeFrame(cin, true)) { - return 0; + return r_nulltex; } if (!cin->outunchanged) { - GL_Bind(texnum); - switch(cin->outtype) - { - case MOT_RGBA: - GL_Upload32("cin", (unsigned int*)cin->outdata, cin->outwidth, cin->outheight, false, false); - break; - case MOT_PALETTE: - GL_Upload8("cin", cin->outdata, cin->outwidth, cin->outheight, false, false); - break; - case MOT_BGR_FLIP: - GL_Upload24BGR_Flip ("cin", cin->outdata, cin->outwidth, cin->outheight, false, false); - break; - case MOT_BGRA: - GL_Upload32_BGRA("cin", (unsigned int*)cin->outdata, cin->outwidth, cin->outheight, false, false); - break; - } + if (!TEXVALID(cin->texture)) + cin->texture = R_AllocNewTexture(cin->outwidth, cin->outheight); + R_Upload(cin->texture, "cin", cin->outtype, cin->outdata, cin->outwidth, cin->outheight, IF_NOMIPMAP|IF_NOALPHA|IF_NOGAMMA); } if (cin->doneframe) cin->doneframe(cin); - return texnum; + return cin->texture; } #endif @@ -1806,7 +1804,7 @@ void Media_PlayFilm_f (void) -#if defined(RGLQUAKE) +#if defined(GLQUAKE) #if defined(WINAVI) #define WINAVIRECORDING PAVIFILE recordavi_file; @@ -1893,12 +1891,7 @@ void Media_RecordFrame (void) if (y < scr_con_current) y = scr_con_current; if (y > vid.height-8) y = vid.height-8; - qglColor4f(1, 0, 0, sin(realtime*4)/4+0.75); - qglEnable(GL_BLEND); - qglDisable(GL_ALPHA_TEST); - GL_TexEnv(GL_MODULATE); - qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - Draw_String((strlen(capturemessage.string)+1)*8, y, "PAUSED"); + Draw_FunString((strlen(capturemessage.string)+1)*8, y, S_COLOR_RED "PAUSED"); return; } @@ -1912,7 +1905,7 @@ void Media_RecordFrame (void) if (y < scr_con_current) y = scr_con_current; if (y > vid.height-8) y = vid.height-8; - Draw_String(0, y, capturemessage.string); + Draw_FunString(0, y, capturemessage.string); } //time for annother frame? @@ -1939,10 +1932,10 @@ void Media_RecordFrame (void) return; } //ask gl for it - qglReadPixels (glx, gly, glwidth, glheight, GL_RGB, GL_UNSIGNED_BYTE, framebuffer ); + qglReadPixels (0, 0, vid.pixelwidth, vid.pixelheight, GL_RGB, GL_UNSIGNED_BYTE, framebuffer ); // swap rgb to bgr - c = glwidth*glheight*3; + c = vid.pixelwidth*vid.pixelheight*3; for (i=0 ; i vid.height-8) y = vid.height-8; - qglColor4f(1, 0, 0, sin(realtime*4)/4+0.75); - qglEnable(GL_BLEND); - qglDisable(GL_ALPHA_TEST); - GL_TexEnv(GL_MODULATE); - qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - Draw_String((strlen(capturemessage.string)+1)*8, y, "RECORDING"); + Draw_FunString((strlen(capturemessage.string)+1)*8, y, S_COLOR_RED"RECORDING"); } } @@ -2262,12 +2250,12 @@ void Media_RecordFilm_f (void) memset(&bitmap_info_header, 0, sizeof(BITMAPINFOHEADER)); bitmap_info_header.biSize = 40; - bitmap_info_header.biWidth = glwidth; - bitmap_info_header.biHeight = glheight; + bitmap_info_header.biWidth = vid.pixelwidth; + bitmap_info_header.biHeight = vid.pixelheight; bitmap_info_header.biPlanes = 1; bitmap_info_header.biBitCount = 24; bitmap_info_header.biCompression = BI_RGB; - bitmap_info_header.biSizeImage = glwidth*glheight * 3; + bitmap_info_header.biSizeImage = vid.pixelwidth*vid.pixelheight * 3; memset(&stream_header, 0, sizeof(stream_header)); @@ -2275,7 +2263,7 @@ void Media_RecordFilm_f (void) stream_header.fccHandler = recordavi_codec_fourcc; stream_header.dwScale = 100; stream_header.dwRate = (unsigned long)(0.5 + 100.0/recordavi_frametime); - SetRect(&stream_header.rcFrame, 0, 0, glwidth, glheight); + SetRect(&stream_header.rcFrame, 0, 0, vid.pixelwidth, vid.pixelheight); hr = AVIFileCreateStream(recordavi_file, &recordavi_uncompressed_video_stream, &stream_header); if (FAILED(hr)) @@ -2350,7 +2338,7 @@ void Media_RecordFilm_f (void) // if (recordavi_wave_format.nSamplesPerSec) // captureaudiomem = BZ_Malloc(recordavi_wave_format.nSamplesPerSec*2); - capturevideomem = BZ_Malloc(glwidth*glheight*3); + capturevideomem = BZ_Malloc(vid.pixelwidth*vid.pixelheight*3); } #endif /* WINAVI */ else @@ -2376,13 +2364,13 @@ void Media_RecordDemo_f(void) else CL_Stopdemo_f(); //capturing failed for some reason } -#else /* RGLQUAKE */ +#else /* GLQUAKE */ void Media_CaptureDemoEnd(void){} void Media_RecordAudioFrame (short *sample_buffer, int samples){} double Media_TweekCaptureFrameTime(double time) { return time ; } void Media_RecordFrame (void) {} qboolean Media_PausedDemo (void) {return false;} //should not return a value -#endif /* RGLQUAKE */ +#endif /* GLQUAKE */ void Media_Init(void) { Cmd_AddCommand("playfilm", Media_PlayFilm_f); @@ -2391,7 +2379,7 @@ void Media_Init(void) Cmd_AddCommand("music_rewind", Media_Rewind_f); Cmd_AddCommand("music_next", Media_Next_f); -#if defined(RGLQUAKE) +#if defined(GLQUAKE) Cmd_AddCommand("capture", Media_RecordFilm_f); Cmd_AddCommand("capturedemo", Media_RecordDemo_f); Cmd_AddCommand("capturestop", Media_StopRecordFilm_f); diff --git a/engine/client/m_multi.c b/engine/client/m_multi.c index 1b37ada5..17ef6031 100644 --- a/engine/client/m_multi.c +++ b/engine/client/m_multi.c @@ -2,6 +2,7 @@ #include "quakedef.h" #include "winquake.h" +#include "shader.h" extern cvar_t maxclients; @@ -25,7 +26,7 @@ void M_Menu_MultiPlayer_f (void) if (mgt == MGT_QUAKE2) { - MC_AddCenterPicture(menu, 4, "pics/m_banner_multiplayer"); + MC_AddCenterPicture(menu, 4, 24, "pics/m_banner_multiplayer"); menu->selecteditem = (menuoption_t*) MC_AddConsoleCommand (menu, 64, 40, "Join network server", "menu_slist\n"); @@ -39,7 +40,7 @@ void M_Menu_MultiPlayer_f (void) } else if (mgt == MGT_HEXEN2) { - MC_AddCenterPicture(menu, 0, "gfx/menu/title4.lmp"); + MC_AddCenterPicture(menu, 0, 60, "gfx/menu/title4.lmp"); mgt=64; menu->selecteditem = (menuoption_t*) @@ -54,8 +55,8 @@ void M_Menu_MultiPlayer_f (void) } else if (QBigFontWorks()) { - MC_AddPicture(menu, 16, 4, "gfx/qplaque.lmp"); - MC_AddCenterPicture(menu, 4, "gfx/p_multi.lmp"); + MC_AddPicture(menu, 16, 4, 32, 144, "gfx/qplaque.lmp"); + MC_AddCenterPicture(menu, 4, 24, "gfx/p_multi.lmp"); mgt=32; menu->selecteditem = (menuoption_t*) @@ -74,9 +75,9 @@ void M_Menu_MultiPlayer_f (void) p = Draw_SafeCachePic("gfx/mp_menu.lmp"); if (p) { - MC_AddPicture(menu, 16, 4, "gfx/qplaque.lmp"); - MC_AddCenterPicture(menu, 4, "gfx/p_multi.lmp"); - MC_AddPicture(menu, 72, 32, "gfx/mp_menu.lmp"); + MC_AddPicture(menu, 16, 4, 32, 144, "gfx/qplaque.lmp"); + MC_AddCenterPicture(menu, 4, 24, "gfx/p_multi.lmp"); + MC_AddPicture(menu, 72, 32, 232, 64, "gfx/mp_menu.lmp"); } } @@ -260,7 +261,7 @@ void MSetupQ2_TransDraw (int x, int y, menucustom_t *option, menu_t *menu) p = Draw_SafeCachePic (va("players/%s_i", skin.string)); } if (p) - Draw_TransPic (x-12, y-8, p); + Draw_ScalePic (x-12, y-8, p->width, p->height, p); } void MSetup_TransDraw (int x, int y, menucustom_t *option, menu_t *menu) @@ -289,7 +290,7 @@ void MSetup_TransDraw (int x, int y, menucustom_t *option, menu_t *menu) p = Draw_SafeCachePic ("gfx/bigbox.lmp"); if (p) - Draw_TransPic (x-12, y-8, p); + Draw_ScalePic (x-12, y-8, 72, 72, p); M_BuildTranslationTable(info->topcolour*16, info->lowercolour*16); Draw_TransPicTranslate (x, y, info->tiwidth, info->tiheight, info->translationimage, translationTable); @@ -321,11 +322,11 @@ void M_Menu_Setup_f (void) info = menu->data; // menu->key = MC_Main_Key; - MC_AddPicture(menu, 0, 4, "pics/m_main_plaque"); + MC_AddPicture(menu, 0, 4, 38, 166, "pics/m_main_plaque"); p = Draw_SafeCachePic("pics/m_main_logo"); if (!p) return; - MC_AddPicture(menu, 0, 173, "pics/m_main_logo"); + MC_AddPicture(menu, 0, 173, 36, 42, "pics/m_main_logo"); menu->selecteditem = (menuoption_t*) (info->nameedit = MC_AddEdit(menu, 64, 40, "Your name", name.string)); @@ -369,8 +370,8 @@ void M_Menu_Setup_f (void) menu = M_CreateMenu(sizeof(setupmenu_t)); info = menu->data; - MC_AddPicture(menu, 16, 4, "gfx/qplaque.lmp"); - MC_AddCenterPicture(menu, 4, "gfx/p_multi.lmp"); + MC_AddPicture(menu, 16, 4, 32, 144, "gfx/qplaque.lmp"); + MC_AddCenterPicture(menu, 4, 24, "gfx/p_multi.lmp"); // MC_AddPicture(menu, 72, 32, Draw_CachePic ("gfx/mp_menu.lmp") ); @@ -563,7 +564,7 @@ void M_Menu_GameOptions_f (void) if (mgt == MGT_QUAKE2) { - MC_AddCenterPicture(menu, 4, "pics/m_banner_start_server"); + MC_AddCenterPicture(menu, 4, 24, "pics/m_banner_start_server"); y += 8; } else if (mgt == MGT_HEXEN2) @@ -571,8 +572,8 @@ void M_Menu_GameOptions_f (void) } else { - MC_AddPicture(menu, 16, 4, "gfx/qplaque.lmp"); - MC_AddCenterPicture(menu, 4, "gfx/p_multi.lmp"); + MC_AddPicture(menu, 16, 4, 32, 144, "gfx/qplaque.lmp"); + MC_AddCenterPicture(menu, 4, 24, "gfx/p_multi.lmp"); } // MC_AddPicture(menu, 72, 32, ("gfx/mp_menu.lmp") ); diff --git a/engine/client/m_options.c b/engine/client/m_options.c index ae815621..c791670a 100644 --- a/engine/client/m_options.c +++ b/engine/client/m_options.c @@ -52,19 +52,19 @@ void M_Menu_Options_f (void) mgt = M_GameType(); if (mgt == MGT_QUAKE2) { //q2... - MC_AddCenterPicture(menu, 4, "pics/m_banner_options"); + MC_AddCenterPicture(menu, 4, 24, "pics/m_banner_options"); y += 32; } else if (mgt == MGT_HEXEN2) { //h2 - MC_AddPicture(menu, 16, 0, "gfx/menu/hplaque.lmp"); - MC_AddCenterPicture(menu, 0, "gfx/menu/title3.lmp"); + MC_AddPicture(menu, 16, 0, 35, 176, "gfx/menu/hplaque.lmp"); + MC_AddCenterPicture(menu, 0, 60, "gfx/menu/title3.lmp"); y+=32; } else { //q1 - MC_AddPicture(menu, 16, 4, "gfx/qplaque.lmp"); - MC_AddCenterPicture(menu, 4, "gfx/p_option.lmp"); + MC_AddPicture(menu, 16, 4, 32, 144, "gfx/qplaque.lmp"); + MC_AddCenterPicture(menu, 4, 24, "gfx/p_option.lmp"); } menu->selecteditem = (union menuoption_s *) @@ -83,7 +83,8 @@ void M_Menu_Options_f (void) MC_AddCheckBox(menu, 16, y, " HUD on left side", &cl_hudswap,0); y+=8; MC_AddCheckBox(menu, 16, y, " Old-style chatting", &cl_standardchat,0);y+=8; MC_AddCheckBox(menu, 16, y, " Old-style messages", &cl_standardmsg,0);y+=8; - y+=4;MC_AddEditCvar(menu, 16, y, " Imitate FPS", "cl_netfps"); y+=8+4; + y+=4;MC_AddEditCvar(menu, 16, y," Imitate FPS", "cl_netfps"); y+=8+4; + y+=4;MC_AddEditCvar(menu, 16, y," Auto status format", "tp_autostatus"); y+=8+4; MC_AddConsoleCommand(menu, 16, y, " Video Options", "menu_video\n"); y+=8; MC_AddConsoleCommand(menu, 16, y, " FPS Options", "menu_fps\n"); y+=8; @@ -271,7 +272,7 @@ void M_Menu_Audio_f (void) if (mgt == MGT_QUAKE2) { - MC_AddCenterPicture(menu, 4, "pics/m_banner_options"); + MC_AddCenterPicture(menu, 4, 24, "pics/m_banner_options"); y += 32; } else if (mgt == MGT_HEXEN2) @@ -279,8 +280,8 @@ void M_Menu_Audio_f (void) } else { - MC_AddPicture(menu, 16, 4, "gfx/qplaque.lmp"); - MC_AddCenterPicture(menu, 4, "gfx/p_option.lmp"); + MC_AddPicture(menu, 16, 4, 32, 144, "gfx/qplaque.lmp"); + MC_AddCenterPicture(menu, 4, 24, "gfx/p_option.lmp"); } menu->selecteditem = (union menuoption_s *) @@ -338,7 +339,7 @@ void M_Menu_Particles_f (void) if (mgt == MGT_QUAKE2) { - MC_AddCenterPicture(menu, 4, "pics/m_banner_options"); + MC_AddCenterPicture(menu, 4, 24, "pics/m_banner_options"); y += 32; } else if (mgt == MGT_HEXEN2) @@ -346,8 +347,8 @@ void M_Menu_Particles_f (void) } else { - MC_AddPicture(menu, 16, 4, "gfx/qplaque.lmp"); - MC_AddCenterPicture(menu, 4, "gfx/p_option.lmp"); + MC_AddPicture(menu, 16, 4, 32, 144, "gfx/qplaque.lmp"); + MC_AddCenterPicture(menu, 4, 24, "gfx/p_option.lmp"); } menu->selecteditem = (union menuoption_s *) @@ -388,18 +389,21 @@ presetinfo_t preset[] = {"r_particlesystem", {"none", "classic", "script", "script", "script"}}, {"r_stains", {"0", "0", "0.75", "0.75", "0.75"}}, {"r_drawflat", {"1", "0", "0", "0", "0"}}, + {"gl_miptexLevel", {"3", "0", "0", "0", "0"}}, {"r_nolerp", {"1", "0", "0", "0", "0"}}, {"r_nolightdir", {"1", "1", "0", "0", "0"}}, - {"r_dynamic", {"0", "0", "1", "1", "1"}}, + {"r_dynamic", {"0", "0", "1", "0", "0"}}, {"r_bloom", {"0", "0", "0", "0", "1"}}, {"gl_flashblend", {"0", "1", "0", "1", "2"}}, {"gl_bump", {"0", "0", "0", "1", "1"}}, + {"r_skin_overlays", {"0", "0", "1", "1", "1"}}, {"gl_specular", {"0", "0", "0", "1", "1"}}, {"r_loadlit", {"0", "1", "1", "2", "2"}}, {"r_fastsky", {"1", "0", "0", "-1", "-1"}}, {"r_waterlayers", {"0", "2", "", "4", "4"}}, {"r_shadows", {"0", "0", "0", "1", "1"}}, {"r_shadow_realtime_world",{"0", "0", "0", "0", "1"}}, + {"r_shadow_realtime_dlight",{"0", "0", "0", "1", "1"}}, {"gl_detail", {"0", "0", "0", "1", "1"}}, {"gl_load24bit", {"0", "0", "1", "1", "1"}}, {"r_replacemodels", {"", "", "md3 md2", "md3 md2", "md3 md2"}}, @@ -441,12 +445,14 @@ void FPS_Preset_f (void) void M_Menu_FPS_f (void) { + char *loadlitoptions[] = {" off", " load", " generate", NULL}; + char *numbervalues[] = {"0", "1", "2"}; int y = 32; menu_t *menu; int mgt; int i, len; -#ifdef RGLQUAKE - extern cvar_t gl_compress, gl_detail, gl_bump, r_flashblend, r_shadow_realtime_world, gl_motionblur; +#ifdef GLQUAKE + extern cvar_t gl_compress, gl_detail, gl_bump, gl_specular, r_flashblend, r_shadow_realtime_world, r_shadow_realtime_dlight, gl_motionblur, r_nolightdir; #endif extern cvar_t r_stains, r_bloodstains, r_loadlits, r_dynamic, v_contentblend, show_fps; @@ -459,7 +465,7 @@ void M_Menu_FPS_f (void) if (mgt == MGT_QUAKE2) { - MC_AddCenterPicture(menu, 4, "pics/m_banner_options"); + MC_AddCenterPicture(menu, 4, 24, "pics/m_banner_options"); y += 32; } else if (mgt == MGT_HEXEN2) @@ -467,8 +473,8 @@ void M_Menu_FPS_f (void) } else { - MC_AddPicture(menu, 16, 4, "gfx/qplaque.lmp"); - MC_AddCenterPicture(menu, 4, "gfx/p_option.lmp"); + MC_AddPicture(menu, 16, 4, 32, 144, "gfx/qplaque.lmp"); + MC_AddCenterPicture(menu, 4, 24, "gfx/p_option.lmp"); } menu->selecteditem = (union menuoption_s *) @@ -480,27 +486,35 @@ void M_Menu_FPS_f (void) len = strlen(preset[0].value[i]); MC_AddConsoleCommand(menu, 48+8*(9-len), y, va("(preset) %s", preset[0].value[i]), va("fps_preset %s\n", preset[0].value[i])); y+=8; } + MC_AddCheckBox(menu, 48, y, " Show FPS", &show_fps,0);y+=8; MC_AddCheckBox(menu, 48, y, " Content blend", &v_contentblend,0);y+=8; - MC_AddCheckBox(menu, 48, y, " Dynamic lights", &r_dynamic,0);y+=8; - MC_AddCheckBox(menu, 48, y, " Stainmaps", &r_stains,0);y+=8; - y+=4;MC_AddEditCvar(menu, 48, y, " Skybox", "r_skybox");y+=8;y+=4; + y+=4;MC_AddEditCvar(menu, 48, y, " Skybox", "r_skybox");y+=8;y+=4; switch(qrenderer) { -#ifdef RGLQUAKE +#ifdef GLQUAKE case QR_OPENGL: - MC_AddCheckBox(menu, 48, y, " Blood stains", &r_bloodstains,0);y+=8; - MC_AddCheckBox(menu, 48, y, " Load .lit files", &r_loadlits,0);y+=8; - MC_AddCheckBox(menu, 48, y, " Flashblending", &r_flashblend,0);y+=8; + MC_AddCvarCombo(menu, 48, y, " Coloured lighting", &r_loadlits, loadlitoptions, numbervalues);y+=8; + MC_AddCheckBox(menu, 48, y, " 32 bit textures", &gl_load24bit,0);y+=8; MC_AddCheckBox(menu, 48, y, " Detail Texturing", &gl_detail,0);y+=8; MC_AddCheckBox(menu, 48, y, " Bumpmaps", &gl_bump,0);y+=8; + MC_AddCheckBox(menu, 48, y, " Specular Textures", &gl_specular,0);y+=8; MC_AddCheckBox(menu, 48, y, " Tex Compression", &gl_compress,0);y+=8; - MC_AddCheckBox(menu, 48, y, " 32 bit textures", &gl_load24bit,0);y+=8; - MC_AddCheckBox(menu, 48, y, " Dynamic shadows", &r_shadows,0);y+=8; - MC_AddCheckBox(menu, 48, y, " Realtime Lights", &r_shadow_realtime_world,0);y+=8; + + MC_AddCheckBox(menu, 48, y, " Stainmaps", &r_stains,0);y+=8; + MC_AddCheckBox(menu, 48, y, " Blood stains", &r_bloodstains,0);y+=8; + + MC_AddCheckBox(menu, 48, y, " Flat mdl Lighting", &r_nolightdir,0);y+=8; + MC_AddCheckBox(menu, 48, y, "Old Dynamic lights", &r_dynamic,0);y+=8; + MC_AddCheckBox(menu, 48, y, " Flashblending", &r_flashblend,0);y+=8; + MC_AddCheckBox(menu, 48, y, " Realtime DLights", &r_shadow_realtime_dlight,0);y+=8; + MC_AddCheckBox(menu, 48, y, " DLights Shadows", &r_shadow_realtime_dlight_shadows,0);y+=8; + MC_AddCheckBox(menu, 48, y, " Realtime WLights", &r_shadow_realtime_world,0);y+=8; + MC_AddCheckBox(menu, 48, y, " World Shadows", &r_shadow_realtime_world_shadows,0);y+=8; + MC_AddCheckBox(menu, 48, y, " Waterwarp", &r_waterwarp,0);y+=8; MC_AddSlider(menu, 48, y, " Motion blur", &gl_motionblur, 0, 0.99, 0);y+=8; break; diff --git a/engine/client/m_script.c b/engine/client/m_script.c index b81234d3..bba4ccf3 100644 --- a/engine/client/m_script.c +++ b/engine/client/m_script.c @@ -1,6 +1,7 @@ //read menu.h #include "quakedef.h" +#include "shader.h" int selectitem; menu_t *menu_script; @@ -145,6 +146,7 @@ void M_MenuS_Picture_f (void) int x = atoi(Cmd_Argv(1)); int y = atoi(Cmd_Argv(2)); char *picname = Cmd_Argv(3); + mpic_t *p; if (!menu_script) { @@ -152,10 +154,14 @@ void M_MenuS_Picture_f (void) return; } + p = Draw_SafeCachePic(picname); + if (!p) + return; + if (!strcmp(Cmd_Argv(1), "-")) - MC_AddCenterPicture(menu_script, y, picname); + MC_AddCenterPicture(menu_script, y, p->height, picname); else - MC_AddPicture(menu_script, x, y, picname); + MC_AddPicture(menu_script, x, y, p->width, p->height, picname); } void M_MenuS_Edit_f (void) diff --git a/engine/client/m_single.c b/engine/client/m_single.c index 06aec591..7167c2fa 100644 --- a/engine/client/m_single.c +++ b/engine/client/m_single.c @@ -2,6 +2,7 @@ #include "quakedef.h" #include "winquake.h" +#include "shader.h" #ifndef CLIENTONLY //============================================================================= /* LOAD/SAVE MENU */ @@ -79,7 +80,7 @@ void M_Menu_Save_f (void) menu = M_CreateMenu(sizeof(loadsavemenuinfo_t)); menu->data = menu+1; - MC_AddCenterPicture (menu, 4, "gfx/p_save.lmp"); + MC_AddCenterPicture (menu, 4, 24, "gfx/p_save.lmp"); menu->cursoritem = (menuoption_t *)MC_AddRedText(menu, 8, 32, NULL, false); M_ScanSaves (); @@ -103,7 +104,7 @@ void M_Menu_Load_f (void) menu = M_CreateMenu(sizeof(loadsavemenuinfo_t)); menu->data = menu+1; - MC_AddCenterPicture(menu, 4, "gfx/p_load.lmp"); + MC_AddCenterPicture(menu, 4, 24, "gfx/p_load.lmp"); menu->cursoritem = (menuoption_t *)MC_AddRedText(menu, 8, 32, NULL, false); M_ScanSaves (); @@ -124,22 +125,31 @@ void M_Menu_Load_f (void) void M_Menu_SinglePlayer_f (void) { - int mgt; -#ifndef CLIENTONLY - menubutton_t *b; -#endif menu_t *menu; +#ifndef CLIENTONLY + int mgt; + menubutton_t *b; mpic_t *p; +#endif key_dest = key_menu; m_state = m_complex; +#ifdef CLIENTONLY + menu = M_CreateMenu(0); + + MC_AddWhiteText(menu, 84, 12*8, "This build is unable", false); + MC_AddWhiteText(menu, 84, 13*8, "to start a local game", false); + + MC_AddBox (menu, 60, 10*8, 25, 4); +#else + mgt = M_GameType(); if (mgt == MGT_QUAKE2) { //q2... menu = M_CreateMenu(0); - MC_AddCenterPicture(menu, 4, "pics/m_banner_game"); + MC_AddCenterPicture(menu, 4, 24, "pics/m_banner_game"); menu->selecteditem = (menuoption_t*) MC_AddConsoleCommand (menu, 64, 40, "Easy", "skill 0;deathmatch 0; coop 0;newgame\n"); @@ -174,8 +184,8 @@ void M_Menu_SinglePlayer_f (void) NULL }; menu = M_CreateMenu(0); - MC_AddPicture(menu, 16, 0, "gfx/menu/hplaque.lmp"); - MC_AddCenterPicture(menu, 0, "gfx/menu/title1.lmp"); + MC_AddPicture(menu, 16, 0, 35, 176, "gfx/menu/hplaque.lmp"); + MC_AddCenterPicture(menu, 0, 60, "gfx/menu/title1.lmp"); menu->selecteditem = (menuoption_t*) MC_AddConsoleCommand (menu, 64, 64, "Easy", "closemenu\nskill 0;deathmatch 0; coop 0;map demo1\n"); @@ -194,8 +204,8 @@ void M_Menu_SinglePlayer_f (void) else if (QBigFontWorks()) { menu = M_CreateMenu(0); - MC_AddPicture(menu, 16, 0, "gfx/qplaque.lmp"); - MC_AddCenterPicture(menu, 0, "gfx/p_option.lmp"); + MC_AddPicture(menu, 16, 4, 32, 144, "gfx/qplaque.lmp"); + MC_AddCenterPicture(menu, 0, 24, "gfx/p_option.lmp"); menu->selecteditem = (menuoption_t*) MC_AddConsoleCommandQBigFont (menu, 72, 32, "New Game", "closemenu\nmaxclients 1;deathmatch 0;coop 0;map start\n"); @@ -208,8 +218,8 @@ void M_Menu_SinglePlayer_f (void) else { //q1 menu = M_CreateMenu(0); - MC_AddPicture(menu, 16, 4, "gfx/qplaque.lmp"); - MC_AddCenterPicture(menu, 4, "gfx/p_option.lmp"); + MC_AddPicture(menu, 16, 4, 32, 144, "gfx/qplaque.lmp"); + MC_AddCenterPicture(menu, 4, 24, "gfx/p_option.lmp"); } p = Draw_SafeCachePic("gfx/sp_menu.lmp"); @@ -222,28 +232,22 @@ void M_Menu_SinglePlayer_f (void) } else { -#ifdef CLIENTONLY - MC_AddWhiteText(menu, 92, 12*8, "QuakeWorld is for", false); - MC_AddWhiteText(menu, 92, 13*8, "Internet play only", false); + MC_AddPicture(menu, 72, 32, 232, 64, "gfx/sp_menu.lmp"); - MC_AddBox (menu, 60, 10*8, 23, 4); -#else - MC_AddPicture(menu, 72, 32, "gfx/sp_menu.lmp"); - - b = MC_AddConsoleCommand (menu, 16, 32, "", "closemenu\nmaxclients 1;deathmatch 0;coop 0;map start\n"); - menu->selecteditem = (menuoption_t *)b; - b->common.width = p->width; - b->common.height = 20; - b = MC_AddConsoleCommand (menu, 16, 52, "", "menu_load\n"); - b->common.width = p->width; - b->common.height = 20; - b = MC_AddConsoleCommand (menu, 16, 72, "", "menu_save\n"); - b->common.width = p->width; - b->common.height = 20; + b = MC_AddConsoleCommand (menu, 16, 32, "", "closemenu\nmaxclients 1;deathmatch 0;coop 0;map start\n"); + menu->selecteditem = (menuoption_t *)b; + b->common.width = p->width; + b->common.height = 20; + b = MC_AddConsoleCommand (menu, 16, 52, "", "menu_load\n"); + b->common.width = p->width; + b->common.height = 20; + b = MC_AddConsoleCommand (menu, 16, 72, "", "menu_save\n"); + b->common.width = p->width; + b->common.height = 20; - menu->cursoritem = (menuoption_t*)MC_AddCursor(menu, 54, 32); -#endif + menu->cursoritem = (menuoption_t*)MC_AddCursor(menu, 54, 32); } +#endif } @@ -312,9 +316,9 @@ static void M_DemoDraw(int x, int y, menucustom_t *control, menu_t *menu) else text = item->name+info->pathlen; if (item == info->selected) - Draw_Alt_String(x, y+8, text); + Draw_AltFunString(x, y+8, text); else - Draw_String(x, y+8, text); + Draw_FunString(x, y+8, text); y+=8; item = item->next; } diff --git a/engine/client/menu.c b/engine/client/menu.c index a549f4f3..aee33a5a 100644 --- a/engine/client/menu.c +++ b/engine/client/menu.c @@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "quakedef.h" #include "winquake.h" +#include "shader.h" void M_Menu_Audio_f (void); void M_Menu_Demos_f (void); @@ -47,60 +48,17 @@ cvar_t m_helpismedia = SCVAR("m_helpismedia", "0"); //============================================================================= /* Support Routines */ -/* -================ -M_DrawCharacter - -Draws one solid graphics character -================ -*/ -void M_DrawCharacter (int cx, int line, unsigned int num) -{ - Draw_Character ( cx + ((vid.width - 320)>>1), line, num); -} - -void M_DrawColouredCharacter (int cx, int line, unsigned int num) -{ - Draw_ColouredCharacter( cx + ((vid.width - 320)>>1), line, num); -} void M_Print (int cx, int cy, qbyte *str) { - while (*str) - { - M_DrawCharacter (cx, cy, (*str)|CON_HIGHCHARSMASK); - str++; - cx += 8; - } + Draw_AltFunString(cx + ((vid.width - 320)>>1), cy, str); } - -void M_PrintColoured (int cx, int cy, int colour, qbyte *str) -{ - while (*str) - { - M_DrawColouredCharacter (cx, cy, (*str) + (colour<>1), cy, str); } - -void M_DrawTransPic (int x, int y, mpic_t *pic) +void M_DrawScalePic (int x, int y, int w, int h, mpic_t *pic) { - Draw_TransPic (x + ((vid.width - 320)>>1), y, pic); -} - -void M_DrawPic (int x, int y, mpic_t *pic) -{ - Draw_Pic (x + ((vid.width - 320)>>1), y, pic); + Draw_ScalePic (x + ((vid.width - 320)>>1), y, w, h, pic); } qbyte identityTable[256]; @@ -149,17 +107,17 @@ void M_DrawTextBox (int x, int y, int width, int lines) p = Draw_SafeCachePic ("gfx/box_tl.lmp"); if (!p) return; //assume we can't find any - M_DrawTransPic (cx, cy, p); + M_DrawScalePic (cx, cy, 8, 8, p); p = Draw_SafeCachePic ("gfx/box_ml.lmp"); if (p) for (n = 0; n < lines; n++) { cy += 8; - M_DrawTransPic (cx, cy, p); + M_DrawScalePic (cx, cy, 8, 8, p); } p = Draw_SafeCachePic ("gfx/box_bl.lmp"); if (p) - M_DrawTransPic (cx, cy+8, p); + M_DrawScalePic (cx, cy+8, 8, 8, p); // draw middle cx += 8; @@ -168,7 +126,7 @@ void M_DrawTextBox (int x, int y, int width, int lines) cy = y; p = Draw_SafeCachePic ("gfx/box_tm.lmp"); if (p) - M_DrawTransPic (cx, cy, p); + M_DrawScalePic (cx, cy, 16, 8, p); p = Draw_SafeCachePic ("gfx/box_mm.lmp"); if (p) for (n = 0; n < lines; n++) @@ -180,11 +138,11 @@ void M_DrawTextBox (int x, int y, int width, int lines) if (!p) break; } - M_DrawTransPic (cx, cy, p); + M_DrawScalePic (cx, cy, 16, 8, p); } p = Draw_SafeCachePic ("gfx/box_bm.lmp"); if (p) - M_DrawTransPic (cx, cy+8, p); + M_DrawScalePic (cx, cy+8, 16, 8, p); width -= 2; cx += 16; } @@ -193,17 +151,17 @@ void M_DrawTextBox (int x, int y, int width, int lines) cy = y; p = Draw_SafeCachePic ("gfx/box_tr.lmp"); if (p) - M_DrawTransPic (cx, cy, p); + M_DrawScalePic (cx, cy, 8, 8, p); p = Draw_SafeCachePic ("gfx/box_mr.lmp"); if (p) for (n = 0; n < lines; n++) { cy += 8; - M_DrawTransPic (cx, cy, p); + M_DrawScalePic (cx, cy, 8, 8, p); } p = Draw_SafeCachePic ("gfx/box_br.lmp"); if (p) - M_DrawTransPic (cx, cy+8, p); + M_DrawScalePic (cx, cy+8, 8, 8, p); } //============================================================================= @@ -235,6 +193,10 @@ void M_ToggleMenu_f (void) if (MP_Toggle()) return; #endif +#ifdef VM_UI + if (UI_OpenMenu()) + return; +#endif if (key_dest == key_menu) { @@ -255,39 +217,6 @@ void M_ToggleMenu_f (void) } } -//============================================================================= -/* OPTIONS MENU */ -#define SLIDER_RANGE 10 - -void M_DrawSlider (int x, int y, float range) -{ - int i; - - if (range < 0) - range = 0; - if (range > 1) - range = 1; - M_DrawCharacter (x-8, y, 128); - for (i=0 ; iwidth)/2, 4, p); - - if (bind_grab) - M_Print (12, 32, "Press a key or button for this action"); - else - M_Print (18, 32, "Enter to change, backspace to clear"); - -// search for known bindings - for (i=0 ; ; i++) - { - if (!bindnames[i].command) - break; - y = 48 + 8*i; - - M_Print (16, y, bindnames[i].name); - - l = strlen (bindnames[i].command); - - M_FindKeysForCommand (bindnames[i].command, keys); - - if (keys[0] == -1) - { - M_Print (140, y, "???"); - } - else - { - name = Key_KeynumToString (keys[0]); - M_Print (140, y, name); - x = strlen(name) * 8; - if (keys[1] != -1) - { - M_Print (140 + x + 8, y, "or"); - M_Print (140 + x + 32, y, Key_KeynumToString (keys[1])); - } - } - } - - if (bind_grab) - M_DrawCharacter (130, 48 + keys_cursor*8, '='); - else - M_DrawCharacter (130, 48 + keys_cursor*8, 12+((int)(realtime*4)&1)); -} - - -void M_Keys_Key (int k) -{ - char cmd[80]; - int keys[2]; - - if (bind_grab) - { // defining a key - S_LocalSound ("misc/menu1.wav"); - if (k == K_ESCAPE) - { - bind_grab = false; - } - else if (k != '`') - { - sprintf (cmd, "bind %s \"%s\"\n", Key_KeynumToString (k), bindnames[keys_cursor].command); - Cbuf_InsertText (cmd, RESTRICT_LOCAL, false); - } - - bind_grab = false; - return; - } - - switch (k) - { - case K_ESCAPE: - M_Menu_Options_f (); - break; - - case K_LEFTARROW: - case K_UPARROW: - S_LocalSound ("misc/menu1.wav"); - keys_cursor--; - if (keys_cursor < 0) - keys_cursor = numbindnames-1; - break; - - case K_DOWNARROW: - case K_RIGHTARROW: - S_LocalSound ("misc/menu1.wav"); - keys_cursor++; - if (keys_cursor >= numbindnames) - keys_cursor = 0; - break; - - case K_ENTER: // go into bind mode - M_FindKeysForCommand (bindnames[keys_cursor].command, keys); - S_LocalSound ("misc/menu2.wav"); - if (keys[1] != -1) - M_UnbindCommand (bindnames[keys_cursor].command); - bind_grab = true; - break; - - case K_BACKSPACE: // delete bindings - case K_DEL: // delete bindings - S_LocalSound ("misc/menu2.wav"); - M_UnbindCommand (bindnames[keys_cursor].command); - break; - } -} - //============================================================================= /* HELP MENU */ @@ -639,7 +453,7 @@ void M_Help_Draw (void) if (!pic) M_Menu_Main_f (); else - M_DrawPic (0, 0, pic); + M_DrawScalePic (0, 0, 320, 200, pic); } @@ -974,7 +788,6 @@ void M_DeInit_Internal (void) #endif Cmd_RemoveCommand ("menu_setup"); Cmd_RemoveCommand ("menu_newmulti"); - Cmd_RemoveCommand ("menu_main"); //I've moved main to last because that way tab give us main and not quit. Cmd_RemoveCommand ("menu_options"); Cmd_RemoveCommand ("menu_video"); @@ -986,6 +799,8 @@ void M_DeInit_Internal (void) Cmd_RemoveCommand ("menu_download"); + + Cmd_RemoveCommand ("menu_main"); //I've moved main to last because that way tab give us main and not quit. Cmd_RemoveCommand ("quickconnect"); } @@ -1043,15 +858,13 @@ void M_Draw (int uimenu) m_recursiveDraw = false; } + Draw_ImageColours(1, 1, 1, 1); + switch (m_state) { case m_none: break; - case m_keys: - M_Keys_Draw (); - break; - case m_help: M_Help_Draw (); break; @@ -1089,10 +902,6 @@ void M_Keydown (int key, int unicode) key_dest = key_console; return; - case m_keys: - M_Keys_Key (key); - return; - case m_help: M_Help_Key (key); return; @@ -1106,7 +915,7 @@ void M_Keydown (int key, int unicode) return; case m_complex: - M_Complex_Key (key); + M_Complex_Key (key, unicode); return; #ifdef PLUGINS case m_plugin: @@ -1145,6 +954,7 @@ void M_Keyup (int key, int unicode) int M_GameType (void) { int cached; +#if defined(Q2CLIENT) int q1, h2, q2; q1 = COM_FDepthFile("gfx/sp_menu.lmp", true); @@ -1156,6 +966,7 @@ int M_GameType (void) else if (h2 < q1) cached = MGT_HEXEN2; else +#endif cached = MGT_QUAKE1; return cached; diff --git a/engine/client/menu.h b/engine/client/menu.h index c52ea1a1..684ede98 100644 --- a/engine/client/menu.h +++ b/engine/client/menu.h @@ -74,7 +74,7 @@ void M_SomeMenuConsoleCommand_f (void) int y = 32; //add the title - MC_AddCenterPicture(m, 4, "gfx/p_option.lmp"); + MC_AddCenterPicture(m, 4, 24, "gfx/p_option.lmp"); //add the blinking > thingie //(note NULL instead of a valid string, this should really be a variant of mt_menudot instead) @@ -113,7 +113,7 @@ void M_Menu_Quit_f (void); struct menu_s; -typedef enum {m_none, m_complex, m_help, m_keys, m_slist, m_media, m_plugin, m_menu_dat} m_state_t; +typedef enum {m_none, m_complex, m_help, m_slist, m_media, m_plugin, m_menu_dat} m_state_t; extern m_state_t m_state; typedef enum { @@ -132,7 +132,6 @@ typedef enum { mt_checkbox, mt_picture, mt_picturesel, - mt_strechpic, mt_menudot, mt_custom } menutype_t; @@ -284,10 +283,9 @@ menutext_t *MC_AddRedText(menu_t *menu, int x, int y, const char *text, qboolean menutext_t *MC_AddWhiteText(menu_t *menu, int x, int y, const char *text, qboolean rightalign); menubind_t *MC_AddBind(menu_t *menu, int x, int y, const char *caption, char *command); menubox_t *MC_AddBox(menu_t *menu, int x, int y, int width, int height); -menupicture_t *MC_AddPicture(menu_t *menu, int x, int y, char *picname); +menupicture_t *MC_AddPicture(menu_t *menu, int x, int y, int width, int height, char *picname); menupicture_t *MC_AddSelectablePicture(menu_t *menu, int x, int y, char *picname); -menupicture_t *MC_AddStrechPicture(menu_t *menu, int x, int y, int width, int height, char *picname); -menupicture_t *MC_AddCenterPicture(menu_t *menu, int y, char *picname); +menupicture_t *MC_AddCenterPicture(menu_t *menu, int y, int height, char *picname); menupicture_t *MC_AddCursor(menu_t *menu, int x, int y); menuslider_t *MC_AddSlider(menu_t *menu, int x, int y, const char *text, cvar_t *var, float min, float max, float delta); menucheck_t *MC_AddCheckBox(menu_t *menu, int x, int y, const char *text, cvar_t *var, int cvarbitmask); @@ -311,9 +309,7 @@ void M_HideMenu (menu_t *menu); void M_RemoveMenu (menu_t *menu); void M_RemoveAllMenus (void); -void DrawCursor(void); - -void M_Complex_Key(int key); +void M_Complex_Key(int key, int unicode); void M_Complex_Draw(void); void M_Script_Init(void); void M_Serverlist_Init(void); @@ -346,7 +342,6 @@ void M_Main_Draw (void); void M_Setup_Draw (void); void M_Net_Draw (void); void M_Options_Draw (void); - void M_Keys_Draw (void); void M_Video_Draw (void); void M_Help_Draw (void); void M_Quit_Draw (void); @@ -366,7 +361,6 @@ void M_Main_Key (int key); void M_Setup_Key (int key); void M_Net_Key (int key); void M_Options_Key (int key); - void M_Keys_Key (int key); void M_Video_Key (int key); void M_Help_Key (int key); void M_Quit_Key (int key); @@ -384,12 +378,11 @@ void M_SListKey(int key); //drawing funcs void M_BuildTranslationTable(int top, int bottom); -void M_DrawTransPicTranslate (int x, int y, mpic_t *pic); -void M_DrawTransPic (int x, int y, mpic_t *pic); +FTE_DEPRECATED void M_DrawTransPicTranslate (int x, int y, mpic_t *pic); void M_DrawCharacter (int cx, int line, unsigned int num); void M_Print (int cx, int cy, qbyte *str); void M_PrintWhite (int cx, int cy, qbyte *str); -void M_DrawPic (int x, int y, mpic_t *pic); +void M_DrawScalePic (int x, int y, int w, int h, mpic_t *pic); void M_FindKeysForCommand (char *command, int *twokeys); diff --git a/engine/client/merged.h b/engine/client/merged.h index 2855ed0e..87e2ee04 100644 --- a/engine/client/merged.h +++ b/engine/client/merged.h @@ -52,24 +52,15 @@ extern r_qrenderer_t qrenderer; extern char *q_renderername; extern mpic_t *(*Draw_SafePicFromWad) (char *name); -extern mpic_t *(*Draw_CachePic) (char *path); extern mpic_t *(*Draw_SafeCachePic) (char *path); extern void (*Draw_Init) (void); -extern void (*Draw_ReInit) (void); -extern void (*Draw_Character) (int x, int y, unsigned int num); extern void (*Draw_TinyCharacter) (int x, int y, unsigned int num); -extern void (*Draw_ColouredCharacter) (int x, int y, unsigned int num); -extern void (*Draw_String) (int x, int y, const qbyte *str); -extern void (*Draw_Alt_String) (int x, int y, const qbyte *str); extern void (*Draw_Crosshair) (void); -extern void (*Draw_DebugChar) (qbyte num); -extern void (*Draw_Pic) (int x, int y, mpic_t *pic); extern void (*Draw_ScalePic) (int x, int y, int width, int height, mpic_t *pic); -extern void (*Draw_SubPic) (int x, int y, mpic_t *pic, int srcx, int srcy, int width, int height); -extern void (*Draw_TransPic) (int x, int y, mpic_t *pic); +extern void (*Draw_SubPic) (int x, int y, int width, int height, mpic_t *pic, int srcx, int srcy, int srcwidth, int srcheight); extern void (*Draw_TransPicTranslate) (int x, int y, int width, int height, qbyte *image, qbyte *translation); extern void (*Draw_ConsoleBackground) (int firstline, int lastline, qboolean forceopaque); -extern void (*Draw_EditorBackground) (int lines); +extern void (*Draw_EditorBackground) (void); extern void (*Draw_TileClear) (int x, int y, int w, int h); extern void (*Draw_Fill) (int x, int y, int w, int h, unsigned int c); extern void (*Draw_FillRGB) (int x, int y, int w, int h, float r, float g, float b); @@ -83,12 +74,8 @@ extern void (*Draw_ImageColours) (float r, float g, float b, float a); extern void (*R_Init) (void); extern void (*R_DeInit) (void); -extern void (*R_ReInit) (void); extern void (*R_RenderView) (void); // must set r_refdef first -extern qboolean (*R_CheckSky) (void); -extern void (*R_SetSky) (char *name, float rotate, vec3_t axis); - extern void (*R_NewMap) (void); extern void (*R_PreNewMap) (void); extern int (*R_LightPoint) (vec3_t point); @@ -96,7 +83,6 @@ extern int (*R_LightPoint) (vec3_t point); extern void (*R_PushDlights) (void); extern void (*R_AddStain) (vec3_t org, float red, float green, float blue, float radius); extern void (*R_LessenStains) (void); -extern void (*R_DrawWaterSurfaces) (void); extern void (*Media_ShowFrameBGR_24_Flip) (qbyte *framedata, int inwidth, int inheight); //input is bottom up... extern void (*Media_ShowFrameRGBA_32) (qbyte *framedata, int inwidth, int inheight); //top down @@ -151,8 +137,9 @@ int Mod_GetBoneRelations(struct model_s *model, int firstbone, int lastbone, fra int Mod_GetBoneParent(struct model_s *model, int bonenum); char *Mod_GetBoneName(struct model_s *model, int bonenum); -void Draw_FunString(int x, int y, unsigned char *str); -void Draw_FunStringLen(int x, int y, unsigned char *str, int len); +void Draw_FunString(int x, int y, const unsigned char *str); +void Draw_AltFunString(int x, int y, const unsigned char *str); +void Draw_FunStringWidth(int x, int y, const unsigned char *str, int width); #ifdef SERVERONLY @@ -168,24 +155,15 @@ typedef struct { r_qrenderer_t rtype; mpic_t *(*Draw_SafePicFromWad) (char *name); - mpic_t *(*Draw_CachePic) (char *path); mpic_t *(*Draw_SafeCachePic) (char *path); void (*Draw_Init) (void); - void (*Draw_ReInit) (void); - void (*Draw_Character) (int x, int y, unsigned int num); - void (*Draw_ColouredCharacter) (int x, int y, unsigned int num); - void (*Draw_TinyCharacter) (int x, int y, unsigned int num); - void (*Draw_String) (int x, int y, const qbyte *str); - void (*Draw_Alt_String) (int x, int y, const qbyte *str); + void (*Draw_Shutdown) (void); void (*Draw_Crosshair) (void); - void (*Draw_DebugChar) (qbyte num); - void (*Draw_Pic) (int x, int y, mpic_t *pic); void (*Draw_ScalePic) (int x, int y, int width, int height, mpic_t *pic); - void (*Draw_SubPic) (int x, int y, mpic_t *pic, int srcx, int srcy, int width, int height); - void (*Draw_TransPic) (int x, int y, mpic_t *pic); + void (*Draw_SubPic) (int x, int y, int width, int height, mpic_t *pic, int srcx, int srcy, int srcwidth, int srcheight); void (*Draw_TransPicTranslate) (int x, int y, int w, int h, qbyte *pic, qbyte *translation); void (*Draw_ConsoleBackground) (int firstline, int lastline, qboolean forceopaque); - void (*Draw_EditorBackground) (int lines); + void (*Draw_EditorBackground) (void); void (*Draw_TileClear) (int x, int y, int w, int h); void (*Draw_Fill) (int x, int y, int w, int h, unsigned int c); void (*Draw_FillRGB) (int x, int y, int w, int h, float r, float g, float b); @@ -198,12 +176,8 @@ typedef struct { void (*R_Init) (void); void (*R_DeInit) (void); - void (*R_ReInit) (void); void (*R_RenderView) (void); // must set r_refdef first - qboolean (*R_CheckSky) (void); - void (*R_SetSky) (char *name, float rotate, vec3_t axis); - void (*R_NewMap) (void); void (*R_PreNewMap) (void); int (*R_LightPoint) (vec3_t point); diff --git a/engine/client/net_master.c b/engine/client/net_master.c index 142dd578..f159701e 100644 --- a/engine/client/net_master.c +++ b/engine/client/net_master.c @@ -584,7 +584,7 @@ void Master_AddMaster (char *address, int type, char *description) #pragma message("Master_AddMaster: add ipv6. don't care about tcp/irc.") if (adr.type != NA_IP && adr.type != NA_IPX) { - Con_Printf("Fixme: unable to poll address family\n", address); + Con_Printf("Fixme: unable to poll address family for \"%s\"\n", address); return; } diff --git a/engine/client/p_classic.c b/engine/client/p_classic.c index cb3fe164..9bdfb308 100644 --- a/engine/client/p_classic.c +++ b/engine/client/p_classic.c @@ -22,6 +22,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef PSET_CLASSIC #include "glquake.h" +#include "shader.h" +#include "renderque.h" void D_DrawParticleTrans (vec3_t porg, float palpha, float pscale, unsigned int pcolour, blendmode_t blendmode); @@ -51,8 +53,14 @@ typedef enum { } effect_type_t; -typedef struct cparticle_s { - enum { +typedef struct cparticle_s +{ + avec3_t org; + float die; + avec3_t vel; + float ramp; + enum + { pt_static, pt_fire, pt_explode, @@ -62,10 +70,6 @@ typedef struct cparticle_s { pt_grav, pt_slowgrav } type; - float die; - vec3_t org; - vec3_t vel; - float ramp; unsigned char color; struct cparticle_s *next; } cparticle_t; @@ -81,6 +85,21 @@ static int ramp2[8] = {0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66}; static int ramp3[8] = {0x6d, 0x6b, 6, 5, 4, 3}; + +#define BUFFERVERTS 2048*3 +static vecV_t classicverts[BUFFERVERTS]; +static union c +{ + byte_vec4_t b; + unsigned int i; +} classiccolours[BUFFERVERTS]; +static vec2_t classictexcoords[BUFFERVERTS]; +index_t classicindexes[BUFFERVERTS]; +static mesh_t classicmesh; +static shader_t *classicshader; + + + //obtains an index for the name, even if it is unknown (one can be loaded after. will only fail if the effect limit is reached) //technically this function is not meant to fail often, but thats fine so long as the other functions are meant to safely reject invalid effect numbers. static int PClassic_ParticleTypeForName(char *name) @@ -172,10 +191,13 @@ static void PClassic_InitParticles (void) extern model_t mod_known[]; extern int mod_numknown; - if ((i = COM_CheckParm ("-particles")) && i + 1 < com_argc) { + if ((i = COM_CheckParm ("-particles")) && i + 1 < com_argc) + { r_numparticles = (int) (Q_atoi(com_argv[i + 1])); r_numparticles = bound(ABSOLUTE_MIN_PARTICLES, r_numparticles, ABSOLUTE_MAX_PARTICLES); - } else { + } + else + { r_numparticles = DEFAULT_NUM_PARTICLES; } @@ -191,6 +213,31 @@ static void PClassic_InitParticles (void) P_DefaultTrail(mod); } + + for (i = 0; i < BUFFERVERTS; i += 3) + { + classictexcoords[i+1][0] = 1; + classictexcoords[i+2][1] = 1; + + classicindexes[i+0] = i+0; + classicindexes[i+1] = i+1; + classicindexes[i+2] = i+2; + } + classicmesh.xyz_array = classicverts; + classicmesh.st_array = classictexcoords; + classicmesh.colors4b_array = (byte_vec4_t*)classiccolours; + classicmesh.indexes = classicindexes; + classicshader = R_RegisterShader("particles_classic", + "{\n" + "{\n" + "map $diffuse\n" + "rgbgen vertex\n" + "alphagen vertex\n" + "blendfunc blend\n" + "}\n" + "}\n" + ); + classicshader->defaulttextures.base = particlecqtexture; } static void PClassic_ShutdownParticles(void) @@ -217,87 +264,27 @@ static void PClassic_ClearParticles (void) particles[r_numparticles - 1].next = NULL; } -#define USEARRAYS - -#define BUFFERVERTS 2048*3 -vec3_t classicverts[BUFFERVERTS]; -union c -{ - byte_vec4_t b; - unsigned int i; -} classiccolours[BUFFERVERTS]; -vec2_t classictexcoords[BUFFERVERTS]; -int classicnumverts; -int setuptexcoords; - //draws all the active particles. static void PClassic_DrawParticles(void) { - RSpeedLocals(); - cparticle_t *p, *kill; int i; float time2, time3, time1, dvel, frametime, grav; -#ifdef RGLQUAKE -#ifndef USEARRAYS - unsigned char *at, theAlpha; -#endif vec3_t up, right; float dist, scale, r_partscale=0; - union c usecolours; -#endif + RSpeedMark(); + + RQ_RenderDistAndClear(); if (!active_particles) { - RQ_RenderDistAndClear(); return; } - switch(qrenderer) - { -#ifdef RGLQUAKE - case QR_OPENGL: - r_partscale = 0.004 * tan (r_refdef.fov_x * (M_PI / 180) * 0.5f); - - GL_Bind(particlecqtexture); - - qglEnable (GL_BLEND); - if (!gl_solidparticles.value) - qglDepthMask (GL_FALSE); - qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - -#ifdef USEARRAYS - if (!setuptexcoords) - { - setuptexcoords = true; - for (i = 0; i < BUFFERVERTS; i += 3) - { - classictexcoords[i+1][0] = 1; - classictexcoords[i+2][1] = 1; - } - } - qglTexCoordPointer(2, GL_FLOAT, 0, classictexcoords); - qglVertexPointer(3, GL_FLOAT, 0, classicverts); - qglColorPointer(4, GL_UNSIGNED_BYTE, 0, classiccolours); - - qglEnableClientState(GL_TEXTURE_COORD_ARRAY); - qglEnableClientState(GL_COLOR_ARRAY); - qglEnableClientState(GL_VERTEX_ARRAY); -#else - qglBegin (GL_TRIANGLES); -#endif - - VectorScale (vup, 1.5, up); - VectorScale (vright, 1.5, right); - - classicnumverts = 0; - break; -#endif - default: - RQ_RenderDistAndClear(); - return; - } + r_partscale = 0.004 * tan (r_refdef.fov_x * (M_PI / 180) * 0.5f); + VectorScale (vup, 1.5, up); + VectorScale (vright, 1.5, right); frametime = host_frametime; if (cl.paused) @@ -336,54 +323,36 @@ static void PClassic_DrawParticles(void) break; } - switch(qrenderer) + if (classicmesh.numvertexes >= BUFFERVERTS-3) { -#ifdef RGLQUAKE - case QR_OPENGL: -#ifdef USEARRAYS - if (classicnumverts >= BUFFERVERTS-3) - { - qglDrawArrays(GL_TRIANGLES, 0, classicnumverts); - classicnumverts = 0; - } -#endif - - // hack a scale up to keep particles from disapearing - dist = (p->org[0] - r_origin[0]) * vpn[0] + (p->org[1] - r_origin[1]) * vpn[1] + (p->org[2] - r_origin[2]) * vpn[2]; - scale = 1 + dist * r_partscale; - -#ifdef USEARRAYS - usecolours.i = d_8to24rgbtable[(int)p->color]; - if (p->type == pt_fire) - usecolours.b[3] = 255 * (6 - p->ramp) / 6; - else - usecolours.b[3] = 255; - - classiccolours[classicnumverts].i = usecolours.i; - VectorCopy(p->org, classicverts[classicnumverts]); - classicnumverts++; - classiccolours[classicnumverts].i = usecolours.i; - VectorMA(p->org, scale, up, classicverts[classicnumverts]); - classicnumverts++; - classiccolours[classicnumverts].i = usecolours.i; - VectorMA(p->org, scale, right, classicverts[classicnumverts]); - classicnumverts++; -#else - - at = (qbyte *) &d_8to24rgbtable[(int)p->color]; - if (p->type == pt_fire) - theAlpha = 255 * (6 - p->ramp) / 6; - else - theAlpha = 255; - qglColor4ub (*at, *(at + 1), *(at + 2), theAlpha); - qglTexCoord2f (0, 0); qglVertex3fv (p->org); - qglTexCoord2f (1, 0); qglVertex3f (p->org[0] + up[0] * scale, p->org[1] + up[1] * scale, p->org[2] + up[2] * scale); - qglTexCoord2f (0, 1); qglVertex3f (p->org[0] + right[0] * scale, p->org[1] + right[1] * scale, p->org[2] + right[2] * scale); -#endif - break; -#endif + classicmesh.numindexes = classicmesh.numvertexes; + BE_DrawMeshChain(classicshader, &classicmesh, NULL, &classicshader->defaulttextures); + classicmesh.numvertexes = 0; } + // hack a scale up to keep particles from disapearing + dist = (p->org[0] - r_origin[0]) * vpn[0] + (p->org[1] - r_origin[1]) * vpn[1] + (p->org[2] - r_origin[2]) * vpn[2]; + scale = 1 + dist * r_partscale; + + + usecolours.i = d_8to24rgbtable[(int)p->color]; + if (p->type == pt_fire) + usecolours.b[3] = 255 * (6 - p->ramp) / 6; + else + usecolours.b[3] = 255; + classiccolours[classicmesh.numvertexes].i = usecolours.i; + VectorCopy(p->org, classicverts[classicmesh.numvertexes]); + classicmesh.numvertexes++; + classiccolours[classicmesh.numvertexes].i = usecolours.i; + VectorMA(p->org, scale, up, classicverts[classicmesh.numvertexes]); + classicmesh.numvertexes++; + classiccolours[classicmesh.numvertexes].i = usecolours.i; + VectorMA(p->org, scale, right, classicverts[classicmesh.numvertexes]); + classicmesh.numvertexes++; + + + + p->org[0] += p->vel[0] * frametime; p->org[1] += p->vel[1] * frametime; p->org[2] += p->vel[2] * frametime; @@ -437,44 +406,16 @@ static void PClassic_DrawParticles(void) } } - switch(qrenderer) + if (classicmesh.numvertexes) { -#ifdef RGLQUAKE - case QR_OPENGL: -#ifdef USEARRAYS - if (classicnumverts) - { - qglDrawArrays(GL_TRIANGLES, 0, classicnumverts); - classicnumverts = 0; - } -#else - qglEnd (); -#endif - qglDisable (GL_BLEND); - qglDepthMask (GL_TRUE); - qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - qglColor3ub (255, 255, 255); - break; -#endif - default: - break; + classicmesh.numindexes = classicmesh.numvertexes; + BE_DrawMeshChain(classicshader, &classicmesh, NULL, &classicshader->defaulttextures); + classicmesh.numvertexes = 0; } - - - - - RSpeedRemark(); - RQ_RenderDistAndClear(); RSpeedEnd(RSPEED_PARTICLESDRAW); } -//called to set up the rendering state (opengl) -static void PClassic_FlushRenderer(void) -{ -} - - static void Classic_ParticleExplosion (vec3_t org) { @@ -677,7 +618,8 @@ static void Classic_ParticleTrail (vec3_t start, vec3_t end, vec3_t *trail_origi goto done; VectorScale(delta, 1 / len, dir); //unit vector in direction of trail - switch (type) { + switch (type) + { case ALT_ROCKET_TRAIL: len /= 1.5; break; case BLOOD_TRAIL: @@ -691,7 +633,8 @@ static void Classic_ParticleTrail (vec3_t start, vec3_t end, vec3_t *trail_origi VectorScale (delta, 1.0 / num_particles, delta); - for (i = 0; i < num_particles && free_particles; i++) { + for (i = 0; i < num_particles && free_particles; i++) + { p = free_particles; free_particles = p->next; p->next = active_particles; @@ -700,7 +643,8 @@ static void Classic_ParticleTrail (vec3_t start, vec3_t end, vec3_t *trail_origi VectorClear (p->vel); p->die = cl.time + 2; - switch(type) { + switch(type) + { case GRENADE_TRAIL: p->ramp = (rand() & 3) + 2; p->color = ramp3[(int) p->ramp]; @@ -732,10 +676,13 @@ static void Classic_ParticleTrail (vec3_t start, vec3_t end, vec3_t *trail_origi tracercount++; VectorCopy (point, p->org); - if (tracercount & 1) { + if (tracercount & 1) + { p->vel[0] = 90 * dir[1]; p->vel[1] = 90 * -dir[0]; - } else { + } + else + { p->vel[0] = 90 * -dir[1]; p->vel[1] = 90 * dir[0]; } @@ -837,8 +784,7 @@ particleengine_t pe_classic = PClassic_ShutdownParticles, PClassic_DelinkTrailstate, PClassic_ClearParticles, - PClassic_DrawParticles, - PClassic_FlushRenderer + PClassic_DrawParticles }; #endif diff --git a/engine/client/p_null.c b/engine/client/p_null.c index 304ab5c5..59f138c3 100644 --- a/engine/client/p_null.c +++ b/engine/client/p_null.c @@ -2,6 +2,7 @@ #include "glquake.h" #include "particles.h" +#include "renderque.h" //obtains an index for the name, even if it is unknown (one can be loaded after. will only fail if the effect limit is reached) static int PNULL_ParticleTypeForName(char *name) @@ -46,14 +47,9 @@ static void PNULL_DrawParticles(void) RSpeedLocals(); RSpeedRemark(); -#ifdef GLQUAKE RQ_RenderDistAndClear(); -#endif RSpeedEnd(RSPEED_PARTICLESDRAW); } -static void PNULL_FlushRenderer(void) -{ -} particleengine_t pe_null = @@ -80,6 +76,5 @@ particleengine_t pe_null = PNULL_ShutdownParticles, PNULL_DelinkTrailstate, PNULL_ClearParticles, - PNULL_DrawParticles, - PNULL_FlushRenderer + PNULL_DrawParticles }; diff --git a/engine/client/p_script.c b/engine/client/p_script.c index 09c09dd9..5765c004 100644 --- a/engine/client/p_script.c +++ b/engine/client/p_script.c @@ -29,9 +29,10 @@ The engine has a few builtins. #ifdef PSET_SCRIPT -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h"//hack #endif +#include "shader.h" #ifdef D3DQUAKE //d3d is awkward @@ -63,8 +64,6 @@ static void buildsintable(void) #define sin(x) (psintable[(int)(x*(64/M_PI)) & 63]) #define cos(x) (psintable[((int)(x*(64/M_PI)) + 16) & 63]) - -// !!! if this is changed, it must be changed in d_ifacea.h too !!! typedef struct particle_s { struct particle_s *next; @@ -72,9 +71,7 @@ typedef struct particle_s // driver-usable fields vec3_t org; - float color; //used by sw renderer. To be removed. - vec3_t rgb; - float alpha; + vec4_t rgba; float scale; float s1, t1, s2, t2; @@ -97,8 +94,7 @@ typedef struct clippeddecal_s vec3_t vertex[3]; vec2_t texcoords[3]; - vec3_t rgb; - float alpha; + vec4_t rgba; } clippeddecal_t; #define BS_LASTSEG 0x1 // no draw to next, no delete @@ -134,11 +130,7 @@ typedef struct { enum {PT_NORMAL, PT_SPARK, PT_SPARKFAN, PT_TEXTUREDSPARK, PT_BEAM, PT_DECAL} type; blendmode_t blendmode; - - int texturenum; -#ifdef D3DQUAKE - void *d3dtexture; -#endif + shader_t *shader; float scalefactor; float invscalefactor; @@ -251,7 +243,7 @@ typedef struct part_type_s { #define PS_INRUNLIST 0x1 // particle type is currently in execution list } part_type_t; -void PScript_DrawParticleTypes (void (*texturedparticles)(int count, particle_t **,plooks_t*), void (*sparklineparticles)(int count, particle_t **,plooks_t*), void (*sparkfanparticles)(int count, particle_t **,plooks_t*), void (*sparktexturedparticles)(int count, particle_t **,plooks_t*), void (*beamparticlest)(int count, beamseg_t**,plooks_t*), void (*beamparticlesut)(int count, beamseg_t**,plooks_t*), void (*drawdecalparticles)(int count, clippeddecal_t**,plooks_t*)); +static void PScript_DrawParticleTypes (void (*texturedparticles)(int count, particle_t **,plooks_t*), void (*sparklineparticles)(int count, particle_t **,plooks_t*), void (*sparkfanparticles)(int count, particle_t **,plooks_t*), void (*sparktexturedparticles)(int count, particle_t **,plooks_t*), void (*beamparticles)(int count, beamseg_t**,plooks_t*), void (*drawdecalparticles)(int count, clippeddecal_t**,plooks_t*)); #ifndef TYPESONLY @@ -261,8 +253,6 @@ static double cost[7] = {1.000000, 0.623490, -0.222521, -0.900969, -0.900969, -0 #define crand() (rand()%32767/16383.5f-1) -void D_DrawParticleTrans (vec3_t porg, float palpha, float pscale, unsigned int pcolour, blendmode_t blendmode); - static void P_ReadPointFile_f (void); static void P_ExportBuiltinSet_f(void); @@ -314,23 +304,14 @@ extern cvar_t r_part_contentswitch; static float particletime; -#define APPLYBLEND(bm) \ - switch (bm) \ - { \ - case BM_ADD: \ - qglBlendFunc(GL_SRC_ALPHA, GL_ONE); \ - break; \ - case BM_SUBTRACT: \ - qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR); \ - break; \ - case BM_BLENDCOLOUR: \ - qglBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR); \ - break; \ - case BM_BLEND: \ - default: \ - qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); \ - break; \ - } +#define BUFFERVERTS 2048*4 +static vecV_t pscriptverts[BUFFERVERTS]; +static avec4_t pscriptcolours[BUFFERVERTS]; +static vec2_t pscripttexcoords[BUFFERVERTS]; +static index_t pscriptquadindexes[(BUFFERVERTS/4)*6]; +static index_t pscripttriindexes[BUFFERVERTS]; +static mesh_t pscriptmesh; +static mesh_t pscripttmesh; static int numparticletypes; static part_type_t *part_type; @@ -481,59 +462,119 @@ static int CheckAssosiation(char *name, int from) static void P_LoadTexture(part_type_t *ptype, qboolean warn) { - switch (qrenderer) + texnums_t tn; + char *defaultshader; + char *namepostfix; + if (qrenderer<=0) + return; + + /*try and load the shader, fail if we would need to generate one*/ + ptype->looks.shader = R_RegisterCustom(ptype->texname, NULL, NULL); + + if (!ptype->looks.shader) { -#ifdef RGLQUAKE - case QR_OPENGL: - if (*ptype->texname && strcmp(ptype->texname, "default")) + /*okay, so no shader, generate a shader that matches the legacy/shaderless mode*/ + switch(ptype->looks.blendmode) { - ptype->looks.texturenum = Mod_LoadHiResTexture(ptype->texname, "particles", true, true, true); + case BM_BLEND: + default: + namepostfix = "_blend"; + defaultshader = + "{\n" + "{\n" + "map $diffuse\n" + "blendfunc blend\n" + "rgbgen vertex\n" + "alphagen vertex\n" + "}\n" + "}\n" + ; + break; + case BM_BLENDCOLOUR: + namepostfix = "_bc"; + defaultshader = + "{\n" + "{\n" + "map $diffuse\n" + "blendfunc GL_SRC_COLOR GL_ONE_MINUS_SRC_COLOR\n" + "rgbgen vertex\n" + "alphagen vertex\n" + "}\n" + "}\n" + ; + break; + case BM_ADD: + namepostfix = "_add"; + defaultshader = + "{\n" + "{\n" + "map $diffuse\n" + "blendfunc GL_SRC_ALPHA GL_ONE\n" + "rgbgen vertex\n" + "alphagen vertex\n" + "}\n" + "}\n" + ; + break; + case BM_SUBTRACT: + namepostfix = "_sub"; + defaultshader = + "{\n" + "{\n" + "map $diffuse\n" + "blendfunc GL_SRC_ALPHA GL_ONE_MINUS_SRC_COLOR\n" + "rgbgen vertex\n" + "alphagen vertex\n" + "}\n" + "}\n" + ; + break; + } - if (!ptype->looks.texturenum) + memset(&tn, 0, sizeof(tn)); + tn.base = R_LoadHiResTexture(ptype->texname, "particles", 0); + if (!TEXVALID(tn.base)) + { + /*okay, so the texture they specified wasn't valid either. use a fully default one*/ + + //note that this could get messy if you depend upon vid_restart to reload your effect without re-execing it after. + ptype->s1 = 0; + ptype->t1 = 0; + ptype->s2 = 1; + ptype->t2 = 1; + ptype->randsmax = 1; + if (ptype->looks.type == PT_BEAM) { - //note that this could get messy if you depend upon vid_restart to reload your effect without re-execing it after. - ptype->s1 = 0; - ptype->t1 = 0; - ptype->s2 = 1; - ptype->t2 = 1; - ptype->randsmax = 1; - - if (warn) - Con_DPrintf("Couldn't load texture %s for particle effect %s\n", ptype->texname, ptype->name); - - if (strstr(ptype->texname, "glow") || strstr(ptype->texname, "ball") || ptype->looks.type == PT_TEXTUREDSPARK) - ptype->looks.texturenum = balltexture; - else - ptype->looks.texturenum = explosiontexture; + /*untextured beams get a single continuous blob*/ + ptype->looks.shader = R_RegisterShader(va("beam%s", namepostfix), defaultshader); + tn.base = beamtexture; + } + else if (ptype->looks.type == PT_SPARKFAN) + { + /*untextured beams get a single continuous blob*/ + ptype->looks.shader = R_RegisterShader(va("fan%s", namepostfix), defaultshader); + tn.base = ptritexture; + } + else if (strstr(ptype->texname, "glow") || strstr(ptype->texname, "ball") || ptype->looks.type == PT_TEXTUREDSPARK) + { + /*sparks and special names get a nice circular texture. + as these are fully default, we can basically discard the texture name in the shader, and get better batching*/ + ptype->looks.shader = R_RegisterShader(va("ball%s", namepostfix), defaultshader); + tn.base = balltexture; + } + else + { + /*anything else gets a fuzzy texture*/ + ptype->looks.shader = R_RegisterShader(va("default%s", namepostfix), defaultshader); + tn.base = explosiontexture; } } else - ptype->looks.texturenum = explosiontexture; - break; -#endif -#ifdef D3DQUAKE - case QR_DIRECT3D: - if (*ptype->texname && strcmp(ptype->texname, "default")) { - ptype->looks.d3dtexture = NULL;//Mod_LoadHiResTexture(ptype->texname, "particles", true, true, true); - - if (!ptype->looks.d3dtexture) - { - if (warn) - Con_DPrintf("Couldn't load texture %s for particle effect %s\n", ptype->texname, ptype->name); - - if (strstr(ptype->texname, "glow") || strstr(ptype->texname, "ball")) - ptype->looks.d3dtexture = d3dballtexture; - else - ptype->looks.d3dtexture = d3dexplosiontexture; - } + /*texture looks good, make a shader, and give it the texture as a diffuse stage*/ + ptype->looks.shader = R_RegisterShader(va("%s%s", ptype->texname, namepostfix), defaultshader); } - else - ptype->looks.d3dtexture = d3dexplosiontexture; - break; -#endif - default: - break; + R_BuildDefaultTexnums(&tn, ptype->looks.shader); } } @@ -1373,6 +1414,29 @@ static void PScript_InitParticles (void) Cvar_Hook(&r_particlesdesc, R_ParticlesDesc_Callback); Cvar_ForceCallback(&r_particlesdesc); + + + for (i = 0; i < (BUFFERVERTS>>2)*6; i += 6) + { + pscriptquadindexes[i+0] = ((i/6)<<2)+0; + pscriptquadindexes[i+1] = ((i/6)<<2)+1; + pscriptquadindexes[i+2] = ((i/6)<<2)+2; + pscriptquadindexes[i+3] = ((i/6)<<2)+0; + pscriptquadindexes[i+4] = ((i/6)<<2)+2; + pscriptquadindexes[i+5] = ((i/6)<<2)+3; + } + pscriptmesh.xyz_array = pscriptverts; + pscriptmesh.st_array = pscripttexcoords; + pscriptmesh.colors4f_array = pscriptcolours; + pscriptmesh.indexes = pscriptquadindexes; + for (i = 0; i < BUFFERVERTS; i++) + { + pscripttriindexes[i] = i; + } + pscripttmesh.xyz_array = pscriptverts; + pscripttmesh.st_array = pscripttexcoords; + pscripttmesh.colors4f_array = pscriptcolours; + pscripttmesh.indexes = pscripttriindexes; } static void PScript_Shutdown (void) @@ -1633,7 +1697,7 @@ static void P_AddRainParticles(void) skytris_t *st; - if (!r_part_rain.value || !r_part_rain_quantity.value) + if (!r_part_rain.ival || !r_part_rain_quantity.ival) { skipped = true; return; @@ -1665,7 +1729,7 @@ glDisable(GL_DEPTH_TEST); glBegin(GL_TRIANGLES); st = skytris; - for (i = 0; i < r_part_rain_quantity.value; i++) + for (i = 0; i < r_part_rain_quantity.ival; i++) st = st->next; glVertex3f(st->org[0], st->org[1], st->org[2]); glVertex3f(st->org[0]+st->x[0], st->org[1]+st->x[1], st->org[2]+st->x[2]); @@ -1917,7 +1981,7 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count, return 1; // inwater check, switch only once - if (r_part_contentswitch.value && ptype->inwater >= 0 && cl.worldmodel) + if (r_part_contentswitch.ival && ptype->inwater >= 0 && cl.worldmodel) { int cont; cont = cl.worldmodel->funcs.PointContents(cl.worldmodel, org); @@ -2035,9 +2099,9 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count, d->die = ptype->randdie*frandom(); if (ptype->die) - d->alpha = ptype->alpha+d->die*ptype->alphachange; + d->rgba[3] = ptype->alpha+d->die*ptype->alphachange; else - d->alpha = ptype->alpha; + d->rgba[3] = ptype->alpha; if (ptype->colorindex >= 0) { @@ -2045,22 +2109,22 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count, cidx = ptype->colorrand > 0 ? rand() % ptype->colorrand : 0; cidx = ptype->colorindex + cidx; if (cidx > 255) - d->alpha = d->alpha / 2; // Hexen 2 style transparency + d->rgba[3] = d->rgba[3] / 2; // Hexen 2 style transparency cidx = (cidx & 0xff) * 3; - d->rgb[0] = host_basepal[cidx] * (1/255.0); - d->rgb[1] = host_basepal[cidx+1] * (1/255.0); - d->rgb[2] = host_basepal[cidx+2] * (1/255.0); + d->rgba[0] = host_basepal[cidx] * (1/255.0); + d->rgba[1] = host_basepal[cidx+1] * (1/255.0); + d->rgba[2] = host_basepal[cidx+2] * (1/255.0); } else - VectorCopy(ptype->rgb, d->rgb); + VectorCopy(ptype->rgb, d->rgba); vec[2] = frandom(); vec[0] = vec[2]*ptype->rgbrandsync[0] + frandom()*(1-ptype->rgbrandsync[0]); vec[1] = vec[2]*ptype->rgbrandsync[1] + frandom()*(1-ptype->rgbrandsync[1]); vec[2] = vec[2]*ptype->rgbrandsync[2] + frandom()*(1-ptype->rgbrandsync[2]); - d->rgb[0] += vec[0]*ptype->rgbrand[0] + ptype->rgbchange[0]*d->die; - d->rgb[1] += vec[1]*ptype->rgbrand[1] + ptype->rgbchange[1]*d->die; - d->rgb[2] += vec[2]*ptype->rgbrand[2] + ptype->rgbchange[2]*d->die; + d->rgba[0] += vec[0]*ptype->rgbrand[0] + ptype->rgbchange[0]*d->die; + d->rgba[1] += vec[1]*ptype->rgbrand[1] + ptype->rgbchange[1]*d->die; + d->rgba[2] += vec[2]*ptype->rgbrand[2] + ptype->rgbchange[2]*d->die; d->die = particletime + ptype->die - d->die; @@ -2191,9 +2255,9 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count, p->die = ptype->randdie*frandom(); p->scale = ptype->scale+ptype->randscale*frandom(); if (ptype->die) - p->alpha = ptype->alpha+p->die*ptype->alphachange; + p->rgba[3] = ptype->alpha+p->die*ptype->alphachange; else - p->alpha = ptype->alpha; + p->rgba[3] = ptype->alpha; // p->color = 0; if (ptype->emittime < 0) p->state.trailstate = NULL; @@ -2219,14 +2283,14 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count, cidx = ptype->colorrand > 0 ? rand() % ptype->colorrand : 0; cidx = ptype->colorindex + cidx; if (cidx > 255) - p->alpha = p->alpha / 2; // Hexen 2 style transparency + p->rgba[3] = p->rgba[3] / 2; // Hexen 2 style transparency cidx = (cidx & 0xff) * 3; - p->rgb[0] = host_basepal[cidx] * (1/255.0); - p->rgb[1] = host_basepal[cidx+1] * (1/255.0); - p->rgb[2] = host_basepal[cidx+2] * (1/255.0); + p->rgba[0] = host_basepal[cidx] * (1/255.0); + p->rgba[1] = host_basepal[cidx+1] * (1/255.0); + p->rgba[2] = host_basepal[cidx+2] * (1/255.0); } else - VectorCopy(ptype->rgb, p->rgb); + VectorCopy(ptype->rgb, p->rgba); // use org temporarily for rgbsync p->org[2] = frandom(); @@ -2234,9 +2298,9 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count, p->org[1] = p->org[2]*ptype->rgbrandsync[1] + frandom()*(1-ptype->rgbrandsync[1]); p->org[2] = p->org[2]*ptype->rgbrandsync[2] + frandom()*(1-ptype->rgbrandsync[2]); - p->rgb[0] += p->org[0]*ptype->rgbrand[0] + ptype->rgbchange[0]*p->die; - p->rgb[1] += p->org[1]*ptype->rgbrand[1] + ptype->rgbchange[1]*p->die; - p->rgb[2] += p->org[2]*ptype->rgbrand[2] + ptype->rgbchange[2]*p->die; + p->rgba[0] += p->org[0]*ptype->rgbrand[0] + ptype->rgbchange[0]*p->die; + p->rgba[1] += p->org[1]*ptype->rgbrand[1] + ptype->rgbchange[1]*p->die; + p->rgba[2] += p->org[2]*ptype->rgbrand[2] + ptype->rgbchange[2]*p->die; // randomvel p->vel[0] = crandom()*ptype->randomvel; @@ -2884,9 +2948,9 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype p->die = ptype->randdie*frandom(); p->scale = ptype->scale+ptype->randscale*frandom(); if (ptype->die) - p->alpha = ptype->alpha+p->die*ptype->alphachange; + p->rgba[3] = ptype->alpha+p->die*ptype->alphachange; else - p->alpha = ptype->alpha; + p->rgba[3] = ptype->alpha; // p->color = 0; // if (ptype->spawnmode == SM_TRACER) @@ -2904,30 +2968,24 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype cidx = ptype->colorindex + cidx; if (cidx > 255) - p->alpha = p->alpha / 2; + p->rgba[3] = p->rgba[3] / 2; cidx = (cidx & 0xff) * 3; - p->rgb[0] = host_basepal[cidx] * (1/255.0); - p->rgb[1] = host_basepal[cidx+1] * (1/255.0); - p->rgb[2] = host_basepal[cidx+2] * (1/255.0); + p->rgba[0] = host_basepal[cidx] * (1/255.0); + p->rgba[1] = host_basepal[cidx+1] * (1/255.0); + p->rgba[2] = host_basepal[cidx+2] * (1/255.0); } else - VectorCopy(ptype->rgb, p->rgb); + VectorCopy(ptype->rgb, p->rgba); // use org temporarily for rgbsync p->org[2] = frandom(); p->org[0] = p->org[2]*ptype->rgbrandsync[0] + frandom()*(1-ptype->rgbrandsync[0]); p->org[1] = p->org[2]*ptype->rgbrandsync[1] + frandom()*(1-ptype->rgbrandsync[1]); p->org[2] = p->org[2]*ptype->rgbrandsync[2] + frandom()*(1-ptype->rgbrandsync[2]); - if (ptype->orgadd) - { - p->org[0] += vec[0]*ptype->orgadd; - p->org[1] += vec[1]*ptype->orgadd; - p->org[2] += vec[2]*ptype->orgadd; - } - p->rgb[0] += p->org[0]*ptype->rgbrand[0] + ptype->rgbchange[0]*p->die; - p->rgb[1] += p->org[1]*ptype->rgbrand[1] + ptype->rgbchange[1]*p->die; - p->rgb[2] += p->org[2]*ptype->rgbrand[2] + ptype->rgbchange[2]*p->die; + p->rgba[0] += p->org[0]*ptype->rgbrand[0] + ptype->rgbchange[0]*p->die; + p->rgba[1] += p->org[1]*ptype->rgbrand[1] + ptype->rgbchange[1]*p->die; + p->rgba[2] += p->org[2]*ptype->rgbrand[2] + ptype->rgbchange[2]*p->die; VectorClear (p->vel); if (ptype->emittime < 0) @@ -3085,6 +3143,13 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype p->org[2] = p->org[2]*ptype->areaspreadvert + start[2]; break; } + + if (ptype->orgadd) + { + p->org[0] += vec[0]*ptype->orgadd; + p->org[1] += vec[1]*ptype->orgadd; + p->org[2] += vec[2]*ptype->orgadd; + } } VectorAdd (start, vstep, start); @@ -3172,7 +3237,7 @@ static int PScript_ParticleTrail (vec3_t startpos, vec3_t end, int type, trailst return 1; // inwater check, switch only once - if (r_part_contentswitch.value && ptype->inwater >= 0) + if (r_part_contentswitch.ival && ptype->inwater >= 0) { int cont; cont = cl.worldmodel->funcs.PointContents(cl.worldmodel, startpos); @@ -3192,27 +3257,26 @@ static void PScript_ParticleTrailIndex (vec3_t start, vec3_t end, int color, int P_ParticleTrail(start, end, pe_defaulttrail, tsk); } -vec3_t pright, pup; +static vec3_t pright, pup; static float pframetime; -#ifdef RGLQUAKE + static void GL_DrawTexturedParticle(int count, particle_t **plist, plooks_t *type) { particle_t *p; float x,y; float scale; - - qglEnable(GL_TEXTURE_2D); - GL_Bind(type->texturenum); - APPLYBLEND(type->blendmode); - qglShadeModel(GL_FLAT); - qglBegin(GL_QUADS); - - while (count--) { p = *plist++; + if (pscriptmesh.numvertexes >= BUFFERVERTS-4) + { + pscriptmesh.numindexes = pscriptmesh.numvertexes/4*6; + BE_DrawMeshChain(type->shader, &pscriptmesh, NULL, &type->shader->defaulttextures); + pscriptmesh.numvertexes = 0; + } + if (type->scalefactor == 1) { scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1] @@ -3226,114 +3290,69 @@ static void GL_DrawTexturedParticle(int count, particle_t **plist, plooks_t *typ else scale = 1; - qglColor4f (p->rgb[0], - p->rgb[1], - p->rgb[2], - p->alpha); + Vector4Copy(p->rgba, pscriptcolours[pscriptmesh.numvertexes+0]); + Vector4Copy(p->rgba, pscriptcolours[pscriptmesh.numvertexes+1]); + Vector4Copy(p->rgba, pscriptcolours[pscriptmesh.numvertexes+2]); + Vector4Copy(p->rgba, pscriptcolours[pscriptmesh.numvertexes+3]); + + Vector2Set(pscripttexcoords[pscriptmesh.numvertexes+0], p->s1, p->t1); + Vector2Set(pscripttexcoords[pscriptmesh.numvertexes+1], p->s1, p->t2); + Vector2Set(pscripttexcoords[pscriptmesh.numvertexes+2], p->s2, p->t2); + Vector2Set(pscripttexcoords[pscriptmesh.numvertexes+3], p->s2, p->t1); if (p->angle) { x = sin(p->angle)*scale; y = cos(p->angle)*scale; - qglTexCoord2f(p->s1,p->t1); - qglVertex3f (p->org[0] - x*pright[0] - y*pup[0], p->org[1] - x*pright[1] - y*pup[1], p->org[2] - x*pright[2] - y*pup[2]); - qglTexCoord2f(p->s1,p->t2); - qglVertex3f (p->org[0] - y*pright[0] + x*pup[0], p->org[1] - y*pright[1] + x*pup[1], p->org[2] - y*pright[2] + x*pup[2]); - qglTexCoord2f(p->s2,p->t2); - qglVertex3f (p->org[0] + x*pright[0] + y*pup[0], p->org[1] + x*pright[1] + y*pup[1], p->org[2] + x*pright[2] + y*pup[2]); - qglTexCoord2f(p->s2,p->t1); - qglVertex3f (p->org[0] + y*pright[0] - x*pup[0], p->org[1] + y*pright[1] - x*pup[1], p->org[2] + y*pright[2] - x*pup[2]); + pscriptverts[pscriptmesh.numvertexes+0][0] = p->org[0] - x*pright[0] - y*pup[0]; + pscriptverts[pscriptmesh.numvertexes+0][1] = p->org[1] - x*pright[1] - y*pup[1]; + pscriptverts[pscriptmesh.numvertexes+0][2] = p->org[2] - x*pright[2] - y*pup[2]; + pscriptverts[pscriptmesh.numvertexes+1][0] = p->org[0] - y*pright[0] + x*pup[0]; + pscriptverts[pscriptmesh.numvertexes+1][1] = p->org[1] - y*pright[1] + x*pup[1]; + pscriptverts[pscriptmesh.numvertexes+1][2] = p->org[2] - y*pright[2] + x*pup[2]; + pscriptverts[pscriptmesh.numvertexes+2][0] = p->org[0] + x*pright[0] + y*pup[0]; + pscriptverts[pscriptmesh.numvertexes+2][1] = p->org[1] + x*pright[1] + y*pup[1]; + pscriptverts[pscriptmesh.numvertexes+2][2] = p->org[2] + x*pright[2] + y*pup[2]; + pscriptverts[pscriptmesh.numvertexes+3][0] = p->org[0] + y*pright[0] - x*pup[0]; + pscriptverts[pscriptmesh.numvertexes+3][1] = p->org[1] + y*pright[1] - x*pup[1]; + pscriptverts[pscriptmesh.numvertexes+3][2] = p->org[2] + y*pright[2] - x*pup[2]; } else { - qglTexCoord2f(p->s1,p->t1); - qglVertex3f (p->org[0] - scale*pup[0], p->org[1] - scale*pup[1], p->org[2] - scale*pup[2]); - qglTexCoord2f(p->s1,p->t2); - qglVertex3f (p->org[0] - scale*pright[0], p->org[1] - scale*pright[1], p->org[2] - scale*pright[2]); - qglTexCoord2f(p->s2,p->t2); - qglVertex3f (p->org[0] + scale*pup[0], p->org[1] + scale*pup[1], p->org[2] + scale*pup[2]); - qglTexCoord2f(p->s2,p->t1); - qglVertex3f (p->org[0] + scale*pright[0], p->org[1] + scale*pright[1], p->org[2] + scale*pright[2]); + VectorMA(p->org, -scale, pup, pscriptverts[pscriptmesh.numvertexes+0]); + VectorMA(p->org, -scale, pright, pscriptverts[pscriptmesh.numvertexes+1]); + VectorMA(p->org, scale, pup, pscriptverts[pscriptmesh.numvertexes+2]); + VectorMA(p->org, scale, pright, pscriptverts[pscriptmesh.numvertexes+3]); } + pscriptmesh.numvertexes += 4; } - qglEnd(); -} - -static void GL_DrawSketchParticle(int count, particle_t **plist, plooks_t *type) -{ - particle_t *p; - float x,y; - float scale; - - int quant; - - qglDisable(GL_TEXTURE_2D); -// if (type->blendmode == BM_ADD) //addative -// glBlendFunc(GL_SRC_ALPHA, GL_ONE); -// else if (type->blendmode == BM_SUBTRACT) //subtractive -// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -// else - qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - qglShadeModel(GL_SMOOTH); - qglBegin(GL_LINES); - - while (count--) + if (pscriptmesh.numvertexes) { - p = *plist++; - - scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1] - + (p->org[2] - r_origin[2])*vpn[2]; - scale = (scale*p->scale)*(type->invscalefactor) + p->scale * (type->scalefactor*250); - if (scale < 20) - scale = 0.25; - else - scale = 0.25 + scale * 0.001; - - qglColor4f (p->rgb[0]/2, - p->rgb[1]/2, - p->rgb[2]/2, - p->alpha*2); - - quant = scale; - - if (p->angle) - { - x = sin(p->angle)*scale; - y = cos(p->angle)*scale; - - qglVertex3f (p->org[0] - x*pright[0] - y*pup[0], p->org[1] - x*pright[1] - y*pup[1], p->org[2] - x*pright[2] - y*pup[2]); - qglVertex3f (p->org[0] + x*pright[0] + y*pup[0], p->org[1] + x*pright[1] + y*pup[1], p->org[2] + x*pright[2] + y*pup[2]); - qglVertex3f (p->org[0] + y*pright[0] - x*pup[0], p->org[1] + y*pright[1] - x*pup[1], p->org[2] + y*pright[2] - x*pup[2]); - qglVertex3f (p->org[0] - y*pright[0] + x*pup[0], p->org[1] - y*pright[1] + x*pup[1], p->org[2] - y*pright[2] + x*pup[2]); - } - else - { - qglVertex3f (p->org[0] - scale*pup[0], p->org[1] - scale*pup[1], p->org[2] - scale*pup[2]); - qglVertex3f (p->org[0] + scale*pup[0], p->org[1] + scale*pup[1], p->org[2] + scale*pup[2]); - qglVertex3f (p->org[0] + scale*pright[0], p->org[1] + scale*pright[1], p->org[2] + scale*pright[2]); - qglVertex3f (p->org[0] - scale*pright[0], p->org[1] - scale*pright[1], p->org[2] - scale*pright[2]); - } + pscriptmesh.numindexes = pscriptmesh.numvertexes/4*6; + BE_DrawMeshChain(type->shader, &pscriptmesh, NULL, &type->shader->defaulttextures); + pscriptmesh.numvertexes = 0; } - qglEnd(); } static void GL_DrawTrifanParticle(int count, particle_t **plist, plooks_t *type) { particle_t *p; - int i; - vec3_t v; + vec3_t v, cr, o2; float scale; - qglDisable(GL_TEXTURE_2D); - APPLYBLEND(type->blendmode); - qglShadeModel(GL_SMOOTH); - while (count--) { p = *plist++; + if (pscripttmesh.numvertexes >= BUFFERVERTS-3) + { + pscripttmesh.numindexes = pscripttmesh.numvertexes; + BE_DrawMeshChain(type->shader, &pscripttmesh, NULL, &type->shader->defaulttextures); + pscripttmesh.numvertexes = 0; + } + scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1] + (p->org[2] - r_origin[2])*vpn[2]; scale = (scale*p->scale)*(type->invscalefactor) + p->scale * (type->scalefactor*250); @@ -3341,33 +3360,40 @@ static void GL_DrawTrifanParticle(int count, particle_t **plist, plooks_t *type) scale = 0.05; else scale = 0.05 + scale * 0.0001; - /* - if ((p->vel[0]*p->vel[0]+p->vel[1]*p->vel[1]+p->vel[2]*p->vel[2])*2*scale > 30*30) - scale = 1+1/30/Length(p->vel)*2;*/ - qglBegin (GL_TRIANGLE_FAN); - qglColor4f (p->rgb[0], - p->rgb[1], - p->rgb[2], - p->alpha); - qglVertex3fv (p->org); - qglColor4f (p->rgb[0]/2, - p->rgb[1]/2, - p->rgb[2]/2, - 0); - for (i=7 ; i>=0 ; i--) - { - v[0] = p->org[0] - p->vel[0]*scale + vright[0]*cost[i%7]*p->scale + vup[0]*sint[i%7]*p->scale; - v[1] = p->org[1] - p->vel[1]*scale + vright[1]*cost[i%7]*p->scale + vup[1]*sint[i%7]*p->scale; - v[2] = p->org[2] - p->vel[2]*scale + vright[2]*cost[i%7]*p->scale + vup[2]*sint[i%7]*p->scale; - qglVertex3fv (v); - } - qglEnd (); + Vector4Copy(p->rgba, pscriptcolours[pscripttmesh.numvertexes+0]); + Vector4Copy(p->rgba, pscriptcolours[pscripttmesh.numvertexes+1]); + Vector4Copy(p->rgba, pscriptcolours[pscripttmesh.numvertexes+2]); + + Vector2Set(pscripttexcoords[pscripttmesh.numvertexes+0], p->s1, p->t1); + Vector2Set(pscripttexcoords[pscripttmesh.numvertexes+1], p->s1, p->t2); + Vector2Set(pscripttexcoords[pscripttmesh.numvertexes+2], p->s2, p->t1); + + + VectorMA(p->org, -scale, p->vel, o2); + VectorSubtract(r_refdef.vieworg, o2, v); + CrossProduct(v, p->vel, cr); + VectorNormalize(cr); + + VectorCopy(p->org, pscriptverts[pscripttmesh.numvertexes+0]); + VectorMA(o2, -p->scale, cr, pscriptverts[pscripttmesh.numvertexes+1]); + VectorMA(o2, p->scale, cr, pscriptverts[pscripttmesh.numvertexes+2]); + + pscripttmesh.numvertexes += 3; + } + + if (pscripttmesh.numvertexes) + { + pscripttmesh.numindexes = pscripttmesh.numvertexes; + BE_DrawMeshChain(type->shader, &pscripttmesh, NULL, &type->shader->defaulttextures); + pscripttmesh.numvertexes = 0; } } static void GL_DrawLineSparkParticle(int count, particle_t **plist, plooks_t *type) { +#pragma message("fixme: no line sparks") +#if 0 particle_t *p; qglDisable(GL_TEXTURE_2D); @@ -3392,39 +3418,43 @@ static void GL_DrawLineSparkParticle(int count, particle_t **plist, plooks_t *ty qglVertex3f (p->org[0]-p->vel[0]/10, p->org[1]-p->vel[1]/10, p->org[2]-p->vel[2]/10); } qglEnd(); +#endif } static void GL_DrawTexturedSparkParticle(int count, particle_t **plist, plooks_t *type) { particle_t *p; - vec3_t v, cr, o2, point; + vec3_t v, cr, o2; - qglEnable(GL_TEXTURE_2D); - GL_Bind(type->texturenum); - APPLYBLEND(type->blendmode); - qglShadeModel(GL_SMOOTH); - qglBegin(GL_QUADS); - - - while(count--) + while (count--) { p = *plist++; - qglColor4f (p->rgb[0], - p->rgb[1], - p->rgb[2], - p->alpha); + if (pscriptmesh.numvertexes >= BUFFERVERTS-4) + { + pscriptmesh.numindexes = pscriptmesh.numvertexes/4*6; + BE_DrawMeshChain(type->shader, &pscriptmesh, NULL, &type->shader->defaulttextures); + pscriptmesh.numvertexes = 0; + } + + Vector4Copy(p->rgba, pscriptcolours[pscriptmesh.numvertexes+0]); + Vector4Copy(p->rgba, pscriptcolours[pscriptmesh.numvertexes+1]); + Vector4Copy(p->rgba, pscriptcolours[pscriptmesh.numvertexes+2]); + Vector4Copy(p->rgba, pscriptcolours[pscriptmesh.numvertexes+3]); + + Vector2Set(pscripttexcoords[pscriptmesh.numvertexes+0], p->s1, p->t1); + Vector2Set(pscripttexcoords[pscriptmesh.numvertexes+1], p->s1, p->t2); + Vector2Set(pscripttexcoords[pscriptmesh.numvertexes+2], p->s2, p->t2); + Vector2Set(pscripttexcoords[pscriptmesh.numvertexes+3], p->s2, p->t1); + + VectorSubtract(r_refdef.vieworg, p->org, v); CrossProduct(v, p->vel, cr); VectorNormalize(cr); - VectorMA(p->org, -p->scale/2, cr, point); - qglTexCoord2f(p->s1, p->t1); - qglVertex3fv(point); - VectorMA(p->org, p->scale/2, cr, point); - qglTexCoord2f(p->s1, p->t2); - qglVertex3fv(point); + VectorMA(p->org, -p->scale/2, cr, pscriptverts[pscriptmesh.numvertexes+0]); + VectorMA(p->org, p->scale/2, cr, pscriptverts[pscriptmesh.numvertexes+1]); VectorMA(p->org, 0.1, p->vel, o2); @@ -3433,249 +3463,119 @@ static void GL_DrawTexturedSparkParticle(int count, particle_t **plist, plooks_t CrossProduct(v, p->vel, cr); VectorNormalize(cr); - VectorMA(o2, p->scale/2, cr, point); - qglTexCoord2f(p->s2, p->t2); - qglVertex3fv(point); - VectorMA(o2, -p->scale/2, cr, point); - qglTexCoord2f(p->s2, p->t1); - qglVertex3fv(point); + VectorMA(o2, p->scale/2, cr, pscriptverts[pscriptmesh.numvertexes+2]); + VectorMA(o2, -p->scale/2, cr, pscriptverts[pscriptmesh.numvertexes+3]); + + pscriptmesh.numvertexes += 4; } - qglEnd(); -} -static void GL_DrawSketchSparkParticle(int count, particle_t **plist, plooks_t *type) -{ - particle_t *p; - - qglDisable(GL_TEXTURE_2D); - APPLYBLEND(type->blendmode); - qglShadeModel(GL_SMOOTH); - qglBegin(GL_LINES); - - while(count--) + if (pscriptmesh.numvertexes) { - p = *plist++; - qglColor4f (p->rgb[0], - p->rgb[1], - p->rgb[2], - p->alpha); - qglVertex3f (p->org[0], p->org[1], p->org[2]); - - qglColor4f (p->rgb[0], - p->rgb[1], - p->rgb[2], - 0); - qglVertex3f (p->org[0]-p->vel[0]/10, p->org[1]-p->vel[1]/10, p->org[2]-p->vel[2]/10); + pscriptmesh.numindexes = pscriptmesh.numvertexes/4*6; + BE_DrawMeshChain(type->shader, &pscriptmesh, NULL, &type->shader->defaulttextures); + pscriptmesh.numvertexes = 0; } - qglEnd(); } -static void GL_DrawParticleBeam_Textured(int count, beamseg_t **blist, plooks_t *type) +static void GL_DrawParticleBeam(int count, beamseg_t **blist, plooks_t *type) { beamseg_t *b; - vec3_t v, point; + vec3_t v; vec3_t cr; beamseg_t *c; particle_t *p; particle_t *q; float ts; - qglEnable(GL_TEXTURE_2D); - GL_Bind(type->texturenum); - APPLYBLEND(type->blendmode); - qglShadeModel(GL_SMOOTH); - qglBegin(GL_QUADS); - while(count--) { b = *blist++; + if (pscriptmesh.numvertexes >= BUFFERVERTS-4) + { + pscriptmesh.numindexes = pscriptmesh.numvertexes/4*6; + BE_DrawMeshChain(type->shader, &pscriptmesh, NULL, &type->shader->defaulttextures); + pscriptmesh.numvertexes = 0; + } + c = b->next; q = c->p; -// if (!q) -// continue; - p = b->p; -// if (!p) -// continue; - qglColor4f(q->rgb[0], - q->rgb[1], - q->rgb[2], - q->alpha); - // qglBegin(GL_LINE_LOOP); VectorSubtract(r_refdef.vieworg, q->org, v); VectorNormalize(v); CrossProduct(c->dir, v, cr); ts = c->texture_s*q->angle + particletime*q->rotationspeed; - - VectorMA(q->org, -q->scale, cr, point); - qglTexCoord2f(ts, p->t1); - qglVertex3fv(point); - VectorMA(q->org, q->scale, cr, point); - qglTexCoord2f(ts, p->t2); - qglVertex3fv(point); - - qglColor4f(p->rgb[0], - p->rgb[1], - p->rgb[2], - p->alpha); + Vector4Copy(q->rgba, pscriptcolours[pscriptmesh.numvertexes+0]); + Vector4Copy(q->rgba, pscriptcolours[pscriptmesh.numvertexes+1]); + Vector2Set(pscripttexcoords[pscriptmesh.numvertexes+0], ts, p->t1); + Vector2Set(pscripttexcoords[pscriptmesh.numvertexes+1], ts, p->t2); + VectorMA(q->org, -q->scale, cr, pscriptverts[pscriptmesh.numvertexes+0]); + VectorMA(q->org, q->scale, cr, pscriptverts[pscriptmesh.numvertexes+1]); VectorSubtract(r_refdef.vieworg, p->org, v); VectorNormalize(v); CrossProduct(b->dir, v, cr); // replace with old p->dir? ts = b->texture_s*p->angle + particletime*p->rotationspeed; + Vector4Copy(p->rgba, pscriptcolours[pscriptmesh.numvertexes+2]); + Vector4Copy(p->rgba, pscriptcolours[pscriptmesh.numvertexes+3]); + Vector2Set(pscripttexcoords[pscriptmesh.numvertexes+2], ts, p->t2); + Vector2Set(pscripttexcoords[pscriptmesh.numvertexes+3], ts, p->t1); + VectorMA(p->org, p->scale, cr, pscriptverts[pscriptmesh.numvertexes+2]); + VectorMA(p->org, -p->scale, cr, pscriptverts[pscriptmesh.numvertexes+3]); - VectorMA(p->org, p->scale, cr, point); - qglTexCoord2f(ts, p->t2); - qglVertex3fv(point); - VectorMA(p->org, -p->scale, cr, point); - qglTexCoord2f(ts, p->t1); - qglVertex3fv(point); + pscriptmesh.numvertexes += 4; } - qglEnd(); -} -static void GL_DrawParticleBeam_Untextured(int count, beamseg_t **blist, plooks_t *type) -{ - vec3_t v; - vec3_t cr; - beamseg_t *c; - particle_t *p; - particle_t *q; - beamseg_t *b; - - vec3_t point[4]; - - - qglDisable(GL_TEXTURE_2D); - APPLYBLEND(type->blendmode); - qglShadeModel(GL_SMOOTH); - qglBegin(GL_QUADS); - - while(count--) + if (pscriptmesh.numvertexes) { - b = *blist++; - - c = b->next; - - q = c->p; - // if (!q) - // continue; - - p = b->p; - // if (!p) - // continue; - - VectorSubtract(r_refdef.vieworg, q->org, v); - VectorNormalize(v); - CrossProduct(c->dir, v, cr); - - VectorMA(q->org, -q->scale, cr, point[0]); - VectorMA(q->org, q->scale, cr, point[1]); - - - VectorSubtract(r_refdef.vieworg, p->org, v); - VectorNormalize(v); - CrossProduct(b->dir, v, cr); // replace with old p->dir? - - VectorMA(p->org, p->scale, cr, point[2]); - VectorMA(p->org, -p->scale, cr, point[3]); - - - //one half - //back out - //back in - //front in - //front out - qglColor4f(q->rgb[0], - q->rgb[1], - q->rgb[2], - 0); - qglVertex3fv(point[0]); - qglColor4f(q->rgb[0], - q->rgb[1], - q->rgb[2], - q->alpha); - qglVertex3fv(q->org); - - qglColor4f(p->rgb[0], - p->rgb[1], - p->rgb[2], - p->alpha); - qglVertex3fv(p->org); - qglColor4f(p->rgb[0], - p->rgb[1], - p->rgb[2], - 0); - qglVertex3fv(point[3]); - - //front out - //front in - //back in - //back out - qglColor4f(p->rgb[0], - p->rgb[1], - p->rgb[2], - 0); - qglVertex3fv(point[2]); - qglColor4f(p->rgb[0], - p->rgb[1], - p->rgb[2], - p->alpha); - qglVertex3fv(p->org); - - qglColor4f(q->rgb[0], - q->rgb[1], - q->rgb[2], - q->alpha); - qglVertex3fv(q->org); - qglColor4f(q->rgb[0], - q->rgb[1], - q->rgb[2], - 0); - qglVertex3fv(point[1]); + pscriptmesh.numindexes = pscriptmesh.numvertexes/4*6; + BE_DrawMeshChain(type->shader, &pscriptmesh, NULL, &type->shader->defaulttextures); + pscriptmesh.numvertexes = 0; } - qglEnd(); } static void GL_DrawClippedDecal(int count, clippeddecal_t **dlist, plooks_t *type) { clippeddecal_t *d; - qglEnable(GL_TEXTURE_2D); - GL_Bind(type->texturenum); - APPLYBLEND(type->blendmode); - qglShadeModel(GL_SMOOTH); - -// qglDisable(GL_TEXTURE_2D); -// qglBegin(GL_LINE_LOOP); - - qglBegin(GL_TRIANGLES); - while (count--) { d = *dlist++; - qglColor4f(d->rgb[0], - d->rgb[1], - d->rgb[2], - d->alpha); + if (pscripttmesh.numvertexes >= BUFFERVERTS-3) + { + pscripttmesh.numindexes = pscripttmesh.numvertexes; + BE_DrawMeshChain(type->shader, &pscripttmesh, NULL, &type->shader->defaulttextures); + pscripttmesh.numvertexes = 0; + } - qglTexCoord2fv(d->texcoords[0]); - qglVertex3fv(d->vertex[0]); - qglTexCoord2fv(d->texcoords[1]); - qglVertex3fv(d->vertex[1]); - qglTexCoord2fv(d->texcoords[2]); - qglVertex3fv(d->vertex[2]); + Vector4Copy(d->rgba, pscriptcolours[pscripttmesh.numvertexes+0]); + Vector4Copy(d->rgba, pscriptcolours[pscripttmesh.numvertexes+1]); + Vector4Copy(d->rgba, pscriptcolours[pscripttmesh.numvertexes+2]); + Vector4Copy(d->rgba, pscriptcolours[pscripttmesh.numvertexes+3]); + + Vector2Copy(d->texcoords[0], pscripttexcoords[pscripttmesh.numvertexes+0]); + Vector2Copy(d->texcoords[1], pscripttexcoords[pscripttmesh.numvertexes+1]); + Vector2Copy(d->texcoords[2], pscripttexcoords[pscripttmesh.numvertexes+2]); + + VectorCopy(d->vertex[0], pscriptverts[pscripttmesh.numvertexes+0]); + VectorCopy(d->vertex[1], pscriptverts[pscripttmesh.numvertexes+1]); + VectorCopy(d->vertex[2], pscriptverts[pscripttmesh.numvertexes+2]); + + pscriptmesh.numvertexes += 3; + } + + if (pscriptmesh.numvertexes) + { + pscripttmesh.numindexes = pscripttmesh.numvertexes; + BE_DrawMeshChain(type->shader, &pscriptmesh, NULL, &type->shader->defaulttextures); + pscripttmesh.numvertexes = 0; } - qglEnd(); } -#endif - -void PScript_DrawParticleTypes (void (*texturedparticles)(int count, particle_t **,plooks_t*), void (*sparklineparticles)(int count, particle_t **,plooks_t*), void (*sparkfanparticles)(int count, particle_t **,plooks_t*), void (*sparktexturedparticles)(int count, particle_t **,plooks_t*), void (*beamparticlest)(int count, beamseg_t**,plooks_t*), void (*beamparticlesut)(int count, beamseg_t**,plooks_t*), void (*drawdecalparticles)(int count, clippeddecal_t**,plooks_t*)) +static void PScript_DrawParticleTypes (void (*texturedparticles)(int count, particle_t **,plooks_t*), void (*sparklineparticles)(int count, particle_t **,plooks_t*), void (*sparkfanparticles)(int count, particle_t **,plooks_t*), void (*sparktexturedparticles)(int count, particle_t **,plooks_t*), void (*beamparticles)(int count, beamseg_t**,plooks_t*), void (*drawdecalparticles)(int count, clippeddecal_t**,plooks_t*)) { RSpeedMark(); @@ -3696,7 +3596,7 @@ void PScript_DrawParticleTypes (void (*texturedparticles)(int count, particle_t //remember that they're not drawn instantly either. beamseg_t *b, *bkill; - int traces=r_particle_tracelimit.value; + int traces=r_particle_tracelimit.ival; int rampind; if (r_plooksdirty) @@ -3734,33 +3634,24 @@ void PScript_DrawParticleTypes (void (*texturedparticles)(int count, particle_t kill_list = kill_first = NULL; - // reassign drawing methods by cvars - if (r_part_beams_textured.value < 0) - beamparticlest = NULL; - else if (!r_part_beams_textured.value) - beamparticlest = beamparticlesut; + if (r_part_beams.ival < 0) + beamparticles = NULL; + else if (!r_part_beams.ival) + beamparticles = NULL; - if (r_part_beams.value < 0) - beamparticlesut = NULL; - else if (!r_part_beams.value) - { - beamparticlest = NULL; - beamparticlesut = NULL; - } - - if (r_part_sparks_textured.value < 0) + if (r_part_sparks_textured.ival < 0) sparktexturedparticles = NULL; - else if (!r_part_sparks_textured.value) + else if (!r_part_sparks_textured.ival) sparktexturedparticles = sparklineparticles; - if (r_part_sparks_trifan.value < 0) + if (r_part_sparks_trifan.ival < 0) sparkfanparticles = NULL; - else if (!r_part_sparks_trifan.value) + else if (!r_part_sparks_trifan.ival) sparkfanparticles = sparklineparticles; - if (r_part_sparks.value < 0) + if (r_part_sparks.ival < 0) sparklineparticles = NULL; - else if (!r_part_sparks.value) + else if (!r_part_sparks.ival) { sparktexturedparticles = NULL; sparkfanparticles = NULL; @@ -3807,22 +3698,22 @@ void PScript_DrawParticleTypes (void (*texturedparticles)(int count, particle_t if (rampind >= type->rampindexes) rampind = type->rampindexes - 1; ramp = type->ramp + rampind; - VectorCopy(ramp->rgb, d->rgb); - d->alpha = ramp->alpha; + VectorCopy(ramp->rgb, d->rgba); + d->rgba[3] = ramp->alpha; break; case RAMP_DELTA: //particle ramps ramp = type->ramp + (int)(type->rampindexes * (type->die - (d->die - particletime)) / type->die); - VectorMA(d->rgb, pframetime, ramp->rgb, d->rgb); - d->alpha -= pframetime*ramp->alpha; + VectorMA(d->rgba, pframetime, ramp->rgb, d->rgba); + d->rgba[3] -= pframetime*ramp->alpha; break; case RAMP_NONE: //particle changes acording to it's preset properties. if (particletime < (d->die-type->die+type->rgbchangetime)) { - d->rgb[0] += pframetime*type->rgbchange[0]; - d->rgb[1] += pframetime*type->rgbchange[1]; - d->rgb[2] += pframetime*type->rgbchange[2]; + d->rgba[0] += pframetime*type->rgbchange[0]; + d->rgba[1] += pframetime*type->rgbchange[1]; + d->rgba[2] += pframetime*type->rgbchange[2]; } - d->alpha += pframetime*type->alphachange; + d->rgba[3] += pframetime*type->alphachange; } drawdecalparticles(1, &d, &type->looks); @@ -3837,10 +3728,7 @@ void PScript_DrawParticleTypes (void (*texturedparticles)(int count, particle_t switch(type->looks.type) { case PT_BEAM: - if (*type->texname) - bdraw = beamparticlest; - else - bdraw = beamparticlesut; + bdraw = beamparticles; break; case PT_DECAL: break; @@ -3870,14 +3758,14 @@ void PScript_DrawParticleTypes (void (*texturedparticles)(int count, particle_t P_RunParticleEffectType(p->org, p->vel, 1, type->emit); // make sure stain effect runs - if (type->stains && r_bloodstains.value) + if (type->stains && r_bloodstains.ival) { if (traces-->0&&tr(oldorg, p->org, stop, normal)) { - R_AddStain(stop, (p->rgb[1]*-10+p->rgb[2]*-10), - (p->rgb[0]*-10+p->rgb[2]*-10), - (p->rgb[0]*-10+p->rgb[1]*-10), - 30*p->alpha*type->stains); + R_AddStain(stop, (p->rgba[1]*-10+p->rgba[2]*-10), + (p->rgba[0]*-10+p->rgba[2]*-10), + (p->rgba[0]*-10+p->rgba[1]*-10), + 30*p->rgba[3]*type->stains); } } @@ -4044,8 +3932,8 @@ void PScript_DrawParticleTypes (void (*texturedparticles)(int count, particle_t if (rampind >= type->rampindexes) rampind = type->rampindexes - 1; ramp = type->ramp + rampind; - VectorCopy(ramp->rgb, p->rgb); - p->alpha = ramp->alpha; + VectorCopy(ramp->rgb, p->rgba); + p->rgba[3] = ramp->alpha; p->scale = ramp->scale; break; case RAMP_DELTA: //particle ramps @@ -4053,18 +3941,18 @@ void PScript_DrawParticleTypes (void (*texturedparticles)(int count, particle_t if (rampind >= type->rampindexes) rampind = type->rampindexes - 1; ramp = type->ramp + rampind; - VectorMA(p->rgb, pframetime, ramp->rgb, p->rgb); - p->alpha -= pframetime*ramp->alpha; + VectorMA(p->rgba, pframetime, ramp->rgb, p->rgba); + p->rgba[3] -= pframetime*ramp->alpha; p->scale += pframetime*ramp->scale; break; case RAMP_NONE: //particle changes acording to it's preset properties. if (particletime < (p->die-type->die+type->rgbchangetime)) { - p->rgb[0] += pframetime*type->rgbchange[0]; - p->rgb[1] += pframetime*type->rgbchange[1]; - p->rgb[2] += pframetime*type->rgbchange[2]; + p->rgba[0] += pframetime*type->rgbchange[0]; + p->rgba[1] += pframetime*type->rgbchange[1]; + p->rgba[2] += pframetime*type->rgbchange[2]; } - p->alpha += pframetime*type->alphachange; + p->rgba[3] += pframetime*type->alphachange; p->scale += pframetime*type->scaledelta; } @@ -4079,15 +3967,15 @@ void PScript_DrawParticleTypes (void (*texturedparticles)(int count, particle_t } } - if (type->cliptype>=0 && r_bouncysparks.value) + if (type->cliptype>=0 && r_bouncysparks.ival) { if (traces-->0&&tr(oldorg, p->org, stop, normal)) { - if (type->stains && r_bloodstains.value) - R_AddStain(stop, p->rgb[1]*-10+p->rgb[2]*-10, - p->rgb[0]*-10+p->rgb[2]*-10, - p->rgb[0]*-10+p->rgb[1]*-10, - 30*p->alpha); + if (type->stains && r_bloodstains.ival) + R_AddStain(stop, p->rgba[1]*-10+p->rgba[2]*-10, + p->rgba[0]*-10+p->rgba[2]*-10, + p->rgba[0]*-10+p->rgba[1]*-10, + 30*p->rgba[3]); if (part_type + type->cliptype == type) { //bounce @@ -4112,14 +4000,14 @@ void PScript_DrawParticleTypes (void (*texturedparticles)(int count, particle_t continue; } } - else if (type->stains && r_bloodstains.value) + else if (type->stains && r_bloodstains.ival) { if (traces-->0&&tr(oldorg, p->org, stop, normal)) { - R_AddStain(stop, (p->rgb[1]*-10+p->rgb[2]*-10), - (p->rgb[0]*-10+p->rgb[2]*-10), - (p->rgb[0]*-10+p->rgb[1]*-10), - 30*p->alpha*type->stains); + R_AddStain(stop, (p->rgba[1]*-10+p->rgba[2]*-10), + (p->rgba[0]*-10+p->rgba[2]*-10), + (p->rgba[0]*-10+p->rgba[1]*-10), + 30*p->rgba[3]*type->stains); p->die = -1; continue; } @@ -4236,13 +4124,6 @@ void PScript_DrawParticleTypes (void (*texturedparticles)(int count, particle_t static void PScript_FlushRenderer(void) { -#ifdef RGLQUAKE - qglDepthMask(0); //primarily to stop close particles from obscuring each other - qglDisable(GL_ALPHA_TEST); - qglEnable (GL_BLEND); - GL_TexEnv(GL_MODULATE); - qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -#endif } /* @@ -4255,57 +4136,15 @@ static void PScript_DrawParticles (void) RSpeedMark(); P_AddRainParticles(); -#if defined(RGLQUAKE) - if (qrenderer == QR_OPENGL) - { - extern int gldepthfunc; - extern cvar_t r_drawflat; - - P_FlushRenderer(); - - if (qglPolygonOffset) - qglPolygonOffset(-1, 0); - qglEnable(GL_POLYGON_OFFSET_FILL); - qglEnable(GL_BLEND); - - qglDepthFunc(gldepthfunc); - - qglDisable(GL_ALPHA_TEST); - if (r_drawflat.value == 2) - PScript_DrawParticleTypes(GL_DrawSketchParticle, GL_DrawSketchSparkParticle, GL_DrawSketchSparkParticle, GL_DrawSketchSparkParticle, GL_DrawParticleBeam_Textured, GL_DrawParticleBeam_Untextured, GL_DrawClippedDecal); - else - PScript_DrawParticleTypes(GL_DrawTexturedParticle, GL_DrawLineSparkParticle, GL_DrawTrifanParticle, GL_DrawTexturedSparkParticle, GL_DrawParticleBeam_Textured, GL_DrawParticleBeam_Untextured, GL_DrawClippedDecal); - qglDisable(GL_POLYGON_OFFSET_FILL); + PScript_FlushRenderer(); - RSpeedRemark(); - RQ_RenderBatchClear(); - RSpeedEnd(RSPEED_PARTICLESDRAW); + PScript_DrawParticleTypes(GL_DrawTexturedParticle, GL_DrawLineSparkParticle, GL_DrawTrifanParticle, GL_DrawTexturedSparkParticle, GL_DrawParticleBeam, GL_DrawClippedDecal); - qglEnable(GL_TEXTURE_2D); - - GL_TexEnv(GL_MODULATE); - qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - qglDepthMask(1); - return; - } -#endif -#if defined(D3DQUAKE) - if (qrenderer == QR_DIRECT3D) - { - if (!D3D7_DrawParticles(particletime)) - D3D9_DrawParticles(particletime); - } -#endif - - if (qrenderer) - { - RSpeedRemark(); - RQ_RenderDistAndClear(); - RSpeedEnd(RSPEED_PARTICLESDRAW); - } + RSpeedRemark(); + RQ_RenderBatchClear(); + RSpeedEnd(RSPEED_PARTICLESDRAW); } @@ -4333,8 +4172,7 @@ particleengine_t pe_script = PScript_Shutdown, PScript_DelinkTrailstate, PScript_ClearParticles, - PScript_DrawParticles, - PScript_FlushRenderer + PScript_DrawParticles }; #endif diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index a703de00..81a699f3 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -16,10 +16,10 @@ #ifdef CSQC_DAT -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h" //evil to include this -#include "shader.h" #endif +#include "shader.h" //#define CHEAT_PARANOID @@ -51,6 +51,7 @@ qboolean csqc_drawsbar; qboolean csqc_addcrosshair; static int num_csqc_edicts; static int csqc_fakereadbyte; +world_t csqc_world; static int csqc_lplayernum; static qboolean csqc_isdarkplaces; @@ -58,7 +59,7 @@ static qboolean csqc_isdarkplaces; static char csqc_printbuffer[8192]; #define CSQCPROGSGROUP "CSQC progs control" -cvar_t pr_csmaxedicts = SCVAR("pr_csmaxedicts", "3072"); +cvar_t pr_csmaxedicts = SCVAR("pr_csmaxedicts", "3072"); //not tied to protocol nor server. cvar_t cl_csqcdebug = SCVAR("cl_csqcdebug", "0"); //prints entity numbers which arrive (so I can tell people not to apply it to players...) cvar_t cl_nocsqc = SCVAR("cl_nocsqc", "0"); cvar_t pr_csqc_coreonerror = SCVAR("pr_csqc_coreonerror", "1"); @@ -181,35 +182,24 @@ typedef enum globalfloat(player_localnum, "player_localnum"); /*float the entity number of the local player*/ \ globalfloat(intermission, "intermission"); /*float set when the client receives svc_intermission*/ \ globalvector(view_angles, "view_angles"); /*float set to the view angles at the start of each new frame (EXT_CSQC_1)*/ \ - globalfloat(dpcompat_sbshowscores, "sb_showscores"); /*float ask darkplaces people, its not part of the csqc standard */ \ + globalfloat(dpcompat_sbshowscores, "sb_showscores"); /*deprecated ask darkplaces people, its not part of the csqc standard */ \ \ - globalvector(pmove_org, "pmove_org"); /*read/written by runplayerphysics*/ \ - globalvector(pmove_vel, "pmove_vel"); /*read/written by runplayerphysics*/ \ - globalvector(pmove_mins, "pmove_mins"); /*read/written by runplayerphysics*/ \ - globalvector(pmove_maxs, "pmove_maxs"); /*read/written by runplayerphysics*/ \ - globalfloat(pmove_jump_held, "pmove_jump_held"); /*read/written by runplayerphysics*/ \ - globalfloat(pmove_waterjumptime, "pmove_waterjumptime"); /*read/written by runplayerphysics*/ \ + globalvector(pmove_org, "pmove_org"); /*deprecated. read/written by runplayerphysics*/ \ + globalvector(pmove_vel, "pmove_vel"); /*deprecated. read/written by runplayerphysics*/ \ + globalvector(pmove_mins, "pmove_mins"); /*deprecated. read/written by runplayerphysics*/ \ + globalvector(pmove_maxs, "pmove_maxs"); /*deprecated. read/written by runplayerphysics*/ \ + globalfloat(pmove_jump_held, "pmove_jump_held"); /*deprecated. read/written by runplayerphysics*/ \ + globalfloat(pmove_waterjumptime, "pmove_waterjumptime"); /*deprecated. read/written by runplayerphysics*/ \ \ globalfloat(input_timelength, "input_timelength"); /*float filled by getinputstate, read by runplayerphysics*/ \ globalvector(input_angles, "input_angles"); /*vector filled by getinputstate, read by runplayerphysics*/ \ globalvector(input_movevalues, "input_movevalues"); /*vector filled by getinputstate, read by runplayerphysics*/ \ globalfloat(input_buttons, "input_buttons"); /*float filled by getinputstate, read by runplayerphysics*/ \ globalfloat(input_impulse, "input_impulse"); /*float filled by getinputstate, read by runplayerphysics*/ \ - globalfloat(input_lightlevel, "input_lightlevel"); /*float filled by getinputstate, read by runplayerphysics*/ \ - globalfloat(input_weapon, "input_weapon"); /*float filled by getinputstate, read by runplayerphysics*/ \ + globalfloat(input_lightlevel, "input_lightlevel"); /*unused float filled by getinputstate, read by runplayerphysics*/ \ + globalfloat(input_weapon, "input_weapon"); /*unused float filled by getinputstate, read by runplayerphysics*/ \ globalfloat(input_servertime, "input_servertime"); /*float filled by getinputstate, read by runplayerphysics*/ \ globalfloat(input_clienttime, "input_clienttime"); /*float filled by getinputstate, read by runplayerphysics*/ \ - \ - globalfloat(movevar_gravity, "movevar_gravity"); /*float obtained from the server*/ \ - globalfloat(movevar_stopspeed, "movevar_stopspeed"); /*float obtained from the server*/ \ - globalfloat(movevar_maxspeed, "movevar_maxspeed"); /*float obtained from the server*/ \ - globalfloat(movevar_spectatormaxspeed,"movevar_spectatormaxspeed"); /*float obtained from the server*/ \ - globalfloat(movevar_accelerate, "movevar_accelerate"); /*float obtained from the server*/ \ - globalfloat(movevar_airaccelerate, "movevar_airaccelerate"); /*float obtained from the server*/ \ - globalfloat(movevar_wateraccelerate,"movevar_wateraccelerate"); /*float obtained from the server*/ \ - globalfloat(movevar_friction, "movevar_friction"); /*float obtained from the server*/ \ - globalfloat(movevar_waterfriction, "movevar_waterfriction"); /*float obtained from the server*/ \ - globalfloat(movevar_entgravity, "movevar_entgravity"); /*float obtained from the server*/ \ typedef struct { @@ -278,85 +268,78 @@ static void CSQC_FindGlobals(void) //this is the list for all the csqc fields. //(the #define is so the list always matches the ones pulled out) -#define csqcfields \ - fieldfloat(entnum); \ - fieldfloat(modelindex); \ - fieldvector(origin); \ - fieldvector(angles); \ - fieldvector(velocity); \ - fieldfloat(pmove_flags); /*transparency*/ \ - fieldfloat(alpha); /*transparency*/ \ - fieldfloat(scale); /*model scale*/ \ - fieldfloat(fatness); /*expand models X units along their normals.*/ \ - fieldfloat(skin); \ - fieldfloat(colormap); \ - fieldfloat(flags); \ - fieldfloat(frame); \ - fieldfloat(frame2); /*EXT_CSQC_1*/\ - fieldfloat(frame1time); /*EXT_CSQC_1*/\ - fieldfloat(frame2time); /*EXT_CSQC_1*/\ - fieldfloat(lerpfrac); /*EXT_CSQC_1*/\ - fieldfloat(renderflags);\ - fieldfloat(forceshader);/*FTE_CSQC_SHADERS*/\ - fieldfloat(dimension_hit); \ - fieldfloat(dimension_solid); \ +#define csqcextfields \ + comfieldfloat(entnum); \ + comfieldfloat(frame2); /*EXT_CSQC_1*/\ + comfieldfloat(frame1time); /*EXT_CSQC_1*/\ + comfieldfloat(frame2time); /*EXT_CSQC_1*/\ + comfieldfloat(lerpfrac); /*EXT_CSQC_1*/\ + comfieldfloat(renderflags);\ + comfieldfloat(forceshader);/*FTE_CSQC_SHADERS*/\ \ - fieldfloat(baseframe); /*FTE_CSQC_BASEFRAME*/\ - fieldfloat(baseframe2); /*FTE_CSQC_BASEFRAME*/\ - fieldfloat(baseframe1time); /*FTE_CSQC_BASEFRAME*/\ - fieldfloat(baseframe2time); /*FTE_CSQC_BASEFRAME*/\ - fieldfloat(baselerpfrac); /*FTE_CSQC_BASEFRAME*/\ - fieldfloat(basebone); /*FTE_CSQC_BASEFRAME*/\ + comfieldfloat(baseframe); /*FTE_CSQC_BASEFRAME*/\ + comfieldfloat(baseframe2); /*FTE_CSQC_BASEFRAME*/\ + comfieldfloat(baseframe1time); /*FTE_CSQC_BASEFRAME*/\ + comfieldfloat(baseframe2time); /*FTE_CSQC_BASEFRAME*/\ + comfieldfloat(baselerpfrac); /*FTE_CSQC_BASEFRAME*/\ + comfieldfloat(basebone); /*FTE_CSQC_BASEFRAME*/\ \ - fieldfloat(bonecontrol1); /*FTE_CSQC_HALFLIFE_MODELS*/\ - fieldfloat(bonecontrol2); /*FTE_CSQC_HALFLIFE_MODELS*/\ - fieldfloat(bonecontrol3); /*FTE_CSQC_HALFLIFE_MODELS*/\ - fieldfloat(bonecontrol4); /*FTE_CSQC_HALFLIFE_MODELS*/\ - fieldfloat(bonecontrol5); /*FTE_CSQC_HALFLIFE_MODELS*/\ - fieldfloat(subblendfrac); /*FTE_CSQC_HALFLIFE_MODELS*/\ - fieldfloat(basesubblendfrac); /*FTE_CSQC_HALFLIFE_MODELS+FTE_CSQC_BASEFRAME*/\ + comfieldfloat(bonecontrol1); /*FTE_CSQC_HALFLIFE_MODELS*/\ + comfieldfloat(bonecontrol2); /*FTE_CSQC_HALFLIFE_MODELS*/\ + comfieldfloat(bonecontrol3); /*FTE_CSQC_HALFLIFE_MODELS*/\ + comfieldfloat(bonecontrol4); /*FTE_CSQC_HALFLIFE_MODELS*/\ + comfieldfloat(bonecontrol5); /*FTE_CSQC_HALFLIFE_MODELS*/\ + comfieldfloat(subblendfrac); /*FTE_CSQC_HALFLIFE_MODELS*/\ + comfieldfloat(basesubblendfrac); /*FTE_CSQC_HALFLIFE_MODELS+FTE_CSQC_BASEFRAME*/\ \ - fieldfloat(skeletonindex); /*FTE_CSQC_SKELETONOBJECTS*/\ + comfieldfloat(skeletonindex); /*FTE_CSQC_SKELETONOBJECTS*/\ \ - fieldfloat(drawmask); /*So that the qc can specify all rockets at once or all bannanas at once*/ \ - fieldfunction(predraw); /*If present, is called just before it's drawn.*/ \ + comfieldfloat(drawmask); /*So that the qc can specify all rockets at once or all bannanas at once*/ \ + comfieldfunction(predraw); /*If present, is called just before it's drawn.*/ \ \ - fieldstring(model); \ - fieldfloat(ideal_yaw); \ - fieldfloat(ideal_pitch);\ - fieldfloat(yaw_speed); \ - fieldfloat(pitch_speed);\ - \ - fieldentity(chain); \ - fieldentity(enemy); \ - fieldentity(groundentity); \ - fieldentity(owner); \ - \ - fieldfunction(touch); \ - \ - fieldfloat(solid); \ - fieldvector(mins); \ - fieldvector(maxs); \ - fieldvector(size); \ - fieldvector(absmin); \ - fieldvector(absmax); \ - fieldfloat(hull); /*(FTE_PEXT_HEXEN2)*/ + comfieldfloat(ideal_pitch);\ + comfieldfloat(pitch_speed);\ + //note: doesn't even have to match the clprogs.dat :) typedef struct { -#define fieldfloat(name) float name -#define fieldvector(name) vec3_t name -#define fieldentity(name) int name -#define fieldstring(name) string_t name -#define fieldfunction(name) func_t name -csqcfields -#undef fieldfloat -#undef fieldvector -#undef fieldentity -#undef fieldstring -#undef fieldfunction + +#define comfieldfloat(ssqcname,sharedname,csqcname) float csqcname +#define comfieldvector(ssqcname,sharedname,csqcname) vec3_t csqcname +#define comfieldentity(ssqcname,sharedname,csqcname) int csqcname +#define comfieldstring(ssqcname,sharedname,csqcname) string_t csqcname +#define comfieldfunction(ssqcname,sharedname,csqcname) func_t csqcname +comqcfields +#undef comfieldfloat +#undef comfieldvector +#undef comfieldentity +#undef comfieldstring +#undef comfieldfunction + +#ifdef VM_Q1 } csqcentvars_t; +typedef struct { +#endif + +#define comfieldfloat(name) float name +#define comfieldvector(name) vec3_t name +#define comfieldentity(name) int name +#define comfieldstring(name) string_t name +#define comfieldfunction(name) func_t name +comextqcfields +csqcextfields +#undef comfieldfloat +#undef comfieldvector +#undef comfieldentity +#undef comfieldstring +#undef comfieldfunction + +#ifdef VM_Q1 +} csqcextentvars_t; +#else +} csqcentvars_t; +#endif typedef struct csqcedict_s { @@ -364,11 +347,29 @@ typedef struct csqcedict_s float freetime; // sv.time when the object was freed int entnum; qboolean readonly; //world +#ifdef VM_Q1 csqcentvars_t *v; + csqcextentvars_t *xv; +#else + union { + csqcentvars_t *v; + csqcentvars_t *xv; + }; +#endif + /*the above is shared with qclib*/ + link_t area; + int num_leafs; + short leafnums[MAX_ENT_LEAFS]; +#ifdef Q2BSPS + int areanum; //q2bsp + int areanum2; //q2bsp + int headnode; //q2bsp +#endif + qbyte solidtype; + /*the above is shared with ssqc*/ //add whatever you wish here trailstate_t *trailstate; - link_t area; } csqcedict_t; static csqcedict_t *csqc_edicts; //consider this 'world' @@ -376,12 +377,33 @@ static csqcedict_t *csqc_edicts; //consider this 'world' static void CSQC_InitFields(void) { //CHANGING THIS FUNCTION REQUIRES CHANGES TO csqcentvars_t -#define fieldfloat(name) PR_RegisterFieldVar(csqcprogs, ev_float, #name, (int)&((csqcentvars_t*)0)->name, -1) -#define fieldvector(name) PR_RegisterFieldVar(csqcprogs, ev_vector, #name, (int)&((csqcentvars_t*)0)->name, -1) -#define fieldentity(name) PR_RegisterFieldVar(csqcprogs, ev_entity, #name, (int)&((csqcentvars_t*)0)->name, -1) -#define fieldstring(name) PR_RegisterFieldVar(csqcprogs, ev_string, #name, (int)&((csqcentvars_t*)0)->name, -1) -#define fieldfunction(name) PR_RegisterFieldVar(csqcprogs, ev_function, #name, (int)&((csqcentvars_t*)0)->name, -1) -csqcfields //any *64->int32 casts are erroneous, it's biased off NULL. +#define comfieldfloat(ssqcname,wname,name) PR_RegisterFieldVar(csqcprogs, ev_float, #name, (int)&((csqcentvars_t*)0)->name, -1) +#define comfieldvector(ssqcname,wname,name) PR_RegisterFieldVar(csqcprogs, ev_vector, #name, (int)&((csqcentvars_t*)0)->name, -1) +#define comfieldentity(ssqcname,wname,name) PR_RegisterFieldVar(csqcprogs, ev_entity, #name, (int)&((csqcentvars_t*)0)->name, -1) +#define comfieldstring(ssqcname,wname,name) PR_RegisterFieldVar(csqcprogs, ev_string, #name, (int)&((csqcentvars_t*)0)->name, -1) +#define comfieldfunction(ssqcname,wname,name) PR_RegisterFieldVar(csqcprogs, ev_function, #name, (int)&((csqcentvars_t*)0)->name, -1) +comqcfields +#undef comfieldfloat +#undef comfieldvector +#undef comfieldentity +#undef comfieldstring +#undef comfieldfunction + +#ifdef VM_Q1 +#define comfieldfloat(name) PR_RegisterFieldVar(csqcprogs, ev_float, #name, sizeof(csqcentvars_t) + (int)&((csqcextentvars_t*)0)->name, -1) +#define comfieldvector(name) PR_RegisterFieldVar(csqcprogs, ev_vector, #name, sizeof(csqcentvars_t) + (int)&((csqcextentvars_t*)0)->name, -1) +#define comfieldentity(name) PR_RegisterFieldVar(csqcprogs, ev_entity, #name, sizeof(csqcentvars_t) + (int)&((csqcextentvars_t*)0)->name, -1) +#define comfieldstring(name) PR_RegisterFieldVar(csqcprogs, ev_string, #name, sizeof(csqcentvars_t) + (int)&((csqcextentvars_t*)0)->name, -1) +#define comfieldfunction(name) PR_RegisterFieldVar(csqcprogs, ev_function, #name, sizeof(csqcentvars_t) + (int)&((csqcextentvars_t*)0)->name, -1) +#else +#define comfieldfloat(name) PR_RegisterFieldVar(csqcprogs, ev_float, #name, (int)&((csqcentvars_t*)0)->name, -1) +#define comfieldvector(name) PR_RegisterFieldVar(csqcprogs, ev_vector, #name, (int)&((csqcentvars_t*)0)->name, -1) +#define comfieldentity(name) PR_RegisterFieldVar(csqcprogs, ev_entity, #name, (int)&((csqcentvars_t*)0)->name, -1) +#define comfieldstring(name) PR_RegisterFieldVar(csqcprogs, ev_string, #name, (int)&((csqcentvars_t*)0)->name, -1) +#define comfieldfunction(name) PR_RegisterFieldVar(csqcprogs, ev_function, #name, (int)&((csqcentvars_t*)0)->name, -1) +#endif +comextqcfields +csqcextfields #undef fieldfloat #undef fieldvector #undef fieldentity @@ -683,7 +705,7 @@ static void CS_ClipToLinks ( areanode_t *node, moveclip_t *clip ) if (clip->passedict->v->solid == SOLID_SLIDEBOX && touch->v->solid == SOLID_CORPSE) continue; - if (!((int)clip->passedict->v->dimension_hit & (int)touch->v->dimension_solid)) + if (!((int)clip->passedict->xv->dimension_hit & (int)touch->xv->dimension_solid)) continue; } @@ -710,7 +732,7 @@ static void CS_ClipToLinks ( areanode_t *node, moveclip_t *clip ) } - if (!((int)clip->passedict->v->dimension_solid & (int)touch->v->dimension_hit)) + if (!((int)clip->passedict->xv->dimension_solid & (int)touch->xv->dimension_hit)) continue; model = CSQC_GetModelForIndex(touch->v->modelindex); @@ -777,57 +799,57 @@ static void cs_getframestate(csqcedict_t *in, unsigned int rflags, framestate_t { //FTE_CSQC_HALFLIFE_MODELS #ifdef HALFLIFEMODELS - out->bonecontrols[0] = in->v->bonecontrol1; - out->bonecontrols[1] = in->v->bonecontrol2; - out->bonecontrols[2] = in->v->bonecontrol3; - out->bonecontrols[3] = in->v->bonecontrol4; - out->bonecontrols[4] = in->v->bonecontrol5; - out->g[FS_REG].subblendfrac = in->v->subblendfrac; - out->g[FST_BASE].subblendfrac = in->v->subblendfrac; + out->bonecontrols[0] = in->xv->bonecontrol1; + out->bonecontrols[1] = in->xv->bonecontrol2; + out->bonecontrols[2] = in->xv->bonecontrol3; + out->bonecontrols[3] = in->xv->bonecontrol4; + out->bonecontrols[4] = in->xv->bonecontrol5; + out->g[FS_REG].subblendfrac = in->xv->subblendfrac; + out->g[FST_BASE].subblendfrac = in->xv->subblendfrac; #endif //FTE_CSQC_BASEFRAME - out->g[FST_BASE].endbone = in->v->basebone; + out->g[FST_BASE].endbone = in->xv->basebone; if (out->g[FST_BASE].endbone) { //small optimisation. out->g[FST_BASE].endbone -= 1; - out->g[FST_BASE].frame[0] = in->v->baseframe; - out->g[FST_BASE].frame[1] = in->v->baseframe2; - out->g[FST_BASE].lerpfrac = in->v->baselerpfrac; + out->g[FST_BASE].frame[0] = in->xv->baseframe; + out->g[FST_BASE].frame[1] = in->xv->baseframe2; + out->g[FST_BASE].lerpfrac = in->xv->baselerpfrac; if (rflags & CSQCRF_FRAMETIMESARESTARTTIMES) { - out->g[FST_BASE].frametime[0] = *csqcg.svtime - in->v->baseframe1time; - out->g[FST_BASE].frametime[1] = *csqcg.svtime - in->v->baseframe2time; + out->g[FST_BASE].frametime[0] = *csqcg.svtime - in->xv->baseframe1time; + out->g[FST_BASE].frametime[1] = *csqcg.svtime - in->xv->baseframe2time; } else { - out->g[FST_BASE].frametime[0] = in->v->baseframe1time; - out->g[FST_BASE].frametime[1] = in->v->baseframe2time; + out->g[FST_BASE].frametime[0] = in->xv->baseframe1time; + out->g[FST_BASE].frametime[1] = in->xv->baseframe2time; } } //and the normal frames. out->g[FS_REG].frame[0] = in->v->frame; - out->g[FS_REG].frame[1] = in->v->frame2; - out->g[FS_REG].lerpfrac = in->v->lerpfrac; + out->g[FS_REG].frame[1] = in->xv->frame2; + out->g[FS_REG].lerpfrac = in->xv->lerpfrac; if (rflags & CSQCRF_FRAMETIMESARESTARTTIMES) { - out->g[FS_REG].frametime[0] = *csqcg.svtime - in->v->frame1time; - out->g[FS_REG].frametime[1] = *csqcg.svtime - in->v->frame2time; + out->g[FS_REG].frametime[0] = *csqcg.svtime - in->xv->frame1time; + out->g[FS_REG].frametime[1] = *csqcg.svtime - in->xv->frame2time; } else { - out->g[FS_REG].frametime[0] = in->v->frame1time; - out->g[FS_REG].frametime[1] = in->v->frame2time; + out->g[FS_REG].frametime[0] = in->xv->frame1time; + out->g[FS_REG].frametime[1] = in->xv->frame2time; } out->bonecount = 0; out->bonestate = NULL; - if (in->v->skeletonindex) + if (in->xv->skeletonindex) { skelobject_t *so; - so = skel_get(csqcprogs, in->v->skeletonindex, 0); + so = skel_get(csqcprogs, in->xv->skeletonindex, 0); if (so && so->inuse == 1) { out->bonecount = so->numbones; @@ -967,7 +989,11 @@ static model_t *CSQC_GetModelForIndex(int index) else if (index > 0 && index < MAX_MODELS) return cl.model_precache[index]; else if (index < 0 && index > -MAX_CSQCMODELS) + { + if (!cl.model_csqcprecache[-index]) + cl.model_csqcprecache[-index] = Mod_ForName(cl.model_csqcname[-index], false); return cl.model_csqcprecache[-index]; + } else return NULL; } @@ -986,9 +1012,9 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out) memset(out, 0, sizeof(*out)); out->model = model; - if (in->v->renderflags) + if (in->xv->renderflags) { - rflags = in->v->renderflags; + rflags = in->xv->renderflags; if (rflags & CSQCRF_VIEWMODEL) out->flags |= Q2RF_DEPTHHACK|Q2RF_WEAPONMODEL; if (rflags & CSQCRF_EXTERNALMODEL) @@ -996,7 +1022,7 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out) if (rflags & CSQCRF_DEPTHHACK) out->flags |= Q2RF_DEPTHHACK; if (rflags & CSQCRF_ADDITIVE) - out->flags |= Q2RF_ADDATIVE; + out->flags |= Q2RF_ADDITIVE; //CSQCRF_USEAXIS is below if (rflags & CSQCRF_NOSHADOW) out->flags |= RF_NOSHADOW; @@ -1022,14 +1048,14 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out) AngleVectors(out->angles, out->axis[0], out->axis[1], out->axis[2]); VectorInverse(out->axis[1]); - if (!in->v->scale || in->v->scale == 1.0f) + if (!in->xv->scale || in->xv->scale == 1.0f) out->scale = 1; else { - VectorScale(out->axis[0], in->v->scale, out->axis[0]); - VectorScale(out->axis[1], in->v->scale, out->axis[1]); - VectorScale(out->axis[2], in->v->scale, out->axis[2]); - out->scale = in->v->scale; + VectorScale(out->axis[0], in->xv->scale, out->axis[0]); + VectorScale(out->axis[1], in->xv->scale, out->axis[1]); + VectorScale(out->axis[2], in->xv->scale, out->axis[2]); + out->scale = in->xv->scale; } } @@ -1041,21 +1067,19 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out) out->shaderRGBAf[0] = 1; out->shaderRGBAf[1] = 1; out->shaderRGBAf[2] = 1; - if (!in->v->alpha) + if (!in->xv->alpha) out->shaderRGBAf[3] = 1; else - out->shaderRGBAf[3] = in->v->alpha; + out->shaderRGBAf[3] = in->xv->alpha; out->skinnum = in->v->skin; - out->fatness = in->v->fatness; -#ifdef Q3SHADERS - if (in->v->forceshader >= 1) - out->forcedshader = r_shaders + ((int)in->v->forceshader-1); + out->fatness = in->xv->fatness; + if (in->xv->forceshader >= 1) + out->forcedshader = r_shaders + ((int)in->xv->forceshader-1); else out->forcedshader = NULL; -#endif - out->keynum = -1; + out->keynum = -in->entnum; return true; } @@ -1112,12 +1136,71 @@ static void PF_R_AddEntity(progfuncs_t *prinst, struct globalvars_s *pr_globals) */ } -static void PF_R_AddDynamicLight(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void PF_R_DynamicLight_Set(progfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + dlight_t *l; + unsigned int lno = G_FLOAT(OFS_PARM0); + int field = G_FLOAT(OFS_PARM1); + if (lno >= cl_maxdlights) + return; + l = cl_dlights+lno; + switch (field) + { + case 0: + VectorCopy(G_VECTOR(OFS_PARM1), l->origin); + break; + case 1: + VectorCopy(G_VECTOR(OFS_PARM2), l->color); + break; + default: + break; + } +} +static void PF_R_DynamicLight_Get(progfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + dlight_t *l; + unsigned int lno = G_FLOAT(OFS_PARM0); + int field = G_FLOAT(OFS_PARM1); + if (lno >= cl_maxdlights) + { + if (field == -1) + G_FLOAT(OFS_RETURN) = cl_maxdlights; + else + G_INT(OFS_RETURN) = 0; + return; + } + l = cl_dlights+lno; + switch (field) + { + case 0: + VectorCopy(l->origin, G_VECTOR(OFS_RETURN)); + break; + case 1: + VectorCopy(l->color, G_VECTOR(OFS_RETURN)); + break; + default: + G_INT(OFS_RETURN) = 0; + break; + } +} + +static void PF_R_DynamicLight_Add(progfuncs_t *prinst, struct globalvars_s *pr_globals) { float *org = G_VECTOR(OFS_PARM0); float radius = G_FLOAT(OFS_PARM1); float *rgb = G_VECTOR(OFS_PARM2); - V_AddLight(org, radius, rgb[0]/5, rgb[1]/5, rgb[2]/5); +// float style = G_FLOAT(OFS_PARM3); +// char *cubemapname = G_STRING(OFS_PARM4); +// float pflags = G_FLOAT(OFS_PARM5); + + csqcedict_t *self; + + //if the org matches self, then attach it. + self = (csqcedict_t*)PROG_TO_EDICT(prinst, *csqcg.self); + if (VectorCompare(self->v->origin, org)) + G_FLOAT(OFS_RETURN) = V_AddLight(-self->entnum, org, radius, rgb[0]/5, rgb[1]/5, rgb[2]/5); + else + G_FLOAT(OFS_RETURN) = V_AddLight(0, org, radius, rgb[0]/5, rgb[1]/5, rgb[2]/5); } static void PF_R_AddEntityMask(progfuncs_t *prinst, struct globalvars_s *pr_globals) @@ -1144,12 +1227,12 @@ static void PF_R_AddEntityMask(progfuncs_t *prinst, struct globalvars_s *pr_glob if (ent->isfree) continue; - if ((int)ent->v->drawmask & mask) + if ((int)ent->xv->drawmask & mask) { - if (ent->v->predraw) + if (ent->xv->predraw) { *csqcg.self = EDICT_TO_PROG(prinst, (void*)ent); - PR_ExecuteProgram(prinst, ent->v->predraw); + PR_ExecuteProgram(prinst, ent->xv->predraw); if (ent->isfree) continue; //bummer... @@ -1172,6 +1255,77 @@ static void PF_R_AddEntityMask(progfuncs_t *prinst, struct globalvars_s *pr_glob } } +static shader_t *csqc_shadern; +static int csqc_startpolyvert; +// #306 void(string texturename) R_BeginPolygon (EXT_CSQC_???) +static void PF_R_PolygonBegin(progfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + csqc_shadern = R_RegisterSkin(PR_GetStringOfs(prinst, OFS_PARM0)); + csqc_startpolyvert = cl_numstrisvert; +} + +// #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex (EXT_CSQC_???) +static void PF_R_PolygonVertex(progfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + if (cl_numstrisvert == cl_maxstrisvert) + { + cl_maxstrisvert+=64; + cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(*cl_strisvertv)*cl_maxstrisvert); + cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(*cl_strisvertt)*cl_maxstrisvert); + cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(*cl_strisvertc)*cl_maxstrisvert); + } + + VectorCopy(G_VECTOR(OFS_PARM0), cl_strisvertv[cl_numstrisvert]); + Vector2Copy(G_VECTOR(OFS_PARM1), cl_strisvertt[cl_numstrisvert]); + VectorCopy(G_VECTOR(OFS_PARM2), cl_strisvertc[cl_numstrisvert]); + cl_strisvertc[cl_numstrisvert][3] = G_FLOAT(OFS_PARM3); + cl_numstrisvert++; +} + +// #308 void() R_EndPolygon (EXT_CSQC_???) +static void PF_R_PolygonEnd(progfuncs_t *prinst, struct globalvars_s *pr_globals) +{ + scenetris_t *t; + int i; + int nv; + /*if the shader didn't change, continue with the old poly*/ + if (cl_numstris && cl_stris[cl_numstris-1].shader == csqc_shadern) + t = &cl_stris[cl_numstris-1]; + else + { + if (cl_numstris == cl_maxstris) + { + cl_maxstris+=8; + cl_stris = BZ_Realloc(cl_stris, sizeof(*cl_stris)*cl_maxstris); + } + t = &cl_stris[cl_numstris++]; + t->shader = csqc_shadern; + t->firstidx = cl_numstrisidx; + t->firstvert = csqc_startpolyvert; + t->numvert = 0; + t->numidx = 0; + } + + nv = cl_numstrisvert-csqc_startpolyvert; + if (cl_numstrisidx+(nv-2)*3 > cl_maxstrisidx) + { + cl_maxstrisidx=cl_numstrisidx+(nv-2)*3 + 64; + cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx); + } + + /*build the triangle fan out of triangles*/ + for (i = 2; i < nv; i++) + { + cl_strisidx[cl_numstrisidx++] = t->numvert + 0; + cl_strisidx[cl_numstrisidx++] = t->numvert + i-1; + cl_strisidx[cl_numstrisidx++] = t->numvert + i; + } + t->numidx = cl_numstrisidx - t->firstidx; + t->numvert += cl_numstrisvert-csqc_startpolyvert; + + /*set up ready for the next poly*/ + csqc_startpolyvert = cl_numstrisvert; +} qboolean csqc_rebuildmatricies; @@ -1557,7 +1711,7 @@ static void PF_R_RenderScene(progfuncs_t *prinst, struct globalvars_s *pr_global if (cl.worldmodel) R_PushDlights (); -#ifdef RGLQUAKE +#ifdef GLQUAKE if (qrenderer == QR_OPENGL) { gl_ztrickdisabled|=16; @@ -1573,7 +1727,7 @@ static void PF_R_RenderScene(progfuncs_t *prinst, struct globalvars_s *pr_global R_RenderView(); -#ifdef RGLQUAKE +#ifdef GLQUAKE if (qrenderer == QR_OPENGL) { gl_ztrickdisabled&=~16; @@ -1583,7 +1737,7 @@ static void PF_R_RenderScene(progfuncs_t *prinst, struct globalvars_s *pr_global } #endif -#ifdef RGLQUAKE +#ifdef GLQUAKE if (qrenderer == QR_OPENGL) { qglDisable(GL_ALPHA_TEST); @@ -1613,7 +1767,7 @@ static void PF_R_RenderScene(progfuncs_t *prinst, struct globalvars_s *pr_global static void PF_cs_getstatf(progfuncs_t *prinst, struct globalvars_s *pr_globals) { int stnum = G_FLOAT(OFS_PARM0); - float val = *(float*)&cl.stats[csqc_lplayernum][stnum]; //copy float into the stat + float val = cl.statsf[csqc_lplayernum][stnum]; //copy float into the stat G_FLOAT(OFS_RETURN) = val; } static void PF_cs_getstati(progfuncs_t *prinst, struct globalvars_s *pr_globals) @@ -1720,10 +1874,10 @@ static void PF_cs_traceline(progfuncs_t *prinst, struct globalvars_s *pr_globals maxs = vec3_origin; } - savedhull = ent->v->hull; - ent->v->hull = 0; + savedhull = ent->xv->hull; + ent->xv->hull = 0; trace = CS_Move (v1, mins, maxs, v2, nomonsters, ent); - ent->v->hull = savedhull; + ent->xv->hull = savedhull; cs_settracevars(&trace); } @@ -1742,10 +1896,10 @@ static void PF_cs_tracebox(progfuncs_t *prinst, struct globalvars_s *pr_globals) nomonsters = G_FLOAT(OFS_PARM4); ent = (csqcedict_t*)G_EDICT(prinst, OFS_PARM5); - savedhull = ent->v->hull; - ent->v->hull = 0; + savedhull = ent->xv->hull; + ent->xv->hull = 0; trace = CS_Move (v1, mins, maxs, v2, nomonsters, ent); - ent->v->hull = savedhull; + ent->xv->hull = savedhull; *csqcg.trace_allsolid = trace.allsolid; *csqcg.trace_startsolid = trace.startsolid; @@ -1783,8 +1937,8 @@ static trace_t CS_Trace_Toss (csqcedict_t *tossent, csqcedict_t *ignore) CS_CheckVelocity (tossent); - savedhull = tossent->v->hull; - tossent->v->hull = 0; + savedhull = tossent->xv->hull; + tossent->xv->hull = 0; for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds { velocity[2] -= gravity; @@ -1798,7 +1952,7 @@ static trace_t CS_Trace_Toss (csqcedict_t *tossent, csqcedict_t *ignore) if (trace.fraction < 1 && trace.ent && (void*)trace.ent != ignore) break; } - tossent->v->hull = savedhull; + tossent->xv->hull = savedhull; trace.fraction = 0; // not relevant return trace; @@ -2175,7 +2329,7 @@ static void PF_cs_sendevent (progfuncs_t *prinst, struct globalvars_s *pr_global { ent = (csqcedict_t*)G_EDICT(prinst, OFS_PARM2+i*3); MSG_WriteByte(&cls.netchan.message, ev_entity); - MSG_WriteShort(&cls.netchan.message, ent->v->entnum); + MSG_WriteShort(&cls.netchan.message, ent->xv->entnum); } else break; @@ -2360,7 +2514,7 @@ typedef struct { if (ent) { - pmove.jump_held = (int)ent->v->pmove_flags & PMF_JUMP_HELD; + pmove.jump_held = (int)ent->xv->pmove_flags & PMF_JUMP_HELD; pmove.waterjumptime = 0; VectorCopy(ent->v->origin, pmove.origin); VectorCopy(ent->v->velocity, pmove.velocity); @@ -2397,12 +2551,13 @@ typedef struct { ent->v->angles[0] *= -1/3.0f; VectorCopy(pmove.origin, ent->v->origin); VectorCopy(pmove.velocity, ent->v->velocity); - ent->v->pmove_flags = 0; - ent->v->pmove_flags += pmove.jump_held ? PMF_JUMP_HELD : 0; - ent->v->pmove_flags += pmove.onladder ? PMF_LADDER : 0; + ent->xv->pmove_flags = 0; + ent->xv->pmove_flags += pmove.jump_held ? PMF_JUMP_HELD : 0; + ent->xv->pmove_flags += pmove.onladder ? PMF_LADDER : 0; } else { + //Legacy path if (csqcg.pmove_jump_held) *csqcg.pmove_jump_held = pmove.jump_held; if (csqcg.pmove_waterjumptime) @@ -2463,7 +2618,7 @@ static void PF_cs_serverkey (progfuncs_t *prinst, struct globalvars_s *pr_global ret = "Unknown"; break; case CP_QUAKEWORLD: - if (cls.fteprotocolextensions) + if (cls.fteprotocolextensions||cls.fteprotocolextensions2) ret = "QuakeWorld FTE"; else if (cls.z_ext) ret = "QuakeWorld ZQuake"; @@ -2786,8 +2941,8 @@ static void PF_cs_changepitch (progfuncs_t *prinst, struct globalvars_s *pr_glob ent = (void*)PROG_TO_EDICT(prinst, *csqcg.self); current = anglemod( ent->v->angles[0] ); - ideal = ent->v->ideal_pitch; - speed = ent->v->pitch_speed; + ideal = ent->xv->ideal_pitch; + speed = ent->xv->pitch_speed; if (current == ideal) return; @@ -3287,11 +3442,7 @@ static void PF_cs_gecko_create (progfuncs_t *prinst, struct globalvars_s *pr_glo { char *shader = PR_GetStringOfs(prinst, OFS_PARM0); cin_t *cin; -#ifdef Q3SHADERS cin = R_ShaderGetCinematic(shader); -#else - cin = NULL; -#endif if (!cin) G_FLOAT(OFS_RETURN) = 0; @@ -3308,11 +3459,7 @@ static void PF_cs_gecko_navigate (progfuncs_t *prinst, struct globalvars_s *pr_g char *shader = PR_GetStringOfs(prinst, OFS_PARM0); char *command = PR_GetStringOfs(prinst, OFS_PARM1); cin_t *cin; -#ifdef Q3SHADERS cin = R_ShaderGetCinematic(shader); -#else - cin = NULL; -#endif if (!cin) return; @@ -3326,11 +3473,7 @@ static void PF_cs_gecko_keyevent (progfuncs_t *prinst, struct globalvars_s *pr_g int key = G_FLOAT(OFS_PARM1); int eventtype = G_FLOAT(OFS_PARM2); cin_t *cin; -#ifdef Q3SHADERS cin = R_ShaderGetCinematic(shader); -#else - cin = NULL; -#endif if (!cin) return; @@ -3343,11 +3486,7 @@ static void PF_cs_gecko_mousemove (progfuncs_t *prinst, struct globalvars_s *pr_ float posx = G_FLOAT(OFS_PARM1); float posy = G_FLOAT(OFS_PARM2); cin_t *cin; -#ifdef Q3SHADERS cin = R_ShaderGetCinematic(shader); -#else - cin = NULL; -#endif if (!cin) return; @@ -3360,11 +3499,7 @@ static void PF_cs_gecko_resize (progfuncs_t *prinst, struct globalvars_s *pr_glo float sizex = G_FLOAT(OFS_PARM1); float sizey = G_FLOAT(OFS_PARM2); cin_t *cin; -#ifdef Q3SHADERS cin = R_ShaderGetCinematic(shader); -#else - cin = NULL; -#endif if (!cin) return; Media_Send_Resize(cin, sizex, sizey); @@ -3376,12 +3511,7 @@ static void PF_cs_gecko_get_texture_extent (progfuncs_t *prinst, struct globalva float *ret = G_VECTOR(OFS_RETURN); int sx, sy; cin_t *cin; -#ifdef Q3SHADERS cin = R_ShaderGetCinematic(shader); -#else - cin = NULL; -#endif - if (cin) { Media_Send_GetSize(cin, &sx, &sy); @@ -3481,7 +3611,7 @@ static void PF_rotatevectorsbytag (progfuncs_t *prinst, struct globalvars_s *pr_ int i; framestate_t fstate; - cs_getframestate(ent, ent->v->renderflags, &fstate); + cs_getframestate(ent, ent->xv->renderflags, &fstate); if (Mod_GetTag(mod, tagnum, &fstate, transforms)) { @@ -3492,14 +3622,14 @@ static void PF_rotatevectorsbytag (progfuncs_t *prinst, struct globalvars_s *pr_ VectorCopy(csqcg.up, src+8); src[11] = 0; - if (ent->v->scale) + if (ent->xv->scale) { for (i = 0; i < 12; i+=4) { - transforms[i+0] *= ent->v->scale; - transforms[i+1] *= ent->v->scale; - transforms[i+2] *= ent->v->scale; - transforms[i+3] *= ent->v->scale; + transforms[i+0] *= ent->xv->scale; + transforms[i+1] *= ent->xv->scale; + transforms[i+2] *= ent->xv->scale; + transforms[i+3] *= ent->xv->scale; } } @@ -3549,7 +3679,7 @@ static void PF_cs_gettaginfo (progfuncs_t *prinst, struct globalvars_s *pr_globa framestate_t fstate; - cs_getframestate(ent, ent->v->renderflags, &fstate); + cs_getframestate(ent, ent->xv->renderflags, &fstate); #pragma message("PF_cs_gettaginfo: This function doesn't honour attachments (but setattachment isn't implemented yet anyway)") if (!Mod_GetTag(mod, tagnum, &fstate, transforms)) @@ -3627,11 +3757,11 @@ static void PF_frameforname (progfuncs_t *prinst, struct globalvars_s *pr_global static void PF_frameduration (progfuncs_t *prinst, struct globalvars_s *pr_globals) { int modelindex = G_FLOAT(OFS_PARM0); - char *str = PF_VarString(prinst, 1, pr_globals); + int frameno = G_FLOAT(OFS_PARM1); model_t *mod = CSQC_GetModelForIndex(modelindex); if (mod && Mod_GetFrameDuration) - G_FLOAT(OFS_RETURN) = Mod_GetFrameDuration(mod, str); + G_FLOAT(OFS_RETURN) = Mod_GetFrameDuration(mod, frameno); else G_FLOAT(OFS_RETURN) = 0; } @@ -3650,21 +3780,23 @@ static void PF_skinforname (progfuncs_t *prinst, struct globalvars_s *pr_globals static void PF_shaderforname (progfuncs_t *prinst, struct globalvars_s *pr_globals) { char *str = PF_VarString(prinst, 0, pr_globals); -#ifdef Q3SHADERS + shader_t *shad; shad = R_RegisterSkin(str); if (shad) G_FLOAT(OFS_RETURN) = shad-r_shaders + 1; else G_FLOAT(OFS_RETURN) = 0; -#else - G_FLOAT(OFS_RETURN) = 0; -#endif } void skel_reset(void) { - numskelobjectsused = 0; + while (numskelobjectsused > 0) + { + numskelobjectsused--; + skelobjects[numskelobjectsused].numbones = 0; + skelobjects[numskelobjectsused].inuse = false; + } } void skel_dodelete(void) @@ -3697,7 +3829,7 @@ skelobject_t *skel_get(progfuncs_t *prinst, int skelidx, int bonecount) { skelobjects[skelidx].numbones = bonecount; skelobjects[skelidx].bonematrix = (float*)PR_AddString(prinst, "", sizeof(float)*12*bonecount); - if (skelidx < numskelobjectsused) + if (skelidx <= numskelobjectsused) { numskelobjectsused = skelidx + 1; skelobjects[skelidx].model = NULL; @@ -3782,7 +3914,7 @@ static void PF_skel_build(progfuncs_t *prinst, struct globalvars_s *pr_globals) if (!model) return; //invalid model, can't get a skeleton - cs_getframestate(ent, ent->v->renderflags, &fstate); + cs_getframestate(ent, ent->xv->renderflags, &fstate); //heh... don't copy. fstate.bonecount = 0; @@ -3895,15 +4027,15 @@ static void PF_skel_get_bonerel (progfuncs_t *prinst, struct globalvars_s *pr_gl if (!skelobj || skelobj->absolute || (unsigned int)boneidx >= skelobj->numbones) { matrix[0][0] = 1; - matrix[0][1] = 0; - matrix[0][2] = 0; - matrix[1][0] = 0; - matrix[1][1] = 1; - matrix[1][2] = 0; - matrix[2][0] = 0; + + matrix[0][1] = 0; + matrix[1][1] = 1; matrix[2][1] = 0; + + matrix[0][2] = 0; + matrix[1][2] = 0; matrix[2][2] = 1; matrix[3][0] = 0; @@ -3912,10 +4044,19 @@ static void PF_skel_get_bonerel (progfuncs_t *prinst, struct globalvars_s *pr_gl } else { - memcpy(matrix[0], skelobj->bonematrix + boneidx*12 + 0, sizeof(vec3_t)); - memcpy(matrix[1], skelobj->bonematrix + boneidx*12 + 3, sizeof(vec3_t)); - memcpy(matrix[2], skelobj->bonematrix + boneidx*12 + 6, sizeof(vec3_t)); - memcpy(matrix[3], skelobj->bonematrix + boneidx*12 + 9, sizeof(vec3_t)); + float *bone = skelobj->bonematrix+12*boneidx; + matrix[0][0] = bone[0]; + matrix[1][0] = bone[1]; + matrix[2][0] = bone[2]; + matrix[3][0] = bone[3]; + matrix[0][1] = bone[4]; + matrix[1][1] = bone[5]; + matrix[2][1] = bone[6]; + matrix[3][1] = bone[7]; + matrix[0][2] = bone[8]; + matrix[1][2] = bone[9]; + matrix[2][2] = bone[10]; + matrix[3][2] = bone[11]; } } @@ -3996,6 +4137,7 @@ static void PF_skel_set_bone (progfuncs_t *prinst, struct globalvars_s *pr_globa unsigned int boneidx = G_FLOAT(OFS_PARM1)-1; float *matrix[4]; skelobject_t *skelobj; + float *bone; if (*prinst->callargc > 5) { @@ -4016,10 +4158,19 @@ static void PF_skel_set_bone (progfuncs_t *prinst, struct globalvars_s *pr_globa if (!skelobj || boneidx >= skelobj->numbones) return; //testme - VectorCopy(matrix[0], skelobj->bonematrix+12*boneidx+0); - VectorCopy(matrix[1], skelobj->bonematrix+12*boneidx+3); - VectorCopy(matrix[2], skelobj->bonematrix+12*boneidx+6); - VectorCopy(matrix[3], skelobj->bonematrix+12*boneidx+9); + bone = skelobj->bonematrix+12*boneidx; + bone[0] = matrix[0][0]; + bone[1] = matrix[1][0]; + bone[2] = matrix[2][0]; + bone[3] = matrix[3][0]; + bone[4] = matrix[0][1]; + bone[5] = matrix[1][1]; + bone[6] = matrix[2][1]; + bone[7] = matrix[3][1]; + bone[8] = matrix[0][2]; + bone[9] = matrix[1][2]; + bone[10]= matrix[2][2]; + bone[11]= matrix[3][2]; } //void(float skel, float bonenum, vector org) skel_mul_bone (FTE_CSQC_SKELETONOBJECTS) (reads v_forward etc) @@ -4197,10 +4348,10 @@ realcheck: start[0] = stop[0] = x ? maxs[0] : mins[0]; start[1] = stop[1] = y ? maxs[1] : mins[1]; - savedhull = ent->v->hull; - ent->v->hull = 0; + savedhull = ent->xv->hull; + ent->xv->hull = 0; trace = CS_Move (start, vec3_origin, vec3_origin, stop, true, ent); - ent->v->hull = savedhull; + ent->xv->hull = savedhull; if (trace.fraction != 1.0 && trace.endpos[2] > bottom) bottom = trace.endpos[2]; @@ -4428,11 +4579,11 @@ static void PF_cs_setlistener (progfuncs_t *prinst, struct globalvars_s *pr_glob static void CSQC_LerpStateToCSQC(lerpents_t *le, csqcedict_t *ent, qboolean nolerp) { ent->v->frame = le->newframe; - ent->v->frame1time = max(0, cl.servertime - le->newframestarttime); - ent->v->frame2 = le->oldframe; - ent->v->frame2time = max(0, cl.servertime - le->newframestarttime); + ent->xv->frame1time = max(0, cl.servertime - le->newframestarttime); + ent->xv->frame2 = le->oldframe; + ent->xv->frame2time = max(0, cl.servertime - le->newframestarttime); - ent->v->lerpfrac = bound(0, cl.servertime - le->newframestarttime, 0.1); + ent->xv->lerpfrac = bound(0, cl.servertime - le->newframestarttime, 0.1); /* if (nolerp) @@ -4469,14 +4620,14 @@ void CSQC_EntStateToCSQC(unsigned int flags, float lerptime, entity_state_t *src if (!(flags & RSES_NOTRAILS)) { //use entnum as a test to see if its new (if the old origin isn't usable) - if (ent->v->entnum && model->particletrail >= 0) + if (ent->xv->entnum && model->particletrail >= 0) { if (pe->ParticleTrail (ent->v->origin, src->origin, model->particletrail, &(le->trailstate))) pe->ParticleTrailIndex(ent->v->origin, src->origin, model->traildefaultindex, 0, &(le->trailstate)); } } - ent->v->entnum = src->number; + ent->xv->entnum = src->number; ent->v->modelindex = src->modelindex; // ent->v->bitmask = src->bitmask; ent->v->flags = src->flags; @@ -4488,15 +4639,15 @@ void CSQC_EntStateToCSQC(unsigned int flags, float lerptime, entity_state_t *src ent->v->skin = src->skinnum; // ent->v->glowsize = src->glowsize; // ent->v->glowcolor = src->glowcolour; - ent->v->scale = src->scale/16.0f; - ent->v->fatness = src->fatness/16.0f; + ent->xv->scale = src->scale/16.0f; + ent->xv->fatness = src->fatness/16.0f; // ent->v->hexen2flags = src->hexen2flags; // ent->v->abslight = src->abslight; // ent->v->dpflags = src->dpflags; // ent->v->colormod[0] = (src->colormod[0]/255.0f)*8; // ent->v->colormod[1] = (src->colormod[1]/255.0f)*8; // ent->v->colormod[2] = (src->colormod[2]/255.0f)*8; - ent->v->alpha = src->trans/255.0f; + ent->xv->alpha = src->trans/255.0f; // ent->v->lightstyle = src->lightstyle; // ent->v->lightpflags = src->lightpflags; // ent->v->solid = src->solid; @@ -4519,7 +4670,7 @@ void CSQC_EntStateToCSQC(unsigned int flags, float lerptime, entity_state_t *src } void CSQC_PlayerStateToCSQC(int pnum, player_state_t *srcp, csqcedict_t *ent) { - ent->v->entnum = pnum+1; + ent->xv->entnum = pnum+1; if (cl.spectator && !Cam_DrawPlayer(0, pnum)) { @@ -4538,9 +4689,9 @@ void CSQC_PlayerStateToCSQC(int pnum, player_state_t *srcp, csqcedict_t *ent) VectorCopy(srcp->velocity, ent->v->velocity); ent->v->angles[0] *= -0.333; ent->v->colormap = pnum+1; - ent->v->scale = srcp->scale/16.0f; + ent->xv->scale = srcp->scale/16.0f; //ent->v->fatness = srcp->fatness; - ent->v->alpha = srcp->alpha/255.0f; + ent->xv->alpha = srcp->alpha/255.0f; // ent->v->colormod[0] = (srcp->colormod[0]/255.0f)*8; // ent->v->colormod[1] = (srcp->colormod[1]/255.0f)*8; @@ -4595,7 +4746,7 @@ qboolean CSQC_DeltaPlayer(int playernum, player_state_t *state) ent = (csqcedict_t *)ED_Alloc(csqcprogs); CSQC_PlayerStateToCSQC(playernum, state, ent); - ent->v->drawmask = MASK_DELTA; + ent->xv->drawmask = MASK_DELTA; *csqcg.self = EDICT_TO_PROG(csqcprogs, (void*)ent); pr_globals = PR_globals(csqcprogs, PR_CURRENT); @@ -4686,7 +4837,7 @@ qboolean CSQC_DeltaUpdate(entity_state_t *src) ent = (csqcedict_t *)ED_Alloc(csqcprogs); CSQC_EntStateToCSQC(deltaflags[src->modelindex], csqcdelta_time, src, ent); - ent->v->drawmask = MASK_DELTA; + ent->xv->drawmask = MASK_DELTA; *csqcg.self = EDICT_TO_PROG(csqcprogs, (void*)ent); @@ -4927,10 +5078,6 @@ void PF_ReadServerEntityState(progfuncs_t *prinst, struct globalvars_s *pr_globa //these are the builtins that still need to be added. #define PS_cs_setattachment PF_Fixme -#define PF_R_PolygonBegin PF_Fixme // #306 void(string texturename) R_BeginPolygon (EXT_CSQC_???) -#define PF_R_PolygonVertex PF_Fixme // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex (EXT_CSQC_???) -#define PF_R_PolygonEnd PF_Fixme // #308 void() R_EndPolygon (EXT_CSQC_???) - //warning: functions that depend on globals are bad, mkay? static struct { char *name; @@ -5142,7 +5289,7 @@ static struct { {"setproperty", PF_R_SetViewFlag, 303}, // #303 float(float property, ...) setproperty (EXT_CSQC) {"renderscene", PF_R_RenderScene, 304}, // #304 void() renderscene (EXT_CSQC) - {"adddynamiclight", PF_R_AddDynamicLight, 305}, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC) + {"dynamiclight_add", PF_R_DynamicLight_Add, 305}, // #305 float(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC) {"R_BeginPolygon", PF_R_PolygonBegin, 306}, // #306 void(string texturename) R_BeginPolygon (EXT_CSQC_???) {"R_PolygonVertex", PF_R_PolygonVertex, 307}, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex (EXT_CSQC_???) @@ -5239,6 +5386,9 @@ static struct { // {"readsingleentitystate", PF_ReadSingleEntityState, 370}, {"deltalisten", PF_DeltaListen, 371}, // #371 float(string modelname, float flags) deltalisten (EXT_CSQC_1) + {"dynamiclight_get", PF_R_DynamicLight_Get, 372}, + {"dynamiclight_set", PF_R_DynamicLight_Set, 373}, + //400 {"copyentity", PF_cs_copyentity, 400}, // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY) {"setcolors", PF_NoCSQC, 401}, // #401 void(entity cl, float colours) setcolors (DP_SV_SETCOLOR) (don't implement) @@ -5465,6 +5615,31 @@ void CSQC_ForgetThreads(void) } } +void CSQC_EntSpawn (struct edict_s *e, int loading) +{ + struct csqcedict_s *ent = (csqcedict_t*)e; +#ifdef VM_Q1 + if (!ent->xv) + ent->xv = (csqcextentvars_t *)(ent->v+1); +#endif +} +pbool CSQC_EntFree (struct edict_s *e) +{ + struct csqcedict_s *ent = (csqcedict_t*)e; + ent->v->solid = SOLID_NOT; + ent->xv->drawmask = 0; + ent->v->modelindex = 0; + ent->v->think = 0; + ent->v->nextthink = 0; + +#ifdef USEODE + World_Physics_RemoveFromEntity(&csqc_world, (wedict_t*)ent); + World_Physics_RemoveJointFromEntity(&csqc_world, (wedict_t*)ent); +#endif + + return true; +} + void CSQC_Shutdown(void) { search_close_progs(csqcprogs, false); @@ -5645,8 +5820,8 @@ qboolean CSQC_Init (unsigned int checksum) csqcprogparms.Abort = CSQC_Abort; csqcprogparms.edictsize = sizeof(csqcedict_t); - csqcprogparms.entspawn = NULL;//void (*entspawn) (struct edict_s *ent); //ent has been spawned, but may not have all the extra variables (that may need to be set) set - csqcprogparms.entcanfree = NULL;//bool (*entcanfree) (struct edict_s *ent); //return true to stop ent from being freed + csqcprogparms.entspawn = CSQC_EntSpawn;//void (*entspawn) (struct edict_s *ent); //ent has been spawned, but may not have all the extra variables (that may need to be set) set + csqcprogparms.entcanfree = CSQC_EntFree;//bool (*entcanfree) (struct edict_s *ent); //return true to stop ent from being freed csqcprogparms.stateop = NULL;//StateOp;//void (*stateop) (float var, func_t func); csqcprogparms.cstateop = NULL;//CStateOp; csqcprogparms.cwstateop = NULL;//CWStateOp; @@ -6281,7 +6456,7 @@ void CSQC_ParseEntities(void) { ent = (csqcedict_t*)ED_Alloc(csqcprogs); csqcent[entnum] = ent; - ent->v->entnum = entnum; + ent->xv->entnum = entnum; G_FLOAT(OFS_PARM0) = true; if (cl_csqcdebug.value) diff --git a/engine/client/pr_menu.c b/engine/client/pr_menu.c index 7cd5140c..31a43c80 100644 --- a/engine/client/pr_menu.c +++ b/engine/client/pr_menu.c @@ -2,12 +2,10 @@ #ifdef MENU_DAT -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h" -#ifdef Q3SHADERS +#endif #include "shader.h" -#endif -#endif #include "pr_common.h" @@ -349,8 +347,7 @@ void PF_CL_drawcharacter (progfuncs_t *prinst, struct globalvars_s *pr_globals) float alpha = G_FLOAT(OFS_PARM4); // float flag = G_FLOAT(OFS_PARM5); - const float fsize = 0.0625; - float frow, fcol; + int x, y; if (!chara) { @@ -358,14 +355,12 @@ void PF_CL_drawcharacter (progfuncs_t *prinst, struct globalvars_s *pr_globals) return; } - chara &= 255; - frow = (chara>>4)*fsize; - fcol = (chara&15)*fsize; - - if (Draw_ImageColours) - Draw_ImageColours(rgb[0], rgb[1], rgb[2], alpha); - if (Draw_Image) - Draw_Image(pos[0], pos[1], size[0], size[1], fcol, frow, fcol+fsize, frow+fsize, Draw_CachePic("conchars")); +#pragma message("fixme: this doesn't scale or colour chars") + Font_BeginString(font_conchar, pos[0], pos[1], &x, &y); + Font_ForceColour(rgb[0], rgb[1], rgb[2], alpha); + Font_DrawChar(x, y, 0xe000|(chara&0xff)); + Font_ForceColour(1, 1, 1, 1); + Font_EndString(font_conchar); G_FLOAT(OFS_RETURN) = 1; } @@ -375,9 +370,10 @@ void PF_CL_drawrawstring (progfuncs_t *prinst, struct globalvars_s *pr_globals) float *pos = G_VECTOR(OFS_PARM0); char *text = PR_GetStringOfs(prinst, OFS_PARM1); float *size = G_VECTOR(OFS_PARM2); -// float *rgb = G_VECTOR(OFS_PARM3); -// float alpha = G_FLOAT(OFS_PARM4); + float *rgb = G_VECTOR(OFS_PARM3); + float alpha = G_FLOAT(OFS_PARM4); // float flag = G_FLOAT(OFS_PARM5); + int x, y; if (!text) { @@ -385,12 +381,15 @@ void PF_CL_drawrawstring (progfuncs_t *prinst, struct globalvars_s *pr_globals) return; } +#pragma message("fixme: this doesn't scale") + Font_BeginString(font_conchar, pos[0], pos[1], &x, &y); + Font_ForceColour(rgb[0], rgb[1], rgb[2], alpha); while(*text) { - G_FLOAT(OFS_PARM1) = *text++; - PF_CL_drawcharacter(prinst, pr_globals); - pos[0] += size[0]; + x = Font_DrawChar(x, y, 0xe000|(*text++&0xff)); } + Font_ForceColour(1, 1, 1, 1); + Font_EndString(font_conchar); } //float drawstring(vector position, string text, vector scale, float alpha, float flag) = #455; @@ -435,9 +434,19 @@ void PF_CL_stringwidth(progfuncs_t *prinst, struct globalvars_s *pr_globals) #define DRAWFLAG_MODULATE 2 #define DRAWFLAG_MODULATE2 3 -#ifdef Q3SHADERS -void GLDraw_ShaderPic (int x, int y, int width, int height, shader_t *pic, float r, float g, float b, float a); -#endif +static void PF_SelectDPDrawFlag(int flag) +{ + //flags: + //0 = blend + //1 = add + //2 = modulate + //3 = modulate*2 + if (flag == 1) + BE_SelectMode(BEM_STANDARD, BEF_FORCEADDITIVE); + else + BE_SelectMode(BEM_STANDARD, BEF_FORCETRANSPARENT); +} + //float drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag) = #456; void PF_CL_drawpic (progfuncs_t *prinst, struct globalvars_s *pr_globals) { @@ -446,46 +455,16 @@ void PF_CL_drawpic (progfuncs_t *prinst, struct globalvars_s *pr_globals) float *size = G_VECTOR(OFS_PARM2); float *rgb = G_VECTOR(OFS_PARM3); float alpha = G_FLOAT(OFS_PARM4); - float flag = G_FLOAT(OFS_PARM5); + int flag = (int)G_FLOAT(OFS_PARM5); mpic_t *p; -#ifdef RGLQUAKE - if (qrenderer == QR_OPENGL) - { -#ifdef Q3SHADERS - shader_t *s; - - s = R_RegisterCustom(picname, NULL, NULL); - if (s) - { - GLDraw_ShaderPic(pos[0], pos[1], size[0], size[1], s, rgb[0], rgb[1], rgb[2], alpha); - return; - } -#endif - - if (flag == 1) //add - qglBlendFunc(GL_SRC_ALPHA, GL_ONE); - else if(flag == 2) //modulate - qglBlendFunc(GL_DST_COLOR, GL_ZERO); - else if(flag == 3) //modulate*2 - qglBlendFunc(GL_DST_COLOR,GL_SRC_COLOR); - else //blend - qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } -#endif - p = Draw_SafeCachePic(picname); - if (Draw_ImageColours) - Draw_ImageColours(rgb[0], rgb[1], rgb[2], alpha); - if (Draw_Image) - Draw_Image(pos[0], pos[1], size[0], size[1], 0, 0, 1, 1, p); - -#ifdef RGLQUAKE - if (qrenderer == QR_OPENGL) - qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -#endif + PF_SelectDPDrawFlag(flag); + Draw_ImageColours(rgb[0], rgb[1], rgb[2], alpha); + Draw_Image(pos[0], pos[1], size[0], size[1], 0, 0, 1, 1, p); + BE_SelectMode(BEM_STANDARD, 0); G_FLOAT(OFS_RETURN) = 1; } @@ -503,49 +482,16 @@ void PF_CL_drawsubpic (progfuncs_t *prinst, struct globalvars_s *pr_globals) mpic_t *p; - if(pos[2] || size[2]) - Con_Printf("VM_drawsubpic: z value%s from %s discarded\n",(pos[2] && size[2]) ? "s" : " ",((pos[2] && size[2]) ? "pos and size" : (pos[2] ? "pos" : "size"))); - -#ifdef RGLQUAKE - if (qrenderer == QR_OPENGL) - { -#ifdef Q3SHADERS - shader_t *s; - - s = R_RegisterCustom(picname, NULL, NULL); - if (s) - { - GLDraw_ShaderPic(pos[0], pos[1], size[0], size[1], s, rgb[0], rgb[1], rgb[2], alpha); - return; - } -#endif - - if (flag == 1) //add - qglBlendFunc(GL_SRC_ALPHA, GL_ONE); - else if(flag == 2) //modulate - qglBlendFunc(GL_DST_COLOR, GL_ZERO); - else if(flag == 3) //modulate*2 - qglBlendFunc(GL_DST_COLOR,GL_SRC_COLOR); - else //blend - qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } -#endif - p = Draw_SafeCachePic(picname); - if (Draw_ImageColours) - Draw_ImageColours(rgb[0], rgb[1], rgb[2], alpha); - if (Draw_Image) - Draw_Image( pos[0], pos[1], - size[0], size[1], - srcPos[0], srcPos[1], - srcPos[0]+srcSize[0], srcPos[1]+srcSize[1], - p); - -#ifdef RGLQUAKE - if (qrenderer == QR_OPENGL) - qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -#endif + PF_SelectDPDrawFlag(flag); + Draw_ImageColours(rgb[0], rgb[1], rgb[2], alpha); + Draw_Image( pos[0], pos[1], + size[0], size[1], + srcPos[0], srcPos[1], + srcPos[0]+srcSize[0], srcPos[1]+srcSize[1], + p); + BE_SelectMode(BEM_STANDARD, 0); G_FLOAT(OFS_RETURN) = 1; } @@ -557,7 +503,7 @@ void PF_CL_drawfill (progfuncs_t *prinst, struct globalvars_s *pr_globals) float *size = G_VECTOR(OFS_PARM1); float *rgb = G_VECTOR(OFS_PARM2); float alpha = G_FLOAT(OFS_PARM3); -#ifdef RGLQUAKE +#ifdef GLQUAKE if (qrenderer == QR_OPENGL) { qglColor4f(rgb[0], rgb[1], rgb[2], alpha); @@ -581,15 +527,15 @@ void PF_CL_drawsetcliparea (progfuncs_t *prinst, struct globalvars_s *pr_globals { float x = G_FLOAT(OFS_PARM0), y = G_FLOAT(OFS_PARM1), w = G_FLOAT(OFS_PARM2), h = G_FLOAT(OFS_PARM3); -#ifdef RGLQUAKE +#ifdef GLQUAKE if (qrenderer == QR_OPENGL && qglScissor) { - x *= (float)glwidth/vid.width; - y *= (float)glheight/vid.height; + x *= (float)vid.pixelwidth/vid.width; + y *= (float)vid.pixelheight/vid.height; - w *= (float)glwidth/vid.width; - h *= (float)glheight/vid.height; + w *= (float)vid.pixelwidth/vid.width; + h *= (float)vid.pixelheight/vid.height; //add a pixel because this makes DP's menus come out right. x-=1; @@ -598,7 +544,7 @@ void PF_CL_drawsetcliparea (progfuncs_t *prinst, struct globalvars_s *pr_globals h+=2; - qglScissor (x, glheight-(y+h), w, h); + qglScissor (x, vid.pixelheight-(y+h), w, h); qglEnable(GL_SCISSOR_TEST); G_FLOAT(OFS_RETURN) = 1; return; @@ -609,7 +555,7 @@ void PF_CL_drawsetcliparea (progfuncs_t *prinst, struct globalvars_s *pr_globals //void drawresetcliparea(void) = #459; void PF_CL_drawresetcliparea (progfuncs_t *prinst, struct globalvars_s *pr_globals) { -#ifdef RGLQUAKE +#ifdef GLQUAKE if (qrenderer == QR_OPENGL) { qglDisable(GL_SCISSOR_TEST); @@ -628,7 +574,7 @@ void PF_CL_drawline (progfuncs_t *prinst, struct globalvars_s *pr_globals) float *pos = G_VECTOR(OFS_PARM4); int numpoints = *prinst->callargc-4; -#ifdef RGLQUAKE // :( +#ifdef GLQUAKE // :( if (qrenderer == QR_OPENGL) { @@ -1762,7 +1708,7 @@ void MP_Draw(void) if (setjmp(mp_abort)) return; -#ifdef RGLQUAKE +#ifdef GLQUAKE if (qrenderer == QR_OPENGL) { GL_TexEnv(GL_MODULATE); diff --git a/engine/client/q2.ico b/engine/client/q2.ico index a2019ff9279ce258eaf03dc7db988674f9fecf4e..372ebcf245ff032ebe1f491a421bfcb50c4ee185 100644 GIT binary patch delta 75 zcmZ1{x=vJ=fq{{MnL$B8fPsO5h2aGg1A`fmWnci|XRt9a$T2f82nc}r6Ln<;8GuS) M03;}|F*=wF03MkJ+5i9m delta 68 zcmZ1{x=vJ=fq{{MnL$B8fB^(vFflNg0cisR2tR|3fkBR$fk8k3%%7+$%hbR$c_EX; MWFKayjmtQ=02B)ekpKVy diff --git a/engine/client/quakedef.h b/engine/client/quakedef.h index dd356b30..1759f8b9 100644 --- a/engine/client/quakedef.h +++ b/engine/client/quakedef.h @@ -24,10 +24,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "bothdefs.h" //first thing included by ALL files. -#if _MSC_VER -#define MSVCDISABLEWARNINGS -#endif - #ifdef MSVCDISABLEWARNINGS //#pragma warning( disable : 4244 4127 4201 4214 4514 4305 4115 4018) /*#pragma warning( disable : 4244) //conversion from const double to float @@ -81,8 +77,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #pragma warning( 4 : 4267) //truncation from const double to float +#pragma warning( error : 4020) -//#pragma warning(error:4013) +#pragma warning(error:4013) #endif @@ -91,11 +88,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define WATERLAYERS -#ifdef GLQUAKE -#define RGLQUAKE -#undef GLQUAKE //compiler option -#endif - #ifdef SERVERONLY #define isDedicated true #endif @@ -151,7 +143,7 @@ extern "C" { #include "vm.h" -//#if defined(RGLQUAKE) +//#if defined(GLQUAKE) #include "gl_model.h" //#else //#include "model.h" @@ -189,12 +181,12 @@ extern "C" { #if (_MSC_VER >= 1400) //with MSVC 8, use MS extensions #define snprintf linuxlike_snprintf_vc8 -int VARGS linuxlike_snprintf_vc8(char *buffer, int size, const char *format, ...); +int VARGS linuxlike_snprintf_vc8(char *buffer, int size, const char *format, ...) LIKEPRINTF(3); #define vsnprintf(a, b, c, d) vsnprintf_s(a, b, _TRUNCATE, c, d) #else //msvc crap #define snprintf linuxlike_snprintf -int VARGS linuxlike_snprintf(char *buffer, int size, const char *format, ...); +int VARGS linuxlike_snprintf(char *buffer, int size, const char *format, ...) LIKEPRINTF(3); #define vsnprintf linuxlike_vsnprintf int VARGS linuxlike_vsnprintf(char *buffer, int size, const char *format, va_list argptr); #endif @@ -256,12 +248,12 @@ void Host_ServerFrame (void); void Host_InitCommands (void); void Host_Init (quakeparms_t *parms); void Host_Shutdown(void); -void VARGS Host_Error (char *error, ...); -void VARGS Host_EndGame (char *message, ...); +NORETURN void VARGS Host_Error (char *error, ...) LIKEPRINTF(1); +NORETURN void VARGS Host_EndGame (char *message, ...) LIKEPRINTF(1); qboolean Host_SimulationTime(float time); void Host_Frame (double time); void Host_Quit_f (void); -void VARGS Host_ClientCommands (char *fmt, ...); +void VARGS Host_ClientCommands (char *fmt, ...) LIKEPRINTF(1); void Host_ShutdownServer (qboolean crash); extern qboolean msg_suppress_1; // suppresses resolution and cache size console output @@ -274,6 +266,14 @@ extern qboolean isDedicated; +void FTE_DEPRECATED GL_DrawAliasMesh (mesh_t *mesh, texid_t texnum); +void FTE_DEPRECATED R_RenderMeshBuffer(struct meshbuffer_s *mb, qboolean shadowpass); + + + + + + #ifdef __cplusplus } #endif diff --git a/engine/client/r_2d.c b/engine/client/r_2d.c new file mode 100644 index 00000000..923dce12 --- /dev/null +++ b/engine/client/r_2d.c @@ -0,0 +1,278 @@ +#include "quakedef.h" +#ifndef SERVERONLY +#include "shader.h" +#include "gl_draw.h" + +texid_t missing_texture; +static mpic_t *conback; +static mpic_t *draw_backtile; +mpic_t *draw_disc; + +static mesh_t draw_mesh; +static vecV_t draw_mesh_xyz[4]; +static vec2_t draw_mesh_st[4]; +static avec4_t draw_mesh_colors[4]; +static index_t r_quad_indexes[6] = {0, 1, 2, 0, 2, 3}; + +extern cvar_t scr_conalpha; +extern cvar_t gl_conback; +extern cvar_t gl_font; + +void R2D_Conback_Callback(struct cvar_s *var, char *oldvalue); + + +//We need this for minor things though, so we'll just use the slow accurate method. +//this is unlikly to be called too often. +qbyte GetPaletteIndex(int red, int green, int blue) +{ + //slow, horrible method. + { + int i, best=15; + int bestdif=256*256*256, curdif; + extern qbyte *host_basepal; + qbyte *pa; + + #define _abs(x) ((x)*(x)) + + pa = host_basepal; + for (i = 0; i < 256; i++, pa+=3) + { + curdif = _abs(red - pa[0]) + _abs(green - pa[1]) + _abs(blue - pa[2]); + if (curdif < bestdif) + { + if (curdif<1) + return i; + bestdif = curdif; + best = i; + } + } + return best; + } +} + +/* +Iniitalise the 2d rendering functions (including font). +Image loading code must be ready for use at this point. +*/ +void R2D_Init(void) +{ + BE_Init(); + draw_mesh.numvertexes = 4; + draw_mesh.numindexes = 6; + draw_mesh.xyz_array = draw_mesh_xyz; + draw_mesh.st_array = draw_mesh_st; + draw_mesh.colors4f_array = draw_mesh_colors; + draw_mesh.indexes = r_quad_indexes; + + + Font_Init(); + +#pragma message("Fixme: move conwidth handling into here") + + + if (font_conchar) + Font_Free(font_conchar); + font_conchar = Font_LoadFont(8*vid.pixelheight/vid.height, gl_font.string); + if (!font_conchar && *gl_font.string) + font_conchar = Font_LoadFont(8*vid.pixelheight/vid.height, ""); + + missing_texture = R_LoadTexture8("no_texture", 16, 16, (unsigned char*)r_notexture_mip + r_notexture_mip->offsets[0], IF_NOALPHA|IF_NOGAMMA, 0); + + draw_backtile = Draw_SafePicFromWad ("backtile"); + if (!draw_backtile) + draw_backtile = Draw_SafeCachePic ("gfx/menu/backtile.lmp"); + + Cvar_Hook(&gl_conback, R2D_Conback_Callback); +} + +mpic_t *R2D_SafeCachePic (char *path) +{ + shader_t *s = R_RegisterPic(path); + if (s->width) + return s; + return NULL; +} + + +char *failedpic; //easier this way +mpic_t *R2D_SafePicFromWad (char *name) +{ + char newname[32]; + shader_t *s; + snprintf(newname, sizeof(newname), "gfx/%s.lmp", name); + s = R_RegisterPic(newname); + if (s->width) + return s; + failedpic = name; + return NULL; +} + + +void R2D_ImageColours(float r, float g, float b, float a) +{ + draw_mesh_colors[0][0] = r; + draw_mesh_colors[0][1] = g; + draw_mesh_colors[0][2] = b; + draw_mesh_colors[0][3] = a; + Vector4Copy(draw_mesh_colors[0], draw_mesh_colors[1]); + Vector4Copy(draw_mesh_colors[0], draw_mesh_colors[2]); + Vector4Copy(draw_mesh_colors[0], draw_mesh_colors[3]); +} + +//awkward and weird to use +void R2D_Image(float x, float y, float w, float h, float s1, float t1, float s2, float t2, mpic_t *pic) +{ + if (!pic) + return; +/* + if (w == 0 && h == 0) + { + w = pic->width; + h = pic->height; + } +*/ + draw_mesh_xyz[0][0] = x; + draw_mesh_xyz[0][1] = y; + draw_mesh_st[0][0] = s1; + draw_mesh_st[0][1] = t1; + + draw_mesh_xyz[1][0] = x+w; + draw_mesh_xyz[1][1] = y; + draw_mesh_st[1][0] = s2; + draw_mesh_st[1][1] = t1; + + draw_mesh_xyz[2][0] = x+w; + draw_mesh_xyz[2][1] = y+h; + draw_mesh_st[2][0] = s2; + draw_mesh_st[2][1] = t2; + + draw_mesh_xyz[3][0] = x; + draw_mesh_xyz[3][1] = y+h; + draw_mesh_st[3][0] = s1; + draw_mesh_st[3][1] = t2; + + BE_DrawMeshChain(pic, &draw_mesh, NULL, &pic->defaulttextures); +} + +void R2D_ScalePic (int x, int y, int width, int height, mpic_t *pic) +{ + R2D_Image(x, y, width, height, 0, 0, 1, 1, pic); +} + +void R2D_SubPic(int x, int y, int width, int height, mpic_t *pic, int srcx, int srcy, int srcwidth, int srcheight) +{ + float newsl, newtl, newsh, newth; + + newsl = (srcx)/(float)srcwidth; + newsh = newsl + (width)/(float)srcwidth; + + newtl = (srcy)/(float)srcheight; + newth = newtl + (height)/(float)srcheight; + + R2D_Image(x, y, width, height, newsl, newtl, newsh, newth, pic); +} + +/* +================ +Draw_ConsoleBackground + +================ +*/ +void R2D_ConsoleBackground (int firstline, int lastline, qboolean forceopaque) +{ + float a; + int w, h; + if (!conback) + return; + + w = vid.conwidth; + h = vid.conheight; + + if (forceopaque) + { + a = 1; // console background is necessary + } + else + { + if (!scr_conalpha.value) + return; + + a = scr_conalpha.value; + } + + if (scr_chatmode == 2) + { + h>>=1; + w>>=1; + } + if (a >= 1) + { + R2D_ImageColours(1, 1, 1, 1); + R2D_ScalePic(0, lastline-(int)vid.conheight, w, h, conback); + } + else + { + R2D_ImageColours(1, 1, 1, a); + R2D_ScalePic (0, lastline - (int)vid.conheight, w, h, conback); + R2D_ImageColours(1, 1, 1, 1); + } +} + +void R2D_EditorBackground (void) +{ + R2D_ScalePic(0, 0, vid.conwidth, vid.conheight, conback); +} + +/* +============= +Draw_TileClear + +This repeats a 64*64 tile graphic to fill the screen around a sized down +refresh window. +============= +*/ +void R2D_TileClear (int x, int y, int w, int h) +{ + float newsl, newsh, newtl, newth; + newsl = (x)/(float)64; + newsh = newsl + (w)/(float)64; + + newtl = (y)/(float)64; + newth = newtl + (h)/(float)64; + + R2D_ImageColours(1,1,1,1); + + draw_mesh_xyz[0][0] = x; + draw_mesh_xyz[0][1] = y; + draw_mesh_st[0][0] = newsl; + draw_mesh_st[0][1] = newtl; + + draw_mesh_xyz[1][0] = x+w; + draw_mesh_xyz[1][1] = y; + draw_mesh_st[1][0] = newsh; + draw_mesh_st[1][1] = newtl; + + draw_mesh_xyz[2][0] = x+w; + draw_mesh_xyz[2][1] = y+h; + draw_mesh_st[2][0] = newsh; + draw_mesh_st[2][1] = newth; + + draw_mesh_xyz[3][0] = x; + draw_mesh_xyz[3][1] = y+h; + draw_mesh_st[3][0] = newsl; + draw_mesh_st[3][1] = newth; + + BE_DrawMeshChain(draw_backtile, &draw_mesh, NULL, NULL); +} + +void R2D_Conback_Callback(struct cvar_s *var, char *oldvalue) +{ + if (*var->string) + conback = R_RegisterPic(var->string); + if (!conback || !conback->width) + conback = R_RegisterCustom("console", NULL, NULL); + if (!conback || !conback->width) + conback = R_RegisterPic("gfx/conback.lmp"); +} + +#endif diff --git a/engine/client/r_bulleten.c b/engine/client/r_bulleten.c index 5ff2c860..1807a0b4 100644 --- a/engine/client/r_bulleten.c +++ b/engine/client/r_bulleten.c @@ -25,7 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" #ifdef PEXT_BULLETENS -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h"//hack #endif @@ -390,12 +390,12 @@ player_info_t *s; #endif R_MakeBulleten(a->texture, a->bultextleft, a->bultexttop, text, a->normaltexture); -#ifdef RGLQUAKE +#ifdef GLQUAKE if (qrenderer == QR_OPENGL) { GL_Bind(a->texture->tn.base); - GL_Upload8 ("bulleten", (qbyte *)a->texture + a->texture->offsets[0], a->texture->width, a->texture->height, false, false); + GL_Upload8 ("bulleten", (qbyte *)a->texture + a->texture->offsets[0], a->texture->width, a->texture->height, IF_NOMIPMAP|IF_NOALPHA|IF_NOGAMMA, 0); } #endif } diff --git a/engine/client/r_bulleten.h b/engine/client/r_bulleten.h index a99a2a13..72c6e5ad 100644 --- a/engine/client/r_bulleten.h +++ b/engine/client/r_bulleten.h @@ -28,10 +28,6 @@ extern bulletentexture_t *bulletentexture; extern qbyte *draw_chars; //console text - -extern int scoreboardlines; -extern int fragsort[]; - qboolean R_AddBulleten (texture_t *textur); void R_MakeBulleten (texture_t *textur, int lefttext, int toptext, char *text, qbyte *background); //void R_MakeBulleten (texture_t *textur, int lefttext, int toptext, char *text); diff --git a/engine/client/r_efrag.c b/engine/client/r_efrag.c index 27174a57..1d21ec11 100644 --- a/engine/client/r_efrag.c +++ b/engine/client/r_efrag.c @@ -222,7 +222,7 @@ void R_StoreEfrags (efrag_t **ppefrag) pent = pefrag->entity; clmodel = pent->model; - if ((!r_drawflame.value) && (clmodel->engineflags & MDLF_FLAME)) + if ((!r_drawflame.ival) && (clmodel->engineflags & MDLF_FLAME)) break; // switch (clmodel->type) @@ -243,7 +243,7 @@ void R_StoreEfrags (efrag_t **ppefrag) pent->visframe = r_framecount; // emit particles for statics (we don't need to cheat check statics) - if (clmodel->particleeffect >= 0 && gl_part_flame.value) + if (clmodel->particleeffect >= 0 && gl_part_flame.ival) { // TODO: this is ugly.. assumes ent is in static entities, and subtracts // pointer math to get an index to use in cl_static emit diff --git a/engine/client/r_part.c b/engine/client/r_part.c index 2472327d..95bfe69d 100644 --- a/engine/client/r_part.c +++ b/engine/client/r_part.c @@ -122,7 +122,6 @@ cvar_t r_part_sparks = SCVAR("r_part_sparks", "1"); cvar_t r_part_sparks_trifan = SCVAR("r_part_sparks_trifan", "1"); cvar_t r_part_sparks_textured = SCVAR("r_part_sparks_textured", "1"); cvar_t r_part_beams = SCVAR("r_part_beams", "1"); -cvar_t r_part_beams_textured = SCVAR("r_part_beams_textured", "1"); cvar_t r_part_contentswitch = SCVAR("r_part_contentswitch", "1"); @@ -150,7 +149,6 @@ void P_InitParticleSystem(void) Cvar_Register(&r_part_sparks_trifan, particlecvargroupname); Cvar_Register(&r_part_sparks_textured, particlecvargroupname); Cvar_Register(&r_part_beams, particlecvargroupname); - Cvar_Register(&r_part_beams_textured, particlecvargroupname); Cvar_Register(&r_part_contentswitch, particlecvargroupname); Cvar_Register (&gl_part_flame, particlecvargroupname); diff --git a/engine/client/render.h b/engine/client/render.h index 43860773..bf324faa 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -31,6 +31,29 @@ extern int r_framecount; struct msurface_s; +typedef union { + int num; +#ifdef D3DQUAKE + void *ptr; +#endif +} texid_t; +static const texid_t r_nulltex = {0}; +#define TEXVALID(t) (t.num!=0) + + +#ifdef D3DQUAKE + #define sizeof_index_t 2 +#endif +#if sizeof_index_t == 2 + #define GL_INDEX_TYPE GL_UNSIGNED_SHORT + #define D3DFMT_QINDEX D3DFMT_INDEX16 + typedef unsigned short index_t; +#else + #define GL_INDEX_TYPE GL_UNSIGNED_INT + #define D3DFMT_QINDEX D3DFMT_INDEX32 + typedef unsigned int index_t; +#endif + //============================================================================= typedef struct efrag_s @@ -93,9 +116,7 @@ typedef struct entity_s refEntityType_t rtype; float rotation; -#ifdef Q3SHADERS struct shader_s *forcedshader; -#endif #ifdef PEXT_SCALE float scale; @@ -155,16 +176,13 @@ extern struct texture_s *r_notexture_mip; extern entity_t r_worldentity; -#if defined(RGLQUAKE) +#if defined(GLQUAKE) void GLR_Init (void); void GLR_ReInit (void); void GLR_InitTextures (void); void GLR_InitEfrags (void); void GLR_RenderView (void); // must set r_refdef first // called whenever r_refdef or vid change -void GLR_InitSky (struct texture_s *mt); // called at level load -void GLR_SetSky (char *name, float rotate, vec3_t axis); -qboolean GLR_CheckSky(void); void GLR_AddEfrags (entity_t *ent); void GLR_RemoveEfrags (entity_t *ent); @@ -182,14 +200,10 @@ void MediaGL_ShowFrame8bit(qbyte *framedata, int inwidth, int inheight, qbyte *p void MediaGL_ShowFrameRGBA_32(qbyte *framedata, int inwidth, int inheight); //top down void MediaGL_ShowFrameBGR_24_Flip(qbyte *framedata, int inwidth, int inheight); //input is bottom up... -void GLR_SetSky (char *name, float rotate, vec3_t axis); -qboolean GLR_CheckSky(void); -void GLR_AddStain(vec3_t org, float red, float green, float blue, float radius); -void GLR_LessenStains(void); - void GLVID_DeInit (void); void GLR_DeInit (void); void GLSCR_DeInit (void); +void GLVID_Console_Resize(void); int GLR_LightPoint (vec3_t p); #endif @@ -198,27 +212,33 @@ int GLR_LightPoint (vec3_t p); void R_AddEfrags (entity_t *ent); void R_RemoveEfrags (entity_t *ent); +enum imageflags +{ + /*warning: many of these flags only apply the first time it is requested*/ + IF_CLAMP = 1<<0, + IF_NOPICMIP = 1<<1, + IF_NOMIPMAP = 1<<2, + IF_NOALPHA = 1<<3, + IF_NOGAMMA = 1<<4 +}; -//normalmaps -//bumpmaps -//32bits -//8bits -//8bitpal24 -//8bitpal32 +enum uploadfmt +{ + TF_INVALID, + TF_RGBA32, /*rgba byte order*/ + TF_BGRA32, /*bgra byte order*/ + TF_RGBX32, /*rgb byte order, with extra wasted byte after blue*/ + TF_RGB24, /*bgr byte order, no alpha channel nor pad, and top down*/ + TF_BGR24_FLIP, /*bgr byte order, no alpha channel nor pad, and bottom up*/ + TF_SOLID8, /*8bit quake-palette image*/ + TF_TRANS8, /*8bit quake-palette image, index 255=transparent*/ + TF_TRANS8_FULLBRIGHT, /*fullbright 8 - fullbright texels have alpha 255, everything else 0*/ + TF_HEIGHT8, /*image data is greyscale, convert to a normalmap and load that, uploaded alpha contains the original heights*/ + TF_H2_T7G1, /*8bit data, odd indexes give greyscale transparence*/ + TF_H2_TRANS8_0, /*8bit data, 0 is transparent, not 255*/ + TF_H2_T4A4 /*8bit data, weird packing*/ +}; -#define TF_NOMIPMAP 0x0000 -#define TF_NOTBUMPMAP 0x0000 -#define TF_NOALPHA 0x0000 - -#define TF_MIPMAP 0x0001 -#define TF_BUMPMAP 0x0002 //or normalmap, depending on 8/24 bitness -#define TF_ALPHA 0x0004 //preserve alpha channel (8biit, use index 255 for transparency) - -#define TF_FULLBRIGHT 0x0008 //dark pixels have alpha forced to 0 -#define TF_24BIT 0x0010 -#define TF_32BIT 0x0020 //use the standard quake palette - -#define TF_MANDATORY (TF_NOMIPMAP|TF_NOTBUMPMAP|TF_NOALPHA) #if 0 /* @@ -278,65 +298,100 @@ int R_LoadTexture(char *name, int width, int height, void *data, void *palette, #define R_FindTexture(name) R_LoadTexture(name, 0, 0, NULL, NULL, 0) #define R_LoadCompressed(name) ((qrenderer == QR_OPENGL)?GL_LoadCompressed(name):0) */ -#elif defined(RGLQUAKE) && defined(D3DQUAKE) +#elif defined(GLQUAKE) && defined(D3DQUAKE) #define R_LoadTexture8Pal32(skinname,width,height,data,palette,usemips,alpha) ((qrenderer == QR_DIRECT3D)?D3D_LoadTexture8Pal32(skinname, width, height, data, palette, usemips, alpha):GL_LoadTexture8Pal32(skinname, width, height, data, palette, usemips, alpha)) #define R_LoadTexture8Pal24(skinname,width,height,data,palette,usemips,alpha) ((qrenderer == QR_DIRECT3D)?D3D_LoadTexture8Pal24(skinname, width, height, data, palette, usemips, alpha):GL_LoadTexture8Pal24(skinname, width, height, data, palette, usemips, alpha)) - #define R_LoadTexture8(skinname,width,height,data,usemips,alpha) ((qrenderer == QR_DIRECT3D)?D3D_LoadTexture(skinname, width, height, data, usemips, alpha):GL_LoadTexture(skinname, width, height, data, usemips, alpha)) - #define R_LoadTexture32(skinname,width,height,data,usemips,alpha) ((qrenderer == QR_DIRECT3D)?D3D_LoadTexture32(skinname, width, height, data, usemips, alpha):GL_LoadTexture32(skinname, width, height, data, usemips, alpha)) - #define R_LoadTextureFB(skinname,width,height,data,usemips,alpha) ((qrenderer == QR_DIRECT3D)?D3D_LoadTextureFB(skinname, width, height, data, usemips, alpha):GL_LoadTextureFB(skinname, width, height, data, usemips, alpha)) - #define R_LoadTexture8Bump(skinname,width,height,data,usemips,alpha) ((qrenderer == QR_DIRECT3D)?D3D_LoadTexture8Bump(skinname, width, height, data, usemips, alpha):GL_LoadTexture8Bump(skinname, width, height, data, usemips, alpha)) - + #define R_FindTexture(name) ((qrenderer == QR_DIRECT3D)?D3D_FindTexture(name):GL_FindTexture(name)) #define R_LoadCompressed(name) ((qrenderer == QR_DIRECT3D)?D3D_LoadCompressed(name):GL_LoadCompressed(name)) #elif defined(D3DQUAKE) - #define R_LoadTexture8Pal32 D3D_LoadTexture8Pal32 - #define R_LoadTexture8Pal24 D3D_LoadTexture8Pal24 - #define R_LoadTexture8 D3D_LoadTexture - #define R_LoadTexture32 D3D_LoadTexture32 - #define R_LoadTextureFB D3D_LoadTextureFB - #define R_LoadTexture8Bump D3D_LoadTexture8Bump +// #define R_LoadTexture8Pal32 +// #define R_LoadTexture8Pal24 #define R_FindTexture D3D_FindTexture #define R_LoadCompressed D3D_LoadCompressed -#elif defined(RGLQUAKE) + + #define R_AllocNewTexture D3D_AllocNewTexture + #define R_Upload D3D_UploadFmt + #define R_LoadTexture D3D_LoadTextureFmt + #define R_DestroyTexture(tno) 0 +#elif defined(GLQUAKE) #define R_LoadTexture8Pal32 GL_LoadTexture8Pal32 #define R_LoadTexture8Pal24 GL_LoadTexture8Pal24 - #define R_LoadTexture8 GL_LoadTexture - #define R_LoadTexture32 GL_LoadTexture32 - #define R_LoadTextureFB GL_LoadTextureFB - #define R_LoadTexture8Bump GL_LoadTexture8Bump #define R_FindTexture GL_FindTexture #define R_LoadCompressed GL_LoadCompressed + + #define R_AllocNewTexture(w,h) GL_AllocNewTexture() + #define R_Upload GL_UploadFmt + #define R_LoadTexture GL_LoadTextureFmt + #define R_DestroyTexture(tno) 0 #endif +#define R_LoadTexture8(id,w,h,d,f,t) R_LoadTexture(id,w,h,t?TF_TRANS8:TF_SOLID8,d,f) +#define R_LoadTexture32(id,w,h,d,f) R_LoadTexture(id,w,h,TF_RGBA32,d,f) +#define R_LoadTextureFB(id,w,h,d,f) R_LoadTexture(id,w,h,TF_TRANS8_FULLBRIGHT,d,f) +#define R_LoadTexture8Bump(id,w,h,d,f) R_LoadTexture(id,w,h,TF_HEIGHT8,d,f) +/*it seems a little excessive to have to include glquake (and windows headers), just to load some textures/shaders for the backend*/ +#ifdef GLQUAKE +texid_t GL_AllocNewTexture(void); +void GL_UploadFmt(texid_t tex, char *name, enum uploadfmt fmt, void *data, int width, int height, unsigned int flags); +texid_t GL_LoadTextureFmt (char *identifier, int width, int height, enum uploadfmt fmt, void *data, unsigned int flags); +#endif +#ifdef D3DQUAKE +texid_t D3D_AllocNewTexture(int width, int height); +void D3D_UploadFmt(texid_t tex, char *name, enum uploadfmt fmt, void *data, int width, int height, unsigned int flags); +texid_t D3D_LoadTextureFmt (char *identifier, int width, int height, enum uploadfmt fmt, void *data, unsigned int flags); + +texid_t D3D_LoadCompressed(char *name); +texid_t D3D_FindTexture (char *identifier); +#endif + +extern int image_width, image_height; +texid_t R_LoadReplacementTexture(char *name, char *subpath, unsigned int flags); +texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags); +texid_t R_LoadBumpmapTexture(char *name, char *subpath); + +extern texid_t particletexture; +extern texid_t particlecqtexture; +extern texid_t explosiontexture; +extern texid_t balltexture; +extern texid_t beamtexture; +extern texid_t ptritexture; void GL_ParallelPerspective(double xmin, double xmax, double ymax, double ymin, double znear, double zfar); void GL_InfinatePerspective(double fovx, double fovy, double zNear); -#if defined(RGLQUAKE) || defined(D3DQUAKE) +#if defined(GLQUAKE) || defined(D3DQUAKE) -void GLMod_Init (void); +void RMod_Init (void); int Mod_TagNumForName(struct model_s *model, char *name); int Mod_SkinNumForName(struct model_s *model, char *name); int Mod_FrameNumForName(struct model_s *model, char *name); float Mod_FrameDuration(struct model_s *model, int frameno); -void GLMod_ClearAll (void); -struct model_s *GLMod_ForName (char *name, qboolean crash); -struct model_s *GLMod_FindName (char *name); -void *GLMod_Extradata (struct model_s *mod); // handles caching -void GLMod_TouchModel (char *name); +void RMod_ClearAll (void); +struct model_s *RMod_ForName (char *name, qboolean crash); +struct model_s *RMod_FindName (char *name); +void *RMod_Extradata (struct model_s *mod); // handles caching +void RMod_TouchModel (char *name); -struct mleaf_s *GLMod_PointInLeaf (struct model_s *model, float *p); +struct mleaf_s *RMod_PointInLeaf (struct model_s *model, float *p); -void GLMod_Think (void); -void GLMod_NowLoadExternal(void); +void RMod_Think (void); +void RMod_NowLoadExternal(void); void GLR_WipeStains(void); void GLR_LoadSkys (void); +void R_BloomRegister(void); #endif +#ifdef RUNTIMELIGHTING +void LightFace (int surfnum); +void LightLoadEntities(char *entstring); +#endif + + extern struct model_s *currentmodel; qboolean Media_ShowFilm(void); @@ -347,11 +402,13 @@ double Media_TweekCaptureFrameTime(double time); void MYgluPerspective(double fovx, double fovy, double zNear, double zFar); -void R_MarkLeaves_Q1 (void); -void R_MarkLeaves_Q2 (void); -void R_MarkLeaves_Q3 (void); -void R_SetFrustum (void); +qbyte *R_MarkLeaves_Q1 (void); +qbyte *R_CalcVis_Q1 (void); +qbyte *R_MarkLeaves_Q2 (void); +qbyte *R_MarkLeaves_Q3 (void); +void R_SetFrustum (float projmat[16], float viewmat[16]); void R_SetRenderer(int wanted); +void R_AnimateLight (void); void RQ_Init(void); void CLQ2_EntityEvent(entity_state_t *es); @@ -380,6 +437,7 @@ void SaturateR8G8B8(qbyte *data, int size, float sat); void AddOcranaLEDsIndexed (qbyte *image, int h, int w); void Renderer_Init(void); +void R_ShutdownRenderer(void); void R_RestartRenderer_f (void);//this goes here so we can save some stack when first initing the sw renderer. //used to live in glquake.h @@ -393,7 +451,8 @@ extern cvar_t r_speeds; extern cvar_t r_waterwarp; extern cvar_t r_fullbright; extern cvar_t r_lightmap; -extern cvar_t r_shadows; +extern cvar_t r_shadow_realtime_dlight, r_shadow_realtime_dlight_shadows; +extern cvar_t r_shadow_realtime_world,r_shadow_realtime_world_shadows; extern cvar_t r_mirroralpha; extern cvar_t r_wateralpha; extern cvar_t r_dynamic; @@ -463,9 +522,12 @@ int rquant[RQUANT_MAX]; #define RQuantAdd(type,quant) rquant[type] += quant; #define RSpeedLocals() int rsp -#define RSpeedMark() int rsp = r_speeds.value?Sys_DoubleTime()*1000000:0 -#define RSpeedRemark() rsp = r_speeds.value?Sys_DoubleTime()*1000000:0 +#define RSpeedMark() int rsp = r_speeds.ival?Sys_DoubleTime()*1000000:0 +#define RSpeedRemark() rsp = r_speeds.ival?Sys_DoubleTime()*1000000:0 -//extern void (_stdcall *qglFinish) (void); -//#define RSpeedEnd(spt) do {qglFinish(); rspeeds[spt] += r_speeds.value?Sys_DoubleTime()*1000000 - rsp:0;}while (0) +#if defined(_WIN32) && defined(GLQUAKE) +extern void (_stdcall *qglFinish) (void); +#define RSpeedEnd(spt) do {if(r_speeds.ival && qglFinish){qglFinish(); rspeeds[spt] += (int)(Sys_DoubleTime()*1000000) - rsp;}}while (0) +#else #define RSpeedEnd(spt) rspeeds[spt] += r_speeds.value?Sys_DoubleTime()*1000000 - rsp:0 +#endif diff --git a/engine/client/renderer.c b/engine/client/renderer.c index e8f7807b..7d7b3fc6 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -1,15 +1,24 @@ #include "quakedef.h" #include "winquake.h" -#ifdef RGLQUAKE -#include "gl_draw.h" -#endif +#include "pr_common.h" +refdef_t r_refdef; +vec3_t r_origin, vpn, vright, vup; +entity_t r_worldentity; +entity_t *currententity; +int sh_shadowframe; //index for msurf->shadowframe + + +void R_InitParticleTexture (void); + qboolean vid_isfullscreen; #define VIDCOMMANDGROUP "Video config" #define GRAPHICALNICETIES "Graphical Nicaties" //or eyecandy, which ever you prefer. +#ifdef PEXT_BULLETENS #define BULLETENVARS "BulletenBoard controls" +#endif #define GLRENDEREROPTIONS "GL Renderer Options" #define SCREENOPTIONS "Screen Options" @@ -20,7 +29,7 @@ extern int gl_anisotropy_factor; // callbacks used for cvars void SCR_Viewsize_Callback (struct cvar_s *var, char *oldvalue); void SCR_Fov_Callback (struct cvar_s *var, char *oldvalue); -#if defined(RGLQUAKE) +#if defined(GLQUAKE) void GL_Texturemode_Callback (struct cvar_s *var, char *oldvalue); void GL_Texturemode2d_Callback (struct cvar_s *var, char *oldvalue); void GL_Texture_Anisotropic_Filtering_Callback (struct cvar_s *var, char *oldvalue); @@ -43,23 +52,12 @@ cvar_t cl_cursorbias = SCVAR ("cl_cursorbias", "4"); cvar_t gl_nocolors = SCVAR ("gl_nocolors", "0"); cvar_t gl_part_flame = SCVAR ("gl_part_flame", "1"); -//opengl library +//opengl library, blank means try default. static cvar_t gl_driver = SCVARF ("gl_driver", "", CVAR_ARCHIVE | CVAR_RENDERERLATCH); -#ifdef Q3SHADERS -cvar_t gl_shadeq1 = SCVARF ("gl_shadeq1", "0", - CVAR_SEMICHEAT); cvar_t gl_shadeq1_name = SCVAR ("gl_shadeq1_name", "*"); -//use if you want. -cvar_t gl_shadeq2 = SCVARF ("gl_shadeq2", "0", - CVAR_SEMICHEAT); -//use if you want. -cvar_t gl_shadeq3 = SCVARF ("gl_shadeq3", "1", - CVAR_SEMICHEAT); - extern cvar_t r_vertexlight; -#endif cvar_t mod_md3flags = SCVAR ("mod_md3flags", "1"); @@ -71,8 +69,8 @@ cvar_t r_bouncysparks = SCVARF ("r_bouncysparks", "0", cvar_t r_drawdisk = SCVAR ("r_drawdisk", "1"); cvar_t r_drawentities = SCVAR ("r_drawentities", "1"); cvar_t r_drawflat = SCVARF ("r_drawflat", "0", - CVAR_SEMICHEAT | CVAR_RENDERERCALLBACK); -cvar_t r_drawflat_nonworldmodel = SCVAR ("r_drawflat_nonworldmodel", "0"); + CVAR_SEMICHEAT | CVAR_RENDERERCALLBACK | CVAR_SHADERSYSTEM); +cvar_t gl_miptexLevel = SCVAR ("gl_miptexLevel", "0"); cvar_t r_drawviewmodel = SCVAR ("r_drawviewmodel", "1"); cvar_t r_drawviewmodelinvis = SCVAR ("r_drawviewmodelinvis", "0"); #ifdef MINIMAL @@ -82,9 +80,10 @@ cvar_t r_dynamic = SCVARF ("r_dynamic", "0", cvar_t r_dynamic = SCVARF ("r_dynamic", "1", CVAR_ARCHIVE); #endif -cvar_t r_fastsky = SCVAR ("r_fastsky", "0"); +cvar_t r_fastsky = SCVARF ("r_fastsky", "0", + CVAR_SHADERSYSTEM); cvar_t r_fastskycolour = SCVARF ("r_fastskycolour", "0", - CVAR_RENDERERCALLBACK); + CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM); cvar_t r_fb_bmodels = SCVARF("gl_fb_bmodels", "1", CVAR_SEMICHEAT|CVAR_RENDERERLATCH); cvar_t r_fb_models = FCVAR ("r_fb_models", "gl_fb_models", "1", @@ -94,13 +93,13 @@ cvar_t r_skin_overlays = SCVARF ("r_skin_overlays", "1", cvar_t r_flashblend = SCVARF ("gl_flashblend", "0", CVAR_ARCHIVE); cvar_t r_floorcolour = SCVARF ("r_floorcolour", "255 255 255", - CVAR_RENDERERCALLBACK); + CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM); cvar_t r_floortexture = SCVARF ("r_floortexture", "", - CVAR_RENDERERCALLBACK); + CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM); cvar_t r_fullbright = SCVARF ("r_fullbright", "0", - CVAR_CHEAT); + CVAR_CHEAT|CVAR_SHADERSYSTEM); cvar_t r_fullbrightSkins = SCVARF ("r_fullbrightSkins", "1", - CVAR_SEMICHEAT); + CVAR_SEMICHEAT|CVAR_SHADERSYSTEM); cvar_t r_lightmap_saturation = SCVAR ("r_lightmap_saturation", "1"); cvar_t r_lightstylesmooth = SCVAR ("r_lightstylesmooth", "0"); cvar_t r_lightstylespeed = SCVAR ("r_lightstylespeed", "10"); @@ -115,19 +114,19 @@ cvar_t r_part_rain = SCVARF ("r_part_rain", "0", CVAR_ARCHIVE); //whack in a value of 2 and you get easily visible players. cvar_t r_skyboxname = SCVARF ("r_skybox", "", - CVAR_RENDERERCALLBACK); -cvar_t r_speeds = SCVARF ("r_speeds", "0", - CVAR_CHEAT); + CVAR_RENDERERCALLBACK | CVAR_SHADERSYSTEM); +cvar_t r_speeds = SCVAR ("r_speeds", "0"); cvar_t r_stainfadeammount = SCVAR ("r_stainfadeammount", "1"); cvar_t r_stainfadetime = SCVAR ("r_stainfadetime", "1"); cvar_t r_stains = SCVARFC("r_stains", "0.75", CVAR_ARCHIVE, Cvar_Limiter_ZeroToOne_Callback); cvar_t r_wallcolour = SCVARF ("r_wallcolour", "255 255 255", - CVAR_RENDERERCALLBACK); + CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM);//FIXME: broken cvar_t r_walltexture = SCVARF ("r_walltexture", "", - CVAR_RENDERERCALLBACK); -cvar_t r_wateralpha = SCVAR ("r_wateralpha", "1"); + CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM); //FIXME: broken +cvar_t r_wateralpha = SCVARF ("r_wateralpha", "1", + CVAR_SHADERSYSTEM); cvar_t r_waterwarp = SCVARF ("r_waterwarp", "1", CVAR_ARCHIVE); @@ -169,7 +168,7 @@ cvar_t vid_renderer = SCVARF ("vid_renderer", "", CVAR_ARCHIVE | CVAR_RENDERERLATCH); static cvar_t vid_allow_modex = SCVARF ("vid_allow_modex", "1", - CVAR_ARCHIVE | CVAR_RENDERERLATCH); + CVAR_ARCHIVE | CVAR_RENDERERLATCH); //FIXME: remove static cvar_t vid_bpp = SCVARF ("vid_bpp", "32", CVAR_ARCHIVE | CVAR_RENDERERLATCH); static cvar_t vid_desktopsettings = SCVARF ("vid_desktopsettings", "0", @@ -189,8 +188,6 @@ static cvar_t vid_multisample = SCVARF ("vid_multisample", "0", CVAR_ARCHIVE | CVAR_RENDERERLATCH); static cvar_t vid_refreshrate = SCVARF ("vid_displayfrequency", "0", CVAR_ARCHIVE | CVAR_RENDERERLATCH); -static cvar_t vid_stretch = SCVARF ("vid_stretch", "1", - CVAR_ARCHIVE | CVAR_RENDERERLATCH); cvar_t vid_wndalpha = SCVAR ("vid_wndalpha", "1"); //more readable defaults to match conwidth/conheight. cvar_t vid_width = SCVARF ("vid_width", "0", @@ -235,7 +232,13 @@ void R_BulletenForce_f (void); rendererstate_t currentrendererstate; -#if defined(RGLQUAKE) || defined(D3DQUAKE) +#if defined(GLQUAKE) +cvar_t vid_gl_context_version = SCVAR ("vid_gl_context_version", ""); +cvar_t vid_gl_context_forwardcompatible = SCVAR ("vid_gl_context_breakeverything", "0"); //not useful, yet, hence the name +cvar_t vid_gl_context_debug = SCVAR ("vid_gl_context_debug", "0"); //for my ati drivers, debug 1 only works if version >= 3 +#endif + +#if defined(GLQUAKE) || defined(D3DQUAKE) cvar_t gl_ati_truform = SCVAR ("gl_ati_truform", "0"); cvar_t gl_ati_truform_type = SCVAR ("gl_ati_truform_type", "1"); cvar_t gl_ati_truform_tesselation = SCVAR ("gl_ati_truform_tesselation", "3"); @@ -298,7 +301,7 @@ cvar_t gl_specular = SCVAR ("gl_specular", "0"); #endif // The callbacks are not in D3D yet (also ugly way of seperating this) -#ifdef RGLQUAKE +#ifdef GLQUAKE cvar_t gl_texture_anisotropic_filtering = SCVARFC("gl_texture_anisotropic_filtering", "0", CVAR_ARCHIVE | CVAR_RENDERERCALLBACK, GL_Texture_Anisotropic_Filtering_Callback); @@ -316,17 +319,21 @@ cvar_t gl_ztrick = SCVAR ("gl_ztrick", "0"); cvar_t r_noaliasshadows = SCVARF ("r_noaliasshadows", "0", CVAR_ARCHIVE); + cvar_t r_shadow_bumpscale_basetexture = SCVAR ("r_shadow_bumpscale_basetexture", "4"); cvar_t r_shadow_bumpscale_bumpmap = SCVAR ("r_shadow_bumpscale_bumpmap", "10"); + cvar_t r_shadow_glsl_offsetmapping = SCVAR ("r_shadow_glsl_offsetmapping", "0"); cvar_t r_shadow_glsl_offsetmapping_bias = SCVAR ("r_shadow_glsl_offsetmapping_bias", "0.04"); cvar_t r_shadow_glsl_offsetmapping_scale = SCVAR ("r_shadow_glsl_offsetmapping_scale", "-0.04"); -cvar_t r_shadow_realtime_world = SCVARF ("r_shadow_realtime_world", "0", - CVAR_CHEAT | CVAR_ARCHIVE); -cvar_t r_shadow_realtime_world_lightmaps = SCVARF ("r_shadow_realtime_world_lightmaps", "0.8", - CVAR_CHEAT); -cvar_t r_shadows = SCVARF ("r_shadows", "0", - CVAR_ARCHIVE | CVAR_RENDERERLATCH); + +cvar_t r_shadow_realtime_world = SCVARF ("r_shadow_realtime_world", "0", CVAR_ARCHIVE); +cvar_t r_shadow_realtime_world_shadows = SCVARF ("r_shadow_realtime_world_shadows", "1", CVAR_ARCHIVE); +cvar_t r_shadow_realtime_dlight = SCVARF ("r_shadow_realtime_dlight", "1", CVAR_ARCHIVE); +cvar_t r_shadow_realtime_dlight_shadows = SCVARF ("r_shadow_realtime_dlight_shadows", "1", CVAR_ARCHIVE); +cvar_t r_shadow_realtime_world_lightmaps = SCVARF ("r_shadow_realtime_world_lightmaps", "0.8", 0); +cvar_t r_shadows = SCVARF ("r_shadows", "0", CVAR_ARCHIVE | CVAR_RENDERERLATCH); + cvar_t r_vertexdlights = SCVAR ("r_vertexdlights", "0"); cvar_t vid_preservegamma = SCVAR ("vid_preservegamma", "0"); @@ -341,7 +348,7 @@ extern cvar_t r_waterlayers; #endif -#if defined(RGLQUAKE) || defined(D3DQUAKE) +#if defined(GLQUAKE) || defined(D3DQUAKE) void GLD3DRenderer_Init(void) { Cvar_Register (&gl_mindist, GLRENDEREROPTIONS); @@ -349,10 +356,16 @@ void GLD3DRenderer_Init(void) } #endif -#if defined(RGLQUAKE) +#if defined(GLQUAKE) void GLRenderer_Init(void) { extern cvar_t gl_contrast; + + //gl-specific video vars + Cvar_Register (&vid_gl_context_version, GLRENDEREROPTIONS); + Cvar_Register (&vid_gl_context_debug, GLRENDEREROPTIONS); + Cvar_Register (&vid_gl_context_forwardcompatible, GLRENDEREROPTIONS); + //screen Cvar_Register (&gl_triplebuffer, GLRENDEREROPTIONS); @@ -384,6 +397,9 @@ void GLRenderer_Init(void) Cvar_Register (&r_shadow_bumpscale_basetexture, GLRENDEREROPTIONS); Cvar_Register (&r_shadow_bumpscale_bumpmap, GLRENDEREROPTIONS); Cvar_Register (&r_shadow_realtime_world, GLRENDEREROPTIONS); + Cvar_Register (&r_shadow_realtime_world_shadows, GLRENDEREROPTIONS); + Cvar_Register (&r_shadow_realtime_dlight, GLRENDEREROPTIONS); + Cvar_Register (&r_shadow_realtime_dlight_shadows, GLRENDEREROPTIONS); Cvar_Register (&r_shadow_realtime_world_lightmaps, GLRENDEREROPTIONS); Cvar_Register (&gl_keeptjunctions, GLRENDEREROPTIONS); @@ -399,7 +415,6 @@ void GLRenderer_Init(void) Cvar_Register (&gl_fontinwardstep, GRAPHICALNICETIES); Cvar_Register (&gl_font, GRAPHICALNICETIES); - Cvar_Register (&gl_conback, GRAPHICALNICETIES); Cvar_Register (&gl_smoothfont, GRAPHICALNICETIES); Cvar_Register (&gl_smoothcrosshair, GRAPHICALNICETIES); @@ -455,15 +470,12 @@ void GLRenderer_Init(void) Cvar_Register (&r_vertexdlights, GLRENDEREROPTIONS); Cvar_Register (&gl_schematics, GLRENDEREROPTIONS); -#ifdef Q3SHADERS + Cvar_Register (&r_vertexlight, GLRENDEREROPTIONS); - Cvar_Register (&gl_shadeq1, GLRENDEREROPTIONS); Cvar_Register (&gl_shadeq1_name, GLRENDEREROPTIONS); - Cvar_Register (&gl_shadeq2, GLRENDEREROPTIONS); - Cvar_Register (&gl_shadeq3, GLRENDEREROPTIONS); Cvar_Register (&gl_blend2d, GLRENDEREROPTIONS); -#endif + Cvar_Register (&gl_blendsprites, GLRENDEREROPTIONS); Cvar_Register (&gl_mylumassuck, GLRENDEREROPTIONS); @@ -473,8 +485,8 @@ void GLRenderer_Init(void) Cvar_Register (&gl_menutint_shader, GLRENDEREROPTIONS); R_BloomRegister(); -#endif } +#endif void R_InitTextures (void) { @@ -519,18 +531,19 @@ void Renderer_Init(void) Cmd_AddCommand("setrenderer", R_SetRenderer_f); Cmd_AddCommand("vid_restart", R_RestartRenderer_f); -#if defined(RGLQUAKE) || defined(D3DQUAKE) +#if defined(GLQUAKE) || defined(D3DQUAKE) GLD3DRenderer_Init(); #endif -#if defined(RGLQUAKE) +#if defined(GLQUAKE) GLRenderer_Init(); #endif + Cvar_Register (&gl_conback, GRAPHICALNICETIES); + Cvar_Register (&r_novis, GLRENDEREROPTIONS); //but register ALL vid_ commands. Cvar_Register (&_vid_wait_override, VIDCOMMANDGROUP); - Cvar_Register (&vid_stretch, VIDCOMMANDGROUP); Cvar_Register (&_windowed_mouse, VIDCOMMANDGROUP); Cvar_Register (&vid_renderer, VIDCOMMANDGROUP); Cvar_Register (&vid_wndalpha, VIDCOMMANDGROUP); @@ -539,7 +552,6 @@ void Renderer_Init(void) Cvar_Register (&vid_fullscreen_npqtv, VIDCOMMANDGROUP); #endif Cvar_Register (&vid_fullscreen, VIDCOMMANDGROUP); -// Cvar_Register (&vid_stretch, VIDCOMMANDGROUP); Cvar_Register (&vid_bpp, VIDCOMMANDGROUP); Cvar_Register (&vid_conwidth, VIDCOMMANDGROUP); @@ -616,14 +628,15 @@ void Renderer_Init(void) Cvar_Register (&r_fastskycolour, GRAPHICALNICETIES); Cvar_Register (&r_wateralpha, GRAPHICALNICETIES); + Cvar_Register (&gl_miptexLevel, GRAPHICALNICETIES); Cvar_Register (&r_drawflat, GRAPHICALNICETIES); - Cvar_Register (&r_drawflat_nonworldmodel, GRAPHICALNICETIES); Cvar_Register (&r_menutint, GRAPHICALNICETIES); Cvar_Register (&r_fb_models, GRAPHICALNICETIES); Cvar_Register (&r_replacemodels, GRAPHICALNICETIES); +#ifdef PEXT_BULLETENS //bulletens Cvar_Register(&bul_nowater, BULLETENVARS); Cvar_Register(&bul_rippleamount, BULLETENVARS); @@ -641,15 +654,15 @@ void Renderer_Init(void) Cvar_Register(&bul_text3, BULLETENVARS); Cvar_Register(&bul_text2, BULLETENVARS); Cvar_Register(&bul_text1, BULLETENVARS); + Cvar_Register(&bul_norender, BULLETENVARS); //find this one first... + + Cmd_AddCommand("bul_make", R_BulletenForce_f); +#endif // misc Cvar_Register(&con_ocranaleds, "Console controls"); - Cvar_Register(&bul_norender, BULLETENVARS); //find this one first... - - Cmd_AddCommand("bul_make", R_BulletenForce_f); - P_InitParticleSystem(); R_InitTextures(); RQ_Init(); @@ -657,26 +670,18 @@ void Renderer_Init(void) mpic_t *(*Draw_SafePicFromWad) (char *name); -mpic_t *(*Draw_CachePic) (char *path); mpic_t *(*Draw_SafeCachePic) (char *path); void (*Draw_Init) (void); -void (*Draw_ReInit) (void); +void (*Draw_Shutdown) (void); -void (*Draw_Character) (int x, int y, unsigned int num); -void (*Draw_ColouredCharacter) (int x, int y, unsigned int num); -void (*Draw_String) (int x, int y, const qbyte *str); -void (*Draw_TinyCharacter) (int x, int y, unsigned int num); -void (*Draw_Alt_String) (int x, int y, const qbyte *str); +//void (*Draw_TinyCharacter) (int x, int y, unsigned int num); void (*Draw_Crosshair) (void); -void (*Draw_DebugChar) (qbyte num); -void (*Draw_Pic) (int x, int y, mpic_t *pic); void (*Draw_ScalePic) (int x, int y, int width, int height, mpic_t *pic); -void (*Draw_SubPic) (int x, int y, mpic_t *pic, int srcx, int srcy, int width, int height); -void (*Draw_TransPic) (int x, int y, mpic_t *pic); +void (*Draw_SubPic) (int x, int y, int width, int height, mpic_t *pic, int srcx, int srcy, int srcwidth, int srcheight); void (*Draw_TransPicTranslate) (int x, int y, int w, int h, qbyte *image, qbyte *translation); void (*Draw_ConsoleBackground) (int firstline, int lastline, qboolean forceopaque); -void (*Draw_EditorBackground) (int lines); +void (*Draw_EditorBackground) (void); void (*Draw_TileClear) (int x, int y, int w, int h); void (*Draw_Fill) (int x, int y, int w, int h, unsigned int c); void (*Draw_FillRGB) (int x, int y, int w, int h, float r, float g, float b); @@ -689,12 +694,8 @@ void (*Draw_ImageColours) (float r, float g, float b, float a); void (*R_Init) (void); void (*R_DeInit) (void); -void (*R_ReInit) (void); void (*R_RenderView) (void); // must set r_refdef first -qboolean (*R_CheckSky) (void); -void (*R_SetSky) (char *name, float rotate, vec3_t axis); - void (*R_NewMap) (void); void (*R_PreNewMap) (void); int (*R_LightPoint) (vec3_t point); @@ -756,20 +757,11 @@ rendererinfo_t dedicatedrendererinfo = { QR_NONE, NULL, //Draw_PicFromWad; //Not supported - NULL, //Draw_CachePic; NULL, //Draw_SafeCachePic; NULL, //Draw_Init; - NULL, //Draw_Init; - NULL, //Draw_Character; - NULL, //Draw_ColouredCharacter; - NULL, //Draw_TinyCharacter; - NULL, //Draw_String; - NULL, //Draw_Alt_String; + NULL, //Draw_Shutdown; NULL, //Draw_Crosshair; - NULL, //Draw_DebugChar; - NULL, //Draw_Pic; NULL, //Draw_SubPic; - NULL, //Draw_TransPic; NULL, //Draw_TransPicTranslate; NULL, //Draw_ConsoleBackground; NULL, //Draw_EditorBackground; @@ -786,12 +778,8 @@ rendererinfo_t dedicatedrendererinfo = { NULL, //R_Init; NULL, //R_DeInit; - NULL, //R_ReInit; NULL, //R_RenderView; - NULL, //R_CheckSky; - NULL, //R_SetSky; - NULL, //R_NewMap; NULL, //R_PreNewMap NULL, //R_LightPoint; @@ -805,16 +793,16 @@ rendererinfo_t dedicatedrendererinfo = { NULL, //Media_ShowFrameRGBA_32; NULL, //Media_ShowFrame8bit; -#if defined(RGLQUAKE) || defined(D3DQUAKE) - GLMod_Init, - GLMod_ClearAll, - GLMod_ForName, - GLMod_FindName, - GLMod_Extradata, - GLMod_TouchModel, +#if defined(GLQUAKE) || defined(D3DQUAKE) + RMod_Init, + RMod_ClearAll, + RMod_ForName, + RMod_FindName, + RMod_Extradata, + RMod_TouchModel, - GLMod_NowLoadExternal, - GLMod_Think, + RMod_NowLoadExternal, + RMod_Think, NULL, //Mod_GetTag NULL, //fixme: server will need this one at some point. @@ -847,131 +835,24 @@ rendererinfo_t dedicatedrendererinfo = { }; rendererinfo_t *pdedicatedrendererinfo = &dedicatedrendererinfo; -#ifdef RGLQUAKE -rendererinfo_t openglrendererinfo = { - "OpenGL", - { - "gl", - "opengl", - "hardware", - }, - QR_OPENGL, - - - GLDraw_SafePicFromWad, - GLDraw_CachePic, - GLDraw_SafeCachePic, - GLDraw_Init, - GLDraw_ReInit, - GLDraw_Character, - GLDraw_ColouredCharacter, - GLDraw_TinyCharacter, - GLDraw_String, - GLDraw_Alt_String, - GLDraw_Crosshair, - GLDraw_DebugChar, - GLDraw_Pic, - GLDraw_ScalePic, - GLDraw_SubPic, - GLDraw_TransPic, - GLDraw_TransPicTranslate, - GLDraw_ConsoleBackground, - GLDraw_EditorBackground, - GLDraw_TileClear, - GLDraw_Fill, - GLDraw_FillRGB, - GLDraw_FadeScreen, - GLDraw_BeginDisc, - GLDraw_EndDisc, - - GLDraw_Image, - GLDraw_ImageColours, - - GLR_Init, - GLR_DeInit, - GLR_ReInit, - GLR_RenderView, - - - GLR_CheckSky, - GLR_SetSky, - - GLR_NewMap, - GLR_PreNewMap, - GLR_LightPoint, - GLR_PushDlights, - - - GLR_AddStain, - GLR_LessenStains, - - MediaGL_ShowFrameBGR_24_Flip, - MediaGL_ShowFrameRGBA_32, - MediaGL_ShowFrame8bit, - - - GLMod_Init, - GLMod_ClearAll, - GLMod_ForName, - GLMod_FindName, - GLMod_Extradata, - GLMod_TouchModel, - - GLMod_NowLoadExternal, - GLMod_Think, - - Mod_GetTag, - Mod_TagNumForName, - Mod_SkinNumForName, - Mod_FrameNumForName, - Mod_FrameDuration, - - GLVID_Init, - GLVID_DeInit, - GLVID_LockBuffer, - GLVID_UnlockBuffer, - GLD_BeginDirectRect, - GLD_EndDirectRect, - GLVID_ForceLockState, - GLVID_ForceUnlockedAndReturnState, - GLVID_SetPalette, - GLVID_ShiftPalette, - GLVID_GetRGBInfo, - - GLVID_SetCaption, //setcaption - - - GLSCR_UpdateScreen, - - "" -}; -rendererinfo_t *popenglrendererinfo = &openglrendererinfo; -#endif - -#ifdef D3DQUAKE +rendererinfo_t openglrendererinfo; +rendererinfo_t d3drendererinfo; rendererinfo_t d3d7rendererinfo; -rendererinfo_t *pd3d7rendererinfo = &d3d7rendererinfo; -#endif - -rendererinfo_t *pd3drendererinfo; - rendererinfo_t d3d9rendererinfo; -rendererinfo_t *pd3d9rendererinfo = &d3d9rendererinfo; -rendererinfo_t **rendererinfo[] = +rendererinfo_t *rendererinfo[] = { #ifndef NPQTV - &pdedicatedrendererinfo, + &dedicatedrendererinfo, #endif -#ifdef RGLQUAKE - &popenglrendererinfo, - &pd3drendererinfo, +#ifdef GLQUAKE + &openglrendererinfo, + &d3drendererinfo, #endif #ifdef D3DQUAKE - &pd3d7rendererinfo, -#endif -#ifdef D3DQUAKE - &pd3d9rendererinfo, + &d3drendererinfo, + &d3d7rendererinfo, + &d3d9rendererinfo, #endif }; @@ -1110,7 +991,7 @@ qboolean M_VideoApply (union menuoption_s *op,struct menu_s *menu,int key) switch(info->renderer->selectedoption) { -#ifdef RGLQUAKE +#ifdef GLQUAKE case 0: Cbuf_AddText("setrenderer gl\n", RESTRICT_LOCAL); break; @@ -1128,13 +1009,13 @@ qboolean M_VideoApply (union menuoption_s *op,struct menu_s *menu,int key) void M_Menu_Video_f (void) { extern cvar_t r_stains, v_contrast; -#if defined(RGLQUAKE) +#if defined(GLQUAKE) extern cvar_t r_bloom; #endif extern cvar_t r_bouncysparks; static const char *modenames[128] = {"Custom"}; static const char *rendererops[] = { -#ifdef RGLQUAKE +#ifdef GLQUAKE "OpenGL", #endif #ifdef D3DQUAKE @@ -1162,7 +1043,7 @@ void M_Menu_Video_f (void) int prefabmode; int prefab2dmode; int currentbpp; -#ifdef RGLQUAKE +#ifdef GLQUAKE int currenttexturefilter; #endif @@ -1185,7 +1066,7 @@ void M_Menu_Video_f (void) menu = M_CreateMenu(sizeof(videomenuinfo_t)); info = menu->data; -#if defined(RGLQUAKE) && defined(USE_D3D) +#if defined(GLQUAKE) && defined(USE_D3D) if (!strcmp(vid_renderer.string, "d3d9")) i = 1; else @@ -1199,7 +1080,7 @@ void M_Menu_Video_f (void) else currentbpp = 0; -#ifdef RGLQUAKE +#ifdef GLQUAKE if (!Q_strcasecmp(gl_texturemode.string, "gl_nearest_mipmap_nearest")) currenttexturefilter = 0; else if (!Q_strcasecmp(gl_texturemode.string, "gl_linear_mipmap_linear")) @@ -1211,7 +1092,7 @@ void M_Menu_Video_f (void) #endif - MC_AddCenterPicture(menu, 4, "vidmodes"); + MC_AddCenterPicture(menu, 4, 24, "vidmodes"); y = 32; info->renderer = MC_AddCombo(menu, 16, y, " Renderer ", rendererops, i); y+=8; @@ -1227,7 +1108,7 @@ void M_Menu_Video_f (void) MC_AddCheckBox(menu, 16, y, " Stain maps", &r_stains,0); y+=8; MC_AddCheckBox(menu, 16, y, " Bouncy sparks", &r_bouncysparks,0); y+=8; MC_AddCheckBox(menu, 16, y, " Rain", &r_part_rain,0); y+=8; -#ifdef RGLQUAKE +#ifdef GLQUAKE MC_AddCheckBox(menu, 16, y, " GL Bumpmapping", &gl_bump,0); y+=8; MC_AddCheckBox(menu, 16, y, " Bloom", &r_bloom,0); y+=8; #endif @@ -1235,7 +1116,7 @@ void M_Menu_Video_f (void) MC_AddSlider(menu, 16, y, " Screen size", &scr_viewsize, 30, 120, 0.1);y+=8; MC_AddSlider(menu, 16, y, " Gamma", &v_gamma, 0.3, 1, 0.05); y+=8; MC_AddSlider(menu, 16, y, " Contrast", &v_contrast, 1, 3, 0.05); y+=8; -#ifdef RGLQUAKE +#ifdef GLQUAKE info->texturefiltercombo = MC_AddCombo(menu, 16, y, " Texture Filter ", texturefilternames, currenttexturefilter); y+=8; MC_AddSlider(menu, 16, y, "Anisotropy Level", &gl_texture_anisotropic_filtering, 1, 16, 1); y+=8; //urm, this shouldn't really be a slider, but should be a combo instead #endif @@ -1245,7 +1126,6 @@ void M_Menu_Video_f (void) menu->event = CheckCustomMode; } - void R_SetRenderer(int wanted) { rendererinfo_t *ri; @@ -1256,28 +1136,19 @@ void R_SetRenderer(int wanted) qrenderer = -1; } else - qrenderer = (*rendererinfo[wanted])->rtype; + qrenderer = rendererinfo[wanted]->rtype; - ri = (*rendererinfo[wanted]); + ri = rendererinfo[wanted]; q_renderername = ri->name[0]; Draw_SafePicFromWad = ri->Draw_SafePicFromWad; //Not supported - Draw_CachePic = ri->Draw_CachePic; Draw_SafeCachePic = ri->Draw_SafeCachePic; Draw_Init = ri->Draw_Init; - Draw_ReInit = ri->Draw_Init; - Draw_Character = ri->Draw_Character; - Draw_ColouredCharacter = ri->Draw_ColouredCharacter; - Draw_String = ri->Draw_String; - Draw_TinyCharacter = ri->Draw_TinyCharacter; - Draw_Alt_String = ri->Draw_Alt_String; + Draw_Shutdown = ri->Draw_Shutdown; Draw_Crosshair = ri->Draw_Crosshair; - Draw_DebugChar = ri->Draw_DebugChar; - Draw_Pic = ri->Draw_Pic; Draw_SubPic = ri->Draw_SubPic; - Draw_TransPic = ri->Draw_TransPic; Draw_TransPicTranslate = ri->Draw_TransPicTranslate; Draw_ConsoleBackground = ri->Draw_ConsoleBackground; Draw_EditorBackground = ri->Draw_EditorBackground; @@ -1299,8 +1170,6 @@ void R_SetRenderer(int wanted) R_PreNewMap = ri->R_PreNewMap; R_LightPoint = ri->R_LightPoint; R_PushDlights = ri->R_PushDlights; - R_CheckSky = ri->R_CheckSky; - R_SetSky = ri->R_SetSky; R_AddStain = ri->R_AddStain; R_LessenStains = ri->R_LessenStains; @@ -1437,7 +1306,7 @@ qboolean R_ApplyRenderer_Load (rendererstate_t *newr) BZ_Free(host_basepal); if (host_colormap) BZ_Free(host_colormap); - host_basepal = (qbyte *)COM_LoadMallocFile ("gfx/palette.lmp"); + host_basepal = (qbyte *)FS_LoadMallocFile ("gfx/palette.lmp"); if (!host_basepal) { qbyte *pcx=NULL; @@ -1454,7 +1323,7 @@ qboolean R_ApplyRenderer_Load (rendererstate_t *newr) goto q2colormap; //skip the colormap.lmp file as we already read it } } - host_colormap = (qbyte *)COM_LoadMallocFile ("gfx/colormap.lmp"); + host_colormap = (qbyte *)FS_LoadMallocFile ("gfx/colormap.lmp"); if (!host_colormap) { vid.fullbright=0; @@ -1502,6 +1371,7 @@ TRACE(("dbg: R_ApplyRenderer: wad loaded\n")); Draw_Init(); TRACE(("dbg: R_ApplyRenderer: draw inited\n")); R_Init(); + R_InitParticleTexture (); TRACE(("dbg: R_ApplyRenderer: renderer inited\n")); SCR_Init(); TRACE(("dbg: R_ApplyRenderer: screen inited\n")); @@ -1532,8 +1402,10 @@ TRACE(("dbg: R_ApplyRenderer: isDedicated = true\n")); } TRACE(("dbg: R_ApplyRenderer: initing mods\n")); Mod_Init(); +#ifdef PEXT_BULLETENS TRACE(("dbg: R_ApplyRenderer: initing bulletein boards\n")); WipeBulletenTextures(); +#endif // host_hunklevel = Hunk_LowMark(); @@ -1545,17 +1417,17 @@ TRACE(("dbg: R_ApplyRenderer: initing bulletein boards\n")); } #ifndef CLIENTONLY - if (sv.worldmodel) + if (sv.world.worldmodel) { - edict_t *ent; + wedict_t *ent; #ifdef Q2SERVER q2edict_t *q2ent; #endif TRACE(("dbg: R_ApplyRenderer: reloading server map\n")); - sv.worldmodel = Mod_ForName (sv.modelname, false); + sv.world.worldmodel = Mod_ForName (sv.modelname, false); TRACE(("dbg: R_ApplyRenderer: loaded\n")); - if (sv.worldmodel->needload) + if (sv.world.worldmodel->needload) { SV_Error("Bsp went missing on render restart\n"); } @@ -1563,23 +1435,23 @@ TRACE(("dbg: R_ApplyRenderer: doing that funky phs thang\n")); SV_CalcPHS (); TRACE(("dbg: R_ApplyRenderer: clearing world\n")); - SV_ClearWorld (); + World_ClearWorld (&sv.world); if (svs.gametype == GT_PROGS) { for (i = 0; i < MAX_MODELS; i++) { - if (sv.strings.model_precache[i] && *sv.strings.model_precache[i] && (!strcmp(sv.strings.model_precache[i] + strlen(sv.strings.model_precache[i]) - 4, ".bsp") || i-1 < sv.worldmodel->numsubmodels)) - sv.models[i] = Mod_FindName(sv.strings.model_precache[i]); + if (sv.strings.model_precache[i] && *sv.strings.model_precache[i] && (!strcmp(sv.strings.model_precache[i] + strlen(sv.strings.model_precache[i]) - 4, ".bsp") || i-1 < sv.world.worldmodel->numsubmodels)) + sv.world.models[i] = Mod_FindName(sv.strings.model_precache[i]); else - sv.models[i] = NULL; + sv.world.models[i] = NULL; } - ent = sv.edicts; + ent = sv.world.edicts; // ent->v->model = PR_NewString(svprogfuncs, sv.worldmodel->name); //FIXME: is this a problem for normal ents? - for (i=0 ; iisfree) @@ -1588,7 +1460,7 @@ TRACE(("dbg: R_ApplyRenderer: clearing world\n")); if (ent->area.prev) { ent->area.prev = ent->area.next = NULL; - SV_LinkEdict (ent, false); // relink ents so touch functions continue to work. + World_LinkEdict (&sv.world, ent, false); // relink ents so touch functions continue to work. } } } @@ -1597,10 +1469,10 @@ TRACE(("dbg: R_ApplyRenderer: clearing world\n")); { for (i = 0; i < MAX_MODELS; i++) { - if (sv.strings.configstring[Q2CS_MODELS+i] && *sv.strings.configstring[Q2CS_MODELS+i] && (!strcmp(sv.strings.configstring[Q2CS_MODELS+i] + strlen(sv.strings.configstring[Q2CS_MODELS+i]) - 4, ".bsp") || i-1 < sv.worldmodel->numsubmodels)) - sv.models[i] = Mod_FindName(sv.strings.configstring[Q2CS_MODELS+i]); + if (sv.strings.configstring[Q2CS_MODELS+i] && *sv.strings.configstring[Q2CS_MODELS+i] && (!strcmp(sv.strings.configstring[Q2CS_MODELS+i] + strlen(sv.strings.configstring[Q2CS_MODELS+i]) - 4, ".bsp") || i-1 < sv.world.worldmodel->numsubmodels)) + sv.world.models[i] = Mod_FindName(sv.strings.configstring[Q2CS_MODELS+i]); else - sv.models[i] = NULL; + sv.world.models[i] = NULL; } q2ent = ge->edicts; @@ -1614,7 +1486,7 @@ TRACE(("dbg: R_ApplyRenderer: clearing world\n")); if (q2ent->area.prev) { q2ent->area.prev = q2ent->area.next = NULL; - SVQ2_LinkEdict (q2ent); // relink ents so touch functions continue to work. + WorldQ2_LinkEdict (&sv.world, q2ent); // relink ents so touch functions continue to work. } } } @@ -1644,7 +1516,11 @@ TRACE(("dbg: R_ApplyRenderer: starting on client state\n")); } cl.worldmodel = NULL; - cl_numvisedicts=0; + cl_numvisedicts = 0; + cl_numstrisidx = 0; + cl_numstrisvert = 0; + cl_numstris = 0; + TRACE(("dbg: R_ApplyRenderer: reloading ALL models\n")); for (i=1 ; idescription) continue; //not valid in this build. :( for (j = 4-1; j >= 0; j--) { - if (!(*rendererinfo[i])->name[j]) + if (!rendererinfo[i]->name[j]) continue; - if (!stricmp((*rendererinfo[i])->name[j], vid_renderer.string)) + if (!stricmp(rendererinfo[i]->name[j], vid_renderer.string)) { newr.renderer = i; break; @@ -1817,7 +1691,7 @@ TRACE(("dbg: R_RestartRenderer_f\n")); { Con_Printf("vid_renderer unset or invalid. Using default.\n"); //gotta do this after main hunk is saved off. -#if defined(RGLQUAKE) +#if defined(GLQUAKE) Cmd_ExecuteString("setrenderer gl\n", RESTRICT_LOCAL); #elif defined(D3DQUAKE) Cmd_ExecuteString("setrenderer d3d9\n", RESTRICT_LOCAL); @@ -1915,6 +1789,7 @@ TRACE(("dbg: R_RestartRenderer_f\n")); #ifdef MENU_DAT MP_Init(); #endif + CL_InitDlights(); } void R_SetRenderer_f (void) @@ -1927,8 +1802,8 @@ void R_SetRenderer_f (void) Con_Printf ("\nValid setrenderer parameters are:\n"); for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++) { - if ((*rendererinfo[i])) - Con_Printf("%s: %s\n", (*rendererinfo[i])->name[0], (*rendererinfo[i])->description); + if (rendererinfo[i]->description) + Con_Printf("%s: %s\n", rendererinfo[i]->name[0], rendererinfo[i]->description); } return; } @@ -1936,13 +1811,13 @@ void R_SetRenderer_f (void) best = -1; for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++) { - if (!*rendererinfo[i]) + if (!rendererinfo[i]->description) continue; //not valid in this build. :( for (j = 4-1; j >= 0; j--) { - if (!(*rendererinfo[i])->name[j]) + if (!rendererinfo[i]->name[j]) continue; - if (!stricmp((*rendererinfo[i])->name[j], param)) + if (!stricmp(rendererinfo[i]->name[j], param)) { best = i; break; @@ -2198,6 +2073,7 @@ mleaf_t *r_viewleaf2, *r_oldviewleaf2; int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2; int r_visframecount; mleaf_t *r_vischain; // linked list of visible leafs +static qbyte curframevis[MAX_MAP_LEAFS/8]; /* =============== @@ -2205,16 +2081,16 @@ R_MarkLeaves =============== */ #ifdef Q3BSPS -void R_MarkLeaves_Q3 (void) +qbyte *R_MarkLeaves_Q3 (void) { - qbyte *vis; + static qbyte *vis; int i; int cluster; mleaf_t *leaf; if (r_oldviewcluster == r_viewcluster && !r_novis.value && r_viewcluster != -1) - return; + return vis; // development aid to let you run around and see exactly where // the pvs ends @@ -2242,7 +2118,7 @@ void R_MarkLeaves_Q3 (void) } else { - vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster, NULL, 0); + vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster, curframevis, sizeof(curframevis)); for (i=0,leaf=cl.worldmodel->leafs ; inumleafs ; i++, leaf++) { cluster = leaf->cluster; @@ -2258,84 +2134,117 @@ void R_MarkLeaves_Q3 (void) } } } + return vis; } #endif #ifdef Q2BSPS -void R_MarkLeaves_Q2 (void) +qbyte *R_MarkLeaves_Q2 (void) { - qbyte fatvis[MAX_MAP_LEAFS/8]; - qbyte *vis; + static qbyte *vis; mnode_t *node; int i; int cluster; mleaf_t *leaf; - int c; + int c; - if (r_oldviewcluster == r_viewcluster && r_oldviewcluster2 == r_viewcluster2) - return; + if (r_oldviewcluster == r_viewcluster && r_oldviewcluster2 == r_viewcluster2) + return vis; - r_oldviewcluster = r_viewcluster; - r_oldviewcluster2 = r_viewcluster2; + r_oldviewcluster = r_viewcluster; + r_oldviewcluster2 = r_viewcluster2; - if (r_novis.value == 2) - return; - r_visframecount++; - if (r_novis.value || r_viewcluster == -1 || !cl.worldmodel->vis) - { - // mark everything - for (i=0 ; inumleafs ; i++) - cl.worldmodel->leafs[i].visframe = r_visframecount; - for (i=0 ; inumnodes ; i++) - cl.worldmodel->nodes[i].visframe = r_visframecount; - return; - } - - vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster, NULL, 0); - // may have to combine two clusters because of solid water boundaries - if (r_viewcluster2 != r_viewcluster) - { - memcpy (fatvis, vis, (cl.worldmodel->numleafs+7)/8); - vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster2, NULL, 0); - c = (cl.worldmodel->numleafs+31)/32; - for (i=0 ; ileafs ; inumleafs ; i++, leaf++) - { - cluster = leaf->cluster; - if (cluster == -1) - continue; - if (vis[cluster>>3] & (1<<(cluster&7))) - { - node = (mnode_t *)leaf; - do - { - if (node->visframe == r_visframecount) - break; - node->visframe = r_visframecount; - node = node->parent; - } while (node); - } - } - return; + if (r_novis.value == 2) + return vis; + r_visframecount++; + if (r_novis.value || r_viewcluster == -1 || !cl.worldmodel->vis) + { + // mark everything + for (i=0 ; inumleafs ; i++) + cl.worldmodel->leafs[i].visframe = r_visframecount; + for (i=0 ; inumnodes ; i++) + cl.worldmodel->nodes[i].visframe = r_visframecount; + return vis; } + + vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster, curframevis, sizeof(curframevis)); + // may have to combine two clusters because of solid water boundaries + if (r_viewcluster2 != r_viewcluster) + { + vis = CM_ClusterPVS (cl.worldmodel, r_viewcluster2, NULL, sizeof(curframevis)); + c = (cl.worldmodel->numleafs+31)/32; + for (i=0 ; ileafs ; inumleafs ; i++, leaf++) + { + cluster = leaf->cluster; + if (cluster == -1) + continue; + if (vis[cluster>>3] & (1<<(cluster&7))) + { + node = (mnode_t *)leaf; + do + { + if (node->visframe == r_visframecount) + break; + node->visframe = r_visframecount; + node = node->parent; + } while (node); + } + } + return vis; +} #endif -void R_MarkLeaves_Q1 (void) +qbyte *R_CalcVis_Q1 (void) +{ + unsigned int i; + static qbyte *vis; + r_visframecount++; + if (r_oldviewleaf == r_viewleaf && r_oldviewleaf2 == r_viewleaf2) + { + } + else + { + r_oldviewleaf = r_viewleaf; + r_oldviewleaf2 = r_viewleaf2; + + if ((int)r_novis.value&1) + { + vis = curframevis; + memset (vis, 0xff, (cl.worldmodel->numleafs+7)>>3); + } + else if (r_viewleaf2 && r_viewleaf2 != r_viewleaf) + { + int c; + Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf2, curframevis, sizeof(curframevis)); + vis = Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf, NULL, sizeof(curframevis)); + c = (cl.worldmodel->numleafs+31)/32; + for (i=0 ; inumleafs+7)>>3); @@ -2378,6 +2287,7 @@ void R_MarkLeaves_Q1 (void) } while (node); } } + return vis; } @@ -2469,7 +2379,7 @@ int SignbitsForPlane (mplane_t *out) return bits; } #if 1 -void R_SetFrustum (void) +void R_SetFrustum (float projmat[16], float viewmat[16]) { float scale; int i; @@ -2478,7 +2388,7 @@ void R_SetFrustum (void) if ((int)r_novis.value & 4) return; - Matrix4_Multiply(r_projection_matrix, r_view_matrix, mvp); + Matrix4_Multiply(projmat, viewmat, mvp); for (i = 0; i < 4; i++) { @@ -2548,3 +2458,157 @@ void R_SetFrustum (void) } } #endif + + + + +#include "glquake.h" + +//we could go for nice smooth round particles... but then we would loose a little bit of the chaotic nature of the particles. +static qbyte dottexture[8][8] = +{ + {0,0,0,0,0,0,0,0}, + {0,0,0,1,1,0,0,0}, + {0,0,1,1,1,1,0,0}, + {0,1,1,1,1,1,1,0}, + {0,1,1,1,1,1,1,0}, + {0,0,1,1,1,1,0,0}, + {0,0,0,1,1,0,0,0}, + {0,0,0,0,0,0,0,0}, +}; +static qbyte exptexture[16][16] = +{ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0}, + {0,0,0,1,1,1,1,1,3,1,1,2,1,0,0,0}, + {0,0,0,1,1,1,1,4,4,4,5,4,2,1,1,0}, + {0,0,1,1,6,5,5,8,6,8,3,6,3,2,1,0}, + {0,0,1,5,6,7,5,6,8,8,8,3,3,1,0,0}, + {0,0,0,1,6,8,9,9,9,9,4,6,3,1,0,0}, + {0,0,2,1,7,7,9,9,9,9,5,3,1,0,0,0}, + {0,0,2,4,6,8,9,9,9,9,8,6,1,0,0,0}, + {0,0,2,2,3,5,6,8,9,8,8,4,4,1,0,0}, + {0,0,1,2,4,1,8,7,8,8,6,5,4,1,0,0}, + {0,1,1,1,7,8,1,6,7,5,4,7,1,0,0,0}, + {0,1,2,1,1,5,1,3,4,3,1,1,0,0,0,0}, + {0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, +}; + +texid_t particletexture; // little dot for particles +texid_t particlecqtexture; // little dot for particles +texid_t explosiontexture; +texid_t balltexture; +texid_t beamtexture; +texid_t ptritexture; +void R_InitParticleTexture (void) +{ +#define PARTICLETEXTURESIZE 64 + int x,y; + float dx, dy, d; + qbyte data[PARTICLETEXTURESIZE*PARTICLETEXTURESIZE][4]; + + // + // particle texture + // + for (x=0 ; x<8 ; x++) + { + for (y=0 ; y<8 ; y++) + { + data[y*8+x][0] = 255; + data[y*8+x][1] = 255; + data[y*8+x][2] = 255; + data[y*8+x][3] = dottexture[x][y]*255; + } + } + + particletexture = R_LoadTexture32("", 8, 8, data, IF_NOMIPMAP|IF_NOPICMIP); + + + // + // particle triangle texture + // + + // clear to transparent white + for (x = 0; x < 32 * 32; x++) + { + data[x][0] = 255; + data[x][1] = 255; + data[x][2] = 255; + data[x][3] = 0; + } + //draw a circle in the top left. + for (x=0 ; x<16 ; x++) + { + for (y=0 ; y<16 ; y++) + { + if ((x - 7.5) * (x - 7.5) + (y - 7.5) * (y - 7.5) <= 8 * 8) + data[y*32+x][3] = 255; + } + } + + particlecqtexture = R_LoadTexture32("", 32, 32, data, IF_NOMIPMAP|IF_NOPICMIP); + + + + + + for (x=0 ; x<16 ; x++) + { + for (y=0 ; y<16 ; y++) + { + data[y*16+x][0] = 255; + data[y*16+x][1] = 255; + data[y*16+x][2] = 255; + data[y*16+x][3] = exptexture[x][y]*255/9.0; + } + } + explosiontexture = R_LoadTexture32("", 16, 16, data, IF_NOMIPMAP|IF_NOPICMIP); + + memset(data, 255, sizeof(data)); + for (y = 0;y < PARTICLETEXTURESIZE;y++) + { + dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1); + for (x = 0;x < PARTICLETEXTURESIZE;x++) + { + dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1); + d = 256 * (1 - (dx*dx+dy*dy)); + d = bound(0, d, 255); + data[y*PARTICLETEXTURESIZE+x][3] = (qbyte) d; + } + } + balltexture = R_LoadTexture32("", PARTICLETEXTURESIZE, PARTICLETEXTURESIZE, data, IF_NOMIPMAP|IF_NOPICMIP); + + memset(data, 255, sizeof(data)); + for (y = 0;y < PARTICLETEXTURESIZE;y++) + { + dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1); + d = 256 * (1 - (dy*dy)); + d = bound(0, d, 255); + for (x = 0;x < PARTICLETEXTURESIZE;x++) + { + data[y*PARTICLETEXTURESIZE+x][3] = (qbyte) d; + } + } + beamtexture = R_LoadTexture32("", PARTICLETEXTURESIZE, PARTICLETEXTURESIZE, data, IF_NOMIPMAP|IF_NOPICMIP); + + for (y = 0;y < PARTICLETEXTURESIZE;y++) + { + dy = y / (PARTICLETEXTURESIZE*0.5f-1); + d = 256 * (1 - (dy*dy)); + d = bound(0, d, 255); + for (x = 0;x < PARTICLETEXTURESIZE;x++) + { + dx = x / (PARTICLETEXTURESIZE*0.5f-1); + d = 256 * (1 - (dx+dy)); + d = bound(0, d, 255); + data[y*PARTICLETEXTURESIZE+x][0] = (qbyte) d; + data[y*PARTICLETEXTURESIZE+x][1] = (qbyte) d; + data[y*PARTICLETEXTURESIZE+x][2] = (qbyte) d; + data[y*PARTICLETEXTURESIZE+x][3] = (qbyte) d/2; + } + } + ptritexture = R_LoadTexture32("", PARTICLETEXTURESIZE, PARTICLETEXTURESIZE, data, IF_NOMIPMAP|IF_NOPICMIP); +} + diff --git a/engine/client/resource.h b/engine/client/resource.h index a85d5611..5f2497b6 100644 --- a/engine/client/resource.h +++ b/engine/client/resource.h @@ -2,15 +2,8 @@ // Microsoft Developer Studio generated include file. // Used by winquake.rc // -#define IDS_STRING1 1 -#define IDI_ICON2 1 -#define IDD_DIALOG1 108 -#define IDD_PROGRESS 109 -#define IDB_QWBITMAP 112 -#define IDI_ICON1 115 -#define IDB_BITMAP1 116 -#define IDI_ICON3 122 -#define IDC_PROGRESS 1000 +#define IDI_ICON1 1 +#define IDI_ICON2 2 // Next default values for new objects // diff --git a/engine/client/sbar.c b/engine/client/sbar.c index ba237ff6..0725da8e 100644 --- a/engine/client/sbar.c +++ b/engine/client/sbar.c @@ -20,6 +20,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // sbar.c -- status bar code #include "quakedef.h" +#include "shader.h" + +#pragma message("hipnotic/rogue: Find out") +#define FINDOUT 1024 extern cvar_t hud_tracking_show; @@ -132,7 +136,7 @@ int Sbar_PlayerNum(void) int Sbar_TopColour(player_info_t *p) { - if (scr_scoreboard_forcecolors.value) + if (scr_scoreboard_forcecolors.ival) return p->ttopcolor; else return p->rtopcolor; @@ -140,30 +144,63 @@ int Sbar_TopColour(player_info_t *p) int Sbar_BottomColour(player_info_t *p) { - if (scr_scoreboard_forcecolors.value) + if (scr_scoreboard_forcecolors.ival) return p->tbottomcolor; else return p->rbottomcolor; } +//Draws a pre-marked-up string with no width limit. doesn't support new lines void Draw_ExpandedString(int x, int y, conchar_t *str) { + Font_BeginString(font_conchar, x, y, &x, &y); while(*str) { - Draw_ColouredCharacter (x, y, *str++); - x += 8; + x = Font_DrawChar(x, y, *str++); } + Font_EndString(font_conchar); } -void Draw_FunString(int x, int y, unsigned char *str) +//Draws a marked-up string using the regular char set with no width limit. doesn't support new lines +void Draw_FunString(int x, int y, const unsigned char *str) { conchar_t buffer[2048]; COM_ParseFunString(CON_WHITEMASK, str, buffer, sizeof(buffer), false); Draw_ExpandedString(x, y, buffer); } +//Draws a marked up string using the alt char set (legacy mode would be |128) +void Draw_AltFunString(int x, int y, const unsigned char *str) +{ + conchar_t buffer[2048]; + COM_ParseFunString(COLOR_MAGENTA<width, p->height, p); x += CHAR_WIDTH; ptr++; l--; @@ -295,6 +343,7 @@ void Sbar_ExecuteLayoutString (char *s) int width; int index; // q2clientinfo_t *ci; + mpic_t *p; if (cls.state != ca_active) return; @@ -357,7 +406,9 @@ void Sbar_ExecuteLayoutString (char *s) { // SCR_AddDirtyPoint (x, y); // SCR_AddDirtyPoint (x+23, y+23); - Draw_Pic (x, y, Draw_SafeCachePic(Get_Q2ConfigString(Q2CS_IMAGES+value))); + p = Sbar_Q2CachePic(Get_Q2ConfigString(Q2CS_IMAGES+value)); + if (p) + Draw_ScalePic (x, y, p->width, p->height, p); } continue; } @@ -389,14 +440,14 @@ void Sbar_ExecuteLayoutString (char *s) time = atoi(com_token); // DrawAltString (x+32, y, ci->name); - Draw_String (x+32, y+8, "Score: "); - Draw_Alt_String (x+32+7*8, y+8, va("%i", score)); - Draw_String (x+32, y+16, va("Ping: %i", ping)); - Draw_String (x+32, y+24, va("Time: %i", time)); + Draw_FunString (x+32, y+8, "Score: "); + Draw_AltFunString (x+32+7*8, y+8, va("%i", score)); + Draw_FunString (x+32, y+16, va("Ping: %i", ping)); + Draw_FunString (x+32, y+24, va("Time: %i", time)); // if (!ci->icon) // ci = &cl.baseclientinfo; -// Draw_Pic (x, y, Draw_CachePic(ci->iconname)); +// Draw_Pic (x, y, Draw_SafeCachePic(ci->iconname)); continue; } @@ -431,7 +482,7 @@ void Sbar_ExecuteLayoutString (char *s) // if (value == cl.playernum) // Draw_Alt_String (x, y, block); // else - Draw_String (x, y, block); + Draw_FunString (x, y, block); continue; } @@ -440,7 +491,9 @@ void Sbar_ExecuteLayoutString (char *s) s = COM_Parse (s); // SCR_AddDirtyPoint (x, y); // SCR_AddDirtyPoint (x+23, y+23); - Draw_Pic (x, y, Draw_SafeCachePic(com_token)); + p = Draw_SafeCachePic(com_token); + if (p) + Draw_ScalePic (x, y, p->width, p->height, p); continue; } @@ -468,7 +521,11 @@ void Sbar_ExecuteLayoutString (char *s) color = 1; if (cl.q2frame.playerstate.stats[Q2STAT_FLASHES] & 1) - Draw_Pic (x, y, Draw_SafeCachePic("field_3")); + { + p = Draw_SafeCachePic("field_3"); + if (p) + Draw_ScalePic (x, y, p->width, p->height, p); + } SCR_DrawField (x, y, color, width, value); continue; @@ -488,7 +545,11 @@ void Sbar_ExecuteLayoutString (char *s) continue; // negative number = don't show if (cl.q2frame.playerstate.stats[Q2STAT_FLASHES] & 4) - Draw_Pic (x, y, Draw_SafeCachePic("field_3")); + { + p = Draw_SafeCachePic("field_3"); + if (p) + Draw_ScalePic (x, y, p->width, p->height, p); + } SCR_DrawField (x, y, color, width, value); continue; @@ -506,7 +567,7 @@ void Sbar_ExecuteLayoutString (char *s) color = 0; // green if (cl.q2frame.playerstate.stats[Q2STAT_FLASHES] & 2) - Draw_Pic (x, y, Draw_SafeCachePic("field_3")); + Draw_ScalePic (x, y, FINDOUT, FINDOUT, Draw_SafeCachePic("field_3")); SCR_DrawField (x, y, color, width, value); continue; @@ -522,7 +583,7 @@ void Sbar_ExecuteLayoutString (char *s) index = cl.q2frame.playerstate.stats[index]; if (index < 0 || index >= Q2MAX_CONFIGSTRINGS) Host_EndGame ("Bad stat_string index"); - Draw_String (x, y, Get_Q2ConfigString(index)); + Draw_FunString (x, y, Get_Q2ConfigString(index)); continue; } @@ -536,7 +597,7 @@ void Sbar_ExecuteLayoutString (char *s) if (!strcmp(com_token, "string")) { s = COM_Parse (s); - Draw_String (x, y, com_token); + Draw_FunString (x, y, com_token); continue; } @@ -550,7 +611,7 @@ void Sbar_ExecuteLayoutString (char *s) if (!strcmp(com_token, "string2")) { s = COM_Parse (s); - Draw_Alt_String (x, y, com_token); + Draw_AltFunString (x, y, com_token); continue; } @@ -622,7 +683,7 @@ Tab key down */ void Sbar_ShowScores (void) { - if (scr_scoreboard_teamscores.value) + if (scr_scoreboard_teamscores.ival) { Sbar_ShowTeamScores(); return; @@ -678,7 +739,7 @@ Tab key up */ void Sbar_DontShowScores (void) { - if (scr_scoreboard_teamscores.value) + if (scr_scoreboard_teamscores.ival) { Sbar_DontShowTeamScores(); return; @@ -896,9 +957,9 @@ void Sbar_Init (void) Sbar_DrawPic ============= */ -void Sbar_DrawPic (int x, int y, mpic_t *pic) +void Sbar_DrawPic (int x, int y, int w, int h, mpic_t *pic) { - Draw_Pic (sbar_rect.x + x /* + ((sbar_rect.width - 320)>>1) */, sbar_rect.y + y + (sbar_rect.height-SBAR_HEIGHT), pic); + Draw_ScalePic(sbar_rect.x + x /* + ((sbar_rect.width - 320)>>1) */, sbar_rect.y + y + (sbar_rect.height-SBAR_HEIGHT), w, h, pic); } /* @@ -908,20 +969,9 @@ Sbar_DrawSubPic JACK: Draws a portion of the picture in the status bar. */ -void Sbar_DrawSubPic(int x, int y, mpic_t *pic, int srcx, int srcy, int width, int height) +void Sbar_DrawSubPic(int x, int y, int width, int height, mpic_t *pic, int srcx, int srcy, int srcwidth, int srcheight) { - Draw_SubPic (sbar_rect.x + x, sbar_rect.y + y+(sbar_rect.height-SBAR_HEIGHT), pic, srcx, srcy, width, height); -} - - -/* -============= -Sbar_DrawTransPic -============= -*/ -void Sbar_DrawTransPic (int x, int y, mpic_t *pic) -{ - Draw_TransPic (sbar_rect.x + x /*+ ((sbar_rect.width - 320)>>1) */, sbar_rect.y + y + (sbar_rect.height-SBAR_HEIGHT), pic); + Draw_SubPic (sbar_rect.x + x, sbar_rect.y + y+(sbar_rect.height-SBAR_HEIGHT), width, height, pic, srcx, srcy, srcwidth, srcheight); } /* @@ -933,7 +983,9 @@ Draws one solid graphics character */ void Sbar_DrawCharacter (int x, int y, int num) { - Draw_Character (sbar_rect.x + x /*+ ((sbar_rect.width - 320)>>1) */ + 4, sbar_rect.y + y + sbar_rect.height-SBAR_HEIGHT, num); + Font_BeginString(font_conchar, sbar_rect.x + x + 4, sbar_rect.y + y + sbar_rect.height-SBAR_HEIGHT, &x, &y); + Font_DrawChar(x, y, num | 0xe000 | CON_WHITEMASK); + Font_EndString(font_conchar); } /* @@ -942,33 +994,33 @@ Sbar_DrawString ================ */ void Sbar_DrawString (int x, int y, char *str) -{ - Draw_String (sbar_rect.x + x /*+ ((sbar_rect.width - 320)>>1) */, sbar_rect.y + y+ sbar_rect.height-SBAR_HEIGHT, str); -} - -void Sbar_DrawFunString (int x, int y, char *str) { Draw_FunString (sbar_rect.x + x /*+ ((sbar_rect.width - 320)>>1) */, sbar_rect.y + y+ sbar_rect.height-SBAR_HEIGHT, str); } void Draw_TinyString (int x, int y, const qbyte *str) { - float xstart = x; + float xstart; + +#pragma message("hexen2: use a tinychar *6 font") + if (!font_tiny) + return; + + Font_BeginString(font_tiny, x, y, &x, &y); + xstart = x; + while (*str) { if (*str == '\n') { x = xstart; - y += 6; + y += Font_CharHeight(); str++; continue; } - if (Draw_TinyCharacter) - Draw_TinyCharacter (x, y, *str); -// Draw_Character (x, y, *str); - str++; - x += 6; + x = Font_DrawChar(x, y, *str++); } + Font_EndString(font_tiny); } void Sbar_DrawTinyString (int x, int y, char *str) { @@ -1083,7 +1135,7 @@ void Sbar_DrawNum (int x, int y, int num, int digits, int color) else frame = *ptr -'0'; - Sbar_DrawTransPic (x,y,sb_nums[color][frame]); + Sbar_DrawPic (x, y, 24, 24, sb_nums[color][frame]); x += 24; ptr++; } @@ -1111,7 +1163,7 @@ void Sbar_Hexen2DrawNum (int x, int y, int num, int digits) else frame = *ptr -'0'; - Sbar_DrawTransPic (x,y,sb_nums[0][frame]); + Sbar_DrawPic (x, y, FINDOUT, FINDOUT, sb_nums[0][frame]); x += 13; ptr++; } @@ -1268,7 +1320,7 @@ void Sbar_SoloScoreboard (void) char str[80]; int minutes, seconds, tens, units; - Sbar_DrawPic (0, 0, sb_scorebar); + Sbar_DrawPic (0, 0, 320, 24, sb_scorebar); // time time = cl.servertime; @@ -1335,12 +1387,12 @@ void Sbar_DrawInventory (int pnum) if (sbar_rogue) { if ( cl.stats[pnum][STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN ) - Sbar_DrawPic (0, -24, rsb_invbar[0]); + Sbar_DrawPic (0, -24, FINDOUT, FINDOUT, rsb_invbar[0]); else - Sbar_DrawPic (0, -24, rsb_invbar[1]); + Sbar_DrawPic (0, -24, FINDOUT, FINDOUT, rsb_invbar[1]); } else - Sbar_DrawPic (0, -24, sb_ibar); + Sbar_DrawPic (0, -24, 320, 24, sb_ibar); } // weapons for (i=0 ; i<7 ; i++) @@ -1361,13 +1413,15 @@ void Sbar_DrawInventory (int pnum) else flashon = (flashon%5) + 2; - if (headsup) { + if (headsup) + { if (i || sbar_rect.height>200) - Sbar_DrawSubPic ((hudswap) ? 0 : (sbar_rect.width-24),-68-(7-i)*16 , sb_weapons[flashon][i],0,0,24,16); - - } else - Sbar_DrawPic (i*24, -16, sb_weapons[flashon][i]); -// Sbar_DrawSubPic (0,0,20,20,i*24, -16, sb_weapons[flashon][i]); + Sbar_DrawSubPic ((hudswap) ? 0 : (sbar_rect.width-24),-68-(7-i)*16, 24,16, sb_weapons[flashon][i],0,0,(i==6)?48:24, 16); + } + else + { + Sbar_DrawPic (i*24, -16, 24, 16, sb_weapons[flashon][i]); + } if (flashon > 1) sb_updates = 0; // force update to remove flash @@ -1386,11 +1440,11 @@ void Sbar_DrawInventory (int pnum) if (headsup) { if (sbar_rect.height>200) - Sbar_DrawSubPic ((hudswap) ? 0 : (sbar_rect.width-24),-68-(5-i)*16 , rsb_weapons[i],0,0,24,16); + Sbar_DrawSubPic ((hudswap) ? 0 : (sbar_rect.width-24),-68-(5-i)*16, FINDOUT, FINDOUT, rsb_weapons[i],0,0,FINDOUT,FINDOUT); } else - Sbar_DrawPic ((i+2)*24, -16, rsb_weapons[i]); + Sbar_DrawPic ((i+2)*24, -16, 24, 16, rsb_weapons[i]); } } } @@ -1399,17 +1453,26 @@ void Sbar_DrawInventory (int pnum) // ammo counts for (i=0 ; i<4 ; i++) { - sprintf (num, "%3i",cl.stats[pnum][STAT_SHELLS+i] ); + snprintf (num, sizeof(num), "%3i",cl.stats[pnum][STAT_SHELLS+i] ); + if (num[0] != ' ') + num[0] += 18-'0'; + if (num[1] != ' ') + num[1] += 18-'0'; + if (num[2] != ' ') + num[2] += 18-'0'; if (headsup) { // Sbar_DrawSubPic(3, -24, sb_ibar, 3, 0, 42,11); - Sbar_DrawSubPic((hudswap) ? 0 : (sbar_rect.width-42), -24 - (4-i)*11, sb_ibar, 3+(i*48), 0, 42, 11); + Sbar_DrawSubPic((hudswap) ? 0 : (sbar_rect.width-42), -24 - (4-i)*11, 42, 11, sb_ibar, 3+(i*48), 0, 320, 24); +/* if (num[0] != ' ') Sbar_DrawCharacter ( (hudswap) ? 3 : (sbar_rect.width-39), -24 - (4-i)*11, 18 + num[0] - '0'); if (num[1] != ' ') Sbar_DrawCharacter ( (hudswap) ? 11 : (sbar_rect.width-31), -24 - (4-i)*11, 18 + num[1] - '0'); if (num[2] != ' ') Sbar_DrawCharacter ( (hudswap) ? 19 : (sbar_rect.width-23), -24 - (4-i)*11, 18 + num[2] - '0'); +*/ + Sbar_DrawString((hudswap) ? 3 : (sbar_rect.width-39), -24 - (4-i)*11, num); } else { @@ -1434,7 +1497,7 @@ void Sbar_DrawInventory (int pnum) sb_updates = 0; } else - Sbar_DrawPic (192 + i*16, -16, sb_items[i]); + Sbar_DrawPic (192 + i*16, -16, 16, 16, sb_items[i]); if (time && time > cl.time - 2) sb_updates = 0; } @@ -1455,7 +1518,7 @@ void Sbar_DrawInventory (int pnum) } else { - Sbar_DrawPic (288 + i*16, -16, rsb_items[i]); + Sbar_DrawPic (288 + i*16, -16, 16, 16, rsb_items[i]); } if (time && time > cl.time - 2) @@ -1476,7 +1539,7 @@ void Sbar_DrawInventory (int pnum) sb_updates = 0; } else - Sbar_DrawPic (320-32 + i*8, -16, sb_sigil[i]); + Sbar_DrawPic (320-32 + i*8, -16, 8, 16, sb_sigil[i]); if (time && time > cl.time - 2) sb_updates = 0; } @@ -1562,22 +1625,22 @@ void Sbar_DrawFace (int pnum) if ( (cl.stats[pnum][STAT_ITEMS] & (IT_INVISIBILITY | IT_INVULNERABILITY) ) == (IT_INVISIBILITY | IT_INVULNERABILITY) ) { - Sbar_DrawPic (112, 0, sb_face_invis_invuln); + Sbar_DrawPic (112, 0, 24, 24, sb_face_invis_invuln); return; } if (cl.stats[pnum][STAT_ITEMS] & IT_QUAD) { - Sbar_DrawPic (112, 0, sb_face_quad ); + Sbar_DrawPic (112, 0, 24, 24, sb_face_quad ); return; } if (cl.stats[pnum][STAT_ITEMS] & IT_INVISIBILITY) { - Sbar_DrawPic (112, 0, sb_face_invis ); + Sbar_DrawPic (112, 0, 24, 24, sb_face_invis ); return; } if (cl.stats[pnum][STAT_ITEMS] & IT_INVULNERABILITY) { - Sbar_DrawPic (112, 0, sb_face_invuln); + Sbar_DrawPic (112, 0, 24, 24, sb_face_invuln); return; } @@ -1596,7 +1659,7 @@ void Sbar_DrawFace (int pnum) } else anim = 0; - Sbar_DrawPic (112, 0, sb_faces[f][anim]); + Sbar_DrawPic (112, 0, 24, 24, sb_faces[f][anim]); } /* @@ -1607,13 +1670,13 @@ Sbar_DrawNormal void Sbar_DrawNormal (int pnum) { if (cl_sbar.value || (scr_viewsize.value<100&&cl.splitclients==1)) - Sbar_DrawPic (0, 0, sb_sbar); + Sbar_DrawPic (0, 0, 320, 24, sb_sbar); // armor if (cl.stats[pnum][STAT_ITEMS] & IT_INVULNERABILITY) { Sbar_DrawNum (24, 0, 666, 3, 1); - Sbar_DrawPic (0, 0, draw_disc); + Sbar_DrawPic (0, 0, 24, 24, draw_disc); } else { @@ -1622,22 +1685,22 @@ void Sbar_DrawNormal (int pnum) Sbar_DrawNum (24, 0, cl.stats[pnum][STAT_ARMOR], 3, cl.stats[pnum][STAT_ARMOR] <= 25); if (cl.stats[pnum][STAT_ITEMS] & RIT_ARMOR3) - Sbar_DrawPic (0, 0, sb_armor[2]); + Sbar_DrawPic (0, 0, 24, 24, sb_armor[2]); else if (cl.stats[pnum][STAT_ITEMS] & RIT_ARMOR2) - Sbar_DrawPic (0, 0, sb_armor[1]); + Sbar_DrawPic (0, 0, 24, 24, sb_armor[1]); else if (cl.stats[pnum][STAT_ITEMS] & RIT_ARMOR1) - Sbar_DrawPic (0, 0, sb_armor[0]); + Sbar_DrawPic (0, 0, 24, 24, sb_armor[0]); } else { Sbar_DrawNum (24, 0, cl.stats[pnum][STAT_ARMOR], 3, cl.stats[pnum][STAT_ARMOR] <= 25); if (cl.stats[pnum][STAT_ITEMS] & IT_ARMOR3) - Sbar_DrawPic (0, 0, sb_armor[2]); + Sbar_DrawPic (0, 0, 24, 24, sb_armor[2]); else if (cl.stats[pnum][STAT_ITEMS] & IT_ARMOR2) - Sbar_DrawPic (0, 0, sb_armor[1]); + Sbar_DrawPic (0, 0, 24, 24, sb_armor[1]); else if (cl.stats[pnum][STAT_ITEMS] & IT_ARMOR1) - Sbar_DrawPic (0, 0, sb_armor[0]); + Sbar_DrawPic (0, 0, 24, 24, sb_armor[0]); } } @@ -1652,30 +1715,30 @@ void Sbar_DrawNormal (int pnum) if (sbar_rogue) { if (cl.stats[pnum][STAT_ITEMS] & RIT_SHELLS) - Sbar_DrawPic (224, 0, sb_ammo[0]); + Sbar_DrawPic (224, 0, 24, 24, sb_ammo[0]); else if (cl.stats[pnum][STAT_ITEMS] & RIT_NAILS) - Sbar_DrawPic (224, 0, sb_ammo[1]); + Sbar_DrawPic (224, 0, 24, 24, sb_ammo[1]); else if (cl.stats[pnum][STAT_ITEMS] & RIT_ROCKETS) - Sbar_DrawPic (224, 0, sb_ammo[2]); + Sbar_DrawPic (224, 0, 24, 24, sb_ammo[2]); else if (cl.stats[pnum][STAT_ITEMS] & RIT_CELLS) - Sbar_DrawPic (224, 0, sb_ammo[3]); + Sbar_DrawPic (224, 0, 24, 24, sb_ammo[3]); else if (cl.stats[pnum][STAT_ITEMS] & RIT_LAVA_NAILS) - Sbar_DrawPic (224, 0, rsb_ammo[0]); + Sbar_DrawPic (224, 0, 24, 24, rsb_ammo[0]); else if (cl.stats[pnum][STAT_ITEMS] & RIT_PLASMA_AMMO) - Sbar_DrawPic (224, 0, rsb_ammo[1]); + Sbar_DrawPic (224, 0, 24, 24, rsb_ammo[1]); else if (cl.stats[pnum][STAT_ITEMS] & RIT_MULTI_ROCKETS) - Sbar_DrawPic (224, 0, rsb_ammo[2]); + Sbar_DrawPic (224, 0, 24, 24, rsb_ammo[2]); } else { if (cl.stats[pnum][STAT_ITEMS] & IT_SHELLS) - Sbar_DrawPic (224, 0, sb_ammo[0]); + Sbar_DrawPic (224, 0, 24, 24, sb_ammo[0]); else if (cl.stats[pnum][STAT_ITEMS] & IT_NAILS) - Sbar_DrawPic (224, 0, sb_ammo[1]); + Sbar_DrawPic (224, 0, 24, 24, sb_ammo[1]); else if (cl.stats[pnum][STAT_ITEMS] & IT_ROCKETS) - Sbar_DrawPic (224, 0, sb_ammo[2]); + Sbar_DrawPic (224, 0, 24, 24, sb_ammo[2]); else if (cl.stats[pnum][STAT_ITEMS] & IT_CELLS) - Sbar_DrawPic (224, 0, sb_ammo[3]); + Sbar_DrawPic (224, 0, 24, 24, sb_ammo[3]); } Sbar_DrawNum (248, 0, cl.stats[pnum][STAT_AMMO], 3 @@ -1759,14 +1822,14 @@ void Sbar_DrawScoreboard (void) void Sbar_Hexen2DrawItem(int pnum, int x, int y, int itemnum) { int num; - Sbar_DrawPic(x, y, Draw_CachePic(va("gfx/arti%02d.lmp", itemnum))); + Sbar_DrawPic(x, y, FINDOUT, FINDOUT, Draw_SafeCachePic(va("gfx/arti%02d.lmp", itemnum))); num = cl.stats[pnum][STAT_H2_CNT_TORCH+itemnum]; if(num > 0) { if (num >= 10) - Sbar_DrawPic(x+20, y+21, Draw_CachePic(va("gfx/artinum%d.lmp", num/10))); - Sbar_DrawPic(x+20+4, y+21, Draw_CachePic(va("gfx/artinum%d.lmp", num%10))); + Sbar_DrawPic(x+20, y+21, FINDOUT, FINDOUT, Draw_SafeCachePic(va("gfx/artinum%d.lmp", num/10))); + Sbar_DrawPic(x+20+4, y+21, FINDOUT, FINDOUT, Draw_SafeCachePic(va("gfx/artinum%d.lmp", num%10))); } } @@ -1782,7 +1845,7 @@ void Sbar_Hexen2DrawInventory(int pnum) for (i = 0, x=320/2-114; i < 7; i++, x+=33) { if ((sb_hexen2_cur_item-3+i+30)%15 == sb_hexen2_cur_item) - Sbar_DrawTransPic(x+9, y-12, Draw_CachePic("gfx/artisel.lmp")); + Sbar_DrawPic(x+9, y-12, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/artisel.lmp")); Sbar_Hexen2DrawItem(pnum, x, y, (sb_hexen2_cur_item-3+i+30)%15); } #else @@ -1827,8 +1890,8 @@ void Sbar_Hexen2DrawExtra (int pnum) //adjust it so there's space sbar_rect.y -= 46+98-SBAR_HEIGHT; - Sbar_DrawPic(0, 46, Draw_SafeCachePic("gfx/btmbar1.lmp")); - Sbar_DrawPic(160, 46, Draw_SafeCachePic("gfx/btmbar2.lmp")); + Sbar_DrawPic(0, 46, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/btmbar1.lmp")); + Sbar_DrawPic(160, 46, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/btmbar2.lmp")); Sbar_DrawTinyString (11, 48, pclassname[pclass]); @@ -1861,7 +1924,7 @@ void Sbar_Hexen2DrawExtra (int pnum) { if (cl.stats[pnum][STAT_H2_ARMOUR1+i] > 0) { - Sbar_DrawPic (164+i*40, 115, Draw_SafeCachePic(va("gfx/armor%d.lmp", i+1))); + Sbar_DrawPic (164+i*40, 115, FINDOUT, FINDOUT, Draw_SafeCachePic(va("gfx/armor%d.lmp", i+1))); Sbar_DrawTinyString (168+i*40, 136, va("+%d", cl.stats[pnum][STAT_H2_ARMOUR1+i])); } } @@ -1869,14 +1932,14 @@ void Sbar_Hexen2DrawExtra (int pnum) { if (cl.stats[pnum][STAT_H2_FLIGHT_T+i] > 0) { - Sbar_DrawPic (ringpos[i], 119, Draw_SafeCachePic(va("gfx/ring_f.lmp"))); + Sbar_DrawPic (ringpos[i], 119, FINDOUT, FINDOUT, Draw_SafeCachePic(va("gfx/ring_f.lmp"))); val = cl.stats[pnum][STAT_H2_FLIGHT_T+i]; if (val > 100) val = 100; if (val < 0) val = 0; - Sbar_DrawPic(ringpos[i]+29 - (int)(26 * (val/(float)100)),142,Draw_CachePic("gfx/ringhlth.lmp")); - Sbar_DrawPic(ringpos[i]+29, 142, Draw_CachePic("gfx/rhlthcvr.lmp")); + Sbar_DrawPic(ringpos[i]+29 - (int)(26 * (val/(float)100)),142, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/ringhlth.lmp")); + Sbar_DrawPic(ringpos[i]+29, 142, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/rhlthcvr.lmp")); } } @@ -1885,23 +1948,23 @@ void Sbar_Hexen2DrawExtra (int pnum) { if (cl.statsstr[pnum][STAT_H2_PUZZLE1+i]) { - Sbar_DrawPic (194+(slot%4)*31, slot<4?51:82, Draw_SafeCachePic(va("gfx/puzzle/%s.lmp", cl.statsstr[pnum][STAT_H2_PUZZLE1+i]))); + Sbar_DrawPic (194+(slot%4)*31, slot<4?51:82, FINDOUT, FINDOUT, Draw_SafeCachePic(va("gfx/puzzle/%s.lmp", cl.statsstr[pnum][STAT_H2_PUZZLE1+i]))); slot++; } } - Sbar_DrawPic(134, 50, Draw_SafeCachePic(va("gfx/cport%d.lmp", pclass))); + Sbar_DrawPic(134, 50, FINDOUT, FINDOUT, Draw_SafeCachePic(va("gfx/cport%d.lmp", pclass))); } void Sbar_Hexen2DrawBasic(int pnum) { int chainpos; int val, maxval; - Sbar_DrawPic(0, 0, Draw_CachePic("gfx/topbar1.lmp")); - Sbar_DrawPic(160, 0, Draw_CachePic("gfx/topbar2.lmp")); - Sbar_DrawTransPic(0, -23, Draw_CachePic("gfx/topbumpl.lmp")); - Sbar_DrawTransPic(138, -8, Draw_CachePic("gfx/topbumpm.lmp")); - Sbar_DrawTransPic(269, -23, Draw_CachePic("gfx/topbumpr.lmp")); + Sbar_DrawPic(0, 0, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/topbar1.lmp")); + Sbar_DrawPic(160, 0, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/topbar2.lmp")); + Sbar_DrawPic(0, -23, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/topbumpl.lmp")); + Sbar_DrawPic(138, -8, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/topbumpm.lmp")); + Sbar_DrawPic(269, -23, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/topbumpr.lmp")); //mana1 maxval = cl.stats[pnum][STAT_H2_MAXMANA]; @@ -1910,8 +1973,8 @@ void Sbar_Hexen2DrawBasic(int pnum) Sbar_DrawTinyString(201, 22, va("%03d", val)); if(val) { - Sbar_DrawPic(190, 26-(int)((val*18.0)/(float)maxval+0.5), Draw_CachePic("gfx/bmana.lmp")); - Sbar_DrawPic(190, 27, Draw_CachePic("gfx/bmanacov.lmp")); + Sbar_DrawPic(190, 26-(int)((val*18.0)/(float)maxval+0.5), FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/bmana.lmp")); + Sbar_DrawPic(190, 27, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/bmanacov.lmp")); } //mana2 @@ -1921,8 +1984,8 @@ void Sbar_Hexen2DrawBasic(int pnum) Sbar_DrawTinyString(243, 22, va("%03d", val)); if(val) { - Sbar_DrawPic(232, 26-(int)((val*18.0)/(float)maxval+0.5), Draw_CachePic("gfx/gmana.lmp")); - Sbar_DrawPic(232, 27, Draw_CachePic("gfx/gmanacov.lmp")); + Sbar_DrawPic(232, 26-(int)((val*18.0)/(float)maxval+0.5), FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/gmana.lmp")); + Sbar_DrawPic(232, 27, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/gmanacov.lmp")); } @@ -1940,10 +2003,10 @@ void Sbar_Hexen2DrawBasic(int pnum) chainpos = (195.0f*cl.stats[pnum][STAT_HEALTH]) / cl.stats[pnum][STAT_H2_MAXHEALTH]; if (chainpos < 0) chainpos = 0; - Sbar_DrawPic(45+((int)chainpos&7), 38, Draw_CachePic("gfx/hpchain.lmp")); - Sbar_DrawPic(45+(int)chainpos, 36, Draw_CachePic("gfx/hpgem.lmp")); - Sbar_DrawPic(43, 36, Draw_CachePic("gfx/chnlcov.lmp")); - Sbar_DrawPic(267, 36, Draw_CachePic("gfx/chnrcov.lmp")); + Sbar_DrawPic(45+((int)chainpos&7), 38, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/hpchain.lmp")); + Sbar_DrawPic(45+(int)chainpos, 36, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/hpgem.lmp")); + Sbar_DrawPic(43, 36, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/chnlcov.lmp")); + Sbar_DrawPic(267, 36, FINDOUT, FINDOUT, Draw_SafeCachePic("gfx/chnrcov.lmp")); Sbar_Hexen2DrawItem(pnum, 144, 3, sb_hexen2_cur_item); @@ -1957,7 +2020,7 @@ void Sbar_DrawTeamStatus(void) int y; int track; - if (!sbar_teamstatus.value) + if (!sbar_teamstatus.ival) return; y = -32; @@ -1979,7 +2042,7 @@ void Sbar_DrawTeamStatus(void) if (*cl.players[p].name) { - Sbar_DrawFunString (0, y, cl.players[p].teamstatus); + Sbar_DrawString (0, y, cl.players[p].teamstatus); y-=8; } } @@ -2106,6 +2169,8 @@ void Sbar_Draw (void) Sbar_Start(); + Draw_ImageColours(1, 1, 1, 1); + for (pnum = 0; pnum < cl.splitclients; pnum++) { if (cl.splitclients>1 || scr_chatmode) @@ -2122,7 +2187,7 @@ void Sbar_Draw (void) sbar_rect.x = 0; sbar_rect.y = 0; - if (scr_centersbar.value) + if (scr_centersbar.ival) { sbar_rect.x = (vid.width - 320)/2; sbar_rect.width -= sbar_rect.x; @@ -2145,8 +2210,8 @@ void Sbar_Draw (void) if (cl.stats[pnum][STAT_HEALTH] <= 0) //when dead, show nothing continue; - if (scr_viewsize.value != 120) - Cvar_Set(&scr_viewsize, "120"); +// if (scr_viewsize.value != 120) +// Cvar_Set(&scr_viewsize, "120"); Sbar_DrawString (0, -8, va("Health: %i", cl.stats[pnum][STAT_HEALTH])); Sbar_DrawString (0, -16, va(" Armor: %i", cl.stats[pnum][STAT_ARMOR])); @@ -2177,7 +2242,7 @@ void Sbar_Draw (void) { if (autocam[pnum] != CAM_TRACK) { - Sbar_DrawPic (0, 0, sb_scorebar); + Sbar_DrawPic (0, 0, 320, 24, sb_scorebar); Sbar_DrawString (160-7*8,4, "SPECTATOR MODE"); Sbar_DrawString(160-14*8+4, 12, "Press [ATTACK] for AutoCamera"); } @@ -2190,11 +2255,11 @@ void Sbar_Draw (void) else Sbar_DrawNormal (pnum); - if (hud_tracking_show.value) + if (hud_tracking_show.ival) { sprintf(st, "Tracking %-.64s", cl.players[spec_track[pnum]].name); - Sbar_DrawFunString(0, -8, st); + Sbar_DrawString(0, -8, st); } } } @@ -2213,7 +2278,7 @@ void Sbar_Draw (void) } } -#ifdef RGLQUAKE +#ifdef GLQUAKE if (cl_sbar.value == 1 || scr_viewsize.value<100) { if (cl.splitclients==1 && sbar_rect.x>0) @@ -2267,7 +2332,7 @@ void Sbar_IntermissionNumber (int x, int y, int num, int digits, int color) else frame = *ptr -'0'; - Draw_TransPic (x,y,sb_nums[color][frame]); + Draw_ScalePic (x,y, 16, 24, sb_nums[color][frame]); x += 24; ptr++; } @@ -2299,19 +2364,22 @@ void Sbar_TeamOverlay (void) y = 0; - if (scr_scoreboard_drawtitle.value) + if (scr_scoreboard_drawtitle.ival) { pic = Draw_SafeCachePic ("gfx/ranking.lmp"); if (pic) - Draw_Pic ((vid.width-pic->width)/2, 0, pic); + { + k = (pic->width * 24) / pic->height; + Draw_ScalePic ((vid.width-k)/2, 0, k, 24, pic); + } y += 24; } x = (vid.width - 320)/2 + 36; - Draw_String(x, y, "low/avg/high team total players"); + Draw_FunString(x, y, "low/avg/high team total players"); y += 8; // Draw_String(x, y, "------------ ---- ----- -------"); - Draw_String(x, y, "\x1d\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1f \x1d\x1e\x1e\x1f \x1d\x1e\x1e\x1e\x1f \x1d\x1e\x1e\x1e\x1e\x1e\x1f"); + Draw_FunString(x, y, "\x1d\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1f \x1d\x1e\x1e\x1f \x1d\x1e\x1e\x1e\x1f \x1d\x1e\x1e\x1e\x1e\x1e\x1f"); y += 8; // sort the teams @@ -2340,23 +2408,24 @@ void Sbar_TeamOverlay (void) pavg = 999; sprintf (num, "%3i/%3i/%3i", plow, pavg, phigh); - Draw_String ( x, y, num); + Draw_FunString ( x, y, num); // draw team Q_strncpyz (team, tm->team, sizeof(team)); - Draw_String (x + 104, y, team); + Draw_FunString (x + 104, y, team); // draw total sprintf (num, "%5i", tm->frags); - Draw_String (x + 104 + 40, y, num); + Draw_FunString (x + 104 + 40, y, num); // draw players sprintf (num, "%5i", tm->players); - Draw_String (x + 104 + 88, y, num); + Draw_FunString (x + 104 + 88, y, num); - if (!strncmp(cl.players[cl.playernum[0]].team, tm->team, 16)) { - Draw_Character ( x + 104 - 8, y, 16); - Draw_Character ( x + 104 + 32, y, 17); + if (!strncmp(cl.players[cl.playernum[0]].team, tm->team, 16)) + { + Draw_FunString ( x + 104 - 8, y, "^Ue016"); + Draw_FunString ( x + 104 + 32, y, "^Ue017"); } y += 8; @@ -2381,14 +2450,14 @@ ping time frags name int p = s->ping; \ if (p < 0 || p > 999) p = 999; \ sprintf(num, "%4i", p); \ - Draw_FunString(x, y, num); \ + Draw_FunStringWidth(x, y, num, 4*8); \ }) #define COLUMN_PL COLUMN(pl, 2*8, \ { \ int p = s->pl; \ sprintf(num, "%2i", p); \ - Draw_FunString(x, y, num); \ + Draw_FunStringWidth(x, y, num, 2*8); \ }) #define COLUMN_TIME COLUMN(time, 4*8, \ { \ @@ -2398,54 +2467,57 @@ ping time frags name total = cl.servertime - s->entertime; \ minutes = (int)total/60; \ sprintf (num, "%4i", minutes); \ - Draw_String ( x , y, num); \ + Draw_FunStringWidth(x, y, num, 4*8); \ }) #define COLUMN_FRAGS COLUMN(frags, 5*8, \ -{ \ +{ \ + int cx; int cy; \ if (s->spectator) \ { \ - if (cl.teamplay) \ - Draw_String( x, y, "spectator" ); \ - else \ - Draw_String( x, y, "spec" ); \ + Draw_FunStringWidth(x, y, "spectator", 5*8); \ } \ else \ { \ if (largegame) \ - Sbar_FillPC ( x, y+1, 40, 3, top); \ + Sbar_FillPC(x, y+1, 40, 3, top); \ else \ - Sbar_FillPC ( x, y, 40, 4, top); \ - Sbar_FillPC ( x, y+4, 40, 4, bottom); \ + Sbar_FillPC(x, y, 40, 4, top); \ + Sbar_FillPC(x, y+4, 40, 4, bottom); \ \ f = s->frags; \ - sprintf (num, "%3i",f); \ + sprintf(num, "%3i",f); \ \ - Draw_Character ( x+8 , y, num[0]); \ - Draw_Character ( x+16 , y, num[1]); \ - Draw_Character ( x+24 , y, num[2]); \ + Font_BeginString(font_conchar, x+8, y, &cx, &cy); \ + Font_DrawChar(cx, cy, num[0] | 0xe000 | CON_WHITEMASK); \ + Font_BeginString(font_conchar, x+16, y, &cx, &cy); \ + Font_DrawChar(cx, cy, num[1] | 0xe000 | CON_WHITEMASK); \ + Font_BeginString(font_conchar, x+24, y, &cx, &cy); \ + Font_DrawChar(cx, cy, num[2] | 0xe000 | CON_WHITEMASK); \ \ if ((cl.spectator && k == spec_track[0]) || \ (!cl.spectator && k == cl.playernum[0])) \ { \ - Draw_Character ( x, y, 16); \ - Draw_Character ( x + 32, y, 17); \ + Font_BeginString(font_conchar, x, y, &cx, &cy); \ + Font_DrawChar(cx, cy, 16 | 0xe000 | CON_WHITEMASK); \ + Font_BeginString(font_conchar, x+32, y, &cx, &cy); \ + Font_DrawChar(cx, cy, 17 | 0xe000 | CON_WHITEMASK); \ } \ + Font_EndString(font_conchar); \ } \ - \ }) #define COLUMN_TEAMNAME COLUMN(team, 4*8, \ { \ if (!s->spectator) \ { \ - Draw_FunStringLen(x, y, s->team, 4); \ + Draw_FunStringWidth(x, y, s->team, 4*8); \ } \ }) -#define COLUMN_NAME COLUMN(name, (cl.teamplay ? 12*8 : 16*8), {Draw_FunString(x, y, s->name);}) -#define COLUMN_KILLS COLUMN(kils, 4*8, {Draw_FunString(x, y, va("%4i", Stats_GetKills(k)));}) -#define COLUMN_TKILLS COLUMN(tkil, 4*8, {Draw_FunString(x, y, va("%4i", Stats_GetTKills(k)));}) -#define COLUMN_DEATHS COLUMN(dths, 4*8, {Draw_FunString(x, y, va("%4i", Stats_GetDeaths(k)));}) -#define COLUMN_TOUCHES COLUMN(tchs, 4*8, {Draw_FunString(x, y, va("%4i", Stats_GetTouches(k)));}) -#define COLUMN_CAPS COLUMN(caps, 4*8, {Draw_FunString(x, y, va("%4i", Stats_GetCaptures(k)));}) +#define COLUMN_NAME COLUMN(name, (cl.teamplay ? 12*8 : 16*8), {Draw_FunStringWidth(x, y, s->name, (cl.teamplay ? 12*8 : 16*8));}) +#define COLUMN_KILLS COLUMN(kils, 4*8, {Draw_FunStringWidth(x, y, va("%4i", Stats_GetKills(k)), 4*8);}) +#define COLUMN_TKILLS COLUMN(tkil, 4*8, {Draw_FunStringWidth(x, y, va("%4i", Stats_GetTKills(k)), 4*8);}) +#define COLUMN_DEATHS COLUMN(dths, 4*8, {Draw_FunStringWidth(x, y, va("%4i", Stats_GetDeaths(k)), 4*8);}) +#define COLUMN_TOUCHES COLUMN(tchs, 4*8, {Draw_FunStringWidth(x, y, va("%4i", Stats_GetTouches(k)), 4*8);}) +#define COLUMN_CAPS COLUMN(caps, 4*8, {Draw_FunStringWidth(x, y, va("%4i", Stats_GetCaptures(k)), 4*8);}) @@ -2489,11 +2561,14 @@ void Sbar_DeathmatchOverlay (int start) else { y = 0; - if (scr_scoreboard_drawtitle.value) + if (scr_scoreboard_drawtitle.ival) { pic = Draw_SafeCachePic ("gfx/ranking.lmp"); if (pic) - Draw_Pic ((vid.width - 320)/2 + 160-pic->width/2, 0, pic); + { + k = (pic->width * 24) / pic->height; + Draw_ScalePic ((vid.width-k)/2, 0, k, 24, pic); + } y += 24; } } @@ -2509,7 +2584,7 @@ void Sbar_DeathmatchOverlay (int start) else y = 24; - if (scr_scoreboard_newstyle.value) + if (scr_scoreboard_newstyle.ival) { // Electro's scoreboard eyecandy: Increase to fit the new scoreboard y += 8; @@ -2551,7 +2626,7 @@ void Sbar_DeathmatchOverlay (int start) startx = (vid.width-rank_width)/2; - if (scr_scoreboard_newstyle.value) + if (scr_scoreboard_newstyle.ival) { // Electro's scoreboard eyecandy: Draw top border Draw_Fill(startx - 3, y - 1, rank_width - 1, 1, 0); @@ -2568,16 +2643,16 @@ void Sbar_DeathmatchOverlay (int start) y += 8; - if (scr_scoreboard_titleseperator.value && !scr_scoreboard_newstyle.value) + if (scr_scoreboard_titleseperator.ival && !scr_scoreboard_newstyle.ival) { x = startx; #define COLUMN(title, width, code) \ if (showcolumns & (1<name[0]) - continue; - - // draw ping - p = s->ping; - if (p < 0 || p > 999) - p = 999; - sprintf (num, "%4i", p); - Draw_FunString ( x, y, num); - - // draw pl - p = s->pl; - sprintf (num, "%3i", p); - if (p > 25) - Draw_Alt_String ( x+32, y, num); - else - Draw_String ( x+32, y, num); - - if (s->spectator) - { - Draw_String (x+56, y, "(spectator)"); - // draw name - if (cl.teamplay) - Draw_FunString (x+152+40, y, s->name); - else - Draw_FunString (x+152, y, s->name); - y += skip; - continue; - } - - - // draw time - if (cl.intermission) - total = cl.completed_time - s->entertime; - else - total = cl.servertime - s->entertime; - minutes = (int)total/60; - sprintf (num, "%4i", minutes); - Draw_String ( x+64 , y, num); - - // draw background - top = s->topcolor; - bottom = s->bottomcolor; - top = Sbar_ColorForMap (top); - bottom = Sbar_ColorForMap (bottom); - - if (largegame) - Draw_Fill ( x+104, y+1, 40, 3, top); - else - Draw_Fill ( x+104, y, 40, 4, top); - Draw_Fill ( x+104, y+4, 40, 4, bottom); - - // draw number - f = s->frags; - sprintf (num, "%3i",f); - - Draw_Character ( x+112 , y, num[0]); - Draw_Character ( x+120 , y, num[1]); - Draw_Character ( x+128 , y, num[2]); - - if ((cl.spectator && k == spec_track[0]) || - (!cl.spectator && k == cl.playernum[0])) - { - Draw_Character ( x + 104, y, 16); - Draw_Character ( x + 136, y, 17); - } - - // team - if (cl.teamplay) - Draw_FunStringLen (x+152, y, s->team, 4); - - // draw name - if (cl.teamplay) - Draw_FunString (x+152+40, y, s->name); - else - Draw_FunString (x+152, y, s->name); - - y += skip; - } -*/ - Draw_Character(0,0,' ' | CON_WHITEMASK); - if (y >= vid.height-10) // we ran over the screen size, squish largegame = true; } @@ -2816,9 +2777,9 @@ void Sbar_ChatModeOverlay(void) y = vid.height/2; x = 4; - Draw_String ( x , y, "name"); + Draw_FunString ( x , y, "name"); y += 8; - Draw_String ( x , y, "\x1d\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1f"); + Draw_FunString ( x , y, "\x1d\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1e\x1f"); y += 8; for (i=0 ; iname); @@ -2866,8 +2827,6 @@ void Sbar_ChatModeOverlay(void) y += skip; } - Draw_Character(0,0,' ' | CON_WHITEMASK); - if (y >= vid.height-10) // we ran over the screen size, squish largegame = true; } @@ -2885,7 +2844,7 @@ void Sbar_MiniDeathmatchOverlay (void) { int i, k; int top, bottom; - int x, y, f; + int x, y, f, px, py; char num[12]; player_info_t *s; int numlines; @@ -2944,26 +2903,31 @@ void Sbar_MiniDeathmatchOverlay (void) f = s->frags; sprintf (num, "%3i",f); - Draw_ColouredCharacter ( x+8 , y, CON_WHITEMASK|num[0]); - Draw_Character ( x+16, y, num[1]); - Draw_Character ( x+24, y, num[2]); + Font_BeginString(font_conchar, x+8, y, &px, &py); + Font_DrawChar ( px, py, num[0] | 0xe000 | CON_WHITEMASK); + Font_BeginString(font_conchar, x+16, y, &px, &py); + Font_DrawChar ( px, py, num[1] | 0xe000 | CON_WHITEMASK); + Font_BeginString(font_conchar, x+24, y, &px, &py); + Font_DrawChar ( px, py, num[2] | 0xe000 | CON_WHITEMASK); if ((cl.spectator && k == spec_track[0]) || (!cl.spectator && k == cl.playernum[0])) { - Draw_Character ( x, y, 16); - Draw_Character ( x + 32, y, 17); + Font_BeginString(font_conchar, x, y, &px, &py); + Font_DrawChar ( px, py, 16 | 0xe000 | CON_WHITEMASK); + Font_BeginString(font_conchar, x+32, y, &px, &py); + Font_DrawChar ( px, py, 17 | 0xe000 | CON_WHITEMASK); } Q_strncpyz(name, s->name, sizeof(name)); // team and name if (cl.teamplay) { - Draw_FunStringLen (x+48, y, s->team, 4); - Draw_FunStringLen (x+48+40, y, name, MAX_DISPLAYEDNAME); + Draw_FunStringWidth (x+48, y, s->team, 32); + Draw_FunStringWidth (x+48+40, y, name, MAX_DISPLAYEDNAME*8); } else - Draw_FunStringLen (x+48, y, name, MAX_DISPLAYEDNAME); + Draw_FunStringWidth (x+48, y, name, MAX_DISPLAYEDNAME*8); y += 8; } @@ -2973,8 +2937,8 @@ void Sbar_MiniDeathmatchOverlay (void) // draw seperator x += 208; - for (y = sbar_rect.height - sb_lines; y < sbar_rect.height - 6; y += 2) - Draw_ColouredCharacter(x, y, CON_WHITEMASK|14); +// for (y = sbar_rect.height - sb_lines; y < sbar_rect.height - 6; y += 2) +// Draw_ColouredCharacter(x, y, CON_WHITEMASK|14); x += 16; @@ -2985,15 +2949,19 @@ void Sbar_MiniDeathmatchOverlay (void) tm = teams + k; // draw pings - Draw_FunStringLen (x, y, tm->team, 4); + Draw_FunStringWidth (x, y, tm->team, 32); // draw total sprintf (num, "%5i", tm->frags); Draw_FunString(x + 40, y, num); - if (!strncmp(cl.players[cl.playernum[0]].team, tm->team, 16)) { - Draw_Character ( x - 8, y, 16); - Draw_Character ( x + 32, y, 17); + if (!strncmp(cl.players[cl.playernum[0]].team, tm->team, 16)) + { + Font_BeginString(font_conchar, x-8, y, &px, &py); + Font_DrawChar(px, py, 16|0xe000|CON_WHITEMASK); + Font_BeginString(font_conchar, x+32, y, &px, &py); + Font_DrawChar(px, py, 17|0xe000|CON_WHITEMASK); + Font_EndString(font_conchar); } y += 8; @@ -3015,27 +2983,27 @@ void Sbar_CoopIntermission (void) pic = Draw_SafeCachePic ("gfx/complete.lmp"); if (!pic) return; - Draw_Pic ((sbar_rect.width - 320)/2 + 64, (sbar_rect.height - 200)/2 + 24, pic); + Draw_ScalePic ((sbar_rect.width - 320)/2 + 64, (sbar_rect.height - 200)/2 + 24, 192, 24, pic); pic = Draw_SafeCachePic ("gfx/inter.lmp"); if (pic) - Draw_TransPic ((sbar_rect.width - 320)/2 + 0, (sbar_rect.height - 200)/2 + 56, pic); + Draw_ScalePic ((sbar_rect.width - 320)/2 + 0, (sbar_rect.height - 200)/2 + 56, 160, 144, pic); // time dig = cl.completed_time/60; Sbar_IntermissionNumber ((sbar_rect.width - 320)/2 + 160, (sbar_rect.height - 200)/2 + 64, dig, 3, 0); num = cl.completed_time - dig*60; - Draw_TransPic ((sbar_rect.width - 320)/2 + 234,(sbar_rect.height - 200)/2 + 64,sb_colon); - Draw_TransPic ((sbar_rect.width - 320)/2 + 246,(sbar_rect.height - 200)/2 + 64,sb_nums[0][num/10]); - Draw_TransPic ((sbar_rect.width - 320)/2 + 266,(sbar_rect.height - 200)/2 + 64,sb_nums[0][num%10]); + Draw_ScalePic ((sbar_rect.width - 320)/2 + 234,(sbar_rect.height - 200)/2 + 64, 16, 24, sb_colon); + Draw_ScalePic ((sbar_rect.width - 320)/2 + 246,(sbar_rect.height - 200)/2 + 64, 16, 26, sb_nums[0][num/10]); + Draw_ScalePic ((sbar_rect.width - 320)/2 + 266,(sbar_rect.height - 200)/2 + 64, 16, 24, sb_nums[0][num%10]); //it is assumed that secrits/monsters are going to be constant for any player... Sbar_IntermissionNumber ((sbar_rect.width - 320)/2 + 160, (sbar_rect.height - 200)/2 + 104, cl.stats[0][STAT_SECRETS], 3, 0); - Draw_TransPic ((sbar_rect.width - 320)/2 + 232,(sbar_rect.height - 200)/2 + 104,sb_slash); + Draw_ScalePic ((sbar_rect.width - 320)/2 + 232,(sbar_rect.height - 200)/2 + 104, 16, 24, sb_slash); Sbar_IntermissionNumber ((sbar_rect.width - 320)/2 + 240, (sbar_rect.height - 200)/2 + 104, cl.stats[0][STAT_TOTALSECRETS], 3, 0); Sbar_IntermissionNumber ((sbar_rect.width - 320)/2 + 160, (sbar_rect.height - 200)/2 + 144, cl.stats[0][STAT_MONSTERS], 3, 0); - Draw_TransPic ((sbar_rect.width - 320)/2 + 232,(sbar_rect.height - 200)/2 + 144,sb_slash); + Draw_ScalePic ((sbar_rect.width - 320)/2 + 232,(sbar_rect.height - 200)/2 + 144, 16, 24, sb_slash); Sbar_IntermissionNumber ((sbar_rect.width - 320)/2 + 240, (sbar_rect.height - 200)/2 + 144, cl.stats[0][STAT_TOTALMONSTERS], 3, 0); } /* @@ -3078,6 +3046,6 @@ void Sbar_FinaleOverlay (void) #endif pic = Draw_SafeCachePic ("gfx/finale.lmp"); if (pic) - Draw_TransPic ( (vid.width-pic->width)/2, 16, pic); + Draw_ScalePic ( (vid.width-pic->width)/2, 16, pic->width, pic->height, pic); } diff --git a/engine/client/sbar.h b/engine/client/sbar.h index af1e76ac..5342777a 100644 --- a/engine/client/sbar.h +++ b/engine/client/sbar.h @@ -28,7 +28,7 @@ extern int sb_lines; // scan lines to draw void Sbar_Init (void); struct player_info_s; qboolean Sbar_UpdateTeamStatus(struct player_info_s *player, char *status); -#ifdef RGLQUAKE +#ifdef GLQUAKE void Sbar_ReInit (void); #endif @@ -49,3 +49,6 @@ void Sbar_SortFrags (qboolean includespec); void Sbar_Start (void); void Sbar_Flush (void); unsigned int Sbar_ColorForMap (unsigned int m); + +extern int scoreboardlines; +extern int fragsort[]; diff --git a/engine/client/screen.h b/engine/client/screen.h index 1697bff5..aea799cc 100644 --- a/engine/client/screen.h +++ b/engine/client/screen.h @@ -48,7 +48,7 @@ qboolean SCR_RSShot (void); //void SCR_UpdateScreen (void); -#if defined(RGLQUAKE) +#if defined(GLQUAKE) void GLSCR_UpdateScreen (void); #endif @@ -67,6 +67,7 @@ void SCR_DrawNet (void); void SCR_DrawTurtle (void); void SCR_DrawPause (void); void SCR_VRectForPlayer(vrect_t *vrect, int pnum); //returns a region for the player's view +void SCR_DrawCursor(int prydoncursornum); void CLSCR_Init(void); //basically so I can register a few friendly cvars. @@ -93,3 +94,20 @@ enum }; int SCR_GetLoadingStage(void); void SCR_SetLoadingStage(int stage); + + +/*fonts*/ +void Font_Init(void); +void Font_Shutdown(void); +struct font_s *Font_LoadFont(int height, char *fontfilename); +void Font_Free(struct font_s *f); +void Font_BeginString(struct font_s *font, int vx, int vy, int *px, int *py); +int Font_CharHeight(void); +int Font_CharWidth(unsigned int charcode); +int Font_DrawChar(int px, int py, unsigned int charcode); +void Font_ForceColour(float r, float g, float b, float a); +void Font_EndString(struct font_s *font); +int Font_LineBreaks(conchar_t *start, conchar_t *end, int maxpixelwidth, int maxlines, conchar_t **starts, conchar_t **ends); +extern struct font_s *font_conchar; +extern struct font_s *font_tiny; +/*end fonts*/ diff --git a/engine/client/skin.c b/engine/client/skin.c index 89e022be..d18b7b96 100644 --- a/engine/client/skin.c +++ b/engine/client/skin.c @@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "quakedef.h" +#include "glquake.h" cvar_t baseskin = SCVAR("baseskin", ""); cvar_t noskins = SCVAR("noskins", "0"); @@ -222,9 +223,9 @@ qbyte *Skin_Cache8 (skin_t *skin) if (skin->failedload) return NULL; - skin->tex_base = 0; - skin->tex_lower = 0; - skin->tex_upper = 0; + skin->tex_base = r_nulltex; + skin->tex_lower = r_nulltex; + skin->tex_upper = r_nulltex; out = Cache_Check (&skin->cache); if (out) @@ -275,16 +276,16 @@ qbyte *Skin_Cache8 (skin_t *skin) { if (strcmp(skin->name, baseskin.string)) { -#if defined(RGLQUAKE) || defined(D3DQUAKE) +#if defined(GLQUAKE) || defined(D3DQUAKE) if (qrenderer == QR_OPENGL || qrenderer == QR_DIRECT3D) { - skin->tex_base = Mod_LoadReplacementTexture(skin->name, "skins", true, false, true); - if (skin->tex_base) + skin->tex_base = R_LoadReplacementTexture(skin->name, "skins", IF_NOALPHA); + if (TEXVALID(skin->tex_base)) { sprintf (name, "%s_shirt", skin->name); - skin->tex_upper = Mod_LoadReplacementTexture(name, "skins", true, true, true); + skin->tex_upper = R_LoadReplacementTexture(name, "skins", 0); sprintf (name, "%s_pants", skin->name); - skin->tex_lower = Mod_LoadReplacementTexture(name, "skins", true, true, true); + skin->tex_lower = R_LoadReplacementTexture(name, "skins", 0); skin->failedload = true; return NULL; @@ -382,7 +383,7 @@ qbyte *Skin_Cache8 (skin_t *skin) } if (dataByte >= 256-vid.fullbright) //kill the fb componant - if (!r_fb_models.value) + if (!r_fb_models.ival) dataByte = fbremap[dataByte + vid.fullbright-256]; while(runLength-- > 0) @@ -528,7 +529,7 @@ void Skin_NextDownload (void) if (!sc->name[0]) continue; Skin_Find (sc); - if (noskins.value) + if (noskins.ival) continue; if (strchr(sc->skin->name, ' ')) //skip over skins using a space @@ -550,7 +551,7 @@ void Skin_NextDownload (void) Skin_Cache32(sc->skin); else Skin_Cache8 (sc->skin); -#ifdef RGLQUAKE +#ifdef GLQUAKE sc->skin = NULL; #endif } diff --git a/engine/client/snd_directx.c b/engine/client/snd_directx.c index 3d8ac9ca..85984dea 100644 --- a/engine/client/snd_directx.c +++ b/engine/client/snd_directx.c @@ -22,6 +22,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include +#ifdef _MSC_VER +#pragma comment(lib, MSVCLIBSPATH "dxsdk7/lib/dxguid.lib") +#endif + #define SND_ERROR 0 #define SND_LOADED 1 #define SND_NOMORE 2 //like error, but doesn't try the next card. @@ -594,7 +598,7 @@ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum) dsndcard="DirectSound"; if (pDirectSoundEnumerate) pDirectSoundEnumerate(&DSEnumCallback, NULL); - if (!snd_usemultipledevices.value) //if only one device, ALWAYS use the default. + if (!snd_usemultipledevices.ival) //if only one device, ALWAYS use the default. dsndguid=NULL; aimedforguid++; @@ -609,7 +613,7 @@ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum) #ifndef MINIMAL #ifdef _IKsPropertySet_ dh->pDS = NULL; - if (snd_eax.value) + if (snd_eax.ival) { CoInitialize(NULL); if (FAILED(CoCreateInstance( &CLSID_EAXDirectSound, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound, (void **)&dh->pDS ))) @@ -676,7 +680,7 @@ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum) dsbuf.lpwfxFormat = NULL; #ifdef DSBCAPS_GLOBALFOCUS - if (snd_inactive.value) + if (snd_inactive.ival) { dsbuf.dwFlags |= DSBCAPS_GLOBALFOCUS; sc->inactive_sound = true; @@ -715,7 +719,7 @@ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum) dsbuf.dwSize = sizeof(DSBUFFERDESC); dsbuf.dwFlags = DSBCAPS_CTRLFREQUENCY|DSBCAPS_LOCSOFTWARE; //dmw 29 may, 2003 removed locsoftware #ifdef DSBCAPS_GLOBALFOCUS - if (snd_inactive.value) + if (snd_inactive.ival) { dsbuf.dwFlags |= DSBCAPS_GLOBALFOCUS; sc->inactive_sound = true; @@ -836,7 +840,7 @@ int DSOUND_InitCard (soundcardinfo_t *sc, int cardnum) #ifdef _IKsPropertySet_ //attempt at eax support - if (snd_eax.value) + if (snd_eax.ival) { int r; DWORD support; @@ -982,7 +986,7 @@ void DSOUND_UpdateCapture(void) // return; - if (!snd_capture.value) + if (!snd_capture.ival) { if (DSCaptureBuffer) { diff --git a/engine/client/snd_dma.c b/engine/client/snd_dma.c index 09a1eded..0b29affd 100644 --- a/engine/client/snd_dma.c +++ b/engine/client/snd_dma.c @@ -129,7 +129,6 @@ void S_SoundInfo_f(void) Con_Printf("%5d samplepos\n", sc->sn.samplepos); Con_Printf("%5d samplebits\n", sc->sn.samplebits); Con_Printf("%5d speed\n", sc->sn.speed); - Con_Printf("0x%x dma buffer\n", sc->sn.buffer); Con_Printf("%5d total_channels\n", sc->total_chans); } } @@ -178,42 +177,42 @@ static int SNDDMA_Init(soundcardinfo_t *sc, int *cardnum, int *drivernum) memset(sc, 0, sizeof(*sc)); // set requested rate - if (!snd_khz.value) + if (!snd_khz.ival) sc->sn.speed = 22050; -/* else if (snd_khz.value >= 195) +/* else if (snd_khz.ival >= 195) sc->sn.speed = 200000; - else if (snd_khz.value >= 180) + else if (snd_khz.ival >= 180) sc->sn.speed = 192000; - else if (snd_khz.value >= 90) + else if (snd_khz.ival >= 90) sc->sn.speed = 96000; */ - else if (snd_khz.value >= 45) + else if (snd_khz.ival >= 45) sc->sn.speed = 48000; - else if (snd_khz.value >= 30) + else if (snd_khz.ival >= 30) sc->sn.speed = 44100; - else if (snd_khz.value >= 20) + else if (snd_khz.ival >= 20) sc->sn.speed = 22050; - else if (snd_khz.value >= 10) + else if (snd_khz.ival >= 10) sc->sn.speed = 11025; else sc->sn.speed = 8000; // set requested speaker count - if (snd_speakers.value > MAXSOUNDCHANNELS) + if (snd_speakers.ival > MAXSOUNDCHANNELS) sc->sn.numchannels = MAXSOUNDCHANNELS; - else if (snd_speakers.value > 1) - sc->sn.numchannels = (int)snd_speakers.value; + else if (snd_speakers.ival > 1) + sc->sn.numchannels = (int)snd_speakers.ival; else sc->sn.numchannels = 1; // set requested sample bits - if (snd_samplebits.value >= 16) + if (snd_samplebits.ival >= 16) sc->sn.samplebits = 16; else sc->sn.samplebits = 8; // set requested buffer size - if (snd_buffersize.value > 0) - sc->sn.samples = (int)snd_buffersize.value * sc->sn.numchannels; + if (snd_buffersize.ival > 0) + sc->sn.samples = snd_buffersize.ival * sc->sn.numchannels; else sc->sn.samples = 0; @@ -362,7 +361,7 @@ void S_Startup (void) sc->next = sndcardinfo; sndcardinfo = sc; - if (!snd_usemultipledevices.value) + if (!snd_usemultipledevices.ival) break; } @@ -383,7 +382,7 @@ void SNDDMA_SetUnderWater(qboolean underwater) //so that the video code can call it directly without flushing the models it's just loaded. void S_DoRestart (void) { - if (nosound.value) + if (nosound.ival) return; S_StopAllSounds (true); @@ -427,13 +426,13 @@ void S_Control_f (void) { if (!Q_strcasecmp(Cmd_Argv (2), "off")) { - if (snd_usemultipledevices.value) + if (snd_usemultipledevices.ival) { Cvar_SetValue(&snd_usemultipledevices, 0); S_Restart_f(); } } - else if (!snd_usemultipledevices.value) + else if (!snd_usemultipledevices.ival) { Cvar_SetValue(&snd_usemultipledevices, 1); S_Restart_f(); @@ -752,13 +751,13 @@ sfx_t *S_PrecacheSound (char *name) { sfx_t *sfx; - if (nosound.value) + if (nosound.ival) return NULL; sfx = S_FindName (name); // cache it in - if (precache.value &&sndcardinfo) + if (precache.ival && sndcardinfo) S_LoadSound (sfx); return sfx; @@ -848,6 +847,9 @@ void SND_Spatialize(soundcardinfo_t *sc, channel_t *ch) dotforward = DotProduct(listener_forward, source_vec); dotup = DotProduct(listener_up, source_vec); + if (snd_leftisright.ival) + dotright = -dotright; + for (i = 0; i < sc->sn.numchannels; i++) { scale = 1 + (dotright*sin(sc->yaw[i]*M_PI/180) + dotforward*cos(sc->yaw[i]*M_PI/180));// - dotup*cos(sc->pitch[0])*2; @@ -878,7 +880,7 @@ void S_StartSoundCard(soundcardinfo_t *sc, int entnum, int entchannel, sfx_t *sf if (!sfx) return; - if (nosound.value) + if (nosound.ival) return; vol = fvol*255; @@ -915,7 +917,7 @@ void S_StartSoundCard(soundcardinfo_t *sc, int entnum, int entchannel, sfx_t *sf return; // couldn't load the sound's data } - if (scache->length > snd_speed*20 && !ruleset_allow_overlongsounds.value) + if (scache->length > snd_speed*20 && !ruleset_allow_overlongsounds.ival) { Con_DPrintf("Shortening over-long sound effect\n"); startpos = scache->length - snd_speed*10; @@ -1366,7 +1368,7 @@ void S_UpdateCard(soundcardinfo_t *sc) // // debugging output // - if (snd_show.value) + if (snd_show.ival) { total = 0; ch = sc->channel; @@ -1422,7 +1424,7 @@ void S_ExtraUpdate (void) IN_Accumulate (); #endif - if (snd_noextraupdate.value) + if (snd_noextraupdate.ival) return; // don't pollute timings S_RunCapture(); @@ -1560,7 +1562,7 @@ void S_LocalSound (char *sound) { sfx_t *sfx; - if (nosound.value) + if (nosound.ival) return; if (!sound_started) return; @@ -1718,7 +1720,7 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels, if (prepadl == 0x7fffffff) { - if (snd_show.value) + if (snd_show.ival) Con_Printf("Wasn't playing\n"); prepadl = 0; spare = s->sfxcache->length; @@ -1762,7 +1764,7 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels, snd_speed, s->sfxcache->width, s->sfxcache->numchannels, - (int)snd_linearresample_stream.value); + snd_linearresample_stream.ival); } s->sfxcache->loopstart = s->sfxcache->length; diff --git a/engine/client/snd_mem.c b/engine/client/snd_mem.c index 965404bb..fac2e33e 100644 --- a/engine/client/snd_mem.c +++ b/engine/client/snd_mem.c @@ -561,7 +561,7 @@ void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, qbyte *data) sc->loopstart = sc->loopstart * scale; sc->speed = snd_speed; - if (loadas8bit.value) + if (loadas8bit.ival) sc->width = 1; else sc->width = inwidth; @@ -575,7 +575,7 @@ void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, qbyte *data) sc->speed, sc->width, sc->numchannels, - (int)snd_linearresample.value); + snd_linearresample.ival); } //============================================================================= diff --git a/engine/client/snd_mp3.c b/engine/client/snd_mp3.c index 2cf29161..87fd121d 100644 --- a/engine/client/snd_mp3.c +++ b/engine/client/snd_mp3.c @@ -51,11 +51,6 @@ #define USE_MADLIB #include "mymad.c" -#ifdef _MSC_VER -#pragma comment (lib, "../libs/libmad/msvc++/release/libmad.lib") -#endif - - /* * This is perhaps the simplest example use of the MAD high-level API. * Standard input is mapped into memory via mmap(), then the high-level API diff --git a/engine/client/snd_ov.c b/engine/client/snd_ov.c index 327103e6..99092c06 100644 --- a/engine/client/snd_ov.c +++ b/engine/client/snd_ov.c @@ -209,7 +209,7 @@ int OV_DecodeSome(sfx_t *s, int minlength) snd_speed, 2, dec->mediasc.numchannels, - (int)snd_linearresample_stream.value); + snd_linearresample_stream.ival); bytesread = (int)floor(bytesread / scale) & ~0x1; } @@ -255,7 +255,7 @@ void OV_CancelDecoder(sfx_t *s) //and it's now indistinguisable from a wav } -static size_t read_func (void *ptr, size_t size, size_t nmemb, void *datasource) +static size_t VARGS read_func (void *ptr, size_t size, size_t nmemb, void *datasource) { ovdecoderbuffer_t *buffer = datasource; int spare = buffer->length - buffer->pos; @@ -267,7 +267,7 @@ static size_t read_func (void *ptr, size_t size, size_t nmemb, void *datasource) return nmemb; } -static int seek_func (void *datasource, ogg_int64_t offset, int whence) +static int VARGS seek_func (void *datasource, ogg_int64_t offset, int whence) { ovdecoderbuffer_t *buffer = datasource; switch(whence) @@ -285,7 +285,7 @@ static int seek_func (void *datasource, ogg_int64_t offset, int whence) return 0; } -static int close_func (void *datasource) +static int VARGS close_func (void *datasource) { ovdecoderbuffer_t *buffer = datasource; BZ_Free(buffer->start); @@ -293,7 +293,7 @@ static int close_func (void *datasource) return 0; } -static long tell_func (void *datasource) +static long VARGS tell_func (void *datasource) { ovdecoderbuffer_t *buffer = datasource; return buffer->pos; diff --git a/engine/client/sound.h b/engine/client/sound.h index 04b26895..02b35c87 100644 --- a/engine/client/sound.h +++ b/engine/client/sound.h @@ -115,6 +115,7 @@ void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation); void S_StopSound (int entnum, int entchannel); void S_StopAllSounds(qboolean clear); void S_UpdateListener(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up, qboolean dontmix); +void S_GetListenerInfo(float *origin, float *forward, float *right, float *up); void S_ExtraUpdate (void); qboolean S_HaveOutput(void); diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index 26bb4951..1a928d8d 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // sys_win.h #include "quakedef.h" + #include "winquake.h" #include "resource.h" #include "errno.h" @@ -33,6 +34,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #endif +#ifdef _DEBUG +#define CATCHCRASH +#endif + #if !defined(CLIENTONLY) && !defined(SERVERONLY) qboolean isDedicated = false; #endif @@ -45,7 +50,7 @@ void Sys_CloseLibrary(dllhandle_t *lib) { FreeLibrary((HMODULE)lib); } -dllhandle_t *Sys_LoadLibrary(char *name, dllfunction_t *funcs) +dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs) { int i; HMODULE lib; @@ -72,7 +77,7 @@ dllhandle_t *Sys_LoadLibrary(char *name, dllfunction_t *funcs) return (dllhandle_t*)lib; } -void *Sys_GetAddressForName(dllhandle_t *module, char *exportname) +void *Sys_GetAddressForName(dllhandle_t *module, const char *exportname) { if (!module) return NULL; @@ -310,6 +315,80 @@ int VARGS Sys_DebugLog(char *file, char *fmt, ...) return 1; }; +#ifdef CATCHCRASH +#include "dbghelp.h" +typedef BOOL (WINAPI *MINIDUMPWRITEDUMP) ( + HANDLE hProcess, + DWORD ProcessId, + HANDLE hFile, + MINIDUMP_TYPE DumpType, + PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, + PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, + PMINIDUMP_CALLBACK_INFORMATION CallbackParam + ); + +static DWORD CrashExceptionHandler (DWORD exceptionCode, LPEXCEPTION_POINTERS exceptionInfo) +{ + char dumpPath[1024]; + HANDLE hProc = GetCurrentProcess(); + DWORD procid = GetCurrentProcessId(); + HANDLE dumpfile; + HMODULE hDbgHelp; + MINIDUMPWRITEDUMP fnMiniDumpWriteDump; + HMODULE hKernel; + BOOL (WINAPI *pIsDebuggerPresent)(void); + + hKernel = LoadLibrary ("kernel32"); + pIsDebuggerPresent = (void*)GetProcAddress(hKernel, "IsDebuggerPresent"); + +#ifdef GLQUAKE + GLVID_Crashed(); +#endif + + if (pIsDebuggerPresent ()) + { + /*if we have a current window, minimize it to bring us out of fullscreen*/ + ShowWindow(mainwindow, SW_MINIMIZE); + return EXCEPTION_CONTINUE_SEARCH; + } + + /*if we have a current window, kill it, so it can't steal input of handle window messages or anything risky like that*/ + DestroyWindow(mainwindow); + + hDbgHelp = LoadLibrary ("DBGHELP"); + if (hDbgHelp) + fnMiniDumpWriteDump = (MINIDUMPWRITEDUMP)GetProcAddress (hDbgHelp, "MiniDumpWriteDump"); + else + fnMiniDumpWriteDump = NULL; + + if (fnMiniDumpWriteDump) + { + if (MessageBox(NULL, "KABOOM! We crashed!\nBlame the monkey in the corner.\nI hope you saved your work.\nWould you like to take a dump now?", DISTRIBUTION " Sucks", MB_ICONSTOP|MB_YESNO) != IDYES) + return EXCEPTION_EXECUTE_HANDLER; + + /*take a dump*/ + GetTempPath (sizeof(dumpPath)-16, dumpPath); + Q_strncatz(dumpPath, DISTRIBUTION"CrashDump.dmp", sizeof(dumpPath)); + dumpfile = CreateFile (dumpPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (dumpfile) + { + MINIDUMP_EXCEPTION_INFORMATION crashinfo; + crashinfo.ClientPointers = TRUE; + crashinfo.ExceptionPointers = exceptionInfo; + crashinfo.ThreadId = GetCurrentThreadId (); + if (fnMiniDumpWriteDump(hProc, procid, dumpfile, MiniDumpWithIndirectlyReferencedMemory|MiniDumpWithDataSegs, &crashinfo, NULL, NULL)) + { + CloseHandle(dumpfile); + MessageBox(NULL, va("You can find the crashdump at\n%s\nPlease send this file to someone.\n\nWarning: sensitive information (like your current user name) might be present in the dump.\nYou will probably want to compress it.", dumpPath), DISTRIBUTION " Sucks", 0); + return EXCEPTION_EXECUTE_HANDLER; + } + } + } + MessageBox(NULL, "Kaboom! Sorry. Blame the nubs.", DISTRIBUTION " Sucks", 0); + return EXCEPTION_EXECUTE_HANDLER; +} +#endif + int *debug; @@ -364,7 +443,7 @@ LRESULT CALLBACK LowLevelKeyboardProc (INT nCode, WPARAM wParam, LPARAM lParam) // Disable CTRL+ESC //this works, but we've got to give some way to tab out... - if (sys_disableTaskSwitch.value) + if (sys_disableTaskSwitch.ival) { if (pkbhs->vkCode == VK_ESCAPE && GetAsyncKeyState (VK_CONTROL) >> ((sizeof(SHORT) * 8) - 1)) return 1; @@ -408,54 +487,6 @@ FILE IO =============================================================================== */ -/* -================ -Sys_filelength -================ -*/ -int Sys_filelength (FILE *f) -{ - int pos; - int end; - - pos = ftell (f); - fseek (f, 0, SEEK_END); - end = ftell (f); - fseek (f, pos, SEEK_SET); - - return end; -} - - -int Sys_FileTime (char *path) -{ - FILE *f; - int t=0, retval; - -#ifndef SERVERONLY - if (qrenderer) - t = VID_ForceUnlockedAndReturnState (); -#endif - - f = fopen(path, "rb"); - - if (f) - { - fclose(f); - retval = 1; - } - else - { - retval = -1; - } - -#ifndef SERVERONLY - if (qrenderer) - VID_ForceLockState (t); -#endif - return retval; -} - void Sys_mkdir (char *path) { _mkdir (path); @@ -735,7 +766,7 @@ void Sys_Quit (void) } -#if 0 +#if 1 /* ================ Sys_DoubleTime @@ -743,91 +774,32 @@ Sys_DoubleTime */ double Sys_DoubleTime (void) { - static int sametimecount; - static unsigned int oldtime; static int first = 1; + static LARGE_INTEGER qpcfreq; LARGE_INTEGER PerformanceCount; - unsigned int temp, t2; - double time; - - Sys_PushFPCW_SetHigh (); + static LONGLONG oldcall; + static LONGLONG firsttime; + LONGLONG diff; QueryPerformanceCounter (&PerformanceCount); - - temp = ((unsigned int)PerformanceCount.LowPart >> lowshift) | - ((unsigned int)PerformanceCount.HighPart << (32 - lowshift)); - if (first) { - oldtime = temp; first = 0; + QueryPerformanceFrequency(&qpcfreq); + firsttime = PerformanceCount.QuadPart; + diff = 0; } else - { - // check for turnover or backward time - if ((temp <= oldtime) && ((oldtime - temp) < 0x10000000)) - { - oldtime = temp; // so we can't get stuck - } - else - { - t2 = temp - oldtime; - - time = (double)t2 * pfreq; - oldtime = temp; - - curtime += time; - - if (curtime == lastcurtime) - { - sametimecount++; - - if (sametimecount > 100000) - { - curtime += 1.0; - sametimecount = 0; - } - } - else - { - sametimecount = 0; - } - - lastcurtime = curtime; - } - } - - Sys_PopFPCW (); - - return curtime; + diff = PerformanceCount.QuadPart - oldcall; + if (diff >= 0) + oldcall = PerformanceCount.QuadPart; + return (oldcall - firsttime) / (double)qpcfreq.QuadPart; } - -/* -================ -Sys_InitFloatTime -================ -*/ -void Sys_InitFloatTime (void) +unsigned int Sys_Milliseconds (void) { - int j; - - Sys_DoubleTime (); - - j = COM_CheckParm("-starttime"); - - if (j) - { - curtime = (double) (Q_atof(com_argv[j+1])); - } - else - { - curtime = 0.0; - } - - lastcurtime = curtime; + return Sys_DoubleTime()*1000; } - -#endif +#else unsigned int Sys_Milliseconds (void) { static DWORD starttime; @@ -861,7 +833,7 @@ double Sys_DoubleTime (void) { return Sys_Milliseconds()/1000.f; } - +#endif @@ -1248,7 +1220,7 @@ void NPQTV_Sys_MainLoop(void) Host_Frame (duratrion); lastlooptime = newtime; - SetHookState(sys_disableWinKeys.value); + SetHookState(sys_disableWinKeys.ival); // Sleep(0); #else @@ -1296,229 +1268,279 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin quakeparms_t parms; double time, oldtime, newtime; char cwd[1024]; - RECT rect; const char *qtvfile = NULL; /* previous instances do not exist in Win32 */ if (hPrevInstance) return 0; + +#ifdef _MSC_VER +#if _M_IX86_FP >= 1 + { + int idedx; + char cpuname[13]; + /*I'm not going to check to make sure cpuid works.*/ + __asm + { + xor eax, eax + cpuid + mov dword ptr [cpuname+0],ebx + mov dword ptr [cpuname+4],edx + mov dword ptr [cpuname+8],ecx + } + cpuname[12] = 0; + __asm + { + mov eax, 0x1 + cpuid + mov idedx, edx + } +// MessageBox(NULL, cpuname, cpuname, 0); +#if _M_IX86_FP >= 2 + if (!(idedx&(1<<26))) + MessageBox(NULL, "This is an SSE2 optimised build, and your cpu doesn't seem to support it", DISTRIBUTION, 0); + else +#endif + if (!(idedx&(1<<25))) + MessageBox(NULL, "This is an SSE optimised build, and your cpu doesn't seem to support it", DISTRIBUTION, 0); + } +#endif +#endif + +#ifdef CATCHCRASH + __try +#endif + { /* #ifndef _DEBUG #ifdef _MSC_VER - signal (SIGFPE, Signal_Error_Handler); - signal (SIGILL, Signal_Error_Handler); - signal (SIGSEGV, Signal_Error_Handler); + signal (SIGFPE, Signal_Error_Handler); + signal (SIGILL, Signal_Error_Handler); + signal (SIGSEGV, Signal_Error_Handler); #endif #endif */ - global_hInstance = hInstance; - global_nCmdShow = nCmdShow; + global_hInstance = hInstance; + global_nCmdShow = nCmdShow; - parms.argc = 1; - argv[0] = exename; + parms.argc = 1; + argv[0] = exename; - while (*lpCmdLine && (parms.argc < MAX_NUM_ARGVS)) - { - while (*lpCmdLine && ((*lpCmdLine <= 32) || (*lpCmdLine > 126))) - lpCmdLine++; - - if (*lpCmdLine) + while (*lpCmdLine && (parms.argc < MAX_NUM_ARGVS)) { - if (*lpCmdLine == '\"') - { + while (*lpCmdLine && ((*lpCmdLine <= 32) || (*lpCmdLine > 126))) lpCmdLine++; - argv[parms.argc] = lpCmdLine; - parms.argc++; - - while (*lpCmdLine && *lpCmdLine != '\"') - lpCmdLine++; - } - else - { - argv[parms.argc] = lpCmdLine; - parms.argc++; - - - while (*lpCmdLine && ((*lpCmdLine > 32) && (*lpCmdLine <= 126))) - lpCmdLine++; - } - if (*lpCmdLine) { - *lpCmdLine = 0; - lpCmdLine++; + if (*lpCmdLine == '\"') + { + lpCmdLine++; + + argv[parms.argc] = lpCmdLine; + parms.argc++; + + while (*lpCmdLine && *lpCmdLine != '\"') + lpCmdLine++; + } + else + { + argv[parms.argc] = lpCmdLine; + parms.argc++; + + + while (*lpCmdLine && ((*lpCmdLine > 32) && (*lpCmdLine <= 126))) + lpCmdLine++; + } + + if (*lpCmdLine) + { + *lpCmdLine = 0; + lpCmdLine++; + } } } - } - GetModuleFileName(NULL, cwd, sizeof(cwd)-1); - strcpy(exename, COM_SkipPath(cwd)); - parms.argv = argv; + GetModuleFileName(NULL, cwd, sizeof(cwd)-1); + strcpy(exename, COM_SkipPath(cwd)); + parms.argv = argv; - COM_InitArgv (parms.argc, parms.argv); + COM_InitArgv (parms.argc, parms.argv); - if (COM_CheckParm("--version") || COM_CheckParm("-v")) - { - printf("version " DISTRIBUTION " " __TIME__ __DATE__ "\n"); - return true; - } - - if (!GetCurrentDirectory (sizeof(cwd), cwd)) - Sys_Error ("Couldn't determine current directory"); - if (parms.argc >= 2) - { - if (*parms.argv[1] != '-' && *parms.argv[1] != '+') + if (COM_CheckParm("--version") || COM_CheckParm("-v")) { - char *e; + printf("version " DISTRIBUTION " " __TIME__ __DATE__ "\n"); + return true; + } - qtvfile = parms.argv[1]; - - - GetModuleFileName(NULL, cwd, sizeof(cwd)-1); - for (e = cwd+strlen(cwd)-1; e >= cwd; e--) + if (!GetCurrentDirectory (sizeof(cwd), cwd)) + Sys_Error ("Couldn't determine current directory"); + if (parms.argc >= 2) + { + if (*parms.argv[1] != '-' && *parms.argv[1] != '+') { - if (*e == '/' || *e == '\\') + char *e; + + qtvfile = parms.argv[1]; + + GetModuleFileName(NULL, cwd, sizeof(cwd)-1); + for (e = cwd+strlen(cwd)-1; e >= cwd; e--) { - *e = 0; - break; + if (*e == '/' || *e == '\\') + { + *e = 0; + break; + } + } + + } + } + + TL_InitLanguages(); + //tprints are now allowed + + parms.basedir = cwd; + + parms.argc = com_argc; + parms.argv = com_argv; + + #if !defined(CLIENTONLY) && !defined(SERVERONLY) + if (COM_CheckParm ("-dedicated")) + isDedicated = true; + #endif + + if (isDedicated) + { + #if !defined(CLIENTONLY) + hwnd_dialog=NULL; + + if (!Sys_InitTerminal()) + Sys_Error ("Couldn't allocate dedicated server console"); + #endif + } + #ifdef IDD_DIALOG1 + else + hwnd_dialog = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, NULL); + + if (hwnd_dialog) + { + RECT rect; + if (GetWindowRect (hwnd_dialog, &rect)) + { + if (rect.left > (rect.top * 2)) + { + SetWindowPos (hwnd_dialog, 0, + (rect.left / 2) - ((rect.right - rect.left) / 2), + rect.top, 0, 0, + SWP_NOZORDER | SWP_NOSIZE); } } + ShowWindow (hwnd_dialog, SW_SHOWDEFAULT); + UpdateWindow (hwnd_dialog); + SetForegroundWindow (hwnd_dialog); } - } + #endif - TL_InitLanguages(); - //tprints are now allowed + if (!Sys_Startup_CheckMem(&parms)) + Sys_Error ("Not enough memory free; check disk space\n"); - parms.basedir = cwd; - parms.argc = com_argc; - parms.argv = com_argv; - -#if !defined(CLIENTONLY) && !defined(SERVERONLY) - if (COM_CheckParm ("-dedicated")) - isDedicated = true; -#endif - - if (isDedicated) - { -#if !defined(CLIENTONLY) - hwnd_dialog=NULL; - - if (!Sys_InitTerminal()) - Sys_Error ("Couldn't allocate dedicated server console"); -#endif - } - else - hwnd_dialog = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, NULL); - - if (hwnd_dialog) - { - if (GetWindowRect (hwnd_dialog, &rect)) + #ifndef CLIENTONLY + if (isDedicated) //compleate denial to switch to anything else - many of the client structures are not initialized. { - if (rect.left > (rect.top * 2)) + SV_Init (&parms); + + SV_Frame (); + + while (1) { - SetWindowPos (hwnd_dialog, 0, - (rect.left / 2) - ((rect.right - rect.left) / 2), - rect.top, 0, 0, - SWP_NOZORDER | SWP_NOSIZE); + if (!isDedicated) + Sys_Error("Dedicated was cleared"); + NET_Sleep(100, false); + SV_Frame (); } + return TRUE; + } + #endif + + tevent = CreateEvent(NULL, FALSE, FALSE, NULL); + if (!tevent) + Sys_Error ("Couldn't create event"); + + #ifdef SERVERONLY + Sys_Printf ("SV_Init\n"); + SV_Init(&parms); + #else + Sys_Printf ("Host_Init\n"); + Host_Init (&parms); + #endif + + oldtime = Sys_DoubleTime (); + + if (qtvfile) + { + char *ext = COM_FileExtension(qtvfile); + if (!strcmp(ext, "qwd") || !strcmp(ext, "dem") || !strcmp(ext, "mvd")) + Cbuf_AddText(va("playdemo \"#%s\"\n", qtvfile), RESTRICT_LOCAL); + else + Cbuf_AddText(va("qtvplay \"#%s\"\n", qtvfile), RESTRICT_LOCAL); } - ShowWindow (hwnd_dialog, SW_SHOWDEFAULT); - UpdateWindow (hwnd_dialog); - SetForegroundWindow (hwnd_dialog); - } - - - if (!Sys_Startup_CheckMem(&parms)) - Sys_Error ("Not enough memory free; check disk space\n"); - - -#ifndef CLIENTONLY - if (isDedicated) //compleate denial to switch to anything else - many of the client structures are not initialized. - { - SV_Init (&parms); - - SV_Frame (); + //client console should now be initialized. + /* main window message loop */ while (1) { - if (!isDedicated) - Sys_Error("Dedicated was cleared"); - NET_Sleep(100, false); - SV_Frame (); + if (isDedicated) + { + #ifndef CLIENTONLY + NET_Sleep(50, false); + + // find time passed since last cycle + newtime = Sys_DoubleTime (); + time = newtime - oldtime; + oldtime = newtime; + + SV_Frame (); + #else + Sys_Error("wut?"); + #endif + } + else + { + #ifndef SERVERONLY + // yield the CPU for a little while when paused, minimized, or not the focus + /* if (cl.paused && !Media_PlayingFullScreen()) + { + SleepUntilInput (PAUSE_SLEEP); + scr_skipupdate = 1; // no point in bothering to draw + } + else if (!ActiveApp && !Media_PlayingFullScreen()) + { + SleepUntilInput (NOT_FOCUS_SLEEP); + } + */ + newtime = Sys_DoubleTime (); + time = newtime - oldtime; + Host_Frame (time); + oldtime = newtime; + + SetHookState(sys_disableWinKeys.ival); + + // Sleep(0); + #else + Sys_Error("wut?"); + #endif + } } - return TRUE; } -#endif - - tevent = CreateEvent(NULL, FALSE, FALSE, NULL); - if (!tevent) - Sys_Error ("Couldn't create event"); - -#ifdef SERVERONLY - Sys_Printf ("SV_Init\n"); - SV_Init(&parms); -#else - Sys_Printf ("Host_Init\n"); - Host_Init (&parms); -#endif - - oldtime = Sys_DoubleTime (); - - - if (qtvfile) - Cbuf_AddText(va("qtvplay \"#%s\"\n", qtvfile), RESTRICT_LOCAL); - -//client console should now be initialized. - - /* main window message loop */ - while (1) +#ifdef CATCHCRASH + __except (CrashExceptionHandler(GetExceptionCode(), GetExceptionInformation())) { - if (isDedicated) - { -#ifndef CLIENTONLY - NET_Sleep(50, false); - - // find time passed since last cycle - newtime = Sys_DoubleTime (); - time = newtime - oldtime; - oldtime = newtime; - - SV_Frame (); -#else - Sys_Error("wut?"); -#endif - } - else - { -#ifndef SERVERONLY - // yield the CPU for a little while when paused, minimized, or not the focus - if (cl.paused && !Media_PlayingFullScreen()) - { - SleepUntilInput (PAUSE_SLEEP); - scr_skipupdate = 1; // no point in bothering to draw - } - else if (!ActiveApp && !Media_PlayingFullScreen()) - { - SleepUntilInput (NOT_FOCUS_SLEEP); - } - - newtime = Sys_DoubleTime (); - time = newtime - oldtime; - Host_Frame (time); - oldtime = newtime; - - SetHookState(sys_disableWinKeys.value); - -// Sleep(0); -#else - Sys_Error("wut?"); -#endif - } + return 1; } +#endif /* return success of application */ return TRUE; diff --git a/engine/client/textedit.c b/engine/client/textedit.c index 0fa8a0bf..25967a39 100644 --- a/engine/client/textedit.c +++ b/engine/client/textedit.c @@ -204,7 +204,7 @@ qboolean EditorSaveFile(char *s) //returns true if succesful { memcpy(data + pos, b->data, b->datalength); pos += b->datalength; - if (editaddcr.value) + if (editaddcr.ival) { data[pos]='\r'; pos++; @@ -294,7 +294,7 @@ void EditorOpenFile(char *name) pos+=len; pos++; //and a \n - if (editstripcr.value) + if (editstripcr.ival) { if (line[len-1] == '\r') len--; @@ -739,6 +739,8 @@ void Editor_Key(int key, int unicode) void Draw_CursorLine(int ox, int y, fileblock_t *b) { +#pragma message("Fixme: ") +/* int x=0; qbyte *d = b->data; int cx; @@ -791,10 +793,13 @@ void Draw_CursorLine(int ox, int y, fileblock_t *b) } if (a == cx) Draw_ColouredCharacter (x+ox, y, 11|CON_WHITEMASK); +*/ } void Draw_NonCursorLine(int x, int y, fileblock_t *b) { +#pragma message("Fixme: ") +/* int nx = 0; qbyte *d = b->data; int i; @@ -831,6 +836,7 @@ void Draw_NonCursorLine(int x, int y, fileblock_t *b) d++; nx += 8; } +*/ } fileblock_t *firstline(void) @@ -863,7 +869,7 @@ void Editor_Draw(void) key_dest = key_editor; if ((editoractive && cls.state == ca_disconnected) || editormodal) - Draw_EditorBackground (vid.height); + Draw_EditorBackground(); if (cursorlinenum < 0) //look for the cursor line num { @@ -905,10 +911,10 @@ void Editor_Draw(void) x = 0; if (madechanges) - Draw_Character (vid.width - 8, 0, '!'|CON_HIGHCHARSMASK); + Draw_FunString (vid.width - 8, 0, "!"); if (!insertkeyhit) - Draw_Character (vid.width - 16, 0, 'O'|CON_HIGHCHARSMASK); - Draw_String(0, 0, va("%6i:%4i:%s", cursorlinenum, cursorx+1, OpenEditorFile)); + Draw_FunString (vid.width - 16, 0, "O"); + Draw_FunString(0, 0, va("%6i:%4i:%s", cursorlinenum, cursorx+1, OpenEditorFile)); if (useeval) { @@ -917,7 +923,7 @@ void Editor_Draw(void) else { char *eq; - Draw_String(0, 8, evalstring); + Draw_FunString(0, 8, evalstring); eq = strchr(evalstring, '='); if (eq) @@ -930,7 +936,7 @@ void Editor_Draw(void) else *eq = '\0'; } - Draw_String(vid.width/2, 8, editprogfuncs->EvaluateDebugString(editprogfuncs, evalstring)); + Draw_FunString(vid.width/2, 8, editprogfuncs->EvaluateDebugString(editprogfuncs, evalstring)); if (eq) *eq = '='; } @@ -976,7 +982,7 @@ void Editor_Draw(void) int QCLibEditor(progfuncs_t *prfncs, char *filename, int line, int nump, char **parms) { - if (editormodal || !developer.value) + if (editormodal || !developer.ival) return line; //whoops if (!qrenderer) diff --git a/engine/client/valid.c b/engine/client/valid.c index a2fc878d..ba4a945e 100644 --- a/engine/client/valid.c +++ b/engine/client/valid.c @@ -72,23 +72,20 @@ static void Validation_Version(void) switch(qrenderer) { -#ifdef RGLQUAKE +#ifdef GLQUAKE case QR_OPENGL: s = sr; //print certain allowed 'cheat' options. //realtime lighting (shadows can show around corners) //drawflat is just lame //24bits can be considered eeeevil, by some. - if (r_shadows.value) - { - if (r_shadow_realtime_world.value) - *s++ = 'W'; - else - *s++ = 'S'; - } - if (r_drawflat.value) + if (r_shadow_realtime_world.ival) + *s++ = 'W'; + else if (r_shadow_realtime_dlight.ival) + *s++ = 'S'; + if (r_drawflat.ival) *s++ = 'F'; - if (gl_load24bit.value) + if (gl_load24bit.ival) *s++ = 'H'; *s = *""; @@ -101,7 +98,7 @@ static void Validation_Version(void) *s = '\0'; - if (!allow_f_version.value) + if (!allow_f_version.ival) return; //suppress it if (Security_Generate_Crc) @@ -133,7 +130,7 @@ void Validation_CheckIfResponse(char *text) if (!Security_Verify_Response) return; //valid or not, we can't check it. - if (!auth_validateclients.value) + if (!auth_validateclients.ival) return; //do the parsing. @@ -274,7 +271,7 @@ void Validation_IncludeFile(char *filename, char *file, int filelen) static void Validation_FilesModified (void) { - Con_Printf ("Not implemented\n", RESTRICT_RCON); + Con_Printf ("Not implemented\n"); } void Validation_FlushFileList(void) @@ -299,7 +296,7 @@ static void Validation_Server(void) #ifndef _MSC_VER #warning is allowing the user to turn this off practical?.. #endif - if (!allow_f_server.value) + if (!allow_f_server.ival) return; Cbuf_AddText(va("say server is %s\n", NET_AdrToString(adr, sizeof(adr), cls.netchan.remote_address)), RESTRICT_LOCAL); } @@ -309,7 +306,7 @@ static void Validation_Skins(void) extern cvar_t r_fullbrightSkins, r_fb_models; int percent = r_fullbrightSkins.value*100; - if (!allow_f_skins.value) + if (!allow_f_skins.ival) return; RulesetLatch(&r_fb_models); @@ -321,7 +318,7 @@ static void Validation_Skins(void) percent = cls.allow_fbskins*100; if (percent) Cbuf_AddText(va("say all player skins %i%% fullbright%s\n", percent, r_fb_models.value?" (plus luma)":""), RESTRICT_LOCAL); - else if (r_fb_models.value) + else if (r_fb_models.ival) Cbuf_AddText("say luma textures only\n", RESTRICT_LOCAL); else Cbuf_AddText("say Only cheaters use full bright skins\n", RESTRICT_LOCAL); @@ -329,9 +326,9 @@ static void Validation_Skins(void) static void Validation_Scripts(void) { //subset of ruleset - if (!allow_f_scripts.value) + if (!allow_f_scripts.ival) return; - if (ruleset_allow_frj.value) + if (ruleset_allow_frj.ival) Cbuf_AddText("say scripts are allowed\n", RESTRICT_LOCAL); else Cbuf_AddText("say scripts are capped\n", RESTRICT_LOCAL); @@ -340,7 +337,7 @@ static void Validation_Scripts(void) static void Validation_FakeShaft(void) { extern cvar_t cl_truelightning; - if (!allow_f_fakeshaft.value) + if (!allow_f_fakeshaft.ival) return; if (cl_truelightning.value > 0.999) Cbuf_AddText("say fakeshaft on\n", RESTRICT_LOCAL); @@ -352,14 +349,14 @@ static void Validation_FakeShaft(void) static void Validation_System(void) { //subset of ruleset - if (!allow_f_system.value) + if (!allow_f_system.ival) return; Cbuf_AddText("say f_system not supported\n", RESTRICT_LOCAL); } static void Validation_CmdLine(void) { - if (!allow_f_cmdline.value) + if (!allow_f_cmdline.ival) return; Cbuf_AddText("say f_cmdline not supported\n", RESTRICT_LOCAL); } @@ -380,8 +377,7 @@ typedef struct { } ruleset_t; rulesetrule_t rulesetrules_strict[] = { - {"gl_shadeq1", "0"}, - {"gl_shadeq3", "0"}, //FIXME: there needs to be some other way to block these + {"ruleset_allow_shaders", "0"}, {"ruleset_allow_playercount", "0"}, {"ruleset_allow_frj", "0"}, {"ruleset_allow_packet", "0"}, @@ -405,8 +401,7 @@ rulesetrule_t rulesetrules_nqr[] = { {"ruleset_allow_modified_eyes", "0"}, {"ruleset_allow_sensative_texture_replacements", "0"}, {"ruleset_allow_localvolume", "0"}, - {"gl_shadeq1", "0"}, - {"gl_shadeq3", "0"}, + {"ruleset_allow_shaders", "0"}, {NULL} }; diff --git a/engine/client/vid.h b/engine/client/vid.h index a3c2ca16..b14efcb6 100644 --- a/engine/client/vid.h +++ b/engine/client/vid.h @@ -35,10 +35,8 @@ typedef struct { int bpp; int rate; int multisample; //for opengl antialiasing (which requires context stuff) - float stretch; char glrenderer[MAX_QPATH]; r_qrenderer_t renderer; - qboolean allow_modex; } rendererstate_t; typedef struct vrect_s @@ -49,32 +47,29 @@ typedef struct vrect_s typedef struct { - pixel_t *buffer; // invisible buffer pixel_t *colormap; // 256 * VID_GRADES size int fullbright; // index of first fullbright color - unsigned rowbytes; // may be > width if displayed in a window + unsigned width; unsigned height; float aspect; // width / height -- < 0 is taller than wide int numpages; int recalc_refdef; // if true, recalc vid-based stuff - pixel_t *conbuffer; - int conrowbytes; - unsigned conwidth; - unsigned conheight; +FTE_DEPRECATED pixel_t *conbuffer; +FTE_DEPRECATED int conrowbytes; +FTE_DEPRECATED unsigned conwidth; +FTE_DEPRECATED unsigned conheight; - int maxwarpwidth; - int maxwarpheight; - pixel_t *direct; // direct drawing to framebuffer, if not - // NULL + unsigned pixelwidth; + unsigned pixelheight; } viddef_t; extern viddef_t vid; // global video state extern unsigned int d_8to24rgbtable[256]; -#ifdef RGLQUAKE +#ifdef GLQUAKE void GLVID_SetPalette (unsigned char *palette); // called at startup and after any gamma correction @@ -89,6 +84,8 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette); void GLVID_Shutdown (void); // Called at shutdown +void GLVID_Crashed(void); + void GLVID_Update (vrect_t *rects); // flushes the given rectangles from the view buffer to the screen diff --git a/engine/client/view.c b/engine/client/view.c index d69c8f2c..0830f7ff 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -362,7 +362,7 @@ void BuildGammaTable (float g, float c) V_CheckGamma ================= */ -#if defined(RGLQUAKE) || defined(D3DQUAKE) +#if defined(GLQUAKE) || defined(D3DQUAKE) void GLV_Gamma_Callback(struct cvar_s *var, char *oldvalue) { BuildGammaTable (v_gamma.value, v_contrast.value); @@ -598,7 +598,7 @@ void V_CalcPowerupCshift (void) V_CalcBlend ============= */ -#if defined(RGLQUAKE) || defined(D3DQUAKE) +#if defined(GLQUAKE) || defined(D3DQUAKE) void GLV_CalcBlendServer (float colors[4]) { @@ -640,7 +640,7 @@ void GLV_CalcBlend (void) { // if (j != CSHIFT_SERVER) // { - if (!gl_cshiftpercent.value || !gl_cshiftenabled.value) + if (!gl_cshiftpercent.value || !gl_cshiftenabled.ival) continue; a2 = ((cl.cshifts[j].percent * gl_cshiftpercent.value) / 100.0) / 255.0; @@ -693,7 +693,7 @@ void GLV_UpdatePalette (qboolean force, double ftime) for (i=0 ; iflags & PF_DEAD && v_deathtilt.value) // PF_GIB will also set PF_DEAD { - if (!cl.spectator || !cl_chasecam.value) - r_refdef.viewangles[ROLL] = 80; // dead view angle + if (!cl.spectator || !cl_chasecam.ival) + r_refdef.viewangles[ROLL] = 80*v_deathtilt.value; // dead view angle } else { @@ -1162,9 +1162,6 @@ entity_t *CL_EntityNum(int num) float CalcFov (float fov_x, float width, float height); void SCR_VRectForPlayer(vrect_t *vrect, int pnum) { -#ifdef GLQUAKE - extern int glwidth, glheight; -#endif #if MAX_SPLITS > 4 #pragma warning "Please change this function to cope with the new MAX_SPLITS value" #endif @@ -1186,7 +1183,7 @@ void SCR_VRectForPlayer(vrect_t *vrect, int pnum) case 2: //horizontal bands case 3: #ifdef GLQUAKE - if (qrenderer == QR_OPENGL && glwidth > glheight * 2) + if (qrenderer == QR_OPENGL && vid.pixelwidth > vid.pixelheight * 2) { //over twice as wide as high, assume duel moniter, horizontal. vrect->width = vid.width/cl.splitclients; vrect->height = vid.height; @@ -1219,15 +1216,12 @@ void SCR_VRectForPlayer(vrect_t *vrect, int pnum) if (cl.stats[pnum][STAT_VIEWZOOM]) r_refdef.fov_x *= cl.stats[pnum][STAT_VIEWZOOM]/255.0f; -#ifdef GLQUAKE - if (qrenderer == QR_OPENGL && vrect->width < (vrect->height*640)/432) + if (vrect->width < (vrect->height*640)/432) { - extern int glwidth, glheight; - r_refdef.fov_y = CalcFov(r_refdef.fov_x, (vrect->width*glwidth)/vid.width, (vrect->height*glheight)/vid.height); + r_refdef.fov_y = CalcFov(r_refdef.fov_x, (vrect->width*vid.pixelwidth)/vid.width, (vrect->height*vid.pixelheight)/vid.height); // r_refdef.fov_x = CalcFov(r_refdef.fov_y, 432, 640); } else -#endif { r_refdef.fov_y = CalcFov(r_refdef.fov_x, 640, 432); r_refdef.fov_x = CalcFov(r_refdef.fov_y, vrect->height, vrect->width); @@ -1247,12 +1241,12 @@ void R_DrawNameTags(void) if (!cl.spectator && !cls.demoplayback) return; - if (!scr_autoid.value) + if (!scr_autoid.ival) return; if (cls.state != ca_active || !cl.validsequence) return; -#ifdef RGLQUAKE +#ifdef GLQUAKE if (qrenderer == QR_OPENGL) { void GL_Set2D (void); @@ -1350,7 +1344,7 @@ void V_RenderPlayerViews(int plnum) r_refdef.vrect.height += vsecheight; } */ -#ifdef RGLQUAKE +#ifdef GLQUAKE gl_ztrickdisabled&=~1; #endif for (viewnum = 0; viewnum < SIDEVIEWS; viewnum++) diff --git a/engine/client/view.h b/engine/client/view.h index b01e32ba..0926a939 100644 --- a/engine/client/view.h +++ b/engine/client/view.h @@ -36,4 +36,4 @@ qboolean V_CheckGamma (void); void V_AddEntity(entity_t *in); void VQ2_AddLerpEntity(entity_t *in); void V_AddAxisEntity(entity_t *in); -void V_AddLight (vec3_t org, float quant, float r, float g, float b); +int V_AddLight (int entsource, vec3_t org, float quant, float r, float g, float b); diff --git a/engine/client/wad.c b/engine/client/wad.c index b1c0561a..c6b7b4cc 100644 --- a/engine/client/wad.c +++ b/engine/client/wad.c @@ -38,7 +38,7 @@ Space padding is so names can be printed nicely in tables. Can safely be performed in place. ================== */ -void W_CleanupName (char *in, char *out) +void W_CleanupName (const char *in, char *out) { int i; int c; @@ -136,7 +136,7 @@ lumpinfo_t *W_GetLumpinfo (char *name) return NULL; } -void *W_SafeGetLumpName (char *name) +void *W_SafeGetLumpName (const char *name) { int i; lumpinfo_t *lump_p; @@ -428,6 +428,25 @@ qbyte *W_GetTexture(char *name, int *width, int *height, qboolean *usesalpha)//r miptex_t *tex; qbyte *data; + if (!strncmp(name, "gfx/", 4)) + { + qpic_t *p; + p = W_SafeGetLumpName(name+4); + if (p) + { + *width = p->width; + *height = p->height; + *usesalpha = false; + + data = BZ_Malloc(p->width * p->height * 4); + for (i = 0; i < p->width * p->height; i++) + { + ((unsigned int*)data)[i] = d_8to24rgbtable[p->data[i]]; + } + return data; + } + } + texname[16] = 0; W_CleanupName (name, texname); for (i = 0;i < numwadtextures;i++) @@ -562,10 +581,11 @@ void Mod_ParseInfoFromEntityLump(char *data, char *mapname) //actually, this sho extern model_t *loadmodel; char key[128]; char skyname[64]; - float skyrotate = 0; - vec3_t skyaxis = {0, 0, 0}; mapskys_t *msky; + cl.skyrotate = 0; + VectorClear(cl.skyaxis); + wads[0] = '\0'; #ifndef CLIENTONLY @@ -622,7 +642,7 @@ void Mod_ParseInfoFromEntityLump(char *data, char *mapname) //actually, this sho } else if (!strcmp("skyrotate", key)) { - skyrotate = atof(com_token); + cl.skyrotate = atof(com_token); } else if (!strcmp("skyaxis", key)) { @@ -631,21 +651,18 @@ void Mod_ParseInfoFromEntityLump(char *data, char *mapname) //actually, this sho s = COM_Parse(key); if (s) { - skyaxis[0] = atof(s); + cl.skyaxis[0] = atof(s); s = COM_Parse(s); if (s) { - skyaxis[1] = atof(s); + cl.skyaxis[1] = atof(s); COM_Parse(s); if (s) - skyaxis[2] = atof(s); + cl.skyaxis[2] = atof(s); } } } } - - skyrotate = VectorNormalize(skyaxis); - R_SetSky(skyname, skyrotate, skyaxis); } //textures/fred.wad is the DP standard - I wanna go for that one. diff --git a/engine/client/wad.h b/engine/client/wad.h index a85b5a70..b33831a9 100644 --- a/engine/client/wad.h +++ b/engine/client/wad.h @@ -43,7 +43,7 @@ typedef struct qbyte data[4]; // variably sized } qpic_t; -#ifdef RGLQUAKE +#ifdef GLQUAKE typedef struct { int texnum; @@ -51,6 +51,7 @@ typedef struct } glpic_t; #endif +/* //this is what's actually used. #define MPIC_ALPHA 1 typedef struct //use this so we don't have to go slow over pics, and don't have to shift too much data around. @@ -62,12 +63,15 @@ typedef struct //use this so we don't have to go slow over pics, and don't have union { int dummy; -#ifdef RGLQUAKE +#ifdef GLQUAKE glpic_t gl; #endif } d; + struct shader_s *shader; } mpic_t; - +*/ +typedef struct shader_s shader_t; +#define mpic_t shader_t extern mpic_t *draw_disc; // also used on sbar @@ -95,10 +99,10 @@ extern lumpinfo_t *wad_lumps; extern qbyte *wad_base; void W_LoadWadFile (char *filename); -void W_CleanupName (char *in, char *out); +void W_CleanupName (const char *in, char *out); lumpinfo_t *W_GetLumpinfo (char *name); void *W_GetLumpName (char *name); -void *W_SafeGetLumpName (char *name); +void *W_SafeGetLumpName (const char *name); void *W_GetLumpNum (int num); void Wads_Flush (void); diff --git a/engine/client/zqtp.c b/engine/client/zqtp.c index 5d608ed0..74ee8358 100644 --- a/engine/client/zqtp.c +++ b/engine/client/zqtp.c @@ -931,7 +931,7 @@ static void CountNearbyPlayers(qboolean dead) static char *Macro_CountNearbyEnemyPlayers (void) { - if (!ruleset_allow_playercount.value) + if (!ruleset_allow_playercount.ival) return " "; CountNearbyPlayers(false); sprintf(macro_buf, "\xffz%d\xff", vars.numenemies); @@ -942,7 +942,7 @@ static char *Macro_CountNearbyEnemyPlayers (void) static char *Macro_Count_Last_NearbyEnemyPlayers (void) { - if (!ruleset_allow_playercount.value) + if (!ruleset_allow_playercount.ival) return " "; if (vars.deathtrigger_time && realtime - vars.deathtrigger_time <= 5) { @@ -960,7 +960,7 @@ static char *Macro_Count_Last_NearbyEnemyPlayers (void) static char *Macro_CountNearbyFriendlyPlayers (void) { - if (!ruleset_allow_playercount.value) + if (!ruleset_allow_playercount.ival) return " "; CountNearbyPlayers(false); sprintf(macro_buf, "\xffz%d\xff", vars.numfriendlies); @@ -971,7 +971,7 @@ static char *Macro_CountNearbyFriendlyPlayers (void) static char *Macro_Count_Last_NearbyFriendlyPlayers (void) { - if (!ruleset_allow_playercount.value) + if (!ruleset_allow_playercount.ival) return " "; if (vars.deathtrigger_time && realtime - vars.deathtrigger_time <= 5) { @@ -1200,7 +1200,7 @@ static char *TP_ParseMacroString (char *s) int i = 0; char *macro_string; - if (!cl_parseSay.value) + if (!cl_parseSay.ival) return s; while (*s && i < MAX_MACRO_STRING-1) @@ -1322,7 +1322,7 @@ static char *TP_ParseFunChars (char *s, qbool chat) char *out = buf; int c; - if (!cl_parseFunChars.value) + if (!cl_parseFunChars.ival) return s; while (*s) { @@ -2505,7 +2505,7 @@ static int CountTeammates (void) player_info_t *player; char *myteam; - if (tp_forceTriggers.value) + if (tp_forceTriggers.ival) return 1; if (!cl.teamplay) @@ -2531,7 +2531,7 @@ static qboolean CheckTrigger (void) if (cl.spectator) return false; - if (tp_forceTriggers.value) + if (tp_forceTriggers.ival) return true; if (!cl.teamplay) @@ -2695,6 +2695,7 @@ more: } } +qboolean R_CullSphere (vec3_t org, float radius); static qboolean TP_IsItemVisible(item_vis_t *visitem) { vec3_t end, v; @@ -2703,6 +2704,9 @@ static qboolean TP_IsItemVisible(item_vis_t *visitem) if (visitem->dist <= visitem->radius) return true; + if (R_CullSphere(visitem->entorg, visitem->radius)) + return false; + VectorNegate (visitem->dir, v); VectorNormalize (v); VectorMA (visitem->entorg, visitem->radius, v, end); @@ -3044,7 +3048,7 @@ void TP_UpdateAutoStatus(void) char newstatusbuf[sizeof(vars.autoteamstatus)]; char *newstatus; - if (vars.autoteamstatus_time > realtime) + if (vars.autoteamstatus_time > realtime || !*tp_autostatus.string) return; vars.autoteamstatus_time = realtime + 3; diff --git a/engine/common/bothdefs.h b/engine/common/bothdefs.h index 6f2a06e3..501d636e 100644 --- a/engine/common/bothdefs.h +++ b/engine/common/bothdefs.h @@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define __BOTHDEFS_H #if defined(__APPLE__) && defined(__MACH__) -#define MACOSX + #define MACOSX #endif #if defined(__MINGW32_VERSION) || defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__) @@ -35,6 +35,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef 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 + #define MSVCLIBSPATH "../libs/" + #endif #ifdef NO_LIBRARIES #define NO_DIRECTX @@ -72,6 +75,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define AVAIL_FREETYPE #endif +//#define ODE_DYNAMIC + #ifdef NO_PNG #undef AVAIL_PNGLIB #endif @@ -92,7 +97,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #endif //#define AVAIL_FREETYPE -//#define NEWBACKEND //set any additional defines or libs in win32 #ifndef AVAIL_MASM @@ -142,8 +146,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define Q2CLIENT //client can connect to q2 servers #define Q3CLIENT #define Q3SERVER -// #define HLCLIENT //we can run HL gamecode (not protocol compatible) -// #define HLSERVER //we can run HL gamecode (not protocol compatible) +// #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 FISH //fisheye distortion stuff #define ZLIB //zip/pk3 support @@ -158,6 +162,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define TEXTEDITOR #define PPL //per pixel lighting (stencil shadowing) #define DDS //a sort of image file format. + #define RTLIGHTS //realtime lighting #define VM_Q1 //q1 qvm gamecode interface @@ -173,8 +178,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define CSQC_DAT //support for csqc #define MENU_DAT //support for menu.dat - #define Q3SHADERS - #define PSET_SCRIPT #define PSET_CLASSIC //#define PSET_DARKPLACES @@ -186,11 +189,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #endif -//temporarily disable stuff here, so as to not break any custom configs -#ifdef Q3SHADERS -//#define NEWBACKEND -#endif - //fix things a little... @@ -207,7 +205,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #endif #endif -#if !defined(AVAIL_D3D) || (!defined(GLQUAKE) && !defined(RGLQUAKE)) +#if !defined(AVAIL_D3D) || !defined(GLQUAKE) #undef USE_D3D #endif @@ -227,7 +225,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #undef WEBCLIENT #undef TEXTEDITOR #undef RUNTIMELIGHTING - #undef Q3SHADERS #undef TERRAIN //not supported #undef PSET_SCRIPT @@ -353,11 +350,32 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #endif #ifdef _MSC_VER -#define VARGS __cdecl + #define VARGS __cdecl + #define MSVCDISABLEWARNINGS + #define FTE_DEPRECATED __declspec(deprecated) + #define NORETURN __declspec(noreturn) +#endif +#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) + #define FTE_DEPRECATED __attribute__((__deprecated__)) //no idea about the actual gcc version + #define LIKEPRINTF(x) __attribute__((format(printf,x,x+1))) +#endif +#if (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5)) + #define NORETURN __attribute__((noreturn)) +#endif + + +#ifndef FTE_DEPRECATED +#define FTE_DEPRECATED +#endif +#ifndef LIKEPRINTF +#define LIKEPRINTF(x) #endif #ifndef VARGS #define VARGS #endif +#ifndef NORETURN +#define NORETURN +#endif #ifdef _WIN32 #define ZEXPORT VARGS diff --git a/engine/common/bspfile.h b/engine/common/bspfile.h index 753d0bae..f53ef3b0 100644 --- a/engine/common/bspfile.h +++ b/engine/common/bspfile.h @@ -492,22 +492,21 @@ typedef struct #define Q2CONTENTS_LADDER 0x20000000 +//Texinfo flags - warning: these mix with q3 surface flags +#define TI_LIGHT 0x1 // value will hold the light strength -#define SURF_LIGHT 0x1 // value will hold the light strength +#define TI_SLICK 0x2 // effects game physics -#define SURF_SLICK 0x2 // effects game physics +#define TI_SKY 0x4 // don't draw, but add to skybox +#define TI_WARP 0x8 // turbulent water warp +#define TI_TRANS33 0x10 +#define TI_TRANS66 0x20 +#define TI_FLOWING 0x40 // scroll towards angle +#define TI_NODRAW 0x80 // don't bother referencing the texture -#define SURF_SKY 0x4 // don't draw, but add to skybox -#define SURF_WARP 0x8 // turbulent water warp -#define SURF_TRANS33 0x10 -#define SURF_TRANS66 0x20 -#define SURF_FLOWING 0x40 // scroll towards angle -#define SURF_NODRAW 0x80 // don't bother referencing the texture - -#define SURF_NODRAW 0x80 // don't bother referencing the texture - -#define SURF_ALPHATEST 0x100 +#define TI_ALPHATEST 0x100 +//Surface flags #define Q3SURF_LADDER 0x8 //wee // content masks diff --git a/engine/common/cmd.c b/engine/common/cmd.c index f67a3d98..b6cb7a68 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" cvar_t com_fs_cache = SCVARF("fs_cache", "0", CVAR_ARCHIVE); -cvar_t rcon_level = SCVAR("rcon_level", "50"); +cvar_t rcon_level = SCVAR("rcon_level", "20"); cvar_t cmd_maxbuffersize = SCVAR("cmd_maxbuffersize", "65536"); int Cmd_ExecLevel; @@ -103,7 +103,7 @@ char *TP_MacroString (char *s, int *len) if (!Q_strcasecmp(s, macro->name)) { if (macro->disputableintentions) - if (!tp_disputablemacros.value) + if (!tp_disputablemacros.ival) continue; if (len) *len = strlen(macro->name); @@ -208,7 +208,7 @@ void Cbuf_AddText (const char *text, int level) newmax = cmd_text[level].buf.maxsize*2; - if (newmax > cmd_maxbuffersize.value && cmd_maxbuffersize.value) + if (newmax > cmd_maxbuffersize.ival && cmd_maxbuffersize.ival) { Con_TPrintf (TL_FUNCOVERFLOW, "Cbuf_AddText"); return; @@ -531,7 +531,7 @@ void Cmd_Exec_f (void) Con_TPrintf (TL_EXECFAILED,name); return; } - if (cl_warncmd.value || developer.value) + if (cl_warncmd.ival || developer.ival) Con_TPrintf (TL_EXECING,name); // don't execute anything as if it was from server @@ -676,7 +676,7 @@ void Cmd_Alias_f (void) { if (!strcmp(s, a->name)) { - if ((a->restriction?a->restriction:rcon_level.value) > Cmd_ExecLevel) + if ((a->restriction?a->restriction:rcon_level.ival) > Cmd_ExecLevel) { Con_TPrintf (TL_ALIASRESTRICTIONLEVELERROR); return; @@ -835,7 +835,7 @@ char *Cmd_AliasExist(char *name, int restrictionlevel) { if (!strcmp(name, a->name)) { - if ((a->restriction?a->restriction:rcon_level.value) > restrictionlevel) + if ((a->restriction?a->restriction:rcon_level.ival) > restrictionlevel) { return NULL; //not at this level... } @@ -879,7 +879,7 @@ void Cmd_AliasLevel_f (void) else if (level < RESTRICT_MIN) level = RESTRICT_MIN; - if (level > Cmd_ExecLevel || (a->restriction?a->restriction:rcon_level.value) > Cmd_ExecLevel) + if (level > Cmd_ExecLevel || (a->restriction?a->restriction:rcon_level.ival) > Cmd_ExecLevel) { Con_TPrintf(TL_ALIASRAISELEVELERROR); return; @@ -908,16 +908,16 @@ void Cmd_AliasList_f (void) for (cmd=cmd_alias ; cmd ; cmd=cmd->next) { - if ((cmd->restriction?cmd->restriction:rcon_level.value) > Cmd_ExecLevel) + if ((cmd->restriction?cmd->restriction:rcon_level.ival) > Cmd_ExecLevel) continue; if (flags && !(cmd->flags & flags)) continue; if (!num) Con_TPrintf(TL_ALIASLIST); if (cmd->execlevel) - Con_Printf("(%2i)(%2i) %s\n", (int)(cmd->restriction?cmd->restriction:rcon_level.value), cmd->execlevel, cmd->name); + Con_Printf("(%2i)(%2i) %s\n", (int)(cmd->restriction?cmd->restriction:rcon_level.ival), cmd->execlevel, cmd->name); else - Con_Printf("(%2i) %s\n", (int)(cmd->restriction?cmd->restriction:rcon_level.value), cmd->name); + Con_Printf("(%2i) %s\n", (int)(cmd->restriction?cmd->restriction:rcon_level.ival), cmd->name); num++; } if (num) @@ -931,7 +931,7 @@ void Alias_WriteAliases (vfsfile_t *f) int num=0; for (cmd=cmd_alias ; cmd ; cmd=cmd->next) { -// if ((cmd->restriction?cmd->restriction:rcon_level.value) > Cmd_ExecLevel) +// if ((cmd->restriction?cmd->restriction:rcon_level.ival) > Cmd_ExecLevel) // continue; if (cmd->flags & ALIAS_FROMSERVER) continue; @@ -1581,9 +1581,9 @@ void Cmd_RestrictCommand_f (void) if (cmd->restriction) Con_TPrintf (TL_RESTRICTCURRENTLEVEL, cmd_name, (int)cmd->restriction); else - Con_TPrintf (TL_RESTRICTCURRENTLEVELDEFAULT, cmd_name, (int)rcon_level.value); + Con_TPrintf (TL_RESTRICTCURRENTLEVELDEFAULT, cmd_name, rcon_level.ival); } - else if ((cmd->restriction?cmd->restriction:rcon_level.value) > Cmd_ExecLevel) + else if ((cmd->restriction?cmd->restriction:rcon_level.ival) > Cmd_ExecLevel) Con_TPrintf(TL_RESTRICTCOMMANDTOOHIGH); else cmd->restriction = level; @@ -1600,9 +1600,9 @@ void Cmd_RestrictCommand_f (void) if (v->restriction) Con_TPrintf (TL_RESTRICTCURRENTLEVEL, cmd_name, (int)v->restriction); else - Con_TPrintf (TL_RESTRICTCURRENTLEVELDEFAULT, cmd_name, (int)rcon_level.value); + Con_TPrintf (TL_RESTRICTCURRENTLEVELDEFAULT, cmd_name, rcon_level.ival); } - else if ((v->restriction?v->restriction:rcon_level.value) > Cmd_ExecLevel) + else if ((v->restriction?v->restriction:rcon_level.ival) > Cmd_ExecLevel) Con_TPrintf(TL_RESTRICTCOMMANDTOOHIGH); else v->restriction = level; @@ -1620,9 +1620,9 @@ void Cmd_RestrictCommand_f (void) if (a->restriction) Con_TPrintf (TL_RESTRICTCURRENTLEVEL, cmd_name, (int)a->restriction); else - Con_TPrintf (TL_RESTRICTCURRENTLEVELDEFAULT, cmd_name, (int)rcon_level.value); + Con_TPrintf (TL_RESTRICTCURRENTLEVELDEFAULT, cmd_name, rcon_level.ival); } - else if ((a->restriction?a->restriction:rcon_level.value) > Cmd_ExecLevel) + else if ((a->restriction?a->restriction:rcon_level.ival) > Cmd_ExecLevel) Con_TPrintf(TL_RESTRICTCOMMANDTOOHIGH); else a->restriction = level; @@ -1642,7 +1642,7 @@ int Cmd_Level(char *name) { if (!strcmp(cmds->name, name)) { - return cmds->restriction?cmds->restriction:rcon_level.value; + return cmds->restriction?cmds->restriction:rcon_level.ival; } } for (a=cmd_alias ; a ; a=a->next) @@ -1796,11 +1796,11 @@ void Cmd_List_f (void) int num=0; for (cmd=cmd_functions ; cmd ; cmd=cmd->next) { - if ((cmd->restriction?cmd->restriction:rcon_level.value) > Cmd_ExecLevel) + if ((cmd->restriction?cmd->restriction:rcon_level.ival) > Cmd_ExecLevel) continue; if (!num) Con_TPrintf(TL_COMMANDLISTHEADER); - Con_Printf("(%2i) %s\n", (int)(cmd->restriction?cmd->restriction:rcon_level.value), cmd->name); + Con_Printf("(%2i) %s\n", (int)(cmd->restriction?cmd->restriction:rcon_level.ival), cmd->name); num++; } if (num) @@ -1912,7 +1912,7 @@ void Cmd_ExecuteString (char *text, int level) if (strcmp (cmd_argv[0],cmd->name)) break; //yes, I know we found it... (but it's the wrong case, go for an alias or cvar instead FIRST) - if ((cmd->restriction?cmd->restriction:rcon_level.value) > level) + if ((cmd->restriction?cmd->restriction:rcon_level.ival) > level) Con_TPrintf(TL_WASRESTIRCTED, cmd_argv[0]); else if (!cmd->function) { @@ -1952,7 +1952,7 @@ void Cmd_ExecuteString (char *text, int level) return; #endif - if ((a->restriction?a->restriction:rcon_level.value) > level) + if ((a->restriction?a->restriction:rcon_level.ival) > level) { Con_TPrintf(TL_WASRESTIRCTED, cmd_argv[0]); return; @@ -1988,7 +1988,7 @@ void Cmd_ExecuteString (char *text, int level) if (cmd) //go for skipped ones { - if ((cmd->restriction?cmd->restriction:rcon_level.value) > level) + if ((cmd->restriction?cmd->restriction:rcon_level.ival) > level) Con_TPrintf(TL_WASRESTIRCTED, cmd_argv[0]); else if (!cmd->function) Cmd_ForwardToServer (); @@ -2219,7 +2219,7 @@ const char *If_Token(const char *func, const char **end) var = Cvar_FindVar(com_token); //for consistancy. if (var) { - if ((var->restriction?var->restriction:rcon_level.value) > Cmd_ExecLevel) + if ((var->restriction?var->restriction:rcon_level.ival) > Cmd_ExecLevel) s2 = "RESTRICTED"; else s2 = var->string; @@ -2904,7 +2904,7 @@ void Cmd_Init (void) Cvar_Register(&tp_disputablemacros, "Teamplay"); #ifndef SERVERONLY - rcon_level.value = atof(rcon_level.string); //client is restricted to not be allowed to change restrictions. + rcon_level.ival = atof(rcon_level.string); //client is restricted to not be allowed to change restrictions. #else Cvar_Register(&rcon_level, "Access controls"); //server gains versatility. #endif diff --git a/engine/common/cmd.h b/engine/common/cmd.h index 8e344b45..226bf3d0 100644 --- a/engine/common/cmd.h +++ b/engine/common/cmd.h @@ -69,6 +69,7 @@ typedef void (*xcommand_t) (void); int Cmd_Level(char *name); void Cmd_Init (void); +void Cmd_Shutdown(void); void Cmd_StuffCmds (void); void Cmd_RemoveCommand (char *cmd_name); @@ -116,14 +117,14 @@ void Cmd_ExecuteString (char *text, int restrictionlevel); void Cmd_Args_Set(char *newargs); -#define RESTRICT_MAX 64 //1-64 it's all about bit size. This is max settable. servers are +1 -#define RESTRICT_DEFAULT 50 //rcon get's 63, local always gets 64 +#define RESTRICT_MAX 29 //1-64 it's all about bit size. This is max settable. servers are +1 or +2 +#define RESTRICT_DEFAULT 20 //rcon get's 63, local always gets 64 #define RESTRICT_MIN 1 //rcon get's 63, local always gets 64 #define RESTRICT_LOCAL RESTRICT_MAX #define RESTRICT_INSECURE RESTRICT_MAX+1 #define RESTRICT_SERVER RESTRICT_MAX+2 -#define RESTRICT_RCON rcon_level.value +#define RESTRICT_RCON rcon_level.ival #define RESTRICT_PROGS RESTRICT_MAX-2 #define Cmd_FromGamecode() (Cmd_ExecLevel>=RESTRICT_SERVER) //cheat provention diff --git a/engine/common/com_mesh.c b/engine/common/com_mesh.c index b0bdc1ed..e0b0b093 100644 --- a/engine/common/com_mesh.c +++ b/engine/common/com_mesh.c @@ -24,7 +24,7 @@ void Mod_DoCRC(model_t *mod, char *buffer, int buffersize) sprintf(st, "%d", (int) crc); Info_SetValueForKey (cls.userinfo, (loadmodel->engineflags & MDLF_PLAYER) ? pmodel_name : emodel_name, - st, MAX_INFO_STRING); + st, sizeof(cls.userinfo)); if (cls.state >= ca_connected) { @@ -43,12 +43,9 @@ void Mod_DoCRC(model_t *mod, char *buffer, int buffersize) -#if defined(D3DQUAKE) || defined(RGLQUAKE) || defined(SERVERONLY) +#if defined(D3DQUAKE) || defined(GLQUAKE) || defined(SERVERONLY) -#ifdef D3DQUAKE -#include "d3dquake.h" -#endif -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h" #endif @@ -116,6 +113,102 @@ clampedmodel_t clampedmodel[] = { {"progs/turrgun.mdl", 3000} }; + + + + + + + + +void Mod_AccumulateTextureVectors(vecV_t *vc, vec2_t *tc, vec3_t *nv, vec3_t *sv, vec3_t *tv, index_t *idx, int numidx) +{ + int i; + float *v0, *v1, *v2; + float *tc0, *tc1, *tc2; + + vec3_t d1, d2; + float td1, td2; + + vec3_t norm, t, s; + vec3_t temp; + + for (i = 0; i < numidx; i += 3) + { + //this is the stuff we're working from + v0 = vc[idx[i+0]]; + v1 = vc[idx[i+1]]; + v2 = vc[idx[i+2]]; + tc0 = tc[idx[i+0]]; + tc1 = tc[idx[i+1]]; + tc2 = tc[idx[i+2]]; + + //calc perpendicular directions + VectorSubtract(v1, v0, d1); + VectorSubtract(v2, v0, d2); + + //calculate s as the pependicular of the t dir + td1 = tc1[1] - tc0[1]; + td2 = tc2[1] - tc0[1]; + s[0] = td1 * d2[0] - td2 * d1[0]; + s[1] = td1 * d2[1] - td2 * d1[1]; + s[2] = td1 * d2[2] - td2 * d1[2]; + + //calculate t as the pependicular of the s dir + td1 = tc1[0] - tc0[0]; + td2 = tc2[0] - tc0[0]; + t[0] = td1 * d2[0] - td2 * d1[0]; + t[1] = td1 * d2[1] - td2 * d1[1]; + t[2] = td1 * d2[2] - td2 * d1[2]; + + //the surface might be a back face and thus textured backwards + //calc the normal twice and compare. + norm[0] = d2[1] * d1[2] - d2[2] * d1[1]; + norm[1] = d2[2] * d1[0] - d2[0] * d1[2]; + norm[2] = d2[0] * d1[1] - d2[1] * d1[0]; + CrossProduct(t, s, temp); + if (DotProduct(temp, norm) < 0) + { + VectorNegate(s, s); + VectorNegate(t, t); + } + + //and we're done, accumulate the result + VectorAdd(sv[idx[i+0]], s, sv[idx[i+0]]); + VectorAdd(sv[idx[i+1]], s, sv[idx[i+1]]); + VectorAdd(sv[idx[i+2]], s, sv[idx[i+2]]); + + VectorAdd(tv[idx[i+0]], t, tv[idx[i+0]]); + VectorAdd(tv[idx[i+1]], t, tv[idx[i+1]]); + VectorAdd(tv[idx[i+2]], t, tv[idx[i+2]]); + } +} + +void Mod_AccumulateMeshTextureVectors(mesh_t *m) +{ + Mod_AccumulateTextureVectors(m->xyz_array, m->st_array, m->normals_array, m->snormals_array, m->tnormals_array, m->indexes, m->numindexes); +} + +void Mod_NormaliseTextureVectors(vec3_t *n, vec3_t *s, vec3_t *t, int v) +{ + int i; + float f; + vec3_t tmp; + + for (i = 0; i < v; i++) + { + f = -DotProduct(s[i], n[i]); + VectorMA(s[i], f, n[i], tmp); + VectorNormalize2(tmp, s[i]); + + f = -DotProduct(t[i], n[i]); + VectorMA(t[i], f, n[i], tmp); + VectorNormalize2(tmp, t[i]); + } +} + + + #ifdef SKELETALMODELS @@ -123,10 +216,9 @@ void Alias_TransformVerticies(float *bonepose, galisskeletaltransforms_t *weight { int i; float *out, *matrix; - float *normo; - galisskeletaltransforms_t *v = weights; #ifndef SERVERONLY + float *normo; if (normout) { for (i = 0;i < numweights;i++, v++) @@ -633,46 +725,95 @@ static void R_LerpBones(float *plerp, float **pose, int poses, galiasbone_t *bon -#if defined(D3DQUAKE) || defined(RGLQUAKE) +#if defined(D3DQUAKE) || defined(GLQUAKE) extern entity_t *currententity; int numTempColours; -byte_vec4_t *tempColours; +avec4_t *tempColours; int numTempVertexCoords; -vec3_t *tempVertexCoords; +vecV_t *tempVertexCoords; int numTempNormals; vec3_t *tempNormals; -vec3_t shadevector; -vec3_t ambientlight; -vec3_t shadelight; +avec3_t shadevector; +avec3_t ambientlight; +avec3_t shadelight; +//#define SSE_INTRINSICS +#ifdef SSE_INTRINSICS +#include +#endif -void R_LightArrays(byte_vec4_t *colours, int vertcount, vec3_t *normals) +void R_LightArrays(vecV_t *coords, avec4_t *colours, int vertcount, vec3_t *normals) { + extern cvar_t r_vertexdlights; int i; float l; - int temp; +#ifdef SSE_INTRINSICS + __m128 va, vs, vl, vr; + va = _mm_load_ps(ambientlight); + vs = _mm_load_ps(shadelight); + va.m128_f32[3] = 0; + vs.m128_f32[3] = 1; +#endif for (i = vertcount-1; i >= 0; i--) { l = DotProduct(normals[i], shadevector); +#ifdef SSE_INTRINSICS + vl = _mm_load1_ps(&l); + vr = _mm_mul_ss(va,vl); + vr = _mm_add_ss(vr,vs); - temp = l*ambientlight[0]+shadelight[0]; - if (temp < 0) temp = 0; - else if (temp > 255) temp = 255; - colours[i][0] = temp; + _mm_storeu_ps(colours[i], vr); + //stomp on colour[i][3] (will be set to 1) +#else + colours[i][0] = l*ambientlight[0]+shadelight[0]; + colours[i][1] = l*ambientlight[1]+shadelight[1]; + colours[i][2] = l*ambientlight[2]+shadelight[2]; +#endif + } - temp = l*ambientlight[1]+shadelight[1]; - if (temp < 0) temp = 0; - else if (temp > 255) temp = 255; - colours[i][1] = temp; + if (r_vertexdlights.ival && r_dynamic.ival) + { + unsigned int lno, v; + vec3_t dir, rel; + float dot, d, a; + //don't include world lights + for (lno = rtlights_first; lno < RTL_FIRST; lno++) + { + if (cl_dlights[lno].radius) + { + VectorSubtract (cl_dlights[lno].origin, + currententity->origin, + dir); + if (Length(dir)>cl_dlights[lno].radius+256) //far out man! + continue; - temp = l*ambientlight[2]+shadelight[2]; - if (temp < 0) temp = 0; - else if (temp > 255) temp = 255; - colours[i][2] = temp; + rel[0] = -DotProduct(dir, currententity->axis[0]); + rel[1] = -DotProduct(dir, currententity->axis[1]); + rel[2] = -DotProduct(dir, currententity->axis[2]); + + for (v = 0; v < vertcount; v++) + { + VectorSubtract(coords[v], rel, dir); + dot = DotProduct(dir, normals[v]); + if (dot>0) + { + d = DotProduct(dir, dir); + a = 1/d; + if (a>0) + { + a *= 10000000*dot/sqrt(d); + colours[v][0] += a*cl_dlights[lno].color[0]; + colours[v][1] += a*cl_dlights[lno].color[1]; + colours[v][2] += a*cl_dlights[lno].color[2]; + } + } + } + } + } } } @@ -683,21 +824,36 @@ static void R_LerpFrames(mesh_t *mesh, galiaspose_t *p1, galiaspose_t *p2, float int i; float l; int temp; - vec3_t *p1v, *p2v; + vecV_t *p1v, *p2v; vec3_t *p1n, *p2n; - p1v = (vec3_t *)((char *)p1 + p1->ofsverts); - p2v = (vec3_t *)((char *)p2 + p2->ofsverts); + vec3_t *p1s, *p2s; + vec3_t *p1t, *p2t; + + p1v = (vecV_t *)((char *)p1 + p1->ofsverts); + p2v = (vecV_t *)((char *)p2 + p2->ofsverts); p1n = (vec3_t *)((char *)p1 + p1->ofsnormals); p2n = (vec3_t *)((char *)p2 + p2->ofsnormals); + p1s = (vec3_t *)((char *)p1 + p1->ofssvector); + p2s = (vec3_t *)((char *)p2 + p2->ofssvector); + + p1t = (vec3_t *)((char *)p1 + p1->ofstvector); + p2t = (vec3_t *)((char *)p2 + p2->ofstvector); + + mesh->normals_array = p1n; + mesh->snormals_array = p1s; + mesh->tnormals_array = p1t; + if (p1v == p2v || r_nolerp.value) { mesh->normals_array = p1n; + mesh->snormals_array = p1s; + mesh->tnormals_array = p1t; mesh->xyz_array = p1v; if (r_nolightdir.value || nolightdir) { - mesh->colors_array = NULL; + mesh->colors4f_array = NULL; } else { @@ -706,29 +862,23 @@ static void R_LerpFrames(mesh_t *mesh, galiaspose_t *p1, galiaspose_t *p2, float l = DotProduct(mesh->normals_array[i], shadevector); temp = l*ambientlight[0]+shadelight[0]; - if (temp < 0) temp = 0; - else if (temp > 255) temp = 255; - mesh->colors_array[i][0] = temp; + mesh->colors4f_array[i][0] = temp; temp = l*ambientlight[1]+shadelight[1]; - if (temp < 0) temp = 0; - else if (temp > 255) temp = 255; - mesh->colors_array[i][1] = temp; + mesh->colors4f_array[i][1] = temp; temp = l*ambientlight[2]+shadelight[2]; - if (temp < 0) temp = 0; - else if (temp > 255) temp = 255; - mesh->colors_array[i][2] = temp; + mesh->colors4f_array[i][2] = temp; - mesh->colors_array[i][3] = alpha; + mesh->colors4f_array[i][3] = alpha; } } } else { - if (r_nolightdir.value || nolightdir) + if (r_nolightdir.ival || nolightdir) { - mesh->colors_array = NULL; + mesh->colors4f_array = NULL; for (i = 0; i < mesh->numvertexes; i++) { mesh->normals_array[i][0] = p1n[i][0]*lerp + p2n[i][0]*blerp; @@ -754,21 +904,15 @@ static void R_LerpFrames(mesh_t *mesh, galiaspose_t *p1, galiaspose_t *p2, float l = DotProduct(mesh->normals_array[i], shadevector); temp = l*ambientlight[0]+shadelight[0]; - if (temp < 0) temp = 0; - else if (temp > 255) temp = 255; - mesh->colors_array[i][0] = temp; + mesh->colors4f_array[i][0] = temp; temp = l*ambientlight[1]+shadelight[1]; - if (temp < 0) temp = 0; - else if (temp > 255) temp = 255; - mesh->colors_array[i][1] = temp; + mesh->colors4f_array[i][1] = temp; temp = l*ambientlight[2]+shadelight[2]; - if (temp < 0) temp = 0; - else if (temp > 255) temp = 255; - mesh->colors_array[i][2] = temp; + mesh->colors4f_array[i][2] = temp; - mesh->colors_array[i][3] = alpha; + mesh->colors4f_array[i][3] = alpha; } } } @@ -806,6 +950,7 @@ static void Alias_BuildSkeletalMesh(mesh_t *mesh, float *bonepose, galisskeletal Alias_TransformVerticies(bonepose, weights, numweights, (float*)mesh->xyz_array, (float*)mesh->normals_array); } +#ifdef GLQUAKE static void Alias_GLDrawSkeletalBones(galiasbone_t *bones, float *bonepose, int bonecount) { qglColor3f(1, 0, 0); @@ -861,8 +1006,9 @@ static void Alias_GLDrawSkeletalBones(galiasbone_t *bones, float *bonepose, int // mesh->numindexes = 0; //don't draw this mesh, as that would obscure the bones. :( } } -#endif -#endif +#endif //GLQUAKE +#endif //!SERVERONLY +#endif //SKELETALMODELS qboolean Alias_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, entity_t *e, @@ -900,7 +1046,7 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, { if (tempVertexCoords) BZ_Free(tempVertexCoords); - tempVertexCoords = BZ_Malloc(sizeof(*tempVertexCoords)*inf->numverts); + tempVertexCoords = BZ_Malloc(sizeof(*tempVertexCoords)*inf->numverts*3); numTempVertexCoords = inf->numverts; } @@ -914,9 +1060,11 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, #ifndef SERVERONLY mesh->st_array = (vec2_t*)((char *)inf + inf->ofs_st_array); mesh->lmst_array = NULL; - mesh->colors_array = tempColours; + mesh->colors4f_array = tempColours; mesh->trneighbors = (int *)((char *)inf + inf->ofs_trineighbours); mesh->normals_array = tempNormals; + mesh->snormals_array = tempNormals+numTempVertexCoords; + mesh->tnormals_array = tempNormals+numTempVertexCoords*2; #endif mesh->xyz_array = tempVertexCoords; @@ -931,6 +1079,7 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, usebonepose = Alias_GetBonePositions(inf, &e->framestate, (float*)bonepose, MAX_BONES); Alias_BuildSkeletalMesh(mesh, usebonepose, (galisskeletaltransforms_t *)((char*)inf+inf->ofstransforms), inf->numtransforms); +#ifdef PEXT_FATNESS if (currententity->fatness) { if (mesh->xyz_array == tempVertexCoords) @@ -942,11 +1091,14 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, } } } - if (!mesh->numindexes) +#endif +#ifdef GLQUAKE + if (!mesh->numindexes && qrenderer == QR_OPENGL) Alias_GLDrawSkeletalBones((galiasbone_t*)((char*)inf + inf->ofsbones), (float *)bonepose, inf->numbones); +#endif - if (mesh->colors_array) - R_LightArrays(mesh->colors_array, mesh->numvertexes, mesh->normals_array); + if (mesh->colors4f_array) + R_LightArrays(mesh->xyz_array, mesh->colors4f_array, mesh->numvertexes, mesh->normals_array); return true; } #endif @@ -1051,7 +1203,7 @@ qboolean Mod_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, ve vec3_t impactpoint; float *posedata; - int *indexes; + index_t *indexes; while(mod) { @@ -1177,7 +1329,7 @@ static void Mod_ClampModelSize(model_t *mod) #endif } -#ifdef RGLQUAKE +#ifdef GLQUAKE static int R_FindTriangleWithEdge ( int *indexes, int numtris, int start, int end, int ignore) { int i; @@ -1222,10 +1374,10 @@ static void Mod_BuildTriangleNeighbours ( int *neighbours, index_t *indexes, int #endif void Mod_CompileTriangleNeighbours(galiasinfo_t *galias) { -#ifdef RGLQUAKE +#ifdef GLQUAKE if (qrenderer != QR_OPENGL) return; - if (r_shadows.value) + if (r_shadow_realtime_dlight_shadows.value || r_shadow_realtime_world_shadows.value) { int *neighbours; neighbours = Hunk_Alloc(sizeof(int)*galias->numindexes/3*3); @@ -1235,7 +1387,43 @@ void Mod_CompileTriangleNeighbours(galiasinfo_t *galias) #endif } -#if defined(D3DQUAKE) || defined(RGLQUAKE) +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) +{ +#ifndef SERVERONLY + int i, p; + galiasgroup_t *group; + galiaspose_t *pose; + vecV_t *vc; + vec3_t *nv, *sv, *tv; + vec2_t *tc; + index_t *idx; + + idx = (index_t*)((char*)galias + galias->ofs_indexes); + tc = (vec2_t*)((char*)galias + galias->ofs_st_array); + group = (galiasgroup_t*)((char*)galias + galias->groupofs); + for (i = 0; i < galias->groups; i++, group++) + { + pose = (galiaspose_t*)((char*)group + group->poseofs); + for (p = 0; p < group->numposes; p++, pose++) + { + vc = (vecV_t *)((char*)pose + pose->ofsverts); + nv = (vec3_t *)((char*)pose + pose->ofsnormals); + if (pose->ofssvector == 0) + continue; + if (pose->ofstvector == 0) + continue; + sv = (vec3_t *)((char*)pose + pose->ofssvector); + tv = (vec3_t *)((char*)pose + pose->ofstvector); + + Mod_AccumulateTextureVectors(vc, tc, nv, sv, tv, idx, galias->numindexes); + Mod_NormaliseTextureVectors(nv, sv, tv, galias->numverts); + } + } +#endif +} + +#if defined(D3DQUAKE) || defined(GLQUAKE) /* ================= Mod_FloodFillSkin @@ -1486,23 +1674,17 @@ void Mod_ParseQ3SkinFile(char *out, char *surfname, char *modelname, int skinnum } } -#if defined(D3DQUAKE) || defined(RGLQUAKE) -void Mod_LoadSkinFile(galiastexnum_t *texnum, char *surfacename, int skinnumber, unsigned char *rawdata, int width, int height, unsigned char *palette) +#if defined(D3DQUAKE) || defined(GLQUAKE) +void Mod_LoadSkinFile(texnums_t *texnum, char *surfacename, int skinnumber, unsigned char *rawdata, int width, int height, unsigned char *palette) { char shadername[MAX_QPATH]; Q_strncpyz(shadername, surfacename, sizeof(shadername)); Mod_ParseQ3SkinFile(shadername, surfacename, loadmodel->name, skinnumber, NULL); -#ifdef Q3SHADERS texnum->shader = R_RegisterSkin(shadername); -#endif - texnum->base = Mod_LoadHiResTexture(shadername, "models", true, true, true); - - //13/4/08 IMPLEMENTME - texnum->loweroverlay = 0; - texnum->upperoverlay = 0; + R_BuildDefaultTexnums(texnum, texnum->shader); } #endif @@ -1596,8 +1778,8 @@ static void *Q1_LoadFrameGroup (daliasframetype_t *pframetype, int *seamremaps) daliasinterval_t *intervals; float sinter; - vec3_t *normals; - vec3_t *verts; + vec3_t *normals, *svec, *tvec; + vecV_t *verts; frame = (galiasgroup_t*)((char *)galias + galias->groupofs); @@ -1608,18 +1790,24 @@ static void *Q1_LoadFrameGroup (daliasframetype_t *pframetype, int *seamremaps) case ALIAS_SINGLE: frameinfo = (daliasframe_t*)((char *)(pframetype+1)); pinframe = (dtrivertx_t*)((char*)frameinfo+sizeof(daliasframe_t)); - pose = (galiaspose_t *)Hunk_Alloc(sizeof(galiaspose_t) + sizeof(vec3_t)*2*galias->numverts); + pose = (galiaspose_t *)Hunk_Alloc(sizeof(galiaspose_t) + (sizeof(vecV_t)+sizeof(vec3_t)*3)*galias->numverts); frame->poseofs = (char *)pose - (char *)frame; frame->numposes = 1; galias->groups++; Q_strncpyz(frame->name, frameinfo->name, sizeof(frame->name)); - verts = (vec3_t *)(pose+1); - normals = &verts[galias->numverts]; + verts = (vecV_t *)(pose+1); + normals = (vec3_t*)&verts[galias->numverts]; + svec = &normals[galias->numverts]; + tvec = &svec[galias->numverts]; pose->ofsverts = (char *)verts - (char *)pose; #ifndef SERVERONLY pose->ofsnormals = (char *)normals - (char *)pose; + pose->ofssvector = (char *)svec - (char *)pose; + pose->ofstvector = (char *)tvec - (char *)pose; +#else +#pragma message("wasted memory") #endif for (j = 0; j < pq1inmodel->numverts; j++) @@ -1646,14 +1834,16 @@ static void *Q1_LoadFrameGroup (daliasframetype_t *pframetype, int *seamremaps) case ALIAS_GROUP_SWAPPED: // prerelease ingroup = (daliasgroup_t *)(pframetype+1); - pose = (galiaspose_t *)Hunk_Alloc(LittleLong(ingroup->numframes)*(sizeof(galiaspose_t) + sizeof(vec3_t)*2*galias->numverts)); + pose = (galiaspose_t *)Hunk_Alloc(LittleLong(ingroup->numframes)*(sizeof(galiaspose_t) + (sizeof(vecV_t)+sizeof(vec3_t)*3)*galias->numverts)); frame->poseofs = (char *)pose - (char *)frame; frame->numposes = LittleLong(ingroup->numframes); frame->loop = true; galias->groups++; - verts = (vec3_t *)(pose+frame->numposes); - normals = &verts[galias->numverts]; + verts = (vecV_t *)(pose+frame->numposes); + normals = (vec3_t*)&verts[galias->numverts]; + svec = &normals[galias->numverts]; + tvec = &svec[galias->numverts]; intervals = (daliasinterval_t *)(ingroup+1); sinter = LittleFloat(intervals->interval); @@ -1667,6 +1857,8 @@ static void *Q1_LoadFrameGroup (daliasframetype_t *pframetype, int *seamremaps) pose->ofsverts = (char *)verts - (char *)pose; #ifndef SERVERONLY pose->ofsnormals = (char *)normals - (char *)pose; + pose->ofssvector = (char *)svec - (char *)pose; + pose->ofstvector = (char *)tvec - (char *)pose; #endif frameinfo = (daliasframe_t*)pinframe; @@ -1689,8 +1881,10 @@ static void *Q1_LoadFrameGroup (daliasframetype_t *pframetype, int *seamremaps) VectorCopy(normals[j], normals[seamremaps[j]]); } } - verts = &normals[galias->numverts]; - normals = &verts[galias->numverts]; + verts = (vecV_t*)&tvec[galias->numverts]; + normals = (vec3_t*)&verts[galias->numverts]; + svec = &normals[galias->numverts]; + tvec = &svec[galias->numverts]; pose++; pinframe += pq1inmodel->numverts; @@ -1741,11 +1935,11 @@ static void *Q1_LoadSkins_SV (daliasskintype_t *pskintype, qboolean alpha) return pskintype; } -#if defined(RGLQUAKE) || defined(D3DQUAKE) -static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, qboolean alpha) +#if defined(GLQUAKE) || defined(D3DQUAKE) +static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, unsigned int skintranstype) { extern cvar_t gl_bump; - galiastexnum_t *texnums; + texnums_t *texnums; char skinname[MAX_QPATH]; int i; int s, t; @@ -1755,9 +1949,9 @@ static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, qboolean alpha) qbyte *data, *saved; galiasskin_t *outskin = (galiasskin_t *)((char *)galias + galias->ofsskins); - int texture; - int fbtexture; - int bumptexture; + texid_t texture; + texid_t fbtexture; + texid_t bumptexture; s = pq1inmodel->skinwidth*pq1inmodel->skinheight; for (i = 0; i < pq1inmodel->numskins; i++) @@ -1769,38 +1963,38 @@ static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, qboolean alpha) outskin->skinheight = pq1inmodel->skinheight; //LH's naming scheme ("models" is likly to be ignored) - fbtexture = 0; - bumptexture = 0; + fbtexture = r_nulltex; + bumptexture = r_nulltex; snprintf(skinname, sizeof(skinname), "%s_%i", loadmodel->name, i); - texture = Mod_LoadReplacementTexture(skinname, "models", true, false, true); - if (texture) + texture = R_LoadReplacementTexture(skinname, "models", IF_NOALPHA); + if (TEXVALID(texture)) { snprintf(skinname, sizeof(skinname), "%s_%i_luma", loadmodel->name, i); - fbtexture = Mod_LoadReplacementTexture(skinname, "models", true, false, true); - if (gl_bump.value) + fbtexture = R_LoadReplacementTexture(skinname, "models", 0); + if (gl_bump.ival) { snprintf(skinname, sizeof(skinname), "%s_%i_bump", loadmodel->name, i); - bumptexture = Mod_LoadBumpmapTexture(skinname, "models"); + bumptexture = R_LoadBumpmapTexture(skinname, "models"); } } else { snprintf(skinname, sizeof(skinname), "%s_%i", loadname, i); - texture = Mod_LoadReplacementTexture(skinname, "models", true, false, true); - if (texture && r_fb_models.value) + texture = R_LoadReplacementTexture(skinname, "models", IF_NOALPHA); + if (TEXVALID(texture) && r_fb_models.ival) { snprintf(skinname, sizeof(skinname), "%s_%i_luma", loadname, i); - fbtexture = Mod_LoadReplacementTexture(skinname, "models", true, true, true); + fbtexture = R_LoadReplacementTexture(skinname, "models", 0); } - if (texture && gl_bump.value) + if (TEXVALID(texture) && gl_bump.ival) { snprintf(skinname, sizeof(skinname), "%s_%i_bump", loadname, i); - bumptexture = Mod_LoadBumpmapTexture(skinname, "models"); + bumptexture = R_LoadBumpmapTexture(skinname, "models"); } } //but only preload it if we have no replacement. - if (!texture || (loadmodel->engineflags & MDLF_NOTREPLACEMENTS)) + if (!TEXVALID(texture) || (loadmodel->engineflags & MDLF_NOTREPLACEMENTS)) { //we're not using 24bits texnums = Hunk_Alloc(sizeof(*texnums)+s); @@ -1809,20 +2003,20 @@ static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, qboolean alpha) memcpy(saved, pskintype+1, s); Mod_FloodFillSkin(saved, outskin->skinwidth, outskin->skinheight); -//the extra underscore is to stop - if (!texture) +//the extra underscore is to stop replacement matches + if (!TEXVALID(texture)) { snprintf(skinname, sizeof(skinname), "%s__%i", loadname, i); - texture = R_LoadTexture8(skinname, outskin->skinwidth, outskin->skinheight, saved, true, alpha); - if (r_fb_models.value) + texture = R_LoadTexture8(skinname, outskin->skinwidth, outskin->skinheight, saved, (skintranstype?0:IF_NOALPHA)|IF_NOGAMMA, skintranstype); + if (r_fb_models.ival) { snprintf(skinname, sizeof(skinname), "%s__%i_luma", loadname, i); - fbtexture = R_LoadTextureFB(skinname, outskin->skinwidth, outskin->skinheight, saved, true, true); + fbtexture = R_LoadTextureFB(skinname, outskin->skinwidth, outskin->skinheight, saved, IF_NOGAMMA); } - if (gl_bump.value) + if (gl_bump.ival) { snprintf(skinname, sizeof(skinname), "%s__%i_bump", loadname, i); - bumptexture = R_LoadTexture8Bump(skinname, outskin->skinwidth, outskin->skinheight, saved, true, true); + bumptexture = R_LoadTexture8Bump(skinname, outskin->skinwidth, outskin->skinheight, saved, IF_NOGAMMA, 1.0); } } } @@ -1832,29 +2026,27 @@ static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, qboolean alpha) outskin->ofstexnums = (char *)texnums - (char *)outskin; -#ifdef Q3SHADERS - if (cls.allow_shaders) - { - sprintf(skinname, "%s_%i", loadname, i); - texnums->shader = R_RegisterCustom (skinname, NULL, NULL); - } -#endif - texnums->loweroverlay = 0; - texnums->upperoverlay = 0; + + sprintf(skinname, "%s_%i", loadname, i); + texnums->shader = R_RegisterSkin(skinname); + R_BuildDefaultTexnums(texnums, texnums->shader); + + texnums->loweroverlay = r_nulltex; + texnums->upperoverlay = r_nulltex; texnums->base = texture; texnums->fullbright = fbtexture; texnums->bump = bumptexture; //13/4/08 IMPLEMENTME - if (r_skin_overlays.value) + if (r_skin_overlays.ival) { snprintf(skinname, sizeof(skinname), "%s_%i_pants", loadname, i); - texnums->loweroverlay = Mod_LoadReplacementTexture(skinname, "models", true, true, true); + texnums->loweroverlay = R_LoadReplacementTexture(skinname, "models", 0); snprintf(skinname, sizeof(skinname), "%s_%i_shirt", loadname, i); - texnums->upperoverlay = Mod_LoadReplacementTexture(skinname, "models", true, true, true); + texnums->upperoverlay = R_LoadReplacementTexture(skinname, "models", 0); } pskintype = (daliasskintype_t *)((char *)(pskintype+1)+s); @@ -1877,34 +2069,34 @@ static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, qboolean alpha) for (t = 0; t < outskin->texnums; t++,data+=s, texnums++) { - texture = 0; - fbtexture = 0; + texture = r_nulltex; + fbtexture = r_nulltex; //LH naming scheme - if (!texture) + if (!TEXVALID(texture)) { sprintf(skinname, "%s_%i_%i", loadmodel->name, i, t); - texture = Mod_LoadReplacementTexture(skinname, "models", true, false, true); + texture = R_LoadReplacementTexture(skinname, "models", IF_NOALPHA); } - if (!fbtexture && r_fb_models.value) + if (!TEXVALID(fbtexture) && r_fb_models.ival) { sprintf(skinname, "%s_%i_%i_luma", loadmodel->name, i, t); - fbtexture = Mod_LoadReplacementTexture(skinname, "models", true, true, true); + fbtexture = R_LoadReplacementTexture(skinname, "models", 0); } //Fuhquake naming scheme - if (!texture) + if (!TEXVALID(texture)) { sprintf(skinname, "%s_%i_%i", loadname, i, t); - texture = Mod_LoadReplacementTexture(skinname, "models", true, false, true); + texture = R_LoadReplacementTexture(skinname, "models", IF_NOALPHA); } - if (!fbtexture && r_fb_models.value) + if (!TEXVALID(fbtexture) && r_fb_models.ival) { sprintf(skinname, "%s_%i_%i_luma", loadname, i, t); - fbtexture = Mod_LoadReplacementTexture(skinname, "models", true, true, true); + fbtexture = R_LoadReplacementTexture(skinname, "models", 0); } - if (!texture || (!fbtexture && r_fb_models.value)) + if (!TEXVALID(texture) || (!TEXVALID(fbtexture) && r_fb_models.ival)) { if (t == 0) { @@ -1915,37 +2107,34 @@ static void *Q1_LoadSkins_GL (daliasskintype_t *pskintype, qboolean alpha) saved = BZ_Malloc(s); memcpy(saved, data, s); Mod_FloodFillSkin(saved, outskin->skinwidth, outskin->skinheight); - if (!texture) + if (!TEXVALID(texture)) { sprintf(skinname, "%s_%i_%i", loadname, i, t); - texture = R_LoadTexture8(skinname, outskin->skinwidth, outskin->skinheight, saved, true, alpha); + texture = R_LoadTexture8(skinname, outskin->skinwidth, outskin->skinheight, saved, (skintranstype?0:IF_NOALPHA)|IF_NOGAMMA, skintranstype); } - if (!fbtexture && r_fb_models.value) + if (!TEXVALID(fbtexture) && r_fb_models.value) { sprintf(skinname, "%s_%i_%i_luma", loadname, i, t); - fbtexture = R_LoadTextureFB(skinname, outskin->skinwidth, outskin->skinheight, saved, true, true); + fbtexture = R_LoadTextureFB(skinname, outskin->skinwidth, outskin->skinheight, saved, IF_NOGAMMA); } if (t != 0) //only keep the first. BZ_Free(saved); } -#ifdef Q3SHADERS - if (cls.allow_shaders) - { - sprintf(skinname, "%s_%i_%i", loadname, i, t); - texnums->shader = R_RegisterCustom (skinname, NULL, NULL); - } -#endif + sprintf(skinname, "%s_%i_%i", loadname, i, t); + texnums->shader = R_RegisterSkin(skinname); texnums->base = texture; texnums->fullbright = fbtexture; //13/4/08 IMPLEMENTME - texnums->loweroverlay = 0; - texnums->upperoverlay = 0; + texnums->loweroverlay = r_nulltex; + texnums->upperoverlay = r_nulltex; + + R_BuildDefaultTexnums(texnums, texnums->shader); } pskintype = (daliasskintype_t *)data; break; @@ -2049,7 +2238,7 @@ qboolean Mod_LoadQ1Model (model_t *mod, void *buffer) switch(qrenderer) { -#if defined(RGLQUAKE) || defined(D3DQUAKE) +#if defined(GLQUAKE) || defined(D3DQUAKE) case QR_DIRECT3D: case QR_OPENGL: pinstverts = (dstvert_t *)Q1_LoadSkins_GL(skinstart, skintranstype); @@ -2138,6 +2327,7 @@ qboolean Mod_LoadQ1Model (model_t *mod, void *buffer) Mod_CompileTriangleNeighbours(galias); + Mod_BuildTextureVectors(galias); VectorCopy (pq1inmodel->scale_origin, mod->mins); VectorMA (mod->mins, 255, pq1inmodel->scale, mod->maxs); @@ -2216,7 +2406,7 @@ static void Q2_LoadSkins(md2_t *pq2inmodel, char *skins) { #ifndef SERVERONLY int i; - galiastexnum_t *texnums; + texnums_t *texnums; galiasskin_t *outskin = (galiasskin_t *)((char *)galias + galias->ofsskins); for (i = 0; i < LittleLong(pq2inmodel->num_skins); i++, outskin++) @@ -2226,12 +2416,10 @@ static void Q2_LoadSkins(md2_t *pq2inmodel, char *skins) outskin->texnums=1; COM_CleanUpPath(skins); //blooming tanks. - texnums->base = Mod_LoadReplacementTexture(skins, "models", true, false, true); -#ifdef Q3SHADERS - texnums->shader = R_RegisterCustom(skins, NULL, NULL); - if (!texnums->base && !texnums->shader) - Con_Printf("Couldn't load %s\n", skins); -#endif + texnums->base = R_LoadReplacementTexture(skins, "models", IF_NOALPHA); + texnums->shader = R_RegisterSkin(skins); + R_BuildDefaultTexnums(texnums, texnums->shader); + outskin->skinwidth = 0; outskin->skinheight = 0; outskin->skinspeed = 0; @@ -2246,13 +2434,11 @@ static void Q2_LoadSkins(md2_t *pq2inmodel, char *skins) outskin += galias->numskins - 1; if (galias->numskins) { - texnums = (galiastexnum_t*)((char *)outskin +outskin->ofstexnums); - if (texnums->base) + texnums = (texnums_t*)((char *)outskin +outskin->ofstexnums); + if (TEXVALID(texnums->base)) return; -#ifdef Q3SHADERS if (texnums->shader) return; -#endif galias->numskins--; } @@ -2283,7 +2469,7 @@ qboolean Mod_LoadQ2Model (model_t *mod, void *buffer) galiasgroup_t *poutframe; dmd2aliasframe_t *pinframe; int framesize; - vec3_t *verts; + vecV_t *verts; int indremap[MD2_MAX_TRIANGLES*3]; unsigned short ptempindex[MD2_MAX_TRIANGLES*3], ptempstindex[MD2_MAX_TRIANGLES*3]; @@ -2421,7 +2607,7 @@ qboolean Mod_LoadQ2Model (model_t *mod, void *buffer) framesize = LittleLong (pq2inmodel->framesize); for (i=0 ; inum_frames) ; i++) { - pose = (galiaspose_t *)Hunk_Alloc(sizeof(galiaspose_t) + sizeof(vec3_t)*numverts + pose = (galiaspose_t *)Hunk_Alloc(sizeof(galiaspose_t) + sizeof(vecV_t)*numverts #ifndef SERVERONLY + sizeof(vec3_t)*numverts #endif @@ -2430,10 +2616,10 @@ qboolean Mod_LoadQ2Model (model_t *mod, void *buffer) poutframe->numposes = 1; galias->groups++; - verts = (vec3_t *)(pose+1); + verts = (vecV_t *)(pose+1); pose->ofsverts = (char *)verts - (char *)pose; #ifndef SERVERONLY - normals = &verts[galias->numverts]; + normals = (vec3_t*)&verts[galias->numverts]; pose->ofsnormals = (char *)normals - (char *)pose; #endif @@ -2477,6 +2663,7 @@ qboolean Mod_LoadQ2Model (model_t *mod, void *buffer) Mod_CompileTriangleNeighbours(galias); + Mod_BuildTextureVectors(galias); /* VectorCopy (pq2inmodel->scale_origin, mod->mins); VectorMA (mod->mins, 255, pq2inmodel->scale, mod->maxs); @@ -2969,10 +3156,12 @@ qboolean Mod_LoadQ3Model(model_t *mod, void *buffer) { #ifndef SERVERONLY galiasskin_t *skin; - galiastexnum_t *texnum; + texnums_t *texnum; float lat, lng; md3St_t *inst; vec3_t *normals; + vec3_t *svector; + vec3_t *tvector; vec2_t *st_array; md3Shader_t *inshader; #endif @@ -2989,7 +3178,7 @@ qboolean Mod_LoadQ3Model(model_t *mod, void *buffer) galiasinfo_t *parent, *root; galiasgroup_t *group; - vec3_t *verts; + vecV_t *verts; md3Triangle_t *intris; md3XyzNormal_t *invert; @@ -3065,17 +3254,21 @@ qboolean Mod_LoadQ3Model(model_t *mod, void *buffer) invert = (md3XyzNormal_t *)((qbyte*)surf + LittleLong(surf->ofsXyzNormals)); for (i = 0; i < LittleLong(surf->numFrames); i++) { - pose = (galiaspose_t *)Hunk_Alloc(sizeof(galiaspose_t) + sizeof(vec3_t)*LittleLong(surf->numVerts) + pose = (galiaspose_t *)Hunk_Alloc(sizeof(galiaspose_t) + sizeof(vecV_t)*LittleLong(surf->numVerts) #ifndef SERVERONLY - + sizeof(vec3_t)*LittleLong(surf->numVerts) + + 3*sizeof(vec3_t)*LittleLong(surf->numVerts) #endif ); - verts = (vec3_t*)(pose+1); + verts = (vecV_t*)(pose+1); pose->ofsverts = (qbyte*)verts - (qbyte*)pose; #ifndef SERVERONLY - normals = verts + LittleLong(surf->numVerts); + normals = (vec3_t*)(verts + LittleLong(surf->numVerts)); pose->ofsnormals = (qbyte*)normals - (qbyte*)pose; + svector = normals + LittleLong(surf->numVerts); + pose->ofssvector = (qbyte*)svector - (qbyte*)pose; + tvector = svector + LittleLong(surf->numVerts); + pose->ofstvector = (qbyte*)tvector - (qbyte*)pose; #endif for (j = 0; j < LittleLong(surf->numVerts); j++) @@ -3120,15 +3313,12 @@ qboolean Mod_LoadQ3Model(model_t *mod, void *buffer) externalskins = LittleLong(surf->numShaders); if (externalskins) { -#ifndef Q3SHADERS - char name[1024]; extern int gl_bumpmappingpossible; -#endif char shadname[1024]; - skin = Hunk_Alloc((LittleLong(surf->numShaders)+externalskins)*((sizeof(galiasskin_t)+sizeof(galiastexnum_t)))); + skin = Hunk_Alloc((LittleLong(surf->numShaders)+externalskins)*((sizeof(galiasskin_t)+sizeof(texnums_t)))); galias->ofsskins = (qbyte *)skin - (qbyte *)galias; - texnum = (galiastexnum_t *)(skin + LittleLong(surf->numShaders)+externalskins); + texnum = (texnums_t *)(skin + LittleLong(surf->numShaders)+externalskins); inshader = (md3Shader_t *)((qbyte *)surf + LittleLong(surf->ofsShaders)); for (i = 0; i < externalskins; i++) { @@ -3145,7 +3335,7 @@ qboolean Mod_LoadQ3Model(model_t *mod, void *buffer) if (!*shadname) { - if (i >= LittleLong(surf->numShaders)) + if (i >= LittleLong(surf->numShaders) || !*inshader->name) strcpy(shadname, "missingskin"); //this shouldn't be possible else strcpy(shadname, inshader->name); @@ -3153,72 +3343,11 @@ qboolean Mod_LoadQ3Model(model_t *mod, void *buffer) Q_strncpyz(skin->name, shadname, sizeof(skin->name)); } -#ifdef Q3SHADERS if (qrenderer) { texnum->shader = R_RegisterSkin(shadname); - - if (r_shadows.value) //real-time shadows requires a texture to lighten the model with, even if it has a shader. - //fixme: this should be read from the shader. - texnum->base = Mod_LoadHiResTexture(shadname, "models", true, true, true); + R_BuildDefaultTexnums(texnum, texnum->shader); } -#else - - texnum->base = Mod_LoadHiResTexture(shadname, "models", true, true, true); - if (!texnum->base) - { - strcpy(name, loadmodel->name); - strcpy(COM_SkipPath(name), COM_SkipPath(shadname)); //eviile eh? - texnum->base = Mod_LoadHiResTexture(name, "models", true, true, true); - } - - texnum->bump = 0; - if (gl_bumpmappingpossible) - { - COM_StripExtension(shadname, name, sizeof(name)); //go for the normalmap - strcat(name, "_norm"); - texnum->bump = Mod_LoadHiResTexture(name, "models", true, true, false); - if (!texnum->bump) - { - strcpy(name, loadmodel->name); - COM_StripExtension(COM_SkipPath(shadname), COM_SkipPath(name), sizeof(name)); - strcat(name, "_norm"); - texnum->bump = Mod_LoadHiResTexture(name, "models", true, true, false); - if (!texnum->bump) - { - COM_StripExtension(shadname, name, sizeof(name)); //bother, go for heightmap and convert - strcat(name, "_bump"); - texnum->bump = Mod_LoadBumpmapTexture(name, "models"); - if (!texnum->bump) - { - strcpy(name, loadmodel->name); - strcpy(COM_SkipPath(name), COM_SkipPath(shadname)); //eviile eh? - COM_StripExtension(name, name, sizeof(name)); - strcat(name, "_bump"); - texnum->bump = Mod_LoadBumpmapTexture(name, "models"); - } - } - } - } - if (r_fb_models.value) - { - COM_StripExtension(shadname, name, sizeof(name)); //go for the normalmap - strcat(name, "_luma"); - texnum->fullbright = Mod_LoadHiResTexture(name, "models", true, true, true); - if (!texnum->base) - { - strcpy(name, loadmodel->name); - strcpy(COM_SkipPath(name), COM_SkipPath(shadname)); //eviile eh? - COM_StripExtension(name, name, sizeof(name)); - strcat(name, "_luma"); - texnum->fullbright = Mod_LoadBumpmapTexture(name, "models"); - } - } -#endif - - //13/4/08 IMPLEMENTME - texnum->loweroverlay = 0; - texnum->upperoverlay = 0; inshader++; skin++; @@ -3233,6 +3362,7 @@ qboolean Mod_LoadQ3Model(model_t *mod, void *buffer) Mod_CompileTriangleNeighbours (galias); + Mod_BuildTextureVectors(galias); surf = (md3Surface_t *)((qbyte *)surf + LittleLong(surf->ofsEnd)); } @@ -3372,7 +3502,7 @@ qboolean Mod_LoadZymoticModel(model_t *mod, void *buffer) { #ifndef SERVERONLY galiasskin_t *skin; - galiastexnum_t *texnum; + texnums_t *texnum; int skinfiles; int j; #endif @@ -3557,8 +3687,8 @@ qboolean Mod_LoadZymoticModel(model_t *mod, void *buffer) root[i].ofs_st_array = (char*)stcoords - (char*)&root[i]; root[i].numskins = skinfiles; - skin = Hunk_Alloc((sizeof(galiasskin_t)+sizeof(galiastexnum_t))*skinfiles); - texnum = (galiastexnum_t*)(skin+skinfiles); + skin = Hunk_Alloc((sizeof(galiasskin_t)+sizeof(texnums_t))*skinfiles); + texnum = (texnums_t*)(skin+skinfiles); for (j = 0; j < skinfiles; j++, texnum++) { skin[j].texnums = 1; //non-sequenced skins. @@ -3731,7 +3861,7 @@ qboolean Mod_LoadDarkPlacesModel(model_t *mod, void *buffer) { #ifndef SERVERONLY galiasskin_t *skin; - galiastexnum_t *texnum; + texnums_t *texnum; int skinfiles; float *inst; float *outst; @@ -3948,8 +4078,8 @@ qboolean Mod_LoadDarkPlacesModel(model_t *mod, void *buffer) #else m->numskins = skinfiles; - skin = Hunk_Alloc((sizeof(galiasskin_t)+sizeof(galiastexnum_t))*skinfiles); - texnum = (galiastexnum_t*)(skin+skinfiles); + skin = Hunk_Alloc((sizeof(galiasskin_t)+sizeof(texnums_t))*skinfiles); + texnum = (texnums_t*)(skin+skinfiles); for (j = 0; j < skinfiles; j++, texnum++) { skin[j].texnums = 1; //non-sequenced skins. @@ -4295,7 +4425,7 @@ galiasinfo_t *Mod_ParseMD5MeshModel(char *buffer) float *posedata; #ifndef SERVERONLY galiasskin_t *skin; - galiastexnum_t *texnum; + texnums_t *texnum; #endif char *filestart = buffer; @@ -4472,8 +4602,8 @@ galiasinfo_t *Mod_ParseMD5MeshModel(char *buffer) { buffer = COM_Parse(buffer); #ifndef SERVERONLY - // texnum->shader = R_RegisterSkin(com_token); - texnum->base = Mod_LoadHiResTexture(com_token, "models", true, true, true); + texnum->shader = R_RegisterSkin(com_token); + R_BuildDefaultTexnums(texnum, texnum->shader); #endif } else if (!strcmp(com_token, "numverts")) @@ -4913,4 +5043,4 @@ char *Mod_GetBoneName(struct model_s *model, int bonenum) { return ""; } -#endif //#if defined(D3DQUAKE) || defined(RGLQUAKE) +#endif //#if defined(D3DQUAKE) || defined(GLQUAKE) diff --git a/engine/common/com_mesh.h b/engine/common/com_mesh.h index 3308d2e1..79666441 100644 --- a/engine/common/com_mesh.h +++ b/engine/common/com_mesh.h @@ -9,6 +9,8 @@ #define MAX_BONES 256 +int HLMod_BoneForName(model_t *mod, char *name); +int HLMod_FrameForName(model_t *mod, char *name); typedef struct { int ofs_indexes; @@ -65,6 +67,8 @@ typedef struct { int ofsverts; #ifndef SERVERONLY int ofsnormals; + int ofstvector; + int ofssvector; #endif vec3_t scale; @@ -101,24 +105,13 @@ typedef struct { char name [MAX_QPATH]; } galiasskin_t; -typedef struct { - int base; - int bump; - int fullbright; - int upperoverlay; - int loweroverlay; - -#ifdef Q3SHADERS - shader_t *shader; -#endif -} galiastexnum_t; - typedef struct { char name[MAX_QPATH]; - galiastexnum_t texnum; + texnums_t texnum; unsigned int tcolour; unsigned int bcolour; int skinnum; + unsigned int subframe; bucket_t bucket; } galiascolourmapped_t; #endif @@ -148,3 +141,7 @@ qboolean Mod_LoadQ1Model (model_t *mod, void *buffer); qboolean Mod_LoadMD5MeshModel(model_t *mod, void *buffer); qboolean Mod_LoadCompositeAnim(model_t *mod, void *buffer); #endif + +void Mod_AccumulateTextureVectors(vecV_t *vc, vec2_t *tc, vec3_t *nv, vec3_t *sv, vec3_t *tv, index_t *idx, int numidx); +void Mod_AccumulateMeshTextureVectors(mesh_t *mesh); +void Mod_NormaliseTextureVectors(vec3_t *n, vec3_t *s, vec3_t *t, int v); diff --git a/engine/common/common.c b/engine/common/common.c index d3e7ab30..8d0b63e9 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -56,7 +56,6 @@ qboolean static_registered = true; // only for startup check, then set qboolean msg_suppress_1 = false; -void COM_InitFilesystem (void); void COM_Path_f (void); void COM_Dir_f (void); void COM_Locate_f (void); @@ -1619,6 +1618,8 @@ void COM_DefaultExtension (char *path, char *extension, int maxlen) src--; } + if (*extension != '.') + Q_strncatz (path, ".", maxlen); Q_strncatz (path, extension, maxlen); } @@ -1755,7 +1756,7 @@ static int dehex(int i) //Takes a q3-style fun string, and returns an expanded string-with-flags (actual return value is the null terminator) //outsize parameter is in _BYTES_ (so sizeof is safe). -conchar_t *COM_ParseFunString(conchar_t defaultflags, char *str, conchar_t *out, int outsize, qboolean keepmarkup) +conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t *out, int outsize, qboolean keepmarkup) { conchar_t extstack[4]; int extstackdepth = 0; @@ -2078,6 +2079,7 @@ messedup: int COM_FunStringLength(unsigned char *str) { + //FIXME: int len = 0; while(*str) @@ -3213,7 +3215,7 @@ int COM_Effectinfo_Add(const char *effectname) void COM_Effectinfo_Reload(void) { int i; - char *f; + char *f, *buf; static const char *dpnames[] = { "TE_GUNSHOT", @@ -3263,6 +3265,7 @@ void COM_Effectinfo_Reload(void) FS_LoadFile("effectinfo.txt", &f); if (!f) return; + buf = f; while (*f) { f = COM_ParseToken(f, NULL); @@ -3281,7 +3284,7 @@ void COM_Effectinfo_Reload(void) } while(*f && strcmp(com_token, "\n")); } } - FS_FreeFile(f); + FS_FreeFile(buf); } unsigned int COM_Effectinfo_ForName(const char *efname) @@ -3314,6 +3317,71 @@ char *COM_Effectinfo_ForNumber(unsigned int efnum) return ""; } +/*************************************************************************/ + +/*remaps map checksums from known non-cheat GPL maps to authentic id1 maps*/ +unsigned int COM_RemapMapChecksum(unsigned int checksum) +{ + static const struct { + char *name; + unsigned int gpl2; + unsigned int id11; + unsigned int id12; + } sums[] = + { + {"maps/start.bsp", -603735309, 714749795, 493454459}, + + {"maps/e1m1.bsp", -1213097692, 523840258, -1391994750}, + {"maps/e1m2.bsp", -2134038629, 1561595172, 1729102119}, + {"maps/e1m3.bsp", 526593427, 1008794158, 893792842}, + {"maps/e1m4.bsp", -1218723400, -442162482, -304478603}, + {"maps/e1m5.bsp", 1709090059, 1856217547, -1473504118}, + {"maps/e1m6.bsp", 1014375998, 1304756164, 738207971}, + {"maps/e1m7.bsp", 1375393448, -1396746908, -1747518694}, + {"maps/e1m8.bsp", 1470379688, -163803419, 79095617}, + + {"maps/e2m1.bsp", -1725230579, -797758554, -587894734}, + {"maps/e2m2.bsp", -1573837115, -355822557, -1349116595}, + {"maps/e2m3.bsp", 156655662, 1203005272, -57072303}, + {"maps/e2m4.bsp", -1530012474, -1629664024, -1021928503}, + {"maps/e3m5.bsp", -594001393, -1405673977, -1854273999}, + {"maps/e2m6.bsp", 1041933133, 583875451, -1851573375}, + {"maps/e2m7.bsp", -1583122652, 1814005234, 2051006488}, + + {"maps/e3m1.bsp", -1118143869, -457270773, -1867379423}, + {"maps/e3m2.bsp", -469484146, 723435606, -1670613704}, + {"maps/e3m3.bsp", -300762423, -540030088, -1009754856}, + {"maps/e3m4.bsp", -214067894, 1107310161, -1317466952}, + {"maps/e3m5.bsp", -594001393, -1405673977, -1854273999}, + {"maps/e3m6.bsp", -1664550468, 1631142730, 767655416}, + {"maps/e3m7.bsp", 781051658, -1513131760, 272220593}, + + {"maps/e4m1.bsp", 1548541253, 1254243660, -1141873840}, + {"maps/e4m2.bsp", -1400585206, 92253388, -472296}, + {"maps/e4m3.bsp", -1230693918, 1961442781, 1505685644}, + {"maps/e4m4.bsp", 842253404, -374904516, 758847551}, + {"maps/e4m5.bsp", -439098147, 389110272, 1771890676}, + {"maps/e4m6.bsp", 1518024640, 1714857656, 102825880}, + {"maps/e4m7.bsp", -381063035, -585362206, -1645477460}, + {"maps/e4m8.bsp", 844770132, 1063417045, 1018457175}, + + {"maps/gpl_dm1.bsp", 2100781454, -1548219590, -976758093}, + {"maps/gpl_dm2.bsp", 2066969664, 392410074, 1710634548}, + {"maps/gpl_dm3.bsp", -1859681874, 2060033246, 367136248}, + {"maps/gpl_dm4.bsp", -1015750775, 326737183, -1670388545}, + {"maps/gpl_dm5.bsp", 2009758949, 766929852, -1339209475}, + {"maps/gpl_dm6.bsp", 537693021, 247150701, 1376311851}, + + {"maps/end.bsp", -124054866, -1503553320, -1143688027} + }; + unsigned int i; + for (i = 0; i < sizeof(sums)/sizeof(sums[0]); i++) + { + if (checksum == sums[i].gpl2) + return sums[i].id12; + } + return checksum; +} /* ===================================================================== diff --git a/engine/common/common.h b/engine/common/common.h index fb598251..744bda81 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -187,7 +187,7 @@ int wildcmp(const char *wild, const char *string); //1 if match #define Q_strcmp(s1, s2) strcmp((s1), (s2)) #define Q_strncmp(s1, s2, n) strncmp((s1), (s2), (n)) -void VARGS Q_snprintfz (char *dest, size_t size, char *fmt, ...); +void VARGS Q_snprintfz (char *dest, size_t size, char *fmt, ...) LIKEPRINTF(3); #define Q_strncpyS(d, s, n) do{const char *____in=(s);char *____out=(d);int ____i; for (____i=0;*(____in); ____i++){if (____i == (n))break;*____out++ = *____in++;}if (____i < (n))*____out='\0';}while(0) //only use this when it should be used. If undiciided, use N #define Q_strncpyN(d, s, n) do{if (n < 0)Sys_Error("Bad length in strncpyz");Q_strncpyS((d), (s), (n));((char *)(d))[n] = '\0';}while(0) //this'll stop me doing buffer overflows. (guarenteed to overflow if you tried the wrong size.) @@ -258,18 +258,19 @@ void COM_ParsePlusSets (void); typedef unsigned int conchar_t; void COM_DeFunString(conchar_t *str, char *out, int outsize, qboolean ignoreflags); -conchar_t *COM_ParseFunString(conchar_t defaultflags, char *str, conchar_t *out, int outsize, qboolean keepmarkup); //ext is usually CON_WHITEMASK, returns its null terminator +conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t *out, int outsize, qboolean keepmarkup); //ext is usually CON_WHITEMASK, returns its null terminator int COM_FunStringLength(unsigned char *str); char *COM_SkipPath (const char *pathname); void COM_StripExtension (const char *in, char *out, int outlen); +void COM_StripAllExtensions (char *in, char *out, int outlen); void COM_FileBase (const char *in, char *out, int outlen); int COM_FileSize(const char *path); void COM_DefaultExtension (char *path, char *extension, int maxlen); char *COM_FileExtension (const char *in); void COM_CleanUpPath(char *str); -char *VARGS va(char *format, ...); +char *VARGS va(char *format, ...) LIKEPRINTF(1); // does a varargs printf into a temp buffer //============================================================================ @@ -338,7 +339,7 @@ typedef struct vfsfile_s { #define VFS_FLUSH(vf) do{if(vf->Flush)vf->Flush(vf);}while(0) #define VFS_PUTS(vf,s) do{const char *t=s;vf->WriteBytes(vf,t,strlen(t));}while(0) char *VFS_GETS(vfsfile_t *vf, char *buffer, int buflen); -void VARGS VFS_PRINTF(vfsfile_t *vf, char *fmt, ...); +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) @@ -371,13 +372,18 @@ qbyte *COM_LoadTempFile2 (const char *path); //allocates a little bit more witho qbyte *COM_LoadHunkFile (const char *path); void COM_LoadCacheFile (const char *path, struct cache_user_s *cu); void COM_CreatePath (char *path); -void COM_Gamedir (const char *dir); void FS_ForceToPure(const char *str, const char *crcs, int seed); char *COM_GetPathInfo (int i, int *crc); char *COM_NextPath (char *prevpath); void COM_FlushFSCache(void); //a file was written using fopen void COM_RefreshFSCache_f(void); +void COM_InitFilesystem (void); +void FS_Shutdown(void); +void COM_Gamedir (const char *dir); +char *FS_GetGamedir(void); + +qbyte *FS_LoadMallocFile (const char *path); int FS_LoadFile(char *name, void **file); void FS_FreeFile(void *file); @@ -393,6 +399,8 @@ void COM_Effectinfo_Clear(void); unsigned int COM_Effectinfo_ForName(const char *efname); char *COM_Effectinfo_ForNumber(unsigned int efnum); +unsigned int COM_RemapMapChecksum(unsigned int checksum); + #define MAX_INFO_KEY 64 char *Info_ValueForKey (char *s, const char *key); void Info_RemoveKey (char *s, const char *key); diff --git a/engine/common/console.h b/engine/common/console.h index 8b2a5a71..aaa46c0b 100644 --- a/engine/common/console.h +++ b/engine/common/console.h @@ -124,13 +124,15 @@ extern int con_notifylines; // scan lines to clear for notify lines void Con_DrawCharacter (int cx, int line, int num); void Con_CheckResize (void); +void Con_ForceActiveNow(void); void Con_Init (void); void Con_DrawConsole (int lines, qboolean noback); +char *Con_CopyConsole(void); void Con_Print (char *txt); -void VARGS Con_Printf (const char *fmt, ...); +void VARGS Con_Printf (const char *fmt, ...) LIKEPRINTF(1); void VARGS Con_TPrintf (translation_t text, ...); -void VARGS Con_DPrintf (char *fmt, ...); -void VARGS Con_SafePrintf (char *fmt, ...); +void VARGS Con_DPrintf (char *fmt, ...) LIKEPRINTF(1); +void VARGS Con_SafePrintf (char *fmt, ...) LIKEPRINTF(1); void Con_Clear_f (void); void Con_DrawNotify (void); void Con_ClearNotify (void); diff --git a/engine/common/cvar.c b/engine/common/cvar.c index 7d58c0b7..a78e5a07 100644 --- a/engine/common/cvar.c +++ b/engine/common/cvar.c @@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // cvar.c -- dynamic variable tracking #include "quakedef.h" +#include "shader.h" cvar_group_t *cvar_groups; @@ -305,7 +306,7 @@ void Cvar_List_f (void) for (cmd=grp->cvars ; cmd ; cmd=cmd->next) { // list only non-restricted cvars - if ((cmd->restriction?cmd->restriction:rcon_level.value) > Cmd_ExecLevel) + if ((cmd->restriction?cmd->restriction:rcon_level.ival) > Cmd_ExecLevel) continue; // list only cvars with search substring @@ -481,7 +482,7 @@ void Cvar_Reset_f (void) for (cmd=grp->cvars ; cmd ; cmd=cmd->next) { // reset only non-restricted cvars - if ((cmd->restriction?cmd->restriction:rcon_level.value) > Cmd_ExecLevel) + if ((cmd->restriction?cmd->restriction:rcon_level.ival) > Cmd_ExecLevel) continue; // don't reset cvars with matched flags @@ -654,6 +655,12 @@ cvar_t *Cvar_SetCore (cvar_t *var, const char *value, qboolean force) } #endif #ifndef SERVERONLY + if (var->flags & CVAR_SHADERSYSTEM) + { + if (var->string && value) + if (strcmp(var->string, value)) + Shader_NeedReload(); + } if (var->flags & CVAR_USERINFO) { char *old = Info_ValueForKey(cls.userinfo, var->name); @@ -1037,7 +1044,7 @@ qboolean Cvar_Command (int level) if (!v) return false; - if ((v->restriction?v->restriction:rcon_level.value) > level) + if ((v->restriction?v->restriction:rcon_level.ival) > level) { Con_Printf ("You do not have the priveledges for %s\n", v->name); return true; diff --git a/engine/common/cvar.h b/engine/common/cvar.h index dfdf47d2..992a4a9e 100644 --- a/engine/common/cvar.h +++ b/engine/common/cvar.h @@ -116,6 +116,7 @@ typedef struct cvar_group_s #define CVAR_RENDERERCALLBACK (1<<13) //force callback for cvars on renderer change #define CVAR_NOUNSAFEEXPAND (1<<14) // do not expand cvar value when command is from gamecode #define CVAR_RULESETLATCH (1<<15) //latched by the ruleset +#define CVAR_SHADERSYSTEM (1<<16) //change flushes shaders. #define CVAR_LASTFLAG CVAR_RULESETLATCH diff --git a/engine/common/fs.c b/engine/common/fs.c index 8aaa64f5..50edd3bc 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -13,6 +13,10 @@ #include "./mingw-libs/SDL_syswm.h" // mingw sdl cross binary complains off sys_parentwindow #endif +#ifdef _MSC_VER +#pragma comment(lib, MSVCLIBSPATH "zlib.lib") +#endif + hashtable_t filesystemhash; qboolean com_fschanged = true; extern cvar_t com_fs_cache; @@ -769,9 +773,6 @@ typedef struct { #define GZ_RESERVED (32|64|128) #include -#ifdef _WIN32 -#pragma comment( lib, "../libs/zlib.lib" ) -#endif vfsfile_t *FS_DecompressGZip(vfsfile_t *infile, gzheader_t *header) { @@ -1231,7 +1232,7 @@ qbyte *COM_LoadFile (const char *path, int usehunk) return buf; } -qbyte *COM_LoadMallocFile (const char *path) //used for temp info along side temp hunk +qbyte *FS_LoadMallocFile (const char *path) { return COM_LoadFile (path, 5); } @@ -1272,7 +1273,7 @@ qbyte *COM_LoadStackFile (const char *path, void *buffer, int bufsize) /*warning: at some point I'll change this function to return only read-only buffers*/ int FS_LoadFile(char *name, void **file) { - *file = COM_LoadMallocFile(name); + *file = FS_LoadMallocFile(name); if (!*file) return -1; return com_filesize; @@ -1638,6 +1639,7 @@ void COM_Gamedir (const char *dir) searchpath_t *next; int plen, dlen; char *p; + qboolean isbase; if (!*dir || !strcmp(dir, ".") || strstr(dir, "..") || strstr(dir, "/") || strstr(dir, "\\") || strstr(dir, ":") ) @@ -1646,9 +1648,12 @@ void COM_Gamedir (const char *dir) return; } + isbase = false; dlen = strlen(dir); - for (next = com_base_searchpaths; next; next = next->next) + for (next = com_searchpaths; next; next = next->next) { + if (next == com_base_searchpaths) + isbase = true; if (next->funcs == &osfilefuncs) { p = next->handle; @@ -1657,14 +1662,32 @@ void COM_Gamedir (const char *dir) { //no basedir, maybe if (!strcmp(p, dir)) - return; + { + if (isbase && com_searchpaths == com_base_searchpaths) + { + Q_strncpyz (gamedirfile, dir, sizeof(gamedirfile)); + return; + } + if (!isbase) + return; + break; + } } else if (plen > dlen) { if (*(p+plen-dlen-1) == '/') { if (!strcmp(p+plen-dlen, dir)) - return; + { + if (isbase && com_searchpaths == com_base_searchpaths) + { + Q_strncpyz (gamedirfile, dir, sizeof(gamedirfile)); + return; + } + if (!isbase) + return; + break; + } } } @@ -1677,7 +1700,7 @@ void COM_Gamedir (const char *dir) Host_WriteConfiguration(); //before we change anything. #endif - strcpy (gamedirfile, dir); + Q_strncpyz (gamedirfile, dir, sizeof(gamedirfile)); #ifndef CLIENTONLY sv.gamedirchanged = true; @@ -1746,12 +1769,10 @@ void COM_Gamedir (const char *dir) } } -#ifdef Q3SHADERS { extern void Shader_Init(void); Shader_Init(); //FIXME! } -#endif COM_Effectinfo_Clear(); diff --git a/engine/common/fs_stdio.c b/engine/common/fs_stdio.c index a2efa781..fbd0a386 100644 --- a/engine/common/fs_stdio.c +++ b/engine/common/fs_stdio.c @@ -1,11 +1,16 @@ #include "quakedef.h" #include "fs.h" +#ifdef WEBSVONLY +#define Z_Free free +#define Z_Malloc malloc +#else #if !defined(_WIN32) || defined(_SDL) #define VFSSTDIO_Open VFSOS_Open #define stdiofilefuncs osfilefuncs #endif #define FSSTDIO_OpenTemp FS_OpenTemp +#endif typedef struct { vfsfile_t funcs; @@ -118,6 +123,8 @@ vfsfile_t *VFSSTDIO_Open(const char *osname, const char *mode) return (vfsfile_t*)file; } + +#ifndef WEBSVONLY static vfsfile_t *FSSTDIO_OpenVFS(void *handle, flocation_t *loc, const char *mode) { char diskname[MAX_OSPATH]; @@ -131,7 +138,7 @@ static vfsfile_t *FSSTDIO_OpenVFS(void *handle, flocation_t *loc, const char *mo static void FSSTDIO_PrintPath(void *handle) { - Con_Printf("%s\n", handle); + Con_Printf("%s\n", (char*)handle); } static void FSSTDIO_ClosePath(void *handle) { @@ -230,3 +237,4 @@ searchpathfuncs_t stdiofilefuncs = { NULL, FSSTDIO_OpenVFS }; +#endif diff --git a/engine/common/fs_zip.c b/engine/common/fs_zip.c index f6d0c9ed..c57a4b40 100644 --- a/engine/common/fs_zip.c +++ b/engine/common/fs_zip.c @@ -6,10 +6,6 @@ #include #include "unzip.c" -#ifdef _WIN32 -#pragma comment( lib, "../libs/zlib.lib" ) -#endif - typedef struct { char name[MAX_QPATH]; diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index 7c4be002..f13fb620 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -1,11 +1,8 @@ #include "quakedef.h" -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h" -#include "shader.h" -#endif -#ifdef D3DQUAKE -#include "d3dquake.h" #endif +#include "com_mesh.h" #define MAX_Q3MAP_INDICES 0x80000 #define MAX_Q3MAP_VERTEXES 0x80000 @@ -22,18 +19,18 @@ #define Q3SURF_SKIP 0x200 // completely ignore, allowing non-closed brushes #define Q3SURF_NONSOLID 0x4000 // don't collide against curves with this set -#if Q3SURF_NODRAW != SURF_NODRAW +#if Q3SURF_NODRAW != TI_NODRAW #error "nodraw isn't constant" #endif extern cvar_t r_shadow_bumpscale_basetexture; //these are in model.c (or gl_model.c) -qboolean GLMod_LoadVertexes (lump_t *l); -qboolean GLMod_LoadEdges (lump_t *l); -qboolean GLMod_LoadMarksurfaces (lump_t *l); -qboolean GLMod_LoadSurfedges (lump_t *l); -void GLMod_LoadLighting (lump_t *l); +qboolean RMod_LoadVertexes (lump_t *l); +qboolean RMod_LoadEdges (lump_t *l); +qboolean RMod_LoadMarksurfaces (lump_t *l); +qboolean RMod_LoadSurfedges (lump_t *l); +void RMod_LoadLighting (lump_t *l); qboolean SWMod_LoadVertexes (lump_t *l); qboolean SWMod_LoadEdges (lump_t *l); @@ -48,7 +45,6 @@ qboolean CM_NativeTrace(model_t *model, int forcehullnum, int frame, vec3_t star unsigned int CM_NativeContents(struct model_s *model, int hulloverride, int frame, vec3_t p, vec3_t mins, vec3_t maxs); unsigned int Q2BSP_PointContents(model_t *mod, vec3_t p); -qbyte areabits[MAX_Q2MAP_AREAS/8]; extern char loadname[32]; @@ -333,15 +329,16 @@ int c_pointcontents; int c_traces, c_brush_traces; -vec3_t *map_verts; //3points +vecV_t *map_verts; //3points int numvertexes; vec2_t *map_vertstmexcoords; vec2_t *map_vertlstmexcoords; -byte_vec4_t *map_colors_array; +vec4_t *map_colors4f_array; vec3_t *map_normals_array; +vec3_t *map_svector_array; +vec3_t *map_tvector_array; -#ifdef Q3SHADERS typedef struct { char shader[MAX_QPATH]; int brushNum; @@ -350,7 +347,6 @@ typedef struct { mfog_t *map_fogs; int map_numfogs; -#endif q3cface_t *map_faces; int numfaces; @@ -425,12 +421,6 @@ qboolean BoundsIntersect (vec3_t mins1, vec3_t maxs1, vec3_t mins2, vec3_t maxs2 maxs1[0] >= mins2[0] && maxs1[1] >= mins2[1] && maxs1[2] >= mins2[2]); } - -#define VectorAvg(a,b,c) ((c)[0]=((a)[0]+(b)[0])*0.5f,(c)[1]=((a)[1]+(b)[1])*0.5f, (c)[2]=((a)[2]+(b)[2])*0.5f) -#define Vector4Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3]) -#define Vector4Scale(in,scale,out) ((out)[0]=(in)[0]*scale,(out)[1]=(in)[1]*scale,(out)[2]=(in)[2]*scale,(out)[3]=(in)[3]*scale) -#define Vector4Add(a,b,c) ((c)[0]=(((a[0])+(b[0]))),(c)[1]=(((a[1])+(b[1]))),(c)[2]=(((a[2])+(b[2]))),(c)[3]=(((a[3])+(b[3])))) - /* =============== Patch_FlatnessTest @@ -1032,17 +1022,19 @@ qbyte *ReadTargaFile(qbyte *buf, int length, int *width, int *height, int asgrey qbyte *ReadTargaFile(qbyte *buf, int length, int *width, int *height, int asgrey); qbyte *ReadPCXFile(qbyte *buf, int length, int *width, int *height); -void *Mod_LoadWall(char *name) +texture_t *Mod_LoadWall(char *name) { qbyte *in, *oin; texture_t *tex; q2miptex_t *wal; - int width, height; + int j; char ln[32]; + texnums_t tn; + memset(&tn, 0, sizeof(tn)); COM_FileBase(name, ln, sizeof(ln)); - wal = (void *)COM_LoadMallocFile (name); + wal = (void *)FS_LoadMallocFile (name); if (!wal) { //they will download eventually... @@ -1063,73 +1055,36 @@ void *Mod_LoadWall(char *name) wal->contents = LittleLong(wal->contents); wal->value = LittleLong(wal->value); -//FIXME: Is this needed? - oin = in = ReadPCXFile((qbyte *)wal, com_filesize, &width, &height); - if (!in) - oin = in = ReadTargaFile((qbyte *)wal, com_filesize, &width, &height, false); - if (in) //this is a pcx. + tex = Hunk_AllocName(sizeof(texture_t), ln); + + tex->offsets[0] = wal->offsets[0]; + tex->width = wal->width; + tex->height = wal->height; + + tn.base = R_LoadReplacementTexture(wal->name, loadname, IF_NOALPHA); + if (!TEXVALID(tn.base)) { -#ifdef RGLQUAKE - if (qrenderer == QR_OPENGL || qrenderer == QR_DIRECT3D) - { - tex = Hunk_AllocName(sizeof(texture_t), ln); - - tex->offsets[0] = sizeof(*tex); - tex->width = width; - tex->height = height; - - if (!(tex->tn.base = Mod_LoadReplacementTexture(name, loadname, true, false, true))) - if (!(tex->tn.base = Mod_LoadReplacementTexture(name, "bmodels", true, false, true))) - tex->tn.base = GL_LoadTexture32 (name, width, height, (unsigned int *)in, true, false); - } - else -#endif - { - Sys_Error("Mod_LoadWall with bad renderer\n"); - tex = NULL; - } - - BZ_Free(oin); - BZ_Free(wal); - - return tex; + tn.base = R_LoadReplacementTexture(wal->name, "bmodels", IF_NOALPHA); + if (!TEXVALID(tn.base)) + tn.base = R_LoadTexture8Pal24 (wal->name, tex->width, tex->height, (qbyte *)wal+wal->offsets[0], d_q28to24table, IF_NOALPHA|IF_NOGAMMA); } -#if defined(RGLQUAKE) || defined(D3DQUAKE) - if (qrenderer == QR_OPENGL || qrenderer == QR_DIRECT3D) - { - int j; - tex = Hunk_AllocName(sizeof(texture_t), ln); - - tex->offsets[0] = wal->offsets[0]; - tex->width = wal->width; - tex->height = wal->height; - - if (!(tex->tn.base = Mod_LoadReplacementTexture(wal->name, loadname, true, false, true))) - if (!(tex->tn.base = Mod_LoadReplacementTexture(wal->name, "bmodels", true, false, true))) - tex->tn.base = R_LoadTexture8Pal24 (wal->name, tex->width, tex->height, (qbyte *)wal+wal->offsets[0], d_q28to24table, true, false); - - in = Hunk_TempAllocMore(wal->width*wal->height); - oin = (qbyte *)wal+wal->offsets[0]; - for (j = 0; j < wal->width*wal->height; j++) - in[j] = (d_q28to24table[oin[j]*3+0] + d_q28to24table[oin[j]*3+1] + d_q28to24table[oin[j]*3+2])/3; - tex->tn.bump = R_LoadTexture8Bump (va("%s_bump", wal->name), tex->width, tex->height, in, true, r_shadow_bumpscale_basetexture.value); - } - else -#endif - { - Sys_Error("Mod_LoadWall with bad renderer\n"); - tex = NULL; - } + in = Hunk_TempAllocMore(wal->width*wal->height); + oin = (qbyte *)wal+wal->offsets[0]; + for (j = 0; j < wal->width*wal->height; j++) + in[j] = (d_q28to24table[oin[j]*3+0] + d_q28to24table[oin[j]*3+1] + d_q28to24table[oin[j]*3+2])/3; + tn.bump = R_LoadTexture8Bump (va("%s_bump", wal->name), tex->width, tex->height, in, true, r_shadow_bumpscale_basetexture.value); BZ_Free(wal); + tex->shader = R_RegisterShader_Lightmap(name); + R_BuildDefaultTexnums(&tn, tex->shader); + return tex; } qboolean CMod_LoadTexInfo (lump_t *l) //yes I know these load from the same place { - extern cvar_t gl_shadeq2; q2texinfo_t *in; mtexinfo_t *out; int i, j, count; @@ -1152,10 +1107,6 @@ qboolean CMod_LoadTexInfo (lump_t *l) //yes I know these load from the same plac loadmodel->texinfo = out; loadmodel->numtexinfo = count; -#if !defined(SERVERONLY) && (defined(RGLQUAKE) || defined(D3DQUAKE)) - skytexturenum = -1; -#endif - for ( i=0 ; iflags = LittleLong (in->flags); @@ -1174,7 +1125,7 @@ qboolean CMod_LoadTexInfo (lump_t *l) //yes I know these load from the same plac else out->mipadjust = 1; - //damn q2... + //damn q2... compact the textures. for (j=0; j < texcount; j++) { if (!strcmp(in->texture, loadmodel->textures[j]->name)) @@ -1203,38 +1154,13 @@ qboolean CMod_LoadTexInfo (lump_t *l) //yes I know these load from the same plac // out->flags = 0; } -#ifdef RGLQUAKE - if (qrenderer == QR_OPENGL) - if (gl_shadeq2.value) - out->texture->shader = R_RegisterCustom (name, NULL, NULL); -#endif Q_strncpyz(out->texture->name, in->texture, sizeof(out->texture->name)); -#if !defined(SERVERONLY) && defined(RGLQUAKE) - if (out->flags & SURF_SKY) - skytexturenum = texcount; -#endif loadmodel->textures[texcount++] = out->texture; } -#if !defined(SERVERONLY) && defined(RGLQUAKE) - else if (out->flags & SURF_SKY && skytexturenum>=0) - out->texture = loadmodel->textures[skytexturenum]; -#endif } loadmodel->numtextures = texcount; - - // count animation frames - /* - for (i=0 ; itexinfo[i]; -// out->numframes = 1; -// for (step = out->next ; step && step != out ; step=step->next) -// out->numframes++; - } - */ - return true; } #endif @@ -1335,11 +1261,11 @@ qboolean CMod_LoadFaces (lump_t *l) out->texinfo = loadmodel->texinfo + ti; #ifndef SERVERONLY - if (out->texinfo->flags & SURF_SKY) + if (out->texinfo->flags & TI_SKY) { out->flags |= SURF_DRAWSKY; } - if (out->texinfo->flags & SURF_WARP) + if (out->texinfo->flags & TI_WARP) { out->flags |= SURF_DRAWTURB|SURF_DRAWTILED; } @@ -1354,7 +1280,7 @@ qboolean CMod_LoadFaces (lump_t *l) i = LittleLong(in->lightofs); if (i == -1) out->samples = NULL; -#ifdef RGLQUAKE +#ifdef GLQUAKE else if (qrenderer == QR_OPENGL || qrenderer == QR_DIRECT3D) out->samples = loadmodel->lightdata + i; #endif @@ -1363,7 +1289,7 @@ qboolean CMod_LoadFaces (lump_t *l) // set the drawing flags - if (out->texinfo->flags & SURF_WARP) + if (out->texinfo->flags & TI_WARP) { out->flags |= SURF_DRAWTURB; for (i=0 ; i<2 ; i++) @@ -1550,6 +1476,7 @@ qboolean CMod_LoadLeafs (lump_t *l) out->cluster = (unsigned short)LittleShort (in->cluster); if (out->cluster == 0xffff) out->cluster = -1; + out->area = LittleShort (in->area); out->firstleafbrush = (unsigned short)LittleShort (in->firstleafbrush); out->numleafbrushes = (unsigned short)LittleShort (in->numleafbrushes); @@ -1965,7 +1892,7 @@ qboolean CModQ3_LoadSubmodels (lump_t *l) return true; } -qboolean CModQ3_LoadShaders (lump_t *l, qboolean useshaders) +qboolean CModQ3_LoadShaders (lump_t *l) { dq3shader_t *in; q2mapsurface_t *out; @@ -1990,10 +1917,6 @@ qboolean CModQ3_LoadShaders (lump_t *l, qboolean useshaders) numtexinfo = count; out = map_surfaces = Hunk_Alloc(count*sizeof(*out)); -#if !defined(SERVERONLY) && (defined(RGLQUAKE) || defined(D3DQUAKE)) - skytexturenum = -1; -#endif - loadmodel->texinfo = Hunk_Alloc(sizeof(mtexinfo_t)*count); loadmodel->numtextures = count; loadmodel->textures = Hunk_Alloc(sizeof(texture_t*)*count); @@ -2002,22 +1925,6 @@ qboolean CModQ3_LoadShaders (lump_t *l, qboolean useshaders) { loadmodel->texinfo[i].texture = Hunk_Alloc(sizeof(texture_t)); Q_strncpyz(loadmodel->texinfo[i].texture->name, in->shadername, sizeof(loadmodel->texinfo[i].texture->name)); -#if defined(RGLQUAKE) || defined(D3DQUAKE) - if ((qrenderer == QR_OPENGL || qrenderer == QR_DIRECT3D) && !useshaders) - { - loadmodel->texinfo[i].texture->tn.base = Mod_LoadHiResTexture(in->shadername, loadname, true, false, true); - if (!loadmodel->texinfo[i].texture->tn.base) - loadmodel->texinfo[i].texture->tn.base = Mod_LoadHiResTexture(in->shadername, "bmodels", true, false, true); - loadmodel->texinfo[i].texture->tn.fullbright = 0; - loadmodel->texinfo[i].texture->tn.bump = 0; - - if (!strncmp(in->shadername, "textures/skies/", 15)) - { - loadmodel->texinfo[i].flags |= SURF_SKY; - skytexturenum = i; - } - } -#endif loadmodel->textures[i] = loadmodel->texinfo[i].texture; out->c.flags = LittleLong ( in->surfflags ); @@ -2030,11 +1937,11 @@ qboolean CModQ3_LoadShaders (lump_t *l, qboolean useshaders) qboolean CModQ3_LoadVertexes (lump_t *l) { q3dvertex_t *in; - vec3_t *out; - vec3_t *nout; + vecV_t *out; + vec3_t *nout, *sout, *tout; int i, count, j; vec2_t *lmout, *stout; - byte_vec4_t *cout; + vec4_t *cout; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) @@ -2055,11 +1962,15 @@ qboolean CModQ3_LoadVertexes (lump_t *l) lmout = Hunk_Alloc ( count*sizeof(*lmout) ); cout = Hunk_Alloc ( count*sizeof(*cout) ); nout = Hunk_Alloc ( count*sizeof(*nout) ); + sout = Hunk_Alloc ( count*sizeof(*nout) ); + tout = Hunk_Alloc ( count*sizeof(*nout) ); map_verts = out; map_vertstmexcoords = stout; map_vertlstmexcoords = lmout; - map_colors_array = cout; + map_colors4f_array = cout; map_normals_array = nout; + map_svector_array = sout; + map_tvector_array = tout; numvertexes = count; for ( i=0 ; icolor[j]; + cout[i][j] = in->color[j]/255.0f; } } @@ -2086,11 +1997,11 @@ qboolean CModQ3_LoadVertexes (lump_t *l) qboolean CModRBSP_LoadVertexes (lump_t *l) { rbspvertex_t *in; - vec3_t *out; - vec3_t *nout; + vecV_t *out; + vec3_t *nout, *sout, *tout; int i, count, j; vec2_t *lmout, *stout; - byte_vec4_t *cout; + vec4_t *cout; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) @@ -2111,11 +2022,15 @@ qboolean CModRBSP_LoadVertexes (lump_t *l) lmout = Hunk_Alloc ( count*sizeof(*lmout) ); cout = Hunk_Alloc ( count*sizeof(*cout) ); nout = Hunk_Alloc ( count*sizeof(*nout) ); + sout = Hunk_Alloc ( count*sizeof(*sout) ); + tout = Hunk_Alloc ( count*sizeof(*tout) ); map_verts = out; map_vertstmexcoords = stout; map_vertlstmexcoords = lmout; - map_colors_array = cout; + map_colors4f_array = cout; map_normals_array = nout; + map_svector_array = sout; + map_tvector_array = tout; numvertexes = count; for ( i=0 ; ivisibleSide ); out->visibleplane = visibleside->plane; - out->shader = R_RegisterShader ( in->shader ); + out->shader = R_RegisterShader_Lightmap ( in->shader ); + R_BuildDefaultTexnums(&out->shader->defaulttextures, out->shader); out->numplanes = brush->numsides; out->planes = Hunk_Alloc ( out->numplanes*sizeof(cplane_t *) ); @@ -2336,56 +2251,11 @@ mfog_t *CM_FogForOrigin(vec3_t org) return NULL; } -#endif //Convert a patch in to a list of glpolys #define MAX_ARRAY_VERTS 2048 - -glpoly_t *GL_MeshToGLPoly(mesh_t *mesh) -{ - int polysize = sizeof(glpoly_t) - (VERTEXSIZE)*sizeof(float); - int gv; - int v; - int rv; - glpoly_t *p, *ret; - - int numindx; - if (!mesh) - return NULL; - - numindx = mesh->numindexes; - ret = NULL; - - p = Hunk_Alloc(polysize * numindx/3); - - for (gv = 0; gv < numindx; ) - { - for (v = gv; v < gv+3; v++) - { - rv = mesh->indexes[v]; - p->verts[v%3][0] = mesh->xyz_array[rv][0]; - p->verts[v%3][1] = mesh->xyz_array[rv][1]; - p->verts[v%3][2] = mesh->xyz_array[rv][2]; - p->verts[v%3][3] = mesh->st_array[rv][0]; - p->verts[v%3][4] = mesh->st_array[rv][1]; - p->verts[v%3][5] = mesh->lmst_array[rv][0]; - p->verts[v%3][6] = mesh->lmst_array[rv][1]; - } - gv+=3; - - p->next = ret; - p->numverts = 3; - ret = p; - p = (glpoly_t *)((char *)p + polysize); - } - - return ret; -} - -#define Vector2Copy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];} - index_t tempIndexesArray[MAX_ARRAY_VERTS*3]; vec4_t tempxyz_array[MAX_ARRAY_VERTS]; //structure is used only at load. vec3_t tempnormals_array[MAX_ARRAY_VERTS]; //so what harm is there in doing this? @@ -2393,17 +2263,13 @@ vec2_t tempst_array[MAX_ARRAY_VERTS]; vec2_t templmst_array[MAX_ARRAY_VERTS]; byte_vec4_t tempcolors_array[MAX_ARRAY_VERTS]; -#ifdef Q3SHADERS -#define Hunk_TempAllocMore Hunk_Alloc -#endif - //mesh_t *GL_CreateMeshForPatch ( model_t *mod, q3dface_t *surf ) mesh_t *GL_CreateMeshForPatch (model_t *mod, int patchwidth, int patchheight, int numverts, int firstvert) { int numindexes, patch_cp[2], step[2], size[2], flat[2], i, u, v, p; vec4_t colors[MAX_ARRAY_VERTS], points[MAX_ARRAY_VERTS], normals[MAX_ARRAY_VERTS], lm_st[MAX_ARRAY_VERTS], tex_st[MAX_ARRAY_VERTS]; - vec4_t c, colors2[MAX_ARRAY_VERTS], points2[MAX_ARRAY_VERTS], normals2[MAX_ARRAY_VERTS], lm_st2[MAX_ARRAY_VERTS], tex_st2[MAX_ARRAY_VERTS]; + vec4_t colors2[MAX_ARRAY_VERTS], points2[MAX_ARRAY_VERTS], normals2[MAX_ARRAY_VERTS], lm_st2[MAX_ARRAY_VERTS], tex_st2[MAX_ARRAY_VERTS]; mesh_t *mesh; index_t *indexes; float subdivlevel; @@ -2423,7 +2289,7 @@ mesh_t *GL_CreateMeshForPatch (model_t *mod, int patchwidth, int patchheight, in for ( i = 0; i < numverts; i++ ) { VectorCopy ( map_verts[firstvert + i], points[i] ); VectorCopy ( map_normals_array[firstvert + i], normals[i] ); - Vector4Scale ( map_colors_array[firstvert + i], (1.0 / 255.0), colors[i] ); + Vector4Copy ( map_colors4f_array[firstvert + i], colors[i] ); Vector2Copy ( map_vertstmexcoords[firstvert + i], tex_st[i] ); Vector2Copy ( map_vertlstmexcoords[firstvert + i], lm_st[i] ); } @@ -2442,17 +2308,16 @@ mesh_t *GL_CreateMeshForPatch (model_t *mod, int patchwidth, int patchheight, in return NULL; } - mesh = (mesh_t *)Hunk_TempAllocMore ( sizeof(mesh_t)); + mesh = (mesh_t *)Hunk_Alloc ( sizeof(mesh_t)); mesh->numvertexes = numverts; - mesh->xyz_array = Hunk_TempAllocMore ( numverts * sizeof(vec3_t)); - mesh->normals_array = Hunk_TempAllocMore ( numverts * sizeof(vec3_t)); - mesh->st_array = Hunk_TempAllocMore ( numverts * sizeof(vec2_t)); - mesh->lmst_array = Hunk_TempAllocMore ( numverts * sizeof(vec2_t)); - mesh->colors_array = Hunk_TempAllocMore ( numverts * sizeof(byte_vec4_t)); - - mesh->patchWidth = size[0]; - mesh->patchHeight = size[1]; + mesh->xyz_array = Hunk_Alloc ( numverts * sizeof(vec3_t)); + mesh->normals_array = Hunk_Alloc ( numverts * sizeof(vec3_t)); + mesh->snormals_array = Hunk_Alloc ( numverts * sizeof(vec3_t)); + mesh->tnormals_array = Hunk_Alloc ( numverts * sizeof(vec3_t)); + mesh->st_array = Hunk_Alloc ( numverts * sizeof(vec2_t)); + mesh->lmst_array = Hunk_Alloc ( numverts * sizeof(vec2_t)); + mesh->colors4f_array = Hunk_Alloc ( numverts * sizeof(vec4_t)); // fill in Patch_Evaluate ( (const vec4_t *)points, patch_cp, step, points2 ); @@ -2465,8 +2330,7 @@ mesh_t *GL_CreateMeshForPatch (model_t *mod, int patchwidth, int patchheight, in { VectorCopy ( points2[i], mesh->xyz_array[i] ); VectorNormalize2 ( normals2[i], mesh->normals_array[i] ); - ColorNormalize ( colors2[i], c ); - Vector4Scale ( c, 255.0, mesh->colors_array[i] ); + ColorNormalize ( colors2[i], mesh->colors4f_array[i] ); Vector2Copy ( tex_st2[i], mesh->st_array[i] ); Vector2Copy ( lm_st2[i], mesh->lmst_array[i] ); } @@ -2505,24 +2369,19 @@ mesh_t *GL_CreateMeshForPatch (model_t *mod, int patchwidth, int patchheight, in // allocate and fill index table mesh->numindexes = numindexes; - mesh->indexes = (index_t *)Hunk_TempAllocMore ( numindexes * sizeof(index_t)); + mesh->indexes = (index_t *)Hunk_Alloc ( numindexes * sizeof(index_t)); memcpy (mesh->indexes, tempIndexesArray, numindexes * sizeof(index_t) ); return mesh; } -#ifdef Q3SHADERS -#undef Hunk_TempAllocMore -#endif - void CModQ3_SortShaders(void) { texture_t *textemp; int i, j; - //sort loadmodel->textures - //correct pointers in loadmodel->texinfo + //sort loadmodel->textures for (i = 0; i < numtexinfo; i++) { for (j = i+1; j < numtexinfo; j++) @@ -2532,25 +2391,14 @@ void CModQ3_SortShaders(void) textemp = loadmodel->textures[j]; loadmodel->textures[j] = loadmodel->textures[i]; loadmodel->textures[i] = textemp; - - if (skytexturenum==i) - skytexturenum=j; - else if (skytexturenum==j) - skytexturenum=i; } } } } mesh_t nullmesh; -qboolean CModQ3_LoadRFaces (lump_t *l, qboolean useshaders) +qboolean CModQ3_LoadRFaces (lump_t *l) { -#ifndef Q3SHADERS - int polysize = sizeof(glpoly_t) - VERTEXSIZE*sizeof(float); - glpoly_t *p; - int rv, fi; - int gv, v; -#endif q3dface_t *in; msurface_t *out; mplane_t *pl; @@ -2607,11 +2455,10 @@ qboolean CModQ3_LoadRFaces (lump_t *l, qboolean useshaders) //q3dm10's thingie is 0 out->flags |= SURF_DRAWALPHA; - if (loadmodel->texinfo[LittleLong(in->shadernum)].flags & SURF_SKY) + if (loadmodel->texinfo[LittleLong(in->shadernum)].flags & TI_SKY) out->flags |= SURF_DRAWSKY; -#ifdef Q3SHADERS - if (!out->texinfo->texture->shader && useshaders) + if (!out->texinfo->texture->shader) { extern cvar_t r_vertexlight; if (LittleLong(in->facetype) == MST_FLARE) @@ -2619,21 +2466,16 @@ qboolean CModQ3_LoadRFaces (lump_t *l, qboolean useshaders) else if (LittleLong(in->facetype) == MST_TRIANGLE_SOUP || r_vertexlight.value) out->texinfo->texture->shader = R_RegisterShader_Vertex (out->texinfo->texture->name); else - out->texinfo->texture->shader = R_RegisterShader(out->texinfo->texture->name); + out->texinfo->texture->shader = R_RegisterShader_Lightmap(out->texinfo->texture->name); - - if (out->texinfo->texture->shader->flags & SHADER_SKY) - { - out->texinfo->flags |= SURF_SKY; - skytexturenum = out->texinfo - loadmodel->texinfo; - } + R_BuildDefaultTexnums(&out->texinfo->texture->shader->defaulttextures, out->texinfo->texture->shader); } if (LittleLong(in->fognum) == -1 || !map_numfogs) out->fog = NULL; else out->fog = map_fogs + LittleLong(in->fognum); -#endif + if (map_surfaces[LittleLong(in->shadernum)].c.flags & (Q3SURF_NODRAW | Q3SURF_SKIP)) { out->mesh = &nullmesh; @@ -2641,6 +2483,8 @@ qboolean CModQ3_LoadRFaces (lump_t *l, qboolean useshaders) else if (LittleLong(in->facetype) == MST_PATCH) { out->mesh = GL_CreateMeshForPatch(loadmodel, LittleLong(in->patchwidth), LittleLong(in->patchheight), LittleLong(in->num_vertices), LittleLong(in->firstvertex)); + Mod_AccumulateMeshTextureVectors(out->mesh); + Mod_NormaliseTextureVectors(out->mesh->normals_array, out->mesh->snormals_array, out->mesh->tnormals_array, out->mesh->numvertexes); } else if (LittleLong(in->facetype) == MST_PLANAR || LittleLong(in->facetype) == MST_TRIANGLE_SOUP) { @@ -2652,14 +2496,12 @@ qboolean CModQ3_LoadRFaces (lump_t *l, qboolean useshaders) return false; } - out->mesh = Hunk_Alloc(sizeof(mesh_t) + (sizeof(vec3_t)) * numverts); + out->mesh = Hunk_Alloc(sizeof(mesh_t)); out->mesh->normals_array= map_normals_array + LittleLong(in->firstvertex); + out->mesh->snormals_array = map_svector_array + LittleLong(in->firstvertex); + out->mesh->tnormals_array = map_tvector_array + LittleLong(in->firstvertex); -#pragma message("s/t vectors not calculated for q3bsp") - out->mesh->snormals_array = out->mesh->normals_array; - out->mesh->tnormals_array = out->mesh->normals_array; - - out->mesh->colors_array = map_colors_array + LittleLong(in->firstvertex); + out->mesh->colors4f_array = map_colors4f_array + LittleLong(in->firstvertex); out->mesh->indexes = map_surfindexes + LittleLong(in->firstindex); out->mesh->xyz_array = map_verts + LittleLong(in->firstvertex); out->mesh->st_array = map_vertstmexcoords + LittleLong(in->firstvertex); @@ -2667,14 +2509,22 @@ qboolean CModQ3_LoadRFaces (lump_t *l, qboolean useshaders) out->mesh->numindexes = numindexes; out->mesh->numvertexes = numverts; + + if (LittleLong(in->facetype) == MST_PLANAR) + if (out->mesh->numindexes == (out->mesh->numvertexes-2)*3) + out->mesh->istrifan = true; + + Mod_AccumulateMeshTextureVectors(out->mesh); } else { + //flare + // int r, g, b; extern index_t r_quad_indexes[6]; mesh = out->mesh = (mesh_t *)Hunk_Alloc ( sizeof(mesh_t)); - mesh->xyz_array = (vec3_t *)Hunk_Alloc ( sizeof(vec3_t)); + mesh->xyz_array = (vecV_t *)Hunk_Alloc ( sizeof(vecV_t)); mesh->numvertexes = 1; mesh->indexes = r_quad_indexes; mesh->numindexes = 6; @@ -2694,20 +2544,15 @@ qboolean CModQ3_LoadRFaces (lump_t *l, qboolean useshaders) */ } } - if (useshaders) - CModQ3_SortShaders(); + Mod_NormaliseTextureVectors(map_normals_array, map_svector_array, map_tvector_array, numvertexes); + + CModQ3_SortShaders(); return true; } -qboolean CModRBSP_LoadRFaces (lump_t *l, qboolean useshaders) +qboolean CModRBSP_LoadRFaces (lump_t *l) { -#ifndef Q3SHADERS - int polysize = sizeof(glpoly_t) - VERTEXSIZE*sizeof(float); - glpoly_t *p; - int rv, fi; - int gv, v; -#endif rbspface_t *in; msurface_t *out; mplane_t *pl; @@ -2766,11 +2611,11 @@ qboolean CModRBSP_LoadRFaces (lump_t *l, qboolean useshaders) //q3dm10's thingie is 0 out->flags |= SURF_DRAWALPHA; - if (loadmodel->texinfo[in->shadernum].flags & SURF_SKY) + if (loadmodel->texinfo[in->shadernum].flags & TI_SKY) out->flags |= SURF_DRAWSKY; #ifdef Q3SHADERS - if (!out->texinfo->texture->shader && useshaders) + if (!out->texinfo->texture->shader) { extern cvar_t r_vertexlight; if (in->facetype == MST_FLARE) @@ -2778,7 +2623,9 @@ qboolean CModRBSP_LoadRFaces (lump_t *l, qboolean useshaders) else if (in->facetype == MST_TRIANGLE_SOUP || r_vertexlight.value) out->texinfo->texture->shader = R_RegisterShader_Vertex (out->texinfo->texture->name); else - out->texinfo->texture->shader = R_RegisterShader(out->texinfo->texture->name); + out->texinfo->texture->shader = R_RegisterShader_Lightmap(out->texinfo->texture->name); + + R_BuildDefaultTexnums(&out->texinfo->texture->shader->defaulttextures, out->texinfo->texture->shader); } if (in->fognum < 0 || in->fognum >= map_numfogs) @@ -2808,7 +2655,7 @@ qboolean CModRBSP_LoadRFaces (lump_t *l, qboolean useshaders) out->mesh = Hunk_Alloc(sizeof(mesh_t) + (sizeof(vec3_t)) * numverts); out->mesh->normals_array= map_normals_array + LittleLong(in->firstvertex); - out->mesh->colors_array = map_colors_array + LittleLong(in->firstvertex); + out->mesh->colors4f_array = map_colors4f_array + LittleLong(in->firstvertex); out->mesh->indexes = map_surfindexes + LittleLong(in->firstindex); out->mesh->xyz_array = map_verts + LittleLong(in->firstvertex); out->mesh->st_array = map_vertstmexcoords + LittleLong(in->firstvertex); @@ -2823,7 +2670,7 @@ qboolean CModRBSP_LoadRFaces (lump_t *l, qboolean useshaders) extern index_t r_quad_indexes[6]; mesh = out->mesh = (mesh_t *)Hunk_Alloc ( sizeof(mesh_t)); - mesh->xyz_array = (vec3_t *)Hunk_Alloc ( sizeof(vec3_t)); + mesh->xyz_array = (vecV_t *)Hunk_Alloc ( sizeof(vecV_t)); mesh->numvertexes = 1; mesh->indexes = r_quad_indexes; mesh->numindexes = 6; @@ -2842,8 +2689,7 @@ qboolean CModRBSP_LoadRFaces (lump_t *l, qboolean useshaders) */ } } - if (useshaders) - CModQ3_SortShaders(); + CModQ3_SortShaders(); return true; } @@ -3355,7 +3201,8 @@ qboolean CModRBSP_LoadLightgrid (lump_t *elements, lump_t *indexes) qbyte *ReadPCXPalette(qbyte *buf, int len, qbyte *out); int CM_GetQ2Palette (void) { - char *f = (void *)COM_LoadMallocFile("pics/colormap.pcx"); + char *f; + FS_LoadFile("pics/colormap.pcx", &f); if (!f) { Con_Printf (CON_WARNING "Couldn't find pics/colormap.pcx\n"); @@ -3364,13 +3211,13 @@ int CM_GetQ2Palette (void) if (!ReadPCXPalette(f, com_filesize, d_q28to24table)) { Con_Printf (CON_WARNING "Couldn't read pics/colormap.pcx\n"); - BZ_Free(f); + FS_FreeFile(f); return -1; } - BZ_Free(f); + FS_FreeFile(f); -#if defined(RGLQUAKE) || defined(D3DQUAKE) +#if defined(GLQUAKE) || defined(D3DQUAKE) { float inf; qbyte palette[768]; @@ -3471,7 +3318,7 @@ void CMQ3_CalcPHS (void) vcount = 0; for (i=0 ; i>3] & (1<<(j&7)) ) @@ -3584,7 +3431,7 @@ void Q2BSP_MarkLights (dlight_t *light, int bit, mnode_t *node) } #ifndef SERVERONLY -#ifdef RGLQUAKE +#ifdef GLQUAKE void GLR_StainSurf (msurface_t *surf, float *parms); void GLR_Q2BSP_StainNode (mnode_t *node, float *parms) { @@ -3627,11 +3474,6 @@ void GLR_Q2BSP_StainNode (mnode_t *node, float *parms) #endif -#ifndef CLIENTONLY -unsigned int Q2BSP_FatPVS (model_t *mod, vec3_t org, qbyte *buffer, unsigned int buffersize, qboolean add); -qboolean Q2BSP_EdictInFatPVS(model_t *mod, edict_t *ent, qbyte *pvs); -void Q2BSP_FindTouchedLeafs(model_t *mod, edict_t *ent, float *mins, float *maxs); -#endif void GLQ2BSP_LightPointValues(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir); void SWQ2BSP_LightPointValues(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir); @@ -3649,7 +3491,6 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned q2dheader_t header; int length; static unsigned last_checksum; - qboolean useshaders; qboolean noerrors = true; int start; @@ -3697,7 +3538,7 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned switch(header.version) { default: - Con_Printf (CON_ERROR "Quake 2 or Quake 3 based BSP with unknown header (%i should be %i or %i)\n" + Con_Printf (CON_ERROR "Quake 2 or Quake 3 based BSP with unknown header (%s: %i should be %i or %i)\n" , name, header.version, Q2BSPVERSION, Q3BSPVERSION); return NULL; break; @@ -3705,16 +3546,6 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned case 1: //rbsp case Q3BSPVERSION+1: //rtcw case Q3BSPVERSION: - -#ifdef Q3SHADERS - { - extern cvar_t gl_shadeq3; - useshaders = qrenderer == QR_OPENGL && gl_shadeq3.value; - } -#else - useshaders = false; -#endif - mapisq3 = true; loadmodel->fromgame = fg_quake3; for (i=0 ; ifuncs.LeafPVS = CM_LeafnumPVS; loadmodel->funcs.LeafnumForPoint = CM_PointLeafnum; -#if defined(RGLQUAKE) || defined(D3DQUAKE) +#if defined(GLQUAKE) || defined(D3DQUAKE) loadmodel->funcs.LightPointValues = GLQ3_LightGrid; loadmodel->funcs.StainNode = GLR_Q2BSP_StainNode; loadmodel->funcs.MarkLights = Q2BSP_MarkLights; @@ -3937,15 +3768,15 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned loadmodel->funcs.NativeContents = CM_NativeContents; break; -#if defined(RGLQUAKE) +#if defined(GLQUAKE) case QR_OPENGL: // load into heap #ifndef SERVERONLY - noerrors = noerrors && GLMod_LoadVertexes (&header.lumps[Q2LUMP_VERTEXES]); - noerrors = noerrors && GLMod_LoadEdges (&header.lumps[Q2LUMP_EDGES]); - noerrors = noerrors && GLMod_LoadSurfedges (&header.lumps[Q2LUMP_SURFEDGES]); + noerrors = noerrors && RMod_LoadVertexes (&header.lumps[Q2LUMP_VERTEXES]); + noerrors = noerrors && RMod_LoadEdges (&header.lumps[Q2LUMP_EDGES]); + noerrors = noerrors && RMod_LoadSurfedges (&header.lumps[Q2LUMP_SURFEDGES]); if (noerrors) - GLMod_LoadLighting (&header.lumps[Q2LUMP_LIGHTING]); + RMod_LoadLighting (&header.lumps[Q2LUMP_LIGHTING]); #endif noerrors = noerrors && CMod_LoadSurfaces (&header.lumps[Q2LUMP_TEXINFO]); noerrors = noerrors && CMod_LoadLeafBrushes (&header.lumps[Q2LUMP_LEAFBRUSHES]); @@ -3953,7 +3784,7 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned #ifndef SERVERONLY noerrors = noerrors && CMod_LoadTexInfo (&header.lumps[Q2LUMP_TEXINFO]); noerrors = noerrors && CMod_LoadFaces (&header.lumps[Q2LUMP_FACES]); - noerrors = noerrors && GLMod_LoadMarksurfaces (&header.lumps[Q2LUMP_LEAFFACES]); + noerrors = noerrors && RMod_LoadMarksurfaces (&header.lumps[Q2LUMP_LEAFFACES]); #endif noerrors = noerrors && CMod_LoadVisibility (&header.lumps[Q2LUMP_VISIBILITY]); noerrors = noerrors && CMod_LoadBrushes (&header.lumps[Q2LUMP_BRUSHES]); @@ -4819,7 +4650,6 @@ void CM_TestBoxInBrush (vec3_t mins, vec3_t maxs, vec3_t p1, // inside this brush trace->startsolid = trace->allsolid = true; - trace->fraction = 0; trace->contents |= brush->contents; } @@ -4875,7 +4705,6 @@ void CM_TestBoxInPatch (vec3_t mins, vec3_t maxs, vec3_t p1, // inside this patch trace->startsolid = trace->allsolid = true; - trace->fraction = 0; trace->contents = brush->contents; } diff --git a/engine/common/mathlib.c b/engine/common/mathlib.c index 43634ed4..34d4b340 100644 --- a/engine/common/mathlib.c +++ b/engine/common/mathlib.c @@ -408,7 +408,7 @@ void AngleVectors (const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up) } } -int VectorCompare (vec3_t v1, vec3_t v2) +int VectorCompare (const vec3_t v1, const vec3_t v2) { int i; @@ -526,13 +526,6 @@ void VectorInverse (vec3_t v) v[2] = -v[2]; } -void VectorScale (vec3_t in, vec_t scale, vec3_t out) -{ - out[0] = in[0]*scale; - out[1] = in[1]*scale; - out[2] = in[2]*scale; -} - int Q_log2(int val) { @@ -732,11 +725,11 @@ fixed16_t Invert24To16(fixed16_t val) -void VectorTransform (const vec3_t in1, matrix3x4 in2, vec3_t out) +void VectorTransform (const vec3_t in1, const matrix3x4 in2, vec3_t out) { out[0] = DotProduct(in1, in2[0]) + in2[0][3]; - out[1] = DotProduct(in1, in2[1]) + in2[1][3]; - out[2] = DotProduct(in1, in2[2]) + in2[2][3]; + out[1] = DotProduct(in1, in2[1]) + in2[1][3]; + out[2] = DotProduct(in1, in2[2]) + in2[2][3]; } #ifdef HALFLIFEMODELS @@ -953,9 +946,9 @@ void Matrix4_ModelViewMatrix(float *modelview, vec3_t viewangles, vec3_t vieworg Matrix4_Multiply(tempmat, Matrix4_NewTranslation(-vieworg[0], -vieworg[1], -vieworg[2]), modelview); // put Z going up } -void Matrix4x4_CreateTranslate (matrix4x4_t *out, float x, float y, float z) +void Matrix4x4_CreateTranslate (float *out, float x, float y, float z) { - memcpy(out, Matrix4_NewTranslation(x, y, z), sizeof(*out)); + memcpy(out, Matrix4_NewTranslation(x, y, z), 16*sizeof(float)); } void Matrix4_ModelViewMatrixFromAxis(float *modelview, vec3_t pn, vec3_t right, vec3_t up, vec3_t vieworg) @@ -983,6 +976,42 @@ void Matrix4_ModelViewMatrixFromAxis(float *modelview, vec3_t pn, vec3_t right, } +void Matrix4x4_ToVectors(const matrix4x4_t *in, float vx[3], float vy[3], float vz[3], float t[3]) +{ + vx[0] = in->m[0][0]; + vx[1] = in->m[0][1]; + vx[2] = in->m[0][2]; + vy[0] = in->m[1][0]; + vy[1] = in->m[1][1]; + vy[2] = in->m[1][2]; + vz[0] = in->m[2][0]; + vz[1] = in->m[2][1]; + vz[2] = in->m[2][2]; + t [0] = in->m[3][0]; + t [1] = in->m[3][1]; + t [2] = in->m[3][2]; +} + +void Matrix4x4_FromVectors(matrix4x4_t *out, const float vx[3], const float vy[3], const float vz[3], const float t[3]) +{ + out->m[0][0] = vx[0]; + out->m[1][0] = vy[0]; + out->m[2][0] = vz[0]; + out->m[3][0] = t[0]; + out->m[0][1] = vx[1]; + out->m[1][1] = vy[1]; + out->m[2][1] = vz[1]; + out->m[3][1] = t[1]; + out->m[0][2] = vx[2]; + out->m[1][2] = vy[2]; + out->m[2][2] = vz[2]; + out->m[3][2] = t[2]; + out->m[0][3] = 0.0f; + out->m[1][3] = 0.0f; + out->m[2][3] = 0.0f; + out->m[3][3] = 1.0f; +} + void Matrix4_ModelMatrixFromAxis(float *modelview, vec3_t pn, vec3_t right, vec3_t up, vec3_t vieworg) { float tempmat[16]; @@ -1163,7 +1192,29 @@ void Matrix4_Orthographic(float *proj, float xmin, float xmax, float ymax, float proj[11] = 0; proj[15] = 1; } +void Matrix4_OrthographicD3D(float *proj, float xmin, float xmax, float ymax, float ymin, + float znear, float zfar) +{ + proj[0] = 2/(xmax-xmin); + proj[4] = 0; + proj[8] = 0; + proj[12] = (xmax+xmin)/(xmax-xmin); + proj[1] = 0; + proj[5] = 2/(ymax-ymin); + proj[9] = 0; + proj[13] = (ymax+ymin)/(ymax-ymin); + + proj[2] = 0; + proj[6] = 0; + proj[10] = -2/(zfar-znear); + proj[14] = (zfar+znear)/(zfar-znear); + + proj[3] = 0; + proj[7] = 0; + proj[11] = 0; + proj[15] = 1; +} /* * Compute inverse of 4x4 transformation matrix. * Code contributed by Jacques Leroy jle@star.be @@ -1450,7 +1501,7 @@ void Matrix3_Multiply (vec3_t *in1, vec3_t *in2, vec3_t *out) out[2][2] = in1[2][0]*in2[0][2] + in1[2][1]*in2[1][2] + in1[2][2]*in2[2][2]; } -vec_t VectorNormalize2 (vec3_t v, vec3_t out) +vec_t VectorNormalize2 (const vec3_t v, vec3_t out) { float length, ilength; diff --git a/engine/common/mathlib.h b/engine/common/mathlib.h index 16e31193..60530403 100644 --- a/engine/common/mathlib.h +++ b/engine/common/mathlib.h @@ -25,7 +25,24 @@ typedef vec_t vec3_t[3]; typedef vec_t vec4_t[4]; typedef vec_t vec5_t[5]; +/*16-byte aligned vectors, for auto-vectorising, should propogate to structs +sse and altivec can unroll loops using aligned reads, which should be faster... 4 at once. +*/ +#ifdef _MSC_VER +typedef __declspec(align(16)) vec3_t avec3_t; +typedef __declspec(align(16)) vec4_t avec4_t; +typedef __declspec(align(4)) qbyte byte_vec4_t[4]; +#elif __GNUC__ >= 3 +typedef __attribute__((aligned(16))) vec3_t avec3_t; +typedef __attribute__((aligned(16))) vec4_t avec4_t; +typedef __attribute__((aligned(4))) qbyte byte_vec4_t[4]; +#else +typedef vec3_t avec3_t; +typedef vec4_t avec4_t; typedef qbyte byte_vec4_t[4]; +#endif + +#define vecV_t avec4_t typedef int fixed4_t; typedef int fixed8_t; @@ -48,12 +65,21 @@ extern int nanmask; #define VectorSubtract(a,b,c) do{(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];}while(0) #define VectorAdd(a,b,c) do{(c)[0]=(a)[0]+(b)[0];(c)[1]=(a)[1]+(b)[1];(c)[2]=(a)[2]+(b)[2];}while(0) #define VectorCopy(a,b) do{(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];}while(0) +#define VectorScale(a,s,b) do{(b)[0]=(s)*(a)[0];(b)[1]=(s)*(a)[1];(b)[2]=(s)*(a)[2];}while(0) #define VectorClear(a) ((a)[0]=(a)[1]=(a)[2]=0) +#define VectorSet(r,x,y,z) {(r)[0] = x; (r)[1] = y;(r)[2] = z;} #define VectorNegate(a,b) ((b)[0]=-(a)[0],(b)[1]=-(a)[1],(b)[2]=-(a)[2]) #define VectorLength(a) Length(a) #define VectorMA(a,s,b,c) do{(c)[0] = (a)[0] + (s)*(b)[0];(c)[1] = (a)[1] + (s)*(b)[1];(c)[2] = (a)[2] + (s)*(b)[2];}while(0) #define VectorEquals(a,b) ((a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == (b)[2]) +#define VectorAvg(a,b,c) ((c)[0]=((a)[0]+(b)[0])*0.5f,(c)[1]=((a)[1]+(b)[1])*0.5f, (c)[2]=((a)[2]+(b)[2])*0.5f) +#define Vector2Copy(a,b) {(b)[0]=(a)[0];(b)[1]=(a)[1];} +#define Vector2Set(r,x,y) {(r)[0] = x; (r)[1] = y;} + +#define Vector4Copy(a,b) do{(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];(b)[3]=(a)[3];}while(0) +#define Vector4Scale(in,scale,out) ((out)[0]=(in)[0]*scale,(out)[1]=(in)[1]*scale,(out)[2]=(in)[2]*scale,(out)[3]=(in)[3]*scale) +#define Vector4Add(a,b,c) ((c)[0]=(((a[0])+(b[0]))),(c)[1]=(((a[1])+(b[1]))),(c)[2]=(((a[2])+(b[2]))),(c)[3]=(((a[3])+(b[3])))) typedef float matrix3x4[3][4]; typedef float matrix3x3[3][3]; @@ -105,10 +131,11 @@ float Q_rsqrt(float number); void Matrix3_Multiply (vec3_t *in1, vec3_t *in2, vec3_t *out); void Matrix4_Identity(float *outm); qboolean Matrix4_Invert(const float *m, float *out); -void Matrix4x4_CreateTranslate (matrix4x4_t *out, float x, float y, float z); +void Matrix4_CreateTranslate (float *out, float x, float y, float z); void Matrix4_ModelMatrixFromAxis (float *modelview, vec3_t pn, vec3_t right, vec3_t up, vec3_t vieworg); void Matrix4_ModelViewMatrix (float *modelview, vec3_t viewangles, vec3_t vieworg); void Matrix4_ModelViewMatrixFromAxis (float *modelview, vec3_t pn, vec3_t right, vec3_t up, vec3_t vieworg); +void Matrix4_CreateFromQuakeEntity (float *matrix, float x, float y, float z, float pitch, float yaw, float roll, float scale); void Matrix4_Multiply (float *a, float *b, float *out); void Matrix4_Project (vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float fovx, float fovy); void Matrix4_Transform3 (float *matrix, float *vector, float *product); @@ -132,12 +159,11 @@ void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]); void R_ConcatRotationsPad (float in1[3][4], float in2[3][4], float out[3][4]); void R_ConcatTransforms (matrix3x4 in1, matrix3x4 in2, matrix3x4 out); void RotatePointAroundVector (vec3_t dst, const vec3_t dir, const vec3_t point, float degrees); -int VectorCompare (vec3_t v1, vec3_t v2); +int VectorCompare (const vec3_t v1, const vec3_t v2); void VectorInverse (vec3_t v); void _VectorMA (const vec3_t veca, const float scale, const vec3_t vecb, vec3_t vecc); float VectorNormalize (vec3_t v); // returns vector length -vec_t VectorNormalize2 (vec3_t v, vec3_t out); +vec_t VectorNormalize2 (const vec3_t v, vec3_t out); void VectorNormalizeFast(vec3_t v); -void VectorScale (vec3_t in, vec_t scale, vec3_t out); -void VectorTransform (const vec3_t in1, matrix3x4 in2, vec3_t out); +void VectorTransform (const vec3_t in1, const matrix3x4 in2, vec3_t out); void VectorVectors (const vec3_t forward, vec3_t right, vec3_t up); diff --git a/engine/common/net.h b/engine/common/net.h index 025f261c..8dcbc4cf 100644 --- a/engine/common/net.h +++ b/engine/common/net.h @@ -100,6 +100,10 @@ char *NET_AdrToStringMasked (char *s, int len, netadr_t a, netadr_t amask); void NET_IntegerToMask (netadr_t *a, netadr_t *amask, int bits); qboolean NET_CompareAdrMasked(netadr_t a, netadr_t b, netadr_t mask); + +struct ftenet_generic_connection_s *FTENET_IRCConnect_EstablishConnection(qboolean isserver, const char *address); +qboolean FTENET_AddToCollection(struct ftenet_connections_s *col, const char *name, const char *address, struct ftenet_generic_connection_s *(*establish)(qboolean isserver, const char *address), qboolean islisten); + //============================================================================ #define OLD_AVG 0.99 // total = oldtotal*OLD_AVG + new*(1-OLD_AVG) @@ -171,12 +175,13 @@ extern int net_drop; // packets dropped before this one void Netchan_Init (void); int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate); void Netchan_OutOfBand (netsrc_t sock, netadr_t adr, int length, qbyte *data); -void VARGS Netchan_OutOfBandPrint (netsrc_t sock, netadr_t adr, char *format, ...); +void VARGS Netchan_OutOfBandPrint (netsrc_t sock, netadr_t adr, char *format, ...) LIKEPRINTF(3); void VARGS Netchan_OutOfBandTPrintf (netsrc_t sock, netadr_t adr, int language, translation_t text, ...); qboolean Netchan_Process (netchan_t *chan); void Netchan_Setup (netsrc_t sock, netchan_t *chan, netadr_t adr, int qport); qboolean Netchan_CanPacket (netchan_t *chan, int rate); +void Netchan_Block (netchan_t *chan, int bytes, int rate); qboolean Netchan_CanReliable (netchan_t *chan, int rate); #ifdef NQPROT nqprot_t NQNetChan_Process(netchan_t *chan); @@ -228,6 +233,7 @@ void Huff_EmitByte(int ch, qbyte *buffer, int *count); #endif int UDP_OpenSocket (int port, qboolean bcast); +int UDP6_OpenSocket (int port, qboolean bcast); int IPX_OpenSocket (int port, qboolean bcast); int NetadrToSockadr (netadr_t *a, struct sockaddr_qstorage *s); void SockadrToNetadr (struct sockaddr_qstorage *s, netadr_t *a); diff --git a/engine/common/net_wins.c b/engine/common/net_wins.c index 7840fd1c..5ea73872 100644 --- a/engine/common/net_wins.c +++ b/engine/common/net_wins.c @@ -2611,7 +2611,7 @@ void FTENET_IRCConnect_Close(ftenet_generic_connection_t *gcon) FTENET_Generic_Close(gcon); } -ftenet_generic_connection_t *FTENET_IRCConnect_EstablishConnection(qboolean isserver, const char *address) +struct ftenet_generic_connection_s *FTENET_IRCConnect_EstablishConnection(qboolean isserver, const char *address) { //this is written to support either ipv4 or ipv6, depending on the remote addr. ftenet_ircconnect_connection_t *newcon; diff --git a/engine/common/particles.h b/engine/common/particles.h index 91dcd528..6a8643a1 100644 --- a/engine/common/particles.h +++ b/engine/common/particles.h @@ -116,7 +116,6 @@ void P_EmitEffect (vec3_t pos, int type, trailstate_t **tsk);//this is just a wr #define P_DelinkTrailstate pe->DelinkTrailstate #define P_ClearParticles pe->ClearParticles #define P_DrawParticles pe->DrawParticles -#define P_FlushRenderer pe->FlushRenderer typedef struct { char *name1; @@ -143,7 +142,6 @@ typedef struct { void (*DelinkTrailstate) (trailstate_t **tsk); void (*ClearParticles) (void); void (*DrawParticles) (void); - void (*FlushRenderer) (void); } particleengine_t; extern particleengine_t *pe; diff --git a/engine/common/plugin.c b/engine/common/plugin.c index 3b74c973..5e16257c 100644 --- a/engine/common/plugin.c +++ b/engine/common/plugin.c @@ -98,7 +98,7 @@ qboolean Init_GNUTLS(void) {return true;} cvar_t plug_sbar = SCVAR("plug_sbar", "1"); cvar_t plug_loaddefault = SCVAR("plug_loaddefault", "1"); -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h" #endif @@ -1626,7 +1626,7 @@ void Plug_SBar(void) return; ret = 0; - if (!plug_sbar.value || cl.splitclients > 1) + if (!plug_sbar.ival || cl.splitclients > 1) currentplug = NULL; else { diff --git a/engine/common/pmove.h b/engine/common/pmove.h index 021d9b45..7a6cf51e 100644 --- a/engine/common/pmove.h +++ b/engine/common/pmove.h @@ -112,6 +112,7 @@ void PM_InitBoxHull (void); void PM_CategorizePosition (void); int PM_HullPointContents (hull_t *hull, int num, vec3_t p); +int PM_ExtraBoxContents (vec3_t p); //Peeks for HL-style water. int PM_PointContents (vec3_t point); qboolean PM_TestPlayerPosition (vec3_t point); #ifndef __cplusplus diff --git a/engine/common/pr_bgcmd.c b/engine/common/pr_bgcmd.c index 7f4e0301..936ef5a5 100644 --- a/engine/common/pr_bgcmd.c +++ b/engine/common/pr_bgcmd.c @@ -515,11 +515,11 @@ void PF_fopen (progfuncs_t *prinst, struct globalvars_s *pr_globals) switch (fmode) { case 0: //read - pf_fopen_files[i].data = COM_LoadMallocFile(pf_fopen_files[i].name); + pf_fopen_files[i].data = FS_LoadMallocFile(pf_fopen_files[i].name); if (!pf_fopen_files[i].data) { Q_strncpyz(pf_fopen_files[i].name, name, sizeof(pf_fopen_files[i].name)); - pf_fopen_files[i].data = COM_LoadMallocFile(pf_fopen_files[i].name); + pf_fopen_files[i].data = FS_LoadMallocFile(pf_fopen_files[i].name); } if (pf_fopen_files[i].data) @@ -534,7 +534,7 @@ void PF_fopen (progfuncs_t *prinst, struct globalvars_s *pr_globals) pf_fopen_files[i].ofs = 0; break; case 1: //append - pf_fopen_files[i].data = COM_LoadMallocFile(pf_fopen_files[i].name); + pf_fopen_files[i].data = FS_LoadMallocFile(pf_fopen_files[i].name); pf_fopen_files[i].ofs = pf_fopen_files[i].bufferlen = pf_fopen_files[i].len = com_filesize; if (pf_fopen_files[i].data) { @@ -736,7 +736,10 @@ void PF_whichpack (progfuncs_t *prinst, struct globalvars_s *pr_globals) if (FS_FLocateFile(srcname, FSLFRT_IFFOUND, &loc)) { - RETURN_TSTRING(FS_WhichPackForLocation(&loc)); + srcname = FS_WhichPackForLocation(&loc); + if (srcname == NULL) + srcname = ""; + RETURN_TSTRING(srcname); } else { diff --git a/engine/common/pr_common.h b/engine/common/pr_common.h index a811602c..ce4149f2 100644 --- a/engine/common/pr_common.h +++ b/engine/common/pr_common.h @@ -12,6 +12,37 @@ typedef struct edict_s { } edict_t; #endif +struct wedict_s +{ + qboolean isfree; + float freetime; // sv.time when the object was freed + int entnum; + qboolean readonly; //world +#ifdef VM_Q1 + comentvars_t *v; + comextentvars_t *xv; +#else + union { + comentvars_t *v; + comentvars_t *xv; + }; +#endif + /*the above is shared with qclib*/ + link_t area; + int num_leafs; + short leafnums[MAX_ENT_LEAFS]; +#ifdef Q2BSPS + int areanum; //q2bsp + int areanum2; //q2bsp + int headnode; //q2bsp +#endif +#ifdef USEODE + entityode_t ode; +#endif + qbyte solidtype; + /*the above is shared with ssqc*/ +}; + #define PF_cin_open PF_Fixme #define PF_cin_close PF_Fixme #define PF_cin_setstate PF_Fixme @@ -50,7 +81,7 @@ typedef struct edict_s { typedef struct lh_extension_s { char *name; int numbuiltins; - qboolean *enabled; + qboolean *queried; char *builtinnames[21]; //extend freely } lh_extension_t; @@ -72,9 +103,10 @@ extern cvar_t pr_tempstringsize; extern cvar_t pr_tempstringcount; int MP_TranslateFTEtoDPCodes(int code); +int MP_TranslateDPtoFTECodes(int code); //pr_cmds.c builtins that need to be moved to a common. -void VARGS PR_BIError(progfuncs_t *progfuncs, char *format, ...); +void VARGS PR_BIError(progfuncs_t *progfuncs, char *format, ...) LIKEPRINTF(2); void PF_print (progfuncs_t *prinst, struct globalvars_s *pr_globals); void PF_dprint (progfuncs_t *prinst, struct globalvars_s *pr_globals); void PF_error (progfuncs_t *prinst, struct globalvars_s *pr_globals); @@ -157,7 +189,7 @@ char *PF_VarString (progfuncs_t *prinst, int first, struct globalvars_s *pr_glob //pr_cmds.c builtins that need to be moved to a common. -void VARGS PR_BIError(progfuncs_t *progfuncs, char *format, ...); +void VARGS PR_BIError(progfuncs_t *progfuncs, char *format, ...) LIKEPRINTF(2); void PF_cvar_string (progfuncs_t *prinst, struct globalvars_s *pr_globals); void PF_cvar_set (progfuncs_t *prinst, struct globalvars_s *pr_globals); void PF_cvar_setf (progfuncs_t *prinst, struct globalvars_s *pr_globals); @@ -294,6 +326,43 @@ void PF_Common_RegisterCvars(void); + +/*these are server ones, provided by pr_cmds.c, as required by pr_q1qvm.c*/ +void PF_WriteByte (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_WriteChar (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_WriteShort (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_WriteLong (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_WriteAngle (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_WriteCoord (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_WriteFloat (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_WriteString (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_WriteEntity (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_multicast (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_svtraceline (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_changelevel (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_cvar_set (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_cvar_setf (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_applylightstyle(int style, char *val, int col); +void PF_ambientsound_Internal (float *pos, char *samp, float vol, float attenuation); +void PF_makestatic (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_logfrag (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_centerprint (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_ExecuteCommand (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_setspawnparms (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_walkmove (progfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_ForceInfoKey(progfuncs_t *prinst, struct globalvars_s *pr_globals); +void PF_precache_vwep_model(progfuncs_t *prinst, struct globalvars_s *pr_globals); +int PF_checkclient_Internal (progfuncs_t *prinst); +void PF_precache_sound_Internal (progfuncs_t *prinst, char *s); +int PF_precache_model_Internal (progfuncs_t *prinst, char *s); +void PF_setmodel_Internal (progfuncs_t *prinst, edict_t *e, char *m); +char *PF_infokey_Internal (int entnum, char *value); +void PF_centerprint_Internal (int entnum, char *s); +void PF_WriteString_Internal (int target, char *str); +pbool ED_CanFree (edict_t *ed); + + + // edict->solid values #define SOLID_NOT 0 // no interaction with other objects #define SOLID_TRIGGER 1 // touch on edge, but not blocking @@ -309,22 +378,28 @@ void PF_Common_RegisterCvars(void); #define DAMAGE_AIM 2 // edict->flags -#define FL_FLY 1 -#define FL_SWIM 2 -#define FL_GLIMPSE 4 -#define FL_CLIENT 8 -#define FL_INWATER 16 -#define FL_MONSTER 32 -#define FL_GODMODE 64 -#define FL_NOTARGET 128 -#define FL_ITEM 256 -#define FL_ONGROUND 512 -#define FL_PARTIALGROUND 1024 // not all corners are valid -#define FL_WATERJUMP 2048 // player jumping out of water - -#define FL_FINDABLE_NONSOLID 16384 //a cpqwsv feature -#define FL_MOVECHAIN_ANGLE 32768 // when in a move chain, will update the angle -#define FL_CLASS_DEPENDENT 2097152 +#define FL_FLY (1<<0) +#define FL_SWIM (1<<1) +#define FL_GLIMPSE (1<<2) +#define FL_CLIENT (1<<3) +#define FL_INWATER (1<<4) +#define FL_MONSTER (1<<5) +#define FL_GODMODE (1<<6) +#define FL_NOTARGET (1<<7) +#define FL_ITEM (1<<8) +#define FL_ONGROUND (1<<9) +#define FL_PARTIALGROUND (1<<10) // not all corners are valid +#define FL_WATERJUMP (1<<11) // player jumping out of water + //12 + //13 +#define FL_FINDABLE_NONSOLID (1<<14) //a cpqwsv feature +#define FL_MOVECHAIN_ANGLE (1<<15) // when in a move chain, will update the angle +#define FL_LAGGEDMOVE (1<<16) + //17 + //18 + //19 + //20 +#define FL_CLASS_DEPENDENT (1<<21) diff --git a/engine/common/protocol.h b/engine/common/protocol.h index 4669400b..7ca10d76 100644 --- a/engine/common/protocol.h +++ b/engine/common/protocol.h @@ -26,7 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef SIDEVIEWS #define PEXT_VIEW2 0x00000010 #endif -#define PEXT_BULLETENS 0x00000020 +//#define PEXT_BULLETENS 0x00000020 #define PEXT_ACCURATETIMINGS 0x00000040 #define PEXT_SOUNDDBL 0x00000080 //revised startsound protocol #define PEXT_FATNESS 0x00000100 //GL only (or servers) @@ -52,10 +52,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define PEXT_SPAWNSTATIC2 0x00400000 //Sends an entity delta instead of a baseline. #define PEXT_CUSTOMTEMPEFFECTS 0x00800000 //supports custom temp ents. #define PEXT_256PACKETENTITIES 0x01000000 //Client can recieve 256 packet entities. -//#define PEXT_64PLAYERS 0x02000000 //Client is able to cope with 64 players. Wow. +//#define PEXT_NEVERUSED 0x02000000 //Client is able to cope with 64 players. Wow. #define PEXT_SHOWPIC 0x04000000 #define PEXT_SETATTACHMENT 0x08000000 //md3 tags (needs networking, they need to lerp). -//#define PEXT_PK3DOWNLOADS 0x10000000 //retrieve a list of pk3s/pk3s/paks for downloading (with optional URL and crcs) +//#define PEXT2_NEVERUSED 0x10000000 //retrieve a list of pk3s/pk3s/paks for downloading (with optional URL and crcs) #define PEXT_CHUNKEDDOWNLOADS 0x20000000 //alternate file download method. Hopefully it'll give quadroupled download speed, especially on higher pings. #ifdef CSQC_DAT @@ -70,6 +70,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define PEXT_BIGUSERINFOS 0xffffffff #endif +#define PEXT2_PRYDONCURSOR 0x00000001 +//#define PEXT2_64PLAYERS 0x02000000 //Client is able to cope with 64 players. Wow. +//#define PEXT2_PK3DOWNLOADS 0x10000000 //retrieve a list of pk3s/pk3s/paks for downloading (with optional URL and crcs) + //ZQuake transparent protocol extensions. #define Z_EXT_PM_TYPE (1<<0) // basic PM_TYPE functionality (reliable jump_held) #define Z_EXT_PM_TYPE_NEW (1<<1) // adds PM_FLY, PM_SPECTATOR @@ -87,6 +91,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define PROTOCOL_VERSION_FTE (('F'<<0) + ('T'<<8) + ('E'<<16) + ('X' << 24)) //fte extensions. +#define PROTOCOL_VERSION_FTE2 (('F'<<0) + ('T'<<8) + ('E'<<16) + ('2' << 24)) //fte extensions. #define PROTOCOL_VERSION_HUFFMAN (('H'<<0) + ('U'<<8) + ('F'<<16) + ('F' << 24)) //packet compression #define PROTOCOL_VERSION_QW 28 @@ -908,7 +913,7 @@ typedef struct q1usercmd_s #define Q2RF_USE_DISGUISE 0x00040000 //ROGUE -#define Q2RF_ADDATIVE 0x00080000 +#define Q2RF_ADDITIVE 0x00080000 #define RF_NOSHADOW 0x00100000 #define RF_NODEPTHTEST 0x00200000 diff --git a/engine/common/q1bsp.c b/engine/common/q1bsp.c index 1180f318..5dec47fb 100644 --- a/engine/common/q1bsp.c +++ b/engine/common/q1bsp.c @@ -1,5 +1,6 @@ #include "quakedef.h" +#include "pr_common.h" /* ============================================================================ @@ -675,13 +676,13 @@ void Fragment_Mesh (fragmentdecal_t *dec, mesh_t *mesh) vec3_t verts[3]; /*if its a triangle fan/poly/quad then we can just submit the entire thing without generating extra fragments*/ - if (0)//mesh->istrifan) + if (mesh->istrifan) { Fragment_ClipPoly(dec, mesh->numvertexes, mesh->xyz_array[0]); return; } - //Fixme: optimise q3 patches + //Fixme: optimise q3 patches (quad strips with bends between each strip) /*otherwise it goes in and out in weird places*/ for (i = 0; i < mesh->numindexes; i+=3) @@ -741,6 +742,12 @@ void Q1BSP_ClipDecalToNodes (fragmentdecal_t *dec, mnode_t *node) Q1BSP_ClipDecalToNodes (dec, node->children[1]); } +#ifdef RTLIGHTS +extern int sh_shadowframe; +#else +static int sh_shadowframe; +#endif +#ifdef Q3BSPS void Q3BSP_ClipDecalToNodes (fragmentdecal_t *dec, mnode_t *node) { mplane_t *splitplane; @@ -758,16 +765,12 @@ void Q3BSP_ClipDecalToNodes (fragmentdecal_t *dec, mnode_t *node) for (i=0 ; inummarksurfaces ; i++, msurf++) { surf = *msurf; - /*if (surf->flags & SURF_PLANEBACK) - { - if (-DotProduct(surf->plane->normal, dec->normal) > -0.5) - continue; - } - else - { - if (DotProduct(surf->plane->normal, dec->normal) > -0.5) - continue; - }*/ + + //only check each surface once. it can appear in multiple leafs. + if (surf->shadowframe == sh_shadowframe) + continue; + surf->shadowframe = sh_shadowframe; + Fragment_Mesh(dec, surf->mesh); } return; @@ -789,6 +792,7 @@ void Q3BSP_ClipDecalToNodes (fragmentdecal_t *dec, mnode_t *node) Q3BSP_ClipDecalToNodes (dec, node->children[0]); Q3BSP_ClipDecalToNodes (dec, node->children[1]); } +#endif int Q1BSP_ClipDecal(vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangent2, float size, float **out) { //quad marks a full, independant quad @@ -810,10 +814,14 @@ int Q1BSP_ClipDecal(vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangen dec.planedist[p] = -(dec.radius - DotProduct(dec.center, dec.planenorm[p])); dec.numplanes = 6; - if (cl.worldmodel->fromgame == fg_quake3) - Q3BSP_ClipDecalToNodes(&dec, cl.worldmodel->nodes); - else + sh_shadowframe++; + + if (cl.worldmodel->fromgame == fg_quake) Q1BSP_ClipDecalToNodes(&dec, cl.worldmodel->nodes); +#ifdef Q3BSPS + else if (cl.worldmodel->fromgame == fg_quake3) + Q3BSP_ClipDecalToNodes(&dec, cl.worldmodel->nodes); +#endif *out = (float *)decalfragmentverts; return dec.numtris; @@ -970,7 +978,7 @@ unsigned int Q1BSP_FatPVS (model_t *mod, vec3_t org, qbyte *pvsbuffer, unsigned return fatbytes; } -qboolean Q1BSP_EdictInFatPVS(model_t *mod, edict_t *ent, qbyte *pvs) +qboolean Q1BSP_EdictInFatPVS(model_t *mod, wedict_t *ent, qbyte *pvs) { int i; @@ -991,7 +999,7 @@ SV_FindTouchedLeafs Links the edict to the right leafs so we can get it's potential visability. =============== */ -void Q1BSP_RFindTouchedLeafs (edict_t *ent, mnode_t *node, float *mins, float *maxs) +void Q1BSP_RFindTouchedLeafs (world_t *w, wedict_t *ent, mnode_t *node, float *mins, float *maxs) { mplane_t *splitplane; mleaf_t *leaf; @@ -1012,7 +1020,7 @@ void Q1BSP_RFindTouchedLeafs (edict_t *ent, mnode_t *node, float *mins, float *m } leaf = (mleaf_t *)node; - leafnum = leaf - sv.worldmodel->leafs - 1; + leafnum = leaf - w->worldmodel->leafs - 1; ent->leafnums[ent->num_leafs] = leafnum; ent->num_leafs++; @@ -1026,16 +1034,16 @@ void Q1BSP_RFindTouchedLeafs (edict_t *ent, mnode_t *node, float *mins, float *m // recurse down the contacted sides if (sides & 1) - Q1BSP_RFindTouchedLeafs (ent, node->children[0], mins, maxs); + Q1BSP_RFindTouchedLeafs (w, ent, node->children[0], mins, maxs); if (sides & 2) - Q1BSP_RFindTouchedLeafs (ent, node->children[1], mins, maxs); + Q1BSP_RFindTouchedLeafs (w, ent, node->children[1], mins, maxs); } -void Q1BSP_FindTouchedLeafs(model_t *mod, edict_t *ent, float *mins, float *maxs) +void Q1BSP_FindTouchedLeafs(world_t *w, model_t *mod, wedict_t *ent, float *mins, float *maxs) { ent->num_leafs = 0; if (ent->v->modelindex) - Q1BSP_RFindTouchedLeafs (ent, mod->nodes, mins, maxs); + Q1BSP_RFindTouchedLeafs (w, ent, mod->nodes, mins, maxs); } #endif diff --git a/engine/common/q2pmove.c b/engine/common/q2pmove.c index 60b31317..c2ca5815 100644 --- a/engine/common/q2pmove.c +++ b/engine/common/q2pmove.c @@ -369,7 +369,7 @@ void PMQ2_Friction (void) drop = 0; // apply ground friction - if ((q2pm->groundentity && q2pml.groundsurface && !(q2pml.groundsurface->flags & SURF_SLICK) ) || (q2pml.ladder) ) + if ((q2pm->groundentity && q2pml.groundsurface && !(q2pml.groundsurface->flags & TI_SLICK) ) || (q2pml.ladder) ) { friction = pm_friction; control = speed < pm_stopspeed ? pm_stopspeed : speed; diff --git a/engine/common/q3common.c b/engine/common/q3common.c index ab3f77b7..446b598b 100644 --- a/engine/common/q3common.c +++ b/engine/common/q3common.c @@ -45,7 +45,7 @@ int VM_fopen (char *name, int *handle, int fmode, int owner) switch (fmode) { case VM_FS_READ: - vm_fopen_files[i].data = COM_LoadMallocFile(name); + vm_fopen_files[i].data = FS_LoadMallocFile(name); vm_fopen_files[i].bufferlen = vm_fopen_files[i].len = com_filesize; vm_fopen_files[i].ofs = 0; if (vm_fopen_files[i].data) @@ -56,7 +56,7 @@ int VM_fopen (char *name, int *handle, int fmode, int owner) /* case VM_FS_APPEND: case VM_FS_APPEND2: - vm_fopen_files[i].data = COM_LoadMallocFile(name); + vm_fopen_files[i].data = FS_LoadMallocFile(name); vm_fopen_files[i].ofs = vm_fopen_files[i].bufferlen = vm_fopen_files[i].len = com_filesize; if (vm_fopen_files[i].data) break; diff --git a/engine/common/sys.h b/engine/common/sys.h index a2b03bfd..7f762ccf 100644 --- a/engine/common/sys.h +++ b/engine/common/sys.h @@ -36,12 +36,12 @@ void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length); // // system IO // -int VARGS Sys_DebugLog(char *file, char *fmt, ...); +int VARGS Sys_DebugLog(char *file, char *fmt, ...) LIKEPRINTF(2); -void VARGS Sys_Error (const char *error, ...); +NORETURN void VARGS Sys_Error (const char *error, ...) LIKEPRINTF(1); // an error will cause the entire program to exit -void VARGS Sys_Printf (char *fmt, ...); +void VARGS Sys_Printf (char *fmt, ...) LIKEPRINTF(1); // send text to the console void Sys_Quit (void); @@ -51,9 +51,9 @@ typedef struct { char *name; } dllfunction_t; typedef void *dllhandle_t; -dllhandle_t *Sys_LoadLibrary(char *name, dllfunction_t *funcs); +dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs); void Sys_CloseLibrary(dllhandle_t *lib); -void *Sys_GetAddressForName(dllhandle_t *module, char *exportname); +void *Sys_GetAddressForName(dllhandle_t *module, const char *exportname); char *Sys_GetNameForAddress(dllhandle_t *module, void *address); unsigned int Sys_Milliseconds (void); diff --git a/engine/common/translate.c b/engine/common/translate.c index fcb9f017..3af58e7f 100644 --- a/engine/common/translate.c +++ b/engine/common/translate.c @@ -243,7 +243,7 @@ static char *defaultlanguagetext = "TL_FAILEDTOOPEN \"Failed to open %s\\n\"\n" "TL_RENAMEFAILED \"failed to rename.\\n\"\n" "TL_UPLOADCOMPLEATE \"Upload completed\\n\"\n" -"TL_FTEEXTENSIONS \"Using FTE extensions 0x%x\\n\"\n" +"TL_FTEEXTENSIONS \"Using FTE extensions 0x%x%x\\n\"\n" "TLC_LINEBREAK_NEWLEVEL \"\\n\\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\\n\\n\"\n" "TLC_PC_PS_NL \"%c%s\\n\"\n" "TLC_NOQ2CINEMATICSSUPPORT \"Cinematics on q2 levels is not yet supported\\nType 'cmd nextserver %i' to proceed.\"\n" @@ -780,7 +780,7 @@ void T_LoadString(void) //count new lines strings_loaded = true; strings_count = 0; - strings_list = COM_LoadMallocFile("strings.txt"); + strings_list = FS_LoadMallocFile("strings.txt"); if (!strings_list) return; diff --git a/engine/common/vm.h b/engine/common/vm.h index a35f25a1..8acfd700 100644 --- a/engine/common/vm.h +++ b/engine/common/vm.h @@ -84,11 +84,12 @@ qboolean Plugin_ExecuteString(void); #ifdef VM_UI qboolean UI_Command(void); void UI_Init (void); +qboolean UI_OpenMenu(void); void UI_Restart_f(void); void UI_Stop (void); qboolean UI_Q2LayoutChanged(void); void UI_StringChanged(int num); -void UI_MousePosition(int xpos, int ypos); +qboolean UI_MousePosition(int xpos, int ypos); int UI_MenuState(void); qboolean UI_KeyPress(int key, int unicode, qboolean down); void UI_Reset(void); diff --git a/engine/common/world.h b/engine/common/world.h index bba4488e..1c24b3d7 100644 --- a/engine/common/world.h +++ b/engine/common/world.h @@ -82,7 +82,7 @@ typedef struct q2trace_s cplane_t plane; // surface normal at impact q2csurface_t *surface; // surface hit int contents; // contents on other side of surface hit - struct edict_s *ent; // not set by CM_*() functions + void *ent; // not set by CM_*() functions } q2trace_t; #define MOVE_NORMAL 0 @@ -92,6 +92,7 @@ typedef struct q2trace_s #define MOVE_RESERVED 8 //so we are less likly to get into tricky situations when we want to steal annother future DP extension. #define MOVE_TRIGGERS 16 //triggers must be marked with FINDABLE_NONSOLID (an alternative to solid-corpse) #define MOVE_EVERYTHING 32 //doesn't use the area grid stuff, and can return triggers and non-solid items if they're marked with FINDABLE_NONSOLID +#define MOVE_LAGGED 64 //trace touches current last-known-state, instead of actual ents (just affects players for now) typedef struct areanode_s { @@ -104,45 +105,93 @@ typedef struct areanode_s #define AREA_DEPTH 4 #define AREA_NODES 32 //pow(2, AREA_DEPTH+1) +typedef struct wedict_s wedict_t; + +typedef struct +{ + qboolean present; + vec3_t laggedpos; +} laggedentinfo_t; + +struct world_s { + unsigned int max_edicts; //limiting factor... 1024 fields*4*MAX_EDICTS == a heck of a lot. + unsigned int num_edicts; // increases towards MAX_EDICTS + unsigned int edict_size; + wedict_t *edicts; // can NOT be array indexed, because + // edict_t is variable sized, but can + // be used to reference the world ent + struct progfuncs_s *progs; + model_t *worldmodel; + struct model_s *models[MAX_MODELS]; + areanode_t areanodes[AREA_NODES]; + int numareanodes; + + double physicstime; + int lastcheck; // used by PF_checkclient + double lastchecktime; // for monster ai + + laggedentinfo_t *lagents; + unsigned int maxlagents; + +#ifdef USEODE + worldode_t ode; +#endif +}; +typedef struct world_s world_t; #ifndef CLIENTONLY -extern areanode_t sv_areanodes[AREA_NODES]; - -void SV_ClearWorld (void); +void World_ClearWorld (world_t *w); // called after the world model has been loaded, before linking any entities -void SV_UnlinkEdict (edict_t *ent); +void World_UnlinkEdict (wedict_t *ent); // call before removing an entity, and before trying to move one, // so it doesn't clip against itself // flags ent->v.modified -void SV_LinkEdict (edict_t *ent, qboolean touch_triggers); +void World_LinkEdict (world_t *w, wedict_t *ent, qboolean touch_triggers); // Needs to be called any time an entity changes origin, mins, maxs, or solid // flags ent->v.modified // sets ent->v.absmin and ent->v.absmax // if touchtriggers, calls prog functions for the intersected triggers -int SV_PointContents (vec3_t p); +void World_TouchLinks (world_t *w, wedict_t *ent, areanode_t *node); + +int World_PointContents (world_t *w, vec3_t p); // returns the CONTENTS_* value from the world at the given point. // does not check any entities at all -edict_t *SV_TestEntityPosition (edict_t *ent); +wedict_t *World_TestEntityPosition (world_t *w, wedict_t *ent); -trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, edict_t *passedict); -// mins and maxs are reletive +/* + World_Move: + mins and maxs are reletive -// if the entire move stays in a solid volume, trace.allsolid will be set + if the entire move stays in a solid volume, trace.allsolid will be set -// if the starting point is in a solid, it will be allowed to move out -// to an open area + if the starting point is in a solid, it will be allowed to move out + to an open area -// nomonsters is used for line of sight or edge testing, where mosnters -// shouldn't be considered solid objects + nomonsters is used for line of sight or edge testing, where mosnters + shouldn't be considered solid objects -// passedict is explicitly excluded from clipping checks (normally NULL) + passedict is explicitly excluded from clipping checks (normally NULL) +*/ +trace_t World_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, wedict_t *passedict); -edict_t *SV_TestPlayerPosition (edict_t *ent, vec3_t origin); +#ifdef Q2SERVER +typedef struct q2edict_s q2edict_t; + +void VARGS WorldQ2_LinkEdict(world_t *w, q2edict_t *ent); +void VARGS WorldQ2_UnlinkEdict(world_t *w, q2edict_t *ent); +int VARGS WorldQ2_AreaEdicts (world_t *w, vec3_t mins, vec3_t maxs, q2edict_t **list, + int maxcount, int areatype); +trace_t WorldQ2_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, q2edict_t *passedict); + +unsigned int Q2BSP_FatPVS (model_t *mod, vec3_t org, qbyte *buffer, unsigned int buffersize, qboolean add); +qboolean Q2BSP_EdictInFatPVS(model_t *mod, wedict_t *ent, qbyte *pvs); +void Q2BSP_FindTouchedLeafs(world_t *w, model_t *mod, wedict_t *ent, float *mins, float *maxs); #endif +#endif diff --git a/engine/d3d/d3d_draw.c b/engine/d3d7/d3d7_draw.c similarity index 100% rename from engine/d3d/d3d_draw.c rename to engine/d3d7/d3d7_draw.c diff --git a/engine/d3d/d3d_mesh.c b/engine/d3d7/d3d7_mesh.c similarity index 100% rename from engine/d3d/d3d_mesh.c rename to engine/d3d7/d3d7_mesh.c diff --git a/engine/d3d/d3d_rmain.c b/engine/d3d7/d3d7_rmain.c similarity index 96% rename from engine/d3d/d3d_rmain.c rename to engine/d3d7/d3d7_rmain.c index 60f31f8e..ee35e1e2 100644 --- a/engine/d3d/d3d_rmain.c +++ b/engine/d3d7/d3d7_rmain.c @@ -891,9 +891,6 @@ void D3D7_DrawWorld(void) #endif { // qglColor3f (1,1,1); - //#ifdef QUAKE2 -// R_ClearSkyBox (); - //#endif RSpeedRemark(); /* diff --git a/engine/d3d/d3d_rsurf.c b/engine/d3d7/d3d7_rsurf.c similarity index 100% rename from engine/d3d/d3d_rsurf.c rename to engine/d3d7/d3d7_rsurf.c diff --git a/engine/d3d/d3dquake.h b/engine/d3d7/d3d7quake.h similarity index 100% rename from engine/d3d/d3dquake.h rename to engine/d3d7/d3d7quake.h diff --git a/engine/d3d/vid_d3d.c b/engine/d3d7/vid_d3d7.c similarity index 95% rename from engine/d3d/vid_d3d.c rename to engine/d3d7/vid_d3d7.c index f70d81ca..9f1d7c70 100644 --- a/engine/d3d/vid_d3d.c +++ b/engine/d3d7/vid_d3d7.c @@ -4,11 +4,6 @@ #include "d3dquake.h" #include "glquake.h" -#pragma comment(lib, "d3dx.lib") -#pragma comment(lib, "ddraw.lib") -#pragma comment(lib, "dxguid.lib") - - #ifndef WM_XBUTTONDOWN #define WM_XBUTTONDOWN 0x020B #define WM_XBUTTONUP 0x020C @@ -87,7 +82,7 @@ qboolean r_cache_thrash; // set if thrashing the surface cache mpic_t *draw_disc; // also used on sbar -#if !defined(RGLQUAKE) +#if !defined(GLQUAKE) qbyte GetPaletteIndex(int red, int green, int blue) { //slow, horrible method. @@ -872,7 +867,7 @@ void (D3D7_SCR_UpdateScreen) (void) { Editor_Draw(); GLV_UpdatePalette (false, host_frametime); -#if defined(_WIN32) && defined(RGLQUAKE) +#if defined(_WIN32) && defined(GLQUAKE) Media_RecordFrame(); #endif GLR_BrightenScreen(); @@ -946,7 +941,7 @@ void (D3D7_SCR_UpdateScreen) (void) SCR_DrawTwoDimensional(uimenu, nohud); // GLV_UpdatePalette (false, host_frametime); -#if defined(_WIN32) && defined(RGLQUAKE) +#if defined(_WIN32) && defined(GLQUAKE) Media_RecordFrame(); #endif diff --git a/engine/d3d9/d3d9_draw.c b/engine/d3d9/d3d9_draw.c index 857a6ec2..fc9241a1 100644 --- a/engine/d3d9/d3d9_draw.c +++ b/engine/d3d9/d3d9_draw.c @@ -123,23 +123,23 @@ void D3D9_RoundDimensions(int *scaled_width, int *scaled_height, qboolean mipmap if (mipmap) { - TRACE(("dbg: GL_RoundDimensions: %f\n", gl_picmip.value)); - *scaled_width >>= (int)gl_picmip.value; - *scaled_height >>= (int)gl_picmip.value; + TRACE(("dbg: GL_RoundDimensions: %i\n", gl_picmip.ival)); + *scaled_width >>= gl_picmip.ival; + *scaled_height >>= gl_picmip.ival; } else { - *scaled_width >>= (int)gl_picmip2d.value; - *scaled_height >>= (int)gl_picmip2d.value; + *scaled_width >>= gl_picmip2d.ival; + *scaled_height >>= gl_picmip2d.ival; } - TRACE(("dbg: GL_RoundDimensions: %f\n", gl_max_size.value)); - if (gl_max_size.value) + TRACE(("dbg: GL_RoundDimensions: %i\n", gl_max_size.ival)); + if (gl_max_size.ival) { - if (*scaled_width > gl_max_size.value) - *scaled_width = gl_max_size.value; - if (*scaled_height > gl_max_size.value) - *scaled_height = gl_max_size.value; + if (*scaled_width > gl_max_size.ival) + *scaled_width = gl_max_size.ival; + if (*scaled_height > gl_max_size.ival) + *scaled_height = gl_max_size.ival; } if (*scaled_width < 1) diff --git a/engine/d3d9/d3d9_rmain.c b/engine/d3d9/d3d9_rmain.c index 3bc3822d..6edb64fa 100644 --- a/engine/d3d9/d3d9_rmain.c +++ b/engine/d3d9/d3d9_rmain.c @@ -1,1160 +1,1160 @@ -#include "quakedef.h" -#ifdef D3DQUAKE -#include "winquake.h" -#include "d3d9quake.h" -#include "renderque.h" - -mleaf_t *r_viewleaf, *r_oldviewleaf; -mleaf_t *r_viewleaf2, *r_oldviewleaf2; -int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2; -extern qbyte areabits[MAX_Q2MAP_AREAS/8]; - - -int r_visframecount; -entity_t r_worldentity; -refdef_t r_refdef; -vec3_t r_origin, vpn, vright, vup; -extern float r_projection_matrix[16]; -extern float r_view_matrix[16]; - - -extern mplane_t frustum[4]; - -vec3_t modelorg; - -entity_t *currententity; -extern cvar_t gl_mindist; - - -void (D3D9_R_DeInit) (void) -{ - int i; - -#ifdef Q3SHADERS - Shader_Shutdown(); -#endif - - - for (i = 0; i < numlightmaps; i++) - { - if (!lightmap[i]) - break; - BZ_Free(lightmap[i]); - lightmap[i] = NULL; - } - - if (lightmap_d3d9textures) - BZ_Free(lightmap_d3d9textures); - if (lightmap) - BZ_Free(lightmap); - - lightmap_d3d9textures=NULL; - lightmap=NULL; - numlightmaps=0; -} -void (D3D9_R_ReInit) (void) -{ -} -void (D3D9_R_Init) (void) -{ - D3D9_R_ReInit(); -} - -//most of this is a direct copy from gl -void (D3D9_SetupFrame) (void) -{ - mleaf_t *leaf; - vec3_t temp; - - GLR_AnimateLight(); - AngleVectors (r_refdef.viewangles, vpn, vright, vup); - VectorCopy (r_refdef.vieworg, r_origin); - r_framecount++; - - if (r_refdef.flags & Q2RDF_NOWORLDMODEL) - { - } -#ifdef Q2BSPS - else if (cl.worldmodel && (cl.worldmodel->fromgame == fg_quake2 || cl.worldmodel->fromgame == fg_quake3)) - { - static mleaf_t fakeleaf; - mleaf_t *leaf; - - r_viewleaf = &fakeleaf; //so we can use quake1 rendering routines for q2 bsps. - r_viewleaf->contents = Q1CONTENTS_EMPTY; - r_viewleaf2 = NULL; - - r_oldviewcluster = r_viewcluster; - r_oldviewcluster2 = r_viewcluster2; - leaf = GLMod_PointInLeaf (cl.worldmodel, r_origin); - r_viewcluster = r_viewcluster2 = leaf->cluster; - - // check above and below so crossing solid water doesn't draw wrong - if (!leaf->contents) - { // look down a bit - vec3_t temp; - - VectorCopy (r_origin, temp); - temp[2] -= 16; - leaf = GLMod_PointInLeaf (cl.worldmodel, temp); - if ( !(leaf->contents & Q2CONTENTS_SOLID) && - (leaf->cluster != r_viewcluster2) ) - r_viewcluster2 = leaf->cluster; - } - else - { // look up a bit - vec3_t temp; - - VectorCopy (r_origin, temp); - temp[2] += 16; - leaf = GLMod_PointInLeaf (cl.worldmodel, temp); - if ( !(leaf->contents & Q2CONTENTS_SOLID) && - (leaf->cluster != r_viewcluster2) ) - r_viewcluster2 = leaf->cluster; - } - } -#endif - else - { - r_oldviewleaf = r_viewleaf; - r_oldviewleaf2 = r_viewleaf2; - r_viewleaf = GLMod_PointInLeaf (cl.worldmodel, r_origin); - - if (!r_viewleaf) - { - } - else if (r_viewleaf->contents == Q1CONTENTS_EMPTY) - { //look down a bit - VectorCopy (r_origin, temp); - temp[2] -= 16; - leaf = GLMod_PointInLeaf (cl.worldmodel, temp); - if (leaf->contents <= Q1CONTENTS_WATER && leaf->contents >= Q1CONTENTS_LAVA) - r_viewleaf2 = leaf; - else - r_viewleaf2 = NULL; - } - else if (r_viewleaf->contents <= Q1CONTENTS_WATER && r_viewleaf->contents >= Q1CONTENTS_LAVA) - { //in water, look up a bit. - - VectorCopy (r_origin, temp); - temp[2] += 16; - leaf = GLMod_PointInLeaf (cl.worldmodel, temp); - if (leaf->contents == Q1CONTENTS_EMPTY) - r_viewleaf2 = leaf; - else - r_viewleaf2 = NULL; - } - else - r_viewleaf2 = NULL; - - if (r_viewleaf) - V_SetContentsColor (r_viewleaf->contents); - } -} - -void D3D9_SetupViewPort(void) -{ - float screenaspect; - int glwidth = vid.width, glheight=vid.height; - int x, x2, y2, y, w, h; - - float fov_x, fov_y; - - D3DVIEWPORT9 vport; - - D3D9_GetBufferSize(&glwidth, &glheight); - - // - // set up viewpoint - // - x = r_refdef.vrect.x * glwidth/(int)vid.width; - x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * glwidth/(int)vid.width; - y = (/*vid.height-*/r_refdef.vrect.y) * glheight/(int)vid.height; - y2 = ((int)/*vid.height - */(r_refdef.vrect.y + r_refdef.vrect.height)) * glheight/(int)vid.height; - - // fudge around because of frac screen scale - if (x > 0) - x--; - if (x2 < glwidth) - x2++; - if (y < 0) - y--; - if (y2 < glheight) - y2++; - - w = x2 - x; - h = y2 - y; - -/* if (envmap) - { - x = y2 = 0; - w = h = 256; - } -*/ - - vport.X = x; - vport.Y = y; - vport.Width = w; - vport.Height = h; - vport.MinZ = 0; - vport.MaxZ = 1; - IDirect3DDevice9_SetViewport(pD3DDev9, &vport); - - fov_x = r_refdef.fov_x;//+sin(cl.time)*5; - fov_y = r_refdef.fov_y;//-sin(cl.time+1)*5; - - if (r_waterwarp.value<0 && r_viewleaf->contents <= Q1CONTENTS_WATER) - { - fov_x *= 1 + (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value); - fov_y *= 1 + (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value); - } - - screenaspect = (float)r_refdef.vrect.width/r_refdef.vrect.height; -// if (r_refdef.useperspective) - { -/* if ((!r_shadows.value || !gl_canstencil) && gl_maxdist.value>256)//gl_nv_range_clamp) - { - // yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*180/M_PI; - // yfov = (2.0 * tan (scr_fov.value/360*M_PI)) / screenaspect; - // yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*(scr_fov.value*2)/M_PI; - // MYgluPerspective (yfov, screenaspect, 4, 4096); - MYgluPerspective (fov_x, fov_y, gl_mindist.value, gl_maxdist.value); - } - else*/ - { - GL_InfinatePerspective(fov_x, fov_y, gl_mindist.value); - } - } -/* else - { - if (gl_maxdist.value>=1) - GL_ParallelPerspective(-fov_x/2, fov_x/2, fov_y/2, -fov_y/2, -gl_maxdist.value, gl_maxdist.value); - else - GL_ParallelPerspective(0, r_refdef.vrect.width, 0, r_refdef.vrect.height, -9999, 9999); - }*/ - - Matrix4_ModelViewMatrixFromAxis(r_view_matrix, vpn, vright, vup, r_refdef.vieworg); - - - IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)r_projection_matrix); - IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_VIEW, (D3DMATRIX*)r_view_matrix); - - - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZFUNC, D3DCMP_LESSEQUAL); - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZENABLE, D3DZB_TRUE); -} - - - - - - -qbyte *Q1BSP_LeafPVS (model_t *model, mleaf_t *leaf, qbyte *buffer); - - - -//fixme: direct copy from gl (apart from lightmaps) -static void D3D9_RecursiveWorldNode (mnode_t *node) -{ - int c, side; - mplane_t *plane; - msurface_t *surf, **mark; - mleaf_t *pleaf; - double dot; - int shift; - -start: - - if (node->contents == Q1CONTENTS_SOLID) - return; // solid - - if (node->visframe != r_visframecount) - return; - if (R_CullBox (node->minmaxs, node->minmaxs+3)) - return; - -// if a leaf node, draw stuff - if (node->contents < 0) - { - pleaf = (mleaf_t *)node; - - mark = pleaf->firstmarksurface; - c = pleaf->nummarksurfaces; - - if (c) - { - do - { - (*mark++)->visframe = r_framecount; - } while (--c); - } - - // deal with model fragments in this leaf - if (pleaf->efrags) - R_StoreEfrags (&pleaf->efrags); - return; - } - -// node is just a decision point, so go down the apropriate sides - -// find which side of the node we are on - plane = node->plane; - - switch (plane->type) - { - case PLANE_X: - dot = modelorg[0] - plane->dist; - break; - case PLANE_Y: - dot = modelorg[1] - plane->dist; - break; - case PLANE_Z: - dot = modelorg[2] - plane->dist; - break; - default: - dot = DotProduct (modelorg, plane->normal) - plane->dist; - break; - } - - if (dot >= 0) - side = 0; - else - side = 1; - -// recurse down the children, front side first - D3D9_RecursiveWorldNode (node->children[side]); - -// draw stuff - c = node->numsurfaces; - - if (c) - { - surf = cl.worldmodel->surfaces + node->firstsurface; - - shift = 0;//GLR_LightmapShift(cl.worldmodel); - -// if (dot < 0 -BACKFACE_EPSILON) -// side = SURF_PLANEBACK; -// else if (dot > BACKFACE_EPSILON) -// side = 0; - { - for ( ; c ; c--, surf++) - { - if (surf->visframe != r_framecount) - continue; - -// if (((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK))) -// continue; // wrong side - - D3DR_RenderDynamicLightmaps (surf, shift); - // if sorting by texture, just store it out -/* if (surf->flags & SURF_DRAWALPHA) - { // add to the translucent chain - surf->nextalphasurface = r_alpha_surfaces; - r_alpha_surfaces = surf; - surf->ownerent = &r_worldentity; - } - else -*/ { - surf->texturechain = surf->texinfo->texture->texturechain; - surf->texinfo->texture->texturechain = surf; - } - } - } - } - -// recurse down the back side -// D3D9_RecursiveWorldNode (node->children[!side]); - node = node->children[!side]; - goto start; -} - -//fixme: direct copy from gl (apart from lightmaps) -static void D3D9_RecursiveQ2WorldNode (mnode_t *node) -{ - int c, side; - mplane_t *plane; - msurface_t *surf, **mark; - mleaf_t *pleaf; - double dot; - int shift; - -start: - - if (node->contents == Q2CONTENTS_SOLID) - return; // solid - - if (node->visframe != r_visframecount) - return; - if (R_CullBox (node->minmaxs, node->minmaxs+3)) - return; - -// if a leaf node, draw stuff - if (node->contents < 0) - { - pleaf = (mleaf_t *)node; - - mark = pleaf->firstmarksurface; - c = pleaf->nummarksurfaces; - - if (c) - { - do - { - (*mark++)->visframe = r_framecount; - } while (--c); - } - - // deal with model fragments in this leaf - if (pleaf->efrags) - R_StoreEfrags (&pleaf->efrags); - return; - } - -// node is just a decision point, so go down the apropriate sides - -// find which side of the node we are on - plane = node->plane; - - switch (plane->type) - { - case PLANE_X: - dot = modelorg[0] - plane->dist; - break; - case PLANE_Y: - dot = modelorg[1] - plane->dist; - break; - case PLANE_Z: - dot = modelorg[2] - plane->dist; - break; - default: - dot = DotProduct (modelorg, plane->normal) - plane->dist; - break; - } - - if (dot >= 0) - side = 0; - else - side = 1; - -// recurse down the children, front side first - D3D9_RecursiveQ2WorldNode (node->children[side]); - -// draw stuff - c = node->numsurfaces; - - if (c) - { - surf = cl.worldmodel->surfaces + node->firstsurface; - - shift = 0;//GLR_LightmapShift(cl.worldmodel); - -// if (dot < 0 -BACKFACE_EPSILON) -// side = SURF_PLANEBACK; -// else if (dot > BACKFACE_EPSILON) -// side = 0; - { - for ( ; c ; c--, surf++) - { - if (surf->visframe != r_framecount) - continue; - -// if (((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK))) -// continue; // wrong side - - D3DR_RenderDynamicLightmaps (surf, shift); - // if sorting by texture, just store it out -/* if (surf->flags & SURF_DRAWALPHA) - { // add to the translucent chain - surf->nextalphasurface = r_alpha_surfaces; - r_alpha_surfaces = surf; - surf->ownerent = &r_worldentity; - } - else -*/ { - surf->texturechain = surf->texinfo->texture->texturechain; - surf->texinfo->texture->texturechain = surf; - } - } - } - } - -// recurse down the back side -// D3D9_RecursiveWorldNode (node->children[!side]); - node = node->children[!side]; - goto start; -} - -#ifdef Q3BSPS -extern mleaf_t *r_vischain; // linked list of visible leafs -static void D3D9_LeafWorldNode (void) -{ - int i; - int clipflags; - msurface_t **mark, *surf; - mleaf_t *pleaf; - - - int clipped; - mplane_t *clipplane; - - - for ( pleaf = r_vischain; pleaf; pleaf = pleaf->vischain ) - { - // check for door connected areas -// if ( areabits ) - { -// if (! (areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) ) -// { -// continue; // not visible -// } - } - - clipflags = 15; // 1 | 2 | 4 | 8 -// if ( !r_nocull->value ) - { - - for (i=0,clipplane=frustum ; i<4 ; i++,clipplane++) - { - clipped = BoxOnPlaneSide ( pleaf->minmaxs, pleaf->minmaxs+3, clipplane ); - if ( clipped == 2 ) { - break; - } else if ( clipped == 1 ) { - clipflags &= ~(1<nummarksurfaces; - mark = pleaf->firstmarksurface; - - do - { - surf = *mark++; - if ( surf->visframe != r_framecount ) //sufraces exist in multiple leafs. - { - surf->visframe = r_framecount; - - surf->texturechain = surf->texinfo->texture->texturechain; - surf->texinfo->texture->texturechain = surf; - } - } while (--i); - -// c_world_leafs++; - } -} -#endif - -struct { - float x, y, z; -// unsigned colour; - float wms, wmt; - float lms, lmt; -} worldvert[1024]; -void D3D9_DrawTextureChains(void) -{ - texture_t *t; - msurface_t *s; - vec3_t *xyz; - vec2_t *wm; - vec2_t *lm; - mesh_t *m; - int i; - int v; - int lmnum; - extern int skytexturenum; // index in cl.loadmodel, not gl texture object - - IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); - IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - - - if (skytexturenum>=0) - { - t = currentmodel->textures[skytexturenum]; - if (t) - { - s = t->texturechain; - if (s) - { - t->texturechain = NULL; - D3D9_DrawSkyChain (s); - } - } - } - - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, FALSE ); - for (i = 0; i < currentmodel->numtextures; i++) - { - t = currentmodel->textures[i]; - if (!t) - continue; //happens on e1m2 - s = t->texturechain; - if (!s) - continue; - t->texturechain = NULL; - - if (s->flags & SURF_DRAWTURB) - { - IDirect3DDevice9_SetTexture(pD3DDev9, 0, (void*)t->tn.base); - -IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_TEXCOORDINDEX, 0); -IDirect3DDevice9_SetTexture(pD3DDev9, 0, (void*)t->tn.base); -IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_TEXCOORDINDEX, 1); -IDirect3DDevice9_SetTexture(pD3DDev9, 1, (void*)t->tn.base); - -IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); -IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); -IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - -IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE); -IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLORARG2, D3DTA_CURRENT); -IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLOROP, D3DTOP_MODULATE2X); - - IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); - IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - - - while(s) - { - m = s->mesh; - xyz = m->xyz_array; - wm = m->st_array; - lm = m->lmst_array; - for (v = 0; v < m->numvertexes; v++, xyz++, wm++, lm++) - { - worldvert[v].x = (*xyz)[0]; - worldvert[v].y = (*xyz)[1]; - worldvert[v].z = (*xyz)[2]; - // worldvert[v].colour = 0; - worldvert[v].wms = (*wm)[0] + cl.time*0.2; - worldvert[v].wmt = (*wm)[1] + cl.time*0.2 + 0.5; - worldvert[v].lms = (*wm)[0] + cl.time*0.1; - worldvert[v].lmt = (*wm)[1] + cl.time*0.1; - } - - - IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_TEX2); - IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, m->numvertexes, m->numindexes/3, m->indexes, D3DFMT_QINDEX, worldvert, sizeof(worldvert[0])); - - s = s->texturechain; - } - lmnum = -4; - - - IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MINFILTER, D3DTEXF_POINT); - IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MIPFILTER, D3DTEXF_NONE); - IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MAGFILTER, D3DTEXF_POINT); - - continue; - } - -IDirect3DDevice9_SetTexture(pD3DDev9, 0, (void*)t->tn.base); -IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); -IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); -IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); -IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_TEXCOORDINDEX, 0); - -IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); -IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - - while(s) - { - m = s->mesh; - if (m) - { - - lmnum = s->lightmaptexturenum; - if (lmnum >= 0) - { - if (lightmap[lmnum]->modified) - { - D3DLOCKED_RECT desc; - - IDirect3DTexture9_LockRect(lightmap_d3d9textures[lmnum], 0, &desc, NULL, DDLOCK_NOSYSLOCK|DDLOCK_WAIT|DDLOCK_WRITEONLY|DDLOCK_DISCARDCONTENTS); - memcpy(desc.pBits, lightmap[lmnum]->lightmaps, LMBLOCK_WIDTH*LMBLOCK_HEIGHT*4); - /* { - int i; - unsigned char *c; - unsigned char v; - c = desc.lpSurface; - for (i = 0; i < LMBLOCK_WIDTH*LMBLOCK_HEIGHT; i++) - { - v = rand(); - *c++ = v; - *c++ = v; - *c++ = v; - c++; - } - }*/ - IDirect3DTexture9_UnlockRect(lightmap_d3d9textures[lmnum], 0); - - lightmap[lmnum]->modified = false; - } - - - IDirect3DDevice9_SetTexture(pD3DDev9, 1, (void*)lightmap_d3d9textures[lmnum]); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLORARG2, D3DTA_CURRENT); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLOROP, D3DTOP_MODULATE); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_TEXCOORDINDEX, 1); - - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - } - else - { - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); - } - -//pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); - - xyz = m->xyz_array; - wm = m->st_array; - lm = m->lmst_array; - - if (!wm || !lm) - { - s = s->texturechain; - continue; - } - - for (v = 0; v < m->numvertexes; v++, xyz++, wm++, lm++) - { - worldvert[v].x = (*xyz)[0]; - worldvert[v].y = (*xyz)[1]; - worldvert[v].z = (*xyz)[2]; -// worldvert[v].colour = 0; - worldvert[v].wms = (*wm)[0]; - worldvert[v].wmt = (*wm)[1]; - worldvert[v].lms = (*lm)[0]; - worldvert[v].lmt = (*lm)[1]; - } - - IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_TEX2); - IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, m->numvertexes, m->numindexes/3, m->indexes, D3DFMT_QINDEX, worldvert, sizeof(worldvert[0])); -// IDirect3DDevice9_DrawIndexedPrimitive(pD3DDev9, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_TEX2, worldvert, m->numvertexes, m->indexes, m->numindexes, 0); - } - s = s->texturechain; - } - } - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, TRUE ); - - IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT); - IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); - IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); -} - -void D3D9_BaseBModelTextures(entity_t *e) -{ - texture_t *t; - msurface_t *s; - vec3_t *xyz; - vec2_t *wm; - vec2_t *lm; - mesh_t *m; - int i; - int v; - float matrix[16]; - int lmnum = -1; - currentmodel = e->model; - - - for (s = currentmodel->surfaces+currentmodel->firstmodelsurface, i = 0; i < currentmodel->nummodelsurfaces; i++, s++) - { - t = R_TextureAnimation(s->texinfo->texture); - - { - m = s->mesh; - if (m) - D3DR_RenderDynamicLightmaps (s, 0); - } - } - - IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); - IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - - Matrix4_ModelMatrixFromAxis(matrix, e->axis[0], e->axis[1], e->axis[2], e->origin); - IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_WORLD, (D3DMATRIX*)matrix); - - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, FALSE ); - for (s = currentmodel->surfaces+currentmodel->firstmodelsurface, i = 0; i < currentmodel->nummodelsurfaces; i++, s++) - { - t = R_TextureAnimation(s->texinfo->texture); - - if (s->lightmaptexturenum < 0) - continue; - - IDirect3DDevice9_SetTexture(pD3DDev9, 0, (void*)t->tn.base); - IDirect3DDevice9_SetTexture(pD3DDev9, 1, (void*)lightmap_d3d9textures[s->lightmaptexturenum]); - { - m = s->mesh; - if (m) - { - - if (lmnum != s->lightmaptexturenum) - { - lmnum = s->lightmaptexturenum; - if (lmnum >= 0) - { -#if 0 - if (lightmap[lmnum]->modified) - { - DDSURFACEDESC2 desc; - - desc.dwSize = sizeof(desc); - lightmap_d3d9textures[lmnum]->lpVtbl->Lock(lightmap_d3dtextures[lmnum], NULL, &desc, DDLOCK_NOSYSLOCK|DDLOCK_WAIT|DDLOCK_WRITEONLY|DDLOCK_DISCARDCONTENTS, NULL); - memcpy(desc.lpSurface, lightmap[lmnum]->lightmaps, LMBLOCK_WIDTH*LMBLOCK_HEIGHT*4); - /* { - int i; - unsigned char *c; - unsigned char v; - c = desc.lpSurface; - for (i = 0; i < LMBLOCK_WIDTH*LMBLOCK_HEIGHT; i++) - { - v = rand(); - *c++ = v; - *c++ = v; - *c++ = v; - c++; - } - }*/ - lightmap_d3d9textures[lmnum]->lpVtbl->Unlock(lightmap_d3d9textures[lmnum], NULL); - - lightmap[lmnum]->modified = false; - } -#endif - - IDirect3DDevice9_SetTexture(pD3DDev9, 1, (void*)lightmap_d3d9textures[lmnum]); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLORARG2, D3DTA_CURRENT); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLOROP, D3DTOP_MODULATE); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_TEXCOORDINDEX, 1); - - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); - } - else - { - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); - } - } - - - - xyz = m->xyz_array; - wm = m->st_array; - lm = m->lmst_array; - - for (v = 0; v < m->numvertexes; v++, xyz++, wm++, lm++) - { - worldvert[v].x = (*xyz)[0]; - worldvert[v].y = (*xyz)[1]; - worldvert[v].z = (*xyz)[2]; -// worldvert[v].colour = 0; - worldvert[v].wms = (*wm)[0]; - worldvert[v].wmt = (*wm)[1]; - worldvert[v].lms = (*lm)[0]; - worldvert[v].lmt = (*lm)[1]; - } - - - IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_TEX2); - IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, m->numvertexes, m->numindexes/3, m->indexes, D3DFMT_QINDEX, worldvert, sizeof(worldvert[0])); -// IDirect3DDevice9_DrawIndexedPrimitive(pD3DDev9, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_TEX2, worldvert, m->numvertexes, m->indexes, m->numindexes, 0); - } - } - } - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, TRUE ); - - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); - - - IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_WORLD, (D3DMATRIX*)matrix); - - - - IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT); - IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); - IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); -} - - - -typedef struct { - float pos[3]; - int colour; - float tc[2]; -} d3dvert_t; -/* -================ -R_GetSpriteFrame -================ -*/ -/* -mspriteframe_t *R_GetSpriteFrame (entity_t *currententity) -{ - msprite_t *psprite; - mspritegroup_t *pspritegroup; - mspriteframe_t *pspriteframe; - int i, numframes, frame; - float *pintervals, fullinterval, targettime, time; - - psprite = currententity->model->cache.data; - frame = currententity->frame; - - if ((frame >= psprite->numframes) || (frame < 0)) - { - Con_DPrintf ("R_DrawSprite: no such frame %d (%s)\n", frame, currententity->model->name); - frame = 0; - } - - if (psprite->frames[frame].type == SPR_SINGLE) - { - pspriteframe = psprite->frames[frame].frameptr; - } - else if (psprite->frames[frame].type == SPR_ANGLED) - { - pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr; - pspriteframe = pspritegroup->frames[(int)((r_refdef.viewangles[1]-currententity->angles[1])/360*8 + 0.5-4)&7]; - } - else - { - pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr; - pintervals = pspritegroup->intervals; - numframes = pspritegroup->numframes; - fullinterval = pintervals[numframes-1]; - - time = currententity->frame1time; - - // when loading in Mod_LoadSpriteGroup, we guaranteed all interval values - // are positive, so we don't have to worry about division by 0 - targettime = time - ((int)(time / fullinterval)) * fullinterval; - - for (i=0 ; i<(numframes-1) ; i++) - { - if (pintervals[i] > targettime) - break; - } - - pspriteframe = pspritegroup->frames[i]; - } - - return pspriteframe; -} -*/ -static void D3D9_DrawSpriteModel (entity_t *e) -{ - vec3_t point; - mspriteframe_t *frame; - vec3_t forward, right, up; - msprite_t *psprite; - - d3dvert_t d3dvert[4]; - index_t vertindexes[6] = { - 0, 1, 2, - 0, 2, 3 - }; - -#ifdef Q3SHADERS - mpic_t *pic = e->forcedshader; -#else - mpic_t *pic = NULL; -#endif - - if (pic || !e->model) - { - int colour; - - colour = 0; - - ((unsigned char*)&colour)[0] = e->shaderRGBAf[2]*255; - ((unsigned char*)&colour)[1] = e->shaderRGBAf[1]*255; - ((unsigned char*)&colour)[2] = e->shaderRGBAf[0]*255; - ((unsigned char*)&colour)[3] = e->shaderRGBAf[3]*255; - - VectorCopy(vup, up); - VectorCopy(vright, right); - - up[0]*=e->scale; - up[1]*=e->scale; - up[2]*=e->scale; - right[0]*=e->scale; - right[1]*=e->scale; - right[2]*=e->scale; - - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); \ - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); \ - - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, FALSE); - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHABLENDENABLE, TRUE); - - if (pic) - IDirect3DDevice9_SetTexture(pD3DDev9, 0, *(LPDIRECT3DBASETEXTURE9*)&pic->d); - else - IDirect3DDevice9_SetTexture(pD3DDev9, 0, NULL); - - if (e->flags & RF_NODEPTHTEST) - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZFUNC, D3DCMP_ALWAYS); - - d3dvert[0].colour = colour; - d3dvert[0].tc[0] = 0; - d3dvert[0].tc[1] = 1; - VectorMA (e->origin, -1, up, point); - VectorMA (point, -1, right, d3dvert[0].pos); - - d3dvert[1].colour = colour; - d3dvert[1].tc[0] = 0; - d3dvert[1].tc[0] = 0; - VectorMA (e->origin, 1, up, point); - VectorMA (point, -1, right, d3dvert[1].pos); - - d3dvert[2].colour = colour; - d3dvert[2].tc[0] = 1; - d3dvert[2].tc[1] = 0; - VectorMA (e->origin, 1, up, point); - VectorMA (point, 1, right, d3dvert[2].pos); - - d3dvert[3].colour = colour; - d3dvert[3].tc[0] = 1; - d3dvert[3].tc[1] = 1; - VectorMA (e->origin, -1, up, point); - VectorMA (point, 1, right, d3dvert[3].pos); - - IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); - IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, 4, 2, vertindexes, D3DFMT_QINDEX, d3dvert, sizeof(d3dvert[0])); - - - if (e->flags & RF_NODEPTHTEST) - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZFUNC, D3DCMP_LESSEQUAL); - - return; - } - - if (!e->model) - return; - - if (e->flags & RF_NODEPTHTEST) - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZFUNC, D3DCMP_ALWAYS); - - // don't even bother culling, because it's just a single - // polygon without a surface cache - frame = R_GetSpriteFrame (e); - if (!frame) - return; - psprite = e->model->cache.data; -// frame = 0x05b94140; - - switch(psprite->type) - { - case SPR_ORIENTED: - // bullet marks on walls - AngleVectors (e->angles, forward, right, up); - break; - - case SPR_FACING_UPRIGHT: - up[0] = 0;up[1] = 0;up[2]=1; - right[0] = e->origin[1] - r_origin[1]; - right[1] = -(e->origin[0] - r_origin[0]); - right[2] = 0; - VectorNormalize (right); - break; - case SPR_VP_PARALLEL_UPRIGHT: - up[0] = 0;up[1] = 0;up[2]=1; - VectorCopy (vright, right); - break; - - default: - case SPR_VP_PARALLEL: - //normal sprite - VectorCopy(vup, up); - VectorCopy(vright, right); - break; - } - up[0]*=e->scale; - up[1]*=e->scale; - up[2]*=e->scale; - right[0]*=e->scale; - right[1]*=e->scale; - right[2]*=e->scale; - - IDirect3DDevice9_SetTexture(pD3DDev9, 0, *(void**)&frame->p.d); - -/* { - extern int gldepthfunc; - qglDepthFunc(gldepthfunc); - qglDepthMask(0); - if (gldepthmin == 0.5) - qglCullFace ( GL_BACK ); - else - qglCullFace ( GL_FRONT ); - - GL_TexEnv(GL_MODULATE); - - qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - qglDisable (GL_ALPHA_TEST); - qglDisable(GL_BLEND); - }*/ - -/* if (e->flags & Q2RF_ADDATIVE) - { - qglEnable(GL_BLEND); - qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - qglBlendFunc(GL_SRC_ALPHA, GL_ONE); - } - else if (e->shaderRGBAf[3]<1 || gl_blendsprites.value) - { - qglEnable(GL_BLEND); - qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - } - else - qglEnable (GL_ALPHA_TEST); -*/ - - d3dvert[0].colour = 0xffffffff; - d3dvert[0].tc[0] = 0; - d3dvert[0].tc[1] = 1; - VectorMA (e->origin, frame->down, up, point); - VectorMA (point, frame->left, right, d3dvert[0].pos); - - d3dvert[1].colour = 0xffffffff; - d3dvert[1].tc[0] = 0; - d3dvert[1].tc[0] = 0; - VectorMA (e->origin, frame->up, up, point); - VectorMA (point, frame->left, right, d3dvert[1].pos); - - d3dvert[2].colour = 0xffffffff; - d3dvert[2].tc[0] = 1; - d3dvert[2].tc[1] = 0; - VectorMA (e->origin, frame->up, up, point); - VectorMA (point, frame->right, right, d3dvert[2].pos); - - d3dvert[3].colour = 0xffffffff; - d3dvert[3].tc[0] = 1; - d3dvert[3].tc[1] = 1; - VectorMA (e->origin, frame->down, up, point); - VectorMA (point, frame->right, right, d3dvert[3].pos); - - IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); - IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, 4, 2, vertindexes, D3DFMT_QINDEX, d3dvert, sizeof(d3dvert[0])); - - - if (e->flags & RF_NODEPTHTEST) - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZFUNC, D3DCMP_LESSEQUAL); - -// if (e->flags & Q2RF_ADDATIVE) //back to regular blending for us! -// qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -} - -//================================================================================== - +#include "quakedef.h" +#ifdef D3DQUAKE +#include "winquake.h" +#include "d3d9quake.h" +#include "renderque.h" + +mleaf_t *r_viewleaf, *r_oldviewleaf; +mleaf_t *r_viewleaf2, *r_oldviewleaf2; +int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2; +extern qbyte areabits[MAX_Q2MAP_AREAS/8]; + + +int r_visframecount; +entity_t r_worldentity; +refdef_t r_refdef; +vec3_t r_origin, vpn, vright, vup; +extern float r_projection_matrix[16]; +extern float r_view_matrix[16]; + + +extern mplane_t frustum[4]; + +vec3_t modelorg; + +entity_t *currententity; +extern cvar_t gl_mindist; + + +void (D3D9_R_DeInit) (void) +{ + int i; + +#ifdef Q3SHADERS + Shader_Shutdown(); +#endif + + + for (i = 0; i < numlightmaps; i++) + { + if (!lightmap[i]) + break; + BZ_Free(lightmap[i]); + lightmap[i] = NULL; + } + + if (lightmap_d3d9textures) + BZ_Free(lightmap_d3d9textures); + if (lightmap) + BZ_Free(lightmap); + + lightmap_d3d9textures=NULL; + lightmap=NULL; + numlightmaps=0; +} +void (D3D9_R_ReInit) (void) +{ +} +void (D3D9_R_Init) (void) +{ + D3D9_R_ReInit(); +} + +//most of this is a direct copy from gl +void (D3D9_SetupFrame) (void) +{ + mleaf_t *leaf; + vec3_t temp; + + GLR_AnimateLight(); + AngleVectors (r_refdef.viewangles, vpn, vright, vup); + VectorCopy (r_refdef.vieworg, r_origin); + r_framecount++; + + if (r_refdef.flags & Q2RDF_NOWORLDMODEL) + { + } +#ifdef Q2BSPS + else if (cl.worldmodel && (cl.worldmodel->fromgame == fg_quake2 || cl.worldmodel->fromgame == fg_quake3)) + { + static mleaf_t fakeleaf; + mleaf_t *leaf; + + r_viewleaf = &fakeleaf; //so we can use quake1 rendering routines for q2 bsps. + r_viewleaf->contents = Q1CONTENTS_EMPTY; + r_viewleaf2 = NULL; + + r_oldviewcluster = r_viewcluster; + r_oldviewcluster2 = r_viewcluster2; + leaf = GLMod_PointInLeaf (cl.worldmodel, r_origin); + r_viewcluster = r_viewcluster2 = leaf->cluster; + + // check above and below so crossing solid water doesn't draw wrong + if (!leaf->contents) + { // look down a bit + vec3_t temp; + + VectorCopy (r_origin, temp); + temp[2] -= 16; + leaf = GLMod_PointInLeaf (cl.worldmodel, temp); + if ( !(leaf->contents & Q2CONTENTS_SOLID) && + (leaf->cluster != r_viewcluster2) ) + r_viewcluster2 = leaf->cluster; + } + else + { // look up a bit + vec3_t temp; + + VectorCopy (r_origin, temp); + temp[2] += 16; + leaf = GLMod_PointInLeaf (cl.worldmodel, temp); + if ( !(leaf->contents & Q2CONTENTS_SOLID) && + (leaf->cluster != r_viewcluster2) ) + r_viewcluster2 = leaf->cluster; + } + } +#endif + else + { + r_oldviewleaf = r_viewleaf; + r_oldviewleaf2 = r_viewleaf2; + r_viewleaf = GLMod_PointInLeaf (cl.worldmodel, r_origin); + + if (!r_viewleaf) + { + } + else if (r_viewleaf->contents == Q1CONTENTS_EMPTY) + { //look down a bit + VectorCopy (r_origin, temp); + temp[2] -= 16; + leaf = GLMod_PointInLeaf (cl.worldmodel, temp); + if (leaf->contents <= Q1CONTENTS_WATER && leaf->contents >= Q1CONTENTS_LAVA) + r_viewleaf2 = leaf; + else + r_viewleaf2 = NULL; + } + else if (r_viewleaf->contents <= Q1CONTENTS_WATER && r_viewleaf->contents >= Q1CONTENTS_LAVA) + { //in water, look up a bit. + + VectorCopy (r_origin, temp); + temp[2] += 16; + leaf = GLMod_PointInLeaf (cl.worldmodel, temp); + if (leaf->contents == Q1CONTENTS_EMPTY) + r_viewleaf2 = leaf; + else + r_viewleaf2 = NULL; + } + else + r_viewleaf2 = NULL; + + if (r_viewleaf) + V_SetContentsColor (r_viewleaf->contents); + } +} + +void D3D9_SetupViewPort(void) +{ + float screenaspect; + int glwidth = vid.width, glheight=vid.height; + int x, x2, y2, y, w, h; + + float fov_x, fov_y; + + D3DVIEWPORT9 vport; + + D3D9_GetBufferSize(&glwidth, &glheight); + + // + // set up viewpoint + // + x = r_refdef.vrect.x * glwidth/(int)vid.width; + x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * glwidth/(int)vid.width; + y = (/*vid.height-*/r_refdef.vrect.y) * glheight/(int)vid.height; + y2 = ((int)/*vid.height - */(r_refdef.vrect.y + r_refdef.vrect.height)) * glheight/(int)vid.height; + + // fudge around because of frac screen scale + if (x > 0) + x--; + if (x2 < glwidth) + x2++; + if (y < 0) + y--; + if (y2 < glheight) + y2++; + + w = x2 - x; + h = y2 - y; + +/* if (envmap) + { + x = y2 = 0; + w = h = 256; + } +*/ + + vport.X = x; + vport.Y = y; + vport.Width = w; + vport.Height = h; + vport.MinZ = 0; + vport.MaxZ = 1; + IDirect3DDevice9_SetViewport(pD3DDev9, &vport); + + fov_x = r_refdef.fov_x;//+sin(cl.time)*5; + fov_y = r_refdef.fov_y;//-sin(cl.time+1)*5; + + if (r_waterwarp.value<0 && r_viewleaf->contents <= Q1CONTENTS_WATER) + { + fov_x *= 1 + (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value); + fov_y *= 1 + (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value); + } + + screenaspect = (float)r_refdef.vrect.width/r_refdef.vrect.height; +// if (r_refdef.useperspective) + { +/* if ((!r_shadows.value || !gl_canstencil) && gl_maxdist.value>256)//gl_nv_range_clamp) + { + // yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*180/M_PI; + // yfov = (2.0 * tan (scr_fov.value/360*M_PI)) / screenaspect; + // yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*(scr_fov.value*2)/M_PI; + // MYgluPerspective (yfov, screenaspect, 4, 4096); + MYgluPerspective (fov_x, fov_y, gl_mindist.value, gl_maxdist.value); + } + else*/ + { + GL_InfinatePerspective(fov_x, fov_y, gl_mindist.value); + } + } +/* else + { + if (gl_maxdist.value>=1) + GL_ParallelPerspective(-fov_x/2, fov_x/2, fov_y/2, -fov_y/2, -gl_maxdist.value, gl_maxdist.value); + else + GL_ParallelPerspective(0, r_refdef.vrect.width, 0, r_refdef.vrect.height, -9999, 9999); + }*/ + + Matrix4_ModelViewMatrixFromAxis(r_view_matrix, vpn, vright, vup, r_refdef.vieworg); + + + IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)r_projection_matrix); + IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_VIEW, (D3DMATRIX*)r_view_matrix); + + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZFUNC, D3DCMP_LESSEQUAL); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZENABLE, D3DZB_TRUE); +} + + + + + + +qbyte *Q1BSP_LeafPVS (model_t *model, mleaf_t *leaf, qbyte *buffer); + + + +//fixme: direct copy from gl (apart from lightmaps) +static void D3D9_RecursiveWorldNode (mnode_t *node) +{ + int c, side; + mplane_t *plane; + msurface_t *surf, **mark; + mleaf_t *pleaf; + double dot; + int shift; + +start: + + if (node->contents == Q1CONTENTS_SOLID) + return; // solid + + if (node->visframe != r_visframecount) + return; + if (R_CullBox (node->minmaxs, node->minmaxs+3)) + return; + +// if a leaf node, draw stuff + if (node->contents < 0) + { + pleaf = (mleaf_t *)node; + + mark = pleaf->firstmarksurface; + c = pleaf->nummarksurfaces; + + if (c) + { + do + { + (*mark++)->visframe = r_framecount; + } while (--c); + } + + // deal with model fragments in this leaf + if (pleaf->efrags) + R_StoreEfrags (&pleaf->efrags); + return; + } + +// node is just a decision point, so go down the apropriate sides + +// find which side of the node we are on + plane = node->plane; + + switch (plane->type) + { + case PLANE_X: + dot = modelorg[0] - plane->dist; + break; + case PLANE_Y: + dot = modelorg[1] - plane->dist; + break; + case PLANE_Z: + dot = modelorg[2] - plane->dist; + break; + default: + dot = DotProduct (modelorg, plane->normal) - plane->dist; + break; + } + + if (dot >= 0) + side = 0; + else + side = 1; + +// recurse down the children, front side first + D3D9_RecursiveWorldNode (node->children[side]); + +// draw stuff + c = node->numsurfaces; + + if (c) + { + surf = cl.worldmodel->surfaces + node->firstsurface; + + shift = 0;//GLR_LightmapShift(cl.worldmodel); + +// if (dot < 0 -BACKFACE_EPSILON) +// side = SURF_PLANEBACK; +// else if (dot > BACKFACE_EPSILON) +// side = 0; + { + for ( ; c ; c--, surf++) + { + if (surf->visframe != r_framecount) + continue; + +// if (((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK))) +// continue; // wrong side + + D3DR_RenderDynamicLightmaps (surf, shift); + // if sorting by texture, just store it out +/* if (surf->flags & SURF_DRAWALPHA) + { // add to the translucent chain + surf->nextalphasurface = r_alpha_surfaces; + r_alpha_surfaces = surf; + surf->ownerent = &r_worldentity; + } + else +*/ { + surf->texturechain = surf->texinfo->texture->texturechain; + surf->texinfo->texture->texturechain = surf; + } + } + } + } + +// recurse down the back side +// D3D9_RecursiveWorldNode (node->children[!side]); + node = node->children[!side]; + goto start; +} + +//fixme: direct copy from gl (apart from lightmaps) +static void D3D9_RecursiveQ2WorldNode (mnode_t *node) +{ + int c, side; + mplane_t *plane; + msurface_t *surf, **mark; + mleaf_t *pleaf; + double dot; + int shift; + +start: + + if (node->contents == Q2CONTENTS_SOLID) + return; // solid + + if (node->visframe != r_visframecount) + return; + if (R_CullBox (node->minmaxs, node->minmaxs+3)) + return; + +// if a leaf node, draw stuff + if (node->contents < 0) + { + pleaf = (mleaf_t *)node; + + mark = pleaf->firstmarksurface; + c = pleaf->nummarksurfaces; + + if (c) + { + do + { + (*mark++)->visframe = r_framecount; + } while (--c); + } + + // deal with model fragments in this leaf + if (pleaf->efrags) + R_StoreEfrags (&pleaf->efrags); + return; + } + +// node is just a decision point, so go down the apropriate sides + +// find which side of the node we are on + plane = node->plane; + + switch (plane->type) + { + case PLANE_X: + dot = modelorg[0] - plane->dist; + break; + case PLANE_Y: + dot = modelorg[1] - plane->dist; + break; + case PLANE_Z: + dot = modelorg[2] - plane->dist; + break; + default: + dot = DotProduct (modelorg, plane->normal) - plane->dist; + break; + } + + if (dot >= 0) + side = 0; + else + side = 1; + +// recurse down the children, front side first + D3D9_RecursiveQ2WorldNode (node->children[side]); + +// draw stuff + c = node->numsurfaces; + + if (c) + { + surf = cl.worldmodel->surfaces + node->firstsurface; + + shift = 0;//GLR_LightmapShift(cl.worldmodel); + +// if (dot < 0 -BACKFACE_EPSILON) +// side = SURF_PLANEBACK; +// else if (dot > BACKFACE_EPSILON) +// side = 0; + { + for ( ; c ; c--, surf++) + { + if (surf->visframe != r_framecount) + continue; + +// if (((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK))) +// continue; // wrong side + + D3DR_RenderDynamicLightmaps (surf, shift); + // if sorting by texture, just store it out +/* if (surf->flags & SURF_DRAWALPHA) + { // add to the translucent chain + surf->nextalphasurface = r_alpha_surfaces; + r_alpha_surfaces = surf; + surf->ownerent = &r_worldentity; + } + else +*/ { + surf->texturechain = surf->texinfo->texture->texturechain; + surf->texinfo->texture->texturechain = surf; + } + } + } + } + +// recurse down the back side +// D3D9_RecursiveWorldNode (node->children[!side]); + node = node->children[!side]; + goto start; +} + +#ifdef Q3BSPS +extern mleaf_t *r_vischain; // linked list of visible leafs +static void D3D9_LeafWorldNode (void) +{ + int i; + int clipflags; + msurface_t **mark, *surf; + mleaf_t *pleaf; + + + int clipped; + mplane_t *clipplane; + + + for ( pleaf = r_vischain; pleaf; pleaf = pleaf->vischain ) + { + // check for door connected areas +// if ( areabits ) + { +// if (! (areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) ) +// { +// continue; // not visible +// } + } + + clipflags = 15; // 1 | 2 | 4 | 8 +// if ( !r_nocull->value ) + { + + for (i=0,clipplane=frustum ; i<4 ; i++,clipplane++) + { + clipped = BoxOnPlaneSide ( pleaf->minmaxs, pleaf->minmaxs+3, clipplane ); + if ( clipped == 2 ) { + break; + } else if ( clipped == 1 ) { + clipflags &= ~(1<nummarksurfaces; + mark = pleaf->firstmarksurface; + + do + { + surf = *mark++; + if ( surf->visframe != r_framecount ) //sufraces exist in multiple leafs. + { + surf->visframe = r_framecount; + + surf->texturechain = surf->texinfo->texture->texturechain; + surf->texinfo->texture->texturechain = surf; + } + } while (--i); + +// c_world_leafs++; + } +} +#endif + +struct { + float x, y, z; +// unsigned colour; + float wms, wmt; + float lms, lmt; +} worldvert[1024]; +void D3D9_DrawTextureChains(void) +{ + texture_t *t; + msurface_t *s; + vec3_t *xyz; + vec2_t *wm; + vec2_t *lm; + mesh_t *m; + int i; + int v; + int lmnum; + extern int skytexturenum; // index in cl.loadmodel, not gl texture object + + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + + + if (skytexturenum>=0) + { + t = currentmodel->textures[skytexturenum]; + if (t) + { + s = t->texturechain; + if (s) + { + t->texturechain = NULL; + D3D9_DrawSkyChain (s); + } + } + } + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, FALSE ); + for (i = 0; i < currentmodel->numtextures; i++) + { + t = currentmodel->textures[i]; + if (!t) + continue; //happens on e1m2 + s = t->texturechain; + if (!s) + continue; + t->texturechain = NULL; + + if (s->flags & SURF_DRAWTURB) + { + IDirect3DDevice9_SetTexture(pD3DDev9, 0, (void*)t->tn.base); + +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_TEXCOORDINDEX, 0); +IDirect3DDevice9_SetTexture(pD3DDev9, 0, (void*)t->tn.base); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_TEXCOORDINDEX, 1); +IDirect3DDevice9_SetTexture(pD3DDev9, 1, (void*)t->tn.base); + +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLORARG2, D3DTA_CURRENT); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLOROP, D3DTOP_MODULATE2X); + + IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + + + while(s) + { + m = s->mesh; + xyz = m->xyz_array; + wm = m->st_array; + lm = m->lmst_array; + for (v = 0; v < m->numvertexes; v++, xyz++, wm++, lm++) + { + worldvert[v].x = (*xyz)[0]; + worldvert[v].y = (*xyz)[1]; + worldvert[v].z = (*xyz)[2]; + // worldvert[v].colour = 0; + worldvert[v].wms = (*wm)[0] + cl.time*0.2; + worldvert[v].wmt = (*wm)[1] + cl.time*0.2 + 0.5; + worldvert[v].lms = (*wm)[0] + cl.time*0.1; + worldvert[v].lmt = (*wm)[1] + cl.time*0.1; + } + + + IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_TEX2); + IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, m->numvertexes, m->numindexes/3, m->indexes, D3DFMT_QINDEX, worldvert, sizeof(worldvert[0])); + + s = s->texturechain; + } + lmnum = -4; + + + IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MINFILTER, D3DTEXF_POINT); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MIPFILTER, D3DTEXF_NONE); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 1, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + + continue; + } + +IDirect3DDevice9_SetTexture(pD3DDev9, 0, (void*)t->tn.base); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_TEXCOORDINDEX, 0); + +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); +IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + + while(s) + { + m = s->mesh; + if (m) + { + + lmnum = s->lightmaptexturenum; + if (lmnum >= 0) + { + if (lightmap[lmnum]->modified) + { + D3DLOCKED_RECT desc; + + IDirect3DTexture9_LockRect(lightmap_d3d9textures[lmnum], 0, &desc, NULL, DDLOCK_NOSYSLOCK|DDLOCK_WAIT|DDLOCK_WRITEONLY|DDLOCK_DISCARDCONTENTS); + memcpy(desc.pBits, lightmap[lmnum]->lightmaps, LMBLOCK_WIDTH*LMBLOCK_HEIGHT*4); + /* { + int i; + unsigned char *c; + unsigned char v; + c = desc.lpSurface; + for (i = 0; i < LMBLOCK_WIDTH*LMBLOCK_HEIGHT; i++) + { + v = rand(); + *c++ = v; + *c++ = v; + *c++ = v; + c++; + } + }*/ + IDirect3DTexture9_UnlockRect(lightmap_d3d9textures[lmnum], 0); + + lightmap[lmnum]->modified = false; + } + + + IDirect3DDevice9_SetTexture(pD3DDev9, 1, (void*)lightmap_d3d9textures[lmnum]); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLORARG2, D3DTA_CURRENT); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLOROP, D3DTOP_MODULATE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_TEXCOORDINDEX, 1); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + } + else + { + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); + } + +//pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); + + xyz = m->xyz_array; + wm = m->st_array; + lm = m->lmst_array; + + if (!wm || !lm) + { + s = s->texturechain; + continue; + } + + for (v = 0; v < m->numvertexes; v++, xyz++, wm++, lm++) + { + worldvert[v].x = (*xyz)[0]; + worldvert[v].y = (*xyz)[1]; + worldvert[v].z = (*xyz)[2]; +// worldvert[v].colour = 0; + worldvert[v].wms = (*wm)[0]; + worldvert[v].wmt = (*wm)[1]; + worldvert[v].lms = (*lm)[0]; + worldvert[v].lmt = (*lm)[1]; + } + + IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_TEX2); + IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, m->numvertexes, m->numindexes/3, m->indexes, D3DFMT_QINDEX, worldvert, sizeof(worldvert[0])); +// IDirect3DDevice9_DrawIndexedPrimitive(pD3DDev9, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_TEX2, worldvert, m->numvertexes, m->indexes, m->numindexes, 0); + } + s = s->texturechain; + } + } + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, TRUE ); + + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); +} + +void D3D9_BaseBModelTextures(entity_t *e) +{ + texture_t *t; + msurface_t *s; + vec3_t *xyz; + vec2_t *wm; + vec2_t *lm; + mesh_t *m; + int i; + int v; + float matrix[16]; + int lmnum = -1; + currentmodel = e->model; + + + for (s = currentmodel->surfaces+currentmodel->firstmodelsurface, i = 0; i < currentmodel->nummodelsurfaces; i++, s++) + { + t = R_TextureAnimation(s->texinfo->texture); + + { + m = s->mesh; + if (m) + D3DR_RenderDynamicLightmaps (s, 0); + } + } + + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + + Matrix4_ModelMatrixFromAxis(matrix, e->axis[0], e->axis[1], e->axis[2], e->origin); + IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_WORLD, (D3DMATRIX*)matrix); + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, FALSE ); + for (s = currentmodel->surfaces+currentmodel->firstmodelsurface, i = 0; i < currentmodel->nummodelsurfaces; i++, s++) + { + t = R_TextureAnimation(s->texinfo->texture); + + if (s->lightmaptexturenum < 0) + continue; + + IDirect3DDevice9_SetTexture(pD3DDev9, 0, (void*)t->tn.base); + IDirect3DDevice9_SetTexture(pD3DDev9, 1, (void*)lightmap_d3d9textures[s->lightmaptexturenum]); + { + m = s->mesh; + if (m) + { + + if (lmnum != s->lightmaptexturenum) + { + lmnum = s->lightmaptexturenum; + if (lmnum >= 0) + { +#if 0 + if (lightmap[lmnum]->modified) + { + DDSURFACEDESC2 desc; + + desc.dwSize = sizeof(desc); + lightmap_d3d9textures[lmnum]->lpVtbl->Lock(lightmap_d3dtextures[lmnum], NULL, &desc, DDLOCK_NOSYSLOCK|DDLOCK_WAIT|DDLOCK_WRITEONLY|DDLOCK_DISCARDCONTENTS, NULL); + memcpy(desc.lpSurface, lightmap[lmnum]->lightmaps, LMBLOCK_WIDTH*LMBLOCK_HEIGHT*4); + /* { + int i; + unsigned char *c; + unsigned char v; + c = desc.lpSurface; + for (i = 0; i < LMBLOCK_WIDTH*LMBLOCK_HEIGHT; i++) + { + v = rand(); + *c++ = v; + *c++ = v; + *c++ = v; + c++; + } + }*/ + lightmap_d3d9textures[lmnum]->lpVtbl->Unlock(lightmap_d3d9textures[lmnum], NULL); + + lightmap[lmnum]->modified = false; + } +#endif + + IDirect3DDevice9_SetTexture(pD3DDev9, 1, (void*)lightmap_d3d9textures[lmnum]); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLORARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLORARG2, D3DTA_CURRENT); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLOROP, D3DTOP_MODULATE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_TEXCOORDINDEX, 1); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 ); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); + } + else + { + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); + } + } + + + + xyz = m->xyz_array; + wm = m->st_array; + lm = m->lmst_array; + + for (v = 0; v < m->numvertexes; v++, xyz++, wm++, lm++) + { + worldvert[v].x = (*xyz)[0]; + worldvert[v].y = (*xyz)[1]; + worldvert[v].z = (*xyz)[2]; +// worldvert[v].colour = 0; + worldvert[v].wms = (*wm)[0]; + worldvert[v].wmt = (*wm)[1]; + worldvert[v].lms = (*lm)[0]; + worldvert[v].lmt = (*lm)[1]; + } + + + IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_TEX2); + IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, m->numvertexes, m->numindexes/3, m->indexes, D3DFMT_QINDEX, worldvert, sizeof(worldvert[0])); +// IDirect3DDevice9_DrawIndexedPrimitive(pD3DDev9, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_TEX2, worldvert, m->numvertexes, m->indexes, m->numindexes, 0); + } + } + } + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, TRUE ); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 1, D3DTSS_COLOROP, D3DTOP_DISABLE); + + + IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_WORLD, (D3DMATRIX*)matrix); + + + + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); +} + + + +typedef struct { + float pos[3]; + int colour; + float tc[2]; +} d3dvert_t; +/* +================ +R_GetSpriteFrame +================ +*/ +/* +mspriteframe_t *R_GetSpriteFrame (entity_t *currententity) +{ + msprite_t *psprite; + mspritegroup_t *pspritegroup; + mspriteframe_t *pspriteframe; + int i, numframes, frame; + float *pintervals, fullinterval, targettime, time; + + psprite = currententity->model->cache.data; + frame = currententity->frame; + + if ((frame >= psprite->numframes) || (frame < 0)) + { + Con_DPrintf ("R_DrawSprite: no such frame %d (%s)\n", frame, currententity->model->name); + frame = 0; + } + + if (psprite->frames[frame].type == SPR_SINGLE) + { + pspriteframe = psprite->frames[frame].frameptr; + } + else if (psprite->frames[frame].type == SPR_ANGLED) + { + pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr; + pspriteframe = pspritegroup->frames[(int)((r_refdef.viewangles[1]-currententity->angles[1])/360*8 + 0.5-4)&7]; + } + else + { + pspritegroup = (mspritegroup_t *)psprite->frames[frame].frameptr; + pintervals = pspritegroup->intervals; + numframes = pspritegroup->numframes; + fullinterval = pintervals[numframes-1]; + + time = currententity->frame1time; + + // when loading in Mod_LoadSpriteGroup, we guaranteed all interval values + // are positive, so we don't have to worry about division by 0 + targettime = time - ((int)(time / fullinterval)) * fullinterval; + + for (i=0 ; i<(numframes-1) ; i++) + { + if (pintervals[i] > targettime) + break; + } + + pspriteframe = pspritegroup->frames[i]; + } + + return pspriteframe; +} +*/ +static void D3D9_DrawSpriteModel (entity_t *e) +{ + vec3_t point; + mspriteframe_t *frame; + vec3_t forward, right, up; + msprite_t *psprite; + + d3dvert_t d3dvert[4]; + index_t vertindexes[6] = { + 0, 1, 2, + 0, 2, 3 + }; + +#ifdef Q3SHADERS + mpic_t *pic = e->forcedshader; +#else + mpic_t *pic = NULL; +#endif + + if (pic || !e->model) + { + int colour; + + colour = 0; + + ((unsigned char*)&colour)[0] = e->shaderRGBAf[2]*255; + ((unsigned char*)&colour)[1] = e->shaderRGBAf[1]*255; + ((unsigned char*)&colour)[2] = e->shaderRGBAf[0]*255; + ((unsigned char*)&colour)[3] = e->shaderRGBAf[3]*255; + + VectorCopy(vup, up); + VectorCopy(vright, right); + + up[0]*=e->scale; + up[1]*=e->scale; + up[2]*=e->scale; + right[0]*=e->scale; + right[1]*=e->scale; + right[2]*=e->scale; + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); \ + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); \ + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, FALSE); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHABLENDENABLE, TRUE); + + if (pic) + IDirect3DDevice9_SetTexture(pD3DDev9, 0, *(LPDIRECT3DBASETEXTURE9*)&pic->d); + else + IDirect3DDevice9_SetTexture(pD3DDev9, 0, NULL); + + if (e->flags & RF_NODEPTHTEST) + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZFUNC, D3DCMP_ALWAYS); + + d3dvert[0].colour = colour; + d3dvert[0].tc[0] = 0; + d3dvert[0].tc[1] = 1; + VectorMA (e->origin, -1, up, point); + VectorMA (point, -1, right, d3dvert[0].pos); + + d3dvert[1].colour = colour; + d3dvert[1].tc[0] = 0; + d3dvert[1].tc[0] = 0; + VectorMA (e->origin, 1, up, point); + VectorMA (point, -1, right, d3dvert[1].pos); + + d3dvert[2].colour = colour; + d3dvert[2].tc[0] = 1; + d3dvert[2].tc[1] = 0; + VectorMA (e->origin, 1, up, point); + VectorMA (point, 1, right, d3dvert[2].pos); + + d3dvert[3].colour = colour; + d3dvert[3].tc[0] = 1; + d3dvert[3].tc[1] = 1; + VectorMA (e->origin, -1, up, point); + VectorMA (point, 1, right, d3dvert[3].pos); + + IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, 4, 2, vertindexes, D3DFMT_QINDEX, d3dvert, sizeof(d3dvert[0])); + + + if (e->flags & RF_NODEPTHTEST) + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZFUNC, D3DCMP_LESSEQUAL); + + return; + } + + if (!e->model) + return; + + if (e->flags & RF_NODEPTHTEST) + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZFUNC, D3DCMP_ALWAYS); + + // don't even bother culling, because it's just a single + // polygon without a surface cache + frame = R_GetSpriteFrame (e); + if (!frame) + return; + psprite = e->model->cache.data; +// frame = 0x05b94140; + + switch(psprite->type) + { + case SPR_ORIENTED: + // bullet marks on walls + AngleVectors (e->angles, forward, right, up); + break; + + case SPR_FACING_UPRIGHT: + up[0] = 0;up[1] = 0;up[2]=1; + right[0] = e->origin[1] - r_origin[1]; + right[1] = -(e->origin[0] - r_origin[0]); + right[2] = 0; + VectorNormalize (right); + break; + case SPR_VP_PARALLEL_UPRIGHT: + up[0] = 0;up[1] = 0;up[2]=1; + VectorCopy (vright, right); + break; + + default: + case SPR_VP_PARALLEL: + //normal sprite + VectorCopy(vup, up); + VectorCopy(vright, right); + break; + } + up[0]*=e->scale; + up[1]*=e->scale; + up[2]*=e->scale; + right[0]*=e->scale; + right[1]*=e->scale; + right[2]*=e->scale; + + IDirect3DDevice9_SetTexture(pD3DDev9, 0, *(void**)&frame->p.d); + +/* { + extern int gldepthfunc; + qglDepthFunc(gldepthfunc); + qglDepthMask(0); + if (gldepthmin == 0.5) + qglCullFace ( GL_BACK ); + else + qglCullFace ( GL_FRONT ); + + GL_TexEnv(GL_MODULATE); + + qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + qglDisable (GL_ALPHA_TEST); + qglDisable(GL_BLEND); + }*/ + +/* if (e->flags & Q2RF_ADDATIVE) + { + qglEnable(GL_BLEND); + qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + qglBlendFunc(GL_SRC_ALPHA, GL_ONE); + } + else if (e->shaderRGBAf[3]<1 || gl_blendsprites.value) + { + qglEnable(GL_BLEND); + qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + } + else + qglEnable (GL_ALPHA_TEST); +*/ + + d3dvert[0].colour = 0xffffffff; + d3dvert[0].tc[0] = 0; + d3dvert[0].tc[1] = 1; + VectorMA (e->origin, frame->down, up, point); + VectorMA (point, frame->left, right, d3dvert[0].pos); + + d3dvert[1].colour = 0xffffffff; + d3dvert[1].tc[0] = 0; + d3dvert[1].tc[0] = 0; + VectorMA (e->origin, frame->up, up, point); + VectorMA (point, frame->left, right, d3dvert[1].pos); + + d3dvert[2].colour = 0xffffffff; + d3dvert[2].tc[0] = 1; + d3dvert[2].tc[1] = 0; + VectorMA (e->origin, frame->up, up, point); + VectorMA (point, frame->right, right, d3dvert[2].pos); + + d3dvert[3].colour = 0xffffffff; + d3dvert[3].tc[0] = 1; + d3dvert[3].tc[1] = 1; + VectorMA (e->origin, frame->down, up, point); + VectorMA (point, frame->right, right, d3dvert[3].pos); + + IDirect3DDevice9_SetFVF(pD3DDev9, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); + IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, D3DPT_TRIANGLELIST, 0, 4, 2, vertindexes, D3DFMT_QINDEX, d3dvert, sizeof(d3dvert[0])); + + + if (e->flags & RF_NODEPTHTEST) + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZFUNC, D3DCMP_LESSEQUAL); + +// if (e->flags & Q2RF_ADDATIVE) //back to regular blending for us! +// qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + +//================================================================================== + void D3D9R_DrawSprite(int count, void **e, void *parm) { while(count--) @@ -1163,731 +1163,728 @@ void D3D9R_DrawSprite(int count, void **e, void *parm) D3D9_DrawSpriteModel (currententity); } -} - - - -qboolean D3D9_ShouldDraw(void) -{ - { - if (currententity->flags & Q2RF_EXTERNALMODEL) - return false; -// if (currententity->keynum == (cl.viewentity[r_refdef.currentplayernum]?cl.viewentity[r_refdef.currentplayernum]:(cl.playernum[r_refdef.currentplayernum]+1))) -// return false; -// if (cl.viewentity[r_refdef.currentplayernum] && currententity->keynum == cl.viewentity[r_refdef.currentplayernum]) -// continue; - if (!Cam_DrawPlayer(r_refdef.currentplayernum, currententity->keynum-1)) - return false; - } - return true; -} - - -void D3D9_R_DrawEntitiesOnList (void) -{ - int i; - - if (!r_drawentities.value) - return; - - // draw sprites seperately, because of alpha blending - for (i=0 ; irtype) - { - case RT_SPRITE: - RQ_AddDistReorder(D3D9R_DrawSprite, currententity, NULL, currententity->origin); - continue; -#ifdef Q3SHADERS - case RT_BEAM: - case RT_RAIL_RINGS: - case RT_LIGHTNING: -// R_DrawLightning(currententity); - continue; - case RT_RAIL_CORE: -// R_DrawRailCore(currententity); - continue; -#endif - case RT_MODEL: //regular model - break; - case RT_PORTALSURFACE: - continue; //this doesn't do anything anyway, does it? - default: - case RT_POLY: //these are a little painful, we need to do them some time... just not yet. - continue; - } - if (currententity->flags & Q2RF_BEAM) - { -// R_DrawBeam(currententity); - continue; - } - if (!currententity->model) - continue; - - - if (cl.lerpents && (cls.allow_anyparticles || currententity->visframe)) //allowed or static - { -/* if (gl_part_flame.value) - { - if (currententity->model->engineflags & MDLF_ENGULPHS) - continue; - }*/ - } - - switch (currententity->model->type) - { - - case mod_alias: -// if (r_refdef.flags & Q2RDF_NOWORLDMODEL || !cl.worldmodel || cl.worldmodel->type != mod_brush || cl.worldmodel->fromgame == fg_doom) - D3D9_DrawAliasModel (); - break; - -#ifdef HALFLIFEMODELS - case mod_halflife: - R_DrawHLModel (currententity); - break; -#endif - - case mod_brush: -// if (!cl.worldmodel || cl.worldmodel->type != mod_brush || cl.worldmodel->fromgame == fg_doom) - D3D9_BaseBModelTextures (currententity); - break; - - case mod_sprite: - RQ_AddDistReorder(D3D9R_DrawSprite, currententity, NULL, currententity->origin); - break; -/* -#ifdef TERRAIN - case mod_heightmap: - D3D9_DrawHeightmapModel(currententity); - break; -#endif -*/ - default: - break; - } - } - - { - float m_identity[16] = { - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 - }; - IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_WORLD, (D3DMATRIX*)m_identity); - } -} - -void D3D9_DrawWorld(void) -{ - RSpeedLocals(); - entity_t ent; - - memset (&ent, 0, sizeof(ent)); - ent.model = cl.worldmodel; - currentmodel = cl.worldmodel; - - VectorCopy (r_refdef.vieworg, modelorg); - - currententity = &ent; -#ifdef TERRAIN -// FIXME: Dunno what needs to be fixed here? -// if (currentmodel->type == mod_heightmap) -// D3D9_DrawHeightmapModel(currententity); -// else -#endif - { -// qglColor3f (1,1,1); - //#ifdef QUAKE2 -// R_ClearSkyBox (); - //#endif - - RSpeedRemark(); - -#ifdef Q2BSPS - if (ent.model->fromgame == fg_quake2 || ent.model->fromgame == fg_quake3) - { - int leafnum; - int clientarea; -#ifdef QUAKE2 - if (cls.protocol == CP_QUAKE2) //we can get server sent info - memcpy(areabits, cl.q2frame.areabits, sizeof(areabits)); - else -#endif - { //generate the info each frame. - leafnum = CM_PointLeafnum (cl.worldmodel, r_refdef.vieworg); - clientarea = CM_LeafArea (cl.worldmodel, leafnum); - CM_WriteAreaBits(cl.worldmodel, areabits, clientarea); - } -#ifdef Q3BSPS - if (ent.model->fromgame == fg_quake3) +} + + + +qboolean D3D9_ShouldDraw(void) +{ + { + if (currententity->flags & Q2RF_EXTERNALMODEL) + return false; +// if (currententity->keynum == (cl.viewentity[r_refdef.currentplayernum]?cl.viewentity[r_refdef.currentplayernum]:(cl.playernum[r_refdef.currentplayernum]+1))) +// return false; +// if (cl.viewentity[r_refdef.currentplayernum] && currententity->keynum == cl.viewentity[r_refdef.currentplayernum]) +// continue; + if (!Cam_DrawPlayer(r_refdef.currentplayernum, currententity->keynum-1)) + return false; + } + return true; +} + + +void D3D9_R_DrawEntitiesOnList (void) +{ + int i; + + if (!r_drawentities.value) + return; + + // draw sprites seperately, because of alpha blending + for (i=0 ; irtype) + { + case RT_SPRITE: + RQ_AddDistReorder(D3D9R_DrawSprite, currententity, NULL, currententity->origin); + continue; +#ifdef Q3SHADERS + case RT_BEAM: + case RT_RAIL_RINGS: + case RT_LIGHTNING: +// R_DrawLightning(currententity); + continue; + case RT_RAIL_CORE: +// R_DrawRailCore(currententity); + continue; +#endif + case RT_MODEL: //regular model + break; + case RT_PORTALSURFACE: + continue; //this doesn't do anything anyway, does it? + default: + case RT_POLY: //these are a little painful, we need to do them some time... just not yet. + continue; + } + if (currententity->flags & Q2RF_BEAM) + { +// R_DrawBeam(currententity); + continue; + } + if (!currententity->model) + continue; + + + if (cl.lerpents && (cls.allow_anyparticles || currententity->visframe)) //allowed or static + { +/* if (gl_part_flame.value) { - R_MarkLeaves_Q3 (); - D3D9_LeafWorldNode (); - } - else + if (currententity->model->engineflags & MDLF_ENGULPHS) + continue; + }*/ + } + + switch (currententity->model->type) + { + + case mod_alias: +// if (r_refdef.flags & Q2RDF_NOWORLDMODEL || !cl.worldmodel || cl.worldmodel->type != mod_brush || cl.worldmodel->fromgame == fg_doom) + D3D9_DrawAliasModel (); + break; + +#ifdef HALFLIFEMODELS + case mod_halflife: + R_DrawHLModel (currententity); + break; +#endif + + case mod_brush: +// if (!cl.worldmodel || cl.worldmodel->type != mod_brush || cl.worldmodel->fromgame == fg_doom) + D3D9_BaseBModelTextures (currententity); + break; + + case mod_sprite: + RQ_AddDistReorder(D3D9R_DrawSprite, currententity, NULL, currententity->origin); + break; +/* +#ifdef TERRAIN + case mod_heightmap: + D3D9_DrawHeightmapModel(currententity); + break; +#endif +*/ + default: + break; + } + } + + { + float m_identity[16] = { + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + }; + IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_WORLD, (D3DMATRIX*)m_identity); + } +} + +void D3D9_DrawWorld(void) +{ + RSpeedLocals(); + entity_t ent; + + memset (&ent, 0, sizeof(ent)); + ent.model = cl.worldmodel; + currentmodel = cl.worldmodel; + + VectorCopy (r_refdef.vieworg, modelorg); + + currententity = &ent; +#ifdef TERRAIN +// FIXME: Dunno what needs to be fixed here? +// if (currentmodel->type == mod_heightmap) +// D3D9_DrawHeightmapModel(currententity); +// else +#endif + { +// qglColor3f (1,1,1); + + RSpeedRemark(); + +#ifdef Q2BSPS + if (ent.model->fromgame == fg_quake2 || ent.model->fromgame == fg_quake3) + { + int leafnum; + int clientarea; +#ifdef QUAKE2 + if (cls.protocol == CP_QUAKE2) //we can get server sent info + memcpy(areabits, cl.q2frame.areabits, sizeof(areabits)); + else +#endif + { //generate the info each frame. + leafnum = CM_PointLeafnum (cl.worldmodel, r_refdef.vieworg); + clientarea = CM_LeafArea (cl.worldmodel, leafnum); + CM_WriteAreaBits(cl.worldmodel, areabits, clientarea); + } +#ifdef Q3BSPS + if (ent.model->fromgame == fg_quake3) + { + R_MarkLeaves_Q3 (); + D3D9_LeafWorldNode (); + } + else #endif { - R_MarkLeaves_Q2 (); + R_MarkLeaves_Q2 (); D3D9_RecursiveQ2WorldNode (cl.worldmodel->nodes); - } - } - else + } + } + else #endif { - R_MarkLeaves_Q1 (); + R_MarkLeaves_Q1 (); D3D9_RecursiveWorldNode (cl.worldmodel->nodes); - } - - RSpeedEnd(RSPEED_WORLDNODE); - TRACE(("dbg: calling PPL_DrawWorld\n")); -// if (r_shadows.value >= 2 && gl_canstencil && gl_mtexable) - D3D9_DrawTextureChains(); -// else -// DrawTextureChains (cl.worldmodel, 1, r_refdef.vieworg); - - -//qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - -// GLR_LessenStains(); - } -} - -void D3D9_R_RenderScene(void) -{ - if (!cl.worldmodel || (!cl.worldmodel->nodes && cl.worldmodel->type != mod_heightmap)) - r_refdef.flags |= Q2RDF_NOWORLDMODEL; - - if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL)) - { - D3D9_DrawWorld (); // adds static entities to the list - } - - D3D9_R_DrawEntitiesOnList (); - - if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL)) - P_DrawParticles(); - - D3D9_Set2D(); -} - -void (D3D9_R_RenderView) (void) -{ - D3D9_SetupFrame(); - D3D9_SetupViewPort(); - R_SetFrustum(); - D3D9_R_RenderScene(); -} - - + } + + RSpeedEnd(RSPEED_WORLDNODE); + TRACE(("dbg: calling PPL_DrawWorld\n")); +// if (r_shadows.value >= 2 && gl_canstencil && gl_mtexable) + D3D9_DrawTextureChains(); +// else +// DrawTextureChains (cl.worldmodel, 1, r_refdef.vieworg); + + +//qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + +// GLR_LessenStains(); + } +} + +void D3D9_R_RenderScene(void) +{ + if (!cl.worldmodel || (!cl.worldmodel->nodes && cl.worldmodel->type != mod_heightmap)) + r_refdef.flags |= Q2RDF_NOWORLDMODEL; + + if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL)) + { + D3D9_DrawWorld (); // adds static entities to the list + } + + D3D9_R_DrawEntitiesOnList (); + + if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL)) + P_DrawParticles(); + + D3D9_Set2D(); +} + +void (D3D9_R_RenderView) (void) +{ + D3D9_SetupFrame(); + D3D9_SetupViewPort(); + R_SetFrustum(); + D3D9_R_RenderScene(); +} + + #ifdef PSET_SCRIPT - + #include "particles.h" #define TYPESONLY -#include "p_script.c" - -#define APPLYD3D9BLEND(bm) \ - switch (bm) \ - { \ - case BM_ADD: \ - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); \ - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DESTBLEND, D3DBLEND_ONE); \ - break; \ - case BM_SUBTRACT: \ - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); \ - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR); \ - break; \ - case BM_BLENDCOLOUR: \ - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR); \ - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR); \ - break; \ - case BM_BLEND: \ - default: \ - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); \ - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); \ - break; \ - } - - -typedef struct d3dparticlevert_s { - float org[3]; - unsigned int colour; - float s, t; //these could actually be preinitialised -} d3dparticlevert_t; -d3dparticlevert_t d3dparticlevert[4]; - -typedef struct d3dparticlevertut_s { - float org[3]; - unsigned int colour; -} d3dparticlevertut_t; +#include "p_script.c" + +#define APPLYD3D9BLEND(bm) \ + switch (bm) \ + { \ + case BM_ADD: \ + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); \ + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DESTBLEND, D3DBLEND_ONE); \ + break; \ + case BM_SUBTRACT: \ + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); \ + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR); \ + break; \ + case BM_BLENDCOLOUR: \ + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR); \ + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR); \ + break; \ + case BM_BLEND: \ + default: \ + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); \ + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); \ + break; \ + } + + +typedef struct d3dparticlevert_s { + float org[3]; + unsigned int colour; + float s, t; //these could actually be preinitialised +} d3dparticlevert_t; +d3dparticlevert_t d3dparticlevert[4]; + +typedef struct d3dparticlevertut_s { + float org[3]; + unsigned int colour; +} d3dparticlevertut_t; d3dparticlevertut_t d3dparticlevertut[4]; - -static vec3_t pright, pup; -static float particletime; - -void IDirect3DDevice9_DrawIndexedPrimitive7(LPDIRECT3DDEVICE9 pD3DDev9, int mode, int fvf, void *verts, int numverts, index_t *indicies, int numindicies, int wasted) -{ - int size = 0; - if (fvf & D3DFVF_XYZ) - size += 12; - if (fvf & D3DFVF_DIFFUSE) - size += 4; - if (fvf & D3DFVF_TEX1) - size += 8; - - IDirect3DDevice9_SetFVF(pD3DDev9, fvf); - IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, mode, 0, numverts, numindicies/3, indicies, D3DFMT_QINDEX, verts, size); + +static vec3_t pright, pup; +static float particletime; + +void IDirect3DDevice9_DrawIndexedPrimitive7(LPDIRECT3DDEVICE9 pD3DDev9, int mode, int fvf, void *verts, int numverts, index_t *indicies, int numindicies, int wasted) +{ + int size = 0; + if (fvf & D3DFVF_XYZ) + size += 12; + if (fvf & D3DFVF_DIFFUSE) + size += 4; + if (fvf & D3DFVF_TEX1) + size += 8; + + IDirect3DDevice9_SetFVF(pD3DDev9, fvf); + IDirect3DDevice9_DrawIndexedPrimitiveUP(pD3DDev9, mode, 0, numverts, numindicies/3, indicies, D3DFMT_QINDEX, verts, size); } - -index_t d3d9particlevertindexes[] = -{ - 0, 1, 2, - 0, 2, 3 -}; - -void D3D9_DrawParticleBlob(int count, particle_t **plist, plooks_t *type) -{ - float scale; - float x; - float y; - unsigned int colour; + +index_t d3d9particlevertindexes[] = +{ + 0, 1, 2, + 0, 2, 3 +}; + +void D3D9_DrawParticleBlob(int count, particle_t **plist, plooks_t *type) +{ + float scale; + float x; + float y; + unsigned int colour; int cb, cg, cr, ca; - particle_t *p; - - IDirect3DDevice9_SetTexture(pD3DDev9, 0, type->d3dtexture); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); - - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - - APPLYD3D9BLEND(type->blendmode); - + particle_t *p; + + IDirect3DDevice9_SetTexture(pD3DDev9, 0, type->d3dtexture); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + APPLYD3D9BLEND(type->blendmode); + while(count--) { p = *plist++; - - scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1] - + (p->org[2] - r_origin[2])*vpn[2]; - scale = (scale*p->scale)*(type->invscalefactor) + p->scale * (type->scalefactor*250); - if (scale < 20) - scale = 0.25; - else - scale = 0.25 + scale * 0.001; - - cr = p->rgb[0]*255; - if (cr < 0) cr = 0; - if (cr > 255) cr = 255; - - cg = p->rgb[1]*255; - if (cg < 0) cg = 0; - if (cg > 255) cg = 255; - - cb = p->rgb[2]*255; - if (cb < 0) cb = 0; - if (cb > 255) cb = 255; - - ca = p->alpha*255; - if (ca < 0) ca = 0; - if (ca > 255) ca = 255; - - colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); - - if (p->angle) - { - x = sin(p->angle)*scale; - y = cos(p->angle)*scale; - } - else - { - x = 0; - y = scale; - } - d3dparticlevert[0].s = 0; - d3dparticlevert[0].t = 0; - d3dparticlevert[0].colour = colour; - d3dparticlevert[0].org[0] = p->org[0] - x*pright[0] - y*pup[0]; - d3dparticlevert[0].org[1] = p->org[1] - x*pright[1] - y*pup[1]; - d3dparticlevert[0].org[2] = p->org[2] - x*pright[2] - y*pup[2]; - - d3dparticlevert[1].s = 0; - d3dparticlevert[1].t = 1; - d3dparticlevert[1].colour = colour; - d3dparticlevert[1].org[0] = p->org[0] - y*pright[0] + x*pup[0]; - d3dparticlevert[1].org[1] = p->org[1] - y*pright[1] + x*pup[1]; - d3dparticlevert[1].org[2] = p->org[2] - y*pright[2] + x*pup[2]; - - d3dparticlevert[2].s = 1; - d3dparticlevert[2].t = 1; - d3dparticlevert[2].colour = colour; - d3dparticlevert[2].org[0] = p->org[0] + x*pright[0] + y*pup[0]; - d3dparticlevert[2].org[1] = p->org[1] + x*pright[1] + y*pup[1]; - d3dparticlevert[2].org[2] = p->org[2] + x*pright[2] + y*pup[2]; - - d3dparticlevert[3].s = 1; - d3dparticlevert[3].t = 0; - d3dparticlevert[3].colour = colour; - d3dparticlevert[3].org[0] = p->org[0] + y*pright[0] - x*pup[0]; - d3dparticlevert[3].org[1] = p->org[1] + y*pright[1] - x*pup[1]; - d3dparticlevert[3].org[2] = p->org[2] + y*pright[2] - x*pup[2]; - //FIXME: batch properly - IDirect3DDevice9_DrawIndexedPrimitive7(pD3DDev9, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dparticlevert, 4, d3d9particlevertindexes, 6, 0); - } -} -void D3D9_DrawParticleSpark(int count, particle_t **plist, plooks_t *type) -{ - vec3_t v, crv, o2; - - unsigned int colour; - int cb, cg, cr, ca; - particle_t *p; - - IDirect3DDevice9_SetTexture(pD3DDev9, 0, type->d3dtexture); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); - - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - - APPLYD3D9BLEND(type->blendmode); - - while(count--) - { - p = *plist++; - - cr = p->rgb[0]*255; - if (cr < 0) cr = 0; - if (cr > 255) cr = 255; - - cg = p->rgb[1]*255; - if (cg < 0) cg = 0; - if (cg > 255) cg = 255; - - cb = p->rgb[2]*255; - if (cb < 0) cb = 0; - if (cb > 255) cb = 255; - - ca = p->alpha*255; - if (ca < 0) ca = 0; - if (ca > 255) ca = 255; - - colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); - - - - - VectorSubtract(r_refdef.vieworg, p->org, v); - CrossProduct(v, p->vel, crv); - VectorNormalize(crv); - - VectorMA(p->org, -p->scale/2, crv, d3dparticlevert[0].org); - d3dparticlevert[0].s = 0; - d3dparticlevert[0].t = 0; - d3dparticlevert[0].colour = colour; - - VectorMA(p->org, p->scale/2, crv, d3dparticlevert[1].org); - d3dparticlevert[1].s = 0; - d3dparticlevert[1].t = 1; - d3dparticlevert[1].colour = colour; - - - VectorMA(p->org, 0.1, p->vel, o2); - - VectorSubtract(r_refdef.vieworg, o2, v); - CrossProduct(v, p->vel, crv); - VectorNormalize(crv); - - VectorMA(o2, p->scale/2, crv, d3dparticlevert[2].org); - d3dparticlevert[2].s = 1; - d3dparticlevert[2].t = 1; - d3dparticlevert[2].colour = colour; - - VectorMA(o2, -p->scale/2, crv, d3dparticlevert[3].org); - d3dparticlevert[3].s = 1; - d3dparticlevert[3].t = 0; - d3dparticlevert[3].colour = colour; - - //FIXME: batch properly - IDirect3DDevice9_DrawIndexedPrimitive7(pD3DDev9, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dparticlevert, 4, d3d9particlevertindexes, 6, 0); - } -} -void D3D9_DrawParticleBeam(int count, beamseg_t **blist, plooks_t *type) -{ - vec3_t v; - vec3_t crv; - beamseg_t *b, *c; - particle_t *p; - particle_t *q; - float ts; - - - unsigned int colour; - int cb, cg, cr, ca; - - - IDirect3DDevice9_SetTexture(pD3DDev9, 0, type->d3dtexture); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); - - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - - APPLYD3D9BLEND(type->blendmode); - - - - while(count--) - { - b = *blist++; - c = b->next; - q = c->p; - p = b->p; - - - cr = q->rgb[0]*255; - if (cr < 0) cr = 0; - if (cr > 255) cr = 255; - - cg = q->rgb[1]*255; - if (cg < 0) cg = 0; - if (cg > 255) cg = 255; - - cb = q->rgb[2]*255; - if (cb < 0) cb = 0; - if (cb > 255) cb = 255; - - ca = q->alpha*255; - if (ca < 0) ca = 0; - if (ca > 255) ca = 255; - - colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); - - - - - - c = b->next; - - q = c->p; - - p = b->p; - - VectorSubtract(r_refdef.vieworg, q->org, v); - VectorNormalize(v); - CrossProduct(c->dir, v, crv); - ts = c->texture_s*q->angle + particletime*q->rotationspeed; - - VectorMA(q->org, -q->scale, crv, d3dparticlevert[0].org); - d3dparticlevert[0].s = ts; - d3dparticlevert[0].t = 0; - d3dparticlevert[0].colour = colour; - - VectorMA(q->org, q->scale, crv, d3dparticlevert[1].org); - d3dparticlevert[1].s = ts; - d3dparticlevert[1].t = 1; - d3dparticlevert[1].colour = colour; - - - cr = p->rgb[0]*255; - if (cr < 0) cr = 0; - if (cr > 255) cr = 255; - - cg = p->rgb[1]*255; - if (cg < 0) cg = 0; - if (cg > 255) cg = 255; - - cb = p->rgb[2]*255; - if (cb < 0) cb = 0; - if (cb > 255) cb = 255; - - ca = p->alpha*255; - if (ca < 0) ca = 0; - if (ca > 255) ca = 255; - - colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); - - - VectorSubtract(r_refdef.vieworg, p->org, v); - VectorNormalize(v); - CrossProduct(b->dir, v, crv); // replace with old p->dir? - ts = b->texture_s*p->angle + particletime*p->rotationspeed; - - VectorMA(p->org, p->scale, crv, d3dparticlevert[2].org); - d3dparticlevert[2].s = ts; - d3dparticlevert[2].t = 1; - d3dparticlevert[2].colour = colour; - - VectorMA(p->org, -p->scale, crv, d3dparticlevert[3].org); - d3dparticlevert[3].s = ts; - d3dparticlevert[3].t = 0; - d3dparticlevert[3].colour = colour; - + scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1] + + (p->org[2] - r_origin[2])*vpn[2]; + scale = (scale*p->scale)*(type->invscalefactor) + p->scale * (type->scalefactor*250); + if (scale < 20) + scale = 0.25; + else + scale = 0.25 + scale * 0.001; - //FIXME: batch properly + cr = p->rgb[0]*255; + if (cr < 0) cr = 0; + if (cr > 255) cr = 255; + + cg = p->rgb[1]*255; + if (cg < 0) cg = 0; + if (cg > 255) cg = 255; + + cb = p->rgb[2]*255; + if (cb < 0) cb = 0; + if (cb > 255) cb = 255; + + ca = p->alpha*255; + if (ca < 0) ca = 0; + if (ca > 255) ca = 255; + + colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); + + if (p->angle) + { + x = sin(p->angle)*scale; + y = cos(p->angle)*scale; + } + else + { + x = 0; + y = scale; + } + d3dparticlevert[0].s = 0; + d3dparticlevert[0].t = 0; + d3dparticlevert[0].colour = colour; + d3dparticlevert[0].org[0] = p->org[0] - x*pright[0] - y*pup[0]; + d3dparticlevert[0].org[1] = p->org[1] - x*pright[1] - y*pup[1]; + d3dparticlevert[0].org[2] = p->org[2] - x*pright[2] - y*pup[2]; + + d3dparticlevert[1].s = 0; + d3dparticlevert[1].t = 1; + d3dparticlevert[1].colour = colour; + d3dparticlevert[1].org[0] = p->org[0] - y*pright[0] + x*pup[0]; + d3dparticlevert[1].org[1] = p->org[1] - y*pright[1] + x*pup[1]; + d3dparticlevert[1].org[2] = p->org[2] - y*pright[2] + x*pup[2]; + + d3dparticlevert[2].s = 1; + d3dparticlevert[2].t = 1; + d3dparticlevert[2].colour = colour; + d3dparticlevert[2].org[0] = p->org[0] + x*pright[0] + y*pup[0]; + d3dparticlevert[2].org[1] = p->org[1] + x*pright[1] + y*pup[1]; + d3dparticlevert[2].org[2] = p->org[2] + x*pright[2] + y*pup[2]; + + d3dparticlevert[3].s = 1; + d3dparticlevert[3].t = 0; + d3dparticlevert[3].colour = colour; + d3dparticlevert[3].org[0] = p->org[0] + y*pright[0] - x*pup[0]; + d3dparticlevert[3].org[1] = p->org[1] + y*pright[1] - x*pup[1]; + d3dparticlevert[3].org[2] = p->org[2] + y*pright[2] - x*pup[2]; + + //FIXME: batch properly IDirect3DDevice9_DrawIndexedPrimitive7(pD3DDev9, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dparticlevert, 4, d3d9particlevertindexes, 6, 0); - } -} - -void D3D9_DrawParticleBeamUT(int count, beamseg_t **blist, plooks_t *type) -{ - vec3_t v; - vec3_t crv; - beamseg_t *b, *c; - particle_t *p; - particle_t *q; - float ts; - - - unsigned int colour; - int cb, cg, cr, ca; - - - IDirect3DDevice9_SetTexture(pD3DDev9, 0, NULL); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2); - - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); - - - APPLYD3D9BLEND(type->blendmode); - - - while(count--) - { - b = *blist++; - c = b->next; - q = c->p; - p = b->p; - - - cr = q->rgb[0]*255; - if (cr < 0) cr = 0; - if (cr > 255) cr = 255; - - cg = q->rgb[1]*255; - if (cg < 0) cg = 0; - if (cg > 255) cg = 255; - - cb = q->rgb[2]*255; - if (cb < 0) cb = 0; - if (cb > 255) cb = 255; - - ca = q->alpha*255; - if (ca < 0) ca = 0; - if (ca > 255) ca = 255; - - colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); - - - - - - c = b->next; - - q = c->p; - - p = b->p; - - VectorSubtract(r_refdef.vieworg, q->org, v); - VectorNormalize(v); - CrossProduct(c->dir, v, crv); - ts = c->texture_s*q->angle + particletime*q->rotationspeed; - - VectorMA(q->org, -q->scale, crv, d3dparticlevertut[0].org); - d3dparticlevertut[0].colour = colour; - - VectorMA(q->org, q->scale, crv, d3dparticlevertut[1].org); - d3dparticlevertut[1].colour = colour; - - - cr = p->rgb[0]*255; - if (cr < 0) cr = 0; - if (cr > 255) cr = 255; - - cg = p->rgb[1]*255; - if (cg < 0) cg = 0; - if (cg > 255) cg = 255; - - cb = p->rgb[2]*255; - if (cb < 0) cb = 0; - if (cb > 255) cb = 255; - - ca = p->alpha*255; - if (ca < 0) ca = 0; - if (ca > 255) ca = 255; - - colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); - - - VectorSubtract(r_refdef.vieworg, p->org, v); - VectorNormalize(v); - CrossProduct(b->dir, v, crv); // replace with old p->dir? - ts = b->texture_s*p->angle + particletime*p->rotationspeed;; - - VectorMA(p->org, p->scale, crv, d3dparticlevertut[2].org); - d3dparticlevertut[2].colour = colour; - - VectorMA(p->org, -p->scale, crv, d3dparticlevertut[3].org); - d3dparticlevertut[3].colour = colour; - - - IDirect3DDevice9_DrawIndexedPrimitive7(pD3DDev9, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE, d3dparticlevertut, 4, d3d9particlevertindexes, 6, 0); - } -} - - - - - - -void D3D9_DrawParticles(float ptime) -{ - RSpeedLocals(); - - particletime = ptime; - VectorScale (vup, 1.5, pup); - VectorScale (vright, 1.5, pright); - - IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); //they're not all mipmapped - IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - - PScript_DrawParticleTypes(D3D9_DrawParticleBlob, D3D9_DrawParticleSpark, D3D9_DrawParticleSpark, D3D9_DrawParticleSpark, D3D9_DrawParticleBeam, D3D9_DrawParticleBeamUT, NULL); - - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZWRITEENABLE, FALSE ); - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, FALSE ); - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHABLENDENABLE, TRUE ); - - RSpeedRemark(); - RQ_RenderDistAndClear(); - RSpeedEnd(RSPEED_PARTICLESDRAW); - - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZWRITEENABLE, TRUE ); - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, TRUE ); - IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHABLENDENABLE, FALSE ); - - IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); - - - IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT); - IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); - IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + } } -#endif -#endif +void D3D9_DrawParticleSpark(int count, particle_t **plist, plooks_t *type) +{ + vec3_t v, crv, o2; + + unsigned int colour; + int cb, cg, cr, ca; + particle_t *p; + + IDirect3DDevice9_SetTexture(pD3DDev9, 0, type->d3dtexture); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + APPLYD3D9BLEND(type->blendmode); + + while(count--) + { + p = *plist++; + + cr = p->rgb[0]*255; + if (cr < 0) cr = 0; + if (cr > 255) cr = 255; + + cg = p->rgb[1]*255; + if (cg < 0) cg = 0; + if (cg > 255) cg = 255; + + cb = p->rgb[2]*255; + if (cb < 0) cb = 0; + if (cb > 255) cb = 255; + + ca = p->alpha*255; + if (ca < 0) ca = 0; + if (ca > 255) ca = 255; + + colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); + + + + + VectorSubtract(r_refdef.vieworg, p->org, v); + CrossProduct(v, p->vel, crv); + VectorNormalize(crv); + + VectorMA(p->org, -p->scale/2, crv, d3dparticlevert[0].org); + d3dparticlevert[0].s = 0; + d3dparticlevert[0].t = 0; + d3dparticlevert[0].colour = colour; + + VectorMA(p->org, p->scale/2, crv, d3dparticlevert[1].org); + d3dparticlevert[1].s = 0; + d3dparticlevert[1].t = 1; + d3dparticlevert[1].colour = colour; + + + VectorMA(p->org, 0.1, p->vel, o2); + + VectorSubtract(r_refdef.vieworg, o2, v); + CrossProduct(v, p->vel, crv); + VectorNormalize(crv); + + VectorMA(o2, p->scale/2, crv, d3dparticlevert[2].org); + d3dparticlevert[2].s = 1; + d3dparticlevert[2].t = 1; + d3dparticlevert[2].colour = colour; + + VectorMA(o2, -p->scale/2, crv, d3dparticlevert[3].org); + d3dparticlevert[3].s = 1; + d3dparticlevert[3].t = 0; + d3dparticlevert[3].colour = colour; + + //FIXME: batch properly + IDirect3DDevice9_DrawIndexedPrimitive7(pD3DDev9, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dparticlevert, 4, d3d9particlevertindexes, 6, 0); + } +} +void D3D9_DrawParticleBeam(int count, beamseg_t **blist, plooks_t *type) +{ + vec3_t v; + vec3_t crv; + beamseg_t *b, *c; + particle_t *p; + particle_t *q; + float ts; + + + unsigned int colour; + int cb, cg, cr, ca; + + + IDirect3DDevice9_SetTexture(pD3DDev9, 0, type->d3dtexture); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + APPLYD3D9BLEND(type->blendmode); + + + + while(count--) + { + b = *blist++; + c = b->next; + q = c->p; + p = b->p; + + + cr = q->rgb[0]*255; + if (cr < 0) cr = 0; + if (cr > 255) cr = 255; + + cg = q->rgb[1]*255; + if (cg < 0) cg = 0; + if (cg > 255) cg = 255; + + cb = q->rgb[2]*255; + if (cb < 0) cb = 0; + if (cb > 255) cb = 255; + + ca = q->alpha*255; + if (ca < 0) ca = 0; + if (ca > 255) ca = 255; + + colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); + + + + + + c = b->next; + + q = c->p; + + p = b->p; + + VectorSubtract(r_refdef.vieworg, q->org, v); + VectorNormalize(v); + CrossProduct(c->dir, v, crv); + ts = c->texture_s*q->angle + particletime*q->rotationspeed; + + VectorMA(q->org, -q->scale, crv, d3dparticlevert[0].org); + d3dparticlevert[0].s = ts; + d3dparticlevert[0].t = 0; + d3dparticlevert[0].colour = colour; + + VectorMA(q->org, q->scale, crv, d3dparticlevert[1].org); + d3dparticlevert[1].s = ts; + d3dparticlevert[1].t = 1; + d3dparticlevert[1].colour = colour; + + + cr = p->rgb[0]*255; + if (cr < 0) cr = 0; + if (cr > 255) cr = 255; + + cg = p->rgb[1]*255; + if (cg < 0) cg = 0; + if (cg > 255) cg = 255; + + cb = p->rgb[2]*255; + if (cb < 0) cb = 0; + if (cb > 255) cb = 255; + + ca = p->alpha*255; + if (ca < 0) ca = 0; + if (ca > 255) ca = 255; + + colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); + + + VectorSubtract(r_refdef.vieworg, p->org, v); + VectorNormalize(v); + CrossProduct(b->dir, v, crv); // replace with old p->dir? + ts = b->texture_s*p->angle + particletime*p->rotationspeed; + + VectorMA(p->org, p->scale, crv, d3dparticlevert[2].org); + d3dparticlevert[2].s = ts; + d3dparticlevert[2].t = 1; + d3dparticlevert[2].colour = colour; + + VectorMA(p->org, -p->scale, crv, d3dparticlevert[3].org); + d3dparticlevert[3].s = ts; + d3dparticlevert[3].t = 0; + d3dparticlevert[3].colour = colour; + + + //FIXME: batch properly + IDirect3DDevice9_DrawIndexedPrimitive7(pD3DDev9, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1, d3dparticlevert, 4, d3d9particlevertindexes, 6, 0); + } +} + +void D3D9_DrawParticleBeamUT(int count, beamseg_t **blist, plooks_t *type) +{ + vec3_t v; + vec3_t crv; + beamseg_t *b, *c; + particle_t *p; + particle_t *q; + float ts; + + + unsigned int colour; + int cb, cg, cr, ca; + + + IDirect3DDevice9_SetTexture(pD3DDev9, 0, NULL); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); + + + APPLYD3D9BLEND(type->blendmode); + + + while(count--) + { + b = *blist++; + c = b->next; + q = c->p; + p = b->p; + + + cr = q->rgb[0]*255; + if (cr < 0) cr = 0; + if (cr > 255) cr = 255; + + cg = q->rgb[1]*255; + if (cg < 0) cg = 0; + if (cg > 255) cg = 255; + + cb = q->rgb[2]*255; + if (cb < 0) cb = 0; + if (cb > 255) cb = 255; + + ca = q->alpha*255; + if (ca < 0) ca = 0; + if (ca > 255) ca = 255; + + colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); + + + + + + c = b->next; + + q = c->p; + + p = b->p; + + VectorSubtract(r_refdef.vieworg, q->org, v); + VectorNormalize(v); + CrossProduct(c->dir, v, crv); + ts = c->texture_s*q->angle + particletime*q->rotationspeed; + + VectorMA(q->org, -q->scale, crv, d3dparticlevertut[0].org); + d3dparticlevertut[0].colour = colour; + + VectorMA(q->org, q->scale, crv, d3dparticlevertut[1].org); + d3dparticlevertut[1].colour = colour; + + + cr = p->rgb[0]*255; + if (cr < 0) cr = 0; + if (cr > 255) cr = 255; + + cg = p->rgb[1]*255; + if (cg < 0) cg = 0; + if (cg > 255) cg = 255; + + cb = p->rgb[2]*255; + if (cb < 0) cb = 0; + if (cb > 255) cb = 255; + + ca = p->alpha*255; + if (ca < 0) ca = 0; + if (ca > 255) ca = 255; + + colour = (cb) | (cg<<8) | (cr << 16) | (ca << 24); + + + VectorSubtract(r_refdef.vieworg, p->org, v); + VectorNormalize(v); + CrossProduct(b->dir, v, crv); // replace with old p->dir? + ts = b->texture_s*p->angle + particletime*p->rotationspeed;; + + VectorMA(p->org, p->scale, crv, d3dparticlevertut[2].org); + d3dparticlevertut[2].colour = colour; + + VectorMA(p->org, -p->scale, crv, d3dparticlevertut[3].org); + d3dparticlevertut[3].colour = colour; + + + IDirect3DDevice9_DrawIndexedPrimitive7(pD3DDev9, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_DIFFUSE, d3dparticlevertut, 4, d3d9particlevertindexes, 6, 0); + } +} + + + + + + +void D3D9_DrawParticles(float ptime) +{ + RSpeedLocals(); + + particletime = ptime; + VectorScale (vup, 1.5, pup); + VectorScale (vright, 1.5, pright); + + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); //they're not all mipmapped + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + + PScript_DrawParticleTypes(D3D9_DrawParticleBlob, D3D9_DrawParticleSpark, D3D9_DrawParticleSpark, D3D9_DrawParticleSpark, D3D9_DrawParticleBeam, D3D9_DrawParticleBeamUT, NULL); + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZWRITEENABLE, FALSE ); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, FALSE ); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHABLENDENABLE, TRUE ); + + RSpeedRemark(); + RQ_RenderDistAndClear(); + RSpeedEnd(RSPEED_PARTICLESDRAW); + + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ZWRITEENABLE, TRUE ); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHATESTENABLE, TRUE ); + IDirect3DDevice9_SetRenderState(pD3DDev9, D3DRS_ALPHABLENDENABLE, FALSE ); + + IDirect3DDevice9_SetTextureStageState(pD3DDev9, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); + + + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); + IDirect3DDevice9_SetSamplerState(pD3DDev9, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); +} +#endif +#endif diff --git a/engine/d3d9/d3d9quake.h b/engine/d3d9/d3d9quake.h index 76672c55..625b49fa 100644 --- a/engine/d3d9/d3d9quake.h +++ b/engine/d3d9/d3d9quake.h @@ -1,204 +1,204 @@ //#include "ddraw.h" #ifndef D3D9QUAKE_H -#define D3D9QUAKE_H - - -#include "d3d9.h" -#include "com_mesh.h" -#include "glquake.h" - -// -// d3d9_draw.c -// -void D3D9_Draw_Alt_String (int x, int y, const qbyte *str); -void D3D9_Draw_BeginDisc (void); -mpic_t* D3D9_Draw_CachePic (char *path); -void D3D9_Draw_Character (int x, int y, unsigned int num); -void D3D9_Draw_ColouredCharacter (int x, int y, unsigned int num); -void D3D9_Draw_ConsoleBackground (int firstline, int lastline, qboolean forceopaque); -void D3D9_Draw_Crosshair (void); -void D3D9_Draw_DebugChar (qbyte num); -void D3D9_Draw_EditorBackground (int lines); -void D3D9_Draw_EndDisc (void); -void D3D9_Draw_FadeScreen (void); -void D3D9_Draw_Fill (int x, int y, int w, int h, unsigned int c); -void D3D9_Draw_Fill_Colours (int x, int y, int w, int h); -void D3D9_Draw_Fill_I (int x, int y, int w, int h, unsigned int imgcolour); -void D3D9_Draw_FillRGB (int x, int y, int w, int h, float r, float g, float b); -void D3D9_Draw_Image (float x, float y, float w, float h, float s1, float t1, float s2, float t2, mpic_t *pic); -void D3D9_Draw_ImageColours (float r, float g, float b, float a); -void D3D9_Draw_Init (void); -void D3D9_Draw_Pic (int x, int y, mpic_t *pic); -void D3D9_Draw_ReInit (void); -mpic_t* D3D9_Draw_SafeCachePic (char *path); -mpic_t* D3D9_Draw_SafePicFromWad (char *name); -void D3D9_Draw_ScalePic (int x, int y, int width, int height, mpic_t *pic); -void D3D9_Draw_String (int x, int y, const qbyte *str); -void D3D9_Draw_SubPic (int x, int y, mpic_t *pic, int srcx, int srcy, int width, int height); -void D3D9_Draw_TileClear (int x, int y, int w, int h); -void D3D9_Draw_TransPic (int x, int y, mpic_t *pic); -void D3D9_Draw_TransPicTranslate (int x, int y, int w, int h, qbyte *pic, qbyte *translation); -void D3D9_InitParticleTexture (void); -LPDIRECT3DBASETEXTURE9 D3D9_LoadTexture_32 (char *name, unsigned int *data, int width, int height, int flags); -LPDIRECT3DBASETEXTURE9 D3D9_LoadTexture_8_Pal24 (char *name, unsigned char *data, int width, int height, int flags, unsigned char *palette, int transparentpix); -LPDIRECT3DBASETEXTURE9 D3D9_LoadTexture_8_Pal32 (char *name, unsigned char *data, int width, int height, int flags, unsigned char *palette); -void D3D9_Media_ShowFrame8bit (qbyte *framedata, int inwidth, int inheight, qbyte *palette); -void D3D9_Media_ShowFrameBGR_24_Flip (qbyte *framedata, int inwidth, int inheight); -void D3D9_Media_ShowFrameRGBA_32 (qbyte *framedata, int inwidth, int inheight); -void D3D9_MipMap (qbyte *out, qbyte *in, int width, int height); -void D3D9_RoundDimensions (int *scaled_width, int *scaled_height, qboolean mipmap); -void D3D9_UnloadTexture (LPDIRECT3DBASETEXTURE9 tex); -static void Upload_Texture_32(LPDIRECT3DTEXTURE9 surf, unsigned int *data, int width, int height); - -// -// d3d9_mesh.c -// -static galiastexnum_t* D3D9_ChooseSkin (galiasinfo_t *inf, char *modelname, int surfnum, entity_t *e); -void D3D9_DrawAliasModel (void); -void D3D9_DrawMesh (mesh_t *mesh); -void d3d9_GAliasFlushSkinCache (void); -static void LotsOfLightDirectionHacks (entity_t *e, model_t *m, vec3_t lightaxis[3]); - -// -// d3d9_rmain.c -// -void D3D9_BaseBModelTextures (entity_t *e); +#define D3D9QUAKE_H + + +#include "d3d9.h" +#include "com_mesh.h" +#include "glquake.h" + +// +// d3d9_draw.c +// +void D3D9_Draw_Alt_String (int x, int y, const qbyte *str); +void D3D9_Draw_BeginDisc (void); +mpic_t* D3D9_Draw_CachePic (char *path); +void D3D9_Draw_Character (int x, int y, unsigned int num); +void D3D9_Draw_ColouredCharacter (int x, int y, unsigned int num); +void D3D9_Draw_ConsoleBackground (int firstline, int lastline, qboolean forceopaque); +void D3D9_Draw_Crosshair (void); +void D3D9_Draw_DebugChar (qbyte num); +void D3D9_Draw_EditorBackground (int lines); +void D3D9_Draw_EndDisc (void); +void D3D9_Draw_FadeScreen (void); +void D3D9_Draw_Fill (int x, int y, int w, int h, unsigned int c); +void D3D9_Draw_Fill_Colours (int x, int y, int w, int h); +void D3D9_Draw_Fill_I (int x, int y, int w, int h, unsigned int imgcolour); +void D3D9_Draw_FillRGB (int x, int y, int w, int h, float r, float g, float b); +void D3D9_Draw_Image (float x, float y, float w, float h, float s1, float t1, float s2, float t2, mpic_t *pic); +void D3D9_Draw_ImageColours (float r, float g, float b, float a); +void D3D9_Draw_Init (void); +void D3D9_Draw_Pic (int x, int y, mpic_t *pic); +void D3D9_Draw_ReInit (void); +mpic_t* D3D9_Draw_SafeCachePic (char *path); +mpic_t* D3D9_Draw_SafePicFromWad (char *name); +void D3D9_Draw_ScalePic (int x, int y, int width, int height, mpic_t *pic); +void D3D9_Draw_String (int x, int y, const qbyte *str); +void D3D9_Draw_SubPic (int x, int y, int width, int height, mpic_t *pic, int srcx, int srcy, int srcwidth, int srcheight); +void D3D9_Draw_TileClear (int x, int y, int w, int h); +void D3D9_Draw_TransPic (int x, int y, mpic_t *pic); +void D3D9_Draw_TransPicTranslate (int x, int y, int w, int h, qbyte *pic, qbyte *translation); +void D3D9_InitParticleTexture (void); +LPDIRECT3DBASETEXTURE9 D3D9_LoadTexture_32 (char *name, unsigned int *data, int width, int height, int flags); +LPDIRECT3DBASETEXTURE9 D3D9_LoadTexture_8_Pal24 (char *name, unsigned char *data, int width, int height, int flags, unsigned char *palette, int transparentpix); +LPDIRECT3DBASETEXTURE9 D3D9_LoadTexture_8_Pal32 (char *name, unsigned char *data, int width, int height, int flags, unsigned char *palette); +void D3D9_Media_ShowFrame8bit (qbyte *framedata, int inwidth, int inheight, qbyte *palette); +void D3D9_Media_ShowFrameBGR_24_Flip (qbyte *framedata, int inwidth, int inheight); +void D3D9_Media_ShowFrameRGBA_32 (qbyte *framedata, int inwidth, int inheight); +void D3D9_MipMap (qbyte *out, qbyte *in, int width, int height); +void D3D9_RoundDimensions (int *scaled_width, int *scaled_height, qboolean mipmap); +void D3D9_UnloadTexture (LPDIRECT3DBASETEXTURE9 tex); +static void Upload_Texture_32(LPDIRECT3DTEXTURE9 surf, unsigned int *data, int width, int height); + +// +// d3d9_mesh.c +// +static galiastexnum_t* D3D9_ChooseSkin (galiasinfo_t *inf, char *modelname, int surfnum, entity_t *e); +void D3D9_DrawAliasModel (void); +void D3D9_DrawMesh (mesh_t *mesh); +void d3d9_GAliasFlushSkinCache (void); +static void LotsOfLightDirectionHacks (entity_t *e, model_t *m, vec3_t lightaxis[3]); + +// +// d3d9_rmain.c +// +void D3D9_BaseBModelTextures (entity_t *e); /* -void D3D9_DrawParticleBeam (beamseg_t *b, part_type_t *type); -void D3D9_DrawParticleBeamUT (beamseg_t *b, part_type_t *type); +void D3D9_DrawParticleBeam (beamseg_t *b, part_type_t *type); +void D3D9_DrawParticleBeamUT (beamseg_t *b, part_type_t *type); void D3D9_DrawParticleBlob (particle_t *p, part_type_t *type); void D3D9_DrawParticleSpark (particle_t *p, part_type_t *type); -*/ -void D3D9_DrawParticles (float ptime); -static void D3D9_DrawSpriteModel (entity_t *e); -void D3D9_DrawTextureChains (void); -void D3D9_DrawWorld (void); -void D3D9_R_DeInit (void); -void D3D9_R_DrawEntitiesOnList (void); -void D3D9_R_Init (void); -void D3D9_R_ReInit (void); -void D3D9_R_RenderScene (void); -void D3D9_R_RenderView (void); -static void D3D9_RecursiveQ2WorldNode (mnode_t *node); -static void D3D9_RecursiveWorldNode (mnode_t *node); -void D3D9_SetupFrame (void); -void D3D9_SetupViewPort (void); -qboolean D3D9_ShouldDraw (void); -void D3D9R_DrawSprite(int count, void **e, void *parm); -void IDirect3DDevice9_DrawIndexedPrimitive7 (LPDIRECT3DDEVICE9 pD3DDev9, int mode, int fvf, void *verts, int numverts, index_t *indicies, int numindicies, int wasted); - -// -// d3d9_rsurf.c -// -int D3D9_AllocBlock (int w, int h, int *x, int *y); -void D3D9_BuildLightmaps (void); -void D3D9_BuildSurfaceDisplayList (msurface_t *fa); -void D3D9_CreateSurfaceLightmap (msurface_t *surf, int shift); -void D3D9_DrawSkyMesh(int pass, int texture, void *verts, int numverts, void *indicies, int numelements); -int D3D9_FillBlock (int texnum, int w, int h, int x, int y); -LPDIRECT3DTEXTURE9 D3D9_NewLightmap (void); -//void D3D9R_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest, stmap *stainsrc, int shift); -void D3D9R_RenderDynamicLightmaps (msurface_t *fa, int shift); - -// -// vid_d3d9.c -// -void D3D9_BrightenScreen (void); -void D3D9_D_BeginDirectRect (int x, int y, qbyte *pbitmap, int width, int height); -void D3D9_D_EndDirectRect (int x, int y, int width, int height); -void D3D9_GetBufferSize(int *width, int *height); -void D3D9_Mod_ClearAll (void); -void* D3D9_Mod_Extradata (struct model_s *mod); -struct model_s* D3D9_Mod_FindName (char *name); -struct model_s* D3D9_Mod_ForName (char *name, qboolean crash); -void D3D9_Mod_Init (void); -void D3D9_Mod_NowLoadExternal (void); -int D3D9_Mod_SkinForName (struct model_s *model, char *name); -void D3D9_Mod_Think (void); -void D3D9_Mod_TouchModel (char *name); -void D3D9_R_AddStain (vec3_t org, float red, float green, float blue, float radius); -qboolean D3D9_R_CheckSky (void); -void D3D9_R_LessenStains (void); -int D3D9_R_LightPoint (vec3_t point); -void D3D9_R_NewMap (void); -void D3D9_R_PreNewMap (void); -void D3D9_R_PushDlights (void); -void D3D9_R_SetSky (char *name, float rotate, vec3_t axis); -void D3D9_SCR_UpdateScreen (void); -void D3D9_Set2D (void); -void D3D9_VID_DeInit (void); -void D3D9_VID_ForceLockState (int lk); -int D3D9_VID_ForceUnlockedAndReturnState (void); -void D3D9_VID_GenPaletteTables (unsigned char *palette); -char* D3D9_VID_GetRGBInfo (int prepad, int *truevidwidth, int *truevidheight); -qboolean D3D9_VID_Init (rendererstate_t *info, unsigned char *palette); -void D3D9_VID_LockBuffer (void); -void D3D9_VID_SetPalette (unsigned char *palette); -void D3D9_VID_SetWindowCaption (char *msg); -void D3D9_VID_ShiftPalette (unsigned char *palette); -void D3D9_VID_UnlockBuffer (void); -static LRESULT WINAPI D3D9_WindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -qboolean D3D9AppActivate (BOOL fActive, BOOL minimize); -int d3d9error (int i); -void initD3D9 (HWND hWnd, rendererstate_t *info); -void resetD3D9 (void); - - -#define D3D9_LoadTexture8Pal32(skinname,width,height,data,palette,usemips,alpha) (int)D3D9_LoadTexture_8_Pal32(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP, host_basepal) -#define D3D9_LoadTexture(skinname,width,height,data,usemips,alpha) (int)D3D9_LoadTexture_8_Pal24(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP, host_basepal, 255) -#define D3D9_LoadTexture32(skinname,width,height,data,usemips,alpha) (int)D3D9_LoadTexture_32(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP) -#define D3D9_LoadTextureFB(skinname,width,height,data,usemips,alpha) 0 -#define D3D9_LoadTexture8Bump(skinname,width,height,data,usemips,alpha) 0 - -#define D3D9_FindTexture(name) -1 -#define D3D9_LoadCompressed(name) 0 - - - -extern LPDIRECT3DDEVICE9 pD3DDev9; - -extern int d_lightstylevalue[256]; // 8.8 fraction of base light value - -#define lightmap_bytes 4 - - -extern int numlightmaps; - -extern mvertex_t *r_pcurrentvertbase; - -#ifndef LMBLOCK_WIDTH -#define LMBLOCK_WIDTH 128 -#define LMBLOCK_HEIGHT LMBLOCK_WIDTH -typedef struct glRect_s { - unsigned char l,t,w,h; -} glRect_t; -typedef unsigned char stmap; - -typedef struct { - qboolean modified; - qboolean deluxmodified; - glRect_t rectchange; - glRect_t deluxrectchange; - int allocated[LMBLOCK_WIDTH]; - qbyte lightmaps[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; - qbyte deluxmaps[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; //fixme: make seperate structure for easy disabling with less memory usage. - stmap stainmaps[3*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; //rgb no a. added to lightmap for added (hopefully) speed. -} lightmapinfo_t; -#endif - -extern LPDIRECT3DTEXTURE9 *lightmap_d3d9textures; -extern LPDIRECT3DTEXTURE9 *deluxmap_d3d9textures; -extern lightmapinfo_t **lightmap; - -extern void *d3dexplosiontexture; -extern void *d3dballtexture; - -extern index_t dummyindex; -#if sizeof_index_t == 2 - #define D3DFMT_QINDEX D3DFMT_INDEX16 -#else - #define D3DFMT_QINDEX D3DFMT_INDEX32 -#endif +*/ +void D3D9_DrawParticles (float ptime); +static void D3D9_DrawSpriteModel (entity_t *e); +void D3D9_DrawTextureChains (void); +void D3D9_DrawWorld (void); +void D3D9_R_DeInit (void); +void D3D9_R_DrawEntitiesOnList (void); +void D3D9_R_Init (void); +void D3D9_R_ReInit (void); +void D3D9_R_RenderScene (void); +void D3D9_R_RenderView (void); +static void D3D9_RecursiveQ2WorldNode (mnode_t *node); +static void D3D9_RecursiveWorldNode (mnode_t *node); +void D3D9_SetupFrame (void); +void D3D9_SetupViewPort (void); +qboolean D3D9_ShouldDraw (void); +void D3D9R_DrawSprite(int count, void **e, void *parm); +void IDirect3DDevice9_DrawIndexedPrimitive7 (LPDIRECT3DDEVICE9 pD3DDev9, int mode, int fvf, void *verts, int numverts, index_t *indicies, int numindicies, int wasted); + +// +// d3d9_rsurf.c +// +int D3D9_AllocBlock (int w, int h, int *x, int *y); +void D3D9_BuildLightmaps (void); +void D3D9_BuildSurfaceDisplayList (msurface_t *fa); +void D3D9_CreateSurfaceLightmap (msurface_t *surf, int shift); +void D3D9_DrawSkyMesh(int pass, int texture, void *verts, int numverts, void *indicies, int numelements); +int D3D9_FillBlock (int texnum, int w, int h, int x, int y); +LPDIRECT3DTEXTURE9 D3D9_NewLightmap (void); +//void D3D9R_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest, stmap *stainsrc, int shift); +void D3D9R_RenderDynamicLightmaps (msurface_t *fa, int shift); + +// +// vid_d3d9.c +// +void D3D9_BrightenScreen (void); +void D3D9_D_BeginDirectRect (int x, int y, qbyte *pbitmap, int width, int height); +void D3D9_D_EndDirectRect (int x, int y, int width, int height); +void D3D9_GetBufferSize(int *width, int *height); +void D3D9_Mod_ClearAll (void); +void* D3D9_Mod_Extradata (struct model_s *mod); +struct model_s* D3D9_Mod_FindName (char *name); +struct model_s* D3D9_Mod_ForName (char *name, qboolean crash); +void D3D9_Mod_Init (void); +void D3D9_Mod_NowLoadExternal (void); +int D3D9_Mod_SkinForName (struct model_s *model, char *name); +void D3D9_Mod_Think (void); +void D3D9_Mod_TouchModel (char *name); +void D3D9_R_AddStain (vec3_t org, float red, float green, float blue, float radius); +qboolean D3D9_R_CheckSky (void); +void D3D9_R_LessenStains (void); +int D3D9_R_LightPoint (vec3_t point); +void D3D9_R_NewMap (void); +void D3D9_R_PreNewMap (void); +void D3D9_R_PushDlights (void); +void D3D9_R_SetSky (char *name, float rotate, vec3_t axis); +void D3D9_SCR_UpdateScreen (void); +void D3D9_Set2D (void); +void D3D9_VID_DeInit (void); +void D3D9_VID_ForceLockState (int lk); +int D3D9_VID_ForceUnlockedAndReturnState (void); +void D3D9_VID_GenPaletteTables (unsigned char *palette); +char* D3D9_VID_GetRGBInfo (int prepad, int *truevidwidth, int *truevidheight); +qboolean D3D9_VID_Init (rendererstate_t *info, unsigned char *palette); +void D3D9_VID_LockBuffer (void); +void D3D9_VID_SetPalette (unsigned char *palette); +void D3D9_VID_SetWindowCaption (char *msg); +void D3D9_VID_ShiftPalette (unsigned char *palette); +void D3D9_VID_UnlockBuffer (void); +static LRESULT WINAPI D3D9_WindowProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +qboolean D3D9AppActivate (BOOL fActive, BOOL minimize); +int d3d9error (int i); +void initD3D9 (HWND hWnd, rendererstate_t *info); +void resetD3D9 (void); + + +#define D3D9_LoadTexture8Pal32(skinname,width,height,data,palette,usemips,alpha) (int)D3D9_LoadTexture_8_Pal32(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP, host_basepal) +#define D3D9_LoadTexture(skinname,width,height,data,usemips,alpha) (int)D3D9_LoadTexture_8_Pal24(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP, host_basepal, 255) +#define D3D9_LoadTexture32(skinname,width,height,data,usemips,alpha) (int)D3D9_LoadTexture_32(skinname, data, width, height, (usemips?TF_MIPMAP:TF_NOMIPMAP) | (alpha?TF_ALPHA:TF_NOALPHA) | TF_NOTBUMPMAP) +#define D3D9_LoadTextureFB(skinname,width,height,data,usemips,alpha) 0 +#define D3D9_LoadTexture8Bump(skinname,width,height,data,usemips,alpha) 0 + +#define D3D9_FindTexture(name) -1 +#define D3D9_LoadCompressed(name) 0 + + + +extern LPDIRECT3DDEVICE9 pD3DDev9; + +extern int d_lightstylevalue[256]; // 8.8 fraction of base light value + +#define lightmap_bytes 4 + + +extern int numlightmaps; + +extern mvertex_t *r_pcurrentvertbase; + +#ifndef LMBLOCK_WIDTH +#define LMBLOCK_WIDTH 128 +#define LMBLOCK_HEIGHT LMBLOCK_WIDTH +typedef struct glRect_s { + unsigned char l,t,w,h; +} glRect_t; +typedef unsigned char stmap; + +typedef struct { + qboolean modified; + qboolean deluxmodified; + glRect_t rectchange; + glRect_t deluxrectchange; + int allocated[LMBLOCK_WIDTH]; + qbyte lightmaps[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; + qbyte deluxmaps[4*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; //fixme: make seperate structure for easy disabling with less memory usage. + stmap stainmaps[3*LMBLOCK_WIDTH*LMBLOCK_HEIGHT]; //rgb no a. added to lightmap for added (hopefully) speed. +} lightmapinfo_t; +#endif + +extern LPDIRECT3DTEXTURE9 *lightmap_d3d9textures; +extern LPDIRECT3DTEXTURE9 *deluxmap_d3d9textures; +extern lightmapinfo_t **lightmap; + +extern void *d3dexplosiontexture; +extern void *d3dballtexture; + +extern index_t dummyindex; +#if sizeof_index_t == 2 + #define D3DFMT_QINDEX D3DFMT_INDEX16 +#else + #define D3DFMT_QINDEX D3DFMT_INDEX32 +#endif #endif diff --git a/engine/d3d9/vid_d3d9.c b/engine/d3d9/vid_d3d9.c index f223fd8d..7d4d938e 100644 --- a/engine/d3d9/vid_d3d9.c +++ b/engine/d3d9/vid_d3d9.c @@ -85,7 +85,7 @@ mpic_t *draw_disc; // also used on sbar int d3d9width, d3d9height; #if 0 -#if !defined(RGLQUAKE) +#if !defined(GLQUAKE) qbyte GetPaletteIndex(int red, int green, int blue) { //slow, horrible method. @@ -1136,7 +1136,7 @@ void (D3D9_SCR_UpdateScreen) (void) { Editor_Draw(); GLV_UpdatePalette (false, host_frametime); -#if defined(_WIN32) && defined(RGLQUAKE) +#if defined(_WIN32) && defined(GLQUAKE) Media_RecordFrame(); #endif GLR_BrightenScreen(); @@ -1209,7 +1209,7 @@ void (D3D9_SCR_UpdateScreen) (void) SCR_DrawTwoDimensional(uimenu, nohud); GLV_UpdatePalette (false, host_frametime); -#if defined(_WIN32) && defined(RGLQUAKE) +#if defined(_WIN32) && defined(GLQUAKE) Media_RecordFrame(); #endif diff --git a/engine/dotnet2005/ftequake.sln b/engine/dotnet2005/ftequake.sln index 7ff2a96d..c0b731a9 100644 --- a/engine/dotnet2005/ftequake.sln +++ b/engine/dotnet2005/ftequake.sln @@ -4,6 +4,7 @@ Microsoft Visual Studio Solution File, Format Version 9.00 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ftequake", "ftequake.vcproj", "{88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}" ProjectSection(ProjectDependencies) = postProject {382E6790-D1CA-48F5-8E53-D114635EB61D} = {382E6790-D1CA-48F5-8E53-D114635EB61D} + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89} = {66E1D0C0-BEB5-4365-A457-E177AFA6EB89} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gas2masm", "gas2masm.vcproj", "{382E6790-D1CA-48F5-8E53-D114635EB61D}" @@ -13,12 +14,16 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "npqtv", "npqtv.vcproj", "{8 {382E6790-D1CA-48F5-8E53-D114635EB61D} = {382E6790-D1CA-48F5-8E53-D114635EB61D} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "botlib", "..\..\plugins\botlib\botlib.vcproj", "{66E1D0C0-BEB5-4365-A457-E177AFA6EB89}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution D3DDebug|Win32 = D3DDebug|Win32 D3DDebug|x64 = D3DDebug|x64 Debug Dedicated Server|Win32 = Debug Dedicated Server|Win32 Debug Dedicated Server|x64 = Debug Dedicated Server|x64 + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 GLDebug|Win32 = GLDebug|Win32 GLDebug|x64 = GLDebug|x64 GLRelease|Win32 = GLRelease|Win32 @@ -33,16 +38,22 @@ Global MRelease|x64 = MRelease|x64 Release Dedicated Server|Win32 = Release Dedicated Server|Win32 Release Dedicated Server|x64 = Release Dedicated Server|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.D3DDebug|Win32.ActiveCfg = D3DDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.D3DDebug|Win32.Build.0 = D3DDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.D3DDebug|x64.ActiveCfg = D3DDebug|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.D3DDebug|x64.Build.0 = D3DDebug|x64 - {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Debug Dedicated Server|Win32.ActiveCfg = MRelease|Win32 - {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Debug Dedicated Server|Win32.Build.0 = MRelease|Win32 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Debug Dedicated Server|Win32.ActiveCfg = Debug Dedicated Server|Win32 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Debug Dedicated Server|Win32.Build.0 = Debug Dedicated Server|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Debug Dedicated Server|x64.ActiveCfg = GLDebug|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Debug Dedicated Server|x64.Build.0 = GLDebug|x64 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Debug|Win32.ActiveCfg = MDebug|Win32 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Debug|Win32.Build.0 = MDebug|Win32 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Debug|x64.ActiveCfg = MDebug|x64 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Debug|x64.Build.0 = MDebug|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.GLDebug|Win32.ActiveCfg = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.GLDebug|Win32.Build.0 = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.GLDebug|x64.ActiveCfg = GLDebug|x64 @@ -71,6 +82,10 @@ Global {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release Dedicated Server|Win32.Build.0 = Release Dedicated Server|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release Dedicated Server|x64.ActiveCfg = Release Dedicated Server|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release Dedicated Server|x64.Build.0 = Release Dedicated Server|x64 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release|Win32.ActiveCfg = GLRelease|Win32 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release|Win32.Build.0 = GLRelease|Win32 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release|x64.ActiveCfg = GLRelease|x64 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1364}.Release|x64.Build.0 = GLRelease|x64 {382E6790-D1CA-48F5-8E53-D114635EB61D}.D3DDebug|Win32.ActiveCfg = Debug|Win32 {382E6790-D1CA-48F5-8E53-D114635EB61D}.D3DDebug|Win32.Build.0 = Debug|Win32 {382E6790-D1CA-48F5-8E53-D114635EB61D}.D3DDebug|x64.ActiveCfg = Debug|x64 @@ -78,6 +93,10 @@ Global {382E6790-D1CA-48F5-8E53-D114635EB61D}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32 {382E6790-D1CA-48F5-8E53-D114635EB61D}.Debug Dedicated Server|Win32.Build.0 = Debug|Win32 {382E6790-D1CA-48F5-8E53-D114635EB61D}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32 + {382E6790-D1CA-48F5-8E53-D114635EB61D}.Debug|Win32.ActiveCfg = Debug|Win32 + {382E6790-D1CA-48F5-8E53-D114635EB61D}.Debug|Win32.Build.0 = Debug|Win32 + {382E6790-D1CA-48F5-8E53-D114635EB61D}.Debug|x64.ActiveCfg = Debug|x64 + {382E6790-D1CA-48F5-8E53-D114635EB61D}.Debug|x64.Build.0 = Debug|x64 {382E6790-D1CA-48F5-8E53-D114635EB61D}.GLDebug|Win32.ActiveCfg = Debug|Win32 {382E6790-D1CA-48F5-8E53-D114635EB61D}.GLDebug|Win32.Build.0 = Debug|Win32 {382E6790-D1CA-48F5-8E53-D114635EB61D}.GLDebug|x64.ActiveCfg = Debug|Win32 @@ -106,14 +125,20 @@ Global {382E6790-D1CA-48F5-8E53-D114635EB61D}.Release Dedicated Server|Win32.Build.0 = Debug|Win32 {382E6790-D1CA-48F5-8E53-D114635EB61D}.Release Dedicated Server|x64.ActiveCfg = Debug|Win32 {382E6790-D1CA-48F5-8E53-D114635EB61D}.Release Dedicated Server|x64.Build.0 = Debug|Win32 + {382E6790-D1CA-48F5-8E53-D114635EB61D}.Release|Win32.ActiveCfg = Debug|x64 + {382E6790-D1CA-48F5-8E53-D114635EB61D}.Release|x64.ActiveCfg = Debug|x64 + {382E6790-D1CA-48F5-8E53-D114635EB61D}.Release|x64.Build.0 = Debug|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.D3DDebug|Win32.ActiveCfg = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.D3DDebug|x64.ActiveCfg = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.D3DDebug|x64.Build.0 = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug Dedicated Server|Win32.ActiveCfg = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug Dedicated Server|x64.ActiveCfg = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug Dedicated Server|x64.Build.0 = GLRelease|x64 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug|Win32.ActiveCfg = GLDebug|Win32 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug|Win32.Build.0 = GLDebug|Win32 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug|x64.ActiveCfg = GLDebug|x64 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Debug|x64.Build.0 = GLDebug|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLDebug|Win32.ActiveCfg = GLDebug|Win32 - {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLDebug|Win32.Build.0 = GLDebug|Win32 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLDebug|x64.ActiveCfg = GLDebug|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLDebug|x64.Build.0 = GLDebug|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.GLRelease|Win32.ActiveCfg = GLRelease|Win32 @@ -137,8 +162,48 @@ Global {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release Dedicated Server|Win32.ActiveCfg = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release Dedicated Server|x64.ActiveCfg = GLRelease|x64 {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release Dedicated Server|x64.Build.0 = GLRelease|x64 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release|Win32.ActiveCfg = GLRelease|Win32 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release|Win32.Build.0 = GLRelease|Win32 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release|x64.ActiveCfg = GLRelease|x64 + {88BFEE0E-7BC0-43AD-9CCC-6B1A6E4C1365}.Release|x64.Build.0 = GLRelease|x64 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.D3DDebug|Win32.ActiveCfg = Debug|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.D3DDebug|Win32.Build.0 = Debug|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.D3DDebug|x64.ActiveCfg = Debug|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.Debug Dedicated Server|Win32.ActiveCfg = Debug|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.Debug Dedicated Server|Win32.Build.0 = Debug|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.Debug Dedicated Server|x64.ActiveCfg = Debug|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.Debug|Win32.ActiveCfg = Debug|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.Debug|Win32.Build.0 = Debug|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.Debug|x64.ActiveCfg = Debug|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.GLDebug|Win32.ActiveCfg = Debug|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.GLDebug|Win32.Build.0 = Debug|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.GLDebug|x64.ActiveCfg = Debug|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.GLRelease|Win32.ActiveCfg = Release|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.GLRelease|Win32.Build.0 = Release|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.GLRelease|x64.ActiveCfg = Release|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.MDebug|Win32.ActiveCfg = Debug|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.MDebug|Win32.Build.0 = Debug|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.MDebug|x64.ActiveCfg = Debug|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.MinGLDebug|Win32.ActiveCfg = Debug|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.MinGLDebug|Win32.Build.0 = Debug|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.MinGLDebug|x64.ActiveCfg = Debug|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.MinGLRelease|Win32.ActiveCfg = Release|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.MinGLRelease|Win32.Build.0 = Release|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.MinGLRelease|x64.ActiveCfg = Release|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.MRelease|Win32.ActiveCfg = Release|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.MRelease|Win32.Build.0 = Release|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.MRelease|x64.ActiveCfg = Release|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.Release Dedicated Server|Win32.ActiveCfg = Release|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.Release Dedicated Server|Win32.Build.0 = Release|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.Release Dedicated Server|x64.ActiveCfg = Release|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.Release|Win32.ActiveCfg = Release|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.Release|Win32.Build.0 = Release|Win32 + {66E1D0C0-BEB5-4365-A457-E177AFA6EB89}.Release|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + AMDCaProjectFile = C:\Games\Quake\ftesrc\engine\dotnet2005\CodeAnalyst\ftequake.caw + EndGlobalSection EndGlobal diff --git a/engine/dotnet2005/ftequake.vcproj b/engine/dotnet2005/ftequake.vcproj index 447775e6..c15e4056 100644 --- a/engine/dotnet2005/ftequake.vcproj +++ b/engine/dotnet2005/ftequake.vcproj @@ -251,7 +251,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -16499,10 +16149,6 @@ /> - - @@ -16839,176 +16485,6 @@ /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -17179,342 +16655,6 @@ /> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -18366,172 +17506,8 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -24048,6 +23038,82 @@ /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -25164,7 +24230,7 @@ > @@ -25183,7 +24249,7 @@ > @@ -25202,7 +24268,7 @@ > @@ -25240,7 +24306,7 @@ > @@ -25259,7 +24325,7 @@ > @@ -25278,7 +24344,7 @@ > @@ -25297,7 +24363,7 @@ > @@ -25339,7 +24405,7 @@ > @@ -25358,7 +24424,7 @@ > @@ -25377,7 +24443,7 @@ > @@ -25416,7 +24482,7 @@ > @@ -25433,7 +24499,7 @@ > @@ -25453,7 +24519,7 @@ > @@ -25470,7 +24536,7 @@ > @@ -25512,7 +24578,7 @@ > @@ -25531,7 +24597,7 @@ > @@ -25550,7 +24616,7 @@ > @@ -25589,7 +24655,7 @@ > @@ -25606,7 +24672,7 @@ > @@ -25626,7 +24692,7 @@ > @@ -25643,7 +24709,7 @@ > @@ -25685,7 +24751,7 @@ > @@ -25704,7 +24770,7 @@ > @@ -25723,7 +24789,7 @@ > @@ -25761,7 +24827,7 @@ > @@ -25780,7 +24846,7 @@ > @@ -25799,7 +24865,7 @@ > @@ -25818,7 +24884,7 @@ > @@ -28684,844 +27750,774 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/engine/dotnet2005/npqtv.vcproj b/engine/dotnet2005/npqtv.vcproj index d67b6285..67ea1c86 100644 --- a/engine/dotnet2005/npqtv.vcproj +++ b/engine/dotnet2005/npqtv.vcproj @@ -18668,6 +18668,14 @@ /> + + + + @@ -31124,6 +31132,26 @@ /> + + + + + + + + diff --git a/engine/dotnet2005/resource.h b/engine/dotnet2005/resource.h index c6f7916b..d1d3ee0d 100644 --- a/engine/dotnet2005/resource.h +++ b/engine/dotnet2005/resource.h @@ -6,9 +6,13 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_RESOURCE_VALUE 103 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1001 -#define _APS_NEXT_SYMED_VALUE 101 +#define _APS_NEXT_SYMED_VALUE 103 #endif #endif + + +#define IDI_ICON1 101 +#define IDI_ICON2 102 diff --git a/engine/ftequake/ftequake.dsp b/engine/ftequake/ftequake.dsp index 21ed3e45..26bdf546 100644 --- a/engine/ftequake/ftequake.dsp +++ b/engine/ftequake/ftequake.dsp @@ -55,7 +55,7 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /G6 /W3 /GX /O2 /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "SWQUAKE" /FR /Yu"quakedef.h" /FD /c +# ADD CPP /nologo /G6 /MT /W3 /GX /O2 /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /I "../libs/freetype2/include" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE" /D "NEWBACKEND" /FR /Yu"quakedef.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "NDEBUG" @@ -65,7 +65,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 -# ADD LINK32 comctl32.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:windows /pdb:none /map /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"../../fteswqw.exe" /libpath:"../libs/dxsdk7/lib" +# ADD LINK32 comctl32.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:windows /pdb:none /map /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"../../fteglqw_n.exe" /libpath:"../libs/dxsdk7/lib" !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" @@ -81,7 +81,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /G6 /W3 /Gm /GX /ZI /Od /I "../client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SWQUAKE" /FR".\Debug/" /Fp".\Debug/qwcl.pch" /Yu"quakedef.h" /Fo".\Debug/" /Fd".\Debug/" /FD /c +# ADD CPP /nologo /G6 /MT /W3 /Gm /GX /ZI /Od /I "../client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /I "../libs/freetype2/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE" /D "NEWBACKEND" /FR".\Debug/" /Fp".\Debug/qwcl.pch" /Yu"quakedef.h" /Fo".\Debug/" /Fd".\Debug/" /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" @@ -91,7 +91,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept -# ADD LINK32 comctl32.lib wsock32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /map /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"../../fteswqw_dbg.exe" /libpath:"../libs/dxsdk7/lib" +# ADD LINK32 comctl32.lib wsock32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /map /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"../../fteglqw_n_dbg.exe" /libpath:"../libs/dxsdk7/lib" # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" @@ -108,7 +108,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /G5 /MT /W3 /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "_DEBUG" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /Yu"quakedef.h" /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c +# ADD CPP /nologo /G5 /MT /W3 /GX /ZI /Od /I "..\client" /I "../libs/freetype2/include" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "_DEBUG" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /Yu"quakedef.h" /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c # SUBTRACT CPP /X # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 @@ -137,7 +137,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /I "..\client" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /G6 /Gr /MT /W3 /GX /O2 /Ob2 /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "NDEBUG" /D "_MBCS" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /FR /Yu"quakedef.h" /FD /c +# ADD CPP /nologo /G6 /Gr /MT /W3 /GX /O2 /Ob2 /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /I "../libs/freetype2/include" /D "NDEBUG" /D "_MBCS" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /FR /Yu"quakedef.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "NDEBUG" @@ -165,7 +165,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /G5 /ML /W3 /GX /ZI /Od /I "..\client\gltod3d\sdk7\include" /I "..\client\gltod3d\D3DFrame" /I "..\dxsdk\sdk\inc" /I "..\scitech\include" /I "..\client" /D "NQPROT" /D "_DEBUG" /D "GLQUAKE" /D "SERVERDLL" /D "WIN32" /D "_WINDOWS" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /YX /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c -# ADD CPP /nologo /G5 /W3 /Gi /GX /ZI /Od /I "..\client" /I "../libs/dxsdk7/include" /I "../libs/dxsdk9/include" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../d3d" /I "../d3d9" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE" /D "SWQUAKE" /D "USE_D3D" /D "D3DQUAKE" /Fr /Fp".\MDebug/qwcl.pch" /Yu"quakedef.h" /FD /c +# ADD CPP /nologo /G5 /W3 /Gi /GX /ZI /Od /I "..\client" /I "../libs/dxsdk9/include" /I "../d3d" /I "../d3d9" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /I "../libs/freetype2/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE" /D "SWQUAKE" /D "USE_D3D" /D "D3DQUAKE" /Fr /Fp".\MDebug/qwcl.pch" /Yu"quakedef.h" /FD /c # SUBTRACT CPP /WX # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 @@ -195,7 +195,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /I "..\client\gltod3d\sdk7\include" /I "..\client\gltod3d\D3DFrame" /I "..\dxsdk\sdk\inc" /I "..\scitech\include" /I "..\client" /D "NOSOUNDASM" /D "NDEBUG" /D "_MBCS" /D "GLQUAKE" /D "SERVERDLL" /D "NQPROT" /D "WIN32" /D "_WINDOWS" /FR /YX /FD /c -# ADD CPP /nologo /G6 /GX /O2 /I "..\client" /I "../libs/dxsdk7/include" /I "../libs/dxsdk9/include" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../d3d" /I "../d3d9" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE" /D "SWQUAKE" /D "USE_D3D" /D "D3DQUAKE" /Fr /Yu"quakedef.h" /FD /c +# ADD CPP /nologo /G6 /GX /O2 /I "..\client" /I "../libs/dxsdk9/include" /I "../d3d" /I "../d3d9" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /I "../libs/freetype2/include" /D "NDEBUG" /D "_MBCS" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE" /D "SWQUAKE" /D "USE_D3D" /D "D3DQUAKE" /Fr /Yu"quakedef.h" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "NDEBUG" @@ -222,7 +222,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /G5 /ML /W3 /GX /ZI /Od /I "..\client\gltod3d\sdk7\include" /I "..\client\gltod3d\D3DFrame" /I "..\dxsdk\sdk\inc" /I "..\scitech\include" /I "..\client" /D "NQPROT" /D "_DEBUG" /D "GLQUAKE" /D "SERVERDLL" /D "WIN32" /D "_WINDOWS" /D "Q2SERVER" /D "DYNAMIC_ENTS" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /YX /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c -# ADD CPP /nologo /G5 /ML /W3 /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "MINIMAL" /D "_DEBUG" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /FR".\GLMinDebug/" /Fp".\GLMinDebug/qwcl.pch" /Yu"quakedef.h" /Fo".\GLMinDebug/" /Fd".\GLMinDebug/" /FD /c +# ADD CPP /nologo /G5 /ML /W3 /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /I "../libs/freetype2/include" /D "MINIMAL" /D "_DEBUG" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /FR".\GLMinDebug/" /Fp".\GLMinDebug/qwcl.pch" /Yu"quakedef.h" /Fo".\GLMinDebug/" /Fd".\GLMinDebug/" /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" @@ -250,7 +250,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /G6 /Gr /W3 /GX /O2 /Ob2 /I "..\client\gltod3d\sdk7\include" /I "..\client\gltod3d\D3DFrame" /I "..\dxsdk\sdk\inc" /I "..\scitech\include" /I "..\client" /D "NOSOUNDASM" /D "NDEBUG" /D "_MBCS" /D "GLQUAKE" /D "SERVERDLL" /D "NQPROT" /D "WIN32" /D "_WINDOWS" /D "Q2SERVER" /D "DYNAMIC_ENTS" /FR /YX /FD /c -# ADD CPP /nologo /G6 /Gr /W3 /GX /O2 /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "MINIMAL" /D "NDEBUG" /D "_MBCS" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /FR"MinGLRelease/" /Fp"MinGLRelease/ftequake.pch" /Yu"quakedef.h" /Fo"MinGLRelease/" /Fd"MinGLRelease/" /FD /c +# ADD CPP /nologo /G6 /Gr /W3 /GX /O2 /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /I "../libs/freetype2/include" /D "MINIMAL" /D "NDEBUG" /D "_MBCS" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /FR"MinGLRelease/" /Fp"MinGLRelease/ftequake.pch" /Yu"quakedef.h" /Fo"MinGLRelease/" /Fd"MinGLRelease/" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "NDEBUG" @@ -260,7 +260,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 comctl32.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:windows /machine:I386 /out:"../../../fteglqw.exe" -# ADD LINK32 wsock32.lib winmm.lib kernel32.lib user32.lib gdi32.lib /nologo /subsystem:windows /pdb:none /map /machine:I386 /out:"../../fteminglqw.exe" /libpath:"../libs/dxsdk7/lib" +# ADD LINK32 wsock32.lib winmm.lib kernel32.lib user32.lib gdi32.lib comctl32.lib shell32.lib advapi32.lib ole32.lib /nologo /subsystem:windows /pdb:none /map /machine:I386 /out:"../../fteminglqw.exe" /libpath:"../libs/dxsdk7/lib" !ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" @@ -277,7 +277,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /G5 /ML /W3 /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /D "MINIMAL" /D "_DEBUG" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /YX /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c -# ADD CPP /nologo /G6 /ML /W3 /Gm /Gi /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SERVERONLY" /FR".\DebugServer/" /Fp".\DebugServer/qwcl.pch" /Yu"quakedef.h" /Fo".\DebugServer/" /Fd".\DebugServer/" /FD /c +# ADD CPP /nologo /G6 /ML /W3 /Gm /Gi /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /I "../libs/freetype2/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SERVERONLY" /FR".\DebugServer/" /Fp".\DebugServer/qwcl.pch" /Yu"quakedef.h" /Fo".\DebugServer/" /Fd".\DebugServer/" /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" @@ -306,7 +306,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /G5 /ML /W3 /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /D "MINIMAL" /D "_DEBUG" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /D "SERVERONLY" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /YX /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c -# ADD CPP /nologo /G6 /ML /W3 /GX /O1 /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "SERVERONLY" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /Yu"quakedef.h" /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c +# ADD CPP /nologo /G6 /ML /W3 /GX /O1 /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /I "../libs/freetype2/include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "SERVERONLY" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /Yu"quakedef.h" /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" @@ -335,7 +335,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /G6 /W3 /Gm /GX /ZI /Od /I "../client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SWQUAKE" /FR".\Debug/" /Fp".\Debug/qwcl.pch" /YX /Fo".\Debug/" /Fd".\Debug/" /FD /c -# ADD CPP /nologo /G6 /W3 /Gm /GX /ZI /Od /I "../client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SWQUAKE" /D "MINIMAL" /FR".\Debug/" /Fp".\Debug/qwcl.pch" /Yu"quakedef.h" /Fo".\Debug/" /Fd".\Debug/" /FD /c +# ADD CPP /nologo /G6 /W3 /Gm /GX /ZI /Od /I "../client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /I "../libs/freetype2/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SWQUAKE" /D "MINIMAL" /FR".\Debug/" /Fp".\Debug/qwcl.pch" /Yu"quakedef.h" /Fo".\Debug/" /Fd".\Debug/" /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" @@ -363,7 +363,7 @@ LINK32=link.exe # PROP Target_Dir "" # ADD BASE CPP /nologo /G5 /ML /W3 /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "_DEBUG" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /D "AVAIL_OGGVORBIS" /D "Q3CLIENT" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /YX /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c # SUBTRACT BASE CPP /X -# ADD CPP /nologo /G5 /W3 /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "_DEBUG" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /FR /Fp".\GLDebugQ3/qwcl.pch" /Yu"quakedef.h" /Fo".\GLDebugQ3/" /Fd".\GLDebugQ3/" /FD /c +# ADD CPP /nologo /G5 /W3 /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /I "../libs/freetype2/include" /D "_DEBUG" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /FR /Fp".\GLDebugQ3/qwcl.pch" /Yu"quakedef.h" /Fo".\GLDebugQ3/" /Fd".\GLDebugQ3/" /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" @@ -392,7 +392,7 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /G6 /ML /W3 /Gm /Gi /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SERVERONLY" /FR".\DebugServer/" /Fp".\DebugServer/qwcl.pch" /Yu"quakedef.h" /Fo".\DebugServer/" /Fd".\DebugServer/" /FD /c -# ADD CPP /nologo /G6 /ML /W3 /Gm /Gi /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SERVERONLY" /D "Q3SERVER" /FR".\DebugServer/" /Fp".\DebugServer/qwcl.pch" /Yu"quakedef.h" /Fo".\DebugServer/" /Fd".\DebugServer/" /FD /c +# ADD CPP /nologo /G6 /ML /W3 /Gm /Gi /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /I "../libs/freetype2/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SERVERONLY" /D "Q3SERVER" /FR".\DebugServer/" /Fp".\DebugServer/qwcl.pch" /Yu"quakedef.h" /Fo".\DebugServer/" /Fd".\DebugServer/" /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" @@ -420,7 +420,7 @@ LINK32=link.exe # PROP Target_Dir "" # ADD BASE CPP /nologo /G5 /W3 /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "_DEBUG" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /Yu"quakedef.h" /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c # SUBTRACT BASE CPP /X -# ADD CPP /nologo /G5 /W3 /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /I "../d3d" /I "../libs/dxsdk9/include" /D "_DEBUG" /D "D3DQUAKE" /D "WIN32" /D "_WINDOWS" /FR".\D3DDebug/" /Fp".\D3DDebug/qwcl.pch" /Yu"quakedef.h" /Fo".\D3DDebug/" /Fd".\D3DDebug/" /FD /c +# ADD CPP /nologo /G5 /W3 /GX /ZI /Od /I "..\client" /I "../d3d" /I "../libs/dxsdk9/include" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /I "../libs/freetype2/include" /D "_DEBUG" /D "D3DQUAKE" /D "WIN32" /D "_WINDOWS" /FR".\D3DDebug/" /Fp".\D3DDebug/qwcl.pch" /Yu"quakedef.h" /Fo".\D3DDebug/" /Fd".\D3DDebug/" /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" @@ -579,12 +579,10 @@ SOURCE=..\server\svq3_game.c !IF "$(CFG)" == "ftequake - Win32 Release" -# PROP Exclude_From_Build 1 # ADD CPP /Yu"qwsvdef.h" !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 # ADD CPP /Yu"qwsvdef.h" !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" @@ -743,12 +741,8 @@ SOURCE=..\client\cl_cg.c !IF "$(CFG)" == "ftequake - Win32 Release" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" !ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" @@ -1351,12 +1345,8 @@ SOURCE=..\client\clq3_parse.c !IF "$(CFG)" == "ftequake - Win32 Release" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" !ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" @@ -3335,8 +3325,6 @@ SOURCE=..\gl\gl_alias.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" !ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" @@ -3379,8 +3367,6 @@ SOURCE=..\gl\gl_backend.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" !ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" @@ -3427,8 +3413,6 @@ SOURCE=..\gl\gl_bloom.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" !ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" @@ -3468,8 +3452,6 @@ SOURCE=..\gl\gl_draw.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" !ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" @@ -3518,7 +3500,6 @@ SOURCE=..\gl\gltod3d\gl_fakegl.cpp !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 # SUBTRACT CPP /YX /Yc /Yu !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" @@ -3583,14 +3564,16 @@ SOURCE=..\gl\gltod3d\gl_fakegl.cpp # End Source File # Begin Source File +SOURCE=..\gl\gl_font.c +# End Source File +# Begin Source File + SOURCE=..\gl\gl_heightmap.c !IF "$(CFG)" == "ftequake - Win32 Release" !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" !ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" @@ -3628,8 +3611,6 @@ SOURCE=..\gl\gl_hlmdl.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" !ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" @@ -3678,8 +3659,6 @@ SOURCE=..\gl\gl_model.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" !ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" @@ -3726,8 +3705,6 @@ SOURCE=..\gl\gl_ngraph.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" !ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" @@ -3774,8 +3751,6 @@ SOURCE=..\gl\gl_ppl.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" !ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" @@ -3859,8 +3834,6 @@ SOURCE=..\gl\gl_rlight.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" !ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" @@ -3907,8 +3880,6 @@ SOURCE=..\gl\gl_rmain.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" !ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" @@ -3955,8 +3926,6 @@ SOURCE=..\gl\gl_rmisc.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" !ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" @@ -4003,8 +3972,6 @@ SOURCE=..\gl\gl_rsurf.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" !ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" @@ -4051,8 +4018,6 @@ SOURCE=..\gl\gl_screen.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" !ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" @@ -4130,14 +4095,20 @@ SOURCE=..\gl\gl_shader.c # End Source File # Begin Source File +SOURCE=..\gl\gl_shadow.c +# End Source File +# Begin Source File + +SOURCE=..\gl\gl_vbo.c +# End Source File +# Begin Source File + SOURCE=..\gl\gl_vidcommon.c !IF "$(CFG)" == "ftequake - Win32 Release" !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" !ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" @@ -4184,8 +4155,6 @@ SOURCE=..\gl\gl_vidnt.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" !ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" @@ -4232,8 +4201,6 @@ SOURCE=..\gl\gl_warp.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" !ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" @@ -4280,8 +4247,6 @@ SOURCE=..\gl\glmod_doom.c !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" !ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" @@ -4330,8 +4295,6 @@ SOURCE=..\gl\LTFACE.C !ELSEIF "$(CFG)" == "ftequake - Win32 Debug" -# PROP Exclude_From_Build 1 - !ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" !ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" @@ -4375,1834 +4338,6 @@ SOURCE=..\gl\LTFACE.C # Begin Source File SOURCE=..\gl\shader.h -# End Source File -# End Group -# Begin Group "sw" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\sw\d_edge.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\d_fill.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\d_init.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\d_modech.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\d_part.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\d_polyse.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\d_scan.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\d_sky.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\d_sprite.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\d_surf.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\d_trans.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\d_vars.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\d_zpoint.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\nonintel.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\r_aclip.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\r_alias.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\r_bsp.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\r_draw.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\r_edge.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\r_light.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\r_main.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\r_misc.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\r_sky.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\r_sprite.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\r_surf.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\r_vars.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\sw_draw.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\sw_model.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\sw_screen.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\vid_ddraw.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\vid_dib.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\vid_win2.c - -!IF "$(CFG)" == "ftequake - Win32 Release" - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - # End Source File # End Group # Begin Group "common" @@ -6705,6 +4840,45 @@ SOURCE=..\QCLIB\pr_multi.c # End Source File # Begin Source File +SOURCE=..\qclib\pr_x86.c + +!IF "$(CFG)" == "ftequake - Win32 Release" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" + +# SUBTRACT CPP /YX /Yc /Yu + +!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" + +!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" + +!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" + +!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" + +!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" + +!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" + +!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" + +!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" + +!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" + +!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" + +!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" + +!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" + +!ENDIF + +# End Source File +# Begin Source File + SOURCE=..\QCLIB\progtype.h # End Source File # Begin Source File @@ -6987,902 +5161,6 @@ SOURCE=..\QCLIB\qcdecomp.c # PROP Default_Filter "" # Begin Source File -SOURCE=..\sw\d_draw.s - -!IF "$(CFG)" == "ftequake - Win32 Release" - -# Begin Custom Build -OutDir=.\Release -InputPath=..\sw\d_draw.s -InputName=d_draw - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -# Begin Custom Build -OutDir=.\Debug -InputPath=..\sw\d_draw.s -InputName=d_draw - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common $(InputPath) > $(OUTDIR)\$(InputName).spp - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Intermediate_Dir ".\MDebug" -# Begin Custom Build -OutDir=.\MDebug -InputPath=..\sw\d_draw.s -InputName=d_draw - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -# PROP BASE Exclude_From_Build 1 -# Begin Custom Build -OutDir=.\MRelease -InputPath=..\sw\d_draw.s -InputName=d_draw - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -# Begin Custom Build -OutDir=.\ftequake___Win32_MinSW -InputPath=..\sw\d_draw.s -InputName=d_draw - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\d_draw16.s - -!IF "$(CFG)" == "ftequake - Win32 Release" - -# Begin Custom Build -OutDir=.\Release -InputPath=..\sw\d_draw16.s -InputName=d_draw16 - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -# Begin Custom Build -OutDir=.\Debug -InputPath=..\sw\d_draw16.s -InputName=d_draw16 - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common $(InputPath) > $(OUTDIR)\$(InputName).spp - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Intermediate_Dir ".\MDebug" -# Begin Custom Build -OutDir=.\MDebug -InputPath=..\sw\d_draw16.s -InputName=d_draw16 - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -# PROP BASE Exclude_From_Build 1 -# Begin Custom Build -OutDir=.\MRelease -InputPath=..\sw\d_draw16.s -InputName=d_draw16 - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -# Begin Custom Build -OutDir=.\ftequake___Win32_MinSW -InputPath=..\sw\d_draw16.s -InputName=d_draw16 - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\d_parta.s - -!IF "$(CFG)" == "ftequake - Win32 Release" - -# Begin Custom Build -OutDir=.\Release -InputPath=..\sw\d_parta.s -InputName=d_parta - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -# Begin Custom Build -OutDir=.\Debug -InputPath=..\sw\d_parta.s -InputName=d_parta - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common $(InputPath) > $(OUTDIR)\$(InputName).spp - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Intermediate_Dir ".\MDebug" -# Begin Custom Build -OutDir=.\MDebug -InputPath=..\sw\d_parta.s -InputName=d_parta - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -# PROP BASE Exclude_From_Build 1 -# Begin Custom Build -OutDir=.\MRelease -InputPath=..\sw\d_parta.s -InputName=d_parta - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -# Begin Custom Build -OutDir=.\ftequake___Win32_MinSW -InputPath=..\sw\d_parta.s -InputName=d_parta - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\d_polysa.s - -!IF "$(CFG)" == "ftequake - Win32 Release" - -# Begin Custom Build -OutDir=.\Release -InputPath=..\sw\d_polysa.s -InputName=d_polysa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -# Begin Custom Build -OutDir=.\Debug -InputPath=..\sw\d_polysa.s -InputName=d_polysa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common $(InputPath) > $(OUTDIR)\$(InputName).spp - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Intermediate_Dir ".\MDebug" -# Begin Custom Build -OutDir=.\MDebug -InputPath=..\sw\d_polysa.s -InputName=d_polysa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -# PROP BASE Exclude_From_Build 1 -# Begin Custom Build -OutDir=.\MRelease -InputPath=..\sw\d_polysa.s -InputName=d_polysa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -# Begin Custom Build -OutDir=.\ftequake___Win32_MinSW -InputPath=..\sw\d_polysa.s -InputName=d_polysa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\d_scana.s - -!IF "$(CFG)" == "ftequake - Win32 Release" - -# Begin Custom Build -OutDir=.\Release -InputPath=..\sw\d_scana.s -InputName=d_scana - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -# Begin Custom Build -OutDir=.\Debug -InputPath=..\sw\d_scana.s -InputName=d_scana - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common $(InputPath) > $(OUTDIR)\$(InputName).spp - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Intermediate_Dir ".\MDebug" -# Begin Custom Build -OutDir=.\MDebug -InputPath=..\sw\d_scana.s -InputName=d_scana - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -# PROP BASE Exclude_From_Build 1 -# Begin Custom Build -OutDir=.\MRelease -InputPath=..\sw\d_scana.s -InputName=d_scana - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -# Begin Custom Build -OutDir=.\ftequake___Win32_MinSW -InputPath=..\sw\d_scana.s -InputName=d_scana - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\d_spr8.s - -!IF "$(CFG)" == "ftequake - Win32 Release" - -# Begin Custom Build -OutDir=.\Release -InputPath=..\sw\d_spr8.s -InputName=d_spr8 - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -# Begin Custom Build -OutDir=.\Debug -InputPath=..\sw\d_spr8.s -InputName=d_spr8 - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common $(InputPath) > $(OUTDIR)\$(InputName).spp - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Intermediate_Dir ".\MDebug" -# Begin Custom Build -OutDir=.\MDebug -InputPath=..\sw\d_spr8.s -InputName=d_spr8 - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -# PROP BASE Exclude_From_Build 1 -# Begin Custom Build -OutDir=.\MRelease -InputPath=..\sw\d_spr8.s -InputName=d_spr8 - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -# Begin Custom Build -OutDir=.\ftequake___Win32_MinSW -InputPath=..\sw\d_spr8.s -InputName=d_spr8 - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\d_varsa.s - -!IF "$(CFG)" == "ftequake - Win32 Release" - -# Begin Custom Build -OutDir=.\Release -InputPath=..\sw\d_varsa.s -InputName=d_varsa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -# Begin Custom Build -OutDir=.\Debug -InputPath=..\sw\d_varsa.s -InputName=d_varsa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common $(InputPath) > $(OUTDIR)\$(InputName).spp - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Intermediate_Dir ".\MDebug" -# Begin Custom Build -OutDir=.\MDebug -InputPath=..\sw\d_varsa.s -InputName=d_varsa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -# PROP BASE Exclude_From_Build 1 -# Begin Custom Build -OutDir=.\MRelease -InputPath=..\sw\d_varsa.s -InputName=d_varsa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -# Begin Custom Build -OutDir=.\ftequake___Win32_MinSW -InputPath=..\sw\d_varsa.s -InputName=d_varsa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - SOURCE=..\common\math.s !IF "$(CFG)" == "ftequake - Win32 Release" @@ -8101,646 +5379,6 @@ InputName=math # End Source File # Begin Source File -SOURCE=..\sw\r_aclipa.s - -!IF "$(CFG)" == "ftequake - Win32 Release" - -# Begin Custom Build -OutDir=.\Release -InputPath=..\sw\r_aclipa.s -InputName=r_aclipa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -# Begin Custom Build -OutDir=.\Debug -InputPath=..\sw\r_aclipa.s -InputName=r_aclipa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common $(InputPath) > $(OUTDIR)\$(InputName).spp - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Intermediate_Dir ".\MDebug" -# Begin Custom Build -OutDir=.\MDebug -InputPath=..\sw\r_aclipa.s -InputName=r_aclipa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -# PROP BASE Exclude_From_Build 1 -# Begin Custom Build -OutDir=.\MRelease -InputPath=..\sw\r_aclipa.s -InputName=r_aclipa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -# Begin Custom Build -OutDir=.\ftequake___Win32_MinSW -InputPath=..\sw\r_aclipa.s -InputName=r_aclipa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\r_aliasa.s - -!IF "$(CFG)" == "ftequake - Win32 Release" - -# Begin Custom Build -OutDir=.\Release -InputPath=..\sw\r_aliasa.s -InputName=r_aliasa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -# Begin Custom Build -OutDir=.\Debug -InputPath=..\sw\r_aliasa.s -InputName=r_aliasa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common $(InputPath) > $(OUTDIR)\$(InputName).spp - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Intermediate_Dir ".\MDebug" -# Begin Custom Build -OutDir=.\MDebug -InputPath=..\sw\r_aliasa.s -InputName=r_aliasa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -# PROP BASE Exclude_From_Build 1 -# Begin Custom Build -OutDir=.\MRelease -InputPath=..\sw\r_aliasa.s -InputName=r_aliasa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -# Begin Custom Build -OutDir=.\ftequake___Win32_MinSW -InputPath=..\sw\r_aliasa.s -InputName=r_aliasa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\r_drawa.s - -!IF "$(CFG)" == "ftequake - Win32 Release" - -# Begin Custom Build -OutDir=.\Release -InputPath=..\sw\r_drawa.s -InputName=r_drawa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -# Begin Custom Build -OutDir=.\Debug -InputPath=..\sw\r_drawa.s -InputName=r_drawa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common $(InputPath) > $(OUTDIR)\$(InputName).spp - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Intermediate_Dir ".\MDebug" -# Begin Custom Build -OutDir=.\MDebug -InputPath=..\sw\r_drawa.s -InputName=r_drawa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -# PROP BASE Exclude_From_Build 1 -# Begin Custom Build -OutDir=.\MRelease -InputPath=..\sw\r_drawa.s -InputName=r_drawa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -# Begin Custom Build -OutDir=.\ftequake___Win32_MinSW -InputPath=..\sw\r_drawa.s -InputName=r_drawa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\r_edgea.s - -!IF "$(CFG)" == "ftequake - Win32 Release" - -# Begin Custom Build -OutDir=.\Release -InputPath=..\sw\r_edgea.s -InputName=r_edgea - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -# Begin Custom Build -OutDir=.\Debug -InputPath=..\sw\r_edgea.s -InputName=r_edgea - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common $(InputPath) > $(OUTDIR)\$(InputName).spp - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Intermediate_Dir ".\MDebug" -# Begin Custom Build -OutDir=.\MDebug -InputPath=..\sw\r_edgea.s -InputName=r_edgea - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -# PROP BASE Exclude_From_Build 1 -# Begin Custom Build -OutDir=.\MRelease -InputPath=..\sw\r_edgea.s -InputName=r_edgea - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -# Begin Custom Build -OutDir=.\ftequake___Win32_MinSW -InputPath=..\sw\r_edgea.s -InputName=r_edgea - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\r_varsa.s - -!IF "$(CFG)" == "ftequake - Win32 Release" - -# Begin Custom Build -OutDir=.\Release -InputPath=..\sw\r_varsa.s -InputName=r_varsa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -# Begin Custom Build -OutDir=.\Debug -InputPath=..\sw\r_varsa.s -InputName=r_varsa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common $(InputPath) > $(OUTDIR)\$(InputName).spp - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Intermediate_Dir ".\MDebug" -# Begin Custom Build -OutDir=.\MDebug -InputPath=..\sw\r_varsa.s -InputName=r_varsa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -# PROP BASE Exclude_From_Build 1 -# Begin Custom Build -OutDir=.\MRelease -InputPath=..\sw\r_varsa.s -InputName=r_varsa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -# Begin Custom Build -OutDir=.\ftequake___Win32_MinSW -InputPath=..\sw\r_varsa.s -InputName=r_varsa - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - SOURCE=..\client\snd_mixa.s !IF "$(CFG)" == "ftequake - Win32 Release" @@ -8928,262 +5566,6 @@ InputName=snd_mixa # End Source File # Begin Source File -SOURCE=..\sw\surf16.s - -!IF "$(CFG)" == "ftequake - Win32 Release" - -# Begin Custom Build -OutDir=.\Release -InputPath=..\sw\surf16.s -InputName=surf16 - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -# Begin Custom Build -OutDir=.\Debug -InputPath=..\sw\surf16.s -InputName=surf16 - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common $(InputPath) > $(OUTDIR)\$(InputName).spp - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Intermediate_Dir ".\MDebug" -# Begin Custom Build -OutDir=.\MDebug -InputPath=..\sw\surf16.s -InputName=surf16 - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -# PROP BASE Exclude_From_Build 1 -# Begin Custom Build -OutDir=.\MRelease -InputPath=..\sw\surf16.s -InputName=surf16 - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -# Begin Custom Build -OutDir=.\ftequake___Win32_MinSW -InputPath=..\sw\surf16.s -InputName=surf16 - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\sw\surf8.s - -!IF "$(CFG)" == "ftequake - Win32 Release" - -# Begin Custom Build -OutDir=.\Release -InputPath=..\sw\surf8.s -InputName=surf8 - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" - -# Begin Custom Build -OutDir=.\Debug -InputPath=..\sw\surf8.s -InputName=surf8 - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common $(InputPath) > $(OUTDIR)\$(InputName).spp - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" - -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Intermediate_Dir ".\MDebug" -# Begin Custom Build -OutDir=.\MDebug -InputPath=..\sw\surf8.s -InputName=surf8 - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" - -# PROP BASE Exclude_From_Build 1 -# Begin Custom Build -OutDir=.\MRelease -InputPath=..\sw\surf8.s -InputName=surf8 - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" - -# Begin Custom Build -OutDir=.\ftequake___Win32_MinSW -InputPath=..\sw\surf8.s -InputName=surf8 - -"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - cl /EP /I ..\common > $(OUTDIR)\$(InputName).spp $(InputPath) - ..\gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm - ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm - del $(OUTDIR)\$(InputName).spp - -# End Custom Build - -!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated ServerQ3" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ELSEIF "$(CFG)" == "ftequake - Win32 D3DDebug" - -# PROP BASE Exclude_From_Build 1 -# PROP Exclude_From_Build 1 - -!ENDIF - -# End Source File -# Begin Source File - SOURCE=..\client\sys_wina.s !IF "$(CFG)" == "ftequake - Win32 Release" diff --git a/engine/ftequake/ftequake.dsw b/engine/ftequake/ftequake.dsw index 21cea1c7..74d44edf 100644 --- a/engine/ftequake/ftequake.dsw +++ b/engine/ftequake/ftequake.dsw @@ -3,6 +3,21 @@ Microsoft Developer Studio Workspace File, Format Version 6.00 ############################################################################### +Project: "csqctest"=..\..\..\GAME\CSQCTEST\SRC\csqctest.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name qcc + End Project Dependency +}}} + +############################################################################### + Project: "ftequake"=.\ftequake.dsp - Package Owner=<4> Package=<5> @@ -111,6 +126,18 @@ Package=<4> ############################################################################### +Project: "websv"=..\HTTP\websv.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + Global: Package=<5> diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index c69de96f..be5b36d8 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -14,10 +14,10 @@ #include "quakedef.h" -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h" #endif -#if defined(RGLQUAKE) +#if defined(GLQUAKE) #ifdef _WIN32 #include @@ -93,7 +93,7 @@ extern cvar_t r_skin_overlays; #ifndef SERVERONLY static hashtable_t skincolourmapped; -extern vec3_t shadevector, shadelight, ambientlight; +extern avec3_t shadevector, shadelight, ambientlight; //changes vertex lighting values static void R_GAliasApplyLighting(mesh_t *mesh, vec3_t org, vec3_t angles, float *colormod) @@ -101,20 +101,20 @@ static void R_GAliasApplyLighting(mesh_t *mesh, vec3_t org, vec3_t angles, float int l, v; vec3_t rel; vec3_t dir; - float dot, d, a, f; + float dot, d, a; - if (mesh->colors_array) + if (mesh->colors4f_array) { float l; int temp; int i; - byte_vec4_t *colours = mesh->colors_array; + avec4_t *colours = mesh->colors4f_array; vec3_t *normals = mesh->normals_array; vec3_t ambient, shade; - qbyte alphab = bound(0, colormod[3]*255, 255); + qbyte alphab = bound(0, colormod[3], 1); if (!mesh->normals_array) { - mesh->colors_array = NULL; + mesh->colors4f_array = NULL; return; } @@ -133,27 +133,22 @@ static void R_GAliasApplyLighting(mesh_t *mesh, vec3_t org, vec3_t angles, float l = DotProduct(normals[i], shadevector); temp = l*ambient[0]+shade[0]; - if (temp < 0) temp = 0; - else if (temp > 255) temp = 255; colours[i][0] = temp; temp = l*ambient[1]+shade[1]; - if (temp < 0) temp = 0; - else if (temp > 255) temp = 255; colours[i][1] = temp; temp = l*ambient[2]+shade[2]; - if (temp < 0) temp = 0; - else if (temp > 255) temp = 255; colours[i][2] = temp; colours[i][3] = alphab; } } - if (r_vertexdlights.value && mesh->colors_array) + if (r_vertexdlights.value && mesh->colors4f_array) { - for (l=0 ; l0) { a *= 10000000*dot/sqrt(d); - f = mesh->colors_array[v][0] + a*cl_dlights[l].color[0]; - if (f > 255) - f = 255; - else if (f < 0) - f = 0; - mesh->colors_array[v][0] = f; - - f = mesh->colors_array[v][1] + a*cl_dlights[l].color[1]; - if (f > 255) - f = 255; - else if (f < 0) - f = 0; - mesh->colors_array[v][1] = f; - - f = mesh->colors_array[v][2] + a*cl_dlights[l].color[2]; - if (f > 255) - f = 255; - else if (f < 0) - f = 0; - mesh->colors_array[v][2] = f; + mesh->colors4f_array[v][0] += a*cl_dlights[l].color[0]; + mesh->colors4f_array[v][1] += a*cl_dlights[l].color[1]; + mesh->colors4f_array[v][2] += a*cl_dlights[l].color[2]; } // else - // mesh->colors_array[v][1] =255; + // mesh->colors4f_array[v][1] = 1; } // else - // mesh->colors_array[v][2] =255; + // mesh->colors4f_array[v][2] = 1; } } } @@ -233,11 +211,12 @@ void GL_GAliasFlushSkinCache(void) skincolourmapped.numbuckets = 0; } -static galiastexnum_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, int surfnum, entity_t *e) +static texnums_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, int surfnum, entity_t *e) { galiasskin_t *skins; - galiastexnum_t *texnums; + texnums_t *texnums; int frame; + unsigned int subframe; unsigned int tc, bc; qboolean forced; @@ -304,27 +283,39 @@ static galiastexnum_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, int sur Hash_InitTable(&skincolourmapped, 256, buckets); } - for (cm = Hash_Get(&skincolourmapped, skinname); cm; cm = Hash_GetNext(&skincolourmapped, skinname, cm)) - { - if (cm->tcolour == tc && cm->bcolour == bc && cm->skinnum == e->skinnum) - { - return &cm->texnum; - } - } - if (!inf->numskins) { skins = NULL; + subframe = 0; texnums = NULL; } else { skins = (galiasskin_t*)((char *)inf + inf->ofsskins); if (!skins->texnums) - return NULL; - if (e->skinnum >= 0 && e->skinnum < inf->numskins) - skins += e->skinnum; - texnums = (galiastexnum_t*)((char *)skins + skins->ofstexnums); + { + skins = NULL; + subframe = 0; + texnums = NULL; + } + else + { + if (e->skinnum >= 0 && e->skinnum < inf->numskins) + skins += e->skinnum; + + subframe = cl.time*skins->skinspeed; + subframe = subframe%skins->texnums; + + texnums = (texnums_t*)((char *)skins + skins->ofstexnums + subframe*sizeof(texnums_t)); + } + } + + for (cm = Hash_Get(&skincolourmapped, skinname); cm; cm = Hash_GetNext(&skincolourmapped, skinname, cm)) + { + if (cm->tcolour == tc && cm->bcolour == bc && cm->skinnum == e->skinnum && cm->subframe == subframe) + { + return &cm->texnum; + } } //colourmap isn't present yet. @@ -334,11 +325,12 @@ static galiastexnum_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, int sur cm->tcolour = tc; cm->bcolour = bc; cm->skinnum = e->skinnum; - cm->texnum.fullbright = 0; - cm->texnum.base = 0; -#ifdef Q3SHADERS - cm->texnum.shader = NULL; -#endif + cm->subframe = subframe; + cm->texnum.fullbright = r_nulltex; + cm->texnum.base = r_nulltex; + cm->texnum.loweroverlay = r_nulltex; + cm->texnum.upperoverlay = r_nulltex; + cm->texnum.shader = texnums?texnums->shader:R_RegisterSkin(skinname); if (!texnums) { //load just the skin @@ -351,7 +343,7 @@ static galiastexnum_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, int sur { inwidth = e->scoreboard->skin->width; inheight = e->scoreboard->skin->height; - cm->texnum.base = cm->texnum.fullbright = GL_LoadTexture32(e->scoreboard->skin->name, inwidth, inheight, (unsigned int*)original, true, false); + cm->texnum.base = GL_LoadTexture32(e->scoreboard->skin->name, inwidth, inheight, (unsigned int*)original, IF_NOALPHA|IF_NOGAMMA); return &cm->texnum; } } @@ -362,12 +354,12 @@ static galiastexnum_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, int sur { inwidth = e->scoreboard->skin->width; inheight = e->scoreboard->skin->height; - cm->texnum.base = cm->texnum.fullbright = GL_LoadTexture(e->scoreboard->skin->name, inwidth, inheight, original, true, false); + cm->texnum.base = GL_LoadTexture(e->scoreboard->skin->name, inwidth, inheight, original, IF_NOALPHA|IF_NOGAMMA, 1); return &cm->texnum; } } - if (e->scoreboard->skin->tex_base) + if (TEXVALID(e->scoreboard->skin->tex_base)) { texnums = &cm->texnum; texnums->loweroverlay = e->scoreboard->skin->tex_lower; @@ -376,7 +368,7 @@ static galiastexnum_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, int sur return texnums; } - cm->texnum.base = Mod_LoadHiResTexture(e->scoreboard->skin->name, "skins", true, false, true); + cm->texnum.base = R_LoadHiResTexture(e->scoreboard->skin->name, "skins", IF_NOALPHA); return &cm->texnum; } return NULL; @@ -389,7 +381,7 @@ static galiastexnum_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, int sur inwidth = e->scoreboard->skin->width; inheight = e->scoreboard->skin->height; - if (!original && e->scoreboard->skin->tex_base) + if (!original && TEXVALID(e->scoreboard->skin->tex_base)) { texnums = &cm->texnum; texnums->loweroverlay = e->scoreboard->skin->tex_lower; @@ -434,8 +426,8 @@ static galiastexnum_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, int sur texnums = &cm->texnum; - texnums->base = 0; - texnums->fullbright = 0; + texnums->base = r_nulltex; + texnums->fullbright = r_nulltex; scaled_width = gl_max_size.value < 512 ? gl_max_size.value : 512; scaled_height = gl_max_size.value < 512 ? gl_max_size.value : 512; @@ -524,10 +516,10 @@ static galiastexnum_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, int sur } texnums->base = GL_AllocNewTexture(); GL_Bind(texnums->base); - qglTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + qglTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //now do the fullbrights. @@ -546,10 +538,10 @@ static galiastexnum_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, int sur } texnums->fullbright = GL_AllocNewTexture(); GL_Bind(texnums->fullbright); - qglTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + qglTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else { @@ -562,7 +554,7 @@ static galiastexnum_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, int sur frame = cl.time*skins->skinspeed; frame = frame%skins->texnums; - texnums = (galiastexnum_t*)((char *)skins + skins->ofstexnums + frame*sizeof(galiastexnum_t)); + texnums = (texnums_t*)((char *)skins + skins->ofstexnums + frame*sizeof(texnums_t)); memcpy(&cm->texnum, texnums, sizeof(cm->texnum)); } return &cm->texnum; @@ -587,7 +579,7 @@ static galiastexnum_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, int sur frame = cl.time*skins->skinspeed; frame = frame%skins->texnums; - texnums = (galiastexnum_t*)((char *)skins + skins->ofstexnums + frame*sizeof(galiastexnum_t)); + texnums = (texnums_t*)((char *)skins + skins->ofstexnums + frame*sizeof(texnums_t)); return texnums; } @@ -635,7 +627,7 @@ static void R_ProjectShadowVolume(mesh_t *mesh, vec3_t lightpos) { int numverts = mesh->numvertexes; int i; - vec3_t *input = mesh->xyz_array; + vecV_t *input = mesh->xyz_array; vec3_t *projected; if (numProjectedShadowVerts < numverts) { @@ -657,7 +649,7 @@ static void R_DrawShadowVolume(mesh_t *mesh) { int t; vec3_t *proj = ProjectedShadowVerts; - vec3_t *verts = mesh->xyz_array; + vecV_t *verts = mesh->xyz_array; index_t *indexes = mesh->indexes; int *neighbours = mesh->trneighbors; int numtris = mesh->numindexes/3; @@ -712,219 +704,51 @@ static void R_DrawShadowVolume(mesh_t *mesh) qglEnd(); } -void GL_DrawAliasMesh_Sketch (mesh_t *mesh, float linejitter) +void GL_DrawAliasMesh (mesh_t *mesh, texid_t texnum) { - int i; - extern int gldepthfunc; -#ifdef Q3SHADERS - R_UnlockArrays(); -#endif + shader_t shader; + memset(&shader, 0, sizeof(shader)); + shader.numpasses = 1; + shader.passes[0].numMergedPasses = 1; + shader.passes[0].anim_frames[0] = texnum; + shader.passes[0].rgbgen = RGB_GEN_IDENTITY; + shader.passes[0].alphagen = ALPHA_GEN_IDENTITY; + shader.passes[0].shaderbits |= SBITS_MISC_DEPTHWRITE; + shader.passes[0].blendmode = GL_MODULATE; + shader.passes[0].texgen = T_GEN_SINGLEMAP; - qglDepthFunc(gldepthfunc); - qglDepthMask(1); - - if (gldepthmin == 0.5) - qglCullFace ( GL_BACK ); - else - qglCullFace ( GL_FRONT ); - - GL_TexEnv(GL_MODULATE); - - qglDisable(GL_TEXTURE_2D); - - qglVertexPointer(3, GL_FLOAT, 0, mesh->xyz_array); - qglEnableClientState( GL_VERTEX_ARRAY ); - - if (mesh->normals_array && qglNormalPointer) //d3d wrapper doesn't support normals, and this is only really needed for truform - { - qglNormalPointer(GL_FLOAT, 0, mesh->normals_array); - qglEnableClientState( GL_NORMAL_ARRAY ); - } - - qglColor3f(1,1,1); -/* if (mesh->colors_array) - { - qglColorPointer(4, GL_UNSIGNED_BYTE, 0, mesh->colors_array); - qglEnableClientState( GL_COLOR_ARRAY ); - } - else -*/ qglDisableClientState( GL_COLOR_ARRAY ); - - qglDrawElements(GL_TRIANGLES, mesh->numindexes, GL_INDEX_TYPE, mesh->indexes); - - qglDisableClientState( GL_VERTEX_ARRAY ); - qglDisableClientState( GL_COLOR_ARRAY ); - qglDisableClientState( GL_NORMAL_ARRAY ); - - if (mesh->colors_array) - qglColor4ub(0, 0, 0, mesh->colors_array[0][3]); - else - qglColor3f(0, 0, 0); - qglBegin(GL_LINES); - for (i = 0; i < mesh->numindexes; i+=3) - { - float *v1, *v2, *v3; - int n; - v1 = mesh->xyz_array[mesh->indexes[i+0]]; - v2 = mesh->xyz_array[mesh->indexes[i+1]]; - v3 = mesh->xyz_array[mesh->indexes[i+2]]; - for (n = 0; n < 3; n++) //rember we do this triangle AND the neighbours - { - qglVertex3f(v1[0]+linejitter*(rand()/(float)RAND_MAX-0.5), - v1[1]+linejitter*(rand()/(float)RAND_MAX-0.5), - v1[2]+linejitter*(rand()/(float)RAND_MAX-0.5)); - qglVertex3f(v2[0]+linejitter*(rand()/(float)RAND_MAX-0.5), - v2[1]+linejitter*(rand()/(float)RAND_MAX-0.5), - v2[2]+linejitter*(rand()/(float)RAND_MAX-0.5)); - - qglVertex3f(v2[0]+linejitter*(rand()/(float)RAND_MAX-0.5), - v2[1]+linejitter*(rand()/(float)RAND_MAX-0.5), - v2[2]+linejitter*(rand()/(float)RAND_MAX-0.5)); - qglVertex3f(v3[0]+linejitter*(rand()/(float)RAND_MAX-0.5), - v3[1]+linejitter*(rand()/(float)RAND_MAX-0.5), - v3[2]+linejitter*(rand()/(float)RAND_MAX-0.5)); - - qglVertex3f(v3[0]+linejitter*(rand()/(float)RAND_MAX-0.5), - v3[1]+linejitter*(rand()/(float)RAND_MAX-0.5), - v3[2]+linejitter*(rand()/(float)RAND_MAX-0.5)); - qglVertex3f(v1[0]+linejitter*(rand()/(float)RAND_MAX-0.5), - v1[1]+linejitter*(rand()/(float)RAND_MAX-0.5), - v1[2]+linejitter*(rand()/(float)RAND_MAX-0.5)); - } - } - qglEnd(); - -#ifdef Q3SHADERS - R_IBrokeTheArrays(); -#endif + BE_DrawMeshChain(&shader, mesh, NULL, NULL); } -//called from sprite code. -/* -void GL_KnownState(void) +//true if no shading is to be used. +static qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel, unsigned int rmode) { - extern int gldepthfunc; - qglDepthFunc(gldepthfunc); - qglDepthMask(1); - if (gldepthmin == 0.5) - qglCullFace ( GL_BACK ); - else - qglCullFace ( GL_FRONT ); - - GL_TexEnv(GL_MODULATE); - - qglEnable (GL_BLEND); - qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -} -*/ - -void GL_DrawAliasMesh (mesh_t *mesh, int texnum) -{ - extern int gldepthfunc; -#ifdef Q3SHADERS - R_UnlockArrays(); -#endif - - qglDepthFunc(gldepthfunc); - qglDepthMask(1); - - GL_Bind(texnum); - if (gldepthmin == 0.5) - qglCullFace ( GL_BACK ); - else - qglCullFace ( GL_FRONT ); - - GL_TexEnv(GL_MODULATE); - - qglVertexPointer(3, GL_FLOAT, 0, mesh->xyz_array); - qglEnableClientState( GL_VERTEX_ARRAY ); - - if (mesh->normals_array && qglNormalPointer) //d3d wrapper doesn't support normals, and this is only really needed for truform - { - qglNormalPointer(GL_FLOAT, 0, mesh->normals_array); - qglEnableClientState( GL_NORMAL_ARRAY ); - } - - if (mesh->colors_array) - { - qglColorPointer(4, GL_UNSIGNED_BYTE, 0, mesh->colors_array); - qglEnableClientState( GL_COLOR_ARRAY ); - } - else - qglDisableClientState( GL_COLOR_ARRAY ); - - qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); - qglTexCoordPointer(2, GL_FLOAT, 0, mesh->st_array); - - qglDrawRangeElements(GL_TRIANGLES, 0, mesh->numvertexes, mesh->numindexes, GL_INDEX_TYPE, mesh->indexes); - - qglDisableClientState( GL_VERTEX_ARRAY ); - qglDisableClientState( GL_COLOR_ARRAY ); - qglDisableClientState( GL_NORMAL_ARRAY ); - qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); - -#ifdef Q3SHADERS - R_IBrokeTheArrays(); -#endif -} - -#ifdef Q3SHADERS -mfog_t *CM_FogForOrigin(vec3_t org); -#endif -void R_DrawGAliasModel (entity_t *e) -{ - extern cvar_t r_drawflat; - model_t *clmodel; - vec3_t dist; - vec_t add; - int i; - galiasinfo_t *inf; - mesh_t mesh; - galiastexnum_t *skin; - float entScale; vec3_t lightdir; + int i; + vec3_t dist; + float add; - vec3_t saveorg; -#ifdef Q3SHADERS - mfog_t *fog; -#endif - int surfnum; - - float tmatrix[3][4]; - - qboolean needrecolour; - qboolean nolightdir; - - currententity = e; - -// if (e->flags & Q2RF_VIEWERMODEL && e->keynum == cl.playernum[r_refdef.currentplayernum]+1) -// return; - - if (r_secondaryview && e->flags & Q2RF_WEAPONMODEL) - return; - + if (clmodel->engineflags & MDLF_FLAME) { - extern int cl_playerindex; - if (e->scoreboard && e->model == cl.model_precache[cl_playerindex]) - { - clmodel = e->scoreboard->model; - if (!clmodel || clmodel->type != mod_alias) - clmodel = e->model; + shadelight[0] = shadelight[1] = shadelight[2] = 4096; + ambientlight[0] = ambientlight[1] = ambientlight[2] = 4096; + return true; } - else - clmodel = e->model; + if ((e->drawflags & MLS_MASKIN) == MLS_FULLBRIGHT || (e->flags & Q2RF_FULLBRIGHT)) + { + shadelight[0] = shadelight[1] = shadelight[2] = 255; + ambientlight[0] = ambientlight[1] = ambientlight[2] = 0; + return true; } - if (clmodel->tainted) + //shortcut here, no need to test bsp lights or world lights when there's realtime lighting going on. + if (rmode == BEM_DEPTHDARK || rmode == BEM_DEPTHONLY) { - if (!ruleset_allow_modified_eyes.value && !strcmp(clmodel->name, "progs/eyes.mdl")) - return; + shadelight[0] = shadelight[1] = shadelight[2] = 0; + ambientlight[0] = ambientlight[1] = ambientlight[2] = 0; + return true; } - if (!(e->flags & Q2RF_WEAPONMODEL)) - if (R_CullEntityBox (e, clmodel->mins, clmodel->maxs)) - return; - if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL)) { if (e->flags & Q2RF_WEAPONMODEL) @@ -940,9 +764,10 @@ void R_DrawGAliasModel (entity_t *e) lightdir[2] = 1; } - if (!r_vertexdlights.value) + if (!r_vertexdlights.ival && r_dynamic.ival) { - for (i=0 ; iengineflags & MDLF_PLAYER) { float fb = r_fullbrightSkins.value; @@ -1004,7 +825,7 @@ void R_DrawGAliasModel (entity_t *e) { ambientlight[0] = ambientlight[1] = ambientlight[2] = 4096; shadelight[0] = shadelight[1] = shadelight[2] = 4096; - nolightdir = true; + return true; } else { @@ -1021,22 +842,15 @@ void R_DrawGAliasModel (entity_t *e) ambientlight[i] = shadelight[i] = 8; } } - if (clmodel->engineflags & MDLF_FLAME) - { - shadelight[0] = shadelight[1] = shadelight[2] = 4096; - ambientlight[0] = ambientlight[1] = ambientlight[2] = 4096; - nolightdir = true; - } - else - { - for (i = 0; i < 3; i++) - { - if (ambientlight[i] > 128) - ambientlight[i] = 128; - shadelight[i] /= 200.0/255; - ambientlight[i] /= 200.0/255; - } + + for (i = 0; i < 3; i++) + { + if (ambientlight[i] > 128) + ambientlight[i] = 128; + + shadelight[i] /= 200.0/255; + ambientlight[i] /= 200.0/255; } if ((e->model->flags & EF_ROTATE) && cl.hexen2pickups) @@ -1049,12 +863,6 @@ void R_DrawGAliasModel (entity_t *e) shadelight[0] = shadelight[1] = shadelight[2] = e->abslight; ambientlight[0] = ambientlight[1] = ambientlight[2] = 0; } - if ((e->drawflags & MLS_MASKIN) == MLS_FULLBRIGHT || (e->flags & Q2RF_FULLBRIGHT)) - { - shadelight[0] = shadelight[1] = shadelight[2] = 255; - ambientlight[0] = ambientlight[1] = ambientlight[2] = 0; - nolightdir = true; - } //#define SHOWLIGHTDIR { //lightdir is absolute, shadevector is relative @@ -1074,84 +882,122 @@ void R_DrawGAliasModel (entity_t *e) VectorNormalize(shadevector); - VectorCopy(shadevector, mesh.lightaxis[2]); - VectorVectors(mesh.lightaxis[2], mesh.lightaxis[1], mesh.lightaxis[0]); - VectorInverse(mesh.lightaxis[1]); } + shadelight[0] *= 1/255.0f; + shadelight[1] *= 1/255.0f; + shadelight[2] *= 1/255.0f; + ambientlight[0] *= 1/255.0f; + ambientlight[1] *= 1/255.0f; + ambientlight[2] *= 1/255.0f; + if (e->flags & Q2RF_GLOW) { shadelight[0] += sin(cl.time)*0.25; shadelight[1] += sin(cl.time)*0.25; shadelight[2] += sin(cl.time)*0.25; } + return false; +} -/* - VectorClear(ambientlight); - VectorClear(shadelight); -*/ +static shader_t reskinnedmodelshader; +void R_DrawGAliasModel (entity_t *e, unsigned int rmode) +{ + extern cvar_t r_drawflat; + model_t *clmodel; + galiasinfo_t *inf; + mesh_t mesh; + texnums_t *skin; + float entScale; - /* - an = e->angles[1]/180*M_PI; - shadevector[0] = cos(-an); - shadevector[1] = sin(-an); - shadevector[2] = 1; - VectorNormalize (shadevector); - */ + vec3_t saveorg; + int surfnum; - GL_DisableMultitexture(); - GL_TexEnv(GL_MODULATE); - if (gl_smoothmodels.value) - qglShadeModel (GL_SMOOTH); - if (gl_affinemodels.value) + float tmatrix[3][4]; + + qboolean needrecolour; + qboolean nolightdir; + + shader_t *shader; + + currententity = e; + +// if (e->flags & Q2RF_VIEWERMODEL && e->keynum == cl.playernum[r_refdef.currentplayernum]+1) +// return; + + if (r_secondaryview && e->flags & Q2RF_WEAPONMODEL) + return; + + { + extern int cl_playerindex; + if (e->scoreboard && e->model == cl.model_precache[cl_playerindex]) + { + clmodel = e->scoreboard->model; + if (!clmodel || clmodel->type != mod_alias) + clmodel = e->model; + } + else + clmodel = e->model; + } + + if (clmodel->tainted) + { + if (!ruleset_allow_modified_eyes.ival && !strcmp(clmodel->name, "progs/eyes.mdl")) + return; + } + + if (!(e->flags & Q2RF_WEAPONMODEL)) + { + if (R_CullEntityBox (e, clmodel->mins, clmodel->maxs)) + return; +#ifdef RTLIGHTS + if (BE_LightCullModel(e->origin, clmodel)) + return; + } + else + { + if (BE_LightCullModel(r_origin, clmodel)) + return; +#endif + } + + nolightdir = R_CalcModelLighting(e, clmodel, rmode); + + if (gl_affinemodels.ival) qglHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); - qglDisable (GL_ALPHA_TEST); - if (e->flags & Q2RF_DEPTHHACK) qglDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin)); -// glColor3f( 1,1,1); - if (e->flags & Q2RF_ADDATIVE) + BE_SelectMode(rmode, BEF_FORCEDEPTHTEST); + + if (e->flags & Q2RF_ADDITIVE) { - qglEnable (GL_BLEND); - qglBlendFunc(GL_ONE, GL_ONE); - } - else if ((e->model->flags & EFH2_SPECIAL_TRANS)) //hexen2 flags. - { - qglEnable (GL_BLEND); - qglBlendFunc (GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA); -// glColor3f( 1,1,1); - qglDisable( GL_CULL_FACE ); + BE_SelectMode(rmode, BEF_FORCEDEPTHTEST|BEF_FORCEADDITIVE); } else if (e->drawflags & DRF_TRANSLUCENT) { - qglEnable (GL_BLEND); - qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + BE_SelectMode(rmode, BEF_FORCEDEPTHTEST|BEF_FORCETRANSPARENT); e->shaderRGBAf[3] = r_wateralpha.value; } + else if ((e->model->flags & EFH2_SPECIAL_TRANS)) //hexen2 flags. + { + //BEFIXME: this needs to generate the right sort of default instead + //(alpha blend+disable cull) + } else if ((e->model->flags & EFH2_TRANSPARENT)) { - qglEnable (GL_BLEND); - qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + //BEFIXME: make sure the shader generator works } else if ((e->model->flags & EFH2_HOLEY)) { - qglEnable (GL_ALPHA_TEST); -// qglEnable (GL_BLEND); - qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + //BEFIXME: this needs to generate the right sort of default instead + //(alpha test) } else if (e->shaderRGBAf[3] < 1) { - qglEnable(GL_BLEND); - qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + BE_SelectMode(rmode, BEF_FORCEDEPTHTEST|BEF_FORCETRANSPARENT); } - else - { - qglDisable(GL_BLEND); - qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - // qglEnable (GL_ALPHA_TEST); qglPushMatrix(); R_RotateForEntity(e); @@ -1256,14 +1102,14 @@ void R_DrawGAliasModel (entity_t *e) qglScalef (2, 2, 2); } - if (!ruleset_allow_larger_models.value && clmodel->clampscale != 1) + if (!ruleset_allow_larger_models.ival && clmodel->clampscale != 1) { //possibly this should be on a per-frame basis, but that's a real pain to do Con_DPrintf("Rescaling %s by %f\n", clmodel->name, clmodel->clampscale); qglScalef(clmodel->clampscale, clmodel->clampscale, clmodel->clampscale); } - inf = GLMod_Extradata (clmodel); - if (qglPNTrianglesfATI && gl_ati_truform.value) + inf = RMod_Extradata (clmodel); + if (qglPNTrianglesfATI && gl_ati_truform.ival) qglEnable(GL_PN_TRIANGLES_ATI); if (clmodel == cl.model_precache_vwep[0]) @@ -1278,14 +1124,6 @@ void R_DrawGAliasModel (entity_t *e) VectorCopy(r_refdef.vieworg, currententity->origin); } -#if defined(Q3SHADERS) && defined(Q2BSPS) - fog = CM_FogForOrigin(currententity->origin); -#elif defined(Q3SHADERS) - fog = NULL; -#endif - - qglColor4f(shadelight[0]/255, shadelight[1]/255, shadelight[2]/255, e->shaderRGBAf[3]); - memset(&mesh, 0, sizeof(mesh)); for(surfnum=0; inf; ((inf->nextsurf)?(inf = (galiasinfo_t*)((char *)inf + inf->nextsurf)):(inf=NULL)), surfnum++) { @@ -1293,232 +1131,55 @@ void R_DrawGAliasModel (entity_t *e) c_alias_polys += mesh.numindexes/3; - if (r_drawflat.value == 2) - { - if (needrecolour) - R_GAliasApplyLighting(&mesh, e->origin, e->angles, e->shaderRGBAf); - GL_DrawAliasMesh_Sketch(&mesh, 0.5); - continue; - } -#ifdef Q3SHADERS - else if (currententity->forcedshader) - { - meshbuffer_t mb; - - R_IBrokeTheArrays(); - - mb.entity = currententity; - mb.shader = currententity->forcedshader; - mb.fog = fog; - mb.mesh = &mesh; - mb.infokey = -1;//currententity->keynum; - mb.dlightbits = 0; - - R_PushMesh(&mesh, mb.shader->features | MF_NONBATCHED | MF_COLORS); - - R_RenderMeshBuffer ( &mb, false ); - - continue; - } -#endif - + shader = currententity->forcedshader; skin = GL_ChooseSkin(inf, clmodel->name, surfnum, e); - if (!skin || ((void*)skin->base == NULL -#ifdef Q3SHADERS - && skin->shader == NULL -#endif - )) + if (!shader) { - if (needrecolour) - R_GAliasApplyLighting(&mesh, e->origin, e->angles, e->shaderRGBAf); - GL_DrawAliasMesh_Sketch(&mesh, 0); - } -#ifdef Q3SHADERS - else if (skin->shader) - { - meshbuffer_t mb; - int olddst = skin->shader->numpasses?skin->shader->passes[0].blenddst:0; - - if (e->flags & Q2RF_ADDATIVE && skin->shader->numpasses) - { //hack the shader into submition. - skin->shader->passes[0].blenddst = GL_ONE; - skin->shader->passes[0].flags &= ~SHADER_PASS_DEPTHWRITE; - } - - mb.entity = currententity; - mb.shader = skin->shader; - mb.fog = fog; - mb.mesh = &mesh; - mb.infokey = -1;//currententity->keynum; - mb.dlightbits = 0; - - R_IBrokeTheArrays(); - - R_PushMesh(&mesh, skin->shader->features | MF_NONBATCHED | MF_COLORS); - - R_RenderMeshBuffer ( &mb, false ); - - if (e->flags & Q2RF_ADDATIVE && skin->shader->numpasses) - { //hack the shader into submition. - skin->shader->passes[0].blenddst = olddst; - } - } -#endif - else - { - if (needrecolour) - R_GAliasApplyLighting(&mesh, e->origin, e->angles, e->shaderRGBAf); - - qglEnable(GL_TEXTURE_2D); -// if (skin->bump) -// GL_DrawMeshBump(&mesh, skin->base, 0, skin->bump, 0); -// else - GL_DrawAliasMesh(&mesh, skin->base); - - if (skin->loweroverlay && r_skin_overlays.value) + if (skin && skin->shader) + shader = skin->shader; + else { - qglEnable(GL_BLEND); - qglBlendFunc (GL_SRC_ALPHA, GL_ONE); - mesh.colors_array = NULL; - if (e->scoreboard) + shader = &reskinnedmodelshader; + skin = &shader->defaulttextures; + reskinnedmodelshader.numpasses = 1; + reskinnedmodelshader.passes[0].flags = 0; + reskinnedmodelshader.passes[0].numMergedPasses = 1; + reskinnedmodelshader.passes[0].anim_frames[0] = skin->base; + if (nolightdir || !mesh.normals_array || !mesh.colors4f_array) { - int c = e->scoreboard->tbottomcolor; - if (c >= 16) - qglColor4f(shadelight[0]/255, shadelight[1]/255, shadelight[2]/255, e->shaderRGBAf[3]); - else if (c >= 8) - qglColor4f(host_basepal[c*16*3]/255.0f, host_basepal[c*16*3+1]/255.0f, host_basepal[c*16*3+2]/255.0f, e->shaderRGBAf[3]); - else - qglColor4f(host_basepal[15+c*16*3]/255.0f, host_basepal[15+c*16*3+1]/255.0f, host_basepal[15+c*16*3+2]/255.0f, e->shaderRGBAf[3]); + reskinnedmodelshader.passes[0].rgbgen = RGB_GEN_IDENTITY_LIGHTING; + reskinnedmodelshader.passes[0].flags |= SHADER_PASS_NOCOLORARRAY; } - c_alias_polys += mesh.numindexes/3; - GL_DrawAliasMesh(&mesh, skin->loweroverlay); + else + reskinnedmodelshader.passes[0].rgbgen = RGB_GEN_LIGHTING_DIFFUSE; + reskinnedmodelshader.passes[0].alphagen = (e->shaderRGBAf[3]<1)?ALPHA_GEN_ENTITY:ALPHA_GEN_IDENTITY; + reskinnedmodelshader.passes[0].shaderbits |= SBITS_MISC_DEPTHWRITE; + reskinnedmodelshader.passes[0].blendmode = GL_MODULATE; + reskinnedmodelshader.passes[0].texgen = T_GEN_DIFFUSE; + + reskinnedmodelshader.flags = SHADER_CULL_FRONT; } - if (skin->upperoverlay && r_skin_overlays.value) - { - qglEnable(GL_BLEND); - qglBlendFunc (GL_SRC_ALPHA, GL_ONE); - mesh.colors_array = NULL; - if (e->scoreboard) - { - int c = e->scoreboard->ttopcolor; - if (c >= 16) - qglColor4f(shadelight[0]/255, shadelight[1]/255, shadelight[2]/255, e->shaderRGBAf[3]); - else if (c >= 8) - qglColor4f(host_basepal[c*16*3]/255.0f, host_basepal[c*16*3+1]/255.0f, host_basepal[c*16*3+2]/255.0f, e->shaderRGBAf[3]); - else - qglColor4f(host_basepal[15+c*16*3]/255.0f, host_basepal[15+c*16*3+1]/255.0f, host_basepal[15+c*16*3+2]/255.0f, e->shaderRGBAf[3]); - } - c_alias_polys += mesh.numindexes/3; - GL_DrawAliasMesh(&mesh, skin->upperoverlay); - } - if (skin->fullbright && r_fb_models.value && cls.allow_luma) - { - mesh.colors_array = NULL; - qglEnable(GL_BLEND); - qglColor4f(e->shaderRGBAf[0], e->shaderRGBAf[1], e->shaderRGBAf[2], e->shaderRGBAf[3]*r_fb_models.value); - c_alias_polys += mesh.numindexes/3; - - qglBlendFunc (GL_SRC_ALPHA, GL_ONE); - GL_DrawAliasMesh(&mesh, skin->fullbright); - qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } -#ifdef Q3BSPS - if (fog) - { - meshbuffer_t mb; - shader_t dummyshader = {0}; - - R_IBrokeTheArrays(); - - mb.entity = currententity; - mb.shader = &dummyshader; - mb.fog = fog; - mb.mesh = &mesh; - mb.infokey = -1;//currententity->keynum; - mb.dlightbits = 0; - - R_PushMesh(&mesh, mb.shader->features | MF_NONBATCHED | MF_COLORS); - - R_RenderMeshBuffer ( &mb, false ); - - - R_ClearArrays(); - } -#endif } + + BE_DrawMeshChain(shader, &mesh, NULL, skin); } if (e->flags & Q2RF_WEAPONMODEL) VectorCopy(saveorg, currententity->origin); - if (qglPNTrianglesfATI && gl_ati_truform.value) + if (qglPNTrianglesfATI && gl_ati_truform.ival) qglDisable(GL_PN_TRIANGLES_ATI); -#ifdef SHOWLIGHTDIR //testing - qglDisable(GL_TEXTURE_2D); - qglBegin(GL_LINES); - qglColor3f(1,0,0); - qglVertex3f( 0, - 0, - 0); - qglVertex3f( 100*mesh.lightaxis[0][0], - 100*mesh.lightaxis[0][1], - 100*mesh.lightaxis[0][2]); - -qglColor3f(0,1,0); - qglVertex3f( 0, - 0, - 0); - qglVertex3f( 100*mesh.lightaxis[1][0], - 100*mesh.lightaxis[1][1], - 100*mesh.lightaxis[1][2]); - -qglColor3f(0,0,1); - qglVertex3f( 0, - 0, - 0); - qglVertex3f( 100*mesh.lightaxis[2][0], - 100*mesh.lightaxis[2][1], - 100*mesh.lightaxis[2][2]); - qglEnd(); - qglEnable(GL_TEXTURE_2D); -#endif - qglPopMatrix(); - qglDisable(GL_BLEND); - - qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - GL_TexEnv(GL_REPLACE); - - qglEnable(GL_TEXTURE_2D); - - qglShadeModel (GL_FLAT); if (gl_affinemodels.value) qglHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); if (e->flags & Q2RF_DEPTHHACK) qglDepthRange (gldepthmin, gldepthmax); - if ((currententity->model->flags & EFH2_SPECIAL_TRANS) && gl_cull.value) - qglEnable( GL_CULL_FACE ); - if ((currententity->model->flags & EFH2_HOLEY)) - qglDisable( GL_ALPHA_TEST ); - -#ifdef SHOWLIGHTDIR //testing - qglDisable(GL_TEXTURE_2D); - qglColor3f(1,1,1); - qglBegin(GL_LINES); - qglVertex3f( currententity->origin[0], - currententity->origin[1], - currententity->origin[2]); - qglVertex3f( currententity->origin[0]+100*lightdir[0], - currententity->origin[1]+100*lightdir[1], - currententity->origin[2]+100*lightdir[2]); - qglEnd(); - qglEnable(GL_TEXTURE_2D); -#endif + BE_SelectMode(rmode, 0); } //returns result in the form of the result vector @@ -1540,15 +1201,10 @@ void GL_LightMesh (mesh_t *mesh, vec3_t lightpos, vec3_t colours, float radius) vec3_t dir; int i; float dot, d, f, a; - vec3_t bcolours; - vec3_t *xyz = mesh->xyz_array; + vecV_t *xyz = mesh->xyz_array; vec3_t *normals = mesh->normals_array; - byte_vec4_t *out = mesh->colors_array; - - bcolours[0] = colours[0]*255; - bcolours[1] = colours[1]*255; - bcolours[2] = colours[2]*255; + vec4_t *out = mesh->colors4f_array; if (!out) return; //urm.. @@ -1566,25 +1222,13 @@ void GL_LightMesh (mesh_t *mesh, vec3_t lightpos, vec3_t colours, float radius) if (a>0) { a *= dot/sqrt(d); - f = a*bcolours[0]; - if (f > 255) - f = 255; - else if (f < 0) - f = 0; + f = a*colours[0]; out[i][0] = f; - f = a*bcolours[1]; - if (f > 255) - f = 255; - else if (f < 0) - f = 0; + f = a*colours[1]; out[i][1] = f; - f = a*bcolours[2]; - if (f > 255) - f = 255; - else if (f < 0) - f = 0; + f = a*colours[2]; out[i][2] = f; } else @@ -1600,24 +1244,18 @@ void GL_LightMesh (mesh_t *mesh, vec3_t lightpos, vec3_t colours, float radius) out[i][1] = 0; out[i][2] = 0; } - out[i][3] = 255; + out[i][3] = 1; } } else { - if (bcolours[0] > 255) - bcolours[0] = 255; - if (bcolours[1] > 255) - bcolours[1] = 255; - if (bcolours[2] > 255) - bcolours[2] = 255; for (i = 0; i < mesh->numvertexes; i++) { VectorSubtract(lightpos, xyz[i], dir); - out[i][0] = bcolours[0]; - out[i][1] = bcolours[1]; - out[i][2] = bcolours[2]; - out[i][3] = 255; + out[i][0] = colours[0]; + out[i][1] = colours[1]; + out[i][2] = colours[2]; + out[i][3] = 1; } } } @@ -1733,238 +1371,6 @@ void R_AliasGenerateVertexLightDirs(mesh_t *mesh, vec3_t lightdir, vec3_t *resul } } - -void R_DrawMeshBumpmap(mesh_t *mesh, galiastexnum_t *skin, vec3_t lightdir) -{ - extern int gldepthfunc; - static vec3_t *lightdirs; - static int maxlightdirs; - extern int normalisationCubeMap; - -#ifdef Q3SHADERS - R_UnlockArrays(); -#endif - - - //(bumpmap dot cubemap)*texture - - //why no luma? - //that's thrown on last. - - //why a cubemap? - //we need to pass colours as a normal somehow - //we could use the fragment colour for it, however, we then wouldn't be able to colour the light. - //so we use a cubemap, which has the added advantage of normalizing the light dir for us. - - //the bumpmap we use is tangent-space (so I'm told) - qglDepthFunc(gldepthfunc); - qglDepthMask(0); - if (gldepthmin == 0.5) - qglCullFace ( GL_BACK ); - else - qglCullFace ( GL_FRONT ); - - qglEnable(GL_BLEND); - - qglVertexPointer(3, GL_FLOAT, 0, mesh->xyz_array); - qglEnableClientState( GL_VERTEX_ARRAY ); - - if (mesh->normals_array && qglNormalPointer) //d3d wrapper doesn't support normals, and this is only really needed for truform - { - qglNormalPointer(GL_FLOAT, 0, mesh->normals_array); - qglEnableClientState( GL_NORMAL_ARRAY ); - } - - if (mesh->colors_array) - { - qglColorPointer(4, GL_UNSIGNED_BYTE, 0, mesh->colors_array); - qglEnableClientState( GL_COLOR_ARRAY ); - } - else - qglDisableClientState( GL_COLOR_ARRAY ); - - - if (maxlightdirs < mesh->numvertexes) - { - maxlightdirs = mesh->numvertexes; - lightdirs = BZ_Malloc(sizeof(vec3_t)*maxlightdirs*4); - } - - R_AliasGenerateVertexLightDirs(mesh, lightdir, - lightdirs + maxlightdirs*0, - lightdirs + maxlightdirs*1, - lightdirs + maxlightdirs*2, - lightdirs + maxlightdirs*3); - - GL_MBind(mtexid0, skin->bump); - GL_TexEnv(GL_REPLACE); - qglEnableClientState(GL_TEXTURE_COORD_ARRAY); - qglTexCoordPointer(2, GL_FLOAT, 0, mesh->st_array); - qglEnable(GL_TEXTURE_2D); - - GL_SelectTexture(mtexid1); - GL_BindType(GL_TEXTURE_CUBE_MAP_ARB, normalisationCubeMap); - qglEnable(GL_TEXTURE_CUBE_MAP_ARB); - qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); - qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); - qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_DOT3_RGB_ARB); - GL_TexEnv(GL_COMBINE_ARB); - - qglEnableClientState(GL_TEXTURE_COORD_ARRAY); - qglTexCoordPointer(3, GL_FLOAT, 0, lightdirs); - - if (gl_mtexarbable>=3) - { - GL_MBind(mtexid0+2, skin->base); - qglEnable(GL_TEXTURE_2D); - } - else - { //we don't support 3tmus, so draw the bumps, and multiply the rest over the top - qglDrawElements(GL_TRIANGLES, mesh->numindexes, GL_INDEX_TYPE, mesh->indexes); - qglDisable(GL_TEXTURE_CUBE_MAP_ARB); - GL_MBind(mtexid0, skin->base); - } - GL_TexEnv(GL_MODULATE); - qglEnableClientState(GL_TEXTURE_COORD_ARRAY); - qglTexCoordPointer(2, GL_FLOAT, 0, mesh->st_array); - - qglDrawElements(GL_TRIANGLES, mesh->numindexes, GL_INDEX_TYPE, mesh->indexes); - - - - -// GL_SelectTexture(mtexid2); - qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); - qglDisable(GL_TEXTURE_2D); - - GL_SelectTexture(mtexid1); - qglDisable(GL_TEXTURE_CUBE_MAP_ARB); - qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); - GL_TexEnv(GL_MODULATE); - - GL_SelectTexture(mtexid0); - qglEnable(GL_TEXTURE_2D); - qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); - - qglDisableClientState( GL_VERTEX_ARRAY ); - qglDisableClientState( GL_COLOR_ARRAY ); - qglDisableClientState( GL_NORMAL_ARRAY ); - -#ifdef Q3SHADERS - R_IBrokeTheArrays(); -#endif -} - -void R_DrawGAliasModelLighting (entity_t *e, vec3_t lightpos, vec3_t colours, float radius) -{ -#if 0 //glitches, no attenuation... :( - - model_t *clmodel = e->model; - vec3_t mins, maxs; - vec3_t lightdir; - galiasinfo_t *inf; - galiastexnum_t *tex; - mesh_t mesh; - int surfnum; - extern cvar_t r_nolightdir; - - if (e->flags & Q2RF_VIEWERMODEL) - return; - if (r_nolightdir.value) //are you crazy? - return; - - //Total insanity with r_shadows 2... -// if (!strcmp (clmodel->name, "progs/flame2.mdl")) -// CL_NewDlight (e, e->origin[0]-1, e->origin[1]+1, e->origin[2]+24, 200 + (rand()&31), host_frametime*2, 3); - -// if (!strcmp (clmodel->name, "progs/armor.mdl")) -// CL_NewDlight (e->keynum, e->origin[0]-1, e->origin[1]+1, e->origin[2]+25, 200 + (rand()&31), host_frametime*2, 3); - - VectorAdd (e->origin, clmodel->mins, mins); - VectorAdd (e->origin, clmodel->maxs, maxs); - -// if (!(e->flags & Q2RF_WEAPONMODEL)) -// if (R_CullBox (mins, maxs)) -// return; - - - RotateLightVector(e->axis, e->origin, lightpos, lightdir); - - - GL_DisableMultitexture(); - GL_TexEnv(GL_MODULATE); - if (gl_smoothmodels.value) - qglShadeModel (GL_SMOOTH); - if (gl_affinemodels.value) - qglHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); - - - if (e->flags & Q2RF_DEPTHHACK) - qglDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin)); - - qglColor3f(colours[0], colours[1], colours[2]); - qglColor4f(1, 1, 1, 1); - - qglPushMatrix(); - R_RotateForEntity(e); - inf = GLMod_Extradata (clmodel); - if (gl_ati_truform.value) - qglEnable(GL_PN_TRIANGLES_ATI); - qglEnable(GL_TEXTURE_2D); - - qglEnable(GL_POLYGON_OFFSET_FILL); - - GL_TexEnv(GL_REPLACE); -// qglDisable(GL_STENCIL_TEST); - qglEnable(GL_BLEND); - qglDisable(GL_ALPHA_TEST); //if you used an alpha channel where you shouldn't have, more fool you. - qglBlendFunc(GL_ONE, GL_ONE); -// qglDepthFunc(GL_ALWAYS); - for(surfnum=0;inf;surfnum++) - { - R_GAliasBuildMesh(&mesh, inf, e->alpha, false); - mesh.colors_array = tempColours; - - tex = GL_ChooseSkin(inf, clmodel->name, surfnum, e); - - if (tex->bump && e->alpha==1) - { - R_DrawMeshBumpmap(&mesh, tex, lightdir); - } - else - { - GL_LightMesh(&mesh, lightdir, colours, radius); - GL_DrawAliasMesh(&mesh, tex->base); - } - - if (inf->nextsurf) - inf = (galiasinfo_t*)((char *)inf + inf->nextsurf); - else - inf = NULL; - } - currententity->fatness=0; - qglPopMatrix(); - if (gl_ati_truform.value) - qglDisable(GL_PN_TRIANGLES_ATI); - - GL_TexEnv(GL_REPLACE); - - qglShadeModel (GL_FLAT); - if (gl_affinemodels.value) - qglHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - qglDisable(GL_POLYGON_OFFSET_FILL); - - if (e->flags & Q2RF_DEPTHHACK) - qglDepthRange (gldepthmin, gldepthmax); - - qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - qglDisable(GL_BLEND); - qglDisable(GL_TEXTURE_2D); - - R_IBrokeTheArrays(); -#endif -} - //FIXME: Be less agressive. //This function will have to be called twice (for geforce cards), with the same data, so do the building once and rendering twice. void R_DrawGAliasShadowVolume(entity_t *e, vec3_t lightpos, float radius) @@ -1976,11 +1382,11 @@ void R_DrawGAliasShadowVolume(entity_t *e, vec3_t lightpos, float radius) if (clmodel->engineflags & (MDLF_FLAME | MDLF_BOLT)) return; - if (r_noaliasshadows.value) + if (r_noaliasshadows.ival) return; - if (e->shaderRGBAf[3] < 0.5) - return; +// if (e->shaderRGBAf[3] < 0.5) +// return; RotateLightVector(e->axis, e->origin, lightpos, lightorg); @@ -1991,7 +1397,7 @@ void R_DrawGAliasShadowVolume(entity_t *e, vec3_t lightpos, float radius) R_RotateForEntity(e); - inf = GLMod_Extradata (clmodel); + inf = RMod_Extradata (clmodel); while(inf) { if (inf->ofs_trineighbours) @@ -2066,7 +1472,7 @@ static void R_BuildTriangleNeighbours ( int *neighbours, index_t *indexes, int n - +#if 0 void GL_GenerateNormals(float *orgs, float *normals, int *indicies, int numtris, int numverts) { vec3_t d1, d2; @@ -2135,5 +1541,6 @@ void GL_GenerateNormals(float *orgs, float *normals, int *indicies, int numtris, } } #endif +#endif -#endif // defined(RGLQUAKE) +#endif // defined(GLQUAKE) diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index 0a4d40bd..c40ae8f6 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -1,10 +1,2758 @@ +#include "quakedef.h" +#ifdef GLQUAKE + +#include "glquake.h" +#include "shader.h" + +#define LIGHTPASS_GLSL_SHARED "\ +varying vec2 tcbase;\n\ +varying vec3 lightvector;\n\ +#if defined(SPECULAR) || defined(USEOFFSETMAPPING)\n\ +varying vec3 eyevector;\n\ +#endif\n\ +#ifdef PCF\n\ +varying vec4 shadowcoord;\n\ +uniform mat4 entmatrix;\n\ +#endif\n\ +" + +#define LIGHTPASS_GLSL_VERTEX "\ +#ifdef VERTEX_SHADER\n\ +\ +uniform vec3 lightposition;\n\ +\ +#if defined(SPECULAR) || defined(USEOFFSETMAPPING)\n\ +uniform vec3 eyeposition;\n\ +#endif\n\ +\ +void main (void)\n\ +{\n\ + gl_Position = ftransform();\n\ +\ + tcbase = gl_MultiTexCoord0.xy; //pass the texture coords straight through\n\ +\ + vec3 lightminusvertex = lightposition - gl_Vertex.xyz;\n\ + lightvector.x = dot(lightminusvertex, gl_MultiTexCoord2.xyz);\n\ + lightvector.y = dot(lightminusvertex, gl_MultiTexCoord3.xyz);\n\ + lightvector.z = dot(lightminusvertex, gl_MultiTexCoord1.xyz);\n\ +\ +#if defined(SPECULAR)||defined(USEOFFSETMAPPING)\n\ + vec3 eyeminusvertex = eyeposition - gl_Vertex.xyz;\n\ + eyevector.x = dot(eyeminusvertex, gl_MultiTexCoord2.xyz);\n\ + eyevector.y = dot(eyeminusvertex, gl_MultiTexCoord3.xyz);\n\ + eyevector.z = dot(eyeminusvertex, gl_MultiTexCoord1.xyz);\n\ +#endif\n\ +#if defined(PCF) || defined(SPOT) || defined(PROJECTION)\n\ + shadowcoord = gl_TextureMatrix[7] * (entmatrix*gl_Vertex);\n\ +#endif\n\ +}\n\ +#endif\n\ +" + +/*this is full 4*4 PCF, with an added attempt at prenumbra*/ +/*the offset consts are 1/(imagesize*2) */ +#define PCF16P(f) "\ + float xPixelOffset = (1.0+shadowcoord.b/lightradius)/512.0;\ + float yPixelOffset = (1.0+shadowcoord.b/lightradius)/512.0;\ + float s = 0.0;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(-1.5 * xPixelOffset * shadowcoord.w, -1.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(-1.5 * xPixelOffset * shadowcoord.w, -0.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(-1.5 * xPixelOffset * shadowcoord.w, 0.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(-1.5 * xPixelOffset * shadowcoord.w, 1.1 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ +\ + s += "f"Proj(shadowmap, shadowcoord + vec4(-0.5 * xPixelOffset * shadowcoord.w, -1.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(-0.5 * xPixelOffset * shadowcoord.w, -0.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(-0.5 * xPixelOffset * shadowcoord.w, 0.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(-0.5 * xPixelOffset * shadowcoord.w, 1.1 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ +\ + s += "f"Proj(shadowmap, shadowcoord + vec4(0.5 * xPixelOffset * shadowcoord.w, -1.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(0.5 * xPixelOffset * shadowcoord.w, -0.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(0.5 * xPixelOffset * shadowcoord.w, 0.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(0.5 * xPixelOffset * shadowcoord.w, 1.1 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ +\ + s += "f"Proj(shadowmap, shadowcoord + vec4(1.5 * xPixelOffset * shadowcoord.w, -1.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(1.5 * xPixelOffset * shadowcoord.w, -0.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(1.5 * xPixelOffset * shadowcoord.w, 0.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(1.5 * xPixelOffset * shadowcoord.w, 1.1 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ +\ + colorscale *= s/5.0;\n\ + " + +/*this is pcf 3*3*/ +/*the offset consts are 1/(imagesize*2) */ +#define PCF9(f) "\ + const float xPixelOffset = 1.0/512.0;\ + const float yPixelOffset = 1.0/512.0;\ + float s = 0.0;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(-1.0 * xPixelOffset * shadowcoord.w, -1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(-1.0 * xPixelOffset * shadowcoord.w, 0.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(-1.0 * xPixelOffset * shadowcoord.w, 1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ +\ + s += "f"Proj(shadowmap, shadowcoord + vec4(0.0 * xPixelOffset * shadowcoord.w, -1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(0.0 * xPixelOffset * shadowcoord.w, 0.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(0.0 * xPixelOffset * shadowcoord.w, 1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ +\ + s += "f"Proj(shadowmap, shadowcoord + vec4(1.0 * xPixelOffset * shadowcoord.w, -1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(1.0 * xPixelOffset * shadowcoord.w, 0.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(1.0 * xPixelOffset * shadowcoord.w, 1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + colorscale *= s/9.0;\n\ + " + +/*this is a lazy form of pcf. take 5 samples in an x*/ +/*the offset consts are 1/(imagesize*2) */ +#define PCF5(f) "\ + float xPixelOffset = 1.0/512.0;\ + float yPixelOffset = 1.0/512.0;\ + float s = 0.0;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(-1.0 * xPixelOffset * shadowcoord.w, -1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(-1.0 * xPixelOffset * shadowcoord.w, 1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(0.0 * xPixelOffset * shadowcoord.w, 0.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(1.0 * xPixelOffset * shadowcoord.w, -1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + s += "f"Proj(shadowmap, shadowcoord + vec4(1.0 * xPixelOffset * shadowcoord.w, 1.0 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\ + colorscale *= s/5.0;\n\ + " + +/*this is unfiltered*/ +#define PCF1(f) "\ + colorscale *= "f"Proj(shadowmap, shadowcoord).r;\n" + +#define LIGHTPASS_GLSL_FRAGMENT "\ +#ifdef FRAGMENT_SHADER\n\ +uniform sampler2D baset;\n\ +#if defined(BUMP) || defined(SPECULAR) || defined(USEOFFSETMAPPING)\n\ +uniform sampler2D bumpt;\n\ +#endif\n\ +#ifdef SPECULAR\n\ +uniform sampler2D speculart;\n\ +#endif\n\ +#ifdef PROJECTION\n\ +uniform sampler2D projected;\n\ +#endif\n\ +#ifdef PCF\n\ +#ifdef CUBE\n\ +uniform samplerCubeShadow shadowmap;\n\ +#else\n\ +uniform sampler2DShadow shadowmap;\n\ +#endif\n\ +#endif\n\ +\ +\ +uniform float lightradius;\n\ +uniform vec3 lightcolour;\n\ +\ +#ifdef USEOFFSETMAPPING\n\ +uniform float offsetmapping_scale;\n\ +uniform float offsetmapping_bias;\n\ +#endif\n\ +\ +\ +void main (void)\n\ +{\n\ +#ifdef USEOFFSETMAPPING\n\ + // this is 3 sample because of ATI Radeon 9500-9800/X300 limits\n\ + vec2 OffsetVector = normalize(eyevector).xy * vec2(-0.333, 0.333);\n\ + vec2 TexCoordOffset = tcbase + OffsetVector * (offsetmapping_bias + offsetmapping_scale * texture2D(bumpt, tcbase).w);\n\ + TexCoordOffset += OffsetVector * (offsetmapping_bias + offsetmapping_scale * texture2D(bumpt, TexCoordOffset).w);\n\ + TexCoordOffset += OffsetVector * (offsetmapping_bias + offsetmapping_scale * texture2D(bumpt, TexCoordOffset).w);\n\ +#define tcbase TexCoordOffset\n\ +#endif\n\ +\ +\ +#ifdef BUMP\n\ + vec3 bases = vec3(texture2D(baset, tcbase));\n\ +#else\n\ + vec3 diff = vec3(texture2D(baset, tcbase));\n\ +#endif\n\ +#if defined(BUMP) || defined(SPECULAR)\n\ + vec3 bumps = vec3(texture2D(bumpt, tcbase)) * 2.0 - 1.0;\n\ +#endif\n\ +#ifdef SPECULAR\n\ + vec3 specs = vec3(texture2D(speculart, tcbase));\n\ +#endif\n\ +\ + vec3 nl = normalize(lightvector);\n\ + float colorscale = max(1.0 - dot(lightvector, lightvector)/(lightradius*lightradius), 0.0);\n\ +\ +#ifdef BUMP\n\ + vec3 diff;\n\ + diff = bases * max(dot(bumps, nl), 0.0);\n\ +#endif\n\ +#ifdef SPECULAR\n\ + vec3 halfdir = (normalize(eyevector) + normalize(lightvector))/2.0;\n\ + float dv = dot(halfdir, bumps);\n\ + diff += pow(dv, 8.0) * specs;\n\ + diff.g = pow(dv, 8.0);\n\ +#endif\n\ +\n\ +#ifdef PCF\n\ +#ifdef CUBE\n\ +"PCF9("shadowCube") /*valid are 1,5,9*/"\n\ +#else\n\ +"PCF9("shadow2D") /*valid are 1,5,9*/"\n\ +#endif\n\ +#endif\n\ +#if defined(SPOT)\n\ +/*Actually, this isn't correct*/\n\ +if (shadowcoord.w < 0.0) discard;\n\ +vec2 spot = ((shadowcoord.st)/shadowcoord.w - 0.5)*2.0;colorscale*=1.0-(dot(spot,spot));\n\ +#endif\n\ +#if defined(PROJECTION)\n\ + lightcolour *= texture2d(projected, shadowcoord);\n\ +#endif\n\ +\n\ + gl_FragColor.rgb = diff*colorscale*lightcolour;\n\ +}\n\ +\ +#endif\n\ +" +static const char LIGHTPASS_SHADER[] = "\ +{\n\ + program\n\ + {\n\ + %s%s\n\ + }\n\ +\ + //incoming fragment\n\ + param texture 0 baset\n\ + param opt texture 1 bumpt\n\ + param opt texture 2 speculart\n\ +\ + //light info\n\ + param lightpos lightposition\n\ + param lightradius lightradius\n\ + param lightcolour lightcolour\n\ +\ + param opt cvarf r_shadow_glsl_offsetmapping_bias offsetmapping_bias\n\ + param opt cvarf r_shadow_glsl_offsetmapping_scale offsetmapping_scale\n\ +\ + //eye pos\n\ + param opt eyepos EyePosition\n\ +\ + {\n\ + map $diffuse\n\ + blendfunc add\n\ + tcgen base\n\ + }\n\ + {\n\ + map $normalmap\n\ + tcgen normal\n\ + }\n\ + {\n\ + map $specular\n\ + tcgen svector\n\ + }\n\ + {\n\ + tcgen tvector\n\ + }\n\ +}"; +static const char PCFPASS_SHADER[] = "\ +{\n\ + program\n\ + {\n\ + //#define CUBE\n\ + #define SPOT\n\ + #define PCF\n\ + %s%s\n\ + }\n\ +\ + //incoming fragment\n\ + param texture 7 shadowmap\n\ + param texture 1 baset\n\ + param opt texture 2 bumpt\n\ + param opt texture 3 speculart\n\ +\ + //light info\n\ + param lightpos lightposition\n\ + param lightradius lightradius\n\ + param lightcolour lightcolour\n\ +\ + param opt cvarf r_shadow_glsl_offsetmapping_bias offsetmapping_bias\n\ + param opt cvarf r_shadow_glsl_offsetmapping_scale offsetmapping_scale\n\ +\ + //eye pos\n\ + param opt eyepos EyePosition\n\ + param opt entmatrix entmatrix\n\ +\ + {\n\ + map $shadowmap\n\ + blendfunc add\n\ + tcgen base\n\ + }\n\ + {\n\ + map $diffuse\n\ + tcgen normal\n\ + }\n\ + {\n\ + map $normalmap\n\ + tcgen svector\n\ + }\n\ + {\n\ + map $specular\n\ + tcgen tvector\n\ + }\n\ +}"; + + +extern texid_t *lightmap_textures; +extern texid_t *deluxmap_textures; +extern int lightmap_bytes; // 1, 2, or 4 +extern lightmapinfo_t **lightmap; +extern int numlightmaps; +extern cvar_t r_shadow_glsl_offsetmapping; + +#if 0//def _DEBUG +#define checkerror() if (qglGetError()) Con_Printf("Error detected at line %s:%i\n", __FILE__, __LINE__) +#else +#define checkerror() +#endif + + +void PPL_CreateShaderObjects(void){} +void PPL_BaseBModelTextures(entity_t *e){} +void R_DrawBeam( entity_t *e ){} +qboolean PPL_ShouldDraw(void) +{ + if (currententity->flags & Q2RF_EXTERNALMODEL && r_secondaryview != 3) + return false; + if (!Cam_DrawPlayer(r_refdef.currentplayernum, currententity->keynum-1)) + return false; + return true; +} + +enum{ +PERMUTATION_GENERIC = 0, +PERMUTATION_BUMPMAP = 1, +PERMUTATION_SPECULAR = 2, +PERMUTATION_BUMP_SPEC, +PERMUTATION_OFFSET = 4, +PERMUTATION_OFFSET_BUMP, +PERMUTATION_OFFSET_SPEC, +PERMUTATION_OFFSET_BUMP_SPEC, + +PERMUTATIONS +}; +static char *lightpassname[PERMUTATIONS] = +{ + "lightpass_flat", + "lightpass_bump", + "lightpass_spec", + "lightpass_bump_spec", + "lightpass_offset", + "lightpass_offset_bump", + "lightpass_offset_spec", + "lightpass_offset_bump_spec" +}; +static char *pcfpassname[PERMUTATIONS] = +{ + "lightpass_pcf", + "lightpass_pcf_bump", + "lightpass_pcf_spec", + "lightpass_pcf_bump_spec", + "lightpass_pcf_offset", + "lightpass_pcf_offset_bump", + "lightpass_pcf_offset_spec", + "lightpass_pcf_offset_bump_spec" +}; +static char *permutationdefines[PERMUTATIONS] = { + "", + "#define BUMP\n", + "#define SPECULAR\n", + "#define SPECULAR\n#define BUMP\n", + "#define USEOFFSETMAPPING\n", + "#define USEOFFSETMAPPING\n#define BUMP\n", + "#define USEOFFSETMAPPING\n#define SPECULAR\n", + "#define USEOFFSETMAPPING\n#define SPECULAR\n#define BUMP\n" +}; + +struct { + //internal state + struct { + int lastpasstmus; + int vbo_colour; + int vbo_texcoords[SHADER_PASS_MAX]; + int vbo_deforms; //holds verticies... in case you didn't realise. + + qboolean initedlightpasses; + const shader_t *lightpassshader[PERMUTATIONS]; + qboolean initedpcfpasses; + const shader_t *pcfpassshader[PERMUTATIONS]; + + qboolean force2d; + int currenttmu; + int texenvmode[SHADER_PASS_MAX]; + int currenttextures[SHADER_PASS_MAX]; + + polyoffset_t curpolyoffset; + unsigned int curcull; + texid_t curshadowmap; + + unsigned int shaderbits; + + mesh_t *pushedmeshes; + vbo_t dummyvbo; + int currentvbo; + int currentebo; + + int pendingvertexvbo; + void *pendingvertexpointer; + int curvertexvbo; + void *curvertexpointer; + + float identitylighting; //set to how bright lightmaps should be (reduced for overbright or realtime_world_lightmaps) + + texid_t temptexture; + }; + + //exterior state + struct { + backendmode_t mode; + unsigned int flags; + + vbo_t *sourcevbo; + const shader_t *curshader; + const entity_t *curentity; + const texnums_t *curtexnums; + texid_t curlightmap; + texid_t curdeluxmap; + + float curtime; + + vec3_t lightorg; + vec3_t lightcolours; + float lightradius; + texid_t lighttexture; + }; +} shaderstate; + +struct { + int numlights; + int shadowsurfcount; +} bench; + +void GL_TexEnv(GLenum mode) +{ + if (mode != shaderstate.texenvmode[shaderstate.currenttmu]) + { + qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode); + shaderstate.texenvmode[shaderstate.currenttmu] = mode; + } +} + +void GL_SetShaderState2D(qboolean is2d) +{ + shaderstate.force2d = is2d; + + if (!is2d) + { + qglEnable(GL_DEPTH_TEST); + shaderstate.shaderbits &= ~SBITS_MISC_NODEPTHTEST; + + qglDepthMask(GL_TRUE); + shaderstate.shaderbits |= SBITS_MISC_DEPTHWRITE; + } +} + +void GL_SelectTexture(int target) +{ + shaderstate.currenttmu = target; + if (qglClientActiveTextureARB) + { + qglClientActiveTextureARB(target + mtexid0); + qglActiveTextureARB(target + mtexid0); + } + else + qglSelectTextureSGIS(target + mtexid0); +} + +void GL_SelectVBO(int vbo) +{ + if (shaderstate.currentvbo != vbo) + { + shaderstate.currentvbo = vbo; + qglBindBufferARB(GL_ARRAY_BUFFER_ARB, shaderstate.currentvbo); + } +} +void GL_SelectEBO(int vbo) +{ + if (shaderstate.currentebo != vbo) + { + shaderstate.currentebo = vbo; + qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, shaderstate.currentebo); + } +} + +static void GL_ApplyVertexPointer(void) +{ + if (shaderstate.curvertexpointer != shaderstate.pendingvertexpointer || shaderstate.pendingvertexvbo != shaderstate.curvertexvbo) + { + shaderstate.curvertexpointer = shaderstate.pendingvertexpointer; + shaderstate.curvertexvbo = shaderstate.pendingvertexvbo; + GL_SelectVBO(shaderstate.curvertexvbo); + qglVertexPointer(3, GL_FLOAT, sizeof(vecV_t), shaderstate.curvertexpointer); + } +} + +void GL_MBind(int target, texid_t texnum) +{ + GL_SelectTexture(target); + + if (shaderstate.currenttextures[shaderstate.currenttmu] == texnum.num) + return; + + shaderstate.currenttextures[shaderstate.currenttmu] = texnum.num; + bindTexFunc (GL_TEXTURE_2D, texnum.num); +} + +void GL_Bind(texid_t texnum) +{ + if (shaderstate.currenttextures[shaderstate.currenttmu] == texnum.num) + return; + + shaderstate.currenttextures[shaderstate.currenttmu] = texnum.num; + + bindTexFunc (GL_TEXTURE_2D, texnum.num); +} + +void GL_BindType(int type, texid_t texnum) +{ + if (shaderstate.currenttextures[shaderstate.currenttmu] == texnum.num) + return; + + shaderstate.currenttextures[shaderstate.currenttmu] = texnum.num; + bindTexFunc (type, texnum.num); +} + +void GL_CullFace(unsigned int sflags) +{ + if (shaderstate.curcull == sflags) + return; + shaderstate.curcull = sflags; + + if (shaderstate.curcull & SHADER_CULL_FRONT) + { + qglEnable(GL_CULL_FACE); + qglCullFace(GL_FRONT); + } + else if (shaderstate.curcull & SHADER_CULL_BACK) + { + qglEnable(GL_CULL_FACE); + qglCullFace(GL_BACK); + } + else + { + qglDisable(GL_CULL_FACE); + } +} + +void R_FetchTopColour(int *retred, int *retgreen, int *retblue) +{ + int i; + + if (currententity->scoreboard) + { + i = currententity->scoreboard->ttopcolor; + } + else + i = TOP_RANGE>>4; + if (i > 8) + { + i<<=4; + } + else + { + i<<=4; + i+=15; + } + i*=3; + *retred = host_basepal[i+0]; + *retgreen = host_basepal[i+1]; + *retblue = host_basepal[i+2]; +/* if (!gammaworks) + { + *retred = gammatable[*retred]; + *retgreen = gammatable[*retgreen]; + *retblue = gammatable[*retblue]; + }*/ +} +void R_FetchBottomColour(int *retred, int *retgreen, int *retblue) +{ + int i; + + if (currententity->scoreboard) + { + i = currententity->scoreboard->tbottomcolor; + } + else + i = BOTTOM_RANGE>>4; + if (i > 8) + { + i<<=4; + } + else + { + i<<=4; + i+=15; + } + i*=3; + *retred = host_basepal[i+0]; + *retgreen = host_basepal[i+1]; + *retblue = host_basepal[i+2]; +/* if (!gammaworks) + { + *retred = gammatable[*retred]; + *retgreen = gammatable[*retgreen]; + *retblue = gammatable[*retblue]; + }*/ +} + +static void RevertToKnownState(void) +{ + shaderstate.curvertexvbo = ~0; + GL_SelectVBO(0); + GL_SelectEBO(0); + + checkerror(); + while(shaderstate.lastpasstmus>0) + { + GL_SelectTexture(--shaderstate.lastpasstmus); + qglDisable(GL_TEXTURE_2D); + qglDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + GL_SelectTexture(0); + + qglEnableClientState(GL_VERTEX_ARRAY); + checkerror(); + + qglColor3f(1,1,1); + qglDepthFunc(GL_LEQUAL); + qglDepthMask(GL_TRUE); + shaderstate.shaderbits &= ~(SBITS_MISC_DEPTHEQUALONLY|SBITS_MISC_DEPTHCLOSERONLY); + shaderstate.shaderbits |= SBITS_MISC_DEPTHWRITE; + + qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); +} + +void PPL_RevertToKnownState(void) +{ + RevertToKnownState(); +} + +void R_IBrokeTheArrays(void) +{ + RevertToKnownState(); +} + +void R_UnlockArrays(void) +{ +} +void R_ClearArrays(void) +{ +} +void GL_FlushBackEnd(void) +{ + memset(&shaderstate, 0, sizeof(shaderstate)); + shaderstate.curcull = ~0; +} +void R_BackendInit(void) +{ +} +qboolean R_MeshWillExceed(mesh_t *mesh) +{ + return false; +} + +//called from gl_shadow +void BE_SetupForShadowMap(void) +{ + while(shaderstate.lastpasstmus>0) + { + GL_SelectTexture(--shaderstate.lastpasstmus); + qglDisable(GL_TEXTURE_2D); + qglDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + + qglDisableClientState(GL_TEXTURE_COORD_ARRAY); + qglShadeModel(GL_FLAT); + GL_TexEnv(GL_REPLACE); + qglDepthMask(GL_TRUE); + shaderstate.shaderbits |= SBITS_MISC_DEPTHWRITE; +// qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); +} + +static texid_t T_Gen_CurrentRender(void) +{ + int vwidth, vheight; + if (gl_config.arb_texture_non_power_of_two) + { + vwidth = vid.pixelwidth; + vheight = vid.pixelheight; + } + else + { + vwidth = 1; + vheight = 1; + while (vwidth < vid.pixelwidth) + { + vwidth *= 2; + } + while (vheight < vid.pixelheight) + { + vheight *= 2; + } + } + // copy the scene to texture + if (!TEXVALID(shaderstate.temptexture)) + shaderstate.temptexture = GL_AllocNewTexture(); + GL_Bind(shaderstate.temptexture); + qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, vwidth, vheight, 0); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + return shaderstate.temptexture; +} + +static texid_t Shader_TextureForPass(const shaderpass_t *pass) +{ + switch(pass->texgen) + { + default: + case T_GEN_SINGLEMAP: + return pass->anim_frames[0]; + case T_GEN_ANIMMAP: + return pass->anim_frames[(int)(pass->anim_fps * shaderstate.curtime) % pass->anim_numframes]; + case T_GEN_LIGHTMAP: + return shaderstate.curlightmap; + case T_GEN_DELUXMAP: + return shaderstate.curdeluxmap; + case T_GEN_DIFFUSE: + return shaderstate.curtexnums?shaderstate.curtexnums->base:r_nulltex; + case T_GEN_NORMALMAP: + return shaderstate.curtexnums?shaderstate.curtexnums->bump:r_nulltex; + case T_GEN_SPECULAR: + return shaderstate.curtexnums->specular; + case T_GEN_UPPEROVERLAY: + return shaderstate.curtexnums->upperoverlay; + case T_GEN_LOWEROVERLAY: + return shaderstate.curtexnums->loweroverlay; + case T_GEN_FULLBRIGHT: + return shaderstate.curtexnums->fullbright; + case T_GEN_SHADOWMAP: + return shaderstate.curshadowmap; + + case T_GEN_VIDEOMAP: +#ifdef NOMEDIA + return shaderstate.curtexnums?shaderstate.curtexnums->base:0; +#else + return Media_UpdateForShader(pass->cin); +#endif + + case T_GEN_CURRENTRENDER: + return T_Gen_CurrentRender(); + } +} + +/*========================================== matrix functions =====================================*/ + +typedef vec3_t mat3_t[3]; +static mat3_t axisDefault={{1, 0, 0}, + {0, 1, 0}, + {0, 0, 1}}; + +static void Matrix3_Transpose (mat3_t in, mat3_t out) +{ + out[0][0] = in[0][0]; + out[1][1] = in[1][1]; + out[2][2] = in[2][2]; + + out[0][1] = in[1][0]; + out[0][2] = in[2][0]; + out[1][0] = in[0][1]; + out[1][2] = in[2][1]; + out[2][0] = in[0][2]; + out[2][1] = in[1][2]; +} +static void Matrix3_Multiply_Vec3 (mat3_t a, vec3_t b, vec3_t product) +{ + product[0] = a[0][0]*b[0] + a[0][1]*b[1] + a[0][2]*b[2]; + product[1] = a[1][0]*b[0] + a[1][1]*b[1] + a[1][2]*b[2]; + product[2] = a[2][0]*b[0] + a[2][1]*b[1] + a[2][2]*b[2]; +} + +static int Matrix3_Compare(mat3_t in, mat3_t out) +{ + return memcmp(in, out, sizeof(mat3_t)); +} + +//end matrix functions +/*========================================== tables for deforms =====================================*/ +#define frand() (rand()*(1.0/RAND_MAX)) +#define FTABLE_SIZE 1024 +#define FTABLE_CLAMP(x) (((int)((x)*FTABLE_SIZE) & (FTABLE_SIZE-1))) +#define FTABLE_EVALUATE(table,x) (table ? table[FTABLE_CLAMP(x)] : frand()*((x)-floor(x))) + +static float r_sintable[FTABLE_SIZE]; +static float r_triangletable[FTABLE_SIZE]; +static float r_squaretable[FTABLE_SIZE]; +static float r_sawtoothtable[FTABLE_SIZE]; +static float r_inversesawtoothtable[FTABLE_SIZE]; + +static float *FTableForFunc ( unsigned int func ) +{ + switch (func) + { + case SHADER_FUNC_SIN: + return r_sintable; + + case SHADER_FUNC_TRIANGLE: + return r_triangletable; + + case SHADER_FUNC_SQUARE: + return r_squaretable; + + case SHADER_FUNC_SAWTOOTH: + return r_sawtoothtable; + + case SHADER_FUNC_INVERSESAWTOOTH: + return r_inversesawtoothtable; + } + + //bad values allow us to crash (so I can debug em) + return NULL; +} + +void Shader_LightPass_Std(char *shortname, shader_t *s, const void *args) +{ + char shadertext[8192*2]; + sprintf(shadertext, LIGHTPASS_SHADER, args, LIGHTPASS_GLSL_SHARED LIGHTPASS_GLSL_VERTEX LIGHTPASS_GLSL_FRAGMENT); + Shader_DefaultScript(shortname, s, shadertext); +} +void Shader_LightPass_PCF(char *shortname, shader_t *s, const void *args) +{ + char shadertext[8192*2]; + sprintf(shadertext, PCFPASS_SHADER, args, LIGHTPASS_GLSL_SHARED LIGHTPASS_GLSL_VERTEX LIGHTPASS_GLSL_FRAGMENT); + Shader_DefaultScript(shortname, s, shadertext); +} + +void BE_Init(void) +{ + int i; + double t; + + be_maxpasses = gl_mtexarbable; + + for (i = 0; i < FTABLE_SIZE; i++) + { + t = (double)i / (double)FTABLE_SIZE; + + r_sintable[i] = sin(t * 2*M_PI); + + if (t < 0.25) + r_triangletable[i] = t * 4.0; + else if (t < 0.75) + r_triangletable[i] = 2 - 4.0 * t; + else + r_triangletable[i] = (t - 0.75) * 4.0 - 1.0; + + if (t < 0.5) + r_squaretable[i] = 1.0f; + else + r_squaretable[i] = -1.0f; + + r_sawtoothtable[i] = t; + r_inversesawtoothtable[i] = 1.0 - t; + } + + shaderstate.identitylighting = 1; + + /*normally we load these lazily, but if they're probably going to be used anyway, load them now to avoid stalls.*/ + if (r_shadow_realtime_dlight.ival && !shaderstate.initedlightpasses) + { + int i; + shaderstate.initedlightpasses = true; + for (i = 0; i < PERMUTATIONS; i++) + { + shaderstate.lightpassshader[i] = R_RegisterCustom(lightpassname[i], Shader_LightPass_Std, permutationdefines[i]); + } + } + + qglEnableClientState(GL_VERTEX_ARRAY); +} + +//end tables + +#define MAX_ARRAY_VERTS 65535 +static avec4_t coloursarray[MAX_ARRAY_VERTS]; +static float texcoordarray[SHADER_PASS_MAX][MAX_ARRAY_VERTS*2]; +static vecV_t vertexarray[MAX_ARRAY_VERTS]; + +/*========================================== texture coord generation =====================================*/ + +static void tcgen_environment(float *st, unsigned int numverts, float *xyz, float *normal) +{ + int i; + vec3_t viewer, reflected; + float d; + + vec3_t rorg; + + + RotateLightVector(shaderstate.curentity->axis, shaderstate.curentity->origin, r_origin, rorg); + + for (i = 0 ; i < numverts ; i++, xyz += 3, normal += 3, st += 2 ) + { + VectorSubtract (rorg, xyz, viewer); + VectorNormalizeFast (viewer); + + d = DotProduct (normal, viewer); + + reflected[0] = normal[0]*2*d - viewer[0]; + reflected[1] = normal[1]*2*d - viewer[1]; + reflected[2] = normal[2]*2*d - viewer[2]; + + st[0] = 0.5 + reflected[1] * 0.5; + st[1] = 0.5 - reflected[2] * 0.5; + } +} + +static float *tcgen(const shaderpass_t *pass, int cnt, float *dst, const mesh_t *mesh) +{ + int i; + vecV_t *src; + switch (pass->tcgen) + { + default: + case TC_GEN_BASE: + return (float*)mesh->st_array; + case TC_GEN_LIGHTMAP: + return (float*)mesh->lmst_array; + case TC_GEN_NORMAL: + return (float*)mesh->normals_array; + case TC_GEN_SVECTOR: + return (float*)mesh->snormals_array; + case TC_GEN_TVECTOR: + return (float*)mesh->tnormals_array; + case TC_GEN_ENVIRONMENT: + tcgen_environment(dst, cnt, (float*)mesh->xyz_array, (float*)mesh->normals_array); + return dst; + +// case TC_GEN_DOTPRODUCT: +// return mesh->st_array[0]; + case TC_GEN_VECTOR: + src = mesh->xyz_array; + for (i = 0; i < cnt; i++, dst += 2) + { + static vec3_t tc_gen_s = { 1.0f, 0.0f, 0.0f }; + static vec3_t tc_gen_t = { 0.0f, 1.0f, 0.0f }; + + dst[0] = DotProduct(tc_gen_s, src[i]); + dst[1] = DotProduct(tc_gen_t, src[i]); + } + return dst; + } +} + +/*src and dst can be the same address when tcmods are chained*/ +static void tcmod(const tcmod_t *tcmod, int cnt, const float *src, float *dst, const mesh_t *mesh) +{ + float *table; + float t1, t2; + float cost, sint; + int j; +#define R_FastSin(x) sin((x)*(2*M_PI)) + switch (tcmod->type) + { + case SHADER_TCMOD_ROTATE: + cost = tcmod->args[0] * shaderstate.curtime; + sint = R_FastSin(cost); + cost = R_FastSin(cost + 0.25); + + for (j = 0; j < cnt; j++, dst+=2,src+=2) + { + t1 = cost * (src[0] - 0.5f) - sint * (src[1] - 0.5f) + 0.5f; + t2 = cost * (src[1] - 0.5f) + sint * (src[0] - 0.5f) + 0.5f; + dst[0] = t1; + dst[1] = t2; + } + break; + + case SHADER_TCMOD_SCALE: + t1 = tcmod->args[0]; + t2 = tcmod->args[1]; + + for (j = 0; j < cnt; j++, dst+=2,src+=2) + { + dst[0] = src[0] * t1; + dst[1] = src[1] * t2; + } + break; + + case SHADER_TCMOD_TURB: + t1 = tcmod->args[2] + shaderstate.curtime * tcmod->args[3]; + t2 = tcmod->args[1]; + + for (j = 0; j < cnt; j++, dst+=2,src+=2) + { + dst[0] = src[0] + R_FastSin (src[0]*t2+t1) * t2; + dst[1] = src[1] + R_FastSin (src[1]*t2+t1) * t2; + } + break; + + case SHADER_TCMOD_STRETCH: + table = FTableForFunc(tcmod->args[0]); + t2 = tcmod->args[3] + shaderstate.curtime * tcmod->args[4]; + t1 = FTABLE_EVALUATE(table, t2) * tcmod->args[2] + tcmod->args[1]; + t1 = t1 ? 1.0f / t1 : 1.0f; + t2 = 0.5f - 0.5f * t1; + for (j = 0; j < cnt; j++, dst+=2,src+=2) + { + dst[0] = src[0] * t1 + t2; + dst[1] = src[1] * t1 + t2; + } + break; + + case SHADER_TCMOD_SCROLL: + t1 = tcmod->args[0] * shaderstate.curtime; + t2 = tcmod->args[1] * shaderstate.curtime; + + for (j = 0; j < cnt; j++, dst += 2, src+=2) + { + dst[0] = src[0] + t1; + dst[1] = src[1] + t2; + } + break; + + case SHADER_TCMOD_TRANSFORM: + for (j = 0; j < cnt; j++, dst+=2, src+=2) + { + 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]; + } + break; + + default: + break; + } +} + +static void GenerateTCMods(const shaderpass_t *pass, int passnum, const mesh_t *meshlist) +{ +#if 1 + for (; meshlist; meshlist = meshlist->next) + { + int i; + float *src; + src = tcgen(pass, meshlist->numvertexes, texcoordarray[passnum]+meshlist->vbofirstvert*2, meshlist); + //tcgen might return unmodified info + if (pass->numtcmods) + { + tcmod(&pass->tcmods[0], meshlist->numvertexes, src, texcoordarray[passnum]+meshlist->vbofirstvert*2, meshlist); + for (i = 1; i < pass->numtcmods; i++) + { + tcmod(&pass->tcmods[i], meshlist->numvertexes, texcoordarray[passnum]+meshlist->vbofirstvert*2, texcoordarray[passnum]+meshlist->vbofirstvert*2, meshlist); + } + src = texcoordarray[passnum]+meshlist->vbofirstvert*2; + } + else if (src != texcoordarray[passnum]+meshlist->vbofirstvert*2) + { + //this shouldn't actually ever be true + memcpy(texcoordarray[passnum]+meshlist->vbofirstvert*2, src, 8*meshlist->numvertexes); + } + } + GL_SelectVBO(0); + qglTexCoordPointer(2, GL_FLOAT, 0, texcoordarray[passnum]); +#else + if (!shaderstate.vbo_texcoords[passnum]) + { + qglGenBuffersARB(1, &shaderstate.vbo_texcoords[passnum]); + } + GL_SelectVBO(shaderstate.vbo_texcoords[passnum]); + + { + qglBufferDataARB(GL_ARRAY_BUFFER_ARB, MAX_ARRAY_VERTS*sizeof(float)*2, NULL, GL_STREAM_DRAW_ARB); + for (; meshlist; meshlist = meshlist->next) + { + int i; + float *src; + src = tcgen(pass, meshlist->numvertexes, texcoordarray[passnum], meshlist); + //tcgen might return unmodified info + if (pass->numtcmods) + { + tcmod(&pass->tcmods[0], meshlist->numvertexes, src, texcoordarray[passnum], meshlist); + for (i = 1; i < pass->numtcmods; i++) + { + tcmod(&pass->tcmods[i], meshlist->numvertexes, texcoordarray[passnum], texcoordarray[passnum], meshlist); + } + src = texcoordarray[passnum]; + } + qglBufferSubDataARB(GL_ARRAY_BUFFER_ARB, meshlist->vbofirstvert*8, meshlist->numvertexes*8, src); + } + } + qglTexCoordPointer(2, GL_FLOAT, 0, NULL); +#endif +} + +//end texture coords +/*========================================== colour generation =====================================*/ + +//source is always packed +//dest is packed too +static void colourgen(const shaderpass_t *pass, int cnt, const avec4_t *src, avec4_t *dst, const mesh_t *mesh) +{ + switch (pass->rgbgen) + { + case RGB_GEN_ENTITY: + while((cnt)--) + { + dst[cnt][0] = shaderstate.curentity->shaderRGBAf[0]; + dst[cnt][1] = shaderstate.curentity->shaderRGBAf[1]; + dst[cnt][2] = shaderstate.curentity->shaderRGBAf[2]; + } + break; + case RGB_GEN_ONE_MINUS_ENTITY: + while((cnt)--) + { + dst[cnt][0] = 1-shaderstate.curentity->shaderRGBAf[0]; + dst[cnt][1] = 1-shaderstate.curentity->shaderRGBAf[1]; + dst[cnt][2] = 1-shaderstate.curentity->shaderRGBAf[2]; + } + break; + case RGB_GEN_VERTEX: + case RGB_GEN_EXACT_VERTEX: + if (!src) + { + while((cnt)--) + { + dst[cnt][0] = shaderstate.identitylighting; + dst[cnt][1] = shaderstate.identitylighting; + dst[cnt][2] = shaderstate.identitylighting; + } + break; + } + + while((cnt)--) + { + dst[cnt][0] = src[cnt][0]; + dst[cnt][1] = src[cnt][1]; + dst[cnt][2] = src[cnt][2]; + } + break; + case RGB_GEN_ONE_MINUS_VERTEX: + while((cnt)--) + { + dst[cnt][0] = 1-src[cnt][0]; + dst[cnt][1] = 1-src[cnt][1]; + dst[cnt][2] = 1-src[cnt][2]; + } + break; + case RGB_GEN_IDENTITY_LIGHTING: + //compensate for overbrights + while((cnt)--) + { + dst[cnt][0] = shaderstate.identitylighting; + dst[cnt][1] = shaderstate.identitylighting; + dst[cnt][2] = shaderstate.identitylighting; + } + break; + default: + case RGB_GEN_IDENTITY: + while((cnt)--) + { + dst[cnt][0] = 1; + dst[cnt][1] = 1; + dst[cnt][2] = 1; + } + break; + case RGB_GEN_CONST: + while((cnt)--) + { + dst[cnt][0] = pass->rgbgen_func.args[0]; + dst[cnt][1] = pass->rgbgen_func.args[1]; + dst[cnt][2] = pass->rgbgen_func.args[2]; + } + break; + case RGB_GEN_LIGHTING_DIFFUSE: + //collect lighting details for mobile entities + if (!mesh->normals_array) + { + while((cnt)--) + { + dst[cnt][0] = 1; + dst[cnt][1] = 1; + dst[cnt][2] = 1; + } + } + else + { + R_LightArrays(mesh->xyz_array, dst, cnt, mesh->normals_array); + } + break; + case RGB_GEN_WAVE: + { + float *table; + float c; + + table = FTableForFunc(pass->rgbgen_func.type); + c = pass->rgbgen_func.args[2] + shaderstate.curtime * pass->rgbgen_func.args[3]; + c = FTABLE_EVALUATE(table, c) * pass->rgbgen_func.args[1] + pass->rgbgen_func.args[0]; + c = bound(0.0f, c, 1.0f); + + while((cnt)--) + { + dst[cnt][0] = c; + dst[cnt][1] = c; + dst[cnt][2] = c; + } + } + break; + + case RGB_GEN_TOPCOLOR: + case RGB_GEN_BOTTOMCOLOR: +#pragma message("fix 24bit player colours") + while((cnt)--) + { + dst[cnt][0] = 1; + dst[cnt][1] = 1; + dst[cnt][2] = 1; + } + // Con_Printf("RGB_GEN %i not supported\n", pass->rgbgen); + break; + } +} + +static void deformgen(const deformv_t *deformv, int cnt, const avec4_t *src, avec4_t *dst, const mesh_t *mesh) +{ + float *table; + int j, k; + float args[4]; + float deflect; + switch (deformv->type) + { + default: + case DEFORMV_NONE: + if (src != dst) + memcpy(dst, src, sizeof(*src)*cnt); + break; + + case DEFORMV_WAVE: + if (!mesh->normals_array) + { + if (src != dst) + memcpy(dst, src, sizeof(*src)*cnt); + return; + } + args[0] = deformv->func.args[0]; + args[1] = deformv->func.args[1]; + args[3] = deformv->func.args[2] + deformv->func.args[3] * shaderstate.curtime; + table = FTableForFunc(deformv->func.type); + + for ( j = 0; j < cnt; j++ ) + { + deflect = deformv->args[0] * (src[j][0]+src[j][1]+src[j][2]) + args[3]; + deflect = FTABLE_EVALUATE(table, deflect) * args[1] + args[0]; + + // Deflect vertex along its normal by wave amount + VectorMA(src[j], deflect, mesh->normals_array[j], dst[j]); + } + break; + + case DEFORMV_NORMAL: + //normal does not actually move the verts, but it does change the normals array + //we don't currently support that. + if (src != dst) + memcpy(dst, src, sizeof(*src)*cnt); +/* + args[0] = deformv->args[1] * shaderstate.curtime; + + for ( j = 0; j < cnt; j++ ) + { + args[1] = normalsArray[j][2] * args[0]; + + deflect = deformv->args[0] * R_FastSin(args[1]); + normalsArray[j][0] *= deflect; + deflect = deformv->args[0] * R_FastSin(args[1] + 0.25); + normalsArray[j][1] *= deflect; + VectorNormalizeFast(normalsArray[j]); + } +*/ break; + + case DEFORMV_MOVE: + table = FTableForFunc(deformv->func.type); + deflect = deformv->func.args[2] + shaderstate.curtime * deformv->func.args[3]; + deflect = FTABLE_EVALUATE(table, deflect) * deformv->func.args[1] + deformv->func.args[0]; + + for ( j = 0; j < cnt; j++ ) + VectorMA(src[j], deflect, deformv->args, dst[j]); + break; + + case DEFORMV_BULGE: + args[0] = deformv->args[0]/(2*M_PI); + args[1] = deformv->args[1]; + args[2] = shaderstate.curtime * deformv->args[2]/(2*M_PI); + + for (j = 0; j < cnt; j++) + { + deflect = R_FastSin(mesh->st_array[j][0]*args[0] + args[2])*args[1]; + dst[j][0] = src[j][0]+deflect*mesh->normals_array[j][0]; + dst[j][1] = src[j][1]+deflect*mesh->normals_array[j][1]; + dst[j][2] = src[j][2]+deflect*mesh->normals_array[j][2]; + } + break; + + case DEFORMV_AUTOSPRITE: + if (mesh->numindexes < 6) + break; + + for (j = 0; j < cnt-3; j+=4, src+=4, dst+=4) + { + vec3_t mid, d; + float radius; + mid[0] = 0.25*(src[0][0] + src[1][0] + src[2][0] + src[3][0]); + mid[1] = 0.25*(src[0][1] + src[1][1] + src[2][1] + src[3][1]); + mid[2] = 0.25*(src[0][2] + src[1][2] + src[2][2] + src[3][2]); + VectorSubtract(src[0], mid, d); + radius = 2*VectorLength(d); + + for (k = 0; k < 4; k++) + { + dst[k][0] = mid[0] + radius*((mesh->st_array[k][0]-0.5)*r_view_matrix[0+0]+(mesh->st_array[k][1]-0.5)*r_view_matrix[0+1]); + dst[k][1] = mid[1] + radius*((mesh->st_array[k][0]-0.5)*r_view_matrix[4+0]+(mesh->st_array[k][1]-0.5)*r_view_matrix[4+1]); + dst[k][2] = mid[2] + radius*((mesh->st_array[k][0]-0.5)*r_view_matrix[8+0]+(mesh->st_array[k][1]-0.5)*r_view_matrix[8+1]); + } + } + break; + + case DEFORMV_AUTOSPRITE2: + if (mesh->numindexes < 6) + break; + + for (k = 0; k < mesh->numindexes; k += 6) + { + int long_axis, short_axis; + vec3_t axis; + float len[3]; + mat3_t m0, m1, m2, result; + float *quad[4]; + vec3_t rot_centre, tv; + + quad[0] = (float *)(dst + mesh->indexes[k+0]); + quad[1] = (float *)(dst + mesh->indexes[k+1]); + quad[2] = (float *)(dst + mesh->indexes[k+2]); + + for (j = 2; j >= 0; j--) + { + quad[3] = (float *)(dst + mesh->indexes[k+3+j]); + if (!VectorEquals (quad[3], quad[0]) && + !VectorEquals (quad[3], quad[1]) && + !VectorEquals (quad[3], quad[2])) + { + break; + } + } + + // build a matrix were the longest axis of the billboard is the Y-Axis + VectorSubtract(quad[1], quad[0], m0[0]); + VectorSubtract(quad[2], quad[0], m0[1]); + VectorSubtract(quad[2], quad[1], m0[2]); + len[0] = DotProduct(m0[0], m0[0]); + len[1] = DotProduct(m0[1], m0[1]); + len[2] = DotProduct(m0[2], m0[2]); + + if ((len[2] > len[1]) && (len[2] > len[0])) + { + if (len[1] > len[0]) + { + long_axis = 1; + short_axis = 0; + } + else + { + long_axis = 0; + short_axis = 1; + } + } + else if ((len[1] > len[2]) && (len[1] > len[0])) + { + if (len[2] > len[0]) + { + long_axis = 2; + short_axis = 0; + } + else + { + long_axis = 0; + short_axis = 2; + } + } + else //if ( (len[0] > len[1]) && (len[0] > len[2]) ) + { + if (len[2] > len[1]) + { + long_axis = 2; + short_axis = 1; + } + else + { + long_axis = 1; + short_axis = 2; + } + } + + if (DotProduct(m0[long_axis], m0[short_axis])) + { + VectorNormalize2(m0[long_axis], axis); + VectorCopy(axis, m0[1]); + + if (axis[0] || axis[1]) + { + VectorVectors(m0[1], m0[2], m0[0]); + } + else + { + VectorVectors(m0[1], m0[0], m0[2]); + } + } + else + { + VectorNormalize2(m0[long_axis], axis); + VectorNormalize2(m0[short_axis], m0[0]); + VectorCopy(axis, m0[1]); + CrossProduct(m0[0], m0[1], m0[2]); + } + + for (j = 0; j < 3; j++) + rot_centre[j] = (quad[0][j] + quad[1][j] + quad[2][j] + quad[3][j]) * 0.25; + + if (shaderstate.curentity) + { + VectorAdd(shaderstate.curentity->origin, rot_centre, tv); + } + else + { + VectorCopy(rot_centre, tv); + } + VectorSubtract(r_origin, tv, tv); + + // filter any longest-axis-parts off the camera-direction + deflect = -DotProduct(tv, axis); + + VectorMA(tv, deflect, axis, m1[2]); + VectorNormalizeFast(m1[2]); + VectorCopy(axis, m1[1]); + CrossProduct(m1[1], m1[2], m1[0]); + + Matrix3_Transpose(m1, m2); + Matrix3_Multiply(m2, m0, result); + + for (j = 0; j < 4; j++) + { + VectorSubtract(quad[j], rot_centre, tv); + Matrix3_Multiply_Vec3(result, tv, quad[j]); + VectorAdd(rot_centre, quad[j], quad[j]); + } + } + break; + +// case DEFORMV_PROJECTION_SHADOW: +// break; + } +} + +static void GenerateVertexDeforms(const shader_t *shader, const mesh_t *meshlist) +{ + int i; + for (; meshlist; meshlist = meshlist->next) + { + deformgen(&shader->deforms[0], meshlist->numvertexes, meshlist->xyz_array, vertexarray+meshlist->vbofirstvert, meshlist); + for (i = 1; i < shader->numdeforms; i++) + { + deformgen(&shader->deforms[i], meshlist->numvertexes, vertexarray+meshlist->vbofirstvert, vertexarray+meshlist->vbofirstvert, meshlist); + } + } + + shaderstate.pendingvertexpointer = vertexarray; + shaderstate.pendingvertexvbo = 0; +} + +/*======================================alpha ===============================*/ + +static void alphagen(const shaderpass_t *pass, int cnt, const avec4_t *src, avec4_t *dst, const mesh_t *mesh) +{ + float *table; + float t; + float f; + vec3_t v1, v2; + int i; + + switch (pass->alphagen) + { + default: + case ALPHA_GEN_IDENTITY: + while(cnt--) + dst[cnt][3] = 1; + break; + + case ALPHA_GEN_CONST: + t = pass->alphagen_func.args[0]; + while(cnt--) + dst[cnt][3] = t; + break; + + case ALPHA_GEN_WAVE: + table = FTableForFunc(pass->alphagen_func.type); + f = pass->alphagen_func.args[2] + shaderstate.curtime * pass->alphagen_func.args[3]; + f = FTABLE_EVALUATE(table, f) * pass->alphagen_func.args[1] + pass->alphagen_func.args[0]; + t = bound(0.0f, f, 1.0f); + while(cnt--) + dst[cnt][3] = t; + break; + + case ALPHA_GEN_PORTAL: + //FIXME: should this be per-vert? + VectorAdd(mesh->xyz_array[0], shaderstate.curentity->origin, v1); + VectorSubtract(r_origin, v1, v2); + f = VectorLength(v2) * (1.0 / 255.0); + f = bound(0.0f, f, 1.0f); + + while(cnt--) + dst[cnt][3] = f; + break; + + case ALPHA_GEN_VERTEX: + if (!src) + { + while(cnt--) + { + dst[cnt][3] = 1; + } + break; + } + + while(cnt--) + { + dst[cnt][3] = src[cnt][3]; + } + break; + + case ALPHA_GEN_ENTITY: + f = bound(0, shaderstate.curentity->shaderRGBAf[3], 1); + while(cnt--) + { + dst[cnt][3] = f; + } + break; + + + case ALPHA_GEN_SPECULAR: + { + mat3_t axis; + AngleVectors(shaderstate.curentity->angles, axis[0], axis[1], axis[2]); + VectorSubtract(r_origin, shaderstate.curentity->origin, v1); + + if (!Matrix3_Compare(axis, axisDefault)) + { + Matrix3_Multiply_Vec3(axis, v2, v2); + } + else + { + VectorCopy(v1, v2); + } + + for (i = 0; i < cnt; i++) + { + VectorSubtract(v2, mesh->xyz_array[i], v1); + f = DotProduct(v1, mesh->normals_array[i] ) * Q_rsqrt(DotProduct(v1,v1)); + f = f * f * f * f * f; + dst[i][3] = bound (0.0f, f, 1.0f); + } + } + break; + } +} + +#define DVBOMETHOD 1 + +static void GenerateColourMods(const shaderpass_t *pass, const mesh_t *meshlist) +{ + if (meshlist->colors4b_array) + { + //hack... + GL_SelectVBO(0); + qglColorPointer(4, GL_UNSIGNED_BYTE, 0, meshlist->colors4b_array); + qglEnableClientState(GL_COLOR_ARRAY); + qglShadeModel(GL_FLAT); + return; + } + if (pass->flags & SHADER_PASS_NOCOLORARRAY) + { + avec4_t scol; + + colourgen(pass, 1, meshlist->colors4f_array, &scol, meshlist); + alphagen(pass, 1, meshlist->colors4f_array, &scol, meshlist); + qglDisableClientState(GL_COLOR_ARRAY); + qglColor4fv(scol); + qglShadeModel(GL_FLAT); + checkerror(); + } + else + { + extern cvar_t r_nolightdir; + if (pass->rgbgen == RGB_GEN_LIGHTING_DIFFUSE && r_nolightdir.ival) + { + extern avec3_t ambientlight, shadelight; + qglDisableClientState(GL_COLOR_ARRAY); + qglColor4f( ambientlight[0]*0.5+shadelight[0], + ambientlight[1]*0.5+shadelight[1], + ambientlight[2]*0.5+shadelight[2], + shaderstate.curentity->shaderRGBAf[3]); + qglShadeModel(GL_FLAT); + checkerror(); + return; + } + + qglShadeModel(GL_SMOOTH); + + //if its vetex lighting, just use the vbo + if ((pass->rgbgen == RGB_GEN_VERTEX || pass->rgbgen == RGB_GEN_EXACT_VERTEX) && pass->alphagen == ALPHA_GEN_VERTEX) + { + GL_SelectVBO(shaderstate.sourcevbo->vbocolours); + qglColorPointer(4, GL_FLOAT, 0, shaderstate.sourcevbo->colours4f); + qglEnableClientState(GL_COLOR_ARRAY); + return; + } + + for (; meshlist; meshlist = meshlist->next) + { + colourgen(pass, meshlist->numvertexes, meshlist->colors4f_array, coloursarray + meshlist->vbofirstvert, meshlist); + alphagen(pass, meshlist->numvertexes, meshlist->colors4f_array, coloursarray + meshlist->vbofirstvert, meshlist); + } + GL_SelectVBO(0); + qglColorPointer(4, GL_FLOAT, 0, coloursarray); + qglEnableClientState(GL_COLOR_ARRAY); + } +} + +static void BE_GeneratePassTC(const shaderpass_t *pass, int passno, const mesh_t *meshlist) +{ + pass += passno; + if (!pass->numtcmods) + { + //if there are no tcmods, pass through here as fast as possible + if (pass->tcgen == TC_GEN_BASE) + { + GL_SelectVBO(shaderstate.sourcevbo->vbotexcoord); + qglTexCoordPointer(2, GL_FLOAT, 0, shaderstate.sourcevbo->texcoord); + } + else if (pass->tcgen == TC_GEN_LIGHTMAP) + { + GL_SelectVBO(shaderstate.sourcevbo->vbolmcoord); + qglTexCoordPointer(2, GL_FLOAT, 0, shaderstate.sourcevbo->lmcoord); + } + else if (pass->tcgen == TC_GEN_NORMAL) + { + GL_SelectVBO(shaderstate.sourcevbo->vbonormals); + qglTexCoordPointer(3, GL_FLOAT, 0, shaderstate.sourcevbo->normals); + } + else if (pass->tcgen == TC_GEN_SVECTOR) + { + GL_SelectVBO(shaderstate.sourcevbo->vbosvector); + qglTexCoordPointer(3, GL_FLOAT, 0, shaderstate.sourcevbo->svector); + } + else if (pass->tcgen == TC_GEN_TVECTOR) + { + GL_SelectVBO(shaderstate.sourcevbo->vbotvector); + qglTexCoordPointer(3, GL_FLOAT, 0, shaderstate.sourcevbo->tvector); + } + else + { + //specular highlights and reflections have no fixed data, and must be generated. + GenerateTCMods(pass, passno, meshlist); + } + } + else + { + GenerateTCMods(pass, passno, meshlist); + } +} + +static void BE_SendPassBlendAndDepth(unsigned int sbits) +{ + unsigned int delta; + + /*2d mode doesn't depth test or depth write*/ +#pragma message("fixme: q3 doesn't seem to have this, why do we need it?") + if (shaderstate.force2d) + { + sbits &= ~(SBITS_MISC_DEPTHWRITE|SBITS_MISC_DEPTHEQUALONLY); + sbits |= SBITS_MISC_NODEPTHTEST; + } + + delta = sbits^shaderstate.shaderbits; + +#pragma message("Hack to work around the fact that other bits of code change this state") + delta |= SBITS_MISC_NODEPTHTEST|SBITS_MISC_DEPTHEQUALONLY; + if (!delta) + return; + shaderstate.shaderbits = sbits; + + if (delta & SBITS_BLEND_BITS) + { + if (sbits & SBITS_BLEND_BITS) + { + int src, dst; + /*unpack the src and dst factors*/ + switch(sbits & SBITS_SRCBLEND_BITS) + { + case SBITS_SRCBLEND_ZERO: src = GL_ZERO; break; + case SBITS_SRCBLEND_ONE: src = GL_ONE; break; + case SBITS_SRCBLEND_DST_COLOR: src = GL_DST_COLOR; break; + case SBITS_SRCBLEND_ONE_MINUS_DST_COLOR: src = GL_ONE_MINUS_DST_COLOR; break; + case SBITS_SRCBLEND_SRC_ALPHA: src = GL_SRC_ALPHA; break; + case SBITS_SRCBLEND_ONE_MINUS_SRC_ALPHA: src = GL_ONE_MINUS_SRC_ALPHA; break; + case SBITS_SRCBLEND_DST_ALPHA: src = GL_DST_ALPHA; break; + case SBITS_SRCBLEND_ONE_MINUS_DST_ALPHA: src = GL_ONE_MINUS_DST_ALPHA; break; + case SBITS_SRCBLEND_ALPHA_SATURATE: src = GL_SRC_ALPHA_SATURATE; break; + default: Sys_Error("Invalid shaderbits\n"); + } + switch(sbits & SBITS_DSTBLEND_BITS) + { + case SBITS_DSTBLEND_ZERO: dst = GL_ZERO; break; + case SBITS_DSTBLEND_ONE: dst = GL_ONE; break; + case SBITS_DSTBLEND_SRC_COLOR: dst = GL_SRC_COLOR; break; + case SBITS_DSTBLEND_ONE_MINUS_SRC_COLOR: dst = GL_ONE_MINUS_SRC_COLOR; break; + case SBITS_DSTBLEND_SRC_ALPHA: dst = GL_SRC_ALPHA; break; + case SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA: dst = GL_ONE_MINUS_SRC_ALPHA; break; + case SBITS_DSTBLEND_DST_ALPHA: dst = GL_DST_ALPHA; break; + case SBITS_DSTBLEND_ONE_MINUS_DST_ALPHA: dst = GL_ONE_MINUS_DST_ALPHA; break; + default: Sys_Error("Invalid shaderbits\n"); + } + qglEnable(GL_BLEND); + qglBlendFunc(src, dst); + } + else + qglDisable(GL_BLEND); + } + + if (delta & SBITS_ATEST_BITS) + { + switch (sbits & SBITS_ATEST_BITS) + { + default: + qglDisable(GL_ALPHA_TEST); + break; + case SBITS_ATEST_GT0: + qglEnable(GL_ALPHA_TEST); + qglAlphaFunc(GL_GREATER, 0); + case SBITS_ATEST_LT128: + qglEnable(GL_ALPHA_TEST); + qglAlphaFunc(GL_LESS, 0.5f); + break; + case SBITS_ATEST_GE128: + qglEnable(GL_ALPHA_TEST); + qglAlphaFunc(GL_GEQUAL, 0.5f); + break; + } + } + + if (delta & SBITS_MISC_DEPTHWRITE) + { + if (sbits & SBITS_MISC_DEPTHWRITE) + qglDepthMask(GL_TRUE); + else + qglDepthMask(GL_FALSE); + } + if (delta & SBITS_MISC_NODEPTHTEST) + { + if (sbits & SBITS_MISC_NODEPTHTEST) + qglDisable(GL_DEPTH_TEST); + else + qglEnable(GL_DEPTH_TEST); + } + if (delta & (SBITS_MISC_DEPTHEQUALONLY|SBITS_MISC_DEPTHCLOSERONLY)) + { + extern int gldepthfunc; + switch (sbits & (SBITS_MISC_DEPTHEQUALONLY|SBITS_MISC_DEPTHCLOSERONLY)) + { + case SBITS_MISC_DEPTHEQUALONLY: + qglDepthFunc(GL_EQUAL); + break; + case SBITS_MISC_DEPTHCLOSERONLY: + if (gldepthfunc == GL_LEQUAL) + qglDepthFunc(GL_LESS); + else + qglDepthFunc(GL_GREATER); + break; + default: + qglDepthFunc(gldepthfunc); + break; + } + } +} + +static void BE_SubmitMeshChain(const mesh_t *meshlist) +{ + int startv, starti, endv, endi; + while (meshlist) + { + startv = meshlist->vbofirstvert; + starti = meshlist->vbofirstelement; + + endv = startv+meshlist->numvertexes; + endi = starti+meshlist->numindexes; + + //find consecutive surfaces + for (meshlist = meshlist->next; meshlist; meshlist = meshlist->next) + { + if (endi == meshlist->vbofirstelement) + { + endv = meshlist->vbofirstvert+meshlist->numvertexes; + endi = meshlist->vbofirstelement+meshlist->numindexes; + } + else + { + break; + } + } + + qglDrawRangeElements(GL_TRIANGLES, startv, endv, endi-starti, GL_INDEX_TYPE, shaderstate.sourcevbo->indicies + starti); + } +} + +static void DrawPass(const shaderpass_t *pass, const mesh_t *meshlist) +{ + int i; + int tmu; + int lastpass = pass->numMergedPasses; + + for (i = 0; i < lastpass; i++) + { + if (pass[i].texgen == T_GEN_UPPEROVERLAY && !TEXVALID(shaderstate.curtexnums->upperoverlay)) + continue; + if (pass[i].texgen == T_GEN_LOWEROVERLAY && !TEXVALID(shaderstate.curtexnums->loweroverlay)) + continue; + if (pass[i].texgen == T_GEN_FULLBRIGHT && !TEXVALID(shaderstate.curtexnums->fullbright)) + continue; + break; + } + if (i == lastpass) + return; + + checkerror(); + BE_SendPassBlendAndDepth(pass[i].shaderbits); + GenerateColourMods(pass+i, meshlist); + checkerror(); + tmu = 0; + for (; i < lastpass; i++) + { + if (pass[i].texgen == T_GEN_UPPEROVERLAY && !TEXVALID(shaderstate.curtexnums->upperoverlay)) + continue; + if (pass[i].texgen == T_GEN_LOWEROVERLAY && !TEXVALID(shaderstate.curtexnums->loweroverlay)) + continue; + if (pass[i].texgen == T_GEN_FULLBRIGHT && !TEXVALID(shaderstate.curtexnums->fullbright)) + continue; + GL_MBind(tmu, Shader_TextureForPass(pass+i)); + + checkerror(); + BE_GeneratePassTC(pass, i, meshlist); + + checkerror(); + if (tmu >= shaderstate.lastpasstmus) + { + qglEnable(GL_TEXTURE_2D); + qglEnableClientState(GL_TEXTURE_COORD_ARRAY); + } + + + switch (pass[i].blendmode) + { + case GL_DOT3_RGB_ARB: + GL_TexEnv(GL_COMBINE_EXT); + qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); + qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); + qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, pass[i].blendmode); + break; + case GL_REPLACE: + GL_TexEnv(GL_REPLACE); + break; + case GL_DECAL: + case GL_ADD: + if (tmu != 0) + { + GL_TexEnv(pass[i].blendmode); + break; + } + default: + case GL_MODULATE: + GL_TexEnv(GL_MODULATE); + break; + } + checkerror(); + tmu++; + } + checkerror(); + + for (i = tmu; i < shaderstate.lastpasstmus; i++) + { + GL_SelectTexture(i); + qglDisableClientState(GL_TEXTURE_COORD_ARRAY); + qglDisable(GL_TEXTURE_2D); + } + shaderstate.lastpasstmus = tmu; + GL_ApplyVertexPointer(); + + BE_SubmitMeshChain(meshlist); + + checkerror(); +} +void Matrix4_TransformN3(float *matrix, float *vector, float *product) +{ + product[0] = -matrix[12] - matrix[0]*vector[0] - matrix[4]*vector[1] - matrix[8]*vector[2]; + product[1] = -matrix[13] - matrix[1]*vector[0] - matrix[5]*vector[1] - matrix[9]*vector[2]; + product[2] = -matrix[14] - matrix[2]*vector[0] - matrix[6]*vector[1] - matrix[10]*vector[2]; +} + +static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pass, const mesh_t *meshlist) +{ + const shader_t *s = shader; + int i; + vec3_t param3; + float m16[16]; + int r, g, b; + + BE_SendPassBlendAndDepth(pass->shaderbits); + GenerateColourMods(pass, meshlist); + + for ( i = 0; i < pass->numMergedPasses; i++) + { + GL_MBind(i, Shader_TextureForPass(pass+i)); + if (i >= shaderstate.lastpasstmus) + { + qglEnable(GL_TEXTURE_2D); + qglEnableClientState(GL_TEXTURE_COORD_ARRAY); + } + BE_GeneratePassTC(pass, i, meshlist); + } + for (; i < shaderstate.lastpasstmus; i++) + { + GL_SelectTexture(i); + qglDisableClientState(GL_TEXTURE_COORD_ARRAY); + qglDisable(GL_TEXTURE_2D); + } + shaderstate.lastpasstmus = pass->numMergedPasses; + + GLSlang_UseProgram(s->programhandle.glsl); + for (i = 0; i < s->numprogparams; i++) + { + switch(s->progparm[i].type) + { + case SP_TIME: + qglUniform1fARB(s->progparm[i].handle, shaderstate.curtime); + break; + case SP_ENTMATRIX: + Matrix4_ModelMatrixFromAxis(m16, currententity->axis[0], currententity->axis[1], currententity->axis[2], currententity->origin); +/* VectorCopy(currententity->axis[0], m16+0); + m16[3] = 0; + VectorCopy(currententity->axis[1], m16+1); + m16[7] = 0; + VectorCopy(currententity->axis[2], m16+2); + m16[11] = 0; + VectorCopy(currententity->origin, m16+3); + m16[15] = 1; + */ + qglUniformMatrix4fvARB(s->progparm[i].handle, 1, false, m16); + break; + case SP_ENTCOLOURS: + qglUniform4fvARB(s->progparm[i].handle, 1, currententity->shaderRGBAf); + break; + case SP_TOPCOLOURS: + R_FetchTopColour(&r, &g, &b); + param3[0] = r/255; + param3[1] = g/255; + param3[2] = b/255; + qglUniform3fvARB(s->progparm[i].handle, 1, param3); + break; + case SP_BOTTOMCOLOURS: + R_FetchBottomColour(&r, &g, &b); + param3[0] = r/255; + param3[1] = g/255; + param3[2] = b/255; + qglUniform3fvARB(s->progparm[i].handle, 1, param3); + break; + + case SP_LIGHTRADIUS: + qglUniform1fARB(s->progparm[i].handle, shaderstate.lightradius); + break; + case SP_LIGHTCOLOUR: + qglUniform3fvARB(s->progparm[i].handle, 1, shaderstate.lightcolours); + break; + case SP_EYEPOS: + { +#pragma message("is this correct?") +// vec3_t t1; + vec3_t t2; + Matrix4_ModelMatrixFromAxis(m16, currententity->axis[0], currententity->axis[1], currententity->axis[2], currententity->origin); + Matrix4_Transform3(m16, r_origin, t2); +// VectorSubtract(r_origin, currententity->origin, t1); +// Matrix3_Multiply_Vec3(currententity->axis, t1, t2); + qglUniform3fvARB(s->progparm[i].handle, 1, t2); + } + break; + case SP_LIGHTPOSITION: + { +#pragma message("is this correct?") + float inv[16]; +// vec3_t t1; + vec3_t t2; + qboolean Matrix4_Invert(const float *m, float *out); + + Matrix4_ModelMatrixFromAxis(m16, currententity->axis[0], currententity->axis[1], currententity->axis[2], currententity->origin); + Matrix4_Invert(m16, inv); + Matrix4_Transform3(inv, shaderstate.lightorg, t2); +// VectorSubtract(shaderstate.lightorg, currententity->origin, t1); +// Matrix3_Multiply_Vec3(currententity->axis, t1, t2); + qglUniform3fvARB(s->progparm[i].handle, 1, t2); + } + break; + + default: + Host_EndGame("Bad shader program parameter type (%i)", s->progparm[i].type); + break; + } + } + GL_ApplyVertexPointer(); + BE_SubmitMeshChain(meshlist); + GLSlang_UseProgram(0); +} + +qboolean BE_LightCullModel(vec3_t org, model_t *model) +{ + if (shaderstate.mode == BEM_LIGHT || shaderstate.mode == BEM_STENCIL) + { + float dist; + vec3_t disp; + if (model->type == mod_alias) + { + VectorSubtract(org, shaderstate.lightorg, disp); + dist = DotProduct(disp, disp); + if (dist > model->radius*model->radius + shaderstate.lightradius*shaderstate.lightradius) + return true; + } + else + { + float dist; + int i; + + for (i = 0; i < 3; i++) + { + if (shaderstate.lightorg[i]-shaderstate.lightradius > org[i] + model->maxs[i]) + return true; + if (shaderstate.lightorg[i]+shaderstate.lightradius < org[i] + model->mins[i]) + return true; + } + } + } + return false; +} + +//Note: Be cautious about using BEM_LIGHT here. +void BE_SelectMode(backendmode_t mode, unsigned int flags) +{ + extern int gldepthfunc; + + if (mode != shaderstate.mode) + { + +qglDisable(GL_POLYGON_OFFSET_FILL); +shaderstate.curpolyoffset.factor = 0; +shaderstate.curpolyoffset.unit = 0; + + if (mode == BEM_STENCIL) + { + qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + +shaderstate.curpolyoffset.factor = 0; +shaderstate.curpolyoffset.unit = 0; +qglEnable(GL_POLYGON_OFFSET_FILL); +qglPolygonOffset(shaderstate.curpolyoffset.factor, shaderstate.curpolyoffset.unit); + + /*BEM_STENCIL doesn't support mesh writing*/ + qglDisableClientState(GL_COLOR_ARRAY); + //disable all tmus + while(shaderstate.lastpasstmus>0) + { + GL_SelectTexture(--shaderstate.lastpasstmus); + qglDisable(GL_TEXTURE_2D); + qglDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + qglShadeModel(GL_FLAT); + //replace mode please + GL_TexEnv(GL_REPLACE); + + //we don't write or blend anything (maybe alpha test... but mneh) + BE_SendPassBlendAndDepth(SBITS_MISC_DEPTHCLOSERONLY); + + //don't change cull stuff, and + //don't actually change stencil stuff - caller needs to be + //aware of how many times stuff is drawn, so they can do that themselves. + } + if (mode == BEM_DEPTHONLY) + { + qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + /*BEM_DEPTHONLY does support mesh writing, but its not the only way its used... FIXME!*/ + qglDisableClientState(GL_COLOR_ARRAY); + while(shaderstate.lastpasstmus>0) + { + GL_SelectTexture(--shaderstate.lastpasstmus); + qglDisable(GL_TEXTURE_2D); + qglDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + qglShadeModel(GL_FLAT); + + //we don't write or blend anything (maybe alpha test... but mneh) + BE_SendPassBlendAndDepth(SBITS_MISC_DEPTHWRITE); + + GL_TexEnv(GL_REPLACE); + qglCullFace(GL_FRONT); + } + if (shaderstate.mode == BEM_STENCIL || shaderstate.mode == BEM_DEPTHONLY) + qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + + if (mode == BEM_SMAPLIGHT) + { + if (!shaderstate.initedpcfpasses) + { + int i; + shaderstate.initedpcfpasses = true; + for (i = 0; i < PERMUTATIONS; i++) + { + shaderstate.pcfpassshader[i] = R_RegisterCustom(pcfpassname[i], Shader_LightPass_PCF, permutationdefines[i]); + } + } + } + if (mode == BEM_LIGHT) + { + if (!shaderstate.initedlightpasses) + { + int i; + shaderstate.initedlightpasses = true; + for (i = 0; i < PERMUTATIONS; i++) + { + shaderstate.lightpassshader[i] = R_RegisterCustom(lightpassname[i], Shader_LightPass_Std, permutationdefines[i]); + } + } + } + } + + shaderstate.mode = mode; + shaderstate.flags = flags; +} + +void BE_SelectDLight(dlight_t *dl, vec3_t colour) +{ + shaderstate.lightradius = dl->radius; + VectorCopy(dl->origin, shaderstate.lightorg); + VectorCopy(colour, shaderstate.lightcolours); + shaderstate.curshadowmap = dl->stexture; +} + +static void DrawMeshChain(const mesh_t *meshlist) +{ + const shaderpass_t *p; + int passno,perm; + passno = 0; + + GL_SelectEBO(shaderstate.sourcevbo->vboe); + if (shaderstate.curshader->numdeforms) + GenerateVertexDeforms(shaderstate.curshader, meshlist); + else + { + shaderstate.pendingvertexpointer = shaderstate.sourcevbo->coord; + shaderstate.pendingvertexvbo = shaderstate.sourcevbo->vbocoord; + } + + if (shaderstate.curcull != (shaderstate.curshader->flags & (SHADER_CULL_FRONT|SHADER_CULL_BACK))) + { + shaderstate.curcull = (shaderstate.curshader->flags & (SHADER_CULL_FRONT|SHADER_CULL_BACK)); + + if (shaderstate.curcull & SHADER_CULL_FRONT) + { + qglEnable(GL_CULL_FACE); + qglCullFace(GL_FRONT); + } + else if (shaderstate.curcull & SHADER_CULL_BACK) + { + qglEnable(GL_CULL_FACE); + qglCullFace(GL_BACK); + } + else + { + qglDisable(GL_CULL_FACE); + } + } + + if (shaderstate.curentity != &r_worldentity) + { + /*some quake doors etc are flush with the walls that they're meant to be hidden behind, or plats the same height as the floor, etc + we move them back very slightly using polygonoffset to avoid really ugly z-fighting*/ + extern cvar_t r_polygonoffset_submodel_offset, r_polygonoffset_submodel_factor; + polyoffset_t po; + po.factor = shaderstate.curshader->polyoffset.factor + r_polygonoffset_submodel_factor.value; + po.unit = shaderstate.curshader->polyoffset.unit + r_polygonoffset_submodel_offset.value; + + if (((int*)&shaderstate.curpolyoffset)[0] != ((int*)&po)[0] || ((int*)&shaderstate.curpolyoffset)[1] != ((int*)&po)[1]) + { + shaderstate.curpolyoffset = po; + if (shaderstate.curpolyoffset.factor || shaderstate.curpolyoffset.unit) + { + qglEnable(GL_POLYGON_OFFSET_FILL); + qglPolygonOffset(shaderstate.curpolyoffset.factor, shaderstate.curpolyoffset.unit); + } + else + qglDisable(GL_POLYGON_OFFSET_FILL); + } + } + else + { + if (*(int*)&shaderstate.curpolyoffset != *(int*)&shaderstate.curshader->polyoffset || *(int*)&shaderstate.curpolyoffset != *(int*)&shaderstate.curshader->polyoffset) + { + shaderstate.curpolyoffset = shaderstate.curshader->polyoffset; + if (shaderstate.curpolyoffset.factor || shaderstate.curpolyoffset.unit) + { + qglEnable(GL_POLYGON_OFFSET_FILL); + qglPolygonOffset(shaderstate.curpolyoffset.factor, shaderstate.curpolyoffset.unit); + } + else + qglDisable(GL_POLYGON_OFFSET_FILL); + } + } + + switch(shaderstate.mode) + { + case BEM_STENCIL: + Host_Error("Shader system is not meant to accept stencil meshes\n"); + break; + case BEM_SMAPLIGHT: + perm = 0; + if (TEXVALID(shaderstate.curtexnums->bump) && shaderstate.pcfpassshader[perm|PERMUTATION_BUMPMAP]) + perm |= PERMUTATION_BUMPMAP; + if (TEXVALID(shaderstate.curtexnums->specular) && shaderstate.pcfpassshader[perm|PERMUTATION_SPECULAR]) + perm |= PERMUTATION_SPECULAR; + if (r_shadow_glsl_offsetmapping.ival && TEXVALID(shaderstate.curtexnums->bump) && shaderstate.pcfpassshader[perm|PERMUTATION_OFFSET]) + perm |= PERMUTATION_OFFSET; + BE_RenderMeshProgram(shaderstate.pcfpassshader[perm], shaderstate.pcfpassshader[perm]->passes, meshlist); + break; + case BEM_LIGHT: + perm = 0; + if (TEXVALID(shaderstate.curtexnums->bump) && shaderstate.lightpassshader[perm|PERMUTATION_BUMPMAP]) + perm |= PERMUTATION_BUMPMAP; + if (TEXVALID(shaderstate.curtexnums->specular) && shaderstate.lightpassshader[perm|PERMUTATION_SPECULAR]) + perm |= PERMUTATION_SPECULAR; + if (r_shadow_glsl_offsetmapping.ival && TEXVALID(shaderstate.curtexnums->bump) && shaderstate.lightpassshader[perm|PERMUTATION_OFFSET]) + perm |= PERMUTATION_OFFSET; + BE_RenderMeshProgram(shaderstate.lightpassshader[perm], shaderstate.lightpassshader[perm]->passes, meshlist); + break; + + case BEM_DEPTHONLY: +#pragma message("fixme: support alpha test") + GL_ApplyVertexPointer(); + BE_SubmitMeshChain(meshlist); + break; + + case BEM_DEPTHDARK: + if (shaderstate.curshader->flags & SHADER_HASLIGHTMAP) + { + qglColor3f(0,0,0); + qglDisableClientState(GL_COLOR_ARRAY); + while(shaderstate.lastpasstmus>0) + { + GL_SelectTexture(--shaderstate.lastpasstmus); + qglDisable(GL_TEXTURE_2D); + qglDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + GL_TexEnv(GL_REPLACE); + BE_SendPassBlendAndDepth(shaderstate.curshader->passes[0].shaderbits); + + GL_ApplyVertexPointer(); + BE_SubmitMeshChain(meshlist); + break; + } + //fallthrough + case BEM_STANDARD: + default: + if (shaderstate.curshader->programhandle.glsl) + BE_RenderMeshProgram(shaderstate.curshader, shaderstate.curshader->passes, meshlist); + else + { + while (passno < shaderstate.curshader->numpasses) + { + p = &shaderstate.curshader->passes[passno]; + passno += p->numMergedPasses; + // if (p->flags & SHADER_PASS_DETAIL) + // continue; + + DrawPass(p, meshlist); + } + } + break; + } +} + +void BE_DrawMeshChain(shader_t *shader, mesh_t *meshchain, vbo_t *vbo, texnums_t *texnums) +{ + if (!vbo) + { + mesh_t *m; + shaderstate.sourcevbo = &shaderstate.dummyvbo; + shaderstate.curshader = shader; + shaderstate.curentity = currententity; + shaderstate.curtexnums = texnums; + shaderstate.curlightmap = r_nulltex; + shaderstate.curdeluxmap = r_nulltex; + shaderstate.curtime = realtime; + + while (meshchain) + { + m = meshchain; + meshchain = meshchain->next; + + shaderstate.dummyvbo.coord = m->xyz_array; + shaderstate.dummyvbo.texcoord = m->st_array; + shaderstate.dummyvbo.indicies = m->indexes; + shaderstate.dummyvbo.normals = m->normals_array; + shaderstate.dummyvbo.svector = m->snormals_array; + shaderstate.dummyvbo.tvector = m->tnormals_array; + shaderstate.dummyvbo.colours4f = m->colors4f_array; + + m->next = NULL; + DrawMeshChain(m); + m->next = meshchain; + } + } + else + { + shaderstate.sourcevbo = vbo; + shaderstate.curshader = shader; + shaderstate.curentity = currententity; + shaderstate.curtexnums = texnums; + shaderstate.curlightmap = r_nulltex; + shaderstate.curdeluxmap = r_nulltex; + shaderstate.curtime = realtime; + + DrawMeshChain(meshchain); + } +} + +//FIXME: Legacy code +void R_RenderMeshBuffer(meshbuffer_t *mb, qboolean shadowpass) +{ + mesh_t *m; + if (!shaderstate.pushedmeshes) + return; + + BE_SelectMode(BEM_STANDARD, 0); + shaderstate.sourcevbo = &shaderstate.dummyvbo; + shaderstate.curshader = mb->shader; + shaderstate.curentity = mb->entity; + shaderstate.curtexnums = NULL; + shaderstate.curlightmap = r_nulltex; + shaderstate.curdeluxmap = r_nulltex; + if (shaderstate.force2d || !shaderstate.curentity) + shaderstate.curtime = realtime; + else + shaderstate.curtime = r_refdef.time - shaderstate.curentity->shaderTime; + + while (shaderstate.pushedmeshes) + { + m = shaderstate.pushedmeshes; + shaderstate.pushedmeshes = m->next; + m->next = NULL; + shaderstate.dummyvbo.coord = m->xyz_array; + shaderstate.dummyvbo.texcoord = m->st_array; + shaderstate.dummyvbo.indicies = m->indexes; + shaderstate.dummyvbo.normals = m->normals_array; + shaderstate.dummyvbo.svector = m->snormals_array; + shaderstate.dummyvbo.tvector = m->tnormals_array; + shaderstate.dummyvbo.colours4f = m->colors4f_array; + if (m->vbofirstvert || m->vbofirstelement) + return; + DrawMeshChain(m); + } +} +void R_PushMesh(mesh_t *mesh, int features) +{ + mesh->next = shaderstate.pushedmeshes; + shaderstate.pushedmeshes = mesh; +} + +static void DrawSurfaceChain(msurface_t *s, shader_t *shader, vbo_t *vbo) +{ //doesn't merge surfaces, but tells gl to do each vertex arrayed surface individually, which means no vertex copying. + int i; + mesh_t *ml, *m; + + if (!vbo) + return; + + ml = NULL; + for (; s ; s=s->texturechain) + { + m = s->mesh; + if (!m) //urm. + continue; + if (m->numvertexes <= 1) + continue; + + if (s->lightmaptexturenum < 0) + { + m->next = ml; + ml = m; + } + else + { + m->next = lightmap[s->lightmaptexturenum]->meshchain; + lightmap[s->lightmaptexturenum]->meshchain = m; + } + } + + shaderstate.sourcevbo = vbo; + shaderstate.curshader = shader; + shaderstate.curentity = currententity; + shaderstate.curtime = realtime; + + if (ml) + { + shaderstate.curlightmap = r_nulltex; + shaderstate.curdeluxmap = r_nulltex; + DrawMeshChain(ml); + } + checkerror(); + for (i = 0; i < numlightmaps; i++) + { + if (!lightmap[i] || !lightmap[i]->meshchain) + continue; + + if (lightmap[i]->modified) + { + glRect_t *theRect; + lightmap[i]->modified = false; + theRect = &lightmap[i]->rectchange; + GL_Bind(lightmap_textures[i]); + qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t, + LMBLOCK_WIDTH, theRect->h, gl_lightmap_format, GL_UNSIGNED_BYTE, + lightmap[i]->lightmaps+(theRect->t) *LMBLOCK_WIDTH*lightmap_bytes); + theRect->l = LMBLOCK_WIDTH; + theRect->t = LMBLOCK_HEIGHT; + theRect->h = 0; + theRect->w = 0; + checkerror(); + + if (lightmap[i]->deluxmodified) + { + lightmap[i]->deluxmodified = false; + theRect = &lightmap[i]->deluxrectchange; + GL_Bind(deluxmap_textures[i]); + qglTexSubImage2D(GL_TEXTURE_2D, 0, 0, theRect->t, + LMBLOCK_WIDTH, theRect->h, GL_RGB, GL_UNSIGNED_BYTE, + lightmap[i]->deluxmaps+(theRect->t) *LMBLOCK_WIDTH*3); + theRect->l = LMBLOCK_WIDTH; + theRect->t = LMBLOCK_HEIGHT; + theRect->h = 0; + theRect->w = 0; + checkerror(); + } + } + + shaderstate.curlightmap = lightmap_textures[i]; + shaderstate.curdeluxmap = deluxmap_textures[i]; + DrawMeshChain(lightmap[i]->meshchain); + lightmap[i]->meshchain = NULL; + } +} + + +void BE_BaseTextureChain(msurface_t *first) +{ + texture_t *t, *tex; + shader_t *shader; + t = first->texinfo->texture; + tex = R_TextureAnimation (t); + + //TEMP: use shader as an input parameter, not tex. + shader = tex->shader; + if (!shader) + { + shader = R_RegisterShader_Lightmap(tex->name); + tex->shader = shader; + } + + shaderstate.curtexnums = &shader->defaulttextures; + DrawSurfaceChain(first, shader, &t->vbo); +} + +static void BaseBrushTextures(entity_t *ent) +{ + int i; + msurface_t *s, *chain; + model_t *model; + + if (BE_LightCullModel(ent->origin, ent->model)) + return; + + qglPushMatrix(); + R_RotateForEntity(ent); + + ent->shaderRGBAf[0] = 1; + ent->shaderRGBAf[1] = 1; + ent->shaderRGBAf[2] = 1; + ent->shaderRGBAf[3] = 1; + + model = ent->model; + chain = NULL; + +// calculate dynamic lighting for bmodel if it's not an +// instanced model + if (model->fromgame != fg_quake3) + { + int k; + int shift; + + if (model->nummodelsurfaces != 0 && r_dynamic.value) + { + for (k=rtlights_first; kfuncs.MarkLights (&cl_dlights[k], 1<nodes + model->hulls[0].firstclipnode); + } + } + + shift = GLR_LightmapShift(model); + +//update lightmaps. + for (s = model->surfaces+model->firstmodelsurface,i = 0; i < model->nummodelsurfaces; i++, s++) + R_RenderDynamicLightmaps (s, shift); + } + + for (s = model->surfaces+model->firstmodelsurface,i = 0; i < model->nummodelsurfaces; i++, s++) + { + /*if (s->texinfo->flags & (Q2TI_TRANS33 | Q2TI_TRANS66)) + { + s->ownerent = currententity; + s->nextalphasurface = r_alpha_surfaces; + r_alpha_surfaces = s; + continue; + } + else */if (chain && s->texinfo->texture != chain->texinfo->texture) //last surface or not the same as the next + { + BE_BaseTextureChain(chain); + chain = NULL; + } + + // s->flags |= sflags; + s->texturechain = chain; + chain = s; + } + + if (chain) + BE_BaseTextureChain(chain); + + qglPopMatrix(); +} + +void BE_BaseEntShadowDepth(void) +{ + extern model_t *currentmodel; + int i; + + if (!r_drawentities.value) + return; + + // draw sprites seperately, because of alpha blending + for (i=0 ; imodel) + continue; + if (currententity->model->needload) + continue; + if (currententity->flags & Q2RF_WEAPONMODEL) + continue; + switch(currententity->model->type) + { + case mod_brush: + BaseBrushTextures(currententity); + break; + case mod_alias: + R_DrawGAliasModel (currententity, BEM_DEPTHONLY); + break; + } + } +} + +void BE_BaseEntTextures(void) +{ + extern model_t *currentmodel; + int i; + + if (!r_drawentities.ival) + return; + + // draw sprites seperately, because of alpha blending + for (i=0 ; imodel) + continue; + if (currententity->model->needload) + continue; + if (!PPL_ShouldDraw()) + continue; + switch(currententity->model->type) + { + case mod_brush: + BaseBrushTextures(currententity); + break; + case mod_alias: + R_DrawGAliasModel (currententity, shaderstate.mode); + break; + } + } +} + +void BE_DrawPolys(qboolean decalsset) +{ + unsigned int i; + mesh_t m; + + if (!cl_numstris) + return; + + memset(&m, 0, sizeof(m)); + for (i = 0; i < cl_numstris; i++) + { + if ((cl_stris[i].shader->sort <= SHADER_SORT_DECAL) ^ decalsset) + continue; + + m.xyz_array = cl_strisvertv + cl_stris[i].firstvert; + m.st_array = cl_strisvertt + cl_stris[i].firstvert; + m.colors4f_array = cl_strisvertc + cl_stris[i].firstvert; + m.indexes = cl_strisidx + cl_stris[i].firstidx; + m.numindexes = cl_stris[i].numidx; + m.numvertexes = cl_stris[i].numvert; + BE_DrawMeshChain(cl_stris[i].shader, &m, NULL, &cl_stris[i].shader->defaulttextures); + } +} + +void BE_SubmitMeshes (void) +{ + texture_t *t; + msurface_t *s; + int i; + model_t *model = cl.worldmodel; + unsigned int fl; + currententity = &r_worldentity; + + for (i=0 ; inumtextures ; i++) + { + t = model->textures[i]; + if (!t) + continue; + s = t->texturechain; + if (!s) + continue; + + fl = s->texinfo->texture->shader->flags; + if (fl & SHADER_NODLIGHT) + if (shaderstate.mode == BEM_LIGHT || shaderstate.mode == BEM_SMAPLIGHT) + continue; + + if (fl & SHADER_SKY) + { + if (shaderstate.mode == BEM_STANDARD) + R_DrawSkyChain (s); + } + else + BE_BaseTextureChain(s); + } + + if (shaderstate.mode == BEM_STANDARD) + BE_DrawPolys(true); + + checkerror(); + BE_BaseEntTextures(); + checkerror(); +} + +static void BE_CleanChains(void) +{ + int i; + model_t *model = cl.worldmodel; + + for (i=0 ; inumtextures ; i++) + { + model->textures[i]->texturechain = NULL; + } +} + +void PPL_DrawWorld (qbyte *vis) +{ + extern cvar_t r_shadow_realtime_world, r_shadow_realtime_world_lightmaps; + RSpeedLocals(); + GL_DoSwap(); + + //make sure the world draws correctly + r_worldentity.shaderRGBAf[0] = 1; + r_worldentity.shaderRGBAf[1] = 1; + r_worldentity.shaderRGBAf[2] = 1; + r_worldentity.shaderRGBAf[3] = 1; + r_worldentity.axis[0][0] = 1; + r_worldentity.axis[1][1] = 1; + r_worldentity.axis[2][2] = 1; + + if (r_shadow_realtime_world.value) + shaderstate.identitylighting = r_shadow_realtime_world_lightmaps.value; + else + shaderstate.identitylighting = 1; + + if (shaderstate.identitylighting == 0) + BE_SelectMode(BEM_DEPTHDARK, 0); + else + BE_SelectMode(BEM_STANDARD, 0); + + checkerror(); + + RSpeedRemark(); + BE_SubmitMeshes(); + RSpeedEnd(RSPEED_WORLD); + +#ifdef RTLIGHTS + RSpeedRemark(); + Sh_DrawLights(vis); + RSpeedEnd(RSPEED_STENCILSHADOWS); +#endif + checkerror(); + + BE_DrawPolys(false); + + BE_CleanChains(); +} + + + + +#if 0 + + #include "quakedef.h" #include "glquake.h" #include "shader.h" -#ifndef NEWBACKEND -#ifdef RGLQUAKE +#ifdef GLQUAKE #define MAX_TEXTURE_UNITS 8 @@ -29,14 +2777,14 @@ extern int gl_filter_max; void GL_SelectTexture (GLenum target) { - gl_state.currenttmu = target - mtexid0; + gl_state.currenttmu = target; if (qglClientActiveTextureARB) { - qglClientActiveTextureARB(target); - qglActiveTextureARB(target); + qglClientActiveTextureARB(target + mtexid0); + qglActiveTextureARB(target + mtexid0); } else - qglSelectTextureSGIS(target); + qglSelectTextureSGIS(target + mtexid0); } void GL_CheckTMUIs0(void) @@ -44,13 +2792,13 @@ void GL_CheckTMUIs0(void) if (gl_state.currenttmu != 0) { Con_Printf("TMU is not 0\n"); - GL_SelectTexture(mtexid0); + GL_SelectTexture(0); } } -void GL_MBind( GLenum target, int texnum ) +void GL_MBind( int target, int texnum ) { - GL_SelectTexture( target ); + GL_SelectTexture(target); if ( gl_state.currenttextures[gl_state.currenttmu] == texnum ) return; @@ -343,8 +3091,8 @@ void GL_InitFogTexture (void) GL_Bind(r_fogtexture); qglTexImage2D (GL_TEXTURE_2D, 0, GL_ALPHA, FOG_TEXTURE_WIDTH, FOG_TEXTURE_HEIGHT, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data); - qglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max); - qglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); + qglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max); + qglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); qglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); qglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -700,7 +3448,7 @@ R_BackendEndFrame */ void R_BackendEndFrame (void) { - if (r_speeds.value) + if (r_speeds.ival) { Con_Printf( "%4i wpoly %4i leafs %4i verts %4i tris %4i flushes\n", c_brush_polys, @@ -885,11 +3633,11 @@ void R_FlushArraysMtex (void) qglColor4ubv(colorArray[0]); } - GL_MBind( mtexid0, r_texNums[0] ); + GL_MBind( 0, r_texNums[0] ); qglEnableClientState( GL_TEXTURE_COORD_ARRAY); for (i = 1; i < r_numUnits; i++) { - GL_MBind(mtexid0 + i, r_texNums[i]); + GL_MBind(i, r_texNums[i]); qglEnable (GL_TEXTURE_2D ); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); } @@ -907,7 +3655,7 @@ void R_FlushArraysMtex (void) for ( i = r_numUnits - 1; i >= 0; i-- ) { - GL_SelectTexture (mtexid0 + i); + GL_SelectTexture (i); if (i) { @@ -1887,7 +4635,7 @@ void R_RenderMeshMultitextured ( meshbuffer_t *mb, shaderpass_t *pass ) r_numUnits = pass->numMergedPasses; - GL_SelectTexture( mtexid0 ); + GL_SelectTexture( 0 ); GL_TexEnv( pass->blendmode ); R_SetShaderpassState ( pass, true ); R_ModifyTextureCoords ( pass, 0 ); @@ -1895,7 +4643,7 @@ void R_RenderMeshMultitextured ( meshbuffer_t *mb, shaderpass_t *pass ) for ( i = 1, pass++; i < r_numUnits; i++, pass++ ) { - GL_SelectTexture( mtexid0 + i ); + GL_SelectTexture( i ); GL_TexEnv( pass->blendmode ); R_ModifyTextureCoords ( pass, i ); } @@ -1917,7 +4665,7 @@ void R_RenderMeshCombined ( meshbuffer_t *mb, shaderpass_t *pass ) R_SetShaderpassState ( pass, true ); R_ModifyColor ( mb, pass ); - GL_SelectTexture( mtexid0 ); + GL_SelectTexture( 0 ); if ( pass->blendmode == GL_REPLACE ) GL_TexEnv( GL_REPLACE ); else @@ -1926,7 +4674,7 @@ void R_RenderMeshCombined ( meshbuffer_t *mb, shaderpass_t *pass ) for ( i = 1, pass++; i < r_numUnits; i++, pass++ ) { - GL_SelectTexture( mtexid0 + i ); + GL_SelectTexture( i ); switch ( pass->blendmode ) @@ -2106,7 +4854,7 @@ void R_RenderMeshProgram ( meshbuffer_t *mb, shaderpass_t *pass ) R_SetShaderpassState ( pass, true ); R_ModifyColor ( mb, pass ); - GL_SelectTexture( mtexid0 ); + GL_SelectTexture( 0 ); if ( pass->blendmode == GL_REPLACE ) GL_TexEnv( GL_REPLACE ); else @@ -2115,7 +4863,7 @@ void R_RenderMeshProgram ( meshbuffer_t *mb, shaderpass_t *pass ) for ( i = 1, pass++; i < r_numUnits; i++, pass++ ) { - GL_SelectTexture( mtexid0 + i ); + GL_SelectTexture( i ); R_ModifyTextureCoords ( pass, i ); } @@ -2576,3 +5324,4 @@ void R_FinishMeshBuffer ( meshbuffer_t *mb ) #endif #endif +#endif diff --git a/engine/gl/gl_bloom.c b/engine/gl/gl_bloom.c index 910c997e..f52ad8a7 100644 --- a/engine/gl/gl_bloom.c +++ b/engine/gl/gl_bloom.c @@ -24,7 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h" extern vrect_t gl_truescreenrect; @@ -71,10 +71,10 @@ static cvar_t r_bloom_fast_sample = SCVARF("r_bloom_fast_sample", "0", CVAR_REN typedef struct { //texture numbers - int tx_screen; - int tx_effect; - int tx_backup; - int tx_downsample; + texid_t tx_screen; + texid_t tx_effect; + texid_t tx_backup; + texid_t tx_downsample; //the viewport dimensions int vp_x; @@ -143,7 +143,7 @@ void R_Bloom_InitBackUpTexture(int widthheight) data = Z_Malloc(widthheight * widthheight * 4); bs.size_backup = widthheight; - bs.tx_backup = GL_LoadTexture32("***bs.tx_backup***", bs.size_backup, bs.size_backup, (unsigned int*)data, false, false); + bs.tx_backup = GL_LoadTexture32("***bs.tx_backup***", bs.size_backup, bs.size_backup, (unsigned int*)data, IF_NOMIPMAP|IF_NOALPHA|IF_NOGAMMA); Z_Free (data); } @@ -182,7 +182,7 @@ void R_Bloom_InitEffectTexture(void) data = Z_Malloc(bs.size_sample * bs.size_sample * 4); - bs.tx_effect = GL_LoadTexture32("***bs.tx_effect***", bs.size_sample, bs.size_sample, (unsigned int*)data, false, false); + bs.tx_effect = GL_LoadTexture32("***bs.tx_effect***", bs.size_sample, bs.size_sample, (unsigned int*)data, IF_NOMIPMAP|IF_NOALPHA|IF_NOGAMMA); Z_Free (data); } @@ -199,8 +199,8 @@ void R_Bloom_InitTextures(void) int maxtexsize; //find closer power of 2 to screen size - for (bs.scr_w = 1;bs.scr_w < glwidth;bs.scr_w *= 2); - for (bs.scr_h = 1;bs.scr_h < glheight;bs.scr_h *= 2); + for (bs.scr_w = 1;bs.scr_w < vid.pixelwidth;bs.scr_w *= 2); + for (bs.scr_h = 1;bs.scr_h < vid.pixelheight;bs.scr_h *= 2); //disable blooms if we can't handle a texture of that size qglGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxtexsize); @@ -217,12 +217,12 @@ void R_Bloom_InitTextures(void) size = bs.scr_w * bs.scr_h * 4; data = Z_Malloc(size); memset(data, 255, size); - if (!bs.tx_screen) + if (!TEXVALID(bs.tx_screen)) bs.tx_screen = GL_AllocNewTexture(); GL_Bind(bs.tx_screen); - qglTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, bs.scr_w, bs.scr_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + qglTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, bs.scr_w, bs.scr_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); Z_Free (data); @@ -230,13 +230,13 @@ void R_Bloom_InitTextures(void) R_Bloom_InitEffectTexture (); //if screensize is more than 2x the bloom effect texture, set up for stepped downsampling - bs.tx_downsample = 0; + bs.tx_downsample = r_nulltex; bs.size_downsample = 0; - if (glwidth > (bs.size_sample * 2) && !r_bloom_fast_sample.value) + if (vid.pixelwidth > (bs.size_sample * 2) && !r_bloom_fast_sample.value) { bs.size_downsample = (int)(bs.size_sample * 2); data = Z_Malloc(bs.size_downsample * bs.size_downsample * 4); - bs.tx_downsample = GL_LoadTexture32("***bs.tx_downsample***", bs.size_downsample, bs.size_downsample, (unsigned int*)data, false, false); + bs.tx_downsample = GL_LoadTexture32("***bs.tx_downsample***", bs.size_downsample, bs.size_downsample, (unsigned int*)data, IF_NOMIPMAP|IF_NOALPHA|IF_NOGAMMA); Z_Free (data); } @@ -266,10 +266,10 @@ R_InitBloomTextures void R_InitBloomTextures(void) { bs.size_sample = 0; - if (!r_bloom.value) + if (!r_bloom.ival) return; - bs.tx_screen = 0; //this came from a vid_restart, where none of the textures are valid any more. + bs.tx_screen = r_nulltex; //this came from a vid_restart, where none of the textures are valid any more. R_Bloom_InitTextures (); } @@ -491,10 +491,10 @@ void R_Bloom_GeneratexDiamonds(void) qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, bs.smp_w, bs.smp_h); //restore full screen workspace - qglViewport(0, 0, glwidth, glheight); + qglViewport(0, 0, vid.pixelwidth, vid.pixelheight); qglMatrixMode(GL_PROJECTION); qglLoadIdentity (); - qglOrtho(0, glwidth, glheight, 0, -10, 100); + qglOrtho(0, vid.pixelwidth, vid.pixelheight, 0, -10, 100); qglMatrixMode(GL_MODELVIEW); qglLoadIdentity (); } @@ -517,9 +517,9 @@ void R_Bloom_DownsampleView( void ) //copy the screen and draw resized GL_Bind(bs.tx_screen); - qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bs.vp_x, glheight - (bs.vp_y + bs.vp_h), bs.vp_w, bs.vp_h); + qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bs.vp_x, vid.pixelheight - (bs.vp_y + bs.vp_h), bs.vp_w, bs.vp_h); - R_Bloom_Quad(0, glheight-midsample_height, midsample_width, midsample_height, bs.scr_s, bs.scr_t); + R_Bloom_Quad(0, vid.pixelheight-midsample_height, midsample_width, midsample_height, bs.scr_s, bs.scr_t); //now copy into Downsampling (mid-sized) texture GL_Bind(bs.tx_downsample); @@ -527,14 +527,14 @@ void R_Bloom_DownsampleView( void ) //now draw again in bloom size qglColor4f(0.5f, 0.5f, 0.5f, 1.0f); - R_Bloom_Quad(0, glheight-bs.smp_h, bs.smp_w, bs.smp_h, bs.smp_s, bs.smp_t); + R_Bloom_Quad(0, vid.pixelheight-bs.smp_h, bs.smp_w, bs.smp_h, bs.smp_s, bs.smp_t); //now blend the big screen texture into the bloom generation space (hoping it adds some blur) qglEnable(GL_BLEND); qglBlendFunc(GL_ONE, GL_ONE); qglColor4f(0.5f, 0.5f, 0.5f, 1.0f); GL_Bind(bs.tx_screen); - R_Bloom_Quad(0, glheight-bs.smp_h, bs.smp_w, bs.smp_h, bs.scr_s, bs.scr_t); + R_Bloom_Quad(0, vid.pixelheight-bs.smp_h, bs.smp_w, bs.smp_h, bs.scr_s, bs.scr_t); qglColor4f(1.0f, 1.0f, 1.0f, 1.0f); qglDisable(GL_BLEND); } @@ -542,8 +542,8 @@ void R_Bloom_DownsampleView( void ) { //downsample simple GL_Bind(bs.tx_screen); - qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bs.vp_x, glheight - (bs.vp_y + bs.vp_h), bs.vp_w, bs.vp_h); - R_Bloom_Quad(0, glheight-bs.smp_h, bs.smp_w, bs.smp_h, bs.scr_s, bs.scr_t); + qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bs.vp_x, vid.pixelheight - (bs.vp_y + bs.vp_h), bs.vp_w, bs.vp_h); + R_Bloom_Quad(0, vid.pixelheight-bs.smp_h, bs.smp_w, bs.smp_h, bs.scr_s, bs.scr_t); } } @@ -558,7 +558,7 @@ void R_BloomBlend (void)//refdef_t *fd, meshlist_t *meshlist ) if (!r_bloom.value) return; - if (!bs.size_sample || bs.scr_w < glwidth || bs.scr_h < glheight) + if (!bs.size_sample || bs.scr_w < vid.pixelwidth || bs.scr_h < vid.pixelheight) R_Bloom_InitTextures(); if (bs.scr_w < bs.size_sample || @@ -566,14 +566,14 @@ void R_BloomBlend (void)//refdef_t *fd, meshlist_t *meshlist ) return; //set up full screen workspace - qglViewport(0, 0, glwidth, glheight); + qglViewport(0, 0, vid.pixelwidth, vid.pixelheight); qglDisable(GL_DEPTH_TEST); qglMatrixMode(GL_PROJECTION); qglLoadIdentity(); - qglOrtho(0, glwidth, glheight, 0, -10, 100); + qglOrtho(0, vid.pixelwidth, vid.pixelheight, 0, -10, 100); qglMatrixMode(GL_MODELVIEW); qglLoadIdentity(); - qglDisable(GL_CULL_FACE); + GL_CullFace(0); qglDisable(GL_BLEND); qglEnable(GL_TEXTURE_2D); @@ -582,7 +582,7 @@ void R_BloomBlend (void)//refdef_t *fd, meshlist_t *meshlist ) //set up current sizes bs.vp_x = gl_truescreenrect.x; - bs.vp_y = glheight - gl_truescreenrect.y; + bs.vp_y = vid.pixelheight - gl_truescreenrect.y; bs.vp_w = gl_truescreenrect.width; bs.vp_h = gl_truescreenrect.height; bs.scr_s = (float)bs.vp_w / (float)bs.scr_w; @@ -621,7 +621,7 @@ void R_BloomBlend (void)//refdef_t *fd, meshlist_t *meshlist ) GL_Bind(bs.tx_backup); qglColor4f(1, 1, 1, 1); R_Bloom_Quad(0, - glheight - (buh), + vid.pixelheight - (buh), buw, buh, bs.smp_s, diff --git a/engine/gl/gl_draw.c b/engine/gl/gl_draw.c index faa412e6..30cac9e7 100644 --- a/engine/gl/gl_draw.c +++ b/engine/gl/gl_draw.c @@ -22,21 +22,91 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // vid buffer #include "quakedef.h" -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h" #include "shader.h" +#include "gl_draw.h" #include // is this needed for atoi? #include // is this needed for atoi? //#define GL_USE8BITTEX -int glx, gly, glwidth, glheight; +void GLDraw_ImageColours(float r, float g, float b, float a); +static void GL_Upload32 (char *name, unsigned *data, int width, int height, unsigned int flags); +static void GL_Upload32_BGRA (char *name, unsigned *data, int width, int height, unsigned int flags); +static void GL_Upload24BGR_Flip (char *name, qbyte *framedata, int inwidth, int inheight, unsigned int flags); +static void GL_Upload8 (char *name, qbyte *data, int width, int height, unsigned int flags, unsigned int alpha); -mesh_t draw_mesh; -vec3_t draw_mesh_xyz[4]; -vec2_t draw_mesh_st[4]; -byte_vec4_t draw_mesh_colors[4]; +void GL_UploadFmt(texid_t tex, char *name, enum uploadfmt fmt, void *data, int width, int height, unsigned int flags) +{ + GL_Bind(tex); + switch(fmt) + { + case TF_INVALID: + break; + + case TF_RGBA32: + GL_Upload32(name, data, width, height, flags); + break; + + case TF_BGRA32: + GL_Upload32_BGRA(name, data, width, height, flags); + break; + +// case TF_BGRA24: +// GL_Upload24BGR(name, data, width, height, flags); +// break; + + case TF_BGR24_FLIP: + GL_Upload24BGR_Flip(name, data, width, height, flags); + break; + + case TF_SOLID8: + GL_Upload8(name, data, width, height, flags, 0); + break; + + case TF_TRANS8: + GL_Upload8(name, data, width, height, flags, 1); + break; + +#ifdef _MSC_VER + default: + Sys_Error("Unsupported image format type\n"); + break; +#endif + } +} +texid_t GL_LoadTextureFmt (char *name, int width, int height, enum uploadfmt fmt, void *data, unsigned int flags) +{ + extern cvar_t r_shadow_bumpscale_basetexture; + switch(fmt) + { + case TF_INVALID: + return r_nulltex; + + case TF_RGBA32: + return GL_LoadTexture32(name, width, height, data, flags); + + case TF_TRANS8: + return GL_LoadTexture(name, width, height, data, flags, 1); + + case TF_TRANS8_FULLBRIGHT: + return GL_LoadTextureFB(name, width, height, data, flags); + + case TF_SOLID8: + return GL_LoadTexture(name, width, height, data, flags, 0); + + case TF_HEIGHT8: + return GL_LoadTexture8Bump(name, width, height, data, flags, r_shadow_bumpscale_basetexture.value); + +#ifdef _MSC_VER + default: + Sys_Error("Unsupported image format type\n"); + break; +#endif + } +} qbyte *uploadmemorybuffer; int sizeofuploadmemorybuffer; @@ -47,15 +117,11 @@ index_t r_quad_indexes[6] = {0, 1, 2, 0, 2, 3}; extern qbyte gammatable[256]; -#ifdef AVAIL_FREETYPE -struct font_s *conchar_font; -#endif - unsigned char *d_15to8table; qboolean inited15to8; extern cvar_t crosshair, crosshairimage, crosshairalpha, cl_crossx, cl_crossy, crosshaircolor, crosshairsize; -static int filmtexture; +static texid_t filmtexture; extern cvar_t gl_nobind; extern cvar_t gl_max_size; @@ -72,41 +138,28 @@ extern cvar_t gl_savecompressedtex; extern cvar_t gl_load24bit; -#ifdef Q3SHADERS -shader_t *shader_console; -#endif extern cvar_t con_ocranaleds; extern cvar_t gl_blend2d; extern cvar_t scr_conalpha; -qbyte *draw_chars; // 8*8 graphic characters -mpic_t *draw_disc; -mpic_t *draw_backtile; - -int translate_texture; -int char_texture, char_tex2, default_char_texture, char_texturetiny; -int missing_texture; //texture used when one is missing. -int cs_texture; // crosshair texture -extern int detailtexture; +texid_t translate_texture; +texid_t missing_texture; //texture used when one is missing. +texid_t cs_texture; // crosshair texture float custom_char_instep, default_char_instep; //to avoid blending issues float char_instep; static unsigned cs_data[16*16]; -static int externalhair; +static texid_t externalhair; int gl_anisotropy_factor; -qbyte conback_buffer[sizeof(mpic_t)]; -qbyte custconback_buffer[sizeof(mpic_t)]; -mpic_t *default_conback = (mpic_t *)&conback_buffer, *conback, *custom_conback = (mpic_t *)&custconback_buffer; +mpic_t *conback; #include "hash.h" hashtable_t gltexturetable; bucket_t *gltexturetablebuckets[256]; int gl_lightmap_format = 4; -int gl_solid_format = 3; -int gl_alpha_format = 4; int gl_filter_min = GL_LINEAR_MIPMAP_NEAREST; int gl_filter_max = GL_LINEAR; @@ -116,473 +169,18 @@ int texels; typedef struct gltexture_s { - int texnum; + texid_t texnum; char identifier[64]; int width, height, bpp; - qboolean mipmap; + unsigned int flags; struct gltexture_s *next; } gltexture_t; static gltexture_t *gltextures; -/* -============================================================================= - - scrap allocation - - Allocate all the little status bar obejcts into a single texture - to crutch up stupid hardware / drivers - -============================================================================= -*/ - -#define MAX_SCRAPS 4 -#define BLOCK_WIDTH 256 -#define BLOCK_HEIGHT 256 - -int scrap_allocated[MAX_SCRAPS][BLOCK_WIDTH]; -qbyte scrap_texels[MAX_SCRAPS][BLOCK_WIDTH*BLOCK_HEIGHT]; -qboolean scrap_dirty; -int scrap_usedcount; -int scrap_texnum[MAX_SCRAPS]; - -// returns a texture number and the position inside it -int Scrap_AllocBlock (int w, int h, int *x, int *y) -{ - int i, j; - int best, best2; - int texnum; - - for (texnum=0 ; texnum= best) - break; - if (scrap_allocated[texnum][i+j] > best2) - best2 = scrap_allocated[texnum][i+j]; - } - if (j == w) - { // this is a valid spot - *x = i; - *y = best = best2; - } - } - - if (best + h > BLOCK_HEIGHT) - continue; - - for (i=0 ; iname)) - return &pic->pic; - - return NULL; -} - -qboolean Draw_RealPicFromWad (mpic_t *out, char *name) -{ - qpic_t *in; - glpic_t *gl; - int texnum; - char name2[256]; - - if (!strncmp(name, "gfx/", 4)) - in = W_SafeGetLumpName (name+4); - else - in = W_SafeGetLumpName (name); - gl = &out->d.gl; - - if (in) - { - out->width = in->width; - out->height = in->height; - } - else - { //default the size. - out->width = 24; //hmm...? - out->height = 24; - } - - //standard names substitution - texnum = Mod_LoadReplacementTexture(name, "wad", false, true, false); - if (!in && !texnum) //try a q2 texture - { - sprintf(name2, "pics/%s", name); - texnum = Mod_LoadHiResTexture(name2, NULL, false, true, false); - qglDisable(GL_ALPHA_TEST); - qglEnable(GL_BLEND); //make sure. - } - - if (texnum) - { - if (!in) - { - out->width = image_width; - out->height = image_height; - } - gl->texnum = texnum; - gl->sl = 0; - gl->sh = 1; - gl->tl = 0; - gl->th = 1; - return true; - } - //all the others require an actual infile rather than a replacement image - else if (!in) - { - return false; - } - - // load little ones into the scrap - else if (in->width < 64 && in->height < 64) - { - int x, y; - int i, j, k; - int texnum; - - texnum = Scrap_AllocBlock (in->width, in->height, &x, &y); - if (texnum >= 0) - { - scrap_dirty = true; - k = 0; - for (i=0 ; iheight ; i++) - for (j=0 ; jwidth ; j++, k++) - scrap_texels[texnum][(y+i)*BLOCK_WIDTH + x + j] = in->data[k]; - texnum = scrap_texnum[texnum]; - gl->texnum = texnum; - gl->sl = (x+0.25)/(float)BLOCK_WIDTH; - gl->sh = (x+in->width-0.25)/(float)BLOCK_WIDTH; - gl->tl = (y+0.25)/(float)BLOCK_WIDTH; - gl->th = (y+in->height-0.25)/(float)BLOCK_WIDTH; - pic_count++; - pic_texels += in->width*in->height; - } - else - { - gl->texnum = GL_LoadPicTexture (in); - gl->sl = 0; - gl->sh = 1; - gl->tl = 0; - gl->th = 1; - } - } - else - { - gl->texnum = GL_LoadPicTexture (in); - gl->sl = 0; - gl->sh = 1; - gl->tl = 0; - gl->th = 1; - } - return true; -} - -char *failedpic; //easier this way -mpic_t *GLDraw_SafePicFromWad (char *name) -{ - int i; - glcachepic_t *pic; - for (pic=glmenu_cachepics, i=0 ; iname)) - return &pic->pic; - - if (glmenu_numcachepics == MAX_CACHED_PICS) - { - Con_Printf ("menu_numcachepics == MAX_CACHED_PICS\n"); - failedpic = name; - return NULL; - } - - glmenu_numcachepics++; - - strcpy(pic->name, name); - if (!Draw_RealPicFromWad(&pic->pic, name)) - { - glmenu_numcachepics--; - failedpic = name; - return NULL; - } - - return &pic->pic; -} - -mpic_t *GLDraw_SafeCachePic (char *path) -{ - //this is EVIL! WRITE IT! - - int height = 0; - qbyte *data; - glcachepic_t *pic; - int i; - qpic_t *qpic; - glpic_t *gl; - - for (pic=glmenu_cachepics, i=0 ; iname)) - return &pic->pic; - - if (glmenu_numcachepics == MAX_CACHED_PICS) - Sys_Error ("menu_numcachepics == MAX_CACHED_PICS"); - -// -// load the pic from disk -// - { - char *mem; - char alternatename[MAX_QPATH]; - snprintf(alternatename, sizeof(alternatename), "pics/%s.pcx", path); - FS_LoadFile(alternatename, (void**)&data); - if (data) - { - strcpy(pic->name, path); - if ((mem = ReadPCXFile(data, com_filesize, &pic->pic.width, &height))) - { - pic->pic.height = height; - gl = &pic->pic.d.gl; - if (!(gl->texnum = Mod_LoadReplacementTexture(alternatename, "pics", false, true, false))) - gl->texnum = GL_LoadTexture32(path, pic->pic.width, pic->pic.height, (unsigned *)mem, false, false); - gl->sl = 0; - gl->sh = 1; - gl->tl = 0; - gl->th = 1; - - BZ_Free(data); - BZ_Free(mem); - glmenu_numcachepics++; - return &pic->pic; - } - FS_FreeFile(data); - } - } - - { - char *mem; - char alternatename[MAX_QPATH]; - snprintf(alternatename, MAX_QPATH-1, "%s", path); - FS_LoadFile(alternatename, &data); - if (data) - { - strcpy(pic->name, path); - mem = NULL; - if (!mem) - mem = ReadTargaFile((qbyte *)data, com_filesize, &pic->pic.width, &height, 0); -#ifdef AVAIL_PNGLIB - if (!mem) - mem = ReadPNGFile((qbyte *)data, com_filesize, &pic->pic.width, &height, alternatename); -#endif -#ifdef AVAIL_JPEGLIB - if (!mem) - mem = ReadJPEGFile((qbyte *)data, com_filesize, &pic->pic.width, &height); -#endif - if (!mem) - mem = ReadPCXFile((qbyte *)data, com_filesize, &pic->pic.width, &height); - pic->pic.height = height; - if (mem) - { - gl = &pic->pic.d.gl; - if (!(gl->texnum = Mod_LoadReplacementTexture(alternatename, NULL, false, true, false))) - gl->texnum = GL_LoadTexture32(path, pic->pic.width, pic->pic.height, (unsigned *)mem, false, true); - gl->sl = 0; - gl->sh = 1; - gl->tl = 0; - gl->th = 1; - - BZ_Free(data); - BZ_Free(mem); - glmenu_numcachepics++; - return &pic->pic; - } - FS_FreeFile(data); - } - } - -#ifdef AVAIL_JPEGLIB - { - char *mem; - char alternatename[MAX_QPATH]; - snprintf(alternatename, MAX_QPATH-1,"%s.jpg", path); - FS_LoadFile(alternatename, (void**)&data); - if (data) - { - strcpy(pic->name, path); - if ((mem = ReadJPEGFile(data, com_filesize, &pic->pic.width, &height))) - { - pic->pic.height = height; - gl = &pic->pic.d.gl; - if (!(gl->texnum = Mod_LoadReplacementTexture(alternatename, NULL, false, true, false))) - gl->texnum = GL_LoadTexture32(path, pic->pic.width, pic->pic.height, (unsigned *)mem, false, false); - gl->sl = 0; - gl->sh = 1; - gl->tl = 0; - gl->th = 1; - - BZ_Free(data); - BZ_Free(mem); - glmenu_numcachepics++; - return &pic->pic; - } - FS_FreeFile(data); - } - } -#endif -/* - { - char *mem; - char alternatename[MAX_QPATH]; - _snprintf(alternatename, MAX_QPATH-1,"%s.tga", path); - dat = (qpic_t *)COM_LoadMallocFile (alternatename); - if (dat) - { - strcpy(pic->name, path); - if (mem = ReadTargaFile ((qbyte *)dat, com_filesize, &pic->pic.width, &pic->pic.height, false)) - { - gl = &pic->pic.d.gl; - if (!(gl->texnum = Mod_LoadReplacementTexture(alternatename, false, true))) - gl->texnum = GL_LoadTexture32(path, pic->pic.width, pic->pic.height, (unsigned *)dat, false, true); - gl->sl = 0; - gl->sh = 1; - gl->tl = 0; - gl->th = 1; - - BZ_Free(dat); - BZ_Free(mem); - glmenu_numcachepics++; - return &pic->pic; - } - BZ_Free(dat); - } - } -*/ - qpic = (qpic_t *)COM_LoadTempFile (path); - if (!qpic) - { - char alternatename[MAX_QPATH]; - sprintf(alternatename, "gfx/%s.lmp", path); - qpic = (qpic_t *)COM_LoadTempFile (alternatename); - if (!qpic) - { - mpic_t *m; - m = GLDraw_SafePicFromWad(path); - return m; - } - } - - SwapPic (qpic); - - if (((8+qpic->width*qpic->height+3)&(~3)) != ((com_filesize+3)&(~3))) //round up to the nearest 4. - { //the filesize didn't match what we were expecting, so it can't be a lmp. reject it. - char alternatename[MAX_QPATH]; - sprintf(alternatename, "gfx/%s.lmp", path); - qpic = (qpic_t *)COM_LoadTempFile (alternatename); - if (!qpic) - return GLDraw_SafePicFromWad(path); - SwapPic (qpic); - } - - { - glmenu_numcachepics++; - Q_strncpyz (pic->name, path, sizeof(pic->name)); - } - - pic->pic.width = qpic->width; - pic->pic.height = qpic->height; - - gl = &pic->pic.d.gl; - if (!(gl->texnum = Mod_LoadReplacementTexture(path, NULL, false, true, false))) - gl->texnum = GL_LoadPicTexture (qpic); - gl->sl = 0; - gl->sh = 1; - gl->tl = 0; - gl->th = 1; - - return &pic->pic; -} -mpic_t *GLDraw_CachePic (char *path) -{ - mpic_t *pic = GLDraw_SafeCachePic (path); - if (!pic) - Sys_Error ("GLDraw_CachePic: failed to load %s", path); - - return pic; -} - -void GLDraw_CharToConback (int num, qbyte *dest) -{ - int row, col; - qbyte *source; - int drawline; - int x; - - row = num>>4; - col = num&15; - source = draw_chars + (row<<10) + (col<<3); - - drawline = 8; - - while (drawline--) - { - for (x=0 ; x<8 ; x++) - if (source[x] != 255) - dest[x] = 0x60 + source[x]; - source += 128; - dest += 320; - } - -} - typedef struct { char *name; @@ -617,11 +215,10 @@ void GL_Texture_Anisotropic_Filtering_Callback (struct cvar_s *var, char *oldval /* change all the existing max anisotropy settings */ for (glt = gltextures; glt ; glt = glt->next) //redo anisotropic filtering when map is changed { - if (glt->mipmap) + if (!(glt->flags & IF_NOMIPMAP)) { - //qglBindTexture (GL_TEXTURE_2D, glt->texnum); GL_Bind (glt->texnum); - qglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)anfactor); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, anfactor); } } @@ -663,11 +260,11 @@ void GL_Texturemode_Callback (struct cvar_s *var, char *oldvalue) // change all the existing mipmap texture objects for (glt=gltextures ; glt ; glt=glt->next) { - if (glt->mipmap) + if (!(glt->flags & IF_NOMIPMAP)) { GL_Bind (glt->texnum); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); } } } @@ -698,22 +295,14 @@ void GL_Texturemode2d_Callback (struct cvar_s *var, char *oldvalue) // change all the existing mipmap texture objects for (glt=gltextures ; glt ; glt=glt->next) { - if (!glt->mipmap) + if (glt->flags & IF_NOMIPMAP) { - //texture2d sampling modes do not affect conchars, use gl_smoothfont for that. - if (glt->texnum == char_texture || glt->texnum == default_char_texture || glt->texnum == char_tex2) - continue; - GL_Bind (glt->texnum); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max_2d); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max_2d); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max_2d); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max_2d); } } - Scrap_Upload(); } - -#ifdef Q3SHADERS -#endif /* =============== Draw_Init @@ -722,18 +311,7 @@ Draw_Init void GLDraw_ReInit (void) { - int i; - qpic_t *cb; - qbyte *dest; - int x; char ver[40]; - glpic_t *gl; - qpic_t *bigfont; - int start; - qbyte *ncdata; - qbyte *pal; - qbyte *tinyfont; - extern int skyboxtex[6]; extern int *lightmap_textures; int maxtexsize; @@ -751,28 +329,14 @@ void GLDraw_ReInit (void) memset(gltexturetablebuckets, 0, sizeof(gltexturetablebuckets)); Hash_InitTable(&gltexturetable, sizeof(gltexturetablebuckets)/sizeof(gltexturetablebuckets[0]), gltexturetablebuckets); - - skyboxtex[0] = 0; skyboxtex[1] = 0; skyboxtex[2] = 0; skyboxtex[3] = 0; skyboxtex[4] = 0; skyboxtex[5] = 0; lightmap_textures=NULL; - filmtexture=0; - glmenu_numcachepics=0; - - draw_mesh.numvertexes = 4; - draw_mesh.numindexes = 6; - draw_mesh.xyz_array = draw_mesh_xyz; - draw_mesh.st_array = draw_mesh_st; - draw_mesh.colors_array = NULL; - draw_mesh.indexes = r_quad_indexes; + filmtexture=r_nulltex; GL_FlushBackEnd(); // GL_FlushSkinCache(); TRACE(("dbg: GLDraw_ReInit: GL_GAliasFlushSkinCache\n")); GL_GAliasFlushSkinCache(); - memset(scrap_allocated, 0, sizeof(scrap_allocated)); - memset(scrap_texels, 255, sizeof(scrap_texels)); - - qglGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxtexsize); if (gl_max_size.value > maxtexsize) { @@ -780,6 +344,8 @@ void GLDraw_ReInit (void) Cvar_ForceSet (&gl_max_size, ver); } + maxtexsize = gl_max_size.value; + if (maxtexsize < 2048) //this needs to be able to hold the image in unscaled form. sizeofuploadmemorybufferintermediate = 2048*2048*4; //make sure we can load 2048*2048 images whatever happens. else @@ -791,122 +357,10 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n")); uploadmemorybuffer = BZ_Realloc(uploadmemorybuffer, sizeofuploadmemorybuffer); uploadmemorybufferintermediate = BZ_Realloc(uploadmemorybufferintermediate, sizeofuploadmemorybufferintermediate); - // load the console background and the charset - // by hand, because we need to write the version - // string into the background before turning - // it into a texture - draw_chars = W_SafeGetLumpName ("conchars"); - if (draw_chars) - { - // add ocrana leds - if (con_ocranaleds.value) - { - if (con_ocranaleds.value != 2 || QCRC_Block(draw_chars, 128*128) == 798) - AddOcranaLEDsIndexed (draw_chars, 128, 128); - } - - for (i=0 ; i<128*128 ; i++) - if (draw_chars[i] == 0) - draw_chars[i] = 255; // proper transparent color - } - - // now turn them into textures - image_width = 0; - image_height = 0; - TRACE(("dbg: GLDraw_ReInit: looking for conchars\n")); - if (!(char_texture=Mod_LoadReplacementTexture("gfx/conchars.lmp", NULL, false, true, false))) //no high res - { - if (!draw_chars) //or low res. - { - if (!(char_texture=Mod_LoadHiResTexture("pics/conchars.pcx", NULL, false, true, false))) //try low res q2 path - if (!(char_texture=Mod_LoadHiResTexture("gfx/2d/bigchars.tga", NULL, false, true, false))) //try q3 path - { - - //gulp... so it's come to this has it? rework the hexen2 conchars into the q1 system. - char *tempchars; - char *in, *out; - FS_LoadFile("gfx/menu/conchars.lmp", (void**)&tempchars); - if (tempchars) - { - draw_chars = BZ_Malloc(8*8*256*8); - - out = draw_chars; - for (i = 0; i < 8*8; i+=1) - { - if ((i/8)&1) - { - in = tempchars + ((i)/8)*16*8*8+(i&7)*32*8 - 256*4+128; - for (x = 0; x < 16*8; x++) - *out++ = *in++; - } - else - { - in = tempchars + (i/8)*16*8*8+(i&7)*32*8; - for (x = 0; x < 16*8; x++) - *out++ = *in++; - } - } - for (i = 0; i < 8*8; i+=1) - { - if ((i/8)&1) - { - in = tempchars+128*128 + ((i)/8)*16*8*8+(i&7)*32*8 - 256*4+128; - for (x = 0; x < 16*8; x++) - *out++ = *in++; - } - else - { - in = tempchars+128*128 + (i/8)*16*8*8+(i&7)*32*8; - for (x = 0; x < 16*8; x++) - *out++ = *in++; - } - } - FS_FreeFile(tempchars); - - // add ocrana leds - if (con_ocranaleds.value && con_ocranaleds.value != 2) - AddOcranaLEDsIndexed (draw_chars, 128, 128); - - for (i=0 ; i<128*128 ; i++) - if (draw_chars[i] == 0) - draw_chars[i] = 255; // proper transparent color - char_texture = GL_LoadTexture ("charset", 128, 128, draw_chars, false, true); - Z_Free(draw_chars); - draw_chars = NULL; - } - else - { - extern qbyte default_conchar[11356]; - int width, height; - int i; - qbyte *image; - - image = ReadTargaFile(default_conchar, sizeof(default_conchar), &width, &height, false); - for (i = 0; i < width*height; i++) - { - image[i*4+3] = image[i*4]; - image[i*4+0] = 255; - image[i*4+1] = 255; - image[i*4+2] = 255; - } - char_texture = GL_LoadTexture32("charset", width, height, (void*)image, false, true); - } - } - } - else - char_texture = GL_LoadTexture ("charset", 128, 128, draw_chars, false, true); - } - default_char_texture=char_texture; - //half a pixel - if (image_width) - custom_char_instep = default_char_instep = 0.5f/((image_width+image_height)/2); //you're an idiot if you use non-square conchars - else - custom_char_instep = default_char_instep = 0.5f/(128); - - TRACE(("dbg: GLDraw_ReInit: loaded charset\n")); + R2D_Init(); TRACE(("dbg: GLDraw_ReInit: GL_BeginRendering\n")); - GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + GL_BeginRendering (); TRACE(("dbg: GLDraw_ReInit: SCR_DrawLoading\n")); GL_Set2D(); @@ -915,226 +369,32 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n")); { mpic_t *pic = Draw_SafeCachePic ("gfx/loading.lmp"); if (pic) - Draw_Pic ( ((int)vid.width - pic->width)/2, - ((int)vid.height - 48 - pic->height)/2, pic); + Draw_ScalePic ( ((int)vid.width - pic->width)/2, + ((int)vid.height - 48 - pic->height)/2, pic->width, pic->height, pic); } TRACE(("dbg: GLDraw_ReInit: GL_EndRendering\n")); GL_EndRendering (); GL_DoSwap(); + Font_Init(); -#ifdef Q3SHADERS Shader_Init(); -#endif - //now emit the conchars picture as if from a wad. - strcpy(glmenu_cachepics[glmenu_numcachepics].name, "conchars"); - glmenu_cachepics[glmenu_numcachepics].pic.width = 128; - glmenu_cachepics[glmenu_numcachepics].pic.height = 128; - gl = &glmenu_cachepics[glmenu_numcachepics].pic.d.gl; - gl->texnum = char_texture; - gl->sl = 0; - gl->tl = 0; - gl->sh = 1; - gl->th = 1; - glmenu_numcachepics++; - - char_texturetiny = 0; - TRACE(("dbg: GLDraw_ReInit: W_SafeGetLumpName\n")); - tinyfont = W_SafeGetLumpName ("tinyfont"); - if (tinyfont) - { - for (i=0 ; i<128*32 ; i++) - if (tinyfont[i] == 0) - tinyfont[i] = 255; // proper transparent color - strcpy(glmenu_cachepics[glmenu_numcachepics].name, "tinyfont"); - glmenu_cachepics[glmenu_numcachepics].pic.width = 128; - glmenu_cachepics[glmenu_numcachepics].pic.height = 32; - gl = &glmenu_cachepics[glmenu_numcachepics].pic.d.gl; - char_texturetiny = gl->texnum = GL_LoadTexture ("tinyfont", 128, 32, tinyfont, false, true); - gl->sl = 0; - gl->tl = 0; - gl->sh = 1; - gl->th = 1; - glmenu_numcachepics++; - } - TRACE(("dbg: GLDraw_ReInit: gfx/menu/bigfont\n")); - FS_LoadFile("gfx/menu/bigfont.lmp", (void**)&bigfont); - if (bigfont) - { - char *data; - data = bigfont->data; - for (i=0 ; iwidth*bigfont->height ; i++) - if (data[i] == 0) - data[i] = 255; // proper transparent color - strcpy(glmenu_cachepics[glmenu_numcachepics].name, "gfx/menu/bigfont.lmp"); - glmenu_cachepics[glmenu_numcachepics].pic.width = bigfont->width; - glmenu_cachepics[glmenu_numcachepics].pic.height = bigfont->height; - gl = &glmenu_cachepics[glmenu_numcachepics].pic.d.gl; - gl->texnum = GL_LoadTexture ("gfx/menu/bigfont.lmp", bigfont->width, bigfont->height, data, false, true); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - gl->sl = 0; - gl->tl = 0; - gl->sh = 1; - gl->th = 1; - glmenu_numcachepics++; - FS_FreeFile(bigfont); - } - - - TRACE(("dbg: GLDraw_ReInit: gfx/conchars2.lmp\n")); - if (!(char_tex2=Mod_LoadReplacementTexture("gfx/conchars2.lmp", NULL, false, true, false))) - { - if (!draw_chars) - char_tex2 = char_texture; - else - char_tex2 = GL_LoadTexture ("charset", 128, 128, draw_chars, false, true); - } - cs_texture = GL_AllocNewTexture(); - missing_texture = GL_LoadTexture("no_texture", 16, 16, (unsigned char*)r_notexture_mip + r_notexture_mip->offsets[0], true, false); + missing_texture = GL_LoadTexture("no_texture", 16, 16, (unsigned char*)r_notexture_mip + r_notexture_mip->offsets[0], IF_NOALPHA|IF_NOGAMMA, 0); GL_SetupSceneProcessingTextures(); - start = Hunk_LowMark (); - conback = default_conback; - - TRACE(("dbg: GLDraw_ReInit: COM_FDepthFile(\"gfx/conback.lmp\", false)\n")); - if (COM_FDepthFile("gfx/conback.lmp", false) <= COM_FDepthFile("gfx/menu/conback.lmp", false)) - cb = (qpic_t *)COM_LoadHunkFile ("gfx/conback.lmp"); - else - cb = (qpic_t *)COM_LoadHunkFile ("gfx/menu/conback.lmp"); - if (cb) - { - TRACE(("dbg: GLDraw_ReInit: conback opened\n")); - SwapPic (cb); - - if (draw_chars) - { - sprintf (ver, "%i", build_number()); - dest = cb->data + 320 + 320*186 - 11 - 8*strlen(ver); - for (x=0 ; xwidth = vid.conwidth; - conback->height = vid.conheight; - - // scale console to vid size - dest = ncdata = Hunk_AllocName(vid.conwidth * vid.conheight, "conback"); - - TRACE(("dbg: GLDraw_ReInit: conback loading\n"); - for (y=0 ; ydata + cb->width * (y*cb->height/vid.conheight); - if (vid.conwidth == cb->width) - memcpy (dest, src, vid.conwidth); - else - { - f = 0; - fstep = cb->width*0x10000/vid.conwidth; - for (x=0 ; x>16]; - f += fstep; - dest[x+1] = src[f>>16]; - f += fstep; - dest[x+2] = src[f>>16]; - f += fstep; - dest[x+3] = src[f>>16]; - f += fstep; - } - } - } - pal = NULL; -#else - conback->width = cb->width; - conback->height = cb->height; - ncdata = cb->data; - - if (com_filesize == cb->width*cb->height+10 + 256*3) - { - pal = ncdata + cb->width*cb->height + 2; - } - else - pal = NULL; -#endif - } - else - { - ncdata = NULL; - pal = 0; - } - - TRACE(("dbg: GLDraw_ReInit: conback loaded\n")); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - gl = &conback->d.gl; - if (!(gl->texnum=Mod_LoadReplacementTexture("gfx/conback.lmp", NULL, false, true, false))) - { - if (!ncdata) //no fallback - { - if (!(gl->texnum=Mod_LoadHiResTexture("pics/conback.pcx", NULL, false, true, false))) - if (!(gl->texnum=Mod_LoadReplacementTexture("gfx/menu/conback.lmp", NULL, false, true, false))) - if (!(gl->texnum=Mod_LoadReplacementTexture("textures/sfx/logo512.jpg", NULL, false, false, false))) - { - int data = 0; - gl->texnum = GL_LoadTexture32("gfx/conback.lmp", 1, 1, (unsigned int *)&data, false, false); - } - } - else - { - if (pal) - gl->texnum = GL_LoadTexture8Pal24("conback", conback->width, conback->height, ncdata, pal, false, false); - else - gl->texnum = GL_LoadTexture ("conback", conback->width, conback->height, ncdata, false, false); - } - } - gl->sl = 0; - gl->sh = 1; - gl->tl = 0; - gl->th = 1; - conback->width = vid.conwidth; - conback->height = vid.conheight; - - memcpy(custconback_buffer, conback_buffer, sizeof(custconback_buffer)); - - custom_conback->width = vid.conwidth; - custom_conback->height = vid.conheight; - gl = &custom_conback->d.gl; - gl->texnum = 0; - gl->sl = 0; - gl->sh = 1; - gl->tl = 0; - gl->th = 1; - custom_conback->width = vid.conwidth; - custom_conback->height = vid.conheight; - - // free loaded console - Hunk_FreeToLowMark (start); - // save a texture slot for translated picture translate_texture = GL_AllocNewTexture(); - // save slots for scraps - for (i = 0; i < MAX_SCRAPS; i++) - scrap_texnum[i] = GL_AllocNewTexture(); - // // get the other pics we need // TRACE(("dbg: GLDraw_ReInit: Draw_SafePicFromWad\n")); draw_disc = Draw_SafePicFromWad ("disc"); - draw_backtile = Draw_SafePicFromWad ("backtile"); - if (!draw_backtile) - draw_backtile = Draw_SafeCachePic ("gfx/menu/backtile.lmp"); - - detailtexture = Mod_LoadHiResTexture("textures/detail", NULL, true, false, false); inited15to8 = false; @@ -1143,8 +403,6 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n")); TRACE(("dbg: GLDraw_ReInit: PPL_LoadSpecularFragmentProgram\n")); PPL_CreateShaderObjects(); - GL_Warp_Init(); - #ifdef PLUGINS Plug_DrawReloadImages(); #endif @@ -1152,39 +410,23 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n")); void GLDraw_Init (void) { - - memset(scrap_allocated, 0, sizeof(scrap_allocated)); - memset(scrap_texels, 255, sizeof(scrap_texels)); +// memset(scrap_allocated, 0, sizeof(scrap_allocated)); +// memset(scrap_texels, 255, sizeof(scrap_texels)); GLDraw_ReInit(); - R_BackendInit(); -#ifdef NEWBACKEND - BE_Init(); -#endif - - - - draw_mesh.numindexes = 6; - draw_mesh.indexes = r_quad_indexes; - draw_mesh.trneighbors = NULL; - - draw_mesh.numvertexes = 4; - draw_mesh.xyz_array = draw_mesh_xyz; - draw_mesh.normals_array = NULL; - draw_mesh.st_array = draw_mesh_st; - draw_mesh.lmst_array = NULL; - + R2D_Init(); } void GLDraw_DeInit (void) { Cmd_RemoveCommand ("gl_texture_anisotropic_filtering"); -#ifdef AVAIL_FREETYPE - if (conchar_font) - Font_Free(conchar_font); - conchar_font = NULL; - Font_Shutdown(); -#endif + + if (font_conchar) + Font_Free(font_conchar); + font_conchar = NULL; + if (font_tiny) + Font_Free(font_tiny); + font_tiny = NULL; draw_disc = NULL; @@ -1197,189 +439,7 @@ void GLDraw_DeInit (void) sizeofuploadmemorybuffer = 0; //and give a nice safe sys_error if we try using it. sizeofuploadmemorybufferintermediate = 0; -#ifdef Q3SHADERS Shader_Shutdown(); -#endif -} - -void GL_DrawAliasMesh (mesh_t *mesh, int texnum); - -void GL_DrawMesh(mesh_t *msh, int texturenum) -{ - GL_DrawAliasMesh(msh, texturenum); -} - - -void GLDraw_TinyCharacter (int x, int y, unsigned int num) -{ - int row, col; - float frow, fcol, sizex, sizey; - - if (y <= -6) - return; // totally off screen - - num &= 127; - - if(num <= 32) - return; - else if(num >= 'a' && num <= 'z') - num -= 64; - else if(num > '_') - return; - else - num -= 32; - - row = num>>4; - col = num&15; - - sizex = 0.0625; - sizey = 0.25; - frow = row*sizey; - fcol = col*sizex; - draw_mesh_xyz[0][0] = x; - draw_mesh_xyz[0][1] = y; - draw_mesh_st[0][0] = fcol; - draw_mesh_st[0][1] = frow; - - draw_mesh_xyz[1][0] = x+8; - draw_mesh_xyz[1][1] = y; - draw_mesh_st[1][0] = fcol+sizex; - draw_mesh_st[1][1] = frow; - - draw_mesh_xyz[2][0] = x+8; - draw_mesh_xyz[2][1] = y+8; - draw_mesh_st[2][0] = fcol+sizex; - draw_mesh_st[2][1] = frow+sizey; - - draw_mesh_xyz[3][0] = x; - draw_mesh_xyz[3][1] = y+8; - draw_mesh_st[3][0] = fcol; - draw_mesh_st[3][1] = frow+sizey; - - qglEnable(GL_BLEND); - qglDisable(GL_ALPHA_TEST); - - GL_DrawMesh(&draw_mesh, char_texturetiny); -} - -/* -================ -Draw_Character - -Draws one 8*8 graphics character with 0 being transparent. -It can be clipped to the top of the screen to allow the console to be -smoothly scrolled off. -================ -*/ -void GLDraw_Character (int x, int y, unsigned int num) -{ - int row, col; - float frow, fcol, size; - - if (y <= -8) - return; // totally off screen - - num &= CON_CHARMASK; - if (num == 32) - return; // space -// if ((num&0xff00) != 0xe000 && num & ~0x7f) -// num = '?'; - - row = num>>4; - col = num&15; - - frow = row*0.0625+char_instep; - fcol = col*0.0625+char_instep; - size = 0.0625-char_instep*2; - draw_mesh_xyz[0][0] = x; - draw_mesh_xyz[0][1] = y; - draw_mesh_st[0][0] = fcol; - draw_mesh_st[0][1] = frow; - - draw_mesh_xyz[1][0] = x+8; - draw_mesh_xyz[1][1] = y; - draw_mesh_st[1][0] = fcol+size; - draw_mesh_st[1][1] = frow; - - draw_mesh_xyz[2][0] = x+8; - draw_mesh_xyz[2][1] = y+8; - draw_mesh_st[2][0] = fcol+size; - draw_mesh_st[2][1] = frow+size; - - draw_mesh_xyz[3][0] = x; - draw_mesh_xyz[3][1] = y+8; - draw_mesh_st[3][0] = fcol; - draw_mesh_st[3][1] = frow+size; - - qglEnable(GL_BLEND); - qglDisable(GL_ALPHA_TEST); - - if (num&CON_2NDCHARSETTEXT) - GL_DrawMesh(&draw_mesh, char_tex2); - else - GL_DrawMesh(&draw_mesh, char_texture); -} - -void GLDraw_FillRGB (int x, int y, int w, int h, float r, float g, float b); -void GLDraw_ColouredCharacter (int x, int y, unsigned int num) -{ - unsigned int col; - - // draw background - if (num & CON_NONCLEARBG) - { - col = (num & CON_BGMASK) >> CON_BGSHIFT; - GLDraw_FillRGB(x, y, 8, 8, consolecolours[col].fr, consolecolours[col].fg, consolecolours[col].fb); - } - - if (num & CON_BLINKTEXT) - { - if (!cl_noblink.value) - if ((int)(realtime*3) & 1) - return; - } - - // render character with foreground color - col = (num & CON_FGMASK) >> CON_FGSHIFT; - qglColor4f(consolecolours[col].fr, consolecolours[col].fg, consolecolours[col].fb, (num & CON_HALFALPHA)?0.5:1); - Draw_Character(x, y, num); -} -/* -================ -Draw_String -================ -*/ -void GLDraw_String (int x, int y, const qbyte *str) -{ - float xstart = x; - while (*str) - { - if (*str == '\n') - { - x = xstart; - y += 8; - str++; - continue; - } - Draw_Character (x, y, *str); - str++; - x += 8; - } -} - -/* -================ -Draw_Alt_String -================ -*/ -void GLDraw_Alt_String (int x, int y, const qbyte *str) -{ - while (*str) - { - Draw_Character (x, y, (*str) | 0x80); - str++; - x += 8; - } } #include "crosshairs.dat" @@ -1388,7 +448,7 @@ vec3_t chcolor; void GLCrosshairimage_Callback(struct cvar_s *var, char *oldvalue) { if (*(var->string)) - externalhair = Mod_LoadHiResTexture (var->string, "crosshairs", false, true, true); + externalhair = R_LoadHiResTexture (var->string, "crosshairs", IF_NOMIPMAP); } void GLCrosshair_Callback(struct cvar_s *var, char *oldvalue) @@ -1420,9 +480,7 @@ void GLCrosshair_Callback(struct cvar_s *var, char *oldvalue) } #undef Pix - GL_Bind (cs_texture); - GL_Upload32(NULL, cs_data, 16, 16, 0, true); - + R_Upload(cs_texture, NULL, TF_RGBA32, cs_data, 16, 16, IF_NOMIPMAP|IF_NOGAMMA); } void GLCrosshaircolor_Callback(struct cvar_s *var, char *oldvalue) @@ -1446,16 +504,17 @@ void GLDraw_Crosshair(void) qboolean usingimage = false; - if (crosshair.value == 1 && !*crosshairimage.string) + if (crosshair.ival == 1 && !*crosshairimage.string) { for (sc = 0; sc < cl.splitclients; sc++) { SCR_CrosshairPosition(sc, &x, &y); - GLDraw_Character (x-4, y-4, '+'); + Font_BeginString(font_conchar, x, y, &x, &y); + Font_DrawChar(x-4, y-4, '+' | 0xe000 | CON_WHITEMASK); + Font_EndString(font_conchar); } return; } - GL_TexEnv(GL_MODULATE); if (*crosshairimage.string) { @@ -1466,7 +525,7 @@ void GLDraw_Crosshair(void) qglEnable (GL_BLEND); qglDisable(GL_ALPHA_TEST); } - else if (crosshair.value) + else if (crosshair.ival) { GL_Bind (cs_texture); chc = 1/16.0; @@ -1475,7 +534,7 @@ void GLDraw_Crosshair(void) if (crosshair.value >= FIRSTANIMATEDCROSHAIR) GLCrosshair_Callback(&crosshair, ""); - if (crosshairalpha.value<1) + if (crosshairalpha.ival<1) { qglEnable (GL_BLEND); qglDisable(GL_ALPHA_TEST); @@ -1489,23 +548,25 @@ void GLDraw_Crosshair(void) else return; + GL_TexEnv(GL_MODULATE); + if (usingimage) - qglColor4f(chcolor[0], chcolor[1], chcolor[2], crosshairalpha.value); + qglColor4f(chcolor[0], chcolor[1], chcolor[2], crosshairalpha.ival); else qglColor4f(1, 1, 1, crosshairalpha.value); size = crosshairsize.value; chc = size * chc; - if (gl_smoothcrosshair.value && (size > 16 || usingimage)) + if (gl_smoothcrosshair.ival && (size > 16 || usingimage)) { - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } else { - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } for (sc = 0; sc < cl.splitclients; sc++) @@ -1528,314 +589,12 @@ void GLDraw_Crosshair(void) qglEnd (); } -// GL_TexEnv ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); -// GL_TexEnv ( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); +// GL_TexEnv ( GL_REPLACE ); +// GL_TexEnv ( GL_MODULATE ); qglColor4f(1, 1, 1, 1); } - -/* -================ -Draw_DebugChar - -Draws a single character directly to the upper right corner of the screen. -This is for debugging lockups by drawing different chars in different parts -of the code. -================ -*/ -void GLDraw_DebugChar (qbyte num) -{ -} - -/* -============= -Draw_Pic -============= -*/ -void GLDraw_Pic (int x, int y, mpic_t *pic) -{ - glpic_t *gl; - - if (!pic) - return; - - if (scrap_dirty) - Scrap_Upload (); - gl = &pic->d.gl; - - draw_mesh_xyz[0][0] = x; - draw_mesh_xyz[0][1] = y; - draw_mesh_st[0][0] = gl->sl; - draw_mesh_st[0][1] = gl->tl; - - draw_mesh_xyz[1][0] = x+pic->width; - draw_mesh_xyz[1][1] = y; - draw_mesh_st[1][0] = gl->sh; - draw_mesh_st[1][1] = gl->tl; - - draw_mesh_xyz[2][0] = x+pic->width; - draw_mesh_xyz[2][1] = y+pic->height; - draw_mesh_st[2][0] = gl->sh; - draw_mesh_st[2][1] = gl->th; - - draw_mesh_xyz[3][0] = x; - draw_mesh_xyz[3][1] = y+pic->height; - draw_mesh_st[3][0] = gl->sl; - draw_mesh_st[3][1] = gl->th; - - if (gl_blend2d.value) - { - qglDisable(GL_ALPHA_TEST); - qglEnable(GL_BLEND); - } - else - { - qglEnable(GL_ALPHA_TEST); - qglDisable(GL_BLEND); - } - - GL_DrawMesh(&draw_mesh, gl->texnum); -} - -#ifdef Q3SHADERS -void GLDraw_ShaderPic (int x, int y, int width, int height, shader_t *pic, float r, float g, float b, float a) -{ - meshbuffer_t mb; - - if (!pic) - return; - - R_IBrokeTheArrays(); - - mb.entity = &r_worldentity; - mb.shader = pic; - mb.fog = NULL; - mb.mesh = &draw_mesh; - mb.infokey = 0; - mb.dlightbits = 0; - - - draw_mesh_xyz[0][0] = x; - draw_mesh_xyz[0][1] = y; - draw_mesh_st[0][0] = 0; - draw_mesh_st[0][1] = 0; - - draw_mesh_xyz[1][0] = x+width; - draw_mesh_xyz[1][1] = y; - draw_mesh_st[1][0] = 1; - draw_mesh_st[1][1] = 0; - - draw_mesh_xyz[2][0] = x+width; - draw_mesh_xyz[2][1] = y+height; - draw_mesh_st[2][0] = 1; - draw_mesh_st[2][1] = 1; - - draw_mesh_xyz[3][0] = x; - draw_mesh_xyz[3][1] = y+height; - draw_mesh_st[3][0] = 0; - draw_mesh_st[3][1] = 1; - - draw_mesh_colors[0][0] = r*255; - draw_mesh_colors[0][1] = g*255; - draw_mesh_colors[0][2] = b*255; - draw_mesh_colors[0][3] = a*255; - ((int*)draw_mesh_colors)[1] = ((int*)draw_mesh_colors)[0]; - ((int*)draw_mesh_colors)[2] = ((int*)draw_mesh_colors)[0]; - ((int*)draw_mesh_colors)[3] = ((int*)draw_mesh_colors)[0]; - - draw_mesh.colors_array = draw_mesh_colors; - - R_PushMesh(&draw_mesh, mb.shader->features | MF_COLORS | MF_NONBATCHED); - R_RenderMeshBuffer ( &mb, false ); - draw_mesh.colors_array = NULL; - - qglEnable(GL_BLEND); -} - -void GLDraw_ShaderImage (int x, int y, int w, int h, float s1, float t1, float s2, float t2, shader_t *pic) -{ - meshbuffer_t mb; - - if (!pic) - return; - - R_IBrokeTheArrays(); - - mb.entity = &r_worldentity; - mb.shader = pic; - mb.fog = NULL; - mb.mesh = &draw_mesh; - mb.infokey = -1; - mb.dlightbits = 0; - - - draw_mesh_xyz[0][0] = x; - draw_mesh_xyz[0][1] = y; - draw_mesh_st[0][0] = s1; - draw_mesh_st[0][1] = t1; - - draw_mesh_xyz[1][0] = x+w; - draw_mesh_xyz[1][1] = y; - draw_mesh_st[1][0] = s2; - draw_mesh_st[1][1] = t1; - - draw_mesh_xyz[2][0] = x+w; - draw_mesh_xyz[2][1] = y+h; - draw_mesh_st[2][0] = s2; - draw_mesh_st[2][1] = t2; - - draw_mesh_xyz[3][0] = x; - draw_mesh_xyz[3][1] = y+h; - draw_mesh_st[3][0] = s1; - draw_mesh_st[3][1] = t2; - -/* draw_mesh_colors[0][0] = r*255; - draw_mesh_colors[0][1] = g*255; - draw_mesh_colors[0][2] = b*255; - draw_mesh_colors[0][3] = a*255; - ((int*)draw_mesh_colors)[1] = ((int*)draw_mesh_colors)[0]; - ((int*)draw_mesh_colors)[2] = ((int*)draw_mesh_colors)[0]; - ((int*)draw_mesh_colors)[3] = ((int*)draw_mesh_colors)[0]; -*/ -/* - draw_mesh_colors[0][0] = 255; - draw_mesh_colors[0][1] = 255; - draw_mesh_colors[0][2] = 255; - draw_mesh_colors[0][3] = 255; -*/ - draw_mesh.colors_array = draw_mesh_colors; - - draw_mesh.numvertexes = 4; - draw_mesh.numindexes = 6; - - R_PushMesh(&draw_mesh, mb.shader->features | MF_COLORS | MF_NONBATCHED); - R_RenderMeshBuffer ( &mb, false ); - draw_mesh.colors_array = NULL; - qglEnable(GL_BLEND); -} -#endif - -void GLDraw_ScalePic (int x, int y, int width, int height, mpic_t *pic) -{ - glpic_t *gl; - - if (!pic) - return; - - if (scrap_dirty) - Scrap_Upload (); - gl = &pic->d.gl; -// qglColor4f (1,1,1,1); - GL_Bind (gl->texnum); - qglBegin (GL_QUADS); - qglTexCoord2f (gl->sl, gl->tl); - qglVertex2f (x, y); - qglTexCoord2f (gl->sh, gl->tl); - qglVertex2f (x+width, y); - qglTexCoord2f (gl->sh, gl->th); - qglVertex2f (x+width, y+height); - qglTexCoord2f (gl->sl, gl->th); - qglVertex2f (x, y+height); - qglEnd (); -} - -/* -============= -Draw_AlphaPic -============= -*/ -void GLDraw_AlphaPic (int x, int y, mpic_t *pic, float alpha) -{ - glpic_t *gl; - - if (scrap_dirty) - Scrap_Upload (); - gl = &pic->d.gl; - qglDisable(GL_ALPHA_TEST); - qglEnable (GL_BLEND); -// qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - qglCullFace(GL_FRONT); - qglColor4f (1,1,1,alpha); - GL_Bind (gl->texnum); - qglBegin (GL_QUADS); - qglTexCoord2f (gl->sl, gl->tl); - qglVertex2f (x, y); - qglTexCoord2f (gl->sh, gl->tl); - qglVertex2f (x+pic->width, y); - qglTexCoord2f (gl->sh, gl->th); - qglVertex2f (x+pic->width, y+pic->height); - qglTexCoord2f (gl->sl, gl->th); - qglVertex2f (x, y+pic->height); - qglEnd (); - qglColor4f (1,1,1,1); - qglEnable(GL_ALPHA_TEST); - qglDisable (GL_BLEND); -} - -void GLDraw_SubPic(int x, int y, mpic_t *pic, int srcx, int srcy, int width, int height) -{ - glpic_t *gl; - float newsl, newtl, newsh, newth; - float oldglwidth, oldglheight; - - if (scrap_dirty) - Scrap_Upload (); - gl = &pic->d.gl; - - oldglwidth = gl->sh - gl->sl; - oldglheight = gl->th - gl->tl; - - newsl = gl->sl + (srcx*oldglwidth)/pic->width; - newsh = newsl + (width*oldglwidth)/pic->width; - - newtl = gl->tl + (srcy*oldglheight)/pic->height; - newth = newtl + (height*oldglheight)/pic->height; - - draw_mesh_xyz[0][0] = x; - draw_mesh_xyz[0][1] = y; - draw_mesh_st[0][0] = newsl; - draw_mesh_st[0][1] = newtl; - - draw_mesh_xyz[1][0] = x+width; - draw_mesh_xyz[1][1] = y; - draw_mesh_st[1][0] = newsh; - draw_mesh_st[1][1] = newtl; - - draw_mesh_xyz[2][0] = x+width; - draw_mesh_xyz[2][1] = y+height; - draw_mesh_st[2][0] = newsh; - draw_mesh_st[2][1] = newth; - - draw_mesh_xyz[3][0] = x; - draw_mesh_xyz[3][1] = y+height; - draw_mesh_st[3][0] = newsl; - draw_mesh_st[3][1] = newth; - - GL_DrawMesh(&draw_mesh, gl->texnum); -} - -/* -============= -Draw_TransPic -============= -*/ -void GLDraw_TransPic (int x, int y, mpic_t *pic) -{ - if (!pic) - return; - if (x < 0 || (unsigned)(x + pic->width) > vid.width || y < 0 || - (unsigned)(y + pic->height) > vid.height) - { - Con_DPrintf("Draw_TransPic: bad coordinates\n"); - return; -// Sys_Error ("Draw_TransPic: bad coordinates"); - } - - GLDraw_Pic (x, y, pic); -} - - /* ============= Draw_TransPicTranslate @@ -1868,10 +627,10 @@ void GLDraw_TransPicTranslate (int x, int y, int width, int height, qbyte *pic, } } - qglTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans); + qglTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); qglColor3f (1,1,1); qglBegin (GL_QUADS); @@ -1886,114 +645,6 @@ void GLDraw_TransPicTranslate (int x, int y, int width, int height, qbyte *pic, qglEnd (); } - -/* -================ -Draw_ConsoleBackground - -================ -*/ -void GLDraw_ConsoleBackground (int firstline, int lastline, qboolean forceopaque) -{ -// char ver[80]; -// int x, i; - float a; - - conback->width = vid.conwidth; - conback->height = vid.conheight; - - if (forceopaque) - { - a = 1; // console background is necessary - } - else - { - if (!scr_conalpha.value) - return; - - a = scr_conalpha.value; - } - - if (scr_chatmode == 2) - { - conback->height>>=1; - conback->width>>=1; - } -#ifdef Q3SHADERS - { - if (shader_console) - { - currententity = &r_worldentity; - GLDraw_ShaderPic(0, lastline - conback->height, vid.width, vid.height, shader_console, 1, 1, 1, a); - qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - return; - } - } -#endif - if (a >= 1) - { - qglColor3f (1,1,1); - GLDraw_Pic(0, lastline-conback->height, conback); - } - else - { - GLDraw_AlphaPic (0, lastline - conback->height, conback, a); - } -} - -void GLDraw_EditorBackground (int lines) -{ - int y; - - y = (vid.height * 3) >> 2; - if (lines > y) - GLDraw_Pic(0, lines-vid.height, conback); - else - GLDraw_AlphaPic (0, lines - vid.height, conback, (float)(1.2 * lines)/y); -} - -/* -============= -Draw_TileClear - -This repeats a 64*64 tile graphic to fill the screen around a sized down -refresh window. -============= -*/ -void GLDraw_TileClear (int x, int y, int w, int h) -{ - qglColor3f (1,1,1); - if (!draw_backtile) - { - qglDisable(GL_TEXTURE_2D); - qglBegin (GL_QUADS); - qglTexCoord2f (x/64.0, y/64.0); - qglVertex2f (x, y); - qglTexCoord2f ( (x+w)/64.0, y/64.0); - qglVertex2f (x+w, y); - qglTexCoord2f ( (x+w)/64.0, (y+h)/64.0); - qglVertex2f (x+w, y+h); - qglTexCoord2f ( x/64.0, (y+h)/64.0 ); - qglVertex2f (x, y+h); - qglEnd (); - qglEnable(GL_TEXTURE_2D); - } - else - { - GL_Bind (draw_backtile->d.gl.texnum); - qglBegin (GL_QUADS); - qglTexCoord2f (x/64.0, y/64.0); - qglVertex2f (x, y); - qglTexCoord2f ( (x+w)/64.0, y/64.0); - qglVertex2f (x+w, y); - qglTexCoord2f ( (x+w)/64.0, (y+h)/64.0); - qglVertex2f (x+w, y+h); - qglTexCoord2f ( x/64.0, (y+h)/64.0 ); - qglVertex2f (x, y+h); - qglEnd (); - } -} - void GLDraw_FillRGB (int x, int y, int w, int h, float r, float g, float b) { qglDisable (GL_TEXTURE_2D); @@ -2084,45 +735,46 @@ void GLR_Menutint_Callback (struct cvar_s *var, char *oldvalue) void GLDraw_FadeScreen (void) { extern cvar_t gl_menutint_shader; - extern int scenepp_texture, scenepp_mt_program, scenepp_mt_parm_colorf, scenepp_mt_parm_inverti; + extern texid_t scenepp_texture; + extern int scenepp_mt_program, scenepp_mt_parm_colorf, scenepp_mt_parm_inverti; if (!faderender) return; - if (scenepp_mt_program && gl_menutint_shader.value) + if (scenepp_mt_program && gl_menutint_shader.ival) { float vwidth = 1, vheight = 1; float vs, vt; // get the powers of 2 for the size of the texture that will hold the scene - while (vwidth < glwidth) + while (vwidth < vid.pixelwidth) vwidth *= 2; - while (vheight < glheight) + while (vheight < vid.pixelheight) vheight *= 2; // get the maxtexcoords while we're at it (cache this or just use largest?) - vs = glwidth / vwidth; - vt = glheight / vheight; + vs = vid.pixelwidth / vwidth; + vt = vid.pixelheight / vheight; // 2d mode, but upside down to quake's normal 2d drawing // this makes grabbing the sreen a lot easier - qglViewport (glx, gly, glwidth, glheight); + qglViewport (0, 0, vid.pixelwidth, vid.pixelheight); qglMatrixMode(GL_PROJECTION); // Push the matrices to go into 2d mode, that matches opengl's mode qglPushMatrix(); qglLoadIdentity (); // TODO: use actual window width and height - qglOrtho (0, glwidth, 0, glheight, -99999, 99999); + qglOrtho (0, vid.pixelwidth, 0, vid.pixelheight, -99999, 99999); qglMatrixMode(GL_MODELVIEW); qglPushMatrix(); qglLoadIdentity (); GL_Bind(scenepp_texture); - qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, glx, gly, vwidth, vheight, 0); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, vwidth, vheight, 0); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); if (qglGetError()) Con_Printf(CON_ERROR "GL Error after qglCopyTexImage2D\n"); @@ -2145,11 +797,11 @@ void GLDraw_FadeScreen (void) qglTexCoord2f (0, 0); qglVertex2f(0, 0); qglTexCoord2f (vs, 0); - qglVertex2f(glwidth, 0); + qglVertex2f(vid.pixelwidth, 0); qglTexCoord2f (vs, vt); - qglVertex2f(glwidth, glheight); + qglVertex2f(vid.pixelwidth, vid.pixelheight); qglTexCoord2f (0, vt); - qglVertex2f(0, glheight); + qglVertex2f(0, vid.pixelheight); qglEnd(); @@ -2190,84 +842,6 @@ void GLDraw_FadeScreen (void) Sbar_Changed(); } -void GLDraw_ImageColours(float r, float g, float b, float a) -{ - draw_mesh_colors[0][0] = r*255; - draw_mesh_colors[0][1] = g*255; - draw_mesh_colors[0][2] = b*255; - draw_mesh_colors[0][3] = a*255; - ((int*)draw_mesh_colors)[1] = ((int*)draw_mesh_colors)[0]; - ((int*)draw_mesh_colors)[2] = ((int*)draw_mesh_colors)[0]; - ((int*)draw_mesh_colors)[3] = ((int*)draw_mesh_colors)[0]; - - qglColor4f(r, g, b, a); -} - -void GLDraw_Image(float x, float y, float w, float h, float s1, float t1, float s2, float t2, mpic_t *pic) -{ - glpic_t *gl; - - if (!pic) - return; - - if (w == 0 && h == 0) - { - w = pic->width; - h = pic->height; - } - - if (scrap_dirty) - Scrap_Upload (); - gl = &pic->d.gl; -/* - s2 = s2 - - newsl = gl->sl + (srcx*oldglwidth)/pic->width; - newsh = newsl + (width*oldglwidth)/pic->width; - - newtl = gl->tl + (srcy*oldglheight)/pic->height; - newth = newtl + (height*oldglheight)/pic->height; -*/ - s2 = s1 + (s2-s1)*gl->sh; - s1 += gl->sl; - t2 = t1 + (t2-t1)*gl->th; - t1 += gl->tl; - - draw_mesh_xyz[0][0] = x; - draw_mesh_xyz[0][1] = y; - draw_mesh_st[0][0] = s1; - draw_mesh_st[0][1] = t1; - - draw_mesh_xyz[1][0] = x+w; - draw_mesh_xyz[1][1] = y; - draw_mesh_st[1][0] = s2; - draw_mesh_st[1][1] = t1; - - draw_mesh_xyz[2][0] = x+w; - draw_mesh_xyz[2][1] = y+h; - draw_mesh_st[2][0] = s2; - draw_mesh_st[2][1] = t2; - - draw_mesh_xyz[3][0] = x; - draw_mesh_xyz[3][1] = y+h; - draw_mesh_st[3][0] = s1; - draw_mesh_st[3][1] = t2; - - if (gl_blend2d.value) - { - qglDisable(GL_ALPHA_TEST); - qglEnable(GL_BLEND); - } - else - { - qglEnable(GL_ALPHA_TEST); - qglDisable(GL_BLEND); - } - - - GL_DrawMesh(&draw_mesh, gl->texnum); -} - //============================================================================= /* @@ -2283,7 +857,7 @@ void GLDraw_BeginDisc (void) if (!draw_disc || !r_drawdisk.value) return; qglDrawBuffer (GL_FRONT); - Draw_Pic (vid.width - draw_disc->width, 0, draw_disc); + Draw_ScalePic(vid.width - 24, 0, 24, 24, draw_disc); qglDrawBuffer (GL_BACK); } @@ -2303,21 +877,12 @@ void GLDraw_EndDisc (void) // conback/font callbacks void GL_Smoothfont_Callback(struct cvar_s *var, char *oldvalue) { - GL_Bind(char_texture); - if (var->value) - { - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - else - { - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } + //FIXME: reimplement } void GL_Fontinwardstep_Callback(struct cvar_s *var, char *oldvalue) { + //FIXME: reimplement if (var->value) char_instep = custom_char_instep*bound(0, var->value, 1); else @@ -2326,59 +891,19 @@ void GL_Fontinwardstep_Callback(struct cvar_s *var, char *oldvalue) void GL_Font_Callback(struct cvar_s *var, char *oldvalue) { - mpic_t *pic; - int old_char_texture = char_texture; - - //testfont = Font_LoadFont(testfontheight, var->string); - - if (!*var->string - || (!(char_texture=Mod_LoadHiResTexture(var->string, "fonts", false, true, true)) - && !(char_texture=Mod_LoadHiResTexture(var->string, "charsets", false, true, true)))) - { - char_texture = default_char_texture; - custom_char_instep = default_char_instep; - } - else - custom_char_instep = 0.5f/((image_width+image_height)/2); - - // update the conchars texture within the menu cache - if (old_char_texture != char_texture) - { - pic = GLDraw_IsCached("conchars"); - if (pic) - { - glpic_t *gl = &pic->d.gl; - gl->texnum = char_texture; - } - else - Con_Printf(CON_ERROR "ERROR: Unable to update conchars texture!"); - } - - GL_Smoothfont_Callback(&gl_smoothfont, ""); - GL_Fontinwardstep_Callback(&gl_fontinwardstep, ""); + //FIXME: reimplement GLVID_Console_Resize(); } void GL_Conback_Callback(struct cvar_s *var, char *oldvalue) { - int newtex = 0; -#ifdef Q3SHADERS - if (*var->string && (shader_console = R_RegisterCustom(var->string, NULL, NULL))) - { - conback = default_conback; - } - else -#endif - if (!*var->string || !(newtex=Mod_LoadHiResTexture(var->string, "gfx", false, true, true))) - { - conback = default_conback; - } - else - { - conback = custom_conback; - conback->d.gl.texnum = newtex; - } + if (*var->string) + conback = R_RegisterPic(var->string); + if (!conback || !conback->width) + conback = R_RegisterCustom("console", NULL, NULL); + if (!conback || !conback->width) + conback = R_RegisterPic("gfx/conback.lmp"); } /* @@ -2392,7 +917,7 @@ void GL_Set2D (void) { GL_SetShaderState2D(true); - qglViewport (glx, gly, glwidth, glheight); + qglViewport (0, 0, vid.pixelwidth, vid.pixelheight); qglMatrixMode(GL_PROJECTION); qglLoadIdentity (); @@ -2401,23 +926,6 @@ void GL_Set2D (void) qglMatrixMode(GL_MODELVIEW); qglLoadIdentity (); - qglDisable (GL_DEPTH_TEST); - qglDisable (GL_CULL_FACE); - - if (gl_blend2d.value) - { - qglEnable (GL_BLEND); - qglDisable (GL_ALPHA_TEST); - } - else - { - qglDisable (GL_BLEND); - qglEnable (GL_ALPHA_TEST); - } -// qglDisable (GL_ALPHA_TEST); - - qglColor4f (1,1,1,1); - r_refdef.time = realtime; } @@ -2428,7 +936,7 @@ void GL_Set2D (void) void MediaGL_ShowFrame8bit(qbyte *framedata, int inwidth, int inheight, qbyte *palette) //bottom up { - if (!filmtexture) + if (!TEXVALID(filmtexture)) { filmtexture=GL_AllocNewTexture(); } @@ -2436,7 +944,7 @@ void MediaGL_ShowFrame8bit(qbyte *framedata, int inwidth, int inheight, qbyte *p GL_Set2D (); GL_Bind(filmtexture); - GL_Upload8Pal24(framedata, palette, inwidth, inheight, false, false); //we may need to rescale the image + GL_Upload8Pal24(framedata, palette, inwidth, inheight, IF_NOMIPMAP|IF_NOALPHA); //we may need to rescale the image // glTexImage2D (GL_TEXTURE_2D, 0, 3, roqfilm->width, roqfilm->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, framedata); // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max); // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); @@ -2465,7 +973,7 @@ void MediaGL_ShowFrame8bit(qbyte *framedata, int inwidth, int inheight, qbyte *p void MediaGL_ShowFrameRGBA_32(qbyte *framedata, int inwidth, int inheight)//top down { - if (!filmtexture) + if (!TEXVALID(filmtexture)) { filmtexture=GL_AllocNewTexture(); } @@ -2473,7 +981,7 @@ void MediaGL_ShowFrameRGBA_32(qbyte *framedata, int inwidth, int inheight)//top GL_Set2D (); GL_Bind(filmtexture); - GL_Upload32("", (unsigned *)framedata, inwidth, inheight, false, false); //we may need to rescale the image + GL_Upload32("", (unsigned *)framedata, inwidth, inheight, IF_NOMIPMAP|IF_NOALPHA|IF_NOGAMMA); //we may need to rescale the image qglDisable(GL_BLEND); qglDisable(GL_ALPHA_TEST); @@ -2570,7 +1078,7 @@ void MediaGL_ShowFrameBGR_24_Flip(qbyte *framedata, int inwidth, int inheight) } } - if (!filmtexture) + if (!TEXVALID(filmtexture)) { filmtexture=GL_AllocNewTexture(); } @@ -2578,7 +1086,7 @@ void MediaGL_ShowFrameBGR_24_Flip(qbyte *framedata, int inwidth, int inheight) GL_Set2D (); GL_Bind(filmtexture); - GL_Upload32("", (unsigned *)uploadmemorybufferintermediate, filmnwidth, filmnheight, false, false); //we may need to rescale the image + GL_Upload32("", (unsigned *)uploadmemorybufferintermediate, filmnwidth, filmnheight, IF_NOMIPMAP|IF_NOALPHA|IF_NOGAMMA); //we may need to rescale the image qglDisable(GL_BLEND); qglDisable(GL_ALPHA_TEST); @@ -2609,13 +1117,17 @@ void MediaGL_ShowFrameBGR_24_Flip(qbyte *framedata, int inwidth, int inheight) GL_FindTexture ================ */ -int GL_FindTexture (char *identifier) +texid_t GL_FindTexture (char *identifier) { gltexture_t *glt; glt = Hash_Get(&gltexturetable, identifier); if (glt) + { + image_width = glt->width; + image_height = glt->height; return glt->texnum; + } /* for (glt=gltextures ; glt ; glt=glt->next) { @@ -2624,7 +1136,7 @@ int GL_FindTexture (char *identifier) } */ - return -1; + return r_nulltex; } gltexture_t *GL_MatchTexture (char *identifier, int bits, int width, int height) @@ -2998,7 +1510,7 @@ void GL_MipMap8Bit (qbyte *in, int width, int height) #endif #endif -qboolean GL_UploadCompressed (qbyte *file, int *out_width, int *out_height, unsigned int *out_mipmap) +qboolean GL_UploadCompressed (qbyte *file, int *out_width, int *out_height, unsigned int *out_flags) { int miplevel; int width; @@ -3014,7 +1526,7 @@ qboolean GL_UploadCompressed (qbyte *file, int *out_width, int *out_height, unsi GETVAR(&nummips) GETVAR(out_width) GETVAR(out_height) - GETVAR(out_mipmap) + GETVAR(out_flags) for (miplevel = 0; miplevel < nummips; miplevel++) { GETVAR(&width); @@ -3030,15 +1542,15 @@ qboolean GL_UploadCompressed (qbyte *file, int *out_width, int *out_height, unsi file += compressed_size; } - if (*out_mipmap) + if (!((*out_flags) & IF_NOMIPMAP)) { - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); } else { - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max_2d); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max_2d); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max_2d); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max_2d); } return true; } @@ -3091,7 +1603,7 @@ void GL_RoundDimensions(int *scaled_width, int *scaled_height, qboolean mipmap) GL_Upload32 =============== */ -void GL_Upload32_Int (char *name, unsigned *data, int width, int height, qboolean mipmap, qboolean alpha, GLenum glcolormode) +void GL_Upload32_Int (char *name, unsigned *data, int width, int height, unsigned int flags, GLenum glcolormode) { int miplevel=0; int samples; @@ -3102,17 +1614,17 @@ void GL_Upload32_Int (char *name, unsigned *data, int width, int height, qboole scaled_width = width; scaled_height = height; - GL_RoundDimensions(&scaled_width, &scaled_height, mipmap); + GL_RoundDimensions(&scaled_width, &scaled_height, !(flags & IF_NOMIPMAP)); - if (alpha) + if (!(flags & IF_NOALPHA)) { //make sure it does actually have those alpha pixels int i; - alpha = false; + flags |= IF_NOALPHA; for (i = 3; i < width*height*4; i+=4) { if (((unsigned char*)data)[i] < 255) { - alpha = true; + flags &= ~IF_NOALPHA; break; } } @@ -3123,21 +1635,21 @@ void GL_Upload32_Int (char *name, unsigned *data, int width, int height, qboole if (scaled_width * scaled_height > sizeofuploadmemorybuffer/4) Sys_Error ("GL_LoadTexture: too big"); - samples = alpha ? gl_alpha_format : gl_solid_format; - if (gl_config.arb_texture_compression && gl_compress.value && name&&mipmap) - samples = alpha ? GL_COMPRESSED_RGBA_ARB : GL_COMPRESSED_RGB_ARB; + samples = (flags&IF_NOALPHA) ? GL_RGB : GL_RGBA; + if (gl_config.arb_texture_compression && gl_compress.value && name && !(flags&IF_NOMIPMAP)) + samples = (flags&IF_NOALPHA) ? GL_COMPRESSED_RGB_ARB : GL_COMPRESSED_RGBA_ARB; texels += scaled_width * scaled_height; - if (gl_config.sgis_generate_mipmap&&mipmap) + if (gl_config.sgis_generate_mipmap && !(flags&IF_NOMIPMAP)) { TRACE(("dbg: GL_Upload32: GL_SGIS_generate_mipmap\n")); - qglTexParameterf(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); + qglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_TRUE); } if (scaled_width == width && scaled_height == height) { - if (!mipmap||gl_config.sgis_generate_mipmap) //gotta love this with NPOT textures... :) + if ((flags&IF_NOMIPMAP)||gl_config.sgis_generate_mipmap) //gotta love this with NPOT textures... :) { TRACE(("dbg: GL_Upload32: non-mipmapped/unscaled\n")); qglTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, glcolormode, GL_UNSIGNED_BYTE, data); @@ -3150,7 +1662,7 @@ texels += scaled_width * scaled_height; TRACE(("dbg: GL_Upload32: recaled\n")); qglTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, glcolormode, GL_UNSIGNED_BYTE, scaled); - if (mipmap && !gl_config.sgis_generate_mipmap) + if (!(flags&IF_NOMIPMAP) && !gl_config.sgis_generate_mipmap) { miplevel = 0; TRACE(("dbg: GL_Upload32: mips\n")); @@ -3167,7 +1679,7 @@ texels += scaled_width * scaled_height; qglTexImage2D (GL_TEXTURE_2D, miplevel, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled); } } - if (gl_config.arb_texture_compression && gl_compress.value && gl_savecompressedtex.value && name&&mipmap) + if (gl_config.arb_texture_compression && gl_compress.value && gl_savecompressedtex.value && name && !(flags&IF_NOMIPMAP)) { vfsfile_t *out; int miplevels; @@ -3192,7 +1704,7 @@ texels += scaled_width * scaled_height; VFS_WRITE(out, &i, sizeof(i)); i = LittleLong(height); VFS_WRITE(out, &i, sizeof(i)); - i = LittleLong(mipmap); + i = LittleLong(flags); VFS_WRITE(out, &i, sizeof(i)); for (miplevel = 0; miplevel < miplevels; miplevel++) { @@ -3220,34 +1732,40 @@ texels += scaled_width * scaled_height; } } done: - if (gl_config.sgis_generate_mipmap&&mipmap) - qglTexParameterf(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_FALSE); + if (gl_config.sgis_generate_mipmap && !(flags&IF_NOMIPMAP)) + qglTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, GL_FALSE); if (gl_anisotropy_factor) qglTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_anisotropy_factor); // without this, you could loose anisotropy on mapchange - if (mipmap) + if (!(flags&IF_NOMIPMAP)) { - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); } else { - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max_2d); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max_2d); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max_2d); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max_2d); + } + + if (flags&IF_CLAMP) + { + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); } } -void GL_Upload32 (char *name, unsigned *data, int width, int height, qboolean mipmap, qboolean alpha) +void GL_Upload32 (char *name, unsigned *data, int width, int height, unsigned int flags) { - GL_Upload32_Int(name, data, width, height, mipmap, alpha, GL_RGBA); + GL_Upload32_Int(name, data, width, height, flags, GL_RGBA); } -void GL_Upload32_BGRA (char *name, unsigned *data, int width, int height, qboolean mipmap, qboolean alpha) +void GL_Upload32_BGRA (char *name, unsigned *data, int width, int height, unsigned int flags) { - GL_Upload32_Int(name, data, width, height, mipmap, alpha, GL_BGRA_EXT); + GL_Upload32_Int(name, data, width, height, flags, GL_BGRA_EXT); } -void GL_Upload24BGR (char *name, qbyte *framedata, int inwidth, int inheight, qboolean mipmap, qboolean alpha) +void GL_Upload24BGR (char *name, qbyte *framedata, int inwidth, int inheight, unsigned int flags) { int outwidth, outheight; int y, x; @@ -3318,9 +1836,9 @@ void GL_Upload24BGR (char *name, qbyte *framedata, int inwidth, int inheight, q } } - GL_Upload32 (name, (unsigned int*)uploadmemorybufferintermediate, outwidth, outheight, mipmap, alpha); + GL_Upload32 (name, (unsigned int*)uploadmemorybufferintermediate, outwidth, outheight, flags); } -void GL_Upload24BGR_Flip (char *name, qbyte *framedata, int inwidth, int inheight, qboolean mipmap, qboolean alpha) +void GL_Upload24BGR_Flip (char *name, qbyte *framedata, int inwidth, int inheight, unsigned int flags) { int outwidth, outheight; int y, x; @@ -3391,11 +1909,11 @@ void GL_Upload24BGR_Flip (char *name, qbyte *framedata, int inwidth, int inheigh } } - GL_Upload32 (name, (unsigned int*)uploadmemorybufferintermediate, outwidth, outheight, mipmap, alpha); + GL_Upload32 (name, (unsigned int*)uploadmemorybufferintermediate, outwidth, outheight, flags); } -void GL_Upload8Grey (unsigned char*data, int width, int height, qboolean mipmap) +void GL_Upload8Grey (unsigned char*data, int width, int height, unsigned int flags) { int samples; unsigned char *scaled = uploadmemorybuffer; @@ -3403,7 +1921,7 @@ void GL_Upload8Grey (unsigned char*data, int width, int height, qboolean mipmap scaled_width = width; scaled_height = height; - GL_RoundDimensions(&scaled_width, &scaled_height, mipmap); + GL_RoundDimensions(&scaled_width, &scaled_height, !(flags&IF_NOMIPMAP)); if (scaled_width * scaled_height > sizeofuploadmemorybuffer/4) Sys_Error ("GL_LoadTexture: too big"); @@ -3414,7 +1932,7 @@ texels += scaled_width * scaled_height; if (scaled_width == width && scaled_height == height) { - if (!mipmap) + if (flags&IF_NOMIPMAP) { qglTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, data); goto done; @@ -3425,7 +1943,7 @@ texels += scaled_width * scaled_height; GL_Resample8BitTexture (data, width, height, scaled, scaled_width, scaled_height); qglTexImage2D (GL_TEXTURE_2D, 0, samples, scaled_width, scaled_height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, scaled); - if (mipmap) + if (!(flags&IF_NOMIPMAP)) { int miplevel; @@ -3445,15 +1963,15 @@ texels += scaled_width * scaled_height; } done: ; - if (mipmap) + if (!(flags&IF_NOMIPMAP)) { - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); } else { - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max_2d); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max_2d); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max_2d); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max_2d); } } @@ -3640,13 +2158,13 @@ void GL_UploadBump(qbyte *data, int width, int height, qboolean mipmap, float bu if (mipmap) { - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); } else { - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max_2d); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max_2d); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_max_2d); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max_2d); } // if (gl_texturefilteranisotropic) @@ -3759,7 +2277,7 @@ unsigned ColorPercent[16] = 25, 51, 76, 102, 114, 127, 140, 153, 165, 178, 191, 204, 216, 229, 237, 247 }; -void GL_Upload8 (char *name, qbyte *data, int width, int height, qboolean mipmap, qboolean alpha) +void GL_Upload8 (char *name, qbyte *data, int width, int height, unsigned int flags, unsigned int alpha) { unsigned *trans = (unsigned *)uploadmemorybufferintermediate; int i, s; @@ -3772,7 +2290,7 @@ void GL_Upload8 (char *name, qbyte *data, int width, int height, qboolean mipma s = width*height; // if there are no transparent pixels, make it a 3 component // texture even if it was specified as otherwise - if (alpha) + if (alpha && !(flags & IF_NOALPHA)) { noalpha = true; for (i=0 ; iwidth = width; glt->height = height; glt->bpp = 8; - glt->mipmap = mipmap; + glt->flags = flags; Hash_Add(&gltexturetable, glt->identifier, glt, (bucket_t*)(glt+1)); GL_Bind(glt->texnum); - GL_Upload8 ("8bit", data, width, height, mipmap, alpha); + GL_Upload8 ("8bit", data, width, height, flags, transtype); return glt->texnum; } -int GL_LoadTextureFB (char *identifier, int width, int height, qbyte *data, qboolean mipmap, qboolean alpha) +texid_t GL_LoadTextureFB (char *identifier, int width, int height, qbyte *data, unsigned int flags) { int i; gltexture_t *glt; @@ -4049,7 +2568,7 @@ int GL_LoadTextureFB (char *identifier, int width, int height, qbyte *data, qboo break; if (i == width*height) - return 0; //none found, don't bother uploading. + return r_nulltex; //none found, don't bother uploading. glt = BZ_Malloc(sizeof(*glt)+sizeof(bucket_t)); glt->next = gltextures; @@ -4060,18 +2579,18 @@ int GL_LoadTextureFB (char *identifier, int width, int height, qbyte *data, qboo glt->width = width; glt->height = height; glt->bpp = 8; - glt->mipmap = mipmap; + glt->flags = flags; Hash_Add(&gltexturetable, glt->identifier, glt, (bucket_t*)(glt+1)); GL_Bind(glt->texnum); - GL_Upload8FB (data, width, height, mipmap); + GL_Upload8FB (data, width, height, flags); return glt->texnum; } -int GL_LoadTexture8Pal24 (char *identifier, int width, int height, qbyte *data, qbyte *palette24, qboolean mipmap, qboolean alpha) +texid_t GL_LoadTexture8Pal24 (char *identifier, int width, int height, qbyte *data, qbyte *palette24, unsigned int flags) { gltexture_t *glt; @@ -4093,17 +2612,17 @@ int GL_LoadTexture8Pal24 (char *identifier, int width, int height, qbyte *data, glt->width = width; glt->height = height; glt->bpp = 24; - glt->mipmap = mipmap; + glt->flags = flags; Hash_Add(&gltexturetable, glt->identifier, glt, (bucket_t*)(glt+1)); GL_Bind(glt->texnum); - GL_Upload8Pal24 (data, palette24, width, height, mipmap, alpha); + GL_Upload8Pal24 (data, palette24, width, height, flags); return glt->texnum; } -int GL_LoadTexture8Pal32 (char *identifier, int width, int height, qbyte *data, qbyte *palette32, qboolean mipmap, qboolean alpha) +texid_t GL_LoadTexture8Pal32 (char *identifier, int width, int height, qbyte *data, qbyte *palette32, unsigned int flags) { gltexture_t *glt; @@ -4125,18 +2644,18 @@ int GL_LoadTexture8Pal32 (char *identifier, int width, int height, qbyte *data, glt->width = width; glt->height = height; glt->bpp = 32; - glt->mipmap = mipmap; + glt->flags = flags; Hash_Add(&gltexturetable, glt->identifier, glt, (bucket_t*)(glt+1)); GL_Bind(glt->texnum); - GL_Upload8Pal32 (data, palette32, width, height, mipmap, alpha); + GL_Upload8Pal32 (data, palette32, width, height, flags); return glt->texnum; } -int GL_LoadTexture32 (char *identifier, int width, int height, unsigned *data, qboolean mipmap, qboolean alpha) +texid_t GL_LoadTexture32 (char *identifier, int width, int height, void *data, unsigned int flags) { // qboolean noalpha; // int p, s; @@ -4159,18 +2678,18 @@ int GL_LoadTexture32 (char *identifier, int width, int height, unsigned *data, q glt->width = width; glt->height = height; glt->bpp = 32; - glt->mipmap = mipmap; + glt->flags = flags; Hash_Add(&gltexturetable, glt->identifier, glt, (bucket_t*)(glt+1)); GL_Bind(glt->texnum); - GL_Upload32 (identifier, data, width, height, mipmap, alpha); + GL_Upload32 (identifier, data, width, height, flags); return glt->texnum; } -int GL_LoadTexture32_BGRA (char *identifier, int width, int height, unsigned *data, qboolean mipmap, qboolean alpha) +texid_t GL_LoadTexture32_BGRA (char *identifier, int width, int height, unsigned *data, unsigned int flags) { // qboolean noalpha; // int p, s; @@ -4193,43 +2712,43 @@ int GL_LoadTexture32_BGRA (char *identifier, int width, int height, unsigned *da glt->width = width; glt->height = height; glt->bpp = 32; - glt->mipmap = mipmap; + glt->flags = flags; Hash_Add(&gltexturetable, glt->identifier, glt, (bucket_t*)(glt+1)); GL_Bind(glt->texnum); - GL_Upload32_BGRA (identifier, data, width, height, mipmap, alpha); + GL_Upload32_BGRA (identifier, data, width, height, flags); return glt->texnum; } -int GL_LoadCompressed(char *name) +texid_t GL_LoadCompressed(char *name) { qbyte *COM_LoadFile (char *path, int usehunk); unsigned char *file; gltexture_t *glt; char inname[MAX_OSPATH]; - if (!gl_config.arb_texture_compression || !gl_compress.value) - return 0; + if (!gl_config.arb_texture_compression || !gl_compress.ival) + return r_nulltex; // see if the texture is already present if (name[0]) { - int num = GL_FindTexture(name); - if (num != -1) + texid_t num = GL_FindTexture(name); + if (TEXVALID(num)) return num; } else - return 0; + return r_nulltex; snprintf(inname, sizeof(inname)-1, "tex/%s.tex", name); file = COM_LoadFile(inname, 5); if (!file) - return 0; + return r_nulltex; glt = BZ_Malloc(sizeof(*glt)+sizeof(bucket_t)); glt->next = gltextures; @@ -4238,18 +2757,19 @@ int GL_LoadCompressed(char *name) strcpy (glt->identifier, name); glt->texnum = GL_AllocNewTexture(); glt->bpp = 32; + glt->flags = 0; Hash_Add(&gltexturetable, glt->identifier, glt, (bucket_t*)(glt+1)); GL_Bind(glt->texnum); - if (!GL_UploadCompressed (file, &glt->width, &glt->height, (unsigned int *)&glt->mipmap)) - return 0; + if (!GL_UploadCompressed(file, &glt->width, &glt->height, (unsigned int *)&glt->flags)) + return r_nulltex; return glt->texnum; } -int GL_LoadTexture8Grey (char *identifier, int width, int height, unsigned char *data, qboolean mipmap) +texid_t GL_LoadTexture8Grey (char *identifier, int width, int height, unsigned char *data, unsigned int flags) { // qboolean noalpha; // int p, s; @@ -4263,6 +2783,8 @@ int GL_LoadTexture8Grey (char *identifier, int width, int height, unsigned char return glt->texnum; } + flags |= IF_NOALPHA; + glt = BZ_Malloc(sizeof(*glt)+sizeof(bucket_t)); glt->next = gltextures; gltextures = glt; @@ -4272,18 +2794,18 @@ int GL_LoadTexture8Grey (char *identifier, int width, int height, unsigned char glt->width = width; glt->height = height; glt->bpp = 8; - glt->mipmap = mipmap; + glt->flags = flags; Hash_Add(&gltexturetable, glt->identifier, glt, (bucket_t*)(glt+1)); GL_Bind(glt->texnum); - GL_Upload8Grey (data, width, height, mipmap); + GL_Upload8Grey (data, width, height, flags); return glt->texnum; } -int GL_LoadTexture8Bump (char *identifier, int width, int height, unsigned char *data, qboolean mipmap, float bumpscale) +texid_t GL_LoadTexture8Bump (char *identifier, int width, int height, unsigned char *data, unsigned int flags, float bumpscale) { // qboolean noalpha; // int p, s; @@ -4311,13 +2833,13 @@ int GL_LoadTexture8Bump (char *identifier, int width, int height, unsigned char glt->width = width; glt->height = height; glt->bpp = 8; - glt->mipmap = mipmap; + glt->flags = flags; Hash_Add(&gltexturetable, glt->identifier, glt, (bucket_t*)(glt+1)); GL_Bind(glt->texnum); - GL_UploadBump (data, width, height, mipmap, bumpscale); + GL_UploadBump (data, width, height, flags, bumpscale); return glt->texnum; } @@ -4327,9 +2849,9 @@ int GL_LoadTexture8Bump (char *identifier, int width, int height, unsigned char GL_LoadPicTexture ================ */ -int GL_LoadPicTexture (qpic_t *pic) +texid_t GL_LoadPicTexture (qpic_t *pic) { - return GL_LoadTexture ("", pic->width, pic->height, pic->data, false, true); + return GL_LoadTexture ("", pic->width, pic->height, pic->data, IF_NOMIPMAP, 1); } /****************************************/ diff --git a/engine/gl/gl_draw.h b/engine/gl/gl_draw.h index d623a184..2f3a99ce 100644 --- a/engine/gl/gl_draw.h +++ b/engine/gl/gl_draw.h @@ -25,32 +25,24 @@ void GLDraw_Init (void); void GLDraw_ReInit (void); void GLDraw_DeInit (void); void GLSurf_DeInit (void); -void GLDraw_Character (int x, int y, unsigned int num); -void GLDraw_ColouredCharacter (int x, int y, unsigned int num); -void GLDraw_TinyCharacter (int x, int y, unsigned int num); -void GLDraw_DebugChar (qbyte num); -void GLDraw_SubPic(int x, int y, mpic_t *pic, int srcx, int srcy, int width, int height); -void GLDraw_Pic (int x, int y, mpic_t *pic); -void GLDraw_ScalePic (int x, int y, int width, int height, mpic_t *pic); -void GLDraw_TransPic (int x, int y, mpic_t *pic); void GLDraw_TransPicTranslate (int x, int y, int w, int h, qbyte *pic, qbyte *translation); -void GLDraw_ConsoleBackground (int firstline, int lastline, qboolean forceopaque); -void GLDraw_EditorBackground (int lines); void GLDraw_BeginDisc (void); void GLDraw_EndDisc (void); -void GLDraw_TileClear (int x, int y, int w, int h); void GLDraw_FillRGB (int x, int y, int w, int h, float r, float g, float b); void GLDraw_Fill (int x, int y, int w, int h, unsigned int c); void GLDraw_FadeScreen (void); -void GLDraw_String (int x, int y, const qbyte *str); -void GLDraw_Alt_String (int x, int y, const qbyte *str); -mpic_t *GLDraw_SafePicFromWad (char *name); -mpic_t *GLDraw_SafeCachePic (char *path); -mpic_t *GLDraw_CachePic (char *path); void GLDraw_Crosshair(void); void GLDraw_LevelPic (mpic_t *pic); -void GLDraw_ImageColours(float r, float g, float b, float a); -void GLDraw_Image(float x, float y, float w, float h, float s1, float t1, float s2, float t2, mpic_t *pic); - -void R_BloomRegister(void); +void R2D_Init(void); +mpic_t *R2D_SafeCachePic (char *path); +mpic_t *R2D_SafePicFromWad (char *name); +void R2D_ImageColours(float r, float g, float b, float a); +void R2D_Image(float x, float y, float w, float h, float s1, float t1, float s2, float t2, mpic_t *pic); +void R2D_ScalePic (int x, int y, int width, int height, mpic_t *pic); +void R2D_SubPic(int x, int y, int width, int height, mpic_t *pic, int srcx, int srcy, int srcwidth, int srcheight); +void R2D_ConsoleBackground (int firstline, int lastline, qboolean forceopaque); +void R2D_EditorBackground (void); +void R2D_TileClear (int x, int y, int w, int h); +void R2D_Init(void); +void R2D_Shutdown(void); diff --git a/engine/gl/gl_font.c b/engine/gl/gl_font.c index 62050482..b2a698bc 100644 --- a/engine/gl/gl_font.c +++ b/engine/gl/gl_font.c @@ -1,26 +1,27 @@ #include "quakedef.h" -#ifdef AVAIL_FREETYPE -#include "glquake.h" +#ifndef SERVERONLY +#include "shader.h" +void Font_Init(void); +void Font_Shutdown(void); +struct font_s *Font_LoadFont(int height, char *fontfilename); +void Font_Free(struct font_s *f); +void Font_BeginString(struct font_s *font, int vx, int vy, int *px, int *py); +int Font_CharHeight(void); +int Font_CharWidth(unsigned int charcode); +int Font_DrawChar(int px, int py, unsigned int charcode); +void Font_EndString(struct font_s *font); +int Font_LineBreaks(conchar_t *start, conchar_t *end, int maxpixelwidth, int maxlines, conchar_t **starts, conchar_t **ends); +struct font_s *font_conchar; +struct font_s *font_tiny; + +#ifdef AVAIL_FREETYPE #include #include FT_FREETYPE_H static FT_Library fontlib; -#define FONTCHARS (1<<16) -#define FONTPLANES (1<<2) //no more than 16 textures per font -#define PLANEIDXTYPE unsigned char -#define CHARIDXTYPE unsigned short - -#define INVALIDPLANE ((1<<(8*sizeof(PLANEIDXTYPE)))-1) -#define PLANEWIDTH (1<<8) -#define PLANEHEIGHT PLANEWIDTH - - - -#define GEN_CONCHAR_GLYPHS 0 //set to 0 or 1 to define whether to generate glyphs from conchars too, or if it should just draw them as glquake always used to -extern cvar_t cl_noblink; qboolean triedtoloadfreetype; dllhandle_t *fontmodule; @@ -29,31 +30,161 @@ FT_Error (VARGS *pFT_Load_Char) (FT_Face face, FT_ULong char_code, FT_Int32 lo FT_Error (VARGS *pFT_Set_Pixel_Sizes) (FT_Face face, FT_UInt pixel_width, FT_UInt pixel_height); FT_Error (VARGS *pFT_New_Face) (FT_Library library, const char *pathname, FT_Long face_index, FT_Face *aface); FT_Error (VARGS *pFT_Done_Face) (FT_Face face); +#endif +static const char *imgs[] = +{ + //0xe10X + "e100","e101", + "inv_shotgun", + "inv_sshotgun", + "inv_nailgun", + "inv_snailgun", + "inv_rlaunch", + "inv_srlaunch", + "inv_lightng", //8 + "e109","e10a","e10b","e10c","e10d","e10e","e10f", + + //0xe11X + "e110","e111", + "inv2_shotgun", + "inv2_sshotgun", + "inv2_nailgun", + "inv2_snailgun", + "inv2_rlaunch", + "inv2_srlaunch", + "inv2_lightng", + "e119","e11a","e11b","e11c","e11d","e11e","e11f", + + //0xe12X + "sb_shells", + "sb_nails", + "sb_rocket", + "sb_cells", + + "sb_armor1", + "sb_armor2", + "sb_armor3", + "e127","e128","e129","e12a","e12b","e12c","e12d","e12e","e12f", + + //0xe13X + "sb_key1", + "sb_key2", + "sb_invis", + "sb_invuln", + "sb_suit", + "sb_quad", + + "sb_sigil1", + "sb_sigil2", + "sb_sigil3", + "sb_sigil4", + "e13a","e13b","e13c","e13d","e13e","e13f", + + //0xe14X + "face1", + "face_p1", + "face2", + "face_p2", + "face3", + "face_p3", + "face4", + "face_p4", + "face5", + "face_p5", + + "face_invis", + "face_invul2", + "face_inv2", + "face_quad", + "e14e", + "e14f", + + //0xe15X + "e150", + "e151", + "e152", + "e153", + "e154", + "e155", + "e156", + "e157", + "e158", + "e159", + "e15a", + "e15b", + "e15c", + "e15d", + "e15e", + "e15f", + + //0xe16X + "e160", + "e161", + "e162", + "e163", + "e164", + "e165", + "e166", + "e167", + "e168", + "e169", + "e16a", + "e16b", + "e16c", + "e16d", + "e16e", + "e16f" +}; + +#define FONTCHARS (1<<16) +#define FONTPLANES (1<<2) //no more than 16 textures per font +#define PLANEIDXTYPE unsigned short +#define CHARIDXTYPE unsigned short + +#define INVALIDPLANE ((1<<(8*sizeof(PLANEIDXTYPE)))-1) +#define BITMAPPLANE ((1<<(8*sizeof(PLANEIDXTYPE)))-2) +#define DEFAULTPLANE ((1<<(8*sizeof(PLANEIDXTYPE)))-3) +#define PLANEWIDTH (1<<8) +#define PLANEHEIGHT PLANEWIDTH + + + +#define GEN_CONCHAR_GLYPHS 0 //set to 0 or 1 to define whether to generate glyphs from conchars too, or if it should just draw them as glquake always used to +extern cvar_t cl_noblink; +extern cvar_t gl_smoothfont; +extern cvar_t con_ocranaleds; typedef struct font_s { struct charcache_s { struct charcache_s *nextchar; + PLANEIDXTYPE texplane; + unsigned char advance; //how wide this char is, when drawn + char pad; + unsigned char bmx; unsigned char bmy; unsigned char bmw; unsigned char bmh; + short top; short left; - unsigned char advance; //how wide this char is, when drawn - char pad; } chars[FONTCHARS]; short charheight; - + texid_t singletexture; +#ifdef AVAIL_FREETYPE FT_Face face; +#endif } font_t; typedef struct { - int texnum[FONTPLANES]; + texid_t texnum[FONTPLANES]; + texid_t defaultfont; + unsigned char plane[PLANEWIDTH*PLANEHEIGHT][4]; //tracks the current plane PLANEIDXTYPE activeplane; unsigned char planerowx; @@ -63,15 +194,132 @@ typedef struct { struct charcache_s *oldestchar; struct charcache_s *newestchar; + shader_t *shader; + shader_t *backshader; } fontplanes_t; static fontplanes_t fontplanes; + +#define FONT_CHAR_BUFFER 64 +static index_t font_indicies[FONT_CHAR_BUFFER*6]; +static vecV_t font_coord[FONT_CHAR_BUFFER*4]; +static vec2_t font_texcoord[FONT_CHAR_BUFFER*4]; +static vbo_t font_buffer; +static mesh_t font_mesh; +static texid_t font_texture; +static int font_colourmask; +static struct font_s *curfont; + +//called at load time - initalises font buffers +void Font_Init(void) +{ + int i; + fontplanes.defaultfont = r_nulltex; + + font_buffer.indicies = font_indicies; + font_buffer.coord = font_coord; + font_buffer.texcoord = font_texcoord; + + font_mesh.indexes = font_buffer.indicies; + font_mesh.xyz_array = font_buffer.coord; + font_mesh.st_array = font_buffer.texcoord; + + for (i = 0; i < FONT_CHAR_BUFFER; i++) + { + font_indicies[i*6+0] = i*4+0; + font_indicies[i*6+1] = i*4+1; + font_indicies[i*6+2] = i*4+2; + font_indicies[i*6+3] = i*4+0; + font_indicies[i*6+4] = i*4+2; + font_indicies[i*6+5] = i*4+3; + } + + for (i = 0; i < FONTPLANES; i++) + { + fontplanes.texnum[i] = R_AllocNewTexture(PLANEWIDTH, PLANEHEIGHT); + } + + fontplanes.shader = R_RegisterShader("ftefont", + "{\n" + "{\n" + "map $diffuse\n" + "rgbgen const\n" + "alphagen const\n" + "blendfunc blend\n" + "}\n" + "}\n" + ); + + fontplanes.backshader = R_RegisterShader("ftefontback", + "{\n" + "{\n" + "map $whiteimage\n" + "rgbgen const\n" + "alphagen const\n" + "blendfunc blend\n" + "}\n" + "}\n" + ); + + font_colourmask = ~0; +} + +//flush the font buffer, by drawing it to the screen +void Font_Flush(void) +{ + if (!font_mesh.numindexes) + return; + + if (fontplanes.planechanged) + { + R_Upload(fontplanes.texnum[fontplanes.activeplane], NULL, TF_RGBA32, (void*)fontplanes.plane, PLANEWIDTH, PLANEHEIGHT, IF_NOPICMIP|IF_NOMIPMAP|IF_NOGAMMA); + + fontplanes.planechanged = false; + } + if (font_colourmask & CON_NONCLEARBG) + { + fontplanes.backshader->defaulttextures.base = r_nulltex; + BE_DrawMeshChain(fontplanes.backshader, &font_mesh, NULL, &fontplanes.backshader->defaulttextures); + + fontplanes.shader->defaulttextures.base = font_texture; + BE_DrawMeshChain(fontplanes.shader, &font_mesh, NULL, &fontplanes.shader->defaulttextures); + } + else + { + fontplanes.shader->defaulttextures.base = font_texture; + BE_DrawMeshChain(fontplanes.shader, &font_mesh, NULL, &fontplanes.shader->defaulttextures); + } + + font_mesh.numindexes = 0; + font_mesh.numvertexes = 0; +} + +static int Font_BeginChar(texid_t tex) +{ + int fvert; + + if (font_mesh.numindexes == FONT_CHAR_BUFFER*6 || memcmp(&font_texture,&tex, sizeof(texid_t))) + { + Font_Flush(); + font_texture = tex; + } + + fvert = font_mesh.numvertexes; + + font_mesh.numindexes += 6; + font_mesh.numvertexes += 4; + + return fvert; +} + +//clear the shared planes and free memory etc void Font_Shutdown(void) { int i; + for (i = 0; i < FONTPLANES; i++) - fontplanes.texnum[i] = 0; + fontplanes.texnum[i] = r_nulltex; fontplanes.activeplane = 0; fontplanes.oldestchar = NULL; fontplanes.newestchar = NULL; @@ -81,18 +329,16 @@ void Font_Shutdown(void) fontplanes.planerowh = 0; } +//we got too many chars and switched to a new plane - purge the chars in that plane void Font_FlushPlane(font_t *f) { /* assumption: oldest chars must be of the oldest plane */ - if (fontplanes.planechanged) - { - GL_Bind(fontplanes.texnum[fontplanes.activeplane]); - GL_Upload32(NULL, (void*)fontplanes.plane, PLANEWIDTH, PLANEHEIGHT, false, true); - fontplanes.planechanged = false; - } + + //we've not broken anything yet, flush while we can + Font_Flush(); fontplanes.activeplane++; fontplanes.activeplane = fontplanes.activeplane % FONTPLANES; @@ -111,7 +357,8 @@ void Font_FlushPlane(font_t *f) fontplanes.newestchar = NULL; } -struct charcache_s *Font_GetChar(font_t *f, CHARIDXTYPE charidx) +//obtains a cached char, null if not cached +static struct charcache_s *Font_GetChar(font_t *f, CHARIDXTYPE charidx) { struct charcache_s *c = &f->chars[charidx]; if (c->texplane == INVALIDPLANE) @@ -122,7 +369,10 @@ struct charcache_s *Font_GetChar(font_t *f, CHARIDXTYPE charidx) return c; } -struct charcache_s *Font_LoadGlyphData(font_t *f, CHARIDXTYPE charidx, int alphaonly, void *data, unsigned int bmw, unsigned int bmh, unsigned int pitch) +//loads a new image into a given character slot for the given font. +//note: make sure it doesn't already exist or things will get cyclic +//alphaonly says if its a greyscale image. false means rgba. +static struct charcache_s *Font_LoadGlyphData(font_t *f, CHARIDXTYPE charidx, int alphaonly, void *data, unsigned int bmw, unsigned int bmh, unsigned int pitch) { int x, y; unsigned char *out; @@ -186,11 +436,10 @@ struct charcache_s *Font_LoadGlyphData(font_t *f, CHARIDXTYPE charidx, int alpha return c; } -struct charcache_s *Font_TryLoadGlyph(font_t *f, CHARIDXTYPE charidx) +//loads the given charidx for the given font, importing from elsewhere if needed. +static struct charcache_s *Font_TryLoadGlyph(font_t *f, CHARIDXTYPE charidx) { struct charcache_s *c; - FT_GlyphSlot slot; - FT_Bitmap *bm; #if GEN_CONCHAR_GLYPHS != 0 if (charidx >= 0xe000 && charidx <= 0xe0ff && draw_chars) @@ -236,61 +485,6 @@ struct charcache_s *Font_TryLoadGlyph(font_t *f, CHARIDXTYPE charidx) if (charidx >= 0xe100 && charidx <= 0xe1ff) { - static const char *imgs[] = - { - "inv_shotgun", - "inv_sshotgun", - "inv_nailgun", - "inv_snailgun", - "inv_rlaunch", - "inv_srlaunch", - "inv_lightng", - - "inv2_shotgun", - "inv2_sshotgun", - "inv2_nailgun", - "inv2_snailgun", - "inv2_rlaunch", - "inv2_srlaunch", - "inv2_lightng", - - "sb_shells", - "sb_nails", - "sb_rocket", - "sb_cells", - - "sb_armor1", - "sb_armor2", - "sb_armor3", - - "sb_key1", - "sb_key2", - "sb_invis", - "sb_invuln", - "sb_suit", - "sb_quad", - - "sb_sigil1", - "sb_sigil2", - "sb_sigil3", - "sb_sigil4", - - "face1", - "face_p1", - "face2", - "face_p2", - "face3", - "face_p3", - "face4", - "face_p4", - "face5", - "face_p5", - - "face_invis", - "face_invul2", - "face_inv2", - "face_quad" - }; qpic_t *wadimg; unsigned char *src; unsigned int img[64*64]; @@ -341,33 +535,41 @@ struct charcache_s *Font_TryLoadGlyph(font_t *f, CHARIDXTYPE charidx) if (c) { c->left = 0; - c->top = f->charheight - (f->charheight - nh) - 1; + c->top = f->charheight - nh; c->advance = nw; return c; } } } - if (pFT_Load_Char(f->face, charidx, FT_LOAD_RENDER)) - return NULL; - - slot = f->face->glyph; - bm = &slot->bitmap; - c = Font_LoadGlyphData(f, charidx, true, bm->buffer, bm->width, bm->rows, bm->pitch); - - if (c) +#ifdef AVAIL_FREETYPE + if (f->face) { - c->advance = slot->advance.x >> 6; - c->left = slot->bitmap_left; - c->top = slot->bitmap_top; + if (pFT_Load_Char(f->face, charidx, FT_LOAD_RENDER) == 0) + { + FT_GlyphSlot slot; + FT_Bitmap *bm; + + slot = f->face->glyph; + bm = &slot->bitmap; + c = Font_LoadGlyphData(f, charidx, true, bm->buffer, bm->width, bm->rows, bm->pitch); + + if (c) + { + c->advance = slot->advance.x >> 6; + c->left = slot->bitmap_left; + c->top = f->charheight*3/4 - slot->bitmap_top; + return c; + } + } } - return c; +#endif + return NULL; } -struct font_s *Font_LoadFont(int height, char *fontfilename) +qboolean Font_LoadFreeTypeFont(struct font_s *f, int height, char *fontfilename) { - int i; - struct font_s *f; +#ifdef AVAIL_FREETYPE FT_Face face; int error; if (!fontlib) @@ -383,15 +585,19 @@ struct font_s *Font_LoadFont(int height, char *fontfilename) {NULL, NULL} }; if (triedtoloadfreetype) - return NULL; + return false; triedtoloadfreetype = true; fontmodule = Sys_LoadLibrary("freetype6", ft2funcs); if (!fontmodule) - return NULL; + return false; error = pFT_Init_FreeType(&fontlib); if (error) - return NULL; + { + Sys_CloseLibrary(fontmodule); + return false; + } + /*any other errors leave freetype open*/ } //fixme: use FT_Open_Face eventually @@ -422,32 +628,224 @@ struct font_s *Font_LoadFont(int height, char *fontfilename) } #endif if (error) - return NULL; + return false; error = pFT_Set_Pixel_Sizes(face, 0, height); if (error) { - return NULL; + return false; } - f = malloc(sizeof(*f)); - memset(f, 0, sizeof(*f)); f->face = face; + return true; +#else + return false; +#endif +} + +static texid_t Font_LoadReplacementConchars(void) +{ + texid_t tex; + //q1 replacement + tex = R_LoadReplacementTexture("gfx/conchars.lmp", NULL, IF_NOMIPMAP|IF_NOGAMMA); + if (TEXVALID(tex)) + return tex; + //q2 + tex = R_LoadHiResTexture("pics/conchars.pcx", NULL, IF_NOMIPMAP|IF_NOGAMMA); + if (TEXVALID(tex)) + return tex; + //q3 + tex = R_LoadHiResTexture("gfx/2d/bigchars.tga", NULL, IF_NOMIPMAP|IF_NOGAMMA); + if (TEXVALID(tex)) + return tex; + return r_nulltex; +} +static texid_t Font_LoadQuakeConchars(void) +{ + unsigned int i; + qbyte *lump; + lump = W_SafeGetLumpName ("conchars"); + if (lump) + { + // add ocrana leds + if (con_ocranaleds.ival) + { + if (con_ocranaleds.ival != 2 || QCRC_Block(lump, 128*128) == 798) + AddOcranaLEDsIndexed (lump, 128, 128); + } + + for (i=0 ; i<128*128 ; i++) + if (lump[i] == 0) + lump[i] = 255; // proper transparent color + + return R_LoadTexture8("charset", 128, 128, (void*)lump, IF_NOMIPMAP|IF_NOGAMMA, 1); + } + return r_nulltex; +} + +static texid_t Font_LoadHexen2Conchars(void) +{ + //gulp... so it's come to this has it? rework the hexen2 conchars into the q1 system. + texid_t tex; + unsigned int i, x; + unsigned char *tempchars; + unsigned char *in, *out, *outbuf; + FS_LoadFile("gfx/menu/conchars.lmp", (void**)&tempchars); + if (tempchars) + { + outbuf = BZ_Malloc(8*8*256*8); + + out = outbuf; + for (i = 0; i < 8*8; i+=1) + { + if ((i/8)&1) + { + in = tempchars + ((i)/8)*16*8*8+(i&7)*32*8 - 256*4+128; + for (x = 0; x < 16*8; x++) + *out++ = *in++; + } + else + { + in = tempchars + (i/8)*16*8*8+(i&7)*32*8; + for (x = 0; x < 16*8; x++) + *out++ = *in++; + } + } + for (i = 0; i < 8*8; i+=1) + { + if ((i/8)&1) + { + in = tempchars+128*128 + ((i)/8)*16*8*8+(i&7)*32*8 - 256*4+128; + for (x = 0; x < 16*8; x++) + *out++ = *in++; + } + else + { + in = tempchars+128*128 + (i/8)*16*8*8+(i&7)*32*8; + for (x = 0; x < 16*8; x++) + *out++ = *in++; + } + } + FS_FreeFile(tempchars); + + // add ocrana leds + if (con_ocranaleds.value && con_ocranaleds.value != 2) + AddOcranaLEDsIndexed (outbuf, 128, 128); + + for (i=0 ; i<128*128 ; i++) + if (outbuf[i] == 0) + outbuf[i] = 255; // proper transparent color + tex = R_LoadTexture8 ("charset", 128, 128, outbuf, IF_NOMIPMAP|IF_NOGAMMA, 1); + Z_Free(outbuf); + return tex; + } + return r_nulltex; +} + +static texid_t Font_LoadFallbackConchars(void) +{ + texid_t tex; + extern qbyte default_conchar[11356]; + int width, height; + unsigned int i; + qbyte *lump; + lump = ReadTargaFile(default_conchar, sizeof(default_conchar), &width, &height, false); + if (!lump) + Sys_Error("Corrupt internal drawchars"); + /*convert greyscale to alpha*/ + for (i = 0; i < width*height; i++) + { + lump[i*4+3] = lump[i*4]; + lump[i*4+0] = 255; + lump[i*4+1] = 255; + lump[i*4+2] = 255; + } + tex = R_LoadTexture32("charset", width, height, (void*)lump, IF_NOMIPMAP|IF_NOGAMMA); + BZ_Free(lump); + return tex; +} + +/*loads a fallback image. not allowed to fail (use syserror if needed)*/ +static texid_t Font_LoadDefaultConchars(void) +{ + texid_t tex; + tex = Font_LoadReplacementConchars(); + if (TEXVALID(tex)) + return tex; + tex = Font_LoadQuakeConchars(); + if (TEXVALID(tex)) + return tex; + tex = Font_LoadHexen2Conchars(); + if (TEXVALID(tex)) + return tex; + tex = Font_LoadFallbackConchars(); + if (TEXVALID(tex)) + return tex; + Sys_Error("Unable to load any conchars\n"); +} + +//creates a new font object from the given file, with each text row with the given height. +//width is implicit and scales with height and choice of font. +struct font_s *Font_LoadFont(int height, char *fontfilename) +{ + struct font_s *f; + int i = 0; + + f = Z_Malloc(sizeof(*f)); f->charheight = height; - for (i = 0; i < FONTPLANES; i++) + if (!Font_LoadFreeTypeFont(f, height, fontfilename)) { - if (!fontplanes.texnum[i]) - fontplanes.texnum[i] = GL_AllocNewTexture(); + if (*fontfilename) + f->singletexture = R_LoadHiResTexture(fontfilename, "fonts", IF_NOMIPMAP); + + /*force it to load, even if there's nothing there*/ + for (; i < 256; i++) + { + f->chars[i].advance = f->charheight; + f->chars[i].bmh = PLANEWIDTH/16; + f->chars[i].bmw = PLANEWIDTH/16; + f->chars[i].bmx = (i&15)*(PLANEWIDTH/16); + f->chars[i].bmy = (i/16)*(PLANEWIDTH/16); + f->chars[i].left = 0; + f->chars[i].top = 0; + f->chars[i].nextchar = 0; //these chars are not linked in + f->chars[i].pad = 0; + f->chars[i].texplane = BITMAPPLANE; + } } - for (i = 0; i < FONTCHARS; i++) + if (!TEXVALID(f->singletexture)) + { + if (!TEXVALID(f->singletexture) && !TEXVALID(fontplanes.defaultfont)) + fontplanes.defaultfont = Font_LoadDefaultConchars(); + + f->singletexture = fontplanes.defaultfont; + } + + for (; i < FONTCHARS; i++) { f->chars[i].texplane = INVALIDPLANE; } + + /*pack the default chars into it*/ + for (i = 0xe000; i <= 0xe0ff; i++) + { + f->chars[i].advance = f->charheight; + f->chars[i].bmh = PLANEWIDTH/16; + f->chars[i].bmw = PLANEWIDTH/16; + f->chars[i].bmx = (i&15)*(PLANEWIDTH/16); + f->chars[i].bmy = (i/16)*(PLANEWIDTH/16); + f->chars[i].left = 0; + f->chars[i].top = 0; + f->chars[i].nextchar = 0; //these chars are not linked in + f->chars[i].pad = 0; + f->chars[i].texplane = BITMAPPLANE; /*if its a 'raster' font, don't use the default chars, always use the raster images*/ + } return f; } +//removes a font from memory. void Font_Free(struct font_s *f) { struct charcache_s **link; @@ -463,40 +861,42 @@ void Font_Free(struct font_s *f) link = &(*link)->nextchar; } - pFT_Done_Face(f->face); +#ifdef AVAIL_FREETYPE + if (f->face) + pFT_Done_Face(f->face); +#endif free(f); } -void GLFont_BeginString(struct font_s *font, int vx, int vy, int *px, int *py) +//maps a given virtual screen coord to a pixel coord, which matches the font's height/width values +void Font_BeginString(struct font_s *font, int vx, int vy, int *px, int *py) { - *px = (vx*glwidth) / (float)vid.width; - *py = (vy*glheight) / (float)vid.height; + curfont = font; + *px = (vx*vid.pixelwidth) / (float)vid.width; + *py = (vy*vid.pixelheight) / (float)vid.height; } -int GLFont_CharHeight(struct font_s *font) +void Font_EndString(struct font_s *font) { - if (!font) - return 8; - - return font->charheight; + Font_Flush(); + curfont = NULL; } -int GLFont_CharWidth(struct font_s *font, unsigned int charcode) +//obtains the font's row height (each row of chars should be drawn using this increment) +int Font_CharHeight(void) +{ + return curfont->charheight; +} + +//obtains the width of a character from a given font. This is how wide it is. The next char should be drawn at x + result. +int Font_CharWidth(unsigned int charcode) { struct charcache_s *c; - if (!font) - return 8; - -#if GEN_CONCHAR_GLYPHS == 0 - if ((charcode&CON_CHARMASK) >= 0xe000 && (charcode&CON_CHARMASK) <= 0xe0ff) - return font->charheight; -#endif - - c = Font_GetChar(font, (CHARIDXTYPE)(charcode&CON_CHARMASK)); + c = Font_GetChar(curfont, (CHARIDXTYPE)(charcode&CON_CHARMASK)); if (!c) { - c = Font_TryLoadGlyph(font, (CHARIDXTYPE)(charcode&CON_CHARMASK)); + c = Font_TryLoadGlyph(curfont, (CHARIDXTYPE)(charcode&CON_CHARMASK)); if (!c) return 0; } @@ -504,7 +904,12 @@ int GLFont_CharWidth(struct font_s *font, unsigned int charcode) return c->advance; } -int GLFont_LineBreaks(struct font_s *font, conchar_t *start, conchar_t *end, int scrwidth, int maxlines, conchar_t **starts, conchar_t **ends) +//for a given font, calculate the line breaks and word wrapping for a block of text +//start+end are the input string +//starts+ends are an array of line start and end points, which have maxlines elements. +//(end is the terminator, null or otherwise) +//maxpixelwidth is the width of the display area in pixels +int Font_LineBreaks(conchar_t *start, conchar_t *end, int maxpixelwidth, int maxlines, conchar_t **starts, conchar_t **ends) { int l, bt; int px; @@ -513,15 +918,15 @@ int GLFont_LineBreaks(struct font_s *font, conchar_t *start, conchar_t *end, int while (start < end) { // scan the width of the line - for (px=0, l=0 ; px <= scrwidth;) + for (px=0, l=0 ; px <= maxpixelwidth; ) { if ((start[l]&CON_CHARMASK) == '\n' || (start+l >= end)) break; l++; - px += GLFont_CharWidth(font, start[l]); + px += Font_CharWidth(start[l]); } //if we did get to the end - if (px > scrwidth) + if (px > maxpixelwidth) { bt = l; //backtrack until we find a space @@ -531,7 +936,7 @@ int GLFont_LineBreaks(struct font_s *font, conchar_t *start, conchar_t *end, int } if (l == 0 && bt>0) l = bt-1; - px -= GLFont_CharWidth(font, start[l]); + px -= Font_CharWidth(start[l]); } starts[foundlines] = start; @@ -541,8 +946,6 @@ int GLFont_LineBreaks(struct font_s *font, conchar_t *start, conchar_t *end, int break; start+=l; -// for (l=0 ; l<40 && *start && *start != '\n'; l++) - // start++; if ((*start&CON_CHARMASK) == '\n'||!l) start++; // skip the \n @@ -551,8 +954,29 @@ int GLFont_LineBreaks(struct font_s *font, conchar_t *start, conchar_t *end, int return foundlines; } +/*Note: *all* strings after the current one will inherit the same colour, until one changes it explicitly +correct usage of this function thus requires calling this with 1111 before Font_EndString*/ +void Font_ForceColour(float r, float g, float b, float a) +{ + Font_Flush(); + font_colourmask = CON_WHITEMASK; + + /*force the colour to the requested one*/ + fontplanes.shader->passes[0].rgbgen_func.args[0] = r; + fontplanes.shader->passes[0].rgbgen_func.args[1] = g; + fontplanes.shader->passes[0].rgbgen_func.args[2] = b; + fontplanes.shader->passes[0].alphagen_func.args[0] = a; + + /*no background*/ + fontplanes.backshader->passes[0].alphagen_func.args[0] = 0; + + /*Any drawchars that are now drawn will get the forced colour*/ +} + void GLDraw_FillRGB (int x, int y, int w, int h, float r, float g, float b); -int GLFont_DrawChar(struct font_s *font, int px, int py, unsigned int charcode) + +//draw a character from the current font at a pixel location. +int Font_DrawChar(int px, int py, unsigned int charcode) { struct charcache_s *c; float s0, s1; @@ -560,133 +984,92 @@ int GLFont_DrawChar(struct font_s *font, int px, int py, unsigned int charcode) float nextx; float sx, sy, sw, sh; int col; + int v; - if (!font) - return px; - -#if GEN_CONCHAR_GLYPHS == 0 - if ((charcode&CON_CHARMASK) >= 0xe000 && (charcode&CON_CHARMASK) <= 0xe0ff) - { - extern char_texture; - - if (charcode == 32) - return px+font->charheight; // space - - if (charcode & CON_BLINKTEXT) - { - if (!cl_noblink.value) - if ((int)(realtime*3) & 1) - return px+font->charheight; - } - - qglEnable(GL_BLEND); - qglDisable(GL_ALPHA_TEST); - - col = (charcode & CON_FGMASK) >> CON_FGSHIFT; - qglColor4f(consolecolours[col].fr, consolecolours[col].fg, consolecolours[col].fb, (charcode & CON_HALFALPHA)?0.5:1); - - charcode &= 0xff; - - sx = ((px)*(int)vid.width) / (float)glwidth; - sy = ((py+font->charheight/8)*(int)vid.height) / (float)glheight; - sw = ((font->charheight)*vid.width) / (float)glwidth; - sh = ((font->charheight)*vid.height) / (float)glheight; - - col = charcode&15; - s0 = (float)col/16; - s1 = (float)(col+1)/16; - - col = charcode>>4; - t0 = (float)col/16; - t1 = (float)(col+1)/16; - - qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - GL_Bind(char_texture); - - qglBegin(GL_QUADS); - qglTexCoord2f(s0, t0); - qglVertex2f(sx, sy); - qglTexCoord2f(s1, t0); - qglVertex2f(sx+sw, sy); - qglTexCoord2f(s1, t1); - qglVertex2f(sx+sw, sy+sh); - qglTexCoord2f(s0, t1); - qglVertex2f(sx, sy+sh); - qglEnd(); - qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - return px+font->charheight; - } -#endif - - c = Font_GetChar(font, (CHARIDXTYPE)(charcode&CON_CHARMASK)); + //crash if there is no current font. + c = Font_GetChar(curfont, (CHARIDXTYPE)(charcode&CON_CHARMASK)); if (!c) { - c = Font_TryLoadGlyph(font, (CHARIDXTYPE)(charcode&CON_CHARMASK)); + c = Font_TryLoadGlyph(curfont, (CHARIDXTYPE)(charcode&CON_CHARMASK)); if (!c) return px; } nextx = px + c->advance; + if ((charcode & CON_CHARMASK) == ' ') + return nextx; + if (charcode & CON_BLINKTEXT) { - if (!cl_noblink.value) + if (!cl_noblink.ival) if ((int)(realtime*3) & 1) return nextx; } - // draw background - if (charcode & CON_NONCLEARBG) + col = charcode & (CON_NONCLEARBG|CON_BGMASK|CON_FGMASK|CON_HALFALPHA); + if (col != font_colourmask) { - sx = ((px)*(int)vid.width) / (float)glwidth; - sy = ((py+(int)font->charheight/3)*(int)vid.height) / (float)glheight; - sw = ((c->advance)*vid.width) / (float)glwidth; - sh = ((font->charheight)*vid.height) / (float)glheight; + Font_Flush(); + font_colourmask = col; - col = (charcode & CON_BGMASK) >> CON_BGSHIFT; - GLDraw_FillRGB(sx, sy, sw, sh, consolecolours[col].fr, consolecolours[col].fg, consolecolours[col].fb); + col = (charcode&CON_FGMASK)>>CON_FGSHIFT; + fontplanes.shader->passes[0].rgbgen_func.args[0] = consolecolours[col].fr; + fontplanes.shader->passes[0].rgbgen_func.args[1] = consolecolours[col].fg; + fontplanes.shader->passes[0].rgbgen_func.args[2] = consolecolours[col].fb; + fontplanes.shader->passes[0].alphagen_func.args[0] = (charcode & CON_HALFALPHA)?0.5:1; + + col = (charcode&CON_BGMASK)>>CON_BGSHIFT; + fontplanes.backshader->passes[0].rgbgen_func.args[0] = consolecolours[col].fr; + fontplanes.backshader->passes[0].rgbgen_func.args[1] = consolecolours[col].fg; + fontplanes.backshader->passes[0].rgbgen_func.args[2] = consolecolours[col].fb; + fontplanes.backshader->passes[0].alphagen_func.args[0] = (charcode & CON_NONCLEARBG)?0.5:0; } - - sx = ((px+c->left)*(int)vid.width) / (float)glwidth; - sy = ((py+font->charheight-c->top)*(int)vid.height) / (float)glheight; - sw = ((c->bmw)*vid.width) / (float)glwidth; - sh = ((c->bmh)*vid.height) / (float)glheight; - s0 = (float)c->bmx/PLANEWIDTH; t0 = (float)c->bmy/PLANEWIDTH; s1 = (float)(c->bmx+c->bmw)/PLANEWIDTH; t1 = (float)(c->bmy+c->bmh)/PLANEWIDTH; - qglEnable(GL_BLEND); - qglDisable(GL_ALPHA_TEST); - - col = (charcode & CON_FGMASK) >> CON_FGSHIFT; - qglColor4f(consolecolours[col].fr, consolecolours[col].fg, consolecolours[col].fb, (charcode & CON_HALFALPHA)?0.5:1); - - qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - if (fontplanes.planechanged) + if (c->texplane >= DEFAULTPLANE) { - GL_Bind(fontplanes.texnum[fontplanes.activeplane]); - GL_Upload32(NULL, (void*)fontplanes.plane, PLANEWIDTH, PLANEHEIGHT, false, true); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - fontplanes.planechanged = false; - } - GL_Bind(fontplanes.texnum[c->texplane]); + sx = ((px+c->left)*(int)vid.width) / (float)vid.pixelwidth; + sy = ((py+c->top)*(int)vid.height) / (float)vid.pixelheight; + sw = ((curfont->charheight)*vid.width) / (float)vid.pixelwidth; + sh = ((curfont->charheight)*vid.height) / (float)vid.pixelheight; + + if (c->texplane == DEFAULTPLANE) + v = Font_BeginChar(fontplanes.defaultfont); + else + v = Font_BeginChar(curfont->singletexture); + } + else + { + sx = ((px+c->left)*(int)vid.width) / (float)vid.pixelwidth; + sy = ((py+c->top)*(int)vid.height) / (float)vid.pixelheight; + sw = ((c->bmw)*vid.width) / (float)vid.pixelwidth; + sh = ((c->bmh)*vid.height) / (float)vid.pixelheight; + v = Font_BeginChar(fontplanes.texnum[c->texplane]); + } + + font_texcoord[v+0][0] = s0; + font_texcoord[v+0][1] = t0; + font_texcoord[v+1][0] = s1; + font_texcoord[v+1][1] = t0; + font_texcoord[v+2][0] = s1; + font_texcoord[v+2][1] = t1; + font_texcoord[v+3][0] = s0; + font_texcoord[v+3][1] = t1; + + font_coord[v+0][0] = sx; + font_coord[v+0][1] = sy; + font_coord[v+1][0] = sx+sw; + font_coord[v+1][1] = sy; + font_coord[v+2][0] = sx+sw; + font_coord[v+2][1] = sy+sh; + font_coord[v+3][0] = sx; + font_coord[v+3][1] = sy+sh; - qglBegin(GL_QUADS); - qglTexCoord2f(s0, t0); - qglVertex2f(sx, sy); - qglTexCoord2f(s1, t0); - qglVertex2f(sx+sw, sy); - qglTexCoord2f(s1, t1); - qglVertex2f(sx+sw, sy+sh); - qglTexCoord2f(s0, t1); - qglVertex2f(sx, sy+sh); - qglEnd(); - qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); return nextx; } -#endif +#endif //!SERVERONLY diff --git a/engine/gl/gl_heightmap.c b/engine/gl/gl_heightmap.c index 7df9bdf9..3b9f06c9 100644 --- a/engine/gl/gl_heightmap.c +++ b/engine/gl/gl_heightmap.c @@ -1,9 +1,10 @@ #include "quakedef.h" #if defined(TERRAIN) && !defined(SERVERONLY) //fixme -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h" #endif +#include "shader.h" //heightmaps work thusly: //there is one raw heightmap file @@ -24,13 +25,13 @@ typedef struct { float terrainscale; float heightscale; int numsegs; - int detailtexture; - int textures[SECTIONS*SECTIONS]; + texid_t detailtexture; + texid_t textures[SECTIONS*SECTIONS]; int displaylist[SECTIONS*SECTIONS]; //display lists are famous for being stupidly fast with heightmaps. unsigned short mins[SECTIONS*SECTIONS], maxs[SECTIONS*SECTIONS]; } heightmap_t; -#ifdef RGLQUAKE +#ifdef GLQUAKE #define DISPLISTS //#define MULTITEXTURE //ATI suck. I don't know about anyone else (this goes at 1/5th the speed). @@ -51,14 +52,11 @@ void GL_DrawHeightmapModel (entity_t *e) if (e->model == cl.worldmodel) { qglColor4f(1, 1, 1, 1); - - R_ClearSkyBox(); - R_ForceSkyBox(); - GL_DrawSkyBox(NULL); + R_DrawSkyChain(NULL); } else qglColor4fv(e->shaderRGBAf); - qglEnable(GL_CULL_FACE); + GL_CullFace(SHADER_CULL_BACK); for (x = 0; x < hm->numsegs; x++) { @@ -84,10 +82,8 @@ void GL_DrawHeightmapModel (entity_t *e) #ifdef MULTITEXTURE if (qglActiveTextureARB) { - qglActiveTextureARB(GL_TEXTURE0_ARB); - bindTexFunc(GL_TEXTURE_2D, hm->textures[x+y*SECTIONS]); - qglActiveTextureARB(GL_TEXTURE1_ARB); - bindTexFunc(GL_TEXTURE_2D, hm->detailtexture); + GL_MBind(0, hm->textures[x+y*SECTIONS]); + GL_MBind(1, hm->detailtexture); qglEnable(GL_TEXTURE_2D); subsize = hm->terrainsize/SECTIONS; @@ -121,7 +117,7 @@ void GL_DrawHeightmapModel (entity_t *e) else #endif { //single texture - bindTexFunc(GL_TEXTURE_2D, hm->textures[x+y*SECTIONS]); + GL_Bind(hm->textures[x+y*SECTIONS]); qglBegin(GL_QUADS); subsize = hm->terrainsize/hm->numsegs; minx = x*subsize; @@ -142,7 +138,7 @@ void GL_DrawHeightmapModel (entity_t *e) } qglEnd(); - bindTexFunc(GL_TEXTURE_2D, hm->detailtexture); + GL_Bind(hm->detailtexture); qglEnable(GL_BLEND); qglBlendFunc (GL_ZERO, GL_SRC_COLOR); @@ -591,12 +587,12 @@ unsigned int Heightmap_FatPVS (model_t *mod, vec3_t org, qbyte *pvsbuffer, unsi } #ifndef CLIENTONLY -qboolean Heightmap_EdictInFatPVS (model_t *mod, edict_t *edict, qbyte *pvsdata) +qboolean Heightmap_EdictInFatPVS (model_t *mod, wedict_t *edict, qbyte *pvsdata) { return true; } -void Heightmap_FindTouchedLeafs (model_t *mod, edict_t *ent, float *mins, float *maxs) +void Heightmap_FindTouchedLeafs (world_t *w, model_t *mod, wedict_t *ent, float *mins, float *maxs) { } #endif @@ -765,23 +761,20 @@ qboolean GL_LoadHeightmapModel (model_t *mod, void *buffer) mod->entities = COM_LoadHunkFile(entfile); -#ifdef RGLQUAKE - hm->detailtexture = Mod_LoadHiResTexture(detailtexname, "", true, true, false); - - for (x = 0; x < numsegs; x++) + if (qrenderer>0) { - int y; + hm->detailtexture = R_LoadHiResTexture(detailtexname, "", IF_NOGAMMA); - for (y = 0; y < numsegs; y++) + for (x = 0; x < numsegs; x++) { - hm->textures[x+y*SECTIONS] = Mod_LoadHiResTexture(va("%s%02ix%02i%s", basetexname, x, y, exttexname), "", true, true, false); - qglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - qglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + int y; + + for (y = 0; y < numsegs; y++) + { + hm->textures[x+y*SECTIONS] = R_LoadHiResTexture(va("%s%02ix%02i%s", basetexname, x, y, exttexname), "", IF_CLAMP|IF_NOGAMMA); + } } } -#endif - - R_SetSky(skyname, skyrotate, skyaxis); mod->funcs.Trace = Heightmap_Trace; mod->funcs.PointContents = Heightmap_PointContents; diff --git a/engine/gl/gl_hlmdl.c b/engine/gl/gl_hlmdl.c index f21081f1..695ec94c 100644 --- a/engine/gl/gl_hlmdl.c +++ b/engine/gl/gl_hlmdl.c @@ -87,6 +87,7 @@ qboolean Mod_LoadHLModel (model_t *mod, void *buffer) hlmdl_tex_t *tex; hlmdl_bone_t *bones; hlmdl_bonecontroller_t *bonectls; + texid_t *texnums; int start, end, total; /*~~*/ @@ -108,7 +109,7 @@ qboolean Mod_LoadHLModel (model_t *mod, void *buffer) sprintf(st, "%d", (int) crc); Info_SetValueForKey (cls.userinfo, (mod->engineflags & MDLF_PLAYER) ? pmodel_name : emodel_name, - st, MAX_INFO_STRING); + st, sizeof(cls.userinfo)); if (cls.state >= ca_connected) { @@ -199,9 +200,11 @@ qboolean Mod_LoadHLModel (model_t *mod, void *buffer) model->bones = (char *)bones - (char *)model; model->bonectls = (char *)bonectls - (char *)model; + texnums = Hunk_Alloc(texheader->numtextures*sizeof(model->texnums)); + model->texnums = (char *)texnums - (char *)model; for(i = 0; i < texheader->numtextures; i++) { - tex[i].i = GL_LoadTexture8Pal24("", tex[i].w, tex[i].h, (qbyte *) texheader + tex[i].i, (qbyte *) texheader + tex[i].w * tex[i].h + tex[i].i, true, false); + texnums[i] = GL_LoadTexture8Pal24("", tex[i].w, tex[i].h, (qbyte *) texheader + tex[i].offset, (qbyte *) texheader + tex[i].w * tex[i].h + tex[i].offset, IF_NOALPHA|IF_NOGAMMA); } @@ -575,6 +578,7 @@ void R_DrawHLModel(entity_t *curent) model.textures = (hlmdl_tex_t *) ((char *)modelc + modelc->textures); model.bones = (hlmdl_bone_t *) ((char *)modelc + modelc->bones); model.bonectls = (hlmdl_bonecontroller_t *) ((char *)modelc + modelc->bonectls); + model.texnums = (texid_t *) ((char *)modelc + modelc->texnums); skins = (short *) ((qbyte *) model.texheader + model.texheader->skins); @@ -680,7 +684,7 @@ void R_DrawHLModel(entity_t *curent) { tex_w = 1.0f / model.textures[skins[mesh->skinindex]].w; tex_h = 1.0f / model.textures[skins[mesh->skinindex]].h; - GL_Bind(model.textures[skins[mesh->skinindex]].i); + GL_Bind(model.texnums[skins[mesh->skinindex]]); } GL_Draw_HL_AliasFrame((short *) ((qbyte *) model.header + mesh->index), transformed, tex_w, tex_h); diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index ce4a60fb..13c22c52 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -25,16 +25,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" -#if defined(RGLQUAKE) || defined(D3DQUAKE) - -#if defined(RGLQUAKE) +#if defined(GLQUAKE) || defined(D3DQUAKE) #include "glquake.h" -#endif - -#ifdef D3DQUAKE -#include "d3dquake.h" -#endif - #include "com_mesh.h" extern cvar_t r_shadow_bumpscale_basetexture; @@ -49,21 +41,21 @@ char loadname[32]; // for hunk tags void CM_Init(void); qboolean GL_LoadHeightmapModel (model_t *mod, void *buffer); -qboolean GLMod_LoadSpriteModel (model_t *mod, void *buffer); -qboolean GLMod_LoadSprite2Model (model_t *mod, void *buffer); -qboolean GLMod_LoadBrushModel (model_t *mod, void *buffer); +qboolean RMod_LoadSpriteModel (model_t *mod, void *buffer); +qboolean RMod_LoadSprite2Model (model_t *mod, void *buffer); +qboolean RMod_LoadBrushModel (model_t *mod, void *buffer); #ifdef Q2BSPS qboolean Mod_LoadQ2BrushModel (model_t *mod, void *buffer); #endif qboolean Mod_LoadHLModel (model_t *mod, void *buffer); -model_t *GLMod_LoadModel (model_t *mod, qboolean crash); +model_t *RMod_LoadModel (model_t *mod, qboolean crash); #ifdef DOOMWADS qboolean Mod_LoadDoomLevel(model_t *mod); #endif #ifdef DOOMWADS -void GLMod_LoadDoomSprite (model_t *mod); +void RMod_LoadDoomSprite (model_t *mod); #endif #define MAX_MOD_KNOWN 2048 @@ -83,7 +75,7 @@ int numlightdata; qboolean writelitfile; int relitsurface; -void GLMod_UpdateLightmap(int snum) +void RMod_UpdateLightmap(int snum) { msurface_t *s; if (lightmodel) @@ -104,7 +96,7 @@ void GLMod_UpdateLightmap(int snum) #endif -void GLMod_TextureList_f(void) +void RMod_TextureList_f(void) { int m, i; texture_t *tx; @@ -135,16 +127,19 @@ void GLMod_TextureList_f(void) } } -void GLMod_BlockTextureColour_f (void) +void RMod_BlockTextureColour_f (void) { char texname[64]; model_t *mod; texture_t *tx; + shader_t *s; char *match = Cmd_Argv(1); int i, m; unsigned int colour[8*8]; unsigned int rgba; + texnums_t tn; + ((char *)&rgba)[0] = atoi(Cmd_Argv(2)); ((char *)&rgba)[1] = atoi(Cmd_Argv(3)); ((char *)&rgba)[2] = atoi(Cmd_Argv(4)); @@ -152,6 +147,14 @@ void GLMod_BlockTextureColour_f (void) sprintf(texname, "8*8_%i_%i_%i", (int)((char *)&rgba)[0], (int)((char *)&rgba)[1], (int)((char *)&rgba)[2]); + s = R_RegisterCustom(Cmd_Argv(2), NULL, NULL); + if (!s) + { + memset(&tn, 0, sizeof(tn)); + tn.base = R_LoadTexture32(texname, 8, 8, colour, IF_NOALPHA|IF_NOGAMMA); + s = R_RegisterCustom (texname, Shader_DefaultBSP, NULL); + } + for (i = 0; i < sizeof(colour)/sizeof(colour[0]); i++) colour[i] = rgba; @@ -167,34 +170,154 @@ void GLMod_BlockTextureColour_f (void) if (!stricmp(tx->name, match)) { - tx->tn.base = R_LoadTexture32(texname, 8, 8, colour, true, false); + tx->shader = s; } } } } } + + + +#if defined(RUNTIMELIGHTING) && defined(MULTITHREAD) +void *relightthread; +volatile qboolean wantrelight; + +int RelightThread(void *arg) +{ + while (wantrelight && relitsurface < lightmodel->numsurfaces) + { + LightFace(relitsurface); + lightmodel->surfaces[relitsurface].cached_dlight = -1; + + relitsurface++; + } + return 0; +} +#endif + +void RMod_Think (void) +{ +#ifdef RUNTIMELIGHTING + if (lightmodel) + { + if (relitsurface >= lightmodel->numsurfaces) + { + return; + } +#ifdef MULTITHREAD + if (!relightthread) + { + wantrelight = true; + relightthread = Sys_CreateThread(RelightThread, lightmodel, 0); + } +#else + LightFace(relitsurface); + RMod_UpdateLightmap(relitsurface); + + relitsurface++; +#endif + if (relitsurface >= lightmodel->numsurfaces) + { + char filename[MAX_QPATH]; + Con_Printf("Finished lighting %s\n", lightmodel->name); + +#ifdef MULTITHREAD + if (relightthread) + { + wantrelight = false; + Sys_WaitOnThread(relightthread); + relightthread = NULL; + } +#endif + + if (lightmodel->deluxdata) + { + COM_StripExtension(lightmodel->name, filename, sizeof(filename)); + COM_DefaultExtension(filename, ".lux", sizeof(filename)); + FS_WriteFile(filename, lightmodel->deluxdata-8, numlightdata*3+8, FS_GAME); + } + + if (writelitfile) //the user might already have a lit file (don't overwrite it). + { + COM_StripExtension(lightmodel->name, filename, sizeof(filename)); + COM_DefaultExtension(filename, ".lit", sizeof(filename)); + FS_WriteFile(filename, lightmodel->lightdata-8, numlightdata*3+8, FS_GAME); + } + } + } +#endif +} + + +/* +=================== +Mod_ClearAll +=================== +*/ +void RMod_ClearAll (void) +{ + int i; + int t; + model_t *mod; + +#ifdef RUNTIMELIGHTING +#ifdef MULTITHREAD + if (relightthread) + { + wantrelight = false; + Sys_WaitOnThread(relightthread); + relightthread = NULL; + } +#endif + lightmodel = NULL; +#endif + + //when the hunk is reset, all bsp models need to be reloaded + for (i=0 , mod=mod_known ; ineedload) + continue; + + if (mod->type == mod_brush) + { + for (t = 0; t < mod->numtextures; t++) + { + if (!mod->textures[t]) + continue; + BE_ClearVBO(&mod->textures[t]->vbo); + } + } + + if (mod->type != mod_alias + && mod->type != mod_halflife + ) + mod->needload = true; + } +} + /* =============== Mod_Init =============== */ -void GLMod_Init (void) +void RMod_Init (void) { mod_numknown = 0; Q1BSP_Init(); - Cmd_AddRemCommand("mod_texturelist", GLMod_TextureList_f); - Cmd_AddRemCommand("mod_usetexture", GLMod_BlockTextureColour_f); + Cmd_AddRemCommand("mod_texturelist", RMod_TextureList_f); + Cmd_AddRemCommand("mod_usetexture", RMod_BlockTextureColour_f); } -void GLMod_Shutdown (void) +void RMod_Shutdown (void) { mod_numknown = 0; Cmd_RemoveCommand("mod_texturelist"); Cmd_RemoveCommand("mod_usetexture"); - GLMod_ClearAll(); + RMod_ClearAll(); } /* @@ -204,7 +327,7 @@ Mod_Init Caches the data if needed =============== */ -void *GLMod_Extradata (model_t *mod) +void *RMod_Extradata (model_t *mod) { void *r; @@ -212,7 +335,7 @@ void *GLMod_Extradata (model_t *mod) if (r) return r; - GLMod_LoadModel (mod, true); + RMod_LoadModel (mod, true); if (!mod->cache.data) Sys_Error ("Mod_Extradata: caching failed"); @@ -224,7 +347,7 @@ void *GLMod_Extradata (model_t *mod) Mod_PointInLeaf =============== */ -mleaf_t *GLMod_PointInLeaf (model_t *model, vec3_t p) +mleaf_t *RMod_PointInLeaf (model_t *model, vec3_t p) { mnode_t *node; float d; @@ -263,131 +386,13 @@ mleaf_t *GLMod_PointInLeaf (model_t *model, vec3_t p) return NULL; // never reached } -#if defined(RUNTIMELIGHTING) && defined(MULTITHREAD) -void *relightthread; -volatile qboolean wantrelight; - -int RelightThread(void *arg) -{ - while (wantrelight && relitsurface < lightmodel->numsurfaces) - { - LightFace(relitsurface); - lightmodel->surfaces[relitsurface].cached_dlight = -1; - - relitsurface++; - - lightmodel->surfaces[relitsurface].cached_dlight = -1; - } - return 0; -} -#endif - -/* -=================== -Mod_ClearAll -=================== -*/ -void GLMod_ClearAll (void) -{ - int i; - int t; - model_t *mod; - -#ifdef RUNTIMELIGHTING -#ifdef MULTITHREAD - if (relightthread) - { - wantrelight = false; - Sys_WaitOnThread(relightthread); - relightthread = NULL; - } -#endif - lightmodel = NULL; -#endif - - //when the hunk is reset, all bsp models need to be reloaded - for (i=0 , mod=mod_known ; ineedload) - continue; - - if (mod->type == mod_brush) - { - for (t = 0; t < mod->numtextures; t++) - { - if (!mod->textures[t]) - continue; - GL_ClearVBO(&mod->textures[t]->vbo); - } - } - - if (mod->type != mod_alias - && mod->type != mod_halflife - ) - mod->needload = true; - } -} - -void GLMod_Think (void) -{ -#ifdef RUNTIMELIGHTING - if (lightmodel) - { - if (relitsurface >= lightmodel->numsurfaces) - { - return; - } -#ifdef MULTITHREAD - if (!relightthread) - { - wantrelight = true; - relightthread = Sys_CreateThread(RelightThread, lightmodel, 0); - } -#else - LightFace(relitsurface); - GLMod_UpdateLightmap(relitsurface); - - relitsurface++; -#endif - if (relitsurface >= lightmodel->numsurfaces) - { - char filename[MAX_QPATH]; - Con_Printf("Finished lighting %s\n", lightmodel->name); - -#ifdef MULTITHREAD - if (relightthread) - { - wantrelight = false; - Sys_WaitOnThread(relightthread); - relightthread = NULL; - } -#endif - - if (lightmodel->deluxdata) - { - COM_StripExtension(lightmodel->name, filename, sizeof(filename)); - COM_DefaultExtension(filename, ".lux", sizeof(filename)); - FS_WriteFile(filename, lightmodel->deluxdata-8, numlightdata*3+8, FS_GAME); - } - - if (writelitfile) //the user might already have a lit file (don't overwrite it). - { - COM_StripExtension(lightmodel->name, filename, sizeof(filename)); - COM_DefaultExtension(filename, ".lit", sizeof(filename)); - FS_WriteFile(filename, lightmodel->lightdata-8, numlightdata*3+8, FS_GAME); - } - } - } -#endif -} - /* ================== Mod_FindName ================== */ -model_t *GLMod_FindName (char *name) +model_t *RMod_FindName (char *name) { int i; model_t *mod; @@ -423,11 +428,11 @@ Mod_TouchModel ================== */ -void GLMod_TouchModel (char *name) +void RMod_TouchModel (char *name) { model_t *mod; - mod = GLMod_FindName (name); + mod = RMod_FindName (name); if (!mod->needload) { @@ -445,7 +450,7 @@ Mod_LoadModel Loads a model into the cache ================== */ -model_t *GLMod_LoadModel (model_t *mod, qboolean crash) +model_t *RMod_LoadModel (model_t *mod, qboolean crash) { void *d; unsigned *buf = NULL; @@ -540,7 +545,7 @@ model_t *GLMod_LoadModel (model_t *mod, qboolean crash) if (doomsprite) // special case needed for doom sprites { mod->needload = false; - GLMod_LoadDoomSprite(mod); + RMod_LoadDoomSprite(mod); P_DefaultTrail(mod); return mod; } @@ -606,13 +611,13 @@ model_t *GLMod_LoadModel (model_t *mod, qboolean crash) //Binary Sprites #ifdef SP2MODELS case IDSPRITE2HEADER: - if (!GLMod_LoadSprite2Model (mod, buf)) + if (!RMod_LoadSprite2Model (mod, buf)) continue; break; #endif case IDSPRITEHEADER: - if (!GLMod_LoadSpriteModel (mod, buf)) + if (!RMod_LoadSpriteModel (mod, buf)) continue; break; @@ -636,7 +641,7 @@ model_t *GLMod_LoadModel (model_t *mod, qboolean crash) case 30: //hl case 29: //q1 case 28: //prerel - if (!GLMod_LoadBrushModel (mod, buf)) + if (!RMod_LoadBrushModel (mod, buf)) continue; break; @@ -677,7 +682,9 @@ model_t *GLMod_LoadModel (model_t *mod, qboolean crash) return mod; } +#ifdef Q2BSPS couldntload: +#endif if (crash) Host_EndGame ("Mod_NumForName: %s not found or couldn't load", mod->name); @@ -702,13 +709,13 @@ Mod_ForName Loads in a model for the given name ================== */ -model_t *GLMod_ForName (char *name, qboolean crash) +model_t *RMod_ForName (char *name, qboolean crash) { model_t *mod; - mod = GLMod_FindName (name); + mod = RMod_FindName (name); - return GLMod_LoadModel (mod, crash); + return RMod_LoadModel (mod, crash); } @@ -722,24 +729,25 @@ model_t *GLMod_ForName (char *name, qboolean crash) qbyte *mod_base; +#if 0 char *advtexturedesc; char *mapsection; char *defaultsection; -static char *GLMod_TD_LeaveSection(char *file) +static char *RMod_TD_LeaveSection(char *file) { //recursive routine to find the next } while(file) { file = COM_Parse(file); if (*com_token == '{') - file = GLMod_TD_LeaveSection(file); + file = RMod_TD_LeaveSection(file); else if (*com_token == '}') return file; } return NULL; } -static char *GLMod_TD_Section(char *file, const char *sectionname) +static char *RMod_TD_Section(char *file, const char *sectionname) { //position within the open brace. while(file) { @@ -759,11 +767,11 @@ static char *GLMod_TD_Section(char *file, const char *sectionname) } if (*com_token == '{') - file = GLMod_TD_LeaveSection(file); + file = RMod_TD_LeaveSection(file); } return NULL; } -void GLMod_InitTextureDescs(char *mapname) +void RMod_InitTextureDescs(char *mapname) { if (advtexturedesc) FS_FreeFile(advtexturedesc); @@ -778,11 +786,11 @@ void GLMod_InitTextureDescs(char *mapname) else { FS_LoadFile(va("map.shaders", mapname), (void**)&advtexturedesc); - mapsection = GLMod_TD_Section(advtexturedesc, mapname); - defaultsection = GLMod_TD_Section(advtexturedesc, "default"); + mapsection = RMod_TD_Section(advtexturedesc, mapname); + defaultsection = RMod_TD_Section(advtexturedesc, "default"); } } -void GLMod_LoadAdvancedTextureSection(char *section, char *name, int *base, int *norm, int *luma, int *gloss, int *alphamode, qboolean *cull) //fixme: add gloss +void RMod_LoadAdvancedTextureSection(char *section, char *name, int *base, int *norm, int *luma, int *gloss, int *alphamode, qboolean *cull) //fixme: add gloss { char stdname[MAX_QPATH] = ""; char flatname[MAX_QPATH] = ""; @@ -791,7 +799,7 @@ void GLMod_LoadAdvancedTextureSection(char *section, char *name, int *base, int char lumaname[MAX_QPATH] = ""; char glossname[MAX_QPATH] = ""; - section = GLMod_TD_Section(section, name); + section = RMod_TD_Section(section, name); while(section) { @@ -860,19 +868,19 @@ void GLMod_LoadAdvancedTextureSection(char *section, char *name, int *base, int if (!*stdname && !*flatname) return; -TRACE(("dbg: GLMod_LoadAdvancedTextureSection: %s\n", name)); +TRACE(("dbg: RMod_LoadAdvancedTextureSection: %s\n", name)); if (norm && gl_bumpmappingpossible && cls.allow_bump) { *base = 0; *norm = 0; if (!*norm && *normname) - *norm = Mod_LoadHiResTexture(normname, NULL, true, false, false); + *norm = Mod_LoadHiResTexture(normname, NULL, IF_NOALPHA|IF_NOGAMMA); if (!*norm && *bumpname) *norm = Mod_LoadBumpmapTexture(bumpname, NULL); if (*norm && *flatname) - *base = Mod_LoadHiResTexture(flatname, NULL, true, false, true); + *base = Mod_LoadHiResTexture(flatname, NULL, IF_NOALPHA); } else { @@ -881,29 +889,52 @@ TRACE(("dbg: GLMod_LoadAdvancedTextureSection: %s\n", name)); *norm = 0; } if (!*base && *stdname) - *base = Mod_LoadHiResTexture(stdname, NULL, true, false, true); + *base = Mod_LoadHiResTexture(stdname, NULL, IF_NOALPHA); if (!*base && *flatname) - *base = Mod_LoadHiResTexture(flatname, NULL, true, false, true); + *base = Mod_LoadHiResTexture(flatname, NULL, IF_NOALPHA); if (luma && *lumaname) - *luma = Mod_LoadHiResTexture(lumaname, NULL, true, true, true); + *luma = Mod_LoadHiResTexture(lumaname, NULL, 0); if (*norm && gloss && *glossname && gl_specular.value) - *gloss = Mod_LoadHiResTexture(glossname, NULL, true, false, true); + *gloss = Mod_LoadHiResTexture(glossname, NULL, 0); } -void GLMod_LoadAdvancedTexture(char *name, int *base, int *norm, int *luma, int *gloss, int *alphamode, qboolean *cull) //fixme: add gloss +void RMod_LoadAdvancedTexture(char *name, int *base, int *norm, int *luma, int *gloss, int *alphamode, qboolean *cull) //fixme: add gloss { if (!gl_load24bit.value) return; if (mapsection) { - GLMod_LoadAdvancedTextureSection(mapsection, name,base,norm,luma,gloss,alphamode,cull); + RMod_LoadAdvancedTextureSection(mapsection, name,base,norm,luma,gloss,alphamode,cull); if (*base) return; } if (defaultsection) - GLMod_LoadAdvancedTextureSection(defaultsection, name,base,norm,luma,gloss,alphamode,cull); + RMod_LoadAdvancedTextureSection(defaultsection, name,base,norm,luma,gloss,alphamode,cull); +} +#endif + +void Mod_FinishTexture(texture_t *tx, texnums_t tn) +{ + extern cvar_t gl_shadeq1_name; + char altname[MAX_QPATH]; + char *star; + //find the * + if (!*gl_shadeq1_name.string || !strcmp(gl_shadeq1_name.string, "*")) + tx->shader = R_RegisterShader_Lightmap(tx->name); //just load the regular name. + else if (!(star = strchr(gl_shadeq1_name.string, '*')) || (strlen(gl_shadeq1_name.string)+strlen(tx->name)+1>=sizeof(altname))) //it's got to fit. + tx->shader = R_RegisterShader_Lightmap(gl_shadeq1_name.string); + else + { + strncpy(altname, gl_shadeq1_name.string, star-gl_shadeq1_name.string); //copy the left + altname[star-gl_shadeq1_name.string] = '\0'; + strcat(altname, tx->name); //insert the * + strcat(altname, star+1); //add any final text. + tx->shader = R_RegisterShader_Lightmap(altname); + } + + R_BuildDefaultTexnums(&tn, tx->shader); } /* @@ -911,7 +942,7 @@ void GLMod_LoadAdvancedTexture(char *name, int *base, int *norm, int *luma, int Mod_LoadTextures ================= */ -qboolean GLMod_LoadTextures (lump_t *l) +qboolean RMod_LoadTextures (lump_t *l) { extern int gl_bumpmappingpossible; int i, j, pixels, num, max, altmax; @@ -923,10 +954,11 @@ qboolean GLMod_LoadTextures (lump_t *l) dmiptexlump_t *m; qboolean alphaed; qbyte *base; + texnums_t tn; -TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n")); +TRACE(("dbg: RMod_LoadTextures: inittexturedescs\n")); - GLMod_InitTextureDescs(loadname); +// RMod_InitTextureDescs(loadname); if (!l->filelen) { @@ -954,7 +986,7 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n")); } mt = (miptex_t *)((qbyte *)m + m->dataofs[i]); - TRACE(("dbg: GLMod_LoadTextures: texture %s\n", loadname)); + TRACE(("dbg: RMod_LoadTextures: texture %s\n", loadname)); if (!*mt->name) //I HATE MAPPERS! { @@ -986,20 +1018,23 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n")); continue; } + memset(&tn, 0, sizeof(tn)); + if (!Q_strncmp(mt->name,"sky",3)) { tx->offsets[0] = (char *)mt + mt->offsets[0] - (char *)tx; - R_InitSky (tx); + tn = R_InitSky (tx); } else #ifdef PEXT_BULLETENS if (!R_AddBulleten(tx)) #endif { - tx->tn.base = 0; - GLMod_LoadAdvancedTexture(tx->name, &tx->tn.base, &tx->tn.bump, &tx->tn.fullbright, &tx->tn.specular, NULL, NULL); - if (tx->tn.base) +/* + RMod_LoadAdvancedTexture(tx->name, &tn.base, &tn.bump, &tn.fullbright, &tn.specular, NULL, NULL); + if (tn.base) continue; +*/ base = (qbyte *)(mt+1); @@ -1007,75 +1042,101 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n")); {//external textures have already been filtered. base = W_ConvertWAD3Texture(mt, &mt->width, &mt->height, &alphaed); //convert texture to 32 bit. tx->alphaed = alphaed; - if (!(tx->tn.base = Mod_LoadReplacementTexture(mt->name, loadname, true, alphaed, true))) - if (!(tx->tn.base = Mod_LoadReplacementTexture(mt->name, "bmodels", true, alphaed, true))) - tx->tn.base = R_LoadTexture32 (mt->name, tx->width, tx->height, (unsigned int *)base, true, alphaed); + tn.base = R_LoadReplacementTexture(mt->name, loadname, alphaed?0:IF_NOALPHA); + if (!TEXVALID(tn.base)) + { + tn.base = R_LoadReplacementTexture(mt->name, "bmodels", alphaed?0:IF_NOALPHA); + if (!TEXVALID(tn.base)) + tn.base = R_LoadTexture32 (mt->name, tx->width, tx->height, (unsigned int *)base, (alphaed?0:IF_NOALPHA)); + } *tx->name = *mt->name; } else { - if (!(tx->tn.base = Mod_LoadReplacementTexture(mt->name, loadname, true, false, true))) - if (!(tx->tn.base = Mod_LoadReplacementTexture(mt->name, "bmodels", true, false, true))) - tx->tn.base = R_LoadTexture8 (mt->name, tx->width, tx->height, base, true, false); + qbyte *mipbase; + unsigned int mipwidth, mipheight; + extern cvar_t gl_miptexLevel; + if ((unsigned int)gl_miptexLevel.ival < 4 && mt->offsets[gl_miptexLevel.ival]) + { + mipbase = (qbyte*)mt + mt->offsets[gl_miptexLevel.ival]; + mipwidth = tx->width>>gl_miptexLevel.ival; + mipheight = tx->height>>gl_miptexLevel.ival; + } + else + { + mipbase = base; + mipwidth = tx->width; + mipheight = tx->height; + } + + tn.base = R_LoadReplacementTexture(mt->name, loadname, IF_NOALPHA); + if (!TEXVALID(tn.base)) + { + tn.base = R_LoadReplacementTexture(mt->name, "bmodels", IF_NOALPHA); + if (!TEXVALID(tn.base)) + tn.base = R_LoadTexture8 (mt->name, mipwidth, mipheight, mipbase, IF_NOALPHA, 1); + } if (r_fb_bmodels.value) { snprintf(altname, sizeof(altname)-1, "%s_luma", mt->name); if (gl_load24bit.value) { - tx->tn.fullbright = Mod_LoadReplacementTexture(altname, loadname, true, false, true); - if (!tx->tn.fullbright) - tx->tn.fullbright = Mod_LoadReplacementTexture(altname, "bmodels", true, false, true); + tn.fullbright = R_LoadReplacementTexture(altname, loadname, IF_NOALPHA); + if (!TEXVALID(tn.fullbright)) + tn.fullbright = R_LoadReplacementTexture(altname, "bmodels", IF_NOALPHA); } - if (!tx->tn.fullbright) //generate one (if possible). - tx->tn.fullbright = R_LoadTextureFB(altname, tx->width, tx->height, base, true, true); + if (!TEXVALID(tn.fullbright)) //generate one (if possible). + tn.fullbright = R_LoadTextureFB(altname, mipwidth, mipheight, mipbase, IF_NOGAMMA); } } - tx->tn.bump = 0; + tn.bump = r_nulltex; if (gl_bumpmappingpossible && cls.allow_bump) { extern cvar_t gl_bump; - if (gl_bump.value<2) //set to 2 to have faster loading. + if (gl_bump.ival<2) //set to 2 to have faster loading. { snprintf(altname, sizeof(altname)-1, "%s_norm", mt->name); - tx->tn.bump = Mod_LoadHiResTexture(altname, loadname, true, false, false); - if (!tx->tn.bump) - tx->tn.bump = Mod_LoadHiResTexture(altname, "bmodels", true, false, false); + tn.bump = R_LoadReplacementTexture(altname, loadname, IF_NOALPHA|IF_NOGAMMA); + if (!TEXVALID(tn.bump)) + tn.bump = R_LoadReplacementTexture(altname, "bmodels", IF_NOALPHA|IF_NOGAMMA); } - if (!tx->tn.bump) + if (!TEXVALID(tn.bump)) { if (gl_load24bit.value) { snprintf(altname, sizeof(altname)-1, "%s_bump", mt->name); - tx->tn.bump = Mod_LoadBumpmapTexture(altname, loadname); - if (!tx->tn.bump) - tx->tn.bump = Mod_LoadBumpmapTexture(altname, "bmodels"); + tn.bump = R_LoadBumpmapTexture(altname, loadname); + if (!TEXVALID(tn.bump)) + tn.bump = R_LoadBumpmapTexture(altname, "bmodels"); } else snprintf(altname, sizeof(altname)-1, "%s_bump", mt->name); } - if (!(tx->tn.bump) && loadmodel->fromgame != fg_halflife) + if (!TEXVALID(tn.bump) && loadmodel->fromgame != fg_halflife) { + //no mip levels here, would be absurd. base = (qbyte *)(mt+1); //convert to greyscale. for (j = 0; j < pixels; j++) base[j] = (host_basepal[base[j]*3] + host_basepal[base[j]*3+1] + host_basepal[base[j]*3+2]) / 3; - tx->tn.bump = R_LoadTexture8Bump(altname, tx->width, tx->height, base, true, r_shadow_bumpscale_basetexture.value); //normalise it and then bump it. + tn.bump = R_LoadTexture8Bump(altname, tx->width, tx->height, base, true, r_shadow_bumpscale_basetexture.value); //normalise it and then bump it. } //don't do any complex quake 8bit -> glossmap. It would likly look a little ugly... if (gl_specular.value && gl_load24bit.value) { snprintf(altname, sizeof(altname)-1, "%s_gloss", mt->name); - tx->tn.specular = Mod_LoadHiResTexture(altname, loadname, true, false, false); - if (!tx->tn.specular) - tx->tn.specular = Mod_LoadHiResTexture(altname, "bmodels", true, false, false); + tn.specular = R_LoadHiResTexture(altname, loadname, IF_NOALPHA|IF_NOGAMMA); + if (!TEXVALID(tn.specular)) + tn.specular = R_LoadHiResTexture(altname, "bmodels", IF_NOALPHA|IF_NOGAMMA); } } } + Mod_FinishTexture(tx, tn); } // // sequence the animations @@ -1185,14 +1246,13 @@ TRACE(("dbg: GLMod_LoadTextures: inittexturedescs\n")); return true; } -void GLMod_NowLoadExternal(void) +void RMod_NowLoadExternal(void) { - extern cvar_t gl_shadeq1, gl_shadeq1_name; - extern int gl_bumpmappingpossible; int i, width, height; qboolean alphaed; texture_t *tx; + texnums_t tn; for (i=0 ; inumtextures ; i++) { @@ -1200,7 +1260,12 @@ void GLMod_NowLoadExternal(void) if (!tx) //e1m2, this happens continue; - if (!tx->tn.base) + if (tx->shader) + continue; + + memset (&tn, 0, sizeof(tn)); + + if (!TEXVALID(tn.base)) { #ifdef PEXT_BULLETENS if (!R_AddBulleten(tx)) @@ -1213,18 +1278,22 @@ void GLMod_NowLoadExternal(void) { //data is from temp hunk, so no need to free. tx->alphaed = alphaed; } - - if (!(tx->tn.base = Mod_LoadHiResTexture(tx->name, loadname, true, false, true))) - if (!(tx->tn.base = Mod_LoadHiResTexture(tx->name, "bmodels", true, false, true))) - tx->tn.base = Mod_LoadReplacementTexture("light1_4", NULL, true, false, true); //a fallback. :/ + + tn.base = R_LoadHiResTexture(tx->name, loadname, IF_NOALPHA); + if (!TEXVALID(tn.base)) + { + tn.base = R_LoadHiResTexture(tx->name, "bmodels", IF_NOALPHA); + if (!TEXVALID(tn.base)) + tn.base = R_LoadReplacementTexture("light1_4", NULL, IF_NOALPHA); //a fallback. :/ + } } } - if (!tx->tn.bump && *tx->name != '{' && gl_bumpmappingpossible && cls.allow_bump) + if (!TEXVALID(tn.bump) && *tx->name != '{' && gl_bumpmappingpossible && cls.allow_bump) { - tx->tn.bump = Mod_LoadBumpmapTexture(va("%s_bump", tx->name), loadname); - if (!tx->tn.bump) - tx->tn.bump = Mod_LoadBumpmapTexture(va("%s_bump", tx->name), "bmodels"); - if (!tx->tn.bump) + tn.bump = R_LoadBumpmapTexture(va("%s_bump", tx->name), loadname); + if (!TEXVALID(tn.bump)) + tn.bump = R_LoadBumpmapTexture(va("%s_bump", tx->name), "bmodels"); + if (!TEXVALID(tn.bump)) { qbyte *data; qbyte *heightmap; @@ -1232,45 +1301,19 @@ void GLMod_NowLoadExternal(void) int j; data = W_GetTexture(tx->name, &width, &height, &alphaed); - if (!data) - continue; - - heightmap = Hunk_TempAllocMore(width*height); - for (j = 0; j < width*height; j++) + if (data) { - *heightmap++ = (data[j*4+0] + data[j*4+1] + data[j*4+2])/3; + heightmap = Hunk_TempAllocMore(width*height); + for (j = 0; j < width*height; j++) + { + *heightmap++ = (data[j*4+0] + data[j*4+1] + data[j*4+2])/3; + } + + tn.bump = R_LoadTexture8Bump (va("%s_bump", tx->name), width, height, heightmap-j, true, r_shadow_bumpscale_basetexture.value); } - - tx->tn.bump = R_LoadTexture8Bump (va("%s_bump", tx->name), width, height, heightmap-j, true, r_shadow_bumpscale_basetexture.value); } } - - -#ifdef NEWBACKEND - tx->shader = R_RegisterCustom(tx->name, Shader_DefaultBSP, &tx->tn); -#pragma message("warning: fix the following block") -#endif -#ifdef Q3SHADERS //load q3 syntax shader last, after the textures inside the bsp have been loaded and stuff. - if (cls.allow_shaders && gl_shadeq1.value && *gl_shadeq1_name.string) - { - char altname[MAX_QPATH]; - char *star; - //find the * - if (!strcmp(gl_shadeq1_name.string, "*")) - // tx->shader = R_RegisterCustom(mt->name, NULL); //just load the regular name. - tx->shader = R_RegisterShader(tx->name); //just load the regular name. - else if (!(star = strchr(gl_shadeq1_name.string, '*')) || (strlen(gl_shadeq1_name.string)+strlen(tx->name)+1>=sizeof(altname))) //it's got to fit. - tx->shader = R_RegisterCustom(gl_shadeq1_name.string, NULL, NULL); - else - { - strncpy(altname, gl_shadeq1_name.string, star-gl_shadeq1_name.string); //copy the left - altname[star-gl_shadeq1_name.string] = '\0'; - strcat(altname, tx->name); //insert the * - strcat(altname, star+1); //add any final text. - tx->shader = R_RegisterCustom(altname, NULL, NULL); - } - } -#endif + Mod_FinishTexture(tx, tn); } } @@ -1306,7 +1349,7 @@ void BuildLightMapGammaTable (float g, float c) Mod_LoadLighting ================= */ -void GLMod_LoadLighting (lump_t *l) +void RMod_LoadLighting (lump_t *l) { qbyte *luxdata = NULL; int mapcomeswith24bitcolouredlighting = false; @@ -1346,8 +1389,13 @@ void GLMod_LoadLighting (lump_t *l) luxdata = COM_LoadHunkFile(luxname); } - COM_StripExtension(COM_SkipPath(loadmodel->name), luxname+5, sizeof(luxname)-5); - strcat(luxname, ".lux"); + if (!luxdata) + { + COM_StripExtension(COM_SkipPath(loadmodel->name), luxname+5, sizeof(luxname)-5); + COM_DefaultExtension(luxname, ".dlit", sizeof(luxname)); + luxdata = COM_LoadHunkFile(luxname); + } + if (luxdata) { if (l->filelen && l->filelen != (com_filesize-8)/3) @@ -1494,8 +1542,12 @@ void GLMod_LoadLighting (lump_t *l) loadmodel->deluxdata += 8; litdata = loadmodel->deluxdata; { - for (i = 0; i < l->filelen*3; i++) + for (i = 0; i < l->filelen; i++) + { *litdata++ = 0.5f*255; + *litdata++ = 0.5f*255; + *litdata++ = 255; + } } } @@ -1541,7 +1593,7 @@ void GLMod_LoadLighting (lump_t *l) Mod_LoadVisibility ================= */ -void GLMod_LoadVisibility (lump_t *l) +void RMod_LoadVisibility (lump_t *l) { if (!l->filelen) { @@ -1558,7 +1610,7 @@ void GLMod_LoadVisibility (lump_t *l) Mod_LoadEntities ================= */ -void GLMod_LoadEntities (lump_t *l) +void RMod_LoadEntities (lump_t *l) { if (!l->filelen) { @@ -1576,7 +1628,7 @@ void GLMod_LoadEntities (lump_t *l) Mod_LoadVertexes ================= */ -qboolean GLMod_LoadVertexes (lump_t *l) +qboolean RMod_LoadVertexes (lump_t *l) { dvertex_t *in; mvertex_t *out; @@ -1610,7 +1662,7 @@ Mod_LoadSubmodels ================= */ static qboolean hexen2map; -qboolean GLMod_LoadSubmodels (lump_t *l) +qboolean RMod_LoadSubmodels (lump_t *l) { dq1model_t *inq; dh2model_t *inh; @@ -1705,7 +1757,7 @@ qboolean GLMod_LoadSubmodels (lump_t *l) Mod_LoadEdges ================= */ -qboolean GLMod_LoadEdges (lump_t *l) +qboolean RMod_LoadEdges (lump_t *l) { dedge_t *in; medge_t *out; @@ -1737,7 +1789,7 @@ qboolean GLMod_LoadEdges (lump_t *l) Mod_LoadTexinfo ================= */ -qboolean GLMod_LoadTexinfo (lump_t *l) +qboolean RMod_LoadTexinfo (lump_t *l) { texinfo_t *in; mtexinfo_t *out; @@ -1863,7 +1915,7 @@ void CalcSurfaceExtents (msurface_t *s); Mod_LoadFaces ================= */ -qboolean GLMod_LoadFaces (lump_t *l) +qboolean RMod_LoadFaces (lump_t *l) { dface_t *in; msurface_t *out; @@ -1943,7 +1995,7 @@ qboolean GLMod_LoadFaces (lump_t *l) }*/ if (!Q_strncmp(out->texinfo->texture->name,"{",1)) // alpha { - out->texinfo->flags |= SURF_ALPHATEST; + out->texinfo->flags |= TI_ALPHATEST; out->flags |= (SURF_DRAWALPHA); continue; } @@ -1965,15 +2017,15 @@ qboolean GLMod_LoadFaces (lump_t *l) Mod_SetParent ================= */ -void GLMod_SetParent (mnode_t *node, mnode_t *parent) +void RMod_SetParent (mnode_t *node, mnode_t *parent) { if (!node) return; node->parent = parent; if (node->contents < 0) return; - GLMod_SetParent (node->children[0], node); - GLMod_SetParent (node->children[1], node); + RMod_SetParent (node->children[0], node); + RMod_SetParent (node->children[1], node); } /* @@ -1981,7 +2033,7 @@ void GLMod_SetParent (mnode_t *node, mnode_t *parent) Mod_LoadNodes ================= */ -qboolean GLMod_LoadNodes (lump_t *l) +qboolean RMod_LoadNodes (lump_t *l) { int i, j, count, p; dnode_t *in; @@ -2023,7 +2075,7 @@ qboolean GLMod_LoadNodes (lump_t *l) } } - GLMod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs + RMod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs return true; } @@ -2032,7 +2084,7 @@ qboolean GLMod_LoadNodes (lump_t *l) Mod_LoadLeafs ================= */ -qboolean GLMod_LoadLeafs (lump_t *l) +qboolean RMod_LoadLeafs (lump_t *l) { dleaf_t *in; mleaf_t *out; @@ -2107,7 +2159,7 @@ void *suplementryclipnodes; void *suplementryplanes; void *crouchhullfile; -void GLMod_LoadCrouchHull(void) +void RMod_LoadCrouchHull(void) { int i, h; int numsm; @@ -2178,7 +2230,7 @@ void GLMod_LoadCrouchHull(void) Mod_LoadClipnodes ================= */ -qboolean GLMod_LoadClipnodes (lump_t *l) +qboolean RMod_LoadClipnodes (lump_t *l) { dclipnode_t *in, *out; int i, count; @@ -2392,7 +2444,7 @@ Mod_MakeHull0 Deplicate the drawing hull structure as a clipping hull ================= */ -void GLMod_MakeHull0 (void) +void RMod_MakeHull0 (void) { mnode_t *in, *child; dclipnode_t *out; @@ -2429,7 +2481,7 @@ void GLMod_MakeHull0 (void) Mod_LoadMarksurfaces ================= */ -qboolean GLMod_LoadMarksurfaces (lump_t *l) +qboolean RMod_LoadMarksurfaces (lump_t *l) { int i, j, count; short *in; @@ -2466,7 +2518,7 @@ qboolean GLMod_LoadMarksurfaces (lump_t *l) Mod_LoadSurfedges ================= */ -qboolean GLMod_LoadSurfedges (lump_t *l) +qboolean RMod_LoadSurfedges (lump_t *l) { int i, count; int *in, *out; @@ -2495,7 +2547,7 @@ qboolean GLMod_LoadSurfedges (lump_t *l) Mod_LoadPlanes ================= */ -qboolean GLMod_LoadPlanes (lump_t *l) +qboolean RMod_LoadPlanes (lump_t *l) { int i, j; mplane_t *out; @@ -2578,7 +2630,7 @@ float RadiusFromBounds (vec3_t mins, vec3_t maxs); void GLR_StainSurf (msurface_t *surf, float *parms); static void Q1BSP_StainNode (mnode_t *node, float *parms) { -#ifdef RGLQUAKE +#ifdef GLQUAKE mplane_t *splitplane; float dist; msurface_t *surf; @@ -2621,15 +2673,15 @@ qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, void GLQ1BSP_LightPointValues(model_t *model, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir); -void GLMod_FixupNodeMinsMaxs (mnode_t *node, mnode_t *parent) +void RMod_FixupNodeMinsMaxs (mnode_t *node, mnode_t *parent) { if (!node) return; if (node->contents >= 0) { - GLMod_FixupNodeMinsMaxs (node->children[0], node); - GLMod_FixupNodeMinsMaxs (node->children[1], node); + RMod_FixupNodeMinsMaxs (node->children[0], node); + RMod_FixupNodeMinsMaxs (node->children[1], node); } if (parent) @@ -2650,7 +2702,7 @@ void GLMod_FixupNodeMinsMaxs (mnode_t *node, mnode_t *parent) } } -void GLMod_FixupMinsMaxs(void) +void RMod_FixupMinsMaxs(void) { //q1 bsps are capped to +/- 32767 by the nodes/leafs //verts arn't though @@ -2733,7 +2785,7 @@ void GLMod_FixupMinsMaxs(void) } while (--c); } } - GLMod_FixupNodeMinsMaxs (loadmodel->nodes, NULL); // sets nodes and leafs + RMod_FixupNodeMinsMaxs (loadmodel->nodes, NULL); // sets nodes and leafs } /* @@ -2741,7 +2793,7 @@ void GLMod_FixupMinsMaxs(void) Mod_LoadBrushModel ================= */ -qboolean GLMod_LoadBrushModel (model_t *mod, void *buffer) +qboolean RMod_LoadBrushModel (model_t *mod, void *buffer) { int i, j; dheader_t *header; @@ -2759,7 +2811,7 @@ qboolean GLMod_LoadBrushModel (model_t *mod, void *buffer) if ((!cl.worldmodel && cls.state>=ca_connected) #ifndef CLIENTONLY - || (!sv.worldmodel && sv.active) + || (!sv.world.worldmodel && sv.active) #endif ) isnotmap = false; @@ -2828,34 +2880,34 @@ qboolean GLMod_LoadBrushModel (model_t *mod, void *buffer) if (!isDedicated) #endif { - noerrors = noerrors && GLMod_LoadVertexes (&header->lumps[LUMP_VERTEXES]); - noerrors = noerrors && GLMod_LoadEdges (&header->lumps[LUMP_EDGES]); - noerrors = noerrors && GLMod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]); - noerrors = noerrors && GLMod_LoadTextures (&header->lumps[LUMP_TEXTURES]); + noerrors = noerrors && RMod_LoadVertexes (&header->lumps[LUMP_VERTEXES]); + noerrors = noerrors && RMod_LoadEdges (&header->lumps[LUMP_EDGES]); + noerrors = noerrors && RMod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]); + noerrors = noerrors && RMod_LoadTextures (&header->lumps[LUMP_TEXTURES]); if (noerrors) - GLMod_LoadLighting (&header->lumps[LUMP_LIGHTING]); + RMod_LoadLighting (&header->lumps[LUMP_LIGHTING]); } - noerrors = noerrors && GLMod_LoadSubmodels (&header->lumps[LUMP_MODELS]); + noerrors = noerrors && RMod_LoadSubmodels (&header->lumps[LUMP_MODELS]); if (noerrors) - GLMod_LoadCrouchHull(); - noerrors = noerrors && GLMod_LoadPlanes (&header->lumps[LUMP_PLANES]); + RMod_LoadCrouchHull(); + noerrors = noerrors && RMod_LoadPlanes (&header->lumps[LUMP_PLANES]); #ifndef CLIENTONLY if (!isDedicated) #endif { - noerrors = noerrors && GLMod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]); - noerrors = noerrors && GLMod_LoadFaces (&header->lumps[LUMP_FACES]); - noerrors = noerrors && GLMod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]); + noerrors = noerrors && RMod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]); + noerrors = noerrors && RMod_LoadFaces (&header->lumps[LUMP_FACES]); + noerrors = noerrors && RMod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]); } if (noerrors) - GLMod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]); - noerrors = noerrors && GLMod_LoadLeafs (&header->lumps[LUMP_LEAFS]); - noerrors = noerrors && GLMod_LoadNodes (&header->lumps[LUMP_NODES]); - noerrors = noerrors && GLMod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]); + RMod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]); + noerrors = noerrors && RMod_LoadLeafs (&header->lumps[LUMP_LEAFS]); + noerrors = noerrors && RMod_LoadNodes (&header->lumps[LUMP_NODES]); + noerrors = noerrors && RMod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]); if (noerrors) { - GLMod_LoadEntities (&header->lumps[LUMP_ENTITIES]); - GLMod_MakeHull0 (); + RMod_LoadEntities (&header->lumps[LUMP_ENTITIES]); + RMod_MakeHull0 (); } if (crouchhullfile) @@ -2942,7 +2994,7 @@ qboolean GLMod_LoadBrushModel (model_t *mod, void *buffer) #endif if (1) - GLMod_FixupMinsMaxs(); + RMod_FixupMinsMaxs(); return true; } @@ -2998,7 +3050,7 @@ typedef struct else if (pos[off] != 255) fdc = pos[off]; \ } -void GLMod_FloodFillSkin( qbyte *skin, int skinwidth, int skinheight ) +void RMod_FloodFillSkin( qbyte *skin, int skinwidth, int skinheight ) { qbyte fillcolor = *skin; // assume this is the pixel to fill floodfill_t fifo[FLOODFILL_FIFO_SIZE]; @@ -3051,12 +3103,13 @@ void GLMod_FloodFillSkin( qbyte *skin, int skinwidth, int skinheight ) Mod_LoadSpriteFrame ================= */ -void * GLMod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum, int version, unsigned char *palette) +void * RMod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum, int version, unsigned char *palette) { dspriteframe_t *pinframe; mspriteframe_t *pspriteframe; int width, height, size, origin[2]; char name[64]; + texid_t texnum; pinframe = (dspriteframe_t *)pin; @@ -3070,8 +3123,6 @@ void * GLMod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum *ppframe = pspriteframe; - pspriteframe->p.width = width; - pspriteframe->p.height = height; origin[0] = LittleLong (pinframe->origin[0]); origin[1] = LittleLong (pinframe->origin[1]); @@ -3080,48 +3131,63 @@ void * GLMod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum pspriteframe->left = origin[0]; pspriteframe->right = width + origin[0]; - pspriteframe->p.d.gl.texnum = 0; - pspriteframe->p.d.gl.sl = 0; - pspriteframe->p.d.gl.sh = 1; - pspriteframe->p.d.gl.tl = 0; - pspriteframe->p.d.gl.th = 1; + texnum = r_nulltex; - if (!pspriteframe->p.d.gl.texnum) + if (!TEXVALID(texnum)) { //the dp way - COM_StripExtension(loadmodel->name, name, sizeof(name)); + Q_strncpyz(name, loadmodel->name, sizeof(name)); Q_strncatz(name, va("_%i", framenum), sizeof(name)); - pspriteframe->p.d.gl.texnum = Mod_LoadReplacementTexture(name, "sprites", true, true, true); + texnum = R_LoadReplacementTexture(name, "sprites", 0); } - if (!pspriteframe->p.d.gl.texnum) + if (!TEXVALID(texnum)) { //the older fte way. COM_StripExtension(loadmodel->name, name, sizeof(name)); Q_strncatz(name, va("_%i", framenum), sizeof(name)); - pspriteframe->p.d.gl.texnum = Mod_LoadReplacementTexture(name, "sprites", true, true, true); + texnum = R_LoadReplacementTexture(name, "sprites", 0); } - if (!pspriteframe->p.d.gl.texnum) + if (!TEXVALID(texnum)) { //the fuhquake way COM_StripExtension(COM_SkipPath(loadmodel->name), name, sizeof(name)); Q_strncatz(name, va("_%i", framenum), sizeof(name)); - pspriteframe->p.d.gl.texnum = Mod_LoadReplacementTexture(name, "sprites", true, true, true); + texnum = R_LoadReplacementTexture(name, "sprites", 0); } if (version == SPRITE32_VERSION) { size *= 4; - if (!pspriteframe->p.d.gl.texnum) - pspriteframe->p.d.gl.texnum = R_LoadTexture32 (name, width, height, (unsigned *)(pinframe + 1), true, true); + if (!TEXVALID(texnum)) + texnum = R_LoadTexture32 (name, width, height, (unsigned *)(pinframe + 1), IF_NOGAMMA); } +#pragma message("no hl sprites") +#ifdef R_LoadTexture8Pal32 else if (version == SPRITEHL_VERSION) { - if (!pspriteframe->p.d.gl.texnum) - pspriteframe->p.d.gl.texnum = R_LoadTexture8Pal32 (name, width, height, (qbyte *)(pinframe + 1), (qbyte*)palette, true, true); + if (!TEXVALID(texnum)) + texnum = R_LoadTexture8Pal32 (name, width, height, (qbyte *)(pinframe + 1), (qbyte*)palette, IF_NOGAMMA); } +#endif else { - if (!pspriteframe->p.d.gl.texnum) - pspriteframe->p.d.gl.texnum = R_LoadTexture8 (name, width, height, (qbyte *)(pinframe + 1), true, true); + if (!TEXVALID(texnum)) + texnum = R_LoadTexture8 (name, width, height, (qbyte *)(pinframe + 1), IF_NOMIPMAP|IF_NOALPHA|IF_NOGAMMA, 1); } + Q_strncpyz(name, loadmodel->name, sizeof(name)); + Q_strncatz(name, va("_%i", framenum), sizeof(name)); + pspriteframe->shader = R_RegisterShader(name, + "{\n" + "{\n" + "map $diffuse\n" + "blendfunc blend\n" + "rgbgen entity\n" + "alphagen entity\n" + "}\n" + "}\n" + ); + pspriteframe->shader->defaulttextures.base = texnum; + pspriteframe->shader->width = width; + pspriteframe->shader->height = height; + return (void *)((qbyte *)(pinframe+1) + size); } @@ -3131,7 +3197,7 @@ void * GLMod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum Mod_LoadSpriteGroup ================= */ -void * GLMod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe, int framenum, int version, unsigned char *palette) +void * RMod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe, int framenum, int version, unsigned char *palette) { dspritegroup_t *pingroup; mspritegroup_t *pspritegroup; @@ -3174,7 +3240,7 @@ void * GLMod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe, int framenum for (i=0 ; iframes[i], framenum * 100 + i, version, palette); + ptemp = RMod_LoadSpriteFrame (ptemp, &pspritegroup->frames[i], framenum * 100 + i, version, palette); } return ptemp; @@ -3185,7 +3251,7 @@ void * GLMod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe, int framenum Mod_LoadSpriteModel ================= */ -qboolean GLMod_LoadSpriteModel (model_t *mod, void *buffer) +qboolean RMod_LoadSpriteModel (model_t *mod, void *buffer) { int i; int version; @@ -3287,13 +3353,13 @@ qboolean GLMod_LoadSpriteModel (model_t *mod, void *buffer) if (frametype == SPR_SINGLE) { pframetype = (dspriteframetype_t *) - GLMod_LoadSpriteFrame (pframetype + 1, + RMod_LoadSpriteFrame (pframetype + 1, &psprite->frames[i].frameptr, i, version, pal); } else { pframetype = (dspriteframetype_t *) - GLMod_LoadSpriteGroup (pframetype + 1, + RMod_LoadSpriteGroup (pframetype + 1, &psprite->frames[i].frameptr, i, version, pal); } if (pframetype == NULL) @@ -3308,7 +3374,7 @@ qboolean GLMod_LoadSpriteModel (model_t *mod, void *buffer) return true; } -qboolean GLMod_LoadSprite2Model (model_t *mod, void *buffer) +qboolean RMod_LoadSprite2Model (model_t *mod, void *buffer) { int i; int version; @@ -3318,6 +3384,7 @@ qboolean GLMod_LoadSprite2Model (model_t *mod, void *buffer) int size; dmd2sprframe_t *pframetype; mspriteframe_t *frame; + int w, h; float origin[2]; int hunkstart; @@ -3376,17 +3443,17 @@ qboolean GLMod_LoadSprite2Model (model_t *mod, void *buffer) frame = psprite->frames[i].frameptr = Hunk_AllocName(sizeof(mspriteframe_t), loadname); - frame->p.d.gl.texnum = Mod_LoadHiResTexture(pframetype->name, NULL, true, true, true); + frame->shader = R_RegisterPic(pframetype->name); - frame->p.width = LittleLong(pframetype->width); - frame->p.height = LittleLong(pframetype->height); + w = LittleLong(pframetype->width); + h = LittleLong(pframetype->height); origin[0] = LittleLong (pframetype->origin_x); origin[1] = LittleLong (pframetype->origin_y); frame->up = -origin[1]; - frame->down = frame->p.height - origin[1]; + frame->down = h - origin[1]; frame->left = -origin[0]; - frame->right = frame->p.width - origin[0]; + frame->right = w - origin[0]; pframetype++; } @@ -3515,7 +3582,7 @@ static void LoadDoomSpriteFrame(char *imagename, mspriteframedesc_t *pdesc, int Doom Sprites ================= */ -void GLMod_LoadDoomSprite (model_t *mod) +void RMod_LoadDoomSprite (model_t *mod) { char files[16384]; char basename[MAX_QPATH]; @@ -3612,7 +3679,7 @@ void GLMod_LoadDoomSprite (model_t *mod) Mod_Print ================ */ -void GLMod_Print (void) +void RMod_Print (void) { int i; model_t *mod; diff --git a/engine/gl/gl_model.h b/engine/gl/gl_model.h index f3b1b8e2..bfd57aa0 100644 --- a/engine/gl/gl_model.h +++ b/engine/gl/gl_model.h @@ -26,7 +26,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. struct hull_s; struct trace_s; -struct edict_s; +struct wedict_s; +struct model_s; +struct world_s; typedef struct { // qboolean (*RecursiveHullCheck) (struct hull_s *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, struct trace_s *trace); @@ -36,6 +38,8 @@ typedef struct { typedef struct { //deals with FTECONTENTS (assumes against solid) + void (*PurgeModel) (struct model_s *mod); + qboolean (*Trace) (struct model_s *model, int hulloverride, int frame, vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, struct trace_s *trace); unsigned int (*PointContents) (struct model_s *model, vec3_t p); unsigned int (*BoxContents) (struct model_s *model, int hulloverride, int frame, vec3_t p, vec3_t mins, vec3_t maxs); @@ -45,8 +49,8 @@ typedef struct { unsigned int (*NativeContents)(struct model_s *model, int hulloverride, int frame, vec3_t p, vec3_t mins, vec3_t maxs); unsigned int (*FatPVS) (struct model_s *model, vec3_t org, qbyte *pvsbuffer, unsigned int buffersize, qboolean merge); - qboolean (*EdictInFatPVS) (struct model_s *model, struct edict_s *edict, qbyte *pvsbuffer); - void (*FindTouchedLeafs_Q1) (struct model_s *model, struct edict_s *ent, vec3_t cullmins, vec3_t cullmaxs); //edict system as opposed to q2 game dll system. + qboolean (*EdictInFatPVS) (struct model_s *model, struct wedict_s *edict, qbyte *pvsbuffer); + void (*FindTouchedLeafs_Q1) (struct world_s *w, struct model_s *model, struct wedict_s *ent, vec3_t cullmins, vec3_t cullmaxs); //edict system as opposed to q2 game dll system. void (*LightPointValues) (struct model_s *model, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir); void (*StainNode) (struct mnode_s *node, float *parms); @@ -54,19 +58,7 @@ typedef struct { qbyte *(*LeafPVS) (struct model_s *model, int num, qbyte *buffer, unsigned int buffersize); int (*LeafnumForPoint) (struct model_s *model, vec3_t point); -} bspfuncs_t; - -#ifdef D3DQUAKE - #define sizeof_index_t 2 -#endif - -#if sizeof_index_t == 2 - #define GL_INDEX_TYPE GL_UNSIGNED_SHORT - typedef unsigned short index_t; -#else - #define GL_INDEX_TYPE GL_UNSIGNED_INT - typedef unsigned int index_t; -#endif +} modelfuncs_t; typedef struct mesh_s { @@ -75,13 +67,14 @@ typedef struct mesh_s int numvertexes; - vec3_t *xyz_array; + vecV_t *xyz_array; vec3_t *normals_array; vec3_t *snormals_array; vec3_t *tnormals_array; vec2_t *st_array; vec2_t *lmst_array; - byte_vec4_t *colors_array; + avec4_t *colors4f_array; + byte_vec4_t *colors4b_array; int numindexes; index_t *indexes; @@ -91,25 +84,19 @@ typedef struct mesh_s vec3_t mins, maxs; float radius; - vec3_t lightaxis[3]; - - //FIXME: these can go when the new backend is done - unsigned int patchWidth; - unsigned int patchHeight; + qboolean istrifan; /*if its a fan/poly/single quad*/ struct mesh_s *next; } mesh_t; -struct meshbuffer_s; +FTE_DEPRECATED struct meshbuffer_s; -void R_PushMesh ( mesh_t *mesh, int features ); -void R_RenderMeshBuffer ( struct meshbuffer_s *mb, qboolean shadowpass ); -qboolean R_MeshWillExceed(mesh_t *mesh); +void FTE_DEPRECATED R_PushMesh ( mesh_t *mesh, int features ); +void FTE_DEPRECATED R_RenderMeshBuffer ( struct meshbuffer_s *mb, qboolean shadowpass ); +qboolean FTE_DEPRECATED R_MeshWillExceed(mesh_t *mesh); extern int gl_canbumpmap; - - /* d*_t structures are on-disk representations @@ -126,7 +113,7 @@ m*_t structures are in-memory #define QWEF_FLAG1 16 //only applies to player entities #define NQEF_NODRAW 16 //so packet entities are free to get this instead #define QWEF_FLAG2 32 //only applies to player entities -#define NQEF_ADDATIVE 32 //so packet entities are free to get this instead +#define NQEF_ADDITIVE 32 //so packet entities are free to get this instead #define EF_BLUE 64 #define EF_RED 128 @@ -169,19 +156,26 @@ typedef struct mplane_s } mplane_t; typedef struct { - int base; - int bump; - int specular; - int fullbright; + texid_t base; + texid_t bump; + texid_t upperoverlay; + texid_t loweroverlay; + texid_t specular; + texid_t fullbright; + + struct shader_s *shader; //fixme: remove... } texnums_t; typedef struct { + int meshcount; + struct msurface_s **meshlist; + int vboe; index_t *indicies; int vbocoord; - vec3_t *coord; + vecV_t *coord; int vbotexcoord; vec2_t *texcoord; int vbolmcoord; @@ -195,8 +189,10 @@ typedef struct vec3_t *tvector; int vbocolours; - byte_vec4_t *colours; + vec4_t *colours4f; } vbo_t; +void GL_SelectVBO(int vbo); +void GL_SelectEBO(int vbo); typedef struct texture_s { @@ -208,8 +204,6 @@ typedef struct texture_s int parttype; - texnums_t tn; - struct shader_s *shader; vbo_t vbo; @@ -273,14 +267,6 @@ typedef struct mtexinfo_s #define VERTEXSIZE 7 #endif -typedef struct glpoly_s -{ - struct glpoly_s *next; - int numverts; - float verts[4][VERTEXSIZE]; // variable sized (xyz s1t1 s2t2 (ldir_xyz) -} glpoly_t; - -#ifdef Q3SHADERS typedef struct mfog_s { struct shader_s *shader; @@ -290,7 +276,6 @@ typedef struct mfog_s int numplanes; mplane_t **planes; } mfog_t; -#endif #if MAX_SWDECALS typedef struct decal_s { @@ -304,9 +289,6 @@ typedef struct decal_s { typedef struct msurface_s { - int visframe; // should be drawn when node is crossed - int shadowframe; - mplane_t *plane; int flags; @@ -320,16 +302,15 @@ typedef struct msurface_s int light_s, light_t; // gl lightmap coordinates -#ifdef Q3SHADERS mfog_t *fog; -#endif mesh_t *mesh; entity_t *ownerent; + struct msurface_s *texturechain; -#if 0 - vec3_t normal; -#endif mtexinfo_t *texinfo; + struct msurface_s **mark; + int visframe; // should be drawn when node is crossed + int shadowframe; // lighting info int dlightframe; @@ -439,18 +420,21 @@ typedef struct hull_s hullfuncs_t funcs; } hull_t; - void Q1BSP_SetHullFuncs(hull_t *hull); void Q1BSP_SetModelFuncs(struct model_s *mod); void Q1BSP_Init(void); +int Q1BSP_ClipDecal(vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangent2, float size, float **out); + qboolean Q1BSP_Trace(struct model_s *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, struct trace_s *trace); qboolean Q1BSP_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, struct trace_s *trace); unsigned int Q1BSP_FatPVS (struct model_s *mod, vec3_t org, qbyte *pvsbuffer, unsigned int buffersize, qboolean add); -qboolean Q1BSP_EdictInFatPVS(struct model_s *mod, struct edict_s *ent, qbyte *pvs); -void Q1BSP_FindTouchedLeafs(struct model_s *mod, struct edict_s *ent, float *mins, float *maxs); +qboolean Q1BSP_EdictInFatPVS(struct model_s *mod, struct wedict_s *ent, qbyte *pvs); +void Q1BSP_FindTouchedLeafs(struct world_s *w, struct model_s *mod, struct wedict_s *ent, float *mins, float *maxs); qbyte *Q1BSP_LeafPVS (struct model_s *model, mleaf_t *leaf, qbyte *buffer, unsigned int buffersize); + +FTE_DEPRECATED texnums_t R_InitSky (struct texture_s *mt); /* ============================================================================== @@ -464,7 +448,7 @@ SPRITE MODELS typedef struct mspriteframe_s { float up, down, left, right; - mpic_t p; + shader_t *shader; } mspriteframe_t; mspriteframe_t *R_GetSpriteFrame (entity_t *currententity); @@ -502,7 +486,7 @@ ALIAS MODELS Alias models are position independent, so the cache manager can move them. ============================================================================== */ - +#if 0 typedef struct { int s; int t; @@ -585,7 +569,7 @@ extern mstvert_t stverts[MAXALIASVERTS*2]; extern mtriangle_t triangles[MAXALIASTRIS]; extern dtrivertx_t *poseverts[MAXALIASFRAMES]; - +#endif /* @@ -601,15 +585,16 @@ extern dtrivertx_t *poseverts[MAXALIASFRAMES]; #define MD2IDALIASHEADER (('2'<<24)+('P'<<16)+('D'<<8)+'I') #define MD2ALIAS_VERSION 8 +#define MD2MAX_SKINNAME 64 //part of the format +/* #define MD2MAX_TRIANGLES 4096 +#define MD2MAX_FRAMES 512 #define MD2MAX_VERTS 2048 -#define MD2MAX_FRAMES 512 #define MD2MAX_SKINS 32 -#define MD2MAX_SKINNAME 64 // sanity checking size #define MD2MAX_SIZE (1024*4200) - +*/ typedef struct { short s; @@ -628,11 +613,13 @@ typedef struct qbyte lightnormalindex; } md2trivertx_t; +/* #define MD2TRIVERTX_V0 0 #define MD2TRIVERTX_V1 1 #define MD2TRIVERTX_V2 2 #define MD2TRIVERTX_LNI 3 #define MD2TRIVERTX_SIZE 4 +*/ typedef struct { @@ -674,12 +661,10 @@ typedef struct int ofs_frames; // offset for first frame int ofs_glcmds; int ofs_end; // end of file - - int gl_texturenum[MAX_SKINS]; } md2_t; -#define ALIASTYPE_MDL 1 -#define ALIASTYPE_MD2 2 +//#define ALIASTYPE_MDL 1 +//#define ALIASTYPE_MD2 2 @@ -736,7 +721,7 @@ typedef enum {fg_quake, fg_quake2, fg_quake3, fg_halflife, fg_new, fg_doom} from #define EF_TRACER2 64 // orange split trail + rotate #define EF_TRACER3 128 // purple trail -//hexen2. +//hexen2 support. #define EFH2_FIREBALL 256 // Yellow transparent trail in all directions #define EFH2_ICE 512 // Blue-white transparent trail, with gravity #define EFH2_MIP_MAP 1024 // This model has mip-maps @@ -849,7 +834,7 @@ typedef struct model_s unsigned checksum2; - bspfuncs_t funcs; + modelfuncs_t funcs; // // additional model data // diff --git a/engine/gl/gl_ngraph.c b/engine/gl/gl_ngraph.c index 911bb937..9a572be6 100644 --- a/engine/gl/gl_ngraph.c +++ b/engine/gl/gl_ngraph.c @@ -20,12 +20,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // gl_ngraph.c #include "quakedef.h" -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h" extern qbyte *draw_chars; // 8*8 graphic characters -int netgraphtexture; // netgraph texture +texid_t netgraphtexture; // netgraph texture #define NET_GRAPHHEIGHT 32 @@ -115,18 +115,18 @@ void GLR_NetGraph (void) y += 8; sprintf(st, "%3i%% packet loss", lost); - Draw_String(8, y, st); + Draw_FunString(8, y, st); y += 8; GL_Bind(netgraphtexture); - qglTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, + qglTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, NET_TIMINGS, NET_GRAPHHEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, ngraph_pixels); GL_TexEnv(GL_MODULATE); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); x = 8; qglColor3f (1,1,1); @@ -175,18 +175,18 @@ void GLR_FrameTimeGraph (int frametime) y += 8; sprintf(st, "%3i%% packet loss", lost); - Draw_String(8, y, st); + Draw_FunString(8, y, st); y += 8; GL_Bind(netgraphtexture); - qglTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, + qglTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, NET_TIMINGS, NET_GRAPHHEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, ngraph_pixels); GL_TexEnv(GL_MODULATE); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); x = 8; qglColor3f (1,1,1); diff --git a/engine/gl/gl_ppl.c b/engine/gl/gl_ppl.c index dc28fc60..7f429e82 100644 --- a/engine/gl/gl_ppl.c +++ b/engine/gl/gl_ppl.c @@ -4,9 +4,9 @@ #include "quakedef.h" -#ifndef NEWBACKEND +#if 0 -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h" #include "shader.h" #include "renderque.h" @@ -64,7 +64,7 @@ extern lightmapinfo_t **lightmap; extern model_t *currentmodel; extern int *deluxmap_textures; -extern int normalisationCubeMap; +//extern int normalisationCubeMap; int r_shadowframe; @@ -79,8 +79,6 @@ int ppl_specular_shader_texr; int ppl_specular_shader_texu; int ppl_specular_shader_texf; -int GLR_LightmapShift (model_t *model); - //#define glBegin glEnd qboolean PPL_ShouldDraw(void) @@ -326,10 +324,10 @@ static void PPL_BaseChain_NoBump_1TMU(msurface_t *first, texture_t *tex) } - GL_MBind(GL_TEXTURE0_ARB, tex->gl_texturenum); + GL_MBind(0, tex->gl_texturenum); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); - GL_SelectTexture(GL_TEXTURE1_ARB); + GL_SelectTexture(1); GL_TexEnv(GL_MODULATE); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -376,7 +374,7 @@ static void PPL_BaseChain_NoBump_1TMU(msurface_t *first, texture_t *tex) qglDisable(GL_TEXTURE_2D); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); - GL_SelectTexture(GL_TEXTURE0_ARB); + GL_SelectTexture(0); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); }*/ @@ -409,10 +407,10 @@ static void PPL_BaseChain_NoBump_2TMU_Overbright(msurface_t *s, texture_t *tex) } - GL_MBind(GL_TEXTURE0_ARB, tex->tn.base); + GL_MBind(0, tex->tn.base); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); - GL_SelectTexture(GL_TEXTURE1_ARB); + GL_SelectTexture(1); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); GL_TexEnv(GL_MODULATE); @@ -485,7 +483,7 @@ static void PPL_BaseChain_NoBump_2TMU_Overbright(msurface_t *s, texture_t *tex) qglDisable(GL_TEXTURE_2D); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); - GL_SelectTexture(GL_TEXTURE0_ARB); + GL_SelectTexture(0); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); if (tex->alphaed) @@ -511,7 +509,7 @@ if (temp1.value) qglVertexPointer(3, GL_FLOAT, 0, vbo->coord); - GL_MBind(GL_TEXTURE0_ARB, tex->tn.base); + GL_MBind(0, tex->tn.base); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo->vbotexcoord); qglTexCoordPointer(2, GL_FLOAT, 0, vbo->texcoord); @@ -538,7 +536,7 @@ if (temp1.value) if (fullbright) { - GL_MBind(GL_TEXTURE2_ARB, tex->tn.fullbright); + GL_MBind(2, tex->tn.fullbright); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); //qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo->vbotexcoord); qglTexCoordPointer(2, GL_FLOAT, 0, vbo->texcoord); @@ -546,7 +544,7 @@ if (temp1.value) qglEnable(GL_TEXTURE_2D); } - GL_SelectTexture(GL_TEXTURE1_ARB); + GL_SelectTexture(1); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo->vbolmcoord); qglTexCoordPointer(2, GL_FLOAT, 0, vbo->lmcoord); @@ -636,12 +634,12 @@ if (temp1.value) if (fullbright) { - GL_SelectTexture(GL_TEXTURE2_ARB); + GL_SelectTexture(2); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); qglDisable(GL_TEXTURE_2D); } - GL_SelectTexture(GL_TEXTURE0_ARB); + GL_SelectTexture(0); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); qglDisable(GL_TEXTURE_2D); @@ -664,7 +662,7 @@ else qglVertexPointer(3, GL_FLOAT, 0, vbo->coord); - GL_MBind(GL_TEXTURE0_ARB, tex->tn.base); + GL_MBind(0, tex->tn.base); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo->vbotexcoord); qglTexCoordPointer(2, GL_FLOAT, 0, vbo->texcoord); @@ -691,7 +689,7 @@ else if (fullbright) { - GL_MBind(GL_TEXTURE2_ARB, tex->tn.fullbright); + GL_MBind(2, tex->tn.fullbright); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); //qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo->vbotexcoord); qglTexCoordPointer(2, GL_FLOAT, 0, vbo->texcoord); @@ -699,7 +697,7 @@ else qglEnable(GL_TEXTURE_2D); } - GL_SelectTexture(GL_TEXTURE1_ARB); + GL_SelectTexture(1); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo->vbolmcoord); qglTexCoordPointer(2, GL_FLOAT, 0, vbo->lmcoord); @@ -789,12 +787,12 @@ else if (fullbright) { - GL_SelectTexture(GL_TEXTURE2_ARB); + GL_SelectTexture(2); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); qglDisable(GL_TEXTURE_2D); } - GL_SelectTexture(GL_TEXTURE0_ARB); + GL_SelectTexture(0); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); @@ -825,9 +823,9 @@ static void PPL_BaseChain_NoBump_2TMU_TEST(msurface_t *s, texture_t *tex) qglCullFace(GL_BACK); - GL_MBind(GL_TEXTURE0_ARB, tex->gl_texturenum); + GL_MBind(0, tex->gl_texturenum); - GL_SelectTexture(GL_TEXTURE1_ARB); + GL_SelectTexture(1); GL_TexEnv(GL_MODULATE); vi = -1; @@ -901,7 +899,7 @@ static void PPL_BaseChain_NoBump_2TMU_TEST(msurface_t *s, texture_t *tex) qglDisable(GL_TEXTURE_2D); - GL_SelectTexture(GL_TEXTURE0_ARB); + GL_SelectTexture(0); } */ @@ -924,7 +922,7 @@ static void PPL_BaseChain_Bump_2TMU(msurface_t *first, texture_t *tex) } //Bind normal map to texture unit 0 - GL_MBind(GL_TEXTURE0_ARB, tex->tn.bump); + GL_MBind(0, tex->tn.bump); qglEnable(GL_TEXTURE_2D); GL_TexEnv(GL_COMBINE_ARB); qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); @@ -933,7 +931,7 @@ static void PPL_BaseChain_Bump_2TMU(msurface_t *first, texture_t *tex) qglEnableClientState(GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer(2, GL_FLOAT, sizeof(surfvertexarray_t), varray_v->stw); - GL_SelectTexture(GL_TEXTURE1_ARB); + GL_SelectTexture(1); qglEnable(GL_TEXTURE_2D); GL_TexEnv(GL_COMBINE_ARB); qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); @@ -974,9 +972,9 @@ static void PPL_BaseChain_Bump_2TMU(msurface_t *first, texture_t *tex) qglEnable(GL_BLEND); qglBlendFunc(GL_DST_COLOR, GL_ZERO); - GL_MBind(GL_TEXTURE0_ARB, tex->tn.base); + GL_MBind(0, tex->tn.base); - GL_SelectTexture(GL_TEXTURE1_ARB); + GL_SelectTexture(1); qglEnable(GL_TEXTURE_2D); GL_TexEnv(GL_MODULATE); @@ -1012,7 +1010,7 @@ static void PPL_BaseChain_Bump_2TMU(msurface_t *first, texture_t *tex) qglDisableClientState(GL_TEXTURE_COORD_ARRAY); qglDisable(GL_TEXTURE_2D); - GL_SelectTexture(GL_TEXTURE0_ARB); + GL_SelectTexture(0); } static void PPL_BaseChain_Bump_4TMU(msurface_t *s, texture_t *tex) @@ -1023,7 +1021,7 @@ static void PPL_BaseChain_Bump_4TMU(msurface_t *s, texture_t *tex) PPL_EnableVertexArrays(); //Bind normal map to texture unit 0 - GL_MBind(GL_TEXTURE0_ARB, tex->tn.bump); + GL_MBind(0, tex->tn.bump); qglEnable(GL_TEXTURE_2D); GL_TexEnv(GL_REPLACE); @@ -1031,7 +1029,7 @@ static void PPL_BaseChain_Bump_4TMU(msurface_t *s, texture_t *tex) qglTexCoordPointer(2, GL_FLOAT, sizeof(surfvertexarray_t), varray_v->stw); //1 gets the deluxmap - GL_SelectTexture(GL_TEXTURE1_ARB); + GL_SelectTexture(1); qglEnable(GL_TEXTURE_2D); GL_TexEnv(GL_COMBINE_ARB); qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); @@ -1042,7 +1040,7 @@ static void PPL_BaseChain_Bump_4TMU(msurface_t *s, texture_t *tex) qglTexCoordPointer(2, GL_FLOAT, sizeof(surfvertexarray_t), varray_v->stl); //2 gets the diffusemap - GL_MBind(GL_TEXTURE2_ARB, tex->tn.base); + GL_MBind(2, tex->tn.base); qglEnable(GL_TEXTURE_2D); GL_TexEnv(GL_MODULATE); @@ -1050,7 +1048,7 @@ static void PPL_BaseChain_Bump_4TMU(msurface_t *s, texture_t *tex) qglTexCoordPointer(2, GL_FLOAT, sizeof(surfvertexarray_t), varray_v->stw); //3 gets the lightmap - GL_SelectTexture(GL_TEXTURE3_ARB); + GL_SelectTexture(3); qglEnable(GL_TEXTURE_2D); GL_TexEnv(GL_MODULATE); @@ -1065,7 +1063,7 @@ static void PPL_BaseChain_Bump_4TMU(msurface_t *s, texture_t *tex) PPL_FlushArrays(); vi = s->lightmaptexturenum; - GL_MBind(GL_TEXTURE1_ARB, deluxmap_textures[vi] ); + GL_MBind(1, deluxmap_textures[vi] ); if (lightmap[vi]->deluxmodified) { lightmap[vi]->deluxmodified = false; @@ -1078,7 +1076,7 @@ static void PPL_BaseChain_Bump_4TMU(msurface_t *s, texture_t *tex) theRect->h = 0; theRect->w = 0; } - GL_MBind(GL_TEXTURE3_ARB, lightmap_textures[vi] ); + GL_MBind(3, lightmap_textures[vi] ); if (lightmap[vi]->modified) { lightmap[vi]->modified = false; @@ -1097,20 +1095,20 @@ static void PPL_BaseChain_Bump_4TMU(msurface_t *s, texture_t *tex) } PPL_FlushArrays(); - GL_SelectTexture(GL_TEXTURE3_ARB); + GL_SelectTexture(3); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); qglDisable(GL_TEXTURE_2D); - GL_SelectTexture(GL_TEXTURE2_ARB); + GL_SelectTexture(2); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); qglDisable(GL_TEXTURE_2D); - GL_SelectTexture(GL_TEXTURE1_ARB); + GL_SelectTexture(1); GL_TexEnv(GL_MODULATE); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); qglDisable(GL_TEXTURE_2D); - GL_SelectTexture(GL_TEXTURE0_ARB); + GL_SelectTexture(0); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); @@ -1421,17 +1419,17 @@ static void PPL_BaseChain_Specular_FP(msurface_t *s, texture_t *tex) if (qglGetError()) Con_Printf("GL Error on shadow lighting\n"); - GL_MBind(GL_TEXTURE0_ARB, tex->tn.base); + GL_MBind(0, tex->tn.base); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); - GL_MBind(GL_TEXTURE1_ARB, tex->tn.bump); + GL_MBind(1, tex->tn.bump); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); -// GL_MBind(GL_TEXTURE2_ARB, lightmap_textures[vi] ); +// GL_MBind(2, lightmap_textures[vi] ); -// GL_MBind(GL_TEXTURE3_ARB, deluxmap_textures[vi] ); +// GL_MBind(3, deluxmap_textures[vi] ); - GL_MBind(GL_TEXTURE4_ARB, tex->tn.specular); + GL_MBind(4, tex->tn.specular); qglUniform3fvARB(ppl_specular_shader_vieworg, 1, r_refdef.vieworg); @@ -1445,7 +1443,7 @@ static void PPL_BaseChain_Specular_FP(msurface_t *s, texture_t *tex) { vi = s->lightmaptexturenum; - GL_MBind(GL_TEXTURE3_ARB, deluxmap_textures[vi] ); + GL_MBind(3, deluxmap_textures[vi] ); if (lightmap[vi]->deluxmodified) { lightmap[vi]->deluxmodified = false; @@ -1458,7 +1456,7 @@ static void PPL_BaseChain_Specular_FP(msurface_t *s, texture_t *tex) theRect->h = 0; theRect->w = 0; } - GL_MBind(GL_TEXTURE2_ARB, lightmap_textures[vi] ); + GL_MBind(2, lightmap_textures[vi] ); if (lightmap[vi]->modified) { lightmap[vi]->modified = false; @@ -1491,13 +1489,13 @@ static void PPL_BaseChain_Specular_FP(msurface_t *s, texture_t *tex) GLSlang_UseProgram(0); - GL_SelectTexture(GL_TEXTURE2_ARB); + GL_SelectTexture(2); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); - GL_SelectTexture(GL_TEXTURE1_ARB); + GL_SelectTexture(1); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); - GL_SelectTexture(GL_TEXTURE0_ARB); + GL_SelectTexture(0); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); @@ -1679,7 +1677,7 @@ static void PPL_BaseChain_SimpleTexture(msurface_t *first) int oldwall=-1; glRect_t *theRect; - GL_SelectTexture(GL_TEXTURE0_ARB); + GL_SelectTexture(0); PPL_EnableVertexArrays(); //draw the surface properly @@ -1689,7 +1687,7 @@ static void PPL_BaseChain_SimpleTexture(msurface_t *first) GL_TexEnv(GL_MODULATE); - GL_SelectTexture(GL_TEXTURE1_ARB); + GL_SelectTexture(1); GL_TexEnv(GL_MODULATE); qglEnable(GL_TEXTURE_2D); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -1710,20 +1708,20 @@ static void PPL_BaseChain_SimpleTexture(msurface_t *first) if (iswall) { - GL_MBind(GL_TEXTURE0_ARB, walltexture); + GL_MBind(0, walltexture); qglColor4fv(wallcolour); } else { - GL_MBind(GL_TEXTURE0_ARB, floortexture); + GL_MBind(0, floortexture); qglColor4fv(floorcolour); } if (vi < 0) - GL_MBind(GL_TEXTURE1_ARB, 0 ); + GL_MBind(1, 0 ); else { - GL_MBind(GL_TEXTURE1_ARB, lightmap_textures[vi] ); + GL_MBind(1, lightmap_textures[vi] ); if (lightmap[vi]->modified) { lightmap[vi]->modified = false; @@ -1746,7 +1744,7 @@ static void PPL_BaseChain_SimpleTexture(msurface_t *first) qglDisable(GL_TEXTURE_2D); qglColor3f(1,1,1); - GL_SelectTexture(GL_TEXTURE0_ARB); + GL_SelectTexture(0); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); qglDisableClientState(GL_VERTEX_ARRAY); qglEnable(GL_TEXTURE_2D); @@ -1760,7 +1758,7 @@ static void PPL_BaseChain_NPR_Sketch(msurface_t *first) int i; glRect_t *theRect; - GL_SelectTexture(GL_TEXTURE0_ARB); + GL_SelectTexture(0); PPL_EnableVertexArrays(); //draw the surface properly @@ -1770,7 +1768,7 @@ static void PPL_BaseChain_NPR_Sketch(msurface_t *first) GL_TexEnv(GL_MODULATE); - GL_SelectTexture(GL_TEXTURE1_ARB); + GL_SelectTexture(1); GL_TexEnv(GL_MODULATE); qglEnable(GL_TEXTURE_2D); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -1784,13 +1782,13 @@ static void PPL_BaseChain_NPR_Sketch(msurface_t *first) PPL_FlushArrays(); vi = s->lightmaptexturenum; - GL_MBind(GL_TEXTURE0_ARB, nprtextures[rand()%10]); + GL_MBind(0, nprtextures[rand()%10]); if (vi < 0) - GL_MBind(GL_TEXTURE1_ARB, 0 ); + GL_MBind(1, 0 ); else { - GL_MBind(GL_TEXTURE1_ARB, lightmap_textures[vi] ); + GL_MBind(1, lightmap_textures[vi] ); if (lightmap[vi]->modified) { lightmap[vi]->modified = false; @@ -1811,7 +1809,7 @@ static void PPL_BaseChain_NPR_Sketch(msurface_t *first) qglDisableClientState(GL_TEXTURE_COORD_ARRAY); qglDisable(GL_TEXTURE_2D); - GL_SelectTexture(GL_TEXTURE0_ARB); + GL_SelectTexture(0); qglDisable(GL_TEXTURE_2D); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); @@ -2034,7 +2032,7 @@ static void PPL_BaseTextureChain(msurface_t *first) // else if (gl_mtexarbable>=8) // PPL_BaseChain_Specular_8TMU(first, t); else - PPL_BaseChain_Bump_4TMU(first, t); //can't do specular. + PPL_BaseChain_Bump_4TMU(first, t); //can't do specular (can be done by using only the screen's alpha channel, but we don't cache that). } else PPL_BaseChain_Bump_4TMU(first, t); @@ -2270,7 +2268,7 @@ void PPL_BaseBModelTextures(entity_t *e) for (s = model->surfaces+model->firstmodelsurface,i = 0; i < model->nummodelsurfaces; i++, s++) { - if (s->texinfo->flags & (SURF_TRANS33 | SURF_TRANS66)) + if (s->texinfo->flags & (Q2TI_TRANS33 | Q2TI_TRANS66)) { s->ownerent = currententity; s->nextalphasurface = r_alpha_surfaces; @@ -2803,18 +2801,18 @@ void PPL_LightTexturesFP_Cached(model_t *model, vec3_t modelorigin, dlight_t *li if (p & PERMUTATION_SPECULAR) GL_MBind(GL_TEXTURE2_ARB, t->tn.specular); - GL_MBind(GL_TEXTURE0_ARB, t->tn.base); + GL_MBind(0, t->tn.base); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); - qglMultiTexCoord3fARB(GL_TEXTURE1_ARB, s->texinfo->vecs[0][0], s->texinfo->vecs[0][1], s->texinfo->vecs[0][2]); - qglMultiTexCoord3fARB(GL_TEXTURE2_ARB, -s->texinfo->vecs[1][0], -s->texinfo->vecs[1][1], -s->texinfo->vecs[1][2]); + qglMultiTexCoord3fARB(1, s->texinfo->vecs[0][0], s->texinfo->vecs[0][1], s->texinfo->vecs[0][2]); + qglMultiTexCoord3fARB(2, -s->texinfo->vecs[1][0], -s->texinfo->vecs[1][1], -s->texinfo->vecs[1][2]); if (s->flags & SURF_PLANEBACK) - qglMultiTexCoord3fARB(GL_TEXTURE3_ARB, -s->plane->normal[0], -s->plane->normal[1], -s->plane->normal[2]); + qglMultiTexCoord3fARB(3, -s->plane->normal[0], -s->plane->normal[1], -s->plane->normal[2]); else - qglMultiTexCoord3fARB(GL_TEXTURE3_ARB, s->plane->normal[0], s->plane->normal[1], s->plane->normal[2]); + qglMultiTexCoord3fARB(3, s->plane->normal[0], s->plane->normal[1], s->plane->normal[2]); qglTexCoordPointer(2, GL_FLOAT, 0, s->mesh->st_array); @@ -2894,11 +2892,11 @@ void PPL_LightTexturesFP(model_t *model, vec3_t modelorigin, dlight_t *light, ve if (p & PERMUTATION_BUMPMAP) - GL_MBind(GL_TEXTURE1_ARB, t->tn.bump); + GL_MBind(1, t->tn.bump); if (p & PERMUTATION_SPECULAR) - GL_MBind(GL_TEXTURE2_ARB, t->tn.specular); + GL_MBind(2, t->tn.specular); - GL_MBind(GL_TEXTURE0_ARB, t->tn.base); + GL_MBind(0, t->tn.base); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); for (; s; s=s->texturechain) @@ -2991,7 +2989,7 @@ void PPL_LightTextures(model_t *model, vec3_t modelorigin, dlight_t *light, vec3 qglEnableClientState(GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer(2, GL_FLOAT, sizeof(surfvertexarray_t), varray_v->stw); - GL_SelectTexture(GL_TEXTURE1_ARB); + GL_SelectTexture(1); GL_BindType(GL_TEXTURE_CUBE_MAP_ARB, normalisationCubeMap); qglEnable(GL_TEXTURE_CUBE_MAP_ARB); GL_TexEnv(GL_COMBINE_ARB); //normalisation cubemap . normalmap @@ -3002,7 +3000,7 @@ void PPL_LightTextures(model_t *model, vec3_t modelorigin, dlight_t *light, vec3 qglEnableClientState(GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer(3, GL_FLOAT, sizeof(surfvertexarray_t), varray_v->ncm); - GL_MBind(GL_TEXTURE2_ARB, t->tn.bump); //a dummy + GL_MBind(2, t->tn.bump); //a dummy qglEnable(GL_TEXTURE_2D); GL_TexEnv(GL_COMBINE_ARB); //bumps * color (the attenuation) qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PRIMARY_COLOR_ARB); //(doesn't actually use the bound texture) @@ -3010,7 +3008,7 @@ void PPL_LightTextures(model_t *model, vec3_t modelorigin, dlight_t *light, vec3 qglTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); qglTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); - GL_MBind(GL_TEXTURE3_ARB, t->tn.base); + GL_MBind(3, t->tn.base); qglEnable(GL_TEXTURE_2D); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer(3, GL_FLOAT, sizeof(surfvertexarray_t), varray_v->stw); @@ -3023,16 +3021,16 @@ void PPL_LightTextures(model_t *model, vec3_t modelorigin, dlight_t *light, vec3 qglDisable(GL_TEXTURE_2D); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); - GL_SelectTexture(GL_TEXTURE2_ARB); + GL_SelectTexture(2); qglDisable(GL_TEXTURE_2D); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); } - GL_SelectTexture(GL_TEXTURE1_ARB); + GL_SelectTexture(1); GL_TexEnv(GL_MODULATE); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); qglDisable(GL_TEXTURE_CUBE_MAP_ARB); - GL_SelectTexture(GL_TEXTURE0_ARB); + GL_SelectTexture(0); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer(2, GL_FLOAT, sizeof(surfvertexarray_t), varray_v->stw); qglDisable(GL_TEXTURE_2D); @@ -3079,12 +3077,12 @@ void PPL_LightTextures(model_t *model, vec3_t modelorigin, dlight_t *light, vec3 GL_TexEnv(GL_MODULATE); qglDisable(GL_TEXTURE_2D); - GL_SelectTexture(GL_TEXTURE1_ARB); + GL_SelectTexture(1); GL_TexEnv(GL_MODULATE); qglDisable(GL_TEXTURE_CUBE_MAP_ARB); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); - GL_SelectTexture(GL_TEXTURE0_ARB); + GL_SelectTexture(0); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); qglDisable(GL_TEXTURE_2D); @@ -3140,11 +3138,11 @@ void PPL_LightBModelTexturesFP(entity_t *e, dlight_t *light, vec3_t colour) qglUniform1fARB(ppl_light_shader_lightradius[p], light->radius); } - GL_MBind(GL_TEXTURE0_ARB, t->tn.base); + GL_MBind(0, t->tn.base); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); - GL_MBind(GL_TEXTURE1_ARB, t->tn.bump); - GL_MBind(GL_TEXTURE2_ARB, t->tn.specular); - GL_SelectTexture(GL_TEXTURE0_ARB); + GL_MBind(1, t->tn.bump); + GL_MBind(2, t->tn.specular); + GL_SelectTexture(0); } qglMultiTexCoord3fARB(GL_TEXTURE1_ARB, -s->texinfo->vecs[0][0], -s->texinfo->vecs[0][1], -s->texinfo->vecs[0][2]); @@ -3212,7 +3210,7 @@ void PPL_LightBModelTextures(entity_t *e, dlight_t *light, vec3_t colour) qglEnableClientState(GL_TEXTURE_COORD_ARRAY); qglTexCoordPointer(2, GL_FLOAT, sizeof(surfvertexarray_t), varray_v->stw); - GL_SelectTexture(GL_TEXTURE1_ARB); + GL_SelectTexture(1); GL_BindType(GL_TEXTURE_CUBE_MAP_ARB, normalisationCubeMap); qglEnable(GL_TEXTURE_CUBE_MAP_ARB); GL_TexEnv(GL_COMBINE_ARB); //normalisation cubemap * normalmap @@ -3244,18 +3242,18 @@ void PPL_LightBModelTextures(entity_t *e, dlight_t *light, vec3_t colour) qglDisable(GL_TEXTURE_2D); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); - GL_SelectTexture(GL_TEXTURE2_ARB); + GL_SelectTexture(2); qglDisable(GL_TEXTURE_2D); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); } GL_TexEnv(GL_MODULATE); qglDisable(GL_TEXTURE_2D); - GL_SelectTexture(GL_TEXTURE1_ARB); + GL_SelectTexture(1); GL_TexEnv(GL_MODULATE); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); qglDisable(GL_TEXTURE_CUBE_MAP_ARB); - GL_SelectTexture(GL_TEXTURE0_ARB); + GL_SelectTexture(0); qglEnableClientState(GL_TEXTURE_COORD_ARRAY); @@ -3300,7 +3298,7 @@ void PPL_LightBModelTextures(entity_t *e, dlight_t *light, vec3_t colour) qglDisable(GL_TEXTURE_2D); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); - GL_SelectTexture(GL_TEXTURE2_ARB); + GL_SelectTexture(2); qglDisable(GL_TEXTURE_2D); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); } @@ -3308,12 +3306,12 @@ void PPL_LightBModelTextures(entity_t *e, dlight_t *light, vec3_t colour) GL_TexEnv(GL_MODULATE); qglDisable(GL_TEXTURE_2D); - GL_SelectTexture(GL_TEXTURE1_ARB); + GL_SelectTexture(1); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); GL_TexEnv(GL_MODULATE); qglDisable(GL_TEXTURE_CUBE_MAP_ARB); - GL_SelectTexture(GL_TEXTURE0_ARB); + GL_SelectTexture(0); qglDisableClientState(GL_TEXTURE_COORD_ARRAY); qglDisable(GL_TEXTURE_2D); @@ -5228,7 +5226,7 @@ void PPL_DrawWorld (void) PPL_BaseEntTextures(); RSpeedEnd(RSPEED_DRAWENTITIES); -// CL_NewDlightRGB(1, r_refdef.vieworg[0], r_refdef.vieworg[1]-16, r_refdef.vieworg[2]-24, 128, 1, 1, 1, 1); +// CL_NewDlightRGB(1, r_refdef.vieworg, 128, 1, 1, 1, 1); // if (qglGetError()) // Con_Printf("GL Error on entities\n"); diff --git a/engine/gl/gl_rlight.c b/engine/gl/gl_rlight.c index 60359ad8..fcc0adb2 100644 --- a/engine/gl/gl_rlight.c +++ b/engine/gl/gl_rlight.c @@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // r_light.c #include "quakedef.h" -#if defined(RGLQUAKE) || defined(D3DQUAKE) +#if defined(GLQUAKE) || defined(D3DQUAKE) #include "glquake.h" int r_dlightframecount; @@ -31,7 +31,7 @@ int d_lightstylevalue[256]; // 8.8 fraction of base light value R_AnimateLight ================== */ -void GLR_AnimateLight (void) +void R_AnimateLight (void) { int i,j; int v1, v2; @@ -64,9 +64,6 @@ void GLR_AnimateLight (void) v2 = cl_lightstyle[j].map[v2] - 'a'; d_lightstylevalue[j] = (v1*(1-f) + v2*(f))*22; - - if (d_lightstylevalue[j] > 255) - d_lightstylevalue[j] = 255; } } @@ -115,7 +112,7 @@ void R_InitBubble(void) } } -#ifdef RGLQUAKE +#ifdef GLQUAKE void R_RenderDlight (dlight_t *light) { int i, j; @@ -123,22 +120,35 @@ void R_RenderDlight (dlight_t *light) vec3_t v; float rad; float *bub_sin, *bub_cos; + vec3_t colour; bub_sin = bubble_sintable; bub_cos = bubble_costable; rad = light->radius * 0.35; + VectorCopy(light->color, colour); + + if (light->fov) + { + float a = -DotProduct(light->axis[0], vpn); + colour[0] *= a; + colour[1] *= a; + colour[2] *= a; + rad *= a; + rad *= 0.33; + } + VectorSubtract (light->origin, r_origin, v); if (Length (v) < rad) { // view is inside the dlight - AddLightBlend (light->color[0]*5, light->color[1]*5, light->color[2]*5, light->radius * 0.0003); + AddLightBlend (colour[0]*5, colour[1]*5, colour[2]*5, light->radius * 0.0003); return; } qglBegin (GL_TRIANGLE_FAN); // qglColor3f (0.2,0.1,0.0); // qglColor3f (0.2,0.1,0.05); // changed dimlight effect - qglColor4f (light->color[0]*2, light->color[1]*2, light->color[2]*2, + qglColor4f (colour[0]*2, colour[1]*2, colour[2]*2, 1);//light->color[3]); for (i=0 ; i<3 ; i++) v[i] = light->origin[i] - vpn[i]*rad/1.5; @@ -168,7 +178,7 @@ void GLR_RenderDlights (void) dlight_t *l; vec3_t waste1, waste2; - if (!r_flashblend.value) + if (!r_flashblend.ival) return; // r_dlightframecount = r_framecount + 1; // because the count hasn't @@ -179,14 +189,14 @@ void GLR_RenderDlights (void) qglEnable (GL_BLEND); qglBlendFunc (GL_ONE, GL_ONE); - if (r_flashblend.value == 2) + if (r_flashblend.ival == 2) { qglDisable(GL_DEPTH_TEST); qglDepthMask(0); } - l = cl_dlights; - for (i=0 ; iradius || !(l->flags & LFLAG_ALLOW_FLASH)) continue; @@ -197,7 +207,7 @@ void GLR_RenderDlights (void) if (l->key == -(cl.playernum[r_refdef.currentplayernum]+1)) continue; //was a muzzleflash - if (r_flashblend.value == 2) + if (r_flashblend.ival == 2) { if (TraceLineN(r_refdef.vieworg, l->origin, waste1, waste2)) continue; @@ -205,7 +215,7 @@ void GLR_RenderDlights (void) R_RenderDlight (l); } - if (r_flashblend.value == 2) + if (r_flashblend.ival == 2) { qglEnable(GL_DEPTH_TEST); qglDepthMask(1); @@ -388,7 +398,7 @@ void GLR_PushDlights (void) r_dlightframecount = r_framecount + 1; // because the count hasn't // advanced yet for this frame - if (!r_dynamic.value || !cl.worldmodel) + if (!r_dynamic.ival || !cl.worldmodel) return; if (!cl.worldmodel->nodes) @@ -396,8 +406,8 @@ void GLR_PushDlights (void) currentmodel = cl.worldmodel; - l = cl_dlights; - for (i=0 ; iradius || !(l->flags & LFLAG_ALLOW_LMHACK)) continue; @@ -475,7 +485,7 @@ void GLQ3_LightGrid(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_a /* qglDisable(GL_TEXTURE_2D); qglDisable(GL_DEPTH_TEST); - qglDisable(GL_CULL_FACE); + GL_CullFace(0); qglColor4f(1,1,1,1); qglBegin(GL_QUADS); for ( i = 0; i < 8; i++ ) diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index 1a49341e..42039080 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -21,13 +21,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h" #include "renderque.h" - -#ifdef Q3SHADERS #include "shader.h" -#endif void R_RenderBrushPoly (msurface_t *fa); @@ -47,7 +44,6 @@ FTEPFNGLGETCOMPRESSEDTEXIMAGEARBPROC qglGetCompressedTexImageARB; entity_t r_worldentity; vec3_t modelorg, r_entorigin; -entity_t *currententity; int r_visframecount; // bumped when going to a new PVS int r_framecount; // used for dlight push checking @@ -60,11 +56,6 @@ int c_brush_polys, c_alias_polys; qboolean envmap; // true during envmap command capture -int particletexture; // little dot for particles -int particlecqtexture; // little dot for particles -int explosiontexture; -int balltexture; - int mirrortexturenum; // quake texturenum, not gltexturenum qboolean mirror; mplane_t *mirror_plane; @@ -119,6 +110,7 @@ cvar_t gl_finish = SCVAR("gl_finish","0"); cvar_t gl_dither = SCVAR("gl_dither", "1"); cvar_t gl_maxdist = SCVAR("gl_maxdist", "8192"); +#pragma message("r_polygonoffset_submodel_offset: not implemented at the mo") cvar_t r_polygonoffset_submodel_factor = SCVAR("r_polygonoffset_submodel_factor", "0.05"); cvar_t r_polygonoffset_submodel_offset = SCVAR("r_polygonoffset_submodel_offset", "25"); @@ -144,10 +136,10 @@ extern cvar_t gl_ztrick; extern cvar_t scr_fov; // post processing stuff -int sceneblur_texture; -int scenepp_texture; -int scenepp_texture_warp; -int scenepp_texture_edge; +texid_t sceneblur_texture; +texid_t scenepp_texture; +texid_t scenepp_texture_warp; +texid_t scenepp_texture_edge; int scenepp_ww_program; int scenepp_ww_parm_texture0i; @@ -160,7 +152,7 @@ int scenepp_mt_parm_texture0i; int scenepp_mt_parm_colorf; int scenepp_mt_parm_inverti; -int scenepp_fisheye_texture; +texid_t scenepp_fisheye_texture; int scenepp_fisheye_program; int scenepp_fisheye_parm_fov; int scenepp_panorama_program; @@ -359,7 +351,7 @@ void GL_SetupSceneProcessingTextures (void) unsigned char pp_warp_tex[PP_WARP_TEX_SIZE*PP_WARP_TEX_SIZE*3]; unsigned char pp_edge_tex[PP_AMP_TEX_SIZE*PP_AMP_TEX_SIZE*3]; - scenepp_fisheye_texture = 0; + scenepp_fisheye_texture = r_nulltex; sceneblur_texture = GL_AllocNewTexture(); @@ -389,8 +381,8 @@ void GL_SetupSceneProcessingTextures (void) } GL_Bind(scenepp_texture_warp); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); qglTexImage2D(GL_TEXTURE_2D, 0, 3, PP_WARP_TEX_SIZE, PP_WARP_TEX_SIZE, 0, GL_RGB, GL_UNSIGNED_BYTE, pp_warp_tex); // TODO: init edge texture - this is ampscale * 2, with ampscale calculated @@ -433,8 +425,8 @@ void GL_SetupSceneProcessingTextures (void) } GL_Bind(scenepp_texture_edge); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, PP_WARP_TEX_SIZE, PP_WARP_TEX_SIZE, 0, GL_RGB, GL_UNSIGNED_BYTE, pp_edge_tex); } @@ -507,11 +499,19 @@ R_DrawSpriteModel void R_DrawSpriteModel (entity_t *e) { vec3_t point; - mspriteframe_t *frame; + mspriteframe_t *frame, genframe; vec3_t forward, right, up; msprite_t *psprite; vec3_t sprorigin; - qbyte coloursb[4]; + unsigned int fl; + unsigned int sprtype; + + static vec2_t texcoords[4]={{0, 1},{0,0},{1,0},{1,1}}; + static index_t indexes[6] = {0, 1, 2, 0, 2, 3}; + vecV_t vertcoords[4]; + avec4_t colours[4]; + mesh_t mesh; + if (e->flags & Q2RF_WEAPONMODEL && r_refdef.currentplayernum >= 0) { @@ -528,74 +528,26 @@ void R_DrawSpriteModel (entity_t *e) else VectorCopy(e->origin, sprorigin); -#ifdef Q3SHADERS - - if (e->forcedshader) + if (!e->model || e->forcedshader) { - meshbuffer_t mb; - mesh_t mesh; - vec2_t texcoords[4]={{0, 1},{0,0},{1,0},{1,1}}; - vec3_t vertcoords[4]; - index_t indexes[6] = {0, 1, 2, 0, 2, 3}; - byte_vec4_t colours[4]; - float x, y; - -#define VectorSet(a,b,c,v) {v[0]=a;v[1]=b;v[2]=c;} - x = cos(e->rotation+225*M_PI/180)*e->scale; - y = sin(e->rotation+225*M_PI/180)*e->scale; - VectorSet (sprorigin[0] - y*vright[0] + x*vup[0], sprorigin[1] - y*vright[1] + x*vup[1], sprorigin[2] - y*vright[2] + x*vup[2], vertcoords[3]); - VectorSet (sprorigin[0] - x*vright[0] - y*vup[0], sprorigin[1] - x*vright[1] - y*vup[1], sprorigin[2] - x*vright[2] - y*vup[2], vertcoords[2]); - VectorSet (sprorigin[0] + y*vright[0] - x*vup[0], sprorigin[1] + y*vright[1] - x*vup[1], sprorigin[2] + y*vright[2] - x*vup[2], vertcoords[1]); - VectorSet (sprorigin[0] + x*vright[0] + y*vup[0], sprorigin[1] + x*vright[1] + y*vup[1], sprorigin[2] + x*vright[2] + y*vup[2], vertcoords[0]); - - coloursb[0] = e->shaderRGBAf[0]*255; - coloursb[1] = e->shaderRGBAf[1]*255; - coloursb[2] = e->shaderRGBAf[2]*255; - coloursb[3] = e->shaderRGBAf[3]*255; - *(int*)colours[0] = *(int*)colours[1] = *(int*)colours[2] = *(int*)colours[3] = *(int*)coloursb; - - mesh.vbofirstelement = 0; - mesh.vbofirstvert = 0; - - mesh.colors_array = colours; - mesh.indexes = indexes; - mesh.lmst_array = NULL; - mesh.st_array = texcoords; - mesh.normals_array = NULL; - mesh.xyz_array = vertcoords; - mesh.numvertexes = 4; - mesh.numindexes = 6; - mesh.radius = e->scale; - - - R_IBrokeTheArrays(); - - mb.entity = e; - mb.shader = e->forcedshader; - mb.fog = NULL;//fog; - mb.mesh = &mesh; - mb.infokey = -1; - mb.dlightbits = 0; - - R_PushMesh(&mesh, mb.shader->features | MF_NONBATCHED|MF_COLORS); - - R_RenderMeshBuffer ( &mb, false ); - return; + genframe.shader = e->forcedshader; + genframe.up = genframe.left = -1; + genframe.down = genframe.right = 1; + sprtype = SPR_VP_PARALLEL; + frame = &genframe; } -#endif - if (!e->model) + else + { + // don't even bother culling, because it's just a single + // polygon without a surface cache + frame = R_GetSpriteFrame (e); + psprite = e->model->cache.data; + sprtype = psprite->type; + } + if (!frame->shader) return; - if (e->flags & RF_NODEPTHTEST) - qglDisable(GL_DEPTH_TEST); - - // don't even bother culling, because it's just a single - // polygon without a surface cache - frame = R_GetSpriteFrame (e); - psprite = e->model->cache.data; -// frame = 0x05b94140; - - switch(psprite->type) + switch(sprtype) { case SPR_ORIENTED: // bullet marks on walls @@ -628,187 +580,64 @@ void R_DrawSpriteModel (entity_t *e) right[1]*=e->scale; right[2]*=e->scale; - qglColor4fv (e->shaderRGBAf); - GL_DisableMultitexture(); + Vector4Copy(e->shaderRGBAf, colours[0]); + Vector4Copy(e->shaderRGBAf, colours[1]); + Vector4Copy(e->shaderRGBAf, colours[2]); + Vector4Copy(e->shaderRGBAf, colours[3]); - GL_Bind(frame->p.d.gl.texnum); + fl = 0; + if (e->flags & Q2RF_ADDITIVE) + fl |= BEF_FORCEADDITIVE; + if (e->shaderRGBAf[3]<1 || gl_blendsprites.value) + fl |= BEF_FORCETRANSPARENT; + if (e->flags & RF_NODEPTHTEST) + fl |= BEF_FORCENODEPTH; + BE_SelectMode(BEM_STANDARD, fl); - { - extern int gldepthfunc; - qglDepthFunc(gldepthfunc); - qglDepthMask(0); - if (gldepthmin == 0.5) - qglCullFace ( GL_BACK ); - else - qglCullFace ( GL_FRONT ); - - GL_TexEnv(GL_MODULATE); - - qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - qglDisable (GL_ALPHA_TEST); - qglDisable(GL_BLEND); - } - - if (e->flags & Q2RF_ADDATIVE) - { - qglEnable(GL_BLEND); - qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - qglBlendFunc(GL_SRC_ALPHA, GL_ONE); - } - else if (e->shaderRGBAf[3]<1 || gl_blendsprites.value) - { - qglEnable(GL_BLEND); - qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - } - else - qglEnable (GL_ALPHA_TEST); - - qglDisable(GL_CULL_FACE); - qglBegin (GL_QUADS); - - qglTexCoord2f (0, 1); VectorMA (sprorigin, frame->down, up, point); - VectorMA (point, frame->left, right, point); - qglVertex3fv (point); + VectorMA (point, frame->left, right, vertcoords[0]); - qglTexCoord2f (0, 0); VectorMA (sprorigin, frame->up, up, point); - VectorMA (point, frame->left, right, point); - qglVertex3fv (point); + VectorMA (point, frame->left, right, vertcoords[1]); - qglTexCoord2f (1, 0); VectorMA (sprorigin, frame->up, up, point); - VectorMA (point, frame->right, right, point); - qglVertex3fv (point); + VectorMA (point, frame->right, right, vertcoords[2]); - qglTexCoord2f (1, 1); VectorMA (sprorigin, frame->down, up, point); - VectorMA (point, frame->right, right, point); - qglVertex3fv (point); + VectorMA (point, frame->right, right, vertcoords[3]); - qglEnd (); - qglDisable(GL_BLEND); - qglDisable (GL_ALPHA_TEST); - qglEnable(GL_DEPTH_TEST); - - qglEnable(GL_CULL_FACE); - qglEnable(GL_BLEND); - - if (e->flags & Q2RF_ADDATIVE) //back to regular blending for us! - qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + memset(&mesh, 0, sizeof(mesh)); + mesh.vbofirstelement = 0; + mesh.vbofirstvert = 0; + mesh.xyz_array = vertcoords; + mesh.indexes = indexes; + mesh.numindexes = sizeof(indexes)/sizeof(indexes[0]); + mesh.colors4f_array = colours; + mesh.lmst_array = NULL; + mesh.normals_array = NULL; + mesh.numvertexes = 4; + mesh.st_array = texcoords; + mesh.istrifan = true; + BE_DrawMeshChain(frame->shader, &mesh, NULL, NULL); } //================================================================================== -#ifdef NEWBACKEND -static void R_DrawShadedSpriteModels(int count, void **entlist, void *parm) -{ - vec3_t point; - mspriteframe_t *frame; - vec3_t forward, right, up; - msprite_t *psprite; - - qbyte coloursb[4]; - - meshbuffer_t mb; - mesh_t mesh; - vec2_t texcoords[4]={{0, 1},{0,0},{1,0},{1,1}}; - vec3_t vertcoords[4]; - index_t indexes[6] = {0, 1, 2, 0, 2, 3}; - byte_vec4_t colours[4]; - float x, y; - - int vnum = 0, inum = 0; - - shader_t *lastshader = NULL; - - mesh.vbofirstelement = 0; - mesh.vbofirstvert = 0; - - mesh.colors_array = colours; - mesh.indexes = indexes; - mesh.lmst_array = NULL; - mesh.st_array = texcoords; - mesh.normals_array = NULL; - mesh.xyz_array = vertcoords; - - mb.fog = NULL;//fog; - mb.mesh = NULL; - mb.infokey = -1; - mb.dlightbits = 0; - - R_IBrokeTheArrays(); - - while (count--) - { - currententity = *entlist++; - if (currententity->forcedshader != lastshader || 1) - { - if (lastshader) - { - mesh.numvertexes = vnum; - mesh.numindexes = inum; - mesh.radius = currententity->scale; - R_PushMesh(&mesh, lastshader->features | MF_NONBATCHED|MF_COLORS); - - mb.entity = currententity; - mb.shader = currententity->forcedshader; - R_RenderMeshBuffer (&mb, false); - } - - lastshader = currententity->forcedshader; - } - - - #define VectorSet(a,b,c,v) {v[0]=a;v[1]=b;v[2]=c;} - x = cos(currententity->rotation+225*M_PI/180)*currententity->scale; - y = sin(currententity->rotation+225*M_PI/180)*currententity->scale; - VectorSet (currententity->origin[0] - y*vright[0] + x*vup[0], currententity->origin[1] - y*vright[1] + x*vup[1], currententity->origin[2] - y*vright[2] + x*vup[2], vertcoords[3]); - VectorSet (currententity->origin[0] - x*vright[0] - y*vup[0], currententity->origin[1] - x*vright[1] - y*vup[1], currententity->origin[2] - x*vright[2] - y*vup[2], vertcoords[2]); - VectorSet (currententity->origin[0] + y*vright[0] - x*vup[0], currententity->origin[1] + y*vright[1] - x*vup[1], currententity->origin[2] + y*vright[2] - x*vup[2], vertcoords[1]); - VectorSet (currententity->origin[0] + x*vright[0] + y*vup[0], currententity->origin[1] + x*vright[1] + y*vup[1], currententity->origin[2] + x*vright[2] + y*vup[2], vertcoords[0]); - - coloursb[0] = currententity->shaderRGBAf[0]*255; - coloursb[1] = currententity->shaderRGBAf[1]*255; - coloursb[2] = currententity->shaderRGBAf[2]*255; - coloursb[3] = currententity->shaderRGBAf[3]*255; - *(int*)colours[0] = *(int*)colours[1] = *(int*)colours[2] = *(int*)colours[3] = *(int*)coloursb; - - vnum += 4; - inum += 6; - } - - if (lastshader) - { - mesh.numvertexes = vnum; - mesh.numindexes = inum; - mesh.radius = currententity->scale; - R_PushMesh(&mesh, lastshader->features | MF_NONBATCHED|MF_COLORS); - - mb.entity = currententity; - mb.shader = currententity->forcedshader; - R_RenderMeshBuffer (&mb, false); - } -} -#endif void GLR_DrawSprite(int count, void **e, void *parm) { -// R_DrawShadedSpriteModels(count, e, parm); -// return; - while(count--) { +#pragma message("this needs merging or q3 railgun will lag like hell") currententity = *e++; - qglEnable(GL_TEXTURE_2D); R_DrawSpriteModel (currententity); } } -#ifdef Q3SHADERS +#ifdef Q3CLIENT //q3 lightning gun void R_DrawLightning(entity_t *e) @@ -818,12 +647,11 @@ void R_DrawLightning(entity_t *e) float scale = e->scale; float length; - vec3_t points[4]; + vecV_t points[4]; vec2_t texcoords[4] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}}; index_t indexarray[6] = {0, 1, 2, 0, 2, 3}; mesh_t mesh; - meshbuffer_t mb; if (!e->forcedshader) return; @@ -853,31 +681,18 @@ void R_DrawLightning(entity_t *e) VectorMA(e->oldorigin, scale/2, cr, points[2]); VectorMA(e->oldorigin, -scale/2, cr, points[3]); + memset(&mesh, 0, sizeof(mesh)); mesh.vbofirstelement = 0; mesh.vbofirstvert = 0; mesh.xyz_array = points; mesh.indexes = indexarray; mesh.numindexes = sizeof(indexarray)/sizeof(indexarray[0]); - mesh.colors_array = NULL; + mesh.colors4f_array = NULL; mesh.lmst_array = NULL; mesh.normals_array = NULL; mesh.numvertexes = 4; mesh.st_array = texcoords; - - mb.entity = e; - mb.mesh = &mesh; - mb.shader = e->forcedshader; - mb.infokey = 0; - mb.fog = NULL; - mb.infokey = currententity->keynum; - mb.dlightbits = 0; - - - R_IBrokeTheArrays(); - - R_PushMesh(&mesh, mb.shader->features | MF_NONBATCHED); - - R_RenderMeshBuffer ( &mb, false ); + BE_DrawMeshChain(e->forcedshader, &mesh, NULL, NULL); } //q3 railgun beam void R_DrawRailCore(entity_t *e) @@ -888,12 +703,10 @@ void R_DrawRailCore(entity_t *e) float length; mesh_t mesh; - meshbuffer_t mb; - vec3_t points[4]; + vecV_t points[4]; vec2_t texcoords[4] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}}; index_t indexarray[6] = {0, 1, 2, 0, 2, 3}; - int colors[4]; - qbyte colorsb[4]; + vec4_t colors[4]; if (!e->forcedshader) return; @@ -923,37 +736,24 @@ void R_DrawRailCore(entity_t *e) VectorMA(e->oldorigin, scale/2, cr, points[2]); VectorMA(e->oldorigin, -scale/2, cr, points[3]); - colorsb[0] = e->shaderRGBAf[0]*255; - colorsb[1] = e->shaderRGBAf[1]*255; - colorsb[2] = e->shaderRGBAf[2]*255; - colorsb[3] = e->shaderRGBAf[3]*255; - colors[0] = colors[1] = colors[2] = colors[3] = *(int*)colorsb; + Vector4Copy(e->shaderRGBAf, colors[0]); + Vector4Copy(e->shaderRGBAf, colors[1]); + Vector4Copy(e->shaderRGBAf, colors[2]); + Vector4Copy(e->shaderRGBAf, colors[3]); + memset(&mesh, 0, sizeof(mesh)); mesh.vbofirstelement = 0; mesh.vbofirstvert = 0; mesh.xyz_array = points; mesh.indexes = indexarray; mesh.numindexes = sizeof(indexarray)/sizeof(indexarray[0]); - mesh.colors_array = (byte_vec4_t*)colors; + mesh.colors4f_array = (vec4_t*)colors; mesh.lmst_array = NULL; mesh.normals_array = NULL; mesh.numvertexes = 4; mesh.st_array = texcoords; - mb.entity = e; - mb.mesh = &mesh; - mb.shader = e->forcedshader; - mb.infokey = 0; - mb.fog = NULL; - mb.infokey = currententity->keynum; - mb.dlightbits = 0; - - - R_IBrokeTheArrays(); - - R_PushMesh(&mesh, mb.shader->features | MF_NONBATCHED | MF_COLORS); - - R_RenderMeshBuffer ( &mb, false ); + BE_DrawMeshChain(e->forcedshader, &mesh, NULL, NULL); } #endif @@ -984,7 +784,7 @@ void GLR_DrawEntitiesOnList (void) RQ_AddDistReorder(GLR_DrawSprite, currententity, NULL, currententity->origin); // R_DrawSpriteModel(currententity); continue; -#ifdef Q3SHADERS +#ifdef Q3CLIENT case RT_BEAM: case RT_RAIL_RINGS: case RT_LIGHTNING: @@ -1031,7 +831,7 @@ void GLR_DrawEntitiesOnList (void) { case mod_alias: if (r_refdef.flags & Q2RDF_NOWORLDMODEL || !cl.worldmodel || cl.worldmodel->type != mod_brush || cl.worldmodel->fromgame == fg_doom) - R_DrawGAliasModel (currententity); + R_DrawGAliasModel (currententity, BEM_STANDARD); break; #ifdef HALFLIFEMODELS @@ -1067,6 +867,7 @@ R_PolyBlend ============ */ void GLV_CalcBlendServer (float colors[4]); +//bright flashes and stuff void R_PolyBlend (void) { float shift[4]; @@ -1081,6 +882,9 @@ void R_PolyBlend (void) //Con_Printf("R_PolyBlend(): %4.2f %4.2f %4.2f %4.2f\n",shift[0], shift[1], shift[2], shift[3]); + PPL_RevertToKnownState(); + + GL_DisableMultitexture(); qglDisable (GL_ALPHA_TEST); @@ -1090,26 +894,24 @@ void R_PolyBlend (void) qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - qglLoadIdentity (); - - qglRotatef (-90, 1, 0, 0); // put Z going up - qglRotatef (90, 0, 0, 1); // put Z going up - qglColor4fv (shift); qglBegin (GL_QUADS); - qglVertex3f (10, 100, 100); - qglVertex3f (10, -100, 100); - qglVertex3f (10, -100, -100); - qglVertex3f (10, 100, -100); + qglVertex3f (r_refdef.vrect.x, r_refdef.vrect.y, -1); + qglVertex3f (r_refdef.vrect.x, r_refdef.vrect.y+r_refdef.vrect.height, -1); + qglVertex3f (r_refdef.vrect.x+r_refdef.vrect.width, r_refdef.vrect.y+r_refdef.vrect.height, -1); + qglVertex3f (r_refdef.vrect.x+r_refdef.vrect.width, r_refdef.vrect.y, -1); qglEnd (); qglDisable (GL_BLEND); qglEnable (GL_TEXTURE_2D); qglEnable (GL_ALPHA_TEST); + + PPL_RevertToKnownState(); } +//for lack of hardware gamma void GLR_BrightenScreen (void) { float f; @@ -1122,6 +924,8 @@ void GLR_BrightenScreen (void) if (r_refdef.flags & Q2RDF_NOWORLDMODEL) return; + PPL_RevertToKnownState(); + f = gl_contrast.value; f = min (f, 3); @@ -1146,6 +950,8 @@ void GLR_BrightenScreen (void) qglDisable (GL_BLEND); qglColor3f(1, 1, 1); + PPL_RevertToKnownState(); + RSpeedEnd(RSPEED_PALETTEFLASHES); } @@ -1163,7 +969,7 @@ void GLR_SetupFrame (void) if (!mirror) { - GLR_AnimateLight (); + R_AnimateLight (); // build the transformation matrix for the given view angles @@ -1189,7 +995,7 @@ void GLR_SetupFrame (void) r_oldviewcluster = r_viewcluster; r_oldviewcluster2 = r_viewcluster2; - leaf = GLMod_PointInLeaf (cl.worldmodel, r_origin); + leaf = RMod_PointInLeaf (cl.worldmodel, r_origin); r_viewcluster = r_viewcluster2 = leaf->cluster; // check above and below so crossing solid water doesn't draw wrong @@ -1199,7 +1005,7 @@ void GLR_SetupFrame (void) VectorCopy (r_origin, temp); temp[2] -= 16; - leaf = GLMod_PointInLeaf (cl.worldmodel, temp); + leaf = RMod_PointInLeaf (cl.worldmodel, temp); if ( !(leaf->contents & Q2CONTENTS_SOLID) && (leaf->cluster != r_viewcluster2) ) r_viewcluster2 = leaf->cluster; @@ -1210,7 +1016,7 @@ void GLR_SetupFrame (void) VectorCopy (r_origin, temp); temp[2] += 16; - leaf = GLMod_PointInLeaf (cl.worldmodel, temp); + leaf = RMod_PointInLeaf (cl.worldmodel, temp); if ( !(leaf->contents & Q2CONTENTS_SOLID) && (leaf->cluster != r_viewcluster2) ) r_viewcluster2 = leaf->cluster; @@ -1224,7 +1030,7 @@ void GLR_SetupFrame (void) r_oldviewleaf = r_viewleaf; r_oldviewleaf2 = r_viewleaf2; - r_viewleaf = GLMod_PointInLeaf (cl.worldmodel, r_origin); + r_viewleaf = RMod_PointInLeaf (cl.worldmodel, r_origin); if (!r_viewleaf) { @@ -1233,7 +1039,7 @@ void GLR_SetupFrame (void) { //look down a bit VectorCopy (r_origin, temp); temp[2] -= 16; - leaf = GLMod_PointInLeaf (cl.worldmodel, temp); + leaf = RMod_PointInLeaf (cl.worldmodel, temp); if (leaf->contents <= Q1CONTENTS_WATER && leaf->contents >= Q1CONTENTS_LAVA) r_viewleaf2 = leaf; else @@ -1244,7 +1050,7 @@ void GLR_SetupFrame (void) VectorCopy (r_origin, temp); temp[2] += 16; - leaf = GLMod_PointInLeaf (cl.worldmodel, temp); + leaf = RMod_PointInLeaf (cl.worldmodel, temp); if (leaf->contents == Q1CONTENTS_EMPTY) r_viewleaf2 = leaf; else @@ -1271,26 +1077,25 @@ R_SetupGL void R_SetupGL (void) { float screenaspect; - extern int glwidth, glheight; int x, x2, y2, y, w, h; float fov_x, fov_y; // // set up viewpoint // - x = r_refdef.vrect.x * glwidth/(int)vid.width; - x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * glwidth/(int)vid.width; - y = (vid.height-r_refdef.vrect.y) * glheight/(int)vid.height; - y2 = ((int)vid.height - (r_refdef.vrect.y + r_refdef.vrect.height)) * glheight/(int)vid.height; + x = r_refdef.vrect.x * vid.pixelwidth/(int)vid.width; + x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * vid.pixelwidth/(int)vid.width; + y = (vid.height-r_refdef.vrect.y) * vid.pixelheight/(int)vid.height; + y2 = ((int)vid.height - (r_refdef.vrect.y + r_refdef.vrect.height)) * vid.pixelheight/(int)vid.height; // fudge around because of frac screen scale if (x > 0) x--; - if (x2 < glwidth) + if (x2 < vid.pixelwidth) x2++; if (y2 < 0) y2--; - if (y < glheight) + if (y < vid.pixelheight) y++; w = x2 - x; @@ -1307,7 +1112,7 @@ void R_SetupGL (void) gl_truescreenrect.width = w; gl_truescreenrect.height = h; - qglViewport (glx + x, gly + y2, w, h); + qglViewport (x, y2, w, h); qglMatrixMode(GL_PROJECTION); @@ -1323,7 +1128,13 @@ void R_SetupGL (void) screenaspect = (float)r_refdef.vrect.width/r_refdef.vrect.height; if (r_refdef.useperspective) { - if ((!r_shadows.value || !gl_canstencil) && gl_maxdist.value>=100)//gl_nv_range_clamp) + int stencilshadows = 0; +#ifdef RTLIGHTS + stencilshadows |= r_shadow_realtime_dlight.value && r_shadow_realtime_dlight_shadows.value; + stencilshadows |= r_shadow_realtime_world.value && r_shadow_realtime_world_shadows.value; +#endif + + if ((!stencilshadows || !gl_canstencil) && gl_maxdist.value>=100)//gl_nv_range_clamp) { // yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*180/M_PI; // yfov = (2.0 * tan (scr_fov.value/360*M_PI)) / screenaspect; @@ -1346,63 +1157,12 @@ void R_SetupGL (void) } qglLoadMatrixf(r_projection_matrix); - if (mirror) - { -// if (mirror_plane->normal[2]) -// qglScalef (1, -1, 1); -// else -// qglScalef (-1, 1, 1); - qglCullFace(GL_BACK); - } - else - { -#ifdef R_XFLIP - if (r_xflip.value) - { - qglScalef (1, -1, 1); - qglCullFace(GL_BACK); - } - else -#endif - qglCullFace(GL_FRONT); - } - qglMatrixMode(GL_MODELVIEW); Matrix4_ModelViewMatrixFromAxis(r_view_matrix, vpn, vright, vup, r_refdef.vieworg); qglLoadMatrixf(r_view_matrix); - // - // set drawing parms - // - if (gl_cull.value) - qglEnable(GL_CULL_FACE); - else - qglDisable(GL_CULL_FACE); - - qglDisable(GL_BLEND); - qglDisable(GL_ALPHA_TEST); - qglEnable(GL_DEPTH_TEST); - -//#ifndef D3DQUAKE -// glClearDepth(1.0f); -//#endif - -// if (gl_lightmap_format == GL_LUMINANCE) -// glBlendFunc (GL_ZERO, GL_ONE_MINUS_SRC_COLOR); -/* else if (gl_lightmap_format == GL_INTENSITY) - { - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); - glColor4f (0,0,0,1); - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - else if (gl_lightmap_format == GL_RGBA) - { - glBlendFunc (GL_ZERO, GL_ONE_MINUS_SRC_COLOR); - } - - */ if (gl_dither.value) { qglEnable(GL_DITHER); @@ -1411,10 +1171,6 @@ void R_SetupGL (void) { qglDisable(GL_DITHER); } - - qglPolygonOffset(r_polygonoffset_submodel_factor.value, r_polygonoffset_submodel_offset.value); - - GL_DisableMultitexture(); } /* @@ -1431,8 +1187,9 @@ void R_RenderScene (void) if (!cl.worldmodel || (!cl.worldmodel->nodes && cl.worldmodel->type != mod_heightmap)) r_refdef.flags |= Q2RDF_NOWORLDMODEL; -#ifdef NEWBACKEND - Sh_GenShadowMaps(); +#ifdef RTLIGHTS + if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL)) + Sh_GenShadowMaps(); #endif GLR_SetupFrame (); @@ -1441,7 +1198,7 @@ void R_RenderScene (void) R_SetupGL (); TRACE(("dbg: calling R_SetFrustrum\n")); - R_SetFrustum (); + R_SetFrustum (r_projection_matrix, r_view_matrix); if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL)) { @@ -1472,11 +1229,6 @@ void R_RenderScene (void) TRACE(("dbg: calling R_DrawParticles\n")); P_DrawParticles (); } - -#ifdef GLTEST - Test_Draw (); -#endif - } @@ -1488,7 +1240,6 @@ R_Clear int gldepthfunc = GL_LEQUAL; void R_Clear (void) { - qglDepthMask(1); if (r_mirroralpha.value != 1.0) { if (gl_clear.value && !r_secondaryview) @@ -1534,8 +1285,6 @@ void R_Clear (void) gldepthmax = 1; gldepthfunc=GL_LEQUAL; } - - qglDepthFunc (gldepthfunc); qglDepthRange (gldepthmin, gldepthmax); } @@ -1621,7 +1370,7 @@ void R_Mirror (void) qglEnableClientState( GL_VERTEX_ARRAY ); for (prevs = s; s; s=s->nextalphasurface) //write the polys to the stencil buffer. { - qglVertexPointer(3, GL_FLOAT, 0, s->mesh->xyz_array); + qglVertexPointer(3, GL_FLOAT, sizeof(vecV_t), s->mesh->xyz_array); qglDrawElements(GL_TRIANGLES, s->mesh->numindexes, GL_INDEX_TYPE, s->mesh->indexes); } @@ -1776,7 +1525,7 @@ qglEnable(GL_POLYGON_OFFSET_FILL); for (s=prevs ; s ; s=s->nextalphasurface) { qglEnable (GL_BLEND); - R_RenderBrushPoly (s); + //R_RenderBrushPoly (s); } qglDisable(GL_POLYGON_OFFSET_FILL); qglPolygonOffset(0, 0); @@ -1858,18 +1607,20 @@ static void R_RenderMotionBlur(void) if (gl_config.arb_texture_non_power_of_two) { //we can use any size, supposedly - vwidth = glwidth; - vheight = glheight; + vwidth = vid.pixelwidth; + vheight = vid.pixelheight; } else { //limit the texture size to square and use padding. - while (vwidth < glwidth) + while (vwidth < vid.pixelwidth) vwidth *= 2; - while (vheight < glheight) + while (vheight < vid.pixelheight) vheight *= 2; } - qglViewport (glx, gly, glwidth, glheight); + qglViewport (0, 0, vid.pixelwidth, vid.pixelheight); + + PPL_RevertToKnownState(); GL_Bind(sceneblur_texture); @@ -1877,20 +1628,20 @@ static void R_RenderMotionBlur(void) qglMatrixMode(GL_PROJECTION); qglPushMatrix(); qglLoadIdentity (); - qglOrtho (0, glwidth, 0, glheight, -99999, 99999); + qglOrtho (0, vid.pixelwidth, 0, vid.pixelheight, -99999, 99999); qglMatrixMode(GL_MODELVIEW); qglPushMatrix(); qglLoadIdentity (); //blend the last frame onto the scene //the maths is because our texture is over-sized (must be power of two) - cs = vs = (float)glwidth / vwidth * 0.5; - ct = vt = (float)glheight / vheight * 0.5; + cs = vs = (float)vid.pixelwidth / vwidth * 0.5; + ct = vt = (float)vid.pixelheight / vheight * 0.5; vs *= gl_motionblurscale.value; vt *= gl_motionblurscale.value; qglDisable (GL_DEPTH_TEST); - qglDisable (GL_CULL_FACE); + GL_CullFace(0); qglDisable (GL_ALPHA_TEST); qglEnable(GL_BLEND); qglColor4f(1, 1, 1, gl_motionblur.value); @@ -1898,11 +1649,11 @@ static void R_RenderMotionBlur(void) qglTexCoord2f(cs-vs, ct-vt); qglVertex2f(0, 0); qglTexCoord2f(cs+vs, ct-vt); - qglVertex2f(glwidth, 0); + qglVertex2f(vid.pixelwidth, 0); qglTexCoord2f(cs+vs, ct+vt); - qglVertex2f(glwidth, glheight); + qglVertex2f(vid.pixelwidth, vid.pixelheight); qglTexCoord2f(cs-vs, ct+vt); - qglVertex2f(0, glheight); + qglVertex2f(0, vid.pixelheight); qglEnd(); qglMatrixMode(GL_PROJECTION); @@ -1912,9 +1663,11 @@ static void R_RenderMotionBlur(void) //copy the image into the texture so that we can play with it next frame too! - qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, glx, gly, vwidth, vheight, 0); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, vwidth, vheight, 0); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + PPL_RevertToKnownState(); } static void R_RenderWaterWarp(void) @@ -1922,54 +1675,56 @@ static void R_RenderWaterWarp(void) float vwidth = 1, vheight = 1; float vs, vt; + PPL_RevertToKnownState(); + // get the powers of 2 for the size of the texture that will hold the scene if (gl_config.arb_texture_non_power_of_two) { - vwidth = glwidth; - vheight = glheight; + vwidth = vid.pixelwidth; + vheight = vid.pixelheight; } else { - while (vwidth < glwidth) + while (vwidth < vid.pixelwidth) { vwidth *= 2; } - while (vheight < glheight) + while (vheight < vid.pixelheight) { vheight *= 2; } } // get the maxtexcoords while we're at it - vs = glwidth / vwidth; - vt = glheight / vheight; + vs = vid.pixelwidth / vwidth; + vt = vid.pixelheight / vheight; // 2d mode, but upside down to quake's normal 2d drawing // this makes grabbing the sreen a lot easier - qglViewport (glx, gly, glwidth, glheight); + qglViewport (0, 0, vid.pixelwidth, vid.pixelheight); qglMatrixMode(GL_PROJECTION); // Push the matrices to go into 2d mode, that matches opengl's mode qglPushMatrix(); qglLoadIdentity (); // TODO: use actual window width and height - qglOrtho (0, glwidth, 0, glheight, -99999, 99999); + qglOrtho (0, vid.pixelwidth, 0, vid.pixelheight, -99999, 99999); qglMatrixMode(GL_MODELVIEW); qglPushMatrix(); qglLoadIdentity (); qglDisable (GL_DEPTH_TEST); - qglDisable (GL_CULL_FACE); + GL_CullFace(0); qglDisable (GL_BLEND); qglEnable (GL_ALPHA_TEST); // copy the scene to texture GL_Bind(scenepp_texture); - qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, glx, gly, vwidth, vheight, 0); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, vwidth, vheight, 0); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); if (qglGetError()) Con_Printf(CON_ERROR "GL Error after qglCopyTexImage2D\n"); @@ -2003,7 +1758,7 @@ static void R_RenderWaterWarp(void) GL_EnableMultitexture(); GL_Bind (scenepp_texture_warp); - GL_SelectTexture(mtexid1+1); + GL_SelectTexture(2); qglEnable(GL_TEXTURE_2D); GL_Bind(scenepp_texture_edge); @@ -2017,22 +1772,22 @@ static void R_RenderWaterWarp(void) qglMTexCoord2fSGIS (mtexid0, vs, 0); qglMTexCoord2fSGIS (mtexid1, xmax, ymin); qglMTexCoord2fSGIS (mtexid1+1, 1, 0); - qglVertex2f(glwidth, 0); + qglVertex2f(vid.pixelwidth, 0); qglMTexCoord2fSGIS (mtexid0, vs, vt); qglMTexCoord2fSGIS (mtexid1, xmax, ymax); qglMTexCoord2fSGIS (mtexid1+1, 1, 1); - qglVertex2f(glwidth, glheight); + qglVertex2f(vid.pixelwidth, vid.pixelheight); qglMTexCoord2fSGIS (mtexid0, 0, vt); qglMTexCoord2fSGIS (mtexid1, xmin, ymax); qglMTexCoord2fSGIS (mtexid1+1, 0, 1); - qglVertex2f(0, glheight); + qglVertex2f(0, vid.pixelheight); qglEnd(); qglDisable(GL_TEXTURE_2D); - GL_SelectTexture(mtexid1); + GL_SelectTexture(1); GL_DisableMultitexture(); } @@ -2046,6 +1801,8 @@ static void R_RenderWaterWarp(void) qglMatrixMode(GL_MODELVIEW); qglPopMatrix(); + PPL_RevertToKnownState(); + if (qglGetError()) Con_Printf("GL Error after drawing with shaderobjects\n"); } @@ -2069,14 +1826,14 @@ qboolean R_RenderScene_Fish(void) if (gl_config.arb_texture_non_power_of_two) { - if (glwidth < glheight) - cmapsize = glwidth; + if (vid.pixelwidth < vid.pixelheight) + cmapsize = vid.pixelwidth; else - cmapsize = glheight; + cmapsize = vid.pixelheight; } else { - while (cmapsize > glwidth || cmapsize > glheight) + while (cmapsize > vid.pixelwidth || cmapsize > vid.pixelheight) { cmapsize /= 2; } @@ -2129,16 +1886,16 @@ qboolean R_RenderScene_Fish(void) order[5] = 5; } - qglViewport (glx, gly+glheight - cmapsize, cmapsize, cmapsize); + qglViewport (0, vid.pixelheight - cmapsize, cmapsize, cmapsize); - if (!scenepp_fisheye_texture) + if (!TEXVALID(scenepp_fisheye_texture)) { scenepp_fisheye_texture = GL_AllocNewTexture(); qglDisable(GL_TEXTURE_2D); qglEnable(GL_TEXTURE_CUBE_MAP_ARB); - bindTexFunc(GL_TEXTURE_CUBE_MAP_ARB, scenepp_fisheye_texture); + GL_BindType(GL_TEXTURE_CUBE_MAP_ARB, scenepp_fisheye_texture); for (i = 0; i < 6; i++) qglCopyTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + i, 0, GL_RGB, 0, 0, cmapsize, cmapsize, 0); qglTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); @@ -2150,8 +1907,8 @@ qboolean R_RenderScene_Fish(void) qglDisable(GL_TEXTURE_CUBE_MAP_ARB); } - r_refdef.vrect.width = (cmapsize+0.99)*vid.width/glwidth; - r_refdef.vrect.height = (cmapsize+0.99)*vid.height/glheight; + r_refdef.vrect.width = (cmapsize+0.99)*vid.width/vid.pixelwidth; + r_refdef.vrect.height = (cmapsize+0.99)*vid.height/vid.pixelheight; r_refdef.vrect.x = 0; r_refdef.vrect.y = vid.height - r_refdef.vrect.height; @@ -2184,9 +1941,6 @@ qboolean R_RenderScene_Fish(void) // render normal view R_RenderScene (); - GLR_DrawWaterSurfaces (); - GLR_DrawAlphaSurfaces (); - // render mirror view R_Mirror (); @@ -2199,7 +1953,7 @@ qboolean R_RenderScene_Fish(void) } //qglClear (GL_COLOR_BUFFER_BIT); - qglViewport (glx, gly, glwidth, glheight); + qglViewport (0, 0, vid.pixelwidth, vid.pixelheight); qglDisable(GL_TEXTURE_2D); GL_BindType(GL_TEXTURE_CUBE_MAP_ARB, scenepp_fisheye_texture); @@ -2221,24 +1975,24 @@ qboolean R_RenderScene_Fish(void) qglMatrixMode(GL_PROJECTION); qglPushMatrix(); qglLoadIdentity (); - qglOrtho (0, glwidth, 0, glheight, -99999, 99999); + qglOrtho (0, vid.pixelwidth, 0, vid.pixelheight, -99999, 99999); qglMatrixMode(GL_MODELVIEW); qglPushMatrix(); qglLoadIdentity (); qglDisable (GL_DEPTH_TEST); - qglDisable (GL_CULL_FACE); + GL_CullFace(0); qglDisable (GL_ALPHA_TEST); qglDisable(GL_BLEND); qglBegin(GL_QUADS); qglTexCoord2f(-0.5, -0.5); qglVertex2f(0, 0); qglTexCoord2f(0.5, -0.5); - qglVertex2f(glwidth, 0); + qglVertex2f(vid.pixelwidth, 0); qglTexCoord2f(0.5, 0.5); - qglVertex2f(glwidth, glheight); + qglVertex2f(vid.pixelwidth, vid.pixelheight); qglTexCoord2f(-0.5, 0.5); - qglVertex2f(0, glheight); + qglVertex2f(0, vid.pixelheight); qglEnd(); qglMatrixMode(GL_PROJECTION); @@ -2269,7 +2023,7 @@ void GLR_RenderView (void) if (qglGetError()) Con_Printf("GL Error before drawing scene\n"); - if (r_norefresh.value || !glwidth || !glheight) + if (r_norefresh.value || !vid.pixelwidth || !vid.pixelheight) { GL_DoSwap(); return; @@ -2300,14 +2054,14 @@ void GLR_RenderView (void) qglPNTrianglesfATI(GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI, gl_ati_truform_tesselation.value); } - if (gl_finish.value) + if (gl_finish.ival) { RSpeedMark(); qglFinish (); RSpeedEnd(RSPEED_FINISH); } - if (r_speeds.value) + if (r_speeds.ival) { time1 = Sys_DoubleTime (); c_brush_polys = 0; @@ -2324,31 +2078,26 @@ void GLR_RenderView (void) { mirror = false; + GL_SetShaderState2D(false); + R_Clear (); // GLR_SetupFog (); r_alpha_surfaces = NULL; - GL_SetShaderState2D(false); - // render normal view R_RenderScene (); - GLR_DrawWaterSurfaces (); - GLR_DrawAlphaSurfaces (); - // render mirror view R_Mirror (); } R_BloomBlend(); - R_PolyBlend (); - // qglDisable(GL_FOG); - if (r_speeds.value) + if (r_speeds.ival) { // glFinish (); time2 = Sys_DoubleTime (); diff --git a/engine/gl/gl_rmisc.c b/engine/gl/gl_rmisc.c index cb3ad1f7..f5e2272e 100644 --- a/engine/gl/gl_rmisc.c +++ b/engine/gl/gl_rmisc.c @@ -20,11 +20,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // r_misc.c #include "quakedef.h" -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h" #include "gl_draw.h" -void R_ReloadRTLights_f(void); +static void R_ReloadRTLights_f(void); +static void R_SaveRTLights_f(void); #ifdef WATERLAYERS @@ -33,36 +34,6 @@ cvar_t r_waterlayers = SCVAR("r_waterlayers",""); extern void R_InitBubble(); -//SW rendering has a faster method, which takes more memory and stuff. -//We need this for minor things though, so we'5ll just use the slow accurate method. -//this is unlikly to be called very often. -qbyte GetPaletteIndex(int red, int green, int blue) -{ - //slow, horrible method. - { - int i, best=15; - int bestdif=256*256*256, curdif; - extern qbyte *host_basepal; - qbyte *pa; - - #define _abs(x) ((x)*(x)) - - pa = host_basepal; - for (i = 0; i < 256; i++, pa+=3) - { - curdif = _abs(red - pa[0]) + _abs(green - pa[1]) + _abs(blue - pa[2]); - if (curdif < bestdif) - { - if (curdif<1) - return i; - bestdif = curdif; - best = i; - } - } - return best; - } -} - /* ================== R_InitTextures @@ -95,143 +66,6 @@ void GLR_InitTextures (void) } } }*/ -//we could go for nice smooth round particles... but then we would loose a little bit of the chaotic nature of the particles. -static qbyte dottexture[8][8] = -{ - {0,0,0,0,0,0,0,0}, - {0,0,0,1,1,0,0,0}, - {0,0,1,1,1,1,0,0}, - {0,1,1,1,1,1,1,0}, - {0,1,1,1,1,1,1,0}, - {0,0,1,1,1,1,0,0}, - {0,0,0,1,1,0,0,0}, - {0,0,0,0,0,0,0,0}, -}; -static qbyte exptexture[16][16] = -{ - {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, - {0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0}, - {0,0,0,1,1,1,1,1,3,1,1,2,1,0,0,0}, - {0,0,0,1,1,1,1,4,4,4,5,4,2,1,1,0}, - {0,0,1,1,6,5,5,8,6,8,3,6,3,2,1,0}, - {0,0,1,5,6,7,5,6,8,8,8,3,3,1,0,0}, - {0,0,0,1,6,8,9,9,9,9,4,6,3,1,0,0}, - {0,0,2,1,7,7,9,9,9,9,5,3,1,0,0,0}, - {0,0,2,4,6,8,9,9,9,9,8,6,1,0,0,0}, - {0,0,2,2,3,5,6,8,9,8,8,4,4,1,0,0}, - {0,0,1,2,4,1,8,7,8,8,6,5,4,1,0,0}, - {0,1,1,1,7,8,1,6,7,5,4,7,1,0,0,0}, - {0,1,2,1,1,5,1,3,4,3,1,1,0,0,0,0}, - {0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0}, - {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, -}; - -void R_InitParticleTexture (void) -{ -#define PARTICLETEXTURESIZE 64 - int x,y; - float dx, dy, d; - qbyte data[PARTICLETEXTURESIZE*PARTICLETEXTURESIZE][4]; - - // - // particle texture - // - particletexture = GL_AllocNewTexture(); - GL_Bind(particletexture); - - for (x=0 ; x<8 ; x++) - { - for (y=0 ; y<8 ; y++) - { - data[y*8+x][0] = 255; - data[y*8+x][1] = 255; - data[y*8+x][2] = 255; - data[y*8+x][3] = dottexture[x][y]*255; - } - } - qglTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - - qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - - // - // particle triangle texture - // - particlecqtexture = GL_AllocNewTexture(); - GL_Bind(particlecqtexture); - - // clear to transparent white - for (x = 0; x < 32 * 32; x++) - { - data[x][0] = 255; - data[x][1] = 255; - data[x][2] = 255; - data[x][3] = 0; - } - //draw a circle in the top left. - for (x=0 ; x<16 ; x++) - { - for (y=0 ; y<16 ; y++) - { - if ((x - 7.5) * (x - 7.5) + (y - 7.5) * (y - 7.5) <= 8 * 8) - data[y*32+x][3] = 255; - } - } - qglTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - - qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - - - - - explosiontexture = GL_AllocNewTexture(); - GL_Bind(explosiontexture); - - for (x=0 ; x<16 ; x++) - { - for (y=0 ; y<16 ; y++) - { - data[y*16+x][0] = 255; - data[y*16+x][1] = 255; - data[y*16+x][2] = 255; - data[y*16+x][3] = exptexture[x][y]*255/9.0; - } - } - qglTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - - qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - - memset(data, 255, sizeof(data)); - for (y = 0;y < PARTICLETEXTURESIZE;y++) - { - dy = (y - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1); - for (x = 0;x < PARTICLETEXTURESIZE;x++) - { - dx = (x - 0.5f*PARTICLETEXTURESIZE) / (PARTICLETEXTURESIZE*0.5f-1); - d = 256 * (1 - (dx*dx+dy*dy)); - d = bound(0, d, 255); - data[y*PARTICLETEXTURESIZE+x][3] = (qbyte) d; - } - } - balltexture = GL_AllocNewTexture(); - GL_Bind(balltexture); - qglTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, PARTICLETEXTURESIZE, PARTICLETEXTURESIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -} /* =============== @@ -256,39 +90,39 @@ void R_Envmap_f (void) r_refdef.viewangles[0] = 0; r_refdef.viewangles[1] = 0; r_refdef.viewangles[2] = 0; - GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + GL_BeginRendering (); R_RenderView (); qglReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer); COM_WriteFile ("env0.rgb", buffer, sizeof(buffer)); r_refdef.viewangles[1] = 90; - GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + GL_BeginRendering (); R_RenderView (); qglReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer); COM_WriteFile ("env1.rgb", buffer, sizeof(buffer)); r_refdef.viewangles[1] = 180; - GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + GL_BeginRendering (); R_RenderView (); qglReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer); COM_WriteFile ("env2.rgb", buffer, sizeof(buffer)); r_refdef.viewangles[1] = 270; - GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + GL_BeginRendering (); R_RenderView (); qglReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer); COM_WriteFile ("env3.rgb", buffer, sizeof(buffer)); r_refdef.viewangles[0] = -90; r_refdef.viewangles[1] = 0; - GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + GL_BeginRendering (); R_RenderView (); qglReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer); COM_WriteFile ("env4.rgb", buffer, sizeof(buffer)); r_refdef.viewangles[0] = 90; r_refdef.viewangles[1] = 0; - GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + GL_BeginRendering (); R_RenderView (); qglReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer); COM_WriteFile ("env5.rgb", buffer, sizeof(buffer)); @@ -310,7 +144,7 @@ void R_Envmap_f (void) - +#if 0 qboolean GenerateNormalisationCubeMap() { unsigned char data[32*32*3]; @@ -466,7 +300,9 @@ qboolean GenerateNormalisationCubeMap() } -int normalisationCubeMap; +texid_t normalisationCubeMap; +#endif + /* =============== R_Init @@ -475,14 +311,11 @@ R_Init void GLR_ReInit (void) { extern int gl_bumpmappingpossible; - R_InitParticleTexture (); -#ifdef GLTEST - Test_Init (); -#endif netgraphtexture = GL_AllocNewTexture(); +#if 0 if (gl_bumpmappingpossible) { //Create normalisation cube map @@ -497,9 +330,9 @@ void GLR_ReInit (void) } else normalisationCubeMap = 0; +#endif R_InitBloomTextures(); - } /* typedef struct @@ -696,7 +529,6 @@ extern cvar_t r_fastskycolour; void GLCrosshairimage_Callback(struct cvar_s *var, char *oldvalue); void GLCrosshair_Callback(struct cvar_s *var, char *oldvalue); void GLCrosshaircolor_Callback(struct cvar_s *var, char *oldvalue); -void GLR_Skyboxname_Callback(struct cvar_s *var, char *oldvalue); void GLR_Menutint_Callback (struct cvar_s *var, char *oldvalue); void GL_Conback_Callback (struct cvar_s *var, char *oldvalue); void GL_Font_Callback (struct cvar_s *var, char *oldvalue); @@ -705,13 +537,7 @@ void GL_Fontinwardstep_Callback (struct cvar_s *var, char *oldvalue); void GLVID_Conwidth_Callback(struct cvar_s *var, char *oldvalue); void GLVID_Conautoscale_Callback(struct cvar_s *var, char *oldvalue); void GLVID_Conheight_Callback(struct cvar_s *var, char *oldvalue); -void GLR_Wallcolour_Callback(struct cvar_s *var, char *oldvalue); -void GLR_Floorcolour_Callback(struct cvar_s *var, char *oldvalue); -void GLR_Walltexture_Callback(struct cvar_s *var, char *oldvalue); -void GLR_Floortexture_Callback(struct cvar_s *var, char *oldvalue); -void GLR_Drawflat_Callback(struct cvar_s *var, char *oldvalue); void GLV_Gamma_Callback(struct cvar_s *var, char *oldvalue); -void GLR_Fastskycolour_Callback(struct cvar_s *var, char *oldvalue); void GLR_DeInit (void) { @@ -752,15 +578,18 @@ void GLR_Init (void) { Cmd_AddRemCommand ("timerefresh", GLR_TimeRefresh_f); Cmd_AddRemCommand ("envmap", R_Envmap_f); +#ifdef RTLIGHTS Cmd_AddRemCommand ("r_editlights_reload", R_ReloadRTLights_f); + Cmd_AddRemCommand ("r_editlights_save", R_SaveRTLights_f); +#endif // Cmd_AddRemCommand ("makewad", R_MakeTexWad_f); Cvar_Hook(&crosshair, GLCrosshair_Callback); Cvar_Hook(&crosshairimage, GLCrosshairimage_Callback); Cvar_Hook(&crosshaircolor, GLCrosshaircolor_Callback); - Cvar_Hook(&r_skyboxname, GLR_Skyboxname_Callback); Cvar_Hook(&r_menutint, GLR_Menutint_Callback); + Cvar_ForceCallback(&gl_conback); Cvar_Hook(&gl_conback, GL_Conback_Callback); Cvar_Hook(&gl_font, GL_Font_Callback); Cvar_Hook(&gl_smoothfont, GL_Smoothfont_Callback); @@ -768,12 +597,12 @@ void GLR_Init (void) Cvar_Hook(&vid_conautoscale, GLVID_Conautoscale_Callback); Cvar_Hook(&vid_conheight, GLVID_Conheight_Callback); Cvar_Hook(&vid_conwidth, GLVID_Conwidth_Callback); - Cvar_Hook(&r_floorcolour, GLR_Floorcolour_Callback); - Cvar_Hook(&r_fastskycolour, GLR_Fastskycolour_Callback); - Cvar_Hook(&r_wallcolour, GLR_Wallcolour_Callback); - Cvar_Hook(&r_floortexture, GLR_Floortexture_Callback); - Cvar_Hook(&r_walltexture, GLR_Walltexture_Callback); - Cvar_Hook(&r_drawflat, GLR_Drawflat_Callback); +// Cvar_Hook(&r_floorcolour, GLR_Floorcolour_Callback); +// Cvar_Hook(&r_fastskycolour, GLR_Fastskycolour_Callback); +// Cvar_Hook(&r_wallcolour, GLR_Wallcolour_Callback); +// Cvar_Hook(&r_floortexture, GLR_Floortexture_Callback); +// Cvar_Hook(&r_walltexture, GLR_Walltexture_Callback); +// Cvar_Hook(&r_drawflat, GLR_Drawflat_Callback); Cvar_Hook(&v_gamma, GLV_Gamma_Callback); Cvar_Hook(&v_contrast, GLV_Gamma_Callback); @@ -782,7 +611,8 @@ void GLR_Init (void) GLR_ReInit(); } -void R_ImportRTLights(char *entlump) +#ifdef RTLIGHTS +static void R_ImportRTLights(char *entlump) { typedef enum lighttype_e {LIGHTTYPE_MINUSX, LIGHTTYPE_RECIPX, LIGHTTYPE_RECIPXX, LIGHTTYPE_NONE, LIGHTTYPE_SUN, LIGHTTYPE_MINUSXX} lighttype_t; @@ -986,11 +816,14 @@ void R_ImportRTLights(char *entlump) VectorAdd(origin, originhack, origin); if (radius >= 1) { - dlight_t *dl = CL_AllocDlight(0); + dlight_t *dl = CL_AllocSlight(); + if (!dl) + break; VectorCopy(origin, dl->origin); AngleVectors(angles, dl->axis[0], dl->axis[1], dl->axis[2]); dl->radius = radius; VectorCopy(color, dl->color); + dl->flags = 0; dl->flags |= LFLAG_REALTIMEMODE; dl->flags |= (pflags & PFLAGS_CORONA)?LFLAG_ALLOW_FLASH:0; dl->flags |= (pflags & PFLAGS_NOSHADOW)?LFLAG_NOSHADOWS:0; @@ -1002,7 +835,7 @@ void R_ImportRTLights(char *entlump) } } -void R_LoadRTLights(void) +static void R_LoadRTLights(void) { dlight_t *dl; char fname[MAX_QPATH]; @@ -1017,9 +850,9 @@ void R_LoadRTLights(void) vec3_t angles; - //delete all old lights - dlights_running = 0; - dlights_software = 0; + //delete all old lights, even dynamic ones + rtlights_first = RTL_FIRST; + rtlights_max = RTL_FIRST; COM_StripExtension(cl.worldmodel->name, fname, sizeof(fname)); strncat(fname, ".rtlights", MAX_QPATH-1); @@ -1035,6 +868,21 @@ void R_LoadRTLights(void) break; *end = '\0'; + while(*file == ' ' || *file == '\t') + file++; + if (*file == '!') + { + flags = LFLAG_NOSHADOWS; + file++; + } + else if (*file == '#') + { + flags = LFLAG_SHADOWMAP; + file++; + } + else + flags = 0; + file = COM_Parse(file); org[0] = atof(com_token); file = COM_Parse(file); @@ -1082,13 +930,16 @@ void R_LoadRTLights(void) file = COM_Parse(file); if (*com_token) - flags = atoi(com_token); + flags |= atoi(com_token); else - flags = LFLAG_REALTIMEMODE; + flags |= LFLAG_REALTIMEMODE; if (radius) { - dl = CL_AllocDlight(0); + dl = CL_AllocSlight(); + if (!dl) + break; + VectorCopy(org, dl->origin); dl->radius = radius; VectorCopy(rgb, dl->color); @@ -1102,6 +953,49 @@ void R_LoadRTLights(void) } } +static void R_SaveRTLights_f(void) +{ + dlight_t *light; + vfsfile_t *f; + unsigned int i; + char fname[MAX_QPATH]; + COM_StripExtension(cl.worldmodel->name, fname, sizeof(fname)); + strncat(fname, ".rtlights", MAX_QPATH-1); + + FS_CreatePath(fname, FS_GAMEONLY); + f = FS_OpenVFS(fname, "wb", FS_GAMEONLY); + if (!f) + { + Con_Printf("couldn't open %s\n", fname); + return; + } + for (light = cl_dlights+rtlights_first, i=rtlights_first; idie) + continue; + if (!light->radius) + continue; + VFS_PUTS(f, va( + "%s%f %f %f " + "%f %f %f %f " + "%i " + /*"\"%s\" %f " + "%f %f %f " + "%f %f %f %i "*/ + "\n" + , + (light->flags & LFLAG_NOSHADOWS)?"!":"", light->origin[0], light->origin[1], light->origin[2], + light->radius, light->color[0], light->color[1], light->color[2], + light->style-1, + "", 0, + 0, 0, 0, + 0, 0, 0, light->flags&(LFLAG_NORMALMODE|LFLAG_REALTIMEMODE) + )); + } + VFS_CLOSE(f); + Con_Printf("rtlights saved to %s\n", fname); +} + void R_ReloadRTLights_f(void) { if (!cl.worldmodel) @@ -1109,17 +1003,20 @@ void R_ReloadRTLights_f(void) Con_Printf("Cannot reload lights at this time\n"); return; } - dlights_running = 0; - dlights_software = 0; - if (strcmp(Cmd_Argv(1), "bsp")) - R_LoadRTLights(); - - if (!dlights_running) - { - Con_Printf("Importing rtlights from BSP\n"); + rtlights_first = RTL_FIRST; + rtlights_max = RTL_FIRST; + if (!strcmp(Cmd_Argv(1), "bsp")) R_ImportRTLights(cl.worldmodel->entities); + else if (!strcmp(Cmd_Argv(1), "rtlights")) + R_LoadRTLights(); + else if (strcmp(Cmd_Argv(1), "none")) + { + R_LoadRTLights(); + if (rtlights_first == rtlights_max) + R_ImportRTLights(cl.worldmodel->entities); } } +#endif /* =============== @@ -1129,7 +1026,7 @@ R_NewMap void GLR_NewMap (void) { char namebuf[MAX_QPATH]; - extern cvar_t host_mapname; + extern cvar_t host_mapname, r_shadow_realtime_dlight, r_shadow_realtime_world; int i; /* @@ -1178,23 +1075,17 @@ TRACE(("dbg: GLR_NewMap: figuring out skys and mirrors\n")); // identify sky texture if (cl.worldmodel->fromgame != fg_quake2 && cl.worldmodel->fromgame != fg_quake3) { - skytexturenum = -1; mirrortexturenum = -1; } for (i=0 ; inumtextures ; i++) { if (!cl.worldmodel->textures[i]) continue; - if (!Q_strncmp(cl.worldmodel->textures[i]->name,"sky",3) ) - skytexturenum = i; if (!Q_strncmp(cl.worldmodel->textures[i]->name,"window02_1",10) ) mirrortexturenum = i; cl.worldmodel->textures[i]->texturechain = NULL; } -TRACE(("dbg: GLR_NewMap: that skybox thang\n")); -//#ifdef QUAKE2 - GLR_LoadSkys (); -//#endif + TRACE(("dbg: GLR_NewMap: ui\n")); #ifdef VM_UI UI_Reset(); @@ -1202,10 +1093,14 @@ TRACE(("dbg: GLR_NewMap: ui\n")); TRACE(("dbg: GLR_NewMap: tp\n")); TP_NewMap(); - if (r_shadows.value) +#ifdef RTLIGHTS + if (r_shadow_realtime_dlight.value || r_shadow_realtime_world.value) { R_LoadRTLights(); + if (rtlights_first == rtlights_max) + R_ImportRTLights(cl.worldmodel->entities); } +#endif } void GLR_PreNewMap(void) diff --git a/engine/gl/gl_rsurf.c b/engine/gl/gl_rsurf.c index c3007dab..261c3a4a 100644 --- a/engine/gl/gl_rsurf.c +++ b/engine/gl/gl_rsurf.c @@ -20,26 +20,23 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // r_surf.c: surface-related refresh code #include "quakedef.h" -#ifdef RGLQUAKE +#if defined(GLQUAKE) //|| defined(D3DQUAKE) #include "glquake.h" #include "shader.h" #include "renderque.h" #include -int skytexturenum; - extern cvar_t gl_bump; -extern qbyte areabits[MAX_Q2MAP_AREAS/8]; +static qbyte areabits[MAX_Q2MAP_AREAS/8]; model_t *currentmodel; int lightmap_bytes; // 1, 3 or 4 -int *lightmap_textures; -int *deluxmap_textures; -int detailtexture; +texid_t *lightmap_textures; +texid_t *deluxmap_textures; #define MAX_LIGHTMAP_SIZE LMBLOCK_WIDTH @@ -58,8 +55,6 @@ extern msurface_t *r_mirror_chain; mleaf_t *r_vischain; // linked list of visible leafs -void R_RenderDynamicLightmaps (msurface_t *fa, int shift); - extern cvar_t gl_detail; extern cvar_t r_stains; extern cvar_t r_loadlits; @@ -72,8 +67,8 @@ int GLR_LightmapShift (model_t *model) { extern cvar_t gl_overbright_all, gl_lightmap_shift; - if (gl_overbright_all.value || (model->engineflags & MDLF_NEEDOVERBRIGHT)) - return bound(0, gl_lightmap_shift.value, 2); + if (gl_overbright_all.ival || (model->engineflags & MDLF_NEEDOVERBRIGHT)) + return bound(0, gl_lightmap_shift.ival, 2); return 0; } @@ -160,7 +155,7 @@ void GLR_StainSurf (msurface_t *surf, float *parms) //combination of R_AddDynamicLights and R_MarkLights /* -void GLR_StainNode (mnode_t *node, float *parms) +static void GLR_StainNode (mnode_t *node, float *parms) { mplane_t *splitplane; float dist; @@ -198,46 +193,6 @@ void GLR_StainNode (mnode_t *node, float *parms) } */ -void GLR_StainQ3Node (mnode_t *node, float *parms) -{ -// mplane_t *splitplane; -// float dist; - int i; - - if (node->contents != -1) - { - msurface_t **mark; - mleaf_t *leaf; - - // mark the polygons - leaf = (mleaf_t *)node; - mark = leaf->firstmarksurface; - for (i=0 ; inummarksurfaces ; i++) - { - GLR_StainSurf(*mark++, parms); - } - - return; - } - /* - splitplane = node->plane; - dist = DotProduct ((parms+1), splitplane->normal) - splitplane->dist; - - if (dist > (*parms)) - { - GLR_StainQ2Node (node->children[0], parms); - return; - } - if (dist < (-*parms)) - { - GLR_StainQ2Node (node->children[1], parms); - return; - }*/ - - GLR_StainQ3Node (node->children[0], parms); - GLR_StainQ3Node (node->children[1], parms); -} - void GLR_AddStain(vec3_t org, float red, float green, float blue, float radius) { physent_t *pe; @@ -363,7 +318,7 @@ void GLR_LessenStains(void) R_AddDynamicLights =============== */ -void GLR_AddDynamicLights (msurface_t *surf) +static void GLR_AddDynamicLights (msurface_t *surf) { int lnum; int sd, td; @@ -379,7 +334,7 @@ void GLR_AddDynamicLights (msurface_t *surf) tmax = (surf->extents[1]>>4)+1; tex = surf->texinfo; - for (lnum=0 ; lnumdlightbits & (1<extents[1]>>4)+1; tex = surf->texinfo; - for (lnum=0 ; lnumdlightbits & (1<extents[1]>>4)+1; tex = surf->texinfo; - for (lnum=0 ; lnumdlightbits & (1<xyz_array); - qglEnableClientState( GL_VERTEX_ARRAY ); - qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); - qglTexCoordPointer(2, GL_FLOAT, 0, mesh->st_array); - qglDrawElements(GL_TRIANGLES, mesh->numindexes, GL_INDEX_TYPE, mesh->indexes); - R_IBrokeTheArrays(); -} - -/* -================ -R_RenderBrushPoly -================ -*/ -void R_RenderBrushPoly (msurface_t *fa) -{ - //FIXME: this code is only used for mirrors. remove. - texture_t *t; - - c_brush_polys++; - - if (fa->flags & SURF_DRAWSKY) - { // warp texture, no lightmaps - return; - } - - t = R_TextureAnimation (fa->texinfo->texture); - GL_Bind (t->tn.base); - - if (fa->flags & SURF_DRAWTURB) - { // warp texture, no lightmaps - EmitWaterPolys (fa, r_wateralphaval); - qglDisable(GL_BLEND); //to ensure. - return; - } - - DrawGLPoly (fa->mesh); -} - /* ================ R_RenderDynamicLightmaps @@ -1782,7 +1684,7 @@ void R_RenderDynamicLightmaps (msurface_t *fa, int shift) if (fa->flags & ( SURF_DRAWSKY | SURF_DRAWTURB) ) return; - if (fa->texinfo->flags & (SURF_SKY|SURF_TRANS33|SURF_TRANS66|SURF_WARP)) + if (fa->texinfo->flags & (TI_SKY|TI_TRANS33|TI_TRANS66|TI_WARP)) return; if (fa->texinfo->flags & (TEX_SPECIAL)) @@ -1835,29 +1737,35 @@ dynamic: if ((theRect->h + theRect->t) < (fa->light_t + tmax)) theRect->h = (fa->light_t-theRect->t)+tmax; - lightmap[fa->lightmaptexturenum]->deluxmodified = true; - theRect = &lightmap[fa->lightmaptexturenum]->deluxrectchange; - if (fa->light_t < theRect->t) { - if (theRect->h) - theRect->h += theRect->t - fa->light_t; - theRect->t = fa->light_t; - } - if (fa->light_s < theRect->l) { - if (theRect->w) - theRect->w += theRect->l - fa->light_s; - theRect->l = fa->light_s; - } + if (gl_bump.ival) + { + lightmap[fa->lightmaptexturenum]->deluxmodified = true; + theRect = &lightmap[fa->lightmaptexturenum]->deluxrectchange; + if (fa->light_t < theRect->t) { + if (theRect->h) + theRect->h += theRect->t - fa->light_t; + theRect->t = fa->light_t; + } + if (fa->light_s < theRect->l) { + if (theRect->w) + theRect->w += theRect->l - fa->light_s; + theRect->l = fa->light_s; + } - if ((theRect->w + theRect->l) < (fa->light_s + smax)) - theRect->w = (fa->light_s-theRect->l)+smax; - if ((theRect->h + theRect->t) < (fa->light_t + tmax)) - theRect->h = (fa->light_t-theRect->t)+tmax; + if ((theRect->w + theRect->l) < (fa->light_s + smax)) + theRect->w = (fa->light_s-theRect->l)+smax; + if ((theRect->h + theRect->t) < (fa->light_t + tmax)) + theRect->h = (fa->light_t-theRect->t)+tmax; + + luxbase = lightmap[fa->lightmaptexturenum]->deluxmaps; + luxbase += fa->light_t * LMBLOCK_WIDTH * 3 + fa->light_s * 3; + } + else + luxbase = NULL; base = lightmap[fa->lightmaptexturenum]->lightmaps; base += fa->light_t * LMBLOCK_WIDTH * lightmap_bytes + fa->light_s * lightmap_bytes; - luxbase = lightmap[fa->lightmaptexturenum]->deluxmaps; - luxbase += fa->light_t * LMBLOCK_WIDTH * 3 + fa->light_s * 3; stainbase = lightmap[fa->lightmaptexturenum]->stainmaps; stainbase += (fa->light_t * LMBLOCK_WIDTH + fa->light_s) * 3; GLR_BuildLightMap (fa, base, luxbase, stainbase, shift); @@ -1880,270 +1788,6 @@ void R_MirrorChain (msurface_t *s) mirror_plane = s->plane; } - -/* -================ -R_DrawWaterSurfaces -================ -*/ -void GLR_DrawWaterSurfaces (void) -{ - int i; - msurface_t *s; - texture_t *t; - - if (r_wateralphaval == 1.0) - return; - - // - // go back to the world matrix - // - - qglLoadMatrixf (r_view_matrix); - - if (r_wateralphaval < 1.0) { - qglEnable (GL_BLEND); - qglDisable (GL_ALPHA_TEST); - qglColor4f (1,1,1,r_wateralphaval); - GL_TexEnv(GL_MODULATE); - } - else - { - qglDisable (GL_BLEND); - qglDisable (GL_ALPHA_TEST); - GL_TexEnv(GL_REPLACE); - } - - for (i=0 ; inumtextures ; i++) - { - t = cl.worldmodel->textures[i]; - if (!t) - continue; - s = t->texturechain; - if (!s) - continue; - if ( !(s->flags & SURF_DRAWTURB ) ) - continue; - - GL_Bind (t->tn.base); - - EmitWaterPolyChain (s, r_wateralphaval); - - t->texturechain = NULL; - } - - if (r_wateralphaval < 1.0) { - GL_TexEnv(GL_REPLACE); - - qglColor4f (1,1,1,1); - qglDisable (GL_BLEND); - } -} - - -static void GLR_DrawAlphaSurface(int count, msurface_t **surfs, void *type) -{ - msurface_t *s = (*surfs); - - qglPushMatrix(); - R_RotateForEntity(s->ownerent); -#ifdef Q3SHADERS - if (s->texinfo->texture->shader) - { - meshbuffer_t mb; - mb.dlightbits = 0; - mb.entity = s->ownerent; - mb.shader = s->texinfo->texture->shader; - mb.sortkey = 0; - - mb.infokey = s->lightmaptexturenum; - mb.mesh = s->mesh; - mb.fog = s->fog; - currententity = s->ownerent; - if (s->mesh) - { - R_PushMesh(s->mesh, mb.shader->features|MF_NONBATCHED); - R_RenderMeshBuffer ( &mb, false ); - } - - qglPopMatrix(); - return; - } -#endif - GL_Bind(s->texinfo->texture->tn.base); - - if (s->texinfo->flags & SURF_TRANS33) - qglColor4f (1,1,1,0.33); - else if (s->texinfo->flags & SURF_TRANS66) - qglColor4f (1,1,1,0.66); - else - { - if (s->flags & SURF_DRAWTURB) - { - qglColor4f (1,1,1,1); - EmitWaterPolys (s, r_wateralphaval); - } - else - { - Sys_Error("GLR_DrawAlphaSurface needs work"); - /* - if (gl_mtexable) - { - int i; - float *v; - glpoly_t *p; - GL_TexEnv(GL_REPLACE); - GL_EnableMultitexture(); - GL_Bind(lightmap_textures[s->lightmaptexturenum]); - GL_TexEnv(GL_BLEND); - p = s->polys; - - qglColor4f (1,1,1,1); - while(p) - { - qglBegin (GL_POLYGON); - v = p->verts[0]; - for (i=0 ; inumverts ; i++, v+= VERTEXSIZE) - { - qglMTexCoord2fSGIS (mtexid0, v[3], v[4]); - qglMTexCoord2fSGIS (mtexid1, v[5], v[6]); - qglVertex3fv (v); - } - qglEnd (); - p=p->next; - } - GL_DisableMultitexture(); - } - else - */ - { - if (s->samples) //could do true vertex lighting... ? - qglColor4ub (*s->samples,*s->samples,*s->samples,255); - else - qglColor4f (1,1,1,1); - DrawGLPoly (s->mesh); - } - } - - qglPopMatrix(); - return; - } - - if (s->flags & SURF_DRAWTURB || s->texinfo->flags & SURF_WARP) - EmitWaterPolys (s, r_wateralphaval); -// else if(s->texinfo->flags & SURF_FLOWING) // PGM 9/16/98 -// DrawGLFlowingPoly (s); // PGM - else - DrawGLPoly (s->mesh); - - qglPopMatrix(); -} - -void GLR_DrawAlphaSurfaces (void) -{ - msurface_t *s; - vec3_t v; - - // - // go back to the world matrix - // - - qglLoadMatrixf (r_view_matrix); - GL_TexEnv(GL_MODULATE); - - qglEnable(GL_ALPHA_TEST); - qglDisable(GL_BLEND); -// if (cl.worldmodel && (cl.worldmodel->fromgame == fg_quake2)) - { //this is a mahoosive hack. - qglDepthMask(0); //this makes no difference to the cheating. - - qglDisable(GL_ALPHA_TEST); - qglEnable(GL_BLEND); - } - qglColor4f (1,1,1,1); - for (s=r_alpha_surfaces ; s ; s=s->nextalphasurface) - { - if (s->flags&0x80000) - { - Con_Printf("Infinate alpha surface loop detected\n"); - break; - } - s->flags |= 0x80000; - if (s->texinfo->flags & SURF_ALPHATEST) - { //simple alpha testing. - - if (s->ownerent != currententity) - { - currententity = s->ownerent; - qglPopMatrix(); - qglPushMatrix(); - R_RotateForEntity(currententity); - } -/* - if (gl_mtexable) - { - int i; - float *v; - glpoly_t *p; - GL_Bind(s->texinfo->texture->gl_texturenum); - GL_TexEnv(GL_REPLACE); - GL_EnableMultitexture(); - GL_Bind(lightmap_textures[s->lightmaptexturenum]); - GL_TexEnv(GL_BLEND); - p = s->polys; - - - while(p) - { - qglBegin (GL_POLYGON); - v = p->verts[0]; - for (i=0 ; inumverts ; i++, v+= VERTEXSIZE) - { - qglMTexCoord2fSGIS (mtexid0, v[3], v[4]); - qglMTexCoord2fSGIS (mtexid1, v[5], v[6]); - qglVertex3fv (v); - } - qglEnd (); - p=p->next; - } - GL_DisableMultitexture(); - } - else -*/ - { -// if (s->samples) //could do true vertex lighting... ? -// qglColor4ub (*s->samples,*s->samples,*s->samples,255); -// else - qglColor4f (1,1,1,1); - DrawGLPoly (s->mesh); - qglColor4f (1,1,1,1); - } - continue; - } - v[0] = s->plane->normal[0] * s->plane->dist+s->ownerent->origin[0]; - v[1] = s->plane->normal[1] * s->plane->dist+s->ownerent->origin[1]; - v[2] = s->plane->normal[2] * s->plane->dist+s->ownerent->origin[2]; - RQ_AddDistReorder((void*)GLR_DrawAlphaSurface, s, NULL, v); - } - for (s=r_alpha_surfaces ; s ; s=s->nextalphasurface) - { - if (!(s->flags&0x80000)) - break; - s->flags &= ~0x80000; - } - RQ_RenderDistAndClear(); - qglDepthMask(1); - - GL_TexEnv(GL_REPLACE); - - qglColor4f (1,1,1,1); - qglDisable (GL_BLEND); - - r_alpha_surfaces = NULL; - - qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); -} - /* ============================================================= @@ -2152,49 +1796,15 @@ void GLR_DrawAlphaSurfaces (void) ============================================================= */ - -#if 0 -void R_MarkLeafSurfaces_Q1 (void) +qbyte *R_MarkLeafSurfaces_Q1 (void) { - static qbyte fatvis[MAX_MAP_LEAFS/8]; - static qbyte *vis; + qbyte *vis; mleaf_t *leaf; int i, j; - qbyte solid[4096]; msurface_t *surf; int shift; - r_visframecount++; - if (r_oldviewleaf == r_viewleaf && r_oldviewleaf2 == r_viewleaf2) - { - } - else - { - r_oldviewleaf = r_viewleaf; - r_oldviewleaf2 = r_viewleaf2; - - if ((int)r_novis.value&1) - { - vis = solid; - memset (solid, 0xff, (cl.worldmodel->numleafs+7)>>3); - } - else if (r_viewleaf2 && r_viewleaf2 != r_viewleaf) - { - int c; - Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf2, fatvis); - vis = Q1BSP_LeafPVS (cl.worldmodel, r_viewleaf, NULL); - c = (cl.worldmodel->numleafs+31)/32; - for (i=0 ; inumleafs ; i++) { @@ -2213,9 +1823,7 @@ void R_MarkLeafSurfaces_Q1 (void) continue; surf->visframe = r_visframecount; - R_RenderDynamicLightmaps (surf, shift); - surf->texturechain = surf->texinfo->texture->texturechain; - surf->texinfo->texture->texturechain = surf; + *surf->mark = surf; } //deal with static ents. @@ -2223,8 +1831,33 @@ void R_MarkLeafSurfaces_Q1 (void) R_StoreEfrags (&leaf->efrags); } } + + { + texture_t *tex; + + shift = GLR_LightmapShift(cl.worldmodel); + + for (i = 0; i < cl.worldmodel->numtextures; i++) + { + tex = cl.worldmodel->textures[i]; + if (!tex) + continue; + for (j = 0; j < tex->vbo.meshcount; j++) + { + surf = tex->vbo.meshlist[j]; + if (surf) + { + R_RenderDynamicLightmaps (surf, shift); + + tex->vbo.meshlist[j] = NULL; + surf->texturechain = surf->texinfo->texture->texturechain; + surf->texinfo->texture->texturechain = surf; + } + } + } + } + return vis; } -#else /* ================ @@ -2343,9 +1976,8 @@ start: } else */ { - *surf->texinfo->texture->texturechain_tail = surf; - surf->texinfo->texture->texturechain_tail = &surf->texturechain; - surf->texturechain = NULL; + surf->texturechain = surf->texinfo->texture->texturechain; + surf->texinfo->texture->texturechain = surf; } } } @@ -2356,7 +1988,6 @@ start: node = node->children[!side]; goto start; } -#endif #ifdef Q2BSPS static void GLR_RecursiveQ2WorldNode (mnode_t *node) @@ -2454,7 +2085,7 @@ static void GLR_RecursiveQ2WorldNode (mnode_t *node) R_RenderDynamicLightmaps (surf, shift); - if (surf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66)) + if (surf->texinfo->flags & (TI_TRANS33|TI_TRANS66)) { // add to the translucent chain surf->nextalphasurface = r_alpha_surfaces; r_alpha_surfaces = surf; @@ -2529,14 +2160,41 @@ static void GLR_LeafWorldNode (void) if (surf->visframe != r_framecount) //sufraces exist in multiple leafs. { surf->visframe = r_framecount; - + if (surf->mark) + *surf->mark = surf; + /* surf->texturechain = surf->texinfo->texture->texturechain; - surf->texinfo->texture->texturechain = surf; + surf->texinfo->texture->texturechain = surf;# + */ } } while (--i); // c_world_leafs++; } + + + + + { + int j; + texture_t *tex; + for (i = 0; i < cl.worldmodel->numtextures; i++) + { + tex = cl.worldmodel->textures[i]; + if (!tex) + continue; + for (j = 0; j < tex->vbo.meshcount; j++) + { + surf = tex->vbo.meshlist[j]; + if (surf) + { + tex->vbo.meshlist[j] = NULL; + surf->texturechain = surf->texinfo->texture->texturechain; + surf->texinfo->texture->texturechain = surf; + } + } + } + } } #endif @@ -2559,6 +2217,7 @@ R_DrawWorld void R_DrawWorld (void) { + qbyte *vis; RSpeedLocals(); entity_t ent; @@ -2576,10 +2235,6 @@ void R_DrawWorld (void) #endif { GLR_ClearChains(); - qglColor3f (1,1,1); - //#ifdef QUAKE2 - R_ClearSkyBox (); - //#endif RSpeedRemark(); @@ -2601,37 +2256,36 @@ void R_DrawWorld (void) #ifdef Q3BSPS if (ent.model->fromgame == fg_quake3) { - R_MarkLeaves_Q3 (); + vis = R_MarkLeaves_Q3 (); GLR_LeafWorldNode (); } else #endif { - R_MarkLeaves_Q2 (); + vis = R_MarkLeaves_Q2 (); GLR_RecursiveQ2WorldNode (cl.worldmodel->nodes); } } else #endif { -#if 0 - R_MarkLeafSurfaces_Q1(); -#else - R_MarkLeaves_Q1 (); - GLR_RecursiveWorldNode (cl.worldmodel->nodes, 0xf); -#endif + extern cvar_t temp1; + if (1)//temp1.value) + vis = R_MarkLeafSurfaces_Q1(); + else + { + vis = R_MarkLeaves_Q1 (); + GLR_RecursiveWorldNode (cl.worldmodel->nodes, 0xf); + } } RSpeedEnd(RSPEED_WORLDNODE); TRACE(("dbg: calling PPL_DrawWorld\n")); // if (r_shadows.value >= 2 && gl_canstencil && gl_mtexable) - PPL_DrawWorld(); + PPL_DrawWorld(vis); // else // DrawTextureChains (cl.worldmodel, 1, r_refdef.vieworg); - -qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - GLR_LessenStains(); } } @@ -2683,6 +2337,14 @@ int GLAllocBlock (int w, int h, int *x, int *y) lightmap[texnum]->modified = true; // reset stainmap since it now starts at 255 memset(lightmap[texnum]->stainmaps, 255, sizeof(lightmap[texnum]->stainmaps)); + + //clear out the deluxmaps incase there is none on the map. + for (j = 0; j < LMBLOCK_HEIGHT*LMBLOCK_HEIGHT*3; j+=3) + { + lightmap[texnum]->deluxmaps[j+0] = 128; + lightmap[texnum]->deluxmaps[j+1] = 128; + lightmap[texnum]->deluxmaps[j+2] = 255; + } } @@ -2757,6 +2419,14 @@ int GLFillBlock (int texnum, int w, int h, int x, int y) lightmap[i]->allocated[l] = LMBLOCK_HEIGHT; } + //clear out the deluxmaps incase there is none on the map. + for (l = 0; l < LMBLOCK_HEIGHT*LMBLOCK_HEIGHT*3; l+=3) + { + lightmap[i]->deluxmaps[l+0] = 0; + lightmap[i]->deluxmaps[l+1] = 0; + lightmap[i]->deluxmaps[l+2] = 255; + } + //maybe someone screwed with my lightmap... memset(lightmap[i]->lightmaps, 255, LMBLOCK_HEIGHT*LMBLOCK_HEIGHT*3); if (cl.worldmodel->lightdata) @@ -2767,7 +2437,7 @@ int GLFillBlock (int texnum, int w, int h, int x, int y) { char basename[MAX_QPATH]; COM_StripExtension(cl.worldmodel->name, basename, sizeof(basename)); - lightmap_textures[i] = Mod_LoadHiResTexture(va("%s/lm_%04i", basename, i), NULL, true, false, false); + lightmap_textures[i] = R_LoadHiResTexture(va("%s/lm_%04i", basename, i), NULL, IF_NOALPHA|IF_NOGAMMA); lightmap[i]->modified = false; } @@ -2805,22 +2475,22 @@ void GL_BuildSurfaceDisplayList (msurface_t *fa) return; //q3 flares. { //build a nice mesh instead of a poly. - int size = sizeof(mesh_t) + sizeof(index_t)*(lnumverts-2)*3 + (sizeof(vec3_t) + 3*sizeof(vec3_t) + 2*sizeof(vec2_t) + sizeof(byte_vec4_t))*lnumverts; + int size = sizeof(mesh_t) + sizeof(index_t)*(lnumverts-2)*3 + (sizeof(vecV_t) + 3*sizeof(vec3_t) + 2*sizeof(vec2_t) + sizeof(vec4_t))*lnumverts; mesh_t *mesh; fa->mesh = mesh = Hunk_Alloc(size); - mesh->xyz_array = (vec3_t*)(mesh + 1); + mesh->xyz_array = (vecV_t*)(mesh + 1); mesh->normals_array = (vec3_t*)(mesh->xyz_array + lnumverts); mesh->snormals_array = (vec3_t*)(mesh->normals_array + lnumverts); mesh->tnormals_array = (vec3_t*)(mesh->snormals_array + lnumverts); mesh->st_array = (vec2_t*)(mesh->tnormals_array + lnumverts); mesh->lmst_array = (vec2_t*)(mesh->st_array + lnumverts); - mesh->colors_array = (byte_vec4_t*)(mesh->lmst_array + lnumverts); - mesh->indexes = (index_t*)(mesh->colors_array + lnumverts); + mesh->colors4f_array = (vec4_t*)(mesh->lmst_array + lnumverts); + mesh->indexes = (index_t*)(mesh->colors4f_array + lnumverts); mesh->numindexes = (lnumverts-2)*3; mesh->numvertexes = lnumverts; - mesh->patchWidth = mesh->patchHeight = 1; + mesh->istrifan = true; for (i=0 ; iplane->normal, mesh->normals_array[i]); VectorNegate(fa->texinfo->vecs[0], mesh->snormals_array[i]); - VectorCopy(fa->texinfo->vecs[1], mesh->tnormals_array[i]); + VectorNegate(fa->texinfo->vecs[1], mesh->tnormals_array[i]); + VectorNormalize(mesh->snormals_array[i]); + VectorNormalize(mesh->tnormals_array[i]); - mesh->colors_array[i][0] = 255; - mesh->colors_array[i][1] = 255; - mesh->colors_array[i][2] = 255; - mesh->colors_array[i][3] = 255; + mesh->colors4f_array[i][0] = 1; + mesh->colors4f_array[i][1] = 1; + mesh->colors4f_array[i][2] = 1; + mesh->colors4f_array[i][3] = 1; } } } @@ -2938,7 +2610,8 @@ void GLSurf_DeInit(void) if (lightmap_textures) { - qglDeleteTextures(numlightmaps, lightmap_textures); + for (i = 0; i < numlightmaps; i++) + qglDeleteTextures(1, &lightmap_textures[i].num); BZ_Free(lightmap_textures); } if (lightmap) @@ -2949,7 +2622,7 @@ void GLSurf_DeInit(void) numlightmaps=0; } -void GL_ClearVBO(vbo_t *vbo) +void BE_ClearVBO(vbo_t *vbo) { int vboh[7]; int i, j; @@ -2984,14 +2657,15 @@ qboolean GL_BuildVBO(vbo_t *vbo, void *vdata, int vsize, void *edata, int elemen return false; qglGenBuffersARB(2, vbos); - qglBindBufferARB(GL_ARRAY_BUFFER_ARB, vbos[0]); + GL_SelectVBO(vbos[0]); qglBufferDataARB(GL_ARRAY_BUFFER_ARB, vsize, vdata, GL_STATIC_DRAW_ARB); - qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vbos[1]); + GL_SelectEBO(vbos[1]); qglBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, elementsize, edata, GL_STATIC_DRAW_ARB); - qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + if (qglGetError()) { + GL_SelectVBO(0); + GL_SelectEBO(0); qglDeleteBuffersARB(2, vbos); return false; } @@ -3006,7 +2680,7 @@ qboolean GL_BuildVBO(vbo_t *vbo, void *vdata, int vsize, void *edata, int elemen if (vbo->coord) { vbo->vbocoord = vbos[0]; - vbo->coord = (vec3_t*)((char*)vbo->coord - (char*)vdata); + vbo->coord = (vecV_t*)((char*)vbo->coord - (char*)vdata); } if (vbo->texcoord) { @@ -3033,6 +2707,12 @@ qboolean GL_BuildVBO(vbo_t *vbo, void *vdata, int vsize, void *edata, int elemen vbo->vbotvector = vbos[0]; vbo->tvector = (vec3_t*)((char*)vbo->tvector - (char*)vdata); } + if (vbo->colours4f) + { + vbo->vbocolours = vbos[0]; + vbo->colours4f = (vec4_t*)((char*)vbo->colours4f - (char*)vdata); + } + return true; } @@ -3046,6 +2726,7 @@ static void GL_GenBrushModelVBO(model_t *mod) unsigned int v; unsigned int vcount, ecount; unsigned int pervertsize; //erm, that name wasn't intentional + unsigned int meshes; vbo_t *vbo; char *vboedata; @@ -3060,10 +2741,11 @@ static void GL_GenBrushModelVBO(model_t *mod) if (!mod->textures[t]) continue; vbo = &mod->textures[t]->vbo; - GL_ClearVBO(vbo); + BE_ClearVBO(vbo); maxvboverts = 0; maxvboelements = 0; + meshes = 0; for (i=0 ; inumsurfaces ; i++) { if (mod->surfaces[i].texinfo->texture != mod->textures[t]) @@ -3072,6 +2754,7 @@ static void GL_GenBrushModelVBO(model_t *mod) if (!m) continue; + meshes++; maxvboelements += m->numindexes; maxvboverts += m->numvertexes; } @@ -3084,24 +2767,31 @@ static void GL_GenBrushModelVBO(model_t *mod) vcount = 0; ecount = 0; - pervertsize = sizeof(vec3_t)+ //cord + pervertsize = sizeof(vecV_t)+ //coord sizeof(vec2_t)+ //tex sizeof(vec2_t)+ //lm sizeof(vec3_t)+ //normal sizeof(vec3_t)+ //sdir - sizeof(vec3_t); //tdir + sizeof(vec3_t)+ //tdir + sizeof(vec4_t); //colours vbovdata = BZ_Malloc(maxvboverts*pervertsize); vboedata = BZ_Malloc(maxvboelements*sizeof(index_t)); - vbo->coord = (vec3_t*)(vbovdata); + vbo->coord = (vecV_t*)(vbovdata); vbo->texcoord = (vec2_t*)((char*)vbo->coord+maxvboverts*sizeof(*vbo->coord)); vbo->lmcoord = (vec2_t*)((char*)vbo->texcoord+maxvboverts*sizeof(*vbo->texcoord)); vbo->normals = (vec3_t*)((char*)vbo->lmcoord+maxvboverts*sizeof(*vbo->lmcoord)); vbo->svector = (vec3_t*)((char*)vbo->normals+maxvboverts*sizeof(*vbo->normals)); vbo->tvector = (vec3_t*)((char*)vbo->svector+maxvboverts*sizeof(*vbo->svector)); + vbo->colours4f = (vec4_t*)((char*)vbo->tvector+maxvboverts*sizeof(*vbo->tvector)); vbo->indicies = (index_t*)vboedata; + vbo->meshcount = meshes; + vbo->meshlist = BZ_Malloc(meshes*sizeof(*vbo->meshlist)); + + meshes = 0; + for (i=0 ; inumsurfaces ; i++) { if (mod->surfaces[i].texinfo->texture != mod->textures[t]) @@ -3110,6 +2800,9 @@ static void GL_GenBrushModelVBO(model_t *mod) if (!m) continue; + mod->surfaces[i].mark = &vbo->meshlist[meshes++]; + *mod->surfaces[i].mark = NULL; + m->vbofirstvert = vcount; m->vbofirstelement = ecount; for (v = 0; v < m->numindexes; v++) @@ -3147,6 +2840,13 @@ static void GL_GenBrushModelVBO(model_t *mod) vbo->tvector[vcount+v][1] = m->tnormals_array[v][1]; vbo->tvector[vcount+v][2] = m->tnormals_array[v][2]; } + if (m->colors4f_array) + { + vbo->colours4f[vcount+v][0] = m->colors4f_array[v][0]; + vbo->colours4f[vcount+v][1] = m->colors4f_array[v][1]; + vbo->colours4f[vcount+v][2] = m->colors4f_array[v][2]; + vbo->colours4f[vcount+v][3] = m->colors4f_array[v][3]; + } } vcount += v; } @@ -3157,6 +2857,11 @@ static void GL_GenBrushModelVBO(model_t *mod) BZ_Free(vboedata); } } + for (i=0 ; inumsurfaces ; i++) + { + if (!mod->surfaces[i].mark) + Host_EndGame("Surfaces with bad textures detected\n"); + } } /* @@ -3292,13 +2997,13 @@ void GL_BuildLightmaps (void) continue; lightmap[i]->modified = false; GL_Bind(lightmap_textures[i]); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); qglTexImage2D (GL_TEXTURE_2D, 0, lightmap_bytes , LMBLOCK_WIDTH, LMBLOCK_HEIGHT, 0, gl_lightmap_format, GL_UNSIGNED_BYTE, lightmap[i]->lightmaps); - if (gl_bump.value) + if (gl_bump.ival) { lightmap[i]->deluxmodified = false; lightmap[i]->deluxrectchange.l = LMBLOCK_WIDTH; @@ -3306,8 +3011,8 @@ void GL_BuildLightmaps (void) lightmap[i]->deluxrectchange.w = 0; lightmap[i]->deluxrectchange.h = 0; GL_Bind(deluxmap_textures[i]); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); qglTexImage2D (GL_TEXTURE_2D, 0, 3 , LMBLOCK_WIDTH, LMBLOCK_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, lightmap[i]->deluxmaps); diff --git a/engine/gl/gl_screen.c b/engine/gl/gl_screen.c index b1dfde78..6832bc1f 100644 --- a/engine/gl/gl_screen.c +++ b/engine/gl/gl_screen.c @@ -21,8 +21,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // screen.c -- master for refresh, status bar, console, chat, notify, etc #include "quakedef.h" -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h" +#include "shader.h" #include @@ -41,15 +42,13 @@ extern qboolean scr_drawloading; extern int scr_chatmode; extern cvar_t scr_chatmodecvar; extern cvar_t vid_conautoscale; +extern qboolean scr_con_forcedraw; // console size manipulation callbacks void GLVID_Console_Resize(void) { -#ifdef AVAIL_FREETYPE - extern struct font_s *conchar_font; extern cvar_t gl_font; -#endif extern cvar_t vid_conwidth, vid_conheight; int cwidth, cheight; float xratio; @@ -71,8 +70,8 @@ void GLVID_Console_Resize(void) yratio = 1 / yratio; //autoscale overrides conwidth/height (without actually changing them) - cwidth = glwidth; - cheight = glheight; + cwidth = vid.pixelwidth; + cheight = vid.pixelheight; } else { @@ -82,9 +81,9 @@ void GLVID_Console_Resize(void) if (!cwidth) - cwidth = glwidth; + cwidth = vid.pixelwidth; if (!cheight) - cheight = glheight; + cheight = vid.pixelheight; cwidth*=xratio; cheight*=yratio; @@ -100,11 +99,11 @@ void GLVID_Console_Resize(void) vid.recalc_refdef = true; Con_CheckResize(); -#ifdef AVAIL_FREETYPE - if (conchar_font) - Font_Free(conchar_font); - conchar_font = Font_LoadFont(8*glheight/vid.height, gl_font.string); -#endif + if (font_conchar) + Font_Free(font_conchar); + font_conchar = Font_LoadFont(8*vid.pixelheight/vid.height, gl_font.string); + if (!font_conchar && *gl_font.string) + font_conchar = Font_LoadFont(8*vid.pixelheight/vid.height, ""); #ifdef PLUGINS Plug_ResChanged(); @@ -183,7 +182,7 @@ void GLSCR_UpdateScreen (void) } else { - GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + GL_BeginRendering (); scr_drawloading = true; SCR_DrawLoading (); scr_drawloading = false; @@ -200,23 +199,21 @@ void GLSCR_UpdateScreen (void) return; // not initialized yet } - qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); - #ifdef VM_UI uimenu = UI_MenuState(); #else uimenu = 0; #endif - GL_BeginRendering (&glx, &gly, &glwidth, &glheight); + GL_BeginRendering (); + Shader_DoReload(); #ifdef TEXTEDITOR if (editormodal) { Editor_Draw(); GLV_UpdatePalette (false, host_frametime); -#if defined(_WIN32) && defined(RGLQUAKE) +#if defined(_WIN32) && defined(GLQUAKE) Media_RecordFrame(); #endif GLR_BrightenScreen(); @@ -233,7 +230,7 @@ void GLSCR_UpdateScreen (void) { M_Draw(0); GLV_UpdatePalette (false, host_frametime); -#if defined(_WIN32) && defined(RGLQUAKE) +#if defined(_WIN32) && defined(GLQUAKE) Media_RecordFrame(); #endif GLR_BrightenScreen(); @@ -281,8 +278,10 @@ void GLSCR_UpdateScreen (void) GL_Set2D (); + R_PolyBlend (); GLR_BrightenScreen(); + scr_con_forcedraw = false; if (noworld) { extern char levelshotname[]; @@ -295,11 +294,13 @@ void GLSCR_UpdateScreen (void) { if(Draw_ScalePic) Draw_ScalePic(0, 0, vid.width, vid.height, Draw_SafeCachePic (levelshotname)); - else + else if (scr_con_current != vid.height) Draw_ConsoleBackground(0, vid.height, true); } - else + else if (scr_con_current != vid.height) Draw_ConsoleBackground(0, vid.height, true); + else + scr_con_forcedraw = true; nohud = true; } @@ -309,7 +310,7 @@ void GLSCR_UpdateScreen (void) SCR_DrawTwoDimensional(uimenu, nohud); GLV_UpdatePalette (false, host_frametime); -#if defined(_WIN32) && defined(RGLQUAKE) +#if defined(_WIN32) && defined(GLQUAKE) Media_RecordFrame(); #endif @@ -324,16 +325,16 @@ char *GLVID_GetRGBInfo(int prepadbytes, int *truewidth, int *trueheight) { //returns a BZ_Malloced array extern qboolean gammaworks; int i, c; - qbyte *ret = BZ_Malloc(prepadbytes + glwidth*glheight*3); + qbyte *ret = BZ_Malloc(prepadbytes + vid.pixelwidth*vid.pixelheight*3); - qglReadPixels (glx, gly, glwidth, glheight, GL_RGB, GL_UNSIGNED_BYTE, ret + prepadbytes); + qglReadPixels (0, 0, vid.pixelwidth, vid.pixelheight, GL_RGB, GL_UNSIGNED_BYTE, ret + prepadbytes); - *truewidth = glwidth; - *trueheight = glheight; + *truewidth = vid.pixelwidth; + *trueheight = vid.pixelheight; if (gammaworks) { - c = prepadbytes+glwidth*glheight*3; + c = prepadbytes+vid.pixelwidth*vid.pixelheight*3; for (i=prepadbytes ; i -extern int missing_texture; - - - -//Spike: Marked code removal areas with FIZME -//readd as porting progresses - - -#ifdef Q3SHADERS +extern texid_t missing_texture; +static qboolean shader_reload_needed; +//cvars that affect shader generation cvar_t r_vertexlight = SCVAR("r_vertexlight", "0"); +extern cvar_t r_fastsky, r_skyboxname; +extern cvar_t r_drawflat; + +//backend fills this in to say the max pass count +int be_maxpasses; + #define Q_stricmp stricmp #define Com_sprintf snprintf @@ -89,7 +90,7 @@ char *COM_ParseExt (char **data_p, qboolean nl) // skip whitespace skipwhite: - while ( (c = *data) <= ' ') + while ((c = *data) <= ' ') { if (c == 0) { @@ -101,7 +102,8 @@ skipwhite: data++; } - if ( newlines && !nl ) { + if (newlines && !nl) + { *data_p = data; return com_token; } @@ -194,6 +196,7 @@ static qboolean Shader_Parsetok( shader_t *shader, shaderpass_t *pass, shaderkey static void Shader_ParseFunc( char **args, shaderfunc_t *func ); static void Shader_MakeCache( char *path ); static void Shader_GetPathAndOffset( char *name, char **path, unsigned int *offset ); +static void Shader_ReadShader(shader_t *s, char *shadersource); //=========================================================================== @@ -228,10 +231,25 @@ static float Shader_ParseFloat ( char **ptr ) static void Shader_ParseVector ( char **ptr, vec3_t v ) { + char *scratch; char *token; qboolean bracket; token = Shader_ParseString ( ptr ); + if (*token == '$') + { + cvar_t *var; + var = Cvar_FindVar(token+1); + if (!var) + { + v[0] = 1; + v[1] = 1; + v[2] = 1; + return; + } + ptr = &scratch; + scratch = var->string; + } if ( !Q_stricmp (token, "(") ) { bracket = true; token = Shader_ParseString ( ptr ); @@ -257,24 +275,61 @@ static void Shader_ParseVector ( char **ptr, vec3_t v ) Shader_ParseString ( ptr ); } } + + if (v[0] > 5 || v[1] > 5 || v[2] > 5) + { + VectorScale(v, 1.0f/255, v); + } } -static void Shader_ParseSkySides ( shader_t *shader, char **ptr, int *images ) +static void Shader_ParseSkySides ( shader_t *shader, char **ptr, texid_t *images ) { - int i; + int i, ss, sp; char *token; char path[MAX_QPATH]; - static char *suf[6] = { "rt", "bk", "lf", "ft", "up", "dn" }; + + static char *skyname_suffix[][6] = { + {"rt", "bk", "lf", "ft", "up", "dn"}, + {"px", "py", "nx", "ny", "pz", "nz"}, + {"posx", "posy", "negx", "negy", "posz", "negz"}, + {"_px", "_py", "_nx", "_ny", "_pz", "_nz"}, + {"_posx", "_posy", "_negx", "_negy", "_posz", "_negz"}, + {"_rt", "_bk", "_lf", "_ft", "_up", "_dn"} + }; + + static char *skyname_pattern[] = { + "%s_%s", + "%s%s", + "env/%s%s", + "gfx/env/%s%s" + }; token = Shader_ParseString ( ptr ); + if (*token == '$') + { + cvar_t *v; + v = Cvar_FindVar(token+1); + if (v) + token = v->string; + } for ( i = 0; i < 6; i++ ) { if ( token[0] == '-' ) { - images[i] = 0; + images[i] = r_nulltex; } else { - Com_sprintf ( path, sizeof(path), "%s_%s", token, suf[i] ); - images[i] = Mod_LoadHiResTexture ( path, NULL, true, false, true);//|IT_SKY ); - if (!images[i]) + for (sp = 0; sp < sizeof(skyname_pattern)/sizeof(skyname_pattern[0]); sp++) + { + for (ss = 0; ss < sizeof(skyname_suffix)/sizeof(skyname_suffix[0]); ss++) + { + Com_sprintf ( path, sizeof(path), skyname_pattern[sp], token, skyname_suffix[ss][i] ); + images[i] = R_LoadHiResTexture ( path, NULL, IF_NOALPHA); + if (TEXVALID(images[i])) + break; + } + if (TEXVALID(images[i])) + break; + } + if (!TEXVALID(images[i])) { Con_Printf("Shader \"%s\" missing texture: %s\n", shader->name, path); images[i] = missing_texture; @@ -310,37 +365,26 @@ static void Shader_ParseFunc ( char **ptr, shaderfunc_t *func ) //=========================================================================== - -enum { - IT_CLAMP = 1<<0, - IT_SKY = 1<<1, - IT_NOMIPMAP = 1<<2, - IT_NOPICMIP = 1<<3 -}; static int Shader_SetImageFlags ( shader_t *shader ) { int flags = 0; - if ( shader->flags & SHADER_SKY ) { - flags |= IT_SKY; - } - if ( shader->flags & SHADER_NOMIPMAPS ) { - flags |= IT_NOMIPMAP; - } - if ( shader->flags & SHADER_NOPICMIP ) { - flags |= IT_NOPICMIP; - } +// if (shader->flags & SHADER_SKY) +// flags |= IF_SKY; + if (shader->flags & SHADER_NOMIPMAPS) + flags |= IF_NOMIPMAP; + if (shader->flags & SHADER_NOPICMIP) + flags |= IF_NOPICMIP; return flags; } -static int Shader_FindImage ( char *name, int flags ) +static texid_t Shader_FindImage ( char *name, int flags ) { - if ( !Q_stricmp (name, "$whiteimage") ) { - return 0; - } else { - return Mod_LoadHiResTexture(name, NULL, !(flags & IT_NOMIPMAP), true, true);//GL_FindImage ( name, flags ); - } + if (!Q_stricmp (name, "$whiteimage")) + return r_nulltex; + else + return R_LoadHiResTexture(name, NULL, flags); } @@ -429,7 +473,8 @@ static void Shader_SkyParms ( shader_t *shader, shaderpass_t *pass, char **ptr ) skydome_t *skydome; float skyheight; - if ( shader->skydome ) { + if (shader->skydome) + { for ( i = 0; i < 5; i++ ) { Z_Free ( shader->skydome->meshes[i].xyz_array ); Z_Free ( shader->skydome->meshes[i].normals_array ); @@ -451,8 +496,6 @@ static void Shader_SkyParms ( shader_t *shader, shaderpass_t *pass, char **ptr ) Shader_ParseSkySides ( shader, ptr, skydome->nearbox_textures ); -// R_CreateSkydome ( shader, skyheight ); - shader->flags |= SHADER_SKY; shader->sort = SHADER_SORT_SKY; } @@ -490,6 +533,8 @@ static void Shader_SurfaceParm ( shader_t *shader, shaderpass_t *pass, char **pt token = Shader_ParseString ( ptr ); if ( !Q_stricmp( token, "nodraw" ) ) shader->flags = SHADER_NODRAW; + else if ( !Q_stricmp( token, "nodlight" ) ) + shader->flags = SHADER_NODLIGHT; } static void Shader_Sort ( shader_t *shader, shaderpass_t *pass, char **ptr ) @@ -524,7 +569,9 @@ static void Shader_Portal ( shader_t *shader, shaderpass_t *pass, char **ptr ) static void Shader_PolygonOffset ( shader_t *shader, shaderpass_t *pass, char **ptr ) { - shader->flags |= SHADER_POLYGONOFFSET; + /*the q3 defaults*/ + shader->polyoffset.factor = -0.05; + shader->polyoffset.unit = -25; } static void Shader_EntityMergable ( shader_t *shader, shaderpass_t *pass, char **ptr ) @@ -532,11 +579,11 @@ static void Shader_EntityMergable ( shader_t *shader, shaderpass_t *pass, char * shader->flags |= SHADER_ENTITY_MERGABLE; } -static void Shader_ProgramName ( shader_t *shader, shaderpass_t *pass, char **ptr ) +static void Shader_SLProgramName (shader_t *shader, shaderpass_t *pass, char **ptr, int qrtype) { void *vert, *frag; char *token; - if (shader->programhandle) + if (shader->programhandle.glsl) { //this allows fallbacks token = Shader_ParseString ( ptr ); token = Shader_ParseString ( ptr ); @@ -572,10 +619,20 @@ static void Shader_ProgramName ( shader_t *shader, shaderpass_t *pass, char **pt else if (*token == '{') count++; } - *token = 0; + frag = BZ_Malloc(token - (char*)vert + 1); + memcpy(frag, vert, token-(char*)vert); + ((char*)frag)[token-(char*)vert] = 0; + vert = frag; *ptr = token+1; - shader->programhandle = GLSlang_CreateProgram("", (char *)vert, (char *)frag); + if (qrenderer != qrtype) + { + } +#ifdef GLQUAKE + else if (qrenderer == QR_OPENGL) + shader->programhandle.glsl = GLSlang_CreateProgram("", (char *)vert, (char *)frag); +#endif + BZ_Free(vert); frag = NULL; vert = NULL; @@ -590,8 +647,13 @@ static void Shader_ProgramName ( shader_t *shader, shaderpass_t *pass, char **pt else FS_LoadFile(token, &frag); - if (vert && frag) - shader->programhandle = GLSlang_CreateProgram("", (char *)vert, (char *)frag); + if (qrenderer != qrtype) + { + } +#ifdef GLQUAKE + else if (vert && frag) + shader->programhandle.glsl = GLSlang_CreateProgram("", (char *)vert, (char *)frag); +#endif if (vert) { if (frag == vert) @@ -602,6 +664,15 @@ static void Shader_ProgramName ( shader_t *shader, shaderpass_t *pass, char **pt FS_FreeFile(frag); } +static void Shader_GLSLProgramName (shader_t *shader, shaderpass_t *pass, char **ptr) +{ + Shader_SLProgramName(shader,pass,ptr,QR_OPENGL); +} +static void Shader_HLSLProgramName (shader_t *shader, shaderpass_t *pass, char **ptr) +{ + Shader_SLProgramName(shader,pass,ptr,QR_DIRECT3D); +} + static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **ptr ) { cvar_t *cv; @@ -609,18 +680,23 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p float specialfloat = 0; enum shaderprogparmtype_e parmtype = SP_BAD; char *token; - unsigned int uniformloc; + qboolean silent = false; - token = Shader_ParseString ( ptr ); + token = Shader_ParseString(ptr); + if (!Q_stricmp(token, "opt")) + { + silent = true; + token = Shader_ParseString(ptr); + } if (!Q_stricmp(token, "texture")) { - token = Shader_ParseString ( ptr ); + token = Shader_ParseString(ptr); specialint = atoi(token); parmtype = SP_TEXTURE; } else if (!Q_stricmp(token, "cvari")) { - token = Shader_ParseString ( ptr ); + token = Shader_ParseString(ptr); cv = Cvar_Get(token, "", 0, "GLSL Shader parameters"); if (cv) { //Cvar_Get returns null if the cvar is the name of a command @@ -631,7 +707,7 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p } else if (!Q_stricmp(token, "cvarf")) { - token = Shader_ParseString ( ptr ); + token = Shader_ParseString(ptr); cv = Cvar_Get(token, "", 0, "GLSL Shader parameters"); if (cv) { //Cvar_Get returns null if the cvar is the name of a command @@ -641,17 +717,13 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p parmtype = SP_CVARF; } else if (!Q_stricmp(token, "time")) - { parmtype = SP_TIME; - } else if (!Q_stricmp(token, "eyepos")) - { parmtype = SP_EYEPOS; - } + else if (!Q_stricmp(token, "entmatrix")) + parmtype = SP_ENTMATRIX; else if (!Q_stricmp(token, "colours") || !Q_stricmp(token, "colors")) - { parmtype = SP_ENTCOLOURS; - } else if (!Q_stricmp(token, "upper")) parmtype = SP_TOPCOLOURS; else if (!Q_stricmp(token, "lower")) @@ -665,236 +737,309 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p else Con_Printf("shader %s: parameter type \"%s\" not known\n", shader->name, token); - if (!shader->programhandle) - { - Con_Printf("shader %s: param without program set\n", shader->name); - token = Shader_ParseString ( ptr ); - } - else - { - GLSlang_UseProgram(shader->programhandle); + token = Shader_ParseString(ptr); - token = Shader_ParseString ( ptr ); - uniformloc = GLSlang_GetUniformLocation(shader->programhandle, token); - - if (uniformloc == -1) +#ifdef GLQUAKE + if (qrenderer == QR_OPENGL) + { + unsigned int uniformloc; + if (!shader->programhandle.glsl) { - Con_Printf("shader %s: param without uniform \"%s\"\n", shader->name, token); + Con_Printf("shader %s: param without program set\n", shader->name); } else { - switch(parmtype) + GLSlang_UseProgram(shader->programhandle.glsl); + uniformloc = qglGetUniformLocationARB(shader->programhandle.glsl, token); + if (uniformloc == -1) { - case SP_BAD: - break; - case SP_TEXTURE: - case SP_CVARI: - GLSlang_SetUniform1i(uniformloc, specialint); - break; - case SP_CVARF: - GLSlang_SetUniform1f(uniformloc, specialfloat); - break; - default: - shader->progparm[shader->numprogparams].type = parmtype; - shader->progparm[shader->numprogparams].handle = uniformloc; - shader->numprogparams++; - break; + if (!silent) + Con_Printf("shader %s: param without uniform \"%s\"\n", shader->name, token); } + else + { + switch(parmtype) + { + case SP_BAD: + break; + case SP_TEXTURE: + case SP_CVARI: + GLSlang_SetUniform1i(uniformloc, specialint); + break; + case SP_CVARF: + GLSlang_SetUniform1f(uniformloc, specialfloat); + break; + default: + shader->progparm[shader->numprogparams].type = parmtype; + shader->progparm[shader->numprogparams].handle = uniformloc; + shader->numprogparams++; + break; + } + } + GLSlang_UseProgram(0); } - GLSlang_UseProgram(0); } +#endif } static shaderkey_t shaderkeys[] = { - {"cull", Shader_Cull }, - {"skyparms", Shader_SkyParms }, - {"fogparms", Shader_FogParms }, - {"surfaceparm", Shader_SurfaceParm }, - {"nomipmaps", Shader_NoMipMaps }, - {"nopicmip", Shader_NoPicMip }, - {"polygonoffset", Shader_PolygonOffset }, - {"sort", Shader_Sort }, - {"deformvertexes", Shader_DeformVertexes }, - {"portal", Shader_Portal }, - {"entitymergable", Shader_EntityMergable }, + {"cull", Shader_Cull}, + {"skyparms", Shader_SkyParms}, + {"fogparms", Shader_FogParms}, + {"surfaceparm", Shader_SurfaceParm}, + {"nomipmaps", Shader_NoMipMaps}, + {"nopicmip", Shader_NoPicMip}, + {"polygonoffset", Shader_PolygonOffset}, + {"sort", Shader_Sort}, + {"deformvertexes", Shader_DeformVertexes}, + {"portal", Shader_Portal}, + {"entitymergable", Shader_EntityMergable}, - {"program", Shader_ProgramName }, //glsl - {"param", Shader_ProgramParam }, + {"glslprogram", Shader_GLSLProgramName}, + {"program", Shader_GLSLProgramName}, //legacy + {"hlslprogram", Shader_HLSLProgramName}, //for d3d + {"param", Shader_ProgramParam}, {NULL, NULL} }; // =============================================================== -static void Shaderpass_Map ( shader_t *shader, shaderpass_t *pass, char **ptr ) +static void Shaderpass_Map (shader_t *shader, shaderpass_t *pass, char **ptr) { int flags; char *token; - token = Shader_ParseString ( ptr ); - if ( !Q_stricmp (token, "$lightmap") ) + pass->anim_frames[0] = r_nulltex; + + token = Shader_ParseString (ptr); + if (!Q_stricmp (token, "$lightmap")) { pass->tcgen = TC_GEN_LIGHTMAP; pass->flags |= SHADER_PASS_LIGHTMAP; - pass->anim_frames[0] = 0; + pass->texgen = T_GEN_LIGHTMAP; + shader->flags |= SHADER_HASLIGHTMAP; } - else if ( !Q_stricmp (token, "$deluxmap") ) + else if (!Q_stricmp (token, "$deluxmap")) { pass->tcgen = TC_GEN_LIGHTMAP; pass->flags |= SHADER_PASS_DELUXMAP; - pass->anim_frames[0] = 0; + pass->texgen = T_GEN_DELUXMAP; + } + else if (!Q_stricmp (token, "$diffuse")) + { + pass->texgen = T_GEN_DIFFUSE; + pass->tcgen = TC_GEN_BASE; + } + else if (!Q_stricmp (token, "$normalmap")) + { + pass->texgen = T_GEN_NORMALMAP; + pass->tcgen = TC_GEN_BASE; + } + else if (!Q_stricmp (token, "$specular")) + { + pass->texgen = T_GEN_SPECULAR; + pass->tcgen = TC_GEN_BASE; + } + else if (!Q_stricmp (token, "$fullbright")) + { + pass->texgen = T_GEN_FULLBRIGHT; + pass->tcgen = TC_GEN_BASE; + } + else if (!Q_stricmp (token, "$upperoverlay")) + { + pass->texgen = T_GEN_UPPEROVERLAY; + pass->tcgen = TC_GEN_BASE; + } + else if (!Q_stricmp (token, "$loweroverlay")) + { + pass->texgen = T_GEN_LOWEROVERLAY; + pass->tcgen = TC_GEN_BASE; + } + else if (!Q_stricmp (token, "$shadowmap")) + { + pass->texgen = T_GEN_SHADOWMAP; + pass->tcgen = TC_GEN_BASE; //FIXME: moo! + } + else if (!Q_stricmp (token, "$currentrender")) + { + pass->texgen = T_GEN_CURRENTRENDER; + pass->tcgen = TC_GEN_BASE; //FIXME: moo! } else { - flags = Shader_SetImageFlags ( shader ); + flags = Shader_SetImageFlags (shader); pass->tcgen = TC_GEN_BASE; - pass->anim_frames[0] = Shader_FindImage ( token, flags ); + pass->anim_frames[0] = Shader_FindImage (token, flags); - if ( !pass->anim_frames[0] ) { + /* + if (!pass->anim_frames[0]) + { pass->anim_frames[0] = missing_texture; Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", shader->name, token ); } + */ } } -static void Shaderpass_AnimMap ( shader_t *shader, shaderpass_t *pass, char **ptr ) +static void Shaderpass_AnimMap (shader_t *shader, shaderpass_t *pass, char **ptr) { int flags; char *token; - int image; + texid_t image; - flags = Shader_SetImageFlags ( shader ); + flags = Shader_SetImageFlags (shader); pass->tcgen = TC_GEN_BASE; pass->flags |= SHADER_PASS_ANIMMAP; - pass->anim_fps = (int)Shader_ParseFloat ( ptr ); + pass->texgen = T_GEN_ANIMMAP; + pass->anim_fps = (int)Shader_ParseFloat (ptr); pass->anim_numframes = 0; - for ( ; ; ) { - token = Shader_ParseString ( ptr ); - if ( !token[0] ) { + for ( ; ; ) + { + token = Shader_ParseString(ptr); + if (!token[0]) + { break; } - if ( pass->anim_numframes < SHADER_ANIM_FRAMES_MAX ) { - image = Shader_FindImage ( token, flags ); + if (pass->anim_numframes < SHADER_ANIM_FRAMES_MAX) + { + image = Shader_FindImage (token, flags); - if ( !image ) { + if (!TEXVALID(image)) + { pass->anim_frames[pass->anim_numframes++] = missing_texture; Con_DPrintf (CON_WARNING "Shader %s has an animmap with no image: %s.\n", shader->name, token ); - } else { + } + else + { pass->anim_frames[pass->anim_numframes++] = image; } } } } -static void Shaderpass_ClampMap ( shader_t *shader, shaderpass_t *pass, char **ptr ) +static void Shaderpass_ClampMap (shader_t *shader, shaderpass_t *pass, char **ptr) { int flags; char *token; - token = Shader_ParseString ( ptr ); - flags = Shader_SetImageFlags ( shader ); + token = Shader_ParseString (ptr); + flags = Shader_SetImageFlags (shader); pass->tcgen = TC_GEN_BASE; - pass->anim_frames[0] = Shader_FindImage ( token, flags | IT_CLAMP ); + pass->anim_frames[0] = Shader_FindImage (token, flags | IF_CLAMP); + pass->texgen = T_GEN_SINGLEMAP; - qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - - if ( !pass->anim_frames[0] ) { + if (!TEXVALID(pass->anim_frames[0])) + { pass->anim_frames[0] = missing_texture; - Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", shader->name, token ); + Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", shader->name, token); } } -static void Shaderpass_VideoMap ( shader_t *shader, shaderpass_t *pass, char **ptr ) +static void Shaderpass_VideoMap (shader_t *shader, shaderpass_t *pass, char **ptr) { char *token; - token = Shader_ParseString ( ptr ); + token = Shader_ParseString (ptr); - if ( pass->cin ) - Z_Free ( pass->cin ); +#ifdef NOMEDIA +#else + if (pass->cin) + Z_Free (pass->cin); pass->cin = Media_StartCin(token); if (!pass->cin) pass->cin = Media_StartCin(va("video/%s.roq", token)); else - Con_DPrintf (CON_WARNING "(shader %s) Couldn't load video %s\n", shader->name, token ); + Con_DPrintf (CON_WARNING "(shader %s) Couldn't load video %s\n", shader->name, token); - pass->anim_frames[0] = GL_AllocNewTexture(); pass->flags |= SHADER_PASS_VIDEOMAP; shader->flags |= SHADER_VIDEOMAP; + pass->texgen = T_GEN_VIDEOMAP; +#endif } -static void Shaderpass_RGBGen ( shader_t *shader, shaderpass_t *pass, char **ptr ) +static void Shaderpass_RGBGen (shader_t *shader, shaderpass_t *pass, char **ptr) { char *token; - token = Shader_ParseString ( ptr ); - if ( !Q_stricmp (token, "identitylighting") ) + token = Shader_ParseString (ptr); + if (!Q_stricmp (token, "identitylighting")) pass->rgbgen = RGB_GEN_IDENTITY_LIGHTING; - else if ( !Q_stricmp (token, "identity") ) + else if (!Q_stricmp (token, "identity")) pass->rgbgen = RGB_GEN_IDENTITY; - else if ( !Q_stricmp (token, "wave") ) + else if (!Q_stricmp (token, "wave")) { pass->rgbgen = RGB_GEN_WAVE; - Shader_ParseFunc ( ptr, &pass->rgbgen_func ); + Shader_ParseFunc ( ptr, &pass->rgbgen_func); } - else if ( !Q_stricmp(token, "entity") ) + else if (!Q_stricmp(token, "entity")) pass->rgbgen = RGB_GEN_ENTITY; - else if ( !Q_stricmp (token, "oneMinusEntity") ) + else if (!Q_stricmp (token, "oneMinusEntity")) pass->rgbgen = RGB_GEN_ONE_MINUS_ENTITY; - else if ( !Q_stricmp (token, "vertex")) + else if (!Q_stricmp (token, "vertex")) pass->rgbgen = RGB_GEN_VERTEX; - else if ( !Q_stricmp (token, "oneMinusVertex") ) + else if (!Q_stricmp (token, "oneMinusVertex")) pass->rgbgen = RGB_GEN_ONE_MINUS_VERTEX; - else if ( !Q_stricmp (token, "lightingDiffuse") ) + else if (!Q_stricmp (token, "lightingDiffuse")) pass->rgbgen = RGB_GEN_LIGHTING_DIFFUSE; - else if ( !Q_stricmp (token, "exactvertex") ) + else if (!Q_stricmp (token, "exactvertex")) pass->rgbgen = RGB_GEN_EXACT_VERTEX; - else if ( !Q_stricmp (token, "const") || !Q_stricmp (token, "constant") ) + else if (!Q_stricmp (token, "const") || !Q_stricmp (token, "constant")) { pass->rgbgen = RGB_GEN_CONST; pass->rgbgen_func.type = SHADER_FUNC_CONSTANT; - Shader_ParseVector ( ptr, pass->rgbgen_func.args ); + Shader_ParseVector (ptr, pass->rgbgen_func.args); } - else if ( !Q_stricmp (token, "topcolor") ) + else if (!Q_stricmp (token, "topcolor")) pass->rgbgen = RGB_GEN_TOPCOLOR; - else if ( !Q_stricmp (token, "bottomcolor") ) + else if (!Q_stricmp (token, "bottomcolor")) pass->rgbgen = RGB_GEN_BOTTOMCOLOR; } -static void Shaderpass_AlphaGen ( shader_t *shader, shaderpass_t *pass, char **ptr ) +static void Shaderpass_AlphaGen (shader_t *shader, shaderpass_t *pass, char **ptr) { char *token; - token = Shader_ParseString ( ptr ); - if ( !Q_stricmp (token, "portal") ) { + token = Shader_ParseString(ptr); + if (!Q_stricmp (token, "portal")) + { pass->alphagen = ALPHA_GEN_PORTAL; shader->flags |= SHADER_AGEN_PORTAL; - } else if ( !Q_stricmp (token, "vertex") ) { + } + else if (!Q_stricmp (token, "vertex")) + { pass->alphagen = ALPHA_GEN_VERTEX; - } else if ( !Q_stricmp (token, "entity") ) { + } + else if (!Q_stricmp (token, "entity")) + { pass->alphagen = ALPHA_GEN_ENTITY; - } else if ( !Q_stricmp (token, "wave") ) { + } + else if (!Q_stricmp (token, "wave")) + { pass->alphagen = ALPHA_GEN_WAVE; - Shader_ParseFunc ( ptr, &pass->alphagen_func ); - } else if ( !Q_stricmp (token, "lightingspecular") ) { + Shader_ParseFunc (ptr, &pass->alphagen_func); + } + else if ( !Q_stricmp (token, "lightingspecular")) + { pass->alphagen = ALPHA_GEN_SPECULAR; - } else if ( !Q_stricmp (token, "const") || !Q_stricmp (token, "constant") ) { + } + else if ( !Q_stricmp (token, "const") || !Q_stricmp (token, "constant")) + { pass->alphagen = ALPHA_GEN_CONST; pass->alphagen_func.type = SHADER_FUNC_CONSTANT; - pass->alphagen_func.args[0] = fabs( Shader_ParseFloat (ptr) ); + pass->alphagen_func.args[0] = fabs(Shader_ParseFloat(ptr)); } } -static void Shaderpass_AlphaShift ( shader_t *shader, shaderpass_t *pass, char **ptr ) //for alienarena +static void Shaderpass_AlphaShift (shader_t *shader, shaderpass_t *pass, char **ptr) //for alienarena { float speed; float min, max; @@ -908,9 +1053,9 @@ static void Shaderpass_AlphaShift ( shader_t *shader, shaderpass_t *pass, char * //arg2 = timeshift //arg3 = timescale - speed = Shader_ParseFloat ( ptr ); - min = Shader_ParseFloat ( ptr ); - max = Shader_ParseFloat ( ptr ); + speed = Shader_ParseFloat(ptr); + min = Shader_ParseFloat(ptr); + max = Shader_ParseFloat(ptr); pass->alphagen_func.args[0] = min + (max - min)/2; pass->alphagen_func.args[1] = (max - min)/2; @@ -918,142 +1063,198 @@ static void Shaderpass_AlphaShift ( shader_t *shader, shaderpass_t *pass, char * pass->alphagen_func.args[3] = 1/speed; } -static void Shaderpass_BlendFunc ( shader_t *shader, shaderpass_t *pass, char **ptr ) +static int Shader_BlendFactor(char *name, qboolean dstnotsrc) +{ + int factor; + if (!strnicmp(name, "gl_", 3)) + name += 3; + + if (!Q_stricmp(name, "zero")) + factor = SBITS_SRCBLEND_ZERO; + else if ( !Q_stricmp(name, "one")) + factor = SBITS_SRCBLEND_ONE; + else if (!Q_stricmp(name, "dst_color")) + factor = SBITS_SRCBLEND_DST_COLOR; + else if (!Q_stricmp(name, "one_minus_src_alpha")) + factor = SBITS_SRCBLEND_ONE_MINUS_SRC_ALPHA; + else if (!Q_stricmp(name, "src_alpha")) + factor = SBITS_SRCBLEND_SRC_ALPHA; + else if (!Q_stricmp(name, "src_color")) + factor = SBITS_SRCBLEND_SRC_COLOR_INVALID; + else if (!Q_stricmp(name, "one_minus_dst_color")) + factor = SBITS_SRCBLEND_ONE_MINUS_DST_COLOR; + else if (!Q_stricmp(name, "one_minus_src_color")) + factor = SBITS_SRCBLEND_ONE_MINUS_SRC_COLOR_INVALID; + else if (!Q_stricmp(name, "dst_alpha") ) + factor = SBITS_SRCBLEND_DST_ALPHA; + else if (!Q_stricmp(name, "one_minus_dst_alpha")) + factor = SBITS_SRCBLEND_ONE_MINUS_DST_ALPHA; + else + factor = SBITS_SRCBLEND_NONE; + + if (dstnotsrc) + { + //dest factors are shifted + factor <<= 4; + + /*gl doesn't accept dst_color for destinations*/ + if (factor == SBITS_DSTBLEND_NONE || + factor == SBITS_DSTBLEND_DST_COLOR_INVALID || + factor == SBITS_DSTBLEND_ONE_MINUS_DST_COLOR_INVALID || + factor == SBITS_DSTBLEND_ALPHA_SATURATE_INVALID) + { + Con_DPrintf("Invalid shader dst blend \"%s\"\n", name); + factor = SBITS_DSTBLEND_ONE; + } + } + else + { + /*gl doesn't accept src_color for sources*/ + if (factor == SBITS_SRCBLEND_NONE || + factor == SBITS_SRCBLEND_SRC_COLOR_INVALID || + factor == SBITS_SRCBLEND_ONE_MINUS_SRC_COLOR_INVALID) + { + Con_DPrintf("Unrecognised shader src blend \"%s\"\n", name); + factor = SBITS_SRCBLEND_ONE; + } + } + + return factor; +} + +static void Shaderpass_BlendFunc (shader_t *shader, shaderpass_t *pass, char **ptr) { char *token; - token = Shader_ParseString ( ptr ); - if ( !Q_stricmp (token, "blend") ) { - pass->blendsrc = GL_SRC_ALPHA; - pass->blenddst = GL_ONE_MINUS_SRC_ALPHA; - } else if ( !Q_stricmp (token, "filter") ) { - pass->blendsrc = GL_DST_COLOR; - pass->blenddst = GL_ZERO; - } else if ( !Q_stricmp (token, "add") ) { - pass->blendsrc = pass->blenddst = GL_ONE; - } else { - int i; - unsigned int *blend; + pass->shaderbits &= ~(SBITS_BLEND_BITS); - for ( i = 0; i < 2; i++ ) - { - blend = (i == 0) ? &pass->blendsrc : &pass->blenddst; - - if ( !Q_stricmp ( token, "gl_zero") ) - *blend = GL_ZERO; - else if ( !Q_stricmp (token, "gl_one") ) - *blend = GL_ONE; - else if ( !Q_stricmp (token, "gl_dst_color") ) - *blend = GL_DST_COLOR; - else if ( !Q_stricmp (token, "gl_one_minus_src_alpha") ) - *blend = GL_ONE_MINUS_SRC_ALPHA; - else if ( !Q_stricmp (token, "gl_src_alpha") ) - *blend = GL_SRC_ALPHA; - else if ( !Q_stricmp (token, "gl_src_color") ) - *blend = GL_SRC_COLOR; - else if ( !Q_stricmp (token, "gl_one_minus_dst_color") ) - *blend = GL_ONE_MINUS_DST_COLOR; - else if ( !Q_stricmp (token, "gl_one_minus_src_color") ) - *blend = GL_ONE_MINUS_SRC_COLOR; - else if ( !Q_stricmp (token, "gl_dst_alpha") ) - *blend = GL_DST_ALPHA; - else if ( !Q_stricmp (token, "gl_one_minus_dst_alpha") ) - *blend = GL_ONE_MINUS_DST_ALPHA; - else - *blend = GL_ONE; - - if ( !i ) { - token = Shader_ParseString ( ptr ); - } - } - } - - pass->flags |= SHADER_PASS_BLEND; -} - -static void Shaderpass_AlphaFunc ( shader_t *shader, shaderpass_t *pass, char **ptr ) -{ - char *token; - - token = Shader_ParseString ( ptr ); - if ( !Q_stricmp (token, "gt0") ) { - pass->alphafunc = SHADER_ALPHA_GT0; - } else if ( !Q_stricmp (token, "lt128") ) { - pass->alphafunc = SHADER_ALPHA_LT128; - } else if ( !Q_stricmp (token, "ge128") ) { - pass->alphafunc = SHADER_ALPHA_GE128; - } else { - return; + token = Shader_ParseString (ptr); + if ( !Q_stricmp (token, "blend")) + { + pass->shaderbits |= SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA; } + else if (!Q_stricmp (token, "filter")) + { + pass->shaderbits |= SBITS_SRCBLEND_DST_COLOR | SBITS_DSTBLEND_ZERO; + } + else if (!Q_stricmp (token, "add")) + { + pass->shaderbits |= SBITS_SRCBLEND_ONE | SBITS_DSTBLEND_ONE; + } + else if (!Q_stricmp (token, "replace")) + { + pass->shaderbits |= SBITS_SRCBLEND_NONE | SBITS_DSTBLEND_NONE; + } + else + { + pass->shaderbits |= Shader_BlendFactor(token, false); - pass->flags |= SHADER_PASS_ALPHAFUNC; + token = Shader_ParseString (ptr); + pass->shaderbits |= Shader_BlendFactor(token, true); + } } -static void Shaderpass_DepthFunc ( shader_t *shader, shaderpass_t *pass, char **ptr ) +static void Shaderpass_AlphaFunc (shader_t *shader, shaderpass_t *pass, char **ptr) { char *token; - token = Shader_ParseString ( ptr ); - if ( !Q_stricmp (token, "equal") ) - pass->depthfunc = GL_EQUAL; - else if ( !Q_stricmp (token, "lequal") ) - pass->depthfunc = GL_LEQUAL; - else if ( !Q_stricmp (token, "gequal") ) - pass->depthfunc = GL_GEQUAL; + pass->shaderbits &= ~SBITS_ATEST_BITS; + + token = Shader_ParseString (ptr); + if (!Q_stricmp (token, "gt0")) + { + pass->shaderbits = SBITS_ATEST_GT0; + } + else if (!Q_stricmp (token, "lt128")) + { + pass->shaderbits = SBITS_ATEST_LT128; + } + else if (!Q_stricmp (token, "ge128")) + { + pass->shaderbits = SBITS_ATEST_GE128; + } } -static void Shaderpass_DepthWrite ( shader_t *shader, shaderpass_t *pass, char **ptr ) +static void Shaderpass_DepthFunc (shader_t *shader, shaderpass_t *pass, char **ptr) +{ + char *token; + + token = Shader_ParseString (ptr); + if (!Q_stricmp (token, "equal")) + pass->shaderbits |= SBITS_MISC_DEPTHEQUALONLY; + else if (!Q_stricmp (token, "lequal")) + pass->shaderbits &= ~SBITS_MISC_DEPTHEQUALONLY; + else + Con_DPrintf("Invalid depth func %s\n", token); +} + +static void Shaderpass_DepthWrite (shader_t *shader, shaderpass_t *pass, char **ptr) { shader->flags |= SHADER_DEPTHWRITE; - pass->flags |= SHADER_PASS_DEPTHWRITE; + pass->shaderbits |= SBITS_MISC_DEPTHWRITE; } -static void Shaderpass_TcMod ( shader_t *shader, shaderpass_t *pass, char **ptr ) +static void Shaderpass_TcMod (shader_t *shader, shaderpass_t *pass, char **ptr) { int i; tcmod_t *tcmod; char *token; - if (pass->numtcmods >= SHADER_TCMOD_MAX) { + if (pass->numtcmods >= SHADER_TCMOD_MAX) + { return; } tcmod = &pass->tcmods[pass->numtcmods]; - token = Shader_ParseString ( ptr ); - if ( !Q_stricmp (token, "rotate") ) { - tcmod->args[0] = -Shader_ParseFloat ( ptr ) / 360.0f; - if ( !tcmod->args[0] ) { + token = Shader_ParseString (ptr); + if (!Q_stricmp (token, "rotate")) + { + tcmod->args[0] = -Shader_ParseFloat(ptr) / 360.0f; + if (!tcmod->args[0]) + { return; } tcmod->type = SHADER_TCMOD_ROTATE; - } else if ( !Q_stricmp (token, "scale") ) { - tcmod->args[0] = Shader_ParseFloat ( ptr ); - tcmod->args[1] = Shader_ParseFloat ( ptr ); + } + else if ( !Q_stricmp (token, "scale") ) + { + tcmod->args[0] = Shader_ParseFloat (ptr); + tcmod->args[1] = Shader_ParseFloat (ptr); tcmod->type = SHADER_TCMOD_SCALE; - } else if ( !Q_stricmp (token, "scroll") ) { - tcmod->args[0] = Shader_ParseFloat ( ptr ); - tcmod->args[1] = Shader_ParseFloat ( ptr ); + } + else if ( !Q_stricmp (token, "scroll") ) + { + tcmod->args[0] = Shader_ParseFloat (ptr); + tcmod->args[1] = Shader_ParseFloat (ptr); tcmod->type = SHADER_TCMOD_SCROLL; - } else if ( !Q_stricmp (token, "stretch") ) { + } + else if (!Q_stricmp(token, "stretch")) + { shaderfunc_t func; - Shader_ParseFunc ( ptr, &func ); + Shader_ParseFunc(ptr, &func); tcmod->args[0] = func.type; for (i = 1; i < 5; ++i) tcmod->args[i] = func.args[i-1]; tcmod->type = SHADER_TCMOD_STRETCH; - } else if ( !Q_stricmp (token, "transform") ) { + } + else if (!Q_stricmp (token, "transform")) + { for (i = 0; i < 6; ++i) - tcmod->args[i] = Shader_ParseFloat ( ptr ); + tcmod->args[i] = Shader_ParseFloat (ptr); tcmod->type = SHADER_TCMOD_TRANSFORM; - } else if ( !Q_stricmp (token, "turb") ) { + } + else if (!Q_stricmp (token, "turb")) + { for (i = 0; i < 4; i++) - tcmod->args[i] = Shader_ParseFloat ( ptr ); + tcmod->args[i] = Shader_ParseFloat (ptr); tcmod->type = SHADER_TCMOD_TURB; - } else { + } + else + { return; } @@ -1164,8 +1365,8 @@ static void Shaderpass_Detail ( shader_t *shader, shaderpass_t *pass, char **ptr static void Shaderpass_AlphaMask ( shader_t *shader, shaderpass_t *pass, char **ptr ) { - pass->flags |= SHADER_PASS_ALPHAFUNC; - pass->alphafunc = SHADER_ALPHA_GE128; + pass->shaderbits &= ~SBITS_ATEST_BITS; + pass->shaderbits |= SBITS_ATEST_GE128; } static void Shaderpass_NoLightMap ( shader_t *shader, shaderpass_t *pass, char **ptr ) @@ -1218,29 +1419,7 @@ qboolean Shader_Init (void) COM_EnumerateFiles("scripts/*.shader", Shader_InitCallback, NULL); // COM_EnumerateFiles("scripts/*.rscript", Shader_InitCallback, NULL); - /* - char *dirptr; - int i, dirlen, numdirs; - - numdirs = FS_GetFileList ( "scripts", "shader", shaderbuf, sizeof(shaderbuf) ); - if ( !numdirs ) { - Con_Printf ("Could not find any shaders!"); - return false; - } - - // now load all the scripts - dirptr = shaderbuf; - memset ( shader_hash, 0, sizeof(shadercache_t *)*HASH_SIZE ); - - for (i=0; ihash_next ) { - if ( !Q_stricmp (cache->name, name) ) { + for ( ; cache; cache = cache->hash_next ) + { + if ( !Q_stricmp (cache->name, name) ) + { *path = cache->path; *offset = cache->offset; return; @@ -1347,11 +1533,13 @@ static void Shader_GetPathAndOffset ( char *name, char **path, unsigned int *off void Shader_FreePass (shaderpass_t *pass) { +#ifndef NOMEDIA if ( pass->flags & SHADER_PASS_VIDEOMAP ) { Media_ShutdownCin(pass->cin); pass->cin = NULL; } +#endif } void Shader_Free (shader_t *shader) @@ -1359,8 +1547,17 @@ void Shader_Free (shader_t *shader) int i; shaderpass_t *pass; - if ( shader->skydome ) { - for ( i = 0; i < 5; i++ ) { +#ifdef GLQUAKE + if (qrenderer == QR_OPENGL) + if (shader->programhandle.glsl) + qglDeleteObjectARB(shader->programhandle.glsl); +#endif + memset(&shader->programhandle, 0, sizeof(shader->programhandle)); + + if (shader->skydome) + { + for (i = 0; i < 5; i++) + { if (shader->skydome->meshes[i].xyz_array) { Z_Free ( shader->skydome->meshes[i].xyz_array ); @@ -1369,12 +1566,13 @@ void Shader_Free (shader_t *shader) } } - Z_Free ( shader->skydome ); + Z_Free (shader->skydome); } pass = shader->passes; - for ( i = 0; i < shader->numpasses; i++, pass++ ) { - Shader_FreePass ( pass ); + for (i = 0; i < shader->numpasses; i++, pass++) + { + Shader_FreePass (pass); } } @@ -1389,14 +1587,16 @@ void Shader_Shutdown (void) { if ( !shader->registration_sequence ) continue; - + Shader_Free ( shader ); } - for ( i = 0; i < HASH_SIZE; i++ ) { + for ( i = 0; i < HASH_SIZE; i++ ) + { cache = shader_hash[i]; - for ( ; cache; cache = cache_next ) { + for ( ; cache; cache = cache_next ) + { cache_next = cache->hash_next; cache->hash_next = NULL; Z_Free ( cache ); @@ -1406,35 +1606,52 @@ void Shader_Shutdown (void) memset (r_shaders, 0, sizeof(shader_t)*MAX_SHADERS); memset (shader_hash, 0, sizeof(shader_hash)); + + shader_reload_needed = false; } -void Shader_SetBlendmode ( shaderpass_t *pass ) +void Shader_SetBlendmode (shaderpass_t *pass) { - if ( !pass->anim_frames[0] && !(pass->flags & SHADER_PASS_LIGHTMAP) ) { - pass->blendmode = 0; +#ifdef GLQUAKE + if (pass->texgen == T_GEN_DELUXMAP) + { + pass->blendmode = GL_DOT3_RGB_ARB; return; } - if ( !(pass->flags & SHADER_PASS_BLEND) && qglMTexCoord2fSGIS ) { - if ( (pass->rgbgen == RGB_GEN_IDENTITY) && (pass->alphagen == ALPHA_GEN_IDENTITY) ) { + if (pass->texgen < T_GEN_DIFFUSE && !TEXVALID(pass->anim_frames[0]) && !(pass->flags & SHADER_PASS_LIGHTMAP)) + { + pass->blendmode = GL_MODULATE; + return; + } + + if (!(pass->shaderbits & SBITS_BLEND_BITS) && qglMTexCoord2fSGIS) + { + if ((pass->rgbgen == RGB_GEN_IDENTITY) && (pass->alphagen == ALPHA_GEN_IDENTITY)) + { pass->blendmode = GL_REPLACE; - } else { - pass->blendsrc = GL_ONE; - pass->blenddst = GL_ZERO; + } + else + { +#pragma message("is this correct?") + pass->shaderbits &= ~SBITS_BLEND_BITS; + pass->shaderbits |= SBITS_SRCBLEND_ONE; + pass->shaderbits |= SBITS_DSTBLEND_ZERO; pass->blendmode = GL_MODULATE; } return; } - if ( (pass->blendsrc == GL_ZERO && pass->blenddst == GL_SRC_COLOR) || - (pass->blendsrc == GL_DST_COLOR && pass->blenddst == GL_ZERO) ) + if (((pass->shaderbits&SBITS_BLEND_BITS) == (SBITS_SRCBLEND_ZERO|SBITS_DSTBLEND_SRC_COLOR)) || + ((pass->shaderbits&SBITS_BLEND_BITS) == (SBITS_SRCBLEND_DST_COLOR|SBITS_DSTBLEND_ZERO))) pass->blendmode = GL_MODULATE; - else if ( pass->blendsrc == GL_ONE && pass->blenddst == GL_ONE ) + else if ((pass->shaderbits&SBITS_BLEND_BITS) == (SBITS_SRCBLEND_ONE|SBITS_DSTBLEND_ONE)) pass->blendmode = GL_ADD; - else if ( pass->blendsrc == GL_SRC_ALPHA && pass->blenddst == GL_ONE_MINUS_SRC_ALPHA ) + else if ((pass->shaderbits&SBITS_BLEND_BITS) == (SBITS_SRCBLEND_SRC_ALPHA|SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA)) pass->blendmode = GL_DECAL; else - pass->blendmode = 0; + pass->blendmode = GL_MODULATE; +#endif } void Shader_Readpass (shader_t *shader, char **ptr) @@ -1444,51 +1661,57 @@ void Shader_Readpass (shader_t *shader, char **ptr) qboolean ignore; static shader_t dummy; - if ( shader->numpasses >= SHADER_PASS_MAX ) { + if ( shader->numpasses >= SHADER_PASS_MAX ) + { ignore = true; shader = &dummy; shader->numpasses = 1; pass = shader->passes; - } else { + } + else + { ignore = false; pass = &shader->passes[shader->numpasses++]; } // Set defaults pass->flags = 0; - pass->anim_frames[0] = 0; + pass->anim_frames[0] = r_nulltex; pass->anim_numframes = 0; - pass->depthfunc = GL_LEQUAL; pass->rgbgen = RGB_GEN_UNKNOWN; pass->alphagen = ALPHA_GEN_IDENTITY; pass->tcgen = TC_GEN_BASE; pass->numtcmods = 0; - - // default to R_RenderMeshGeneric pass->numMergedPasses = 1; - pass->flush = R_RenderMeshGeneric; while ( ptr ) { token = COM_ParseExt (ptr, true); - if ( !token[0] ) { + if ( !token[0] ) + { continue; - } else if ( token[0] == '}' ) { + } + else if ( token[0] == '}' ) + { break; - } else if ( Shader_Parsetok (shader, pass, shaderpasskeys, token, ptr) ) { + } + else if ( Shader_Parsetok (shader, pass, shaderpasskeys, token, ptr) ) + { break; } } // check some things - if ( ignore ) { + if ( ignore ) + { Shader_Free ( shader ); return; } - if ( (pass->blendsrc == GL_ONE) && (pass->blenddst == GL_ZERO) ) { - pass->flags |= SHADER_PASS_DEPTHWRITE; + if ((pass->shaderbits&SBITS_BLEND_BITS) == (SBITS_SRCBLEND_ONE|SBITS_DSTBLEND_ZERO)) + { + pass->shaderbits |= SBITS_MISC_DEPTHWRITE; shader->flags |= SHADER_DEPTHWRITE; } @@ -1519,15 +1742,62 @@ void Shader_Readpass (shader_t *shader, char **ptr) break; } - Shader_SetBlendmode ( pass ); - - if ( (shader->flags & SHADER_SKY) && (shader->flags & SHADER_DEPTHWRITE) ) { - if ( pass->flags & SHADER_PASS_DEPTHWRITE ) { - pass->flags &= ~SHADER_PASS_DEPTHWRITE; - } + if ((shader->flags & SHADER_SKY) && (shader->flags & SHADER_DEPTHWRITE)) + { +#pragma message("is this valid?") + pass->shaderbits &= ~SBITS_MISC_DEPTHWRITE; } } +static qboolean Shader_EvaluateCondition(char **ptr) +{ + char *token; + cvar_t *cv; + qboolean conditiontrue = true; + token = COM_ParseExt ( ptr, false ); + if (*token == '!') + { + conditiontrue = false; + token++; + } + if (*token == '$') + { + extern cvar_t gl_bump; + token++; + if (!Q_stricmp(token, "lightmap")) + conditiontrue = conditiontrue == !r_fullbright.value; + else if (!Q_stricmp(token, "deluxmap") ) + conditiontrue = conditiontrue == !!gl_bump.value; + + //normalmaps are generated if they're not already known. + else if (!Q_stricmp(token, "normalmap") ) + conditiontrue = conditiontrue == !!gl_bump.value; + +#pragma message("shader fixme") + else if (!Q_stricmp(token, "diffuse") ) + conditiontrue = conditiontrue == true; + else if (!Q_stricmp(token, "specular") ) + conditiontrue = conditiontrue == false; + else if (!Q_stricmp(token, "fullbright") ) + conditiontrue = conditiontrue == false; + else if (!Q_stricmp(token, "topoverlay") ) + conditiontrue = conditiontrue == false; + else if (!Q_stricmp(token, "loweroverlay") ) + conditiontrue = conditiontrue == false; + + else + conditiontrue = conditiontrue == false; + } + else + { + cv = Cvar_Get(token, "", 0, "Shader Conditions"); + if (cv) + conditiontrue = conditiontrue == !!cv->value; + } + + return conditiontrue; +} + static qboolean Shader_Parsetok (shader_t *shader, shaderpass_t *pass, shaderkey_t *keys, char *token, char **ptr) { shaderkey_t *key; @@ -1543,57 +1813,6 @@ static qboolean Shader_Parsetok (shader_t *shader, shaderpass_t *pass, shaderkey } } - if (!Q_stricmp(token, "if")) - { - int indent = 0; - cvar_t *cv; - qboolean conditiontrue = true; - token = COM_ParseExt ( ptr, false ); - if (*token == '!') - { - conditiontrue = false; - token++; - } - cv = Cvar_Get(token, "", 0, "Shader Conditions"); - if (cv) - conditiontrue = conditiontrue == !!cv->value; - - if (conditiontrue) - { - while ( ptr ) - { - token = COM_ParseExt (ptr, true); - if ( !token[0] ) - continue; - else if (token[0] == ']' || token[0] == '}') - indent--; - else if (token[0] == '[') - indent++; - else - Shader_Parsetok (shader, pass, keys, token, ptr); - if (!indent) - break; - } - } - else - { - while ( ptr ) - { - token = COM_ParseExt (ptr, true); - if (!token[0]) - continue; - else if (token[0] == ']' || token[0] == '}') - indent--; - else if (token[0] == '[') - indent++; - if (!indent) - break; - } - } - - return ( ptr && *ptr && **ptr == '}' ); - } - // Next Line while (ptr) { @@ -1606,75 +1825,78 @@ static qboolean Shader_Parsetok (shader_t *shader, shaderpass_t *pass, shaderkey return false; } -void Shader_SetPassFlush ( shaderpass_t *pass, shaderpass_t *pass2 ) +void Shader_SetPassFlush (shaderpass_t *pass, shaderpass_t *pass2) { - if ( ((pass->flags & SHADER_PASS_DETAIL) && !r_detailtextures.value) || +#ifdef GLQUAKE + if (((pass->flags & SHADER_PASS_DETAIL) && !r_detailtextures.value) || ((pass2->flags & SHADER_PASS_DETAIL) && !r_detailtextures.value) || (pass->flags & SHADER_PASS_VIDEOMAP) || (pass2->flags & SHADER_PASS_VIDEOMAP) || - ((pass->flags & SHADER_PASS_ALPHAFUNC) && (pass2->depthfunc != GL_EQUAL)) ) { + ((pass->shaderbits & SBITS_ATEST_BITS) && !(pass2->shaderbits & SBITS_MISC_DEPTHEQUALONLY))) + { return; } - if ( pass2->rgbgen != RGB_GEN_IDENTITY || pass2->alphagen != ALPHA_GEN_IDENTITY ) { + if (pass2->rgbgen != RGB_GEN_IDENTITY || pass2->alphagen != ALPHA_GEN_IDENTITY) + { return; } - if (pass->rgbgen != RGB_GEN_IDENTITY || pass->alphagen != ALPHA_GEN_IDENTITY ) + if (pass->rgbgen != RGB_GEN_IDENTITY || pass->alphagen != ALPHA_GEN_IDENTITY) return; - // check if we can use R_RenderMeshCombined - - if ( gl_config.tex_env_combine || gl_config.nv_tex_env_combine4 ) + // check if we can use multiple passes + if (pass2->blendmode == GL_DOT3_RGB_ARB) + { + pass->numMergedPasses++; + } + else if (gl_config.tex_env_combine || gl_config.nv_tex_env_combine4) { if ( pass->blendmode == GL_REPLACE ) { if ((pass2->blendmode == GL_DECAL && gl_config.tex_env_combine) || (pass2->blendmode == GL_ADD && gl_config.env_add) || - (pass2->blendmode && pass2->blendmode != GL_ADD) || gl_config.nv_tex_env_combine4 ) + (pass2->blendmode && pass2->blendmode != GL_ADD) || gl_config.nv_tex_env_combine4) { - pass->flush = R_RenderMeshCombined; + pass->numMergedPasses++; } } - else if ( pass->blendmode == GL_ADD && - pass2->blendmode == GL_ADD && gl_config.env_add ) + else if (pass->blendmode == GL_ADD && + pass2->blendmode == GL_ADD && gl_config.env_add) { - pass->flush = R_RenderMeshCombined; - } else if ( pass->blendmode == GL_MODULATE && - pass2->blendmode == GL_MODULATE ) + pass->numMergedPasses++; + } + else if (pass->blendmode == GL_MODULATE && pass2->blendmode == GL_MODULATE) { - pass->flush = R_RenderMeshCombined; + pass->numMergedPasses++; } } else if ( qglMTexCoord2fSGIS ) { + //don't merge more than 2 tmus. + if (pass->numMergedPasses != 1) + return; + // check if we can use R_RenderMeshMultitextured if ( pass->blendmode == GL_REPLACE ) { if ( pass2->blendmode == GL_ADD && gl_config.env_add ) { - pass->flush = R_RenderMeshMultitextured; pass->numMergedPasses = 2; } else if ( pass2->blendmode && pass2->blendmode != GL_DECAL ) { - pass->flush = R_RenderMeshMultitextured; pass->numMergedPasses = 2; } } - else if ( pass->blendmode == GL_MODULATE && - pass2->blendmode == GL_MODULATE ) + else if (pass->blendmode == GL_MODULATE && pass2->blendmode == GL_MODULATE) { - pass->flush = R_RenderMeshMultitextured; + pass->numMergedPasses = 2; } - else if ( pass->blendmode == GL_ADD && - pass2->blendmode == GL_ADD && gl_config.env_add ) + else if (pass->blendmode == GL_ADD && pass2->blendmode == GL_ADD && gl_config.env_add) { - pass->flush = R_RenderMeshCombined; + pass->numMergedPasses = 2; } } - - if ( pass->flush != R_RenderMeshGeneric ) { - pass->numMergedPasses = 2; - } +#endif } void Shader_SetFeatures ( shader_t *s ) @@ -1685,8 +1907,10 @@ void Shader_SetFeatures ( shader_t *s ) s->features = MF_NONE; - for ( i = 0, trnormals = true; i < s->numdeforms; i++ ) { - switch ( s->deforms[i].type ) { + for (i = 0, trnormals = true; i < s->numdeforms; i++) + { + switch (s->deforms[i].type) + { case DEFORMV_BULGE: case DEFORMV_WAVE: trnormals = false; @@ -1701,12 +1925,15 @@ void Shader_SetFeatures ( shader_t *s ) } } - if ( trnormals ) { + if (trnormals) + { s->features |= MF_TRNORMALS; } - for ( i = 0, pass = s->passes; i < s->numpasses; i++, pass++ ) { - switch ( pass->rgbgen ) { + for (i = 0, pass = s->passes; i < s->numpasses; i++, pass++) + { + switch (pass->rgbgen) + { case RGB_GEN_LIGHTING_DIFFUSE: s->features |= MF_NORMALS; break; @@ -1719,7 +1946,8 @@ void Shader_SetFeatures ( shader_t *s ) break; } - switch ( pass->alphagen ) { + switch ( pass->alphagen ) + { case ALPHA_GEN_SPECULAR: s->features |= MF_NORMALS; break; @@ -1730,7 +1958,8 @@ void Shader_SetFeatures ( shader_t *s ) break; } - switch ( pass->tcgen ) { + switch (pass->tcgen) + { default: s->features |= MF_STCOORDS; break; @@ -1741,17 +1970,35 @@ void Shader_SetFeatures ( shader_t *s ) case TC_GEN_NORMAL: s->features |= MF_NORMALS; break; + case TC_GEN_SVECTOR: + case TC_GEN_TVECTOR: + s->features |= MF_NORMALS; + break; } } } -void Shader_Finish ( shader_t *s ) +void Shader_Finish (shader_t *s) { int i; shaderpass_t *pass; - if ( !Q_stricmp (s->name, "flareShader") ) { - s->flags |= SHADER_FLARE; + if (s->flags & SHADER_SKY && r_fastsky.ival) + { + s->flags = 0; + s->numdeforms = 0; + s->numpasses = 0; + s->numprogparams = 0; + + Shader_DefaultScript(s->name, s, + "{\n" + "{\n" + "map $whiteimage\n" + "rgbgen $r_fastskycolour\n" + "}\n" + "}\n" + ); + return; } if (!s->numpasses && !(s->flags & (SHADER_NODRAW|SHADER_SKY)) && !s->fog_dist) @@ -1759,74 +2006,83 @@ void Shader_Finish ( shader_t *s ) pass = &s->passes[s->numpasses++]; pass = &s->passes[0]; pass->tcgen = TC_GEN_BASE; - pass->anim_frames[0] = Mod_LoadHiResTexture(s->name, NULL, true, false, true);//GL_FindImage (shortname, 0); - if (!pass->anim_frames[0]) + pass->anim_frames[0] = R_LoadHiResTexture(s->name, NULL, IF_NOALPHA); + if (!TEXVALID(pass->anim_frames[0])) { Con_Printf("Shader %s failed to load default texture\n", s->name); pass->anim_frames[0] = missing_texture; } - pass->depthfunc = GL_LEQUAL; - pass->flags = SHADER_PASS_DEPTHWRITE; + pass->shaderbits |= SBITS_MISC_DEPTHWRITE; pass->rgbgen = RGB_GEN_VERTEX; pass->alphagen = ALPHA_GEN_IDENTITY; - pass->blendmode = GL_MODULATE; pass->numMergedPasses = 1; - pass->flush = R_RenderMeshGeneric; + Shader_SetBlendmode(pass); Con_Printf("Shader %s with no passes and no surfaceparm nodraw, inserting pass\n", s->name); } - if ( !s->numpasses && !s->sort ) { + if (!Q_stricmp (s->name, "flareShader")) + { + s->flags |= SHADER_FLARE; + } + + if (!s->numpasses && !s->sort) + { s->sort = SHADER_SORT_ADDITIVE; return; } - if ( (s->flags & SHADER_POLYGONOFFSET) && !s->sort ) { - s->sort = SHADER_SORT_ADDITIVE - 1; + if (!s->sort && s->passes->texgen == T_GEN_CURRENTRENDER) + s->sort = SHADER_SORT_NEAREST; + + + if ((s->polyoffset.unit < 0) && !s->sort) + { + s->sort = SHADER_SORT_DECAL; } - if ( r_vertexlight.value && !s->programhandle) + if (r_vertexlight.value && !s->programhandle.glsl) { // do we have a lightmap pass? pass = s->passes; - for ( i = 0; i < s->numpasses; i++, pass++ ) + for (i = 0; i < s->numpasses; i++, pass++) { - if ( pass->flags & SHADER_PASS_LIGHTMAP ) + if (pass->flags & SHADER_PASS_LIGHTMAP) break; } - if ( i == s->numpasses ) + if (i == s->numpasses) { goto done; } // try to find pass with rgbgen set to RGB_GEN_VERTEX pass = s->passes; - for ( i = 0; i < s->numpasses; i++, pass++ ) + for (i = 0; i < s->numpasses; i++, pass++) { - if ( pass->rgbgen == RGB_GEN_VERTEX ) + if (pass->rgbgen == RGB_GEN_VERTEX) break; } - if ( i < s->numpasses ) + if (i < s->numpasses) { // we found it pass->flags |= SHADER_CULL_FRONT; - pass->flags &= ~(SHADER_PASS_BLEND|SHADER_PASS_ANIMMAP); + pass->flags &= ~SHADER_PASS_ANIMMAP; + pass->shaderbits &= ~SBITS_BLEND_BITS; pass->blendmode = 0; - pass->flags |= SHADER_PASS_DEPTHWRITE; + pass->shaderbits |= SBITS_MISC_DEPTHWRITE; pass->alphagen = ALPHA_GEN_IDENTITY; pass->numMergedPasses = 1; - pass->flush = R_RenderMeshGeneric; s->flags |= SHADER_DEPTHWRITE; s->sort = SHADER_SORT_OPAQUE; s->numpasses = 1; - memcpy ( &s->passes[0], pass, sizeof(shaderpass_t) ); + memcpy(&s->passes[0], pass, sizeof(shaderpass_t)); } else { // we didn't find it - simply remove all lightmap passes pass = s->passes; - for ( i = 0; i < s->numpasses; i++, pass++ ) + for(i = 0; i < s->numpasses; i++, pass++) { - if ( pass->flags & SHADER_PASS_LIGHTMAP ) + if (pass->flags & SHADER_PASS_LIGHTMAP) break; } @@ -1858,10 +2114,10 @@ void Shader_Finish ( shader_t *s ) s->passes[0].rgbgen = RGB_GEN_VERTEX; s->passes[0].alphagen = ALPHA_GEN_IDENTITY; s->passes[0].blendmode = 0; - s->passes[0].flags &= ~(SHADER_PASS_BLEND|SHADER_PASS_ANIMMAP|SHADER_PASS_NOCOLORARRAY); - s->passes[0].flags |= SHADER_PASS_DEPTHWRITE; + s->passes[0].flags &= ~(SHADER_PASS_ANIMMAP|SHADER_PASS_NOCOLORARRAY); + pass->shaderbits &= ~SBITS_BLEND_BITS; + s->passes[0].shaderbits |= SBITS_MISC_DEPTHWRITE; s->passes[0].numMergedPasses = 1; - s->passes[0].flush = R_RenderMeshGeneric; s->numpasses = 1; s->flags |= SHADER_DEPTHWRITE; } @@ -1869,95 +2125,115 @@ void Shader_Finish ( shader_t *s ) done:; pass = s->passes; - for ( i = 0; i < s->numpasses; i++, pass++ ) { - if ( !(pass->flags & SHADER_PASS_BLEND) ) { + for (i = 0; i < s->numpasses; i++, pass++) + { + if (!(pass->shaderbits & SBITS_BLEND_BITS)) + { break; } } // all passes have blendfuncs - if ( i == s->numpasses ) { + if (i == s->numpasses) + { int opaque; opaque = -1; pass = s->passes; - for ( i = 0; i < s->numpasses; i++, pass++ ) { - if ( (pass->blendsrc == GL_ONE) && (pass->blenddst == GL_ZERO) ) { + for (i = 0; i < s->numpasses; i++, pass++ ) + { + if ((pass->shaderbits&SBITS_BLEND_BITS) == (SBITS_SRCBLEND_DST_COLOR|SBITS_DSTBLEND_ZERO)) + { opaque = i; } - if ( pass->rgbgen == RGB_GEN_UNKNOWN ) { - if ( !s->fog_dist && !(pass->flags & SHADER_PASS_LIGHTMAP) ) + if (pass->rgbgen == RGB_GEN_UNKNOWN) + { + if (!s->fog_dist && !(pass->flags & SHADER_PASS_LIGHTMAP)) pass->rgbgen = RGB_GEN_IDENTITY_LIGHTING; else pass->rgbgen = RGB_GEN_IDENTITY; } + + Shader_SetBlendmode (pass); } - if ( !( s->flags & SHADER_SKY ) && !s->sort ) { - if ( opaque == -1 ) + if (!(s->flags & SHADER_SKY ) && !s->sort) + { + if (opaque == -1) s->sort = SHADER_SORT_ADDITIVE; - else if ( s->passes[opaque].flags & SHADER_PASS_ALPHAFUNC ) + else if (s->passes[opaque].shaderbits & SBITS_ATEST_BITS) s->sort = SHADER_SORT_OPAQUE + 1; else s->sort = SHADER_SORT_OPAQUE; } - } else { + } + else + { int j; shaderpass_t *sp; sp = s->passes; - for ( j = 0; j < s->numpasses; j++, sp++ ) { - if ( sp->rgbgen == RGB_GEN_UNKNOWN ) { + for (j = 0; j < s->numpasses; j++, sp++) + { + if (sp->rgbgen == RGB_GEN_UNKNOWN) + { sp->rgbgen = RGB_GEN_IDENTITY; } + + Shader_SetBlendmode (sp); } - if ( !s->sort ) { - if ( pass->flags & SHADER_PASS_ALPHAFUNC ) + if (!s->sort) + { + if (pass->shaderbits & SBITS_ATEST_BITS) s->sort = SHADER_SORT_OPAQUE + 1; } - if ( !( s->flags & SHADER_DEPTHWRITE ) && - !( s->flags & SHADER_SKY ) ) + if (!( s->flags & SHADER_DEPTHWRITE) && + !(s->flags & SHADER_SKY)) { - pass->flags |= SHADER_PASS_DEPTHWRITE; + pass->shaderbits |= SBITS_MISC_DEPTHWRITE; s->flags |= SHADER_DEPTHWRITE; } } - if ( s->numpasses >= 2 ) + if (s->numpasses >= 2) { + int j; + pass = s->passes; - for ( i = 0; i < s->numpasses; ) + for (i = 0; i < s->numpasses;) { - if ( i == s->numpasses - 1 ) + if (i == s->numpasses - 1) break; pass = s->passes + i; - Shader_SetPassFlush ( pass, pass + 1 ); + for (j = 1; j < s->numpasses-i && j == i + pass->numMergedPasses && j < be_maxpasses; j++) + Shader_SetPassFlush (pass, pass + j); i += pass->numMergedPasses; } } - if ( !s->sort ) { + if (!s->sort) + { s->sort = SHADER_SORT_OPAQUE; } - if ( (s->flags & SHADER_SKY) && (s->flags & SHADER_DEPTHWRITE) ) { + if ((s->flags & SHADER_SKY) && (s->flags & SHADER_DEPTHWRITE)) + { s->flags &= ~SHADER_DEPTHWRITE; } - if (s->programhandle) + if (s->programhandle.glsl) { if (!s->numpasses) s->numpasses = 1; s->passes->numMergedPasses = s->numpasses; - s->passes->flush = R_RenderMeshProgram; } - Shader_SetFeatures ( s ); + Shader_SetFeatures(s); } /* void Shader_UpdateRegistration (void) @@ -1966,62 +2242,36 @@ void Shader_UpdateRegistration (void) shader_t *shader; shaderpass_t *pass; -#ifdef FIZME - if ( chars_shader ) - chars_shader->registration_sequence = registration_sequence; - - if ( propfont1_shader ) - propfont1_shader->registration_sequence = registration_sequence; - - if ( propfont1_glow_shader ) - propfont1_glow_shader->registration_sequence = registration_sequence; - - if ( propfont2_shader ) - propfont2_shader->registration_sequence = registration_sequence; - - if ( particle_shader ) - particle_shader->registration_sequence = registration_sequence; -#endif shader = r_shaders; for (i = 0; i < MAX_SHADERS; i++, shader++) { - if ( !shader->registration_sequence ) + if (!shader->registration_sequence) continue; - if ( shader->registration_sequence != registration_sequence ) { + if (shader->registration_sequence != registration_sequence) + { Shader_Free ( shader ); shader->registration_sequence = 0; continue; } -#ifdef FIZME: skydomes - if ( shader->flags & SHADER_SKY && shader->skydome ) { - if ( shader->skydome->farbox_textures[0] ) { - for ( j = 0; j < 6; j++ ) { - if ( shader->skydome->farbox_textures[j] ) - shader->skydome->farbox_textures[j]->registration_sequence = registration_sequence; - } - } - if ( shader->skydome->nearbox_textures[0] ) { - for ( j = 0; j < 6; j++ ) { - if ( shader->skydome->nearbox_textures[j] ) - shader->skydome->nearbox_textures[j]->registration_sequence = registration_sequence; - } - } - } -#endif pass = shader->passes; for (j = 0; j < shader->numpasses; j++, pass++) { - if ( pass->flags & SHADER_PASS_ANIMMAP ) { + if (pass->flags & SHADER_PASS_ANIMMAP) + { for (l = 0; l < pass->anim_numframes; l++) { - if ( pass->anim_frames[l] ) + if (pass->anim_frames[l]) pass->anim_frames[l]->registration_sequence = registration_sequence; } - } else if ( pass->flags & SHADER_PASS_VIDEOMAP ) { + } + else if ( pass->flags & SHADER_PASS_VIDEOMAP ) + { // Shader_RunCinematic will do the job // pass->cin->frame = -1; - } else if ( !(pass->flags & SHADER_PASS_LIGHTMAP) ) { + } + else if ( !(pass->flags & SHADER_PASS_LIGHTMAP) ) + { if ( pass->anim_frames[0] ) pass->anim_frames[0]->registration_sequence = registration_sequence; } @@ -2029,293 +2279,287 @@ void Shader_UpdateRegistration (void) } } */ -/* -void Shader_UploadCinematic (shader_t *shader) + +void R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader) { - int j; - shaderpass_t *pass; - - // upload cinematics - pass = shader->passes; - for ( j = 0; j < shader->numpasses; j++, pass++ ) { - if ( pass->flags & SHADER_PASS_VIDEOMAP ) { - pass->anim_frames[0] = GL_ResampleCinematicFrame ( pass ); - } - } -} - -void Shader_RunCinematic (void) -{ - int i, j; - shader_t *shader; - shaderpass_t *pass; - - shader = r_shaders; - for ( i = 0; i < MAX_SHADERS; i++, shader++ ) { - if ( !shader->registration_sequence ) - continue; - if ( !(shader->flags & SHADER_VIDEOMAP) ) - continue; - - pass = shader->passes; - for ( j = 0; j < shader->numpasses; j++, pass++ ) { - if ( !(pass->flags & SHADER_PASS_VIDEOMAP) ) - continue; - - // reinitialize - if ( pass->cin->frame == -1 ) { - GL_StopCinematic ( pass->cin ); - GL_PlayCinematic( pass->cin ); - - if ( pass->cin->time == 0 ) { // not found - pass->flags &= ~SHADER_PASS_VIDEOMAP; - Z_Free ( pass->cin ); - } - - continue; - } - - GL_RunCinematic ( pass->cin ); - } - } -} -*/ - -void Shader_DefaultBSP(char *shortname, shader_t *s, void *args) -{ - texnums_t *tn = args; - shaderpass_t *pass; - - int bumptex; extern cvar_t gl_bump; - if (*shortname == '*' && tn) - { - extern int waterprogram; - extern int waterprogram_time; + /*dlights/realtime lighting needs some stuff*/ + if (!TEXVALID(tn->base)) + tn->base = R_LoadHiResTexture(shader->name, NULL, IF_NOALPHA); - if (waterprogram) - { - //quake1 water - pass = &s->passes[s->numpasses++]; + if (!TEXVALID(tn->bump) && gl_bump.ival) + tn->bump = R_LoadHiResTexture(va("%s_norm", shader->name), NULL, IF_NOALPHA); + if (!TEXVALID(tn->bump) && gl_bump.ival) + tn->bump = R_LoadHiResTexture(va("%s_bump", shader->name), NULL, IF_NOALPHA); + if (!TEXVALID(tn->bump) && gl_bump.ival) + tn->bump = R_LoadHiResTexture(va("normalmaps/%s", shader->name), NULL, IF_NOALPHA); - pass->flags = SHADER_PASS_DEPTHWRITE|SHADER_PASS_NOCOLORARRAY; - pass->tcgen = TC_GEN_BASE; - pass->anim_frames[0] = tn->base; - pass->depthfunc = GL_LEQUAL; - pass->blendmode = GL_MODULATE; - pass->alphagen = ALPHA_GEN_IDENTITY; - pass->rgbgen = RGB_GEN_IDENTITY; - - pass->numMergedPasses = 1; - pass->flush = R_RenderMeshProgram; - - s->programhandle = waterprogram; - s->numprogparams = 0; - s->progparm[s->numprogparams].handle = waterprogram_time; - s->progparm[s->numprogparams].type = SP_TIME; - s->numprogparams++; - - s->numdeforms = 0; - s->flags = SHADER_DEPTHWRITE|SHADER_CULL_FRONT; //q1 surfaces are one sided - there are actually two of them - s->features = MF_STCOORDS; - s->sort = SHADER_SORT_OPAQUE; - s->registration_sequence = 1;//fizme: registration_sequence; - return; - } - } - - if (!strncmp(shortname, "sky", 3) && tn) - { - extern int skyprogram; - extern int skyprogram_time; - extern int skyprogram_eyepos; - - if (skyprogram) - { - //quake1 sky - pass = &s->passes[s->numpasses++]; - - pass->flags = SHADER_PASS_DEPTHWRITE|SHADER_PASS_NOCOLORARRAY; - pass->tcgen = TC_GEN_BASE; - pass->anim_frames[0] = tn->base; - pass->depthfunc = GL_LEQUAL; - pass->blendmode = GL_MODULATE; - pass->alphagen = ALPHA_GEN_IDENTITY; - pass->rgbgen = RGB_GEN_IDENTITY; - - pass->numMergedPasses = 2; - pass->flush = R_RenderMeshProgram; - - pass = &s->passes[s->numpasses++]; - - pass->flags = SHADER_PASS_NOCOLORARRAY; - pass->tcgen = TC_GEN_BASE; - pass->anim_frames[0] = tn->fullbright; - pass->depthfunc = GL_LEQUAL; - pass->blendmode = GL_MODULATE; - pass->alphagen = ALPHA_GEN_IDENTITY; - pass->rgbgen = RGB_GEN_IDENTITY; - - s->programhandle = skyprogram; - s->numprogparams = 0; - s->progparm[s->numprogparams].handle = skyprogram_time; - s->progparm[s->numprogparams].type = SP_TIME; - s->numprogparams++; - s->progparm[s->numprogparams].handle = skyprogram_eyepos; - s->progparm[s->numprogparams].type = SP_EYEPOS; - s->numprogparams++; - - s->numdeforms = 0; - s->flags = SHADER_DEPTHWRITE|SHADER_CULL_FRONT; //q1 surfaces are one sided - there are actually two of them - s->features = MF_STCOORDS; - s->sort = SHADER_SORT_OPAQUE; - s->registration_sequence = 1;//fizme: registration_sequence; - return; - } - } - - if (gl_config.arb_texture_env_dot3) - { - if (gl_bump.value) - { - bumptex = GL_FindTexture(va("%s_bump", shortname)); - if (bumptex == -1) - bumptex = GL_FindTexture(va("%s_norm", shortname)); - if (bumptex == -1) - bumptex = Mod_LoadHiResTexture(va("normalmaps/%s", shortname), NULL, true, false, false);//GL_FindImage (shortname, 0); - } - else - bumptex = 0; - } - else - bumptex = 0; - - if (bumptex) - { - pass = &s->passes[s->numpasses++]; - pass->flags = SHADER_PASS_DELUXMAP | SHADER_PASS_DEPTHWRITE | SHADER_PASS_NOCOLORARRAY; - pass->tcgen = TC_GEN_LIGHTMAP; - pass->anim_frames[0] = 0; - pass->depthfunc = GL_LEQUAL; - pass->blendmode = GL_REPLACE; - pass->alphagen = ALPHA_GEN_IDENTITY; - pass->rgbgen = RGB_GEN_IDENTITY; - pass->numMergedPasses = 2; - if (pass->numMergedPasses > gl_mtexarbable) - pass->numMergedPasses = gl_mtexarbable; - pass->flush = R_RenderMeshCombined; - - - pass = &s->passes[s->numpasses++]; - pass->flags = SHADER_PASS_BLEND | SHADER_PASS_NOCOLORARRAY; - pass->tcgen = TC_GEN_BASE; - pass->anim_frames[0] = bumptex; - pass->anim_numframes = 1; - pass->blendmode = GL_DOT3_RGB_ARB; - pass->rgbgen = RGB_GEN_IDENTITY; - pass->alphagen = ALPHA_GEN_IDENTITY; - - - pass = &s->passes[s->numpasses++]; - pass->flags = SHADER_PASS_NOCOLORARRAY | SHADER_PASS_BLEND; - pass->tcgen = TC_GEN_BASE; - pass->anim_frames[0] = Mod_LoadHiResTexture(shortname, NULL, true, false, true);//GL_FindImage (shortname, 0); - if (!pass->anim_frames[0]) - pass->anim_frames[0] = missing_texture; - pass->depthfunc = GL_LEQUAL; - pass->blendsrc = GL_ZERO; - pass->blenddst = GL_SRC_COLOR; - pass->blendmode = GL_MODULATE; - pass->alphagen = ALPHA_GEN_IDENTITY; - pass->rgbgen = RGB_GEN_IDENTITY; - pass->numMergedPasses = 2; - pass->flush = R_RenderMeshMultitextured; - - pass = &s->passes[s->numpasses++]; - pass->flags = SHADER_PASS_LIGHTMAP | SHADER_PASS_NOCOLORARRAY | SHADER_PASS_BLEND; - pass->tcgen = TC_GEN_LIGHTMAP; - pass->anim_frames[0] = 0; - pass->depthfunc = GL_LEQUAL; - pass->blendsrc = GL_ZERO; - pass->blenddst = GL_SRC_COLOR; - pass->blendmode = GL_MODULATE; - pass->alphagen = ALPHA_GEN_IDENTITY; - pass->rgbgen = RGB_GEN_IDENTITY; - pass->numMergedPasses = 1; - pass->flush = R_RenderMeshGeneric; - } - else - { - pass = &s->passes[0]; - pass->flags = SHADER_PASS_LIGHTMAP | SHADER_PASS_DEPTHWRITE | SHADER_PASS_NOCOLORARRAY; - pass->tcgen = TC_GEN_LIGHTMAP; - pass->anim_frames[0] = 0; - pass->depthfunc = GL_LEQUAL; - pass->blendmode = GL_REPLACE; - pass->alphagen = ALPHA_GEN_IDENTITY; - pass->rgbgen = RGB_GEN_IDENTITY; - pass->numMergedPasses = 2; - - if ( qglMTexCoord2fSGIS ) - { - pass->numMergedPasses = 2; - pass->flush = R_RenderMeshMultitextured; - } - else - { - pass->numMergedPasses = 1; - pass->flush = R_RenderMeshGeneric; - } - - pass = &s->passes[1]; - pass->flags = SHADER_PASS_BLEND | SHADER_PASS_NOCOLORARRAY; - pass->tcgen = TC_GEN_BASE; - pass->anim_frames[0] = Mod_LoadHiResTexture(shortname, NULL, true, false, true);//GL_FindImage (shortname, 0); - if (!pass->anim_frames[0]) - pass->anim_frames[0] = missing_texture; - pass->anim_numframes = 1; - pass->blendsrc = GL_ZERO; - pass->blenddst = GL_SRC_COLOR; - pass->blendmode = GL_MODULATE; - pass->depthfunc = GL_LEQUAL; - pass->rgbgen = RGB_GEN_IDENTITY; - pass->alphagen = ALPHA_GEN_IDENTITY; - - pass->numMergedPasses = 1; - pass->flush = R_RenderMeshGeneric; - - if ( !pass->anim_frames[0] ) { - Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", s->name, shortname ); - pass->anim_frames[0] = missing_texture; - } - - s->numpasses = 2; - } - s->numdeforms = 0; - s->flags = SHADER_DEPTHWRITE|SHADER_CULL_FRONT; - s->features = MF_STCOORDS|MF_LMCOORDS|MF_TRNORMALS; - s->sort = SHADER_SORT_OPAQUE; - s->registration_sequence = 1;//fizme: registration_sequence; - - s->style = SSTYLE_LIGHTMAPPED; + shader->defaulttextures = *tn; } -void Shader_DefaultBSPVertex(char *shortname, shader_t *s, void *args) +void Shader_DefaultScript(char *shortname, shader_t *s, const void *args) +{ + const char *f = args; + if (!args) + return; + while (*f == ' ' || *f == '\t' || *f == '\n' || *f == '\r') + f++; + if (*f == '{') + { + f++; + Shader_ReadShader(s, (void*)f); + } +}; + +void Shader_DefaultBSP(char *shortname, shader_t *s, const void *args) +{ + char *builtin = NULL; + if (!builtin && (*shortname == '*')) + { + //q1 water + /* if (r_fastturb.value) + { + builtin = ( + "{\n" + "{\n" + "map $whiteimage\n" + "rgbgen $r_fastturbcolour\n" + "}\n" + "}\n" + ); + } + else*/ + builtin = ( + "{\n" + "program\n" + "{\n" + "#ifdef VERTEX_SHADER\n" + "varying vec3 pos;\n" + "varying vec2 tc;\n" + + "void main (void)\n" + "{\n" + " tc = gl_MultiTexCoord0.st;\n" + " gl_Position = ftransform();\n" + "}\n" + "#endif\n" + + "#ifdef FRAGMENT_SHADER\n" + "uniform sampler2D watertexture;\n" + "uniform float time;\n" + "varying vec2 tc;\n" + + "void main (void)\n" + "{\n" + " vec2 ntc;\n" + " ntc.s = tc.s + sin(tc.t+time)*0.125;\n" + " ntc.t = tc.t + sin(tc.s+time)*0.125;\n" + " vec3 ts = vec3(texture2D(watertexture, ntc));\n" + + " gl_FragColor.rgb = ts;\n" + "}\n" + "#endif\n" + "}\n" + "param time time\n" + "param texture 0 watertexture\n" + "surfaceparm nodlight\n" + "{\n" + "map $diffuse\n" + "}\n" + "}\n" + ); + } + if (!builtin && !strncmp(shortname, "sky", 3)) + { + //q1 sky + if (r_fastsky.ival) + builtin = ( + "{\n" + "{\n" + "map $whiteimage\n" + "rgbgen $r_fastskycolour\n" + "}\n" + "}\n" + ); + else if (*r_skyboxname.string) + builtin = ( + "{\n" + "skyparms $r_skybox - -\n" + "}\n" + ); + else + builtin = ( + "{\n" + "program\n" + "{\n" + "#ifdef VERTEX_SHADER\n" + "varying vec3 pos;\n" + + "void main (void)\n" + "{\n" + " pos = gl_Vertex.xyz;\n" + " gl_Position = ftransform();\n" + "}\n" + "#endif\n" + + "#ifdef FRAGMENT_SHADER\n" + "uniform sampler2D solidt;\n" + "uniform sampler2D transt;\n" + + "uniform float time;\n" + "uniform vec3 eyepos;\n" + "varying vec3 pos;\n" + + "void main (void)\n" + "{\n" + " vec2 tccoord;\n" + + " vec3 dir = pos - eyepos;\n" + + " dir.z *= 3.0;\n" + " dir.xy /= 0.5*length(dir);\n" + + " tccoord = (dir.xy + time*0.03125);\n" + " vec3 solid = vec3(texture2D(solidt, tccoord));\n" + + " tccoord = (dir.xy + time*0.0625);\n" + " vec4 clouds = texture2D(transt, tccoord);\n" + + " gl_FragColor.rgb = (solid.rgb*(1.0-clouds.a)) + (clouds.a*clouds.rgb);\n" + // " gl_FragColor.rgb = solid.rgb;/*gl_FragColor.g = clouds.r;*/gl_FragColor.b = clouds.a;\n" + "}\n" + "#endif\n" + "}\n" + "param time time\n" + "param eyepos eyepos\n" + "param texture 0 solidt\n" + "param texture 1 transt\n" + "surfaceparm nodlight\n" + //"skyparms - 512 -\n" + "{\n" + "map $diffuse\n" + "}\n" + "{\n" + "map $fullbright\n" + "}\n" + "}\n" + ); + } + if (!builtin && *shortname == '{') + { + /*alpha test*/ + builtin = ( + "{\n" + /* "if $deluxmap\n" + "[\n" + "{\n" + "map $normalmap\n" + "tcgen base\n" + "}\n" + "{\n" + "map $deluxmap\n" + "tcgen lightmap\n" + "}\n" + "]\n"*/ + "{\n" + "map $diffuse\n" + "tcgen base\n" + "alphamask\n" + "}\n" + "if $lightmap\n" + "[\n" + "{\n" + "map $lightmap\n" + "blendfunc gl_dst_color gl_zero\n" + "depthfunc equal\n" + "}\n" + "]\n" + "{\n" + "map $fullbright\n" + "blendfunc add\n" + "depthfunc equal\n" + "}\n" + "}\n" + ); + } + + /*Hack: note that halflife would normally expect you to use rendermode/renderampt*/ + if (!builtin && (!strncmp(shortname, "glass", 5) || !strncmp(shortname, "window", 6))) + { + /*alpha bended*/ + builtin = ( + "{\n" + "{\n" + "map $diffuse\n" + "tcgen base\n" + "blendfunc blend\n" + "}\n" + "}\n" + ); + } + + if (!builtin && r_drawflat.value) + builtin = ( + "{\n" + "{\n" + "map $lightmap\n" + "tcgen lightmap\n" + "rgbgen const $r_floorcolour\n" + "}\n" + "}\n" + ); + + if (!builtin) + builtin = ( + "{\n" + "if $deluxmap\n" + "[\n" + "{\n" + "map $normalmap\n" + "tcgen base\n" + "}\n" + "{\n" + "map $deluxmap\n" + "tcgen lightmap\n" + "}\n" + "]\n" + "{\n" + "map $diffuse\n" + "tcgen base\n" + "}\n" + "if $lightmap\n" + "[\n" + "{\n" + "map $lightmap\n" + "blendfunc gl_dst_color gl_zero\n" + "}\n" + "]\n" + "{\n" + "map $fullbright\n" + "blendfunc add\n" + "depthfunc equal\n" + "}\n" + "}\n" + ); + + Shader_DefaultScript(shortname, s, builtin); +} + +void Shader_DefaultBSPVertex(char *shortname, shader_t *s, const void *args) { shaderpass_t *pass; pass = &s->passes[0]; pass->tcgen = TC_GEN_BASE; - pass->anim_frames[0] = Mod_LoadHiResTexture(shortname, NULL, true, false, true);//GL_FindImage (shortname, 0); - pass->depthfunc = GL_LEQUAL; - pass->flags = SHADER_PASS_DEPTHWRITE; + pass->anim_frames[0] = R_LoadHiResTexture(shortname, NULL, 0); + pass->shaderbits |= SBITS_MISC_DEPTHWRITE; pass->rgbgen = RGB_GEN_VERTEX; pass->alphagen = ALPHA_GEN_IDENTITY; - pass->blendmode = GL_MODULATE; pass->numMergedPasses = 1; - pass->flush = R_RenderMeshGeneric; + Shader_SetBlendmode(pass); - if ( !pass->anim_frames[0] ) { + if (!TEXVALID(pass->anim_frames[0])) + { Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", s->name, shortname ); pass->anim_frames[0] = missing_texture; } @@ -2323,28 +2567,26 @@ void Shader_DefaultBSPVertex(char *shortname, shader_t *s, void *args) s->numpasses = 1; s->numdeforms = 0; s->flags = SHADER_DEPTHWRITE|SHADER_CULL_FRONT; - s->features = MF_STCOORDS|MF_COLORS|MF_TRNORMALS; + s->features = MF_STCOORDS|MF_COLORS; s->sort = SHADER_SORT_OPAQUE; s->registration_sequence = 1;//fizme: registration_sequence; } -void Shader_DefaultBSPFlare(char *shortname, shader_t *s, void *args) +void Shader_DefaultBSPFlare(char *shortname, shader_t *s, const void *args) { shaderpass_t *pass; pass = &s->passes[0]; - pass->flags = SHADER_PASS_BLEND | SHADER_PASS_NOCOLORARRAY; - pass->blendsrc = GL_ONE; - pass->blenddst = GL_ONE; - pass->blendmode = GL_MODULATE; - pass->anim_frames[0] = Mod_LoadHiResTexture(shortname, NULL, true, true, true);//GL_FindImage (shortname, 0); - pass->depthfunc = GL_LEQUAL; + pass->flags = SHADER_PASS_NOCOLORARRAY; + pass->shaderbits |= SBITS_SRCBLEND_ONE|SBITS_DSTBLEND_ONE; + pass->anim_frames[0] = R_LoadHiResTexture(shortname, NULL, 0); pass->rgbgen = RGB_GEN_VERTEX; pass->alphagen = ALPHA_GEN_IDENTITY; pass->numtcmods = 0; pass->tcgen = TC_GEN_BASE; pass->numMergedPasses = 1; - pass->flush = R_RenderMeshGeneric; + Shader_SetBlendmode(pass); - if ( !pass->anim_frames[0] ) { + if (!TEXVALID(pass->anim_frames[0])) + { Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", s->name, shortname ); pass->anim_frames[0] = missing_texture; } @@ -2356,129 +2598,48 @@ void Shader_DefaultBSPFlare(char *shortname, shader_t *s, void *args) s->sort = SHADER_SORT_ADDITIVE; s->registration_sequence = 1;//fizme: registration_sequence; } -void Shader_DefaultSkin(char *shortname, shader_t *s, void *args) +void Shader_DefaultSkin(char *shortname, shader_t *s, const void *args) { - int tex; - shaderpass_t *pass; - - s->numpasses = 0; - - tex = Mod_LoadHiResTexture(shortname, NULL, true, true, true); - if (!tex) - tex = missing_texture; -// if (tex) - { - pass = &s->passes[s->numpasses++]; - pass->flags = SHADER_PASS_DEPTHWRITE; - pass->anim_frames[0] = tex; - pass->depthfunc = GL_LEQUAL; - pass->rgbgen = RGB_GEN_LIGHTING_DIFFUSE; - pass->numtcmods = 0; - pass->tcgen = TC_GEN_BASE; - pass->blendsrc = GL_SRC_ALPHA; - pass->blenddst = GL_ONE_MINUS_SRC_ALPHA; - pass->blendmode = GL_MODULATE; - pass->numMergedPasses = 1; - pass->flush = R_RenderMeshGeneric; - if (!pass->anim_frames[0]) - { - Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", s->name, shortname ); - pass->anim_frames[0] = missing_texture; - } - } -/* - tex = Mod_LoadHiResTexture(va("%s_shirt", shortname), NULL, true, true, true); - if (tex) - { - pass = &s->passes[s->numpasses++]; - pass->flags = SHADER_PASS_BLEND; - pass->anim_frames[0] = tex; - pass->depthfunc = GL_EQUAL; - pass->rgbgen = RGB_GEN_TOPCOLOR; - pass->numtcmods = 0; - pass->tcgen = TC_GEN_BASE; - pass->blendsrc = GL_ONE; - pass->blenddst = GL_ONE; - pass->blendmode = GL_MODULATE; - pass->numMergedPasses = 1; - pass->flush = R_RenderMeshGeneric; - if (!pass->anim_frames[0]) - { - Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", s->name, shortname ); - pass->anim_frames[0] = missing_texture; - } - } - - tex = Mod_LoadHiResTexture(va("%s_pants", shortname), NULL, true, true, true); - if (tex) - { - pass = &s->passes[s->numpasses++]; - pass->flags = SHADER_PASS_BLEND; - pass->anim_frames[0] = tex; - pass->depthfunc = GL_EQUAL; - pass->rgbgen = RGB_GEN_BOTTOMCOLOR; - pass->numtcmods = 0; - pass->tcgen = TC_GEN_BASE; - pass->blendsrc = GL_ONE; - pass->blenddst = GL_ONE; - pass->blendmode = GL_MODULATE; - pass->numMergedPasses = 1; - pass->flush = R_RenderMeshGeneric; - if (!pass->anim_frames[0]) - { - Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", s->name, shortname ); - pass->anim_frames[0] = missing_texture; - } - } -*/ - tex = Mod_LoadHiResTexture(va("%s_glow", shortname), NULL, true, true, true); - if (tex) - { - pass = &s->passes[s->numpasses++]; - pass->flags = SHADER_PASS_BLEND; - pass->anim_frames[0] = tex; - pass->depthfunc = GL_EQUAL; - pass->rgbgen = RGB_GEN_LIGHTING_DIFFUSE; - pass->numtcmods = 0; - pass->tcgen = TC_GEN_BASE; - pass->blendsrc = GL_ONE; - pass->blenddst = GL_ONE; - pass->blendmode = GL_MODULATE; - pass->numMergedPasses = 1; - pass->flush = R_RenderMeshGeneric; - if (!pass->anim_frames[0]) - { - Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", s->name, shortname); - pass->anim_frames[0] = missing_texture; - } - } - - s->numdeforms = 0; - s->flags = SHADER_DEPTHWRITE|SHADER_CULL_FRONT; - s->features = MF_STCOORDS|MF_NORMALS; - s->sort = SHADER_SORT_OPAQUE; - s->registration_sequence = 1;//fizme: registration_sequence; + Shader_DefaultScript(shortname, s, + "{\n" + "{\n" + "map $diffuse\n" + "rgbgen lightingDiffuse\n" + "}\n" + "{\n" + "map $loweroverlay\n" + "rgbgen bottomcolor\n" + "}\n" + "{\n" + "map $upperoverlay\n" + "rgbgen uppercolor\n" + "}\n" + "{\n" + "map $fullbright\n" + "blendfunc add\n" + "}\n" + "}\n" + ); } -void Shader_DefaultSkinShell(char *shortname, shader_t *s, void *args) +void Shader_DefaultSkinShell(char *shortname, shader_t *s, const void *args) { shaderpass_t *pass; pass = &s->passes[0]; - pass->flags = SHADER_PASS_DEPTHWRITE | SHADER_PASS_BLEND; - pass->anim_frames[0] = Mod_LoadHiResTexture(shortname, NULL, true, true, true);//GL_FindImage (shortname, 0); - if (!pass->anim_frames[0]) + pass->shaderbits |= SBITS_MISC_DEPTHWRITE; + pass->anim_frames[0] = R_LoadHiResTexture(shortname, NULL, 0); + if (!TEXVALID(pass->anim_frames[0])) pass->anim_frames[0] = missing_texture; - pass->depthfunc = GL_LEQUAL; pass->rgbgen = RGB_GEN_ENTITY; pass->alphagen = ALPHA_GEN_ENTITY; pass->numtcmods = 0; pass->tcgen = TC_GEN_BASE; - pass->blendsrc = GL_SRC_ALPHA; - pass->blenddst = GL_ONE_MINUS_SRC_ALPHA; - pass->blendmode = GL_MODULATE; + pass->shaderbits |= SBITS_SRCBLEND_SRC_ALPHA; + pass->shaderbits |= SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA; pass->numMergedPasses = 1; - pass->flush = R_RenderMeshGeneric; + Shader_SetBlendmode(pass); - if ( !pass->anim_frames[0] ) { + if (!TEXVALID(pass->anim_frames[0])) + { Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", s->name, shortname ); pass->anim_frames[0] = missing_texture; } @@ -2490,35 +2651,25 @@ void Shader_DefaultSkinShell(char *shortname, shader_t *s, void *args) s->sort = SHADER_SORT_OPAQUE; s->registration_sequence = 1;//fizme: registration_sequence; } -void Shader_Default2D(char *shortname, shader_t *s, void *genargs) +void Shader_Default2D(char *shortname, shader_t *s, const void *genargs) { - mpic_t *mp; - shaderpass_t *pass; pass = &s->passes[0]; - pass->flags = SHADER_PASS_BLEND | SHADER_PASS_NOCOLORARRAY; - pass->blendsrc = GL_SRC_ALPHA; - pass->blenddst = GL_ONE_MINUS_SRC_ALPHA; - pass->blendmode = GL_MODULATE; - pass->anim_frames[0] = Mod_LoadHiResTexture(shortname, NULL, false, true, true);//GL_FindImage (shortname, IT_NOPICMIP|IT_NOMIPMAP); - if (!pass->anim_frames[0]) - { - mp = Draw_SafeCachePic(va("%s.lmp", shortname)); - if (mp) - pass->anim_frames[0] = mp->d.gl.texnum; - - if (!pass->anim_frames[0]) - pass->anim_frames[0] = missing_texture; - } - pass->depthfunc = GL_LEQUAL; + pass->flags = SHADER_PASS_NOCOLORARRAY; + pass->shaderbits |= SBITS_SRCBLEND_SRC_ALPHA; + pass->shaderbits |= SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA; + pass->anim_frames[0] = R_LoadHiResTexture(shortname, NULL, IF_NOPICMIP|IF_NOMIPMAP); + s->width = image_width; + s->height = image_height; pass->rgbgen = RGB_GEN_VERTEX; pass->alphagen = ALPHA_GEN_VERTEX; pass->numtcmods = 0; pass->tcgen = TC_GEN_BASE; pass->numMergedPasses = 1; - pass->flush = R_RenderMeshGeneric; + Shader_SetBlendmode(pass); - if ( !pass->anim_frames[0] ) { + if (!TEXVALID(pass->anim_frames[0])) + { Con_DPrintf (CON_WARNING "Shader %s has a stage with no image: %s.\n", s->name, shortname ); pass->anim_frames[0] = missing_texture; } @@ -2531,6 +2682,52 @@ void Shader_Default2D(char *shortname, shader_t *s, void *genargs) s->registration_sequence = 1;//fizme: registration_sequence; } +//loads a shader string into an existing shader object, and finalises it and stuff +static void Shader_ReadShader(shader_t *s, char *shadersource) +{ + char *token; + +// set defaults + s->flags = SHADER_CULL_FRONT; + s->registration_sequence = 1;//fizme: registration_sequence; + + while (shadersource) + { + token = COM_ParseExt (&shadersource, true); + + if ( !token[0] ) + continue; + else if ( token[0] == '}' ) + break; + else if (!Q_stricmp(token, "if")) + { + qboolean conditionistrue = Shader_EvaluateCondition(&shadersource); + + while (shadersource) + { + token = COM_ParseExt (&shadersource, true); + if ( !token[0] ) + continue; + else if (token[0] == ']') + break; + else if (conditionistrue) + { + if (token[0] == '{') + Shader_Readpass (s, &shadersource); + else + Shader_Parsetok (s, NULL, shaderkeys, token, &shadersource); + } + } + } + else if ( token[0] == '{' ) + Shader_Readpass ( s, &shadersource ); + else if ( Shader_Parsetok (s, NULL, shaderkeys, token, &shadersource ) ) + break; + } + + Shader_Finish ( s ); +} + qboolean Shader_ParseShader(char *shortname, char *usename, shader_t *s) { unsigned int offset = 0, length; @@ -2561,35 +2758,11 @@ qboolean Shader_ParseShader(char *shortname, char *usename, shader_t *s) return false; } - + Shader_Free(s); memset ( s, 0, sizeof( shader_t ) ); - Com_sprintf ( s->name, MAX_QPATH, usename ); - // set defaults - s->flags = SHADER_CULL_FRONT; - s->registration_sequence = 1;//fizme: registration_sequence; - -// if (!strcmp(COM_FileExtension(ts), "rscript")) -// { -// Shader_DefaultBSP(shortname, s); -// } - - while ( file ) - { - token = COM_ParseExt (&file, true); - - if ( !token[0] ) - continue; - else if ( token[0] == '}' ) - break; - else if ( token[0] == '{' ) - Shader_Readpass ( s, &file ); - else if ( Shader_Parsetok (s, NULL, shaderkeys, token, &file ) ) - break; - } - - Shader_Finish ( s ); + Shader_ReadShader(s, file); FS_FreeFile(buf); return true; @@ -2601,7 +2774,7 @@ qboolean Shader_ParseShader(char *shortname, char *usename, shader_t *s) return false; } -int R_LoadShader ( char *name, void(*defaultgen)(char *name, shader_t*, void *args), void *genargs) +int R_LoadShader ( char *name, shader_gen_t *defaultgen, const char *genargs) { int i, f = -1; char shortname[MAX_QPATH]; @@ -2614,7 +2787,7 @@ int R_LoadShader ( char *name, void(*defaultgen)(char *name, shader_t*, void *ar // test if already loaded for (i = 0; i < MAX_SHADERS; i++) { - if (!r_shaders[i].registration_sequence) + if (!r_shaders[i].generator) { if ( f == -1 ) // free shader f = i; @@ -2636,19 +2809,34 @@ int R_LoadShader ( char *name, void(*defaultgen)(char *name, shader_t*, void *ar s = &r_shaders[f]; - if (gl_config.arb_shader_objects) + if (ruleset_allow_shaders.ival) { - if (Shader_ParseShader(va("%s_glsl", shortname), shortname, s)) +#ifdef GLQUAKE + if (qrenderer == QR_OPENGL && gl_config.arb_shader_objects) + { + if (Shader_ParseShader(va("%s_glsl", shortname), shortname, s)) + { + s->generator = defaultgen; + s->genargs = genargs; + return f; + } + } +#endif + if (Shader_ParseShader(shortname, shortname, s)) + { + s->generator = defaultgen; + s->genargs = genargs; return f; + } } - if (Shader_ParseShader(shortname, shortname, s)) - return f; // make a default shader if (defaultgen) { memset ( s, 0, sizeof( shader_t ) ); + s->generator = defaultgen; + s->genargs = genargs; Com_sprintf ( s->name, MAX_QPATH, shortname ); defaultgen(shortname, s, genargs); @@ -2657,8 +2845,75 @@ int R_LoadShader ( char *name, void(*defaultgen)(char *name, shader_t*, void *ar return -1; } +void Shader_DoReload(void) +{ + shader_t *s; + unsigned int i; + char shortname[MAX_QPATH]; + shader_gen_t *defaultgen; + const char *genargs; + texnums_t oldtn; + + if (!shader_reload_needed) + return; + shader_reload_needed = false; + Con_Printf("Reloading all shaders\n"); + + for (s = r_shaders, i = 0; i < MAX_SHADERS; i++, s++) + { + if (!s->generator) + continue; + + defaultgen = s->generator; + genargs = s->genargs; + oldtn = s->defaulttextures; + + strcpy(shortname, s->name); + if (ruleset_allow_shaders.ival) + { +#ifdef GLQUAKE + if (qrenderer == QR_OPENGL && gl_config.arb_shader_objects) + { + if (Shader_ParseShader(va("%s_glsl", shortname), shortname, s)) + { + s->generator = defaultgen; + s->genargs = genargs; + R_BuildDefaultTexnums(&oldtn, s); + continue; + } + } +#endif + if (Shader_ParseShader(shortname, shortname, s)) + { + s->generator = defaultgen; + s->genargs = genargs; + R_BuildDefaultTexnums(&oldtn, s); + continue; + } + } + if (s->generator) + { + Shader_Free(s); + memset ( s, 0, sizeof( shader_t ) ); + s->generator = defaultgen; + s->genargs = genargs; + Com_sprintf ( s->name, MAX_QPATH, shortname ); + s->generator(shortname, s, s->genargs); + R_BuildDefaultTexnums(&oldtn, s); + } + } +} + +void Shader_NeedReload(void) +{ + shader_reload_needed = true; +} + cin_t *R_ShaderGetCinematic(char *name) { +#ifdef NOMEDIA + return NULL; +#else int i, j; char shortname[MAX_QPATH]; shader_t *s; @@ -2687,6 +2942,7 @@ cin_t *R_ShaderGetCinematic(char *name) //but it has no cinematic passes. return NULL; +#endif } shader_t *R_RegisterPic (char *name) @@ -2694,7 +2950,12 @@ shader_t *R_RegisterPic (char *name) return &r_shaders[R_LoadShader (name, Shader_Default2D, NULL)]; } -shader_t *R_RegisterShader (char *name) +shader_t *R_RegisterShader (char *name, const char *shaderscript) +{ + return &r_shaders[R_LoadShader (name, Shader_DefaultScript, shaderscript)]; +} + +shader_t *R_RegisterShader_Lightmap (char *name) { return &r_shaders[R_LoadShader (name, Shader_DefaultBSP, NULL)]; } @@ -2713,7 +2974,7 @@ shader_t *R_RegisterSkin (char *name) { return &r_shaders[R_LoadShader (name, Shader_DefaultSkin, NULL)]; } -shader_t *R_RegisterCustom (char *name, void(*defaultgen)(char *name, shader_t*, void *args), void *args) +shader_t *R_RegisterCustom (char *name, shader_gen_t *defaultgen, const void *args) { int i; i = R_LoadShader (name, defaultgen, args); @@ -2721,5 +2982,4 @@ shader_t *R_RegisterCustom (char *name, void(*defaultgen)(char *name, shader_t*, return NULL; return &r_shaders[i]; } -#endif - +#endif //SERVERONLY diff --git a/engine/gl/gl_shadow.c b/engine/gl/gl_shadow.c new file mode 100644 index 00000000..9c5d1a92 --- /dev/null +++ b/engine/gl/gl_shadow.c @@ -0,0 +1,2321 @@ +#include "quakedef.h" + +#ifdef GLQUAKE +#ifdef RTLIGHTS + +#include "glquake.h" +#include "shader.h" + +#define lradius l->radius +#define nearplane (16) + +#if 0//def _DEBUG +#define checkerror() if (qglGetError()) Con_Printf("Error detected at line %s:%i\n", __FILE__, __LINE__) +#else +#define checkerror() +#endif + +static void Sh_DrawEntLighting(dlight_t *light, vec3_t colour); + + +struct { + int numlights; + int shadowsurfcount; + + int numfrustumculled; + int numpvsculled; + int numscissorculled; +} bench; + + + + + + + + +typedef struct { + unsigned int count; + unsigned int max; + msurface_t **s; +} shadowmeshsurfs_t; +typedef struct shadowmesh_s { + unsigned int numindicies; + unsigned int maxindicies; + index_t *indicies; + + unsigned int numverts; + unsigned int maxverts; + vecV_t *verts; + + //we also have a list of all the surfaces that this light lights. + unsigned int numsurftextures; + shadowmeshsurfs_t *litsurfs; + + unsigned int leafbytes; + unsigned char *litleaves; +} shadowmesh_t; + +/*state of the current shadow mesh*/ +#define inc 128 +int sh_shadowframe; +static int sh_type; +static int sh_firstindex; +static int sh_vertnum; //vertex number (set to 0 at SH_Begin) +static shadowmesh_t *sh_shmesh, sh_tempshmesh; + +/* functions to add geometry to the shadow mesh */ +static void SHM_Begin (GLenum e) +{ + sh_type = e; + sh_firstindex = sh_shmesh->numverts; +} +static void SHM_End (void) +{ + int i; + int v1, v2; + switch(sh_type) + { + case GL_POLYGON: + i = (sh_shmesh->numindicies+(sh_vertnum-2)*3+inc+5)&~(inc-1); //and a bit of padding + if (sh_shmesh->maxindicies != i) + { + sh_shmesh->maxindicies = i; + sh_shmesh->indicies = BZ_Realloc(sh_shmesh->indicies, i * sizeof(*sh_shmesh->indicies)); + } + //decompose the poly into a triangle fan. + v1 = sh_firstindex + 0; + v2 = sh_firstindex + 1; + for (i = 2; i < sh_vertnum; i++) + { + sh_shmesh->indicies[sh_shmesh->numindicies++] = v1; + sh_shmesh->indicies[sh_shmesh->numindicies++] = v2; + sh_shmesh->indicies[sh_shmesh->numindicies++] = v2 = sh_firstindex + i; + } + sh_vertnum = 0; + break; + case GL_TRIANGLES: + i = (sh_shmesh->numindicies+(sh_vertnum)+inc+5)&~(inc-1); //and a bit of padding + if (sh_shmesh->maxindicies != i) + { + sh_shmesh->maxindicies = i; + sh_shmesh->indicies = BZ_Realloc(sh_shmesh->indicies, i * sizeof(*sh_shmesh->indicies)); + } + //add the extra triangles + for (i = 0; i < sh_vertnum; i+=3) + { + sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+0; + sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+1; + sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+2; + } + sh_vertnum = 0; + break; + case GL_QUADS: + i = (sh_shmesh->numindicies+(sh_vertnum/4)*6+inc+5)&~(inc-1); //and a bit of padding + if (sh_shmesh->maxindicies != i) + { + sh_shmesh->maxindicies = i; + sh_shmesh->indicies = BZ_Realloc(sh_shmesh->indicies, i * sizeof(*sh_shmesh->indicies)); + } + //add the extra triangles + for (i = 0; i < sh_vertnum; i+=4) + { + sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+0; + sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+1; + sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+2; + + sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+0; + sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+2; + sh_shmesh->indicies[sh_shmesh->numindicies++] = sh_firstindex + i+3; + } + sh_vertnum = 0; + break; + default: + if (sh_vertnum) + Sys_Error("SH_End: verticies were left"); + } +} +static void SHM_Vertex3f (GLfloat x, GLfloat y, GLfloat z) +{ + int i; + +//add the verts as we go + i = (sh_shmesh->numverts+inc+5)&~(inc-1); //and a bit of padding + if (sh_shmesh->maxverts != i) + { + sh_shmesh->maxverts = i; + sh_shmesh->verts = BZ_Realloc(sh_shmesh->verts, i * sizeof(*sh_shmesh->verts)); + } + + sh_shmesh->verts[sh_shmesh->numverts][0] = x; + sh_shmesh->verts[sh_shmesh->numverts][1] = y; + sh_shmesh->verts[sh_shmesh->numverts][2] = z; + + sh_vertnum++; + sh_shmesh->numverts++; + + switch(sh_type) + { + case GL_POLYGON: + break; + case GL_TRIANGLES: + if (sh_vertnum == 3) + { + SHM_End(); + sh_firstindex = sh_shmesh->numverts; + } + break; + case GL_QUADS: + if (sh_vertnum == 4) + { + SHM_End(); + sh_firstindex = sh_shmesh->numverts; + } + break; + default: + Sys_Error("SH_Vertex3f: bad type"); + } +} +static void APIENTRY SHM_Vertex3fv (const GLfloat *v) +{ + SHM_Vertex3f(v[0], v[1], v[2]); +} + +static void SHM_Shadow_Cache_Surface(msurface_t *surf) +{ + int i; + +#pragma message("Remove this loop ffs!") + for (i = 0; i < cl.worldmodel->numtextures; i++) + { + if (surf->texinfo->texture == cl.worldmodel->textures[i]) + { + if (sh_shmesh->litsurfs[i].count == sh_shmesh->litsurfs[i].max) + { + sh_shmesh->litsurfs[i].max += 64; + sh_shmesh->litsurfs[i].s = BZ_Realloc(sh_shmesh->litsurfs[i].s, sizeof(void*)*(sh_shmesh->litsurfs[i].max)); + } + sh_shmesh->litsurfs[i].s[sh_shmesh->litsurfs[i].count] = surf; + sh_shmesh->litsurfs[i].count++; + break; + } + } +} + +static void SHM_Shadow_Cache_Leaf(mleaf_t *leaf) +{ + int i; + + i = leaf - cl.worldmodel->leafs; + sh_shmesh->litleaves[i>>3] |= 1<<(i&7); +} + +static void SHM_BeginShadowMesh(dlight_t *dl) +{ + unsigned int i; + sh_vertnum = 0; + + if (!dl->die) + { + sh_shmesh = Z_Malloc(sizeof(*sh_shmesh) + (cl.worldmodel->numleafs+7)/8); + sh_shmesh->leafbytes = (cl.worldmodel->numleafs+7)/8; + sh_shmesh->litleaves = (unsigned char*)(sh_shmesh+1); + + dl->worldshadowmesh = sh_shmesh; + } + else + { + unsigned int lb; +//FIXME: many dynamic lights are static. cache for a frame and see if it can be reused. + sh_shmesh = &sh_tempshmesh; + lb = (cl.worldmodel->numleafs+7)/8; + if (sh_shmesh->leafbytes != lb) + { + sh_shmesh->leafbytes = lb; + Z_Free(sh_shmesh->litleaves); + sh_shmesh->litleaves = Z_Malloc(lb); + } + } + sh_shmesh->maxverts = 0; + sh_shmesh->numverts = 0; + sh_shmesh->maxindicies = 0; + sh_shmesh->numindicies = 0; + + if (sh_shmesh->numsurftextures < cl.worldmodel->numtextures) + { + if (sh_shmesh->litsurfs) + { + for (i = 0; i < sh_shmesh->numsurftextures; i++) + Z_Free(sh_shmesh->litsurfs[i].s); + Z_Free(sh_shmesh->litsurfs); + } + sh_shmesh->litsurfs = Z_Malloc(sizeof(shadowmeshsurfs_t)*cl.worldmodel->numtextures); + sh_shmesh->numsurftextures=cl.worldmodel->numtextures; + } + else + { + for (i = 0; i < sh_shmesh->numsurftextures; i++) + sh_shmesh->litsurfs[i].count = 0; + } +} +static struct shadowmesh_s *SHM_FinishShadowMesh(dlight_t *dl) +{ + return sh_shmesh; +} + + +/*state of the world that is still to compile*/ +static struct { + short count; + short count2; + int next; + int prev; +} edge[MAX_MAP_EDGES]; +static int firstedge; + +static void SHM_RecursiveWorldNodeQ1_r (dlight_t *dl, mnode_t *node) +{ + int c, side; + mplane_t *plane; + msurface_t *surf, **mark; + mleaf_t *pleaf; + double dot; + int v; + + float *v1; + vec3_t v3; + + float l, maxdist; + int j, s, t; + vec3_t impact; + + if (node->shadowframe != sh_shadowframe) + return; + + if (node->contents == Q1CONTENTS_SOLID) + return; // solid + + + //if light areabox is outside node, ignore node + children + for (c = 0; c < 3; c++) + { + if (dl->origin[c] + dl->radius < node->minmaxs[c]) + return; + if (dl->origin[c] - dl->radius > node->minmaxs[3+c]) + return; + } + +// if a leaf node, draw stuff + if (node->contents < 0) + { + pleaf = (mleaf_t *)node; + SHM_Shadow_Cache_Leaf(pleaf); + + mark = pleaf->firstmarksurface; + c = pleaf->nummarksurfaces; + + if (c) + { + do + { + (*mark++)->shadowframe = sh_shadowframe; + } while (--c); + } + return; + } + +// node is just a decision point, so go down the apropriate sides + +// find which side of the node we are on + plane = node->plane; + + switch (plane->type) + { + case PLANE_X: + dot = dl->origin[0] - plane->dist; + break; + case PLANE_Y: + dot = dl->origin[1] - plane->dist; + break; + case PLANE_Z: + dot = dl->origin[2] - plane->dist; + break; + default: + dot = DotProduct (dl->origin, plane->normal) - plane->dist; + break; + } + + if (dot >= 0) + side = 0; + else + side = 1; + +// recurse down the children, front side first + SHM_RecursiveWorldNodeQ1_r (dl, node->children[side]); + +// draw stuff + c = node->numsurfaces; + + if (c) + { + surf = cl.worldmodel->surfaces + node->firstsurface; + + { + + maxdist = dl->radius*dl->radius; + + for ( ; c ; c--, surf++) + { + if (surf->shadowframe != sh_shadowframe) + continue; + +// if ((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK)) +// continue; // wrong side + +// if (surf->flags & SURF_PLANEBACK) +// continue; + + if (surf->flags & (SURF_DRAWALPHA | SURF_DRAWTILED)) + { // no shadows + continue; + } + + //is the light on the right side? + if (surf->flags & SURF_PLANEBACK) + {//inverted normal. + if (-DotProduct(surf->plane->normal, dl->origin)+surf->plane->dist >= dl->radius) + continue; + } + else + { + if (DotProduct(surf->plane->normal, dl->origin)-surf->plane->dist >= dl->radius) + continue; + } + + //Yeah, you can blame LordHavoc for this alternate code here. + for (j=0 ; j<3 ; j++) + impact[j] = dl->origin[j] - surf->plane->normal[j]*dot; + + // clamp center of light to corner and check brightness + l = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0]; + s = l+0.5;if (s < 0) s = 0;else if (s > surf->extents[0]) s = surf->extents[0]; + s = l - s; + l = DotProduct (impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1]; + t = l+0.5;if (t < 0) t = 0;else if (t > surf->extents[1]) t = surf->extents[1]; + t = l - t; + // compare to minimum light + if ((s*s+t*t+dot*dot) < maxdist) + { + SHM_Shadow_Cache_Surface(surf); + + + + #define PROJECTION_DISTANCE (float)(dl->radius*2)//0x7fffffff + + //build a list of the edges that are to be drawn. + for (v = 0; v < surf->numedges; v++) + { + int e, delta; + e = cl.worldmodel->surfedges[surf->firstedge+v]; + //negative edge means backwards edge. + if (e < 0) + { + e=-e; + delta = -1; + } + else + { + delta = 1; + } + + if (!edge[e].count) + { + if (firstedge) + edge[firstedge].prev = e; + edge[e].next = firstedge; + edge[e].prev = 0; + firstedge = e; + edge[e].count = delta; + } + else + { + edge[e].count += delta; + + if (!edge[e].count) //unlink + { + if (edge[e].next) + { + edge[edge[e].next].prev = edge[e].prev; + } + if (edge[e].prev) + edge[edge[e].prev].next = edge[e].next; + else + firstedge = edge[e].next; + } + } + } + + //fixme:this only works becuse q1bsps don't have combined meshes yet... + SHM_Begin(GL_POLYGON); + for (v = 0; v < surf->mesh->numvertexes; v++) + { + SHM_Vertex3fv(surf->mesh->xyz_array[v]); + } + SHM_End(); + + //back (depth precision doesn't matter) + SHM_Begin(GL_POLYGON); + for (v = surf->mesh->numvertexes-1; v >=0; v--) + { + v1 = surf->mesh->xyz_array[v]; + v3[0] = ( v1[0]-dl->origin[0] )*PROJECTION_DISTANCE; + v3[1] = ( v1[1]-dl->origin[1] )*PROJECTION_DISTANCE; + v3[2] = ( v1[2]-dl->origin[2] )*PROJECTION_DISTANCE; + + SHM_Vertex3f( v1[0]+v3[0], v1[1]+v3[1], v1[2]+v3[2] ); + } + SHM_End(); + } + } + } + } + +// recurse down the back side + SHM_RecursiveWorldNodeQ1_r (dl, node->children[!side]); +} + +static void SHM_RecursiveWorldNodeQ2_r (dlight_t *dl, mnode_t *node) +{ + int c, side; + mplane_t *plane; + msurface_t *surf, **mark; + mleaf_t *pleaf; + double dot; + int v; + + float *v1; + vec3_t v3; + + float l, maxdist; + int j, s, t; + vec3_t impact; + + if (node->shadowframe != sh_shadowframe) + return; + + if (node->contents == Q2CONTENTS_SOLID) + return; // solid + + + //if light areabox is outside node, ignore node + children + for (c = 0; c < 3; c++) + { + if (dl->origin[c] + dl->radius < node->minmaxs[c]) + return; + if (dl->origin[c] - dl->radius > node->minmaxs[3+c]) + return; + } + +// if a leaf node, draw stuff + if (node->contents != -1) + { + pleaf = (mleaf_t *)node; + SHM_Shadow_Cache_Leaf(pleaf); + + mark = pleaf->firstmarksurface; + c = pleaf->nummarksurfaces; + + if (c) + { + do + { + (*mark++)->shadowframe = sh_shadowframe; + } while (--c); + } + return; + } + +// node is just a decision point, so go down the apropriate sides + +// find which side of the node we are on + plane = node->plane; + + switch (plane->type) + { + case PLANE_X: + dot = dl->origin[0] - plane->dist; + break; + case PLANE_Y: + dot = dl->origin[1] - plane->dist; + break; + case PLANE_Z: + dot = dl->origin[2] - plane->dist; + break; + default: + dot = DotProduct (dl->origin, plane->normal) - plane->dist; + break; + } + + if (dot >= 0) + side = 0; + else + side = 1; + +// recurse down the children, front side first + SHM_RecursiveWorldNodeQ2_r (dl, node->children[side]); + +// draw stuff + c = node->numsurfaces; + + if (c) + { + surf = cl.worldmodel->surfaces + node->firstsurface; + + { + + maxdist = dl->radius*dl->radius; + + for ( ; c ; c--, surf++) + { + if (surf->shadowframe != sh_shadowframe) + continue; + +// if ((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK)) +// continue; // wrong side + +// if (surf->flags & SURF_PLANEBACK) +// continue; + + if (surf->flags & (SURF_DRAWALPHA | SURF_DRAWTILED)) + { // no shadows + continue; + } + + //is the light on the right side? + if (surf->flags & SURF_PLANEBACK) + {//inverted normal. + if (-DotProduct(surf->plane->normal, dl->origin)+surf->plane->dist >= dl->radius) + continue; + } + else + { + if (DotProduct(surf->plane->normal, dl->origin)-surf->plane->dist >= dl->radius) + continue; + } + + //Yeah, you can blame LordHavoc for this alternate code here. + for (j=0 ; j<3 ; j++) + impact[j] = dl->origin[j] - surf->plane->normal[j]*dot; + + // clamp center of light to corner and check brightness + l = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0]; + s = l+0.5;if (s < 0) s = 0;else if (s > surf->extents[0]) s = surf->extents[0]; + s = l - s; + l = DotProduct (impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1]; + t = l+0.5;if (t < 0) t = 0;else if (t > surf->extents[1]) t = surf->extents[1]; + t = l - t; + // compare to minimum light + if ((s*s+t*t+dot*dot) < maxdist) + { + SHM_Shadow_Cache_Surface(surf); + + + + #define PROJECTION_DISTANCE (float)(dl->radius*2)//0x7fffffff + + //build a list of the edges that are to be drawn. + for (v = 0; v < surf->numedges; v++) + { + int e, delta; + e = cl.worldmodel->surfedges[surf->firstedge+v]; + //negative edge means backwards edge. + if (e < 0) + { + e=-e; + delta = -1; + } + else + { + delta = 1; + } + + if (!edge[e].count) + { + if (firstedge) + edge[firstedge].prev = e; + edge[e].next = firstedge; + edge[e].prev = 0; + firstedge = e; + edge[e].count = delta; + } + else + { + edge[e].count += delta; + + if (!edge[e].count) //unlink + { + if (edge[e].next) + { + edge[edge[e].next].prev = edge[e].prev; + } + if (edge[e].prev) + edge[edge[e].prev].next = edge[e].next; + else + firstedge = edge[e].next; + } + } + } + + SHM_Begin(GL_POLYGON); + for (v = 0; v < surf->mesh->numvertexes; v++) + { + SHM_Vertex3fv(surf->mesh->xyz_array[v]); + } + SHM_End(); + + //back (depth precision doesn't matter) + SHM_Begin(GL_POLYGON); + for (v = surf->mesh->numvertexes-1; v >=0; v--) + { + v1 = surf->mesh->xyz_array[v]; + v3[0] = ( v1[0]-dl->origin[0] )*PROJECTION_DISTANCE; + v3[1] = ( v1[1]-dl->origin[1] )*PROJECTION_DISTANCE; + v3[2] = ( v1[2]-dl->origin[2] )*PROJECTION_DISTANCE; + + SHM_Vertex3f( v1[0]+v3[0], v1[1]+v3[1], v1[2]+v3[2] ); + } + SHM_End(); + } + } + } + } + +// recurse down the back side + SHM_RecursiveWorldNodeQ2_r (dl, node->children[!side]); +} + +#ifdef Q2BSPS +static void SHM_MarkLeavesQ2(dlight_t *dl, unsigned char *lvis, unsigned char *vvis) +{ + mnode_t *node; + int i; + mleaf_t *leaf; + int cluster; + sh_shadowframe++; + + if (!dl->die) + { + //static + //variation on mark leaves + for (i=0,leaf=cl.worldmodel->leafs ; inumleafs ; i++, leaf++) + { + cluster = leaf->cluster; + if (cluster == -1) + continue; + if (lvis[cluster>>3] & (1<<(cluster&7)))// && vvis[cluster>>3] & (1<<(cluster&7))) + { + node = (mnode_t *)leaf; + do + { + if (node->shadowframe == sh_shadowframe) + break; + node->shadowframe = sh_shadowframe; + node = node->parent; + } while (node); + } + } + } + else + { + //dynamic lights will be discarded after this frame anyway, so only include leafs that are visible + //variation on mark leaves + for (i=0,leaf=cl.worldmodel->leafs ; inumleafs ; i++, leaf++) + { + cluster = leaf->cluster; + if (cluster == -1) + continue; + if (lvis[cluster>>3] & vvis[cluster>>3] & (1<<(cluster&7))) + { + node = (mnode_t *)leaf; + do + { + if (node->shadowframe == sh_shadowframe) + break; + node->shadowframe = sh_shadowframe; + node = node->parent; + } while (node); + } + } + } +} +#endif + +static void SHM_MarkLeavesQ1(dlight_t *dl, unsigned char *lvis, unsigned char *vvis) +{ + mnode_t *node; + int i; + sh_shadowframe++; + + if (!dl->die || !vvis) + { + //static + //variation on mark leaves + for (i=0 ; inumleafs ; i++) + { + if (lvis[i>>3] & (1<<(i&7)))// && vvis[i>>3] & (1<<(i&7))) + { + node = (mnode_t *)&cl.worldmodel->leafs[i+1]; + do + { + if (node->shadowframe == sh_shadowframe) + break; + node->shadowframe = sh_shadowframe; + node = node->parent; + } while (node); + } + } + } + else + { + //dynamic lights will be discarded after this frame anyway, so only include leafs that are visible + //variation on mark leaves + for (i=0 ; inumleafs ; i++) + { + if (lvis[i>>3] & vvis[i>>3] & (1<<(i&7))) + { + node = (mnode_t *)&cl.worldmodel->leafs[i+1]; + do + { + if (node->shadowframe == sh_shadowframe) + break; + node->shadowframe = sh_shadowframe; + node = node->parent; + } while (node); + } + } + } +} + +#ifdef Q3BSPS +void SHM_RecursiveWorldNodeQ3_r (dlight_t *dl, mnode_t *node) +{ + mplane_t *splitplane; + float dist; + msurface_t **msurf; + msurface_t *surf; + mleaf_t *leaf; + int i; + + if (node->contents != -1) + { + leaf = (mleaf_t *)node; + SHM_Shadow_Cache_Leaf(leaf); + + // mark the polygons + msurf = leaf->firstmarksurface; + for (i=0 ; inummarksurfaces ; i++, msurf++) + { + surf = *msurf; + + //only check each surface once. it can appear in multiple leafs. + if (surf->shadowframe == sh_shadowframe) + continue; + surf->shadowframe = sh_shadowframe; + + SHM_Shadow_Cache_Surface(surf); + } + return; + } + + splitplane = node->plane; + dist = DotProduct (dl->origin, splitplane->normal) - splitplane->dist; + + if (dist > dl->radius) + { + SHM_RecursiveWorldNodeQ3_r (dl, node->children[0]); + return; + } + if (dist < -dl->radius) + { + SHM_RecursiveWorldNodeQ3_r (dl, node->children[1]); + return; + } + SHM_RecursiveWorldNodeQ3_r (dl, node->children[0]); + SHM_RecursiveWorldNodeQ3_r (dl, node->children[1]); +} +#endif + +static SHM_ComposeVolume_BruteForce(dlight_t *dl) +{ + shadowmeshsurfs_t *sms; + unsigned int tno; + unsigned int sno; + unsigned int vno, vno2; + unsigned int fvert, lvert; + float *v1; + vec3_t v3; + mesh_t *sm; + for (tno = 0; tno < sh_shmesh->numsurftextures; tno++) + { + sms = &sh_shmesh->litsurfs[tno]; + if (!sms->count) + continue; + for (sno = 0; sno < sms->count; sno++) + { + sm = sms->s[sno]->mesh; + + if (sm->istrifan) + { + //planer poly +//if ((rand()&63)!=63) +//continue; + fvert = sh_shmesh->numverts; + + //front + SHM_Begin(GL_POLYGON); + for (vno = 0; vno < sm->numvertexes; vno++) + { + SHM_Vertex3fv(sm->xyz_array[vno]); + } + SHM_End(); + + //back (depth precision doesn't matter) + SHM_Begin(GL_POLYGON); + for (vno = sm->numvertexes; vno > 0; ) + { + vno--; + v1 = sm->xyz_array[vno]; + v3[0] = (v1[0]-dl->origin[0])*PROJECTION_DISTANCE; + v3[1] = (v1[1]-dl->origin[1])*PROJECTION_DISTANCE; + v3[2] = (v1[2]-dl->origin[2])*PROJECTION_DISTANCE; + + SHM_Vertex3f(v1[0]+v3[0], v1[1]+v3[1], v1[2]+v3[2]); + } + SHM_End(); + + vno = (sh_shmesh->numindicies+sm->numvertexes*6); //and a bit of padding + if (sh_shmesh->maxindicies < vno) + { + sh_shmesh->maxindicies = vno; + sh_shmesh->indicies = BZ_Realloc(sh_shmesh->indicies, vno * sizeof(*sh_shmesh->indicies)); + } + lvert = fvert + sm->numvertexes*2-1; + for (vno = 0; vno < sm->numvertexes; vno++) + { + if (vno == sm->numvertexes-1) + vno2 = 0; + else + vno2 = vno+1; + sh_shmesh->indicies[sh_shmesh->numindicies++] = fvert+vno; + sh_shmesh->indicies[sh_shmesh->numindicies++] = lvert-vno; + sh_shmesh->indicies[sh_shmesh->numindicies++] = fvert+vno2; + + sh_shmesh->indicies[sh_shmesh->numindicies++] = lvert-vno; + sh_shmesh->indicies[sh_shmesh->numindicies++] = lvert-vno2; + sh_shmesh->indicies[sh_shmesh->numindicies++] = fvert+vno2; + } + } + else + { + /*each triangle may or may not face the light*/ + } + } + } + + + /* unsigned int numindicies; + unsigned int maxindicies; + index_t *indicies; + + unsigned int numverts; + unsigned int maxverts; + vec3_t *verts; + + //we also have a list of all the surfaces that this light lights. + unsigned int numsurftextures; + shadowmeshsurfs_t *litsurfs; + + unsigned int leafbytes; + unsigned char *litleaves; + */ +} + +static struct shadowmesh_s *SHM_BuildShadowVolumeMesh(dlight_t *dl, unsigned char *lvis, unsigned char *vvis) +{ + float *v1, *v2; + vec3_t v3, v4; + + if (dl->worldshadowmesh) + return dl->worldshadowmesh; + + if (cl.worldmodel->fromgame == fg_quake || cl.worldmodel->fromgame == fg_halflife) + { + SHM_BeginShadowMesh(dl); + SHM_MarkLeavesQ1(dl, lvis, vvis); + SHM_RecursiveWorldNodeQ1_r(dl, cl.worldmodel->nodes); + } +#ifdef Q3BSPS + else if (cl.worldmodel->fromgame == fg_quake3) + { + SHM_BeginShadowMesh(dl); + sh_shadowframe++; + SHM_RecursiveWorldNodeQ3_r(dl, cl.worldmodel->nodes); + SHM_ComposeVolume_BruteForce(dl); + return SHM_FinishShadowMesh(dl); +// SHM_RecursiveWorldNodeQ3_r(cl.worldmodel->nodes); + + //if generating shadow volumes too: + // decompose the shadow-casting faces into triangles + // find neighbours + // emit front faces (clip back faces to the light's cube?) + // emit edges where there were no neighbours + } +#endif +#ifdef Q2BSPS + else if (cl.worldmodel->fromgame == fg_quake2) + { + SHM_BeginShadowMesh(dl); + SHM_MarkLeavesQ2(dl, lvis, vvis); + SHM_RecursiveWorldNodeQ2_r(dl, cl.worldmodel->nodes); + } +#endif + else + return NULL; + + SHM_Begin(GL_QUADS); + while(firstedge) + { + //border + v1 = cl.worldmodel->vertexes[cl.worldmodel->edges[firstedge].v[0]].position; + v2 = cl.worldmodel->vertexes[cl.worldmodel->edges[firstedge].v[1]].position; + + //get positions of v3 and v4 based on the light position + v3[0] = v1[0] + ( v1[0]-dl->origin[0] )*PROJECTION_DISTANCE; + v3[1] = v1[1] + ( v1[1]-dl->origin[1] )*PROJECTION_DISTANCE; + v3[2] = v1[2] + ( v1[2]-dl->origin[2] )*PROJECTION_DISTANCE; + + v4[0] = v2[0] + ( v2[0]-dl->origin[0] )*PROJECTION_DISTANCE; + v4[1] = v2[1] + ( v2[1]-dl->origin[1] )*PROJECTION_DISTANCE; + v4[2] = v2[2] + ( v2[2]-dl->origin[2] )*PROJECTION_DISTANCE; + + if (edge[firstedge].count > 0) + { + SHM_Vertex3fv(v3); + SHM_Vertex3fv(v4); + SHM_Vertex3fv(v2); + SHM_Vertex3fv(v1); + } + else + { + SHM_Vertex3fv(v1); + SHM_Vertex3fv(v2); + SHM_Vertex3fv(v4); + SHM_Vertex3fv(v3); + } + edge[firstedge].count=0; + + firstedge = edge[firstedge].next; + } + SHM_End(); + + firstedge=0; + + return SHM_FinishShadowMesh(dl); +} + + + + + + + + + + + + + + +static void Sh_Scissor (int x, int y, int width, int height) +{ +#if 0 //visible scissors + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho (0, glwidth, glheight, 0, -99999, 99999); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); +// GL_Set2D(); + + glColor4f(1,1,1,1); + glDisable(GL_DEPTH_TEST); + glDisable(GL_SCISSOR_TEST); + glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE ); + glDisable(GL_TEXTURE_2D); + GL_TexEnv(GL_REPLACE); + + glBegin(GL_LINE_LOOP); + glVertex2f(x, y); + glVertex2f(x+glwidth, y); + glVertex2f(x+glwidth, y+glheight); + glVertex2f(x, y+glheight); + glEnd(); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); +#endif + qglScissor(x, vid.pixelheight - (y + height),width,height); +} + +#define BoxesOverlap(a,b,c,d) ((a)[0] <= (d)[0] && (b)[0] >= (c)[0] && (a)[1] <= (d)[1] && (b)[1] >= (c)[1] && (a)[2] <= (d)[2] && (b)[2] >= (c)[2]) +static qboolean Sh_ScissorForBox(vec3_t mins, vec3_t maxs) +{ + int i, ix1, iy1, ix2, iy2; + float x1, y1, x2, y2, x, y, f; + vec3_t smins, smaxs; + vec4_t v, v2; + int r_view_x = 0; + int r_view_y = 0; + int r_view_width = vid.pixelwidth; + int r_view_height = vid.pixelheight; + if (0)//!r_shadow_scissor.integer) + { + Sh_Scissor(r_view_x, r_view_y, r_view_width, r_view_height); + return false; + } + // if view is inside the box, just say yes it's visible + if (BoxesOverlap(r_refdef.vieworg, r_refdef.vieworg, mins, maxs)) + { + Sh_Scissor(r_view_x, r_view_y, r_view_width, r_view_height); + return false; + } + for (i = 0;i < 3;i++) + { + if (vpn[i] >= 0) + { + v[i] = mins[i]; + v2[i] = maxs[i]; + } + else + { + v[i] = maxs[i]; + v2[i] = mins[i]; + } + } + f = DotProduct(vpn, r_refdef.vieworg) + 1; + if (DotProduct(vpn, v2) <= f) + { + // entirely behind nearclip plane + Sh_Scissor(r_view_x, r_view_y, r_view_width, r_view_height); + return true; + } + if (DotProduct(vpn, v) >= f) + { + // entirely infront of nearclip plane + x1 = y1 = x2 = y2 = 0; + for (i = 0;i < 8;i++) + { + v[0] = (i & 1) ? mins[0] : maxs[0]; + v[1] = (i & 2) ? mins[1] : maxs[1]; + v[2] = (i & 4) ? mins[2] : maxs[2]; + v[3] = 1.0f; + Matrix4_Project(v, v2, r_refdef.viewangles, r_refdef.vieworg, r_refdef.fov_x, r_refdef.fov_y); + v2[0]*=r_view_width; + v2[1]*=r_view_height; +// GL_TransformToScreen(v, v2); + //Con_Printf("%.3f %.3f %.3f %.3f transformed to %.3f %.3f %.3f %.3f\n", v[0], v[1], v[2], v[3], v2[0], v2[1], v2[2], v2[3]); + x = v2[0]; + y = v2[1]; + if (i) + { + if (x1 > x) x1 = x; + if (x2 < x) x2 = x; + if (y1 > y) y1 = y; + if (y2 < y) y2 = y; + } + else + { + x1 = x2 = x; + y1 = y2 = y; + } + } + } + else + { + // clipped by nearclip plane + // this is nasty and crude... + // create viewspace bbox + for (i = 0;i < 8;i++) + { + v[0] = ((i & 1) ? mins[0] : maxs[0]) - r_refdef.vieworg[0]; + v[1] = ((i & 2) ? mins[1] : maxs[1]) - r_refdef.vieworg[1]; + v[2] = ((i & 4) ? mins[2] : maxs[2]) - r_refdef.vieworg[2]; + v2[0] = DotProduct(v, vright); + v2[1] = DotProduct(v, vup); + v2[2] = DotProduct(v, vpn); + if (i) + { + if (smins[0] > v2[0]) smins[0] = v2[0]; + if (smaxs[0] < v2[0]) smaxs[0] = v2[0]; + if (smins[1] > v2[1]) smins[1] = v2[1]; + if (smaxs[1] < v2[1]) smaxs[1] = v2[1]; + if (smins[2] > v2[2]) smins[2] = v2[2]; + if (smaxs[2] < v2[2]) smaxs[2] = v2[2]; + } + else + { + smins[0] = smaxs[0] = v2[0]; + smins[1] = smaxs[1] = v2[1]; + smins[2] = smaxs[2] = v2[2]; + } + } + // now we have a bbox in viewspace + // clip it to the view plane + if (smins[2] < 1) + smins[2] = 1; + // return true if that culled the box + if (smins[2] >= smaxs[2]) + return true; + // ok some of it is infront of the view, transform each corner back to + // worldspace and then to screenspace and make screen rect + // initialize these variables just to avoid compiler warnings + x1 = y1 = x2 = y2 = 0; + for (i = 0;i < 8;i++) + { + v2[0] = (i & 1) ? smins[0] : smaxs[0]; + v2[1] = (i & 2) ? smins[1] : smaxs[1]; + v2[2] = (i & 4) ? smins[2] : smaxs[2]; + v[0] = v2[0] * vright[0] + v2[1] * vup[0] + v2[2] * vpn[0] + r_refdef.vieworg[0]; + v[1] = v2[0] * vright[1] + v2[1] * vup[1] + v2[2] * vpn[1] + r_refdef.vieworg[1]; + v[2] = v2[0] * vright[2] + v2[1] * vup[2] + v2[2] * vpn[2] + r_refdef.vieworg[2]; + v[3] = 1.0f; + Matrix4_Project(v, v2, r_refdef.viewangles, r_refdef.vieworg, r_refdef.fov_x, r_refdef.fov_y); + v2[0]*=r_view_width; + v2[1]*=r_view_height; +// GL_TransformToScreen(v, v2); + //Con_Printf("%.3f %.3f %.3f %.3f transformed to %.3f %.3f %.3f %.3f\n", v[0], v[1], v[2], v[3], v2[0], v2[1], v2[2], v2[3]); + x = v2[0]; + y = v2[1]; + if (i) + { + if (x1 > x) x1 = x; + if (x2 < x) x2 = x; + if (y1 > y) y1 = y; + if (y2 < y) y2 = y; + } + else + { + x1 = x2 = x; + y1 = y2 = y; + } + } +#if 0 + // this code doesn't handle boxes with any points behind view properly + x1 = 1000;x2 = -1000; + y1 = 1000;y2 = -1000; + for (i = 0;i < 8;i++) + { + v[0] = (i & 1) ? mins[0] : maxs[0]; + v[1] = (i & 2) ? mins[1] : maxs[1]; + v[2] = (i & 4) ? mins[2] : maxs[2]; + v[3] = 1.0f; + GL_TransformToScreen(v, v2); + v2[0]*=r_view_width; + v2[1]*=r_view_height; + //Con_Printf("%.3f %.3f %.3f %.3f transformed to %.3f %.3f %.3f %.3f\n", v[0], v[1], v[2], v[3], v2[0], v2[1], v2[2], v2[3]); + if (v2[2] > 0) + { + x = v2[0]; + y = v2[1]; + + if (x1 > x) x1 = x; + if (x2 < x) x2 = x; + if (y1 > y) y1 = y; + if (y2 < y) y2 = y; + } + } +#endif + } + ix1 = x1 - 1.0f; + iy1 = y1 - 1.0f; + ix2 = x2 + 1.0f; + iy2 = y2 + 1.0f; + //Con_Printf("%f %f %f %f\n", x1, y1, x2, y2); + if (ix1 < r_view_x) ix1 = r_view_x; + if (iy1 < r_view_y) iy1 = r_view_y; + if (ix2 > r_view_x + r_view_width) ix2 = r_view_x + r_view_width; + if (iy2 > r_view_y + r_view_height) iy2 = r_view_y + r_view_height; + if (ix2 <= ix1 || iy2 <= iy1) + return true; + // set up the scissor rectangle + qglScissor(ix1, iy1, ix2 - ix1, iy2 - iy1); + //qglEnable(GL_SCISSOR_TEST); + return false; +} + + +void GL_BeginRenderBuffer_DepthOnly(texid_t depthtexture) +{ + static int fboid; + + if (qglGenRenderbuffersEXT) + { + if (!fboid) + { + qglGenRenderbuffersEXT(1, &fboid); + qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboid); + qglDrawBuffer(GL_NONE); + qglReadBuffer(GL_NONE); + } + else + qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboid); + + if (TEXVALID(depthtexture)) + qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, depthtexture.num, 0); + } +} +void GL_EndRenderBuffer_DepthOnly(texid_t depthtexture, int texsize) +{ + if (qglGenRenderbuffersEXT) + { + qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + } + else + { + GL_Bind(depthtexture); + qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, texsize, texsize); + } +} + +static void Sh_GenShadowFace(dlight_t *l, shadowmesh_t *smesh, int face) +{ + int i; + msurface_t *s; + float mvm[16], proj[16]; + int ve; + + int smsize = 512; + int tno, sno; + mesh_t *m, *sm; + texture_t *tex; + +// qglDepthRange(0, 1); + + BE_SetupForShadowMap(); + +checkerror(); + if (1) + { + qglViewport (0, 0, smsize, smsize); + + if (!l->fov) + l->fov = 90; + + Matrix4_Projection_Far(proj, l->fov, l->fov, nearplane, lradius); + Matrix4_ModelViewMatrixFromAxis(mvm, l->axis[0], l->axis[1], l->axis[2], l->origin); + + qglMatrixMode(GL_PROJECTION); + qglLoadMatrixf(proj); + qglMatrixMode(GL_MODELVIEW); + qglLoadMatrixf(mvm); + + R_SetFrustum(proj, mvm); + } +checkerror(); + + BE_SelectMode(BEM_DEPTHONLY, 0); + + GL_BeginRenderBuffer_DepthOnly(l->stexture); + qglClear (GL_DEPTH_BUFFER_BIT); + + if (smesh) + for (tno = 0; tno < smesh->numsurftextures; tno++) + { + m = NULL; + if (!smesh->litsurfs[tno].count) + continue; + tex = smesh->litsurfs[tno].s[0]->texinfo->texture; + for (sno = 0; sno < smesh->litsurfs[tno].count; sno++) + { + sm = smesh->litsurfs[tno].s[sno]->mesh; + if (!sm) + continue; + sm->next = m; + m = sm; + } + if (m) + BE_DrawMeshChain(tex->shader, m, &tex->vbo, &tex->shader->defaulttextures); + } + + BE_BaseEntShadowDepth(); + + GL_EndRenderBuffer_DepthOnly(l->stexture, smsize); + + if (0) + { + int i; + static float depth[512*512]; + qglReadPixels(0, 0, smsize, smsize, + GL_DEPTH_COMPONENT, GL_FLOAT, depth); + for (i = 512*512; i --> 0; ) + { + if (depth[i] == 1) + *((unsigned int*)depth+i) = 0; + else + *((unsigned int*)depth+i) = 0xff000000|((((unsigned char)(int)(depth[i]*128)))*0x10101); + } + qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + smsize, smsize, 0, + GL_RGBA, GL_UNSIGNED_BYTE, depth); + + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + } + + checkerror(); +} + +void Sh_GenShadowMaps (void) +{ + dlight_t *l; + int i; + int f; + int smsize = 512; + + shadowmesh_t *smesh; + + //FIXME: push dynamic shadow volume generation to another thread. + //FIXME: cull lights here. + + for (l = cl_dlights+rtlights_first, i=rtlights_first; iflags & LFLAG_SHADOWMAP)) + continue; + if (!l->radius || l->flags & LFLAG_NOSHADOWS) + continue; + if (l->color[0]<0) + continue; //quick check for darklight + + if (!TEXVALID(l->stexture)) + { + l->stexture = GL_AllocNewTexture(); + + checkerror(); + + GL_Bind(l->stexture); + checkerror(); + qglTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32_ARB, smsize, smsize, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); + // qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, smsize, smsize, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + checkerror(); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + checkerror(); + } + else if (l->refresh-->0) + continue; //FIXME: need to optimise GenShadowFace first + l->refresh = 0; + + if (l->worldshadowmesh) + smesh = l->worldshadowmesh; + else + { + unsigned int leaf; + qbyte lvisb[MAX_MAP_LEAFS/8]; + qbyte *lvis; + leaf = cl.worldmodel->funcs.LeafnumForPoint(cl.worldmodel, l->origin); + lvis = cl.worldmodel->funcs.LeafPVS(cl.worldmodel, leaf, lvisb, sizeof(lvisb)); + smesh = SHM_BuildShadowVolumeMesh(l, lvis, NULL); + } + + qglEnable(GL_POLYGON_OFFSET_FILL); + qglPolygonOffset(5, 25); + for (f = 0; f < 1; f++) + { + Sh_GenShadowFace(l, smesh, f); + } + qglDisable(GL_POLYGON_OFFSET_FILL); + } +} + +static float shadowprojectionbias[16] = +{ + 0.5f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.5f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.5f, 0.0f, + 0.5f, 0.5f, 0.4993f, 1.0f +}; + +static void Sh_DrawLameSpotLightShadowMap(dlight_t *l, vec3_t colour) +{ + float t[16]; + float bp[16]; + float proj[16], view[16]; + vec3_t biasorg; + int ve; + + Matrix4_Projection_Far(proj, l->fov, l->fov, nearplane, lradius); + VectorMA(l->origin, 0, l->axis[0], biasorg); + Matrix4_ModelViewMatrixFromAxis(view, l->axis[0], l->axis[1], l->axis[2], l->origin); + + //bp = shadowprojectionbias*proj*view; + Matrix4_Multiply(shadowprojectionbias, proj, t); + Matrix4_Multiply(t, view, bp); + + t[0] = bp[0]; + t[1] = bp[4]; + t[2] = bp[8]; + t[3] = bp[12]; + t[4] = bp[1]; + t[5] = bp[5]; + t[6] = bp[9]; + t[7] = bp[13]; + t[8] = bp[2]; + t[9] = bp[6]; + t[10] = bp[10]; + t[11] = bp[14]; + t[12] = bp[3]; + t[13] = bp[7]; + t[14] = bp[11]; + t[15] = bp[15]; +checkerror(); + + bench.numlights++; + +#if 1 + qglMatrixMode(GL_TEXTURE); + GL_MBind(7, l->stexture); +// qglEnable(GL_TEXTURE_2D); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); + qglTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE); + qglLoadMatrixf(bp); + qglMatrixMode(GL_MODELVIEW); + PPL_RevertToKnownState(); + + GL_SelectTexture(0); + + checkerror(); + ve = 0; + + BE_SelectDLight(l, colour); + BE_SelectMode(BEM_SMAPLIGHT, 0); + Sh_DrawEntLighting(l, colour); + + GL_SelectTexture(7); + qglDisable(GL_TEXTURE_2D); + qglMatrixMode(GL_TEXTURE); + qglLoadIdentity(); + qglMatrixMode(GL_MODELVIEW); +// PPL_RevertToKnownState(); + + checkerror(); +#else +GL_MBind(0, l->stexture); +qglEnable(GL_TEXTURE_2D); + //Set up texture coordinate generation. + qglTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + qglTexGenfv(GL_S, GL_EYE_PLANE, &t[0]); + qglEnable(GL_TEXTURE_GEN_S); + + qglTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + qglTexGenfv(GL_T, GL_EYE_PLANE, &t[4]); + qglEnable(GL_TEXTURE_GEN_T); + + qglTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + qglTexGenfv(GL_R, GL_EYE_PLANE, &t[8]); + qglEnable(GL_TEXTURE_GEN_R); + + qglTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + qglTexGenfv(GL_Q, GL_EYE_PLANE, &t[12]); + qglEnable(GL_TEXTURE_GEN_Q); +checkerror(); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); + qglTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA); +checkerror(); + + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + +if (1) +{ + GL_MBind(1, balltexture); + qglEnable(GL_TEXTURE_2D); + + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + + + qglTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + qglTexGenfv(GL_S, GL_EYE_PLANE, &t[0]); + qglEnable(GL_TEXTURE_GEN_S); + + qglTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + qglTexGenfv(GL_T, GL_EYE_PLANE, &t[4]); + qglEnable(GL_TEXTURE_GEN_T); + + qglTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + qglTexGenfv(GL_R, GL_EYE_PLANE, &t[8]); + qglEnable(GL_TEXTURE_GEN_R); + + qglTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); + qglTexGenfv(GL_Q, GL_EYE_PLANE, &t[12]); + qglEnable(GL_TEXTURE_GEN_Q); +} +else +{ + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + qglTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA); +} + + qglEnable(GL_BLEND); + qglBlendFunc (GL_SRC_ALPHA, GL_ONE); + qglDisable(GL_ALPHA_TEST); + qglColor3f(colour[0], colour[1], colour[2]); + qglEnableClientState(GL_VERTEX_ARRAY); + qglDisableClientState(GL_COLOR_ARRAY); +checkerror(); + qglDepthMask(0); + GL_TexEnv(GL_MODULATE); + ve = 0; + + //qglEnable(GL_POLYGON_OFFSET_FILL); + qglPolygonOffset(-0.5, -25); + + for (i = 0; i < cl.worldmodel->numsurfaces; i++) + { + s = &cl.worldmodel->surfaces[i]; +// if(s->visframe != r_framecount) +// continue; + + if (ve != s->texinfo->texture->vbo.vboe) + { + ve = s->texinfo->texture->vbo.vboe; + + GL_SelectVBO(s->texinfo->texture->vbo.vbocoord); + GL_SelectEBO(s->texinfo->texture->vbo.vboe); + qglVertexPointer(3, GL_FLOAT, sizeof(vecV_t), s->texinfo->texture->vbo.coord); + } + qglDrawRangeElements(GL_TRIANGLES, s->mesh->vbofirstvert, s->mesh->numvertexes, s->mesh->numindexes, GL_INDEX_TYPE, (index_t*)(s->mesh->vbofirstelement*sizeof(index_t))); + } + checkerror(); + + qglDisable(GL_POLYGON_OFFSET_FILL); + + GL_SelectVBO(0); + GL_SelectEBO(0); + + GL_MBind(1, 0); + qglDisable(GL_TEXTURE_2D); + qglDisable(GL_TEXTURE_GEN_S); + qglDisable(GL_TEXTURE_GEN_T); + qglDisable(GL_TEXTURE_GEN_R); + qglDisable(GL_TEXTURE_GEN_Q); + GL_MBind(0, 0); + qglDisable(GL_TEXTURE_GEN_S); + qglDisable(GL_TEXTURE_GEN_T); + qglDisable(GL_TEXTURE_GEN_R); + qglDisable(GL_TEXTURE_GEN_Q); + checkerror(); +#endif +} + + + + + + +static void Sh_WorldLightingPass(void) +{ + msurface_t *s; + int i; + int ve; + + ve = 0; + for (i = 0; i < cl.worldmodel->numsurfaces; i++) + { + s = &cl.worldmodel->surfaces[i]; + if(s->visframe != r_framecount) + continue; + + if (ve != s->texinfo->texture->vbo.vboe) + { + ve = s->texinfo->texture->vbo.vboe; + + GL_SelectVBO(s->texinfo->texture->vbo.vbocoord); + GL_SelectEBO(s->texinfo->texture->vbo.vboe); + qglVertexPointer(3, GL_FLOAT, sizeof(vecV_t), s->texinfo->texture->vbo.coord); + } + qglDrawRangeElements(GL_TRIANGLES, s->mesh->vbofirstvert, s->mesh->numvertexes, s->mesh->numindexes, GL_INDEX_TYPE, (index_t*)(s->mesh->vbofirstelement*sizeof(index_t))); + } +} + + + + +#pragma message("move to header") +void BE_BaseEntTextures(void); + +/* +draws faces facing the light +Note: Backend mode must have been selected in advance, as must the light to light from +*/ +static void Sh_DrawEntLighting(dlight_t *light, vec3_t colour) +{ + mesh_t *meshchain, *surfmesh; + int tno, sno; + msurface_t *surf; + texture_t *tex; + shadowmesh_t *sm; + + currententity = &r_worldentity; + sm = light->worldshadowmesh; + if (sm) + { + for (tno = 0; tno < sm->numsurftextures; tno++) + { + if (!sm->litsurfs[tno].count) + continue; + meshchain = NULL; + tex = sm->litsurfs[tno].s[0]->texinfo->texture; + for (sno = 0; sno < sm->litsurfs[tno].count; sno++) + { + surf = sm->litsurfs[tno].s[sno]; +// if (surf->visframe == r_visframecount) + { + /*was visible this frame*/ + surfmesh = surf->mesh; + surfmesh->next = meshchain; + meshchain = surfmesh; + } + } + if (meshchain) + BE_DrawMeshChain(tex->shader, meshchain, &tex->vbo, &tex->shader->defaulttextures); + } + + BE_BaseEntTextures(); + } + else + { +#pragma message("FIXME: For dynamic lights, the entire view is redrawn! Bad!") + BE_SubmitMeshes(); + } +} + + + + + + + +#define PROJECTION_DISTANCE (float)(dl->radius*2)//0x7fffffff +/*Fixme: this is brute forced*/ +static void Sh_DrawBrushModelShadow(dlight_t *dl, entity_t *e) +{ + int v; + float *v1, *v2; + vec3_t v3, v4; + vec3_t lightorg; + + int i; + model_t *model; + msurface_t *surf; + + if (BE_LightCullModel(e->origin, e->model)) + return; + + RotateLightVector(e->axis, e->origin, dl->origin, lightorg); + + qglPushMatrix(); + R_RotateForEntity(e); + + GL_SelectVBO(0); + GL_SelectEBO(0); + qglEnableClientState(GL_VERTEX_ARRAY); + qglEnable(GL_VERTEX_ARRAY); + + model = e->model; + surf = model->surfaces+model->firstmodelsurface; + for (i = 0; i < model->nummodelsurfaces; i++, surf++) + { + if (surf->flags & SURF_PLANEBACK) + {//inverted normal. + if (DotProduct(surf->plane->normal, lightorg)-surf->plane->dist >= -0.1) + continue; + } + else + { + if (DotProduct(surf->plane->normal, lightorg)-surf->plane->dist <= 0.1) + continue; + } + + if (surf->flags & (SURF_DRAWALPHA | SURF_DRAWTILED)) + { // no shadows + continue; + } + + //front face + qglVertexPointer(3, GL_FLOAT, sizeof(vecV_t), surf->mesh->xyz_array); + qglDrawArrays(GL_POLYGON, 0, surf->mesh->numvertexes); +// qglDrawRangeElements(GL_TRIANGLES, 0, surf->mesh->numvertexes, surf->mesh->numindexes, GL_INDEX_TYPE, surf->mesh->indexes); + + for (v = 0; v < surf->mesh->numvertexes; v++) + { + //border + v1 = surf->mesh->xyz_array[v]; + v2 = surf->mesh->xyz_array[( v+1 )%surf->mesh->numvertexes]; + + //get positions of v3 and v4 based on the light position + v3[0] = ( v1[0]-lightorg[0] )*PROJECTION_DISTANCE; + v3[1] = ( v1[1]-lightorg[1] )*PROJECTION_DISTANCE; + v3[2] = ( v1[2]-lightorg[2] )*PROJECTION_DISTANCE; + + v4[0] = ( v2[0]-lightorg[0] )*PROJECTION_DISTANCE; + v4[1] = ( v2[1]-lightorg[1] )*PROJECTION_DISTANCE; + v4[2] = ( v2[2]-lightorg[2] )*PROJECTION_DISTANCE; + + //Now draw the quad from the two verts to the projected light + //verts + qglBegin( GL_QUAD_STRIP ); + qglVertex3fv(v1); + qglVertex3f (v1[0]+v3[0], v1[1]+v3[1], v1[2]+v3[2]); + qglVertex3fv(v2); + qglVertex3f (v2[0]+v4[0], v2[1]+v4[1], v2[2]+v4[2]); + qglEnd(); + } + +//back + //the same applies as earlier + qglBegin(GL_POLYGON); + for (v = surf->mesh->numvertexes-1; v >=0; v--) + { + v1 = surf->mesh->xyz_array[v]; + v3[0] = (v1[0]-lightorg[0])*PROJECTION_DISTANCE; + v3[1] = (v1[1]-lightorg[1])*PROJECTION_DISTANCE; + v3[2] = (v1[2]-lightorg[2])*PROJECTION_DISTANCE; + + qglVertex3f(v1[0]+v3[0], v1[1]+v3[1], v1[2]+v3[2]); + } + qglEnd(); + } + qglPopMatrix(); +} + + +/*when this is called, the gl state has been set up to draw the stencil volumes using whatever extensions we have +if secondside is set, then the gpu sucks and we're drawing stuff the slow 2-pass way, and this is the second pass. +*/ +static void Sh_DrawStencilLightShadows(dlight_t *dl, qbyte *lvis, qbyte *vvis, qboolean secondside) +{ + extern cvar_t gl_part_flame; + int i; + struct shadowmesh_s *sm; + + sm = SHM_BuildShadowVolumeMesh(dl, lvis, vvis); + if (!sm) + Sh_DrawBrushModelShadow(dl, &r_worldentity); + else + { + currententity = &r_worldentity; + +//qglEnable(GL_POLYGON_OFFSET_FILL); +//qglPolygonOffset(shaderstate.curpolyoffset.factor, shaderstate.curpolyoffset.unit); + + GL_SelectVBO(0); + GL_SelectEBO(0); + qglEnableClientState(GL_VERTEX_ARRAY); + qglEnable(GL_VERTEX_ARRAY); + //draw cached world shadow mesh + qglVertexPointer(3, GL_FLOAT, sizeof(vecV_t), sm->verts); + qglDrawRangeElements(GL_TRIANGLES, 0, sm->numverts, sm->numindicies, GL_INDEX_TYPE, sm->indicies); + +//qglEnable(GL_POLYGON_OFFSET_FILL); +//qglPolygonOffset(shaderstate.curpolyoffset.factor, shaderstate.curpolyoffset.unit); + } + if (!r_drawentities.value) + return; + + // draw sprites seperately, because of alpha blending + for (i=0 ; iflags & RF_NOSHADOW) + continue; + + { + if (currententity->keynum == dl->key && currententity->keynum) + continue; + } + + if (currententity->flags & Q2RF_BEAM) + { + R_DrawBeam(currententity); + continue; + } + if (!currententity->model) + continue; + + if (cls.allow_anyparticles || currententity->visframe) //allowed or static + { + if (currententity->model->engineflags & MDLF_ENGULPHS) + { + if (gl_part_flame.value) + continue; + } + } + + switch (currententity->model->type) + { + case mod_alias: + R_DrawGAliasShadowVolume (currententity, dl->origin, dl->radius); + break; + + case mod_brush: + Sh_DrawBrushModelShadow (dl, currententity); + break; + + default: + break; + } + } +} + +static qboolean Sh_VisOverlaps(qbyte *v1, qbyte *v2) +{ + int i, m; + m = (cl.worldmodel->numleafs-1)>>3; + for (i=0 ; inumleafs); + mleaf_t *wl = cl.worldmodel->leafs; + unsigned char lv; + + /*we can potentially walk off the end of the leafs, but lightvis shouldn't be set for those*/ + + + for (i = 0; i < m; i += 1<<3) + { + lv = lightvis[i>>3];// & vvis[i>>3]; + if (!lv) + continue; + if ((lv&0x01) && wl[i+0].visframe == r_visframecount) return true; + if ((lv&0x02) && wl[i+1].visframe == r_visframecount) return true; + if ((lv&0x04) && wl[i+2].visframe == r_visframecount) return true; + if ((lv&0x08) && wl[i+3].visframe == r_visframecount) return true; + if ((lv&0x10) && wl[i+4].visframe == r_visframecount) return true; + if ((lv&0x20) && wl[i+5].visframe == r_visframecount) return true; + if ((lv&0x40) && wl[i+6].visframe == r_visframecount) return true; + if ((lv&0x80) && wl[i+7].visframe == r_visframecount) return true; + } + + return false; +} + +//draws a light using stencil shadows. +//redraws world geometry up to 3 times per light... +static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, qbyte *vvis) +{ + extern int gldepthfunc; + int i; + int sdecrw; + int sincrw; + int leaf; + qbyte *lvis; + + qbyte lvisb[MAX_MAP_LEAFS/8]; + + vec3_t mins; + vec3_t maxs; + + if (R_CullSphere(dl->origin, dl->radius)) + { + bench.numfrustumculled++; + return false; //this should be the more common case + } + + mins[0] = dl->origin[0] - dl->radius; + mins[1] = dl->origin[1] - dl->radius; + mins[2] = dl->origin[2] - dl->radius; + + maxs[0] = dl->origin[0] + dl->radius; + maxs[1] = dl->origin[1] + dl->radius; + maxs[2] = dl->origin[2] + dl->radius; + + if (dl->worldshadowmesh) + { + //fixme: check head node first? + if (!Sh_LeafInView(dl->worldshadowmesh->litleaves, vvis)) + { + bench.numpvsculled++; + return false; + } +/* + if (cl.worldmodel->fromgame == fg_quake2 || cl.worldmodel->fromgame == fg_quake3) + i = cl.worldmodel->funcs.LeafForPoint(r_refdef.vieworg, cl.worldmodel); + else + i = r_viewleaf - cl.worldmodel->leafs; + + // if (!(lvis[i>>3] & (1<<(i&7)))) //light might not be visible, but it's effects probably should be. + // return; + if (!Sh_VisOverlaps(dl->worldshadowmesh->litleaves, vvis)) //The two viewing areas do not intersect. + return; +*/ + lvis = NULL; + } + else + { + if (cl.worldmodel->fromgame == fg_quake2 || cl.worldmodel->fromgame == fg_quake3) + i = cl.worldmodel->funcs.LeafnumForPoint(cl.worldmodel, r_refdef.vieworg); + else + i = r_viewleaf - cl.worldmodel->leafs; + + leaf = cl.worldmodel->funcs.LeafnumForPoint(cl.worldmodel, dl->origin); + lvis = cl.worldmodel->funcs.LeafPVS(cl.worldmodel, leaf, lvisb, sizeof(lvisb)); + + // if (!(lvis[i>>3] & (1<<(i&7)))) //light might not be visible, but it's effects probably should be. + // return; + if (!Sh_VisOverlaps(lvis, vvis)) //The two viewing areas do not intersect. + { + bench.numpvsculled++; + return false; + } + } + + //sets up the gl scissor (and culls to view) + if (Sh_ScissorForBox(mins, maxs)) + { + bench.numscissorculled++; + return false; //this doesn't cull often. + } + bench.numlights++; + + checkerror(); + + BE_SelectDLight(dl, colour); + BE_SelectMode(BEM_STENCIL, 0); + + //The backend doesn't maintain scissor state. + qglEnable(GL_SCISSOR_TEST); + //The backend doesn't maintain stencil test state either - it needs to be active for more than just stencils, or disabled. its awkward. + qglEnable(GL_STENCIL_TEST); + + //FIXME: is it practical to test to see if scissors allow not clearing the stencil buffer? + + /*we don't need all that much stencil buffer depth, and if we don't get enough or have dodgy volumes, wrap if we can*/ + sincrw = GL_INCR; + sdecrw = GL_DECR; + if (gl_config.ext_stencil_wrap) + { //minimise damage... + sincrw = GL_INCR_WRAP_EXT; + sdecrw = GL_DECR_WRAP_EXT; + } + //our stencil writes. + +#ifdef _DEBUG +/* if (r_shadows.value == 666) //testing (visible shadow volumes) + { + checkerror(); + qglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); + qglColor3f(dl->color[0], dl->color[1], dl->color[2]); + qglDisable(GL_STENCIL_TEST); + qglEnable(GL_POLYGON_OFFSET_FILL); + qglPolygonOffset(-1, -1); + // qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + Sh_DrawStencilLightShadows(dl, lvis, false); + qglDisable(GL_POLYGON_OFFSET_FILL); + checkerror(); + qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + }*/ +#endif + + if (qglStencilOpSeparateATI) + { + qglClearStencil(0); + qglClear(GL_STENCIL_BUFFER_BIT); + GL_CullFace(0); + + qglStencilFunc( GL_ALWAYS, 1, ~0 ); + + qglStencilOpSeparateATI(GL_BACK, GL_KEEP, sincrw, GL_KEEP); + qglStencilOpSeparateATI(GL_FRONT, GL_KEEP, sdecrw, GL_KEEP); + + Sh_DrawStencilLightShadows(dl, lvis, vvis, false); + qglStencilOpSeparateATI(GL_FRONT_AND_BACK, GL_KEEP, GL_KEEP, GL_KEEP); + + GL_CullFace(SHADER_CULL_FRONT); + + qglStencilFunc( GL_EQUAL, 0, ~0 ); + } + else if (qglActiveStencilFaceEXT) + { + /*personally I prefer the ATI way*/ + qglClearStencil(0); + qglClear(GL_STENCIL_BUFFER_BIT); + GL_CullFace(0); + + qglEnable(GL_STENCIL_TEST_TWO_SIDE_EXT); + + qglActiveStencilFaceEXT(GL_BACK); + qglStencilOp(GL_KEEP, sincrw, GL_KEEP); + qglStencilFunc( GL_ALWAYS, 1, ~0 ); + + qglActiveStencilFaceEXT(GL_FRONT); + qglStencilOp(GL_KEEP, sdecrw, GL_KEEP); + qglStencilFunc( GL_ALWAYS, 1, ~0 ); + + Sh_DrawStencilLightShadows(dl, lvis, vvis, false); + + qglActiveStencilFaceEXT(GL_BACK); + qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + qglStencilFunc( GL_ALWAYS, 0, ~0 ); + + qglActiveStencilFaceEXT(GL_FRONT); + qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + qglStencilFunc( GL_EQUAL, 0, ~0 ); +#pragma message("fixme: does this work properly on ati cards? cull front, but leave front as equals?") + qglDisable(GL_STENCIL_TEST_TWO_SIDE_EXT); + + GL_CullFace(SHADER_CULL_FRONT); + } + else //your graphics card sucks and lacks efficient stencil shadow techniques. + { //centered around 0. Will only be increased then decreased less. + qglClearStencil(0); + qglClear(GL_STENCIL_BUFFER_BIT); + + qglStencilFunc(GL_ALWAYS, 0, ~0); + + GL_CullFace(SHADER_CULL_BACK); + qglStencilOp(GL_KEEP, sincrw, GL_KEEP); + Sh_DrawStencilLightShadows(dl, lvis, vvis, false); + + GL_CullFace(SHADER_CULL_FRONT); + qglStencilOp(GL_KEEP, sdecrw, GL_KEEP); + Sh_DrawStencilLightShadows(dl, lvis, vvis, true); + + qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + qglStencilFunc(GL_EQUAL, 0, ~0); + } + //end stencil writing. + +#if 0 //draw the stencil stuff to the red channel + qglMatrixMode(GL_PROJECTION); + qglPushMatrix(); + qglMatrixMode(GL_MODELVIEW); + qglPushMatrix(); + GL_Set2D(); + + { + qglColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_FALSE); + qglStencilFunc(GL_GREATER, 1, ~0); + Draw_ConsoleBackground(vid.height); + + qglColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE); + qglStencilFunc(GL_LESS, 1, ~0); + Draw_ConsoleBackground(vid.height); + + qglColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE); + qglStencilFunc(GL_NEVER, 1, ~0); + Draw_ConsoleBackground(vid.height); + } + + qglMatrixMode(GL_PROJECTION); + qglPopMatrix(); + qglMatrixMode(GL_MODELVIEW); + qglPopMatrix(); +#endif + + checkerror(); + + PPL_RevertToKnownState(); + + BE_SelectMode(BEM_LIGHT, 0); + Sh_DrawEntLighting(dl, colour); + + qglDisable(GL_STENCIL_TEST); + qglStencilFunc( GL_ALWAYS, 0, ~0 ); +/* + if (developer.ival) + { + PPL_RevertToKnownState(); + qglEnable(GL_BLEND); + qglBlendFunc(GL_ONE, GL_ONE); + qglDisable(GL_DEPTH_TEST); + qglDepthMask(0); + qglShadeModel (GL_SMOOTH); + qglDepthMask (0); + qglDisable (GL_TEXTURE_2D); + qglShadeModel (GL_SMOOTH); + qglEnable (GL_BLEND); + qglBlendFunc (GL_ONE, GL_ONE); + + R_RenderDlight (dl); + qglEnable(GL_DEPTH_TEST); + qglShadeModel (GL_FLAT); + PPL_RevertToKnownState(); + } +*/ + checkerror(); + return true; +} + +static void Sh_DrawShadowlessLight(dlight_t *dl, vec3_t colour, qbyte *vvis) +{ + vec3_t mins, maxs; + + if (R_CullSphere(dl->origin, dl->radius)) + { + bench.numfrustumculled++; + return; //this should be the more common case + } + + if (dl->worldshadowmesh) + { + //fixme: check head node first? + if (!Sh_LeafInView(dl->worldshadowmesh->litleaves, vvis)) + { + bench.numpvsculled++; + return; + } + } + else + { + int i; + int leaf; + qbyte *lvis; + qbyte lvisb[MAX_MAP_LEAFS/8]; + if (cl.worldmodel->fromgame == fg_quake2 || cl.worldmodel->fromgame == fg_quake3) + i = cl.worldmodel->funcs.LeafnumForPoint(cl.worldmodel, r_refdef.vieworg); + else + i = r_viewleaf - cl.worldmodel->leafs; + + leaf = cl.worldmodel->funcs.LeafnumForPoint(cl.worldmodel, dl->origin); + lvis = cl.worldmodel->funcs.LeafPVS(cl.worldmodel, leaf, lvisb, sizeof(lvisb)); + + if (!dl->die) + SHM_BuildShadowVolumeMesh(dl, lvis, vvis); + + // if (!(lvis[i>>3] & (1<<(i&7)))) //light might not be visible, but it's effects probably should be. + // return; + if (!Sh_VisOverlaps(lvis, vvis)) //The two viewing areas do not intersect. + { + bench.numpvsculled++; + return; + } + } + + mins[0] = dl->origin[0] - dl->radius; + mins[1] = dl->origin[1] - dl->radius; + mins[2] = dl->origin[2] - dl->radius; + + maxs[0] = dl->origin[0] + dl->radius; + maxs[1] = dl->origin[1] + dl->radius; + maxs[2] = dl->origin[2] + dl->radius; + + +//sets up the gl scissor (and culls to view) + if (Sh_ScissorForBox(mins, maxs)) + return; //was culled. + + bench.numlights++; + + BE_SelectDLight(dl, colour); + BE_SelectMode(BEM_LIGHT, 0); + Sh_DrawEntLighting(dl, colour); +} + +void Sh_DrawLights(qbyte *vis) +{ + vec3_t colour; + dlight_t *dl; + int i; + unsigned int ignoreflags; + extern cvar_t r_shadow_realtime_world, r_shadow_realtime_dlight; + extern cvar_t r_shadow_realtime_world_shadows, r_shadow_realtime_dlight_shadows; + + if (!r_shadow_realtime_world.ival && !r_shadow_realtime_dlight.ival) + return; + + if (!gl_config.arb_shader_objects) + return; + + ignoreflags = (r_shadow_realtime_world.value?LFLAG_REALTIMEMODE:LFLAG_NORMALMODE); + + for (dl = cl_dlights+rtlights_first, i=rtlights_first; iradius) + continue; //dead + + if (!(dl->flags & ignoreflags)) + continue; + + if (dl->die) + { + colour[0] = dl->color[0]*10; + colour[1] = dl->color[1]*10; + colour[2] = dl->color[2]*10; + } + else + { + colour[0] = dl->color[0]; + colour[1] = dl->color[1]; + colour[2] = dl->color[2]; + } + if (dl->style) + { + if (cl_lightstyle[dl->style-1].colour & 1) + colour[0] *= d_lightstylevalue[dl->style-1]/255.0f; + else + colour[0] = 0; + if (cl_lightstyle[dl->style-1].colour & 2) + colour[1] *= d_lightstylevalue[dl->style-1]/255.0f; + else + colour[1] = 0; + if (cl_lightstyle[dl->style-1].colour & 4) + colour[2] *= d_lightstylevalue[dl->style-1]/255.0f; + else + colour[2] = 0; + } + + if (colour[0] < 0.001 && colour[1] < 0.001 && colour[2] < 0.001) + continue; //just switch these off. + + if (((!dl->die)?!r_shadow_realtime_world_shadows.value:!r_shadow_realtime_dlight_shadows.value) || dl->flags & LFLAG_NOSHADOWS) + { + Sh_DrawShadowlessLight(dl, colour, vis); + } + else if (dl->flags & LFLAG_SHADOWMAP) + { + Sh_DrawLameSpotLightShadowMap(dl, colour); + } + else + { + Sh_DrawStencilLight(dl, colour, vis); + } + } + + qglDisable(GL_SCISSOR_TEST); + BE_SelectMode(BEM_STANDARD, 0); + + if (developer.value) + Con_Printf("%i lights drawn, %i frustum culled, %i pvs culled, %i scissor culled\n", bench.numlights, bench.numfrustumculled, bench.numpvsculled, bench.numscissorculled); + memset(&bench, 0, sizeof(bench)); +} +#endif +#endif diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index 8f5b4720..29925695 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -1,6 +1,7 @@ #include "quakedef.h" -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h" +#include "gl_draw.h" //standard 1.1 opengl calls void (APIENTRY *qglAlphaFunc) (GLenum func, GLclampf ref); @@ -34,6 +35,7 @@ void (APIENTRY *qglFinish) (void); void (APIENTRY *qglFlush) (void); void (APIENTRY *qglFrustum) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); GLuint (APIENTRY *qglGenLists) (GLsizei range); +void (APIENTRY *qglGenTextures) (GLsizei n, GLuint *textures); GLenum (APIENTRY *qglGetError) (void); void (APIENTRY *qglGetFloatv) (GLenum pname, GLfloat *params); void (APIENTRY *qglGetIntegerv) (GLenum pname, GLint *params); @@ -108,6 +110,17 @@ void (APIENTRY *qglBufferSubDataARB)(GLenum target, GLint offset, GLsizei size, void *(APIENTRY *qglMapBufferARB)(GLenum target, GLenum access); GLboolean (APIENTRY *qglUnmapBufferARB)(GLenum target); +const GLubyte * (APIENTRY * qglGetStringi) (GLenum name, GLuint index); + +void (APIENTRY *qglGenFramebuffersEXT)(GLsizei n, GLuint* ids); +void (APIENTRY *qglDeleteFramebuffersEXT)(GLsizei n, const GLuint* ids); +void (APIENTRY *qglBindFramebufferEXT)(GLenum target, GLuint id); +void (APIENTRY *qglGenRenderbuffersEXT)(GLsizei n, GLuint* ids); +void (APIENTRY *qglDeleteRenderbuffersEXT)(GLsizei n, const GLuint* ids); +void (APIENTRY *qglBindRenderbufferEXT)(GLenum target, GLuint id); +void (APIENTRY *qglRenderbufferStorageEXT)(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height); +void (APIENTRY *qglFramebufferTexture2DEXT)(GLenum target, GLenum attachmentPoint, GLenum textureTarget, GLuint textureId, GLint level); + /* PFNGLPROGRAMSTRINGARBPROC qglProgramStringARB; PFNGLGETPROGRAMIVARBPROC qglGetProgramivARB; @@ -129,6 +142,7 @@ FTEPFNGLATTACHOBJECTARBPROC qglAttachObjectARB; FTEPFNGLGETINFOLOGARBPROC qglGetInfoLogARB; FTEPFNGLLINKPROGRAMARBPROC qglLinkProgramARB; FTEPFNGLGETUNIFORMLOCATIONARBPROC qglGetUniformLocationARB; +FTEPFNGLUNIFORMMATRIX4FVARBPROC qglUniformMatrix4fvARB; FTEPFNGLUNIFORM4FARBPROC qglUniform4fARB; FTEPFNGLUNIFORM4FVARBPROC qglUniform4fvARB; FTEPFNGLUNIFORM3FARBPROC qglUniform3fARB; @@ -176,13 +190,35 @@ float gldepthmin, gldepthmax; const char *gl_vendor; const char *gl_renderer; const char *gl_version; -const char *gl_extensions; +static const char *gl_extensions; -static int texture_extension_number = 1; +unsigned int gl_major_version; +unsigned int gl_minor_version; +static unsigned int gl_num_extensions; -int GL_AllocNewTexture(void) + +qboolean GL_CheckExtension(char *extname) { - return texture_extension_number++; + int i; + if (gl_num_extensions && qglGetStringi) + { + for (i = 0; i < gl_num_extensions; i++) + if (!strcmp(qglGetStringi(GL_EXTENSIONS, i), extname)) + return true; + } + + if (!gl_extensions) + return false; + + //note that this is not actually correct... + return !!strstr(gl_extensions, extname); +} + +texid_t GL_AllocNewTexture(void) +{ + texid_t r; + qglGenTextures(1, &r.num); + return r; } void APIENTRY GL_DrawRangeElementsEmul(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) @@ -233,6 +269,15 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) qglGenProgramsARB = NULL; */ + qglGenFramebuffersEXT = NULL; + qglDeleteFramebuffersEXT = NULL; + qglBindFramebufferEXT = NULL; + qglGenRenderbuffersEXT = NULL; + qglDeleteRenderbuffersEXT = NULL; + qglBindRenderbufferEXT = NULL; + qglRenderbufferStorageEXT = NULL; + qglFramebufferTexture2DEXT = NULL; + gl_config.arb_texture_non_power_of_two = false; gl_config.sgis_generate_mipmap = false; @@ -248,19 +293,19 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) gl_config.ext_texture_filter_anisotropic = 0; - if (strstr(gl_extensions, "GL_EXT_texture_filter_anisotropic")) + if (GL_CheckExtension("GL_EXT_texture_filter_anisotropic")) { qglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gl_config.ext_texture_filter_anisotropic); Con_SafePrintf("Anisotropic filter extension found (%dx max).\n",gl_config.ext_texture_filter_anisotropic); } - if (strstr(gl_extensions, "GL_ARB_texture_non_power_of_two")) + if (GL_CheckExtension("GL_ARB_texture_non_power_of_two")) gl_config.arb_texture_non_power_of_two = true; -// if (strstr(gl_extensions, "GL_SGIS_generate_mipmap")) //a suprising number of implementations have this broken. +// if (GL_CheckExtension("GL_SGIS_generate_mipmap")) //a suprising number of implementations have this broken. // gl_config.sgis_generate_mipmap = true; - if (strstr(gl_extensions, "GL_ARB_multitexture") && !COM_CheckParm("-noamtex")) + if (GL_CheckExtension("GL_ARB_multitexture") && !COM_CheckParm("-noamtex")) { //ARB multitexture is the popular choice. qglActiveTextureARB = (void *) getglext("glActiveTextureARB"); qglClientActiveTextureARB = (void *) getglext("glClientActiveTextureARB"); @@ -292,7 +337,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) } } - else if (strstr(gl_extensions, "GL_SGIS_multitexture") && !COM_CheckParm("-nomtex")) + else if (GL_CheckExtension("GL_SGIS_multitexture") && !COM_CheckParm("-nomtex")) { //SGIS multitexture, limited in many ways but basic functionality is identical to ARB Con_SafePrintf("Multitexture extensions found.\n"); qglMTexCoord2fSGIS = (void *) getglext("glMTexCoord2fSGIS"); @@ -303,15 +348,15 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) mtexid1 = GL_TEXTURE1_SGIS; } - if (strstr(gl_extensions, "GL_EXT_stencil_wrap")) + if (GL_CheckExtension("GL_EXT_stencil_wrap")) gl_config.ext_stencil_wrap = true; - if (strstr(gl_extensions, "GL_ATI_separate_stencil")) + if (GL_CheckExtension("GL_ATI_separate_stencil")) qglStencilOpSeparateATI = (void *) getglext("glStencilOpSeparateATI"); - if (strstr(gl_extensions, "GL_EXT_stencil_two_side")) + if (GL_CheckExtension("GL_EXT_stencil_two_side")) qglActiveStencilFaceEXT = (void *) getglext("glActiveStencilFaceEXT"); - if (strstr(gl_extensions, "GL_ARB_texture_compression")) + if (GL_CheckExtension("GL_ARB_texture_compression")) { qglCompressedTexImage2DARB = (void *)getglext("glCompressedTexImage2DARB"); qglGetCompressedTexImageARB = (void *)getglext("glGetCompressedTexImageARB"); @@ -325,37 +370,37 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) gl_config.arb_texture_compression = true; } - if (strstr(gl_extensions, "GL_ATI_pn_triangles")) + if (GL_CheckExtension("GL_ATI_pn_triangles")) { qglPNTrianglesfATI = (void *)getglext("glPNTrianglesfATI"); qglPNTrianglesiATI = (void *)getglext("glPNTrianglesiATI"); } - if (strstr(gl_extensions, "GL_EXT_texture_object")) + if (GL_CheckExtension("GL_EXT_texture_object")) { bindTexFunc = (void *)getglext("glBindTextureEXT"); if (!bindTexFunc) //grrr bindTexFunc = (void *)getglext("glBindTexture"); } - if (strstr(gl_extensions, "GL_EXT_compiled_vertex_array")) + if (GL_CheckExtension("GL_EXT_compiled_vertex_array")) { qglLockArraysEXT = (void *)getglext("glLockArraysEXT"); qglUnlockArraysEXT = (void *)getglext("glUnlockArraysEXT"); } - gl_config.tex_env_combine = !!strstr(gl_extensions, "GL_EXT_texture_env_combine"); - gl_config.env_add = !!strstr(gl_extensions, "GL_EXT_texture_env_add"); - gl_config.nv_tex_env_combine4 = !!strstr(gl_extensions, "GL_NV_texture_env_combine4"); + gl_config.tex_env_combine = GL_CheckExtension("GL_EXT_texture_env_combine"); + gl_config.env_add = GL_CheckExtension("GL_EXT_texture_env_add"); + gl_config.nv_tex_env_combine4 = GL_CheckExtension("GL_NV_texture_env_combine4"); - gl_config.arb_texture_env_combine = !!strstr(gl_extensions, "GL_ARB_texture_env_combine"); - gl_config.arb_texture_env_dot3 = !!strstr(gl_extensions, "GL_ARB_texture_env_dot3"); - gl_config.arb_texture_cube_map = !!strstr(gl_extensions, "GL_ARB_texture_cube_map"); + gl_config.arb_texture_env_combine = GL_CheckExtension("GL_ARB_texture_env_combine"); + gl_config.arb_texture_env_dot3 = GL_CheckExtension("GL_ARB_texture_env_dot3"); + gl_config.arb_texture_cube_map = GL_CheckExtension("GL_ARB_texture_cube_map"); if (gl_mtexarbable && gl_config.arb_texture_cube_map && gl_config.arb_texture_env_combine && gl_config.arb_texture_env_dot3 && !COM_CheckParm("-nobump") && gl_bump.value) gl_bumpmappingpossible = true; - if (strstr(gl_extensions, "GL_ARB_vertex_buffer_object")) + if (GL_CheckExtension("GL_ARB_vertex_buffer_object")) { qglGenBuffersARB = (void *)getglext("glGenBuffersARB"); qglDeleteBuffersARB = (void *)getglext("glDeleteBuffersARB"); @@ -367,7 +412,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) } /* - if (!!strstr(gl_extensions, "GL_ARB_fragment_program")) + if (GL_CheckExtension("GL_ARB_fragment_program")) { gl_config.arb_fragment_program = true; qglProgramStringARB = (void *)getglext("glProgramStringARB"); @@ -380,9 +425,9 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) // glslang //the gf2 to gf4 cards emulate vertex_shader and thus supports shader_objects. //but our code kinda requires both for clean workings. - if (!!strstr(gl_extensions, "GL_ARB_fragment_shader")) - if (!!strstr(gl_extensions, "GL_ARB_vertex_shader")) - if (!!strstr(gl_extensions, "GL_ARB_shader_objects")) + if (GL_CheckExtension("GL_ARB_fragment_shader")) + if (GL_CheckExtension("GL_ARB_vertex_shader")) + if (GL_CheckExtension("GL_ARB_shader_objects")) { gl_config.arb_shader_objects = true; qglCreateProgramObjectARB = (void *)getglext("glCreateProgramObjectARB"); @@ -396,6 +441,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) qglGetInfoLogARB = (void *)getglext("glGetInfoLogARB"); qglLinkProgramARB = (void *)getglext("glLinkProgramARB"); qglGetUniformLocationARB = (void *)getglext("glGetUniformLocationARB"); + qglUniformMatrix4fvARB = (void *)getglext("glUniformMatrix4fvARB"); qglUniform4fARB = (void *)getglext("glUniform4fARB"); qglUniform4fvARB = (void *)getglext("glUniform4fvARB"); qglUniform3fARB = (void *)getglext("glUniform3fARB"); @@ -405,6 +451,18 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name)) GL_InitSceneProcessingShaders(); } + + if (GL_CheckExtension("GL_ARB_fragment_shader")) + { + qglGenFramebuffersEXT = (void *)getglext("glGenFramebuffersEXT"); + qglDeleteFramebuffersEXT = (void *)getglext("glDeleteFramebuffersEXT"); + qglBindFramebufferEXT = (void *)getglext("glBindFramebufferEXT"); + qglGenRenderbuffersEXT = (void *)getglext("glGenRenderbuffersEXT"); + qglDeleteRenderbuffersEXT = (void *)getglext("glDeleteRenderbuffersEXT"); + qglBindRenderbufferEXT = (void *)getglext("glBindRenderbufferEXT"); + qglRenderbufferStorageEXT = (void *)getglext("glRenderbufferStorageEXT"); + qglFramebufferTexture2DEXT = (void *)getglext("glFramebufferTexture2DEXT"); + } } @@ -443,6 +501,7 @@ GLhandleARB GLSlang_CreateShader (char *precompilerconstants, char *shadersource if(!compiled) { qglGetInfoLogARB(shader, sizeof(str), NULL, str); + qglDeleteObjectARB(shader); switch (shadertype) { case GL_FRAGMENT_SHADER_ARB: @@ -473,6 +532,10 @@ GLhandleARB GLSlang_CreateProgramObject (GLhandleARB vert, GLhandleARB frag) qglLinkProgramARB(program); + //flag the source objects for deletion, they'll only be deleted when they're no longer attached to anything + qglDeleteObjectARB(vert); + qglDeleteObjectARB(frag); + qglGetObjectParameterivARB(program, GL_OBJECT_LINK_STATUS_ARB, &linked); if(!linked) @@ -496,7 +559,12 @@ GLhandleARB GLSlang_CreateProgram(char *precompilerconstants, char *vert, char * vs = GLSlang_CreateShader(precompilerconstants, vert, GL_VERTEX_SHADER_ARB); fs = GLSlang_CreateShader(precompilerconstants, frag, GL_FRAGMENT_SHADER_ARB); if (!vs || !fs) + { + //delete ignores 0s. + qglDeleteObjectARB(vs); + qglDeleteObjectARB(fs); return 0; + } return GLSlang_CreateProgramObject(vs, fs); } @@ -542,6 +610,7 @@ void GL_Init(void *(*getglfunction) (char *name)) qglFinish = (void *)getglcore("glFinish"); qglFlush = (void *)getglcore("glFlush"); qglFrustum = (void *)getglcore("glFrustum"); + qglGenTextures = (void *)getglcore("glGenTextures"); qglGetFloatv = (void *)getglcore("glGetFloatv"); qglGetIntegerv = (void *)getglcore("glGetIntegerv"); qglGetString = (void *)getglcore("glGetString"); @@ -614,6 +683,8 @@ void GL_Init(void *(*getglfunction) (char *name)) qglPolygonOffset = (void *)getglext("glPolygonOffset"); + qglGetStringi = (void *)getglext("glGetStringi"); + //used by heightmaps qglGenLists = (void*)getglcore("glGenLists"); qglNewList = (void*)getglcore("glNewList"); @@ -634,37 +705,144 @@ void GL_Init(void *(*getglfunction) (char *name)) gl_version = qglGetString (GL_VERSION); Con_SafePrintf ("GL_VERSION: %s\n", gl_version); - gl_extensions = qglGetString (GL_EXTENSIONS); - Con_DPrintf ("GL_EXTENSIONS: %s\n", gl_extensions); - if (!gl_extensions) - Sys_Error("no extensions\n"); + if (qglGetError()) + Con_Printf("glGetError %s:%i\n", __FILE__, __LINE__); + qglGetIntegerv(GL_MAJOR_VERSION, &gl_major_version); + qglGetIntegerv(GL_MINOR_VERSION, &gl_minor_version); + if (qglGetError()) + { + gl_major_version = 1; + gl_minor_version = 1; + } + qglGetIntegerv(GL_NUM_EXTENSIONS, &gl_num_extensions); + if (!qglGetError()) + { + int i; + if (developer.value) + { + Con_DPrintf ("GL_EXTENSIONS:"); + for (i = 0; i < gl_num_extensions; i++) + Con_DPrintf (" %s", qglGetStringi(GL_EXTENSIONS, i)); + Con_DPrintf ("\n"); + } + else + Con_Printf ("GL_EXTENSIONS: %i extensions\n", gl_num_extensions); + gl_extensions = NULL; + } + else + { + gl_num_extensions = 0; + gl_extensions = qglGetString (GL_EXTENSIONS); + Con_DPrintf ("GL_EXTENSIONS: %s\n", gl_extensions); + + if (!gl_extensions) + Sys_Error("no extensions\n"); + } GL_CheckExtensions (getglfunction); qglClearColor (0,0,0,0); //clear to black so that it looks a little nicer on start. qglClear(GL_COLOR_BUFFER_BIT); - qglCullFace(GL_FRONT); - qglEnable(GL_TEXTURE_2D); - - qglEnable(GL_ALPHA_TEST); - qglAlphaFunc(GL_GREATER, 0.666); qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); qglShadeModel (GL_FLAT); - texture_extension_number = 1; - - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - - qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - -// qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); } unsigned int d_8to24rgbtable[256]; + + + + + +rendererinfo_t openglrendererinfo = { + "OpenGL", + { + "gl", + "opengl", + "hardware", + }, + QR_OPENGL, + + + R2D_SafePicFromWad, + R2D_SafeCachePic, + GLDraw_Init, + GLDraw_ReInit, + GLDraw_Crosshair, + R2D_ScalePic, + R2D_SubPic, + GLDraw_TransPicTranslate, + R2D_ConsoleBackground, + R2D_EditorBackground, + R2D_TileClear, + GLDraw_Fill, + GLDraw_FillRGB, + GLDraw_FadeScreen, + GLDraw_BeginDisc, + GLDraw_EndDisc, + + R2D_Image, + R2D_ImageColours, + + GLR_Init, + GLR_DeInit, + GLR_RenderView, + + + GLR_NewMap, + GLR_PreNewMap, + GLR_LightPoint, + GLR_PushDlights, + + + GLR_AddStain, + GLR_LessenStains, + + MediaGL_ShowFrameBGR_24_Flip, + MediaGL_ShowFrameRGBA_32, + MediaGL_ShowFrame8bit, + + + RMod_Init, + RMod_ClearAll, + RMod_ForName, + RMod_FindName, + RMod_Extradata, + RMod_TouchModel, + + RMod_NowLoadExternal, + RMod_Think, + + Mod_GetTag, + Mod_TagNumForName, + Mod_SkinNumForName, + Mod_FrameNumForName, + Mod_FrameDuration, + + GLVID_Init, + GLVID_DeInit, + GLVID_LockBuffer, + GLVID_UnlockBuffer, + GLD_BeginDirectRect, + GLD_EndDirectRect, + GLVID_ForceLockState, + GLVID_ForceUnlockedAndReturnState, + GLVID_SetPalette, + GLVID_ShiftPalette, + GLVID_GetRGBInfo, + + GLVID_SetCaption, //setcaption + + + GLSCR_UpdateScreen, + + "" +}; + #endif diff --git a/engine/gl/gl_vidlinuxglx.c b/engine/gl/gl_vidlinuxglx.c index cc469b3e..7b1978aa 100644 --- a/engine/gl/gl_vidlinuxglx.c +++ b/engine/gl/gl_vidlinuxglx.c @@ -395,12 +395,12 @@ static void GetEvent(void) switch (event.type) { case ResizeRequest: - glwidth = event.xresizerequest.width; - glheight = event.xresizerequest.height; + vid.pixelwidth = event.xresizerequest.width; + vid.pixelheight = event.xresizerequest.height; break; case ConfigureNotify: - glwidth = event.xconfigurerequest.width; - glheight = event.xconfigurerequest.height; + vid.pixelwidth = event.xconfigurerequest.width; + vid.pixelheight = event.xconfigurerequest.height; break; case KeyPress: b = XLateKey(&event.xkey, &uc); @@ -722,10 +722,6 @@ GL_BeginRendering */ void GL_BeginRendering (int *x, int *y, int *width, int *height) { - *x = *y = 0; - *width = glwidth; - *height = glheight; - // if (!wglMakeCurrent( maindc, baseRC )) // Sys_Error ("wglMakeCurrent failed"); @@ -762,9 +758,9 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette) unsigned long mask; Window root; XVisualInfo *visinfo; + qboolean fullscreen = false; #ifdef WITH_VMODE - qboolean fullscreen = false; int MajorVersion, MinorVersion; if (info->fullscreen) @@ -953,8 +949,8 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette) return false; } - glwidth = info->width; - glheight = info->height; + vid.pixelwidth = info->width; + vid.pixelheight = info->height; if (vid.conheight > info->height) vid.conheight = info->height; diff --git a/engine/gl/gl_vidnt.c b/engine/gl/gl_vidnt.c index 802e509d..3945678f 100644 --- a/engine/gl/gl_vidnt.c +++ b/engine/gl/gl_vidnt.c @@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // gl_vidnt.c -- NT GL vid component #include "quakedef.h" -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h" #include "winquake.h" #include "resource.h" @@ -170,6 +170,10 @@ extern cvar_t vid_desktopgamma; extern cvar_t gl_lateswap; extern cvar_t vid_preservegamma; +extern cvar_t vid_gl_context_version; +extern cvar_t vid_gl_context_debug; +extern cvar_t vid_gl_context_forwardcompatible; + int window_center_x, window_center_y, window_x, window_y, window_width, window_height; RECT window_rect; @@ -228,6 +232,16 @@ BOOL (APIENTRY *qSetDeviceGammaRamp)(HDC hDC, GLvoid *ramp); BOOL (APIENTRY *qwglChoosePixelFormatARB)(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int* piFormats, UINT* nNumFormats); +HGLRC (APIENTRY *qwglCreateContextAttribsARB)(HDC hDC, HGLRC hShareContext, const int *attribList); +#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 +#define WGL_CONTEXT_FLAGS_ARB 0x2094 +#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 +#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 +#define ERROR_INVALID_VERSION_ARB 0x2095 + + qboolean GLInitialise (char *renderer) { if (hInstGL) @@ -675,6 +689,7 @@ int GLVID_SetMode (rendererstate_t *info, unsigned char *palette) // Set either the fullscreen or windowed mode qwglChoosePixelFormatARB = NULL; + qwglCreateContextAttribsARB = NULL; stat = CreateMainWindow(info); if (stat) { @@ -848,8 +863,8 @@ void VID_UpdateWindowStatus (HWND hWnd) window_y = p.y; window_width = WindowRect.right - WindowRect.left; window_height = WindowRect.bottom - WindowRect.top; - glwidth = window_width; - glheight = window_height; + vid.pixelwidth = window_width; + vid.pixelheight = window_height; window_rect.left = window_x; window_rect.top = window_y; @@ -940,9 +955,81 @@ qboolean VID_AttachGL (rendererstate_t *info) return false; } + qwglCreateContextAttribsARB = getglfunc("wglCreateContextAttribsARB"); +#ifdef _DEBUG + //attempt to promote that to opengl3. + if (qwglCreateContextAttribsARB) + { + HGLRC opengl3; + int attribs[7]; + char *mv; + int i = 0; + + mv = vid_gl_context_version.string; + while (*mv) + { + if (*mv++ == '.') + break; + } + + if (*vid_gl_context_version.string) + { + attribs[i++] = WGL_CONTEXT_MAJOR_VERSION_ARB; + attribs[i++] = (int)vid_gl_context_version.value; + } + if (*mv) + { + attribs[i++] = WGL_CONTEXT_MINOR_VERSION_ARB; + attribs[i++] = atoi(mv); + } + + //flags + attribs[i+1] = 0; + if (vid_gl_context_debug.value) + attribs[i+1] |= WGL_CONTEXT_DEBUG_BIT_ARB; + if (vid_gl_context_forwardcompatible.value) + attribs[i+1] |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; + + if (attribs[i+1]) + { + attribs[i] = WGL_CONTEXT_FLAGS_ARB; + i += 2; + } + + attribs[i] = 0; + + if (!i) + { + //just use the default (ie: max = opengl 2.1 or so) + } + else if ((opengl3 = qwglCreateContextAttribsARB(maindc, NULL, attribs))) + { + qwglMakeCurrent(NULL, NULL); + qwglDeleteContext(baseRC); + + baseRC = opengl3; + if (!qwglMakeCurrent( maindc, baseRC )) + { + Con_SafePrintf(CON_ERROR "wglMakeCurrent failed\n"); //green to make it show. + return false; + } + } + else + { + DWORD error = GetLastError(); + if (error == ERROR_INVALID_VERSION_ARB) + Con_Printf("Unsupported OpenGL context version (%s).\n", vid_gl_context_version.string); + else + Con_Printf("Unknown error creating an OpenGL (%s) Context.\n", vid_gl_context_version.string); + } + } +#endif + TRACE(("dbg: VID_AttachGL: GL_Init\n")); GL_Init(getglfunc); + qwglChoosePixelFormatARB = getglfunc("wglChoosePixelFormatARB"); + qwglSwapIntervalEXT = getglfunc("wglSwapIntervalEXT"); if (qwglSwapIntervalEXT && *_vid_wait_override.string) { @@ -966,11 +1053,10 @@ GL_BeginRendering ================= */ -void GL_BeginRendering (int *x, int *y, int *width, int *height) +void GL_BeginRendering (void) { - *x = *y = 0; - *width = WindowRect.right - WindowRect.left; - *height = WindowRect.bottom - WindowRect.top; + vid.pixelwidth = WindowRect.right - WindowRect.left; + vid.pixelheight = WindowRect.bottom - WindowRect.top; // if (!wglMakeCurrent( maindc, baseRC )) // Sys_Error ("wglMakeCurrent failed"); @@ -1153,6 +1239,15 @@ void GLVID_ShiftPalette (unsigned char *palette) } } +void GLVID_Crashed(void) +{ + if (qSetDeviceGammaRamp && gammaworks) + { + OblitterateOldGamma(); + qSetDeviceGammaRamp(maindc, originalgammaramps); + } +} + void GLVID_Shutdown (void) { if (qSetDeviceGammaRamp) @@ -1316,8 +1411,13 @@ BOOL bSetupPixelFormat(HDC hDC) 0, // shift bit ignored 0, // no accumulation buffer 0, 0, 0, 0, // accum bits ignored - 32, // 32-bit z-buffer +#ifndef RTLIGHTS + 32, // 32-bit z-buffer + 0, // 0 stencil, don't need it unless we're using rtlights +#else + 24, // 24-bit z-buffer 8, // stencil buffer +#endif 0, // no auxiliary buffer PFD_MAIN_PLANE, // main layer 0, // reserved @@ -1676,13 +1776,13 @@ LONG WINAPI GLMainWndProc ( } -qboolean GLVID_Is8bit() { +qboolean GLVID_Is8bit(void) { return is8bit; } #define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB -void VID_Init8bitPalette() +void VID_Init8bitPalette(void) { // Check for 8bit Extensions and initialize them. int i; @@ -1690,15 +1790,15 @@ void VID_Init8bitPalette() char *oldPalette, *newPalette; qglColorTableEXT = (void *)qwglGetProcAddress("glColorTableEXT"); - if (!qglColorTableEXT || strstr(gl_extensions, "GL_EXT_shared_texture_palette") || - COM_CheckParm("-no8bit")) + if (!qglColorTableEXT || !GL_CheckExtension("GL_EXT_shared_texture_palette") || COM_CheckParm("-no8bit")) return; Con_SafePrintf("8-bit GL extensions enabled.\n"); - qglEnable( GL_SHARED_TEXTURE_PALETTE_EXT ); + qglEnable(GL_SHARED_TEXTURE_PALETTE_EXT); oldPalette = (char *) d_8to24rgbtable; //d_8to24table3dfx; newPalette = thePalette; - for (i=0;i<256;i++) { + for (i=0;i<256;i++) + { *newPalette++ = *oldPalette++; *newPalette++ = *oldPalette++; *newPalette++ = *oldPalette++; @@ -1747,13 +1847,11 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette) if (!RegisterClass (&wc)) //this isn't really fatal, we'll let the CreateWindow fail instead. MessageBox(NULL, "RegisterClass failed", "GAH", 0); - hIcon = LoadIcon (global_hInstance, MAKEINTRESOURCE (IDI_ICON2)); + hIcon = LoadIcon (global_hInstance, MAKEINTRESOURCE (IDI_ICON1)); vid_initialized = false; vid_initializing = true; - vid.maxwarpwidth = WARP_WIDTH; - vid.maxwarpheight = WARP_HEIGHT; vid.colormap = host_colormap; if (hwnd_dialog) diff --git a/engine/gl/gl_warp.c b/engine/gl/gl_warp.c index a9f3d9ad..d99d5269 100644 --- a/engine/gl/gl_warp.c +++ b/engine/gl/gl_warp.c @@ -20,545 +20,89 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // gl_warp.c -- sky and water polygons #include "quakedef.h" -#if defined(RGLQUAKE) || defined(D3DQUAKE) +#if defined(GLQUAKE) || defined(D3DQUAKE) #include "glquake.h" -#ifdef D3DQUAKE -#include "d3dquake.h" -#endif -#ifdef Q3SHADERS #include "shader.h" -#endif #include - -extern void GL_DrawAliasMesh (mesh_t *mesh, int texnum); - -static void GL_DrawProgram_WaterChain(msurface_t *fa); -static void GL_DrawProgram_SkyChain(msurface_t *fa); static void R_CalcSkyChainBounds (msurface_t *s); static void GL_DrawSkyGrid (texture_t *tex); static void GL_DrawSkySphere (msurface_t *fa); static void GL_SkyForceDepth(msurface_t *fa); -void D3D7_DrawSkySphere (msurface_t *fa); -void D3D9_DrawSkySphere (msurface_t *fa); +static void GL_DrawSkyBox (texid_t *texnums, msurface_t *s); -extern model_t *loadmodel; - -int skytexturenum; +//static int skytexturenum; static float speedscale; // for top sky and bottom sky -static float skyrotate; -static vec3_t skyaxis; +//static float skyrotate; +//static vec3_t skyaxis; -static qboolean usingskybox; +//static qboolean usingskybox; -static msurface_t *warpface; +//static msurface_t *warpface; -extern cvar_t r_skyboxname; +//extern cvar_t r_skyboxname; extern cvar_t gl_skyboxdist; extern cvar_t r_fastsky; extern cvar_t r_fastskycolour; -static char defaultskybox[MAX_QPATH]; +//static char defaultskybox[MAX_QPATH]; -/*static*/ int skyprogram; -/*static*/ int skyprogram_time; -/*static*/ int skyprogram_eyepos; +//static int skyprogram; +//static int skyprogram_time; +//static int skyprogram_eyepos; -/*static*/ int waterprogram; -/*static*/ int waterprogram_time; +//static int waterprogram; +//static int waterprogram_time; -int skyboxtex[6]; -static vec3_t glskycolor; - -void GLR_Fastskycolour_Callback(struct cvar_s *var, char *oldvalue) -{ - SCR_StringToRGB(var->string, glskycolor, 255); -} +static qboolean overrideskybox; +static texid_t overrideskyboxtex[6]; +//static vec3_t glskycolor; -static void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs) -{ - int i, j; - float *v; - - mins[0] = mins[1] = mins[2] = 9999; - maxs[0] = maxs[1] = maxs[2] = -9999; - v = verts; - for (i=0 ; i maxs[j]) - maxs[j] = *v; - } -} - -void GL_Warp_Init(void) -{ - char *progtext; - static char *skyglslprog = - "#ifdef VERTEX_SHADER\n" - "varying vec3 pos;\n" - - "void main (void)\n" - "{\n" - " pos = gl_Vertex.xyz;\n" - " gl_Position = ftransform();\n" - "}\n" - "#endif\n" - - "#ifdef FRAGMENT_SHADER\n" - "uniform sampler2D solidt;\n" - "uniform sampler2D transt;\n" - - "uniform float time;\n" - "uniform vec3 eyepos;\n" - "varying vec3 pos;\n" - - "void main (void)\n" - "{\n" - " vec2 tccoord;\n" - - " vec3 dir = pos - eyepos;\n" - - " dir.z *= 3.0;\n" - " dir.xy /= 0.5*length(dir);\n" - - " tccoord = (dir.xy + time*0.03125);\n" - " vec3 solid = vec3(texture2D(solidt, tccoord));\n" - - " tccoord = (dir.xy + time*0.0625);\n" - " vec4 clouds = texture2D(transt, tccoord);\n" - - " gl_FragColor.rgb = solid*(1.0-clouds.a) + clouds.rgb*clouds.a;\n" -// " gl_FragColor.rgb = solid+clouds.rgb;\n" - "}\n" - "#endif\n" - ; - - static char *waterglslprog = - "#ifdef VERTEX_SHADER\n" - "varying vec3 pos;\n" - "varying vec2 tc;\n" - - "void main (void)\n" - "{\n" - " tc = gl_MultiTexCoord0.st;\n" - " gl_Position = ftransform();\n" - "}\n" - "#endif\n" - - "#ifdef FRAGMENT_SHADER\n" - "uniform sampler2D watertexture;\n" - "uniform float time;\n" - "varying vec2 tc;\n" - - "void main (void)\n" - "{\n" - " vec2 ntc;\n" - " ntc.s = tc.s + sin(tc.t+time)*0.125;\n" - " ntc.t = tc.t + sin(tc.s+time)*0.125;\n" - " vec3 ts = vec3(texture2D(watertexture, ntc));\n" - - " gl_FragColor.rgb = ts;\n" - "}\n" - "#endif\n" - ; - - if (FS_LoadFile("quakesky.glsl", &progtext) < 0) - progtext = skyglslprog; - skyprogram = GLSlang_CreateProgram("", progtext, progtext); - if (progtext != skyglslprog) - FS_FreeFile(progtext); - - if (skyprogram) - { - GLSlang_UseProgram(skyprogram); - - qglUniform1iARB(qglGetUniformLocationARB(skyprogram, "solidt"), 0); - qglUniform1iARB(qglGetUniformLocationARB(skyprogram, "transt"), 1); - - skyprogram_time = qglGetUniformLocationARB(skyprogram, "time"); - skyprogram_eyepos = qglGetUniformLocationARB(skyprogram, "eyepos"); - - GLSlang_UseProgram(0); - } - - if (FS_LoadFile("quakewater.glsl", &progtext) < 0) - progtext = waterglslprog; - waterprogram = GLSlang_CreateProgram("", progtext, progtext); - if (progtext != waterglslprog) - FS_FreeFile(progtext); - - if (waterprogram) - { - GLSlang_UseProgram(waterprogram); - - qglUniform1iARB(qglGetUniformLocationARB(waterprogram, "watertexture"), 0); - waterprogram_time = qglGetUniformLocationARB(waterprogram, "time"); - - GLSlang_UseProgram(0); - } -} //========================================================= -/* -// speed up sin calculations - Ed -float turbsin[] = -{ - #include "gl_warp_sin.h" -}; -#define TURBSCALE (256.0 / (2 * M_PI)) -*/ -/* -============= -EmitWaterPolys - -Does a water warp on the pre-fragmented glpoly_t chain -============= -*/ -#ifdef RGLQUAKE -void EmitWaterPolys (msurface_t *fa, float basealpha) -{ - float a; - int l; - extern cvar_t r_waterlayers; - //the code prior to april 2005 gave a nicer result, but was incompatible with meshes and required poly lists instead - //the new code uses vertex arrays but sacrifises the warping. We're left only with scaling. - //The default settings still look nicer than original quake but not pre-april. - //in the plus side, you can never see the junction glitches of the old warping. :) - -#ifdef Q3SHADERS - if (fa->texinfo->texture->shader) - { - meshbuffer_t mb; - mb.sortkey = 0; - mb.infokey = 0; - mb.dlightbits = 0; - mb.entity = &r_worldentity; - mb.shader = fa->texinfo->texture->shader; - mb.fog = NULL; - mb.mesh = fa->mesh; - r_worldentity.shaderRGBAf[3] = basealpha; - R_PushMesh(mb.mesh, mb.shader->features); - r_worldentity.shaderRGBAf[3] = 1; - R_RenderMeshBuffer(&mb, false); - return; - } -#endif - if (!*r_waterlayers.string) - { - if (waterprogram) - { - GL_DrawProgram_WaterChain(fa); - return; - } - r_waterlayers.value = 3; - } - if (r_waterlayers.value>=1) - { - qglEnable(GL_BLEND); //to ensure. - qglMatrixMode(GL_TEXTURE); - fa->mesh->colors_array=NULL; - for (a=basealpha,l = 0; l < r_waterlayers.value; l++,a=a*4/6) - { - qglPushMatrix(); - qglColor4f(1, 1, 1, a); - qglTranslatef (sin(cl.time+l*4) * 0.04f+cos(cl.time/2+l)*0.02f+cl.time/(64+l*8), cos(cl.time+l*4) * 0.06f+sin(cl.time/2+l)*0.02f+cl.time/(16+l*2), 0); - GL_DrawAliasMesh(fa->mesh, fa->texinfo->texture->tn.base); - qglPopMatrix(); - } - qglMatrixMode(GL_MODELVIEW); - qglDisable(GL_BLEND); //to ensure. - } - else //dull (fast) single player - { - qglMatrixMode(GL_TEXTURE); - qglPushMatrix(); - qglTranslatef (sin(cl.time) * 0.4f, cos(cl.time) * 0.06f, 0); - fa->mesh->colors_array = NULL; - GL_DrawAliasMesh(fa->mesh, fa->texinfo->texture->tn.base); - qglPopMatrix(); - qglMatrixMode(GL_MODELVIEW); - } -} - -#endif - -void EmitWaterPolyChain (msurface_t *s, float basealpha) -{ - float a; - int l; - extern cvar_t r_waterlayers; - -#ifdef Q3SHADERS - if (s->texinfo->texture->shader) - { - meshbuffer_t mb; - mb.sortkey = 0; - mb.infokey = 0; - mb.dlightbits = 0; - mb.entity = &r_worldentity; - mb.shader = s->texinfo->texture->shader; - mb.fog = NULL; - mb.mesh = s->mesh; - r_worldentity.shaderRGBAf[3] = basealpha; - while(s) - { - if (R_MeshWillExceed(s->mesh)) - R_RenderMeshBuffer(&mb, false); - R_PushMesh(s->mesh, mb.shader->features); - } - r_worldentity.shaderRGBAf[3] = 1; - R_RenderMeshBuffer(&mb, false); - return; - } -#endif - if (!*r_waterlayers.string) - { - if (waterprogram) - { - GL_DrawProgram_WaterChain(s); - return; - } - r_waterlayers.value = 3; - } - if (r_waterlayers.value>=1) - { - msurface_t *fa; - qglEnable(GL_BLEND); //to ensure. - qglMatrixMode(GL_TEXTURE); - for (a=basealpha,l = 0; l < r_waterlayers.value; l++,a=a*4/6) - { - qglPushMatrix(); - qglColor4f(1, 1, 1, a); - qglTranslatef (sin(cl.time+l*4) * 0.04f+cos(cl.time/2+l)*0.02f+cl.time/(64+l*8), cos(cl.time+l*4) * 0.06f+sin(cl.time/2+l)*0.02f+cl.time/(16+l*2), 0); - for (fa = s; fa; fa = fa->texturechain) - { - fa->mesh->colors_array=NULL; - GL_DrawAliasMesh(fa->mesh, fa->texinfo->texture->tn.base); - } - qglPopMatrix(); - } - qglMatrixMode(GL_MODELVIEW); - qglDisable(GL_BLEND); //to ensure. - } - else //dull (fast) single player - { - msurface_t *fa; - qglMatrixMode(GL_TEXTURE); - qglPushMatrix(); - qglTranslatef (sin(cl.time) * 0.4f, cos(cl.time) * 0.06f, 0); - for (fa = s; fa; fa = fa->texturechain) - { - fa->mesh->colors_array=NULL; - GL_DrawAliasMesh(fa->mesh, fa->texinfo->texture->tn.base); - } - qglPopMatrix(); - qglMatrixMode(GL_MODELVIEW); - } -} - /* ================= GL_DrawSkyChain ================= */ -#ifdef RGLQUAKE +#ifdef GLQUAKE static void R_DrawSkyBoxChain (msurface_t *s); -void GL_DrawSkyChain (msurface_t *s) +void R_DrawSkyChain (msurface_t *s) { - msurface_t *fa; + texid_t *skyboxtex; - GL_DisableMultitexture(); -#ifdef Q3SHADERS - if (!skyboxtex[0] && !usingskybox) + skyboxtex = s->texinfo->texture->shader->skydome->farbox_textures; + + R_CalcSkyChainBounds(s); + +#ifdef GLQUAKE + if (qrenderer == QR_OPENGL) { - int i; - if (s->texinfo->texture->shader && s->texinfo->texture->shader->skydome) - { - for (i = 0; i < 6; i++) - { - skyboxtex[i] = s->texinfo->texture->shader->skydome->farbox_textures[i]; - } - } + GL_DrawSkyBox (skyboxtex, s); + GL_SkyForceDepth(s); + return; } #endif - R_IBrokeTheArrays(); - qglDisable(GL_BLEND); - qglDisable(GL_ALPHA_TEST); - - if (r_fastsky.value>0) //this is for visability only... we'd otherwise not stoop this low (and this IS low) + if (*r_fastsky.string) { - qglDisable(GL_TEXTURE_2D); - qglColor3f(glskycolor[0], glskycolor[1], glskycolor[2]); - qglDisableClientState( GL_COLOR_ARRAY ); - qglEnableClientState( GL_VERTEX_ARRAY ); - for (fa=s ; fa ; fa=fa->texturechain) - { - qglVertexPointer(3, GL_FLOAT, 0, fa->mesh->xyz_array); - qglDrawElements(GL_TRIANGLES, fa->mesh->numindexes, GL_INDEX_TYPE, fa->mesh->indexes); - } - qglColor3f(1, 1, 1); - qglEnable(GL_TEXTURE_2D); - R_IBrokeTheArrays(); - return; - } - - if (s->texinfo->texture->shader) - { - //this is the only pathway that actually uses shaders properly - GL_DrawSkySphere(s); - } - else if (skyprogram && !usingskybox) - { - GL_DrawProgram_SkyChain(s); + GL_DrawSkyGrid(s->texinfo->texture); + GL_SkyForceDepth(s); } else { - R_CalcSkyChainBounds(s); - - #ifdef RGLQUAKE - if (usingskybox) - if (qrenderer == QR_OPENGL) - { - GL_DrawSkyBox (s); - GL_SkyForceDepth(s); - R_IBrokeTheArrays(); - return; - } - #endif - - if (*r_fastsky.string) - { - GL_DrawSkyGrid(s->texinfo->texture); - GL_SkyForceDepth(s); - } - else - { - GL_DrawSkySphere(s); - GL_SkyForceDepth(s); - } + GL_DrawSkySphere(s); + GL_SkyForceDepth(s); } R_IBrokeTheArrays(); } #endif -#ifdef D3DQUAKE -static void R_DrawSkyBoxChain (msurface_t *s); -void D3D7_DrawSkyChain (msurface_t *s) -{ - //msurface_t *fa; - -#ifdef Q3SHADERS - if (!solidskytexture&&!usingskybox) - { - int i; - if (s->texinfo->texture->shader && s->texinfo->texture->shader->skydome) - { - for (i = 0; i < 6; i++) - { - skyboxtex[i] = s->texinfo->texture->shader->skydome->farbox_textures[i]; - } - solidskytexture = 1; - } - } -#endif -/* - if (r_fastsky.value||(!solidskytexture&&!usingskybox)) //this is for visability only... we'd otherwise not stoop this low (and this IS low) - { - int fc; - qbyte *pal; - fc = r_fastskycolour.value; - if (fc > 255) - fc = 255; - if (fc < 0) - fc = 0; - pal = host_basepal+fc*3; - qglDisable(GL_TEXTURE_2D); - qglColor3f(pal[0]/255.0f, pal[1]/255.0f, pal[2]/255.0f); - qglDisableClientState( GL_COLOR_ARRAY ); - for (fa=s ; fa ; fa=fa->texturechain) - { - qglVertexPointer(3, GL_FLOAT, 0, fa->mesh->xyz_array); - qglDrawElements(GL_TRIANGLES, fa->mesh->numindexes, GL_INDEX_TYPE, fa->mesh->indexes); - } - R_IBrokeTheArrays(); - - qglColor3f(1, 1, 1); - qglEnable(GL_TEXTURE_2D); - return; - } -*/ -/* if (usingskybox) - { - R_DrawSkyBoxChain(s); - return; - } -*/ - D3D7_DrawSkySphere(s); -} - -void D3D9_DrawSkyChain (msurface_t *s) -{ - //msurface_t *fa; - -#ifdef Q3SHADERS - if (!solidskytexture&&!usingskybox) - { - int i; - if (s->texinfo->texture->shader && s->texinfo->texture->shader->skydome) - { - for (i = 0; i < 6; i++) - { - skyboxtex[i] = s->texinfo->texture->shader->skydome->farbox_textures[i]; - } - solidskytexture = 1; - } - } -#endif -/* - if (r_fastsky.value||(!solidskytexture&&!usingskybox)) //this is for visability only... we'd otherwise not stoop this low (and this IS low) - { - int fc; - qbyte *pal; - fc = r_fastskycolour.value; - if (fc > 255) - fc = 255; - if (fc < 0) - fc = 0; - pal = host_basepal+fc*3; - qglDisable(GL_TEXTURE_2D); - qglColor3f(pal[0]/255.0f, pal[1]/255.0f, pal[2]/255.0f); - qglDisableClientState( GL_COLOR_ARRAY ); - for (fa=s ; fa ; fa=fa->texturechain) - { - qglVertexPointer(3, GL_FLOAT, 0, fa->mesh->xyz_array); - qglDrawElements(GL_TRIANGLES, fa->mesh->numindexes, GL_INDEX_TYPE, fa->mesh->indexes); - } - R_IBrokeTheArrays(); - - qglColor3f(1, 1, 1); - qglEnable(GL_TEXTURE_2D); - return; - } -*/ -/* if (usingskybox) - { - R_DrawSkyBoxChain(s); - return; - } -*/ - D3D9_DrawSkySphere(s); -} -#endif - /* ================================================================= @@ -567,106 +111,6 @@ void D3D9_DrawSkyChain (msurface_t *s) ================================================================= */ - -/* -================== -R_LoadSkys -================== -*/ -static char *skyname_suffix[][6] = { - {"px", "py", "nx", "ny", "pz", "nz"}, - {"posx", "posy", "negx", "negy", "posz", "negz"}, - {"rt", "bk", "lf", "ft", "up", "dn"}, - {"_px", "_py", "_nx", "_ny", "_pz", "_nz"}, - {"_posx", "_posy", "_negx", "_negy", "_posz", "_negz"}, - {"_rt", "_bk", "_lf", "_ft", "_up", "_dn"} -}; - -static char *skyname_pattern[] = { - "%s_%s", - "%s%s", - "env/%s%s", - "gfx/env/%s%s" -}; - -void GLR_LoadSkys (void) -{ - int i; - char name[MAX_QPATH]; - char *boxname; - int p, s; - - if (*r_skyboxname.string) - boxname = r_skyboxname.string; //user forced - else - boxname = defaultskybox; - - if (!*boxname) - { //wipe the box - for (i=0 ; i<6 ; i++) - skyboxtex[i] = 0; - } - else - { - for(;;) - { - for (i=0 ; i<6 ; i++) - { - for (p = 0; p < sizeof(skyname_pattern)/sizeof(skyname_pattern[0]); p++) - { - for (s = 0; s < sizeof(skyname_suffix)/sizeof(skyname_suffix[0]); s++) - { - snprintf (name, sizeof(name), skyname_pattern[p], boxname, skyname_suffix[s][i]); - skyboxtex[i] = Mod_LoadHiResTexture(name, NULL, false, false, true); - if (skyboxtex[i]) - break; - } - if (skyboxtex[i]) - break; - } - if (!skyboxtex[i]) - break; - -#ifdef RGLQUAKE - //so the user can specify GL_NEAREST and still get nice skyboxes... yeah, a hack - if (qrenderer == QR_OPENGL) - { - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } -#endif - } - if (boxname != defaultskybox && i < 6 && *defaultskybox) - { - boxname = defaultskybox; - continue; - } - break; - } - } -} - - -qboolean GLR_CheckSky() -{ - return true; -} - -void GLR_Skyboxname_Callback(struct cvar_s *var, char *oldvalue) -{ - GLR_LoadSkys(); -} - -void GLR_SetSky(char *name, float rotate, vec3_t axis) //called from the client code, once per level -{ - Q_strncpyz(defaultskybox, name, sizeof(defaultskybox)); - if (!*r_skyboxname.string) //don't override a user's settings - GLR_Skyboxname_Callback(&r_skyboxname, ""); - - skyrotate = rotate; - VectorCopy(axis, skyaxis); -} - static vec3_t skyclip[6] = { {1,1,0}, {1,-1,0}, @@ -892,6 +336,12 @@ static void R_CalcSkyChainBounds (msurface_t *s) c_sky = 0; + for (i=0 ; i<6 ; i++) + { + skymins[0][i] = skymins[1][i] = 9999; + skymaxs[0][i] = skymaxs[1][i] = -9999; + } + // calculate vertex values for sky box for (fa=s ; fa ; fa=fa->texturechain) @@ -1006,8 +456,8 @@ static void d3d_skyspherecalc(int skytype) } #endif -#ifdef RGLQUAKE -static float skysphere_vertex3f[skysphere_numverts * 3]; +#ifdef GLQUAKE +static vecV_t skysphere_vertex3f[skysphere_numverts]; static mesh_t skymesh; @@ -1015,7 +465,8 @@ static void gl_skyspherecalc(int skytype) { //yes, this is basically stolen from DarkPlaces int i, j; index_t *e; - float a, b, x, ax, ay, v[3], length, *vertex3f, *texcoord2f; + float a, b, x, ax, ay, v[3], length, *texcoord2f; + vecV_t* vertex; float dx, dy, dz; float texscale; @@ -1043,7 +494,7 @@ static void gl_skyspherecalc(int skytype) dx = 16; dy = 16; dz = 16 / 3; - vertex3f = skysphere_vertex3f; + vertex = skysphere_vertex3f; texcoord2f = skysphere_texcoord2f; for (j = 0;j <= skygridy;j++) { @@ -1060,9 +511,10 @@ static void gl_skyspherecalc(int skytype) length = texscale / sqrt(v[0]*v[0]+v[1]*v[1]+(v[2]*v[2]*9)); *texcoord2f++ = v[0] * length; *texcoord2f++ = v[1] * length; - *vertex3f++ = v[0]; - *vertex3f++ = v[1]; - *vertex3f++ = v[2]; + (*vertex)[0] = v[0]; + (*vertex)[1] = v[1]; + (*vertex)[2] = v[2]; + vertex++; } } e = skysphere_element3i; @@ -1111,89 +563,6 @@ static void GL_SkyForceDepth(msurface_t *fa) } } -static void GL_DrawProgram_SkyChain(msurface_t *fa) -{ - vbo_t *v; - mesh_t *m; - - - v = &fa->texinfo->texture->vbo; - qglUseProgramObjectARB(skyprogram); - qglUniform1fARB(skyprogram_time, r_refdef.time); - qglUniform3fvARB(skyprogram_eyepos, 1, r_origin); - - - qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, v->vboe); - qglBindBufferARB(GL_ARRAY_BUFFER_ARB, v->vbocoord); - qglVertexPointer(3, GL_FLOAT, 0, v->coord); - qglEnableClientState(GL_VERTEX_ARRAY); - -#ifndef MINIMAL - if (fa->texinfo->texture->shader) - { - GL_MBind(mtexid0, fa->texinfo->texture->shader->passes[0].anim_frames[0]); - qglEnable(GL_TEXTURE_2D); - GL_MBind(mtexid1, fa->texinfo->texture->shader->passes[1].anim_frames[0]); - qglEnable(GL_TEXTURE_2D); - } - else - { -#endif - GL_MBind(mtexid0, fa->texinfo->texture->tn.base); - qglEnable(GL_TEXTURE_2D); - GL_MBind(mtexid1, fa->texinfo->texture->tn.fullbright); - qglEnable(GL_TEXTURE_2D); -#ifndef MINIMAL -} -#endif - - for (; fa; fa = fa->texturechain) - { - m = fa->mesh; - qglDrawRangeElements(GL_TRIANGLES, m->vbofirstvert, m->vbofirstvert+m->numvertexes, m->numindexes, GL_INDEX_TYPE, v->indicies+m->vbofirstelement); - } - - qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); - qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - qglUseProgramObjectARB(0); - qglDisable(GL_TEXTURE_2D); - GL_SelectTexture(mtexid0); -} - -static void GL_DrawProgram_WaterChain(msurface_t *fa) -{ - vbo_t *v; - mesh_t *m; - - v = &fa->texinfo->texture->vbo; - qglUseProgramObjectARB(waterprogram); - qglUniform1fARB(waterprogram_time, cl.time); - - - qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, v->vboe); - qglBindBufferARB(GL_ARRAY_BUFFER_ARB, v->vbocoord); - qglVertexPointer(3, GL_FLOAT, 0, v->coord); - qglEnableClientState(GL_VERTEX_ARRAY); - - GL_MBind(mtexid0, fa->texinfo->texture->tn.base); - qglEnable(GL_TEXTURE_2D); - - qglBindBufferARB(GL_ARRAY_BUFFER_ARB, v->vbotexcoord); - qglTexCoordPointer(2, GL_FLOAT, 0, v->texcoord); - qglEnableClientState(GL_TEXTURE_COORD_ARRAY); - - for (; fa; fa = fa->texturechain) - { - m = fa->mesh; - qglDrawRangeElements(GL_TRIANGLES, m->vbofirstvert, m->vbofirstvert+m->numvertexes, m->numindexes, GL_INDEX_TYPE, v->indicies+m->vbofirstelement); - } - - qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); - qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - qglUseProgramObjectARB(0); - GL_SelectTexture(mtexid0); -} - static void GL_DrawSkySphere (msurface_t *fa) { extern cvar_t gl_maxdist; @@ -1211,7 +580,6 @@ static void GL_DrawSkySphere (msurface_t *fa) //draw in bulk? this is eeevil //FIXME: We should use the skybox clipping code and split the sphere into 6 sides. -#ifdef Q3SHADERS if (fa->texinfo->texture->shader) { //the shader route. meshbuffer_t mb; @@ -1227,17 +595,16 @@ static void GL_DrawSkySphere (msurface_t *fa) R_RenderMeshBuffer(&mb, false); } else -#endif { //the boring route. gl_skyspherecalc(1); qglMatrixMode(GL_TEXTURE); qglPushMatrix(); qglTranslatef(time*8/128, time*8/128, 0); - GL_DrawAliasMesh(&skymesh, fa->texinfo->texture->tn.base); + GL_DrawAliasMesh(&skymesh, fa->texinfo->texture->shader->defaulttextures.base); qglColor4f(1,1,1,0.5); qglEnable(GL_BLEND); qglTranslatef(time*8/128, time*8/128, 0); - GL_DrawAliasMesh(&skymesh, fa->texinfo->texture->tn.fullbright); + GL_DrawAliasMesh(&skymesh, fa->texinfo->texture->shader->defaulttextures.fullbright); qglDisable(GL_BLEND); qglPopMatrix(); qglMatrixMode(GL_MODELVIEW); @@ -1246,210 +613,9 @@ static void GL_DrawSkySphere (msurface_t *fa) } #endif -#ifdef D3DQUAKE -static void D3D7_DrawSkySphere (msurface_t *fa) -{ - extern cvar_t gl_maxdist; - float time = cl.gametime+realtime-cl.gametimemark; - float skydist = 99999;//gl_maxdist.value; - if (skydist<1) - skydist=gl_skyboxdist.value; - skydist/=16; - //scale sky sphere and place around view origin. -// qglPushMatrix(); -// qglTranslatef(r_refdef.vieworg[0], r_refdef.vieworg[1], r_refdef.vieworg[2]); -// qglScalef(skydist, skydist, skydist); - -//draw in bulk? this is eeevil -//FIXME: We should use the skybox clipping code and split the sphere into 6 sides. -/*#ifdef Q3SHADERS - if (fa->texinfo->texture->shader) - { //the shader route. - meshbuffer_t mb; - d3d_skyspherecalc(2); - mb.sortkey = 0; - mb.infokey = -1; - mb.dlightbits = 0; - mb.entity = &r_worldentity; - mb.shader = fa->texinfo->texture->shader; - mb.fog = NULL; - mb.mesh = &skymesh; - R_PushMesh(mb.mesh, mb.shader->features); - R_RenderMeshBuffer(&mb, false); - } - else -#endif*/ - { //the boring route. - d3d_skyspherecalc(1); -// qglMatrixMode(GL_TEXTURE); -// qglPushMatrix(); -// qglTranslatef(time*8/128, time*8/128, 0); - - pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, FALSE ); - - pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); -// pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_CURRENT); - pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - - pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); -// pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG2, D3DTA_CURRENT); - pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - - pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA); - pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA); - - d3d_animateskysphere(time*8/128); - pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, (LPDIRECTDRAWSURFACE7)solidskytexture); - pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_TEX1, skysphere_d3dvertex, skysphere_numverts, skysphere_element3i, skysphere_numtriangles * 3, 0); - - pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHABLENDENABLE, TRUE); -// pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHATESTENABLE, TRUE); - - pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLORARG2, D3DTA_CURRENT); - pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_COLOROP, D3DTOP_MODULATE); - - pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); -// pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAARG2, D3DTA_CURRENT); - pD3DDev->lpVtbl->SetTextureStageState(pD3DDev, 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - -// qglTranslatef(time*8/128, time*8/128, 0); - d3d_animateskysphere(time*16/128); - pD3DDev->lpVtbl->SetTexture(pD3DDev, 0, (LPDIRECTDRAWSURFACE7)alphaskytexture); - pD3DDev->lpVtbl->DrawIndexedPrimitive(pD3DDev, D3DPT_TRIANGLELIST, D3DFVF_XYZ|D3DFVF_TEX1, skysphere_d3dvertex, skysphere_numverts, skysphere_element3i, skysphere_numtriangles * 3, 0); - - pD3DDev->lpVtbl->SetRenderState(pD3DDev, D3DRENDERSTATE_ALPHABLENDENABLE, FALSE); -// qglDisable(GL_BLEND); -// qglPopMatrix(); -// qglMatrixMode(GL_MODELVIEW); - } -// qglPopMatrix(); - -/* - if (!cls.allow_skyboxes) //allow a little extra fps. - {//Draw the texture chain to only the depth buffer. - if (qglColorMask) - qglColorMask(0,0,0,0); - for (; fa; fa = fa->texturechain) - { - GL_DrawAliasMesh(fa->mesh, 0); - } - if (qglColorMask) - qglColorMask(1,1,1,1); - } - */ -} -static void D3D9_DrawSkySphere (msurface_t *fa) -{ - extern cvar_t gl_maxdist; - float time = cl.gametime+realtime-cl.gametimemark; - - float skydist = 99999;//gl_maxdist.value; - if (skydist<1) - skydist=gl_skyboxdist.value; - skydist/=16; - - //scale sky sphere and place around view origin. -// qglPushMatrix(); -// qglTranslatef(r_refdef.vieworg[0], r_refdef.vieworg[1], r_refdef.vieworg[2]); -// qglScalef(skydist, skydist, skydist); - -//draw in bulk? this is eeevil -//FIXME: We should use the skybox clipping code and split the sphere into 6 sides. -/*#ifdef Q3SHADERS - if (fa->texinfo->texture->shader) - { //the shader route. - meshbuffer_t mb; - d3d_skyspherecalc(2); - mb.sortkey = 0; - mb.infokey = -1; - mb.dlightbits = 0; - mb.entity = &r_worldentity; - mb.shader = fa->texinfo->texture->shader; - mb.fog = NULL; - mb.mesh = &skymesh; - R_PushMesh(mb.mesh, mb.shader->features); - R_RenderMeshBuffer(&mb, false); - } - else -#endif*/ - { //the boring route. - d3d_skyspherecalc(1); -// qglMatrixMode(GL_TEXTURE); -// qglPushMatrix(); -// qglTranslatef(time*8/128, time*8/128, 0); - - d3d_animateskysphere(time*8/128); - D3D9_DrawSkyMesh(0, solidskytexture, skysphere_d3dvertex, skysphere_numverts, skysphere_element3i, skysphere_numtriangles); - d3d_animateskysphere(time*16/128); - D3D9_DrawSkyMesh(1, alphaskytexture, skysphere_d3dvertex, skysphere_numverts, skysphere_element3i, skysphere_numtriangles); - -// qglDisable(GL_BLEND); -// qglPopMatrix(); -// qglMatrixMode(GL_MODELVIEW); - } -// qglPopMatrix(); - -/* - if (!cls.allow_skyboxes) //allow a little extra fps. - {//Draw the texture chain to only the depth buffer. - if (qglColorMask) - qglColorMask(0,0,0,0); - for (; fa; fa = fa->texturechain) - { - GL_DrawAliasMesh(fa->mesh, 0); - } - if (qglColorMask) - qglColorMask(1,1,1,1); - } - */ -} -#endif - -/* -============== -R_ClearSkyBox -============== -*/ -void R_ClearSkyBox (void) -{ - int i; - - if (!cl.worldmodel) //allow skyboxes on non quake1 maps. (expect them even) - { - usingskybox = false; - return; - } - - for (i=0 ; i<6 ; i++) - { - skymins[0][i] = skymins[1][i] = 9999; - skymaxs[0][i] = skymaxs[1][i] = -9999; - } - - if (!skyboxtex[0] || !skyboxtex[1] || !skyboxtex[2] || !skyboxtex[3] || !skyboxtex[4] || !skyboxtex[5]) - { - usingskybox = false; - return; - } - - usingskybox = true; -} - -void R_ForceSkyBox (void) -{ - int i; - - for (i=0 ; i<6 ; i++) - { - skymins[0][i] = skymins[1][i] = -1; - skymaxs[0][i] = skymaxs[1][i] = 1; - } -} - -#ifdef RGLQUAKE +#ifdef GLQUAKE static void GL_MakeSkyVec (float s, float t, int axis) { vec3_t v, b; @@ -1459,9 +625,9 @@ static void GL_MakeSkyVec (float s, float t, int axis) if (!skydist) { - if (r_shadows.value || !gl_maxdist.value) - skydist = 1000000; //inifite distance - else +// if (r_shadows.value || !gl_maxdist.value) +// skydist = 1000000; //inifite distance +// else skydist = gl_maxdist.value * 0.577; } @@ -1533,9 +699,9 @@ static void MakeSkyGridVec2 (float s, float t, int axis, vec3_t v) if (!skydist) { - if (r_shadows.value || !gl_maxdist.value) - skydist = 1000000; //inifite distance - else +// if (r_shadows.value || !gl_maxdist.value) +// skydist = 1000000; //inifite distance +// else skydist = gl_maxdist.value * 0.577; } @@ -1602,7 +768,7 @@ static void GL_DrawSkyGrid (texture_t *tex) float time = cl.gametime+realtime-cl.gametimemark; GL_DisableMultitexture(); - GL_Bind (tex->tn.base); + GL_Bind (tex->shader->defaulttextures.base); speedscale = time*8; speedscale -= (int)speedscale & ~127; @@ -1615,7 +781,7 @@ static void GL_DrawSkyGrid (texture_t *tex) } qglEnable (GL_BLEND); - GL_Bind (tex->tn.fullbright); + GL_Bind (tex->shader->defaulttextures.fullbright); speedscale = time*16; speedscale -= (int)speedscale & ~127; @@ -1636,16 +802,13 @@ static void GL_DrawSkyGrid (texture_t *tex) R_DrawSkyBox ============== */ -int skytexorder[6] = {0,2,1,3,4,5}; -#ifdef RGLQUAKE -void GL_DrawSkyBox (msurface_t *s) +static int skytexorder[6] = {0,2,1,3,4,5}; +#ifdef GLQUAKE +static void GL_DrawSkyBox (texid_t *texnums, msurface_t *s) { int i; - if (!usingskybox) - return; - - if (skyrotate) + if (cl.skyrotate) { for (i=0 ; i<6 ; i++) { @@ -1671,8 +834,8 @@ void GL_DrawSkyBox (msurface_t *s) qglPushMatrix (); qglTranslatef (r_origin[0], r_origin[1], r_origin[2]); - if (skyrotate) - qglRotatef (cl.time * skyrotate, skyaxis[0], skyaxis[1], skyaxis[2]); + if (cl.skyrotate) + qglRotatef (cl.time * cl.skyrotate, cl.skyaxis[0], cl.skyaxis[1], cl.skyaxis[2]); for (i=0 ; i<6 ; i++) { @@ -1680,7 +843,7 @@ void GL_DrawSkyBox (msurface_t *s) || skymins[1][i] >= skymaxs[1][i]) continue; - GL_Bind (skyboxtex[skytexorder[i]]); + GL_Bind (texnums[skytexorder[i]]); qglBegin (GL_QUADS); GL_MakeSkyVec (skymins[0][i], skymins[1][i], i); @@ -1705,7 +868,7 @@ R_InitSky A sky texture is 256*128, with the right side being a masked overlay ============== */ -void R_InitSky (texture_t *mt) +texnums_t R_InitSky (texture_t *mt) { int i, j, p; qbyte *src; @@ -1714,9 +877,9 @@ void R_InitSky (texture_t *mt) int r, g, b; unsigned *rgba; char name[MAX_QPATH]; + texnums_t tn; - int solidskytexture; - int alphaskytexture; + memset(&tn, 0, sizeof(tn)); src = (qbyte *)mt + mt->offsets[0]; @@ -1742,18 +905,10 @@ void R_InitSky (texture_t *mt) Q_snprintfz(name, sizeof(name), "%s_solid", mt->name); Q_strlwr(name); - solidskytexture = Mod_LoadReplacementTexture(name, NULL, true, false, true); - if (!solidskytexture) - solidskytexture = R_LoadTexture32(name, 128, 128, trans, true, false); -/* - if (!solidskytexture) - solidskytexture = texture_extension_number++; + tn.base = R_LoadReplacementTexture(name, NULL, IF_NOALPHA); + if (!TEXVALID(tn.base)) + tn.base = R_LoadTexture32(name, 128, 128, trans, IF_NOALPHA|IF_NOGAMMA); - GL_Bind (solidskytexture ); - glTexImage2D (GL_TEXTURE_2D, 0, gl_solid_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -*/ alphamask = LittleLong(0x7fffffff); for (i=0 ; i<128 ; i++) for (j=0 ; j<128 ; j++) @@ -1767,19 +922,10 @@ void R_InitSky (texture_t *mt) Q_snprintfz(name, sizeof(name), "%s_trans", mt->name); Q_strlwr(name); - alphaskytexture = Mod_LoadReplacementTexture(name, NULL, true, true, true); - if (!alphaskytexture) - alphaskytexture = R_LoadTexture32(name, 128, 128, trans, true, true); -/* - if (!alphaskytexture) - alphaskytexture = texture_extension_number++; - GL_Bind(alphaskytexture); - glTexImage2D (GL_TEXTURE_2D, 0, gl_alpha_format, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, trans); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); -*/ + tn.fullbright = R_LoadReplacementTexture(name, NULL, 0); + if (!TEXVALID(tn.fullbright)) + tn.fullbright = R_LoadTexture32(name, 128, 128, trans, IF_NOGAMMA); - mt->tn.base = solidskytexture; - mt->tn.fullbright = alphaskytexture; + return tn; } #endif diff --git a/engine/gl/glmod_doom.c b/engine/gl/glmod_doom.c index 6aa5b003..1eb25207 100644 --- a/engine/gl/glmod_doom.c +++ b/engine/gl/glmod_doom.c @@ -1,6 +1,6 @@ #include "quakedef.h" #ifdef DOOMWADS -#ifdef RGLQUAKE +#ifdef GLQUAKE #include "glquake.h" #include "doommap.h" @@ -130,7 +130,7 @@ int Doom_LoadFlat(char *name) sprintf(texname, "flat-%-.8s", name); Q_strlwr(texname); - tex = Mod_LoadReplacementTexture(texname, "flats", true, false, true); + tex = R_LoadReplacementTexture(texname, "flats", true, false, true); if (tex) return tex; @@ -536,7 +536,7 @@ qboolean GLR_DoomWorld(void) //pick a point, follow along the walls making a triangle fan, until an angle of > 180, throw out fan, rebuild arrays. //at new point, start a new fan. Be prepared to not be able to generate one. -#ifdef RGLQUAKE +#ifdef GLQUAKE #define MAX_REGIONS 256 #define MAX_POLYVERTS (MAX_FLATTRIS*3) @@ -772,7 +772,7 @@ static void Triangulate_Sectors(dsector_t *sectorl, qboolean glbspinuse) sectorm = BZ_Malloc(sectorc * sizeof(*sectorm)); -#ifdef RGLQUAKE +#ifdef GLQUAKE if (glbspinuse) { for (i = 0; i < ssectorsc; i++) @@ -839,7 +839,7 @@ static void Triangulate_Sectors(dsector_t *sectorl, qboolean glbspinuse) for (i = 0; i < sectorc; i++) { -#ifdef RGLQUAKE +#ifdef GLQUAKE sectorm[i].ceilingtex = Doom_LoadFlat(sectorl[i].ceilingtexture); sectorm[i].floortex = Doom_LoadFlat(sectorl[i].floortexture); #endif @@ -1045,7 +1045,7 @@ static void CleanWalls(dsidedef_t *sidedefsl) sidedefsm = BZ_Malloc(sidedefsc * sizeof(*sidedefsm)); for (i = 0; i < sidedefsc; i++) { -#ifdef RGLQUAKE +#ifdef GLQUAKE strncpy(texname, sidedefsl[i].middletex, 8); texname[8] = '\0'; if (!strcmp(texname, "-")) diff --git a/engine/gl/glquake.h b/engine/gl/glquake.h index 729f9297..e553d937 100644 --- a/engine/gl/glquake.h +++ b/engine/gl/glquake.h @@ -42,7 +42,7 @@ void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs); qboolean BoundsIntersect (vec3_t mins1, vec3_t maxs1, vec3_t mins2, vec3_t maxs2); void ClearBounds (vec3_t mins, vec3_t maxs); -#ifdef RGLQUAKE +#ifdef GLQUAKE #ifdef __MACOSX__ //apple, you suck. #include @@ -54,23 +54,19 @@ void ClearBounds (vec3_t mins, vec3_t maxs); void GL_InitFogTexture(void); -void GL_BeginRendering (int *x, int *y, int *width, int *height); +void GL_BeginRendering (void); void GL_EndRendering (void); +void R_PolyBlend (void); void GLR_BrightenScreen (void); void GLR_NetGraph (void); -void GLR_DrawAlphaSurfaces (void); +void GLR_FrameTimeGraph (int frametime); void GL_FlushSkinCache(void); void GL_GAliasFlushSkinCache(void); void PPL_CreateShaderObjects(void); void PPL_BaseBModelTextures(entity_t *e); -#ifdef RUNTIMELIGHTING -void LightFace (int surfnum); -void LightLoadEntities(char *entstring); -#endif - // Function prototypes for the Texture Object Extension routines typedef GLboolean (APIENTRY *ARETEXRESFUNCPTR)(GLsizei, const GLuint *, const GLboolean *); @@ -99,6 +95,7 @@ typedef void (APIENTRYP FTEPFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei typedef void (APIENTRYP FTEPFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); typedef GLint (APIENTRYP FTEPFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); typedef void (APIENTRYP FTEPFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +typedef void (APIENTRYP FTEPFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, GLfloat *value); typedef void (APIENTRYP FTEPFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, GLfloat *value); typedef void (APIENTRYP FTEPFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); typedef void (APIENTRYP FTEPFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, GLfloat *value); @@ -117,7 +114,7 @@ extern FTEPFNGLGETCOMPRESSEDTEXIMAGEARBPROC qglGetCompressedTexImageARB; extern FTEPFNGLPNTRIANGLESIATIPROC qglPNTrianglesiATI; extern FTEPFNGLPNTRIANGLESFATIPROC qglPNTrianglesfATI; -int GL_AllocNewTexture(void); +qboolean GL_CheckExtension(char *extname); typedef struct { qboolean tex_env_combine; @@ -143,24 +140,26 @@ extern gl_config_t gl_config; extern float gldepthmin, gldepthmax; -void GL_Upload32 (char *name, unsigned *data, int width, int height, qboolean mipmap, qboolean alpha); //name was added for texture compression output -void GL_Upload32_BGRA (char *name, unsigned *data, int width, int height, qboolean mipmap, qboolean alpha); //name was added for texture compression output -void GL_Upload8 (char *name, qbyte *data, int width, int height, qboolean mipmap, qboolean alpha); -void GL_Upload24BGR_Flip (char *name, qbyte *data, int width, int height, qboolean mipmap, qboolean alpha); -void GL_Upload24BGR (char *name, qbyte *data, int width, int height, qboolean mipmap, qboolean alpha); +/* +void GL_Upload32 (char *name, unsigned *data, int width, int height, unsigned int flags); //name was added for texture compression output +void GL_Upload32_BGRA (char *name, unsigned *data, int width, int height, unsigned int flags); //name was added for texture compression output +void GL_Upload8 (char *name, qbyte *data, int width, int height, unsigned int flags, unsigned int alphatype); +void GL_Upload24BGR_Flip (char *name, qbyte *data, int width, int height, unsigned int flags); +void GL_Upload24BGR (char *name, qbyte *data, int width, int height, unsigned int flags); #ifdef GL_EXT_paletted_texture void GL_Upload8_EXT (qbyte *data, int width, int height, qboolean mipmap, qboolean alpha); #endif -int GL_LoadTexture (char *identifier, int width, int height, qbyte *data, qboolean mipmap, qboolean alpha); -int GL_LoadTexture8Bump (char *identifier, int width, int height, unsigned char *data, qboolean mipmap, float bumpscale); -int GL_LoadTexture8Pal24 (char *identifier, int width, int height, qbyte *data, qbyte *palette24, qboolean mipmap, qboolean alpha); -int GL_LoadTexture8Pal32 (char *identifier, int width, int height, qbyte *data, qbyte *palette32, qboolean mipmap, qboolean alpha); -int GL_LoadTexture32 (char *identifier, int width, int height, unsigned *data, qboolean mipmap, qboolean alpha); -int GL_LoadCompressed(char *name); -int GL_FindTexture (char *identifier); +*/ +texid_t GL_LoadTexture (char *identifier, int width, int height, qbyte *data, unsigned int flags, unsigned int transtype); +texid_t GL_LoadTexture8Bump (char *identifier, int width, int height, unsigned char *data, unsigned int flags, float bumpscale); +texid_t GL_LoadTexture8Pal24 (char *identifier, int width, int height, qbyte *data, qbyte *palette24, unsigned int flags); +texid_t GL_LoadTexture8Pal32 (char *identifier, int width, int height, qbyte *data, qbyte *palette32, unsigned int flags); +texid_t GL_LoadTexture32 (char *identifier, int width, int height, void *data, unsigned int flags); +texid_t GL_LoadCompressed(char *name); +texid_t GL_FindTexture (char *identifier); -int GL_LoadTextureFB (char *identifier, int width, int height, qbyte *data, qboolean mipmap, qboolean alpha); -void GL_Upload8Pal24 (qbyte *data, qbyte *pal, int width, int height, qboolean mipmap, qboolean alpha); +texid_t GL_LoadTextureFB (char *identifier, int width, int height, qbyte *data, unsigned int flags); +void GL_Upload8Pal24 (qbyte *data, qbyte *pal, int width, int height, unsigned int flags); typedef struct { @@ -169,44 +168,41 @@ typedef struct float r, g, b; } glvert_t; -extern glvert_t glv; - -extern int glx, gly, glwidth, glheight; +FTE_DEPRECATED extern glvert_t glv; #endif // r_local.h -- private refresh defs -#define ALIAS_BASE_SIZE_RATIO (1.0 / 11.0) +//#define ALIAS_BASE_SIZE_RATIO (1.0 / 11.0) // normalizing factor so player model works out to about // 1 pixel per triangle -#define MAX_LBM_HEIGHT 480 +//#define MAX_LBM_HEIGHT 480 -#define TILE_SIZE 128 // size of textures generated by R_GenTiledSurf +//#define TILE_SIZE 128 // size of textures generated by R_GenTiledSurf -#define SKYSHIFT 7 -#define SKYSIZE (1 << SKYSHIFT) -#define SKYMASK (SKYSIZE - 1) +//#define SKYSHIFT 7 +//#define SKYSIZE (1 << SKYSHIFT) +//#define SKYMASK (SKYSIZE - 1) #define BACKFACE_EPSILON 0.01 void R_TimeRefresh_f (void); -texture_t *SWR_TextureAnimation (texture_t *base); +FTE_DEPRECATED texture_t *SWR_TextureAnimation (texture_t *base); texture_t *R_TextureAnimation (texture_t *base); #include "particles.h" //==================================================== - extern entity_t r_worldentity; extern vec3_t modelorg, r_entorigin; extern entity_t *currententity; extern int r_visframecount; // ??? what difs? extern int r_framecount; extern mplane_t frustum[4]; -extern int c_brush_polys, c_alias_polys; +FTE_DEPRECATED extern int c_brush_polys, c_alias_polys; extern float r_wateralphaval; @@ -228,18 +224,10 @@ extern int r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2; extern texture_t *r_notexture_mip; extern int d_lightstylevalue[256]; // 8.8 fraction of base light value -extern qboolean envmap; -extern int particletexture; -extern int particlecqtexture; -extern int explosiontexture; -extern int balltexture; -extern int netgraphtexture; // netgraph texture - -extern int skytexturenum; // index in cl.loadmodel, not gl texture object +FTE_DEPRECATED extern qboolean envmap; +extern texid_t netgraphtexture; // netgraph texture extern int gl_lightmap_format; -extern int gl_solid_format; -extern int gl_alpha_format; extern int mirrortexturenum; // quake texturenum, not gltexturenum extern qboolean mirror; @@ -251,26 +239,22 @@ extern float r_view_matrix[16]; extern const char *gl_vendor; extern const char *gl_renderer; extern const char *gl_version; -extern const char *gl_extensions; #ifdef Q3SHADERS -void R_UnlockArrays (void); -void R_IBrokeTheArrays(void); -void R_ClearArrays (void); +FTE_DEPRECATED void R_UnlockArrays (void); +FTE_DEPRECATED void R_IBrokeTheArrays(void); +FTE_DEPRECATED void R_ClearArrays (void); #endif +FTE_DEPRECATED void PPL_RevertToKnownState(void); -int Mod_LoadReplacementTexture(char *name, char *subpath, qboolean mipmap, qboolean alpha, qboolean gammaadjust); -extern int image_width, image_height; -int Mod_LoadHiResTexture(char *name, char *subpath, qboolean mipmap, qboolean alpha, qboolean gammaadjust); -int Mod_LoadBumpmapTexture(char *name, char *subpath); - -#ifdef RGLQUAKE +#ifdef GLQUAKE void R_TranslatePlayerSkin (int playernum); -void GL_Bind (int texnum); -void GL_MBind( GLenum target, int texnum ); -void GL_TexEnv( GLenum mode ); -void GL_BindType (int type, int texnum); +void GL_Bind (texid_t texnum); +void GL_MBind(int tmunum, texid_t texnum); +void GL_CullFace(unsigned int sflags); +void GL_TexEnv(GLenum mode); +void GL_BindType (int type, texid_t texnum); void GL_FlushBackEnd (void); // Multitexture @@ -299,7 +283,7 @@ extern qboolean gl_mtexable; void GL_DisableMultitexture(void); void GL_EnableMultitexture(void); -void GL_SelectTexture (GLenum target); +void GL_SelectTexture (int tmunum); void GL_SetShaderState2D(qboolean is2d); void R_DrawRailCore(entity_t *e); @@ -311,31 +295,28 @@ void R_DrawBeam( entity_t *e ); // // vid_gl*.c // -#ifdef RGLQUAKE +#ifdef GLQUAKE void GL_DoSwap (void); #endif // // gl_backend.c // -#ifdef RGLQUAKE -void R_BackendInit(void); -void R_IBrokeTheArrays(void); +#ifdef GLQUAKE +void FTE_DEPRECATED R_BackendInit(void); +void FTE_DEPRECATED R_IBrokeTheArrays(void); #endif +void R_DrawSkyChain (msurface_t *s); +texnums_t R_InitSky (texture_t *mt); + // // gl_warp.c // -#ifdef RGLQUAKE -void GL_DrawSkyBox (msurface_t *s); -void GL_SubdivideSurface (msurface_t *fa, float dividesize); -void GL_EmitBothSkyLayers (msurface_t *fa); -void EmitWaterPolyChain (msurface_t *fa, float basealpha); //chains through the texture chain -void EmitWaterPolys (msurface_t *fa, float basealpha); //don't use if you can avoid it -void GL_DrawSkyChain (msurface_t *s); -void R_InitSky (texture_t *mt); +#ifdef GLQUAKE +void FTE_DEPRECATED GL_SubdivideSurface (msurface_t *fa, float dividesize); +void FTE_DEPRECATED GL_EmitBothSkyLayers (msurface_t *fa); -void R_ClearSkyBox (void); void R_DrawSkyBox (msurface_t *s); void R_ForceSkyBox (void); void R_AddSkySurface (msurface_t *fa); @@ -348,15 +329,15 @@ void D3D9_DrawSkyChain (msurface_t *s); // // gl_draw.c // -#ifdef RGLQUAKE -int GL_LoadPicTexture (qpic_t *pic); +#ifdef GLQUAKE +texid_t GL_LoadPicTexture (qpic_t *pic); void GL_Set2D (void); #endif // // gl_rmain.c // -#ifdef RGLQUAKE +#ifdef GLQUAKE qboolean R_CullBox (vec3_t mins, vec3_t maxs); qboolean R_CullSphere (vec3_t origin, float radius); qboolean R_CullEntityBox(entity_t *e, vec3_t modmins, vec3_t modmaxs); @@ -369,16 +350,13 @@ void GL_SetupSceneProcessingTextures (void); // // gl_alias.c // -#ifdef RGLQUAKE -void R_DrawGAliasModel (entity_t *e); +#ifdef GLQUAKE +void R_DrawGAliasModel (entity_t *e, unsigned int rmode); void R_DrawGAliasShadowVolume(entity_t *e, vec3_t lightpos, float radius); -void R_DrawGAliasModelLighting (entity_t *e, vec3_t lightpos, vec3_t colours, float radius); -void R_LightArrays(byte_vec4_t *colours, int vertcount, vec3_t *normals); +void R_LightArrays(vecV_t *coords, vec4_t *colours, int vertcount, vec3_t *normals); //misc model formats -void R_DrawAlias3Model (entity_t *ent); void R_DrawHLModel(entity_t *curent); -void R_DrawGroupModel (entity_t *ent); //typedef float m3by3_t[3][3]; //int GetTag(model_t *mod, char *tagname, int frame, float **org, m3by3_t **ang); @@ -387,7 +365,7 @@ void R_DrawGroupModel (entity_t *ent); // // gl_rlight.c // -#ifdef RGLQUAKE +#ifdef GLQUAKE void GLR_MarkLights (dlight_t *light, int bit, mnode_t *node); void GLR_MarkQ2Lights (dlight_t *light, int bit, mnode_t *node); void GLR_RenderDlights (void); @@ -396,20 +374,16 @@ int GLR_LightPoint (vec3_t p); void GLQ3_LightGrid(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir); #endif -#if defined(RGLQUAKE) || defined(D3DQUAKE) -void GLR_AnimateLight (void); -#endif - // // gl_heightmap.c // -#ifdef RGLQUAKE +#ifdef GLQUAKE void GL_DrawHeightmapModel (entity_t *e); qboolean GL_LoadHeightmapModel (model_t *mod, void *buffer); #endif //gl_bloom.c -#ifdef RGLQUAKE +#ifdef GLQUAKE void R_BloomRegister(void); void R_BloomBlend(void); void R_InitBloomTextures(void); @@ -418,10 +392,12 @@ void R_InitBloomTextures(void); // // gl_rsurf.c // -#ifdef RGLQUAKE -void R_DrawBrushModel (entity_t *e); +#ifdef GLQUAKE +FTE_DEPRECATED void R_DrawBrushModel (entity_t *e); void R_DrawWorld (void); void GL_BuildLightmaps (void); +void R_RenderDynamicLightmaps (msurface_t *fa, int shift); +int GLR_LightmapShift (model_t *model); void GL_LoadShaders(void); @@ -448,9 +424,9 @@ typedef struct { #endif //gl_ppl.c -void PPL_DrawWorld (void); -qboolean PPL_ShouldDraw(void); -void RotateLightVector(const vec3_t *angles, const vec3_t origin, const vec3_t lightpoint, vec3_t result); +FTE_DEPRECATED void PPL_DrawWorld (qbyte *viewvis); +FTE_DEPRECATED qboolean PPL_ShouldDraw(void); +FTE_DEPRECATED void RotateLightVector(const vec3_t *angles, const vec3_t origin, const vec3_t lightpoint, vec3_t result); // // gl_refrag.c @@ -464,7 +440,7 @@ void R_StoreEfrags (efrag_t **ppefrag); void R_NetGraph (void); -#if defined(RGLQUAKE) +#if defined(GLQUAKE) extern void (APIENTRY *qglAccum) (GLenum op, GLfloat value); extern void (APIENTRY *qglAlphaFunc) (GLenum func, GLclampf ref); @@ -825,7 +801,16 @@ extern void (APIENTRY *qglBufferSubDataARB)(GLenum target, GLint offset, GLsizei extern void *(APIENTRY *qglMapBufferARB)(GLenum target, GLenum access); extern GLboolean (APIENTRY *qglUnmapBufferARB)(GLenum target); +extern const GLubyte * (APIENTRY * qglGetStringi) (GLenum name, GLuint index); +extern void (APIENTRY *qglGenFramebuffersEXT)(GLsizei n, GLuint* ids); +extern void (APIENTRY *qglDeleteFramebuffersEXT)(GLsizei n, const GLuint* ids); +extern void (APIENTRY *qglBindFramebufferEXT)(GLenum target, GLuint id); +extern void (APIENTRY *qglGenRenderbuffersEXT)(GLsizei n, GLuint* ids); +extern void (APIENTRY *qglDeleteRenderbuffersEXT)(GLsizei n, const GLuint* ids); +extern void (APIENTRY *qglBindRenderbufferEXT)(GLenum target, GLuint id); +extern void (APIENTRY *qglRenderbufferStorageEXT)(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height); +extern void (APIENTRY *qglFramebufferTexture2DEXT)(GLenum target, GLenum attachmentPoint, GLenum textureTarget, GLuint textureId, GLint level); /* extern qboolean gl_arb_fragment_program; @@ -847,6 +832,7 @@ extern FTEPFNGLATTACHOBJECTARBPROC qglAttachObjectARB; extern FTEPFNGLGETINFOLOGARBPROC qglGetInfoLogARB; extern FTEPFNGLLINKPROGRAMARBPROC qglLinkProgramARB; extern FTEPFNGLGETUNIFORMLOCATIONARBPROC qglGetUniformLocationARB; +extern FTEPFNGLUNIFORMMATRIX4FVARBPROC qglUniformMatrix4fvARB; extern FTEPFNGLUNIFORM4FARBPROC qglUniform4fARB; extern FTEPFNGLUNIFORM4FVARBPROC qglUniform4fvARB; extern FTEPFNGLUNIFORM3FARBPROC qglUniform3fARB; diff --git a/engine/gl/glsupp.h b/engine/gl/glsupp.h index 4dfab5ac..aebf96cd 100644 --- a/engine/gl/glsupp.h +++ b/engine/gl/glsupp.h @@ -614,4 +614,71 @@ typedef void (APIENTRY * PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); typedef void (APIENTRY * PFNGLUNLOCKARRAYSEXTPROC) (void); #endif + + + +#ifndef GL_EXT_framebuffer_object +#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 +#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 +#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 +#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 +#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 +#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 +#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 +#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD +#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF +#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 +#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 +#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 +#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 +#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 +#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 +#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 +#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 +#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 +#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 +#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA +#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB +#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC +#define GL_COLOR_ATTACHMENT13_EXT 0x8CED +#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE +#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF +#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 +#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 +#define GL_FRAMEBUFFER_EXT 0x8D40 +#define GL_RENDERBUFFER_EXT 0x8D41 +#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 +#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 +#define GL_STENCIL_INDEX1_EXT 0x8D46 +#define GL_STENCIL_INDEX4_EXT 0x8D47 +#define GL_STENCIL_INDEX8_EXT 0x8D48 +#define GL_STENCIL_INDEX16_EXT 0x8D49 +#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 +#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 +#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 +#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 +#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 +#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 +#endif + + + +#ifndef GL_VERSION_3_0 +#define GL_MAJOR_VERSION 0x821B +#define GL_MINOR_VERSION 0x821C +#define GL_NUM_EXTENSIONS 0x821D +#endif + + + #endif diff --git a/engine/gl/gltod3d/gl_fakegl.cpp b/engine/gl/gltod3d/gl_fakegl.cpp index 3d367c17..243c3d8a 100644 --- a/engine/gl/gltod3d/gl_fakegl.cpp +++ b/engine/gl/gltod3d/gl_fakegl.cpp @@ -4114,8 +4114,8 @@ rendererinfo_t d3drendererinfo = { GLR_RenderView, - GLR_CheckSky, - GLR_SetSky, + NULL, + NULL, GLR_NewMap, GLR_PreNewMap, diff --git a/engine/gl/ltface.c b/engine/gl/ltface.c index b13ef509..09d184a2 100644 --- a/engine/gl/ltface.c +++ b/engine/gl/ltface.c @@ -1,7 +1,7 @@ #include "quakedef.h" #ifdef RUNTIMELIGHTING -#if defined(RGLQUAKE) || defined(D3DQUAKE) +#if defined(GLQUAKE) || defined(D3DQUAKE) extern model_t *lightmodel; @@ -677,7 +677,7 @@ static void SingleLightFace (mentity_t *light, llightinfo_t *l) lightsamp[c][1] += add*light->colour[1]; lightsamp[c][2] += add*light->colour[2]; - norms[c][0] += add * incoming[0]; //Quake doesn't make sence some times. + norms[c][0] -= add * incoming[0]; //Quake doesn't make sence some times. norms[c][1] -= add * incoming[1]; norms[c][2] -= add * incoming[2]; @@ -761,7 +761,7 @@ void LightFace (int surfnum) byte *rgbout; byte *dulout; vec3_t *light, *norm; - vec3_t wnorm, temp; + vec3_t wnorm, temp, svector, tvector; int w, h; f = dfaces + surfnum; @@ -871,7 +871,14 @@ void LightFace (int surfnum) #else rgbout = f->samples; if (lightmodel->deluxdata) + { dulout = f->samples - lightmodel->lightdata + lightmodel->deluxdata; + + VectorCopy(bsptexinfo(f->texinfo).vecs[0], svector); + VectorNegate(bsptexinfo(f->texinfo).vecs[1], tvector); + VectorNormalize(svector); + VectorNormalize(tvector); + } else dulout = NULL; #endif @@ -931,13 +938,13 @@ void LightFace (int surfnum) if (dulout) { - temp[0] = DotProduct(wnorm, bsptexinfo(f->texinfo).vecs[0]); - temp[1] = DotProduct(wnorm, bsptexinfo(f->texinfo).vecs[1]); + temp[0] = DotProduct(wnorm, svector); + temp[1] = DotProduct(wnorm, tvector); temp[2] = DotProduct(wnorm, l.facenormal); VectorNormalize(temp); - *dulout++ = (temp[0]+1)/2 * 255; - *dulout++ = (temp[1]+1)/2 * 255; - *dulout++ = (temp[2]+1)/2 * 255; + *dulout++ = -(temp[0]+1)*128 + 128; + *dulout++ = (temp[1]+1)*128 + 128; + *dulout++ = (temp[2]+1)*128 + 128; } } } diff --git a/engine/gl/model_hl.h b/engine/gl/model_hl.h index 32e56b33..1535776c 100644 --- a/engine/gl/model_hl.h +++ b/engine/gl/model_hl.h @@ -56,7 +56,7 @@ typedef struct int flags; int w; /* width */ int h; /* height */ - int i; /* index */ + int offset; /* index */ } hlmdl_tex_t; /* @@ -213,6 +213,7 @@ typedef struct hlmdl_tex_t *textures; hlmdl_bone_t *bones; hlmdl_bonecontroller_t *bonectls; + texid_t *texnums; } hlmodel_t; typedef struct //this is stored as the cache. an hlmodel_t is generated when drawing @@ -222,6 +223,7 @@ typedef struct //this is stored as the cache. an hlmodel_t is generated when dra int textures; int bones; int bonectls; + int texnums; } hlmodelcache_t; /* HL mathlib prototypes: */ @@ -231,7 +233,7 @@ void QuaternionGLMatrix(float x, float y, float z, float w, vec4_t *GLM); /* HL drawing */ qboolean Mod_LoadHLModel (model_t *mod, void *buffer); -void R_Draw_HL_AliasModel(hlmodel_t *model); +void R_DrawHLModel(entity_t *curent); /* physics stuff */ void *Mod_GetHalfLifeModelData(model_t *mod); diff --git a/engine/gl/shader.h b/engine/gl/shader.h index a476ba92..a8f4d316 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -1,4 +1,5 @@ -#ifdef Q3SHADERS +typedef void (shader_gen_t)(char *name, shader_t*, const void *args); + #define SHADER_PASS_MAX 8 #define SHADER_MAX_TC_MODS 8 #define SHADER_DEFORM_MAX 8 @@ -22,6 +23,7 @@ typedef enum { SHADER_SORT_OPAQUE, SHADER_SORT_BANNER, SHADER_SORT_UNDERWATER, + SHADER_SORT_DECAL, SHADER_SORT_ADDITIVE, SHADER_SORT_NEAREST } shadersort_t; @@ -103,40 +105,71 @@ typedef struct shaderfunc_t func; } deformv_t; +enum +{ + /*source and dest factors match each other for easier parsing + but they're not meant to ever be set on the shader itself + NONE is also invalid, and is used to signify disabled, it should never be set on only one + */ + SBITS_SRCBLEND_NONE = 0x00000000, + SBITS_SRCBLEND_ZERO = 0x00000001, + SBITS_SRCBLEND_ONE = 0x00000002, + SBITS_SRCBLEND_DST_COLOR = 0x00000003, + SBITS_SRCBLEND_ONE_MINUS_DST_COLOR = 0x00000004, + SBITS_SRCBLEND_SRC_ALPHA = 0x00000005, + SBITS_SRCBLEND_ONE_MINUS_SRC_ALPHA = 0x00000006, + SBITS_SRCBLEND_DST_ALPHA = 0x00000007, + SBITS_SRCBLEND_ONE_MINUS_DST_ALPHA = 0x00000008, + SBITS_SRCBLEND_SRC_COLOR_INVALID = 0x00000009, + SBITS_SRCBLEND_ONE_MINUS_SRC_COLOR_INVALID = 0x0000000a, + SBITS_SRCBLEND_ALPHA_SATURATE = 0x0000000b, +#define SBITS_SRCBLEND_BITS 0x0000000f + + /*must match src factors, just shifted 4*/ + SBITS_DSTBLEND_NONE = 0x00000000, + SBITS_DSTBLEND_ZERO = 0x00000010, + SBITS_DSTBLEND_ONE = 0x00000020, + SBITS_DSTBLEND_DST_COLOR_INVALID = 0x00000030, + SBITS_DSTBLEND_ONE_MINUS_DST_COLOR_INVALID = 0x00000040, + SBITS_DSTBLEND_SRC_ALPHA = 0x00000050, + SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA = 0x00000060, + SBITS_DSTBLEND_DST_ALPHA = 0x00000070, + SBITS_DSTBLEND_ONE_MINUS_DST_ALPHA = 0x00000080, + SBITS_DSTBLEND_SRC_COLOR = 0x00000090, + SBITS_DSTBLEND_ONE_MINUS_SRC_COLOR = 0x000000a0, + SBITS_DSTBLEND_ALPHA_SATURATE_INVALID = 0x000000b0, +#define SBITS_DSTBLEND_BITS 0x000000f0 + +#define SBITS_BLEND_BITS (SBITS_SRCBLEND_BITS|SBITS_DSTBLEND_BITS) + + SBITS_ATEST_NONE = 0x00000000, + SBITS_ATEST_GT0 = 0x00000100, + SBITS_ATEST_LT128 = 0x00000200, + SBITS_ATEST_GE128 = 0x00000300, +#define SBITS_ATEST_BITS 0x00000f00 + + SBITS_MISC_DEPTHWRITE = 0x00001000, + SBITS_MISC_NODEPTHTEST = 0x00002000, + + SBITS_MISC_DEPTHEQUALONLY = 0x00004000, + SBITS_MISC_DEPTHCLOSERONLY = 0x00008000, + +// SBITS_MISC_POLYFILL_LINES = 0x00008000, +#define SBITS_MISC_BITS 0x0000f000 +}; + typedef struct shaderpass_s { int numMergedPasses; - shaderfunc_t rgbgen_func; - shaderfunc_t alphagen_func; - +#ifndef NOMEDIA struct cin_s *cin; - +#endif - unsigned int blendsrc, blenddst; // glBlendFunc args - unsigned int blendmode, envmode; + unsigned int shaderbits; - unsigned int combinesrc0, combinesrc1, combinemode; + unsigned int blendmode; - unsigned int depthfunc; // glDepthFunc arg - enum { - SHADER_ALPHA_GT0, - SHADER_ALPHA_LT128, - SHADER_ALPHA_GE128 - } alphafunc; - - enum { - TC_GEN_BASE, //basic specified texture coords - TC_GEN_LIGHTMAP, //use loaded lightmap coords - TC_GEN_ENVIRONMENT, - TC_GEN_DOTPRODUCT, - TC_GEN_VECTOR, - - //these are really for use only in glsl stuff. - TC_GEN_NORMAL, - TC_GEN_SVECTOR, - TC_GEN_TVECTOR, - } tcgen; enum { RGB_GEN_WAVE, RGB_GEN_ENTITY, @@ -152,6 +185,8 @@ typedef struct shaderpass_s { RGB_GEN_TOPCOLOR, RGB_GEN_BOTTOMCOLOR } rgbgen; + shaderfunc_t rgbgen_func; + enum { ALPHA_GEN_ENTITY, ALPHA_GEN_WAVE, @@ -161,27 +196,55 @@ typedef struct shaderpass_s { ALPHA_GEN_VERTEX, ALPHA_GEN_CONST } alphagen; + shaderfunc_t alphagen_func; + enum { + TC_GEN_BASE, //basic specified texture coords + TC_GEN_LIGHTMAP, //use loaded lightmap coords + TC_GEN_ENVIRONMENT, + TC_GEN_DOTPRODUCT, + TC_GEN_VECTOR, + + //these are really for use only in glsl stuff. + TC_GEN_NORMAL, + TC_GEN_SVECTOR, + TC_GEN_TVECTOR, + } tcgen; int numtcmods; tcmod_t tcmods[SHADER_MAX_TC_MODS]; - void (*flush) (meshbuffer_t *mb, struct shaderpass_s *pass); - int anim_numframes; - int anim_frames[SHADER_MAX_ANIMFRAMES]; + texid_t anim_frames[SHADER_MAX_ANIMFRAMES]; float anim_fps; - unsigned int texturetype; +// unsigned int texturetype; enum { - SHADER_PASS_BLEND = 1 << 0, - SHADER_PASS_ALPHAFUNC = 1 << 1, - SHADER_PASS_DEPTHWRITE = 1 << 2, + T_GEN_SINGLEMAP, //single texture specified in the shader + T_GEN_ANIMMAP, //animating sequence of textures specified in the shader + T_GEN_LIGHTMAP, //world light samples + T_GEN_DELUXMAP, //world light directions + T_GEN_SHADOWMAP, //light's depth values. - SHADER_PASS_VIDEOMAP = 1 << 3, - SHADER_PASS_DETAIL = 1 << 4, - SHADER_PASS_LIGHTMAP = 1 << 5, - SHADER_PASS_DELUXMAP = 1 << 6, - SHADER_PASS_NOCOLORARRAY = 1<< 7, + T_GEN_DIFFUSE, //texture's default diffuse texture + T_GEN_NORMALMAP, //texture's default normalmap + T_GEN_SPECULAR, //texture's default specular texture + T_GEN_UPPEROVERLAY, //texture's default personal colour + T_GEN_LOWEROVERLAY, //texture's default team colour + T_GEN_FULLBRIGHT, //texture's default fullbright overlay + + T_GEN_CURRENTRENDER,//copy the current screen to a texture, and draw that + + T_GEN_VIDEOMAP, //use the media playback as an image source, updating each frame for which it is visible + } texgen; + + enum { + SHADER_PASS_NOCOLORARRAY = 1<< 3, + + //FIXME: remove these + SHADER_PASS_VIDEOMAP = 1 << 4, + SHADER_PASS_DETAIL = 1 << 5, + SHADER_PASS_LIGHTMAP = 1 << 6, + SHADER_PASS_DELUXMAP = 1 << 7, SHADER_PASS_ANIMMAP = 1 << 8 } flags; } shaderpass_t; @@ -190,8 +253,8 @@ typedef struct { mesh_t meshes[5]; - int farbox_textures[6]; - int nearbox_textures[6]; + texid_t farbox_textures[6]; + texid_t nearbox_textures[6]; } skydome_t; typedef struct { @@ -203,6 +266,7 @@ typedef struct { SP_BOTTOMCOLOURS, SP_TIME, SP_EYEPOS, + SP_ENTMATRIX, SP_LIGHTRADIUS, SP_LIGHTCOLOUR, @@ -217,13 +281,16 @@ typedef struct { unsigned int handle; } shaderprogparm_t; -typedef struct shader_s { - enum { - SSTYLE_CUSTOM, - SSTYLE_FULLBRIGHT, - SSTYLE_LIGHTMAPPED - } style; - int numpasses; //careful... 0 means it's not loaded... and not actually a proper shader. +typedef struct { + float factor; + float unit; +} polyoffset_t; +struct shader_s +{ + int width; + int height; + int numpasses; + texnums_t defaulttextures; struct shader_s *next; char name[MAX_QPATH]; //end of shared fields. @@ -234,6 +301,8 @@ typedef struct shader_s { int numdeforms; deformv_t deforms[SHADER_DEFORM_MAX]; + polyoffset_t polyoffset; + enum { SHADER_SKY = 1 << 0, SHADER_NOMIPMAPS = 1 << 1, @@ -243,16 +312,21 @@ typedef struct shader_s { SHADER_DEFORMV_BULGE = 1 << 5, SHADER_AUTOSPRITE = 1 << 6, SHADER_FLARE = 1 << 7, - SHADER_POLYGONOFFSET = 1 << 8, +// SHADER_REMOVED = 1 << 8, SHADER_ENTITY_MERGABLE = 1 << 9, SHADER_VIDEOMAP = 1 << 10, SHADER_DEPTHWRITE = 1 << 11, SHADER_AGEN_PORTAL = 1 << 12, SHADER_BLEND = 1 << 13, //blend or alphatest (not 100% opaque). - SHADER_NODRAW = 1 << 14 //parsed only to pee off developers when they forget it on no-pass shaders. + SHADER_NODRAW = 1 << 14, //parsed only to pee off developers when they forget it on no-pass shaders. + + SHADER_NODLIGHT = 1 << 15, //from surfaceflags + SHADER_HASLIGHTMAP = 1 << 16 } flags; - unsigned int programhandle; + union { + int glsl; + } programhandle; int numprogparams; shaderprogparm_t progparm[SHADER_PROGPARMS_MAX]; @@ -261,38 +335,78 @@ typedef struct shader_s { shadersort_t sort; skydome_t *skydome; + shader_gen_t *generator; + const char *genargs; meshfeatures_t features; int registration_sequence; -} shader_t; +}; extern shader_t r_shaders[]; +extern int be_maxpasses; - - -void R_RenderMeshGeneric ( meshbuffer_t *mb, shaderpass_t *pass ); -void R_RenderMeshCombined ( meshbuffer_t *mb, shaderpass_t *pass ); -void R_RenderMeshMultitextured ( meshbuffer_t *mb, shaderpass_t *pass ); -void R_RenderMeshProgram ( meshbuffer_t *mb, shaderpass_t *pass ); - shader_t *R_RegisterPic (char *name); -shader_t *R_RegisterShader (char *name); +shader_t *R_RegisterShader (char *name, const char *shaderscript); +shader_t *R_RegisterShader_Lightmap (char *name); shader_t *R_RegisterShader_Vertex (char *name); shader_t *R_RegisterShader_Flare (char *name); shader_t *R_RegisterSkin (char *name); -shader_t *R_RegisterCustom (char *name, void(*defaultgen)(char *name, shader_t*, void *args), void *args); +shader_t *R_RegisterCustom (char *name, shader_gen_t *defaultgen, const void *args); +void R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader); cin_t *R_ShaderGetCinematic(char *name); -void Shader_DefaultSkinShell(char *shortname, shader_t *s, void *args); -void Shader_DefaultBSP(char *shortname, shader_t *s, void *args); - +void Shader_DefaultSkinShell(char *shortname, shader_t *s, const void *args); +void Shader_DefaultBSP(char *shortname, shader_t *s, const void *args); +void Shader_DefaultScript(char *shortname, shader_t *s, const void *args); +void Shader_DoReload(void); void R_BackendInit (void); void Shader_Shutdown (void); qboolean Shader_Init (void); +void Shader_NeedReload(void); mfog_t *CM_FogForOrigin(vec3_t org); + +//not all modes accept meshes - STENCIL(intentional) and DEPTHONLY(not implemented) +typedef enum +{ + BEM_STANDARD, //regular mode to draw surfaces akin to q3 (aka: legacy mode). lightmaps+delux+ambient + BEM_DEPTHONLY, //just a quick depth pass. textures used only for alpha test (shadowmaps). + BEM_STENCIL, //used for drawing shadow volumes to the stencil buffer. + BEM_DEPTHDARK, //a quick depth pass. textures used only for alpha test. additive textures still shown as normal. + BEM_LIGHT, //we have a valid light + BEM_SMAPLIGHT //we have a light using a shadowmap +} backendmode_t; + +#define BEF_FORCEDEPTHWRITE 1 +#define BEF_FORCEDEPTHTEST 2 +#define BEF_FORCEADDITIVE 4 //blend dest = GL_ONE +#define BEF_FORCETRANSPARENT 8 //texenv replace -> modulate +#define BEF_FORCENODEPTH 16 //disables any and all depth. + +//Select the current render mode and modifier flags +void BE_SelectMode(backendmode_t mode, unsigned int flags); + +//Draws an entire mesh chain from a VBO. vbo can be null, in which case the chain may be drawn without batching. +void BE_DrawMeshChain(shader_t *shader, mesh_t *meshchain, vbo_t *vbo, texnums_t *texnums); + +//submits the world and ents... used only by gl_shadows.c +void BE_SubmitMeshes (void); + +void BE_Init(void); + +void BE_ClearVBO(vbo_t *vbo); + +#ifdef RTLIGHTS +void BE_SetupForShadowMap(void); +void Sh_GenShadowMaps (void); +void Sh_DrawLights(qbyte *vis); +void BE_BaseEntShadowDepth(void); +void BE_SelectDLight(dlight_t *dl, vec3_t colour); + +//Returns true if the mesh is not lit by the current light +qboolean BE_LightCullModel(vec3_t org, model_t *model); #endif diff --git a/engine/http/ftpclient.c b/engine/http/ftpclient.c index 4cc16c27..3469f58d 100644 --- a/engine/http/ftpclient.c +++ b/engine/http/ftpclient.c @@ -126,12 +126,12 @@ int FTP_CL_makelistensocket(void) if ((sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { - Sys_Error ("FTP_TCP_OpenSocket: socket:", strerror(qerrno)); + Sys_Error ("FTP_TCP_OpenSocket: socket: %s", strerror(qerrno)); } if (ioctlsocket (sock, FIONBIO, &_true) == -1) { - Sys_Error ("FTP_TCP_OpenSocket: ioctl FIONBIO:", strerror(qerrno)); + Sys_Error ("FTP_TCP_OpenSocket: ioctl FIONBIO: %s", strerror(qerrno)); } if( bind (sock, (void *)&address, sizeof(address)) == -1) @@ -158,14 +158,14 @@ int FTP_CL_makeconnectsocket(char *ftpdest) if ((sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { - IWebWarnPrintf ("FTP_UDP_OpenSocket: socket:", strerror(qerrno)); + IWebWarnPrintf ("FTP_UDP_OpenSocket: socket: %s", strerror(qerrno)); return INVALID_SOCKET; } if (ioctlsocket (sock, FIONBIO, &_true) == -1) { closesocket(sock); - IWebWarnPrintf ("FTTP_UDP_OpenSocket: ioctl FIONBIO:", strerror(qerrno)); + IWebWarnPrintf ("FTTP_UDP_OpenSocket: ioctl FIONBIO: %s", strerror(qerrno)); return INVALID_SOCKET; } @@ -179,7 +179,7 @@ int FTP_CL_makeconnectsocket(char *ftpdest) { closesocket(sock); - IWebWarnPrintf ("FTTP_UDP_OpenSocket: bind:", strerror(qerrno)); + IWebWarnPrintf ("FTTP_UDP_OpenSocket: bind: %s", strerror(qerrno)); return INVALID_SOCKET; } @@ -191,7 +191,7 @@ int FTP_CL_makeconnectsocket(char *ftpdest) /* { closesocket(sock); - Con_Printf ("FTTP_UDP_OpenSocket: ioctl FIONBIO:", strerror(qerrno)); + Con_Printf ("FTTP_UDP_OpenSocket: ioctl FIONBIO: %s", strerror(qerrno)); return INVALID_SOCKET; } */ diff --git a/engine/http/ftpserver.c b/engine/http/ftpserver.c index 31e43159..6cde1597 100644 --- a/engine/http/ftpserver.c +++ b/engine/http/ftpserver.c @@ -1,5 +1,13 @@ #include "quakedef.h" +#ifdef WEBSVONLY +#undef vsnprintf +#undef _vsnprintf +#ifdef _WIN32 +#define vsnprintf _vsnprintf +#endif +#endif + #ifdef WEBSERVER #include "iweb.h" @@ -51,14 +59,14 @@ qboolean FTP_ServerInit(int port) if ((ftpserversocket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { - Con_Printf ("FTP_TCP_OpenSocket: socket: %s\n", strerror(qerrno)); + IWebPrintf ("FTP_TCP_OpenSocket: socket: %s\n", strerror(qerrno)); ftpserverfailed = true; return false; } if (ioctlsocket (ftpserversocket, FIONBIO, &_true) == -1) { - Sys_Error ("FTP_TCP_OpenSocket: ioctl FIONBIO:", strerror(qerrno)); + IWebPrintf ("FTP_TCP_OpenSocket: ioctl FIONBIO: %s", strerror(qerrno)); ftpserverfailed = true; return false; } @@ -79,7 +87,7 @@ qboolean FTP_ServerInit(int port) if( bind (ftpserversocket, (void *)&address, sizeof(address)) == -1) { - Con_Printf("FTP_ServerInit: failed to bind socket\n"); + IWebPrintf("FTP_ServerInit: failed to bind socket\n"); closesocket(ftpserversocket); ftpserverfailed = true; return false; @@ -126,9 +134,9 @@ static int SendFileNameTo(const char *rawname, int size, void *param) fname = slash+1; if (isdir) - sprintf(buffer, "drw-r--r--\t1\troot\troot\t%8i Jan 1 12:00 %s\r\n", size, fname); + sprintf(buffer, "drw-r--r--\t1\troot\troot\t%8u Jan 1 12:00 %s\r\n", size, fname); else - sprintf(buffer, "-rw-r--r--\t1\troot\troot\t%8i Jan 1 12:00 %s\r\n", size, fname); + sprintf(buffer, "-rw-r--r--\t1\troot\troot\t%8u Jan 1 12:00 %s\r\n", size, fname); // strcpy(buffer, fname); // for (i = strlen(buffer); i < 40; i+=8) @@ -138,7 +146,7 @@ static int SendFileNameTo(const char *rawname, int size, void *param) return true; } -int FTP_SV_makelistensocket(unsigned long blocking) +int FTP_SV_makelistensocket(unsigned long nblocking) { char name[256]; int sock; @@ -160,12 +168,12 @@ int FTP_SV_makelistensocket(unsigned long blocking) if ((sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { - Sys_Error ("FTP_TCP_OpenSocket: socket:", strerror(qerrno)); + Sys_Error ("FTP_TCP_OpenSocket: socket: %s", strerror(qerrno)); } - if (ioctlsocket (sock, FIONBIO, &blocking) == -1) + if (ioctlsocket (sock, FIONBIO, &nblocking) == -1) { - Sys_Error ("FTP_TCP_OpenSocket: ioctl FIONBIO:", strerror(qerrno)); + Sys_Error ("FTP_TCP_OpenSocket: ioctl FIONBIO: %s", strerror(qerrno)); } if( bind (sock, (void *)&address, sizeof(address)) == -1) @@ -215,6 +223,7 @@ void QueueMessage(FTPclient_t *cl, char *msg) strcat(cl->messagebuffer, msg); } } + void VARGS QueueMessageva(FTPclient_t *cl, char *fmt, ...) { va_list argptr; @@ -222,6 +231,7 @@ void VARGS QueueMessageva(FTPclient_t *cl, char *fmt, ...) va_start (argptr, fmt); vsnprintf (msg,sizeof(msg)-1, fmt,argptr); + msg[sizeof(msg)-1] = 0; va_end (argptr); if (send (cl->controlsock, msg, strlen(msg), 0) == -1) @@ -240,6 +250,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl) char mode[64]; static char resource[8192]; + int _true = true; if (cl->datadir == 1) { @@ -283,6 +294,13 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl) cl->datadir = 0; } } + + pos = cl->datadir?1:!cl->blocking; + if (ioctlsocket (cl->controlsock, FIONBIO, &pos) == -1) + { + IWebPrintf ("FTP_ServerRun: blocking error: %s\n", strerror(qerrno)); + return 0; + } } else if (cl->datadir == 2) { @@ -439,7 +457,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl) cl->datasock = INVALID_SOCKET; } - cl->datasock = FTP_SV_makelistensocket(cl->blocking); + cl->datasock = FTP_SV_makelistensocket(true); if (cl->datasock == INVALID_SOCKET) QueueMessage (cl, "425 server was unable to make a listen socket\r\n"); else @@ -467,12 +485,12 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl) if ((cl->datasock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { - Sys_Error ("FTP_UDP_OpenSocket: socket:", strerror(qerrno)); + Sys_Error ("FTP_UDP_OpenSocket: socket: %s", strerror(qerrno)); } - if (ioctlsocket (cl->datasock, FIONBIO, &cl->blocking) == -1) + if (ioctlsocket (cl->datasock, FIONBIO, &_true) == -1) { - Sys_Error ("FTTP_UDP_OpenSocket: ioctl FIONBIO:", strerror(qerrno)); + Sys_Error ("FTTP_UDP_OpenSocket: ioctl FIONBIO: %s", strerror(qerrno)); } from.sin_family = AF_INET; @@ -592,7 +610,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl) continue; } - if (!*resource == '/') + if (!(*resource == '/')) { memmove(resource+strlen(cl->path), resource, strlen(resource)+1); memcpy(resource, cl->path, strlen(cl->path)); @@ -735,7 +753,7 @@ unsigned int WINAPI BlockingClient(FTPclient_t *cl) return 0; } - cl->blocking = false; + cl->blocking = true; while (!FTP_ServerThinkForConnection(cl)) { diff --git a/engine/http/httpserver.c b/engine/http/httpserver.c index 4ce2a2ea..cc309722 100644 --- a/engine/http/httpserver.c +++ b/engine/http/httpserver.c @@ -24,14 +24,14 @@ qboolean HTTP_ServerInit(int port) if ((httpserversocket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { - Con_Printf ("HTTP_ServerInit: socket: %s\n", strerror(qerrno)); + IWebPrintf ("HTTP_ServerInit: socket: %s\n", strerror(qerrno)); httpserverfailed = true; return false; } if (ioctlsocket (httpserversocket, FIONBIO, &_true) == -1) { - Con_Printf ("HTTP_ServerInit: ioctl FIONBIO: %s\n", strerror(qerrno)); + IWebPrintf ("HTTP_ServerInit: ioctl FIONBIO: %s\n", strerror(qerrno)); httpserverfailed = true; return false; } @@ -55,7 +55,7 @@ qboolean HTTP_ServerInit(int port) if( bind (httpserversocket, (void *)&address, sizeof(address)) == -1) { closesocket(httpserversocket); - Con_Printf("HTTP_ServerInit: failed to bind to socket\n"); + IWebPrintf("HTTP_ServerInit: failed to bind to socket\n"); httpserverfailed = true; return false; } @@ -312,7 +312,7 @@ cont: if (contentlen) { - content = BZ_Malloc(contentlen+1); + content = IWebMalloc(contentlen+1); memcpy(content, msg, contentlen+1); } @@ -337,7 +337,7 @@ cont: resource[0] = '/'; resource[1] = 0; //I'm lazy, they need to comply } - Con_Printf("Download request for \"%s\"\n", resource+1); + IWebPrintf("Download request for \"%s\"\n", resource+1); if (!strnicmp(mode, "P", 1)) //when stuff is posted, data is provided. Give an error message if we couldn't do anything with that data. cl->file = IWebGenerateFile(resource+1, content, contentlen); else @@ -427,7 +427,7 @@ notimplemented: } if (content) - BZ_Free(content); + IWebFree(content); break; case HTTP_SENDING: @@ -544,13 +544,15 @@ qboolean HTTP_ServerPoll(qboolean httpserverwanted, int portnum) //loop while tr if (ioctlsocket (clientsock, FIONBIO, &_true) == -1) { - Con_Printf ("HTTP_ServerInit: ioctl FIONBIO: %s\n", strerror(qerrno)); + IWebPrintf ("HTTP_ServerInit: ioctl FIONBIO: %s\n", strerror(qerrno)); closesocket(clientsock); return false; } +#ifndef WEBSVONLY SockadrToNetadr(&from, &na); - Con_Printf("New http connection from %s\n", NET_AdrToString(buf, sizeof(buf), na)); + IWebPrintf("New http connection from %s\n", NET_AdrToString(buf, sizeof(buf), na)); +#endif cl = IWebMalloc(sizeof(HTTP_active_connections_t)); diff --git a/engine/http/iweb.h b/engine/http/iweb.h index 5893f8d0..5ea9bcba 100644 --- a/engine/http/iweb.h +++ b/engine/http/iweb.h @@ -7,32 +7,10 @@ #ifdef WEBSVONLY typedef unsigned char qbyte; -typedef enum {false, true} qboolean; -typedef enum {NA_INVALID, NA_LOOPBACK, NA_IP, NA_IPX, NA_BROADCAST_IP, NA_BROADCAST_IPX} netadrtype_t; -typedef struct -{ - netadrtype_t type; - - qbyte ip[4]; - qbyte ipx[10]; - - unsigned short port; -} netadr_t; #include #include #include -#ifdef _WIN32 -#include -#endif - - -#define PORT_ANY 0 -void Sys_Error(char *fmt, ...); -int COM_CheckParm(char *parm); -int com_argc; -char **com_argv; - #define Con_TPrintf IWebPrintf #define TL_NETBINDINTERFACE "binding to %s" #define TL_CONNECTIONLOSTORABORTED "connection lost or aborted" @@ -45,20 +23,10 @@ char **com_argv; #define IWebMalloc(x) calloc(x, 1) #define IWebRealloc(x, y) realloc(x, y) #define IWebFree free - -#define MAX_OSPATH 1024 - -#else - -#ifndef QUAKEDEF_H__ +#endif #include "quakedef.h" -#else -//#include -#endif -#endif - #ifdef _WIN32 #include "winquake.h" #endif @@ -82,9 +50,9 @@ typedef qboolean iwboolean; //it's not allowed to error. #ifndef WEBSVONLY -void VARGS IWebDPrintf(char *fmt, ...); -void VARGS IWebPrintf(char *fmt, ...); -void VARGS IWebWarnPrintf(char *fmt, ...); +void VARGS IWebDPrintf(char *fmt, ...) LIKEPRINTF(1); +void VARGS IWebPrintf(char *fmt, ...) LIKEPRINTF(1); +void VARGS IWebWarnPrintf(char *fmt, ...) LIKEPRINTF(1); #endif typedef struct { diff --git a/engine/http/iwebiface.c b/engine/http/iwebiface.c index ae358766..2cbe398d 100644 --- a/engine/http/iwebiface.c +++ b/engine/http/iwebiface.c @@ -1,4 +1,4 @@ -#include "bothdefs.h" +#include "quakedef.h" #ifdef WEBSVONLY #define WEBSERVER @@ -12,6 +12,40 @@ #ifdef WEBSVONLY //we need some functions from quake +qboolean SV_AllowDownload (const char *name) +{ + return true; +} +char com_token[1024]; +com_tokentype_t com_tokentype; +int com_argc; +const char **com_argv; + +vfsfile_t *IWebGenerateFile(char *name, char *content, int contentlength) +{ + return NULL; +} +vfsfile_t *VFSSTDIO_Open(const char *osname, const char *mode); +vfsfile_t *FS_OpenVFS(const char *filename, const char *mode, enum fs_relative relativeto) +{ + return VFSSTDIO_Open(filename, mode); +} +void Q_strncpyz(char *d, const char *s, int n) +{ + int i; + n--; + if (n < 0) + return; //this could be an error + + for (i=0; *s; i++) + { + if (i == n) + break; + *d++ = *s++; + } + *d='\0'; +} + /*char *va(char *format, ...) { #define VA_BUFFERS 2 //power of two @@ -29,13 +63,15 @@ return string[bufnum]; }*/ -void Sys_Error(char *format, ...) +#undef _vsnprintf +void Sys_Error(const char *format, ...) { va_list argptr; char string[1024]; - + va_start (argptr, format); _vsnprintf (string,sizeof(string)-1, format,argptr); + string[sizeof(string)-1] = 0; va_end (argptr); printf("%s", string); @@ -43,7 +79,7 @@ void Sys_Error(char *format, ...) exit(1000); } -int COM_CheckParm(char *parm) +int COM_CheckParm(const char *parm) { return 0; } @@ -66,16 +102,14 @@ int main(int argc, char **argv) while(1) { - FTP_ServerRun(1); - HTTP_ServerPoll(1); - if (ftpserverfailed || httpserverfailed) - Sys_Error("FTP/HTTP server failed"); + FTP_ServerRun(1, 21); + HTTP_ServerPoll(1, 80); Sleep(1); } } -void COM_EnumerateFiles (char *match, int (*func)(char *, int, void *), void *parm) +void COM_EnumerateFiles (const char *match, int (*func)(const char *, int, void *), void *parm) { HANDLE r; WIN32_FIND_DATA fd; @@ -116,10 +150,7 @@ void COM_EnumerateFiles (char *match, int (*func)(char *, int, void *), void *pa FindClose(r); } - - -enum {TTP_UNKNOWN, TTP_STRING} com_tokentype; -char *COM_ParseOut (char *data, char *out, int outlen) +char *COM_ParseOut (const char *data, char *out, int outlen) { int c; int len; @@ -159,13 +190,13 @@ skipwhite: while (1) { if (len >= outlen-1) - return data; + return (char*)data; c = *data++; if (c=='\"' || !c) { out[len] = 0; - return data; + return (char*)data; } out[len] = c; len++; @@ -178,7 +209,7 @@ skipwhite: do { if (len >= outlen-1) - return data; + return (char*)data; out[len] = c; data++; @@ -187,11 +218,10 @@ skipwhite: } while (c>32); out[len] = 0; - return data; + return (char*)data; } -char com_token[2048]; -char *COM_ParseToken (char *data) +char *COM_ParseToken (const char *data, const char *punctuation) { int c; int len; @@ -242,7 +272,7 @@ skipwhite: if (c=='\"' || !c) { com_token[len] = 0; - return data; + return (char*)data; } com_token[len] = c; len++; @@ -257,7 +287,7 @@ skipwhite: com_token[len] = c; len++; com_token[len] = 0; - return data+1; + return (char*)data+1; } // parse a regular word @@ -272,10 +302,10 @@ skipwhite: } while (c>32); com_token[len] = 0; - return data; + return (char*)data; } - +/* IWEBFILE *IWebFOpenRead(char *name) //fread(name, "rb"); { FILE *f; @@ -304,7 +334,7 @@ IWEBFILE *IWebFOpenRead(char *name) //fread(name, "rb"); } return NULL; } - +*/ #else @@ -384,8 +414,8 @@ void IWebRun(void) #ifdef WEBSERVER extern qboolean httpserverfailed, ftpserverfailed; - FTP_ServerRun(ftpserver.value!= 0, ftpserver_port.value); - HTTP_ServerPoll(httpserver.value!=0, httpserver_port.value); + FTP_ServerRun(ftpserver.ival!= 0, ftpserver_port.ival); + HTTP_ServerPoll(httpserver.ival!=0, httpserver_port.ival); if (ftpserverfailed) { Con_Printf("FTP Server failed to load, setting %s to 0\n", ftpserver.name); diff --git a/engine/http/webgen.c b/engine/http/webgen.c index dcf8a69a..d874b52b 100644 --- a/engine/http/webgen.c +++ b/engine/http/webgen.c @@ -5,7 +5,7 @@ #include "iweb.h" #ifdef CLIENTONLY -IWEBFILE *IWebGenerateFile(char *name) +vfsfile_t *IWebGenerateFile(char *name) { return NULL; } @@ -32,7 +32,7 @@ void IWeb_MoreGeneratedResize(int newsize) { memcpy(IWeb_GenerationBuffer->data, ob->data, ob->len); IWeb_GenerationBuffer->len = ob->len; - BZ_Free(ob); + IWebFree(ob); } IWeb_GenerationBufferTotal = newsize; diff --git a/engine/libs/vorbis/vorbisfile.h b/engine/libs/vorbis/vorbisfile.h index da7ce703..d291b15e 100644 --- a/engine/libs/vorbis/vorbisfile.h +++ b/engine/libs/vorbis/vorbisfile.h @@ -37,10 +37,10 @@ extern "C" * unseekable */ typedef struct { - size_t (*read_func) (void *ptr, size_t size, size_t nmemb, void *datasource); - int (*seek_func) (void *datasource, ogg_int64_t offset, int whence); - int (*close_func) (void *datasource); - long (*tell_func) (void *datasource); + size_t (VARGS *read_func) (void *ptr, size_t size, size_t nmemb, void *datasource); + int (VARGS *seek_func) (void *datasource, ogg_int64_t offset, int whence); + int (VARGS *close_func) (void *datasource); + long (VARGS *tell_func) (void *datasource); } ov_callbacks; #define NOTOPEN 0 diff --git a/engine/qclib/cmdlib.h b/engine/qclib/cmdlib.h index 2da37795..768d899a 100644 --- a/engine/qclib/cmdlib.h +++ b/engine/qclib/cmdlib.h @@ -43,9 +43,18 @@ int QC_strcasecmp (const char *s1, const char *s2); #define QC_vsnprintf vsnprintf #endif +#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) + #ifndef LIKEPRINTF + #define LIKEPRINTF(x) __attribute__((format(printf,x,x+1))) + #endif +#endif +#ifndef LIKEPRINTF +#define LIKEPRINTF(x) +#endif + double I_FloatTime (void); -void VARGS QCC_Error (int errortype, const char *error, ...); +void VARGS QCC_Error (int errortype, const char *error, ...) LIKEPRINTF(2); int CheckParm (char *check); diff --git a/engine/qclib/initlib.c b/engine/qclib/initlib.c index ca44b781..59ace148 100644 --- a/engine/qclib/initlib.c +++ b/engine/qclib/initlib.c @@ -95,7 +95,7 @@ int PR_InitEnts(progfuncs_t *progfuncs, int max_ents) sv_edicts = PRHunkAlloc(progfuncs, externs->edictsize); prinst->edicttable[0] = sv_edicts; ((edictrun_t*)prinst->edicttable[0])->fields = PRAddressableAlloc(progfuncs, max_fields_size); - ED_ClearEdict(progfuncs, (edictrun_t *)sv_edicts); + QC_ClearEdict(progfuncs, sv_edicts); sv_num_edicts = 1; return max_fields_size; @@ -643,7 +643,8 @@ progfuncs_t deffuncs = { PR_StringToProgs, PR_StringToNative, 0, - PR_QueryField + PR_QueryField, + QC_ClearEdict }; #undef printf diff --git a/engine/qclib/pr_edict.c b/engine/qclib/pr_edict.c index 6ee3963e..868e3310 100644 --- a/engine/qclib/pr_edict.c +++ b/engine/qclib/pr_edict.c @@ -45,13 +45,14 @@ static gefv_cache gefvCache[GEFV_CACHESIZE] = {{NULL, ""}, {NULL, ""}}; /* ================= -ED_ClearEdict +QC_ClearEdict Sets everything to NULL ================= */ -void ED_ClearEdict (progfuncs_t *progfuncs, edictrun_t *e) +void QC_ClearEdict (progfuncs_t *progfuncs, struct edict_s *ed) { + edictrun_t *e = (edictrun_t *)ed; int num = e->entnum; memset (e->fields, 0, fields_size); e->isfree = false; @@ -66,7 +67,7 @@ edictrun_t *ED_AllocIntoTable (progfuncs_t *progfuncs, int num) memset(e, 0, externs->edictsize); e->fields = PRAddressableAlloc(progfuncs, fields_size); e->entnum = num; - ED_ClearEdict(progfuncs, e); + QC_ClearEdict(progfuncs, (struct edict_s*)e); return e; } @@ -97,7 +98,7 @@ struct edict_s *ED_Alloc (progfuncs_t *progfuncs) if (!e) e = ED_AllocIntoTable(progfuncs, i); else - ED_ClearEdict (progfuncs, e); + QC_ClearEdict (progfuncs, (struct edict_s*)e); if (externs->entspawn) externs->entspawn((struct edict_s *) e, false); @@ -117,7 +118,7 @@ struct edict_s *ED_Alloc (progfuncs_t *progfuncs) if (!e) e = ED_AllocIntoTable(progfuncs, i); else - ED_ClearEdict (progfuncs, e); + QC_ClearEdict (progfuncs, (struct edict_s*)e); if (externs->entspawn) externs->entspawn((struct edict_s *) e, false); @@ -146,7 +147,7 @@ struct edict_s *ED_Alloc (progfuncs_t *progfuncs) if (!e) e = ED_AllocIntoTable(progfuncs, i); else - ED_ClearEdict (progfuncs, e); + QC_ClearEdict (progfuncs, (struct edict_s*)e); if (externs->entspawn) externs->entspawn((struct edict_s *) e, false); @@ -1184,7 +1185,7 @@ char *ED_ParseEdict (progfuncs_t *progfuncs, char *data, edictrun_t *ent) data = QCC_COM_Parse (data); if (!data) { - printf ("ED_ParseEntity: EOF without closing brace"); + printf ("ED_ParseEntity: EOF without closing brace\n"); return NULL; } @@ -3112,6 +3113,6 @@ unsigned int NUM_FOR_EDICT(progfuncs_t *progfuncs, struct edict_s *e) { edictrun_t *er = (edictrun_t*)e; if (er->entnum >= maxedicts) - Sys_Error ("QCLIB: NUM_FOR_EDICT: bad pointer (%i)", e); + Sys_Error ("QCLIB: NUM_FOR_EDICT: bad pointer (%p)", e); return er->entnum; } diff --git a/engine/qclib/pr_x86.c b/engine/qclib/pr_x86.c index acd0a1f4..4ebfdda2 100644 --- a/engine/qclib/pr_x86.c +++ b/engine/qclib/pr_x86.c @@ -119,7 +119,7 @@ pbool PR_GenerateJit(progfuncs_t *progfuncs) int *glob = (int*)current_progstate->globals; if (current_progstate->numbuiltins) - return; + return false; jitstatements = numstatements; @@ -259,7 +259,7 @@ pbool PR_GenerateJit(progfuncs_t *progfuncs) //remember to change the je above //err... exit depth? no idea - EmitByte(0xcd);EmitByte(op[i].op); + EmitByte(0xcd);EmitByte(op[i].op); //int $X //ret @@ -560,7 +560,7 @@ EmitByte(0xcc); //jmp 10 EmitByte(0xeb);EmitByte(0x0a); //mov 1.0f,glob[C] - EmitByte(0xc7);EmitByte(0x05); EmitAdr(glob + op[i].a);EmitFloat(1.0f); + EmitByte(0xc7);EmitByte(0x05); EmitAdr(glob + op[i].c);EmitFloat(1.0f); break; case OP_BITOR: //floats... @@ -972,7 +972,55 @@ EmitByte(0xcc); //add $12,%esp EmitByte(0x83); EmitByte(0xc4); EmitByte(0x0c); break; -/* +#if 0 + case OP_NOT_V: + //flds 0 + //flds glob[A+0] + //fcomip %st(1),%st + //jne _true + //flds glob[A+1] + //fcomip %st(1),%st + //jne _true + //flds glob[A+1] + //fcomip %st(1),%st + //jne _true + //mov 1,C + //jmp done + //_true: + //mov 0,C + //done: + break; + + case OP_EQ_V: + //flds glob[A] + EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + op[i].a+0); + //flds glob[B] + EmitByte(0xd9);EmitByte(0x05);EmitAdr(glob + op[i].b+0); + //fcomip %st(1),%st + EmitByte(0xdf);EmitByte(0xe9); + //fstp %st(0) (aka: pop) + EmitByte(0xdd);EmitByte(0xd8); + + //jncc _true + if (op[i].op == OP_NE_V) + EmitByte(0x74); //je + else + EmitByte(0x75); //jne + EmitByte(0x0c); +//_false0: + //mov 0.0f,c + EmitByte(0xc7); EmitByte(0x05); EmitAdr(glob + op[i].c); EmitFloat(1.0f); + //jmp done + EmitByte(0xeb); EmitByte(0x0a); + + +//_true: + //mov 1.0f,c + EmitByte(0xc7); EmitByte(0x05); EmitAdr(glob + op[i].c); EmitFloat(0.0f); +//_done: + break; + + case OP_EQ_V: EmitByte(0xcd);EmitByte(op[i].op); printf("QCJIT: instruction %i is not implemented\n", op[i].op); @@ -987,7 +1035,7 @@ EmitByte(0xcc); EmitByte(0xcd);EmitByte(op[i].op); printf("QCJIT: instruction %i is not implemented\n", op[i].op); break; -*/ +#endif default: printf("QCJIT: Extended instruction set %i is not supported, not using jit.\n", op[i].op); @@ -1021,7 +1069,7 @@ void PR_EnterJIT(progfuncs_t *progfuncs, int statement) { #ifdef __GNUC__ //call, it clobbers pretty much everything. - asm("call %0" :: "r"(statementoffsets[statement+1]),"b"(prinst->edicttable):"cc","memory","eax","ecx","edx"); + asm("call *%0" :: "r"(statementoffsets[statement+1]),"b"(prinst->edicttable):"cc","memory","eax","ecx","edx"); #elif defined(_MSC_VER) void *entry = statementoffsets[statement+1]; void *edicttable = prinst->edicttable; @@ -1036,4 +1084,4 @@ void PR_EnterJIT(progfuncs_t *progfuncs, int statement) #error "Sorry, no idea how to enter assembler safely for your compiler" #endif } -#endif \ No newline at end of file +#endif diff --git a/engine/qclib/progsint.h b/engine/qclib/progsint.h index e73d7afd..0b4e44ab 100644 --- a/engine/qclib/progsint.h +++ b/engine/qclib/progsint.h @@ -1,4 +1,4 @@ -#ifdef WIN32 +#ifdef _WIN32 #ifndef AVAIL_ZLIB #ifdef _MSC_VER @@ -89,8 +89,13 @@ void PRHunkFree(progfuncs_t *progfuncs, int mark); void *PRHunkAlloc(progfuncs_t *progfuncs, int size); void *PRAddressableAlloc(progfuncs_t *progfuncs, int ammount); +#ifdef printf +#undef LIKEPRINTF +#define LIKEPRINTF(x) +#endif + //void *HunkAlloc (int size); -char *VARGS qcva (char *text, ...); +char *VARGS qcva (char *text, ...) LIKEPRINTF(1); void QC_InitShares(progfuncs_t *progfuncs); void QC_StartShares(progfuncs_t *progfuncs); void QC_AddSharedVar(progfuncs_t *progfuncs, int num, int type); @@ -281,7 +286,7 @@ const extern unsigned int type_size[]; extern unsigned short pr_crc; -void VARGS PR_RunError (progfuncs_t *progfuncs, char *error, ...); +void VARGS PR_RunError (progfuncs_t *progfuncs, char *error, ...) LIKEPRINTF(2); void ED_PrintEdicts (progfuncs_t *progfuncs); void ED_PrintNum (progfuncs_t *progfuncs, int ent); @@ -447,7 +452,7 @@ func_t PR_FindFunc(progfuncs_t *progfncs, char *funcname, progsnum_t pnum); void PR_Configure (progfuncs_t *progfncs, int addressable_size, int max_progs); int PR_InitEnts(progfuncs_t *progfncs, int maxents); char *PR_ValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val); -void ED_ClearEdict (progfuncs_t *progfuncs, edictrun_t *e); +void QC_ClearEdict (progfuncs_t *progfuncs, struct edict_s *ed); void PRAddressableFlush(progfuncs_t *progfuncs, int totalammount); void QC_FlushProgsOffsets(progfuncs_t *progfuncs); @@ -466,6 +471,9 @@ char *PR_GlobalStringNoContents (progfuncs_t *progfuncs, int ofs); pbool CompileFile(progfuncs_t *progfuncs, char *filename); +pbool PR_GenerateJit(progfuncs_t *progfuncs); +void PR_EnterJIT(progfuncs_t *progfuncs, int statement); + char *QCC_COM_Parse (char *data); extern char qcc_token[1024]; #endif diff --git a/engine/qclib/progslib.h b/engine/qclib/progslib.h index 45aa91bf..f3f4488a 100644 --- a/engine/qclib/progslib.h +++ b/engine/qclib/progslib.h @@ -22,10 +22,16 @@ typedef char *string_t; */ #ifdef _MSC_VER -#define VARGS __cdecl + #define VARGS __cdecl +#endif +#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) + #define LIKEPRINTF(x) __attribute__((format(printf,x,x+1))) +#endif +#ifndef LIKEPRINTF + #define LIKEPRINTF(x) #endif #ifndef VARGS -#define VARGS + #define VARGS #endif @@ -60,7 +66,7 @@ struct progfuncs_s { struct globalvars_s *(*globals) (progfuncs_t *prinst, progsnum_t num); //get the globals of a progs struct entvars_s *(*entvars) (progfuncs_t *prinst, struct edict_s *ent); //return a pointer to the entvars of an ent. can be achieved via the edict_t structure instead, so obsolete. - void (VARGS *RunError) (progfuncs_t *prinst, char *msg, ...); //builtins call this to say there was a problem + void (VARGS *RunError) (progfuncs_t *prinst, char *msg, ...) LIKEPRINTF(2); //builtins call this to say there was a problem void (*PrintEdict) (progfuncs_t *prinst, struct edict_s *ed); //get a listing of all vars on an edict (sent back via 'print') struct edict_s *(*EntAlloc) (progfuncs_t *prinst); @@ -137,7 +143,9 @@ struct progfuncs_s { char *(*StringToNative) (progfuncs_t *prinst, string_t str); int stringtablesize; - int (*QueryField) (progfuncs_t *prinst, unsigned int fieldoffset, etype_t *type, char **name, evalc_t *fieldcache); //find info on a field definition at an offset + int (*QueryField) (progfuncs_t *prinst, unsigned int fieldoffset, etype_t *type, char **name, evalc_t *fieldcache); //find info on a field definition at an offset + + void (*EntClear) (progfuncs_t *progfuncs, struct edict_s *e); }; typedef struct progexterns_s { @@ -146,9 +154,9 @@ typedef struct progexterns_s { unsigned char *(*ReadFile) (char *fname, void *buffer, int len); int (*FileSize) (char *fname); //-1 if file does not exist pbool (*WriteFile) (char *name, void *data, int len); - int (VARGS *printf) (const char *, ...); - void (VARGS *Sys_Error) (const char *, ...); - void (VARGS *Abort) (char *, ...); + int (VARGS *printf) (const char *, ...) LIKEPRINTF(1); + void (VARGS *Sys_Error) (const char *, ...) LIKEPRINTF(1); + void (VARGS *Abort) (char *, ...) LIKEPRINTF(1); int edictsize; //size of edict_t void (*entspawn) (struct edict_s *ent, int loading); //ent has been spawned, but may not have all the extra variables (that may need to be set) set @@ -183,7 +191,9 @@ typedef struct progexterns_s { //FIXMEs void QC_AddSharedVar(progfuncs_t *progfuncs, int start, int size); void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num, char *relstringtable); -void ED_Print (progfuncs_t *progfuncs, struct edict_s *ed); +void ED_Print(progfuncs_t *progfuncs, struct edict_s *ed); +char *PR_RemoveProgsString(progfuncs_t *progfuncs, string_t str); +int PR_GetFuncArgCount(progfuncs_t *progfuncs, func_t func); #if defined(QCLIBDLL_EXPORTS) __declspec(dllexport) @@ -218,7 +228,7 @@ typedef union eval_s #define PR_LoadProgs(pf, s, headercrc, builtins, numb) (*pf->LoadProgs) (pf, s, headercrc, builtins, numb) #define PR_InitEnts(pf, maxents) (*pf->InitEnts) (pf, maxents) #define PR_ExecuteProgram(pf, fnum) (*pf->ExecuteProgram) (pf, fnum) -#define PR_SwitchProgs(pf, num) (*pf->SwitchProgs) (pf, num); +#define PR_SwitchProgs(pf, num) (*pf->SwitchProgs) (pf, num) #define PR_globals(pf, num) (*pf->globals) (pf, num) #define PR_entvars(pf, ent) (*pf->entvars) (pf, ent) @@ -226,6 +236,7 @@ typedef union eval_s #define ED_Alloc(pf) (*pf->EntAlloc) (pf) #define ED_Free(pf, ed) (*pf->EntFree) (pf, ed) +#define ED_Clear(pf, ed) (*pf->EntClear) (pf, ed) #define PR_LoadEnts(pf, s, kf) (*pf->load_ents) (pf, s, kf) #define PR_SaveEnts(pf, buf, size, mode) (*pf->save_ents) (pf, buf, size, mode) @@ -251,7 +262,7 @@ typedef union eval_s #define PR_Alloc(pf,size) (*pf->Tempmem) (pf, size) #define PROG_TO_EDICT(pf, ed) (*pf->ProgsToEdict) (pf, ed) -#define EDICT_TO_PROG(pf, ed) (*pf->EdictToProgs) (pf, ed) +#define EDICT_TO_PROG(pf, ed) (*pf->EdictToProgs) (pf, (struct edict_s*)ed) #define PR_RegisterBuiltin(pf, name, func) (*pf->RegisterBuiltin) (pf, name, func) diff --git a/engine/qclib/qcc.h b/engine/qclib/qcc.h index 75b2b378..65b360ba 100644 --- a/engine/qclib/qcc.h +++ b/engine/qclib/qcc.h @@ -477,6 +477,7 @@ extern pbool flag_laxcasts; extern pbool flag_hashonly; extern pbool flag_fasttrackarrays; extern pbool flag_assume_integer; +extern pbool flag_msvcstyle; extern pbool opt_overlaptemps; extern pbool opt_shortenifnots; diff --git a/engine/qclib/qcc_pr_comp.c b/engine/qclib/qcc_pr_comp.c index cb7abd28..ccb4aa10 100644 --- a/engine/qclib/qcc_pr_comp.c +++ b/engine/qclib/qcc_pr_comp.c @@ -74,6 +74,7 @@ pbool flag_caseinsensative; //symbols will be matched to an insensative case if pbool flag_laxcasts; //Allow lax casting. This'll produce loadsa warnings of course. But allows compilation of certain dodgy code. pbool flag_hashonly; //Allows use of only #constant for precompiler constants, allows certain preqcc using mods to compile pbool flag_fasttrackarrays; //Faster arrays, dynamically detected, activated only in supporting engines. +pbool flag_msvcstyle; //MSVC style warnings, so msvc's ide works properly pbool flag_assume_integer; //5 - is that an integer or a float? qcc says float. but we support int too, so maybe we want that instead? pbool opt_overlaptemps; //reduce numpr_globals by reuse of temps. When they are not needed they are freed for reuse. The way this is implemented is better than frikqcc's. (This is the single most important optimisation) diff --git a/engine/qclib/qcc_pr_lex.c b/engine/qclib/qcc_pr_lex.c index 6b442bca..43e13316 100644 --- a/engine/qclib/qcc_pr_lex.c +++ b/engine/qclib/qcc_pr_lex.c @@ -1401,7 +1401,7 @@ void QCC_PR_LexNumber (void) pr_file_p++; } pr_token[tokenlen++] = 0; - pr_immediate._float = atof(pr_token); + pr_immediate._float = (float)atof(pr_token); return; } else if (c == 'i') @@ -2599,7 +2599,12 @@ void QCC_PR_ParsePrintDef (int type, QCC_def_t *def) if (qccwarningdisabled[type]) return; if (def->s_file) - printf ("%s:%i: %s is defined here\n", strings + def->s_file, def->s_line, def->name); + { + if (flag_msvcstyle) + printf ("%s(%i) : %s is defined here\n", strings + def->s_file, def->s_line, def->name); + else + printf ("%s:%i: %s is defined here\n", strings + def->s_file, def->s_line, def->name); + } } void *errorscope; void QCC_PR_PrintScope (void) @@ -2645,7 +2650,10 @@ void VARGS QCC_PR_ParseError (int errortype, char *error, ...) #endif QCC_PR_PrintScope(); - printf ("%s:%i: error: %s\n", strings + s_file, pr_source_line, string); + if (flag_msvcstyle) + printf ("%s(%i) : error: %s\n", strings + s_file, pr_source_line, string); + else + printf ("%s:%i: error: %s\n", strings + s_file, pr_source_line, string); longjmp (pr_parse_abort, 1); } @@ -2662,7 +2670,10 @@ void VARGS QCC_PR_ParseErrorPrintDef (int errortype, QCC_def_t *def, char *error editbadfile(strings+s_file, pr_source_line); #endif QCC_PR_PrintScope(); - printf ("%s:%i: error: %s\n", strings + s_file, pr_source_line, string); + if (flag_msvcstyle) + printf ("%s(%i) : error: %s\n", strings + s_file, pr_source_line, string); + else + printf ("%s:%i: error: %s\n", strings + s_file, pr_source_line, string); QCC_PR_ParsePrintDef(WARN_ERROR, def); @@ -2683,12 +2694,18 @@ void VARGS QCC_PR_ParseWarning (int type, char *error, ...) QCC_PR_PrintScope(); if (type >= ERR_PARSEERRORS) { - printf ("%s:%i: error: %s\n", strings + s_file, pr_source_line, string); + if (flag_msvcstyle) + printf ("%s(%i) : error: %s\n", strings + s_file, pr_source_line, string); + else + printf ("%s:%i: error: %s\n", strings + s_file, pr_source_line, string); pr_error_count++; } else { - printf ("%s:%i: warning: %s\n", strings + s_file, pr_source_line, string); + if (flag_msvcstyle) + printf ("%s(%i) : warning: %s\n", strings + s_file, pr_source_line, string); + else + printf ("%s:%i: warning: %s\n", strings + s_file, pr_source_line, string); pr_warning_count++; } } @@ -2707,7 +2724,12 @@ void VARGS QCC_PR_Warning (int type, char *file, int line, char *error, ...) QCC_PR_PrintScope(); if (file) - printf ("%s:%i: warning: %s\n", file, line, string); + { + if (flag_msvcstyle) + printf ("%s(%i) : warning: %s\n", file, line, string); + else + printf ("%s:%i: warning: %s\n", file, line, string); + } else printf ("warning: %s\n", string); pr_warning_count++; diff --git a/engine/qclib/qccmain.c b/engine/qclib/qccmain.c index 48d1994e..770fb44e 100644 --- a/engine/qclib/qccmain.c +++ b/engine/qclib/qccmain.c @@ -15,6 +15,7 @@ extern int optres_test2; int writeasm; static pbool pr_werror; +pbool verbose; pbool QCC_PR_SimpleGetToken (void); @@ -230,6 +231,7 @@ compiler_flag_t compiler_flag[] = { {&flag_laxcasts, FLAG_MIDCOMPILE,"lax", "Lax type checks", "Disables many errors (generating warnings instead) when function calls or operations refer to two normally incompatible types. This is required for reacc support, and can also allow certain (evil) mods to compile that were originally written for frikqcc."}, //Allow lax casting. This'll produce loadsa warnings of course. But allows compilation of certain dodgy code. {&flag_hashonly, FLAG_MIDCOMPILE,"hashonly", "Hash-only constants", "Allows use of only #constant for precompiler constants, allows certain preqcc using mods to compile"}, {&opt_logicops, FLAG_MIDCOMPILE,"lo", "Logic ops", "This changes the behaviour of your code. It generates additional if operations to early-out in if statements. With this flag, the line if (0 && somefunction()) will never call the function. It can thus be considered an optimisation. However, due to the change of behaviour, it is not considered so by fteqcc. Note that due to inprecisions with floats, this flag can cause runaway loop errors within the player walk and run functions (without iffloat also enabled). This code is advised:\nplayer_stand1:\n if (self.velocity_x || self.velocity_y)\nplayer_run\n if (!(self.velocity_x || self.velocity_y))"}, + {&flag_msvcstyle, FLAG_MIDCOMPILE,"msvcstyle", "MSVC-style errors", "Generates warning and error messages in a format that msvc understands, to facilitate ide integration."}, {&flag_fasttrackarrays, FLAG_MIDCOMPILE|FLAG_ASDEFAULT,"fastarrays","fast arrays where possible", "Generates extra instructions inside array handling functions to detect engine and use extension opcodes only in supporting engines.\nAdds a global which is set by the engine if the engine supports the extra opcodes. Note that this applies to all arrays or none."}, {&flag_assume_integer, FLAG_MIDCOMPILE,"assumeint", "Assume Integers", "Numerical constants are assumed to be integers, instead of floats."}, {NULL} @@ -634,10 +636,13 @@ pbool QCC_WriteData (int crc) //include a type block? types = debugtarget;//!!QCC_PR_CheckCompConstDefined("TYPES"); //useful for debugging and saving (maybe, anyway...). - if (qcc_targetformat == QCF_DARKPLACES) - printf("DarkPlaces or FTE will be required\n"); - else - printf("An FTE executor will be required\n"); + if (verbose) + { + if (qcc_targetformat == QCF_DARKPLACES) + printf("DarkPlaces or FTE will be required\n"); + else + printf("An FTE executor will be required\n"); + } break; case QCF_KK7: if (bodylessfuncs) @@ -845,16 +850,20 @@ pbool QCC_WriteData (int crc) //PrintGlobals (); strofs = (strofs+3)&~3; - printf ("%6i strofs (of %i)\n", strofs, MAX_STRINGS); - printf ("%6i numstatements (of %i)\n", numstatements, MAX_STATEMENTS); - printf ("%6i numfunctions (of %i)\n", numfunctions, MAX_FUNCTIONS); - printf ("%6i numglobaldefs (of %i)\n", numglobaldefs, MAX_GLOBALS); - printf ("%6i numfielddefs (%i unique) (of %i)\n", numfielddefs, pr.size_fields, MAX_FIELDS); - printf ("%6i numpr_globals (of %i)\n", numpr_globals, MAX_REGS); + if (verbose) + { + printf ("%6i strofs (of %i)\n", strofs, MAX_STRINGS); + printf ("%6i numstatements (of %i)\n", numstatements, MAX_STATEMENTS); + printf ("%6i numfunctions (of %i)\n", numfunctions, MAX_FUNCTIONS); + printf ("%6i numglobaldefs (of %i)\n", numglobaldefs, MAX_GLOBALS); + printf ("%6i numfielddefs (%i unique) (of %i)\n", numfielddefs, pr.size_fields, MAX_FIELDS); + printf ("%6i numpr_globals (of %i)\n", numpr_globals, MAX_REGS); + } if (!*destfile) strcpy(destfile, "progs.dat"); - printf("Writing %s\n", destfile); + if (verbose) + printf("Writing %s\n", destfile); h = SafeOpenWrite (destfile, 2*1024*1024); SafeWrite (h, &progs, sizeof(progs)); SafeWrite (h, "\r\n\r\n", 4); @@ -1187,7 +1196,8 @@ strofs = (strofs+3)&~3; break; } - printf ("%6i TOTAL SIZE\n", (int)SafeSeek (h, 0, SEEK_CUR)); + if (verbose) + printf ("%6i TOTAL SIZE\n", (int)SafeSeek (h, 0, SEEK_CUR)); progs.entityfields = pr.size_fields; @@ -1215,7 +1225,8 @@ strofs = (strofs+3)&~3; unsigned int version = 1; StripExtension(destfile); strcat(destfile, ".lno"); - printf("Writing %s\n", destfile); + if (verbose) + printf("Writing %s for debugging\n", destfile); h = SafeOpenWrite (destfile, 2*1024*1024); SafeWrite (h, &lnotype, sizeof(int)); SafeWrite (h, &version, sizeof(int)); @@ -1608,8 +1619,9 @@ int QCC_PR_FinishCompilation (void) } else { - QCC_PR_Warning(WARN_NOTDEFINED, strings + d->s_file, d->s_line, "function %s was not defined",d->name); + QCC_PR_ParseErrorPrintDef(ERR_NOFUNC, d, "function %s was not defined",d->name); bodylessfuncs = true; + errors = true; } // errors = true; } @@ -1887,28 +1899,35 @@ unsigned short QCC_PR_WriteProgdefs (char *filename) case 12923: //#pragma sourcefile usage break; case 54730: - printf("Recognised progs as QuakeWorld\n"); + if (verbose) + printf("Recognised progs as QuakeWorld\n"); break; case 5927: - printf("Recognised progs as NetQuake server gamecode\n"); + if (verbose) + printf("Recognised progs as NetQuake server gamecode\n"); break; case 26940: - printf("Recognised progs as Quake pre-release...\n"); + if (verbose) + printf("Recognised progs as Quake pre-release...\n"); break; case 38488: - printf("Recognised progs as original Hexen2\n"); + if (verbose) + printf("Recognised progs as original Hexen2\n"); break; case 26905: - printf("Recognised progs as Hexen2 Mission Pack\n"); + if (verbose) + printf("Recognised progs as Hexen2 Mission Pack\n"); break; case 14046: - printf("Recognised progs as Hexen2 (demo)\n"); + if (verbose) + printf("Recognised progs as Hexen2 (demo)\n"); break; case 22390: //EXT_CSQC_1 - printf("Recognised progs as a CSQC module\n"); + if (verbose) + printf("Recognised progs as an EXT_CSQC_1 module\n"); break; case 17105: case 32199: //outdated ext_csqc @@ -1918,7 +1937,8 @@ unsigned short QCC_PR_WriteProgdefs (char *filename) printf("Recognised progs as outdated CSQC module\n"); break; case 10020: - printf("Recognised progs as a DP/FTE Menu module\n"); + if (verbose) + printf("Recognised progs as a DP/FTE Menu module\n"); break; case 32401: @@ -2274,14 +2294,17 @@ void QCC_CopyFiles (void) char srcdir[1024], destdir[1024]; int p; - if (numsounds > 0) - printf ("%3i unique precache_sounds\n", numsounds); - if (nummodels > 0) - printf ("%3i unique precache_models\n", nummodels); - if (numtextures > 0) - printf ("%3i unique precache_textures\n", numtextures); - if (numfiles > 0) - printf ("%3i unique precache_files\n", numfiles); + if (verbose) + { + if (numsounds > 0) + printf ("%3i unique precache_sounds\n", numsounds); + if (nummodels > 0) + printf ("%3i unique precache_models\n", nummodels); + if (numtextures > 0) + printf ("%3i unique precache_textures\n", numtextures); + if (numfiles > 0) + printf ("%3i unique precache_files\n", numfiles); + } p = QCC_CheckParm ("-copy"); if (p && p < myargc-2) @@ -3157,7 +3180,9 @@ void QCC_ContinueCompile(void) if (autoprototype) printf ("prototyping %s\n", qccmfilename); else + { printf ("compiling %s\n", qccmfilename); + } QCC_LoadFile (qccmfilename, (void *)&qccmsrc2); if (!QCC_PR_CompileFile (qccmsrc2, qccmfilename) ) @@ -3217,58 +3242,61 @@ void QCC_FinishCompile(void) if (donesomething) { - printf ("Compile Complete\n\n"); + if (verbose) + { + printf ("Compile Complete\n\n"); - if (optres_shortenifnots) - printf("optres_shortenifnots %i\n", optres_shortenifnots); - if (optres_overlaptemps) - printf("optres_overlaptemps %i\n", optres_overlaptemps); - if (optres_noduplicatestrings) - printf("optres_noduplicatestrings %i\n", optres_noduplicatestrings); - if (optres_constantarithmatic) - printf("optres_constantarithmatic %i\n", optres_constantarithmatic); - if (optres_nonvec_parms) - printf("optres_nonvec_parms %i\n", optres_nonvec_parms); - if (optres_constant_names) - printf("optres_constant_names %i\n", optres_constant_names); - if (optres_constant_names_strings) - printf("optres_constant_names_strings %i\n", optres_constant_names_strings); - if (optres_precache_file) - printf("optres_precache_file %i\n", optres_precache_file); - if (optres_filenames) - printf("optres_filenames %i\n", optres_filenames); - if (optres_assignments) - printf("optres_assignments %i\n", optres_assignments); - if (optres_unreferenced) - printf("optres_unreferenced %i\n", optres_unreferenced); - if (optres_locals) - printf("optres_locals %i\n", optres_locals); - if (optres_function_names) - printf("optres_function_names %i\n", optres_function_names); - if (optres_dupconstdefs) - printf("optres_dupconstdefs %i\n", optres_dupconstdefs); - if (optres_return_only) - printf("optres_return_only %i\n", optres_return_only); - if (optres_compound_jumps) - printf("optres_compound_jumps %i\n", optres_compound_jumps); - // if (optres_comexprremoval) - // printf("optres_comexprremoval %i\n", optres_comexprremoval); - if (optres_stripfunctions) - printf("optres_stripfunctions %i\n", optres_stripfunctions); - if (optres_locals_marshalling) - printf("optres_locals_marshalling %i\n", optres_locals_marshalling); - if (optres_logicops) - printf("optres_logicops %i\n", optres_logicops); + if (optres_shortenifnots) + printf("optres_shortenifnots %i\n", optres_shortenifnots); + if (optres_overlaptemps) + printf("optres_overlaptemps %i\n", optres_overlaptemps); + if (optres_noduplicatestrings) + printf("optres_noduplicatestrings %i\n", optres_noduplicatestrings); + if (optres_constantarithmatic) + printf("optres_constantarithmatic %i\n", optres_constantarithmatic); + if (optres_nonvec_parms) + printf("optres_nonvec_parms %i\n", optres_nonvec_parms); + if (optres_constant_names) + printf("optres_constant_names %i\n", optres_constant_names); + if (optres_constant_names_strings) + printf("optres_constant_names_strings %i\n", optres_constant_names_strings); + if (optres_precache_file) + printf("optres_precache_file %i\n", optres_precache_file); + if (optres_filenames) + printf("optres_filenames %i\n", optres_filenames); + if (optres_assignments) + printf("optres_assignments %i\n", optres_assignments); + if (optres_unreferenced) + printf("optres_unreferenced %i\n", optres_unreferenced); + if (optres_locals) + printf("optres_locals %i\n", optres_locals); + if (optres_function_names) + printf("optres_function_names %i\n", optres_function_names); + if (optres_dupconstdefs) + printf("optres_dupconstdefs %i\n", optres_dupconstdefs); + if (optres_return_only) + printf("optres_return_only %i\n", optres_return_only); + if (optres_compound_jumps) + printf("optres_compound_jumps %i\n", optres_compound_jumps); + // if (optres_comexprremoval) + // printf("optres_comexprremoval %i\n", optres_comexprremoval); + if (optres_stripfunctions) + printf("optres_stripfunctions %i\n", optres_stripfunctions); + if (optres_locals_marshalling) + printf("optres_locals_marshalling %i\n", optres_locals_marshalling); + if (optres_logicops) + printf("optres_logicops %i\n", optres_logicops); - if (optres_test1) - printf("optres_test1 %i\n", optres_test1); - if (optres_test2) - printf("optres_test2 %i\n", optres_test2); - - printf("numtemps %i\n", numtemps); - - printf("%i warnings\n", pr_warning_count); + if (optres_test1) + printf("optres_test1 %i\n", optres_test1); + if (optres_test2) + printf("optres_test2 %i\n", optres_test2); + + printf("numtemps %i\n", numtemps); + } + if (!flag_msvcstyle) + printf("%i warnings\n", pr_warning_count); } qcc_compileactive = false; diff --git a/engine/server/net_preparse.c b/engine/server/net_preparse.c index f9701654..6aa5031f 100644 --- a/engine/server/net_preparse.c +++ b/engine/server/net_preparse.c @@ -201,7 +201,7 @@ void NPP_NQFlush(void) memcpy(&cd, &buffer[multicastpos+sizeofcoord*2], sizeofcoord); org[2] = MSG_FromCoord(cd, sizeofcoord); - SV_MulticastProtExt(org, multicasttype, FULLDIMENSIONMASK, requireextension, 0); + SV_MulticastProtExt(org, multicasttype, pr_global_struct->dimension_send, requireextension, 0); } writedest = NULL; } @@ -1000,7 +1000,7 @@ void NPP_QWFlush(void) qwsize = sv.multicast.cursize; sv.multicast.cursize = 0; - SV_MulticastProtExt(org, multicasttype, FULLDIMENSIONMASK, requireextension, 0); + SV_MulticastProtExt(org, multicasttype, pr_global_struct->dimension_send, requireextension, 0); sv.multicast.cursize = qwsize; } writedest = NULL; diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index c834d72f..f817ecb5 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -160,9 +160,6 @@ char *QC_ProgsNameForEnt(edict_t *ent) return "?"; } - -int pr_edict_size; - void ED_Spawned (struct edict_s *ent, int loading) { #ifdef VM_Q1 @@ -185,7 +182,7 @@ void ED_Spawned (struct edict_s *ent, int loading) pbool ED_CanFree (edict_t *ed) { - if (ed == sv.edicts) + if (ed == (edict_t*)sv.world.edicts) { if (developer.value) { @@ -202,7 +199,7 @@ pbool ED_CanFree (edict_t *ed) *svprogfuncs->pr_trace = 1; return false; } - SV_UnlinkEdict (ed); // unlink from world bsp + World_UnlinkEdict ((wedict_t*)ed); // unlink from world bsp ed->v->model = 0; ed->v->takedamage = 0; @@ -215,7 +212,6 @@ pbool ED_CanFree (edict_t *ed) ed->v->nextthink = 0; ed->v->solid = 0; - ed->v->classname = 0; if (pr_imitatemvdsv.value) @@ -232,6 +228,12 @@ pbool ED_CanFree (edict_t *ed) ed->xv->SendEntity = 0; sv.csqcentversion[ed->entnum] = ed->xv->Version+1; +#ifdef USEODE + World_Physics_RemoveFromEntity(&sv.world, (wedict_t*)ed); + World_Physics_RemoveJointFromEntity(&sv.world, (wedict_t*)ed); +#endif + + return true; } @@ -423,14 +425,14 @@ void Q_SetProgsParms(qboolean forcompiler) svprogparms.gametime = &sv.time; - svprogparms.sv_edicts = &sv.edicts; - svprogparms.sv_num_edicts = &sv.num_edicts; + svprogparms.sv_edicts = (edict_t**)&sv.world.edicts; + svprogparms.sv_num_edicts = &sv.world.num_edicts; svprogparms.useeditor = QCEditor;//void (*useeditor) (char *filename, int line, int nump, char **parms); if (!svprogfuncs) { - svprogfuncs = InitProgs(&svprogparms); + sv.world.progs = svprogfuncs = InitProgs(&svprogparms); } PR_ClearThreads(); PR_fclose_progs(svprogfuncs); @@ -868,17 +870,17 @@ void PR_ApplyCompilation_f (void) PR_Configure(svprogfuncs, -1, MAX_PROGS); PR_RegisterFields(); - PR_InitEnts(svprogfuncs, sv.max_edicts); + PR_InitEnts(svprogfuncs, sv.world.max_edicts); - pr_edict_size=svprogfuncs->load_ents(svprogfuncs, s, 0); + sv.world.edict_size=svprogfuncs->load_ents(svprogfuncs, s, 0); PR_LoadGlabalStruct(); - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; - SV_ClearWorld (); + World_ClearWorld (&sv.world); for (i=0 ; iisfree) continue; - SV_LinkEdict (ent, false); // force retouch even for stationary + World_LinkEdict (&sv.world, (wedict_t*)ent, false); // force retouch even for stationary } svprogfuncs->parms->memfree(s); @@ -1238,7 +1240,7 @@ void Q_InitProgs(void) } prnum = 0; - switch (sv.worldmodel->fromgame) //spawn functions for - spawn funcs still come from the first progs found. + switch (sv.world.worldmodel->fromgame) //spawn functions for - spawn funcs still come from the first progs found. { case fg_quake2: if (COM_FDepthFile("q2bsp.dat", true)!=0x7fffffff) @@ -1376,10 +1378,10 @@ void Q_InitProgs(void) } } - sv.max_edicts = pr_maxedicts.value; - if (sv.max_edicts > MAX_EDICTS) - sv.max_edicts = MAX_EDICTS; - pr_edict_size = PR_InitEnts(svprogfuncs, sv.max_edicts); + sv.world.max_edicts = pr_maxedicts.value; + if (sv.world.max_edicts > MAX_EDICTS) + sv.world.max_edicts = MAX_EDICTS; + sv.world.edict_size = PR_InitEnts(svprogfuncs, sv.world.max_edicts); } qboolean PR_QCChat(char *text, int say_type) @@ -1448,7 +1450,7 @@ qboolean PR_GameCodePacket(char *s) return false; pr_globals = PR_globals(svprogfuncs, PR_CURRENT); - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; // check for packets from connected clients pr_global_struct->self = 0; @@ -1486,7 +1488,7 @@ qboolean PR_KrimzonParseCommand(char *s) { //the QC is expected to send it back to use via a builtin. pr_globals = PR_globals(svprogfuncs, PR_CURRENT); - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player); G_INT(OFS_PARM0) = (int)PR_TempString(svprogfuncs, s); @@ -1515,7 +1517,7 @@ qboolean PR_UserCmd(char *s) { //the QC is expected to send it back to use via a builtin. pr_globals = PR_globals(svprogfuncs, PR_CURRENT); - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player); G_INT(OFS_PARM0) = (int)PR_TempString(svprogfuncs, s); @@ -1526,7 +1528,7 @@ qboolean PR_UserCmd(char *s) #ifdef VM_Q1 if (svs.gametype == GT_Q1QVM) { - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player); Q1QVM_ClientCommand(); return true; //qvm can print something if it wants @@ -1547,7 +1549,7 @@ qboolean PR_UserCmd(char *s) } pr_globals = PR_globals(svprogfuncs, PR_CURRENT); - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player); G_INT(OFS_PARM0) = (int)PR_TempString(svprogfuncs, s); @@ -1584,8 +1586,8 @@ qboolean PR_ConsoleCmd(void) { if (sv_redirected != RD_OBLIVION) { - pr_global_struct->time = sv.physicstime; - pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.edicts); + pr_global_struct->time = sv.world.physicstime; + pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.world.edicts); } PR_ExecuteProgram (svprogfuncs, gfuncs.ConsoleCmd); @@ -1603,7 +1605,7 @@ void PR_ClientUserInfoChanged(char *name, char *oldivalue, char *newvalue) globalvars_t *pr_globals; pr_globals = PR_globals(svprogfuncs, PR_CURRENT); - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player); G_INT(OFS_PARM0) = PR_TempString(svprogfuncs, name); @@ -1621,8 +1623,8 @@ void PR_LocalInfoChanged(char *name, char *oldivalue, char *newvalue) globalvars_t *pr_globals; pr_globals = PR_globals(svprogfuncs, PR_CURRENT); - pr_global_struct->time = sv.physicstime; - pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.edicts); + pr_global_struct->time = sv.world.physicstime; + pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.world.edicts); G_INT(OFS_PARM0) = PR_TempString(svprogfuncs, name); G_INT(OFS_PARM1) = PR_TempString(svprogfuncs, oldivalue); @@ -1786,7 +1788,7 @@ void PF_setorigin (progfuncs_t *prinst, struct globalvars_s *pr_globals) e = G_EDICT(prinst, OFS_PARM0); org = G_VECTOR(OFS_PARM1); VectorCopy (org, e->v->origin); - SV_LinkEdict (e, false); + World_LinkEdict (&sv.world, (wedict_t*)e, false); } @@ -1816,7 +1818,7 @@ void PF_setsize (progfuncs_t *prinst, struct globalvars_s *pr_globals) VectorCopy (min, e->v->mins); VectorCopy (max, e->v->maxs); VectorSubtract (max, min, e->v->size); - SV_LinkEdict (e, false); + World_LinkEdict (&sv.world, (wedict_t*)e, false); } @@ -1860,7 +1862,7 @@ void PF_setmodel_Internal (progfuncs_t *prinst, edict_t *e, char *m) #endif m = sv.strings.model_precache[i] = PR_AddString(prinst, m, 0); if (!strcmp(m + strlen(m) - 4, ".bsp")) - sv.models[i] = Mod_FindName(m); + sv.world.models[i] = Mod_FindName(m); Con_Printf("WARNING: SV_ModelIndex: model %s not precached\n", m); if (sv.state != ss_loading) @@ -1895,7 +1897,7 @@ void PF_setmodel_Internal (progfuncs_t *prinst, edict_t *e, char *m) VectorCopy (mod->mins, e->v->mins); VectorCopy (mod->maxs, e->v->maxs); VectorSubtract (mod->maxs, mod->mins, e->v->size); - SV_LinkEdict (e, false); + World_LinkEdict (&sv.world, (wedict_t*)e, false); } return; @@ -1921,7 +1923,7 @@ void PF_setmodel_Internal (progfuncs_t *prinst, edict_t *e, char *m) //nq dedicated servers load bsps and mdls //qw dedicated servers only load bsps (better) - mod = sv.models[i]; + mod = sv.world.models[i]; if (mod) { mod = Mod_ForName (m, false); @@ -1930,7 +1932,7 @@ void PF_setmodel_Internal (progfuncs_t *prinst, edict_t *e, char *m) VectorCopy (mod->mins, e->v->mins); VectorCopy (mod->maxs, e->v->maxs); VectorSubtract (mod->maxs, mod->mins, e->v->size); - SV_LinkEdict (e, false); + World_LinkEdict (&sv.world, (wedict_t*)e, false); } } else @@ -1946,12 +1948,12 @@ void PF_setmodel_Internal (progfuncs_t *prinst, edict_t *e, char *m) e->v->maxs[1] = e->v->maxs[2] = 16; VectorSubtract (e->v->maxs, e->v->mins, e->v->size); - SV_LinkEdict (e, false); + World_LinkEdict (&sv.world, (wedict_t*)e, false); } } else { - if (sv.models[i]) + if (sv.world.models[i]) { mod = Mod_ForName (m, false); if (mod) @@ -1959,7 +1961,7 @@ void PF_setmodel_Internal (progfuncs_t *prinst, edict_t *e, char *m) VectorCopy (mod->mins, e->v->mins); VectorCopy (mod->maxs, e->v->maxs); VectorSubtract (mod->maxs, mod->mins, e->v->size); - SV_LinkEdict (e, false); + World_LinkEdict (&sv.world, (wedict_t*)e, false); } } //qw was fixed - it never sets the size of an alias model, mostly because it doesn't know it. @@ -1994,7 +1996,7 @@ static void PF_frameforname (progfuncs_t *prinst, struct globalvars_s *pr_global { unsigned int modelindex = G_FLOAT(OFS_PARM0); char *str = PF_VarString(prinst, 1, pr_globals); - model_t *mod = (modelindex>= MAX_MODELS)?NULL:sv.models[modelindex]; + model_t *mod = (modelindex>= MAX_MODELS)?NULL:sv.world.models[modelindex]; if (mod && Mod_FrameForName) G_FLOAT(OFS_RETURN) = Mod_FrameForName(mod, str); @@ -2011,9 +2013,9 @@ static void PF_frameduration (progfuncs_t *prinst, struct globalvars_s *pr_globa G_FLOAT(OFS_RETURN) = 0; else { - mod = sv.models[modelindex]; + mod = sv.world.models[modelindex]; if (!mod) - mod = sv.models[modelindex] = Mod_ForName(sv.strings.model_precache[modelindex], false); + mod = sv.world.models[modelindex] = Mod_ForName(sv.strings.model_precache[modelindex], false); if (mod && Mod_GetFrameDuration) G_FLOAT(OFS_RETURN) = Mod_GetFrameDuration(mod, framenum); @@ -2026,7 +2028,7 @@ static void PF_skinforname (progfuncs_t *prinst, struct globalvars_s *pr_globals #ifndef SERVERONLY unsigned int modelindex = G_FLOAT(OFS_PARM0); char *str = PF_VarString(prinst, 1, pr_globals); - model_t *mod = (modelindex>= MAX_MODELS)?NULL:sv.models[modelindex]; + model_t *mod = (modelindex>= MAX_MODELS)?NULL:sv.world.models[modelindex]; if (mod && Mod_SkinForName) @@ -2616,6 +2618,9 @@ void PF_svtraceline (progfuncs_t *prinst, struct globalvars_s *pr_globals) nomonsters = G_FLOAT(OFS_PARM2); ent = G_EDICT(prinst, OFS_PARM3); + if (sv_antilag.ival == 2) + nomonsters |= MOVE_LAGGED; + if (*svprogfuncs->callargc == 6) { mins = G_VECTOR(OFS_PARM4); @@ -2629,7 +2634,7 @@ void PF_svtraceline (progfuncs_t *prinst, struct globalvars_s *pr_globals) savedhull = ent->xv->hull; ent->xv->hull = 0; - trace = SV_Move (v1, mins, maxs, v2, nomonsters, ent); + trace = World_Move (&sv.world, v1, mins, maxs, v2, nomonsters, (wedict_t*)ent); ent->xv->hull = savedhull; if (trace.startsolid) @@ -2652,7 +2657,7 @@ void PF_svtraceline (progfuncs_t *prinst, struct globalvars_s *pr_globals) if (trace.ent) pr_global_struct->trace_ent = EDICT_TO_PROG(prinst, trace.ent); else - pr_global_struct->trace_ent = EDICT_TO_PROG(prinst, sv.edicts); + pr_global_struct->trace_ent = EDICT_TO_PROG(prinst, sv.world.edicts); } static void PF_traceboxh2 (progfuncs_t *prinst, struct globalvars_s *pr_globals) @@ -2672,7 +2677,7 @@ static void PF_traceboxh2 (progfuncs_t *prinst, struct globalvars_s *pr_globals) savedhull = ent->xv->hull; ent->xv->hull = 0; - trace = SV_Move (v1, mins, maxs, v2, nomonsters, ent); + trace = World_Move (&sv.world, v1, mins, maxs, v2, nomonsters, (wedict_t*)ent); ent->xv->hull = savedhull; if (trace.startsolid) @@ -2692,7 +2697,7 @@ static void PF_traceboxh2 (progfuncs_t *prinst, struct globalvars_s *pr_globals) if (trace.ent) pr_global_struct->trace_ent = EDICT_TO_PROG(prinst, trace.ent); else - pr_global_struct->trace_ent = EDICT_TO_PROG(prinst, sv.edicts); + pr_global_struct->trace_ent = EDICT_TO_PROG(prinst, sv.world.edicts); } static void PF_traceboxdp (progfuncs_t *prinst, struct globalvars_s *pr_globals) @@ -2712,7 +2717,7 @@ static void PF_traceboxdp (progfuncs_t *prinst, struct globalvars_s *pr_globals) savedhull = ent->xv->hull; ent->xv->hull = 0; - trace = SV_Move (v1, mins, maxs, v2, nomonsters, ent); + trace = World_Move (&sv.world, v1, mins, maxs, v2, nomonsters, (wedict_t*)ent); ent->xv->hull = savedhull; if (trace.startsolid) @@ -2735,7 +2740,7 @@ static void PF_traceboxdp (progfuncs_t *prinst, struct globalvars_s *pr_globals) if (trace.ent) pr_global_struct->trace_ent = EDICT_TO_PROG(prinst, trace.ent); else - pr_global_struct->trace_ent = EDICT_TO_PROG(prinst, sv.edicts); + pr_global_struct->trace_ent = EDICT_TO_PROG(prinst, sv.world.edicts); } extern trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore); @@ -2746,7 +2751,7 @@ static void PF_TraceToss (progfuncs_t *prinst, struct globalvars_s *pr_globals) edict_t *ignore; ent = G_EDICT(prinst, OFS_PARM0); - if (ent == sv.edicts) + if (ent == (edict_t*)sv.world.edicts) Con_DPrintf("tracetoss: can not use world entity\n"); ignore = G_EDICT(prinst, OFS_PARM1); @@ -2765,7 +2770,7 @@ static void PF_TraceToss (progfuncs_t *prinst, struct globalvars_s *pr_globals) if (trace.ent) pr_global_struct->trace_ent = EDICT_TO_PROG(prinst, trace.ent); else - pr_global_struct->trace_ent = EDICT_TO_PROG(prinst, sv.edicts); + pr_global_struct->trace_ent = EDICT_TO_PROG(prinst, sv.world.edicts); } /* @@ -2830,8 +2835,8 @@ int PF_newcheckclient (progfuncs_t *prinst, int check) // get the PVS for the entity VectorAdd (ent->v->origin, ent->v->view_ofs, org); - leaf = sv.worldmodel->funcs.LeafnumForPoint(sv.worldmodel, org); - checkpvs = sv.worldmodel->funcs.LeafPVS (sv.worldmodel, leaf, checkpvsbuffer, sizeof(checkpvsbuffer)); + leaf = sv.world.worldmodel->funcs.LeafnumForPoint(sv.world.worldmodel, org); + checkpvs = sv.world.worldmodel->funcs.LeafPVS (sv.world.worldmodel, leaf, checkpvsbuffer, sizeof(checkpvsbuffer)); return i; } @@ -2858,16 +2863,17 @@ int PF_checkclient_Internal (progfuncs_t *prinst) edict_t *ent, *self; int l; vec3_t view; + world_t *w = &sv.world; // find a new check if on a new frame - if (sv.time - sv.lastchecktime >= 0.1) + if (w->physicstime - w->lastchecktime >= 0.1) { - sv.lastcheck = PF_newcheckclient (prinst, sv.lastcheck); - sv.lastchecktime = sv.time; + w->lastcheck = PF_newcheckclient (prinst, w->lastcheck); + w->lastchecktime = w->physicstime; } // return check if it might be visible - ent = EDICT_NUM(prinst, sv.lastcheck); + ent = EDICT_NUM(prinst, w->lastcheck); if (ent->isfree || ent->v->health <= 0) { return 0; @@ -2876,7 +2882,7 @@ int PF_checkclient_Internal (progfuncs_t *prinst) // if current entity can't possibly see the check entity, return 0 self = PROG_TO_EDICT(prinst, pr_global_struct->self); VectorAdd (self->v->origin, self->v->view_ofs, view); - l = sv.worldmodel->funcs.LeafnumForPoint(sv.worldmodel, view)-1; + l = w->worldmodel->funcs.LeafnumForPoint(w->worldmodel, view)-1; if ( (l<0) || !(checkpvs[l>>3] & (1<<(l&7)) ) ) { c_notvis++; @@ -2885,7 +2891,7 @@ c_notvis++; // might be able to see it c_invis++; - return sv.lastcheck; + return w->lastcheck; } void PF_checkclient (progfuncs_t *prinst, struct globalvars_s *pr_globals) @@ -3040,7 +3046,7 @@ void PF_spawnclient (progfuncs_t *prinst, struct globalvars_s *pr_globals) return; } } - RETURN_EDICT(prinst, sv.edicts); + RETURN_EDICT(prinst, sv.world.edicts); } //DP_SV_BOTCLIENT @@ -3085,7 +3091,7 @@ static void PF_cvar (progfuncs_t *prinst, struct globalvars_s *pr_globals) else if (!strcmp(str, "pr_map_builtin")) G_FLOAT(OFS_RETURN) = PR_EnableEBFSBuiltin("map_builtin", 0); else if (!strcmp(str, "halflifebsp")) - G_FLOAT(OFS_RETURN) = sv.worldmodel->fromgame == fg_halflife; + G_FLOAT(OFS_RETURN) = sv.world.worldmodel->fromgame == fg_halflife; else { cvar_t *cv = Cvar_FindVar(str); @@ -3107,11 +3113,12 @@ static void PF_cvar (progfuncs_t *prinst, struct globalvars_s *pr_globals) void PF_sv_getlight (progfuncs_t *prinst, struct globalvars_s *pr_globals) { + /*not shared with client - clients get more lights*/ float *point = G_VECTOR(OFS_PARM0); vec3_t diffuse, ambient, dir; - if (sv.worldmodel && sv.worldmodel->funcs.LightPointValues) + if (sv.world.worldmodel && sv.world.worldmodel->funcs.LightPointValues) { - sv.worldmodel->funcs.LightPointValues(sv.worldmodel, point, diffuse, ambient, dir); + sv.world.worldmodel->funcs.LightPointValues(sv.world.worldmodel, point, diffuse, ambient, dir); VectorMA(ambient, 0.5, diffuse, G_VECTOR(OFS_RETURN)); } else @@ -3140,13 +3147,13 @@ void PF_findradius (progfuncs_t *prinst, struct globalvars_s *pr_globals) vec3_t eorg; int i, j; - chain = (edict_t *)sv.edicts; + chain = (edict_t *)sv.world.edicts; org = G_VECTOR(OFS_PARM0); rad = G_FLOAT(OFS_PARM1); rad = rad*rad; - for (i=1 ; iisfree) @@ -3314,7 +3321,7 @@ int PF_precache_model_Internal (progfuncs_t *prinst, char *s) sv.strings.model_precache[i] = PR_AddString(prinst, s, 0); s = sv.strings.model_precache[i]; if (!strcmp(s + strlen(s) - 4, ".bsp")) - sv.models[i] = Mod_FindName(s); + sv.world.models[i] = Mod_FindName(s); if (sv.state != ss_loading) { @@ -3497,14 +3504,14 @@ void PF_droptofloor (progfuncs_t *prinst, struct globalvars_s *pr_globals) end[2] -= 256; VectorCopy (ent->v->origin, start); - trace = SV_Move (start, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent); + trace = World_Move (&sv.world, start, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, (wedict_t*)ent); if (trace.fraction == 1 || trace.allsolid) G_FLOAT(OFS_RETURN) = 0; else { VectorCopy (trace.endpos, ent->v->origin); - SV_LinkEdict (ent, false); + World_LinkEdict (&sv.world, (wedict_t*)ent, false); ent->v->flags = (int)ent->v->flags | FL_ONGROUND; ent->v->groundentity = EDICT_TO_PROG(prinst, trace.ent); G_FLOAT(OFS_RETURN) = 1; @@ -3674,7 +3681,7 @@ void PF_pointcontents (progfuncs_t *prinst, struct globalvars_s *pr_globals) v = G_VECTOR(OFS_PARM0); // cont = SV_Move(v, vec3_origin, vec3_origin, v, MOVE_NOMONSTERS, NULL).contents; - cont = SV_PointContents (v); + cont = World_PointContents (&sv.world, v); if (cont & FTECONTENTS_SOLID) G_FLOAT(OFS_RETURN) = Q1CONTENTS_SOLID; else if (cont & FTECONTENTS_SKY) @@ -3730,7 +3737,7 @@ void PF_aim (progfuncs_t *prinst, struct globalvars_s *pr_globals) // try sending a trace straight VectorCopy (P_VEC(v_forward), dir); VectorMA (start, 2048, dir, end); - tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent); + tr = World_Move (&sv.world, start, vec3_origin, vec3_origin, end, false, (wedict_t*)ent); if (tr.ent && ((edict_t *)tr.ent)->v->takedamage == DAMAGE_AIM && (!teamplay.value || ent->v->team <=0 || ent->v->team != ((edict_t *)tr.ent)->v->team) ) { @@ -3744,7 +3751,7 @@ void PF_aim (progfuncs_t *prinst, struct globalvars_s *pr_globals) bestdist = sv_aim.value; bestent = NULL; - for (i=1 ; iv->takedamage != DAMAGE_AIM) @@ -3761,7 +3768,7 @@ void PF_aim (progfuncs_t *prinst, struct globalvars_s *pr_globals) dist = DotProduct (dir, P_VEC(v_forward)); if (dist < bestdist) continue; // to far to turn - tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent); + tr = World_Move (&sv.world, start, vec3_origin, vec3_origin, end, false, (wedict_t*)ent); if (tr.ent == check) { // can shoot at this one bestdist = dist; @@ -6079,8 +6086,8 @@ void PF_checkextension (progfuncs_t *prinst, struct globalvars_s *pr_globals) } } - if (ext->enabled) - *ext->enabled = true; + if (ext->queried) + *ext->queried = true; G_FLOAT(OFS_RETURN) = true; Con_DPrintf("Extension %s is supported\n", s); @@ -6453,7 +6460,7 @@ void PF_log(progfuncs_t *prinst, struct globalvars_s *pr_globals) #ifdef Q2BSPS void PF_OpenPortal (progfuncs_t *prinst, struct globalvars_s *pr_globals) { - if (sv.worldmodel->fromgame == fg_quake2) + if (sv.world.worldmodel->fromgame == fg_quake2) { int i, portal = G_FLOAT(OFS_PARM0); int state = G_FLOAT(OFS_PARM1)!=0; @@ -6486,8 +6493,8 @@ static void PF_copyentity (progfuncs_t *prinst, struct globalvars_s *pr_globals) in = G_EDICT(prinst, OFS_PARM0); out = G_EDICT(prinst, OFS_PARM1); - memcpy(out->v, in->v, pr_edict_size); - SV_LinkEdict(out, false); + memcpy(out->v, in->v, sv.world.edict_size); + World_LinkEdict(&sv.world, (wedict_t*)out, false); } @@ -8191,7 +8198,7 @@ typedef struct zymbone_s int SV_TagForName(int modelindex, char *tagname) { #if 1 - model_t *model = sv.models[modelindex]; + model_t *model = sv.world.models[modelindex]; if (!model) model = Mod_ForName(sv.strings.model_precache[modelindex], false); if (!model) @@ -8257,18 +8264,18 @@ void PF_setattachment(progfuncs_t *prinst, struct globalvars_s *pr_globals) tagidx = 0; - if (tagentity != sv.edicts && tagname && tagname[0]) + if (tagentity != (edict_t*)sv.world.edicts && tagname && tagname[0]) { modelindex = (int)tagentity->v->modelindex; if (modelindex > 0 && modelindex < MAX_MODELS) { - if (!sv.models[modelindex]) - sv.models[modelindex] = Mod_ForName(sv.strings.model_precache[modelindex], false); - if (sv.models[modelindex]) + if (!sv.world.models[modelindex]) + sv.world.models[modelindex] = Mod_ForName(sv.strings.model_precache[modelindex], false); + if (sv.world.models[modelindex]) { tagidx = SV_TagForName(modelindex, tagname); if (tagidx == 0) - Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", NUM_FOR_EDICT(prinst, e), NUM_FOR_EDICT(prinst, tagentity), tagname, tagname, NUM_FOR_EDICT(prinst, tagentity), sv.models[modelindex]->name); + Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", NUM_FOR_EDICT(prinst, e), NUM_FOR_EDICT(prinst, tagentity), tagname, tagname, NUM_FOR_EDICT(prinst, tagentity), sv.world.models[modelindex]->name); } else Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): Couldn't load model %s\n", NUM_FOR_EDICT(prinst, e), NUM_FOR_EDICT(prinst, tagentity), tagname, sv.modelname[modelindex]); @@ -8301,7 +8308,7 @@ void PF_gettagindex(progfuncs_t *prinst, struct globalvars_s *pr_globals) { tagidx = SV_TagForName(modelindex, tagname); if (tagidx == 0) - Con_DPrintf("PF_gettagindex(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", NUM_FOR_EDICT(prinst, e), NUM_FOR_EDICT(prinst, e), tagname, tagname, NUM_FOR_EDICT(prinst, e), sv.models[modelindex]->name); + Con_DPrintf("PF_gettagindex(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", NUM_FOR_EDICT(prinst, e), NUM_FOR_EDICT(prinst, e), tagname, tagname, NUM_FOR_EDICT(prinst, e), sv.world.models[modelindex]->name); } else Con_DPrintf("PF_gettagindex(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i but it has no model\n", NUM_FOR_EDICT(prinst, e), NUM_FOR_EDICT(prinst, e), tagname, tagname, NUM_FOR_EDICT(prinst, e)); @@ -8330,7 +8337,7 @@ void PF_sv_gettaginfo(progfuncs_t *prinst, struct globalvars_s *pr_globals) float result[12]; edict_t *ent = G_EDICT(prinst, OFS_PARM0); int tagnum = G_FLOAT(OFS_PARM1); - model_t *model = sv.models[(int)ent->v->modelindex]; + model_t *model = sv.world.models[(int)ent->v->modelindex]; float *origin = G_VECTOR(OFS_RETURN); float *axis[3]; @@ -8429,7 +8436,7 @@ void PF_runclientphys(progfuncs_t *prinst, struct globalvars_s *pr_globals) pmove.hullnum = SV_HullNumForPlayer(ent->xv->hull, ent->v->mins, ent->v->maxs); pmove.numphysent = 1; - pmove.physents[0].model = sv.worldmodel; + pmove.physents[0].model = sv.world.worldmodel; for (i=0 ; i<3 ; i++) { @@ -8437,9 +8444,10 @@ void PF_runclientphys(progfuncs_t *prinst, struct globalvars_s *pr_globals) pmove_mins[i] = pmove.origin[i] - 256; pmove_maxs[i] = pmove.origin[i] + 256; } - AddLinksToPmove(ent, sv_areanodes); + AddLinksToPmove(ent, sv.world.areanodes); // AddAllEntsToPmove(); + SV_PreRunCmd(); while(msecs) //break up longer commands { @@ -8448,61 +8456,62 @@ void PF_runclientphys(progfuncs_t *prinst, struct globalvars_s *pr_globals) pmove.cmd.msec = 50; msecs -= pmove.cmd.msec; PM_PlayerMove(1); - } - ent->xv->pmove_flags = 0; - ent->xv->pmove_flags += ((int)pmove.jump_held?PMF_JUMP_HELD:0); - ent->xv->pmove_flags += ((int)pmove.onladder?PMF_LADDER:0); - ent->v->teleport_time = pmove.waterjumptime; - VectorCopy(pmove.origin, ent->v->origin); - VectorCopy(pmove.velocity, ent->v->velocity); + ent->xv->pmove_flags = 0; + ent->xv->pmove_flags += ((int)pmove.jump_held?PMF_JUMP_HELD:0); + ent->xv->pmove_flags += ((int)pmove.onladder?PMF_LADDER:0); + ent->v->teleport_time = pmove.waterjumptime; + VectorCopy(pmove.origin, ent->v->origin); + VectorCopy(pmove.velocity, ent->v->velocity); - ent->v->waterlevel = pmove.waterlevel; + ent->v->waterlevel = pmove.waterlevel; - if (pmove.watertype & FTECONTENTS_SOLID) - ent->v->watertype = Q1CONTENTS_SOLID; - else if (pmove.watertype & FTECONTENTS_SKY) - ent->v->watertype = Q1CONTENTS_SKY; - else if (pmove.watertype & FTECONTENTS_LAVA) - ent->v->watertype = Q1CONTENTS_LAVA; - else if (pmove.watertype & FTECONTENTS_SLIME) - ent->v->watertype = Q1CONTENTS_SLIME; - else if (pmove.watertype & FTECONTENTS_WATER) - ent->v->watertype = Q1CONTENTS_WATER; - else - ent->v->watertype = Q1CONTENTS_EMPTY; - - if (pmove.onground) - { - ent->v->flags = (int)sv_player->v->flags | FL_ONGROUND; - ent->v->groundentity = EDICT_TO_PROG(svprogfuncs, EDICT_NUM(svprogfuncs, pmove.physents[pmove.groundent].info)); - } - else - ent->v->flags = (int)ent->v->flags & ~FL_ONGROUND; - - - SV_LinkEdict(ent, true); - for (i=0 ; iv->touch || (playertouch[n/8]&(1<<(n%8)))) - continue; - - pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, touched); - pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, ent); - pr_global_struct->time = sv.time; -#ifdef VM_Q1 - if (svs.gametype == GT_Q1QVM) - Q1QVM_Touch(); + if (pmove.watertype & FTECONTENTS_SOLID) + ent->v->watertype = Q1CONTENTS_SOLID; + else if (pmove.watertype & FTECONTENTS_SKY) + ent->v->watertype = Q1CONTENTS_SKY; + else if (pmove.watertype & FTECONTENTS_LAVA) + ent->v->watertype = Q1CONTENTS_LAVA; + else if (pmove.watertype & FTECONTENTS_SLIME) + ent->v->watertype = Q1CONTENTS_SLIME; + else if (pmove.watertype & FTECONTENTS_WATER) + ent->v->watertype = Q1CONTENTS_WATER; else -#endif - PR_ExecuteProgram (svprogfuncs, touched->v->touch); - playertouch[n/8] |= 1 << (n%8); + ent->v->watertype = Q1CONTENTS_EMPTY; + + if (pmove.onground) + { + ent->v->flags = (int)sv_player->v->flags | FL_ONGROUND; + ent->v->groundentity = EDICT_TO_PROG(svprogfuncs, EDICT_NUM(svprogfuncs, pmove.physents[pmove.groundent].info)); + } + else + ent->v->flags = (int)ent->v->flags & ~FL_ONGROUND; + + + + World_LinkEdict(&sv.world, (wedict_t*)ent, true); + for (i=0 ; iv->touch || (playertouch[n/8]&(1<<(n%8)))) + continue; + + pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, touched); + pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, ent); + pr_global_struct->time = sv.time; + #ifdef VM_Q1 + if (svs.gametype == GT_Q1QVM) + Q1QVM_Touch(); + else + #endif + PR_ExecuteProgram (svprogfuncs, touched->v->touch); + playertouch[n/8] |= 1 << (n%8); + } } } @@ -8540,7 +8549,7 @@ qboolean SV_RunFullQCMovement(client_t *client, usercmd_t *ucmd) sv_player->xv->button6 = ((ucmd->buttons >> 5) & 1); sv_player->xv->button7 = ((ucmd->buttons >> 6) & 1); sv_player->xv->button8 = ((ucmd->buttons >> 7) & 1); - if (ucmd->impulse && SV_FiltureImpulse(ucmd->impulse, host_client->trustlevel)) + if (ucmd->impulse && SV_FilterImpulse(ucmd->impulse, host_client->trustlevel)) sv_player->v->impulse = ucmd->impulse; if (host_client->iscuffed) @@ -8620,7 +8629,7 @@ void PF_getsurfacenumpoints(progfuncs_t *prinst, struct globalvars_s *pr_globals modelindex = ent->v->modelindex; if (modelindex > 0 && modelindex < MAX_MODELS) - model = sv.models[(int)ent->v->modelindex]; + model = sv.world.models[(int)ent->v->modelindex]; else model = NULL; @@ -8643,7 +8652,7 @@ void PF_getsurfacepoint(progfuncs_t *prinst, struct globalvars_s *pr_globals) modelindex = ent->v->modelindex; if (modelindex > 0 && modelindex < MAX_MODELS) - model = sv.models[(int)ent->v->modelindex]; + model = sv.world.models[(int)ent->v->modelindex]; else model = NULL; @@ -8674,7 +8683,7 @@ void PF_getsurfacenormal(progfuncs_t *prinst, struct globalvars_s *pr_globals) modelindex = ent->v->modelindex; if (modelindex > 0 && modelindex < MAX_MODELS) - model = sv.models[(int)ent->v->modelindex]; + model = sv.world.models[(int)ent->v->modelindex]; else model = NULL; @@ -8707,7 +8716,7 @@ void PF_getsurfacetexture(progfuncs_t *prinst, struct globalvars_s *pr_globals) modelindex = ent->v->modelindex; if (modelindex > 0 && modelindex < MAX_MODELS) - model = sv.models[(int)ent->v->modelindex]; + model = sv.world.models[(int)ent->v->modelindex]; else model = NULL; @@ -8745,7 +8754,7 @@ void PF_getsurfacenearpoint(progfuncs_t *prinst, struct globalvars_s *pr_globals modelindex = ent->v->modelindex; if (modelindex > 0 && modelindex < MAX_MODELS) - model = sv.models[(int)ent->v->modelindex]; + model = sv.world.models[(int)ent->v->modelindex]; else model = NULL; @@ -8818,9 +8827,9 @@ void PF_checkpvs(progfuncs_t *prinst, struct globalvars_s *pr_globals) //FIXME: Make all alternatives of FatPVS not recalulate the pvs. //and yeah, this is overkill what with the whole fat thing and all. - sv.worldmodel->funcs.FatPVS(sv.worldmodel, viewpos, qcpvs, sizeof(qcpvs), false); + sv.world.worldmodel->funcs.FatPVS(sv.world.worldmodel, viewpos, qcpvs, sizeof(qcpvs), false); - G_FLOAT(OFS_RETURN) = sv.worldmodel->funcs.EdictInFatPVS(sv.worldmodel, ent, qcpvs); + G_FLOAT(OFS_RETURN) = sv.world.worldmodel->funcs.EdictInFatPVS(sv.world.worldmodel, (wedict_t*)ent, qcpvs); } //entity(string match [, float matchnum]) matchclient = #241; @@ -9551,8 +9560,8 @@ void PR_ResetBuiltins(progstype_t type) //fix all nulls to PF_FIXME and add any for (i = 0; i < QSG_Extensions_count; i++) { - if (QSG_Extensions[i].enabled) - *QSG_Extensions[i].enabled = false; + if (QSG_Extensions[i].queried) + *QSG_Extensions[i].queried = false; } if (type == PROG_QW && pr_imitatemvdsv.value>0) //pretend to be mvdsv for a bit. @@ -9683,178 +9692,39 @@ int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]); void PR_RegisterFields(void) //it's just easier to do it this way. { -#define fieldfloat(name) PR_RegisterFieldVar(svprogfuncs, ev_float, #name, (int)&((stdentvars_t*)0)->name, -1) -#define fieldvector(name) PR_RegisterFieldVar(svprogfuncs, ev_vector, #name, (int)&((stdentvars_t*)0)->name, -1) -#define fieldentity(name) PR_RegisterFieldVar(svprogfuncs, ev_entity, #name, (int)&((stdentvars_t*)0)->name, -1) -#define fieldstring(name) PR_RegisterFieldVar(svprogfuncs, ev_string, #name, (int)&((stdentvars_t*)0)->name, -1) -#define fieldfunction(name) PR_RegisterFieldVar(svprogfuncs, ev_function, #name, (int)&((stdentvars_t*)0)->name, -1) - +#define comfieldfloat(ssqcname,sharedname,csqcname) PR_RegisterFieldVar(svprogfuncs, ev_float, #ssqcname, (int)&((stdentvars_t*)0)->ssqcname, -1) +#define comfieldvector(ssqcname,sharedname,csqcname) PR_RegisterFieldVar(svprogfuncs, ev_vector, #ssqcname, (int)&((stdentvars_t*)0)->ssqcname, -1) +#define comfieldentity(ssqcname,sharedname,csqcname) PR_RegisterFieldVar(svprogfuncs, ev_entity, #ssqcname, (int)&((stdentvars_t*)0)->ssqcname, -1) +#define comfieldstring(ssqcname,sharedname,csqcname) PR_RegisterFieldVar(svprogfuncs, ev_string, #ssqcname, (int)&((stdentvars_t*)0)->ssqcname, -1) +#define comfieldfunction(ssqcname,sharedname,csqcname) PR_RegisterFieldVar(svprogfuncs, ev_function, #ssqcname, (int)&((stdentvars_t*)0)->ssqcname, -1) +comqcfields +#undef comfieldfloat +#undef comfieldvector +#undef comfieldentity +#undef comfieldstring +#undef comfieldfunction #ifdef VM_Q1 -#define fieldxfloat(name) PR_RegisterFieldVar(svprogfuncs, ev_float, #name, sizeof(stdentvars_t) + (int)&((extentvars_t*)0)->name, -1) -#define fieldxvector(name) PR_RegisterFieldVar(svprogfuncs, ev_vector, #name, sizeof(stdentvars_t) + (int)&((extentvars_t*)0)->name, -1) -#define fieldxentity(name) PR_RegisterFieldVar(svprogfuncs, ev_entity, #name, sizeof(stdentvars_t) + (int)&((extentvars_t*)0)->name, -1) -#define fieldxstring(name) PR_RegisterFieldVar(svprogfuncs, ev_string, #name, sizeof(stdentvars_t) + (int)&((extentvars_t*)0)->name, -1) -#define fieldxfunction(name) PR_RegisterFieldVar(svprogfuncs, ev_function, #name, sizeof(stdentvars_t) + (int)&((extentvars_t*)0)->name, -1) +#define comfieldfloat(name) PR_RegisterFieldVar(svprogfuncs, ev_float, #name, sizeof(stdentvars_t) + (int)&((extentvars_t*)0)->name, -1) +#define comfieldvector(name) PR_RegisterFieldVar(svprogfuncs, ev_vector, #name, sizeof(stdentvars_t) + (int)&((extentvars_t*)0)->name, -1) +#define comfieldentity(name) PR_RegisterFieldVar(svprogfuncs, ev_entity, #name, sizeof(stdentvars_t) + (int)&((extentvars_t*)0)->name, -1) +#define comfieldstring(name) PR_RegisterFieldVar(svprogfuncs, ev_string, #name, sizeof(stdentvars_t) + (int)&((extentvars_t*)0)->name, -1) +#define comfieldfunction(name) PR_RegisterFieldVar(svprogfuncs, ev_function, #name, sizeof(stdentvars_t) + (int)&((extentvars_t*)0)->name, -1) #else -#define fieldxfloat fieldfloat -#define fieldxvector fieldvector -#define fieldxentity fieldentity -#define fieldxstring fieldstring -#define fieldxfunction fieldfunction +#define comfieldfloat(ssqcname) PR_RegisterFieldVar(svprogfuncs, ev_float, #ssqcname, (int)&((stdentvars_t*)0)->ssqcname, -1) +#define comfieldvector(ssqcname) PR_RegisterFieldVar(svprogfuncs, ev_vector, #ssqcname, (int)&((stdentvars_t*)0)->ssqcname, -1) +#define comfieldentity(ssqcname) PR_RegisterFieldVar(svprogfuncs, ev_entity, #ssqcname, (int)&((stdentvars_t*)0)->ssqcname, -1) +#define comfieldstring(ssqcname) PR_RegisterFieldVar(svprogfuncs, ev_string, #ssqcname, (int)&((stdentvars_t*)0)->ssqcname, -1) +#define comfieldfunction(ssqcname) PR_RegisterFieldVar(svprogfuncs, ev_function, #ssqcname, (int)&((stdentvars_t*)0)->ssqcname, -1) #endif - fieldfloat(modelindex); - fieldvector(absmin); - fieldvector(absmax); - fieldfloat(ltime); - fieldfloat(lastruntime); - fieldfloat(movetype); - fieldfloat(solid); - fieldvector(origin); - fieldvector(oldorigin); - fieldvector(velocity); - fieldvector(angles); - fieldvector(avelocity); - fieldstring(classname); - fieldstring(model); - fieldfloat(frame); - fieldfloat(skin); - fieldfloat(effects); - fieldvector(mins); - fieldvector(maxs); - fieldvector(size); - fieldfunction(touch); - fieldfunction(use); - fieldfunction(think); - fieldfunction(blocked); - fieldfloat(nextthink); - fieldentity(groundentity); - fieldfloat(health); - fieldfloat(frags); - fieldfloat(weapon); - fieldstring(weaponmodel); - fieldfloat(weaponframe); - fieldfloat(currentammo); - fieldfloat(ammo_shells); - fieldfloat(ammo_nails); - fieldfloat(ammo_rockets); - fieldfloat(ammo_cells); - fieldfloat(items); - fieldfloat(takedamage); - fieldentity(chain); - fieldfloat(deadflag); - fieldvector(view_ofs); - fieldfloat(button0); - fieldfloat(button1); - fieldfloat(button2); - fieldfloat(impulse); - fieldfloat(fixangle); - fieldvector(v_angle); - fieldstring(netname); - fieldentity(enemy); - fieldfloat(flags); - fieldfloat(colormap); - fieldfloat(team); - fieldfloat(max_health); - fieldfloat(teleport_time); - fieldfloat(armortype); - fieldfloat(armorvalue); - fieldfloat(waterlevel); - fieldfloat(watertype); - fieldfloat(ideal_yaw); - fieldfloat(yaw_speed); - fieldentity(aiment); - fieldentity(goalentity); - fieldfloat(spawnflags); - fieldstring(target); - fieldstring(targetname); - fieldfloat(dmg_take); - fieldfloat(dmg_save); - fieldentity(dmg_inflictor); - fieldentity(owner); - fieldvector(movedir); - fieldfloat(sounds); - fieldstring(noise); - fieldstring(noise1); - fieldstring(noise2); - fieldstring(noise3); +comextqcfields +svextqcfields -//the rest are extras. (not in header) - fieldxfloat(button3); - fieldxfloat(button4); - fieldxfloat(button5); - fieldxfloat(button6); - fieldxfloat(button7); - fieldxfloat(button8); - fieldxfloat(gravity); //standard extension - fieldxfloat(maxspeed); //standard extension - fieldxfloat(items2); //standard nq - fieldxvector(punchangle);//standard nq - fieldxfloat(scale); - fieldxfloat(alpha); - fieldxfloat(fatness); - fieldxentity(view2); - fieldxvector(movement); - fieldxfloat(pmove_flags); - fieldxfloat(vw_index); - - //dp extra fields - fieldxentity(nodrawtoclient); - fieldxentity(drawonlytoclient); - fieldxentity(viewmodelforclient); - fieldxentity(exteriormodeltoclient); - - fieldxfloat(viewzoom); - - fieldxentity(tag_entity); - fieldxfloat(tag_index); - - fieldxfloat(glow_size); - fieldxfloat(glow_color); - fieldxfloat(glow_trail); - - fieldxvector(colormod); - -// if (progstype == PROG_H2) - { - fieldxvector(color); - } - fieldxfloat(light_lev); - fieldxfloat(style); - fieldxfloat(pflags); - - fieldxfloat(clientcolors); - -//hexen 2 stuff - fieldxfloat(playerclass); - fieldxfloat(hull); - fieldxfloat(hasted); - - fieldxfloat(light_level); - fieldxfloat(abslight); - fieldxfloat(drawflags); - fieldxentity(movechain); - fieldxfunction(chainmoved); - - //QSG_DIMENSION_PLANES - fieldxfloat(dimension_see); - fieldxfloat(dimension_seen); - fieldxfloat(dimension_ghost); - fieldxfloat(dimension_ghost_alpha); - fieldxfloat(dimension_solid); - fieldxfloat(dimension_hit); - - - // EXT_CSQC - fieldxfunction(SendEntity); - fieldxfloat(SendFlags); - fieldxfloat(Version); - fieldxfloat(pvsflags); - - // FTE_ENT_UNIQUESPAWNID - fieldxfloat(uniquespawnid); - - fieldxfunction(customizeentityforclient); +#undef comfieldfloat +#undef comfieldvector +#undef comfieldentity +#undef comfieldstring +#undef comfieldfunction //Tell the qc library to split the entity fields each side. //the fields above become < 0, the remaining fields specified by the qc stay where the mod specified, as far as possible (with addons at least). diff --git a/engine/server/pr_q1qvm.c b/engine/server/pr_q1qvm.c index 2500c890..d6f442ad 100755 --- a/engine/server/pr_q1qvm.c +++ b/engine/server/pr_q1qvm.c @@ -23,6 +23,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef VM_Q1 +#include "pr_common.h" + #define GAME_API_VERSION 13 #define MAX_Q1QVM_EDICTS 768 //according to ktx at api version 12 (fte's protocols go to 2048) @@ -344,14 +346,14 @@ static edict_t *Q1QVMPF_EdictNum(progfuncs_t *pf, unsigned int num) { edict_t *e; - if (/*num < 0 ||*/ num >= sv.max_edicts) + if (/*num < 0 ||*/ num >= sv.world.max_edicts) return NULL; e = q1qvmedicts[num]; if (!e) { e = q1qvmedicts[num] = Z_TagMalloc(sizeof(edict_t)+sizeof(extentvars_t), VMFSID_Q1QVM); - e->v = (stdentvars_t*)((char*)evars + (num * pr_edict_size) + WASTED_EDICT_T_SIZE); + e->v = (stdentvars_t*)((char*)evars + (num * sv.world.edict_size) + WASTED_EDICT_T_SIZE); e->xv = (extentvars_t*)(e+1); e->entnum = num; } @@ -365,13 +367,13 @@ static unsigned int Q1QVMPF_NumForEdict(progfuncs_t *pf, edict_t *e) static int Q1QVMPF_EdictToProgs(progfuncs_t *pf, edict_t *e) { - return e->entnum*pr_edict_size; + return e->entnum*sv.world.edict_size; } static edict_t *Q1QVMPF_ProgsToEdict(progfuncs_t *pf, int num) { - if (num % pr_edict_size) + if (num % sv.world.edict_size) Con_Printf("Edict To Progs with remainder\n"); - num /= pr_edict_size; + num /= sv.world.edict_size; return Q1QVMPF_EdictNum(pf, num); } @@ -380,7 +382,7 @@ void Q1QVMED_ClearEdict (edict_t *e, qboolean wipe) { int num = e->entnum; if (wipe) - memset (e->v, 0, pr_edict_size - WASTED_EDICT_T_SIZE); + memset (e->v, 0, sv.world.edict_size - WASTED_EDICT_T_SIZE); e->isfree = false; e->entnum = num; } @@ -397,7 +399,7 @@ static edict_t *Q1QVMPF_EntAlloc(progfuncs_t *pf) { int i; edict_t *e; - for ( i=0 ; i= sv.max_edicts-1) //try again, but use timed out ents. + if (i >= sv.world.max_edicts-1) //try again, but use timed out ents. { - for ( i=0 ; i= sv.max_edicts-1) + if (i >= sv.world.max_edicts-1) { Sys_Error ("ED_Alloc: no free edicts"); } } - sv.num_edicts++; + sv.world.num_edicts++; e = (edict_t*)EDICT_NUM(pf, i); // new ents come ready wiped @@ -449,7 +451,7 @@ static int Q1QVMPF_LoadEnts(progfuncs_t *pf, char *mapstring, float spawnflags) q1qvmentstring = mapstring; VM_Call(q1qvm, GAME_LOADENTS); q1qvmentstring = NULL; - return pr_edict_size; + return sv.world.edict_size; } static eval_t *Q1QVMPF_GetEdictFieldValue(progfuncs_t *pf, edict_t *e, char *fieldname, evalc_t *cache) @@ -481,44 +483,6 @@ static char *Q1QVMPF_StringToNative(progfuncs_t *prinst, string_t str) return (char*)VM_MemoryBase(q1qvm) + str; } -//FIXME: move these to a header -void PF_WriteByte (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_WriteChar (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_WriteShort (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_WriteLong (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_WriteAngle (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_WriteCoord (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_WriteFloat (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_WriteString (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_WriteEntity (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_multicast (progfuncs_t *prinst, struct globalvars_s *pr_globals); - -void PF_svtraceline (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_changelevel (progfuncs_t *prinst, struct globalvars_s *pr_globals); - -void PF_cvar_set (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_cvar_setf (progfuncs_t *prinst, struct globalvars_s *pr_globals); - -void PF_applylightstyle(int style, char *val, int col); -void PF_ambientsound_Internal (float *pos, char *samp, float vol, float attenuation); - -void PF_makestatic (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_logfrag (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_centerprint (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_ExecuteCommand (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_setspawnparms (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_walkmove (progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_ForceInfoKey(progfuncs_t *prinst, struct globalvars_s *pr_globals); -void PF_precache_vwep_model(progfuncs_t *prinst, struct globalvars_s *pr_globals); - - -int PF_checkclient_Internal (progfuncs_t *prinst); -void PF_precache_sound_Internal (progfuncs_t *prinst, char *s); -void PF_precache_model_Internal (progfuncs_t *prinst, char *s); -void PF_setmodel_Internal (progfuncs_t *prinst, edict_t *e, char *m); -char *PF_infokey_Internal (int entnum, char *value); -void PF_centerprint_Internal (int entnum, char *s); - static int WrapQCBuiltin(builtin_t func, void *offset, quintptr_t mask, const qintptr_t *arg, char *argtypes) { globalvars_t gv; @@ -594,7 +558,7 @@ static qintptr_t syscallhandle (void *offset, quintptr_t mask, qintptr_t fn, con return Q1QVMPF_EntAlloc(svprogfuncs)->entnum; case G_REMOVE_ENT: - if (arg[0] >= sv.max_edicts) + if (arg[0] >= sv.world.max_edicts) return false; Q1QVMPF_EntRemove(svprogfuncs, q1qvmedicts[arg[0]]); return true; @@ -620,7 +584,7 @@ static qintptr_t syscallhandle (void *offset, quintptr_t mask, qintptr_t fn, con e->v->origin[0] = VM_FLOAT(arg[1]); e->v->origin[1] = VM_FLOAT(arg[2]); e->v->origin[2] = VM_FLOAT(arg[3]); - SV_LinkEdict (e, false); + World_LinkEdict (&sv.world, (wedict_t*)e, false); return true; } break; @@ -640,7 +604,7 @@ static qintptr_t syscallhandle (void *offset, quintptr_t mask, qintptr_t fn, con e->v->maxs[2] = VM_FLOAT(arg[6]); VectorSubtract (e->v->maxs, e->v->mins, e->v->size); - SV_LinkEdict (e, false); + World_LinkEdict (&sv.world, (wedict_t*)e, false); return true; } case G_SETMODEL: @@ -737,20 +701,20 @@ static qintptr_t syscallhandle (void *offset, quintptr_t mask, qintptr_t fn, con case G_FINDRADIUS: { - int start = ((char*)VM_POINTER(arg[0]) - (char*)evars) / pr_edict_size; + int start = ((char*)VM_POINTER(arg[0]) - (char*)evars) / sv.world.edict_size; edict_t *ed; vec3_t diff; float *org = VM_POINTER(arg[1]); float rad = VM_FLOAT(arg[2]); rad *= rad; - for(start++; start < sv.num_edicts; start++) + for(start++; start < sv.world.num_edicts; start++) { ed = EDICT_NUM(svprogfuncs, start); if (ed->isfree) continue; VectorSubtract(ed->v->origin, org, diff); if (rad > DotProduct(diff, diff)) - return (qintptr_t)(vevars + start*pr_edict_size); + return (qintptr_t)(vevars + start*sv.world.edict_size); } return 0; } @@ -779,14 +743,14 @@ static qintptr_t syscallhandle (void *offset, quintptr_t mask, qintptr_t fn, con end[2] -= 256; VectorCopy (ent->v->origin, start); - trace = SV_Move (start, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent); + trace = World_Move (&sv.world, start, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, (wedict_t*)ent); if (trace.fraction == 1 || trace.allsolid) return false; else { VectorCopy (trace.endpos, ent->v->origin); - SV_LinkEdict (ent, false); + World_LinkEdict (&sv.world, (wedict_t*)ent, false); ent->v->flags = (int)ent->v->flags | FL_ONGROUND; ent->v->groundentity = EDICT_TO_PROG(svprogfuncs, trace.ent); return true; @@ -803,7 +767,7 @@ static qintptr_t syscallhandle (void *offset, quintptr_t mask, qintptr_t fn, con v[0] = VM_FLOAT(arg[0]); v[1] = VM_FLOAT(arg[1]); v[2] = VM_FLOAT(arg[2]); - return sv.worldmodel->funcs.PointContents(sv.worldmodel, v); + return sv.world.worldmodel->funcs.PointContents(sv.world.worldmodel, v); } break; @@ -816,7 +780,7 @@ static qintptr_t syscallhandle (void *offset, quintptr_t mask, qintptr_t fn, con while (1) { i++; - if (i >= sv.num_edicts) + if (i >= sv.world.num_edicts) { return 0; } @@ -1062,11 +1026,11 @@ static qintptr_t syscallhandle (void *offset, quintptr_t mask, qintptr_t fn, con int ofs = VM_LONG(arg[1]) - WASTED_EDICT_T_SIZE; char *match = VM_POINTER(arg[2]); char *field; - int first = e?((char*)e - (char*)evars)/pr_edict_size:0; + int first = e?((char*)e - (char*)evars)/sv.world.edict_size:0; int i; if (!match) match = ""; - for (i = first+1; i < sv.num_edicts; i++) + for (i = first+1; i < sv.world.num_edicts; i++) { e = q1qvmedicts[i]; field = VM_POINTER(*((string_t*)e->v + ofs/4)); @@ -1217,11 +1181,11 @@ Con_DPrintf("PF_readcmd: %s\n%s", s, output); case G_NEXTCLIENT: { - unsigned int start = ((char*)VM_POINTER(arg[0]) - (char*)evars) / pr_edict_size; + unsigned int start = ((char*)VM_POINTER(arg[0]) - (char*)evars) / sv.world.edict_size; while (start < sv.allocated_client_slots) { if (svs.clients[start].state == cs_spawned) - return (qintptr_t)(vevars + (start+1) * pr_edict_size); + return (qintptr_t)(vevars + (start+1) * sv.world.edict_size); start++; } return 0; @@ -1312,7 +1276,7 @@ void Q1QVM_Shutdown(void) q1qvm = NULL; VM_fcloseall(VMFSID_Q1QVM); if (svprogfuncs == &q1qvmprogfuncs) - svprogfuncs = NULL; + sv.world.progs = svprogfuncs = NULL; Z_FreeTags(VMFSID_Q1QVM); } @@ -1352,9 +1316,9 @@ qboolean PR_LoadQ1QVM(void) q1qvmprogfuncs.StringToProgs = Q1QVMPF_StringToProgs; q1qvmprogfuncs.StringToNative = Q1QVMPF_StringToNative; - sv.num_edicts = 0; //we're not ready for most of the builtins yet - sv.max_edicts = 0; //so clear these out, just in case - pr_edict_size = 0; //if we get a division by zero, then at least its a safe crash + sv.world.num_edicts = 0; //we're not ready for most of the builtins yet + sv.world.max_edicts = 0; //so clear these out, just in case + sv.world.edict_size = 0; //if we get a division by zero, then at least its a safe crash memset(q1qvmedicts, 0, sizeof(q1qvmedicts)); @@ -1385,14 +1349,14 @@ qboolean PR_LoadQ1QVM(void) gd = (gameDataN_t*)((char*)VM_MemoryBase(q1qvm) + ret); //qvm is 32bit } - pr_edict_size = gd->sizeofent; + sv.world.edict_size = gd->sizeofent; vevars = (qintptr_t)gd->ents; evars = ((char*)VM_MemoryBase(q1qvm) + vevars); //FIXME: range check this pointer //FIXME: range check the globals pointer - sv.num_edicts = 1; - sv.max_edicts = sizeof(q1qvmedicts)/sizeof(q1qvmedicts[0]); + sv.world.num_edicts = 1; + sv.world.max_edicts = sizeof(q1qvmedicts)/sizeof(q1qvmedicts[0]); //WARNING: global is not remapped yet... //This code is written evilly, but works well enough @@ -1453,7 +1417,7 @@ qboolean PR_LoadQ1QVM(void) spawnparamglobals[i] = NULL; - sv.edicts = EDICT_NUM(svprogfuncs, 0); + sv.world.edicts = (wedict_t*)EDICT_NUM(svprogfuncs, 0); return true; } @@ -1470,12 +1434,12 @@ void Q1QVM_ClientConnect(client_t *cl) strcpy(cl->name, cl->namebuf); } // call the spawn function - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, cl->edict); VM_Call(q1qvm, GAME_CLIENT_CONNECT, cl->spectator); // actually spawn the player - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, cl->edict); VM_Call(q1qvm, GAME_PUT_CLIENT_IN_SERVER, cl->spectator); } @@ -1489,7 +1453,7 @@ qboolean Q1QVM_GameConsoleCommand(void) //FIXME: if an rcon command from someone on the server, mvdsv sets self to match the ip of that player //this is not required (broken by proxies anyway) but is a nice handy feature - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; oldself = pr_global_struct->self; //these are usually useless oldother = pr_global_struct->other; //but its possible that someone makes a mod that depends on the 'mod' command working via redirectcmd+co //this at least matches mvdsv @@ -1509,7 +1473,7 @@ qboolean Q1QVM_ClientSay(edict_t *player, qboolean team) if (!q1qvm) return false; - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = Q1QVMPF_EdictToProgs(svprogfuncs, player); washandled = VM_Call(q1qvm, GAME_CLIENT_SAY, team); @@ -1521,7 +1485,7 @@ qboolean Q1QVM_UserInfoChanged(edict_t *player) if (!q1qvm) return false; - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = Q1QVMPF_EdictToProgs(svprogfuncs, player); return VM_Call(q1qvm, GAME_CLIENT_USERINFO_CHANGED); } diff --git a/engine/server/progdefs.h b/engine/server/progdefs.h index f5340a33..8abd2f2e 100644 --- a/engine/server/progdefs.h +++ b/engine/server/progdefs.h @@ -91,169 +91,227 @@ typedef struct nqglobalvars_s #define P_VEC(v) (pr_global_struct->V_##v) + +/*my hands are tied when it comes to the layout of this structure +On the server side, the structure *must* match original quakeworld, or we break compatibility with mvdsv's qvm api +On the client, it really doesn't matter what order fields are in, qclib will remap. +But fields that are actually useful on both sides need to be in the same locations. +But if we include all, that's a waste for csqc... +But we can overlap useful csqc-only ones with ssqc ones that are not going to be used on the client, so long as the types match. +This list isn't shared with the menu. + +If the left has an underscore, it means we don't use in for ssqc at all, its dead, purely for the ssqc mod +If the middle has an underscore, then we don't use it in shared code. +If the right has an underscore, then we don't use it in csqc (yet) + +if the middle has a valid name, both left+right must have valid names too. + +so the base fields are a fixed size +and the extension fields are added on the end and can have extra vm-specific stuff added on the end +*/ +/*DO NOT ADD TO THIS STRUCTURE*/ +#define comqcfields \ + comfieldfloat(modelindex,modelindex,modelindex);\ + comfieldvector(absmin,absmin,absmin);\ + comfieldvector(absmax,absmax,absmax);\ + comfieldfloat(ltime,_ltime,_ltime);\ + comfieldfloat(lastruntime,_lastruntime,_lastruntime); /*type doesn't match the qc, we use a hidden double instead. this is dead.*/ \ + comfieldfloat(movetype,movetype,movetype);\ + comfieldfloat(solid,solid,solid);\ + comfieldvector(origin,origin,origin);\ + comfieldvector(oldorigin,_oldorigin,_oldorigin);\ + comfieldvector(velocity,velocity,velocity);\ + comfieldvector(angles,angles,angles);\ + comfieldvector(avelocity,avelocity,avelocity);\ + comfieldstring(classname,classname,classname);\ + comfieldstring(model,model,model);\ + comfieldfloat(frame,frame,frame);\ + comfieldfloat(skin,skin,skin);\ + comfieldfloat(effects,_effects,_effects);\ + comfieldvector(mins,mins,mins);\ + comfieldvector(maxs,maxs,maxs);\ + comfieldvector(size,size,size);\ + comfieldfunction(touch,touch,touch);\ + comfieldfunction(_use,_use,_use);\ + comfieldfunction(think,_think,think);\ + comfieldfunction(blocked,_blocked,_blocked);\ + comfieldfloat(nextthink,_nextthink,nextthink);\ + comfieldentity(groundentity,groundentity,groundentity);\ + comfieldfloat(health,_health,_health);\ + comfieldfloat(frags,_frags,_frags);\ + comfieldfloat(weapon,_weapon,_weapon);\ + comfieldstring(weaponmodel,_weaponmodel,_weaponmodel);\ + comfieldfloat(weaponframe,_weaponframe,_weaponframe);\ + comfieldfloat(currentammo,_currentammo,_currentammo);\ + comfieldfloat(ammo_shells,_ammo_shells,_ammo_shells);\ + comfieldfloat(ammo_nails,_ammo_nails,_ammo_nails);\ + comfieldfloat(ammo_rockets,_ammo_rockets,_ammo_rockets);\ + comfieldfloat(ammo_cells,_ammo_cells,_ammo_cells);\ + comfieldfloat(items,_items,_items);\ + comfieldfloat(takedamage,_takedamage,_takedamage);\ + comfieldentity(chain,chain,chain);\ + comfieldfloat(_deadflag,_deadflag,_deadflag);\ + comfieldvector(view_ofs,_view_ofs,_view_ofs);\ + comfieldfloat(button0,_button0,_button0);\ + comfieldfloat(button1,_button1,_button1); /*dead field in nq mode*/ \ + comfieldfloat(button2,_button2,_button2);\ + comfieldfloat(impulse,_impulse,_impulse);\ + comfieldfloat(fixangle,_fixangle,_fixangle);\ + comfieldvector(v_angle,_v_angle,_v_angle);\ + comfieldstring(netname,_netname,_netname);\ + comfieldentity(enemy,enemy,enemy);\ + comfieldfloat(flags,flags,flags);\ + comfieldfloat(colormap,colormap,colormap);\ + comfieldfloat(team,_team,_team);\ + comfieldfloat(_max_health,_max_health,_max_health);\ + comfieldfloat(teleport_time,_teleport_time,_teleport_time);\ + comfieldfloat(_armortype,_armortype,_armortype);\ + comfieldfloat(armorvalue,_armorvalue,_armorvalue);\ + comfieldfloat(waterlevel,_waterlevel,_waterlevel);\ + comfieldfloat(watertype,_watertype,_watertype);\ + comfieldfloat(ideal_yaw,ideal_yaw,ideal_yaw);\ + comfieldfloat(yaw_speed,yaw_speed,yaw_speed);\ + comfieldentity(aiment,aiment,aiment);\ + comfieldentity(goalentity,_goalentity,_goalentity);\ + comfieldfloat(_spawnflags,_spawnflags,_spawnflags);\ + comfieldstring(_target,_target,_target);\ + comfieldstring(targetname,_targetname,_targetname);\ + comfieldfloat(dmg_take,_dmg_take,_dmg_take);\ + comfieldfloat(dmg_save,_dmg_save,_dmg_save);\ + comfieldentity(dmg_inflictor,_dmg_inflictor,_dmg_inflictor);\ + comfieldentity(owner,owner,owner);\ + comfieldvector(movedir,movedir,movedir);\ + comfieldstring(message,_message,_message); /*not used directly, hexen2 uses floats, so we go via qclib for message*/\ + comfieldfloat(sounds,_sounds,_sounds);\ + comfieldstring(_noise,_noise,_noise);\ + comfieldstring(_noise1,_noise1,_noise1);\ + comfieldstring(_noise2,_noise2,_noise2);\ + comfieldstring(_noise3,_noise3,_noise3); +/*DO NOT ADD TO THE ABOVE STRUCTURE*/ + +#define comextqcfields \ + comfieldfloat(gravity); /*added in quake 1.09 (for hipnotic)*/\ + comfieldfloat(hull);/*PEXT_HEXEN2*/\ + comfieldfloat(dimension_solid);/*EXT_DIMENSION_PHYSICS*/\ + comfieldfloat(dimension_hit);/*EXT_DIMENSION_PHYSICS*/\ + comfieldfloat(scale);/*DP_ENT_SCALE*/\ + comfieldfloat(fatness);/*FTE_PEXT_FATNESS*/\ + comfieldfloat(alpha);/*DP_ENT_ALPHA*/\ + comfieldfloat(pmove_flags);/*EXT_CSQC_1*/\ + comfieldfloat(jointtype);/*DP_...PHYSICS*/\ + comfieldfloat(mass);/*DP_...PHYSICS*/\ + comfieldfloat(bouncefactor);/*DP_...PHYSICS*/\ + comfieldfloat(bouncestop);/*DP_...PHYSICS*/ + +#define svextqcfields \ + comfieldfloat(maxspeed);/*added in quake 1.09*/\ + comfieldfloat(items2); /*added in quake 1.09 (for hipnotic)*/\ + comfieldvector(punchangle); /*std in nq*/\ + comfieldentity(view2);/*FTE_PEXT_VIEW2*/\ + comfieldvector(movement);\ + comfieldfloat(vw_index);\ + comfieldentity(nodrawtoclient);\ + comfieldentity(drawonlytoclient);\ + comfieldentity(viewmodelforclient);/*DP_ENT_VIEWMODEL*/\ + comfieldentity(exteriormodeltoclient);\ + comfieldfloat(button3); /*DP_INPUTBUTTONS (note in qw, we set 1 to equal 3, to match zquake/fuhquake/mvdsv)*/\ + comfieldfloat(button4);\ + comfieldfloat(button5);\ + comfieldfloat(button6);\ + comfieldfloat(button7);\ + comfieldfloat(button8);\ + comfieldfloat(viewzoom);/*DP_VIEWZOOM*/\ + comfieldentity(tag_entity);\ + comfieldfloat(tag_index);\ + comfieldfloat(glow_size);\ + comfieldfloat(glow_color);\ + comfieldfloat(glow_trail);\ + comfieldvector(color);\ + comfieldvector(colormod);\ + comfieldfloat(light_lev);\ + comfieldfloat(style);\ + comfieldfloat(pflags);\ + comfieldfloat(clientcolors);\ + comfieldfloat(dimension_see);/*EXT_DIMENSION_VISIBLE*/\ + comfieldfloat(dimension_seen);/*EXT_DIMENSION_VISIBLE*/\ + comfieldfloat(dimension_ghost);/*EXT_DIMENSION_GHOST*/\ + comfieldfloat(dimension_ghost_alpha);/*EXT_DIMENSION_GHOST*/\ + comfieldfloat(playerclass);/*hexen2 requirements*/\ + comfieldfloat(drawflags);/*hexen2*/\ + comfieldentity(movechain);/*hexen2*/\ + comfieldfunction(chainmoved);/*hexen2*/\ + comfieldfloat(hasted);/*hexen2 uses this AS WELL as maxspeed*/\ + comfieldfloat(light_level);/*hexen2's grabbing light level from client*/\ + comfieldfloat(abslight);/*hexen2's force a lightlevel*/\ + comfieldfunction(SendEntity);/*EXT_CSQC*/\ + comfieldfloat(SendFlags);/*EXT_CSQC_1 (one of the DP guys came up with it)*/\ + comfieldfloat(Version);/*EXT_CSQC (obsolete)*/\ + comfieldfloat(pvsflags);/*EXT_CSQC_1*/\ + comfieldfloat(uniquespawnid);/*FTE_ENT_UNIQUESPAWNID*/\ + comfieldfunction(customizeentityforclient); + typedef struct stdentvars_s //standard = standard for qw { - float modelindex; - vec3_t absmin; - vec3_t absmax; - float ltime; - int lastruntime; //type doesn't match the qc, we use a hidden double instead. this is dead. - float movetype; - float solid; - vec3_t origin; - vec3_t oldorigin; - vec3_t velocity; - vec3_t angles; - vec3_t avelocity; - string_t classname; - string_t model; - float frame; - float skin; - float effects; - vec3_t mins; - vec3_t maxs; - vec3_t size; - func_t touch; - func_t use; - func_t think; - func_t blocked; - float nextthink; - int groundentity; - float health; - float frags; - float weapon; - string_t weaponmodel; - float weaponframe; - float currentammo; - float ammo_shells; - float ammo_nails; - float ammo_rockets; - float ammo_cells; - float items; - float takedamage; - int chain; - float deadflag; - vec3_t view_ofs; - float button0; - float button1; //dead field in nq mode - float button2; - float impulse; - float fixangle; - vec3_t v_angle; - string_t netname; - int enemy; - float flags; - float colormap; - float team; - float max_health; - float teleport_time; - float armortype; - float armorvalue; - float waterlevel; - float watertype; - float ideal_yaw; - float yaw_speed; - int aiment; - int goalentity; - float spawnflags; - string_t target; - string_t targetname; - float dmg_take; - float dmg_save; - int dmg_inflictor; - int owner; - vec3_t movedir; - string_t message; //WARNING: hexen2 uses a float and not a string - float sounds; - string_t noise; - string_t noise1; - string_t noise2; - string_t noise3; - +#define comfieldfloat(ssqcname,sharedname,csqcname) float ssqcname +#define comfieldvector(ssqcname,sharedname,csqcname) vec3_t ssqcname +#define comfieldentity(ssqcname,sharedname,csqcname) int ssqcname +#define comfieldstring(ssqcname,sharedname,csqcname) string_t ssqcname +#define comfieldfunction(ssqcname,sharedname,csqcname) func_t ssqcname +comqcfields +#undef comfieldfloat +#undef comfieldvector +#undef comfieldentity +#undef comfieldstring +#undef comfieldfunction #ifdef VM_Q1 } stdentvars_t; typedef struct extentvars_s { #endif +#define comfieldfloat(name) float name +#define comfieldvector(name) vec3_t name +#define comfieldentity(name) int name +#define comfieldstring(name) string_t name +#define comfieldfunction(name) func_t name +comextqcfields +svextqcfields +#undef comfieldfloat +#undef comfieldvector +#undef comfieldentity +#undef comfieldstring +#undef comfieldfunction - //extra vars. use these if you wish. - float maxspeed; //added in quake 1.09 - float gravity; //added in quake 1.09 (for hipnotic) - float items2; //added in quake 1.09 (for hipnotic) - vec3_t punchangle; //std in nq - - float scale; //DP_ENT_SCALE - float alpha; //DP_ENT_ALPHA - float fatness; //FTE_PEXT_FATNESS - int view2; //FTE_PEXT_VIEW2 - vec3_t movement; - float vw_index; - - //dp extra fields - int nodrawtoclient; // - int drawonlytoclient; - int viewmodelforclient; //DP_ENT_VIEWMODEL - int exteriormodeltoclient; - float button3; //DP_INPUTBUTTONS (note in qw, we set 1 to equal 3, to match zquake/fuhquake/mvdsv) - float button4; - float button5; - float button6; - float button7; - float button8; - - float viewzoom; //DP_VIEWZOOM - - int tag_entity; - float tag_index; - - float glow_size; - float glow_color; - float glow_trail; - - vec3_t color; - vec3_t colormod; - float light_lev; - float style; - float pflags; - float clientcolors; - - //EXT_DIMENSION_VISIBLE - float dimension_see; - float dimension_seen; - //EXT_DIMENSION_GHOST - float dimension_ghost; - float dimension_ghost_alpha; - //EXT_DIMENSION_PHYSICS - float dimension_solid; - float dimension_hit; - - //hexen2 stuff - float playerclass; //hexen2 requirements - float hull; - float drawflags; - - int movechain; - func_t chainmoved; - - float light_level;//hexen2's grabbing light level from client - float abslight; //hexen2's force a lightlevel - float hasted; //hexen2 uses this AS WELL as maxspeed - - //csqc stuph. - func_t SendEntity; //EXT_CSQC - float SendFlags; //EXT_CSQC_1 (one of the DP guys came up with it) - float Version; //EXT_CSQC (obsolete) - float pvsflags; //EXT_CSQC_1 - float pmove_flags; //EXT_CSQC_1 (FIXME: is this really needed?) - - //FTE_ENT_UNIQUESPAWNID - float uniquespawnid; - - func_t customizeentityforclient; #ifdef VM_Q1 } extentvars_t; #else } stdentvars_t; #endif +typedef struct { +#define comfieldfloat(ssqcname,sharedname,csqcname) float sharedname +#define comfieldvector(ssqcname,sharedname,csqcname) vec3_t sharedname +#define comfieldentity(ssqcname,sharedname,csqcname) int sharedname +#define comfieldstring(ssqcname,sharedname,csqcname) string_t sharedname +#define comfieldfunction(ssqcname,sharedname,csqcname) func_t sharedname +comqcfields +#undef comfieldfloat +#undef comfieldvector +#undef comfieldentity +#undef comfieldstring +#undef comfieldfunction +} comentvars_t; + +typedef struct { +#define comfieldfloat(name) float name +#define comfieldvector(name) vec3_t name +#define comfieldentity(name) int name +#define comfieldstring(name) string_t name +#define comfieldfunction(name) func_t name +comextqcfields +#undef comfieldfloat +#undef comfieldvector +#undef comfieldentity +#undef comfieldstring +#undef comfieldfunction +} comextentvars_t; diff --git a/engine/server/progs.h b/engine/server/progs.h index 5c58a75f..485fb2a0 100644 --- a/engine/server/progs.h +++ b/engine/server/progs.h @@ -20,6 +20,9 @@ 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; + #define MAX_PROGS 64 #define MAXADDONS 16 @@ -33,6 +36,7 @@ void Q_InitProgs(void); void PR_RegisterFields(void); void PR_Init(void); void ED_Spawned (struct edict_s *ent, int loading); +qboolean SV_RunFullQCMovement(struct client_s *client, usercmd_t *ucmd); qboolean PR_KrimzonParseCommand(char *s); qboolean PR_UserCmd(char *cmd); qboolean PR_ConsoleCmd(void); @@ -54,13 +58,65 @@ extern progstype_t progstype; //extern globalvars_t *glob0; -extern int pr_edict_size; - //extern progparms_t progparms; //extern progsnum_t mainprogs; +#if defined(ODE_STATIC) || defined(ODE_DYNAMIC) +#define USEODE 1 +#endif + +#ifdef USEODE +typedef struct { + // physics parameters + qboolean ode_physics; + void *ode_body; + void *ode_geom; + void *ode_joint; + float *ode_vertex3f; + int *ode_element3i; + int ode_numvertices; + int ode_numtriangles; + vec3_t ode_mins; + vec3_t ode_maxs; + vec_t ode_mass; + vec3_t ode_origin; + vec3_t ode_velocity; + vec3_t ode_angles; + vec3_t ode_avelocity; + qboolean ode_gravity; + int ode_modelindex; + vec_t ode_movelimit; // smallest component of (maxs[]-mins[]) + float ode_offsetmatrix[16]; + float ode_offsetimatrix[16]; + int ode_joint_type; + int ode_joint_enemy; + int ode_joint_aiment; + vec3_t ode_joint_origin; // joint anchor + vec3_t ode_joint_angles; // joint axis + vec3_t ode_joint_velocity; // second joint axis + vec3_t ode_joint_movedir; // parameters + void *ode_massbuf; +} entityode_t; + +typedef struct +{ + // for ODE physics engine + qboolean ode; // if true then ode is activated + void *ode_world; + void *ode_space; + void *ode_contactgroup; + // number of constraint solver iterations to use (for dWorldStepFast) + int ode_iterations; + // actual step (server frametime / ode_iterations) + vec_t ode_step; + // max velocity for a 1-unit radius object at current step to prevent + // missed collisions + vec_t ode_movelimit; +} worldode_t; +#endif + #define MAX_ENT_LEAFS 16 typedef struct edict_s { @@ -69,27 +125,33 @@ typedef struct edict_s float freetime; // sv.time when the object was freed int entnum; qboolean readonly; //world - -#ifndef VM_Q1 - stdentvars_t *v; - #define xv v -#else - stdentvars_t *v; - - //the rest is free for adaption +#ifdef VM_Q1 + stdentvars_t *v; extentvars_t *xv; +#else + union { + stdentvars_t *v; + stdentvars_t *xv; + }; #endif - link_t area; // linked to a division node or leaf + /*qc lib doesn't care about the rest*/ + /*these are shared with csqc*/ + link_t area; int num_leafs; short leafnums[MAX_ENT_LEAFS]; - int areanum; //q2bsp - int areanum2; //q2bsp - int headnode; //q2bsp +#ifdef Q2BSPS + int areanum; + int areanum2; + int headnode; +#endif +#ifdef USEODE + entityode_t ode; +#endif + qbyte solidtype; + /*csqc doesn't reference the rest*/ entity_state_t baseline; - - qbyte solidtype; //relinks entities if their solidity changed // other fields from progs come immediately after } edict_t; @@ -109,7 +171,7 @@ extern progfuncs_t *svprogfuncs; //instance extern progparms_t svprogparms; extern progsnum_t svmainprogs; extern progsnum_t clmainprogs; -#define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area) +#define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,wedict_t,area) #define HLEDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,hledict_t,area) #define Q2EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,q2edict_t,area) #define Q3EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,q3serverEntity_t,area) diff --git a/engine/server/q2game.h b/engine/server/q2game.h index 16c293d9..d0b7d4ef 100644 --- a/engine/server/q2game.h +++ b/engine/server/q2game.h @@ -139,7 +139,6 @@ typedef struct q2entity_state_s } q2entity_state_t; -typedef struct q2edict_s q2edict_t; struct q2edict_s { q2entity_state_t s; @@ -179,10 +178,10 @@ struct q2edict_s typedef struct { // special messages - void (VARGS *bprintf) (int printlevel, char *fmt, ...); - void (VARGS *dprintf) (char *fmt, ...); - void (VARGS *cprintf) (q2edict_t *ent, int printlevel, char *fmt, ...); - void (VARGS *centerprintf) (q2edict_t *ent, char *fmt, ...); + void (VARGS *bprintf) (int printlevel, char *fmt, ...) LIKEPRINTF(2); + void (VARGS *dprintf) (char *fmt, ...) LIKEPRINTF(1); + void (VARGS *cprintf) (q2edict_t *ent, int printlevel, char *fmt, ...) LIKEPRINTF(3); + void (VARGS *centerprintf) (q2edict_t *ent, char *fmt, ...) LIKEPRINTF(2); void (VARGS *sound) (q2edict_t *ent, int channel, int soundindex, float volume, float attenuation, float timeofs); void (VARGS *positioned_sound) (vec3_t origin, q2edict_t *ent, int channel, int soundinedex, float volume, float attenuation, float timeofs); @@ -192,7 +191,7 @@ typedef struct // they connect, and changes are sent to all connected clients. void (VARGS *configstring) (int num, char *string); - void (VARGS *error) (char *fmt, ...); + void (VARGS *error) (char *fmt, ...) LIKEPRINTF(1); // the *index functions create configstrings and some internal server state int (VARGS *modelindex) (char *name); diff --git a/engine/server/qwsvdef.h b/engine/server/qwsvdef.h index 870b03d0..86e48ef0 100644 --- a/engine/server/qwsvdef.h +++ b/engine/server/qwsvdef.h @@ -93,12 +93,12 @@ extern double host_frametime; extern double realtime; // not bounded in any way, changed at // start of every frame, never reset -void SV_Error (char *error, ...); +void SV_Error (char *error, ...) LIKEPRINTF(1); void SV_Init (struct quakeparms_s *parms); -void Con_Printf (char *fmt, ...); +void Con_Printf (char *fmt, ...) LIKEPRINTF(1); void Con_TPrintf (translation_t fmt, ...); -void Con_DPrintf (char *fmt, ...); +void Con_DPrintf (char *fmt, ...) LIKEPRINTF(1); #endif diff --git a/engine/server/savegame.c b/engine/server/savegame.c index ea52a775..c3888cb9 100644 --- a/engine/server/savegame.c +++ b/engine/server/savegame.c @@ -551,7 +551,7 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers) char syspath[MAX_OSPATH]; SV_SpawnServer (level, startspot, false, false); - SV_ClearWorld(); + World_ClearWorld(&sv.world); if (!ge) { Con_Printf("Incorrect gamecode type.\n"); @@ -654,7 +654,7 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers) PR_Configure(svprogfuncs, -1, MAX_PROGS); PR_RegisterFields(); - PR_InitEnts(svprogfuncs, sv.max_edicts); + PR_InitEnts(svprogfuncs, sv.world.max_edicts); modelpos = VFS_TELL(f); LoadModelsAndSounds(f); @@ -666,14 +666,14 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers) memset(file, 0, filelen+1); clnum=VFS_READ(f, file, filelen); file[filelen]='\0'; - pr_edict_size=svprogfuncs->load_ents(svprogfuncs, file, 0); + sv.world.edict_size=svprogfuncs->load_ents(svprogfuncs, file, 0); BZ_Free(file); progstype = pt; PR_LoadGlabalStruct(); - pr_global_struct->time = sv.time = sv.physicstime = time; + pr_global_struct->time = sv.time = sv.world.physicstime = time; sv.starttime = Sys_DoubleTime() - sv.time; VFS_SEEK(f, modelpos); @@ -683,7 +683,7 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers) PF_InitTempStrings(svprogfuncs); - SV_ClearWorld (); + World_ClearWorld (&sv.world); for (i=0 ; ispawn_parms[j]; } - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent); ent->area.next = ent->area.prev = NULL; G_FLOAT(OFS_PARM0) = sv.time-host_client->spawninfotime; @@ -729,13 +729,13 @@ qboolean SV_LoadLevelCache(char *level, char *startspot, qboolean ignoreplayers) } } - for (i=0 ; iisfree) continue; - SV_LinkEdict (ent, false); // force retouch even for stationary + World_LinkEdict (&sv.world, (wedict_t*)ent, false); // force retouch even for stationary } return true; //yay diff --git a/engine/server/server.h b/engine/server/server.h index 41f841d8..32bb050c 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -115,12 +115,8 @@ typedef struct double time; double starttime; - double physicstime; //This is the time at which the physics were last run. int framenum; - int lastcheck; // used by PF_checkclient - double lastchecktime; // for monster ai - qboolean paused; // are we paused? float pausedstart; @@ -131,7 +127,8 @@ typedef struct char name[64]; // file map name char mapname[256]; char modelname[MAX_QPATH]; // maps/.bsp, for model_precache[0] - struct model_s *worldmodel; + + world_t world; union { #ifdef Q2SERVER @@ -147,14 +144,8 @@ typedef struct char lightstylecolours[MAX_LIGHTSTYLES]; }; } strings; - struct model_s *models[MAX_MODELS]; int allocated_client_slots; //number of slots available. (used mostly to stop single player saved games cacking up) - int max_edicts; //limiting factor... 1024 fields*4*MAX_EDICTS == a heck of a lot. - int num_edicts; // increases towards MAX_EDICTS - edict_t *edicts; // can NOT be array indexed, because - // edict_t is variable sized, but can - // be used to reference the world ent qbyte *pvs, *phs; // fully expanded and decompressed @@ -300,6 +291,8 @@ typedef struct int move_msecs; int packetsizein; int packetsizeout; + vec3_t playerpositions[MAX_CLIENTS]; + qboolean playerpresent[MAX_CLIENTS]; packet_entities_t entities; //must come last (mvd states are bigger) } client_frame_t; @@ -404,6 +397,9 @@ typedef struct client_s double connection_started; // or time of disconnect for zombies qboolean send_message; // set on frames a datagram arived on + laggedentinfo_t laggedents[MAX_CLIENTS]; + unsigned int laggedents_count; + // spawn parms are carried from level to level float spawn_parms[NUM_SPAWN_PARMS]; char *spawninfo; @@ -497,6 +493,7 @@ typedef struct client_s qboolean csqcactive; #ifdef PROTOCOL_VERSION_FTE unsigned long fteprotocolextensions; + unsigned long fteprotocolextensions2; #endif unsigned long zquake_extensions; @@ -754,6 +751,7 @@ typedef struct #ifdef PROTOCOLEXTENSIONS unsigned long fteprotocolextensions; + unsigned long fteprotocolextensions2; #endif qboolean demoplayback; @@ -784,6 +782,7 @@ typedef struct #define MOVETYPE_FOLLOW 12 // track movement of aiment #define MOVETYPE_PUSHPULL 13 // pushable/pullable object #define MOVETYPE_SWIM 14 // should keep the object in water +#define MOVETYPE_PHYSICS 32 // edict->solid values #define SOLID_NOT 0 // no interaction with other objects @@ -794,28 +793,45 @@ typedef struct #define SOLID_PHASEH2 5 #define SOLID_CORPSE 5 #define SOLID_LADDER 20 //dmw. touch on edge, not blocking. Touching players have different physics. Otherwise a SOLID_TRIGGER +#define SOLID_PHYSICS_BOX 32 ///< physics object (mins, maxs, mass, origin, axis_forward, axis_left, axis_up, velocity, spinvelocity) +#define SOLID_PHYSICS_SPHERE 33 ///< physics object (mins, maxs, mass, origin, axis_forward, axis_left, axis_up, velocity, spinvelocity) +#define SOLID_PHYSICS_CAPSULE 34 ///< physics object (mins, maxs, mass, origin, axis_forward, axis_left, axis_up, velocity, spinvelocity) + + +#define JOINTTYPE_POINT 1 +#define JOINTTYPE_HINGE 2 +#define JOINTTYPE_SLIDER 3 +#define JOINTTYPE_UNIVERSAL 4 +#define JOINTTYPE_HINGE2 5 +#define JOINTTYPE_FIXED -1 #define DAMAGE_NO 0 #define DAMAGE_YES 1 #define DAMAGE_AIM 2 // edict->flags -#define FL_FLY 1 -#define FL_SWIM 2 -#define FL_GLIMPSE 4 -#define FL_CLIENT 8 -#define FL_INWATER 16 -#define FL_MONSTER 32 -#define FL_GODMODE 64 -#define FL_NOTARGET 128 -#define FL_ITEM 256 -#define FL_ONGROUND 512 -#define FL_PARTIALGROUND 1024 // not all corners are valid -#define FL_WATERJUMP 2048 // player jumping out of water - -#define FL_FINDABLE_NONSOLID 16384 //a cpqwsv feature -#define FL_MOVECHAIN_ANGLE 32768 // when in a move chain, will update the angle -#define FL_CLASS_DEPENDENT 2097152 +#define FL_FLY (1<<0) +#define FL_SWIM (1<<1) +#define FL_GLIMPSE (1<<2) +#define FL_CLIENT (1<<3) +#define FL_INWATER (1<<4) +#define FL_MONSTER (1<<5) +#define FL_GODMODE (1<<6) +#define FL_NOTARGET (1<<7) +#define FL_ITEM (1<<8) +#define FL_ONGROUND (1<<9) +#define FL_PARTIALGROUND (1<<10) // not all corners are valid +#define FL_WATERJUMP (1<<11) // player jumping out of water + //12 + //13 +#define FL_FINDABLE_NONSOLID (1<<14) //a cpqwsv feature +#define FL_MOVECHAIN_ANGLE (1<<15) // when in a move chain, will update the angle +#define FL_LAGGEDMOVE (1<<16) + //17 + //18 + //19 + //20 +#define FL_CLASS_DEPENDENT (1<<21) #define PVSF_NORMALPVS 0x0 #define PVSF_NOTRACECHECK 0x1 @@ -834,21 +850,21 @@ typedef struct #define EF_FULLBRIGHT 512 -#define SPAWNFLAG_NOT_EASY 256 -#define SPAWNFLAG_NOT_MEDIUM 512 -#define SPAWNFLAG_NOT_HARD 1024 -#define SPAWNFLAG_NOT_DEATHMATCH 2048 +#define SPAWNFLAG_NOT_EASY (1<<8) +#define SPAWNFLAG_NOT_MEDIUM (1<<9) +#define SPAWNFLAG_NOT_HARD (1<<10) +#define SPAWNFLAG_NOT_DEATHMATCH (1<<11) -#define SPAWNFLAG_NOT_H2PALADIN 256 -#define SPAWNFLAG_NOT_H2CLERIC 512 -#define SPAWNFLAG_NOT_H2NECROMANCER 1024 -#define SPAWNFLAG_NOT_H2THEIF 2048 -#define SPAWNFLAG_NOT_H2EASY 4096 -#define SPAWNFLAG_NOT_H2MEDIUM 8192 -#define SPAWNFLAG_NOT_H2HARD 16384 -#define SPAWNFLAG_NOT_H2DEATHMATCH 32768 -#define SPAWNFLAG_NOT_H2COOP 65536 -#define SPAWNFLAG_NOT_H2SINGLE 131072 +#define SPAWNFLAG_NOT_H2PALADIN (1<<8) +#define SPAWNFLAG_NOT_H2CLERIC (1<<9) +#define SPAWNFLAG_NOT_H2NECROMANCER (1<<10) +#define SPAWNFLAG_NOT_H2THEIF (1<<11) +#define SPAWNFLAG_NOT_H2EASY (1<<12) +#define SPAWNFLAG_NOT_H2MEDIUM (1<<13) +#define SPAWNFLAG_NOT_H2HARD (1<<14) +#define SPAWNFLAG_NOT_H2DEATHMATCH (1<<15) +#define SPAWNFLAG_NOT_H2COOP (1<<16) +#define SPAWNFLAG_NOT_H2SINGLE (1<<17) #if 0//ndef Q2SERVER typedef enum multicast_e @@ -876,6 +892,7 @@ typedef enum multicast_e extern cvar_t sv_mintic, sv_maxtic; extern cvar_t sv_maxspeed; +extern cvar_t sv_antilag; extern netadr_t master_adr[MAX_MASTERS]; // address of the master server @@ -904,7 +921,7 @@ extern vfsfile_t *sv_fraglogfile; // // sv_main.c // -void VARGS SV_Error (char *error, ...); +NORETURN void VARGS SV_Error (char *error, ...) LIKEPRINTF(1); void SV_Shutdown (void); void SV_Frame (void); void SV_FinalMessage (char *message); @@ -955,6 +972,7 @@ void SV_UnspawnServer (void); void SV_FlushSignon (void); void SV_FilterImpulseInit(void); +qboolean SV_FilterImpulse(int imp, int level); //svq2_game.c qboolean SVQ2_InitGameProgs(void); @@ -985,7 +1003,6 @@ qboolean SVQ3_Command(void); // // sv_phys.c // -void SV_TouchLinks ( edict_t *ent, areanode_t *node ); void SV_ProgStartFrame (void); qboolean SV_Physics (void); void SV_CheckVelocity (edict_t *ent); @@ -1014,11 +1031,11 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int void SV_StartSound (int entnum, vec3_t origin, int seenmask, int channel, char *sample, int volume, float attenuation); void SVQ1_StartSound (edict_t *entity, int channel, char *sample, int volume, float attenuation); void SV_PrintToClient(client_t *cl, int level, char *string); -void VARGS SV_ClientPrintf (client_t *cl, int level, char *fmt, ...); +void VARGS SV_ClientPrintf (client_t *cl, int level, char *fmt, ...) LIKEPRINTF(3); void VARGS SV_ClientTPrintf (client_t *cl, int level, translation_t text, ...); -void VARGS SV_BroadcastPrintf (int level, char *fmt, ...); +void VARGS SV_BroadcastPrintf (int level, char *fmt, ...) LIKEPRINTF(2); void VARGS SV_BroadcastTPrintf (int level, translation_t fmt, ...); -void VARGS SV_BroadcastCommand (char *fmt, ...); +void VARGS SV_BroadcastCommand (char *fmt, ...) LIKEPRINTF(1); void SV_SendServerInfoChange(char *key, const char *value); void SV_SendMessagesToAll (void); void SV_FindModelNumbers (void); @@ -1080,6 +1097,7 @@ qboolean PR_ShouldTogglePause(client_t *initiator, qboolean pausedornot); // sv_ents.c // void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignorepvs); +void SVQ3Q1_BuildEntityPacket(client_t *client, packet_entities_t *pack); int SV_HullNumForPlayer(int h2hull, float *mins, float *maxs); void SV_GibFilterInit(void); void SV_CleanupEnts(void); @@ -1287,12 +1305,6 @@ qboolean TransformedNativeTrace (struct model_s *model, int hulloverride, int fr void SVVC_Frame (qboolean enabled); void SV_CalcPHS (void); -#ifdef Q2SERVER -void VARGS SVQ2_LinkEdict(q2edict_t *ent); -void VARGS SVQ2_UnlinkEdict(q2edict_t *ent); -int VARGS SVQ2_AreaEdicts (vec3_t mins, vec3_t maxs, q2edict_t **list, - int maxcount, int areatype); -#endif void SV_GetConsoleCommands (void); void SV_CheckTimer(void); @@ -1310,3 +1322,5 @@ typedef struct void SV_TimeOfDay(date_t *date); void SV_LogPlayer(client_t *cl, char *msg); + +void AddLinksToPmove ( edict_t *player, areanode_t *node ); diff --git a/engine/server/sv_ccmds.c b/engine/server/sv_ccmds.c index 8009ba4b..63bca4dd 100644 --- a/engine/server/sv_ccmds.c +++ b/engine/server/sv_ccmds.c @@ -152,6 +152,7 @@ Make a master server current ==================== */ void Master_ClearAll(void); +void Master_ReResolve(void); void Master_Add(char *stringadr); void SV_SetMaster_f (void) @@ -335,7 +336,7 @@ void SV_Give_f (void) { int oldself; oldself = pr_global_struct->self; - pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.edicts); + pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.world.edicts); Con_Printf("Result: %s\n", svprogfuncs->EvaluateDebugString(svprogfuncs, Cmd_Args())); pr_global_struct->self = oldself; } @@ -1398,7 +1399,7 @@ void SV_Status_f (void) else Con_Printf ("current map : %s\n", sv.name); - Con_Printf("map uptime : %s\n", ShowTime(sv.physicstime)); + Con_Printf("map uptime : %s\n", ShowTime(sv.world.physicstime)); Con_Printf("server uptime : %s\n", ShowTime(realtime)); if (sv.csqcdebug) Con_Printf("csqc debug : true\n"); @@ -1865,7 +1866,8 @@ void SV_Snap (int uid) if (cl->userid == uid) break; } - if (i >= MAX_CLIENTS) { + if (i >= MAX_CLIENTS) + { Con_TPrintf (STL_USERDOESNTEXIST); return; } @@ -1877,7 +1879,7 @@ void SV_Snap (int uid) sprintf(pcxname, "%d-00.pcx", uid); - sprintf(checkname, "%s/snap", gamedirfile); + strcpy(checkname, "snap"); Sys_mkdir(gamedirfile); Sys_mkdir(checkname); @@ -1886,7 +1888,7 @@ void SV_Snap (int uid) pcxname[strlen(pcxname) - 6] = i/10 + '0'; pcxname[strlen(pcxname) - 5] = i%10 + '0'; sprintf (checkname, "%s/snap/%s", gamedirfile, pcxname); - if (Sys_FileTime(checkname) == -1) + if (!COM_FCheckExists(checkname)) break; // file doesn't exist } if (i==100) diff --git a/engine/server/sv_demo.c b/engine/server/sv_demo.c index 7d858790..cb4dd507 100644 --- a/engine/server/sv_demo.c +++ b/engine/server/sv_demo.c @@ -359,7 +359,8 @@ readnext: } // decide if it is time to grab the next message - if (!sv.paused) { // always grab until fully connected + if (!sv.paused) + { // always grab until fully connected if (!svd.mvdplayback) { if (svd.realtime + 1.0 < demotime) { diff --git a/engine/server/sv_ents.c b/engine/server/sv_ents.c index 7d429d1a..830440bb 100644 --- a/engine/server/sv_ents.c +++ b/engine/server/sv_ents.c @@ -19,7 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "qwsvdef.h" - +#include "pr_common.h" #ifndef CLIENTONLY void SV_CleanupEnts(void); @@ -63,7 +63,7 @@ unsigned int SV_Q2BSP_FatPVS (model_t *mod, vec3_t org, qbyte *resultbuf, unsig if (count < 1) Sys_Error ("SV_Q2FatPVS: count < 1"); - if (sv.worldmodel->fromgame == fg_quake3) + if (sv.world.worldmodel->fromgame == fg_quake3) longs = CM_ClusterSize(mod); else longs = (CM_NumClusters(mod)+7)/8; @@ -345,7 +345,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg) client->csqcentsequence[ent->entnum] = currentsequence; } //now remove any out dated ones - for (en = 1; en < sv.num_edicts; en++) + for (en = 1; en < sv.world.num_edicts; en++) { ent = EDICT_NUM(svprogfuncs, en); if (client->csqcentversions[en] > 0 && (client->csqcentversions[en] != sv.csqcentversion[en]) && !((int)ent->xv->pvsflags & PVSF_NOREMOVE)) @@ -392,7 +392,7 @@ void SV_CSQC_DroppedPacket(client_t *client, int sequence) if (!(client->csqcactive)) //we don't need this, but it might be a little faster. return; - for (i = 0; i < sv.num_edicts; i++) + for (i = 0; i < sv.world.num_edicts; i++) if (client->csqcentsequence[i] == sequence) client->csqcentversions[i]--; //do that update thang (but later). } @@ -402,7 +402,7 @@ void SV_CSQC_DropAll(client_t *client) if (!(client->csqcactive)) //we don't need this, but it might be a little faster. return; - for (i = 0; i < sv.num_edicts; i++) + for (i = 0; i < sv.world.num_edicts; i++) client->csqcentversions[i]--; //do that update thang (but later). } #endif @@ -1084,7 +1084,7 @@ int SV_HullNumForPlayer(int h2hull, float *mins, float *maxs) int best; int hullnum, i; - if (sv.worldmodel->fromgame != fg_quake) + if (sv.world.worldmodel->fromgame != fg_quake) { VectorSubtract (maxs, mins, size); return size[2]; //clients are expected to decide themselves. @@ -1101,10 +1101,10 @@ int SV_HullNumForPlayer(int h2hull, float *mins, float *maxs) for (i = 0; i < MAX_MAP_HULLSM; i++) { #define sq(x) ((x)*(x)) - diff = sq(sv.worldmodel->hulls[i].clip_maxs[2] - maxs[2]) + - sq(sv.worldmodel->hulls[i].clip_mins[2] - mins[2]) + - sq(sv.worldmodel->hulls[i].clip_maxs[0] - maxs[0]) + - sq(sv.worldmodel->hulls[i].clip_mins[0] - mins[0]); + diff = sq(sv.world.worldmodel->hulls[i].clip_maxs[2] - maxs[2]) + + sq(sv.world.worldmodel->hulls[i].clip_mins[2] - mins[2]) + + sq(sv.world.worldmodel->hulls[i].clip_maxs[0] - maxs[0]) + + sq(sv.world.worldmodel->hulls[i].clip_mins[0] - mins[0]); if (diff < best) { best = diff; @@ -1387,7 +1387,7 @@ qboolean Cull_Traceline(edict_t *viewer, edict_t *seen) //stage 1: check against their origin VectorAdd(viewer->v->origin, viewer->v->view_ofs, start); tr.fraction = 1; - if (!sv.worldmodel->funcs.Trace (sv.worldmodel, 1, 0, start, seen->v->origin, vec3_origin, vec3_origin, &tr)) + if (!sv.world.worldmodel->funcs.Trace (sv.world.worldmodel, 1, 0, start, seen->v->origin, vec3_origin, vec3_origin, &tr)) return false; //wasn't blocked //stage 2: check against their bbox @@ -1398,7 +1398,7 @@ qboolean Cull_Traceline(edict_t *viewer, edict_t *seen) end[2] = seen->v->origin[2] + ((i&4)?seen->v->mins[2]+0.1:seen->v->maxs[2]); tr.fraction = 1; - if (!sv.worldmodel->funcs.Trace (sv.worldmodel, 1, 0, start, end, vec3_origin, vec3_origin, &tr)) + if (!sv.world.worldmodel->funcs.Trace (sv.world.worldmodel, 1, 0, start, end, vec3_origin, vec3_origin, &tr)) return false; //this trace went through, so don't cull } @@ -1412,7 +1412,7 @@ SV_WritePlayersToClient ============= */ -void SV_WritePlayersToClient (client_t *client, edict_t *clent, qbyte *pvs, sizebuf_t *msg) +void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, edict_t *clent, qbyte *pvs, sizebuf_t *msg) { qboolean isbot; int i, j; @@ -1688,7 +1688,7 @@ void SV_WritePlayersToClient (client_t *client, edict_t *clent, qbyte *pvs, size continue; // ignore if not touching a PV leaf - if (!sv.worldmodel->funcs.EdictInFatPVS(sv.worldmodel, ent, pvs)) + if (!sv.world.worldmodel->funcs.EdictInFatPVS(sv.world.worldmodel, (wedict_t*)ent, pvs)) continue; if (!((int)clent->xv->dimension_see & ((int)ent->xv->dimension_seen | (int)ent->xv->dimension_ghost))) @@ -1786,7 +1786,14 @@ void SV_WritePlayersToClient (client_t *client, edict_t *clent, qbyte *pvs, size { clst.lastcmd = NULL; clst.velocity = NULL; + clst.localtime = sv.time; + VectorCopy(clst.origin, frame->playerpositions[j]); } + else + { + VectorMA(clst.origin, (sv.time - clst.localtime), clst.velocity, frame->playerpositions[j]); + } + frame->playerpresent[j] = true; SV_WritePlayerToClient(msg, &clst); } @@ -2100,7 +2107,7 @@ unsigned int Q2BSP_FatPVS(model_t *mod, vec3_t org, qbyte *buffer, unsigned int return SV_Q2BSP_FatPVS (mod, org, buffer, buffersize, add); } -qboolean Q2BSP_EdictInFatPVS(model_t *mod, edict_t *ent, qbyte *pvs) +qboolean Q2BSP_EdictInFatPVS(model_t *mod, wedict_t *ent, qbyte *pvs) { int i,l; if (!CM_AreasConnected (mod, clientarea, ent->areanum)) @@ -2359,6 +2366,7 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs, && ISQWCLIENT(client) #endif ) //this entity is watching from outside themselves. The client is tricked into thinking that they themselves are in the view ent, and a new dummy ent (the old them) must be spawned. + { //FIXME: this hack needs cleaning up @@ -2401,7 +2409,7 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs, #ifdef NQPROT - for (e=(ISQWCLIENT(client)?sv.allocated_client_slots+1:1) ; exv->tag_entity); } - if (!sv.worldmodel->funcs.EdictInFatPVS(sv.worldmodel, p, pvs)) + if (!sv.world.worldmodel->funcs.EdictInFatPVS(sv.world.worldmodel, (wedict_t*)p, pvs)) continue; } else { - if (!sv.worldmodel->funcs.EdictInFatPVS(sv.worldmodel, ent, pvs)) + if (!sv.world.worldmodel->funcs.EdictInFatPVS(sv.world.worldmodel, (wedict_t*)ent, pvs)) continue; } } - else if ((pvsflags & PVSF_MODE_MASK) == PVSF_USEPHS && sv.worldmodel->fromgame == fg_quake) + else if ((pvsflags & PVSF_MODE_MASK) == PVSF_USEPHS && sv.world.worldmodel->fromgame == fg_quake) { int leafnum; unsigned char *mask; - leafnum = sv.worldmodel->funcs.LeafnumForPoint(sv.worldmodel, host_client->edict->v->origin); - mask = sv.phs + leafnum * 4*((sv.worldmodel->numleafs+31)>>5); + leafnum = sv.world.worldmodel->funcs.LeafnumForPoint(sv.world.worldmodel, host_client->edict->v->origin); + mask = sv.phs + leafnum * 4*((sv.world.worldmodel->numleafs+31)>>5); - leafnum = sv.worldmodel->funcs.LeafnumForPoint (sv.worldmodel, ent->v->origin)-1; + leafnum = sv.world.worldmodel->funcs.LeafnumForPoint (sv.world.worldmodel, ent->v->origin)-1; if ( !(mask[leafnum>>3] & (1<<(leafnum&7)) ) ) { Con_Printf ("PHS supressed entity\n"); @@ -2635,12 +2643,12 @@ qbyte *SV_Snapshot_SetupPVS(client_t *client, qbyte *pvs, unsigned int pvsbufsiz for (; client; client = client->controlled) { VectorAdd (client->edict->v->origin, client->edict->v->view_ofs, org); - sv.worldmodel->funcs.FatPVS(sv.worldmodel, org, pvs, pvsbufsize, leavepvs); + sv.world.worldmodel->funcs.FatPVS(sv.world.worldmodel, org, pvs, pvsbufsize, leavepvs); leavepvs = true; #ifdef PEXT_VIEW2 if (client->edict->xv->view2) //add a second view point to the pvs - sv.worldmodel->funcs.FatPVS(sv.worldmodel, PROG_TO_EDICT(svprogfuncs, client->edict->xv->view2)->v->origin, pvs, pvsbufsize, leavepvs); + sv.world.worldmodel->funcs.FatPVS(sv.world.worldmodel, PROG_TO_EDICT(svprogfuncs, client->edict->xv->view2)->v->origin, pvs, pvsbufsize, leavepvs); #endif } @@ -2693,6 +2701,8 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore // this is the frame we are creating frame = &client->frameunion.frames[client->netchan.incoming_sequence & UPDATE_MASK]; + if (!sv.paused) + memset(frame->playerpresent, 0, sizeof(frame->playerpresent)); // find the client's PVS if (ignorepvs) @@ -2717,7 +2727,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore // send over the players in the PVS if (svs.gametype != GT_HALFLIFE) - SV_WritePlayersToClient (client, clent, pvs, msg); + SV_WritePlayersToClient (client, frame, clent, pvs, msg); // put other visible entities into either a packet_entities or a nails message diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index 82411004..b00f5c05 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -62,7 +62,7 @@ int SV_ModelIndex (char *name) { Q_strncpyz(sv.strings.model_precache[i], name, sizeof(sv.strings.model_precache[i])); if (!strcmp(name + strlen(name) - 4, ".bsp")) - sv.models[i] = Mod_FindName(sv.strings.model_precache[i]); + sv.world.models[i] = Mod_FindName(sv.strings.model_precache[i]); Con_Printf("WARNING: SV_ModelIndex: model %s not precached\n", name); } else @@ -278,7 +278,7 @@ void SVNQ_CreateBaseline (void) int playermodel = SV_SafeModelIndex("progs/player.mdl"); - for (entnum = 0; entnum < sv.num_edicts ; entnum++) + for (entnum = 0; entnum < sv.world.num_edicts ; entnum++) { svent = EDICT_NUM(svprogfuncs, entnum); @@ -438,7 +438,7 @@ void SV_CalcPHS (void) qbyte *scan, *lf; int count, vcount; - if (sv.worldmodel->fromgame == fg_quake2 || sv.worldmodel->fromgame == fg_quake3) + if (sv.world.worldmodel->fromgame == fg_quake2 || sv.world.worldmodel->fromgame == fg_quake3) { //PHS calcs are pointless with Q2 bsps return; @@ -447,7 +447,7 @@ void SV_CalcPHS (void) if (developer.value) Con_TPrintf (STL_BUILDINGPHS); - num = sv.worldmodel->numleafs; + num = sv.world.worldmodel->numleafs; rowwords = (num+31)>>5; rowbytes = rowwords*4; @@ -456,7 +456,7 @@ void SV_CalcPHS (void) vcount = 0; for (i=0 ; ifuncs.LeafPVS(sv.worldmodel, i, scan, rowbytes); + lf = sv.world.worldmodel->funcs.LeafPVS(sv.world.worldmodel, i, scan, rowbytes); if (lf != scan) memcpy (scan, lf, rowbytes); if (i == 0) @@ -546,7 +546,7 @@ void SV_UnspawnServer (void) //terminate the running server. #ifdef HLSERVER SVHL_ShutdownGame(); #endif - sv.worldmodel = NULL; + sv.world.worldmodel = NULL; sv.state = ss_dead; *sv.name = '\0'; } @@ -789,10 +789,10 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us sprintf (sv.modelname,"maps/%s.bsp", server); } sv.state = ss_loading; - sv.worldmodel = Mod_ForName (sv.modelname, true); - if (!sv.worldmodel || sv.worldmodel->needload) + sv.world.worldmodel = Mod_ForName (sv.modelname, true); + if (!sv.world.worldmodel || sv.world.worldmodel->needload) Sys_Error("%s is missing or corrupt\n", sv.modelname); - if (sv.worldmodel->type != mod_brush && sv.worldmodel->type != mod_heightmap) + if (sv.world.worldmodel->type != mod_brush && sv.world.worldmodel->type != mod_heightmap) Sys_Error("%s is not a bsp model\n", sv.modelname); sv.state = ss_dead; @@ -808,13 +808,13 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us SCR_ImageName(server); #endif - if (sv.worldmodel->fromgame == fg_doom) + if (sv.world.worldmodel->fromgame == fg_doom) Info_SetValueForStarKey(svs.info, "*bspversion", "1", MAX_SERVERINFO_STRING); - else if (sv.worldmodel->fromgame == fg_halflife) + else if (sv.world.worldmodel->fromgame == fg_halflife) Info_SetValueForStarKey(svs.info, "*bspversion", "30", MAX_SERVERINFO_STRING); - else if (sv.worldmodel->fromgame == fg_quake2) + else if (sv.world.worldmodel->fromgame == fg_quake2) Info_SetValueForStarKey(svs.info, "*bspversion", "38", MAX_SERVERINFO_STRING); - else if (sv.worldmodel->fromgame == fg_quake3) + else if (sv.world.worldmodel->fromgame == fg_quake3) Info_SetValueForStarKey(svs.info, "*bspversion", "46", MAX_SERVERINFO_STRING); else Info_SetValueForStarKey(svs.info, "*bspversion", "", MAX_SERVERINFO_STRING); @@ -827,7 +827,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us // // clear physics interaction links // - SV_ClearWorld (); + World_ClearWorld (&sv.world); //do we allow csprogs? #ifdef PEXT_CSQC @@ -871,7 +871,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us if (svprogfuncs) //we don't want the q1 stuff anymore. { CloseProgs(svprogfuncs); - svprogfuncs = NULL; + sv.world.progs = svprogfuncs = NULL; } } @@ -889,7 +889,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us else #endif #ifdef Q2SERVER - if ((sv.worldmodel->fromgame == fg_quake2 || sv.worldmodel->fromgame == fg_quake3) && !*progs.string && SVQ2_InitGameProgs()) //these are the rules for running a q2 server + if ((sv.world.worldmodel->fromgame == fg_quake2 || sv.world.worldmodel->fromgame == fg_quake3) && !*progs.string && SVQ2_InitGameProgs()) //these are the rules for running a q2 server newgametype = GT_QUAKE2; //we loaded the dll else #endif @@ -935,7 +935,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us #endif - sv.models[1] = sv.worldmodel; + sv.world.models[1] = sv.world.worldmodel; #ifdef VM_Q1 if (svs.gametype == GT_Q1QVM) { @@ -943,10 +943,10 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us sv.strings.model_precache[0] = ""; sv.strings.model_precache[1] = sv.modelname; //the qvm doesn't have access to this array - for (i=1 ; inumsubmodels ; i++) + for (i=1 ; inumsubmodels ; i++) { sv.strings.model_precache[1+i] = localmodels[i]; - sv.models[i+1] = Mod_ForName (localmodels[i], false); + sv.world.models[i+1] = Mod_ForName (localmodels[i], false); } //check player/eyes models for hacks @@ -961,10 +961,10 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us sv.strings.model_precache[0] = ""; sv.strings.model_precache[1] = PR_AddString(svprogfuncs, sv.modelname, 0); - for (i=1 ; inumsubmodels ; i++) + for (i=1 ; inumsubmodels ; i++) { sv.strings.model_precache[1+i] = PR_AddString(svprogfuncs, localmodels[i], 0); - sv.models[i+1] = Mod_ForName (localmodels[i], false); + sv.world.models[i+1] = Mod_ForName (localmodels[i], false); } //check player/eyes models for hacks @@ -985,16 +985,16 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us strcpy(sv.strings.configstring[Q2CS_AIRACCEL], "0"); // init map checksum config string but only for Q2/Q3 maps - if (sv.worldmodel->fromgame == fg_quake2 || sv.worldmodel->fromgame == fg_quake3) + if (sv.world.worldmodel->fromgame == fg_quake2 || sv.world.worldmodel->fromgame == fg_quake3) sprintf(sv.strings.configstring[Q2CS_MAPCHECKSUM], "%i", map_checksum); else strcpy(sv.strings.configstring[Q2CS_MAPCHECKSUM], "0"); strcpy(sv.strings.configstring[Q2CS_MODELS+1], sv.modelname); - for (i=1; inumsubmodels; i++) + for (i=1; inumsubmodels; i++) { strcpy(sv.strings.configstring[Q2CS_MODELS+1+i], localmodels[i]); - sv.models[i+1] = Mod_ForName (localmodels[i], false); + sv.world.models[i+1] = Mod_ForName (localmodels[i], false); } } #endif @@ -1116,7 +1116,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us #ifdef VM_Q1 if (svs.gametype != GT_Q1QVM) //we cannot do this with qvm #endif - ent->v->model = PR_NewString(svprogfuncs, sv.worldmodel->name, 0); + ent->v->model = PR_NewString(svprogfuncs, sv.world.worldmodel->name, 0); ent->v->modelindex = 1; // world model ent->v->solid = SOLID_BSP; ent->v->movetype = MOVETYPE_PUSH; @@ -1224,7 +1224,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us spawnflagmask = SPAWNFLAG_NOT_DEATHMATCH; //do this and get the precaches/start up the game if (sv_loadentfiles.value) - file = COM_LoadMallocFile(va("maps/%s.ent", server)); + file = FS_LoadMallocFile(va("maps/%s.ent", server)); else file = NULL; if (file) @@ -1238,7 +1238,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us break; case GT_Q1QVM: case GT_PROGS: - pr_edict_size = PR_LoadEnts(svprogfuncs, file, spawnflagmask); + sv.world.edict_size = PR_LoadEnts(svprogfuncs, file, spawnflagmask); break; case GT_QUAKE2: #ifdef Q2SERVER @@ -1264,18 +1264,18 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us break; case GT_Q1QVM: case GT_PROGS: - pr_edict_size = PR_LoadEnts(svprogfuncs, sv.worldmodel->entities, spawnflagmask); + sv.world.edict_size = PR_LoadEnts(svprogfuncs, sv.world.worldmodel->entities, spawnflagmask); break; case GT_QUAKE2: #ifdef Q2SERVER - ge->SpawnEntities(sv.name, sv.worldmodel->entities, startspot?startspot:""); + ge->SpawnEntities(sv.name, sv.world.worldmodel->entities, startspot?startspot:""); #endif break; case GT_QUAKE3: break; case GT_HALFLIFE: #ifdef HLSERVER - SVHL_SpawnEntities(sv.worldmodel->entities); + SVHL_SpawnEntities(sv.world.worldmodel->entities); #endif break; } @@ -1404,12 +1404,12 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us sv_player->xv->clientcolors = atoi(Info_ValueForKey(host_client->userinfo, "topcolor"))*16 + atoi(Info_ValueForKey(host_client->userinfo, "bottomcolor")); // call the spawn function - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player); PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect); // actually spawn the player - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player); PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer); diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 386200e1..7c5ab6de 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -176,7 +176,7 @@ cvar_t fraglimit = SCVARF("fraglimit", "" , CVAR_SERVERINFO); cvar_t timelimit = SCVARF("timelimit", "" , CVAR_SERVERINFO); cvar_t teamplay = SCVARF("teamplay", "" , CVAR_SERVERINFO); cvar_t samelevel = SCVARF("samelevel", "" , CVAR_SERVERINFO); -cvar_t maxclients = SCVARF("maxclients", "8", CVAR_SERVERINFO); +cvar_t maxclients = FCVAR("maxclients","sv_maxclients","8",CVAR_SERVERINFO); cvar_t maxspectators = SCVARF("maxspectators", "8", CVAR_SERVERINFO); #ifdef SERVERONLY cvar_t deathmatch = SCVARF("deathmatch", "1", CVAR_SERVERINFO); // 0, 1, or 2 @@ -188,6 +188,7 @@ cvar_t skill = SCVARF("skill", "" , CVAR_SERVERINFO); // 0, 1, 2 or 3 cvar_t spawn = SCVARF("spawn", "" , CVAR_SERVERINFO); cvar_t watervis = SCVARF("watervis", "" , CVAR_SERVERINFO); cvar_t rearview = SCVARF("rearview", "" , CVAR_SERVERINFO); +cvar_t allow_fish = SCVARF("allow_fish", "0", CVAR_SERVERINFO); cvar_t allow_luma = SCVARF("allow_luma", "1", CVAR_SERVERINFO); cvar_t allow_bump = SCVARF("allow_bump", "1", CVAR_SERVERINFO); cvar_t allow_skybox = SCVARF("allow_skybox", "", CVAR_SERVERINFO); @@ -317,8 +318,8 @@ void VARGS SV_Error (char *error, ...) inerror = false; Host_EndGame("SV_Error: %s\n",string); - return; } + SCR_EndLoadingPlaque(); if (!isDedicated) //dedicated servers crash... { @@ -326,7 +327,6 @@ void VARGS SV_Error (char *error, ...) SCR_EndLoadingPlaque(); inerror=false; longjmp (host_abort, 1); - return; } #endif @@ -477,7 +477,7 @@ void SV_DropClient (client_t *drop) } if (progstype == PROG_NQ) - ED_ClearEdict(svprogfuncs, drop->edict); + ED_Clear(svprogfuncs, drop->edict); } if (drop->spawninfo) @@ -524,6 +524,7 @@ void SV_DropClient (client_t *drop) if (drop->netchan.remote_address.type == NA_LOOPBACK) { Netchan_Transmit(&drop->netchan, 0, "", SV_RateForClient(drop)); +#pragma message("This mans that we may not see the reason we kicked ourselves.") CL_Disconnect(); drop->state = cs_free; //don't do zombie stuff } @@ -1355,6 +1356,17 @@ void SVC_GetChallenge (void) memcpy(over, &lng, sizeof(lng)); over+=sizeof(lng); } + //tell the client what fte extensions we support + if (svs.fteprotocolextensions2) + { + lng = LittleLong(PROTOCOL_VERSION_FTE2); + memcpy(over, &lng, sizeof(lng)); + over+=sizeof(lng); + + lng = LittleLong(svs.fteprotocolextensions2); + memcpy(over, &lng, sizeof(lng)); + over+=sizeof(lng); + } #endif #ifdef HUFFNETWORK @@ -1614,6 +1626,7 @@ client_t *SVC_DirectConnect(void) int protocol; unsigned int protextsupported=0; + unsigned int protextsupported2=0; char *name; @@ -1762,9 +1775,13 @@ client_t *SVC_DirectConnect(void) protextsupported = Q_atoi(Cmd_Argv(1)); Con_DPrintf("Client supports 0x%x fte extensions\n", protextsupported); break; + case PROTOCOL_VERSION_FTE2: + protextsupported2 = Q_atoi(Cmd_Argv(1)); + Con_DPrintf("Client supports 0x%x fte2 extensions\n", protextsupported); + break; case PROTOCOL_VERSION_HUFFMAN: huffcrc = Q_atoi(Cmd_Argv(1)); - Con_DPrintf("Client supports huffman compression\n", huffcrc); + Con_DPrintf("Client supports huffman compression. crc 0x%x\n", huffcrc); break; } } @@ -1839,6 +1856,7 @@ client_t *SVC_DirectConnect(void) newcl->userid = nextuserid; newcl->fteprotocolextensions = protextsupported; + newcl->fteprotocolextensions2 = protextsupported2; newcl->protocol = protocol; if (sv.msgfromdemo) @@ -1898,7 +1916,7 @@ client_t *SVC_DirectConnect(void) if (protocol == SCP_QUAKEWORLD &&!atoi(Info_ValueForKey (temp.userinfo, "iknow"))) { - if (sv.worldmodel->fromgame == fg_halflife && !(newcl->fteprotocolextensions & PEXT_HLBSP)) + if (sv.world.worldmodel->fromgame == fg_halflife && !(newcl->fteprotocolextensions & PEXT_HLBSP)) { if (atof(Info_ValueForKey (temp.userinfo, "*FuhQuake")) < 0.3) { @@ -1908,7 +1926,7 @@ client_t *SVC_DirectConnect(void) } } #ifdef PEXT_Q2BSP - else if (sv.worldmodel->fromgame == fg_quake2 && !(newcl->fteprotocolextensions & PEXT_Q2BSP)) + else if (sv.world.worldmodel->fromgame == fg_quake2 && !(newcl->fteprotocolextensions & PEXT_Q2BSP)) { SV_RejectMessage (protocol, "The server is using a quake 2 level and we don't think your client supports this\nuse 'setinfo iknow 1' to ignore this check\nYou can go to "ENGINEWEBSITE" to get a compatible client\n\nYou may need to enable an option\n\n"); // Con_Printf("player %s was dropped due to incompatible client\n", name); @@ -1916,7 +1934,7 @@ client_t *SVC_DirectConnect(void) } #endif #ifdef PEXT_Q3BSP - else if (sv.worldmodel->fromgame == fg_quake3 && !(newcl->fteprotocolextensions & PEXT_Q3BSP)) + else if (sv.world.worldmodel->fromgame == fg_quake3 && !(newcl->fteprotocolextensions & PEXT_Q3BSP)) { SV_RejectMessage (protocol, "The server is using a quake 3 level and we don't think your client supports this\nuse 'setinfo iknow 1' to ignore this check\nYou can go to "ENGINEWEBSITE" to get a compatible client\n\nYou may need to enable an option\n\n"); // Con_Printf("player %s was dropped due to incompatible client\n", name); @@ -2491,7 +2509,7 @@ void SVC_RemoteCommand (void) strcat (remaining, " "); } - Cmd_ExecuteString (remaining, rcon_level.value); + Cmd_ExecuteString (remaining, rcon_level.ival); } @@ -2842,13 +2860,14 @@ SV_ReadPackets */ //FIMXE: move to header qboolean SV_GetPacket (void); -void SV_ReadPackets (void) +qboolean SV_ReadPackets (void) { int i; client_t *cl; int qport; laggedpacket_t *lp; char *banreason; + qboolean received = false; for (i = 0; i < MAX_CLIENTS; i++) //fixme: shouldn't we be using svs.allocated_client_slots ? { @@ -2871,6 +2890,7 @@ void SV_ReadPackets (void) if (Netchan_Process(&cl->netchan)) { // this is a valid, sequenced packet, so process it + received++; svs.stats.packets++; if (cl->state > cs_zombie) { //make sure they didn't already disconnect @@ -2909,6 +2929,7 @@ void SV_ReadPackets (void) #ifdef Q3SERVER if (svs.gametype == GT_QUAKE3) { + received++; SVQ3_HandleClient(); continue; } @@ -2935,6 +2956,7 @@ void SV_ReadPackets (void) { if (NQNetChan_Process(&cl->netchan)) { + received++; svs.stats.packets++; SVNQ_ExecuteClientMessage(cl); } @@ -2949,6 +2971,7 @@ void SV_ReadPackets (void) #pragma message("qwoverq3: fixme: this will block qw+q3 clients from the same ip") if (cl->state != cs_zombie) { + received++; SVQ3_HandleClient(); } break; @@ -2992,6 +3015,7 @@ void SV_ReadPackets (void) if (Netchan_Process(&cl->netchan)) { // this is a valid, sequenced packet, so process it + received++; svs.stats.packets++; if (cl->state != cs_zombie) { @@ -3019,6 +3043,8 @@ void SV_ReadPackets (void) // Con_Printf ("%s:sequenced packet without connection\n" // ,NET_AdrToString(net_from)); } + + return received; } /* @@ -3073,7 +3099,8 @@ void SV_CheckTimeouts (void) } } } - if (sv.paused && !nclients) { + if (sv.paused && !nclients) + { // nobody left, unpause the server if (SV_TogglePause(NULL)) SV_BroadcastTPrintf(PRINT_HIGH, STL_CLIENTLESSUNPAUSE); @@ -3198,7 +3225,7 @@ void SV_Impulse_f (void) if (!svprogfuncs) return; - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; svs.clients[i].state = cs_connected; @@ -3209,7 +3236,7 @@ void SV_Impulse_f (void) pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, svs.clients[i].edict); PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect); - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, svs.clients[i].edict); PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer); @@ -3246,6 +3273,7 @@ void SV_Frame (void) extern cvar_t pr_imitatemvdsv; static double start, end; float oldtime; + qboolean isidle; start = Sys_DoubleTime (); svs.stats.idle += start - end; @@ -3283,10 +3311,10 @@ void SV_Frame (void) IWebRun(); #endif - if (sv_master.value) + if (sv_master.ival) { - if (sv_masterport.value) - SVM_Think(sv_masterport.value); + if (sv_masterport.ival) + SVM_Think(sv_masterport.ival); else SVM_Think(PORT_MASTER); } @@ -3296,7 +3324,7 @@ void SV_MVDStream_Poll(void); SV_MVDStream_Poll(); } - if (sv.state < ss_active || !sv.worldmodel) + if (sv.state < ss_active || !sv.world.worldmodel) { #ifndef SERVERONLY // check for commands typed to the host @@ -3322,9 +3350,9 @@ void SV_MVDStream_Poll(void); SV_CheckLog (); // get packets - SV_ReadPackets (); + isidle = !SV_ReadPackets (); - if (pr_imitatemvdsv.value) + if (pr_imitatemvdsv.ival) { Cbuf_Execute (); if (sv.state < ss_active) //whoops... @@ -3340,8 +3368,13 @@ void SV_MVDStream_Poll(void); // move autonomous things around if enough time has passed if (!sv.paused) { +#ifdef Q2SERVER + //q2 is idle even if clients sent packets. + if (svs.gametype == GT_QUAKE2) + isidle = true; +#endif if (SV_Physics ()) - return; + isidle = false; } else { @@ -3357,55 +3390,59 @@ void SV_MVDStream_Poll(void); } } + if (!isidle) + { + #ifdef SQL - PR_SQLCycle(); + PR_SQLCycle(); #endif - while(SV_ReadMVD()); + while(SV_ReadMVD()); - if (sv.multicast.cursize) - { - Con_Printf("Unterminated multicast\n"); - sv.multicast.cursize=0; - } + if (sv.multicast.cursize) + { + Con_Printf("Unterminated multicast\n"); + sv.multicast.cursize=0; + } #ifndef SERVERONLY // check for commands typed to the host - if (isDedicated) + if (isDedicated) #endif - { + { #ifdef PLUGINS - Plug_Tick(); + Plug_Tick(); #endif - SV_GetConsoleCommands (); + SV_GetConsoleCommands (); // process console commands - if (!pr_imitatemvdsv.value) - Cbuf_Execute (); - } + if (!pr_imitatemvdsv.value) + Cbuf_Execute (); + } - if (sv.state < ss_active) //whoops... - return; + if (sv.state < ss_active) //whoops... + return; - SV_CheckVars (); + SV_CheckVars (); // send messages back to the clients that had packets read this frame - SV_SendClientMessages (); + SV_SendClientMessages (); // demo_start = Sys_DoubleTime (); - SV_SendMVDMessage(); + SV_SendMVDMessage(); // demo_end = Sys_DoubleTime (); // svs.stats.demo += demo_end - demo_start; // send a heartbeat to the master if needed - Master_Heartbeat (); + Master_Heartbeat (); #ifdef Q2SERVER - if (ge && ge->edicts) - SVQ2_ClearEvents(); + if (ge && ge->edicts) + SVQ2_ClearEvents(); #endif + } // collect timing statistics end = Sys_DoubleTime (); @@ -3488,6 +3525,7 @@ void SV_InitLocal (void) Cvar_Register (&watervis, cvargroup_serverinfo); Cvar_Register (&rearview, cvargroup_serverinfo); Cvar_Register (&mirrors, cvargroup_serverinfo); + Cvar_Register (&allow_fish, cvargroup_serverinfo); Cvar_Register (&allow_luma, cvargroup_serverinfo); Cvar_Register (&allow_bump, cvargroup_serverinfo); Cvar_Register (&allow_skybox, cvargroup_serverinfo); @@ -3693,6 +3731,8 @@ void SV_InitLocal (void) svs.fteprotocolextensions |= PEXT_DPFLAGS; #endif + svs.fteprotocolextensions2 |= PEXT2_PRYDONCURSOR; + // if (svs.protocolextensions) // Info_SetValueForStarKey (svs.info, "*"DISTRIBUTION"_ext", va("%x", svs.protocolextensions), MAX_SERVERINFO_STRING); diff --git a/engine/server/sv_move.c b/engine/server/sv_move.c index 7a8c9458..d22d7a2e 100644 --- a/engine/server/sv_move.c +++ b/engine/server/sv_move.c @@ -54,7 +54,7 @@ qboolean SV_CheckBottom (edict_t *ent) { start[0] = x ? maxs[0] : mins[0]; start[1] = y ? maxs[1] : mins[1]; - if (!(SV_PointContents (start) & FTECONTENTS_SOLID)) + if (!(World_PointContents (&sv.world, start) & FTECONTENTS_SOLID)) goto realcheck; } @@ -74,7 +74,7 @@ realcheck: stop[2] = start[2] - 2*movevars.stepheight; savedhull = ent->xv->hull; ent->xv->hull = 0; - trace = SV_Move (start, vec3_origin, vec3_origin, stop, true, ent); + trace = World_Move (&sv.world, start, vec3_origin, vec3_origin, stop, true, (wedict_t*)ent); ent->xv->hull = savedhull; if (trace.fraction == 1.0) @@ -90,7 +90,7 @@ realcheck: savedhull = ent->xv->hull; ent->xv->hull = 0; - trace = SV_Move (start, vec3_origin, vec3_origin, stop, true, ent); + trace = World_Move (&sv.world, start, vec3_origin, vec3_origin, stop, true, (wedict_t*)ent); ent->xv->hull = savedhull; if (trace.fraction != 1.0 && trace.endpos[2] > bottom) @@ -117,7 +117,7 @@ void set_move_trace(trace_t *trace, struct globalvars_s *pr_globals) if (trace->ent) pr_global_struct->trace_ent = EDICT_TO_PROG(svprogfuncs, trace->ent); else - pr_global_struct->trace_ent = EDICT_TO_PROG(svprogfuncs, sv.edicts); + pr_global_struct->trace_ent = EDICT_TO_PROG(svprogfuncs, sv.world.edicts); } /* @@ -136,7 +136,7 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink, qboolean noene vec3_t oldorg, neworg, end; trace_t trace; int i; - edict_t *enemy = sv.edicts; + edict_t *enemy = (edict_t*)sv.world.edicts; // try the move VectorCopy (ent->v->origin, oldorg); @@ -152,7 +152,7 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink, qboolean noene if (!noenemy) { enemy = PROG_TO_EDICT(svprogfuncs, ent->v->enemy); - if (i == 0 && enemy != sv.edicts) + if (i == 0 && enemy != (edict_t*)sv.world.edicts) { dz = ent->v->origin[2] - PROG_TO_EDICT(svprogfuncs, ent->v->enemy)->v->origin[2]; if (dz > 40) @@ -161,22 +161,22 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink, qboolean noene neworg[2] += 8; } } - trace = SV_Move (ent->v->origin, ent->v->mins, ent->v->maxs, neworg, false, ent); + trace = World_Move (&sv.world, ent->v->origin, ent->v->mins, ent->v->maxs, neworg, false, (wedict_t*)ent); if (set_trace) set_move_trace(&trace, set_trace); if (trace.fraction == 1) { - if ( ((int)ent->v->flags & FL_SWIM) && !(SV_PointContents(trace.endpos) & FTECONTENTS_FLUID)) + if ( ((int)ent->v->flags & FL_SWIM) && !(World_PointContents(&sv.world, trace.endpos) & FTECONTENTS_FLUID)) return false; // swim monster left water VectorCopy (trace.endpos, ent->v->origin); if (relink) - SV_LinkEdict (ent, true); + World_LinkEdict (&sv.world, (wedict_t*)ent, true); return true; } - if (noenemy || enemy == sv.edicts) + if (noenemy || enemy == (edict_t*)sv.world.edicts) break; } @@ -188,7 +188,7 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink, qboolean noene VectorCopy (neworg, end); end[2] -= movevars.stepheight*2; - trace = SV_Move (neworg, ent->v->mins, ent->v->maxs, end, false, ent); + trace = World_Move (&sv.world, neworg, ent->v->mins, ent->v->maxs, end, false, (wedict_t*)ent); if (set_trace) set_move_trace(&trace, set_trace); @@ -198,7 +198,7 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink, qboolean noene if (trace.startsolid) { neworg[2] -= movevars.stepheight; - trace = SV_Move (neworg, ent->v->mins, ent->v->maxs, end, false, ent); + trace = World_Move (&sv.world, neworg, ent->v->mins, ent->v->maxs, end, false, (wedict_t*)ent); if (set_trace) set_move_trace(&trace, set_trace); if (trace.allsolid || trace.startsolid) @@ -211,7 +211,7 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink, qboolean noene { VectorAdd (ent->v->origin, move, ent->v->origin); if (relink) - SV_LinkEdict (ent, true); + World_LinkEdict (&sv.world, (wedict_t*)ent, true); ent->v->flags = (int)ent->v->flags & ~FL_ONGROUND; // Con_Printf ("fall down\n"); return true; @@ -229,7 +229,7 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink, qboolean noene { // entity had floor mostly pulled out from underneath it // and is trying to correct if (relink) - SV_LinkEdict (ent, true); + World_LinkEdict (&sv.world, (wedict_t*)ent, true); return true; } VectorCopy (oldorg, ent->v->origin); @@ -245,7 +245,7 @@ qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink, qboolean noene // the move is ok if (relink) - SV_LinkEdict (ent, true); + World_LinkEdict (&sv.world, (wedict_t*)ent, true); return true; } @@ -284,10 +284,10 @@ qboolean SV_StepDirection (edict_t *ent, float yaw, float dist, struct globalvar { // not turned far enough, so don't take the step VectorCopy (oldorigin, ent->v->origin); } - SV_LinkEdict (ent, true); + World_LinkEdict (&sv.world, (wedict_t*)ent, true); return true; } - SV_LinkEdict (ent, true); + World_LinkEdict (&sv.world, (wedict_t*)ent, true); return false; } @@ -440,7 +440,7 @@ void SV_MoveToGoal (progfuncs_t *prinst, struct globalvars_s *pr_globals) } // if the next step hits the enemy, return immediately - if ( PROG_TO_EDICT(svprogfuncs, ent->v->enemy) != sv.edicts && SV_CloseEnough (ent, goal, dist) ) + if ( PROG_TO_EDICT(svprogfuncs, ent->v->enemy) != (edict_t*)sv.world.edicts && SV_CloseEnough (ent, goal, dist) ) return; // bump around... diff --git a/engine/server/sv_mvd.c b/engine/server/sv_mvd.c index b8688831..bb247d63 100644 --- a/engine/server/sv_mvd.c +++ b/engine/server/sv_mvd.c @@ -1749,7 +1749,7 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest) memset(&from, 0, sizeof(from)); - for (n = 0; n < sv.num_edicts; n++) + for (n = 0; n < sv.world.num_edicts; n++) { ent = EDICT_NUM(svprogfuncs, n); state = &ent->baseline; @@ -2316,16 +2316,16 @@ void SV_MVDStream_Poll(void) char *ip; char adrbuf[MAX_ADR_SIZE]; - if (!sv.state || !qtv_streamport.value) + if (!sv.state || !qtv_streamport.ival) wanted = false; - else if (listenport && (int)qtv_streamport.value != listenport) //easy way to switch... disable for a frame. :) + else if (listenport && qtv_streamport.ival != listenport) //easy way to switch... disable for a frame. :) { - listenport = qtv_streamport.value; + listenport = qtv_streamport.ival; wanted = false; } else { - listenport = qtv_streamport.value; + listenport = qtv_streamport.ival; wanted = true; } diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index 7cec48f1..b74f4b17 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -80,7 +80,7 @@ void SV_CheckAllEnts (void) edict_t *check; // see if any solid entities are inside the final position - for (e=1 ; eisfree) @@ -91,7 +91,7 @@ void SV_CheckAllEnts (void) || check->v->movetype == MOVETYPE_NOCLIP) continue; - if (SV_TestEntityPosition (check)) + if (World_TestEntityPosition (&sv.world, (wedict_t*)check)) Con_Printf ("entity in invalid position\n"); } } @@ -146,17 +146,17 @@ qboolean SV_RunThink (edict_t *ent) if (sv_nomsec.value>=2) //try and imitate nq as closeley as possible { thinktime = ent->v->nextthink; - if (thinktime <= 0 || thinktime > sv.physicstime + host_frametime) + if (thinktime <= 0 || thinktime > sv.world.physicstime + host_frametime) return true; - if (thinktime < sv.physicstime) - thinktime = sv.physicstime; // don't let things stay in the past. + if (thinktime < sv.world.physicstime) + thinktime = sv.world.physicstime; // don't let things stay in the past. // it is possible to start that way // by a trigger with a local time. ent->v->nextthink = 0; pr_global_struct->time = thinktime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent); - pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.edicts); + pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.world.edicts); #ifdef VM_Q1 if (svs.gametype == GT_Q1QVM) Q1QVM_Think(); @@ -171,18 +171,18 @@ qboolean SV_RunThink (edict_t *ent) thinktime = ent->v->nextthink; if (thinktime <= 0) return true; - if (thinktime > sv.physicstime + host_frametime) + if (thinktime > sv.world.physicstime + host_frametime) return true; - if (thinktime < sv.physicstime) - thinktime = sv.physicstime; // don't let things stay in the past. + if (thinktime < sv.world.physicstime) + thinktime = sv.world.physicstime; // don't let things stay in the past. // it is possible to start that way // by a trigger with a local time. ent->v->nextthink = 0; pr_global_struct->time = thinktime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent); - pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.edicts); + pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.world.edicts); #ifdef VM_Q1 if (svs.gametype == GT_Q1QVM) Q1QVM_Think(); @@ -214,7 +214,7 @@ void SV_Impact (edict_t *e1, edict_t *e2) old_self = pr_global_struct->self; old_other = pr_global_struct->other; - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; if (e1->v->touch && e1->v->solid != SOLID_NOT) { pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, e1); @@ -314,7 +314,7 @@ int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) for (i=0 ; i<3 ; i++) end[i] = ent->v->origin[i] + time_left * ent->v->velocity[i]; - trace = SV_Move (ent->v->origin, ent->v->mins, ent->v->maxs, end, false, ent); + trace = World_Move (&sv.world, ent->v->origin, ent->v->mins, ent->v->maxs, end, false, (wedict_t*)ent); if (trace.startsolid) { // entity is trapped in another solid @@ -471,26 +471,29 @@ SV_PushEntity Does not change the entities velocity at all ============ */ -trace_t SV_PushEntity (edict_t *ent, vec3_t push) +trace_t SV_PushEntity (edict_t *ent, vec3_t push, unsigned int traceflags) { trace_t trace; vec3_t end; VectorAdd (ent->v->origin, push, end); + if ((int)ent->v->flags&FL_LAGGEDMOVE) + traceflags |= MOVE_LAGGED; + if (ent->v->movetype == MOVETYPE_FLYMISSILE) - trace = SV_Move (ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_MISSILE, ent); + trace = World_Move (&sv.world, ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_MISSILE|traceflags, (wedict_t*)ent); else if (ent->v->solid == SOLID_TRIGGER || ent->v->solid == SOLID_NOT) // only clip against bmodels - trace = SV_Move (ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NOMONSTERS, ent); + trace = World_Move (&sv.world, ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NOMONSTERS|traceflags, (wedict_t*)ent); else - trace = SV_Move (ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent); + trace = World_Move (&sv.world, ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL|traceflags, (wedict_t*)ent); // if (trace.ent) // VectorMA(trace.endpos, sv_impactpush.value, trace.plane.normal, ent->v->origin); // else VectorCopy (trace.endpos, ent->v->origin); - SV_LinkEdict (ent, true); + World_LinkEdict (&sv.world, (wedict_t*)ent, true); if (trace.ent) SV_Impact (ent, trace.ent); @@ -551,10 +554,10 @@ qboolean SV_PushAngles (edict_t *pusher, vec3_t move, vec3_t amove) // move the pusher to it's final position VectorAdd (pusher->v->origin, move, pusher->v->origin); VectorAdd (pusher->v->angles, amove, pusher->v->angles); - SV_LinkEdict (pusher, false); + World_LinkEdict (&sv.world, (wedict_t*)pusher, false); // see if any solid entities are inside the final position - for (e = 1; e < sv.num_edicts; e++) + for (e = 1; e < sv.world.num_edicts; e++) { check = EDICT_NUM(svprogfuncs, e); if (check->isfree) @@ -568,7 +571,7 @@ qboolean SV_PushAngles (edict_t *pusher, vec3_t move, vec3_t amove) #if 1 oldsolid = pusher->v->solid; pusher->v->solid = SOLID_NOT; - block = SV_TestEntityPosition (check); + block = (edict_t*)World_TestEntityPosition (&sv.world, (wedict_t*)check); pusher->v->solid = oldsolid; if (block) continue; @@ -592,7 +595,7 @@ qboolean SV_PushAngles (edict_t *pusher, vec3_t move, vec3_t amove) // see if the ent's bbox is inside the pusher's final position - if (!SV_TestEntityPosition (check)) + if (!World_TestEntityPosition (&sv.world, (wedict_t*)check)) continue; } @@ -626,10 +629,10 @@ qboolean SV_PushAngles (edict_t *pusher, vec3_t move, vec3_t amove) if (PROG_TO_EDICT(svprogfuncs, check->v->groundentity) != pusher) check->v->groundentity = 0; - block = SV_TestEntityPosition (check); + block = (edict_t*)World_TestEntityPosition (&sv.world, (wedict_t*)check); if (!block) { // pushed ok - SV_LinkEdict (check, false); + World_LinkEdict (&sv.world, (wedict_t*)check, false); // impact? continue; } @@ -640,7 +643,7 @@ qboolean SV_PushAngles (edict_t *pusher, vec3_t move, vec3_t amove) // this is only relevent for riding entities, not pushed // FIXME: this doesn't acount for rotation VectorSubtract (check->v->origin, move, check->v->origin); - block = SV_TestEntityPosition (check); + block = (edict_t*)World_TestEntityPosition (&sv.world, (wedict_t*)check); if (!block) { pushed_p--; @@ -651,7 +654,7 @@ qboolean SV_PushAngles (edict_t *pusher, vec3_t move, vec3_t amove) // if it is sitting on top. Do not block. if (check->v->mins[0] == check->v->maxs[0]) { - SV_LinkEdict (check, false); + World_LinkEdict (&sv.world, (wedict_t*)check, false); continue; } @@ -679,7 +682,7 @@ qboolean SV_PushAngles (edict_t *pusher, vec3_t move, vec3_t amove) // { // p->ent->client->ps.pmove.delta_angles[YAW] = p->deltayaw; // } - SV_LinkEdict (p->ent, false); + World_LinkEdict (&sv.world, (wedict_t*)p->ent, false); } return false; } @@ -687,7 +690,7 @@ qboolean SV_PushAngles (edict_t *pusher, vec3_t move, vec3_t amove) //FIXME: is there a better way to handle this? // see if anything we moved has touched a trigger for (p=pushed_p-1 ; p>=pushed ; p--) - SV_TouchLinks ( p->ent, sv_areanodes ); + World_TouchLinks (&sv.world, (wedict_t*)p->ent, sv.world.areanodes ); return true; } @@ -725,11 +728,11 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove) // move the pusher to it's final position VectorAdd (pusher->v->origin, move, pusher->v->origin); - SV_LinkEdict (pusher, false); + World_LinkEdict (&sv.world, (wedict_t*)pusher, false); // see if any solid entities are inside the final position num_moved = 0; - for (e=1 ; eisfree) @@ -742,7 +745,7 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove) oldsolid = pusher->v->solid; pusher->v->solid = SOLID_NOT; - block = SV_TestEntityPosition (check); + block = (edict_t*)World_TestEntityPosition (&sv.world, (wedict_t*)check); pusher->v->solid = oldsolid; if (block) continue; @@ -761,7 +764,7 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove) continue; // see if the ent's bbox is inside the pusher's final position - if (!SV_TestEntityPosition (check)) + if (!World_TestEntityPosition (&sv.world, (wedict_t*)check)) continue; } @@ -773,16 +776,16 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove) // try moving the contacted entity VectorAdd (check->v->origin, move, check->v->origin); - block = SV_TestEntityPosition (check); + block = (edict_t*)World_TestEntityPosition (&sv.world, (wedict_t*)check); if (!block) { // pushed ok - SV_LinkEdict (check, false); + World_LinkEdict (&sv.world, (wedict_t*)check, false); continue; } // if it is ok to leave in the old position, do it VectorSubtract (check->v->origin, move, check->v->origin); - block = SV_TestEntityPosition (check); + block = (edict_t*)World_TestEntityPosition (&sv.world, (wedict_t*)check); if (!block) { //if leaving it where it was, allow it to drop to the floor again (useful for plats that move downward) @@ -795,19 +798,19 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove) // if it is still inside the pusher, block if (check->v->mins[0] == check->v->maxs[0]) { - SV_LinkEdict (check, false); + World_LinkEdict (&sv.world, (wedict_t*)check, false); continue; } if (check->v->solid == SOLID_NOT || check->v->solid == SOLID_TRIGGER) { // corpse check->v->mins[0] = check->v->mins[1] = 0; VectorCopy (check->v->mins, check->v->maxs); - SV_LinkEdict (check, false); + World_LinkEdict (&sv.world, (wedict_t*)check, false); continue; } VectorCopy (pushorig, pusher->v->origin); - SV_LinkEdict (pusher, false); + World_LinkEdict (&sv.world, (wedict_t*)pusher, false); // if the pusher has a "blocked" function, call it // otherwise, just stay in place until the obstacle is gone @@ -827,7 +830,7 @@ qboolean SV_Push (edict_t *pusher, vec3_t move, vec3_t amove) for (i=0 ; iv->origin); - SV_LinkEdict (moved_edict[i], false); + World_LinkEdict (&sv.world, (wedict_t*)moved_edict[i], false); } return false; } @@ -903,9 +906,9 @@ float l; VectorCopy (ent->v->origin, oldorg); VectorCopy (ent->v->angles, oldang); ent->v->nextthink = 0; - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent); - pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.edicts); + pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.world.edicts); #ifdef VM_Q1 if (svs.gametype == GT_Q1QVM) Q1QVM_Think(); @@ -971,7 +974,7 @@ void SV_Physics_Follow (edict_t *ent) ent->v->origin[2] = v[0] * vu[0] + v[1] * vu[1] + v[2] * vu[2] + e->v->origin[2]; } VectorAdd (e->v->angles, ent->v->v_angle, ent->v->angles); - SV_LinkEdict (ent, true); + World_LinkEdict (&sv.world, (wedict_t*)ent, true); } /* @@ -990,7 +993,7 @@ void SV_Physics_Noclip (edict_t *ent) VectorMA (ent->v->angles, host_frametime, ent->v->avelocity, ent->v->angles); VectorMA (ent->v->origin, host_frametime, ent->v->velocity, ent->v->origin); - SV_LinkEdict (ent, false); + World_LinkEdict (&sv.world, (wedict_t*)ent, false); } /* @@ -1011,7 +1014,7 @@ void SV_CheckWaterTransition (edict_t *ent) { int cont; - cont = SV_PointContents (ent->v->origin); + cont = World_PointContents (&sv.world, ent->v->origin); //needs to be q1 progs compatible if (cont & FTECONTENTS_LAVA) @@ -1104,7 +1107,8 @@ void SV_Physics_Toss (edict_t *ent) VectorScale (ent->v->velocity, host_frametime, move); VectorCopy(ent->v->origin, temporg); VectorCopy(temporg, ent->v->origin); - trace = SV_PushEntity (ent, move); + + trace = SV_PushEntity (ent, move, (sv_antilag.ival==2)?MOVE_LAGGED:0); if (trace.allsolid) trace.fraction = 0; @@ -1176,7 +1180,7 @@ void SV_Physics_Step (edict_t *ent) SV_AddGravity (ent, 1.0); SV_CheckVelocity (ent); SV_FlyMove (ent, host_frametime, NULL); - SV_LinkEdict (ent, true); + World_LinkEdict (&sv.world, (wedict_t*)ent, true); if ( (int)ent->v->flags & FL_ONGROUND ) // just hit ground { @@ -1202,9 +1206,9 @@ void SV_ProgStartFrame (void) { // let the progs know that a new frame has started - pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.edicts); - pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.edicts); - pr_global_struct->time = sv.physicstime; + pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.world.edicts); + pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.world.edicts); + pr_global_struct->time = sv.world.physicstime; #ifdef VM_Q1 if (svs.gametype == GT_Q1QVM) Q1QVM_StartFrame(); @@ -1239,7 +1243,7 @@ void SV_CheckStuck (edict_t *ent) int z; vec3_t org; //return; - if (!SV_TestEntityPosition(ent)) + if (!World_TestEntityPosition (&sv.world, (wedict_t*)ent)) { VectorCopy (ent->v->origin, ent->v->oldorigin); return; @@ -1247,10 +1251,10 @@ void SV_CheckStuck (edict_t *ent) VectorCopy (ent->v->origin, org); VectorCopy (ent->v->oldorigin, ent->v->origin); - if (!SV_TestEntityPosition(ent)) + if (!World_TestEntityPosition (&sv.world, (wedict_t*)ent)) { Con_DPrintf ("Unstuck.\n"); - SV_LinkEdict (ent, true); + World_LinkEdict (&sv.world, (wedict_t*)ent, true); return; } @@ -1261,10 +1265,10 @@ void SV_CheckStuck (edict_t *ent) ent->v->origin[0] = org[0] + i; ent->v->origin[1] = org[1] + j; ent->v->origin[2] = org[2] + z; - if (!SV_TestEntityPosition(ent)) + if (!World_TestEntityPosition (&sv.world, (wedict_t*)ent)) { Con_DPrintf ("Unstuck.\n"); - SV_LinkEdict (ent, true); + World_LinkEdict (&sv.world, (wedict_t*)ent, true); return; } } @@ -1289,7 +1293,7 @@ qboolean SV_CheckWater (edict_t *ent) ent->v->waterlevel = 0; ent->v->watertype = Q1CONTENTS_EMPTY; - cont = SV_PointContents (point); + cont = World_PointContents (&sv.world, point); if (cont & FTECONTENTS_FLUID) { if (cont & FTECONTENTS_LAVA) @@ -1302,12 +1306,12 @@ qboolean SV_CheckWater (edict_t *ent) ent->v->watertype = Q1CONTENTS_SKY; ent->v->waterlevel = 1; point[2] = ent->v->origin[2] + (ent->v->mins[2] + ent->v->maxs[2])*0.5; - cont = SV_PointContents (point); + cont = World_PointContents (&sv.world, point); if (cont & FTECONTENTS_FLUID) { ent->v->waterlevel = 2; point[2] = ent->v->origin[2] + ent->v->view_ofs[2]; - cont = SV_PointContents (point); + cont = World_PointContents (&sv.world, point); if (cont & FTECONTENTS_FLUID) ent->v->waterlevel = 3; } @@ -1383,7 +1387,7 @@ int SV_TryUnstick (edict_t *ent, vec3_t oldvel) case 7: dir[0] = -2; dir[1] = -2; break; } - SV_PushEntity (ent, dir); + SV_PushEntity (ent, dir, MOVE_NORMAL); // retry the original move ent->v->velocity[0] = oldvel[0]; @@ -1583,7 +1587,7 @@ int SV_SetOnGround (edict_t *ent) end[0] = ent->v->origin[0]; end[1] = ent->v->origin[1]; end[2] = ent->v->origin[2] - 1; - trace = SV_Move(ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, ent); + trace = World_Move(&sv.world, ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, (wedict_t*)ent); if (trace.fraction <= DIST_EPSILON && trace.plane.normal[2] >= 0.7) { ent->v->flags = (int)ent->v->flags | FL_ONGROUND; @@ -1652,7 +1656,7 @@ void SV_WalkMove (edict_t *ent) VectorClear (upmove); upmove[2] = movevars.stepheight; // FIXME: don't link? - SV_PushEntity(ent, upmove); + SV_PushEntity(ent, upmove, MOVE_NORMAL); // move forward ent->v->velocity[2] = 0; @@ -1695,7 +1699,7 @@ void SV_WalkMove (edict_t *ent) VectorClear (downmove); downmove[2] = -movevars.stepheight + start_velocity[2]*host_frametime; // FIXME: don't link? - downtrace = SV_PushEntity (ent, downmove); + downtrace = SV_PushEntity (ent, downmove, MOVE_NORMAL); if (downtrace.fraction < 1 && downtrace.plane.normal[2] > 0.7) { @@ -1735,7 +1739,7 @@ void SV_MoveChain(edict_t *ent, edict_t *movechain, float *initial_origin, float VectorSubtract(ent->v->angles, initial_angle, moveang); VectorSubtract(ent->v->origin, initial_origin, moveorg); - for(i=16;i && movechain != sv.edicts && !movechain->isfree;i--, movechain = PROG_TO_EDICT(svprogfuncs, movechain->xv->movechain)) + for(i=16;i && movechain != (edict_t*)sv.world.edicts && !movechain->isfree;i--, movechain = PROG_TO_EDICT(svprogfuncs, movechain->xv->movechain)) { if ((int)movechain->v->flags & FL_MOVECHAIN_ANGLE) VectorAdd(movechain->v->angles, moveang, movechain->v->angles); @@ -1791,7 +1795,7 @@ void SV_RunEntity (edict_t *ent) // // call standard client pre-think // - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent); #ifdef VM_Q1 if (svs.gametype == GT_Q1QVM) @@ -1817,7 +1821,7 @@ void SV_RunEntity (edict_t *ent) movechain = PROG_TO_EDICT(svprogfuncs, ent->xv->movechain); - if (movechain != sv.edicts) + if (movechain != (edict_t*)sv.world.edicts) { VectorCopy(ent->v->origin,initial_origin); VectorCopy(ent->v->angles,initial_angle); @@ -1860,23 +1864,27 @@ void SV_RunEntity (edict_t *ent) SV_WalkMove (ent); if (!(ent->entnum > 0 && ent->entnum <= sv.allocated_client_slots)) - SV_LinkEdict (ent, true); + World_LinkEdict (&sv.world, (wedict_t*)ent, true); break; + case MOVETYPE_PHYSICS: + if (SV_RunThink(ent)) + World_LinkEdict (&sv.world, (wedict_t*)ent, true); + break; default: - SV_Error ("SV_Physics: bad movetype %i on %s", (int)ent->v->movetype, svprogfuncs->stringtable + ent->v->classname); + SV_Error ("SV_Physics: bad movetype %i on %s", (int)ent->v->movetype, PR_GetString(svprogfuncs, ent->v->classname)); } - if (movechain != sv.edicts) + if (movechain != (edict_t*)sv.world.edicts) { SV_MoveChain(ent, movechain, initial_origin, initial_angle); } if (ent->entnum > 0 && ent->entnum <= sv.allocated_client_slots) { - SV_LinkEdict (ent, true); + World_LinkEdict (&sv.world, (wedict_t*)ent, true); - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent); #ifdef VM_Q1 if (svs.gametype == GT_Q1QVM) @@ -1942,7 +1950,7 @@ trace_t SV_Trace_Toss (edict_t *tossent, edict_t *ignore) velocity[2] -= gravity; VectorScale (velocity, 0.05, move); VectorAdd (origin, move, end); - trace = SV_Move (origin, tossent->v->mins, tossent->v->maxs, end, MOVE_NORMAL, tossent); + trace = World_Move (&sv.world, origin, tossent->v->mins, tossent->v->maxs, end, MOVE_NORMAL, (wedict_t*)tossent); VectorCopy (trace.endpos, origin); if (trace.fraction < 1 && trace.ent && trace.ent != ignore) @@ -1970,26 +1978,27 @@ qboolean SV_Physics (void) int i; qboolean retouch; edict_t *ent; + qboolean moved = false; if (svs.gametype != GT_PROGS && svs.gametype != GT_Q1QVM && svs.gametype != GT_HALFLIFE) //make tics multiples of sv_maxtic (defaults to 0.1) { - host_frametime = sv.time - sv.physicstime; + host_frametime = sv.time - sv.world.physicstime; if (host_frametime<0) { if (host_frametime < -1) - sv.physicstime = sv.time; + sv.world.physicstime = sv.time; host_frametime = 0; } if (svs.gametype != GT_QUAKE3) if (host_frametime < sv_maxtic.value && realtime) { // sv.time+=host_frametime; - return true; //don't bother with the whole server thing for a bit longer + return false; //don't bother with the whole server thing for a bit longer } if (host_frametime > sv_maxtic.value) host_frametime = sv_maxtic.value; - sv.physicstime = sv.time; + sv.world.physicstime = sv.time; sv.framenum++; @@ -2008,7 +2017,7 @@ qboolean SV_Physics (void) default: break; } - return false; + return true; } if (svs.gametype != GT_HALFLIFE && /*sv.botsonthemap &&*/ progstype == PROG_QW) @@ -2067,10 +2076,10 @@ qboolean SV_Physics (void) // don't bother running a frame if sys_ticrate seconds haven't passed while (1) { - host_frametime = sv.time - sv.physicstime; + host_frametime = sv.time - sv.world.physicstime; if (host_frametime < 0) { - sv.physicstime = sv.time; + sv.world.physicstime = sv.time; break; } if (host_frametime <= 0 || host_frametime < sv_mintic.value) @@ -2079,15 +2088,17 @@ qboolean SV_Physics (void) { //cap the distance to run physics host_frametime = sv_maxtic.value; - sv.physicstime = sv.time; + sv.world.physicstime = sv.time; } else { if (host_frametime > sv_maxtic.value) host_frametime = sv_maxtic.value; - sv.physicstime += host_frametime; + sv.world.physicstime += host_frametime; } + moved = true; + #ifdef HLSERVER if (svs.gametype == GT_HALFLIFE) { @@ -2100,6 +2111,10 @@ qboolean SV_Physics (void) SV_ProgStartFrame (); +#ifdef USEODE + World_Physics_Frame(&sv.world, host_frametime, sv_gravity.value); +#endif + PR_RunThreads(); @@ -2109,7 +2124,7 @@ qboolean SV_Physics (void) // treat each object in turn // even the world gets a chance to think // - for (i=0 ; iisfree) @@ -2118,10 +2133,10 @@ qboolean SV_Physics (void) if (ent->solidtype != ent->v->solid) { // Con_Printf("Entity \"%s\" improperly changed solid type\n", svprogfuncs->stringtable+ent->v->classname); - SV_LinkEdict (ent, true); // a change of solidity should always relink the edict. someone messed up. + World_LinkEdict (&sv.world, (wedict_t*)ent, true); // a change of solidity should always relink the edict. someone messed up. } else if (retouch) - SV_LinkEdict (ent, true); // force retouch even for stationary + World_LinkEdict (&sv.world, (wedict_t*)ent, true); // force retouch even for stationary if (i > 0 && i <= sv.allocated_client_slots) { @@ -2131,7 +2146,7 @@ qboolean SV_Physics (void) SV_RunNewmis (); } else - SV_LinkEdict(ent, true); + World_LinkEdict(&sv.world, (wedict_t*)ent, true); continue; // clients are run directly from packets } @@ -2145,25 +2160,25 @@ qboolean SV_Physics (void) #ifdef VM_Q1 if (svs.gametype == GT_Q1QVM) { - pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.edicts); - pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.edicts); - pr_global_struct->time = sv.physicstime; + pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.world.edicts); + pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.world.edicts); + pr_global_struct->time = sv.world.physicstime; Q1QVM_EndFrame(); } else #endif if (EndFrameQC) { - pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.edicts); - pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.edicts); - pr_global_struct->time = sv.physicstime; + pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv.world.edicts); + pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv.world.edicts); + pr_global_struct->time = sv.world.physicstime; PR_ExecuteProgram (svprogfuncs, EndFrameQC); } NPP_Flush(); //flush it just in case there was an error and we stopped preparsing. This is only really needed while debugging. } - return false; + return moved; } void SV_SetMoveVars(void) diff --git a/engine/server/sv_send.c b/engine/server/sv_send.c index 54f1d729..93d882d0 100644 --- a/engine/server/sv_send.c +++ b/engine/server/sv_send.c @@ -485,7 +485,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int // to = MULTICAST_ALL; #ifdef Q2BSPS - if (sv.worldmodel->fromgame == fg_quake2 || sv.worldmodel->fromgame == fg_quake3) + if (sv.world.worldmodel->fromgame == fg_quake2 || sv.world.worldmodel->fromgame == fg_quake3) { int area1, area2, cluster; @@ -493,8 +493,8 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int if (to != MULTICAST_ALL_R && to != MULTICAST_ALL) { - leafnum = CM_PointLeafnum (sv.worldmodel, origin); - area1 = CM_LeafArea (sv.worldmodel, leafnum); + leafnum = CM_PointLeafnum (sv.world.worldmodel, origin); + area1 = CM_LeafArea (sv.world.worldmodel, leafnum); } else { @@ -514,17 +514,17 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int case MULTICAST_PHS_R: reliable = true; // intentional fallthrough case MULTICAST_PHS: - leafnum = CM_PointLeafnum (sv.worldmodel, origin); - cluster = CM_LeafCluster (sv.worldmodel, leafnum); - mask = CM_ClusterPHS (sv.worldmodel, cluster); + leafnum = CM_PointLeafnum (sv.world.worldmodel, origin); + cluster = CM_LeafCluster (sv.world.worldmodel, leafnum); + mask = CM_ClusterPHS (sv.world.worldmodel, cluster); break; case MULTICAST_PVS_R: reliable = true; // intentional fallthrough case MULTICAST_PVS: - leafnum = CM_PointLeafnum (sv.worldmodel, origin); - cluster = CM_LeafCluster (sv.worldmodel, leafnum); - mask = CM_ClusterPVS (sv.worldmodel, cluster, NULL, 0); + leafnum = CM_PointLeafnum (sv.world.worldmodel, origin); + cluster = CM_LeafCluster (sv.world.worldmodel, leafnum); + mask = CM_ClusterPVS (sv.world.worldmodel, cluster, NULL, 0); break; default: @@ -556,13 +556,13 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int { #ifdef Q2SERVER if (ge) - leafnum = CM_PointLeafnum (sv.worldmodel, client->q2edict->s.origin); + leafnum = CM_PointLeafnum (sv.world.worldmodel, client->q2edict->s.origin); else #endif - leafnum = CM_PointLeafnum (sv.worldmodel, client->edict->v->origin); - cluster = CM_LeafCluster (sv.worldmodel, leafnum); - area2 = CM_LeafArea (sv.worldmodel, leafnum); - if (!CM_AreasConnected (sv.worldmodel, area1, area2)) + leafnum = CM_PointLeafnum (sv.world.worldmodel, client->edict->v->origin); + cluster = CM_LeafCluster (sv.world.worldmodel, leafnum); + area2 = CM_LeafArea (sv.world.worldmodel, leafnum); + if (!CM_AreasConnected (sv.world.worldmodel, area1, area2)) continue; if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) ) continue; @@ -618,7 +618,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int else #endif { - leafnum = sv.worldmodel->funcs.LeafnumForPoint(sv.worldmodel, origin); + leafnum = sv.world.worldmodel->funcs.LeafnumForPoint(sv.world.worldmodel, origin); reliable = false; @@ -633,13 +633,13 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int case MULTICAST_PHS_R: reliable = true; // intentional fallthrough case MULTICAST_PHS: - mask = sv.phs + leafnum * 4*((sv.worldmodel->numleafs+31)>>5); + mask = sv.phs + leafnum * 4*((sv.world.worldmodel->numleafs+31)>>5); break; case MULTICAST_PVS_R: reliable = true; // intentional fallthrough case MULTICAST_PVS: - mask = sv.pvs + leafnum * 4*((sv.worldmodel->numleafs+31)>>5); + mask = sv.pvs + leafnum * 4*((sv.world.worldmodel->numleafs+31)>>5); break; default: @@ -686,7 +686,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int // -1 is because pvs rows are 1 based, not 0 based like leafs if (mask != sv.pvs) { - leafnum = sv.worldmodel->funcs.LeafnumForPoint (sv.worldmodel, client->edict->v->origin)-1; + leafnum = sv.world.worldmodel->funcs.LeafnumForPoint (sv.world.worldmodel, client->edict->v->origin)-1; if ( !(mask[leafnum>>3] & (1<<(leafnum&7)) ) ) { // Con_Printf ("PVS supressed multicast\n"); @@ -1063,21 +1063,21 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg) // on client side doesn't stray too far off if (ISQWCLIENT(client)) { - if (client->fteprotocolextensions & PEXT_ACCURATETIMINGS && sv.physicstime - client->nextservertimeupdate > 0) + if (client->fteprotocolextensions & PEXT_ACCURATETIMINGS && sv.world.physicstime - client->nextservertimeupdate > 0) { //the fte pext causes the server to send out accurate timings, allowing for perfect interpolation. MSG_WriteByte (msg, svc_updatestatlong); MSG_WriteByte (msg, STAT_TIME); - MSG_WriteLong (msg, (int)(sv.physicstime * 1000)); + MSG_WriteLong (msg, (int)(sv.world.physicstime * 1000)); - client->nextservertimeupdate = sv.physicstime;//+10; + client->nextservertimeupdate = sv.world.physicstime;//+10; } - else if (client->zquake_extensions & Z_EXT_SERVERTIME && sv.physicstime - client->nextservertimeupdate > 0) + else if (client->zquake_extensions & Z_EXT_SERVERTIME && sv.world.physicstime - client->nextservertimeupdate > 0) { //the zquake ext causes the server to send out peridoic timings, allowing for moderatly accurate game time. MSG_WriteByte (msg, svc_updatestatlong); MSG_WriteByte (msg, STAT_TIME); - MSG_WriteLong (msg, (int)(sv.physicstime * 1000)); + MSG_WriteLong (msg, (int)(sv.world.physicstime * 1000)); - client->nextservertimeupdate = sv.physicstime+10; + client->nextservertimeupdate = sv.world.physicstime+10; } } @@ -1089,9 +1089,9 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg) MSG_WriteByte (msg, svc_time); - MSG_WriteFloat(msg, sv.physicstime); - client->nextservertimeupdate = sv.physicstime; -// Con_Printf("%f\n", sv.physicstime); + MSG_WriteFloat(msg, sv.world.physicstime); + client->nextservertimeupdate = sv.world.physicstime; +// Con_Printf("%f\n", sv.world.physicstime); bits = 0; @@ -1638,7 +1638,7 @@ qboolean SV_SendClientDatagram (client_t *client) msg.allowoverflow = true; msg.overflowed = false; - if (sv.worldmodel && !client->controller) + if (sv.world.worldmodel && !client->controller) { if (ISQ2CLIENT(client)) { @@ -1669,7 +1669,7 @@ qboolean SV_SendClientDatagram (client_t *client) SZ_Clear (&client->datagram); // send deltas over reliable stream - if (sv.worldmodel) + if (sv.world.worldmodel) if (!ISQ2CLIENT(client) && Netchan_CanReliable (&client->netchan, SV_RateForClient(client))) { int pnum=1; @@ -2011,7 +2011,7 @@ void SV_SendClientMessages (void) int i, j; client_t *c; int sentbytes, fnum; - float pt = sv.physicstime; + float pt = sv.world.physicstime; #ifdef Q3SERVER if (svs.gametype == GT_QUAKE3) @@ -2151,14 +2151,14 @@ void SV_SendClientMessages (void) if (c->state == cs_connected && !c->datagram.cursize && !c->netchan.message.cursize) { - if (c->nextservertimeupdate < sv.physicstime) + if (c->nextservertimeupdate < sv.world.physicstime) { //part of the nq protocols allowed downloading content over isdn //the nop requirement of the protocol persisted to prevent timeouts when content loading is otherwise slow.. //aditionally we might need this for lost packets, not sure //but the client isn't able to respond unless we send an occasional datagram if (c->nextservertimeupdate) MSG_WriteByte(&c->datagram, svc_nop); - c->nextservertimeupdate = sv.physicstime+5; + c->nextservertimeupdate = sv.world.physicstime+5; } } } diff --git a/engine/server/sv_sys_unix.c b/engine/server/sv_sys_unix.c index aba86331..cc2a89a8 100644 --- a/engine/server/sv_sys_unix.c +++ b/engine/server/sv_sys_unix.c @@ -659,7 +659,7 @@ int main(int argc, char *argv[]) if (j) parms.memsize = (int) (Q_atof(com_argv[j+1]) * 1024 * 1024); if ((parms.membase = malloc (parms.memsize)) == NULL) - Sys_Error("Can't allocate %ld\n", parms.memsize); + Sys_Error("Can't allocate %u\n", parms.memsize); parms.basedir = "."; @@ -779,7 +779,7 @@ void Sys_CloseLibrary(dllhandle_t *lib) { dlclose((void*)lib); } -dllhandle_t *Sys_LoadLibrary(char *name, dllfunction_t *funcs) +dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs) { int i; dllhandle_t lib; diff --git a/engine/server/sv_sys_win.c b/engine/server/sv_sys_win.c index f688afa0..95b7568b 100644 --- a/engine/server/sv_sys_win.c +++ b/engine/server/sv_sys_win.c @@ -45,7 +45,7 @@ void Sys_CloseLibrary(dllhandle_t *lib) { FreeLibrary((HMODULE)lib); } -dllhandle_t *Sys_LoadLibrary(char *name, dllfunction_t *funcs) +dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs) { int i; HMODULE lib; @@ -69,7 +69,7 @@ dllhandle_t *Sys_LoadLibrary(char *name, dllfunction_t *funcs) return (dllhandle_t*)lib; } -void *Sys_GetAddressForName(dllhandle_t *module, char *exportname) +void *Sys_GetAddressForName(dllhandle_t *module, const char *exportname) { if (!module) return NULL; diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index 77d7c5d4..66aeae73 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "qwsvdef.h" #ifndef CLIENTONLY +#include "pr_common.h" #include #define Q2EDICT_NUM(i) (q2edict_t*)((char *)ge->edicts+i*ge->edict_size) @@ -43,6 +44,7 @@ cvar_t sv_spectalk = SCVAR("sv_spectalk", "1"); cvar_t sv_mapcheck = SCVAR("sv_mapcheck", "1"); +cvar_t sv_antilag = SCVARF("sv_antilag", "0", CVAR_SERVERINFO); cvar_t sv_cheatpc = SCVAR("sv_cheatpc", "125"); cvar_t sv_cheatspeedchecktime = SCVAR("sv_cheatspeedchecktime", "30"); cvar_t sv_playermodelchecks = SCVAR("sv_playermodelchecks", "1"); @@ -251,6 +253,11 @@ void SV_New_f (void) else ClientReliableWrite_Long (host_client, host_client->fteprotocolextensions); } + if (host_client->fteprotocolextensions2)//let the client know + { + ClientReliableWrite_Long (host_client, PROTOCOL_VERSION_FTE2); + ClientReliableWrite_Long (host_client, host_client->fteprotocolextensions2); + } #endif ClientReliableWrite_Long (host_client, ISQ2CLIENT(host_client)?PROTOCOL_VERSION_Q2:PROTOCOL_VERSION_QW); ClientReliableWrite_Long (host_client, svs.spawncount); @@ -362,7 +369,7 @@ void SV_New_f (void) ClientReliableWrite_Byte (host_client, svc_cdtrack); if (svprogfuncs) - ClientReliableWrite_Byte (host_client, sv.edicts->v->sounds); + ClientReliableWrite_Byte (host_client, ((edict_t*)sv.world.edicts)->v->sounds); else ClientReliableWrite_Byte (host_client, 0); @@ -453,8 +460,8 @@ void SVNQ_New_f (void) // send music MSG_WriteByte (&host_client->netchan.message, svc_cdtrack); - MSG_WriteByte (&host_client->netchan.message, sv.edicts->v->sounds); - MSG_WriteByte (&host_client->netchan.message, sv.edicts->v->sounds); + MSG_WriteByte (&host_client->netchan.message, ((edict_t*)sv.world.edicts)->v->sounds); + MSG_WriteByte (&host_client->netchan.message, ((edict_t*)sv.world.edicts)->v->sounds); // set view MSG_WriteByte (&host_client->netchan.message, svc_setview); @@ -1060,7 +1067,7 @@ void SV_PreSpawn_f (void) statics = sv.numextrastatics; buf = atoi(Cmd_Argv(2)); - if (buf >= bufs+statics+sv.num_edicts+255) + if (buf >= bufs+statics+sv.world.num_edicts+255) { SV_EndRedirect(); Con_Printf ("SV_Modellist_f: %s send an invalid index\n", host_client->name); @@ -1071,17 +1078,17 @@ void SV_PreSpawn_f (void) if (!buf) { // should be three numbers following containing checksums - check = atoi(Cmd_Argv(3)); + check = COM_RemapMapChecksum(atoi(Cmd_Argv(3))); // Con_DPrintf("Client check = %d\n", check); - if (sv_mapcheck.value && check != sv.worldmodel->checksum && - check != LittleLong(sv.worldmodel->checksum2)) + if (sv_mapcheck.value && check != sv.world.worldmodel->checksum && + check != COM_RemapMapChecksum(LittleLong(sv.world.worldmodel->checksum2))) if (!sv.demofile || (sv.demofile && !sv.democausesreconnect)) //demo playing causes no check. If it's the return level, check anyway to avoid that loophole. { SV_ClientTPrintf (host_client, PRINT_HIGH, STL_MAPCHEAT, - sv.modelname, check, sv.worldmodel->checksum, sv.worldmodel->checksum2); + sv.modelname, check, sv.world.worldmodel->checksum, sv.world.worldmodel->checksum2); SV_DropClient (host_client); return; } @@ -1140,7 +1147,7 @@ void SV_PreSpawn_f (void) } while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2)) //baselines { - if (buf - bufs - sv.numextrastatics >= sv.num_edicts) + if (buf - bufs - sv.numextrastatics >= sv.world.num_edicts) break; ent = EDICT_NUM(svprogfuncs, buf - bufs - sv.numextrastatics); @@ -1196,7 +1203,7 @@ void SV_PreSpawn_f (void) } while (host_client->netchan.message.cursize < (host_client->netchan.message.maxsize/2)) { - i = buf - bufs - sv.numextrastatics - sv.num_edicts; + i = buf - bufs - sv.numextrastatics - sv.world.num_edicts; if (i >= 255) break; @@ -1235,7 +1242,7 @@ void SV_PreSpawn_f (void) } else if (buf >= bufs) { - buf = bufs+sv.numextrastatics+sv.num_edicts+255; + buf = bufs+sv.numextrastatics+sv.world.num_edicts+255; } else { @@ -1260,7 +1267,7 @@ void SV_PreSpawn_f (void) } } } - if (buf == bufs+sv.numextrastatics+sv.num_edicts+255) + if (buf == bufs+sv.numextrastatics+sv.world.num_edicts+255) { // all done prespawning MSG_WriteByte (&host_client->netchan.message, svc_stufftext); MSG_WriteString (&host_client->netchan.message, va("cmd spawn %i\n",svs.spawncount) ); @@ -1434,7 +1441,7 @@ void SV_SpawnSpectator (void) // search for an info_playerstart to spawn the spectator at //this is only useful when a mod doesn't nativly support spectators. old qw on nq mods. - for (i=MAX_CLIENTS+1 ; iv->classname), "info_player_start")) @@ -1473,7 +1480,7 @@ void SV_Begin_Core(client_t *split) f = PR_FindFunction(svprogfuncs, "RestoreGame", PR_ANY); if (f) { - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict); PR_ExecuteProgram (svprogfuncs, f); } @@ -1501,7 +1508,7 @@ void SV_Begin_Core(client_t *split) } // call the spawn function - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict); PR_ExecuteProgram (svprogfuncs, SpectatorConnect); } @@ -1519,7 +1526,7 @@ void SV_Begin_Core(client_t *split) edict_t *ent; ent = split->edict; j = strlen(split->spawninfo); - SV_UnlinkEdict(ent); + World_UnlinkEdict((wedict_t*)ent); svprogfuncs->restoreent(svprogfuncs, split->spawninfo, &j, ent); eval2 = svprogfuncs->GetEdictFieldValue(svprogfuncs, ent, "stats_restored", NULL); @@ -1530,7 +1537,7 @@ void SV_Begin_Core(client_t *split) if (spawnparamglobals[j]) *spawnparamglobals[j] = split->spawn_parms[j]; } - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent); G_FLOAT(OFS_PARM0) = sv.time - split->spawninfotime; PR_ExecuteProgram(svprogfuncs, eval->function); @@ -1553,13 +1560,13 @@ void SV_Begin_Core(client_t *split) { globalvars_t *pr_globals = PR_globals(svprogfuncs, PR_CURRENT); - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict); G_FLOAT(OFS_PARM0) = split->csqcactive; //this arg is part of EXT_CSQC_1, but doesn't have to be supported by the mod PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect); // actually spawn the player - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, split->edict); PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer); } @@ -1994,7 +2001,7 @@ void SV_NextUpload (void) if (!host_client->upload) { - host_client->upload = FS_OpenVFS(host_client->uploadfn, "wb", FS_GAME); + host_client->upload = FS_OpenVFS(host_client->uploadfn, "wb", FS_GAMEONLY); if (!host_client->upload) { Sys_Printf("Can't create %s\n", host_client->uploadfn); @@ -2815,7 +2822,7 @@ void SV_Kill_f (void) #ifdef VM_Q1 if (svs.gametype == GT_Q1QVM) { - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player); Q1QVM_ClientCommand(); return; @@ -2840,7 +2847,7 @@ void SV_Kill_f (void) SV_PushFloodProt(host_client); } - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player); PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientKill); @@ -3531,7 +3538,7 @@ void Cmd_SetPos_f(void) sv_player->v->origin[0] = atof(Cmd_Argv(1)); sv_player->v->origin[1] = atof(Cmd_Argv(2)); sv_player->v->origin[2] = atof(Cmd_Argv(3)); - SV_LinkEdict (sv_player, false); + World_LinkEdict (&sv.world, (wedict_t*)sv_player, false); } void ED_ClearEdict (progfuncs_t *progfuncs, edict_t *e); @@ -3550,7 +3557,7 @@ void SV_SetUpClientEdict (client_t *cl, edict_t *ent) #endif { if (progstype != PROG_NQ) //allow frikbots to work in NQ mods (but not qw!) - ED_ClearEdict(svprogfuncs, ent); + ED_Clear(svprogfuncs, ent); ent->v->netname = PR_SetString(svprogfuncs, cl->name); } ED_Spawned(ent, false); @@ -3653,12 +3660,12 @@ void Cmd_Join_f (void) } // call the spawn function - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player); PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect); // actually spawn the player - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player); PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer); @@ -3748,7 +3755,7 @@ void Cmd_Observe_f (void) // call the spawn function if (SpectatorConnect) { - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player); PR_ExecuteProgram (svprogfuncs, SpectatorConnect); } @@ -3841,6 +3848,15 @@ void SV_DisableClientsCSQC(void) #endif } +void SV_STFU_f(void) +{ + char *msg; + SV_ClientPrintf(host_client, 255, "stfu\n"); + msg = "cl_antilag 0\n"; + ClientReliableWrite_Begin(host_client, svc_stufftext, 2+strlen(msg)); + ClientReliableWrite_String(host_client, msg); +} + void SV_MVDList_f (void); void SV_MVDInfo_f (void); typedef struct @@ -3860,6 +3876,8 @@ ucmd_t ucmds[] = {"spawn", SV_Spawn_f, true}, {"begin", SV_Begin_f, true}, + {"al", SV_STFU_f, true}, + {"join", Cmd_Join_f}, {"observe", Cmd_Observe_f}, @@ -4114,7 +4132,7 @@ void SVNQ_Spawn_f (void) } else { - memset (ent->v, 0, pr_edict_size); + memset (ent->v, 0, sv.world.edict_size); ED_Spawned(ent, false); ent->v->colormap = NUM_FOR_EDICT(svprogfuncs, ent); @@ -4191,7 +4209,7 @@ void SVNQ_Begin_f (void) } // call the spawn function - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player); PR_ExecuteProgram (svprogfuncs, SpectatorConnect); } @@ -4206,12 +4224,12 @@ void SVNQ_Begin_f (void) } // call the spawn function - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player); PR_ExecuteProgram (svprogfuncs, pr_global_struct->ClientConnect); // actually spawn the player - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player); PR_ExecuteProgram (svprogfuncs, pr_global_struct->PutClientInServer); } @@ -4281,7 +4299,7 @@ void SVNQ_PreSpawn_f (void) return; } - for (e = 1; e < sv.num_edicts; e++) + for (e = 1; e < sv.world.num_edicts; e++) { ent = EDICT_NUM(svprogfuncs, e); state = &ent->baseline; @@ -4524,7 +4542,7 @@ void SVNQ_ExecuteUserCommand (char *s) int implevels[256]; -qboolean SV_FiltureImpulse(int imp, int level) +qboolean SV_FilterImpulse(int imp, int level) { if (imp < 0 || imp > 255) return true; //erm @@ -4633,7 +4651,7 @@ void AddLinksToPmove ( edict_t *player, areanode_t *node ) for (l = node->solid_edicts.next ; l != &node->solid_edicts ; l = next) { next = l->next; - check = EDICT_FROM_AREA(l); + check = (edict_t*)EDICT_FROM_AREA(l); if (check->v->owner == pl) continue; // player's own missile @@ -4665,7 +4683,7 @@ void AddLinksToPmove ( edict_t *player, areanode_t *node ) { if(progstype != PROG_H2) pe->angles[0]*=-1; //quake is wierd. I guess someone fixed it hexen2... or my code is buggy or something... - pe->model = sv.models[(int)(check->v->modelindex)]; + pe->model = sv.world.models[(int)(check->v->modelindex)]; VectorCopy (check->v->angles, pe->angles); } else @@ -4681,7 +4699,7 @@ void AddLinksToPmove ( edict_t *player, areanode_t *node ) for (l = node->trigger_edicts.next ; l != &node->trigger_edicts ; l = next) { next = l->next; - check = EDICT_FROM_AREA(l); + check = (edict_t*)EDICT_FROM_AREA(l); if (check->v->owner == pl) continue; // player's own missile @@ -4697,7 +4715,7 @@ void AddLinksToPmove ( edict_t *player, areanode_t *node ) if (!((int)player->xv->dimension_hit & (int)check->xv->dimension_solid)) continue; - model = sv.models[(int)check->v->modelindex]; + model = sv.world.models[(int)check->v->modelindex]; if (model) // test the point if (model->funcs.PointContents (model, player->v->origin) == FTECONTENTS_SOLID) @@ -4732,7 +4750,7 @@ void AddAllEntsToPmove (void) int pl; pl = EDICT_TO_PROG(svprogfuncs, sv_player); - for (e=1 ; eisfree) @@ -4759,7 +4777,7 @@ void AddAllEntsToPmove (void) if (check->v->solid == SOLID_BSP) { VectorCopy (check->v->angles, pe->angles); - pe->model = sv.models[(int)(check->v->modelindex)]; + pe->model = sv.world.models[(int)(check->v->modelindex)]; } else { @@ -4933,7 +4951,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse) pmove.jump_msec = 0; pmove.waterjumptime = 0; pmove.numphysent = 1; - pmove.physents[0].model = sv.worldmodel; + pmove.physents[0].model = sv.world.worldmodel; pmove.cmd = *ucmd; pmove.hullnum = SV_HullNumForPlayer(0, player_mins, player_maxs); @@ -4990,7 +5008,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse) sv_player->xv->button6 = ((ucmd->buttons >> 5) & 1); sv_player->xv->button7 = ((ucmd->buttons >> 6) & 1); sv_player->xv->button8 = ((ucmd->buttons >> 7) & 1); - if (ucmd->impulse && SV_FiltureImpulse(ucmd->impulse, host_client->trustlevel)) + if (ucmd->impulse && SV_FilterImpulse(ucmd->impulse, host_client->trustlevel)) sv_player->v->impulse = ucmd->impulse; if (host_client->iscuffed) @@ -5101,7 +5119,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse) else pmove.waterjumptime = sv_player->v->teleport_time; pmove.numphysent = 1; - pmove.physents[0].model = sv.worldmodel; + pmove.physents[0].model = sv.world.worldmodel; pmove.cmd = *ucmd; pmove.hullnum = SV_HullNumForPlayer(sv_player->xv->hull, sv_player->v->mins, sv_player->v->maxs); @@ -5124,7 +5142,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse) } sv_player->xv->pmove_flags = (int)sv_player->xv->pmove_flags & ~PMF_LADDER; //assume not touching ladder trigger #if 1 - AddLinksToPmove ( sv_player, sv_areanodes ); + AddLinksToPmove ( sv_player, sv.world.areanodes ); #else AddAllEntsToPmove (); #endif @@ -5201,7 +5219,7 @@ if (sv_player->v->health > 0 && before && !after ) if (!host_client->spectator) { // link into place and touch triggers - SV_LinkEdict (sv_player, true); + World_LinkEdict (&sv.world, (wedict_t*)sv_player, true); /* for (i = 0; i < pmove.numphysent; i++) { @@ -5333,7 +5351,7 @@ void SV_ReadPrydonCursor(void) if (cursor_impact) cursor_impact->_vector[2] = f; entnum = (unsigned short)MSG_ReadShort(); - if (entnum >= sv.max_edicts) + if (entnum >= sv.world.max_edicts) { Con_DPrintf("SV_ReadPrydonCursor: client send bad cursor_entitynumber\n"); entnum = 0; @@ -5350,7 +5368,7 @@ void SV_ReadPrydonCursor(void) void SV_ReadQCRequest(void) { int e; - char args[9]; + char args[7]; char *rname; func_t f; int i; @@ -5367,16 +5385,18 @@ void SV_ReadQCRequest(void) for (i = 0; ; i++) { if (i >= sizeof(args)) + { if (MSG_ReadByte() != ev_void) { msg_badread = true; return; } + goto done; + } switch(MSG_ReadByte()) { case ev_void: - i = 6; - break; + goto done; case ev_float: args[i] = 'f'; G_FLOAT(OFS_PARM0+i*3) = MSG_ReadFloat(); @@ -5398,17 +5418,20 @@ void SV_ReadQCRequest(void) case ev_entity: args[i] = 's'; e = MSG_ReadShort(); - if (e < 0 || e >= sv.num_edicts) + if (e < 0 || e >= sv.world.num_edicts) e = 0; G_INT(OFS_PARM0+i*3) = EDICT_TO_PROG(svprogfuncs, EDICT_NUM(svprogfuncs, e)); break; } } +done: rname = MSG_ReadString(); - f = PR_FindFunc(svprogfuncs, va("Cmd_%s_%s", rname, args), PR_ANY); + f = PR_FindFunction(svprogfuncs, va("Cmd_%s_%s", rname, args), PR_ANY); if (f) PR_ExecuteProgram(svprogfuncs, f); + else + SV_ClientPrintf(host_client, PRINT_HIGH, "qcrequest \"%s\" not supported\n", rname); } /* @@ -5469,6 +5492,25 @@ void SV_ExecuteClientMessage (client_t *cl) SV_CSQC_DropAll(cl); #endif cl->lastsequence_acknoledged = cl->netchan.incoming_acknowledged; + + if (sv_antilag.ival) + { + /* + extern cvar_t temp1; + if (temp1.ival) + frame = &cl->frameunion.frames[(cl->netchan.incoming_acknowledged+temp1.ival) & UPDATE_MASK]; + */ +#pragma message("FIXME: make antilag optionally support non-player ents too") + for (i = 0; i < sv.allocated_client_slots; i++) + { + cl->laggedents[i].present = frame->playerpresent[i]; + if (cl->laggedents[i].present) + VectorCopy(frame->playerpositions[i], cl->laggedents[i].laggedpos); + } + cl->laggedents_count = sv.allocated_client_slots; + } + else + cl->laggedents_count = 0; } else { @@ -5721,7 +5763,7 @@ haveannothergo: else if (host_client->spectator) { VectorCopy(o, sv_player->v->origin); - SV_LinkEdict(sv_player, false); + World_LinkEdict(&sv.world, (wedict_t*)sv_player, false); } break; @@ -5952,7 +5994,7 @@ void SVNQ_ReadClientMove (usercmd_t *move) if (SV_RunFullQCMovement(host_client, move)) { - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player); #ifdef VM_Q1 if (svs.gametype == GT_Q1QVM) @@ -5968,7 +6010,7 @@ void SVNQ_ReadClientMove (usercmd_t *move) } - if (i && SV_FiltureImpulse(i, host_client->trustlevel)) + if (i && SV_FilterImpulse(i, host_client->trustlevel)) host_client->edict->v->impulse = i; host_client->edict->v->button0 = bits & 1; @@ -6095,6 +6137,7 @@ void SV_UserInit (void) Cvar_Register (&sv_spectalk, cvargroup_servercontrol); Cvar_Register (&sv_mapcheck, cvargroup_servercontrol); + Cvar_Register (&sv_antilag, cvargroup_servercontrol); Cvar_Register (&sv_cheatpc, cvargroup_servercontrol); Cvar_Register (&sv_cheatspeedchecktime, cvargroup_servercontrol); Cvar_Register (&sv_playermodelchecks, cvargroup_servercontrol); @@ -6222,7 +6265,7 @@ void SV_UserFriction (void) start[2] = origin[2] + sv_player->v->mins[2]; stop[2] = start[2] - 34; - trace = SV_Move (start, vec3_origin, vec3_origin, stop, true, sv_player); + trace = World_Move (&sv.world, start, vec3_origin, vec3_origin, stop, true, (wedict_t*)sv_player); if (trace.fraction == 1.0) friction = sv_friction.value*sv_edgefriction.value; @@ -6454,7 +6497,7 @@ void SV_ClientThink (void) if (SV_PlayerPhysicsQC) { - pr_global_struct->time = sv.physicstime; + pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player); PR_ExecuteProgram (svprogfuncs, SV_PlayerPhysicsQC); return; diff --git a/engine/server/svhl_game.c b/engine/server/svhl_game.c index 9ade2460..0be3ed93 100644 --- a/engine/server/svhl_game.c +++ b/engine/server/svhl_game.c @@ -28,14 +28,14 @@ int lastusermessage; -string_t GHL_AllocString(char *string) +string_t QDECL GHL_AllocString(char *string) { char *news; news = Hunk_Alloc(strlen(string)+1); memcpy(news, string, strlen(string)+1); return news - SVHL_Globals.stringbase; } -int GHL_PrecacheModel(char *name) +int QDECL GHL_PrecacheModel(char *name) { int i; @@ -81,7 +81,7 @@ int GHL_PrecacheModel(char *name) SV_Error ("GHL_precache_model: overflow"); return 0; } -int GHL_PrecacheSound(char *name) +int QDECL GHL_PrecacheSound(char *name) { int i; @@ -125,7 +125,7 @@ int GHL_PrecacheSound(char *name) SV_Error ("GHL_precache_sound: overflow"); return 0; } -void GHL_SetModel(hledict_t *ed, char *modelname) +void QDECL GHL_SetModel(hledict_t *ed, char *modelname) { model_t *mod; int mdlidx = GHL_PrecacheModel(modelname); @@ -141,40 +141,40 @@ void GHL_SetModel(hledict_t *ed, char *modelname) } SVHL_LinkEdict(ed, false); } -unk GHL_ModelIndex(unk){notimp(__LINE__);} -int GHL_ModelFrames(int midx) +unk QDECL GHL_ModelIndex(unk){notimp(__LINE__);} +int QDECL GHL_ModelFrames(int midx) { //returns the number of frames(sequences I assume) this model has ignore("ModelFrames"); return 1; } -void GHL_SetSize(hledict_t *ed, float *mins, float *maxs) +void QDECL GHL_SetSize(hledict_t *ed, float *mins, float *maxs) { VectorCopy(mins, ed->v.mins); VectorCopy(maxs, ed->v.maxs); SVHL_LinkEdict(ed, false); } -void GHL_ChangeLevel(char *nextmap, char *startspot) +void QDECL GHL_ChangeLevel(char *nextmap, char *startspot) { Cbuf_AddText(va("changelevel %s %s@%f@%f@%f\n", nextmap, startspot, SVHL_Globals.landmark[0], SVHL_Globals.landmark[1], SVHL_Globals.landmark[2]), RESTRICT_PROGS); } -unk GHL_GetSpawnParms(unk){notimp(__LINE__);} -unk GHL_SaveSpawnParms(unk){notimp(__LINE__);} -float GHL_VecToYaw(float *inv) +unk QDECL GHL_GetSpawnParms(unk){notimp(__LINE__);} +unk QDECL GHL_SaveSpawnParms(unk){notimp(__LINE__);} +float QDECL GHL_VecToYaw(float *inv) { vec3_t outa; VectorAngles(inv, NULL, outa); return outa[1]; } -void GHL_VecToAngles(float *inv, float *outa) +void QDECL GHL_VecToAngles(float *inv, float *outa) { VectorAngles(inv, NULL, outa); } -unk GHL_MoveToOrigin(unk){notimp(__LINE__);} -unk GHL_ChangeYaw(unk){notimp(__LINE__);} -unk GHL_ChangePitch(unk){notimp(__LINE__);} -hledict_t *GHL_FindEntityByString(hledict_t *last, char *field, char *value) +unk QDECL GHL_MoveToOrigin(unk){notimp(__LINE__);} +unk QDECL GHL_ChangeYaw(unk){notimp(__LINE__);} +unk QDECL GHL_ChangePitch(unk){notimp(__LINE__);} +hledict_t *QDECL GHL_FindEntityByString(hledict_t *last, char *field, char *value) { hledict_t *ent; int i; @@ -205,8 +205,8 @@ hledict_t *GHL_FindEntityByString(hledict_t *last, char *field, char *value) } return SVHL_Edict; } -unk GHL_GetEntityIllum(unk){notimp(__LINE__);} -hledict_t *GHL_FindEntityInSphere(hledict_t *last, float *org, float radius) +unk QDECL GHL_GetEntityIllum(unk){notimp(__LINE__);} +hledict_t *QDECL GHL_FindEntityInSphere(hledict_t *last, float *org, float radius) { int i, j; vec3_t eorg; @@ -235,7 +235,7 @@ hledict_t *GHL_FindEntityInSphere(hledict_t *last, float *org, float radius) } return NULL; } -hledict_t *GHL_FindClientInPVS(hledict_t *ed) +hledict_t *QDECL GHL_FindClientInPVS(hledict_t *ed) { qbyte *viewerpvs; int best = 0, i; @@ -248,7 +248,7 @@ hledict_t *GHL_FindClientInPVS(hledict_t *ed) //fixme: we need to track some state //a different client should be returned each call _per ent_ (so it can be used once per frame) - viewerpvs = sv.worldmodel->funcs.LeafPVS(sv.worldmodel, sv.worldmodel->funcs.LeafnumForPoint(sv.worldmodel, ed->v.origin), NULL); + viewerpvs = sv.worldmodel->funcs.LeafPVS(sv.worldmodel, sv.worldmodel->funcs.LeafnumForPoint(sv.worldmodel, ed->v.origin), NULL, 0); for (i = 0; i < MAX_CLIENTS; i++) { @@ -279,19 +279,19 @@ hledict_t *GHL_FindClientInPVS(hledict_t *ed) return &SVHL_Edict[best]; return NULL; } -unk GHL_EntitiesInPVS(unk){notimp(__LINE__);} -void GHL_MakeVectors(float *angles) +unk QDECL GHL_EntitiesInPVS(unk){notimp(__LINE__);} +void QDECL GHL_MakeVectors(float *angles) { AngleVectors(angles, SVHL_Globals.v_forward, SVHL_Globals.v_right, SVHL_Globals.v_up); } -void GHL_AngleVectors(float *angles, float *forward, float *right, float *up) +void QDECL GHL_AngleVectors(float *angles, float *forward, float *right, float *up) { AngleVectors(angles, forward, right, up); } /////////////////////////////////////////////////////////// -hledict_t *GHL_CreateEntity(void) +hledict_t *QDECL GHL_CreateEntity(void) { int i; static int spawnnumber; @@ -321,69 +321,71 @@ hledict_t *GHL_CreateEntity(void) SV_Error("Ran out of free edicts"); return NULL; } -void GHL_RemoveEntity(hledict_t *ed) +void QDECL GHL_RemoveEntity(hledict_t *ed) { SVHL_UnlinkEdict(ed); ed->isfree = true; ed->freetime = sv.time+2; } -hledict_t *GHL_CreateNamedEntity(string_t name) +hledict_t *QDECL GHL_CreateNamedEntity(string_t name) { - void (*spawnfunc)(hlentvars_t *evars); + void (QDECL *spawnfunc)(hlentvars_t *evars); hledict_t *ed; ed = GHL_CreateEntity(); if (!ed) return NULL; ed->v.classname = name; - spawnfunc = (void(*)(hlentvars_t*))GetProcAddress((HINSTANCE)hlgamecode, name+SVHL_Globals.stringbase); + spawnfunc = (void(QDECL *)(hlentvars_t*))GetProcAddress((HINSTANCE)hlgamecode, name+SVHL_Globals.stringbase); if (spawnfunc) spawnfunc(&ed->v); return ed; } -void *GHL_PvAllocEntPrivateData(hledict_t *ed, long quant) +void *QDECL GHL_PvAllocEntPrivateData(hledict_t *ed, long quant) { + if (!ed) + return NULL; ed->moddata = Z_Malloc(quant); return ed->moddata; } -unk GHL_PvEntPrivateData(unk) +unk QDECL GHL_PvEntPrivateData(unk) { notimp(__LINE__); } -unk GHL_FreeEntPrivateData(unk) +unk QDECL GHL_FreeEntPrivateData(unk) { notimp(__LINE__); } -unk GHL_GetVarsOfEnt(unk) +unk QDECL GHL_GetVarsOfEnt(unk) { notimp(__LINE__); } -hledict_t *GHL_PEntityOfEntOffset(int ednum) +hledict_t *QDECL GHL_PEntityOfEntOffset(int ednum) { return (hledict_t *)(ednum + (char*)SVHL_Edict); } -int GHL_EntOffsetOfPEntity(hledict_t *ed) +int QDECL GHL_EntOffsetOfPEntity(hledict_t *ed) { return (char*)ed - (char*)SVHL_Edict; } -int GHL_IndexOfEdict(hledict_t *ed) +int QDECL GHL_IndexOfEdict(hledict_t *ed) { return ed - SVHL_Edict; } -hledict_t *GHL_PEntityOfEntIndex(int idx) +hledict_t *QDECL GHL_PEntityOfEntIndex(int idx) { return &SVHL_Edict[idx]; } -unk GHL_FindEntityByVars(unk) +unk QDECL GHL_FindEntityByVars(unk) { notimp(__LINE__); } /////////////////////////////////////////////////////// -unk GHL_MakeStatic(unk){notimp(__LINE__);} -unk GHL_EntIsOnFloor(unk){notimp(__LINE__);} -int GHL_DropToFloor(hledict_t *ed) +unk QDECL GHL_MakeStatic(unk){notimp(__LINE__);} +unk QDECL GHL_EntIsOnFloor(unk){notimp(__LINE__);} +int QDECL GHL_DropToFloor(hledict_t *ed) { vec3_t top; vec3_t bottom; @@ -396,25 +398,25 @@ int GHL_DropToFloor(hledict_t *ed) VectorCopy(tr.endpos, ed->v.origin); return tr.fraction != 0 && tr.fraction != 1; } -int GHL_WalkMove(hledict_t *ed, float yaw, float dist, int mode) +int QDECL GHL_WalkMove(hledict_t *ed, float yaw, float dist, int mode) { ignore("walkmove"); return 1; } -void GHL_SetOrigin(hledict_t *ed, float *neworg) +void QDECL GHL_SetOrigin(hledict_t *ed, float *neworg) { VectorCopy(neworg, ed->v.origin); SVHL_LinkEdict(ed, false); } -void GHL_EmitSound(hledict_t *ed, int chan, char *soundname, float vol, float atten, int flags, int pitch) +void QDECL GHL_EmitSound(hledict_t *ed, int chan, char *soundname, float vol, float atten, int flags, int pitch) { SV_StartSound(ed-SVHL_Edict, ed->v.origin, ~0, chan, soundname, vol*255, atten); } -void GHL_EmitAmbientSound(hledict_t *ed, float *org, char *soundname, float vol, float atten, unsigned int flags, int pitch) +void QDECL GHL_EmitAmbientSound(hledict_t *ed, float *org, char *soundname, float vol, float atten, unsigned int flags, int pitch) { SV_StartSound(0, org, ~0, 0, soundname, vol*255, atten); } -void GHL_TraceLine(float *start, float *end, int flags, hledict_t *ignore, hltraceresult_t *result) +void QDECL GHL_TraceLine(float *start, float *end, int flags, hledict_t *ignore, hltraceresult_t *result) { trace_t t; @@ -433,9 +435,9 @@ void GHL_TraceLine(float *start, float *end, int flags, hledict_t *ignore, hltra result->touched = &SVHL_Edict[0]; result->hitgroup = 0; } -unk GHL_TraceToss(unk){notimp(__LINE__);} -unk GHL_TraceMonsterHull(unk){notimp(__LINE__);} -void GHL_TraceHull(float *start, float *end, int flags, int hullnum, hledict_t *ignore, hltraceresult_t *result) +unk QDECL GHL_TraceToss(unk){notimp(__LINE__);} +unk QDECL GHL_TraceMonsterHull(unk){notimp(__LINE__);} +void QDECL GHL_TraceHull(float *start, float *end, int flags, int hullnum, hledict_t *ignore, hltraceresult_t *result) { trace_t t; @@ -452,35 +454,35 @@ void GHL_TraceHull(float *start, float *end, int flags, int hullnum, hledict_t * result->touched = t.ent; result->hitgroup = 0; } -unk GHL_TraceModel(unk){notimp(__LINE__);} -char *GHL_TraceTexture(hledict_t *againstent, vec3_t start, vec3_t end) +unk QDECL GHL_TraceModel(unk){notimp(__LINE__);} +char *QDECL GHL_TraceTexture(hledict_t *againstent, vec3_t start, vec3_t end) { trace_t tr; sv.worldmodel->funcs.Trace(sv.worldmodel, 0, 0, start, end, vec3_origin, vec3_origin, &tr); return tr.surface->name; } -unk GHL_TraceSphere(unk){notimp(__LINE__);} -unk GHL_GetAimVector(unk){notimp(__LINE__);} -void GHL_ServerCommand(char *cmd) +unk QDECL GHL_TraceSphere(unk){notimp(__LINE__);} +unk QDECL GHL_GetAimVector(unk){notimp(__LINE__);} +void QDECL GHL_ServerCommand(char *cmd) { Cbuf_AddText(cmd, RESTRICT_PROGS); } -void GHL_ServerExecute(void) +void QDECL GHL_ServerExecute(void) { Cbuf_ExecuteLevel(RESTRICT_PROGS); } -unk GHL_ClientCommand(unk){notimp(__LINE__);} -unk GHL_ParticleEffect(unk){notimp(__LINE__);} -void GHL_LightStyle(int stylenum, char *stylestr) +unk QDECL GHL_ClientCommand(unk){notimp(__LINE__);} +unk QDECL GHL_ParticleEffect(unk){notimp(__LINE__);} +void QDECL GHL_LightStyle(int stylenum, char *stylestr) { PF_applylightstyle(stylenum, stylestr, 7); } -int GHL_DecalIndex(char *decalname) +int QDECL GHL_DecalIndex(char *decalname) { Con_Printf("Fixme: precache decal %s\n", decalname); return 0; } -int GHL_PointContents(float *org) +int QDECL GHL_PointContents(float *org) { return Q1CONTENTS_EMPTY; } @@ -488,7 +490,7 @@ int GHL_PointContents(float *org) int svhl_messagedest; vec3_t svhl_messageorigin; hledict_t *svhl_messageent; -void GHL_MessageBegin(int dest, int type, float *org, hledict_t *ent) +void QDECL GHL_MessageBegin(int dest, int type, float *org, hledict_t *ent) { svhl_messagedest = dest; if (org) @@ -506,7 +508,7 @@ void GHL_MessageBegin(int dest, int type, float *org, hledict_t *ent) MSG_WriteShort(&sv.multicast, 0); MSG_WriteByte(&sv.multicast, type); } -void GHL_MessageEnd(unk) +void QDECL GHL_MessageEnd(unk) { unsigned short len; client_t *cl; @@ -552,42 +554,42 @@ void GHL_MessageEnd(unk) SZ_Clear (&sv.multicast); } -void GHL_WriteByte(int value) +void QDECL GHL_WriteByte(int value) { MSG_WriteByte(&sv.multicast, value); } -void GHL_WriteChar(int value) +void QDECL GHL_WriteChar(int value) { MSG_WriteChar(&sv.multicast, value); } -void GHL_WriteShort(int value) +void QDECL GHL_WriteShort(int value) { MSG_WriteShort(&sv.multicast, value); } -void GHL_WriteLong(int value) +void QDECL GHL_WriteLong(int value) { MSG_WriteLong(&sv.multicast, value); } -void GHL_WriteAngle(float value) +void QDECL GHL_WriteAngle(float value) { MSG_WriteAngle8(&sv.multicast, value); } -void GHL_WriteCoord(float value) +void QDECL GHL_WriteCoord(float value) { coorddata i = MSG_ToCoord(value, 2); SZ_Write (&sv.multicast, (void*)&i, 2); } -void GHL_WriteString(char *string) +void QDECL GHL_WriteString(char *string) { MSG_WriteString(&sv.multicast, string); } -void GHL_WriteEntity(int entnum) +void QDECL GHL_WriteEntity(int entnum) { MSG_WriteShort(&sv.multicast, entnum); } -void GHL_AlertMessage(int level, char *fmt, ...) +void QDECL GHL_AlertMessage(int level, char *fmt, ...) { va_list argptr; char string[1024]; @@ -598,12 +600,12 @@ void GHL_AlertMessage(int level, char *fmt, ...) Con_Printf("%s\n", string); } -void GHL_EngineFprintf(FILE *f, char *fmt, ...) +void QDECL GHL_EngineFprintf(FILE *f, char *fmt, ...) { SV_Error("Halflife gamecode tried to use EngineFprintf\n"); } -unk GHL_SzFromIndex(unk){notimp(__LINE__);} -void *GHL_GetModelPtr(hledict_t *ed) +unk QDECL GHL_SzFromIndex(unk){notimp(__LINE__);} +void *QDECL GHL_GetModelPtr(hledict_t *ed) { #ifdef SERVERONLY return NULL; @@ -615,7 +617,7 @@ void *GHL_GetModelPtr(hledict_t *ed) return Mod_GetHalfLifeModelData(sv.models[ed->v.modelindex]); #endif } -int GHL_RegUserMsg(char *msgname, int msgsize) +int QDECL GHL_RegUserMsg(char *msgname, int msgsize) { //we use 1 as the code to choose others. if (lastusermessage <= 1) @@ -639,47 +641,47 @@ int GHL_RegUserMsg(char *msgname, int msgsize) return lastusermessage--; } -unk GHL_AnimationAutomove(unk){notimp(__LINE__);} -unk GHL_GetBonePosition(unk){notimp(__LINE__);} +unk QDECL GHL_AnimationAutomove(unk){notimp(__LINE__);} +unk QDECL GHL_GetBonePosition(unk){notimp(__LINE__);} -hlintptr_t GHL_FunctionFromName(char *name) +hlintptr_t QDECL GHL_FunctionFromName(char *name) { return (hlintptr_t)Sys_GetAddressForName(hlgamecode, name); } -char *GHL_NameForFunction(hlintptr_t function) +char *QDECL GHL_NameForFunction(hlintptr_t function) { return Sys_GetNameForAddress(hlgamecode, (void*)function); } -unk GHL_ClientPrintf(unk) +unk QDECL GHL_ClientPrintf(unk) { // SV_ClientPrintf( notimp(__LINE__); } -void GHL_ServerPrint(char *msg) +void QDECL GHL_ServerPrint(char *msg) { Con_Printf("%s", msg); } -char *GHL_Cmd_Args(void) +char *QDECL GHL_Cmd_Args(void) { return Cmd_Args(); } -char *GHL_Cmd_Argv(int arg) +char *QDECL GHL_Cmd_Argv(int arg) { return Cmd_Argv(arg); } -int GHL_Cmd_Argc(unk) +int QDECL GHL_Cmd_Argc(unk) { return Cmd_Argc(); } -unk GHL_GetAttachment(unk){notimp(__LINE__);} -void GHL_CRC32_Init(hlcrc_t *crc) +unk QDECL GHL_GetAttachment(unk){notimp(__LINE__);} +void QDECL GHL_CRC32_Init(hlcrc_t *crc) { unsigned short crc16 = *crc; QCRC_Init(&crc16); *crc = crc16; } -void GHL_CRC32_ProcessBuffer(hlcrc_t *crc, qbyte *p, int len) +void QDECL GHL_CRC32_ProcessBuffer(hlcrc_t *crc, qbyte *p, int len) { unsigned short crc16 = *crc; while(len-->0) @@ -688,29 +690,29 @@ void GHL_CRC32_ProcessBuffer(hlcrc_t *crc, qbyte *p, int len) } *crc = crc16; } -void GHL_CRC32_ProcessByte(hlcrc_t *crc, qbyte b) +void QDECL GHL_CRC32_ProcessByte(hlcrc_t *crc, qbyte b) { unsigned short crc16 = *crc; QCRC_ProcessByte(&crc16, b); *crc = crc16; } -hlcrc_t GHL_CRC32_Final(hlcrc_t crc) +hlcrc_t QDECL GHL_CRC32_Final(hlcrc_t crc) { unsigned short crc16 = crc; return QCRC_Value(crc16); } -long GHL_RandomLong(long minv, long maxv) +long QDECL GHL_RandomLong(long minv, long maxv) { return minv + frandom()*(maxv-minv); } -float GHL_RandomFloat(float minv, float maxv) +float QDECL GHL_RandomFloat(float minv, float maxv) { return minv + frandom()*(maxv-minv); } -unk GHL_SetView(unk){notimp(__LINE__);} -unk GHL_Time(unk){notimp(__LINE__);} -unk GHL_CrosshairAngle(unk){notimp(__LINE__);} -void *GHL_LoadFileForMe(char *name, int *size_out) +unk QDECL GHL_SetView(unk){notimp(__LINE__);} +unk QDECL GHL_Time(unk){notimp(__LINE__);} +unk QDECL GHL_CrosshairAngle(unk){notimp(__LINE__);} +void *QDECL GHL_LoadFileForMe(char *name, int *size_out) { int fsize; void *fptr; @@ -721,13 +723,13 @@ void *GHL_LoadFileForMe(char *name, int *size_out) return NULL; return fptr; } -void GHL_FreeFile(void *fptr) +void QDECL GHL_FreeFile(void *fptr) { FS_FreeFile(fptr); } -unk GHL_EndSection(unk){notimp(__LINE__);} +unk QDECL GHL_EndSection(unk){notimp(__LINE__);} #include -int GHL_CompareFileTime(char *fname1, char *fname2, int *result) +int QDECL GHL_CompareFileTime(char *fname1, char *fname2, int *result) { flocation_t loc1, loc2; struct stat stat1, stat2; @@ -752,50 +754,50 @@ int GHL_CompareFileTime(char *fname1, char *fname2, int *result) return 1; } -void GHL_GetGameDir(char *gamedir) +void QDECL GHL_GetGameDir(char *gamedir) { extern char gamedirfile[]; //warning: the output buffer size is not specified! Q_strncpyz(gamedir, gamedirfile, MAX_QPATH); } -unk GHL_Cvar_RegisterVariable(unk){notimp(__LINE__);} -unk GHL_FadeClientVolume(unk){notimp(__LINE__);} -unk GHL_SetClientMaxspeed(unk) +unk QDECL GHL_Cvar_RegisterVariable(unk){notimp(__LINE__);} +unk QDECL GHL_FadeClientVolume(unk){notimp(__LINE__);} +unk QDECL GHL_SetClientMaxspeed(unk) { notimp(__LINE__); } -unk GHL_CreateFakeClient(unk){notimp(__LINE__);} -unk GHL_RunPlayerMove(unk){notimp(__LINE__);} -int GHL_NumberOfEntities(void) +unk QDECL GHL_CreateFakeClient(unk){notimp(__LINE__);} +unk QDECL GHL_RunPlayerMove(unk){notimp(__LINE__);} +int QDECL GHL_NumberOfEntities(void) { return 0; } -char *GHL_GetInfoKeyBuffer(hledict_t *ed) +char *QDECL GHL_GetInfoKeyBuffer(hledict_t *ed) { if (!ed) return svs.info; return svs.clients[ed - SVHL_Edict - 1].userinfo; } -char *GHL_InfoKeyValue(char *infostr, char *key) +char *QDECL GHL_InfoKeyValue(char *infostr, char *key) { return Info_ValueForKey(infostr, key); } -unk GHL_SetKeyValue(unk){notimp(__LINE__);} -unk GHL_SetClientKeyValue(unk){notimp(__LINE__);} -unk GHL_IsMapValid(unk){notimp(__LINE__);} -unk GHL_StaticDecal(unk){notimp(__LINE__);} -unk GHL_PrecacheGeneric(unk){notimp(__LINE__);} -int GHL_GetPlayerUserId(hledict_t *ed) +unk QDECL GHL_SetKeyValue(unk){notimp(__LINE__);} +unk QDECL GHL_SetClientKeyValue(unk){notimp(__LINE__);} +unk QDECL GHL_IsMapValid(unk){notimp(__LINE__);} +unk QDECL GHL_StaticDecal(unk){notimp(__LINE__);} +unk QDECL GHL_PrecacheGeneric(unk){notimp(__LINE__);} +int QDECL GHL_GetPlayerUserId(hledict_t *ed) { unsigned int clnum = (ed - SVHL_Edict) - 1; if (clnum >= sv.allocated_client_slots) return -1; return svs.clients[clnum].userid; } -unk GHL_BuildSoundMsg(unk){notimp(__LINE__);} +unk QDECL GHL_BuildSoundMsg(unk){notimp(__LINE__);} -int GHL_IsDedicatedServer(void) +int QDECL GHL_IsDedicatedServer(void) { #ifdef SERVERONLY return 1; @@ -878,7 +880,7 @@ void SVHL_FreeCvar(hlcvar_t *var) } } -hlcvar_t *GHL_CVarGetPointer(char *varname) +hlcvar_t *QDECL GHL_CVarGetPointer(char *varname) { cvar_t *var; hlcvar_t *hlvar; @@ -901,7 +903,7 @@ hlcvar_t *GHL_CVarGetPointer(char *varname) } return hlvar; } -void GHL_CVarRegister(hlcvar_t *hlvar) +void QDECL GHL_CVarRegister(hlcvar_t *hlvar) { cvar_t *var; var = Cvar_Get(hlvar->name, hlvar->string, 0, "HalfLife"); @@ -919,7 +921,7 @@ void GHL_CVarRegister(hlcvar_t *hlvar) } var->hlcvar = hlvar; } -float GHL_CVarGetFloat(char *vname) +float QDECL GHL_CVarGetFloat(char *vname) { cvar_t *var = Cvar_FindVar(vname); if (var) @@ -927,7 +929,7 @@ float GHL_CVarGetFloat(char *vname) Con_Printf("cvar %s does not exist\n", vname); return 0; } -char *GHL_CVarGetString(char *vname) +char *QDECL GHL_CVarGetString(char *vname) { cvar_t *var = Cvar_FindVar(vname); if (var) @@ -935,7 +937,7 @@ char *GHL_CVarGetString(char *vname) Con_Printf("cvar %s does not exist\n", vname); return ""; } -void GHL_CVarSetFloat(char *vname, float value) +void QDECL GHL_CVarSetFloat(char *vname, float value) { cvar_t *var = Cvar_FindVar(vname); if (var) @@ -943,7 +945,7 @@ void GHL_CVarSetFloat(char *vname, float value) else Con_Printf("cvar %s does not exist\n", vname); } -void GHL_CVarSetString(char *vname, char *value) +void QDECL GHL_CVarSetString(char *vname, char *value) { cvar_t *var = Cvar_FindVar(vname); if (var) @@ -952,56 +954,56 @@ void GHL_CVarSetString(char *vname, char *value) Con_Printf("cvar %s does not exist\n", vname); } -unk GHL_GetPlayerWONId(unk){notimp(__LINE__);} -unk GHL_Info_RemoveKey(unk){notimp(__LINE__);} -unk GHL_GetPhysicsKeyValue(unk){notimp(__LINE__);} -unk GHL_SetPhysicsKeyValue(unk){notimp(__LINE__);} -unk GHL_GetPhysicsInfoString(unk){notimp(__LINE__);} -unsigned short GHL_PrecacheEvent(int eventtype, char *eventname) +unk QDECL GHL_GetPlayerWONId(unk){notimp(__LINE__);} +unk QDECL GHL_Info_RemoveKey(unk){notimp(__LINE__);} +unk QDECL GHL_GetPhysicsKeyValue(unk){notimp(__LINE__);} +unk QDECL GHL_SetPhysicsKeyValue(unk){notimp(__LINE__);} +unk QDECL GHL_GetPhysicsInfoString(unk){notimp(__LINE__);} +unsigned short QDECL GHL_PrecacheEvent(int eventtype, char *eventname) { Con_Printf("Fixme: GHL_PrecacheEvent: %s\n", eventname); return 0; } -void GHL_PlaybackEvent(int flags, hledict_t *ent, unsigned short eventidx, float delay, float *origin, float *angles, float f1, float f2, int i1, int i2, int b1, int b2) +void QDECL GHL_PlaybackEvent(int flags, hledict_t *ent, unsigned short eventidx, float delay, float *origin, float *angles, float f1, float f2, int i1, int i2, int b1, int b2) { ignore("GHL_PlaybackEvent not implemented"); } -unk GHL_SetFatPVS(unk){notimp(__LINE__);} -unk GHL_SetFatPAS(unk){notimp(__LINE__);} -unk GHL_CheckVisibility(unk){notimp(__LINE__);} -unk GHL_DeltaSetField(unk){notimp(__LINE__);} -unk GHL_DeltaUnsetField(unk){notimp(__LINE__);} -unk GHL_DeltaAddEncoder(unk){notimp(__LINE__);} -unk GHL_GetCurrentPlayer(unk){notimp(__LINE__);} -unk GHL_CanSkipPlayer(unk){notimp(__LINE__);} -unk GHL_DeltaFindField(unk){notimp(__LINE__);} -unk GHL_DeltaSetFieldByIndex(unk){notimp(__LINE__);} -unk GHL_DeltaUnsetFieldByIndex(unk){notimp(__LINE__);} -unk GHL_SetGroupMask(unk){notimp(__LINE__);} -unk GHL_CreateInstancedBaseline(unk){notimp(__LINE__);} -unk GHL_Cvar_DirectSet(unk){notimp(__LINE__);} -unk GHL_ForceUnmodified(unk){notimp(__LINE__);} -unk GHL_GetPlayerStats(unk){notimp(__LINE__);} -unk GHL_AddServerCommand(unk){notimp(__LINE__);} -unk GHL_Voice_GetClientListening(unk){notimp(__LINE__);} -qboolean GHL_Voice_SetClientListening(int listener, int sender, int shouldlisten) +unk QDECL GHL_SetFatPVS(unk){notimp(__LINE__);} +unk QDECL GHL_SetFatPAS(unk){notimp(__LINE__);} +unk QDECL GHL_CheckVisibility(unk){notimp(__LINE__);} +unk QDECL GHL_DeltaSetField(unk){notimp(__LINE__);} +unk QDECL GHL_DeltaUnsetField(unk){notimp(__LINE__);} +unk QDECL GHL_DeltaAddEncoder(unk){notimp(__LINE__);} +unk QDECL GHL_GetCurrentPlayer(unk){notimp(__LINE__);} +unk QDECL GHL_CanSkipPlayer(unk){notimp(__LINE__);} +unk QDECL GHL_DeltaFindField(unk){notimp(__LINE__);} +unk QDECL GHL_DeltaSetFieldByIndex(unk){notimp(__LINE__);} +unk QDECL GHL_DeltaUnsetFieldByIndex(unk){notimp(__LINE__);} +unk QDECL GHL_SetGroupMask(unk){notimp(__LINE__);} +unk QDECL GHL_CreateInstancedBaseline(unk){notimp(__LINE__);} +unk QDECL GHL_Cvar_DirectSet(unk){notimp(__LINE__);} +unk QDECL GHL_ForceUnmodified(unk){notimp(__LINE__);} +unk QDECL GHL_GetPlayerStats(unk){notimp(__LINE__);} +unk QDECL GHL_AddServerCommand(unk){notimp(__LINE__);} +unk QDECL GHL_Voice_GetClientListening(unk){notimp(__LINE__);} +qboolean QDECL GHL_Voice_SetClientListening(int listener, int sender, int shouldlisten) { return false; } -unk GHL_GetPlayerAuthId(unk){notimp(__LINE__);} -unk GHL_SequenceGet(unk){notimp(__LINE__);} -unk GHL_SequencePickSentence(unk){notimp(__LINE__);} -unk GHL_GetFileSize(unk){notimp(__LINE__);} -unk GHL_GetApproxWavePlayLen(unk){notimp(__LINE__);} -unk GHL_IsCareerMatch(unk){notimp(__LINE__);} -unk GHL_GetLocalizedStringLength(unk){notimp(__LINE__);} -unk GHL_RegisterTutorMessageShown(unk){notimp(__LINE__);} -unk GHL_GetTimesTutorMessageShown(unk){notimp(__LINE__);} -unk GHL_ProcessTutorMessageDecayBuffer(unk){notimp(__LINE__);} -unk GHL_ConstructTutorMessageDecayBuffer(unk){notimp(__LINE__);} -unk GHL_ResetTutorMessageDecayData(unk){notimp(__LINE__);} -unk GHL_QueryClientCvarValue(unk){notimp(__LINE__);} -unk GHL_QueryClientCvarValue2(unk){notimp(__LINE__);} +unk QDECL GHL_GetPlayerAuthId(unk){notimp(__LINE__);} +unk QDECL GHL_SequenceGet(unk){notimp(__LINE__);} +unk QDECL GHL_SequencePickSentence(unk){notimp(__LINE__);} +unk QDECL GHL_GetFileSize(unk){notimp(__LINE__);} +unk QDECL GHL_GetApproxWavePlayLen(unk){notimp(__LINE__);} +unk QDECL GHL_IsCareerMatch(unk){notimp(__LINE__);} +unk QDECL GHL_GetLocalizedStringLength(unk){notimp(__LINE__);} +unk QDECL GHL_RegisterTutorMessageShown(unk){notimp(__LINE__);} +unk QDECL GHL_GetTimesTutorMessageShown(unk){notimp(__LINE__);} +unk QDECL GHL_ProcessTutorMessageDecayBuffer(unk){notimp(__LINE__);} +unk QDECL GHL_ConstructTutorMessageDecayBuffer(unk){notimp(__LINE__);} +unk QDECL GHL_ResetTutorMessageDecayData(unk){notimp(__LINE__);} +unk QDECL GHL_QueryClientCvarValue(unk){notimp(__LINE__);} +unk QDECL GHL_QueryClientCvarValue2(unk){notimp(__LINE__);} @@ -1216,8 +1218,8 @@ int SVHL_InitGame(void) char *gamedll; char *path; char fullname[MAX_OSPATH]; - void (*GiveFnptrsToDll) (funcs, globals); - int (*GetEntityAPI)(SVHL_GameFuncs_t *pFunctionTable, int apivers); + void (QDECL *GiveFnptrsToDll) (funcs, globals); + int (QDECL *GetEntityAPI)(SVHL_GameFuncs_t *pFunctionTable, int apivers); dllfunction_t hlgamefuncs[] = { @@ -1262,7 +1264,9 @@ int SVHL_InitGame(void) if (!GetEntityAPI(&SVHL_GameFuncs, HALFLIFE_API_VERSION)) { - Con_Printf(CON_ERROR "Error: %s is incompatible\n", fullname); + Con_Printf(CON_ERROR "Error: %s is incompatible (FTE is %i)\n", fullname, HALFLIFE_API_VERSION); + if (GetEntityAPI(&SVHL_GameFuncs, 138)) + Con_Printf(CON_ERROR "mod is 138\n"); Sys_CloseLibrary(hlgamecode); hlgamecode = NULL; return 0; diff --git a/engine/server/svhl_gcapi.h b/engine/server/svhl_gcapi.h index 7bc7561b..e15e8126 100644 --- a/engine/server/svhl_gcapi.h +++ b/engine/server/svhl_gcapi.h @@ -1,5 +1,20 @@ -//#define HALFLIFE_API_VERSION 138 -#define HALFLIFE_API_VERSION 140 +/*supported halflife API versions: +138 +140 +*/ +#if HLSERVER >= 1 + #define HALFLIFE_API_VERSION HLSERVER +#else + #define HALFLIFE_API_VERSION 140 +#endif + +#ifndef QDECL + #ifdef _MSC_VER + #define QDECL _cdecl + #else + #define QDECL + #endif +#endif typedef long hllong; //long is 64bit on amd64+linux, not sure that's what valve meant, but lets keep it for compatibility. typedef struct hledict_s hledict_t; @@ -317,237 +332,237 @@ vec3_t landmark; //http://metamod.org/dllapi_notes.html typedef struct { - void (*GameDLLInit)(void); - int (*DispatchSpawn)(hledict_t *ed); - void (*DispatchThink)(hledict_t *ed); - unk (*DispatchUse)(unk); - void (*DispatchTouch)(hledict_t *e1, hledict_t *e2); - void (*DispatchBlocked)(hledict_t *self, hledict_t *other); - void (*DispatchKeyValue)(hledict_t *ed, hlfielddef_t *fdef); - unk (*DispatchSave)(unk); - unk (*DispatchRestore)(unk); - unk (*DispatchObjectCollsionBox)(unk); - unk (*SaveWriteFields)(unk); - unk (*SaveReadFields)(unk); - unk (*SaveGlobalState)(unk); - unk (*RestoreGlobalState)(unk); - unk (*ResetGlobalState)(unk); - qboolean (*ClientConnect)(hledict_t *ed, char *name, char *ip, char reject[128]); - void (*ClientDisconnect)(hledict_t *ed); - void (*ClientKill)(hledict_t *ed); - void (*ClientPutInServer)(hledict_t *ed); - void (*ClientCommand)(hledict_t *ed); - unk (*ClientUserInfoChanged)(unk); - void (*ServerActivate)(hledict_t *edictlist, int numedicts, int numplayers); + void (QDECL *GameDLLInit)(void); + int (QDECL *DispatchSpawn)(hledict_t *ed); + void (QDECL *DispatchThink)(hledict_t *ed); + unk (QDECL *DispatchUse)(unk); + void (QDECL *DispatchTouch)(hledict_t *e1, hledict_t *e2); + void (QDECL *DispatchBlocked)(hledict_t *self, hledict_t *other); + void (QDECL *DispatchKeyValue)(hledict_t *ed, hlfielddef_t *fdef); + unk (QDECL *DispatchSave)(unk); + unk (QDECL *DispatchRestore)(unk); + unk (QDECL *DispatchObjectCollsionBox)(unk); + unk (QDECL *SaveWriteFields)(unk); + unk (QDECL *SaveReadFields)(unk); + unk (QDECL *SaveGlobalState)(unk); + unk (QDECL *RestoreGlobalState)(unk); + unk (QDECL *ResetGlobalState)(unk); + qboolean (QDECL *ClientConnect)(hledict_t *ed, char *name, char *ip, char reject[128]); + void (QDECL *ClientDisconnect)(hledict_t *ed); + void (QDECL *ClientKill)(hledict_t *ed); + void (QDECL *ClientPutInServer)(hledict_t *ed); + void (QDECL *ClientCommand)(hledict_t *ed); + unk (QDECL *ClientUserInfoChanged)(unk); + void (QDECL *ServerActivate)(hledict_t *edictlist, int numedicts, int numplayers); #if HALFLIFE_API_VERSION > 138 - unk (*ServerDeactivate)(unk); + unk (QDECL *ServerDeactivate)(unk); #endif - void (*PlayerPreThink)(hledict_t *ed); - void (*PlayerPostThink)(hledict_t *ed); - unk (*StartFrame)(unk); - unk (*ParmsNewLevel)(unk); - unk (*ParmsChangeLevel)(unk); - unk (*GetGameDescription)(unk); - unk (*PlayerCustomization)(unk); - unk (*SpectatorConnect)(unk); - unk (*SpectatorDisconnect)(unk); - unk (*SpectatorThink)(unk); + void (QDECL *PlayerPreThink)(hledict_t *ed); + void (QDECL *PlayerPostThink)(hledict_t *ed); + unk (QDECL *StartFrame)(unk); + unk (QDECL *ParmsNewLevel)(unk); + unk (QDECL *ParmsChangeLevel)(unk); + unk (QDECL *GetGameDescription)(unk); + unk (QDECL *PlayerCustomization)(unk); + unk (QDECL *SpectatorConnect)(unk); + unk (QDECL *SpectatorDisconnect)(unk); + unk (QDECL *SpectatorThink)(unk); //138 #if HALFLIFE_API_VERSION > 138 - unk (*Sys_Error)(unk); - unk (*PM_Move)(unk); - unk (*PM_Init)(unk); - unk (*PM_FindTextureType)(unk); - unk (*SetupVisibility)(unk); - unk (*UpdateClientData)(unk); - unk (*AddToFullPack)(unk); - unk (*CreateBaseline)(unk); - unk (*RegisterEncoders)(unk); - unk (*GetWeaponData)(unk); - unk (*CmdStart)(unk); - unk (*CmdEnd)(unk); - unk (*ConnectionlessPacket)(unk); - unk (*GetHullBounds)(unk); - unk (*CreateInstancedBaselines)(unk); - unk (*InconsistentFile)(unk); - unk (*AllowLagCompensation)(unk); + unk (QDECL *Sys_Error)(unk); + unk (QDECL *PM_Move)(unk); + unk (QDECL *PM_Init)(unk); + unk (QDECL *PM_FindTextureType)(unk); + unk (QDECL *SetupVisibility)(unk); + unk (QDECL *UpdateClientData)(unk); + unk (QDECL *AddToFullPack)(unk); + unk (QDECL *CreateBaseline)(unk); + unk (QDECL *RegisterEncoders)(unk); + unk (QDECL *GetWeaponData)(unk); + unk (QDECL *CmdStart)(unk); + unk (QDECL *CmdEnd)(unk); + unk (QDECL *ConnectionlessPacket)(unk); + unk (QDECL *GetHullBounds)(unk); + unk (QDECL *CreateInstancedBaselines)(unk); + unk (QDECL *InconsistentFile)(unk); + unk (QDECL *AllowLagCompensation)(unk); #endif } SVHL_GameFuncs_t; //http://metamod.org/newapi_notes.html struct { - unk (*OnFreeEntPrivateData)(unk); - unk (*GameShutdown)(unk); - unk (*ShouldCollide)(unk); - unk (*CvarValue)(unk); - unk (*CvarValue2 )(unk); + unk (QDECL *OnFreeEntPrivateData)(unk); + unk (QDECL *GameShutdown)(unk); + unk (QDECL *ShouldCollide)(unk); + unk (QDECL *CvarValue)(unk); + unk (QDECL *CvarValue2 )(unk); } *SVHL_GameFuncsEx; // http://metamod.org/engine_notes.html typedef struct { - int (*PrecacheModel)(char *name); - int (*PrecacheSound)(char *name); - void (*SetModel)(hledict_t *ed, char *modelname); - unk (*ModelIndex)(unk); - int (*ModelFrames)(int midx); - void (*SetSize)(hledict_t *ed, float *mins, float *maxs); - void (*ChangeLevel)(char *nextmap, char *startspot); - unk (*GetSpawnParms)(unk); - unk (*SaveSpawnParms)(unk); - float (*VecToYaw)(float *inv); - void (*VecToAngles)(float *inv, float *outa); - unk (*MoveToOrigin)(unk); - unk (*ChangeYaw)(unk); - unk (*ChangePitch)(unk); - hledict_t *(*FindEntityByString)(hledict_t *last, char *field, char *value); - unk (*GetEntityIllum)(unk); - hledict_t *(*FindEntityInSphere)(hledict_t *last, float *org, float radius); - hledict_t *(*FindClientInPVS)(hledict_t *ed); - unk (*EntitiesInPVS)(unk); - void (*MakeVectors)(float *angles); - void (*AngleVectors)(float *angles, float *forward, float *right, float *up); - hledict_t *(*CreateEntity)(void); - void (*RemoveEntity)(hledict_t *ed); - hledict_t *(*CreateNamedEntity)(string_t name); - unk (*MakeStatic)(unk); - unk (*EntIsOnFloor)(unk); - int (*DropToFloor)(hledict_t *ed); - int (*WalkMove)(hledict_t *ed, float yaw, float dist, int mode); - void (*SetOrigin)(hledict_t *ed, float *neworg); - void (*EmitSound)(hledict_t *ed, int chan, char *soundname, float vol, float atten, int flags, int pitch); - void (*EmitAmbientSound)(hledict_t *ed, float *org, char *samp, float vol, float attenuation, unsigned int flags, int pitch); - void (*TraceLine)(float *start, float *end, int flags, hledict_t *ignore, hltraceresult_t *result); - unk (*TraceToss)(unk); - unk (*TraceMonsterHull)(unk); - void (*TraceHull)(float *start, float *end, int flags, int hullnum, hledict_t *ignore, hltraceresult_t *result); - unk (*TraceModel)(unk); - char *(*TraceTexture)(hledict_t *againstent, vec3_t start, vec3_t end); - unk (*TraceSphere)(unk); - unk (*GetAimVector)(unk); - void (*ServerCommand)(char *cmd); - void (*ServerExecute)(void); - unk (*ClientCommand)(unk); - unk (*ParticleEffect)(unk); - void (*LightStyle)(int stylenum, char *stylestr); - int (*DecalIndex)(char *decalname); - int (*PointContents)(float *org); - void (*MessageBegin)(int dest, int svc, float *org, hledict_t *ent); - void (*MessageEnd)(void); - void (*WriteByte)(int value); - void (*WriteChar)(int value); - void (*WriteShort)(int value); - void (*WriteLong)(int value); - void (*WriteAngle)(float value); - void (*WriteCoord)(float value); - void (*WriteString)(char *string); - void (*WriteEntity)(int entnum); - void (*CVarRegister)(hlcvar_t *hlvar); - float (*CVarGetFloat)(char *vname); - char *(*CVarGetString)(char *vname); - void (*CVarSetFloat)(char *vname, float v); - void (*CVarSetString)(char *vname, char *v); - void (*AlertMessage)(int level, char *fmt, ...); - void (*EngineFprintf)(FILE *f, char *fmt, ...); - void *(*PvAllocEntPrivateData)(hledict_t *ed, long quant); - unk (*PvEntPrivateData)(unk); - unk (*FreeEntPrivateData)(unk); - unk (*SzFromIndex)(unk); - string_t (*AllocString)(char *string); - unk (*GetVarsOfEnt)(unk); - hledict_t * (*PEntityOfEntOffset)(int ednum); - int (*EntOffsetOfPEntity)(hledict_t *ed); - int (*IndexOfEdict)(hledict_t *ed); - hledict_t *(*PEntityOfEntIndex)(int idx); - unk (*FindEntityByVars)(unk); - void *(*GetModelPtr)(hledict_t *ed); - int (*RegUserMsg)(char *msgname, int msgsize); - unk (*AnimationAutomove)(unk); - unk (*GetBonePosition)(unk); - hlintptr_t (*FunctionFromName)(char *name); - char *(*NameForFunction)(hlintptr_t); - unk (*ClientPrintf)(unk); - void (*ServerPrint)(char *msg); - char *(*Cmd_Args)(void); - char *(*Cmd_Argv)(int argno); - int (*Cmd_Argc)(void); - unk (*GetAttachment)(unk); - void (*CRC32_Init)(hlcrc_t *crc); - void (*CRC32_ProcessBuffer)(hlcrc_t *crc, qbyte *p, int len); - void (*CRC32_ProcessByte)(hlcrc_t *crc, qbyte b); - hlcrc_t (*CRC32_Final)(hlcrc_t crc); - long (*RandomLong)(long minv, long maxv); - float (*RandomFloat)(float minv, float maxv); - unk (*SetView)(unk); - unk (*Time)(unk); - unk (*CrosshairAngle)(unk); - void *(*LoadFileForMe)(char *name, int *size_out); - void (*FreeFile)(void *fptr); - unk (*EndSection)(unk); - int (*CompareFileTime)(char *fname1, char *fname2, int *result); - void (*GetGameDir)(char *gamedir); - unk (*Cvar_RegisterVariable)(unk); - unk (*FadeClientVolume)(unk); - unk (*SetClientMaxspeed)(unk); - unk (*CreateFakeClient)(unk); - unk (*RunPlayerMove)(unk); - unk (*NumberOfEntities)(unk); - unk (*GetInfoKeyBuffer)(unk); - unk (*InfoKeyValue)(unk); - unk (*SetKeyValue)(unk); - unk (*SetClientKeyValue)(unk); - unk (*IsMapValid)(unk); - unk (*StaticDecal)(unk); - unk (*PrecacheGeneric)(unk); - int (*GetPlayerUserId)(hledict_t *ed); - unk (*BuildSoundMsg)(unk); - unk (*IsDedicatedServer)(unk); + int (QDECL *PrecacheModel)(char *name); + int (QDECL *PrecacheSound)(char *name); + void (QDECL *SetModel)(hledict_t *ed, char *modelname); + unk (QDECL *ModelIndex)(unk); + int (QDECL *ModelFrames)(int midx); + void (QDECL *SetSize)(hledict_t *ed, float *mins, float *maxs); + void (QDECL *ChangeLevel)(char *nextmap, char *startspot); + unk (QDECL *GetSpawnParms)(unk); + unk (QDECL *SaveSpawnParms)(unk); + float (QDECL *VecToYaw)(float *inv); + void (QDECL *VecToAngles)(float *inv, float *outa); + unk (QDECL *MoveToOrigin)(unk); + unk (QDECL *ChangeYaw)(unk); + unk (QDECL *ChangePitch)(unk); + hledict_t *(QDECL *FindEntityByString)(hledict_t *last, char *field, char *value); + unk (QDECL *GetEntityIllum)(unk); + hledict_t *(QDECL *FindEntityInSphere)(hledict_t *last, float *org, float radius); + hledict_t *(QDECL *FindClientInPVS)(hledict_t *ed); + unk (QDECL *EntitiesInPVS)(unk); + void (QDECL *MakeVectors)(float *angles); + void (QDECL *AngleVectors)(float *angles, float *forward, float *right, float *up); + hledict_t *(QDECL *CreateEntity)(void); + void (QDECL *RemoveEntity)(hledict_t *ed); + hledict_t *(QDECL *CreateNamedEntity)(string_t name); + unk (QDECL *MakeStatic)(unk); + unk (QDECL *EntIsOnFloor)(unk); + int (QDECL *DropToFloor)(hledict_t *ed); + int (QDECL *WalkMove)(hledict_t *ed, float yaw, float dist, int mode); + void (QDECL *SetOrigin)(hledict_t *ed, float *neworg); + void (QDECL *EmitSound)(hledict_t *ed, int chan, char *soundname, float vol, float atten, int flags, int pitch); + void (QDECL *EmitAmbientSound)(hledict_t *ed, float *org, char *samp, float vol, float attenuation, unsigned int flags, int pitch); + void (QDECL *TraceLine)(float *start, float *end, int flags, hledict_t *ignore, hltraceresult_t *result); + unk (QDECL *TraceToss)(unk); + unk (QDECL *TraceMonsterHull)(unk); + void (QDECL *TraceHull)(float *start, float *end, int flags, int hullnum, hledict_t *ignore, hltraceresult_t *result); + unk (QDECL *TraceModel)(unk); + char *(QDECL *TraceTexture)(hledict_t *againstent, vec3_t start, vec3_t end); + unk (QDECL *TraceSphere)(unk); + unk (QDECL *GetAimVector)(unk); + void (QDECL *ServerCommand)(char *cmd); + void (QDECL *ServerExecute)(void); + unk (QDECL *ClientCommand)(unk); + unk (QDECL *ParticleEffect)(unk); + void (QDECL *LightStyle)(int stylenum, char *stylestr); + int (QDECL *DecalIndex)(char *decalname); + int (QDECL *PointContents)(float *org); + void (QDECL *MessageBegin)(int dest, int svc, float *org, hledict_t *ent); + void (QDECL *MessageEnd)(void); + void (QDECL *WriteByte)(int value); + void (QDECL *WriteChar)(int value); + void (QDECL *WriteShort)(int value); + void (QDECL *WriteLong)(int value); + void (QDECL *WriteAngle)(float value); + void (QDECL *WriteCoord)(float value); + void (QDECL *WriteString)(char *string); + void (QDECL *WriteEntity)(int entnum); + void (QDECL *CVarRegister)(hlcvar_t *hlvar); + float (QDECL *CVarGetFloat)(char *vname); + char *(QDECL *CVarGetString)(char *vname); + void (QDECL *CVarSetFloat)(char *vname, float v); + void (QDECL *CVarSetString)(char *vname, char *v); + void (QDECL *AlertMessage)(int level, char *fmt, ...); + void (QDECL *EngineFprintf)(FILE *f, char *fmt, ...); + void *(QDECL *PvAllocEntPrivateData)(hledict_t *ed, long quant); + unk (QDECL *PvEntPrivateData)(unk); + unk (QDECL *FreeEntPrivateData)(unk); + unk (QDECL *SzFromIndex)(unk); + string_t (QDECL *AllocString)(char *string); + unk (QDECL *GetVarsOfEnt)(unk); + hledict_t * (QDECL *PEntityOfEntOffset)(int ednum); + int (QDECL *EntOffsetOfPEntity)(hledict_t *ed); + int (QDECL *IndexOfEdict)(hledict_t *ed); + hledict_t *(QDECL *PEntityOfEntIndex)(int idx); + unk (QDECL *FindEntityByVars)(unk); + void *(QDECL *GetModelPtr)(hledict_t *ed); + int (QDECL *RegUserMsg)(char *msgname, int msgsize); + unk (QDECL *AnimationAutomove)(unk); + unk (QDECL *GetBonePosition)(unk); + hlintptr_t (QDECL *FunctionFromName)(char *name); + char *(QDECL *NameForFunction)(hlintptr_t); + unk (QDECL *ClientPrintf)(unk); + void (QDECL *ServerPrint)(char *msg); + char *(QDECL *Cmd_Args)(void); + char *(QDECL *Cmd_Argv)(int argno); + int (QDECL *Cmd_Argc)(void); + unk (QDECL *GetAttachment)(unk); + void (QDECL *CRC32_Init)(hlcrc_t *crc); + void (QDECL *CRC32_ProcessBuffer)(hlcrc_t *crc, qbyte *p, int len); + void (QDECL *CRC32_ProcessByte)(hlcrc_t *crc, qbyte b); + hlcrc_t (QDECL *CRC32_Final)(hlcrc_t crc); + long (QDECL *RandomLong)(long minv, long maxv); + float (QDECL *RandomFloat)(float minv, float maxv); + unk (QDECL *SetView)(unk); + unk (QDECL *Time)(unk); + unk (QDECL *CrosshairAngle)(unk); + void *(QDECL *LoadFileForMe)(char *name, int *size_out); + void (QDECL *FreeFile)(void *fptr); + unk (QDECL *EndSection)(unk); + int (QDECL *CompareFileTime)(char *fname1, char *fname2, int *result); + void (QDECL *GetGameDir)(char *gamedir); + unk (QDECL *Cvar_RegisterVariable)(unk); + unk (QDECL *FadeClientVolume)(unk); + unk (QDECL *SetClientMaxspeed)(unk); + unk (QDECL *CreateFakeClient)(unk); + unk (QDECL *RunPlayerMove)(unk); + unk (QDECL *NumberOfEntities)(unk); + char *(QDECL *GHL_GetInfoKeyBuffer)(hledict_t *ed); + char *(QDECL *GHL_InfoKeyValue)(char *infostr, char *key); + unk (QDECL *SetKeyValue)(unk); + unk (QDECL *SetClientKeyValue)(unk); + unk (QDECL *IsMapValid)(unk); + unk (QDECL *StaticDecal)(unk); + unk (QDECL *PrecacheGeneric)(unk); + int (QDECL *GetPlayerUserId)(hledict_t *ed); + unk (QDECL *BuildSoundMsg)(unk); + unk (QDECL *IsDedicatedServer)(unk); //138 #if HALFLIFE_API_VERSION > 138 - hlcvar_t *(*CVarGetPointer)(char *varname); - unk (*GetPlayerWONId)(unk); - unk (*Info_RemoveKey)(unk); - unk (*GetPhysicsKeyValue)(unk); - unk (*SetPhysicsKeyValue)(unk); - unk (*GetPhysicsInfoString)(unk); - unsigned short (*PrecacheEvent)(int eventtype, char *eventname); - void (*PlaybackEvent)(int flags, hledict_t *ent, unsigned short eventidx, float delay, float *origin, float *angles, float f1, float f2, int i1, int i2, int b1, int b2); - unk (*SetFatPVS)(unk); - unk (*SetFatPAS)(unk); - unk (*CheckVisibility)(unk); - unk (*DeltaSetField)(unk); - unk (*DeltaUnsetField)(unk); - unk (*DeltaAddEncoder)(unk); - unk (*GetCurrentPlayer)(unk); - unk (*CanSkipPlayer)(unk); - unk (*DeltaFindField)(unk); - unk (*DeltaSetFieldByIndex)(unk); - unk (*DeltaUnsetFieldByIndex)(unk); - unk (*SetGroupMask)(unk); - unk (*CreateInstancedBaseline)(unk); - unk (*Cvar_DirectSet)(unk); - unk (*ForceUnmodified)(unk); - unk (*GetPlayerStats)(unk); - unk (*AddServerCommand)(unk); + hlcvar_t *(QDECL *CVarGetPointer)(char *varname); + unk (QDECL *GetPlayerWONId)(unk); + unk (QDECL *Info_RemoveKey)(unk); + unk (QDECL *GetPhysicsKeyValue)(unk); + unk (QDECL *SetPhysicsKeyValue)(unk); + unk (QDECL *GetPhysicsInfoString)(unk); + unsigned short (QDECL *PrecacheEvent)(int eventtype, char *eventname); + void (QDECL *PlaybackEvent)(int flags, hledict_t *ent, unsigned short eventidx, float delay, float *origin, float *angles, float f1, float f2, int i1, int i2, int b1, int b2); + unk (QDECL *SetFatPVS)(unk); + unk (QDECL *SetFatPAS)(unk); + unk (QDECL *CheckVisibility)(unk); + unk (QDECL *DeltaSetField)(unk); + unk (QDECL *DeltaUnsetField)(unk); + unk (QDECL *DeltaAddEncoder)(unk); + unk (QDECL *GetCurrentPlayer)(unk); + unk (QDECL *CanSkipPlayer)(unk); + unk (QDECL *DeltaFindField)(unk); + unk (QDECL *DeltaSetFieldByIndex)(unk); + unk (QDECL *DeltaUnsetFieldByIndex)(unk); + unk (QDECL *SetGroupMask)(unk); + unk (QDECL *CreateInstancedBaseline)(unk); + unk (QDECL *Cvar_DirectSet)(unk); + unk (QDECL *ForceUnmodified)(unk); + unk (QDECL *GetPlayerStats)(unk); + unk (QDECL *AddServerCommand)(unk); // - unk (*Voice_GetClientListening)(unk); - qboolean (*Voice_SetClientListening)(int listener, int sender, int shouldlisten); + unk (QDECL *Voice_GetClientListening)(unk); + qboolean (QDECL *Voice_SetClientListening)(int listener, int sender, int shouldlisten); //140 - unk (*GetPlayerAuthId)(unk); - unk (*SequenceGet)(unk); - unk (*SequencePickSentence)(unk); - unk (*GetFileSize)(unk); - unk (*GetApproxWavePlayLen)(unk); - unk (*IsCareerMatch)(unk); - unk (*GetLocalizedStringLength)(unk); - unk (*RegisterTutorMessageShown)(unk); - unk (*GetTimesTutorMessageShown)(unk); - unk (*ProcessTutorMessageDecayBuffer)(unk); - unk (*ConstructTutorMessageDecayBuffer)(unk); - unk (*ResetTutorMessageDecayData)(unk); - unk (*QueryClientCvarValue)(unk); - unk (*QueryClientCvarValue2)(unk); + unk (QDECL *GetPlayerAuthId)(unk); + unk (QDECL *SequenceGet)(unk); + unk (QDECL *SequencePickSentence)(unk); + unk (QDECL *GetFileSize)(unk); + unk (QDECL *GetApproxWavePlayLen)(unk); + unk (QDECL *IsCareerMatch)(unk); + unk (QDECL *GetLocalizedStringLength)(unk); + unk (QDECL *RegisterTutorMessageShown)(unk); + unk (QDECL *GetTimesTutorMessageShown)(unk); + unk (QDECL *ProcessTutorMessageDecayBuffer)(unk); + unk (QDECL *ConstructTutorMessageDecayBuffer)(unk); + unk (QDECL *ResetTutorMessageDecayData)(unk); + unk (QDECL *QueryClientCvarValue)(unk); + unk (QDECL *QueryClientCvarValue2)(unk); #endif int check; //added so I can be sure parameters match this list, etc @@ -560,8 +575,7 @@ extern hledict_t *SVHL_Edict; extern int SVHL_NumActiveEnts; - - +void QDECL GHL_RemoveEntity(hledict_t *ed); void SVHL_LinkEdict (hledict_t *ent, qboolean touch_triggers); void SVHL_UnlinkEdict (hledict_t *ent); diff --git a/engine/server/svq2_ents.c b/engine/server/svq2_ents.c index 68c69d79..8e9727a1 100644 --- a/engine/server/svq2_ents.c +++ b/engine/server/svq2_ents.c @@ -19,9 +19,6 @@ int svs_next_client_entities; q2entity_state_t sv_baselines[Q2MAX_EDICTS]; -int areabytes; -extern qbyte areabits[]; - /* ============================================================================= @@ -582,8 +579,8 @@ void SV_WriteFrameToClient (client_t *client, sizebuf_t *msg) // client->surpressCount = 0; // send over the areabits - MSG_WriteByte (msg, areabytes); - SZ_Write (msg, areabits, areabytes); + MSG_WriteByte (msg, frame->areabytes); + SZ_Write (msg, frame->areabits, frame->areabytes); // delta encode the playerstate SVQ2_WritePlayerstateToClient (oldframe, frame, msg); @@ -648,19 +645,19 @@ void SV_BuildClientFrame (client_t *client) for (i=0 ; i<3 ; i++) org[i] = clent->client->ps.pmove.origin[i]*0.125 + clent->client->ps.viewoffset[i]; - leafnum = CM_PointLeafnum (sv.worldmodel, org); - clientarea = CM_LeafArea (sv.worldmodel, leafnum); - clientcluster = CM_LeafCluster (sv.worldmodel, leafnum); + leafnum = CM_PointLeafnum (sv.world.worldmodel, org); + clientarea = CM_LeafArea (sv.world.worldmodel, leafnum); + clientcluster = CM_LeafCluster (sv.world.worldmodel, leafnum); // calculate the visible areas - areabytes = CM_WriteAreaBits (sv.worldmodel, areabits, clientarea); + frame->areabytes = CM_WriteAreaBits (sv.world.worldmodel, frame->areabits, clientarea); // grab the current player_state_t frame->ps = clent->client->ps; - sv.worldmodel->funcs.FatPVS(sv.worldmodel, org, clientpvs, sizeof(clientpvs), false); - clientphs = CM_ClusterPHS (sv.worldmodel, clientcluster); + sv.world.worldmodel->funcs.FatPVS(sv.world.worldmodel, org, clientpvs, sizeof(clientpvs), false); + clientphs = CM_ClusterPHS (sv.world.worldmodel, clientcluster); // build up the list of visible entities frame->num_entities = 0; @@ -685,11 +682,11 @@ void SV_BuildClientFrame (client_t *client) if (ent != clent) { // check area - if (!CM_AreasConnected (sv.worldmodel, clientarea, ent->areanum)) + if (!CM_AreasConnected (sv.world.worldmodel, clientarea, ent->areanum)) { // doors can legally straddle two areas, so // we may need to check another one if (!ent->areanum2 - || !CM_AreasConnected (sv.worldmodel, clientarea, ent->areanum2)) + || !CM_AreasConnected (sv.world.worldmodel, clientarea, ent->areanum2)) continue; // blocked by a door } @@ -707,7 +704,7 @@ void SV_BuildClientFrame (client_t *client) if (ent->num_clusters == -1) { // too many leafs for individual check, go by headnode - if (!CM_HeadnodeVisible (sv.worldmodel, ent->headnode, clientpvs)) + if (!CM_HeadnodeVisible (sv.world.worldmodel, ent->headnode, clientpvs)) continue; c_fullsend++; } diff --git a/engine/server/svq2_game.c b/engine/server/svq2_game.c index fb2bb673..a63910c4 100644 --- a/engine/server/svq2_game.c +++ b/engine/server/svq2_game.c @@ -10,8 +10,6 @@ qboolean SVQ2_InitGameProgs(void) #else game_export_t *ge; -trace_t SVQ2_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, q2edict_t *passedict); - void Sys_UnloadGame (void); @@ -304,7 +302,7 @@ static void VARGS PFQ2_setmodel (q2edict_t *ent, char *name) mod = Mod_FindName (name); VectorCopy (mod->mins, ent->mins); VectorCopy (mod->maxs, ent->maxs); - SVQ2_LinkEdict (ent); + WorldQ2_LinkEdict (&sv.world, ent); } } @@ -347,17 +345,17 @@ static qboolean VARGS PFQ2_inPVS (vec3_t p1, vec3_t p2) int area1, area2; qbyte *mask; - leafnum = CM_PointLeafnum (sv.worldmodel, p1); - cluster = CM_LeafCluster (sv.worldmodel, leafnum); - area1 = CM_LeafArea (sv.worldmodel, leafnum); - mask = CM_ClusterPVS (sv.worldmodel, cluster, NULL, 0); + leafnum = CM_PointLeafnum (sv.world.worldmodel, p1); + cluster = CM_LeafCluster (sv.world.worldmodel, leafnum); + area1 = CM_LeafArea (sv.world.worldmodel, leafnum); + mask = CM_ClusterPVS (sv.world.worldmodel, cluster, NULL, 0); - leafnum = CM_PointLeafnum (sv.worldmodel, p2); - cluster = CM_LeafCluster (sv.worldmodel, leafnum); - area2 = CM_LeafArea (sv.worldmodel, leafnum); + leafnum = CM_PointLeafnum (sv.world.worldmodel, p2); + cluster = CM_LeafCluster (sv.world.worldmodel, leafnum); + area2 = CM_LeafArea (sv.world.worldmodel, leafnum); if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) ) return false; - if (!CM_AreasConnected (sv.worldmodel, area1, area2)) + if (!CM_AreasConnected (sv.world.worldmodel, area1, area2)) return false; // a door blocks sight return true; } @@ -377,17 +375,17 @@ static qboolean VARGS PFQ2_inPHS (vec3_t p1, vec3_t p2) int area1, area2; qbyte *mask; - leafnum = CM_PointLeafnum (sv.worldmodel, p1); - cluster = CM_LeafCluster (sv.worldmodel, leafnum); - area1 = CM_LeafArea (sv.worldmodel, leafnum); - mask = CM_ClusterPHS (sv.worldmodel, cluster); + leafnum = CM_PointLeafnum (sv.world.worldmodel, p1); + cluster = CM_LeafCluster (sv.world.worldmodel, leafnum); + area1 = CM_LeafArea (sv.world.worldmodel, leafnum); + mask = CM_ClusterPHS (sv.world.worldmodel, cluster); - leafnum = CM_PointLeafnum (sv.worldmodel, p2); - cluster = CM_LeafCluster (sv.worldmodel, leafnum); - area2 = CM_LeafArea (sv.worldmodel, leafnum); + leafnum = CM_PointLeafnum (sv.world.worldmodel, p2); + cluster = CM_LeafCluster (sv.world.worldmodel, leafnum); + area2 = CM_LeafArea (sv.world.worldmodel, leafnum); if ( mask && (!(mask[cluster>>3] & (1<<(cluster&7)) ) ) ) return false; // more than one bounce away - if (!CM_AreasConnected (sv.worldmodel, area1, area2)) + if (!CM_AreasConnected (sv.world.worldmodel, area1, area2)) return false; // a door blocks hearing return true; @@ -395,7 +393,7 @@ static qboolean VARGS PFQ2_inPHS (vec3_t p1, vec3_t p2) qboolean VARGS PFQ2_AreasConnected(int area1, int area2) { - return CM_AreasConnected(sv.worldmodel, area1, area2); + return CM_AreasConnected(sv.world.worldmodel, area1, area2); } @@ -545,7 +543,7 @@ static q2trace_t VARGS SVQ2_Trace (vec3_t start, vec3_t mins, vec3_t maxs, vec3_ mins = nullvec; if (!maxs) maxs = nullvec; - tr = SVQ2_Move(start, mins, maxs, end, contentmask, passedict); + tr = WorldQ2_Move(&sv.world, start, mins, maxs, end, contentmask, passedict); memcpy(&ret, &tr, sizeof(q2trace_t)); return ret; } @@ -618,6 +616,19 @@ Init the game subsystem for a new map void VARGS Q2SCR_DebugGraph(float value, int color) {return;} +static void VARGS SVQ2_LinkEdict (q2edict_t *ent) +{ + WorldQ2_LinkEdict(&sv.world, ent); +} +static void VARGS SVQ2_UnlinkEdict (q2edict_t *ent) +{ + WorldQ2_UnlinkEdict(&sv.world, ent); +} +static int VARGS SVQ2_AreaEdicts (vec3_t mins, vec3_t maxs, q2edict_t **list, int maxcount, int areatype) +{ + return WorldQ2_AreaEdicts(&sv.world, mins, maxs, list, maxcount, areatype); +} + qboolean SVQ2_InitGameProgs(void) { volatile static game_import_t import; //volatile because msvc sucks @@ -628,7 +639,7 @@ qboolean SVQ2_InitGameProgs(void) } // unload anything we have now - if (sv.worldmodel->fromgame == fg_quake || sv.worldmodel->fromgame == fg_halflife) //we don't support q1 or hl maps yet... If ever. + if (sv.world.worldmodel->fromgame == fg_quake || sv.world.worldmodel->fromgame == fg_halflife) //we don't support q1 or hl maps yet... If ever. { SVQ2_ShutdownGameProgs(); return false; @@ -691,7 +702,7 @@ qboolean SVQ2_InitGameProgs(void) import.SetAreaPortalState = CMQ2_SetAreaPortalState; import.AreasConnected = PFQ2_AreasConnected; - if (sv.worldmodel->fromgame == fg_quake || sv.worldmodel->fromgame == fg_halflife) + if (sv.world.worldmodel->fromgame == fg_quake || sv.world.worldmodel->fromgame == fg_halflife) { return false; /* diff --git a/engine/server/svq3_game.c b/engine/server/svq3_game.c index de05ec8f..8016cdfc 100644 --- a/engine/server/svq3_game.c +++ b/engine/server/svq3_game.c @@ -25,192 +25,24 @@ float RadiusFromBounds (vec3_t mins, vec3_t maxs); #define Z_TAG_BOTLIB 221726 -#ifdef _WIN32 - #if 0 - #pragma comment (lib, "botlib.lib") - #define FTE_GetBotLibAPI GetBotLibAPI - #else - #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN - #endif +botlib_export_t *FTE_GetBotLibAPI(int apiVersion, botlib_import_t *import) +{ //a stub that will prevent botlib from loading. + static void *botlib; + static botlib_export_t *(QDECL *pGetBotLibAPI)(int apiVersion, botlib_import_t *import); - #include - botlib_export_t *FTE_GetBotLibAPI( int apiVersion, botlib_import_t *import ) - { - botlib_export_t *(QDECL *pGetBotLibAPI)( int apiVersion, botlib_import_t *import ); - - static HINSTANCE hmod; - if (!hmod) - hmod = LoadLibrary("botlib.dll"); - if (!hmod) - return NULL; - - pGetBotLibAPI = (void*)GetProcAddress(hmod, "GetBotLibAPI"); - - if (!pGetBotLibAPI) - return NULL; - return pGetBotLibAPI(apiVersion, import); - } - #endif - -#elif defined(__linux__) - - #include "dlfcn.h" - botlib_export_t *FTE_GetBotLibAPI( int apiVersion, botlib_import_t *import ) + dllfunction_t funcs[] = { - botlib_export_t *(*QDECL pGetBotLibAPI)( int apiVersion, botlib_import_t *import ); - void *handle; - handle = dlopen("botlib.so", RTLD_LAZY); - if (!handle) - return NULL; - - pGetBotLibAPI = dlsym(handle, "GetBotLibAPI"); - if (!pGetBotLibAPI) - return NULL; - return pGetBotLibAPI(apiVersion, import); - } -#else - botlib_export_t *FTE_GetBotLibAPI(int apiVersion, botlib_import_t *import) - { //a stub that will prevent botlib from loading. + {(void**)&pGetBotLibAPI, "GetBotLibAPI"}, + {NULL} + }; + if (!botlib) + botlib = Sys_LoadLibrary("botlib", funcs); + if (!botlib) return NULL; - } -#endif + return pGetBotLibAPI(apiVersion, import); +} botlib_export_t *botlib; - - - - -int COM_Compress( char *data_p ) { - char *in, *out; - int c; - qboolean newline = false, whitespace = false; - - in = out = data_p; - if (in) { - while ((c = *in) != 0) { - // skip double slash comments - if ( c == '/' && in[1] == '/' ) { - while (*in && *in != '\n') { - in++; - } - // skip /* */ comments - } else if ( c == '/' && in[1] == '*' ) { - while ( *in && ( *in != '*' || in[1] != '/' ) ) - in++; - if ( *in ) - in += 2; - // record when we hit a newline - } else if ( c == '\n' || c == '\r' ) { - newline = true; - in++; - // record when we hit whitespace - } else if ( c == ' ' || c == '\t') { - whitespace = true; - in++; - // an actual token - } else { - // if we have a pending newline, emit it (and it counts as whitespace) - if (newline) { - *out++ = '\n'; - newline = false; - whitespace = false; - } if (whitespace) { - *out++ = ' '; - whitespace = false; - } - - // copy quoted strings unmolested - if (c == '"') { - *out++ = c; - in++; - while (1) { - c = *in; - if (c && c != '"') { - *out++ = c; - in++; - } else { - break; - } - } - if (c == '"') { - *out++ = c; - in++; - } - } else { - *out = c; - out++; - in++; - } - } - } - } - *out = 0; - return out - data_p; -} - -void Com_Memset (void* dest, const int val, const size_t count) -{ - memset(dest, val, count); -} -void Com_Memcpy (void* dest, const void* src, const size_t count) -{ - memcpy(dest, src, count); -} -int Q_stricmp(char *a, char *b) -{ - return stricmp(a, b); -} -#if _MSC_VER < 700 -int _ftol2 (float f) -{ - return (int)f; -} -#endif -void QDECL Com_Error( int level, const char *error, ... ) -{ - va_list argptr; - char text[1024]; - - va_start (argptr, error); - vsprintf (text, error, argptr); - va_end (argptr); - Sys_Error("%s", text); -} -void QDECL Com_Printf( const char *error, ... ) -{ - va_list argptr; - char text[1024]; - - va_start (argptr, error); - vsprintf (text, error, argptr); - va_end (argptr); - - Con_Printf("%s", text); -} - -void QDECL Com_sprintf( char *dest, int size, const char *fmt, ...) -{ - int len; - va_list argptr; - char bigbuffer[32000]; // big, but small enough to fit in PPC stack - - va_start (argptr,fmt); - len = vsprintf (bigbuffer,fmt,argptr); - va_end (argptr); - if ( len >= sizeof( bigbuffer ) ) { - Com_Error( 0, "Com_sprintf: overflowed bigbuffer" ); - } - if (len >= size) { - Com_Printf ("Com_sprintf: overflow of %i in %i\n", len, size); -#ifdef _DEBUG - __asm { - int 3; - } -#endif - } - Q_strncpyz (dest, bigbuffer, size ); -} #endif @@ -224,18 +56,18 @@ static vm_t *q3gamevm; #define fs_key 0 #define MAX_CONFIGSTRINGS 1024 -char *svq3_configstrings[MAX_CONFIGSTRINGS]; +static char *svq3_configstrings[MAX_CONFIGSTRINGS]; -q3sharedEntity_t *q3_entarray; -int numq3entities; -int sizeofq3gentity; -q3playerState_t *q3playerstates; -int sizeofGameClient; +static q3sharedEntity_t *q3_entarray; +static int numq3entities; +static int sizeofq3gentity; +static q3playerState_t *q3playerstates; +static int sizeofGameClient; -int q3_num_snapshot_entities; -int q3_next_snapshot_entities; -q3entityState_t *q3_snapshot_entities; -q3entityState_t *q3_baselines; +static int q3_num_snapshot_entities; +static int q3_next_snapshot_entities; +static q3entityState_t *q3_snapshot_entities; +static q3entityState_t *q3_baselines; #define NUM_FOR_GENTITY(ge) (((char*)ge - (char*)q3_entarray) / sizeofq3gentity) #define NUM_FOR_SENTITY(se) (se - q3_sentities) @@ -302,7 +134,7 @@ typedef struct { } q3serverEntity_t; q3serverEntity_t *q3_sentities; -void Q3G_UnlinkEntity(q3sharedEntity_t *ent) +static void Q3G_UnlinkEntity(q3sharedEntity_t *ent) { q3serverEntity_t *sent; @@ -327,7 +159,7 @@ void Q3G_UnlinkEntity(q3sharedEntity_t *ent) #define MAX_TOTAL_ENT_LEAFS 256 -void Q3G_LinkEntity(q3sharedEntity_t *ent) +static void Q3G_LinkEntity(q3sharedEntity_t *ent) { areanode_t *node; q3serverEntity_t *sent; @@ -416,7 +248,7 @@ void Q3G_LinkEntity(q3sharedEntity_t *ent) sent->areanum2 = -1; //get all leafs, including solids - if (sv.worldmodel->type == mod_heightmap) + if (sv.world.worldmodel->type == mod_heightmap) { sent->areanum = 0; num_leafs = 1; @@ -427,7 +259,7 @@ void Q3G_LinkEntity(q3sharedEntity_t *ent) } else { - num_leafs = CM_BoxLeafnums(sv.worldmodel, ent->r.absmin, ent->r.absmax, + num_leafs = CM_BoxLeafnums(sv.world.worldmodel, ent->r.absmin, ent->r.absmax, leafs, MAX_TOTAL_ENT_LEAFS, &topnode); if(!num_leafs) @@ -436,8 +268,8 @@ void Q3G_LinkEntity(q3sharedEntity_t *ent) // set areas for(i=0; i= 0) { // doors may legally straggle two areas, @@ -494,7 +326,7 @@ void Q3G_LinkEntity(q3sharedEntity_t *ent) sent->linked = true; // find the first node that the ent's box crosses - node = sv_areanodes; + node = sv.world.areanodes; while(1) { if(node->axis == -1) @@ -511,7 +343,7 @@ void Q3G_LinkEntity(q3sharedEntity_t *ent) InsertLinkBefore((link_t *)&sent->area, &node->solid_edicts); } -int SVQ3_EntitiesInBoxNode(areanode_t *node, vec3_t mins, vec3_t maxs, int *list, int maxcount) +static int SVQ3_EntitiesInBoxNode(areanode_t *node, vec3_t mins, vec3_t maxs, int *list, int maxcount) { link_t *l, *next; q3serverEntity_t *sent; @@ -547,27 +379,15 @@ int SVQ3_EntitiesInBoxNode(areanode_t *node, vec3_t mins, vec3_t maxs, int *list return linkcount; } -int SVQ3_EntitiesInBox(vec3_t mins, vec3_t maxs, int *list, int maxcount) +static int SVQ3_EntitiesInBox(vec3_t mins, vec3_t maxs, int *list, int maxcount) { if (maxcount < 0) return 0; - return SVQ3_EntitiesInBoxNode(sv_areanodes, mins, maxs, list, maxcount); -} - -model_t *SVQ3_ModelForEntity(q3sharedEntity_t *es) -{ - if (es->r.bmodel) - { - return Mod_ForName(va("*%i", es->s.modelindex), false); - } - else - { - return CM_TempBoxModel(es->r.mins, es->r.maxs); - } + return SVQ3_EntitiesInBoxNode(sv.world.areanodes, mins, maxs, list, maxcount); } #define ENTITYNUM_WORLD (MAX_GENTITIES-2) -void SVQ3_Trace(q3trace_t *result, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int entnum, int contentmask) +static void SVQ3_Trace(q3trace_t *result, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int entnum, int contentmask) { int contactlist[128]; trace_t tr; @@ -582,7 +402,7 @@ void SVQ3_Trace(q3trace_t *result, vec3_t start, vec3_t mins, vec3_t maxs, vec3_ if (!maxs) maxs = vec3_origin; - sv.worldmodel->funcs.NativeTrace(sv.worldmodel, 0, 0, start, end, mins, maxs, contentmask, &tr); + sv.world.worldmodel->funcs.NativeTrace(sv.world.worldmodel, 0, 0, start, end, mins, maxs, contentmask, &tr); result->allsolid = tr.allsolid; result->contents = tr.contents; VectorCopy(tr.endpos, result->endpos); @@ -670,7 +490,7 @@ void SVQ3_Trace(q3trace_t *result, vec3_t start, vec3_t mins, vec3_t maxs, vec3_ } } -int SVQ3_PointContents(vec3_t pos, int entnum) +static int SVQ3_PointContents(vec3_t pos, int entnum) { int contactlist[128]; trace_t tr; @@ -684,7 +504,7 @@ int SVQ3_PointContents(vec3_t pos, int entnum) // sv.worldmodel->funcs.Trace(sv.worldmodel, 0, 0, pos, pos, vec3_origin, vec3_origin, &tr); // tr = CM_BoxTrace(sv.worldmodel, pos, pos, vec3_origin, vec3_origin, 0); - cont = sv.worldmodel->funcs.NativeContents (sv.worldmodel, 0, 0, pos, vec3_origin, vec3_origin); + cont = sv.world.worldmodel->funcs.NativeContents (sv.world.worldmodel, 0, 0, pos, vec3_origin, vec3_origin); if ((unsigned)entnum >= MAX_GENTITIES) ourowner = -1; @@ -733,7 +553,7 @@ int SVQ3_PointContents(vec3_t pos, int entnum) return cont; } -int SVQ3_Contact(vec3_t mins, vec3_t maxs, q3sharedEntity_t *ent) +static int SVQ3_Contact(vec3_t mins, vec3_t maxs, q3sharedEntity_t *ent) { model_t *mod; trace_t tr; @@ -753,7 +573,7 @@ int SVQ3_Contact(vec3_t mins, vec3_t maxs, q3sharedEntity_t *ent) return false; } -void SVQ3_SetBrushModel(q3sharedEntity_t *ent, char *modelname) +static void SVQ3_SetBrushModel(q3sharedEntity_t *ent, char *modelname) { model_t *mod; mod = Mod_ForName(modelname, false); @@ -780,11 +600,11 @@ typedef struct { signed char forwardmove, rightmove, upmove; } q3usercmd_t; #define CMD_MASK Q3UPDATE_MASK -qboolean SVQ3_GetUserCmd(int clientnumber, q3usercmd_t *ucmd) +static qboolean SVQ3_GetUserCmd(int clientnumber, q3usercmd_t *ucmd) { usercmd_t *cmd; - if (clientnumber < 0 || clientnumber >= MAX_CLIENTS) + if (clientnumber < 0 || clientnumber >= sv.allocated_client_slots) SV_Error("SVQ3_GetUserCmd: Client out of range"); cmd = &svs.clients[clientnumber].lastcmd; @@ -806,7 +626,7 @@ void SVQ3_SendServerCommand(client_t *cl, char *str) if (!cl) { //broadcast int i; - for (i = 0; i < MAX_CLIENTS; i++) + for (i = 0; i < sv.allocated_client_slots; i++) { if (svs.clients[i].state>cs_zombie) { @@ -832,18 +652,18 @@ void SVQ3_SetConfigString(int num, char *string) SVQ3_SendServerCommand( NULL, va("cs %i \"%s\"\n", num, string)); } -int FloatAsInt(float f) +static int FloatAsInt(float f) { return *(int*)&f; } -int SVQ3_BotGetConsoleMessage( int client, char *buf, int size ) +static int SVQ3_BotGetConsoleMessage( int client, char *buf, int size ) { //retrieves server->client commands that were sent to a bot client_t *cl; int index; - if ((unsigned)client >= MAX_CLIENTS) + if ((unsigned)client >= sv.allocated_client_slots) return false; cl = &svs.clients[client]; @@ -861,29 +681,29 @@ int SVQ3_BotGetConsoleMessage( int client, char *buf, int size ) Q_strncpyz( buf, cl->server_commands[index], size ); return true; } -int SVQ3_BotGetSnapshotEntity(int client, int entnum) +static int SVQ3_BotGetSnapshotEntity(int client, int entnum) { //fixme: does the bot actually use this?... return -1; } -void SVQ3_Adjust_Area_Portal_State(q3sharedEntity_t *ge, qboolean open) +static void SVQ3_Adjust_Area_Portal_State(q3sharedEntity_t *ge, qboolean open) { q3serverEntity_t *se = SENTITY_FOR_GENTITY(ge); CMQ3_SetAreaPortalState(se->areanum, se->areanum2, open); } #define VALIDATEPOINTER(o,l) if ((int)o + l >= mask || VM_POINTER(o) < offset) SV_Error("Call to game trap %i passes invalid pointer\n", fn); //out of bounds. -int Q3G_SystemCallsEx(void *offset, unsigned int mask, int fn, const int *arg) +static int Q3G_SystemCallsEx(void *offset, unsigned int mask, int fn, const int *arg) { int ret = 0; switch(fn) { case G_PRINT: // ( const char *string ); - Con_Printf("%s", VM_POINTER(arg[0])); + Con_Printf("%s", (char*)VM_POINTER(arg[0])); break; case G_ERROR: // ( const char *string ); - SV_Error("Q3 Game error: %s", VM_POINTER(arg[0])); + SV_Error("Q3 Game error: %s", (char*)VM_POINTER(arg[0])); break; case G_MILLISECONDS: return Sys_DoubleTime()*1000; @@ -936,7 +756,7 @@ int Q3G_SystemCallsEx(void *offset, unsigned int mask, int fn, const int *arg) case G_BOT_FREE_CLIENT: case G_DROP_CLIENT: - if ((unsigned)VM_LONG(arg[0]) < MAX_CLIENTS) + if ((unsigned)VM_LONG(arg[0]) < sv.allocated_client_slots) SV_DropClient(&svs.clients[VM_LONG(arg[0])]); break; @@ -995,7 +815,7 @@ int Q3G_SystemCallsEx(void *offset, unsigned int mask, int fn, const int *arg) case G_SEND_SERVER_COMMAND: // ( int clientNum, const char *fmt, ... ); 17 - Con_DPrintf("Game dispatching %s\n", VM_POINTER(arg[1])); + Con_DPrintf("Game dispatching %s\n", (char*)VM_POINTER(arg[1])); if (VM_LONG(arg[0]) == -1) { //broadcast SVQ3_SendServerCommand(NULL, VM_POINTER(arg[1])); @@ -1003,7 +823,7 @@ int Q3G_SystemCallsEx(void *offset, unsigned int mask, int fn, const int *arg) else { int i = VM_LONG(arg[0]); - if (i < 0 || i >= MAX_CLIENTS) + if (i < 0 || i >= sv.allocated_client_slots) return false; SVQ3_SendServerCommand(&svs.clients[i], VM_POINTER(arg[1])); } @@ -1170,7 +990,7 @@ int Q3G_SystemCallsEx(void *offset, unsigned int mask, int fn, const int *arg) { q3usercmd_t *uc = VM_POINTER(arg[1]); int i = VM_LONG(arg[0]); - if ((unsigned)i >= MAX_CLIENTS) + if ((unsigned)i >= sv.allocated_client_slots) return 1; svs.clients[i].lastcmd.angles[0] = uc->angles[0]; svs.clients[i].lastcmd.angles[1] = uc->angles[1]; @@ -1576,7 +1396,7 @@ int Q3G_SystemCallsEx(void *offset, unsigned int mask, int fn, const int *arg) } -int EXPORT_FN Q3G_SystemCalls(int arg, ...) +static int EXPORT_FN Q3G_SystemCalls(int arg, ...) { int args[13]; va_list argptr; @@ -1634,7 +1454,7 @@ void SVQ3_ShutdownGame(void) } #ifdef USEBOTLIB -void VARGS BL_Print(int l, char *fmt, ...) +static void VARGS BL_Print(int l, char *fmt, ...) { va_list argptr; char text[1024]; @@ -1646,12 +1466,12 @@ void VARGS BL_Print(int l, char *fmt, ...) Con_Printf("%s", text); } -int botlibmemoryavailable; -int BL_AvailableMemory(void) +static int botlibmemoryavailable; +static int QDECL BL_AvailableMemory(void) { return botlibmemoryavailable; } -void *BL_Malloc(int size) +static void *QDECL BL_Malloc(int size) { int *mem; botlibmemoryavailable-=size; @@ -1661,22 +1481,22 @@ void *BL_Malloc(int size) return (void *)(mem + 1); } -void BL_Free(void *mem) +static void QDECL BL_Free(void *mem) { int *memref = ((int *)mem) - 1; botlibmemoryavailable+=memref[0]; Z_TagFree(memref); } -void *BL_HunkMalloc(int size) +static void *QDECL BL_HunkMalloc(int size) { return BL_Malloc(size);//Hunk_AllocName(size, "botlib"); } -int BL_FOpenFile(const char *name, fileHandle_t *handle, fsMode_t mode) +static int QDECL BL_FOpenFile(const char *name, fileHandle_t *handle, fsMode_t mode) { return VM_fopen((char*)name, (int*)handle, mode, Z_TAG_BOTLIB); } -int BL_FRead( void *buffer, int len, fileHandle_t f ) +static int QDECL BL_FRead( void *buffer, int len, fileHandle_t f ) { return VM_FRead(buffer, len, (int)f, Z_TAG_BOTLIB); } @@ -1684,7 +1504,7 @@ int BL_FRead( void *buffer, int len, fileHandle_t f ) //{ // return VM_FWrite(buffer, len, f, Z_TAG_BOTLIB); //} -void BL_FCloseFile( fileHandle_t f ) +static void QDECL BL_FCloseFile( fileHandle_t f ) { VM_fclose((int)f, Z_TAG_BOTLIB); } @@ -1692,11 +1512,11 @@ void BL_FCloseFile( fileHandle_t f ) //{ // VM_fseek(f, Z_TAG_BOTLIB) //} -char *BL_BSPEntityData(void) +static char *QDECL BL_BSPEntityData(void) { - return sv.worldmodel->entities; + return sv.world.worldmodel->entities; } -void BL_Trace(bsp_trace_t *trace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask) +static void QDECL BL_Trace(bsp_trace_t *trace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask) { q3trace_t tr; SVQ3_Trace(&tr, start, mins, maxs, end, passent, contentmask); @@ -1714,17 +1534,17 @@ void BL_Trace(bsp_trace_t *trace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t trace->contents = 0;//tr.contents; trace->ent = tr.entityNum; } -int BL_PointContents(vec3_t point) +static int QDECL BL_PointContents(vec3_t point) { return SVQ3_PointContents(point, -1); } -int BL_inPVS(vec3_t p1, vec3_t p2) +static int QDECL BL_inPVS(vec3_t p1, vec3_t p2) { return true;// FIXME: :( } -void BL_EntityTrace(bsp_trace_t *trace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int entnum, int contentmask) +static void QDECL BL_EntityTrace(bsp_trace_t *trace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int entnum, int contentmask) { trace->allsolid = 0;//tr.allsolid; trace->startsolid = 0;//tr.startsolid; @@ -1740,7 +1560,7 @@ void BL_EntityTrace(bsp_trace_t *trace, vec3_t start, vec3_t mins, vec3_t maxs, // trace->ent = tr.entityNum; } -void BL_BSPModelMinsMaxsOrigin(int modelnum, vec3_t angles, vec3_t outmins, vec3_t outmaxs, vec3_t origin) +static void QDECL BL_BSPModelMinsMaxsOrigin(int modelnum, vec3_t angles, vec3_t outmins, vec3_t outmaxs, vec3_t origin) { model_t *mod; vec3_t mins, maxs; @@ -1769,7 +1589,7 @@ void BL_BSPModelMinsMaxsOrigin(int modelnum, vec3_t angles, vec3_t outmins, vec3 if (origin) VectorClear(origin); } -void BL_BotClientCommand(int clientnum, char *command) +static void QDECL BL_BotClientCommand(int clientnum, char *command) { Cmd_TokenizeString(command, false, false); VM_Call(q3gamevm, GAME_CLIENT_COMMAND, clientnum); @@ -1777,14 +1597,14 @@ void BL_BotClientCommand(int clientnum, char *command) #endif -void SV_InitBotLib() +static void SV_InitBotLib(void) { cvar_t *bot_enable = Cvar_Get("bot_enable", "1", 0, "Q3 compatability"); #ifdef USEBOTLIB botlib_import_t import; - Cvar_Set(Cvar_Get("sv_mapChecksum", "0", 0, "Q3 compatability"), va("%i", sv.worldmodel->checksum)); + Cvar_Set(Cvar_Get("sv_mapChecksum", "0", 0, "Q3 compatability"), va("%i", sv.world.worldmodel->checksum)); memset(&import, 0, sizeof(import)); import.Print = BL_Print; @@ -1843,12 +1663,12 @@ qboolean SVQ3_InitGame(void) extern cvar_t progs; cvar_t *sv_pure; - if (sv.worldmodel->type == mod_heightmap) + if (sv.world.worldmodel->type == mod_heightmap) { } else { - if (sv.worldmodel->fromgame == fg_quake || sv.worldmodel->fromgame == fg_halflife || sv.worldmodel->fromgame == fg_quake2) + if (sv.world.worldmodel->fromgame == fg_quake || sv.world.worldmodel->fromgame == fg_halflife || sv.world.worldmodel->fromgame == fg_quake2) return false; //always fail on q1bsp } @@ -1865,7 +1685,7 @@ qboolean SVQ3_InitGame(void) SV_InitBotLib(); - SV_ClearWorld(); + World_ClearWorld(&sv.world); q3_sentities = Z_Malloc(sizeof(q3serverEntity_t)*MAX_GENTITIES); @@ -1899,7 +1719,7 @@ qboolean SVQ3_InitGame(void) SVQ3_SetConfigString(1, sysinfo); - mapentspointer = sv.worldmodel->entities; + mapentspointer = sv.world.worldmodel->entities; VM_Call(q3gamevm, GAME_INIT, 0, (int)rand(), false); CM_InitBoxHull(); @@ -2265,7 +2085,7 @@ static qboolean SVQ3_EntityIsVisible( q3sharedEntity_t *ent ) if (sent->num_clusters == -1) { // too many leafs for individual check, go by headnode - if (!CM_HeadnodeVisible(sv.worldmodel, sent->headnode, bitvector)) + if (!CM_HeadnodeVisible(sv.world.worldmodel, sent->headnode, bitvector)) { return false; } @@ -2331,7 +2151,7 @@ q3playerState_t *SVQ3Q1_BuildPlayerState(client_t *client) state.stats[2] = (int)client->edict->v->items&1023; state.stats[3] = client->edict->v->armorvalue; state.stats[4] = client->edict->v->angles[1]; - state.stats[6] = client->edict->v->max_health; +// state.stats[6] = client->edict->v->max_health; state.persistant[0] = client->edict->v->frags; state.ammo[0] = client->edict->v->currentammo; state.ammo[1] = client->edict->v->ammo_shells; @@ -2394,9 +2214,9 @@ void SVQ3_BuildClientSnapshot( client_t *client ) VectorCopy( ps->origin, org ); org[2] += ps->viewheight; - clientarea = CM_PointLeafnum(sv.worldmodel, org); - bitvector = sv.worldmodel->funcs.LeafPVS(sv.worldmodel, sv.worldmodel->funcs.LeafnumForPoint(sv.worldmodel, org), NULL, 0); - clientarea = CM_LeafArea(sv.worldmodel, clientarea); + clientarea = CM_PointLeafnum(sv.world.worldmodel, org); + bitvector = sv.world.worldmodel->funcs.LeafPVS(sv.world.worldmodel, sv.world.worldmodel->funcs.LeafnumForPoint(sv.world.worldmodel, org), NULL, 0); + clientarea = CM_LeafArea(sv.world.worldmodel, clientarea); /* if (client->areanum != clientarea) { @@ -2407,7 +2227,7 @@ void SVQ3_BuildClientSnapshot( client_t *client ) // calculate the visible areas areabits = snap->areabits; - snap->areabytes = CM_WriteAreaBits(sv.worldmodel, areabits, clientarea); + snap->areabytes = CM_WriteAreaBits(sv.world.worldmodel, areabits, clientarea); // grab the current playerState_t memcpy( &snap->ps, ps, sizeof( snap->ps ) ); @@ -2431,8 +2251,8 @@ void SVQ3_BuildClientSnapshot( client_t *client ) continue; // merge PVS if portal - portalarea = CM_PointLeafnum(sv.worldmodel, ent->s.origin2); - portalarea = CM_LeafArea(sv.worldmodel, portalarea); + portalarea = CM_PointLeafnum(sv.world.worldmodel, ent->s.origin2); + portalarea = CM_LeafArea(sv.world.worldmodel, portalarea); // CM_MergePVS ( ent->s.origin2 ); @@ -2635,7 +2455,7 @@ Con_Printf("Sysinfo: %s\n", sysinfo); cfgstr[20] = "QuakeWorld-Over-Q3"; //you can get the gamedir out of the serverinfo //add in 32 clients - for (i = 0; i < MAX_CLIENTS; i++) + for (i = 0; i < sv.allocated_client_slots; i++) { cfgstr[cs_players+i] = svs.clients[i].userinfo; } @@ -2719,7 +2539,7 @@ void SVQ3_SendGameState(client_t *client) case GT_Q1QVM: SVQ3Q1_SendGamestateConfigstrings(&msg); - for (i = sv.allocated_client_slots+1; i < sv.num_edicts; i++) + for (i = sv.allocated_client_slots+1; i < sv.world.num_edicts; i++) { edict_t *e = EDICT_NUM(svprogfuncs, i); if (e->baseline.modelindex) @@ -2743,16 +2563,16 @@ void SVQ3_SendGameState(client_t *client) MSG_WriteBits(&msg, svcq3_eom, 8); // send the datagram - SVQ3_Netchan_Transmit( client, msg.cursize, msg.data ); + SVQ3_Netchan_Transmit(client, msg.cursize, msg.data); // calculate client->sendTime -// SV_RateDrop( client, msg.cursize ); +// SV_RateDrop(client, msg.cursize); client->state = cs_connected; client->gamestatesequence = client->last_sequence; } -void SVQ3_WriteServerCommandsToClient( client_t *client, sizebuf_t *msg ) +void SVQ3_WriteServerCommandsToClient(client_t *client, sizebuf_t *msg) { int i; int j, len; @@ -2778,7 +2598,7 @@ void SVQ3_SendMessage(client_t *client) msg.data = buffer; msg.packing = SZ_HUFFMAN; - SVQ3_BuildClientSnapshot( client ); + SVQ3_BuildClientSnapshot(client); MSG_WriteBits(&msg, client->last_client_command_num, 32); @@ -2787,14 +2607,14 @@ void SVQ3_SendMessage(client_t *client) // send over all the relevant entityState_t // and the playerState_t - SVQ3_WriteSnapshotToClient( client, &msg ); + SVQ3_WriteSnapshotToClient(client, &msg); - // SV_WriteDownloadToClient( client, &msg ); + // SV_WriteDownloadToClient(client, &msg); // end of message marker MSG_WriteBits(&msg, svcq3_eom, 8); - SVQ3_Netchan_Transmit( client, msg.cursize, msg.data ); + SVQ3_Netchan_Transmit(client, msg.cursize, msg.data); } @@ -2802,8 +2622,18 @@ void SVQ3_SendMessage(client_t *client) client_t *SVQ3_FindEmptyPlayerSlot(void) { + extern cvar_t maxclients; + int pcount = 0; int i; - for (i = 0; i < MAX_CLIENTS; i++) + for (i = 0; i < sv.allocated_client_slots; i++) + { + if (svs.clients[i].state) + pcount++; + } + //in q3, spectators are not special + if (pcount >= maxclients.value) + return NULL; + for (i = 0; i < sv.allocated_client_slots; i++) { if (!svs.clients[i].state) return &svs.clients[i]; @@ -2813,7 +2643,7 @@ client_t *SVQ3_FindEmptyPlayerSlot(void) client_t *SVQ3_FindExistingPlayerByIP(netadr_t na, int qport) { int i; - for (i = 0; i < MAX_CLIENTS; i++) + for (i = 0; i < sv.allocated_client_slots; i++) { if (svs.clients[i].state && NET_CompareAdr(svs.clients[i].netchan.remote_address, na)) return &svs.clients[i]; @@ -2859,14 +2689,14 @@ static qboolean SVQ3_Netchan_Process(client_t *client) #ifndef Q3_NOENCRYPT // decrypt the packet - for( i=msg_readcount+12,j=0 ; i 127 || c == '%' ) + if(c > 127 || c == '%') { c = '.'; } @@ -2878,7 +2708,7 @@ static qboolean SVQ3_Netchan_Process(client_t *client) return true; } -void SVQ3_Netchan_Transmit( client_t *client, int length, qbyte *data ) +void SVQ3_Netchan_Transmit(client_t *client, int length, qbyte *data) { qbyte buffer[MAX_OVERALLMSGLEN]; qbyte bitmask; @@ -2892,17 +2722,18 @@ void SVQ3_Netchan_Transmit( client_t *client, int length, qbyte *data ) #ifndef Q3_NOENCRYPT //first four bytes are not encrypted. - for( i=0; i<4 ; i++) + for(i=0; i<4 ; i++) buffer[i] = data[i]; // encrypt the packet - for( j=0 ; i 127 || c == '%' ) { + if (c > 127 || c == '%') + { c = '.'; } bitmask ^= c << (i & 1); @@ -2914,10 +2745,10 @@ void SVQ3_Netchan_Transmit( client_t *client, int length, qbyte *data ) #endif // deliver the message - Netchan_TransmitQ3( &client->netchan, length, buffer); + Netchan_TransmitQ3(&client->netchan, length, buffer); } -int StringKey( const char *string, int length ); +int StringKey(const char *string, int length); #define MAX_PACKET_USERCMDS 64 void SVQ3_ParseUsercmd(client_t *client, qboolean delta) { @@ -2930,7 +2761,7 @@ void SVQ3_ParseUsercmd(client_t *client, qboolean delta) int cmdCount; char *string; - if( delta ) + if(delta) { client->delta_sequence = client->last_sequence; // client->snapLatency[client->last_sequence & (LATENCY_COUNTS-1)] = Sys_Milliseconds()/*svs.levelTime*/ - client->snapshots[client->last_sequence & UPDATE_MASK].serverTime; @@ -2989,10 +2820,18 @@ void SVQ3_ParseUsercmd(client_t *client, qboolean delta) } for(i=0,to=commands; iservertime <= client->lastcmd.servertime ) + if(to->servertime <= client->lastcmd.servertime) + { + Con_Printf("%i vs %i\n", to->servertime, client->lastcmd.servertime); continue; + } + if (to->servertime-10 > sv.time*1000) //10 ms allows some server latency... + { + Con_Printf("ignoring command from the future...\n"); + continue; + } - memcpy( &client->lastcmd, to, sizeof(client->lastcmd)); + memcpy(&client->lastcmd, to, sizeof(client->lastcmd)); if (svs.gametype == GT_QUAKE3) SVQ3_ClientThink(client); else @@ -3023,7 +2862,7 @@ void SVQ3_ParseUsercmd(client_t *client, qboolean delta) void SVQ3_UpdateUserinfo_f(client_t *cl) { - Q_strncpyz( cl->userinfo, Cmd_Argv(1), sizeof(cl->userinfo) ); + Q_strncpyz(cl->userinfo, Cmd_Argv(1), sizeof(cl->userinfo)); SV_ExtractFromUserinfo (cl); @@ -3036,23 +2875,24 @@ void SVQ3_Drop_f(client_t *cl) SV_DropClient(cl); } -typedef struct ucmd_s { +typedef struct ucmd_s +{ char *name; - void (*func)( client_t * ); + void (*func)(client_t *); } ucmd_t; -static const ucmd_t ucmds[] = { - { "userinfo", SVQ3_UpdateUserinfo_f}, - { "disconnect", SVQ3_Drop_f},//SV_Disconnect_f }, +static const ucmd_t ucmds[] = +{ + {"userinfo", SVQ3_UpdateUserinfo_f}, + {"disconnect", SVQ3_Drop_f}, - // TODO - { "cp", NULL }, - { "download", NULL }, - { "nextdl", NULL }, - { "stopdl", NULL }, - { "donedl", NULL }, + {"cp", NULL}, + {"download", NULL}, + {"nextdl", NULL}, + {"stopdl", NULL}, + {"donedl", NULL}, - { NULL, NULL } + {NULL, NULL} }; void SVQ3_ParseClientCommand(client_t *client) { @@ -3082,7 +2922,7 @@ void SVQ3_ParseClientCommand(client_t *client) if(commandNum > client->last_client_command_num) { - Con_Printf("Client %s lost %i clientCommands\n", commandNum - client->last_client_command_num); + Con_Printf("Client %s lost %i clientCommands\n", client->name, commandNum - client->last_client_command_num); SV_DropClient(client); return; } @@ -3103,8 +2943,6 @@ void SVQ3_ParseClientCommand(client_t *client) } } - // TODO - flood protection - if (svs.gametype == GT_QUAKE3) if(!u->name && sv.state == ss_active) SVQ3_ClientCommand(client); @@ -3143,14 +2981,15 @@ void SVQ3_ParseClientMessage(client_t *client) { if(client->gamestatesequence>=0) { - if( client->last_sequence - client->gamestatesequence < 100 ) + if (client->last_sequence - client->gamestatesequence < 100) { return; // don't resend gameState too frequently } - Con_DPrintf( "%s : dropped gamestate, resending\n", client->name ); + Con_DPrintf("%s : dropped gamestate, resending\n", client->name); } - SVQ3_SendGameState( client ); + client->lastcmd.servertime = sv.time*1000; + SVQ3_SendGameState(client); return; } @@ -3215,7 +3054,7 @@ void SVQ3_HandleClient(void) MSG_ReadBits(32); qport = (unsigned short)MSG_ReadBits(16); - for (i = 0; i < MAX_CLIENTS; i++) + for (i = 0; i < sv.allocated_client_slots; i++) { if (svs.clients[i].state <= cs_zombie) continue; @@ -3227,7 +3066,7 @@ void SVQ3_HandleClient(void) //found them. break; } - if (i == MAX_CLIENTS) + if (i == sv.allocated_client_slots) return; //nope if (!SVQ3_Netchan_Process(&svs.clients[i])) diff --git a/engine/server/world.c b/engine/server/world.c index a5944bfb..c688326e 100644 --- a/engine/server/world.c +++ b/engine/server/world.c @@ -19,7 +19,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // world.c -- world query functions -#include "qwsvdef.h" +#include "quakedef.h" +#include "pr_common.h" #ifndef CLIENTONLY /* @@ -40,7 +41,7 @@ typedef struct float *start, *end; trace_t trace; int type; - edict_t *passedict; + wedict_t *passedict; #ifdef Q2SERVER q2edict_t *q2passedict; #endif @@ -68,7 +69,7 @@ Set up the planes and clipnodes so that the six floats of a bounding box can just be stored out and get a proper hull_t structure. =================== */ -void SV_InitBoxHull (void) +static void World_InitBoxHull (void) { int i; int side; @@ -107,7 +108,7 @@ To keep everything totally uniform, bounding boxes are turned into small BSP trees instead of being compared directly. =================== */ -hull_t *SV_HullForBox (vec3_t mins, vec3_t maxs) +static hull_t *World_HullForBox (vec3_t mins, vec3_t maxs) { box_planes[0].dist = maxs[0]; box_planes[1].dist = mins[0]; @@ -127,24 +128,20 @@ ENTITY AREA CHECKING =============================================================================== */ - -areanode_t sv_areanodes[AREA_NODES]; -int sv_numareanodes; - /* =============== SV_CreateAreaNode =============== */ -areanode_t *SV_CreateAreaNode (int depth, vec3_t mins, vec3_t maxs) +static areanode_t *World_CreateAreaNode (world_t *w, int depth, vec3_t mins, vec3_t maxs) { areanode_t *anode; vec3_t size; vec3_t mins1, maxs1, mins2, maxs2; - anode = &sv_areanodes[sv_numareanodes]; - sv_numareanodes++; + anode = &w->areanodes[w->numareanodes]; + w->numareanodes++; ClearLink (&anode->trigger_edicts); ClearLink (&anode->solid_edicts); @@ -170,8 +167,8 @@ areanode_t *SV_CreateAreaNode (int depth, vec3_t mins, vec3_t maxs) maxs1[anode->axis] = mins2[anode->axis] = anode->dist; - anode->children[0] = SV_CreateAreaNode (depth+1, mins2, maxs2); - anode->children[1] = SV_CreateAreaNode (depth+1, mins1, maxs1); + anode->children[0] = World_CreateAreaNode (w, depth+1, mins2, maxs2); + anode->children[1] = World_CreateAreaNode (w, depth+1, mins1, maxs1); return anode; } @@ -182,13 +179,13 @@ SV_ClearWorld =============== */ -void SV_ClearWorld (void) +void World_ClearWorld (world_t *w) { - SV_InitBoxHull (); + World_InitBoxHull (); - memset (sv_areanodes, 0, sizeof(sv_areanodes)); - sv_numareanodes = 0; - SV_CreateAreaNode (0, sv.worldmodel->mins, sv.worldmodel->maxs); + memset (w->areanodes, 0, sizeof(w->areanodes)); + w->numareanodes = 0; + World_CreateAreaNode (w, 0, w->worldmodel->mins, w->worldmodel->maxs); } @@ -198,7 +195,7 @@ SV_UnlinkEdict =============== */ -void SV_UnlinkEdict (edict_t *ent) +void World_UnlinkEdict (wedict_t *ent) { if (!ent->area.prev) return; // not linked in anywhere @@ -213,11 +210,11 @@ SV_TouchLinks ==================== */ #define MAX_NODELINKS 256 //all this means is that any more than this will not touch. -edict_t *nodelinks[MAX_NODELINKS]; -void SV_TouchLinks ( edict_t *ent, areanode_t *node ) -{ //Spike: rewritten this function to cope with killtargets used on a few maps. +static wedict_t *nodelinks[MAX_NODELINKS]; +void World_TouchLinks (world_t *w, wedict_t *ent, areanode_t *node) +{ link_t *l, *next; - edict_t *touch; + wedict_t *touch; int old_self, old_other; int linkcount = 0, ln; @@ -260,6 +257,7 @@ void SV_TouchLinks ( edict_t *ent, areanode_t *node ) continue; if (!touch->v->touch || touch->v->solid != SOLID_TRIGGER) continue; + if (ent->v->absmin[0] > touch->v->absmax[0] || ent->v->absmin[1] > touch->v->absmax[1] || ent->v->absmin[2] > touch->v->absmax[2] @@ -271,15 +269,15 @@ void SV_TouchLinks ( edict_t *ent, areanode_t *node ) if (!((int)ent->xv->dimension_solid & (int)touch->xv->dimension_hit)) //didn't change did it?... continue; - pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, touch); - pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, ent); - pr_global_struct->time = sv.physicstime; + pr_global_struct->self = EDICT_TO_PROG(w->progs, touch); + pr_global_struct->other = EDICT_TO_PROG(w->progs, ent); + pr_global_struct->time = w->physicstime; #ifdef VM_Q1 - if (svs.gametype == GT_Q1QVM) + if (w==&sv.world && svs.gametype == GT_Q1QVM) Q1QVM_Touch(); else #endif - PR_ExecuteProgram (svprogfuncs, touch->v->touch); + PR_ExecuteProgram (w->progs, touch->v->touch); if (ent->isfree) break; @@ -292,14 +290,14 @@ void SV_TouchLinks ( edict_t *ent, areanode_t *node ) if (node->axis == -1 || ent->isfree) return; - if ( ent->v->absmax[node->axis] > node->dist ) - SV_TouchLinks ( ent, node->children[0] ); - if ( ent->v->absmin[node->axis] < node->dist ) - SV_TouchLinks ( ent, node->children[1] ); + if (ent->v->absmax[node->axis] > node->dist) + World_TouchLinks (w, ent, node->children[0]); + if (ent->v->absmin[node->axis] < node->dist) + World_TouchLinks (w, ent, node->children[1]); } #ifdef Q2BSPS -void Q2BSP_FindTouchedLeafs(model_t *model, edict_t *ent, float *mins, float *maxs) +void Q2BSP_FindTouchedLeafs(world_t *w, model_t *model, wedict_t *ent, float *mins, float *maxs) { #define MAX_TOTAL_ENT_LEAFS 128 int leafs[MAX_TOTAL_ENT_LEAFS]; @@ -325,14 +323,9 @@ void Q2BSP_FindTouchedLeafs(model_t *model, edict_t *ent, float *mins, float *ma area = CM_LeafArea (model, leafs[i]); if (area) { // doors may legally straggle two areas, - // but nothing should evern need more than that + // but nothing should ever need more than that if (ent->areanum && ent->areanum != area) - { - if (ent->areanum2 && ent->areanum2 != area && sv.state == ss_loading) - Con_DPrintf ("Object touching 3 areas at %f %f %f\n", - ent->v->absmin[0], ent->v->absmin[1], ent->v->absmin[2]); ent->areanum2 = area; - } else ent->areanum = area; } @@ -375,16 +368,16 @@ SV_LinkEdict =============== */ -void SV_LinkEdict (edict_t *ent, qboolean touch_triggers) +void World_LinkEdict (world_t *w, wedict_t *ent, qboolean touch_triggers) { areanode_t *node; if (ent->area.prev) - SV_UnlinkEdict (ent); // unlink from old position + World_UnlinkEdict (ent); // unlink from old position ent->solidtype = ent->v->solid; - if (ent == sv.edicts) + if (ent == w->edicts) return; // don't add the world if (ent->isfree) @@ -479,14 +472,14 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers) } // link to PVS leafs - sv.worldmodel->funcs.FindTouchedLeafs_Q1(sv.worldmodel, ent, ent->v->absmin, ent->v->absmax); + w->worldmodel->funcs.FindTouchedLeafs_Q1(w, w->worldmodel, ent, ent->v->absmin, ent->v->absmax); /* #ifdef Q2BSPS - if (sv.worldmodel->fromgame == fg_quake2 || sv.worldmodel->fromgame == fg_quake3) + if (w->worldmodel->fromgame == fg_quake2 || w->worldmodel->fromgame == fg_quake3) Q2BSP_FindTouchedLeafs(ent); else #endif - if (sv.worldmodel->fromgame == fg_doom) + if (w->worldmodel->fromgame == fg_doom) { } else @@ -497,7 +490,7 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers) return; // find the first node that the ent's box crosses - node = sv_areanodes; + node = w->areanodes; while (1) { if (node->axis == -1) @@ -519,12 +512,12 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers) // if touch_triggers, touch all entities at this node and decend for more if (touch_triggers) - SV_TouchLinks ( ent, sv_areanodes ); + World_TouchLinks (w, ent, w->areanodes); } #ifdef Q2SERVER -void VARGS SVQ2_UnlinkEdict(q2edict_t *ent) +void VARGS WorldQ2_UnlinkEdict(world_t *w, q2edict_t *ent) { if (!ent->area.prev) return; // not linked in anywhere @@ -532,7 +525,7 @@ void VARGS SVQ2_UnlinkEdict(q2edict_t *ent) ent->area.prev = ent->area.next = NULL; } -void VARGS SVQ2_LinkEdict(q2edict_t *ent) +void VARGS WorldQ2_LinkEdict(world_t *w, q2edict_t *ent) { areanode_t *node; int leafs[MAX_TOTAL_ENT_LEAFS]; @@ -543,7 +536,7 @@ void VARGS SVQ2_LinkEdict(q2edict_t *ent) int topnode; if (ent->area.prev) - SVQ2_UnlinkEdict (ent); // unlink from old position + WorldQ2_UnlinkEdict (w, ent); // unlink from old position if (ent == ge->edicts) return; // don't add the world @@ -630,24 +623,19 @@ void VARGS SVQ2_LinkEdict(q2edict_t *ent) ent->areanum2 = 0; //get all leafs, including solids - num_leafs = CM_BoxLeafnums (sv.worldmodel, ent->absmin, ent->absmax, + num_leafs = CM_BoxLeafnums (w->worldmodel, ent->absmin, ent->absmax, leafs, MAX_TOTAL_ENT_LEAFS, &topnode); // set areas for (i=0 ; iworldmodel, leafs[i]); + area = CM_LeafArea (w->worldmodel, leafs[i]); if (area) { // doors may legally straggle two areas, // but nothing should evern need more than that if (ent->areanum && ent->areanum != area) - { - if (ent->areanum2 && ent->areanum2 != area && sv.state == ss_loading) - Con_DPrintf ("Object touching 3 areas at %f %f %f\n", - ent->absmin[0], ent->absmin[1], ent->absmin[2]); ent->areanum2 = area; - } else ent->areanum = area; } @@ -693,7 +681,7 @@ void VARGS SVQ2_LinkEdict(q2edict_t *ent) return; // find the first node that the ent's box crosses - node = sv_areanodes; + node = w->areanodes; while (1) { if (node->axis == -1) @@ -714,13 +702,13 @@ void VARGS SVQ2_LinkEdict(q2edict_t *ent) } -void SVQ2_Q1BSP_LinkEdict(q2edict_t *ent) +void WorldQ2_Q1BSP_LinkEdict(world_t *w, q2edict_t *ent) { areanode_t *node; int i, j, k; if (ent->area.prev) - SVQ2_UnlinkEdict (ent); // unlink from old position + WorldQ2_UnlinkEdict (w, ent); // unlink from old position if (ent == ge->edicts) return; // don't add the world @@ -823,9 +811,6 @@ void SVQ2_Q1BSP_LinkEdict(q2edict_t *ent) // but nothing should evern need more than that if (ent->areanum && ent->areanum != area) { - if (ent->areanum2 && ent->areanum2 != area && sv.state == ss_loading) - Con_DPrintf ("Object touching 3 areas at %f %f %f\n", - ent->absmin[0], ent->absmin[1], ent->absmin[2]); ent->areanum2 = area; } else @@ -874,7 +859,7 @@ void SVQ2_Q1BSP_LinkEdict(q2edict_t *ent) return; // find the first node that the ent's box crosses - node = sv_areanodes; + node = w->areanodes; while (1) { if (node->axis == -1) @@ -909,9 +894,9 @@ SV_PointContents ================== */ -int SV_PointContents (vec3_t p) +int World_PointContents (world_t *w, vec3_t p) { - return sv.worldmodel->funcs.PointContents(sv.worldmodel, p); + return w->worldmodel->funcs.PointContents(w->worldmodel, p); } //=========================================================================== @@ -924,14 +909,14 @@ A small wrapper around SV_BoxInSolidEntity that never clips against the supplied entity. ============ */ -edict_t *SV_TestEntityPosition (edict_t *ent) +wedict_t *World_TestEntityPosition (world_t *w, wedict_t *ent) { trace_t trace; - trace = SV_Move (ent->v->origin, ent->v->mins, ent->v->maxs, ent->v->origin, 0, ent); + trace = World_Move (w, ent->v->origin, ent->v->mins, ent->v->maxs, ent->v->origin, 0, ent); if (trace.startsolid) - return sv.edicts; + return w->edicts; return NULL; } @@ -1111,28 +1096,15 @@ Handles selection or creation of a clipping hull, and offseting (and eventually rotation) of the end points ================== */ -trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int hullnum, qboolean hitmodel) //hullnum overrides min/max for q1 style bsps +static trace_t World_ClipMoveToEntity (world_t *w, wedict_t *ent, vec3_t eorg, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int hullnum, qboolean hitmodel) //hullnum overrides min/max for q1 style bsps { trace_t trace; model_t *model; -/* -#ifdef Q2BSPS - if (ent->v->solid == SOLID_BSP) - if (sv.models[(int)ent->v->modelindex] && (sv.models[(int)ent->v->modelindex]->fromgame == fg_quake2 || sv.models[(int)ent->v->modelindex]->fromgame == fg_quake3)) - { - trace = CM_TransformedBoxTrace (start, end, mins, maxs, sv.models[(int)ent->v->modelindex]->hulls[0].firstclipnode, MASK_PLAYERSOLID, ent->v->origin, ent->v->angles); - if (trace.fraction < 1 || trace.startsolid) - trace.ent = ent; - return trace; - } -#endif -*/ - // get the clipping hull if (ent->v->solid == SOLID_BSP) { - model = sv.models[(int)ent->v->modelindex]; + model = w->models[(int)ent->v->modelindex]; if (!model || (model->type != mod_brush && model->type != mod_heightmap)) SV_Error("SOLID_BSP with non bsp model (classname: %s)", PR_GetString(svprogfuncs, ent->v->classname)); } @@ -1141,7 +1113,7 @@ trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t max vec3_t boxmins, boxmaxs; VectorSubtract (ent->v->mins, maxs, boxmins); VectorSubtract (ent->v->maxs, mins, boxmaxs); - SV_HullForBox(boxmins, boxmaxs); + World_HullForBox(boxmins, boxmaxs); model = NULL; } @@ -1149,12 +1121,12 @@ trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t max if (ent->v->solid != SOLID_BSP) { ent->v->angles[0]*=-1; //carmack made bsp models rotate wrongly. - TransformedTrace(model, hullnum, ent->v->frame, start, end, mins, maxs, &trace, ent->v->origin, ent->v->angles); + TransformedTrace(model, hullnum, ent->v->frame, start, end, mins, maxs, &trace, eorg, ent->v->angles); ent->v->angles[0]*=-1; } else { - TransformedTrace(model, hullnum, ent->v->frame, start, end, mins, maxs, &trace, ent->v->origin, ent->v->angles); + TransformedTrace(model, hullnum, ent->v->frame, start, end, mins, maxs, &trace, eorg, ent->v->angles); } // fix trace up by the offset @@ -1167,23 +1139,23 @@ trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t max model_t *model; if (ent->v->modelindex < 1 || ent->v->modelindex >= MAX_MODELS) SV_Error("SV_ClipMoveToEntity: modelindex out of range\n"); - model = sv.models[ (int)ent->v->modelindex ]; + model = w->models[ (int)ent->v->modelindex ]; if (!model) { //if the model isn't loaded, load it. //this saves on memory requirements with mods that don't ever use this. - model = sv.models[(int)ent->v->modelindex] = Mod_ForName(sv.strings.model_precache[(int)ent->v->modelindex], false); + model = w->models[(int)ent->v->modelindex] = Mod_ForName(sv.strings.model_precache[(int)ent->v->modelindex], false); } if (model && model->funcs.Trace) { //do the second trace - TransformedTrace(model, hullnum, ent->v->frame, start, end, mins, maxs, &trace, ent->v->origin, ent->v->angles); + TransformedTrace(model, hullnum, ent->v->frame, start, end, mins, maxs, &trace, eorg, ent->v->angles); } } if (trace.startsolid) { - if (ent != sv.edicts) + if (ent != w->edicts) Con_Printf("Trace started solid\n"); } } @@ -1195,7 +1167,7 @@ trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t max return trace; } #ifdef Q2SERVER -trace_t SVQ2_ClipMoveToEntity (q2edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end) +static trace_t WorldQ2_ClipMoveToEntity (world_t *w, q2edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end) { trace_t trace; model_t *model; @@ -1203,7 +1175,7 @@ trace_t SVQ2_ClipMoveToEntity (q2edict_t *ent, vec3_t start, vec3_t mins, vec3_t // get the clipping hull if (ent->s.solid == Q2SOLID_BSP) { - model = sv.models[(int)ent->s.modelindex]; + model = w->models[(int)ent->s.modelindex]; if (!model || model->type != mod_brush) SV_Error("SOLID_BSP with non bsp model"); } @@ -1212,7 +1184,7 @@ trace_t SVQ2_ClipMoveToEntity (q2edict_t *ent, vec3_t start, vec3_t mins, vec3_t vec3_t boxmins, boxmaxs; VectorSubtract (ent->mins, maxs, boxmins); VectorSubtract (ent->maxs, mins, boxmaxs); - SV_HullForBox(boxmins, boxmaxs); + World_HullForBox(boxmins, boxmaxs); model = NULL; } @@ -1228,17 +1200,17 @@ trace_t SVQ2_ClipMoveToEntity (q2edict_t *ent, vec3_t start, vec3_t mins, vec3_t #endif #ifdef Q2BSPS float *area_mins, *area_maxs; -edict_t **area_list; +wedict_t **area_list; #ifdef Q2SERVER q2edict_t **area_q2list; #endif int area_count, area_maxcount; int area_type; #define AREA_SOLID 1 -void SV_AreaEdicts_r (areanode_t *node) +static void World_AreaEdicts_r (areanode_t *node) { link_t *l, *next, *start; - edict_t *check; + wedict_t *check; int count; count = 0; @@ -1279,9 +1251,9 @@ void SV_AreaEdicts_r (areanode_t *node) // recurse down both sides if ( area_maxs[node->axis] > node->dist ) - SV_AreaEdicts_r ( node->children[0] ); + World_AreaEdicts_r ( node->children[0] ); if ( area_mins[node->axis] < node->dist ) - SV_AreaEdicts_r ( node->children[1] ); + World_AreaEdicts_r ( node->children[1] ); } /* @@ -1289,7 +1261,7 @@ void SV_AreaEdicts_r (areanode_t *node) SV_AreaEdicts ================ */ -int SV_AreaEdicts (vec3_t mins, vec3_t maxs, edict_t **list, +int World_AreaEdicts (world_t *w, vec3_t mins, vec3_t maxs, wedict_t **list, int maxcount, int areatype) { area_mins = mins; @@ -1299,13 +1271,13 @@ int SV_AreaEdicts (vec3_t mins, vec3_t maxs, edict_t **list, area_maxcount = maxcount; area_type = areatype; - SV_AreaEdicts_r (sv_areanodes); + World_AreaEdicts_r (w->areanodes); return area_count; } #ifdef Q2SERVER -void SVQ2_AreaEdicts_r (areanode_t *node) +static void WorldQ2_AreaEdicts_r (areanode_t *node) { link_t *l, *next, *start; q2edict_t *check; @@ -1324,7 +1296,7 @@ void SVQ2_AreaEdicts_r (areanode_t *node) if (!l) { int i; - SV_ClearWorld(); + World_ClearWorld(&sv.world); check = ge->edicts; for (i = 0; i < ge->num_edicts; i++, check = (q2edict_t *)((char *)check + ge->edict_size)) memset(&check->area, 0, sizeof(check->area)); @@ -1359,12 +1331,12 @@ void SVQ2_AreaEdicts_r (areanode_t *node) // recurse down both sides if ( area_maxs[node->axis] > node->dist ) - SVQ2_AreaEdicts_r ( node->children[0] ); + WorldQ2_AreaEdicts_r ( node->children[0] ); if ( area_mins[node->axis] < node->dist ) - SVQ2_AreaEdicts_r ( node->children[1] ); + WorldQ2_AreaEdicts_r ( node->children[1] ); } -int VARGS SVQ2_AreaEdicts (vec3_t mins, vec3_t maxs, q2edict_t **list, +int VARGS WorldQ2_AreaEdicts (world_t *w, vec3_t mins, vec3_t maxs, q2edict_t **list, int maxcount, int areatype) { area_mins = mins; @@ -1374,7 +1346,7 @@ int VARGS SVQ2_AreaEdicts (vec3_t mins, vec3_t maxs, q2edict_t **list, area_maxcount = maxcount; area_type = areatype; - SVQ2_AreaEdicts_r (sv_areanodes); + WorldQ2_AreaEdicts_r (w->areanodes); return area_count; } @@ -1392,14 +1364,14 @@ testing object's origin to get a point to use with the returned hull. */ #ifdef Q2SERVER -static model_t *SVQ2_ModelForEntity (q2edict_t *ent) +static model_t *WorldQ2_ModelForEntity (world_t *w, q2edict_t *ent) { model_t *model; // decide which clipping hull to use, based on the size if (ent->solid == Q2SOLID_BSP) { // explicit hulls in the BSP model - model = sv.models[ (int)ent->s.modelindex ]; + model = w->models[ (int)ent->s.modelindex ]; if (!model) SV_Error ("Q2SOLID_BSP with a non bsp model"); @@ -1412,113 +1384,9 @@ static model_t *SVQ2_ModelForEntity (q2edict_t *ent) return CM_TempBoxModel (ent->mins, ent->maxs); } #endif -/* -void SV_ClipMoveToEntities ( moveclip_t *clip ) -{ - int i, num; - edict_t *touchlist[MAX_EDICTS], *touch; - trace_t trace; - int headnode; - float *angles; - int passed = clip->passedict?EDICT_TO_PROG(svprogfuncs, clip->passedict):0; - - num = SV_AreaEdicts (clip->boxmins, clip->boxmaxs, touchlist - , MAX_EDICTS, AREA_SOLID); - - // be careful, it is possible to have an entity in this - // list removed before we get to it (killtriggered) - for (i=0 ; iv->solid == SOLID_NOT) - continue; - if (touch == clip->passedict) - continue; - if (clip->trace.allsolid) - return; - if (clip->passedict) - { - if (touch->v->owner == passed) - continue; // don't clip against own missiles - if (clip->passedict->v->owner == EDICT_TO_PROG(svprogfuncs, touch)) - continue; // don't clip against owner - } - - if (clip->type & MOVE_NOMONSTERS && touch->v->solid != SOLID_BSP) - continue; - - // don't clip corpse against character - if (clip->passedict->v->solid == SOLID_CORPSE && (touch->v->solid == SOLID_SLIDEBOX || touch->v->solid == SOLID_CORPSE)) - continue; - // don't clip character against corpse - if (clip->passedict->v->solid == SOLID_SLIDEBOX && touch->v->solid == SOLID_CORPSE) - continue; - - if (!((int)clip->passedict->xv->dimension_hit & (int)touch->xv->dimension_solid)) - continue; - -// if ( !(clip->contentmask & CONTENTS_DEADMONSTER) -// && (touch->svflags & SVF_DEADMONSTER) ) -// continue; - - // might intersect, so do an exact clip - headnode = SV_HeadnodeForEntity (touch); - angles = touch->v->angles; - if (touch->v->solid != SOLID_BSP) - angles = vec3_origin; // boxes don't rotate - - if ((int)touch->v->flags & FL_MONSTER) - trace = CM_TransformedBoxTrace (clip->start, clip->end, - clip->mins2, clip->maxs2, headnode, MASK_PLAYERSOLID, - touch->v->origin, angles); - else - trace = CM_TransformedBoxTrace (clip->start, clip->end, - clip->mins, clip->maxs, headnode, MASK_PLAYERSOLID, - touch->v->origin, angles); - - if (trace.allsolid || trace.startsolid || - trace.fraction < clip->trace.fraction) - { - if (clip->type & MOVE_HITMODEL && touch->v->solid != SOLID_BSP) - { - model_t *model; - if (touch->v->modelindex < 1 || touch->v->modelindex >= MAX_MODELS) - SV_Error("SV_ClipMoveToEntity: modelindex out of range\n"); - model = sv.models[ (int)touch->v->modelindex ]; - if (!model) - { //if the model isn't loaded, load it. - //this saves on memory requirements with mods that don't ever use this. - model = sv.models[(int)touch->v->modelindex] = Mod_ForName(sv.model_precache[(int)touch->v->modelindex], false); - } - - if (model && model->hulls[0].available) - { - hull_t *hull = &model->hulls[0]; - //do the second trace - memset (&trace, 0, sizeof(trace_t)); - trace.fraction = 1; - trace.allsolid = true; - TransformedHullCheck(hull, clip->start, clip->end, &trace, touch->v->angles); - - if (trace.fraction < clip->trace.fraction) - { - trace.ent = touch; - clip->trace = trace; - } - } - } - else - { - trace.ent = touch; - clip->trace = trace; - } - } - } -} -*/ #ifdef Q2SERVER -void SVQ2_ClipMoveToEntities ( moveclip_t *clip, int contentsmask ) +void WorldQ2_ClipMoveToEntities (world_t *w, moveclip_t *clip, int contentsmask ) { int i, num; q2edict_t *touchlist[MAX_EDICTS], *touch; @@ -1526,7 +1394,7 @@ void SVQ2_ClipMoveToEntities ( moveclip_t *clip, int contentsmask ) model_t *model; float *angles; - num = SVQ2_AreaEdicts (clip->boxmins, clip->boxmaxs, touchlist + num = WorldQ2_AreaEdicts (w, clip->boxmins, clip->boxmaxs, touchlist , MAX_EDICTS, AREA_SOLID); // be careful, it is possible to have an entity in this @@ -1553,7 +1421,7 @@ void SVQ2_ClipMoveToEntities ( moveclip_t *clip, int contentsmask ) continue; // might intersect, so do an exact clip - model = SVQ2_ModelForEntity (touch); + model = WorldQ2_ModelForEntity (w, touch); angles = touch->s.angles; if (touch->solid != Q2SOLID_BSP) angles = vec3_origin; // boxes don't rotate @@ -1597,14 +1465,14 @@ like SV_ClipToLinks, but doesn't use the links part. This can be used for checki Sounds pointless, I know. ==================== */ -void SV_ClipToEverything (moveclip_t *clip) +static void World_ClipToEverything (world_t *w, moveclip_t *clip) { int e; trace_t trace; - edict_t *touch; - for (e=1 ; enum_edicts ; e++) { - touch = EDICT_NUM(svprogfuncs, e); + touch = (wedict_t*)EDICT_NUM(svprogfuncs, e); if (touch->isfree) continue; @@ -1648,16 +1516,16 @@ void SV_ClipToEverything (moveclip_t *clip) return; if (clip->passedict) { - if (PROG_TO_EDICT(svprogfuncs, touch->v->owner) == clip->passedict) + if ((wedict_t*)PROG_TO_EDICT(svprogfuncs, touch->v->owner) == clip->passedict) continue; // don't clip against own missiles - if (PROG_TO_EDICT(svprogfuncs, clip->passedict->v->owner) == touch) + if ((wedict_t*)PROG_TO_EDICT(svprogfuncs, clip->passedict->v->owner) == touch) continue; // don't clip against owner } if ((int)touch->v->flags & FL_MONSTER) - trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL); + trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins2, clip->maxs2, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL); else - trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL); + trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins, clip->maxs, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL); if (trace.allsolid || trace.startsolid || trace.fraction < clip->trace.fraction) { @@ -1674,10 +1542,10 @@ SV_ClipToLinks Mins and maxs enclose the entire area swept by the move ==================== */ -void SV_ClipToLinks ( areanode_t *node, moveclip_t *clip ) +static void World_ClipToLinks (world_t *w, areanode_t *node, moveclip_t *clip) { link_t *l, *next; - edict_t *touch; + wedict_t *touch; trace_t trace; if (clip->type & MOVE_TRIGGERS) @@ -1726,16 +1594,16 @@ void SV_ClipToLinks ( areanode_t *node, moveclip_t *clip ) return; if (clip->passedict) { - if (PROG_TO_EDICT(svprogfuncs, touch->v->owner) == clip->passedict) + if ((wedict_t*)PROG_TO_EDICT(svprogfuncs, touch->v->owner) == clip->passedict) continue; // don't clip against own missiles - if (PROG_TO_EDICT(svprogfuncs, clip->passedict->v->owner) == touch) + if ((wedict_t*)PROG_TO_EDICT(svprogfuncs, clip->passedict->v->owner) == touch) continue; // don't clip against owner } if ((int)touch->v->flags & FL_MONSTER) - trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL); + trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins2, clip->maxs2, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL); else - trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL); + trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins, clip->maxs, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL); if (trace.allsolid || trace.startsolid || trace.fraction < clip->trace.fraction) { @@ -1757,6 +1625,14 @@ void SV_ClipToLinks ( areanode_t *node, moveclip_t *clip ) if (touch->v->solid == SOLID_TRIGGER || touch->v->solid == SOLID_LADDER) SV_Error ("Trigger (%s) in clipping list", PR_GetString(svprogfuncs, touch->v->classname)); + if (clip->type & MOVE_LAGGED) + { + //can't touch lagged ents - we do an explicit test for them later. + if (touch->entnum-1 < w->maxlagents) + if (w->lagents[touch->entnum-1].present) + continue; + } + if (clip->type & MOVE_NOMONSTERS && touch->v->solid != SOLID_BSP) continue; @@ -1789,16 +1665,16 @@ void SV_ClipToLinks ( areanode_t *node, moveclip_t *clip ) return; if (clip->passedict) { - if (PROG_TO_EDICT(svprogfuncs, touch->v->owner) == clip->passedict) + if ((wedict_t*)PROG_TO_EDICT(svprogfuncs, touch->v->owner) == clip->passedict) continue; // don't clip against own missiles - if (PROG_TO_EDICT(svprogfuncs, clip->passedict->v->owner) == touch) + if ((wedict_t*)PROG_TO_EDICT(svprogfuncs, clip->passedict->v->owner) == touch) continue; // don't clip against owner } if ((int)touch->v->flags & FL_MONSTER) - trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL); + trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins2, clip->maxs2, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL); else - trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL); + trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins, clip->maxs, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL); if (trace.allsolid || trace.startsolid || trace.fraction < clip->trace.fraction) { @@ -1812,12 +1688,12 @@ void SV_ClipToLinks ( areanode_t *node, moveclip_t *clip ) return; if ( clip->boxmaxs[node->axis] > node->dist ) - SV_ClipToLinks ( node->children[0], clip ); + World_ClipToLinks (w, node->children[0], clip ); if ( clip->boxmins[node->axis] < node->dist ) - SV_ClipToLinks ( node->children[1], clip ); + World_ClipToLinks (w, node->children[1], clip ); } #ifdef Q2SERVER -void SVQ2_ClipToLinks ( areanode_t *node, moveclip_t *clip ) +static void WorldQ2_ClipToLinks (world_t *w, areanode_t *node, moveclip_t *clip) { link_t *l, *next; q2edict_t *touch; @@ -1860,10 +1736,7 @@ void SVQ2_ClipToLinks ( areanode_t *node, moveclip_t *clip ) continue; // don't clip against owner } -// if ((int)touch->s.flags & FL_MONSTER) -// trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end); -// else - trace = SVQ2_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end); + trace = WorldQ2_ClipMoveToEntity (w, touch, clip->start, clip->mins, clip->maxs, clip->end); if (trace.allsolid || trace.startsolid || trace.fraction < clip->trace.fraction) @@ -1878,9 +1751,9 @@ void SVQ2_ClipToLinks ( areanode_t *node, moveclip_t *clip ) return; if ( clip->boxmaxs[node->axis] > node->dist ) - SV_ClipToLinks ( node->children[0], clip ); + World_ClipToLinks (w, node->children[0], clip ); if ( clip->boxmins[node->axis] < node->dist ) - SV_ClipToLinks ( node->children[1], clip ); + World_ClipToLinks (w, node->children[1], clip ); } #endif /* @@ -1888,7 +1761,7 @@ void SVQ2_ClipToLinks ( areanode_t *node, moveclip_t *clip ) SV_MoveBounds ================== */ -void SV_MoveBounds (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, vec3_t boxmins, vec3_t boxmaxs) +static void World_MoveBounds (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, vec3_t boxmins, vec3_t boxmaxs) { #if 0 // debug to test against everything @@ -1918,7 +1791,7 @@ boxmaxs[0] = boxmaxs[1] = boxmaxs[2] = 9999; SV_Move ================== */ -trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, edict_t *passedict) +trace_t World_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, wedict_t *passedict) { moveclip_t clip; int i; @@ -1940,13 +1813,13 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e //z pos/height are assumed to be different from all the others. for (i = 0; i < MAX_MAP_HULLSM; i++) { - if (!sv.worldmodel->hulls[i].available) + if (!w->worldmodel->hulls[i].available) continue; #define sq(x) ((x)*(x)) - diff = sq(sv.worldmodel->hulls[i].clip_maxs[2] - maxs[2]) + - sq(sv.worldmodel->hulls[i].clip_mins[2] - mins[2]) + - sq(sv.worldmodel->hulls[i].clip_maxs[1] - maxs[1]) + - sq(sv.worldmodel->hulls[i].clip_mins[0] - mins[0]); + diff = sq(w->worldmodel->hulls[i].clip_maxs[2] - maxs[2]) + + sq(w->worldmodel->hulls[i].clip_mins[2] - mins[2]) + + sq(w->worldmodel->hulls[i].clip_maxs[1] - maxs[1]) + + sq(w->worldmodel->hulls[i].clip_mins[0] - mins[0]); if (diff < best) { best = diff; @@ -1957,7 +1830,7 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e } // clip to world - clip.trace = SV_ClipMoveToEntity ( sv.edicts, start, mins, maxs, end, hullnum, false); + clip.trace = World_ClipMoveToEntity (w, w->edicts, w->edicts->v->origin, start, mins, maxs, end, hullnum, false); clip.start = start; clip.end = end; @@ -1985,13 +1858,102 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e } // create the bounding box of the entire move - SV_MoveBounds ( start, clip.mins2, clip.maxs2, end, clip.boxmins, clip.boxmaxs ); + World_MoveBounds (start, clip.mins2, clip.maxs2, end, clip.boxmins, clip.boxmaxs ); // clip to entities if (clip.type & MOVE_EVERYTHING) - SV_ClipToEverything (&clip); + World_ClipToEverything (w, &clip); else - SV_ClipToLinks ( sv_areanodes, &clip ); + { + if (clip.type & MOVE_LAGGED) + { + clip.type &= ~MOVE_LAGGED; + + if (passedict->entnum && passedict->entnum <= MAX_CLIENTS) + { + clip.type |= MOVE_LAGGED; + w->lagents = svs.clients[passedict->entnum-1].laggedents; + w->maxlagents = svs.clients[passedict->entnum-1].laggedents_count; + } + else if (passedict->v->owner) + { + if (passedict->v->owner && passedict->v->owner <= MAX_CLIENTS) + { + clip.type |= MOVE_LAGGED; + w->lagents = svs.clients[passedict->v->owner-1].laggedents; + w->maxlagents = svs.clients[passedict->v->owner-1].laggedents_count; + } + } + } + if (clip.type & MOVE_LAGGED) + { + trace_t trace; + wedict_t *touch; + + World_ClipToLinks (w, w->areanodes, &clip ); + + for (i = 0; i < w->maxlagents; i++) + { + if (!w->lagents[i].present) + continue; + if (clip.trace.allsolid) + break; + + touch = (wedict_t*)EDICT_NUM(w->progs, i+1); + if (touch->v->solid == SOLID_NOT) + continue; + if (touch == clip.passedict) + continue; + if (touch->v->solid == SOLID_TRIGGER || touch->v->solid == SOLID_LADDER) + SV_Error ("Trigger (%s) in clipping list", PR_GetString(svprogfuncs, touch->v->classname)); + + if (clip.type & MOVE_NOMONSTERS && touch->v->solid != SOLID_BSP) + continue; + + if (clip.passedict) + { + // don't clip corpse against character + if (clip.passedict->v->solid == SOLID_CORPSE && (touch->v->solid == SOLID_SLIDEBOX || touch->v->solid == SOLID_CORPSE)) + continue; + // don't clip character against corpse + if (clip.passedict->v->solid == SOLID_SLIDEBOX && touch->v->solid == SOLID_CORPSE) + continue; + + if (!((int)clip.passedict->xv->dimension_hit & (int)touch->xv->dimension_solid)) + continue; + } + + if (clip.boxmins[0] > touch->v->absmax[0] + || clip.boxmins[1] > touch->v->absmax[1] + || clip.boxmins[2] > touch->v->absmax[2] + || clip.boxmaxs[0] < touch->v->absmin[0] + || clip.boxmaxs[1] < touch->v->absmin[1] + || clip.boxmaxs[2] < touch->v->absmin[2] ) + continue; + + if (clip.passedict && clip.passedict->v->size[0] && !touch->v->size[0]) + continue; // points never interact + + if (clip.passedict) + { + if ((wedict_t*)PROG_TO_EDICT(svprogfuncs, touch->v->owner) == clip.passedict) + continue; // don't clip against own missiles + if ((wedict_t*)PROG_TO_EDICT(svprogfuncs, clip.passedict->v->owner) == touch) + continue; // don't clip against owner + } + + trace = World_ClipMoveToEntity (w, touch, w->lagents[i].laggedpos, clip.start, clip.mins, clip.maxs, clip.end, clip.hullnum, clip.type & MOVE_HITMODEL); + + if (trace.allsolid || trace.startsolid || trace.fraction < clip.trace.fraction) + { + trace.ent = touch; + clip.trace = trace; + } + } + } + else + World_ClipToLinks (w, w->areanodes, &clip ); + } if (clip.trace.startsolid) clip.trace.fraction = 0; @@ -2002,15 +1964,15 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e return clip.trace; } #ifdef Q2SERVER -trace_t SVQ2_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, q2edict_t *passedict) +trace_t WorldQ2_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, q2edict_t *passedict) { moveclip_t clip; memset ( &clip, 0, sizeof ( moveclip_t ) ); // clip to world - clip.trace = CM_BoxTrace(sv.worldmodel, start, end, mins, maxs, type);//SVQ2_ClipMoveToEntity ( ge->edicts, start, mins, maxs, end ); - clip.trace.ent = (edict_t *)ge->edicts; + clip.trace = CM_BoxTrace(w->worldmodel, start, end, mins, maxs, type);//SVQ2_ClipMoveToEntity ( ge->edicts, start, mins, maxs, end ); + clip.trace.ent = ge->edicts; if (clip.trace.fraction == 0) return clip.trace; @@ -2027,15 +1989,15 @@ trace_t SVQ2_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, VectorCopy (maxs, clip.maxs2); // create the bounding box of the entire move - SV_MoveBounds ( start, clip.mins2, clip.maxs2, end, clip.boxmins, clip.boxmaxs ); + World_MoveBounds ( start, clip.mins2, clip.maxs2, end, clip.boxmins, clip.boxmaxs ); // clip to entities #ifdef Q2BSPS - if (sv.worldmodel->fromgame == fg_quake2 || sv.worldmodel->fromgame == fg_quake3) - SVQ2_ClipMoveToEntities(&clip, type); + if (w->worldmodel->fromgame == fg_quake2 || w->worldmodel->fromgame == fg_quake3) + WorldQ2_ClipMoveToEntities(w, &clip, type); else #endif - SVQ2_ClipToLinks ( sv_areanodes, &clip ); + WorldQ2_ClipToLinks (w, w->areanodes, &clip ); return clip.trace; } diff --git a/plugins/paths.bat b/plugins/paths.bat index fb8f6093..824ceed8 100644 --- a/plugins/paths.bat +++ b/plugins/paths.bat @@ -3,8 +3,8 @@ REM building qvms is dependant upon the q3 source release. REM the gpled version is safe to use, but you will need to compile your own q3asm. REM I guess we should include our own copy of them. -set QuakeDir=\quake -set Q3SrcDir=\quake\quake3 +set QuakeDir=h:\quake +set Q3SrcDir=h:\quakestuff\quake3 set Path=%Q3SrcDir%\quake3-1.32b\lcc\bin;%Q3SrcDir%\quake3-1.32b\q3asm\debug;..\..\..\lcc;..\..\..\q3asm2 set PluginsDir=%QuakeDir%\fte\plugins diff --git a/plugins/plugins.dsw b/plugins/plugins.dsw index 83a60e26..f8d53146 100644 --- a/plugins/plugins.dsw +++ b/plugins/plugins.dsw @@ -15,7 +15,7 @@ Package=<4> ############################################################################### -Project: "emailsv"=.\emailsv\emailsv.dsp - Package Owner=<4> +Project: "emailsv"=..\..\plugins\emailsv\emailsv.dsp - Package Owner=<4> Package=<5> {{{ @@ -63,6 +63,18 @@ Package=<4> ############################################################################### +Project: "jabber"=.\jabber\jabber.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + Project: "serverb"=.\serverb\serverb.dsp - Package Owner=<4> Package=<5> diff --git a/plugins/xsv/m_x.c b/plugins/xsv/m_x.c index c41ae1bb..2469e1fa 100644 --- a/plugins/xsv/m_x.c +++ b/plugins/xsv/m_x.c @@ -1848,6 +1848,8 @@ int Plug_Init(int *args) Con_Printf("XServer plugin started\n"); + Cmd_AddCommand("startx"); + K_CTRL = Key_GetKeyCode("ctrl"); K_ALT = Key_GetKeyCode("alt"); diff --git a/plugins/xsv/x_reqs.c b/plugins/xsv/x_reqs.c index 7a1405c9..0bf5a08e 100644 --- a/plugins/xsv/x_reqs.c +++ b/plugins/xsv/x_reqs.c @@ -106,8 +106,6 @@ void XR_QueryExtension (xclient_t *cl, xReq *request) } else #endif - if (0) {} //for the else - else { Con_Printf("Extension %s not supported\n", extname); rep.major_opcode = 0; @@ -1035,7 +1033,7 @@ void XR_ChangeWindowAttributes (xclient_t *cl, xReq *request) if (req->valueMask > CWCursor) //anything else is an error on some implementation's part. X_SendError(cl, BadImplementation, 0, X_ChangeWindowAttributes, 0); - XW_ClearArea(wnd, 0, 0, wnd->width, wnd->height); +// XW_ClearArea(wnd, 0, 0, wnd->width, wnd->height); } void XR_ConfigureWindow (xclient_t *cl, xReq *request) diff --git a/specs/antilag.txt b/specs/antilag.txt new file mode 100644 index 00000000..d07d8ce5 --- /dev/null +++ b/specs/antilag.txt @@ -0,0 +1,14 @@ +FTE is able to perform serverside lag compensation +It is primarily controlled via the sv_antilag cvar, which shall be present in the serverinfo. + +If the cvar is set to 0, then no anti-lag will be performed, even if the mod attempts it. +If the cvar is 1, then the MOVE_LAGGED and FL_LAGGEDMOVE bit flags are valid. +If the cvar is 2, then the server will act as 1, but ALL tracelines will have laggedmove set (but not traceboxes), and ALL movetype_flymissile or movetype_bounce entities will act as if they have FL_LAGGEDMOVE set. This value is to force anti-lag within a mod, without any mod changes. Using this value may potentially cause a mod to malfunction, as it affects all tracelines - this does depend upon the mod. Thus it is better/safer if mods are adapted to use the new flags instead of it being forced. + +A separate but related feature found in FTE servers is the sv_minping cvar, which will enforce a minimum specific ping, however this doesn't always ensure a fair ping. + + +//antilag.qc: +//new cvar, sv_antilag. values 0, 1, 2 +float FL_LAGGEDMOVE = 65536; /*if set in self.flags, the entity will collide against a lagged copy of the world. The lagged copy depends upon the player, which is either this entity, or the entity's owner, whichever is the first player.*/ +float MOVE_LAGGED = 64; /*if this bit is set within the 'nomonsters' argument of traceline or tracebox, the trace will collide against the lagged world. Uses the ent parameter as the lagged player. If its not a player then the owner is used instead.*/ \ No newline at end of file diff --git a/specs/distort.pk3 b/specs/distort.pk3 new file mode 100644 index 0000000000000000000000000000000000000000..d5f7cfa7e4bab7e30b6e6bd6f521d39d3d27fd71 GIT binary patch literal 880 zcmWIWW@Zs#U|`^2Fy@Z8o)sdc*2u`faEFP3K@2EboROH4T2!o`l384mUsR$8;g<&a zdLMQWuw8!Pzrlj`C0Vn?Y+d=6%2%!Q(0#NvXY$=06W+9)T(+&_|J|Fum)#sa5}uvi zV{VR|c*fvM>@4fK-&!?_1-qM+FoPYd-LMWTk^)n5gTaKB$6DzaX z*}Cee{t}O!4cmWa+1B6RW9OUpdFtzHMy*YrPj72%m@xUfl$uS0!HE!66R|o6r*$)) z&K8gLRNlI%@3KI+vF^p?>r&@R?|k-q<j5UyG54@wL8=!4`b*GzB;JZVM zZ<)`XvpS^fGF$i6Cxw>vaph$zrfxaj+$EZNuF$4gclD0W-CGy?ZhGMUv|e2O{;>tC z+TNMkT-0;_k@>Koz9CV%{@C1I_FT$4HYpw4aC6JWMVC5cGGwGm-kq7uRKxgPfYm{K z{su8|1B+^*O@05lQzElxJ**B^mOo#!{m0h1HS?64e)LZ@`}Sht#zjk=u2ekxGMArK z`=QZF!JS55mdogN-86gLbx%y_B9o53{f+#L*}=P4gfi)69lQ9QIRGAMHo!>hj(lwW z9~fDBz)0f;(y+)%PD}5da5wLe0Z;4tl~>9?a0jTihP=s~FnPwhtc+DA2QD1h{rF3M z!REJ0lWO~tYmYy?k=!BBU%G%#_vy{@dAUlpN4*t1;*w=b*suCH)oWuA`yR88d`jo#DyO9apwKZ_^;t{Z}-FDq--1l>uPu4jdu7znOZf#lf`*vLHv*OOky>;R7TI=f5DlhIR{Rrs) zee9W6pXVj_X+OntQg?}*UU^gX`A3!jZ$>5&2HeRT7+4I93<@9$2(Tx1WHYdZHb^JL cjIF?ogB11w-mGjONhTny1=4qc(Zj$10IYFyXaE2J literal 0 HcmV?d00001 diff --git a/specs/distort.txt b/specs/distort.txt new file mode 100644 index 00000000..4253da1d --- /dev/null +++ b/specs/distort.txt @@ -0,0 +1,13 @@ +What is this? + +Its a simple particle config with somewhat more complex (glsl) rendering effect. +Simply put, it'll distort the screen behind rockets and grenades. + +To use, place the pk3 in your quake/fte/ dir. +Start up FTE. +r_particlesystem script +r_particlesdesc "spikeset tsshaft distort" + +The second line will give you the default particle config, with the two replacement trails overriding the built in effects. + +If you want to look at how its done, you can open the pk3 with winrar/7zip/winzip/windows explorer (if you change the filename extension). There are two text files inside. The effect could be adapted and applied to explosions and other stuff too. Enjoy. diff --git a/specs/example.shader b/specs/example.shader index 581e5589..a8b1ab75 100644 --- a/specs/example.shader +++ b/specs/example.shader @@ -24,6 +24,4 @@ console_glsl } } -//gl_shadeq1 can be used to allow shaders on q1 bsps/mdls -//gl_shadeq2 for q2 content -//gl_shadeq3 (default enabled) allows shaders on md3s and q3bsp + diff --git a/specs/ext_csqc_1.txt b/specs/ext_csqc_1.txt index d5830201..e69e0a11 100644 --- a/specs/ext_csqc_1.txt +++ b/specs/ext_csqc_1.txt @@ -327,8 +327,7 @@ float() readangle = #365; string() readstring = #366; float() readfloat = #367; float() readentitynum = #368; - Reads a part of a network message. - Note that these builtins are only valid when the engine directs the csqc to start reading. Valid only during that call. + Reads a part of a network message. Note that these builtins are only valid when the engine directs the csqc to start reading. Valid only during that call. In the case of readstring, it is returned within a temporary string. It is up to the engine exactly how big coords and angles are, so the csqc must ensure correct matching. For entities, readentitynum reads only an entity number. This must be matched to an entity with a matching .entnum field. The given entity may not always be known, so matching up in the parse function may not be advantageous. @@ -350,8 +349,7 @@ string(float statnum) getstats = #332; string(float playernum, string keyname) getplayerkey = #348; Obtains various player specific things. Items that must be supported are: name, frags, bottomcolor, topcolor. - This info is required for scoreboards. - Negative player indexes are interpreted as frag-sorted. -1 is the leading player, -2 is the second best player. There is no explicit teamplay support. + This info is required for scoreboards. Negative player indexes are interpreted as frag-sorted. -1 is the leading player, -2 is the second best player. There is no explicit teamplay support. This is akin to quakeworld's infokey builtin with a player number. Note: QuakeWorld engines normally provide a team field. NQ engines typically use bottomcolor. @@ -409,16 +407,19 @@ void(float index, float type, .void field) clientstat = #232; This affects all clients. There are two stat namespaces. Strings and numbers. Strings use independant indexes from numbers. Eg, stat 64 can hold "hello world" and the number 53.6 at the same time, depending on which you query. Index should not be less than 32. An engine is not required to support more than 128. + Sending a float is more efficient if it is rounded in advance. However, if it is not rounded, the stat will be sent with full precision. Type is a value equating to the ev_ values found in qcc to dictate types. Valid ones are: 1: string 2: float (if rounded between 0 and 255, this is sent compacted) - 3: vector (actually registers 3 consecutive floats) + 3: vector (actually registers 3 consecutive floats. Note rounding efficiencies.) 4: entity (actually the server's entity number, to match .entnum on the client, clients should read this as a whole number). + 8: integer (applicable only if your qcc and qcvm support integer types). + Certain other type values have meaning, but are not practical and thus are not valid arguments. void(float index, float type, string globalname) globalstat = #233; - Sets up a stat based on a global. + Sets up a stat based upon a global. Works the same way as clientstat, except that the global is passed by way of the name of the global, so beware of typos. - All clients will receive this stat. + All clients will receive the same stat value. .float(entity viewer, float sendflags) SendEntity; Field used to store which function is responsible for sending the current (self) entity data. diff --git a/specs/rtlights.txt b/specs/rtlights.txt new file mode 100644 index 00000000..6ca86463 --- /dev/null +++ b/specs/rtlights.txt @@ -0,0 +1,22 @@ +r_shadow_realtime_world: if 1, enables static realtime lighting +r_shadow_realtime_world_lightmaps: sets the intensity of the precomputed lightstyles. 0 means pure realtime lights, everything else is black. only effective if r_shadow_realtime_world is on +r_shadow_realtime_world_shadows: 0 disables shadows on static realtime lights. tbh not that useful, you're more likely to disable them entirely. + +r_shadow_realtime_dlight: if 1, enables dynamic shadows (on rockets and stuff). +r_shadow_realtime_dlight_shadows: controls whether you want to see shadows moving as the rocket flys past stuff or not. + +r_editlights_reload: command - changes the static realtime lights + : attempts to load lighting from maps/$mapname.rtlights. If that fails, acts as if bsp was specified. + bsp: generates static realtime lighting from the light entities within a bsp. not ideal, but can be useful depending on the number of lights on the map + none: removes all static realtime lights. the map goes dark... well, depending upon r_shadow_realtime_world_lightmaps anyway + note that this is performed implicitly at the start of each map. if static realtime lights is on, rtlights will be loaded. otherwise none will be. This command allows you to force reload, either because they're not loaded yet or you changed the rtlights file. +r_editlights_save: overwrites the rtlight file for the current map with the currently loaded rtlights. more for mods to provide a light editor interface. only really useful to generate a 'default' rtlights file which could then be edited by hand. not convienient. + +gl_bump: allows the loading and thus usage of bumpmaps, which basically add depth to the lighting effects. +gl_specular: makes surfaces shiny. aka: gloss. + + +at the time of writing, r_polygonoffset_* need to be set to 0, or you'll get pure black doors and stuff, doing so will renable z-fighting with co-planer bsp objects. To Be Fixed. + +Cheats: static realtime lighting _used_ to be cheat protected. Which made it useless and unusable. Darkplaces has permitted realtime lights for a while on quakeworld servers without complaint. Thus FTE no longer mandates that the server explicitly allows it. +Having said that, you can tell if static or dynamic lights are enabled in someone else's client via the f_version say request. \ No newline at end of file diff --git a/specs/videocapture.txt b/specs/videocapture.txt new file mode 100644 index 00000000..eaba16c2 --- /dev/null +++ b/specs/videocapture.txt @@ -0,0 +1,64 @@ +Video Capturing with FTE + +Overview: +FTE supports screen capture, outputting to either a series of screenshots or (on windows) AVI output. See the description of capturecodec for how output is chosen. +Capturing will work anywhere, in game, in menus, at the console, etc, with one exception. If a demo is currently being played, both the capturing and demo playback will pause whenever the game is not shown fullscreen - that is, if the console is shown, the menu is loaded, etc. +This allows you to visit the console and issue commands without breaks and pauses. +Also, when a demo is playing, the demo will be slowed to keep exactly in sync with the capturing. This is important with slow codecs, cpus, framerates, or hard disks. + +To capture part of a demo, issue the command: +capture demo.mvd;demo_jump 30:30;capturepause +This will begin capturing demo.mvd at a specific point, and will be paused. +You can then change the spectator to the correct point + + + + +Relevent commands: + +capture [outfilename] + This command tells FTE to begin capturing. + +capturedemo + This command tells FTE to begin capturing, and to play a demo at the same time. + This has only one advantage over capture and playdemo in that the result is fully synced to the demo. No loading screens and no stuff on the end. + This has limited use to making frag videos. + +capturestop + Terminates capturing immediatly. + +capturepause + Pauses capturing. Video displayed during this time will not be in the result. + +demo_jump [+][mins:]seconds + If the + is present, will jump relative to the current position. + Does not truly support rewinding, but will restart and jump the demo if you try. + + + +Relevent cvars: + +cl_demospeed + Can be used to slow down or accelerate a demo for one reason or annother. Set to 0 to freeze, and 1 for normal speed. + +capturemessage + Specifies a message to be placed on the screen, visible only in the output. + This can be changed at any point during capturing. + +capturesound + Specifies weather sound should be captured. This is only supported for AVI output. + Audio will be captured at the current snd_khz speed. Use snd_restart while not capturing to apply a new snd_khz setting. + Changes will not take effect until capturing is restarted. + +capturerate + Specifies the video frames per second to capture + Changes will not take effect until capturing is restarted. + +capturecodec + Specifies the type of output you want. + If left empty, the output will be uncompressed AVI. + If one of tga, jpg, png, or pcx are specified, output will be a series of screenshots, one image per file. + If it's a four-character-code, then it specifies what sort of video compression to use. Some codecs force splashscreens, so it might be a good idea to try new ones when running windowed. + Common four-character-codes are: + divx + xvid \ No newline at end of file