Move Quake3 support to a plugin. There's still a number of stubs+bugs.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6209 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2022-03-08 05:31:34 +00:00
parent dd9bdab8dc
commit 6ceb76233c
101 changed files with 4173 additions and 3924 deletions

View File

@ -550,7 +550,6 @@ SET(FTE_COMMON_FILES
engine/common/pr_bgcmd.c
engine/common/q1bsp.c
engine/common/q2pmove.c
engine/common/q3common.c
engine/common/qvm.c
engine/common/sha1.c
engine/common/sha2.c
@ -572,7 +571,6 @@ SET(FTE_COMMON_FILES
engine/client/client.h
engine/client/cl_ignore.h
engine/client/cl_master.h
engine/client/clq3defs.h
engine/client/input.h
engine/client/keys.h
engine/client/menu.h
@ -629,11 +627,9 @@ SET(FTE_COMMON_FILES
engine/qclib/progtype.h
engine/qclib/qcc.h
engine/qclib/qcd.h
engine/server/botlib.h
engine/server/progdefs.h
engine/server/progs.h
engine/server/q2game.h
engine/server/q3g_public.h
engine/server/server.h
#engine/server/svhl_gcapi.h
engine/server/sv_sql.h
@ -688,13 +684,11 @@ SET(FTE_SERVER_FILES
# engine/server/svhl_world.c
engine/server/svq2_ents.c
engine/server/svq2_game.c
engine/server/svq3_game.c
)
#these files are only in the client
SET(FTE_CLIENT_FILES
engine/client/cl_cam.c
engine/client/cl_cg.c
engine/client/cl_demo.c
engine/client/cl_ents.c
engine/client/cl_ignore.c
@ -704,11 +698,9 @@ SET(FTE_CLIENT_FILES
engine/client/cl_pred.c
engine/client/cl_screen.c
engine/client/cl_tent.c
engine/client/cl_ui.c
# engine/client/clhl_game.c
engine/client/clq2_cin.c
engine/client/clq2_ents.c
engine/client/clq3_parse.c
engine/client/console.c
engine/client/fragstats.c
engine/client/image.c
@ -767,42 +759,73 @@ SET(FTE_CLIENT_FILES
${FTE_VK_FILES}
)
SET(FTE_LIB_Q3BOT true CACHE BOOL "Compile Q3 Bot library.")
IF(FTE_LIB_Q3BOT)
ADD_LIBRARY(fteq3bot MODULE
engine/botlib/be_aas_bspq3.c
engine/botlib/be_aas_entity.c
engine/botlib/be_aas_move.c
engine/botlib/be_aas_routealt.c
engine/botlib/be_ai_char.c
engine/botlib/be_ai_goal.c
engine/botlib/be_ai_weight.c
engine/botlib/l_crc.c
engine/botlib/l_memory.c
engine/botlib/l_struct.c
engine/botlib/be_aas_cluster.c
engine/botlib/be_aas_file.c
engine/botlib/be_aas_optimize.c
engine/botlib/be_aas_route.c
engine/botlib/be_ai_chat.c
engine/botlib/be_ai_move.c
engine/botlib/be_ea.c
engine/botlib/l_libvar.c
engine/botlib/l_precomp.c
engine/botlib/be_aas_debug.c
engine/botlib/be_aas_main.c
engine/botlib/be_aas_reach.c
engine/botlib/be_aas_sample.c
engine/botlib/be_ai_gen.c
engine/botlib/be_ai_weap.c
engine/botlib/be_interface.c
engine/botlib/l_log.c
engine/botlib/l_script.c
engine/botlib/standalone.c
)
SET_TARGET_PROPERTIES(fteq3bot PROPERTIES COMPILE_DEFINITIONS "${FTE_LIB_DEFINES};${FTE_DEFINES};${FTE_REVISON};BOTLIB;EXTERNALBOTLIB")
TARGET_LINK_LIBRARIES(fteq3bot ${FTE_LIBS} )
SET_TARGET_PROPERTIES(fteq3bot PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
SET(FTE_BOTLIB_FILES
engine/botlib/be_aas_bspq3.c
engine/botlib/be_aas_entity.c
engine/botlib/be_aas_move.c
engine/botlib/be_aas_routealt.c
engine/botlib/be_ai_char.c
engine/botlib/be_ai_goal.c
engine/botlib/be_ai_weight.c
engine/botlib/l_crc.c
engine/botlib/l_memory.c
engine/botlib/l_struct.c
engine/botlib/be_aas_cluster.c
engine/botlib/be_aas_file.c
engine/botlib/be_aas_optimize.c
engine/botlib/be_aas_route.c
engine/botlib/be_ai_chat.c
engine/botlib/be_ai_move.c
engine/botlib/be_ea.c
engine/botlib/l_libvar.c
engine/botlib/l_precomp.c
engine/botlib/be_aas_debug.c
engine/botlib/be_aas_main.c
engine/botlib/be_aas_reach.c
engine/botlib/be_aas_sample.c
engine/botlib/be_ai_gen.c
engine/botlib/be_ai_weap.c
engine/botlib/be_interface.c
engine/botlib/l_log.c
engine/botlib/l_script.c
engine/botlib/standalone.c
)
SET(FTE_Q3_FILES
${FTE_BOTLIB_FILES}
engine/client/cl_cg.c
engine/client/cl_ui.c
engine/client/clq3_parse.c
engine/server/svq3_game.c
engine/common/q3common.c
engine/common/q3common.h
engine/client/clq3defs.h
engine/server/q3g_public.h
)
SET(FTE_PLUG_QUAKE3 true CACHE BOOL "Compile Quake3 plugin.")
IF(FTE_PLUG_QUAKE3)
IF (0)
SET(FTE_DEFINES ${FTE_DEFINES};${Q3_DEFINES})
SET(FTE_LIBS ${FTE_LIBS} quake3)
#define the modules and make sure they're linked (one generic, one for server-only builds.
ADD_LIBRARY(quake3 STATIC ${FTE_Q3_FILES})
SET_TARGET_PROPERTIES(quake3 PROPERTIES COMPILE_DEFINITIONS "${FTE_LIB_DEFINES};${FTE_REVISON};BOTLIB;BOTLIB_STATIC;FTEPLUGIN;STATIC_Q3")
TARGET_LINK_LIBRARIES(quake3 m)
#ADD_LIBRARY(q3sv STATIC EXCLUDE_FROM_ALL ${FTE_Q3_FILES})
#SET_TARGET_PROPERTIES(q3sv PROPERTIES COMPILE_DEFINITIONS "${FTE_LIB_DEFINES};${FTE_REVISON};BOTLIB;BOTLIB_STATIC;SERVERONLY")
#SET_TARGET_PROPERTIES(q3sv PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
#TARGET_LINK_LIBRARIES(q3sv m)
#SET(FTESV_LIBS ${FTESV_LIBS} q3sv)
ELSE()
#define the modules and make sure they're linked (one generic, one for server-only builds.
ADD_LIBRARY(plug_quake3 MODULE ${FTE_Q3_FILES} plugins/plugin.c)
SET_TARGET_PROPERTIES(plug_quake3 PROPERTIES COMPILE_DEFINITIONS "${FTE_LIB_DEFINES};${FTE_REVISON};BOTLIB;BOTLIB_STATIC;FTEPLUGIN")
TARGET_LINK_LIBRARIES(plug_quake3 m)
EMBED_PLUGIN_META(quake3 "Quake3 Compat" "Provides compatability with Quake3's gamecode.")
ENDIF()
ENDIF()
FILE(STRINGS "${FTE_BUILD_CONFIG}" BULLET_INTERNAL REGEX "^#define[\t ]+USE_INTERNAL_BULLET")
@ -1537,4 +1560,4 @@ IF(FTE_MENU_SYS)
quakec/menusys/menu/options_video.qc
quakec/menusys/menu/quit.qc
)
ENDIF()
ENDIF()

View File

@ -646,7 +646,7 @@ endif
SDL_INCLUDES=
#-I$(LIBS_DIR)/sdl/include -I/usr/include/SDL -I$(LIBS_DIR)/sdl/include/SDL
BASE_INCLUDES=-I$(CLIENT_DIR) -I$(SERVER_DIR) -I$(COMMON_DIR) -I$(GL_DIR) -I$(D3D_DIR) -I$(PROGS_DIR) -I.
BASE_CFLAGS=$(WARNINGFLAGS) $(GNUC_FUNCS) $(BASE_INCLUDES) -I$(LIBS_DIR)/dxsdk9/include -I$(LIBS_DIR)/dxsdk7/include $(SDL_INCLUDES) $(BOTLIB_CFLAGS) $(SVNREVISION)
BASE_CFLAGS=$(WARNINGFLAGS) $(GNUC_FUNCS) $(BASE_INCLUDES) -I$(LIBS_DIR)/dxsdk9/include -I$(LIBS_DIR)/dxsdk7/include $(SDL_INCLUDES) $(SVNREVISION)
CLIENT_ONLY_CFLAGS=-DCLIENTONLY
SERVER_ONLY_CFLAGS=-DSERVERONLY
JOINT_CFLAGS=
@ -737,10 +737,7 @@ CLIENT_OBJS = \
cl_cam.o \
cl_screen.o \
pr_clcmd.o \
cl_ui.o \
cl_ignore.o \
cl_cg.o \
clq3_parse.o \
pr_csqc.o \
console.o \
image.o \
@ -874,7 +871,6 @@ SERVER_OBJS = \
savegame.o \
svq2_ents.o \
svq2_game.o \
svq3_game.o \
webgen.o \
ftpserver.o \
httpserver.o
@ -937,7 +933,6 @@ COMMON_OBJS = \
r_d3.o \
gl_q2bsp.o \
glmod_doom.o \
q3common.o \
world.o \
sv_phys.o \
sv_move.o \
@ -952,6 +947,11 @@ COMMON_OBJS = \
ifeq (1,$(USE_BOTLIB))
BOTLIB_CFLAGS=-I$(BOTLIB_DIR) -DBOTLIB -DBOTLIB_STATIC
BOTLIB_OBJS = \
clq3_parse.o \
cl_ui.o \
cl_cg.o \
svq3_game.o \
q3common.o \
be_aas_bspq3.o \
be_aas_cluster.o \
be_aas_debug.o \
@ -1062,7 +1062,7 @@ endif
SDLCONFIG?=sdl-config
FTE_FULLTARGET?=sdl$(FTE_TARGET)$(BITS)
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o
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=../$(EXE_NAME)-gl$(FTE_FULLTARGET)
GLCL_EXE_NAME=../$(EXE_NAME)cl-gl$(FTE_FULLTARGET)
@ -1083,14 +1083,14 @@ GLB_DIR=gl_$(FTE_FULLTARGET)
GLCL_DIR=glcl_$(FTE_FULLTARGET)
SV_DIR?=sv_$(FTE_FULLTARGET)
VKCL_OBJS=$(VKQUAKE_OBJS) $(D3DGL_OBJS) gl_bloom.o $(BOTLIB_OBJS) gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o
VKCL_OBJS=$(VKQUAKE_OBJS) $(D3DGL_OBJS) gl_bloom.o gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o
VK_CFLAGS=-DFTE_SDL $(VKCFLAGS) -DMULTITHREAD `$(SDLCONFIG) --cflags`
VKB_DIR=vk_$(FTE_FULLTARGET)
VKCL_DIR=vk_$(FTE_FULLTARGET)
VK_EXE_NAME=../$(EXE_NAME)-vk$(FTE_FULLTARGET)
VKCL_EXE_NAME=../$(EXE_NAME)-vkcl$(FTE_FULLTARGET)
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(SERVERONLY_OBJS) $(BOTLIB_OBJS)
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(SERVERONLY_OBJS)
SV_EXE_NAME=../$(EXE_NAME)-sv$(FTE_FULLTARGET)
SV_CFLAGS=-DFTE_SDL -DMULTITHREAD `$(SDLCONFIG) --cflags` $(SERVER_ONLY_CFLAGS)
@ -1101,7 +1101,7 @@ MB_DIR=m_$(FTE_FULLTARGET)
MCL_DIR=mcl_$(FTE_FULLTARGET)
M_EXE_NAME=../$(EXE_NAME)-$(FTE_FULLTARGET)
MCL_EXE_NAME=../$(EXE_NAME)-cl$(FTE_FULLTARGET)
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(BOTLIB_OBJS) gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o
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=-DFTE_SDL $(VKCFLAGS) $(GLCFLAGS) -DMULTITHREAD `$(SDLCONFIG) --cflags`
QCC_DIR=qcc$(BITS)
@ -1170,7 +1170,7 @@ ifeq ($(FTE_TARGET),nacl)
GL_CFLAGS+=-I$(realpath $(NACL_SDK_ROOT)/include)
BASELDFLAGS+=-L$(realpath $(NACL_SDK_ROOT)/lib/$(NACLLIBS))
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) sys_ppapi.o cd_null.o gl_vidppapi.o fs_ppapi.o snd_ppapi.o
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) sys_ppapi.o cd_null.o gl_vidppapi.o fs_ppapi.o snd_ppapi.o
GL_LDFLAGS=$(GLLDFLAGS)
M_LDFLAGS=$(GLLDFLAGS)
@ -1204,7 +1204,7 @@ ifeq (win_SDL,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET)))
ARCH_CFLAGS=`$(SDLCONFIG) --cflags`
#the defaults for sdl come first
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o snd_directx.o $(LTO_END) resources.o $(LTO_START)
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o snd_directx.o $(LTO_END) resources.o $(LTO_START)
GL_EXE_NAME=../$(EXE_NAME)-sdl-gl$(BITS)$(EXEPOSTFIX)
GLCL_EXE_NAME=../$(EXE_NAME)-sdl-glcl$(BITS)$(EXEPOSTFIX)
ifdef windir
@ -1226,7 +1226,7 @@ ifeq (win_SDL,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET)))
GLB_DIR=gl_mgw_sdl$(BITS)
GLCL_DIR=glcl_mgw_sdl$(BITS)
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(WINDOWSSERVERONLY_OBJS) $(BOTLIB_OBJS) $(LTO_END) resources.o $(LTO_START)
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(WINDOWSSERVERONLY_OBJS) $(LTO_END) resources.o $(LTO_START)
SV_EXE_NAME=../$(EXE_NAME)-sdl-sv$(BITS)$(EXEPOSTFIX)
SV_CFLAGS=$(SERVER_ONLY_CFLAGS) -DFTE_SDL
@ -1236,13 +1236,13 @@ ifeq (win_SDL,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET)))
MB_DIR=m_mgw_sdl$(BITS)
M_EXE_NAME=../$(EXE_NAME)-sdl$(BITS)$(EXEPOSTFIX)
#with d3d...
#MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(D3DQUAKE_OBJS) $(BOTLIB_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) 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) $(VKCFLAGS) $(GLCFLAGS) -DFTE_SDL $(CLIENTLIBFLAGS) $(DX7SDK)
#without d3d...
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(BOTLIB_OBJS) gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o snd_directx.o $(LTO_END) resources.o $(LTO_START)
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_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=$(VKCFLAGS) $(GLCFLAGS) -DFTE_SDL $(CLIENTLIBFLAGS) $(DX7SDK)
D3DCL_OBJS=$(D3DQUAKE_OBJS) $(BOTLIB_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) 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=../$(EXE_NAME)-sdl-d3d$(BITS)$(EXEPOSTFIX)
D3DCL_EXE_NAME=../$(EXE_NAME)-sdl-d3dcl$(BITS)$(EXEPOSTFIX)
D3D_LDFLAGS=$(IMAGELDFLAGS) -lws2_32 -lmingw32 $(SDL_LDFLAGS) -mwindows -ldxguid -lwinmm -lole32
@ -1251,7 +1251,7 @@ ifeq (win_SDL,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET)))
D3DCL_DIR=sdl_d3dcl_mgw$(BITS)
VKCL_OBJS=$(VKQUAKE_OBJS) $(BOTLIB_OBJS) gl_bloom.o gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o snd_directx.o $(D3DGL_OBJS) $(LTO_END) resources.o $(LTO_START)
VKCL_OBJS=$(VKQUAKE_OBJS) gl_bloom.o gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o snd_directx.o $(D3DGL_OBJS) $(LTO_END) resources.o $(LTO_START)
VK_EXE_NAME=../$(EXE_NAME)-sdl-vk$(BITS)$(EXEPOSTFIX)
VKCL_EXE_NAME=../$(EXE_NAME)-sdl-vkcl$(BITS)$(EXEPOSTFIX)
VK_CFLAGS=$(VKCFLAGS) -DFTE_SDL -DNO_XFLIP $(CLIENTLIBFLAGS) $(DX7SDK)
@ -1358,7 +1358,7 @@ ifeq ($(findstring msvc,$(FTE_TARGET)),msvc)
SV_CFLAGS=$(SERVER_ONLY_CFLAGS) $(W32_CFLAGS) -DMULTITHREAD -DMSVCLIBPATH=libs/
SV_EXE_NAME=../$(EXE_NAME)-sv$(BITS)$(EXEPOSTFIX)
SV_DIR=sv_vc$(BITS)
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(BOTLIB_OBJS) $(PROGS_OBJS) $(WINDOWSSERVERONLY_OBJS) fs_win32.o resources.o
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(WINDOWSSERVERONLY_OBJS) fs_win32.o resources.o
SV_LDFLAGS=ole32.lib /subsystem:console
GL_EXE_NAME=../$(EXE_NAME)-gl$(BITS)$(EXEPOSTFIX)
@ -1367,13 +1367,13 @@ ifeq ($(findstring msvc,$(FTE_TARGET)),msvc)
GLCL_DIR=glcl_vc$(BITS)
GL_LDFLAGS=$(GLLDFLAGS) $(JPEGLIB) libs/libpng$(BITS).lib uuid.lib gdi32.lib ole32.lib /subsystem:windows
GL_CFLAGS=$(GLCFLAGS) $(W32_CFLAGS) -DMULTITHREAD -DMSVCLIBPATH=libs/
GLCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) gl_vidnt.o $(WINDOWS_OBJS)
GLCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) gl_vidnt.o $(WINDOWS_OBJS)
GL_OBJS=
MINGL_DIR=mingl_vc$(BITS)
MINGL_EXE_NAME=../$(EXE_NAME)-mingl$(BITS)$(EXEPOSTFIX)
VKCL_OBJS=$(VKQUAKE_OBJS) $(D3DGL_OBJS) $(BOTLIB_OBJS) gl_bloom.o gl_vidnt.o $(WINDOWS_OBJS)
VKCL_OBJS=$(VKQUAKE_OBJS) $(D3DGL_OBJS) gl_bloom.o gl_vidnt.o $(WINDOWS_OBJS)
VK_EXE_NAME=../$(EXE_NAME)-vk$(BITS)$(EXEPOSTFIX)
VKCL_EXE_NAME=../$(EXE_NAME)-vkcl$(BITS)$(EXEPOSTFIX)
VK_CFLAGS=$(VKCFLAGS) $(CLIENTLIBFLAGS) $(DX7SDK) -DMULTITHREAD -DMSVCLIBPATH=libs/
@ -1381,7 +1381,7 @@ ifeq ($(findstring msvc,$(FTE_TARGET)),msvc)
VKB_DIR=vk_vc$(BITS)
VKCL_DIR=vkcl_vc$(BITS)
D3DCL_OBJS=$(D3DQUAKE_OBJS) $(D3DGL_OBJS) $(BOTLIB_OBJS) $(WINDOWS_OBJS)
D3DCL_OBJS=$(D3DQUAKE_OBJS) $(D3DGL_OBJS) $(WINDOWS_OBJS)
D3D_EXE_NAME=../$(EXE_NAME)-d3d$(BITS)$(EXEPOSTFIX)
D3DCL_EXE_NAME=../$(EXE_NAME)-d3dcl$(BITS)$(EXEPOSTFIX)
D3D_LDFLAGS=$(JPEGLIB) libs/libpng$(BITS).lib uuid.lib gdi32.lib ole32.lib /subsystem:windows
@ -1390,7 +1390,7 @@ ifeq ($(findstring msvc,$(FTE_TARGET)),msvc)
D3DCL_DIR=d3dcl_vc$(BITS)
#merged client stuff
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(D3DQUAKE_OBJS) $(BOTLIB_OBJS) gl_vidnt.o gl_videgl.o $(WINDOWS_OBJS)
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(D3DQUAKE_OBJS) gl_vidnt.o gl_videgl.o $(WINDOWS_OBJS)
M_EXE_NAME=../$(EXE_NAME)$(BITS)$(EXEPOSTFIX)
MCL_EXE_NAME=../$(EXE_NAME)cl$(BITS)$(EXEPOSTFIX)
M_CFLAGS=$(GLCFLAGS) $(W32_CFLAGS) $(D3DCFLAGS) $(DX7SDK) $(VKCFLAGS) -DMULTITHREAD $(CLIENTLIBFLAGS)
@ -1436,11 +1436,11 @@ ifeq (win,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET)))
SV_EXE_NAME=../$(EXE_NAME)sv$(BITS)$(EXEPOSTFIX)
SV_LDFLAGS=-lws2_32 -lwinmm -lole32
SV_DIR=sv_mingw$(BITS)
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(WINDOWSSERVERONLY_OBJS) $(BOTLIB_OBJS) fs_win32.o $(LTO_END) resources.o $(LTO_START)
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(WINDOWSSERVERONLY_OBJS) fs_win32.o $(LTO_END) resources.o $(LTO_START)
SV_CFLAGS=$(SERVER_ONLY_CFLAGS) $(W32_CFLAGS)
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) gl_vidnt.o $(WINDOWS_OBJS)
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) gl_vidnt.o $(WINDOWS_OBJS)
GL_EXE_NAME=../fteglqw$(BITS)$(EXEPOSTFIX)
GLCL_EXE_NAME=../fteglqwcl$(BITS)$(EXEPOSTFIX)
GL_LDFLAGS=$(GLLDFLAGS) $(IMAGELDFLAGS) -ldxguid -lws2_32 -lwinmm -lgdi32 -lole32 -Wl,--subsystem,windows
@ -1454,7 +1454,7 @@ ifeq (win,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET)))
NPFTE_CFLAGS=$(NPFTECFLAGS) $(W32_CFLAGS) -DMULTITHREAD
NPFTEB_DIR=npfte_mgw$(BITS)
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(D3DQUAKE_OBJS) $(BOTLIB_OBJS) gl_vidnt.o gl_videgl.o $(WINDOWS_OBJS)
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(D3DQUAKE_OBJS) gl_vidnt.o gl_videgl.o $(WINDOWS_OBJS)
M_EXE_NAME=../$(EXE_NAME)$(BITS)$(EXEPOSTFIX)
MCL_EXE_NAME=../$(EXE_NAME)cl$(BITS)$(EXEPOSTFIX)
M_LDFLAGS=$(GLLDFLAGS) $(IMAGELDFLAGS) -ldxguid -lws2_32 -lwinmm -lgdi32 -lole32 -Wl,--subsystem,windows
@ -1462,7 +1462,7 @@ ifeq (win,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET)))
MB_DIR=m_mgw$(BITS)
MCL_DIR=mcl_mgw$(BITS)
D3DCL_OBJS=$(D3DQUAKE_OBJS) $(D3DGL_OBJS) $(BOTLIB_OBJS) $(WINDOWS_OBJS)
D3DCL_OBJS=$(D3DQUAKE_OBJS) $(D3DGL_OBJS) $(WINDOWS_OBJS)
D3D_EXE_NAME=../fted3dqw$(BITS)$(EXEPOSTFIX)
D3DCL_EXE_NAME=../fted3dclqw$(BITS)$(EXEPOSTFIX)
D3D_LDFLAGS=$(IMAGELDFLAGS) -ldxguid -lws2_32 -lwinmm -lgdi32 -lole32 -Wl,--subsystem,windows
@ -1470,7 +1470,7 @@ ifeq (win,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET)))
D3DB_DIR=d3d_mgw$(BITS)
D3DCL_DIR=d3dcl_mgw$(BITS)
VKCL_OBJS=$(GLQUAKE_OBJS) $(D3DGL_OBJS) $(BOTLIB_OBJS) $(WINDOWS_OBJS) gl_vidnt.o
VKCL_OBJS=$(GLQUAKE_OBJS) $(D3DGL_OBJS) $(WINDOWS_OBJS) gl_vidnt.o
VK_EXE_NAME=../ftevkqw$(BITS)$(EXEPOSTFIX)
VKCL_EXE_NAME=../ftevkclqw$(BITS)$(EXEPOSTFIX)
VK_LDFLAGS=$(IMAGELDFLAGS) -ldxguid -lws2_32 -lwinmm -lgdi32 -lole32 -Wl,--subsystem,windows
@ -1508,7 +1508,7 @@ ifeq ($(FTE_TARGET),bsd)
SV_LDFLAGS=-lpthread
SV_CFLAGS=$(SERVER_ONLY_CFLAGS) -DMULTITHREAD
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o sys_linux_threads.o
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o sys_linux_threads.o
GL_EXE_NAME=../$(EXE_NAME)-gl
GLCL_EXE_NAME=../$(EXE_NAME)-glcl
GL_LDFLAGS= -L/usr/local/lib $(GLLDFLAGS) $(XLDFLAGS) -lpthread
@ -1516,7 +1516,7 @@ ifeq ($(FTE_TARGET),bsd)
GLB_DIR=gl_bsd
GLCL_DIR=glcl_bsd
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(BOTLIB_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o sys_linux_threads.o
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o sys_linux_threads.o
M_EXE_NAME=../$(EXE_NAME)
MCL_EXE_NAME=../$(EXE_NAME)-cl
M_LDFLAGS= -L/usr/local/lib -L/usr/X11R6/lib $(GLLDFLAGS) $(XLDFLAGS) -lpthread
@ -1577,7 +1577,7 @@ ifneq (,$(findstring linux,$(FTE_TARGET)))
NPFTE_CFLAGS=$(NPFTECFLAGS) $(W32_CFLAGS) -DMULTITHREAD -fPIC -DDYNAMIC_LIBPNG -DDYNAMIC_LIBJPEG
NPFTEB_DIR=npfte_linux$(BITS)
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) gl_vidlinuxglx.o gl_vidwayland.o gl_videgl.o snd_pulse.o snd_alsa.o snd_linux.o snd_sdl.o cd_linux.o sys_linux.o sys_linux_threads.o
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) gl_vidlinuxglx.o gl_vidwayland.o gl_videgl.o snd_pulse.o snd_alsa.o snd_linux.o snd_sdl.o cd_linux.o sys_linux.o sys_linux_threads.o
GL_EXE_NAME=../$(EXE_NAME)-gl$(BITS)
GLCL_EXE_NAME=../$(EXE_NAME)-glcl$(BITS)
GL_LDFLAGS=$(GLLDFLAGS) $(XLDFLAGS)
@ -1585,7 +1585,7 @@ ifneq (,$(findstring linux,$(FTE_TARGET)))
GLB_DIR=gl_linux$(BITS)
GLCL_DIR=glcl_linux$(BITS)
VKCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) gl_vidlinuxglx.o gl_vidwayland.o gl_videgl.o snd_pulse.o snd_alsa.o snd_linux.o snd_sdl.o cd_linux.o sys_linux.o sys_linux_threads.o
VKCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) gl_vidlinuxglx.o gl_vidwayland.o gl_videgl.o snd_pulse.o snd_alsa.o snd_linux.o snd_sdl.o cd_linux.o sys_linux.o sys_linux_threads.o
VK_EXE_NAME=../$(EXE_NAME)-vk$(BITS)
VKCL_EXE_NAME=../$(EXE_NAME)-vkcl$(BITS)
VK_LDFLAGS=$(GLLDFLAGS) $(XLDFLAGS)
@ -1593,7 +1593,7 @@ ifneq (,$(findstring linux,$(FTE_TARGET)))
VKB_DIR=vk_linux$(BITS)
VKCL_DIR=vkcl_linux$(BITS)
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(BOTLIB_OBJS) gl_vidlinuxglx.o gl_vidwayland.o gl_videgl.o snd_linux.o snd_sdl.o snd_pulse.o snd_alsa.o cd_linux.o sys_linux.o sys_linux_threads.o
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidlinuxglx.o gl_vidwayland.o gl_videgl.o snd_linux.o snd_sdl.o snd_pulse.o snd_alsa.o cd_linux.o sys_linux.o sys_linux_threads.o
M_EXE_NAME=../$(EXE_NAME)$(BITS)
MCL_EXE_NAME=../$(EXE_NAME)-cl$(BITS)
M_LDFLAGS=$(GL_LDFLAGS)
@ -1648,7 +1648,7 @@ ifneq ($(shell echo $(FTE_TARGET)|grep macosx),)
endif
GL_LDFLAGS=-framework AGL -framework OpenGL -framework Cocoa -framework AudioUnit
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) gl_vidcocoa.mo gl_vidmacos.o sys_linux.o cd_null.o snd_macos.o sys_linux_threads.o
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) gl_vidcocoa.mo gl_vidmacos.o sys_linux.o cd_null.o snd_macos.o sys_linux_threads.o
GL_EXE_NAME=../$(EXE_NAME)-macosx-gl$(EXTENSION)$(BITS)
GLCL_EXE_NAME=../$(EXE_NAME)cl-macosx-gl$(EXTENSION)$(BITS)
@ -1657,7 +1657,7 @@ ifneq ($(shell echo $(FTE_TARGET)|grep macosx),)
MINGL_EXE_NAME=../$(EXE_NAME)-macosx-mingl$(EXTENSION)$(BITS)
MINGL_DIR=mingl_macosx$(EXTENSION)$(BITS)
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(BOTLIB_OBJS) $(SERVERONLY_OBJS)
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(SERVERONLY_OBJS)
SV_EXE_NAME=../$(EXE_NAME)-macosx-sv$(EXTENSION)$(BITS)
SV_CFLAGS=$(SERVER_ONLY_CFLAGS)
SV_LDFLAGS=-lz
@ -1674,7 +1674,7 @@ ifeq ($(FTE_TARGET),morphos)
SV_DIR=sv_morphos
SV_LDFLAGS=-ldl -lz
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) gl_vidmorphos.o in_morphos.o snd_morphos.o cd_null.o sys_morphos.o
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) gl_vidmorphos.o in_morphos.o snd_morphos.o cd_null.o sys_morphos.o
GL_EXE_NAME=../$(EXE_NAME)-morphos-gl
GLCL_EXE_NAME=../$(EXE_NAME)-morphos-glcl
GL_LDFLAGS=$(GLLDFLAGS) -ldl $(IMAGELDFLAGS) -lz
@ -1682,7 +1682,7 @@ ifeq ($(FTE_TARGET),morphos)
GLB_DIR=gl_morphos
GLCL_DIR=glcl_morphos
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(BOTLIB_OBJS) gl_vidmorphos.o vid_morphos.o in_morphos.o snd_morphos.o cd_null.o sys_morphos.o
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidmorphos.o vid_morphos.o in_morphos.o snd_morphos.o cd_null.o sys_morphos.o
M_EXE_NAME=../$(EXE_NAME)-morphos
MCL_EXE_NAME=../$(EXE_NAME)-morphos-cl
M_LDFLAGS=$(GLLDFLAGS)
@ -1693,7 +1693,7 @@ ifeq ($(FTE_TARGET),morphos)
MINGL_EXE_NAME=../$(EXE_NAME)-morphos-mingl
MINGL_DIR=mingl_morphos
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(SERVERONLY_OBJS) $(BOTLIB_OBJS)
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(SERVERONLY_OBJS)
SV_EXE_NAME=../$(EXE_NAME)-morphos-sv$(BITS)
SV_CFLAGS=$(SERVER_ONLY_CFLAGS)
endif
@ -1719,7 +1719,7 @@ ifeq ($(FTE_TARGET),dos)
SV_EXE_NAME=../$(EXE_NAME)sv$(BITS)$(EXEPOSTFIX)
VK_EXE_NAME=../$(EXE_NAME)-vk$(BITS)$(EXEPOSTFIX)
VKCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) cd_null.o sys_dos.o snd_sblaster.o
VKCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) cd_null.o sys_dos.o snd_sblaster.o
endif
ifeq ($(FTE_TARGET),cyg)
@ -1728,7 +1728,7 @@ ifeq ($(FTE_TARGET),cyg)
SV_CFLAGS=$(SERVER_ONLY_CFLAGS)
EXEPOSTFIX=.exe
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o sys_linux_threads.o
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o sys_linux_threads.o
GL_EXE_NAME=../$(EXE_NAME)-cyg-gl$(EXEPOSTFIX)
GLCL_EXE_NAME=../$(EXE_NAME)-cyg-glcl$(EXEPOSTFIX)
GL_LDFLAGS=$(GLLDFLAGS) $(XLDFLAGS) -lz -lltdl
@ -1736,7 +1736,7 @@ ifeq ($(FTE_TARGET),cyg)
GLB_DIR=gl_cygwin
GLCL_DIR=glcl_cygwin
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(BOTLIB_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o sys_linux_threads.o
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) gl_vidlinuxglx.o snd_linux.o cd_null.o sys_linux.o sys_linux_threads.o
M_EXE_NAME=../$(EXE_NAME)-cyg$(EXEPOSTFIX)
MCL_EXE_NAME=../$(EXE_NAME)-cyg-cl$(EXEPOSTFIX)
M_LDFLAGS=$(GLLDFLAGS) $(XLDFLAGS) -lz -lltdl
@ -1761,18 +1761,18 @@ ifeq ($(FTE_TARGET),droid)
SV_CFLAGS=$(SERVER_ONLY_CFLAGS) $(W32_CFLAGS)
SV_LDFLAGS=
SV_DIR=sv_droid-$(DROID_ARCH)
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(BOTLIB_OBJS) $(SYS_DROID_O)
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(SYS_DROID_O)
SV_EXE_NAME=libftedroid.so
GL_CFLAGS=$(GLCFLAGS)
GL_LDFLAGS=$(GLLDFLAGS) -landroid
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) $(GL_DROID_O) cd_null.o snd_droid.o
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(GL_DROID_O) cd_null.o snd_droid.o
GLB_DIR=gl_droid-$(DROID_ARCH)
GL_EXE_NAME=libftedroid.so
M_CFLAGS=$(VKCFLAGS) $(GLCFLAGS) -DMULTITHREAD
M_LDFLAGS=$(GLLDFLAGS) -landroid -lEGL -lOpenSLES
MCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) $(GL_DROID_O) cd_null.o snd_opensl.o
MCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(GL_DROID_O) cd_null.o snd_opensl.o
#snd_droid.o
MB_DIR=m_droid-$(DROID_ARCH)
M_EXE_NAME=libftedroid.so
@ -1835,7 +1835,6 @@ ifeq ($(FTE_TARGET),web)
CLIENTLDDEPS=
SERVERLDDEPS=
#BOTLIB_CFLAGS=
#generate deps properly
#DEPCC=
#DEPCXX=

View File

@ -163,6 +163,11 @@ int Q_strncasecmp (const char *s1, const char *s2, int n)
return -1;
}
int Q_strcasecmp (const char *s1, const char *s2)
{
return Q_strncasecmp (s1, s2, 0x7fffffff);
}
int QDECL Q_stricmp (const char *s1, const char *s2)
{
return Q_strncasecmp (s1, s2, 0x7fffffff);
@ -184,6 +189,7 @@ void QDECL Q_strncpyz(char *d, const char *s, int n)
*d='\0';
}
/*
char *QDECL va(char *format, ...)
{
#define VA_BUFFER_SIZE 1024
@ -196,3 +202,4 @@ char *QDECL va(char *format, ...)
return string;
}
*/

View File

@ -1,6 +1,6 @@
#include "quakedef.h"
#include "q3common.h"
//#include "cg_public.h"
#ifdef VM_CG
#if defined(VM_CG) && defined(HAVE_CLIENT)
#include "shader.h"
@ -11,23 +11,15 @@ typedef float m3by3_t[3][3];
#endif
#include "clq3defs.h"
#include "com_mesh.h"
//cl_ui.c
void CG_Command_f(void);
#define CGAME_IMPORT_API_VERSION 4
#define CGTAGNUM 5423
extern model_t *mod_known;
extern int mod_numknown;
#define VM_FROMMHANDLE(a) ((a&&((unsigned int)a)<=mod_numknown)?mod_known+a-1:NULL)
#define VM_TOMHANDLE(a) (a?a-mod_known+1:0)
#define VM_FROMSHANDLE(a) ((a&&(unsigned int)a<=r_numshaders)?r_shaders[a-1]:NULL)
#define VM_TOSHANDLE(a) (a?a->id+1:0)
static model_t *box_model;
cvar_t *cl_shownet_ptr, *cl_c2sdupe_ptr, *cl_nodelta_ptr;
typedef enum {
CG_PRINT,
@ -136,10 +128,11 @@ typedef enum {
CG_TESTPRINTFLOAT,
CG_ACOS,
CG_FTE_FINDPARTICLEEFFECT = 200,
/*CG_FTE_FINDPARTICLEEFFECT = 200,
CG_FTE_SPAWNPARTICLEEFFECT,
CG_FTE_SPAWNPARTICLETRAIL,
CG_FTE_FREEPARTICLESTATE
CG_FTE_FREEPARTICLESTATE*/
} cgameImport_t;
/*
@ -240,16 +233,19 @@ unsigned int Contents_From_Q3(unsigned int Q3)
return ret;
}
#define MAX_GAMESTATE_CHARS 16000
#define MAX_CONFIGSTRINGS 1024
typedef struct {
int stringOffsets[MAX_CONFIGSTRINGS];
char stringData[MAX_GAMESTATE_CHARS];
int stringOffsets[MAX_Q3_CONFIGSTRINGS];
char stringData[MAX_Q3_GAMESTATE_CHARS];
int dataCount;
} gameState_t;
gameState_t cggamestate;
static gameState_t cggamestate;
void CG_InsertIntoGameState(int num, char *str)
void CG_ClearGameState(void)
{
memset(&cggamestate, 0, sizeof(cggamestate));
}
void CG_InsertIntoGameState(int num, const char *str)
{
if (num < 5)
{
@ -259,24 +255,24 @@ void CG_InsertIntoGameState(int num, char *str)
if (num == CFGSTR_SYSINFO)
{
//check some things.
cl.servercount = atoi(Info_ValueForKey(str, "sv_serverid"));
ccs.servercount = atoi(worldfuncs->GetInfoKey(str, "sv_serverid"));
}
if (cggamestate.dataCount + strlen(str)+1 > MAX_GAMESTATE_CHARS)
if (cggamestate.dataCount + strlen(str)+1 > countof(cggamestate.stringData))
{
char oldstringData[MAX_GAMESTATE_CHARS];
char oldstringData[countof(cggamestate.stringData)];
int i;
char *oldstr;
//copy the old strings to a temporary buffer
memcpy(oldstringData, cggamestate.stringData, MAX_GAMESTATE_CHARS);
memcpy(oldstringData, cggamestate.stringData, countof(cggamestate.stringData));
cggamestate.dataCount = 0;
for (i = 0; i < MAX_CONFIGSTRINGS; i++)
for (i = 0; i < countof(cggamestate.stringOffsets); i++)
{
oldstr = oldstringData+cggamestate.stringOffsets[i];
if (*oldstr)
{
if (cggamestate.dataCount + strlen(oldstr)+1 > MAX_GAMESTATE_CHARS)
Host_EndGame("Too much configstring text\n");
if (cggamestate.dataCount + strlen(oldstr)+1 > countof(cggamestate.stringData))
plugfuncs->EndGame("Too much configstring text\n");
cggamestate.dataCount+=1;
strcpy(cggamestate.stringData+cggamestate.dataCount, oldstr);
@ -300,9 +296,9 @@ void CG_InsertIntoGameState(int num, char *str)
cggamestate.dataCount += strlen(str);
}
char *CG_GetConfigString(int num)
const char *CG_GetConfigString(int num)
{
if ((unsigned)num >= MAX_CONFIGSTRINGS)
if ((unsigned)num >= countof(cggamestate.stringOffsets))
return "";
return cggamestate.stringData + cggamestate.stringOffsets[num];
}
@ -316,7 +312,7 @@ int CG_GetGameState(gameState_t *gs)
static int CGQ3_GetCurrentCmdNumber(void)
{ //Q3 sequences are 1-based, so 1<=idx<=latestsequence are valid
//FTE's sequences are 0-based, so 0<=idx<latestsequence are valid
return cl.movesequence-1;
return inputfuncs->GetMoveCount()-1;
}
static qboolean CGQ3_GetUserCmd(int cmdNumber, q3usercmd_t *ucmd)
{
@ -326,14 +322,14 @@ static qboolean CGQ3_GetUserCmd(int cmdNumber, q3usercmd_t *ucmd)
usercmd_t *cmd;
//q3 does not do partials.
if (cmdNumber >= cl.movesequence)
Host_EndGame("CLQ3_GetUserCmd: %i >= %i", cmdNumber, cl.movesequence);
if (cmdNumber < 0)
return false; //grr, stoopid q3.
if (cmdNumber >= inputfuncs->GetMoveCount())
plugfuncs->EndGame("CLQ3_GetUserCmd: %i >= %i", cmdNumber, inputfuncs->GetMoveCount());
if (cl.movesequence - (cmdNumber+1) > Q3CMD_BACKUP)
cmd = inputfuncs->GetMoveEntry(cmdNumber);
if (!cmd)
return false;
//note: frames and commands are desynced in q3.
cmd = &cl.outframes[(cmdNumber) & Q3CMD_MASK].cmd[0];
ucmd->angles[0] = cmd->angles[0];
ucmd->angles[1] = cmd->angles[1];
ucmd->angles[2] = cmd->angles[2];
@ -344,16 +340,19 @@ static qboolean CGQ3_GetUserCmd(int cmdNumber, q3usercmd_t *ucmd)
ucmd->buttons = cmd->buttons;
ucmd->weapon = cmd->weapon;
return true;
}
static vm_t *cgvm;
vm_t *cgvm;
static const char *mapentspointer;
extern int keycatcher;
qboolean CG_GetServerCommand(int cmdnum)
{
static char bigconfigstring[65536];
char *arg0;
//quote from cgame code:
// get the gamestate from the client system, which will have the
@ -362,31 +361,32 @@ qboolean CG_GetServerCommand(int cmdnum)
char *str = ccs.serverCommands[cmdnum & Q3TEXTCMD_MASK];
Con_DPrintf("Dispaching %s\n", str);
Cmd_TokenizeString(str, false, false);
cmdfuncs->TokenizeString(str);
arg0 = cmdfuncs->Argv(0, NULL, 0);
if (!strcmp(Cmd_Argv(0), "bcs0"))
if (!strcmp(arg0, "bcs0"))
{ //start
Q_snprintfz(bigconfigstring, sizeof(bigconfigstring), "cs %s \"%s", Cmd_Argv(1), Cmd_Argv(2));
Q_snprintfz(bigconfigstring, sizeof(bigconfigstring), "cs %s \"%s", cmdfuncs->Argv(1, NULL, 0), cmdfuncs->Argv(2, NULL, 0));
return false;
}
if (!strcmp(Cmd_Argv(0), "bcs1"))
if (!strcmp(arg0, "bcs1"))
{ //continuation
Q_strncatz(bigconfigstring, Cmd_Argv(2), sizeof(bigconfigstring));
Q_strncatz(bigconfigstring, cmdfuncs->Argv(2, NULL, 0), sizeof(bigconfigstring));
return false;
}
if (!strcmp(Cmd_Argv(0), "bcs2"))
if (!strcmp(arg0, "bcs2"))
{ //end
Q_strncatz(bigconfigstring, Cmd_Argv(2), sizeof(bigconfigstring));
Q_strncatz(bigconfigstring, cmdfuncs->Argv(2, NULL, 0), sizeof(bigconfigstring));
Q_strncatz(bigconfigstring, "\"", sizeof(bigconfigstring));
Cmd_TokenizeString(bigconfigstring, false, false);
cmdfuncs->TokenizeString(bigconfigstring);
}
if (!strcmp(Cmd_Argv(0), "cs"))
CG_InsertIntoGameState(atoi(Cmd_Argv(1)), Cmd_Argv(2));
else if (!strcmp(Cmd_Argv(0), "map_restart"))
if (!strcmp(arg0, "cs"))
CG_InsertIntoGameState(atoi(cmdfuncs->Argv(1, NULL, 0)), cmdfuncs->Argv(2, NULL, 0));
else if (!strcmp(arg0, "map_restart"))
Con_ClearNotify();
else if (!strcmp(Cmd_Argv(0), "disconnect"))
Host_EndGame("Server disconnected - %s", (Cmd_Argc()>1)?Cmd_Argv(1):"No reason given");
else if (!strcmp(arg0, "disconnect"))
plugfuncs->EndGame("Server disconnected - %s", (cmdfuncs->Argc()>1)?cmdfuncs->Argv(1, NULL, 0):"No reason given");
return true;
}
@ -478,7 +478,7 @@ int CG_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projecti
ctx.frags = fragmentBuffer;
ctx.numfrags = 0;
ctx.maxfrags = maxFragments;
Mod_ClipDecal(cl.worldmodel, center, axis[0], axis[1], axis[2], radius, 0,0, CG_MarkFragments_Callback, &ctx);
scenefuncs->ClipDecal(ccs.worldmodel, center, axis[0], axis[1], axis[2], radius, 0,0, CG_MarkFragments_Callback, &ctx);
return ctx.numfrags;
}
@ -521,7 +521,7 @@ static void CG_StopLoopingSounds(unsigned int entnum)
loopers[i] = loopers[numloopers-1];
numloopers--;
}
static void CG_StartLoopingSounds(unsigned int entnum, float *origin, float *velocity, const char *soundname, qboolean persistent)
static void CG_StartLoopingSounds(unsigned int entnum, float *origin, float *velocity, int range, const char *soundname, float volume, qboolean persistent)
{
size_t i;
for (i = 0; i < numloopers; i++)
@ -539,8 +539,10 @@ static void CG_StartLoopingSounds(unsigned int entnum, float *origin, float *vel
loopers[i].entnum = entnum;
VectorCopy(origin, loopers[i].origin);
//VectorCopy(velocity, loopers[i].velocity);
loopers[i].sfx = S_PrecacheSound(soundname);
loopers[i].sfx = audiofuncs->PrecacheSound(soundname);
loopers[i].ispersistent = persistent;
// loopers[i].range = range;
// loopers[i].volume = volume;
}
static void CG_MoveLoopingSound(unsigned int entnum, float *origin)
{
@ -575,9 +577,11 @@ static void CG_ClearLoopingSounds(qboolean clearall)
}
}
int VM_LerpTag(void *out, model_t *model, int f1, int f2, float l2, char *tagname);
#define VALIDATEPOINTER(o,l) if ((int)o + l >= mask || VM_POINTER(o) < offset) Host_EndGame("Call to cgame trap %u passes invalid pointer\n", (unsigned int)fn); //out of bounds.
int VM_LerpTag(float *out, model_t *model, int f1, int f2, float l2, char *tagname);
#define VALIDATEPOINTER(o,l) if ((int)o + l >= mask || VM_POINTER(o) < offset) plugfuncs->EndGame("Call to cgame trap %u passes invalid pointer\n", (unsigned int)fn); //out of bounds.
static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, const qintptr_t *arg)
{
@ -593,25 +597,28 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
//make sure that any called functions are also range checked.
//like reading from files copies names into alternate buffers, allowing stack screwups.
//OutputDebugString(va("cl_cg: %i\n", fn));
switch(fn)
switch((cgameImport_t)fn)
{
case CG_PRINT:
Con_Printf("%s", (char*)VM_POINTER(arg[0]));
{
const char *text = VM_POINTER(arg[0]);
Con_Printf("%s", text);
}
break;
case CG_ERROR:
Host_EndGame("cgame: %s", (char*)VM_POINTER(arg[0]));
plugfuncs->EndGame("cgame: %s", (char*)VM_POINTER(arg[0]));
break;
case CG_ARGC:
VM_LONG(ret) = Cmd_Argc();
VM_LONG(ret) = cmdfuncs->Argc();
break;
case CG_ARGV:
VALIDATEPOINTER(arg[1], arg[2]);
Q_strncpyz(VM_POINTER(arg[1]), Cmd_Argv(VM_LONG(arg[0])), VM_LONG(arg[2]));
cmdfuncs->Argv(VM_LONG(arg[0]), VM_POINTER(arg[1]), VM_LONG(arg[2]));
break;
case CG_ARGS:
VALIDATEPOINTER(arg[0], arg[1]);
Q_strncpyz(VM_POINTER(arg[0]), Cmd_Args(), VM_LONG(arg[1]));
cmdfuncs->Args(VM_POINTER(arg[0]), VM_LONG(arg[1]));
break;
case CG_CVAR_REGISTER:
if (arg[0])
@ -622,19 +629,11 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
return VMQ3_Cvar_Update(VM_POINTER(arg[0]));
case CG_CVAR_SET:
{
cvar_t *var;
var = Cvar_FindVar(VM_POINTER(arg[0]));
if (var)
Cvar_Set(var, VM_POINTER(arg[1])?VM_POINTER(arg[1]):""); //set it
else
Cvar_Get(VM_POINTER(arg[0]), VM_POINTER(arg[1]), 0, "Q3CG created"); //create one
}
cvarfuncs->SetString(VM_POINTER(arg[0]), VM_POINTER(arg[1])?VM_POINTER(arg[1]):"");
break;
case CG_CVAR_VARIABLESTRINGBUFFER:
{
cvar_t *var;
var = Cvar_FindVar(VM_POINTER(arg[0]));
cvar_t *var = cvarfuncs->GetNVFDG(VM_POINTER(arg[0]), NULL, 0, NULL, "Q3CG created");
if (!VM_LONG(arg[2]))
VM_LONG(ret) = 0;
else if (!var)
@ -653,20 +652,18 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
case CG_SENDCONSOLECOMMAND:
Con_DPrintf("CG_SENDCONSOLECOMMAND: %s", (char*)VM_POINTER(arg[0]));
Cbuf_AddText(VM_POINTER(arg[0]), RESTRICT_SERVER);
cmdfuncs->AddText(VM_POINTER(arg[0]), false);
break;
case CG_ADDCOMMAND:
Cmd_AddCommand(VM_POINTER(arg[0]), NULL);
cmdfuncs->AddCommand(VM_POINTER(arg[0]), NULL, NULL);
break;
case CG_SENDCLIENTCOMMAND:
Con_DPrintf("CG_SENDCLIENTCOMMAND: %s", (char*)VM_POINTER(arg[0]));
CL_SendClientCommand(true, "%s", (char*)VM_POINTER(arg[0]));
CLQ3_SendClientCommand("%s", (char*)VM_POINTER(arg[0]));
break;
case CG_UPDATESCREEN: //force a buffer swap cos loading won't refresh it soon.
if (!Key_Dest_Has(kdm_console))
scr_con_current = 0;
SCR_UpdateScreen();
drawfuncs->RedrawScreen();
break;
case CG_FS_FOPENFILE: //fopen
@ -682,6 +679,8 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
case CG_FS_WRITE: //fwrite
Con_DPrintf("CG_FS_WRITE: not implemented\n");
break;
case CG_FS_SEEK:
return VM_FSeek(arg[0], arg[1], arg[2], 1);
case CG_FS_FCLOSEFILE: //fclose
VM_fclose(VM_LONG(arg[0]), 1);
break;
@ -691,15 +690,15 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
unsigned int pc;
unsigned int modhandle = VM_LONG(arg[1]);
model_t *mod;
if (modhandle >= MAX_PRECACHE_MODELS)
if (modhandle >= countof(ccs.model_precache))
{
// if (modhandle == MAX_PRECACHE_MODELS+1)
// if (modhandle == countof(ccs.model_precache)+1)
// mod = &capsule_model;
// else
mod = box_model;
}
else
mod = cl.model_precache[modhandle+1];
mod = ccs.model_precache[modhandle];
if (mod && mod->loadstate == MLS_LOADED)
pc = mod->funcs.NativeContents(mod, 0, 0, NULL, VM_POINTER(arg[0]), vec3_origin, vec3_origin);
else
@ -716,15 +715,15 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
float *origin = VM_POINTER(arg[2]);
float *angles = VM_POINTER(arg[3]);
model_t *mod;
if (modhandle >= MAX_PRECACHE_MODELS)
if (modhandle >= countof(ccs.model_precache))
{
// if (modhandle == MAX_PRECACHE_MODELS+1)
// if (modhandle == countof(ccs.model_precache)+1)
// mod = &capsule_model;
// else
mod = box_model;
}
else
mod = cl.model_precache[modhandle+1];
mod = ccs.model_precache[modhandle];
if (mod && mod->loadstate == MLS_LOADED)
{
@ -768,15 +767,15 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
float *origin = VM_POINTER(arg[7]);
float *angles = VM_POINTER(arg[8]);
model_t *mod;
if (modhandle >= MAX_PRECACHE_MODELS)
if (modhandle >= countof(ccs.model_precache))
{
// if (modhandle == MAX_PRECACHE_MODELS+1)
// if (modhandle == countof(ccs.model_precache)+1)
// mod = &capsule_model;
// else
mod = box_model;
}
else
mod = cl.model_precache[modhandle+1];
mod = ccs.model_precache[modhandle];
if (!mins)
mins = vec3_origin;
@ -788,7 +787,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
angles = vec3_origin;
if (mod && mod->loadstate == MLS_LOADED)
#if !defined(CLIENTONLY) || defined(CSQC_DAT)
World_TransformedTrace(mod, 0, 0, start, end, mins, maxs, fn==CG_CM_TRANSFORMEDCAPSULETRACE, &tr, origin, angles, brushmask);
worldfuncs->TransformedTrace(mod, 0, 0, start, end, mins, maxs, fn==CG_CM_TRANSFORMEDCAPSULETRACE, &tr, origin, angles, brushmask);
#else
{
#ifdef warningmsg
@ -828,27 +827,31 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
float *end = VM_POINTER(arg[2]);
float *mins = VM_POINTER(arg[3]);
float *maxs = VM_POINTER(arg[4]);
unsigned int modhandle = VM_LONG(arg[5]);
int brushmask = VM_LONG(arg[6]);
unsigned int modhandle = VM_LONG(arg[5]);
unsigned int brushmask = VM_LONG(arg[6]);
model_t *mod;
if (modhandle >= MAX_PRECACHE_MODELS)
if (modhandle >= countof(ccs.model_precache))
{
// if (modhandle == MAX_PRECACHE_MODELS+1)
// if (modhandle == countof(ccs.model_precache)+1)
// mod = &capsule_model;
// else
mod = box_model;
}
else
mod = cl.model_precache[modhandle+1];
mod = ccs.model_precache[modhandle];
if (mod->loadstate != MLS_LOADED)
{
if (mod->loadstate == MLS_NOTLOADED)
Mod_LoadModel(mod, MLV_SILENT);
scenefuncs->LoadModel(mod->publicname, MLV_SILENTSYNC);
if (mod->loadstate == MLS_LOADING)
COM_WorkerPartialSync(mod, &mod->loadstate, MLS_LOADING);
if (mod->loadstate != MLS_LOADED)
mod = box_model; //stop crashes, even if this is wrong.
{
memset(results, 0, sizeof(*results));
results->fraction = 1;
break;
}
}
if (!mins)
@ -875,45 +878,40 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
{
int i;
char *mapname = VM_POINTER(arg[0]);
strcpy(cl.model_name[1], mapname);
cl.worldmodel = cl.model_precache[1] = Mod_ForName(Mod_FixName(mapname, mapname), MLV_SILENT);
if (cl.worldmodel->loadstate == MLS_LOADING)
COM_WorkerPartialSync(cl.worldmodel, &cl.worldmodel->loadstate, MLS_LOADING);
if (cl.worldmodel->loadstate != MLS_LOADED)
Host_EndGame("Couldn't load map %s", mapname);
ccs.worldmodel = ccs.model_precache[0] = worldfuncs->LoadModel(mapname, MLV_SILENTSYNC);
if (ccs.worldmodel->loadstate != MLS_LOADED)
plugfuncs->EndGame("Couldn't load map %s", mapname);
for (i=1 ; i<cl.model_precache[1]->numsubmodels ; i++)
{
strcpy(cl.model_name[1+i], va("*%i", i));
cl.model_precache[i+1] = Mod_ForName (Mod_FixName(cl.model_name[i+1], mapname), MLV_SILENT);
}
for (i=1 ; i<=ccs.worldmodel->numsubmodels && i < countof(ccs.model_precache); i++)
ccs.model_precache[i] = worldfuncs->LoadModel(worldfuncs->FixName(va("*%i", i), mapname), MLV_SILENTSYNC);
}
break;
case CG_CM_INLINEMODEL:
if ((unsigned int)VM_LONG(arg[0]) > (cl.worldmodel?cl.worldmodel->numsubmodels:0))
Host_EndGame("cgame asked for invalid model number\n");
if ((unsigned int)VM_LONG(arg[0]) > (ccs.worldmodel?ccs.worldmodel->numsubmodels:0))
plugfuncs->EndGame("cgame asked for invalid model number\n");
VM_LONG(ret) = VM_LONG(arg[0]);
break;
case CG_CM_NUMINLINEMODELS:
VM_LONG(ret) = cl.worldmodel?cl.worldmodel->numsubmodels:0;
VM_LONG(ret) = ccs.worldmodel?ccs.worldmodel->numsubmodels:0;
break;
case CG_CM_TEMPBOXMODEL:
box_model = CM_TempBoxModel(VM_POINTER(arg[0]), VM_POINTER(arg[1]));
VM_LONG(ret) = MAX_PRECACHE_MODELS;
box_model = worldfuncs->TempBoxModel(VM_POINTER(arg[0]), VM_POINTER(arg[1]));
VM_LONG(ret) = countof(ccs.model_precache);
break;
case CG_CM_TEMPCAPSULEMODEL:
box_model = CM_TempBoxModel(VM_POINTER(arg[0]), VM_POINTER(arg[1]));
VM_LONG(ret) = MAX_PRECACHE_MODELS+1;
box_model = worldfuncs->TempBoxModel(VM_POINTER(arg[0]), VM_POINTER(arg[1]));
VM_LONG(ret) = countof(ccs.model_precache)+1;
break;
case CG_R_MODELBOUNDS:
VALIDATEPOINTER(arg[1], sizeof(vec3_t));
VALIDATEPOINTER(arg[2], sizeof(vec3_t));
{
model_t *mod = VM_FROMMHANDLE(arg[0]);
model_t *mod = scenefuncs->ModelFromId(arg[0]);
if (mod)
{
if (mod->loadstate == MLS_LOADING)
@ -929,42 +927,41 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
{
char *name = VM_POINTER(arg[0]);
model_t *mod;
mod = Mod_ForName(Mod_FixName(name, cl.model_name[1]), MLV_SILENT);
if (mod->loadstate == MLS_LOADING)
{ //needed to ensure it really is missing
if (!COM_FCheckExists(mod->name))
COM_WorkerPartialSync(mod, &mod->loadstate, MLS_LOADING);
}
if (!name)
return 0;
mod = scenefuncs->LoadModel(worldfuncs->FixName(name, ccs.worldmodel->name), MLV_SILENTSYNC);
if (mod->loadstate == MLS_FAILED || mod->type == mod_dummy)
VM_LONG(ret) = 0;
else
VM_LONG(ret) = VM_TOMHANDLE(mod);
VM_LONG(ret) = scenefuncs->ModelToId(mod);
}
break;
case CG_R_REGISTERSKIN:
VM_LONG(ret) = Mod_RegisterSkinFile(VM_POINTER(arg[0]));
VM_LONG(ret) = scenefuncs->RegisterSkinFile(VM_POINTER(arg[0]));
break;
case CG_R_REGISTERSHADER:
if (!*(char*)VM_POINTER(arg[0]))
VM_LONG(ret) = 0;
else
VM_LONG(ret) = VM_TOSHANDLE(R_RegisterPic(VM_POINTER(arg[0]), NULL));
VM_LONG(ret) = drawfuncs->LoadImage(VM_POINTER(arg[0]));
break;
case CG_R_REGISTERSHADERNOMIP:
if (!*(char*)VM_POINTER(arg[0]))
VM_LONG(ret) = 0;
else
VM_LONG(ret) = VM_TOSHANDLE(R_RegisterPic(VM_POINTER(arg[0]), NULL));
VM_LONG(ret) = drawfuncs->LoadImage(VM_POINTER(arg[0]));
break;
case CG_R_CLEARSCENE: //clear scene (not rtlights, only dynamic ones)
CL_ClearEntityLists();
rtlights_first = RTL_FIRST;
scenefuncs->ClearScene();
break;
case CG_R_ADDPOLYTOSCENE:
VQ3_AddPoly(VM_FROMSHANDLE(arg[0]), VM_LONG(arg[1]), VM_POINTER(arg[2]));
VQ3_AddPolys(drawfuncs->ShaderFromId(arg[0]), VM_LONG(arg[1]), VM_POINTER(arg[2]), 1);
break;
case CG_R_ADDPOLYSTOSCENE:
VQ3_AddPolys(drawfuncs->ShaderFromId(arg[0]), VM_LONG(arg[1]), VM_POINTER(arg[2]), VM_LONG(arg[3]));
break;
case CG_R_ADDREFENTITYTOSCENE: //add ent to scene
VQ3_AddEntity(VM_POINTER(arg[0]));
@ -972,12 +969,14 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
case CG_R_ADDADDITIVELIGHTTOSCENE:
case CG_R_ADDLIGHTTOSCENE: //add light to scene.
{
float *org = VM_POINTER(arg[0]);
CL_NewDlight(-1, org, VM_FLOAT(arg[1]), 0, VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]));
dlight_t *dl = scenefuncs->AllocDlightOrg(-1, VM_POINTER(arg[0]));
dl->flags = LFLAG_NORMALMODE|LFLAG_REALTIMEMODE;
dl->radius = VM_FLOAT(arg[1]);
dl->die = ccs.time+0.1;
VectorSet(dl->color, VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]));
}
break;
case CG_R_RENDERSCENE: //render scene
R_PushDlights();
VQ3_RenderView(VM_POINTER(arg[0]));
break;
@ -985,25 +984,25 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
{
float *f = VM_POINTER(arg[0]);
if (f)
R2D_ImageColours(f[0], f[1], f[2], f[3]);
drawfuncs->Colour4f(f[0], f[1], f[2], f[3]);
else
R2D_ImageColours(1, 1, 1, 1);
drawfuncs->Colour4f(1, 1, 1, 1);
}
break;
case CG_R_DRAWSTRETCHPIC:
R2D_Image(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), VM_FROMSHANDLE(VM_LONG(arg[8])));
drawfuncs->Image(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), VM_LONG(arg[8]));
break;
case CG_R_LERPTAG: //Lerp tag...
VALIDATEPOINTER(arg[0], sizeof(float)*12);
VM_LONG(ret) = VM_LerpTag(VM_POINTER(arg[0]), VM_FROMMHANDLE(arg[1]), VM_LONG(arg[2]), VM_LONG(arg[3]), VM_FLOAT(arg[4]), VM_POINTER(arg[5]));
VM_LONG(ret) = VM_LerpTag(VM_POINTER(arg[0]), scenefuncs->ModelFromId(arg[1]), VM_LONG(arg[2]), VM_LONG(arg[3]), VM_FLOAT(arg[4]), VM_POINTER(arg[5]));
break;
case CG_S_REGISTERSOUND:
{
sfx_t *sfx;
sfx = S_PrecacheSound(VM_POINTER(arg[0]));
sfx = audiofuncs->PrecacheSound(VM_POINTER(arg[0]));
if (sfx)
VM_LONG(ret) = VM_TOSTRCACHE(arg[0]);
else
@ -1013,20 +1012,20 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
case CG_S_STARTLOCALSOUND:
if (VM_LONG(arg[0]) != -1 && arg[0])
S_LocalSound(VM_FROMSTRCACHE(arg[0]));
audiofuncs->LocalSound(VM_FROMSTRCACHE(arg[0]), CHAN_AUTO, 1.0);
break;
case CG_S_STARTSOUND:// ( vec3_t origin, int entityNum, int entchannel, sfxHandle_t sfx )
S_StartSound(VM_LONG(arg[1])+1, VM_LONG(arg[2]), S_PrecacheSound(VM_FROMSTRCACHE(arg[3])), VM_POINTER(arg[0]), NULL, 1, 1, 0, 0, CF_CLI_NODUPES);
audiofuncs->StartSound(VM_LONG(arg[1])+1, VM_LONG(arg[2]), audiofuncs->PrecacheSound(VM_FROMSTRCACHE(arg[3])), VM_POINTER(arg[0]), NULL, 1, 1, 0, 0, CF_CLI_NODUPES);
break;
case CG_S_ADDLOOPINGSOUND:
//entnum, origin, velocity, sfx
CG_StartLoopingSounds(VM_LONG(arg[0])+1, VM_POINTER(arg[1]), VM_POINTER(arg[2]), VM_FROMSTRCACHE(arg[3]), false);
CG_StartLoopingSounds(VM_LONG(arg[0])+1, VM_POINTER(arg[1]), VM_POINTER(arg[2]), -1, VM_FROMSTRCACHE(arg[3]), 1, false);
break;
case CG_S_ADDREALLOOPINGSOUND:
//entnum, origin, velocity, sfx
CG_StartLoopingSounds(VM_LONG(arg[0])+1, VM_POINTER(arg[1]), VM_POINTER(arg[2]), VM_FROMSTRCACHE(arg[3]), true);
CG_StartLoopingSounds(VM_LONG(arg[0])+1, VM_POINTER(arg[1]), VM_POINTER(arg[2]), -1, VM_FROMSTRCACHE(arg[3]), 1, true);
break;
case CG_S_STOPLOOPINGSOUND:
//entnum
@ -1042,33 +1041,19 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
break;
case CG_S_STARTBACKGROUNDTRACK:
Media_NamedTrack(VM_POINTER(arg[0]), VM_POINTER(arg[1]));
audiofuncs->ChangeMusicTrack(VM_POINTER(arg[0]), VM_POINTER(arg[1]));
return 0;
case CG_S_STOPBACKGROUNDTRACK:
Media_NamedTrack(NULL, NULL);
audiofuncs->ChangeMusicTrack(NULL, NULL);
return 0;
case CG_S_RESPATIALIZE://void trap_S_Respatialize( int entityNum, const vec3_t origin, vec3_t axis[3], int inwater );
{
int entnum = VM_LONG(arg[0])+1;
float *org = VM_POINTER(arg[1]);
vec3_t *axis = VM_POINTER(arg[2]);
int inwater = VM_LONG(arg[3]);
cl.playerview[0].audio.defaulted = false;
cl.playerview[0].audio.entnum = entnum;
VectorCopy(org, cl.playerview[0].audio.origin);
VectorCopy(axis[0], cl.playerview[0].audio.forward);
VectorCopy(axis[1], cl.playerview[0].audio.right);
VectorCopy(axis[2], cl.playerview[0].audio.up);
cl.playerview[0].audio.reverbtype = inwater?1:0;
VectorClear(cl.playerview[0].audio.velocity);
}
audiofuncs->Spacialize(0, VM_LONG(arg[0])+1, VM_POINTER(arg[1]), VM_POINTER(arg[2]), VM_LONG(arg[3])?1:0, vec3_origin);
break;
case CG_KEY_ISDOWN:
{
if (keydown[VM_LONG(arg[0])])
if (inputfuncs->IsKeyDown(VM_LONG(arg[0])))
VM_LONG(ret) = 1;
else
VM_LONG(ret) = 0;
@ -1078,7 +1063,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
case CG_KEY_GETKEY:
{
int ret[1];
M_FindKeysForCommand (0, 0, VM_POINTER(arg[0]), ret, NULL, countof(ret));
inputfuncs->FindKeysForCommand(0, VM_POINTER(arg[0]), ret, NULL, countof(ret));
return ret[0];
}
break;
@ -1091,16 +1076,31 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
break;
case CG_GETGLCONFIG:
VALIDATEPOINTER(arg[0], 11332);
{
float vsize[2];
q3glconfig_t *cfg;
VALIDATEPOINTER(arg[0], sizeof(q3glconfig_t));
drawfuncs->GetVideoSize(vsize, NULL);
cfg = VM_POINTER(arg[0]);
{ //FIXME: Clean this shit up
//do any needed work
unsigned char *glconfig = VM_POINTER(arg[0]);
memset(glconfig, 0, 11304);
*(int *)(glconfig+11304) = vid.width;
*(int *)(glconfig+11308) = vid.height;
*(float *)(glconfig+11312) = (float)vid.width/vid.height;
memset((glconfig+11316), 0, 11332-11316);
memset(cfg, 0, sizeof(*cfg));
Q_strncpyz(cfg->renderer_string, "", sizeof(cfg->renderer_string));
Q_strncpyz(cfg->vendor_string, "", sizeof(cfg->vendor_string));
Q_strncpyz(cfg->version_string, "", sizeof(cfg->version_string));
Q_strncpyz(cfg->extensions_string, "", sizeof(cfg->extensions_string));
cfg->colorBits = 32;
cfg->depthBits = 24;
cfg->stencilBits = 8;//sh_config.stencilbits;
cfg->textureCompression = true;//!!sh_config.hw_bc;
cfg->textureEnvAddAvailable = true;//sh_config.env_add;
//these are the only three that really matter.
cfg->vidWidth = vsize[0];
cfg->vidHeight = vsize[1];
cfg->windowAspect = (float)vsize[0]/vsize[1];
}
break;
@ -1146,7 +1146,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
break;
case CG_MILLISECONDS:
VM_LONG(ret) = Sys_Milliseconds();
VM_LONG(ret) = plugfuncs->GetMilliseconds();
break;
case CG_REAL_TIME:
VALIDATEPOINTER(arg[0], sizeof(q3time_t));
@ -1227,7 +1227,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
break;
case CG_R_REMAP_SHADER:
R_RemapShader(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_FLOAT(arg[2]));
scenefuncs->RemapShader(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_FLOAT(arg[2]));
break;
case CG_R_REGISTERFONT:
@ -1235,6 +1235,11 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
UI_RegisterFont(VM_POINTER(arg[0]), VM_LONG(arg[1]), VM_POINTER(arg[2]));
break;
case CG_GET_ENTITY_TOKEN:
mapentspointer = cmdfuncs->ParseToken(mapentspointer, VM_POINTER(arg[0]), arg[1], NULL);
return !!mapentspointer;
case CG_CIN_PLAYCINEMATIC:
return UI_Cin_Play(VM_POINTER(arg[0]), VM_LONG(arg[1]), VM_LONG(arg[2]), VM_LONG(arg[3]), VM_LONG(arg[4]), VM_LONG(arg[5]));
case CG_CIN_STOPCINEMATIC:
@ -1246,7 +1251,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
case CG_CIN_SETEXTENTS:
return UI_Cin_SetExtents(VM_LONG(arg[0]), VM_LONG(arg[1]), VM_LONG(arg[2]), VM_LONG(arg[3]), VM_LONG(arg[4]));
case CG_FTE_FINDPARTICLEEFFECT:
/* case CG_FTE_FINDPARTICLEEFFECT:
return pe->FindParticleType(VM_POINTER(arg[0]));
case CG_FTE_SPAWNPARTICLEEFFECT:
return pe->RunParticleEffectState(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_FLOAT(arg[2]), VM_LONG(arg[3]), VM_POINTER(arg[4]));
@ -1255,7 +1260,14 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
case CG_FTE_FREEPARTICLESTATE:
pe->DelinkTrailstate(VM_POINTER(arg[0]));
break;
default:
*/
case CG_CM_LOADMODEL:
case CG_REMOVECOMMAND:
case CG_TESTPRINTINT:
case CG_TESTPRINTFLOAT:
case CG_R_INPVS:
case CG_R_LIGHTFORPOINT:
// default:
Con_Printf("Q3CG: Bad system trap: %i\n", (int)fn);
}
@ -1308,18 +1320,14 @@ static qintptr_t EXPORT_FN CG_SystemCallsNative(qintptr_t arg, ...)
return CG_SystemCalls(NULL, ~(quintptr_t)0, arg, args);
}
int CG_Refresh(void)
int CG_Refresh(double time)
{
int time;
if (!cgvm)
return false;
r_refdef.skyroom_enabled = false;
time = cl.time*1000;
VM_Call(cgvm, CG_DRAW_ACTIVE_FRAME, time, 0, false);
R2D_ImageColours(1, 1, 1, 1);
ccs.time = time;
vmfuncs->Call(cgvm, CG_DRAW_ACTIVE_FRAME, (int)(ccs.time*1000), 0, false);
drawfuncs->Colour4f(1, 1, 1, 1);
return true;
}
@ -1330,10 +1338,11 @@ void CG_Stop (void)
Q3_SetKeyCatcher(Q3_GetKeyCatcher()&~2);
if (cgvm)
{
VM_Call(cgvm, CG_SHUTDOWN);
VM_Destroy(cgvm);
vmfuncs->Call(cgvm, CG_SHUTDOWN);
vmfuncs->Destroy(cgvm);
VM_fcloseall(1);
cgvm = NULL;
}
}
@ -1341,7 +1350,7 @@ qboolean CG_VideoRestarted(void)
{
if (cgvm)
{
VM_Call(cgvm, CG_INIT, ccs.serverMessageNum, ccs.lastServerCommandNum, cl.playerview[0].playernum);
vmfuncs->Call(cgvm, CG_INIT, ccs.serverMessageNum, ccs.lastServerCommandNum, ccs.playernum);
return true;
}
return false;
@ -1350,39 +1359,35 @@ qboolean CG_VideoRestarted(void)
void CG_Start (void)
{
SCR_SetLoadingStage(0);
if (cls.protocol != CP_QUAKE3)
{ //q3 clients only.
CG_Stop();
return;
}
CG_Stop();
Z_FreeTags(CGTAGNUM);
SCR_BeginLoadingPlaque();
box_model = CM_TempBoxModel(vec3_origin, vec3_origin);
box_model = worldfuncs->TempBoxModel(vec3_origin, vec3_origin); //just in case.
cgvm = VM_Create("cgame", com_nogamedirnativecode.ival?NULL:CG_SystemCallsNative, "vm/cgame", CG_SystemCallsVM);
cgvm = vmfuncs->Create("cgame", cvarfuncs->GetFloat("com_gamedirnativecode")?CG_SystemCallsNative:NULL, "vm/cgame", CG_SystemCallsVM);
if (cgvm)
{ //hu... cgame doesn't appear to have a query version call!
SCR_EndLoadingPlaque();
VM_Call(cgvm, CG_INIT, ccs.serverMessageNum, ccs.lastServerCommandNum, cl.playerview[0].playernum);
vmfuncs->Call(cgvm, CG_INIT, ccs.serverMessageNum, ccs.lastServerCommandNum, ccs.playernum);
}
else
{
SCR_EndLoadingPlaque();
Host_EndGame("Failed to initialise cgame module\n");
plugfuncs->EndGame("Failed to initialise cgame module\n");
}
}
qboolean CG_Command(void)
qboolean CG_ConsoleCommand(void)
{
if (!cgvm)
return false;
Con_DPrintf("CG_Command: %s %s\n", Cmd_Argv(0), Cmd_Args());
return VM_Call(cgvm, CG_CONSOLE_COMMAND);
// Con_DPrintf("CG_Command: %s %s\n", cmdfuncs->Argv(0), cmdfuncs->Args());
return vmfuncs->Call(cgvm, CG_CONSOLE_COMMAND);
}
void CG_Command_f(void)
/*void CG_Command_f(void)
{
if (cgvm)
{
@ -1392,12 +1397,12 @@ void CG_Command_f(void)
Cmd_ForwardToServer();
}
}
}
}*/
qboolean CG_KeyPress(int key, int unicode, int down)
qboolean CG_KeyPressed(int key, int unicode, int down)
{
int catcher = Q3_GetKeyCatcher();
if (!cgvm || !(catcher&8))
if (!cgvm || !(Q3_GetKeyCatcher()&8))
return false;
/* if you change this here, it'll have to be changed in cl_cg.c too */
@ -1451,18 +1456,13 @@ qboolean CG_KeyPress(int key, int unicode, int down)
break;
}
return VM_Call(cgvm, CG_KEY_EVENT, key, down);
return vmfuncs->Call(cgvm, CG_KEY_EVENT, key, down);
}
void CG_Restart_f(void)
void CG_Restart(void)
{
CG_Stop();
CG_Start();
}
void CG_Init(void)
{
Cmd_AddCommand("cg_restart", CG_Restart_f);
}
#endif

View File

@ -262,7 +262,7 @@ int demo_preparsedemo(unsigned char *buffer, int bytes)
{
net_message.cursize = length;
memcpy(net_message.data, buffer+ofs, length);
MSG_BeginReading(cls.netchan.netprim);
MSG_BeginReading(&net_message, cls.netchan.netprim);
CLQW_ParseServerMessage();
}

View File

@ -172,11 +172,11 @@ void CL_CloneDlight(dlight_t *dl, dlight_t *src)
dl->customstyle = src->customstyle?Z_StrDup(src->customstyle):NULL;
Z_Free(customstyle);
}
static void CL_ClearDlight(dlight_t *dl, int key)
static void CL_ClearDlight(dlight_t *dl, int key, qboolean reused)
{
void *sm = dl->worldshadowmesh;
unsigned int oq = dl->coronaocclusionquery;
unsigned int oqr = (dl->key == key)?dl->coronaocclusionresult:false;
unsigned int oqr = reused?dl->coronaocclusionresult:false;
Z_Free(dl->customstyle);
memset (dl, 0, sizeof(*dl));
dl->coronaocclusionquery = oq;
@ -224,7 +224,7 @@ dlight_t *CL_AllocSlight(void)
}
dl = &cl_dlights[i];
CL_ClearDlight(dl, 0);
CL_ClearDlight(dl, 0, false);
dl->flags = LFLAG_REALTIMEMODE;
dl->corona = 0;
return dl;
@ -249,7 +249,7 @@ dlight_t *CL_AllocDlight (int key)
{
if (dl->key == key)
{
CL_ClearDlight(dl, key);
CL_ClearDlight(dl, key, true);
return dl;
}
}
@ -270,10 +270,48 @@ dlight_t *CL_AllocDlight (int key)
if (rtlights_first > dl - cl_dlights)
rtlights_first = dl - cl_dlights;
CL_ClearDlight(dl, key);
CL_ClearDlight(dl, key, false);
return dl;
}
dlight_t *CL_AllocDlightOrg (int keyidx, vec3_t keyorg)
{
int i;
dlight_t *dl;
// first look for an exact key match
dl = cl_dlights+rtlights_first;
for (i=rtlights_first ; i<RTL_FIRST ; i++, dl++)
{
if (dl->key == keyidx && VectorCompare(dl->origin, keyorg))
{
CL_ClearDlight(dl, keyidx, true);
VectorCopy(keyorg, dl->origin);
return dl;
}
}
//default to the first
dl = &cl_dlights[rtlights_first?rtlights_first-1:0];
//try and find one that is free
for (i=RTL_FIRST; i > rtlights_first && i > 0; )
{
i--;
if (!cl_dlights[i].radius)
{
dl = &cl_dlights[i];
break;
}
}
if (rtlights_first > dl - cl_dlights)
rtlights_first = dl - cl_dlights;
CL_ClearDlight(dl, keyidx, false);
VectorCopy(keyorg, dl->origin);
return dl;
}
/*
===============
CL_NewDlight

View File

@ -1609,7 +1609,7 @@ void VARGS CL_SendSeatClientCommand(qboolean reliable, unsigned int seat, char *
#ifdef Q3CLIENT
if (cls.protocol == CP_QUAKE3)
{
CLQ3_SendClientCommand("%s", string);
q3->cl.SendClientCommand("%s", string);
return;
}
#endif
@ -2135,7 +2135,7 @@ static void CL_SendUserinfoUpdate(void)
if (info == &cls.userinfo[0])
{
InfoBuf_ToString(info, userinfo, sizeof(userinfo), NULL, NULL, NULL, NULL, NULL);
CLQ3_SendClientCommand("userinfo \"%s\"", userinfo);
q3->cl.SendClientCommand("userinfo \"%s\"", userinfo);
}
return;
}
@ -2527,7 +2527,11 @@ void CL_SendCmd (double frametime, qboolean mainloop)
#ifdef Q3CLIENT
case CP_QUAKE3:
msecs -= (double)msecstouse;
CLQ3_SendCmd(&cl_pendingcmd[0]);
i = cl.movesequence&UPDATE_MASK;
memcpy(cl.outframes[i].cmd, cl_pendingcmd, sizeof(usercmd_t)*bound(1, cl.splitclients, MAX_SPLITS));
cl.outframes[i].cmd_sequence = cl.movesequence++;
q3->cl.SendCmd(cls.sockets, cl.outframes[i].cmd, cl.movesequence, cl.time);
cls.netchan.outgoing_sequence = cl.movesequence;
CL_ClearPendingCommands();
//don't bank too much, because that results in banking speedcheats

View File

@ -57,7 +57,7 @@ cvar_t cl_timeout = CVAR("cl_timeout", "60");
cvar_t cl_shownet = CVARD("cl_shownet","0", "Debugging var. 0 shows nothing. 1 shows incoming packet sizes. 2 shows individual messages. 3 shows entities too."); // can be 0, 1, or 2
cvar_t cl_disconnectreason = CVARAFD("_cl_disconnectreason", "", "com_errorMessage", CVAR_NOSAVE, "This cvar contains the reason for the last disconnection, so that mod menus can know why things failed.");
cvar_t cl_disconnectreason = CVARAFD("_cl_disconnectreason", "", /*q3*/"com_errorMessage", CVAR_NOSAVE, "This cvar contains the reason for the last disconnection, so that mod menus can know why things failed.");
cvar_t cl_pure = CVARD("cl_pure", "0", "0=standard quake rules.\n1=clients should prefer files within packages present on the server.\n2=clients should use *only* files within packages present on the server.\nDue to quake 1.01/1.06 differences, a setting of 2 is only reliable with total conversions.\nIf sv_pure is set, the client will prefer the highest value set.");
cvar_t cl_sbar = CVARFC("cl_sbar", "0", CVAR_ARCHIVE, CL_Sbar_Callback);
@ -695,7 +695,9 @@ void CL_SendConnectPacket (netadr_t *to, int mtu,
#ifdef Q3CLIENT
if (connectinfo.protocol == CP_QUAKE3)
{ //q3 requires some very strange things.
CLQ3_SendConnectPacket(to, connectinfo.challenge, connectinfo.qport);
//cl.splitclients = 1;
if (q3)
q3->cl.SendConnectPacket(cls.sockets, to, connectinfo.challenge, connectinfo.qport, cls.userinfo);
return;
}
#endif
@ -1118,7 +1120,7 @@ void CL_CheckForResend (void)
net_message.packing = SZ_RAWBYTES;
net_message.cursize = 0;
MSG_BeginReading(net_message.prim);
MSG_BeginReading(&net_message, net_message.prim);
if (connectinfo.mode == CIM_QEONLY)
{
@ -1247,10 +1249,7 @@ void CL_CheckForResend (void)
if (!connectinfo.clogged)
{
#ifdef Q3CLIENT
//Q3 clients send their cdkey to the q3 authorize server.
//they send this packet with the challenge.
//and the server will refuse the client if it hasn't sent it.
CLQ3_SendAuthPacket(to);
q3->cl.SendAuthPacket(cls.sockets, to);
#endif
if (connectinfo.istransfer || connectinfo.numadr>1)
@ -1281,7 +1280,7 @@ void CL_CheckForResend (void)
{
contype |= 1; /*always try qw type connections*/
#ifdef VM_UI
if (!UI_IsRunning()) //don't try to connect to nq servers when running a q3ui. I was getting annoying error messages from q3 servers due to this.
if (!q3->ui.IsRunning()) //don't try to connect to nq servers when running a q3ui. I was getting annoying error messages from q3 servers due to this.
#endif
contype |= 2; /*try nq connections periodically (or if its the default nq port)*/
}
@ -1823,6 +1822,7 @@ static void CL_ReconfigureCommands(int newgame)
#endif
extern void CL_Say_f (void);
extern void CL_SayTeam_f (void);
extern void CL_Color_f (void);
static const struct
{
const char *name;
@ -1834,8 +1834,9 @@ static void CL_ReconfigureCommands(int newgame)
#define Q2 (1u<<CP_QUAKE2)
#define Q3 (1u<<CP_QUAKE3)
{
{"sizeup", SCR_SizeUp_f, "Increase viewsize", Q3},
{"sizedown", SCR_SizeDown_f, "Decrease viewsize", Q3},
{"sizeup", SCR_SizeUp_f, "Increase viewsize", Q3},
{"sizedown", SCR_SizeDown_f, "Decrease viewsize", Q3},
{"color", CL_Color_f, "Change Player Colours", Q3},
#ifdef QUAKESTATS
{"weapon", IN_Weapon, "Configures weapon priorities for the next +attack as an alternative for the impulse command", ~Q1},
{"+fire", IN_FireDown, "'+fire 8 7' will fire lg if you have it and fall back on rl if you don't, and just fire your current weapon if neither are held. Releasing fire will then switch away to exploit a bug in most mods to deny your weapon upgrades to your killer.", ~Q1},
@ -2089,7 +2090,8 @@ void CL_Disconnect (const char *reason)
// stop sounds (especially looping!)
S_StopAllSounds (true);
#ifdef VM_CG
CG_Stop();
if (q3)
q3->cl.Disconnect(cls.sockets);
#endif
#ifdef CSQC_DAT
CSQC_Shutdown();
@ -2199,7 +2201,7 @@ void CL_Disconnect (const char *reason)
CL_ClearState(false);
FS_PureMode(0, NULL, NULL, NULL, NULL, 0);
FS_PureMode(NULL, 0, NULL, NULL, NULL, NULL, 0);
Alias_WipeStuffedAliases();
@ -2440,7 +2442,7 @@ void CL_CheckServerPacks(void)
if (pure != oldpure || cl.serverpakschanged)
{
CL_PakDownloads((pure && !cl_download_packages.ival)?1:cl_download_packages.ival);
FS_PureMode(pure, cl.serverpacknames, cl.serverpackhashes, NULL, NULL, cls.challenge);
FS_PureMode(NULL, pure, cl.serverpacknames, cl.serverpackhashes, NULL, NULL, cls.challenge);
if (pure)
{
@ -3226,7 +3228,7 @@ void CL_ConnectionlessPacket (void)
int c;
char adr[MAX_ADR_SIZE];
MSG_BeginReading (msg_nullnetprim);
MSG_BeginReading (&net_message, msg_nullnetprim);
MSG_ReadLong (); // skip the -1
Cmd_TokenizeString(net_message.data+4, false, false);
@ -3885,7 +3887,9 @@ client_connect: //fixme: make function
#endif
CL_ParseEstablished();
#ifdef Q3CLIENT
if (cls.protocol != CP_QUAKE3)
if (cls.protocol == CP_QUAKE3)
q3->cl.Established();
else
#endif
CL_SendClientCommand(true, "new");
cls.state = ca_connected;
@ -4004,7 +4008,7 @@ void CLNQ_ConnectionlessPacket(void)
if (net_message.cursize < 5)
return; //not enough size to be meaningful (qe does not include a port number)
MSG_BeginReading (msg_nullnetprim);
MSG_BeginReading (&net_message, msg_nullnetprim);
length = LongSwap(MSG_ReadLong ());
if (!(length & NETFLAG_CTL))
return; //not an nq control packet.
@ -4118,7 +4122,7 @@ void CL_ReadPacket(void)
#ifdef NQPROT
if (cls.demoplayback == DPB_NETQUAKE)
{
MSG_BeginReading (cls.netchan.netprim);
MSG_BeginReading (&net_message, cls.netchan.netprim);
cls.netchan.last_received = realtime;
CLNQ_ParseServerMessage ();
@ -4130,7 +4134,7 @@ void CL_ReadPacket(void)
#ifdef Q2CLIENT
if (cls.demoplayback == DPB_QUAKE2)
{
MSG_BeginReading (cls.netchan.netprim);
MSG_BeginReading (&net_message, cls.netchan.netprim);
cls.netchan.last_received = realtime;
CLQ2_ParseServerMessage ();
return;
@ -4212,13 +4216,21 @@ void CL_ReadPacket(void)
#endif
case CP_QUAKE3:
#ifdef Q3CLIENT
CLQ3_ParseServerMessage();
{
cactive_t newstate = q3->cl.ParseServerMessage(&net_message);
if (newstate != cls.state)
{
cls.state = newstate;
if (cls.state == ca_active)
CL_MakeActive("Quake3Arena"); //became active, can flush old stuff now.
}
}
#endif
break;
case CP_QUAKEWORLD:
if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
{
MSG_BeginReading(cls.netchan.netprim);
MSG_BeginReading(&net_message, cls.netchan.netprim);
cls.netchan.last_received = realtime;
cls.netchan.outgoing_sequence = cls.netchan.incoming_sequence;
}
@ -5343,6 +5355,7 @@ void CL_Init (void)
Stats_Init();
#endif
CL_ClearState(false); //make sure the cl.* fields are set properly if there's no ssqc or whatever.
R_BumpLightstyles(1);
}
@ -5968,7 +5981,7 @@ done:
if (!(f->flags & HRF_ACTION))
{
Key_Dest_Remove(kdm_console);
Menu_Prompt(Host_RunFilePrompted, f, va("Exec %s?\n", COM_SkipPath(f->fname)), "Yes", NULL, "Cancel");
Menu_Prompt(Host_RunFilePrompted, f, va("Exec %s?\n", COM_SkipPath(f->fname)), "Yes", NULL, "Cancel", true);
return;
}
if (f->flags & HRF_OPENED)
@ -6079,17 +6092,17 @@ done:
Key_Dest_Remove(kdm_console);
if (haschanged)
{
Menu_Prompt(Host_RunFilePrompted, f, va("File already exists.\nWhat would you like to do?\n%s\n", displayname), "Overwrite", "Run old", "Cancel");
Menu_Prompt(Host_RunFilePrompted, f, va("File already exists.\nWhat would you like to do?\n%s\n", displayname), "Overwrite", "Run old", "Cancel", true);
return;
}
else if (isnew)
{
Menu_Prompt(Host_RunFilePrompted, f, va("File appears new.\nWould you like to install\n%s\n", displayname), "Install!", "", "Cancel");
Menu_Prompt(Host_RunFilePrompted, f, va("File appears new.\nWould you like to install\n%s\n", displayname), "Install!", "", "Cancel", true);
return;
}
else
{
Menu_Prompt(NULL, NULL, va("File is already installed\n%s\n", displayname), NULL, NULL, "Cancel");
Menu_Prompt(NULL, NULL, va("File is already installed\n%s\n", displayname), NULL, NULL, "Cancel", true);
f->flags |= HRF_ABORT;
}
}
@ -6721,11 +6734,6 @@ void CL_StartCinematicOrMenu(void)
Key_Dest_Remove(kdm_console); //make sure console doesn't stay up weirdly.
}
//start up the ui now we have a renderer
#ifdef VM_UI
UI_Start();
#endif
Cbuf_AddText("menu_restart\n", RESTRICT_LOCAL);
Con_TPrintf ("^Ue080^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081 %s %sInitialized ^Ue081^Ue081^Ue081^Ue081^Ue081^Ue081^Ue082\n", *fs_gamename.string?fs_gamename.string:"Nothing", com_installer?"Installer ":"");
@ -7043,7 +7051,7 @@ void Host_FinishLoading(void)
char *scheme = Sys_URIScheme_NeedsRegistering();
if (scheme)
{
Menu_Prompt(Host_URIPrompt, NULL, va("The URI scheme %s:// is not configured.\nRegister now?", scheme), "Register", NULL, "No");
Menu_Prompt(Host_URIPrompt, NULL, va("The URI scheme %s:// is not configured.\nRegister now?", scheme), "Register", NULL, "No", true);
Z_Free(scheme);
}
}
@ -7147,10 +7155,6 @@ void Host_Init (quakeparms_t *parms)
Editor_Init();
#endif
#ifdef VM_UI
UI_Init();
#endif
#ifdef CL_MASTER
Master_SetupSockets();
#endif
@ -7168,6 +7172,10 @@ void Host_Init (quakeparms_t *parms)
host_initialized = true;
forcesaveprompt = false;
#ifdef PLUGINS
Plug_Initialise(false);
#endif
Sys_SendKeyEvents();
//the engine is fully running, except the file system may be nulled out waiting for a manifest to download.
@ -7207,10 +7215,6 @@ void Host_Shutdown(void)
CSQC_Shutdown();
#endif
#ifdef VM_UI
UI_Stop();
#endif
S_Shutdown(true);
CDAudio_Shutdown ();
IN_Shutdown ();
@ -7240,9 +7244,6 @@ void Host_Shutdown(void)
Stats_Clear();
#endif
Ruleset_Shutdown();
#ifdef Q3CLIENT
VMQ3_FlushStringHandles();
#endif
COM_DestroyWorkerThread();

View File

@ -239,8 +239,8 @@ void MasterInfo_WriteServers(void);
char *Master_ServerToString (char *s, int len, serverinfo_t *a); //like NET_AdrToString, but handles more complex addresses.
hostcachekey_t Master_KeyForName(const char *keyname);
float Master_ReadKeyFloat(serverinfo_t *server, hostcachekey_t keynum);
char *Master_ReadKeyString(serverinfo_t *server, hostcachekey_t keynum);
float Master_ReadKeyFloat(serverinfo_t *server, unsigned int keynum);
char *Master_ReadKeyString(serverinfo_t *server, unsigned int keynum);
int Master_SortServers(void);
void Master_SetSortField(hostcachekey_t field, qboolean descending);

View File

@ -1492,8 +1492,7 @@ static int CL_LoadModels(int stage, qboolean dontactuallyload)
SCR_SetLoadingFile("newmap");
// if (!cl.worldmodel || cl.worldmodel->type == mod_dummy)
// Host_EndGame("No worldmodel was loaded\n");
cl.model_precaches_added = false;
Surf_NewMap ();
Surf_NewMap (cl.worldmodel);
pmove.physents[0].model = cl.worldmodel;
@ -2642,7 +2641,7 @@ void DL_Abort(qdownload_t *dl, enum qdlabort aborttype)
break;
#ifdef Q3CLIENT
case DL_Q3:
CLQ3_SendClientCommand("stopdl");
q3->cl.SendClientCommand("stopdl");
break;
#endif
case DL_QW:
@ -3329,13 +3328,7 @@ static void CLQW_ParseServerData (void)
#ifndef CLIENTONLY
if (!sv.state)
#endif
{
COM_FlushTempoaryPacks();
COM_Gamedir(str, NULL);
#ifndef CLIENTONLY
InfoBuf_SetStarKey (&svs.info, "*gamedir", str);
#endif
}
CL_ClearState (true);
#ifdef QUAKEHUD
@ -3541,9 +3534,6 @@ static void CLQW_ParseServerData (void)
S_Voip_MapChange();
#endif
#ifdef VM_CG
CG_Stop();
#endif
#ifdef CSQC_DAT
CSQC_Shutdown(); //revive it when we get the serverinfo saying the checksum.
#endif
@ -3935,13 +3925,7 @@ static void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caut
#ifndef CLIENTONLY
if (!sv.state)
#endif
{
COM_FlushTempoaryPacks();
COM_Gamedir(str, NULL);
#ifndef CLIENTONLY
InfoBuf_SetStarKey (&svs.info, "*gamedir", str);
#endif
}
}
if (cl.allocated_client_slots > MAX_CLIENTS)
{
@ -4189,9 +4173,6 @@ Con_DPrintf ("CL_SignonReply: %i\n", cls.signon);
case 3:
CL_SendClientCommand(true, "begin");
#ifdef VM_CG
CG_Start();
#endif
break;
case 4:
@ -4838,10 +4819,6 @@ static void CLQ2_Precache_f (void)
cl.contentstage = 0;
cl.sendprespawn = true;
SCR_SetLoadingFile("loading data");
#ifdef VM_CG
CG_Start();
#endif
}
#endif
@ -6924,8 +6901,6 @@ static void CL_ParsePrecache(void)
// Con_Printf("svc_precache: Mod_ForName(\"%s\") failed\n", s);
cl.model_precache[i] = model;
Q_strncpyz (cl.model_name[i], s, sizeof(cl.model_name[i]));
cl.model_precaches_added = true;
}
else
Con_Printf("svc_precache: model index %i outside range %i...%i\n", i, 1, MAX_PRECACHE_MODELS);

View File

@ -103,6 +103,33 @@ static unsigned int IN_GetKeyDest(void)
return key_dest_mask;
}
qboolean QDECL Plug_Input_IsKeyDown(int key)
{
extern qboolean keydown[K_MAX];
if (key >= 0 && key < K_MAX)
return !!keydown[key];
return false;
}
void QDECL Plug_Input_ClearKeyStates(void)
{
Key_ClearStates();
}
unsigned int QDECL Plug_Input_GetMoveCount(void)
{
return cl.movesequence;
}
usercmd_t *QDECL Plug_Input_GetMoveEntry(unsigned int move)
{
if (move == cl.movesequence)
return NULL; //the partial
else if (move >= cl.movesequence)
return NULL; //too new
else if (cl.outframes[move&UPDATE_MASK].cmd_sequence != move)
return NULL; //too old or otherwise missing
else
return &cl.outframes[move&UPDATE_MASK].cmd[0];
}
/*
static void QDECL Plug_SCR_CenterPrint(int seat, const char *text)
@ -114,112 +141,37 @@ static void QDECL Plug_SCR_CenterPrint(int seat, const char *text)
typedef struct {
//Make SURE that the engine has resolved all cvar pointers into globals before this happens.
plugin_t *plugin;
char name[64];
int type; //cache, wad, shader, raw
char *script;
mpic_t *pic;
} pluginimagearray_t;
size_t pluginimagearraylen;
pluginimagearray_t *pluginimagearray;
#include "shader.h"
static void Plug_Draw_UnloadImage(qhandle_t image)
static qboolean Plug_Draw_GetScreenSize(float *vsize, unsigned int *psize)
{
size_t i = image-1;
if (i < 0 || i >= pluginimagearraylen)
return;
if (pluginimagearray[i].plugin == currentplug)
{
pluginimagearray[i].plugin = 0;
if (pluginimagearray[i].pic)
R_UnloadShader(pluginimagearray[i].pic);
pluginimagearray[i].pic = NULL;
pluginimagearray[i].name[0] = '\0';
}
}
static void Plug_FreePlugImages(plugin_t *plug)
{
size_t i;
for (i = 0; i < pluginimagearraylen; i++)
{
if (pluginimagearray[i].plugin == plug)
{
pluginimagearray[i].plugin = 0;
if (pluginimagearray[i].pic)
R_UnloadShader(pluginimagearray[i].pic);
pluginimagearray[i].pic = NULL;
pluginimagearray[i].name[0] = '\0';
}
}
}
//called before shaders get flushed, to avoid issues later.
void Plug_FreeAllImages(void)
{
size_t i;
for (i = 0; i < pluginimagearraylen; i++)
{
if (pluginimagearray[i].pic)
{
R_UnloadShader(pluginimagearray[i].pic);
pluginimagearray[i].pic = NULL;
}
}
if (qrenderer<=0)
return false;
if (vsize)
vsize[0] = vid.width, vsize[1] = vid.height;
if (psize)
psize[0] = vid.pixelwidth, psize[1] = vid.pixelheight;
return true;
}
static qhandle_t Plug_Draw_LoadImage(const char *name, int type, const char *script)
{
int i;
mpic_t *pic;
if (!*name)
return 0;
for (i = 0; i < pluginimagearraylen; i++)
{
if (!pluginimagearray[i].plugin)
break;
if (pluginimagearray[i].plugin == currentplug)
{
if (!strcmp(name, pluginimagearray[i].name))
break;
}
}
if (i == pluginimagearraylen)
{
pluginimagearraylen++;
pluginimagearray = BZ_Realloc(pluginimagearray, pluginimagearraylen*sizeof(pluginimagearray_t));
pluginimagearray[i].pic = NULL;
}
if (pluginimagearray[i].pic)
return i+1; //already loaded.
shader_t *pic;
if (qrenderer != QR_NONE)
{
if (type == 3)
pic = NULL;
else if (type == 2)
pic = R_RegisterShader(name, SUF_NONE, script);
else if (type)
pic = R2D_SafePicFromWad(name);
else
pic = R2D_SafeCachePic(name);
}
else
pic = NULL;
Q_strncpyz(pluginimagearray[i].name, name, sizeof(pluginimagearray[i].name));
pluginimagearray[i].type = type;
pluginimagearray[i].pic = pic;
pluginimagearray[i].plugin = currentplug;
pluginimagearray[i].script = script?Z_StrDup(script):NULL;
return i + 1;
if (pic)
return pic->id+1;
return 0;
}
static qhandle_t QDECL Plug_Draw_LoadImageData(const char *name, const char *mimetype, void *codeddata, size_t datalength)
@ -232,8 +184,6 @@ static qhandle_t QDECL Plug_Draw_LoadImageData(const char *name, const char *mim
if ((rgbdata = ReadRawImageFile(codeddata, datalength, &width, &height, &format, false, name)))
{
// name = va("%s", name);
t = Image_FindTexture(name, NULL, IF_PREMULTIPLYALPHA|IF_NOMIPMAP|IF_UIPIC|IF_CLAMP);
if (!TEXVALID(t))
t = Image_CreateTexture(name, NULL, IF_PREMULTIPLYALPHA|IF_NOMIPMAP|IF_UIPIC|IF_CLAMP);
@ -251,93 +201,51 @@ static qhandle_t QDECL Plug_Draw_LoadImageShader(const char *name, const char *s
{
return Plug_Draw_LoadImage(name, 2, script);
}
static qhandle_t QDECL Plug_Draw_LoadImagePic(const char *name, qboolean type)
static qhandle_t QDECL Plug_Draw_LoadImagePic(const char *name)
{
if (type != 0 && type != 1)
return 0;
return Plug_Draw_LoadImage(name, type, NULL);
return Plug_Draw_LoadImage(name, 0, NULL);
}
void Plug_DrawReloadImages(void)
static shader_t *Plug_Draw_ShaderFromId(qhandle_t id)
{
int i;
for (i = 0; i < pluginimagearraylen; i++)
{
if (!pluginimagearray[i].plugin)
{
pluginimagearray[i].pic = NULL;
continue;
}
pluginimagearray[i].pic = R2D_SafePicFromWad(pluginimagearray[i].name);
//pluginimagearray[i].pic = R2D_SafeCachePic(pluginimagearray[i].name);
//pluginimagearray[i].pic = NULL;
}
if (--id >= r_numshaders)
return NULL;
return r_shaders[id];
}
//int R2D_ImageSize (qhandle_t image, float *w, float *h)
static int QDECL Plug_Draw_ImageSize(qhandle_t image, float *w, float *h)
{
int iw, ih, ret;
mpic_t *pic;
int i;
*w = 0;
*h = 0;
if (qrenderer == QR_NONE)
return 0;
i = image;
if (i <= 0 || i > pluginimagearraylen)
return -1; // you fool
i = i - 1;
if (pluginimagearray[i].plugin != currentplug)
return -1;
if (pluginimagearray[i].pic)
pic = pluginimagearray[i].pic;
else if (pluginimagearray[i].type == 1)
return 0; //wasn't loaded.
else
if (image > 0 && image <= r_numshaders)
{
pic = R2D_SafeCachePic(pluginimagearray[i].name);
if (!pic)
return -1;
ret = R_GetShaderSizes(r_shaders[image-1], &iw, &ih, true);
if (w)
*w = iw;
if (h)
*h = ih;
return ret;
}
ret = R_GetShaderSizes(pic, &iw, &ih, true);
*w = iw;
*h = ih;
return ret;
return -1;
}
static int QDECL Plug_Draw_Image(float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t image)
{
mpic_t *pic;
int i;
if (qrenderer == QR_NONE)
return 0;
i = image;
if (i <= 0 || i > pluginimagearraylen)
return -1; // you fool
i = i - 1;
if (pluginimagearray[i].plugin != currentplug)
return -1;
if (pluginimagearray[i].pic)
pic = pluginimagearray[i].pic;
else if (pluginimagearray[i].type == 1)
return 0; //wasn't loaded.
else
if (image > 0 && image <= r_numshaders)
{
pic = R2D_SafeCachePic(pluginimagearray[i].name);
if (!pic)
return -1;
R2D_Image(x, y, w, h, s1, t1, s2, t2, r_shaders[image-1]);
return 1;
}
R2D_Image(x, y, w, h, s1, t1, s2, t2, pic);
return 1;
return 0;
}
static int QDECL Plug_Draw_Image2dQuad(const vec2_t *points, const vec2_t *texcoords, const vec4_t *colours, qhandle_t image)
{
if (image > 0 && image <= r_numshaders)
{
R2D_Image2dQuad(points, texcoords, colours, r_shaders[image-1]);
return 1;
}
return 0;
}
//x1,y1,x2,y2
static void QDECL Plug_Draw_Line(float x1, float y1, float x2, float y2)
@ -454,13 +362,148 @@ static void QDECL Plug_Draw_Colour4f(float r, float g, float b, float a)
R2D_ImageColours(r,g,b,a);
}
static void QDECL Plug_Draw_RedrawScreen(void)
{
SCR_UpdateScreen();
}
static qhandle_t Plug_Scene_ModelToId(model_t *mod)
{
if (!mod)
return 0;
return (mod-mod_known)+1;
}
static model_t *Plug_Scene_ModelFromId(qhandle_t id)
{
extern int mod_numknown;
if ((unsigned)(--id) >= mod_numknown)
return NULL;
return mod_known+id;
}
static qhandle_t Plug_Scene_ShaderForSkin(qhandle_t modelid, int surfaceidx, int skinnum, float time)
{
shader_t *s = Mod_ShaderForSkin(Plug_Scene_ModelFromId(modelid), surfaceidx, skinnum, time, NULL);
return s->id+1;
}
static void QDECL Plug_Scene_Clear(void)
{
CL_ClearEntityLists();
rtlights_first = RTL_FIRST;
}
static unsigned int Plug_Scene_AddPolydata(struct shader_s *s, unsigned int beflags, size_t numverts, size_t numidx, vecV_t **vertcoord, vec2_t **texcoord, vec4_t **colour, index_t **indexes)
{
unsigned int ret;
scenetris_t *t;
/*reuse the previous trigroup if its the same shader*/
if (cl_numstris && cl_stris[cl_numstris-1].shader == s && cl_stris[cl_numstris-1].flags == beflags)
t = &cl_stris[cl_numstris-1];
else
{
if (cl_numstris == cl_maxstris)
{
cl_maxstris += 8;
cl_stris = BZ_Realloc(cl_stris, sizeof(*cl_stris)*cl_maxstris);
}
t = &cl_stris[cl_numstris++];
t->shader = s;
t->flags = beflags;
t->numidx = 0;
t->numvert = 0;
t->firstidx = cl_numstrisidx;
t->firstvert = cl_numstrisvert;
}
ret = cl_numstrisvert - t->firstvert;
if (cl_maxstrisvert < cl_numstrisvert+numverts)
cl_stris_ExpandVerts(cl_numstrisvert+numverts + 64);
if (cl_maxstrisidx < cl_numstrisidx+numidx)
{
cl_maxstrisidx = cl_numstrisidx+numidx + 64;
cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx);
}
*vertcoord = cl_strisvertv+cl_numstrisvert;
*texcoord = cl_strisvertt+cl_numstrisvert;
*colour = cl_strisvertc+cl_numstrisvert;
*indexes = cl_strisidx+cl_numstrisidx;
t->numvert += numverts;
t->numidx += numidx;
cl_numstrisvert += numverts;
cl_numstrisidx += numidx;
return ret;
}
void R_DrawNameTags(void);
static void Plug_Scene_RenderScene(plugrefdef_t *in, size_t areabytes, const qbyte *areadata)
{
size_t i;
extern cvar_t r_torch;
if (R2D_Flush)
R2D_Flush();
VectorCopy(in->viewaxisorg[0], r_refdef.viewaxis[0]);
VectorCopy(in->viewaxisorg[1], r_refdef.viewaxis[1]);
VectorCopy(in->viewaxisorg[2], r_refdef.viewaxis[2]);
VectorCopy(in->viewaxisorg[3], r_refdef.vieworg);
VectorAngles(r_refdef.viewaxis[0], r_refdef.viewaxis[2], r_refdef.viewangles, false); //do we actually still need this?
r_refdef.flags = in->flags;
r_refdef.fov_x = in->fov[0];
r_refdef.fov_y = in->fov[1];
r_refdef.fovv_x = in->fov_viewmodel[0];
r_refdef.fovv_y = in->fov_viewmodel[1];
r_refdef.vrect.x = in->rect.x;
r_refdef.vrect.y = in->rect.y;
r_refdef.vrect.width = in->rect.w;
r_refdef.vrect.height = in->rect.h;
r_refdef.time = in->time;
r_refdef.useperspective = true;
r_refdef.mindist = bound(0.1, gl_mindist.value, 4);
r_refdef.maxdist = gl_maxdist.value;
r_refdef.playerview = &cl.playerview[0];
if (in->flags & RDF_SKYROOMENABLED)
{
r_refdef.skyroom_enabled = true;
VectorCopy(in->skyroom_org, r_refdef.skyroom_pos);
}
else
r_refdef.skyroom_enabled = false;
if (r_refdef.vrect.y < 0)
{ //evil hack to work around player model ui bug.
//if the y coord is off screen, reduce the height to keep things centred, and reduce the fov to compensate.
r_refdef.vrect.height += r_refdef.vrect.y*2;
r_refdef.fov_y = in->fov[1] * r_refdef.vrect.height / in->rect.h;
r_refdef.fovv_y = in->fov_viewmodel[1] * r_refdef.vrect.height / in->rect.h;
r_refdef.vrect.y = 0;
}
memset(&r_refdef.globalfog, 0, sizeof(r_refdef.globalfog));
if (r_torch.ival)
{
dlight_t *dl;
dl = CL_NewDlight(0, r_refdef.vieworg, 300, r_torch.ival, 0.5, 0.5, 0.2);
dl->flags |= LFLAG_SHADOWMAP|LFLAG_FLASHBLEND;
dl->fov = 60;
VectorCopy(r_refdef.viewaxis[0], dl->axis[0]);
VectorCopy(r_refdef.viewaxis[1], dl->axis[1]);
VectorCopy(r_refdef.viewaxis[2], dl->axis[2]);
}
r_refdef.areabitsknown = areabytes>0;
for (i = 0; i < sizeof(r_refdef.areabits)/sizeof(int) && i < areabytes/sizeof(int); i++)
((int*)r_refdef.areabits)[i] = ((int*)areadata)[i] ^ ~0;
R_PushDlights();
R_RenderView();
R_DrawNameTags();
r_refdef.playerview = NULL;
r_refdef.time = 0;
}
static void QDECL Plug_LocalSound(const char *soundname, int channel, float volume)
{
@ -592,6 +635,18 @@ static void QDECL Plug_SetUserInfo(int seat, const char *key, const char *value)
CL_SetInfo(seat, key, value);
}
void QDECL Plug_CL_ClearState(void)
{
CL_ClearState(true);
}
void QDECL Plug_CL_UpdateGameTime(double servertime)
{
cl.oldgametime = cl.gametime;
cl.oldgametimemark = cl.gametimemark;
cl.gametime = servertime;
cl.gametimemark = realtime;
}
static qboolean QDECL Plug_GetLastInputFrame(int seat, usercmd_t *outcmd)
{
unsigned int curframe = (cl.movesequence-1u) & UPDATE_MASK;
@ -1056,11 +1111,27 @@ static void QDECL Plug_S_RawAudio(int sourceid, void *data, int speed, int sampl
{
S_RawAudio(sourceid, data, speed, samples, channels, width, volume);
}
static void QDECL S_Spacialize(unsigned int seat, int entnum, vec3_t origin, vec3_t axis[3], int reverb, vec3_t velocity)
{
if (seat >= countof(cl.playerview))
return;
cl.playerview[seat].audio.defaulted = false;
cl.playerview[seat].audio.entnum = entnum;
VectorCopy(origin, cl.playerview[seat].audio.origin);
VectorCopy(axis[0], cl.playerview[seat].audio.forward);
VectorCopy(axis[1], cl.playerview[seat].audio.right);
VectorCopy(axis[2], cl.playerview[seat].audio.up);
cl.playerview[seat].audio.reverbtype = reverb;
VectorCopy(velocity, cl.playerview[seat].audio.velocity);
}
static sfx_t *QDECL Plug_S_PrecacheSound(const char *sndname)
{
return S_PrecacheSound(sndname);
}
static void Plug_Client_Close(plugin_t *plug)
{
menu_t *m = Menu_FindContext(currentplug);
Plug_FreePlugImages(plug);
if (m)
Menu_Unlink(m, true);
@ -1072,13 +1143,6 @@ static void Plug_Client_Close(plugin_t *plug)
}
}
static void Plug_Client_Shutdown(void)
{
BZ_Free(pluginimagearray);
pluginimagearray = NULL;
pluginimagearraylen = 0;
}

View File

@ -2293,7 +2293,7 @@ void SCR_SetUpToDrawConsole (void)
scr_con_target = 0; // not looking at an normal console
}
#ifdef VM_UI
else if (UI_OpenMenu())
else if (q3 && q3->ui.OpenMenu())
scr_con_current = scr_con_target = 0; //force instantly hidden.
#endif
else
@ -2499,7 +2499,7 @@ void *SCR_ScreenShot_Capture(int fbwidth, int fbheight, int *stride, enum upload
R2D_FillBlock(0, 0, vid.fbvwidth, vid.fbvheight);
#ifdef VM_CG
if (!okay && CG_Refresh())
if (!okay && q3->cg.Redraw(cl.time))
okay = true;
#endif
#ifdef CSQC_DAT

File diff suppressed because it is too large Load Diff

View File

@ -919,7 +919,6 @@ typedef struct
char *particle_csname[MAX_CSPARTICLESPRE];
int particle_csprecache[MAX_CSPARTICLESPRE]; //these are actually 1-based, so we can be lazy and do a simple negate.
qboolean model_precaches_added;
qboolean particle_ssprecaches; //says to not try to do any dp-compat hacks.
qboolean particle_csprecaches; //says to not try to do any dp-compat hacks.
@ -1117,8 +1116,9 @@ extern qboolean nomaster;
//
void CL_InitDlights(void);
void CL_FreeDlights(void);
dlight_t *CL_AllocDlight (int key);
dlight_t *CL_AllocSlight (void); //allocates a static light
dlight_t *CL_AllocDlight (int key); //allocates or reuses the light with the specified key index
dlight_t *CL_AllocDlightOrg (int keyidx, vec3_t keyorg); //reuses the light at the specified origin...
dlight_t *CL_AllocSlight (void); //allocates a new static light
dlight_t *CL_NewDlight (int key, const vec3_t origin, float radius, float time, float r, float g, float b);
dlight_t *CL_NewDlightCube (int key, const vec3_t origin, vec3_t angles, float radius, float time, vec3_t colours);
void CL_CloneDlight(dlight_t *dl, dlight_t *src); //copies one light to another safely
@ -1196,7 +1196,7 @@ extern char emodel_name[], pmodel_name[], prespawn_name[], modellist_name[], sou
//CL_TraceLine traces against network(positive)+csqc(negative) ents. returns frac(1 on failure), and impact, normal, ent values
float CL_TraceLine (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal, int *ent);
entity_t *TraceLineR (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal);
entity_t *TraceLineR (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal, qboolean bsponly);
//
// cl_input
@ -1445,25 +1445,6 @@ void CL_LinkProjectiles (void);
void CL_ClearLerpEntsParticleState (void);
qboolean CL_MayLerp(void);
//
//clq3_parse.c
//
#ifdef Q3CLIENT
void VARGS CLQ3_SendClientCommand(const char *fmt, ...) LIKEPRINTF(1);
void CLQ3_SendAuthPacket(netadr_t *gameserver);
void CLQ3_SendConnectPacket(netadr_t *to, int challenge, int qport);
void CLQ3_SendCmd(usercmd_t *cmd);
qboolean CLQ3_Netchan_Process(void);
void CLQ3_ParseServerMessage (void);
struct snapshot_s;
qboolean CG_FillQ3Snapshot(int snapnum, struct snapshot_s *snapshot);
void CG_InsertIntoGameState(int num, char *str);
void CG_Restart_f(void);
char *CG_GetConfigString(int num);
#endif
//
//pr_csqc.c
//

View File

@ -1,18 +1,55 @@
#include "quakedef.h"
#include "q3common.h"
#include "shader.h"
#include "glquake.h"
#include "shader.h"
#include "cl_master.h"
#ifndef STATIC_Q3
void Cvar_ForceCheatVars(qboolean semicheats, qboolean absolutecheats){} //locks/unlocks cheat cvars depending on weather we are allowed them.
//int Cvar_ApplyLatches(int latchflag){return 0;}
unsigned int utf8_decode(int *error, const void *in, char const**out){return 0;}
void Con_PrintFlags(const char *txt, unsigned int setflags, unsigned int clearflags){}
void Con_ClearNotify (void){}
unsigned int key_dest_mask;
float in_sensitivityscale;
void Sys_Clipboard_PasteText(clipboardtype_t clipboardtype, void (*callback)(void *cb, const char *utf8), void *ctx){}; //calls the callback once the text is available (maybe instantly). utf8 arg may be NULL if the clipboard was unavailable.
void SCR_SetLoadingStage(int stage){}
void SCR_BeginLoadingPlaque (void){}
void SCR_EndLoadingPlaque (void){}
void Shader_DefaultCinematic (struct shaderparsestate_s *ps, const char *shortname, const void *args){}
shader_t *R_RegisterCustom (model_t *mod, const char *name, unsigned int usageflags, shader_gen_t *defaultgen, const void *args){return NULL;}
cin_t *R_ShaderGetCinematic(shader_t *s){return NULL;}
void Media_SetState(cin_t *cin, cinstates_t newstate){}
void R_UnloadShader(shader_t *shader){}
cinstates_t Media_GetState(cin_t *cin){return 0;}
void Media_Send_Reset(cin_t *cin){}
char *CL_TryingToConnect(void){return NULL;}
downloadlist_t *CL_DownloadFailed(const char *name, qdownload_t *qdl, enum dlfailreason_e failreason){return NULL;}
qboolean DL_Begun(qdownload_t *dl){return 0;}
void CL_DownloadFinished(qdownload_t *dl){}
int Sys_EnumerateFiles (const char *gpath, const char *match, int (QDECL *func)(const char *fname, qofs_t fsize, time_t modtime, void *parm, searchpathfuncs_t *spath), void *parm, searchpathfuncs_t *spath){return 0;}
#endif
//urm, yeah, this is more than just parse.
#ifdef Q3CLIENT
#include "clq3defs.h"
#define SHOWSTRING(s) if(cl_shownet.value==2)Con_Printf ("%s\n", s);
#define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x);
#define SHOWNET2(x, y) if(cl_shownet.value==2)Con_Printf ("%3i:%3i:%s\n", msg_readcount-1, y, x);
#define SHOWSTRING(s) if(cl_shownet_ptr->value==2)Con_Printf ("%s\n", s);
#define SHOWNET(x) if(cl_shownet_ptr->value==2)Con_Printf ("%3i:%s\n", msg->currentbit-8, x);
#define SHOWNET2(x, y) if(cl_shownet_ptr->value==2)Con_Printf ("%3i:%3i:%s\n", msg->currentbit-8, y, x);
void MSG_WriteBits(sizebuf_t *msg, int value, int bits);
static qboolean CLQ3_Netchan_Process(sizebuf_t *msg);
ClientConnectionState_t ccs;
@ -26,7 +63,7 @@ qboolean CG_FillQ3Snapshot(int snapnum, snapshot_t *snapshot)
if (snapnum > ccs.serverMessageNum)
{
Host_EndGame("CG_FillQ3Snapshot: snapshotNumber > cl.snap.serverMessageNum");
plugfuncs->EndGame("CG_FillQ3Snapshot: snapshotNumber > cl.snap.serverMessageNum");
}
if (ccs.serverMessageNum - snapnum >= Q3UPDATE_BACKUP)
@ -70,10 +107,10 @@ void CLQ3_ParseServerCommand(void)
int number;
char *string;
number = MSG_ReadLong();
SHOWNET(va("%i", number));
number = msgfuncs->ReadLong();
// SHOWNET(va("%i", number));
string = MSG_ReadString();
string = msgfuncs->ReadString();
SHOWSTRING(string);
if( number <= ccs.lastServerCommandNum )
@ -158,16 +195,11 @@ static void CLQ3_ParsePacketEntities( clientSnap_t *oldframe, clientSnap_t *newf
while( 1 )
{
newnum = MSG_ReadBits( GENTITYNUM_BITS );
if( newnum < 0 || newnum >= MAX_GENTITIES )
{
Host_EndGame("CLQ3_ParsePacketEntities: bad number %i", newnum);
}
if( msg_readcount > net_message.cursize )
{
Host_EndGame("CLQ3_ParsePacketEntities: end of message");
}
newnum = msgfuncs->ReadBits( GENTITYNUM_BITS );
if (newnum < 0)
plugfuncs->EndGame("CLQ3_ParsePacketEntities: end of message");
else if (newnum >= MAX_GENTITIES )
plugfuncs->EndGame("CLQ3_ParsePacketEntities: bad number %i", newnum);
// end of packetentities
if( newnum == ENTITYNUM_NONE )
@ -252,26 +284,23 @@ void CLQ3_ParseSnapshot(void)
clientSnap_t snap, *oldsnap;
int delta;
int len;
int i;
outframe_t *frame;
// int i;
// outframe_t *frame;
// usercmd_t *ucmd;
// int commandTime;
memset(&snap, 0, sizeof(snap));
snap.serverMessageNum = ccs.serverMessageNum;
snap.serverCommandNum = ccs.lastServerCommandNum;
snap.serverTime = MSG_ReadLong();
snap.serverTime = msgfuncs->ReadLong();
//so we can delta to it properly.
cl.oldgametime = cl.gametime;
cl.oldgametimemark = cl.gametimemark;
cl.gametime = snap.serverTime / 1000.0f;
cl.gametimemark = Sys_DoubleTime();
clientfuncs->UpdateGameTime(snap.serverTime / 1000.0f);
// If the frame is delta compressed from data that we
// no longer have available, we must suck up the rest of
// the frame, but not use it, then ask for a non-compressed message
delta = MSG_ReadByte();
delta = msgfuncs->ReadByte();
if(delta)
{
snap.deltaFrame = ccs.serverMessageNum - delta;
@ -306,11 +335,11 @@ void CLQ3_ParseSnapshot(void)
}
// read snapFlags
snap.snapFlags = MSG_ReadByte();
snap.snapFlags = msgfuncs->ReadByte();
// read areabits
len = MSG_ReadByte();
MSG_ReadData(snap.areabits, len );
len = msgfuncs->ReadByte();
msgfuncs->ReadData(snap.areabits, len );
// read playerinfo
SHOWSTRING("playerstate");
@ -330,15 +359,15 @@ void CLQ3_ParseSnapshot(void)
// Find last usercmd server has processed and calculate snap.ping
snap.ping = 3;
for (i=cls.netchan.outgoing_sequence-1 ; i>cls.netchan.outgoing_sequence-Q3CMD_BACKUP ; i--)
/* for (i=ccs.netchan.outgoing_sequence-1 ; i>ccs.netchan.outgoing_sequence-Q3CMD_BACKUP ; i--)
{
frame = &cl.outframes[i & Q3CMD_MASK];
if (frame->server_message_num == snap.deltaFrame)
{
snap.ping = Sys_Milliseconds() - frame->client_time;
snap.ping = plugfuncs->GetMilliseconds() - frame->client_time;
break;
}
}
}*/
memcpy(&ccs.snap, &snap, sizeof(snap));
memcpy(&ccs.snapshots[ccs.serverMessageNum & Q3UPDATE_MASK], &snap, sizeof(snap));
@ -349,37 +378,37 @@ void CLQ3_ParseSnapshot(void)
#define MAXCHUNKSIZE 65536
void CLQ3_ParseDownload(void)
{
qdownload_t *dl = cls.download;
qdownload_t *dl = ccs.download;
unsigned int chunknum;
unsigned int chunksize;
unsigned char chunkdata[MAXCHUNKSIZE];
int i;
char *s;
chunknum = (unsigned short) MSG_ReadShort();
chunknum = (unsigned short) msgfuncs->ReadShort();
chunknum |= ccs.downloadchunknum&~0xffff; //add the chunk number, truncated by the network protocol.
if (!chunknum)
{
dl->size = (unsigned int)MSG_ReadLong();
Cvar_SetValue( Cvar_Get("cl_downloadSize", "0", 0, "Download stuff"), dl->size );
dl->size = (unsigned int)msgfuncs->ReadLong();
cvarfuncs->SetFloat( cvarfuncs->GetNVFDG("cl_downloadSize", "0", 0, NULL, "Q3 Compat")->name, dl->size ); //so the gamecode knows download progress.
}
if (dl->size == (unsigned int)-1)
{ //the only downloads we should be getting is pk3s.
//if they're advertised-but-failing then its probably due to permissions rather than file-not-found
s = MSG_ReadString();
s = msgfuncs->ReadString();
CL_DownloadFailed(dl->remotename, dl, DLFAIL_SERVERCVAR);
Host_EndGame("%s", s);
plugfuncs->EndGame("%s", s);
return;
}
chunksize = (unsigned short)MSG_ReadShort();
chunksize = (unsigned short)msgfuncs->ReadShort();
if (chunksize > MAXCHUNKSIZE)
Host_EndGame("Server sent a download chunk of size %i (it's too damn big!)\n", chunksize);
plugfuncs->EndGame("Server sent a download chunk of size %i (it's too damn big!)\n", chunksize);
for (i = 0; i < chunksize; i++)
chunkdata[i] = MSG_ReadByte();
chunkdata[i] = msgfuncs->ReadByte();
if (ccs.downloadchunknum != chunknum) //the q3 client is rather lame.
{ //ccs.downloadchunknum holds the chunk number.
@ -410,9 +439,7 @@ void CLQ3_ParseDownload(void)
{
CL_DownloadFinished(dl);
FS_ReloadPackFiles();
cl.servercount = -1; //make sure the server resends us that vital gamestate.
ccs.servercount = -1; //make sure the server resends us that vital gamestate.
ccs.downloadchunknum = -1;
return;
}
@ -437,45 +464,45 @@ static qboolean CLQ3_SendDownloads(char *rc, char *rn)
qdownload_t *dl;
char localname[MAX_QPATH];
char tempname[MAX_QPATH];
char filename[MAX_QPATH];
char crc[64];
vfsfile_t *f;
extern cvar_t cl_downloads;
rc = COM_ParseOut(rc, crc, sizeof(crc));
rn = COM_Parse(rn);
if (!*com_token)
rc = cmdfuncs->ParseToken(rc, crc, sizeof(crc), NULL);
rn = cmdfuncs->ParseToken(rn, filename, sizeof(filename), NULL);
if (!*filename)
break;
if (!strchr(com_token, '/')) //don't let some muppet tell us to download quake3.exe
if (!strchr(filename, '/')) //don't let some muppet tell us to download quake3.exe
break;
//as much as I'd like to use COM_FCheckExists, this stuf is relative to root, not the gamedir.
f = FS_OpenVFS(va("%s.pk3", com_token), "rb", FS_ROOT);
f = fsfuncs->OpenVFS(va("%s.pk3", filename), "rb", FS_ROOT);
if (f)
{
VFS_CLOSE(f);
continue;
}
if (!FS_GenCachedPakName(va("%s.pk3", com_token), crc, localname, sizeof(localname)))
if (!fsfuncs->GenCachedPakName(va("%s.pk3", filename), crc, localname, sizeof(localname)))
continue;
f = FS_OpenVFS(localname, "rb", FS_ROOT);
f = fsfuncs->OpenVFS(localname, "rb", FS_ROOT);
if (f)
{
VFS_CLOSE(f);
continue;
}
if (!FS_GenCachedPakName(va("%s.tmp", com_token), crc, tempname, sizeof(tempname)))
if (!fsfuncs->GenCachedPakName(va("%s.tmp", filename), crc, tempname, sizeof(tempname)))
continue;
if (!cl_downloads.ival)
if (!cvarfuncs->GetFloat("cl_downloads"))
{
Con_Printf(CON_WARNING "Need to download %s.pk3, but downloads are disabled\n", com_token);
Con_Printf(CON_WARNING "Need to download %s.pk3, but downloads are disabled\n", filename);
continue;
}
//fixme: request to download it
Con_Printf("Sending request to download %s.pk3\n", com_token);
CLQ3_SendClientCommand("download %s.pk3", com_token);
Con_Printf("Sending request to download %s.pk3\n", filename);
CLQ3_SendClientCommand("download %s.pk3", filename);
ccs.downloadchunknum = 0;
dl = Z_Malloc(sizeof(*dl));
//q3's downloads are relative to root, but they do at least force a pk3 extension.
@ -484,84 +511,73 @@ static qboolean CLQ3_SendDownloads(char *rc, char *rn)
dl->prefixbytes = 8;
dl->fsroot = FS_ROOT;
Q_snprintfz(dl->remotename, sizeof(dl->remotename), "%s.pk3", com_token);
Q_snprintfz(dl->remotename, sizeof(dl->remotename), "%s.pk3", filename);
dl->method = DL_Q3;
dl->percent = 0;
cls.download = dl;
ccs.download = dl;
return true;
}
return false;
}
qboolean CLQ3_SystemInfoChanged(char *str)
qboolean CLQ3_SystemInfoChanged(const char *str)
{
qboolean usingpure, usingcheats;
char *value;
char *pc, *pn;
char *rc, *rn;
Con_Printf("Server's sv_pure: \"%s\"\n", Info_ValueForKey(str, "sv_pure"));
usingpure = atoi(Info_ValueForKey(str, "sv_pure"));
usingcheats = atoi(Info_ValueForKey(str, "sv_cheats"));
Con_Printf("Server's sv_pure: \"%s\"\n", worldfuncs->GetInfoKey(str, "sv_pure"));
usingpure = atoi(worldfuncs->GetInfoKey(str, "sv_pure"));
usingcheats = atoi(worldfuncs->GetInfoKey(str, "sv_cheats"));
Cvar_ForceCheatVars(usingpure||usingcheats, usingcheats);
// if (atoi(value))
// Host_EndGame("Unable to connect to Q3 Pure Servers\n");
value = Info_ValueForKey(str, "fs_game");
// if (atoi(value))
// Host_EndGame("Unable to connect to Q3 Pure Servers\n");
value = worldfuncs->GetInfoKey(str, "fs_game");
#ifndef CLIENTONLY
if (!sv.state)
#endif
if (!*value)
{
COM_FlushTempoaryPacks();
if (!*value)
value = "baseq3";
COM_Gamedir(value, NULL);
#ifndef CLIENTONLY
InfoBuf_SetStarKey (&svs.info, "*gamedir", value);
#endif
value = "baseq3";
}
rc = Info_ValueForKey(str, "sv_referencedPaks"); //the ones that we should download.
rn = Info_ValueForKey(str, "sv_referencedPakNames");
rc = worldfuncs->GetInfoKey(str, "sv_referencedPaks"); //the ones that we should download.
rn = worldfuncs->GetInfoKey(str, "sv_referencedPakNames");
if (CLQ3_SendDownloads(rc, rn))
return false;
pc = Info_ValueForKey(str, "sv_paks"); //the ones that we are allowed to use (in order!)
pn = Info_ValueForKey(str, "sv_pakNames");
FS_PureMode(usingpure?2:0, pn, pc, rn, rc, ccs.fs_key);
pc = worldfuncs->GetInfoKey(str, "sv_paks"); //the ones that we are allowed to use (in order!)
pn = worldfuncs->GetInfoKey(str, "sv_pakNames");
fsfuncs->PureMode(value, usingpure?2:0, pn, pc, rn, rc, ccs.fs_key);
return true; //yay, we're in
}
void CLQ3_ParseGameState(void)
void CLQ3_ParseGameState(sizebuf_t *msg)
{
int c;
int index;
char *configString;
cvar_t *cl_paused;
//
// wipe the client_state_t struct
//
CL_ClearState(true);
clientfuncs->ClearClientState();
CG_ClearGameState();
ccs.firstParseEntity = 0;
memset(ccs.parseEntities, 0, sizeof(ccs.parseEntities));
memset(ccs.baselines, 0, sizeof(ccs.baselines));
cl.minpitch = -90;
cl.maxpitch = 90;
ccs.lastServerCommandNum = MSG_ReadLong();
ccs.lastServerCommandNum = msgfuncs->ReadLong();
for(;;)
{
c = MSG_ReadByte();
c = msgfuncs->ReadByte();
if(msg_badread)
if(c < 0)
{
Host_EndGame("CLQ3_ParseGameState: read past end of server message");
plugfuncs->EndGame("CLQ3_ParseGameState: read past end of server message");
break;
}
if(c == svcq3_eom)
@ -574,33 +590,33 @@ void CLQ3_ParseGameState(void)
switch(c)
{
default:
Host_EndGame("CLQ3_ParseGameState: bad command byte %i", c);
plugfuncs->EndGame("CLQ3_ParseGameState: bad command byte %i", c);
break;
case svcq3_configstring:
index = MSG_ReadBits(16);
index = msgfuncs->ReadBits(16);
if (index < 0 || index >= MAX_Q3_CONFIGSTRINGS)
{
Host_EndGame("CLQ3_ParseGameState: configString index %i out of range", index);
plugfuncs->EndGame("CLQ3_ParseGameState: configString index %i out of range", index);
}
configString = MSG_ReadString();
configString = msgfuncs->ReadString();
CG_InsertIntoGameState(index, configString);
break;
case svcq3_baseline:
index = MSG_ReadBits(GENTITYNUM_BITS);
index = msgfuncs->ReadBits(GENTITYNUM_BITS);
if (index < 0 || index >= MAX_GENTITIES)
{
Host_EndGame("CLQ3_ParseGameState: baseline index %i out of range", index);
plugfuncs->EndGame("CLQ3_ParseGameState: baseline index %i out of range", index);
}
MSG_Q3_ReadDeltaEntity(NULL, &ccs.baselines[index], index);
break;
}
}
cl.playerview[0].playernum = MSG_ReadLong();
ccs.fs_key = MSG_ReadLong();
ccs.playernum = msgfuncs->ReadLong();
ccs.fs_key = msgfuncs->ReadLong();
if (!CLQ3_SystemInfoChanged(CG_GetConfigString(CFGSTR_SYSINFO)))
{
@ -608,56 +624,48 @@ void CLQ3_ParseGameState(void)
return;
}
CG_Restart_f();
CG_Restart();
UI_Restart_f();
if (!cl.worldmodel)
Host_EndGame("CGame didn't set a map.\n");
if (!ccs.worldmodel)
plugfuncs->EndGame("CGame didn't set a map.\n");
cl.model_precaches_added = false;
Surf_NewMap ();
scenefuncs->NewMap (ccs.worldmodel);
SCR_EndLoadingPlaque();
CL_MakeActive("Quake3Arena");
cl.splitclients = 1;
ccs.state = ca_active;
{
char buffer[2048];
strcpy(buffer, va("cp %i ", cl.servercount));
FSQ3_GenerateClientPacksList(buffer, sizeof(buffer), ccs.fs_key);
strcpy(buffer, va("cp %i ", ccs.servercount));
fsfuncs->GenerateClientPacksList(buffer, sizeof(buffer), ccs.fs_key);
CLQ3_SendClientCommand("%s", buffer); // warning: format not a string literal and no format arguments
}
// load cgame, etc
// CL_ChangeLevel();
cl_paused = Cvar_FindVar("cl_paused");
if (cl_paused && cl_paused->ival)
Cvar_ForceSet(cl_paused, "0");
cvarfuncs->ForceSetString("cl_paused", "0");
}
void CLQ3_ParseServerMessage (void)
int CLQ3_ParseServerMessage (sizebuf_t *msg)
{
int cmd;
if (!CLQ3_Netchan_Process())
return; //was a fragment.
if (!CLQ3_Netchan_Process(msg))
return ccs.state; //was a fragment.
if (cl_shownet.value == 1)
Con_Printf ("%i ",net_message.cursize);
else if (cl_shownet.value == 2)
if (cl_shownet_ptr->value == 1)
Con_Printf ("%i ", msg->cursize);
else if (cl_shownet_ptr->value == 2)
Con_Printf ("------------------\n");
net_message.packing = SZ_RAWBYTES;
MSG_BeginReading(msg_nullnetprim);
ccs.serverMessageNum = MSG_ReadLong();
net_message.packing = SZ_HUFFMAN; //the rest is huffman compressed.
net_message.currentbit = msg_readcount*8;
msgfuncs->BeginReading(msg, msg_nullnetprim);
ccs.serverMessageNum = msgfuncs->ReadLong();
msg->packing = SZ_HUFFMAN; //the rest is huffman compressed.
// read last client command number server received
ccs.lastClientCommandNum = MSG_ReadLong();
ccs.lastClientCommandNum = msgfuncs->ReadLong();
if( ccs.lastClientCommandNum <= ccs.numClientCommands - Q3TEXTCMD_BACKUP )
{
ccs.lastClientCommandNum = ccs.numClientCommands - Q3TEXTCMD_BACKUP + 1;
@ -672,11 +680,11 @@ void CLQ3_ParseServerMessage (void)
//
for(;;)
{
cmd = MSG_ReadByte();
cmd = msgfuncs->ReadByte();
if(msg_badread) //hm, we have an eom, so only stop when the message is bad.
if(cmd < 0) //hm, we have an eom, so only stop when the message is bad.
{
Host_EndGame("CLQ3_ParseServerMessage: read past end of server message");
plugfuncs->EndGame("CLQ3_ParseServerMessage: read past end of server message");
break;
}
@ -692,12 +700,12 @@ void CLQ3_ParseServerMessage (void)
switch(cmd)
{
default:
Host_EndGame("CLQ3_ParseServerMessage: Illegible server message");
plugfuncs->EndGame("CLQ3_ParseServerMessage: Illegible server message");
break;
case svcq3_nop:
break;
case svcq3_gamestate:
CLQ3_ParseGameState();
CLQ3_ParseGameState(msg);
break;
case svcq3_serverCommand:
CLQ3_ParseServerCommand();
@ -710,71 +718,58 @@ void CLQ3_ParseServerMessage (void)
break;
}
}
return ccs.state;
}
qboolean CLQ3_Netchan_Process(void)
static qboolean CLQ3_Netchan_Process(sizebuf_t *msg)
{
#ifndef Q3_NOENCRYPT
int sequence;
int lastClientCommandNum;
qbyte bitmask;
qbyte c;
int i, j;
char *string;
int bit;
int readcount;
#endif
if(!Netchan_ProcessQ3(&cls.netchan))
if(Netchan_ProcessQ3(&ccs.netchan, msg))
{
return false;
}
#ifndef Q3_NOENCRYPT
// archive buffer state
bit = net_message.currentbit;
readcount = msg_readcount;
net_message.packing = SZ_HUFFMAN;
net_message.currentbit = 32;
int sequence;
int lastClientCommandNum;
qbyte bitmask;
qbyte c;
int i, j;
char *string;
int readcount;
lastClientCommandNum = MSG_ReadLong();
sequence = LittleLong(*(int *)net_message.data);
msgfuncs->BeginReading(msg, msg_nullnetprim);
sequence = msgfuncs->ReadLong();
msg->packing = SZ_HUFFMAN;
readcount = msg->currentbit>>3;
lastClientCommandNum = msgfuncs->ReadLong();
// restore buffer state
net_message.currentbit = bit;
msg_readcount = readcount;
// calculate bitmask
bitmask = (sequence ^ ccs.challenge) & 0xff;
string = ccs.clientCommands[lastClientCommandNum & Q3TEXTCMD_MASK];
// calculate bitmask
bitmask = (sequence ^ cls.challenge) & 0xff;
string = ccs.clientCommands[lastClientCommandNum & Q3TEXTCMD_MASK];
// decrypt the packet
for(i=msg_readcount+4,j=0 ; i<net_message.cursize ; i++,j++)
{
if(!string[j])
// decrypt the packet
for(i=readcount+4,j=0 ; i<msg->cursize ; i++,j++)
{
j = 0; // another way around
if(!string[j])
j = 0; // another way around
c = string[j];
if(c > 127 || c == '%')
c = '.';
bitmask ^= c << ((i-readcount) & 1);
msg->data[i] ^= bitmask;
}
c = string[j];
if(c > 127 || c == '%')
{
c = '.';
}
bitmask ^= c << ((i-msg_readcount) & 1);
net_message.data[i] ^= bitmask;
}
msg->packing = SZ_RAWBITS; //first bit was plain...
#endif
return true;
return true; //all good
}
return false; //its bad dude, bad.
}
void CL_Netchan_Transmit( int length, const qbyte *data )
void CL_Netchan_Transmit(struct ftenet_connections_s *socket, int length, const qbyte *data )
{
#define msg net_message
#ifndef Q3_NOENCRYPT
sizebuf_t msg;
char msgdata[MAX_OVERALLMSGLEN];
int serverid;
int lastSequence;
int lastServerCommandNum;
@ -782,47 +777,45 @@ void CL_Netchan_Transmit( int length, const qbyte *data )
qbyte c;
int i, j;
char *string;
#endif
net_message.cursize = 0;
SZ_Write(&msg, data, length);
if(msg.overflowed)
msgfuncs->BeginWriting(&msg, msg_nullnetprim, msgdata, sizeof(msgdata));
msgfuncs->WriteData(&msg, data, length);
if (msg.overflowed)
{
Host_EndGame("Client message overflowed");
plugfuncs->EndGame("Client message overflowed");
}
#ifndef Q3_NOENCRYPT
msg_readcount = 0;
msg.currentbit = 0;
msgfuncs->BeginReading(&msg, msg_nullnetprim);
msg.packing = SZ_HUFFMAN;
serverid = MSG_ReadLong();
lastSequence = MSG_ReadLong();
lastServerCommandNum = MSG_ReadLong();
serverid = msgfuncs->ReadLong();
lastSequence = msgfuncs->ReadLong();
lastServerCommandNum = msgfuncs->ReadLong();
// calculate bitmask
bitmask = (lastSequence ^ serverid ^ cls.challenge) & 0xff;
bitmask = (lastSequence ^ serverid ^ ccs.challenge) & 0xff;
string = ccs.serverCommands[lastServerCommandNum & Q3TEXTCMD_MASK];
// encrypt the packet
for( i=12,j=0 ; i<msg.cursize ; i++,j++ )
for (i=12,j=0 ; i<msg.cursize ; i++,j++)
{
if( !string[j] )
if (!string[j])
{
j = 0; // another way around
}
c = string[j];
if( c > 127 || c == '%' )
if (c > 127 || c == '%')
{
c = '.';
}
bitmask ^= c << (i & 1);
msg.data[i] ^= bitmask;
}
data = msg.data;
length = msg.cursize;
#endif
Netchan_TransmitQ3( &cls.netchan, msg.cursize, msg.data );
#undef msg
Netchan_TransmitQ3(socket, &ccs.netchan, length, data);
}
@ -832,12 +825,12 @@ static void MSG_WriteDeltaKey( sizebuf_t *msg, int key, int from, int to, int bi
{
if( from == to )
{
MSG_WriteBits( msg, 0, 1 );
msgfuncs->WriteBits( msg, 0, 1 );
return; // unchanged
}
MSG_WriteBits( msg, 1, 1 );
MSG_WriteBits( msg, to ^ key, bits );
msgfuncs->WriteBits( msg, 1, 1 );
msgfuncs->WriteBits( msg, to ^ key, bits );
}
void MSG_Q3_WriteDeltaUsercmd( sizebuf_t *msg, int key, const usercmd_t *from, const usercmd_t *to )
@ -845,29 +838,27 @@ void MSG_Q3_WriteDeltaUsercmd( sizebuf_t *msg, int key, const usercmd_t *from, c
// figure out how to pack serverTime
if( to->servertime - from->servertime < 255 )
{
MSG_WriteBits(msg, 1, 1);
MSG_WriteBits(msg, to->servertime - from->servertime, 8);
msgfuncs->WriteBits(msg, 1, 1);
msgfuncs->WriteBits(msg, to->servertime - from->servertime, 8);
}
else
{
MSG_WriteBits( msg, 0, 1 );
MSG_WriteBits( msg, to->servertime, 32);
msgfuncs->WriteBits( msg, 0, 1 );
msgfuncs->WriteBits( msg, to->servertime, 32);
}
if( !memcmp( (qbyte *)from + 4, (qbyte *)to + 4, sizeof( usercmd_t ) - 4 ) )
{
MSG_WriteBits(msg, 0, 1);
msgfuncs->WriteBits(msg, 0, 1);
return; // nothing changed
}
MSG_WriteBits(msg, 1, 1);
key ^= to->servertime;
msgfuncs->WriteBits(msg, 1, 1);
MSG_WriteDeltaKey(msg, key, from->angles[0], to->angles[0], 16);
MSG_WriteDeltaKey(msg, key, from->angles[1], to->angles[1], 16);
MSG_WriteDeltaKey(msg, key, from->angles[2], to->angles[2], 16);
MSG_WriteDeltaKey(msg, key, from->forwardmove, to->forwardmove, 8);
MSG_WriteDeltaKey(msg, key, from->sidemove, to->sidemove, 8 );
MSG_WriteDeltaKey(msg, key, from->sidemove, to->sidemove, 8);
MSG_WriteDeltaKey(msg, key, from->upmove, to->upmove, 8);
MSG_WriteDeltaKey(msg, key, from->buttons, to->buttons, 16);
MSG_WriteDeltaKey(msg, key, from->weapon, to->weapon, 8);
@ -889,28 +880,29 @@ void VARGS CLQ3_SendClientCommand(const char *fmt, ...)
// check if server will lose some of our clientCommands
if(ccs.numClientCommands - ccs.lastClientCommandNum >= Q3TEXTCMD_BACKUP)
Host_EndGame("Client command overflow");
plugfuncs->EndGame("Client command overflow");
Q_strncpyz(ccs.clientCommands[ccs.numClientCommands & Q3TEXTCMD_MASK], command, sizeof(ccs.clientCommands[0]));
Con_DPrintf("Sending %s\n", command);
}
void CLQ3_SendCmd(usercmd_t *cmd)
void CLQ3_SendCmd(struct ftenet_connections_s *socket, usercmd_t *cmd, unsigned int movesequence, double gametime)
{
char *string;
int i;
char data[MAX_OVERALLMSGLEN];
sizebuf_t msg;
outframe_t *frame, *oldframe;
// outframe_t *frame;
unsigned int oldsequence;
int cmdcount, key;
usercmd_t *to;
const usercmd_t *from;
extern cvar_t cl_nodelta, cl_c2sdupe;
const usercmd_t *to, *from;
static usercmd_t nullcmd;
//reuse the q1 array
cmd->servertime = cl.servertime*1000;
cmd->servertime = gametime*1000;
cmd->weapon = ccs.selected_weapon;
cmd->forwardmove *= 127/400.0f;
cmd->sidemove *= 127/400.0f;
cmd->upmove *= 127/400.0f;
@ -935,59 +927,55 @@ void CLQ3_SendCmd(usercmd_t *cmd)
if (Key_Dest_Has(~kdm_game))
cmd->buttons |= 2; //add in the 'at console' button
cl.outframes[cl.movesequence&Q3CMD_MASK].cmd[0] = *cmd;
cl.movesequence++;
//FIXME: q3 generates a new command every video frame, but a new packet at a more limited rate.
//FIXME: we should return here if its not yet time for a network frame.
frame = &cl.outframes[cls.netchan.outgoing_sequence & Q3CMD_MASK];
frame->cmd_sequence = cl.movesequence;
/* frame = &cl.outframes[ccs.netchan.outgoing_sequence & Q3CMD_MASK];
frame->cmd_sequence = movesequence;
frame->server_message_num = ccs.serverMessageNum;
frame->server_time = cl.gametime;
frame->client_time = Sys_DoubleTime()*1000;
frame->server_time = gametime;
frame->client_time = plugfuncs->GetMilliseconds();
*/
memset(&msg, 0, sizeof(msg));
msg.maxsize = sizeof(data);
msg.data = data;
msg.packing = SZ_HUFFMAN;
MSG_WriteBits(&msg, cl.servercount, 32);
MSG_WriteBits(&msg, ccs.serverMessageNum, 32);
MSG_WriteBits(&msg, ccs.lastServerCommandNum, 32);
msgfuncs->WriteBits(&msg, ccs.servercount, 32);
msgfuncs->WriteBits(&msg, ccs.serverMessageNum, 32);
msgfuncs->WriteBits(&msg, ccs.lastServerCommandNum, 32);
// write clientCommands not acknowledged by server yet
for (i=ccs.lastClientCommandNum+1; i<=ccs.numClientCommands; i++)
{
MSG_WriteBits(&msg, clcq3_clientCommand, 8);
MSG_WriteBits(&msg, i, 32);
msgfuncs->WriteBits(&msg, clcq3_clientCommand, 8);
msgfuncs->WriteBits(&msg, i, 32);
string = ccs.clientCommands[i & Q3TEXTCMD_MASK];
while(*string)
MSG_WriteBits(&msg, *string++, 8);
MSG_WriteBits(&msg, 0, 8);
msgfuncs->WriteBits(&msg, *string++, 8);
msgfuncs->WriteBits(&msg, 0, 8);
}
i = cls.netchan.outgoing_sequence;
i -= bound(0, cl_c2sdupe.ival, 5); //extra age, if desired
i = ccs.netchan.outgoing_sequence;
i -= bound(0, cl_c2sdupe_ptr->ival, 5); //extra age, if desired
i--;
if (i < cls.netchan.outgoing_sequence-Q3CMD_MASK)
i = cls.netchan.outgoing_sequence-Q3CMD_MASK;
oldframe = &cl.outframes[i & Q3CMD_MASK];
cmdcount = cl.movesequence - oldframe->cmd_sequence;
if (i < ccs.netchan.outgoing_sequence-Q3CMD_MASK)
i = ccs.netchan.outgoing_sequence-Q3CMD_MASK;
oldsequence = movesequence-1;//cl.outframes[i & Q3CMD_MASK].cmd_sequence;
cmdcount = movesequence - oldsequence;
if (cmdcount > Q3CMD_MASK)
cmdcount = Q3CMD_MASK;
// begin a client move command, if any
if (cmdcount)
{
if(cl_nodelta.value || !ccs.snap.valid ||
ccs.snap.serverMessageNum != ccs.serverMessageNum)
MSG_WriteBits(&msg, clcq3_nodeltaMove, 8); // no compression
if(cl_nodelta_ptr->value || !ccs.snap.valid || ccs.snap.serverMessageNum != ccs.serverMessageNum)
msgfuncs->WriteBits(&msg, clcq3_nodeltaMove, 8); // no compression
else
MSG_WriteBits(&msg, clcq3_move, 8);
msgfuncs->WriteBits(&msg, clcq3_move, 8);
// write cmdcount
MSG_WriteBits(&msg, cmdcount, 8);
msgfuncs->WriteBits(&msg, cmdcount, 8);
// calculate key
string = ccs.serverCommands[ccs.lastServerCommandNum & Q3TEXTCMD_MASK];
@ -996,22 +984,24 @@ void CLQ3_SendCmd(usercmd_t *cmd)
//note that q3 uses timestamps so sequences are not important
//we can also send dupes without issue.
from = &nullcmd;
for (i = cl.movesequence-cmdcount; i < cl.movesequence; i++)
for (i = movesequence-cmdcount; i < movesequence; i++)
{
to = &cl.outframes[i&Q3CMD_MASK].cmd[0];
to = inputfuncs->GetMoveEntry(i);
if (!to)
to = from;
MSG_Q3_WriteDeltaUsercmd( &msg, key, from, to );
from = to;
}
}
MSG_WriteBits(&msg, clcq3_eom, 8);
msgfuncs->WriteBits(&msg, clcq3_eom, 8);
CL_Netchan_Transmit( msg.cursize, msg.data );
while(cls.netchan.reliable_length)
Netchan_TransmitNextFragment(&cls.netchan);
CL_Netchan_Transmit(socket, msg.cursize, msg.data );
while(ccs.netchan.reliable_length)
Netchan_TransmitNextFragment(socket, &ccs.netchan);
}
void CLQ3_SendAuthPacket(netadr_t *gameserver)
void CLQ3_SendAuthPacket(struct ftenet_connections_s *socket, netadr_t *gameserver)
{
#ifdef HAVE_PACKET
char data[2048];
@ -1021,30 +1011,27 @@ void CLQ3_SendAuthPacket(netadr_t *gameserver)
//this should be the right code, but it doesn't work.
if (gameserver->type == NA_IP)
{
char *key = Cvar_Get("cl_cdkey", "", 0, "Quake3 auth")->string;
char *key = cvarfuncs->GetNVFDG("cl_cdkey", "", CVAR_ARCHIVE, "Quake3 auth", "Q3 Compat")->string;
netadr_t authaddr;
#define Q3_AUTHORIZE_SERVER_NAME "authorize.quake3arena.com:27952"
if (*key)
{
Con_Printf("Resolving %s\n", Q3_AUTHORIZE_SERVER_NAME);
if (NET_StringToAdr(Q3_AUTHORIZE_SERVER_NAME, 0, &authaddr))
if (masterfuncs->StringToAdr(Q3_AUTHORIZE_SERVER_NAME, 0, &authaddr, 1, NULL))
{
msg.data = data;
msg.cursize = 0;
msg.overflowed = msg.allowoverflow = 0;
msg.maxsize = sizeof(data);
MSG_WriteLong(&msg, -1);
MSG_WriteString(&msg, "getKeyAuthorize 0 ");
msgfuncs->BeginWriting(&msg, msg_nullnetprim, data, sizeof(data));
msgfuncs->WriteLong(&msg, -1);
msgfuncs->WriteString(&msg, "getKeyAuthorize 0 ");
msg.cursize--;
while(*key)
{
if ((*key >= 'a' && *key <= 'z') || (*key >= 'A' && *key <= 'Z') || (*key >= '0' && *key <= '9'))
MSG_WriteByte(&msg, *key);
msgfuncs->WriteByte(&msg, *key);
key++;
}
MSG_WriteByte(&msg, 0);
msgfuncs->WriteByte(&msg, 0);
NET_SendPacket (cls.sockets, msg.cursize, msg.data, &authaddr);
msgfuncs->SendPacket(socket, msg.cursize, msg.data, &authaddr);
}
else
Con_Printf(" failed\n");
@ -1053,33 +1040,45 @@ void CLQ3_SendAuthPacket(netadr_t *gameserver)
#endif
}
void CLQ3_SendConnectPacket(netadr_t *to, int challenge, int qport)
void CLQ3_SendConnectPacket(struct ftenet_connections_s *socket, netadr_t *to, int challenge, int qport, infobuf_t *userinfo)
{
char infostr[1024];
char data[2048];
sizebuf_t msg;
static const char *priorityq3[] = {"*", "name", NULL};
static const char *nonq3[] = {"challenge", "qport", "protocol", "ip", "chat", NULL};
int protocol = cvarfuncs->GetFloat("com_protocolversion");
memset(&ccs, 0, sizeof(ccs));
ccs.servercount = -1;
ccs.challenge = challenge;
Netchan_SetupQ3(NS_CLIENT, &ccs.netchan, to, qport);
InfoBuf_ToString(&cls.userinfo[0], infostr, sizeof(infostr), basicuserinfos, nonq3, NULL, &cls.userinfosync, &cls.userinfo[0]);
worldfuncs->IBufToInfo(userinfo, infostr, sizeof(infostr), priorityq3, nonq3, NULL, NULL,/*&cls.userinfosync,*/ userinfo);
cl.splitclients = 1;
msg.data = data;
msg.cursize = 0;
msg.overflowed = msg.allowoverflow = 0;
msg.maxsize = sizeof(data);
MSG_WriteLong(&msg, -1);
MSG_WriteString(&msg, va("connect \"\\challenge\\%i\\qport\\%i\\protocol\\%i%s\"", challenge, qport, PROTOCOL_VERSION_Q3, infostr));
msgfuncs->BeginWriting(&msg, msg_nullnetprim, data, sizeof(data));
msgfuncs->WriteLong(&msg, -1);
msgfuncs->WriteString(&msg, va("connect \"\\challenge\\%i\\qport\\%i\\protocol\\%i%s\"", challenge, qport, protocol, infostr));
#ifdef HUFFNETWORK
Huff_EncryptPacket(&msg, 12);
if (!Huff_CompressionCRC(HUFFCRC_QUAKE3))
if (msgfuncs->Huff_EncryptPacket)
msgfuncs->Huff_EncryptPacket(&msg, 12);
if (!msgfuncs->Huff_CompressionCRC || !msgfuncs->Huff_CompressionCRC(HUFFCRC_QUAKE3))
{
Con_Printf("Huffman compression error\n");
return;
}
#endif
NET_SendPacket (cls.sockets, msg.cursize, msg.data, to);
msgfuncs->SendPacket (socket, msg.cursize, msg.data, to);
}
void CLQ3_Established(void)
{
ccs.state = ca_connected;
}
void CLQ3_Disconnect(struct ftenet_connections_s *socket)
{
ccs.state = ca_disconnected;
}
#endif

View File

@ -1,11 +1,6 @@
#ifndef _Q3DEFS_H_
#define _Q3DEFS_H_
//#define Q3_NOENCRYPT //a debugging property, makes it incompatible with q3
#define PROTOCOL_VERSION_Q3 68
void Q3_SetKeyCatcher(int newcatcher);
int Q3_GetKeyCatcher(void);
@ -24,10 +19,9 @@ typedef struct {
#define MAX_Q3_STATS 16
#define MAX_Q3_PERSISTANT 16
#define MAX_Q3_POWERUPS 16
#define MAX_Q3_POWERUPS 16
#define MAX_Q3_WEAPONS 16
#define MAX_PS_EVENTS 2
#define MAX_PS_EVENTS 2
typedef struct q3playerState_s {
int commandTime; // cmd->serverTime of last executed command
int pm_type;
@ -85,16 +79,15 @@ typedef struct q3playerState_s {
int persistant[MAX_Q3_PERSISTANT]; // stats that aren't cleared on death
int powerups[MAX_Q3_POWERUPS]; // level.time that the powerup runs out
int ammo[MAX_Q3_WEAPONS];
int generic1;
int loopSound;
int jumppad_ent; // jumppad entity hit this frame
// not communicated over the net at all
int ping; // server to game info for scoreboard
int pmove_framecount; // FIXME: don't transmit over the network
int jumppad_frame;
int entityEventSequence;
} q3playerState_t;
@ -149,6 +142,7 @@ typedef struct q3entityState_s {
int event; // impulse events -- muzzle flashes, footsteps, etc
int eventParm;
// for players
int powerups; // bit flags
int weapon; // determines weapon and flash model, etc
@ -162,6 +156,7 @@ typedef struct q3entityState_s {
#define MAX_MAP_AREA_BYTES 32
#define MAX_ENTITIES_IN_SNAPSHOT 256
//This struct is exposed to the cgame
typedef struct snapshot_s {
int snapFlags; // SNAPFLAG_RATE_DELAYED, etc
int ping;
@ -182,9 +177,7 @@ typedef struct snapshot_s {
//
// clientSnap_t is will be converted to snapshot_t for internal cgame use
//
//this struct is used internally, using a ringbuffer for entities instead of worst-case memory usage.
typedef struct clientSnap_s {
qboolean valid; // cleared if delta parsing was invalid
int snapFlags;
@ -220,32 +213,45 @@ typedef struct {
#define Q3MAX_PARSE_ENTITIES 2048
#define Q3PARSE_ENTITIES_MASK (Q3MAX_PARSE_ENTITIES-1)
#define MAX_Q3_GAMESTATE_CHARS 16000
#define MAX_STRING_CHARS 1024
#define Q3TEXTCMD_BACKUP 64 //number of reliable text commands that can be queued, must be power of two
#define MAX_Q3_CONFIGSTRINGS 1024
#define Q3TEXTCMD_BACKUP 64 //number of reliable text commands that can be queued, must be power of two
#define Q3TEXTCMD_MASK (Q3TEXTCMD_BACKUP-1)
#define MAX_Q3_CONFIGSTRINGS 1024
#define CFGSTR_SYSINFO 1
#define MODELINDEX_BITS 8
#define GENTITYNUM_BITS 10
#define MAX_GENTITIES (1<<GENTITYNUM_BITS)
#define ENTITYNUM_NONE (MAX_GENTITIES-1)
typedef struct {
cactive_t state;
double time;
netchan_t netchan;
unsigned int challenge;
int lastClientCommandNum;
int lastServerCommandNum;
int numClientCommands;
int serverMessageNum;
int servercount; //bumped on map changes
int serverMessageNum;
int downloadchunknum;
int firstParseEntity;
int playernum;
int fs_key;
//this stuff gets inserted into usercmd_t messages.
int selected_weapon;
qdownload_t *download;
model_t *worldmodel;
model_t *model_precache[1u<<MODELINDEX_BITS];
clientSnap_t snapshots[Q3UPDATE_BACKUP];
clientSnap_t snap;
@ -317,6 +323,7 @@ typedef struct {
char name[OLD_MAX_QPATH];
} fontInfo_t;
void UI_RegisterFont(char *fontName, int pointSize, fontInfo_t *font);
qboolean UI_OpenMenu(void);
int UI_Cin_Play(const char *name, int x, int y, int w, int h, unsigned int flags);
int UI_Cin_Stop(int idx);
@ -324,13 +331,43 @@ int UI_Cin_Run(int idx);
int UI_Cin_Draw(int idx);
int UI_Cin_SetExtents(int idx, int x, int y, int w, int h);
void Netchan_TransmitNextFragment( netchan_t *chan );
void Netchan_TransmitQ3( netchan_t *chan, int length, const qbyte *data );
qboolean Netchan_ProcessQ3 (netchan_t *chan);
typedef struct {
char renderer_string[MAX_STRING_CHARS];
char vendor_string[MAX_STRING_CHARS];
char version_string[MAX_STRING_CHARS];
char extensions_string[8192];
qboolean MSG_Q3_ReadDeltaEntity( const q3entityState_t *from, q3entityState_t *to, int number );
int maxTextureSize; // queried from GL
int numTextureUnits; // multitexture ability
int colorBits, depthBits, stencilBits;
int driverType; //glDriverType_t
int hardwareType; //glHardwareType_t
qboolean deviceSupportsGamma;
int textureCompression; //textureCompression_t
qboolean textureEnvAddAvailable;
int vidWidth, vidHeight;
float windowAspect;
int displayFrequency;
qboolean isFullscreen;
qboolean stereoEnabled;
qboolean smpActive;
} q3glconfig_t;
void Netchan_SetupQ3(netsrc_t sock, netchan_t *chan, netadr_t *adr, int qport);
void Netchan_TransmitNextFragment(struct ftenet_connections_s *socket, netchan_t *chan);
void Netchan_TransmitQ3(struct ftenet_connections_s *socket, netchan_t *chan, int length, const qbyte *data);
qboolean Netchan_ProcessQ3 (netchan_t *chan, sizebuf_t *msg);
qboolean MSG_Q3_ReadDeltaEntity(const q3entityState_t *from, q3entityState_t *to, int number);
void MSGQ3_WriteDeltaEntity(sizebuf_t *msg, const q3entityState_t *from, const q3entityState_t *to, qboolean force);
void MSG_Q3_ReadDeltaPlayerstate( const q3playerState_t *from, q3playerState_t *to );
void MSG_Q3_ReadDeltaPlayerstate(const q3playerState_t *from, q3playerState_t *to);
void MSGQ3_WriteDeltaPlayerstate(sizebuf_t *msg, const q3playerState_t *from, const q3playerState_t *to);
void MSG_Q3_ReadDeltaUsercmd(int key, const usercmd_t *from, usercmd_t *to);
@ -343,8 +380,59 @@ void MSG_WriteBits(sizebuf_t *msg, int value, int bits);
typedef struct q3refEntity_s q3refEntity_t;
void VQ3_AddEntity(const q3refEntity_t *q3);
typedef struct q3polyvert_s q3polyvert_t;
void VQ3_AddPoly(shader_t *s, int num, q3polyvert_t *verts);
void VQ3_AddPolys(shader_t *s, int num, q3polyvert_t *verts, size_t count);
typedef struct q3refdef_s q3refdef_t;
void VQ3_RenderView(const q3refdef_t *ref);
qboolean CG_FillQ3Snapshot(int snapnum, snapshot_t *snapshot);
void CG_ClearGameState(void);
void CG_InsertIntoGameState(int num, const char *str);
const char *CG_GetConfigString(int num);
void CG_Restart(void);
void UI_Restart_f(void);
vm_t *UI_GetUIVM(void);
int Script_LoadFile(char *filename);
void Script_Get_File_And_Line(int handle, char *filename, int *line);
int Script_Read(int handle, struct pc_token_s *token);
void Script_Free(int handle);
void VARGS CLQ3_SendClientCommand(const char *fmt, ...) LIKEPRINTF(1);
void CLQ3_SendAuthPacket(struct ftenet_connections_s *socket, netadr_t *gameserver);
void CLQ3_SendConnectPacket(struct ftenet_connections_s *socket, netadr_t *to, int challenge, int qport, infobuf_t *userinfo);
void CLQ3_Established(void);
void CLQ3_Disconnect(struct ftenet_connections_s *socket);
void CLQ3_SendCmd(struct ftenet_connections_s *socket, usercmd_t *cmd, unsigned int movesequence, double gametime);
int CLQ3_ParseServerMessage (sizebuf_t *msg);
void CG_Stop (void);
void CG_Start (void);
int CG_Refresh(double time);
qboolean CG_ConsoleCommand(void);
qboolean CG_KeyPressed(int key, int unicode, int down);
unsigned int CG_GatherLoopingSounds(vec3_t *positions, unsigned int *entnums, sfx_t **sounds, unsigned int max);
qboolean UI_IsRunning(void);
qboolean UI_ConsoleCommand(void);
void UI_Init (void);
void UI_Start (void);
void UI_Stop (void);
qboolean UI_OpenMenu(void);
void UI_Reset(void);
void SVQ3_ShutdownGame(qboolean restarting);
qboolean SVQ3_InitGame(server_static_t *server_state_static, server_t *server_state, qboolean restart);
qboolean SVQ3_ConsoleCommand(void);
qboolean SVQ3_PrefixedConsoleCommand(void);
qboolean SVQ3_HandleClient(netadr_t *from, sizebuf_t *msg);
void SVQ3_DirectConnect(netadr_t *from, sizebuf_t *msg);
void SVQ3_NewMapConnects(void);
void SVQ3_DropClient(struct client_s *cl);
void SVQ3_RunFrame(void);
void SVQ3_SendMessage(struct client_s *client);
qboolean SVQ3_RestartGamecode(void);
void SVQ3_ServerinfoChanged(const char *key);
#endif

View File

@ -2749,25 +2749,22 @@ static void Con_DrawModelPreview(model_t *model, float x, float y, float w, floa
VectorScale(ent.axis[0], scale, ent.axis[0]);
VectorScale(ent.axis[1], scale, ent.axis[1]);
VectorScale(ent.axis[2], scale, ent.axis[2]);
/*if (strstr(model->name, "player"))
{
ent.bottomcolour = genhsv(realtime*0.1 + 0, 1, 1);
ent.topcolour = genhsv(realtime*0.1 + 0.5, 1, 1);
}
else*/
{
ent.topcolour = TOP_DEFAULT;
ent.bottomcolour = BOTTOM_DEFAULT;
}
ent.topcolour = TOP_DEFAULT;
ent.bottomcolour = BOTTOM_DEFAULT;
// ent.fatness = sin(realtime)*5;
ent.playerindex = -1;
ent.skinnum = 0;
ent.shaderTime = 0;//realtime;
ent.framestate.g[FS_REG].lerpweight[0] = 1;
// ent.framestate.g[FS_REG].frame[0] = animationnum;
ent.framestate.g[FS_REG].frametime[0] = ent.framestate.g[FS_REG].frametime[1] = realtime;
ent.framestate.g[FS_REG].endbone = 0x7fffffff;
// ent.customskin = Mod_RegisterSkinFile(va("%s_0.skin", mods->modelname));
ent.customskin = Mod_RegisterSkinFile(va("%s_0.skin", model->publicname));
if (ent.customskin == 0)
{
char haxxor[MAX_QPATH];
COM_StripExtension(model->publicname, haxxor, sizeof(haxxor));
ent.customskin = Mod_RegisterSkinFile(va("%s_default.skin", haxxor));
}
Vector4Set(ent.shaderRGBAf, 1,1,1,1);
VectorSet(ent.glowmod, 1,1,1);

View File

@ -839,4 +839,4 @@ void Stats_NewMap(void)
{
Stats_LoadFragFile("fragfile");
}
#endif
#endif

View File

@ -50,7 +50,6 @@ qbyte bindcmdlevel[K_MAX][KEY_MODIFIERSTATES]; //should be a struct, but not due
qboolean consolekeys[K_MAX]; // if true, can't be rebound while in console
int keyshift[K_MAX]; // key to map to if shift held down in console
unsigned int keydown[K_MAX]; // bitmask, for each device (to block autorepeat binds per-seat).
//unsigned int key_modifier[K_MAX];
#define MAX_INDEVS 8
@ -273,6 +272,8 @@ keyname_t keynames[] =
{"PLUS", '+'}, // because "shift++" is inferior to shift+plus
{"MINUS", '-'}, // because "shift+-" is inferior to shift+minus
{"APOSTROPHE", '\''}, //can mess up string parsing, unfortunately
{"QUOTES", '\"'}, //can mess up string parsing, unfortunately
{"TILDE", '~'},
{"BACKQUOTE", '`'},
{"BACKSLASH", '\\'},
@ -2845,32 +2846,6 @@ void Key_Init (void)
consolekeys[K_MWHEELUP] = true;
consolekeys[K_MWHEELDOWN] = true;
for (i=0 ; i<K_MAX ; i++)
keyshift[i] = i;
for (i='a' ; i<='z' ; i++)
keyshift[i] = i - 'a' + 'A';
keyshift['1'] = '!';
keyshift['2'] = '@';
keyshift['3'] = '#';
keyshift['4'] = '$';
keyshift['5'] = '%';
keyshift['6'] = '^';
keyshift['7'] = '&';
keyshift['8'] = '*';
keyshift['9'] = '(';
keyshift['0'] = ')';
keyshift['-'] = '_';
keyshift['='] = '+';
keyshift[','] = '<';
keyshift['.'] = '>';
keyshift['/'] = '?';
keyshift[';'] = ':';
keyshift['\''] = '"';
keyshift['['] = '{';
keyshift[']'] = '}';
keyshift['`'] = '~';
keyshift['\\'] = '|';
//
// register our functions
//
@ -2969,7 +2944,7 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down
return;
#endif
#ifdef VM_CG
if (CG_KeyPress(key, unicode, down))
if (q3 && q3->cg.KeyPressed(key, unicode, down))
return;
#endif
}

View File

@ -32,9 +32,9 @@ static char enginerevision[256] = STRINGIFY(SVNREVISION);
#ifdef ENABLEPLUGINSBYDEFAULT
cvar_t pkg_autoupdate = CVARFD("pkg_autoupdate", "1", CVAR_NOTFROMSERVER|CVAR_NOSAVE|CVAR_NOSET, "Controls autoupdates, can only be changed via the downloads menu.\n0: off.\n1: enabled (stable only).\n2: enabled (unstable).\nNote that autoupdate will still prompt the user to actually apply the changes."); //read from the package list only.
cvar_t pkg_autoupdate = CVARFD("pkg_autoupdate", "1", CVAR_NOTFROMSERVER|CVAR_NOSAVE|CVAR_NOSET|CVAR_NORESET, "Controls autoupdates, can only be changed via the downloads menu.\n0: off.\n1: enabled (stable only).\n2: enabled (unstable).\nNote that autoupdate will still prompt the user to actually apply the changes."); //read from the package list only.
#else
cvar_t pkg_autoupdate = CVARFD("pkg_autoupdate", "-1", CVAR_NOTFROMSERVER|CVAR_NOSAVE|CVAR_NOSET, "Controls autoupdates, can only be changed via the downloads menu.\n0: off.\n1: enabled (stable only).\n2: enabled (unstable).\nNote that autoupdate will still prompt the user to actually apply the changes."); //read from the package list only.
cvar_t pkg_autoupdate = CVARFD("pkg_autoupdate", "-1", CVAR_NOTFROMSERVER|CVAR_NOSAVE|CVAR_NOSET|CVAR_NORESET, "Controls autoupdates, can only be changed via the downloads menu.\n0: off.\n1: enabled (stable only).\n2: enabled (unstable).\nNote that autoupdate will still prompt the user to actually apply the changes."); //read from the package list only.
#endif
#define INSTALLEDFILES "installed.lst" //the file that resides in the quakedir (saying what's installed).
@ -198,6 +198,8 @@ static char *manifestpackages; //metapackage named by the manicfest.
static char *declinedpackages; //metapackage named by the manicfest.
static int domanifestinstall; //SECURITY_MANIFEST_*
static int pluginsadded; //so we only show prompts for new externally-installed plugins once, instead of every time the file is reloaded.
#ifdef WEBCLIENT
static struct
{
@ -1638,8 +1640,19 @@ static qboolean PM_ParsePackageList(const char *f, unsigned int parseflags, cons
return forcewrite;
}
static qboolean PM_NameIsInStrings(const char *strings, const char *match)
{
char tok[1024];
while (strings && *strings)
{
strings = COM_ParseStringSetSep(strings, ';', tok, sizeof(tok));
if (!Q_strcasecmp(tok, match)) //okay its here.
return true;
}
return false;
}
#ifdef PLUGINS
void PM_EnumeratePlugins(void (*callback)(const char *name))
void PM_EnumeratePlugins(void (*callback)(const char *name, qboolean blocked))
{
package_t *p;
struct packagedep_s *d;
@ -1655,7 +1668,10 @@ void PM_EnumeratePlugins(void (*callback)(const char *name))
if (d->dtype == DEP_FILE)
{
if (!Q_strncasecmp(d->name, PLUGINPREFIX, strlen(PLUGINPREFIX)))
callback(d->name);
{
qboolean blocked = PM_NameIsInStrings(manifestpackages, va("!%s", p->name));
callback(d->name, blocked);
}
}
}
}
@ -2050,20 +2066,10 @@ static void PM_PreparePackageList(void)
#ifdef PLUGINS
{
int foundone = false;
char nat[MAX_OSPATH];
FS_NativePath("", FS_BINARYPATH, nat, sizeof(nat));
Con_DPrintf("Loading plugins from \"%s\"\n", nat);
Sys_EnumerateFiles(nat, PLUGINPREFIX"*" ARCH_DL_POSTFIX, PM_EnumeratedPlugin, &foundone, NULL);
#ifndef ENABLEPLUGINSBYDEFAULT
if (foundone && !pluginpromptshown)
{
pluginpromptshown = true;
#ifndef SERVERONLY
Menu_Prompt(PM_PluginDetected, NULL, "Plugin(s) appears to have\nbeen installed externally.\nUse the updates menu\nto enable them.", "View", "Disable", "Later...");
#endif
}
#endif
Sys_EnumerateFiles(nat, PLUGINPREFIX"*" ARCH_DL_POSTFIX, PM_EnumeratedPlugin, &pluginsadded, NULL);
}
#endif
}
@ -2462,18 +2468,6 @@ static qboolean PM_MarkPackage(package_t *package, unsigned int markflag)
return true;
}
static qboolean PM_NameIsInStrings(const char *strings, const char *match)
{
char tok[1024];
while (strings && *strings)
{
strings = COM_ParseStringSetSep(strings, ';', tok, sizeof(tok));
if (!Q_strcasecmp(tok, match)) //okay its here.
return true;
}
return false;
}
//just flag stuff as needing updating
unsigned int PM_MarkUpdates (void)
{
@ -2491,13 +2485,14 @@ unsigned int PM_MarkUpdates (void)
char *strings = manifestpackages;
while (strings && *strings)
{
strings = COM_ParseStringSetSep(strings, ';', tok, sizeof(tok));
if (PM_NameIsInStrings(declinedpackages, tok))
continue;
qboolean isunwanted = (*tok=='!');
strings = COM_ParseStringSetSep(strings, ';', tok+isunwanted, sizeof(tok));
p = PM_MarkedPackage(tok, DPF_MARKED);
if (!p)
{
if (PM_NameIsInStrings(declinedpackages, tok))
continue;
p = PM_FindPackage(tok);
if (p)
{
@ -2505,6 +2500,11 @@ unsigned int PM_MarkUpdates (void)
changecount++;
}
}
else if (isunwanted)
{
PM_UnmarkPackage(p, DPF_AUTOMARKED); //try and unmark it.
changecount++;
}
else if (!(p->flags & DPF_ENABLED))
changecount++;
}
@ -2685,6 +2685,7 @@ static void PM_ListDownloaded(struct dl_download *dl)
if (f)
{
pm_source[listidx].status = SRCSTAT_OBTAINED;
downloadablessequence++;
if (pm_source[listidx].flags & SRCFL_UNSAFE)
PM_ParsePackageList(f, DPF_SIGNATUREACCEPTED, dl->url, pm_source[listidx].prefix);
else
@ -2837,7 +2838,7 @@ static void PM_UpdatePackageList(qboolean autoupdate, int retry)
else if (allowphonehome == -1)
{
if (retry)
Menu_Prompt(PM_AllowPackageListQuery_Callback, NULL, "Query updates list?\n", "Okay", NULL, "Nope");
Menu_Prompt(PM_AllowPackageListQuery_Callback, NULL, "Query updates list?\n", "Okay", NULL, "Nope", true);
return;
}
#else
@ -2888,6 +2889,7 @@ static void PM_UpdatePackageList(qboolean autoupdate, int retry)
}
}
}
#endif
if (autoupdate)
{
@ -2902,7 +2904,6 @@ static void PM_UpdatePackageList(qboolean autoupdate, int retry)
PM_PrintChanges();
}
}
#endif
}
qboolean PM_RegisterUpdateSource(void *module, plugupdatesourcefuncs_t *funcs)
@ -3304,16 +3305,16 @@ static void PM_PackageEnabled(package_t *p)
}
#ifndef HAVE_CLIENT
#define Menu_Prompt(cb,ctx,msg,yes,no,cancel) Con_Printf(CON_WARNING msg "\n")
#define Menu_Prompt(cb,ctx,msg,yes,no,cancel,highpri) Con_Printf(CON_WARNING msg "\n")
#endif
if (FS_NativePath(ef->name, p->fsroot, native, sizeof(native)) && Sys_SetUpdatedBinary(native))
{
Q_strncpyz(enginerevision, p->version, sizeof(enginerevision)); //make sure 'revert' picks up the new binary...
Menu_Prompt(NULL, NULL, "Engine binary updated.\nRestart to use.", NULL, NULL, NULL);
Menu_Prompt(NULL, NULL, "Engine binary updated.\nRestart to use.", NULL, NULL, NULL, true);
}
else
Menu_Prompt(NULL, NULL, "Engine update failed.\nManual update required.", NULL, NULL, NULL);
Menu_Prompt(NULL, NULL, "Engine update failed.\nManual update required.", NULL, NULL, NULL, true);
}
#endif
}
@ -4381,7 +4382,7 @@ static void PM_PromptApplyChanges(void)
//lock it down, so noone can make any changes while this prompt is still displayed
if (pkg_updating)
{
Menu_Prompt(PM_PromptApplyChanges_Callback, NULL, "An update is already in progress\nPlease wait\n", NULL, NULL, "Cancel");
Menu_Prompt(PM_PromptApplyChanges_Callback, NULL, "An update is already in progress\nPlease wait\n", NULL, NULL, "Cancel", true);
return;
}
pkg_updating = true;
@ -4389,7 +4390,7 @@ static void PM_PromptApplyChanges(void)
strcpy(text, "Really decline the following\nrecommended packages?\n\n");
if (PM_DeclinedPackages(text+strlen(text), sizeof(text)-strlen(text)))
Menu_Prompt(PM_PromptApplyDecline_Callback, NULL, text, NULL, "Confirm", "Cancel");
Menu_Prompt(PM_PromptApplyDecline_Callback, NULL, text, NULL, "Confirm", "Cancel", true);
else
{
strcpy(text, "Apply the following changes?\n\n");
@ -4401,7 +4402,7 @@ static void PM_PromptApplyChanges(void)
#endif
}
else
Menu_Prompt(PM_PromptApplyChanges_Callback, NULL, text, "Apply", NULL, "Cancel");
Menu_Prompt(PM_PromptApplyChanges_Callback, NULL, text, "Apply", NULL, "Cancel", true);
}
}
#endif
@ -4499,7 +4500,7 @@ void PM_Command_f(void)
else
{
#ifdef HAVE_CLIENT
Menu_Prompt(PM_AddSubList_Callback, Z_StrDup(Cmd_Argv(2)), va("Add updates source?\n%s", Cmd_Argv(2)), "Confirm", NULL, "Cancel");
Menu_Prompt(PM_AddSubList_Callback, Z_StrDup(Cmd_Argv(2)), va("Add updates source?\n%s", Cmd_Argv(2)), "Confirm", NULL, "Cancel", true);
#else
PM_AddSubList(Cmd_Argv(2), "", SRCFL_USER|SRCFL_ENABLED);
PM_WriteInstalledPackages();
@ -5176,7 +5177,7 @@ qboolean PM_CanInstall(const char *packagename)
{
return false;
}
void PM_EnumeratePlugins(void (*callback)(const char *name))
void PM_EnumeratePlugins(void (*callback)(const char *name, qboolean blocked))
{
}
void PM_ManifestPackage(const char *metaname, int security)
@ -5215,6 +5216,15 @@ static void MD_Draw (int x, int y, struct menucustom_s *c, struct emenu_s *m)
if (c->dint != downloadablessequence)
return; //probably stale
if (allowphonehome == -2)
{
allowphonehome = false;
#ifdef HAVE_CLIENT
Menu_Prompt(PM_AllowPackageListQuery_Callback, NULL, "Query updates list?\n", "Okay", NULL, "Nope", true);
#endif
}
p = c->dptr;
if (p)
{
@ -5251,16 +5261,16 @@ static void MD_Draw (int x, int y, struct menucustom_s *c, struct emenu_s *m)
if (!(p->flags & DPF_ENABLED))
{ //DPF_MARKED|!DPF_ENABLED:
if (p->flags & DPF_PURGE)
Draw_FunStringWidth (x, y, "GET", 48, 2, false);
Draw_FunStringWidth (x, y, S_COLOR_GREEN"GET", 48, 2, false);
else if (p->flags & (DPF_PRESENT))
Draw_FunStringWidth (x, y, "USE", 48, 2, false);
Draw_FunStringWidth (x, y, S_COLOR_GREEN"USE", 48, 2, false);
else
Draw_FunStringWidth (x, y, "GET", 48, 2, false);
Draw_FunStringWidth (x, y, S_COLOR_GREEN"GET", 48, 2, false);
}
else
{ //DPF_MARKED|DPF_ENABLED:
if (p->flags & DPF_PURGE)
Draw_FunStringWidth (x, y, "GET", 48, 2, false); //purge and reinstall.
Draw_FunStringWidth (x, y, S_COLOR_GREEN"GET", 48, 2, false); //purge and reinstall.
else if (p->flags & DPF_CORRUPT)
Draw_FunStringWidth (x, y, "?""?""?", 48, 2, false);
else
@ -5272,20 +5282,20 @@ static void MD_Draw (int x, int y, struct menucustom_s *c, struct emenu_s *m)
}
}
else if (p->flags & DPF_MARKED)
{
{ //auto-use options. draw with half alpha to darken them a little.
if (!(p->flags & DPF_ENABLED))
{ //DPF_MARKED|!DPF_ENABLED:
if (p->flags & DPF_PURGE)
Draw_FunStringWidth (x, y, "^hGET", 48, 2, false);
Draw_FunStringWidth (x, y, S_COLOR_GREEN"^hGET", 48, 2, false);
else if (p->flags & (DPF_PRESENT))
Draw_FunStringWidth (x, y, "^hUSE", 48, 2, false);
Draw_FunStringWidth (x, y, S_COLOR_GREEN"^hUSE", 48, 2, false);
else
Draw_FunStringWidth (x, y, "^hGET", 48, 2, false);
Draw_FunStringWidth (x, y, S_COLOR_GREEN"^hGET", 48, 2, false);
}
else
{ //DPF_MARKED|DPF_ENABLED:
if (p->flags & DPF_PURGE)
Draw_FunStringWidth (x, y, "^hGET", 48, 2, false); //purge and reinstall.
Draw_FunStringWidth (x, y, S_COLOR_GREEN"^hGET", 48, 2, false); //purge and reinstall.
else if (p->flags & DPF_CORRUPT)
Draw_FunStringWidth (x, y, "?""?""?", 48, 2, false);
else
@ -5301,7 +5311,7 @@ static void MD_Draw (int x, int y, struct menucustom_s *c, struct emenu_s *m)
if (!(p->flags & DPF_ENABLED))
{ //!DPF_MARKED|!DPF_ENABLED:
if (p->flags & DPF_PURGE)
Draw_FunStringWidth (x, y, "DEL", 48, 2, false); //purge
Draw_FunStringWidth (x, y, S_COLOR_RED"DEL", 48, 2, false); //purge
else if (p->flags & DPF_HIDDEN)
Draw_FunStringWidth (x, y, "---", 48, 2, false);
else if (p->flags & DPF_CORRUPT)
@ -5322,9 +5332,9 @@ static void MD_Draw (int x, int y, struct menucustom_s *c, struct emenu_s *m)
else
{ //!DPF_MARKED|DPF_ENABLED:
if ((p->flags & DPF_PURGE) || PM_PurgeOnDisable(p))
Draw_FunStringWidth (x, y, "DEL", 48, 2, false);
Draw_FunStringWidth (x, y, S_COLOR_RED"DEL", 48, 2, false);
else
Draw_FunStringWidth (x, y, "DIS", 48, 2, false);
Draw_FunStringWidth (x, y, S_COLOR_YELLOW"DIS", 48, 2, false);
}
}
}
@ -6007,22 +6017,28 @@ static void MD_Download_UpdateStatus(struct emenu_s *m)
b->rightalign = false;
y+=8;
#ifdef WEBCLIENT
b = MC_AddCommand(m, 48, 320-16, y, "Mark Updates", MD_MarkUpdatesButton);
b->rightalign = false;
b->common.tooltip = "Select any updated versions of packages that are already installed.";
y+=8;
if (pm_numsources)
{
b = MC_AddCommand(m, 48, 320-16, y, "Mark Updates", MD_MarkUpdatesButton);
b->rightalign = false;
b->common.tooltip = "Select any updated versions of packages that are already installed.";
y+=8;
}
#endif
b = MC_AddCommand(m, 48, 320-16, y, "Revert Updates", MD_RevertUpdates);
b = MC_AddCommand(m, 48, 320-16, y, "Undo Changes", MD_RevertUpdates);
b->rightalign = false;
b->common.tooltip = "Reset selection to only those packages that are currently installed.";
y+=8;
#ifdef WEBCLIENT
c = MC_AddCustom(m, 48, y, p, 0, NULL);
c->draw = MD_AutoUpdate_Draw;
c->key = MD_AutoUpdate_Key;
c->common.width = 320-48-16;
c->common.height = 8;
y += 8;
if (pm_numsources)
{
c = MC_AddCustom(m, 48, y, p, 0, NULL);
c->draw = MD_AutoUpdate_Draw;
c->key = MD_AutoUpdate_Key;
c->common.width = 320-48-16;
c->common.height = 8;
y += 8;
}
#endif
y+=4; //small gap
MC_AddBufferedText(m, 48, 320-16, y, "Packages", false, true), y += 8;
@ -6148,7 +6164,7 @@ qboolean PM_AreSourcesNew(qboolean doprompt)
if (doprompt)
{
const char *msg = va("Enable update source\n\n^x66F%s", (pm_source[i].flags&SRCFL_MANIFEST)?PrettyHostFromURL(pm_source[i].url):pm_source[i].url);
Menu_Prompt(PM_ConfirmSource, Z_StrDup(pm_source[i].url), msg, "Enable", "Configure", "Later");
Menu_Prompt(PM_ConfirmSource, Z_StrDup(pm_source[i].url), msg, "Enable", "Configure", "Later", true);
pm_source[i].flags |= SRCFL_PROMPTED;
}
break;
@ -6157,7 +6173,7 @@ qboolean PM_AreSourcesNew(qboolean doprompt)
/*if (!pluginpromptshown && i < pm_numsources)
{
pluginpromptshown = true;
Menu_Prompt(PM_AutoUpdateQuery, NULL, "Configure update sources now?", "View", NULL, "Later");
Menu_Prompt(PM_AutoUpdateQuery, NULL, "Configure update sources now?", "View", NULL, "Later", true);
}*/
}
#endif

View File

@ -2587,7 +2587,7 @@ void M_Menu_Main_f (void)
if (!mainm)
{
mainm = M_CreateMenu(0);
MC_AddRedText(mainm, 16, 170, 0, "MAIN MENU", false);
MC_AddRedText(mainm, 72, 320, 0, "Main Menu", false);
y = 36;
mainm->selecteditem = (menuoption_t *)

View File

@ -292,7 +292,7 @@ static void SL_ServerDraw (int x, int y, menucustom_t *ths, emenu_t *menu)
servertypes_t stype;
char adr[MAX_ADR_SIZE];
if (sb_filtertext.modified != info->filtermodcount)
if (sb_filtertext.modifiedcount != info->filtermodcount)
CalcFilters(menu);
si = Master_SortedServer(thisone);
@ -1097,7 +1097,7 @@ static qboolean SL_SliderKey (menucustom_t *ths, emenu_t *menu, int key, unsigne
static void CalcFilters(emenu_t *menu)
{
serverlist_t *info = (serverlist_t*)(menu + 1);
info->filtermodcount = sb_filtertext.modified;
info->filtermodcount = sb_filtertext.modifiedcount;
Master_ClearMasks();

View File

@ -2181,6 +2181,12 @@ static void Media_Roq_Shutdown(struct cin_s *cin)
cin->roq.roqfilm=NULL;
}
static void Media_Roq_Rewind(struct cin_s *cin)
{
roq_rewind(cin->roq.roqfilm);
cin->roq.nextframetime = 0;
}
static qboolean Media_Roq_DecodeFrame (cin_t *cin, qboolean nosound, qboolean forcevideo, double mediatime, void (QDECL *uploadtexture)(void *ctx, uploadfmt_t fmt, int width, int height, void *data, void *palette), void *ctx)
{
qboolean doupdate = forcevideo;
@ -2296,6 +2302,7 @@ static cin_t *Media_RoQ_TryLoad(char *name)
{
cin = Z_Malloc(sizeof(cin_t));
cin->decodeframe = Media_Roq_DecodeFrame;
cin->rewind = Media_Roq_Rewind;
cin->shutdown = Media_Roq_Shutdown;
cin->getsize = Media_Roq_GetSize;

View File

@ -463,7 +463,7 @@ qboolean MN_Init(void)
while(COM_IteratePaths(&iterator, syspath, sizeof(syspath), gamepath, sizeof(gamepath)))
{
if (!com_nogamedirnativecode.ival)
if (com_gamedirnativecode.ival)
libmenu = Sys_LoadLibrary(va("%smenu_"ARCH_CPU_POSTFIX ARCH_DL_POSTFIX, syspath), funcs);
if (libmenu)
break;

View File

@ -3317,7 +3317,7 @@ typedef struct
float dist;
char modelname[MAX_QPATH];
char forceshader[MAX_QPATH];
char skinname[MAX_QPATH];
char shaderfile[MAX_QPATH];
char *shadertext;
@ -3528,7 +3528,18 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct emenu
ent.framestate.g[FS_REG].frame[0] = mods->framegroup;
ent.framestate.g[FS_REG].frametime[0] = ent.framestate.g[FS_REG].frametime[1] = realtime - mods->framechangetime;
ent.framestate.g[FS_REG].endbone = 0x7fffffff;
ent.customskin = Mod_RegisterSkinFile(va("%s_%i.skin", mods->modelname, ent.skinnum));
if (*mods->skinname)
ent.customskin = Mod_RegisterSkinFile(mods->skinname); //explicit .skin file to use
else
{
ent.customskin = Mod_RegisterSkinFile(va("%s_%i.skin", mods->modelname, ent.skinnum));
if (ent.customskin == 0)
{
char haxxor[MAX_QPATH];
COM_StripExtension(mods->modelname, haxxor, sizeof(haxxor));
ent.customskin = Mod_RegisterSkinFile(va("%s_default.skin", haxxor)); //fall back to some default
}
}
skin = Mod_LookupSkin(ent.customskin);
ent.light_avg[0] = ent.light_avg[1] = ent.light_avg[2] = 0.66;
@ -4242,7 +4253,7 @@ void M_Menu_ModelViewer_f(void)
mv->yaw = 180;// + crandom()*45;
mv->dist = 150;
Q_strncpyz(mv->modelname, Cmd_Argv(1), sizeof(mv->modelname));
Q_strncpyz(mv->forceshader, Cmd_Argv(2), sizeof(mv->forceshader));
Q_strncpyz(mv->skinname, Cmd_Argv(2), sizeof(mv->skinname));
mv->framechangetime = realtime;
mv->skinchangetime = realtime;

View File

@ -107,16 +107,12 @@ void Menu_Push(menu_t *menu, qboolean prompt)
{
if (!Menu_IsLinked(menu))
{ //only link once.
if (prompt)
{
menu->prev = promptmenu;
promptmenu = menu;
}
else
{
menu->prev = topmenu;
topmenu = menu;
}
//annoying logic so that persistent menus always appear on top of other stuff.
menu_t **prev = prompt?&promptmenu:&topmenu;
while (menu->lowpriority && *prev && !(*prev)->lowpriority)
prev = &(*prev)->prev;
menu->prev = *prev;
*prev = menu;
}
if (menu == promptmenu)
{
@ -383,7 +379,7 @@ void M_ToggleMenu_f (void)
}
#endif
#ifdef VM_UI
if (UI_OpenMenu())
if (q3 && q3->ui.OpenMenu())
return;
#endif
@ -410,6 +406,12 @@ void M_Restart_f(void)
}
else
M_Reinit();
//start up the ui now we have a renderer
#ifdef VM_UI
if (q3)
q3->ui.Start();
#endif
}
@ -594,7 +596,7 @@ static void Prompt_Release(struct menu_s *gm, qboolean forced)
callback(ctx, PROMPT_CANCEL);
Z_Free(m);
}
void Menu_Prompt (void (*callback)(void *, promptbutton_t), void *ctx, const char *messages, const char *optionyes, const char *optionno, const char *optioncancel)
void Menu_Prompt (void (*callback)(void *, promptbutton_t), void *ctx, const char *messages, const char *optionyes, const char *optionno, const char *optioncancel, qboolean highpri)
{
promptmenu_t *m;
char *t;
@ -617,7 +619,8 @@ void Menu_Prompt (void (*callback)(void *, promptbutton_t), void *ctx, const cha
m->m.release = Prompt_Release;
m->mbutton = -1;
m->kbutton = -1;
Menu_Push(&m->m, true);
m->m.persist = true;
Menu_Push(&m->m, highpri);
m->callback = callback;
m->ctx = ctx;
@ -1267,10 +1270,10 @@ void M_Menu_Quit_f (void)
#endif
break;
case 2:
Menu_Prompt (M_Menu_DoQuitSave, NULL, "You have unsaved settings\nWould you like to\nsave them now?", "Yes", "No", "Cancel");
Menu_Prompt (M_Menu_DoQuitSave, NULL, "You have unsaved settings\nWould you like to\nsave them now?", "Yes", "No", "Cancel", true);
break;
case 1:
Menu_Prompt (M_Menu_DoQuit, NULL, quitMessage[rand()%countof(quitMessage)], "Quit", NULL, "Cancel");
Menu_Prompt (M_Menu_DoQuit, NULL, quitMessage[rand()%countof(quitMessage)], "Quit", NULL, "Cancel", true);
break;
}
}
@ -1278,7 +1281,7 @@ void M_Menu_Quit_f (void)
#ifdef HAVE_LEGACY
void M_Menu_Credits_f (void)
{
Menu_Prompt (NULL, NULL, "That's all folks!\nTry a different mod now.", NULL, NULL, "Sure!");
Menu_Prompt (NULL, NULL, "That's all folks!\nTry a different mod now.", NULL, NULL, "Sure!", false);
}
#endif

View File

@ -108,6 +108,7 @@ typedef struct menu_s {
qboolean (*joyaxis) (struct menu_s *, unsigned int devid, int axis, float val);
void (*drawmenu) (struct menu_s *);
struct key_cursor_s *cursor; //NULL for relative motion
qboolean lowpriority; //appears underneath other menus.
qboolean isopaque; //guarentees an opaque background
qboolean persist; //try really hard to not kill this.
} menu_t;
@ -128,7 +129,7 @@ typedef enum
PROMPT_NO = 1,
PROMPT_CANCEL = -1,
} promptbutton_t;
void Menu_Prompt (void (*callback)(void *, promptbutton_t), void *ctx, const char *messages, const char *optionyes, const char *optionno, const char *optioncancel);
void Menu_Prompt (void (*callback)(void *, promptbutton_t), void *ctx, const char *messages, const char *optionyes, const char *optionno, const char *optioncancel, qboolean highpri);
#ifndef NOBUILTINMENUS
@ -560,4 +561,4 @@ void Plug_FreeAllImages(void);
#else
#define PLUGINPREFIX "fteplug_" //this string defines what consitutes a plugin, as opposed to some other dll
#endif
#endif
#endif

View File

@ -169,6 +169,7 @@ enum mod_purge_e
enum mlverbosity_e
{
MLV_SILENT,
MLV_SILENTSYNC,
MLV_WARN,
MLV_WARNSYNC,
MLV_ERROR
@ -202,7 +203,7 @@ extern int Mod_GetFrameCount (struct model_s *model);
#undef FNC
extern qboolean Mod_GetTag (struct model_s *model, int tagnum, framestate_t *framestate, float *transforms);
extern int Mod_TagNumForName (struct model_s *model, const char *name);
extern int Mod_TagNumForName (struct model_s *model, const char *name, int firsttag);
void Mod_AddSingleSurface(struct entity_s *ent, int surfaceidx, shader_t *shader, int mode);
int Mod_GetNumBones(struct model_s *model, qboolean allowtags);

View File

@ -1354,13 +1354,13 @@ int Master_NumSorted(void)
}
float Master_ReadKeyFloat(serverinfo_t *server, hostcachekey_t keynum)
float Master_ReadKeyFloat(serverinfo_t *server, unsigned int keynum)
{
if (!server)
return -1;
else if (keynum < SLKEY_CUSTOM)
{
switch(keynum)
switch((hostcachekey_t)keynum)
{
case SLKEY_PING:
return server->ping;
@ -1416,7 +1416,7 @@ void Master_DecodeColour(vec3_t ret, int col)
VectorSet(ret, ((col&0xff0000)>>16)/255.0, ((col&0x00ff00)>>8)/255.0, ((col&0x0000ff)>>0)/255.0);
}
char *Master_ReadKeyString(serverinfo_t *server, hostcachekey_t keynum)
char *Master_ReadKeyString(serverinfo_t *server, unsigned int keynum)
{
static char adr[MAX_ADR_SIZE];
@ -1459,7 +1459,7 @@ char *Master_ReadKeyString(serverinfo_t *server, hostcachekey_t keynum)
}
else
{
switch(keynum)
switch((hostcachekey_t)keynum)
{
case SLKEY_MAP:
return server->map;
@ -2225,10 +2225,10 @@ void Master_CheckPollSockets(void)
int c;
char *s;
MSG_BeginReading (msg_nullnetprim);
MSG_BeginReading (&net_message, msg_nullnetprim);
MSG_ReadLong (); // skip the -1
c = msg_readcount;
c = net_message.currentbit;
s = MSG_ReadStringLine(); //peek for q2 messages.
#ifdef Q2CLIENT
if (!strcmp(s, "print"))
@ -2244,14 +2244,14 @@ void Master_CheckPollSockets(void)
#ifdef HAVE_IPV6
if (!strncmp(s, "server6", 7)) //parse a bit more...
{
msg_readcount = c+7;
net_message.currentbit = (c+7)<<3;
CL_MasterListParse(NA_IPV6, SS_QUAKE2, false);
continue;
}
#endif
if (!strncmp(s, "servers", 7)) //parse a bit more...
{
msg_readcount = c+7;
net_message.currentbit = (c+7)<<3;
CL_MasterListParse(NA_IP, SS_QUAKE2, false);
continue;
}
@ -2267,20 +2267,20 @@ void Master_CheckPollSockets(void)
#ifdef HAVE_IPV6
if (!strncmp(s, "getserversResponse6", 19) && (s[19] == '\\' || s[19] == '/')) //parse a bit more...
{
msg_readcount = c+19-1;
net_message.currentbit = (c+19-1)<<3;
CL_MasterListParse(NA_IPV6, SS_DARKPLACES, true);
continue;
}
#endif
if (!strncmp(s, "getserversExtResponse", 21) && (s[21] == '\\' || s[21] == '/')) //parse a bit more...
{
msg_readcount = c+21-1;
net_message.currentbit = (c+21-1)<<3;
CL_MasterListParse(NA_IP, SS_DARKPLACES, true);
continue;
}
if (!strncmp(s, "getserversResponse", 18) && (s[18] == '\\' || s[18] == '/')) //parse a bit more...
{
msg_readcount = c+18-1;
net_message.currentbit = (c+18-1)<<3;
CL_MasterListParse(NA_IP, SS_DARKPLACES, true);
continue;
}
@ -2293,13 +2293,13 @@ void Master_CheckPollSockets(void)
#ifdef HAVE_IPV6
if (!strncmp(s, "qw_slist6\\", 10)) //parse a bit more...
{
msg_readcount = c+9-1;
net_message.currentbit = (c+9-1)<<3;
CL_MasterListParse(NA_IPV6, SS_QUAKEWORLD, false);
continue;
}
#endif
msg_readcount = c;
net_message.currentbit = c;
c = MSG_ReadByte ();
@ -2325,7 +2325,7 @@ void Master_CheckPollSockets(void)
int control;
int ccrep;
MSG_BeginReading (msg_nullnetprim);
MSG_BeginReading (&net_message, msg_nullnetprim);
control = BigLong(*((int *)net_message.data));
MSG_ReadLong();
if (control == -1)
@ -3578,7 +3578,7 @@ void CL_MasterListParse(netadrtype_t adrtype, int type, qboolean slashpad)
last = firstserver;
while(msg_readcount+1+2 < net_message.cursize)
while((net_message.currentbit>>3)+1+2 < net_message.cursize)
{
if (slashpad)
{

View File

@ -2748,7 +2748,7 @@ static void QCBUILTIN PF_R_RenderScene(pubprogfuncs_t *prinst, struct globalvars
csqc_worldchanged = false;
cl.worldmodel = r_worldentity.model = csqc_world.worldmodel;
FS_LoadMapPackFile(cl.worldmodel->name, cl.worldmodel->archive);
Surf_NewMap();
Surf_NewMap(csqc_world.worldmodel);
CL_UpdateWindowTitle();
World_RBE_Shutdown(&csqc_world);

View File

@ -380,7 +380,7 @@ static qboolean rag_dollline(dollcreatectx_t *ctx, int linenum)
//create a new body
else if (argc == 3 && !stricmp(cmd, "body"))
{
int boneidx = Mod_TagNumForName(d->model, Cmd_Argv(2))-1;
int boneidx = Mod_TagNumForName(d->model, Cmd_Argv(2), 0)-1;
ctx->joint = NULL;
ctx->body = NULL;
if (boneidx >= 0)
@ -576,7 +576,7 @@ static qboolean rag_dollline(dollcreatectx_t *ctx, int linenum)
//the origin is specified in base-frame model space
//we need to make it relative to the joint's bodies
char *bone = val;
i = Mod_TagNumForName(d->model, bone)-1;
i = Mod_TagNumForName(d->model, bone, 0)-1;
if (argc > 2)
{
ctx->joint->offset[0] = atof(Cmd_Argv(2));
@ -2256,7 +2256,7 @@ void QCBUILTIN PF_skel_find_bone (pubprogfuncs_t *prinst, struct globalvars_s *p
if (!skelobj)
G_FLOAT(OFS_RETURN) = 0;
else
G_FLOAT(OFS_RETURN) = Mod_TagNumForName(skelobj->model, bname);
G_FLOAT(OFS_RETURN) = Mod_TagNumForName(skelobj->model, bname, 0);
}
//vector(float skel, float bonenum) skel_get_bonerel (FTE_CSQC_SKELETONOBJECTS) (sets v_forward etc)
@ -2661,7 +2661,7 @@ void QCBUILTIN PF_gettagindex (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
const char *tagname = PR_GetStringOfs(prinst, OFS_PARM1);
model_t *mod = *tagname?w->Get_CModel(w, ent->v->modelindex):NULL;
if (mod)
G_FLOAT(OFS_RETURN) = Mod_TagNumForName(mod, tagname);
G_FLOAT(OFS_RETURN) = Mod_TagNumForName(mod, tagname, 0);
else
G_FLOAT(OFS_RETURN) = 0;
}

View File

@ -207,6 +207,8 @@ extern "C" {
#endif
#endif
#include "q3api.h"
#ifdef __cplusplus
#define q_max(a,b) ((a) > (b) ? (a) : (b))
#define q_min(a,b) ((a) < (b) ? (a) : (b))
@ -323,7 +325,7 @@ extern cvar_t pkg_autoupdate;
#endif
extern cvar_t com_protocolname;
extern cvar_t com_protocolversion;
extern cvar_t com_nogamedirnativecode;
extern cvar_t com_gamedirnativecode;
extern cvar_t com_parseutf8;
#ifdef HAVE_LEGACY
extern cvar_t scr_usekfont;

View File

@ -223,10 +223,6 @@ void R2D_Shutdown(void)
Z_Free(atlas.data);
memset(&atlas, 0, sizeof(atlas));
#ifdef PLUGINS
Plug_FreeAllImages();
#endif
}
/*
@ -460,10 +456,6 @@ void R2D_Init(void)
Cvar_ForceCallback(&crosshair);
Cvar_ForceCallback(&crosshaircolor);
#ifdef PLUGINS
Plug_DrawReloadImages();
#endif
R2D_Font_Changed();
R_NetgraphInit();

View File

@ -789,7 +789,7 @@ void P_Shutdown(void)
//0 says hit nothing.
//1 says hit world
//>1 says hit some entity
entity_t *TraceLineR (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal)
entity_t *TraceLineR (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal, qboolean bsponly)
{
trace_t trace;
float len, bestlen;
@ -827,9 +827,11 @@ entity_t *TraceLineR (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal)
pe = &r_worldentity;
else
pe = &cl_visedicts[i];
if (pe->rtype != RT_MODEL || pe->shaderRGBAf[3] < 1 || (pe->flags & (RF_ADDITIVE|RF_NODEPTHTEST|RF_TRANSLUCENT|RF_EXTERNALMODEL)))
if (pe->rtype != RT_MODEL || !pe->model || (pe->shaderRGBAf[3] < 1&&(pe->flags&RF_TRANSLUCENT)) || (pe->flags & (RF_ADDITIVE|RF_NODEPTHTEST|RF_TRANSLUCENT|RF_EXTERNALMODEL)))
continue;
if (pe->model && pe->model->funcs.NativeTrace && pe->model->loadstate == MLS_LOADED)
if (bsponly && pe->model->type != mod_brush)
continue;
if (pe->model->funcs.NativeTrace && pe->model->loadstate == MLS_LOADED)
{
//try to trivially reject the mesh.
float ext = 0;

View File

@ -3971,7 +3971,7 @@ void Surf_BuildLightmaps (void)
Surf_NewMap
===============
*/
void Surf_NewMap (void)
void Surf_NewMap (model_t *worldmodel)
{
char namebuf[MAX_QPATH];
extern cvar_t host_mapname;
@ -3981,6 +3981,8 @@ void Surf_NewMap (void)
#endif
int i;
cl.worldmodel = worldmodel;
//evil haxx
r_dynamic.ival = r_dynamic.value;
if (r_dynamic.ival > 0 && cl.worldmodel->fromgame == fg_quake3) //quake3 has no lightmaps, disable r_dynamic
@ -4046,7 +4048,8 @@ TRACE(("dbg: Surf_NewMap: building lightmaps\n"));
TRACE(("dbg: Surf_NewMap: ui\n"));
#ifdef VM_UI
UI_Reset();
if (q3)
q3->ui.Reset();
#endif
TRACE(("dbg: Surf_NewMap: tp\n"));
TP_NewMap();

View File

@ -251,7 +251,7 @@ typedef struct {
#define R_MAX_RECURSE 6
#endif
#define RDFD_FOV 1
typedef struct
typedef struct refdef_s
{
vrect_t grect; // game rectangle. fullscreen except for csqc/splitscreen/hud.
vrect_t vrect; // subwindow in grect for 3d view. equal to grect if no hud.
@ -346,7 +346,7 @@ void R_Clutter_Emit(struct batch_s **batches);
void R_Clutter_Purge(void);
//r_surf.c
void Surf_NewMap (void);
void Surf_NewMap (struct model_s *worldmodel);
void Surf_PreNewMap(void);
void Surf_SetupFrame(void); //determine pvs+viewcontents
void Surf_DrawWorld(void);
@ -552,7 +552,7 @@ skinfile_t *Mod_LookupSkin(skinid_t id);
void Mod_Init (qboolean initial);
void Mod_Shutdown (qboolean final);
int Mod_TagNumForName(struct model_s *model, const char *name);
int Mod_TagNumForName(struct model_s *model, const char *name, int firsttag);
int Mod_SkinNumForName(struct model_s *model, int surfaceidx, const char *name);
int Mod_FrameNumForName(struct model_s *model, int surfaceidx, const char *name);
int Mod_FrameNumForAction(struct model_s *model, int surfaceidx, int actionid);
@ -624,6 +624,7 @@ void R_AnimateLight (void);
void R_UpdateHDR(vec3_t org);
void R_UpdateLightStyle(unsigned int style, const char *stylestring, float r, float g, float b);
void R_BumpLightstyles(unsigned int maxstyle); //bumps the cl_max_lightstyles array size, if needed.
qboolean R_CalcModelLighting(entity_t *e, struct model_s *clmodel);
struct texture_s *R_TextureAnimation (int frame, struct texture_s *base); //mostly deprecated, only lingers for rtlights so world only.
struct texture_s *R_TextureAnimation_Q2 (struct texture_s *base); //mostly deprecated, only lingers for rtlights so world only.
void RQ_Init(void);

View File

@ -378,7 +378,7 @@ cvar_t r_deluxemapping_cvar = CVARAFD ("r_deluxemapping", "1", "r_glsl_delux
cvar_t mod_loadsurfenvmaps = CVARD ("r_loadsurfenvmaps", "1", "Load local reflection environment-maps, where available. These are normally defined via env_cubemap entities dotted around the place.");
qboolean r_deluxemapping;
cvar_t r_shaderblobs = CVARD ("r_shaderblobs", "0", "If enabled, can massively accelerate vid restarts / loading (especially with the d3d renderer). Can cause issues when upgrading engine versions, so this is disabled by default.");
cvar_t gl_compress = CVARFD ("gl_compress", "0", CVAR_ARCHIVE, "Enable automatic texture compression even for textures which are not pre-compressed.");
cvar_t gl_compress = CVARAFD ("gl_compress", "0", "r_ext_compressed_textures"/*q3*/, CVAR_ARCHIVE, "Enable automatic texture compression even for textures which are not pre-compressed.");
cvar_t gl_conback = CVARFCD ("gl_conback", "",
CVAR_RENDERERCALLBACK, R2D_Conback_Callback, "Specifies which conback shader/image to use. The Quake fallback is gfx/conback.lmp");
//cvar_t gl_detail = CVARF ("gl_detail", "0",
@ -440,7 +440,7 @@ cvar_t gl_specular_fallbackexp = CVARF ("gl_specular_fallbackexp", "1", CVAR
cvar_t gl_texture_anisotropic_filtering = CVARAFCD("gl_texture_anisotropy", "4",
"gl_texture_anisotropic_filtering"/*old*/, CVAR_ARCHIVE | CVAR_RENDERERCALLBACK,
Image_TextureMode_Callback, "Allows for higher quality textures on surfaces that slope away from the camera (like the floor). Set to 16 or something. Only supported with trilinear filtering.");
cvar_t gl_texturemode = CVARFCD("gl_texturemode", "GL_LINEAR_MIPMAP_LINEAR",
cvar_t gl_texturemode = CVARAFCD("gl_texturemode", "GL_LINEAR_MIPMAP_LINEAR", "r_texturemode"/*q3*/,
CVAR_ARCHIVE | CVAR_RENDERERCALLBACK | CVAR_SAVE, Image_TextureMode_Callback,
"Specifies how world/model textures appear. Typically 3 letters eg "S_COLOR_GREEN"nll"S_COLOR_WHITE" or "S_COLOR_GREEN"lll"S_COLOR_WHITE".\nFirst letter can be l(inear) or n(earest) and says how to upscale low-res textures (n for the classic look - often favoured for embedded textures, l for blurry - best for high-res textures).\nThe middle letter can be set to '.' to disable mipmaps, or n for ugly banding with distance, or l for smooth mipmap transitions.\nThe third letter says what to do when the texture is too high resolution, and should generally be set to 'l' to reduce sparkles including when aiming for the classic lego look.");
cvar_t gl_texture_lodbias = CVARAFCD("d_lodbias", "0", "gl_texture_lodbias",
@ -1775,15 +1775,17 @@ TRACE(("dbg: R_ApplyRenderer: starting on client state\n"));
if (!isDedicated)
S_DoRestart(true);
#ifdef VM_UI
if (q3)
q3->ui.Reset();
#endif
#ifdef Q3SERVER
if (svs.gametype == GT_QUAKE3)
{
cl.worldmodel = NULL;
CG_Stop();
memset(cl.model_precache, 0, sizeof(cl.model_precache));
CG_Start();
if (cl.worldmodel)
Surf_NewMap();
if (q3)
q3->cg.VideoRestarted();
}
else
#endif
@ -1847,9 +1849,7 @@ TRACE(("dbg: R_ApplyRenderer: done the models\n"));
// Con_Printf ("You may need to download or purchase a client pack in order to play on this server.\n\n");
CL_Disconnect ("Worldmodel missing after video reload");
#ifdef VM_UI
UI_Reset();
#endif
if (newr)
memcpy(&currentrendererstate, newr, sizeof(currentrendererstate));
return true;
@ -1862,19 +1862,13 @@ TRACE(("dbg: R_ApplyRenderer: checking any wad textures\n"));
cl_static_entities[i].ent.model = NULL;
TRACE(("dbg: R_ApplyRenderer: Surf_NewMap\n"));
Surf_NewMap();
Surf_NewMap(cl.worldmodel);
TRACE(("dbg: R_ApplyRenderer: efrags\n"));
// Skin_FlushAll();
Skin_FlushPlayers();
}
else
{
#ifdef VM_UI
UI_Reset();
#endif
}
#ifdef SKELETALOBJECTS
skel_reload();

View File

@ -39,9 +39,10 @@ typedef struct roq_info_s {
} roq_info;
/* -------------------------------------------------------------------------- */
void roq_init(void);
void roq_cleanup(void);
//void roq_init(void);
//void roq_cleanup(void);
roq_info *roq_open(char *fname);
void roq_rewind(roq_info *ri);
void roq_close(roq_info *ri);
int roq_read_frame(roq_info *ri);
int roq_read_audio(roq_info *ri);

View File

@ -361,6 +361,12 @@ int i;
return ri;
}
//reset enough that we'll start decoding from the start next time we try to read a frame.
void roq_rewind(roq_info *ri)
{
ri->frame_num = 0;
ri->aud_pos = ri->vid_pos = ri->roq_start;
}
/* -------------------------------------------------------------------------- */
void roq_close(roq_info *ri)

View File

@ -3679,7 +3679,7 @@ static void S_Q2_AddEntitySounds(soundcardinfo_t *sc)
#endif
#ifdef VM_CG
if (cls.protocol == CP_QUAKE3)
count = CG_GatherLoopingSounds(positions, entnums, sounds, countof(sounds));
count = q3->cg.GatherLoopingSounds(positions, entnums, sounds, countof(sounds));
else
#endif
return;

View File

@ -850,7 +850,7 @@ qboolean Con_Editor_Close(console_t *con, qboolean force)
{
if (!strncmp(con->title, "MODIFIED: ", 10))
{
Menu_Prompt(Con_Editor_CloseCallback, con, va("Save changes?\n%s\n", con->name), "Yes", "No", "Cancel");
Menu_Prompt(Con_Editor_CloseCallback, con, va("Save changes?\n%s\n", con->name), "Yes", "No", "Cancel", true);
return false;
}
}

View File

@ -3872,7 +3872,7 @@ void CL_Say (qboolean team, char *extra)
#ifdef Q3CLIENT
if (cls.protocol == CP_QUAKE3)
CLQ3_SendClientCommand("%s %s%s", team ? "say_team" : "say", extra?extra:"", sendtext);
q3->cl.SendClientCommand("%s %s%s", team ? "say_team" : "say", extra?extra:"", sendtext);
else
#endif
{

View File

@ -934,7 +934,7 @@ static void Cmd_Exec_f (void)
#ifdef HAVE_CLIENT
if (!cl_warncmd.ival && foundone && (!strcmp(name, "quake.rc") || !strcmp(name, "default.cfg") || !strcmp(name, "autoexec.cfg")))
{
#if defined(HAVE_LEGACY) && defined(HAVE_CLIENT)
#if defined(HAVE_LEGACY)
if (!strcmp(name, "default.cfg"))
{
s = (char*)replacementq1binds;
@ -943,7 +943,7 @@ static void Cmd_Exec_f (void)
else
#endif
{
Menu_Prompt(NULL, NULL, va("WARNING: nquake %s file detected. The file has been ignored.", name), NULL, NULL, "Argh");
Menu_Prompt(NULL, NULL, va("WARNING: nquake %s file detected. The file has been ignored.", name), NULL, NULL, "Argh", false);
*s = 0;
foundone = 0;
}
@ -2730,7 +2730,7 @@ void Cmd_ForwardToServer (void)
#ifdef Q3CLIENT
if (cls.protocol == CP_QUAKE3)
{
CLQ3_SendClientCommand("%s %s", Cmd_Argv(0), Cmd_Args());
q3->cl.SendClientCommand("%s %s", Cmd_Argv(0), Cmd_Args());
return;
}
#endif
@ -2810,6 +2810,84 @@ void Cmd_ForwardToServer (void)
}
#endif
static void Cmd_FindForExecution (const char *name, int level, cmd_function_t **foundcmd, cmdalias_t **foundalias, cvar_t **foundcvar)
{
//WARNING: PF_checkcommand should match the order.
cmd_function_t *cmd;
cmdalias_t *a;
*foundcmd = NULL;
*foundalias = NULL;
*foundcvar = NULL;
for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
{
if (!Q_strcasecmp (name, cmd->name))
{
*foundcmd = cmd;
if (!strcmp (name, cmd->name))
break; //don't keep looking for others when we get an exact match.
}
}
cmd = *foundcmd;
if (!cmd)
;
else if (level == RESTRICT_TEAMPLAY)
{ //extra weirdness so that teamplay macros can only execute certain known commands
static char *tpcmds[] =
{
"if", "wait", /*would be nice to include alias in here*/
"say", "say_team", "echo", /*display stuff, because it would be useless otherwise*/
"set_tp", "set", "set_calc", "inc", /*because scripting variables is fun. not.*/
"tp_point", "tp_pickup", "tp_took" /*updates what the $took etc macros are allowed to generate*/
};
size_t i;
for (i = 0; i < countof(tpcmds); i++)
if (!strcmp(cmd->name, tpcmds[i]))
break;
if (i == countof(tpcmds))
*foundcmd = NULL;
else if (cmd->restriction && cmd->restriction > 0)
{
//warning, these commands would normally be considered to be run at restrict_local, but they're running at a much lower level
//which means that if there's ANY restriction on them then they'll fail.
//this means we have to ignore the default restriction levels and just do it anyway.
Con_TPrintf("'%s' was restricted.\n", cmd_argv[0]);
*foundcmd = NULL;
}
}
else if ((cmd->restriction?cmd->restriction:rcon_level.ival) > level)
{
Con_TPrintf("cmd '%s' was restricted.\n", name);
*foundcmd = NULL;
}
// check alias
for (a=cmd_alias ; a ; a=a->next)
{
if (!Q_strcasecmp (cmd_argv[0], a->name))
{
//teamplay restrictions block any execlevel elevations, so the contents are what matter
//(there's no reason to restrict aliases other than for exec level promotion)
if (level!=RESTRICT_TEAMPLAY)
if ((a->restriction?a->restriction:rcon_level.ival) > level)
{
Con_TPrintf("alias '%s' was restricted.\n", cmd_argv[0]);
return;
}
*foundalias = a;
if (!strcmp (name, a->name))
break;
}
}
// check cvars
*foundcvar = Cvar_FindVar(name);
}
/*
============
Cmd_ExecuteString
@ -2818,14 +2896,15 @@ A complete command line has been parsed, so try to execute it
FIXME: lookupnoadd the token to speed search?
============
*/
static void Cmd_ExecuteStringGlobalsAreEvil (const char *text, int level)
void Cmd_ExecuteString (const char *text, int level)
{
//WARNING: PF_checkcommand should match the order.
cmd_function_t *cmd;
cmdalias_t *a;
cvar_t *var;
int olev = Cmd_ExecLevel;
char dest[65536];
Cmd_ExecLevel = level;
while (*text == ' ' || *text == '\n')
text++;
@ -2839,234 +2918,134 @@ static void Cmd_ExecuteStringGlobalsAreEvil (const char *text, int level)
if (!Cmd_Argc())
return; // no tokens
// check functions
for (cmd=cmd_functions ; cmd ; cmd=cmd->next)
Cmd_FindForExecution (cmd_argv[0], level, &cmd, &a, &var);
//check (explicit) functions
if (cmd && cmd->function)
{
if (!Q_strcasecmp (cmd_argv[0],cmd->name))
{
if (strcmp (cmd_argv[0],cmd->name))
break; //yes, I know we found it... (but it's the wrong case, go for an alias or cvar instead FIRST)
if (!level)
break;
if ((cmd->restriction?cmd->restriction:rcon_level.ival) > level)
Con_TPrintf("cmd '%s' was restricted.\n", cmd_argv[0]);
else if (!cmd->function)
{
#if defined(VM_CG) && defined(HAVE_CLIENT)
if (CG_Command())
return;
#endif
#if defined(Q3SERVER) && defined(HAVE_SERVER)
if (SVQ3_Command())
return;
#endif
#if defined(VM_UI) && defined(HAVE_CLIENT)
if (UI_Command())
return;
#endif
if (Cmd_AliasExist(cmd_argv[0], level))
break; //server stuffed an alias for a command that it would already have received. use that instead.
#if defined(CSQC_DAT) && defined(HAVE_CLIENT)
if (CSQC_ConsoleCommand(-1, text))
return; //let the csqc handle it if it wants.
#endif
#if defined(MENU_DAT) && defined(HAVE_CLIENT)
if (MP_ConsoleCommand(text))
return; //let the csqc handle it if it wants.
#endif
#if defined(MENU_NATIVECODE) && defined(HAVE_CLIENT)
if (mn_entry && mn_entry->ConsoleCommand(text, cmd_argc, (char const*const*)cmd_argv))
return;
#endif
Cmd_ForwardToServer ();
}
else
cmd->function ();
return;
}
Cmd_ExecLevel = level;
cmd->function();
Cmd_ExecLevel = olev;
return;
}
// check alias
for (a=cmd_alias ; a ; a=a->next)
//priority is cmd>alias>cvar
//but this means that user aliases can override cvars
//which means users can use aliases to block cvar access, aka cheat.
//so favour the cvar when its a server command (unless the alias was also created by the server)
if (a && (!var || Cmd_ExecLevel<RESTRICT_SERVER || a->flags&ALIAS_FROMSERVER))
{
if (!Q_strcasecmp (cmd_argv[0], a->name))
{
int execlevel;
int execlevel;
#ifdef HAVE_CLIENT //an emergency escape mechansim, to avoid infinatly recursing aliases.
extern unsigned int con_splitmodifier;
extern unsigned int con_splitmodifier;
if (keydown[K_SHIFT] && (keydown[K_LCTRL]||keydown[K_RCTRL]) && (keydown[K_LALT]||keydown[K_RALT]) && !isDedicated)
return;
if (keydown[K_SHIFT] && (keydown[K_LCTRL]||keydown[K_RCTRL]) && (keydown[K_LALT]||keydown[K_RALT]) && !isDedicated)
return;
#endif
if (!level)
execlevel = level;
Cmd_ExecLevel = level;
if (level == RESTRICT_TEAMPLAY)
execlevel = level; //teamplay aliases can't let the user's settings promote them out of their restrictions.
else
{
if (a->execlevel)
execlevel = a->execlevel;
else
{
if ((a->restriction?a->restriction:rcon_level.ival) > level)
execlevel = level;
}
Cbuf_InsertText ("\n", execlevel, false);
// if the alias value is a command or cvar and
// the alias is called with parameters, add them
//unless we're mimicing dp, or the alias has explicit expansions (or macros) in which case it can do its own damn args
{
char *ignoringquoteswasstupid;
Cmd_ExpandString(a->value, dest, sizeof(dest), &execlevel, !Cmd_IsInsecure()?true:false, true);
for (ignoringquoteswasstupid = dest; *ignoringquoteswasstupid; )
{ //double up dollars, to prevent expansion when its actually execed.
if (*ignoringquoteswasstupid == '$')
{
Con_TPrintf("alias '%s' was restricted.\n", cmd_argv[0]);
return;
}
if (a->execlevel)
execlevel = a->execlevel;
else
execlevel = level;
}
Cbuf_InsertText ("\n", execlevel, false);
// if the alias value is a command or cvar and
// the alias is called with parameters, add them
//unless we're mimicing dp, or the alias has explicit expansions (or macros) in which case it can do its own damn args
{
char *ignoringquoteswasstupid;
Cmd_ExpandString(a->value, dest, sizeof(dest), &execlevel, !Cmd_IsInsecure()?true:false, true);
for (ignoringquoteswasstupid = dest; *ignoringquoteswasstupid; )
{ //double up dollars, to prevent expansion when its actually execed.
if (*ignoringquoteswasstupid == '$')
{
memmove(ignoringquoteswasstupid+1, ignoringquoteswasstupid, strlen(ignoringquoteswasstupid)+1);
ignoringquoteswasstupid++;
}
memmove(ignoringquoteswasstupid+1, ignoringquoteswasstupid, strlen(ignoringquoteswasstupid)+1);
ignoringquoteswasstupid++;
}
if ((a->restriction?a->restriction:rcon_level.ival) > execlevel)
return;
ignoringquoteswasstupid++;
}
if (!dpcompat_console.ival)
if ((a->restriction?a->restriction:rcon_level.ival) > execlevel)
return;
}
if (!dpcompat_console.ival)
{
if (Cmd_Argc() > 1 && (!strncmp(a->value, "cmd ", 4) || (!strchr(a->value, ' ') && !strchr(a->value, '\t') &&
(Cvar_FindVar(a->value) || (Cmd_Exists(a->value) && a->value[0] != '+' && a->value[0] != '-'))))
)
{
if (Cmd_Argc() > 1 && (!strncmp(a->value, "cmd ", 4) || (!strchr(a->value, ' ') && !strchr(a->value, '\t') &&
(Cvar_FindVar(a->value) || (Cmd_Exists(a->value) && a->value[0] != '+' && a->value[0] != '-'))))
)
{
Cbuf_InsertText (Cmd_Args(), execlevel, false);
Cbuf_InsertText (" ", execlevel, false);
}
Cbuf_InsertText (Cmd_Args(), execlevel, false);
Cbuf_InsertText (" ", execlevel, false);
}
Cbuf_InsertText (dest, execlevel, false);
}
Cbuf_InsertText (dest, execlevel, false);
#ifdef HAVE_CLIENT
if (con_splitmodifier > 0)
{ //if the alias was execed via p1/p2 etc, make sure that propagates properly (at least for simple aliases like impulses)
//fixme: should probably prefix each line. that may have different issues however.
//don't need to care about + etc
Cbuf_InsertText (va("p %i ", con_splitmodifier), execlevel, false);
}
if (con_splitmodifier > 0)
{ //if the alias was execed via p1/p2 etc, make sure that propagates properly (at least for simple aliases like impulses)
//fixme: should probably prefix each line. that may have different issues however.
//don't need to care about + etc
Cbuf_InsertText (va("p %i ", con_splitmodifier), execlevel, false);
}
#endif
Con_DPrintf("Execing alias %s ^3%s:\n^1%s\n^2%s\n", a->name, Cmd_Args(), a->value, dest);
return;
}
Con_DPrintf("Execing alias %s ^3%s:\n^1%s\n^2%s\n", a->name, Cmd_Args(), a->value, dest);
Cmd_ExecLevel = olev;
return;
}
// check cvars
if (Cvar_Command (level))
return;
if (!level)
{
//teamplay macros run at level 0, and are restricted to much fewer commands
char *tpcmds[] =
{
"if", "wait", /*would be nice to include alias in here*/
"say", "say_team", "echo", /*display stuff, because it would be useless otherwise*/
"set_tp", "set", "set_calc", "inc", /*because scripting variables is fun. not.*/
"tp_point", "tp_pickup", "tp_took" /*updates what the $took etc macros are allowed to generate*/
};
if (cmd)
{
for (level = 0; level < countof(tpcmds); level++)
{
if (!strcmp(cmd_argv[0], tpcmds[level]))
{
if (cmd->restriction && cmd->restriction > 0)
{ //warning, these commands would normally be considered to be run at restrict_local, but they're running at a much lower level
//which means that if there's ANY restriction on them then they'll fail.
//this means we have to ignore the default restriction levels and just do it anyway.
Con_TPrintf("'%s' was restricted.\n", cmd_argv[0]);
return;
}
Cmd_ExecLevel = 0;
if (!cmd->function)
Cmd_ForwardToServer ();
else
cmd->function();
return;
}
}
}
Con_TPrintf("'%s' is not permitted in combination with teamplay macros.\n", cmd_argv[0]);
return;
}
if (cmd) //go for skipped ones
{
if ((cmd->restriction?cmd->restriction:rcon_level.ival) > level)
Con_TPrintf("'%s' was restricted.\n", cmd_argv[0]);
else if (!cmd->function)
Cmd_ForwardToServer ();
else
cmd->function ();
return;
}
Cmd_ExecLevel = level;
if (!cmd && Cvar_Command (var, level))
;
#if defined(CSQC_DAT) && defined(HAVE_CLIENT)
if (CSQC_ConsoleCommand(-1, text))
return;
else if (CSQC_ConsoleCommand(-1, text))
;
#endif
#if defined(MENU_DAT) && defined(HAVE_CLIENT)
if (MP_ConsoleCommand(text))
return; //let the csqc handle it if it wants.
else if (MP_ConsoleCommand(text))
; //let the csqc handle it if it wants.
#endif
#if defined(MENU_NATIVECODE) && defined(HAVE_CLIENT)
if (mn_entry && mn_entry->ConsoleCommand(text, cmd_argc, (char const*const*)cmd_argv))
return;
#endif
#ifdef PLUGINS
if (Plugin_ExecuteString())
return;
;
#endif
#ifdef HAVE_SERVER
if (sv.state)
{
if (PR_ConsoleCmd(text))
return;
}
else if (sv.state && PR_ConsoleCmd(text))
;
#endif
#if defined(VM_CG) && defined(HAVE_CLIENT)
if (CG_Command())
return;
else if (q3 && q3->cg.ConsoleCommand())
;
#endif
#if defined(Q3SERVER) && defined(HAVE_SERVER)
if (SVQ3_Command())
return;
else if (q3 && q3->sv.ConsoleCommand())
;
#endif
#if defined(VM_UI) && defined(HAVE_CLIENT)
if (UI_Command())
return;
else if (q3 && q3->ui.ConsoleCommand())
;
#endif
else if (cmd
#if defined(Q2CLIENT) && defined(HAVE_CLIENT)
if (cls.protocol == CP_QUAKE2 || cls.protocol == CP_QUAKE3)
|| (cls.state!=ca_disconnected && (cls.protocol == CP_QUAKE2 || cls.protocol == CP_QUAKE3))
#endif
)
{ //q2 servers convert unknown commands to text.
Cmd_ForwardToServer();
return;
}
#endif
if ((cl_warncmd.value && level <= RESTRICT_LOCAL) || developer.value)
else if ((cl_warncmd.value && level <= RESTRICT_LOCAL) || developer.value)
Con_TPrintf ("Unknown command \"%s\"\n", Cmd_Argv(0));
}
void Cmd_ExecuteString (const char *text, int level)
{ //inserted a small wrapper due to all the returns in the original function.
//a number of things check for seats if nothing else, and security says is safer to do this than to be in doubt.
int olev = Cmd_ExecLevel;
Cmd_ExecuteStringGlobalsAreEvil(text, level);
Cmd_ExecLevel = olev;
}
@ -3917,7 +3896,7 @@ static void Cmd_set_f(void)
forceflags |= 0;
}
var = Cvar_Get2 (name, text, CVAR_TEAMPLAYTAINT, desc, "Custom variables");
var = Cvar_Get2 (name, text, CVAR_TEAMPLAYTAINT|forceflags, desc, "Custom variables");
mark = If_Token_GetMark();
@ -4093,6 +4072,11 @@ static void Cmd_WriteConfig_f(void)
char sysname[MAX_OSPATH];
qboolean all = true;
//special variation that only saves if an archived cvar was actually modified.
if (!Q_strcasecmp(Cmd_Argv(0), "cfg_save_ifmodified"))
if (!Cvar_UnsavedArchive())
return;
filename = Cmd_Argv(1);
if (!*filename)
{
@ -4379,6 +4363,7 @@ void Cmd_Init (void)
// register our commands
//
Cmd_AddCommandAD ("cfg_save",Cmd_WriteConfig_f, Cmd_Exec_c, NULL);
Cmd_AddCommandAD ("cfg_save_ifmodified",Cmd_WriteConfig_f, Cmd_Exec_c, NULL);
Cmd_AddCommandAD ("saveconfig",Cmd_WriteConfig_f, Cmd_Exec_c, NULL); //for dpcompat
Cmd_AddCommandAD ("cfg_load",Cmd_Exec_f, Cmd_Exec_c, NULL);

View File

@ -224,7 +224,7 @@ void Cmd_Args_Set(const char *newargs, size_t len);
#define RESTRICT_MAX_USER 29
#define RESTRICT_DEFAULT 20
#define RESTRICT_MIN 1
#define RESTRICT_TEAMPLAY 0
#define RESTRICT_TEAMPLAY 0 //this is blocked from everything but aliases.
#define RESTRICT_MAX RESTRICT_MAX_USER

View File

@ -5426,7 +5426,7 @@ qboolean Mod_GetTag(model_t *model, int tagnum, framestate_t *fstate, float *res
return false;
}
int Mod_TagNumForName(model_t *model, const char *name)
int Mod_TagNumForName(model_t *model, const char *name, int firsttag)
{
#ifdef SKELORTAGS
int i;
@ -5457,7 +5457,7 @@ int Mod_TagNumForName(model_t *model, const char *name)
{
galiasbone_t *b;
b = inf->ofsbones;
for (i = 0; i < inf->numbones; i++)
for (i = firsttag; i < inf->numbones; i++)
{
if (!strcmp(b[i].name, name))
return i+1;
@ -5468,7 +5468,7 @@ int Mod_TagNumForName(model_t *model, const char *name)
if (inf->numtags)
{
md3tag_t *t = inf->ofstags;
for (i = 0; i < inf->numtags; i++)
for (i = firsttag; i < inf->numtags; i++)
{
if (!strcmp(t[i].name, name))
return i+1;
@ -6327,6 +6327,13 @@ static qboolean QDECL Mod_LoadQ3Model(model_t *mod, void *buffer, size_t fsize)
#ifdef ZYMOTICMODELS
@ -10114,6 +10121,8 @@ void Alias_Register(void)
Mod_RegisterModelFormatText(NULL, "MD5 Mesh/Anim (md5mesh)", "MD5Version", Mod_LoadMD5MeshModel);
Mod_RegisterModelFormatText(NULL, "External Anim", "EXTERNALANIM", Mod_LoadCompositeAnim);
#endif
#ifdef MODELFMT_OBJ
Mod_RegisterModelFormatText(NULL, "Wavefront Object (obj)", ".obj", Mod_LoadObjModel);
Cvar_Register(&mod_obj_orientation, NULL);

View File

@ -86,7 +86,7 @@ cvar_t com_protocolname = CVARAD("com_protocolname", NULL, "com_gamename", "The
cvar_t com_protocolversion = CVARAD("com_protocolversion", "3", NULL, "The protocol version used for dpmaster queries."); //3 by default, for compat with DP/NQ, even if our QW protocol uses different versions entirely. really it only matters for master servers.
cvar_t com_parseutf8 = CVARD("com_parseutf8", "1", "Interpret console messages/playernames/etc as UTF-8. Requires special fonts. -1=iso 8859-1. 0=quakeascii(chat uses high chars). 1=utf8, revert to ascii on decode errors. 2=utf8 ignoring errors"); //1 parse. 2 parse, but stop parsing that string if a char was malformed.
cvar_t com_highlightcolor = CVARD("com_highlightcolor", STRINGIFY(COLOR_RED), "ANSI colour to be used for highlighted text, used when com_parseutf8 is active.");
cvar_t com_nogamedirnativecode = CVARFD("com_nogamedirnativecode", "1", CVAR_NOTFROMSERVER, FULLENGINENAME" blocks all downloads of files with a .dll or .so extension, however other engines (eg: ezquake and fodquake) do not - this omission can be used to trigger delayed eremote exploits in any engine (including "DISTRIBUTION") which is later run from the same gamedir.\nQuake2, Quake3(when debugging), and KTX typically run native gamecode from within gamedirs, so if you wish to run any of these games you will need to ensure this cvar is changed to 0, as well as ensure that you don't run unsafe clients.");
cvar_t com_gamedirnativecode = CVARFD("com_gamedirnativecode", "0", CVAR_NOTFROMSERVER, FULLENGINENAME" blocks all downloads of files with a .dll or .so extension, however other engines (eg: ezquake and fodquake) do not - this omission can be used to trigger delayed eremote exploits in any engine (including "DISTRIBUTION") which is later run from the same gamedir.\nQuake2, Quake3(when debugging), and KTX typically run native gamecode from within gamedirs, so if you wish to run any of these games you will need to ensure this cvar is changed to 1, as well as ensure that you don't run unsafe clients.");
cvar_t sys_platform = CVAR("sys_platform", PLATFORM);
cvar_t host_mapname = CVARAFD("mapname", "", "host_mapname", 0, "Cvar that holds the short name of the current map, for scripting type stuff");
#ifdef HAVE_LEGACY
@ -868,6 +868,147 @@ Handles qbyte ordering and avoids alignment errors
// writing functions
//
void MSG_BeginWriting (sizebuf_t *msg, struct netprim_s prim, void *bufferstorage, size_t buffersize)
{
if (bufferstorage || buffersize)
{ //otherwise just clear it.
msg->data = bufferstorage;
msg->maxsize = buffersize;
}
msg->overflowed = false;
msg->cursize = 0;
msg->currentbit = 0;
msg->packing = SZ_RAWBYTES;
msg->prim = prim;
msg->allowoverflow = false;
}
static void MSG_WriteRawBytes(sizebuf_t *msg, int value, int bits)
{
qbyte *buf;
if (bits <= 8)
{
buf = SZ_GetSpace(msg, 1);
buf[0] = value;
}
else if (bits <= 16)
{
buf = SZ_GetSpace(msg, 2);
buf[0] = value & 0xFF;
buf[1] = value >> 8;
}
else //if (bits <= 32)
{
buf = SZ_GetSpace(msg, 4);
buf[0] = value & 0xFF;
buf[1] = (value >> 8) & 0xFF;
buf[2] = (value >> 16) & 0xFF;
buf[3] = value >> 24;
}
}
static void MSG_WriteRawBits(sizebuf_t *msg, int value, int bits)
{
int i;
for (i=0; i<bits; )
{
if (!(msg->currentbit&7))
{ //we need another byte now...
msg->cursize++;
if (bits >= 8)
{ //splurge an entire byte
msg->data[msg->currentbit>>3] = (value>>i)&0xff;
i += 8;
msg->currentbit += 8;
continue;
}
//clear it for the following 8 bits to splurge
msg->data[msg->currentbit>>3] = 0;
}
msg->data[msg->currentbit>>3] |= ((value>>i)&1) << (msg->currentbit & 7);
msg->currentbit++;
i++;
}
}
#ifdef HUFFNETWORK
static void MSG_WriteHuffBits(sizebuf_t *msg, int value, int bits)
{
int remaining;
int i;
value &= 0xFFFFFFFFu >> (32 - bits);
remaining = bits & 7;
for( i=0; i<remaining ; i++ )
{
if( !(msg->currentbit & 7) )
{
msg->data[msg->currentbit >> 3] = 0;
}
msg->data[msg->currentbit >> 3] |= (value & 1) << (msg->currentbit & 7);
msg->currentbit++;
value >>= 1;
}
bits -= remaining;
if( bits > 0 )
{
for( i=0 ; i<(bits+7)>>3 ; i++ )
{
Huff_EmitByte( value & 255, msg->data, &msg->currentbit );
value >>= 8;
}
}
msg->cursize = (msg->currentbit >> 3) + 1;
}
#endif
/*
============
MSG_WriteBits
============
*/
void MSG_WriteBits(sizebuf_t *msg, int value, int bits)
{
if( !bits || bits < -31 || bits > 32 )
Sys_Error("MSG_WriteBits: bad bits %i", bits);
if (bits < 0)
{ //negative means sign extension on reading
if (value & (1u<<(bits-1)))
value |= ~1u<<bits; //sign extend, just in case it matters (rawbytes with bits < n*8)...
bits = -bits;
}
switch( msg->packing )
{
default:
case SZ_BAD:
Sys_Error("MSG_WriteBits: bad msg->packing %i", msg->packing );
break;
case SZ_RAWBYTES:
MSG_WriteRawBytes( msg, value, bits );
break;
case SZ_RAWBITS:
MSG_WriteRawBits( msg, value, bits );
break;
#ifdef HUFFNETWORK
case SZ_HUFFMAN:
if( msg->maxsize - msg->cursize < 4 )
{
if (!msg->allowoverflow)
msg->overflowed = true;
return;
}
MSG_WriteHuffBits( msg, value, bits );
break;
#endif
}
}
void MSG_WriteChar (sizebuf_t *sb, int c)
{
qbyte *buf;
@ -1760,14 +1901,16 @@ void MSGCL_WriteDeltaUsercmd (sizebuf_t *buf, const usercmd_t *from, const userc
int msg_readcount;
qboolean msg_badread;
struct netprim_s msg_nullnetprim;
static sizebuf_t *msg_readmsg;
void MSG_BeginReading (struct netprim_s prim)
void MSG_BeginReading (sizebuf_t *sb, struct netprim_s prim)
{
msg_readmsg = sb;
msg_readcount = 0;
msg_badread = false;
net_message.currentbit = 0;
net_message.packing = SZ_RAWBYTES;
net_message.prim = prim;
sb->currentbit = 0;
sb->packing = SZ_RAWBYTES;
sb->prim = prim;
}
void MSG_ChangePrimitives(struct netprim_s prim)
@ -1777,7 +1920,7 @@ void MSG_ChangePrimitives(struct netprim_s prim)
int MSG_GetReadCount(void)
{
return msg_readcount;
return msg_readmsg->currentbit>>3;
}
@ -1827,6 +1970,13 @@ static int MSG_ReadRawBits(sizebuf_t *msg, int bits)
int val;
int bitmask = 0;
if (msg->currentbit + bits > (msg->cursize<<3))
{
msg_badread = true;
msg->currentbit = msg->cursize<<3;
return -1;
}
for(i=0 ; i<bits ; i++)
{
val = msg->data[msg->currentbit >> 3] >> (msg->currentbit & 7);
@ -1858,6 +2008,12 @@ static int MSG_ReadHuffBits(sizebuf_t *msg, int bits)
bitmask |= val << (i + remaining);
}
if (msg->currentbit > (msg->cursize<<3))
{
msg_badread = true;
msg->currentbit = msg->cursize<<3;
return -1;
}
msg_readcount = (msg->currentbit >> 3) + 1;
return bitmask;
@ -1880,21 +2036,21 @@ int MSG_ReadBits(int bits)
extend = true;
}
switch(net_message.packing)
switch(msg_readmsg->packing)
{
default:
case SZ_BAD:
Sys_Error("MSG_ReadBits: bad net_message.packing");
Sys_Error("MSG_ReadBits: bad msg_readmsg->packing");
break;
case SZ_RAWBYTES:
bitmask = MSG_ReadRawBytes(&net_message, bits);
bitmask = MSG_ReadRawBytes(msg_readmsg, bits);
break;
case SZ_RAWBITS:
bitmask = MSG_ReadRawBits(&net_message, bits);
bitmask = MSG_ReadRawBits(msg_readmsg, bits);
break;
#ifdef HUFFNETWORK
case SZ_HUFFMAN:
bitmask = MSG_ReadHuffBits(&net_message, bits);
bitmask = MSG_ReadHuffBits(msg_readmsg, bits);
break;
#endif
}
@ -1912,7 +2068,7 @@ int MSG_ReadBits(int bits)
void MSG_ReadSkip(int bytes)
{
if (net_message.packing!=SZ_RAWBYTES)
if (msg_readmsg->packing!=SZ_RAWBYTES)
{
while (bytes > 4)
{
@ -1925,13 +2081,14 @@ void MSG_ReadSkip(int bytes)
bytes--;
}
}
if (msg_readcount+bytes > net_message.cursize)
if (msg_readcount+bytes > msg_readmsg->cursize)
{
msg_readcount = net_message.cursize;
msg_readcount = msg_readmsg->cursize;
msg_badread = true;
return;
}
msg_readcount += bytes;
msg_readmsg->currentbit = msg_readcount<<3;
}
@ -1940,17 +2097,19 @@ int MSG_ReadChar (void)
{
int c;
if (net_message.packing!=SZ_RAWBYTES)
return (signed char)MSG_ReadBits(8);
if (msg_readmsg->packing!=SZ_RAWBYTES)
return MSG_ReadBits(-8);
if (msg_readcount+1 > net_message.cursize)
msg_readcount = msg_readmsg->currentbit>>3;
if (msg_readcount+1 > msg_readmsg->cursize)
{
msg_badread = true;
return -1;
}
c = (signed char)net_message.data[msg_readcount];
c = (signed char)msg_readmsg->data[msg_readcount];
msg_readcount++;
msg_readmsg->currentbit = msg_readcount<<3;
return c;
}
@ -1959,17 +2118,19 @@ int MSG_ReadByte (void)
{
unsigned char c;
if (net_message.packing!=SZ_RAWBYTES)
return (unsigned char)MSG_ReadBits(8);
if (msg_readmsg->packing!=SZ_RAWBYTES)
return MSG_ReadBits(8);
if (msg_readcount+1 > net_message.cursize)
msg_readcount = msg_readmsg->currentbit>>3;
if (msg_readcount+1 > msg_readmsg->cursize)
{
msg_badread = true;
return -1;
}
c = (unsigned char)net_message.data[msg_readcount];
c = (unsigned char)msg_readmsg->data[msg_readcount];
msg_readcount++;
msg_readmsg->currentbit = msg_readcount<<3;
return c;
}
@ -1978,19 +2139,21 @@ int MSG_ReadShort (void)
{
int c;
if (net_message.packing!=SZ_RAWBYTES)
if (msg_readmsg->packing!=SZ_RAWBYTES)
return (short)MSG_ReadBits(16);
if (msg_readcount+2 > net_message.cursize)
msg_readcount = msg_readmsg->currentbit>>3;
if (msg_readcount+2 > msg_readmsg->cursize)
{
msg_badread = true;
return -1;
}
c = (short)(net_message.data[msg_readcount]
+ (net_message.data[msg_readcount+1]<<8));
c = (short)(msg_readmsg->data[msg_readcount]
+ (msg_readmsg->data[msg_readcount+1]<<8));
msg_readcount += 2;
msg_readmsg->currentbit = msg_readcount<<3;
return c;
}
@ -1999,21 +2162,23 @@ int MSG_ReadLong (void)
{
int c;
if (net_message.packing!=SZ_RAWBYTES)
if (msg_readmsg->packing!=SZ_RAWBYTES)
return (int)MSG_ReadBits(32);
if (msg_readcount+4 > net_message.cursize)
msg_readcount = msg_readmsg->currentbit>>3;
if (msg_readcount+4 > msg_readmsg->cursize)
{
msg_badread = true;
return -1;
}
c = net_message.data[msg_readcount]
+ (net_message.data[msg_readcount+1]<<8)
+ (net_message.data[msg_readcount+2]<<16)
+ (net_message.data[msg_readcount+3]<<24);
c = msg_readmsg->data[msg_readcount]
+ (msg_readmsg->data[msg_readcount+1]<<8)
+ (msg_readmsg->data[msg_readcount+2]<<16)
+ (msg_readmsg->data[msg_readcount+3]<<24);
msg_readcount += 4;
msg_readmsg->currentbit = msg_readcount<<3;
return c;
}
@ -2072,23 +2237,25 @@ float MSG_ReadFloat (void)
int l;
} dat;
if (net_message.packing!=SZ_RAWBYTES)
if (msg_readmsg->packing!=SZ_RAWBYTES)
{
dat.l = MSG_ReadBits(32);
return dat.f;
}
if (msg_readcount+4 > net_message.cursize)
msg_readcount = msg_readmsg->currentbit>>3;
if (msg_readcount+4 > msg_readmsg->cursize)
{
msg_badread = true;
return -1;
}
dat.b[0] = net_message.data[msg_readcount];
dat.b[1] = net_message.data[msg_readcount+1];
dat.b[2] = net_message.data[msg_readcount+2];
dat.b[3] = net_message.data[msg_readcount+3];
dat.b[0] = msg_readmsg->data[msg_readcount];
dat.b[1] = msg_readmsg->data[msg_readcount+1];
dat.b[2] = msg_readmsg->data[msg_readcount+2];
dat.b[3] = msg_readmsg->data[msg_readcount+3];
msg_readcount += 4;
msg_readmsg->currentbit = msg_readcount<<3;
if (bigendian)
dat.l = LittleLong (dat.l);
@ -2185,7 +2352,7 @@ char *MSG_ReadStringLine (void)
float MSG_ReadCoord (void)
{
coorddata c = {{0}};
unsigned char coordtype = net_message.prim.coordtype;
unsigned char coordtype = msg_readmsg->prim.coordtype;
if (coordtype == COORDTYPE_UNDEFINED)
{
static float throttle;
@ -2265,7 +2432,7 @@ float MSG_ReadAngle16 (void)
}
float MSG_ReadAngle (void)
{
int sz = net_message.prim.anglesize;
int sz = msg_readmsg->prim.anglesize;
if (!sz)
{
static float throttle;
@ -2360,7 +2527,7 @@ void MSGQ2_ReadDeltaUsercmd (const usercmd_t *from, usercmd_t *move)
bits = MSG_ReadByte ();
if (net_message.prim.flags & NPQ2_R1Q2_UCMD)
if (msg_readmsg->prim.flags & NPQ2_R1Q2_UCMD)
buttons = MSG_ReadByte();
// read current angles
@ -2407,7 +2574,7 @@ void MSGQ2_ReadDeltaUsercmd (const usercmd_t *from, usercmd_t *move)
// read buttons
if (bits & Q2CM_BUTTONS)
{
if (net_message.prim.flags & NPQ2_R1Q2_UCMD)
if (msg_readmsg->prim.flags & NPQ2_R1Q2_UCMD)
move->buttons = buttons & (1|2|128); //only use the bits that are actually buttons, so gamecode can't get excited despite being crippled by this.
else
move->buttons = MSG_ReadByte ();
@ -5601,13 +5768,13 @@ static void COM_Version_f (void)
#ifdef BOTLIB_STATIC
Con_Printf(" Quake3");
#else
Con_Printf(" Quake3^h(no-botlib)^h");
Con_Printf(" Quake3^h(dynamic)^h");
#endif
#elif defined(Q3SERVER)
#ifdef BOTLIB_STATIC
Con_Printf(" Quake3(server)");
#else
Con_Printf(" Quake3(server,no-botlib)");
Con_Printf(" Quake3(server,dynamic)");
#endif
#elif defined(Q3CLIENT)
Con_Printf(" Quake3(client)");
@ -6409,7 +6576,7 @@ void COM_Init (void)
Cvar_Register (&gameversion, "Gamecode");
Cvar_Register (&gameversion_min, "Gamecode");
Cvar_Register (&gameversion_max, "Gamecode");
Cvar_Register (&com_nogamedirnativecode, "Gamecode");
Cvar_Register (&com_gamedirnativecode, "Gamecode");
Cvar_Register (&com_parseutf8, "Internationalisation");
#ifdef HAVE_LEGACY
Cvar_Register (&scr_usekfont, NULL);

View File

@ -318,7 +318,9 @@ float MSG_FromCoord(coorddata c, int bytes);
coorddata MSG_ToCoord(float f, int bytes);
coorddata MSG_ToAngle(float f, int bytes);
void MSG_BeginWriting (sizebuf_t *msg, struct netprim_s prim, void *bufferstorage, size_t buffersize);
void MSG_WriteChar (sizebuf_t *sb, int c);
void MSG_WriteBits (sizebuf_t *msg, int value, int bits);
void MSG_WriteByte (sizebuf_t *sb, int c);
void MSG_WriteShort (sizebuf_t *sb, int c);
void MSG_WriteLong (sizebuf_t *sb, int c);
@ -344,7 +346,7 @@ extern int msg_readcount;
extern qboolean msg_badread; // set if a read goes beyond end of message
extern struct netprim_s msg_nullnetprim;
void MSG_BeginReading (struct netprim_s prim);
void MSG_BeginReading (sizebuf_t *sb, struct netprim_s prim);
void MSG_ChangePrimitives(struct netprim_s prim);
int MSG_GetReadCount(void);
int MSG_ReadChar (void);
@ -452,7 +454,7 @@ char *COM_ParseType (const char *data, char *out, size_t outlen, com_tokentype_t
char *COM_ParseStringSet (const char *data, char *out, size_t outlen); //whitespace or semi-colon separators
char *COM_ParseStringSetSep (const char *data, char sep, char *out, size_t outsize); //single-char-separator, no whitespace
char *COM_ParseCString (const char *data, char *out, size_t maxoutlen, size_t *writtenlen);
char *COM_StringParse (const char *data, char *token, unsigned int tokenlen, qboolean expandmacros, qboolean qctokenize);
char *COM_StringParse (const char *data, char *token, unsigned int tokenlen, qboolean expandmacros, qboolean qctokenize); //fancy version used for console etc parsing
#define COM_ParseToken(data,punct) COM_ParseTokenOut(data, punct, com_token, sizeof(com_token), &com_tokentype)
char *COM_ParseTokenOut (const char *data, const char *punctuation, char *token, size_t tokenlen, com_tokentype_t *tokentype); //note that line endings are a special type of token.
char *COM_TrimString(char *str, char *buffer, int buffersize);
@ -572,7 +574,7 @@ typedef struct searchpath_s
struct searchpath_s *next;
struct searchpath_s *nextpure;
} searchpath_t;
typedef struct {
typedef struct flocation_s{
struct searchpath_s *search; //used to say which filesystem driver to open the file from
void *fhandle; //used by the filesystem driver as a simple reference to the file
char rawname[MAX_OSPATH]; //blank means not readable directly
@ -660,7 +662,7 @@ enum fs_relative{
//note that many of theses paths can map to multiple system locations. FS_NativePath can vary somewhat in terms of what it returns, generally favouring writable locations rather then the path that actually contains a file.
FS_BINARYPATH, //where the 'exe' is located. we'll check here for dlls too.
FS_LIBRARYPATH, //for system dlls and stuff
FS_ROOT, //either homedir or basedir,
FS_ROOT, //./ (effectively -homedir if enabled, otherwise effectively -basedir arg)
FS_SYSTEM, //a system path. absolute paths are explicitly allowed and expected, but not required.
//after this point, all types must be relative to a gamedir
@ -708,7 +710,7 @@ void MyRegDeleteKeyValue(void *base, const char *keyname, const char *valuename)
void FS_UnloadPackFiles(void);
void FS_ReloadPackFiles(void);
char *FSQ3_GenerateClientPacksList(char *buffer, int maxlen, int basechecksum);
void FS_PureMode(int mode, char *purenamelist, char *purecrclist, char *refnamelist, char *refcrclist, int seed); //implies an fs_restart. ref package names are optional, for q3 where pure names don't contain usable paths
void FS_PureMode(const char *gamedir, int mode, char *purenamelist, char *purecrclist, char *refnamelist, char *refcrclist, int seed); //implies an fs_restart. ref package names are optional, for q3 where pure names don't contain usable paths
int FS_PureOkay(void);
//recursively tries to open files until it can get a zip.
@ -828,7 +830,7 @@ int FS_GetManifestArgv(char **argv, int maxargs);
struct zonegroup_s;
void *FS_LoadMallocGroupFile(struct zonegroup_s *ctx, char *path, size_t *fsize, qboolean filters);
qbyte *FS_LoadMallocFile (const char *path, size_t *fsize);
void *FS_LoadMallocFile (const char *path, size_t *fsize);
qbyte *FS_LoadMallocFileFlags (const char *path, unsigned int locateflags, size_t *fsize);
qofs_t FS_LoadFile(const char *name, void **file);
void FS_FreeFile(void *file);

View File

@ -595,6 +595,40 @@ void Cvar_PurgeDefaults_f(void)
}
}
//we're changing games. reset everything to engine defaults and kill all user cvars
static void Cvar_Free(cvar_t *tbf);
void Cvar_GamedirChange(void)
{
cvar_t *var, **link;
cvar_group_t *grp;
for (grp = cvar_groups; grp; grp = grp->next)
{
for (link = &grp->cvars; (var=*link); )
{
if (var->flags & CVAR_NORESET)
; //don't reset it (nor kill it).
else if (var->enginevalue)
Cvar_ForceSet(var, var->enginevalue);
else if (var->flags & CVAR_POINTER)
{
*link = var->next;
Z_Free(var->string);
if (var->defaultstr != var->enginevalue)
Cvar_DefaultFree(var->defaultstr);
if (var->latched_string)
Z_Free(var->latched_string);
if (var->name)
AHash_RemoveDataInsensitive(&cvar_hash, var->name, var);
if (var->name2)
AHash_RemoveDataInsensitive(&cvar_hash, var->name2, var);
Z_Free(var);
continue;
}
link = &(*link)->next;
}
}
}
void Cvar_ResetAll_f(void)
{
cvar_group_t *grp;
@ -992,7 +1026,8 @@ static cvar_t *Cvar_SetCore (cvar_t *var, const char *value, qboolean force)
{
if (strcmp(latch, value))
{
var->modified++; //only modified if it changed.
var->modified=true; //only modified if it changed.
var->modifiedcount++;
if (var->callback)
var->callback(var, latch);
@ -1226,6 +1261,7 @@ static void Cvar_Free(cvar_t *tbf)
grp->cvars = tbf->next;
goto unlinked;
}
if (grp->cvars)
for (var=grp->cvars ; var->next ; var=var->next)
{
if (var->next == tbf)
@ -1281,6 +1317,7 @@ qboolean Cvar_Register (cvar_t *variable, const char *groupname)
group = Cvar_GetGroup(groupname);
variable->modified = old->modified;
variable->modifiedcount = old->modifiedcount;
variable->flags |= (old->flags & CVAR_ARCHIVE);
// link the variable in
@ -1358,7 +1395,23 @@ cvar_t *Cvar_Get2(const char *name, const char *defaultvalue, int flags, const c
var = Cvar_FindVar(name);
if (var)
{
#ifdef HAVE_CLIENT
if ((flags & CVAR_USERINFO) && !(var->flags & CVAR_USERINFO))
{
var->flags |= CVAR_USERINFO;
InfoBuf_SetKey(&cls.userinfo[0], var->name, var->string);
}
#endif
#ifdef HAVE_SERVER
if ((flags & CVAR_SERVERINFO) && !(var->flags & CVAR_SERVERINFO))
{
var->flags |= CVAR_SERVERINFO;
InfoBuf_SetKey (&svs.info, var->name, var->string);
}
#endif
return var;
}
if (!description || !*description)
description = NULL;
@ -1371,6 +1424,7 @@ cvar_t *Cvar_Get2(const char *name, const char *defaultvalue, int flags, const c
strcpy(var->name, name);
var->string = (char*)defaultvalue;
var->flags = flags|CVAR_POINTER|CVAR_USERCREATED;
var->modifiedcount = 1; //this counter always starts at 1, for q3 compat
if (description)
{
char *desc = var->name+strlen(var->name)+1;
@ -1419,19 +1473,17 @@ Cvar_Command
Handles variable inspection and changing from the console
============
*/
qboolean Cvar_Command (int level)
qboolean Cvar_Command (cvar_t *v, int level)
{
cvar_t *v;
char *str;
char buffer[65536];
int olev;
// check variables
v = Cvar_FindVar (Cmd_Argv(0));
if (!v)
return false;
if (!level || (v->restriction?v->restriction:rcon_level.ival) > level)
if (level==RESTRICT_TEAMPLAY || (v->restriction?v->restriction:rcon_level.ival) > level)
{
Con_TPrintf ("You do not have the priveledges for %s\n", v->name);
return true;

View File

@ -62,7 +62,7 @@ typedef struct cvar_s
char *string;
char *latched_string; // for CVAR_LATCHMASK vars
unsigned int flags;
int modified; // increased each time the cvar is changed
qboolean modified;
float value;
struct cvar_s *next;
@ -73,11 +73,11 @@ typedef struct cvar_s
const char *description;
char *enginevalue; //when changing manifest dir, the cvar will be reset to this value. never freed.
char *defaultstr; //this is the current mod's default value. set on first update.
qbyte restriction;
int ival;
vec4_t vec4; //0,0,0,1 if something didn't parse.
qbyte restriction;
int modifiedcount;
#ifdef HLSERVER
struct hlcvar_s *hlcvar;
@ -206,7 +206,7 @@ char *Cvar_CompleteVariable (const char *partial);
// attempts to match a partial variable name for command line completion
// returns NULL if nothing fits
qboolean Cvar_Command (int level);
qboolean Cvar_Command (cvar_t *v, int level);
// called by Cmd_ExecuteString when Cmd_Argv(0) doesn't match a known
// command. Returns true if the command was a variable reference that
// was handled. (print or change)

View File

@ -24,14 +24,13 @@ static unsigned int fs_restarts;
void *fs_thread_mutex;
float fs_accessed_time; //timestamp of read (does not include flocates, which should normally happen via a cache).
static cvar_t com_fs_cache = CVARF("fs_cache", IFMINIMAL("2","1"), CVAR_ARCHIVE);
static cvar_t fs_noreexec = CVARD("fs_noreexec", "0", "Disables automatic re-execing configs on gamedir switches.\nThis means your cvar defaults etc may be from the wrong mod, and cfg_save will leave that stuff corrupted!");
static cvar_t cfg_reload_on_gamedir = CVAR("cfg_reload_on_gamedir", "1");
static cvar_t fs_game = CVARAFCD("fs_game"/*q3*/, "", "game"/*q2/qs*/, CVAR_NOSAVE|CVAR_NORESET, fs_game_callback, "Provided for Q2 compat.");
#ifdef Q2SERVER
static cvar_t fs_gamedir = CVARFD("fs_gamedir", "", CVAR_NOUNSAFEEXPAND|CVAR_NOSET|CVAR_NOSAVE, "Provided for Q2 compat.");
static cvar_t fs_basedir = CVARFD("fs_basedir", "", CVAR_NOUNSAFEEXPAND|CVAR_NOSET|CVAR_NOSAVE, "Provided for Q2 compat.");
#endif
static cvar_t com_fs_cache = CVARFD ("fs_cache", IFMINIMAL("2","1"), CVAR_ARCHIVE, "0: Do individual lookups.\n1: Scan all files for accelerated lookups. This provides a performance boost on windows and avoids case sensitivity issues on linux.\n2: like 1, but don't bother checking for external changes (avoiding the cost of rebuild the cache).");
static cvar_t fs_noreexec = CVARD ("fs_noreexec", "0", "Disables automatic re-execing configs on gamedir switches.\nThis means your cvar defaults etc may be from the wrong mod, and cfg_save will leave that stuff corrupted!");
static cvar_t cfg_reload_on_gamedir = CVAR ("cfg_reload_on_gamedir", "1");
static cvar_t fs_game = CVARAFCD ("fs_game"/*q3*/, "", "game"/*q2/qs*/, CVAR_NOSAVE|CVAR_NORESET, fs_game_callback, "Provided for Q2 compat. Contains the subdir of the current mod.");
static cvar_t fs_gamepath = CVARAFD ("fs_gamepath"/*q3ish*/, "", "fs_gamedir"/*q2*/, CVAR_NOUNSAFEEXPAND|CVAR_NOSET|CVAR_NOSAVE, "Provided for Q2/Q3 compat. System path of the active gamedir.");
static cvar_t fs_basepath = CVARAFD ("fs_basepath"/*q3*/, "", "fs_basedir"/*q2*/, CVAR_NOUNSAFEEXPAND|CVAR_NOSET|CVAR_NOSAVE, "Provided for Q2/Q3 compat. System path of the base directory.");
static cvar_t fs_homepath = CVARAFD ("fs_homepath"/*q3ish*/, "", "fs_homedir"/*q2ish*/, CVAR_NOUNSAFEEXPAND|CVAR_NOSET|CVAR_NOSAVE, "Provided for Q2/Q3 compat. System path of the base directory.");
static cvar_t dpcompat_ignoremodificationtimes = CVARAFD("fs_packageprioritisation", "1", "dpcompat_ignoremodificationtimes", CVAR_NOUNSAFEEXPAND|CVAR_NOSAVE, "Favours the package that is:\n0: Most recently modified\n1: Is alphabetically last (favour z over a, 9 over 0).");
int active_fs_cachetype;
static int fs_referencetype;
@ -2564,6 +2563,13 @@ qboolean FS_Rename2(const char *oldf, const char *newf, enum fs_relative oldrela
}
qboolean FS_Rename(const char *oldf, const char *newf, enum fs_relative relativeto)
{
char cleanold[MAX_QPATH];
char cleannew[MAX_QPATH];
if (relativeto != FS_SYSTEM)
{
oldf = FS_GetCleanPath(oldf, false, cleanold, sizeof(cleanold));
newf = FS_GetCleanPath(newf, false, cleannew, sizeof(cleannew));
}
return FS_Rename2(oldf, newf, relativeto, relativeto);
}
qboolean FS_Remove(const char *fname, enum fs_relative relativeto)
@ -2781,7 +2787,7 @@ qbyte *COM_LoadFile (const char *path, unsigned int locateflags, int usehunk, si
return buf;
}
qbyte *FS_LoadMallocFile (const char *path, size_t *fsize)
void *FS_LoadMallocFile (const char *path, size_t *fsize)
{
return COM_LoadFile (path, 0, 5, fsize);
}
@ -3872,27 +3878,14 @@ qboolean FS_PathURLCache(const char *url, char *path, size_t pathsize)
return true;
}
/*
================
COM_Gamedir
Sets the gamedir and path to a different directory.
================
*/
void COM_Gamedir (const char *dir, const struct gamepacks *packagespaths)
static ftemanifest_t *FS_Manifest_ChangeGameDir(const char *newgamedir)
{
ftemanifest_t *man;
if (!fs_manifest)
FS_ChangeGame(NULL, true, false);
//we do allow empty here, for base.
if (*dir && !FS_GamedirIsOkay(dir))
{
Con_Printf ("Gamedir should be a single filename, not \"%s\"\n", dir);
return;
}
if (*newgamedir && !FS_GamedirIsOkay(newgamedir))
return fs_manifest;
man = FS_Manifest_ReadMod(dir);
man = FS_Manifest_ReadMod(newgamedir);
if (!man)
{
@ -3906,14 +3899,14 @@ void COM_Gamedir (const char *dir, const struct gamepacks *packagespaths)
if (!man)
man = FS_Manifest_Clone(fs_manifest);
FS_Manifest_PurgeGamedirs(man);
if (*dir)
if (*newgamedir)
{
char token[MAX_QPATH], quot[MAX_QPATH];
char *dup = Z_StrDup(dir); //FIXME: is this really needed?
dir = dup;
while ((dir = COM_ParseStringSet(dir, token, sizeof(token))))
char *dup = Z_StrDup(newgamedir); //FIXME: is this really needed?
newgamedir = dup;
while ((newgamedir = COM_ParseStringSet(newgamedir, token, sizeof(token))))
{
if (!strcmp(dir, ";"))
if (!strcmp(newgamedir, ";"))
continue;
if (!*token)
continue;
@ -3923,20 +3916,52 @@ void COM_Gamedir (const char *dir, const struct gamepacks *packagespaths)
}
Z_Free(dup);
}
while(packagespaths && packagespaths->path)
{
char quot[MAX_QPATH];
char quot2[MAX_OSPATH];
char quot3[MAX_OSPATH];
if (packagespaths->url)
Cmd_TokenizeString(va("package %s prefix %s %s", COM_QuotedString(packagespaths->path, quot, sizeof(quot), false), COM_QuotedString(packagespaths->subpath?packagespaths->subpath:"", quot3, sizeof(quot3), false), COM_QuotedString(packagespaths->url, quot2, sizeof(quot2), false)), false, false);
else
Cmd_TokenizeString(va("package %s prefix %s", COM_QuotedString(packagespaths->path, quot, sizeof(quot), false), COM_QuotedString(packagespaths->subpath?packagespaths->subpath:"", quot3, sizeof(quot3), false)), false, false);
FS_Manifest_ParseTokens(man);
packagespaths++;
}
}
return man;
}
/*
================
COM_Gamedir
Sets the gamedir and path to a different directory.
================
*/
void COM_Gamedir (const char *dir, const struct gamepacks *packagespaths)
{
ftemanifest_t *man;
COM_FlushTempoaryPacks();
if (!fs_manifest)
FS_ChangeGame(NULL, true, false);
//we do allow empty here, for base.
if (*dir && !FS_GamedirIsOkay(dir))
{
Con_Printf ("Gamedir should be a single filename, not \"%s\"\n", dir);
return;
}
man = FS_Manifest_ChangeGameDir(dir);
while(packagespaths && packagespaths->path)
{
char quot[MAX_QPATH];
char quot2[MAX_OSPATH];
char quot3[MAX_OSPATH];
if (packagespaths->url)
Cmd_TokenizeString(va("package %s prefix %s %s", COM_QuotedString(packagespaths->path, quot, sizeof(quot), false), COM_QuotedString(packagespaths->subpath?packagespaths->subpath:"", quot3, sizeof(quot3), false), COM_QuotedString(packagespaths->url, quot2, sizeof(quot2), false)), false, false);
else
Cmd_TokenizeString(va("package %s prefix %s", COM_QuotedString(packagespaths->path, quot, sizeof(quot), false), COM_QuotedString(packagespaths->subpath?packagespaths->subpath:"", quot3, sizeof(quot3), false)), false, false);
FS_Manifest_ParseTokens(man);
packagespaths++;
}
FS_ChangeGame(man, cfg_reload_on_gamedir.ival, false);
#ifdef HAVE_SERVER
if (!*dir)
dir = FS_GetGamedir(true);
InfoBuf_SetStarKey (&svs.info, "*gamedir", dir);
#endif
}
#if !defined(HAVE_LEGACY) || !defined(HAVE_CLIENT)
@ -3980,15 +4005,17 @@ void COM_Gamedir (const char *dir, const struct gamepacks *packagespaths)
/*set some stuff so our regular qw client appears more like hexen2. sv_mintic is required to 'fix' the ravenstaff so that its projectiles don't impact upon each other*/
#define HEX2CFG "//schemes hexen2\n" "set v_gammainverted 1\nset com_parseutf8 -1\nset gl_font gfx/hexen2\nset in_builtinkeymap 0\nset_calc cl_playerclass int (random * 5) + 1\nset cl_forwardspeed 200\nset cl_backspeed 200\ncl_sidespeed 225\nset sv_maxspeed 640\ncl_run 0\nset watervis 1\nset r_lavaalpha 1\nset r_lavastyle -2\nset r_wateralpha 0.5\nset sv_pupglow 1\ngl_shaftlight 0.5\nsv_mintic 0.015\nset r_meshpitch -1\nset r_meshroll -1\nr_sprite_backfacing 1\nset mod_warnmodels 0\nset cl_model_bobbing 1\nsv_sound_watersplash \"misc/hith2o.wav\"\nsv_sound_land \"fx/thngland.wav\"\nset sv_walkpitch 0\n"
/*yay q2!*/
#define Q2CFG "//schemes quake2\n" "set v_gammainverted 1\nset com_parseutf8 0\ncom_nogamedirnativecode 0\nset sv_bigcoords 0\nsv_port "STRINGIFY(PORT_Q2SERVER)"\n"
#define Q2CFG "//schemes quake2\n" "set v_gammainverted 1\nset com_parseutf8 0\ncom_gamedirnativecode 1\nset sv_bigcoords 0\nsv_port "STRINGIFY(PORT_Q2SERVER)"\ncl_defaultport "STRINGIFY(PORT_Q2SERVER)"\n"
/*Q3's ui doesn't like empty model/headmodel/handicap cvars, even if the gamecode copes*/
#define Q3CFG "//schemes quake3\n" "set v_gammainverted 0\nset snd_ignorecueloops 1\nsetfl g_gametype 0 s\nset gl_clear 1\nset r_clearcolour 0 0 0\nset com_parseutf8 0\ngl_overbright "FORWEB("0","2")"\nseta model sarge\nseta headmodel sarge\nseta handicap 100\ncom_nogamedirnativecode 0\nsv_port "STRINGIFY(PORT_Q3SERVER)"\n"
#define Q3CFG "//schemes quake3\n" "set v_gammainverted 0\nset snd_ignorecueloops 1\nsetfl g_gametype 0 s\nset gl_clear 1\nset r_clearcolour 0 0 0\nset com_parseutf8 0\ngl_overbright "FORWEB("0","2")"\nseta model sarge\nseta headmodel sarge\nseta handicap 100\ncom_gamedirnativecode 1\nsv_port "STRINGIFY(PORT_Q3SERVER)"\ncl_defaultport "STRINGIFY(PORT_Q3SERVER)"\ncom_protocolversion 68\n"
//#define RMQCFG "sv_bigcoords 1\n"
#ifdef HAVE_SSL
#define UPDATEURL(g) "/downloadables.php?game=" #g
#else
#define UPDATEURL(g) NULL
#ifndef UPDATEURL
#ifdef HAVE_SSL
#define UPDATEURL(g) "/downloadables.php?game=" #g
#else
#define UPDATEURL(g) NULL
#endif
#endif
#define QUAKEPROT "FTE-Quake DarkPlaces-Quake"
@ -4002,9 +4029,10 @@ typedef struct {
const char *customexec;
const char *dir[4];
const char *poshname; //Full name for the game.
const char *downloadsurl;
const char *manifestfile;
const char *poshname; //Full name for the game.
const char *downloadsurl; //url to check for updates.
const char *needpackages; //package name(s) that are considered mandatory for this game to work.
const char *manifestfile; //contents of manifest file to use.
} gamemode_info_t;
static const gamemode_info_t gamemode_info[] = {
#ifdef GAME_SHORTNAME
@ -4027,7 +4055,7 @@ static const gamemode_info_t gamemode_info[] = {
#define GAME_MANIFESTUPDATE NULL
#endif
{"-"GAME_SHORTNAME, GAME_SHORTNAME, GAME_PROTOCOL, {GAME_IDENTIFYINGFILES}, GAME_DEFAULTCMDS, {GAME_BASEGAMES}, GAME_FULLNAME, GAME_MANIFESTUPDATE},
{"-"GAME_SHORTNAME, GAME_SHORTNAME, GAME_PROTOCOL, {GAME_IDENTIFYINGFILES}, GAME_DEFAULTCMDS, {GAME_BASEGAMES}, GAME_FULLNAME, NULL/*updateurl*/, NULL/*needpackages*/, GAME_MANIFESTUPDATE},
#endif
//note that there is no basic 'fte' gamemode, this is because we aim for network compatability. Darkplaces-Quake is the closest we get.
//this is to avoid having too many gamemodes anyway.
@ -4089,8 +4117,8 @@ static const gamemode_info_t gamemode_info[] = {
#endif
#if defined(Q3CLIENT) || defined(Q3SERVER)
{"-quake3", "q3", "Quake3", {"baseq3/pak0.pk3"}, Q3CFG, {"baseq3", "*fteq3"}, "Quake III Arena", UPDATEURL(Q3)},
{"-quake3demo", "q3demo", "Quake3Demo", {"demoq3/pak0.pk3"}, Q3CFG, {"demoq3", "*fteq3"}, "Quake III Arena Demo"},
{"-quake3", "q3", "Quake3", {"baseq3/pak0.pk3"}, Q3CFG, {"baseq3", "*fteq3"}, "Quake III Arena", UPDATEURL(Q3), "quake3"},
{"-quake3demo", "q3demo", "Quake3Demo", {"demoq3/pak0.pk3"}, Q3CFG, {"demoq3", "*fteq3"}, "Quake III Arena Demo", NULL, "quake3"},
//the rest are not supported in any real way. maps-only mostly, if that
// {"-quake4", "q4", "FTE-Quake4", {"q4base/pak00.pk4"}, NULL, {"q4base", "*fteq4"}, "Quake 4"},
// {"-et", NULL, "FTE-EnemyTerritory", {"etmain/pak0.pk3"}, NULL, {"etmain", "*fteet"}, "Wolfenstein - Enemy Territory"},
@ -4419,8 +4447,9 @@ qboolean CL_ListFilesInPackage(searchpathfuncs_t *search, char *name, int (QDECL
return ret;
}
void FS_PureMode(int puremode, char *purenamelist, char *purecrclist, char *refnamelist, char *refcrclist, int pureseed)
void FS_PureMode(const char *gamedir, int puremode, char *purenamelist, char *purecrclist, char *refnamelist, char *refcrclist, int pureseed)
{
ftemanifest_t *man;
qboolean pureflush;
#ifdef HAVE_SERVER
@ -4451,7 +4480,12 @@ void FS_PureMode(int puremode, char *purenamelist, char *purecrclist, char *refn
fs_refnames = refnamelist?Z_StrDup(refnamelist):NULL;
fs_refcrcs = refcrclist?Z_StrDup(refcrclist):NULL;
FS_ChangeGame(fs_manifest, false, false);
if (gamedir)
man = FS_Manifest_ChangeGameDir(gamedir);
else
man = fs_manifest;
FS_ChangeGame(man, false, false);
if (pureflush)
{
@ -6146,7 +6180,13 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs, qboolean
Cmd_TokenizeString(va("downloadsurl \"%s\"", gamemode_info[i].downloadsurl), false, false);
FS_Manifest_ParseTokens(man);
}
if (!man->installupd && gamemode_info[i].needpackages)
{
Cmd_TokenizeString(va("install \"%s\"", gamemode_info[i].needpackages), false, false);
FS_Manifest_ParseTokens(man);
}
#endif
if (!man->protocolname)
{
Cmd_TokenizeString(va("protocolname \"%s\"", gamemode_info[i].protocolname), false, false);
@ -6357,10 +6397,9 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs, qboolean
Cvar_ForceSet(&fs_game, FS_GetGamedir(false));
fs_game.callback = callback;
}
#ifdef Q2SERVER
Cvar_ForceSet(&fs_gamedir, va("%s%s", com_gamepath, FS_GetGamedir(false)));
Cvar_ForceSet(&fs_basedir, com_gamepath);
#endif
Cvar_ForceSet(&fs_gamepath, va("%s%s", com_gamepath, FS_GetGamedir(false)));
Cvar_ForceSet(&fs_basepath, com_gamepath);
Cvar_ForceSet(&fs_homepath, com_gamepath);
Mods_FlushModList();
@ -6624,7 +6663,8 @@ qboolean FS_FixupGamedirForExternalFile(char *input, char *filename, size_t fnam
return false;
}
void Cvar_GamedirChange(void);
void Plug_Shutdown(qboolean preliminary);
/*mod listing management*/
static struct modlist_s *modlist;
@ -6831,7 +6871,7 @@ static void FS_ModInstallGot(struct dl_download *dl)
if (ctx->man && !strcmp(ctx->man->basedir, com_gamepath))
{
//should probably show just the hostname for brevity.
Menu_Prompt(FS_ModInstallConfirmed, ctx, va("Install %s from\n%s ?", ctx->man->formalname, ctx->url), "Install", NULL, "Cancel");
Menu_Prompt(FS_ModInstallConfirmed, ctx, va("Install %s from\n%s ?", ctx->man->formalname, ctx->url), "Install", NULL, "Cancel", true);
return;
}
}
@ -6947,6 +6987,19 @@ static void FS_ChangeGame_f(void)
}
else
{
arg = Z_StrDup(arg);
#ifdef HAVE_SERVER
if (sv.state)
SV_UnspawnServer();
#endif
#ifdef HAVE_CLIENT
CL_Disconnect (NULL);
#endif
#ifdef PLUGINS
Plug_Shutdown(true);
#endif
Cvar_GamedirChange();
if (strrchr(arg, '/') && !strrchr(arg, '/')[1])
{ //ends in slash. a new basedir.
Q_strncpyz(com_gamepath, arg, sizeof(com_gamepath));
@ -6961,15 +7014,27 @@ static void FS_ChangeGame_f(void)
{
Con_Printf("Switching to %s\n", gamemode_info[i].argname+1);
FS_ChangeGame(FS_GenerateLegacyManifest(i, NULL), true, true);
return;
break;
}
}
if (!gamemode_info[i].argname)
{
#ifdef HAVE_CLIENT
if (!Host_RunFile(arg, strlen(arg), NULL))
Con_Printf("Game unknown\n");
if (!Host_RunFile(arg, strlen(arg), NULL))
Con_Printf("Game unknown\n");
#endif
}
}
Z_Free((char*)arg);
#ifdef PLUGINS
Plug_Initialise(true);
#endif
#if defined(HAVE_CLIENT) && defined(Q3CLIENT)
if (q3)
q3->ui.Start();
#endif
}
}
@ -7421,10 +7486,9 @@ void COM_InitFilesystem (void)
Cvar_Register(&com_protocolname, "Server Info");
Cvar_Register(&com_protocolversion, "Server Info");
Cvar_Register(&fs_game, "Filesystem");
#ifdef Q2SERVER
Cvar_Register(&fs_gamedir, "Filesystem");
Cvar_Register(&fs_basedir, "Filesystem");
#endif
Cvar_Register(&fs_gamepath, "Filesystem");
Cvar_Register(&fs_basepath, "Filesystem");
Cvar_Register(&fs_homepath, "Filesystem");
COM_InitHomedir(NULL);

View File

@ -74,7 +74,7 @@ void FS_AddHashedPackage(searchpath_t **oldpaths, const char *parent_pure, const
void PM_LoadPackages(searchpath_t **oldpaths, const char *parent_pure, const char *parent_logical, searchpath_t *search, unsigned int loadstuff, int minpri, int maxpri);
void *PM_GeneratePackageFromMeta(vfsfile_t *file, char *fname, size_t fnamesize, enum fs_relative *fsroot);
void PM_FileInstalled(const char *filename, enum fs_relative fsroot, void *metainfo, qboolean enable); //we finished installing a file via some other mechanism (drag+drop or from server. insert it into the updates menu.
void PM_EnumeratePlugins(void (*callback)(const char *name));
void PM_EnumeratePlugins(void (*callback)(const char *name, qboolean blocked));
struct xcommandargcompletioncb_s;
void PM_EnumerateMaps(const char *partial, struct xcommandargcompletioncb_s *ctx);
void PM_LoadMap(const char *package, const char *map);

View File

@ -486,6 +486,7 @@ static void Huff_Init(huffman_t *huff)
Huff_addRef(&huff->decompressor, (qbyte)i);
}
}
huff->built = true;
}

View File

@ -848,7 +848,7 @@ qboolean CertLog_ConnectOkay(const char *hostname, void *cert, size_t certsize,
text[len] = 0;
//FIXME: display some sort of fingerprint
Menu_Prompt(CertLog_Add_Prompted, ctx, text, accepttext, NULL, localtext("Disconnect"));
Menu_Prompt(CertLog_Add_Prompted, ctx, text, accepttext, NULL, localtext("Disconnect"), true);
}
return false; //can't connect yet...
}

View File

@ -72,6 +72,10 @@ typedef struct netadr_s
netadrtype_t type;
netproto_t prot;
unsigned short port;
unsigned short connum; //which quake connection/socket the address is talking about. 1-based. 0 is unspecified. this is NOT used for address equivelency.
unsigned int scopeid; //ipv6 interface id thing.
union {
qbyte ip[4];
qbyte ip6[16];
@ -97,10 +101,6 @@ typedef struct netadr_s
} un;
#endif
} address;
unsigned short port;
unsigned short connum; //which quake connection/socket the address is talking about. 1-based. 0 is unspecified. this is NOT used for address equivelency.
unsigned int scopeid; //ipv6 interface id thing.
} netadr_t;
struct sockaddr_qstorage

View File

@ -451,7 +451,7 @@ enum nqnc_packettype_e NQNetChan_Process(netchan_t *chan)
int drop;
chan->bytesin += net_message.cursize;
MSG_BeginReading (chan->netprim);
MSG_BeginReading (&net_message, chan->netprim);
header = LongSwap(MSG_ReadLong());
@ -486,7 +486,7 @@ enum nqnc_packettype_e NQNetChan_Process(netchan_t *chan)
}
memcpy(net_message.data, tmp, net_message.cursize);
MSG_BeginReading (chan->netprim);
MSG_BeginReading (&net_message, chan->netprim);
header = LongSwap(MSG_ReadLong()); //re-read the now-decompressed copy of the header for the real flags
}
#endif
@ -598,7 +598,7 @@ enum nqnc_packettype_e NQNetChan_Process(netchan_t *chan)
SZ_Clear(&net_message);
SZ_Write(&net_message, chan->in_fragment_buf, chan->in_fragment_length);
chan->in_fragment_length = 0;
MSG_BeginReading(chan->netprim);
MSG_BeginReading(&net_message, chan->netprim);
if (showpackets.value)
Con_Printf ("in %s r=%i %i\n"
@ -1001,7 +1001,7 @@ qboolean Netchan_Process (netchan_t *chan)
chan->bytesin += net_message.cursize;
// get sequence numbers
MSG_BeginReading (chan->netprim);
MSG_BeginReading (&net_message, chan->netprim);
sequence = MSG_ReadLong ();
sequence_ack = MSG_ReadLong ();

View File

@ -12,88 +12,6 @@
#ifdef HAVE_GNUTLS
#if defined(_WIN32) && !defined(MINGW) && 0
#define GNUTLS_VERSION "2.12.23"
#define GNUTLS_SOPREFIX ""
#define GNUTLS_SONUM 26
#ifdef _MSC_VER
#if SIZE_MAX == ULONG_MAX
#define ssize_t long
#else
#define ssize_t int
#endif
#endif
//lets rip stuff out of the header and supply a seperate dll.
//gnutls is huge.
//also this helps get around the whole msvc/mingw thing.
struct DSTRUCT;
typedef struct DSTRUCT* gnutls_certificate_credentials_t;
typedef gnutls_certificate_credentials_t gnutls_certificate_client_credentials_t;
typedef struct DSTRUCT* gnutls_anon_client_credentials_t;
struct gnutls_session_int;
typedef struct gnutls_session_int* gnutls_session_t;
typedef void * gnutls_transport_ptr_t;
struct gnutls_x509_crt_int;
typedef struct gnutls_x509_crt_int *gnutls_x509_crt_t;
typedef struct
{
unsigned char *data;
unsigned int size;
} gnutls_datum_t;
typedef enum gnutls_kx_algorithm { GNUTLS_KX_RSA=1, GNUTLS_KX_DHE_DSS,
GNUTLS_KX_DHE_RSA, GNUTLS_KX_ANON_DH, GNUTLS_KX_SRP,
GNUTLS_KX_RSA_EXPORT, GNUTLS_KX_SRP_RSA, GNUTLS_KX_SRP_DSS
} gnutls_kx_algorithm;
typedef enum {
GNUTLS_CRT_UNKNOWN = 0,
GNUTLS_CRT_X509 = 1,
GNUTLS_CRT_OPENPGP = 2,
GNUTLS_CRT_RAW = 3
} gnutls_certificate_type_t;
typedef enum {
GNUTLS_X509_FMT_DER = 0,
GNUTLS_X509_FMT_PEM = 1
} gnutls_x509_crt_fmt_t;
typedef enum
{
GNUTLS_CERT_INVALID = 1<<1,
GNUTLS_CERT_REVOKED = 1<<5,
GNUTLS_CERT_SIGNER_NOT_FOUND = 1<<6,
GNUTLS_CERT_SIGNER_NOT_CA = 1<<7,
GNUTLS_CERT_INSECURE_ALGORITHM = 1<<8,
GNUTLS_CERT_NOT_ACTIVATED = 1<<9,
GNUTLS_CERT_EXPIRED = 1<<10,
GNUTLS_CERT_SIGNATURE_FAILURE = 1<<11,
GNUTLS_CERT_REVOCATION_DATA_SUPERSEDED = 1<<12,
GNUTLS_CERT_UNEXPECTED_OWNER = 1<<14,
GNUTLS_CERT_REVOCATION_DATA_ISSUED_IN_FUTURE = 1<<15,
GNUTLS_CERT_SIGNER_CONSTRAINTS_FAILURE = 1<<16,
GNUTLS_CERT_MISMATCH = 1<<17,
} gnutls_certificate_status_t;
typedef enum gnutls_connection_end { GNUTLS_SERVER=1, GNUTLS_CLIENT } gnutls_connection_end_t;
typedef enum gnutls_credentials_type { GNUTLS_CRD_CERTIFICATE=1, GNUTLS_CRD_ANON, GNUTLS_CRD_SRP } gnutls_credentials_type_t;
typedef enum gnutls_close_request { GNUTLS_SHUT_RDWR=0, GNUTLS_SHUT_WR=1 } gnutls_close_request_t;
typedef ssize_t (*gnutls_pull_func) (gnutls_transport_ptr_t, void *, size_t);
typedef ssize_t (*gnutls_push_func) (gnutls_transport_ptr_t, const void *, size_t);
#define GNUTLS_E_AGAIN -28
#define GNUTLS_E_CERTIFICATE_ERROR -43
#define GNUTLS_E_INTERRUPTED -52
#define GNUTLS_E_PREMATURE_TERMINATION -110
typedef enum
{
GNUTLS_NAME_DNS = 1
} gnutls_server_name_type_t;
typedef int (VARGS gnutls_certificate_verify_function)(gnutls_session_t session);
#else
#include <gnutls/gnutls.h>
#if GNUTLS_VERSION_MAJOR >= 3
#include <gnutls/abstract.h>
@ -128,7 +46,6 @@ typedef int (VARGS gnutls_certificate_verify_function)(gnutls_session_t session)
#ifndef GNUTLS_SOPREFIX
#define GNUTLS_SOPREFIX
#endif
#endif
#if GNUTLS_VERSION_MAJOR >= 3
#if GNUTLS_VERSION_MAJOR >= 3

View File

@ -9,6 +9,9 @@
#define FTEENGINE
#include "../plugins/plugin.h"
struct q3gamecode_s *q3;
static struct plugin_s *q3plug;
#ifdef PLUGINS
#ifdef MODELFMT_GLTF
@ -21,6 +24,7 @@
cvar_t plug_sbar = CVARD("plug_sbar", "3", "Controls whether plugins are allowed to draw the hud, rather than the engine (when allowed by csqc). This is typically used to permit the ezhud plugin without needing to bother unloading it.\n=0: never use hud plugins.\n&1: Use hud plugins in deathmatch.\n&2: Use hud plugins in singleplayer/coop.\n=3: Always use hud plugins (when loaded).");
cvar_t plug_loaddefault = CVARD("plug_loaddefault", "1", "0: Load plugins only via explicit plug_load commands\n1: Load built-in plugins and those selected via the package manager\n2: Scan for misc plugins, loading all that can be found, but not built-ins.\n3: Scan for plugins, and then load any built-ins");
qboolean Plug_Q3_Init(void);
static struct
{
const char *name;
@ -36,6 +40,10 @@ static struct
#if defined(MODELFMT_GLTF)
{"GLTF", Plug_GLTF_Init},
#endif
#ifdef STATIC_Q3
{"Q3", Plug_Q3_Init},
#endif
{NULL}
};
//for internal plugins to link against
@ -87,7 +95,6 @@ typedef struct plugin_s {
dllhandle_t *lib;
void (QDECL *tick)(double realtime, double gametime);
qboolean (QDECL *executestring)(qboolean isinsecure);
#ifndef SERVERONLY
qboolean (QDECL *consolelink)(void);
qboolean (QDECL *consolelinkmouseover)(float x, float y);
@ -116,6 +123,7 @@ plugin_t *currentplug;
#ifndef SERVERONLY
#include "cl_plugin.inc"
#include "cl_master.h"
#else
void Plug_Client_Init(void){}
void Plug_Client_Close(plugin_t *plug) {}
@ -275,9 +283,22 @@ static plugin_t *Plug_Load(const char *file)
return newplug;
}
static void Plug_Load_Update(const char *name)
static void Plug_Load_Update(const char *name, qboolean blocked)
{
Plug_Load(name);
if (blocked)
{ //plugins can be blocked by gametypes (to prevents conflicts)
plugin_t *plug;
for (plug = plugs; plug; plug = plug->next)
{
if (!strcmp(plug->name, name))
{
Plug_Close(plug);
return;
}
}
}
else
Plug_Load(name);
}
static int QDECL Plug_EnumeratedRoot (const char *name, qofs_t size, time_t mtime, void *param, searchpathfuncs_t *spath)
@ -311,10 +332,6 @@ static void QDECL Plug_Con_Print(const char *text)
{
Con_Printf("%s", text);
}
static void QDECL Plug_Sys_Error(const char *text)
{
Sys_Error("%s", text);
}
static quintptr_t QDECL Plug_Sys_Milliseconds(void)
{
return Sys_DoubleTime()*1000u;
@ -322,10 +339,10 @@ static quintptr_t QDECL Plug_Sys_Milliseconds(void)
qboolean VARGS PlugBI_ExportFunction(const char *name, funcptr_t function)
{
if (!currentplug)
return false;
if (!strcmp(name, "Tick")) //void(int realtime)
currentplug->tick = function;
else if (!strcmp(name, "ExecuteCommand")) //bool(isinsecure)
currentplug->executestring = function;
else if (!strcmp(name, "Shutdown")) //void()
currentplug->shutdown = function;
else if (!strcmp(name, "MayShutdown")||!strcmp(name, "MayUnload"))
@ -407,6 +424,20 @@ static qboolean QDECL PlugBI_ExportInterface(const char *name, void *interfacept
#endif
if (!strcmp(name, "Crypto"))
return NET_RegisterCrypto(currentplug, interfaceptr);
#if defined(Q3SERVER)||defined(Q3CLIENT)
if (!strcmp(name, "Quake3Plugin") && sizeof(*q3) == structsize)
{
if (q3plug)
{
struct plugin_s *p = currentplug;
Plug_Close(q3plug);
currentplug = p;
}
q3 = interfaceptr;
q3plug = currentplug;
return true;
}
#endif
#ifdef HAVE_CLIENT
if (!strcmp(name, plugvrfuncs_name))
return R_RegisterVRDriver(currentplug, interfaceptr);
@ -429,65 +460,14 @@ static cvar_t *QDECL Plug_Cvar_GetNVFDG(const char *name, const char *defaultval
return Cvar_Get2(name, defaultvalue, flags&1, description, groupname);
}
typedef struct {
//Make SURE that the engine has resolved all cvar pointers into globals before this happens.
plugin_t *plugin;
cvar_t *var;
} plugincvararray_t;
static int plugincvararraylen;
static plugincvararray_t *plugincvararray;
//qhandle_t Cvar_Register (char *name, char *defaultval, int flags, char *grouphint);
static qhandle_t QDECL Plug_Cvar_Register(const char *name, const char *defaultvalue, int flags, const char *groupname)
{
cvar_t *var;
int i;
var = Cvar_Get(name, defaultvalue, flags&1, groupname);
for (i = 0; i < plugincvararraylen; i++)
{
if (!plugincvararray[i].var)
{ //hmm... a gap...
plugincvararray[i].plugin = currentplug;
plugincvararray[i].var = var;
return i;
}
}
i = plugincvararraylen;
plugincvararraylen++;
plugincvararray = BZ_Realloc(plugincvararray, (plugincvararraylen)*sizeof(plugincvararray_t));
plugincvararray[i].plugin = currentplug;
plugincvararray[i].var = var;
return i;
}
//int Cvar_Update, (qhandle_t handle, int modificationcount, char *stringv, float *floatv)); //stringv is 256 chars long, don't expect this function to do anything if modification count is unchanged.
static qboolean QDECL Plug_Cvar_Update(qhandle_t handle, int *modificationcount, char *outstringv, size_t stringsize, float *outfloatv)
{
cvar_t *var;
if (handle < 0 || handle >= plugincvararraylen)
return false;
if (plugincvararray[handle].plugin != currentplug)
return false; //I'm not letting you know what annother plugin has registered.
var = plugincvararray[handle].var;
//if (var->modified != *modificationcount) //for future optimisation
{
//*modificationcount = var->modified;
Q_strncpyz(outstringv, var->string, stringsize);
*outfloatv = var->value;
return true;
}
return false;
}
static void QDECL Plug_Cmd_TokenizeString(const char *text)
{
Cmd_TokenizeString(text, false, false);
}
static void QDECL Plug_Cmd_ShiftArgs(int args)
{
Cmd_ShiftArgs(args, false);
}
//void Cmd_Args(char *buffer, int buffersize)
static void QDECL Plug_Cmd_Args(char *buffer, int maxsize)
{
@ -502,7 +482,7 @@ static void QDECL Plug_Cmd_Args(char *buffer, int maxsize)
strcpy(buffer, args);
}
//void Cmd_Argv(int num, char *buffer, int buffersize)
static void QDECL Plug_Cmd_Argv(int argn, char *outbuffer, size_t buffersize)
static char *QDECL Plug_Cmd_Argv(int argn, char *outbuffer, size_t buffersize)
{
char *args;
args = Cmd_Argv(argn);
@ -514,6 +494,7 @@ static void QDECL Plug_Cmd_Argv(int argn, char *outbuffer, size_t buffersize)
}
else
strcpy(outbuffer, args);
return args;
}
//int Cmd_Argc(void)
static int QDECL Plug_Cmd_Argc(void)
@ -528,6 +509,13 @@ static void QDECL Plug_Cvar_SetString(const char *name, const char *value)
if (var)
Cvar_Set(var, value);
}
//void Cvar_SetString (char *name, char *value);
static void QDECL Plug_Cvar_ForceSetString(const char *name, const char *value)
{
cvar_t *var = Cvar_Get(name, value, 0, "Plugin vars");
if (var)
Cvar_ForceSet(var, value);
}
//void Cvar_SetFloat (char *name, float value);
static void QDECL Plug_Cvar_SetFloat(const char *cvarname, float newvalue)
@ -573,6 +561,8 @@ static qboolean QDECL Plug_Cvar_GetString(const char *name, char *outbuffer, qui
else
{
var = Cvar_Get(name, "", 0, "Plugin vars");
if (!var)
return false;
if (strlen(var->name)+1 > sizeofbuffer)
return false;
@ -592,10 +582,16 @@ static void QDECL Plug_Cmd_AddText(const char *text, qboolean insert)
Cbuf_AddText(text, level);
}
static qboolean QDECL Plug_Cmd_IsInsecure(void)
{
return Cmd_IsInsecure();
}
static int plugincommandarraylen;
typedef struct {
plugin_t *plugin;
char command[64];
xcommand_t func;
} plugincommand_t;
static plugincommand_t *plugincommandarray;
void Plug_Command_f(void)
@ -605,7 +601,7 @@ void Plug_Command_f(void)
plugin_t *oldplug = currentplug;
for (i = 0; i < plugincommandarraylen; i++)
{
if (!plugincommandarray[i].plugin)
if (!plugincommandarray[i].func)
continue; //don't check commands who's owners died.
if (Q_strcasecmp(plugincommandarray[i].command, cmd)) //not the right command
@ -613,17 +609,46 @@ void Plug_Command_f(void)
currentplug = plugincommandarray[i].plugin;
if (currentplug->executestring)
currentplug->executestring(Cmd_IsInsecure());
plugincommandarray[i].func();
break;
}
currentplug = oldplug;
}
static qboolean QDECL Plug_Cmd_AddCommand(const char *name)
static qboolean QDECL Plug_Cmd_AddCommand(const char *name, xcommand_t func, const char *desc)
{
int i;
if (!currentplug)
return false;
for (i = 0; i < plugincommandarraylen; i++)
{
if (!plugincommandarray[i].plugin)
break;
if (plugincommandarray[i].plugin == currentplug)
{
if (!strcmp(name, plugincommandarray[i].command))
return true; //already registered
}
}
if (i == plugincommandarraylen)
{
plugincommandarraylen++;
plugincommandarray = BZ_Realloc(plugincommandarray, plugincommandarraylen*sizeof(plugincommand_t));
}
Q_strncpyz(plugincommandarray[i].command, name, sizeof(plugincommandarray[i].command));
if (!Cmd_AddCommandD(plugincommandarray[i].command, Plug_Command_f, desc))
return false;
plugincommandarray[i].plugin = currentplug; //worked
plugincommandarray[i].func = func; //worked
return true;
}
static qboolean QDECL Plug_Cmd_AddCommandOld(const char *name)
{
int i;
if (!currentplug)
return false;
for (i = 0; i < plugincommandarraylen; i++)
{
if (!plugincommandarray[i].plugin)
@ -644,6 +669,7 @@ static qboolean QDECL Plug_Cmd_AddCommand(const char *name)
if (!Cmd_AddCommand(plugincommandarray[i].command, Plug_Command_f))
return false;
plugincommandarray[i].plugin = currentplug; //worked
plugincommandarray[i].func = NULL; //worked
return true;
}
static void Plug_FreeConCommands(plugin_t *plug)
@ -654,7 +680,9 @@ static void Plug_FreeConCommands(plugin_t *plug)
if (plugincommandarray[i].plugin == plug)
{
plugincommandarray[i].plugin = NULL;
plugincommandarray[i].func = NULL;
Cmd_RemoveCommand(plugincommandarray[i].command);
*plugincommandarray[i].command = 0;
}
}
}
@ -1198,11 +1226,11 @@ void Plug_Initialise(qboolean fromgamedir)
if (plug_loaddefault.ival & 1)
{
unsigned int u;
PM_EnumeratePlugins(Plug_Load_Update);
for (u = 0; staticplugins[u].name; u++)
{
Plug_Load(staticplugins[u].name);
}
PM_EnumeratePlugins(Plug_Load_Update);
}
}
@ -1240,27 +1268,6 @@ void Plug_ResChanged(void)
}
#endif
qboolean Plugin_ExecuteString(void)
{
plugin_t *oldplug = currentplug;
if (Cmd_Argc()>0)
{
for (currentplug = plugs; currentplug; currentplug = currentplug->next)
{
if (currentplug->executestring)
{
if (currentplug->executestring(0))
{
currentplug = oldplug;
return true;
}
}
}
}
currentplug = oldplug;
return false;
}
#ifndef SERVERONLY
qboolean Plug_ConsoleLinkMouseOver(float x, float y, char *text, char *info)
{
@ -1552,6 +1559,12 @@ void Plug_Close(plugin_t *plug)
FS_UnRegisterFileSystemModule(plug);
Mod_UnRegisterAllModelFormats(plug);
if (q3plug == plug)
{
q3 = NULL;
q3plug = NULL;
}
//tell the plugin that everything is closed and that it should free up any lingering memory/stuff
//it is still allowed to create/have open files.
if (plug->shutdown)
@ -1766,17 +1779,9 @@ void Plug_Shutdown(qboolean preliminary)
pluginstreamarray = NULL;
pluginstreamarraylen = 0;
plugincvararraylen = 0;
BZ_Free(plugincvararray);
plugincvararray = NULL;
plugincommandarraylen = 0;
BZ_Free(plugincommandarray);
plugincommandarray = NULL;
#ifndef SERVERONLY
Plug_Client_Shutdown();
#endif
}
}
@ -1789,8 +1794,10 @@ plugcorefuncs_t plugcorefuncs =
PlugBI_ExportInterface,
PlugBI_GetPluginName,
Plug_Con_Print,
Plug_Sys_Error,
Sys_Error,
Host_EndGame,
Plug_Sys_Milliseconds,
Sys_DoubleTime,
Sys_LoadLibrary,
Sys_GetAddressForName,
Sys_CloseLibrary,
@ -1799,6 +1806,7 @@ plugcorefuncs_t plugcorefuncs =
BZ_Realloc,
Z_Free,
ZG_Malloc,
ZG_Free,
ZG_FreeGroup,
};
@ -1817,9 +1825,11 @@ static void *QDECL PlugBI_GetEngineInterface(const char *interfacename, size_t s
COM_ParseType,
COM_ParseTokenOut,
Plug_Cmd_TokenizeString,
Plug_Cmd_ShiftArgs,
Plug_Cmd_Args,
Plug_Cmd_Argv,
Plug_Cmd_Argc,
Plug_Cmd_IsInsecure,
Plug_Cmd_AddCommand,
Plug_Cmd_AddText,
};
@ -1829,12 +1839,12 @@ static void *QDECL PlugBI_GetEngineInterface(const char *interfacename, size_t s
qboolean (QDECL*AddCommand) (const char *cmdname);
void (QDECL*TokenizeString) (const char *msg);
void (QDECL*Args) (char *buffer, int bufsize);
void (QDECL*Argv) (int argnum, char *buffer, size_t bufsize);
char * (QDECL*Argv) (int argnum, char *buffer, size_t bufsize);
int (QDECL*Argc) (void);
void (QDECL*AddText) (const char *text, qboolean insert);
} oldfuncs =
{
Plug_Cmd_AddCommand,
Plug_Cmd_AddCommandOld,
Plug_Cmd_TokenizeString,
Plug_Cmd_Args,
Plug_Cmd_Argv,
@ -1854,9 +1864,8 @@ static void *QDECL PlugBI_GetEngineInterface(const char *interfacename, size_t s
Plug_Cvar_SetFloat,
Plug_Cvar_GetString,
Plug_Cvar_GetFloat,
Plug_Cvar_Register,
Plug_Cvar_Update,
Plug_Cvar_GetNVFDG,
Plug_Cvar_ForceSetString,
};
if (structsize == sizeof(funcs))
return &funcs;
@ -1872,8 +1881,12 @@ static void *QDECL PlugBI_GetEngineInterface(const char *interfacename, size_t s
Plug_FS_Seek,
Plug_FS_GetLength,
FS_FLocateFile,
FS_OpenVFS,
FS_NativePath,
FS_Rename,
FS_Remove,
COM_EnumerateFiles,
wildcmp,
@ -1882,6 +1895,50 @@ static void *QDECL PlugBI_GetEngineInterface(const char *interfacename, size_t s
COM_CleanUpPath,
Com_BlockChecksum,
FS_LoadMallocFile,
FS_GetPackHashes,
FS_GetPackNames,
FS_GenCachedPakName,
#ifdef HAVE_CLIENT
FS_PureMode,
#endif
#ifdef Q3CLIENT
FSQ3_GenerateClientPacksList,
#endif
};
if (structsize == sizeof(funcs))
return &funcs;
}
if (!strcmp(interfacename, plugmsgfuncs_name))
{
static plugmsgfuncs_t funcs =
{
MSG_BeginReading,
MSG_GetReadCount,
MSG_ReadBits,
MSG_ReadByte,
MSG_ReadShort,
MSG_ReadLong,
MSG_ReadData,
MSG_ReadString,
MSG_BeginWriting,
MSG_WriteBits,
MSG_WriteByte,
MSG_WriteShort,
MSG_WriteLong,
SZ_Write,
MSG_WriteString,
NET_CompareAdr,
NET_CompareBaseAdr,
NET_AdrToString,
NET_StringToAdr2,
NET_SendPacket,
Huff_CompressionCRC,
Huff_EncryptPacket,
Huff_DecryptPacket,
};
if (structsize == sizeof(funcs))
return &funcs;
@ -1915,16 +1972,44 @@ static void *QDECL PlugBI_GetEngineInterface(const char *interfacename, size_t s
if (structsize == sizeof(funcs))
return &funcs;
}
if (!strcmp(interfacename, plugworldfuncs_name))
{
static plugworldfuncs_t funcs =
{
Mod_ForName,
Mod_FixName,
Mod_GetEntitiesString,
World_TransformedTrace,
CM_TempBoxModel,
InfoBuf_ToString,
InfoBuf_FromString,
InfoBuf_SetKey,
InfoBuf_ValueForKey,
Info_ValueForKey,
Info_SetValueForKey,
SV_DropClient,
SV_ExtractFromUserinfo,
SV_ChallengePasses,
};
if (structsize == sizeof(funcs))
return &funcs;
}
#ifdef HAVE_CLIENT
if (!strcmp(interfacename, plug2dfuncs_name))
{
static plug2dfuncs_t funcs =
{
Plug_Draw_GetScreenSize,
Plug_Draw_LoadImageData,
Plug_Draw_LoadImageShader,
Plug_Draw_LoadImagePic,
Plug_Draw_UnloadImage,
Plug_Draw_ShaderFromId,
NULL,//Plug_Draw_UnloadImage,
Plug_Draw_Image,
Plug_Draw_Image2dQuad,
Plug_Draw_ImageSize,
Plug_Draw_Fill,
Plug_Draw_Line,
@ -1936,11 +2021,41 @@ static void *QDECL PlugBI_GetEngineInterface(const char *interfacename, size_t s
Plug_Draw_ColourP,
Plug_Draw_Colour4f,
Plug_Draw_RedrawScreen,
Plug_LocalSound,
};
if (structsize == sizeof(funcs))
return &funcs;
}
if (!strcmp(interfacename, plug3dfuncs_name))
{
static plug3dfuncs_t funcs =
{
Mod_ForName,
Plug_Scene_ModelToId,
Plug_Scene_ModelFromId,
R_RemapShader,
Plug_Scene_ShaderForSkin,
Mod_RegisterSkinFile,
Mod_LookupSkin,
Mod_TagNumForName,
Mod_GetTag,
Mod_ClipDecal,
Surf_NewMap,
Plug_Scene_Clear,
V_AddAxisEntity,
Plug_Scene_AddPolydata,
CL_NewDlight,
CL_AllocDlightOrg,
R_CalcModelLighting,
Plug_Scene_RenderScene,
};
if (structsize == sizeof(funcs))
return &funcs;
}
if (!strcmp(interfacename, plugclientfuncs_name))
{
static plugclientfuncs_t funcs =
@ -1969,6 +2084,9 @@ static void *QDECL PlugBI_GetEngineInterface(const char *interfacename, size_t s
NULL,
NULL,
#endif
Plug_CL_ClearState,
Plug_CL_UpdateGameTime,
};
if (structsize == sizeof(funcs))
return &funcs;
@ -1980,6 +2098,9 @@ static void *QDECL PlugBI_GetEngineInterface(const char *interfacename, size_t s
Plug_SetMenuFocus,
Plug_HasMenuFocus,
Menu_Push,
Menu_Unlink,
//for menu input
Plug_Key_GetKeyCode,
Plug_Key_GetKeyName,
@ -1987,12 +2108,18 @@ static void *QDECL PlugBI_GetEngineInterface(const char *interfacename, size_t s
Plug_Key_GetKeyBind,
Plug_Key_SetKeyBind,
Plug_Input_IsKeyDown,
Plug_Input_ClearKeyStates,
Plug_Input_GetMoveCount,
Plug_Input_GetMoveEntry,
IN_GetKeyDest,
IN_KeyEvent,
IN_MouseMove,
IN_JoystickAxisEvent,
IN_Accelerometer,
IN_Gyroscope,
IN_SetHandPosition,
};
if (structsize == sizeof(funcs))
@ -2023,6 +2150,35 @@ static void *QDECL PlugBI_GetEngineInterface(const char *interfacename, size_t s
{
Plug_LocalSound,
Plug_S_RawAudio,
S_Spacialize,
S_UpdateReverb,
Plug_S_PrecacheSound,
S_StartSound,
S_GetChannelLevel,
S_Voip_ClientLoudness,
Media_NamedTrack
};
if (structsize == sizeof(funcs))
return &funcs;
}
if (!strcmp(interfacename, plugmasterfuncs_name))
{
static plugmasterfuncs_t funcs =
{
NET_StringToAdr2,
NET_AdrToString,
Master_InfoForServer,
CL_QueryServers,
Master_QueryServer,
Master_CheckPollSockets,
Master_TotalCount,
Master_InfoForNum,
Master_ReadKeyString,
Master_ReadKeyFloat,
MasterInfo_WriteServers,
Master_ServerToString,
};
if (structsize == sizeof(funcs))
return &funcs;
@ -2082,6 +2238,21 @@ static void *QDECL PlugBI_GetEngineInterface(const char *interfacename, size_t s
return &funcs;
}
#endif
#ifdef VM_ANY
if (!strcmp(interfacename, plugq3vmfuncs_name))
{
static plugq3vmfuncs_t funcs =
{
VM_Create,
VM_NonNative,
VM_MemoryBase,
VM_Call,
VM_Destroy,
};
if (structsize == sizeof(funcs))
return &funcs;
}
#endif
#ifdef SKELETALMODELS
if (!strcmp(interfacename, plugmodfuncs_name))
{

View File

@ -1434,7 +1434,7 @@ void QCBUILTIN PF_setattachment(pubprogfuncs_t *prinst, struct globalvars_s *pr_
{
if (model && model->loadstate == MLS_LOADING)
COM_WorkerPartialSync(model, &model->loadstate, MLS_LOADING);
tagidx = Mod_TagNumForName(model, tagname);
tagidx = Mod_TagNumForName(model, tagname, 0);
if (tagidx == 0)
Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", NUM_FOR_EDICT(prinst, e), NUM_FOR_EDICT(prinst, tagentity), tagname, tagname, NUM_FOR_EDICT(prinst, tagentity), model->name);
}

View File

@ -1457,7 +1457,8 @@ typedef struct q1usercmd_s
#define RDF_RENDERSCALE (1u<<21)
#define RDF_SCENEGAMMA (1u<<22)
#define RDF_DISABLEPARTICLES (1u<<23) //mostly for skyrooms
#define RDF_SKIPSKY (1u<<24) //we have a skyroom, skip drawing sky chains for this scene.
#define RDF_SKIPSKY (1u<<24) //we drew a skyroom, skip drawing sky chains for this scene.
#define RDF_SKYROOMENABLED (1u<<25) //skyroom position is known, be prepared to draw the skyroom if its visible.
#define RDF_ALLPOSTPROC (RDF_BLOOM|RDF_FISHEYE|RDF_WATERWARP|RDF_CUSTOMPOSTPROC|RDF_ANTIALIAS|RDF_SCENEGAMMA) //these flags require rendering to an fbo for the various different post-processing shaders.
@ -1766,6 +1767,8 @@ typedef struct q1usercmd_s
#define MLS_POWERMODE 2
#define MLS_TORCH 3
#define MLS_TOTALDARK 4
#define MLS_UNUSED 4
#define MLS_ADDLIGHT 6
#define MLS_ABSLIGHT (MLS_MASK)
#define SCALE_TYPE_MASK (SCALE_TYPE_UNIFORM|SCALE_TYPE_XYONLY|SCALE_TYPE_ZONLY)
#define SCALE_TYPE_UNIFORM 0 // Scale X, Y, and Z

57
engine/common/q3api.h Normal file
View File

@ -0,0 +1,57 @@
#if defined(Q3CLIENT) || defined(Q3SERVER)
struct sfx_s;
struct server_static_s;
struct server_s;
struct usercmd_s;
struct q3gamecode_s
{
struct
{
void (*SendAuthPacket)(struct ftenet_connections_s *socket, netadr_t *gameserver);
void (*SendConnectPacket)(struct ftenet_connections_s *socket, netadr_t *to, int challenge, int qport, infobuf_t *userinfo);
void (*Established)(void);
void (*VARGS SendClientCommand)(const char *fmt, ...) LIKEPRINTF(1);
void (*SendCmd)(struct ftenet_connections_s *socket, struct usercmd_s *cmd, unsigned int movesequence, double gametime);
int (*ParseServerMessage) (sizebuf_t *msg);
void (*Disconnect) (struct ftenet_connections_s *socket); //disconnects from the server, killing all connection+cgame state.
} cl;
struct
{
void (*VideoRestarted) (void);
int (*Redraw) (double time);
qboolean (*ConsoleCommand) (void);
qboolean (*KeyPressed) (int key, int unicode, int down);
unsigned int (*GatherLoopingSounds) (vec3_t *positions, unsigned int *entnums, struct sfx_s **sounds, unsigned int max);
} cg;
struct
{
qboolean (*IsRunning)(void);
qboolean (*ConsoleCommand)(void);
void (*Start) (void);
qboolean (*OpenMenu)(void);
void (*Reset)(void);
} ui;
//server stuff
struct
{
void (*ShutdownGame) (qboolean restart);
qboolean (*InitGame) (struct server_static_s *server_state_static, struct server_s *server_state, qboolean restart);
qboolean (*ConsoleCommand) (void);
qboolean (*PrefixedConsoleCommand) (void);
qboolean (*HandleClient) (netadr_t *from, sizebuf_t *msg);
void (*DirectConnect) (netadr_t *from, sizebuf_t *msg);
void (*NewMapConnects) (void);
void (*DropClient) (struct client_s *cl);
void (*RunFrame) (void);
void (*SendMessage) (struct client_s *client);
qboolean (*RestartGamecode) (void);
void (*ServerinfoChanged) (const char *key);
} sv;
};
extern struct q3gamecode_s *q3;
#endif

File diff suppressed because it is too large Load Diff

67
engine/common/q3common.h Normal file
View File

@ -0,0 +1,67 @@
#include "../plugins/plugin.h"
#include "clq3defs.h"
//#define Q3_NOENCRYPT //a debugging property, makes it incompatible with q3
extern plug2dfuncs_t *drawfuncs;
extern plug3dfuncs_t *scenefuncs;
extern pluginputfuncs_t *inputfuncs;
extern plugaudiofuncs_t *audiofuncs;
extern plugmasterfuncs_t*masterfuncs;
extern plugclientfuncs_t*clientfuncs;
extern plugq3vmfuncs_t *vmfuncs;
extern plugfsfuncs_t *fsfuncs;
extern plugmsgfuncs_t *msgfuncs;
extern plugworldfuncs_t *worldfuncs;
extern cvar_t *sv_maxclients;
extern cvar_t *cl_shownet_ptr, *cl_c2sdupe_ptr, *cl_nodelta_ptr;
#define Q_snprintfz Q_snprintf
#define Sys_Error plugfuncs->Error
#define Z_Malloc plugfuncs->Malloc
#define Z_Free plugfuncs->Free
typedef struct //merge?
{
int flags;
int areabytes;
qbyte areabits[MAX_Q2MAP_AREAS/8]; // portalarea visibility bits
q3playerState_t ps;
int num_entities;
int first_entity; // into the circular sv_packet_entities[]
int senttime; // for ping calculations
int serverMessageNum;
int serverCommandNum;
int serverTime; // server time the message is valid for (in msec)
int localTime;
int deltaFrame;
} q3client_frame_t;
typedef struct
{
world_t *world;
model_t *models[1u<<MODELINDEX_BITS];
qboolean restarting;
float restartedtime;
vec2_t gridbias;
vec2_t gridscale;
size_t gridsize[2];
areagridlink_t *gridareas; //[gridsize[0]*gridsize[1]]
areagridlink_t jumboarea; //node containing ents too large to fit.
int areagridsequence;
server_static_t *server_state_static;
server_t *server_state;
} q3serverstate_t;
extern q3serverstate_t sv3;
#undef CALCAREAGRIDBOUNDS

View File

@ -37,25 +37,6 @@ char *VMQ3_StringFromHandle(int handle);
int VMQ3_StringToHandle(char *str);
void VMQ3_FlushStringHandles(void);
#ifdef VM_UI
qboolean UI_IsRunning(void);
qboolean UI_Command(void);
void UI_Init (void);
void UI_Start (void);
void UI_Stop (void);
qboolean UI_OpenMenu(void);
void UI_Restart_f(void);
int UI_IsFullscreen(void);
void UI_Reset(void);
//sans botlib
struct pc_token_s;
int Script_LoadFile(char *filename);
void Script_Free(int handle);
int Script_Read(int handle, struct pc_token_s *token);
void Script_Get_File_And_Line(int handle, char *filename, int *line);
#endif
#define VM_FS_READ 0
#define VM_FS_WRITE 1
#define VM_FS_APPEND 2
@ -69,16 +50,6 @@ void VM_fclose (int fnum, int owner);
void VM_fcloseall (int owner);
int VM_GetFileList(const char *path, const char *ext, char *output, int buffersize);
#ifdef VM_CG
void CG_Stop (void);
void CG_Start (void);
qboolean CG_VideoRestarted(void);
int CG_Refresh(void);
qboolean CG_Command(void);
qboolean CG_KeyPress(int key, int unicode, int down);
unsigned int CG_GatherLoopingSounds(vec3_t *positions, unsigned int *entnums, sfx_t **sounds, unsigned int max);
#endif
typedef struct {
int handle;
int modificationCount;

View File

@ -85,6 +85,7 @@ void Mod_WipeSkin(skinid_t id, qboolean force)
return;
if (!force && --sk->refcount > 0)
return; //still in use.
registeredskins[id] = NULL;
for (i = 0; i < sk->nummappings; i++)
{
@ -95,8 +96,7 @@ void Mod_WipeSkin(skinid_t id, qboolean force)
}
R_UnloadShader(sk->mappings[i].shader);
}
Z_Free(registeredskins[id]);
registeredskins[id] = NULL;
Z_Free(sk);
}
static void Mod_WipeAllSkins(qboolean final)
{
@ -275,6 +275,7 @@ skinid_t Mod_ReadSkinFile(const char *skinname, const char *skintext)
skin->q1upper = Q1UNSPECIFIED;
#endif
while(skintext)
{
if (skin->nummappings == skin->maxmappings)
@ -414,6 +415,7 @@ skinid_t Mod_ReadSkinFile(const char *skinname, const char *skintext)
if (!*skintext)
break;
}
registeredskins[id] = skin;
#ifdef QWSKINS
@ -1383,7 +1385,7 @@ qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel)
return e->light_known-1;
}
if (!(r_refdef.flags & RDF_NOWORLDMODEL))
if (!(r_refdef.flags & RDF_NOWORLDMODEL) && cl.worldmodel)
{
if (e->flags & RF_WEAPONMODEL)
{
@ -1479,6 +1481,17 @@ qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel)
}
else
{
#ifdef HEXEN2
if ((e->drawflags & MLS_MASK) == MLS_ADDLIGHT)
{
ambientlight[0] += e->abslight;
ambientlight[1] += e->abslight;
ambientlight[2] += e->abslight;
shadelight[0] += e->abslight;
shadelight[1] += e->abslight;
shadelight[2] += e->abslight;
}
#endif
if (!r_vertexdlights.ival && r_dynamic.ival > 0)
{
float *org = e->origin;

View File

@ -1548,18 +1548,18 @@ void GLBE_Init(void)
shaderstate.curentity = &r_worldentity;
be_maxpasses = gl_config_nofixedfunc?1:gl_mtexarbable;
be_maxpasses = min(SHADER_TMU_MAX, min(be_maxpasses, 32-VATTR_LEG_TMU0));
gl_stencilbits = 0;
sh_config.stencilbits = 0;
#ifndef GLESONLY
if (!gl_config_gles && gl_config.glversion >= 3.0 && gl_config_nofixedfunc)
{
//docs say this line should be okay in gl3+. nvidia do not seem to agree. GL_STENCIL_BITS is depricated however. so for now, just assume.
qglGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER_EXT, GL_STENCIL, GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &gl_stencilbits);
qglGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER_EXT, GL_STENCIL, GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &sh_config.stencilbits);
if (qglGetError())
gl_stencilbits = 8;
sh_config.stencilbits = 8;
}
else
#endif
qglGetIntegerv(GL_STENCIL_BITS, &gl_stencilbits);
qglGetIntegerv(GL_STENCIL_BITS, &sh_config.stencilbits);
for (i = 0; i < FTABLE_SIZE; i++)
{
t = (double)i / (double)FTABLE_SIZE;

View File

@ -1056,6 +1056,7 @@ void Mod_ModelLoaded(void *ctx, void *data, size_t a, size_t b)
Con_Printf(CON_ERROR "Unable to load %s\n", mod->name);
break;
case MLV_SILENT:
case MLV_SILENTSYNC:
break;
}
}
@ -1369,18 +1370,16 @@ model_t *Mod_LoadModel (model_t *mod, enum mlverbosity_e verbose)
COM_InsertWork(WG_LOADER, Mod_LoadModelWorker, mod, NULL, verbose, 0);
else
COM_AddWork(WG_LOADER, Mod_LoadModelWorker, mod, NULL, verbose, 0);
//block until its loaded, if we care.
if (verbose == MLV_ERROR || verbose == MLV_WARNSYNC)
COM_WorkerPartialSync(mod, &mod->loadstate, MLS_LOADING);
}
//block until its loaded, if we care.
if (mod->loadstate == MLS_LOADING && (verbose == MLV_ERROR || verbose == MLV_WARNSYNC || verbose == MLV_SILENTSYNC))
COM_WorkerPartialSync(mod, &mod->loadstate, MLS_LOADING);
if (verbose == MLV_ERROR)
{
//someone already tried to load it without caring if it failed or not. make sure its loaded.
//fixme: this is a spinloop.
if (mod->loadstate == MLS_LOADING)
COM_WorkerPartialSync(mod, &mod->loadstate, MLS_LOADING);
if (mod->loadstate != MLS_LOADED)
Host_EndGame ("Mod_NumForName: %s not found or couldn't load", mod->name);

View File

@ -448,10 +448,6 @@ void R_RenderDlights (void)
switch(method)
{
case 2:
if (TraceLineR(r_refdef.vieworg, l->origin, waste1, waste2))
continue;
break;
case 0:
break;
case 3:
@ -534,8 +530,9 @@ void R_RenderDlights (void)
#endif
//other renderers fall through
default:
case 1:
if (CL_TraceLine(r_refdef.vieworg, l->origin, waste1, NULL, NULL) < 1)
case 1: //bsp-only
case 2: //non-bsp too
if (TraceLineR(r_refdef.vieworg, l->origin, waste1, waste2, method!=2))
continue;
break;
}

View File

@ -608,7 +608,7 @@ static void R_SetupGL (vec3_t eyeangorg[2], vec4_t fovoverrides, float projmatri
if (r_refdef.useperspective)
{
float maxdist = r_refdef.maxdist;
if (gl_stencilbits && Sh_StencilShadowsActive())
if (sh_config.stencilbits && Sh_StencilShadowsActive())
maxdist = 0; //if we're using stencil shadows then force the maxdist to infinite to ensure the shadow volume is sealed.
Matrix4x4_CM_Projection_Offset(r_refdef.m_projection_std, fov_l, fov_r, fov_d, fov_u, r_refdef.mindist, maxdist, false);
Matrix4x4_CM_Projection_Offset(r_refdef.m_projection_view, -fovv_x/2, fovv_x/2, -fovv_y/2, fovv_y/2, r_refdef.mindist, maxdist, false);

View File

@ -175,7 +175,7 @@ qboolean GLSCR_UpdateScreen (void)
if (topmenu && topmenu->isopaque)
nohud = true;
#ifdef VM_CG
else if (CG_Refresh())
else if (q3 && q3->cg.Redraw(cl.time))
nohud = true;
#endif
#ifdef CSQC_DAT

View File

@ -700,8 +700,8 @@ qboolean Shader_ParseSkySides (char *shadername, char *texturename, texid_t *ima
}
if (!images[i]->width)
{
Con_Printf("Sky \"%s\" missing texture: %s\n", shadername, path);
images[i] = missing_texture;
Con_DPrintf("Sky \"%s\" missing texture: %s\n", shadername, path);
images[i] = r_blackimage;
allokay = false;
}
}

View File

@ -3424,7 +3424,7 @@ static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, vec3_t axis[3],
sfrontfail = GL_DECR_WRAP_EXT;
}
#else
sref = (1<<gl_stencilbits)-1; /*this is halved for two-sided stencil support, just in case there's no wrap support*/
sref = (1<<sh_config.stencilbits)-1; /*this is halved for two-sided stencil support, just in case there's no wrap support*/
sbackfail = GL_DECR;
sfrontfail = GL_INCR;
if (gl_config.ext_stencil_wrap)
@ -3935,7 +3935,7 @@ void Sh_CheckSettings(void)
else if (!gl_config.arb_depth_texture)
Con_DPrintf("Shadowmapping unsupported: No arb_depth_texture\n");
}
if (gl_stencilbits)
if (sh_config.stencilbits)
canstencil = true;
break;
#endif

View File

@ -392,7 +392,6 @@ extern qboolean gammaworks; //if the gl drivers can set proper gamma.
gl_config_t gl_config;
int gl_stencilbits;
float gldepthmin, gldepthmax;
const char *gl_vendor;

View File

@ -846,6 +846,7 @@ typedef struct
qboolean can_mipbias; //gl1.4+
qboolean can_genmips; //gl3.0+
qboolean havecubemaps; //since gl1.3, so pretty much everyone will have this... should probably only be set if we also have seamless or clamp-to-edge.
unsigned int stencilbits;
void (*pDeleteProg) (program_t *prog);
qboolean (*pLoadBlob) (program_t *prog, unsigned int permu, vfsfile_t *blobfile);

View File

@ -1,519 +1 @@
/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
This file is part of Quake III Arena source code.
Quake III Arena source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Quake III Arena source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Foobar; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
//
/*****************************************************************************
* name: botlib.h
*
* desc: bot AI library
*
* $Archive: /source/code/game/botai.h $
*
*****************************************************************************/
#define BOTLIB_API_VERSION 2
struct aas_clientmove_s;
struct aas_entityinfo_s;
struct aas_areainfo_s;
struct aas_altroutegoal_s;
struct aas_predictroute_s;
struct bot_consolemessage_s;
struct bot_match_s;
struct bot_goal_s;
struct bot_moveresult_s;
struct bot_initmove_s;
struct weaponinfo_s;
#define BOTFILESBASEFOLDER "botfiles"
//debug line colors
#define LINECOLOR_NONE -1
#define LINECOLOR_RED 1//0xf2f2f0f0L
#define LINECOLOR_GREEN 2//0xd0d1d2d3L
#define LINECOLOR_BLUE 3//0xf3f3f1f1L
#define LINECOLOR_YELLOW 4//0xdcdddedfL
#define LINECOLOR_ORANGE 5//0xe0e1e2e3L
//Print types
#define PRT_MESSAGE 1
#define PRT_WARNING 2
#define PRT_ERROR 3
#define PRT_FATAL 4
#define PRT_EXIT 5
//console message types
#define CMS_NORMAL 0
#define CMS_CHAT 1
//botlib error codes
#define BLERR_NOERROR 0 //no error
#define BLERR_LIBRARYNOTSETUP 1 //library not setup
#define BLERR_INVALIDENTITYNUMBER 2 //invalid entity number
#define BLERR_NOAASFILE 3 //no AAS file available
#define BLERR_CANNOTOPENAASFILE 4 //cannot open AAS file
#define BLERR_WRONGAASFILEID 5 //incorrect AAS file id
#define BLERR_WRONGAASFILEVERSION 6 //incorrect AAS file version
#define BLERR_CANNOTREADAASLUMP 7 //cannot read AAS file lump
#define BLERR_CANNOTLOADICHAT 8 //cannot load initial chats
#define BLERR_CANNOTLOADITEMWEIGHTS 9 //cannot load item weights
#define BLERR_CANNOTLOADITEMCONFIG 10 //cannot load item config
#define BLERR_CANNOTLOADWEAPONWEIGHTS 11 //cannot load weapon weights
#define BLERR_CANNOTLOADWEAPONCONFIG 12 //cannot load weapon config
//action flags
#define ACTION_ATTACK 0x0000001
#define ACTION_USE 0x0000002
#define ACTION_RESPAWN 0x0000008
#define ACTION_JUMP 0x0000010
#define ACTION_MOVEUP 0x0000020
#define ACTION_CROUCH 0x0000080
#define ACTION_MOVEDOWN 0x0000100
#define ACTION_MOVEFORWARD 0x0000200
#define ACTION_MOVEBACK 0x0000800
#define ACTION_MOVELEFT 0x0001000
#define ACTION_MOVERIGHT 0x0002000
#define ACTION_DELAYEDJUMP 0x0008000
#define ACTION_TALK 0x0010000
#define ACTION_GESTURE 0x0020000
#define ACTION_WALK 0x0080000
#define ACTION_AFFIRMATIVE 0x0100000
#define ACTION_NEGATIVE 0x0200000
#define ACTION_GETFLAG 0x0800000
#define ACTION_GUARDBASE 0x1000000
#define ACTION_PATROL 0x2000000
#define ACTION_FOLLOWME 0x8000000
//the bot input, will be converted to an usercmd_t
typedef struct bot_input_s
{
float thinktime; //time since last output (in seconds)
vec3_t dir; //movement direction
float speed; //speed in the range [0, 400]
vec3_t viewangles; //the view angles
int actionflags; //one of the ACTION_? flags
int weapon; //weapon to use
} bot_input_t;
#ifndef BSPTRACE
#define BSPTRACE
//bsp_trace_t hit surface
typedef struct bsp_surface_s
{
char name[16];
int flags;
int value;
} bsp_surface_t;
//remove the bsp_trace_s structure definition l8r on
//a trace is returned when a box is swept through the world
typedef struct bsp_trace_s
{
qboolean allsolid; // if true, plane is not valid
qboolean startsolid; // if true, the initial point was in a solid area
float fraction; // time completed, 1.0 = didn't hit anything
vec3_t endpos; // final position
cplane_t plane; // surface normal at impact
float exp_dist; // expanded plane distance
int sidenum; // number of the brush side hit
bsp_surface_t surface; // the hit point surface
int contents; // contents on other side of surface hit
int ent; // number of entity hit
} bsp_trace_t;
#endif // BSPTRACE
//entity state
typedef struct bot_entitystate_s
{
int type; // entity type
int flags; // entity flags
vec3_t origin; // origin of the entity
vec3_t angles; // angles of the model
vec3_t old_origin; // for lerping
vec3_t mins; // bounding box minimums
vec3_t maxs; // bounding box maximums
int groundent; // ground entity
int solid; // solid type
int modelindex; // model used
int modelindex2; // weapons, CTF flags, etc
int frame; // model frame number
int event; // impulse events -- muzzle flashes, footsteps, etc
int eventParm; // even parameter
int powerups; // bit flags
int weapon; // determines weapon and flash model, etc
int legsAnim; // mask off ANIM_TOGGLEBIT
int torsoAnim; // mask off ANIM_TOGGLEBIT
} bot_entitystate_t;
//bot AI library exported functions
typedef struct botlib_import_s
{
//print messages from the bot library
void (QDECL *Print)(int type, char *fmt, ...);
//trace a bbox through the world
void (QDECL *Trace)(bsp_trace_t *trace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask);
//trace a bbox against a specific entity
void (QDECL *EntityTrace)(bsp_trace_t *trace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int entnum, int contentmask);
//retrieve the contents at the given point
int (QDECL *PointContents)(vec3_t point);
//check if the point is in potential visible sight
int (QDECL *inPVS)(vec3_t p1, vec3_t p2);
//retrieve the BSP entity data lump
const char *(QDECL *BSPEntityData)(void);
//
void (QDECL *BSPModelMinsMaxsOrigin)(int modelnum, vec3_t angles, vec3_t mins, vec3_t maxs, vec3_t origin);
//send a bot client command
void (QDECL *BotClientCommand)(int client, char *command);
//memory allocation
void *(QDECL *GetMemory)(int size); // allocate from Zone
void (QDECL *FreeMemory)(void *ptr); // free memory from Zone
int (QDECL *AvailableMemory)(void); // available Zone memory
void *(QDECL *HunkAlloc)(int size); // allocate from hunk
//file system access
int (QDECL *FS_FOpenFile)( const char *qpath, fileHandle_t *file, fsMode_t mode );
int (QDECL *FS_Read)( void *buffer, int len, fileHandle_t f );
int (QDECL *FS_Write)( const void *buffer, int len, fileHandle_t f );
void (QDECL *FS_FCloseFile)( fileHandle_t f );
int (QDECL *FS_Seek)( fileHandle_t f, long offset, int origin );
//debug visualisation stuff
int (QDECL *DebugLineCreate)(void);
void (QDECL *DebugLineDelete)(int line);
void (QDECL *DebugLineShow)(int line, vec3_t start, vec3_t end, int color);
//
int (QDECL *DebugPolygonCreate)(int color, int numPoints, vec3_t *points);
void (QDECL *DebugPolygonDelete)(int id);
//FTE additions...
void (QDECL *Error)(const char *error);
} botlib_import_t;
typedef struct aas_export_s
{
//-----------------------------------
// be_aas_entity.h
//-----------------------------------
void (QDECL *AAS_EntityInfo)(int entnum, struct aas_entityinfo_s *info);
//-----------------------------------
// be_aas_main.h
//-----------------------------------
int (QDECL *AAS_Initialized)(void);
void (QDECL *AAS_PresenceTypeBoundingBox)(int presencetype, vec3_t mins, vec3_t maxs);
float (QDECL *AAS_Time)(void);
//--------------------------------------------
// be_aas_sample.c
//--------------------------------------------
int (QDECL *AAS_PointAreaNum)(vec3_t point);
int (QDECL *AAS_PointReachabilityAreaIndex)( vec3_t point );
int (QDECL *AAS_TraceAreas)(vec3_t start, vec3_t end, int *areas, vec3_t *points, int maxareas);
int (QDECL *AAS_BBoxAreas)(vec3_t absmins, vec3_t absmaxs, int *areas, int maxareas);
int (QDECL *AAS_AreaInfo)( int areanum, struct aas_areainfo_s *info );
//--------------------------------------------
// be_aas_bspq3.c
//--------------------------------------------
int (QDECL *AAS_PointContents)(vec3_t point);
int (QDECL *AAS_NextBSPEntity)(int ent);
int (QDECL *AAS_ValueForBSPEpairKey)(int ent, char *key, char *value, int size);
int (QDECL *AAS_VectorForBSPEpairKey)(int ent, char *key, vec3_t v);
int (QDECL *AAS_FloatForBSPEpairKey)(int ent, char *key, float *value);
int (QDECL *AAS_IntForBSPEpairKey)(int ent, char *key, int *value);
//--------------------------------------------
// be_aas_reach.c
//--------------------------------------------
int (QDECL *AAS_AreaReachability)(int areanum);
//--------------------------------------------
// be_aas_route.c
//--------------------------------------------
int (QDECL *AAS_AreaTravelTimeToGoalArea)(int areanum, vec3_t origin, int goalareanum, int travelflags);
int (QDECL *AAS_EnableRoutingArea)(int areanum, int enable);
int (QDECL *AAS_PredictRoute)(struct aas_predictroute_s *route, int areanum, vec3_t origin,
int goalareanum, int travelflags, int maxareas, int maxtime,
int stopevent, int stopcontents, int stoptfl, int stopareanum);
//--------------------------------------------
// be_aas_altroute.c
//--------------------------------------------
int (QDECL *AAS_AlternativeRouteGoals)(vec3_t start, int startareanum, vec3_t goal, int goalareanum, int travelflags,
struct aas_altroutegoal_s *altroutegoals, int maxaltroutegoals,
int type);
//--------------------------------------------
// be_aas_move.c
//--------------------------------------------
int (QDECL *AAS_Swimming)(vec3_t origin);
int (QDECL *AAS_PredictClientMovement)(struct aas_clientmove_s *move,
int entnum, vec3_t origin,
int presencetype, int onground,
vec3_t velocity, vec3_t cmdmove,
int cmdframes,
int maxframes, float frametime,
int stopevent, int stopareanum, int visualize);
} aas_export_t;
typedef struct ea_export_s
{
//ClientCommand elementary actions
void (QDECL *EA_Command)(int client, char *command );
void (QDECL *EA_Say)(int client, char *str);
void (QDECL *EA_SayTeam)(int client, char *str);
//
void (QDECL *EA_Action)(int client, int action);
void (QDECL *EA_Gesture)(int client);
void (QDECL *EA_Talk)(int client);
void (QDECL *EA_Attack)(int client);
void (QDECL *EA_Use)(int client);
void (QDECL *EA_Respawn)(int client);
void (QDECL *EA_MoveUp)(int client);
void (QDECL *EA_MoveDown)(int client);
void (QDECL *EA_MoveForward)(int client);
void (QDECL *EA_MoveBack)(int client);
void (QDECL *EA_MoveLeft)(int client);
void (QDECL *EA_MoveRight)(int client);
void (QDECL *EA_Crouch)(int client);
void (QDECL *EA_SelectWeapon)(int client, int weapon);
void (QDECL *EA_Jump)(int client);
void (QDECL *EA_DelayedJump)(int client);
void (QDECL *EA_Move)(int client, vec3_t dir, float speed);
void (QDECL *EA_View)(int client, vec3_t viewangles);
//send regular input to the server
void (QDECL *EA_EndRegular)(int client, float thinktime);
void (QDECL *EA_GetInput)(int client, float thinktime, bot_input_t *input);
void (QDECL *EA_ResetInput)(int client);
} ea_export_t;
typedef struct ai_export_s
{
//-----------------------------------
// be_ai_char.h
//-----------------------------------
int (QDECL *BotLoadCharacter)(char *charfile, float skill);
void (QDECL *BotFreeCharacter)(int character);
float (QDECL *Characteristic_Float)(int character, int index);
float (QDECL *Characteristic_BFloat)(int character, int index, float min, float max);
int (QDECL *Characteristic_Integer)(int character, int index);
int (QDECL *Characteristic_BInteger)(int character, int index, int min, int max);
void (QDECL *Characteristic_String)(int character, int index, char *buf, int size);
//-----------------------------------
// be_ai_chat.h
//-----------------------------------
int (QDECL *BotAllocChatState)(void);
void (QDECL *BotFreeChatState)(int handle);
void (QDECL *BotQueueConsoleMessage)(int chatstate, int type, char *message);
void (QDECL *BotRemoveConsoleMessage)(int chatstate, int handle);
int (QDECL *BotNextConsoleMessage)(int chatstate, struct bot_consolemessage_s *cm);
int (QDECL *BotNumConsoleMessages)(int chatstate);
void (QDECL *BotInitialChat)(int chatstate, char *type, int mcontext, char *var0, char *var1, char *var2, char *var3, char *var4, char *var5, char *var6, char *var7);
int (QDECL *BotNumInitialChats)(int chatstate, char *type);
int (QDECL *BotReplyChat)(int chatstate, char *message, int mcontext, int vcontext, char *var0, char *var1, char *var2, char *var3, char *var4, char *var5, char *var6, char *var7);
int (QDECL *BotChatLength)(int chatstate);
void (QDECL *BotEnterChat)(int chatstate, int client, int sendto);
void (QDECL *BotGetChatMessage)(int chatstate, char *buf, int size);
int (QDECL *StringContains)(char *str1, char *str2, int casesensitive);
int (QDECL *BotFindMatch)(char *str, struct bot_match_s *match, unsigned long int context);
void (QDECL *BotMatchVariable)(struct bot_match_s *match, int variable, char *buf, int size);
void (QDECL *UnifyWhiteSpaces)(char *string);
void (QDECL *BotReplaceSynonyms)(char *string, unsigned long int context);
int (QDECL *BotLoadChatFile)(int chatstate, char *chatfile, char *chatname);
void (QDECL *BotSetChatGender)(int chatstate, int gender);
void (QDECL *BotSetChatName)(int chatstate, char *name, int client);
//-----------------------------------
// be_ai_goal.h
//-----------------------------------
void (QDECL *BotResetGoalState)(int goalstate);
void (QDECL *BotResetAvoidGoals)(int goalstate);
void (QDECL *BotRemoveFromAvoidGoals)(int goalstate, int number);
void (QDECL *BotPushGoal)(int goalstate, struct bot_goal_s *goal);
void (QDECL *BotPopGoal)(int goalstate);
void (QDECL *BotEmptyGoalStack)(int goalstate);
void (QDECL *BotDumpAvoidGoals)(int goalstate);
void (QDECL *BotDumpGoalStack)(int goalstate);
void (QDECL *BotGoalName)(int number, char *name, int size);
int (QDECL *BotGetTopGoal)(int goalstate, struct bot_goal_s *goal);
int (QDECL *BotGetSecondGoal)(int goalstate, struct bot_goal_s *goal);
int (QDECL *BotChooseLTGItem)(int goalstate, vec3_t origin, int *inventory, int travelflags);
int (QDECL *BotChooseNBGItem)(int goalstate, vec3_t origin, int *inventory, int travelflags,
struct bot_goal_s *ltg, float maxtime);
int (QDECL *BotTouchingGoal)(vec3_t origin, struct bot_goal_s *goal);
int (QDECL *BotItemGoalInVisButNotVisible)(int viewer, vec3_t eye, vec3_t viewangles, struct bot_goal_s *goal);
int (QDECL *BotGetLevelItemGoal)(int index, char *classname, struct bot_goal_s *goal);
int (QDECL *BotGetNextCampSpotGoal)(int num, struct bot_goal_s *goal);
int (QDECL *BotGetMapLocationGoal)(char *name, struct bot_goal_s *goal);
float (QDECL *BotAvoidGoalTime)(int goalstate, int number);
void (QDECL *BotSetAvoidGoalTime)(int goalstate, int number, float avoidtime);
void (QDECL *BotInitLevelItems)(void);
void (QDECL *BotUpdateEntityItems)(void);
int (QDECL *BotLoadItemWeights)(int goalstate, char *filename);
void (QDECL *BotFreeItemWeights)(int goalstate);
void (QDECL *BotInterbreedGoalFuzzyLogic)(int parent1, int parent2, int child);
void (QDECL *BotSaveGoalFuzzyLogic)(int goalstate, char *filename);
void (QDECL *BotMutateGoalFuzzyLogic)(int goalstate, float range);
int (QDECL *BotAllocGoalState)(int client);
void (QDECL *BotFreeGoalState)(int handle);
//-----------------------------------
// be_ai_move.h
//-----------------------------------
void (QDECL *BotResetMoveState)(int movestate);
void (QDECL *BotMoveToGoal)(struct bot_moveresult_s *result, int movestate, struct bot_goal_s *goal, int travelflags);
int (QDECL *BotMoveInDirection)(int movestate, vec3_t dir, float speed, int type);
void (QDECL *BotResetAvoidReach)(int movestate);
void (QDECL *BotResetLastAvoidReach)(int movestate);
int (QDECL *BotReachabilityArea)(vec3_t origin, int testground);
int (QDECL *BotMovementViewTarget)(int movestate, struct bot_goal_s *goal, int travelflags, float lookahead, vec3_t target);
int (QDECL *BotPredictVisiblePosition)(vec3_t origin, int areanum, struct bot_goal_s *goal, int travelflags, vec3_t target);
int (QDECL *BotAllocMoveState)(void);
void (QDECL *BotFreeMoveState)(int handle);
void (QDECL *BotInitMoveState)(int handle, struct bot_initmove_s *initmove);
void (QDECL *BotAddAvoidSpot)(int movestate, vec3_t origin, float radius, int type);
//-----------------------------------
// be_ai_weap.h
//-----------------------------------
int (QDECL *BotChooseBestFightWeapon)(int weaponstate, int *inventory);
void (QDECL *BotGetWeaponInfo)(int weaponstate, int weapon, struct weaponinfo_s *weaponinfo);
int (QDECL *BotLoadWeaponWeights)(int weaponstate, char *filename);
int (QDECL *BotAllocWeaponState)(void);
void (QDECL *BotFreeWeaponState)(int weaponstate);
void (QDECL *BotResetWeaponState)(int weaponstate);
//-----------------------------------
// be_ai_gen.h
//-----------------------------------
int (QDECL *GeneticParentsAndChildSelection)(int numranks, float *ranks, int *parent1, int *parent2, int *child);
} ai_export_t;
//bot AI library imported functions
typedef struct botlib_export_s
{
//Area Awareness System functions
aas_export_t aas;
//Elementary Action functions
ea_export_t ea;
//AI functions
ai_export_t ai;
//setup the bot library, returns BLERR_
int (QDECL *BotLibSetup)(void);
//shutdown the bot library, returns BLERR_
int (QDECL *BotLibShutdown)(void);
//sets a library variable returns BLERR_
int (QDECL *BotLibVarSet)(char *var_name, char *value);
//gets a library variable returns BLERR_
int (QDECL *BotLibVarGet)(char *var_name, char *value, int size);
//sets a C-like define returns BLERR_
int (QDECL *PC_AddGlobalDefine)(char *string);
int (QDECL *PC_LoadSourceHandle)(const char *filename);
int (QDECL *PC_FreeSourceHandle)(int handle);
int (QDECL *PC_ReadTokenHandle)(int handle, pc_token_t *pc_token);
int (QDECL *PC_SourceFileAndLine)(int handle, char *filename, int *line);
//start a frame in the bot library
int (QDECL *BotLibStartFrame)(float time);
//load a new map in the bot library
int (QDECL *BotLibLoadMap)(const char *mapname);
//entity updates
int (QDECL *BotLibUpdateEntity)(int ent, bot_entitystate_t *state);
//just for testing
int (QDECL *Test)(int parm0, char *parm1, vec3_t parm2, vec3_t parm3);
} botlib_export_t;
//linking of bot library
botlib_export_t *QDECL GetBotLibAPI( int apiVersion, botlib_import_t *import );
/* Library variables:
name: default: module(s): description:
"basedir" "" l_utils.c base directory
"gamedir" "" l_utils.c game directory
"cddir" "" l_utils.c CD directory
"log" "0" l_log.c enable/disable creating a log file
"maxclients" "4" be_interface.c maximum number of clients
"maxentities" "1024" be_interface.c maximum number of entities
"bot_developer" "0" be_interface.c bot developer mode
"phys_friction" "6" be_aas_move.c ground friction
"phys_stopspeed" "100" be_aas_move.c stop speed
"phys_gravity" "800" be_aas_move.c gravity value
"phys_waterfriction" "1" be_aas_move.c water friction
"phys_watergravity" "400" be_aas_move.c gravity in water
"phys_maxvelocity" "320" be_aas_move.c maximum velocity
"phys_maxwalkvelocity" "320" be_aas_move.c maximum walk velocity
"phys_maxcrouchvelocity" "100" be_aas_move.c maximum crouch velocity
"phys_maxswimvelocity" "150" be_aas_move.c maximum swim velocity
"phys_walkaccelerate" "10" be_aas_move.c walk acceleration
"phys_airaccelerate" "1" be_aas_move.c air acceleration
"phys_swimaccelerate" "4" be_aas_move.c swim acceleration
"phys_maxstep" "18" be_aas_move.c maximum step height
"phys_maxsteepness" "0.7" be_aas_move.c maximum floor steepness
"phys_maxbarrier" "32" be_aas_move.c maximum barrier height
"phys_maxwaterjump" "19" be_aas_move.c maximum waterjump height
"phys_jumpvel" "270" be_aas_move.c jump z velocity
"phys_falldelta5" "40" be_aas_move.c
"phys_falldelta10" "60" be_aas_move.c
"rs_waterjump" "400" be_aas_move.c
"rs_teleport" "50" be_aas_move.c
"rs_barrierjump" "100" be_aas_move.c
"rs_startcrouch" "300" be_aas_move.c
"rs_startgrapple" "500" be_aas_move.c
"rs_startwalkoffledge" "70" be_aas_move.c
"rs_startjump" "300" be_aas_move.c
"rs_rocketjump" "500" be_aas_move.c
"rs_bfgjump" "500" be_aas_move.c
"rs_jumppad" "250" be_aas_move.c
"rs_aircontrolledjumppad" "300" be_aas_move.c
"rs_funcbob" "300" be_aas_move.c
"rs_startelevator" "50" be_aas_move.c
"rs_falldamage5" "300" be_aas_move.c
"rs_falldamage10" "500" be_aas_move.c
"rs_maxjumpfallheight" "450" be_aas_move.c
"max_aaslinks" "4096" be_aas_sample.c maximum links in the AAS
"max_routingcache" "4096" be_aas_route.c maximum routing cache size in KB
"forceclustering" "0" be_aas_main.c force recalculation of clusters
"forcereachability" "0" be_aas_main.c force recalculation of reachabilities
"forcewrite" "0" be_aas_main.c force writing of aas file
"aasoptimize" "0" be_aas_main.c enable aas optimization
"sv_mapChecksum" "0" be_aas_main.c BSP file checksum
"bot_visualizejumppads" "0" be_aas_reach.c visualize jump pads
"bot_reloadcharacters" "0" - reload bot character files
"ai_gametype" "0" be_ai_goal.c game type
"droppedweight" "1000" be_ai_goal.c additional dropped item weight
"weapindex_rocketlauncher" "5" be_ai_move.c rl weapon index for rocket jumping
"weapindex_bfg10k" "9" be_ai_move.c bfg weapon index for bfg jumping
"weapindex_grapple" "10" be_ai_move.c grapple weapon index for grappling
"entitytypemissile" "3" be_ai_move.c ET_MISSILE
"offhandgrapple" "0" be_ai_move.c enable off hand grapple hook
"cmd_grappleon" "grappleon" be_ai_move.c command to activate off hand grapple
"cmd_grappleoff" "grappleoff" be_ai_move.c command to deactivate off hand grapple
"itemconfig" "items.c" be_ai_goal.c item configuration file
"weaponconfig" "weapons.c" be_ai_weap.c weapon configuration file
"synfile" "syn.c" be_ai_chat.c file with synonyms
"rndfile" "rnd.c" be_ai_chat.c file with random strings
"matchfile" "match.c" be_ai_chat.c file with match strings
"nochat" "0" be_ai_chat.c disable chats
"max_messages" "1024" be_ai_chat.c console message heap size
"max_weaponinfo" "32" be_ai_weap.c maximum number of weapon info
"max_projectileinfo" "32" be_ai_weap.c maximum number of projectile info
"max_iteminfo" "256" be_ai_goal.c maximum number of item info
"max_levelitems" "256" be_ai_goal.c maximum number of level items
*/
#include "../botlib/botlib.h"

View File

@ -1305,66 +1305,166 @@ static qintptr_t QVM_TraceBox (void *offset, quintptr_t mask, const qintptr_t *a
WrapQCBuiltin(PF_svtraceline, offset, mask, arg, "vvinvv");
return 0;
}
typedef struct {
vfsfile_t *file;
} vm_fopen_files_t;
static vm_fopen_files_t vm_fopen_files[64];
static qintptr_t QVM_FS_OpenFile (void *offset, quintptr_t mask, const qintptr_t *arg)
{
//0 = name
//1 = &handle
//2 = mode
//ret = filesize or -1
// Con_Printf("G_FSOpenFile: %s (mode %i)\n", VM_POINTER(arg[0]), arg[2]);
int mode;
switch((q1qvmfsMode_t)arg[2])
{
default:
const char *name = VM_POINTER(arg[0]);
int *handle = VM_POINTER(arg[1]);
int fmode = VM_LONG(arg[2]);
int fnum;
static struct {
const char *mode;
enum fs_relative root;
} mode[] = {
/*FS_READ_BIN*/{"rb",FS_GAME},
/*FS_READ_TXT*/{"rt",FS_GAME},
/*FS_WRITE_BIN*/{"wb",FS_GAMEONLY},
/*FS_WRITE_TXT*/{"wt",FS_GAMEONLY},
/*FS_APPEND_BIN*/{"ab",FS_GAMEONLY},
/*FS_APPEND_TXT*/{"at",FS_GAMEONLY},
};
if (fmode < 0 || fmode >= countof(mode))
return -1;
case FS_READ_BIN:
case FS_READ_TXT:
mode = VM_FS_READ;
break;
case FS_WRITE_BIN:
case FS_WRITE_TXT:
mode = VM_FS_WRITE;
break;
case FS_APPEND_BIN:
case FS_APPEND_TXT:
mode = VM_FS_APPEND;
break;
}
return VM_fopen(VM_POINTER(arg[0]), VM_POINTER(arg[1]), mode, VMFSID_Q1QVM);
for (fnum = 0; fnum < countof(vm_fopen_files); fnum++)
if (!vm_fopen_files[fnum].file)
break;
if (fnum == countof(vm_fopen_files)) //too many already open
return -1;
vm_fopen_files[fnum].file = FS_OpenVFS(name, mode[fmode].mode, mode[fmode].root);
if (!vm_fopen_files[fnum].file)
return -1;
*handle = fnum+1;
return VFS_GETLEN(vm_fopen_files[fnum].file);
}
static qintptr_t QVM_FS_CloseFile (void *offset, quintptr_t mask, const qintptr_t *arg)
{
VM_fclose(arg[0], VMFSID_Q1QVM);
return 0;
int fnum = VM_LONG(arg[0])-1;
if (fnum >= 0 && fnum < countof(vm_fopen_files) && vm_fopen_files[fnum].file)
{
VFS_CLOSE(vm_fopen_files[fnum].file);
vm_fopen_files[fnum].file = NULL;
return 0;
}
return -1;
}
static void QVM_FS_CloseFileAll (void)
{
size_t fnum;
for (fnum = 0; fnum < countof(vm_fopen_files); fnum++)
if (vm_fopen_files[fnum].file)
{
VFS_CLOSE(vm_fopen_files[fnum].file);
vm_fopen_files[fnum].file = NULL;
}
}
static qintptr_t QVM_FS_ReadFile (void *offset, quintptr_t mask, const qintptr_t *arg)
{
if (VM_OOB(arg[0], arg[1]))
void *dest = VM_POINTER(arg[0]);
int size = VM_LONG(arg[1]);
int fnum = VM_LONG(arg[2])-1;
if (VM_OOB(arg[0], size))
return 0;
return VM_FRead(VM_POINTER(arg[0]), VM_LONG(arg[1]), VM_LONG(arg[2]), VMFSID_Q1QVM);
if (fnum >= 0 && fnum < countof(vm_fopen_files) && vm_fopen_files[fnum].file && vm_fopen_files[fnum].file->ReadBytes)
return VFS_READ(vm_fopen_files[fnum].file, dest, size);
return 0;
}
static qintptr_t QVM_FS_WriteFile (void *offset, quintptr_t mask, const qintptr_t *arg)
{
if (VM_OOB(arg[0], arg[1]))
void *dest = VM_POINTER(arg[0]);
int size = VM_LONG(arg[1]);
int fnum = VM_LONG(arg[2])-1;
if (VM_OOB(arg[0], size))
return 0;
return VM_FWrite(VM_POINTER(arg[0]), VM_LONG(arg[1]), VM_LONG(arg[2]), VMFSID_Q1QVM);
if (fnum >= 0 && fnum < countof(vm_fopen_files) && vm_fopen_files[fnum].file && vm_fopen_files[fnum].file->ReadBytes)
return VFS_WRITE(vm_fopen_files[fnum].file, dest, size);
return 0;
}
static qintptr_t QVM_FS_SeekFile (void *offset, quintptr_t mask, const qintptr_t *arg)
{
//fixme: what should the return value be?
VM_FSeek(VM_LONG(arg[0]), VM_LONG(arg[1]), VM_LONG(arg[2]), VMFSID_Q1QVM);
int fnum = VM_LONG(arg[0])-1;
quintptr_t foffset = arg[1];
int seektype = VM_LONG(arg[2]);
if (fnum >= 0 && fnum < countof(vm_fopen_files) && vm_fopen_files[fnum].file && vm_fopen_files[fnum].file->seekstyle != SS_UNSEEKABLE)
{
if (seektype == 0) //cur
foffset += VFS_TELL(vm_fopen_files[fnum].file);
else if (seektype == 2) //end
foffset = VFS_GETLEN(vm_fopen_files[fnum].file) + (qintptr_t)foffset;
return VFS_SEEK(vm_fopen_files[fnum].file, foffset);
}
return 0;
}
static qintptr_t QVM_FS_TellFile (void *offset, quintptr_t mask, const qintptr_t *arg)
{
return VM_FTell(VM_LONG(arg[0]), VMFSID_Q1QVM);
int fnum = VM_LONG(arg[0])-1;
if (fnum >= 0 && fnum < countof(vm_fopen_files) && vm_fopen_files[fnum].file)
{
return VFS_TELL(vm_fopen_files[fnum].file);
}
return -1;
}
//filesystem searches result in a tightly-packed blob of null-terminated filenames (along with a count for how many entries)
typedef struct {
char *initialbuffer;
char *buffer;
int found;
int bufferleft;
int skip;
} vmsearch_t;
static int QDECL VMEnum(const char *match, qofs_t size, time_t mtime, void *args, searchpathfuncs_t *spath)
{
char *check;
int newlen;
match += ((vmsearch_t *)args)->skip;
newlen = strlen(match)+1;
if (newlen > ((vmsearch_t *)args)->bufferleft)
return false; //too many files for the buffer
check = ((vmsearch_t *)args)->initialbuffer;
while(check < ((vmsearch_t *)args)->buffer)
{
if (!Q_strcasecmp(check, match))
return true; //we found this one already
check += strlen(check)+1;
}
memcpy(((vmsearch_t *)args)->buffer, match, newlen);
((vmsearch_t *)args)->buffer+=newlen;
((vmsearch_t *)args)->bufferleft-=newlen;
((vmsearch_t *)args)->found++;
return true;
}
static qintptr_t QVM_FS_GetFileList (void *offset, quintptr_t mask, const qintptr_t *arg)
{
if (VM_OOB(arg[2], arg[3]))
vmsearch_t vms;
const char *path = VM_POINTER(arg[0]);
const char *ext = VM_POINTER(arg[1]);
char *output = VM_POINTER(arg[2]);
size_t buffersize = VM_LONG(arg[3]);
if (VM_OOB(arg[2], buffersize))
return 0;
return VM_GetFileList(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_POINTER(arg[2]), VM_LONG(arg[3]));
vms.initialbuffer = vms.buffer = output;
vms.skip = strlen(path)+1;
vms.bufferleft = buffersize;
vms.found=0;
if (*(const char *)ext == '.' || *(const char *)ext == '/')
COM_EnumerateFiles(va("%s/*%s", path, ext), VMEnum, &vms);
else
COM_EnumerateFiles(va("%s/*.%s", path, ext), VMEnum, &vms);
return vms.found;
}
static qintptr_t QVM_CVar_Set_Float (void *offset, quintptr_t mask, const qintptr_t *arg)
{
@ -2189,7 +2289,7 @@ void Q1QVM_Shutdown(qboolean notifygame)
VM_Call(q1qvm, GAME_SHUTDOWN, 0, 0, 0);
VM_Destroy(q1qvm);
q1qvm = NULL;
VM_fcloseall(VMFSID_Q1QVM);
QVM_FS_CloseFileAll();
if (svprogfuncs == &q1qvmprogfuncs)
sv.world.progs = svprogfuncs = NULL;
Z_FreeTags(VMFSID_Q1QVM);
@ -2269,12 +2369,12 @@ qboolean PR_LoadQ1QVM(void)
Q1QVM_Shutdown(true);
q1qvm = VM_Create(fname, com_nogamedirnativecode.ival?NULL:syscallnative, fname, syscallqvm);
q1qvm = VM_Create(fname, com_gamedirnativecode.ival?syscallnative:NULL, fname, syscallqvm);
if (!q1qvm)
q1qvm = VM_Create(fname, syscallnative, fname, NULL);
if (!q1qvm)
{
if (com_nogamedirnativecode.ival && COM_FCheckExists(va("%s"ARCH_DL_POSTFIX, fname)))
if (!com_gamedirnativecode.ival && COM_FCheckExists(va("%s"ARCH_DL_POSTFIX, fname)))
Con_Printf(CON_WARNING"%s"ARCH_DL_POSTFIX" exists, but is blocked from loading due to known bugs in other engines. If this is from a safe source then either ^aset com_nogamedirnativecode 0^a or rename to eg %s%s_%s"ARCH_DL_POSTFIX"\n", fname, ((host_parms.binarydir && *host_parms.binarydir)?host_parms.binarydir:host_parms.basedir), fname, FS_GetGamedir(false));
if (svprogfuncs == &q1qvmprogfuncs)
sv.world.progs = svprogfuncs = NULL;

View File

@ -96,8 +96,6 @@ typedef struct {
q3entityShared_t r; // shared by both the server system and game - I *really* don't understand this, it looks like a bug.
} q3sharedEntity_t;
//===============================================================
//
@ -112,6 +110,7 @@ typedef enum {
G_ERROR, // ( const char *string );
// abort the game
G_MILLISECONDS, // ( void );
// get current time for profiling reasons
// this should NOT be used for any game related tasks,
@ -283,6 +282,7 @@ typedef enum {
BOTLIB_AAS_SWIMMING,
BOTLIB_AAS_PREDICT_CLIENT_MOVEMENT,
BOTLIB_EA_SAY = 400,
BOTLIB_EA_SAY_TEAM,
BOTLIB_EA_COMMAND,
@ -373,7 +373,6 @@ typedef enum {
BOTLIB_AI_ALLOC_MOVE_STATE,
BOTLIB_AI_FREE_MOVE_STATE,
BOTLIB_AI_INIT_MOVE_STATE,
BOTLIB_AI_CHOOSE_BEST_FIGHT_WEAPON,
BOTLIB_AI_GET_WEAPON_INFO,
BOTLIB_AI_LOAD_WEAPON_WEIGHTS,
@ -402,8 +401,8 @@ typedef enum {
BOTLIB_PC_READ_TOKEN,
BOTLIB_PC_SOURCE_FILE_AND_LINE,
G_DEFAULTCASEWARNINGDISABLE //note: not an allowed index, just exists to prevent clang from warning about the default case.
G_DEFAULTCASEWARNINGDISABLE //note: not an allowed index, just exists to prevent clang from warning about the default case.
} q3ggameImport_t;

View File

@ -2114,7 +2114,7 @@ qboolean SV_Loadgame (const char *unsafe_savename)
best = p;
}
}
Q_snprintfz (filename, sizeof(filename), savefiles[best].pattern, savename);
f = FS_OpenReadLocation(filename, &savefiles[best].loc);
if (!f)

View File

@ -104,7 +104,7 @@ extern int sv_max_staticentities;
extern staticsound_state_t *sv_staticsounds;
extern int sv_max_staticsounds;
typedef struct
typedef struct server_s
{
qboolean active; // false when server is going down
server_state_t state; // precache commands are only valid during load
@ -112,15 +112,14 @@ typedef struct
float gamespeed; //time progression multiplier, fixed per-level.
unsigned int csqcchecksum;
qboolean mapchangelocked;
qboolean restarting;
#ifdef SAVEDGAMES
char loadgame_on_restart[MAX_QPATH]; //saved game to load on map_restart
double autosave_time;
#endif
double time; //current map time
double restartedtime; //sv.time from last map restart
double starttime; //system time we changed map.
double time; //time passed since map (re)start
double starttime; //Sys_DoubleTime at the start of the map
double restarttime; //for delayed map restarts - map will restart once sv.time reaches this stamp
int framenum;
int logindatabase;
@ -391,26 +390,6 @@ typedef struct //merge?
float ping_time;
} q2client_frame_t;
#endif
#ifdef Q3SERVER
#include "../client/clq3defs.h"
typedef struct //merge?
{
int flags;
int areabytes;
qbyte areabits[MAX_Q2MAP_AREAS/8]; // portalarea visibility bits
q3playerState_t ps;
int num_entities;
int first_entity; // into the circular sv_packet_entities[]
int senttime; // for ping calculations
int serverMessageNum;
int serverCommandNum;
int serverTime; // server time the message is valid for (in msec)
int localTime;
int deltaFrame;
} q3client_frame_t;
#endif
#define MAX_BACK_BUFFERS 16
@ -584,7 +563,7 @@ typedef struct client_s
q2client_frame_t *q2frames;
#endif
#ifdef Q3SERVER
q3client_frame_t *q3frames;
void *q3frames;
#endif
} frameunion;
packet_entities_t sentents;
@ -624,7 +603,7 @@ typedef struct client_s
//quake3 does reliables only via this mechanism. basically just like q1's stuffcmds.
int server_command_ack; //number known to have been received.
int server_command_sequence; //number available.
char server_commands[64][1024]; //the commands, to deal with resends
char server_commands[256][1024]; //the commands, to deal with resends
#endif
//true/false/persist
@ -940,7 +919,7 @@ typedef struct svtcpstream_s {
} svtcpstream_t;
#endif
typedef struct
typedef struct server_static_s
{
gametype_e gametype;
int spawncount; // number of servers spawned since start,
@ -1293,24 +1272,6 @@ void MSGQ2_WriteDeltaEntity (q2entity_state_t *from, q2entity_state_t *to, sizeb
void SVQ2_BuildBaselines(void);
#endif
//q3 stuff
#ifdef Q3SERVER
void SVQ3_ShutdownGame(qboolean restarting);
qboolean SVQ3_InitGame(qboolean restarting);
void SVQ3_ServerinfoChanged(const char *key);
qboolean SVQ3_RestartGamecode(void);
qboolean SVQ3_ConsoleCommand(void);
qboolean SVQ3_HandleClient(void);
void SVQ3_DirectConnect(void);
void SVQ3_NewMapConnects(void);
void SVQ3_DropClient(client_t *cl);
int SVQ3_AddBot(void);
void SVQ3_RunFrame(void);
void SVQ3_SendMessage(client_t *client);
qboolean SVQ3_Command(void);
#endif
//
// sv_send.c
//

View File

@ -466,7 +466,7 @@ static int QDECL CompleteMapList (const char *name, qofs_t flags, time_t mtime,
char stripped[64];
if (name[5] == 'b' && name[6] == '_') //skip box models
return true;
COM_StripExtension(name+5, stripped, sizeof(stripped));
ctx->cb(stripped, NULL, NULL, ctx);
return true;
@ -530,6 +530,8 @@ variations:
'changelevel' will not flush the level cache, for h2 compat (won't save current level state in such a situation, as nq would prefer not)
'gamemap' will save the game to 'save0' after loading, for q2 compat
'spmap' is for q3 and sets 'gametype' to '2', otherwise identical to 'map'. all other map commands will reset it to '0' if its '2' at the time.
'spdevmap' forces sv_cheats 1, otherwise spmap
'devmap' forces sv_cheats 1, otherwise map
'map_restart' restarts the current map. Name is needed for q3 compat.
'restart' is an alias for 'map_restart'. Exists for NQ compat, but as an alias for QW mods that tried to use it for mod-specific things.
@ -572,16 +574,16 @@ void SV_Map_f (void)
#ifdef Q3SERVER
qboolean q3singleplayer = false; //forces g_gametype to 2 (otherwise clears if it was 2).
#endif
qboolean waschangelevel = false;
qboolean mapeditor = false;
int i;
char *startspot;
const char *cmd = Cmd_Argv(0);
#ifndef SERVERONLY
if (!Renderer_Started() && !isDedicated)
{
Cbuf_AddText(va("wait;%s %s\n", Cmd_Argv(0), Cmd_Args()), Cmd_ExecLevel);
Cbuf_AddText(va("wait;%s %s\n", cmd, Cmd_Args()), Cmd_ExecLevel);
return;
}
#endif
@ -592,14 +594,18 @@ void SV_Map_f (void)
return;
#endif
if (!Q_strcasecmp(Cmd_Argv(0), "map_restart"))
if (!Q_strcasecmp(cmd, "map_restart"))
{
const char *arg = Cmd_Argv(1);
#ifdef Q3SERVER
if (sv.state==ss_active && svs.gametype==GT_QUAKE3)
if (SVQ3_RestartGamecode())
return;
Cvar_ApplyLatches(CVAR_MAPLATCH, false);
if (sv.state==ss_active && svs.gametype==GT_QUAKE3 && q3->sv.RestartGamecode())
{
sv.time = sv.world.physicstime;
sv.starttime = Sys_DoubleTime() - sv.time;
return;
}
#endif
#ifdef SAVEDGAMES
@ -615,7 +621,8 @@ void SV_Map_f (void)
Con_DPrintf ("map_restart delay not implemented yet\n");
}
Q_strncpyz (level, ".", sizeof(level));
startspot = NULL; //FIXME: startspot forgotten on restart
startspot = NULL;
isrestart = true;
//FIXME: if precaches+statics don't change, don't do the whole networking thing.
}
@ -655,15 +662,15 @@ void SV_Map_f (void)
}
#ifdef Q3SERVER
q3singleplayer = !strcmp(Cmd_Argv(0), "spmap");
q3singleplayer = !strncmp(cmd, "sp", 2);
#endif
if ((svs.gametype == GT_PROGS || svs.gametype == GT_Q1QVM) && progstype == PROG_QW)
flushparms = !strcmp(Cmd_Argv(0), "spmap"); //quakeworld's map command preserves spawnparms.
flushparms = !strncmp(cmd, "sp", 2); //quakeworld's map command preserves spawnparms. q3 doesn't do parms, so we might as well reuse sp[dev]map to flush in qw
else
flushparms = !strcmp(Cmd_Argv(0), "map") || !strcmp(Cmd_Argv(0), "spmap"); //[sp]map flushes in nq+h2+q2+etc
flushparms = !strcmp(cmd, "map") || !strncmp(cmd, "sp", 2); //[sp]map flushes in nq+h2+q2+etc
#ifdef SAVEDGAMES
newunit = flushparms || (!strcmp(Cmd_Argv(0), "changelevel") && !startspot);
q2savetos0 = !strcmp(Cmd_Argv(0), "gamemap") && !isDedicated; //q2
q2savetos0 = !strcmp(cmd, "gamemap") && !isDedicated; //q2
#endif
mapeditor = !strcmp(Cmd_Argv(0), "mapedit");
@ -876,12 +883,15 @@ void SV_Map_f (void)
#ifdef Q3SERVER
{
cvar_t *gametype;
cvar_t *var, *gametype;
Cvar_ApplyLatches(CVAR_MAPLATCH, false);
host_mapname.flags |= CVAR_SERVERINFO;
var = Cvar_Get("nextmap", "", 0, "Q3 compatibility");
Cvar_ForceSet(var, "map_restart 0"); //on every map change matches q3.
gametype = Cvar_Get("g_gametype", "", CVAR_MAPLATCH|CVAR_SERVERINFO, "Q3 compatability");
// gametype->callback = gtcallback;
@ -1504,7 +1514,7 @@ static void SV_FilterIP_f (void)
if (i == countof(banflags))
Con_Printf("Unknown ban/penalty flag: %s. ignoring.\n", com_token);
}
//if no flags were specified,
//if no flags were specified,
if (!proto.banflags)
{
if (!strcmp(Cmd_Argv(0), "ban"))
@ -2241,18 +2251,22 @@ static void SV_Status_f (void)
#define C_USERID COLUMN(1, "userid", Con_Printf("%6i ", (int)cl->userid))
#define C_ADDRESS COLUMN(2, "address ", Con_Printf("%-16.16s", s))
#define C_NAME COLUMN(3, "name ", Con_Printf("%-16.16s", cl->name))
#define C_RATE COLUMN(4, "rate", Con_Printf("%4i ", cl->frameunion.frames?(int)(1/cl->netchan.frame_rate):0))
#define C_RATE COLUMN(4, "rate", Con_Printf("%4i ", (cl->frameunion.frames&&cl->netchan.frame_rate>0)?(int)(1/cl->netchan.frame_rate):0))
#define C_PING COLUMN(5, "ping", Con_Printf("%4i ", (int)SV_CalcPing (cl, false)))
#define C_DROP COLUMN(6, "drop", Con_Printf("%4.1f ", 100.0*cl->netchan.drop_count / cl->netchan.incoming_sequence))
#define C_DLP COLUMN(7, "dl ", if (!cl->download)Con_Printf(" ");else Con_Printf("%3.0f ", (cl->downloadcount*100.0)/cl->downloadsize))
#define C_DLP COLUMN(7, "dl ", if (!cl->download||!cl->downloadsize)Con_Printf(" ");else Con_Printf("%3.0f ", (cl->downloadcount*100.0)/cl->downloadsize))
#define C_DLS COLUMN(8, "dls", if (!cl->download)Con_Printf(" ");else Con_Printf("%3u ", (unsigned int)(cl->downloadsize/1024)))
#define C_PROT COLUMN(9, "prot ", Con_Printf("%-6.6s", p))
#define C_PROT COLUMN(9, "prot ", Con_Printf("%-6.5s", p))
#define C_MODELSKIN COLUMN(11, "model/skin ", Con_Printf("%s", s))
#define C_ADDRESS2 COLUMN(10, "address ", Con_Printf("%s", s))
int columns = (1<<6)-1;
int columns = (1<<4)-1;
for (i=0,cl=svs.clients ; i<svs.allocated_client_slots ; i++,cl++)
{
if (!cl->state)
continue;
if (cl->netchan.drop_count)
columns |= 1<<6;
if (cl->download)
@ -2260,11 +2274,17 @@ static void SV_Status_f (void)
columns |= 1<<7;
columns |= 1<<8;
}
if (cl->protocol != SCP_QUAKEWORLD || cl->spectator || !(cl->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS))
if (cl->frameunion.frames&&cl->netchan.frame_rate>0)
columns |= 1<<4;
if (cl->netchan.remote_address.type > NA_LOOPBACK)
columns |= 1<<5;
if (cl->protocol != SCP_BAD && (cl->protocol >= SCP_NETQUAKE || cl->spectator || (cl->protocol == SCP_QUAKEWORLD && !(cl->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS))))
columns |= 1<<9;
if (cl->netchan.remote_address.type == NA_IPV6)
columns = (columns & ~(1<<2)) | (1<<10);
if (cl->netchan.remote_address.type == NA_IPV6||cl->reversedns)
columns |= (1<<10);
}
if (columns&(1<<10)) //if address2, remove the limited length addresses.
columns &= ~(1<<2);
#define COLUMN(f,t,v) if (columns&(1<<f)) Con_Printf(t" ");
COLUMNS
@ -2299,12 +2319,9 @@ static void SV_Status_f (void)
else
s = NET_BaseAdrToString (adr, sizeof(adr), &cl->netchan.remote_address);
switch(cl->protocol)
safeswitch(cl->protocol)
{
default:
case SCP_BAD:
p = "";
break;
case SCP_BAD: p = "none"; break;
case SCP_QUAKEWORLD: p = (cl->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)?"fteqw":"qw"; break;
case SCP_QUAKE2: p = "q2"; break;
case SCP_QUAKE3: p = "q3"; break;
@ -2313,6 +2330,9 @@ static void SV_Status_f (void)
case SCP_FITZ666: p = (cl->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)?"ftenq":(cl->qex?"qe666":"fitz"); break;
case SCP_DARKPLACES6: p = "dpp6"; break;
case SCP_DARKPLACES7: p = "dpp7"; break;
safedefault:
p = "";
break;
}
if (cl->state == cs_connected && cl->protocol>=SCP_NETQUAKE)
p = "nq"; //not actually known yet.
@ -2593,7 +2613,7 @@ void SV_User_f (void)
char buf[256];
extern cvar_t sv_userinfo_bytelimit, sv_userinfo_keylimit;
static const char *pext1names[32] = { "setview", "scale", "lightstylecol", "trans", "view2", "builletens", "accuratetimings", "sounddbl",
"fatness", "hlbsp", "bullet", "hullsize", "modeldbl", "entitydbl", "entitydbl2", "floatcoords",
"fatness", "hlbsp", "bullet", "hullsize", "modeldbl", "entitydbl", "entitydbl2", "floatcoords",
"OLD vweap", "q2bsp", "q3bsp", "colormod", "splitscreen", "hexen2", "spawnstatic2", "customtempeffects",
"packents", "UNKNOWN", "showpic", "setattachment","UNKNOWN", "chunkeddls", "csqc", "dpflags"};
static const char *pext2names[32] = { "prydoncursor", "voip", "setangledelta", "rplcdeltas", "maxplayers", "predinfo", "sizeenc", "infoblobs",
@ -2607,16 +2627,16 @@ void SV_User_f (void)
return;
}
Con_Printf("Userinfo:\n");
while((cl = SV_GetClientForString(Cmd_Argv(1), &clnum)))
{
Con_Printf("Userinfo (%i):\n", cl->userid);
InfoBuf_Print (&cl->userinfo, " ");
Con_Printf("[%u/%i, %u/%i]\n", (unsigned)cl->userinfo.totalsize, sv_userinfo_bytelimit.ival, (unsigned)cl->userinfo.numkeys, sv_userinfo_keylimit.ival);
switch(cl->protocol)
{
case SCP_BAD:
Con_Printf("protocol: bot/invalid\n");
break;
continue;
case SCP_QUAKEWORLD: //branding is everything...
if (cl->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
Con_Printf("protocol: fteqw-nack\n");
@ -2846,10 +2866,7 @@ static void SV_Gamedir_f (void)
Con_TPrintf ("%s should be a single filename, not a path\n", Cmd_Argv(0));
}
else
{
COM_Gamedir (dir, NULL);
InfoBuf_SetValueForStarKey (&svs.info, "*gamedir", dir);
}
Z_Free(dir);
}
@ -3024,7 +3041,7 @@ static void SV_SetTimer_f(void)
static void SV_SendGameCommand_f(void)
{
#ifdef Q3SERVER
if (SVQ3_ConsoleCommand())
if (q3->sv.PrefixedConsoleCommand())
return;
#endif
@ -3175,7 +3192,7 @@ void SV_MemInfo_f(void)
fr += sizeof(*cl->sentents.entities) * cl->sentents.max_entities;
csfr = sizeof(*cl->pendingcsqcbits) * cl->max_net_ents;
Con_Printf("%"PRIuSIZE" minping=%i frame=%i, csqc=%i\n", sizeof(svs.clients[i]), sz, fr, csfr);
}
}

View File

@ -130,7 +130,7 @@ static int MSV_SubServerRead(pubsubserver_t *ps)
net_message.cursize = len-2;
memmove(ps->inbuffer, ps->inbuffer+len, ps->inbuffersize - len);
ps->inbuffersize -= len;
MSG_BeginReading (msg_nullnetprim);
MSG_BeginReading (&net_message, msg_nullnetprim);
return len;
}
@ -1233,7 +1233,7 @@ void MSV_PollSlaves(void)
memmove(inbuffer, inbuffer+size, inbuffersize-size);
inbuffersize -= size;
MSG_BeginReading (msg_nullnetprim);
MSG_BeginReading (&net_message, msg_nullnetprim);
SSV_ReadFromControlServer();
}
else
@ -1259,7 +1259,7 @@ void MSV_PollSlaves(void)
{
VFS_READ(msv_loop_to_ss, net_message.data, size);
net_message.cursize = size-2;
MSG_BeginReading (msg_nullnetprim);
MSG_BeginReading (&net_message, msg_nullnetprim);
SSV_ReadFromControlServer();
}
}

View File

@ -628,7 +628,8 @@ void SV_UnspawnServer (void) //terminate the running server.
}
PR_Deinit();
#ifdef Q3SERVER
SVQ3_ShutdownGame(false);
if (q3)
q3->sv.ShutdownGame(false);
#endif
#ifdef Q2SERVER
SVQ2_ShutdownGameProgs();
@ -927,14 +928,11 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents,
// if (0)
// cls.state = ca_connected;
Surf_PreNewMap();
#ifdef VM_CG
CG_Stop();
#endif
#endif
#ifdef Q3SERVER
if (svs.gametype == GT_QUAKE3)
SVQ3_ShutdownGame(false); //botlib kinda mandates this. :(
q3->sv.ShutdownGame(false); //botlib kinda mandates this. :(
#endif
Mod_ClearAll ();
@ -994,7 +992,6 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents,
CL_CheckServerInfo();
#endif
sv.restarting = false;
sv.state = ss_loading;
#if defined(Q2BSPS)
if (usecinematic)
@ -1162,7 +1159,7 @@ MSV_OpenUserDatabase();
newgametype = GT_HALFLIFE;
#endif
#ifdef Q3SERVER
else if (SVQ3_InitGame(false))
else if (q3 && q3->sv.InitGame(&svs, &sv, false))
newgametype = GT_QUAKE3;
#endif
#ifdef Q2SERVER
@ -1193,7 +1190,7 @@ MSV_OpenUserDatabase();
#endif
#ifdef Q3SERVER
if (newgametype != GT_QUAKE3)
SVQ3_ShutdownGame(false);
q3->sv.ShutdownGame(false);
#endif
#ifdef Q2SERVER
if (newgametype != GT_QUAKE2) //we don't want the q2 stuff anymore.
@ -1403,6 +1400,7 @@ MSV_OpenUserDatabase();
#endif
#ifdef Q3SERVER
case GT_QUAKE3:
Cvar_LockFromServer(&maxclients, maxclients.string);
SV_UpdateMaxPlayers(playerslots?playerslots:max(8,maxclients.ival));
break;
#endif
@ -1764,7 +1762,7 @@ MSV_OpenUserDatabase();
#ifdef Q3SERVER
if (svs.gametype == GT_QUAKE3)
{
SVQ3_NewMapConnects();
q3->sv.NewMapConnects();
}
#endif
@ -1784,6 +1782,11 @@ MSV_OpenUserDatabase();
sv.autosave_time = sv.time + sv_autosave.value*60;
#endif
#ifdef HAVE_CLIENT
//there's a whole load of ugly debug crap there. make sure it stays hidden.
Con_ClearNotify();
#endif
#ifdef __GLIBC__
if (isDedicated)
malloc_trim(0);

View File

@ -606,7 +606,7 @@ void SV_DropClient (client_t *drop)
break;
case GT_QUAKE3:
#ifdef Q3SERVER
SVQ3_DropClient(drop);
q3->sv.DropClient(drop);
#endif
break;
case GT_HALFLIFE:
@ -657,9 +657,10 @@ void SV_DropClient (client_t *drop)
}
else
#endif
if (drop->state == cs_spawned || drop->istobeloaded)
if (drop->protocol == SCP_BAD)
drop->state = cs_free; //skip zombie state for bots.
else if (drop->state == cs_spawned || drop->istobeloaded)
{
drop->istobeloaded = false;
drop->state = cs_zombie; // become free in a few seconds
drop->connection_started = realtime; // for zombie timeout
}
@ -2170,7 +2171,7 @@ void SV_ClientProtocolExtensionsChanged(client_t *client)
case SCP_QUAKE3:
if (client->frameunion.q3frames)
Z_Free(client->frameunion.q3frames);
client->frameunion.q3frames = Z_Malloc(Q3UPDATE_BACKUP*sizeof(*client->frameunion.q3frames));
client->frameunion.q3frames = NULL;//Z_Malloc(Q3UPDATE_BACKUP*sizeof(*client->frameunion.q3frames));
break;
#endif
@ -4040,7 +4041,7 @@ qboolean SV_ConnectionlessPacket (void)
char *c;
char adr[MAX_ADR_SIZE];
MSG_BeginReading (svs.netprim);
MSG_BeginReading (&net_message, svs.netprim);
if (net_message.cursize >= MAX_QWMSGLEN) //add a null term in message space
{
@ -4096,7 +4097,7 @@ qboolean SV_ConnectionlessPacket (void)
#ifdef Q3SERVER
if (svs.gametype == GT_QUAKE3)
{
SVQ3_DirectConnect();
q3->sv.DirectConnect(&net_from, &net_message);
return true;
}
@ -4251,7 +4252,7 @@ qboolean SVNQ_ConnectionlessPacket(void)
if (!sv_listen_nq.value || SSV_IsSubServer())
return false;
MSG_BeginReading(svs.netprim);
MSG_BeginReading(&net_message, svs.netprim);
header = LongSwap(MSG_ReadLong());
if (!(header & NETFLAG_CTL))
{
@ -4664,7 +4665,7 @@ void SV_ReadPacket(void)
#ifdef Q3SERVER
if (svs.gametype == GT_QUAKE3)
{
if (SVQ3_HandleClient())
if (q3->sv.HandleClient(&net_from, &net_message))
inboundsequence++;
else if (NET_WasSpecialPacket(svs.sockets))
return;
@ -4674,7 +4675,7 @@ void SV_ReadPacket(void)
// read the qport out of the message so we can fix up
// stupid address translating routers
MSG_BeginReading (svs.netprim);
MSG_BeginReading (&net_message, svs.netprim);
MSG_ReadLong (); // sequence number
MSG_ReadLong (); // sequence number
qport = MSG_ReadShort () & 0xffff;
@ -4789,7 +4790,7 @@ dominping:
return;
#ifdef QWOVERQ3
if (sv_listen_q3.ival && SVQ3_HandleClient())
if (sv_listen_q3.ival && q3->sv.HandleClient())
{
received++;
continue;
@ -4906,7 +4907,6 @@ qboolean SV_ReadPackets (float *delay)
NET_DTLS_Timeouts(svs.sockets);
#endif
if (inboundsequence == oldinboundsequence)
return false; //nothing new.
oldinboundsequence = inboundsequence;
@ -5527,7 +5527,8 @@ static void SV_InfoChanged(void *context, const char *key)
size_t i;
#ifdef Q3SERVER
SVQ3_ServerinfoChanged(key);
if (q3)
q3->sv.ServerinfoChanged(key);
#endif
if (context != &svs.info && *key == '_')

View File

@ -1120,10 +1120,10 @@ static void SVM_ProcessUDPPacket(void)
svm.time = Sys_DoubleTime();
MSG_BeginReading(msg_nullnetprim);
MSG_BeginReading(&net_message, msg_nullnetprim);
if (MSG_ReadLong() != -1 || msg_badread)
{ //go back to start...
MSG_BeginReading(msg_nullnetprim);
MSG_BeginReading(&net_message, msg_nullnetprim);
}
line = MSG_ReadStringLine();
s = COM_Parse(line);

View File

@ -2519,7 +2519,7 @@ qboolean SV_Physics (void)
{
int i;
qboolean moved = false;
int maxtics;
int maxtics = sv_limittics.ival;
double trueframetime = host_frametime;
double maxtic = sv_maxtic.value;
double mintic = sv_mintic.value;
@ -2530,6 +2530,9 @@ qboolean SV_Physics (void)
if (maxtic < mintic)
maxtic = mintic;
if (maxtics>1&&sv.spawned_observer_slots==0&&sv.spawned_client_slots==0)
maxtics = 1; //no players on the server. let timings slide
//keep gravity tracking the cvar properly
movevars.gravity = sv_gravity.value;
@ -2540,43 +2543,52 @@ qboolean SV_Physics (void)
) //make tics multiples of sv_maxtic (defaults to 0.1)
{
if (svs.gametype == GT_QUAKE2)
maxtic = 0.1; //fucking fuckity fuck. we should warn about this.
mintic = maxtic = 0.1; //fucking fuckity fuck. we should warn about this.
mintic = max(mintic, 1/1000.0);
host_frametime = sv.time - sv.world.physicstime;
if (host_frametime<0)
for(;;)
{
if (host_frametime < -1)
host_frametime = sv.time - sv.world.physicstime;
if (host_frametime<0)
{
if (host_frametime < -1)
sv.world.physicstime = sv.time;
host_frametime = 0;
}
if (!maxtics--)
{ //don't loop infinitely if we froze (eg debugger or suspend/hibernate)
sv.world.physicstime = sv.time;
host_frametime = 0;
}
if (svs.gametype != GT_QUAKE3)
if (host_frametime < maxtic && realtime)
{
// sv.time+=host_frametime;
host_frametime = trueframetime;
return false; //don't bother with the whole server thing for a bit longer
}
if (host_frametime > maxtic)
host_frametime = maxtic;
sv.world.physicstime = sv.time;
break;
}
if (!host_frametime || (host_frametime < mintic && realtime))
{
// sv.time+=host_frametime;
host_frametime = trueframetime;
return false; //don't bother with the whole server thing for a bit longer
}
if (host_frametime > maxtic)
host_frametime = maxtic;
sv.world.physicstime += host_frametime;
moved = true;
switch(svs.gametype)
{
switch(svs.gametype)
{
#ifdef Q2SERVER
case GT_QUAKE2:
ge->RunFrame();
break;
case GT_QUAKE2:
ge->RunFrame();
break;
#endif
#ifdef Q3SERVER
case GT_QUAKE3:
SVQ3_RunFrame();
break;
case GT_QUAKE3:
q3->sv.RunFrame();
break;
#endif
default:
break;
default:
break;
}
}
host_frametime = trueframetime;
return true;
return moved;
}
if (svs.gametype != GT_HALFLIFE && /*sv.botsonthemap &&*/ progstype == PROG_QW)
@ -2644,10 +2656,6 @@ qboolean SV_Physics (void)
}
}
maxtics = sv_limittics.ival;
if (sv.spawned_observer_slots==0&&sv.spawned_client_slots==0)
maxtics = 1; //no players on the server. let timings slide
// don't bother running a frame if sys_ticrate seconds haven't passed
while (1)
{

View File

@ -3384,7 +3384,11 @@ void SV_SendClientMessages (void)
continue;
}
SVQ3_SendMessage(c);
if (c->lastoutgoingphysicstime == pt)
continue;
c->lastoutgoingphysicstime = pt;
q3->sv.SendMessage(c);
}
return;
}
@ -3461,7 +3465,7 @@ void SV_SendClientMessages (void)
#ifdef Q3SERVER
if (ISQ3CLIENT(c))
{ //q3 protocols bypass backbuffering and pretty much everything else
SVQ3_SendMessage(c);
q3->sv.SendMessage(c);
continue;
}
#endif

View File

@ -92,13 +92,13 @@ void *SVQ2_GetGameAPI (void *parms)
}
else if (*gamename[o] == '/')
{ //system path. o.O
if (com_nogamedirnativecode.ival) //just in case they match.
if (!com_gamedirnativecode.ival) //just in case they match.
continue;
Q_snprintfz(name, sizeof(name), gamename[o], gamepath);
}
else
{ //gamedir paths as specified above.
if (com_nogamedirnativecode.ival)
if (!com_gamedirnativecode.ival)
continue;
Q_snprintfz(name, sizeof(name), "%s%s", syspath, gamename[o]);
}

File diff suppressed because it is too large Load Diff

View File

@ -3497,7 +3497,7 @@ static void VK_PaintScreen(void)
if (topmenu && topmenu->isopaque)
nohud = true;
#ifdef VM_CG
else if (CG_Refresh())
else if (q3->cg.Redraw(cl.time))
nohud = true;
#endif
#ifdef CSQC_DAT

View File

@ -184,7 +184,7 @@ char *COM_SkipPath (const char *pathname)
#ifdef __unix__
#include <sys/stat.h>
#endif
qbyte *FS_LoadMallocFile (const char *path, size_t *fsize)
void *FS_LoadMallocFile (const char *path, size_t *fsize)
{
qbyte *data = NULL;
FILE *f;

View File

@ -356,6 +356,51 @@ else
$(PLUG_PREFIX)cef$(PLUG_NATIVE_EXT):
@echo cef plugin not supported on this arch - $(FTE_TARGET) - $(CEF_ARCH)
endif
######################################
#quake3
BOTLIBFILES=../engine/botlib/be_aas_bspq3.c \
../engine/botlib/be_aas_cluster.c \
../engine/botlib/be_aas_debug.c \
../engine/botlib/be_aas_entity.c \
../engine/botlib/be_aas_file.c \
../engine/botlib/be_aas_main.c \
../engine/botlib/be_aas_move.c \
../engine/botlib/be_aas_optimize.c \
../engine/botlib/be_aas_reach.c \
../engine/botlib/be_aas_routealt.c \
../engine/botlib/be_aas_route.c \
../engine/botlib/be_aas_sample.c \
../engine/botlib/be_ai_char.c \
../engine/botlib/be_ai_chat.c \
../engine/botlib/be_ai_gen.c \
../engine/botlib/be_ai_goal.c \
../engine/botlib/be_ai_move.c \
../engine/botlib/be_ai_weap.c \
../engine/botlib/be_ai_weight.c \
../engine/botlib/be_ea.c \
../engine/botlib/be_interface.c \
../engine/botlib/l_crc.c \
../engine/botlib/l_libvar.c \
../engine/botlib/l_log.c \
../engine/botlib/l_memory.c \
../engine/botlib/l_precomp.c \
../engine/botlib/l_script.c \
../engine/botlib/l_struct.c \
../engine/botlib/standalone.c
QUAKE3FILES=$(BOTLIBFILES) \
plugin.c \
../engine/client/cl_cg.c \
../engine/client/cl_ui.c \
../engine/client/clq3_parse.c \
../engine/server/svq3_game.c \
../engine/common/q3common.c
$(PLUG_PREFIX)quake3$(PLUG_NATIVE_EXT): ${QUAKE3FILES}
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -DBOTLIB -DBOTLIB_STATIC -o $@ -shared $(PLUG_CFLAGS) $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS_ZLIB) $(PLUG_LDFLAGS)
$(call EMBEDMETA,quake3,$@,Quake3 Compat,Quake3 Gamecode Compatibility)
NATIVE_PLUGINS+=quake3
######################################
#for custom/private plugins...

View File

@ -782,66 +782,43 @@ static media_encoder_funcs_t encoderfuncs =
};
qboolean AVEnc_ExecuteCommand(qboolean isinsecure)
static void AVEnc_Preset_Nvidia_f(void)
{
char cmd[256];
cmdfuncs->Argv(0, cmd, sizeof(cmd));
/*
if (!strcmp(cmd, ENCODERNAME"_configure"))
{
menuclear
menualias menucallback
cvarfuncs->SetString("capturedriver", ENCODERNAME); //be sure to use our encoder
cvarfuncs->SetString(ENCODERNAME"_videocodec", "h264_nvenc");
cvarfuncs->SetString("capturerate", "60"); //we should be able to cope with it, and the default of 30 sucks
cvarfuncs->SetString("capturedemowidth", "1920"); //force a specific size, some codecs need multiples of 16 or whatever.
cvarfuncs->SetString("capturedemoheight", "1080"); //so this avoids issues with various video codecs.
menubox 0 0 320 8
menutext 0 0 "GO GO GO!!!" "radio21"
menutext 0 8 "Fall back" "radio22"
menutext 0 8 "Stick together" "radio23"
menutext 0 16 "Get in position" "radio24"
menutext 0 24 "Storm the front" "radio25"
menutext 0 24 "Report in" "radio26"
menutext 0 24 "Cancel"
return true;
}
*/
if (!strcmp(cmd, ENCODERNAME"_nvidia"))
{
cvarfuncs->SetString("capturedriver", ENCODERNAME); //be sure to use our encoder
cvarfuncs->SetString(ENCODERNAME"_videocodec", "h264_nvenc");
cvarfuncs->SetString("capturerate", "60"); //we should be able to cope with it, and the default of 30 sucks
cvarfuncs->SetString("capturedemowidth", "1920"); //force a specific size, some codecs need multiples of 16 or whatever.
cvarfuncs->SetString("capturedemoheight", "1080"); //so this avoids issues with various video codecs.
cvarfuncs->SetString("capturesound", "1");
cvarfuncs->SetString("capturesoundchannels", "2");
cvarfuncs->SetString("capturesoundbits", "16");
cvarfuncs->SetString("capturesound", "1");
cvarfuncs->SetString("capturesoundchannels", "2");
cvarfuncs->SetString("capturesoundbits", "16");
Con_Printf(ENCODERNAME": now configured for nvidia's hardware encoder\n");
Con_Printf(ENCODERNAME": use ^[/capture foo.mp4^] or ^[/capturedemo foo.mvd foo.mkv^] commands to begin capturing\n");
}
void AVEnc_Preset_Defaults_f(void)
{ //most formats will end up using the x264 encoder or something
cvarfuncs->SetString(ENCODERNAME"_format_force", "");
cvarfuncs->SetString(ENCODERNAME"_videocodec", "");
cvarfuncs->SetString(ENCODERNAME"_videobitrate", "");
cvarfuncs->SetString(ENCODERNAME"_videoforcewidth", "");
cvarfuncs->SetString(ENCODERNAME"_videoforceheight", "");
cvarfuncs->SetString(ENCODERNAME"_videopreset", "veryfast");
cvarfuncs->SetString(ENCODERNAME"_video_crf", "");
cvarfuncs->SetString(ENCODERNAME"_audiocodec", "");
cvarfuncs->SetString(ENCODERNAME"_audiobitrate", "");
Con_Printf(ENCODERNAME": now configured for nvidia's hardware encoder\n");
Con_Printf(ENCODERNAME": use ^[/capture foo.mp4^] or ^[/capturedemo foo.mvd foo.mkv^] commands to begin capturing\n");
}
if (!strcmp(cmd, ENCODERNAME"_defaults"))
{ //most formats will end up using the x264 encoder or something
cvarfuncs->SetString(ENCODERNAME"_format_force", "");
cvarfuncs->SetString(ENCODERNAME"_videocodec", "");
cvarfuncs->SetString(ENCODERNAME"_videobitrate", "");
cvarfuncs->SetString(ENCODERNAME"_videoforcewidth", "");
cvarfuncs->SetString(ENCODERNAME"_videoforceheight", "");
cvarfuncs->SetString(ENCODERNAME"_videopreset", "veryfast");
cvarfuncs->SetString(ENCODERNAME"_video_crf", "");
cvarfuncs->SetString(ENCODERNAME"_audiocodec", "");
cvarfuncs->SetString(ENCODERNAME"_audiobitrate", "");
cvarfuncs->SetString("capturedriver", ENCODERNAME);
cvarfuncs->SetString("capturerate", "30");
cvarfuncs->SetString("capturedemowidth", "0");
cvarfuncs->SetString("capturedemoheight", "0");
cvarfuncs->SetString("capturesound", "1");
cvarfuncs->SetString("capturesoundchannels", "2");
cvarfuncs->SetString("capturesoundbits", "16");
cvarfuncs->SetString("capturedriver", ENCODERNAME);
cvarfuncs->SetString("capturerate", "30");
cvarfuncs->SetString("capturedemowidth", "0");
cvarfuncs->SetString("capturedemoheight", "0");
cvarfuncs->SetString("capturesound", "1");
cvarfuncs->SetString("capturesoundchannels", "2");
cvarfuncs->SetString("capturesoundbits", "16");
Con_Printf(ENCODERNAME": capture settings reset to "ENCODERNAME" defaults\n");
Con_Printf(ENCODERNAME": Note that some codecs may have restrictions on video sizes\n");
}
return false;
Con_Printf(ENCODERNAME": capture settings reset to "ENCODERNAME" defaults\n");
Con_Printf(ENCODERNAME": Note that some codecs may have restrictions on video sizes\n");
}
@ -864,12 +841,10 @@ qboolean AVEnc_Init(void)
ffmpeg_audiocodec = cvarfuncs->GetNVFDG(ENCODERNAME"_audiocodec", "", 0, "Forces which audio encoder to use. If blank, guesses based upon container defaults.", ENCODERNAME);
ffmpeg_audiobitrate = cvarfuncs->GetNVFDG(ENCODERNAME"_audiobitrate", "", 0, "Specifies the target audio bitrate", ENCODERNAME);
if (plugfuncs->ExportFunction("ExecuteCommand", AVEnc_ExecuteCommand))
{
// cmdfuncs->AddCommand(ENCODERNAME"_configure");
cmdfuncs->AddCommand(ENCODERNAME"_nvidia");
cmdfuncs->AddCommand(ENCODERNAME"_defaults");
}
// cmdfuncs->AddCommand(ENCODERNAME"_configure", AVEnc_LoadPreset_f);
cmdfuncs->AddCommand(ENCODERNAME"_nvidia", AVEnc_Preset_Nvidia_f, "Attempts to reconfigure video capture to use nvidia's hardware encoder.");
cmdfuncs->AddCommand(ENCODERNAME"_defaults", AVEnc_Preset_Defaults_f, "Reconfigures video capture to the "ENCODERNAME" plugin's default settings.");
//cmdfuncs->AddCommand(ENCODERNAME"_twitch", AVEnc_Preset_Twitch_f, "Reconfigures video capture to stream to twitch.");
return true;
}

View File

@ -2174,38 +2174,31 @@ int NATIVEEXPORT CefSubprocessInit(plugcorefuncs_t *corefuncs)
return Cef_Init(false);
}
static qintptr_t Cef_ExecuteCommand(qintptr_t *args)
void Cef_ExecuteCommand(void)
{
char cmd[256];
cmdfuncs->Argv(0, cmd, sizeof(cmd));
if (!strcmp(cmd, "cef"))
if (confuncs && Cef_Init(true))
{
if (confuncs && Cef_Init(true))
{
static int sequence;
char f[128];
char videomap[8192];
Q_snprintf(f, sizeof(f), "libcef:%i", ++sequence);
newconsole = f;
strcpy(videomap, "cef:");
cmdfuncs->Argv(1, videomap+4, sizeof(videomap)-4);
if (!videomap[4])
strcpy(videomap, "cef:http://fte.triptohell.info");
confuncs->SetConsoleString(f, "title", videomap+4);
confuncs->SetConsoleFloat(f, "iswindow", true);
confuncs->SetConsoleFloat(f, "forceutf8", true);
confuncs->SetConsoleFloat(f, "wnd_w", 640+16);
confuncs->SetConsoleFloat(f, "wnd_h", 480+16+8);
confuncs->SetConsoleString(f, "backvideomap", videomap);
confuncs->SetConsoleFloat(f, "linebuffered", 2);
confuncs->SetActive(f);
static int sequence;
char f[128];
char videomap[8192];
Q_snprintf(f, sizeof(f), "libcef:%i", ++sequence);
newconsole = f;
strcpy(videomap, "cef:");
cmdfuncs->Argv(1, videomap+4, sizeof(videomap)-4);
if (!videomap[4])
strcpy(videomap, "cef:http://fte.triptohell.info");
newconsole = NULL;
}
return true;
confuncs->SetConsoleString(f, "title", videomap+4);
confuncs->SetConsoleFloat(f, "iswindow", true);
confuncs->SetConsoleFloat(f, "forceutf8", true);
confuncs->SetConsoleFloat(f, "wnd_w", 640+16);
confuncs->SetConsoleFloat(f, "wnd_h", 480+16+8);
confuncs->SetConsoleString(f, "backvideomap", videomap);
confuncs->SetConsoleFloat(f, "linebuffered", 2);
confuncs->SetActive(f);
newconsole = NULL;
}
return false;
}
static qboolean QDECL Cef_PluginMayUnload(void)
@ -2249,8 +2242,7 @@ qboolean Plug_Init(void)
return false;
}
if (plugfuncs->ExportFunction("ExecuteCommand", Cef_ExecuteCommand))
cmdfuncs->AddCommand("cef");
cmdfuncs->AddCommand("cef", Cef_ExecuteCommand, "Open a web page!");
cef_incognito = cvarfuncs->GetNVFDG("cef_incognito", "0", 0, NULL, "browser settings");
cef_allowplugins = cvarfuncs->GetNVFDG("cef_allowplugins", "0", 0, NULL, "browser settings");

View File

@ -224,11 +224,13 @@ mpic_t *Draw_CachePicSafe(const char *name, qbool crash, qbool ignorewad)
{
if (!*name)
return NULL;
return (mpic_t*)(qintptr_t)drawfuncs->LoadImage(name, false);
return (mpic_t*)(qintptr_t)drawfuncs->LoadImage(name);
}
mpic_t *Draw_CacheWadPic(const char *name)
{
return (mpic_t*)(qintptr_t)drawfuncs->LoadImage(name, true);
char ftename[MAX_QPATH];
Q_snprintf(ftename, sizeof(ftename), "gfx/%s.lmp", name);
return (mpic_t*)(qintptr_t)drawfuncs->LoadImage(ftename);
}
mpic_t *SCR_LoadCursorImage(char *cursorimage)
@ -506,40 +508,10 @@ void EZHud_UseNquake_f(void)
cmdfuncs->AddText(hudstr, true);
}
static struct
{
xcommand_t cmd;
const char *name;
} concmds[128];
static int numconcmds;
qboolean Cmd_AddCommand (const char *funcname, xcommand_t function)
{
if (numconcmds < sizeof(concmds)/sizeof(concmds[0]))
{
concmds[numconcmds].cmd = function;
concmds[numconcmds].name = funcname;
numconcmds++;
cmdfuncs->AddCommand(funcname);
return true;
}
Con_Printf("ezhud: too many console commands\n");
return false;
return cmdfuncs->AddCommand(funcname, function, NULL);
};
static qboolean QDECL EZHud_ExecuteCommand(qboolean isinsecure)
{
char buffer[128];
int i;
cmdfuncs->Argv(0, buffer, sizeof(buffer));
for (i = 0; i < numconcmds; i++)
{
if (!strcmp(buffer, concmds[i].name))
{
concmds[i].cmd();
return 1;
}
}
return 0;
}
int IN_BestWeapon(void)
{
@ -743,8 +715,7 @@ qboolean Plug_Init(void)
if (cvarfuncs && drawfuncs && clientfuncs && filefuncs && inputfuncs &&
plugfuncs->ExportFunction("SbarBase", EZHud_Draw) &&
plugfuncs->ExportFunction("MenuEvent", EZHud_MenuEvent) &&
plugfuncs->ExportFunction("Tick", EZHud_Tick) &&
plugfuncs->ExportFunction("ExecuteCommand", EZHud_ExecuteCommand))
plugfuncs->ExportFunction("Tick", EZHud_Tick))
{
Cmd_AddCommand("ezhud_nquake", EZHud_UseNquake_f);
HUD_Init();

View File

@ -29,31 +29,16 @@ enum tlsmode_e
TLS_STARTING //don't send any nick/user/pass info while this is set
};
#define irccvars "IRC Console Variables"
static vmcvar_t irc_debug = {"irc_debug", "0", irccvars, 0};
static vmcvar_t irc_motd = {"irc_motd", "0", irccvars, 0};
static vmcvar_t irc_nick = {"irc_nick", "", irccvars, 0};
static vmcvar_t irc_altnick = {"irc_altnick", "", irccvars, 0};
static vmcvar_t irc_realname = {"irc_realname", "FTE IRC-Plugin", irccvars, 0};
static vmcvar_t irc_hostname = {"irc_hostname", "localhost", irccvars, 0};
static vmcvar_t irc_username = {"irc_username", "FTE", irccvars, 0};
static vmcvar_t irc_timestamp = {"irc_timestamp", "0", irccvars, 0};
static vmcvar_t irc_quitmessage = {"irc_quitmessage", "", irccvars, 0};
static vmcvar_t irc_config = {"irc_config", "1", irccvars, 0};
#undef irccvars
static vmcvar_t *cvarlist[] ={
&irc_debug,
&irc_motd,
&irc_nick,
&irc_altnick,
&irc_realname,
&irc_hostname,
&irc_username,
&irc_timestamp,
&irc_quitmessage,
NULL
};
static cvar_t *irc_debug;// = {"irc_debug", "0", irccvars, 0};
static cvar_t *irc_motd;// = {"irc_motd", "0", irccvars, 0};
static cvar_t *irc_nick;// = {"irc_nick", "", irccvars, 0};
static cvar_t *irc_altnick;// = {"irc_altnick", "", irccvars, 0};
static cvar_t *irc_realname;// = {"irc_realname", "FTE IRC-Plugin", irccvars, 0};
static cvar_t *irc_hostname;// = {"irc_hostname", "localhost", irccvars, 0};
static cvar_t *irc_username;// = {"irc_username", "FTE", irccvars, 0};
static cvar_t *irc_timestamp;// = {"irc_timestamp", "0", irccvars, 0};
static cvar_t *irc_quitmessage;// = {"irc_quitmessage", "", irccvars, 0};
static cvar_t *irc_config;// = {"irc_config", "1", irccvars, 0};
static icefuncs_t *piceapi;
static int next_window_x;
@ -378,29 +363,21 @@ static void IRC_Printf(ircclient_t *irc, const char *subname, const char *format
static void IRC_InitCvars(void)
{
vmcvar_t *v;
int i;
for (i=0; cvarlist[i]; i++)
{
v = cvarlist[i];
v->handle = cvarfuncs->Register(v->name, v->string, v->flags, v->group);
}
}
static int IRC_CvarUpdate(void) // perhaps void instead?
{
vmcvar_t *v;
int i;
for (i=0; cvarlist[i]; i++)
{
v = cvarlist[i];
cvarfuncs->Update(v->handle, &v->modificationcount, v->string, sizeof(v->string), &v->value);
}
return 0;
const char *cvargroup = "IRC Console Variables";
irc_debug = cvarfuncs->GetNVFDG("irc_debug", "0", 0, NULL, cvargroup);
irc_motd = cvarfuncs->GetNVFDG("irc_motd", "0", 0, NULL, cvargroup);
irc_nick = cvarfuncs->GetNVFDG("irc_nick", "", 0, NULL, cvargroup);
irc_altnick = cvarfuncs->GetNVFDG("irc_altnick", "", 0, NULL, cvargroup);
irc_realname = cvarfuncs->GetNVFDG("irc_realname", "FTE IRC-Plugin", 0, NULL, cvargroup);
irc_hostname = cvarfuncs->GetNVFDG("irc_hostname", "localhost", 0, NULL, cvargroup);
irc_username = cvarfuncs->GetNVFDG("irc_username", "FTE", 0, NULL, cvargroup);
irc_timestamp = cvarfuncs->GetNVFDG("irc_timestamp", "0", 0, NULL, cvargroup);
irc_quitmessage = cvarfuncs->GetNVFDG("irc_quitmessage", "", 0, NULL, cvargroup);
irc_config = cvarfuncs->GetNVFDG("irc_config", "1", 0, NULL, cvargroup);
}
void IRC_Command(ircclient_t *ircclient, char *dest, char *args);
qboolean IRC_ExecuteCommand(qboolean isinsecure);
void IRC_ExecuteCommand_f(void);
int IRC_ConExecuteCommand(qboolean isinsecure);
void IRC_Frame(double realtime, double gametime);
qboolean IRC_ConsoleLink(void);
@ -416,10 +393,9 @@ qboolean Plug_Init(void)
if (netfuncs &&
filefuncs &&
plugfuncs->ExportFunction("Tick", IRC_Frame) &&
plugfuncs->ExportFunction("ExecuteCommand", IRC_ExecuteCommand))
plugfuncs->ExportFunction("Tick", IRC_Frame))
{
cmdfuncs->AddCommand(COMMANDNAME);
cmdfuncs->AddCommand(COMMANDNAME, IRC_ExecuteCommand_f, "Internet Relay Chat client, use ^[/"COMMANDNAME" /help^] for help");
plugfuncs->ExportFunction("ConsoleLink", IRC_ConsoleLink);
if (!confuncs || !plugfuncs->ExportFunction("ConExecuteCommand", IRC_ConExecuteCommand))
@ -441,20 +417,13 @@ qboolean Plug_Init(void)
qboolean IRC_ExecuteCommand(qboolean isinsecure)
void IRC_ExecuteCommand_f(void)
{
char cmd[256];
cmdfuncs->Argv(0, cmd, sizeof(cmd));
if (!strcmp(cmd, COMMANDNAME))
{
ircclient_t *ircclient = ircclients;
char imsg[8192];
cmdfuncs->Args(imsg, sizeof(imsg));
//FIXME: select an irc network more inteligently
IRC_Command(ircclient, ircclient?ircclient->defaultdest:"", imsg);
return true;
}
return false;
ircclient_t *ircclient = ircclients;
char imsg[8192];
cmdfuncs->Args(imsg, sizeof(imsg));
//FIXME: select an irc network more inteligently
IRC_Command(ircclient, ircclient?ircclient->defaultdest:"", imsg);
}
int IRC_ConExecuteCommand(qboolean isinsecure)
{
@ -500,7 +469,7 @@ static void IRC_AddClientMessage(ircclient_t *irc, char *msg)
memcpy(irc->bufferedoutmessage + irc->bufferedoutammount, output, len);
irc->bufferedoutammount += len;
if (irc_debug.value == 1) { IRC_Printf(irc, DEFAULTCONSOLE,COLOURYELLOW "<< %s \n",msg); }
if (irc_debug->value == 1) { IRC_Printf(irc, DEFAULTCONSOLE,COLOURYELLOW "<< %s \n",msg); }
}
static ircclient_t *IRC_FindAccount(const char *server)
@ -534,8 +503,6 @@ static ircclient_t *IRC_Create(const char *server, const char *nick, const char
Q_strlcpy(irc->server, server, sizeof(irc->server));
IRC_CvarUpdate();
Q_strlcpy(irc->primarynick, nick, sizeof(irc->primarynick));
Q_strlcpy(irc->nick, nick, sizeof(irc->nick));
Q_strlcpy(irc->realname, realname, sizeof(irc->realname));
@ -570,8 +537,6 @@ static void IRC_SetNick(ircclient_t *irc, char *nick)
}
static void IRC_SetUser(ircclient_t *irc, char *user)
{
IRC_CvarUpdate();
if (irc->tlsmode != TLS_STARTING)
{
const char *username = irc->username;
@ -632,7 +597,7 @@ static qboolean IRC_Establish(ircclient_t *irc)
irc->nicktries = 0;
IRC_SetPass(irc, irc->pwd);
IRC_SetNick(irc, irc->nick);
IRC_SetUser(irc, irc_username.string);
IRC_SetUser(irc, irc_username->string);
}
return true;
@ -692,7 +657,7 @@ static void IRC_WriteConfig(void)
{
qhandle_t config;
if (irc_config.value == 0)
if (irc_config->value == 0)
return;
filefuncs->Open("**plugconfig", &config, 2);
@ -981,8 +946,6 @@ static void IRC_TryNewNick(ircclient_t *irc, char *nickname)
{
char *seedednick;
IRC_CvarUpdate();
if (irc->tlsmode == TLS_STARTING)
{
//don't submit any of this info here.
@ -1002,18 +965,18 @@ static void IRC_TryNewNick(ircclient_t *irc, char *nickname)
if (irc->nicktries == 1)
{
irc->nicktries++;
if (*irc_nick.string && strcmp(nickname, irc_nick.string))
if (*irc_nick->string && strcmp(nickname, irc_nick->string))
{
IRC_SetNick(irc, irc_nick.string);
IRC_SetNick(irc, irc_nick->string);
return;
}
}
if (irc->nicktries == 2)
{
irc->nicktries++;
if (*irc_altnick.string && strcmp(nickname, irc_altnick.string))
if (*irc_altnick->string && strcmp(nickname, irc_altnick->string))
{
IRC_SetNick(irc, irc_altnick.string);
IRC_SetNick(irc, irc_altnick->string);
return;
}
}
@ -1028,10 +991,10 @@ static void IRC_TryNewNick(ircclient_t *irc, char *nickname)
//IRC_Printf(irc, DEFAULTCONSOLE, COLOURRED "ERROR: primary nickname in use. Attempting random nickname.\n");
if (*irc->primarynick && irc->nicktries < 7)
seedednick = va("%.6s%i", irc->primarynick, rand());
else if (*irc_nick.string && irc->nicktries < 8)
seedednick = va("%.6s%i", irc_nick.string, rand());
else if (*irc_altnick.string && irc->nicktries < 9)
seedednick = va("%.6s%i", irc_altnick.string, rand());
else if (*irc_nick->string && irc->nicktries < 8)
seedednick = va("%.6s%i", irc_nick->string, rand());
else if (*irc_altnick->string && irc->nicktries < 9)
seedednick = va("%.6s%i", irc_altnick->string, rand());
else
seedednick = va("%.6s%i", "FTE", rand());
seedednick[9] = 0; //'Each client is distinguished from other clients by a unique nickname having a maximum length of nine (9) characters'
@ -1057,7 +1020,7 @@ static void numbered_command(int comm, char *msg, ircclient_t *irc) // move vars
if (irc->tlsmode != TLS_STARTING)
irc->connecting = 0; // ok we are connected
if (irc_motd.value)
if (irc_motd->value)
IRC_Printf(irc, DEFAULTCONSOLE, COLOURYELLOW "SERVER STATS: %s\n",casevar[3]);
return;
}
@ -1068,13 +1031,13 @@ static void numbered_command(int comm, char *msg, ircclient_t *irc) // move vars
// }
case 20: /* RPL_HELLO */
{
if (irc_motd.value)
if (irc_motd->value)
IRC_Printf(irc, DEFAULTCONSOLE, COLOURYELLOW "%s\n",casevar[3]);
return;
}
case 42: /*RPL_YOURID */
{
if (irc_motd.value)
if (irc_motd->value)
IRC_Printf(irc, DEFAULTCONSOLE, COLOURYELLOW "%s\n",casevar[3]);
return;
}
@ -1091,7 +1054,7 @@ static void numbered_command(int comm, char *msg, ircclient_t *irc) // move vars
case 265:
case 266:
{
if (irc_motd.value)
if (irc_motd->value)
IRC_Printf(irc, DEFAULTCONSOLE, COLOURYELLOW "SERVER STATS: %s\n",casevar[3]);
return;
}
@ -1211,11 +1174,9 @@ static void numbered_command(int comm, char *msg, ircclient_t *irc) // move vars
{
char *motdmessage = casevar[3]+1;
IRC_CvarUpdate();
if (irc_motd.value == 2)
if (irc_motd->value == 2)
IRC_Printf(irc, DEFAULTCONSOLE, "MOTD: %s\n", motdmessage);
else if (irc_motd.value)
else if (irc_motd->value)
IRC_Printf(irc, DEFAULTCONSOLE, "%s\n", motdmessage);
if (*irc->autochannels)
@ -1318,7 +1279,7 @@ static void numbered_command(int comm, char *msg, ircclient_t *irc) // move vars
irc->nicktries = 0;
IRC_SetPass(irc, irc->pwd);
IRC_SetNick(irc, irc->nick);
IRC_SetUser(irc, irc_username.string);
IRC_SetUser(irc, irc_username->string);
return;
}
case 691: /* ERR_STARTTLS */
@ -1937,10 +1898,8 @@ static int IRC_ClientFrame(ircclient_t *irc)
}
IRC_CvarUpdate(); // is this the right place for it?
// if (irc_debug.value == 1) { IRC_Printf(irc, DEFAULTCONSOLE,COLOURRED "!!!!! ^11: %s ^22: %s ^33: %s ^44: %s ^55: %s ^66: %s ^77: %s ^88: %s\n",var[1],var[2],var[3],var[4],var[5],var[6],var[7],var[8]); }
if (irc_debug.value == 1) { IRC_Printf(irc, DEFAULTCONSOLE,COLOURRED "%s\n",var[1]); }
// if (irc_debug->value == 1) { IRC_Printf(irc, DEFAULTCONSOLE,COLOURRED "!!!!! ^11: %s ^22: %s ^33: %s ^44: %s ^55: %s ^66: %s ^77: %s ^88: %s\n",var[1],var[2],var[3],var[4],var[5],var[6],var[7],var[8]); }
if (irc_debug->value == 1) { IRC_Printf(irc, DEFAULTCONSOLE,COLOURRED "%s\n",var[1]); }
if (*msg == ':') //we need to strip off the prefix
{
@ -2005,7 +1964,7 @@ static int IRC_ClientFrame(ircclient_t *irc)
to++;
for (end = to + strlen(to)-1; end >= to && *end <= ' '; end--)
*end = '\0';
if (!strcmp(to, irc_nick.string))
if (!strcmp(to, irc_nick->string))
to = prefix; //This was directed straight at us.
//So change the 'to', to the 'from'.
@ -2258,7 +2217,7 @@ static int IRC_ClientFrame(ircclient_t *irc)
else if (!strncmp(msg, "372 ", 4))
{
char *text = strstr(msg, ":-");
if (!*irc->autochannels || irc_motd.value)
if (!*irc->autochannels || irc_motd->value)
{
if (text)
IRC_Printf(irc, DEFAULTCONSOLE, "%s\n", text+2);
@ -2395,9 +2354,7 @@ static int IRC_ClientFrame(ircclient_t *irc)
numbered_command(atoi(var[2]), msg, irc);
IRC_CvarUpdate();
if (irc_debug.value == 1) { IRC_Printf(irc, DEFAULTCONSOLE, "%s\n", msg); }
if (irc_debug->value == 1) { IRC_Printf(irc, DEFAULTCONSOLE, "%s\n", msg); }
}
else
IRC_Printf(irc, DEFAULTCONSOLE, "%s\n", msg);
@ -2488,7 +2445,7 @@ void IRC_Command(ircclient_t *ircclient, char *dest, char *args)
//set up some defaults
if (!*nick)
Q_strlcpy(nick, irc_nick.string, sizeof(nick));
Q_strlcpy(nick, irc_nick->string, sizeof(nick));
if (!*nick)
cvarfuncs->GetString("name", nick, sizeof(nick));
@ -2502,7 +2459,7 @@ void IRC_Command(ircclient_t *ircclient, char *dest, char *args)
}
}
else
ircclient = IRC_Create(server, nick, irc_realname.string, irc_hostname.string, irc_username.string, password, channels);
ircclient = IRC_Create(server, nick, irc_realname->string, irc_hostname->string, irc_username->string, password, channels);
if (ircclient)
{
IRC_MakeDefault(ircclient);
@ -2529,7 +2486,7 @@ void IRC_Command(ircclient_t *ircclient, char *dest, char *args)
{
msg = COM_Parse(msg, token, sizeof(token));
if (!ircclient) //not yet connected.
cvarfuncs->SetString(irc_nick.name, token);
cvarfuncs->SetString(irc_nick->name, token);
else
{
if (!handleisvalid(ircclient->socket))
@ -2543,7 +2500,7 @@ void IRC_Command(ircclient_t *ircclient, char *dest, char *args)
else if (!strcmp(token+1, "user"))
{
msg = COM_Parse(msg, token, sizeof(token));
cvarfuncs->SetString(irc_username.name, token);
cvarfuncs->SetString(irc_username->name, token);
if (ircclient)
IRC_SetUser(ircclient, token);
@ -2723,7 +2680,7 @@ void IRC_Command(ircclient_t *ircclient, char *dest, char *args)
if (*token)
IRC_AddClientMessage(ircclient, va("QUIT :%s", token));
else
IRC_AddClientMessage(ircclient, va("QUIT :%s", irc_quitmessage.string));
IRC_AddClientMessage(ircclient, va("QUIT :%s", irc_quitmessage->string));
ircclient->quitting = true;
IRC_WriteConfig();

View File

@ -867,23 +867,21 @@ static struct {
{NULL}
};
qboolean JCL_ExecuteCommand(qboolean isinsecure)
static void JCL_ExecuteCommand_f(void)
{
qboolean isinsecure = cmdfuncs->IsInsecure();
char cmd[256];
cmdfuncs->Argv(0, cmd, sizeof(cmd));
if (!strcmp(cmd, COMMANDPREFIX) || !strcmp(cmd, COMMANDPREFIX2) || !strcmp(cmd, COMMANDPREFIX3))
{
if (!isinsecure || cmdfuncs->Argc() == 1)
JCL_Command(0, "");
return true;
}
if (!strncmp(cmd, COMMANDPREFIX, strlen(COMMANDPREFIX)))
else if (!strncmp(cmd, COMMANDPREFIX, strlen(COMMANDPREFIX)))
{
if (!isinsecure || cmdfuncs->Argc() == 1)
JCL_Command(atoi(cmd+strlen(COMMANDPREFIX)), "");
return true;
}
return false;
}
qboolean JCL_ConsoleLink(void);
@ -903,6 +901,7 @@ static void QDECL JCL_UpdateVideo(int width, int height)
qboolean Plug_Init(void)
{
const char *cmddesc = "XMPP client - ^[/"COMMANDPREFIX" /help^] for help.";
jclient_needreadconfig = true;
confuncs = (plugsubconsolefuncs_t*)plugfuncs->GetEngineInterface(plugsubconsolefuncs_name, sizeof(*confuncs));
@ -913,8 +912,7 @@ qboolean Plug_Init(void)
if (netfuncs && filefuncs &&
plugfuncs->ExportFunction("Tick", JCL_Frame) &&
plugfuncs->ExportFunction("Shutdown", JCL_Shutdown) &&
plugfuncs->ExportFunction("ExecuteCommand", JCL_ExecuteCommand))
plugfuncs->ExportFunction("Shutdown", JCL_Shutdown))
{
Con_Printf("XMPP Plugin Loaded. For help, use: ^[/"COMMANDPREFIX" /help^]\n");
@ -931,26 +929,26 @@ qboolean Plug_Init(void)
else
Con_TrySubPrint = confuncs->SubPrint;
cmdfuncs->AddCommand(COMMANDPREFIX);
cmdfuncs->AddCommand(COMMANDPREFIX2);
cmdfuncs->AddCommand(COMMANDPREFIX3);
cmdfuncs->AddCommand(COMMANDPREFIX, JCL_ExecuteCommand_f, cmddesc);
cmdfuncs->AddCommand(COMMANDPREFIX2, JCL_ExecuteCommand_f, cmddesc);
cmdfuncs->AddCommand(COMMANDPREFIX3, JCL_ExecuteCommand_f, cmddesc);
cmdfuncs->AddCommand(COMMANDPREFIX"0");
cmdfuncs->AddCommand(COMMANDPREFIX"1");
cmdfuncs->AddCommand(COMMANDPREFIX"2");
cmdfuncs->AddCommand(COMMANDPREFIX"3");
cmdfuncs->AddCommand(COMMANDPREFIX"4");
cmdfuncs->AddCommand(COMMANDPREFIX"5");
cmdfuncs->AddCommand(COMMANDPREFIX"6");
cmdfuncs->AddCommand(COMMANDPREFIX"7");
cmdfuncs->AddCommand(COMMANDPREFIX"0", JCL_ExecuteCommand_f, cmddesc);
cmdfuncs->AddCommand(COMMANDPREFIX"1", JCL_ExecuteCommand_f, cmddesc);
cmdfuncs->AddCommand(COMMANDPREFIX"2", JCL_ExecuteCommand_f, cmddesc);
cmdfuncs->AddCommand(COMMANDPREFIX"3", JCL_ExecuteCommand_f, cmddesc);
cmdfuncs->AddCommand(COMMANDPREFIX"4", JCL_ExecuteCommand_f, cmddesc);
cmdfuncs->AddCommand(COMMANDPREFIX"5", JCL_ExecuteCommand_f, cmddesc);
cmdfuncs->AddCommand(COMMANDPREFIX"6", JCL_ExecuteCommand_f, cmddesc);
cmdfuncs->AddCommand(COMMANDPREFIX"7", JCL_ExecuteCommand_f, cmddesc);
//flags&1 == archive
cvarfuncs->Register("xmpp_nostatus", "0", 0, "xmpp");
cvarfuncs->Register("xmpp_showstatusupdates", "0", 0, "xmpp");
cvarfuncs->Register("xmpp_autoacceptjoins", "0", 0, "xmpp");
cvarfuncs->Register("xmpp_autoacceptinvites", "0", 0, "xmpp");
cvarfuncs->Register("xmpp_autoacceptvoice", "0", 0, "xmpp");
cvarfuncs->Register("xmpp_debug", "0", 0, "xmpp");
cvarfuncs->GetNVFDG("xmpp_nostatus", "0", 0, NULL, "xmpp");
cvarfuncs->GetNVFDG("xmpp_showstatusupdates", "0", 0, NULL, "xmpp");
cvarfuncs->GetNVFDG("xmpp_autoacceptjoins", "0", 0, NULL, "xmpp");
cvarfuncs->GetNVFDG("xmpp_autoacceptinvites", "0", 0, NULL, "xmpp");
cvarfuncs->GetNVFDG("xmpp_autoacceptvoice", "0", 0, NULL, "xmpp");
cvarfuncs->GetNVFDG("xmpp_debug", "0", 0, NULL, "xmpp");
#ifdef JINGLE
piceapi = plugfuncs->GetEngineInterface(ICE_API_CURRENT, sizeof(*piceapi));

View File

@ -818,28 +818,22 @@ extern qboolean QDECL Mod_LoadGLTFModel (struct model_s *mod, void *buffer, size
extern qboolean QDECL Mod_LoadGLBModel (struct model_s *mod, void *buffer, size_t fsize);
extern void Mod_ExportIQM(char *fname, int flags, galiasinfo_t *mesh);
qboolean Mod_ExecuteCommand(qboolean isinsecure)
#if !defined(SERVERONLY) && defined(SKELETALMODELS)
static void Mod_ExportIQM_f(void)
{
char tok[128];
cmdfuncs->Argv(0, tok, sizeof(tok));
#if !defined(SERVERONLY) && defined(SKELETALMODELS)
if (!strcmp(tok, "exportiqm"))
model_t *mod;
cmdfuncs->Argv(1, tok, sizeof(tok));
mod = modfuncs->GetModel(tok, MLV_WARNSYNC);
if (!mod || mod->type != mod_alias || !mod->meshinfo)
Con_Printf("Couldn't load \"%s\"\n", tok);
else
{
model_t *mod;
cmdfuncs->Argv(1, tok, sizeof(tok));
mod = modfuncs->GetModel(tok, MLV_WARNSYNC);
if (!mod || mod->type != mod_alias || !mod->meshinfo)
Con_Printf("Couldn't load \"%s\"\n", tok);
else
{
cmdfuncs->Argv(2, tok, sizeof(tok));
Mod_ExportIQM(tok, mod->flags, mod->meshinfo);
}
return true;
cmdfuncs->Argv(2, tok, sizeof(tok));
Mod_ExportIQM(tok, mod->flags, mod->meshinfo);
}
#endif
return false;
}
#endif
qboolean Plug_Init(void)
{
@ -860,8 +854,9 @@ qboolean Plug_Init(void)
Plug_GLTF_Init();
#endif
plugfuncs->ExportFunction("ExecuteCommand", Mod_ExecuteCommand);
cmdfuncs->AddCommand("exportiqm");
#if !defined(SERVERONLY) && defined(SKELETALMODELS)
cmdfuncs->AddCommand("exportiqm", Mod_ExportIQM_f, NULL);
#endif
return true;
}
return false;

View File

@ -37,10 +37,10 @@ static void LoadPics(void)
char buffer[256];
//main bar (add cvars later)
con_chars = drawfuncs->LoadImage("gfx/conchars.lmp", false);
con_chars = drawfuncs->LoadImage("gfx/conchars.lmp");
cvarfuncs->GetString("cl_cursor", buffer, sizeof(buffer));
if (*buffer)
pic_cursor = drawfuncs->LoadImage(buffer, false);
pic_cursor = drawfuncs->LoadImage(buffer);
else
pic_cursor = 0;
}
@ -171,18 +171,11 @@ static qboolean QDECL Plug_MenuEvent(int eventtype, int param, int unicode, floa
return 0;
}
static qboolean Plug_ExecuteCommand(qboolean isinsecure)
static void Plug_NameMaker_f(void)
{
char cmd[256];
cmdfuncs->Argv(0, cmd, sizeof(cmd));
if (!strcmp("namemaker", cmd))
{
inputfuncs->SetMenuFocus(true, NULL, 0, 0, 0); //grab input focus
cvarfuncs->GetString("name", (char*)namebuffer, sizeof(namebuffer));
insertpos = strlen(namebuffer);
return 1;
}
return 0;
inputfuncs->SetMenuFocus(true, NULL, 0, 0, 0); //grab input focus
cvarfuncs->GetString("name", (char*)namebuffer, sizeof(namebuffer));
insertpos = strlen(namebuffer);
}
qboolean Plug_Init(void)
@ -192,7 +185,6 @@ qboolean Plug_Init(void)
if (drawfuncs && inputfuncs &&
// plugfuncs->ExportFunction("SbarBase", UI_StatusBar) &&
// plugfuncs->ExportFunction("SbarOverlay", UI_ScoreBoard) &&
plugfuncs->ExportFunction("ExecuteCommand", Plug_ExecuteCommand) &&
plugfuncs->ExportFunction("MenuEvent", Plug_MenuEvent))
{
@ -213,7 +205,7 @@ qboolean Plug_Init(void)
K_PAGEDOWN = inputfuncs->GetKeyCode("pgdn", NULL);
K_BACKSPACE = inputfuncs->GetKeyCode("backspace", NULL);
cmdfuncs->AddCommand("namemaker");
cmdfuncs->AddCommand("namemaker", Plug_NameMaker_f, "Provides a simple way to select from quake's glyphs.");
LoadPics();

View File

@ -886,7 +886,7 @@ static qboolean XR_Init(vrsetup_t *qreqs, rendererstate_t *info)
return true;
}
static qboolean XR_HapticCommand_f(qboolean isinsecure)
static void XR_HapticCommand_f(void)
{
size_t u;
char actionname[XR_MAX_ACTION_NAME_SIZE];
@ -910,10 +910,9 @@ static qboolean XR_HapticCommand_f(qboolean isinsecure)
haptic.frequency = *actionname?atof(actionname):XR_FREQUENCY_UNSPECIFIED;
xrApplyHapticFeedback(xr.session, &info, (XrHapticBaseHeader*)&haptic);
}
return true;
break;
}
}
return false;
}
static XrAction XR_DefineAction(enum actset_e set, XrActionType type, const char *name, const char *description, const char *root)
@ -994,7 +993,7 @@ static XrAction XR_DefineAction(enum actset_e set, XrActionType type, const char
Con_Printf("openxr: Unable to create action %s [%s] - %s\n", info.actionName, info.localizedActionName, XR_StringForResult(res));
if (info.actionType == XR_ACTION_TYPE_VIBRATION_OUTPUT)
cmdfuncs->AddCommand(xr.actions[u].actname);
cmdfuncs->AddCommand(xr.actions[u].actname, XR_HapticCommand_f, "Linked to an OpenXR haptic feedback.");
return xr.actions[u].action;
}
@ -2285,7 +2284,6 @@ qboolean Plug_Init(void)
fsfuncs = plugfuncs->GetEngineInterface(plugfsfuncs_name, sizeof(*fsfuncs));
inputfuncs = plugfuncs->GetEngineInterface(pluginputfuncs_name, sizeof(*inputfuncs));
plugfuncs->ExportFunction("MayUnload", XR_PluginMayUnload);
plugfuncs->ExportFunction("ExecuteCommand", XR_HapticCommand_f);
if (plugfuncs->ExportInterface(plugvrfuncs_name, &openxr, sizeof(openxr)))
{
xr_enable = cvarfuncs->GetNVFDG("xr_enable", "1", 0, "Controls whether to use openxr rendering or not.", "OpenXR configuration");

View File

@ -255,6 +255,31 @@ void Sys_Errorf(const char *format, ...)
plugfuncs->Error(string);
}
qboolean ZF_ReallocElements(void **ptr, size_t *elements, size_t newelements, size_t elementsize)
{
void *n;
size_t oldsize;
size_t newsize;
//protect against malicious overflows
if (newelements > SIZE_MAX / elementsize)
return false;
oldsize = *elements * elementsize;
newsize = newelements * elementsize;
n = plugfuncs->Realloc(*ptr, newsize);
if (!n)
return false;
if (newsize > oldsize)
memset((char*)n+oldsize, 0, newsize - oldsize);
*elements = newelements;
*ptr = n;
return true;
}
#ifdef __cplusplus
extern "C"
#endif

View File

@ -15,10 +15,13 @@
#define false qfalse
#define true qtrue
#endif
typedef float vec4_t[4];
typedef float vec3_t[3];
typedef float vec2_t[2];
typedef unsigned char qbyte;
#include <stdint.h>
#define qint64_t int64_t
#define quint64_t uint64_t
typedef quint64_t qofs_t;
@ -184,6 +187,7 @@ struct wstats_s;
#define F(t, n, args) t (QDECL *n) args
#define dllhandle_t void
struct dllfunction_s;
struct zonegroup_s;
typedef struct //core stuff
{
//Basic builtins:
@ -192,8 +196,12 @@ typedef struct //core stuff
F(qboolean, ExportInterface, (const char *interfacename, void *interfaceptr, size_t structsize)); //export a named interface struct to the engine
F(qboolean, GetPluginName, (int plugnum, char *buffer, size_t bufsize)); //query loaded plugin names. -1 == active plugin
F(void, Print, (const char *message)); //print on (main) console.
F(void, Error, (const char *message)); //abort the entire engine.
F(void, Error, (const char *message, ...)); //abort the entire engine.
F(void, EndGame, (const char *reason, ...)); //some sort of networking problem happened and we need to disconnect. Engine can continue running (displaying the message to the user).
F(quintptr_t,GetMilliseconds, (void));
F(double, GetSeconds, (void));
//for soft linking (with more readable error messages).
F(dllhandle_t*,LoadDLL, (const char *modulename, struct dllfunction_s *funcs));
F(void*, GetDLLSymbol, (dllhandle_t *handle, const char *symbolname));
F(void, CloseDLL, (dllhandle_t *handle)); //not guarenteed to actually do anything, of course.
@ -205,6 +213,7 @@ typedef struct //core stuff
//for lazy mallocs
F(void*, GMalloc, (struct zonegroup_s *ctx, size_t size));
F(void, GFree, (struct zonegroup_s *ctx, void *ptr));
F(void, GFreeAll, (struct zonegroup_s *ctx));
#define plugcorefuncs_name "Core"
} plugcorefuncs_t;
@ -233,12 +242,14 @@ typedef struct //console command/tokenizing/cbuf functions
F(char *, ParsePunctuation, (const char *data, const char *punctuation, char *token, size_t tokenlen, enum com_tokentype_e *tokentype)); //use explicit punctuation.
F(void, TokenizeString, (const char *msg)); //tokenize a string.
F(void, ShiftArgs, (int args)); //updates tokenize state to ignore arg 0 (and updates Args).
F(void, Args, (char *buffer, int bufsize)); //Gets the extra args
F(void, Argv, (int argnum, char *buffer, size_t bufsize)); //Gets a 0-based token
F(char *, Argv, (int argnum, char *buffer, size_t bufsize)); //Gets a 0-based token
F(int, Argc, (void)); //gets the number of tokens available.
F(qboolean, AddCommand, (const char *cmdname)); //Registers a console command.
F(qboolean, IsInsecure, (void));
F(qboolean, AddCommand, (const char *cmdname, void (*func)(void), const char *desc)); //Registers a console command.
F(void, AddText, (const char *text, qboolean insert));
#define plugcmdfuncs_name "Cmd"
@ -250,16 +261,24 @@ typedef struct //console command and cbuf functions
F(void, SetFloat, (const char *name, float value));
F(qboolean, GetString, (const char *name, char *retstring, quintptr_t sizeofretstring));
F(float, GetFloat, (const char *name));
F(qhandle_t,Register, (const char *name, const char *defaultval, int flags, const char *grouphint));
F(qboolean, Update, (qhandle_t handle, int *modificationcount, char *outstringv, size_t stringsize, float *outfloatv)); //stringv is 256 chars long, don't expect this function to do anything if modification count is unchanged.
F(cvar_t*, GetNVFDG, (const char *name, const char *defaultval, unsigned int flags, const char *description, const char *groupname));
F(void, ForceSetString, (const char *name, const char *value));
#define plugcvarfuncs_name "Cvar"
} plugcvarfuncs_t;
typedef struct
{
F(void, LocalSound, (const char *soundname, int channel, float volume));
F(void, RawAudio, (int sourceid, void *data, int speed, int samples, int channels, int width, float volume));
F(void, LocalSound, (const char *soundname, int channel, float volume));
F(void, RawAudio, (int sourceid, void *data, int speed, int samples, int channels, int width, float volume));
F(void, Spacialize, (unsigned int seat, int entnum, vec3_t origin, vec3_t *axis, int reverb, vec3_t velocity));
F(qboolean, UpdateReverb, (size_t slot, void *reverb, size_t reverbsize));
F(struct sfx_s*,PrecacheSound, (const char *sample));
F(void, StartSound, (int entnum, int entchannel, struct sfx_s *sfx, vec3_t origin, vec3_t velocity, float fvol, float attenuation, float timeofs, float pitchadj, unsigned int flags));
F(float, GetChannelLevel, (int entnum, int entchannel));
F(int, Voip_ClientLoudness,(unsigned int plno));
F(qboolean, ChangeMusicTrack, (const char *initialtrack, const char *looptrack));
#define plugaudiofuncs_name "Audio"
} plugaudiofuncs_t;
@ -290,21 +309,33 @@ typedef struct //q1 client/network info
F(int, GetWeaponStats, (int player, struct wstats_s *result, size_t maxresults));
F(float, GetTrackerOwnFrags, (int seat, char *text, size_t textsize));
F(void, GetPredInfo, (int seat, vec3_t outvel));
F(void, ClearClientState, (void)); //called at the start of map changes.
F(void, UpdateGameTime, (double)); //tells the client an updated snapshot time for interpolation/timedrift.
#define plugclientfuncs_name "Client"
} plugclientfuncs_t;
struct menu_s;
typedef struct //for menu-like stuff
{
//for menus
F(qboolean, SetMenuFocus, (qboolean wantkeyfocus, const char *cursorname, float hot_x, float hot_y, float scale)); //null cursorname=relmouse, set/empty cursorname=absmouse
F(qboolean, HasMenuFocus, (void));
F(qboolean, SetMenuFocus, (qboolean wantkeyfocus, const char *cursorname, float hot_x, float hot_y, float scale)); //null cursorname=relmouse, set/empty cursorname=absmouse
F(qboolean, HasMenuFocus, (void));
F(void, Menu_Push, (struct menu_s *menu, qboolean prompt));
F(void, Menu_Unlink, (struct menu_s *menu, qboolean forced));
//for menu input
F(int, GetKeyCode, (const char *keyname, int *out_modifier));
F(const char*,GetKeyName, (int keycode, int modifier));
F(int, FindKeysForCommand,(int bindmap, const char *command, int *out_keycodes, int *out_modifiers, int maxkeys));
F(const char*,GetKeyBind, (int bindmap, int keynum, int modifier));
F(void, SetKeyBind, (int bindmap, int keycode, int modifier, const char *newbinding));
F(int, GetKeyCode, (const char *keyname, int *out_modifier));
F(const char*, GetKeyName, (int keycode, int modifier));
F(int, FindKeysForCommand, (int bindmap, const char *command, int *out_keycodes, int *out_modifiers, int maxkeys));
F(const char*, GetKeyBind, (int bindmap, int keynum, int modifier));
F(void, SetKeyBind, (int bindmap, int keycode, int modifier, const char *newbinding));
F(qboolean, IsKeyDown, (int keycode));
F(void, ClearKeyStates, (void)); //forget any keys that are still held.
F(unsigned int, GetMoveCount, (void));
F(usercmd_t*, GetMoveEntry, (unsigned int move)); //GetMoveEntry(GetMoveCount()) gives you the partial entry. forgotten entries return NULL.
unsigned int (*GetKeyDest) (void);
void (*KeyEvent) (unsigned int devid, int down, int keycode, int unicode);
@ -316,14 +347,50 @@ typedef struct //for menu-like stuff
#define pluginputfuncs_name "Input"
} pluginputfuncs_t;
#if defined(FTEENGINE) || defined(FTEPLUGIN)
typedef struct
{
F(void, BeginReading, (sizebuf_t *sb, struct netprim_s prim));
F(int, ReadCount, (void));
F(int, ReadBits, (int bits));
F(int, ReadByte, (void));
F(int, ReadShort, (void));
F(int, ReadLong, (void));
F(void, ReadData, (void *data, int len));
F(char*, ReadString, (void));
F(void, BeginWriting, (sizebuf_t *sb, struct netprim_s prim, void *bufferstorage, size_t buffersize));
F(void, WriteBits, (sizebuf_t *sb, int value, int bits));
F(void, WriteByte, (sizebuf_t *sb, int c));
F(void, WriteShort, (sizebuf_t *sb, int c));
F(void, WriteLong, (sizebuf_t *sb, int c));
F(void, WriteData, (sizebuf_t *sb, const void *data, int len));
F(void, WriteString, (sizebuf_t *sb, const char *s));
F(qboolean, CompareAdr, (netadr_t *a, netadr_t *b));
F(qboolean, CompareBaseAdr, (netadr_t *a, netadr_t *b));
F(char*, AdrToString, (char *s, int len, netadr_t *a));
F(size_t, StringToAdr, (const char *s, int defaultport, netadr_t *a, size_t addrcount, const char **pathstart));
F(neterr_t, SendPacket, (struct ftenet_connections_s *col, int length, const void *data, netadr_t *to));
F(huffman_t*,Huff_CompressionCRC, (int crc));
F(void, Huff_EncryptPacket, (sizebuf_t *msg, int offset));
F(void, Huff_DecryptPacket, (sizebuf_t *msg, int offset));
#define plugmsgfuncs_name "Messaging"
} plugmsgfuncs_t;
#endif
typedef struct //for huds and menus alike
{
F(qboolean, GetVideoSize, (float *vsize, unsigned int *psize)); //returns false if there's no video yet...
//note: these use handles instead of shaders, to make them persistent over renderer restarts.
F(qhandle_t,LoadImageData, (const char *name, const char *mime, void *data, size_t datasize)); //load/replace a named texture
F(qhandle_t,LoadImageShader,(const char *name, const char *defaultshader)); //loads a shader.
F(qhandle_t,LoadImage, (const char *name, qboolean iswadimage)); //wad image is ONLY for loading out of q1 gfx.wad. loads a shader.
F(qhandle_t,LoadImage, (const char *name)); //wad image is ONLY for loading out of q1 gfx.wad. loads a shader. use gfx/foo.lmp for hud stuff.
F(struct shader_s*,ShaderFromId, (qhandle_t shaderid));
F(void, UnloadImage, (qhandle_t image));
F(int, Image, (float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t image));
F(int, Image2dQuad, (const vec2_t *points, const vec2_t *tcoords, const vec4_t *colours, qhandle_t image));
F(int, ImageSize, (qhandle_t image, float *x, float *y));
F(void, Fill, (float x, float y, float w, float h));
F(void, Line, (float x1, float y1, float x2, float y2));
@ -335,10 +402,95 @@ typedef struct //for huds and menus alike
F(void, Colourpa, (int palcol, float a)); //for legacy code
F(void, Colour4f, (float r, float g, float b, float a));
F(void, RedrawScreen, (void)); //redraws the entire screen and presents it. for loading screen type things.
F(void, LocalSound, (const char *soundname, int channel, float volume));
#define plug2dfuncs_name "2D"
} plug2dfuncs_t;
#if defined(FTEENGINE) || defined(FTEPLUGIN)
struct entity_s;
typedef struct
{
struct
{
float x,y,w,h;
} rect;
vec2_t fov;
vec2_t fov_viewmodel;
vec3_t viewaxisorg[4];
vec3_t skyroom_org;
float time;
unsigned int flags;
} plugrefdef_t;
typedef struct //for huds and menus alike
{
F(model_t *, LoadModel, (const char *modelname, enum mlverbosity_e sync));
F(qhandle_t, ModelToId, (model_t *model));
F(model_t *, ModelFromId, (qhandle_t modelid));
F(void, RemapShader, (const char *sourcename, const char *destname, float timeoffset));
F(qhandle_t, ShaderForSkin, (qhandle_t modelid, int surfaceidx, int skinnum, float time));
F(skinid_t, RegisterSkinFile, (const char *skinname));
F(skinfile_t *, LookupSkin, (skinid_t id));
F(int, TagNumForName, (struct model_s *model, const char *name, int firsttag));
F(qboolean, GetTag, (struct model_s *model, int tagnum, framestate_t *framestate, float *transforms));
F(void, ClipDecal, (struct model_s *mod, vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangent2, float size, unsigned int surfflagmask, unsigned int surflagmatch, void (*callback)(void *ctx, vec3_t *fte_restrict points, size_t numpoints, shader_t *shader), void *ctx));
F(void, NewMap, (model_t *worldmode));
F(void, ClearScene, (void));
F(void, AddEntity, (struct entity_s *ent));
F(unsigned int, AddPolydata, (struct shader_s *s, unsigned int befflags, size_t numverts, size_t numidx, vecV_t **vertcoord, vec2_t **texcoord, vec4_t **colour, index_t **indexes)); //allocates space for some polygons
F(dlight_t *, NewDlight, (int key, const vec3_t origin, float radius, float time, float r, float g, float b));
F(dlight_t *, AllocDlightOrg, (int keyidx, vec3_t keyorg));
F(qboolean, CalcModelLighting, (entity_t *e, model_t *clmodel));
F(void, RenderScene, (plugrefdef_t *viewer, size_t areabytes, const qbyte *areadata));
#define plug3dfuncs_name "3D"
} plug3dfuncs_t;
typedef struct //for collision stuff
{
F(model_t *, LoadModel, (const char *modelname, enum mlverbosity_e sync));
F(const char *, FixName, (const char *modname, const char *worldname));
F(const char *, GetEntitiesString, (struct model_s *mod));
F(qboolean, TransformedTrace, (struct model_s *model, int hulloverride, framestate_t *framestate, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, struct trace_s *trace, vec3_t origin, vec3_t angles, unsigned int hitcontentsmask));
F(model_t *, TempBoxModel, (const vec3_t mins, const vec3_t maxs));
//general things that probably shouldn't be here...
F(size_t, IBufToInfo, (infobuf_t *info, char *infostring, size_t maxsize, const char **priority, const char **ignore, const char **exclusive, infosync_t *sync, void *synccontext));
F(void, IBufFromInfo, (infobuf_t *info, const char *infostring, qboolean append));
F(qboolean, SetIBufKey, (infobuf_t *info, const char *key, const char *val));
F(char *, GetIBufKey, (infobuf_t *info, const char *key));
F(char*, GetInfoKey, (const char *s, const char *key));
F(void, SetInfoKey, (char *s, const char *key, const char *value, int maxsize));
//server things, shouldn't really be here but small. null in client-only builds
F(void, DropClient, (client_t *drop));
F(void, ExtractFromUserinfo,(client_t *cl, qboolean verbose));
F(qboolean, ChallengePasses, (int challenge));
#define plugworldfuncs_name "World"
} plugworldfuncs_t;
typedef struct //for querying master servers
{
F(size_t, StringToAdr, (const char *s, int defaultport, netadr_t *a, size_t numaddresses, const char **pathstart));
F(char *, AdrToString, (char *s, int len, netadr_t *a));
F(struct serverinfo_s*,InfoForServer,(netadr_t *addr, const char *brokerid));
F(qboolean, QueryServers, (void));
F(void, QueryServer, (struct serverinfo_s *server));
F(void, CheckPollSockets, (void));
F(unsigned int, TotalCount, (void));
F(struct serverinfo_s*,InfoForNum, (int num));
F(char *, ReadKeyString, (struct serverinfo_s *server, unsigned int keynum));
F(float, ReadKeyFloat, (struct serverinfo_s *server, unsigned int keynum));
F(void, WriteServers, (void));
F(char *, ServerToString, (char *s, int len, struct serverinfo_s *a));
#define plugmasterfuncs_name "Master"
} plugmasterfuncs_t;
#endif
struct flocation_s;
typedef struct //for plugins that need to read/write files...
{
F(int, Open, (const char *name, qhandle_t *handle, int mode));
@ -349,8 +501,12 @@ typedef struct //for plugins that need to read/write files...
F(qboolean, GetLen, (qhandle_t handle, qofs_t *outsize));
F(int, LocateFile, (const char *filename, unsigned int lflags, struct flocation_s *loc));
F(vfsfile_t*,OpenVFS, (const char *filename, const char *mode, enum fs_relative relativeto)); //opens a direct vfs file, without any access checks, and so can be used in threaded plugins
F(qboolean, NativePath, (const char *name, enum fs_relative relativeto, char *out, int outlen));
F(qboolean, Rename, (const char *oldf, const char *newf, enum fs_relative relativeto));
F(qboolean, Remove, (const char *fname, enum fs_relative relativeto));
F(void, EnumerateFiles, (const char *match, int (QDECL *callback)(const char *fname, qofs_t fsize, time_t mtime, void *ctx, struct searchpathfuncs_s *package), void *ctx));
//helpers
@ -359,7 +515,14 @@ typedef struct //for plugins that need to read/write files...
F(void, FileBase, (const char *in, char *out, int outlen));
F(void, CleanUpPath, (char *str));
F(unsigned int,BlockChecksum,(const void *buffer, int length)); //mostly for pack hashes.
F(qbyte*, LoadFile, (const char *fname, size_t *fsize)); //plugfuncs->Free
F(void*, LoadFile, (const char *fname, size_t *fsize)); //plugfuncs->Free
//stuff that's useful for networking.
F(char*, GetPackHashes, (char *buffer, int buffersize, qboolean referencedonly));
F(char*, GetPackNames, (char *buffer, int buffersize, int referencedonly, qboolean ext));
F(qboolean, GenCachedPakName, (const char *pname, const char *crc, char *local, int llen));
F(void, PureMode, (const char *gamedir, int mode, char *purenamelist, char *purecrclist, char *refnamelist, char *refcrclist, int seed));
F(char*, GenerateClientPacksList, (char *buffer, int maxlen, int basechecksum));
#define plugfsfuncs_name "Filesystem"
} plugfsfuncs_t;
@ -387,6 +550,20 @@ typedef struct //for when you need basic socket access, hopefully rare...
#define plugnetfuncs_name "Net"
} plugnetfuncs_t;
//fixme: this sucks.
struct vm_s;
typedef qintptr_t (QDECL *sys_calldll_t) (qintptr_t arg, ...);
typedef int (*sys_callqvm_t) (void *offset, quintptr_t mask, int fn, const int *arg);
typedef struct
{
F(struct vm_s *,Create, (const char *dllname, sys_calldll_t syscalldll, const char *qvmname, sys_callqvm_t syscallqvm));
F(qboolean, NonNative, (struct vm_s *vm));
F(void *, MemoryBase, (struct vm_s *vm));
F(qintptr_t, Call, (struct vm_s *vm, qintptr_t instruction, ...));
F(void, Destroy, (struct vm_s *vm));
#define plugq3vmfuncs_name "Quake3 QVM"
} plugq3vmfuncs_t;
#undef F
extern plugcorefuncs_t *plugfuncs;

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