Compare commits

..

33 Commits
master ... hl2

Author SHA1 Message Date
Shpoike 42d18bc5f1 resize the modelviewer's texture display if it would have gone offscreen. 2021-08-19 07:21:19 +01:00
Shpoike fa5538f696 Accept portal2's models too. 2021-08-19 07:21:19 +01:00
Shpoike 86e427126c First attempt at hl2 lightcube stuff. 2021-08-19 07:21:19 +01:00
Shpoike 483b25be2c Use more of the static prop properties - alphafading, lightorg, and leafrefs. 2021-08-19 07:21:19 +01:00
Shpoike f0fc7bfa0f Dedicated hl2bsp servers should now compile and work. 2021-08-19 07:21:19 +01:00
Shpoike 26d7371c95 Fix up some -Werror errors. 2021-08-19 07:21:19 +01:00
M.C. a65e717d21 vmt loader: handle rendertarget surfaces 2021-08-19 07:21:19 +01:00
M.C. 60ba88c33b change vmt_unlit to the default fallback for unknown vmt shaders 2021-08-19 07:21:19 +01:00
Shpoike 45ffcb91f4 Fix up r_showfields 3 a little, to make it easier to see which props are which. 2021-08-19 07:21:19 +01:00
Shpoike 93ee065acf This is Eukara's attempt to parse vmt files better. 2021-08-19 07:21:19 +01:00
Shpoike 804ff3f5b2 Load hl2 model textures and multiple bodies+meshes. lods are still broken. 2021-08-19 07:21:19 +01:00
Shpoike f4d9df2b24 Make sure iso8859-1 displays with accentless ascii fallbacks, for people who insist on using quake's glyphs. 2021-08-19 07:21:19 +01:00
Shpoike aabf9b316d Fix confusion between the outside and explicit pvs (read: recursive portal rendering). 2021-08-19 07:21:19 +01:00
Shpoike c1e320116d nullarea stuff was inconsistent. This was breaking areaportals. 2021-08-19 07:21:19 +01:00
Shpoike ff9495fcf7 Try to improve hl2bsp light intensities to better match hl2. favour ldr lightmap textures, as we overbright too much otherwise. 2021-08-19 07:21:19 +01:00
Shpoike 5392900887 Fix hl2bsp static props with r_ignoreentpvs 0. 2021-08-19 07:21:19 +01:00
Shpoike 42148878aa Fix alpha stuff in vmt materials. 2021-08-19 07:21:19 +01:00
Shpoike 5ab71f6b01 Enable more bloatware. 2021-08-19 07:21:19 +01:00
Shpoike e3b37db8bc fix typo in comment. 2021-08-19 07:21:19 +01:00
Shpoike f918b3c9c8 make sure lightmap textures have the right image format shown. 2021-08-19 07:21:19 +01:00
Shpoike e09f707067 Defective/buggy/limited support for hl2 models. 2021-08-19 07:21:19 +01:00
Shpoike bac71b8d58 Avoid mutex deadlock in an error path. 2021-08-19 07:21:19 +01:00
Shpoike 84313ce213 Basic parsing of hl2bsp static props. 2021-08-19 07:21:19 +01:00
Shpoike 76d232b007 Fix possible crash due to hl2bsp support. 2021-08-19 07:21:19 +01:00
Shpoike 7612446a59 Fix up blackslashes in zips on load, so FSZIP_FLocate won't fail because of it. 2021-08-19 07:21:19 +01:00
Shpoike 7ca893c3e1 Fix up our VFS pipe logic to handle larger initial blobs properly. 2021-08-19 07:21:19 +01:00
Shpoike 6f82d0fd8b Add support for hl2bsps's zip-inside-bsp lump... 2021-08-19 07:21:19 +01:00
Shpoike 586a92ec47 Try to make sense of hl2 materials. 2021-08-19 07:21:19 +01:00
Shpoike 6658565956 Try to handle hl2bsp's area portals. 2021-08-19 07:21:19 +01:00
Shpoike e470cc5033 Added displacement support for HL2BSPs. 2021-08-19 07:21:19 +01:00
Shpoike 955e9d3fb6 Basic hl2bsp support. 2021-08-19 07:21:18 +01:00
Shpoike 3e81fdef8a Update and enable our VTF loader. 2021-08-19 07:21:18 +01:00
Shpoike e1a0f5fa4e Fix vpk support. 2021-08-19 07:21:18 +01:00
351 changed files with 23182 additions and 32599 deletions

View File

@ -62,8 +62,7 @@ IF (EXISTS ${CMAKE_SOURCE_DIR}/.git)
ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE
)
MESSAGE(STATUS "FTE GIT ${FTE_BRANCH} Revision git-${FTE_REVISON_GIT}, ${FTE_DATE}")
SET(SVNREVISION git-${FTE_REVISON_GIT})
SET(FTE_REVISON SVNREVISION=${SVNREVISION} SVNDATE=${FTE_DATE} FTE_BRANCH=${FTE_BRANCH})
SET(FTE_REVISON SVNREVISION=git-${FTE_REVISON_GIT} SVNDATE=${FTE_DATE} FTE_BRANCH=${FTE_BRANCH})
ENDIF()
#plugins need visibility hidden in order to avoid conflicts with function names that match the engine.
@ -213,21 +212,6 @@ IF(CMAKE_BUILD_TYPE MATCHES "Debug")
ENDIF()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_FILE_OFFSET_BITS=64")
FUNCTION(EMBED_PLUGIN_META PLUGNAME PLUGTITLE PLUGDESC)
SET_TARGET_PROPERTIES(plug_${PLUGNAME} PROPERTIES OUTPUT_NAME "${PLUGNAME}")
SET_TARGET_PROPERTIES(plug_${PLUGNAME} PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(plug_${PLUGNAME} PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
SET(INSTALLTARGS ${INSTALLTARGS} "plug_${PLUGNAME}")
#sadly we need to use a temp zip file, because otherwise zip insists on using zip64 extensions which breaks zip -A (as well as any attempts to read any files).
ADD_CUSTOM_COMMAND(
TARGET plug_${PLUGNAME} POST_BUILD
COMMAND echo "{\\n package fteplug_${PLUGNAME}\\n ver \"${SVNREVISION}\"\\n category Plugins\\n title \"${PLUGTITLE}\"\\n gamedir \"\"\\n desc \"${PLUGDESC}\"\\n}" | zip -q -9 -fz- $<TARGET_FILE:plug_${PLUGNAME}>.zip -
COMMAND cat $<TARGET_FILE:plug_${PLUGNAME}>.zip >> "$<TARGET_FILE:plug_${PLUGNAME}>"
COMMAND zip -A "$<TARGET_FILE:plug_${PLUGNAME}>"
COMMAND rm $<TARGET_FILE:plug_${PLUGNAME}>.zip
VERBATIM)
ENDFUNCTION()
IF(${ANDROID})
# FIND_PACKAGE(Freetype REQUIRED)
@ -294,13 +278,6 @@ ELSEIF(${UNIX} AND NOT FTE_USE_SDL) #linux(ish)
IF(NOT GNUTLS_FOUND)
MESSAGE(WARNING "gnutls library NOT available. HTTPS/DTLS will not be available.")
SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};NO_GNUTLS)
ELSE()
SET(GNUTLS_STATIC false CACHE BOOL "Link gnutls statically.") #usually as an .so though. :/
IF(GNUTLS_STATIC)
SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};GNUTLS_STATIC)
SET(FTE_LIBS ${FTE_LIBS} ${GNUTLS_LIBRARY})
SET(FTESV_LIBS ${FTESV_LIBS} ${GNUTLS_LIBRARY})
ENDIF()
ENDIF()
#linux-only packages
@ -527,7 +504,6 @@ SET(FTE_COMMON_FILES
engine/common/com_mesh.c
engine/common/com_bih.c
engine/common/common.c
engine/common/json.c
engine/common/crc.c
engine/common/cvar.c
engine/common/fs.c
@ -536,6 +512,7 @@ SET(FTE_COMMON_FILES
engine/common/fs_stdio.c
engine/common/fs_xz.c
engine/common/fs_zip.c
engine/common/fs_vpk.c
engine/common/gl_q2bsp.c
engine/common/huff.c
engine/common/log.c
@ -550,6 +527,7 @@ 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
@ -571,6 +549,7 @@ 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
@ -627,9 +606,11 @@ 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
@ -684,11 +665,13 @@ 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
@ -698,9 +681,11 @@ 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
@ -759,72 +744,40 @@ SET(FTE_CLIENT_FILES
${FTE_VK_FILES}
)
SET(FTE_Q3_FILES
plugins/quake3/botlib/be_aas_bspq3.c
plugins/quake3/botlib/be_aas_entity.c
plugins/quake3/botlib/be_aas_move.c
plugins/quake3/botlib/be_aas_routealt.c
plugins/quake3/botlib/be_ai_char.c
plugins/quake3/botlib/be_ai_goal.c
plugins/quake3/botlib/be_ai_weight.c
plugins/quake3/botlib/l_crc.c
plugins/quake3/botlib/l_memory.c
plugins/quake3/botlib/l_struct.c
plugins/quake3/botlib/be_aas_cluster.c
plugins/quake3/botlib/be_aas_file.c
plugins/quake3/botlib/be_aas_optimize.c
plugins/quake3/botlib/be_aas_route.c
plugins/quake3/botlib/be_ai_chat.c
plugins/quake3/botlib/be_ai_move.c
plugins/quake3/botlib/be_ea.c
plugins/quake3/botlib/l_libvar.c
plugins/quake3/botlib/l_precomp.c
plugins/quake3/botlib/be_aas_debug.c
plugins/quake3/botlib/be_aas_main.c
plugins/quake3/botlib/be_aas_reach.c
plugins/quake3/botlib/be_aas_sample.c
plugins/quake3/botlib/be_ai_gen.c
plugins/quake3/botlib/be_ai_weap.c
plugins/quake3/botlib/be_interface.c
plugins/quake3/botlib/l_log.c
plugins/quake3/botlib/l_script.c
plugins/quake3/botlib/standalone.c
plugins/quake3/clq3_cg.c
plugins/quake3/clq3_ui.c
plugins/quake3/clq3_parse.c
plugins/quake3/svq3_game.c
plugins/quake3/q3common.c
plugins/quake3/q3common.h
plugins/quake3/clq3defs.h
plugins/quake3/q3g_public.h
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(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()
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")
FILE(STRINGS "${FTE_BUILD_CONFIG}" BULLET_INTERNAL REGEX "^#define[\t ]+USE_INTERNAL_BULLET")
IF(BULLET_INTERNAL)
@ -846,109 +799,63 @@ ELSE()
)
TARGET_INCLUDE_DIRECTORIES(plug_bullet PUBLIC ${BULLET_INCLUDE_DIRS})
SET_TARGET_PROPERTIES(plug_bullet PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
SET_TARGET_PROPERTIES(plug_bullet PROPERTIES OUTPUT_NAME "bullet")
SET_TARGET_PROPERTIES(plug_bullet PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(plug_bullet PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(plug_bullet ${SYS_LIBS} ${BULLET_LIBRARIES})
EMBED_PLUGIN_META(bullet "Bullet Physics Plugin" "Provides Rigid Body Physics.")
SET(INSTALLTARGS ${INSTALLTARGS} plug_bullet)
ELSE()
MESSAGE(WARNING "bullet library not detected, skipping plugin")
ENDIF()
ENDIF()
ENDIF()
#ODE Physics library plugin
SET(FTE_PLUG_ODE true CACHE STRING "Compile ODE rigid body physics plugin.")
SET_PROPERTY(CACHE FTE_PLUG_ODE PROPERTY STRINGS false true static)
IF(FTE_PLUG_ODE)
FIND_PATH(LIBODE_INCLUDE_DIR ode/ode.h)
IF (LIBODE_INCLUDE_DIR)
FIND_LIBRARY(LIBODE_LIBRARY ode)
ENDIF()
IF (LIBODE_LIBRARY)
IF (FTE_PLUG_ODE STREQUAL "static")
#SET (FTE_COMMON_FILES ${FTE_COMMON_FILES} engine/common/com_phys_ode.c)
SET(FTE_LIB_DEFINES "${FTE_LIB_DEFINES};USE_INTERNAL_ODE;ODE_STATIC")
SET(FTE_LIBS ${FTE_LIBS} ${LIBODE_LIBRARY})
SET(FTESV_LIBS ${FTE_LIBS} ${LIBODE_LIBRARY})
SET(FTE_INCLUDES ${FTE_INCLUDES} ${ODE_INCLUDE_DIRS})
ELSE()
ADD_LIBRARY(plug_ode MODULE
plugins/plugin.c
engine/common/com_phys_ode.c
engine/common/mathlib.c
)
TARGET_INCLUDE_DIRECTORIES(plug_ode PUBLIC ${ODE_INCLUDE_DIRS})
SET_TARGET_PROPERTIES(plug_ode PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;ODE_STATIC")
TARGET_LINK_LIBRARIES(plug_ode ${SYS_LIBS} ${LIBODE_LIBRARY})
EMBED_PLUGIN_META(ode "ODE Physics" "Provides Rigid Body Physics behaviours.")
ENDIF()
ELSE()
MESSAGE(WARNING "ODE library not found, no ode plugin for you")
ENDIF()
ENDIF()
IF(ANDROID)
#android sucks. everything is a library. so we build the engine as a shared library and completely ignore dedicated servers+tools
SET(FTE_ENGINE_FTEDROID true CACHE BOOL "Compile ftedroid engine shared library.")
IF(FTE_ENGINE_FTEDROID)
ADD_LIBRARY(ftedroid MODULE
${FTE_ARCH_FILES}
${FTE_COMMON_FILES}
${FTE_CLIENT_FILES}
)
SET_TARGET_PROPERTIES(ftedroid PROPERTIES COMPILE_DEFINITIONS "${FTE_LIB_DEFINES};${FTE_DEFINES};${FTE_REVISON}")
TARGET_INCLUDE_DIRECTORIES(ftedroid PUBLIC ${FTE_INCLUDES})
TARGET_LINK_LIBRARIES(ftedroid ${FTE_LIBS} )
SET(INSTALLTARGS ${INSTALLTARGS} ftedroid)
ENDIF()
ADD_LIBRARY(ftedroid MODULE
${FTE_ARCH_FILES}
${FTE_COMMON_FILES}
${FTE_CLIENT_FILES}
)
SET_TARGET_PROPERTIES(ftedroid PROPERTIES COMPILE_DEFINITIONS "${FTE_LIB_DEFINES};${FTE_DEFINES};${FTE_REVISON}")
TARGET_LINK_LIBRARIES(ftedroid ${FTE_LIBS} )
SET(INSTALLTARGS ${INSTALLTARGS} ftedroid)
ELSE()
#systems that actually have executables...
SET(FTE_ENGINE true CACHE BOOL "Compile fteqw engine binary.")
IF(FTE_ENGINE)
ADD_EXECUTABLE(fteqw WIN32
${FTE_ARCH_FILES}
${FTE_COMMON_FILES}
${FTE_CLIENT_FILES}
${FTE_SERVER_FILES}
)
SET_TARGET_PROPERTIES(fteqw PROPERTIES COMPILE_DEFINITIONS "${FTE_LIB_DEFINES};${FTE_DEFINES};${FTE_REVISON}")
TARGET_INCLUDE_DIRECTORIES(fteqw PUBLIC ${FTE_INCLUDES})
TARGET_LINK_LIBRARIES(fteqw ${FTE_LIBS})
SET(INSTALLTARGS ${INSTALLTARGS} fteqw)
ENDIF()
ADD_EXECUTABLE(fteqw WIN32
${FTE_ARCH_FILES}
${FTE_COMMON_FILES}
${FTE_CLIENT_FILES}
${FTE_SERVER_FILES}
)
SET_TARGET_PROPERTIES(fteqw PROPERTIES COMPILE_DEFINITIONS "${FTE_LIB_DEFINES};${FTE_DEFINES};${FTE_REVISON}")
TARGET_LINK_LIBRARIES(fteqw ${FTE_LIBS})
SET(INSTALLTARGS ${INSTALLTARGS} fteqw)
SET(FTE_ENGINE_SERVER_ONLY true CACHE BOOL "Compile fteqw-sv (server only) engine binary.")
IF(FTE_ENGINE_SERVER_ONLY)
ADD_EXECUTABLE(fteqw-sv
${FTESV_ARCH_FILES}
${FTE_COMMON_FILES}
${FTE_SERVER_FILES}
)
SET_TARGET_PROPERTIES(fteqw-sv PROPERTIES COMPILE_DEFINITIONS "SERVERONLY;${FTE_LIB_DEFINES};${FTESV_DEFINES};${FTE_REVISON}")
TARGET_INCLUDE_DIRECTORIES(fteqw-sv PUBLIC ${FTE_INCLUDES})
TARGET_LINK_LIBRARIES(fteqw-sv ${FTESV_LIBS})
SET(INSTALLTARGS ${INSTALLTARGS} fteqw-sv)
ENDIF()
ADD_EXECUTABLE(fteqw-sv
${FTESV_ARCH_FILES}
${FTE_COMMON_FILES}
${FTE_SERVER_FILES}
)
SET_TARGET_PROPERTIES(fteqw-sv PROPERTIES COMPILE_DEFINITIONS "SERVERONLY;${FTE_LIB_DEFINES};${FTESV_DEFINES};${FTE_REVISON}")
TARGET_LINK_LIBRARIES(fteqw-sv ${FTESV_LIBS})
SET(INSTALLTARGS ${INSTALLTARGS} fteqw-sv)
SET(FTE_ENGINE_CLIENT_ONLY false CACHE BOOL "Compile ftedw-cl (client-only) engine binary.")
IF(FTE_ENGINE_CLIENT_ONLY)
IF(0)
ADD_EXECUTABLE(fteqw-cl
${FTE_ARCH_FILES}
${FTE_COMMON_FILES}
${FTE_CLIENT_FILES}
)
SET_TARGET_PROPERTIES(fteqw-cl PROPERTIES COMPILE_DEFINITIONS "CLIENTONLY;${FTE_LIB_DEFINES};${FTE_DEFINES};${FTE_REVISON}")
TARGET_INCLUDE_DIRECTORIES(fteqw-cl PUBLIC ${FTE_INCLUDES})
TARGET_LINK_LIBRARIES(fteqw-cl ${FTE_LIBS})
SET(INSTALLTARGS ${INSTALLTARGS} fteqw-cl)
ENDIF()
IF(FTE_ENGINE OR FTE_ENGINE_CLIENT)
FIND_PACKAGE(SDL2)
IF(SDL2_FOUND)
SET(FTE_SDL2 FTE_SDL)
SET(FTE_SDL2_INCLUDES ${SDL2_INCLUDE_DIRS})
ENDIF()
FIND_PACKAGE(SDL2)
IF(SDL2_FOUND)
SET(FTE_SDL2 FTE_SDL)
SET(FTE_SDL2_INCLUDES ${SDL2_INCLUDE_DIRS})
ENDIF()
SET(FTE_TOOL_IQM true CACHE BOOL "Compile IQM Tool.")
@ -956,7 +863,6 @@ ELSE()
ADD_EXECUTABLE(iqmtool
iqm/iqm.cpp
plugins/models/gltf.c
engine/common/json.c
engine/client/image.c
imgtool.c
iqm/iqm.h
@ -1145,9 +1051,10 @@ IF(0)
engine/sw/sw_spans.h
)
SET_TARGET_PROPERTIES(sw PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES};SWQUAKE")
SET_TARGET_PROPERTIES(sw PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(sw PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(sw ${SYS_LIBS})
EMBED_PLUGIN_META(sw "Software Renderer" "Provides software rendering. Slow.")
SET(INSTALLTARGS ${INSTALLTARGS} sw)
ENDIF()
#Quake Injector Alike plugin
@ -1160,25 +1067,22 @@ IF(FTE_PLUG_QI)
plugins/jabber/xml.c
)
SET_TARGET_PROPERTIES(plug_qi PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
SET_TARGET_PROPERTIES(plug_qi PROPERTIES OUTPUT_NAME "qi")
SET_TARGET_PROPERTIES(plug_qi PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(plug_qi PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(plug_qi ${SYS_LIBS})
EMBED_PLUGIN_META(qi "Quaddicted Map Database" "Provides easy access to the quaddicted map database. Once installed you can use eg 'map qi_dopa:start' to begin playing dopa, or load it via the menus.")
SET(INSTALLTARGS ${INSTALLTARGS} plug_qi)
ENDIF()
SET(FTE_PLUG_OPENSSL false CACHE BOOL "Compile OpenSSL.")
SET(FTE_PLUG_OPENSSL false CACHE BOOL "Compile OpenSSL (beware license).")
IF(FTE_PLUG_OPENSSL)
#the openssl license is incompatible with the GPL, so while we have code to use it distributing the binaries built with it is not a (legal) option.
#note that openssl 3.0.0 upwards are apache-2 licensed, which IS gpl-3 compatible (though not gpl-2). debian has not caught up with that yet, however.
FIND_PACKAGE(OpenSSL)
IF(OPENSSL_VERSION_MAJOR LESS 3)
SET(FTE_PRIVATE_USE_ONLY false CACHE BOOL "Ignore license violations.")
ENDIF()
IF(NOT OPENSSL_FOUND)
MESSAGE(WARNING "openssl library NOT available. you'll have to use some other library.")
ELSEIF(OPENSSL_VERSION_MAJOR LESS 3 AND NOT FTE_PRIVATE_USE_ONLY)
MESSAGE(WARNING "openssl v3 required for GPL compliance. Enable FTE_PRIVATE_USE_ONLY to compile openssl plugin.")
ELSE()
IF(OPENSSL_VERSION_MAJOR LESS 3)
IF(OPENSSL_VERSION_MAJOR LESS 3 AND NOT FTE_PRIVATE_USE_ONLY)
MESSAGE(WARNING "openssl library version is not 3 or above. You may not distribute plugin binaries due to license conflict.")
ELSE()
MESSAGE(WARNING "Using openssl. Resulting plugin must be licensed as GPLv3.")
@ -1190,30 +1094,38 @@ IF(FTE_PLUG_OPENSSL)
plugins/net_ssl_openssl.c
)
SET_TARGET_PROPERTIES(plug_openssl PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
SET_TARGET_PROPERTIES(plug_openssl PROPERTIES OUTPUT_NAME "openssl")
SET_TARGET_PROPERTIES(plug_openssl PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(plug_openssl PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(plug_openssl ${SYS_LIBS} ${OPENSSL_LIBRARIES})
EMBED_PLUGIN_META(openssl "OpenSSL" "Provides OpenSSL support for dtls/tls/https support. The crypto library that is actually used is controlled via the tls_provider cvar.")
SET(INSTALLTARGS ${INSTALLTARGS} plug_openssl)
ENDIF()
ENDIF()
#SET(FTE_PLUG_GNUTLS true CACHE BOOL "Compile GnuTLS Library.")
#IF(FTE_PLUG_GNUTLS)
# FIND_PACKAGE(GnuTLS)
# IF(NOT GNUTLS_FOUND)
# MESSAGE(WARNING "openssl library NOT available. you'll have to use some other library.")
# ELSE()
# SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES})
#
# ADD_LIBRARY(plug_gnutls MODULE
# plugins/plugin.c
# engine/common/net_ssl_gnutls.c
# )
# SET_TARGET_PROPERTIES(plug_gnutls PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
# TARGET_LINK_LIBRARIES(plug_gnutls ${SYS_LIBS} ${GNUTLS_LIBRARIES})
#
# EMBED_PLUGIN_META(gnutls "GnuTLS" "Provides GnuTLS support for dtls/tls/https support. The crypto library that is actually used is controlled via the tls_provider cvar.")
# ENDIF()
#ENDIF()
#ODE Physics library plugin
SET(FTE_PLUG_ODE true CACHE BOOL "Compile ODE rigid body physics plugin.")
IF(FTE_PLUG_ODE)
FIND_PATH(LIBODE_INCLUDE_DIR ode/ode.h)
IF (LIBODE_INCLUDE_DIR)
FIND_LIBRARY(LIBODE_LIBRARY ode)
ENDIF()
IF (LIBODE_LIBRARY)
ADD_LIBRARY(plug_ode MODULE
plugins/plugin.c
engine/common/com_phys_ode.c
engine/common/mathlib.c
)
TARGET_INCLUDE_DIRECTORIES(plug_ode PUBLIC ${ODE_INCLUDE_DIRS})
SET_TARGET_PROPERTIES(plug_ode PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;ODE_STATIC")
SET_TARGET_PROPERTIES(plug_ode PROPERTIES OUTPUT_NAME "ode")
SET_TARGET_PROPERTIES(plug_ode PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(plug_ode PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(plug_ode ${SYS_LIBS} ${LIBODE_LIBRARY})
SET(INSTALLTARGS ${INSTALLTARGS} plug_ode)
ELSE()
MESSAGE(WARNING "ODE library not found, no ode plugin for you")
ENDIF()
ENDIF()
#EzQuake Hud port plugin
SET(FTE_PLUG_EZHUD true CACHE BOOL "Compile MoreQuakeWorld Hud plugin .")
@ -1226,9 +1138,11 @@ IF(FTE_PLUG_EZHUD)
plugins/ezhud/hud_editor.c
)
SET_TARGET_PROPERTIES(plug_ezhud PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
SET_TARGET_PROPERTIES(plug_ezhud PROPERTIES OUTPUT_NAME "ezhud")
SET_TARGET_PROPERTIES(plug_ezhud PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(plug_ezhud PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(plug_ezhud ${SYS_LIBS})
EMBED_PLUGIN_META(ezhud "EzHud Plugin" "Provides compat with ezquake's hud scripts.")
SET(INSTALLTARGS ${INSTALLTARGS} plug_ezhud)
ENDIF()
#NameMaker string generation plugin
@ -1244,8 +1158,6 @@ IF(FTE_PLUG_NAMEMAKER)
SET_TARGET_PROPERTIES(plug_namemaker PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(plug_namemaker ${SYS_LIBS})
SET(INSTALLTARGS ${INSTALLTARGS} plug_namemaker)
EMBED_PLUGIN_META(namemaker "Name Maker Plugin" "Provides a lame UI for selecting arbitrary non-ascii glyphs as part of your nickname.")
ENDIF()
#Terrain Generation plugin
@ -1256,9 +1168,11 @@ IF(FTE_PLUG_TERRAINGEN)
plugins/terrorgen/terragen.c
)
SET_TARGET_PROPERTIES(plug_terraingen PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
SET_TARGET_PROPERTIES(plug_terraingen PROPERTIES OUTPUT_NAME "terragen")
SET_TARGET_PROPERTIES(plug_terraingen PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(plug_terraingen PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(plug_terraingen ${SYS_LIBS})
EMBED_PLUGIN_META(terraingen "TerrainGen Plugin" "A lame example plugin for randomised terrain generation.")
SET(INSTALLTARGS ${INSTALLTARGS} plug_terraingen)
ENDIF()
#IRC client plugin
@ -1269,9 +1183,11 @@ IF(FTE_PLUG_IRC)
plugins/irc/ircclient.c
)
SET_TARGET_PROPERTIES(plug_irc PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_REVISON};${FTE_LIB_DEFINES}")
SET_TARGET_PROPERTIES(plug_irc PROPERTIES OUTPUT_NAME "irc")
SET_TARGET_PROPERTIES(plug_irc PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(plug_irc PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(plug_irc ${SYS_LIBS})
EMBED_PLUGIN_META(irc "IRC Plugin" "Allows you to chat on IRC without tabbing out.")
SET(INSTALLTARGS ${INSTALLTARGS} plug_irc)
ENDIF()
#mpq package format plugin (blizzard games)
@ -1283,27 +1199,11 @@ IF(FTE_PLUG_MPQ)
plugins/mpq/fs_mpq.c
)
SET_TARGET_PROPERTIES(plug_mpq PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
SET_TARGET_PROPERTIES(plug_mpq PROPERTIES OUTPUT_NAME "mpq")
SET_TARGET_PROPERTIES(plug_mpq PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(plug_mpq PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(plug_mpq ${SYS_LIBS} ${ZLIB_LIBRARIES})
EMBED_PLUGIN_META(irc "MPQ Archive Plugin" "Adds support for reading .mpq files. Not very useful...")
ENDIF()
#vpk package format plugin (halflife2)
SET(FTE_PLUG_HL2 true CACHE BOOL "Compile support for hl2 file formats.")
IF(FTE_PLUG_HL2)
ADD_LIBRARY(plug_hl2 MODULE
plugins/plugin.c
plugins/hl2/hl2.c
plugins/hl2/fs_vpk.c
plugins/hl2/img_vtf.c
plugins/hl2/mod_hl2.c
plugins/hl2/mod_vbsp.c
plugins/hl2/mat_vmt.c
)
SET_TARGET_PROPERTIES(plug_hl2 PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;MULTITHREAD;${FTE_LIB_DEFINES}")
TARGET_LINK_LIBRARIES(plug_hl2 ${SYS_LIBS} ${ZLIB_LIBRARIES})
EMBED_PLUGIN_META(hl2 "HalfLife2 Formats Plugin" "Adds support for reading various file formats used by HalfLife2. Requires mod support to be useful.")
SET(INSTALLTARGS ${INSTALLTARGS} plug_mpq)
ENDIF()
#model formats plugin
@ -1313,13 +1213,14 @@ IF(FTE_PLUG_MODELS)
plugins/plugin.c
plugins/models/models.c
plugins/models/gltf.c
engine/common/json.c
plugins/models/exportiqm.c
)
SET_TARGET_PROPERTIES(plug_models PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
SET_TARGET_PROPERTIES(plug_models PROPERTIES OUTPUT_NAME "models")
SET_TARGET_PROPERTIES(plug_models PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(plug_models PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(plug_models ${SYS_LIBS})
EMBED_PLUGIN_META(models "Models Plugin" "Kinda redundant now that the engine has gltf2 loading.")
SET(INSTALLTARGS ${INSTALLTARGS} plug_models)
ENDIF()
SET(FTE_PLUG_X11SV false CACHE BOOL "Compile x11 server plugin.")
@ -1334,9 +1235,11 @@ IF(FTE_PLUG_X11SV)
engine/qclib/hash.c
)
SET_TARGET_PROPERTIES(plug_x11sv PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
SET_TARGET_PROPERTIES(plug_x11sv PROPERTIES OUTPUT_NAME "x11sv")
SET_TARGET_PROPERTIES(plug_x11sv PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(plug_x11sv PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(plug_x11sv ${SYS_LIBS})
EMBED_PLUGIN_META(x11sv "X11 Server Plugin" "Provides a primitive X11 server in the form of a video decoder plugin.")
SET(INSTALLTARGS ${INSTALLTARGS} plug_x11sv)
ENDIF()
#ffmpeg client plugin. no proper way to detect dependancies right now, so I've gotta try the manual way.
@ -1359,10 +1262,12 @@ IF(FTE_PLUG_FFMPEG)
plugins/avplug/avencode.c
)
TARGET_INCLUDE_DIRECTORIES(plug_ffmpeg PUBLIC ${AVCODEC_INCLUDE_DIR} ${AVFORMAT_INCLUDE_DIR} ${AVUTIL_INCLUDE_DIR} ${AVSWSCALE_INCLUDE_DIR})
SET_TARGET_PROPERTIES(plug_ffmpeg PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(plug_ffmpeg ${SYS_LIBS} ${AVFORMAT_LIBRARY} ${AVCODEC_LIBRARY} ${AVUTIL_LIBRARY} ${AVSWSCALE_LIBRARY})
SET_TARGET_PROPERTIES(plug_ffmpeg PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
EMBED_PLUGIN_META(ffmpeg "FFMPEG Video Decoding Plugin" "Provides support for more audio formats, as well as video playback and better capture support.")
SET_TARGET_PROPERTIES(plug_ffmpeg PROPERTIES OUTPUT_NAME "ffmpeg")
SET_TARGET_PROPERTIES(plug_ffmpeg PROPERTIES PREFIX "fteplug_")
SET(INSTALLTARGS ${INSTALLTARGS} plug_ffmpeg)
ELSE()
MESSAGE(WARNING "ffmpeg library NOT available. Quake shouldn't be playing fmv anyway.")
ENDIF()
@ -1380,10 +1285,12 @@ IF(FTE_PLUG_TIMIDITY)
plugins/timidity.c
)
TARGET_INCLUDE_DIRECTORIES(plug_timidity PUBLIC ${TIMIDITY_INCLUDE_DIR})
SET_TARGET_PROPERTIES(plug_timidity PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(plug_timidity ${SYS_LIBS} ${TIMIDITY_LIBRARY})
SET_TARGET_PROPERTIES(plug_timidity PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
EMBED_PLUGIN_META(timidity "Timidity Plugin" "Provides support for playback of midi files.")
SET_TARGET_PROPERTIES(plug_timidity PROPERTIES OUTPUT_NAME "timidity")
SET_TARGET_PROPERTIES(plug_timidity PROPERTIES PREFIX "fteplug_")
SET(INSTALLTARGS ${INSTALLTARGS} plug_timidity)
ELSE()
MESSAGE(WARNING "timidity library NOT available. We'll just stick to fake-cd music for hexen2.")
ENDIF()
@ -1404,6 +1311,9 @@ IF(FTE_PLUG_OPENXR)
)
TARGET_INCLUDE_DIRECTORIES(plug_openxr PRIVATE ${OPENXR_INCLUDE_DIRS} )
SET_TARGET_PROPERTIES(plug_openxr PROPERTIES OUTPUT_NAME "openxr")
SET_TARGET_PROPERTIES(plug_openxr PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(plug_openxr PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
IF (1) #dynamically link
SET_TARGET_PROPERTIES(plug_openxr PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES};${FTE_DEFINES};XR_NO_PROTOTYPES")
TARGET_LINK_LIBRARIES(plug_openxr ${SYS_LIBS})
@ -1411,53 +1321,26 @@ IF(FTE_PLUG_OPENXR)
SET_TARGET_PROPERTIES(plug_openxr PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES};${FTE_DEFINES}")
TARGET_LINK_LIBRARIES(plug_openxr ${SYS_LIBS} ${OPENXR_LIBRARIES})
ENDIF()
EMBED_PLUGIN_META(openxr "OpenXR Plugin" "Provides support for Virtual Reality headsets and input devices.")
SET(INSTALLTARGS ${INSTALLTARGS} plug_openxr)
ELSE()
MESSAGE(WARNING "openxr library NOT available. Quake is already a reality anyway.")
ENDIF()
ENDIF()
ENDIF()
##cef plugin
##libcef itself can be obtained from https://cef-builds.spotifycdn.com/index.html#linux64 (minimal builds, which still ends up with a 1,162,752,744 byte libcef.so - yes, actual size)
##(be sure to manually strip the binary of its debug info)
##to get this cmake stuff to recognise the headers etc:
## cd $FTEQW-REPO && ln -s $FOO/cef_binary_$FOO+chromium-$FOO_linux64_minimal plugins/cef/cef_linux64
##(note that other systems use other subdir names)
#cef plugin
#libcef itself can be obtained from http://opensource.spotify.com/cefbuilds/index.html (minimal builds, which still ends up with a 940mb libcef.so - yes, actual size)
#(be sure to manually strip the binary of its debug info)
SET(FTE_PLUG_CEF true CACHE BOOL "Compile libcef (webbrowser) plugin.")
SET(CEF_PATH ${CEF_PATH} CACHE PATH "Base location of libcef for target platform.")
IF(FTE_PLUG_CEF)
IF(CEF_PATH MATCHES "")
UNSET(CEF_PATH CACHE)
IF(WIN32)
IF(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "AMD64")
FIND_PATH (CEF_PATH include/cef_version.h plugins/cef/cef_windows64)
ELSEIF(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86")
FIND_PATH (CEF_PATH include/cef_version.h plugins/cef/cef_windows32)
ELSEIF(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "ARM64")
FIND_PATH (CEF_PATH include/cef_version.h plugins/cef/cef_windowsarm64)
ENDIF()
ELSEIF("${CMAKE_SYSTEM}" MATCHES "Linux")
IF(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "x86_64")
FIND_PATH (CEF_PATH include/cef_version.h plugins/cef/cef_linux64)
ELSEIF(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "i686")
FIND_PATH (CEF_PATH include/cef_version.h plugins/cef/cef_linux32)
ENDIF()
ENDIF()
ENDIF()
FIND_PATH (CEF_PATH include/cef_version.h /tmp/cef/cef_binary_81.3.1+gb2b49f1+chromium-81.0.4044.113_linux64_minimal)
#FIND_LIBRARY(CEF_LIBRARIES cef ${CEF_PATH}/Release)
IF (CEF_PATH)
##statically link only for release builds. debug builds probably don't want to have to wait for ages for the debugger to finish loading debug info unless we're actually using this stuff.
IF(CMAKE_BUILD_TYPE MATCHES "Release")
SET(CEF_LIBRARIES "${CMAKE_BINARY_DIR}/libcef.so")
ENDIF()
ADD_LIBRARY(plug_cef MODULE
plugins/plugin.c
plugins/cef/cef.c
)
TARGET_INCLUDE_DIRECTORIES(plug_cef PRIVATE ${CEF_PATH})
SET_TARGET_PROPERTIES(plug_cef PROPERTIES BUILD_RPATH_USE_ORIGIN true)
TARGET_INCLUDE_DIRECTORIES(plug_cef PRIVATE ${CEF_PATH}/..)
if (CEF_LIBRARIES)
SET_TARGET_PROPERTIES(plug_cef PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES};${FTE_DEFINES};LIBCEF_STATIC")
TARGET_LINK_LIBRARIES(plug_cef ${SYS_LIBS} ${CEF_LIBRARIES} ${CMAKE_DL_LIBS})
@ -1465,35 +1348,9 @@ IF(FTE_PLUG_CEF)
SET_TARGET_PROPERTIES(plug_cef PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES};${FTE_DEFINES};LIBCEF_DYNAMIC")
TARGET_LINK_LIBRARIES(plug_cef ${SYS_LIBS} ${CMAKE_DL_LIBS})
ENDIF()
IF(NOT ${UNIX})
ADD_CUSTOM_COMMAND(
TARGET plug_cef PRE_LINK
COMMAND cp ${CEF_PATH}/Release/* ${CMAKE_BINARY_DIR}
COMMAND cp ${CEF_PATH}/Resources/* ${CMAKE_BINARY_DIR}
)
ELSE()
IF(CMAKE_BUILD_TYPE MATCHES "Release")
#sigh, cef ain't stripped properly on linux.
ADD_CUSTOM_COMMAND(
TARGET plug_cef PRE_LINK
COMMAND ln -f -s ${CEF_PATH}/Release/* ${CMAKE_BINARY_DIR}
COMMAND strip ${CMAKE_BINARY_DIR}/libcef.so -o libcef.so
COMMAND strip ${CMAKE_BINARY_DIR}/libEGL.so -o libEGL.so
COMMAND strip ${CMAKE_BINARY_DIR}/libGLESv2.so -o libGLESv2.so
COMMAND strip ${CMAKE_BINARY_DIR}/chrome-sandbox -o chrome-sandbox
COMMAND ln -f -s ${CEF_PATH}/Resources/* ${CMAKE_BINARY_DIR}
)
ELSE()
ADD_CUSTOM_COMMAND(
TARGET plug_cef PRE_LINK
COMMAND ln -f -s ${CEF_PATH}/Release/* ${CMAKE_BINARY_DIR}
COMMAND ln -f -s ${CEF_PATH}/Resources/* ${CMAKE_BINARY_DIR}
)
ENDIF()
ENDIF()
EMBED_PLUGIN_META(cef "libcef(Browser) Plugin" "This plugin provides support for an in-game web browser.")
SET_TARGET_PROPERTIES(plug_cef PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(plug_cef PROPERTIES OUTPUT_NAME "cef")
SET_TARGET_PROPERTIES(plug_cef PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
ELSE()
MESSAGE(WARNING "libcef library NOT available. no web browser support on walls.")
ENDIF()
@ -1514,12 +1371,14 @@ IF(FTE_PLUG_XMPP)
plugins/emailnot/md5.c
)
SET_TARGET_PROPERTIES(plug_xmpp PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
SET_TARGET_PROPERTIES(plug_xmpp PROPERTIES OUTPUT_NAME "xmpp")
SET_TARGET_PROPERTIES(plug_xmpp PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(plug_xmpp PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
IF(${WIN32})
ELSE()
TARGET_LINK_LIBRARIES(plug_xmpp ${SYS_LIBS} resolv)
ENDIF()
EMBED_PLUGIN_META(xmpp "XMPP Plugin" "XMPP/Jabber instant messenger plugin for chatting without tabbing out.")
SET(INSTALLTARGS ${INSTALLTARGS} plug_xmpp)
ENDIF()
ENDIF() #android
@ -1530,13 +1389,10 @@ INSTALL(TARGETS ${INSTALLTARGS}
LIBRARY DESTINATION "${CMAKE_INSTALL_FULL_LIBDIR}"
)
SET(FTE_MENU_SYS true CACHE BOOL "Compile System Menu.")
IF(FTE_MENU_SYS)
IF (1)
ADD_CUSTOM_TARGET(menusys ALL
VERBATIM
DEPENDS fteqcc
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/quakec/menusys/"
COMMAND fteqcc -srcfile "menu.src" -o "${CMAKE_CURRENT_BINARY_DIR}/menu.dat"
COMMAND fteqcc -srcfile "${CMAKE_CURRENT_SOURCE_DIR}/quakec/menusys/menu.src" -o "${CMAKE_CURRENT_BINARY_DIR}/menu.dat"
BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/menu.dat" "${CMAKE_CURRENT_BINARY_DIR}/menu.lno"
SOURCES
quakec/menusys/menu.src
@ -1573,35 +1429,4 @@ IF(FTE_MENU_SYS)
quakec/menusys/menu/options_video.qc
quakec/menusys/menu/quit.qc
)
ENDIF()
SET(FTE_CSADDON true CACHE BOOL "CS Addon.")
IF(FTE_CSADDON)
ADD_CUSTOM_TARGET(csaddon ALL
VERBATIM
DEPENDS fteqcc
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/quakec/csaddon/src/"
COMMAND fteqcc -srcfile "csaddon.src" -o "${CMAKE_CURRENT_BINARY_DIR}/csaddon.dat"
BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/csaddon.dat" "${CMAKE_CURRENT_BINARY_DIR}/csaddon.lno"
SOURCES
quakec/csaddon/src/csaddon.src
quakec/csaddon/src/csplat.qc
quakec/csaddon/src/csfixups.qc
quakec/csaddon/src/editor_lights.qc
quakec/csaddon/src/editor_terrain.qc
quakec/csaddon/src/brush_selection.qc
quakec/csaddon/src/brush_history.qc
quakec/csaddon/src/brush_manip.qc
quakec/csaddon/src/brush_draw.qc
quakec/csaddon/src/brush_vertedit.qc
quakec/csaddon/src/editor_brushes.qc
quakec/csaddon/src/editor_ents.qc
quakec/csaddon/src/textfield.qc
quakec/csaddon/src/editor_particles.qc
quakec/csaddon/src/menu.qc
quakec/csaddon/src/cam.qc
quakec/csaddon/src/csaddon.qc
)
ENDIF()
ENDIF()

View File

@ -89,12 +89,12 @@ if [ "$FTEQCC" != "" ]; then
( cd quakec/csaddon/src
echo -n "Making csaddon... "
$FTEQCC -srcfile csaddon.src > $BUILDLOGFOLDER/csaddon.txt 2>&1
$FTEQCC -srcfile csaddon.src > $BUILDLOGFOLDER/csaddon.txt
if [ $? -eq 0 ]; then
echo "done"
cp ../csaddon.dat $BUILDFOLDER/csaddon/
cd ..
zip -q9 $BUILDFOLDER/csaddon/csaddon.pk3 csaddon.dat
zip -9 $BUILDFOLDER/csaddon/csaddon.pk3 csaddon.dat
else
echo "failed"
fi
@ -102,13 +102,13 @@ if [ "$FTEQCC" != "" ]; then
( cd quakec/menusys
echo -n "Making menusys... "
$FTEQCC -srcfile menu.src > $BUILDLOGFOLDER/menu.txt 2>&1
$FTEQCC -srcfile menu.src > $BUILDLOGFOLDER/menu.txt
if [ $? -eq 0 ]; then
echo "done"
zip -q -q9 -o -r $BUILDFOLDER/csaddon/menusys_src.zip .
zip -q -9 -o -r $BUILDFOLDER/csaddon/menusys_src.zip .
cp ../menu.dat $BUILDFOLDER/csaddon/
cd ..
zip -q9 $BUILDFOLDER/csaddon/menusys.pk3 menu.dat
zip -9 $BUILDFOLDER/csaddon/menusys.pk3 menu.dat
else
echo "failed"
fi

View File

@ -37,27 +37,26 @@ TARGETS_LINUX="qcc-rel rel dbg plugins-rel plugins-dbg" #gl-rel vk-rel
TARGETS_WINDOWS="sv-rel m-rel qcc-rel qccgui-scintilla qccgui-dbg m-dbg sv-dbg plugins-dbg plugins-rel" #gl-rel vk-rel mingl-rel d3d-rel
PLUGINS_DROID="qi ezhud irc hl2"
PLUGINS_LINUXx86="openxr ode qi ezhud xmpp irc hl2"
PLUGINS_LINUXx64="openxr ode qi ezhud xmpp irc hl2"
PLUGINS_LINUXx32="qi ezhud xmpp irc hl2"
PLUGINS_LINUXarmhf="qi ezhud xmpp irc hl2"
PLUGINS_LINUXaarch64="qi ezhud xmpp irc hl2"
PLUGINS_DROID="qi ezhud irc"
PLUGINS_LINUXx86="openxr ode qi ezhud xmpp irc"
PLUGINS_LINUXx64="openxr ode qi ezhud xmpp irc"
PLUGINS_LINUXx32="qi ezhud xmpp irc"
PLUGINS_LINUXarmhf="qi ezhud xmpp irc"
if [ "$(uname -m)" != "x86_64" ]; then
PLUGINS_LINUXx86="openxr ode qi ezhud xmpp irc hl2"
PLUGINS_LINUXx86="openxr ode qi ezhud xmpp irc"
fi
if [ "$(uname -m)" == "x86_64" ]; then
PLUGINS_LINUX64="openxr ode qi ezhud xmpp irc hl2"
PLUGINS_LINUX64="openxr ode qi ezhud xmpp irc"
fi
#windows is always cross compiled, so we don't have issues with non-native ffmpeg
#windows doesn't cross compile, so no system dependancy issues
#skip some dependancies if we're running on cygwin, ode is buggy.
if [ "$(uname -s)" == "Linux" ]; then
PLUGINS_WIN32="ode qi ezhud xmpp irc hl2"
PLUGINS_WIN64="ode qi ezhud xmpp irc hl2"
PLUGINS_WIN32="ode qi ezhud xmpp irc"
PLUGINS_WIN64="ode qi ezhud xmpp irc"
else
PLUGINS_WIN32="qi ezhud xmpp irc hl2"
PLUGINS_WIN64="qi ezhud xmpp irc hl2"
PLUGINS_WIN32="qi ezhud xmpp irc"
PLUGINS_WIN64="qi ezhud xmpp irc"
fi
echo
@ -195,7 +194,6 @@ BUILD_LINUXx86=${BUILD_LINUXx86:-y}
BUILD_LINUXx64=${BUILD_LINUXx64:-y}
BUILD_LINUXx32=${BUILD_LINUXx32:-n}
BUILD_LINUXarmhf=${BUILD_LINUXarmhf:-n}
BUILD_LINUXaarch64=${BUILD_LINUXaarch64:-n}
BUILD_CYGWIN=${BUILD_CYGWIN:-n}
BUILD_WIN32=${BUILD_WIN32:-y}
BUILD_WIN64=${BUILD_WIN64:-y}
@ -228,7 +226,6 @@ if [ "$UID" != "0" ]; then
echo "BUILD_LINUXx64=\"$BUILD_LINUXx64\"" >>$FTECONFIG
echo "BUILD_LINUXx32=\"$BUILD_LINUXx32\"" >>$FTECONFIG
echo "BUILD_LINUXarmhf=\"$BUILD_LINUXarmhf\"" >>$FTECONFIG
echo "BUILD_LINUXaarch64=\"$BUILD_LINUXaarch64\"" >>$FTECONFIG
echo "BUILD_CYGWIN=\"$BUILD_CYGWIN\"" >>$FTECONFIG
echo "BUILD_WIN32=\"$BUILD_WIN32\"" >>$FTECONFIG
echo "BUILD_WIN64=\"$BUILD_WIN64\"" >>$FTECONFIG
@ -248,7 +245,6 @@ if [ "$UID" != "0" ]; then
echo "PLUGINS_LINUXx64=\"$PLUGINS_LINUXx64\"" >>$FTECONFIG
echo "PLUGINS_LINUXx32=\"$PLUGINS_LINUXx32\"" >>$FTECONFIG
echo "PLUGINS_LINUXarmhf=\"$PLUGINS_LINUXarmhf\"" >>$FTECONFIG
echo "PLUGINS_LINUXaarch64=\"$PLUGINS_LINUXaarch64\"" >>$FTECONFIG
echo "PLUGINS_DROID=\"$PLUGINS_DROID\"" >>$FTECONFIG
fi
@ -483,10 +479,6 @@ if [ $UID -ne 0 ] && [ $REBUILD_TOOLCHAINS == "y" ]; then
echo "Making libraries (linux armhf)..."
make FTE_TARGET=linuxarmhf makelibs CPUOPTIMISATIONS=-fno-finite-math-only 2>&1 >>/dev/null
fi
if [ "$BUILD_LINUXaarch64" == "y" ]; then
echo "Making libraries (linux aarch64)..."
make FTE_TARGET=linuxaarch64 makelibs CPUOPTIMISATIONS=-fno-finite-math-only 2>&1 >>/dev/null
fi
if [ "$BUILD_WIN32" == "y" ]; then
echo "Making libraries (win32)..."
make FTE_TARGET=win32 makelibs CPUOPTIMISATIONS=-fno-finite-math-only 2>&1 >>/dev/null

View File

@ -20,11 +20,11 @@ BUILD_WIN32=y
BUILD_WIN64=y
BUILD_ANDROID=y
BUILD_WEB=y
PLUGINS_LINUXx86="qi ezhud xmpp irc hl2"
PLUGINS_LINUXx64="qi ezhud xmpp irc hl2"
PLUGINS_LINUXx32="qi ezhud xmpp irc hl2"
PLUGINS_WIN32="ffmpeg ode qi ezhud xmpp irc hl2"
PLUGINS_WIN64="ffmpeg ode qi ezhud xmpp irc hl2"
PLUGINS_LINUXx86="qi ezhud xmpp irc"
PLUGINS_LINUXx64="qi ezhud xmpp irc"
PLUGINS_LINUXx32="qi ezhud xmpp irc"
PLUGINS_WIN32="ffmpeg ode qi ezhud xmpp irc"
PLUGINS_WIN64="ffmpeg ode qi ezhud xmpp irc"
THREADS="-j 4"
TARGETS_LINUX="qcc-rel rel dbg vk-rel plugins-rel plugins-dbg"
@ -81,7 +81,6 @@ do
BUILD_LINUXx86="n"
BUILD_LINUXx64="n"
BUILD_LINUXarmhf="n"
BUILD_LINUXaarch64="n"
BUILD_WIN32="n"
BUILD_WIN64="n"
BUILD_ANDROID="n"
@ -91,7 +90,6 @@ do
BUILD_LINUXx86="n"
BUILD_LINUXx64="n"
BUILD_LINUXarmhf="n"
BUILD_LINUXaarch64="n"
BUILD_WIN32="n"
BUILD_WIN64="n"
BUILD_ANDROID="y"
@ -176,8 +174,6 @@ function build {
fi
echo -n "Making $NAME... "
date > $BUILDLOGFOLDER/$DEST.txt
echo BUILD: $NAME >> $BUILDLOGFOLDER/$DEST.txt
echo PLUGINS: $NATIVE_PLUGINS >> $BUILDLOGFOLDER/$DEST.txt
echo make $MAKEARGS $* >> $BUILDLOGFOLDER/$DEST.txt 2>&1
make $MAKEARGS $* >> $BUILDLOGFOLDER/$DEST.txt 2>&1
if [ $? -eq 0 ]; then
@ -219,9 +215,6 @@ if [ "$BUILD_LINUXarmhf" != "n" ]; then
#debian/ubuntu's armhf targets armv7. we instead target armv6, because that means we work on rpi too (but still with hard-float). It should be compatible although we likely need more ops.
NATIVE_PLUGINS="$PLUGINS_LINUXarmhf" build "Linux ARMhf" linux_armhf FTE_TARGET=linux_armhf CPUOPTIMIZATIONS=-fno-finite-math-only $TARGETS_LINUX
fi
if [ "$BUILD_LINUXaarch64" != "n" ]; then
NATIVE_PLUGINS="$PLUGINS_LINUXaarch64" build "Linux aarch64" linux_aarch64 FTE_TARGET=linux_aarch64 CPUOPTIMIZATIONS=-fno-finite-math-only $TARGETS_LINUX
fi
if [ "$BUILD_CYGWIN" != "n" ]; then
NATIVE_PLUGINS="qi ezhud" build "Cygwin" cygwin qcc-rel rel dbg plugins-rel plugins-dbg
fi
@ -343,9 +336,6 @@ fi
if [ "$BUILD_LINUXarmhf" != "n" ]; then
cp $BUILDFOLDER/linux_armhf/fteqccarmhf $QCCBUILDFOLDER/linuxarmhf-fteqcc
fi
if [ "$BUILD_LINUXaarch64" != "n" ]; then
cp $BUILDFOLDER/linux_armhf/fteqccaarch64 $QCCBUILDFOLDER/linuxaarch64-fteqcc
fi
if [ "$BUILD_WIN32" != "n" ]; then
cp $BUILDFOLDER/win32/fteqcc.exe $QCCBUILDFOLDER/win32-fteqcc.exe
cp $BUILDFOLDER/win32/fteqccgui.exe $QCCBUILDFOLDER/win32-fteqccgui.exe

View File

@ -31,7 +31,6 @@ STRIP?=strip
STRIPFLAGS=--strip-unneeded --remove-section=.comment
VISIBILITY_FLAGS=-fvisibility=hidden #just assume this for sanities sake. disable only for compilers that error.
CPUOPTIMIZATIONS=-Os
COMPILE_SYS:=$(shell uname -o 2>&1)
@ -53,18 +52,12 @@ ifeq ($(SVNREVISION),)
SVN_VERSION:=$(shell test -d $(BASE_DIR)/../.svn && svnversion $(BASE_DIR))
SVN_DATE:=$(shell test -d $(BASE_DIR)/../.svn && cd $(BASE_DIR) && svn info --show-item last-changed-date --no-newline)
ifeq (,$(SVN_VERSION))
#grab the svn version from git-svn (assuming no other modifications). this fails when there's extra commits (probably a good thing).
SVN_VERSION=$(shell test -d $(BASE_DIR)/../.git && git svn find-rev `git rev-parse HEAD`)
SVN_DATE:=$(shell test -d $(BASE_DIR)/../.git && git log -1 --format=%cs $(BASE_DIR))
endif
ifeq (,$(SVN_VERSION))
#try to get git version info instead. this usually uses git-count-hash[-dirty] format
SVN_VERSION:=$(shell test -d $(BASE_DIR)/../.git && cd $(BASE_DIR) && echo $$((`git rev-list HEAD --count` + 29)))
GIT_VERSION:=$(shell test -d $(BASE_DIR)/../.git && cd $(BASE_DIR) && git describe --long --always --dirty)
#try to get git version info instead.
SVN_VERSION:=$(shell test -d $(BASE_DIR)/../.git && cd $(BASE_DIR) && git describe --long --always --dirty)
SVN_DATE:=$(shell test -d $(BASE_DIR)/../.git && git log -1 --format=%cs $(BASE_DIR))
ifneq (,$(SVN_VERSION))
#make sure its prefixed with something specific. we use versions for versioning, which will confuse the update mechanism if they're inconsistent - like random hashses that have no implied ordering...
SVN_VERSION:=git-$(SVN_VERSION)-$(GIT_VERSION)
SVN_VERSION:=git-$(SVN_VERSION)
endif
endif
@ -76,14 +69,14 @@ ifneq (M,$(findstring M,$(SVN_VERSION)))
SVNREVISION+=-DSVNDATE=$(SVN_DATE)
endif
endif
MAKE:=$(MAKE) --no-print-directory SVNREVISION="$(SVNREVISION)" SVN_VERSION="$(SVN_VERSION)"
MAKE:=$(MAKE) --no-print-directory SVNREVISION="$(SVNREVISION)"
#WHOAMI:=$(shell whoami)
#update these to download+build a different version. this assumes that the url+subdirs etc contain a consistant version everywhere.
JPEGVER=9c
ZLIBVER=1.2.12
ZLIBVER=1.2.11
PNGVER=1.6.37
OGGVER=1.3.4
VORBISVER=1.3.6
@ -123,7 +116,7 @@ endif
FTE_CONFIG?=fteqw
ifneq ($(findstring msvc,$(FTE_TARGET)),msvc)
ifeq (,$(FTE_CONFIG_EXTRA))
export FTE_CONFIG_EXTRA := $(shell $(CC) -xc -E -P -DFTE_TARGET_$(FTE_TARGET) -DCOMPILE_OPTS $(CFLAGS) common/config_$(FTE_CONFIG).h)
export FTE_CONFIG_EXTRA := $(shell $(CC) -xc -E -P -DFTE_TARGET_$(FTE_TARGET) -DCOMPILE_OPTS common/config_$(FTE_CONFIG).h)
endif
endif
BRANDFLAGS+=-DCONFIG_FILE_NAME=config_$(FTE_CONFIG).h $(FTE_CONFIG_EXTRA)
@ -134,8 +127,8 @@ endif
ifeq (,$(findstring DNO_OPUS,$(FTE_CONFIG_EXTRA)))
USE_OPUS=1
endif
ifneq (,$(findstring DLINK_QUAKE3,$(FTE_CONFIG_EXTRA)))
LINK_QUAKE3=1
ifeq (,$(findstring DNO_BOTLIB,$(FTE_CONFIG_EXTRA)))
USE_BOTLIB=1
endif
ifeq (,$(findstring DNO_VORBISFILE,$(FTE_CONFIG_EXTRA)))
USE_VORBISFILE=1
@ -156,13 +149,8 @@ ifneq (,$(findstring -Os,$(FTE_CONFIG_EXTRA)))
CPUOPTIMIZATIONS+=-Os
BRANDFLAGS:=$(filter-out -O%,$(BRANDFLAGS))
endif
ifneq (,$(findstring DLINK_ODE,$(FTE_CONFIG_EXTRA)))
#ode library will be statically linked.
LINK_ODE=1
endif
ifneq (,$(findstring DLINK_INTERNAL_BULLET,$(FTE_CONFIG_EXTRA)))
#bullet plugin will be built into the exe itself
INTERNAL_BULLET=1
INTERNAL_BULLET=1 #bullet plugin will be built into the exe itself
endif
ifeq ($(BITS),64)
@ -481,14 +469,6 @@ ifeq ($(FTE_TARGET),linux_arm64)
BITS=arm64
USE_SPEEX=0 #fails to compile due to neon asm, I'm just going to disable it (will still soft-link).
endif
ifeq ($(FTE_TARGET),linux_aarch64)
FTE_TARGET=linux
CC=aarch64-linux-gnu-gcc
CXX=aarch64-linux-gnu-g++
STRIP=aarch64-linux-gnu-strip
BITS=aarch64
USE_SPEEX=0 #fails to compile due to neon asm, I'm just going to disable it (will still soft-link).
endif
ifeq ($(FTE_TARGET),linux_x32)
#DO NOT CONFUSE WITH linux_x86. this target is amd64-with-32bit-pointers
#note: the x32 abi is still not finished or something.
@ -513,11 +493,6 @@ ifeq ($(FTE_TARGET),linux64)
STRIP=strip
BITS=64
endif
ifeq ($(FTE_TARGET),web)
CC=emcc
CXX=em++
AR=emar
endif
ifeq ($(FTE_TARGET),cygwin)
FTE_TARGET=cyg
endif
@ -575,6 +550,7 @@ HTTP_DIR=$(BASE_DIR)/http
LIBS_DIR?=.
PROGS_DIR=$(BASE_DIR)/qclib
NACL_DIR=$(BASE_DIR)/nacl
BOTLIB_DIR=$(BASE_DIR)/botlib
ifeq ($(NOCOMPAT),1)
NCCFLAGS=-DNOLEGACY -DOMIT_QCC
@ -604,7 +580,6 @@ DO_CXX=$(DO_ECHO) $(CXX) $(LTO_CC) $(ALL_CXXFLAGS) -o $@ -c $<
ifeq ($(findstring msvc,$(FTE_TARGET)),msvc)
BASELDFLAGS=
VISIBILITY_FLAGS=
endif
ifeq ($(FTE_TARGET),cyg)
BASELDFLAGS=-lm
@ -615,9 +590,18 @@ endif
ifeq ($(FTE_TARGET),morphos)
BASELDFLAGS=-lm
endif
ifneq (,$(findstring bsd,$(FTE_TARGET)))
BASELDFLAGS=-lm
VISIBILITY_FLAGS=-fvisibility=hidden
endif
ifneq (,$(findstring linux,$(FTE_TARGET)))
VISIBILITY_FLAGS=-fvisibility=hidden
endif
ifneq (,$(findstring droid,$(FTE_TARGET)))
VISIBILITY_FLAGS=-fvisibility=hidden
endif
ifneq (,$(findstring macos,$(FTE_TARGET)))
VISIBILITY_FLAGS=-fvisibility=hidden
endif
BASELDFLAGS ?= -lm -ldl -lpthread
@ -634,6 +618,7 @@ ifeq (win,$(findstring cyg,$(FTE_TARGET))$(findstring win,$(FTE_TARGET)))
endif
OGGVORBISLDFLAGS ?= -lvorbisfile -lvorbis -logg
VISIBILITY_FLAGS?=
#BASELDFLAGS=-lm -lz
XLDFLAGS=-L$(ARCHLIBS) $(IMAGELDFLAGS)
@ -650,12 +635,12 @@ 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) $(SVNREVISION)
BASE_CFLAGS=$(WARNINGFLAGS) $(GNUC_FUNCS) $(BASE_INCLUDES) -I$(LIBS_DIR)/dxsdk9/include -I$(LIBS_DIR)/dxsdk7/include $(SDL_INCLUDES) $(BOTLIB_CFLAGS) $(SVNREVISION)
CLIENT_ONLY_CFLAGS=-DCLIENTONLY
SERVER_ONLY_CFLAGS=-DSERVERONLY
JOINT_CFLAGS=
DEBUG_CFLAGS?=-ggdb -g
DEBUG_CFLAGS+=-DDEBUG -D_DEBUG
DEBUG_CFLAGS+=-DDEBUG
RELEASE_CFLAGS?=$(CPUOPTIMIZATIONS)
#
#note: RELEASE_CFLAGS used to contain -ffast-math
@ -697,7 +682,7 @@ endif
PKGCONFIG?=$(ARCH)-pkg-config
ifeq ($(shell which $(PKGCONFIG) 2> /dev/null),)
FFS:=$(shell echo $(PKGCONFIG) not found 1>&2 )
PKGCONFIG=/bin/false #don't end up using eg /usr/include when cross-compiling. makelibs is a valid workaround.
PKGCONFIG=/bin/true #don't end up using eg /usr/include when cross-compiling. makelibs is a valid workaround.
endif
#try to statically link
ifeq ($(COMPILE_SYS),Darwin)
@ -717,8 +702,6 @@ ifeq ($(FTE_TARGET),SDL2)
BASE_CFLAGS+=-DLIBJPEG_STATIC -DLIBJPEG_STATIC -DLIBPNG_STATIC -DOPUS_STATIC -DSPEEX_STATIC -DFREETYPE_STATIC -DLIBVORBISFILE_STATIC
endif
VPATH := $(BASE_DIR) : $(CLIENT_DIR) : $(GL_DIR) : $(SW_DIR) : $(COMMON_DIR) : $(SERVER_DIR) : $(HTTP_DIR) : $(QUX_DIR) : $(PROGS_DIR) : $(NACL_DIR) : $(D3D_DIR) : $(VK_DIR) : $(BASE_DIR)/web
PROFILE_CFLAGS=-pg
DX7SDK=-I./libs/dxsdk7/include/
@ -743,7 +726,10 @@ 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 \
@ -877,6 +863,7 @@ SERVER_OBJS = \
savegame.o \
svq2_ents.o \
svq2_game.o \
svq3_game.o \
webgen.o \
ftpserver.o \
httpserver.o
@ -911,7 +898,6 @@ COMMON_OBJS = \
com_bih.o \
com_mesh.o \
common.o \
json.o \
cvar.o \
cmd.o \
crc.o \
@ -921,6 +907,7 @@ COMMON_OBJS = \
fs_stdio.o \
fs_pak.o \
fs_zip.o \
fs_vpk.o \
fs_dzip.o \
fs_xz.o \
m_download.o \
@ -939,6 +926,7 @@ COMMON_OBJS = \
r_d3.o \
gl_q2bsp.o \
glmod_doom.o \
q3common.o \
world.o \
sv_phys.o \
sv_move.o \
@ -950,15 +938,9 @@ COMMON_OBJS = \
q1bsp.o \
q2pmove.o
ifeq (1,$(LINK_QUAKE3))
VPATH := $(VPATH) : $(BASE_DIR)/../plugins/quake3 : $(BASE_DIR)/../plugins/quake3/botlib
ALL_CFLAGS+=-DBOTLIB -DBOTLIB_STATIC -DSTATIC_Q3
COMMON_OBJS += \
clq3_parse.o \
clq3_ui.o \
clq3_cg.o \
svq3_game.o \
q3common.o \
ifeq (1,$(USE_BOTLIB))
BOTLIB_CFLAGS=-I$(BOTLIB_DIR) -DBOTLIB -DBOTLIB_STATIC
BOTLIB_OBJS = \
be_aas_bspq3.o \
be_aas_cluster.o \
be_aas_debug.o \
@ -1045,10 +1027,6 @@ ifeq (1,$(LINK_ZLIB))
CLIENTLIBFLAGS+=-DZLIB_STATIC
CLIENTLDDEPS+=-lz
endif
ifeq (1,$(LINK_ODE))
ALL_CFLAGS+=$(shell $(PKGCONFIG) ode --cflags --silence-errors) -DODE_STATIC
COMMONLDDEPS+=$(shell $(PKGCONFIG) ode --libs --silence-errors)
endif
ifeq (1,$(strip $(INTERNAL_BULLET)))
COMMON_OBJS+=com_phys_bullet.o
ALL_CFLAGS+=-I/usr/include/bullet -I$(ARCHLIBS)/bullet3-$(BULLETVER)/src
@ -1073,7 +1051,7 @@ endif
SDLCONFIG?=sdl-config
FTE_FULLTARGET?=sdl$(FTE_TARGET)$(BITS)
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_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)
@ -1089,19 +1067,19 @@ else
M_LDFLAGS=$(MLDFLAGS) $(IMAGELDFLAGS) `$(SDLCONFIG) --libs`
SV_LDFLAGS=`$(SDLCONFIG) --libs`
endif
GL_CFLAGS=-DFTE_SDL $(GLCFLAGS) -DMULTITHREAD `$(SDLCONFIG) --cflags`
GL_CFLAGS=-DFTE_SDL $(GLCFLAGS) -DMLTITHREAD `$(SDLCONFIG) --cflags`
GLB_DIR=gl_$(FTE_FULLTARGET)
GLCL_DIR=glcl_$(FTE_FULLTARGET)
SV_DIR?=sv_$(FTE_FULLTARGET)
VKCL_OBJS=$(VKQUAKE_OBJS) $(D3DGL_OBJS) gl_bloom.o gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o
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
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)
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(SERVERONLY_OBJS) $(BOTLIB_OBJS)
SV_EXE_NAME=../$(EXE_NAME)-sv$(FTE_FULLTARGET)
SV_CFLAGS=-DFTE_SDL -DMULTITHREAD `$(SDLCONFIG) --cflags` $(SERVER_ONLY_CFLAGS)
@ -1112,8 +1090,8 @@ 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) gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o
M_CFLAGS=-DFTE_SDL $(VKCFLAGS) $(GLCFLAGS) -DMULTITHREAD `$(SDLCONFIG) --cflags`
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(BOTLIB_OBJS) gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o
M_CFLAGS=-DFTE_SDL $(VKCFLAGS) $(GLCFLAGS) -DMULTITHRED `$(SDLCONFIG) --cflags`
QCC_DIR=qcc$(BITS)
@ -1181,7 +1159,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) sys_ppapi.o cd_null.o gl_vidppapi.o fs_ppapi.o snd_ppapi.o
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
GL_LDFLAGS=$(GLLDFLAGS)
M_LDFLAGS=$(GLLDFLAGS)
@ -1215,7 +1193,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) 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) $(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)
GL_EXE_NAME=../$(EXE_NAME)-sdl-gl$(BITS)$(EXEPOSTFIX)
GLCL_EXE_NAME=../$(EXE_NAME)-sdl-glcl$(BITS)$(EXEPOSTFIX)
ifdef windir
@ -1237,7 +1215,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) $(LTO_END) resources.o $(LTO_START)
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(WINDOWSSERVERONLY_OBJS) $(BOTLIB_OBJS) $(LTO_END) resources.o $(LTO_START)
SV_EXE_NAME=../$(EXE_NAME)-sdl-sv$(BITS)$(EXEPOSTFIX)
SV_CFLAGS=$(SERVER_ONLY_CFLAGS) -DFTE_SDL
@ -1247,13 +1225,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) gl_vidsdl.o snd_sdl.o cd_sdl.o sys_sdl.o in_sdl.o snd_directx.o $(LTO_END) resources.o $(LTO_START)
#MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(D3DQUAKE_OBJS) $(BOTLIB_OBJS) 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) 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) $(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)
M_CFLAGS=$(VKCFLAGS) $(GLCFLAGS) -DFTE_SDL $(CLIENTLIBFLAGS) $(DX7SDK)
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)
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)
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
@ -1262,7 +1240,7 @@ ifeq (win_SDL,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET)))
D3DCL_DIR=sdl_d3dcl_mgw$(BITS)
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)
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)
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)
@ -1369,7 +1347,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) $(PROGS_OBJS) $(WINDOWSSERVERONLY_OBJS) fs_win32.o resources.o
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(BOTLIB_OBJS) $(PROGS_OBJS) $(WINDOWSSERVERONLY_OBJS) fs_win32.o resources.o
SV_LDFLAGS=ole32.lib /subsystem:console
GL_EXE_NAME=../$(EXE_NAME)-gl$(BITS)$(EXEPOSTFIX)
@ -1378,13 +1356,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) gl_vidnt.o $(WINDOWS_OBJS)
GLCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_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) gl_bloom.o gl_vidnt.o $(WINDOWS_OBJS)
VKCL_OBJS=$(VKQUAKE_OBJS) $(D3DGL_OBJS) $(BOTLIB_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/
@ -1392,7 +1370,7 @@ ifeq ($(findstring msvc,$(FTE_TARGET)),msvc)
VKB_DIR=vk_vc$(BITS)
VKCL_DIR=vkcl_vc$(BITS)
D3DCL_OBJS=$(D3DQUAKE_OBJS) $(D3DGL_OBJS) $(WINDOWS_OBJS)
D3DCL_OBJS=$(D3DQUAKE_OBJS) $(D3DGL_OBJS) $(BOTLIB_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
@ -1401,7 +1379,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) gl_vidnt.o gl_videgl.o $(WINDOWS_OBJS)
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(D3DQUAKE_OBJS) $(BOTLIB_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)
@ -1447,11 +1425,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) fs_win32.o $(LTO_END) resources.o $(LTO_START)
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(WINDOWSSERVERONLY_OBJS) $(BOTLIB_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) gl_vidnt.o $(WINDOWS_OBJS)
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_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
@ -1465,7 +1443,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) gl_vidnt.o gl_videgl.o $(WINDOWS_OBJS)
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(D3DQUAKE_OBJS) $(BOTLIB_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
@ -1473,7 +1451,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) $(WINDOWS_OBJS)
D3DCL_OBJS=$(D3DQUAKE_OBJS) $(D3DGL_OBJS) $(BOTLIB_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
@ -1481,7 +1459,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) $(WINDOWS_OBJS) gl_vidnt.o
VKCL_OBJS=$(GLQUAKE_OBJS) $(D3DGL_OBJS) $(BOTLIB_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
@ -1519,7 +1497,7 @@ ifeq ($(FTE_TARGET),bsd)
SV_LDFLAGS=-lpthread
SV_CFLAGS=$(SERVER_ONLY_CFLAGS) -DMULTITHREAD
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_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) $(BOTLIB_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
@ -1527,7 +1505,7 @@ ifeq ($(FTE_TARGET),bsd)
GLB_DIR=gl_bsd
GLCL_DIR=glcl_bsd
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_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) $(BOTLIB_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
@ -1588,7 +1566,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) 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) $(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
GL_EXE_NAME=../$(EXE_NAME)-gl$(BITS)
GLCL_EXE_NAME=../$(EXE_NAME)-glcl$(BITS)
GL_LDFLAGS=$(GLLDFLAGS) $(XLDFLAGS)
@ -1596,7 +1574,7 @@ ifneq (,$(findstring linux,$(FTE_TARGET)))
GLB_DIR=gl_linux$(BITS)
GLCL_DIR=glcl_linux$(BITS)
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
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
VK_EXE_NAME=../$(EXE_NAME)-vk$(BITS)
VKCL_EXE_NAME=../$(EXE_NAME)-vkcl$(BITS)
VK_LDFLAGS=$(GLLDFLAGS) $(XLDFLAGS)
@ -1604,7 +1582,7 @@ ifneq (,$(findstring linux,$(FTE_TARGET)))
VKB_DIR=vk_linux$(BITS)
VKCL_DIR=vkcl_linux$(BITS)
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
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
M_EXE_NAME=../$(EXE_NAME)$(BITS)
MCL_EXE_NAME=../$(EXE_NAME)-cl$(BITS)
M_LDFLAGS=$(GL_LDFLAGS)
@ -1659,7 +1637,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) 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) $(BOTLIB_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)
@ -1668,7 +1646,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) $(SERVERONLY_OBJS)
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(BOTLIB_OBJS) $(SERVERONLY_OBJS)
SV_EXE_NAME=../$(EXE_NAME)-macosx-sv$(EXTENSION)$(BITS)
SV_CFLAGS=$(SERVER_ONLY_CFLAGS)
SV_LDFLAGS=-lz
@ -1685,7 +1663,7 @@ ifeq ($(FTE_TARGET),morphos)
SV_DIR=sv_morphos
SV_LDFLAGS=-ldl -lz
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) gl_vidmorphos.o in_morphos.o snd_morphos.o cd_null.o sys_morphos.o
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) gl_vidmorphos.o in_morphos.o snd_morphos.o cd_null.o sys_morphos.o
GL_EXE_NAME=../$(EXE_NAME)-morphos-gl
GLCL_EXE_NAME=../$(EXE_NAME)-morphos-glcl
GL_LDFLAGS=$(GLLDFLAGS) -ldl $(IMAGELDFLAGS) -lz
@ -1693,7 +1671,7 @@ ifeq ($(FTE_TARGET),morphos)
GLB_DIR=gl_morphos
GLCL_DIR=glcl_morphos
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
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_OBJS) $(BOTLIB_OBJS) gl_vidmorphos.o vid_morphos.o in_morphos.o snd_morphos.o cd_null.o sys_morphos.o
M_EXE_NAME=../$(EXE_NAME)-morphos
MCL_EXE_NAME=../$(EXE_NAME)-morphos-cl
M_LDFLAGS=$(GLLDFLAGS)
@ -1704,7 +1682,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)
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(SERVERONLY_OBJS) $(BOTLIB_OBJS)
SV_EXE_NAME=../$(EXE_NAME)-morphos-sv$(BITS)
SV_CFLAGS=$(SERVER_ONLY_CFLAGS)
endif
@ -1730,7 +1708,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) cd_null.o sys_dos.o snd_sblaster.o
VKCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) cd_null.o sys_dos.o snd_sblaster.o
endif
ifeq ($(FTE_TARGET),cyg)
@ -1739,7 +1717,7 @@ ifeq ($(FTE_TARGET),cyg)
SV_CFLAGS=$(SERVER_ONLY_CFLAGS)
EXEPOSTFIX=.exe
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_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) $(BOTLIB_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
@ -1747,7 +1725,7 @@ ifeq ($(FTE_TARGET),cyg)
GLB_DIR=gl_cygwin
GLCL_DIR=glcl_cygwin
MCL_OBJS=$(D3DGL_OBJS) $(GLQUAKE_OBJS) $(SOFTWARE_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) $(BOTLIB_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
@ -1772,18 +1750,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) $(SYS_DROID_O)
SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(BOTLIB_OBJS) $(SYS_DROID_O)
SV_EXE_NAME=libftedroid.so
GL_CFLAGS=$(GLCFLAGS)
GL_LDFLAGS=$(GLLDFLAGS) -landroid
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(GL_DROID_O) cd_null.o snd_droid.o
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_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) $(GL_DROID_O) cd_null.o snd_opensl.o
MCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) $(GL_DROID_O) cd_null.o snd_opensl.o
#snd_droid.o
MB_DIR=m_droid-$(DROID_ARCH)
M_EXE_NAME=libftedroid.so
@ -1806,9 +1784,6 @@ ifeq ($(FTE_TARGET),web)
# EMCC_CFLAGS+= -s BINARYEN_TRAP_MODE='clamp' #fix bigfloat->int rounding crashes
EMCC_CFLAGS+= -s LEGACY_GL_EMULATION=0 #simplify the opengl wrappers.
EMCC_CFLAGS+= -s NO_FILESYSTEM=1 #we have our own.
EMCC_CFLAGS+= -s FILESYSTEM=0 #we have our own.
EMCC_CFLAGS+= -s ALLOW_MEMORY_GROWTH=1 #reduce crashes...
EMCC_CFLAGS+= -s MAX_WEBGL_VERSION=2 #make use of what we can.
EMCC_LDFLAGS+=-s ERROR_ON_UNDEFINED_SYMBOLS=1 #fairly obvious. no runtime errors please.
RELEASE_CFLAGS=-DOMIT_QCC -DGL_STATIC $(EMCC_CFLAGS)
DEBUG_CFLAGS=-g4 -DOMIT_QCC -DGL_STATIC $(EMCC_CFLAGS)
@ -1817,16 +1792,15 @@ ifeq ($(FTE_TARGET),web)
DEBUG_LDFLAGS=-O0 -g4 -s TOTAL_MEMORY=$(WEB_MEMORY) $(EMCC_LDFLAGS) -s SAFE_HEAP=1 -s ALIASING_FUNCTION_POINTERS=0 -s ASSERTIONS=2
CC=emcc
CXX=em++
AR=emar
BASELDFLAGS=-lz
#BASELDFLAGS=
PRECOMPHEADERS=
#mostly we inherit the sdl defaults. because we can, however emscripten does not support sdl cd code.
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(BOTLIB_OBJS) $(GLQUAKE_OBJS) gl_vidweb.o cd_null.o
GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) gl_vidweb.o cd_null.o
SDL_INCLUDES=
SV_DIR=sv_web
SV_LDFLAGS=
#SV_LDFLAGS=-lz
#SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS)
SV_EXE_NAME=../libftesv.js
SV_CFLAGS=$(SERVER_ONLY_CFLAGS)
@ -1846,6 +1820,7 @@ ifeq ($(FTE_TARGET),web)
CLIENTLDDEPS=
SERVERLDDEPS=
BOTLIB_CFLAGS=
#generate deps properly
#DEPCC=
#DEPCXX=
@ -1899,6 +1874,8 @@ ifneq ($(OUT_DIR),)
endif
VPATH = $(BASE_DIR) : $(CLIENT_DIR) : $(GL_DIR) : $(SW_DIR) : $(COMMON_DIR) : $(SERVER_DIR) : $(HTTP_DIR) : $(BASE_DIR)/irc : $(BASE_DIR)/email : $(QUX_DIR) : $(PROGS_DIR) : $(NACL_DIR) : $(D3D_DIR) : $(VK_DIR) : $(BOTLIB_DIR) : $(BASE_DIR)/web
DO_WINDRES?=$(DO_ECHO) $(WINDRES) $(BRANDFLAGS) -I$(CLIENT_DIR) -O coff $< $@
# This is for linking the FTE icon to the MinGW target
@ -2275,9 +2252,6 @@ nacl-dbg:
#################################################
#webgl helpers
ifeq ($(FTE_TARGET),web)
$(OUT_DIR)/$(EXE_NAME): web/ftejslib.js web/prejs.js
endif
ifneq ($(shell which emcc 2> /dev/null),)
EMCC?=emcc
else
@ -2298,16 +2272,16 @@ endif
web-rel:
@PATH="$(EMSCRIPTENPATH)" $(MAKE) gl-rel FTE_TARGET=web CC="$(EMCC)"
cp $(BASE_DIR)/web/fteshell.html $(RELEASE_DIR)/ftewebgl.html
@gzip -kf $(RELEASE_DIR)/ftewebgl.html
@gzip -kf $(RELEASE_DIR)/ftewebgl.js
@gzip -kf $(RELEASE_DIR)/ftewebgl.wasm
@gzip -f $(RELEASE_DIR)/ftewebgl.html
@gzip -f $(RELEASE_DIR)/ftewebgl.js
@gzip -f $(RELEASE_DIR)/ftewebgl.wasm
web-dbg:
@PATH="$(EMSCRIPTENPATH)" $(MAKE) gl-dbg FTE_TARGET=web CC="$(EMCC)"
cp $(BASE_DIR)/web/fteshell.html $(DEBUG_DIR)/ftewebgl.html
@gzip -kf $(DEBUG_DIR)/ftewebgl.html
@gzip -kf $(DEBUG_DIR)/ftewebgl.js
@gzip -kf $(DEBUG_DIR)/ftewebgl.wasm
@gzip -f $(DEBUG_DIR)/ftewebgl.html
@gzip -f $(DEBUG_DIR)/ftewebgl.js
@gzip -f $(DEBUG_DIR)/ftewebgl.wasm
#################################################
#android
@ -2420,15 +2394,9 @@ libs-$(ARCH)/libjpeg.a:
test -f jpegsrc.v$(JPEGVER).tar.gz || wget http://www.ijg.org/files/jpegsrc.v$(JPEGVER).tar.gz
-test -f libs-$(ARCH)/libjpeg.a || (mkdir -p libs-$(ARCH) && cd libs-$(ARCH) && tar -xvzf ../jpegsrc.v$(JPEGVER).tar.gz && cd jpeg-$(JPEGVER) && $(TOOLOVERRIDES) ./configure $(CONFIGARGS) && $(TOOLOVERRIDES) $(MAKE) && cp .libs/libjpeg.a ../ && $(TOOLOVERRIDES) $(AR) -s ../libjpeg.a && cp jconfig.h jerror.h jmorecfg.h jpeglib.h jversion.h ../ )
ifeq ($(FTE_TARGET),web)
libs-$(ARCH)/libz.a libs-$(ARCH)/libz.pc:
test -f zlib-$(ZLIBVER).tar.gz || wget http://zlib.net/zlib-$(ZLIBVER).tar.gz
-test -f libs-$(ARCH)/libz.a || (mkdir -p libs-$(ARCH) && cd libs-$(ARCH) && tar -xvzf ../zlib-$(ZLIBVER).tar.gz && cd zlib-$(ZLIBVER) && emconfigure ./configure --static && emmake $(MAKE) libz.a CC="$(CC) $(W32_CFLAGS) -fPIC" && cp libz.a ../ && $(TOOLOVERRIDES) $(AR) -s ../libz.a && cp zlib.h zconf.h zutil.h zlib.pc ../ )
else
libs-$(ARCH)/libz.a libs-$(ARCH)/libz.pc:
test -f zlib-$(ZLIBVER).tar.gz || wget http://zlib.net/zlib-$(ZLIBVER).tar.gz
-test -f libs-$(ARCH)/libz.a || (mkdir -p libs-$(ARCH) && cd libs-$(ARCH) && tar -xvzf ../zlib-$(ZLIBVER).tar.gz && cd zlib-$(ZLIBVER) && $(TOOLOVERRIDES) ./configure --static && $(TOOLOVERRIDES) $(MAKE) libz.a CC="$(CC) $(W32_CFLAGS) -fPIC" && cp libz.a ../ && $(TOOLOVERRIDES) $(AR) -s ../libz.a && cp zlib.h zconf.h zutil.h zlib.pc ../ )
endif
libs-$(ARCH)/libpng.a libs-$(ARCH)/libpng.pc: libs-$(ARCH)/libz.a libs-$(ARCH)/libz.pc
test -f libpng-$(PNGVER).tar.gz || wget http://prdownloads.sourceforge.net/libpng/libpng-$(PNGVER).tar.gz?download -O libpng-$(PNGVER).tar.gz
@ -2444,7 +2412,7 @@ libs-$(ARCH)/libvorbis.a: libs-$(ARCH)/libogg.a
libs-$(ARCH)/libopus.a:
test -f opus-$(OPUSVER).tar.gz || wget https://archive.mozilla.org/pub/opus/opus-$(OPUSVER).tar.gz
-test -f libs-$(ARCH)/libopus.a || (mkdir -p libs-$(ARCH) && cd libs-$(ARCH) && tar -xvzf ../opus-$(OPUSVER).tar.gz && cd opus-$(OPUSVER) && CFLAGS="-D_FORTIFY_SOURCE=0 $(CFLAGS) -Os" $(TOOLOVERRIDES) ./configure $(CONFIGARGS) && $(TOOLOVERRIDES) $(MAKE) && cp .libs/libopus.a ../ && cp include/opus*.h ../)
-test -f libs-$(ARCH)/libopus.a || (mkdir -p libs-$(ARCH) && cd libs-$(ARCH) && tar -xvzf ../opus-$(OPUSVER).tar.gz && cd opus-$(OPUSVER) && CFLAGS="$(CFLAGS) -Os" $(TOOLOVERRIDES) ./configure $(CONFIGARGS) && $(TOOLOVERRIDES) $(MAKE) && cp .libs/libopus.a ../ && cp include/opus*.h ../)
libs-$(ARCH)/libspeex.a:
test -f speex-$(SPEEXVER).tar.gz || wget http://downloads.us.xiph.org/releases/speex/speex-$(SPEEXVER).tar.gz
@ -2462,26 +2430,22 @@ libs-$(ARCH)/libBulletDynamics.a:
test -f bullet3-$(BULLETVER).tar.gz || wget https://github.com/bulletphysics/bullet3/archive/$(BULLETVER).tar.gz -O bullet3-$(BULLETVER).tar.gz
-test -f libs-$(ARCH)/libBulletDynamics.a || (mkdir -p libs-$(ARCH) && cd libs-$(ARCH) && tar -xvzf ../bullet3-$(BULLETVER).tar.gz && cd bullet3-$(BULLETVER) && CFLAGS="$(CFLAGS) -Os" $(TOOLOVERRIDES) $(DO_CMAKE) . && $(TOOLOVERRIDES) $(MAKE) LinearMath BulletDynamics BulletCollision && cp src/LinearMath/libLinearMath.a src/BulletDynamics/libBulletDynamics.a src/BulletCollision/libBulletCollision.a src/btBulletCollisionCommon.h src/btBulletDynamicsCommon.h ..)
ifeq ($(FTE_TARGET),web)
makelibs: libs-$(ARCH)/libz.a $(MAKELIBS)
else
makelibs: libs-$(ARCH)/libjpeg.a libs-$(ARCH)/libz.a libs-$(ARCH)/libpng.a libs-$(ARCH)/libogg.a libs-$(ARCH)/libvorbis.a libs-$(ARCH)/libopus.a libs-$(ARCH)/libspeex.a libs-$(ARCH)/libspeexdsp.a libs-$(ARCH)/libfreetype.a $(MAKELIBS)
endif
HTTP_OBJECTS=http/httpserver.c http/iwebiface.c common/fs_stdio.c http/ftpserver.c
$(RELEASE_DIR)/httpserver$(BITS)$(EXEPOSTFIX): $(HTTP_OBJECTS)
$(CC) -o $@ -Icommon -Iclient -Iqclib -Igl -Iserver -DWEBSERVER -DWEBSVONLY -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -DNO_PNG $(HTTP_OBJECTS)
httpserver: $(RELEASE_DIR)/httpserver$(BITS)$(EXEPOSTFIX)
IQM_OBJECTS=../iqm/iqm.cpp ../imgtool.c client/image.c common/json.c ../plugins/models/gltf.c
IQM_OBJECTS=../iqm/iqm.cpp ../imgtool.c client/image.c ../plugins/models/gltf.c
$(RELEASE_DIR)/iqmtool$(BITS)$(EXEPOSTFIX): $(IQM_OBJECTS)
ifeq (win,$(findstring win,$(FTE_TARGET)))
$(CC) -o $@ $(IQM_OBJECTS) -Icommon -Iclient -Iqclib -Igl -Iserver $(ALL_CFLAGS) $(CLIENTLIBFLAGS) -DIQMTOOL $(BASELDFLAGS) $(CLIENTLDDEPS) --static -static-libgcc -static-libstdc++ -lstdc++ -lm -Os
else
$(CC) -o $@ $(IQM_OBJECTS) -Icommon -Iclient -Iqclib -Igl -Iserver $(ALL_CFLAGS) -DIQMTOOL -lstdc++ -lm -ldl -Os
endif
iqm-rel: reldir $(RELEASE_DIR)/iqmtool$(BITS)$(EXEPOSTFIX)
iqmtool-rel: reldir $(RELEASE_DIR)/iqmtool$(BITS)$(EXEPOSTFIX)
iqm-rel: $(RELEASE_DIR)/iqmtool$(BITS)$(EXEPOSTFIX)
iqmtool-rel: $(RELEASE_DIR)/iqmtool$(BITS)$(EXEPOSTFIX)
iqm: iqm-rel
iqmtool: iqmtool-rel
@ -2525,7 +2489,7 @@ qtv-rel:
@$(MAKE) $(RELEASE_DIR)/qtv$(BITS)$(EXEPOSTFIX) VPATH="$(BASE_DIR)/../fteqtv:$(VPATH)"
qtv: qtv-rel
utils: httpserver iqmtool imgtool master qtv-rel
utils: httpserver iqm imgtool master qtv-rel
prefix ?= /usr/local
exec_prefix ?= $(prefix)
@ -2543,5 +2507,4 @@ install: sv-rel gl-rel mingl-rel qcc-rel
version:
@echo $(SVN_VERSION)
@echo $(SVN_DATE)
@echo $(FTE_CONFIG_EXTRA)

View File

@ -163,11 +163,6 @@ 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);
@ -189,7 +184,6 @@ void QDECL Q_strncpyz(char *d, const char *s, int n)
*d='\0';
}
/*
char *QDECL va(char *format, ...)
{
#define VA_BUFFER_SIZE 1024
@ -202,4 +196,3 @@ char *QDECL va(char *format, ...)
return string;
}
*/

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2015-2018
* Marco Cawthorne All rights reserved.
* Marco Hladik All rights reserved.
*
* This is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -1,15 +1,33 @@
#include "q3common.h"
#if defined(VM_CG) && defined(HAVE_CLIENT)
#include "quakedef.h"
//#include "cg_public.h"
#ifdef VM_CG
#include "shader.h"
#if 1
#include "glquake.h"//hack
#else
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
static model_t *box_model;
cvar_t *cl_shownet_ptr, *cl_c2sdupe_ptr, *cl_nodelta_ptr;
#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)
extern model_t box_model;
typedef enum {
CG_PRINT,
@ -118,11 +136,10 @@ 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;
/*
@ -223,19 +240,16 @@ unsigned int Contents_From_Q3(unsigned int Q3)
return ret;
}
#define MAX_GAMESTATE_CHARS 16000
#define MAX_CONFIGSTRINGS 1024
typedef struct {
int stringOffsets[MAX_Q3_CONFIGSTRINGS];
char stringData[MAX_Q3_GAMESTATE_CHARS];
int stringOffsets[MAX_CONFIGSTRINGS];
char stringData[MAX_GAMESTATE_CHARS];
int dataCount;
} gameState_t;
static gameState_t cggamestate;
gameState_t cggamestate;
void CG_ClearGameState(void)
{
memset(&cggamestate, 0, sizeof(cggamestate));
}
void CG_InsertIntoGameState(int num, const char *str)
void CG_InsertIntoGameState(int num, char *str)
{
if (num < 5)
{
@ -245,24 +259,24 @@ void CG_InsertIntoGameState(int num, const char *str)
if (num == CFGSTR_SYSINFO)
{
//check some things.
ccs.servercount = atoi(worldfuncs->GetInfoKey(str, "sv_serverid"));
cl.servercount = atoi(Info_ValueForKey(str, "sv_serverid"));
}
if (cggamestate.dataCount + strlen(str)+1 > countof(cggamestate.stringData))
if (cggamestate.dataCount + strlen(str)+1 > MAX_GAMESTATE_CHARS)
{
char oldstringData[countof(cggamestate.stringData)];
char oldstringData[MAX_GAMESTATE_CHARS];
int i;
char *oldstr;
//copy the old strings to a temporary buffer
memcpy(oldstringData, cggamestate.stringData, countof(cggamestate.stringData));
memcpy(oldstringData, cggamestate.stringData, MAX_GAMESTATE_CHARS);
cggamestate.dataCount = 0;
for (i = 0; i < countof(cggamestate.stringOffsets); i++)
for (i = 0; i < MAX_CONFIGSTRINGS; i++)
{
oldstr = oldstringData+cggamestate.stringOffsets[i];
if (*oldstr)
{
if (cggamestate.dataCount + strlen(oldstr)+1 > countof(cggamestate.stringData))
plugfuncs->EndGame("Too much configstring text\n");
if (cggamestate.dataCount + strlen(oldstr)+1 > MAX_GAMESTATE_CHARS)
Host_EndGame("Too much configstring text\n");
cggamestate.dataCount+=1;
strcpy(cggamestate.stringData+cggamestate.dataCount, oldstr);
@ -286,9 +300,9 @@ void CG_InsertIntoGameState(int num, const char *str)
cggamestate.dataCount += strlen(str);
}
const char *CG_GetConfigString(int num)
char *CG_GetConfigString(int num)
{
if ((unsigned)num >= countof(cggamestate.stringOffsets))
if ((unsigned)num >= MAX_CONFIGSTRINGS)
return "";
return cggamestate.stringData + cggamestate.stringOffsets[num];
}
@ -302,7 +316,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 inputfuncs->GetMoveCount()-1;
return cl.movesequence-1;
}
static qboolean CGQ3_GetUserCmd(int cmdNumber, q3usercmd_t *ucmd)
{
@ -312,14 +326,14 @@ static qboolean CGQ3_GetUserCmd(int cmdNumber, q3usercmd_t *ucmd)
usercmd_t *cmd;
//q3 does not do partials.
if (cmdNumber < 0)
return false; //grr, stoopid q3.
if (cmdNumber >= inputfuncs->GetMoveCount())
plugfuncs->EndGame("CLQ3_GetUserCmd: %i >= %i", cmdNumber, inputfuncs->GetMoveCount());
if (cmdNumber >= cl.movesequence)
Host_EndGame("CLQ3_GetUserCmd: %i >= %i", cmdNumber, cl.movesequence);
cmd = inputfuncs->GetMoveEntry(cmdNumber);
if (!cmd)
if (cl.movesequence - (cmdNumber+1) > Q3CMD_BACKUP)
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];
@ -330,19 +344,16 @@ static qboolean CGQ3_GetUserCmd(int cmdNumber, q3usercmd_t *ucmd)
ucmd->buttons = cmd->buttons;
ucmd->weapon = cmd->weapon;
return true;
}
vm_t *cgvm;
static const char *mapentspointer;
static vm_t *cgvm;
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
@ -351,32 +362,31 @@ qboolean CG_GetServerCommand(int cmdnum)
char *str = ccs.serverCommands[cmdnum & Q3TEXTCMD_MASK];
Con_DPrintf("Dispaching %s\n", str);
cmdfuncs->TokenizeString(str);
arg0 = cmdfuncs->Argv(0, NULL, 0);
Cmd_TokenizeString(str, false, false);
if (!strcmp(arg0, "bcs0"))
if (!strcmp(Cmd_Argv(0), "bcs0"))
{ //start
Q_snprintfz(bigconfigstring, sizeof(bigconfigstring), "cs %s \"%s", cmdfuncs->Argv(1, NULL, 0), cmdfuncs->Argv(2, NULL, 0));
Q_snprintfz(bigconfigstring, sizeof(bigconfigstring), "cs %s \"%s", Cmd_Argv(1), Cmd_Argv(2));
return false;
}
if (!strcmp(arg0, "bcs1"))
if (!strcmp(Cmd_Argv(0), "bcs1"))
{ //continuation
Q_strncatz(bigconfigstring, cmdfuncs->Argv(2, NULL, 0), sizeof(bigconfigstring));
Q_strncatz(bigconfigstring, Cmd_Argv(2), sizeof(bigconfigstring));
return false;
}
if (!strcmp(arg0, "bcs2"))
if (!strcmp(Cmd_Argv(0), "bcs2"))
{ //end
Q_strncatz(bigconfigstring, cmdfuncs->Argv(2, NULL, 0), sizeof(bigconfigstring));
Q_strncatz(bigconfigstring, Cmd_Argv(2), sizeof(bigconfigstring));
Q_strncatz(bigconfigstring, "\"", sizeof(bigconfigstring));
cmdfuncs->TokenizeString(bigconfigstring);
Cmd_TokenizeString(bigconfigstring, false, false);
}
if (!strcmp(arg0, "cs"))
CG_InsertIntoGameState(atoi(cmdfuncs->Argv(1, NULL, 0)), cmdfuncs->Argv(2, NULL, 0));
else if (!strcmp(arg0, "map_restart"))
clientfuncs->ClearNotify();
else if (!strcmp(arg0, "disconnect"))
plugfuncs->EndGame("Server disconnected - %s", (cmdfuncs->Argc()>1)?cmdfuncs->Argv(1, NULL, 0):"No reason given");
if (!strcmp(Cmd_Argv(0), "cs"))
CG_InsertIntoGameState(atoi(Cmd_Argv(1)), Cmd_Argv(2));
else if (!strcmp(Cmd_Argv(0), "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");
return true;
}
@ -468,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;
scenefuncs->ClipDecal(ccs.worldmodel, center, axis[0], axis[1], axis[2], radius, 0,0, CG_MarkFragments_Callback, &ctx);
Mod_ClipDecal(cl.worldmodel, center, axis[0], axis[1], axis[2], radius, 0,0, CG_MarkFragments_Callback, &ctx);
return ctx.numfrags;
}
@ -511,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, int range, const char *soundname, float volume, qboolean persistent)
static void CG_StartLoopingSounds(unsigned int entnum, float *origin, float *velocity, const char *soundname, qboolean persistent)
{
size_t i;
for (i = 0; i < numloopers; i++)
@ -529,10 +539,8 @@ 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 = audiofuncs->PrecacheSound(soundname);
loopers[i].sfx = S_PrecacheSound(soundname);
loopers[i].ispersistent = persistent;
// loopers[i].range = range;
// loopers[i].volume = volume;
}
static void CG_MoveLoopingSound(unsigned int entnum, float *origin)
{
@ -567,11 +575,9 @@ static void CG_ClearLoopingSounds(qboolean clearall)
}
}
int VM_LerpTag(void *out, model_t *model, int f1, int f2, float l2, char *tagname);
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.
#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.
static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, const qintptr_t *arg)
{
@ -587,28 +593,25 @@ 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((cgameImport_t)fn)
switch(fn)
{
case CG_PRINT:
{
const char *text = VM_POINTER(arg[0]);
Con_Printf("%s", text);
}
Con_Printf("%s", (char*)VM_POINTER(arg[0]));
break;
case CG_ERROR:
plugfuncs->EndGame("cgame: %s", (char*)VM_POINTER(arg[0]));
Host_EndGame("cgame: %s", (char*)VM_POINTER(arg[0]));
break;
case CG_ARGC:
VM_LONG(ret) = cmdfuncs->Argc();
VM_LONG(ret) = Cmd_Argc();
break;
case CG_ARGV:
VALIDATEPOINTER(arg[1], arg[2]);
cmdfuncs->Argv(VM_LONG(arg[0]), VM_POINTER(arg[1]), VM_LONG(arg[2]));
Q_strncpyz(VM_POINTER(arg[1]), Cmd_Argv(VM_LONG(arg[0])), VM_LONG(arg[2]));
break;
case CG_ARGS:
VALIDATEPOINTER(arg[0], arg[1]);
cmdfuncs->Args(VM_POINTER(arg[0]), VM_LONG(arg[1]));
Q_strncpyz(VM_POINTER(arg[0]), Cmd_Args(), VM_LONG(arg[1]));
break;
case CG_CVAR_REGISTER:
if (arg[0])
@ -619,11 +622,19 @@ 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:
cvarfuncs->SetString(VM_POINTER(arg[0]), VM_POINTER(arg[1])?VM_POINTER(arg[1]):"");
{
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
}
break;
case CG_CVAR_VARIABLESTRINGBUFFER:
{
cvar_t *var = cvarfuncs->GetNVFDG(VM_POINTER(arg[0]), NULL, 0, NULL, "Q3CG created");
cvar_t *var;
var = Cvar_FindVar(VM_POINTER(arg[0]));
if (!VM_LONG(arg[2]))
VM_LONG(ret) = 0;
else if (!var)
@ -642,18 +653,20 @@ 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]));
cmdfuncs->AddText(VM_POINTER(arg[0]), false);
Cbuf_AddText(VM_POINTER(arg[0]), RESTRICT_SERVER);
break;
case CG_ADDCOMMAND:
cmdfuncs->AddCommand(VM_POINTER(arg[0]), NULL, NULL);
Cmd_AddCommand(VM_POINTER(arg[0]), NULL);
break;
case CG_SENDCLIENTCOMMAND:
Con_DPrintf("CG_SENDCLIENTCOMMAND: %s", (char*)VM_POINTER(arg[0]));
CLQ3_SendClientCommand("%s", (char*)VM_POINTER(arg[0]));
CL_SendClientCommand(true, "%s", (char*)VM_POINTER(arg[0]));
break;
case CG_UPDATESCREEN: //force a buffer swap cos loading won't refresh it soon.
drawfuncs->RedrawScreen();
if (!Key_Dest_Has(kdm_console))
scr_con_current = 0;
SCR_UpdateScreen();
break;
case CG_FS_FOPENFILE: //fopen
@ -669,8 +682,6 @@ 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;
@ -680,15 +691,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 >= countof(ccs.model_precache))
if (modhandle >= MAX_PRECACHE_MODELS)
{
// if (modhandle == countof(ccs.model_precache)+1)
// if (modhandle == MAX_PRECACHE_MODELS+1)
// mod = &capsule_model;
// else
mod = box_model;
mod = &box_model;
}
else
mod = ccs.model_precache[modhandle];
mod = cl.model_precache[modhandle+1];
if (mod && mod->loadstate == MLS_LOADED)
pc = mod->funcs.NativeContents(mod, 0, 0, NULL, VM_POINTER(arg[0]), vec3_origin, vec3_origin);
else
@ -705,15 +716,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 >= countof(ccs.model_precache))
if (modhandle >= MAX_PRECACHE_MODELS)
{
// if (modhandle == countof(ccs.model_precache)+1)
// if (modhandle == MAX_PRECACHE_MODELS+1)
// mod = &capsule_model;
// else
mod = box_model;
mod = &box_model;
}
else
mod = ccs.model_precache[modhandle];
mod = cl.model_precache[modhandle+1];
if (mod && mod->loadstate == MLS_LOADED)
{
@ -757,15 +768,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 >= countof(ccs.model_precache))
if (modhandle >= MAX_PRECACHE_MODELS)
{
// if (modhandle == countof(ccs.model_precache)+1)
// if (modhandle == MAX_PRECACHE_MODELS+1)
// mod = &capsule_model;
// else
mod = box_model;
mod = &box_model;
}
else
mod = ccs.model_precache[modhandle];
mod = cl.model_precache[modhandle+1];
if (!mins)
mins = vec3_origin;
@ -776,7 +787,18 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
if (!angles)
angles = vec3_origin;
if (mod && mod->loadstate == MLS_LOADED)
worldfuncs->TransformedTrace(mod, 0, 0, start, end, mins, maxs, fn==CG_CM_TRANSFORMEDCAPSULETRACE, &tr, origin, angles, brushmask);
#if !defined(CLIENTONLY) || defined(CSQC_DAT)
World_TransformedTrace(mod, 0, 0, start, end, mins, maxs, fn==CG_CM_TRANSFORMEDCAPSULETRACE, &tr, origin, angles, brushmask);
#else
{
#ifdef warningmsg
#pragma warningmsg("FIXME: G3 CGame requires World_TransformedTrace!")
#endif
memset(&tr, 0, sizeof(tr));
tr.allsolid = tr.startsolid = true;
tr.contents = 1;
}
#endif
else
{
memset(&tr, 0, sizeof(tr));
@ -806,31 +828,27 @@ 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]);
unsigned int brushmask = VM_LONG(arg[6]);
unsigned int modhandle = VM_LONG(arg[5]);
int brushmask = VM_LONG(arg[6]);
model_t *mod;
if (modhandle >= countof(ccs.model_precache))
if (modhandle >= MAX_PRECACHE_MODELS)
{
// if (modhandle == countof(ccs.model_precache)+1)
// if (modhandle == MAX_PRECACHE_MODELS+1)
// mod = &capsule_model;
// else
mod = box_model;
mod = &box_model;
}
else
mod = ccs.model_precache[modhandle];
mod = cl.model_precache[modhandle+1];
if (mod->loadstate != MLS_LOADED)
{
if (mod->loadstate == MLS_NOTLOADED)
scenefuncs->LoadModel(mod->publicname, MLV_SILENTSYNC);
if (mod->loadstate == MLS_LOADING && threadfuncs)
threadfuncs->WaitForCompletion(mod, &mod->loadstate, MLS_LOADING);
Mod_LoadModel(mod, MLV_SILENT);
if (mod->loadstate == MLS_LOADING)
COM_WorkerPartialSync(mod, &mod->loadstate, MLS_LOADING);
if (mod->loadstate != MLS_LOADED)
{
memset(results, 0, sizeof(*results));
results->fraction = 1;
break;
}
mod = &box_model; //stop crashes, even if this is wrong.
}
if (!mins)
@ -849,54 +867,57 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
}
break;
case CG_R_LOADWORLDMAP:
{ //rendering
scenefuncs->NewMap(worldfuncs->LoadModel(VM_POINTER(arg[0]), MLV_SILENTSYNC));
}
break;
case CG_R_LOADWORLDMAP: //FTE can't distinguish. :/
Con_DPrintf("CG_R_LOADWORLDMAP: not implemented\n");
break; //So long as noone has one collision model with a different rendering one, we'll be fine
case CG_CM_LOADMAP:
{ //collisions
{
int i;
char *mapname = VM_POINTER(arg[0]);
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);
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);
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);
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);
}
}
break;
case CG_CM_INLINEMODEL:
if ((unsigned int)VM_LONG(arg[0]) > (ccs.worldmodel?ccs.worldmodel->numsubmodels:0))
plugfuncs->EndGame("cgame asked for invalid model number\n");
if ((unsigned int)VM_LONG(arg[0]) > (cl.worldmodel?cl.worldmodel->numsubmodels:0))
Host_EndGame("cgame asked for invalid model number\n");
VM_LONG(ret) = VM_LONG(arg[0]);
break;
case CG_CM_NUMINLINEMODELS:
VM_LONG(ret) = ccs.worldmodel?ccs.worldmodel->numsubmodels:0;
VM_LONG(ret) = cl.worldmodel?cl.worldmodel->numsubmodels:0;
break;
case CG_CM_TEMPBOXMODEL:
box_model = worldfuncs->TempBoxModel(VM_POINTER(arg[0]), VM_POINTER(arg[1]));
VM_LONG(ret) = countof(ccs.model_precache);
CM_TempBoxModel(VM_POINTER(arg[0]), VM_POINTER(arg[1]));
VM_LONG(ret) = MAX_PRECACHE_MODELS;
break;
case CG_CM_TEMPCAPSULEMODEL:
box_model = worldfuncs->TempBoxModel(VM_POINTER(arg[0]), VM_POINTER(arg[1]));
VM_LONG(ret) = countof(ccs.model_precache)+1;
CM_TempBoxModel(VM_POINTER(arg[0]), VM_POINTER(arg[1]));
VM_LONG(ret) = MAX_PRECACHE_MODELS+1;
break;
case CG_R_MODELBOUNDS:
VALIDATEPOINTER(arg[1], sizeof(vec3_t));
VALIDATEPOINTER(arg[2], sizeof(vec3_t));
{
model_t *mod = scenefuncs->ModelFromId(arg[0]);
model_t *mod = VM_FROMMHANDLE(arg[0]);
if (mod)
{
if (mod->loadstate == MLS_LOADING && threadfuncs)
threadfuncs->WaitForCompletion(mod, &mod->loadstate, MLS_LOADING);
if (mod->loadstate == MLS_LOADING)
COM_WorkerPartialSync(mod, &mod->loadstate, MLS_LOADING);
VectorCopy(mod->mins, ((float*)VM_POINTER(arg[1])));
VectorCopy(mod->maxs, ((float*)VM_POINTER(arg[2])));
@ -908,41 +929,42 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
{
char *name = VM_POINTER(arg[0]);
model_t *mod;
if (!name)
return 0;
mod = scenefuncs->LoadModel(worldfuncs->FixName(name, ccs.worldmodel->name), MLV_SILENTSYNC);
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 (mod->loadstate == MLS_FAILED || mod->type == mod_dummy)
VM_LONG(ret) = 0;
else
VM_LONG(ret) = scenefuncs->ModelToId(mod);
VM_LONG(ret) = VM_TOMHANDLE(mod);
}
break;
case CG_R_REGISTERSKIN:
VM_LONG(ret) = scenefuncs->RegisterSkinFile(VM_POINTER(arg[0]));
VM_LONG(ret) = Mod_RegisterSkinFile(VM_POINTER(arg[0]));
break;
case CG_R_REGISTERSHADER:
if (!*(char*)VM_POINTER(arg[0]))
VM_LONG(ret) = 0;
else
VM_LONG(ret) = drawfuncs->LoadImage(VM_POINTER(arg[0]));
VM_LONG(ret) = VM_TOSHANDLE(R_RegisterPic(VM_POINTER(arg[0]), NULL));
break;
case CG_R_REGISTERSHADERNOMIP:
if (!*(char*)VM_POINTER(arg[0]))
VM_LONG(ret) = 0;
else
VM_LONG(ret) = drawfuncs->LoadImage(VM_POINTER(arg[0]));
VM_LONG(ret) = VM_TOSHANDLE(R_RegisterPic(VM_POINTER(arg[0]), NULL));
break;
case CG_R_CLEARSCENE: //clear scene (not rtlights, only dynamic ones)
scenefuncs->ClearScene();
CL_ClearEntityLists();
rtlights_first = RTL_FIRST;
break;
case CG_R_ADDPOLYTOSCENE:
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]));
VQ3_AddPoly(VM_FROMSHANDLE(arg[0]), VM_LONG(arg[1]), VM_POINTER(arg[2]));
break;
case CG_R_ADDREFENTITYTOSCENE: //add ent to scene
VQ3_AddEntity(VM_POINTER(arg[0]));
@ -950,14 +972,12 @@ 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.
{
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]));
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]));
}
break;
case CG_R_RENDERSCENE: //render scene
R_PushDlights();
VQ3_RenderView(VM_POINTER(arg[0]));
break;
@ -965,25 +985,25 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
{
float *f = VM_POINTER(arg[0]);
if (f)
drawfuncs->Colour4f(f[0], f[1], f[2], f[3]);
R2D_ImageColours(f[0], f[1], f[2], f[3]);
else
drawfuncs->Colour4f(1, 1, 1, 1);
R2D_ImageColours(1, 1, 1, 1);
}
break;
case CG_R_DRAWSTRETCHPIC:
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]));
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])));
break;
case CG_R_LERPTAG: //Lerp tag...
VALIDATEPOINTER(arg[0], sizeof(float)*12);
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]));
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]));
break;
case CG_S_REGISTERSOUND:
{
sfx_t *sfx;
sfx = audiofuncs->PrecacheSound(VM_POINTER(arg[0]));
sfx = S_PrecacheSound(VM_POINTER(arg[0]));
if (sfx)
VM_LONG(ret) = VM_TOSTRCACHE(arg[0]);
else
@ -993,20 +1013,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])
audiofuncs->LocalSound(VM_FROMSTRCACHE(arg[0]), CHAN_AUTO, 1.0);
S_LocalSound(VM_FROMSTRCACHE(arg[0]));
break;
case CG_S_STARTSOUND:// ( vec3_t origin, int entityNum, int entchannel, sfxHandle_t sfx )
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);
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);
break;
case CG_S_ADDLOOPINGSOUND:
//entnum, origin, velocity, sfx
CG_StartLoopingSounds(VM_LONG(arg[0])+1, VM_POINTER(arg[1]), VM_POINTER(arg[2]), -1, VM_FROMSTRCACHE(arg[3]), 1, false);
CG_StartLoopingSounds(VM_LONG(arg[0])+1, VM_POINTER(arg[1]), VM_POINTER(arg[2]), VM_FROMSTRCACHE(arg[3]), 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]), -1, VM_FROMSTRCACHE(arg[3]), 1, true);
CG_StartLoopingSounds(VM_LONG(arg[0])+1, VM_POINTER(arg[1]), VM_POINTER(arg[2]), VM_FROMSTRCACHE(arg[3]), true);
break;
case CG_S_STOPLOOPINGSOUND:
//entnum
@ -1022,19 +1042,33 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
break;
case CG_S_STARTBACKGROUNDTRACK:
audiofuncs->ChangeMusicTrack(VM_POINTER(arg[0]), VM_POINTER(arg[1]));
Media_NamedTrack(VM_POINTER(arg[0]), VM_POINTER(arg[1]));
return 0;
case CG_S_STOPBACKGROUNDTRACK:
audiofuncs->ChangeMusicTrack(NULL, NULL);
Media_NamedTrack(NULL, NULL);
return 0;
case CG_S_RESPATIALIZE://void trap_S_Respatialize( int entityNum, const vec3_t origin, vec3_t axis[3], int inwater );
audiofuncs->Spacialize(0, VM_LONG(arg[0])+1, VM_POINTER(arg[1]), VM_POINTER(arg[2]), VM_LONG(arg[3])?1:0, vec3_origin);
{
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);
}
break;
case CG_KEY_ISDOWN:
{
if (inputfuncs->IsKeyDown(VM_LONG(arg[0])))
if (keydown[VM_LONG(arg[0])])
VM_LONG(ret) = 1;
else
VM_LONG(ret) = 0;
@ -1044,7 +1078,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
case CG_KEY_GETKEY:
{
int ret[1];
inputfuncs->FindKeysForCommand(0, VM_POINTER(arg[0]), ret, NULL, countof(ret));
M_FindKeysForCommand (0, 0, VM_POINTER(arg[0]), ret, NULL, countof(ret));
return ret[0];
}
break;
@ -1057,31 +1091,16 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
break;
case CG_GETGLCONFIG:
{
float vsize[2];
q3glconfig_t *cfg;
VALIDATEPOINTER(arg[0], sizeof(q3glconfig_t));
drawfuncs->GetVideoSize(vsize, NULL);
cfg = VM_POINTER(arg[0]);
VALIDATEPOINTER(arg[0], 11332);
{ //FIXME: Clean this shit up
//do any needed work
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];
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);
}
break;
@ -1115,7 +1134,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
break;
case CG_SETUSERCMDVALUE: //weaponselect, zoomsensitivity.
ccs.selected_weapon = VM_LONG(arg[0]);
inputfuncs->SetSensitivityScale(VM_FLOAT(arg[1]));
in_sensitivityscale = VM_FLOAT(arg[1]);
break;
case CG_GETSERVERCOMMAND:
@ -1127,7 +1146,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
break;
case CG_MILLISECONDS:
VM_LONG(ret) = plugfuncs->GetMilliseconds();
VM_LONG(ret) = Sys_Milliseconds();
break;
case CG_REAL_TIME:
VALIDATEPOINTER(arg[0], sizeof(q3time_t));
@ -1208,7 +1227,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
break;
case CG_R_REMAP_SHADER:
scenefuncs->RemapShader(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_FLOAT(arg[2]));
R_RemapShader(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_FLOAT(arg[2]));
break;
case CG_R_REGISTERFONT:
@ -1216,11 +1235,6 @@ 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:
@ -1232,7 +1246,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]));
@ -1241,14 +1255,7 @@ 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;
*/
case CG_CM_LOADMODEL:
case CG_REMOVECOMMAND:
case CG_TESTPRINTINT:
case CG_TESTPRINTFLOAT:
case CG_R_INPVS:
case CG_R_LIGHTFORPOINT:
// default:
default:
Con_Printf("Q3CG: Bad system trap: %i\n", (int)fn);
}
@ -1301,14 +1308,18 @@ static qintptr_t EXPORT_FN CG_SystemCallsNative(qintptr_t arg, ...)
return CG_SystemCalls(NULL, ~(quintptr_t)0, arg, args);
}
int CG_Refresh(double time)
int CG_Refresh(void)
{
int time;
if (!cgvm)
return false;
ccs.time = time;
vmfuncs->Call(cgvm, CG_DRAW_ACTIVE_FRAME, (int)(ccs.time*1000), 0, false);
drawfuncs->Colour4f(1, 1, 1, 1);
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);
return true;
}
@ -1319,11 +1330,10 @@ void CG_Stop (void)
Q3_SetKeyCatcher(Q3_GetKeyCatcher()&~2);
if (cgvm)
{
vmfuncs->Call(cgvm, CG_SHUTDOWN);
vmfuncs->Destroy(cgvm);
VM_Call(cgvm, CG_SHUTDOWN);
VM_Destroy(cgvm);
VM_fcloseall(1);
cgvm = NULL;
}
}
@ -1331,7 +1341,7 @@ qboolean CG_VideoRestarted(void)
{
if (cgvm)
{
vmfuncs->Call(cgvm, CG_INIT, ccs.serverMessageNum, ccs.lastServerCommandNum, ccs.playernum);
VM_Call(cgvm, CG_INIT, ccs.serverMessageNum, ccs.lastServerCommandNum, cl.playerview[0].playernum);
return true;
}
return false;
@ -1339,30 +1349,38 @@ qboolean CG_VideoRestarted(void)
void CG_Start (void)
{
CG_Stop();
SCR_SetLoadingStage(0);
if (cls.protocol != CP_QUAKE3)
{ //q3 clients only.
CG_Stop();
return;
}
box_model = worldfuncs->TempBoxModel(vec3_origin, vec3_origin); //just in case.
Z_FreeTags(CGTAGNUM);
SCR_BeginLoadingPlaque();
clientfuncs->SetLoadingState(true);
cgvm = vmfuncs->Create("cgame", cvarfuncs->GetFloat("com_gamedirnativecode")?CG_SystemCallsNative:NULL, "vm/cgame", CG_SystemCallsVM);
clientfuncs->SetLoadingState(false);
cgvm = VM_Create("cgame", com_nogamedirnativecode.ival?NULL:CG_SystemCallsNative, "vm/cgame", CG_SystemCallsVM);
if (cgvm)
{ //hu... cgame doesn't appear to have a query version call!
vmfuncs->Call(cgvm, CG_INIT, ccs.serverMessageNum, ccs.lastServerCommandNum, ccs.playernum);
SCR_EndLoadingPlaque();
VM_Call(cgvm, CG_INIT, ccs.serverMessageNum, ccs.lastServerCommandNum, cl.playerview[0].playernum);
}
else
plugfuncs->EndGame("Failed to initialise cgame module\n");
{
SCR_EndLoadingPlaque();
Host_EndGame("Failed to initialise cgame module\n");
}
}
qboolean CG_ConsoleCommand(void)
qboolean CG_Command(void)
{
if (!cgvm)
return false;
// Con_DPrintf("CG_Command: %s %s\n", cmdfuncs->Argv(0), cmdfuncs->Args());
return vmfuncs->Call(cgvm, CG_CONSOLE_COMMAND);
Con_DPrintf("CG_Command: %s %s\n", Cmd_Argv(0), Cmd_Args());
return VM_Call(cgvm, CG_CONSOLE_COMMAND);
}
/*void CG_Command_f(void)
void CG_Command_f(void)
{
if (cgvm)
{
@ -1372,12 +1390,12 @@ qboolean CG_ConsoleCommand(void)
Cmd_ForwardToServer();
}
}
}*/
}
qboolean CG_KeyPressed(int key, int unicode, int down)
qboolean CG_KeyPress(int key, int unicode, int down)
{
if (!cgvm || !(Q3_GetKeyCatcher()&8))
int catcher = Q3_GetKeyCatcher();
if (!cgvm || !(catcher&8))
return false;
/* if you change this here, it'll have to be changed in cl_cg.c too */
@ -1431,13 +1449,18 @@ qboolean CG_KeyPressed(int key, int unicode, int down)
break;
}
return vmfuncs->Call(cgvm, CG_KEY_EVENT, key, down);
return VM_Call(cgvm, CG_KEY_EVENT, key, down);
}
void CG_Restart(void)
void CG_Restart_f(void)
{
CG_Stop();
CG_Start();
}
void CG_Init(void)
{
Cmd_AddCommand("cg_restart", CG_Restart_f);
}
#endif

View File

@ -162,18 +162,18 @@ void CL_WriteDemoMessage (sizebuf_t *msg, int payloadoffset)
c = dem_read;
VFS_WRITE (cls.demooutfile, &c, sizeof(c));
if (*(int*)msg->data == -1 && payloadoffset==0)
if (*(int*)msg->data == -1)
{
//connectionless packet.
len = LittleLong (msg->cursize);
VFS_WRITE (cls.demooutfile, &len, 4);
VFS_WRITE (cls.demooutfile, msg->data + payloadoffset, msg->cursize - payloadoffset);
VFS_WRITE (cls.demooutfile, msg->data + msg_readcount, msg->cursize - msg_readcount);
}
else
{
//regenerate a legacy netchan. no fragmentation support, but whatever. this ain't udp.
//the length
len = LittleLong (msg->cursize - payloadoffset + 8);
len = LittleLong (msg->cursize - msg_readcount + 8);
VFS_WRITE (cls.demooutfile, &len, 4);
//hack the netchan here.
i = cls.netchan.incoming_sequence;
@ -181,7 +181,7 @@ void CL_WriteDemoMessage (sizebuf_t *msg, int payloadoffset)
i = cls.netchan.incoming_acknowledged;
VFS_WRITE (cls.demooutfile, &i, 4);
//and the data
VFS_WRITE (cls.demooutfile, msg->data + payloadoffset, msg->cursize - payloadoffset);
VFS_WRITE (cls.demooutfile, msg->data + msg_readcount, msg->cursize - msg_readcount);
}
break;
#ifdef Q2CLIENT
@ -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(&net_message, cls.netchan.netprim);
MSG_BeginReading(cls.netchan.netprim);
CLQW_ParseServerMessage();
}
@ -1008,10 +1008,11 @@ void CL_Stop_f (void)
#endif
{
SZ_Clear (&net_message);
msg_readcount = 0;
MSG_WriteLong (&net_message, -1); // -1 sequence means out of band
MSG_WriteByte (&net_message, svc_disconnect);
MSG_WriteString (&net_message, "EndOfDemo");
CL_WriteDemoMessage (&net_message, 0);
CL_WriteDemoMessage (&net_message, sizeof(int));
}
// finish up
@ -1749,8 +1750,7 @@ void CL_Record_f (void)
if (cls.state != ca_active)
{
Con_Printf ("You must either be connected to record, or specify a map name to load.\n");
Con_Printf ("%s: <demoname> <mapname>\n", Cmd_Argv(0));
Con_Printf ("You must be connected to record.\n");
return;
}
@ -2108,8 +2108,6 @@ void CL_Record_f (void)
break;
}
cl.validsequence = 0; //ask for a sequence reset.
if (cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
if (cl.numackframes < sizeof(cl.ackframes)/sizeof(cl.ackframes[0]))
cl.ackframes[cl.numackframes++] = -1;
@ -2553,9 +2551,258 @@ void CL_Demo_ClientCommand(char *commandtext)
}
}
static char qtvhostname[1024];
static char qtvrequestbuffer[4096];
static size_t qtvrequestsize;
static char qtvrequestcmdbuffer[4096];
static int qtvrequestcmdsize;
static vfsfile_t *qtvrequest;
void CL_QTVPoll (void)
{
char *s, *e, *colon;
char *tail = NULL;
int len;
qboolean streamavailable = false;
qboolean saidheader = false;
#ifndef NOBUILTINMENUS
emenu_t *sourcesmenu = NULL;
#endif
int sourcenum = 0;
int streamid;
int numplayers = 0;
int numviewers = 0;
qboolean init_numplayers = false;
qboolean init_numviewers = false;
qboolean iseztv = false;
char srchost[256];
char auth[64];
char challenge[128];
if (!qtvrequest)
return;
if (qtvrequestcmdsize)
{
len = VFS_WRITE(qtvrequest, qtvrequestcmdbuffer, qtvrequestcmdsize);
if (len > 0)
{
memmove(qtvrequestcmdbuffer, qtvrequestcmdbuffer+len, qtvrequestcmdsize-len);
qtvrequestcmdsize -= len;
}
}
for(;;)
{
len = VFS_READ(qtvrequest, qtvrequestbuffer+qtvrequestsize, (sizeof(qtvrequestbuffer) - qtvrequestsize -1 > 0)?1:0);
if (len <= 0)
break;
qtvrequestsize += len;
}
qtvrequestbuffer[qtvrequestsize] = '\0';
if (qtvrequestsize >= sizeof(qtvrequestbuffer) - 1)
{
//flag it as an error if the response is larger than we can handle.
//this error gets ignored if the header is okay (any actual errors will get reported again by the demo code anyway), and only counts if the end of the reply header was not found.
len = -1;
}
if (!qtvrequestsize && len == 0)
return;
//make sure it's a compleate chunk.
for (s = qtvrequestbuffer; *s; s++)
{
if (s[0] == '\n' && s[1] == '\n')
{
tail = s+2;
break;
}
if (s[0] == '\r' && s[1] == '\n' && s[2] == '\r' && s[3] == '\n')
{
tail = s+4;
break;
}
if (s[0] == '\r' && s[1] == '\n' && s[2] == '\n')
{
tail = s+3;
break;
}
if (s[0] == '\n' && s[1] == '\r' && s[2] == '\n')
{
tail = s+3;
break;
}
}
if (!tail)
{
if (len < 0)
{
if (!qtvrequestsize)
Con_Printf("Connection to QTV server closed without any reply.\n");
else
Con_Printf("invalid QTV handshake\n");
SCR_SetLoadingStage(LS_NONE);
VFS_CLOSE(qtvrequest);
qtvrequest = NULL;
qtvrequestsize = 0;
}
return;
}
s[1] = '\0'; //make sure its null terminated before the data payload
s = qtvrequestbuffer;
*auth = *challenge = 0;
for (e = s; *e; )
{
if (*e == '\r')
*e = '\0';
else if (*e == '\n')
{
*e = '\0';
colon = strchr(s, ':');
if (colon)
*colon++ = '\0';
else
colon = "";
if (!strcmp(s, "PERROR"))
{ //permanent printable error
Con_Printf("QTV Error:\n%s\n", colon);
}
else if (!strcmp(s, "PRINT"))
{ //printable error
Con_Printf("QTV:\n%s\n", colon);
}
else if (!strcmp(s, "TERROR"))
{ //temporary printable error
Con_Printf("QTV Error:\n%s\n", colon);
}
else if (!strcmp(s, "ADEMO"))
{ //printable error
Con_Printf("Demo%s is available\n", colon);
}
else if (!strcmp(s, "AUTH"))
{
while (*colon && *(unsigned char*)colon <= ' ')
colon++;
Q_strncpyz(auth, colon, sizeof(auth));
}
else if (!strcmp(s, "CHALLENGE"))
Q_strncpyz(challenge, colon, sizeof(challenge));
//generic sourcelist responce
else if (!strcmp(s, "ASOURCE"))
{ //printable source
if (!saidheader)
{
saidheader=true;
Con_Printf("Available Sources:\n");
}
Con_Printf("%s\n", colon);
//we're too lazy to even try and parse this
}
else if (!strcmp(s, "BEGIN"))
{
while (*colon && *(unsigned char*)colon <= ' ')
colon++;
if (*colon)
Con_Printf("streaming \"%s\" from qtv\n", colon);
else
Con_Printf("qtv connection established to %s\n", qtvhostname);
streamavailable = true;
}
//eztv extensions to v1.0
else if (!strcmp(s, "QTV_EZQUAKE_EXT"))
{
iseztv = true;
Con_Printf("Warning: eztv extensions %s\n", colon);
}
//v1.1 sourcelist response includes SRCSRV, SRCHOST, SRCPLYRS, SRCVIEWS, SRCID
else if (!strcmp(s, "SRCSRV"))
{
//the proxy's source string (beware of file:blah without file:blah@blah)
}
else if (!strcmp(s, "SRCHOST"))
{
//the hostname from the server the stream came from
Q_strncpyz(srchost, colon, sizeof(srchost));
}
else if (!strcmp(s, "SRCPLYRS"))
{
//number of active players actually playing on that stream
numplayers = atoi(colon);
init_numplayers = true;
}
else if (!strcmp(s, "SRCVIEWS"))
{
//number of people watching this stream on the proxy itself
numviewers = atoi(colon);
init_numviewers = true;
}
else if (!strcmp(s, "SRCID"))
{
streamid = atoi(colon);
#ifndef NOBUILTINMENUS
//now put it on a menu
if (!sourcesmenu)
{
sourcesmenu = M_CreateMenu(0);
MC_AddPicture(sourcesmenu, 16, 4, 32, 144, "gfx/qplaque.lmp");
MC_AddCenterPicture(sourcesmenu, 4, 24, "gfx/p_option.lmp");
}
if (init_numplayers == true && init_numviewers == true)
MC_AddConsoleCommand(sourcesmenu, 42, 170, (sourcenum++)*8 + 32, va("%s (p%i, v%i)", srchost, numplayers, numviewers), va("qtvplay %i@%s\n", streamid, qtvhostname));
//else
// FIXME: add error message here
#else
(void)init_numviewers;
(void)numviewers;
(void)init_numplayers;
(void)numplayers;
(void)streamid;
(void)sourcenum;
#endif
}
//end of sourcelist entry
//from e to s, we have a line
s = e+1;
}
e++;
}
if (streamavailable)
{
CL_PlayDemoStream(qtvrequest, NULL, false, iseztv?DPB_EZTV:DPB_MVD, BUFFERTIME);
qtvrequest = NULL;
demo_resetcache(qtvrequestsize - (tail-qtvrequestbuffer), tail);
return;
}
if (!strcmp(auth, "NONE"))
;
// else if (!strcmp(auth, "PLAIN"))
// else if (!strcmp(auth, "MD4"))
// else if (!strcmp(auth, "SHA1"))
else if (*auth)
Con_Printf("Server requires unsupported auth method: %s\n", auth);
SCR_SetLoadingStage(LS_NONE);
VFS_CLOSE(qtvrequest);
qtvrequest = NULL;
qtvrequestsize = 0;
}
char *strchrrev(char *str, char chr)
{
const char *firstchar = str;
char *firstchar = str;
for (str = str + strlen(str)-1; str>=firstchar; str--)
if (*str == chr)
return str;
@ -2731,343 +2978,58 @@ void CL_ParseQTVDescriptor(vfsfile_t *f, const char *name)
}
#include "netinc.h"
static struct pendingqtv_s
void CL_QTVPlay_f (void)
{
struct pendingqtv_s *next;
qboolean raw;
char hostname[1024];
char password[1024];
char requestbuffer[4096];
size_t requestsize;
char requestcmdbuffer[4096];
int requestcmdsize;
vfsfile_t *stream;
char postauth[1];
} *pendingqtv;
void CL_QTVPoll (void)
{
struct pendingqtv_s **link, *qtv;
for (link = &pendingqtv; (qtv = *link); link = &qtv->next)
{
char *s, *e, *colon;
char *tail = NULL;
int len;
char *streamavailable = NULL;
qboolean saidheader = false;
#ifndef NOBUILTINMENUS
emenu_t *sourcesmenu = NULL;
#endif
int sourcenum = 0;
int numplayers = 0;
int numviewers = 0;
qboolean init_numplayers = false;
qboolean init_numviewers = false;
qboolean iseztv = false;
char srchost[256];
char auth[64];
char challenge[128];
hashfunc_t *hashfunc = NULL;
//try to finish sending
if (qtv->requestcmdsize)
{
len = VFS_WRITE(qtv->stream, qtv->requestcmdbuffer, qtv->requestcmdsize);
if (len > 0)
{
memmove(qtv->requestcmdbuffer, qtv->requestcmdbuffer+len, qtv->requestcmdsize-len);
qtv->requestcmdsize -= len;
}
if (len < 0)
goto fail;
}
for(;;)
{
len = VFS_READ(qtv->stream, qtv->requestbuffer+qtv->requestsize, (sizeof(qtv->requestbuffer) - qtv->requestsize -1 > 0)?1:0);
if (len <= 0)
break;
qtv->requestsize += len;
}
qtv->requestbuffer[qtv->requestsize] = '\0';
if (qtv->raw)
{
tail = qtv->requestbuffer;
streamavailable = "";
}
else
{
if (qtv->requestsize >= sizeof(qtv->requestbuffer) - 1)
{
//flag it as an error if the response is larger than we can handle.
//this error gets ignored if the header is okay (any actual errors will get reported again by the demo code anyway), and only counts if the end of the reply header was not found.
len = -1;
}
if (!qtv->requestsize && len == 0)
continue; //still trying.
//make sure it's a compleate chunk.
for (s = qtv->requestbuffer; *s; s++)
{
if (s[0] == '\n' && s[1] == '\n')
{
tail = s+2;
break;
}
if (s[0] == '\r' && s[1] == '\n' && s[2] == '\r' && s[3] == '\n')
{
tail = s+4;
break;
}
if (s[0] == '\r' && s[1] == '\n' && s[2] == '\n')
{
tail = s+3;
break;
}
if (s[0] == '\n' && s[1] == '\r' && s[2] == '\n')
{
tail = s+3;
break;
}
}
}
if (!tail)
{
if (len < 0)
{
if (!qtv->requestsize)
Con_Printf("Connection to QTV server closed without any reply.\n");
else
Con_Printf("invalid QTV handshake\n");
fail:
SCR_SetLoadingStage(LS_NONE);
if (qtv->stream)
VFS_CLOSE(qtv->stream);
qtv->stream = NULL;
qtv->requestsize = 0;
*link = qtv->next;
Z_Free(qtv);
return;
}
continue;
}
s = qtv->requestbuffer;
colon = "";
*auth = *challenge = 0;
for (e = s; e < tail; )
{
if (*e == '\r')
*e = '\0';
else if (*e == '\n')
{
*e = '\0';
colon = strchr(s, ':');
if (colon)
{
*colon++ = '\0';
if (*colon && *(unsigned char*)colon <= ' ')
colon++;
}
else
colon = "";
if (!strcmp(s, "PERROR"))
{ //permanent printable error
Con_Printf("QTV Error:\n%s\n", colon);
}
else if (!strcmp(s, "PRINT"))
{ //printable error
Con_Printf("QTV:\n%s\n", colon);
}
else if (!strcmp(s, "TERROR"))
{ //temporary printable error
Con_Printf("QTV Error:\n%s\n", colon);
}
else if (!strcmp(s, "ADEMO"))
{ //printable error
Con_Printf("Demo%s is available\n", colon);
}
else if (!strcmp(s, "AUTH"))
{
while (*colon && *(unsigned char*)colon <= ' ')
colon++;
Q_strncpyz(auth, colon, sizeof(auth));
}
else if (!strcmp(s, "CHALLENGE"))
{
while (*colon && *(unsigned char*)colon <= ' ')
colon++;
Q_strncpyz(challenge, colon, sizeof(challenge));
}
//generic sourcelist responce
else if (!strcmp(s, "ASOURCE"))
{ //printable source
if (!saidheader)
{
saidheader=true;
Con_Printf("Available Sources:\n");
}
Con_Printf("%s\n", colon);
//we're too lazy to even try and parse this
}
else if (!strcmp(s, "BEGIN"))
{
while (*colon && *(unsigned char*)colon <= ' ')
colon++;
streamavailable = colon;
}
//eztv extensions to v1.0
else if (!strcmp(s, "QTV_EZQUAKE_EXT"))
{
iseztv = true;
Con_Printf("Warning: eztv extensions %s\n", colon);
}
//v1.1 sourcelist response includes SRCSRV, SRCHOST, SRCPLYRS, SRCVIEWS, SRCID
else if (!strcmp(s, "SRCSRV"))
{
//the proxy's source string (beware of file:blah without file:blah@blah)
}
else if (!strcmp(s, "SRCHOST"))
{
//the hostname from the server the stream came from
Q_strncpyz(srchost, colon, sizeof(srchost));
}
else if (!strcmp(s, "SRCPLYRS"))
{
//number of active players actually playing on that stream
numplayers = atoi(colon);
init_numplayers = true;
}
else if (!strcmp(s, "SRCVIEWS"))
{
//number of people watching this stream on the proxy itself
numviewers = atoi(colon);
init_numviewers = true;
}
else if (!strcmp(s, "SRCID") && !streamavailable)
{
char *streamid = colon;
#ifndef NOBUILTINMENUS
//now put it on a menu
if (!sourcesmenu)
{
sourcesmenu = M_CreateMenu(0);
MC_AddPicture(sourcesmenu, 16, 4, 32, 144, "gfx/qplaque.lmp");
MC_AddCenterPicture(sourcesmenu, 4, 24, "gfx/p_option.lmp");
}
if (init_numplayers == true && init_numviewers == true)
MC_AddConsoleCommand(sourcesmenu, 42, 170, (sourcenum++)*8 + 32, va("%s (p%i, v%i)", srchost, numplayers, numviewers), va("qtvplay %s@%s\n", streamid, qtv->hostname));
//else
// FIXME: add error message here
#else
(void)init_numviewers;
(void)numviewers;
(void)init_numplayers;
(void)numplayers;
(void)streamid;
(void)sourcenum;
#endif
}
//end of sourcelist entry
//from e to s, we have a line
s = e+1;
}
e++;
}
if (streamavailable)
{
if (*streamavailable)
Con_Printf("streaming \"%s\" from qtv\n", streamavailable);
else
Con_Printf("qtv connection established to %s\n", qtv->hostname);
CL_PlayDemoStream(qtv->stream, NULL, false, iseztv?DPB_EZTV:DPB_MVD, BUFFERTIME);
qtv->stream = NULL;
demo_resetcache(qtv->requestsize - (tail-qtv->requestbuffer), tail);
*link = qtv->next;
Z_Free(qtv);
return;
}
//something failed. if its giving us an auth type then we should be authing before sending our request...
if (!strcmp(auth, "NONE"))
;
// else if (!strcmp(auth, "PLAIN"))
// else if (!strcmp(auth, "MD4"))
else if (!strcmp(auth, "SHA1"))
hashfunc = &hash_sha1;
else if (!strcmp(auth, "SHA2_256"))
hashfunc = &hash_sha256;
else if (!strcmp(auth, "SHA2_512"))
hashfunc = &hash_sha512;
else if (*auth)
Con_Printf("Server requires unsupported auth method: %s\n", auth);
qtv->requestsize -= tail-qtv->requestbuffer;
memmove(qtv->requestbuffer, tail, qtv->requestsize);
if (hashfunc && *qtv->postauth)
{
if (*qtv->password)
{
char hash[DIGEST_MAXSIZE*2+1];
qbyte digest[DIGEST_MAXSIZE];
Q_snprintfz(hash, sizeof(hash), "%s%s", challenge, qtv->password);
CalcHash(hashfunc, digest, sizeof(digest), hash, strlen(hash));
Base64_EncodeBlock(digest, hashfunc->digestsize, hash, sizeof(hash));
Q_snprintfz(qtv->requestcmdbuffer, sizeof(qtv->requestcmdbuffer),
"QTV\n"
"VERSION: 1.1\n"
"AUTH: %s\n"
"PASSWORD: \"%s\"\n"
"%s\n",
auth, hash, qtv->postauth);
qtv->requestcmdsize = strlen(qtv->requestcmdbuffer);
continue;
}
else
Con_Printf("QTV server requires a password\n");
}
SCR_SetLoadingStage(LS_NONE);
VFS_CLOSE(qtv->stream);
qtv->stream = NULL;
qtv->requestsize = 0;
*link = qtv->next;
Z_Free(qtv);
return;
}
}
void CL_QTVPlay_Establish (const char *host, const char *password, const char *command)
{
struct pendingqtv_s *qtv = Z_Malloc(sizeof(*qtv) + strlen(command));
qboolean raw=0;
char *connrequest;
vfsfile_t *newf;
char *host;
char msg[4096];
int msglen=0;
char *password;
// SCR_SetLoadingStage(LS_CONNECTION);
qtv->stream = FS_OpenTCP(host, 27599, false);
if (!qtv->stream)
if (Cmd_Argc() < 2)
{
Con_Printf("Usage: qtvplay [stream@][tls://]hostname[:port] [password]\n");
return;
}
connrequest = Cmd_Argv(1);
/*if (*connrequest == '#')
{
//#FILENAME is a local system path
CL_ParseQTVDescriptor(VFSOS_Open(connrequest+1, "rt"), connrequest+1);
return;
}*/
strcpy(cls.servername, "qtv:");
Q_strncpyz(cls.servername+4, connrequest, sizeof(cls.servername)-4);
SCR_SetLoadingStage(LS_CONNECTION);
host = connrequest;
connrequest = strchrrev(connrequest, '@');
if (connrequest)
host = connrequest+1;
Q_strncpyz(qtvhostname, host, sizeof(qtvhostname));
newf = FS_OpenTCP(qtvhostname, 27599, false);
if (!newf)
{
SCR_SetLoadingStage(LS_NONE);
Con_Printf("Couldn't connect to proxy\n");
Z_Free(qtv);
return;
}
Q_strncpyz(qtv->password, password, sizeof(qtv->password));
host = Cmd_Argv(1);
if (connrequest)
*connrequest = '\0';
else
host = NULL;
password = Cmd_Argv(2);
if (qtvcl_forceversion1.ival)
{
@ -3083,31 +3045,23 @@ void CL_QTVPlay_Establish (const char *host, const char *password, const char *c
}
msglen += strlen(msg+msglen);
if (*password)
if (password)
{
if (qtv->raw)
{
//just send it directly, we can't handle any kind of response and that includes the tripple handshake for the challenge info
Q_snprintfz(msg+msglen, sizeof(msg)-msglen,
"AUTH: PLAIN\n"
"PASSWORD: %s\n"
, password);
}
else
{
//report supported auth methods to the server. it'll pick one and send us a challenge.
Q_snprintfz(msg+msglen, sizeof(msg)-msglen,
"AUTH: SHA2_512\n"
"AUTH: SHA2_256\n"
"AUTH: SHA1\n"
// "AUTH: MD4\n"
// "AUTH: CCITT\n"
// "AUTH: PLAIN\n"
);
}
#if 0
//just send it directly, we can't handle the tripple handshake for the challenge info
Q_snprintfz(msg+msglen, sizeof(msg)-msglen,
"AUTH: PLAIN\n"
"PASSWORD: %s\n"
, password);
#else
//report supported auth methods to the server. it'll pick one and send us a challenge.
Q_snprintfz(msg+msglen, sizeof(msg)-msglen,
// "AUTH: SHA1\n"
// "AUTH: MD4\n"
// "AUTH: CCITT\n"
"AUTH: PLAIN\n");
#endif
msglen += strlen(msg+msglen);
strcpy(qtv->postauth, command);
}
else
{
@ -3116,59 +3070,15 @@ void CL_QTVPlay_Establish (const char *host, const char *password, const char *c
"AUTH: NONE\n"
"");
msglen += strlen(msg+msglen);
Q_snprintfz(msg+msglen, sizeof(msg)-msglen, "%s", command);
msglen += strlen(msg+msglen);
*qtv->postauth = 0;
}
if (qtv->raw)
{ //peer must either disconnect instantly, or respond with an mvd file without extra headers.
if (raw)
{
Q_snprintfz(msg+msglen, sizeof(msg)-msglen,
"RAW: 1\n");
msglen += strlen(msg+msglen);
}
Q_snprintfz(msg+msglen, sizeof(msg)-msglen,
"\n");
msglen += strlen(msg+msglen);
memcpy(qtv->requestcmdbuffer, msg, msglen);
qtv->requestcmdsize = msglen;
qtv->requestsize = 0;
//and link it in.
qtv->next = pendingqtv;
pendingqtv = qtv;
}
void CL_QTVPlay_f (void)
{
char *host;
const char *password;
char *streamid;
char msg[4096];
int msglen=0;
if (Cmd_Argc() < 2)
{
Con_Printf("Usage: qtvplay [stream@][tls://]hostname[:port] [password]\n");
return;
}
streamid = Cmd_Argv(1);
password = Cmd_Argv(2);
host = strchrrev(streamid, '@');
if (host)
*host++ = 0;
else
{
host = streamid;
streamid = NULL;
}
if (streamid)
else if (host)
{
if (qtvcl_eztvextensions.ival)
{
@ -3183,27 +3093,95 @@ void CL_QTVPlay_f (void)
}
Q_snprintfz(msg+msglen, sizeof(msg)-msglen,
"SOURCE: %s\n", streamid);
"SOURCE: %s\n", host);
msglen += strlen(msg+msglen);
SCR_SetLoadingStage(LS_CONNECTION);
CL_QTVPlay_Establish(host, password, msg);
}
else
{
CL_QTVPlay_Establish(host, password, "SOURCELIST\n");
Q_snprintfz(msg+msglen, sizeof(msg)-msglen,
"SOURCELIST\n");
msglen += strlen(msg+msglen);
}
Q_snprintfz(msg+msglen, sizeof(msg)-msglen,
"\n");
msglen += strlen(msg+msglen);
if (raw)
{
VFS_WRITE(newf, msg, msglen);
CL_PlayDemoStream(qtvrequest, qtvhostname, false, DPB_MVD, BUFFERTIME);
}
else
{
if (qtvrequest)
VFS_CLOSE(qtvrequest);
memcpy(qtvrequestcmdbuffer, msg, msglen);
qtvrequestcmdsize = msglen;
qtvrequest = newf;
qtvrequestsize = 0;
}
}
void CL_QTVList_f (void)
{
CL_QTVPlay_Establish(Cmd_Argv(1), Cmd_Argv(2), "SOURCELIST\n");
char *connrequest;
vfsfile_t *newf;
newf = FS_OpenTCP(qtvhostname, 27599, false);
if (!newf)
{
Con_Printf("Couldn't connect to proxy\n");
return;
}
if (qtvcl_forceversion1.ival)
{
connrequest = "QTV\n"
"VERSION: 1.0\n";
}
else
{
connrequest = "QTV\n"
"VERSION: 1.1\n";
}
VFS_WRITE(newf, connrequest, strlen(connrequest));
connrequest = "SOURCELIST\n";
VFS_WRITE(newf, connrequest, strlen(connrequest));
connrequest = "\n";
VFS_WRITE(newf, connrequest, strlen(connrequest));
if (qtvrequest)
VFS_CLOSE(qtvrequest);
qtvrequest = newf;
qtvrequestsize = 0;
}
void CL_QTVDemos_f (void)
{
CL_QTVPlay_Establish(Cmd_Argv(1), Cmd_Argv(2), "DEMOLIST\n");
char *connrequest;
vfsfile_t *newf;
newf = FS_OpenTCP(Cmd_Argv(1), 27599, false);
if (!newf)
{
Con_Printf("Couldn't connect to proxy\n");
return;
}
connrequest = "QTV\n"
"VERSION: 1\n";
VFS_WRITE(newf, connrequest, strlen(connrequest));
connrequest = "DEMOLIST\n";
VFS_WRITE(newf, connrequest, strlen(connrequest));
connrequest = "\n";
VFS_WRITE(newf, connrequest, strlen(connrequest));
if (qtvrequest)
VFS_CLOSE(qtvrequest);
qtvrequest = newf;
qtvrequestsize = 0;
}
/*

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, qboolean reused)
static void CL_ClearDlight(dlight_t *dl, int key)
{
void *sm = dl->worldshadowmesh;
unsigned int oq = dl->coronaocclusionquery;
unsigned int oqr = reused?dl->coronaocclusionresult:false;
unsigned int oqr = (dl->key == key)?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, false);
CL_ClearDlight(dl, 0);
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, true);
CL_ClearDlight(dl, key);
return dl;
}
}
@ -270,48 +270,10 @@ dlight_t *CL_AllocDlight (int key)
if (rtlights_first > dl - cl_dlights)
rtlights_first = dl - cl_dlights;
CL_ClearDlight(dl, key, false);
CL_ClearDlight(dl, key);
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
@ -598,8 +560,7 @@ void FlushEntityPacket (void)
memset (&olde, 0, sizeof(olde));
if ((cl.validsequence&UPDATE_MASK) == (cls.netchan.incoming_sequence&UPDATE_MASK))
cl.validsequence = 0; // last-known-good sequence is becoming invalid.
cl.validsequence = 0; // can't render a frame
cl.inframes[cls.netchan.incoming_sequence&UPDATE_MASK].invalid = true;
// read it all, but ignore it
@ -631,11 +592,9 @@ void CLFTE_ReadDelta(unsigned int entnum, entity_state_t *news, entity_state_t *
bits |= MSG_ReadByte()<<16;
if (bits & UF_EXTEND3)
bits |= MSG_ReadByte()<<24;
if (bits & UF_EXTEND4)
Host_EndGame("ent update bit %#x\n", UF_EXTEND4);
if (cl_shownet.ival >= 3)
Con_Printf("%3i: Update %4i 0x%x\n", MSG_GetReadCount(), entnum, bits);
Con_Printf("%3i: Update %4i 0x%x\n", msg_readcount, entnum, bits);
if (bits & UF_RESET)
{
@ -656,15 +615,10 @@ void CLFTE_ReadDelta(unsigned int entnum, entity_state_t *news, entity_state_t *
if (bits & UF_FRAME)
{
if (cls.fteprotocolextensions2 & PEXT2_LERPTIME)
news->frame = MSG_ReadULEB128();
if (bits & UF_16BIT)
news->frame = MSG_ReadShort();
else
{
if (bits & UF_16BIT_LERPTIME)
news->frame = MSG_ReadShort();
else
news->frame = MSG_ReadByte();
}
news->frame = MSG_ReadByte();
}
if (cls.ezprotocolextensions1 & EZPEXT1_FLOATENTCOORDS)
@ -710,24 +664,12 @@ void CLFTE_ReadDelta(unsigned int entnum, entity_state_t *news, entity_state_t *
news->angles[1] = MSG_ReadAngle();
}
if (cls.fteprotocolextensions2 & PEXT2_LERPTIME)
{
if (bits & UF_16BIT_LERPTIME)
news->lerpend = cl.gametime + MSG_ReadULEB128()*(1/1000.0); //most things will animate at 100ms, so this will usually fit a single byte, without capping out.
if (bits & UF_EFFECTS)
news->effects = MSG_ReadULEB128();
if (bits & UF_EFFECTS2_OLD)
Host_EndGame("Received unexpected (redefined) bit %#x\n", UF_EFFECTS2_OLD);
}
else
{
if ((bits & (UF_EFFECTS | UF_EFFECTS2_OLD)) == (UF_EFFECTS | UF_EFFECTS2_OLD))
news->effects = MSG_ReadLong();
else if (bits & UF_EFFECTS2_OLD)
news->effects = (unsigned short)MSG_ReadShort();
else if (bits & UF_EFFECTS)
news->effects = MSG_ReadByte();
}
if ((bits & (UF_EFFECTS | UF_EFFECTS2)) == (UF_EFFECTS | UF_EFFECTS2))
news->effects = MSG_ReadLong();
else if (bits & UF_EFFECTS2)
news->effects = (unsigned short)MSG_ReadShort();
else if (bits & UF_EFFECTS)
news->effects = MSG_ReadByte();
news->u.q1.movement[0] = 0;
news->u.q1.movement[1] = 0;
@ -812,35 +754,20 @@ void CLFTE_ReadDelta(unsigned int entnum, entity_state_t *news, entity_state_t *
if (bits & UF_MODEL)
{
if (cls.fteprotocolextensions2 & PEXT2_LERPTIME)
news->modelindex = MSG_ReadULEB128();
if (bits & UF_16BIT)
news->modelindex = MSG_ReadShort();
else
{
if (bits & UF_16BIT_LERPTIME)
news->modelindex = MSG_ReadShort();
else
news->modelindex = MSG_ReadByte();
}
news->modelindex = MSG_ReadByte();
}
if (bits & UF_SKIN)
{
if (cls.fteprotocolextensions2 & PEXT2_LERPTIME)
news->skinnum = MSG_ReadULEB128()-64; //biased for content overrides
if (bits & UF_16BIT)
news->skinnum = MSG_ReadShort();
else
{
if (bits & UF_16BIT_LERPTIME)
news->skinnum = MSG_ReadShort();
else
news->skinnum = MSG_ReadByte();
}
news->skinnum = MSG_ReadByte();
}
if (bits & UF_COLORMAP)
{
if (cls.fteprotocolextensions2 & PEXT2_LERPTIME)
news->colormap = MSG_ReadULEB128();
else
news->colormap = MSG_ReadByte();
}
news->colormap = MSG_ReadByte();
if (bits & UF_SOLID)
{
@ -867,12 +794,7 @@ void CLFTE_ReadDelta(unsigned int entnum, entity_state_t *news, entity_state_t *
}
if (bits & UF_FLAGS)
{
if (cls.fteprotocolextensions2 & PEXT2_LERPTIME)
news->dpflags = MSG_ReadULEB128();
else
news->dpflags = MSG_ReadByte();
}
news->dpflags = MSG_ReadByte();
if (bits & UF_ALPHA)
news->trans = MSG_ReadByte();
@ -895,16 +817,8 @@ void CLFTE_ReadDelta(unsigned int entnum, entity_state_t *news, entity_state_t *
news->bonecount = 0; //oo, it went away.
if (fl & 0x40)
{
if (cls.fteprotocolextensions2 & PEXT2_LERPTIME)
{
news->basebone = MSG_ReadULEB128();
news->baseframe = MSG_ReadULEB128();
}
else
{
news->basebone = MSG_ReadByte();
news->baseframe = MSG_ReadShort();
}
news->basebone = MSG_ReadByte();
news->baseframe = MSG_ReadShort();
}
else
{
@ -933,14 +847,9 @@ void CLFTE_ReadDelta(unsigned int entnum, entity_state_t *news, entity_state_t *
if (bits & UF_TAGINFO)
{
news->tagentity = MSGCL_ReadEntity();
if (cls.fteprotocolextensions2 & PEXT2_LERPTIME)
news->tagindex = MSG_ReadULEB128()-1; //biased for q3-like portals.
else
{
news->tagindex = MSG_ReadByte();
if (news->tagindex == 0xff)
news->tagindex = ~0;
}
news->tagindex = MSG_ReadByte();
if (news->tagindex == 0xff)
news->tagindex = ~0;
}
if (bits & UF_LIGHT)
{
@ -948,32 +857,20 @@ void CLFTE_ReadDelta(unsigned int entnum, entity_state_t *news, entity_state_t *
news->light[1] = MSG_ReadShort();
news->light[2] = MSG_ReadShort();
news->light[3] = MSG_ReadShort();
if (cls.fteprotocolextensions2 & PEXT2_LERPTIME)
news->lightstyle = MSG_ReadULEB128();
else
news->lightstyle = MSG_ReadByte();
news->lightstyle = MSG_ReadByte();
news->lightpflags = MSG_ReadByte();
}
if (bits & UF_TRAILEFFECT)
{
if (cls.fteprotocolextensions2 & PEXT2_LERPTIME)
{
news->u.q1.traileffectnum = MSG_ReadULEB128();
news->u.q1.emiteffectnum = MSG_ReadULEB128();
}
else
{
unsigned short s;
s = MSG_ReadShort();
news->u.q1.traileffectnum = s & 0x3fff;
if (s & 0x8000)
news->u.q1.emiteffectnum = MSG_ReadShort() & 0x3fff;
else
news->u.q1.emiteffectnum = 0;
}
unsigned short s;
s = MSG_ReadShort();
news->u.q1.traileffectnum = s & 0x3fff;
if (news->u.q1.traileffectnum >= countof(cl.particle_ssprecache))
news->u.q1.traileffectnum = 0;
if (s & 0x8000)
news->u.q1.emiteffectnum = MSG_ReadShort() & 0x3fff;
else
news->u.q1.emiteffectnum = 0;
if (news->u.q1.emiteffectnum >= countof(cl.particle_ssprecache))
news->u.q1.emiteffectnum = 0;
}
@ -996,24 +893,23 @@ void CLFTE_ReadDelta(unsigned int entnum, entity_state_t *news, entity_state_t *
news->fatness = MSG_ReadByte();
if (bits & UF_MODELINDEX2)
{
if (cls.fteprotocolextensions2 & PEXT2_LERPTIME)
news->modelindex2 = MSG_ReadULEB128();
if (bits & UF_16BIT)
news->modelindex2 = MSG_ReadShort();
else
{
if (bits & UF_16BIT_LERPTIME)
news->modelindex2 = MSG_ReadShort();
else
news->modelindex2 = MSG_ReadByte();
}
news->modelindex2 = MSG_ReadByte();
}
if (bits & UF_GRAVITYDIR)
{
news->u.q1.gravitydir[0] = MSG_ReadByte();
news->u.q1.gravitydir[1] = MSG_ReadByte();
}
if (bits & UF_UNUSED2)
{
Host_EndGame("UF_UNUSED2 bit\n");
}
if (bits & UF_UNUSED1)
{
Host_EndGame("ent update bit %#x\n", UF_UNUSED1);
Host_EndGame("UF_UNUSED1 bit\n");
}
}
@ -1077,7 +973,7 @@ void CLFTE_ParseEntities(void)
if (!cl.validsequence)
cl.ackframes[cl.numackframes++] = -1;
else
cl.ackframes[cl.numackframes++] = cls.netchan.incoming_unreliable;
cl.ackframes[cl.numackframes++] = cls.netchan.incoming_sequence;
{
extern vec3_t demoangles;
@ -1203,13 +1099,13 @@ void CLFTE_ParseEntities(void)
if (removeflag)
{
if (cl_shownet.ival >= 3)
Con_Printf("%3i: Remove %i @ %i\n", MSG_GetReadCount(), newnum, cls.netchan.incoming_sequence);
Con_Printf("%3i: Remove %i @ %i\n", msg_readcount, newnum, cls.netchan.incoming_sequence);
if (!newnum)
{
/*removal of world - means forget all entities*/
if (cl_shownet.ival >= 3)
Con_Printf("%3i: Reset all\n", MSG_GetReadCount());
Con_Printf("%3i: Reset all\n", msg_readcount);
newp->num_entities = 0;
oldp = &nullp;
oldp->num_entities = 0;
@ -1317,18 +1213,36 @@ void CLQW_ParsePacketEntities (qboolean delta)
from = MSG_ReadByte ();
// Con_Printf("%i %i from %i\n", cls.netchan.outgoing_sequence, cls.netchan.incoming_sequence, from);
oldpacket = cl.inframes[newpacket].delta_sequence;
if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
from = oldpacket = cls.netchan.incoming_sequence - 1;
oldpacket = cl.inframes[from & UPDATE_MASK].frameid;
if (cl.inframes[from&UPDATE_MASK].invalid || //old frame is unusable
cls.netchan.outgoing_sequence - oldpacket >= UPDATE_BACKUP - 1) // we must have lost the sequence its trying to delta from (or just too old).
{
if (cls.netchan.outgoing_sequence - cls.netchan.incoming_sequence >= UPDATE_BACKUP - 1) {
// there are no valid frames left, so drop it
FlushEntityPacket ();
cl.validsequence = 0;
return;
}
oldp = &cl.inframes[from & UPDATE_MASK].packet_entities;
if ((from & UPDATE_MASK) != (oldpacket & UPDATE_MASK)) {
Con_DPrintf ("WARNING: from mismatch\n");
// FlushEntityPacket ();
// cl.validsequence = 0;
// return;
}
if (cls.netchan.outgoing_sequence - oldpacket >= UPDATE_BACKUP - 1)
{
// we can't use this, it is too old
FlushEntityPacket ();
// don't clear cl.validsequence, so that frames can still be rendered;
// it is possible that a fresh packet will be received before
// (outgoing_sequence - incoming_sequence) exceeds UPDATE_BACKUP - 1
return;
}
oldp = &cl.inframes[oldpacket & UPDATE_MASK].packet_entities;
full = false;
}
else
@ -1378,7 +1292,7 @@ void CLQW_ParsePacketEntities (qboolean delta)
if (word & U_MOREBITS)
{
int oldpos = MSG_GetReadCount();
int oldpos = msg_readcount;
int excessive;
excessive = MSG_ReadByte();
if (excessive & U_EVENMORE)
@ -1390,7 +1304,7 @@ void CLQW_ParsePacketEntities (qboolean delta)
newnum += 1024;
}
MSG_ReadSkip(oldpos-MSG_GetReadCount());//undo the read...
msg_readcount = oldpos;//undo the read...
}
oldnum = oldindex >= oldp->num_entities ? 9999 : oldp->entities[oldindex].number;
@ -1411,7 +1325,7 @@ void CLQW_ParsePacketEntities (qboolean delta)
newp->entities = BZ_Realloc(newp->entities, sizeof(entity_state_t)*newp->max_entities);
}
if (oldindex >= oldp->max_entities)
Host_EndGame("Old packet entity too big\n");
Host_EndGame("Old packet entity too big\n");
newp->entities[newindex] = oldp->entities[oldindex];
newindex++;
oldindex++;
@ -1507,7 +1421,7 @@ void DP5_ParseDelta(entity_state_t *s, packet_entities_t *pack)
unsigned int bits;
if (cl_shownet.ival >= 3)
Con_Printf("%3i: Update %i", MSG_GetReadCount(), s->number);
Con_Printf("%3i: Update %i", msg_readcount, s->number);
bits = MSG_ReadByte();
if (bits & E5_EXTEND1)
@ -1860,7 +1774,6 @@ void CLNQ_ParseEntity(unsigned int bits)
packet_entities_t *pack;
qboolean isnehahra = CPNQ_IS_BJP||(cls.protocol_nq == CPNQ_NEHAHRA);
qboolean floatcoords;
if (cls.signon == 4 - 1)
{ // first update is the final signon stage
@ -1924,8 +1837,6 @@ void CLNQ_ParseEntity(unsigned int bits)
state->dpflags = 0;
floatcoords = cls.qex && (bits & QE_U_FLOATCOORDS);
if (bits & NQU_MODEL)
{
if (CPNQ_IS_BJP)
@ -1944,34 +1855,20 @@ void CLNQ_ParseEntity(unsigned int bits)
state->skinnum = MSG_ReadByte();
if (bits & NQU_EFFECTS)
{
i = MSG_ReadByte();
if (cls.qex)
{
unsigned fixed = i & ~(REEF_QUADLIGHT|REEF_PENTLIGHT|REEF_CANDLELIGHT);
if (i & REEF_QUADLIGHT)
fixed |= EF_BLUE;
if (i & REEF_PENTLIGHT)
fixed |= EF_RED;
if (i & REEF_CANDLELIGHT)
fixed |= 0; //tiny light
i = fixed;
}
state->effects = i;
}
state->effects = MSG_ReadByte();
if (bits & NQU_ORIGIN1)
state->origin[0] = floatcoords?MSG_ReadFloat():MSG_ReadCoord ();
state->origin[0] = MSG_ReadCoord ();
if (bits & NQU_ANGLE1)
state->angles[0] = MSG_ReadAngle();
if (bits & NQU_ORIGIN2)
state->origin[1] = floatcoords?MSG_ReadFloat():MSG_ReadCoord ();
state->origin[1] = MSG_ReadCoord ();
if (bits & NQU_ANGLE2)
state->angles[1] = MSG_ReadAngle();
if (bits & NQU_ORIGIN3)
state->origin[2] = floatcoords?MSG_ReadFloat():MSG_ReadCoord ();
state->origin[2] = MSG_ReadCoord ();
if (bits & NQU_ANGLE3)
state->angles[2] = MSG_ReadAngle();
@ -2009,21 +1906,7 @@ void CLNQ_ParseEntity(unsigned int bits)
state->modelindex = (state->modelindex & 0xff) | (MSG_ReadByte() << 8);
if (bits & FITZU_LERPFINISH)
state->lerpend = cl.gametime + MSG_ReadByte()/255.0f;
if (cls.qex)
{
if (bits & QE_U_SOLIDTYPE) /*state->solidsize =*/ MSG_ReadByte(); //needed for correct prediction
if (bits & QE_U_ENTFLAGS) /*state->entflags = */ MSG_ReadULEB128(); //for onground/etc state
if (bits & QE_U_HEALTH) /*state->health =*/ MSG_ReadSignedQEX(); //health... not really sure why, I suppose it changes player physics (they should have sent movetype instead though).
if (bits & QE_U_UNKNOWN26) /*unknown =*/MSG_ReadByte();
if (bits & QE_U_UNUSED27) Con_Printf(CON_WARNING"QE_U_UNUSED27: %u\n", MSG_ReadByte());
if (bits & QE_U_UNUSED28) Con_Printf(CON_WARNING"QE_U_UNUSED28: %u\n", MSG_ReadByte());
if (bits & QE_U_UNUSED29) Con_Printf(CON_WARNING"QE_U_UNUSED29: %u\n", MSG_ReadByte());
if (bits & QE_U_UNUSED30) Con_Printf(CON_WARNING"QE_U_UNUSED30: %u\n", MSG_ReadByte());
if (bits & QE_U_UNUSED31) Con_Printf(CON_WARNING"QE_U_UNUSED31: %u\n", MSG_ReadByte());
}
MSG_ReadByte();
}
else
{ //dp tends to leak stuff, so parse as quakedp if the normal protocol doesn't define it as something better.
@ -2291,19 +2174,6 @@ entity_t *V_AddEntity(entity_t *in)
return ent;
}
entity_t *V_AddNewEntity(void)
{
entity_t *ent;
if (cl_numvisedicts == cl_maxvisedicts)
{
cl_expandvisents = true;
return NULL; // object list is full
}
ent = &cl_visedicts[cl_numvisedicts];
cl_numvisedicts++;
return ent;
}
/*
void VQ2_AddLerpEntity(entity_t *in) //a convienience function
{
@ -3375,7 +3245,7 @@ static void CL_LerpNetFrameState(framestate_t *fs, lerpents_t *le)
fs->g[0].endbone = le->basebone;
}
static void CL_UpdateNetFrameLerpState(qboolean force, int curframe, int curbaseframe, int curbasebone, lerpents_t *le, float lerpend)
static void CL_UpdateNetFrameLerpState(qboolean force, int curframe, int curbaseframe, int curbasebone, lerpents_t *le)
{
int fst, frame;
if (curbasebone != le->basebone)
@ -3392,10 +3262,7 @@ static void CL_UpdateNetFrameLerpState(qboolean force, int curframe, int curbase
frame = (fst==FST_BASE)?curbaseframe:curframe;
if (force || frame != le->newframe[fst])
{
if (lerpend)
le->framelerpdeltatime[fst] = bound(0, lerpend - cl.servertime, cl_lerp_maxinterval.value); //clamp to 10 tics per second
else
le->framelerpdeltatime[fst] = bound(0, cl.servertime - le->newframestarttime[fst], cl_lerp_maxinterval.value); //clamp to 10 tics per second
le->framelerpdeltatime[fst] = bound(0, cl.servertime - le->newframestarttime[fst], cl_lerp_maxinterval.value); //clamp to 10 tics per second
if (!force)
{
@ -3430,6 +3297,7 @@ void CL_ClearLerpEntsParticleState(void)
}
}
qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel);
void CL_LinkStaticEntities(void *pvs, int *areas)
{
int i;
@ -3534,6 +3402,73 @@ void CL_LinkStaticEntities(void *pvs, int *areas)
// FIXME: no effects on static ents
// CLQ1_AddPowerupShell(ent, false, stat->effects);
}
if (cl.worldmodel->numstaticents)
{
struct modelstaticent_s *sent;
entity_t *src;
float d;
vec3_t disp;
for (i = 0; i < cl.worldmodel->numstaticents; i++)
{
if (cl_numvisedicts == cl_maxvisedicts)
{
cl_expandvisents=true;
break;
}
sent = &cl.worldmodel->staticents[i];
src = &sent->ent;
if (sent->fademaxdist)
{
VectorSubtract(r_refdef.vieworg, src->origin, disp);
d = VectorLength(disp);
if (d > sent->fademaxdist)
continue; //skip it.
d -= sent->fademindist;
d /= sent->fademaxdist-sent->fademindist;
if (d < 0)
d = 0;
}
else
d = 0;
if (!src->model || src->model->loadstate != MLS_LOADED)
{
if (src->model && src->model->loadstate == MLS_NOTLOADED)
Mod_LoadModel(src->model, MLV_WARN); //we use threads, so these'll load in time.
continue;
}
/*if (!src->light_known)
{
vec3_t tmp;
VectorCopy(src->origin, tmp);
VectorCopy(sent->lightorg, src->origin);
R_CalcModelLighting(src, src->model); //bake and cache, now everything else is working.
VectorCopy(tmp, src->origin);
}*/
if (src->pvscache.num_leafs==-2)
{
vec3_t absmin, absmax;
float r = src->model->radius;
VectorSet(absmin, -r,-r,-r);
VectorSet(absmax, r,r,r);
VectorAdd(absmin, src->origin, absmin);
VectorAdd(absmax, src->origin, absmax);
cl.worldmodel->funcs.FindTouchedLeafs(cl.worldmodel, &src->pvscache, absmin, absmax);
}
ent = &cl_visedicts[cl_numvisedicts++];
*ent = *src;
ent->framestate.g[FS_REG].frametime[0] = cl.time;
ent->framestate.g[FS_REG].frametime[1] = cl.time;
if (d)
{
ent->shaderRGBAf[3] *= 1-d;
ent->flags |= RF_TRANSLUCENT;
}
}
}
}
//returns cos(angle)
@ -3684,7 +3619,7 @@ static void CL_TransitionPacketEntities(int newsequence, packet_entities_t *newp
le->isnew = true;
VectorCopy(le->origin, le->lastorigin);
}
CL_UpdateNetFrameLerpState(sold == snew, snew->frame, snew->baseframe, snew->basebone, le, snew->lerpend);
CL_UpdateNetFrameLerpState(sold == snew, snew->frame, snew->baseframe, snew->basebone, le);
from = sold; //eww
@ -3754,10 +3689,7 @@ static void CL_TransitionPacketEntities(int newsequence, packet_entities_t *newp
VectorCopy(snew__origin, le->neworigin);
VectorCopy(snew->angles, le->newangle);
if (snew->lerpend)
le->orglerpdeltatime = bound(0.001, snew->lerpend - newpack->servertime, cl_lerp_maxinterval.value);
else
le->orglerpdeltatime = newpack->servertime - oldpack->servertime;
le->orglerpdeltatime = newpack->servertime - oldpack->servertime;
le->orglerpstarttime = oldpack->servertime;
le->isnew = true;
@ -3785,8 +3717,6 @@ static void CL_TransitionPacketEntities(int newsequence, packet_entities_t *newp
VectorCopy(snew->angles, le->newangle);
}
if (snew->lerpend)
le->orglerpdeltatime = bound(0.001, snew->lerpend - le->orglerpstarttime, cl_lerp_maxinterval.value);
lfrac = (servertime - le->orglerpstarttime) / le->orglerpdeltatime;
lfrac = bound(0, lfrac, 1);
if (r_nolerp.ival)
@ -3824,8 +3754,6 @@ static void CL_TransitionPacketEntities(int newsequence, packet_entities_t *newp
le->orglerpstarttime = servertime;
}
if (snew->lerpend)
le->orglerpdeltatime = bound(0.001, snew->lerpend - le->orglerpstarttime, cl_lerp_maxinterval.value);
lfrac = (servertime - le->orglerpstarttime) / le->orglerpdeltatime;
lfrac = bound(0, lfrac, 1);
@ -3856,7 +3784,7 @@ static void CL_TransitionPacketEntities(int newsequence, packet_entities_t *newp
}
#endif
CL_UpdateNetFrameLerpState(isnew, snew->frame, snew->baseframe, snew->basebone, le, snew->lerpend);
CL_UpdateNetFrameLerpState(isnew, snew->frame, snew->baseframe, snew->basebone, le);
}
}
@ -4144,7 +4072,7 @@ void CL_LinkPacketEntities (void)
#ifdef HEXEN2
ent->h2playerclass = 0;
#endif
ent->light_known = 0;
ent->light_type = ELT_UNKNOWN;
ent->forcedshader = NULL;
ent->shaderTime = 0;
@ -4236,22 +4164,6 @@ void CL_LinkPacketEntities (void)
#endif
}
if (r_torch.ival && state->number <= cl.allocated_client_slots)
{
dlight_t *dl;
dl = CL_NewDlight(state->number, ent->origin, 300, r_torch.ival, 0.9, 0.9, 0.6);
dl->flags |= LFLAG_SHADOWMAP|LFLAG_FLASHBLEND;
dl->fov = 90;
VectorCopy(le->angles, angles);
angles[0] *= 3;
// angles[1] += sin(realtime)*8;
// angles[0] += cos(realtime*1.13)*5;
AngleVectorsMesh(angles, dl->axis[0], dl->axis[1], dl->axis[2]);
VectorInverse(dl->axis[1]);
VectorMA(dl->origin, 16, dl->axis[0], dl->origin);
}
// if set to invisible, skip
if (state->modelindex<1 || (state->effects & NQEF_NODRAW))
{
@ -4299,7 +4211,7 @@ void CL_LinkPacketEntities (void)
if (cl.model_precache_vwep[0] && state->modelindex2 < MAX_VWEP_MODELS)
{
if (state->modelindex == cl_playerindex && cl.model_precache_vwep[0]->loadstate == MLS_LOADED &&
state->modelindex2 && cl.model_precache_vwep[state->modelindex2] && cl.model_precache_vwep[state->modelindex2]->loadstate == MLS_LOADED)
cl.model_precache_vwep[state->modelindex2] && cl.model_precache_vwep[state->modelindex2]->loadstate == MLS_LOADED)
{
model = cl.model_precache_vwep[0];
model2 = cl.model_precache_vwep[state->modelindex2];
@ -4434,7 +4346,10 @@ void CL_LinkPacketEntities (void)
ent->shaderRGBAf[1] = (state->colormod[1]*8.0f)/256;
ent->shaderRGBAf[2] = (state->colormod[2]*8.0f)/256;
}
VectorScale(state->glowmod, 8.0/256.0, ent->glowmod);
if (state->colormod[0] == 32 && state->colormod[1] == 32 && state->colormod[2] == 32)
VectorSet(ent->glowmod, 1, 1, 1);
else
VectorScale(state->glowmod, 1/255.0, ent->glowmod);
#ifdef PEXT_FATNESS
//set trans
@ -4544,6 +4459,20 @@ void CL_LinkPacketEntities (void)
CLQ1_AddShadow(ent);
CLQ1_AddPowerupShell(ent, false, state->effects);
if (r_torch.ival && ent->keynum <= cl.allocated_client_slots)
{
dlight_t *dl;
dl = CL_NewDlight(ent->keynum, ent->origin, 300, r_torch.ival, 0.9, 0.9, 0.6);
dl->flags |= LFLAG_SHADOWMAP|LFLAG_FLASHBLEND;
dl->fov = 90;
angles[0] *= 3;
// angles[1] += sin(realtime)*8;
// angles[0] += cos(realtime*1.13)*5;
AngleVectors(angles, dl->axis[0], dl->axis[1], dl->axis[2]);
VectorMA(dl->origin, 16, dl->axis[0], dl->origin);
}
if (model2)
CL_AddVWeapModel (ent, model2);
@ -5357,7 +5286,7 @@ void CL_LinkPlayers (void)
continue; // not present this frame
}
CL_UpdateNetFrameLerpState(false, state->frame, 0, 0, &cl.lerpplayers[j], 0);
CL_UpdateNetFrameLerpState(false, state->frame, 0, 0, &cl.lerpplayers[j]);
cl.lerpplayers[j].sequence = cl.lerpentssequence;
#ifdef CSQC_DAT

View File

@ -289,327 +289,60 @@ static cvar_t cl_weaponforgetorder = CVARD("cl_weaponforgetorder", "0", "The 'we
cvar_t r_viewpreselgun = CVARD("r_viewpreselgun", "0", "HACK: Display the preselected weaponmodel, instead of the current weaponmodel.");
static int preselectedweapons[MAX_SPLITS];
static int preselectedweapon[MAX_SPLITS][32];
static kbutton_t in_wwheel;
static float wwheeldir[MAX_SPLITS][2];
static size_t wwheelsel[MAX_SPLITS];
static double wwheelseltime[MAX_SPLITS];
static struct weaponinfo_s {
char shortname[32]; //must not look like an impulse.
int impulse; //primary key...
int items_mask;
int items_val;
// int weapon_val; //unused...
int ammostat;
int ammomin;
char *icons[3]; //unselected,selected,ammo
char *viewmodel;
} *weaponinfo;
static size_t weaponinfo_count;
static int IN_NameToWeaponIdx(const char *name)
{
size_t i;
char *end;
i = strtoul(name, &end, 10);
if (i && !end)
{ //select by impulse when they specified something numeric.
for (i = 0; i < weaponinfo_count; i++)
{
if (weaponinfo[i].impulse == i)
return i;
}
}
else
{
for (i = 0; i < weaponinfo_count; i++)
{
if (!strcmp(name, weaponinfo[i].shortname))
return i;
}
}
return -1;
}
static int IN_RegisterWeapon(int impulse, const char *name, int items_mask, int items_val, int weapon_val, int ammostat, int ammomin, const char *viewmodel, const char *icon,const char *selicon, const char *ammoicon)
{
size_t i;
char *end;
if (impulse <= 0 || impulse > 255)
return -1; //no. just no...
if (strtol(name, &end, 10) != impulse)
{
if (!*end)
return -1; //parsed as a number, which didn't match its impulse... don't break the impulse command.
}
//slots are unique/replaced by impulse
for (i = 0; i < weaponinfo_count; i++)
{
if (weaponinfo[i].impulse == impulse)
break; //replace...
}
if (i == weaponinfo_count)
Z_ReallocElements((void**)&weaponinfo, &weaponinfo_count, i+1, sizeof(*weaponinfo));
weaponinfo[i].impulse = impulse;
Q_strncpyz(weaponinfo[i].shortname, name, sizeof(weaponinfo[i].shortname));
weaponinfo[i].items_mask = items_mask;
weaponinfo[i].items_val = items_val;
// weaponinfo[i].weapon_val; //unused...
weaponinfo[i].ammostat = ammostat;
weaponinfo[i].ammomin = ammomin;
#define Z_StrDupPtr2(v,s) do{Z_Free(*v),*(v) = (s&&*s)?strcpy(Z_Malloc(strlen(s)+1), s):NULL;}while(0)
Z_StrDupPtr2(&weaponinfo[i].viewmodel, viewmodel);
Z_StrDupPtr2(&weaponinfo[i].icons[0], icon);
Z_StrDupPtr2(&weaponinfo[i].icons[1], selicon);
Z_StrDupPtr2(&weaponinfo[i].icons[2], ammoicon);
return i;
}
static void IN_RegisterWeapon_Clear(void)
{
while(weaponinfo_count)
Z_Free(weaponinfo[--weaponinfo_count].viewmodel);
Z_Free(weaponinfo);
weaponinfo = NULL;
}
void IN_RegisterWeapon_Reset(void)
{
vfsfile_t *f;
IN_RegisterWeapon_Clear();
f = FS_OpenVFS("wwheel.txt", "rb", FS_GAME);
if (f)
{ //from the rerelease:
/*
slot N
{
impulse N
icon "gfx/weapons/ww_foo_1.lmp"
icon_sel "gfx/weapons/ww_foo_2.lmp"
ammoicon "FOO"
entvaroffs N
weaponnum N
}
*/
char line[1024];
char *v;
for(;;)
{
if (!VFS_GETS(f, line, sizeof(line)))
break;
v = COM_Parse(line);
if (!strcmp(com_token, "slot")) //slot N... just assume they're ordered.
{
//v = COM_Parse(line);
//slot = com_token
if (!VFS_GETS(f, line, sizeof(line)))
break;
v = COM_Parse(line);
if (!strcmp(com_token, "{"))
{
int weaponbit=0;
int impulse=0;
int ammostat=-1;
int ammocount=0;
int field;
char *icon = NULL;
char *selicon = NULL;
char *ammoicon = NULL;
char *viewmodel = NULL;
char *name = NULL;
for (;;)
{
if (!VFS_GETS(f, line, sizeof(line)))
break;
v = COM_Parse(line);
if (!strcmp(com_token, "}"))
{ //end of this weapon.
IN_RegisterWeapon(impulse, name?name:va("%i", impulse), weaponbit,weaponbit, weaponbit, ammostat,ammocount, viewmodel, icon, selicon, ammoicon);
break;
}
else if (!strcmp(com_token, "impulse"))
{
v = COM_Parse(v);
impulse = atoi(com_token);
}
else if (!strcmp(com_token, "weaponnum"))
{
v = COM_Parse(v);
weaponbit = atoi(com_token);
}
else if (!strcmp(com_token, "icon"))
{
v = COM_Parse(v);
Z_StrDupPtr(&icon, com_token);
}
else if (!strcmp(com_token, "icon_sel"))
{
v = COM_Parse(v);
Z_StrDupPtr(&selicon, com_token);
}
else if (!strcmp(com_token, "ammoicon"))
{
v = COM_Parse(v);
if (strchr(com_token, '.') || strchr(com_token, '/'))
Z_StrDupPtr(&ammoicon, com_token);
else
Z_StrDupPtr(&ammoicon, va("gfx/%s", com_token));
}
else if (!strcmp(com_token, "entvaroffs"))
{ //this seems to be a host-only thing. the server can poke the qc's fields directly but other clients can't.
//remap known indexes to stats - this can only work for nq's system fields.
//note that rogue does some windowing thing so our client can only know either nails or lavanails, not both. either way those are NOT the normal stats and these weapons will appear to have infinite ammo as a result, sorry.
//they really should have used field names here, not numbers, but hey, not my spec... use our 'ammostat' instead for fancy mods.
v = COM_Parse(v);
field = atoi(com_token);
switch(field)
{
case 216: ammostat = STAT_SHELLS, ammocount = 1; break;
case 220: ammostat = STAT_NAILS, ammocount = 1; break;
case 224: ammostat = STAT_ROCKETS, ammocount = 1; break;
case 228: ammostat = STAT_CELLS, ammocount = 1; break;
default: ammostat = -1, ammocount = 0; break;
}
}
else if (!strcmp(com_token, "ammostat"))
{ //non-qe
v = COM_Parse(v);
ammostat = atoi(com_token);
if (ammocount <= 0)
ammocount = 1;
}
else if (!strcmp(com_token, "ammomin"))
{ //non-qe
v = COM_Parse(v);
ammocount = atoi(com_token);
}
else if (!strcmp(com_token, "viewmodel"))
{ //non-qe, so preselect can show the correct model before its actually changed.
v = COM_Parse(v);
Z_StrDupPtr(&viewmodel, com_token);
}
else if (!strcmp(com_token, "shortname"))
{ //non-qe, for `+fire nq`
v = COM_Parse(v);
Z_StrDupPtr(&name, com_token);
}
else if (*com_token)
Con_Printf("Unexpected line in wwheel.txt: %s\n", line);
}
Z_Free(icon);
Z_Free(selicon);
Z_Free(ammoicon);
Z_Free(viewmodel);
Z_Free(name);
}
else
{
Con_Printf("missing block, found: %s\n", line);
break;
}
}
else if (*com_token)
Con_Printf("Unexpected line in wwheel.txt: %s\n", line);
}
VFS_CLOSE(f);
}
else
{
IN_RegisterWeapon(2, "sg", IT_SHOTGUN,IT_SHOTGUN, IT_SHOTGUN, STAT_SHELLS,1, "progs/v_shot.mdl", NULL,NULL, "gfx/sb_shells");
IN_RegisterWeapon(3, "ssg", IT_SUPER_SHOTGUN,IT_SUPER_SHOTGUN, IT_SUPER_SHOTGUN, STAT_SHELLS,1, "progs/v_shot2.mdl", NULL,NULL, "gfx/sb_shells");
IN_RegisterWeapon(4, "ng", IT_NAILGUN,IT_NAILGUN, IT_NAILGUN, STAT_NAILS,1, "progs/v_nail.mdl", NULL,NULL, "gfx/sb_nails");
IN_RegisterWeapon(5, "sng", IT_SUPER_NAILGUN,IT_SUPER_NAILGUN, IT_SUPER_NAILGUN, STAT_NAILS,1, "progs/v_nail2.mdl", NULL,NULL, "gfx/sb_nails");
IN_RegisterWeapon(6, "gl", IT_GRENADE_LAUNCHER,IT_GRENADE_LAUNCHER, IT_GRENADE_LAUNCHER, STAT_ROCKETS,1, "progs/v_rock.mdl", NULL,NULL, "gfx/sb_rocket");
IN_RegisterWeapon(7, "rl", IT_ROCKET_LAUNCHER,IT_ROCKET_LAUNCHER, IT_ROCKET_LAUNCHER, STAT_ROCKETS,1, "progs/v_rock2.mdl", NULL,NULL, "gfx/sb_rocket");
IN_RegisterWeapon(8, "lg", IT_LIGHTNING,IT_LIGHTNING, IT_LIGHTNING, STAT_CELLS,1, "progs/v_light.mdl", NULL,NULL, "gfx/sb_cells");
IN_RegisterWeapon(1, "axe", IT_AXE,IT_AXE, IT_AXE, -1,0, "progs/v_axe.mdl", NULL, NULL, NULL);
}
}
static void IN_RegisterWeapon_f(void)
{
if (Cmd_Argc() <= 2)
{
const char *arg = Cmd_Argv(1);
if (!strcmp(arg, "clear"))
IN_RegisterWeapon_Clear();
else if (!strcmp(arg, "reset") || !strcmp(arg, "quake")) //'quake' for compat with dp.
IN_RegisterWeapon_Reset();
else
Con_Printf("Unknown arg %s\n", Cmd_Argv(1));
}
else
{
IN_RegisterWeapon( atoi(Cmd_Argv(2)), //impulse
Cmd_Argv(1), //name
atoi(Cmd_Argv(3)), //itemsmask
atoi(Cmd_Argv(3)), //itemsval
atoi(Cmd_Argv(4)), //weaponval
atoi(Cmd_Argv(5)), //ammostat
atoi(Cmd_Argv(6)), //ammomin
Cmd_Argv(7), //viewmodel
Cmd_Argv(8), //weaponicon
Cmd_Argv(9), //weaponicon_sel
Cmd_Argv(10)); //ammoicon
}
}
//hacks, because we have to guess what the mod is doing. we'll probably get it wrong, which sucks.
static qboolean IN_HaveWeapon_Idx(int pnum, size_t widx)
static qboolean IN_HaveWeapon(int pnum, int imp)
{
if (widx < weaponinfo_count)
if ((cl.playerview[pnum].stats[STAT_ITEMS]&weaponinfo[widx].items_mask) == weaponinfo[widx].items_val) //we have the weapon
if (weaponinfo[widx].ammostat < 0 || cl.playerview[pnum].stats[weaponinfo[widx].ammostat] >= weaponinfo[widx].ammomin) //and we have enough ammo for it too.
return true;
return false;
}
static qboolean IN_HaveWeapon(int pnum, int impulse)
{
size_t widx;
for (widx = 0; widx < weaponinfo_count; widx++)
unsigned int items = cl.playerview[pnum].stats[STAT_ITEMS];
switch (imp)
{
if (weaponinfo[widx].impulse == impulse)
return IN_HaveWeapon_Idx(pnum, widx);
case 1: return (items & IT_AXE)?true:false;
case 2: return (items & IT_SHOTGUN && cl.playerview[pnum].stats[STAT_SHELLS] >= 1)?true:false;
case 3: return (items & IT_SUPER_SHOTGUN && cl.playerview[pnum].stats[STAT_SHELLS] >= 2)?true:false;
case 4: return (items & IT_NAILGUN && cl.playerview[pnum].stats[STAT_NAILS] >= 1)?true:false;
case 5: return (items & IT_SUPER_NAILGUN && cl.playerview[pnum].stats[STAT_NAILS] >= 2)?true:false;
case 6: return (items & IT_GRENADE_LAUNCHER && cl.playerview[pnum].stats[STAT_ROCKETS] >= 1)?true:false;
case 7: return (items & IT_ROCKET_LAUNCHER && cl.playerview[pnum].stats[STAT_ROCKETS] >= 1)?true:false;
case 8: return (items & IT_LIGHTNING && cl.playerview[pnum].stats[STAT_CELLS] >= 1)?true:false;
}
return false; //we don't really know about it, but assume we can't because false negatives are better than false positives here.
}
static qboolean IN_HaveWeapon_Name(int pnum, char *name, int *impulse)
{
int widx = IN_NameToWeaponIdx(name);
if (widx < 0)
return false;
if (!IN_HaveWeapon_Idx(pnum, widx))
return false;
*impulse = weaponinfo[widx].impulse;
return true;
return false;
}
static int IN_BestWeapon_Pre(unsigned int pnum);
//if we're using weapon preselection, then we probably also want to show which weapon will be selected, instead of showing the shotgun the whole time.
//this of course requires more hacks.
const char *IN_GetPreselectedViewmodelName(unsigned int pnum)
{
static const char *nametable[] =
{
NULL, //can't cope with a 0
"progs/v_axe.mdl",
"progs/v_shot.mdl",
"progs/v_shot2.mdl",
"progs/v_nail.mdl",
"progs/v_nail2.mdl",
"progs/v_rock.mdl",
"progs/v_rock2.mdl",
"progs/v_light.mdl",
};
if (r_viewpreselgun.ival && cl_weaponpreselect.ival && pnum < countof(preselectedweapons) && preselectedweapons[pnum])
{
int best = IN_BestWeapon_Pre(pnum);
size_t widx;
for (widx = 0; widx < weaponinfo_count; widx++)
{
if (weaponinfo[widx].impulse == best)
return weaponinfo[widx].viewmodel;
}
if (best < countof(nametable))
return nametable[best];
}
return NULL;
}
//FIXME: make a script to decide if a weapon is held? call into the csqc?
static int IN_BestWeapon_Args(unsigned int pnum, int firstarg, int argcount)
{ //returns impulses.
{
int i, imp;
unsigned int best = 0;
for (i = firstarg + argcount; --i >= firstarg; )
{
if (IN_HaveWeapon_Name(pnum, Cmd_Argv(i), &imp))
imp = Q_atoi(Cmd_Argv(i));
if (IN_HaveWeapon(pnum, imp))
best = imp;
}
@ -632,21 +365,13 @@ static int IN_BestWeapon_Pre(unsigned int pnum)
static void IN_DoPostSelect(void)
{
int pnum = CL_TargettedSplit(false);
if (cl_weaponpreselect.ival)
{
int pnum = CL_TargettedSplit(false);
int best = IN_BestWeapon_Pre(pnum);
if (best)
CL_QueueImpulse(pnum, best);
}
if (in_wwheel.state[pnum]&1)
{
in_wwheel.state[pnum] = 0;
pnum = CL_TargettedSplit(false);
if (wwheelsel[pnum] < weaponinfo_count)
CL_QueueImpulse(pnum, weaponinfo[wwheelsel[pnum]].impulse);
}
}
//The weapon command autoselects a prioritised weapon like multi-arg impulse does.
//however, it potentially makes the switch only on the next +attack.
@ -656,17 +381,9 @@ void IN_Weapon (void)
int pnum = CL_TargettedSplit(false);
int mode, best, i;
preselectedweapons[pnum] = 0;
for (i = 1; i < Cmd_Argc() && i <= countof(preselectedweapon[pnum]); i++)
{
best = IN_NameToWeaponIdx(Cmd_Argv(i));
if (best >= 0)
best = weaponinfo[best].impulse; //a known weapon
else
best = atoi(Cmd_Argv(i)); //fall back
if (best > 0)
preselectedweapon[pnum][preselectedweapons[pnum]++] = best;
}
preselectedweapon[pnum][i-1] = atoi(Cmd_Argv(i));
preselectedweapons[pnum] = i-1;
best = IN_BestWeapon_Pre(pnum);
if (best)
@ -730,7 +447,8 @@ static void IN_DoWeaponHide(void)
while(l && *l)
{
l = COM_ParseOut(l, tok, sizeof(tok));
if (IN_HaveWeapon_Name(pnum, tok, &impulse))
impulse = atoi(tok);
if (IN_HaveWeapon(pnum, impulse))
best = impulse;
}
if (best)
@ -758,130 +476,6 @@ void IN_FireUp(void)
if (KeyUp_Scan(&in_attack, k))
IN_DoWeaponHide();
}
qboolean IN_WeaponWheelAccumulate(int pnum, float x, float y) //either mouse or controller
{
if (!(in_wwheel.state[pnum]&1) || !weaponinfo_count)
return false;
wwheeldir[pnum][0] += x;
wwheeldir[pnum][1] += y;
return true;
}
#include "shader.h"
qboolean IN_DrawWeaponWheel(int pnum)
{
int w;
float pos[2], centre[2];
const float radius = 64;
float d, a;
shader_t *s;
if (!(in_wwheel.state[pnum]&1) || !weaponinfo_count)
return false;
R2D_ImageColours(1,1,1,1);
centre[0] = cl.playerview[pnum].gamerect.x + cl.playerview[pnum].gamerect.width/2;
centre[1] = cl.playerview[pnum].gamerect.y + cl.playerview[pnum].gamerect.height/2;
d = DotProduct2(wwheeldir[pnum],wwheeldir[pnum]);
a = 32;
if (d > a*a && d)
{
wwheeldir[pnum][0] *= a/sqrt(d);
wwheeldir[pnum][1] *= a/sqrt(d);
}
a = atan2(wwheeldir[pnum][1], wwheeldir[pnum][0]);
w = (a/(2*M_PI)+1) * weaponinfo_count + 0.5;
w = w % weaponinfo_count;
if (w != wwheelsel[pnum])
{
wwheelseltime[pnum] = realtime;
wwheelsel[pnum] = w;
}
s = R2D_SafeCachePic("gfx/weaponwheel.lmp");
if (R_GetShaderSizes(s, NULL, NULL, false)>0)
R2D_Image(centre[0]-radius*2, centre[1]-radius*2, radius*4, radius*4, 0, 0, 1, 1, s);
for (w = 0; w < weaponinfo_count; w++)
{
pos[0] = centre[0] + cos((w*2*M_PI) / weaponinfo_count)*radius;
pos[1] = centre[1] + sin((w*2*M_PI) / weaponinfo_count)*radius;
if (weaponinfo[w].icons[0])
{ //draw a shadow
R2D_ImageColours(0,0,0,1);
R2D_Image(pos[0]-24+2, pos[1]-16+2, 48, 32, 0, 0, 1, 1, R2D_SafeCachePic(weaponinfo[w].icons[0]));
}
//and the real icon (dark if unavailable)
if (IN_HaveWeapon_Idx(pnum, w))
R2D_ImageColours(1,1,1,1);
else
R2D_ImageColours(0.2,0.2,0.2,1);
if (w == wwheelsel[pnum])
d = 1+sin((realtime - wwheelseltime[pnum])*10); //make it bounce
else
d = 0;
if (cl.playerview[pnum].stats[STAT_ACTIVEWEAPON] == weaponinfo[w].items_val && weaponinfo[w].icons[1])
R2D_Image(pos[0]-24-d, pos[1]-16-d, 48, 32, 0, 0, 1, 1, R2D_SafeCachePic(weaponinfo[w].icons[1]));
else if (weaponinfo[w].icons[0])
R2D_Image(pos[0]-24-d, pos[1]-16-d, 48, 32, 0, 0, 1, 1, R2D_SafeCachePic(weaponinfo[w].icons[0]));
else
Draw_FunStringWidth(pos[0]-32-d, pos[1]-4-d, weaponinfo[w].shortname, 64, 2, cl.playerview[pnum].stats[STAT_ACTIVEWEAPON] == weaponinfo[w].items_val);
}
R2D_ImageColours(1,1,1,1);
w = wwheelsel[pnum];
if (weaponinfo[w].icons[2])
R2D_Image(centre[0]-12, centre[1]-12, 24, 24, 0, 0, 1, 1, R2D_SafeCachePic(weaponinfo[w].icons[2]));
Draw_FunStringWidth(centre[0]-32, centre[1] - 28, weaponinfo[w].shortname, 64, 2, false);
if (weaponinfo[w].ammostat >= 0)
Draw_FunStringWidth(centre[0]-32, centre[1] + 20, va("%s%d", (cl.playerview[pnum].stats[weaponinfo[w].ammostat]<20)?S_COLOR_RED:"", cl.playerview[pnum].stats[weaponinfo[w].ammostat]), 64, 2, false);
pos[0] = centre[0] + cos(a)*radius*0.6;
pos[1] = centre[1] + sin(a)*radius*0.6;
Draw_FunString(pos[0], pos[1], "X");
return true;
}
static void IN_WWheelDown (void)
{
#ifdef CSQC_DAT
int pnum = CL_TargettedSplit(false);
if (CSQC_ConsoleCommand(pnum, Cmd_Argv(0)))
return;
#endif
if (!(in_wwheel.state[pnum]&1))
{
size_t w;
for (w = 0; w < weaponinfo_count; w++)
{
if (cl.playerview[pnum].stats[STAT_ACTIVEWEAPON] == weaponinfo[w].items_val)
{ //this is our active weapon. start with it highlighted.
wwheelseltime[pnum] = realtime;
wwheelsel[pnum] = w;
wwheeldir[pnum][0] = cos((wwheelsel[pnum]*2*M_PI) / weaponinfo_count)*16;
wwheeldir[pnum][1] = sin((wwheelsel[pnum]*2*M_PI) / weaponinfo_count)*16;
break;
}
}
}
KeyDown(&in_wwheel, NULL);
}
static void IN_WWheelUp (void)
{
int pnum = CL_TargettedSplit(false);
#ifdef CSQC_DAT
if (CSQC_ConsoleCommand(pnum, Cmd_Argv(0)))
return;
#endif
if (!KeyUp(&in_wwheel))
return;
if (wwheelsel[pnum] < weaponinfo_count)
CL_QueueImpulse(pnum, weaponinfo[wwheelsel[pnum]].impulse);
}
#else
#define IN_DoPostSelect()
#define IN_DoWeaponHide()
@ -1173,7 +767,7 @@ cvar_t cl_anglespeedkey = CVAR("cl_anglespeedkey","1.5");
#define GATHERBIT(bname,bit) if (bname.state[pnum] & 3) {bits |= (1u<<(bit));} bname.state[pnum] &= ~2;
#define UNUSEDBUTTON(bnum) if (in_button[bnum].state[pnum] & 3) {Con_Printf("+button%i is not supported on this protocol\n", bnum); } in_button[bnum].state[pnum] &= ~3;
#define UNUSEDBUTTON(bnum) if (in_button[bnum].state[pnum] & 3) {Con_Printf("+button%i is not supported on this protocol\n", pnum); } in_button[bnum].state[pnum] &= ~3;
void CL_GatherButtons (usercmd_t *cmd, int pnum)
{
unsigned int bits = 0;
@ -1317,24 +911,34 @@ CL_BaseMove
Send the intended movement message to the server
================
*/
static void CL_BaseMove (vec3_t moves, int pnum)
void CL_BaseMove (usercmd_t *cmd, int pnum, float priortime, float extratime)
{
float scale;
float nscale = extratime?extratime / (extratime+priortime):0;
float oscale = 1 - nscale;
cmd->fservertime = cl.time;
cmd->servertime = cl.time*1000;
//
// adjust for speed key
//
scale = ((in_speed.state[pnum] & 1) ^ cl_run.ival)?cl_movespeedkey.value:1;
if ((in_speed.state[pnum] & 1) ^ cl_run.ival)
nscale *= cl_movespeedkey.value;
moves[0] = 0;
if (! (in_klook.state[pnum] & 1) )
{
moves[0] += scale*(cl_forwardspeed.value * CL_KeyState (&in_forward, pnum, true) -
(*cl_backspeed.string?cl_backspeed.value:cl_forwardspeed.value) * CL_KeyState (&in_back, pnum, true));
}
moves[1] = scale*cl_sidespeed.value * (CL_KeyState (&in_moveright, pnum, true) - CL_KeyState (&in_moveleft, pnum, true)) * (in_xflip.ival?-1:1);
if (in_strafe.state[pnum] & 1)
moves[1] += scale*cl_sidespeed.value * (CL_KeyState (&in_right, pnum, true) - CL_KeyState (&in_left, pnum, true)) * (in_xflip.ival?-1:1);
moves[2] = scale*cl_upspeed.value * (CL_KeyState (&in_up, pnum, true) - CL_KeyState (&in_down, pnum, true));
cmd->sidemove = cmd->sidemove*oscale + nscale*cl_sidespeed.value * (CL_KeyState (&in_right, pnum, true) - CL_KeyState (&in_left, pnum, true)) * (in_xflip.ival?-1:1);
cmd->sidemove = cmd->sidemove*oscale + nscale*cl_sidespeed.value * (CL_KeyState (&in_moveright, pnum, true) - CL_KeyState (&in_moveleft, pnum, true)) * (in_xflip.ival?-1:1);
cmd->upmove = cmd->upmove*oscale + nscale*cl_upspeed.value * (CL_KeyState (&in_up, pnum, true) - CL_KeyState (&in_down, pnum, true));
if (! (in_klook.state[pnum] & 1) )
{
cmd->forwardmove = cmd->forwardmove*oscale + nscale*(cl_forwardspeed.value * CL_KeyState (&in_forward, pnum, true) -
(*cl_backspeed.string?cl_backspeed.value:cl_forwardspeed.value) * CL_KeyState (&in_back, pnum, true));
}
if (!priortime) //only gather buttons if we've not had any this frame. this avoids jump feeling weird with prediction. FIXME: should probably still allow +attack to reduce latency
CL_GatherButtons(cmd, pnum);
}
void CL_ClampPitch (int pnum, float frametime)
@ -1611,64 +1215,6 @@ static void CL_FinishMove (usercmd_t *cmd, int pnum)
}
static void CL_AccumlateInput(int plnum, float frametime/*extra contribution*/, float framemsecs/*total accumulated*/)
{
usercmd_t *cmd = &cl_pendingcmd[plnum];
int i;
static vec3_t mousemovements[MAX_SPLITS];
vec3_t newmoves;
float nscale = framemsecs?framemsecs / (framemsecs+cmd->msec):0;
float oscale = 1 - nscale;
unsigned int st;
CL_BaseMove (newmoves, plnum);
CL_AdjustAngles (plnum, frametime);
if (!cmd->msec)
VectorClear(mousemovements[plnum]);
IN_Move (mousemovements[plnum], newmoves, plnum, frametime);
CL_ClampPitch(plnum, frametime);
for (i=0 ; i<3 ; i++)
cmd->angles[i] = ((int)(cl.playerview[plnum].viewangles[i]*65536.0/360)&65535);
cmd->fservertime = cl.servertime;
cmd->servertime = cl.time*1000;
#ifdef CSQC_DAT
cmd->fclienttime = realtime - cl.mapstarttime;
#endif
cmd->forwardmove = bound(-32768, cmd->forwardmove*oscale + newmoves[0]*nscale + mousemovements[plnum][0], 32767);
cmd->sidemove = bound(-32768, cmd->sidemove*oscale + newmoves[1]*nscale + mousemovements[plnum][1], 32767);
cmd->upmove = bound(-32768, cmd->upmove*oscale + newmoves[2]*nscale + mousemovements[plnum][2], 32767);
if (!cmd->msec && framemsecs)
{
CL_GatherButtons(cmd, plnum); //buttons are from the initial state. don't blend them.
CL_FinishMove(cmd, plnum);
Cbuf_Waited(); //its okay to stop waiting now
}
cmd->msec = framemsecs;
if (cl.movesequence >= 1)
{ //fix up the servertime value to make sure our msecs are actually correct.
st = cl.outframes[(cl.movesequence-1)&UPDATE_MASK].cmd[plnum].servertime + (cmd->msec); //round it.
if (abs((int)st-(int)cmd->servertime) < 50)
{
cmd->servertime = st;
cmd->fservertime = (double)st/1000.0;
}
}
// if we are spectator, try autocam
// if (cl.spectator)
Cam_Track(&cl.playerview[plnum], &cl_pendingcmd[plnum]);
Cam_FinishMove(&cl.playerview[plnum], &cl_pendingcmd[plnum]);
}
static qboolean CLFTE_SendVRCmd (sizebuf_t *buf, unsigned int seats)
{
//compute the delay between receiving the frame we're acking and when we're sending the new frame
@ -1776,6 +1322,29 @@ void CL_UpdatePrydonCursor(usercmd_t *from, int pnum)
from->cursor_screen[1] = 1;
}
/*
if (cl.cmd.cursor_screen[0] < -1)
{
cl.viewangles[YAW] -= m_yaw.value * (cl.cmd.cursor_screen[0] - -1) * vid.realwidth * sensitivity.value * cl.viewzoom;
cl.cmd.cursor_screen[0] = -1;
}
if (cl.cmd.cursor_screen[0] > 1)
{
cl.viewangles[YAW] -= m_yaw.value * (cl.cmd.cursor_screen[0] - 1) * vid.realwidth * sensitivity.value * cl.viewzoom;
cl.cmd.cursor_screen[0] = 1;
}
if (cl.cmd.cursor_screen[1] < -1)
{
cl.viewangles[PITCH] += m_pitch.value * (cl.cmd.cursor_screen[1] - -1) * vid.realheight * sensitivity.value * cl.viewzoom;
cl.cmd.cursor_screen[1] = -1;
}
if (cl.cmd.cursor_screen[1] > 1)
{
cl.viewangles[PITCH] += m_pitch.value * (cl.cmd.cursor_screen[1] - 1) * vid.realheight * sensitivity.value * cl.viewzoom;
cl.cmd.cursor_screen[1] = 1;
}
*/
VectorClear(from->cursor_start);
temp[0] = (from->cursor_screen[0]+1)/2;
temp[1] = (-from->cursor_screen[1]+1)/2;
@ -1816,12 +1385,6 @@ void CLNQ_SendMove (usercmd_t *cmd, int pnum, sizebuf_t *buf)
return;
}
if (cls.qex)
{
MSG_WriteByte (buf, clc_delta);
MSG_WriteULEB128(buf, cl.movesequence);
}
MSG_WriteByte (buf, clc_move);
if (cls.protocol_nq >= CPNQ_DP7)
@ -1836,9 +1399,6 @@ void CLNQ_SendMove (usercmd_t *cmd, int pnum, sizebuf_t *buf)
MSG_WriteFloat (buf, cmd->fservertime); // use latest time. because ping reports!
if (cls.qex)
MSG_WriteByte(buf, 4);
for (i=0 ; i<3 ; i++)
{
if (cls.protocol_nq == CPNQ_FITZ666 || (cls.proquake_angles_hack && buf->prim.anglesize <= 1))
@ -2026,7 +1586,7 @@ void VARGS CL_SendSeatClientCommand(qboolean reliable, unsigned int seat, char *
#ifdef Q3CLIENT
if (cls.protocol == CP_QUAKE3)
{
q3->cl.SendClientCommand("%s", string);
CLQ3_SendClientCommand("%s", string);
return;
}
#endif
@ -2511,12 +2071,15 @@ qboolean CLQW_SendCmd (sizebuf_t *buf, qboolean actuallysend)
cl.validsequence = 0;
//delta_sequence is the _expected_ previous sequences, so is set before it arrives.
if (cl.validsequence && !cl_nodelta.ival && cls.state == ca_active)// && !cls.demorecording)
if (cl.validsequence && !cl_nodelta.ival && cls.state == ca_active && !cls.demorecording)
{
cl.inframes[cls.netchan.outgoing_sequence&UPDATE_MASK].delta_sequence = cl.validsequence;
MSG_WriteByte (buf, clc_delta);
// Con_Printf("%i\n", cl.validsequence);
MSG_WriteByte (buf, cl.validsequence&255);
}
else
cl.inframes[cls.netchan.outgoing_sequence&UPDATE_MASK].delta_sequence = -1;
if (cl.sendprespawn || !actuallysend)
buf->cursize = st; //don't send movement commands while we're still supposedly downloading. mvdsv does not like that.
@ -2549,7 +2112,7 @@ static void CL_SendUserinfoUpdate(void)
if (info == &cls.userinfo[0])
{
InfoBuf_ToString(info, userinfo, sizeof(userinfo), NULL, NULL, NULL, NULL, NULL);
q3->cl.SendClientCommand("userinfo \"%s\"", userinfo);
CLQ3_SendClientCommand("userinfo \"%s\"", userinfo);
}
return;
}
@ -2671,12 +2234,37 @@ void CL_SendCmd (double frametime, qboolean mainloop)
}
for (plnum = 0; plnum < cl.splitclients; plnum++)
{
vec3_t mousemovements;
playerview_t *pv = &cl.playerview[plnum];
cmd = &cl.outframes[i].cmd[plnum];
CL_AccumlateInput(plnum, frametime, frametime*1000);
*cmd = cl_pendingcmd[plnum];
memset(&cl_pendingcmd[plnum], 0, sizeof(*cmd)); //reset the pending for the next frame.
memset(cmd, 0, sizeof(*cmd));
msecs += frametime*1000;
if (msecs > 50)
msecs = 50;
cmd->msec = msecs;
msecs -= cmd->msec;
cl_pendingcmd[plnum].msec = 0;
CL_AdjustAngles (plnum, frametime);
// get basic movement from keyboard
CL_BaseMove (cmd, plnum, 0, 1);
// allow mice or other external controllers to add to the move
VectorClear(mousemovements);
IN_Move (mousemovements, plnum, frametime);
cl_pendingcmd[plnum].forwardmove += mousemovements[0];
cl_pendingcmd[plnum].sidemove += mousemovements[1];
cl_pendingcmd[plnum].upmove += mousemovements[2];
CL_ClampPitch(plnum, frametime);
// if we are spectator, try autocam
if (pv->spectator)
Cam_Track(pv, cmd);
CL_FinishMove(cmd, plnum);
Cam_FinishMove(pv, cmd);
#ifdef CSQC_DAT
CSQC_Input_Frame(plnum, cmd);
@ -2703,7 +2291,7 @@ void CL_SendCmd (double frametime, qboolean mainloop)
cls.netchan.outgoing_sequence = cl.movesequence;
}
IN_Move (NULL, NULL, 0, frametime);
IN_Move (NULL, 0, frametime);
Cbuf_Waited(); //its okay to stop waiting now
return; // sendcmds come from the demo
@ -2816,7 +2404,32 @@ void CL_SendCmd (double frametime, qboolean mainloop)
if (!CLHL_BuildUserInput(msecstouse, &cl_pendingcmd[0]))
#endif
for (plnum = 0; plnum < (cl.splitclients?cl.splitclients:1); plnum++)
CL_AccumlateInput(plnum, frametime, framemsecs);
{
vec3_t mousemovements;
CL_AdjustAngles (plnum, frametime);
VectorClear(mousemovements);
IN_Move (mousemovements, plnum, frametime);
CL_ClampPitch(plnum, frametime);
cl_pendingcmd[plnum].forwardmove += mousemovements[0]; //FIXME: this will get nuked by CL_BaseMove.
cl_pendingcmd[plnum].sidemove += mousemovements[1];
cl_pendingcmd[plnum].upmove += mousemovements[2];
for (i=0 ; i<3 ; i++)
cl_pendingcmd[plnum].angles[i] = ((int)(cl.playerview[plnum].viewangles[i]*65536.0/360)&65535);
CL_BaseMove (&cl_pendingcmd[plnum], plnum, cl_pendingcmd[plnum].msec, framemsecs);
if (!cl_pendingcmd[plnum].msec && framemsecs)
{
CL_FinishMove(&cl_pendingcmd[plnum], plnum);
Cbuf_Waited(); //its okay to stop waiting now
}
cl_pendingcmd[plnum].msec = framemsecs;
// if we are spectator, try autocam
// if (cl.spectator)
Cam_Track(&cl.playerview[plnum], &cl_pendingcmd[plnum]);
Cam_FinishMove(&cl.playerview[plnum], &cl_pendingcmd[plnum]);
}
//the main loop isn't allowed to send
if (runningindepphys && mainloop)
@ -2941,11 +2554,7 @@ void CL_SendCmd (double frametime, qboolean mainloop)
#ifdef Q3CLIENT
case CP_QUAKE3:
msecs -= (double)msecstouse;
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;
CLQ3_SendCmd(&cl_pendingcmd[0]);
CL_ClearPendingCommands();
//don't bank too much, because that results in banking speedcheats
@ -2967,7 +2576,6 @@ void CL_SendCmd (double frametime, qboolean mainloop)
//clear enough of the pending command for the next frame.
for (plnum = 0; plnum < cl.splitclients; plnum++)
{
cl_pendingcmd[plnum].sequence = cl.movesequence;
cl_pendingcmd[plnum].msec = 0;
cl_pendingcmd[plnum].impulse = 0;
// cl_pendingcmd[plnum].buttons = 0;
@ -3170,10 +2778,6 @@ void CL_InitInput (void)
Cmd_AddCommand ("-mlook", IN_MLookUp);
#ifdef QUAKESTATS
Cmd_AddCommand ("+weaponwheel", IN_WWheelDown);
Cmd_AddCommand ("-weaponwheel", IN_WWheelUp);
Cmd_AddCommandD ("register_bestweapon", IN_RegisterWeapon_f, "Normally set via a mod's default.cfg file");
Cmd_AddCommandD ("bestweapon", IN_Impulse, "Works like 'impulse', for compat with other engines.");
Cvar_Register (&cl_weaponhide, inputnetworkcvargroup);
Cvar_Register (&cl_weaponhide_preference, inputnetworkcvargroup);
Cvar_Register (&cl_weaponpreselect, inputnetworkcvargroup);

File diff suppressed because it is too large Load Diff

View File

@ -22,18 +22,17 @@ enum masterprotocol_e
#define SS_UNKNOWN 0
#define SS_QUAKEWORLD 1
#define SS_NETQUAKE 2
#define SS_QUAKE2 3
#define SS_QUAKE3 4
#define SS_QEPROT 5 //needs dtls and a different ccreq version
#define SS_DARKPLACES 3
#define SS_QUAKE2 4
#define SS_QUAKE3 5
//#define SS_UNUSED 6
//#define SS_UNUSED 7
#define SS_LOCAL (1<<3u) //local servers are ones we detected without being listed on a master server (masters will report public ips, so these may appear as dupes if they're also public)
#define SS_FTESERVER (1<<4u) //just highlighting differences, to give some impression of superiority.
#define SS_FTESERVER (1<<4u) //hehehe...
#define SS_FAVORITE (1<<5u) //filter all others.
#define SS_KEEPINFO (1<<6u)
#define SS_GETINFO (1<<7u) //explicitly query via getinfo
#define SS_PROXY (1<<8u) //qizmo/qwfwd/qtv/eztv
#define SS_PROXY (1<<7u)
#define PING_DEAD 0xffff //default ping value to denote servers that are not responding.
#define PING_UNKNOWN 0xfffe //these servers are considered up, but we can't query them directly so can't determine the final ping from here.
@ -225,7 +224,7 @@ extern qboolean sb_favouriteschanged;
void Master_SetupSockets(void);
qboolean CL_QueryServers(void);
void Master_CheckPollSockets(void);
int Master_CheckPollSockets(void);
void MasterInfo_Shutdown(void);
void MasterInfo_WriteServers(void);
serverinfo_t *Master_InfoForServer (netadr_t *addr, const char *brokerid);
@ -240,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, unsigned int keynum);
char *Master_ReadKeyString(serverinfo_t *server, unsigned int keynum);
float Master_ReadKeyFloat(serverinfo_t *server, hostcachekey_t keynum);
char *Master_ReadKeyString(serverinfo_t *server, hostcachekey_t keynum);
int Master_SortServers(void);
void Master_SetSortField(hostcachekey_t field, qboolean descending);

File diff suppressed because it is too large Load Diff

View File

@ -98,42 +98,6 @@ void QDECL Plug_Key_SetKeyBind(int bindmap, int keycode, int modifier, const cha
Key_SetBinding (keycode, modifier, newbinding, RESTRICT_LOCAL);
}
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();
}
void QDECL Plug_Input_SetSensitivityScale(float scale)
{
in_sensitivityscale = scale;
}
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)
@ -145,37 +109,112 @@ 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 qboolean Plug_Draw_GetScreenSize(float *vsize, unsigned int *psize)
static void Plug_Draw_UnloadImage(qhandle_t image)
{
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;
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;
}
}
}
static qhandle_t Plug_Draw_LoadImage(const char *name, int type, const char *script)
{
shader_t *pic;
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.
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;
if (pic)
return pic->id+1;
return 0;
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;
}
static qhandle_t QDECL Plug_Draw_LoadImageData(const char *name, const char *mimetype, void *codeddata, size_t datalength)
@ -188,6 +227,8 @@ 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);
@ -205,54 +246,93 @@ 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)
static qhandle_t QDECL Plug_Draw_LoadImagePic(const char *name, qboolean type)
{
return Plug_Draw_LoadImage(name, 0, NULL);
}
static shader_t *Plug_Draw_ShaderFromId(qhandle_t id)
{
if (--id >= r_numshaders)
return NULL;
return r_shaders[id];
}
static void Plug_Draw_UnloadImage(qhandle_t id)
{
R_UnloadShader(Plug_Draw_ShaderFromId(id));
if (type != 0 && type != 1)
return 0;
return Plug_Draw_LoadImage(name, type, NULL);
}
void Plug_DrawReloadImages(void)
{
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;
}
}
//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;
if (image > 0 && image <= r_numshaders)
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
{
ret = R_GetShaderSizes(r_shaders[image-1], &iw, &ih, true);
if (w)
*w = iw;
if (h)
*h = ih;
return ret;
pic = R2D_SafeCachePic(pluginimagearray[i].name);
if (!pic)
return -1;
}
return -1;
ret = R_GetShaderSizes(pic, &iw, &ih, true);
*w = iw;
*h = ih;
return ret;
}
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)
{
if (image > 0 && image <= r_numshaders)
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
{
R2D_Image(x, y, w, h, s1, t1, s2, t2, r_shaders[image-1]);
return 1;
pic = R2D_SafeCachePic(pluginimagearray[i].name);
if (!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;
R2D_Image(x, y, w, h, s1, t1, s2, t2, pic);
return 1;
}
//x1,y1,x2,y2
static void QDECL Plug_Draw_Line(float x1, float y1, float x2, float y2)
@ -369,169 +449,13 @@ 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();
}
#ifdef HAVE_MEDIA_DECODER
static void QDECL Plug_Media_SetState(cin_t *cin, int state)
{
Media_SetState(cin, state);
}
static int QDECL Plug_Media_GetState(cin_t *cin)
{
return Media_GetState(cin);
}
#endif
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);
VectorSet(r_refdef.weaponmatrix[0], 1,0,0);
VectorSet(r_refdef.weaponmatrix[1], 0,1,0);
VectorSet(r_refdef.weaponmatrix[2], 0,0,1);
VectorSet(r_refdef.weaponmatrix[3], 0,0,0);
VectorSet(r_refdef.weaponmatrix_bob[0], 1,0,0);
VectorSet(r_refdef.weaponmatrix_bob[1], 0,1,0);
VectorSet(r_refdef.weaponmatrix_bob[2], 0,0,1);
VectorSet(r_refdef.weaponmatrix_bob[3], 0,0,0);
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)
{
@ -540,13 +464,6 @@ static void QDECL Plug_LocalSound(const char *soundname, int channel, float volu
}
static void QDECL Plug_CL_SetLoadscreenState(qboolean state)
{
if (state)
SCR_BeginLoadingPlaque();
else
SCR_EndLoadingPlaque();
}
static int QDECL Plug_CL_GetStats(int pnum, unsigned int *stats, int maxstats)
{
@ -627,7 +544,7 @@ static size_t QDECL Plug_GetLocalPlayerNumbers(size_t first, size_t count, int *
return count;
}
static void QDECL Plug_GetServerInfoRaw(char *outptr, size_t outlen)
static void QDECL Plug_GetServerInfo(char *outptr, size_t outlen)
{
extern float demtime;
@ -664,107 +581,11 @@ static void QDECL Plug_GetServerInfoRaw(char *outptr, size_t outlen)
#endif
Q_strncatz(outptr, va("\\matchstart\\%f", cl.matchgametimestart), outlen);
}
static size_t QDECL Plug_GetServerInfoBlob(const char *key, void *outptr, size_t outsize)
{
char tmp[32];
size_t blobsize;
const char *blob = InfoBuf_BlobForKey(&cl.serverinfo, key, &blobsize, NULL);
if (!blob)
{ //inescapable hacks
if (!strcmp(key, "matchstart"))
{
float matchstart = cl.matchgametimestart;
#ifdef QUAKEHUD
if (cl.playerview[0].statsf[STAT_MATCHSTARTTIME])
matchstart = cl.playerview[0].statsf[STAT_MATCHSTARTTIME]/1000;
#endif
snprintf(tmp, sizeof(tmp), "%f", matchstart), blob=tmp;
}
else if (!strcmp(key, "demotime"))
{
extern float demtime;
snprintf(tmp, sizeof(tmp), "%f", demtime-cls.demostarttime), blob=tmp;
}
else if (!strcmp(key, "demotype"))
{
switch(cls.demoplayback)
{
case DPB_NONE:
break;
case DPB_MVD:
case DPB_EZTV:
blob = "mvd";
break;
case DPB_QUAKEWORLD:
blob = "qw";
break;
#ifdef NQPROT
case DPB_NETQUAKE:
blob = "nq";
break;
#endif
#ifdef Q2CLIENT
case DPB_QUAKE2:
blob = "q2";
break;
#endif
}
}
else if (!strcmp(key, "intermission"))
snprintf(tmp, sizeof(tmp), "%i", cl.intermissionmode), blob=tmp;
if (blob)
blobsize = strlen(blob);
}
if (outptr)
{
if (blobsize > outsize)
return 0; //error
memcpy(outptr, blob, blobsize);
return blobsize;
}
else
return blobsize;
}
static void QDECL Plug_SetUserInfo(int seat, const char *key, const char *value)
{
CL_SetInfo(seat, key, value);
}
static void QDECL Plug_SetUserInfoBlob(int seat, const char *key, const void *value, size_t size)
{
CL_SetInfoBlob(seat, key, value, size);
}
static size_t QDECL Plug_GetUserInfoBlob(int seat, const char *key, void *outptr, size_t outsize)
{
size_t blobsize;
const char *blob;
if (seat >= countof(cls.userinfo))
blob = NULL, blobsize = 0;
else
blob = InfoBuf_BlobForKey(&cls.userinfo[seat], key, &blobsize, NULL);
if (outptr)
{
if (blobsize > outsize)
return 0; //error
memcpy(outptr, blob, blobsize);
return blobsize;
}
else
return blobsize;
}
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)
{
@ -1230,27 +1051,11 @@ 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);
@ -1262,6 +1067,13 @@ static void Plug_Client_Close(plugin_t *plug)
}
}
static void Plug_Client_Shutdown(void)
{
BZ_Free(pluginimagearray);
pluginimagearray = NULL;
pluginimagearraylen = 0;
}

View File

@ -198,9 +198,8 @@ int VARGS CLQ2_PMpointcontents (vec3_t point)
int num;
model_t *cmodel;
int contents;
vec3_t axis[3], relpos;
contents = cl.worldmodel->funcs.PointContents(cl.worldmodel, NULL, point);
contents = CM_PointContents (cl.worldmodel, point);
for (i=0 ; i<cl.q2frame.num_entities ; i++)
{
@ -214,10 +213,7 @@ int VARGS CLQ2_PMpointcontents (vec3_t point)
if (!cmodel)
continue;
AngleVectors (ent->angles, axis[0], axis[1], axis[2]);
VectorNegate(axis[1], axis[1]);
VectorSubtract(point, ent->origin, relpos);
contents |= cmodel->funcs.PointContents(cmodel, axis, relpos);
contents |= CM_TransformedPointContents (cl.worldmodel, point, cmodel->hulls[0].firstclipnode, ent->origin, ent->angles);
}
return contents;
@ -231,24 +227,14 @@ CL_PredictMovement
Sets cl.predicted_origin and cl.predicted_angles
=================
*/
static void CLQ2_UserCmdToQ2(q2usercmd_t *out, const usercmd_t *cmd)
{
out->msec = cmd->msec;
out->buttons = cmd->buttons;
VectorCopy(cmd->angles, out->angles);
out->forwardmove = cmd->forwardmove;
out->sidemove = cmd->sidemove;
out->upmove = cmd->upmove;
out->impulse = cmd->impulse;
out->lightlevel = cmd->lightlevel;
}
static void CLQ2_PredictMovement (int seat) //q2 doesn't support split clients.
{
#ifdef Q2BSPS
int ack, current;
int frame;
int oldframe;
q2pmove_t pm;
q2usercmd_t *cmd;
q2pmove_t pm;
int step;
int oldz;
#endif
@ -303,7 +289,10 @@ static void CLQ2_PredictMovement (int seat) //q2 doesn't support split clients.
while (++ack < current)
{
frame = ack & (UPDATE_MASK);
CLQ2_UserCmdToQ2(&pm.cmd, &cl.outframes[frame].cmd[seat]);
cmd = (q2usercmd_t*)&cl.outframes[frame].cmd[seat];
cmd->msec = cl.outframes[frame].cmd[seat].msec;
pm.cmd = *cmd;
Q2_Pmove (&pm);
// save for debug checking
@ -312,7 +301,10 @@ static void CLQ2_PredictMovement (int seat) //q2 doesn't support split clients.
if (cl_pendingcmd[seat].msec)
{
CLQ2_UserCmdToQ2(&pm.cmd, &cl_pendingcmd[seat]);
cmd = (q2usercmd_t*)&cl_pendingcmd[seat];
cmd->msec = cl_pendingcmd[seat].msec;
pm.cmd = *cmd;
Q2_Pmove (&pm);
}

View File

@ -403,13 +403,8 @@ for a few moments
*/
void SCR_CenterPrint (int pnum, const char *str, qboolean skipgamecode)
{
unsigned int pfl = 0;
size_t i;
cprint_t *p;
#ifdef HAVE_LEGACY
if (scr_usekfont.ival)
pfl |= PFS_FORCEUTF8;
#endif
if (!str)
{
if (cl.intermissionmode == IM_NONE)
@ -490,14 +485,7 @@ void SCR_CenterPrint (int pnum, const char *str, qboolean skipgamecode)
else if (str[1] == 'F')
{ //'F' is reserved for special handling via svc_finale
if (cl.intermissionmode == IM_NONE)
{
TP_ExecTrigger ("f_mapend", false);
if (cl.playerview[pnum].spectator || cls.demoplayback)
TP_ExecTrigger ("f_specmapend", true);
else
TP_ExecTrigger ("f_playmapend", true);
cl.completed_time = cl.time;
}
str+=2;
switch(*str++)
{
@ -557,7 +545,7 @@ void SCR_CenterPrint (int pnum, const char *str, qboolean skipgamecode)
for (;;)
{
p->charcount = COM_ParseFunString(CON_WHITEMASK, str, p->string, p->stringbytes, pfl) - p->string;
p->charcount = COM_ParseFunString(CON_WHITEMASK, str, p->string, p->stringbytes, false) - p->string;
if ((p->charcount+1)*sizeof(*p->string) < p->stringbytes)
break;
@ -583,7 +571,6 @@ void SCR_CenterPrint (int pnum, const char *str, qboolean skipgamecode)
p->time_off = scr_centertime.value;
p->time_start = cl.time;
VRUI_SnapAngle();
}
void VARGS Stats_Message(char *msg, ...)
@ -897,13 +884,6 @@ void SCR_CheckDrawCenterString (void)
p = &scr_centerprint[pnum];
p->cursorchar = NULL;
#ifdef QUAKESTATS
if (IN_DrawWeaponWheel(pnum))
{ //we won't draw the cprint, but it also won't fade while the wwheel is shown.
continue;
}
#endif
if (p->time_off <= 0 && !(p->flags & CPRINT_PERSIST))
continue; //'/P' prefix doesn't time out
@ -1011,9 +991,6 @@ void SCR_DrawCursor(void)
}
}
if (vrui.enabled && kcurs->handle)
kcurs->dirty = true;
if (kcurs->dirty)
{
if (kcurs->scale <= 0 || !*kcurs->name)
@ -1025,7 +1002,7 @@ void SCR_DrawCursor(void)
kcurs->dirty = false;
oldcurs = kcurs->handle;
if (rf->VID_CreateCursor && !vrui.enabled && strcmp(kcurs->name, "none"))
if (rf->VID_CreateCursor && strcmp(kcurs->name, "none"))
{
image_t dummytex;
flocation_t loc;
@ -2307,7 +2284,7 @@ void SCR_SetUpToDrawConsole (void)
scr_con_target = 0; // not looking at an normal console
}
#ifdef VM_UI
else if (q3 && q3->ui.OpenMenu())
else if (UI_OpenMenu())
scr_con_current = scr_con_target = 0; //force instantly hidden.
#endif
else
@ -2392,10 +2369,7 @@ void SCR_DrawConsole (qboolean noback)
if (!Key_Dest_Has(kdm_console|kdm_menu))
Con_DrawNotify (); // only draw notify in game
}
if (vrui.enabled) //make the console all-or-nothing when its a vr ui.
Con_DrawConsole (scr_con_target?vid.height:0, noback);
else
Con_DrawConsole (scr_con_current, noback);
Con_DrawConsole (scr_con_current, noback);
if (scr_con_current || Key_Dest_Has(kdm_cwindows))
clearconsole = 0;
}
@ -2513,7 +2487,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 && q3 && q3->cg.Redraw(cl.time))
if (!okay && CG_Refresh())
okay = true;
#endif
#ifdef CSQC_DAT
@ -2921,8 +2895,8 @@ void SCR_ScreenShot_Cubemap_f(void)
bb=0;
for (i = 0; i < 6; i++)
{
VectorCopy(sides[i].angle, cl.playerview->aimangles);
VectorCopy(cl.playerview->aimangles, cl.playerview->viewangles);
VectorCopy(sides[i].angle, cl.playerview->simangles);
VectorCopy(cl.playerview->simangles, cl.playerview->viewangles);
//don't use hdr when saving dds files. it generally means dx10 dds files and most tools suck too much and then I get blamed for writing 'corrupt' dds files.
facedata = SCR_ScreenShot_Capture(fbwidth, fbheight, &stride, &fmt, true, !!strcmp(ext, ".dds"));
@ -3006,8 +2980,8 @@ void SCR_ScreenShot_Cubemap_f(void)
{
for (i = firstside; i < firstside+6; i++)
{
VectorCopy(sides[i].angle, cl.playerview->aimangles);
VectorCopy(cl.playerview->aimangles, cl.playerview->viewangles);
VectorCopy(sides[i].angle, cl.playerview->simangles);
VectorCopy(cl.playerview->simangles, cl.playerview->viewangles);
buffer = SCR_ScreenShot_Capture(fbwidth, fbheight, &stride, &fmt, true, false);
if (buffer)
@ -3312,6 +3286,8 @@ void SCR_DrawTwoDimensional(qboolean nohud)
qboolean consolefocused = !!Key_Dest_Has(kdm_console|kdm_cwindows);
RSpeedMark();
r_refdef.playerview = &cl.playerview[0];
R2D_ImageColours(1, 1, 1, 1);
//

View File

@ -208,8 +208,8 @@ struct beam_s {
vec3_t start, end;
vec3_t offset; //when attached, this is the offset from the owning entity. probably only z is meaningful.
// int particlecolour; //some effects have specific colours. which is weird.
trailkey_t trailstate;
trailkey_t emitstate;
trailstate_t *trailstate;
trailstate_t *emitstate;
};
beam_t *cl_beams;
@ -237,7 +237,7 @@ typedef struct
model_t *model;
int skinnum;
int traileffect;
trailkey_t trailstate;
trailstate_t *trailstate;
} explosion_t;
static explosion_t *cl_explosions;
@ -1065,8 +1065,8 @@ void CL_ParseStream (int type)
P_DelinkTrailstate(&b2->trailstate);
P_DelinkTrailstate(&b2->emitstate);
memcpy(b2, b, sizeof(*b2));
b2->trailstate = trailkey_null;
b2->emitstate = trailkey_null;
b2->trailstate = NULL;
b2->emitstate = NULL;
b2->alpha = 0.5;
b2->rflags = RF_TRANSLUCENT|RF_NOSHADOW;
}
@ -1924,7 +1924,7 @@ void CL_ParseTEnt (void)
void CL_ParseTEnt_Sized (void)
{
unsigned short sz = MSG_ReadShort();
int start = MSG_GetReadCount();
int start = msg_readcount;
for(;;)
{
@ -1940,24 +1940,25 @@ void CL_ParseTEnt_Sized (void)
CL_ParseTEnt();
#endif
if (MSG_GetReadCount() < start + sz)
if (msg_readcount < start + sz)
{ //try to be more compatible with xonotic.
int next = MSG_ReadByte();
if (next == svc_temp_entity)
continue;
msg_readcount--;
Con_Printf("Sized temp_entity data too large (next byte %i, %i bytes unread)\n", next, (start+sz)-MSG_GetReadCount()-1);
MSG_ReadSkip(start+sz-MSG_GetReadCount());
Con_Printf("Sized temp_entity data too large (next byte %i, %i bytes unread)\n", next, (start+sz)-msg_readcount);
msg_readcount = start + sz;
return;
}
break;
}
if (MSG_GetReadCount() != start + sz)
if (msg_readcount != start + sz)
{
Con_Printf("Tempentity size did not match parsed size misread a gamecode packet (%i bytes too much)\n", MSG_GetReadCount() - (start+sz));
MSG_ReadSkip(start+sz-MSG_GetReadCount());
Con_Printf("Tempentity size did not match parsed size misread a gamecode packet (%i bytes too much)\n", msg_readcount - (start+sz));
msg_readcount = start + sz;
}
}
@ -2325,7 +2326,7 @@ void CL_ParseTrailParticles(void)
int entityindex;
int effectindex;
vec3_t start, end;
trailkey_t *tk;
trailstate_t **ts;
entityindex = MSGCL_ReadEntity();
effectindex = (unsigned short)MSG_ReadShort();
@ -2340,12 +2341,12 @@ void CL_ParseTrailParticles(void)
effectindex = CL_TranslateParticleFromServer(effectindex);
if (entityindex>0 && (unsigned int)entityindex < cl.maxlerpents)
tk = &cl.lerpents[entityindex].trailstate;
ts = &cl.lerpents[entityindex].trailstate;
else
tk = NULL;
ts = NULL;
if (P_ParticleTrail(start, end, effectindex, 1, entityindex, NULL, tk))
P_ParticleTrail(start, end, rt_blood, 1, entityindex, NULL, tk);
if (P_ParticleTrail(start, end, effectindex, 1, entityindex, NULL, ts))
P_ParticleTrail(start, end, rt_blood, 1, entityindex, NULL, ts);
}
void CL_ParsePointParticles(qboolean compact)

File diff suppressed because it is too large Load Diff

View File

@ -248,6 +248,9 @@ typedef struct
typedef struct
{
//this is the sequence we requested for this frame.
int delta_sequence; // sequence number to delta from, -1 = full update
// received from server
int frameid; //the sequence number of the frame, so we can easily detect which frames are valid without poking all in advance, etc
int ackframe; //the outgoing sequence this frame acked (for prediction backlerping).
@ -328,7 +331,6 @@ typedef struct dlight_s
#endif
float corona;
float coronascale;
float fade[2];
unsigned int flags;
char cubemapname[MAX_QPATH];
@ -471,9 +473,6 @@ typedef struct
#define CPNQ_IS_DP (cls.protocol_nq >= CPNQ_DP5)
#define CPNQ_IS_BJP (cls.protocol_nq >= CPNQ_BJP1 && cls.protocol_nq <= CPNQ_BJP3)
qboolean proquake_angles_hack; //angles are always 16bit
#ifdef NQPROT
qboolean qex; //we're connected to a QuakeEx server, which means lots of special workarounds that are not controlled via the actual protocol version.
#endif
int protocol_q2;
@ -576,7 +575,6 @@ typedef struct downloadlist_s {
#define DLLF_BEGUN (1u<<8) //server has confirmed that the file exists, is readable, and we've opened a file. should not be set on new requests.
#define DLLF_ALLOWWEB (1u<<9) //failed http downloads should retry but from the game server itself
#define DLLF_TRYWEB (1u<<10) //should be trying to download it from a website...
enum dlfailreason_e failreason;
struct downloadlist_s *next;
@ -585,8 +583,8 @@ typedef struct downloadlist_s {
typedef struct {
//current persistant state
trailkey_t trailstate; //when to next throw out a trail
trailkey_t emitstate; //when to next emit
trailstate_t *trailstate; //when to next throw out a trail
trailstate_t *emitstate; //when to next emit
//current origin
vec3_t origin; //current render position
@ -755,6 +753,8 @@ struct playerview_s
vec4_t screentint;
vec4_t bordertint; //won't contain v_cshift values, only powerup+contents+damage+bf flashes
vec3_t vw_axis[3]; //weapons should be positioned relative to this
vec3_t vw_origin; //weapons should be positioned relative to this
// entity_t viewent; // is this not utterly redundant yet?
struct
{
@ -852,7 +852,6 @@ typedef struct
// is rendering at. always <= realtime
double lasttime; //cl.time from last frame.
double lastlinktime; //cl.time from last frame.
double mapstarttime; //for computing csqc's cltime.
float servertime; //current server time, bound between gametime and gametimemark
float mtime; //server time as on the server when we last received a packet. not allowed to decrease.
@ -914,6 +913,7 @@ 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.
@ -1083,7 +1083,7 @@ typedef struct
{
entity_t ent;
entity_state_t state;
trailkey_t emit;
trailstate_t *emit;
int mdlidx; /*negative are csqc indexes*/
} static_entity_t;
@ -1111,9 +1111,8 @@ extern qboolean nomaster;
//
void CL_InitDlights(void);
void CL_FreeDlights(void);
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_AllocDlight (int key);
dlight_t *CL_AllocSlight (void); //allocates a 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
@ -1143,6 +1142,7 @@ void CL_SaveInfo(vfsfile_t *f);
void CL_SetInfo (int pnum, const char *key, const char *value);
void CL_SetInfoBlob (int pnum, const char *key, const char *value, size_t valuesize);
void CL_BeginServerConnect(const char *host, int port, qboolean noproxy);
char *CL_TryingToConnect(void);
void CL_ExecInitialConfigs(char *defaultexec);
@ -1191,7 +1191,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, qboolean bsponly);
entity_t *TraceLineR (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal);
//
// cl_input
@ -1215,8 +1215,6 @@ void CL_UpdateWindowTitle(void);
#ifdef QUAKESTATS
const char *IN_GetPreselectedViewmodelName(unsigned int pnum);
qboolean IN_WeaponWheelAccumulate(int pnum, float x, float y);
qboolean IN_DrawWeaponWheel(int pnum);
#endif
void CL_InitInput (void);
void CL_SendCmd (double frametime, qboolean mainloop);
@ -1263,12 +1261,12 @@ void CL_ReadPacket(void);
int CL_ReadFromServer (void);
void CL_WriteToServer (usercmd_t *cmd);
void CL_BaseMove (usercmd_t *cmd, int pnum, float priortime, float extratime);
int Master_FindBestRoute(char *server, char *out, size_t outsize, int *directcost, int *chainedcost);
float CL_KeyState (kbutton_t *key, int pnum, qboolean noslowstart);
const char *Key_KeynumToString (int keynum, int modifier);
const char *Key_KeynumToLocalString (int keynum, int modifier);
int Key_StringToKeynum (const char *str, int *modifier);
const char *Key_GetBinding(int keynum, int bindmap, int modifier);
void Key_GetBindMap(int *bindmaps);
@ -1443,6 +1441,25 @@ 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
//
@ -1689,13 +1706,12 @@ void CL_AddVWeapModel(entity_t *player, struct model_s *model);
typedef struct cin_s cin_t;
#ifdef HAVE_MEDIA_DECODER
#ifdef Q2CLIENT /*q2 cinematics*/
/*q2 cinematics*/
struct cinematics_s;
void CIN_StopCinematic (struct cinematics_s *cin);
struct cinematics_s *CIN_PlayCinematic (char *arg);
int CIN_RunCinematic (struct cinematics_s *cin, float playbacktime, qbyte **outdata, int *outwidth, int *outheight, qbyte **outpalette);
void CIN_Rewind(struct cinematics_s *cin);
#endif
typedef enum
{

View File

@ -1,5 +1,5 @@
#include "quakedef.h"
#if defined(HAVE_MEDIA_DECODER) && defined(Q2CLIENT)
#ifdef HAVE_MEDIA_DECODER
typedef struct
{

View File

@ -89,8 +89,8 @@ typedef struct q2centity_s
int serverframe; // if not current, this ent isn't in the frame
trailkey_t trailstate;
trailkey_t emitstate;
trailstate_t *trailstate;
trailstate_t *emitstate;
// float trailcount; // for diminishing grenade trails
vec3_t lerp_origin; // for trails (variable hz)
@ -1166,7 +1166,7 @@ static void CLQ2_ParsePacketEntities (q2frame_t *oldframe, q2frame_t *newframe)
if (newnum >= MAX_Q2EDICTS)
Host_EndGame ("CL_ParsePacketEntities: bad number:%i", newnum);
if (MSG_GetReadCount() > net_message.cursize)
if (msg_readcount > net_message.cursize)
Host_EndGame ("CL_ParsePacketEntities: end of message");
if (!newnum)
@ -1483,7 +1483,7 @@ void CLR1Q2_ParsePlayerUpdate(void)
st = &clq2_parse_entities[(frame->parse_entities+pnum) & (MAX_PARSE_ENTITIES-1)];
//I don't like how r1q2 does its maxclients, so I'm just going to go on message size instead
if (MSG_GetReadCount() == net_message.cursize)
if (msg_readcount == net_message.cursize)
break;
//the local client(s) is not included, thanks to prediction covering that.
@ -1503,11 +1503,11 @@ void CLR1Q2_ParsePlayerUpdate(void)
}
//just for sanity's sake
if (MSG_GetReadCount() != net_message.cursize)
if (msg_readcount != net_message.cursize)
msg_badread = true;
}
//this should be the only/last thing in these packets, because if it isn't then we're screwed when a packet got lost
net_message.currentbit = net_message.cursize<<3;
msg_readcount = net_message.cursize;
}
/*
@ -2062,7 +2062,7 @@ static void CLQ2_AddPacketEntities (q2frame_t *frame)
ent.shaderRGBAf[1] = 0;
ent.shaderRGBAf[2] = 0;
//bypasses world lighting
ent.light_known = true;
ent.light_type = ELT_LAMBERT;
VectorSet(ent.light_avg, 1, 1, 1);
VectorSet(ent.light_range, 0, 0, 0);
//(yes, its a bit shit. not even a post-process thing)
@ -2070,7 +2070,7 @@ static void CLQ2_AddPacketEntities (q2frame_t *frame)
// add to refresh list
V_AddEntity (&ent);
ent.light_known = false;
ent.light_type = ELT_UNKNOWN;
ent.customskin = 0;
@ -2179,7 +2179,7 @@ static void CLQ2_AddPacketEntities (q2frame_t *frame)
else
*/ // pmm
V_AddEntity (&ent);
V_AddEntity (&ent);
}
if (s1->u.q2.modelindex3)
{
@ -2395,10 +2395,9 @@ static void CLQ2_AddViewWeapon (int seat, q2player_state_t *ps, q2player_state_t
return;
//generate root matrix..
VectorCopy(pv->simorg, r_refdef.weaponmatrix[3]);
AngleVectors(pv->simangles, r_refdef.weaponmatrix[0], r_refdef.weaponmatrix[1], r_refdef.weaponmatrix[2]);
VectorInverse(r_refdef.weaponmatrix[1]);
memcpy(r_refdef.weaponmatrix_bob, r_refdef.weaponmatrix, sizeof(r_refdef.weaponmatrix_bob));
VectorCopy(pv->simorg, pv->vw_origin);
AngleVectors(pv->simangles, pv->vw_axis[0], pv->vw_axis[1], pv->vw_axis[2]);
VectorInverse(pv->vw_axis[1]);
pv->vm.oldmodel = cl.model_precache[ps->gunindex];
if (!pv->vm.oldmodel)

View File

@ -1,24 +1,18 @@
#include "q3common.h"
#include "quakedef.h"
#include "shader.h"
#include "glquake.h"
#include "shader.h"
#include "cl_master.h"
//urm, yeah, this is more than just parse.
#ifdef Q3CLIENT
#include "clq3defs.h"
#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);
#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);
void MSG_WriteBits(sizebuf_t *msg, int value, int bits);
static qboolean CLQ3_Netchan_Process(sizebuf_t *msg);
ClientConnectionState_t ccs;
@ -32,7 +26,7 @@ qboolean CG_FillQ3Snapshot(int snapnum, snapshot_t *snapshot)
if (snapnum > ccs.serverMessageNum)
{
plugfuncs->EndGame("CG_FillQ3Snapshot: snapshotNumber > cl.snap.serverMessageNum");
Host_EndGame("CG_FillQ3Snapshot: snapshotNumber > cl.snap.serverMessageNum");
}
if (ccs.serverMessageNum - snapnum >= Q3UPDATE_BACKUP)
@ -76,10 +70,10 @@ void CLQ3_ParseServerCommand(void)
int number;
char *string;
number = msgfuncs->ReadLong();
// SHOWNET(va("%i", number));
number = MSG_ReadLong();
SHOWNET(va("%i", number));
string = msgfuncs->ReadString();
string = MSG_ReadString();
SHOWSTRING(string);
if( number <= ccs.lastServerCommandNum )
@ -164,11 +158,16 @@ static void CLQ3_ParsePacketEntities( clientSnap_t *oldframe, clientSnap_t *newf
while( 1 )
{
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);
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");
}
// end of packetentities
if( newnum == ENTITYNUM_NONE )
@ -253,23 +252,26 @@ 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 = msgfuncs->ReadLong();
snap.serverTime = MSG_ReadLong();
//so we can delta to it properly.
clientfuncs->UpdateGameTime(snap.serverTime / 1000.0f);
cl.oldgametime = cl.gametime;
cl.oldgametimemark = cl.gametimemark;
cl.gametime = snap.serverTime / 1000.0f;
cl.gametimemark = Sys_DoubleTime();
// 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 = msgfuncs->ReadByte();
delta = MSG_ReadByte();
if(delta)
{
snap.deltaFrame = ccs.serverMessageNum - delta;
@ -304,11 +306,11 @@ void CLQ3_ParseSnapshot(void)
}
// read snapFlags
snap.snapFlags = msgfuncs->ReadByte();
snap.snapFlags = MSG_ReadByte();
// read areabits
len = msgfuncs->ReadByte();
msgfuncs->ReadData(snap.areabits, len );
len = MSG_ReadByte();
MSG_ReadData(snap.areabits, len );
// read playerinfo
SHOWSTRING("playerstate");
@ -328,15 +330,15 @@ void CLQ3_ParseSnapshot(void)
// Find last usercmd server has processed and calculate snap.ping
snap.ping = 3;
/* for (i=ccs.netchan.outgoing_sequence-1 ; i>ccs.netchan.outgoing_sequence-Q3CMD_BACKUP ; i--)
for (i=cls.netchan.outgoing_sequence-1 ; i>cls.netchan.outgoing_sequence-Q3CMD_BACKUP ; i--)
{
frame = &cl.outframes[i & Q3CMD_MASK];
if (frame->server_message_num == snap.deltaFrame)
{
snap.ping = plugfuncs->GetMilliseconds() - frame->client_time;
snap.ping = Sys_Milliseconds() - frame->client_time;
break;
}
}*/
}
memcpy(&ccs.snap, &snap, sizeof(snap));
memcpy(&ccs.snapshots[ccs.serverMessageNum & Q3UPDATE_MASK], &snap, sizeof(snap));
@ -347,37 +349,37 @@ void CLQ3_ParseSnapshot(void)
#define MAXCHUNKSIZE 65536
void CLQ3_ParseDownload(void)
{
qdownload_t *dl = ccs.download;
qdownload_t *dl = cls.download;
unsigned int chunknum;
unsigned int chunksize;
unsigned char chunkdata[MAXCHUNKSIZE];
int i;
char *s;
chunknum = (unsigned short) msgfuncs->ReadShort();
chunknum = (unsigned short) MSG_ReadShort();
chunknum |= ccs.downloadchunknum&~0xffff; //add the chunk number, truncated by the network protocol.
if (!chunknum)
{
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.
dl->size = (unsigned int)MSG_ReadLong();
Cvar_SetValue( Cvar_Get("cl_downloadSize", "0", 0, "Download stuff"), dl->size );
}
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 = msgfuncs->ReadString();
clientfuncs->DownloadFailed(dl->remotename, dl, DLFAIL_SERVERCVAR);
plugfuncs->EndGame("%s", s);
s = MSG_ReadString();
CL_DownloadFailed(dl->remotename, dl, DLFAIL_SERVERCVAR);
Host_EndGame("%s", s);
return;
}
chunksize = (unsigned short)msgfuncs->ReadShort();
chunksize = (unsigned short)MSG_ReadShort();
if (chunksize > MAXCHUNKSIZE)
plugfuncs->EndGame("Server sent a download chunk of size %i (it's too damn big!)\n", chunksize);
Host_EndGame("Server sent a download chunk of size %i (it's too damn big!)\n", chunksize);
for (i = 0; i < chunksize; i++)
chunkdata[i] = msgfuncs->ReadByte();
chunkdata[i] = MSG_ReadByte();
if (ccs.downloadchunknum != chunknum) //the q3 client is rather lame.
{ //ccs.downloadchunknum holds the chunk number.
@ -395,9 +397,9 @@ void CLQ3_ParseDownload(void)
if (!dl->file)
{
if (!clientfuncs->DownloadBegun(dl))
if (!DL_Begun(dl))
{
clientfuncs->DownloadFailed(dl->remotename, dl, DLFAIL_CLIENTFILE);
CL_DownloadFailed(dl->remotename, dl, DLFAIL_CLIENTFILE);
return;
}
}
@ -406,9 +408,11 @@ void CLQ3_ParseDownload(void)
if (!chunksize)
{
clientfuncs->DownloadFinished(dl);
CL_DownloadFinished(dl);
ccs.servercount = -1; //make sure the server resends us that vital gamestate.
FS_ReloadPackFiles();
cl.servercount = -1; //make sure the server resends us that vital gamestate.
ccs.downloadchunknum = -1;
return;
}
@ -433,45 +437,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;
rc = cmdfuncs->ParseToken(rc, crc, sizeof(crc), NULL);
rn = cmdfuncs->ParseToken(rn, filename, sizeof(filename), NULL);
if (!*filename)
extern cvar_t cl_downloads;
rc = COM_ParseOut(rc, crc, sizeof(crc));
rn = COM_Parse(rn);
if (!*com_token)
break;
if (!strchr(filename, '/')) //don't let some muppet tell us to download quake3.exe
if (!strchr(com_token, '/')) //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 = fsfuncs->OpenVFS(va("%s.pk3", filename), "rb", FS_ROOT);
f = FS_OpenVFS(va("%s.pk3", com_token), "rb", FS_ROOT);
if (f)
{
VFS_CLOSE(f);
continue;
}
if (!fsfuncs->GenCachedPakName(va("%s.pk3", filename), crc, localname, sizeof(localname)))
if (!FS_GenCachedPakName(va("%s.pk3", com_token), crc, localname, sizeof(localname)))
continue;
f = fsfuncs->OpenVFS(localname, "rb", FS_ROOT);
f = FS_OpenVFS(localname, "rb", FS_ROOT);
if (f)
{
VFS_CLOSE(f);
continue;
}
if (!fsfuncs->GenCachedPakName(va("%s.tmp", filename), crc, tempname, sizeof(tempname)))
if (!FS_GenCachedPakName(va("%s.tmp", com_token), crc, tempname, sizeof(tempname)))
continue;
if (!cvarfuncs->GetFloat("cl_downloads"))
if (!cl_downloads.ival)
{
Con_Printf(CON_WARNING "Need to download %s.pk3, but downloads are disabled\n", filename);
Con_Printf(CON_WARNING "Need to download %s.pk3, but downloads are disabled\n", com_token);
continue;
}
//fixme: request to download it
Con_Printf("Sending request to download %s.pk3\n", filename);
CLQ3_SendClientCommand("download %s.pk3", filename);
Con_Printf("Sending request to download %s.pk3\n", com_token);
CLQ3_SendClientCommand("download %s.pk3", com_token);
ccs.downloadchunknum = 0;
dl = Z_Malloc(sizeof(*dl));
//q3's downloads are relative to root, but they do at least force a pk3 extension.
@ -480,73 +484,84 @@ static qboolean CLQ3_SendDownloads(char *rc, char *rn)
dl->prefixbytes = 8;
dl->fsroot = FS_ROOT;
Q_snprintfz(dl->remotename, sizeof(dl->remotename), "%s.pk3", filename);
Q_snprintfz(dl->remotename, sizeof(dl->remotename), "%s.pk3", com_token);
dl->method = DL_Q3;
dl->percent = 0;
ccs.download = dl;
cls.download = dl;
return true;
}
return false;
}
qboolean CLQ3_SystemInfoChanged(const char *str)
qboolean CLQ3_SystemInfoChanged(char *str)
{
qboolean usingpure, usingcheats;
char *value;
char *pc, *pn;
char *rc, *rn;
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"));
clientfuncs->ForceCheatVars(usingpure||usingcheats, usingcheats);
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"));
Cvar_ForceCheatVars(usingpure||usingcheats, usingcheats);
// if (atoi(value))
// Host_EndGame("Unable to connect to Q3 Pure Servers\n");
value = worldfuncs->GetInfoKey(str, "fs_game");
// if (atoi(value))
// Host_EndGame("Unable to connect to Q3 Pure Servers\n");
value = Info_ValueForKey(str, "fs_game");
if (!*value)
#ifndef CLIENTONLY
if (!sv.state)
#endif
{
value = "baseq3";
COM_FlushTempoaryPacks();
if (!*value)
value = "baseq3";
COM_Gamedir(value, NULL);
#ifndef CLIENTONLY
InfoBuf_SetStarKey (&svs.info, "*gamedir", value);
#endif
}
rc = worldfuncs->GetInfoKey(str, "sv_referencedPaks"); //the ones that we should download.
rn = worldfuncs->GetInfoKey(str, "sv_referencedPakNames");
rc = Info_ValueForKey(str, "sv_referencedPaks"); //the ones that we should download.
rn = Info_ValueForKey(str, "sv_referencedPakNames");
if (CLQ3_SendDownloads(rc, rn))
return false;
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);
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);
return true; //yay, we're in
}
void CLQ3_ParseGameState(sizebuf_t *msg)
void CLQ3_ParseGameState(void)
{
int c;
int index;
char *configString;
cvar_t *cl_paused;
//
// wipe the client_state_t struct
//
clientfuncs->ClearClientState();
CG_ClearGameState();
CL_ClearState(true);
ccs.firstParseEntity = 0;
memset(ccs.parseEntities, 0, sizeof(ccs.parseEntities));
memset(ccs.baselines, 0, sizeof(ccs.baselines));
ccs.lastServerCommandNum = msgfuncs->ReadLong();
cl.minpitch = -90;
cl.maxpitch = 90;
ccs.lastServerCommandNum = MSG_ReadLong();
for(;;)
{
c = msgfuncs->ReadByte();
c = MSG_ReadByte();
if(c < 0)
if(msg_badread)
{
plugfuncs->EndGame("CLQ3_ParseGameState: read past end of server message");
break;
Host_EndGame("CLQ3_ParseGameState: read past end of server message");
}
if(c == svcq3_eom)
@ -559,33 +574,33 @@ void CLQ3_ParseGameState(sizebuf_t *msg)
switch(c)
{
default:
plugfuncs->EndGame("CLQ3_ParseGameState: bad command byte %i", c);
Host_EndGame("CLQ3_ParseGameState: bad command byte %i", c);
break;
case svcq3_configstring:
index = msgfuncs->ReadBits(16);
index = MSG_ReadBits(16);
if (index < 0 || index >= MAX_Q3_CONFIGSTRINGS)
{
plugfuncs->EndGame("CLQ3_ParseGameState: configString index %i out of range", index);
Host_EndGame("CLQ3_ParseGameState: configString index %i out of range", index);
}
configString = msgfuncs->ReadString();
configString = MSG_ReadString();
CG_InsertIntoGameState(index, configString);
break;
case svcq3_baseline:
index = msgfuncs->ReadBits(GENTITYNUM_BITS);
index = MSG_ReadBits(GENTITYNUM_BITS);
if (index < 0 || index >= MAX_GENTITIES)
{
plugfuncs->EndGame("CLQ3_ParseGameState: baseline index %i out of range", index);
Host_EndGame("CLQ3_ParseGameState: baseline index %i out of range", index);
}
MSG_Q3_ReadDeltaEntity(NULL, &ccs.baselines[index], index);
break;
}
}
ccs.playernum = msgfuncs->ReadLong();
ccs.fs_key = msgfuncs->ReadLong();
cl.playerview[0].playernum = MSG_ReadLong();
ccs.fs_key = MSG_ReadLong();
if (!CLQ3_SystemInfoChanged(CG_GetConfigString(CFGSTR_SYSINFO)))
{
@ -593,48 +608,56 @@ void CLQ3_ParseGameState(sizebuf_t *msg)
return;
}
scenefuncs->NewMap(NULL);
CG_Restart();
CG_Restart_f();
UI_Restart_f();
if (!ccs.worldmodel)
plugfuncs->EndGame("CGame didn't set a map.\n");
if (!cl.worldmodel)
Host_EndGame("CGame didn't set a map.\n");
clientfuncs->SetLoadingState(false);
cl.model_precaches_added = false;
Surf_NewMap ();
ccs.state = ca_active;
SCR_EndLoadingPlaque();
CL_MakeActive("Quake3Arena");
cl.splitclients = 1;
{
char buffer[2048];
strcpy(buffer, va("cp %i ", ccs.servercount));
fsfuncs->GenerateClientPacksList(buffer, sizeof(buffer), ccs.fs_key);
strcpy(buffer, va("cp %i ", cl.servercount));
FSQ3_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();
cvarfuncs->ForceSetString("cl_paused", "0");
cl_paused = Cvar_FindVar("cl_paused");
if (cl_paused && cl_paused->ival)
Cvar_ForceSet(cl_paused, "0");
}
int CLQ3_ParseServerMessage (sizebuf_t *msg)
void CLQ3_ParseServerMessage (void)
{
int cmd;
if (!CLQ3_Netchan_Process(msg))
return ccs.state; //was a fragment.
if (!CLQ3_Netchan_Process())
return; //was a fragment.
if (cl_shownet_ptr->value == 1)
Con_Printf ("%i ", msg->cursize);
else if (cl_shownet_ptr->value == 2)
if (cl_shownet.value == 1)
Con_Printf ("%i ",net_message.cursize);
else if (cl_shownet.value == 2)
Con_Printf ("------------------\n");
msgfuncs->BeginReading(msg, msg_nullnetprim);
ccs.serverMessageNum = msgfuncs->ReadLong();
msg->packing = SZ_HUFFMAN; //the rest is huffman compressed.
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;
// read last client command number server received
ccs.lastClientCommandNum = msgfuncs->ReadLong();
ccs.lastClientCommandNum = MSG_ReadLong();
if( ccs.lastClientCommandNum <= ccs.numClientCommands - Q3TEXTCMD_BACKUP )
{
ccs.lastClientCommandNum = ccs.numClientCommands - Q3TEXTCMD_BACKUP + 1;
@ -649,11 +672,11 @@ int CLQ3_ParseServerMessage (sizebuf_t *msg)
//
for(;;)
{
cmd = msgfuncs->ReadByte();
cmd = MSG_ReadByte();
if(cmd < 0) //hm, we have an eom, so only stop when the message is bad.
if(msg_badread) //hm, we have an eom, so only stop when the message is bad.
{
plugfuncs->EndGame("CLQ3_ParseServerMessage: read past end of server message");
Host_EndGame("CLQ3_ParseServerMessage: read past end of server message");
break;
}
@ -669,12 +692,12 @@ int CLQ3_ParseServerMessage (sizebuf_t *msg)
switch(cmd)
{
default:
plugfuncs->EndGame("CLQ3_ParseServerMessage: Illegible server message");
Host_EndGame("CLQ3_ParseServerMessage: Illegible server message");
break;
case svcq3_nop:
break;
case svcq3_gamestate:
CLQ3_ParseGameState(msg);
CLQ3_ParseGameState();
break;
case svcq3_serverCommand:
CLQ3_ParseServerCommand();
@ -687,58 +710,71 @@ int CLQ3_ParseServerMessage (sizebuf_t *msg)
break;
}
}
return ccs.state;
}
static qboolean CLQ3_Netchan_Process(sizebuf_t *msg)
qboolean CLQ3_Netchan_Process(void)
{
if(Netchan_ProcessQ3(&ccs.netchan, msg))
{
#ifndef Q3_NOENCRYPT
int sequence;
int lastClientCommandNum;
qbyte bitmask;
qbyte c;
int i, j;
char *string;
int readcount;
msgfuncs->BeginReading(msg, msg_nullnetprim);
sequence = msgfuncs->ReadLong();
msg->packing = SZ_HUFFMAN;
readcount = msg->currentbit>>3;
lastClientCommandNum = msgfuncs->ReadLong();
// calculate bitmask
bitmask = (sequence ^ ccs.challenge) & 0xff;
string = ccs.clientCommands[lastClientCommandNum & Q3TEXTCMD_MASK];
// decrypt the packet
for(i=readcount+4,j=0 ; i<msg->cursize ; i++,j++)
{
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;
}
msg->packing = SZ_RAWBITS; //first bit was plain...
int sequence;
int lastClientCommandNum;
qbyte bitmask;
qbyte c;
int i, j;
char *string;
int bit;
int readcount;
#endif
return true; //all good
if(!Netchan_ProcessQ3(&cls.netchan))
{
return false;
}
return false; //its bad dude, bad.
#ifndef Q3_NOENCRYPT
// archive buffer state
bit = net_message.currentbit;
readcount = msg_readcount;
net_message.packing = SZ_HUFFMAN;
net_message.currentbit = 32;
lastClientCommandNum = MSG_ReadLong();
sequence = LittleLong(*(int *)net_message.data);
// restore buffer state
net_message.currentbit = bit;
msg_readcount = readcount;
// 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])
{
j = 0; // another way around
}
c = string[j];
if(c > 127 || c == '%')
{
c = '.';
}
bitmask ^= c << ((i-msg_readcount) & 1);
net_message.data[i] ^= bitmask;
}
#endif
return true;
}
void CL_Netchan_Transmit(struct ftenet_connections_s *socket, int length, const qbyte *data )
void CL_Netchan_Transmit( 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;
@ -746,45 +782,47 @@ void CL_Netchan_Transmit(struct ftenet_connections_s *socket, int length, const
qbyte c;
int i, j;
char *string;
#endif
net_message.cursize = 0;
SZ_Write(&msg, data, length);
msgfuncs->BeginWriting(&msg, msg_nullnetprim, msgdata, sizeof(msgdata));
msgfuncs->WriteData(&msg, data, length);
if (msg.overflowed)
if(msg.overflowed)
{
plugfuncs->EndGame("Client message overflowed");
Host_EndGame("Client message overflowed");
}
msgfuncs->BeginReading(&msg, msg_nullnetprim);
#ifndef Q3_NOENCRYPT
msg_readcount = 0;
msg.currentbit = 0;
msg.packing = SZ_HUFFMAN;
serverid = msgfuncs->ReadLong();
lastSequence = msgfuncs->ReadLong();
lastServerCommandNum = msgfuncs->ReadLong();
serverid = MSG_ReadLong();
lastSequence = MSG_ReadLong();
lastServerCommandNum = MSG_ReadLong();
// calculate bitmask
bitmask = (lastSequence ^ serverid ^ ccs.challenge) & 0xff;
bitmask = (lastSequence ^ serverid ^ cls.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(socket, &ccs.netchan, length, data);
Netchan_TransmitQ3( &cls.netchan, msg.cursize, msg.data );
#undef msg
}
@ -794,12 +832,12 @@ static void MSG_WriteDeltaKey( sizebuf_t *msg, int key, int from, int to, int bi
{
if( from == to )
{
msgfuncs->WriteBits( msg, 0, 1 );
MSG_WriteBits( msg, 0, 1 );
return; // unchanged
}
msgfuncs->WriteBits( msg, 1, 1 );
msgfuncs->WriteBits( msg, to ^ key, bits );
MSG_WriteBits( msg, 1, 1 );
MSG_WriteBits( msg, to ^ key, bits );
}
void MSG_Q3_WriteDeltaUsercmd( sizebuf_t *msg, int key, const usercmd_t *from, const usercmd_t *to )
@ -807,27 +845,29 @@ 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 )
{
msgfuncs->WriteBits(msg, 1, 1);
msgfuncs->WriteBits(msg, to->servertime - from->servertime, 8);
MSG_WriteBits(msg, 1, 1);
MSG_WriteBits(msg, to->servertime - from->servertime, 8);
}
else
{
msgfuncs->WriteBits( msg, 0, 1 );
msgfuncs->WriteBits( msg, to->servertime, 32);
MSG_WriteBits( msg, 0, 1 );
MSG_WriteBits( msg, to->servertime, 32);
}
if( !memcmp( (qbyte *)from + 4, (qbyte *)to + 4, sizeof( usercmd_t ) - 4 ) )
{
msgfuncs->WriteBits(msg, 0, 1);
MSG_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);
@ -849,29 +889,28 @@ void VARGS CLQ3_SendClientCommand(const char *fmt, ...)
// check if server will lose some of our clientCommands
if(ccs.numClientCommands - ccs.lastClientCommandNum >= Q3TEXTCMD_BACKUP)
plugfuncs->EndGame("Client command overflow");
Host_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(struct ftenet_connections_s *socket, usercmd_t *cmd, unsigned int movesequence, double gametime)
void CLQ3_SendCmd(usercmd_t *cmd)
{
char *string;
int i;
char data[MAX_OVERALLMSGLEN];
sizebuf_t msg;
// outframe_t *frame;
unsigned int oldsequence;
outframe_t *frame, *oldframe;
int cmdcount, key;
const usercmd_t *to, *from;
static usercmd_t nullcmd;
usercmd_t *to;
const usercmd_t *from;
extern cvar_t cl_nodelta, cl_c2sdupe;
//reuse the q1 array
cmd->servertime = gametime*1000;
cmd->servertime = cl.servertime*1000;
cmd->weapon = ccs.selected_weapon;
cmd->forwardmove *= 127/400.0f;
cmd->sidemove *= 127/400.0f;
cmd->upmove *= 127/400.0f;
@ -893,58 +932,62 @@ void CLQ3_SendCmd(struct ftenet_connections_s *socket, usercmd_t *cmd, unsigned
cmd->upmove = 100;
cmd->buttons &= ~2;
}
if (inputfuncs->GetKeyDest() & ~kdm_game)
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[ccs.netchan.outgoing_sequence & Q3CMD_MASK];
frame->cmd_sequence = movesequence;
frame = &cl.outframes[cls.netchan.outgoing_sequence & Q3CMD_MASK];
frame->cmd_sequence = cl.movesequence;
frame->server_message_num = ccs.serverMessageNum;
frame->server_time = gametime;
frame->client_time = plugfuncs->GetMilliseconds();
*/
frame->server_time = cl.gametime;
frame->client_time = Sys_DoubleTime()*1000;
memset(&msg, 0, sizeof(msg));
msg.maxsize = sizeof(data);
msg.data = data;
msg.packing = SZ_HUFFMAN;
msgfuncs->WriteBits(&msg, ccs.servercount, 32);
msgfuncs->WriteBits(&msg, ccs.serverMessageNum, 32);
msgfuncs->WriteBits(&msg, ccs.lastServerCommandNum, 32);
MSG_WriteBits(&msg, cl.servercount, 32);
MSG_WriteBits(&msg, ccs.serverMessageNum, 32);
MSG_WriteBits(&msg, ccs.lastServerCommandNum, 32);
// write clientCommands not acknowledged by server yet
for (i=ccs.lastClientCommandNum+1; i<=ccs.numClientCommands; i++)
{
msgfuncs->WriteBits(&msg, clcq3_clientCommand, 8);
msgfuncs->WriteBits(&msg, i, 32);
MSG_WriteBits(&msg, clcq3_clientCommand, 8);
MSG_WriteBits(&msg, i, 32);
string = ccs.clientCommands[i & Q3TEXTCMD_MASK];
while(*string)
msgfuncs->WriteBits(&msg, *string++, 8);
msgfuncs->WriteBits(&msg, 0, 8);
MSG_WriteBits(&msg, *string++, 8);
MSG_WriteBits(&msg, 0, 8);
}
i = ccs.netchan.outgoing_sequence;
i -= bound(0, cl_c2sdupe_ptr->ival, 5); //extra age, if desired
i = cls.netchan.outgoing_sequence;
i -= bound(0, cl_c2sdupe.ival, 5); //extra age, if desired
i--;
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 (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 (cmdcount > Q3CMD_MASK)
cmdcount = Q3CMD_MASK;
// begin a client move command, if any
if (cmdcount)
{
if(cl_nodelta_ptr->value || !ccs.snap.valid || ccs.snap.serverMessageNum != ccs.serverMessageNum)
msgfuncs->WriteBits(&msg, clcq3_nodeltaMove, 8); // no compression
if(cl_nodelta.value || !ccs.snap.valid ||
ccs.snap.serverMessageNum != ccs.serverMessageNum)
MSG_WriteBits(&msg, clcq3_nodeltaMove, 8); // no compression
else
msgfuncs->WriteBits(&msg, clcq3_move, 8);
MSG_WriteBits(&msg, clcq3_move, 8);
// write cmdcount
msgfuncs->WriteBits(&msg, cmdcount, 8);
MSG_WriteBits(&msg, cmdcount, 8);
// calculate key
string = ccs.serverCommands[ccs.lastServerCommandNum & Q3TEXTCMD_MASK];
@ -953,24 +996,22 @@ void CLQ3_SendCmd(struct ftenet_connections_s *socket, usercmd_t *cmd, unsigned
//note that q3 uses timestamps so sequences are not important
//we can also send dupes without issue.
from = &nullcmd;
for (i = movesequence-cmdcount; i < movesequence; i++)
for (i = cl.movesequence-cmdcount; i < cl.movesequence; i++)
{
to = inputfuncs->GetMoveEntry(i);
if (!to)
to = from;
to = &cl.outframes[i&Q3CMD_MASK].cmd[0];
MSG_Q3_WriteDeltaUsercmd( &msg, key, from, to );
from = to;
}
}
msgfuncs->WriteBits(&msg, clcq3_eom, 8);
MSG_WriteBits(&msg, clcq3_eom, 8);
CL_Netchan_Transmit(socket, msg.cursize, msg.data );
while(ccs.netchan.reliable_length)
Netchan_TransmitNextFragment(socket, &ccs.netchan);
CL_Netchan_Transmit( msg.cursize, msg.data );
while(cls.netchan.reliable_length)
Netchan_TransmitNextFragment(&cls.netchan);
}
void CLQ3_SendAuthPacket(struct ftenet_connections_s *socket, netadr_t *gameserver)
void CLQ3_SendAuthPacket(netadr_t *gameserver)
{
#ifdef HAVE_PACKET
char data[2048];
@ -980,27 +1021,30 @@ void CLQ3_SendAuthPacket(struct ftenet_connections_s *socket, netadr_t *gameserv
//this should be the right code, but it doesn't work.
if (gameserver->type == NA_IP)
{
char *key = cvarfuncs->GetNVFDG("cl_cdkey", "", CVAR_ARCHIVE, "Quake3 auth", "Q3 Compat")->string;
char *key = Cvar_Get("cl_cdkey", "", 0, "Quake3 auth")->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 (masterfuncs->StringToAdr(Q3_AUTHORIZE_SERVER_NAME, 0, &authaddr, 1, NULL))
if (NET_StringToAdr(Q3_AUTHORIZE_SERVER_NAME, 0, &authaddr))
{
msgfuncs->BeginWriting(&msg, msg_nullnetprim, data, sizeof(data));
msgfuncs->WriteLong(&msg, -1);
msgfuncs->WriteString(&msg, "getKeyAuthorize 0 ");
msg.data = data;
msg.cursize = 0;
msg.overflowed = msg.allowoverflow = 0;
msg.maxsize = sizeof(data);
MSG_WriteLong(&msg, -1);
MSG_WriteString(&msg, "getKeyAuthorize 0 ");
msg.cursize--;
while(*key)
{
if ((*key >= 'a' && *key <= 'z') || (*key >= 'A' && *key <= 'Z') || (*key >= '0' && *key <= '9'))
msgfuncs->WriteByte(&msg, *key);
MSG_WriteByte(&msg, *key);
key++;
}
msgfuncs->WriteByte(&msg, 0);
MSG_WriteByte(&msg, 0);
msgfuncs->SendPacket(socket, msg.cursize, msg.data, &authaddr);
NET_SendPacket (cls.sockets, msg.cursize, msg.data, &authaddr);
}
else
Con_Printf(" failed\n");
@ -1009,45 +1053,33 @@ void CLQ3_SendAuthPacket(struct ftenet_connections_s *socket, netadr_t *gameserv
#endif
}
void CLQ3_SendConnectPacket(struct ftenet_connections_s *socket, netadr_t *to, int challenge, int qport, infobuf_t *userinfo)
void CLQ3_SendConnectPacket(netadr_t *to, int challenge, int qport)
{
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);
worldfuncs->IBufToInfo(userinfo, infostr, sizeof(infostr), priorityq3, nonq3, NULL, NULL,/*&cls.userinfosync,*/ userinfo);
InfoBuf_ToString(&cls.userinfo[0], infostr, sizeof(infostr), basicuserinfos, nonq3, NULL, &cls.userinfosync, &cls.userinfo[0]);
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));
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));
#ifdef HUFFNETWORK
if (msgfuncs->Huff_EncryptPacket)
msgfuncs->Huff_EncryptPacket(&msg, 12);
if (!msgfuncs->Huff_CompressionCRC || !msgfuncs->Huff_CompressionCRC(HUFFCRC_QUAKE3))
Huff_EncryptPacket(&msg, 12);
if (!Huff_CompressionCRC(HUFFCRC_QUAKE3))
{
Con_Printf("Huffman compression error\n");
return;
}
#endif
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;
NET_SendPacket (cls.sockets, msg.cursize, msg.data, to);
}
#endif

View File

@ -1,6 +1,11 @@
#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);
@ -19,9 +24,10 @@ 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;
@ -79,15 +85,16 @@ 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;
@ -142,7 +149,6 @@ 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
@ -156,7 +162,6 @@ 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;
@ -177,7 +182,9 @@ typedef struct snapshot_s {
//this struct is used internally, using a ringbuffer for entities instead of worst-case memory usage.
//
// clientSnap_t is will be converted to snapshot_t for internal cgame use
//
typedef struct clientSnap_s {
qboolean valid; // cleared if delta parsing was invalid
int snapFlags;
@ -213,45 +220,32 @@ 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 MAX_Q3_CONFIGSTRINGS 1024
#define Q3TEXTCMD_BACKUP 64 //number of reliable text commands that can be queued, must be power of two
#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 servercount; //bumped on map changes
int serverMessageNum;
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;
@ -323,7 +317,6 @@ 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);
@ -331,43 +324,13 @@ 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);
typedef struct {
char renderer_string[MAX_STRING_CHARS];
char vendor_string[MAX_STRING_CHARS];
char version_string[MAX_STRING_CHARS];
char extensions_string[8192];
void Netchan_TransmitNextFragment( netchan_t *chan );
void Netchan_TransmitQ3( netchan_t *chan, int length, const qbyte *data );
qboolean Netchan_ProcessQ3 (netchan_t *chan);
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);
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);
@ -380,59 +343,8 @@ 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_AddPolys(shader_t *s, int num, q3polyvert_t *verts, size_t count);
void VQ3_AddPoly(shader_t *s, int num, q3polyvert_t *verts);
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

@ -637,7 +637,6 @@ void Con_ToggleConsole_Force(void)
{
con_curwindow = con;
Key_Dest_Add(kdm_cwindows);
VRUI_SnapAngle();
}
}
else
@ -645,10 +644,7 @@ void Con_ToggleConsole_Force(void)
if (Key_Dest_Has(kdm_console))
Key_Dest_Remove(kdm_console);
else
{
Key_Dest_Add(kdm_console);
VRUI_SnapAngle();
}
}
}
void Con_ToggleConsole_f (void)
@ -987,8 +983,6 @@ void Con_PrintCon (console_t *con, const char *txt, unsigned int parseflags)
con->current->flags |= CONL_CENTERED;
if (parseflags & PFS_NONOTIFY)
con->current->flags |= CONL_NONOTIFY;
else if (!Key_Dest_Has(~kdm_game) && (con->flags & CONF_NOTIFY))
VRUI_SnapAngle();
#if defined(HAVE_SPEECHTOTEXT)
if (con->current)
@ -2749,27 +2743,25 @@ 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]);
ent.topcolour = TOP_DEFAULT;
ent.bottomcolour = BOTTOM_DEFAULT;
/*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.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;
if (model->submodelof)
;
else
{
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));
}
}
// ent.customskin = Mod_RegisterSkinFile(va("%s_0.skin", mods->modelname));
Vector4Set(ent.shaderRGBAf, 1,1,1,1);
VectorSet(ent.glowmod, 1,1,1);
@ -2816,7 +2808,7 @@ static void Con_DrawModelPreview(model_t *model, float x, float y, float w, floa
ent.light_dir[1] = DotProduct(lightpos, ent.axis[1]);
ent.light_dir[2] = DotProduct(lightpos, ent.axis[2]);
ent.light_known = 2;
ent.light_type = ELT_FLAT;
V_AddEntity(&ent);
@ -2914,15 +2906,12 @@ static void Con_DrawMouseOver(console_t *mouseconsole)
}
else
shader = NULL;
if (!vrui.enabled)
key = Info_ValueForKey(info, "modelviewer");
if (*key)
{
key = Info_ValueForKey(info, "modelviewer");
if (*key)
{
model = Mod_ForName(key, MLV_WARN);
if (model->loadstate != MLS_LOADED)
model = NULL;
}
model = Mod_ForName(key, MLV_WARN);
if (model->loadstate != MLS_LOADED)
model = NULL;
}
key = Info_ValueForKey(info, "playaudio");
@ -3145,7 +3134,7 @@ void Con_DrawConsole (int lines, qboolean noback)
#ifdef QUAKETC //total conversions should have their own website.
ENGINEWEBSITE
#else //otherwise use some more useful page, for quake mods.
"cmd:home"
"https://www.quakeworld.nu/wiki/Overview"
#endif
, NULL, NULL};
float tw;

View File

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

View File

@ -230,44 +230,6 @@ static float HalfToFloat(unsigned short val);
static unsigned short FloatToHalf(float val);
static struct
{
void *module;
plugimageloaderfuncs_t *funcs;
} *imageloader;
static size_t imageloader_count;
qboolean Image_RegisterLoader(void *module, plugimageloaderfuncs_t *driver)
{
int i;
if (!driver)
{
for (i = 0; i < imageloader_count; )
{
if (imageloader[i].module == module)
{
memmove(&imageloader[i], &imageloader[i+1], imageloader_count-(i+1));
imageloader_count--;
}
else
i++;
}
return true;
}
else
{
void *n = BZ_Malloc(sizeof(*imageloader)*(imageloader_count+1));
memcpy(n, imageloader, sizeof(*imageloader)*imageloader_count);
Z_Free(imageloader);
imageloader = n;
imageloader[imageloader_count].module = module;
imageloader[imageloader_count].funcs = driver;
imageloader_count++;
return true;
}
}
#if defined(AVAIL_JPEGLIB) || defined(AVAIL_PNGLIB)
static void GenerateXMPData(char *blob, size_t blobsize, int width, int height, unsigned int metainfo)
{ //XMP is a general thing that applies to multiple formats - or at least png+jpeg.
@ -5146,12 +5108,12 @@ qboolean Image_WriteKTXFile(const char *filename, enum fs_relative fsroot, struc
case PTI_ANY:
VFS_CLOSE(file);
return false;
case PTI_CUBE: //special case, size is per-face
sz = (browbytes+padbytes) * brows;
break;
case PTI_2D:
case PTI_2D_ARRAY:
case PTI_CUBE:
case PTI_CUBE_ARRAY:
sz = (browbytes+padbytes) * brows;
break;
case PTI_3D:
sz = (browbytes+padbytes) * brows * blayers;
break;
@ -7177,6 +7139,225 @@ static struct pendingtextureinfo *Image_ReadBLPFile(unsigned int flags, const ch
}
#endif
#ifdef IMAGEFMT_VTF
//many of these look like dupes, not really sure how they're meant to work. probably legacy.
typedef enum {
VMF_INVALID=-1,
VMF_RGBA8=0,
// VMF_ABGR8=1,
VMF_RGB8=2,
VMF_BGR8=3,
// VMF_RGB565=4,
VMF_I8=5,
VMF_IA8=6,
// VMF_P8=7,
// VMF_A8=8,
// VMF_RGB8_BS=9,
// VMF_BGR8_BS=10,
// VMF_ARGB_BS=11,
VMF_BGRA8=12,
VMF_BC1=13,
VMF_BC2=14,
VMF_BC3=15,
VMF_BGRX8=16,
// VMF_BGR565=17,
// VMF_BGRX5551=18,
// VMF_BGRA4444=19,
VMF_BC1A=20,
// VMF_BGRA5551=21,
VMF_UV88=22,
// VMF_UVWQ8=23,
VMF_RGBA16F=24,
// VMF_RGBA16N=25,
// VMF_UVLX8=26,
VMF_MAX
} fmtfmt_t;
static uploadfmt_t ImageVTF_VtfToFTE(fmtfmt_t f)
{
switch(f)
{
case VMF_BC1:
return PTI_BC1_RGB;
case VMF_BC1A:
return PTI_BC1_RGBA;
case VMF_BC2:
return PTI_BC2_RGBA;
case VMF_BC3:
return PTI_BC3_RGBA;
case VMF_RGB8:
return PTI_RGB8;
case VMF_RGBA8:
return PTI_RGBA8;
case VMF_BGR8:
return PTI_BGR8;
case VMF_BGRA8:
return PTI_BGRA8;
case VMF_BGRX8:
return PTI_BGRX8;
case VMF_RGBA16F:
return PTI_RGBA16F;
case VMF_UV88:
return PTI_RG8;
case VMF_I8:
return PTI_L8;
case VMF_IA8:
return PTI_L8A8;
case VMF_INVALID:
return PTI_INVALID;
default:
return PTI_INVALID;
}
}
static struct pendingtextureinfo *Image_ReadVTFFile(unsigned int flags, const char *fname, qbyte *filedata, size_t filesize)
{
//FIXME: cba with endian.
struct vtf_s
{
char magic[4];
unsigned int major,minor;
unsigned int headersize;
unsigned short width, height;
unsigned int flags;
unsigned short numframes, firstframe;
unsigned int pad1;
vec3_t reflectivity;
float pad2;
float bumpmapscale;
unsigned int imgformat;
unsigned char mipmapcount;
unsigned char lowresfmt_misaligned[4];
unsigned char lowreswidth;
unsigned char lowresheight;
//7.2
unsigned char depth_misaligned[2];
//7.3
unsigned char pad3[3];
unsigned int numresources;
} *vtf;
fmtfmt_t vmffmt, lrfmt;
unsigned int bw, bh, bd, bb;
qbyte *end = filedata + filesize;
unsigned int faces, frame, frames, miplevel, miplevels, img;
unsigned int w, h, d = 1;
size_t datasize;
unsigned int version;
struct pendingtextureinfo *mips;
vtf = (void*)filedata;
if (memcmp(vtf->magic, "VTF\0", 4))
return NULL;
version = (vtf->major<<16)|vtf->minor;
if (version > 0x00070005)
{
Con_Printf("%s: VTF version %i.%i is not supported\n", fname, vtf->major, vtf->minor);
return NULL;
}
lrfmt = (vtf->lowresfmt_misaligned[0]<<0)|(vtf->lowresfmt_misaligned[1]<<16)|(vtf->lowresfmt_misaligned[2]<<16)|(vtf->lowresfmt_misaligned[3]<<24);
vmffmt = vtf->imgformat;
mips = NULL;
if (version >= 0x00070003)
{
int i;
struct
{
unsigned int rtype;
unsigned int rdata; //usually an offset.
} *restable = (void*)(filedata+sizeof(*vtf));
for (i = 0; i < vtf->numresources; i++, restable++)
{
if ((restable->rtype & 0x00ffffff) == 0x30)
{
mips = Z_Malloc(sizeof(*mips));
mips->extrafree = filedata;
filedata += restable->rdata;
break;
}
//other unknown resource types.
}
}
if (!mips)
{
mips = Z_Malloc(sizeof(*mips));
mips->extrafree = filedata;
//skip the header
filedata += vtf->headersize;
//and skip the low-res image too.
if (vtf->lowreswidth && vtf->lowresheight)
Image_BlockSizeForEncoding(ImageVTF_VtfToFTE(lrfmt), &bb, &bw, &bh, &bd);
else
bb=bw=bh=bd=1;
datasize = ((vtf->lowreswidth+bw-1)/bw) * ((vtf->lowresheight+bh-1)/bh) * ((1/*vtf->lowresdepth*/+bd-1)/bd) * bb;
filedata += datasize;
}
//now handle the high-res image
if (mips)
{
mips->type = (vtf->flags & 0x4000)?PTI_CUBE:PTI_2D;
mips->encoding = ImageVTF_VtfToFTE(vmffmt);
Image_BlockSizeForEncoding(mips->encoding, &bb, &bw, &bh, &bd);
miplevels = vtf->mipmapcount;
frames = 1;//vtf->numframes;
faces = ((mips->type==PTI_CUBE)?6:1); //no cubemaps yet.
mips->mipcount = miplevels * frames;
while (mips->mipcount > countof(mips->mip))
{
if (miplevels > 1)
miplevels--;
else
frames--;
mips->mipcount = miplevels * frames;
}
if (!mips->mipcount)
{
Z_Free(mips);
return NULL;
}
for (miplevel = vtf->mipmapcount; miplevel-- > 0;)
{ //smallest to largest, which is awkward.
w = vtf->width>>miplevel;
h = vtf->height>>miplevel;
if (!w)
w = 1;
if (!h)
h = 1;
datasize = ((w+bw-1)/bw) * ((h+bh-1)/bh) * ((d+bd-1)/bd) * bb;
for (frame = 0; frame < vtf->numframes; frame++)
{
if (miplevel < miplevels)
{
img = miplevel + frame*miplevels;
if (img >= countof(mips->mip))
break; //erk?
if (filedata + datasize > end)
break; //no more data here...
mips->mip[img].width = w;
mips->mip[img].height = h;
mips->mip[img].depth = faces;
mips->mip[img].data = filedata;
mips->mip[img].datasize = datasize*faces;
}
filedata += datasize*faces;
}
}
}
return mips;
}
#endif
//This is for the version command
void Image_PrintInputFormatVersions(void)
@ -7194,6 +7375,9 @@ void Image_PrintInputFormatVersions(void)
#ifdef IMAGEFMT_KTX
Con_Printf(" ktx");
#endif
#ifdef IMAGEFMT_VTF
Con_Printf(" vtf");
#endif
#ifdef IMAGEFMT_TGA
Con_Printf(" tga");
#endif
@ -7289,7 +7473,6 @@ void Image_PrintInputFormatVersions(void)
//if force_rgba8 then it guarentees rgba8 or rgbx8, otherwise can return l8, etc
qbyte *ReadRawImageFile(qbyte *buf, int len, int *width, int *height, uploadfmt_t *format, qboolean force_rgba8, const char *fname)
{
size_t l, i;
qbyte *data;
*format = PTI_RGBX8;
#ifdef IMAGEFMT_TGA
@ -7383,58 +7566,6 @@ qbyte *ReadRawImageFile(qbyte *buf, int len, int *width, int *height, uploadfmt_
}
#endif
for (l = 0; l < imageloader_count; l++)
{
struct pendingtextureinfo *mips = imageloader[l].funcs->ReadImageFile(0, fname, buf, len);
if (mips)
{
if (mips->extrafree != buf)
Sys_Error("Image loader did weird extrafree things.");
mips->extrafree = NULL;
//free any excess mips
while (mips->mipcount > 1)
if (mips->mip[--mips->mipcount].needfree)
BZ_Free(mips->mip[mips->mipcount].data);
if (mips->mipcount > 0 && mips->type == PTI_2D)
{
if (force_rgba8)
{
qboolean rgbx8only[PTI_MAX] = {0};
rgbx8only[PTI_RGBX8] = true;
rgbx8only[PTI_RGBA8] = true;
Image_ChangeFormat(mips, rgbx8only, mips->encoding, fname);
}
if (mips->mip[0].needfree)
{
data = mips->mip[0].data;
mips->mip[0].data = NULL;
mips->mip[0].needfree = false;
}
else
{
data = BZ_Malloc(mips->mip[0].datasize);
memcpy(data, mips->mip[0].data, mips->mip[0].datasize);
}
*width = mips->mip[0].width;
*height = mips->mip[0].height;
*format = mips->encoding;
}
for (i = 0; i < mips->mipcount; i++)
if (mips->mip[i].needfree)
BZ_Free(mips->mip[i].data);
if (mips->extrafree && mips->extrafree)
BZ_Free(mips->extrafree);
BZ_Free(mips);
if (data)
return data;
}
}
#ifdef IMAGEFMT_LMP
if (len >= 8) //.lmp has no magic id. guess at it.
{
@ -7443,29 +7574,18 @@ qbyte *ReadRawImageFile(qbyte *buf, int len, int *width, int *height, uploadfmt_
int i;
if (w >= 3 && h >= 4 && w*h+sizeof(int)*2 == len)
{ //quake lmp
if (force_rgba8)
qboolean foundalpha = false;
qbyte *in = buf+sizeof(int)*2;
data = BZ_Malloc(w * h * sizeof(int));
for (i = 0; i < w * h; i++)
{
qboolean foundalpha = false;
qbyte *in = buf+sizeof(int)*2;
data = BZ_Malloc(w * h * sizeof(int));
for (i = 0; i < w * h; i++)
{
if (in[i] == 255)
foundalpha = true;
((unsigned int*)data)[i] = d_8to24rgbtable[in[i]];
}
*width = w;
*height = h;
*format = foundalpha?PTI_RGBA8:PTI_RGBX8;
}
else
{
data = BZ_Malloc(w * h);
memcpy(data, buf+8, w*h);
*width = w;
*height = h;
*format = TF_TRANS8;
if (in[i] == 255)
foundalpha = true;
((unsigned int*)data)[i] = d_8to24rgbtable[in[i]];
}
*width = w;
*height = h;
*format = foundalpha?PTI_RGBA8:PTI_RGBX8;
return data;
}
else if (w >= 3 && h >= 4 && w*h+sizeof(int)*2+768+2 == len)
@ -12104,9 +12224,9 @@ static struct
{PTI_RGBA32F, PTI_RGB32F, Image_Tr_DropBytes, (16<<16)|12, true},
{PTI_RG8, PTI_RGBX8, Image_Tr_RG8ToRGXX8},
{PTI_RGBX8, PTI_P8, Image_Tr_RGBX8toPaletted, 0|(256<<16)},
{PTI_RGBX8, TF_H2_TRANS8_0, Image_Tr_RGBX8toPaletted, 1|(256<<16)},
{PTI_RGBX8, TF_TRANS8, Image_Tr_RGBX8toPaletted, 0|(255<<16)},
{PTI_RGBX8, PTI_P8, Image_Tr_RGBX8toPaletted, 0},
{PTI_RGBX8, TF_H2_TRANS8_0, Image_Tr_RGBX8toPaletted, 1|(255<<16)},
{PTI_RGBX8, TF_TRANS8, Image_Tr_RGBX8toPaletted, 0|(254<<16)},
{PTI_P8, PTI_RGBX8, Image_Tr_PalettedtoRGBX8, -1},
{TF_SOLID8, PTI_RGBX8, Image_Tr_PalettedtoRGBX8, -1},
{TF_H2_TRANS8_0,PTI_RGBA8, Image_Tr_PalettedtoRGBX8, 0},
@ -13245,7 +13365,6 @@ struct pendingtextureinfo *Image_LoadMipsFromMemory(int flags, const char *iname
qbyte *rgbadata;
int imgwidth, imgheight;
size_t l;
struct pendingtextureinfo *mips = NULL;
@ -13266,8 +13385,10 @@ struct pendingtextureinfo *Image_LoadMipsFromMemory(int flags, const char *iname
if (!mips && filedata[0] == 'B' && filedata[1] == 'L' && filedata[2] == 'P' && filedata[3] == '2')
mips = Image_ReadBLPFile(flags, fname, filedata, filesize);
#endif
for (l = 0; !mips && l < imageloader_count; l++)
mips = imageloader[l].funcs->ReadImageFile(flags, fname, filedata, filesize);
#ifdef IMAGEFMT_VTF
if (!mips && filedata[0] == 'V' && filedata[1] == 'T' && filedata[2] == 'F' && filedata[3] == '\0')
mips = Image_ReadVTFFile(flags, fname, filedata, filesize);
#endif
#ifdef IMAGEFMT_ASTC
if (!mips && filesize>= 16 && filedata[0] == 0x13 && filedata[1] == 0xab && filedata[2] == 0xa1 && filedata[3] == 0x5c)
mips = Image_ReadASTCFile(flags, fname, filedata, filesize);
@ -13375,17 +13496,8 @@ struct pendingtextureinfo *Image_LoadMipsFromMemory(int flags, const char *iname
mips->mipcount = 1;
mips->encoding = PTI_WHOLEFILE;
mips->extrafree = NULL;
//evil ensues:
if (filesize >= 32 && !strncmp(filedata, "\x89PNG", 4) && !strncmp(filedata+12, "IHDR", 4))
{ //need to do this to get png sizes working right for the quake rerelease's content
mips->mip[0].width = (filedata[0x13]<<0)|(filedata[0x12]<<8)|(filedata[0x11]<<16)|(filedata[0x10]<<24);
mips->mip[0].height = (filedata[0x17]<<0)|(filedata[0x16]<<8)|(filedata[0x15]<<16)|(filedata[0x14]<<24);
}
else
{
mips->mip[0].width = 1;
mips->mip[0].height = 1;
}
mips->mip[0].width = 1;
mips->mip[0].height = 1;
mips->mip[0].depth = 1;
mips->mip[0].data = filedata;
mips->mip[0].datasize = filesize;
@ -13786,8 +13898,6 @@ qboolean Image_LocateHighResTexture(image_t *tex, flocation_t *bestloc, char *be
continue;
s = COM_SkipPath(nicename);
if (!*s)
continue;
n = basename;
while (*s && (*s != '.'||exactext) && n < basename+sizeof(basename)-5)
*n++ = *s++;
@ -13933,7 +14043,7 @@ static void Image_LoadHiResTextureWorker(void *ctx, void *data, size_t a, size_t
unsigned int locflags = 0;
vfsfile_t *f;
size_t fsize, l;
size_t fsize;
char *buf;
int i, j;
@ -14015,12 +14125,10 @@ static void Image_LoadHiResTextureWorker(void *ctx, void *data, size_t a, size_t
if (!mips)
mips = Image_ReadDDSFile(tex->flags, altname, buf, fsize);
#endif
for (l = 0; !mips && l < imageloader_count; l++)
{
if (!imageloader[l].funcs->canloadcubemaps)
continue;
mips = imageloader[l].funcs->ReadImageFile(tex->flags, altname, buf, fsize);
}
#ifdef IMAGEFMT_VTF
if (!mips)
mips = Image_ReadVTFFile(tex->flags, altname, buf, fsize);
#endif
if (!mips)
BZ_Free(buf);
}

View File

@ -469,17 +469,12 @@ void IN_Commands(void)
{
if (topmenu && topmenu->joyaxis && topmenu->joyaxis(topmenu, ev->devid, ev->joy.axis, ev->joy.value))
joy[ev->devid].axis[ev->joy.axis] = 0;
#ifdef QUAKESTATS
else if (ev->joy.axis==GPAXIS_LT_RIGHT && IN_WeaponWheelAccumulate(ev->devid, ev->joy.value, 0))
joy[ev->devid].axis[ev->joy.axis] = 0;
else if (ev->joy.axis==GPAXIS_LT_DOWN && IN_WeaponWheelAccumulate(ev->devid, 0, ev->joy.value))
joy[ev->devid].axis[ev->joy.axis] = 0;
#endif
#ifdef CSQC_DAT
else if (CSQC_JoystickAxis(ev->joy.axis, ev->joy.value, ev->devid))
joy[ev->devid].axis[ev->joy.axis] = 0;
#endif
else
#ifdef CSQC_DAT
if (CSQC_JoystickAxis(ev->joy.axis, ev->joy.value, ev->devid))
joy[ev->devid].axis[ev->joy.axis] = 0;
else
#endif
joy[ev->devid].axis[ev->joy.axis] = ev->joy.value;
}
break;
@ -497,7 +492,7 @@ void IN_Commands(void)
ptr[ev->devid].delta[1] += ev->mouse.y;
//if we're emulating a cursor, make sure that's updated too.
if (touchcursor < 0 && !vrui.enabled && Key_MouseShouldBeFree())
if (touchcursor < 0 && Key_MouseShouldBeFree())
{
mousecursor_x += ev->mouse.x;
mousecursor_y += ev->mouse.y;
@ -526,7 +521,6 @@ void IN_Commands(void)
case IEV_MOUSEABS:
//Con_Printf("IEV_MOUSEABS %i: %f %f\n", ev->devid, ev->mouse.x, ev->mouse.y);
/*mouse cursors only really work with one pointer*/
if (!vrui.enabled)
if (ev->devid == touchcursor || (touchcursor < 0 && ev->devid < MAXPOINTERS && (ptr[ev->devid].oldpos[0] != ev->mouse.x || ptr[ev->devid].oldpos[1] != ev->mouse.y)))
{
float fl;
@ -663,7 +657,7 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum, float frame
mousemove_x += mx;
mousemove_y += my;
if (!vrui.enabled && Key_MouseShouldBeFree())
if (Key_MouseShouldBeFree())
mx=my=0;
if (mouse->type == M_TOUCH)
@ -773,11 +767,7 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum, float frame
#endif
//if game is not focused, kill any mouse look
if (
#ifdef QUAKESTATS
IN_WeaponWheelAccumulate(pnum, mx, my) ||
#endif
Key_Dest_Has(~kdm_game))
if (Key_Dest_Has(~kdm_game))
{
mx = 0;
my = 0;
@ -1015,14 +1005,14 @@ void IN_MoveJoystick(struct joy_s *joy, float *movements, int pnum, float framet
movements[2] += joy_movesens[2].value * mag*cl_upspeed.value * jstrafe[2];
}
void IN_Move (float *nudgemovements, float *absmovements, int pnum, float frametime)
void IN_Move (float *movements, int pnum, float frametime)
{
int i;
for (i = 0; i < MAXPOINTERS; i++)
IN_MoveMouse(&ptr[i], nudgemovements, pnum, frametime);
IN_MoveMouse(&ptr[i], movements, pnum, frametime);
for (i = 0; i < MAXJOYSTICKS; i++)
IN_MoveJoystick(&joy[i], absmovements, pnum, frametime);
IN_MoveJoystick(&joy[i], movements, pnum, frametime);
}
void IN_JoystickAxisEvent(unsigned int devid, int axis, float value)
@ -1104,17 +1094,17 @@ qboolean IN_SetHandPosition(const char *devname, vec3_t org, vec3_t ang, vec3_t
int dtype;
int seat;
struct vrdevinfo_s *dev;
if (!strncasecmp(devname, "left", 4))
if (!strncmp(devname, "left", 4))
{
seat = atoi(devname+4);
dtype = VRDEV_LEFT;
}
else if (!strncasecmp(devname, "right", 5))
else if (!strncmp(devname, "right", 5))
{
seat = atoi(devname+5);
dtype = VRDEV_RIGHT;
}
else if (!strncasecmp(devname, "head", 4))
else if (!strncmp(devname, "head", 4))
{
seat = atoi(devname+4);
dtype = VRDEV_HEAD;

View File

@ -933,12 +933,6 @@ static unsigned int tbl_sdltoquake[] =
};
#endif
/* stubbed */
qboolean INS_KeyToLocalName(int qkey, char *buf, size_t bufsize)
{
return false;
}
static unsigned int tbl_sdltoquakemouse[] =
{
K_MOUSE1,

View File

@ -709,7 +709,7 @@ void INS_UpdateGrabs(int fullscreen, int activeapp)
grabmouse = false;
else if (fullscreen || in_simulatemultitouch.ival || in_windowed_mouse.value)
{
if (vrui.enabled || !Key_MouseShouldBeFree())
if (!Key_MouseShouldBeFree())
grabmouse = true;
else
grabmouse = false;
@ -2413,28 +2413,6 @@ void INS_TranslateKeyEvent(WPARAM wParam, LPARAM lParam, qboolean down, int qdev
IN_KeyEvent(qdeviceid, down, qcode, unicode);
}
qboolean INS_KeyToLocalName(int qkey, char *buf, size_t bufsize)
{
int i;
*buf = 0; //assume failure
for (i = 0; i < countof(scantokey); i++)
{
if (!scantokey[i])
continue; //not a vkey that quake understands
if (scantokey[i] == qkey)
{
wchar_t tmpbuf[64];
if (GetKeyNameTextW(i<<16, tmpbuf, sizeof(tmpbuf)))
{
narrowen(buf, bufsize, tmpbuf); //yay for utf-8
return true;
}
break;
}
}
return false;
}
#ifndef APPCOMMAND_BROWSER_BACKWARD //added in win2k (but was probably used before that too)
#define APPCOMMAND_BROWSER_BACKWARD 1

View File

@ -32,7 +32,7 @@ void IN_Commands (void);
qboolean IN_MouseDevIsTouch(unsigned int devid); //check if a mouse devid is a touch screen, and thus if we should check the cursor and simulate a ui event or not
int IN_TranslateMButtonPress(unsigned int devid); //allow the touchscreen code to swallow mouse1 as a begin-looking event
void IN_Move (float *nudgemovements, float *absmovements, int pnum, float frametime);
void IN_Move (float *movements, int pnum, float frametime);
// add additional movement on top of the keyboard move cmd
extern cvar_t in_xflip;
@ -68,7 +68,6 @@ void INS_Rumble(int joy, quint16_t amp_low, quint16_t amp_high, quint32_t durati
void INS_RumbleTriggers(int joy, quint16_t left, quint16_t right, quint32_t duration);
void INS_SetLEDColor(int id, vec3_t color);
void INS_SetTriggerFX(int id, const void *data, size_t size);
qboolean INS_KeyToLocalName(int qkey, char *buf, size_t bufsize); //returns a name for the key, according to their keyboard layout AND system language(hopefully), or false on unsupported/error. result may change at any time (eg: tap alt+shift on windows)
#define DEVID_UNSET ~0u

View File

@ -50,6 +50,7 @@ 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
@ -196,8 +197,6 @@ keyname_t keynames[] =
{"MOUSE10", K_MOUSE10},
{"MWHEELUP", K_MWHEELUP},
{"MWHEELDOWN", K_MWHEELDOWN},
{"MWHEELLEFT", K_MWHEELLEFT},
{"MWHEELRIGHT", K_MWHEELRIGHT},
{"LWIN", K_LWIN}, //windows name
{"RWIN", K_RWIN}, //windows name
@ -274,8 +273,6 @@ 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", '\\'},
@ -322,16 +319,6 @@ keyname_t keynames[] =
{"GP_RTHUMB_LEFT", K_GP_RIGHT_THUMB_LEFT},
{"GP_RTHUMB_RIGHT", K_GP_RIGHT_THUMB_RIGHT},
#ifdef Q2BSPS
//kingpin compat
{"ESC", K_ESCAPE},
{"B_SPACE", K_BACKSPACE},
{"U_ARROW", K_UPARROW},
{"D_ARROW", K_DOWNARROW},
{"L_ARROW", K_LEFTARROW},
{"R_ARROW", K_RIGHTARROW},
#endif
#ifndef QUAKETC
//dp compat
{"X360_DPAD_UP", K_GP_DPAD_UP},
@ -1095,14 +1082,6 @@ void Key_DefaultLinkClicked(console_t *con, char *text, char *info)
Cbuf_AddText(va("\nssv \"%s\"\n", c), RESTRICT_LOCAL);
return;
}
#endif
#ifdef SUPPORT_ICE
c = Info_ValueForKey(info, "ice");
if (*c && !strchr(c, ';') && !strchr(c, '\n'))
{
Cbuf_AddText(va("\nnet_ice_show \"%s\"\n", c), RESTRICT_LOCAL);
return;
}
#endif
c = Info_ValueForKey(info, "impulse");
if (*c && !strchr(c, ';') && !strchr(c, '\n'))
@ -1378,35 +1357,49 @@ static const qbyte *builtinemojidata =
static void Key_LoadEmojiList(void)
{
qbyte line[1024];
char nam[64];
char rep[64];
vfsfile_t *f;
char *json = FS_MallocFile("data-by-emoji.json", FS_GAME, NULL); //https://unpkg.com/unicode-emoji-json/data-by-emoji.json
char *json = FS_MallocFile("emoji.json", FS_GAME, NULL); //https://unicodey.com/emoji-data/emoji.json
emojidata = Z_StrDup(builtinemojidata);
if (json)
{
//eg: { "utf8":{"slug":"text_for_emoji"}, ... } (there's a few other keys*/
json_t *root = JSON_Parse(json);
json_t *def;
char nam[64];
for (def = (root?root->child:NULL); def; def = def->sibling)
char *unified;
for (unified = json; (unified = strstr(unified, ",\"unified\":\"")); )
{
int e;
const char *o;
utf8_decode(&e, def->name, &o);
if (*o)
continue; //we can only cope with single codepoints.
if (JSON_GetString(def, "slug", nam+1, sizeof(nam)-2, NULL))
int i = 0;
char *t;
char *sn;
unsigned int u;
unified += 12;
t = unified;
//do
//{
u = strtol(t, &t, 16);
i += utf8_encode(rep+i, u, countof(rep)-i);
//} while (i < countof(rep) && *t++ == '-');
if (*t!='\"')
continue;
rep[i] = 0;
sn = strstr(unified, "\"short_names\":[");
if (sn)
{
nam[0] = ':';
Q_strncatz(nam, ":", sizeof(nam));
line[0] = strlen(nam);
line[1] = strlen(def->name);
strcpy(line+2, nam);
strcpy(line+2+line[0], def->name);
Z_StrCat((char**)&emojidata, line);
sn += 15;
while (sn && *sn == '\"')
{
sn = COM_ParseTokenOut(sn, NULL, nam+1, sizeof(nam)-1, NULL);
nam[0] = ':';
Q_strncatz(nam, ":", sizeof(nam));
line[0] = strlen(nam);
line[1] = strlen(rep);
strcpy(line+2, nam);
strcpy(line+2+line[0], rep);
Z_StrCat((char**)&emojidata, line);
}
}
}
JSON_Destroy(root);
FS_FreeFile(json);
}
@ -1875,15 +1868,6 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
return true;
}
if (key == K_GP_BACK)
{
Key_Dest_Remove(kdm_console);
Key_Dest_Remove(kdm_cwindows);
if (!cls.state && !Key_Dest_Has(~kdm_game))
M_ToggleMenu_f ();
return true;
}
if ((key == K_MOUSE1 || key == K_MOUSE2))
{
int olddown[2] = {con->mousedown[0],con->mousedown[1]};
@ -2459,39 +2443,6 @@ const char *Key_KeynumToString (int keynum, int modifier)
}
}
const char *Key_KeynumToLocalString (int keynum, int modifier)
{
const char *r;
#if defined(_WIN32) || (defined(__linux__)&&!defined(NO_X11)) //not defined in all targets yet...
static char tmp[64];
if (INS_KeyToLocalName(keynum, tmp, sizeof(tmp)))
r = tmp;
else
#endif
r = Key_KeynumToStringRaw(keynum);
if (r[0] == '<' && r[1])
modifier = 0; //would be too weird.
switch(modifier)
{
case KEY_MODIFIER_CTRL|KEY_MODIFIER_ALT|KEY_MODIFIER_SHIFT:
return va("Ctrl+Alt+Shift+%s", r);
case KEY_MODIFIER_ALT|KEY_MODIFIER_SHIFT:
return va("Alt+Shift+%s", r);
case KEY_MODIFIER_CTRL|KEY_MODIFIER_SHIFT:
return va("Ctrl+Shift+%s", r);
case KEY_MODIFIER_CTRL|KEY_MODIFIER_ALT:
return va("Ctrl+Alt+%s", r);
case KEY_MODIFIER_CTRL:
return va("Ctrl+%s", r);
case KEY_MODIFIER_ALT:
return va("Alt+%s", r);
case KEY_MODIFIER_SHIFT:
return va("Shift+%s", r);
default:
return r; //no modifier or a bindmap
}
}
/*
===================
Key_SetBinding
@ -2827,6 +2778,7 @@ void Key_WriteBindings (vfsfile_t *f)
}
}
/*
===================
Key_Init
@ -2899,6 +2851,32 @@ 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
//
@ -2997,7 +2975,7 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down
return;
#endif
#ifdef VM_CG
if (q3 && q3->cg.KeyPressed(key, unicode, down))
if (CG_KeyPress(key, unicode, down))
return;
#endif
}

View File

@ -104,11 +104,11 @@ typedef enum {
K_KP_STAR,
K_KP_EQUALS,
K_MOUSE1, //aka left
K_MOUSE2, //aka right
K_MOUSE3, //aka middle
K_MOUSE4, //aka back
K_MOUSE5, //aka forward
K_MOUSE1,
K_MOUSE2,
K_MOUSE3,
K_MOUSE4,
K_MOUSE5,
K_MWHEELDOWN,
K_MWHEELUP,
@ -210,10 +210,6 @@ typedef enum {
K_MOUSE9,
K_MOUSE10,
/*FIXME*/
#define K_MWHEELLEFT K_MOUSE9
#define K_MWHEELRIGHT K_MOUSE10
/* spare joystick button presses */
K_JOY_UP,
K_JOY_DOWN,

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|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.
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.
#else
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.
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.
#endif
#define INSTALLEDFILES "installed.lst" //the file that resides in the quakedir (saying what's installed).
@ -131,7 +131,7 @@ typedef struct package_s {
char *mirror[MAXMIRRORS]; //FIXME: move to two types of dep...
char gamedir[16];
enum fs_relative fsroot; //FS_BINARYPATH or FS_ROOT _ONLY_
char version[24];
char version[16];
char *arch;
char *qhash;
char *packprefix; //extra weirdness to skip embedded gamedirs or force extra maps/ nesting
@ -198,10 +198,6 @@ static char *manifestpackages; //metapackage named by the manicfest.
static char *declinedpackages; //metapackage named by the manicfest.
static int domanifestinstall; //SECURITY_MANIFEST_*
#ifdef PLUGINS
static int pluginsadded; //so we only show prompts for new externally-installed plugins once, instead of every time the file is reloaded.
#endif
#ifdef WEBCLIENT
static struct
{
@ -245,7 +241,6 @@ static struct pm_source_s
#define SRCFL_ENABLED (1u<<6) //source was explicitly enabled.
#define SRCFL_PROMPTED (1u<<7) //source was explicitly enabled.
#define SRCFL_ONCE (1u<<8) //autoupdates are disabled, but the user is viewing packages anyway. enabled via a prompt.
#define SRCFL_UNSAFE (1u<<9) //ignore signing requirements.
unsigned int flags;
struct dl_download *curdl; //the download context
@ -315,10 +310,6 @@ static void PM_FreePackage(package_t *p)
Z_Free(p->previewimage);
Z_Free(p->qhash);
Z_Free(p->arch);
Z_Free(p->packprefix);
Z_Free(p->filesha1);
Z_Free(p->filesha512);
Z_Free(p->signature);
Z_Free(p);
}
@ -541,10 +532,6 @@ static void PM_ValidatePackage(package_t *p)
if (!(p->flags & (DPF_NATIVE|DPF_CACHED)))
Con_Printf("WARNING: %s (%s) no longer exists\n", p->name, n);
}
//if no files were present, unmark it.
if (!(p->flags & (DPF_NATIVE|DPF_CACHED)))
p->flags &= ~DPF_ENABLED;
}
else
{
@ -994,7 +981,6 @@ static void PM_AddSubListModule(void *module, plugupdatesourcefuncs_t *funcs, co
Z_Free(pm_source[i].prefix);
pm_source[i].prefix = Z_StrDup(prefix);
}
pm_source[i].flags |= flags & SRCFL_UNSAFE;
break;
}
}
@ -1255,7 +1241,7 @@ static const char *PM_ParsePackage(struct packagesourceinfo_s *source, const cha
Z_StrDupPtr(&p->signature, val);
else
{
Con_DPrintf("Unknown package property \"%s\"\n", key);
Con_DPrintf("Unknown package property\n");
}
}
@ -1409,7 +1395,7 @@ static qboolean PM_ParsePackageList(const char *f, unsigned int parseflags, cons
if (!f)
return forcewrite;
source.validated = (parseflags & (DPF_ENABLED|DPF_SIGNATUREACCEPTED))?VH_CORRECT/*FIXME*/:VH_UNSUPPORTED;
source.validated = (parseflags & DPF_ENABLED)?VH_CORRECT/*FIXME*/:VH_UNSUPPORTED;
Q_strncpyz(source.gamedir, FS_GetGamedir(false), sizeof(source.gamedir));
if (url)
@ -1642,19 +1628,8 @@ 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, qboolean blocked))
void PM_EnumeratePlugins(void (*callback)(const char *name))
{
package_t *p;
struct packagedep_s *d;
@ -1670,10 +1645,7 @@ void PM_EnumeratePlugins(void (*callback)(const char *name, qboolean blocked))
if (d->dtype == DEP_FILE)
{
if (!Q_strncasecmp(d->name, PLUGINPREFIX, strlen(PLUGINPREFIX)))
{
qboolean blocked = PM_NameIsInStrings(manifestpackages, va("!%s", p->name));
callback(d->name, blocked);
}
callback(d->name);
}
}
}
@ -1721,7 +1693,7 @@ static qboolean QDECL Host_StubClose (struct vfsfile_s *file)
{
return true;
}
static char *PM_GetMetaTextFromFile(vfsfile_t *file, const char *filename, char *qhash, size_t hashsize) //seeks, but does not close.
static char *PM_GetMetaTextFromFile(vfsfile_t *file, char *filename, char *qhash, size_t hashsize) //seeks, but does not close.
{
qboolean (QDECL *OriginalClose) (struct vfsfile_s *file) = file->Close; //evilness
searchpathfuncs_t *archive;
@ -1736,8 +1708,6 @@ static char *PM_GetMetaTextFromFile(vfsfile_t *file, const char *filename, char
vfsfile_t *metafile = NULL;
if (archive->FindFile(archive, &loc, "fte.meta", NULL))
metafile = archive->OpenVFS(archive, &loc, "rb");
else if (archive->FindFile(archive, &loc, "-", NULL)) //lame.
metafile = archive->OpenVFS(archive, &loc, "rb");
if (metafile)
{
size_t sz = VFS_GETLEN(metafile);
@ -1815,10 +1785,6 @@ void *PM_GeneratePackageFromMeta(vfsfile_t *file, char *fname, size_t fnamesize,
static qboolean PM_FileInstalled_Internal(const char *package, const char *category, const char *title, const char *filename, enum fs_relative fsroot, unsigned pkgflags, void *metainfo, qboolean enable)
{
package_t *p;
char *dlcache, *end;
if (!*filename)
return false; //wtf?
if (metainfo)
{
@ -1834,6 +1800,7 @@ static qboolean PM_FileInstalled_Internal(const char *package, const char *categ
{
p = Z_Malloc(sizeof(*p));
p->priority = PM_DEFAULTPRIORITY;
p->fsroot = fsroot;
strcpy(p->version, "?" "?" "?" "?");
}
@ -1841,59 +1808,15 @@ static qboolean PM_FileInstalled_Internal(const char *package, const char *categ
p->deps->dtype = DEP_FILE;
strcpy(p->deps->name, filename);
dlcache = strstr(p->deps->name+1, "/dlcache/");
if (dlcache)
{
memmove(dlcache+1, dlcache+9, strlen(dlcache+9)+1);
dlcache = (char*)(COM_GetFileExtension(p->deps->name, NULL));
if (dlcache[0] == '.' && dlcache[1] && *COM_GetFileExtension(p->deps->name, dlcache))
{
unsigned int qhash = strtoul(dlcache+1, &end, 16);
if (!*end) //reached the end of the name?...
{
p->qhash = Z_StrDupf("%#x", qhash); //that looks like a qhash!
*dlcache = 0; //strip it from the name.
}
}
}
if (fsroot == FS_PUBGAMEONLY)
{
Q_strncpyz(p->gamedir, FS_GetGamedir(true), sizeof(p->gamedir));
p->fsroot = FS_ROOT;
}
else if (fsroot == FS_ROOT && pkgflags)
{
dlcache = strchr(p->deps->name+1, '/');
if (dlcache)
{
*dlcache++ = 0;
Q_strncpyz(p->gamedir, p->deps->name, sizeof(p->gamedir));
memmove(p->deps->name, dlcache, strlen(dlcache)+1);
}
p->fsroot = FS_ROOT;
}
else
p->fsroot = fsroot;
if (pkgflags&DPF_PLUGIN)
{
if (strcmp(p->version, STRINGIFY(SVNREVISION)))
enable = false;
if (!p->arch)
p->arch = Z_StrDup(THISARCH);
Z_Free(p->qhash); //don't get confused.
p->qhash = NULL;
}
else
pkgflags |= DPF_FORGETONUNINSTALL;
p->arch = Z_StrDup(THISARCH);
if (!p->name || !*p->name)
p->name = Z_StrDup(package);
if (!p->title || !*p->title)
p->title = Z_StrDup(title);
if (!p->category || !*p->category)
p->category = Z_StrDup(category);
p->flags = pkgflags|DPF_NATIVE;
p->flags = pkgflags|DPF_NATIVE|DPF_FORGETONUNINSTALL;
if (enable)
p->flags |= DPF_USERMARKED|DPF_ENABLED;
@ -1929,8 +1852,6 @@ static int QDECL PM_EnumeratedPlugin (const char *name, qofs_t size, time_t mtim
int len, l, a;
char *dot;
char *pkgname;
char *metainfo = NULL;
vfsfile_t *f;
if (!strncmp(name, PLUGINPREFIX, strlen(PLUGINPREFIX)))
Q_strncpyz(vmname, name+strlen(PLUGINPREFIX), sizeof(vmname));
else
@ -1983,16 +1904,7 @@ static int QDECL PM_EnumeratedPlugin (const char *name, qofs_t size, time_t mtim
return true; //don't include it if its a dupe anyway.
//FIXME: should be checking whether there's a package that provides the file...
f = FS_OpenVFS(name, "rb", FS_BINARYPATH);
if (f)
{
char qhash[16];
metainfo = PM_GetMetaTextFromFile(f, name, qhash, sizeof(qhash));
VFS_CLOSE(f);
}
return PM_FileInstalled_Internal(pkgname, "Plugins/", vmname, name, FS_BINARYPATH, DPF_PLUGIN|DPF_SIGNATUREACCEPTED, metainfo,
return PM_FileInstalled_Internal(pkgname, "Plugins/", vmname, name, FS_BINARYPATH, DPF_PLUGIN, NULL,
#ifdef ENABLEPLUGINSBYDEFAULT
true
#else
@ -2032,7 +1944,6 @@ static void PM_PreparePackageList(void)
//figure out what we've previously installed.
if (fs_manifest && !loadedinstalled)
{
int parm;
qofs_t sz = 0;
char *f = FS_MallocFile(INSTALLEDFILES, FS_ROOT, &sz);
loadedinstalled = true;
@ -2042,36 +1953,31 @@ static void PM_PreparePackageList(void)
PM_WriteInstalledPackages();
BZ_Free(f);
}
parm = COM_CheckParm ("-updatesrc");
if (parm)
//make sure our sources are okay.
if (fs_manifest && fs_manifest->downloadsurl && *fs_manifest->downloadsurl)
{
unsigned int fl = SRCFL_USER;
if (COM_CheckParm ("-unsafe"))
fl |= SRCFL_UNSAFE;
do
{
PM_AddSubList(com_argv[parm+1], NULL, fl); //enable it by default. functionality is kinda broken otherwise.
parm = COM_CheckNextParm ("-updatesrc", parm);
} while (parm && parm < com_argc-1);
}
else if (fs_manifest && fs_manifest->downloadsurl && *fs_manifest->downloadsurl)
{
unsigned int fl = SRCFL_MANIFEST;
char *s = fs_manifest->downloadsurl;
if (fs_manifest->security==MANIFEST_SECURITY_NOT)
fl |= SRCFL_DISABLED; //don't trust it, don't even prompt.
while ((s = COM_Parse(s)))
PM_AddSubList(com_token, NULL, fl); //enable it by default. functionality is kinda broken otherwise.
PM_AddSubList(fs_manifest->downloadsurl, NULL, SRCFL_MANIFEST|SRCFL_DISABLED); //don't trust it, don't even prompt.
else
PM_AddSubList(fs_manifest->downloadsurl, NULL, SRCFL_MANIFEST); //enable it by default. functionality is kinda broken otherwise.
}
#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, &pluginsadded, NULL);
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
}
#endif
}
@ -2191,7 +2097,7 @@ static package_t *PM_FindExactPackage(const char *packagename, const char *arch,
if (*version == '<' && strcmp(p->version, version+1)>=0)
continue;
}
if (!r || strcmp(p->version, r->version)>0)
if (!r || strcmp(r->version, p->version)>0)
r = p;
}
}
@ -2470,6 +2376,18 @@ 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)
{
@ -2487,14 +2405,13 @@ unsigned int PM_MarkUpdates (void)
char *strings = manifestpackages;
while (strings && *strings)
{
qboolean isunwanted = (*tok=='!');
strings = COM_ParseStringSetSep(strings, ';', tok+isunwanted, sizeof(tok));
strings = COM_ParseStringSetSep(strings, ';', tok, sizeof(tok));
if (PM_NameIsInStrings(declinedpackages, tok))
continue;
p = PM_MarkedPackage(tok, DPF_MARKED);
if (!p)
{
if (PM_NameIsInStrings(declinedpackages, tok))
continue;
p = PM_FindPackage(tok);
if (p)
{
@ -2502,11 +2419,6 @@ 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++;
}
@ -2687,11 +2599,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
PM_ParsePackageList(f, 0, dl->url, pm_source[listidx].prefix);
PM_ParsePackageList(f, 0, dl->url, pm_source[listidx].prefix);
PM_ResortPackages();
}
else if (dl->replycode == HTTP_DNSFAILURE)
@ -2774,24 +2682,16 @@ static void PM_ListDownloaded(struct dl_download *dl)
static void PM_Plugin_Source_Finished(void *ctx, vfsfile_t *f)
{
struct pm_source_s *src = ctx;
size_t idx = src-pm_source;
if (idx < pm_numsources && ctx == &pm_source[idx])
COM_AssertMainThread("PM_Plugin_Source_Finished");
if (!src->curdl)
{
COM_AssertMainThread("PM_Plugin_Source_Finished");
if (!src->curdl)
{
struct dl_download dl;
dl.file = f;
dl.status = DL_FINISHED;
dl.user_num = src-pm_source;
dl.url = src->url;
src->curdl = &dl;
PM_ListDownloaded(&dl);
}
}
else
{
Con_Printf("PM_Plugin_Source_Finished: stale\n");
struct dl_download dl;
dl.file = f;
dl.status = DL_FINISHED;
dl.user_num = src-pm_source;
dl.url = src->url;
src->curdl = &dl;
PM_ListDownloaded(&dl);
}
VFS_CLOSE(f);
}
@ -2840,7 +2740,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", true);
Menu_Prompt(PM_AllowPackageListQuery_Callback, NULL, "Query updates list?\n", "Okay", NULL, "Nope");
return;
}
#else
@ -2891,13 +2791,10 @@ static void PM_UpdatePackageList(qboolean autoupdate, int retry)
}
}
}
#endif
if (autoupdate)
{
#ifdef WEBCLIENT
doautoupdate = 0;
#endif
if (PM_MarkUpdates())
{
#ifdef DOWNLOADMENU
@ -2908,6 +2805,7 @@ static void PM_UpdatePackageList(qboolean autoupdate, int retry)
PM_PrintChanges();
}
}
#endif
}
qboolean PM_RegisterUpdateSource(void *module, plugupdatesourcefuncs_t *funcs)
@ -3309,16 +3207,16 @@ static void PM_PackageEnabled(package_t *p)
}
#ifndef HAVE_CLIENT
#define Menu_Prompt(cb,ctx,msg,yes,no,cancel,highpri) Con_Printf(CON_WARNING msg "\n")
#define Menu_Prompt(cb,ctx,msg,yes,no,cancel) 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, true);
Menu_Prompt(NULL, NULL, "Engine binary updated.\nRestart to use.", NULL, NULL, NULL);
}
else
Menu_Prompt(NULL, NULL, "Engine update failed.\nManual update required.", NULL, NULL, NULL, true);
Menu_Prompt(NULL, NULL, "Engine update failed.\nManual update required.", NULL, NULL, NULL);
}
#endif
}
@ -3700,7 +3598,7 @@ static void QDECL HashFile_Flush (struct vfsfile_s *file)
}
static qboolean QDECL HashFile_Close (struct vfsfile_s *file)
{
qbyte digest[DIGEST_MAXSIZE];
qbyte digest[256];
hashfile_t *f = (hashfile_t*)file;
if (!VFS_CLOSE(f->f))
f->fail = true; //something went wrong.
@ -3716,23 +3614,14 @@ static qboolean QDECL HashFile_Close (struct vfsfile_s *file)
}
else if (memcmp(digest, f->need, f->hashfunc->digestsize))
{
qbyte base64[(DIGEST_MAXSIZE*2)+16];
qbyte base64[512];
Con_Printf("Invalid hash for downloaded file %s, try again later?\n", f->fname);
if (f->hashfunc == &hash_sha1)
{
base64[Base16_EncodeBlock(digest, f->hashfunc->digestsize, base64, sizeof(base64)-1)] = 0;
Con_Printf("%s vs ", base64);
base64[Base16_EncodeBlock(f->need, f->hashfunc->digestsize, base64, sizeof(base64)-1)] = 0;
Con_Printf("%s\n", base64);
}
else
{
base64[Base64_EncodeBlock(digest, f->hashfunc->digestsize, base64, sizeof(base64)-1)] = 0;
Con_Printf("%s vs ", base64);
base64[Base64_EncodeBlock(f->need, f->hashfunc->digestsize, base64, sizeof(base64)-1)] = 0;
Con_Printf("%s\n", base64);
}
Base64_EncodeBlock(digest, f->hashfunc->digestsize, base64, sizeof(base64)-1);
base64[sizeof(base64)-1] = 0;
Con_Printf("%s vs", base64);
Base64_EncodeBlock(f->need, f->hashfunc->digestsize, base64, sizeof(base64)-1);
Con_Printf("%s\n", base64);
f->fail = true;
}
@ -4386,7 +4275,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", true);
Menu_Prompt(PM_PromptApplyChanges_Callback, NULL, "An update is already in progress\nPlease wait\n", NULL, NULL, "Cancel");
return;
}
pkg_updating = true;
@ -4394,7 +4283,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", true);
Menu_Prompt(PM_PromptApplyDecline_Callback, NULL, text, NULL, "Confirm", "Cancel");
else
{
strcpy(text, "Apply the following changes?\n\n");
@ -4406,7 +4295,7 @@ static void PM_PromptApplyChanges(void)
#endif
}
else
Menu_Prompt(PM_PromptApplyChanges_Callback, NULL, text, "Apply", NULL, "Cancel", true);
Menu_Prompt(PM_PromptApplyChanges_Callback, NULL, text, "Apply", NULL, "Cancel");
}
}
#endif
@ -4504,7 +4393,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", true);
Menu_Prompt(PM_AddSubList_Callback, Z_StrDup(Cmd_Argv(2)), va("Add updates source?\n%s", Cmd_Argv(2)), "Confirm", NULL, "Cancel");
#else
PM_AddSubList(Cmd_Argv(2), "", SRCFL_USER|SRCFL_ENABLED);
PM_WriteInstalledPackages();
@ -5181,7 +5070,7 @@ qboolean PM_CanInstall(const char *packagename)
{
return false;
}
void PM_EnumeratePlugins(void (*callback)(const char *name, qboolean blocked))
void PM_EnumeratePlugins(void (*callback)(const char *name))
{
}
void PM_ManifestPackage(const char *metaname, int security)
@ -5220,17 +5109,6 @@ static void MD_Draw (int x, int y, struct menucustom_s *c, struct emenu_s *m)
if (c->dint != downloadablessequence)
return; //probably stale
#ifdef WEBCLIENT
if (allowphonehome == -2)
{
allowphonehome = false;
#ifdef HAVE_CLIENT
Menu_Prompt(PM_AllowPackageListQuery_Callback, NULL, "Query updates list?\n", "Okay", NULL, "Nope", true);
#endif
}
#endif
p = c->dptr;
if (p)
{
@ -5267,16 +5145,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, S_COLOR_GREEN"GET", 48, 2, false);
Draw_FunStringWidth (x, y, "GET", 48, 2, false);
else if (p->flags & (DPF_PRESENT))
Draw_FunStringWidth (x, y, S_COLOR_GREEN"USE", 48, 2, false);
Draw_FunStringWidth (x, y, "USE", 48, 2, false);
else
Draw_FunStringWidth (x, y, S_COLOR_GREEN"GET", 48, 2, false);
Draw_FunStringWidth (x, y, "GET", 48, 2, false);
}
else
{ //DPF_MARKED|DPF_ENABLED:
if (p->flags & DPF_PURGE)
Draw_FunStringWidth (x, y, S_COLOR_GREEN"GET", 48, 2, false); //purge and reinstall.
Draw_FunStringWidth (x, y, "GET", 48, 2, false); //purge and reinstall.
else if (p->flags & DPF_CORRUPT)
Draw_FunStringWidth (x, y, "?""?""?", 48, 2, false);
else
@ -5288,20 +5166,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, S_COLOR_GREEN"^hGET", 48, 2, false);
Draw_FunStringWidth (x, y, "^hGET", 48, 2, false);
else if (p->flags & (DPF_PRESENT))
Draw_FunStringWidth (x, y, S_COLOR_GREEN"^hUSE", 48, 2, false);
Draw_FunStringWidth (x, y, "^hUSE", 48, 2, false);
else
Draw_FunStringWidth (x, y, S_COLOR_GREEN"^hGET", 48, 2, false);
Draw_FunStringWidth (x, y, "^hGET", 48, 2, false);
}
else
{ //DPF_MARKED|DPF_ENABLED:
if (p->flags & DPF_PURGE)
Draw_FunStringWidth (x, y, S_COLOR_GREEN"^hGET", 48, 2, false); //purge and reinstall.
Draw_FunStringWidth (x, y, "^hGET", 48, 2, false); //purge and reinstall.
else if (p->flags & DPF_CORRUPT)
Draw_FunStringWidth (x, y, "?""?""?", 48, 2, false);
else
@ -5317,7 +5195,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, S_COLOR_RED"DEL", 48, 2, false); //purge
Draw_FunStringWidth (x, y, "DEL", 48, 2, false); //purge
else if (p->flags & DPF_HIDDEN)
Draw_FunStringWidth (x, y, "---", 48, 2, false);
else if (p->flags & DPF_CORRUPT)
@ -5338,9 +5216,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, S_COLOR_RED"DEL", 48, 2, false);
Draw_FunStringWidth (x, y, "DEL", 48, 2, false);
else
Draw_FunStringWidth (x, y, S_COLOR_YELLOW"DIS", 48, 2, false);
Draw_FunStringWidth (x, y, "DIS", 48, 2, false);
}
}
}
@ -6023,28 +5901,22 @@ static void MD_Download_UpdateStatus(struct emenu_s *m)
b->rightalign = false;
y+=8;
#ifdef WEBCLIENT
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;
}
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, "Undo Changes", MD_RevertUpdates);
b = MC_AddCommand(m, 48, 320-16, y, "Revert Updates", MD_RevertUpdates);
b->rightalign = false;
b->common.tooltip = "Reset selection to only those packages that are currently installed.";
y+=8;
#ifdef WEBCLIENT
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;
}
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;
@ -6170,7 +6042,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", true);
Menu_Prompt(PM_ConfirmSource, Z_StrDup(pm_source[i].url), msg, "Enable", "Configure", "Later");
pm_source[i].flags |= SRCFL_PROMPTED;
}
break;
@ -6179,7 +6051,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", true);
Menu_Prompt(PM_AutoUpdateQuery, NULL, "Configure update sources now?", "View", NULL, "Later");
}*/
}
#endif

View File

@ -2,7 +2,6 @@
#include "quakedef.h"
#include "shader.h"
#include "fs.h"
//draws the size specified, plus a little extra border (about 8 pixels in each direction, could be more though).
//size is in vpixels.
@ -217,13 +216,10 @@ mpic_t *QBigFontWorks(void)
if (p && R_GetShaderSizes(p, NULL, NULL, true))
return p;
}
return (mpic_t*)font_menu;
return NULL;
}
void Draw_BigFontString(int x, int y, const char *text)
{
conchar_t *w, buffer[256];
unsigned int codeflags, oldflags=CON_WHITEMASK, codepoint;
int sx, sy;
mpic_t *p;
p = QBigFontWorks();
@ -232,77 +228,38 @@ void Draw_BigFontString(int x, int y, const char *text)
Draw_AltFunString(x, y + (20-8)/2, text);
return;
}
if (p == (mpic_t*)font_menu)
{
Draw_FunStringWidthFont(font_menu, x, y, text, vid.width-x, false, false);
return;
}
{ //a hack for scaling
p->width = 20*8;
p->height = 20*8;
}
COM_ParseFunString(oldflags, text, buffer, sizeof(buffer), false);
for (w = buffer; *w; )
while(*text)
{
w = Font_Decode(w, &codeflags, &codepoint);
if (codepoint >= 0xe020 && codepoint <= 0xe07f)
codepoint &= 0x00ff; //convert to quake glyph to unicode/ascii...
if (codeflags != oldflags)
if (*text >= 'A' && *text <= 'Z')
{
vec4_t rgba;
unsigned int col;
oldflags = codeflags;
col = (codeflags&CON_FGMASK)>>CON_FGSHIFT;
rgba[0] = consolecolours[col].fr;
rgba[1] = consolecolours[col].fg;
rgba[2] = consolecolours[col].fb;
if(codeflags & CON_HALFALPHA)
rgba[3] = 0.5;
else
rgba[3] = 1;
if (vid.flags&VID_SRGBAWARE)
{
rgba[0] = M_SRGBToLinear(rgba[0], 1);
rgba[1] = M_SRGBToLinear(rgba[1], 1);
rgba[2] = M_SRGBToLinear(rgba[2], 1);
}
if (codeflags & CON_BLINKTEXT)
{
float a = (sin(realtime*3)+1)*0.3 + 0.4;
VectorScale(rgba, a, rgba);
}
R2D_ImageColours(rgba[0], rgba[1], rgba[2], rgba[3]);
sx = ((*text-'A')%8)*(p->width>>3);
sy = ((*text-'A')/8)*(p->height>>3);
}
if (codepoint >= 'A' && codepoint <= 'Z')
else if (*text >= 'a' && *text <= 'z')
{
sx = ((codepoint-'A')%8)*(p->width>>3);
sy = ((codepoint-'A')/8)*(p->height>>3);
sx = ((*text-'a'+26)%8)*(p->width>>3);
sy = ((*text-'a'+26)/8)*(p->height>>3);
}
else if (codepoint >= 'a' && codepoint <= 'z')
else if (*text >= '0' && *text <= '1')
{
sx = ((codepoint-'a'+26)%8)*(p->width>>3);
sy = ((codepoint-'a'+26)/8)*(p->height>>3);
sx = ((*text-'0'+26*2)%8)*(p->width>>3);
sy = ((*text-'0'+26*2)/8)*(p->height>>3);
}
else if (codepoint >= '0' && codepoint <= '1')
else if (*text == ':')
{
sx = ((codepoint-'0'+26*2)%8)*(p->width>>3);
sy = ((codepoint-'0'+26*2)/8)*(p->height>>3);
sx = ((*text-'0'+26*2+10)%8)*(p->width>>3);
sy = ((*text-'0'+26*2+10)/8)*(p->height>>3);
}
else if (codepoint == ':')
else if (*text == '/')
{
sx = ((codepoint-'0'+26*2+10)%8)*(p->width>>3);
sy = ((codepoint-'0'+26*2+10)/8)*(p->height>>3);
}
else if (codepoint == '/')
{
sx = ((codepoint-'0'+26*2+11)%8)*(p->width>>3);
sy = ((codepoint-'0'+26*2+11)/8)*(p->height>>3);
sx = ((*text-'0'+26*2+11)%8)*(p->width>>3);
sy = ((*text-'0'+26*2+11)/8)*(p->height>>3);
}
else// if (*text <= ' ')
{
@ -312,8 +269,8 @@ void Draw_BigFontString(int x, int y, const char *text)
if(sx>=0)
R2D_SubPic(x, y, 20, 20, p, sx, sy, 20*8, 20*8);
x+=(p->width>>3);
text++;
}
R2D_ImageColours(1,1,1,1);
}
char *menudotstyle;
@ -408,12 +365,6 @@ static qboolean M_MouseMoved(emenu_t *menu)
if (menu->mouseitem != option)
{
menu->mouseitem = option;
if (vrui.enabled)
{
menu->selecteditem = option;
if (menu->cursoritem)
menu->cursoritem->common.posy = menu->selecteditem->common.posy;
}
menu->tooltiptime = realtime + 1;
MenuTooltipChange(menu, menu->mouseitem->common.tooltip);
}
@ -764,9 +715,6 @@ static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, emenu_t *men
int x = xpos+option->common.posx;
int y = ypos+option->common.posy;
if (!option->edit.slim)
y += (16-8)/2; //fat ones are twice the height on account of the text box's borders.
Draw_FunStringWidth(x, y, option->edit.caption, option->edit.captionwidth, true, !menu->cursoritem && menu->selecteditem == option);
x += option->edit.captionwidth + 3*8;
if (option->edit.slim)
@ -813,7 +761,7 @@ static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, emenu_t *men
Draw_FunString (x + 8, y, "or");
x += 32;
}
keyname = Key_KeynumToLocalString (keys[j], keymods[j]);
keyname = Key_KeynumToString (keys[j], keymods[j]);
Draw_FunString (x, y, keyname);
x += strlen(keyname) * 8;
}
@ -1783,7 +1731,7 @@ static void M_Draw (menu_t *menu)
menu_mousedown = false;
return;
}
if (!vrui.enabled && (!menu_script || scr_con_current))
if ((!menu_script || scr_con_current))
{
if (m->nobacktint || (m->selecteditem && m->selecteditem->common.type == mt_slider && (m->selecteditem->slider.var == &v_gamma || m->selecteditem->slider.var == &v_contrast)))
/*no menu tint if we're trying to adjust gamma*/;
@ -1934,19 +1882,6 @@ void M_MenuPop_f (void)
Menu_Unlink(topmenu, false);
}
menubutton_t *M_FindButton(emenu_t *menu, const char *command)
{
menuoption_t *o;
for (o = menu->options; o; o = o->common.next)
{
if (( o->common.type == mt_button
||o->common.type == mt_qbuttonbigfont
||o->common.type == mt_hexen2buttonbigfont)
&& !strcmp(o->button.command, command))
return (menubutton_t*)o;
}
return NULL;
}
static menuoption_t *M_NextItem(emenu_t *m, menuoption_t *old)
{
menuoption_t *op = m->options;
@ -2040,7 +1975,7 @@ void M_Complex_Key(emenu_t *currentmenu, int key, int unicode)
if (currentmenu->key(key, currentmenu))
return;
if (currentmenu->selecteditem && currentmenu->selecteditem->common.type == mt_custom && (key == K_DOWNARROW || key == K_KP_DOWNARROW || key == K_GP_DPAD_DOWN || key == K_GP_A || key == K_GP_B || key == K_UPARROW || key == K_KP_UPARROW || key == K_GP_DPAD_UP || key == K_TAB || key == K_MWHEELUP || key == K_MWHEELDOWN || key == K_PGUP || key == K_PGDN))
if (currentmenu->selecteditem && currentmenu->selecteditem->common.type == mt_custom && (key == K_DOWNARROW || key == K_KP_DOWNARROW || key == K_GP_DPAD_DOWN || key == K_GP_A || key == K_GP_B || key == K_UPARROW || key == K_KP_UPARROW || key == K_GP_DPAD_UP || key == K_TAB || key == K_MWHEELUP || key == K_MWHEELDOWN))
if (currentmenu->selecteditem->custom.key)
if (currentmenu->selecteditem->custom.key(&currentmenu->selecteditem->custom, currentmenu, key, unicode))
return;
@ -2085,8 +2020,7 @@ void M_Complex_Key(emenu_t *currentmenu, int key, int unicode)
switch(key)
{
case K_MOUSE2: //right
case K_MOUSE4: //back
case K_MOUSE2:
case K_ESCAPE:
case K_GP_BACK:
//remove
@ -2191,6 +2125,7 @@ void M_Complex_Key(emenu_t *currentmenu, int key, int unicode)
}
case K_MOUSE1:
case K_MOUSE3:
case K_MOUSE4:
case K_MOUSE5:
case K_MOUSE6:
case K_MOUSE7:
@ -2298,9 +2233,9 @@ static int M_Main_AddExtraOptions(emenu_t *mainm, int y)
if (Cmd_Exists("menu_download"))
{
#ifdef WEBCLIENT
MC_AddConsoleCommandQBigFont(mainm, 72, y, "^bUpdates ", "menu_download\n"); y += 20;
MC_AddConsoleCommandQBigFont(mainm, 72, y, "Updates ", "menu_download\n"); y += 20;
#else
MC_AddConsoleCommandQBigFont(mainm, 72, y, "^bPackages ", "menu_download\n"); y += 20;
MC_AddConsoleCommandQBigFont(mainm, 72, y, "Packages ", "menu_download\n"); y += 20;
#endif
}
if (Cmd_Exists("menu_mods"))
@ -2312,32 +2247,6 @@ static int M_Main_AddExtraOptions(emenu_t *mainm, int y)
return y;
}
void MC_Main_Predraw(emenu_t *menu)
{
extern cvar_t m_preset_chosen;
menubutton_t *b;
b = M_FindButton(menu, "menu_options\n");
if (b && b->text[0] && b->text[1])
{
qboolean flash =
#ifdef PACKAGEMANAGER
PM_AreSourcesNew(false)||
#endif
!m_preset_chosen.ival;
b->text = (char*)(b+1) + (flash?0:2);
}
#ifdef PACKAGEMANAGER
b = M_FindButton(menu, "menu_download\n");
if (b && b->text[0] && b->text[1])
{
qboolean flash = PM_AreSourcesNew(false);
b->text = (char*)(b+1) + (flash?0:2);
}
#endif
}
void M_Menu_Main_f (void)
{
extern cvar_t m_helpismedia;
@ -2404,7 +2313,7 @@ void M_Menu_Main_f (void)
MC_AddPicture(mainm, 0, 4, 38, 166, "pics/m_main_plaque");
MC_AddPicture(mainm, 0, 173, 36, 42, "pics/m_main_logo");
#if defined(HAVE_SERVER) && defined(Q2SERVER)
#ifndef CLIENTONLY
MC_AddSelectablePicture(mainm, 68, 13, itemheight, "pics/m_main_game");
#endif
MC_AddSelectablePicture(mainm, 68, 53, itemheight, "pics/m_main_multiplayer");
@ -2412,7 +2321,7 @@ void M_Menu_Main_f (void)
MC_AddSelectablePicture(mainm, 68, 133, itemheight, "pics/m_main_video");
MC_AddSelectablePicture(mainm, 68, 173, itemheight, "pics/m_main_quit");
#if defined(HAVE_SERVER) && defined(Q2SERVER)
#ifndef CLIENTONLY
b = MC_AddConsoleCommand (mainm, 68, 320, 13, "", "menu_single\n");
b->common.tooltip = "Singleplayer.";
mainm->selecteditem = (menuoption_t *)b;
@ -2421,8 +2330,9 @@ void M_Menu_Main_f (void)
#endif
b = MC_AddConsoleCommand (mainm, 68, 320, 53, "", "menu_multi\n");
b->common.tooltip = "Multiplayer.";
if (!mainm->selecteditem)
mainm->selecteditem = (menuoption_t *)b;
#ifdef CLIENTONLY
mainm->selecteditem = (menuoption_t *)b;
#endif
b->common.width = 12*20;
b->common.height = itemheight;
b = MC_AddConsoleCommand (mainm, 68, 320, 93, "", "menu_options\n");
@ -2470,7 +2380,7 @@ void M_Menu_Main_f (void)
b->common.width = 12*20;
b->common.height = 20;
y += 20;
b=MC_AddConsoleCommandHexen2BigFont (mainm, 80, y, "^bOptions", "menu_options\n");
b=MC_AddConsoleCommandHexen2BigFont (mainm, 80, y, "Options", "menu_options\n");
b->common.width = 12*20;
b->common.height = 20;
y += 20;
@ -2514,7 +2424,7 @@ void M_Menu_Main_f (void)
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Single ", "menu_single\n"); y += 20;
#endif
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Multiplayer ", "menu_multi\n"); y += 20;
MC_AddConsoleCommandQBigFont (mainm, 72, y,"^bOptions ", "menu_options\n"); y += 20;
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Options ", "menu_options\n"); y += 20;
if (m_helpismedia.value)
{MC_AddConsoleCommandQBigFont(mainm, 72, y, "Media ", "menu_media\n"); y += 20;}
else
@ -2526,7 +2436,7 @@ void M_Menu_Main_f (void)
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Quit ", "menu_quit\n"); y += 20;
#endif
mainm->cursoritem = (menuoption_t *)MC_AddCursor(mainm, &resel, 54, mainm->selecteditem->common.posy);
mainm->cursoritem = (menuoption_t *)MC_AddCursor(mainm, &resel, 54, 32);
}
}
else
@ -2580,38 +2490,28 @@ void M_Menu_Main_f (void)
M_Main_AddExtraOptions(mainm, 112+20);
mainm->cursoritem = (menuoption_t *)MC_AddCursor(mainm, &resel, 54, mainm->selecteditem->common.posy);
mainm->cursoritem = (menuoption_t *)MC_AddCursor(mainm, &resel, 54, 32);
}
}
if (!mainm)
{
mainm = M_CreateMenu(0);
MC_AddRedText(mainm, 72, 320, 0, "Main Menu", false);
MC_AddRedText(mainm, 16, 170, 0, "MAIN MENU", false);
y = 36;
mainm->selecteditem = (menuoption_t *)
//skip menu_single if we don't seem to have any content.
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Join server", "menu_servers\n"); y += 20;
MC_AddConsoleCommandQBigFont (mainm, 72, y, "^bOptions", "menu_options\n"); y += 20;
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Options", "menu_options\n"); y += 20;
y = M_Main_AddExtraOptions(mainm, y);
MC_AddConsoleCommandQBigFont (mainm, 72, y, "Quit", "menu_quit\n"); y += 20;
mainm->cursoritem = (menuoption_t *)MC_AddCursor(mainm, &resel, 54, mainm->selecteditem->common.posy);
mainm->cursoritem = (menuoption_t *)MC_AddCursor(mainm, &resel, 54, 36);
}
mainm->predraw = MC_Main_Predraw; //disable flashes as appropriate.
//pick a better default option...
b = NULL;
if (!b && !m_preset_chosen.ival)
b = M_FindButton(mainm, "menu_options\n");
if (!b && PM_AreSourcesNew(false))
b = M_FindButton(mainm, "menu_download\n");
if (b)
{
mainm->selecteditem = (menuoption_t*)b;
mainm->cursoritem->common.posy = mainm->selecteditem->common.posy;
}
if (!m_preset_chosen.ival)
M_Menu_Preset_f();
}
int MC_AddBulk(struct emenu_s *menu, menuresel_t *resel, menubulk_t *bulk, int xstart, int xtextend, int y)
@ -2711,13 +2611,14 @@ int MC_AddBulk(struct emenu_s *menu, menuresel_t *resel, menubulk_t *bulk, int x
{
default:
case 0:
y += 4;
control = (union menuoption_s *)MC_AddEditCvar(menu, xleft, xtextend, y, bulk->text, bulk->cvarname, false);
spacing += 4;
break;
case 1:
control = (union menuoption_s *)MC_AddEditCvar(menu, xleft, xtextend, y, bulk->text, bulk->cvarname, true);
break;
}
spacing = control->common.height;
break;
default:
Con_Printf(CON_ERROR "Invalid type in bulk menu!\n");

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