1
0
Fork 0
forked from fte/fteqw

sdl2 support.

hacky rendertarget stuff. not polished. don't use except for testing. feedback desired.
switched file system to use a qofs_t type instead. define FS_64BIT to make it 64bit (standard on 64bit cpus).
rewrote zip support, ditching unzip.c. this provided zip64 support, and unicode in zips.
changed local address enumeration to not be so stupid.
updated ode support a little to match some dp features.
changed fs_cache scheme, to not rebuild needlessly.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4596 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2014-02-07 08:38:40 +00:00
parent b9e46e4fa6
commit 1bb752b582
116 changed files with 3885 additions and 5423 deletions

View file

@ -28,6 +28,9 @@ WHOAMI:=$(shell whoami)
#linux->macosx (FTE_TARGET=macosx) or (FTE_TARGET=macosx_x86) #linux->macosx (FTE_TARGET=macosx) or (FTE_TARGET=macosx_x86)
#linux->javascript (FTE_TARGET=web) #linux->javascript (FTE_TARGET=web)
#linux->nacl (FTE_TARGET=nacl NARCH=x86_64) #linux->nacl (FTE_TARGET=nacl NARCH=x86_64)
#win32->nacl
#linux->droid (make droid)
#win32->droid (make droid)
#if you are cross compiling, you'll need to use FTE_TARGET=mytarget #if you are cross compiling, you'll need to use FTE_TARGET=mytarget
#cygwin's make's paths confuses non-cygwin things #cygwin's make's paths confuses non-cygwin things
@ -35,9 +38,14 @@ RELEASE_DIR=$(BASE_DIR)/release
DEBUG_DIR=$(BASE_DIR)/debug DEBUG_DIR=$(BASE_DIR)/debug
PROFILE_DIR=$(BASE_DIR)/profile PROFILE_DIR=$(BASE_DIR)/profile
ifneq ($(shell uname -o 2>&1 | grep Cygwin),) ifneq ($(shell uname -o 2>&1 | grep Cygwin),)
NATIVE_RELEASE_DIR=$(shell cygpath -m $(RELEASE_DIR)) OUT_DIR?=.
NATIVE_DEBUG_DIR=$(shell cygpath -m $(DEBUG_DIR)) NATIVE_OUT_DIR:=$(shell cygpath -m $(OUT_DIR))
NATIVE_BASE_DIR:=$(shell cygpath -m $(BASE_DIR))
NATIVE_RELEASE_DIR:=$(shell cygpath -m $(RELEASE_DIR))
NATIVE_DEBUG_DIR:=$(shell cygpath -m $(DEBUG_DIR))
endif endif
NATIVE_OUT_DIR?=$(OUT_DIR)
NATIVE_BASE_DIR?=$(BASE_DIR)
NATIVE_RELEASE_DIR?=$(RELEASE_DIR) NATIVE_RELEASE_DIR?=$(RELEASE_DIR)
NATIVE_DEBUG_DIR?=$(DEBUG_DIR) NATIVE_DEBUG_DIR?=$(DEBUG_DIR)
@ -346,11 +354,6 @@ ifeq ($(shell echo $(FTE_TARGET)|grep -v win),)
IMAGELDFLAGS=$(MINGW_LIBS_DIR)/libpng.a $(MINGW_LIBS_DIR)/libz.a $(MINGW_LIBS_DIR)/libjpeg.a IMAGELDFLAGS=$(MINGW_LIBS_DIR)/libpng.a $(MINGW_LIBS_DIR)/libz.a $(MINGW_LIBS_DIR)/libjpeg.a
OGGVORBISLDFLAGS=$(MINGW_LIBS_DIR)/libvorbisfile.a $(MINGW_LIBS_DIR)/libvorbis.a $(MINGW_LIBS_DIR)/libogg.a OGGVORBISLDFLAGS=$(MINGW_LIBS_DIR)/libvorbisfile.a $(MINGW_LIBS_DIR)/libvorbis.a $(MINGW_LIBS_DIR)/libogg.a
ifeq ($(shell echo $(FTE_TARGET)|grep -v -i _SDL),)
RELEASE_CFLAGS+= -D_SDL
SDL_LDFLAGS=$(MINGW_LIBS_DIR)/libSDL.a $(MINGW_LIBS_DIR)/libSDLmain.a -L./libs/mingw64-libs
endif
endif endif
IMAGELDFLAGS ?= -lpng -ljpeg IMAGELDFLAGS ?= -lpng -ljpeg
@ -369,13 +372,15 @@ else
GNUC_FUNCS= -Dstrnicmp=strncasecmp -Dstricmp=strcasecmp GNUC_FUNCS= -Dstrnicmp=strncasecmp -Dstricmp=strcasecmp
endif endif
SDL_INCLUDES=-I$(LIBS_DIR)/sdl/include -I/usr/include/SDL -I$(LIBS_DIR)/sdl/include/SDL SDL_INCLUDES=
#-I$(LIBS_DIR)/sdl/include -I/usr/include/SDL -I$(LIBS_DIR)/sdl/include/SDL
BOTLIB_CFLAGS=-I$(BOTLIB_DIR) -DBOTLIB BOTLIB_CFLAGS=-I$(BOTLIB_DIR) -DBOTLIB
BASE_CFLAGS=$(WARNINGFLAGS) $(GNUC_FUNCS) -I$(CLIENT_DIR) -I$(SERVER_DIR) -I$(COMMON_DIR) -I$(GL_DIR) -I$(D3D_DIR) -I$(PROGS_DIR) -I. -I$(LIBS_DIR) -I$(LIBS_DIR)/dxsdk9/include -I$(LIBS_DIR)/dxsdk7/include $(SDL_INCLUDES) -I./libs/freetype2/include -I./libs/freetype2/include/freetype -I./libs/speex $(BOTLIB_CFLAGS) $(SVNREVISION) BASE_CFLAGS=$(WARNINGFLAGS) $(GNUC_FUNCS) -I$(CLIENT_DIR) -I$(SERVER_DIR) -I$(COMMON_DIR) -I$(GL_DIR) -I$(D3D_DIR) -I$(PROGS_DIR) -I. -I$(LIBS_DIR) -I$(LIBS_DIR)/dxsdk9/include -I$(LIBS_DIR)/dxsdk7/include $(SDL_INCLUDES) -I./libs/freetype2/include -I./libs/freetype2/include/freetype -I./libs/speex $(BOTLIB_CFLAGS) $(SVNREVISION)
CLIENT_ONLY_CFLAGS=-DCLIENTONLY CLIENT_ONLY_CFLAGS=-DCLIENTONLY
SERVER_ONLY_CFLAGS=-DSERVERONLY SERVER_ONLY_CFLAGS=-DSERVERONLY
JOINT_CFLAGS= JOINT_CFLAGS=
DEBUG_CFLAGS=-ggdb -g -DDEBUG DEBUG_CFLAGS?=-ggdb -g
DEBUG_CFLAGS+=-DDEBUG
RELEASE_CFLAGS?=-O3 -ffast-math $(CPUOPTIMIZATIONS) RELEASE_CFLAGS?=-O3 -ffast-math $(CPUOPTIMIZATIONS)
#incase our compiler doesn't support it (mingw) #incase our compiler doesn't support it (mingw)
@ -682,12 +687,15 @@ BOTLIB_OBJS = \
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o
GL_EXE_NAME=../fteqw_sdl.gl$(BITS) GL_EXE_NAME=../fteqw_sdl.gl$(BITS)
GLCL_EXE_NAME=../fteqwcl_sdl.gl$(BITS) GLCL_EXE_NAME=../fteqwcl_sdl.gl$(BITS)
SDLCONFIG?=sdl-config
CC_MACHINE:=$(shell $(CC) -dumpmachine)
#SDLCONFIG:=libs/sdl2_mingw/$(CC_MACHINE)/bin/sdl2-config --prefix=libs/sdl2_mingw/$(CC_MACHINE)
ifdef windir ifdef windir
GL_LDFLAGS=$(GLLDFLAGS) -lmingw32 -lws2_32 `sdl-config --libs` GL_LDFLAGS=$(GLLDFLAGS) -lmingw32 -lws2_32 `$(SDLCONFIG) --libs`
else else
GL_LDFLAGS=$(GLLDFLAGS) $(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) `sdl-config --libs` GL_LDFLAGS=$(GLLDFLAGS) $(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) `$(SDLCONFIG) --libs`
endif endif
GL_CFLAGS=$(GLCFLAGS) `sdl-config --cflags` GL_CFLAGS=$(GLCFLAGS) `$(SDLCONFIG) --cflags`
GLB_DIR=gl_sdl$(FTE_TARGET)$(BITS) GLB_DIR=gl_sdl$(FTE_TARGET)$(BITS)
GLCL_DIR=glcl_sdl$(FTE_TARGET)$(BITS) GLCL_DIR=glcl_sdl$(FTE_TARGET)$(BITS)
@ -702,14 +710,14 @@ MINGL_EXE_NAME=../fteqw_sdl.mingl$(BITS)
MB_DIR=m_sdl$(FTE_TARGET)$(BITS) MB_DIR=m_sdl$(FTE_TARGET)$(BITS)
M_EXE_NAME=../fteqw_sdl$(BITS) M_EXE_NAME=../fteqw_sdl$(BITS)
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o
M_CFLAGS=$(GLCFLAGS) `sdl-config --cflags` -D_MERGED_SDL M_CFLAGS=$(GLCFLAGS) `$(SDLCONFIG) --cflags` -D_MERGED_SDL
M_LDFLAGS=$(GLLDFLAGS) $(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) M_LDFLAGS=$(GLLDFLAGS) $(IMAGELDFLAGS) $(OGGVORBISLDFLAGS)
ifdef windir ifdef windir
M_LDFLAGS=$(MLDFLAGS) -lmingw32 -lws2_32 -lSDLmain -lSDL M_LDFLAGS=$(MLDFLAGS) -lmingw32 -lws2_32 `$(SDLCONFIG) --libs`
else else
#pthread is needed because of SDL. #pthread is needed because of SDL.
M_LDFLAGS=$(MLDFLAGS) `sdl-config --libs` $(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) M_LDFLAGS=$(MLDFLAGS) `$(SDLCONFIG) --libs` $(IMAGELDFLAGS) $(OGGVORBISLDFLAGS)
endif endif
@ -793,12 +801,12 @@ ifeq ($(shell echo $(FTE_TARGET)|grep -E -i -v "win(32|64)_sdl$$"),)
GL_EXE_NAME=../fteqw_sdl_gl$(BITS)$(EXEPOSTFIX) GL_EXE_NAME=../fteqw_sdl_gl$(BITS)$(EXEPOSTFIX)
GLCL_EXE_NAME=../fteqwcl_sdl$(BITS)$(EXEPOSTFIX) GLCL_EXE_NAME=../fteqwcl_sdl$(BITS)$(EXEPOSTFIX)
ifdef windir ifdef windir
GL_LDFLAGS=$(GLLDFLAGS) -lmingw32 -lws2_32 `sdl-config --libs` GL_LDFLAGS=$(GLLDFLAGS) -lmingw32 -lws2_32 `$(SDLCONFIG) --libs`
else else
GL_LDFLAGS=$(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) -lws2_32 -lmingw32 $(SDL_LDFLAGS) -mwindows -ldxguid -lwinmm -lole32 $(GLLDFLAGS) `sdl-config --libs` GL_LDFLAGS=$(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) -lws2_32 -lmingw32 $(SDL_LDFLAGS) -mwindows -ldxguid -lwinmm -lole32 $(GLLDFLAGS) `$(SDLCONFIG) --libs`
endif endif
GL_CFLAGS=-D_SDL -I$(MINGW_LIBS_DIR)/ -I$(MINGW_LIBS_DIR) -I$(LIBS_DIR) $(GLCFLAGS) -DLIBVORBISFILE_STATIC `sdl-config --cflags` $(DX7SDK) $(SPEEXCFLAGS) GL_CFLAGS=-D_SDL -I$(MINGW_LIBS_DIR)/ -I$(MINGW_LIBS_DIR) -I$(LIBS_DIR) $(GLCFLAGS) -DLIBVORBISFILE_STATIC `$(SDLCONFIG) --cflags` $(DX7SDK) $(SPEEXCFLAGS)
ifeq ($(shell echo $(FTE_TARGET)|grep -E -i -v "win32.*sdl"),) ifeq ($(shell echo $(FTE_TARGET)|grep -E -i -v "win32.*sdl"),)
GL_CFLAGS+= -D_MINGW_VFPRINTF GL_CFLAGS+= -D_MINGW_VFPRINTF
endif endif
@ -817,7 +825,7 @@ ifeq ($(shell echo $(FTE_TARGET)|grep -E -i -v "win(32|64)_sdl$$"),)
MB_DIR=m_mgw_sdl$(BITS) MB_DIR=m_mgw_sdl$(BITS)
M_EXE_NAME=../fteqw_sdl$(BITS)$(EXEPOSTFIX) M_EXE_NAME=../fteqw_sdl$(BITS)$(EXEPOSTFIX)
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(D3DQUAKE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o snd_directx.o $(LTO_END) resources.o $(LTO_START) MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(D3DQUAKE_OBJS) $(BOTLIB_OBJS) $(SPEEX_OBJS) gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o snd_directx.o $(LTO_END) resources.o $(LTO_START)
M_CFLAGS=$(D3DCFLAGS) -D_SDL -I$(LIBS_DIR) -I$(MINGW_LIBS_DIR)/ -I$(MINGW_LIBS_DIR) $(GLCFLAGS) -DLIBVORBISFILE_STATIC `sdl-config --cflags` -D_MERGED_SDL $(DX7SDK) $(SPEEXCFLAGS) M_CFLAGS=$(D3DCFLAGS) -D_SDL -I$(LIBS_DIR) -I$(MINGW_LIBS_DIR)/ -I$(MINGW_LIBS_DIR) $(GLCFLAGS) -DLIBVORBISFILE_STATIC `$(SDL_CONFIG) --cflags` -D_MERGED_SDL $(DX7SDK) $(SPEEXCFLAGS)
ifeq ($(shell echo $(FTE_TARGET)|grep -E -i -v "win32.*sdl"),) ifeq ($(shell echo $(FTE_TARGET)|grep -E -i -v "win32.*sdl"),)
M_CFLAGS+= -D_MINGW_VFPRINTF M_CFLAGS+= -D_MINGW_VFPRINTF
@ -826,17 +834,17 @@ ifeq ($(shell echo $(FTE_TARGET)|grep -E -i -v "win(32|64)_sdl$$"),)
M_LDFLAGS=$(GLLDFLAGS) $(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) M_LDFLAGS=$(GLLDFLAGS) $(IMAGELDFLAGS) $(OGGVORBISLDFLAGS)
ifdef windir ifdef windir
M_LDFLAGS=$(MLDFLAGS) -lmingw32 -lws2_32 -lSDLmain -lSDL M_LDFLAGS=$(MLDFLAGS) -lmingw32 -lws2_32 `$(SDLCONFIG) --libs`
else else
#pthread is needed because of SDL. #pthread is needed because of SDL.
M_LDFLAGS=$(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) -lws2_32 -lmingw32 $(MINGW_LIBS_DIR)/libSDL.a $(MINGW_LIBS_DIR)/libSDLmain.a -mwindows -ldxguid -lwinmm -lole32 $(MLDFLAGS) `sdl-config --libs` $(IMAGELDFLAGS) M_LDFLAGS=$(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) -lws2_32 -lmingw32 -mwindows -ldxguid -lwinmm -lole32 $(MLDFLAGS) `$(SDL_CONFIG) --libs` $(IMAGELDFLAGS)
endif endif
D3DCL_OBJS=$(D3DQUAKE_OBJS) $(SPEEX_OBJS) snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o snd_directx.o $(D3DGL_OBJS) $(LTO_END) resources.o $(LTO_START) D3DCL_OBJS=$(D3DQUAKE_OBJS) $(SPEEX_OBJS) snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o snd_directx.o $(D3DGL_OBJS) $(LTO_END) resources.o $(LTO_START)
D3D_EXE_NAME=../fted3d_sdl_qw$(BITS)$(EXEPOSTFIX) D3D_EXE_NAME=../fted3d_sdl_qw$(BITS)$(EXEPOSTFIX)
D3DCL_EXE_NAME=../fted3d_sdl_clqw$(BITS)$(EXEPOSTFIX) D3DCL_EXE_NAME=../fted3d_sdl_clqw$(BITS)$(EXEPOSTFIX)
D3D_LDFLAGS=$(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) -lws2_32 -lmingw32 $(SDL_LDFLAGS) -mwindows -ldxguid -lwinmm -lole32 D3D_LDFLAGS=$(IMAGELDFLAGS) $(OGGVORBISLDFLAGS) -lws2_32 -lmingw32 $(SDL_LDFLAGS) -mwindows -ldxguid -lwinmm -lole32
D3D_CFLAGS=$(D3DCFLAGS) -D_SDL -DNO_XFLIP -I$(LIBS_DIR) -I$(MINGW_LIBS_DIR)/ -I$(MINGW_LIBS_DIR) -DLIBVORBISFILE_STATIC `sdl-config --cflags` $(DX7SDK) $(SPEEXCFLAGS) D3D_CFLAGS=$(D3DCFLAGS) -D_SDL -DNO_XFLIP -I$(LIBS_DIR) -I$(MINGW_LIBS_DIR)/ -I$(MINGW_LIBS_DIR) -DLIBVORBISFILE_STATIC `$(SDL_CONFIG) --cflags` $(DX7SDK) $(SPEEXCFLAGS)
ifeq ($(shell echo $(FTE_TARGET)|grep -E -i -v "win32.*sdl"),) ifeq ($(shell echo $(FTE_TARGET)|grep -E -i -v "win32.*sdl"),)
D3D_CFLAGS+= -D_MINGW_VFPRINTF D3D_CFLAGS+= -D_MINGW_VFPRINTF
endif endif
@ -847,19 +855,23 @@ endif
#FTE_TARGET=vc (Visual C) #FTE_TARGET=vc (Visual C)
ifeq ($(FTE_TARGET),vc) ifeq ($(FTE_TARGET),vc)
DEBUG_CFLAGS=
MSVCDIR=Microsoft Visual Studio 10.0
WINDOWSSDKDIR=C:/Program Files/Microsoft SDKs/Windows/v7.1
ifeq ($(BITS),64) ifeq ($(BITS),64)
WINDRES=x86_64-w64-mingw32-windres WINDRES=x86_64-w64-mingw32-windres
MSVCPATH=C:/Program Files (x86)/Microsoft Visual Studio 8/VC/BIN/amd64/ MSVCPATH=C:/Program Files (x86)/$(MSVCDIR)/VC/BIN/amd64/
MSVCINC=-I"C:\Program Files (x86)\Microsoft Visual Studio 8\VC\ATLMFC\INCLUDE" -I"C:\Program Files (x86)\Microsoft Visual Studio 8\VC\INCLUDE" -I"C:\Program Files (x86)\Microsoft Visual Studio 8\VC\PlatformSDK\include" -I"C:\Program Files (x86)\Microsoft Visual Studio 8\SDK\v2.0\include" MSVCINC=-I"C:\Program Files (x86)\$(MSVCDIR)\VC\ATLMFC\INCLUDE" -I"C:\Program Files (x86)\$(MSVCDIR)\VC\INCLUDE" -I"C:\Program Files (x86)\Microsoft Visual Studio 8\VC\PlatformSDK\include" -I"C:\Program Files (x86)\Microsoft Visual Studio 8\SDK\v2.0\include"
MSVCLIB=/LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio 8\VC\ATLMFC\LIB\amd64" /LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio 8\VC\LIB\amd64" /LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio 8\VC\PlatformSDK\lib\amd64" /LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio 8\SDK\v2.0\LIB\AMD64" MSVCLIB=/LIBPATH:"C:\Program Files (x86)\$(MSVCPATH)\VC\ATLMFC\LIB\amd64" /LIBPATH:"C:\Program Files (x86)\$(MSVCPATH)\VC\LIB\amd64" /LIBPATH:"$(WINDOWSSDKDIR)\lib\amd64" /LIBPATH:"C:\Program Files (x86)\$(MSVCPATH)\SDK\v2.0\LIB\AMD64"
JPEGLIB=libs/libjpeg$(BITS).lib JPEGLIB=libs/libjpeg$(BITS).lib
else else
MSVCPATH=C:/Program Files (x86)/Microsoft Visual Studio 8/VC/BIN/ WINDRES=i686-w64-mingw32-windres
MSVCPATH=C:/Program Files (x86)/$(MSVCDIR)/VC/BIN/
MSVCINC=-I"C:\Program Files (x86)\Microsoft Visual Studio 8\VC\ATLMFC\INCLUDE" -I"C:\Program Files (x86)\Microsoft Visual Studio 8\VC\INCLUDE" -I"C:\Program Files (x86)\Microsoft Visual Studio 8\VC\PlatformSDK\include" -I"C:\Program Files (x86)\Microsoft Visual Studio 8\SDK\v2.0\include" MSVCINC=-I"C:\Program Files (x86)\$(MSVCDIR)\VC\ATLMFC\INCLUDE" -I"C:\Program Files (x86)\$(MSVCDIR)\VC\INCLUDE" -I"C:\Program Files (x86)\$(MSVCDIR)\VC\PlatformSDK\include" -I"C:\Program Files (x86)\$(MSVCDIR)\SDK\v2.0\include"
MSVCLIB=/LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio 8\VC\ATLMFC\LIB" /LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio 8\VC\LIB" /LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio 8\VC\PlatformSDK\lib" /LIBPATH:"C:\Program Files (x86)\Microsoft Visual Studio 8\SDK\v2.0\LIB" MSVCLIB=/LIBPATH:"C:\Program Files (x86)\$(MSVCDIR)\VC\ATLMFC\LIB" /LIBPATH:"C:\Program Files (x86)\$(MSVCDIR)\VC\LIB" /LIBPATH:"$(WINDOWSSDKDIR)\lib" /LIBPATH:"C:\Program Files (x86)\$(MSVCDIR)\SDK\v2.0\LIB"
JPEGLIB=libs/jpeg.lib JPEGLIB=libs/jpeg.lib
endif endif
STRIP=@echo strip STRIP=@echo strip
@ -869,11 +881,12 @@ ifeq ($(FTE_TARGET),vc)
DEBUG_CFLAGS ?= -Od $(CPUOPTIMIZATIONS) /fp:fast DEBUG_CFLAGS ?= -Od $(CPUOPTIMIZATIONS) /fp:fast
PROFILE_CFLAGS = -O2 -Ot -Ox -GL $(CPUOPTIMISATIONS) /fp:fast PROFILE_CFLAGS = -O2 -Ot -Ox -GL $(CPUOPTIMISATIONS) /fp:fast
PROFILE_LDFLAGS = /LTCG:PGINSTRUMENT PROFILE_LDFLAGS = /LTCG:PGINSTRUMENT
RELEASE_CFLAGS = -O2 -Ot -Ox -GL $(CPUOPTIMIZATIONS) /fp:fast RELEASE_CFLAGS = -O2 -Ot -Ox -GL -GS- -Gr $(CPUOPTIMIZATIONS) /fp:fast
RELEASE_LDFLAGS = /LTCG:PGOPTIMIZE RELEASE_LDFLAGS = /LTCG
# /LTCG:PGOPTIMIZE
DO_CC=@$(CC) /nologo $(ALL_CFLAGS) -Fo$@ -c $< DO_CC=@$(CC) /nologo $(ALL_CFLAGS) -Fo$(shell cygpath -m $@) -c $(shell cygpath -m $<)
DO_LD=$(DO_ECHO) "$(MSVCPATH)link" /nologo /out:"$@" /nodefaultlib:libc.lib /LARGEADDRESSAWARE /nodefaultlib:MSVCRT $(MSVCLIB) /manifest:no /OPT:REF wsock32.lib user32.lib advapi32.lib winmm.lib libs/zlib$(BITS).lib shell32.lib DO_LD=$(DO_ECHO) "$(MSVCPATH)link" /nologo /out:"$(shell cygpath -m $@)" /nodefaultlib:libc.lib /LARGEADDRESSAWARE /nodefaultlib:MSVCRT $(MSVCLIB) /manifest:no /OPT:REF wsock32.lib user32.lib kernel32.lib advapi32.lib winmm.lib libs/zlib$(BITS).lib shell32.lib
PRECOMPHEADERS = PRECOMPHEADERS =
DEPCC= DEPCC=
@ -881,6 +894,7 @@ ifeq ($(FTE_TARGET),vc)
SPEEXCFLAGS+= -Dinline=_inline -D_USE_MATH_DEFINES SPEEXCFLAGS+= -Dinline=_inline -D_USE_MATH_DEFINES
BASE_CFLAGS:=$(WARNINGFLAGS) $(GNUC_FUNCS) -I$(shell cygpath -m $(CLIENT_DIR)) -I$(shell cygpath -m $(SERVER_DIR)) -I$(shell cygpath -m $(COMMON_DIR)) -I$(shell cygpath -m $(GL_DIR)) -I$(shell cygpath -m $(D3D_DIR)) -I$(shell cygpath -m $(PROGS_DIR)) -I. -I$(LIBS_DIR) -I$(LIBS_DIR)/dxsdk9/include -I$(LIBS_DIR)/dxsdk7/include $(SDL_INCLUDES) -I./libs/freetype2/include -I./libs/freetype2/include/freetype -I./libs/speex $(BOTLIB_CFLAGS) $(SVNREVISION)
SV_CFLAGS=$(SERVER_ONLY_CFLAGS) $(W32_CFLAGS) -DMULTITHREAD -DMSVCLIBSPATH="libs/" SV_CFLAGS=$(SERVER_ONLY_CFLAGS) $(W32_CFLAGS) -DMULTITHREAD -DMSVCLIBSPATH="libs/"
SV_EXE_NAME=../fteqwsv$(BITS)$(EXEPOSTFIX) SV_EXE_NAME=../fteqwsv$(BITS)$(EXEPOSTFIX)
@ -1311,7 +1325,7 @@ PRECOMPHEADERS ?= $(OUT_DIR)/quakedef.h.gch
DO_LD ?= $(CC) -o $@ $(LTO_LD) $(WCFLAGS) $(CFLAGS) DO_LD ?= $(CC) -o $@ $(LTO_LD) $(WCFLAGS) $(CFLAGS)
$(OUT_DIR)/$(EXE_NAME): $(PRECOMPHEADERS) $(foreach fn, $(CUSTOMOBJS) $(foreach ol, $(OBJS), $($(ol))),$(if $(findstring ltox,$(fn)),,$(OUT_DIR)/$(fn))) $(OUT_DIR)/$(EXE_NAME): $(PRECOMPHEADERS) $(foreach fn, $(CUSTOMOBJS) $(foreach ol, $(OBJS), $($(ol))),$(if $(findstring ltox,$(fn)),,$(OUT_DIR)/$(fn)))
$(DO_LD) $(foreach fn, $(CUSTOMOBJS) $(foreach ol, $(OBJS) $(LTO_END), $($(ol))),$(if $(findstring ltox,$(fn)),$(subst ltox,-x ,$(fn)),$(OUT_DIR)/$(fn)) ) $(LDFLAGS) $(DO_LD) $(foreach fn, $(CUSTOMOBJS) $(foreach ol, $(OBJS) $(LTO_END), $($(ol))),$(if $(findstring ltox,$(fn)),$(subst ltox,-x ,$(fn)),$(NATIVE_OUT_DIR)/$(fn)) ) $(LDFLAGS)
_out-rel: _out-rel:
@$(MAKE) $(OUT_DIR)/$(EXE_NAME) EXE_NAME="$(EXE_NAME)" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(WCFLAGS) $(RELEASE_CFLAGS)" LDFLAGS="$(BASELDFLAGS) $(LDFLAGS) $(RELEASE_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)"
@ -1415,7 +1429,7 @@ m-dbg:
m-profile: m-profile:
@$(MAKE) m-tmp TYPE=_clsv-profile OUT_DIR="$(PROFILE_DIR)/$(MB_DIR)" @$(MAKE) m-tmp TYPE=_clsv-profile OUT_DIR="$(PROFILE_DIR)/$(MB_DIR)"
.PHONY: m-tmp mcl-tmp mingl-tmp glcl-tmp gl-tmp sv-tmp _clsv-dbg _clsv-rel _cl-dbg _cl-rel _out-rel _out-dbg .PHONY: m-tmp mcl-tmp mingl-tmp glcl-tmp gl-tmp sv-tmp _clsv-dbg _clsv-rel _cl-dbg _cl-rel _out-rel _out-dbg reldir debugdir
_qcc-tmp: $(REQDIR) _qcc-tmp: $(REQDIR)

View file

@ -2,6 +2,11 @@
#include <SDL.h> #include <SDL.h>
#if SDL_MAJOR_VERSION >= 2
//sdl2 has no cd support. sod off.
#include "cd_null.c"
#else
extern cvar_t bgmvolume; extern cvar_t bgmvolume;
static qboolean initialized = false; static qboolean initialized = false;
@ -121,3 +126,4 @@ void CDAudio_Shutdown(void)
cddevice = NULL; cddevice = NULL;
initialized = false; initialized = false;
} }
#endif

View file

@ -1646,7 +1646,7 @@ void CL_PlayDemoStream(vfsfile_t *file, struct dl_download *dl, char *filename,
void CL_PlayDemo(char *demoname) void CL_PlayDemo(char *demoname)
{ {
char name[256]; char name[256];
int start; qofs_t start;
vfsfile_t *f; vfsfile_t *f;
// //

View file

@ -4489,12 +4489,6 @@ void CL_LinkViewModel(void)
extern cvar_t cl_gunx, cl_guny, cl_gunz; extern cvar_t cl_gunx, cl_guny, cl_gunz;
extern cvar_t cl_gunanglex, cl_gunangley, cl_gunanglez; extern cvar_t cl_gunanglex, cl_gunangley, cl_gunanglez;
#ifdef SIDEVIEWS
extern qboolean r_secondaryview;
if (r_secondaryview==1)
return;
#endif
if (r_drawviewmodel.value <= 0 || !Cam_DrawViewModel(r_refdef.playerview)) if (r_drawviewmodel.value <= 0 || !Cam_DrawViewModel(r_refdef.playerview))
return; return;

View file

@ -1734,9 +1734,12 @@ void CL_SendCmd (double frametime, qboolean mainloop)
// if (skipcmd) // if (skipcmd)
// return; // return;
if (!fullsend) if (!fullsend || !msecstouse)
return; // when we're actually playing we try to match netfps exactly to avoid gameplay problems return; // when we're actually playing we try to match netfps exactly to avoid gameplay problems
if (msecstouse > 127)
Con_Printf("%i\n", msecstouse, msecs);
#ifdef NQPROT #ifdef NQPROT
if (cls.protocol != CP_NETQUAKE || cls.netchan.nqreliable_allowed) if (cls.protocol != CP_NETQUAKE || cls.netchan.nqreliable_allowed)
#endif #endif

View file

@ -3988,7 +3988,7 @@ void Host_DoRunFile(hrf_t *f)
qboolean Host_RunFile(const char *fname, int nlen, vfsfile_t *file) qboolean Host_RunFile(const char *fname, int nlen, vfsfile_t *file)
{ {
hrf_t *f; hrf_t *f;
#ifdef _WIN32 #if defined(_WIN32) && !defined(_SDL)
//win32 file urls are basically fucked, so defer to the windows api. //win32 file urls are basically fucked, so defer to the windows api.
char utf8[MAX_OSPATH*3]; char utf8[MAX_OSPATH*3];
if (nlen >= 7 && !strncmp(fname, "file://", 7)) if (nlen >= 7 && !strncmp(fname, "file://", 7))

View file

@ -411,6 +411,21 @@ void CL_AckedInputFrame(int inseq, int outseq, qboolean worldstateokay)
//============================================================================= //=============================================================================
int CL_IsDownloading(char *localname)
{
downloadlist_t *dl;
/*check for dupes*/
for (dl = cl.downloadlist; dl; dl = dl->next) //It's already on our list. Ignore it.
{
if (!strcmp(dl->localname, localname))
return 2; //queued
}
if (!strcmp(cls.downloadlocalname, localname))
return 1; //downloading
return 0;
}
//note: this will overwrite existing files. //note: this will overwrite existing files.
//returns true if the download is going to be downloaded after the call. //returns true if the download is going to be downloaded after the call.
qboolean CL_EnqueDownload(char *filename, char *localname, unsigned int flags) qboolean CL_EnqueDownload(char *filename, char *localname, unsigned int flags)
@ -461,21 +476,19 @@ qboolean CL_EnqueDownload(char *filename, char *localname, unsigned int flags)
} }
/*check for dupes*/ /*check for dupes*/
for (dl = cl.downloadlist; dl; dl = dl->next) //It's already on our list. Ignore it. switch(CL_IsDownloading(localname))
{
if (!strcmp(dl->rname, filename))
{
if (flags & DLLF_VERBOSE)
Con_Printf("Already waiting for \"%s\"\n", filename);
return true;
}
}
if (!strcmp(cls.downloadremotename, filename))
{ {
case 2:
if (flags & DLLF_VERBOSE)
Con_Printf("Already waiting for \"%s\"\n", filename);
return true;
default:
case 1:
if (flags & DLLF_VERBOSE) if (flags & DLLF_VERBOSE)
Con_Printf("Already downloading \"%s\"\n", filename); Con_Printf("Already downloading \"%s\"\n", filename);
return true; return true;
case 0:
break;
} }
if (!*filename) if (!*filename)
@ -1699,7 +1712,7 @@ void CL_ParseChunkedDownload(void)
qbyte *svname; qbyte *svname;
//qbyte osname[MAX_OSPATH]; //unreferenced //qbyte osname[MAX_OSPATH]; //unreferenced
int totalsize; int totalsize;
int chunknum, ridx; qofs_t chunknum, ridx;
char data[DLBLOCKSIZE]; char data[DLBLOCKSIZE];
chunknum = MSG_ReadLong(); chunknum = MSG_ReadLong();
@ -2076,7 +2089,7 @@ qboolean CL_ParseOOBDownload(void)
void CLDP_ParseDownloadData(void) void CLDP_ParseDownloadData(void)
{ {
unsigned char buffer[1<<16]; unsigned char buffer[1<<16];
int start; qofs_t start;
int size; int size;
start = MSG_ReadLong(); start = MSG_ReadLong();
size = (unsigned short)MSG_ReadShort(); size = (unsigned short)MSG_ReadShort();

View file

@ -1027,6 +1027,7 @@ void CLQ2_ParseServerMessage (void);
#endif #endif
void CL_NewTranslation (int slot); void CL_NewTranslation (int slot);
int CL_IsDownloading(char *localname);
qboolean CL_CheckOrEnqueDownloadFile (char *filename, char *localname, unsigned int flags); qboolean CL_CheckOrEnqueDownloadFile (char *filename, char *localname, unsigned int flags);
qboolean CL_EnqueDownload(char *filename, char *localname, unsigned int flags); qboolean CL_EnqueDownload(char *filename, char *localname, unsigned int flags);
downloadlist_t *CL_DownloadFailed(char *name, qboolean cancel); downloadlist_t *CL_DownloadFailed(char *name, qboolean cancel);
@ -1105,7 +1106,7 @@ void CL_ParsePlayerinfo (void);
void CL_ParseClientPersist(void); void CL_ParseClientPersist(void);
//these last ones are needed for csqc handling of engine-bound ents. //these last ones are needed for csqc handling of engine-bound ents.
void CL_ClearEntityLists(void); void CL_ClearEntityLists(void);
void CL_EditExternalModels(int newviewentity); int CL_EditExternalModels(int newviewentity, entity_t *viewentities, int maxviewenties);
void CL_FreeVisEdicts(void); void CL_FreeVisEdicts(void);
void CL_LinkViewModel(void); void CL_LinkViewModel(void);
void CL_LinkPlayers (void); void CL_LinkPlayers (void);

View file

@ -489,7 +489,7 @@ cinematics_t *CIN_PlayCinematic (char *arg)
} }
else else
{ {
Con_Printf(CON_WARNING "Cinematic %s not found.\n", name); Con_Printf(CON_WARNING "Cinematic %s not found.\n", arg);
} }
return cin; return cin;
} }

View file

@ -732,7 +732,7 @@ void Con_PrintCon (console_t *con, char *txt)
reuse->newer = NULL; reuse->newer = NULL;
reuse->older = NULL; reuse->older = NULL;
} }
reuse->id = ++con->nextlineid; reuse->id = (++con->nextlineid) & 0xffff;
reuse->older = con->current; reuse->older = con->current;
con->current->newer = reuse; con->current->newer = reuse;
con->current = reuse; con->current = reuse;
@ -1286,7 +1286,7 @@ void Con_DrawNotify (void)
conchar_t *ends[8]; conchar_t *ends[8];
conchar_t markup[MAXCMDLINE+64]; conchar_t markup[MAXCMDLINE+64];
conchar_t *c, *end; conchar_t *c, *end;
char *foo = va(chat_team?"say_team: %s":"say: %s", chat_buffer?chat_buffer:""); char *foo = va(chat_team?"say_team: %s":"say: %s", chat_buffer?(char*)chat_buffer:"");
int lines, i, pos; int lines, i, pos;
Font_BeginString(font_console, 0, 0, &x, &y); Font_BeginString(font_console, 0, 0, &x, &y);
y = con_main.notif_l * Font_CharHeight(); y = con_main.notif_l * Font_CharHeight();

View file

@ -670,16 +670,21 @@ qbyte *ReadTargaFile(qbyte *buf, int length, int *width, int *height, qboolean *
#define PNG_ALLOCATED #define PNG_ALLOCATED
#endif #endif
#define png_const_infop png_infop #if PNG_LIBPNG_VER < 10500
#define png_const_structp png_structp #define png_const_infop png_infop
#define png_const_bytep png_bytep #define png_const_structp png_structp
#define png_const_bytep png_bytep
#endif
#if PNG_LIBPNG_VER < 10600
#define png_const_inforp png_const_infop
#endif
void (PNGAPI *qpng_error) PNGARG((png_structp png_ptr, png_const_charp error_message)) PSTATIC(png_error); void (PNGAPI *qpng_error) PNGARG((png_structp png_ptr, png_const_charp error_message)) PSTATIC(png_error);
void (PNGAPI *qpng_read_end) PNGARG((png_structp png_ptr, png_infop info_ptr)) PSTATIC(png_read_end); void (PNGAPI *qpng_read_end) PNGARG((png_structp png_ptr, png_infop info_ptr)) PSTATIC(png_read_end);
void (PNGAPI *qpng_read_image) PNGARG((png_structp png_ptr, png_bytepp image)) PSTATIC(png_read_image); void (PNGAPI *qpng_read_image) PNGARG((png_structp png_ptr, png_bytepp image)) PSTATIC(png_read_image);
png_byte (PNGAPI *qpng_get_bit_depth) PNGARG((png_const_structp png_ptr, png_const_infop info_ptr)) PSTATIC(png_get_bit_depth); png_byte (PNGAPI *qpng_get_bit_depth) PNGARG((png_const_structp png_ptr, png_const_inforp info_ptr)) PSTATIC(png_get_bit_depth);
png_byte (PNGAPI *qpng_get_channels) PNGARG((png_const_structp png_ptr, png_const_infop info_ptr)) PSTATIC(png_get_channels); png_byte (PNGAPI *qpng_get_channels) PNGARG((png_const_structp png_ptr, png_const_inforp info_ptr)) PSTATIC(png_get_channels);
png_size_t (PNGAPI *qpng_get_rowbytes) PNGARG((png_const_structp png_ptr, png_const_infop info_ptr)) PSTATIC(png_get_rowbytes); png_size_t (PNGAPI *qpng_get_rowbytes) PNGARG((png_const_structp png_ptr, png_const_inforp info_ptr)) PSTATIC(png_get_rowbytes);
void (PNGAPI *qpng_read_update_info) PNGARG((png_structp png_ptr, png_infop info_ptr)) PSTATIC(png_read_update_info); void (PNGAPI *qpng_read_update_info) PNGARG((png_structp png_ptr, png_infop info_ptr)) PSTATIC(png_read_update_info);
void (PNGAPI *qpng_set_strip_16) PNGARG((png_structp png_ptr)) PSTATIC(png_set_strip_16); void (PNGAPI *qpng_set_strip_16) PNGARG((png_structp png_ptr)) PSTATIC(png_set_strip_16);
void (PNGAPI *qpng_set_expand) PNGARG((png_structp png_ptr)) PSTATIC(png_set_expand); void (PNGAPI *qpng_set_expand) PNGARG((png_structp png_ptr)) PSTATIC(png_set_expand);
@ -759,9 +764,16 @@ qboolean LibPNG_Init(void)
}; };
if (!LIBPNG_LOADED()) if (!LIBPNG_LOADED())
libpng_handle = Sys_LoadLibrary("libpng", pngfuncs); {
if (!LIBPNG_LOADED()) #ifdef _WIN32
libpng_handle = Sys_LoadLibrary("libpng12", pngfuncs); libpng_handle = Sys_LoadLibrary("libpng"STRINGIFY(PNG_LIBPNG_VER_DLLNUM), pngfuncs);
#else
libpng_handle = Sys_LoadLibrary("libpng.so."STRINGIFY(PNG_LIBPNG_VER_SONUM), pngfuncs);
#endif
}
// if (!LIBPNG_LOADED())
// libpng_handle = Sys_LoadLibrary("libpng", pngfuncs);
#endif #endif
return LIBPNG_LOADED(); return LIBPNG_LOADED();
} }
@ -2509,15 +2521,18 @@ qbyte *Read32BitImageFile(qbyte *buf, int len, int *width, int *height, qboolean
int i; int i;
if (w >= 4 && h >= 4 && w*h+sizeof(int)*2 == com_filesize) if (w >= 4 && h >= 4 && w*h+sizeof(int)*2 == com_filesize)
{ {
unsigned int *in = (unsigned int*)buf+2; qboolean foundalpha = false;
qbyte *in = (qbyte*)((int*)buf+2);
data = BZ_Malloc(w * h * sizeof(int)); data = BZ_Malloc(w * h * sizeof(int));
for (i = 0; i < w * h; i++) for (i = 0; i < w * h; i++)
{ {
if (in[i] == 255)
foundalpha = true;
((unsigned int*)data)[i] = d_8to24rgbtable[in[i]]; ((unsigned int*)data)[i] = d_8to24rgbtable[in[i]];
} }
*width = w; *width = w;
*height = h; *height = h;
*hasalpha = false; *hasalpha = foundalpha;
return data; return data;
} }
} }
@ -2629,6 +2644,72 @@ static struct
}; };
int image_width, image_height; int image_width, image_height;
qboolean R_LoadTextureFromMemory(texid_t *tex, int flags, char *iname, char *fname, qbyte *filedata, int filesize)
{
qboolean hasalpha;
qbyte *rgbadata;
//these formats have special handling, because they cannot be implemented via Read32BitImageFile - they don't result in rgba images.
#ifdef IMAGEFMT_DDS
*tex = GL_ReadTextureDDS(iname, filedata, filesize);
if (TEXVALID(*tex))
return true;
#endif
#ifdef IMAGEFMT_BLP
if (filedata[0] == 'B' && filedata[1] == 'L' && filedata[2] == 'P' && filedata[3] == '2')
{
*tex = GL_ReadBLPFile(iname, filedata, filesize);
if (TEXVALID(*tex))
return true;
}
#endif
hasalpha = false;
if ((rgbadata = Read32BitImageFile(filedata, filesize, &image_width, &image_height, &hasalpha, fname)))
{
extern cvar_t vid_hardwaregamma;
if (!(flags&IF_NOGAMMA) && !vid_hardwaregamma.value)
BoostGamma(rgbadata, image_width, image_height);
if (hasalpha)
flags &= ~IF_NOALPHA;
else if (!(flags & IF_NOALPHA))
{
unsigned int alpha_width, alpha_height, p;
char aname[MAX_QPATH];
unsigned char *alphadata;
char *alph;
COM_StripExtension(fname, aname, sizeof(aname));
Q_strncatz(aname, "_alpha", sizeof(aname));
Q_strncatz(aname, COM_FileExtension(fname), sizeof(aname));
if ((alph = COM_LoadFile (aname, 5)))
{
if ((alphadata = Read32BitImageFile(alph, filesize, &alpha_width, &alpha_height, &hasalpha, aname)))
{
if (alpha_width == image_width && alpha_height == image_height)
{
for (p = 0; p < alpha_width*alpha_height; p++)
{
rgbadata[(p<<2) + 3] = (alphadata[(p<<2) + 0] + alphadata[(p<<2) + 1] + alphadata[(p<<2) + 2])/3;
}
}
BZ_Free(alphadata);
}
BZ_Free(alph);
}
}
TRACE(("dbg: Mod_LoadHiResTexture: %s loaded\n", iname));
*tex = R_LoadTexture32 (iname, image_width, image_height, rgbadata, flags);
BZ_Free(rgbadata);
return true;
}
else
Con_Printf("Unable to read file %s (format unsupported)\n", fname);
return false;
}
texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags) texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags)
{ {
qboolean alphaed; qboolean alphaed;
@ -2636,7 +2717,7 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags)
unsigned char *data; unsigned char *data;
texid_t tex; texid_t tex;
// int h; // int h;
char fname[MAX_QPATH], nicename[MAX_QPATH]; char fname[MAX_QPATH], nicename[MAX_QPATH], iname[MAX_QPATH];
qboolean hasalpha; qboolean hasalpha;
int i, e; int i, e;
@ -2682,6 +2763,7 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags)
} }
} }
//cubemaps need special all-at-once handling or something, and is not individual textures.
if ((flags & IF_TEXTYPE) == IF_CUBEMAP) if ((flags & IF_TEXTYPE) == IF_CUBEMAP)
{ {
int j; int j;
@ -2809,85 +2891,17 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags)
TRACE(("dbg: Mod_LoadHiResTexture: trying %s\n", fname)); TRACE(("dbg: Mod_LoadHiResTexture: trying %s\n", fname));
if ((buf = COM_LoadFile (fname, 5))) if ((buf = COM_LoadFile (fname, 5)))
{ {
//these formats have special handling, because they cannot be implemented via Read32BitImageFile - they don't result in rgba images. if (tex_path[i].args >= 3)
#ifdef IMAGEFMT_DDS snprintf(iname, sizeof(iname)-1, "%s/%s", subpath, name); /*should be safe if its null*/
tex = GL_ReadTextureDDS(name, buf, com_filesize);
if (TEXVALID(tex))
{
BZ_Free(buf);
return tex;
}
#endif
#ifdef IMAGEFMT_BLP
if (buf[0] == 'B' && buf[1] == 'L' && buf[2] == 'P' && buf[3] == '2')
{
tex = GL_ReadBLPFile(name, buf, com_filesize);
if (TEXVALID(tex))
{
BZ_Free(buf);
return tex;
}
}
#endif
hasalpha = false;
if ((data = Read32BitImageFile(buf, com_filesize, &image_width, &image_height, &hasalpha, fname)))
{
extern cvar_t vid_hardwaregamma;
if (!(flags&IF_NOGAMMA) && !vid_hardwaregamma.value)
BoostGamma(data, image_width, image_height);
if (hasalpha)
flags &= ~IF_NOALPHA;
else if (!(flags & IF_NOALPHA))
{
unsigned int alpha_width, alpha_height, p;
char aname[MAX_QPATH];
unsigned char *alphadata;
char *alph;
if (tex_path[i].args >= 3)
snprintf(aname, sizeof(aname)-1, tex_path[i].path, subpath, nicename, va("_alpha%s", tex_extensions[e].name));
else
snprintf(aname, sizeof(aname)-1, tex_path[i].path, nicename, va("_alpha%s", tex_extensions[e].name));
if ((alph = COM_LoadFile (aname, 5)))
{
if ((alphadata = Read32BitImageFile(alph, com_filesize, &alpha_width, &alpha_height, &hasalpha, aname)))
{
if (alpha_width == image_width && alpha_height == image_height)
{
for (p = 0; p < alpha_width*alpha_height; p++)
{
data[(p<<2) + 3] = (alphadata[(p<<2) + 0] + alphadata[(p<<2) + 1] + alphadata[(p<<2) + 2])/3;
}
}
BZ_Free(alphadata);
}
BZ_Free(alph);
}
}
TRACE(("dbg: Mod_LoadHiResTexture: %s loaded\n", name));
if (tex_path[i].args >= 3)
{ //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);
tex = R_LoadTexture32 (fname, image_width, image_height, data, flags);
}
else
tex = R_LoadTexture32 (name, image_width, image_height, data, flags);
BZ_Free(data);
BZ_Free(buf);
return tex;
}
else else
snprintf(iname, sizeof(iname)-1, "%s", name); /*should be safe if its null*/
if (R_LoadTextureFromMemory(&tex, flags, iname, fname, buf, com_filesize))
{ {
Con_Printf("Unable to read file %s (format unsupported)\n", fname);
BZ_Free(buf); BZ_Free(buf);
continue; return tex;
} }
BZ_Free(buf);
} }
} }
} }
@ -2895,25 +2909,17 @@ texid_t R_LoadHiResTexture(char *name, char *subpath, unsigned int flags)
if (!(flags & IF_SUBDIRONLY)) if (!(flags & IF_SUBDIRONLY))
{ {
/*still failed? attempt to load quake lmp files, which have no real format id*/ /*still failed? attempt to load quake lmp files, which have no real format id*/
if (flags & IF_EXACTEXTENSION) Q_strncpyz(fname, name, sizeof(fname));
Q_strncpyz(fname, nicename, sizeof(fname)); COM_DefaultExtension(fname, ".lmp", sizeof(fname));
else
snprintf(fname, sizeof(fname)-1, "%s%s", nicename, ".lmp");
if ((buf = COM_LoadFile (fname, 5))) if ((buf = COM_LoadFile (fname, 5)))
{ {
extern cvar_t vid_hardwaregamma; if (R_LoadTextureFromMemory(&tex, flags, name, fname, buf, com_filesize))
TEXASSIGNF(tex, r_nulltex);
if (com_filesize >= 8)
{ {
image_width = LittleLong(((int*)buf)[0]); BZ_Free(buf);
image_height = LittleLong(((int*)buf)[1]); return tex;
if (image_width >= 4 && image_height >= 4 && image_width*image_height+8 == com_filesize)
{
tex = R_LoadTexture8(name, image_width, image_height, buf+8, flags, 1);
}
} }
BZ_Free(buf); BZ_Free(buf);
return tex; return r_nulltex;
} }
//now look in wad files. (halflife compatability) //now look in wad files. (halflife compatability)

View file

@ -10,8 +10,9 @@ static cvar_t m_accel = CVARF("m_accel", "0", CVAR_ARCHIVE);
static cvar_t m_forcewheel = CVARD("m_forcewheel", "1", "0: ignore mousewheels in apis where it is abiguous.\n1: Use mousewheel when it is treated as a third axis. Motion above a threshold is ignored, to avoid issues with an unknown threshold.\n2: Like 1, but excess motion is retained. The threshold specifies exact z-axis distance per notice."); static cvar_t m_forcewheel = CVARD("m_forcewheel", "1", "0: ignore mousewheels in apis where it is abiguous.\n1: Use mousewheel when it is treated as a third axis. Motion above a threshold is ignored, to avoid issues with an unknown threshold.\n2: Like 1, but excess motion is retained. The threshold specifies exact z-axis distance per notice.");
static cvar_t m_forcewheel_threshold = CVARD("m_forcewheel_threshold", "32", "Mousewheel graduations smaller than this will not trigger mousewheel deltas."); static cvar_t m_forcewheel_threshold = CVARD("m_forcewheel_threshold", "32", "Mousewheel graduations smaller than this will not trigger mousewheel deltas.");
static cvar_t m_strafeonright = CVARFD("m_strafeonright", "1", CVAR_ARCHIVE, "If 1, touching the right half of the touchscreen will strafe/move, while the left side will turn."); static cvar_t m_strafeonright = CVARFD("m_strafeonright", "1", CVAR_ARCHIVE, "If 1, touching the right half of the touchscreen will strafe/move, while the left side will turn.");
static cvar_t m_fatpressthreshold = CVARFD("m_fatpressthreshold", "0.5", CVAR_ARCHIVE, "How fat your thumb has to be to register a fat press (touchscreens)."); static cvar_t m_fatpressthreshold = CVARFD("m_fatpressthreshold", "0.2", CVAR_ARCHIVE, "How fat your thumb has to be to register a fat press (touchscreens).");
static cvar_t m_slidethreshold = CVARFD("m_slidethreshold", "5", CVAR_ARCHIVE, "How far your finger needs to move to be considered a slide event (touchscreens)."); static cvar_t m_touchmajoraxis = CVARFD("m_touchmajoraxis", "1", CVAR_ARCHIVE, "When using a touchscreen, use only the major axis for strafing.");
static cvar_t m_slidethreshold = CVARFD("m_slidethreshold", "10", CVAR_ARCHIVE, "How far your finger needs to move to be considered a slide event (touchscreens).");
extern cvar_t cl_forcesplitclient; //all devices claim to be a single player extern cvar_t cl_forcesplitclient; //all devices claim to be a single player
extern cvar_t _windowed_mouse; extern cvar_t _windowed_mouse;
@ -108,6 +109,7 @@ void IN_Init(void)
Cvar_Register (&m_strafeonright, "input controls"); Cvar_Register (&m_strafeonright, "input controls");
Cvar_Register (&m_fatpressthreshold, "input controls"); Cvar_Register (&m_fatpressthreshold, "input controls");
Cvar_Register (&m_slidethreshold, "input controls"); Cvar_Register (&m_slidethreshold, "input controls");
Cvar_Register (&m_touchmajoraxis, "input controls");
INS_Init(); INS_Init();
} }
@ -354,14 +356,27 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum)
//if they're strafing, calculate the speed to move at based upon their displacement //if they're strafing, calculate the speed to move at based upon their displacement
if (mouse->down) if (mouse->down)
{ {
mx = (mouse->oldpos[0] - mouse->downpos[0])*0.1; mx = mouse->oldpos[0] - (vid.pixelwidth*3)/4;
my = (mouse->oldpos[1] - mouse->downpos[1])*0.1; my = mouse->oldpos[1] - (vid.pixelheight*3)/4;
//mx = (mouse->oldpos[0] - mouse->downpos[0])*0.1;
//my = (mouse->oldpos[1] - mouse->downpos[1])*0.1;
} }
else else
{ {
mx = 0; mx = 0;
my = 0; my = 0;
} }
if (m_touchmajoraxis.ival)
{
//major axis only
if (fabs(mx) > fabs(my))
my = 0;
else
mx = 0;
}
strafe_x = true; strafe_x = true;
strafe_y = true; strafe_y = true;
} }
@ -369,6 +384,10 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum)
{ {
strafe_x = false; strafe_x = false;
strafe_y = false; strafe_y = false;
//boost sensitivity so that the default works okay.
mx *= 1.75;
my *= 1.75;
} }
} }
else else

View file

@ -2,19 +2,20 @@
#include <SDL.h> #include <SDL.h>
SDL_Surface *sdlsurf; #if SDL_MAJOR_VERSION >=2
SDL_Window *sdlwindow;
#else
extern SDL_Surface *sdlsurf;
#endif
qboolean ActiveApp; qboolean ActiveApp;
qboolean mouseactive; qboolean mouseactive;
extern qboolean mouseusedforgui; extern qboolean mouseusedforgui;
extern qboolean vid_isfullscreen; extern qboolean vid_isfullscreen;
#ifdef FTE_TARGET_WEB //theoretically generic, but the IME is probably going to be more annoying on systems where its actually implemented properly.
#if SDL_MAJOR_VERSION > 1 || (SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION >= 3) #if SDL_MAJOR_VERSION > 1 || (SDL_MAJOR_VERSION == 1 && SDL_MINOR_VERSION >= 3)
#define HAVE_SDL_TEXTINPUT #define HAVE_SDL_TEXTINPUT
#endif #endif
#endif
void IN_ActivateMouse(void) void IN_ActivateMouse(void)
{ {
@ -23,7 +24,13 @@ void IN_ActivateMouse(void)
mouseactive = true; mouseactive = true;
SDL_ShowCursor(0); SDL_ShowCursor(0);
#if SDL_MAJOR_VERSION >= 2
SDL_SetRelativeMouseMode(true);
SDL_SetWindowGrab(sdlwindow, true);
#else
SDL_WM_GrabInput(SDL_GRAB_ON); SDL_WM_GrabInput(SDL_GRAB_ON);
#endif
} }
void IN_DeactivateMouse(void) void IN_DeactivateMouse(void)
@ -33,9 +40,266 @@ void IN_DeactivateMouse(void)
mouseactive = false; mouseactive = false;
SDL_ShowCursor(1); SDL_ShowCursor(1);
#if SDL_MAJOR_VERSION >= 2
SDL_SetRelativeMouseMode(false);
SDL_SetWindowGrab(sdlwindow, false);
#else
SDL_WM_GrabInput(SDL_GRAB_OFF); SDL_WM_GrabInput(SDL_GRAB_OFF);
#endif
} }
#if SDL_MAJOR_VERSION >= 2
unsigned int MySDL_MapKey(unsigned int sdlkey)
{
switch(sdlkey)
{
default: return 0;
//any ascii chars can be mapped directly to keys, even if they're only ever accessed with shift etc... oh well.
case SDLK_RETURN: return K_ENTER;
case SDLK_ESCAPE: return K_ESCAPE;
case SDLK_BACKSPACE: return K_BACKSPACE;
case SDLK_TAB: return K_TAB;
case SDLK_SPACE: return K_SPACE;
case SDLK_EXCLAIM:
case SDLK_QUOTEDBL:
case SDLK_HASH:
case SDLK_PERCENT:
case SDLK_DOLLAR:
case SDLK_AMPERSAND:
case SDLK_QUOTE:
case SDLK_LEFTPAREN:
case SDLK_RIGHTPAREN:
case SDLK_ASTERISK:
case SDLK_PLUS:
case SDLK_COMMA:
case SDLK_MINUS:
case SDLK_PERIOD:
case SDLK_SLASH:
case SDLK_0:
case SDLK_1:
case SDLK_2:
case SDLK_3:
case SDLK_4:
case SDLK_5:
case SDLK_6:
case SDLK_7:
case SDLK_8:
case SDLK_9:
case SDLK_COLON:
case SDLK_SEMICOLON:
case SDLK_LESS:
case SDLK_EQUALS:
case SDLK_GREATER:
case SDLK_QUESTION:
case SDLK_AT:
case SDLK_LEFTBRACKET:
case SDLK_BACKSLASH:
case SDLK_RIGHTBRACKET:
case SDLK_CARET:
case SDLK_UNDERSCORE:
case SDLK_BACKQUOTE:
case SDLK_a:
case SDLK_b:
case SDLK_c:
case SDLK_d:
case SDLK_e:
case SDLK_f:
case SDLK_g:
case SDLK_h:
case SDLK_i:
case SDLK_j:
case SDLK_k:
case SDLK_l:
case SDLK_m:
case SDLK_n:
case SDLK_o:
case SDLK_p:
case SDLK_q:
case SDLK_r:
case SDLK_s:
case SDLK_t:
case SDLK_u:
case SDLK_v:
case SDLK_w:
case SDLK_x:
case SDLK_y:
case SDLK_z:
return sdlkey;
case SDLK_CAPSLOCK: return K_CAPSLOCK;
case SDLK_F1: return K_F1;
case SDLK_F2: return K_F2;
case SDLK_F3: return K_F3;
case SDLK_F4: return K_F4;
case SDLK_F5: return K_F5;
case SDLK_F6: return K_F6;
case SDLK_F7: return K_F7;
case SDLK_F8: return K_F8;
case SDLK_F9: return K_F9;
case SDLK_F10: return K_F10;
case SDLK_F11: return K_F11;
case SDLK_F12: return K_F12;
case SDLK_PRINTSCREEN: return K_PRINTSCREEN;
case SDLK_SCROLLLOCK: return K_SCRLCK;
case SDLK_PAUSE: return K_PAUSE;
case SDLK_INSERT: return K_INS;
case SDLK_HOME: return K_HOME;
case SDLK_PAGEUP: return K_PGUP;
case SDLK_DELETE: return K_DEL;
case SDLK_END: return K_END;
case SDLK_PAGEDOWN: return K_PGDN;
case SDLK_RIGHT: return K_RIGHTARROW;
case SDLK_LEFT: return K_LEFTARROW;
case SDLK_DOWN: return K_DOWNARROW;
case SDLK_UP: return K_UPARROW;
case SDLK_NUMLOCKCLEAR: return K_KP_NUMLOCK;
case SDLK_KP_DIVIDE: return K_KP_SLASH;
case SDLK_KP_MULTIPLY: return K_KP_STAR;
case SDLK_KP_MINUS: return K_KP_MINUS;
case SDLK_KP_PLUS: return K_KP_PLUS;
case SDLK_KP_ENTER: return K_KP_ENTER;
case SDLK_KP_1: return K_KP_END;
case SDLK_KP_2: return K_KP_DOWNARROW;
case SDLK_KP_3: return K_KP_PGDN;
case SDLK_KP_4: return K_KP_LEFTARROW;
case SDLK_KP_5: return K_KP_5;
case SDLK_KP_6: return K_KP_RIGHTARROW;
case SDLK_KP_7: return K_KP_HOME;
case SDLK_KP_8: return K_KP_UPARROW;
case SDLK_KP_9: return K_KP_PGDN;
case SDLK_KP_0: return K_KP_INS;
case SDLK_KP_PERIOD: return K_KP_DEL;
case SDLK_APPLICATION: return K_APP;
case SDLK_POWER: return K_POWER;
case SDLK_KP_EQUALS: return K_KP_EQUALS;
case SDLK_F13: return K_F13;
case SDLK_F14: return K_F14;
case SDLK_F15: return K_F15;
/*
case SDLK_F16: return K_;
case SDLK_F17: return K_;
case SDLK_F18: return K_;
case SDLK_F19: return K_;
case SDLK_F20: return K_;
case SDLK_F21: return K_;
case SDLK_F22: return K_;
case SDLK_F23: return K_;
case SDLK_F24: return K_;
case SDLK_EXECUTE: return K_;
case SDLK_HELP: return K_;
case SDLK_MENU: return K_;
case SDLK_SELECT: return K_;
case SDLK_STOP: return K_;
case SDLK_AGAIN: return K_;
case SDLK_UNDO: return K_;
case SDLK_CUT: return K_;
case SDLK_COPY: return K_;
case SDLK_PASTE: return K_;
case SDLK_FIND: return K_;
case SDLK_MUTE: return K_;
*/
case SDLK_VOLUMEUP: return K_VOLUP;
case SDLK_VOLUMEDOWN: return K_VOLDOWN;
/*
case SDLK_KP_COMMA: return K_;
case SDLK_KP_EQUALSAS400: return K_;
case SDLK_ALTERASE: return K_;
case SDLK_SYSREQ: return K_;
case SDLK_CANCEL: return K_;
case SDLK_CLEAR: return K_;
case SDLK_PRIOR: return K_;
case SDLK_RETURN2: return K_;
case SDLK_SEPARATOR: return K_;
case SDLK_OUT: return K_;
case SDLK_OPER: return K_;
case SDLK_CLEARAGAIN: return K_;
case SDLK_CRSEL: return K_;
case SDLK_EXSEL: return K_;
case SDLK_KP_00: return K_;
case SDLK_KP_000: return K_;
case SDLK_THOUSANDSSEPARATOR: return K_;
case SDLK_DECIMALSEPARATOR: return K_;
case SDLK_CURRENCYUNIT: return K_;
case SDLK_CURRENCYSUBUNIT: return K_;
case SDLK_KP_LEFTPAREN: return K_;
case SDLK_KP_RIGHTPAREN: return K_;
case SDLK_KP_LEFTBRACE: return K_;
case SDLK_KP_RIGHTBRACE: return K_;
case SDLK_KP_TAB: return K_;
case SDLK_KP_BACKSPACE: return K_;
case SDLK_KP_A: return K_;
case SDLK_KP_B: return K_;
case SDLK_KP_C: return K_;
case SDLK_KP_D: return K_;
case SDLK_KP_E: return K_;
case SDLK_KP_F: return K_;
case SDLK_KP_XOR: return K_;
case SDLK_KP_POWER: return K_;
case SDLK_KP_PERCENT: return K_;
case SDLK_KP_LESS: return K_;
case SDLK_KP_GREATER: return K_;
case SDLK_KP_AMPERSAND: return K_;
case SDLK_KP_DBLAMPERSAND: return K_;
case SDLK_KP_VERTICALBAR: return K_;
case SDLK_KP_DBLVERTICALBAR: return K_;
case SDLK_KP_COLON: return K_;
case SDLK_KP_HASH: return K_;
case SDLK_KP_SPACE: return K_;
case SDLK_KP_AT: return K_;
case SDLK_KP_EXCLAM: return K_;
case SDLK_KP_MEMSTORE: return K_;
case SDLK_KP_MEMRECALL: return K_;
case SDLK_KP_MEMCLEAR: return K_;
case SDLK_KP_MEMADD: return K_;
case SDLK_KP_MEMSUBTRACT: return K_;
case SDLK_KP_MEMMULTIPLY: return K_;
case SDLK_KP_MEMDIVIDE: return K_;
case SDLK_KP_PLUSMINUS: return K_;
case SDLK_KP_CLEAR: return K_;
case SDLK_KP_CLEARENTRY: return K_;
case SDLK_KP_BINARY: return K_;
case SDLK_KP_OCTAL: return K_;
case SDLK_KP_DECIMAL: return K_;
case SDLK_KP_HEXADECIMAL: return K_;
*/
case SDLK_LCTRL: return K_LCTRL;
case SDLK_LSHIFT: return K_LSHIFT;
case SDLK_LALT: return K_LALT;
case SDLK_LGUI: return K_APP;
case SDLK_RCTRL: return K_RCTRL;
case SDLK_RSHIFT: return K_RSHIFT;
case SDLK_RALT: return K_RALT;
/*
case SDLK_RGUI: return K_;
case SDLK_MODE: return K_;
case SDLK_AUDIONEXT: return K_;
case SDLK_AUDIOPREV: return K_;
case SDLK_AUDIOSTOP: return K_;
case SDLK_AUDIOPLAY: return K_;
case SDLK_AUDIOMUTE: return K_;
case SDLK_MEDIASELECT: return K_;
case SDLK_WWW: return K_;
case SDLK_MAIL: return K_;
case SDLK_CALCULATOR: return K_;
case SDLK_COMPUTER: return K_;
case SDLK_AC_SEARCH: return K_;
case SDLK_AC_HOME: return K_;
case SDLK_AC_BACK: return K_;
case SDLK_AC_FORWARD: return K_;
case SDLK_AC_STOP: return K_;
case SDLK_AC_REFRESH: return K_;
case SDLK_AC_BOOKMARKS: return K_;
case SDLK_BRIGHTNESSDOWN: return K_;
case SDLK_BRIGHTNESSUP: return K_;
case SDLK_DISPLAYSWITCH: return K_;
case SDLK_KBDILLUMTOGGLE: return K_;
case SDLK_KBDILLUMDOWN: return K_;
case SDLK_KBDILLUMUP: return K_;
case SDLK_EJECT: return K_;
case SDLK_SLEEP: return K_;
*/
}
}
#else
#define tenoh 0,0,0,0,0, 0,0,0,0,0 #define tenoh 0,0,0,0,0, 0,0,0,0,0
#define fiftyoh tenoh, tenoh, tenoh, tenoh, tenoh #define fiftyoh tenoh, tenoh, tenoh, tenoh, tenoh
#define hundredoh fiftyoh, fiftyoh #define hundredoh fiftyoh, fiftyoh
@ -188,6 +452,7 @@ static unsigned int tbl_sdltoquake[] =
'e', //SDLK_EURO = 321, /* Some european keyboards */ 'e', //SDLK_EURO = 321, /* Some european keyboards */
0 //SDLK_UNDO = 322, /* Atari keyboard has Undo */ 0 //SDLK_UNDO = 322, /* Atari keyboard has Undo */
}; };
#endif
static unsigned int tbl_sdltoquakemouse[] = static unsigned int tbl_sdltoquakemouse[] =
{ {
@ -212,6 +477,37 @@ void Sys_SendKeyEvents(void)
{ {
switch(event.type) switch(event.type)
{ {
#if SDL_MAJOR_VERSION >= 2
case SDL_WINDOWEVENT:
switch(event.window.event)
{
default:
break;
case SDL_WINDOWEVENT_SIZE_CHANGED:
#if SDL_PATCHLEVEL >= 1
SDL_GL_GetDrawableSize(sdlwindow, &vid.pixelwidth, &vid.pixelheight); //get the proper physical size.
#else
SDL_GetWindowSize(sdlwindow, &vid.pixelwidth, &vid.pixelheight);
#endif
{
extern cvar_t vid_conautoscale, vid_conwidth; //make sure the screen is updated properly.
Cvar_ForceCallback(&vid_conautoscale);
Cvar_ForceCallback(&vid_conwidth);
}
break;
case SDL_WINDOWEVENT_FOCUS_GAINED:
ActiveApp = true;
break;
case SDL_WINDOWEVENT_FOCUS_LOST:
ActiveApp = false;
break;
case SDL_WINDOWEVENT_CLOSE:
Cbuf_AddText("quit prompt\n", RESTRICT_LOCAL);
break;
}
break;
#else
case SDL_ACTIVEEVENT: case SDL_ACTIVEEVENT:
if (event.active.state & SDL_APPINPUTFOCUS) if (event.active.state & SDL_APPINPUTFOCUS)
{ //follow keyboard status { //follow keyboard status
@ -231,17 +527,21 @@ void Sys_SendKeyEvents(void)
} }
#endif #endif
break; break;
#endif
case SDL_KEYUP: case SDL_KEYUP:
case SDL_KEYDOWN: case SDL_KEYDOWN:
{ {
int u = event.key.keysym.unicode;
int s = event.key.keysym.sym; int s = event.key.keysym.sym;
int qs; int qs;
#if SDL_MAJOR_VERSION >= 2
qs = MySDL_MapKey(s);
#else
if (s < sizeof(tbl_sdltoquake) / sizeof(tbl_sdltoquake[0])) if (s < sizeof(tbl_sdltoquake) / sizeof(tbl_sdltoquake[0]))
qs = tbl_sdltoquake[s]; qs = tbl_sdltoquake[s];
else else
qs = 0; qs = 0;
#endif
#ifdef FTE_TARGET_WEB #ifdef FTE_TARGET_WEB
if (s == 1249) if (s == 1249)
@ -250,14 +550,13 @@ void Sys_SendKeyEvents(void)
#ifdef HAVE_SDL_TEXTINPUT #ifdef HAVE_SDL_TEXTINPUT
IN_KeyEvent(0, event.key.state, qs, 0); IN_KeyEvent(0, event.key.state, qs, 0);
#else #else
IN_KeyEvent(0, event.key.state, qs, u); IN_KeyEvent(0, event.key.state, qs, event.key.keysym.unicode);
#endif #endif
} }
break; break;
#ifdef HAVE_SDL_TEXTINPUT #ifdef HAVE_SDL_TEXTINPUT
case SDL_TEXTINPUT: case SDL_TEXTINPUT:
{ {
int i;
unsigned int uc; unsigned int uc;
int err; int err;
char *text = event.text.text; char *text = event.text.text;
@ -274,23 +573,50 @@ void Sys_SendKeyEvents(void)
break; break;
#endif #endif
#if SDL_MAJOR_VERSION >= 2
case SDL_FINGERDOWN:
case SDL_FINGERUP:
IN_MouseMove(event.tfinger.fingerId, true, event.tfinger.x * vid.pixelwidth, event.tfinger.y * vid.pixelheight, 0, event.tfinger.pressure);
IN_KeyEvent(event.tfinger.fingerId, event.type==SDL_FINGERDOWN, K_MOUSE1, 0);
break;
case SDL_FINGERMOTION:
IN_MouseMove(event.tfinger.fingerId, true, event.tfinger.x * vid.pixelwidth, event.tfinger.y * vid.pixelheight, 0, event.tfinger.pressure);
break;
case SDL_DROPFILE:
Host_RunFile(event.drop.file, strlen(event.drop.file), NULL);
SDL_free(event.drop.file);
break;
#endif
case SDL_MOUSEMOTION: case SDL_MOUSEMOTION:
#if SDL_MAJOR_VERSION >= 2
if (event.motion.which == SDL_TOUCH_MOUSEID)
break; //ignore legacy touch events.
#endif
if (!mouseactive) if (!mouseactive)
IN_MouseMove(0, true, event.motion.x, event.motion.y, 0, 0); IN_MouseMove(event.motion.which, true, event.motion.x, event.motion.y, 0, 0);
else else
IN_MouseMove(0, false, event.motion.xrel, event.motion.yrel, 0, 0); IN_MouseMove(event.motion.which, false, event.motion.xrel, event.motion.yrel, 0, 0);
break; break;
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONUP:
//Hmm. SDL allows for 255 buttons... #if SDL_MAJOR_VERSION >= 2
if (event.button.which == SDL_TOUCH_MOUSEID)
break; //ignore legacy touch events.
#endif
//Hmm. SDL allows for 255 buttons, but only defines 5...
if (event.button.button > sizeof(tbl_sdltoquakemouse)/sizeof(tbl_sdltoquakemouse[0])) if (event.button.button > sizeof(tbl_sdltoquakemouse)/sizeof(tbl_sdltoquakemouse[0]))
event.button.button = sizeof(tbl_sdltoquakemouse)/sizeof(tbl_sdltoquakemouse[0]); event.button.button = sizeof(tbl_sdltoquakemouse)/sizeof(tbl_sdltoquakemouse[0]);
IN_KeyEvent(0, event.button.state, tbl_sdltoquakemouse[event.button.button-1], 0); IN_KeyEvent(event.button.which, event.button.state, tbl_sdltoquakemouse[event.button.button-1], 0);
break; break;
case SDL_APP_TERMINATING:
Cbuf_AddText("quit force\n", RESTRICT_LOCAL);
break;
case SDL_QUIT: case SDL_QUIT:
Cbuf_AddText("quit", RESTRICT_LOCAL); Cbuf_AddText("quit\n", RESTRICT_LOCAL);
break; break;
} }
} }
@ -315,6 +641,9 @@ void INS_ReInit (void)
#else #else
SDL_EnableUNICODE(SDL_ENABLE); SDL_EnableUNICODE(SDL_ENABLE);
#endif #endif
#if SDL_MAJOR_VERSION >= 2
SDL_EventState(SDL_DROPFILE, SDL_ENABLE);
#endif
} }
//stubs, all the work is done in Sys_SendKeyEvents //stubs, all the work is done in Sys_SendKeyEvents

View file

@ -701,7 +701,7 @@ void M_Media_Draw (void)
char compleatenamepath[MAX_OSPATH]; char compleatenamepath[MAX_OSPATH];
char compleatenamename[MAX_OSPATH]; char compleatenamename[MAX_OSPATH];
qboolean compleatenamemultiple; qboolean compleatenamemultiple;
int QDECL Com_CompleatenameCallback(const char *name, int size, void *data, searchpathfuncs_t *spath) int QDECL Com_CompleatenameCallback(const char *name, qofs_t size, void *data, searchpathfuncs_t *spath)
{ {
if (*compleatenamename) if (*compleatenamename)
compleatenamemultiple = true; compleatenamemultiple = true;
@ -1480,7 +1480,7 @@ cin_t *Media_WinAvi_TryLoad(char *name)
FS_FLocateFile(name, FSLFRT_DEPTH_OSONLY, &loc); FS_FLocateFile(name, FSLFRT_DEPTH_OSONLY, &loc);
if (!loc.offset && !qAVIFileOpenA(&pavi, loc.rawname, OF_READ, NULL))//!AVIStreamOpenFromFile(&pavi, name, streamtypeVIDEO, 0, OF_READ, NULL)) if (!loc.offset && *loc.rawname && !qAVIFileOpenA(&pavi, loc.rawname, OF_READ, NULL))//!AVIStreamOpenFromFile(&pavi, name, streamtypeVIDEO, 0, OF_READ, NULL))
{ {
int filmwidth; int filmwidth;
int filmheight; int filmheight;

View file

@ -188,7 +188,7 @@ typedef struct {
int match; int match;
} q2skinsearch_t; } q2skinsearch_t;
int QDECL q2skin_enumerate(const char *name, int fsize, void *parm, searchpathfuncs_t *spath) int QDECL q2skin_enumerate(const char *name, qofs_t fsize, void *parm, searchpathfuncs_t *spath)
{ {
char blah[MAX_QPATH]; char blah[MAX_QPATH];
q2skinsearch_t *s = parm; q2skinsearch_t *s = parm;

View file

@ -369,7 +369,7 @@ void M_Menu_Audio_f (void)
MB_SPACING(8), MB_SPACING(8),
MB_CONSOLECMD("Restart Sound", "snd_restart\n", "Restart audio systems and apply set options."), MB_CONSOLECMD("Restart Sound", "snd_restart\n", "Restart audio systems and apply set options."),
MB_SPACING(4), MB_SPACING(4),
MB_COMBOCVAR("Output Device", snd_device, info->outdevdescs, info->outdevnames, NULL), MB_COMBOCVAR("Output Device", snd_device, (const char**)info->outdevdescs, (const char**)info->outdevnames, NULL),
MB_SLIDER("Volume", volume, 0, 1, 0.1, NULL), MB_SLIDER("Volume", volume, 0, 1, 0.1, NULL),
MB_COMBOCVAR("Speaker Setup", snd_speakers, speakeroptions, speakervalues, NULL), MB_COMBOCVAR("Speaker Setup", snd_speakers, speakeroptions, speakervalues, NULL),
MB_COMBOCVAR("Frequency", snd_khz, soundqualityoptions, soundqualityvalues, NULL), MB_COMBOCVAR("Frequency", snd_khz, soundqualityoptions, soundqualityvalues, NULL),
@ -394,7 +394,7 @@ void M_Menu_Audio_f (void)
#ifdef VOICECHAT #ifdef VOICECHAT
MB_REDTEXT("Voice Options", false), MB_REDTEXT("Voice Options", false),
MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false), MB_TEXT("\x80\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x81\x82", false),
MB_COMBOCVAR("Microphone Device", snd_voip_capturedevice, info->capdevdescs, info->capdevnames, NULL), MB_COMBOCVAR("Microphone Device", snd_voip_capturedevice, (const char**)info->capdevdescs, (const char**)info->capdevnames, NULL),
MB_SLIDER("Voice Volume", snd_voip_play, 0, 2, 0.1, NULL), MB_SLIDER("Voice Volume", snd_voip_play, 0, 2, 0.1, NULL),
MB_CHECKBOXCVAR("Microphone Test", snd_voip_test, 0), MB_CHECKBOXCVAR("Microphone Test", snd_voip_test, 0),
MB_SLIDER("Microphone Volume", snd_voip_micamp, 0, 2, 0.1, NULL), MB_SLIDER("Microphone Volume", snd_voip_micamp, 0, 2, 0.1, NULL),
@ -547,7 +547,7 @@ const char *presetexec[] =
"r_shadow_realtime_dlight 0;" "r_shadow_realtime_dlight 0;"
"r_shadow_realtime_world 0;" "r_shadow_realtime_world 0;"
"r_glsl_offsetmapping 0;" "r_glsl_offsetmapping 0;"
"gl_detail 0;" // "gl_detail 0;"
"gl_load24bit 0;" "gl_load24bit 0;"
"r_replacemodels \"\";" "r_replacemodels \"\";"
"r_waterwarp 0;" "r_waterwarp 0;"
@ -595,7 +595,7 @@ const char *presetexec[] =
"gl_texturemode ll;" "gl_texturemode ll;"
#ifndef MINIMAL #ifndef MINIMAL
"r_particlesystem script;" "r_particlesystem script;"
"r_particledesc \"spikeset tsshaft\";" "r_particledesc \"high tsshaft\";"
#endif #endif
"gl_specular 1;" "gl_specular 1;"
"r_loadlit 2;" "r_loadlit 2;"
@ -603,7 +603,7 @@ const char *presetexec[] =
"gl_blendsprites 1;" "gl_blendsprites 1;"
// "r_fastsky -1;" // "r_fastsky -1;"
"r_shadow_realtime_dlight 1;" "r_shadow_realtime_dlight 1;"
"gl_detail 1;" // "gl_detail 1;"
"r_lightstylesmooth 1;" "r_lightstylesmooth 1;"
"gl_texture_anisotropic_filtering 4;" "gl_texture_anisotropic_filtering 4;"
@ -898,7 +898,7 @@ void M_Menu_Textures_f (void)
MB_SPACING(4), MB_SPACING(4),
MB_CHECKBOXCVAR("Deluxemapping", r_deluxemapping, 0), MB_CHECKBOXCVAR("Deluxemapping", r_deluxemapping, 0),
MB_CHECKBOXCVAR("Specular Highlights", gl_specular, 0), MB_CHECKBOXCVAR("Specular Highlights", gl_specular, 0),
MB_CHECKBOXCVAR("Detail Textures", gl_detail, 0), // MB_CHECKBOXCVAR("Detail Textures", gl_detail, 0),
MB_CHECKBOXCVAR("offsetmapping", r_glsl_offsetmapping, 0), MB_CHECKBOXCVAR("offsetmapping", r_glsl_offsetmapping, 0),
MB_SPACING(4), MB_SPACING(4),
MB_CHECKBOXCVAR("Texture Compression", gl_compress, 0), // merge the save compressed tex options into here? MB_CHECKBOXCVAR("Texture Compression", gl_compress, 0), // merge the save compressed tex options into here?
@ -2329,7 +2329,7 @@ void M_Menu_Video_f (void)
"Wait for Display Enable", "Wait for Display Enable",
NULL NULL
}; };
extern cvar_t _vid_wait_override; extern cvar_t vid_vsync;
*/ */
videomenuinfo_t *info; videomenuinfo_t *info;
static char current3dres[32]; // enough to fit 1920x1200 static char current3dres[32]; // enough to fit 1920x1200
@ -2429,7 +2429,7 @@ void M_Menu_Video_f (void)
y+=4;info->customwidth = MC_AddEdit(menu, 16, y, " Custom width", vid_width.string); y+=8; y+=4;info->customwidth = MC_AddEdit(menu, 16, y, " Custom width", vid_width.string); y+=8;
y+=4;info->customheight = MC_AddEdit(menu, 16, y, " Custom height", vid_height.string); y+=12; y+=4;info->customheight = MC_AddEdit(menu, 16, y, " Custom height", vid_height.string); y+=12;
info->vsynccombo = MC_AddCombo(menu, 16, y, " VSync", vsyncoptions, currentvsync); y+=8; info->vsynccombo = MC_AddCombo(menu, 16, y, " VSync", vsyncoptions, currentvsync); y+=8;
//MC_AddCheckBox(menu, 16, y, " Override VSync", &_vid_wait_override,0); y+=8; //MC_AddCheckBox(menu, 16, y, " Override VSync", &vid_vsync,0); y+=8;
MC_AddCheckBox(menu, 16, y, " Desktop Settings", &vid_desktopsettings,0); y+=8; MC_AddCheckBox(menu, 16, y, " Desktop Settings", &vid_desktopsettings,0); y+=8;
y+=8; y+=8;
MC_AddCommand(menu, 16, y, "= Apply Changes =", M_VideoApply); y+=8; MC_AddCommand(menu, 16, y, "= Apply Changes =", M_VideoApply); y+=8;

View file

@ -500,7 +500,7 @@ static qboolean M_DemoKey(menucustom_t *control, menu_t *menu, int key)
return false; return false;
} }
static int QDECL DemoAddItem(const char *filename, int size, void *parm, searchpathfuncs_t *spath) static int QDECL DemoAddItem(const char *filename, qofs_t size, void *parm, searchpathfuncs_t *spath)
{ {
int extnum; int extnum;
demomenu_t *menu = parm; demomenu_t *menu = parm;

View file

@ -914,6 +914,7 @@ void M_Menu_Quit_f (void)
break; break;
case 2: case 2:
Key_Dest_Add(kdm_menu); Key_Dest_Add(kdm_menu);
Key_Dest_Remove(kdm_console);
m_state = m_complex; m_state = m_complex;
quitmenu = M_CreateMenuInfront(0); quitmenu = M_CreateMenuInfront(0);
@ -932,6 +933,7 @@ void M_Menu_Quit_f (void)
break; break;
case 1: case 1:
Key_Dest_Add(kdm_menu); Key_Dest_Add(kdm_menu);
Key_Dest_Remove(kdm_console);
m_state = m_complex; m_state = m_complex;
quitmenu = M_CreateMenuInfront(0); quitmenu = M_CreateMenuInfront(0);

View file

@ -256,10 +256,17 @@ typedef enum uploadfmt
TF_H2_TRANS8_0, /*8bit data, 0 is transparent, not 255*/ TF_H2_TRANS8_0, /*8bit data, 0 is transparent, not 255*/
TF_H2_T4A4, /*8bit data, weird packing*/ TF_H2_T4A4, /*8bit data, weird packing*/
/*anything below requires a palette*/ /*this block requires a palette*/
TF_PALETTES, TF_PALETTES,
TF_8PAL24, TF_8PAL24,
TF_8PAL32 TF_8PAL32,
/*for render targets*/
TF_DEPTH16,
TF_DEPTH24,
TF_DEPTH32,
TF_RGBA16F,
TF_RGBA32F
} uploadfmt_t; } uploadfmt_t;
//not all modes accept meshes - STENCIL(intentional) and DEPTHONLY(not implemented) //not all modes accept meshes - STENCIL(intentional) and DEPTHONLY(not implemented)
@ -369,3 +376,7 @@ typedef struct rendererinfo_s {
#define BE_VBO_Finish rf->BE_VBO_Finish #define BE_VBO_Finish rf->BE_VBO_Finish
#define BE_VBO_Destroy rf->BE_VBO_Destroy #define BE_VBO_Destroy rf->BE_VBO_Destroy
#define BE_Scissor rf->BE_Scissor #define BE_Scissor rf->BE_Scissor
texid_t R2D_RT_Configure(unsigned int id, int width, int height, uploadfmt_t rtfmt);
texid_t R2D_RT_GetTexture(unsigned int id, unsigned int *width, unsigned int *height);

View file

@ -902,17 +902,18 @@ void NET_SendPollPacket(int len, void *data, netadr_t to)
if (ret == -1) if (ret == -1)
{ {
int er = neterrno();
// wouldblock is silent // wouldblock is silent
if (qerrno == EWOULDBLOCK) if (er == NET_EWOULDBLOCK)
return; return;
if (qerrno == ECONNREFUSED) if (er == NET_ECONNREFUSED)
return; return;
if (qerrno == EADDRNOTAVAIL) if (er == NET_EADDRNOTAVAIL)
Con_DPrintf("NET_SendPollPacket Warning: %i\n", qerrno); Con_DPrintf("NET_SendPollPacket Warning: %i\n", er);
else else
Con_Printf ("NET_SendPollPacket ERROR: %i\n", qerrno); Con_Printf ("NET_SendPollPacket ERROR: %i\n", er);
} }
} }
@ -937,23 +938,24 @@ int Master_CheckPollSockets(void)
if (ret == -1) if (ret == -1)
{ {
if (qerrno == EWOULDBLOCK) int e = neterrno();
if (e == NET_EWOULDBLOCK)
continue; continue;
if (qerrno == EMSGSIZE) if (e == NET_EMSGSIZE)
{ {
SockadrToNetadr (&from, &net_from); SockadrToNetadr (&from, &net_from);
Con_Printf ("Warning: Oversize packet from %s\n", Con_Printf ("Warning: Oversize packet from %s\n",
NET_AdrToString (adr, sizeof(adr), &net_from)); NET_AdrToString (adr, sizeof(adr), &net_from));
continue; continue;
} }
if (qerrno == ECONNABORTED || qerrno == ECONNRESET) if (e == NET_ECONNABORTED || e == NET_ECONNRESET)
{ {
// Con_Printf ("Connection lost or aborted\n"); // Con_Printf ("Connection lost or aborted\n");
continue; continue;
} }
Con_Printf ("NET_CheckPollSockets: %i, %s\n", qerrno, strerror(qerrno)); Con_Printf ("NET_CheckPollSockets: %i, %s\n", e, strerror(e));
continue; continue;
} }
SockadrToNetadr (&from, &net_from); SockadrToNetadr (&from, &net_from);

View file

@ -1432,7 +1432,7 @@ static void QCBUILTIN PF_R_SetViewFlag(pubprogfuncs_t *prinst, struct globalvars
case VF_VIEWENTITY: case VF_VIEWENTITY:
//switches over EXTERNALMODEL flags and clears WEAPONMODEL flagged entities. //switches over EXTERNALMODEL flags and clears WEAPONMODEL flagged entities.
//FIXME: make affect addentities(MASK_ENGINE) calls too. //FIXME: make affect addentities(MASK_ENGINE) calls too.
CL_EditExternalModels(*p); CL_EditExternalModels(*p, NULL, 0);
break; break;
case VF_FOV: case VF_FOV:
//explicit fov overrides aproximate fov //explicit fov overrides aproximate fov
@ -1543,6 +1543,47 @@ static void QCBUILTIN PF_R_SetViewFlag(pubprogfuncs_t *prinst, struct globalvars
r_refdef.useperspective = *p; r_refdef.useperspective = *p;
break; break;
case VF_RT_DESTCOLOUR:
if (prinst->callargc >= 4)
{
float fmt = G_FLOAT(OFS_PARM2);
float *size = G_VECTOR(OFS_PARM3);
R2D_RT_Configure(*p, size[0], size[1], fmt);
}
r_refdef.rt_destcolour = *p;
GLBE_RenderToTextureUpdate2d(true);
break;
case VF_RT_SOURCECOLOUR:
if (prinst->callargc >= 4)
{
float fmt = G_FLOAT(OFS_PARM2);
float *size = G_VECTOR(OFS_PARM3);
R2D_RT_Configure(*p, size[0], size[1], fmt);
}
r_refdef.rt_sourcecolour = *p;
GLBE_RenderToTextureUpdate2d(false);
break;
case VF_RT_DEPTH:
if (prinst->callargc >= 4)
{
float fmt = G_FLOAT(OFS_PARM2);
float *size = G_VECTOR(OFS_PARM3);
R2D_RT_Configure(*p, size[0], size[1], fmt);
}
r_refdef.rt_depth = *p;
GLBE_RenderToTextureUpdate2d(false);
break;
case VF_RT_RIPPLE:
if (prinst->callargc >= 4)
{
float fmt = G_FLOAT(OFS_PARM2);
float *size = G_VECTOR(OFS_PARM3);
R2D_RT_Configure(*p, size[0], size[1], fmt);
}
r_refdef.rt_ripplemap = *p;
GLBE_RenderToTextureUpdate2d(false);
break;
default: default:
Con_DPrintf("SetViewFlag: %i not recognised\n", parametertype); Con_DPrintf("SetViewFlag: %i not recognised\n", parametertype);
G_FLOAT(OFS_RETURN) = 0; G_FLOAT(OFS_RETURN) = 0;
@ -1566,10 +1607,10 @@ static void QCBUILTIN PF_R_RenderScene(pubprogfuncs_t *prinst, struct globalvars
{ {
srect_t srect; srect_t srect;
srect.x = (float)r_refdef.grect.x / vid.width; srect.x = (float)r_refdef.grect.x / vid.fbvwidth;
srect.y = (float)r_refdef.grect.y / vid.height; srect.y = (float)r_refdef.grect.y / vid.fbvheight;
srect.width = (float)r_refdef.grect.width / vid.width; srect.width = (float)r_refdef.grect.width / vid.fbvwidth;
srect.height = (float)r_refdef.grect.height / vid.height; srect.height = (float)r_refdef.grect.height / vid.fbvheight;
srect.dmin = -99999; srect.dmin = -99999;
srect.dmax = 99999; srect.dmax = 99999;
srect.y = (1-srect.y) - srect.height; srect.y = (1-srect.y) - srect.height;
@ -3982,7 +4023,7 @@ static void QCBUILTIN PF_getentity(pubprogfuncs_t *prinst, struct globalvars_s *
if (entnum >= cl.maxlerpents || !cl.lerpentssequence || cl.lerpents[entnum].sequence != cl.lerpentssequence) if (entnum >= cl.maxlerpents || !cl.lerpentssequence || cl.lerpents[entnum].sequence != cl.lerpentssequence)
{ {
Con_Printf("PF_getentity: entity %i is not valid\n", fldnum); Con_DPrintf("PF_getentity: entity %i is not valid\n", entnum);
VectorCopy(vec3_origin, G_VECTOR(OFS_RETURN)); VectorCopy(vec3_origin, G_VECTOR(OFS_RETURN));
return; return;
} }
@ -4494,6 +4535,7 @@ static struct {
{"hash_getkey", PF_hash_getkey, 292}, {"hash_getkey", PF_hash_getkey, 292},
{"hash_getcb", PF_hash_getcb, 293}, {"hash_getcb", PF_hash_getcb, 293},
{"checkcommand", PF_checkcommand, 294}, {"checkcommand", PF_checkcommand, 294},
{"argescape", PF_argescape, 295},
//300 //300
{"clearscene", PF_R_ClearScene, 300}, // #300 void() clearscene (EXT_CSQC) {"clearscene", PF_R_ClearScene, 300}, // #300 void() clearscene (EXT_CSQC)
{"addentities", PF_R_AddEntityMask, 301}, // #301 void(float mask) addentities (EXT_CSQC) {"addentities", PF_R_AddEntityMask, 301}, // #301 void(float mask) addentities (EXT_CSQC)
@ -4808,6 +4850,12 @@ static struct {
{"soundlength", PF_soundlength, 534}, {"soundlength", PF_soundlength, 534},
{"buf_loadfile", PF_buf_loadfile, 535}, {"buf_loadfile", PF_buf_loadfile, 535},
{"buf_writefile", PF_buf_writefile, 536}, {"buf_writefile", PF_buf_writefile, 536},
// {"bufstr_find", PF_Fixme, 537},
// {"matchpattern", PF_Fixme, 538},
// {"undefined", PF_Fixme, 539},
{"physics_enable", PF_physics_enable, 540},
{"physics_addforce", PF_physics_addforce, 541},
{"physics_addtorque", PF_physics_addtorque, 542},
{"setmousetarget", PF_cl_setmousetarget, 603}, {"setmousetarget", PF_cl_setmousetarget, 603},
{"getmousetarget", PF_cl_getmousetarget, 604}, {"getmousetarget", PF_cl_getmousetarget, 604},

View file

@ -439,7 +439,14 @@ void QCBUILTIN PF_CL_drawpic (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
p = R2D_SafeCachePic(picname); p = R2D_SafeCachePic(picname);
if (!p) if (!p)
p = R2D_SafePicFromWad(picname); p = R2D_SafePicFromWad(picname);
G_FLOAT(OFS_RETURN) = !!p;
if (!p)
{
if (!CL_IsDownloading(picname))
p = R2D_SafeCachePic("no_texture");
}
else
G_FLOAT(OFS_RETURN) = 0;
r2d_be_flags = PF_SelectDPDrawFlag(flag); r2d_be_flags = PF_SelectDPDrawFlag(flag);
R2D_ImageColours(rgb[0], rgb[1], rgb[2], alpha); R2D_ImageColours(rgb[0], rgb[1], rgb[2], alpha);

View file

@ -318,7 +318,7 @@ static dollcreatectx_t *rag_createdoll(model_t *mod, char *fname, int numbones)
memset(&ctx->defbody, 0, sizeof(ctx->defbody)); memset(&ctx->defbody, 0, sizeof(ctx->defbody));
ctx->defbody.animate = true; ctx->defbody.animate = true;
ctx->defbody.shape = SOLID_PHYSICS_BOX; ctx->defbody.geomshape = GEOMTYPE_BOX;
ctx->defbody.dimensions[0] = 4; ctx->defbody.dimensions[0] = 4;
ctx->defbody.dimensions[1] = 4; ctx->defbody.dimensions[1] = 4;
ctx->defbody.dimensions[2] = 4; ctx->defbody.dimensions[2] = 4;
@ -458,13 +458,13 @@ static qboolean rag_dollline(dollcreatectx_t *ctx, int linenum)
else if (ctx->body && argc == 2 && !stricmp(cmd, "shape")) else if (ctx->body && argc == 2 && !stricmp(cmd, "shape"))
{ {
if (!stricmp(val, "box")) if (!stricmp(val, "box"))
ctx->body->shape = SOLID_PHYSICS_BOX; ctx->body->geomshape = GEOMTYPE_BOX;
else if (!stricmp(val, "sphere")) else if (!stricmp(val, "sphere"))
ctx->body->shape = SOLID_PHYSICS_SPHERE; ctx->body->geomshape = GEOMTYPE_SPHERE;
else if (!stricmp(val, "cylinder")) else if (!stricmp(val, "cylinder"))
ctx->body->shape = SOLID_PHYSICS_CYLINDER; ctx->body->geomshape = GEOMTYPE_CYLINDER;
else if (!stricmp(val, "capsule")) else if (!stricmp(val, "capsule"))
ctx->body->shape = SOLID_PHYSICS_CAPSULE; ctx->body->geomshape = GEOMTYPE_CAPSULE;
else if (!ctx->errors++) else if (!ctx->errors++)
Con_Printf("^[Joint shape \"%s\" not recognised\\edit\\%s %i^]\n", val, d->name, linenum); Con_Printf("^[Joint shape \"%s\" not recognised\\edit\\%s %i^]\n", val, d->name, linenum);
} }
@ -1259,23 +1259,23 @@ void rag_derive(skelobject_t *sko, skelobject_t *asko, float *emat)
World_ODE_RagMatrixFromBody(sko->world, &sko->body[i].odebody, bodymat); World_ODE_RagMatrixFromBody(sko->world, &sko->body[i].odebody, bodymat);
switch(doll->body[i].shape) switch(doll->body[i].geomshape)
{ {
default: default:
case SOLID_PHYSICS_BOX: case GEOMTYPE_BOX:
VectorScale(doll->body[i].dimensions, -0.5, mins); VectorScale(doll->body[i].dimensions, -0.5, mins);
VectorScale(doll->body[i].dimensions, 0.5, maxs); VectorScale(doll->body[i].dimensions, 0.5, maxs);
CLQ1_AddOrientedCube(debugshader, mins, maxs, bodymat, 0.2, 0.2, 0.2, 1); CLQ1_AddOrientedCube(debugshader, mins, maxs, bodymat, 0.2, 0.2, 0.2, 1);
break; break;
case SOLID_PHYSICS_CYLINDER: case GEOMTYPE_CYLINDER:
rad = (doll->body[i].dimensions[0] + doll->body[i].dimensions[1])*0.5; rad = (doll->body[i].dimensions[0] + doll->body[i].dimensions[1])*0.5;
CLQ1_AddOrientedCylinder(debugshader, rad, doll->body[i].dimensions[2], false, bodymat, 0.2, 0.2, 0.2, 1); CLQ1_AddOrientedCylinder(debugshader, rad, doll->body[i].dimensions[2], false, bodymat, 0.2, 0.2, 0.2, 1);
break; break;
case SOLID_PHYSICS_CAPSULE: case GEOMTYPE_CAPSULE:
rad = (doll->body[i].dimensions[0] + doll->body[i].dimensions[1])*0.5; rad = (doll->body[i].dimensions[0] + doll->body[i].dimensions[1])*0.5;
CLQ1_AddOrientedCylinder(debugshader, rad, doll->body[i].dimensions[2], true, bodymat, 0.2, 0.2, 0.2, 1); CLQ1_AddOrientedCylinder(debugshader, rad, doll->body[i].dimensions[2], true, bodymat, 0.2, 0.2, 0.2, 1);
break; break;
case SOLID_PHYSICS_SPHERE: case GEOMTYPE_SPHERE:
rad = (doll->body[i].dimensions[0] + doll->body[i].dimensions[1] + doll->body[i].dimensions[2])/3; rad = (doll->body[i].dimensions[0] + doll->body[i].dimensions[1] + doll->body[i].dimensions[2])/3;
CLQ1_AddOrientedCylinder(debugshader, rad, rad, true, bodymat, 0.2, 0.2, 0.2, 1); CLQ1_AddOrientedCylinder(debugshader, rad, rad, true, bodymat, 0.2, 0.2, 0.2, 1);
break; break;

View file

@ -34,6 +34,15 @@ static avec4_t draw_mesh_colors[4];
index_t r_quad_indexes[6] = {0, 1, 2, 2, 3, 0}; index_t r_quad_indexes[6] = {0, 1, 2, 2, 3, 0};
unsigned int r2d_be_flags; unsigned int r2d_be_flags;
static struct
{
texid_t id;
int width;
int height;
uploadfmt_t fmt;
} *rendertargets;
static unsigned int numrendertargets;
extern cvar_t scr_conalpha; extern cvar_t scr_conalpha;
extern cvar_t gl_conback; extern cvar_t gl_conback;
extern cvar_t gl_font; extern cvar_t gl_font;
@ -116,6 +125,11 @@ void R2D_Shutdown(void)
cl_numstris = 0; cl_numstris = 0;
cl_maxstris = 0; cl_maxstris = 0;
while (numrendertargets>0)
R_DestroyTexture(rendertargets[--numrendertargets].id);
free(rendertargets);
rendertargets = NULL;
if (font_console == font_default) if (font_console == font_default)
font_console = NULL; font_console = NULL;
@ -344,8 +358,8 @@ mpic_t *R2D_SafePicFromWad (char *name)
char newnamegfx[32]; char newnamegfx[32];
shader_t *s; shader_t *s;
snprintf(newnamewad, sizeof(newnamewad), "wad/%s.lmp", name); snprintf(newnamewad, sizeof(newnamewad), "wad/%s", name);
snprintf(newnamegfx, sizeof(newnamegfx), "gfx/%s.lmp", name); snprintf(newnamegfx, sizeof(newnamegfx), "gfx/%s", name);
s = R_RegisterPic(newnamewad); s = R_RegisterPic(newnamewad);
if (!(s->flags & SHADER_NOIMAGE)) if (!(s->flags & SHADER_NOIMAGE))
@ -615,7 +629,7 @@ void R2D_Conback_Callback(struct cvar_s *var, char *oldvalue)
} }
} }
#ifdef _WIN32 #if defined(_WIN32) && !defined(_SDL)
#include <windows.h> #include <windows.h>
qboolean R2D_Font_WasAdded(char *buffer, char *fontfilename) qboolean R2D_Font_WasAdded(char *buffer, char *fontfilename)
{ {
@ -1279,6 +1293,77 @@ void R2D_DrawCrosshair(void)
R2D_ImageColours(1, 1, 1, 1); R2D_ImageColours(1, 1, 1, 1);
} }
//resize a texture for a render target and specify the format of it.
//pass TF_INVALID and sizes=0 to get without configuring (shaders that hardcode an $rt1 etc).
texid_t R2D_RT_Configure(unsigned int id, int width, int height, uploadfmt_t rtfmt)
{
id--; //0 is invalid.
if (id < 0 || id > 255) //sanity limit
return r_nulltex;
//extend the array if needed. these should be fairly light.
if (id >= numrendertargets)
{
rendertargets = realloc(rendertargets, (id+1) * sizeof(*rendertargets));
while(numrendertargets <= id)
{
rendertargets[numrendertargets].id = r_nulltex;
rendertargets[numrendertargets].width = 0;
rendertargets[numrendertargets].height = 0;
rendertargets[numrendertargets].fmt = TF_INVALID;
numrendertargets++;
}
}
if (!TEXVALID(rendertargets[id].id))
rendertargets[id].id = R_AllocNewTexture(va("", id+1), 0, 0, IF_NOMIPMAP);
if (rtfmt)
{
switch(rtfmt)
{
case 1: rtfmt = TF_RGBA32; break;
case 2: rtfmt = TF_RGBA16F; break;
case 3: rtfmt = TF_RGBA32F; break;
case 4: rtfmt = TF_DEPTH16; break;
case 5: rtfmt = TF_DEPTH24; break;
case 6: rtfmt = TF_DEPTH32; break;
default:rtfmt = TF_INVALID; break;
}
// if (rendertargets[id].fmt != rtfmt || rendertargets[id].width != width || rendertargets[id].height != height)
{
rendertargets[id].fmt = rtfmt;
rendertargets[id].width = width;
rendertargets[id].height = height;
R_Upload(rendertargets[id].id, "", rtfmt, NULL, NULL, width, height, IF_NOMIPMAP);
}
}
return rendertargets[id].id;
}
texid_t R2D_RT_GetTexture(unsigned int id, unsigned int *width, unsigned int *height)
{
if (!id)
{
*width = 0;
*height = 0;
return r_nulltex;
}
id--;
if (id >= numrendertargets)
{
Con_Printf("Render target %u is not configured\n", id);
R2D_RT_Configure(id, 0, 0, TF_INVALID);
if (id >= numrendertargets)
{
*width = 0;
*height = 0;
return r_nulltex;
}
}
*width = rendertargets[id].width;
*height = rendertargets[id].height;
return rendertargets[id].id;
}
#endif #endif

View file

@ -1510,12 +1510,11 @@ char *particle_set_high =
"scalefactor 1\n" "scalefactor 1\n"
"scaledelta -15\n" "scaledelta -15\n"
"randomvel 0\n" "randomvel 0\n"
// lightradius 350
"lightradius 350\n" // lightrgb 1.4 1.2 1.05
"lightrgb 1.4 1.2 1.05\n" // lighttime 0.5
"lighttime 0.5\n" // lightradiusfade 350
"lightradiusfade 350\n" // lightrgbfade 2 2 2
"lightrgbfade 2 2 2 \n"
"}\n" "}\n"
//smoke //smoke
"r_part +te_explosion\n" "r_part +te_explosion\n"
@ -1558,7 +1557,7 @@ char *particle_set_high =
"}\n" "}\n"
//hide lights in explosions. //hide lights in explosions.
"r_explosionlight 0\n" //r_explosionlight 0
//hide the explosion sprite in nq+qw - WARNING: some mods use this sprite as a flame thrower. //hide the explosion sprite in nq+qw - WARNING: some mods use this sprite as a flame thrower.
"cl_expsprite 0\n" "cl_expsprite 0\n"

View file

@ -150,6 +150,7 @@ typedef struct mplane_s
#define MAXFRUSTUMPLANES 7 //4 side, 1 near, 1 far (fog), 1 water plane. #define MAXFRUSTUMPLANES 7 //4 side, 1 near, 1 far (fog), 1 water plane.
#define R_MAX_RECURSE 6 #define R_MAX_RECURSE 6
#define R_POSTPROC_PASSES 6
#define RDFD_FOV 1 #define RDFD_FOV 1
typedef struct typedef struct
{ {
@ -188,8 +189,10 @@ typedef struct
unsigned int flipcull; /*reflected/flipped view, requires inverted culling (should be set to SHADER_CULL_FLIPPED or 0)*/ unsigned int flipcull; /*reflected/flipped view, requires inverted culling (should be set to SHADER_CULL_FLIPPED or 0)*/
qboolean useperspective; /*not orthographic*/ qboolean useperspective; /*not orthographic*/
int postprocshader; /*if set, renders to texture then invokes this shader*/ int rt_destcolour; /*used for 2d. written by 3d*/
int postproccube; /*postproc shader wants a cubemap, this is the mask of sides required*/ int rt_sourcecolour; /*read by 2d. not used for 3d. */
int rt_depth; /*read by 2d. used by 3d (renderbuffer used if not set)*/
int rt_ripplemap; /*read by 2d. used by 3d (internal ripplemap buffer used if not set)*/
qbyte *forcedvis; qbyte *forcedvis;

View file

@ -45,8 +45,8 @@ void GL_Texturemode2d_Callback (struct cvar_s *var, char *oldvalue);
void GL_Texture_Anisotropic_Filtering_Callback (struct cvar_s *var, char *oldvalue); void GL_Texture_Anisotropic_Filtering_Callback (struct cvar_s *var, char *oldvalue);
#endif #endif
cvar_t _vid_wait_override = CVARAF ("vid_wait", "0", cvar_t vid_vsync = CVARAF ("vid_wait", "0",
"_vid_wait_override", CVAR_ARCHIVE); "vid_vsync", CVAR_ARCHIVE);
cvar_t _windowed_mouse = CVARF ("_windowed_mouse","1", cvar_t _windowed_mouse = CVARF ("_windowed_mouse","1",
CVAR_ARCHIVE); CVAR_ARCHIVE);
@ -63,7 +63,7 @@ cvar_t gl_part_flame = CVARFD ("gl_part_flame", "1", CVAR_ARCHIVE, "Enable
//opengl library, blank means try default. //opengl library, blank means try default.
static cvar_t gl_driver = CVARF ("gl_driver", "", static cvar_t gl_driver = CVARF ("gl_driver", "",
CVAR_ARCHIVE | CVAR_RENDERERLATCH); CVAR_ARCHIVE | CVAR_RENDERERLATCH);
cvar_t gl_shadeq1_name = CVAR ("gl_shadeq1_name", "*"); cvar_t gl_shadeq1_name = CVARD ("gl_shadeq1_name", "*", "Rename all surfaces from quake1 bsps using this pattern for the purposes of shader names.");
extern cvar_t r_vertexlight; extern cvar_t r_vertexlight;
cvar_t mod_md3flags = CVAR ("mod_md3flags", "1"); cvar_t mod_md3flags = CVAR ("mod_md3flags", "1");
@ -107,8 +107,8 @@ cvar_t r_floorcolour = CVARAF ("r_floorcolour", "64 64 128",
"r_floorcolor", CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM); "r_floorcolor", CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM);
cvar_t r_floortexture = SCVARF ("r_floortexture", "", cvar_t r_floortexture = SCVARF ("r_floortexture", "",
CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM); CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM);
cvar_t r_fullbright = SCVARF ("r_fullbright", "0", cvar_t r_fullbright = CVARFD ("r_fullbright", "0",
CVAR_CHEAT|CVAR_SHADERSYSTEM); CVAR_CHEAT|CVAR_SHADERSYSTEM, "Ignore world lightmaps, drawing everything fully lit.");
cvar_t r_fullbrightSkins = SCVARF ("r_fullbrightSkins", "0.8", /*don't default to 1, as it looks a little ugly (too bright), but don't default to 0 either because then you're handicapped in the dark*/ cvar_t r_fullbrightSkins = SCVARF ("r_fullbrightSkins", "0.8", /*don't default to 1, as it looks a little ugly (too bright), but don't default to 0 either because then you're handicapped in the dark*/
CVAR_SEMICHEAT|CVAR_SHADERSYSTEM); CVAR_SEMICHEAT|CVAR_SHADERSYSTEM);
cvar_t r_lightmap_saturation = SCVAR ("r_lightmap_saturation", "1"); cvar_t r_lightmap_saturation = SCVAR ("r_lightmap_saturation", "1");
@ -145,8 +145,8 @@ cvar_t r_wateralpha = CVARF ("r_wateralpha", "1",
cvar_t r_waterwarp = CVARF ("r_waterwarp", "1", cvar_t r_waterwarp = CVARF ("r_waterwarp", "1",
CVAR_ARCHIVE); CVAR_ARCHIVE);
cvar_t r_replacemodels = CVARF ("r_replacemodels", IFMINIMAL("","md3 md2"), cvar_t r_replacemodels = CVARFD ("r_replacemodels", IFMINIMAL("","md3 md2"),
CVAR_ARCHIVE); CVAR_ARCHIVE, "A list of filename extensions to attempt to use instead of mdl.");
//otherwise it would defeat the point. //otherwise it would defeat the point.
cvar_t scr_allowsnap = CVARF ("scr_allowsnap", "1", cvar_t scr_allowsnap = CVARF ("scr_allowsnap", "1",
@ -184,33 +184,33 @@ cvar_t vid_conheight = CVARF ("vid_conheight", "0",
cvar_t vid_conwidth = CVARF ("vid_conwidth", "0", cvar_t vid_conwidth = CVARF ("vid_conwidth", "0",
CVAR_ARCHIVE | CVAR_RENDERERCALLBACK); CVAR_ARCHIVE | CVAR_RENDERERCALLBACK);
//see R_RestartRenderer_f for the effective default 'if (newr.renderer == -1)'. //see R_RestartRenderer_f for the effective default 'if (newr.renderer == -1)'.
cvar_t vid_renderer = CVARF ("vid_renderer", "", cvar_t vid_renderer = CVARFD ("vid_renderer", "",
CVAR_ARCHIVE | CVAR_RENDERERLATCH); CVAR_ARCHIVE | CVAR_RENDERERLATCH, "Specifies which backend is used. Values that might work are: sv (dedicated server), gl (opengl), egl (opengl es), d3d9 (direct3d 9), d3d11 (direct3d 11, with default hardware rendering), d3d11 warp (direct3d 11, with software rendering).");
cvar_t vid_bpp = CVARF ("vid_bpp", "32", cvar_t vid_bpp = CVARFD ("vid_bpp", "32",
CVAR_ARCHIVE | CVAR_RENDERERLATCH); CVAR_ARCHIVE | CVAR_RENDERERLATCH, "The number of colour bits to request from the renedering context");
cvar_t vid_desktopsettings = CVARF ("vid_desktopsettings", "0", cvar_t vid_desktopsettings = CVARFD ("vid_desktopsettings", "0",
CVAR_ARCHIVE | CVAR_RENDERERLATCH); CVAR_ARCHIVE | CVAR_RENDERERLATCH, "Ignore the values of vid_width and vid_height, and just use the same settings that are used for the desktop.");
#ifdef NACL #ifdef NACL
cvar_t vid_fullscreen = CVARF ("vid_fullscreen", "0", cvar_t vid_fullscreen = CVARF ("vid_fullscreen", "0",
CVAR_ARCHIVE); CVAR_ARCHIVE);
#else #else
//these cvars will be given their names when they're registered, based upon whether -plugin was used. this means code can always use vid_fullscreen without caring, but gets saved properly. //these cvars will be given their names when they're registered, based upon whether -plugin was used. this means code can always use vid_fullscreen without caring, but gets saved properly.
cvar_t vid_fullscreen = CVARAF (NULL, "1", "vid_fullscreen", cvar_t vid_fullscreen = CVARAFD (NULL, "1", "vid_fullscreen",
CVAR_ARCHIVE | CVAR_RENDERERLATCH); CVAR_ARCHIVE | CVAR_RENDERERLATCH, "Whether to use fullscreen or not.");
cvar_t vid_fullscreen_alternative = CVARF (NULL, "1", cvar_t vid_fullscreen_alternative = CVARFD (NULL, "1",
CVAR_ARCHIVE); CVAR_ARCHIVE, "Whether to use fuollscreen or not. This cvar is saved to your config but not otherwise used in this operating mode.");
#endif #endif
cvar_t vid_height = CVARF ("vid_height", "0", cvar_t vid_height = CVARFD ("vid_height", "0",
CVAR_ARCHIVE | CVAR_RENDERERLATCH); CVAR_ARCHIVE | CVAR_RENDERERLATCH, "The screen height to attempt to use, in physical pixels. 0 means use desktop resolution.");
cvar_t vid_multisample = CVARF ("vid_multisample", "0", cvar_t vid_multisample = CVARF ("vid_multisample", "0",
CVAR_ARCHIVE | CVAR_RENDERERLATCH); CVAR_ARCHIVE | CVAR_RENDERERLATCH);
cvar_t vid_refreshrate = CVARF ("vid_displayfrequency", "0", cvar_t vid_refreshrate = CVARF ("vid_displayfrequency", "0",
CVAR_ARCHIVE | CVAR_RENDERERLATCH); CVAR_ARCHIVE | CVAR_RENDERERLATCH);
cvar_t vid_wndalpha = CVAR ("vid_wndalpha", "1"); cvar_t vid_wndalpha = CVAR ("vid_wndalpha", "1");
//more readable defaults to match conwidth/conheight. //more readable defaults to match conwidth/conheight.
cvar_t vid_width = CVARF ("vid_width", "0", cvar_t vid_width = CVARFD ("vid_width", "0",
CVAR_ARCHIVE | CVAR_RENDERERLATCH); CVAR_ARCHIVE | CVAR_RENDERERLATCH, "The screen width to attempt to use, in physical pixels. 0 means use desktop resolution.");
cvar_t r_stereo_separation = CVARD("r_stereo_separation", "4", "How far your eyes are apart, in quake units. A non-zero value will enable stereoscoping rendering. You might need some of them retro 3d glasses. Hardware support is recommended, see r_stereo_context."); cvar_t r_stereo_separation = CVARD("r_stereo_separation", "4", "How far your eyes are apart, in quake units. A non-zero value will enable stereoscoping rendering. You might need some of them retro 3d glasses. Hardware support is recommended, see r_stereo_context.");
cvar_t r_stereo_method = CVARD("r_stereo_method", "0", "Value 0 = Off.\nValue 1 = Attempt hardware acceleration. Requires vid_restart.\nValue 2 = red/cyan.\nValue 3 = red/blue.\nValue 4=red/green.\nValue 5=eye strain."); cvar_t r_stereo_method = CVARD("r_stereo_method", "0", "Value 0 = Off.\nValue 1 = Attempt hardware acceleration. Requires vid_restart.\nValue 2 = red/cyan.\nValue 3 = red/blue.\nValue 4=red/green.\nValue 5=eye strain.");
@ -223,7 +223,7 @@ extern cvar_t r_drawentities;
extern cvar_t r_drawviewmodel; extern cvar_t r_drawviewmodel;
extern cvar_t r_drawworld; extern cvar_t r_drawworld;
extern cvar_t r_fullbright; extern cvar_t r_fullbright;
cvar_t r_mirroralpha = SCVARF("r_mirroralpha","1", CVAR_CHEAT|CVAR_SHADERSYSTEM); cvar_t r_mirroralpha = CVARFD("r_mirroralpha","1", CVAR_CHEAT|CVAR_SHADERSYSTEM, "Specifies how the default shader is generated for the 'window02_1' texture. Values less than 1 will turn it into a mirror.");
extern cvar_t r_netgraph; extern cvar_t r_netgraph;
extern cvar_t r_norefresh; extern cvar_t r_norefresh;
extern cvar_t r_novis; extern cvar_t r_novis;
@ -246,11 +246,11 @@ rendererstate_t currentrendererstate;
#if defined(GLQUAKE) #if defined(GLQUAKE)
cvar_t gl_workaround_ati_shadersource = CVARD ("gl_workaround_ati_shadersource", "1", "Work around ATI driver bugs in the glShaderSource function. Can safely be enabled with other drivers too."); cvar_t gl_workaround_ati_shadersource = CVARD ("gl_workaround_ati_shadersource", "1", "Work around ATI driver bugs in the glShaderSource function. Can safely be enabled with other drivers too.");
cvar_t vid_gl_context_version = SCVAR ("vid_gl_context_version", ""); cvar_t vid_gl_context_version = CVARD ("vid_gl_context_version", "", "Specifies the version of OpenGL to try to create.");
cvar_t vid_gl_context_forwardcompatible = SCVAR ("vid_gl_context_forwardcompatible", "0"); cvar_t vid_gl_context_forwardcompatible = CVARD ("vid_gl_context_forwardcompatible", "0", "Requests an opengl context with no depricated features enabled.");
cvar_t vid_gl_context_compatibility = SCVAR ("vid_gl_context_compatibility", "1"); cvar_t vid_gl_context_compatibility = CVARD ("vid_gl_context_compatibility", "1", "Requests an OpenGL context with fixed-function backwards compat.");
cvar_t vid_gl_context_debug = SCVAR ("vid_gl_context_debug", "0"); //for my ati drivers, debug 1 only works if version >= 3 cvar_t vid_gl_context_debug = CVARD ("vid_gl_context_debug", "0", "Requests a debug opengl context. This provides better error oreporting."); //for my ati drivers, debug 1 only works if version >= 3
cvar_t vid_gl_context_es2 = SCVAR ("vid_gl_context_es2", "0"); //requires version set correctly, no debug, no compat cvar_t vid_gl_context_es = CVARD ("vid_gl_context_es", "0", "Requests an OpenGLES context. Be sure to set vid_gl_context_version to 2 or so."); //requires version set correctly, no debug, no compat
#endif #endif
#if defined(GLQUAKE) || defined(D3DQUAKE) #if defined(GLQUAKE) || defined(D3DQUAKE)
@ -258,23 +258,22 @@ cvar_t gl_ati_truform = CVAR ("gl_ati_truform", "0");
cvar_t gl_ati_truform_type = CVAR ("gl_ati_truform_type", "1"); cvar_t gl_ati_truform_type = CVAR ("gl_ati_truform_type", "1");
cvar_t gl_ati_truform_tesselation = CVAR ("gl_ati_truform_tesselation", "3"); cvar_t gl_ati_truform_tesselation = CVAR ("gl_ati_truform_tesselation", "3");
cvar_t gl_blend2d = CVAR ("gl_blend2d", "1"); cvar_t gl_blend2d = CVAR ("gl_blend2d", "1");
cvar_t gl_blendsprites = CVAR ("gl_blendsprites", "0"); cvar_t gl_blendsprites = CVARD ("gl_blendsprites", "0", "Blend sprites instead of alpha testing them");
cvar_t r_deluxemapping = CVARAF ("r_deluxemapping", "0", "r_glsl_deluxemapping", cvar_t r_deluxemapping = CVARAFD ("r_deluxemapping", "0", "r_glsl_deluxemapping",
CVAR_ARCHIVE | CVAR_RENDERERLATCH); CVAR_ARCHIVE | CVAR_RENDERERLATCH, "Enables bumpmapping based upon precomputed light directions");
cvar_t gl_compress = CVARF ("gl_compress", "0", cvar_t gl_compress = CVARFD ("gl_compress", "0", CVAR_ARCHIVE, "Enable automatic texture compression even for textures which are not pre-compressed.");
CVAR_ARCHIVE); cvar_t gl_conback = CVARFDC ("gl_conback", "",
cvar_t gl_conback = CVARFC ("gl_conback", "", CVAR_RENDERERCALLBACK, "Specifies which conback shader/image to use. The Quake fallback is gfx/conback.lmp", R2D_Conback_Callback);
CVAR_RENDERERCALLBACK, R2D_Conback_Callback); //cvar_t gl_detail = CVARF ("gl_detail", "0",
cvar_t gl_detail = CVARF ("gl_detail", "0", // CVAR_ARCHIVE);
CVAR_ARCHIVE); //cvar_t gl_detailscale = CVAR ("gl_detailscale", "5");
cvar_t gl_detailscale = CVAR ("gl_detailscale", "5");
cvar_t gl_font = CVARFD ("gl_font", "", cvar_t gl_font = CVARFD ("gl_font", "",
CVAR_RENDERERCALLBACK, ("Specifies the font file to use. a value such as FONT:ALTFONT specifies an alternative font to be used when ^^a is used.\n" CVAR_RENDERERCALLBACK, ("Specifies the font file to use. a value such as FONT:ALTFONT specifies an alternative font to be used when ^^a is used.\n"
"When using TTF fonts, you will likely need to scale text to at least 150% - vid_conautoscale 1.5 will do this.\n" "When using TTF fonts, you will likely need to scale text to at least 150% - vid_conautoscale 1.5 will do this.\n"
"TTF fonts may be loaded from your windows directory. \'gl_font cour:couri\' loads eg: c:\\windows\\fonts\\cour.ttf, and uses the italic version of courier for alternative text." "TTF fonts may be loaded from your windows directory. \'gl_font cour:couri\' loads eg: c:\\windows\\fonts\\cour.ttf, and uses the italic version of courier for alternative text."
)); ));
cvar_t gl_lateswap = CVAR ("gl_lateswap", "0"); cvar_t gl_lateswap = CVAR ("gl_lateswap", "0");
cvar_t gl_lerpimages = CVARF ("gl_lerpimages", "1", CVAR_ARCHIVE); cvar_t gl_lerpimages = CVARFD ("gl_lerpimages", "1", CVAR_ARCHIVE, "Enables smoother resampling for images which are not power-of-two, when the drivers do not support non-power-of-two textures.");
//cvar_t gl_lightmapmode = SCVARF("gl_lightmapmode", "", //cvar_t gl_lightmapmode = SCVARF("gl_lightmapmode", "",
// CVAR_ARCHIVE); // CVAR_ARCHIVE);
cvar_t gl_load24bit = SCVARF ("gl_load24bit", "1", cvar_t gl_load24bit = SCVARF ("gl_load24bit", "1",
@ -282,14 +281,14 @@ cvar_t gl_load24bit = SCVARF ("gl_load24bit", "1",
cvar_t r_clear = CVARAF("r_clear","0", cvar_t r_clear = CVARAF("r_clear","0",
"gl_clear", 0); "gl_clear", 0);
cvar_t gl_max_size = SCVARF ("gl_max_size", "2048", CVAR_RENDERERLATCH); cvar_t gl_max_size = CVARFD ("gl_max_size", "8192", CVAR_RENDERERLATCH, "Specifies the maximum texture size that the engine may use. Textures larger than this will be downsized. Clamped by the value the driver supports.");
cvar_t gl_maxshadowlights = SCVARF ("gl_maxshadowlights", "2", cvar_t gl_maxshadowlights = SCVARF ("gl_maxshadowlights", "2",
CVAR_ARCHIVE); CVAR_ARCHIVE);
cvar_t gl_menutint_shader = SCVAR ("gl_menutint_shader", "1"); cvar_t gl_menutint_shader = CVARD ("gl_menutint_shader", "1", "Controls the use of GLSL to desaturate the background when drawing the menu, like quake's dos software renderer used to do before the ugly dithering of winquake.");
//by setting to 64 or something, you can use this as a wallhack //by setting to 64 or something, you can use this as a wallhack
cvar_t gl_mindist = SCVARF ("gl_mindist", "4", cvar_t gl_mindist = CVARFD ("gl_mindist", "4",
CVAR_CHEAT); CVAR_CHEAT, "Distance to the near clip plane. Smaller values may damage depth precision, high values can potentialy be used to see through walls...");
cvar_t gl_motionblur = SCVARF ("gl_motionblur", "0", cvar_t gl_motionblur = SCVARF ("gl_motionblur", "0",
CVAR_ARCHIVE); CVAR_ARCHIVE);
@ -299,14 +298,14 @@ cvar_t gl_overbright = CVARFC ("gl_overbright", "1",
Surf_RebuildLightmap_Callback); Surf_RebuildLightmap_Callback);
cvar_t gl_overbright_all = SCVARF ("gl_overbright_all", "0", cvar_t gl_overbright_all = SCVARF ("gl_overbright_all", "0",
CVAR_ARCHIVE); CVAR_ARCHIVE);
cvar_t gl_picmip = CVARF ("gl_picmip", "0", CVAR_ARCHIVE); cvar_t gl_picmip = CVARFD ("gl_picmip", "0", CVAR_ARCHIVE, "Reduce world/model texture sizes by some exponential factor.");
cvar_t gl_picmip2d = CVARF ("gl_picmip2d", "0", CVAR_ARCHIVE); cvar_t gl_picmip2d = CVARFD ("gl_picmip2d", "0", CVAR_ARCHIVE, "Reduce hud/menu texture sizes by some exponential factor.");
cvar_t gl_nohwblend = SCVAR ("gl_nohwblend","1"); cvar_t gl_nohwblend = CVARD ("gl_nohwblend","1", "If 1, don't use hardware gamma ramps for transient effects that change each frame (does not affect long-term effects like holding quad or underwater tints).");
cvar_t gl_savecompressedtex = SCVAR ("gl_savecompressedtex", "0"); cvar_t gl_savecompressedtex = CVARD ("gl_savecompressedtex", "0", "Write out a copy of textures in a compressed format. The driver will do the compression on the fly, thus this setting is likely inferior to software which does not care so much about compression times.");
cvar_t gl_schematics = SCVAR ("gl_schematics", "0"); //cvar_t gl_schematics = CVARD ("gl_schematics", "0", "Gimmick rendering mode that draws the length of various world edges.");
cvar_t gl_skyboxdist = SCVAR ("gl_skyboxdist", "0"); //0 = guess. cvar_t gl_skyboxdist = CVARD ("gl_skyboxdist", "0", "The distance of the skybox. If 0, the engine will determine it based upon the far clip plane distance."); //0 = guess.
cvar_t gl_smoothcrosshair = SCVAR ("gl_smoothcrosshair", "1"); cvar_t gl_smoothcrosshair = SCVAR ("gl_smoothcrosshair", "1");
cvar_t gl_maxdist = SCVAR("gl_maxdist", "8192"); cvar_t gl_maxdist = CVARD ("gl_maxdist", "8192", "The distance of the far clip plane. If set to 0, some fancy maths will be used to place it at an infinite distance.");
#ifdef SPECULAR #ifdef SPECULAR
cvar_t gl_specular = CVARF ("gl_specular", "1", CVAR_ARCHIVE); cvar_t gl_specular = CVARF ("gl_specular", "1", CVAR_ARCHIVE);
@ -329,33 +328,30 @@ cvar_t gl_texturemode2d = CVARFC("gl_texturemode2d", "GL_LINEAR",
GL_Texturemode2d_Callback); GL_Texturemode2d_Callback);
#endif #endif
cvar_t vid_triplebuffer = CVARAF ("vid_triplebuffer", "1", cvar_t vid_triplebuffer = CVARAFD ("vid_triplebuffer", "1", "gl_triplebuffer", CVAR_ARCHIVE, "Specifies whether the hardware is forcing tripplebuffering on us, this is the number of extra page swaps required before old data has been completely overwritten.");
"gl_triplebuffer", CVAR_ARCHIVE);
cvar_t r_portalrecursion = CVARD ("r_portalrecursion", "1", "The number of portals the camera is allowed to recurse through."); cvar_t r_portalrecursion = CVARD ("r_portalrecursion", "1", "The number of portals the camera is allowed to recurse through.");
cvar_t dpcompat_psa_ungroup = SCVAR ("dpcompat_psa_ungroup", "0"); cvar_t dpcompat_psa_ungroup = SCVAR ("dpcompat_psa_ungroup", "0");
cvar_t r_noaliasshadows = SCVARF ("r_noaliasshadows", "0", cvar_t r_noaliasshadows = SCVARF ("r_noaliasshadows", "0", CVAR_ARCHIVE);
CVAR_ARCHIVE); cvar_t r_shadows = CVARFD ("r_shadows", "0", CVAR_ARCHIVE, "Draw basic blob shadows underneath entities without using realtime lighting.");
cvar_t r_shadows = SCVARF ("r_shadows", "0",
CVAR_ARCHIVE);
cvar_t r_showbboxes = CVARD("r_showbboxes", "0", "Debugging. Shows bounding boxes. 1=ssqc, 2=csqc. Red=solid, Green=stepping/toss/bounce, Blue=onground."); cvar_t r_showbboxes = CVARD("r_showbboxes", "0", "Debugging. Shows bounding boxes. 1=ssqc, 2=csqc. Red=solid, Green=stepping/toss/bounce, Blue=onground.");
cvar_t r_lightprepass = CVARFD("r_lightprepass", "0", CVAR_SHADERSYSTEM, "Experimental. Attempt to use a different lighting mechanism."); cvar_t r_lightprepass = CVARFD("r_lightprepass", "0", CVAR_SHADERSYSTEM, "Experimental. Attempt to use a different lighting mechanism.");
cvar_t r_shadow_bumpscale_basetexture = CVARD ("r_shadow_bumpscale_basetexture", "0", "bumpyness scaler for generation of fallback normalmap textures from models"); cvar_t r_shadow_bumpscale_basetexture = CVARD ("r_shadow_bumpscale_basetexture", "0", "bumpyness scaler for generation of fallback normalmap textures from models");
cvar_t r_shadow_bumpscale_bumpmap = CVARD ("r_shadow_bumpscale_bumpmap", "4", "bumpyness scaler for _bump textures"); cvar_t r_shadow_bumpscale_bumpmap = CVARD ("r_shadow_bumpscale_bumpmap", "4", "bumpyness scaler for _bump textures");
cvar_t r_glsl_offsetmapping = CVARF ("r_glsl_offsetmapping", "0", CVAR_ARCHIVE|CVAR_SHADERSYSTEM); cvar_t r_glsl_offsetmapping = CVARFD ("r_glsl_offsetmapping", "0", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "Enables the use of paralax mapping, adding fake depth to textures.");
cvar_t r_glsl_offsetmapping_scale = CVAR ("r_glsl_offsetmapping_scale", "0.04"); cvar_t r_glsl_offsetmapping_scale = CVAR ("r_glsl_offsetmapping_scale", "0.04");
cvar_t r_glsl_offsetmapping_reliefmapping = CVARF("r_glsl_offsetmapping_reliefmapping", "1", CVAR_ARCHIVE|CVAR_SHADERSYSTEM); cvar_t r_glsl_offsetmapping_reliefmapping = CVARFD("r_glsl_offsetmapping_reliefmapping", "1", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "Changes the paralax sampling mode to be a bit nicer. r_glsl_offsetmapping must be set.");
cvar_t r_glsl_turbscale = CVARF ("r_glsl_turbscale", "1", CVAR_ARCHIVE); //cvar_t r_glsl_turbscale = CVARF ("r_glsl_turbscale", "1", CVAR_ARCHIVE);
cvar_t r_waterstyle = CVARFD ("r_waterstyle", "1", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "Changes how water, and teleporters are drawn. Possible values are:\n0: fastturb-style block colour.\n1: regular q1-style water.\n2: refraction(ripply and transparent)\n3: refraction with reflection at an angle\n4: ripplemapped without reflections (requires particle effects)\n5: ripples+reflections"); cvar_t r_waterstyle = CVARFD ("r_waterstyle", "1", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "Changes how water, and teleporters are drawn. Possible values are:\n0: fastturb-style block colour.\n1: regular q1-style water.\n2: refraction(ripply and transparent)\n3: refraction with reflection at an angle\n4: ripplemapped without reflections (requires particle effects)\n5: ripples+reflections");
cvar_t r_slimestyle = CVARFD ("r_slimestyle", "", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "See r_waterstyle, but affects only slime. If empty, defers to r_waterstyle."); cvar_t r_slimestyle = CVARFD ("r_slimestyle", "", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "See r_waterstyle, but affects only slime. If empty, defers to r_waterstyle.");
cvar_t r_lavastyle = CVARFD ("r_lavastyle", "1", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "See r_waterstyle, but affects only lava. If empty, defers to r_waterstyle."); cvar_t r_lavastyle = CVARFD ("r_lavastyle", "1", CVAR_ARCHIVE|CVAR_SHADERSYSTEM, "See r_waterstyle, but affects only lava. If empty, defers to r_waterstyle.");
cvar_t r_vertexdlights = SCVAR ("r_vertexdlights", "0"); cvar_t r_vertexdlights = CVARD ("r_vertexdlights", "0", "Determine model lighting with respect to nearby dlights. Poor-man's rtlights.");
cvar_t vid_preservegamma = SCVAR ("vid_preservegamma", "0"); cvar_t vid_preservegamma = CVARD ("vid_preservegamma", "0", "Restore initial hardware gamma ramps when quitting.");
cvar_t vid_hardwaregamma = CVARFD ("vid_hardwaregamma", "1", cvar_t vid_hardwaregamma = CVARFD ("vid_hardwaregamma", "1",
CVAR_ARCHIVE | CVAR_RENDERERLATCH, "Use hardware gamma ramps. 0=loadtime-gamma, 1=glsl(windowed) or hardware(fullscreen), 2=always glsl, 3=always hardware gamma."); CVAR_ARCHIVE | CVAR_RENDERERLATCH, "Use hardware gamma ramps. 0=loadtime-gamma, 1=glsl(windowed) or hardware(fullscreen), 2=always glsl, 3=always hardware gamma.");
cvar_t vid_desktopgamma = CVARFD ("vid_desktopgamma", "0", cvar_t vid_desktopgamma = CVARFD ("vid_desktopgamma", "0",
@ -386,7 +382,7 @@ void GLRenderer_Init(void)
Cvar_Register (&vid_gl_context_debug, GLRENDEREROPTIONS); Cvar_Register (&vid_gl_context_debug, GLRENDEREROPTIONS);
Cvar_Register (&vid_gl_context_forwardcompatible, GLRENDEREROPTIONS); Cvar_Register (&vid_gl_context_forwardcompatible, GLRENDEREROPTIONS);
Cvar_Register (&vid_gl_context_compatibility, GLRENDEREROPTIONS); Cvar_Register (&vid_gl_context_compatibility, GLRENDEREROPTIONS);
Cvar_Register (&vid_gl_context_es2, GLRENDEREROPTIONS); Cvar_Register (&vid_gl_context_es, GLRENDEREROPTIONS);
//screen //screen
Cvar_Register (&vid_preservegamma, GLRENDEREROPTIONS); Cvar_Register (&vid_preservegamma, GLRENDEREROPTIONS);
@ -424,7 +420,7 @@ void GLRenderer_Init(void)
Cvar_Register (&r_glsl_offsetmapping, GRAPHICALNICETIES); Cvar_Register (&r_glsl_offsetmapping, GRAPHICALNICETIES);
Cvar_Register (&r_glsl_offsetmapping_scale, GRAPHICALNICETIES); Cvar_Register (&r_glsl_offsetmapping_scale, GRAPHICALNICETIES);
Cvar_Register (&r_glsl_offsetmapping_reliefmapping, GRAPHICALNICETIES); Cvar_Register (&r_glsl_offsetmapping_reliefmapping, GRAPHICALNICETIES);
Cvar_Register (&r_glsl_turbscale, GRAPHICALNICETIES); // Cvar_Register (&r_glsl_turbscale, GRAPHICALNICETIES);
#ifdef R_XFLIP #ifdef R_XFLIP
@ -442,8 +438,8 @@ void GLRenderer_Init(void)
Cvar_Register (&gl_texture_anisotropic_filtering, GLRENDEREROPTIONS); Cvar_Register (&gl_texture_anisotropic_filtering, GLRENDEREROPTIONS);
Cvar_Register (&gl_savecompressedtex, GLRENDEREROPTIONS); Cvar_Register (&gl_savecompressedtex, GLRENDEREROPTIONS);
Cvar_Register (&gl_compress, GLRENDEREROPTIONS); Cvar_Register (&gl_compress, GLRENDEREROPTIONS);
Cvar_Register (&gl_detail, GRAPHICALNICETIES); // Cvar_Register (&gl_detail, GRAPHICALNICETIES);
Cvar_Register (&gl_detailscale, GRAPHICALNICETIES); // Cvar_Register (&gl_detailscale, GRAPHICALNICETIES);
Cvar_Register (&gl_overbright, GRAPHICALNICETIES); Cvar_Register (&gl_overbright, GRAPHICALNICETIES);
Cvar_Register (&gl_overbright_all, GRAPHICALNICETIES); Cvar_Register (&gl_overbright_all, GRAPHICALNICETIES);
Cvar_Register (&gl_dither, GRAPHICALNICETIES); Cvar_Register (&gl_dither, GRAPHICALNICETIES);
@ -464,7 +460,7 @@ void GLRenderer_Init(void)
Cvar_Register (&r_vertexdlights, GLRENDEREROPTIONS); Cvar_Register (&r_vertexdlights, GLRENDEREROPTIONS);
Cvar_Register (&gl_schematics, GLRENDEREROPTIONS); // Cvar_Register (&gl_schematics, GLRENDEREROPTIONS);
Cvar_Register (&r_vertexlight, GLRENDEREROPTIONS); Cvar_Register (&r_vertexlight, GLRENDEREROPTIONS);
@ -562,7 +558,7 @@ void Renderer_Init(void)
//but register ALL vid_ commands. //but register ALL vid_ commands.
Cvar_Register (&gl_driver, GLRENDEREROPTIONS); Cvar_Register (&gl_driver, GLRENDEREROPTIONS);
Cvar_Register (&_vid_wait_override, VIDCOMMANDGROUP); Cvar_Register (&vid_vsync, VIDCOMMANDGROUP);
Cvar_Register (&_windowed_mouse, VIDCOMMANDGROUP); Cvar_Register (&_windowed_mouse, VIDCOMMANDGROUP);
Cvar_Register (&vid_renderer, VIDCOMMANDGROUP); Cvar_Register (&vid_renderer, VIDCOMMANDGROUP);
Cvar_Register (&vid_wndalpha, VIDCOMMANDGROUP); Cvar_Register (&vid_wndalpha, VIDCOMMANDGROUP);
@ -1360,10 +1356,10 @@ qboolean R_BuildRenderstate(rendererstate_t *newr, char *rendererstring)
newr->rate = vid_refreshrate.value; newr->rate = vid_refreshrate.value;
newr->stereo = (r_stereo_method.ival == 1); newr->stereo = (r_stereo_method.ival == 1);
if (!*_vid_wait_override.string || _vid_wait_override.value < 0) if (!*vid_vsync.string || vid_vsync.value < 0)
newr->wait = -1; newr->wait = -1;
else else
newr->wait = _vid_wait_override.value; newr->wait = vid_vsync.value;
newr->renderer = NULL; newr->renderer = NULL;

View file

@ -28,7 +28,7 @@ typedef struct {
roq_cell cells[256]; roq_cell cells[256];
roq_qcell qcells[256]; roq_qcell qcells[256];
short snd_sqr_arr[256]; short snd_sqr_arr[256];
long roq_start, aud_pos, vid_pos; qofs_t roq_start, aud_pos, vid_pos;
long *frame_offset; long *frame_offset;
unsigned long num_frames, num_audio_bytes; unsigned long num_frames, num_audio_bytes;
int width, height, frame_num, audio_channels; int width, height, frame_num, audio_channels;

View file

@ -70,7 +70,7 @@ static int roq_parse_file(vfsfile_t *fp, roq_info *ri)
{ {
unsigned int head1, head3, chunk_id;//, chunk_arg; unsigned int head1, head3, chunk_id;//, chunk_arg;
long head2, chunk_size; long head2, chunk_size;
long fpos; qofs_t fpos;
#ifndef FAST #ifndef FAST
int max_frame; int max_frame;
#endif #endif
@ -400,7 +400,7 @@ unsigned char *tp, *buf;
int frame_stats[2][4] = {{0},{0}}; int frame_stats[2][4] = {{0},{0}};
roq_qcell *qcell; roq_qcell *qcell;
long fpos = ri->vid_pos; qofs_t fpos = ri->vid_pos;
VFS_SEEK(fp, fpos); VFS_SEEK(fp, fpos);
while(fpos+8 < ri->maxpos) while(fpos+8 < ri->maxpos)

View file

@ -50,7 +50,7 @@ vec3_t listener_up = {0, 0, 1};
vec3_t listener_velocity; vec3_t listener_velocity;
vec_t sound_nominal_clip_dist=1000.0; vec_t sound_nominal_clip_dist=1000.0;
#define MAX_SFX 2048 #define MAX_SFX 8192
sfx_t *known_sfx; // hunk allocated [MAX_SFX] sfx_t *known_sfx; // hunk allocated [MAX_SFX]
int num_sfx; int num_sfx;
@ -3085,9 +3085,9 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
{ {
soundcardinfo_t *si; soundcardinfo_t *si;
int i; int i;
int prepadl; int prepadl; //this is the amount of data that was previously available, and will be removed from the buffer.
int spare; int spare; //the amount of existing data that is still left to be played
int outsamples; int outsamples; //the amount of data we're going to add (at the output rate)
double speedfactor; double speedfactor;
qbyte *newcache; qbyte *newcache;
streaming_t *s, *free=NULL; streaming_t *s, *free=NULL;
@ -3150,7 +3150,7 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
s->width = width; s->width = width;
s->numchannels = channels; s->numchannels = channels;
s->length = 0; s->length = 0;
// Con_Printf("Restarting raw stream\n"); Con_Printf("Restarting raw stream\n");
} }
speedfactor = (double)speed/snd_speed; speedfactor = (double)speed/snd_speed;
@ -3188,7 +3188,7 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
if (spare < 0) //remaining samples since last time if (spare < 0) //remaining samples since last time
spare = 0; spare = 0;
if (spare > snd_speed*2) // more than 2 seconds of sound if (spare > snd_speed*2) // more than 2 seconds of sound. don't buffer more than 2 seconds. 1: its probably buggy if we need to. 2: takes too much memory, and we use malloc+copies.
{ {
Con_DPrintf("Sacrificed raw sound stream\n"); Con_DPrintf("Sacrificed raw sound stream\n");
spare = 0; //too far out. sacrifice it all spare = 0; //too far out. sacrifice it all

View file

@ -104,16 +104,16 @@ CHANNEL MIXING
=============================================================================== ===============================================================================
*/ */
void SND_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int endtime); static void SND_PaintChannel8_O2I1 (channel_t *ch, sfxcache_t *sc, int starttime, int count);
void SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int endtime); static void SND_PaintChannel16_O2I1 (channel_t *ch, sfxcache_t *sc, int starttime, int count);
void SND_PaintChannelFrom8_4Speaker (channel_t *ch, sfxcache_t *sc, int count); static void SND_PaintChannel8_O4I1 (channel_t *ch, sfxcache_t *sc, int count);
void SND_PaintChannelFrom16_4Speaker (channel_t *ch, sfxcache_t *sc, int count); static void SND_PaintChannel16_O4I1 (channel_t *ch, sfxcache_t *sc, int count);
void SND_PaintChannelFrom8_6Speaker (channel_t *ch, sfxcache_t *sc, int count); static void SND_PaintChannel8_O6I1 (channel_t *ch, sfxcache_t *sc, int count);
void SND_PaintChannelFrom16_6Speaker (channel_t *ch, sfxcache_t *sc, int count); static void SND_PaintChannel16_O6I1 (channel_t *ch, sfxcache_t *sc, int count);
void SND_PaintChannelFrom8_8Speaker (channel_t *ch, sfxcache_t *sc, int count); static void SND_PaintChannel8_O8I1 (channel_t *ch, sfxcache_t *sc, int count);
void SND_PaintChannelFrom16_8Speaker (channel_t *ch, sfxcache_t *sc, int count); static void SND_PaintChannel16_O8I1 (channel_t *ch, sfxcache_t *sc, int count);
void SND_PaintChannelFrom8Stereo (channel_t *ch, sfxcache_t *sc, int count); static void SND_PaintChannel8_O2I2 (channel_t *ch, sfxcache_t *sc, int starttime, int count);
void SND_PaintChannelFrom16Stereo (channel_t *ch, sfxcache_t *sc, int count); static void SND_PaintChannel16_O2I2 (channel_t *ch, sfxcache_t *sc, int starttime, int count);
//NOTE: MAY NOT CALL SYS_ERROR //NOTE: MAY NOT CALL SYS_ERROR
void S_PaintChannels(soundcardinfo_t *sc, int endtime) void S_PaintChannels(soundcardinfo_t *sc, int endtime)
@ -216,28 +216,28 @@ void S_PaintChannels(soundcardinfo_t *sc, int endtime)
if (scache->width == 1) if (scache->width == 1)
{ {
if (scache->numchannels==2) if (scache->numchannels==2)
SND_PaintChannelFrom8Stereo(ch, scache, count); SND_PaintChannel8_O2I2(ch, scache, ltime-sc->paintedtime, count);
else if (sc->sn.numchannels == 8) else if (sc->sn.numchannels <= 2)
SND_PaintChannelFrom8_8Speaker(ch, scache, count); SND_PaintChannel8_O2I1(ch, scache, ltime-sc->paintedtime, count);
else if (sc->sn.numchannels == 6) else if (sc->sn.numchannels <= 4)
SND_PaintChannelFrom8_6Speaker(ch, scache, count); SND_PaintChannel8_O4I1(ch, scache, count);
else if (sc->sn.numchannels == 4) else if (sc->sn.numchannels <= 6)
SND_PaintChannelFrom8_4Speaker(ch, scache, count); SND_PaintChannel8_O6I1(ch, scache, count);
else else
SND_PaintChannelFrom8(ch, scache, count); SND_PaintChannel8_O8I1(ch, scache, count);
} }
else else
{ {
if (scache->numchannels==2) if (scache->numchannels==2)
SND_PaintChannelFrom16Stereo(ch, scache, count); SND_PaintChannel16_O2I2(ch, scache, ltime-sc->paintedtime, count);
else if (sc->sn.numchannels == 8) else if (sc->sn.numchannels <= 2)
SND_PaintChannelFrom16_8Speaker(ch, scache, count); SND_PaintChannel16_O2I1(ch, scache, ltime-sc->paintedtime, count);
else if (sc->sn.numchannels == 6) else if (sc->sn.numchannels <= 4)
SND_PaintChannelFrom16_6Speaker(ch, scache, count); SND_PaintChannel16_O4I1(ch, scache, count);
else if (sc->sn.numchannels == 4) else if (sc->sn.numchannels <= 6)
SND_PaintChannelFrom16_4Speaker(ch, scache, count); SND_PaintChannel16_O6I1(ch, scache, count);
else else
SND_PaintChannelFrom16(ch, scache, count); SND_PaintChannel16_O8I1(ch, scache, count);
} }
ltime += count; ltime += count;
ch->pos += ch->rate * count; ch->pos += ch->rate * count;
@ -282,7 +282,7 @@ void S_PaintChannels(soundcardinfo_t *sc, int endtime)
} }
} }
void SND_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int count) static void SND_PaintChannel8_O2I1 (channel_t *ch, sfxcache_t *sc, int starttime, int count)
{ {
int data; int data;
signed char *sfx; signed char *sfx;
@ -296,8 +296,8 @@ void SND_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int count)
{ {
data = sfx[pos>>PITCHSHIFT]; data = sfx[pos>>PITCHSHIFT];
pos += ch->rate; pos += ch->rate;
paintbuffer[i].s[0] += ch->vol[0] * data; paintbuffer[starttime+i].s[0] += ch->vol[0] * data;
paintbuffer[i].s[1] += ch->vol[1] * data; paintbuffer[starttime+i].s[1] += ch->vol[1] * data;
} }
} }
else else
@ -306,13 +306,13 @@ void SND_PaintChannelFrom8 (channel_t *ch, sfxcache_t *sc, int count)
for (i=0 ; i<count ; i++) for (i=0 ; i<count ; i++)
{ {
data = sfx[i]; data = sfx[i];
paintbuffer[i].s[0] += ch->vol[0] * data; paintbuffer[starttime+i].s[0] += ch->vol[0] * data;
paintbuffer[i].s[1] += ch->vol[1] * data; paintbuffer[starttime+i].s[1] += ch->vol[1] * data;
} }
} }
} }
void SND_PaintChannelFrom8Stereo (channel_t *ch, sfxcache_t *sc, int count) static void SND_PaintChannel8_O2I2 (channel_t *ch, sfxcache_t *sc, int starttime, int count)
{ {
// int data; // int data;
signed char *sfx; signed char *sfx;
@ -324,8 +324,8 @@ void SND_PaintChannelFrom8Stereo (channel_t *ch, sfxcache_t *sc, int count)
sfx = (signed char *)sc->data; sfx = (signed char *)sc->data;
for (i=0 ; i<count ; i++) for (i=0 ; i<count ; i++)
{ {
paintbuffer[i].s[0] += ch->vol[0] * sfx[(pos>>(PITCHSHIFT-1))&~1]; paintbuffer[starttime+i].s[0] += ch->vol[0] * sfx[(pos>>(PITCHSHIFT-1))&~1];
paintbuffer[i].s[1] += ch->vol[1] * sfx[(pos>>(PITCHSHIFT-1))|1]; paintbuffer[starttime+i].s[1] += ch->vol[1] * sfx[(pos>>(PITCHSHIFT-1))|1];
pos += ch->rate; pos += ch->rate;
} }
} }
@ -334,13 +334,13 @@ void SND_PaintChannelFrom8Stereo (channel_t *ch, sfxcache_t *sc, int count)
sfx = (signed char *)sc->data + (pos>>PITCHSHIFT)*2; sfx = (signed char *)sc->data + (pos>>PITCHSHIFT)*2;
for (i=0 ; i<count ; i++) for (i=0 ; i<count ; i++)
{ {
paintbuffer[i].s[0] += ch->vol[0] * sfx[(i<<1)]; paintbuffer[starttime+i].s[0] += ch->vol[0] * sfx[(i<<1)];
paintbuffer[i].s[1] += ch->vol[1] * sfx[(i<<1)+1]; paintbuffer[starttime+i].s[1] += ch->vol[1] * sfx[(i<<1)+1];
} }
} }
} }
void SND_PaintChannelFrom8_4Speaker (channel_t *ch, sfxcache_t *sc, int count) static void SND_PaintChannel8_O4I1 (channel_t *ch, sfxcache_t *sc, int count)
{ {
signed char *sfx; signed char *sfx;
int i; int i;
@ -373,7 +373,7 @@ void SND_PaintChannelFrom8_4Speaker (channel_t *ch, sfxcache_t *sc, int count)
} }
} }
void SND_PaintChannelFrom8_6Speaker (channel_t *ch, sfxcache_t *sc, int count) static void SND_PaintChannel8_O6I1 (channel_t *ch, sfxcache_t *sc, int count)
{ {
signed char *sfx; signed char *sfx;
int i; int i;
@ -410,7 +410,7 @@ void SND_PaintChannelFrom8_6Speaker (channel_t *ch, sfxcache_t *sc, int count)
} }
} }
void SND_PaintChannelFrom8_8Speaker (channel_t *ch, sfxcache_t *sc, int count) static void SND_PaintChannel8_O8I1 (channel_t *ch, sfxcache_t *sc, int count)
{ {
signed char *sfx; signed char *sfx;
int i; int i;
@ -452,7 +452,7 @@ void SND_PaintChannelFrom8_8Speaker (channel_t *ch, sfxcache_t *sc, int count)
} }
void SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count) static void SND_PaintChannel16_O2I1 (channel_t *ch, sfxcache_t *sc, int starttime, int count)
{ {
int data; int data;
int left, right; int left, right;
@ -472,8 +472,8 @@ void SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count)
{ {
data = sfx[pos>>PITCHSHIFT]; data = sfx[pos>>PITCHSHIFT];
pos += ch->rate; pos += ch->rate;
paintbuffer[i].s[0] += (leftvol * data)>>8; paintbuffer[starttime+i].s[0] += (leftvol * data)>>8;
paintbuffer[i].s[1] += (rightvol * data)>>8; paintbuffer[starttime+i].s[1] += (rightvol * data)>>8;
} }
} }
else else
@ -484,13 +484,13 @@ void SND_PaintChannelFrom16 (channel_t *ch, sfxcache_t *sc, int count)
data = sfx[i]; data = sfx[i];
left = (data * leftvol) >> 8; left = (data * leftvol) >> 8;
right = (data * rightvol) >> 8; right = (data * rightvol) >> 8;
paintbuffer[i].s[0] += left; paintbuffer[starttime+i].s[0] += left;
paintbuffer[i].s[1] += right; paintbuffer[starttime+i].s[1] += right;
} }
} }
} }
void SND_PaintChannelFrom16Stereo (channel_t *ch, sfxcache_t *sc, int count) static void SND_PaintChannel16_O2I2 (channel_t *ch, sfxcache_t *sc, int starttime, int count)
{ {
int leftvol, rightvol; int leftvol, rightvol;
signed short *sfx; signed short *sfx;
@ -509,8 +509,8 @@ void SND_PaintChannelFrom16Stereo (channel_t *ch, sfxcache_t *sc, int count)
l = sfx[(pos>>(PITCHSHIFT-1))&~1]; l = sfx[(pos>>(PITCHSHIFT-1))&~1];
r = sfx[(pos>>(PITCHSHIFT-1))|1]; r = sfx[(pos>>(PITCHSHIFT-1))|1];
pos += ch->rate; pos += ch->rate;
paintbuffer[i].s[0] += (ch->vol[0] * l)>>8; paintbuffer[starttime+i].s[0] += (ch->vol[0] * l)>>8;
paintbuffer[i].s[1] += (ch->vol[1] * r)>>8; paintbuffer[starttime+i].s[1] += (ch->vol[1] * r)>>8;
} }
} }
else else
@ -518,13 +518,13 @@ void SND_PaintChannelFrom16Stereo (channel_t *ch, sfxcache_t *sc, int count)
sfx = (signed short *)sc->data + (pos>>PITCHSHIFT)*2; sfx = (signed short *)sc->data + (pos>>PITCHSHIFT)*2;
for (i=0 ; i<count ; i++) for (i=0 ; i<count ; i++)
{ {
paintbuffer[i].s[0] += (*sfx++ * leftvol) >> 8; paintbuffer[starttime+i].s[0] += (*sfx++ * leftvol) >> 8;
paintbuffer[i].s[1] += (*sfx++ * rightvol) >> 8; paintbuffer[starttime+i].s[1] += (*sfx++ * rightvol) >> 8;
} }
} }
} }
void SND_PaintChannelFrom16_4Speaker (channel_t *ch, sfxcache_t *sc, int count) static void SND_PaintChannel16_O4I1 (channel_t *ch, sfxcache_t *sc, int count)
{ {
int vol[4]; int vol[4];
signed short *sfx; signed short *sfx;
@ -563,7 +563,7 @@ void SND_PaintChannelFrom16_4Speaker (channel_t *ch, sfxcache_t *sc, int count)
} }
} }
void SND_PaintChannelFrom16_6Speaker (channel_t *ch, sfxcache_t *sc, int count) static void SND_PaintChannel16_O6I1 (channel_t *ch, sfxcache_t *sc, int count)
{ {
int vol[6]; int vol[6];
signed short *sfx; signed short *sfx;
@ -608,7 +608,7 @@ void SND_PaintChannelFrom16_6Speaker (channel_t *ch, sfxcache_t *sc, int count)
} }
} }
void SND_PaintChannelFrom16_8Speaker (channel_t *ch, sfxcache_t *sc, int count) static void SND_PaintChannel16_O8I1 (channel_t *ch, sfxcache_t *sc, int count)
{ {
int vol[8]; int vol[8];
signed short *sfx; signed short *sfx;

View file

@ -461,7 +461,7 @@ void Sys_SaveClipboard(char *text)
} }
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, int, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath) int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, qofs_t, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath)
{ {
DIR *dir; DIR *dir;
char apath[MAX_OSPATH]; char apath[MAX_OSPATH];
@ -537,7 +537,7 @@ int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const
#if 0 #if 0
#include <android/asset_manager.h> #include <android/asset_manager.h>
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, int, void *), void *parm) int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, qofs_t, void *), void *parm)
{ {
qboolean go = true; qboolean go = true;
const char *f; const char *f;

View file

@ -408,7 +408,7 @@ int Sys_DebugLog(char *file, char *fmt, ...)
return 1; return 1;
} }
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, int, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath) int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, qofs_t, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath)
{ {
DIR *dir; DIR *dir;
char apath[MAX_OSPATH]; char apath[MAX_OSPATH];
@ -566,7 +566,7 @@ dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs)
lib = NULL; lib = NULL;
if (!lib) if (!lib)
lib = dlopen (name, RTLD_LAZY); lib = dlopen (name, RTLD_LAZY);
if (!lib && strcmp(COM_FileExtension(name), "so")) if (!lib && !strstr(name, ".so"))
lib = dlopen (va("%s.so", name), RTLD_LAZY); lib = dlopen (va("%s.so", name), RTLD_LAZY);
if (!lib) if (!lib)
{ {

View file

@ -199,7 +199,7 @@ int Sys_FileTime(char *path)
return ret; return ret;
} }
int Sys_EnumerateFiles(const char *gpath, const char *match, int (*func)(const char *, int, void *), void *parm) int Sys_EnumerateFiles(const char *gpath, const char *match, int (*func)(const char *, qofs_t, void *), void *parm)
{ {
char *pattern; char *pattern;
char pattrans[256]; char pattrans[256];

View file

@ -19,9 +19,14 @@
#include <emscripten/emscripten.h> #include <emscripten/emscripten.h>
#endif #endif
#if SDL_MAJOR_VERSION >= 2
SDL_Window *sdlwindow;
#endif
#ifndef isDedicated #ifndef isDedicated
qboolean isDedicated; qboolean isDedicated;
#endif #endif
extern qboolean ActiveApp;
void Sys_Error (const char *error, ...) void Sys_Error (const char *error, ...)
{ {
@ -33,9 +38,11 @@ void Sys_Error (const char *error, ...)
va_end (argptr); va_end (argptr);
fprintf(stderr, "Error: %s\n", string); fprintf(stderr, "Error: %s\n", string);
Con_Print ("Quake Error: "); Sys_Printf ("Quake Error: %s\n", string);
Con_Print (string);
Con_Print ("\n"); #if SDL_MAJOR_VERSION >= 2
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Sys_Error", string, sdlwindow);
#endif
if (COM_CheckParm("-crashonerror")) if (COM_CheckParm("-crashonerror"))
*(int*)-3 = 0; *(int*)-3 = 0;
@ -122,7 +129,8 @@ void Sys_mkdir (char *path)
#if WIN32 #if WIN32
_mkdir (path); _mkdir (path);
#else #else
mkdir (path, 0777); //WARNING: DO NOT RUN AS ROOT! //user, group, others
mkdir (path, 0755); //WARNING: DO NOT RUN AS ROOT!
#endif #endif
} }
@ -152,7 +160,7 @@ void Sys_Quit (void)
//SDL provides no file enumeration facilities. //SDL provides no file enumeration facilities.
#if defined(_WIN32) #if defined(_WIN32)
#include <windows.h> #include <windows.h>
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, int, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath) int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, qofs_t, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath)
{ {
HANDLE r; HANDLE r;
WIN32_FIND_DATA fd; WIN32_FIND_DATA fd;
@ -218,7 +226,7 @@ int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const
} }
#elif defined(linux) || defined(__unix__) || defined(__MACH__) #elif defined(linux) || defined(__unix__) || defined(__MACH__)
#include <dirent.h> #include <dirent.h>
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, int, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath) int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, qofs_t, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath)
{ {
DIR *dir; DIR *dir;
char apath[MAX_OSPATH]; char apath[MAX_OSPATH];
@ -292,7 +300,7 @@ int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const
return true; return true;
} }
#else #else
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, int, void *, void *), void *parm, void *spath) int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, qofs_t, void *, void *), void *parm, void *spath)
{ {
Con_Printf("Warning: Sys_EnumerateFiles not implemented\n"); Con_Printf("Warning: Sys_EnumerateFiles not implemented\n");
return false; return false;
@ -497,8 +505,13 @@ int QDECL main(int argc, char **argv)
double sleeptime; double sleeptime;
// yield the CPU for a little while when paused, minimized, or not the focus // yield the CPU for a little while when paused, minimized, or not the focus
if (!(SDL_GetAppState() & SDL_APPACTIVE)) #if SDL_MAJOR_VERSION >= 2
if (!ActiveApp)
SDL_Delay(1); SDL_Delay(1);
#else
if (!(SDL_GetAppState() & SDL_APPINPUTFOCUS))
SDL_Delay(1);
#endif
newtime = Sys_DoubleTime (); newtime = Sys_DoubleTime ();
time = newtime - oldtime; time = newtime - oldtime;
@ -536,12 +549,23 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refreshrate) qboolean Sys_GetDesktopParameters(int *width, int *height, int *bpp, int *refreshrate)
{ {
#if SDL_MAJOR_VERSION >= 2
SDL_DisplayMode mode;
if (!SDL_GetDesktopDisplayMode(0, &mode))
{
*width = mode.w;
*height = mode.h;
*bpp = (SDL_PIXELTYPE(mode.format) == SDL_PIXELTYPE_PACKED32)?32:16;
*refreshrate = mode.refresh_rate;
return true;
}
#endif
return false; return false;
} }
#if SDL_MAJOR_VERSION >= 2 //probably could inclued 1.3 #if SDL_MAJOR_VERSION >= 2 //probably could include 1.3
#include <SDL_clipboard.h> #include <SDL_clipboard.h>
char *Sys_GetClipboard(void) char *Sys_GetClipboard(void)
{ {
@ -549,7 +573,7 @@ char *Sys_GetClipboard(void)
} }
void Sys_CloseClipboard(char *bf) void Sys_CloseClipboard(char *bf)
{ {
SDL_Free(bf); SDL_free(bf);
} }
void Sys_SaveClipboard(char *text) void Sys_SaveClipboard(char *text)
{ {
@ -578,7 +602,11 @@ void Sys_SaveClipboard(char *text)
void *Sys_CreateThread(char *name, int (*func)(void *), void *args, int priority, int stacksize) void *Sys_CreateThread(char *name, int (*func)(void *), void *args, int priority, int stacksize)
{ {
// SDL threads do not support setting thread stack size // SDL threads do not support setting thread stack size
#if SDL_MAJOR_VERSION >= 2
return (void *)SDL_CreateThread(func, name, args);
#else
return (void *)SDL_CreateThread(func, args); return (void *)SDL_CreateThread(func, args);
#endif
} }
void Sys_WaitOnThread(void *thread) void Sys_WaitOnThread(void *thread)

View file

@ -63,6 +63,8 @@ unsigned int sys_parentheight;
int qwinvermaj; int qwinvermaj;
int qwinvermin; int qwinvermin;
char *sys_argv[MAX_NUM_ARGVS];
#ifdef RESTARTTEST #ifdef RESTARTTEST
jmp_buf restart_jmpbuf; jmp_buf restart_jmpbuf;
@ -730,7 +732,7 @@ qboolean Sys_Rename (char *oldfname, char *newfname)
return !rename(oldfname, newfname); return !rename(oldfname, newfname);
} }
static int Sys_EnumerateFiles2 (const char *match, int matchstart, int neststart, int (QDECL *func)(const char *fname, int fsize, void *parm, searchpathfuncs_t *spath), void *parm, searchpathfuncs_t *spath) static int Sys_EnumerateFiles2 (const char *match, int matchstart, int neststart, int (QDECL *func)(const char *fname, qofs_t fsize, void *parm, searchpathfuncs_t *spath), void *parm, searchpathfuncs_t *spath)
{ {
qboolean go; qboolean go;
if (!WinNT) if (!WinNT)
@ -818,7 +820,7 @@ static int Sys_EnumerateFiles2 (const char *match, int matchstart, int neststart
if (strlen(tmproot+matchstart) + strlen(fd.cFileName) + 2 < MAX_OSPATH) if (strlen(tmproot+matchstart) + strlen(fd.cFileName) + 2 < MAX_OSPATH)
{ {
Q_snprintfz(file, sizeof(file), "%s%s/", tmproot+matchstart, fd.cFileName); Q_snprintfz(file, sizeof(file), "%s%s/", tmproot+matchstart, fd.cFileName);
go = func(file, fd.nFileSizeLow, parm, spath); go = func(file, qofs_Make(fd.nFileSizeLow, fd.nFileSizeHigh), parm, spath);
} }
} }
} }
@ -829,7 +831,7 @@ static int Sys_EnumerateFiles2 (const char *match, int matchstart, int neststart
if (strlen(tmproot+matchstart) + strlen(fd.cFileName) + 1 < MAX_OSPATH) if (strlen(tmproot+matchstart) + strlen(fd.cFileName) + 1 < MAX_OSPATH)
{ {
Q_snprintfz(file, sizeof(file), "%s%s", tmproot+matchstart, fd.cFileName); Q_snprintfz(file, sizeof(file), "%s%s", tmproot+matchstart, fd.cFileName);
go = func(file, fd.nFileSizeLow, parm, spath); go = func(file, qofs_Make(fd.nFileSizeLow, fd.nFileSizeHigh), parm, spath);
} }
} }
} }
@ -933,7 +935,7 @@ static int Sys_EnumerateFiles2 (const char *match, int matchstart, int neststart
if (strlen(tmproot+matchstart) + strlen(utf8) + 2 < MAX_OSPATH) if (strlen(tmproot+matchstart) + strlen(utf8) + 2 < MAX_OSPATH)
{ {
Q_snprintfz(file, sizeof(file), "%s%s/", tmproot+matchstart, utf8); Q_snprintfz(file, sizeof(file), "%s%s/", tmproot+matchstart, utf8);
go = func(file, fd.nFileSizeLow, parm, spath); go = func(file, qofs_Make(fd.nFileSizeLow, fd.nFileSizeHigh), parm, spath);
} }
} }
} }
@ -944,7 +946,7 @@ static int Sys_EnumerateFiles2 (const char *match, int matchstart, int neststart
if (strlen(tmproot+matchstart) + strlen(utf8) + 1 < MAX_OSPATH) if (strlen(tmproot+matchstart) + strlen(utf8) + 1 < MAX_OSPATH)
{ {
Q_snprintfz(file, sizeof(file), "%s%s", tmproot+matchstart, utf8); Q_snprintfz(file, sizeof(file), "%s%s", tmproot+matchstart, utf8);
go = func(file, fd.nFileSizeLow, parm, spath); go = func(file, qofs_Make(fd.nFileSizeLow, fd.nFileSizeHigh), parm, spath);
} }
} }
} }
@ -954,7 +956,7 @@ static int Sys_EnumerateFiles2 (const char *match, int matchstart, int neststart
} }
return go; return go;
} }
int Sys_EnumerateFiles (const char *gpath, const char *match, int (QDECL *func)(const char *fname, int fsize, void *parm, searchpathfuncs_t *spath), void *parm, searchpathfuncs_t *spath) int Sys_EnumerateFiles (const char *gpath, const char *match, int (QDECL *func)(const char *fname, qofs_t fsize, void *parm, searchpathfuncs_t *spath), void *parm, searchpathfuncs_t *spath)
{ {
char fullmatch[MAX_OSPATH]; char fullmatch[MAX_OSPATH];
int start; int start;
@ -1127,6 +1129,7 @@ void Sys_Init (void)
void Sys_Shutdown(void) void Sys_Shutdown(void)
{ {
int i;
if (tevent) if (tevent)
CloseHandle (tevent); CloseHandle (tevent);
tevent = NULL; tevent = NULL;
@ -1134,6 +1137,14 @@ void Sys_Shutdown(void)
if (qwclsemaphore) if (qwclsemaphore)
CloseHandle (qwclsemaphore); CloseHandle (qwclsemaphore);
qwclsemaphore = NULL; qwclsemaphore = NULL;
for (i = 0; i < MAX_NUM_ARGVS; i++)
{
if (!sys_argv[i])
break;
free(sys_argv[i]);
sys_argv[i] = NULL;
}
} }
@ -1762,7 +1773,6 @@ WinMain
*/ */
HINSTANCE global_hInstance; HINSTANCE global_hInstance;
int global_nCmdShow; int global_nCmdShow;
char *argv[MAX_NUM_ARGVS];
HWND hwnd_dialog; HWND hwnd_dialog;
@ -2105,9 +2115,9 @@ void Win7_TaskListInit(void)
#if defined(SVNREVISION) && !defined(MINIMAL) #if defined(SVNREVISION) && !defined(MINIMAL)
#define SVNREVISIONSTR STRINGIFY(SVNREVISION) #define SVNREVISIONSTR STRINGIFY(SVNREVISION)
#if defined(OFFICIAL_RELEASE) #if defined(OFFICIAL_RELEASE)
#define BUILDTYPE "rel" #define UPD_BUILDTYPE "rel"
#else #else
#define BUILDTYPE "test" #define UPD_BUILDTYPE "test"
#define UPDATE_URL "http://triptohell.info/moodles/" #define UPDATE_URL "http://triptohell.info/moodles/"
#define UPDATE_URL_VERSION UPDATE_URL "version.txt" #define UPDATE_URL_VERSION UPDATE_URL "version.txt"
#ifdef _WIN64 #ifdef _WIN64
@ -2285,7 +2295,7 @@ void Update_Version_Updated(struct dl_download *dl)
char pendingname[MAX_OSPATH]; char pendingname[MAX_OSPATH];
vfsfile_t *pending; vfsfile_t *pending;
Update_GetHomeDirectory(pendingname, sizeof(pendingname)); Update_GetHomeDirectory(pendingname, sizeof(pendingname));
Q_strncatz(pendingname, DISTRIBUTION BUILDTYPE EXETYPE".tmp", sizeof(pendingname)); Q_strncatz(pendingname, DISTRIBUTION UPD_BUILDTYPE EXETYPE".tmp", sizeof(pendingname));
Update_CreatePath(pendingname); Update_CreatePath(pendingname);
pending = VFSOS_Open(pendingname, "wb"); pending = VFSOS_Open(pendingname, "wb");
if (!pending) if (!pending)
@ -2302,7 +2312,7 @@ void Update_Version_Updated(struct dl_download *dl)
VFS_CLOSE(pending); VFS_CLOSE(pending);
if (VFS_GETLEN(dl->file) == size) if (VFS_GETLEN(dl->file) == size)
{ {
MyRegSetValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, "pending" BUILDTYPE EXETYPE, REG_SZ, pendingname, strlen(pendingname)+1); MyRegSetValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, "pending" UPD_BUILDTYPE EXETYPE, REG_SZ, pendingname, strlen(pendingname)+1);
} }
} }
} }
@ -2372,19 +2382,19 @@ qboolean Sys_CheckUpdated(void)
char pendingpath[MAX_OSPATH]; char pendingpath[MAX_OSPATH];
char updatedpath[MAX_OSPATH]; char updatedpath[MAX_OSPATH];
MyRegGetStringValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, "pending" BUILDTYPE EXETYPE, pendingpath, sizeof(pendingpath)); MyRegGetStringValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, "pending" UPD_BUILDTYPE EXETYPE, pendingpath, sizeof(pendingpath));
if (*pendingpath) if (*pendingpath)
{ {
MyRegDeleteKeyValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, "pending" BUILDTYPE EXETYPE); MyRegDeleteKeyValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, "pending" UPD_BUILDTYPE EXETYPE);
Update_GetHomeDirectory(updatedpath, sizeof(updatedpath)); Update_GetHomeDirectory(updatedpath, sizeof(updatedpath));
Update_CreatePath(updatedpath); Update_CreatePath(updatedpath);
Q_strncatz(updatedpath, "cur" BUILDTYPE EXETYPE".exe", sizeof(updatedpath)); Q_strncatz(updatedpath, "cur" UPD_BUILDTYPE EXETYPE".exe", sizeof(updatedpath));
DeleteFile(updatedpath); DeleteFile(updatedpath);
if (MoveFile(pendingpath, updatedpath)) if (MoveFile(pendingpath, updatedpath))
MyRegSetValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, BUILDTYPE EXETYPE, REG_SZ, updatedpath, strlen(updatedpath)+1); MyRegSetValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, UPD_BUILDTYPE EXETYPE, REG_SZ, updatedpath, strlen(updatedpath)+1);
} }
MyRegGetStringValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, BUILDTYPE EXETYPE, updatedpath, sizeof(updatedpath)); MyRegGetStringValue(HKEY_CURRENT_USER, "Software\\"FULLENGINENAME, UPD_BUILDTYPE EXETYPE, updatedpath, sizeof(updatedpath));
if (*updatedpath) if (*updatedpath)
{ {
@ -2638,9 +2648,11 @@ static int Sys_ProcessCommandline(char **argv, int maxargc, char *argv0)
} }
} }
} }
argv[argc] = argv0;
if (argc < 1) if (argc < 1)
{
argv[0] = argv0;
argc = 1; argc = 1;
}
for (i = 0; i < argc; i++) for (i = 0; i < argc; i++)
argv[i] = strdup(argv[i]); argv[i] = strdup(argv[i]);
return i; return i;
@ -2745,9 +2757,9 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
} }
else else
GetModuleFileNameA(NULL, bindir, sizeof(bindir)-1); GetModuleFileNameA(NULL, bindir, sizeof(bindir)-1);
parms.argc = Sys_ProcessCommandline(argv, MAX_NUM_ARGVS, bindir); parms.argc = Sys_ProcessCommandline(sys_argv, MAX_NUM_ARGVS, bindir);
*COM_SkipPath(bindir) = 0; *COM_SkipPath(bindir) = 0;
parms.argv = (const char **)argv; parms.argv = (const char **)sys_argv;
host_parms.binarydir = bindir; host_parms.binarydir = bindir;
COM_InitArgv (parms.argc, parms.argv); COM_InitArgv (parms.argc, parms.argv);

View file

@ -61,8 +61,14 @@ typedef struct
qboolean isminimized; //can omit rendering as it won't be seen anyway. qboolean isminimized; //can omit rendering as it won't be seen anyway.
int fullbright; // index of first fullbright color int fullbright; // index of first fullbright color
unsigned width; /*virtual 2d width*/ unsigned fbvwidth; /*virtual 2d width*/
unsigned height; /*virtual 2d height*/ unsigned fbvheight; /*virtual 2d height*/
unsigned fbpwidth; /*virtual 2d width*/
unsigned fbpheight; /*virtual 2d height*/
unsigned width; /*virtual 2d screen width*/
unsigned height; /*virtual 2d screen height*/
int numpages; int numpages;
unsigned rotpixelwidth; /*width after rotation in pixels*/ unsigned rotpixelwidth; /*width after rotation in pixels*/

View file

@ -145,15 +145,15 @@ float V_CalcBob (playerview_t *pv, qboolean queryold)
if (cl.spectator) if (cl.spectator)
return 0; return 0;
if (cl_bobcycle.value <= 0 || cl.intermission)
return 0;
if (!pv->onground || cl.paused) if (!pv->onground || cl.paused)
{ {
pv->bobcltime = cl.time; pv->bobcltime = cl.time;
return pv->bob; // just use old value return pv->bob; // just use old value
} }
if (cl_bobcycle.value <= 0)
return 0;
pv->bobtime += cl.time - pv->bobcltime; pv->bobtime += cl.time - pv->bobcltime;
pv->bobcltime = cl.time; pv->bobcltime = cl.time;
cycle = pv->bobtime - (int)(pv->bobtime/cl_bobcycle.value)*cl_bobcycle.value; cycle = pv->bobtime - (int)(pv->bobtime/cl_bobcycle.value)*cl_bobcycle.value;
@ -1158,9 +1158,11 @@ void V_ApplyRefdef (void)
} }
//if the view entities differ, removes all externalmodel flags except for adding it to the new entity, and removes weaponmodels. //if the view entities differ, removes all externalmodel flags except for adding it to the new entity, and removes weaponmodels.
void CL_EditExternalModels(int newviewentity) //returns the number of view entities that were stripped out
int CL_EditExternalModels(int newviewentity, entity_t *viewentities, int maxviewenties)
{ {
int i; int i;
int viewents = 0;
for (i = 0; i < cl_numvisedicts; ) for (i = 0; i < cl_numvisedicts; )
{ {
if (cl_visedicts[i].keynum == newviewentity && newviewentity) if (cl_visedicts[i].keynum == newviewentity && newviewentity)
@ -1170,12 +1172,15 @@ void CL_EditExternalModels(int newviewentity)
if (cl_visedicts[i].flags & Q2RF_WEAPONMODEL) if (cl_visedicts[i].flags & Q2RF_WEAPONMODEL)
{ {
if (viewents < maxviewenties)
viewentities[viewents++] = cl_visedicts[i];
memmove(&cl_visedicts[i], &cl_visedicts[i+1], sizeof(*cl_visedicts) * (cl_numvisedicts-(i+1))); memmove(&cl_visedicts[i], &cl_visedicts[i+1], sizeof(*cl_visedicts) * (cl_numvisedicts-(i+1)));
cl_numvisedicts--; cl_numvisedicts--;
} }
else else
i++; i++;
} }
return viewents;
} }
/* /*
@ -1197,6 +1202,10 @@ void V_ClearRefdef(playerview_t *pv)
r_refdef.drawsbar = !cl.intermission; r_refdef.drawsbar = !cl.intermission;
r_refdef.flags = 0; r_refdef.flags = 0;
// memset(r_refdef.postprocshader, 0, sizeof(r_refdef.postprocshader));
// memset(r_refdef.postprocsize, 0, sizeof(r_refdef.postprocsize));
// r_refdef.postproccube = 0;
} }
/* /*
@ -1491,6 +1500,7 @@ void V_RenderPlayerViews(playerview_t *pv)
VectorCopy(pv->cam_desired_position, r_refdef.vieworg); VectorCopy(pv->cam_desired_position, r_refdef.vieworg);
R_RenderView (); R_RenderView ();
} }
r_secondaryview = true;
#ifdef SIDEVIEWS #ifdef SIDEVIEWS
@ -1514,8 +1524,6 @@ void V_RenderPlayerViews(playerview_t *pv)
float ofx; float ofx;
float ofy; float ofy;
r_secondaryview = true;
if (vsec_x[viewnum].value < 0) if (vsec_x[viewnum].value < 0)
vsec_x[viewnum].value = 0; vsec_x[viewnum].value = 0;
if (vsec_y[viewnum].value < 0) if (vsec_y[viewnum].value < 0)
@ -1536,6 +1544,10 @@ void V_RenderPlayerViews(playerview_t *pv)
r_refdef.vrect.y += r_refdef.vrect.height*vsec_y[viewnum].value; r_refdef.vrect.y += r_refdef.vrect.height*vsec_y[viewnum].value;
r_refdef.vrect.width *= vsec_scalex[viewnum].value; r_refdef.vrect.width *= vsec_scalex[viewnum].value;
r_refdef.vrect.height *= vsec_scaley[viewnum].value; r_refdef.vrect.height *= vsec_scaley[viewnum].value;
r_refdef.fov_x = 0;
r_refdef.fov_y = 0;
V_ApplyAFov(NULL);
#ifdef PEXT_VIEW2 #ifdef PEXT_VIEW2
//secondary view entity. //secondary view entity.
e=NULL; e=NULL;
@ -1565,7 +1577,7 @@ void V_RenderPlayerViews(playerview_t *pv)
} }
CL_EditExternalModels(e->keynum); CL_EditExternalModels(e->keynum, NULL, 0);
R_RenderView (); R_RenderView ();
// r_framecount = old_framecount; // r_framecount = old_framecount;
@ -1579,7 +1591,7 @@ void V_RenderPlayerViews(playerview_t *pv)
r_refdef.viewangles[PITCH] *= -cos((vsec_yaw[viewnum].value / 180 * 3.14)+3.14); r_refdef.viewangles[PITCH] *= -cos((vsec_yaw[viewnum].value / 180 * 3.14)+3.14);
if (vsec_enabled[viewnum].value!=2) if (vsec_enabled[viewnum].value!=2)
{ {
CL_EditExternalModels(0); CL_EditExternalModels(0, NULL, 0);
R_RenderView (); R_RenderView ();
} }
} }
@ -1612,7 +1624,7 @@ void V_RenderView (void)
if (viewnum) if (viewnum)
{ {
//should be enough to just hack a few things. //should be enough to just hack a few things.
CL_EditExternalModels(cl.playerview[viewnum].viewentity); CL_EditExternalModels(cl.playerview[viewnum].viewentity, NULL, 0);
} }
else else
{ {

View file

@ -3541,7 +3541,10 @@ void CL_Say (qboolean team, char *extra)
CLQ3_SendClientCommand("%s %s%s", team ? "say_team" : "say", extra?extra:"", sendtext); CLQ3_SendClientCommand("%s %s%s", team ? "say_team" : "say", extra?extra:"", sendtext);
else else
#endif #endif
CL_SendClientCommand(true, "%s \"%s%s\"", team ? "say_team" : "say", extra?extra:"", sendtext); {
int split = CL_TargettedSplit(true);
CL_SendClientCommand(true, "%s%s \"%s%s\"", split?va("%i ", split+1):"", team ? "say_team" : "say", extra?extra:"", sendtext);
}
} }

View file

@ -588,7 +588,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define MAX_SSPARTICLESPRE 1024 // precached particle effect names, for server-side pointparticles/trailparticles. #define MAX_SSPARTICLESPRE 1024 // precached particle effect names, for server-side pointparticles/trailparticles.
#define MAX_VWEP_MODELS 32 #define MAX_VWEP_MODELS 32
#define MAX_CSMODELS 512 // these live entirly clientside #define MAX_CSMODELS 1024 // these live entirly clientside
#define MAX_CSPARTICLESPRE 1024 #define MAX_CSPARTICLESPRE 1024
#define SAVEGAME_COMMENT_LENGTH 39 #define SAVEGAME_COMMENT_LENGTH 39

View file

@ -526,9 +526,9 @@ void Cmd_Exec_f (void)
else else
Q_strncpyz(name, Cmd_Argv(1), sizeof(name)); Q_strncpyz(name, Cmd_Argv(1), sizeof(name));
if (FS_LoadFile(name, (void **)&f) != -1) if (!qofs_Error(FS_LoadFile(name, (void **)&f)))
; ;
else if (FS_LoadFile(va("%s.cfg", name), (void **)&f) != -1) else if (!qofs_Error(FS_LoadFile(va("%s.cfg", name), (void **)&f)))
; ;
else else
{ {
@ -1928,7 +1928,13 @@ void Cmd_ForwardToServer_f (void)
} }
if (Cmd_Argc() > 1) if (Cmd_Argc() > 1)
CL_SendClientCommand(true, "%s", Cmd_Args()); {
int split = CL_TargettedSplit(true);
if (split)
CL_SendClientCommand(true, "%i %s", split+1, Cmd_Args());
else
CL_SendClientCommand(true, "%s", Cmd_Args());
}
} }
#else #else
void Cmd_ForwardToServer (void) void Cmd_ForwardToServer (void)

View file

@ -2270,7 +2270,7 @@ static void Mod_FloodFillSkin( qbyte *skin, int skinwidth, int skinheight )
char ** skinfilelist; char ** skinfilelist;
int skinfilecount; int skinfilecount;
static qboolean VARGS Mod_TryAddSkin(const char *skinname, ...) static qboolean VARGS Mod_TryAddSkin(qboolean force, const char *skinname, ...)
{ {
va_list argptr; va_list argptr;
char string[MAX_QPATH]; char string[MAX_QPATH];
@ -2290,7 +2290,7 @@ static qboolean VARGS Mod_TryAddSkin(const char *skinname, ...)
return true; //already added return true; //already added
} }
if (!COM_FCheckExists(string)) if (!force && !COM_FCheckExists(string))
return false; return false;
skinfilelist = BZ_Realloc(skinfilelist, sizeof(*skinfilelist)*(skinfilecount+1)); skinfilelist = BZ_Realloc(skinfilelist, sizeof(*skinfilelist)*(skinfilecount+1));
@ -2300,13 +2300,13 @@ static qboolean VARGS Mod_TryAddSkin(const char *skinname, ...)
return true; return true;
} }
int QDECL Mod_EnumerateSkins(const char *name, int size, void *param, searchpathfuncs_t *spath) int QDECL Mod_EnumerateSkins(const char *name, qofs_t size, void *param, searchpathfuncs_t *spath)
{ {
Mod_TryAddSkin(name); Mod_TryAddSkin(false, name);
return true; return true;
} }
int Mod_BuildSkinFileList(char *modelname) int Mod_BuildSkinFileList(qboolean forcedefault, char *modelname)
{ {
int i; int i;
char skinfilename[MAX_QPATH]; char skinfilename[MAX_QPATH];
@ -2324,31 +2324,31 @@ int Mod_BuildSkinFileList(char *modelname)
//try and add numbered skins, and then try fixed names. //try and add numbered skins, and then try fixed names.
for (i = 0; ; i++) for (i = 0; ; i++)
{ {
if (!Mod_TryAddSkin("%s_%i.skin", modelname, i)) if (!Mod_TryAddSkin(false, "%s_%i.skin", modelname, i))
{ {
if (i == 0) if (i == 0)
{ {
if (!Mod_TryAddSkin("%s_default.skin", skinfilename, i)) if (!Mod_TryAddSkin(forcedefault, "%s_default.skin", skinfilename, i))
break; break;
} }
else if (i == 1) else if (i == 1)
{ {
if (!Mod_TryAddSkin("%s_blue.skin", skinfilename, i)) if (!Mod_TryAddSkin(false, "%s_blue.skin", skinfilename, i))
break; break;
} }
else if (i == 2) else if (i == 2)
{ {
if (!Mod_TryAddSkin("%s_red.skin", skinfilename, i)) if (!Mod_TryAddSkin(false, "%s_red.skin", skinfilename, i))
break; break;
} }
else if (i == 3) else if (i == 3)
{ {
if (!Mod_TryAddSkin("%s_green.skin", skinfilename, i)) if (!Mod_TryAddSkin(false, "%s_green.skin", skinfilename, i))
break; break;
} }
else if (i == 4) else if (i == 4)
{ {
if (!Mod_TryAddSkin("%s_yellow.skin", skinfilename, i)) if (!Mod_TryAddSkin(false, "%s_yellow.skin", skinfilename, i))
break; break;
} }
else else
@ -2442,11 +2442,11 @@ void Mod_ParseQ3SkinFile(char *out, char *surfname, char *modelname, int skinnum
} }
#if defined(D3DQUAKE) || defined(GLQUAKE) #if defined(D3DQUAKE) || defined(GLQUAKE)
shader_t *Mod_LoadSkinFile(char *surfacename, int skinnumber, unsigned char *rawdata, int width, int height, unsigned char *palette) shader_t *Mod_LoadSkinFile(char *defaultshadername, char *surfacename, int skinnumber, unsigned char *rawdata, int width, int height, unsigned char *palette)
{ {
shader_t *shader; shader_t *shader;
char shadername[MAX_QPATH]; char shadername[MAX_QPATH];
Q_strncpyz(shadername, surfacename, sizeof(shadername)); Q_strncpyz(shadername, defaultshadername?defaultshadername:surfacename, sizeof(shadername));
Mod_ParseQ3SkinFile(shadername, surfacename, loadmodel->name, skinnumber, NULL); Mod_ParseQ3SkinFile(shadername, surfacename, loadmodel->name, skinnumber, NULL);
@ -4164,7 +4164,7 @@ qboolean QDECL Mod_LoadQ3Model(model_t *mod, void *buffer)
root = NULL; root = NULL;
#ifndef SERVERONLY #ifndef SERVERONLY
externalskins = Mod_BuildSkinFileList(mod->name); externalskins = Mod_BuildSkinFileList(false, mod->name);
#else #else
externalskins = 0; externalskins = 0;
#endif #endif
@ -4610,9 +4610,7 @@ qboolean QDECL Mod_LoadZymoticModel(model_t *mod, void *buffer)
} }
#ifndef SERVERONLY #ifndef SERVERONLY
skinfiles = Mod_BuildSkinFileList(loadmodel->name); skinfiles = Mod_BuildSkinFileList(true, loadmodel->name);
if (skinfiles < 1)
skinfiles = 1;
#endif #endif
for (i = 0; i < header->numsurfaces; i++, surfname+=32) for (i = 0; i < header->numsurfaces; i++, surfname+=32)
@ -4633,7 +4631,7 @@ qboolean QDECL Mod_LoadZymoticModel(model_t *mod, void *buffer)
skin[j].numshaders = 1; //non-sequenced skins. skin[j].numshaders = 1; //non-sequenced skins.
skin[j].ofsshaders = shaders; skin[j].ofsshaders = shaders;
shaders[0] = Mod_LoadSkinFile(surfname, j, NULL, 0, 0, NULL); shaders[0] = Mod_LoadSkinFile(NULL, surfname, j, NULL, 0, 0, NULL);
} }
root[i].ofsskins = skin; root[i].ofsskins = skin;
@ -5657,9 +5655,7 @@ qboolean QDECL Mod_LoadDarkPlacesModel(model_t *mod, void *buffer)
} }
#ifndef SERVERONLY #ifndef SERVERONLY
skinfiles = Mod_BuildSkinFileList(loadmodel->name); skinfiles = Mod_BuildSkinFileList(true, loadmodel->name);
if (skinfiles < 1)
skinfiles = 1;
#endif #endif
mesh = (dpmmesh_t*)((char*)buffer + header->ofs_meshs); mesh = (dpmmesh_t*)((char*)buffer + header->ofs_meshs);
@ -5690,7 +5686,7 @@ qboolean QDECL Mod_LoadDarkPlacesModel(model_t *mod, void *buffer)
skin[j].numshaders = 1; //non-sequenced skins. skin[j].numshaders = 1; //non-sequenced skins.
skin[j].ofsshaders = shaders; skin[j].ofsshaders = shaders;
shaders[0] = Mod_LoadSkinFile(mesh->shadername, j, NULL, 0, 0, NULL); shaders[0] = Mod_LoadSkinFile(NULL, mesh->shadername, j, NULL, 0, 0, NULL);
} }
m->ofsskins = skin; m->ofsskins = skin;
@ -5889,6 +5885,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
#ifndef SERVERONLY #ifndef SERVERONLY
galiasskin_t *skin; galiasskin_t *skin;
shader_t **shaders; shader_t **shaders;
int skinfiles;
#endif #endif
galiasgroup_t *fgroup; galiasgroup_t *fgroup;
galiasbone_t *bones; galiasbone_t *bones;
@ -5997,7 +5994,8 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
memsize += sizeof(*fgroup)*numgroups + sizeof(float)*12*(h->num_joints + (h->num_poses*h->num_frames)) + sizeof(*bones)*h->num_joints; memsize += sizeof(*fgroup)*numgroups + sizeof(float)*12*(h->num_joints + (h->num_poses*h->num_frames)) + sizeof(*bones)*h->num_joints;
memsize += (sizeof(*opos) + sizeof(*onorm1) + sizeof(*onorm2) + sizeof(*onorm3) + sizeof(*otcoords) + (noweights?0:(sizeof(*oindex)+sizeof(*oweight)))) * h->num_vertexes; memsize += (sizeof(*opos) + sizeof(*onorm1) + sizeof(*onorm2) + sizeof(*onorm3) + sizeof(*otcoords) + (noweights?0:(sizeof(*oindex)+sizeof(*oweight)))) * h->num_vertexes;
#ifndef SERVERONLY #ifndef SERVERONLY
memsize += sizeof(*skin)*h->num_meshes + sizeof(*shaders)*h->num_meshes; skinfiles = Mod_BuildSkinFileList(true, loadmodel->name);
memsize += (sizeof(*skin)*h->num_meshes + sizeof(*shaders)*h->num_meshes)*skinfiles;
#endif #endif
/*allocate a nice big block of memory and figure out where stuff is*/ /*allocate a nice big block of memory and figure out where stuff is*/
@ -6024,7 +6022,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
opose = oposebase + 12*h->num_joints; opose = oposebase + 12*h->num_joints;
#ifndef SERVERONLY #ifndef SERVERONLY
skin = (galiasskin_t*)(opose + 12*(h->num_poses*h->num_frames)); skin = (galiasskin_t*)(opose + 12*(h->num_poses*h->num_frames));
shaders = (shader_t**)(skin + h->num_meshes); shaders = (shader_t**)(skin + h->num_meshes*skinfiles);
#endif #endif
//no code to load animations or bones //no code to load animations or bones
@ -6162,21 +6160,26 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
offset = LittleLong(mesh[i].first_vertex); offset = LittleLong(mesh[i].first_vertex);
#ifndef SERVERONLY #ifndef SERVERONLY
/*skins*/ /*texture coords*/
gai[i].numskins = 1;
gai[i].ofsskins = &skin[i];
Q_strncpyz(skin[i].name, strings+mesh[i].material, sizeof(skin[i].name));
skin[i].skinwidth = 1;
skin[i].skinheight = 1;
skin[i].ofstexels = 0; /*doesn't support 8bit colourmapping*/
skin[i].skinspeed = 10; /*something to avoid div by 0*/
skin[i].numshaders = 1;
skin[i].ofsshaders = &shaders[i];
shaders[i] = R_RegisterSkin(skin[i].name, mod->name);
R_BuildDefaultTexnums(NULL, shaders[i]);
if (shaders[i]->flags & SHADER_NOIMAGE)
Con_Printf("Unable to load texture for shader \"%s\" on polyset \"%s\" for model \"%s\"\n", shaders[i]->name, strings+mesh[i].name, loadmodel->name);
gai[i].ofs_st_array = (otcoords+offset); gai[i].ofs_st_array = (otcoords+offset);
/*skins*/
gai[i].numskins = skinfiles;
gai[i].ofsskins = skin;
for (j = 0; j < skinfiles; j++)
{
Q_strncpyz(skin->name, skinfilelist[j], sizeof(skin[i].name));
skin->skinwidth = 1;
skin->skinheight = 1;
skin->ofstexels = 0; /*doesn't support 8bit colourmapping*/
skin->skinspeed = 10; /*something to avoid div by 0*/
skin->numshaders = 1; //non-sequenced skins.
skin->ofsshaders = shaders;
skin++;
*shaders++ = Mod_LoadSkinFile(strings+mesh[i].material, strings+mesh[i].name, j, NULL, 0, 0, NULL);
}
skin += skinfiles;
#endif #endif
nt = LittleLong(mesh[i].num_triangles); nt = LittleLong(mesh[i].num_triangles);
@ -6958,7 +6961,7 @@ qboolean QDECL Mod_LoadCompositeAnim(model_t *mod, void *buffer)
{ {
char namebkup[MAX_QPATH]; char namebkup[MAX_QPATH];
Q_strncpyz(namebkup, com_token, sizeof(namebkup)); Q_strncpyz(namebkup, com_token, sizeof(namebkup));
if (!Mod_ParseMD5Anim(file, root, &poseofs[numgroups], &grouplist[numgroups])) if (!Mod_ParseMD5Anim(file, root, (void**)&poseofs[numgroups], &grouplist[numgroups]))
{ {
return false; return false;
} }
@ -6976,7 +6979,7 @@ qboolean QDECL Mod_LoadCompositeAnim(model_t *mod, void *buffer)
{ {
char namebkup[MAX_QPATH]; char namebkup[MAX_QPATH];
Q_strncpyz(namebkup, com_token, sizeof(namebkup)); Q_strncpyz(namebkup, com_token, sizeof(namebkup));
if (!Mod_ParseMD5Anim(file, root, &poseofs[numgroups], &grouplist[numgroups])) if (!Mod_ParseMD5Anim(file, root, (void**)&poseofs[numgroups], &grouplist[numgroups]))
{ {
return false; return false;
} }

View file

@ -363,10 +363,10 @@ const dReal * (ODE_API *dBodyGetAngularVel)(dBodyID);
void (ODE_API *dBodySetMass)(dBodyID, const dMass *mass); void (ODE_API *dBodySetMass)(dBodyID, const dMass *mass);
//void (ODE_API *dBodyGetMass)(dBodyID, dMass *mass); //void (ODE_API *dBodyGetMass)(dBodyID, dMass *mass);
//void (ODE_API *dBodyAddForce)(dBodyID, dReal fx, dReal fy, dReal fz); //void (ODE_API *dBodyAddForce)(dBodyID, dReal fx, dReal fy, dReal fz);
//void (ODE_API *dBodyAddTorque)(dBodyID, dReal fx, dReal fy, dReal fz); void (ODE_API *dBodyAddTorque)(dBodyID, dReal fx, dReal fy, dReal fz);
//void (ODE_API *dBodyAddRelForce)(dBodyID, dReal fx, dReal fy, dReal fz); //void (ODE_API *dBodyAddRelForce)(dBodyID, dReal fx, dReal fy, dReal fz);
//void (ODE_API *dBodyAddRelTorque)(dBodyID, dReal fx, dReal fy, dReal fz); //void (ODE_API *dBodyAddRelTorque)(dBodyID, dReal fx, dReal fy, dReal fz);
//void (ODE_API *dBodyAddForceAtPos)(dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); void (ODE_API *dBodyAddForceAtPos)(dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz);
//void (ODE_API *dBodyAddForceAtRelPos)(dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); //void (ODE_API *dBodyAddForceAtRelPos)(dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz);
//void (ODE_API *dBodyAddRelForceAtPos)(dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); //void (ODE_API *dBodyAddRelForceAtPos)(dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz);
//void (ODE_API *dBodyAddRelForceAtRelPos)(dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz); //void (ODE_API *dBodyAddRelForceAtRelPos)(dBodyID, dReal fx, dReal fy, dReal fz, dReal px, dReal py, dReal pz);
@ -389,8 +389,8 @@ dJointID (ODE_API *dBodyGetJoint)(dBodyID, int index);
//void (ODE_API *dBodySetDynamic)(dBodyID); //void (ODE_API *dBodySetDynamic)(dBodyID);
//void (ODE_API *dBodySetKinematic)(dBodyID); //void (ODE_API *dBodySetKinematic)(dBodyID);
//int (ODE_API *dBodyIsKinematic)(dBodyID); //int (ODE_API *dBodyIsKinematic)(dBodyID);
//void (ODE_API *dBodyEnable)(dBodyID); void (ODE_API *dBodyEnable)(dBodyID);
//void (ODE_API *dBodyDisable)(dBodyID); void (ODE_API *dBodyDisable)(dBodyID);
//int (ODE_API *dBodyIsEnabled)(dBodyID); //int (ODE_API *dBodyIsEnabled)(dBodyID);
void (ODE_API *dBodySetGravityMode)(dBodyID b, int mode); void (ODE_API *dBodySetGravityMode)(dBodyID b, int mode);
int (ODE_API *dBodyGetGravityMode)(dBodyID b); int (ODE_API *dBodyGetGravityMode)(dBodyID b);
@ -828,10 +828,10 @@ static dllfunction_t odefuncs[] =
{(void **) &dBodySetMass, "dBodySetMass"}, {(void **) &dBodySetMass, "dBodySetMass"},
// {"dBodyGetMass", (void **) &dBodyGetMass}, // {"dBodyGetMass", (void **) &dBodyGetMass},
// {"dBodyAddForce", (void **) &dBodyAddForce}, // {"dBodyAddForce", (void **) &dBodyAddForce},
// {"dBodyAddTorque", (void **) &dBodyAddTorque}, {(void **) &dBodyAddTorque, "dBodyAddTorque"},
// {"dBodyAddRelForce", (void **) &dBodyAddRelForce}, // {"dBodyAddRelForce", (void **) &dBodyAddRelForce},
// {"dBodyAddRelTorque", (void **) &dBodyAddRelTorque}, // {"dBodyAddRelTorque", (void **) &dBodyAddRelTorque},
// {"dBodyAddForceAtPos", (void **) &dBodyAddForceAtPos}, {(void **) &dBodyAddForceAtPos, "dBodyAddForceAtPos"},
// {"dBodyAddForceAtRelPos", (void **) &dBodyAddForceAtRelPos}, // {"dBodyAddForceAtRelPos", (void **) &dBodyAddForceAtRelPos},
// {"dBodyAddRelForceAtPos", (void **) &dBodyAddRelForceAtPos}, // {"dBodyAddRelForceAtPos", (void **) &dBodyAddRelForceAtPos},
// {"dBodyAddRelForceAtRelPos", (void **) &dBodyAddRelForceAtRelPos}, // {"dBodyAddRelForceAtRelPos", (void **) &dBodyAddRelForceAtRelPos},
@ -854,8 +854,8 @@ static dllfunction_t odefuncs[] =
// {"dBodySetDynamic", (void **) &dBodySetDynamic}, // {"dBodySetDynamic", (void **) &dBodySetDynamic},
// {"dBodySetKinematic", (void **) &dBodySetKinematic}, // {"dBodySetKinematic", (void **) &dBodySetKinematic},
// {"dBodyIsKinematic", (void **) &dBodyIsKinematic}, // {"dBodyIsKinematic", (void **) &dBodyIsKinematic},
// {"dBodyEnable", (void **) &dBodyEnable}, {(void **) &dBodyEnable, "dBodyEnable"},
// {"dBodyDisable", (void **) &dBodyDisable}, {(void **) &dBodyDisable, "dBodyDisable"},
// {"dBodyIsEnabled", (void **) &dBodyIsEnabled}, // {"dBodyIsEnabled", (void **) &dBodyIsEnabled},
{(void **) &dBodySetGravityMode, "dBodySetGravityMode"}, {(void **) &dBodySetGravityMode, "dBodySetGravityMode"},
{(void **) &dBodyGetGravityMode, "dBodyGetGravityMode"}, {(void **) &dBodyGetGravityMode, "dBodyGetGravityMode"},
@ -1171,6 +1171,8 @@ static dllfunction_t odefuncs[] =
dllhandle_t ode_dll = NULL; dllhandle_t ode_dll = NULL;
#endif #endif
static void World_ODE_RunCmd(world_t *world, odecommandqueue_t *cmd);
void World_ODE_Init(void) void World_ODE_Init(void)
{ {
#ifdef ODE_DYNAMIC #ifdef ODE_DYNAMIC
@ -1798,22 +1800,22 @@ qboolean World_ODE_RagCreateBody(world_t *world, odebody_t *bodyptr, odebodyinfo
world->ode.hasodeents = true; //I don't like this, but we need the world etc to be solid. world->ode.hasodeents = true; //I don't like this, but we need the world etc to be solid.
world->ode.hasextraobjs = true; world->ode.hasextraobjs = true;
switch(bodyinfo->shape) switch(bodyinfo->geomshape)
{ {
case SOLID_PHYSICS_CAPSULE: case GEOMTYPE_CAPSULE:
radius = (bodyinfo->dimensions[0] + bodyinfo->dimensions[1]) * 0.5; radius = (bodyinfo->dimensions[0] + bodyinfo->dimensions[1]) * 0.5;
bodyptr->ode_geom = (void *)dCreateCapsule(world->ode.ode_space, radius, bodyinfo->dimensions[2]); bodyptr->ode_geom = (void *)dCreateCapsule(world->ode.ode_space, radius, bodyinfo->dimensions[2]);
dMassSetCapsuleTotal(&mass, bodyinfo->mass, 3, radius, bodyinfo->dimensions[2]); dMassSetCapsuleTotal(&mass, bodyinfo->mass, 3, radius, bodyinfo->dimensions[2]);
//aligned along the geom's local z axis //aligned along the geom's local z axis
break; break;
case SOLID_PHYSICS_SPHERE: case GEOMTYPE_SPHERE:
//radius //radius
radius = (bodyinfo->dimensions[0] + bodyinfo->dimensions[1] + bodyinfo->dimensions[2]) / 3; radius = (bodyinfo->dimensions[0] + bodyinfo->dimensions[1] + bodyinfo->dimensions[2]) / 3;
bodyptr->ode_geom = dCreateSphere(world->ode.ode_space, radius); bodyptr->ode_geom = dCreateSphere(world->ode.ode_space, radius);
dMassSetSphereTotal(&mass, bodyinfo->mass, radius); dMassSetSphereTotal(&mass, bodyinfo->mass, radius);
//aligned along the geom's local z axis //aligned along the geom's local z axis
break; break;
case SOLID_PHYSICS_CYLINDER: case GEOMTYPE_CYLINDER:
//radius, length //radius, length
radius = (bodyinfo->dimensions[0] + bodyinfo->dimensions[1]) * 0.5; radius = (bodyinfo->dimensions[0] + bodyinfo->dimensions[1]) * 0.5;
bodyptr->ode_geom = dCreateCylinder(world->ode.ode_space, radius, bodyinfo->dimensions[2]); bodyptr->ode_geom = dCreateCylinder(world->ode.ode_space, radius, bodyinfo->dimensions[2]);
@ -1821,7 +1823,7 @@ qboolean World_ODE_RagCreateBody(world_t *world, odebody_t *bodyptr, odebodyinfo
//alignment is irreleevnt, thouse I suppose it might be scaled wierdly. //alignment is irreleevnt, thouse I suppose it might be scaled wierdly.
break; break;
default: default:
case SOLID_PHYSICS_BOX: case GEOMTYPE_BOX:
//diameter //diameter
bodyptr->ode_geom = dCreateBox(world->ode.ode_space, bodyinfo->dimensions[0], bodyinfo->dimensions[1], bodyinfo->dimensions[2]); bodyptr->ode_geom = dCreateBox(world->ode.ode_space, bodyinfo->dimensions[0], bodyinfo->dimensions[1], bodyinfo->dimensions[2]);
dMassSetBoxTotal(&mass, bodyinfo->mass, bodyinfo->dimensions[0], bodyinfo->dimensions[1], bodyinfo->dimensions[2]); dMassSetBoxTotal(&mass, bodyinfo->mass, bodyinfo->dimensions[0], bodyinfo->dimensions[1], bodyinfo->dimensions[2]);
@ -2074,6 +2076,7 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
int modelindex = 0; int modelindex = 0;
int movetype = MOVETYPE_NONE; int movetype = MOVETYPE_NONE;
int solid = SOLID_NOT; int solid = SOLID_NOT;
int geomtype = GEOMTYPE_SOLID;
qboolean modified = false; qboolean modified = false;
vec3_t angles; vec3_t angles;
vec3_t avelocity; vec3_t avelocity;
@ -2099,15 +2102,32 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
if (!ode_dll) if (!ode_dll)
return; return;
#endif #endif
geomtype = (int)ed->xv->geomtype;
solid = (int)ed->v->solid; solid = (int)ed->v->solid;
movetype = (int)ed->v->movetype; movetype = (int)ed->v->movetype;
scale = ed->xv->scale?ed->xv->scale:1; scale = ed->xv->scale?ed->xv->scale:1;
modelindex = 0; modelindex = 0;
model = NULL; model = NULL;
switch(solid) if (!geomtype)
{ {
case SOLID_BSP: switch((int)ed->v->solid)
{
case SOLID_NOT: geomtype = GEOMTYPE_NONE; break;
case SOLID_TRIGGER: geomtype = GEOMTYPE_NONE; break;
case SOLID_BSP: geomtype = GEOMTYPE_TRIMESH; break;
case SOLID_PHYSICS_TRIMESH: geomtype = GEOMTYPE_TRIMESH; break;
case SOLID_PHYSICS_BOX: geomtype = GEOMTYPE_BOX; break;
case SOLID_PHYSICS_SPHERE: geomtype = GEOMTYPE_SPHERE; break;
case SOLID_PHYSICS_CAPSULE: geomtype = GEOMTYPE_CAPSULE; break;
case SOLID_PHYSICS_CYLINDER:geomtype = GEOMTYPE_CYLINDER; break;
default: geomtype = GEOMTYPE_BOX; break;
}
}
switch(geomtype)
{
case GEOMTYPE_TRIMESH:
modelindex = (int)ed->v->modelindex; modelindex = (int)ed->v->modelindex;
model = world->Get_CModel(world, modelindex); model = world->Get_CModel(world, modelindex);
if (model) if (model)
@ -2123,18 +2143,16 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
massval = 1.0f; massval = 1.0f;
} }
break; break;
case SOLID_BBOX: case GEOMTYPE_BOX:
case SOLID_SLIDEBOX: case GEOMTYPE_SPHERE:
case SOLID_CORPSE: case GEOMTYPE_CAPSULE:
case SOLID_PHYSICS_BOX:
case SOLID_PHYSICS_SPHERE:
case SOLID_PHYSICS_CAPSULE:
VectorCopy(ed->v->mins, entmins); VectorCopy(ed->v->mins, entmins);
VectorCopy(ed->v->maxs, entmaxs); VectorCopy(ed->v->maxs, entmaxs);
if (ed->xv->mass) if (ed->xv->mass)
massval = ed->xv->mass; massval = ed->xv->mass;
break; break;
default: default:
// case GEOMTYPE_NONE:
if (ed->ode.ode_physics) if (ed->ode.ode_physics)
World_ODE_RemoveFromEntity(world, ed); World_ODE_RemoveFromEntity(world, ed);
return; return;
@ -2177,9 +2195,9 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
VectorSet(geomsize, 1.0f, 1.0f, 1.0f); VectorSet(geomsize, 1.0f, 1.0f, 1.0f);
} }
switch(solid) switch(geomtype)
{ {
case SOLID_BSP: case GEOMTYPE_TRIMESH:
Matrix4x4_Identity(ed->ode.ode_offsetmatrix); Matrix4x4_Identity(ed->ode.ode_offsetmatrix);
ed->ode.ode_geom = NULL; ed->ode.ode_geom = NULL;
if (!model) if (!model)
@ -2203,20 +2221,17 @@ static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
ed->ode.ode_geom = (void *)dCreateTriMesh(world->ode.ode_space, dataID, NULL, NULL, NULL); ed->ode.ode_geom = (void *)dCreateTriMesh(world->ode.ode_space, dataID, NULL, NULL, NULL);
dMassSetBoxTotal(&mass, massval, geomsize[0], geomsize[1], geomsize[2]); dMassSetBoxTotal(&mass, massval, geomsize[0], geomsize[1], geomsize[2]);
break; break;
case SOLID_BBOX: case GEOMTYPE_BOX:
case SOLID_SLIDEBOX:
case SOLID_CORPSE:
case SOLID_PHYSICS_BOX:
Matrix4x4_RM_CreateTranslate(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2]); Matrix4x4_RM_CreateTranslate(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2]);
ed->ode.ode_geom = (void *)dCreateBox(world->ode.ode_space, geomsize[0], geomsize[1], geomsize[2]); ed->ode.ode_geom = (void *)dCreateBox(world->ode.ode_space, geomsize[0], geomsize[1], geomsize[2]);
dMassSetBoxTotal(&mass, massval, geomsize[0], geomsize[1], geomsize[2]); dMassSetBoxTotal(&mass, massval, geomsize[0], geomsize[1], geomsize[2]);
break; break;
case SOLID_PHYSICS_SPHERE: case GEOMTYPE_SPHERE:
Matrix4x4_RM_CreateTranslate(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2]); Matrix4x4_RM_CreateTranslate(ed->ode.ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2]);
ed->ode.ode_geom = (void *)dCreateSphere(world->ode.ode_space, geomsize[0] * 0.5f); ed->ode.ode_geom = (void *)dCreateSphere(world->ode.ode_space, geomsize[0] * 0.5f);
dMassSetSphereTotal(&mass, massval, geomsize[0] * 0.5f); dMassSetSphereTotal(&mass, massval, geomsize[0] * 0.5f);
break; break;
case SOLID_PHYSICS_CAPSULE: case GEOMTYPE_CAPSULE:
axisindex = 0; axisindex = 0;
if (geomsize[axisindex] < geomsize[1]) if (geomsize[axisindex] < geomsize[1])
axisindex = 1; axisindex = 1;
@ -2627,6 +2642,15 @@ void World_ODE_Frame(world_t *world, double frametime, double gravity)
if (!ed->isfree) if (!ed->isfree)
World_ODE_Frame_JointFromEntity(world, ed); World_ODE_Frame_JointFromEntity(world, ed);
} }
while(world->ode.cmdqueuehead)
{
odecommandqueue_t *cmd = world->ode.cmdqueuehead;
world->ode.cmdqueuehead = cmd->next;
if (!cmd->next)
world->ode.cmdqueuetail = NULL;
World_ODE_RunCmd(world, cmd);
Z_Free(cmd);
}
} }
for (i = 0;i < world->ode.ode_iterations;i++) for (i = 0;i < world->ode.ode_iterations;i++)
@ -2671,4 +2695,81 @@ void World_ODE_Frame(world_t *world, double frametime, double gravity)
} }
} }
static void World_ODE_RunCmd(world_t *world, odecommandqueue_t *cmd)
{
switch(cmd->command)
{
case ODECMD_ENABLE:
if (cmd->edict->ode.ode_body)
dBodyEnable(cmd->edict->ode.ode_body);
break;
case ODECMD_DISABLE:
if (cmd->edict->ode.ode_body)
dBodyDisable(cmd->edict->ode.ode_body);
break;
case ODECMD_FORCE:
if (cmd->edict->ode.ode_body)
{
dBodyEnable(cmd->edict->ode.ode_body);
dBodyAddForceAtPos(cmd->edict->ode.ode_body, cmd->v1[0], cmd->v1[1], cmd->v1[2], cmd->v2[0], cmd->v2[1], cmd->v2[2]);
}
break;
case ODECMD_TORQUE:
if (cmd->edict->ode.ode_body)
{
dBodyEnable(cmd->edict->ode.ode_body);
dBodyAddTorque(cmd->edict->ode.ode_body, cmd->v1[0], cmd->v1[1], cmd->v1[2]);
}
break;
}
}
static odecommandqueue_t *physics_queuecommand(world_t *world)
{
odecommandqueue_t *cmd = Z_Malloc(sizeof(*cmd));
world->ode.hasodeents = true; //just in case.
//add on the end of the queue, so that order is preserved.
if (world->ode.cmdqueuehead)
world->ode.cmdqueuetail->next = world->ode.cmdqueuetail = cmd;
else
world->ode.cmdqueuetail = world->ode.cmdqueuehead = cmd;
return cmd;
}
void QCBUILTIN PF_physics_enable(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
wedict_t*e = G_WEDICT(prinst, OFS_PARM0);
int isenable = G_FLOAT(OFS_PARM1);
world_t *world = prinst->parms->user;
odecommandqueue_t *cmd = physics_queuecommand(world);
cmd->command = isenable?ODECMD_ENABLE:ODECMD_DISABLE;
cmd->edict = e;
}
void QCBUILTIN PF_physics_addforce(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
wedict_t*e = G_WEDICT(prinst, OFS_PARM0);
float *force = G_VECTOR(OFS_PARM1);
float *relative_ofs = G_VECTOR(OFS_PARM2);
world_t *world = prinst->parms->user;
odecommandqueue_t *cmd = physics_queuecommand(world);
cmd->command = ODECMD_FORCE;
cmd->edict = e;
VectorCopy(force, cmd->v1);
VectorCopy(relative_ofs, cmd->v2);
}
void QCBUILTIN PF_physics_addtorque(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
wedict_t*e = G_WEDICT(prinst, OFS_PARM0);
float *torque = G_VECTOR(OFS_PARM1);
world_t *world = prinst->parms->user;
odecommandqueue_t *cmd = physics_queuecommand(world);
cmd->command = ODECMD_TORQUE;
cmd->edict = e;
VectorCopy(torque, cmd->v1);
}
#endif #endif

View file

@ -40,7 +40,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "./mingw-libs/jpeglib.h" #include "./mingw-libs/jpeglib.h"
#endif #endif
#ifdef _SDL #ifdef _SDL
#include "./mingw-libs/SDL_version.h" #include <SDL.h>
#endif #endif
#elif defined(_WIN32) #elif defined(_WIN32)
#if defined(AVAIL_PNGLIB) && !defined(SERVERONLY) #if defined(AVAIL_PNGLIB) && !defined(SERVERONLY)
@ -55,7 +55,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "jpeglib.h" #include "jpeglib.h"
#endif #endif
#ifdef _SDL #ifdef _SDL
#include "SDL_version.h" #include <SDL.h>
#endif #endif
#else #else
#if defined(AVAIL_PNGLIB) && !defined(SERVERONLY) #if defined(AVAIL_PNGLIB) && !defined(SERVERONLY)
@ -69,7 +69,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <jpeglib.h> #include <jpeglib.h>
#endif #endif
#ifdef _SDL #ifdef _SDL
#include <SDL_version.h> #include <SDL.h>
#endif #endif
#endif #endif
@ -2160,7 +2160,7 @@ unsigned int utf8_encode(void *out, unsigned int unicode, int maxlen)
{ {
shift = bcount*6; shift = bcount*6;
shift = shift-6; shift = shift-6;
*((unsigned char *)out) = (unsigned char)((unicode>>shift)&(0x0000007f>>bcount)) | (0xffffff00 >> bcount); *((unsigned char *)out) = (unsigned char)((unicode>>shift)&(0x0000007f>>bcount)) | ((0xffffff00 >> bcount) & 0xff);
out = (char*)out + 1; out = (char*)out + 1;
do do
{ {
@ -2181,7 +2181,7 @@ unsigned int qchar_encode(char *out, unsigned int unicode, int maxlen, qboolean
{ //quake compatible chars { //quake compatible chars
if (maxlen < 1) if (maxlen < 1)
return 0; return 0;
*out++ = unicode; *out++ = unicode & 0xff;
return 1; return 1;
} }
else if (!markup) else if (!markup)
@ -5282,12 +5282,12 @@ int VARGS linuxlike_snprintf_vc8(char *buffer, int size, const char *format, ...
#endif #endif
// libSDL.a and libSDLmain.a mingw32 libs use this function for some reason, just here to shut gcc up // libSDL.a and libSDLmain.a mingw32 libs use this function for some reason, just here to shut gcc up
#ifdef _MINGW_VFPRINTF /*#ifdef _MINGW_VFPRINTF
int __mingw_vfprintf (FILE *__stream, const char *__format, __VALIST __local_argv) int __mingw_vfprintf (FILE *__stream, const char *__format, __VALIST __local_argv)
{ {
return vfprintf( __stream, __format, __local_argv ); return vfprintf( __stream, __format, __local_argv );
} }
#endif #endif*/
int version_number(void) int version_number(void)
{ {

View file

@ -338,12 +338,30 @@ extern char com_configdir[MAX_OSPATH]; //dir to put cfg_save configs in
void COM_WriteFile (const char *filename, const void *data, int len); void COM_WriteFile (const char *filename, const void *data, int len);
//qofs_Make is used to 'construct' a variable of qofs_t type. this is so the code can merge two 32bit ints on old systems and use a long long type internally without generating warnings about bit shifts when qofs_t is only 32bit instead.
#if defined(__amd64__) || defined(_AMD64_) || __WORDSIZE == 64
#define FS_64BIT
#endif
#ifdef FS_64BIT
typedef unsigned long long qofs_t; //type to use for a file offset
#define qofs_Make(low,high) (low | (((qofs_t)(high))<<32))
#define qofs_Low(o) ((o)&0xffffffffu)
#define qofs_High(o) ((o)>>32)
#define qofs_Error(o) ((o) == ~0ull)
#else
typedef unsigned int qofs_t; //type to use for a file offset
#define qofs_Make(low,high) (low)
#define qofs_Low(o) (o)
#define qofs_High(o) (0)
#define qofs_Error(o) ((o) == ~0ul)
#endif
typedef struct { typedef struct {
struct searchpath_s *search; struct searchpath_s *search; //used to say which filesystem driver to open the file from
int index; int index; //used by the filesystem driver as a simple reference to the file
char rawname[MAX_OSPATH]; char rawname[MAX_OSPATH]; //blank means not readable directly
int offset; qofs_t offset; //only usable if rawname is set.
int len; qofs_t len; //uncompressed length
} flocation_t; } flocation_t;
struct vfsfile_s; struct vfsfile_s;
@ -372,14 +390,13 @@ FTE_DEPRECATED void COM_CloseFile (FILE *h);
#define COM_FDepthFile(filename,ignorepacks) FS_FLocateFile(filename,ignorepacks?FSLFRT_DEPTH_OSONLY:FSLFRT_DEPTH_ANYPATH, NULL) #define COM_FDepthFile(filename,ignorepacks) FS_FLocateFile(filename,ignorepacks?FSLFRT_DEPTH_OSONLY:FSLFRT_DEPTH_ANYPATH, NULL)
#define COM_FCheckExists(filename) FS_FLocateFile(filename,FSLFRT_IFFOUND, NULL) #define COM_FCheckExists(filename) FS_FLocateFile(filename,FSLFRT_IFFOUND, NULL)
typedef struct vfsfile_s typedef struct vfsfile_s
{ {
int (QDECL *ReadBytes) (struct vfsfile_s *file, void *buffer, int bytestoread); int (QDECL *ReadBytes) (struct vfsfile_s *file, void *buffer, int bytestoread);
int (QDECL *WriteBytes) (struct vfsfile_s *file, const void *buffer, int bytestoread); int (QDECL *WriteBytes) (struct vfsfile_s *file, const void *buffer, int bytestoread);
qboolean (QDECL *Seek) (struct vfsfile_s *file, unsigned long pos); //returns false for error qboolean (QDECL *Seek) (struct vfsfile_s *file, qofs_t pos); //returns false for error
unsigned long (QDECL *Tell) (struct vfsfile_s *file); qofs_t (QDECL *Tell) (struct vfsfile_s *file);
unsigned long (QDECL *GetLen) (struct vfsfile_s *file); //could give some lag qofs_t (QDECL *GetLen) (struct vfsfile_s *file); //could give some lag
void (QDECL *Close) (struct vfsfile_s *file); void (QDECL *Close) (struct vfsfile_s *file);
void (QDECL *Flush) (struct vfsfile_s *file); void (QDECL *Flush) (struct vfsfile_s *file);
qboolean seekingisabadplan; qboolean seekingisabadplan;
@ -476,15 +493,15 @@ char *FS_GetBasedir(void);
struct zonegroup_s; struct zonegroup_s;
void *FS_LoadMallocGroupFile(struct zonegroup_s *ctx, char *path); void *FS_LoadMallocGroupFile(struct zonegroup_s *ctx, char *path);
qbyte *FS_LoadMallocFile (const char *path); qbyte *FS_LoadMallocFile (const char *path);
int FS_LoadFile(char *name, void **file); qofs_t FS_LoadFile(char *name, void **file);
void FS_FreeFile(void *file); void FS_FreeFile(void *file);
qbyte *COM_LoadFile (const char *path, int usehunk); qbyte *COM_LoadFile (const char *path, int usehunk);
qboolean COM_LoadMapPackFile(const char *name, int offset); qboolean COM_LoadMapPackFile(const char *name, qofs_t offset);
void COM_FlushTempoaryPacks(void); void COM_FlushTempoaryPacks(void);
void COM_EnumerateFiles (const char *match, int (QDECL *func)(const char *fname, int fsize, void *parm, searchpathfuncs_t *spath), void *parm); void COM_EnumerateFiles (const char *match, int (QDECL *func)(const char *fname, qofs_t fsize, void *parm, searchpathfuncs_t *spath), void *parm);
extern struct cvar_s registered; extern struct cvar_s registered;
extern qboolean standard_quake; //fixme: remove extern qboolean standard_quake; //fixme: remove

View file

@ -92,6 +92,7 @@ typedef struct cvar_s
#define CVARAFD(ConsoleName,Value,ConsoleName2,Flags,Description)CVARAFDC(ConsoleName, Value, ConsoleName2, Flags, Description, NULL) #define CVARAFD(ConsoleName,Value,ConsoleName2,Flags,Description)CVARAFDC(ConsoleName, Value, ConsoleName2, Flags, Description, NULL)
#define CVARAFC(ConsoleName,Value,ConsoleName2,Flags,Callback) CVARAFC(ConsoleName, Value, ConsoleName2, Flags, NULL, Callback) #define CVARAFC(ConsoleName,Value,ConsoleName2,Flags,Callback) CVARAFC(ConsoleName, Value, ConsoleName2, Flags, NULL, Callback)
#define CVARAF(ConsoleName,Value,ConsoleName2,Flags) CVARAFDC(ConsoleName, Value, ConsoleName2, Flags, NULL, NULL) #define CVARAF(ConsoleName,Value,ConsoleName2,Flags) CVARAFDC(ConsoleName, Value, ConsoleName2, Flags, NULL, NULL)
#define CVARFDC(ConsoleName,Value,Flags,Description,Callback) CVARAFDC(ConsoleName, Value, NULL, Flags, Description, Callback)
#define CVARFC(ConsoleName,Value,Flags,Callback) CVARAFDC(ConsoleName, Value, NULL, Flags, NULL, Callback) #define CVARFC(ConsoleName,Value,Flags,Callback) CVARAFDC(ConsoleName, Value, NULL, Flags, NULL, Callback)
#define CVARAD(ConsoleName,Value,ConsoleName2,Description) CVARAFDC(ConsoleName, Value, ConsoleName2, 0, Description, NULL) #define CVARAD(ConsoleName,Value,ConsoleName2,Description) CVARAFDC(ConsoleName, Value, ConsoleName2, 0, Description, NULL)
#define CVARFD(ConsoleName,Value,Flags,Description) CVARAFDC(ConsoleName, Value, NULL, Flags, Description, NULL) #define CVARFD(ConsoleName,Value,Flags,Description) CVARAFDC(ConsoleName, Value, NULL, Flags, Description, NULL)

View file

@ -12,12 +12,7 @@
#include "winquake.h" #include "winquake.h"
#endif #endif
#if defined(MINGW) && defined(_SDL)
#include "./mingw-libs/SDL_syswm.h" // mingw sdl cross binary complains off sys_parentwindow
#endif
hashtable_t filesystemhash; hashtable_t filesystemhash;
qboolean blockcache = true;
qboolean com_fschanged = true; qboolean com_fschanged = true;
static unsigned int fs_restarts; static unsigned int fs_restarts;
extern cvar_t com_fs_cache; extern cvar_t com_fs_cache;
@ -315,27 +310,27 @@ static void FS_Manifest_ParseTokens(ftemanifest_t *man)
if (*fname == '*') if (*fname == '*')
fname++; fname++;
if (!stricmp(fname, "game")) if (!Q_strcasecmp(fname, "game"))
{ {
Z_Free(man->installation); Z_Free(man->installation);
man->installation = Z_StrDup(Cmd_Argv(1)); man->installation = Z_StrDup(Cmd_Argv(1));
} }
else if (!stricmp(fname, "name")) else if (!Q_strcasecmp(fname, "name"))
{ {
Z_Free(man->formalname); Z_Free(man->formalname);
man->formalname = Z_StrDup(Cmd_Argv(1)); man->formalname = Z_StrDup(Cmd_Argv(1));
} }
else if (!stricmp(fname, "protocolname")) else if (!Q_strcasecmp(fname, "protocolname"))
{ {
Z_Free(man->protocolname); Z_Free(man->protocolname);
man->protocolname = Z_StrDup(Cmd_Argv(1)); man->protocolname = Z_StrDup(Cmd_Argv(1));
} }
else if (!stricmp(fname, "defaultexec")) else if (!Q_strcasecmp(fname, "defaultexec"))
{ {
Z_Free(man->defaultexec); Z_Free(man->defaultexec);
man->defaultexec = Z_StrDup(Cmd_Argv(1)); man->defaultexec = Z_StrDup(Cmd_Argv(1));
} }
else if (!stricmp(fname, "basegame") || !stricmp(fname, "gamedir")) else if (!Q_strcasecmp(fname, "basegame") || !Q_strcasecmp(fname, "gamedir"))
{ {
int i; int i;
char *newdir = Cmd_Argv(1); char *newdir = Cmd_Argv(1);
@ -351,7 +346,7 @@ static void FS_Manifest_ParseTokens(ftemanifest_t *man)
{ {
if (!man->gamepath[i].path) if (!man->gamepath[i].path)
{ {
man->gamepath[i].base = !stricmp(fname, "basegame"); man->gamepath[i].base = !Q_strcasecmp(fname, "basegame");
man->gamepath[i].path = Z_StrDup(newdir); man->gamepath[i].path = Z_StrDup(newdir);
break; break;
} }
@ -367,7 +362,7 @@ static void FS_Manifest_ParseTokens(ftemanifest_t *man)
qboolean crcknown; qboolean crcknown;
int crc; int crc;
int i, j; int i, j;
if (!stricmp(fname, "package")) if (!Q_strcasecmp(fname, "package"))
Cmd_ShiftArgs(1, false); Cmd_ShiftArgs(1, false);
crcknown = (strcmp(Cmd_Argv(1), "-") && *Cmd_Argv(1)); crcknown = (strcmp(Cmd_Argv(1), "-") && *Cmd_Argv(1));
@ -527,7 +522,7 @@ COM_Dir_f
============ ============
*/ */
static int QDECL COM_Dir_List(const char *name, int size, void *parm, searchpathfuncs_t *spath) static int QDECL COM_Dir_List(const char *name, qofs_t size, void *parm, searchpathfuncs_t *spath)
{ {
searchpath_t *s; searchpath_t *s;
for (s=com_searchpaths ; s ; s=s->next) for (s=com_searchpaths ; s ; s=s->next)
@ -535,7 +530,14 @@ static int QDECL COM_Dir_List(const char *name, int size, void *parm, searchpath
if (s->handle == spath) if (s->handle == spath)
break; break;
} }
Con_Printf("%s (%i) (%s)\n", name, size, s?s->logicalpath:"??"); if (size > 1.0*1024*1024*1024)
Con_Printf("%s \t(%#.3ggb) (%s)\n", name, size/(1024.0*1024*1024), s?s->logicalpath:"??");
else if (size > 1.0*1024*1024)
Con_Printf("%s \t(%#.3gmb) (%s)\n", name, size/(1024.0*1024), s?s->logicalpath:"??");
else if (size > 1.0*1024)
Con_Printf("%s \t(%#.3gkb) (%s)\n", name, size/1024.0, s?s->logicalpath:"??");
else
Con_Printf("%s \t(%ub) (%s)\n", name, (unsigned int)size, s?s->logicalpath:"??");
return 1; return 1;
} }
@ -668,26 +670,32 @@ static void COM_CopyFile (char *netpath, char *cachepath)
int fs_hash_dups; int fs_hash_dups;
int fs_hash_files; int fs_hash_files;
//normally the filesystem drivers pass a pre-allocated bucket and static strings to us
//the OS driver can't really be expected to track things that reliably however, so it just gives names via the stack.
//these files are grouped up to avoid excessive memory allocations.
struct fsbucketblock
{
struct fsbucketblock *prev;
int used;
int total;
qbyte data[1];
};
static struct fsbucketblock *fs_hash_filebuckets;
void FS_FlushFSHashReally(void) void FS_FlushFSHashReally(void)
{ {
if (filesystemhash.numbuckets) if (filesystemhash.numbuckets)
{ {
int i; int i;
fsbucket_t *bucket, *next;
for (i = 0; i < filesystemhash.numbuckets; i++) for (i = 0; i < filesystemhash.numbuckets; i++)
{
bucket = (fsbucket_t*)filesystemhash.bucket[i];
filesystemhash.bucket[i] = NULL; filesystemhash.bucket[i] = NULL;
while(bucket) }
{
next = (fsbucket_t*)bucket->buck.next; while (fs_hash_filebuckets)
/*if the string starts right after the bucket, free it*/ {
if (bucket->depth < 0) struct fsbucketblock *n = fs_hash_filebuckets->prev;
Z_Free(bucket); Z_Free(fs_hash_filebuckets);
bucket = next; fs_hash_filebuckets = n;
}
}
} }
com_fschanged = true; com_fschanged = true;
@ -710,27 +718,34 @@ static void QDECL FS_AddFileHash(int depth, const char *fname, fsbucket_t *fileh
if (old) if (old)
{ {
fs_hash_dups++; fs_hash_dups++;
if (depth >= ((old->depth<0)?(-old->depth-1):old->depth)) if (depth >= old->depth)
{ {
return; return;
} }
//remove the old version //remove the old version
Hash_RemoveBucket(&filesystemhash, fname, &old->buck); Hash_RemoveBucket(&filesystemhash, fname, &old->buck);
if (old->depth < 0)
Z_Free(old);
} }
if (!filehandle) if (!filehandle)
{ {
filehandle = Z_Malloc(sizeof(*filehandle) + strlen(fname)+1); int nlen = strlen(fname)+1;
if (!fs_hash_filebuckets || fs_hash_filebuckets->used+sizeof(*filehandle)+nlen > fs_hash_filebuckets->total)
{
void *o = fs_hash_filebuckets;
fs_hash_filebuckets = Z_Malloc(65536);
fs_hash_filebuckets->total = 65536 - sizeof(*fs_hash_filebuckets);
fs_hash_filebuckets->prev = o;
}
filehandle = (fsbucket_t*)(fs_hash_filebuckets->data+fs_hash_filebuckets->used);
fs_hash_filebuckets->used += sizeof(*filehandle)+nlen;
if (!filehandle) if (!filehandle)
return; //eep! return; //eep!
strcpy((char*)(filehandle+1), fname); memcpy((char*)(filehandle+1), fname, nlen);
fname = (char*)(filehandle+1); fname = (char*)(filehandle+1);
filehandle->depth = -depth-1;
} }
else filehandle->depth = depth; filehandle->depth = depth;
Hash_AddInsensative(&filesystemhash, fname, pathhandle, &filehandle->buck); Hash_AddInsensative(&filesystemhash, fname, pathhandle, &filehandle->buck);
fs_hash_files++; fs_hash_files++;
@ -740,6 +755,9 @@ void FS_RebuildFSHash(void)
{ {
int depth = 1; int depth = 1;
searchpath_t *search; searchpath_t *search;
if (!com_fschanged)
return;
if (!filesystemhash.numbuckets) if (!filesystemhash.numbuckets)
{ {
filesystemhash.numbuckets = 1024; filesystemhash.numbuckets = 1024;
@ -810,10 +828,8 @@ int FS_FLocateFile(const char *filename, FSLF_ReturnType_e returntype, flocation
goto fail; goto fail;
} }
if (com_fs_cache.ival && !blockcache) if (com_fs_cache.ival && !com_fschanged)
{ {
if (com_fschanged)
FS_RebuildFSHash();
pf = Hash_GetInsensative(&filesystemhash, filename); pf = Hash_GetInsensative(&filesystemhash, filename);
if (!pf) if (!pf)
goto fail; goto fail;
@ -1088,71 +1104,6 @@ void FS_ReferenceControl(unsigned int refflag, unsigned int resetflags)
fs_referencetype = refflag; fs_referencetype = refflag;
} }
#if 0
int COM_FOpenLocationFILE(flocation_t *loc, FILE **file)
{
if (!*loc->rawname)
{
if (!loc->len)
{
*file = NULL;
return -1;
}
if (loc->search->funcs->ReadFile)
{//create a new, temp file, bung the contents of the compressed file into it, then continue.
char *buf;
FILE *f = tmpfile();
buf = BZ_Malloc(loc->len);
loc->search->funcs->ReadFile(loc->search->handle, loc, buf);
fwrite(buf, 1, loc->len, f);
BZ_Free(buf);
fseek(f, 0, SEEK_SET);
*file = f;
com_pathforfile = loc->search;
return loc->len;
}
return -1;
}
// Con_Printf("Opening %s\n", loc->rawname);
*file = fopen(loc->rawname, "rb");
if (!*file)
return -1;
fseek(*file, loc->offset, SEEK_SET);
com_pathforfile = loc->search;
return loc->len;
}
int COM_FOpenFile(char *filename, FILE **file)
{
flocation_t loc;
Con_Printf(CON_ERROR "COM_FOpenFile is obsolete\n");
FS_FLocateFile(filename, FSLFRT_LENGTH, &loc);
com_filesize = -1;
if (loc.search)
{
com_file_copyprotected = loc.search->copyprotected;
com_file_untrusted = !!(loc.search->flags & SPF_UNTRUSTED);
com_filesize = COM_FOpenLocationFILE(&loc, file);
}
else
*file = NULL;
return com_filesize;
}
/*
int COM_FOpenWriteFile(char *filename, FILE **file)
{
COM_CreatePath(filename);
*file = fopen(filename, "wb");
return !!*file;
}
*/
#endif
//int COM_FOpenFile (char *filename, FILE **file) {file_from_pak=0;return COM_FOpenFile2 (filename, file, false);} //FIXME: TEMPORARY
//outbuf might not be written into //outbuf might not be written into
static const char *FS_GetCleanPath(const char *pattern, char *outbuf, int outlen) static const char *FS_GetCleanPath(const char *pattern, char *outbuf, int outlen)
{ {
@ -1219,7 +1170,7 @@ vfsfile_t *VFS_Filter(const char *filename, vfsfile_t *handle)
return handle; return handle;
// ext = COM_FileExtension (filename); // ext = COM_FileExtension (filename);
#ifdef AVAIL_ZLIB #ifdef AVAIL_ZLIB
// if (!stricmp(ext, ".gz")) // if (!Q_strcasecmp(ext, ".gz"))
{ {
return FS_DecompressGZip(handle, NULL); return FS_DecompressGZip(handle, NULL);
} }
@ -1482,7 +1433,7 @@ qbyte *COM_LoadFile (const char *path, int usehunk)
{ {
vfsfile_t *f; vfsfile_t *f;
qbyte *buf; qbyte *buf;
int len; qofs_t len;
char base[MAX_OSPATH]; char base[MAX_OSPATH];
flocation_t loc; flocation_t loc;
FS_FLocateFile(path, FSLFRT_LENGTH, &loc); FS_FLocateFile(path, FSLFRT_LENGTH, &loc);
@ -1490,6 +1441,8 @@ qbyte *COM_LoadFile (const char *path, int usehunk)
if (!loc.search) if (!loc.search)
return NULL; //wasn't found return NULL; //wasn't found
if (loc.len > 0x7fffffff) //don't malloc 5000gb sparse files or anything crazy on a 32bit system...
return NULL;
f = loc.search->handle->OpenVFS(loc.search->handle, &loc, "rb"); f = loc.search->handle->OpenVFS(loc.search->handle, &loc, "rb");
if (!f) if (!f)
@ -1581,11 +1534,11 @@ qbyte *QDECL COM_LoadStackFile (const char *path, void *buffer, int bufsize)
/*warning: at some point I'll change this function to return only read-only buffers*/ /*warning: at some point I'll change this function to return only read-only buffers*/
int FS_LoadFile(char *name, void **file) qofs_t FS_LoadFile(char *name, void **file)
{ {
*file = FS_LoadMallocFile(name); *file = FS_LoadMallocFile(name);
if (!*file) if (!*file)
return -1; return (qofs_t)-1;
return com_filesize; return com_filesize;
} }
void FS_FreeFile(void *file) void FS_FreeFile(void *file)
@ -1595,7 +1548,7 @@ void FS_FreeFile(void *file)
void COM_EnumerateFiles (const char *match, int (QDECL *func)(const char *, int, void *, searchpathfuncs_t*), void *parm) void COM_EnumerateFiles (const char *match, int (QDECL *func)(const char *, qofs_t, void *, searchpathfuncs_t*), void *parm)
{ {
searchpath_t *search; searchpath_t *search;
for (search = com_searchpaths; search ; search = search->next) for (search = com_searchpaths; search ; search = search->next)
@ -1628,7 +1581,7 @@ void COM_FlushTempoaryPacks(void)
com_purepaths = NULL; com_purepaths = NULL;
} }
qboolean COM_LoadMapPackFile (const char *filename, int ofs) qboolean COM_LoadMapPackFile (const char *filename, qofs_t ofs)
{ {
return false; return false;
} }
@ -1643,7 +1596,7 @@ searchpathfuncs_t *FS_GetOldPath(searchpath_t **oldpaths, const char *dir, unsig
{ {
p = *oldpaths; p = *oldpaths;
if (!stricmp(p->logicalpath, dir)) if (!Q_strcasecmp(p->logicalpath, dir))
{ {
*keepflags |= p->flags & (SPF_REFERENCED | SPF_UNTRUSTED); *keepflags |= p->flags & (SPF_REFERENCED | SPF_UNTRUSTED);
*oldpaths = p->next; *oldpaths = p->next;
@ -1664,7 +1617,7 @@ typedef struct {
const char *puredesc; const char *puredesc;
} wildpaks_t; } wildpaks_t;
static int QDECL FS_AddWildDataFiles (const char *descriptor, int size, void *vparam, searchpathfuncs_t *funcs) static int QDECL FS_AddWildDataFiles (const char *descriptor, qofs_t size, void *vparam, searchpathfuncs_t *funcs)
{ {
wildpaks_t *param = vparam; wildpaks_t *param = vparam;
vfsfile_t *vfs; vfsfile_t *vfs;
@ -1679,7 +1632,7 @@ static int QDECL FS_AddWildDataFiles (const char *descriptor, int size, void *vp
for (search = com_searchpaths; search; search = search->next) for (search = com_searchpaths; search; search = search->next)
{ {
if (!stricmp(search->logicalpath, pakfile)) //assumption: first member of structure is a char array if (!Q_strcasecmp(search->logicalpath, pakfile)) //assumption: first member of structure is a char array
return true; //already loaded (base paths?) return true; //already loaded (base paths?)
} }
@ -1791,9 +1744,9 @@ static void FS_AddDataFiles(searchpath_t **oldpaths, const char *purepath, const
for (oldp = com_searchpaths; oldp; oldp = oldp->next) for (oldp = com_searchpaths; oldp; oldp = oldp->next)
{ {
if (!stricmp(oldp->purepath, fs_manifest->package[i].path)) if (!Q_strcasecmp(oldp->purepath, fs_manifest->package[i].path))
break; break;
if (!stricmp(oldp->logicalpath, lname)) if (!Q_strcasecmp(oldp->logicalpath, lname))
break; break;
} }
if (!oldp) if (!oldp)
@ -1902,6 +1855,9 @@ void COM_FlushFSCache(void)
com_fschanged |= search->handle->PollChanges(search->handle); com_fschanged |= search->handle->PollChanges(search->handle);
} }
} }
//rebuild it if needed
FS_RebuildFSHash();
} }
/*since should start as 0, otherwise this can be used to poll*/ /*since should start as 0, otherwise this can be used to poll*/
@ -1940,7 +1896,7 @@ void FS_AddGameDirectory (searchpath_t **oldpaths, const char *puredir, const ch
for (search = com_searchpaths; search; search = search->next) for (search = com_searchpaths; search; search = search->next)
{ {
if (!stricmp(search->logicalpath, dir)) if (!Q_strcasecmp(search->logicalpath, dir))
return; //already loaded (base paths?) return; //already loaded (base paths?)
} }
@ -2554,7 +2510,7 @@ void FS_ReloadPackFilesFlags(unsigned int reloadflags)
//this works around 1.01 vs 1.06 issues. //this works around 1.01 vs 1.06 issues.
for (sp = com_searchpaths; sp; sp = sp->next) for (sp = com_searchpaths; sp; sp = sp->next)
{ {
if (!stricmp(pname, sp->purepath)) if (!Q_strcasecmp(pname, sp->purepath))
break; break;
} }
} }
@ -2847,17 +2803,7 @@ qboolean Sys_FindGameData(const char *poshname, const char *gamename, char *base
BROWSEINFO bi; BROWSEINFO bi;
LPITEMIDLIST il; LPITEMIDLIST il;
memset(&bi, 0, sizeof(bi)); memset(&bi, 0, sizeof(bi));
bi.hwndOwner = mainwindow; //note that this is usually still null
#if defined(_SDL) && defined (WIN32) && defined (MINGW) // mingw32 sdl cross compiled binary, code completely untested, doesn't crash so good sign ~moodles
SDL_SysWMinfo wmInfo;
SDL_GetWMInfo(&wmInfo);
HWND sys_parentwindow = wmInfo.window;
if (sys_parentwindow)
bi.hwndOwner = sys_parentwindow; //note that this is usually still null
else
#endif
bi.hwndOwner = mainwindow; //note that this is usually still null
bi.pidlRoot = NULL; bi.pidlRoot = NULL;
bi.pszDisplayName = resultpath; bi.pszDisplayName = resultpath;
bi.lpszTitle = va("Please locate your existing %s installation", poshname); bi.lpszTitle = va("Please locate your existing %s installation", poshname);
@ -3461,8 +3407,6 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs)
} }
fs_manifest = man; fs_manifest = man;
blockcache = true;
if (man->installation && *man->installation) if (man->installation && *man->installation)
{ {
for (i = 0; gamemode_info[i].argname; i++) for (i = 0; gamemode_info[i].argname; i++)
@ -3562,7 +3506,9 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs)
} }
} }
} }
blockcache = false;
//rebuild the cache now, should be safe to waste some cycles on it
FS_RebuildFSHash();
COM_Effectinfo_Clear(); COM_Effectinfo_Clear();
#ifndef SERVERONLY #ifndef SERVERONLY
@ -3589,7 +3535,7 @@ void FS_ChangeGame_f(void)
{ {
for (i = 0; gamemode_info[i].argname; i++) for (i = 0; gamemode_info[i].argname; i++)
{ {
if (!stricmp(gamemode_info[i].argname+1, arg)) if (!Q_strcasecmp(gamemode_info[i].argname+1, arg))
{ {
Con_Printf("Switching to %s\n", gamemode_info[i].argname+1); Con_Printf("Switching to %s\n", gamemode_info[i].argname+1);
FS_ChangeGame(FS_GenerateLegacyManifest(NULL, 0, true, i), true); FS_ChangeGame(FS_GenerateLegacyManifest(NULL, 0, true, i), true);

View file

@ -21,13 +21,13 @@ struct searchpathfuncs_s
int fsver; int fsver;
void (QDECL *ClosePath)(searchpathfuncs_t *handle); void (QDECL *ClosePath)(searchpathfuncs_t *handle);
void (QDECL *GetPathDetails)(searchpathfuncs_t *handle, char *outdetails, unsigned int sizeofdetails); void (QDECL *GetPathDetails)(searchpathfuncs_t *handle, char *outdetails, size_t sizeofdetails);
void (QDECL *BuildHash)(searchpathfuncs_t *handle, int depth, void (QDECL *FS_AddFileHash)(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle)); void (QDECL *BuildHash)(searchpathfuncs_t *handle, int depth, void (QDECL *FS_AddFileHash)(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle));
unsigned int (QDECL *FindFile)(searchpathfuncs_t *handle, flocation_t *loc, const char *name, void *hashedresult); //true if found (hashedresult can be NULL) unsigned int (QDECL *FindFile)(searchpathfuncs_t *handle, flocation_t *loc, const char *name, void *hashedresult); //true if found (hashedresult can be NULL)
//note that if rawfile and offset are set, many Com_FileOpens will read the raw file //note that if rawfile and offset are set, many Com_FileOpens will read the raw file
//otherwise ReadFile will be called instead. //otherwise ReadFile will be called instead.
void (QDECL *ReadFile)(searchpathfuncs_t *handle, flocation_t *loc, char *buffer); //reads the entire file in one go (size comes from loc, so make sure the loc is valid, this is for performance with compressed archives) void (QDECL *ReadFile)(searchpathfuncs_t *handle, flocation_t *loc, char *buffer); //reads the entire file in one go (size comes from loc, so make sure the loc is valid, this is for performance with compressed archives)
int (QDECL *EnumerateFiles)(searchpathfuncs_t *handle, const char *match, int (QDECL *func)(const char *fname, int fsize, void *parm, searchpathfuncs_t *spath), void *parm); int (QDECL *EnumerateFiles)(searchpathfuncs_t *handle, const char *match, int (QDECL *func)(const char *fname, qofs_t fsize, void *parm, searchpathfuncs_t *spath), void *parm);
int (QDECL *GeneratePureCRC) (searchpathfuncs_t *handle, int seed, int usepure); int (QDECL *GeneratePureCRC) (searchpathfuncs_t *handle, int seed, int usepure);

View file

@ -55,7 +55,7 @@ typedef struct
#define MAX_FILES_IN_PACK 2048 #define MAX_FILES_IN_PACK 2048
static void QDECL FSPAK_GetPathDetails(searchpathfuncs_t *handle, char *out, unsigned int outlen) static void QDECL FSPAK_GetPathDetails(searchpathfuncs_t *handle, char *out, size_t outlen)
{ {
pack_t *pak = (pack_t*)handle; pack_t *pak = (pack_t*)handle;
@ -87,7 +87,7 @@ static void QDECL FSPAK_BuildHash(searchpathfuncs_t *handle, int depth, void (QD
AddFileHash(depth, pak->files[i].name, &pak->files[i].bucket, &pak->files[i]); AddFileHash(depth, pak->files[i].name, &pak->files[i].bucket, &pak->files[i]);
} }
} }
static int QDECL FSPAK_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const char *filename, void *hashedresult) static unsigned int QDECL FSPAK_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const char *filename, void *hashedresult)
{ {
mpackfile_t *pf = hashedresult; mpackfile_t *pf = hashedresult;
int i; int i;
@ -125,7 +125,7 @@ static int QDECL FSPAK_FLocate(searchpathfuncs_t *handle, flocation_t *loc, cons
} }
return FF_NOTFOUND; return FF_NOTFOUND;
} }
static int QDECL FSPAK_EnumerateFiles (searchpathfuncs_t *handle, const char *match, int (QDECL *func)(const char *, int, void *, searchpathfuncs_t *spath), void *parm) static int QDECL FSPAK_EnumerateFiles (searchpathfuncs_t *handle, const char *match, int (QDECL *func)(const char *, qofs_t, void *, searchpathfuncs_t *spath), void *parm)
{ {
pack_t *pak = (pack_t*)handle; pack_t *pak = (pack_t*)handle;
int num; int num;
@ -174,9 +174,9 @@ static int QDECL FSPAK_GeneratePureCRC(searchpathfuncs_t *handle, int seed, int
typedef struct { typedef struct {
vfsfile_t funcs; vfsfile_t funcs;
pack_t *parentpak; pack_t *parentpak;
unsigned long startpos; qofs_t startpos;
unsigned long length; qofs_t length;
unsigned long currentpos; qofs_t currentpos;
} vfspack_t; } vfspack_t;
static int QDECL VFSPAK_ReadBytes (struct vfsfile_s *vfs, void *buffer, int bytestoread) static int QDECL VFSPAK_ReadBytes (struct vfsfile_s *vfs, void *buffer, int bytestoread)
{ {
@ -206,7 +206,7 @@ static int QDECL VFSPAK_WriteBytes (struct vfsfile_s *vfs, const void *buffer, i
Sys_Error("Cannot write to pak files\n"); Sys_Error("Cannot write to pak files\n");
return 0; return 0;
} }
static qboolean QDECL VFSPAK_Seek (struct vfsfile_s *vfs, unsigned long pos) static qboolean QDECL VFSPAK_Seek (struct vfsfile_s *vfs, qofs_t pos)
{ {
vfspack_t *vfsp = (vfspack_t*)vfs; vfspack_t *vfsp = (vfspack_t*)vfs;
if (pos < 0 || pos > vfsp->length) if (pos < 0 || pos > vfsp->length)
@ -215,12 +215,12 @@ static qboolean QDECL VFSPAK_Seek (struct vfsfile_s *vfs, unsigned long pos)
return true; return true;
} }
static unsigned long QDECL VFSPAK_Tell (struct vfsfile_s *vfs) static qofs_t QDECL VFSPAK_Tell (struct vfsfile_s *vfs)
{ {
vfspack_t *vfsp = (vfspack_t*)vfs; vfspack_t *vfsp = (vfspack_t*)vfs;
return vfsp->currentpos - vfsp->startpos; return vfsp->currentpos - vfsp->startpos;
} }
static unsigned long QDECL VFSPAK_GetLen (struct vfsfile_s *vfs) static qofs_t QDECL VFSPAK_GetLen (struct vfsfile_s *vfs)
{ {
vfspack_t *vfsp = (vfspack_t*)vfs; vfspack_t *vfsp = (vfspack_t*)vfs;
return vfsp->length; return vfsp->length;
@ -269,15 +269,6 @@ static void QDECL FSPAK_ReadFile(searchpathfuncs_t *handle, flocation_t *loc, ch
return; return;
VFS_READ(f, buffer, loc->len); VFS_READ(f, buffer, loc->len);
VFS_CLOSE(f); VFS_CLOSE(f);
/*
FILE *f;
f = fopen(loc->rawname, "rb");
if (!f) //err...
return;
fseek(f, loc->offset, SEEK_SET);
fread(buffer, 1, loc->len, f);
fclose(f);
*/
} }

View file

@ -34,12 +34,12 @@ static int QDECL VFSSTDIO_WriteBytes (struct vfsfile_s *file, const void *buffer
vfsstdiofile_t *intfile = (vfsstdiofile_t*)file; vfsstdiofile_t *intfile = (vfsstdiofile_t*)file;
return fwrite(buffer, 1, bytestoread, intfile->handle); return fwrite(buffer, 1, bytestoread, intfile->handle);
} }
static qboolean QDECL VFSSTDIO_Seek (struct vfsfile_s *file, unsigned long pos) static qboolean QDECL VFSSTDIO_Seek (struct vfsfile_s *file, qofs_t pos)
{ {
vfsstdiofile_t *intfile = (vfsstdiofile_t*)file; vfsstdiofile_t *intfile = (vfsstdiofile_t*)file;
return fseek(intfile->handle, pos, SEEK_SET) == 0; return fseek(intfile->handle, pos, SEEK_SET) == 0;
} }
static unsigned long QDECL VFSSTDIO_Tell (struct vfsfile_s *file) static qofs_t QDECL VFSSTDIO_Tell (struct vfsfile_s *file)
{ {
vfsstdiofile_t *intfile = (vfsstdiofile_t*)file; vfsstdiofile_t *intfile = (vfsstdiofile_t*)file;
return ftell(intfile->handle); return ftell(intfile->handle);
@ -49,7 +49,7 @@ static void QDECL VFSSTDIO_Flush(struct vfsfile_s *file)
vfsstdiofile_t *intfile = (vfsstdiofile_t*)file; vfsstdiofile_t *intfile = (vfsstdiofile_t*)file;
fflush(intfile->handle); fflush(intfile->handle);
} }
static unsigned long QDECL VFSSTDIO_GetSize (struct vfsfile_s *file) static qofs_t QDECL VFSSTDIO_GetSize (struct vfsfile_s *file)
{ {
vfsstdiofile_t *intfile = (vfsstdiofile_t*)file; vfsstdiofile_t *intfile = (vfsstdiofile_t*)file;
@ -218,7 +218,7 @@ static qboolean QDECL FSSTDIO_PollChanges(searchpathfuncs_t *handle)
// stdiopath_t *np = handle; // stdiopath_t *np = handle;
return true; //can't verify that or not, so we have to assume the worst return true; //can't verify that or not, so we have to assume the worst
} }
static int QDECL FSSTDIO_RebuildFSHash(const char *filename, int filesize, void *data, searchpathfuncs_t *spath) static int QDECL FSSTDIO_RebuildFSHash(const char *filename, qofs_t filesize, void *data, searchpathfuncs_t *spath)
{ {
stdiopath_t *sp = (void*)spath; stdiopath_t *sp = (void*)spath;
void (QDECL *AddFileHash)(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle) = data; void (QDECL *AddFileHash)(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle) = data;
@ -240,7 +240,7 @@ static void QDECL FSSTDIO_BuildHash(searchpathfuncs_t *handle, int depth, void (
sp->AddFileHash = AddFileHash; sp->AddFileHash = AddFileHash;
Sys_EnumerateFiles(sp->rootpath, "*", FSSTDIO_RebuildFSHash, AddFileHash, handle); Sys_EnumerateFiles(sp->rootpath, "*", FSSTDIO_RebuildFSHash, AddFileHash, handle);
} }
static int QDECL FSSTDIO_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const char *filename, void *hashedresult) static unsigned int QDECL FSSTDIO_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const char *filename, void *hashedresult)
{ {
stdiopath_t *sp = (void*)handle; stdiopath_t *sp = (void*)handle;
int len; int len;
@ -304,7 +304,7 @@ static void QDECL FSSTDIO_ReadFile(searchpathfuncs_t *handle, flocation_t *loc,
fclose(f); fclose(f);
} }
static int QDECL FSSTDIO_EnumerateFiles (searchpathfuncs_t *handle, const char *match, int (QDECL *func)(const char *, int, void *, searchpathfuncs_t *spath), void *parm) static int QDECL FSSTDIO_EnumerateFiles (searchpathfuncs_t *handle, const char *match, int (QDECL *func)(const char *, qofs_t, void *, searchpathfuncs_t *spath), void *parm)
{ {
stdiopath_t *sp = (stdiopath_t*)handle; stdiopath_t *sp = (stdiopath_t*)handle;
return Sys_EnumerateFiles(sp->rootpath, match, func, parm, handle); return Sys_EnumerateFiles(sp->rootpath, match, func, parm, handle);

View file

@ -16,6 +16,7 @@
typedef struct { typedef struct {
searchpathfuncs_t pub; searchpathfuncs_t pub;
HANDLE changenotification; HANDLE changenotification;
void (QDECL *AddFileHash)(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle);
int hashdepth; int hashdepth;
char rootpath[1]; char rootpath[1];
} vfsw32path_t; } vfsw32path_t;
@ -133,9 +134,9 @@ static int QDECL VFSW32_WriteBytes (struct vfsfile_s *file, const void *buffer,
return 0; return 0;
return written; return written;
} }
static qboolean QDECL VFSW32_Seek (struct vfsfile_s *file, unsigned long pos) static qboolean QDECL VFSW32_Seek (struct vfsfile_s *file, qofs_t pos)
{ {
unsigned long upper, lower; DWORD hi, lo;
vfsw32file_t *intfile = (vfsw32file_t*)file; vfsw32file_t *intfile = (vfsw32file_t*)file;
if (intfile->mmap) if (intfile->mmap)
{ {
@ -143,17 +144,18 @@ static qboolean QDECL VFSW32_Seek (struct vfsfile_s *file, unsigned long pos)
return true; return true;
} }
lower = (pos & 0xffffffff); lo = qofs_Low(pos);
upper = ((pos>>16)>>16); hi = qofs_High(pos);
return SetFilePointer(intfile->hand, lo, &hi, FILE_BEGIN) != INVALID_SET_FILE_POINTER;
return SetFilePointer(intfile->hand, lower, &upper, FILE_BEGIN) != INVALID_SET_FILE_POINTER;
} }
static unsigned long QDECL VFSW32_Tell (struct vfsfile_s *file) static qofs_t QDECL VFSW32_Tell (struct vfsfile_s *file)
{ {
DWORD hi = 0, lo;
vfsw32file_t *intfile = (vfsw32file_t*)file; vfsw32file_t *intfile = (vfsw32file_t*)file;
if (intfile->mmap) if (intfile->mmap)
return intfile->offset; return intfile->offset;
return SetFilePointer(intfile->hand, 0, NULL, FILE_CURRENT); lo = SetFilePointer(intfile->hand, 0, &hi, FILE_CURRENT);
return qofs_Make(lo,hi);
} }
static void QDECL VFSW32_Flush(struct vfsfile_s *file) static void QDECL VFSW32_Flush(struct vfsfile_s *file)
{ {
@ -162,13 +164,15 @@ static void QDECL VFSW32_Flush(struct vfsfile_s *file)
FlushViewOfFile(intfile->mmap, intfile->length); FlushViewOfFile(intfile->mmap, intfile->length);
FlushFileBuffers(intfile->hand); FlushFileBuffers(intfile->hand);
} }
static unsigned long QDECL VFSW32_GetSize (struct vfsfile_s *file) static qofs_t QDECL VFSW32_GetSize (struct vfsfile_s *file)
{ {
DWORD lo, hi = 0;
vfsw32file_t *intfile = (vfsw32file_t*)file; vfsw32file_t *intfile = (vfsw32file_t*)file;
if (intfile->mmap) if (intfile->mmap)
return intfile->length; return intfile->length;
return GetFileSize(intfile->hand, NULL); lo = GetFileSize(intfile->hand, &hi);
return qofs_Make(lo,hi);
} }
static void QDECL VFSW32_Close(vfsfile_t *file) static void QDECL VFSW32_Close(vfsfile_t *file)
{ {
@ -180,15 +184,15 @@ static void QDECL VFSW32_Close(vfsfile_t *file)
} }
CloseHandle(intfile->hand); CloseHandle(intfile->hand);
Z_Free(file); Z_Free(file);
COM_FlushFSCache();
} }
vfsfile_t *QDECL VFSW32_Open(const char *osname, const char *mode) //WARNING: handle can be null
static vfsfile_t *QDECL VFSW32_OpenInternal(vfsw32path_t *handle, const char *quakename, const char *osname, const char *mode)
{ {
HANDLE h, mh; HANDLE h, mh;
unsigned int fsize; unsigned int fsize;
void *mmap; void *mmap;
qboolean didexist = true;
vfsw32file_t *file; vfsw32file_t *file;
qboolean read = !!strchr(mode, 'r'); qboolean read = !!strchr(mode, 'r');
@ -214,18 +218,45 @@ vfsfile_t *QDECL VFSW32_Open(const char *osname, const char *mode)
{ {
wchar_t wide[MAX_OSPATH]; wchar_t wide[MAX_OSPATH];
widen(wide, sizeof(wide), osname); widen(wide, sizeof(wide), osname);
if ((write && read) || append)
h = CreateFileW(wide, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_DELETE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); h = INVALID_HANDLE_VALUE;
if (write || append)
{
h = CreateFileW(wide, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE)
{
didexist = false;
if (!read) //if we're not reading, the file will be created anew. make sure we don't just reuse it. we do want to avoid rebuilding our name->location cache though.
{
CloseHandle(h);
h = INVALID_HANDLE_VALUE;
}
}
}
if (h != INVALID_HANDLE_VALUE)
;
else if ((write && read) || append)
h = CreateFileW(wide, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_DELETE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
else if (write) else if (write)
h = CreateFileW(wide, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); h = CreateFileW(wide, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
else if (read) else if (read)
h = CreateFileW(wide, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); h = CreateFileW(wide, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
else else
h = INVALID_HANDLE_VALUE; h = INVALID_HANDLE_VALUE;
} }
if (h == INVALID_HANDLE_VALUE) if (h == INVALID_HANDLE_VALUE)
return NULL; return NULL;
if (!didexist)
{
if (handle && handle->AddFileHash)
handle->AddFileHash(handle->hashdepth, quakename, NULL, handle);
else
COM_RefreshFSCache_f(); //no idea where this path is. if its inside a quake path, make sure it gets flushed properly. FIXME: his shouldn't be needed if we have change notifications working properly.
}
fsize = GetFileSize(h, NULL); fsize = GetFileSize(h, NULL);
if (write || append || text || fsize > 1024*1024*5) if (write || append || text || fsize > 1024*1024*5)
{ {
@ -273,11 +304,17 @@ vfsfile_t *QDECL VFSW32_Open(const char *osname, const char *mode)
return (vfsfile_t*)file; return (vfsfile_t*)file;
} }
vfsfile_t *QDECL VFSW32_Open(const char *osname, const char *mode)
{
//called without regard to a search path
return VFSW32_OpenInternal(NULL, NULL, osname, mode);
}
static vfsfile_t *QDECL VFSW32_OpenVFS(searchpathfuncs_t *handle, flocation_t *loc, const char *mode) static vfsfile_t *QDECL VFSW32_OpenVFS(searchpathfuncs_t *handle, flocation_t *loc, const char *mode)
{ {
//path is already cleaned, as anything that gets a valid loc needs cleaning up first. //path is already cleaned, as anything that gets a valid loc needs cleaning up first.
vfsw32path_t *wp = (void*)handle;
return VFSW32_Open(loc->rawname, mode); return VFSW32_OpenInternal(wp, loc->rawname+strlen(wp->rootpath)+1, loc->rawname, mode);
} }
static void QDECL VFSW32_ClosePath(searchpathfuncs_t *handle) static void QDECL VFSW32_ClosePath(searchpathfuncs_t *handle)
{ {
@ -311,10 +348,9 @@ static qboolean QDECL VFSW32_PollChanges(searchpathfuncs_t *handle)
} }
return result; return result;
} }
static int QDECL VFSW32_RebuildFSHash(const char *filename, int filesize, void *handle, searchpathfuncs_t *spath) static int QDECL VFSW32_RebuildFSHash(const char *filename, qofs_t filesize, void *handle, searchpathfuncs_t *spath)
{ {
vfsw32path_t *wp = (void*)spath; vfsw32path_t *wp = (void*)spath;
void (QDECL *AddFileHash)(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle) = handle;
if (filename[strlen(filename)-1] == '/') if (filename[strlen(filename)-1] == '/')
{ //this is actually a directory { //this is actually a directory
@ -324,16 +360,17 @@ static int QDECL VFSW32_RebuildFSHash(const char *filename, int filesize, void *
return true; return true;
} }
AddFileHash(wp->hashdepth, filename, NULL, wp); wp->AddFileHash(wp->hashdepth, filename, NULL, wp);
return true; return true;
} }
static void QDECL VFSW32_BuildHash(searchpathfuncs_t *handle, int hashdepth, void (QDECL *AddFileHash)(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle)) static void QDECL VFSW32_BuildHash(searchpathfuncs_t *handle, int hashdepth, void (QDECL *AddFileHash)(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle))
{ {
vfsw32path_t *wp = (void*)handle; vfsw32path_t *wp = (void*)handle;
wp->AddFileHash = AddFileHash;
wp->hashdepth = hashdepth; wp->hashdepth = hashdepth;
Sys_EnumerateFiles(wp->rootpath, "*", VFSW32_RebuildFSHash, AddFileHash, handle); Sys_EnumerateFiles(wp->rootpath, "*", VFSW32_RebuildFSHash, AddFileHash, handle);
} }
static int QDECL VFSW32_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const char *filename, void *hashedresult) static unsigned int QDECL VFSW32_FLocate(searchpathfuncs_t *handle, flocation_t *loc, const char *filename, void *hashedresult)
{ {
vfsw32path_t *wp = (void*)handle; vfsw32path_t *wp = (void*)handle;
FILE *f; FILE *f;
@ -392,7 +429,7 @@ static void QDECL VFSW32_ReadFile(searchpathfuncs_t *handle, flocation_t *loc, c
fread(buffer, 1, loc->len, f); fread(buffer, 1, loc->len, f);
fclose(f); fclose(f);
} }
static int QDECL VFSW32_EnumerateFiles (searchpathfuncs_t *handle, const char *match, int (QDECL *func)(const char *, int, void *, searchpathfuncs_t *spath), void *parm) static int QDECL VFSW32_EnumerateFiles (searchpathfuncs_t *handle, const char *match, int (QDECL *func)(const char *, qofs_t, void *, searchpathfuncs_t *spath), void *parm)
{ {
vfsw32path_t *wp = (vfsw32path_t*)handle; vfsw32path_t *wp = (vfsw32path_t*)handle;
return Sys_EnumerateFiles(wp->rootpath, match, func, parm, handle); return Sys_EnumerateFiles(wp->rootpath, match, func, parm, handle);

File diff suppressed because it is too large Load diff

View file

@ -311,46 +311,41 @@ struct icestate_s *QDECL ICE_Create(void *module, char *conname, char *peername,
if (collection) if (collection)
{ {
int i; int i, m;
int adrno, adrcount=1;
netadr_t adr; netadr_t addr[64];
for (i = 0; i < MAX_CONNECTIONS; i++) struct ftenet_generic_connection_s *gcon[sizeof(addr)/sizeof(addr[0])];
int flags[sizeof(addr)/sizeof(addr[0])];
m = NET_EnumerateAddresses(collection, gcon, flags, addr, sizeof(addr)/sizeof(addr[0]));
for (i = 0; i < m; i++)
{ {
if (!collection->conn[i]) if (addr[i].type == NA_IP || addr[i].type == NA_IPV6)
continue;
adrno = 0;
if (collection->conn[i]->GetLocalAddress)
{ {
for (adrcount=1; (adrcount = collection->conn[i]->GetLocalAddress(collection->conn[i], &adr, adrno)) && adrno < adrcount; adrno++) ICE_AddLCandidateInfo(con, &addr[i], i, ICE_HOST);
{
if (adr.type == NA_IP || adr.type == NA_IPV6)
{
adr.connum = i;
ICE_AddLCandidateInfo(con, &adr, adrno, ICE_HOST);
/* /*
cand = Z_Malloc(sizeof(*cand)); cand = Z_Malloc(sizeof(*cand));
cand->info.network = i; cand->info.network = i;
cand->info.port = ntohs(adr.port); cand->info.port = ntohs(adr.port);
adr.port = 0; //to make sure its not part of the string... adr.port = 0; //to make sure its not part of the string...
Q_strncpyz(cand->info.addr, NET_AdrToString(adrbuf, sizeof(adrbuf), &adr), sizeof(cand->info.addr)); Q_strncpyz(cand->info.addr, NET_AdrToString(adrbuf, sizeof(adrbuf), &adr), sizeof(cand->info.addr));
cand->info.generation = 0; cand->info.generation = 0;
cand->info.component = 1; cand->info.component = 1;
cand->info.foundation = 1; cand->info.foundation = 1;
cand->info.priority = cand->info.priority =
(1<<24)*(126) + (1<<24)*(126) +
(1<<8)*((adr.type == NA_IP?32768:0)+net*256+(255-adrno)) + (1<<8)*((adr.type == NA_IP?32768:0)+net*256+(255-adrno)) +
(1<<0)*(256 - cand->info.component); (1<<0)*(256 - cand->info.component);
Sys_RandomBytes((void*)rnd, sizeof(rnd)); Sys_RandomBytes((void*)rnd, sizeof(rnd));
Q_strncpyz(cand->info.candidateid, va("x%08x%08x", rnd[0], rnd[1]), sizeof(cand->info.candidateid)); Q_strncpyz(cand->info.candidateid, va("x%08x%08x", rnd[0], rnd[1]), sizeof(cand->info.candidateid));
cand->dirty = true; cand->dirty = true;
cand->next = con->lc; cand->next = con->lc;
con->lc = cand; con->lc = cand;
*/ */
}
}
} }
} }
} }

View file

@ -573,17 +573,17 @@ static int QDECL SSPI_WriteBytes (struct vfsfile_s *file, const void *buffer, in
return bytestowrite; return bytestowrite;
} }
static qboolean QDECL SSPI_Seek (struct vfsfile_s *file, unsigned long pos) static qboolean QDECL SSPI_Seek (struct vfsfile_s *file, qofs_t pos)
{ {
SSPI_Error((sslfile_t*)file, "unable to seek on streams\n"); SSPI_Error((sslfile_t*)file, "unable to seek on streams\n");
return false; return false;
} }
static unsigned long QDECL SSPI_Tell (struct vfsfile_s *file) static qofs_t QDECL SSPI_Tell (struct vfsfile_s *file)
{ {
SSPI_Error((sslfile_t*)file, "unable to seek on streams\n"); SSPI_Error((sslfile_t*)file, "unable to seek on streams\n");
return 0; return 0;
} }
static unsigned long QDECL SSPI_GetLen (struct vfsfile_s *file) static qofs_t QDECL SSPI_GetLen (struct vfsfile_s *file)
{ {
return 0; return 0;
} }

View file

@ -1557,14 +1557,16 @@ void NET_SendLoopPacket (int sock, int length, void *data, netadr_t *to)
loop->msgs[i].datalen = length; loop->msgs[i].datalen = length;
} }
int FTENET_Loop_GetLocalAddress(ftenet_generic_connection_t *con, netadr_t *out, int adrnum) int FTENET_Loop_GetLocalAddresses(struct ftenet_generic_connection_s *con, unsigned int *adrflags, netadr_t *addresses, int maxaddresses)
{ {
if (adrnum==0) if (maxaddresses)
{ {
out->type = NA_LOOPBACK; addresses->type = NA_LOOPBACK;
out->port = con->thesocket+1; addresses->port = con->thesocket+1;
*adrflags = 0;
return 1;
} }
return 1; return 0;
} }
qboolean FTENET_Loop_GetPacket(ftenet_generic_connection_t *con) qboolean FTENET_Loop_GetPacket(ftenet_generic_connection_t *con)
@ -1613,7 +1615,7 @@ static ftenet_generic_connection_t *FTENET_Loop_EstablishConnection(qboolean iss
{ {
loopbacks[sock].inited = true; loopbacks[sock].inited = true;
newcon->GetLocalAddress = FTENET_Loop_GetLocalAddress; newcon->GetLocalAddresses = FTENET_Loop_GetLocalAddresses;
newcon->GetPacket = FTENET_Loop_GetPacket; newcon->GetPacket = FTENET_Loop_GetPacket;
newcon->SendPacket = FTENET_Loop_SendPacket; newcon->SendPacket = FTENET_Loop_SendPacket;
newcon->Close = FTENET_Loop_Close; newcon->Close = FTENET_Loop_Close;
@ -1664,7 +1666,7 @@ typedef struct
unsigned int refreshtime; unsigned int refreshtime;
} pmpcon_t; } pmpcon_t;
int FTENET_NATPMP_GetLocalAddress(struct ftenet_generic_connection_s *con, netadr_t *local, int adridx); int FTENET_NATPMP_GetLocalAddresses(struct ftenet_generic_connection_s *con, unsigned int *adrflags, netadr_t *addresses, int maxaddresses);
static qboolean NET_Was_NATPMP(ftenet_connections_t *collection) static qboolean NET_Was_NATPMP(ftenet_connections_t *collection)
{ {
pmpcon_t *pmp; pmpcon_t *pmp;
@ -1688,7 +1690,7 @@ static qboolean NET_Was_NATPMP(ftenet_connections_t *collection)
{ {
if (!collection->conn[i]) if (!collection->conn[i])
continue; continue;
if (collection->conn[i]->GetLocalAddress == FTENET_NATPMP_GetLocalAddress) if (collection->conn[i]->GetLocalAddresses == FTENET_NATPMP_GetLocalAddresses)
{ {
pmp = (pmpcon_t*)collection->conn[i]; pmp = (pmpcon_t*)collection->conn[i];
if (NET_CompareAdr(&pmp->pmpaddr, &net_from)) if (NET_CompareAdr(&pmp->pmpaddr, &net_from))
@ -1704,7 +1706,7 @@ static qboolean NET_Was_NATPMP(ftenet_connections_t *collection)
pmp->natadr.port = 0; pmp->natadr.port = 0;
memcpy(pmp->natadr.address.ip, pmpreqrep->ipv4, sizeof(pmp->natadr.address.ip)); memcpy(pmp->natadr.address.ip, pmpreqrep->ipv4, sizeof(pmp->natadr.address.ip));
NET_AdrToString(adrbuf, sizeof(adrbuf), &pmp->natadr); NET_AdrToString(adrbuf, sizeof(adrbuf), &pmp->natadr);
pmp->natadr.connum = i; pmp->natadr.connum = i+1;
Con_DPrintf("NAT-PMP: Public ip is %s\n", adrbuf); Con_DPrintf("NAT-PMP: Public ip is %s\n", adrbuf);
if (pmp->natadr.type && pmp->natadr.port) if (pmp->natadr.type && pmp->natadr.port)
@ -1752,9 +1754,13 @@ static qboolean NET_Was_NATPMP(ftenet_connections_t *collection)
static void FTENET_NATPMP_Refresh(pmpcon_t *pmp, short oldport, ftenet_connections_t *collection) static void FTENET_NATPMP_Refresh(pmpcon_t *pmp, short oldport, ftenet_connections_t *collection)
{ {
int i; int i, m;
int adrno, adrcount=1;
netadr_t adr; netadr_t adr;
netadr_t addr[64];
struct ftenet_generic_connection_s *con[sizeof(addr)/sizeof(addr[0])];
int flags[sizeof(addr)/sizeof(addr[0])];
struct struct
{ {
qbyte ver; qbyte op; short reserved1; qbyte ver; qbyte op; short reserved1;
@ -1772,78 +1778,90 @@ static void FTENET_NATPMP_Refresh(pmpcon_t *pmp, short oldport, ftenet_connectio
if (!collection) if (!collection)
return; return;
for (i = 0; i < MAX_CONNECTIONS; i++) m = NET_EnumerateAddresses(collection, con, flags, addr, sizeof(addr)/sizeof(addr[0]));
for (i = 0; i < m; i++)
{ {
if (!collection->conn[i]) //ignore any ips which are proxied by other people. that would be too weird.
if (flags[i] & (ADDR_NATPMP|ADDR_UPNPIGP))
continue; continue;
if (collection->conn[i]->GetLocalAddress && collection->conn[i]->GetLocalAddress != FTENET_NATPMP_GetLocalAddress)
adr = addr[i];
//unipv6ify it if its a hybrid socket.
if (adr.type == NA_IPV6 &&
!*(int*)&adr.address.ip6[0] &&
!*(int*)&adr.address.ip6[4] &&
!*(short*)&adr.address.ip6[8] &&
*(short*)&adr.address.ip6[10]==(short)0xffff &&
!*(int*)&adr.address.ip6[12])
{ {
for (adrno = 0, adrcount=1; (adrcount = collection->conn[i]->GetLocalAddress(collection->conn[i], &adr, adrno)) && adrno < adrcount; adrno++) *(int*)adr.address.ip = *(int*)&adr.address.ip6[12];
{ adr.type = NA_IP;
// Con_Printf("net address (%s): %s\n", collection->conn[i]->name, NET_AdrToString(adrbuf, sizeof(adrbuf), adr));
//unipv6ify it if its a hybrid socket.
if (adr.type == NA_IPV6 &&
!*(int*)&adr.address.ip6[0] &&
!*(int*)&adr.address.ip6[4] &&
!*(short*)&adr.address.ip6[8] &&
*(short*)&adr.address.ip6[10]==(short)0xffff &&
!*(int*)&adr.address.ip6[12])
{
*(int*)adr.address.ip = *(int*)&adr.address.ip6[12];
adr.type = NA_IP;
}
if (adr.type == NA_IP)
{
if (adr.address.ip[0] == 127) //yes. loopback has a lot of ip addresses. wasteful but whatever.
continue;
//assume a netmask of 255.255.255.0
adr.address.ip[3] = 1;
}
// else if (adr.type == NA_IPV6)
// {
// }
else
continue;
pmpreqmsg.privport = adr.port;
pmpreqmsg.pubport = oldport?oldport:adr.port;
if (*(int*)pmp->reqpmpaddr.address.ip == INADDR_ANY)
{
pmp->pmpaddr = adr;
pmp->pmpaddr.port = pmp->reqpmpaddr.port;
}
else
pmp->pmpaddr = pmp->reqpmpaddr;
if (*(int*)pmp->pmpaddr.address.ip == INADDR_ANY)
continue;
//get the public ip.
pmpreqmsg.op = 0;
NET_SendPacket(NS_SERVER, 2, &pmpreqmsg, &pmp->pmpaddr);
//open the firewall/nat.
pmpreqmsg.op = 1;
NET_SendPacket(NS_SERVER, sizeof(pmpreqmsg), &pmpreqmsg, &pmp->pmpaddr);
break;
}
} }
if (adr.type == NA_IP)
{
if (adr.address.ip[0] == 127) //yes. loopback has a lot of ip addresses. wasteful but whatever.
continue;
//assume a netmask of 255.255.255.0
adr.address.ip[3] = 1;
}
// else if (adr.type == NA_IPV6)
// {
// }
else
continue;
pmpreqmsg.privport = adr.port;
pmpreqmsg.pubport = oldport?oldport:adr.port;
if (*(int*)pmp->reqpmpaddr.address.ip == INADDR_ANY)
{
pmp->pmpaddr = adr;
pmp->pmpaddr.port = pmp->reqpmpaddr.port;
}
else
pmp->pmpaddr = pmp->reqpmpaddr;
if (*(int*)pmp->pmpaddr.address.ip == INADDR_ANY)
continue;
//get the public ip.
pmpreqmsg.op = 0;
NET_SendPacket(NS_SERVER, 2, &pmpreqmsg, &pmp->pmpaddr);
//open the firewall/nat.
pmpreqmsg.op = 1;
NET_SendPacket(NS_SERVER, sizeof(pmpreqmsg), &pmpreqmsg, &pmp->pmpaddr);
break;
} }
} }
#define PMP_POLL_TIME (1000*30)//every 30 seconds #define PMP_POLL_TIME (1000*30)//every 30 seconds
int FTENET_NATPMP_GetLocalAddress(struct ftenet_generic_connection_s *con, netadr_t *local, int adridx) qboolean Net_OpenUDPPort(char *privateip, int privateport, char *publicip, size_t publiciplen, int *publicport);
int FTENET_NATPMP_GetLocalAddresses(struct ftenet_generic_connection_s *con, unsigned int *adrflags, netadr_t *addresses, int maxaddresses)
{ {
pmpcon_t *pmp = (pmpcon_t*)con; pmpcon_t *pmp = (pmpcon_t*)con;
local->type = NA_INVALID; /*
char pubip[256];
int pubport;
if (adridx == 0) if (Net_OpenUDPPort("192.168.1.4", 27500, pubip, sizeof(pubip), &pubport))
*local = pmp->natadr; {
return (pmp->natadr.type != NA_INVALID) && (pmp->natadr.port != 0); *adrflags = ADDR_UPNPIGP;
NET_StringToAdr(pubip, pubport, addresses);
return 1;
}
*/
if (maxaddresses)
{
*adrflags = ADDR_NATPMP;
*addresses = pmp->natadr;
return (pmp->natadr.type != NA_INVALID) && (pmp->natadr.port != 0);
}
return 0;
} }
qboolean FTENET_NATPMP_GetPacket(struct ftenet_generic_connection_s *con) qboolean FTENET_NATPMP_GetPacket(struct ftenet_generic_connection_s *con)
{ {
@ -1876,12 +1894,12 @@ ftenet_generic_connection_t *FTENET_NATPMP_EstablishConnection(qboolean isserver
pmpadr.type = NA_IP; pmpadr.type = NA_IP;
if (pmpadr.type != NA_IP) if (pmpadr.type != NA_IP)
return NULL; return NULL;
pmp = Z_Malloc(sizeof(*pmp)); pmp = Z_Malloc(sizeof(*pmp));
pmp->col = svs.sockets; pmp->col = svs.sockets;
Q_strncpyz(pmp->pub.name, "natpmp", sizeof(pmp->pub.name)); Q_strncpyz(pmp->pub.name, "natpmp", sizeof(pmp->pub.name));
pmp->reqpmpaddr = pmpadr; pmp->reqpmpaddr = pmpadr;
pmp->pub.GetLocalAddress = FTENET_NATPMP_GetLocalAddress; pmp->pub.GetLocalAddresses = FTENET_NATPMP_GetLocalAddresses;
pmp->pub.GetPacket = FTENET_NATPMP_GetPacket; pmp->pub.GetPacket = FTENET_NATPMP_GetPacket;
//qboolean (*ChangeLocalAddress)(struct ftenet_generic_connection_s *con, const char *newaddress); //qboolean (*ChangeLocalAddress)(struct ftenet_generic_connection_s *con, const char *newaddress);
pmp->pub.SendPacket = FTENET_NATPMP_SendPacket; pmp->pub.SendPacket = FTENET_NATPMP_SendPacket;
@ -1896,10 +1914,6 @@ ftenet_generic_connection_t *FTENET_NATPMP_EstablishConnection(qboolean isserver
} }
#endif #endif
#ifdef UPNP
ftenet_generic_connection_t *FTENET_NATUPNP_EstablishConnection(qboolean isserver, const char *address);
#endif
qboolean FTENET_AddToCollection_Ptr(ftenet_connections_t *col, const char *name, const char *address, ftenet_generic_connection_t *(*establish)(qboolean isserver, const char *address), qboolean islisten) qboolean FTENET_AddToCollection_Ptr(ftenet_connections_t *col, const char *name, const char *address, ftenet_generic_connection_t *(*establish)(qboolean isserver, const char *address), qboolean islisten)
{ {
int count = 0; int count = 0;
@ -2029,15 +2043,14 @@ void FTENET_Generic_Close(ftenet_generic_connection_t *con)
} }
#ifdef _WIN32 #ifdef _WIN32
int FTENET_GetLocalAddress(netadr_t *out, int port, int count, qboolean ipx, qboolean ipv4, qboolean ipv6) int FTENET_GetLocalAddress(int port, qboolean ipx, qboolean ipv4, qboolean ipv6, unsigned int *adrflags, netadr_t *addresses, int maxaddresses)
{ {
//in win32, we can look up our own hostname to retrieve a list of local interface addresses. //in win32, we can look up our own hostname to retrieve a list of local interface addresses.
netadr_t adr;
#ifdef USE_GETHOSTNAME_LOCALLISTING #ifdef USE_GETHOSTNAME_LOCALLISTING
char adrs[MAX_ADR_SIZE]; char adrs[MAX_ADR_SIZE];
int b; int b;
#endif #endif
int idx = 0; int found = 0;
gethostname(adrs, sizeof(adrs)); gethostname(adrs, sizeof(adrs));
#ifdef IPPROTO_IPV6 #ifdef IPPROTO_IPV6
@ -2060,28 +2073,35 @@ int FTENET_GetLocalAddress(netadr_t *out, int port, int count, qboolean ipx, qbo
|| (itr->ai_addr->sa_family == AF_IPX && ipx) || (itr->ai_addr->sa_family == AF_IPX && ipx)
#endif #endif
) )
if (idx++ == count) if (maxaddresses)
{ {
SockadrToNetadr((struct sockaddr_qstorage*)itr->ai_addr, out); SockadrToNetadr((struct sockaddr_qstorage*)itr->ai_addr, addresses);
out->port = port; addresses->port = port;
*adrflags++ = 0;
addresses++;
maxaddresses--;
found++;
} }
} }
pfreeaddrinfo(result); pfreeaddrinfo(result);
/*if none found, fill in the 0.0.0.0 or whatever*/ /*if none found, fill in the 0.0.0.0 or whatever*/
if (!idx) if (!found && maxaddresses)
{ {
idx++; memset(addresses, 0, sizeof(*addresses));
memset(out, 0, sizeof(*out)); addresses->port = port;
out->port = port;
if (ipv6) if (ipv6)
out->type = NA_IPV6; addresses->type = NA_IPV6;
else if (ipv4) else if (ipv4)
out->type = NA_IP; addresses->type = NA_IP;
else if (ipx) else if (ipx)
out->type = NA_IPX; addresses->type = NA_IPX;
else else
out->type = NA_INVALID; addresses->type = NA_INVALID;
*adrflags++ = 0;
addresses++;
maxaddresses--;
found++;
} }
} }
} }
@ -2094,33 +2114,38 @@ int FTENET_GetLocalAddress(netadr_t *out, int port, int count, qboolean ipx, qbo
#ifdef HAVE_IPV4 #ifdef HAVE_IPV4
if(h && h->h_addrtype == AF_INET) if(h && h->h_addrtype == AF_INET)
{ {
for (b = 0; h->h_addr_list[b]; b++) for (b = 0; h->h_addr_list[b] && maxaddresses; b++)
{ {
struct sockaddr_in from; struct sockaddr_in from;
from.sin_family = AF_INET; from.sin_family = AF_INET;
memcpy(&from.sin_addr, h->h_addr_list[b], sizeof(&from.sin_addr)); memcpy(&from.sin_addr, h->h_addr_list[b], sizeof(&from.sin_addr));
SockadrToNetadr((struct sockaddr_qstorage*)&from, &adr); SockadrToNetadr((struct sockaddr_qstorage*)&from, addresses);
if (idx++ == count)
*out = adr; *adrflags++ = 0;
addresses++;
maxaddresses--;
found++;
} }
} }
#endif #endif
#ifdef IPPROTO_IPV6 #ifdef IPPROTO_IPV6
if(h && h->h_addrtype == AF_INET6) if(h && h->h_addrtype == AF_INET6)
{ {
for (b = 0; h->h_addr_list[b]; b++) for (b = 0; h->h_addr_list[b] && maxaddresses; b++)
{ {
struct sockaddr_in6 from; struct sockaddr_in6 from;
from.sin6_family = AF_INET6; from.sin6_family = AF_INET6;
memcpy(&from.sin6_addr, h->h_addr_list[b], sizeof(((struct sockaddr_in6*)&from)->sin6_addr)); memcpy(&from.sin6_addr, h->h_addr_list[b], sizeof(((struct sockaddr_in6*)&from)->sin6_addr));
SockadrToNetadr((struct sockaddr_qstorage*)&from, &adr); SockadrToNetadr((struct sockaddr_qstorage*)&from, addresses);
if (idx++ == count) *adrflags++ = 0;
*out = adr; addresses++;
maxaddresses--;
found++;
} }
} }
#endif #endif
} }
return idx; return found;
} }
#elif defined(__linux__) && !defined(ANDROID) #elif defined(__linux__) && !defined(ANDROID)
@ -2185,7 +2210,7 @@ int FTENET_GetLocalAddress(netadr_t *out, int count)
} }
#endif #endif
int FTENET_Generic_GetLocalAddress(ftenet_generic_connection_t *con, netadr_t *out, int count) int FTENET_Generic_GetLocalAddresses(struct ftenet_generic_connection_s *con, unsigned int *adrflags, netadr_t *addresses, int maxaddresses)
{ {
#ifndef HAVE_PACKET #ifndef HAVE_PACKET
return 0; return 0;
@ -2193,7 +2218,7 @@ int FTENET_Generic_GetLocalAddress(ftenet_generic_connection_t *con, netadr_t *o
struct sockaddr_qstorage from; struct sockaddr_qstorage from;
int fromsize = sizeof(from); int fromsize = sizeof(from);
netadr_t adr; netadr_t adr;
int idx = 0; int found = 0;
if (getsockname (con->thesocket, (struct sockaddr*)&from, &fromsize) != -1) if (getsockname (con->thesocket, (struct sockaddr*)&from, &fromsize) != -1)
{ {
@ -2211,7 +2236,7 @@ int FTENET_Generic_GetLocalAddress(ftenet_generic_connection_t *con, netadr_t *o
{ {
//ipv6 socket bound to the ipv4-any address is a bit weird, but oh well. //ipv6 socket bound to the ipv4-any address is a bit weird, but oh well.
//FIXME: should we first validate that we support hybrid sockets? //FIXME: should we first validate that we support hybrid sockets?
idx = FTENET_GetLocalAddress(out, adr.port, count, false, true, false); found = FTENET_GetLocalAddress(adr.port, false, true, false, adrflags, addresses, maxaddresses);
} }
else else
{ {
@ -2239,32 +2264,42 @@ int FTENET_Generic_GetLocalAddress(ftenet_generic_connection_t *con, netadr_t *o
ipv6 = true; ipv6 = true;
} }
idx = FTENET_GetLocalAddress(out, adr.port, count, ipx, ipv4, ipv6); found = FTENET_GetLocalAddress(adr.port, ipx, ipv4, ipv6, adrflags, addresses, maxaddresses);
} }
} }
#endif #endif
//and use the bound address (even if its 0.0.0.0) if we didn't grab a list from the system. //and use the bound address (even if its 0.0.0.0) if we didn't grab a list from the system.
if (!idx) if (!found)
{ {
if (adr.type == NA_IPV6 && if (maxaddresses && adr.type == NA_IPV6 &&
!*(int*)&adr.address.ip6[0] && !*(int*)&adr.address.ip6[0] &&
!*(int*)&adr.address.ip6[4] && !*(int*)&adr.address.ip6[4] &&
!*(int*)&adr.address.ip6[8] && !*(int*)&adr.address.ip6[8] &&
!*(int*)&adr.address.ip6[12]) !*(int*)&adr.address.ip6[12])
{ {
if (idx++ == count) *addresses = adr;
{ addresses->type = NA_IP;
*out = adr;
out->type = NA_IP; *adrflags++ = 0;
} addresses++;
maxaddresses--;
found++;
}
if (maxaddresses)
{
*addresses = adr;
*adrflags++ = 0;
addresses++;
maxaddresses--;
found++;
} }
if (idx++ == count)
*out = adr;
} }
} }
return idx; return found;
#endif #endif
} }
@ -2287,18 +2322,18 @@ qboolean FTENET_Generic_GetPacket(ftenet_generic_connection_t *con)
if (ret == -1) if (ret == -1)
{ {
err = qerrno; err = neterrno();
if (err == EWOULDBLOCK) if (err == NET_EWOULDBLOCK)
return false; return false;
if (err == EMSGSIZE) if (err == NET_EMSGSIZE)
{ {
SockadrToNetadr (&from, &net_from); SockadrToNetadr (&from, &net_from);
Con_TPrintf ("Warning: Oversize packet from %s\n", Con_TPrintf ("Warning: Oversize packet from %s\n",
NET_AdrToString (adr, sizeof(adr), &net_from)); NET_AdrToString (adr, sizeof(adr), &net_from));
return false; return false;
} }
if (err == ECONNABORTED || err == ECONNRESET) if (err == NET_ECONNABORTED || err == NET_ECONNRESET)
{ {
Con_TPrintf ("Connection lost or aborted\n"); //server died/connection lost. Con_TPrintf ("Connection lost or aborted\n"); //server died/connection lost.
#ifndef SERVERONLY #ifndef SERVERONLY
@ -2391,22 +2426,22 @@ qboolean FTENET_Generic_SendPacket(ftenet_generic_connection_t *con, int length,
ret = sendto (con->thesocket, data, length, 0, (struct sockaddr*)&addr, size ); ret = sendto (con->thesocket, data, length, 0, (struct sockaddr*)&addr, size );
if (ret == -1) if (ret == -1)
{ {
int ecode = qerrno; int ecode = neterrno();
// wouldblock is silent // wouldblock is silent
if (ecode == EWOULDBLOCK) if (ecode == NET_EWOULDBLOCK)
return true; return true;
if (ecode == ECONNREFUSED) if (ecode == NET_ECONNREFUSED)
return true; return true;
if (ecode == EACCES) if (ecode == NET_EACCES)
{ {
Con_Printf("Access denied: check firewall\n"); Con_Printf("Access denied: check firewall\n");
return true; return true;
} }
#ifndef SERVERONLY #ifndef SERVERONLY
if (ecode == EADDRNOTAVAIL) if (ecode == NET_EADDRNOTAVAIL)
Con_DPrintf("NET_SendPacket Warning: %i\n", ecode); Con_DPrintf("NET_SendPacket Warning: %i\n", ecode);
else else
#endif #endif
@ -2542,7 +2577,7 @@ ftenet_generic_connection_t *FTENET_Generic_EstablishConnection(int adrfamily, i
} }
if (ioctlsocket (newsocket, FIONBIO, &_true) == -1) if (ioctlsocket (newsocket, FIONBIO, &_true) == -1)
Sys_Error ("UDP_OpenSocket: ioctl FIONBIO: %s", strerror(qerrno)); Sys_Error ("UDP_OpenSocket: ioctl FIONBIO: %s", strerror(neterrno()));
// //
@ -2554,7 +2589,7 @@ ftenet_generic_connection_t *FTENET_Generic_EstablishConnection(int adrfamily, i
newcon = Z_Malloc(sizeof(*newcon)); newcon = Z_Malloc(sizeof(*newcon));
if (newcon) if (newcon)
{ {
newcon->GetLocalAddress = FTENET_Generic_GetLocalAddress; newcon->GetLocalAddresses = FTENET_Generic_GetLocalAddresses;
newcon->GetPacket = FTENET_Generic_GetPacket; newcon->GetPacket = FTENET_Generic_GetPacket;
newcon->SendPacket = FTENET_Generic_SendPacket; newcon->SendPacket = FTENET_Generic_SendPacket;
newcon->Close = FTENET_Generic_Close; newcon->Close = FTENET_Generic_Close;
@ -2720,17 +2755,17 @@ qboolean FTENET_TCPConnect_GetPacket(ftenet_generic_connection_t *gcon)
} }
else if (ret == -1) else if (ret == -1)
{ {
err = qerrno; err = neterrno();
if (err == EWOULDBLOCK) if (err == NET_EWOULDBLOCK)
ret = 0; ret = 0;
else else
{ {
if (err == ECONNABORTED || err == ECONNRESET) if (err == NET_ECONNABORTED || err == NET_ECONNRESET)
{ {
Con_TPrintf ("Connection lost or aborted\n"); //server died/connection lost. Con_TPrintf ("Connection lost or aborted\n"); //server died/connection lost.
} }
else if (err == ENOTCONN) else if (err == NET_ENOTCONN)
Con_Printf ("TCPConnect_GetPacket: connection failed\n"); Con_Printf ("TCPConnect_GetPacket: connection failed\n");
else else
Con_Printf ("TCPConnect_GetPacket: Error (%i): %s\n", err, strerror(err)); Con_Printf ("TCPConnect_GetPacket: Error (%i): %s\n", err, strerror(err));
@ -3527,7 +3562,7 @@ ftenet_generic_connection_t *FTENET_TCPConnect_EstablishConnection(int affamily,
} }
if (ioctlsocket (newsocket, FIONBIO, &_true) == -1) if (ioctlsocket (newsocket, FIONBIO, &_true) == -1)
Sys_Error ("UDP_OpenSocket: ioctl FIONBIO: %s", strerror(qerrno)); Sys_Error ("UDP_OpenSocket: ioctl FIONBIO: %s", strerror(neterrno()));
#endif #endif
} }
else else
@ -3549,7 +3584,7 @@ ftenet_generic_connection_t *FTENET_TCPConnect_EstablishConnection(int affamily,
if (newcon) if (newcon)
{ {
if (isserver) if (isserver)
newcon->generic.GetLocalAddress = FTENET_Generic_GetLocalAddress; newcon->generic.GetLocalAddresses = FTENET_Generic_GetLocalAddresses;
newcon->generic.GetPacket = FTENET_TCPConnect_GetPacket; newcon->generic.GetPacket = FTENET_TCPConnect_GetPacket;
newcon->generic.SendPacket = FTENET_TCPConnect_SendPacket; newcon->generic.SendPacket = FTENET_TCPConnect_SendPacket;
newcon->generic.Close = FTENET_TCPConnect_Close; newcon->generic.Close = FTENET_TCPConnect_Close;
@ -3701,11 +3736,11 @@ qboolean FTENET_IRCConnect_GetPacket(ftenet_generic_connection_t *gcon)
read = recv(con->generic.thesocket, con->incoming+con->income, sizeof(con->incoming)-1 - con->income, 0); read = recv(con->generic.thesocket, con->incoming+con->income, sizeof(con->incoming)-1 - con->income, 0);
if (read < 0) if (read < 0)
{ {
read = qerrno; read = neterrno();
switch(read) switch(read)
{ {
case ECONNABORTED: case NET_ECONNABORTED:
case ECONNRESET: case NET_ECONNRESET:
closesocket(con->generic.thesocket); closesocket(con->generic.thesocket);
con->generic.thesocket = INVALID_SOCKET; con->generic.thesocket = INVALID_SOCKET;
break; break;
@ -4622,16 +4657,17 @@ int NET_GetPacket (netsrc_t netsrc, int firstsock)
int NET_LocalAddressForRemote(ftenet_connections_t *collection, netadr_t *remote, netadr_t *local, int idx) int NET_LocalAddressForRemote(ftenet_connections_t *collection, netadr_t *remote, netadr_t *local, int idx)
{ {
int adrflags;
if (!remote->connum) if (!remote->connum)
return 0; return 0;
if (!collection->conn[remote->connum-1]) if (!collection->conn[remote->connum-1])
return 0; return 0;
if (!collection->conn[remote->connum-1]->GetLocalAddress) if (!collection->conn[remote->connum-1]->GetLocalAddresses)
return 0; return 0;
return collection->conn[remote->connum-1]->GetLocalAddress(collection->conn[remote->connum-1], local, idx); return collection->conn[remote->connum-1]->GetLocalAddresses(collection->conn[remote->connum-1], &adrflags, local, 1);
} }
qboolean NET_SendPacket (netsrc_t netsrc, int length, void *data, netadr_t *to) qboolean NET_SendPacket (netsrc_t netsrc, int length, void *data, netadr_t *to)
@ -4710,30 +4746,60 @@ qboolean NET_EnsureRoute(ftenet_connections_t *collection, char *routename, char
return true; return true;
} }
void NET_PrintAddresses(ftenet_connections_t *collection) int NET_EnumerateAddresses(ftenet_connections_t *collection, struct ftenet_generic_connection_s **con, int *adrflags, netadr_t *addresses, int maxaddresses)
{ {
int i; unsigned int found = 0, c, i, j;
int adrno, adrcount=1;
netadr_t adr;
char adrbuf[MAX_ADR_SIZE];
if (!collection)
return;
for (i = 0; i < MAX_CONNECTIONS; i++) for (i = 0; i < MAX_CONNECTIONS; i++)
{ {
if (!collection->conn[i]) if (!collection->conn[i])
continue; continue;
adrno = 0;
if (collection->conn[i]->GetLocalAddress) c = collection->conn[i]->GetLocalAddresses(collection->conn[i], adrflags, addresses, maxaddresses);
if (maxaddresses && !c)
{ {
for (adrcount=1; (adrcount = collection->conn[i]->GetLocalAddress(collection->conn[i], &adr, adrno)) && adrno < adrcount; adrno++) *adrflags = 0;
{ addresses->type = NA_INVALID;
Con_Printf("net address (%s): %s\n", collection->conn[i]->name, NET_AdrToString(adrbuf, sizeof(adrbuf), &adr)); c = 1;
}
} }
if (!adrno)
Con_Printf("net address (%s): no addresses\n", collection->conn[i]->name); //fill in connection info
for (j = 0; j < c; j++)
{
con[j] = collection->conn[i];
addresses[j].connum = i+1;
}
con += c;
adrflags += c;
addresses += c;
maxaddresses -= c;
found += c;
}
return found;
}
#define MAXADDRESSES 64
void NET_PrintAddresses(ftenet_connections_t *collection)
{
int i;
char adrbuf[MAX_ADR_SIZE];
int m;
netadr_t addr[64];
struct ftenet_generic_connection_s *con[sizeof(addr)/sizeof(addr[0])];
int flags[sizeof(addr)/sizeof(addr[0])];
if (!collection)
return;
m = NET_EnumerateAddresses(collection, con, flags, addr, sizeof(addr)/sizeof(addr[0]));
for (i = 0; i < m; i++)
{
if (addr[i].type == NA_INVALID)
Con_Printf("net address (%s): no addresses\n", con[i]->name);
else
Con_Printf("net address (%s): %s\n", con[i]->name, NET_AdrToString(adrbuf, sizeof(adrbuf), &addr[i]));
} }
} }
@ -4759,7 +4825,7 @@ int TCP_OpenStream (netadr_t *remoteaddr)
setsockopt(newsocket, SOL_SOCKET, SO_RCVBUF, (void*)&recvbufsize, sizeof(recvbufsize)); setsockopt(newsocket, SOL_SOCKET, SO_RCVBUF, (void*)&recvbufsize, sizeof(recvbufsize));
if (ioctlsocket (newsocket, FIONBIO, &_true) == -1) if (ioctlsocket (newsocket, FIONBIO, &_true) == -1)
Sys_Error ("UDP_OpenSocket: ioctl FIONBIO: %s", strerror(qerrno)); Sys_Error ("UDP_OpenSocket: ioctl FIONBIO: %s", strerror(neterrno()));
// memset(&loc, 0, sizeof(loc)); // memset(&loc, 0, sizeof(loc));
// ((struct sockaddr*)&loc)->sa_family = ((struct sockaddr*)&loc)->sa_family; // ((struct sockaddr*)&loc)->sa_family = ((struct sockaddr*)&loc)->sa_family;
@ -4767,19 +4833,19 @@ int TCP_OpenStream (netadr_t *remoteaddr)
if (connect(newsocket, (struct sockaddr *)&qs, temp) == INVALID_SOCKET) if (connect(newsocket, (struct sockaddr *)&qs, temp) == INVALID_SOCKET)
{ {
int err = qerrno; int err = neterrno();
if (err != EWOULDBLOCK && err != EINPROGRESS) if (err != NET_EWOULDBLOCK && err != NET_EINPROGRESS)
{ {
char buf[256]; char buf[256];
NET_AdrToString(buf, sizeof(buf), remoteaddr); NET_AdrToString(buf, sizeof(buf), remoteaddr);
if (err == EADDRNOTAVAIL) if (err == NET_EADDRNOTAVAIL)
{ {
if (remoteaddr->port == 0 && (remoteaddr->type == NA_IP || remoteaddr->type == NA_IPV6)) if (remoteaddr->port == 0 && (remoteaddr->type == NA_IP || remoteaddr->type == NA_IPV6))
Con_Printf ("TCP_OpenStream: no port specified (%s)\n", buf); Con_Printf ("TCP_OpenStream: no port specified (%s)\n", buf);
else else
Con_Printf ("TCP_OpenStream: invalid address trying to connect to %s\n", buf); Con_Printf ("TCP_OpenStream: invalid address trying to connect to %s\n", buf);
} }
else if (err == EACCES) else if (err == NET_EACCES)
Con_Printf ("TCP_OpenStream: access denied: check firewall (%s)\n", buf); Con_Printf ("TCP_OpenStream: access denied: check firewall (%s)\n", buf);
else else
Con_Printf ("TCP_OpenStream: connect: error %i (%s)\n", err, buf); Con_Printf ("TCP_OpenStream: connect: error %i (%s)\n", err, buf);
@ -4884,7 +4950,7 @@ int maxport = port + 100;
return (int)INVALID_SOCKET; return (int)INVALID_SOCKET;
if (ioctlsocket (newsocket, FIONBIO, &_true) == -1) if (ioctlsocket (newsocket, FIONBIO, &_true) == -1)
Sys_Error ("UDP_OpenSocket: ioctl FIONBIO: %s", strerror(qerrno)); Sys_Error ("UDP_OpenSocket: ioctl FIONBIO: %s", strerror(neterrno()));
if (bcast) if (bcast)
{ {
@ -4915,10 +4981,10 @@ int maxport = port + 100;
if( bind (newsocket, (void *)&address, sizeof(address)) == -1) if( bind (newsocket, (void *)&address, sizeof(address)) == -1)
{ {
if (!port) if (!port)
Sys_Error ("UDP_OpenSocket: bind: %s", strerror(qerrno)); Sys_Error ("UDP_OpenSocket: bind: %s", strerror(neterrno()));
port++; port++;
if (port > maxport) if (port > maxport)
Sys_Error ("UDP_OpenSocket: bind: %s", strerror(qerrno)); Sys_Error ("UDP_OpenSocket: bind: %s", strerror(neterrno()));
} }
else else
break; break;
@ -4941,12 +5007,12 @@ int maxport = port + 100;
if ((newsocket = socket (PF_INET6, SOCK_DGRAM, 0)) == INVALID_SOCKET) if ((newsocket = socket (PF_INET6, SOCK_DGRAM, 0)) == INVALID_SOCKET)
{ {
Con_Printf("IPV6 is not supported: %s\n", strerror(qerrno)); Con_Printf("IPV6 is not supported: %s\n", strerror(neterrno()));
return (int)INVALID_SOCKET; return (int)INVALID_SOCKET;
} }
if (ioctlsocket (newsocket, FIONBIO, &_true) == -1) if (ioctlsocket (newsocket, FIONBIO, &_true) == -1)
Sys_Error ("UDP_OpenSocket: ioctl FIONBIO: %s", strerror(qerrno)); Sys_Error ("UDP_OpenSocket: ioctl FIONBIO: %s", strerror(neterrno()));
if (bcast) if (bcast)
{ {
@ -4984,7 +5050,7 @@ int maxport = port + 100;
{ {
if (!port) if (!port)
{ {
err = qerrno; err = neterrno();
Con_Printf ("UDP6_OpenSocket: bind: (%i) %s", err, strerror(err)); Con_Printf ("UDP6_OpenSocket: bind: (%i) %s", err, strerror(err));
closesocket(newsocket); closesocket(newsocket);
return (int)INVALID_SOCKET; return (int)INVALID_SOCKET;
@ -4992,7 +5058,7 @@ int maxport = port + 100;
port++; port++;
if (port > maxport) if (port > maxport)
{ {
err = qerrno; err = neterrno();
Con_Printf ("UDP6_OpenSocket: bind: (%i) %s", err, strerror(err)); Con_Printf ("UDP6_OpenSocket: bind: (%i) %s", err, strerror(err));
closesocket(newsocket); closesocket(newsocket);
return (int)INVALID_SOCKET; return (int)INVALID_SOCKET;
@ -5022,15 +5088,16 @@ int IPX_OpenSocket (int port, qboolean bcast)
if ((newsocket = socket (PF_IPX, SOCK_DGRAM, NSPROTO_IPX)) == INVALID_SOCKET) if ((newsocket = socket (PF_IPX, SOCK_DGRAM, NSPROTO_IPX)) == INVALID_SOCKET)
{ {
if (qerrno != EAFNOSUPPORT) int e = neterrno();
Con_Printf ("WARNING: IPX_Socket: socket: %i\n", qerrno); if (e != NET_EAFNOSUPPORT)
Con_Printf ("WARNING: IPX_Socket: socket: %i\n", e);
return INVALID_SOCKET; return INVALID_SOCKET;
} }
// make it non-blocking // make it non-blocking
if (ioctlsocket (newsocket, FIONBIO, &_true) == -1) if (ioctlsocket (newsocket, FIONBIO, &_true) == -1)
{ {
Con_Printf ("WARNING: IPX_Socket: ioctl FIONBIO: %i\n", qerrno); Con_Printf ("WARNING: IPX_Socket: ioctl FIONBIO: %i\n", neterrno());
return INVALID_SOCKET; return INVALID_SOCKET;
} }
@ -5039,7 +5106,7 @@ int IPX_OpenSocket (int port, qboolean bcast)
// make it broadcast capable // make it broadcast capable
if (setsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&_true, sizeof(_true)) == -1) if (setsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&_true, sizeof(_true)) == -1)
{ {
Con_Printf ("WARNING: IPX_Socket: setsockopt SO_BROADCAST: %i\n", qerrno); Con_Printf ("WARNING: IPX_Socket: setsockopt SO_BROADCAST: %i\n", neterrno());
return INVALID_SOCKET; return INVALID_SOCKET;
} }
} }
@ -5054,7 +5121,7 @@ int IPX_OpenSocket (int port, qboolean bcast)
if( bind (newsocket, (void *)&address, sizeof(address)) == -1) if( bind (newsocket, (void *)&address, sizeof(address)) == -1)
{ {
Con_Printf ("WARNING: IPX_Socket: bind: %i\n", qerrno); Con_Printf ("WARNING: IPX_Socket: bind: %i\n", neterrno());
closesocket (newsocket); closesocket (newsocket);
return INVALID_SOCKET; return INVALID_SOCKET;
} }
@ -5258,6 +5325,12 @@ qboolean NET_WasSpecialPacket(netsrc_t netsrc)
#endif #endif
return false; return false;
} }
void NET_UPNPIGP_Callback(cvar_t *var, char *oldval)
{
}
cvar_t net_upnpigp = CVARCD("net_upnpigp", "0", NET_UPNPIGP_Callback, "If set, enables the use of the upnp-igd protocol to punch holes in your local NAT box.");
/* /*
==================== ====================
NET_Init NET_Init
@ -5300,6 +5373,9 @@ void NET_Init (void)
#ifndef SERVERONLY #ifndef SERVERONLY
Cmd_AddCommand("cl_addport", NET_ClientPort_f); Cmd_AddCommand("cl_addport", NET_ClientPort_f);
#endif #endif
Cvar_Register (&net_upnpigp, "networking");
net_upnpigp.restriction = RESTRICT_MAX;
} }
#ifndef SERVERONLY #ifndef SERVERONLY
void NET_InitClient(void) void NET_InitClient(void)
@ -5584,21 +5660,21 @@ int QDECL VFSTCP_ReadBytes (struct vfsfile_s *file, void *buffer, int bytestorea
len = recv(tf->sock, tf->readbuffer + tf->readbuffered, trying, 0); len = recv(tf->sock, tf->readbuffer + tf->readbuffered, trying, 0);
if (len == -1) if (len == -1)
{ {
int e = qerrno; int e = neterrno();
if (e != EWOULDBLOCK) if (e != NET_EWOULDBLOCK)
{ {
switch(e) switch(e)
{ {
case ENOTCONN: case NET_ENOTCONN:
Con_Printf("connection to \"%s\" failed\n", tf->peer); Con_Printf("connection to \"%s\" failed\n", tf->peer);
break; break;
case ECONNABORTED: case NET_ECONNABORTED:
Con_DPrintf("connection to \"%s\" aborted\n", tf->peer); Con_DPrintf("connection to \"%s\" aborted\n", tf->peer);
break; break;
case ECONNREFUSED: case NET_ECONNREFUSED:
Con_DPrintf("connection to \"%s\" refused\n", tf->peer); Con_DPrintf("connection to \"%s\" refused\n", tf->peer);
break; break;
case ECONNRESET: case NET_ECONNRESET:
Con_DPrintf("connection to \"%s\" reset\n", tf->peer); Con_DPrintf("connection to \"%s\" reset\n", tf->peer);
break; break;
default: default:
@ -5665,12 +5741,12 @@ int QDECL VFSTCP_WriteBytes (struct vfsfile_s *file, const void *buffer, int byt
len = send(tf->sock, buffer, bytestoread, 0); len = send(tf->sock, buffer, bytestoread, 0);
if (len == -1 || len == 0) if (len == -1 || len == 0)
{ {
int e = qerrno; int e = neterrno();
switch(e) switch(e)
{ {
case EWOULDBLOCK: case NET_EWOULDBLOCK:
return 0; //nothing available yet. return 0; //nothing available yet.
case ENOTCONN: case NET_ENOTCONN:
Con_Printf("connection to \"%s\" failed\n", tf->peer); Con_Printf("connection to \"%s\" failed\n", tf->peer);
break; break;
default: default:
@ -5684,17 +5760,17 @@ int QDECL VFSTCP_WriteBytes (struct vfsfile_s *file, const void *buffer, int byt
} }
return len; return len;
} }
qboolean QDECL VFSTCP_Seek (struct vfsfile_s *file, unsigned long pos) qboolean QDECL VFSTCP_Seek (struct vfsfile_s *file, qofs_t pos)
{ {
VFSTCP_Error((tcpfile_t*)file); VFSTCP_Error((tcpfile_t*)file);
return false; return false;
} }
unsigned long QDECL VFSTCP_Tell (struct vfsfile_s *file) qofs_t QDECL VFSTCP_Tell (struct vfsfile_s *file)
{ {
VFSTCP_Error((tcpfile_t*)file); VFSTCP_Error((tcpfile_t*)file);
return 0; return 0;
} }
unsigned long QDECL VFSTCP_GetLen (struct vfsfile_s *file) qofs_t QDECL VFSTCP_GetLen (struct vfsfile_s *file)
{ {
return 0; return 0;
} }

View file

@ -127,18 +127,6 @@
#ifdef ENOTCONN #ifdef ENOTCONN
#undef ENOTCONN #undef ENOTCONN
#endif #endif
#define EWOULDBLOCK WSAEWOULDBLOCK
#define EINPROGRESS WSAEINPROGRESS
#define EMSGSIZE WSAEMSGSIZE
#define ECONNRESET WSAECONNRESET
#define ECONNABORTED WSAECONNABORTED
#define ECONNREFUSED WSAECONNREFUSED
#define ENOTCONN WSAENOTCONN
#define EACCES WSAEACCES
#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
#define EAFNOSUPPORT WSAEAFNOSUPPORT
#else #else
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
@ -177,11 +165,37 @@
#endif #endif
#if defined(_WIN32) #if defined(_WIN32)
#define qerrno WSAGetLastError() #define neterrno() WSAGetLastError()
//this madness is because winsock defines its own errors instead of using system error codes.
//*AND* microsoft then went and defined names for all the unix ones too... with different values! oh the insanity of it all!
#define NET_EWOULDBLOCK WSAEWOULDBLOCK
#define NET_EINPROGRESS WSAEINPROGRESS
#define NET_EMSGSIZE WSAEMSGSIZE
#define NET_ECONNRESET WSAECONNRESET
#define NET_ECONNABORTED WSAECONNABORTED
#define NET_ECONNREFUSED WSAECONNREFUSED
#define NET_ENOTCONN WSAENOTCONN
#define NET_EACCES WSAEACCES
#define NET_EADDRNOTAVAIL WSAEADDRNOTAVAIL
#define NET_EAFNOSUPPORT WSAEAFNOSUPPORT
#elif defined(__MORPHOS__) && !defined(ixemul) #elif defined(__MORPHOS__) && !defined(ixemul)
#define qerrno Errno() #define neterrno() Errno()
#else #else
#define qerrno errno #define neterrno() errno
#endif
#ifndef NET_EWOULDBLOCK
//assume unix codes instead, so our prefix still works.
#define NET_EWOULDBLOCK EWOULDBLOCK
#define NET_EINPROGRESS EINPROGRESS
#define NET_EMSGSIZE EMSGSIZE
#define NET_ECONNRESET ECONNRESET
#define NET_ECONNABORTED ECONNABORTED
#define NET_ECONNREFUSED ECONNREFUSED
#define NET_ENOTCONN ENOTCONN
#define NET_EACCES EACCES
#define NET_EADDRNOTAVAIL EADDRNOTAVAIL
#define NET_EAFNOSUPPORT EAFNOSUPPORT
#endif #endif
#ifndef INVALID_SOCKET #ifndef INVALID_SOCKET
@ -254,12 +268,14 @@ extern icefuncs_t iceapi;
#endif #endif
#define ADDR_NATPMP (1u<<0)
#define ADDR_UPNPIGP (1u<<1)
#define FTENET_ADDRTYPES 2 #define FTENET_ADDRTYPES 2
typedef struct ftenet_generic_connection_s { typedef struct ftenet_generic_connection_s {
char name[MAX_QPATH]; char name[MAX_QPATH];
int (*GetLocalAddress)(struct ftenet_generic_connection_s *con, netadr_t *local, int adridx); int (*GetLocalAddresses)(struct ftenet_generic_connection_s *con, unsigned int *adrflags, netadr_t *addresses, int maxaddresses);
qboolean (*ChangeLocalAddress)(struct ftenet_generic_connection_s *con, const char *newaddress); qboolean (*ChangeLocalAddress)(struct ftenet_generic_connection_s *con, const char *newaddress);
qboolean (*GetPacket)(struct ftenet_generic_connection_s *con); qboolean (*GetPacket)(struct ftenet_generic_connection_s *con);
qboolean (*SendPacket)(struct ftenet_generic_connection_s *con, int length, void *data, netadr_t *to); qboolean (*SendPacket)(struct ftenet_generic_connection_s *con, int length, void *data, netadr_t *to);
@ -292,3 +308,5 @@ void QDECL ICE_AddLCandidateInfo(struct icestate_s *con, netadr_t *adr, int adrn
ftenet_connections_t *FTENET_CreateCollection(qboolean listen); ftenet_connections_t *FTENET_CreateCollection(qboolean listen);
void FTENET_CloseCollection(ftenet_connections_t *col); void FTENET_CloseCollection(ftenet_connections_t *col);
qboolean FTENET_AddToCollection(struct ftenet_connections_s *col, const char *name, const char *address, netadrtype_t addrtype, qboolean islisten); qboolean FTENET_AddToCollection(struct ftenet_connections_s *col, const char *name, const char *address, netadrtype_t addrtype, qboolean islisten);
int NET_EnumerateAddresses(ftenet_connections_t *collection, struct ftenet_generic_connection_s **con, int *adrflags, netadr_t *addresses, int maxaddresses);

View file

@ -278,7 +278,7 @@ plugin_t *Plug_Load(char *file, int type)
return newplug; return newplug;
} }
static int QDECL Plug_Emumerated (const char *name, int size, void *param, searchpathfuncs_t *spath) static int QDECL Plug_Emumerated (const char *name, qofs_t size, void *param, searchpathfuncs_t *spath)
{ {
char vmname[MAX_QPATH]; char vmname[MAX_QPATH];
Q_strncpyz(vmname, name, sizeof(vmname)); Q_strncpyz(vmname, name, sizeof(vmname));
@ -288,7 +288,7 @@ static int QDECL Plug_Emumerated (const char *name, int size, void *param, searc
return true; return true;
} }
static int QDECL Plug_EnumeratedRoot (const char *name, int size, void *param, searchpathfuncs_t *spath) static int QDECL Plug_EnumeratedRoot (const char *name, qofs_t size, void *param, searchpathfuncs_t *spath)
{ {
char vmname[MAX_QPATH]; char vmname[MAX_QPATH];
int len; int len;
@ -1086,7 +1086,7 @@ qintptr_t VARGS Plug_Net_Recv(void *offset, quintptr_t mask, const qintptr_t *ar
read = recv(pluginstreamarray[handle].socket, dest, destlen, 0); read = recv(pluginstreamarray[handle].socket, dest, destlen, 0);
if (read < 0) if (read < 0)
{ {
if (qerrno == EWOULDBLOCK) if (neterrno() == NET_EWOULDBLOCK)
return -1; return -1;
else else
return -2; return -2;
@ -1117,7 +1117,7 @@ qintptr_t VARGS Plug_Net_Send(void *offset, quintptr_t mask, const qintptr_t *ar
written = send(pluginstreamarray[handle].socket, src, srclen, 0); written = send(pluginstreamarray[handle].socket, src, srclen, 0);
if (written < 0) if (written < 0)
{ {
if (qerrno == EWOULDBLOCK) if (neterrno() == NET_EWOULDBLOCK)
return -1; return -1;
else else
return -2; return -2;
@ -1162,7 +1162,7 @@ qintptr_t VARGS Plug_Net_SendTo(void *offset, quintptr_t mask, const qintptr_t *
written = sendto(pluginstreamarray[handle].socket, src, srclen, 0, (struct sockaddr*)&sockaddr, sizeof(sockaddr)); written = sendto(pluginstreamarray[handle].socket, src, srclen, 0, (struct sockaddr*)&sockaddr, sizeof(sockaddr));
if (written < 0) if (written < 0)
{ {
if (qerrno == EWOULDBLOCK) if (neterrno() == NET_EWOULDBLOCK)
return -1; return -1;
else else
return -2; return -2;

View file

@ -1718,7 +1718,7 @@ void search_close_progs(pubprogfuncs_t *prinst, qboolean complain)
prvm_nextsearchhandle = 0; //might as well. prvm_nextsearchhandle = 0; //might as well.
} }
int QDECL search_enumerate(const char *name, int fsize, void *parm, searchpathfuncs_t *spath) int QDECL search_enumerate(const char *name, qofs_t fsize, void *parm, searchpathfuncs_t *spath)
{ {
prvmsearch_t *s = parm; prvmsearch_t *s = parm;
@ -2314,7 +2314,12 @@ void QCBUILTIN PF_str2chr (pubprogfuncs_t *prinst, struct globalvars_s *pr_globa
if (ofs && (ofs < 0 || ofs > strlen(instr))) if (ofs && (ofs < 0 || ofs > strlen(instr)))
G_FLOAT(OFS_RETURN) = '\0'; G_FLOAT(OFS_RETURN) = '\0';
else else
G_FLOAT(OFS_RETURN) = VMUTF8?unicode_decode(&err, instr+ofs, &next, VMUTF8MARKUP):(unsigned char)instr[ofs]; {
if (VMUTF8)
G_FLOAT(OFS_RETURN) = unicode_decode(&err, instr+ofs, &next, VMUTF8MARKUP);
else
G_FLOAT(OFS_RETURN) = (unsigned char)instr[ofs];
}
} }
//FTE_STRINGS //FTE_STRINGS
@ -3581,6 +3586,13 @@ void QCBUILTIN PF_ArgV (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals
RETURN_TSTRING(qctoken[idx].token); RETURN_TSTRING(qctoken[idx].token);
} }
void QCBUILTIN PF_argescape(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
char temp[8192];
char *str = PR_GetStringOfs(prinst, OFS_PARM0);
RETURN_TSTRING(COM_QuotedString(str, temp, sizeof(temp)));
}
//Console functions //Console functions
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
//Maths functions //Maths functions

View file

@ -184,6 +184,7 @@ void QCBUILTIN PF_entityfieldtype (pubprogfuncs_t *prinst, struct globalvars_s *
void QCBUILTIN PF_getentityfieldstring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_getentityfieldstring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_putentityfieldstring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_putentityfieldstring (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_checkcommand (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_checkcommand (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_argescape(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_getsurfacenumpoints(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_getsurfacenumpoints(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
@ -252,6 +253,9 @@ void QCBUILTIN PF_setattachment(pubprogfuncs_t *prinst, struct globalvars_s *pr_
void skel_dodelete(pubprogfuncs_t *prinst); void skel_dodelete(pubprogfuncs_t *prinst);
void skel_reset(pubprogfuncs_t *prinst); void skel_reset(pubprogfuncs_t *prinst);
#endif #endif
void QCBUILTIN PF_physics_enable(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_physics_addforce(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_physics_addtorque(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
void QCBUILTIN PF_touchtriggers(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals); void QCBUILTIN PF_touchtriggers(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals);
@ -484,10 +488,25 @@ pbool QDECL ED_CanFree (edict_t *ed);
#define SOLID_CORPSE 5 // non-solid to solid_slidebox entities and itself. #define SOLID_CORPSE 5 // non-solid to solid_slidebox entities and itself.
#define SOLID_LADDER 20 //dmw. touch on edge, not blocking. Touching players have different physics. Otherwise a SOLID_TRIGGER #define SOLID_LADDER 20 //dmw. touch on edge, not blocking. Touching players have different physics. Otherwise a SOLID_TRIGGER
#define SOLID_PORTAL 21 //1: traces always use point-size. 2: various movetypes automatically transform entities. 3: traces that impact portal bbox use a union. 4. traces ignore part of the world within the portal's box #define SOLID_PORTAL 21 //1: traces always use point-size. 2: various movetypes automatically transform entities. 3: traces that impact portal bbox use a union. 4. traces ignore part of the world within the portal's box
#define SOLID_PHYSICS_BOX 32 ///< physics object (mins, maxs, mass, origin, axis_forward, axis_left, axis_up, velocity, spinvelocity) #define SOLID_PHYSICS_BOX 32 // deprecated. 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_SPHERE 33 // deprecated. 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 SOLID_PHYSICS_CAPSULE 34 // deprecated. physics object (mins, maxs, mass, origin, axis_forward, axis_left, axis_up, velocity, spinvelocity)
#define SOLID_PHYSICS_CYLINDER 35 #define SOLID_PHYSICS_TRIMESH 35
#define SOLID_PHYSICS_CYLINDER 36
#define GEOMTYPE_NONE -1
#define GEOMTYPE_SOLID 0
#define GEOMTYPE_BOX 1
#define GEOMTYPE_SPHERE 2
#define GEOMTYPE_CAPSULE 3
#define GEOMTYPE_TRIMESH 4
#define GEOMTYPE_CYLINDER 5
#define GEOMTYPE_CAPSULE_X 6
#define GEOMTYPE_CAPSULE_Y 7
#define GEOMTYPE_CAPSULE_Z 8
#define GEOMTYPE_CYLINDER_X 9
#define GEOMTYPE_CYLINDER_Y 10
#define GEOMTYPE_CYLINDER_Z 11
#define JOINTTYPE_POINT 1 #define JOINTTYPE_POINT 1
@ -549,6 +568,11 @@ typedef enum
VF_VIEWENTITY = 206, VF_VIEWENTITY = 206,
VF_STATSENTITIY = 207, //the player number for the stats. VF_STATSENTITIY = 207, //the player number for the stats.
VF_SCREENVOFFSET = 208, VF_SCREENVOFFSET = 208,
VF_RT_DESTCOLOUR = 209,
VF_RT_SOURCECOLOUR = 210,
VF_RT_DEPTH = 211,
VF_RT_RIPPLE = 212, /**/
} viewflags; } viewflags;
/*FIXME: this should be changed*/ /*FIXME: this should be changed*/

View file

@ -186,7 +186,7 @@ typedef struct {
int bufferleft; int bufferleft;
int skip; int skip;
} vmsearch_t; } vmsearch_t;
static int QDECL VMEnum(const char *match, int size, void *args, searchpathfuncs_t *spath) static int QDECL VMEnum(const char *match, qofs_t size, void *args, searchpathfuncs_t *spath)
{ {
char *check; char *check;
int newlen; int newlen;
@ -210,13 +210,13 @@ static int QDECL VMEnum(const char *match, int size, void *args, searchpathfuncs
return true; return true;
} }
static int QDECL IfFound(const char *match, int size, void *args, searchpathfuncs_t *spath) static int QDECL IfFound(const char *match, qofs_t size, void *args, searchpathfuncs_t *spath)
{ {
*(qboolean*)args = true; *(qboolean*)args = true;
return true; return true;
} }
static int QDECL VMEnumMods(const char *match, int size, void *args, searchpathfuncs_t *spath) static int QDECL VMEnumMods(const char *match, qofs_t size, void *args, searchpathfuncs_t *spath)
{ {
char *check; char *check;
char desc[1024]; char desc[1024];
@ -235,7 +235,7 @@ static int QDECL VMEnumMods(const char *match, int size, void *args, searchpathf
return true; return true;
if (!stricmp(match, "baseq3/")) if (!stricmp(match, "baseq3/"))
return true; //we don't want baseq3 return true; //we don't want baseq3. FIXME: should be any basedir, rather than hardcoded.
foundone = false; foundone = false;
Sys_EnumerateFiles(va("%s%s/", ((vmsearch_t *)args)->dir, match), "*.pk3", IfFound, &foundone, spath); Sys_EnumerateFiles(va("%s%s/", ((vmsearch_t *)args)->dir, match), "*.pk3", IfFound, &foundone, spath);

View file

@ -87,7 +87,7 @@ void Sys_ServerActivity(void);
void Sys_SendKeyEvents (void); void Sys_SendKeyEvents (void);
// Perform Key_Event () callbacks until the input que is empty // Perform Key_Event () callbacks until the input que is empty
int Sys_EnumerateFiles (const char *gpath, const char *match, int (QDECL *func)(const char *fname, int fsize, void *parm, searchpathfuncs_t *spath), void *parm, searchpathfuncs_t *spath); int Sys_EnumerateFiles (const char *gpath, const char *match, int (QDECL *func)(const char *fname, qofs_t fsize, void *parm, searchpathfuncs_t *spath), void *parm, searchpathfuncs_t *spath);
void Sys_Vibrate(float count); void Sys_Vibrate(float count);

View file

@ -10,6 +10,7 @@
char sys_language[64] = ""; char sys_language[64] = "";
struct language_s languages[MAX_LANGUAGES];
void TL_LanguageChanged(struct cvar_s *var, char *oldvalue) void TL_LanguageChanged(struct cvar_s *var, char *oldvalue)
{ {

View file

@ -12,7 +12,8 @@ struct language_s
{ {
char *name; char *name;
struct po_s *po; struct po_s *po;
} languages[MAX_LANGUAGES]; };
extern struct language_s languages[MAX_LANGUAGES];
#define langtext(t,l) PO_GetText(languages[l].po, t) #define langtext(t,l) PO_GetText(languages[l].po, t)
int TL_FindLanguage(const char *lang); int TL_FindLanguage(const char *lang);

File diff suppressed because it is too large Load diff

View file

@ -1,282 +0,0 @@
/* unzip.h -- IO for uncompress .zip files using zlib
Version 0.15 beta, Mar 19th, 1998,
Copyright (C) 1998 Gilles Vollant
This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
WinZip, InfoZip tools and compatible.
Encryption and multi volume ZipFile (span) are not supported.
Old compressions used by old PKZip 1.x are not supported
THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE
CAN CHANGE IN FUTURE VERSION !!
I WAIT FEEDBACK at mail info@winimage.com
Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
Condition of use and distribution are the same than zlib :
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
//(2) This source has been modified to compile for AMD64 archetectures with gcc
/* for more info about .ZIP format, see
ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip
PkWare has also a specification at :
ftp://ftp.pkware.com/probdesc.zip */
#ifndef _unz_H
#define _unz_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _ZLIB_H
#include "zlib.h"
#endif
#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
/* like the STRICT of WIN32, we define a pointer that cannot be converted
from (void*) without cast */
typedef struct TagunzFile__ { int unused; } unzFile__;
typedef unzFile__ *unzFile;
#else
typedef voidp unzFile;
#endif
#define UNZ_OK (0)
#define UNZ_END_OF_LIST_OF_FILE (-100)
#define UNZ_ERRNO (Z_ERRNO)
#define UNZ_EOF (0)
#define UNZ_PARAMERROR (-102)
#define UNZ_BADZIPFILE (-103)
#define UNZ_INTERNALERROR (-104)
#define UNZ_CRCERROR (-105)
/* tm_unz contain date/time info */
//typedef struct tm_unz_s
//{
// uInt tm_sec; /* seconds after the minute - [0,59] */
// uInt tm_min; /* minutes after the hour - [0,59] */
// uInt tm_hour; /* hours since midnight - [0,23] */
// uInt tm_mday; /* day of the month - [1,31] */
// uInt tm_mon; /* months since January - [0,11] */
// uInt tm_year; /* years - [1980..2044] */
//} tm_unz;
/* unz_global_info structure contain global data about the ZIPfile
These data comes from the end of central dir */
typedef struct unz_global_info_s
{
unsigned long number_entry; /* total number of entries in
the central dir on this disk */
unsigned long size_comment; /* size of the global comment of the zipfile */
} unz_global_info;
/* unz_file_info contain information about a file in the zipfile */
#pragma pack(push, 1)
typedef struct unz_file_info_s
{
unsigned short version; /* version made by 2 bytes */
unsigned short version_needed; /* version needed to extract 2 bytes */
unsigned short flag; /* general purpose bit flag 2 bytes */
unsigned short compression_method; /* compression method 2 bytes */
unsigned long dosDate; /* last mod file date in Dos fmt 4 bytes */
unsigned long crc; /* crc-32 4 bytes */
unsigned long compressed_size; /* compressed size 4 bytes */
unsigned long uncompressed_size; /* uncompressed size 4 bytes */
unsigned short size_filename; /* filename length 2 bytes */
unsigned short size_file_extra; /* extra field length 2 bytes */
unsigned short size_file_comment; /* file comment length 2 bytes */
unsigned short disk_num_start; /* disk number start 2 bytes */
unsigned short internal_fa; /* internal file attributes 2 bytes */
unsigned long external_fa; /* external file attributes 4 bytes */
// tm_unz tmu_date;
unsigned long offset, c_offset;
} unz_file_info;
#pragma pack(pop)
extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
const char* fileName2,
int iCaseSensitivity));
/*
Compare two filename (fileName1,fileName2).
If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
or strcasecmp)
If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
(like 1 on Unix, 2 on Windows)
*/
extern unzFile ZEXPORT unzOpen (vfsfile_t *fin);
/*
Open a Zip file. path contain the full pathname (by example,
on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer
"zlib/zlib111.zip".
If the zipfile cannot be opened (file don't exist or in not valid), the
return value is NULL.
Else, the return value is a unzFile Handle, usable with other function
of this unzip package.
*/
extern int ZEXPORT unzClose (unzFile file);
/*
Close a ZipFile opened with unzipOpen.
If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
return UNZ_OK if there is no problem. */
extern int ZEXPORT unzGetGlobalInfo (unzFile file,
unz_global_info *pglobal_info);
/*
Write info about the ZipFile in the *pglobal_info structure.
No preparation of the structure is needed
return UNZ_OK if there is no problem. */
extern int ZEXPORT unzGetGlobalComment (unzFile file,
char *szComment,
unsigned long uSizeBuf);
/*
Get the global comment string of the ZipFile, in the szComment buffer.
uSizeBuf is the size of the szComment buffer.
return the number of byte copied or an error code <0
*/
/***************************************************************************/
/* Unzip package allow you browse the directory of the zipfile */
extern int ZEXPORT unzGoToFirstFile (unzFile file);
/*
Set the current file of the zipfile to the first file.
return UNZ_OK if there is no problem
*/
extern int ZEXPORT unzGoToNextFile (unzFile file);
/*
Set the current file of the zipfile to the next file.
return UNZ_OK if there is no problem
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
*/
extern int ZEXPORT unzLocateFile (unzFile file,
const char *szFileName,
int iCaseSensitivity);
extern int ZEXPORT unzLocateFileMy (unzFile file, unsigned long num, unsigned long pos);
/*
Try locate the file szFileName in the zipfile.
For the iCaseSensitivity signification, see unzStringFileNameCompare
return value :
UNZ_OK if the file is found. It becomes the current file.
UNZ_END_OF_LIST_OF_FILE if the file is not found
*/
extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
unz_file_info *pfile_info,
char *szFileName,
unsigned long fileNameBufferSize,
void *extraField,
unsigned long extraFieldBufferSize,
char *szComment,
unsigned long commentBufferSize);
/*
Get Info about the current file
if pfile_info!=NULL, the *pfile_info structure will contain somes info about
the current file
if szFileName!=NULL, the filemane string will be copied in szFileName
(fileNameBufferSize is the size of the buffer)
if extraField!=NULL, the extra field information will be copied in extraField
(extraFieldBufferSize is the size of the buffer).
This is the Central-header version of the extra field
if szComment!=NULL, the comment string of the file will be copied in szComment
(commentBufferSize is the size of the buffer)
*/
/***************************************************************************/
/* for reading the content of the current zipfile, you can open it, read data
from it, and close it (you can close it before reading all the file)
*/
extern int ZEXPORT unzOpenCurrentFile (unzFile file);
/*
Open for reading data the current file in the zipfile.
If there is no error, the return value is UNZ_OK.
*/
extern int ZEXPORT unzCloseCurrentFile (unzFile file);
/*
Close the file in zip opened with unzOpenCurrentFile
Return UNZ_CRCERROR if all the file was read but the CRC is not good
*/
extern int ZEXPORT unzReadCurrentFile (unzFile file,
voidp buf,
unsigned len);
/*
Read bytes from the current file (opened by unzOpenCurrentFile)
buf contain buffer where data must be copied
len the size of buf.
return the number of byte copied if somes bytes are copied
return 0 if the end of file was reached
return <0 with error code if there is an error
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
*/
extern z_off_t ZEXPORT unztell (unzFile file);
/*
Give the current position in uncompressed data
*/
extern int ZEXPORT unzeof (unzFile file);
/*
return 1 if the end of file was reached, 0 elsewhere
*/
extern int ZEXPORT unzGetLocalExtrafield (unzFile file,
voidp buf,
unsigned len);
/*
Read extra field from the current file (opened by unzOpenCurrentFile)
This is the local-header version of the extra field (sometimes, there is
more info in the local-header version than in the central-header)
if buf==NULL, it return the size of the local extra field
if buf!=NULL, len is the size of the buffer, the extra header is copied in
buf.
the return value is the number of bytes copied in buf, or (if <0)
the error code
*/
#ifdef __cplusplus
}
#endif
#endif /* _unz_H */

View file

@ -17,8 +17,12 @@
#if defined(_WIN64) #if defined(_WIN64)
#define qintptr_t __int64 #define qintptr_t __int64
#define FTE_WORDSIZE 64 #define FTE_WORDSIZE 64
#define quintptr_t unsigned qintptr_t
#elif defined(_WIN32) #elif defined(_WIN32)
#define qintptr_t __int32 typedef __int32 qintptr_t; //add __w64 if you need msvc to shut up about unsafe type conversions
typedef unsigned __int32 quintptr_t;
// #define qintptr_t __int32
// #define quintptr_t unsigned qintptr_t
#define FTE_WORDSIZE 32 #define FTE_WORDSIZE 32
#else #else
#if __WORDSIZE == 64 #if __WORDSIZE == 64
@ -28,8 +32,8 @@
#define qintptr_t long #define qintptr_t long
#define FTE_WORDSIZE 32 #define FTE_WORDSIZE 32
#endif #endif
#define quintptr_t unsigned qintptr_t
#endif #endif
#define quintptr_t unsigned qintptr_t
#endif #endif
#ifndef FTE_WORDSIZE #ifndef FTE_WORDSIZE

View file

@ -126,8 +126,8 @@ char *D3D_NameForResult(HRESULT hr)
static void D3D11_PresentOrCrash(void) static void D3D11_PresentOrCrash(void)
{ {
extern cvar_t _vid_wait_override; extern cvar_t vid_vsync;
HRESULT hr = IDXGISwapChain_Present(d3dswapchain, _vid_wait_override.ival, 0); HRESULT hr = IDXGISwapChain_Present(d3dswapchain, vid_vsync.ival, 0);
if (FAILED(hr)) if (FAILED(hr))
Sys_Error("IDXGISwapChain_Present: %s\n", D3D_NameForResult(hr)); Sys_Error("IDXGISwapChain_Present: %s\n", D3D_NameForResult(hr));
} }

File diff suppressed because it is too large Load diff

View file

@ -89,13 +89,11 @@ struct {
texid_t tex_normals; texid_t tex_normals;
texid_t tex_diffuse; texid_t tex_diffuse;
int fbo_current; //the one currently being rendered to int fbo_current; //the one currently being rendered to
int fbo_diffuse;
int rb_depth;
int rb_stencil;
texid_t tex_sourcecol; /*this is used by $sourcecolour tgen*/ texid_t tex_sourcecol; /*this is used by $sourcecolour tgen*/
texid_t tex_sourcedepth; texid_t tex_sourcedepth;
int fbo_depthless; fbostate_t fbo_2dfbo;
int fbo_reflection; fbostate_t fbo_reflectrefrac;
fbostate_t fbo_lprepass;
texid_t tex_reflection; /*basically a portal rendered to texture*/ texid_t tex_reflection; /*basically a portal rendered to texture*/
texid_t tex_refraction; /*the (culled) underwater view*/ texid_t tex_refraction; /*the (culled) underwater view*/
texid_t tex_refractiondepth; /*the (culled) underwater view*/ texid_t tex_refractiondepth; /*the (culled) underwater view*/
@ -1501,6 +1499,11 @@ static float *tcgen(unsigned int tcgen, int cnt, float *dst, const mesh_t *mesh)
dst[1] = DotProduct(tc_gen_t, src[i]); dst[1] = DotProduct(tc_gen_t, src[i]);
} }
return dst; return dst;
// case TC_GEN_SKYBOX:
// case TC_GEN_WOBBLESKY:
// case TC_GEN_REFLECT:
// break;
} }
} }
@ -2348,14 +2351,14 @@ static void BE_GeneratePassTC(const shaderpass_t *pass, int tmu)
if (!pass->numtcmods) if (!pass->numtcmods)
{ {
//if there are no tcmods, pass through here as fast as possible //if there are no tcmods, pass through here as fast as possible
if (pass->tcgen == TC_GEN_BASE) switch(pass->tcgen)
{ {
case TC_GEN_BASE:
shaderstate.pendingtexcoordparts[tmu] = 2; shaderstate.pendingtexcoordparts[tmu] = 2;
shaderstate.pendingtexcoordvbo[tmu] = shaderstate.sourcevbo->texcoord.gl.vbo; shaderstate.pendingtexcoordvbo[tmu] = shaderstate.sourcevbo->texcoord.gl.vbo;
shaderstate.pendingtexcoordpointer[tmu] = shaderstate.sourcevbo->texcoord.gl.addr; shaderstate.pendingtexcoordpointer[tmu] = shaderstate.sourcevbo->texcoord.gl.addr;
} break;
else if (pass->tcgen == TC_GEN_LIGHTMAP) case TC_GEN_LIGHTMAP:
{
if (!shaderstate.sourcevbo->lmcoord[0].gl.addr) if (!shaderstate.sourcevbo->lmcoord[0].gl.addr)
{ {
shaderstate.pendingtexcoordparts[tmu] = 2; shaderstate.pendingtexcoordparts[tmu] = 2;
@ -2368,29 +2371,30 @@ static void BE_GeneratePassTC(const shaderpass_t *pass, int tmu)
shaderstate.pendingtexcoordvbo[tmu] = shaderstate.sourcevbo->lmcoord[0].gl.vbo; shaderstate.pendingtexcoordvbo[tmu] = shaderstate.sourcevbo->lmcoord[0].gl.vbo;
shaderstate.pendingtexcoordpointer[tmu] = shaderstate.sourcevbo->lmcoord[0].gl.addr; shaderstate.pendingtexcoordpointer[tmu] = shaderstate.sourcevbo->lmcoord[0].gl.addr;
} }
} break;
else if (pass->tcgen == TC_GEN_NORMAL) case TC_GEN_NORMAL:
{
shaderstate.pendingtexcoordparts[tmu] = 3; shaderstate.pendingtexcoordparts[tmu] = 3;
shaderstate.pendingtexcoordvbo[tmu] = shaderstate.sourcevbo->normals.gl.vbo; shaderstate.pendingtexcoordvbo[tmu] = shaderstate.sourcevbo->normals.gl.vbo;
shaderstate.pendingtexcoordpointer[tmu] = shaderstate.sourcevbo->normals.gl.addr; shaderstate.pendingtexcoordpointer[tmu] = shaderstate.sourcevbo->normals.gl.addr;
} break;
else if (pass->tcgen == TC_GEN_SVECTOR) case TC_GEN_SVECTOR:
{
shaderstate.pendingtexcoordparts[tmu] = 3; shaderstate.pendingtexcoordparts[tmu] = 3;
shaderstate.pendingtexcoordvbo[tmu] = shaderstate.sourcevbo->svector.gl.vbo; shaderstate.pendingtexcoordvbo[tmu] = shaderstate.sourcevbo->svector.gl.vbo;
shaderstate.pendingtexcoordpointer[tmu] = shaderstate.sourcevbo->svector.gl.addr; shaderstate.pendingtexcoordpointer[tmu] = shaderstate.sourcevbo->svector.gl.addr;
} break;
else if (pass->tcgen == TC_GEN_TVECTOR) case TC_GEN_TVECTOR:
{
shaderstate.pendingtexcoordparts[tmu] = 3; shaderstate.pendingtexcoordparts[tmu] = 3;
shaderstate.pendingtexcoordvbo[tmu] = shaderstate.sourcevbo->tvector.gl.vbo; shaderstate.pendingtexcoordvbo[tmu] = shaderstate.sourcevbo->tvector.gl.vbo;
shaderstate.pendingtexcoordpointer[tmu] = shaderstate.sourcevbo->tvector.gl.addr; shaderstate.pendingtexcoordpointer[tmu] = shaderstate.sourcevbo->tvector.gl.addr;
} break;
else // case TC_GEN_SKYBOX:
{ //position - viewpos
// case TC_GEN_WOBBLESKY:
// case TC_GEN_REFLECT:
default:
//specular highlights and reflections have no fixed data, and must be generated. //specular highlights and reflections have no fixed data, and must be generated.
GenerateTCMods(pass, tmu); GenerateTCMods(pass, tmu);
break;
} }
} }
else else
@ -3775,6 +3779,7 @@ static void DrawMeshes(void)
case BEM_WIREFRAME: case BEM_WIREFRAME:
//FIXME: do this with a shader instead? its not urgent as we can draw the shader normally anyway, just faster. //FIXME: do this with a shader instead? its not urgent as we can draw the shader normally anyway, just faster.
//FIXME: we need to use a shader for vertex blending. not really an issue with mdl, but more significant with iqms (base pose!).
GL_DeSelectProgram(); GL_DeSelectProgram();
shaderstate.pendingcolourvbo = 0; shaderstate.pendingcolourvbo = 0;
shaderstate.pendingcolourpointer = NULL; shaderstate.pendingcolourpointer = NULL;
@ -4210,6 +4215,7 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
if ((batch->shader->flags & (SHADER_HASREFLECT | SHADER_HASREFRACT | SHADER_HASRIPPLEMAP)) && shaderstate.mode != BEM_WIREFRAME) if ((batch->shader->flags & (SHADER_HASREFLECT | SHADER_HASREFRACT | SHADER_HASRIPPLEMAP)) && shaderstate.mode != BEM_WIREFRAME)
{ {
int oldfbo;
float oldil; float oldil;
int oldbem; int oldbem;
//these flags require rendering some view as an fbo //these flags require rendering some view as an fbo
@ -4234,23 +4240,22 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
} }
GL_ForceDepthWritable(); oldfbo = GLBE_FBO_Update(&shaderstate.fbo_reflectrefrac, true, FBO_TEX_COLOUR|FBO_RB_DEPTH, shaderstate.tex_reflection, r_nulltex, vid.pixelwidth/2, vid.pixelheight/2);
GLBE_RenderToTexture(r_nulltex, r_nulltex, shaderstate.tex_reflection, r_nulltex, true);
r_refdef.vrect.x = 0; r_refdef.vrect.x = 0;
r_refdef.vrect.y = 0; r_refdef.vrect.y = 0;
r_refdef.vrect.width = vid.width/2; r_refdef.vrect.width = vid.fbvwidth/2;
r_refdef.vrect.height = vid.height/2; r_refdef.vrect.height = vid.fbvheight/2;
r_refdef.pxrect.x = 0; r_refdef.pxrect.x = 0;
r_refdef.pxrect.y = 0; r_refdef.pxrect.y = 0;
r_refdef.pxrect.width = vid.pixelwidth/2; r_refdef.pxrect.width = vid.fbpwidth/2;
r_refdef.pxrect.height = vid.pixelheight/2; r_refdef.pxrect.height = vid.fbpheight/2;
r_refdef.pxrect.maxheight = vid.pixelheight/2; r_refdef.pxrect.maxheight = shaderstate.fbo_reflectrefrac.rb_size[1];
GL_ViewportUpdate(); GL_ViewportUpdate();
GL_ForceDepthWritable(); GL_ForceDepthWritable();
qglClearColor(0, 0, 0, 0); qglClearColor(0, 0, 0, 0);
qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLR_DrawPortal(batch, cl.worldmodel->batches, NULL, 1); GLR_DrawPortal(batch, cl.worldmodel->batches, NULL, 1);
GLBE_RenderToTexture(r_nulltex, r_nulltex, r_nulltex, r_nulltex, false); GLBE_FBO_Pop(oldfbo);
r_refdef.vrect = orect; r_refdef.vrect = orect;
r_refdef.pxrect = oprect; r_refdef.pxrect = oprect;
GL_ViewportUpdate(); GL_ViewportUpdate();
@ -4261,7 +4266,6 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
{ {
vrect_t ovrect = r_refdef.vrect; vrect_t ovrect = r_refdef.vrect;
pxrect_t oprect = r_refdef.pxrect; pxrect_t oprect = r_refdef.pxrect;
GL_ForceDepthWritable();
if (!shaderstate.tex_refraction.num) if (!shaderstate.tex_refraction.num)
{ {
@ -4285,27 +4289,29 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
} }
GLBE_RenderToTexture(r_nulltex, r_nulltex, shaderstate.tex_refraction, shaderstate.tex_refractiondepth, true); oldfbo = GLBE_FBO_Update(&shaderstate.fbo_reflectrefrac, true, FBO_TEX_COLOUR|FBO_TEX_DEPTH, shaderstate.tex_refraction, shaderstate.tex_refractiondepth, vid.pixelwidth/2, vid.pixelheight/2);
} }
else else
GLBE_RenderToTexture(r_nulltex, r_nulltex, shaderstate.tex_refraction, r_nulltex, true); {
oldfbo = GLBE_FBO_Update(&shaderstate.fbo_reflectrefrac, true, FBO_TEX_COLOUR|FBO_RB_DEPTH, shaderstate.tex_refraction, r_nulltex, vid.pixelwidth/2, vid.pixelheight/2);
}
r_refdef.vrect.x = 0; r_refdef.vrect.x = 0;
r_refdef.vrect.y = 0; r_refdef.vrect.y = 0;
r_refdef.vrect.width = vid.width/2; r_refdef.vrect.width = vid.fbvwidth/2;
r_refdef.vrect.height = vid.height/2; r_refdef.vrect.height = vid.fbvheight/2;
r_refdef.pxrect.x = 0; r_refdef.pxrect.x = 0;
r_refdef.pxrect.y = 0; r_refdef.pxrect.y = 0;
r_refdef.pxrect.width = vid.pixelwidth/2; r_refdef.pxrect.width = vid.fbpwidth/2;
r_refdef.pxrect.height = vid.pixelheight/2; r_refdef.pxrect.height = vid.fbpheight/2;
r_refdef.pxrect.maxheight = vid.pixelheight/2; r_refdef.pxrect.maxheight = shaderstate.fbo_reflectrefrac.rb_size[1];
GL_ViewportUpdate(); GL_ViewportUpdate();
GL_ForceDepthWritable(); GL_ForceDepthWritable();
qglClearColor(0, 0, 0, 0); qglClearColor(0, 0, 0, 0);
qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLR_DrawPortal(batch, cl.worldmodel->batches, NULL, ((batch->shader->flags & SHADER_HASREFRACTDEPTH)?3:2)); //fixme GLR_DrawPortal(batch, cl.worldmodel->batches, NULL, ((batch->shader->flags & SHADER_HASREFRACTDEPTH)?3:2)); //fixme
GLBE_RenderToTexture(r_nulltex, r_nulltex, r_nulltex, r_nulltex, false); GLBE_FBO_Pop(oldfbo);
r_refdef.vrect = ovrect; r_refdef.vrect = ovrect;
r_refdef.pxrect = oprect; r_refdef.pxrect = oprect;
@ -4323,22 +4329,22 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
//FIXME: can we use RGB8 instead? //FIXME: can we use RGB8 instead?
shaderstate.tex_ripplemap = GL_AllocNewTexture("***tex_ripplemap***", vid.pixelwidth/2, vid.pixelheight/2, 0); shaderstate.tex_ripplemap = GL_AllocNewTexture("***tex_ripplemap***", vid.pixelwidth/2, vid.pixelheight/2, 0);
GL_MTBind(0, GL_TEXTURE_2D, shaderstate.tex_ripplemap); GL_MTBind(0, GL_TEXTURE_2D, shaderstate.tex_ripplemap);
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, vid.pixelwidth/2, vid.pixelheight/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); qglTexImage2D(GL_TEXTURE_2D, 0, /*(gl_config.glversion>3.1)?GL_RGBA8_SNORM:*/GL_RGBA16F_ARB, vid.pixelwidth/2, vid.pixelheight/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 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_MIN_FILTER, GL_LINEAR);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
} }
GLBE_RenderToTexture(r_nulltex, r_nulltex, shaderstate.tex_ripplemap, r_nulltex, false); oldfbo = GLBE_FBO_Update(&shaderstate.fbo_reflectrefrac, true, FBO_TEX_COLOUR, shaderstate.tex_ripplemap, r_nulltex, vid.pixelwidth/2, vid.pixelheight/2);
r_refdef.vrect.x = 0; r_refdef.vrect.x = 0;
r_refdef.vrect.y = 0; r_refdef.vrect.y = 0;
r_refdef.vrect.width = vid.width/2; r_refdef.vrect.width = vid.fbvwidth/2;
r_refdef.vrect.height = vid.height/2; r_refdef.vrect.height = vid.fbvheight/2;
r_refdef.pxrect.x = 0; r_refdef.pxrect.x = 0;
r_refdef.pxrect.y = 0; r_refdef.pxrect.y = 0;
r_refdef.pxrect.width = vid.pixelwidth/2; r_refdef.pxrect.width = vid.fbpwidth/2;
r_refdef.pxrect.height = vid.pixelheight/2; r_refdef.pxrect.height = vid.fbpheight/2;
r_refdef.pxrect.maxheight = vid.pixelheight/2; r_refdef.pxrect.maxheight = shaderstate.fbo_reflectrefrac.rb_size[1];
GL_ViewportUpdate(); GL_ViewportUpdate();
qglClearColor(0, 0, 0, 0); qglClearColor(0, 0, 0, 0);
@ -4349,7 +4355,7 @@ static void GLBE_SubmitMeshesSortList(batch_t *sortlist)
r_refdef.recurse+=1; //paranoid, should stop potential infinite loops r_refdef.recurse+=1; //paranoid, should stop potential infinite loops
GLBE_SubmitMeshes(true, SHADER_SORT_RIPPLE, SHADER_SORT_RIPPLE); GLBE_SubmitMeshes(true, SHADER_SORT_RIPPLE, SHADER_SORT_RIPPLE);
r_refdef.recurse-=1; r_refdef.recurse-=1;
GLBE_RenderToTexture(r_nulltex, r_nulltex, r_nulltex, r_nulltex, false); GLBE_FBO_Pop(oldfbo);
r_refdef.vrect = orect; r_refdef.vrect = orect;
r_refdef.pxrect = oprect; r_refdef.pxrect = oprect;
@ -4462,6 +4468,179 @@ void GLBE_BaseEntTextures(void)
} }
#endif #endif
void GLBE_RenderToTextureUpdate2d(qboolean destchanged)
{
unsigned int width, height;
if (destchanged)
{
if (r_refdef.rt_destcolour)
{
texid_t tex = R2D_RT_GetTexture(r_refdef.rt_destcolour, &width, &height);
GLBE_FBO_Update(&shaderstate.fbo_2dfbo, true, FBO_TEX_COLOUR, tex, r_nulltex, width, height);
}
else
GLBE_FBO_Push(NULL);
GL_Set2D(false);
}
else
{
shaderstate.tex_sourcecol = R2D_RT_GetTexture(r_refdef.rt_sourcecolour, &width, &height);
shaderstate.tex_sourcedepth = R2D_RT_GetTexture(r_refdef.rt_depth, &width, &height);
}
}
void GLBE_FBO_Sources(texid_t sourcecolour, texid_t sourcedepth)
{
shaderstate.tex_sourcecol = sourcecolour;
shaderstate.tex_sourcedepth = sourcedepth;
}
int GLBE_FBO_Push(fbostate_t *state)
{
int newfbo;
int oldfbo = shaderstate.fbo_current;
if (state)
newfbo = state->fbo;
else
newfbo = 0;
if (shaderstate.fbo_current == newfbo) //don't bother if its not changed (also avoids crashes when fbos are not supported)
return oldfbo;
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shaderstate.fbo_current=newfbo);
return oldfbo;
}
void GLBE_FBO_Pop(int oldfbo)
{
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, oldfbo);
shaderstate.fbo_current = oldfbo;
}
void GLBE_FBO_Destroy(fbostate_t *state)
{
if (state->fbo == shaderstate.fbo_current)
GLBE_FBO_Push(NULL);
//wasn't initialised anyway.
if (!state->fbo)
return;
qglDeleteFramebuffersEXT(1, &state->fbo);
state->fbo = 0;
if (state->rb_depth)
qglDeleteRenderbuffersEXT(1, &state->rb_depth);
state->rb_depth = 0;
if (state->rb_stencil)
qglDeleteRenderbuffersEXT(1, &state->rb_stencil);
state->rb_stencil = 0;
if (state->rb_depthstencil)
qglDeleteRenderbuffersEXT(1, &state->rb_depthstencil);
state->rb_depthstencil = 0;
state->enables = 0;
}
//state->colour is created if usedepth is set and it doesn't previously exist
int GLBE_FBO_Update(fbostate_t *state, qboolean bind, unsigned int enables, texid_t destcol, texid_t destdepth, int width, int height)
{
int old;
if (TEXVALID(destcol))
{
enables |= FBO_TEX_COLOUR;
enables &= ~FBO_RB_COLOUR;
}
if (TEXVALID(destdepth))
{
enables |= FBO_TEX_DEPTH;
enables &= ~FBO_RB_DEPTH;
}
if ((state->enables ^ enables) & ~FBO_RESET)
{
GLBE_FBO_Destroy(state);
state->enables = enables & ~FBO_RESET;
enables |= FBO_RESET;
}
if (!state->fbo)
{
qglGenFramebuffersEXT(1, &state->fbo);
old = GLBE_FBO_Push(state);
enables |= FBO_RESET;
}
else
old = GLBE_FBO_Push(state);
if (state->rb_size[0] != width || state->rb_size[1] != height || (enables & FBO_RESET))
{
if (state->rb_depth && !(enables & FBO_RB_DEPTH))
{
qglDeleteRenderbuffersEXT(1, &state->rb_depth);
state->rb_depth = 0;
}
if (state->rb_stencil && !(enables & FBO_RB_STENCIL))
{
qglDeleteRenderbuffersEXT(1, &state->rb_stencil);
state->rb_stencil = 0;
}
state->rb_size[0] = width;
state->rb_size[1] = height;
enables |= FBO_RESET;
if (enables & (FBO_TEX_COLOUR|FBO_RB_COLOUR))
{
qglDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
qglReadBuffer(GL_COLOR_ATTACHMENT0_EXT);
}
else
{
qglDrawBuffer(GL_NONE);
qglReadBuffer(GL_NONE);
}
}
if (enables & FBO_TEX_DEPTH)
{
qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, destdepth.num, 0);
//fixme: no stencil
}
else if (enables & FBO_RB_DEPTH)
{
if (!state->rb_depth)
{
//create an unnamed depth buffer
qglGenRenderbuffersEXT(1, &state->rb_depth);
qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, state->rb_depth);
if (!gl_config.ext_packed_depth_stencil)
qglGenRenderbuffersEXT(1, &state->rb_stencil);
enables |= FBO_RESET; //make sure it gets instanciated
}
if (enables & FBO_RESET)
{
qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, state->rb_depth);
if (gl_config.ext_packed_depth_stencil)
qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, state->rb_size[0], state->rb_size[1]);
else
{
qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24_ARB, state->rb_size[0], state->rb_size[1]);
qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, state->rb_stencil);
qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT, state->rb_size[0], state->rb_size[1]);
}
qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, state->rb_depth);
if (gl_config.ext_packed_depth_stencil)
qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, state->rb_depth);
else
qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, state->rb_stencil);
}
}
if (enables & FBO_TEX_COLOUR)
qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, destcol.num, 0);
return old;
}
/*
void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, texid_t destdepth, qboolean usedepth) void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, texid_t destdepth, qboolean usedepth)
{ {
shaderstate.tex_sourcecol = sourcecol; shaderstate.tex_sourcecol = sourcecol;
@ -4485,16 +4664,12 @@ void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destco
qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, shaderstate.rb_depth); qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, shaderstate.rb_depth);
if (gl_config.ext_packed_depth_stencil) if (gl_config.ext_packed_depth_stencil)
{ {
qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, vid.pixelwidth/2, vid.pixelheight/2);
qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, shaderstate.rb_depth); qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, shaderstate.rb_depth);
} }
else else
{ {
qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24_ARB, vid.pixelwidth/2, vid.pixelheight/2);
qglGenRenderbuffersEXT(1, &shaderstate.rb_stencil); qglGenRenderbuffersEXT(1, &shaderstate.rb_stencil);
qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, shaderstate.rb_stencil); qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, shaderstate.rb_stencil);
qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT, vid.pixelwidth/2, vid.pixelheight/2);
qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, shaderstate.rb_stencil); qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, shaderstate.rb_stencil);
} }
qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, shaderstate.rb_depth); qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, shaderstate.rb_depth);
@ -4507,9 +4682,38 @@ void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destco
shaderstate.fbo_current = shaderstate.fbo_diffuse; shaderstate.fbo_current = shaderstate.fbo_diffuse;
if (destdepth.num) if (destdepth.num)
{
qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, destdepth.num, 0); qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, destdepth.num, 0);
qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0);
}
else else
{
//resize the depth renderbuffer if its the wrong size now
if (shaderstate.rb_depth_size[0] != r_refdef.fbo_width || shaderstate.rb_depth_size[1] != r_refdef.fbo_height)
{
shaderstate.rb_depth_size[0] = r_refdef.fbo_width;
shaderstate.rb_depth_size[1] = r_refdef.fbo_height;
qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, shaderstate.rb_depth);
if (gl_config.ext_packed_depth_stencil)
{
qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, r_refdef.fbo_width, r_refdef.fbo_height);
qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, shaderstate.rb_depth);
}
else
{
qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24_ARB, r_refdef.fbo_width, r_refdef.fbo_height);
qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, shaderstate.rb_stencil);
qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT, r_refdef.fbo_width, r_refdef.fbo_height);
}
}
qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, shaderstate.rb_depth); qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, shaderstate.rb_depth);
if (gl_config.ext_packed_depth_stencil)
qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, shaderstate.rb_depth);
else
qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, shaderstate.rb_stencil);
}
} }
else else
{ {
@ -4530,9 +4734,18 @@ void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destco
qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, destcol.num, 0); qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, destcol.num, 0);
} }
} }
*/
void GLBE_DrawLightPrePass(qbyte *vis) void GLBE_DrawLightPrePass(qbyte *vis)
{ {
/*
walls(bumps) -> normalbuffer
lights+normalbuffer -> lightlevelbuffer
walls(diffuse)+lightlevelbuffer -> screen
normalbuffer contains depth in the alpha channel. an actual depthbuffer is also generated at this time, which is used for depth test stuff but not as a shader input.
*/
int oldfbo;
if (!shaderstate.initeddepthnorm) if (!shaderstate.initeddepthnorm)
{ {
shaderstate.initeddepthnorm = true; shaderstate.initeddepthnorm = true;
@ -4579,8 +4792,6 @@ void GLBE_DrawLightPrePass(qbyte *vis)
if (!TEXVALID(shaderstate.tex_diffuse)) if (!TEXVALID(shaderstate.tex_diffuse))
{ {
int drb;
shaderstate.tex_diffuse = GL_AllocNewTexture("***prepass diffuse***", vid.pixelwidth, vid.pixelheight, 0); shaderstate.tex_diffuse = GL_AllocNewTexture("***prepass diffuse***", vid.pixelwidth, vid.pixelheight, 0);
GL_MTBind(0, GL_TEXTURE_2D, shaderstate.tex_diffuse); GL_MTBind(0, GL_TEXTURE_2D, shaderstate.tex_diffuse);
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, vid.pixelwidth, vid.pixelheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, vid.pixelwidth, vid.pixelheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
@ -4592,26 +4803,12 @@ void GLBE_DrawLightPrePass(qbyte *vis)
r_lightprepass.modified = false; r_lightprepass.modified = false;
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); qglTexParameteri(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_MIN_FILTER, GL_NEAREST);
qglGenFramebuffersEXT(1, &shaderstate.fbo_diffuse);
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shaderstate.fbo_diffuse);
qglGenRenderbuffersEXT(1, &drb);
qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, drb);
qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24_ARB, vid.pixelwidth, vid.pixelheight);
qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, drb);
qglDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
// qglReadBuffer(GL_NONE);
} }
else
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shaderstate.fbo_diffuse);
/*set the FB up to draw surface info*/ /*set the FB up to draw surface info*/
qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, shaderstate.tex_normals.num, 0); oldfbo = GLBE_FBO_Update(&shaderstate.fbo_lprepass, true, FBO_TEX_COLOUR|FBO_RB_DEPTH, shaderstate.tex_normals, r_nulltex, vid.pixelwidth, vid.pixelheight);
GL_ForceDepthWritable(); GL_ForceDepthWritable();
//FIXME: should probably clear colour buffer too.
qglClear(GL_DEPTH_BUFFER_BIT); qglClear(GL_DEPTH_BUFFER_BIT);
if (GL_FRAMEBUFFER_COMPLETE_EXT != qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)) if (GL_FRAMEBUFFER_COMPLETE_EXT != qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT))
@ -4624,8 +4821,8 @@ void GLBE_DrawLightPrePass(qbyte *vis)
GLBE_SubmitMeshes(true, SHADER_SORT_OPAQUE, SHADER_SORT_OPAQUE); GLBE_SubmitMeshes(true, SHADER_SORT_OPAQUE, SHADER_SORT_OPAQUE);
/*reconfigure - now drawing diffuse light info using the previous fb image as a source image*/ /*reconfigure - now drawing diffuse light info using the previous fb image as a source image*/
shaderstate.tex_sourcecol = shaderstate.tex_normals; GLBE_FBO_Sources(shaderstate.tex_normals, r_nulltex);
qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, shaderstate.tex_diffuse.num, 0); GLBE_FBO_Update(&shaderstate.fbo_lprepass, true, FBO_TEX_COLOUR|FBO_RB_DEPTH, shaderstate.tex_diffuse, r_nulltex, vid.pixelwidth, vid.pixelheight);
BE_SelectMode(BEM_STANDARD); BE_SelectMode(BEM_STANDARD);
qglClearColor (0,0,0,0); qglClearColor (0,0,0,0);
@ -4636,8 +4833,8 @@ void GLBE_DrawLightPrePass(qbyte *vis)
GLBE_SubmitMeshes(true, SHADER_SORT_PRELIGHT, SHADER_SORT_PRELIGHT); GLBE_SubmitMeshes(true, SHADER_SORT_PRELIGHT, SHADER_SORT_PRELIGHT);
/*final reconfigure - now drawing final surface data onto true framebuffer*/ /*final reconfigure - now drawing final surface data onto true framebuffer*/
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); GLBE_FBO_Pop(oldfbo);
shaderstate.tex_sourcecol = shaderstate.tex_diffuse; GLBE_FBO_Sources(shaderstate.tex_diffuse, r_nulltex);
qglDrawBuffer(GL_BACK); qglDrawBuffer(GL_BACK);
/*now draw the postlight passes (this includes blended stuff which will NOT be lit)*/ /*now draw the postlight passes (this includes blended stuff which will NOT be lit)*/
@ -4650,9 +4847,7 @@ void GLBE_DrawLightPrePass(qbyte *vis)
Sh_DrawLights(vis); Sh_DrawLights(vis);
#endif #endif
shaderstate.tex_sourcecol = r_nulltex; GLBE_FBO_Sources(r_nulltex, r_nulltex);
shaderstate.tex_sourcedepth = r_nulltex;
qglClearColor (1,0,0,1); qglClearColor (1,0,0,1);
} }
@ -4670,7 +4865,6 @@ void GLBE_DrawWorld (qboolean drawworld, qbyte *vis)
if (!r_refdef.recurse) if (!r_refdef.recurse)
{ {
shaderstate.fbo_current = 0; //just in case something crashed
GL_DoSwap(); GL_DoSwap();
if (shaderstate.wbatch + 50 > shaderstate.maxwbatches) if (shaderstate.wbatch + 50 > shaderstate.maxwbatches)
{ {
@ -4684,6 +4878,10 @@ void GLBE_DrawWorld (qboolean drawworld, qbyte *vis)
} }
if (shaderstate.oldwidth != vid.pixelwidth || shaderstate.oldheight != vid.pixelheight) if (shaderstate.oldwidth != vid.pixelwidth || shaderstate.oldheight != vid.pixelheight)
{ {
GLBE_FBO_Destroy(&shaderstate.fbo_2dfbo);
GLBE_FBO_Destroy(&shaderstate.fbo_reflectrefrac);
GLBE_FBO_Destroy(&shaderstate.fbo_lprepass);
if (shaderstate.tex_reflection.num) if (shaderstate.tex_reflection.num)
{ {
R_DestroyTexture(shaderstate.tex_reflection); R_DestroyTexture(shaderstate.tex_reflection);
@ -4704,17 +4902,6 @@ void GLBE_DrawWorld (qboolean drawworld, qbyte *vis)
R_DestroyTexture(shaderstate.temptexture); R_DestroyTexture(shaderstate.temptexture);
shaderstate.temptexture = r_nulltex; shaderstate.temptexture = r_nulltex;
} }
if (shaderstate.fbo_diffuse)
{
qglDeleteFramebuffersEXT(1, &shaderstate.fbo_diffuse);
shaderstate.fbo_diffuse = 0;
}
if (shaderstate.rb_depth)
qglDeleteRenderbuffersEXT(1, &shaderstate.rb_depth);
shaderstate.rb_depth = 0;
if (shaderstate.rb_stencil)
qglDeleteRenderbuffersEXT(1, &shaderstate.rb_stencil);
shaderstate.rb_stencil = 0;
shaderstate.oldwidth = vid.pixelwidth; shaderstate.oldwidth = vid.pixelwidth;
shaderstate.oldheight = vid.pixelheight; shaderstate.oldheight = vid.pixelheight;

View file

@ -55,6 +55,7 @@ static shader_t *bloomfinal;
#define MAXLEVELS 3 #define MAXLEVELS 3
texid_t scrtex; texid_t scrtex;
texid_t pingtex[2][MAXLEVELS]; texid_t pingtex[2][MAXLEVELS];
fbostate_t fbo_bloom;
static int scrwidth, scrheight; static int scrwidth, scrheight;
static int texwidth[MAXLEVELS], texheight[MAXLEVELS]; static int texwidth[MAXLEVELS], texheight[MAXLEVELS];
@ -172,6 +173,7 @@ static void R_SetupBloomTextures(int w, int h)
void R_BloomBlend (void) void R_BloomBlend (void)
{ {
int i; int i;
int oldfbo = 0;
if (!gl_config.ext_framebuffer_objects) if (!gl_config.ext_framebuffer_objects)
return; return;
@ -198,14 +200,16 @@ void R_BloomBlend (void)
if (i == 0) if (i == 0)
{ {
/*filter the screen into a downscaled image*/ /*filter the screen into a downscaled image*/
GLBE_RenderToTexture(scrtex, r_nulltex, pingtex[0][0], r_nulltex, false); oldfbo = GLBE_FBO_Update(&fbo_bloom, true, FBO_TEX_COLOUR, pingtex[0][0], r_nulltex, 0, 0);
GLBE_FBO_Sources(scrtex, r_nulltex);
qglViewport (0, 0, texwidth[0], texheight[0]); qglViewport (0, 0, texwidth[0], texheight[0]);
R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomfilter); R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomfilter);
} }
else else
{ {
/*simple downscale that multiple times*/ /*simple downscale that multiple times*/
GLBE_RenderToTexture(pingtex[0][i-1], r_nulltex, pingtex[0][i], r_nulltex, false); GLBE_FBO_Update(&fbo_bloom, true, FBO_TEX_COLOUR, pingtex[0][i], r_nulltex, 0, 0);
GLBE_FBO_Sources(pingtex[0][i-1], r_nulltex);
qglViewport (0, 0, texwidth[i], texheight[i]); qglViewport (0, 0, texwidth[i], texheight[i]);
R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomrescale); R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomrescale);
} }
@ -218,13 +222,15 @@ void R_BloomBlend (void)
*/ */
r_worldentity.glowmod[0] = 1.2 / texwidth[i]; r_worldentity.glowmod[0] = 1.2 / texwidth[i];
r_worldentity.glowmod[1] = 0; r_worldentity.glowmod[1] = 0;
GLBE_RenderToTexture(pingtex[0][i], r_nulltex, pingtex[1][i], r_nulltex, false); GLBE_FBO_Update(&fbo_bloom, true, FBO_TEX_COLOUR, pingtex[1][i], r_nulltex, 0, 0);
GLBE_FBO_Sources(pingtex[0][i], r_nulltex);
qglViewport (0, 0, texwidth[i], texheight[i]); qglViewport (0, 0, texwidth[i], texheight[i]);
R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomblur); R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomblur);
r_worldentity.glowmod[0] = 0; r_worldentity.glowmod[0] = 0;
r_worldentity.glowmod[1] = 1.2 / texheight[i]; r_worldentity.glowmod[1] = 1.2 / texheight[i];
GLBE_RenderToTexture(pingtex[1][i], r_nulltex, pingtex[0][i], r_nulltex, false); GLBE_FBO_Update(&fbo_bloom, true, FBO_TEX_COLOUR, pingtex[0][i], r_nulltex, 0, 0);
GLBE_FBO_Sources(pingtex[1][i], r_nulltex);
qglViewport (0, 0, texwidth[i], texheight[i]); qglViewport (0, 0, texwidth[i], texheight[i]);
R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomblur); R2D_ScalePic(0, vid.height, vid.width, -(int)vid.height, bloomblur);
} }
@ -234,7 +240,8 @@ void R_BloomBlend (void)
GL_Set2D(false); GL_Set2D(false);
/*combine them onto the screen*/ /*combine them onto the screen*/
GLBE_RenderToTexture(scrtex, r_nulltex, r_nulltex, r_nulltex, false); GLBE_FBO_Pop(oldfbo);
GLBE_FBO_Sources(scrtex, r_nulltex);
R2D_ScalePic(r_refdef.vrect.x, r_refdef.vrect.y + r_refdef.vrect.height, r_refdef.vrect.width, -r_refdef.vrect.height, bloomfinal); R2D_ScalePic(r_refdef.vrect.x, r_refdef.vrect.y + r_refdef.vrect.height, r_refdef.vrect.width, -r_refdef.vrect.height, bloomfinal);
} }
void R_InitBloomTextures(void) void R_InitBloomTextures(void)

View file

@ -37,6 +37,7 @@ static void GL_Upload32_BGRA (char *name, unsigned *data, int width, int height,
static void GL_Upload24BGR_Flip (char *name, qbyte *framedata, int inwidth, int inheight, 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); static void GL_Upload8 (char *name, qbyte *data, int width, int height, unsigned int flags, unsigned int alpha);
static void GL_Upload8Pal32 (qbyte *data, qbyte *pal, int width, int height, unsigned int flags); static void GL_Upload8Pal32 (qbyte *data, qbyte *pal, int width, int height, unsigned int flags);
static void GL_Upload32_Int (char *name, unsigned *data, int width, int height, unsigned int flags, GLenum glcolormode);
void GL_UploadFmt(texid_t tex, char *name, enum uploadfmt fmt, void *data, void *palette, int width, int height, unsigned int flags) void GL_UploadFmt(texid_t tex, char *name, enum uploadfmt fmt, void *data, void *palette, int width, int height, unsigned int flags)
{ {
@ -81,6 +82,23 @@ void GL_UploadFmt(texid_t tex, char *name, enum uploadfmt fmt, void *data, void
GL_Upload8Pal32(data, palette, width, height, flags); GL_Upload8Pal32(data, palette, width, height, flags);
break; break;
//render target formats, data is not supported. this means we can just use the 32bit upload.
case TF_DEPTH16:
GL_Upload32_Int(name, NULL, width, height, flags|IF_NOMIPMAP, GL_DEPTH_COMPONENT16_ARB);
break;
case TF_DEPTH24:
GL_Upload32_Int(name, NULL, width, height, flags|IF_NOMIPMAP, GL_DEPTH_COMPONENT24_ARB);
break;
case TF_DEPTH32:
GL_Upload32_Int(name, NULL, width, height, flags|IF_NOMIPMAP, GL_DEPTH_COMPONENT32_ARB);
break;
case TF_RGBA16F:
GL_Upload32_Int(name, NULL, width, height, flags|IF_NOMIPMAP, GL_RGBA16F_ARB);
break;
case TF_RGBA32F:
GL_Upload32_Int(name, NULL, width, height, flags|IF_NOMIPMAP, GL_RGBA32F_ARB);
break;
default: default:
Sys_Error("Unsupported image format type\n"); Sys_Error("Unsupported image format type\n");
break; break;
@ -569,10 +587,25 @@ void GL_Set2D (qboolean flipped)
float rad, ang; float rad, ang;
float tmp[16], tmp2[16]; float tmp[16], tmp2[16];
float w = vid.width, h = vid.height; float w = vid.width, h = vid.height;
qboolean fbo = !!r_refdef.rt_destcolour;
if (fbo)
{
R2D_RT_GetTexture(r_refdef.rt_destcolour, &vid.fbpwidth, &vid.fbpheight);
vid.fbvwidth = vid.fbpwidth;
vid.fbvheight = vid.fbpheight;
}
else
{
vid.fbvwidth = vid.width;
vid.fbvheight = vid.height;
vid.fbpwidth = vid.pixelwidth;
vid.fbpheight = vid.pixelheight;
}
ang = (gl_screenangle.value>0?(gl_screenangle.value+45):(gl_screenangle.value-45))/90; ang = (gl_screenangle.value>0?(gl_screenangle.value+45):(gl_screenangle.value-45))/90;
ang = (int)ang * 90; ang = (int)ang * 90;
if (ang) if (ang && !fbo)
{ /*more expensive maths*/ { /*more expensive maths*/
rad = (ang * M_PI) / 180; rad = (ang * M_PI) / 180;
@ -587,17 +620,20 @@ void GL_Set2D (qboolean flipped)
} }
else else
{ {
w = vid.fbvwidth;
h = vid.fbvheight;
if (flipped) if (flipped)
Matrix4x4_CM_Orthographic(r_refdef.m_projection, 0, vid.width, 0, vid.height, -99999, 99999); Matrix4x4_CM_Orthographic(r_refdef.m_projection, 0, w, 0, h, -99999, 99999);
else else
Matrix4x4_CM_Orthographic(r_refdef.m_projection, 0, vid.width, vid.height, 0, -99999, 99999); Matrix4x4_CM_Orthographic(r_refdef.m_projection, 0, w, h, 0, -99999, 99999);
Matrix4x4_Identity(r_refdef.m_view); Matrix4x4_Identity(r_refdef.m_view);
} }
//current physical position on the current render target.
r_refdef.pxrect.x = 0; r_refdef.pxrect.x = 0;
r_refdef.pxrect.y = 0; r_refdef.pxrect.y = 0;
r_refdef.pxrect.width = vid.pixelwidth; r_refdef.pxrect.width = vid.fbpwidth;
r_refdef.pxrect.height = vid.pixelheight; r_refdef.pxrect.height = vid.fbpheight;
r_refdef.pxrect.maxheight = vid.pixelheight; r_refdef.pxrect.maxheight = vid.fbpheight;
r_refdef.time = realtime; r_refdef.time = realtime;
/*flush that gl state*/ /*flush that gl state*/
GL_ViewportUpdate(); GL_ViewportUpdate();
@ -1137,7 +1173,7 @@ void GL_8888to4444(int targ, unsigned char *in, unsigned short *out, unsigned in
GL_Upload32 GL_Upload32
=============== ===============
*/ */
void GL_Upload32_Int (char *name, unsigned *data, int width, int height, unsigned int flags, GLenum glcolormode) static void GL_Upload32_Int (char *name, unsigned *data, int width, int height, unsigned int flags, GLenum glcolormode)
{ {
int miplevel=0; int miplevel=0;
int samples; int samples;
@ -1150,18 +1186,21 @@ void GL_Upload32_Int (char *name, unsigned *data, int width, int height, unsigne
scaled_width = width; scaled_width = width;
scaled_height = height; scaled_height = height;
GL_RoundDimensions(&scaled_width, &scaled_height, flags); if (data)
{
GL_RoundDimensions(&scaled_width, &scaled_height, flags);
if (!(flags & IF_NOALPHA)) if (!(flags & IF_NOALPHA))
{ //make sure it does actually have those alpha pixels (q3 compat) { //make sure it does actually have those alpha pixels (q3 compat)
int i; int i;
flags |= IF_NOALPHA; flags |= IF_NOALPHA;
for (i = 3; i < width*height*4; i+=4) for (i = 3; i < width*height*4; i+=4)
{
if (((unsigned char*)data)[i] < 255)
{ {
flags &= ~IF_NOALPHA; if (((unsigned char*)data)[i] < 255)
break; {
flags &= ~IF_NOALPHA;
break;
}
} }
} }
} }
@ -1182,14 +1221,25 @@ void GL_Upload32_Int (char *name, unsigned *data, int width, int height, unsigne
TRACE(("dbg: GL_Upload32: %i %i\n", scaled_width, scaled_height)); TRACE(("dbg: GL_Upload32: %i %i\n", scaled_width, scaled_height));
if (scaled_width * scaled_height*4 > sizeofuploadmemorybuffer) if (!data)
scaled = NULL;
else
{ {
sizeofuploadmemorybuffer = scaled_width * scaled_height * 4; if (scaled_width * scaled_height*4 > sizeofuploadmemorybuffer)
uploadmemorybuffer = BZ_Realloc(uploadmemorybuffer, sizeofuploadmemorybuffer); {
sizeofuploadmemorybuffer = scaled_width * scaled_height * 4;
uploadmemorybuffer = BZ_Realloc(uploadmemorybuffer, sizeofuploadmemorybuffer);
}
scaled = (unsigned *)uploadmemorybuffer;
} }
scaled = (unsigned *)uploadmemorybuffer;
if (gl_config.gles) if (glcolormode == GL_DEPTH_COMPONENT || glcolormode == GL_DEPTH_COMPONENT16_ARB || glcolormode == GL_DEPTH_COMPONENT24_ARB || glcolormode == GL_DEPTH_COMPONENT32_ARB)
{
samples = glcolormode;
glcolormode = GL_DEPTH_COMPONENT;
type = GL_UNSIGNED_BYTE;
}
else if (gl_config.gles)
{ {
glcolormode = GL_RGBA; /*our input is RGBA or RGBX, with the internal format restriction, we must therefore always have an alpha value*/ glcolormode = GL_RGBA; /*our input is RGBA or RGBX, with the internal format restriction, we must therefore always have an alpha value*/
type = GL_UNSIGNED_BYTE; type = GL_UNSIGNED_BYTE;
@ -1266,7 +1316,9 @@ void GL_Upload32_Int (char *name, unsigned *data, int width, int height, unsigne
GL_Texturemode_Apply(targ, flags); GL_Texturemode_Apply(targ, flags);
if (scaled_width == width && scaled_height == height) if (!data)
qglTexImage2D (targface, 0, samples, scaled_width, scaled_height, 0, glcolormode, GL_UNSIGNED_BYTE, data);
else if (scaled_width == width && scaled_height == height)
{ {
if ((flags&IF_NOMIPMAP)||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... :)
{ {

View file

@ -218,6 +218,7 @@ typedef struct font_s
ftfontface_t *face[MAX_FTFACES]; ftfontface_t *face[MAX_FTFACES];
#endif #endif
struct font_s *alt; struct font_s *alt;
vec3_t tint;
vec3_t alttint; vec3_t alttint;
} font_t; } font_t;
@ -1058,7 +1059,18 @@ struct font_s *Font_LoadFont(int vheight, char *fontfilename)
int i = 0; int i = 0;
int defaultplane; int defaultplane;
char *aname; char *aname;
char *parms;
int height = (vheight * vid.rotpixelheight)/vid.height; int height = (vheight * vid.rotpixelheight)/vid.height;
char facename[MAX_QPATH];
Q_strncpy(facename, fontfilename, sizeof(facename));
aname = strstr(facename, ":");
if (aname)
*aname++ = 0;
parms = strstr(facename, "?");
if (parms)
*parms++ = 0;
f = Z_Malloc(sizeof(*f)); f = Z_Malloc(sizeof(*f));
f->charheight = height; f->charheight = height;
@ -1073,6 +1085,35 @@ struct font_s *Font_LoadFont(int vheight, char *fontfilename)
VectorSet(f->alttint, 1.16, 0.54, 0.41); VectorSet(f->alttint, 1.16, 0.54, 0.41);
break; break;
} }
VectorSet(f->tint, 1, 1, 1);
fontfilename = facename;
if (parms)
{
while (*parms)
{
if (!strncmp(parms, "col=", 4))
{
char *t = parms+4;
f->tint[0] = strtod(t, &t);
if (*t == ',') t++;
if (*t == ' ') t++;
f->tint[1] = strtod(t, &t);
if (*t == ',') t++;
if (*t == ' ') t++;
f->tint[2] = strtod(t, &t);
parms = t;
}
while(*parms && *parms != '&')
parms++;
if (*parms == '&')
{
parms++;
continue;
}
}
}
#ifdef DOOMWADS #ifdef DOOMWADS
if (!*fontfilename) if (!*fontfilename)
@ -1195,21 +1236,28 @@ struct font_s *Font_LoadFont(int vheight, char *fontfilename)
return f; return f;
} }
aname = strstr(fontfilename, ":");
if (aname) if (aname)
{ {
*aname = 0; if (!strncmp(aname, "?col=", 5))
if (!strncmp(aname+1, "?col=", 5))
{ {
char *t = aname+6; char *t = aname+5;
f->alttint[0] = strtod(t, &t); f->alttint[0] = strtod(t, &t);
if (*t == ',') t++;
if (*t == ' ') t++; if (*t == ' ') t++;
f->alttint[1] = strtod(t, &t); f->alttint[1] = strtod(t, &t);
if (*t == ',') t++;
if (*t == ' ') t++; if (*t == ' ') t++;
f->alttint[2] = strtod(t, &t); f->alttint[2] = strtod(t, &t);
} }
else else
f->alt = Font_LoadFont(vheight, aname+1); {
f->alt = Font_LoadFont(vheight, aname);
if (f->alt)
{
VectorCopy(f->alt->tint, f->alttint);
VectorCopy(f->alt->tint, f->alt->alttint);
}
}
} }
{ {
@ -1258,8 +1306,6 @@ struct font_s *Font_LoadFont(int vheight, char *fontfilename)
f->chars[i].texplane = BITMAPPLANE; f->chars[i].texplane = BITMAPPLANE;
} }
} }
if (aname)
*aname = ':';
defaultplane = BITMAPPLANE;/*assume the bitmap plane - don't use the fallback as people don't think to use com_parseutf8*/ defaultplane = BITMAPPLANE;/*assume the bitmap plane - don't use the fallback as people don't think to use com_parseutf8*/
if (!TEXVALID(f->singletexture)) if (!TEXVALID(f->singletexture))
@ -1359,6 +1405,7 @@ void Font_BeginString(struct font_s *font, float vx, float vy, int *px, int *py)
curfont_scale[0] = curfont->charheight; curfont_scale[0] = curfont->charheight;
curfont_scale[1] = curfont->charheight; curfont_scale[1] = curfont->charheight;
curfont_scaled = false; curfont_scaled = false;
font_colourmask = ~0u; //force the colour to be recalculated.
} }
void Font_Transform(float vx, float vy, int *px, int *py) void Font_Transform(float vx, float vy, int *px, int *py)
{ {
@ -1385,6 +1432,7 @@ void Font_BeginScaledString(struct font_s *font, float vx, float vy, float szx,
curfont_scale[0] = (szx * (float)vid.rotpixelheight) / (curfont->charheight * (float)vid.height); curfont_scale[0] = (szx * (float)vid.rotpixelheight) / (curfont->charheight * (float)vid.height);
curfont_scale[1] = (szy * (float)vid.rotpixelheight) / (curfont->charheight * (float)vid.height); curfont_scale[1] = (szy * (float)vid.rotpixelheight) / (curfont->charheight * (float)vid.height);
font_colourmask = ~0u; //force the colour to be recalculated.
} }
void Font_EndString(struct font_s *font) void Font_EndString(struct font_s *font)
@ -1601,7 +1649,7 @@ int Font_DrawChar(int px, int py, unsigned int charcode)
if (font->alt) if (font->alt)
{ {
font = font->alt; font = font->alt;
charcode &= ~CON_2NDCHARSETTEXT; // charcode &= ~CON_2NDCHARSETTEXT;
} }
else if ((charcode&CON_CHARMASK) >= 0xe000 && (charcode&CON_CHARMASK) <= 0xe0ff) else if ((charcode&CON_CHARMASK) >= 0xe000 && (charcode&CON_CHARMASK) <= 0xe0ff)
charcode &= ~CON_2NDCHARSETTEXT; //don't double-dip charcode &= ~CON_2NDCHARSETTEXT; //don't double-dip
@ -1680,6 +1728,12 @@ int Font_DrawChar(int px, int py, unsigned int charcode)
font_forecolour[1] = min(font_forecolour[1]*font->alttint[1], 255); font_forecolour[1] = min(font_forecolour[1]*font->alttint[1], 255);
font_forecolour[2] = min(font_forecolour[2]*font->alttint[2], 255); font_forecolour[2] = min(font_forecolour[2]*font->alttint[2], 255);
} }
else
{
font_forecolour[0] = min(font_forecolour[0]*font->tint[0], 255);
font_forecolour[1] = min(font_forecolour[1]*font->tint[1], 255);
font_forecolour[2] = min(font_forecolour[2]*font->tint[2], 255);
}
} }
} }
@ -1856,6 +1910,12 @@ float Font_DrawScaleChar(float px, float py, unsigned int charcode)
font_forecolour[1] = min(font_forecolour[1]*font->alttint[1], 255); font_forecolour[1] = min(font_forecolour[1]*font->alttint[1], 255);
font_forecolour[2] = min(font_forecolour[2]*font->alttint[2], 255); font_forecolour[2] = min(font_forecolour[2]*font->alttint[2], 255);
} }
else
{
font_forecolour[0] = min(font_forecolour[0]*font->tint[0], 255);
font_forecolour[1] = min(font_forecolour[1]*font->tint[1], 255);
font_forecolour[2] = min(font_forecolour[2]*font->tint[2], 255);
}
} }
} }

View file

@ -163,7 +163,7 @@ struct hmwater_s
{ {
struct hmwater_s *next; struct hmwater_s *next;
unsigned int contentmask; unsigned int contentmask;
qboolean simple; qboolean simple; //no holes, one height
float minheight; float minheight;
float maxheight; float maxheight;
shader_t *shader; shader_t *shader;
@ -555,6 +555,7 @@ static void *Terr_GenerateWater(hmsection_t *s, float maxheight)
w->shader = R_RegisterCustom (s->hmmod->watershadername, SUF_NONE, Shader_DefaultWaterShader, NULL); w->shader = R_RegisterCustom (s->hmmod->watershadername, SUF_NONE, Shader_DefaultWaterShader, NULL);
#endif #endif
w->simple = true; w->simple = true;
w->contentmask = FTECONTENTS_WATER;
memset(w->holes, 0, sizeof(w->holes)); memset(w->holes, 0, sizeof(w->holes));
for (i = 0; i < 9*9; i++) for (i = 0; i < 9*9; i++)
w->heights[i] = maxheight; w->heights[i] = maxheight;
@ -754,7 +755,7 @@ static void Terr_TrimWater(hmsection_t *s)
int i; int i;
struct hmwater_s *w, **link; struct hmwater_s *w, **link;
for (link = &s->water; (w = *link); link = &(*link)->next) for (link = &s->water; (w = *link); )
{ {
//one has a height above the terrain? //one has a height above the terrain?
for (i = 0; i < 9*9; i++) for (i = 0; i < 9*9; i++)
@ -766,6 +767,8 @@ static void Terr_TrimWater(hmsection_t *s)
Z_Free(w); Z_Free(w);
continue; continue;
} }
else
link = &(*link)->next;
} }
} }
static void Terr_SaveV2(heightmap_t *hm, hmsection_t *s, vfsfile_t *f, int sx, int sy) static void Terr_SaveV2(heightmap_t *hm, hmsection_t *s, vfsfile_t *f, int sx, int sy)
@ -831,7 +834,7 @@ static void Terr_SaveV2(heightmap_t *hm, hmsection_t *s, vfsfile_t *f, int sx, i
for (j = 0, w = s->water; w; j++) for (j = 0, w = s->water; w; j++)
w = w->next; w = w->next;
Terr_Write_SInt(&strm, j); Terr_Write_SInt(&strm, j);
for (i = 0; i < j; i++) for (i = 0, w = s->water; i < j; i++, w = w->next)
{ {
char *shadername = w->shader->name; char *shadername = w->shader->name;
int fl = 0; int fl = 0;
@ -917,9 +920,6 @@ static void Terr_SaveV2(heightmap_t *hm, hmsection_t *s, vfsfile_t *f, int sx, i
for (i = 0; i < s->numents; i++) for (i = 0; i < s->numents; i++)
{ {
unsigned int mf; unsigned int mf;
mf = 0;
if (s->ents[i].scale != 1)
mf |= TMF_SCALE;
//make sure we don't overflow. we should always be aligned at this point. //make sure we don't overflow. we should always be aligned at this point.
if (strm.pos > strm.maxsize/2) if (strm.pos > strm.maxsize/2)
@ -928,6 +928,10 @@ static void Terr_SaveV2(heightmap_t *hm, hmsection_t *s, vfsfile_t *f, int sx, i
strm.pos = 0; strm.pos = 0;
} }
mf = 0;
if (s->ents[i].scale != 1)
mf |= TMF_SCALE;
Terr_Write_SInt(&strm, mf);
if (s->ents[i].model) if (s->ents[i].model)
Terr_Write_String(&strm, s->ents[i].model->name); Terr_Write_String(&strm, s->ents[i].model->name);
else else
@ -996,6 +1000,7 @@ static void *Terr_ReadV2(heightmap_t *hm, hmsection_t *s, void *ptr, int len)
int fl = Terr_Read_SInt(&strm); int fl = Terr_Read_SInt(&strm);
w->next = s->water; w->next = s->water;
s->water = w; s->water = w;
w->simple = true;
w->contentmask = Terr_Read_SInt(&strm); w->contentmask = Terr_Read_SInt(&strm);
if (fl & 1) if (fl & 1)
Terr_Read_String(&strm, shadername, sizeof(shadername)); Terr_Read_String(&strm, shadername, sizeof(shadername));
@ -1009,6 +1014,7 @@ static void *Terr_ReadV2(heightmap_t *hm, hmsection_t *s, void *ptr, int len)
{ {
for (x = 0; x < 8; x++) for (x = 0; x < 8; x++)
w->holes[i] = Terr_Read_Byte(&strm); w->holes[i] = Terr_Read_Byte(&strm);
w->simple = false;
} }
if (fl & 4) if (fl & 4)
{ {
@ -1016,6 +1022,7 @@ static void *Terr_ReadV2(heightmap_t *hm, hmsection_t *s, void *ptr, int len)
{ {
w->heights[x] = Terr_Read_Float(&strm); w->heights[x] = Terr_Read_Float(&strm);
} }
w->simple = false;
} }
else else
{ //all heights the same can be used as a way to compress the data { //all heights the same can be used as a way to compress the data
@ -1071,7 +1078,7 @@ static void *Terr_ReadV2(heightmap_t *hm, hmsection_t *s, void *ptr, int len)
for (x = 0; x < SECTTEXSIZE; x++) for (x = 0; x < SECTTEXSIZE; x++)
{ {
delta = Terr_Read_Byte(&strm); delta = Terr_Read_Byte(&strm);
last += delta; last = (last+delta)&0xff;
lm[x*4+j] = last; lm[x*4+j] = last;
} }
lm += (HMLMSTRIDE)*lightmap_bytes; lm += (HMLMSTRIDE)*lightmap_bytes;
@ -1146,6 +1153,9 @@ static void *Terr_ReadV2(heightmap_t *hm, hmsection_t *s, void *ptr, int len)
return ptr; return ptr;
} }
//#include "gl_adt.inc"
//#include "gl_m2.inc"
static void Terr_GenerateDefault(heightmap_t *hm, hmsection_t *s) static void Terr_GenerateDefault(heightmap_t *hm, hmsection_t *s)
{ {
int i; int i;
@ -1195,7 +1205,7 @@ static void Terr_GenerateDefault(heightmap_t *hm, hmsection_t *s)
#if 0//def DEBUG #if 0//def DEBUG
void *f; void *f;
if (lightmap_bytes == 4 && lightmap_bgra && FS_LoadFile(va("maps/%s/splatt.png", hm->path), &f) >= 0) if (lightmap_bytes == 4 && lightmap_bgra && FS_LoadFile(va("maps/%s/splatt.png", hm->path), &f) != (qofs_t)-1)
{ {
//temp //temp
int vx, vy; int vx, vy;
@ -1239,7 +1249,7 @@ static void Terr_GenerateDefault(heightmap_t *hm, hmsection_t *s)
FS_FreeFile(f); FS_FreeFile(f);
} }
if (lightmap_bytes == 4 && lightmap_bgra && FS_LoadFile(va("maps/%s/heightmap.png", hm->path), &f) >= 0) if (lightmap_bytes == 4 && lightmap_bgra && !qofs_Error(FS_LoadFile(va("maps/%s/heightmap.png", hm->path), &f)))
{ {
//temp //temp
int vx, vy; int vx, vy;
@ -1278,7 +1288,6 @@ static void Terr_GenerateDefault(heightmap_t *hm, hmsection_t *s)
} }
#endif #endif
} }
static hmsection_t *Terr_ReadSection(heightmap_t *hm, int ver, int sx, int sy, void *filebase, unsigned int filelen) static hmsection_t *Terr_ReadSection(heightmap_t *hm, int ver, int sx, int sy, void *filebase, unsigned int filelen)
{ {
void *ptr = filebase; void *ptr = filebase;
@ -1322,7 +1331,7 @@ static hmsection_t *Terr_ReadSection(heightmap_t *hm, int ver, int sx, int sy, v
#ifndef SERVERONLY #ifndef SERVERONLY
qboolean Terr_DownloadedSection(char *fname) qboolean Terr_DownloadedSection(char *fname)
{ {
int len; qofs_t len;
dsection_t *fileptr; dsection_t *fileptr;
int x, y; int x, y;
heightmap_t *hm; heightmap_t *hm;
@ -1336,9 +1345,9 @@ qboolean Terr_DownloadedSection(char *fname)
if (Terr_IsSectionFName(hm, fname, &x, &y)) if (Terr_IsSectionFName(hm, fname, &x, &y))
{ {
fileptr = NULL; fileptr = NULL;
len = FS_LoadFile(fname, &fileptr); len = FS_LoadFile(fname, (void**)&fileptr);
if (len >= sizeof(*fileptr) && fileptr->magic == SECTION_MAGIC) if (!qofs_Error(len) && len >= sizeof(*fileptr) && fileptr->magic == SECTION_MAGIC)
Terr_ReadSection(hm, ver, x, y, fileptr+1, len - sizeof(*fileptr)); Terr_ReadSection(hm, ver, x, y, fileptr+1, len - sizeof(*fileptr));
else else
Terr_ReadSection(hm, ver, x, y, NULL, 0); Terr_ReadSection(hm, ver, x, y, NULL, 0);
@ -1355,7 +1364,7 @@ qboolean Terr_DownloadedSection(char *fname)
static void Terr_LoadSection(heightmap_t *hm, hmsection_t *s, int sx, int sy, unsigned int flags) static void Terr_LoadSection(heightmap_t *hm, hmsection_t *s, int sx, int sy, unsigned int flags)
{ {
void *diskimage; void *diskimage;
int len; qofs_t len;
int ver = 0; int ver = 0;
#ifndef SERVERONLY #ifndef SERVERONLY
//when using networked terrain, the client will never load a section from disk, but will only load it from the server //when using networked terrain, the client will never load a section from disk, but will only load it from the server
@ -1373,7 +1382,7 @@ static void Terr_LoadSection(heightmap_t *hm, hmsection_t *s, int sx, int sy, un
#if SECTIONSPERBLOCK > 1 #if SECTIONSPERBLOCK > 1
len = FS_LoadFile(Terr_DiskBlockName(hm, sx, sy), (void**)&diskimage); len = FS_LoadFile(Terr_DiskBlockName(hm, sx, sy), (void**)&diskimage);
if (len >= 0) if (!qofs_Error(len))
{ {
int offset; int offset;
int x, y; int x, y;
@ -1416,7 +1425,7 @@ static void Terr_LoadSection(heightmap_t *hm, hmsection_t *s, int sx, int sy, un
//legacy one-section-per-file format. //legacy one-section-per-file format.
len = FS_LoadFile(Terr_DiskSectionName(hm, sx, sy), (void**)&diskimage); len = FS_LoadFile(Terr_DiskSectionName(hm, sx, sy), (void**)&diskimage);
if (len >= 0) if (!qofs_Error(len))
{ {
dsection_t *h = diskimage; dsection_t *h = diskimage;
if (len >= sizeof(*h) && h->magic == SECTION_MAGIC) if (len >= sizeof(*h) && h->magic == SECTION_MAGIC)
@ -1439,7 +1448,7 @@ static void Terr_LoadSection(heightmap_t *hm, hmsection_t *s, int sx, int sy, un
//download it if it couldn't be loaded. //download it if it couldn't be loaded.
#ifndef SERVERONLY #ifndef SERVERONLY
if (!cl.downloadlist) if (!cl.downloadlist && !(flags & TGS_NODOWNLOAD))
CL_CheckOrEnqueDownloadFile(Terr_DiskSectionName(hm, sx, sy), NULL, 0); CL_CheckOrEnqueDownloadFile(Terr_DiskSectionName(hm, sx, sy), NULL, 0);
#endif #endif
} }
@ -2013,7 +2022,7 @@ void Terr_DrawTerrainWater(heightmap_t *hm, float *mins, float *maxs, struct hmw
{ {
cl_strisvertv[cl_numstrisvert][0] = mins[0] + step*x; cl_strisvertv[cl_numstrisvert][0] = mins[0] + step*x;
cl_strisvertv[cl_numstrisvert][1] = mins[1] + step*y; cl_strisvertv[cl_numstrisvert][1] = mins[1] + step*y;
cl_strisvertv[cl_numstrisvert][2] = w->heights[x + y*8]; cl_strisvertv[cl_numstrisvert][2] = w->heights[x + y*9];
cl_strisvertt[cl_numstrisvert][0] = cl_strisvertv[cl_numstrisvert][0]/64; cl_strisvertt[cl_numstrisvert][0] = cl_strisvertv[cl_numstrisvert][0]/64;
cl_strisvertt[cl_numstrisvert][1] = cl_strisvertv[cl_numstrisvert][1]/64; cl_strisvertt[cl_numstrisvert][1] = cl_strisvertv[cl_numstrisvert][1]/64;
Vector4Set(cl_strisvertc[cl_numstrisvert], 1,1,1,1) Vector4Set(cl_strisvertc[cl_numstrisvert], 1,1,1,1)
@ -2116,6 +2125,7 @@ static void Terr_RebuildMesh(model_t *model, hmsection_t *s, int x, int y)
switch(hm->mode) switch(hm->mode)
{ {
case HMM_BLOCKS: case HMM_BLOCKS:
//tiles, like dungeon keeper
if (mesh->xyz_array) if (mesh->xyz_array)
BZ_Free(mesh->xyz_array); BZ_Free(mesh->xyz_array);
{ {
@ -2314,6 +2324,7 @@ static void Terr_RebuildMesh(model_t *model, hmsection_t *s, int x, int y)
} }
break; break;
case HMM_TERRAIN: case HMM_TERRAIN:
//smooth terrain
if (!mesh->xyz_array) if (!mesh->xyz_array)
{ {
mesh->xyz_array = BZ_Malloc((sizeof(vecV_t)+sizeof(vec2_t)+sizeof(vec2_t)) * (SECTHEIGHTSIZE)*(SECTHEIGHTSIZE)); mesh->xyz_array = BZ_Malloc((sizeof(vecV_t)+sizeof(vec2_t)+sizeof(vec2_t)) * (SECTHEIGHTSIZE)*(SECTHEIGHTSIZE));
@ -3452,19 +3463,37 @@ qboolean Heightmap_Trace(struct model_s *model, int hulloverride, int frame, vec
return trace->fraction < 1; return trace->fraction < 1;
} }
typedef struct
{
int id;
int x, y;
} hmpvs_t;
unsigned int Heightmap_FatPVS (model_t *mod, vec3_t org, qbyte *pvsbuffer, unsigned int pvssize, qboolean add) unsigned int Heightmap_FatPVS (model_t *mod, vec3_t org, qbyte *pvsbuffer, unsigned int pvssize, qboolean add)
{ {
return 0; //embed the org onto the pvs
hmpvs_t *hmpvs = (hmpvs_t*)pvsbuffer;
hmpvs->id = 0xdeadbeef;
hmpvs->x = org[0];
hmpvs->y = org[1];
return sizeof(*hmpvs);
} }
#ifndef CLIENTONLY #ifndef CLIENTONLY
qboolean Heightmap_EdictInFatPVS (model_t *mod, struct pvscache_s *edict, qbyte *pvsdata) qboolean Heightmap_EdictInFatPVS (model_t *mod, struct pvscache_s *edict, qbyte *pvsdata)
{ {
return true; int x,y;
hmpvs_t *hmpvs = (hmpvs_t*)pvsdata;
//check distance
x = edict->areanum - hmpvs->x;
y = edict->areanum2 - hmpvs->y;
return (x*x+y*y) < 4096*4096;
} }
void Heightmap_FindTouchedLeafs (model_t *mod, pvscache_t *ent, float *mins, float *maxs) void Heightmap_FindTouchedLeafs (model_t *mod, pvscache_t *ent, float *mins, float *maxs)
{ {
ent->areanum = (mins[0] + maxs[0]) * 0.5;
ent->areanum2 = (mins[1] + maxs[1]) * 0.5;
} }
#endif #endif

View file

@ -4816,7 +4816,7 @@ typedef struct {
short xpos; short xpos;
short ypos; short ypos;
} doomimage_t; } doomimage_t;
static int QDECL FindDoomSprites(const char *name, int size, void *param, searchpathfuncs_t *spath) static int QDECL FindDoomSprites(const char *name, qofs_t size, void *param, searchpathfuncs_t *spath)
{ {
if (*(int *)param + strlen(name)+1 > 16000) if (*(int *)param + strlen(name)+1 > 16000)
Sys_Error("Too many doom sprites\n"); Sys_Error("Too many doom sprites\n");

View file

@ -37,17 +37,11 @@ extern int gl_stencilbits;
FTEPFNGLCOMPRESSEDTEXIMAGE2DARBPROC qglCompressedTexImage2DARB; FTEPFNGLCOMPRESSEDTEXIMAGE2DARBPROC qglCompressedTexImage2DARB;
FTEPFNGLGETCOMPRESSEDTEXIMAGEARBPROC qglGetCompressedTexImageARB; FTEPFNGLGETCOMPRESSEDTEXIMAGEARBPROC qglGetCompressedTexImageARB;
vec3_t modelorg, r_entorigin;
extern int r_visframecount; // bumped when going to a new PVS extern int r_visframecount; // bumped when going to a new PVS
extern int r_framecount; // used for dlight push checking extern int r_framecount; // used for dlight push checking
float r_wateralphaval; //allowed or not...
//mplane_t frustum[4]; //mplane_t frustum[4];
int c_brush_polys, c_alias_polys;
// //
// view origin // view origin
// //
@ -100,6 +94,8 @@ texid_t scenepp_texture_edge;
texid_t scenepp_postproc_cube; texid_t scenepp_postproc_cube;
int scenepp_postproc_cube_size; int scenepp_postproc_cube_size;
fbostate_t fbo_gameview;
// KrimZon - init post processing - called in GL_CheckExtensions, when they're called // KrimZon - init post processing - called in GL_CheckExtensions, when they're called
// I put it here so that only this file need be changed when messing with the post // I put it here so that only this file need be changed when messing with the post
// processing shaders // processing shaders
@ -381,40 +377,60 @@ void R_SetupGL (float stereooffset)
// //
// set up viewpoint // set up viewpoint
// //
x = r_refdef.vrect.x * (int)vid.pixelwidth/(int)vid.width; if (r_refdef.rt_destcolour)
x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * (int)vid.pixelwidth/(int)vid.width; {
y = (r_refdef.vrect.y) * (int)vid.pixelheight/(int)vid.height; //with fbo rendering, we disable all virtual scaling.
y2 = (r_refdef.vrect.y + r_refdef.vrect.height) * (int)vid.pixelheight/(int)vid.height; x = r_refdef.vrect.x;
x2 = r_refdef.vrect.x + r_refdef.vrect.width;
y = r_refdef.vrect.y;
y2 = r_refdef.vrect.y + r_refdef.vrect.height;
// fudge around because of frac screen scale w = x2 - x;
if (x > 0) h = y2 - y;
x--;
if (x2 < vid.pixelwidth)
x2++;
if (y2 < vid.pixelheight)
y2++;
if (y > 0)
y--;
w = x2 - x; r_refdef.pxrect.x = x;
h = y2 - y; r_refdef.pxrect.y = y;
r_refdef.pxrect.width = w;
r_refdef.pxrect.height = h;
r_refdef.pxrect.maxheight = vid.fbpheight;
}
else
{
x = r_refdef.vrect.x * (int)vid.pixelwidth/(int)vid.width;
x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * (int)vid.pixelwidth/(int)vid.width;
y = (r_refdef.vrect.y) * (int)vid.pixelheight/(int)vid.height;
y2 = (r_refdef.vrect.y + r_refdef.vrect.height) * (int)vid.pixelheight/(int)vid.height;
// fudge around because of frac screen scale
if (x > 0)
x--;
if (x2 < vid.pixelwidth)
x2++;
if (y2 < vid.pixelheight)
y2++;
if (y > 0)
y--;
w = x2 - x;
h = y2 - y;
if (stereooffset && r_stereo_method.ival == 5)
{
w /= 2;
if (stereooffset > 0)
x += vid.pixelwidth/2;
}
r_refdef.pxrect.x = x;
r_refdef.pxrect.y = y;
r_refdef.pxrect.width = w;
r_refdef.pxrect.height = h;
r_refdef.pxrect.maxheight = vid.pixelheight;
}
fov_x = r_refdef.fov_x;//+sin(cl.time)*5; fov_x = r_refdef.fov_x;//+sin(cl.time)*5;
fov_y = r_refdef.fov_y;//-sin(cl.time+1)*5; fov_y = r_refdef.fov_y;//-sin(cl.time+1)*5;
if (stereooffset && r_stereo_method.ival == 5)
{
w /= 2;
if (stereooffset > 0)
x += vid.pixelwidth/2;
}
r_refdef.pxrect.x = x;
r_refdef.pxrect.y = y;
r_refdef.pxrect.width = w;
r_refdef.pxrect.height = h;
r_refdef.pxrect.maxheight = vid.pixelheight;
GL_ViewportUpdate(); GL_ViewportUpdate();
if (r_waterwarp.value<0 && (r_viewcontents & FTECONTENTS_FLUID)) if (r_waterwarp.value<0 && (r_viewcontents & FTECONTENTS_FLUID))
@ -969,6 +985,7 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2],
qglClipPlane(GL_CLIP_PLANE0, glplane); qglClipPlane(GL_CLIP_PLANE0, glplane);
qglEnable(GL_CLIP_PLANE0); qglEnable(GL_CLIP_PLANE0);
}*/ }*/
//fixme: we can probably scissor a smaller frusum
R_SetFrustum (r_refdef.m_projection, vmat); R_SetFrustum (r_refdef.m_projection, vmat);
if (r_refdef.frustum_numplanes < MAXFRUSTUMPLANES) if (r_refdef.frustum_numplanes < MAXFRUSTUMPLANES)
{ {
@ -1101,7 +1118,7 @@ void R_Clear (void)
/*tbh, this entire function should be in the backend*/ /*tbh, this entire function should be in the backend*/
GL_ForceDepthWritable(); GL_ForceDepthWritable();
{ {
if (r_clear.ival && r_refdef.grect.x == 0 && r_refdef.grect.y == 0 && r_refdef.grect.width == vid.width && r_refdef.grect.height == vid.height && !(r_refdef.flags & Q2RDF_NOWORLDMODEL)) if (r_clear.ival && r_refdef.grect.x == 0 && r_refdef.grect.y == 0 && (unsigned)r_refdef.grect.width == vid.fbvwidth && (unsigned)r_refdef.grect.height == vid.fbvheight && !(r_refdef.flags & Q2RDF_NOWORLDMODEL))
{ {
qglClearColor(1, 0, 0, 0); qglClearColor(1, 0, 0, 0);
qglClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); qglClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -1208,10 +1225,12 @@ static void R_RenderMotionBlur(void)
"}\n" "}\n"
"}\n" "}\n"
); );
GLBE_RenderToTexture(sceneblur_texture, r_nulltex, r_nulltex, r_nulltex, false); // GLBE_RenderToTexture(sceneblur_texture, r_nulltex, r_nulltex, r_nulltex, false);
Con_Printf("FIXME: tex_sourcecolour = sceneblur_texture\n");
R2D_ImageColours(1, 1, 1, gl_motionblur.value); R2D_ImageColours(1, 1, 1, gl_motionblur.value);
R2D_Image(0, 0, vid.width, vid.height, cs-vs, ct+vt, cs+vs, ct-vt, shader); R2D_Image(0, 0, vid.width, vid.height, cs-vs, ct+vt, cs+vs, ct-vt, shader);
GLBE_RenderToTexture(r_nulltex, r_nulltex, r_nulltex, r_nulltex, false); Con_Printf("FIXME: tex_sourcecolour = reset\n");
// GLBE_RenderToTexture(r_nulltex, r_nulltex, r_nulltex, r_nulltex, false);
//grab the current image so we can feed that back into the next frame. //grab the current image so we can feed that back into the next frame.
GL_MTBind(0, GL_TEXTURE_2D, sceneblur_texture); GL_MTBind(0, GL_TEXTURE_2D, sceneblur_texture);
@ -1402,21 +1421,22 @@ r_refdef must be set before the first call
*/ */
void GLR_RenderView (void) void GLR_RenderView (void)
{ {
int oldfbo = 0;
int dofbo = r_refdef.rt_destcolour || r_refdef.rt_depth;
double time1 = 0, time2; double time1 = 0, time2;
checkglerror(); checkglerror();
GL_DoSwap();
if (r_norefresh.value || !vid.pixelwidth || !vid.pixelheight) if (r_norefresh.value || !vid.pixelwidth || !vid.pixelheight)
{
GL_DoSwap();
return; return;
}
if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL)) if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL))
{
//FIXME: fbo stuff
if (!r_worldentity.model || r_worldentity.model->needload || !cl.worldmodel) if (!r_worldentity.model || r_worldentity.model->needload || !cl.worldmodel)
{ {
GL_DoSwap();
GL_Set2D (false); GL_Set2D (false);
R2D_ImageColours(0, 0, 0, 1); R2D_ImageColours(0, 0, 0, 1);
R2D_FillBlock(r_refdef.vrect.x, r_refdef.vrect.y, r_refdef.vrect.width, r_refdef.vrect.height); R2D_FillBlock(r_refdef.vrect.x, r_refdef.vrect.y, r_refdef.vrect.width, r_refdef.vrect.height);
@ -1424,8 +1444,52 @@ void GLR_RenderView (void)
return; return;
} }
// Sys_Error ("R_RenderView: NULL worldmodel"); // Sys_Error ("R_RenderView: NULL worldmodel");
}
BE_Scissor(NULL);
if (dofbo)
{
unsigned int flags = 0;
texid_t col = r_nulltex, depth = r_nulltex;
unsigned int cw=0, ch=0, dw=0, dh=0;
//3d views generally ignore source colour+depth.
//FIXME: support depth with no colour
if (r_refdef.rt_destcolour)
col = R2D_RT_GetTexture(r_refdef.rt_destcolour, &cw, &ch);
if (r_refdef.rt_depth)
depth = R2D_RT_GetTexture(r_refdef.rt_depth, &dw, &dh);
if (r_refdef.rt_destcolour)
{ //colour (with or without depth)
if (r_refdef.rt_depth && (dw != cw || dh != dh))
{
Con_Printf("RT: destcolour and depth render targets are of different sizes\n"); //should check rgb/depth modes too I guess.
depth = r_nulltex;
}
vid.fbvwidth = vid.fbpwidth = cw;
vid.fbvheight = vid.fbpheight = ch;
}
else
{ //depth, with no colour
vid.fbvwidth = vid.fbpwidth = dw;
vid.fbvheight = vid.fbpheight = dh;
}
if (TEXVALID(col))
flags |= FBO_TEX_COLOUR;
if (TEXVALID(depth))
flags |= FBO_TEX_DEPTH;
else
flags |= FBO_RB_DEPTH;
oldfbo = GLBE_FBO_Update(&fbo_gameview, true, flags, col, depth, vid.fbpwidth, vid.fbpheight);
//oldfbo will probably be the 2d fbo
}
else
{
vid.fbvwidth = vid.width;
vid.fbvheight = vid.height;
vid.fbpwidth = vid.pixelwidth;
vid.fbpheight = vid.pixelheight;
}
if (qglPNTrianglesiATI) if (qglPNTrianglesiATI)
{ {
@ -1452,11 +1516,9 @@ void GLR_RenderView (void)
if (r_speeds.ival) if (r_speeds.ival)
{ {
time1 = Sys_DoubleTime (); time1 = Sys_DoubleTime ();
c_brush_polys = 0;
c_alias_polys = 0;
} }
if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL) && R_RenderScene_Cubemap()) if (!dofbo && !(r_refdef.flags & Q2RDF_NOWORLDMODEL) && R_RenderScene_Cubemap())
{ {
} }
@ -1481,16 +1543,23 @@ void GLR_RenderView (void)
RQuantAdd(RQUANT_MSECS, (int)((time2-time1)*1000000)); RQuantAdd(RQUANT_MSECS, (int)((time2-time1)*1000000));
RQuantAdd(RQUANT_WPOLYS, c_brush_polys);
RQuantAdd(RQUANT_EPOLYS, c_alias_polys);
// Con_Printf ("%3i ms %4i wpoly %4i epoly\n", (int)((time2-time1)*1000), c_brush_polys, c_alias_polys); // Con_Printf ("%3i ms %4i wpoly %4i epoly\n", (int)((time2-time1)*1000), c_brush_polys, c_alias_polys);
} }
checkglerror(); checkglerror();
GL_Set2D (false); //update stuff now that we're not rendering the 3d scene
if (dofbo)
GLBE_RenderToTextureUpdate2d(true);
else
{
GLBE_RenderToTextureUpdate2d(false);
GL_Set2D (false);
}
if ((r_refdef.flags & Q2RDF_NOWORLDMODEL) || r_secondaryview) //FIXME: support bloom+waterwarp even when drawing to an fbo?
//FIXME: force waterwarp to a temp fbo always
if ((r_refdef.flags & Q2RDF_NOWORLDMODEL) || r_secondaryview || dofbo)
return; return;
if (r_secondaryview) if (r_secondaryview)

View file

@ -353,16 +353,14 @@ void R_MakeTexWad_f(void)
if (buf) if (buf)
break; break;
} }
width = 16;
height = 16;
if (buf) if (buf)
data = Read32BitImageFile(buf, com_filesize, &width, &height, &hasalpha, imagename); data = Read32BitImageFile(buf, com_filesize, &width, &height, &hasalpha, imagename);
else else
data = NULL; data = NULL;
if (!data) if (!data)
{ data = Z_Malloc(width*height*4);
data = Z_Malloc(16*16*4);
width = 16;
height = 16;
}
dummymip.width = (int)(width/scale) & ~0xf; dummymip.width = (int)(width/scale) & ~0xf;
dummymip.height = (int)(height/scale) & ~0xf; dummymip.height = (int)(height/scale) & ~0xf;

View file

@ -3097,7 +3097,8 @@ static shaderkey_t shaderpasskeys[] =
{"maskalpha", Shaderpass_MaskAlpha}, {"maskalpha", Shaderpass_MaskAlpha},
{"alphatest", Shaderpass_AlphaTest}, {"alphatest", Shaderpass_AlphaTest},
{"texgen", Shaderpass_TexGen}, {"texgen", Shaderpass_TexGen},
{"cameracubemap",Shaderpass_CubeMap}, {"cubemap", Shaderpass_CubeMap}, //one of these is wrong
{"cameracubemap",Shaderpass_CubeMap}, //one of these is wrong
{"red", Shaderpass_Red}, {"red", Shaderpass_Red},
{"green", Shaderpass_Green}, {"green", Shaderpass_Green},
{"blue", Shaderpass_Blue}, {"blue", Shaderpass_Blue},
@ -3161,7 +3162,7 @@ void Shader_Free (shader_t *shader)
int QDECL Shader_InitCallback (const char *name, int size, void *param, searchpathfuncs_t *spath) int QDECL Shader_InitCallback (const char *name, qofs_t size, void *param, searchpathfuncs_t *spath)
{ {
strcpy(shaderbuf+shaderbuflen, name); strcpy(shaderbuf+shaderbuflen, name);
Shader_MakeCache(shaderbuf+shaderbuflen); Shader_MakeCache(shaderbuf+shaderbuflen);
@ -3311,6 +3312,7 @@ static void Shader_GetPathAndOffset(char *name, char **path, unsigned int *offse
void Shader_Reset(shader_t *s) void Shader_Reset(shader_t *s)
{ {
char name[MAX_QPATH]; char name[MAX_QPATH];
int id = s->id;
int uses = s->uses; int uses = s->uses;
shader_gen_t *defaultgen = s->generator; shader_gen_t *defaultgen = s->generator;
char *genargs = s->genargs; char *genargs = s->genargs;
@ -3323,6 +3325,7 @@ void Shader_Reset(shader_t *s)
Shader_Free(s); Shader_Free(s);
memset(s, 0, sizeof(*s)); memset(s, 0, sizeof(*s));
s->id = id;
s->width = w; s->width = w;
s->height = h; s->height = h;
s->defaulttextures = dt; s->defaulttextures = dt;
@ -4163,6 +4166,13 @@ void Shader_UpdateRegistration (void)
void R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader) void R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
{ {
char *h;
char imagename[MAX_QPATH];
strcpy(imagename, shader->name);
h = strchr(imagename, '#');
if (h)
*h = 0;
if (!tn) if (!tn)
tn = &shader->defaulttextures; tn = &shader->defaulttextures;
if (!TEXVALID(shader->defaulttextures.base)) if (!TEXVALID(shader->defaulttextures.base))
@ -4170,7 +4180,7 @@ void R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
/*dlights/realtime lighting needs some stuff*/ /*dlights/realtime lighting needs some stuff*/
if (!TEXVALID(tn->base)) if (!TEXVALID(tn->base))
{ {
tn->base = R_LoadHiResTexture(shader->name, NULL, IF_NOALPHA); tn->base = R_LoadHiResTexture(imagename, NULL, IF_NOALPHA);
} }
if (TEXVALID(tn->base)) if (TEXVALID(tn->base))
shader->flags &= ~SHADER_NOIMAGE; shader->flags &= ~SHADER_NOIMAGE;
@ -4178,16 +4188,18 @@ void R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
TEXASSIGN(shader->defaulttextures.base, tn->base); TEXASSIGN(shader->defaulttextures.base, tn->base);
} }
COM_StripExtension(imagename, imagename, sizeof(imagename));
if (!TEXVALID(shader->defaulttextures.bump)) if (!TEXVALID(shader->defaulttextures.bump))
{ {
if (r_loadbumpmapping) if (r_loadbumpmapping)
{ {
if (!TEXVALID(tn->bump)) if (!TEXVALID(tn->bump))
tn->bump = R_LoadHiResTexture(va("%s_norm", shader->name), NULL, IF_NOALPHA); tn->bump = R_LoadHiResTexture(va("%s_norm", imagename), NULL, IF_NOALPHA);
if (!TEXVALID(tn->bump)) if (!TEXVALID(tn->bump))
tn->bump = R_LoadHiResTexture(va("%s_bump", shader->name), NULL, IF_NOALPHA); tn->bump = R_LoadHiResTexture(va("%s_bump", imagename), NULL, IF_NOALPHA);
if (!TEXVALID(tn->bump)) if (!TEXVALID(tn->bump))
tn->bump = R_LoadHiResTexture(va("normalmaps/%s", shader->name), NULL, IF_NOALPHA); tn->bump = R_LoadHiResTexture(va("normalmaps/%s", imagename), NULL, IF_NOALPHA);
} }
TEXASSIGN(shader->defaulttextures.bump, tn->bump); TEXASSIGN(shader->defaulttextures.bump, tn->bump);
} }
@ -4197,7 +4209,7 @@ void R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
if (shader->flags & SHADER_HASTOPBOTTOM) if (shader->flags & SHADER_HASTOPBOTTOM)
{ {
if (!TEXVALID(tn->loweroverlay)) if (!TEXVALID(tn->loweroverlay))
tn->loweroverlay = R_LoadHiResTexture(va("%s_pants", shader->name), NULL, 0); /*how rude*/ tn->loweroverlay = R_LoadHiResTexture(va("%s_pants", imagename), NULL, 0); /*how rude*/
} }
TEXASSIGN(shader->defaulttextures.loweroverlay, tn->loweroverlay); TEXASSIGN(shader->defaulttextures.loweroverlay, tn->loweroverlay);
} }
@ -4207,7 +4219,7 @@ void R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
if (shader->flags & SHADER_HASTOPBOTTOM) if (shader->flags & SHADER_HASTOPBOTTOM)
{ {
if (!TEXVALID(tn->upperoverlay)) if (!TEXVALID(tn->upperoverlay))
tn->upperoverlay = R_LoadHiResTexture(va("%s_shirt", shader->name), NULL, 0); tn->upperoverlay = R_LoadHiResTexture(va("%s_shirt", imagename), NULL, 0);
} }
TEXASSIGN(shader->defaulttextures.upperoverlay, tn->upperoverlay); TEXASSIGN(shader->defaulttextures.upperoverlay, tn->upperoverlay);
} }
@ -4218,7 +4230,7 @@ void R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
if ((shader->flags & SHADER_HASGLOSS) && gl_specular.value && gl_load24bit.value) if ((shader->flags & SHADER_HASGLOSS) && gl_specular.value && gl_load24bit.value)
{ {
if (!TEXVALID(tn->specular)) if (!TEXVALID(tn->specular))
tn->specular = R_LoadHiResTexture(va("%s_gloss", shader->name), NULL, 0); tn->specular = R_LoadHiResTexture(va("%s_gloss", imagename), NULL, 0);
} }
TEXASSIGN(shader->defaulttextures.specular, tn->specular); TEXASSIGN(shader->defaulttextures.specular, tn->specular);
} }
@ -4436,7 +4448,7 @@ void Shader_DefaultCinematic(char *shortname, shader_t *s, const void *args)
"{\n" "{\n"
"program default2d\n" "program default2d\n"
"{\n" "{\n"
"videomap %s\n" "videomap \"%s\"\n"
"}\n" "}\n"
"}\n" "}\n"
, (const char*)args) , (const char*)args)
@ -5115,29 +5127,19 @@ void R_UnloadShader(shader_t *shader)
static shader_t *R_LoadShader (char *name, unsigned int usageflags, shader_gen_t *defaultgen, const char *genargs) static shader_t *R_LoadShader (char *name, unsigned int usageflags, shader_gen_t *defaultgen, const char *genargs)
{ {
int i, f = -1; int i, f = -1;
char cleanname[MAX_QPATH];
char shortname[MAX_QPATH]; char shortname[MAX_QPATH];
char *hash; char *argsstart;
shader_t *s; shader_t *s;
if (!*name) if (!*name)
name = "gfx/white"; name = "gfx/white";
hash = strchr(name, '#'); Q_strncpyz(cleanname, name, sizeof(cleanname));
if (hash) //don't strip anything. COM_CleanUpPath(cleanname);
{
Q_strncpyz(shortname, name, sizeof(shortname));
hash = shortname+(hash-name);
}
else
{
*(int*)shortname = 0;
COM_StripExtension ( name, shortname, sizeof(shortname));
}
COM_CleanUpPath(shortname);
// check the hash first // check the hash first
s = Hash_Get(&shader_active_hash, shortname); s = Hash_Get(&shader_active_hash, cleanname);
while (s) while (s)
{ {
//make sure the same texture can be used as either a lightmap or vertexlit shader //make sure the same texture can be used as either a lightmap or vertexlit shader
@ -5148,7 +5150,7 @@ static shader_t *R_LoadShader (char *name, unsigned int usageflags, shader_gen_t
s->uses++; s->uses++;
return s; return s;
} }
s = Hash_GetNext(&shader_active_hash, shortname, s); s = Hash_GetNext(&shader_active_hash, cleanname, s);
} }
// not loaded, find a free slot // not loaded, find a free slot
@ -5183,6 +5185,11 @@ static shader_t *R_LoadShader (char *name, unsigned int usageflags, shader_gen_t
r_maxshaders = nm; r_maxshaders = nm;
} }
} }
if (strlen(cleanname) >= sizeof(s->name))
{
Sys_Error( "R_LoadShader: Shader name too long.");
return NULL;
}
s = r_shaders[f]; s = r_shaders[f];
if (!s) if (!s)
@ -5191,7 +5198,7 @@ static shader_t *R_LoadShader (char *name, unsigned int usageflags, shader_gen_t
if (r_numshaders < f+1) if (r_numshaders < f+1)
r_numshaders = f+1; r_numshaders = f+1;
Q_strncpyz(s->name, shortname, sizeof(s->name)); Q_strncpyz(s->name, cleanname, sizeof(s->name));
s->usageflags = usageflags; s->usageflags = usageflags;
s->generator = defaultgen; s->generator = defaultgen;
if (genargs) if (genargs)
@ -5199,9 +5206,11 @@ static shader_t *R_LoadShader (char *name, unsigned int usageflags, shader_gen_t
else else
s->genargs = NULL; s->genargs = NULL;
//now strip off the hash so we find the right shader script //now determine the 'short name'. ie: the shader that is loaded off disk (no args, no extension)
if (hash) argsstart = strchr(cleanname, '#');
*hash = 0; if (argsstart)
*argsstart = 0;
COM_StripExtension (cleanname, shortname, sizeof(shortname));
if (ruleset_allow_shaders.ival) if (ruleset_allow_shaders.ival)
{ {
@ -5266,13 +5275,13 @@ static shader_t *R_LoadShader (char *name, unsigned int usageflags, shader_gen_t
Shader_Reset(s); Shader_Reset(s);
if (!strcmp(shortname, "textures/common/clip")) if (!strcmp(shortname, "textures/common/clip"))
Shader_DefaultScript(shortname, s, Shader_DefaultScript(cleanname, s,
"{\n" "{\n"
"surfaceparm nodraw\n" "surfaceparm nodraw\n"
"surfaceparm nodlight\n" "surfaceparm nodlight\n"
"}\n"); "}\n");
else else
s->generator(shortname, s, s->genargs); s->generator(cleanname, s, s->genargs);
return s; return s;
} }
else else

View file

@ -45,6 +45,7 @@ static int shadow_fbo_id;
static int shadow_fbo_depth_num; static int shadow_fbo_depth_num;
static int crepuscular_fbo_id; static int crepuscular_fbo_id;
texid_t crepuscular_texture_id; texid_t crepuscular_texture_id;
fbostate_t crepuscular_fbo;
shader_t *crepuscular_shader; shader_t *crepuscular_shader;
cvar_t r_shadow_shadowmapping_nearclip = CVAR("r_shadow_shadowmapping_nearclip", "1"); cvar_t r_shadow_shadowmapping_nearclip = CVAR("r_shadow_shadowmapping_nearclip", "1");
@ -2365,6 +2366,8 @@ qboolean Sh_GenShadowMap (dlight_t *l, qbyte *lvis, int smsize)
switch(qrenderer) switch(qrenderer)
{ {
default:
return false;
#ifdef GLQUAKE #ifdef GLQUAKE
case QR_OPENGL: case QR_OPENGL:
if (!TEXVALID(shadowmap[isspot])) if (!TEXVALID(shadowmap[isspot]))
@ -2458,6 +2461,8 @@ qboolean Sh_GenShadowMap (dlight_t *l, qbyte *lvis, int smsize)
switch(qrenderer) switch(qrenderer)
{ {
default:
break;
#ifdef GLQUAKE #ifdef GLQUAKE
case QR_OPENGL: case QR_OPENGL:
/*end framebuffer*/ /*end framebuffer*/
@ -3142,6 +3147,7 @@ void GLBE_SubmitMeshes (qboolean drawworld, int start, int stop);
void Sh_DrawCrepuscularLight(dlight_t *dl, float *colours) void Sh_DrawCrepuscularLight(dlight_t *dl, float *colours)
{ {
#ifdef GLQUAKE #ifdef GLQUAKE
int oldfbo;
static mesh_t mesh; static mesh_t mesh;
static vecV_t xyz[4] = static vecV_t xyz[4] =
{ {
@ -3209,19 +3215,19 @@ void Sh_DrawCrepuscularLight(dlight_t *dl, float *colours)
BE_Scissor(NULL); BE_Scissor(NULL);
GLBE_RenderToTexture(r_nulltex, r_nulltex, crepuscular_texture_id, r_nulltex, false); oldfbo = GLBE_FBO_Update(&crepuscular_fbo, true, FBO_TEX_COLOUR, crepuscular_texture_id, r_nulltex, vid.pixelwidth, vid.pixelheight);
BE_SelectMode(BEM_CREPUSCULAR); BE_SelectMode(BEM_CREPUSCULAR);
BE_SelectDLight(dl, colours, LSHADER_STANDARD); BE_SelectDLight(dl, colours, LSHADER_STANDARD);
GLBE_SubmitMeshes(true, SHADER_SORT_PORTAL, SHADER_SORT_BLEND); GLBE_SubmitMeshes(true, SHADER_SORT_PORTAL, SHADER_SORT_BLEND);
GLBE_RenderToTexture(crepuscular_texture_id, r_nulltex, r_nulltex, r_nulltex, false); GLBE_FBO_Pop(oldfbo);
Con_Printf("FIXME: shaderstate.tex_sourceocolour = crepuscular_texture_id\n");
BE_SelectMode(BEM_STANDARD); BE_SelectMode(BEM_STANDARD);
GLBE_DrawMesh_Single(crepuscular_shader, &mesh, NULL, &crepuscular_shader->defaulttextures, 0); GLBE_DrawMesh_Single(crepuscular_shader, &mesh, NULL, &crepuscular_shader->defaulttextures, 0);
Con_Printf("FIXME: shaderstate.tex_sourceocolour = reset\n");
GLBE_RenderToTexture(r_nulltex, r_nulltex, r_nulltex, r_nulltex, false);
#endif #endif
} }

View file

@ -1294,7 +1294,7 @@ qboolean GLSlang_GenerateIncludes(int maxstrings, int *strings, const GLchar *pr
} }
if (!glsl_hdrs[i]) if (!glsl_hdrs[i])
{ {
if (FS_LoadFile(incname, (void**)&inc) >= 0) if (FS_LoadFile(incname, (void**)&inc) != (qofs_t)-1)
{ {
if (!GLSlang_GenerateIncludes(maxstrings, strings, prstrings, length, inc)) if (!GLSlang_GenerateIncludes(maxstrings, strings, prstrings, length, inc))
{ {
@ -1745,6 +1745,9 @@ void GL_Init(void *(*getglfunction) (char *name))
qglBindBufferARB = GL_BindBufferARBStub; qglBindBufferARB = GL_BindBufferARBStub;
#endif #endif
if (!qglGetString)
Sys_Error("qglGetString not set. Serious gl library initialisation error\n");
gl_vendor = qglGetString (GL_VENDOR); gl_vendor = qglGetString (GL_VENDOR);
Con_SafePrintf ("GL_VENDOR: %s\n", gl_vendor); Con_SafePrintf ("GL_VENDOR: %s\n", gl_vendor);
gl_renderer = qglGetString (GL_RENDERER); gl_renderer = qglGetString (GL_RENDERER);

View file

@ -161,7 +161,7 @@ qboolean isPermedia = false;
// Note that 0 is MODE_WINDOWED // Note that 0 is MODE_WINDOWED
extern cvar_t vid_mode; extern cvar_t vid_mode;
// Note that 3 is MODE_FULLSCREEN_DEFAULT // Note that 3 is MODE_FULLSCREEN_DEFAULT
extern cvar_t _vid_wait_override; extern cvar_t vid_vsync;
extern cvar_t _windowed_mouse; extern cvar_t _windowed_mouse;
extern cvar_t vid_hardwaregamma; extern cvar_t vid_hardwaregamma;
extern cvar_t vid_desktopgamma; extern cvar_t vid_desktopgamma;
@ -170,7 +170,7 @@ extern cvar_t vid_preservegamma;
extern cvar_t vid_gl_context_version; extern cvar_t vid_gl_context_version;
extern cvar_t vid_gl_context_debug; extern cvar_t vid_gl_context_debug;
extern cvar_t vid_gl_context_es2; extern cvar_t vid_gl_context_es;
extern cvar_t vid_gl_context_forwardcompatible; extern cvar_t vid_gl_context_forwardcompatible;
extern cvar_t vid_gl_context_compatibility; extern cvar_t vid_gl_context_compatibility;
@ -184,6 +184,9 @@ static char reqminidriver[MAX_OSPATH];
static char opengldllname[MAX_OSPATH]; static char opengldllname[MAX_OSPATH];
#ifdef _DEBUG #ifdef _DEBUG
//this is a list of the functions that exist in opengles2, as well as wglCreateContextAttribsARB.
//functions not in this list *should* be stubs that just return errors, but we can't always depend on drivers for that... they shouldn't get called.
//this list is just to make it easier to test+debug android gles2 stuff using windows.
static char *gles2funcs[] = static char *gles2funcs[] =
{ {
#define f(n) #n, #define f(n) #n,
@ -350,7 +353,7 @@ void *getglfunc(char *name)
} }
#ifdef _DEBUG #ifdef _DEBUG
if (vid_gl_context_es2.ival == 2) if (vid_gl_context_es.ival == 2)
{ {
int i; int i;
for (i = 0; gles2funcs[i]; i++) for (i = 0; gles2funcs[i]; i++)
@ -1154,7 +1157,7 @@ qboolean VID_AttachGL (rendererstate_t *info)
char *ver; char *ver;
ver = vid_gl_context_version.string; ver = vid_gl_context_version.string;
if (!*ver && vid_gl_context_es2.ival) if (!*ver && vid_gl_context_es.ival)
ver = "2.0"; ver = "2.0";
mv = ver; mv = ver;
@ -1189,10 +1192,10 @@ qboolean VID_AttachGL (rendererstate_t *info)
} }
/*only switch contexts if there's actually a point*/ /*only switch contexts if there's actually a point*/
if (i || !vid_gl_context_compatibility.ival || vid_gl_context_es2.ival) if (i || !vid_gl_context_compatibility.ival || vid_gl_context_es.ival)
{ {
attribs[i+1] = 0; attribs[i+1] = 0;
if (vid_gl_context_es2.ival) if (vid_gl_context_es.ival)
attribs[i+1] |= WGL_CONTEXT_ES2_PROFILE_BIT_EXT; attribs[i+1] |= WGL_CONTEXT_ES2_PROFILE_BIT_EXT;
else if (vid_gl_context_compatibility.ival) else if (vid_gl_context_compatibility.ival)
attribs[i+1] |= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; attribs[i+1] |= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
@ -1200,7 +1203,7 @@ qboolean VID_AttachGL (rendererstate_t *info)
attribs[i+1] |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB; attribs[i+1] |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
attribs[i] = WGL_CONTEXT_PROFILE_MASK_ARB; attribs[i] = WGL_CONTEXT_PROFILE_MASK_ARB;
//WGL_CONTEXT_PROFILE_MASK_ARB is ignored if < 3.2 - however, nvidia do not agree and return errors //WGL_CONTEXT_PROFILE_MASK_ARB is ignored if < 3.2 - however, nvidia do not agree and return errors
if (atof(ver) >= 3.2 || vid_gl_context_es2.ival) if (atof(ver) >= 3.2 || vid_gl_context_es.ival)
i+=2; i+=2;
attribs[i] = 0; attribs[i] = 0;
@ -1223,7 +1226,7 @@ qboolean VID_AttachGL (rendererstate_t *info)
if (error == (0xc0070000 | ERROR_INVALID_VERSION_ARB)) if (error == (0xc0070000 | ERROR_INVALID_VERSION_ARB))
Con_Printf("Unsupported OpenGL context version (%s).\n", vid_gl_context_version.string); Con_Printf("Unsupported OpenGL context version (%s).\n", vid_gl_context_version.string);
else if (error == (0xc0070000 | ERROR_INVALID_PROFILE_ARB)) else if (error == (0xc0070000 | ERROR_INVALID_PROFILE_ARB))
Con_Printf("Unsupported OpenGL profile (%s).\n", vid_gl_context_es2.ival?"gles":(vid_gl_context_compatibility.ival?"compat":"core")); Con_Printf("Unsupported OpenGL profile (%s).\n", vid_gl_context_es.ival?"gles":(vid_gl_context_compatibility.ival?"compat":"core"));
else if (error == (0xc0070000 | ERROR_INVALID_OPERATION)) else if (error == (0xc0070000 | ERROR_INVALID_OPERATION))
Con_Printf("wglCreateContextAttribsARB returned invalid operation.\n"); Con_Printf("wglCreateContextAttribsARB returned invalid operation.\n");
else if (error == (0xc0070000 | ERROR_DC_NOT_FOUND)) else if (error == (0xc0070000 | ERROR_DC_NOT_FOUND))
@ -1255,10 +1258,10 @@ qboolean VID_AttachGL (rendererstate_t *info)
qwglChoosePixelFormatARB = getglfunc("wglChoosePixelFormatARB"); qwglChoosePixelFormatARB = getglfunc("wglChoosePixelFormatARB");
qwglSwapIntervalEXT = getglfunc("wglSwapIntervalEXT"); qwglSwapIntervalEXT = getglfunc("wglSwapIntervalEXT");
if (qwglSwapIntervalEXT && *_vid_wait_override.string) if (qwglSwapIntervalEXT && *vid_vsync.string)
{ {
TRACE(("dbg: VID_AttachGL: qwglSwapIntervalEXT\n")); TRACE(("dbg: VID_AttachGL: qwglSwapIntervalEXT\n"));
qwglSwapIntervalEXT(_vid_wait_override.value); qwglSwapIntervalEXT(vid_vsync.value);
} }
TRACE(("dbg: VID_AttachGL: qSwapBuffers\n")); TRACE(("dbg: VID_AttachGL: qSwapBuffers\n"));
qglClearColor(0, 0, 0, 0); qglClearColor(0, 0, 0, 0);
@ -1292,8 +1295,8 @@ void GL_BeginRendering (void)
void VID_Wait_Override_Callback(struct cvar_s *var, char *oldvalue) void VID_Wait_Override_Callback(struct cvar_s *var, char *oldvalue)
{ {
if (qwglSwapIntervalEXT && *_vid_wait_override.string) if (qwglSwapIntervalEXT && *vid_vsync.string)
qwglSwapIntervalEXT(_vid_wait_override.value); qwglSwapIntervalEXT(vid_vsync.value);
} }
void GLVID_Recenter_f(void) void GLVID_Recenter_f(void)
@ -1318,7 +1321,7 @@ void GLVID_Recenter_f(void)
sys_parentheight = atoi(Cmd_Argv(4)); sys_parentheight = atoi(Cmd_Argv(4));
if (Cmd_Argc() > 5) if (Cmd_Argc() > 5)
{ {
HWND newparent = (HWND)strtoull(Cmd_Argv(5), NULL, 16); HWND newparent = (HWND)(DWORD_PTR)strtoull(Cmd_Argv(5), NULL, 16);
if (newparent != sys_parentwindow && mainwindow && modestate==MS_WINDOWED) if (newparent != sys_parentwindow && mainwindow && modestate==MS_WINDOWED)
SetParent(mainwindow, sys_parentwindow); SetParent(mainwindow, sys_parentwindow);
sys_parentwindow = newparent; sys_parentwindow = newparent;
@ -1623,7 +1626,7 @@ BOOL bSetupPixelFormat(HDC hDC, rendererstate_t *info)
1, // version number 1, // version number
PFD_DRAW_TO_WINDOW // support window PFD_DRAW_TO_WINDOW // support window
| PFD_SUPPORT_OPENGL // support OpenGL | PFD_SUPPORT_OPENGL // support OpenGL
| PFD_DOUBLEBUFFER , // double buffered | PFD_DOUBLEBUFFER, // double buffered
PFD_TYPE_RGBA, // RGBA type PFD_TYPE_RGBA, // RGBA type
24, // 24-bit color depth 24, // 24-bit color depth
0, 0, 0, 0, 0, 0, // color bits ignored 0, 0, 0, 0, 0, 0, // color bits ignored
@ -1673,6 +1676,8 @@ BOOL bSetupPixelFormat(HDC hDC, rendererstate_t *info)
{ {
Con_Printf(CON_WARNING "WARNING: software-rendered opengl context\nPlease install appropriate graphics drivers, or try d3d rendering instead\n"); Con_Printf(CON_WARNING "WARNING: software-rendered opengl context\nPlease install appropriate graphics drivers, or try d3d rendering instead\n");
} }
else if (pfd.dwFlags & PFD_SWAP_COPY)
Con_Printf(CON_WARNING "WARNING: buffer swaps will use copy operations\n");
return TRUE; return TRUE;
} }
} }
@ -1699,6 +1704,8 @@ BOOL bSetupPixelFormat(HDC hDC, rendererstate_t *info)
{ {
Con_Printf(CON_WARNING "WARNING: software-rendered opengl context\nPlease install appropriate graphics drivers, or try d3d rendering instead\n"); Con_Printf(CON_WARNING "WARNING: software-rendered opengl context\nPlease install appropriate graphics drivers, or try d3d rendering instead\n");
} }
else if (pfd.dwFlags & PFD_SWAP_COPY)
Con_Printf(CON_WARNING "WARNING: buffer swaps will use copy operations\n");
FixPaletteInDescriptor(hDC, &pfd); FixPaletteInDescriptor(hDC, &pfd);
return TRUE; return TRUE;
@ -2061,7 +2068,7 @@ void GLVID_DeInit (void)
GLVID_Shutdown(); GLVID_Shutdown();
ActiveApp = false; ActiveApp = false;
Cvar_Unhook(&_vid_wait_override); Cvar_Unhook(&vid_vsync);
Cvar_Unhook(&vid_wndalpha); Cvar_Unhook(&vid_wndalpha);
Cmd_RemoveCommand("vid_recenter"); Cmd_RemoveCommand("vid_recenter");
@ -2112,7 +2119,7 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
vid_canalttab = true; vid_canalttab = true;
Cvar_Hook(&_vid_wait_override, VID_Wait_Override_Callback); Cvar_Hook(&vid_vsync, VID_Wait_Override_Callback);
Cvar_Hook(&vid_wndalpha, VID_WndAlpha_Override_Callback); Cvar_Hook(&vid_wndalpha, VID_WndAlpha_Override_Callback);
Cmd_AddCommand("vid_recenter", GLVID_Recenter_f); Cmd_AddCommand("vid_recenter", GLVID_Recenter_f);

View file

@ -2,11 +2,23 @@
#include "glquake.h" #include "glquake.h"
#include <SDL.h> #include <SDL.h>
#include <SDL_syswm.h>
#if SDL_MAJOR_VERSION >= 2
SDL_Window *sdlwindow;
static SDL_GLContext *sdlcontext;
#else
SDL_Surface *sdlsurf; SDL_Surface *sdlsurf;
#endif
extern cvar_t vid_vsync;
extern cvar_t vid_hardwaregamma; extern cvar_t vid_hardwaregamma;
extern cvar_t gl_lateswap; extern cvar_t gl_lateswap;
extern cvar_t vid_gl_context_version;
extern cvar_t vid_gl_context_debug;
extern cvar_t vid_gl_context_forwardcompatible;
extern cvar_t vid_gl_context_es;
extern cvar_t vid_gl_context_compatibility;
extern int gammaworks; extern int gammaworks;
#ifdef _WIN32 //half the rest of the code uses windows apis to focus windows. Should be fixed, but it's not too important. #ifdef _WIN32 //half the rest of the code uses windows apis to focus windows. Should be fixed, but it's not too important.
@ -15,7 +27,9 @@ HWND mainwindow;
extern qboolean vid_isfullscreen; extern qboolean vid_isfullscreen;
#if SDL_MAJOR_VERSION < 2
unsigned short intitialgammaramps[3][256]; unsigned short intitialgammaramps[3][256];
#endif
qboolean ActiveApp; qboolean ActiveApp;
qboolean mouseactive; qboolean mouseactive;
@ -34,29 +48,113 @@ static void *GLVID_getsdlglfunction(char *functionname)
qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette) qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
{ {
int flags; int flags = 0;
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE); SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE);
#ifndef FTE_TARGET_WEB #if !defined(FTE_TARGET_WEB) && SDL_MAJOR_VERSION < 2
SDL_SetVideoMode( 0, 0, 0, 0 ); //to get around some SDL bugs SDL_SetVideoMode(0, 0, 0, 0); //to get around some SDL bugs
#endif #endif
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 ); #if SDL_MAJOR_VERSION >= 2
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 ); SDL_GL_LoadLibrary(NULL);
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 ); #endif
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 8 ); if (info->bpp >= 32)
{
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); //technically we don't always need stencil support.
}
else
{
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 0);
}
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
if (info->stereo)
SDL_GL_SetAttribute(SDL_GL_STEREO, 1);
#if 0//SDL_MAJOR_VERSION >= 2
//FIXME: this stuff isn't part of info.
//this means it shouldn't be exposed to the menu or widely advertised.
if (*vid_gl_context_version.string)
{
int major, minor;
char *ver = vid_gl_context_version.string;
major = strtoul(ver, &ver, 10);
if (*ver == '.')
{
ver++;
minor = strtoul(ver, &ver, 10);
}
else
minor = 0;
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor);
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS,
(vid_gl_context_debug.ival?SDL_GL_CONTEXT_DEBUG_FLAG:0) |
(vid_gl_context_forwardcompatible.ival?SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG:0) |
0);
if (vid_gl_context_es.ival)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
else if (vid_gl_context_compatibility.ival)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
else
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
#endif
if (info->multisample) if (info->multisample)
{ {
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, info->multisample); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, info->multisample);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1); SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
} }
SDL_GetGammaRamp(intitialgammaramps[0], intitialgammaramps[1], intitialgammaramps[2]); #if SDL_MAJOR_VERSION >= 2
if (info->fullscreen)
flags |= SDL_WINDOW_FULLSCREEN;
flags |= SDL_WINDOW_OPENGL;
flags |= SDL_WINDOW_RESIZABLE;
flags |= SDL_WINDOW_INPUT_GRABBED;
flags |= SDL_WINDOW_SHOWN;
#if SDL_PATCHLEVEL >= 1
flags |= SDL_WINDOW_ALLOW_HIGHDPI;
#endif
sdlwindow = SDL_CreateWindow("My Magic Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, info->width, info->height, flags);
if (!sdlwindow)
{
Con_Printf("Couldn't set video mode: %s\n", SDL_GetError());
return false;
}
#if SDL_PATCHLEVEL >= 1
SDL_GL_GetDrawableSize(sdlwindow, &vid.pixelwidth, &vid.pixelheight); //get the proper physical size.
#else
SDL_GetWindowSize(sdlwindow, &vid.pixelwidth, &vid.pixelheight);
#endif
sdlcontext = SDL_GL_CreateContext(sdlwindow);
if (!sdlcontext)
{
Con_Printf("Couldn't initialize GL context: %s\n", SDL_GetError());
return false;
}
{
SDL_Surface *iconsurf;
#include "bymorphed.h"
iconsurf = SDL_CreateRGBSurfaceFrom(icon.pixel_data, icon.width, icon.height, 32, 4*icon.height, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000); //RGBA byte order on a little endian machine, at least...
SDL_SetWindowIcon(sdlwindow, iconsurf);
SDL_FreeSurface(iconsurf);
}
#else
SDL_GetGammaRamp(intitialgammaramps[0], intitialgammaramps[1], intitialgammaramps[2]);
if (info->fullscreen) if (info->fullscreen)
{ {
flags = SDL_FULLSCREEN; flags = SDL_FULLSCREEN;
@ -73,7 +171,7 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
Con_Printf("Couldn't set GL mode: %s\n", SDL_GetError()); Con_Printf("Couldn't set GL mode: %s\n", SDL_GetError());
return false; return false;
} }
#endif
ActiveApp = true; ActiveApp = true;
GL_Init(GLVID_getsdlglfunction); GL_Init(GLVID_getsdlglfunction);
@ -84,6 +182,31 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
if (vid_isfullscreen) if (vid_isfullscreen)
IN_ActivateMouse(); IN_ActivateMouse();
#if SDL_MAJOR_VERSION < 2
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
#endif
vid_vsync.modified = true;
SDL_DisableScreenSaver();
#ifdef _WIN32
{ //win32 apis are very insistant upon having a window context for things that have nothing to do with windowing system stuff.
#if SDL_MAJOR_VERSION >= 2
SDL_SysWMinfo info;
SDL_GetWindowWMInfo(sdlwindow, &info);
if (info.subsystem == SDL_SYSWM_WINDOWS)
mainwindow = info.info.win.window;
else
mainwindow = NULL; //if we're using an x11 subsystem but running in windows then don't feck up... here, at least.
#else
SDL_SysWMinfo wmInfo;
SDL_GetWMInfo(&wmInfo);
memset(&bi, 0, sizeof(bi));
mainwindow = wmInfo.window; //note that this is usually still null
#endif
}
#endif
return true; return true;
} }
@ -92,7 +215,16 @@ void GLVID_DeInit (void)
ActiveApp = false; ActiveApp = false;
IN_DeactivateMouse(); IN_DeactivateMouse();
#if SDL_MAJOR_VERSION >= 2
SDL_SetWindowGammaRamp(sdlwindow, NULL, NULL, NULL);
SDL_GL_DeleteContext(sdlcontext);
SDL_DestroyWindow(sdlwindow);
#else
SDL_SetGammaRamp (intitialgammaramps[0], intitialgammaramps[1], intitialgammaramps[2]); SDL_SetGammaRamp (intitialgammaramps[0], intitialgammaramps[1], intitialgammaramps[2]);
#endif
sdlwindow = NULL;
SDL_QuitSubSystem(SDL_INIT_VIDEO); SDL_QuitSubSystem(SDL_INIT_VIDEO);
} }
@ -113,7 +245,22 @@ void GL_DoSwap (void)
return; return;
screenflush = 0; screenflush = 0;
SDL_GL_SwapBuffers( ); if (vid_vsync.modified)
{
if (*vid_vsync.string)
{
//if swap_tear isn't supported, try without.
if (SDL_GL_SetSwapInterval(vid_vsync.ival) == -1 && vid_vsync.ival < 0)
SDL_GL_SetSwapInterval(-vid_vsync.ival);
}
vid_vsync.modified = false;
}
#if SDL_MAJOR_VERSION >= 2
SDL_GL_SwapWindow(sdlwindow);
#else
SDL_GL_SwapBuffers();
#endif
if (!vid_isfullscreen) if (!vid_isfullscreen)
@ -141,6 +288,29 @@ void GL_EndRendering (void)
qboolean GLVID_ApplyGammaRamps (unsigned short *ramps) qboolean GLVID_ApplyGammaRamps (unsigned short *ramps)
{ {
#if SDL_MAJOR_VERSION >= 2
if (ramps)
{
if (vid_hardwaregamma.value)
{
if (gammaworks)
{ //we have hardware gamma applied - if we're doing a BF, we don't want to reset to the default gamma (yuck)
SDL_SetWindowGammaRamp (sdlwindow, &ramps[0], &ramps[256], &ramps[512]);
return true;
}
gammaworks = !SDL_SetWindowGammaRamp (sdlwindow, &ramps[0], &ramps[256], &ramps[512]);
}
else
gammaworks = false;
return gammaworks;
}
else
{
SDL_SetWindowGammaRamp (sdlwindow, NULL, NULL, NULL);
return true;
}
#else
if (ramps) if (ramps)
{ {
if (vid_hardwaregamma.value) if (vid_hardwaregamma.value)
@ -162,11 +332,16 @@ qboolean GLVID_ApplyGammaRamps (unsigned short *ramps)
SDL_SetGammaRamp (intitialgammaramps[0], intitialgammaramps[1], intitialgammaramps[2]); SDL_SetGammaRamp (intitialgammaramps[0], intitialgammaramps[1], intitialgammaramps[2]);
return true; return true;
} }
#endif
} }
void GLVID_SetCaption(char *text) void GLVID_SetCaption(char *text)
{ {
SDL_WM_SetCaption( text, NULL ); #if SDL_MAJOR_VERSION >= 2
SDL_SetWindowTitle(sdlwindow, text);
#else
SDL_WM_SetCaption(text, NULL);
#endif
} }

View file

@ -278,7 +278,6 @@ extern entity_t *currententity;
extern int r_visframecount; // ??? what difs? extern int r_visframecount; // ??? what difs?
extern int r_framecount; extern int r_framecount;
extern float r_wateralphaval;
extern qboolean r_loadbumpmapping; extern qboolean r_loadbumpmapping;
// //

View file

@ -603,11 +603,35 @@ void GLBE_SelectEntity(entity_t *ent);
qboolean GLBE_SelectDLight(dlight_t *dl, vec3_t colour, unsigned int lmode); qboolean GLBE_SelectDLight(dlight_t *dl, vec3_t colour, unsigned int lmode);
void GLBE_Scissor(srect_t *rect); void GLBE_Scissor(srect_t *rect);
void GLBE_SubmitMeshes (qboolean drawworld, int start, int stop); void GLBE_SubmitMeshes (qboolean drawworld, int start, int stop);
void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, texid_t destdepth, qboolean usedepth); //void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, texid_t destdepth, qboolean usedepth);
void GLBE_RenderToTextureUpdate2d(qboolean destchanged);
void GLBE_VBO_Begin(vbobctx_t *ctx, unsigned int maxsize); void GLBE_VBO_Begin(vbobctx_t *ctx, unsigned int maxsize);
void GLBE_VBO_Data(vbobctx_t *ctx, void *data, unsigned int size, vboarray_t *varray); void GLBE_VBO_Data(vbobctx_t *ctx, void *data, unsigned int size, vboarray_t *varray);
void GLBE_VBO_Finish(vbobctx_t *ctx, void *edata, unsigned int esize, vboarray_t *earray); void GLBE_VBO_Finish(vbobctx_t *ctx, void *edata, unsigned int esize, vboarray_t *earray);
void GLBE_VBO_Destroy(vboarray_t *vearray); void GLBE_VBO_Destroy(vboarray_t *vearray);
typedef struct
{
int fbo;
int rb_size[2];
int rb_depth;
int rb_stencil;
int rb_depthstencil;
texid_t colour;
unsigned int enables;
} fbostate_t;
#define FBO_RB_COLOUR 1
#define FBO_RB_DEPTH 2
#define FBO_RB_STENCIL 4
#define FBO_RESET 8 //resize all renderbuffers / free any that are not active. implied if the sizes differ
#define FBO_TEX_COLOUR 16 //internal
#define FBO_TEX_DEPTH 32 //internal
#define FBO_TEX_STENCIL 64 //internal
void GLBE_FBO_Sources(texid_t sourcecolour, texid_t sourcedepth);
int GLBE_FBO_Push(fbostate_t *state);
void GLBE_FBO_Pop(int oldfbo);
void GLBE_FBO_Destroy(fbostate_t *state);
int GLBE_FBO_Update(fbostate_t *state, qboolean bind, unsigned int enables, texid_t destcol, texid_t destdepth, int width, int height);
#endif #endif
#ifdef D3D9QUAKE #ifdef D3D9QUAKE
void D3D9BE_Init(void); void D3D9BE_Init(void);

View file

@ -21,7 +21,7 @@
#include "netinc.h" #include "netinc.h"
static iwboolean ftpserverinitied = false; static iwboolean ftpserverinitied = false;
static int ftpserversocket = INVALID_SOCKET; static SOCKET ftpserversocket = INVALID_SOCKET;
qboolean ftpserverfailed; qboolean ftpserverfailed;
@ -36,8 +36,8 @@ typedef struct FTPclient_s{
int cmdbuflen; int cmdbuflen;
int msgbuflen; int msgbuflen;
int controlsock; SOCKET controlsock;
int datasock; //FTP only allows one transfer per connection. SOCKET datasock; //FTP only allows one transfer per connection.
int dataislisten; int dataislisten;
int datadir; //0 no data, 1 reading, 2 writing int datadir; //0 no data, 1 reading, 2 writing
vfsfile_t *file; vfsfile_t *file;
@ -49,13 +49,13 @@ typedef struct FTPclient_s{
FTPclient_t *FTPclient; FTPclient_t *FTPclient;
int FTP_BeginListening(int aftype, int port) SOCKET FTP_BeginListening(int aftype, int port)
{ {
struct sockaddr_qstorage address; struct sockaddr_qstorage address;
unsigned long _true = true; unsigned long _true = true;
unsigned long _false = false; unsigned long _false = false;
int i; int i;
int sock; SOCKET sock;
#ifdef IPPROTO_IPV6 #ifdef IPPROTO_IPV6
if ((sock = socket ((aftype!=1)?PF_INET6:PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) if ((sock = socket ((aftype!=1)?PF_INET6:PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
@ -63,13 +63,13 @@ int FTP_BeginListening(int aftype, int port)
if ((sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) if ((sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
#endif #endif
{ {
IWebPrintf ("FTP_BeginListening: socket: %s\n", strerror(qerrno)); IWebPrintf ("FTP_BeginListening: socket: %s\n", strerror(neterrno()));
return INVALID_SOCKET; return INVALID_SOCKET;
} }
if (ioctlsocket (sock, FIONBIO, &_true) == -1) if (ioctlsocket (sock, FIONBIO, &_true) == -1)
{ {
IWebPrintf ("FTP_BeginListening: ioctl FIONBIO: %s", strerror(qerrno)); IWebPrintf ("FTP_BeginListening: ioctl FIONBIO: %s", strerror(neterrno()));
return INVALID_SOCKET; return INVALID_SOCKET;
} }
@ -134,9 +134,9 @@ void FTP_ServerShutdown(void)
} }
//we ought to filter this to remove duplicates. //we ought to filter this to remove duplicates.
static int QDECL SendFileNameTo(const char *rawname, int size, void *param, searchpathfuncs_t *spath) static int QDECL SendFileNameTo(const char *rawname, qofs_t size, void *param, searchpathfuncs_t *spath)
{ {
int socket = *(int*)param; SOCKET socket = *(SOCKET*)param;
// int i; // int i;
char buffer[256+1]; char buffer[256+1];
char *slash; char *slash;
@ -171,10 +171,10 @@ static int QDECL SendFileNameTo(const char *rawname, int size, void *param, sear
return true; return true;
} }
int FTP_SV_makelistensocket(unsigned long nblocking) SOCKET FTP_SV_makelistensocket(unsigned long nblocking)
{ {
char name[256]; char name[256];
int sock; SOCKET sock;
struct hostent *hent; struct hostent *hent;
struct sockaddr_in address; struct sockaddr_in address;
@ -193,12 +193,12 @@ int FTP_SV_makelistensocket(unsigned long nblocking)
if ((sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) if ((sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
{ {
Sys_Error ("FTP_TCP_OpenSocket: socket: %s", strerror(qerrno)); Sys_Error ("FTP_TCP_OpenSocket: socket: %s", strerror(neterrno()));
} }
if (ioctlsocket (sock, FIONBIO, &nblocking) == -1) if (ioctlsocket (sock, FIONBIO, &nblocking) == -1)
{ {
Sys_Error ("FTP_TCP_OpenSocket: ioctl FIONBIO: %s", strerror(qerrno)); Sys_Error ("FTP_TCP_OpenSocket: ioctl FIONBIO: %s", strerror(neterrno()));
} }
if( bind (sock, (void *)&address, sizeof(address)) == -1) if( bind (sock, (void *)&address, sizeof(address)) == -1)
@ -211,7 +211,7 @@ int FTP_SV_makelistensocket(unsigned long nblocking)
return sock; return sock;
} }
iwboolean FTP_SVSocketPortToString (int socket, char *s) iwboolean FTP_SVSocketPortToString (SOCKET socket, char *s)
{ {
struct sockaddr_qstorage addr; struct sockaddr_qstorage addr;
int adrlen = sizeof(addr); int adrlen = sizeof(addr);
@ -226,7 +226,7 @@ iwboolean FTP_SVSocketPortToString (int socket, char *s)
return true; return true;
} }
//only to be used for ipv4 sockets. //only to be used for ipv4 sockets.
iwboolean FTP_SVSocketToString (int socket, char *s) iwboolean FTP_SVSocketToString (SOCKET socket, char *s)
{ {
struct sockaddr_in addr; struct sockaddr_in addr;
qbyte *baddr; qbyte *baddr;
@ -249,7 +249,7 @@ iwboolean FTP_SVSocketToString (int socket, char *s)
sprintf(s, "%i,%i,%i,%i,%i,%i", baddr[0], baddr[1], baddr[2], baddr[3], ((qbyte *)&addr.sin_port)[0], ((qbyte *)&addr.sin_port)[1]); sprintf(s, "%i,%i,%i,%i,%i,%i", baddr[0], baddr[1], baddr[2], baddr[3], ((qbyte *)&addr.sin_port)[0], ((qbyte *)&addr.sin_port)[1]);
return true; return true;
} }
iwboolean FTP_SVRemoteSocketToString (int socket, char *s, int slen) iwboolean FTP_SVRemoteSocketToString (SOCKET socket, char *s, int slen)
{ {
struct sockaddr_qstorage addr; struct sockaddr_qstorage addr;
netadr_t na; netadr_t na;
@ -327,7 +327,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
if (sent == -1) if (sent == -1)
{ {
VFS_SEEK(cl->file, pos); VFS_SEEK(cl->file, pos);
if (qerrno != EWOULDBLOCK) if (neterrno() != NET_EWOULDBLOCK)
{ {
closesocket(cl->datasock); closesocket(cl->datasock);
cl->datasock = INVALID_SOCKET; cl->datasock = INVALID_SOCKET;
@ -361,7 +361,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
pos = cl->datadir?1:!cl->blocking; pos = cl->datadir?1:!cl->blocking;
if (ioctlsocket (cl->controlsock, FIONBIO, (u_long *)&pos) == -1) if (ioctlsocket (cl->controlsock, FIONBIO, (u_long *)&pos) == -1)
{ {
IWebPrintf ("FTP_ServerRun: blocking error: %s\n", strerror(qerrno)); IWebPrintf ("FTP_ServerRun: blocking error: %s\n", strerror(neterrno()));
return 0; return 0;
} }
} }
@ -374,7 +374,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
} }
if (len == -1) if (len == -1)
{ {
if (qerrno != EWOULDBLOCK) if (neterrno() != NET_EWOULDBLOCK)
{ {
closesocket(cl->datasock); closesocket(cl->datasock);
cl->datasock = INVALID_SOCKET; cl->datasock = INVALID_SOCKET;
@ -398,13 +398,14 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
ret = recv(cl->controlsock, cl->commandbuffer+cl->cmdbuflen, sizeof(cl->commandbuffer)-1 - cl->cmdbuflen, 0); ret = recv(cl->controlsock, cl->commandbuffer+cl->cmdbuflen, sizeof(cl->commandbuffer)-1 - cl->cmdbuflen, 0);
if (ret == -1) if (ret == -1)
{ {
if (qerrno == EWOULDBLOCK) int e = neterrno();
if (e == NET_EWOULDBLOCK)
return false; //remove return false; //remove
if (qerrno == ECONNABORTED || qerrno == ECONNRESET) if (e == NET_ECONNABORTED || e == NET_ECONNRESET)
return true; return true;
Con_Printf ("NET_GetPacket: %s\n", strerror(qerrno)); Con_Printf ("NET_GetPacket: %s\n", strerror(e));
return true; return true;
} }
if (*cl->messagebuffer) if (*cl->messagebuffer)
@ -583,12 +584,12 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
if ((cl->datasock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) if ((cl->datasock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
{ {
Sys_Error ("FTP_ServerThinkForConnection: socket: %s", strerror(qerrno)); Sys_Error ("FTP_ServerThinkForConnection: socket: %s", strerror(neterrno()));
} }
if (ioctlsocket (cl->datasock, FIONBIO, (u_long *)&_true) == -1) if (ioctlsocket (cl->datasock, FIONBIO, (u_long *)&_true) == -1)
{ {
Sys_Error ("FTP_ServerThinkForConnection: ioctl FIONBIO: %s", strerror(qerrno)); Sys_Error ("FTP_ServerThinkForConnection: ioctl FIONBIO: %s", strerror(neterrno()));
} }
from.sin_family = AF_INET; from.sin_family = AF_INET;
@ -629,7 +630,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
struct sockaddr_qstorage adr; struct sockaddr_qstorage adr;
int adrlen = sizeof(adr); int adrlen = sizeof(adr);
temp = accept(cl->datasock, (struct sockaddr *)&adr, &adrlen); temp = accept(cl->datasock, (struct sockaddr *)&adr, &adrlen);
err = qerrno; err = neterrno();
closesocket(cl->datasock); closesocket(cl->datasock);
cl->datasock = temp; cl->datasock = temp;
cl->dataislisten = false; cl->dataislisten = false;
@ -690,7 +691,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
if (cl->datasock == INVALID_SOCKET) if (cl->datasock == INVALID_SOCKET)
{ {
QueueMessageva (cl, "425 Can't accept pasv data connection - %i.\r\n", qerrno); QueueMessageva (cl, "425 Can't accept pasv data connection - %i.\r\n", neterrno());
continue; continue;
} }
else else
@ -779,7 +780,7 @@ iwboolean FTP_ServerThinkForConnection(FTPclient_t *cl)
if (cl->datasock == INVALID_SOCKET) if (cl->datasock == INVALID_SOCKET)
{ {
QueueMessageva (cl, "425 Can't accept pasv data connection - %i.\r\n", qerrno); QueueMessageva (cl, "425 Can't accept pasv data connection - %i.\r\n", neterrno());
continue; continue;
} }
else else
@ -885,7 +886,7 @@ iwboolean FTP_ServerRun(iwboolean ftpserverwanted, int port)
FTPclient_t *cl, *prevcl; FTPclient_t *cl, *prevcl;
struct sockaddr_qstorage from; struct sockaddr_qstorage from;
int fromlen; int fromlen;
int clientsock; SOCKET clientsock;
unsigned long _true = true; unsigned long _true = true;
if (!ftpserverinitied) if (!ftpserverinitied)
@ -949,23 +950,24 @@ unsigned long _true = true;
if (clientsock == INVALID_SOCKET) if (clientsock == INVALID_SOCKET)
{ {
if (qerrno == EWOULDBLOCK) int e = neterrno();
if (e == NET_EWOULDBLOCK)
return false; return false;
if (qerrno == ECONNABORTED || qerrno == ECONNRESET) if (e == NET_ECONNABORTED || e == NET_ECONNRESET)
{ {
Con_TPrintf ("Connection lost or aborted\n"); Con_TPrintf ("Connection lost or aborted\n");
return false; return false;
} }
Con_Printf ("NET_GetPacket: %s\n", strerror(qerrno)); Con_Printf ("NET_GetPacket: %s\n", strerror(e));
return false; return false;
} }
if (ioctlsocket (clientsock, FIONBIO, &_true) == -1) if (ioctlsocket (clientsock, FIONBIO, &_true) == -1)
{ {
IWebPrintf ("FTP_ServerRun: blocking error: %s\n", strerror(qerrno)); IWebPrintf ("FTP_ServerRun: blocking error: %s\n", strerror(neterrno()));
return false; return false;
} }
cl = IWebMalloc(sizeof(FTPclient_t)); cl = IWebMalloc(sizeof(FTPclient_t));

View file

@ -338,7 +338,7 @@ static qboolean HTTP_DL_Work(struct dl_download *dl)
if (ammount < 0) if (ammount < 0)
{ {
if (qerrno != EWOULDBLOCK) if (neterrno() != NET_EWOULDBLOCK)
return false; return false;
return true; return true;
} }
@ -358,7 +358,7 @@ static qboolean HTTP_DL_Work(struct dl_download *dl)
return false; return false;
if (ammount < 0) if (ammount < 0)
{ {
if (qerrno != EWOULDBLOCK) if (neterrno() != NET_EWOULDBLOCK)
return false; return false;
return true; return true;
} }
@ -554,7 +554,7 @@ static qboolean HTTP_DL_Work(struct dl_download *dl)
ammount = recv(con->sock, con->buffer+con->bufferused, con->bufferlen-con->bufferused-1, 0); ammount = recv(con->sock, con->buffer+con->bufferused, con->bufferlen-con->bufferused-1, 0);
if (ammount < 0) if (ammount < 0)
{ {
if (qerrno != EWOULDBLOCK) if (neterrno() != NET_EWOULDBLOCK)
return false; return false;
return true; return true;
} }
@ -1029,7 +1029,7 @@ void QDECL VFSPIPE_Close(vfsfile_t *f)
free(p->data); free(p->data);
free(p); free(p);
} }
unsigned long QDECL VFSPIPE_GetLen(vfsfile_t *f) qofs_t QDECL VFSPIPE_GetLen(vfsfile_t *f)
{ {
vfspipe_t *p = (vfspipe_t*)f; vfspipe_t *p = (vfspipe_t*)f;
return p->writepos - p->readpos; return p->writepos - p->readpos;

View file

@ -133,14 +133,14 @@ qboolean HTTP_ServerInit(int port)
if ((httpserversocket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) if ((httpserversocket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
{ {
IWebPrintf ("HTTP_ServerInit: socket: %s\n", strerror(qerrno)); IWebPrintf ("HTTP_ServerInit: socket: %s\n", strerror(neterrno()));
httpserverfailed = true; httpserverfailed = true;
return false; return false;
} }
if (ioctlsocket (httpserversocket, FIONBIO, &_true) == -1) if (ioctlsocket (httpserversocket, FIONBIO, &_true) == -1)
{ {
IWebPrintf ("HTTP_ServerInit: ioctl FIONBIO: %s\n", strerror(qerrno)); IWebPrintf ("HTTP_ServerInit: ioctl FIONBIO: %s\n", strerror(neterrno()));
httpserverfailed = true; httpserverfailed = true;
return false; return false;
} }
@ -305,7 +305,7 @@ void HTTP_RunExisting (void)
ammount = recv(cl->datasock, cl->inbuffer+cl->inbufferused, ammount, 0); ammount = recv(cl->datasock, cl->inbuffer+cl->inbufferused, ammount, 0);
if (ammount < 0) if (ammount < 0)
{ {
if (qerrno != EWOULDBLOCK) //they closed on us. Assume end. if (neterrno() != NET_EWOULDBLOCK) //they closed on us. Assume end.
{ {
cl->closereason = "recv error"; cl->closereason = "recv error";
} }
@ -622,8 +622,8 @@ notimplemented:
if (ammount == -1) if (ammount == -1)
{ {
localerrno = qerrno; localerrno = neterrno();
if (localerrno != EWOULDBLOCK) if (localerrno != NET_EWOULDBLOCK)
{ {
cl->closereason = "some error when sending"; cl->closereason = "some error when sending";
} }
@ -698,26 +698,27 @@ qboolean HTTP_ServerPoll(qboolean httpserverwanted, int portnum) //loop while tr
if (clientsock == -1) if (clientsock == -1)
{ {
if (qerrno == EWOULDBLOCK) int e = neterrno();
if (e == NET_EWOULDBLOCK)
{ {
HTTP_RunExisting(); HTTP_RunExisting();
return false; return false;
} }
if (qerrno == ECONNABORTED || qerrno == ECONNRESET) if (e == NET_ECONNABORTED || e == NET_ECONNRESET)
{ {
Con_TPrintf ("Connection lost or aborted\n"); Con_TPrintf ("Connection lost or aborted\n");
return false; return false;
} }
Con_Printf ("NET_GetPacket: %s\n", strerror(qerrno)); Con_Printf ("NET_GetPacket: %s\n", strerror(e));
return false; return false;
} }
if (ioctlsocket (clientsock, FIONBIO, (u_long *)&_true) == -1) if (ioctlsocket (clientsock, FIONBIO, (u_long *)&_true) == -1)
{ {
IWebPrintf ("HTTP_ServerInit: ioctl FIONBIO: %s\n", strerror(qerrno)); IWebPrintf ("HTTP_ServerInit: ioctl FIONBIO: %s\n", strerror(neterrno()));
closesocket(clientsock); closesocket(clientsock);
return false; return false;
} }

View file

@ -355,7 +355,7 @@ int QDECL VFSGen_WriteBytes(vfsfile_t *f, const void *buffer, int bytes)
return 0; return 0;
} }
qboolean QDECL VFSGen_Seek(vfsfile_t *f, unsigned long newpos) qboolean QDECL VFSGen_Seek(vfsfile_t *f, qofs_t newpos)
{ {
vfsgen_t *g = (vfsgen_t*)f; vfsgen_t *g = (vfsgen_t*)f;
if (newpos < 0 || newpos >= g->buffer->len) if (newpos < 0 || newpos >= g->buffer->len)
@ -366,13 +366,13 @@ qboolean QDECL VFSGen_Seek(vfsfile_t *f, unsigned long newpos)
return true; return true;
} }
unsigned long QDECL VFSGen_Tell(vfsfile_t *f) qofs_t QDECL VFSGen_Tell(vfsfile_t *f)
{ {
vfsgen_t *g = (vfsgen_t*)f; vfsgen_t *g = (vfsgen_t*)f;
return g->pos; return g->pos;
} }
unsigned long QDECL VFSGen_GetLen(vfsfile_t *f) qofs_t QDECL VFSGen_GetLen(vfsfile_t *f)
{ {
vfsgen_t *g = (vfsgen_t*)f; vfsgen_t *g = (vfsgen_t*)f;
return g->buffer->len; return g->buffer->len;

View file

@ -201,18 +201,18 @@ static int VFSMEM_WriteBytes (struct vfsfile_s *file, const void *buffer, int by
// Sys_Printf("written: %i, file is now at %i\n", total, f->offset); // Sys_Printf("written: %i, file is now at %i\n", total, f->offset);
return total; return total;
} }
static qboolean VFSMEM_Seek (struct vfsfile_s *file, unsigned long pos) static qboolean VFSMEM_Seek (struct vfsfile_s *file, qofs_t pos)
{ {
vfsmfile_t *f = (vfsmfile_t*)file; vfsmfile_t *f = (vfsmfile_t*)file;
f->offset = pos; f->offset = pos;
return true; return true;
} }
static unsigned long VFSMEM_Tell (struct vfsfile_s *file) static qofs_t VFSMEM_Tell (struct vfsfile_s *file)
{ {
vfsmfile_t *f = (vfsmfile_t*)file; vfsmfile_t *f = (vfsmfile_t*)file;
return f->offset; return f->offset;
} }
static unsigned long VFSMEM_GetSize (struct vfsfile_s *file) static qofs_t VFSMEM_GetSize (struct vfsfile_s *file)
{ {
vfsmfile_t *f = (vfsmfile_t*)file; vfsmfile_t *f = (vfsmfile_t*)file;
return f->file->length; return f->file->length;
@ -395,7 +395,7 @@ static void FSPPAPI_ClosePath(searchpathfuncs_t *handle)
Z_Free(handle); Z_Free(handle);
} }
int Sys_EnumerateFiles (const char *rootpath, const char *match, int (*func)(const char *, int, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath) int Sys_EnumerateFiles (const char *rootpath, const char *match, int (*func)(const char *, qofs_t, void *, searchpathfuncs_t *), void *parm, searchpathfuncs_t *spath)
{ {
int rootlen = strlen(rootpath); int rootlen = strlen(rootpath);
char *sub; char *sub;
@ -418,13 +418,13 @@ int Sys_EnumerateFiles (const char *rootpath, const char *match, int (*func)(con
} }
return true; return true;
} }
static int FSPPAPI_EnumerateFiles (searchpathfuncs_t *handle, const char *match, int (*func)(const char *, int, void *, searchpathfuncs_t *), void *parm) static int FSPPAPI_EnumerateFiles (searchpathfuncs_t *handle, const char *match, int (*func)(const char *, qofs_t, void *, searchpathfuncs_t *), void *parm)
{ {
pppath_t *sp = (void*)handle; pppath_t *sp = (void*)handle;
return Sys_EnumerateFiles(sp->rootpath, match, func, parm, handle); return Sys_EnumerateFiles(sp->rootpath, match, func, parm, handle);
} }
static int FSPPAPI_RebuildFSHash(const char *filename, int filesize, void *data, searchpathfuncs_t *handle) static int FSPPAPI_RebuildFSHash(const char *filename, qofs_t filesize, void *data, searchpathfuncs_t *handle)
{ {
pppath_t *sp = (void*)handle; pppath_t *sp = (void*)handle;
void (QDECL *AddFileHash)(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle) = data; void (QDECL *AddFileHash)(int depth, const char *fname, fsbucket_t *filehandle, void *pathhandle) = data;
@ -571,13 +571,13 @@ static int VFSPPAPI_WriteBytes (struct vfsfile_s *file, const void *buffer, int
intfile->offset += res; intfile->offset += res;
return res; return res;
} }
static qboolean VFSPPAPI_Seek (struct vfsfile_s *file, unsigned long pos) static qboolean VFSPPAPI_Seek (struct vfsfile_s *file, qofs_t pos)
{ {
vfsppapifile_t *intfile = (vfsppapifile_t*)file; vfsppapifile_t *intfile = (vfsppapifile_t*)file;
intfile->offset = pos; intfile->offset = pos;
return true; return true;
} }
static unsigned long VFSPPAPI_Tell (struct vfsfile_s *file) static qofs_t VFSPPAPI_Tell (struct vfsfile_s *file)
{ {
vfsppapifile_t *intfile = (vfsppapifile_t*)file; vfsppapifile_t *intfile = (vfsppapifile_t*)file;
return intfile->offset; return intfile->offset;
@ -587,7 +587,7 @@ static void VFSPPAPI_Flush(struct vfsfile_s *file)
vfsppapifile_t *intfile = (vfsppapifile_t*)file; vfsppapifile_t *intfile = (vfsppapifile_t*)file;
ppb_fileio->Flush(intfile->handle, nullccb); ppb_fileio->Flush(intfile->handle, nullccb);
} }
static unsigned long VFSPPAPI_GetSize (struct vfsfile_s *file) static qofs_t VFSPPAPI_GetSize (struct vfsfile_s *file)
{ {
vfsppapifile_t *intfile = (vfsppapifile_t*)file; vfsppapifile_t *intfile = (vfsppapifile_t*)file;
struct PP_FileInfo fileinfo; struct PP_FileInfo fileinfo;
@ -710,7 +710,7 @@ static void FSPPAPI_ClosePath(searchpathfuncs_t *handle)
{ {
Z_Free(handle); Z_Free(handle);
} }
static int FSPPAPI_RebuildFSHash(const char *filename, int filesize, void *data) static int FSPPAPI_RebuildFSHash(const char *filename, qofs_t filesize, void *data)
{ {
if (filename[strlen(filename)-1] == '/') if (filename[strlen(filename)-1] == '/')
{ //this is actually a directory { //this is actually a directory

View file

@ -17,7 +17,7 @@ extern PPB_Instance* instance_interface;
int delayedswap = false; int delayedswap = false;
qboolean swappending; qboolean swappending;
extern cvar_t _vid_wait_override; extern cvar_t vid_vsync;
void FrameEvent(void* user_data, int32_t result); void FrameEvent(void* user_data, int32_t result);
qboolean NAGL_SwapPending(void) qboolean NAGL_SwapPending(void)
@ -49,7 +49,7 @@ void GL_DoSwap(void)
{ {
if (delayedswap) if (delayedswap)
{ {
qboolean vsync = _vid_wait_override.ival || !*_vid_wait_override.string; qboolean vsync = vid_vsync.ival || !*vid_vsync.string;
struct PP_CompletionCallback ccb = { swap_callback, NULL, vsync?PP_COMPLETIONCALLBACK_FLAG_NONE:PP_COMPLETIONCALLBACK_FLAG_OPTIONAL}; struct PP_CompletionCallback ccb = { swap_callback, NULL, vsync?PP_COMPLETIONCALLBACK_FLAG_NONE:PP_COMPLETIONCALLBACK_FLAG_OPTIONAL};
glFlush(); glFlush();
delayedswap = false; delayedswap = false;
@ -63,7 +63,7 @@ void GL_DoSwap(void)
break; break;
case PP_ERROR_INPROGRESS: case PP_ERROR_INPROGRESS:
Con_DPrintf("chrome still can't handle vid_wait 0. forcing vsync\n"); Con_DPrintf("chrome still can't handle vid_wait 0. forcing vsync\n");
_vid_wait_override.ival = 1; vid_vsync.ival = 1;
break; break;
default: default:
Con_DPrintf("unknown error on SwapBuffers call\n"); Con_DPrintf("unknown error on SwapBuffers call\n");

View file

@ -172,7 +172,7 @@ void INS_Shutdown(void)
/* /*
//nacl supposedly has no way to implement this (other than us writing a listfile in each directory) //nacl supposedly has no way to implement this (other than us writing a listfile in each directory)
int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, int, void *), void *parm) int Sys_EnumerateFiles (const char *gpath, const char *match, int (*func)(const char *, qofs_t, void *), void *parm)
{ {
return 0; return 0;
} }

View file

@ -213,12 +213,11 @@ r_part te_explosion
scalefactor 1 scalefactor 1
scaledelta -15 scaledelta -15
randomvel 0 randomvel 0
// lightradius 350
lightradius 350 // lightrgb 1.4 1.2 1.05
lightrgb 1.4 1.2 1.05 // lighttime 0.5
lighttime 0.5 // lightradiusfade 350
lightradiusfade 350 // lightrgbfade 2 2 2
lightrgbfade 2 2 2
} }
//smoke //smoke
r_part +te_explosion r_part +te_explosion
@ -261,7 +260,7 @@ r_part +te_explosion
} }
//hide lights in explosions. //hide lights in explosions.
r_explosionlight 0 //r_explosionlight 0
//hide the explosion sprite in nq+qw - WARNING: some mods use this sprite as a flame thrower. //hide the explosion sprite in nq+qw - WARNING: some mods use this sprite as a flame thrower.
cl_expsprite 0 cl_expsprite 0

View file

@ -2309,7 +2309,9 @@ char *PDECL PR_SaveEnt (pubprogfuncs_t *ppf, char *buf, int *size, int maxsize,
fdef_t *d; fdef_t *d;
int *v; int *v;
unsigned int i;unsigned int j; unsigned int i;unsigned int j;
char *name; char *name, *mname;
char *classname = NULL;
int classnamelen = 0;
int type; int type;
// if (ed->free) // if (ed->free)
@ -2338,6 +2340,40 @@ char *PDECL PR_SaveEnt (pubprogfuncs_t *ppf, char *buf, int *size, int maxsize,
if (j == type_size[type]) if (j == type_size[type])
continue; continue;
if (strstr(name, "::"))
{
if (*name != ':')
continue; //don't directly generate anything from class::foo
if (!classname)
{
fdef_t *cnfd;
cnfd = ED_FindField(progfuncs, "classname");
if (cnfd)
{
string_t *v;
v = (string_t *)((char *)edvars(ed) + cnfd->ofs*4);
classname = PR_StringToNative(&progfuncs->funcs, *v);
}
else
classname = "";
classnamelen = strlen(classname);
}
for (j = i+1; j < prinst.numfields; j++)
{
if (prinst.field[j].ofs == d->ofs)
{
mname = prinst.field[j].name;
if (!strncmp(mname, classname, classnamelen) && mname[classnamelen] == ':')
{
//okay, we have a match...
name = prinst.field[j].name;
break;
}
}
}
}
//add it to the file //add it to the file
AddS("\""); AddS(name); AddS("\" \""); AddS(PR_UglyValueString(&progfuncs->funcs, d->type, (eval_t *)v)); AddS("\"\n"); AddS("\""); AddS(name); AddS("\" \""); AddS(PR_UglyValueString(&progfuncs->funcs, d->type, (eval_t *)v)); AddS("\"\n");
} }

View file

@ -90,7 +90,7 @@ struct pubprogfuncs_s
struct progstate_s **progstate; //internal to the library. struct progstate_s **progstate; //internal to the library.
func_t (PDECL *FindFunction) (pubprogfuncs_t *prinst, char *funcname, progsnum_t num); func_t (PDECL *FindFunction) (pubprogfuncs_t *prinst, const char *funcname, progsnum_t num);
int (PDECL *StartCompile) (pubprogfuncs_t *prinst, int argv, char **argc); //1 if can compile, 0 if failed to compile int (PDECL *StartCompile) (pubprogfuncs_t *prinst, int argv, char **argc); //1 if can compile, 0 if failed to compile
int (PDECL *ContinueCompile) (pubprogfuncs_t *prinst); //2 if finished, 1 if more to go, 0 if failed int (PDECL *ContinueCompile) (pubprogfuncs_t *prinst); //2 if finished, 1 if more to go, 0 if failed

View file

@ -4932,6 +4932,16 @@ void QCC_PR_EmitClassFromFunction(QCC_def_t *scope, QCC_type_t *basetype)
ed = QCC_PR_GetDef(type_entity, "self", NULL, true, 0, false); ed = QCC_PR_GetDef(type_entity, "self", NULL, true, 0, false);
{
QCC_def_t *fclassname = QCC_PR_GetDef(NULL, "classname", NULL, false, 0, false);
if (fclassname)
{
QCC_def_t *point = QCC_PR_Statement(&pr_opcodes[OP_ADDRESS], ed, fclassname, NULL);
type_pointer->aux_type = type_string;
QCC_PR_Statement(&pr_opcodes[OP_STOREP_FNC], QCC_MakeStringConst(basetype->name), point, NULL);
}
}
QCC_PR_EmitClassFunctionTable(basetype, basetype, ed); QCC_PR_EmitClassFunctionTable(basetype, basetype, ed);
//FIXME: these constructors are called in the wrong order //FIXME: these constructors are called in the wrong order

View file

@ -1319,7 +1319,7 @@ void QCC_PR_LexString (void)
void QCC_PR_LexString (void) void QCC_PR_LexString (void)
{ {
int c; int c;
int len; int len = 0;
char *end, *cnst; char *end, *cnst;
int raw; int raw;
char rawdelim[64]; char rawdelim[64];
@ -1356,6 +1356,18 @@ void QCC_PR_LexString (void)
rawdelim[raw++] = c; rawdelim[raw++] = c;
} }
rawdelim[raw++] = '\"'; rawdelim[raw++] = '\"';
//these two conditions are generally part of the C preprocessor.
if (!strncmp(pr_file_p, "\\\r\n", 3))
{ //dos format
pr_file_p += 3;
pr_source_line++;
}
else if (!strncmp(pr_file_p, "\\\r", 2) || !strncmp(pr_file_p, "\\\n", 2))
{ //mac + unix format
pr_file_p += 2;
pr_source_line++;
}
} }
else if (*pr_file_p == '\"') else if (*pr_file_p == '\"')
pr_file_p++; pr_file_p++;
@ -1365,14 +1377,13 @@ void QCC_PR_LexString (void)
break; break;
first = false; first = false;
len = 0;
for(;;) for(;;)
{ {
c = *pr_file_p++; c = *pr_file_p++;
if (!c) if (!c)
QCC_PR_ParseError (ERR_EOF, "EOF inside quote"); QCC_PR_ParseError (ERR_EOF, "EOF inside quote");
//these two conditions are generally part of the C preprocessor. /* //these two conditions are generally part of the C preprocessor.
if (c == '\\' && *pr_file_p == '\r' && pr_file_p[1] == '\n') if (c == '\\' && *pr_file_p == '\r' && pr_file_p[1] == '\n')
{ //dos format { //dos format
pr_file_p += 2; pr_file_p += 2;
@ -1385,10 +1396,10 @@ void QCC_PR_LexString (void)
pr_source_line++; pr_source_line++;
continue; continue;
} }
*/
if (raw) if (raw)
{ {
//raw strings contain very little parsing. just delimiter and \NL support. //raw strings contain very little parsing. just delimiter and initial \NL support.
if (c == rawdelim[0] && !strncmp(pr_file_p, rawdelim+1, raw-1)) if (c == rawdelim[0] && !strncmp(pr_file_p, rawdelim+1, raw-1))
{ {
pr_file_p += raw-1; pr_file_p += raw-1;

View file

@ -580,11 +580,16 @@ void QCC_InitData (void)
qcc_sourcefile = NULL; qcc_sourcefile = NULL;
memset(stringtablist, 0, sizeof(stringtablist)); memset(stringtablist, 0, sizeof(stringtablist));
numstatements = 1; numstatements = 1; //first statement should be an OP_DONE, matching the null function(ish), in case it somehow doesn't get caught by the vm.
strofs = 2; strofs = 2; //null, empty, *other stuff*
numfunctions = 1; numfunctions = 1; //first function is a null function.
numglobaldefs = 1; numglobaldefs = 1; //first globaldef is a null def. just because. doesn't include parms+ret. is there any point to this?
numfielddefs = 1;
numfielddefs = 0;
fields[numfielddefs].type = ev_void;
fields[numfielddefs].s_name = 0; //should map to null
fields[numfielddefs].ofs = 0;
numfielddefs++; //FIXME: do we actually need a null field? is there any point to this at all?
memset(&ret_temp, 0, sizeof(ret_temp)); memset(&ret_temp, 0, sizeof(ret_temp));
@ -3478,10 +3483,14 @@ void QCC_ContinueCompile(void)
if (newstylesource) if (newstylesource)
{ {
char *ofp = pr_file_p;
do do
{ {
new_QCC_ContinueCompile(); new_QCC_ContinueCompile();
} while(currentchunk); //while parsing through preprocessor, make sure nothing gets hurt. } while(currentchunk); //while parsing through preprocessor, make sure nothing gets hurt.
if (ofp == pr_file_p && qcc_compileactive && pr_token_type != tt_eof)
QCC_Error (ERR_INTERNAL, "Syntax error\n");
return; return;
} }

View file

@ -1290,8 +1290,6 @@ void NPP_NQWriteAngle(int dest, float in) //replacement write func (nq to qw)
} }
void NPP_NQWriteCoord(int dest, float in) //replacement write func (nq to qw) void NPP_NQWriteCoord(int dest, float in) //replacement write func (nq to qw)
{ {
short datas = (int)(in*8);
float dataf = in;
NPP_NQCheckDest(dest); NPP_NQCheckDest(dest);
if (!bufferlen) if (!bufferlen)
Con_Printf("NQWriteCoord: Messages should start with WriteByte\n"); Con_Printf("NQWriteCoord: Messages should start with WriteByte\n");
@ -1323,11 +1321,15 @@ void NPP_NQWriteCoord(int dest, float in) //replacement write func (nq to qw)
if (destprim->coordsize==4) if (destprim->coordsize==4)
{ {
float dataf = in;
dataf = LittleFloat(dataf); dataf = LittleFloat(dataf);
NPP_AddData(&dataf, sizeof(float)); NPP_AddData(&dataf, sizeof(float));
} }
else else
{ {
short datas = (int)(in*8);
datas = LittleShort(datas); datas = LittleShort(datas);
NPP_AddData(&datas, sizeof(short)); NPP_AddData(&datas, sizeof(short));
} }

View file

@ -9352,6 +9352,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"hash_getkey", PF_hash_getkey, 0, 0, 0, 292, D("string(float table, float idx)", "gets some random key name. add+delete can change return values of this, so don't blindly increment the key index if you're removing all.")}, {"hash_getkey", PF_hash_getkey, 0, 0, 0, 292, D("string(float table, float idx)", "gets some random key name. add+delete can change return values of this, so don't blindly increment the key index if you're removing all.")},
{"hash_getcb", PF_hash_getcb, 0, 0, 0, 293, D("void(float table, void(string keyname, __variant val) callback, optional string name)", "For each item in the table that matches the name, call the callback. if name is omitted, will enumerate ALL keys.")}, {"hash_getcb", PF_hash_getcb, 0, 0, 0, 293, D("void(float table, void(string keyname, __variant val) callback, optional string name)", "For each item in the table that matches the name, call the callback. if name is omitted, will enumerate ALL keys.")},
{"checkcommand", PF_checkcommand, 0, 0, 0, 294, D("float(string name)", "Checks to see if the supplied name is a valid command, cvar, or alias. Returns 0 if it does not exist.")}, {"checkcommand", PF_checkcommand, 0, 0, 0, 294, D("float(string name)", "Checks to see if the supplied name is a valid command, cvar, or alias. Returns 0 if it does not exist.")},
{"argescape", PF_argescape, 0, 0, 0, 295, D("string(string s)", "Marks up a string so that it can be reliably tokenized as a single argument later.")},
{"clearscene", PF_Fixme, 0, 0, 0, 300, D("void()", "Forgets all rentities, polygons, and temporary dlights. Resets all view properties to their default values.")},// (EXT_CSQC) {"clearscene", PF_Fixme, 0, 0, 0, 300, D("void()", "Forgets all rentities, polygons, and temporary dlights. Resets all view properties to their default values.")},// (EXT_CSQC)
@ -9675,9 +9676,10 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
// {"bufstr_find", PF_Fixme, 0, 0, 0, 537, "float(float bufhandle, string match, float matchrule, float startpos)"}, // {"bufstr_find", PF_Fixme, 0, 0, 0, 537, "float(float bufhandle, string match, float matchrule, float startpos)"},
// {"matchpattern", PF_Fixme, 0, 0, 0, 538, "float(string s, string pattern, float matchrule)"}, // {"matchpattern", PF_Fixme, 0, 0, 0, 538, "float(string s, string pattern, float matchrule)"},
// {"undefined", PF_Fixme, 0, 0, 0, 539, ""}, // {"undefined", PF_Fixme, 0, 0, 0, 539, ""},
{"physics_enable", PF_Ignore, 0, 0, 0, 540, "void(entity e, float physics_enabled)" STUB},
{"physics_addforce",PF_Ignore, 0, 0, 0, 541, "void(entity e, vector force, vector relative_ofs)" STUB}, {"physics_enable", PF_physics_enable, 0, 0, 0, 540, D("void(entity e, float physics_enabled)", "Enable or disable the physics attached to a MOVETYPE_PHYSICS entity. Entities which have been disabled in this way will stop taking so much cpu time.")},
{"physics_addtorque",PF_Ignore, 0, 0, 0, 542, "void(entity e, vector torque)" STUB}, {"physics_addforce",PF_physics_addforce,0, 0, 0, 541, D("void(entity e, vector force, vector relative_ofs)", "Apply some impulse directional force upon a MOVETYPE_PHYSICS entity.")},
{"physics_addtorque",PF_physics_addtorque,0, 0, 0, 542, D("void(entity e, vector torque)", "Apply some impulse rotational force upon a MOVETYPE_PHYSICS entity.")},
{"setkeydest", PF_Fixme, 0, 0, 0, 601, "void(float dest)"}, {"setkeydest", PF_Fixme, 0, 0, 0, 601, "void(float dest)"},
{"getkeydest", PF_Fixme, 0, 0, 0, 602, "float()"}, {"getkeydest", PF_Fixme, 0, 0, 0, 602, "float()"},
@ -10529,6 +10531,11 @@ void PR_DumpPlatform_f(void)
{"VF_SCREENPSIZE", "const float", CS, "Provides a reliable way to retrieve the current physical screen size (cvars need vid_restart for them to take effect).", VF_SCREENPSIZE}, {"VF_SCREENPSIZE", "const float", CS, "Provides a reliable way to retrieve the current physical screen size (cvars need vid_restart for them to take effect).", VF_SCREENPSIZE},
{"VF_VIEWENTITY", "const float", CS, "Changes the RF_EXTERNALMODEL flag on entities to match the new selection, and removes entities flaged with RF_VIEWENTITY. Requires cunning use of .entnum and typically requires calling addentities(MASK_VIEWMODEL) too.", VF_VIEWENTITY}, {"VF_VIEWENTITY", "const float", CS, "Changes the RF_EXTERNALMODEL flag on entities to match the new selection, and removes entities flaged with RF_VIEWENTITY. Requires cunning use of .entnum and typically requires calling addentities(MASK_VIEWMODEL) too.", VF_VIEWENTITY},
{"VF_RT_DESTCOLOUR", "const float", CS, "The FrameBuffer texture index to write colour info into. 1-based. Additional arguments are: format (rgba8=1,rgba16f=2,rgba32f=3), sizexy. Written to by both 3d and 2d rendering.", VF_RT_DESTCOLOUR},
{"VF_RT_SOURCECOLOUR", "const float", CS, "The FrameBuffer texture index to use with shaders that specify a $sourcecolour map.", VF_RT_SOURCECOLOUR},
{"VF_RT_DEPTH", "const float", CS, "The FrameBuffer texture index to use as a depth buffer. Also used for shaders that specify $sourcedepth. 1-based. Additional arguments are: format (16=4,24=5,32=6), sizexy.", VF_RT_DEPTH},
{"VF_RT_RIPPLE", "const float", CS, "The FrameBuffer texture index to use as a ripplemap (target for shaders with 'sort ripple'). Also used for shaders that specify $ripplemap. 1-based. Additional arguments are: format, sizexy.", VF_RT_RIPPLE},
{"RF_VIEWMODEL", "const float", CS, "Specifies that the entity is a view model, and that its origin is relative to the current view position. These entities are also subject to viewweapon bob.", CSQCRF_VIEWMODEL}, {"RF_VIEWMODEL", "const float", CS, "Specifies that the entity is a view model, and that its origin is relative to the current view position. These entities are also subject to viewweapon bob.", CSQCRF_VIEWMODEL},
{"RF_EXTERNALMODEL", "const float", CS, "Specifies that this entity should be displayed in mirrors (and may still cast shadows), but will not otherwise be visible.", CSQCRF_EXTERNALMODEL}, {"RF_EXTERNALMODEL", "const float", CS, "Specifies that this entity should be displayed in mirrors (and may still cast shadows), but will not otherwise be visible.", CSQCRF_EXTERNALMODEL},
{"RF_DEPTHHACK", "const float", CS, "Hacks the depth values such that the entity uses depth values as if it were closer to the screen. This is useful when combined with viewmodels to avoid weapons poking in to walls.", CSQCRF_DEPTHHACK}, {"RF_DEPTHHACK", "const float", CS, "Hacks the depth values such that the entity uses depth values as if it were closer to the screen. This is useful when combined with viewmodels to avoid weapons poking in to walls.", CSQCRF_DEPTHHACK},

View file

@ -207,6 +207,7 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldvector(gravitydir,NULL)\ comfieldvector(gravitydir,NULL)\
comfieldfunction(camera_transform,".vector(vector org, vector ang)", NULL)\ comfieldfunction(camera_transform,".vector(vector org, vector ang)", NULL)\
comfieldfloat(pmove_flags,NULL)/*EXT_CSQC_1*/\ comfieldfloat(pmove_flags,NULL)/*EXT_CSQC_1*/\
comfieldfloat(geomtype,NULL)/*DP_...PHYSICS*/\
comfieldfloat(friction,NULL)/*DP_...PHYSICS*/\ comfieldfloat(friction,NULL)/*DP_...PHYSICS*/\
comfieldfloat(erp,NULL)/*DP_...PHYSICS*/\ comfieldfloat(erp,NULL)/*DP_...PHYSICS*/\
comfieldfloat(jointtype,NULL)/*DP_...PHYSICS*/\ comfieldfloat(jointtype,NULL)/*DP_...PHYSICS*/\
@ -240,21 +241,21 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldvector(color,NULL)/*Hexen2 has a .float color, the warnings should be benign*/ \ comfieldvector(color,NULL)/*Hexen2 has a .float color, the warnings should be benign*/ \
comfieldfloat(light_lev,NULL)\ comfieldfloat(light_lev,NULL)\
comfieldfloat(style,NULL)\ comfieldfloat(style,NULL)\
comfieldfloat(pflags,NULL)\ comfieldfloat(pflags,"Realtime lighting flags")\
comfieldfloat(clientcolors,NULL)\ comfieldfloat(clientcolors,NULL)\
comfieldfloat(dimension_see,NULL)/*EXT_DIMENSION_VISIBLE*/\ comfieldfloat(dimension_see,"This is the dimension mask (bitfield) that the client is allowed to see. Entities and events not in this dimension mask will be invisible.")/*EXT_DIMENSION_VISIBLE*/\
comfieldfloat(dimension_seen,NULL)/*EXT_DIMENSION_VISIBLE*/\ comfieldfloat(dimension_seen,"This is the dimension mask (bitfield) that the client is visible within. Clients that cannot see this dimension mask will not see this entity.")/*EXT_DIMENSION_VISIBLE*/\
comfieldfloat(dimension_ghost,NULL)/*EXT_DIMENSION_GHOST*/\ comfieldfloat(dimension_ghost,"If this entity is visible only within these dimensions, it will become transparent, as if a ghost.")/*EXT_DIMENSION_GHOST*/\
comfieldfloat(dimension_ghost_alpha,NULL)/*EXT_DIMENSION_GHOST*/\ comfieldfloat(dimension_ghost_alpha,"If this entity is subject to dimension_ghost, this is the scaler for its alpha value. If 0, 0.5 will be used instead.")/*EXT_DIMENSION_GHOST*/\
comfieldfloat(playerclass,NULL)/*hexen2 requirements*/\ comfieldfloat(playerclass,NULL)/*hexen2 requirements*/\
comfieldfloat(drawflags,NULL)/*hexen2*/\ comfieldfloat(drawflags,NULL)/*hexen2*/\
comfieldfloat(hasted,NULL)/*hexen2 uses this AS WELL as maxspeed*/\ comfieldfloat(hasted,NULL)/*hexen2 uses this AS WELL as maxspeed*/\
comfieldfloat(light_level,NULL)/*hexen2's grabbing light level from client*/\ comfieldfloat(light_level,NULL)/*hexen2's grabbing light level from client*/\
comfieldfloat(abslight,NULL)/*hexen2's force a lightlevel*/\ comfieldfloat(abslight,"Allows overriding light levels. Use drawflags to state that this field should actually be used.")/*hexen2's force a lightlevel*/\
comfieldfunction(SendEntity, ".float(entity playerent, float changedflags)",NULL)/*EXT_CSQC*/\ comfieldfunction(SendEntity, ".float(entity playerent, float changedflags)",NULL)/*EXT_CSQC*/\
comfieldfloat(SendFlags,NULL)/*EXT_CSQC_1 (one of the DP guys came up with it)*/\ comfieldfloat(SendFlags,NULL)/*EXT_CSQC_1 (one of the DP guys came up with it)*/\
comfieldfloat(Version,NULL)/*EXT_CSQC (obsolete)*/\ comfieldfloat(Version,"Obsolete")/*EXT_CSQC (obsolete)*/\
comfieldfloat(pvsflags,NULL)/*EXT_CSQC_1*/\ comfieldfloat(pvsflags,"Reconfigures when the entity is visible to clients")/*EXT_CSQC_1*/\
comfieldfloat(modelflags,NULL)\ comfieldfloat(modelflags,NULL)\
comfieldfloat(uniquespawnid,NULL)/*FTE_ENT_UNIQUESPAWNID*/\ comfieldfloat(uniquespawnid,NULL)/*FTE_ENT_UNIQUESPAWNID*/\
comfieldfunction(customizeentityforclient, ".float()",NULL) comfieldfunction(customizeentityforclient, ".float()",NULL)
@ -379,7 +380,7 @@ typedef struct
int orientpeer; int orientpeer;
//ode info //ode info
int shape; int geomshape;
vec3_t dimensions; vec3_t dimensions;
float mass; float mass;
} odebodyinfo_t; } odebodyinfo_t;
@ -411,6 +412,21 @@ typedef struct
vec3_t axis, axis2; vec3_t axis, axis2;
} odejointinfo_t; } odejointinfo_t;
typedef struct odecommandqueue_s
{
struct odecommandqueue_s *next;
enum
{
ODECMD_ENABLE,
ODECMD_DISABLE,
ODECMD_FORCE,
ODECMD_TORQUE,
} command;
struct wedict_s *edict;
vec3_t v1;
vec3_t v2;
} odecommandqueue_t;
typedef struct typedef struct
{ {
// physics parameters // physics parameters
@ -469,5 +485,7 @@ typedef struct
// max velocity for a 1-unit radius object at current step to prevent // max velocity for a 1-unit radius object at current step to prevent
// missed collisions // missed collisions
vec_t ode_movelimit; vec_t ode_movelimit;
odecommandqueue_t *cmdqueuehead;
odecommandqueue_t *cmdqueuetail;
} worldode_t; } worldode_t;
#endif #endif

View file

@ -834,7 +834,7 @@ typedef struct
#define SOLID_BSP 4 // bsp clip, touch on edge, block #define SOLID_BSP 4 // bsp clip, touch on edge, block
#define SOLID_PHASEH2 5 #define SOLID_PHASEH2 5
#define SOLID_CORPSE 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_LADDER 20 //dmw. touch on edge, not blocking. Touching players have different physics. Otherwise a SOLID_TRIGGER. deprecated. use solid_bsp and skin=-16
#define DAMAGE_NO 0 #define DAMAGE_NO 0
#define DAMAGE_YES 1 #define DAMAGE_YES 1
@ -1266,7 +1266,11 @@ void SV_ConSay_f(void);
//this header gives supported version numbers and stuff //this header gives supported version numbers and stuff
typedef struct mvdpendingdest_s { typedef struct mvdpendingdest_s {
qboolean error; //disables writers, quit ASAP. qboolean error; //disables writers, quit ASAP.
#ifdef _WIN32
qintptr_t socket;
#else
int socket; int socket;
#endif
char inbuffer[2048]; char inbuffer[2048];
char outbuffer[2048]; char outbuffer[2048];

Some files were not shown because too many files have changed in this diff Show more