mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-21 19:41:14 +00:00
Many general cleaups and warning fixes.
Console code no longer makes assumptions about con_main Screenshots rework, for screenshot_360, but also some other cleanups. Fixed an issue with beginpolygon (finally). Added per-rtlight style strings. Added cvar to control whether ents will be culled by fog. Added define to disable IPLOG, etc. Added r_editlights cvar and related commands, for whenever csaddon isn't available. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5338 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
398c1afaf9
commit
2ee8387644
102 changed files with 4081 additions and 1630 deletions
138
CMakeLists.txt
138
CMakeLists.txt
|
@ -6,7 +6,7 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
|
||||
cmake_policy(SET CMP0063 NEW)
|
||||
|
||||
PROJECT(fteqw)
|
||||
PROJECT(FTEQuake)
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
engine/common
|
||||
|
@ -35,51 +35,40 @@ set(CMAKE_CXX_VISIBILITY_PRESET hidden)
|
|||
set(CMAKE_C_VISIBILITY_PRESET hidden)
|
||||
|
||||
IF(${CMAKE_VERSION} VERSION_LESS "3.9.0")
|
||||
MESSAGE(STATUS "no LTO - old cmake.")
|
||||
ELSE()
|
||||
IF(NOT ${CMAKE_BUILD_TYPE} MATCHES "Debug")
|
||||
cmake_policy(SET CMP0069 NEW)
|
||||
IF(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
|
||||
#use LTO where possible. reportedly requires cmake 3.9 to actually work
|
||||
INCLUDE(CheckIPOSupported)
|
||||
check_ipo_supported(RESULT result)
|
||||
IF(result)
|
||||
SET(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
|
||||
MESSAGE(STATUS "Using LTO.")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "no LTO - not supported.")
|
||||
ENDIF()
|
||||
ELSE()
|
||||
MESSAGE(STATUS "no LTO - debug.")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
SET(FTE_BUILD_CONFIG ${CMAKE_HOME_DIRECTORY}/engine/common/config_fteqw.h CACHE FILEPATH "Which build config file to use to control supported features.")
|
||||
SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};CONFIG_FILE_NAME=${FTE_BUILD_CONFIG})
|
||||
|
||||
FIND_PACKAGE(ZLIB)
|
||||
IF(NOT ZLIB_FOUND)
|
||||
MESSAGE(WARNING "libz library NOT available. compressed pk3 will not be available.")
|
||||
SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};NO_ZLIB)
|
||||
SET(ZLIB_LIBRARY m)
|
||||
SET(ZLIB_LIBRARIES m)
|
||||
ENDIF()
|
||||
|
||||
FIND_PACKAGE(GnuTLS)
|
||||
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)
|
||||
ENDIF()
|
||||
|
||||
FIND_PACKAGE(ALSA)
|
||||
IF(NOT ALSA_FOUND)
|
||||
MESSAGE(WARNING "asound (alsa) library NOT available.")
|
||||
SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};NO_ALSA)
|
||||
ENDIF()
|
||||
|
||||
FIND_PACKAGE(X11)
|
||||
IF(X11_FOUND)
|
||||
IF (NOT X11_Xcursor_FOUND)
|
||||
SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};NO_X11_CURSOR)
|
||||
MESSAGE(WARNING "Xcursor library NOT available.")
|
||||
ENDIF()
|
||||
ELSE()
|
||||
MESSAGE(WARNING "x11 library NOT available.")
|
||||
SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};NO_X11)
|
||||
SET(ZLIB_LIBRARY )
|
||||
SET(ZLIB_LIBRARIES )
|
||||
ENDIF()
|
||||
|
||||
SET(OpenGL_GL_PREFERENCE LEGACY)
|
||||
FIND_PACKAGE(OpenGL)
|
||||
IF(NOT OpenGL_FOUND)
|
||||
IF(OpenGL_FOUND)
|
||||
SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};GLQUAKE)
|
||||
ELSE()
|
||||
MESSAGE(WARNING "opengl library NOT available. Will depend upon vulkan.")
|
||||
SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};NO_OPENGL)
|
||||
ENDIF()
|
||||
|
@ -104,6 +93,15 @@ ELSE()
|
|||
SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};NO_FREETYPE)
|
||||
ENDIF()
|
||||
|
||||
#FIND_PACKAGE(Vulkan)
|
||||
#IF(Vulkan_FOUND)
|
||||
# INCLUDE_DIRECTORIES( ${Vulkan_INCLUDE_DIRS} )
|
||||
SET(FTE_DEFINES ${FTE_DEFINES};VKQUAKE)
|
||||
#ELSE()
|
||||
# SET(FTE_DEFINES ${FTE_DEFINES};VKQUAKE)
|
||||
# MESSAGE(WARNING "System vulkan headers NOT available.")
|
||||
#ENDIF()
|
||||
|
||||
FIND_LIBRARY(VORBISFILE_LIBRARY NAMES vorbisfile)
|
||||
IF(NOT VORBISFILE_LIBRARY)
|
||||
MESSAGE(WARNING "libvorbisfile library NOT available. Who listens to the bgm anyway?")
|
||||
|
@ -133,7 +131,7 @@ IF(${ANDROID})
|
|||
|
||||
# INCLUDE_DIRECTORIES( ${FREETYPE_INCLUDE_DIRS} )
|
||||
|
||||
SET(FTE_DEFINES ${FTE_DEFINES};ANDROID;GLQUAKE;VKQUAKE;DYNAMIC_LIBPNG;DYNAMIC_LIBJPEG;MULTITHREAD;stricmp=strcasecmp;strnicmp=strncasecmp)
|
||||
SET(FTE_DEFINES ${FTE_DEFINES};ANDROID;VKQUAKE;DYNAMIC_LIBPNG;DYNAMIC_LIBJPEG;MULTITHREAD;stricmp=strcasecmp;strnicmp=strncasecmp)
|
||||
SET(FTE_LIBS android log EGL ${ZLIB_LIBRARIES} m ${CMAKE_DL_LIBS})
|
||||
SET(FTE_ARCH_FILES
|
||||
engine/client/sys_droid.c
|
||||
|
@ -148,8 +146,8 @@ ELSEIF(${WIN32})
|
|||
|
||||
# engine/server/sv_sys_win.c
|
||||
|
||||
SET(FTE_LIBS ${ZLIB_LIBRARIES} ole32 gdi32 wsock32 winmm)
|
||||
SET(FTE_DEFINES ${FTE_DEFINES};GLQUAKE;VKQUAKE;D3D9QUAKE;DYNAMIC_LIBPNG;DYNAMIC_LIBJPEG) #D3D11QUAKE not included.
|
||||
SET(FTE_LIBS ${ZLIB_LIBRARIES} ole32 gdi32 wsock32 winmm dxguid)
|
||||
SET(FTE_DEFINES ${FTE_DEFINES};D3D9QUAKE;D3D11QUAKE;DYNAMIC_LIBPNG;DYNAMIC_LIBJPEG)
|
||||
SET(FTE_ARCH_FILES
|
||||
engine/client/winquake.rc
|
||||
engine/common/sys_win_threads.c
|
||||
|
@ -189,7 +187,32 @@ ELSEIF(${WIN32})
|
|||
)
|
||||
ELSEIF(${UNIX}) #linux(ish)
|
||||
#openbsd will have issues with snd_linux.c
|
||||
SET(FTE_DEFINES ${FTE_DEFINES};GLQUAKE;VKQUAKE;DYNAMIC_LIBPNG;DYNAMIC_LIBJPEG;DYNAMIC_SDL;MULTITHREAD;stricmp=strcasecmp;strnicmp=strncasecmp)
|
||||
|
||||
#linux-only packages
|
||||
FIND_PACKAGE(GnuTLS)
|
||||
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)
|
||||
ENDIF()
|
||||
|
||||
FIND_PACKAGE(ALSA)
|
||||
IF(NOT ALSA_FOUND)
|
||||
MESSAGE(WARNING "asound (alsa) library NOT available.")
|
||||
SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};NO_ALSA)
|
||||
ENDIF()
|
||||
|
||||
FIND_PACKAGE(X11)
|
||||
IF(X11_FOUND)
|
||||
IF (NOT X11_Xcursor_FOUND)
|
||||
SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};NO_X11_CURSOR)
|
||||
MESSAGE(WARNING "Xcursor library NOT available.")
|
||||
ENDIF()
|
||||
ELSE()
|
||||
MESSAGE(WARNING "x11 library NOT available.")
|
||||
SET(FTE_LIB_DEFINES ${FTE_LIB_DEFINES};NO_X11)
|
||||
ENDIF()
|
||||
|
||||
SET(FTE_DEFINES ${FTE_DEFINES};DYNAMIC_LIBPNG;DYNAMIC_LIBJPEG;DYNAMIC_SDL;MULTITHREAD;stricmp=strcasecmp;strnicmp=strncasecmp)
|
||||
SET(FTE_LIBS ${ZLIB_LIBRARIES} m ${CMAKE_DL_LIBS} pthread ${SDL2_LIBRARIES})
|
||||
SET(FTE_ARCH_FILES
|
||||
engine/client/sys_linux.c
|
||||
|
@ -262,7 +285,7 @@ ELSEIF(1) #SDL
|
|||
INCLUDE_DIRECTORIES(${FREETYPE_INCLUDE_DIRS} ${SDL2_INCLUDE_DIRS})
|
||||
|
||||
#SDL2.0.7 supports vulkan, so lets use it.
|
||||
SET(FTE_DEFINES ${FTE_DEFINES};GLQUAKE;VKQUAKE;FTE_SDL;DYNAMIC_LIBPNG;DYNAMIC_LIBJPEG;stricmp=strcasecmp;strnicmp=strncasecmp)
|
||||
SET(FTE_DEFINES ${FTE_DEFINES};FTE_SDL;DYNAMIC_LIBPNG;DYNAMIC_LIBJPEG;stricmp=strcasecmp;strnicmp=strncasecmp)
|
||||
SET(FTE_LIBS ${ZLIB_LIBRARIES} m ${CMAKE_DL_LIBS} ${SDL2_LIBRARIES})
|
||||
SET(FTE_ARCH_FILES
|
||||
engine/client/sys_sdl.c
|
||||
|
@ -519,7 +542,7 @@ SET(FTE_CLIENT_FILES
|
|||
engine/vk/vk_init.c
|
||||
)
|
||||
|
||||
IF(${ANDROID})
|
||||
IF(ANDROID)
|
||||
#android sucks. everything is a library. so we build the engine as a shared library and completely ignore dedicated servers+tools
|
||||
ADD_LIBRARY(ftedroid MODULE
|
||||
${FTE_ARCH_FILES}
|
||||
|
@ -545,6 +568,19 @@ ELSE()
|
|||
SET_TARGET_PROPERTIES(fteqw-sv PROPERTIES COMPILE_DEFINITIONS "SERVERONLY;${FTE_LIB_DEFINES};${FTESV_DEFINES};${FTE_REVISON}")
|
||||
TARGET_LINK_LIBRARIES(fteqw-sv ${FTESV_LIBS})
|
||||
|
||||
ADD_EXECUTABLE(iqmtool
|
||||
iqm/iqm.cpp
|
||||
iqm/iqm.h
|
||||
)
|
||||
SET_TARGET_PROPERTIES(iqmtool PROPERTIES COMPILE_DEFINITIONS "${FTE_REVISON}")
|
||||
|
||||
ADD_EXECUTABLE(httpserver
|
||||
engine/common/fs_stdio.c
|
||||
engine/http/httpserver.c
|
||||
engine/http/iwebiface.c
|
||||
engine/http/ftpserver.c
|
||||
)
|
||||
SET_TARGET_PROPERTIES(httpserver PROPERTIES COMPILE_DEFINITIONS "WEBSERVER;WEBSVONLY;${FTE_REVISON};stricmp=strcasecmp;strnicmp=strncasecmp")
|
||||
|
||||
ADD_EXECUTABLE(fteqcc
|
||||
engine/qclib/qcctui.c
|
||||
|
@ -593,7 +629,7 @@ SET_TARGET_PROPERTIES(qi PROPERTIES PREFIX "fteplug_")
|
|||
|
||||
#Bullet Physics library plugin
|
||||
#FIND_PACKAGE(Bullet)
|
||||
IF (${BULLET_FOUND})
|
||||
IF (BULLET_FOUND)
|
||||
ADD_LIBRARY(bullet MODULE
|
||||
plugins/qvm_api.c
|
||||
plugins/plugin.c
|
||||
|
@ -606,7 +642,7 @@ ENDIF()
|
|||
|
||||
#ODE Physics library plugin
|
||||
#FIND_PACKAGE(ode)
|
||||
IF (${ODE_FOUND})
|
||||
IF (ODE_FOUND)
|
||||
ADD_LIBRARY(ode MODULE
|
||||
plugins/qvm_api.c
|
||||
plugins/plugin.c
|
||||
|
@ -638,7 +674,34 @@ ADD_LIBRARY(irc MODULE
|
|||
SET_TARGET_PROPERTIES(irc PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
|
||||
SET_TARGET_PROPERTIES(irc PROPERTIES PREFIX "fteplug_")
|
||||
|
||||
IF(NOT ${ANDROID})
|
||||
#ffmpeg client plugin. no proper way to detect dependancies right now, so I've gotta try the manual way.
|
||||
FIND_PATH(AVCODEC_INCLUDE_DIR libavcodec/avcodec.h)
|
||||
FIND_PATH(AVFORMAT_INCLUDE_DIR libavformat/avformat.h)
|
||||
FIND_PATH(AVUTIL_INCLUDE_DIR libavutil/avutil.h)
|
||||
FIND_PATH(AVSWSCALE_INCLUDE_DIR libswscale/swscale.h)
|
||||
IF(AVFORMAT_INCLUDE_DIR)
|
||||
FIND_LIBRARY(AVCODEC_LIBRARY avcodec)
|
||||
FIND_LIBRARY(AVFORMAT_LIBRARY avformat)
|
||||
FIND_LIBRARY(AVUTIL_LIBRARY avutil)
|
||||
FIND_LIBRARY(AVSWSCALE_LIBRARY swscale)
|
||||
|
||||
ADD_LIBRARY(ffmpeg MODULE
|
||||
plugins/qvm_api.c
|
||||
plugins/plugin.c
|
||||
plugins/avplug/avaudio.c
|
||||
plugins/avplug/avdecode.c
|
||||
plugins/avplug/avencode.c
|
||||
)
|
||||
TARGET_INCLUDE_DIRECTORIES(ffmpeg PUBLIC ${AVCODEC_INCLUDE_DIR} ${AVFORMAT_INCLUDE_DIR} ${AVUTIL_INCLUDE_DIR} ${AVSWSCALE_INCLUDE_DIR})
|
||||
SET_TARGET_PROPERTIES(ffmpeg PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
|
||||
TARGET_LINK_LIBRARIES(ffmpeg m ${AVFORMAT_LIBRARY} ${AVCODEC_LIBRARY} ${AVUTIL_LIBRARY} ${AVSWSCALE_LIBRARY})
|
||||
SET_TARGET_PROPERTIES(ffmpeg PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
|
||||
SET_TARGET_PROPERTIES(ffmpeg PROPERTIES PREFIX "fteplug_")
|
||||
ELSE()
|
||||
MESSAGE(WARNING "ffmpeg library NOT available. Quake shouldn't be playing fmv anyway.")
|
||||
ENDIF()
|
||||
|
||||
IF(NOT ANDROID)
|
||||
#XMPP/jabber client plugin
|
||||
ADD_LIBRARY(xmpp MODULE
|
||||
plugins/qvm_api.c
|
||||
|
@ -654,5 +717,4 @@ IF(NOT ${ANDROID})
|
|||
SET_TARGET_PROPERTIES(xmpp PROPERTIES PREFIX "fteplug_")
|
||||
ENDIF()
|
||||
|
||||
#ffmpeg plugin
|
||||
#cef plugin
|
||||
|
|
|
@ -40,16 +40,22 @@ BULLETVER=2.87
|
|||
#only limited forms of cross-making is supported
|
||||
#only the following 3 are supported
|
||||
#linux->win32 (FTE_TARGET=win32) RPM Package: "mingw32-gcc", DEB Package: "mingw32"
|
||||
#linux->linux32 (FTE_TARGET=linux32)
|
||||
#linux->linux64 (FTE_TARGET=linux64)
|
||||
#linux->win64 (FTE_TARGET=win64) RPM Package: "mingw32-gcc", DEB Package: "mingw32"
|
||||
#linux->linux 32 (FTE_TARGET=linux32)
|
||||
#linux->linux 64 (FTE_TARGET=linux64)
|
||||
#linux->linux x32 (FTE_TARGET=linuxx32)
|
||||
#linux->linux armhf (FTE_TARGET=linuxarmhf)
|
||||
#linux->linux arm64/aarch64 (FTE_TARGET=linuxarm64)
|
||||
#linux->linux *others* (FTE_TARGET=linux CC=other-gcc)
|
||||
#linux->morphos (FTE_TARGET=morphos)
|
||||
#linux->macosx (FTE_TARGET=macosx) or (FTE_TARGET=macosx_x86)
|
||||
#linux->javascript (FTE_TARGET=web)
|
||||
#linux->nacl (FTE_TARGET=nacl NARCH=x86_64)
|
||||
#linux->nacl (FTE_TARGET=nacl NARCH=x86_64) deprecated.
|
||||
#win32->nacl
|
||||
#linux->droid (make droid)
|
||||
#win32->droid (make droid)
|
||||
#if you are cross compiling, you'll need to use FTE_TARGET=mytarget
|
||||
#note: cross compiling will typically require 'make makelibs FTE_TARGET=mytarget', which avoids installing lots of extra system packages.
|
||||
|
||||
#cygwin's make's paths confuses non-cygwin things
|
||||
RELEASE_DIR=$(BASE_DIR)/release
|
||||
|
@ -86,7 +92,7 @@ endif
|
|||
BRANDFLAGS+=-DCONFIG_FILE_NAME=config_$(FTE_CONFIG).h $(FTE_CONFIG_EXTRA)
|
||||
EXE_NAME=$(FTE_CONFIG)
|
||||
ifeq (,$(findstring DNO_SPEEX,$(FTE_CONFIG_EXTRA)))
|
||||
USE_SPEEX=1
|
||||
USE_SPEEX?=1
|
||||
endif
|
||||
ifeq (,$(findstring DNO_OPUS,$(FTE_CONFIG_EXTRA)))
|
||||
USE_OPUS=1
|
||||
|
@ -395,12 +401,25 @@ ifeq ($(FTE_TARGET),linuxarmhf)
|
|||
CXX=arm-linux-gnueabihf-g++ -marm -march=armv6 -mfpu=vfp -mfloat-abi=hard
|
||||
BITS=armhf
|
||||
endif
|
||||
ifeq ($(FTE_TARGET),linuxarm64)
|
||||
FTE_TARGET=linux
|
||||
CC=aarch64-linux-gnu-gcc
|
||||
CXX=aarch64-linux-gnu-g++
|
||||
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),linuxx32)
|
||||
#note: the x32 abi is still not finished or something.
|
||||
#at the current time, you will need to edit your kernel's commandline to allow this stuff to run
|
||||
#try and use a proper cross-compiler if we can, otherwise fall back on multi-arch.
|
||||
FTE_TARGET=linux
|
||||
ifneq ($(shell which x86_64-linux-gnux32-gcc 2> /dev/null),)
|
||||
CC=x86_64-linux-gnux32-gcc
|
||||
CXX=x86_64-linux-gnux32-g++
|
||||
else
|
||||
CC=gcc -mx32
|
||||
CXX=g++ -mx32
|
||||
endif
|
||||
BITS=x32
|
||||
endif
|
||||
ifeq ($(FTE_TARGET),linux64)
|
||||
|
@ -1351,12 +1370,12 @@ ifneq (,$(findstring linux,$(FTE_TARGET)))
|
|||
SV_LDFLAGS=
|
||||
SV_CFLAGS=$(SERVER_ONLY_CFLAGS) -DMULTITHREAD
|
||||
|
||||
ifneq ("$(wildcard $(/usr/include/wayland-client.h))","")
|
||||
ifneq ("$(wildcard /usr/include/wayland-client.h)","")
|
||||
HAVE_WAYLAND=-DWAYLANDQUAKE
|
||||
else
|
||||
HAVE_WAYLAND=
|
||||
endif
|
||||
ifneq ("$(wildcard $(/usr/include/EGL/egl.h))","")
|
||||
ifneq ("$(wildcard /usr/include/EGL/egl.h)","")
|
||||
HAVE_EGL=-DUSE_EGL
|
||||
else
|
||||
HAVE_EGL=
|
||||
|
|
|
@ -27,7 +27,7 @@ float recdemostart; //keyed to Sys_DoubleTime
|
|||
int demoframe;
|
||||
|
||||
int cls_lastto;
|
||||
int cls_lasttype;
|
||||
static int cls_lasttype;
|
||||
|
||||
void CL_PlayDemo(char *demoname, qboolean usesystempath);
|
||||
void CL_PlayDemoFile(vfsfile_t *f, char *demoname, qboolean issyspath);
|
||||
|
@ -1680,7 +1680,7 @@ static int CL_RecordInitialPlayers(sizebuf_t *buf, int seq, qboolean isnq)
|
|||
}
|
||||
static int CL_RecordInitialStats(sizebuf_t *buf, int seq, qboolean isnq)
|
||||
{
|
||||
int seat, i;
|
||||
size_t seat, i;
|
||||
for (seat = 0; seat < cl.splitclients; seat++)
|
||||
{
|
||||
//higher stats should be 0 and thus not be sent, if not valid.
|
||||
|
@ -1741,7 +1741,7 @@ void CL_Record_f (void)
|
|||
int c;
|
||||
char name[MAX_OSPATH];
|
||||
sizebuf_t buf;
|
||||
char buf_data[MAX_OVERALLMSGLEN];
|
||||
qbyte buf_data[MAX_OVERALLMSGLEN];
|
||||
int n, i;
|
||||
char *s, *p, *fname;
|
||||
extern char gamedirfile[];
|
||||
|
@ -2601,12 +2601,12 @@ void CL_Demo_ClientCommand(char *commandtext)
|
|||
}
|
||||
}
|
||||
|
||||
char qtvhostname[1024];
|
||||
char qtvrequestbuffer[4096];
|
||||
int qtvrequestsize;
|
||||
char qtvrequestcmdbuffer[4096];
|
||||
int qtvrequestcmdsize;
|
||||
vfsfile_t *qtvrequest;
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -125,6 +125,8 @@ void CL_FreeDlights(void)
|
|||
if (cl_dlights)
|
||||
for (i = 0; i < rtlights_max; i++)
|
||||
{
|
||||
if (cl_dlights[i].customstyle)
|
||||
Z_Free(cl_dlights[i].customstyle);
|
||||
if (cl_dlights[i].worldshadowmesh)
|
||||
SH_FreeShadowMesh(cl_dlights[i].worldshadowmesh);
|
||||
|
||||
|
@ -147,11 +149,26 @@ void CL_InitDlights(void)
|
|||
memset(cl_dlights, 0, sizeof(*cl_dlights)*cl_maxdlights);
|
||||
}
|
||||
|
||||
void CL_CloneDlight(dlight_t *dl, dlight_t *src)
|
||||
{
|
||||
char *customstyle = dl->customstyle;
|
||||
void *sm = dl->worldshadowmesh;
|
||||
unsigned int oq = dl->coronaocclusionquery;
|
||||
unsigned int oqr = (dl->key == src->key)?dl->coronaocclusionresult:false;
|
||||
memcpy (dl, src, sizeof(*dl));
|
||||
dl->coronaocclusionquery = oq;
|
||||
dl->coronaocclusionresult = oqr;
|
||||
dl->rebuildcache = true;
|
||||
dl->worldshadowmesh = sm;
|
||||
dl->customstyle = src->customstyle?Z_StrDup(src->customstyle):NULL;
|
||||
Z_Free(customstyle);
|
||||
}
|
||||
static void CL_ClearDlight(dlight_t *dl, int key)
|
||||
{
|
||||
void *sm = dl->worldshadowmesh;
|
||||
unsigned int oq = dl->coronaocclusionquery;
|
||||
unsigned int oqr = (dl->key == key)?dl->coronaocclusionresult:false;
|
||||
Z_Free(dl->customstyle);
|
||||
memset (dl, 0, sizeof(*dl));
|
||||
dl->coronaocclusionquery = oq;
|
||||
dl->coronaocclusionresult = oqr;
|
||||
|
@ -179,13 +196,23 @@ static void CL_ClearDlight(dlight_t *dl, int key)
|
|||
dlight_t *CL_AllocSlight(void)
|
||||
{
|
||||
dlight_t *dl;
|
||||
if (rtlights_max == cl_maxdlights)
|
||||
int i;
|
||||
for (i = RTL_FIRST; i < rtlights_max; i++)
|
||||
{
|
||||
cl_maxdlights = rtlights_max+8;
|
||||
cl_dlights = BZ_Realloc(cl_dlights, sizeof(*cl_dlights)*cl_maxdlights);
|
||||
memset(&cl_dlights[rtlights_max], 0, sizeof(*cl_dlights)*(cl_maxdlights-rtlights_max));
|
||||
if (cl_dlights[i].radius <= 0)
|
||||
break;
|
||||
}
|
||||
dl = &cl_dlights[rtlights_max++];
|
||||
if (i == rtlights_max)
|
||||
{
|
||||
if (rtlights_max == cl_maxdlights)
|
||||
{
|
||||
cl_maxdlights = rtlights_max+8;
|
||||
cl_dlights = BZ_Realloc(cl_dlights, sizeof(*cl_dlights)*cl_maxdlights);
|
||||
memset(&cl_dlights[rtlights_max], 0, sizeof(*cl_dlights)*(cl_maxdlights-rtlights_max));
|
||||
}
|
||||
i = rtlights_max++;
|
||||
}
|
||||
dl = &cl_dlights[i];
|
||||
|
||||
CL_ClearDlight(dl, 0);
|
||||
dl->flags = LFLAG_REALTIMEMODE;
|
||||
|
@ -2459,10 +2486,86 @@ void CLQ1_DrawLine(shader_t *shader, vec3_t v1, vec3_t v2, float r, float g, flo
|
|||
t->numidx = cl_numstrisidx - t->firstidx;
|
||||
cl_numstrisvert += 2;
|
||||
}
|
||||
void CLQ1_AddSpriteQuad(shader_t *shader, vec3_t mid, float radius)
|
||||
{
|
||||
float r=1, g=1, b=1;
|
||||
scenetris_t *t;
|
||||
int flags = BEF_NODLIGHT|BEF_NOSHADOWS;
|
||||
|
||||
if (cl_numstris && cl_stris[cl_numstris-1].shader == shader && cl_stris[cl_numstris-1].flags == flags && cl_stris[cl_numstris-1].numvert + 4 <= MAX_INDICIES)
|
||||
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 = shader;
|
||||
t->firstidx = cl_numstrisidx;
|
||||
t->firstvert = cl_numstrisvert;
|
||||
t->numvert = 0;
|
||||
t->numidx = 0;
|
||||
t->flags = flags;
|
||||
}
|
||||
|
||||
if (cl_numstrisidx+6 > cl_maxstrisidx)
|
||||
{
|
||||
cl_maxstrisidx=cl_numstrisidx+6 + 64;
|
||||
cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx);
|
||||
}
|
||||
if (cl_numstrisvert+4 > cl_maxstrisvert)
|
||||
{
|
||||
cl_maxstrisvert+=64;
|
||||
cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(*cl_strisvertv)*cl_maxstrisvert);
|
||||
cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(*cl_strisvertt)*cl_maxstrisvert);
|
||||
cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(*cl_strisvertc)*cl_maxstrisvert);
|
||||
}
|
||||
|
||||
{
|
||||
VectorMA(mid, radius, vright, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], radius, vup, cl_strisvertv[cl_numstrisvert]);
|
||||
Vector4Set(cl_strisvertc[cl_numstrisvert], r, g, b, 0.2);
|
||||
Vector2Set(cl_strisvertt[cl_numstrisvert], 1, 1);
|
||||
cl_numstrisvert++;
|
||||
|
||||
VectorMA(mid, radius, vright, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], -radius, vup, cl_strisvertv[cl_numstrisvert]);
|
||||
Vector4Set(cl_strisvertc[cl_numstrisvert], r, g, b, 0.2);
|
||||
Vector2Set(cl_strisvertt[cl_numstrisvert], 1, 0);
|
||||
cl_numstrisvert++;
|
||||
|
||||
VectorMA(mid, -radius, vright, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], -radius, vup, cl_strisvertv[cl_numstrisvert]);
|
||||
Vector4Set(cl_strisvertc[cl_numstrisvert], r, g, b, 0.2);
|
||||
Vector2Set(cl_strisvertt[cl_numstrisvert], 0, 0);
|
||||
cl_numstrisvert++;
|
||||
|
||||
VectorMA(mid, -radius, vright, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], radius, vup, cl_strisvertv[cl_numstrisvert]);
|
||||
Vector4Set(cl_strisvertc[cl_numstrisvert], r, g, b, 0.2);
|
||||
Vector2Set(cl_strisvertt[cl_numstrisvert], 0, 1);
|
||||
cl_numstrisvert++;
|
||||
}
|
||||
|
||||
/*build the triangles*/
|
||||
cl_strisidx[cl_numstrisidx++] = t->numvert + 0;
|
||||
cl_strisidx[cl_numstrisidx++] = t->numvert + 1;
|
||||
cl_strisidx[cl_numstrisidx++] = t->numvert + 2;
|
||||
|
||||
cl_strisidx[cl_numstrisidx++] = t->numvert + 0;
|
||||
cl_strisidx[cl_numstrisidx++] = t->numvert + 2;
|
||||
cl_strisidx[cl_numstrisidx++] = t->numvert + 3;
|
||||
|
||||
|
||||
t->numidx = cl_numstrisidx - t->firstidx;
|
||||
t->numvert += 4;
|
||||
}
|
||||
#include "shader.h"
|
||||
//well, 8192
|
||||
void CL_DrawDebugPlane(float *normal, float dist, float r, float g, float b, qboolean enqueue)
|
||||
{
|
||||
const float radius = 8192; //infinite is quite small nowadays.
|
||||
scenetris_t *t;
|
||||
if (!enqueue)
|
||||
cl_numstris = 0;
|
||||
|
@ -2501,26 +2604,26 @@ void CL_DrawDebugPlane(float *normal, float dist, float r, float g, float b, qbo
|
|||
VectorNormalize(forward);
|
||||
|
||||
VectorScale( normal, dist, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], 8192, right, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], 8192, forward, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], radius, right, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], radius, forward, cl_strisvertv[cl_numstrisvert]);
|
||||
Vector4Set(cl_strisvertc[cl_numstrisvert], r, g, b, 0.2);
|
||||
cl_numstrisvert++;
|
||||
|
||||
VectorScale( normal, dist, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], 8192, right, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], -8192, forward, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], radius, right, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], -radius, forward, cl_strisvertv[cl_numstrisvert]);
|
||||
Vector4Set(cl_strisvertc[cl_numstrisvert], r, g, b, 0.2);
|
||||
cl_numstrisvert++;
|
||||
|
||||
VectorScale( normal, dist, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], -8192, right, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], -8192, forward, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], -radius, right, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], -radius, forward, cl_strisvertv[cl_numstrisvert]);
|
||||
Vector4Set(cl_strisvertc[cl_numstrisvert], r, g, b, 0.2);
|
||||
cl_numstrisvert++;
|
||||
|
||||
VectorScale( normal, dist, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], -8192, right, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], 8192, forward, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], -radius, right, cl_strisvertv[cl_numstrisvert]);
|
||||
VectorMA(cl_strisvertv[cl_numstrisvert], radius, forward, cl_strisvertv[cl_numstrisvert]);
|
||||
Vector4Set(cl_strisvertc[cl_numstrisvert], r, g, b, 0.2);
|
||||
cl_numstrisvert++;
|
||||
}
|
||||
|
@ -2874,7 +2977,7 @@ static void CL_AddDecal_Callback(void *vctx, vec3_t *fte_restrict points, size_t
|
|||
cl_strisvertc[cl_numstrisvert+v][0] = ctx->rgbavalue[0];
|
||||
cl_strisvertc[cl_numstrisvert+v][1] = ctx->rgbavalue[1];
|
||||
cl_strisvertc[cl_numstrisvert+v][2] = ctx->rgbavalue[2];
|
||||
cl_strisvertc[cl_numstrisvert+v][3] = ctx->rgbavalue[3] * (1-(DotProduct(points[v], ctx->axis[0]) - ctx->offset[0]) * ctx->scale[0]);
|
||||
cl_strisvertc[cl_numstrisvert+v][3] = ctx->rgbavalue[3] * (1-fabs(DotProduct(points[v], ctx->axis[0]) - ctx->offset[0]) * ctx->scale[0]);
|
||||
}
|
||||
for (v = 0; v < numpoints; v++)
|
||||
{
|
||||
|
@ -2889,7 +2992,7 @@ static void CL_AddDecal_Callback(void *vctx, vec3_t *fte_restrict points, size_t
|
|||
void CL_AddDecal(shader_t *shader, vec3_t origin, vec3_t up, vec3_t side, vec3_t rgbvalue, float alphavalue)
|
||||
{
|
||||
scenetris_t *t;
|
||||
float l, s, radius;
|
||||
float l, s, radius, vradius;
|
||||
cl_adddecal_ctx_t ctx;
|
||||
|
||||
VectorNegate(up, ctx.axis[0]);
|
||||
|
@ -2897,20 +3000,24 @@ void CL_AddDecal(shader_t *shader, vec3_t origin, vec3_t up, vec3_t side, vec3_t
|
|||
|
||||
s = DotProduct(ctx.axis[2], ctx.axis[2]);
|
||||
l = DotProduct(ctx.axis[0], ctx.axis[0]);
|
||||
vradius = 1/sqrt(l);
|
||||
radius = 1/sqrt(s);
|
||||
|
||||
VectorScale(ctx.axis[0], 1/sqrt(l), ctx.axis[0]);
|
||||
VectorScale(ctx.axis[0], vradius, ctx.axis[0]);
|
||||
VectorScale(ctx.axis[2], radius, ctx.axis[2]);
|
||||
|
||||
CrossProduct(ctx.axis[0], ctx.axis[2], ctx.axis[1]);
|
||||
|
||||
ctx.offset[1] = DotProduct(origin, ctx.axis[1]) + 0.5*radius;
|
||||
ctx.offset[2] = DotProduct(origin, ctx.axis[2]) + 0.5*radius;
|
||||
ctx.offset[1] = DotProduct(origin, ctx.axis[1]) + 0.5*radius;
|
||||
ctx.offset[0] = DotProduct(origin, ctx.axis[0]);
|
||||
|
||||
ctx.scale[1] = 1/radius;
|
||||
ctx.scale[2] = 1/radius;
|
||||
ctx.scale[0] = 1;
|
||||
ctx.scale[1] = 1/radius;
|
||||
ctx.scale[0] = 2/vradius;
|
||||
|
||||
if (R2D_Flush)
|
||||
R2D_Flush();
|
||||
|
||||
/*reuse the previous trigroup if its the same shader*/
|
||||
if (cl_numstris && cl_stris[cl_numstris-1].shader == shader && cl_stris[cl_numstris-1].flags == (BEF_NODLIGHT|BEF_NOSHADOWS))
|
||||
|
@ -2934,7 +3041,7 @@ void CL_AddDecal(shader_t *shader, vec3_t origin, vec3_t up, vec3_t side, vec3_t
|
|||
ctx.t = t;
|
||||
VectorCopy(rgbvalue, ctx.rgbavalue);
|
||||
ctx.rgbavalue[3] = alphavalue;
|
||||
Mod_ClipDecal(cl.worldmodel, origin, ctx.axis[0], ctx.axis[1], ctx.axis[2], radius, 0,0, CL_AddDecal_Callback, &ctx);
|
||||
Mod_ClipDecal(cl.worldmodel, origin, ctx.axis[0], ctx.axis[1], ctx.axis[2], max(radius, vradius), 0,0, CL_AddDecal_Callback, &ctx);
|
||||
|
||||
if (!t->numidx)
|
||||
cl_numstris--;
|
||||
|
@ -4302,6 +4409,10 @@ void CL_LinkPacketEntities (void)
|
|||
#endif
|
||||
|
||||
CLQ1_AddVisibleBBoxes();
|
||||
|
||||
#ifdef RTLIGHTS
|
||||
R_EditLights_DrawLights();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -232,10 +232,10 @@ static_entity_t *cl_static_entities;
|
|||
unsigned int cl_max_static_entities;
|
||||
lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES];
|
||||
dlight_t *cl_dlights;
|
||||
unsigned int cl_maxdlights; /*size of cl_dlights array*/
|
||||
size_t cl_maxdlights; /*size of cl_dlights array*/
|
||||
|
||||
int cl_baselines_count;
|
||||
int rtlights_first, rtlights_max;
|
||||
size_t rtlights_first, rtlights_max;
|
||||
|
||||
// refresh list
|
||||
// this is double buffered so the last frame
|
||||
|
@ -2448,7 +2448,7 @@ void CL_SetInfo_f (void)
|
|||
if (Cmd_Argc() == 1)
|
||||
{
|
||||
InfoBuf_Print (&cls.userinfo[pnum], "");
|
||||
Con_Printf("[%u]", (unsigned int)cls.userinfo[pnum].totalsize);
|
||||
Con_Printf("[%u]\n", (unsigned int)cls.userinfo[pnum].totalsize);
|
||||
return;
|
||||
}
|
||||
if (Cmd_Argc() != 3)
|
||||
|
@ -4876,10 +4876,10 @@ void Host_RunFileNotify(struct dl_download *dl)
|
|||
#define HRF_DEMO (HRF_DEMO_MVD|HRF_DEMO_QWD|HRF_DEMO_DM2|HRF_DEMO_DEM)
|
||||
#define HRF_FILETYPES (HRF_DEMO|HRF_QTVINFO|HRF_MANIFEST|HRF_BSP|HRF_PACKAGE|HRF_ARCHIVE|HRF_MODEL|HRF_CONFIG)
|
||||
typedef struct {
|
||||
unsigned int flags;
|
||||
struct dl_download *dl;
|
||||
vfsfile_t *srcfile;
|
||||
vfsfile_t *dstfile;
|
||||
unsigned int flags;
|
||||
char fname[1]; //system path or url.
|
||||
} hrf_t;
|
||||
|
||||
|
@ -6294,8 +6294,10 @@ void Host_FinishLoading(void)
|
|||
|
||||
Menu_Download_Update();
|
||||
|
||||
#ifdef IPLOG
|
||||
IPLog_Merge_File("iplog.txt");
|
||||
IPLog_Merge_File("iplog.dat"); //legacy crap, for compat with proquake
|
||||
#endif
|
||||
}
|
||||
|
||||
if (PM_IsApplying(true))
|
||||
|
|
|
@ -6029,7 +6029,8 @@ void CL_PrintChat(player_info_t *plr, char *msg, int plrflags)
|
|||
|
||||
if (con_separatechat.ival == 1)
|
||||
{
|
||||
Con_PrintCon(&con_main, fullchatmessage, con_main.parseflags|PFS_NONOTIFY);
|
||||
console_t *c = Con_GetMain();
|
||||
Con_PrintCon(c, fullchatmessage, c->parseflags|PFS_NONOTIFY);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -6585,7 +6586,7 @@ static void CL_ParsePrecache(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void Con_HexDump(qbyte *packet, size_t len)
|
||||
static void Con_HexDump(qbyte *packet, size_t len, size_t badoffset)
|
||||
{
|
||||
int i;
|
||||
int pos;
|
||||
|
@ -6598,6 +6599,8 @@ static void Con_HexDump(qbyte *packet, size_t len)
|
|||
{
|
||||
if (pos >= len)
|
||||
Con_Printf(" - ");
|
||||
else if (pos == badoffset)
|
||||
Con_Printf("^b^1%2x ", packet[pos]);
|
||||
else
|
||||
Con_Printf("%2x ", packet[pos]);
|
||||
pos++;
|
||||
|
@ -6608,9 +6611,19 @@ static void Con_HexDump(qbyte *packet, size_t len)
|
|||
if (pos >= len)
|
||||
Con_Printf("X");
|
||||
else if (packet[pos] == 0 || packet[pos] == '\t' || packet[pos] == '\r' || packet[pos] == '\n')
|
||||
Con_Printf(".");
|
||||
{
|
||||
if (pos == badoffset)
|
||||
Con_Printf("^b^1.");
|
||||
else
|
||||
Con_Printf(".");
|
||||
}
|
||||
else
|
||||
Con_Printf("%c", packet[pos]);
|
||||
{
|
||||
if (pos == badoffset)
|
||||
Con_Printf("^b^1%c", packet[pos]);
|
||||
else
|
||||
Con_Printf("%c", packet[pos]);
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
Con_Printf("\n");
|
||||
|
@ -6619,7 +6632,7 @@ static void Con_HexDump(qbyte *packet, size_t len)
|
|||
}
|
||||
void CL_DumpPacket(void)
|
||||
{
|
||||
Con_HexDump(net_message.data, net_message.cursize);
|
||||
Con_HexDump(net_message.data, net_message.cursize, msg_readcount-1);
|
||||
}
|
||||
|
||||
static void CL_ParsePortalState(void)
|
||||
|
|
|
@ -183,8 +183,8 @@ float mousemove_x, mousemove_y;
|
|||
float multicursor_x[8], multicursor_y[8];
|
||||
qboolean multicursor_active[8];
|
||||
|
||||
float scr_con_current;
|
||||
float scr_conlines; // lines of console to display
|
||||
float scr_con_current; //current console lines shown
|
||||
float scr_con_target; //the target number of lines (not a local, because it helps to know if we're at the target yet, etc)
|
||||
|
||||
qboolean scr_con_forcedraw;
|
||||
|
||||
|
@ -200,7 +200,6 @@ extern cvar_t scr_printspeed;
|
|||
extern cvar_t scr_allowsnap;
|
||||
extern cvar_t scr_sshot_type;
|
||||
extern cvar_t scr_sshot_prefix;
|
||||
extern cvar_t scr_sshot_compression;
|
||||
extern cvar_t crosshair;
|
||||
extern cvar_t scr_consize;
|
||||
cvar_t scr_neticontimeout = CVAR("scr_neticontimeout", "0.3");
|
||||
|
@ -222,7 +221,7 @@ qboolean scr_disabled_for_loading;
|
|||
qboolean scr_drawloading;
|
||||
float scr_disabled_time;
|
||||
|
||||
cvar_t con_stayhidden = CVARFD("con_stayhidden", "0", CVAR_NOTFROMSERVER, "0: allow console to pounce on the user\n1: console stays hidden unless explicitly invoked\n2:toggleconsole command no longer works\n3: shift+escape key no longer works");
|
||||
cvar_t con_stayhidden = CVARFD("con_stayhidden", "1", CVAR_NOTFROMSERVER, "0: allow console to pounce on the user\n1: console stays hidden unless explicitly invoked\n2:toggleconsole command no longer works\n3: shift+escape key no longer works");
|
||||
cvar_t show_fps = CVARFD("show_fps", "0", CVAR_ARCHIVE, "Displays the current framerate on-screen.\n1: framerate average over a second.\n2: Slowest frame over the last second (the game will play like shit if this is significantly lower than the average).\n3: Shows the rate of the fastest frame (not very useful).\n4: Shows the current frame's timings (this depends upon timer precision).\n5: Display a graph of how long it took to render each frame, large spikes are BAD BAD BAD.\n6: Displays the standard deviation of the frame times, if its greater than 3 then something is probably badly made, or you've a virus scanner running...\n7: Framegraph, for use with slower frames.");
|
||||
cvar_t show_fps_x = CVAR("show_fps_x", "-1");
|
||||
cvar_t show_fps_y = CVAR("show_fps_y", "-1");
|
||||
|
@ -727,7 +726,7 @@ void SCR_DrawCenterString (vrect_t *rect, cprint_t *p, struct font_s *font)
|
|||
|
||||
Font_BeginString(font, rect->x, y, &left, &top);
|
||||
Font_BeginString(font, rect->x+rect->width, rect->y+rect->height, &right, &bottom);
|
||||
linecount = Font_LineBreaks(p->string, p->string + p->charcount, right - left, MAX_CPRINT_LINES, line_start, line_end);
|
||||
linecount = Font_LineBreaks(p->string, p->string + p->charcount, (p->flags & CPRINT_NOWRAP)?0x7fffffff:(right - left), MAX_CPRINT_LINES, line_start, line_end);
|
||||
|
||||
ch = Font_CharHeight();
|
||||
|
||||
|
@ -1943,8 +1942,6 @@ void SCR_SetLoadingStage(int stage)
|
|||
SCR_SetLoadingFile("waiting for connection...");
|
||||
break;
|
||||
case LS_SERVER:
|
||||
if (scr_con_current > vid.height*scr_consize.value)
|
||||
scr_con_current = vid.height*scr_consize.value;
|
||||
SCR_SetLoadingFile("starting server...");
|
||||
break;
|
||||
case LS_CLIENT:
|
||||
|
@ -2287,85 +2284,85 @@ SCR_SetUpToDrawConsole
|
|||
void SCR_SetUpToDrawConsole (void)
|
||||
{
|
||||
extern int startuppending; //true if we're downloading media or something and have not yet triggered the startup action (read: main menu or cinematic)
|
||||
// if (scr_drawloading)
|
||||
// return; // never a console with loading plaque
|
||||
|
||||
// decide on the height of the console
|
||||
// if (!scr_disabled_for_loading)
|
||||
{
|
||||
float fullscreenpercent = 1;
|
||||
float fullscreenpercent = 1;
|
||||
#ifdef ANDROID
|
||||
//android has an onscreen imm that we don't want to obscure
|
||||
fullscreenpercent = scr_consize.value;
|
||||
//android has an onscreen imm that we don't want to obscure
|
||||
fullscreenpercent = scr_consize.value;
|
||||
#endif
|
||||
if (!con_stayhidden.ival && (!Key_Dest_Has(~(kdm_console|kdm_game))) && (!cl.sendprespawn && cl.worldmodel && cl.worldmodel->loadstate != MLS_LOADED))
|
||||
if (!con_stayhidden.ival && (!Key_Dest_Has(~(kdm_console|kdm_game))) && (!cl.sendprespawn && cl.worldmodel && cl.worldmodel->loadstate != MLS_LOADED))
|
||||
{
|
||||
//force console to fullscreen if we're loading stuff (but don't necessarily force focus)
|
||||
// Key_Dest_Add(kdm_console);
|
||||
scr_con_target = scr_con_current = vid.height * fullscreenpercent;
|
||||
}
|
||||
else if (!startuppending && !Key_Dest_Has(kdm_emenu|kdm_gmenu) && (!Key_Dest_Has(~((!con_stayhidden.ival?kdm_console:0)|kdm_game))) && SCR_GetLoadingStage() == LS_NONE && cls.state < ca_active && !Media_PlayingFullScreen() && !CSQC_UnconnectedOkay(false))
|
||||
{
|
||||
//go fullscreen if we're not doing anything
|
||||
if (con_curwindow && !cls.state && !scr_drawloading && !Key_Dest_Has(kdm_console))
|
||||
{
|
||||
//force console to fullscreen if we're loading stuff
|
||||
// Key_Dest_Add(kdm_console);
|
||||
scr_conlines = scr_con_current = vid.height * fullscreenpercent;
|
||||
Key_Dest_Add(kdm_cwindows);
|
||||
scr_con_target = 0; // not looking at an normal console
|
||||
}
|
||||
else if (!startuppending && !Key_Dest_Has(kdm_emenu|kdm_gmenu) && (!Key_Dest_Has(~((!con_stayhidden.ival?kdm_console:0)|kdm_game))) && SCR_GetLoadingStage() == LS_NONE && cls.state < ca_active && !Media_PlayingFullScreen() && !CSQC_UnconnectedOkay(false))
|
||||
{
|
||||
//go fullscreen if we're not doing anything
|
||||
if (con_curwindow && !cls.state && !scr_drawloading)
|
||||
{
|
||||
Key_Dest_Add(kdm_cwindows);
|
||||
scr_conlines = 0;
|
||||
}
|
||||
#ifdef VM_UI
|
||||
else if (UI_MenuState() || UI_OpenMenu())
|
||||
scr_con_current = scr_conlines = 0;
|
||||
else if (UI_MenuState() || UI_OpenMenu())
|
||||
scr_con_current = scr_con_target = 0; //force instantly hidden.
|
||||
#endif
|
||||
else
|
||||
else
|
||||
{
|
||||
qboolean legacyfullscreen = false;
|
||||
if (cls.state < ca_demostart)
|
||||
{
|
||||
if (cls.state < ca_demostart)
|
||||
{
|
||||
if (con_stayhidden.ival)
|
||||
if (con_stayhidden.ival)
|
||||
{ //go to the menu instead of the console.
|
||||
extern int startuppending;
|
||||
if (!scr_drawloading && SCR_GetLoadingStage() == LS_NONE)
|
||||
{
|
||||
extern int startuppending;
|
||||
scr_conlines = 0;
|
||||
if (SCR_GetLoadingStage() == LS_NONE)
|
||||
{
|
||||
if (CL_TryingToConnect()) //if we're trying to connect, make sure there's a loading/connecting screen showing instead of forcing the menu visible
|
||||
SCR_SetLoadingStage(LS_CONNECTION);
|
||||
else if (!Key_Dest_Has(kdm_emenu) && !startuppending) //don't force anything until the startup stuff has been done
|
||||
M_ToggleMenu_f();
|
||||
}
|
||||
if (CL_TryingToConnect()) //if we're trying to connect, make sure there's a loading/connecting screen showing instead of forcing the menu visible
|
||||
SCR_SetLoadingStage(LS_CONNECTION);
|
||||
else if (!Key_Dest_Has(kdm_emenu) && !startuppending) //don't force anything until the startup stuff has been done
|
||||
M_ToggleMenu_f();
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{ //nothing happening, make sure the console is visible or something.
|
||||
if (!scr_drawloading)
|
||||
Key_Dest_Add(kdm_console);
|
||||
legacyfullscreen = true;
|
||||
}
|
||||
}
|
||||
if (Key_Dest_Has(kdm_console) || (!con_stayhidden.ival && !startuppending && !scr_drawloading && !scr_disabled_for_loading && cls.state < ca_connected))
|
||||
scr_con_current = scr_conlines = vid.height * fullscreenpercent;
|
||||
else
|
||||
scr_conlines = 0;
|
||||
}
|
||||
else if (Key_Dest_Has(kdm_console))
|
||||
{
|
||||
//go half-screen if we're meant to have the console visible
|
||||
scr_conlines = vid.height*scr_consize.value; // half screen
|
||||
if (scr_conlines < 32)
|
||||
scr_conlines = 32; //prevent total loss of console.
|
||||
else if (scr_conlines>vid.height)
|
||||
scr_conlines = vid.height;
|
||||
}
|
||||
else
|
||||
scr_conlines = 0; // none visible
|
||||
|
||||
if (startuppending)
|
||||
scr_con_target = 0; //not made any decisions yet
|
||||
else if (Key_Dest_Has(kdm_console) || legacyfullscreen)
|
||||
scr_con_current = scr_con_target = vid.height * fullscreenpercent; // force instantly to fullscreen
|
||||
else
|
||||
scr_con_target = 0;
|
||||
}
|
||||
}
|
||||
if (scr_conlines < scr_con_current)
|
||||
else if (Key_Dest_Has(kdm_console))
|
||||
{
|
||||
//go half-screen if we're meant to have the console visible
|
||||
scr_con_target = vid.height*scr_consize.value; // half screen
|
||||
if (scr_con_target < 32)
|
||||
scr_con_target = 32; //prevent total loss of console.
|
||||
else if (scr_con_target>vid.height)
|
||||
scr_con_target = vid.height;
|
||||
}
|
||||
else
|
||||
scr_con_target = 0; // scroll to nothing
|
||||
|
||||
if (scr_con_target < scr_con_current)
|
||||
{
|
||||
scr_con_current -= scr_conspeed.value*host_frametime * (vid.height/320.0f);
|
||||
if (scr_conlines > scr_con_current)
|
||||
scr_con_current = scr_conlines;
|
||||
if (scr_con_target > scr_con_current)
|
||||
scr_con_current = scr_con_target;
|
||||
|
||||
}
|
||||
else if (scr_conlines > scr_con_current)
|
||||
else if (scr_con_target > scr_con_current)
|
||||
{
|
||||
scr_con_current += scr_conspeed.value*host_frametime * (vid.height/320.0f);
|
||||
if (scr_conlines < scr_con_current)
|
||||
scr_con_current = scr_conlines;
|
||||
if (scr_con_target < scr_con_current)
|
||||
scr_con_current = scr_con_target;
|
||||
}
|
||||
|
||||
if (scr_con_current>vid.height)
|
||||
|
@ -2406,266 +2403,6 @@ void SCR_DrawConsole (qboolean noback)
|
|||
==============================================================================
|
||||
*/
|
||||
|
||||
typedef struct _TargaHeader {
|
||||
unsigned char id_length, colormap_type, image_type;
|
||||
unsigned short colormap_index, colormap_length;
|
||||
unsigned char colormap_size;
|
||||
unsigned short x_origin, y_origin, width, height;
|
||||
unsigned char pixel_size, attributes;
|
||||
} TargaHeader;
|
||||
|
||||
|
||||
#if defined(AVAIL_JPEGLIB) && !defined(NO_JPEG)
|
||||
qboolean screenshotJPEG(char *filename, enum fs_relative fsroot, int compression, qbyte *screendata, int bytestride, int screenwidth, int screenheight, enum uploadfmt fmt);
|
||||
#endif
|
||||
#ifdef AVAIL_PNGLIB
|
||||
int Image_WritePNG (char *filename, enum fs_relative fsroot, int compression, void **buffers, int numbuffers, int bytestride, int width, int height, enum uploadfmt fmt);
|
||||
#endif
|
||||
qboolean WriteBMPFile(char *filename, enum fs_relative fsroot, qbyte *in, int instride, int width, int height, uploadfmt_t fmt);
|
||||
|
||||
qboolean WriteTGA(char *filename, enum fs_relative fsroot, const qbyte *fte_restrict rgb_buffer, int bytestride, int width, int height, enum uploadfmt fmt)
|
||||
{
|
||||
size_t c, i;
|
||||
vfsfile_t *vfs;
|
||||
if (fmt != TF_BGRA32 && fmt != TF_RGB24 && fmt != TF_RGBA32 && fmt != TF_BGR24 && fmt != TF_RGBX32 && fmt != TF_BGRX32)
|
||||
return false;
|
||||
FS_CreatePath(filename, fsroot);
|
||||
vfs = FS_OpenVFS(filename, "wb", fsroot);
|
||||
if (vfs)
|
||||
{
|
||||
int ipx,opx;
|
||||
qboolean rgb;
|
||||
unsigned char header[18];
|
||||
memset (header, 0, 18);
|
||||
|
||||
if (fmt == TF_BGRA32 || fmt == TF_RGBA32)
|
||||
{
|
||||
rgb = fmt==TF_RGBA32;
|
||||
ipx = 4;
|
||||
opx = 4;
|
||||
}
|
||||
else if (fmt == TF_RGBX32 || fmt == TF_BGRX32)
|
||||
{
|
||||
rgb = fmt==TF_RGBX32;
|
||||
ipx = 4;
|
||||
opx = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
rgb = fmt==TF_RGB24;
|
||||
ipx = 3;
|
||||
opx = 3;
|
||||
}
|
||||
|
||||
header[2] = 2; // uncompressed type
|
||||
header[12] = width&255;
|
||||
header[13] = width>>8;
|
||||
header[14] = height&255;
|
||||
header[15] = height>>8;
|
||||
header[16] = opx*8; // pixel size
|
||||
header[17] = 0x00; // flags
|
||||
|
||||
if (bytestride < 0)
|
||||
{ //if we're upside down, lets just use an upside down tga.
|
||||
rgb_buffer += bytestride*(height-1);
|
||||
bytestride = -bytestride;
|
||||
//now we can just do everything without worrying about rows
|
||||
}
|
||||
else //our data is top-down, set up the header to also be top-down.
|
||||
header[17] = 0x20;
|
||||
|
||||
if (ipx == opx && !rgb)
|
||||
{ //can just directly write it
|
||||
//bgr24, bgra24
|
||||
c = width*height*opx;
|
||||
|
||||
VFS_WRITE(vfs, header, sizeof(header));
|
||||
VFS_WRITE(vfs, rgb_buffer, c);
|
||||
}
|
||||
else
|
||||
{
|
||||
qbyte *fte_restrict rgb_out = malloc(width*opx*height);
|
||||
|
||||
//no need to swap alpha, and if we're just swapping alpha will be fine in-place.
|
||||
if (rgb)
|
||||
{ //rgb24, rgbx32, rgba32
|
||||
// compact, and swap
|
||||
c = width*height;
|
||||
for (i=0 ; i<c ; i++)
|
||||
{
|
||||
rgb_out[i*opx+2] = rgb_buffer[i*ipx+0];
|
||||
rgb_out[i*opx+1] = rgb_buffer[i*ipx+1];
|
||||
rgb_out[i*opx+0] = rgb_buffer[i*ipx+2];
|
||||
}
|
||||
}
|
||||
else
|
||||
{ //(bgr24), bgrx32, (bgra32)
|
||||
// compact
|
||||
c = width*height;
|
||||
for (i=0 ; i<c ; i++)
|
||||
{
|
||||
rgb_out[i*opx+0] = rgb_buffer[i*ipx+0];
|
||||
rgb_out[i*opx+1] = rgb_buffer[i*ipx+1];
|
||||
rgb_out[i*opx+2] = rgb_buffer[i*ipx+2];
|
||||
}
|
||||
}
|
||||
c *= opx;
|
||||
|
||||
VFS_WRITE(vfs, header, sizeof(header));
|
||||
VFS_WRITE(vfs, rgb_out, c);
|
||||
free(rgb_out);
|
||||
}
|
||||
|
||||
VFS_CLOSE(vfs);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
Find closest color in the palette for named color
|
||||
*/
|
||||
int MipColor(int r, int g, int b)
|
||||
{
|
||||
int i;
|
||||
float dist;
|
||||
int best=15;
|
||||
float bestdist;
|
||||
int r1, g1, b1;
|
||||
static int lr = -1, lg = -1, lb = -1;
|
||||
static int lastbest;
|
||||
|
||||
if (r == lr && g == lg && b == lb)
|
||||
return lastbest;
|
||||
|
||||
bestdist = 256*256*3;
|
||||
|
||||
for (i = 0; i < 256; i++) {
|
||||
r1 = host_basepal[i*3] - r;
|
||||
g1 = host_basepal[i*3+1] - g;
|
||||
b1 = host_basepal[i*3+2] - b;
|
||||
dist = r1*r1 + g1*g1 + b1*b1;
|
||||
if (dist < bestdist) {
|
||||
bestdist = dist;
|
||||
best = i;
|
||||
}
|
||||
}
|
||||
lr = r; lg = g; lb = b;
|
||||
lastbest = best;
|
||||
return best;
|
||||
}
|
||||
|
||||
qboolean SCR_ScreenShot (char *filename, enum fs_relative fsroot, void **buffer, int numbuffers, int bytestride, int width, int height, enum uploadfmt fmt)
|
||||
{
|
||||
#if defined(AVAIL_PNGLIB) || defined(AVAIL_JPEGLIB)
|
||||
extern cvar_t scr_sshot_compression;
|
||||
#endif
|
||||
|
||||
char ext[8];
|
||||
void *nbuffers[2];
|
||||
|
||||
switch(fmt)
|
||||
{ //nuke any alpha channel...
|
||||
case TF_RGBA32: fmt = TF_RGBX32; break;
|
||||
case TF_BGRA32: fmt = TF_BGRX32; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (!bytestride)
|
||||
bytestride = width*4;
|
||||
if (bytestride < 0)
|
||||
{ //fix up the buffers so callers don't have to.
|
||||
int nb = numbuffers;
|
||||
for (numbuffers = 0; numbuffers < nb && numbuffers < countof(nbuffers); numbuffers++)
|
||||
nbuffers[numbuffers] = (char*)buffer[numbuffers] - bytestride*(height-1);
|
||||
buffer = nbuffers;
|
||||
}
|
||||
|
||||
COM_FileExtension(filename, ext, sizeof(ext));
|
||||
|
||||
#ifdef AVAIL_PNGLIB
|
||||
if (!Q_strcasecmp(ext, "png") || !Q_strcasecmp(ext, "pns"))
|
||||
{
|
||||
//png can do bgr+rgb
|
||||
//rgba bgra will result in an extra alpha chan
|
||||
//actual stereo is also supported. huzzah.
|
||||
return Image_WritePNG(filename, fsroot, scr_sshot_compression.value, buffer, numbuffers, bytestride, width, height, fmt);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#ifdef AVAIL_JPEGLIB
|
||||
if (!Q_strcasecmp(ext, "jpeg") || !Q_strcasecmp(ext, "jpg"))
|
||||
{
|
||||
return screenshotJPEG(filename, fsroot, scr_sshot_compression.value, buffer[0], bytestride, width, height, fmt);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (!Q_strcasecmp(ext, "bmp"))
|
||||
{
|
||||
return WriteBMPFile(filename, fsroot, buffer[0], bytestride, width, height, fmt);
|
||||
}
|
||||
else
|
||||
if (!Q_strcasecmp(ext, "pcx"))
|
||||
{
|
||||
int y, x, s;
|
||||
qbyte *src, *dest;
|
||||
qbyte *srcbuf = buffer[0], *dstbuf;
|
||||
if (fmt == TF_RGB24 || fmt == TF_RGBA32 || fmt == TF_RGBX32)
|
||||
{
|
||||
dstbuf = malloc(width*height);
|
||||
s = (fmt == TF_RGB24)?3:4;
|
||||
// convert in-place to eight bit
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
src = srcbuf + (bytestride * y);
|
||||
dest = dstbuf + (width * y);
|
||||
|
||||
for (x = 0; x < width; x++) {
|
||||
*dest++ = MipColor(src[0], src[1], src[2]);
|
||||
src += s;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (fmt == TF_BGR24 || fmt == TF_BGRA32 || fmt == TF_BGRX32)
|
||||
{
|
||||
dstbuf = malloc(width*height);
|
||||
s = (fmt == TF_BGR24)?3:4;
|
||||
// convert in-place to eight bit
|
||||
for (y = 0; y < height; y++)
|
||||
{
|
||||
src = srcbuf + (bytestride * y);
|
||||
dest = dstbuf + (width * y);
|
||||
|
||||
for (x = 0; x < width; x++) {
|
||||
*dest++ = MipColor(src[2], src[1], src[0]);
|
||||
src += s;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
WritePCXfile (filename, fsroot, dstbuf, width, height, width, host_basepal, false);
|
||||
free(dstbuf);
|
||||
}
|
||||
else if (!Q_strcasecmp(ext, "tga")) //tga
|
||||
return WriteTGA(filename, fsroot, buffer[0], bytestride, width, height, fmt);
|
||||
/*else if (!Q_strcasecmp(ext, "ktx")) //ktx
|
||||
{
|
||||
struct pendingtextureinfo out = {PTI_2D};
|
||||
out.encoding = fmt;
|
||||
out.mipcount = 1;
|
||||
out.mip[0].data = buffer[0];
|
||||
out.mip[0].datasize = bytestride*height;
|
||||
out.mip[0].width = width;
|
||||
out.mip[0].height = height;
|
||||
out.mip[0].depth = 1;
|
||||
return Image_WriteKTXFile(filename, fsroot, &out);
|
||||
}*/
|
||||
else //extension / type not recognised.
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
SCR_ScreenShot_f
|
||||
|
@ -2726,7 +2463,8 @@ static void SCR_ScreenShot_f (void)
|
|||
rgbbuffer = VID_GetRGBInfo(&stride, &width, &height, &fmt);
|
||||
if (rgbbuffer)
|
||||
{
|
||||
if (SCR_ScreenShot(pcxname, FS_GAMEONLY, &rgbbuffer, 1, stride, width, height, fmt))
|
||||
//regarding metadata - we don't really know what's on the screen, so don't write something that may be wrong (eg: if there's only a console, don't claim that its a 360 image)
|
||||
if (SCR_ScreenShot(pcxname, FS_GAMEONLY, &rgbbuffer, 1, stride, width, height, fmt, false))
|
||||
{
|
||||
Con_Printf ("Wrote %s\n", sysname);
|
||||
BZ_Free(rgbbuffer);
|
||||
|
@ -2737,7 +2475,7 @@ static void SCR_ScreenShot_f (void)
|
|||
Con_Printf (CON_ERROR "Couldn't write %s\n", sysname);
|
||||
}
|
||||
|
||||
void *SCR_ScreenShot_Capture(int fbwidth, int fbheight, int *stride, enum uploadfmt *fmt)
|
||||
void *SCR_ScreenShot_Capture(int fbwidth, int fbheight, int *stride, enum uploadfmt *fmt, qboolean no2d)
|
||||
{
|
||||
int width, height;
|
||||
void *buf;
|
||||
|
@ -2764,7 +2502,7 @@ void *SCR_ScreenShot_Capture(int fbwidth, int fbheight, int *stride, enum upload
|
|||
#endif
|
||||
if (!okay && r_worldentity.model)
|
||||
{
|
||||
V_RenderView ();
|
||||
V_RenderView (no2d);
|
||||
okay = true;
|
||||
}
|
||||
//fixme: add a way to get+save the depth values too
|
||||
|
@ -2792,6 +2530,7 @@ void *SCR_ScreenShot_Capture(int fbwidth, int fbheight, int *stride, enum upload
|
|||
|
||||
static void SCR_ScreenShot_Mega_f(void)
|
||||
{
|
||||
extern cvar_t r_projection;
|
||||
int stride[2];
|
||||
int width[2];
|
||||
int height[2];
|
||||
|
@ -2801,6 +2540,7 @@ static void SCR_ScreenShot_Mega_f(void)
|
|||
int buf;
|
||||
char filename[MAX_QPATH];
|
||||
stereomethod_t osm = r_refdef.stereomethod;
|
||||
int projection = r_projection.ival;
|
||||
|
||||
//massage the rendering code to redraw the screen with an fbo forced.
|
||||
//this allows us to generate screenshots which are not otherwise possible to actually draw.
|
||||
|
@ -2841,8 +2581,12 @@ static void SCR_ScreenShot_Mega_f(void)
|
|||
mangle = COM_SkipPath(filename);
|
||||
Q_snprintfz(mangle, sizeof(filename) - (mangle-filename), "%s", screenyname);
|
||||
}
|
||||
|
||||
if (!strcmp(Cmd_Argv(0), "screenshot_360"))
|
||||
r_projection.ival = PROJ_EQUIRECTANGULAR;
|
||||
|
||||
if (!strcmp(Cmd_Argv(0), "screenshot_stereo"))
|
||||
COM_DefaultExtension (filename, "png", sizeof(filename));
|
||||
COM_DefaultExtension (filename, "png", sizeof(filename)); //png/pns is the only format that can really cope with this right now.
|
||||
else
|
||||
COM_DefaultExtension (filename, scr_sshot_type.string, sizeof(filename));
|
||||
|
||||
|
@ -2868,7 +2612,7 @@ static void SCR_ScreenShot_Mega_f(void)
|
|||
r_refdef.stereomethod = STEREO_LEFTONLY;
|
||||
}
|
||||
|
||||
buffers[buf] = SCR_ScreenShot_Capture(fbwidth, fbheight, &stride[buf], &fmt[buf]);
|
||||
buffers[buf] = SCR_ScreenShot_Capture(fbwidth, fbheight, &stride[buf], &fmt[buf], false);
|
||||
width[buf] = fbwidth;
|
||||
height[buf] = fbheight;
|
||||
|
||||
|
@ -2885,7 +2629,7 @@ static void SCR_ScreenShot_Mega_f(void)
|
|||
//okay, we drew something, we're good to save a screeny.
|
||||
if (buffers[0])
|
||||
{
|
||||
if (SCR_ScreenShot(filename, FS_GAMEONLY, buffers, numbuffers, stride[0], width[0], height[0], fmt[0]))
|
||||
if (SCR_ScreenShot(filename, FS_GAMEONLY, buffers, numbuffers, stride[0], width[0], height[0], fmt[0], true))
|
||||
{
|
||||
char sysname[1024];
|
||||
FS_NativePath(filename, FS_GAMEONLY, sysname, sizeof(sysname));
|
||||
|
@ -2899,11 +2643,13 @@ static void SCR_ScreenShot_Mega_f(void)
|
|||
BZ_Free(buffers[buf]);
|
||||
|
||||
r_refdef.stereomethod = osm;
|
||||
r_projection.ival = projection;
|
||||
}
|
||||
|
||||
static void SCR_ScreenShot_VR_f(void)
|
||||
{
|
||||
char *screenyname = Cmd_Argv(1);
|
||||
const char *ext;
|
||||
int width = atoi(Cmd_Argv(2));
|
||||
int stride=0;
|
||||
//we spin the camera around, taking slices from equirectangular screenshots
|
||||
|
@ -2911,13 +2657,14 @@ static void SCR_ScreenShot_VR_f(void)
|
|||
int height; //equirectangular 360 * 180 gives a nice clean ratio
|
||||
int px = 4;
|
||||
int step = atof(Cmd_Argv(3));
|
||||
void *left_buffer, *right_buffer, *buf;
|
||||
void *buffer[2], *buf;
|
||||
enum uploadfmt fmt;
|
||||
int lx, rx, x, y;
|
||||
vec3_t baseang;
|
||||
float ang;
|
||||
qboolean fail = false;
|
||||
extern cvar_t r_projection, r_stereo_separation, r_stereo_convergence;;
|
||||
extern cvar_t r_projection, r_stereo_separation, r_stereo_convergence;
|
||||
qboolean stereo;
|
||||
VectorCopy(r_refdef.viewangles, baseang);
|
||||
|
||||
if (width <= 2)
|
||||
|
@ -2928,8 +2675,8 @@ static void SCR_ScreenShot_VR_f(void)
|
|||
if (step <= 0)
|
||||
step = 5;
|
||||
|
||||
left_buffer = BZF_Malloc (width*height*2*px);
|
||||
right_buffer = (qbyte*)left_buffer + width*height*px;
|
||||
buffer[0] = BZF_Malloc (width*height*2*px);
|
||||
buffer[1] = (qbyte*)buffer[0] + width*height*px;
|
||||
|
||||
if (strstr (screenyname, "..") || strchr(screenyname, ':') || *screenyname == '.' || *screenyname == '/')
|
||||
screenyname = "";
|
||||
|
@ -2947,9 +2694,12 @@ static void SCR_ScreenShot_VR_f(void)
|
|||
}
|
||||
COM_DefaultExtension (filename, scr_sshot_type.string, sizeof(filename));
|
||||
|
||||
ext = COM_GetFileExtension(filename, NULL);
|
||||
stereo = !strcasecmp(ext, ".pns") || !strcasecmp(ext, ".jns");
|
||||
|
||||
|
||||
if (!left_buffer)
|
||||
|
||||
if (!buffer[0])
|
||||
{
|
||||
Con_Printf("out of memory\n");
|
||||
return;
|
||||
|
@ -2977,22 +2727,22 @@ static void SCR_ScreenShot_VR_f(void)
|
|||
r_refdef.eyeoffset[0] = sin(ang) * r_stereo_separation.value * 0.5;
|
||||
r_refdef.eyeoffset[1] = cos(ang) * r_stereo_separation.value * 0.5;
|
||||
r_refdef.eyeoffset[2] = 0;
|
||||
buf = SCR_ScreenShot_Capture(width, height, &stride, &fmt);
|
||||
buf = SCR_ScreenShot_Capture(width, height, &stride, &fmt, true);
|
||||
switch(fmt)
|
||||
{
|
||||
case TF_BGRA32:
|
||||
for (y = 0; y < height; y++)
|
||||
for (x = lx; x < rx; x++)
|
||||
((unsigned int*)left_buffer)[y*width + x] = ((unsigned int*)buf)[y*width + x];
|
||||
((unsigned int*)buffer[0])[y*width + x] = ((unsigned int*)buf)[y*width + x];
|
||||
break;
|
||||
case TF_RGB24:
|
||||
for (y = 0; y < height; y++)
|
||||
for (x = lx; x < rx; x++)
|
||||
{
|
||||
((qbyte*)left_buffer)[(y*width + x)*4+0] = ((qbyte*)buf)[(y*width + x)*3+2];
|
||||
((qbyte*)left_buffer)[(y*width + x)*4+1] = ((qbyte*)buf)[(y*width + x)*3+1];
|
||||
((qbyte*)left_buffer)[(y*width + x)*4+2] = ((qbyte*)buf)[(y*width + x)*3+0];
|
||||
((qbyte*)left_buffer)[(y*width + x)*4+3] = 255;
|
||||
((qbyte*)buffer[0])[(y*width + x)*4+0] = ((qbyte*)buf)[(y*width + x)*3+2];
|
||||
((qbyte*)buffer[0])[(y*width + x)*4+1] = ((qbyte*)buf)[(y*width + x)*3+1];
|
||||
((qbyte*)buffer[0])[(y*width + x)*4+2] = ((qbyte*)buf)[(y*width + x)*3+0];
|
||||
((qbyte*)buffer[0])[(y*width + x)*4+3] = 255;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -3011,22 +2761,22 @@ static void SCR_ScreenShot_VR_f(void)
|
|||
r_refdef.eyeoffset[0] *= -1;
|
||||
r_refdef.eyeoffset[1] *= -1;
|
||||
r_refdef.eyeoffset[2] = 0;
|
||||
buf = SCR_ScreenShot_Capture(width, height, &stride, &fmt);
|
||||
buf = SCR_ScreenShot_Capture(width, height, &stride, &fmt, true);
|
||||
switch(fmt)
|
||||
{
|
||||
case TF_BGRA32:
|
||||
for (y = 0; y < height; y++)
|
||||
for (x = lx; x < rx; x++)
|
||||
((unsigned int*)right_buffer)[y*width + x] = ((unsigned int*)buf)[y*width + x];
|
||||
((unsigned int*)buffer)[y*width + x] = ((unsigned int*)buf)[y*width + x];
|
||||
break;
|
||||
case TF_RGB24:
|
||||
for (y = 0; y < height; y++)
|
||||
for (x = lx; x < rx; x++)
|
||||
{
|
||||
((qbyte*)right_buffer)[(y*width + x)*4+0] = ((qbyte*)buf)[(y*width + x)*3+2];
|
||||
((qbyte*)right_buffer)[(y*width + x)*4+1] = ((qbyte*)buf)[(y*width + x)*3+1];
|
||||
((qbyte*)right_buffer)[(y*width + x)*4+2] = ((qbyte*)buf)[(y*width + x)*3+0];
|
||||
((qbyte*)right_buffer)[(y*width + x)*4+3] = 255;
|
||||
((qbyte*)buffer[1])[(y*width + x)*4+0] = ((qbyte*)buf)[(y*width + x)*3+2];
|
||||
((qbyte*)buffer[1])[(y*width + x)*4+1] = ((qbyte*)buf)[(y*width + x)*3+1];
|
||||
((qbyte*)buffer[1])[(y*width + x)*4+2] = ((qbyte*)buf)[(y*width + x)*3+0];
|
||||
((qbyte*)buffer[1])[(y*width + x)*4+3] = 255;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -3038,31 +2788,82 @@ static void SCR_ScreenShot_VR_f(void)
|
|||
|
||||
if (fail)
|
||||
Con_Printf ("Unable to capture suitable screen image\n");
|
||||
else if (SCR_ScreenShot(filename, FS_GAMEONLY, &left_buffer, 1, stride, width, height*2, TF_BGRA32))
|
||||
else if (SCR_ScreenShot(filename, FS_GAMEONLY, buffer, (stereo?2:1), stride, width, height*(stereo?1:2), TF_BGRX32, true))
|
||||
{
|
||||
char sysname[1024];
|
||||
FS_NativePath(filename, FS_GAMEONLY, sysname, sizeof(sysname));
|
||||
Con_Printf ("Wrote %s\n", sysname);
|
||||
}
|
||||
|
||||
BZ_Free(left_buffer);
|
||||
BZ_Free(buffer[0]);
|
||||
|
||||
r_projection.ival = r_projection.value;
|
||||
VectorCopy(baseang, r_refdef.viewangles);
|
||||
VectorClear(r_refdef.eyeoffset);
|
||||
}
|
||||
|
||||
//flips an image so that the result is always top-down
|
||||
static void *SCR_ScreenShot_FixStride(void *buffer, unsigned int fbwidth, unsigned int fbheight, int *stride, uploadfmt_t fmt, qboolean horizontalflip, qboolean verticalflip)
|
||||
{
|
||||
unsigned int bb, bw, bh;
|
||||
Image_BlockSizeForEncoding(fmt, &bb, &bw, &bh);
|
||||
if (bw == 1 && bh == 1)
|
||||
{
|
||||
if (horizontalflip)
|
||||
{
|
||||
int y, x, p;
|
||||
char *bad = buffer;
|
||||
char *in = buffer, *out;
|
||||
buffer = out = BZ_Malloc(fbwidth*fbheight*bb);
|
||||
if (*stride < 0)
|
||||
in += fbwidth*bb*(fbheight-1);
|
||||
for (y = 0; y < fbheight; y++, in += *stride, out += fbwidth*bb)
|
||||
{
|
||||
for (x = 0; x < fbwidth*bb; x+=bb)
|
||||
{
|
||||
for (p = 0; p < bb; p++)
|
||||
out[x+p] = in[(fbwidth-1)*bb-x+p];
|
||||
}
|
||||
}
|
||||
BZ_Free(bad);
|
||||
*stride = fbwidth*bb;
|
||||
}
|
||||
if (verticalflip && bh == 1)
|
||||
*stride = -*stride;
|
||||
|
||||
if (*stride != fbwidth*bw)
|
||||
{
|
||||
unsigned int y;
|
||||
char *tofree = buffer;
|
||||
char *out = BZ_Malloc(fbwidth*fbheight*bb);
|
||||
char *in = buffer;
|
||||
buffer = out;
|
||||
if (*stride < 0)
|
||||
in += fbwidth*bb*(fbheight-1); //the memory pointer always starts at the lowest address regardless of bottom-up state.
|
||||
for (y = 0; y < fbheight; y++, in += *stride, out += fbwidth*bb)
|
||||
{
|
||||
memcpy(out, in, fbwidth*bb);
|
||||
}
|
||||
BZ_Free(tofree);
|
||||
*stride = fbwidth*bb;
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void SCR_ScreenShot_Cubemap_f(void)
|
||||
{
|
||||
void *buffer;
|
||||
int stride, fbwidth, fbheight;
|
||||
uploadfmt_t fmt;
|
||||
char filename[MAX_QPATH];
|
||||
char sysname[1024];
|
||||
char *fname = Cmd_Argv(1);
|
||||
int i, firstside;
|
||||
char olddrawviewmodel[64]; //hack, so we can set r_drawviewmodel to 0 so that it doesn't appear in screenshots even if the csqc is generating new data.
|
||||
vec3_t oldangles;
|
||||
const struct
|
||||
struct pendingtextureinfo mips;
|
||||
static const struct
|
||||
{
|
||||
vec3_t angle;
|
||||
const char *postfix;
|
||||
|
@ -3086,6 +2887,8 @@ void SCR_ScreenShot_Cubemap_f(void)
|
|||
{{90, 0, 0}, "_dn"},
|
||||
{{-90, 0, 0}, "_up"}
|
||||
};
|
||||
const char *ext;
|
||||
unsigned int bb, bw, bh;
|
||||
|
||||
if (!cls.state || !cl.worldmodel || cl.worldmodel->loadstate != MLS_LOADED)
|
||||
{
|
||||
|
@ -3106,74 +2909,146 @@ void SCR_ScreenShot_Cubemap_f(void)
|
|||
fbheight = 512;
|
||||
fbwidth = fbheight;
|
||||
|
||||
for (i = firstside; i < firstside+6; i++)
|
||||
ext = COM_GetFileExtension(fname, NULL);
|
||||
if (!*fname || ext == fname)
|
||||
{ //generate a default filename if none exists yet.
|
||||
char base[MAX_QPATH];
|
||||
COM_FileBase(cl.worldmodel->name, base, sizeof(base));
|
||||
fname = va("%s/%i_%i_%i", base, (int)r_refdef.vieworg[0], (int)r_refdef.vieworg[1], (int)r_refdef.vieworg[2]);
|
||||
}
|
||||
if (!strcmp(ext, ".ktx") || !strcmp(ext, ".dds"))
|
||||
{
|
||||
if (!*fname)
|
||||
qboolean fail = false;
|
||||
mips.type = PTI_CUBEMAP;
|
||||
mips.encoding = 0;
|
||||
mips.extrafree = NULL;
|
||||
mips.mipcount = 6;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
char base[MAX_QPATH];
|
||||
COM_FileBase(cl.worldmodel->name, base, sizeof(base));
|
||||
fname = va("%s/%i_%i_%i", base, (int)r_refdef.vieworg[0], (int)r_refdef.vieworg[1], (int)r_refdef.vieworg[2]);
|
||||
VectorCopy(sides[i].angle, cl.playerview->simangles);
|
||||
VectorCopy(cl.playerview->simangles, cl.playerview->viewangles);
|
||||
|
||||
mips.mip[i].data = SCR_ScreenShot_Capture(fbwidth, fbheight, &stride, &fmt, true);
|
||||
if (!mips.mip[i].data)
|
||||
fail = true;
|
||||
if (!i)
|
||||
mips.encoding = fmt;
|
||||
else if (fmt != mips.encoding || fbwidth != mips.mip[0].width || fbheight != mips.mip[0].height)
|
||||
fail = true; //zomgwtfbbq
|
||||
|
||||
mips.mip[i].data = SCR_ScreenShot_FixStride(mips.mip[i].data, fbwidth, fbheight, &stride, fmt, sides[i].horizontalflip, sides[i].verticalflip);
|
||||
Image_BlockSizeForEncoding(fmt, &bb, &bw, &bh);
|
||||
|
||||
mips.mip[i].datasize = bb*((fbwidth+bw-1)/bw)*((fbheight+bh-1)/bh);
|
||||
mips.mip[i].width = fbwidth;
|
||||
mips.mip[i].height = fbheight;
|
||||
mips.mip[i].depth = 0;
|
||||
mips.mip[i].needfree = true;
|
||||
}
|
||||
Q_snprintfz(filename, sizeof(filename), "textures/%s%s", fname, sides[i].postfix);
|
||||
COM_DefaultExtension (filename, scr_sshot_type.string, sizeof(filename));
|
||||
|
||||
VectorCopy(sides[i].angle, cl.playerview->simangles);
|
||||
VectorCopy(cl.playerview->simangles, cl.playerview->viewangles);
|
||||
/*FIXME:
|
||||
while (!fail && (w > 1 || h > 1))
|
||||
{ //warning: d3d is different
|
||||
w = max(1,w>>1);
|
||||
h = max(1,h>>1);
|
||||
if (mips.mipcount+6 > countof(mips.mip))
|
||||
break; //erk! how big was the original image?!?
|
||||
|
||||
buffer = SCR_ScreenShot_Capture(fbwidth, fbheight, &stride, &fmt);
|
||||
if (buffer)
|
||||
{
|
||||
char sysname[1024];
|
||||
if (sides[i].horizontalflip)
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
int y, x, p;
|
||||
int pxsize;
|
||||
char *bad = buffer;
|
||||
char *in = buffer, *out;
|
||||
switch(fmt)
|
||||
{
|
||||
case TF_RGBA32:
|
||||
case TF_BGRA32:
|
||||
case TF_RGBX32:
|
||||
case TF_BGRX32:
|
||||
pxsize = 4;
|
||||
break;
|
||||
case TF_RGB24:
|
||||
case TF_BGR24:
|
||||
pxsize = 3;
|
||||
break;
|
||||
default: //erk!
|
||||
pxsize = 1;
|
||||
break;
|
||||
}
|
||||
buffer = out = BZ_Malloc(fbwidth*fbheight*pxsize);
|
||||
for (y = 0; y < fbheight; y++, in += abs(stride), out += fbwidth*pxsize)
|
||||
{
|
||||
for (x = 0; x < fbwidth*pxsize; x+=pxsize)
|
||||
{
|
||||
for (p = 0; p < pxsize; p++)
|
||||
out[x+p] = in[(fbwidth-1)*pxsize-x+p];
|
||||
}
|
||||
}
|
||||
BZ_Free(bad);
|
||||
if (stride < 0)
|
||||
stride = -fbwidth*pxsize;
|
||||
else
|
||||
stride = fbwidth*pxsize;
|
||||
mips.mip[mips.mipcount] = GenerateMip(mips.mip[mips.mipcount-6]);
|
||||
mips.mipcount++;
|
||||
}
|
||||
if (sides[i].verticalflip)
|
||||
stride = -stride;
|
||||
if (SCR_ScreenShot(filename, FS_GAMEONLY, &buffer, 1, stride, fbwidth, fbheight, fmt))
|
||||
}
|
||||
*/
|
||||
|
||||
Q_snprintfz(filename, sizeof(filename), "textures/%s", fname);
|
||||
COM_DefaultExtension (filename, ext, sizeof(filename));
|
||||
#ifdef IMAGEFMT_KTX
|
||||
COM_DefaultExtension (filename, ".ktx", sizeof(filename));
|
||||
#endif
|
||||
#ifdef IMAGEFMT_DDS
|
||||
COM_DefaultExtension (filename, ".dds", sizeof(filename));
|
||||
#endif
|
||||
ext = COM_GetFileExtension(filename, NULL);
|
||||
if (fail)
|
||||
Con_Printf("Unable to generate cubemap data\n");
|
||||
#ifdef IMAGEFMT_DDS
|
||||
else if (!strcmp(ext, ".dds"))
|
||||
{
|
||||
if (Image_WriteDDSFile(filename, FS_GAMEONLY, &mips))
|
||||
{
|
||||
FS_NativePath(filename, FS_GAMEONLY, sysname, sizeof(sysname));
|
||||
Con_Printf ("Wrote %s\n", sysname);
|
||||
}
|
||||
else
|
||||
}
|
||||
#endif
|
||||
#ifdef IMAGEFMT_KTX
|
||||
else if (!strcmp(ext, ".ktx"))
|
||||
{
|
||||
if (Image_WriteKTXFile(filename, FS_GAMEONLY, &mips))
|
||||
{
|
||||
FS_NativePath(filename, FS_GAMEONLY, sysname, sizeof(sysname));
|
||||
Con_Printf ("Failed to write %s\n", sysname);
|
||||
Con_Printf ("Wrote %s\n", sysname);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
Con_Printf ("%s: Unknown format %s\n", Cmd_Argv(0), filename);
|
||||
while (i-- > 0)
|
||||
if (mips.mip[i].needfree)
|
||||
BZ_Free(mips.mip[i].data);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = firstside; i < firstside+6; i++)
|
||||
{
|
||||
VectorCopy(sides[i].angle, cl.playerview->simangles);
|
||||
VectorCopy(cl.playerview->simangles, cl.playerview->viewangles);
|
||||
|
||||
buffer = SCR_ScreenShot_Capture(fbwidth, fbheight, &stride, &fmt, true);
|
||||
if (buffer)
|
||||
{
|
||||
Image_BlockSizeForEncoding(fmt, &bb, &bw, &bh);
|
||||
if (sides[i].horizontalflip)
|
||||
{
|
||||
int y, x, p;
|
||||
char *bad = buffer;
|
||||
char *in = buffer, *out;
|
||||
buffer = out = BZ_Malloc(fbwidth*fbheight*bb);
|
||||
for (y = 0; y < fbheight; y++, in += abs(stride), out += fbwidth*bb)
|
||||
{
|
||||
for (x = 0; x < fbwidth*bb; x+=bb)
|
||||
{
|
||||
for (p = 0; p < bb; p++)
|
||||
out[x+p] = in[(fbwidth-1)*bb-x+p];
|
||||
}
|
||||
}
|
||||
BZ_Free(bad);
|
||||
if (stride < 0)
|
||||
stride = -fbwidth*bb;
|
||||
else
|
||||
stride = fbwidth*bb;
|
||||
}
|
||||
if (sides[i].verticalflip)
|
||||
stride = -stride;
|
||||
|
||||
Q_snprintfz(filename, sizeof(filename), "textures/%s%s", fname, sides[i].postfix);
|
||||
COM_DefaultExtension (filename, scr_sshot_type.string, sizeof(filename));
|
||||
|
||||
if (SCR_ScreenShot(filename, FS_GAMEONLY, &buffer, 1, stride, fbwidth, fbheight, fmt, false))
|
||||
{
|
||||
FS_NativePath(filename, FS_GAMEONLY, sysname, sizeof(sysname));
|
||||
Con_Printf ("Wrote %s\n", sysname);
|
||||
}
|
||||
else
|
||||
{
|
||||
FS_NativePath(filename, FS_GAMEONLY, sysname, sizeof(sysname));
|
||||
Con_Printf ("Failed to write %s\n", sysname);
|
||||
}
|
||||
BZ_Free(buffer);
|
||||
}
|
||||
BZ_Free(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3527,6 +3402,7 @@ void SCR_Init (void)
|
|||
//
|
||||
Cmd_AddCommandD ("screenshot_mega",SCR_ScreenShot_Mega_f, "screenshot_mega <name> [width] [height]\nTakes a screenshot with explicit sizes that are not tied to the size of your monitor, allowing for true monstrosities.");
|
||||
Cmd_AddCommandD ("screenshot_stereo",SCR_ScreenShot_Mega_f, "screenshot_stereo <name> [width] [height]\nTakes a simple stereo screenshot.");
|
||||
Cmd_AddCommandD ("screenshot_360",SCR_ScreenShot_Mega_f, "screenshot_360 <name> [width] [height]\nTakes an equirectangular screenshot.");
|
||||
Cmd_AddCommandD ("screenshot_vr",SCR_ScreenShot_VR_f, "screenshot_vr <name> [width]\nTakes a spherical stereoscopic panorama image, for viewing with VR displays.");
|
||||
Cmd_AddCommandD ("screenshot_cubemap",SCR_ScreenShot_Cubemap_f, "screenshot_cubemap <name> [size]\nTakes 6 screenshots forming a single cubemap.");
|
||||
Cmd_AddCommandD ("envmap",SCR_ScreenShot_Cubemap_f, "Legacy name for the screenshot_cubemap command."); //legacy
|
||||
|
|
|
@ -1561,8 +1561,6 @@ qboolean UI_KeyPress(int key, int unicode, qboolean down)
|
|||
}
|
||||
|
||||
UI_OpenMenu();
|
||||
|
||||
scr_conlines = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -315,6 +315,7 @@ typedef struct dlight_s
|
|||
int key; // so entities can reuse same entry
|
||||
vec3_t origin;
|
||||
vec3_t axis[3];
|
||||
vec3_t angles; //used only for reflection, to avoid things getting rounded/cycled.
|
||||
vec3_t rotation; //cubemap/spotlight rotation
|
||||
float radius;
|
||||
float die; // stop lighting after this time
|
||||
|
@ -330,6 +331,7 @@ typedef struct dlight_s
|
|||
|
||||
unsigned int flags;
|
||||
char cubemapname[64];
|
||||
char *customstyle;
|
||||
|
||||
int coronaocclusionquery;
|
||||
unsigned int coronaocclusionresult;
|
||||
|
@ -780,7 +782,7 @@ typedef struct
|
|||
double last_servermessage;
|
||||
|
||||
//list of ent frames that still need to be acked.
|
||||
int numackframes;
|
||||
unsigned int numackframes;
|
||||
int ackframes[64];
|
||||
|
||||
#ifdef Q2CLIENT
|
||||
|
@ -1049,9 +1051,9 @@ extern static_entity_t *cl_static_entities;
|
|||
extern unsigned int cl_max_static_entities;
|
||||
extern lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES];
|
||||
extern dlight_t *cl_dlights;
|
||||
extern unsigned int cl_maxdlights;
|
||||
extern size_t cl_maxdlights;
|
||||
|
||||
extern int rtlights_first, rtlights_max;
|
||||
extern size_t rtlights_first, rtlights_max;
|
||||
extern int cl_baselines_count;
|
||||
|
||||
extern qboolean nomaster;
|
||||
|
@ -1068,6 +1070,7 @@ 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
|
||||
void CL_DecayLights (void);
|
||||
|
||||
void CLQW_ParseDelta (struct entity_state_s *from, struct entity_state_s *to, int bits);
|
||||
|
@ -1305,7 +1308,7 @@ qboolean CL_CheckBaselines (int size);
|
|||
void V_StartPitchDrift (playerview_t *pv);
|
||||
void V_StopPitchDrift (playerview_t *pv);
|
||||
|
||||
void V_RenderView (void);
|
||||
void V_RenderView (qboolean no2d);
|
||||
void V_Register (void);
|
||||
void V_ParseDamage (playerview_t *pv);
|
||||
void V_SetContentsColor (int contents);
|
||||
|
|
|
@ -22,10 +22,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "quakedef.h"
|
||||
#include "shader.h"
|
||||
|
||||
console_t con_main;
|
||||
console_t *con_curwindow;
|
||||
console_t *con_current; // points to whatever is the visible console
|
||||
console_t *con_head; // first console in the list
|
||||
console_t *con_curwindow; // the (window) console that's currently got focus.
|
||||
console_t *con_current; // points to whatever is the active console (the one that has focus ONLY when kdm_console)
|
||||
console_t *con_mouseover; // points to whichever console's title is currently mouseovered, or null
|
||||
|
||||
console_t *con_main; // the default console that text will be thrown at. recreated as needed.
|
||||
console_t *con_chat; // points to a chat console
|
||||
|
||||
#define Font_ScreenWidth() (vid.pixelwidth)
|
||||
|
@ -55,27 +57,55 @@ qterm_t *activeqterm;
|
|||
//int con_linewidth; // characters across screen
|
||||
//int con_totallines; // total lines in console scrollback
|
||||
|
||||
float con_cursorspeed = 4;
|
||||
static float con_cursorspeed = 4;
|
||||
|
||||
|
||||
cvar_t con_numnotifylines = CVAR("con_notifylines","4"); //max lines to show
|
||||
cvar_t con_notifytime = CVAR("con_notifytime","3"); //seconds
|
||||
cvar_t con_notify_x = CVAR("con_notify_x","0");
|
||||
cvar_t con_notify_y = CVAR("con_notify_y","0");
|
||||
cvar_t con_notify_w = CVAR("con_notify_w","1");
|
||||
cvar_t con_centernotify = CVAR("con_centernotify", "0");
|
||||
cvar_t con_displaypossibilities = CVAR("con_displaypossibilities", "1");
|
||||
cvar_t con_showcompletion = CVAR("con_showcompletion", "1");
|
||||
cvar_t con_maxlines = CVAR("con_maxlines", "1024");
|
||||
cvar_t cl_chatmode = CVARD("cl_chatmode", "2", "0(nq) - everything is assumed to be a console command. prefix with 'say', or just use a messagemode bind\n1(q3) - everything is assumed to be chat, unless its prefixed with a /\n2(qw) - anything explicitly recognised as a command will be used as a command, anything unrecognised will be a chat message.\n/ prefix is supported in all cases.\nctrl held when pressing enter always makes any implicit chat into team chat instead.");
|
||||
cvar_t con_numnotifylines_chat = CVAR("con_numnotifylines_chat", "8");
|
||||
cvar_t con_notifytime_chat = CVAR("con_notifytime_chat", "8");
|
||||
cvar_t con_separatechat = CVAR("con_separatechat", "0");
|
||||
cvar_t con_timestamps = CVAR("con_timestamps", "0");
|
||||
cvar_t con_timeformat = CVAR("con_timeformat", "(%H:%M:%S) ");
|
||||
cvar_t con_textsize = CVARD("con_textsize", "8", "Resize the console text to be a different height, scaled separately from the hud. The value is the height in (virtual) pixels.");
|
||||
static cvar_t con_numnotifylines = CVAR("con_notifylines","4"); //max lines to show
|
||||
static cvar_t con_notifytime = CVAR("con_notifytime","3"); //seconds
|
||||
static cvar_t con_notify_x = CVAR("con_notify_x","0");
|
||||
static cvar_t con_notify_y = CVAR("con_notify_y","0");
|
||||
static cvar_t con_notify_w = CVAR("con_notify_w","1");
|
||||
static cvar_t con_centernotify = CVAR("con_centernotify", "0");
|
||||
static cvar_t con_displaypossibilities = CVAR("con_displaypossibilities", "1");
|
||||
static cvar_t con_showcompletion = CVAR("con_showcompletion", "1");
|
||||
static cvar_t con_maxlines = CVAR("con_maxlines", "1024");
|
||||
cvar_t cl_chatmode = CVARD("cl_chatmode", "2", "0(nq) - everything is assumed to be a console command. prefix with 'say', or just use a messagemode bind\n1(q3) - everything is assumed to be chat, unless its prefixed with a /\n2(qw) - anything explicitly recognised as a command will be used as a command, anything unrecognised will be a chat message.\n/ prefix is supported in all cases.\nctrl held when pressing enter always makes any implicit chat into team chat instead.");
|
||||
static cvar_t con_numnotifylines_chat = CVAR("con_numnotifylines_chat", "8");
|
||||
static cvar_t con_notifytime_chat = CVAR("con_notifytime_chat", "8");
|
||||
cvar_t con_separatechat = CVAR("con_separatechat", "0");
|
||||
static cvar_t con_timestamps = CVAR("con_timestamps", "0");
|
||||
static cvar_t con_timeformat = CVAR("con_timeformat", "(%H:%M:%S) ");
|
||||
cvar_t con_textsize = CVARD("con_textsize", "8", "Resize the console text to be a different height, scaled separately from the hud. The value is the height in (virtual) pixels.");
|
||||
extern cvar_t log_developer;
|
||||
|
||||
void con_window_cb(cvar_t *var, char *oldval)
|
||||
{
|
||||
if (!con_main)
|
||||
return; //doesn't matter right now.
|
||||
|
||||
if (var->ival)
|
||||
{
|
||||
con_main->flags &= ~CONF_NOTIFY;
|
||||
if (!(con_main->flags & CONF_ISWINDOW))
|
||||
{
|
||||
con_main->flags |= CONF_ISWINDOW;
|
||||
if (con_current == con_main)
|
||||
Con_SetActive(con_main);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
con_main->flags |= CONF_NOTIFY;
|
||||
if (con_main->flags & CONF_ISWINDOW)
|
||||
{
|
||||
con_main->flags &= ~CONF_ISWINDOW;
|
||||
if (con_curwindow == con_main)
|
||||
Con_SetActive(con_main);
|
||||
}
|
||||
}
|
||||
}
|
||||
static cvar_t con_window = CVARCD("con_window", "0", con_window_cb, "States whether the console should be a floating window as in source engine games, or a top-of-the-screen-only thing.");
|
||||
|
||||
#define NUM_CON_TIMES 24
|
||||
|
||||
qboolean con_initialized;
|
||||
|
@ -110,7 +140,7 @@ int Con_IsActive (console_t *con)
|
|||
void Con_Destroy (console_t *con)
|
||||
{
|
||||
shader_t *shader;
|
||||
console_t *prev;
|
||||
console_t **link;
|
||||
conline_t *t;
|
||||
|
||||
if (con->close)
|
||||
|
@ -135,19 +165,11 @@ void Con_Destroy (console_t *con)
|
|||
Z_Free(con->completionline);
|
||||
con->completionline = NULL;
|
||||
|
||||
if (con == &con_main)
|
||||
for (link = &con_head; *link; link = &(*link)->next)
|
||||
{
|
||||
/*main console is never destroyed, only cleared (unless shutting down)*/
|
||||
if (con_initialized)
|
||||
Con_Finit(con);
|
||||
return;
|
||||
}
|
||||
|
||||
for (prev = &con_main; prev->next; prev = prev->next)
|
||||
{
|
||||
if (prev->next == con)
|
||||
if (*link == con)
|
||||
{
|
||||
prev->next = con->next;
|
||||
(*link) = con->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -156,12 +178,15 @@ void Con_Destroy (console_t *con)
|
|||
|
||||
BZ_Free(con);
|
||||
|
||||
//make sure any special references are fixed up now that its gone
|
||||
if (con_mouseover == con)
|
||||
con_mouseover = NULL;
|
||||
if (con_current == con)
|
||||
con_current = &con_main;
|
||||
con_current = con_head;
|
||||
|
||||
if (con_curwindow == con)
|
||||
{
|
||||
for (con_curwindow = &con_main; con_curwindow; con_curwindow = con_curwindow->next)
|
||||
for (con_curwindow = con_head; con_curwindow; con_curwindow = con_curwindow->next)
|
||||
{
|
||||
if (con_curwindow->flags & CONF_ISWINDOW)
|
||||
break;
|
||||
|
@ -180,7 +205,7 @@ void Con_FlushBackgrounds(void)
|
|||
{
|
||||
console_t *con;
|
||||
//fixme: we really need to handle videomaps differently here, for vid_restarts.
|
||||
for (con = &con_main; con; con = con->next)
|
||||
for (con = con_head; con; con = con->next)
|
||||
{
|
||||
if (con->backshader)
|
||||
R_UnloadShader(con->backshader);
|
||||
|
@ -194,7 +219,9 @@ console_t *Con_FindConsole(const char *name)
|
|||
console_t *con;
|
||||
if (!strcmp(name, "current") && con_current)
|
||||
return con_current;
|
||||
for (con = &con_main; con; con = con->next)
|
||||
if (!strcmp(name, "head") && con_current)
|
||||
return con_head;
|
||||
for (con = con_head; con; con = con->next)
|
||||
{
|
||||
if (!strcmp(con->name, name))
|
||||
return con;
|
||||
|
@ -204,9 +231,11 @@ console_t *Con_FindConsole(const char *name)
|
|||
/*creates a potentially duplicate console_t - please use Con_FindConsole first, as its confusing otherwise*/
|
||||
console_t *Con_Create(const char *name, unsigned int flags)
|
||||
{
|
||||
console_t *con;
|
||||
console_t *con, *p;
|
||||
if (!strcmp(name, "current"))
|
||||
return NULL;
|
||||
if (!strcmp(name, "head"))
|
||||
return NULL;
|
||||
con = Z_Malloc(sizeof(console_t));
|
||||
Q_strncpyz(con->name, name, sizeof(con->name));
|
||||
Q_strncpyz(con->title, name, sizeof(con->title));
|
||||
|
@ -214,11 +243,51 @@ console_t *Con_Create(const char *name, unsigned int flags)
|
|||
|
||||
con->flags = flags;
|
||||
Con_Finit(con);
|
||||
con->next = con_main.next;
|
||||
con_main.next = con;
|
||||
|
||||
//insert at end. make it active if you must.
|
||||
if (!con_head)
|
||||
con_head = con;
|
||||
else
|
||||
{
|
||||
for (p = con_head; p->next; p = p->next)
|
||||
;
|
||||
p->next = con;
|
||||
}
|
||||
|
||||
return con;
|
||||
}
|
||||
|
||||
static qboolean Con_Main_BlockClose(console_t *con, qboolean force)
|
||||
{
|
||||
if (!force)
|
||||
{ //trying to close it just hides it (this is to avoid it getting cleared).
|
||||
if (con_curwindow == con)
|
||||
Key_Dest_Remove(kdm_cwindows);
|
||||
return false;
|
||||
}
|
||||
con_main = NULL; //its forced to die. and don't forget it.
|
||||
return true;
|
||||
}
|
||||
console_t *Con_GetMain(void)
|
||||
{
|
||||
if (!con_main)
|
||||
{
|
||||
con_main = Con_Create("", 0);
|
||||
|
||||
con_main->linebuffered = Con_ExecuteLine;
|
||||
con_main->commandcompletion = true;
|
||||
con_main->wnd_w = 640;
|
||||
con_main->wnd_h = 480;
|
||||
con_main->wnd_x = 0;
|
||||
con_main->wnd_y = 0;
|
||||
con_main->close = Con_Main_BlockClose;
|
||||
Q_strncpyz(con_main->title, "MAIN", sizeof(con_main->title));
|
||||
Q_strncpyz(con_main->prompt, "]", sizeof(con_main->prompt));
|
||||
|
||||
Cvar_ForceCallback(&con_window);
|
||||
}
|
||||
return con_main;
|
||||
}
|
||||
/*sets a console as the active one*/
|
||||
void Con_SetActive (console_t *con)
|
||||
{
|
||||
|
@ -231,7 +300,7 @@ void Con_SetActive (console_t *con)
|
|||
if (con_curwindow == con)
|
||||
return;
|
||||
|
||||
for (prev = &con_main; prev; prev = prev->next)
|
||||
for (prev = con_head; prev; prev = prev->next)
|
||||
{
|
||||
if (prev->next == con)
|
||||
{
|
||||
|
@ -248,7 +317,13 @@ void Con_SetActive (console_t *con)
|
|||
con_curwindow = con;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (con_curwindow == con)
|
||||
con_curwindow = NULL;
|
||||
Key_Dest_Add(kdm_console);
|
||||
Key_Dest_Remove(kdm_cwindows);
|
||||
con_current = con;
|
||||
}
|
||||
|
||||
if (con->footerline)
|
||||
{
|
||||
|
@ -263,7 +338,7 @@ void Con_SetActive (console_t *con)
|
|||
qboolean Con_NameForNum(int num, char *buffer, int buffersize)
|
||||
{
|
||||
console_t *con;
|
||||
for (con = &con_main; con; con = con->next, num--)
|
||||
for (con = con_head; con; con = con->next, num--)
|
||||
{
|
||||
if (num <= 0)
|
||||
{
|
||||
|
@ -544,9 +619,11 @@ void Con_ToggleConsole_f (void)
|
|||
{
|
||||
extern cvar_t con_stayhidden;
|
||||
|
||||
Con_GetMain();
|
||||
|
||||
if (!con_curwindow)
|
||||
{
|
||||
for (con_curwindow = &con_main; con_curwindow; con_curwindow = con_curwindow->next)
|
||||
for (con_curwindow = con_head; con_curwindow; con_curwindow = con_curwindow->next)
|
||||
if (con_curwindow->flags & CONF_ISWINDOW)
|
||||
break;
|
||||
}
|
||||
|
@ -598,9 +675,10 @@ Con_Clear_f
|
|||
*/
|
||||
void Con_Clear_f (void)
|
||||
{
|
||||
if (Cmd_IsInsecure())
|
||||
console_t *con = Con_FindConsole(Cmd_Argv(1));
|
||||
if (!con || Cmd_IsInsecure())
|
||||
return;
|
||||
Con_ClearCon(&con_main);
|
||||
Con_ClearCon(con);
|
||||
}
|
||||
|
||||
|
||||
|
@ -680,7 +758,7 @@ void Con_MessageMode2_f (void)
|
|||
void Con_ForceActiveNow(void)
|
||||
{
|
||||
Key_Dest_Add(kdm_console);
|
||||
scr_conlines = scr_con_current = vid.height;
|
||||
scr_con_target = scr_con_current = vid.height;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -692,18 +770,10 @@ void Log_Init (void);
|
|||
|
||||
void Con_Init (void)
|
||||
{
|
||||
con_current = &con_main;
|
||||
Con_Finit(&con_main);
|
||||
con_current = NULL;
|
||||
con_head = NULL;
|
||||
|
||||
con_main.linebuffered = Con_ExecuteLine;
|
||||
con_main.commandcompletion = true;
|
||||
// con_main.flags |= CONF_ISWINDOW;
|
||||
con_main.wnd_w = 640;
|
||||
con_main.wnd_h = 480;
|
||||
con_main.wnd_x = 0;
|
||||
con_main.wnd_y = 0;
|
||||
Q_strncpyz(con_main.title, "MAIN", sizeof(con_main.title));
|
||||
Q_strncpyz(con_main.prompt, "]", sizeof(con_main.prompt));
|
||||
con_main = Con_GetMain();
|
||||
|
||||
con_initialized = true;
|
||||
// Con_TPrintf ("Console initialized.\n");
|
||||
|
@ -727,6 +797,8 @@ void Con_Init (void)
|
|||
Cvar_Register (&con_timestamps, "Console controls");
|
||||
Cvar_Register (&con_timeformat, "Console controls");
|
||||
Cvar_Register (&con_textsize, "Console controls");
|
||||
Cvar_Register (&con_window, "Console controls");
|
||||
Cvar_ForceCallback(&con_window);
|
||||
|
||||
Cmd_AddCommand ("toggleconsole", Con_ToggleConsole_f);
|
||||
Cmd_AddCommand ("messagemode", Con_MessageMode_f);
|
||||
|
@ -736,11 +808,11 @@ void Con_Init (void)
|
|||
Cmd_AddCommand ("qterm", Con_QTerm_f);
|
||||
#endif
|
||||
|
||||
Cmd_AddCommand ("conecho_center", Cmd_ConEchoCenter_f);
|
||||
Cmd_AddCommand ("conecho", Cmd_ConEcho_f);
|
||||
Cmd_AddCommand ("conclear", Cmd_ConClear_f);
|
||||
Cmd_AddCommand ("conclose", Cmd_ConClose_f);
|
||||
Cmd_AddCommand ("conactivate", Cmd_ConActivate_f);
|
||||
Cmd_AddCommandD ("conecho_center", Cmd_ConEchoCenter_f, "conecho_center consolename The Text To Echo\nUse \"\" for the main console.\nAny added lines will be aligned to the middle of the console.");
|
||||
Cmd_AddCommandD ("conecho", Cmd_ConEcho_f, "conecho consolename The Text To Echo\nEchos text to a named console instead of just the main one.");
|
||||
Cmd_AddCommandD ("conclear", Cmd_ConClear_f, "Clears a named console (instead of just the main one)");
|
||||
Cmd_AddCommandD ("conclose", Cmd_ConClose_f, "Destroys a named console");
|
||||
Cmd_AddCommandD ("conactivate", Cmd_ConActivate_f, "Brings focus to the named console. Will not do anything if the named console is not created yet (so be sure to do any echos before using this command)");
|
||||
|
||||
Log_Init();
|
||||
}
|
||||
|
@ -754,12 +826,9 @@ void Con_Shutdown(void)
|
|||
BZ_Free(key_lines[i]);
|
||||
}
|
||||
|
||||
while(con_main.next)
|
||||
{
|
||||
Con_Destroy(con_main.next);
|
||||
}
|
||||
while(con_head)
|
||||
Con_Destroy(con_head);
|
||||
con_initialized = false;
|
||||
Con_Destroy(&con_main);
|
||||
}
|
||||
|
||||
void TTS_SayConString(conchar_t *stringtosay);
|
||||
|
@ -935,19 +1004,22 @@ void Con_PrintCon (console_t *con, const char *txt, unsigned int parseflags)
|
|||
|
||||
void Con_CenterPrint(const char *txt)
|
||||
{
|
||||
int flags = con_main.parseflags|PFS_NONOTIFY|PFS_CENTERED;
|
||||
Con_PrintCon(&con_main, "^Ue01d^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01f\n", flags);
|
||||
Con_PrintCon(&con_main, txt, flags); //client console
|
||||
Con_PrintCon(&con_main, "\n^Ue01d^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01f\n", flags);
|
||||
console_t *c = Con_GetMain();
|
||||
int flags = c->parseflags|PFS_NONOTIFY|PFS_CENTERED;
|
||||
Con_PrintCon(c, "^Ue01d^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01f\n", flags);
|
||||
Con_PrintCon(c, txt, flags); //client console
|
||||
Con_PrintCon(c, "\n^Ue01d^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01e^Ue01f\n", flags);
|
||||
}
|
||||
|
||||
void Con_Print (const char *txt)
|
||||
{
|
||||
Con_PrintCon(&con_main, txt, con_main.parseflags); //client console
|
||||
console_t *c = Con_GetMain();
|
||||
Con_PrintCon(c, txt, c->parseflags); //client console
|
||||
}
|
||||
void Con_PrintFlags(const char *txt, unsigned int setflags, unsigned int clearflags)
|
||||
{
|
||||
setflags |= con_main.parseflags;
|
||||
console_t *c = Con_GetMain();
|
||||
setflags |= c->parseflags;
|
||||
setflags &= ~clearflags;
|
||||
|
||||
// also echo to debugging console
|
||||
|
@ -957,19 +1029,26 @@ void Con_PrintFlags(const char *txt, unsigned int setflags, unsigned int clearfl
|
|||
Con_Log (txt);
|
||||
|
||||
if (con_initialized)
|
||||
Con_PrintCon(&con_main, txt, setflags);
|
||||
Con_PrintCon(c, txt, setflags);
|
||||
}
|
||||
|
||||
void Con_CycleConsole(void)
|
||||
{
|
||||
console_t *first = con_current?con_current:con_head;
|
||||
while(1)
|
||||
{
|
||||
con_current = con_current->next;
|
||||
if (!con_current)
|
||||
con_current = &con_main;
|
||||
con_current = con_head;
|
||||
if (con_current == first)
|
||||
{
|
||||
if (con_current->flags & (CONF_HIDDEN|CONF_ISWINDOW))
|
||||
con_current = NULL; //no valid consoles
|
||||
break; //we wrapped? oh noes
|
||||
}
|
||||
|
||||
if (con_current->flags & (CONF_HIDDEN|CONF_ISWINDOW))
|
||||
continue;
|
||||
continue; //this is a valid choice
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1098,8 +1177,9 @@ static void Con_DPrintFromThread (void *ctx, void *data, size_t a, size_t b)
|
|||
Con_Log(data);
|
||||
if (developer.ival >= (int)a)
|
||||
{
|
||||
console_t *c = Con_GetMain();
|
||||
Sys_Printf ("%s", (const char*)data); // also echo to debugging console
|
||||
Con_PrintCon(&con_main, data, con_main.parseflags);
|
||||
Con_PrintCon(c, data, c->parseflags);
|
||||
}
|
||||
BZ_Free(data);
|
||||
}
|
||||
|
@ -1140,9 +1220,9 @@ void VARGS Con_DPrintf (const char *fmt, ...)
|
|||
Con_Log(msg);
|
||||
if (developer.ival)
|
||||
{
|
||||
console_t *c = Con_GetMain();
|
||||
Sys_Printf ("%s", msg); // also echo to debugging console
|
||||
if (con_initialized)
|
||||
Con_PrintCon(&con_main, msg, con_main.parseflags);
|
||||
Con_PrintCon(c, msg, c->parseflags);
|
||||
}
|
||||
}
|
||||
void VARGS Con_DLPrintf (int level, const char *fmt, ...)
|
||||
|
@ -1177,7 +1257,10 @@ void VARGS Con_DLPrintf (int level, const char *fmt, ...)
|
|||
{
|
||||
Sys_Printf ("%s", msg); // also echo to debugging console
|
||||
if (con_initialized)
|
||||
Con_PrintCon(&con_main, msg, con_main.parseflags);
|
||||
{
|
||||
console_t *c = Con_GetMain();
|
||||
Con_PrintCon(c, msg, c->parseflags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1607,7 +1690,7 @@ void Con_ClearNotify(void)
|
|||
{
|
||||
console_t *con;
|
||||
conline_t *l;
|
||||
for (con = &con_main; con; con = con->next)
|
||||
for (con = con_head; con; con = con->next)
|
||||
{
|
||||
for (l = con->current; l; l = l->older)
|
||||
l->flags |= CONL_NONOTIFY;
|
||||
|
@ -1618,13 +1701,15 @@ void Con_DrawNotify (void)
|
|||
extern int startuppending;
|
||||
console_t *con;
|
||||
|
||||
con_main.flags |= CONF_NOTIFY;
|
||||
/*keep the main console up to date*/
|
||||
con_main.notif_l = con_numnotifylines.ival;
|
||||
con_main.notif_w = con_notify_w.value;
|
||||
con_main.notif_x = con_notify_x.value;
|
||||
con_main.notif_y = con_notify_y.value;
|
||||
con_main.notif_t = con_notifytime.value;
|
||||
if (con_main)
|
||||
{
|
||||
/*keep the main console up to date*/
|
||||
con_main->notif_l = con_numnotifylines.ival;
|
||||
con_main->notif_w = con_notify_w.value;
|
||||
con_main->notif_x = con_notify_x.value;
|
||||
con_main->notif_y = con_notify_y.value;
|
||||
con_main->notif_t = con_notifytime.value;
|
||||
}
|
||||
|
||||
if (con_chat)
|
||||
{
|
||||
|
@ -1643,7 +1728,7 @@ void Con_DrawNotify (void)
|
|||
}
|
||||
else
|
||||
{
|
||||
for (con = &con_main; con; con = con->next)
|
||||
for (con = con_head; con; con = con->next)
|
||||
{
|
||||
if (con->flags & CONF_NOTIFY)
|
||||
Con_DrawNotifyOne(con);
|
||||
|
@ -1660,7 +1745,7 @@ void Con_DrawNotify (void)
|
|||
char *foo = va(chat_team?"say_team: %s":"say: %s", chat_buffer?(char*)chat_buffer:"");
|
||||
int lines, i, pos;
|
||||
Font_BeginString(font_console, 0, 0, &x, &y);
|
||||
y = con_main.notif_l * Font_CharHeight();
|
||||
y = con_numnotifylines.ival * Font_CharHeight();
|
||||
|
||||
i = chat_team?10:5;
|
||||
pos = strlen(foo)+i;
|
||||
|
@ -1697,12 +1782,15 @@ void Con_DrawNotify (void)
|
|||
//This is so that system consoles in windows can scroll up and have all the text.
|
||||
void Con_PrintToSys(void)
|
||||
{
|
||||
console_t *curcon = &con_main;
|
||||
console_t *curcon = con_main;
|
||||
conline_t *l;
|
||||
int i;
|
||||
conchar_t *t;
|
||||
char buf[16];
|
||||
|
||||
if (!curcon)
|
||||
return;
|
||||
|
||||
for (l = curcon->oldest; l; l = l->newer)
|
||||
{
|
||||
t = (conchar_t*)(l+1);
|
||||
|
@ -1896,23 +1984,23 @@ int Con_DrawAlternateConsoles(int lines)
|
|||
char *txt;
|
||||
int x, y = 0, lx;
|
||||
int consshown = 0;
|
||||
console_t *con = &con_main, *om = con_mouseover;
|
||||
console_t *con, *om = con_mouseover;
|
||||
conchar_t buffer[512], *end, *start;
|
||||
unsigned int codeflags, codepoint;
|
||||
|
||||
for (con = &con_main; con; con = con->next)
|
||||
for (con = con_head; con; con = con->next)
|
||||
{
|
||||
if (!(con->flags & (CONF_HIDDEN|CONF_ISWINDOW)))
|
||||
consshown++;
|
||||
}
|
||||
|
||||
if (lines == (int)scr_conlines && consshown > 1)
|
||||
if (lines == (int)scr_con_target && consshown > 1)
|
||||
{
|
||||
int mx, my, h;
|
||||
Font_BeginString(font_console, mousecursor_x, mousecursor_y, &mx, &my);
|
||||
Font_BeginString(font_console, 0, y, &x, &y);
|
||||
h = Font_CharHeight();
|
||||
for (x = 0, con = &con_main; con; con = con->next)
|
||||
for (x = 0, con = con_head; con; con = con->next)
|
||||
{
|
||||
if (con->flags & (CONF_HIDDEN|CONF_ISWINDOW))
|
||||
continue;
|
||||
|
@ -2386,10 +2474,13 @@ void Con_DrawConsole (int lines, qboolean noback)
|
|||
console_t *w, *mouseconsole;
|
||||
float fadetime;
|
||||
|
||||
if (!con_current)
|
||||
con_current = Con_GetMain();
|
||||
|
||||
con_mouseover = NULL;
|
||||
|
||||
//draw any windowed consoles (under main console)
|
||||
for (w = &con_main; w; w = w->next)
|
||||
for (w = con_head; w; w = w->next)
|
||||
{
|
||||
srect_t srect;
|
||||
if ((w->flags & (CONF_HIDDEN|CONF_ISWINDOW)) != CONF_ISWINDOW)
|
||||
|
@ -2576,7 +2667,7 @@ void Con_DrawConsole (int lines, qboolean noback)
|
|||
}
|
||||
|
||||
//draw main console...
|
||||
if (lines > 0 && !(con_current->flags & CONF_ISWINDOW))
|
||||
if (lines > 0 && con_current && !(con_current->flags & CONF_ISWINDOW))
|
||||
{
|
||||
int top;
|
||||
#ifdef QTERM
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1579,16 +1579,16 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
|
|||
if ((unicode >= '0' && unicode <= '9') || unicode == '.' || key < 0)
|
||||
key = 0;
|
||||
|
||||
if (key == K_TAB && !(con->flags & CONF_ISWINDOW) && ctrl&&shift)
|
||||
{ // cycle consoles with ctrl+shift+tab.
|
||||
// (ctrl+tab forces tab completion,
|
||||
// shift+tab controls completion cycle,
|
||||
// so it has to be both.)
|
||||
Con_CycleConsole();
|
||||
return true;
|
||||
}
|
||||
if (con->redirect)
|
||||
{
|
||||
if (key == K_TAB)
|
||||
{ // command completion
|
||||
if (ctrl || shift)
|
||||
{
|
||||
Con_CycleConsole();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (key == K_MOUSE1 || key == K_MOUSE2)
|
||||
;
|
||||
else if (con->redirect(con, unicode, key))
|
||||
|
@ -1614,7 +1614,7 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
|
|||
{
|
||||
if (key == K_MOUSE2 && !(con->flags & CONF_ISWINDOW))
|
||||
{
|
||||
if (con->close && !con->close(con, true))
|
||||
if (con->close && !con->close(con, false))
|
||||
return true;
|
||||
Con_Destroy (con);
|
||||
}
|
||||
|
@ -1843,12 +1843,6 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
|
|||
|
||||
if (key == K_TAB)
|
||||
{ // command completion
|
||||
if (ctrl&&shift)
|
||||
{
|
||||
Con_CycleConsole();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (con->commandcompletion)
|
||||
CompleteCommand (ctrl, shift?-1:1);
|
||||
return true;
|
||||
|
@ -2841,7 +2835,13 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down
|
|||
{
|
||||
if (Key_Dest_Has(kdm_console|kdm_cwindows))
|
||||
{
|
||||
console_t *con = Key_Dest_Has(kdm_console)?con_current:con_curwindow;
|
||||
console_t *con;
|
||||
if (Key_Dest_Has(kdm_console))
|
||||
con = con_current;
|
||||
else if (Key_Dest_Has(kdm_cwindows))
|
||||
con = con_curwindow;
|
||||
else
|
||||
con = NULL;
|
||||
if (con_mouseover && key >= K_MOUSE1 && key <= K_MWHEELDOWN)
|
||||
con = con_mouseover;
|
||||
if (con_curwindow && con_curwindow != con)
|
||||
|
|
|
@ -2321,7 +2321,17 @@ static void PM_StartADownload(void)
|
|||
}
|
||||
|
||||
if (tmpfile)
|
||||
{
|
||||
p->download = HTTP_CL_Get(mirror, NULL, PM_Download_Got);
|
||||
if (!p->download)
|
||||
Con_Printf("Unable to download %s\n", p->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
char syspath[MAX_OSPATH];
|
||||
FS_NativePath(temp, p->fsroot, syspath, sizeof(syspath));
|
||||
Con_Printf("Unable to write %s. Fix permissions before trying to download %s\n", syspath, p->name);
|
||||
}
|
||||
if (p->download)
|
||||
{
|
||||
Con_Printf("Downloading %s\n", p->name);
|
||||
|
@ -2333,7 +2343,6 @@ static void PM_StartADownload(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
Con_Printf("Unable to download %s\n", p->name);
|
||||
p->flags &= ~DPF_MARKED; //can't do it.
|
||||
if (tmpfile)
|
||||
VFS_CLOSE(tmpfile);
|
||||
|
|
|
@ -213,7 +213,7 @@ void Draw_BigFontString(int x, int y, const char *text)
|
|||
p = QBigFontWorks();
|
||||
if (!p)
|
||||
{
|
||||
Draw_AltFunString(x, y, text);
|
||||
Draw_AltFunString(x, y + (20-8)/2, text);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -438,7 +438,10 @@ static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu
|
|||
case mt_menudot:
|
||||
i = (int)(realtime * 10)%maxdots;
|
||||
p = R2D_SafeCachePic(va(menudotstyle, i+mindot ));
|
||||
R2D_ScalePic(xpos+option->common.posx, ypos+option->common.posy+dotofs, option->common.width, option->common.height, p);
|
||||
if (R_GetShaderSizes(p, NULL, NULL, false)>0)
|
||||
R2D_ScalePic(xpos+option->common.posx, ypos+option->common.posy+dotofs, option->common.width, option->common.height, p);
|
||||
else if ((int)(realtime*4)&1)
|
||||
Draw_FunString(xpos+option->common.posx, ypos+option->common.posy + (option->common.height-8)/2, "^a^Ue00d");
|
||||
break;
|
||||
case mt_picturesel:
|
||||
p = NULL;
|
||||
|
@ -2206,6 +2209,8 @@ void M_Menu_Main_f (void)
|
|||
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, 36);
|
||||
}
|
||||
|
||||
if (!m_preset_chosen.ival)
|
||||
|
|
|
@ -2986,7 +2986,7 @@ static void QDECL capture_raw_video (void *vctx, int frame, void *data, int stri
|
|||
char filename[MAX_OSPATH];
|
||||
ctx->frames = frame+1;
|
||||
Q_snprintfz(filename, sizeof(filename), "%s%8.8i.%s", ctx->videonameprefix, frame, ctx->videonameextension);
|
||||
SCR_ScreenShot(filename, ctx->fsroot, &data, 1, stride, width, height, fmt);
|
||||
SCR_ScreenShot(filename, ctx->fsroot, &data, 1, stride, width, height, fmt, true);
|
||||
|
||||
if (capturethrottlesize.ival)
|
||||
{
|
||||
|
@ -5159,10 +5159,10 @@ void Media_Init(void)
|
|||
#endif
|
||||
Media_RegisterEncoder(NULL, &capture_raw);
|
||||
|
||||
Cmd_AddCommand("capture", Media_RecordFilm_f);
|
||||
Cmd_AddCommand("capturedemo", Media_RecordDemo_f);
|
||||
Cmd_AddCommand("capturestop", Media_StopRecordFilm_f);
|
||||
Cmd_AddCommand("capturepause", Media_CapturePause_f);
|
||||
Cmd_AddCommandD("capture", Media_RecordFilm_f, "Captures realtime action to a named video file. Check the capture* cvars to control driver/codecs/rates.");
|
||||
Cmd_AddCommandD("capturedemo", Media_RecordDemo_f, "Capture a nemed demo to a named video file. Demo capturing can be performed offscreen, allowing arbitrary video sizes, or smooth captures on underpowered hardware.");
|
||||
Cmd_AddCommandD("capturestop", Media_StopRecordFilm_f, "Aborts the current video capture.");
|
||||
Cmd_AddCommandD("capturepause", Media_CapturePause_f, "Pauses the video capture, allowing you to avoid capturing uninteresting parts. This is a toggle, so reuse the same command to resume capturing again.");
|
||||
|
||||
Cvar_Register(&capturemessage, "Video Capture Controls");
|
||||
Cvar_Register(&capturesound, "Video Capture Controls");
|
||||
|
|
|
@ -145,6 +145,7 @@ void R_DrawTextField(int x, int y, int w, int h, const char *text, unsigned int
|
|||
#define CPRINT_RALIGN (1<<2) //R
|
||||
#define CPRINT_BALIGN (1<<3) //B
|
||||
#define CPRINT_BACKGROUND (1<<4) //P
|
||||
#define CPRINT_NOWRAP (1<<5)
|
||||
|
||||
#define CPRINT_OBITUARTY (1<<16) //O (show at 2/3rds from top)
|
||||
#define CPRINT_PERSIST (1<<17) //P (doesn't time out)
|
||||
|
@ -309,6 +310,8 @@ struct pendingtextureinfo
|
|||
int depth;
|
||||
qboolean needfree;
|
||||
} mip[72]; //enough for a 4096 cubemap. or a really smegging big 2d texture...
|
||||
//mips are ordered as in arrayindex THEN mip order, allowing easy truncation of mip levels.
|
||||
//cubemaps are just arrayindex*6
|
||||
};
|
||||
|
||||
//small context for easy vbo creation.
|
||||
|
|
|
@ -1117,7 +1117,7 @@ static void QCBUILTIN PF_R_DynamicLight_Set(pubprogfuncs_t *prinst, struct globa
|
|||
{
|
||||
const char *s;
|
||||
dlight_t *l;
|
||||
unsigned int lno = G_FLOAT(OFS_PARM0);
|
||||
size_t lno = G_FLOAT(OFS_PARM0);
|
||||
int field = G_FLOAT(OFS_PARM1);
|
||||
while (lno >= cl_maxdlights)
|
||||
{
|
||||
|
@ -1149,7 +1149,8 @@ static void QCBUILTIN PF_R_DynamicLight_Set(pubprogfuncs_t *prinst, struct globa
|
|||
l->style = G_FLOAT(OFS_PARM2)+1;
|
||||
break;
|
||||
case lfield_angles:
|
||||
AngleVectors(G_VECTOR(OFS_PARM2), l->axis[0], l->axis[1], l->axis[2]);
|
||||
VectorCopy(G_VECTOR(OFS_PARM2), l->angles);
|
||||
AngleVectors(l->angles, l->axis[0], l->axis[1], l->axis[2]);
|
||||
VectorInverse(l->axis[1]);
|
||||
break;
|
||||
case lfield_fov:
|
||||
|
@ -1170,6 +1171,11 @@ static void QCBUILTIN PF_R_DynamicLight_Set(pubprogfuncs_t *prinst, struct globa
|
|||
l->cubetexture = r_nulltex;
|
||||
break;
|
||||
#ifdef RTLIGHTS
|
||||
case lfield_stylestring:
|
||||
s = PR_GetStringOfs(prinst, OFS_PARM2);
|
||||
Z_Free(l->customstyle);
|
||||
l->customstyle = (s&&*s)?Z_StrDup(s):NULL;
|
||||
break;
|
||||
case lfield_ambientscale:
|
||||
l->lightcolourscales[0] = G_FLOAT(OFS_PARM2);
|
||||
break;
|
||||
|
@ -1202,7 +1208,6 @@ static void QCBUILTIN PF_R_DynamicLight_Set(pubprogfuncs_t *prinst, struct globa
|
|||
}
|
||||
static void QCBUILTIN PF_R_DynamicLight_Get(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
vec3_t v;
|
||||
dlight_t *l;
|
||||
unsigned int lno = G_FLOAT(OFS_PARM0);
|
||||
enum lightfield_e field = G_FLOAT(OFS_PARM1);
|
||||
|
@ -1233,10 +1238,7 @@ static void QCBUILTIN PF_R_DynamicLight_Get(pubprogfuncs_t *prinst, struct globa
|
|||
G_FLOAT(OFS_RETURN) = l->style-1;
|
||||
break;
|
||||
case lfield_angles:
|
||||
VectorAngles(l->axis[0], l->axis[2], v, false);
|
||||
G_FLOAT(OFS_RETURN+0) = anglemod(v[0]);
|
||||
G_FLOAT(OFS_RETURN+1) = v[1];
|
||||
G_FLOAT(OFS_RETURN+2) = v[2];
|
||||
VectorCopy(l->angles, G_VECTOR(OFS_RETURN));
|
||||
break;
|
||||
case lfield_fov:
|
||||
G_FLOAT(OFS_RETURN) = l->fov;
|
||||
|
@ -1251,6 +1253,12 @@ static void QCBUILTIN PF_R_DynamicLight_Get(pubprogfuncs_t *prinst, struct globa
|
|||
RETURN_TSTRING(l->cubemapname);
|
||||
break;
|
||||
#ifdef RTLIGHTS
|
||||
case lfield_stylestring:
|
||||
if (l->customstyle)
|
||||
RETURN_TSTRING(l->customstyle);
|
||||
else
|
||||
RETURN_TSTRING("");
|
||||
break;
|
||||
case lfield_ambientscale:
|
||||
G_FLOAT(OFS_RETURN) = l->lightcolourscales[0];
|
||||
break;
|
||||
|
@ -1497,7 +1505,6 @@ static void CSQC_PolyFlush(void)
|
|||
if (!csqc_poly_2d)
|
||||
{
|
||||
scenetris_t *t;
|
||||
/*regular 3d polys are inserted into a 'scene trisoup' that the backend can then source from (multiple times, depending on how its drawn)*/
|
||||
if (cl_numstris == cl_maxstris)
|
||||
{
|
||||
cl_maxstris+=8;
|
||||
|
@ -1510,7 +1517,7 @@ static void CSQC_PolyFlush(void)
|
|||
t->firstvert = csqc_poly_origvert;
|
||||
|
||||
t->numidx = cl_numstrisidx - t->firstidx;
|
||||
t->numvert = cl_numstrisvert-csqc_poly_origvert;
|
||||
t->numvert = cl_numstrisvert-t->firstvert;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2135,7 +2142,7 @@ void QCBUILTIN PF_R_SetViewFlag(pubprogfuncs_t *prinst, struct globalvars_s *pr_
|
|||
case VF_ACTIVESEAT:
|
||||
if (prinst == csqc_world.progs)
|
||||
{
|
||||
if (csqc_playerseat != *p)
|
||||
if (csqc_playerseat != (int)*p)
|
||||
{
|
||||
CSQC_ChangeLocalPlayer(*p);
|
||||
if (prinst->callargc < 3 || G_FLOAT(OFS_PARM2))
|
||||
|
@ -2419,6 +2426,9 @@ static void QCBUILTIN PF_R_RenderScene(pubprogfuncs_t *prinst, struct globalvars
|
|||
scissored = false;
|
||||
|
||||
R_DrawNameTags();
|
||||
#ifdef RTLIGHTS
|
||||
R_EditLights_DrawInfo();
|
||||
#endif
|
||||
|
||||
if (r_refdef.drawsbar)
|
||||
{
|
||||
|
@ -7010,6 +7020,9 @@ void CSQC_Shutdown(void)
|
|||
int i;
|
||||
if (csqcprogs)
|
||||
{
|
||||
if (csqcg.shutdown_function)
|
||||
PR_ExecuteProgram(csqcprogs, csqcg.shutdown_function);
|
||||
|
||||
key_dest_absolutemouse &= ~kdm_game;
|
||||
CSQC_ForgetThreads();
|
||||
PR_ReleaseFonts(kdm_game);
|
||||
|
|
|
@ -996,7 +996,7 @@ void QCBUILTIN PF_SubConGetSet (pubprogfuncs_t *prinst, struct globalvars_s *pr_
|
|||
else if (!strcmp(field, "next"))
|
||||
{
|
||||
con = con->next;
|
||||
if (con && con != &con_main)
|
||||
if (con)
|
||||
RETURN_TSTRING(con->name);
|
||||
}
|
||||
else if (!strcmp(field, "unseen"))
|
||||
|
|
|
@ -164,6 +164,7 @@ extern "C" {
|
|||
#include "mathlib.h"
|
||||
#include "cvar.h"
|
||||
#include "net.h"
|
||||
#ifndef WEBSVONLY
|
||||
#include "protocol.h"
|
||||
#include "cmd.h"
|
||||
#include "console.h"
|
||||
|
@ -197,6 +198,7 @@ extern "C" {
|
|||
#else
|
||||
#include "server.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b) ((a) > (b) ? (a) : (b))
|
||||
|
|
|
@ -967,6 +967,7 @@ void QDECL R2D_Conback_Callback(struct cvar_s *var, char *oldvalue)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef AVAIL_FREETYPE
|
||||
#if defined(_WIN32) && !defined(FTE_SDL) && !defined(WINRT) && !defined(_XBOX)
|
||||
#include <windows.h>
|
||||
qboolean R2D_Font_WasAdded(char *buffer, char *fontfilename)
|
||||
|
@ -1026,6 +1027,7 @@ int R2D_Font_ListSystemFonts(const char *fname, qofs_t fsize, time_t modtime, vo
|
|||
return true;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
void R2D_Font_Changed(void)
|
||||
{
|
||||
float tsize;
|
||||
|
@ -1062,7 +1064,9 @@ void R2D_Font_Changed(void)
|
|||
|
||||
if (!strcmp(gl_font.string, "?"))
|
||||
{
|
||||
#if defined(_WIN32) && !defined(FTE_SDL) && !defined(WINRT) && !defined(_XBOX)
|
||||
#ifndef AVAIL_FREETYPE
|
||||
Cvar_Set(&gl_font, "");
|
||||
#elif defined(_WIN32) && !defined(FTE_SDL) && !defined(WINRT) && !defined(_XBOX)
|
||||
BOOL (APIENTRY *pChooseFontW)(LPCHOOSEFONTW) = NULL;
|
||||
dllfunction_t funcs[] =
|
||||
{
|
||||
|
@ -1112,6 +1116,7 @@ void R2D_Font_Changed(void)
|
|||
return;
|
||||
#else
|
||||
Sys_EnumerateFiles("/usr/share/fonts/truetype/", "*/*.ttf", R2D_Font_ListSystemFonts, NULL, NULL);
|
||||
COM_EnumerateFiles("*.ttf", R2D_Font_ListSystemFonts, NULL);
|
||||
Cvar_Set(&gl_font, "");
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -452,6 +452,8 @@ void Image_Upload (texid_t tex, uploadfmt_t fmt, void *data, void *palette, in
|
|||
void Image_Purge(void); //purge any textures which are not needed any more (releases memory, but doesn't give null pointers).
|
||||
void Image_Init(void);
|
||||
void Image_Shutdown(void);
|
||||
qboolean Image_WriteKTXFile(const char *filename, enum fs_relative fsroot, struct pendingtextureinfo *mips);
|
||||
qboolean Image_WriteDDSFile(const char *filename, enum fs_relative fsroot, struct pendingtextureinfo *mips);
|
||||
void Image_BlockSizeForEncoding(uploadfmt_t encoding, unsigned int *blockbytes, unsigned int *blockwidth, unsigned int *blockheight);
|
||||
const char *Image_FormatName(uploadfmt_t encoding);
|
||||
|
||||
|
@ -612,10 +614,6 @@ extern cvar_t r_shadow_realtime_dlight_diffuse;
|
|||
extern cvar_t r_shadow_realtime_dlight_specular;
|
||||
extern cvar_t r_shadow_realtime_world, r_shadow_realtime_world_shadows, r_shadow_realtime_world_lightmaps;
|
||||
extern cvar_t r_shadow_shadowmapping;
|
||||
extern cvar_t r_editlights_import_radius;
|
||||
extern cvar_t r_editlights_import_ambient;
|
||||
extern cvar_t r_editlights_import_diffuse;
|
||||
extern cvar_t r_editlights_import_specular;
|
||||
extern cvar_t r_mirroralpha;
|
||||
extern cvar_t r_wateralpha;
|
||||
extern cvar_t r_lavaalpha;
|
||||
|
|
|
@ -240,7 +240,7 @@ cvar_t scr_showpause = CVAR ("showpause", "1");
|
|||
cvar_t scr_showturtle = CVAR ("showturtle", "0");
|
||||
cvar_t scr_turtlefps = CVAR ("scr_turtlefps", "10");
|
||||
cvar_t scr_sshot_compression = CVAR ("scr_sshot_compression", "75");
|
||||
cvar_t scr_sshot_type = CVAR ("scr_sshot_type", "png");
|
||||
cvar_t scr_sshot_type = CVARD ("scr_sshot_type", "png", "This specifies the default extension(and thus file format) for screenshots.\nKnown extensions are: png, jpg/jpeg, bmp, pcx, tga, ktx, dds.");
|
||||
cvar_t scr_sshot_prefix = CVAR ("scr_sshot_prefix", "screenshots/fte-");
|
||||
cvar_t scr_viewsize = CVARFC("viewsize", "100", CVAR_ARCHIVE, SCR_Viewsize_Callback);
|
||||
|
||||
|
@ -458,6 +458,7 @@ cvar_t vid_hardwaregamma = CVARFD ("vid_hardwaregamma", "1",
|
|||
cvar_t vid_desktopgamma = CVARFD ("vid_desktopgamma", "0",
|
||||
CVAR_ARCHIVE | CVAR_RENDERERLATCH, "Apply gamma ramps upon the desktop rather than the window.");
|
||||
|
||||
cvar_t r_fog_cullentities = CVARD ("r_fog_cullentities", "1", "Automatically cull entities according to fog.");
|
||||
cvar_t r_fog_exp2 = CVARD ("r_fog_exp2", "1", "Expresses how fog fades with distance. 0 (matching DarkPlaces's default) is typically more realistic, while 1 (matching FitzQuake and others) is more common.");
|
||||
cvar_t r_fog_permutation = CVARFD ("r_fog_permutation", "1", CVAR_SHADERSYSTEM, "Renders fog using a material permutation. 0 plays nicer with q3 shaders, but 1 is otherwise a better choice.");
|
||||
|
||||
|
@ -557,6 +558,7 @@ void GLRenderer_Init(void)
|
|||
Cvar_Register (&gl_overbright, GRAPHICALNICETIES);
|
||||
Cvar_Register (&gl_overbright_all, GRAPHICALNICETIES);
|
||||
Cvar_Register (&gl_dither, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_fog_cullentities, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_fog_exp2, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_fog_permutation, GLRENDEREROPTIONS);
|
||||
|
||||
|
@ -732,14 +734,9 @@ void Renderer_Init(void)
|
|||
Cmd_AddCommand("vid_toggle", R_ToggleFullscreen_f);
|
||||
|
||||
#ifdef RTLIGHTS
|
||||
Cmd_AddCommand ("r_editlights_reload", R_ReloadRTLights_f);
|
||||
Cmd_AddCommand ("r_editlights_save", R_SaveRTLights_f);
|
||||
Cvar_Register (&r_editlights_import_radius, "Realtime Light editing/importing");
|
||||
Cvar_Register (&r_editlights_import_ambient, "Realtime Light editing/importing");
|
||||
Cvar_Register (&r_editlights_import_diffuse, "Realtime Light editing/importing");
|
||||
Cvar_Register (&r_editlights_import_specular, "Realtime Light editing/importing");
|
||||
|
||||
R_EditLights_RegisterCommands();
|
||||
#endif
|
||||
|
||||
Cmd_AddCommand("r_dumpshaders", Shader_WriteOutGenerics_f);
|
||||
Cmd_AddCommand("r_remapshader", Shader_RemapShader_f);
|
||||
Cmd_AddCommand("r_showshader", Shader_ShowShader_f);
|
||||
|
@ -1243,12 +1240,12 @@ rendererinfo_t *rendererinfo[16] =
|
|||
void R_RegisterRenderer(rendererinfo_t *ri)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++)
|
||||
for (i = 0; i < countof(rendererinfo); i++)
|
||||
{ //already registered
|
||||
if (rendererinfo[i] == ri)
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++)
|
||||
for (i = 0; i < countof(rendererinfo); i++)
|
||||
{ //register it in the first empty slot
|
||||
if (!rendererinfo[i])
|
||||
{
|
||||
|
@ -1603,7 +1600,6 @@ TRACE(("dbg: R_ApplyRenderer: initing mods\n"));
|
|||
Cvar_ForceSetValue(&vid_dpi_x, vid.dpi_x);
|
||||
Cvar_ForceSetValue(&vid_dpi_y, vid.dpi_y);
|
||||
|
||||
|
||||
TRACE(("dbg: R_ApplyRenderer: R_PreNewMap (how handy)\n"));
|
||||
Surf_PreNewMap();
|
||||
|
||||
|
@ -1690,6 +1686,10 @@ TRACE(("dbg: R_ApplyRenderer: clearing world\n"));
|
|||
Plug_ResChanged();
|
||||
#endif
|
||||
Cvar_ForceCallback(&r_particlesystem);
|
||||
#ifdef MENU_NATIVECODE
|
||||
if (mn_entry)
|
||||
mn_entry->Init(MI_RENDERER, vid.width, vid.height, vid.rotpixelwidth, vid.rotpixelheight);
|
||||
#endif
|
||||
|
||||
CL_InitDlights();
|
||||
|
||||
|
@ -1861,6 +1861,22 @@ void R_ReloadRenderer_f (void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static int R_PriorityForRenderer(rendererinfo_t *r)
|
||||
{
|
||||
if (r && r->name[0])
|
||||
{
|
||||
if (r->VID_GetPriority)
|
||||
return r->VID_GetPriority();
|
||||
else if (r->rtype == QR_HEADLESS)
|
||||
return -1; //headless renderers are a really poor choice, and will make the user think it buggy.
|
||||
else if (r->rtype == QR_NONE)
|
||||
return 0; //dedicated servers are possible, but we really don't want to use them unless we have no other choice.
|
||||
else
|
||||
return 1; //assume 1 for most renderers.
|
||||
}
|
||||
return -2; //invalid renderer
|
||||
}
|
||||
|
||||
//use Cvar_ApplyLatches(CVAR_RENDERERLATCH) beforehand.
|
||||
qboolean R_BuildRenderstate(rendererstate_t *newr, char *rendererstring)
|
||||
{
|
||||
|
@ -1932,20 +1948,7 @@ qboolean R_BuildRenderstate(rendererstate_t *newr, char *rendererstring)
|
|||
//I'd like to just qsort the renderers, but that isn't stable and might reorder gl+d3d etc.
|
||||
for (i = 0; i < countof(rendererinfo); i++)
|
||||
{
|
||||
if (rendererinfo[i] && rendererinfo[i]->name[0])
|
||||
{
|
||||
if (rendererinfo[i]->VID_GetPriority)
|
||||
pri = rendererinfo[i]->VID_GetPriority();
|
||||
else if (rendererinfo[i]->rtype == QR_HEADLESS)
|
||||
pri = -1; //headless renderers are a really poor choice, and will make the user think it buggy.
|
||||
else if (rendererinfo[i]->rtype == QR_NONE)
|
||||
pri = 0; //dedicated servers are possible, but we really don't want to use them unless we have no other choice.
|
||||
else
|
||||
pri = 1; //assume 1 for most renderers.
|
||||
}
|
||||
else
|
||||
pri = -2;
|
||||
|
||||
pri = R_PriorityForRenderer(rendererinfo[i]);
|
||||
if (pri > bestpri)
|
||||
{
|
||||
bestpri = pri;
|
||||
|
@ -1956,7 +1959,7 @@ qboolean R_BuildRenderstate(rendererstate_t *newr, char *rendererstring)
|
|||
else if (!strcmp(com_token, "random"))
|
||||
{
|
||||
int count;
|
||||
for (i = 0, count = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++)
|
||||
for (i = 0, count = 0; i < countof(rendererinfo); i++)
|
||||
{
|
||||
if (!rendererinfo[i] || !rendererinfo[i]->description)
|
||||
continue; //not valid in this build. :(
|
||||
|
@ -1967,7 +1970,7 @@ qboolean R_BuildRenderstate(rendererstate_t *newr, char *rendererstring)
|
|||
count++;
|
||||
}
|
||||
count = rand()%count;
|
||||
for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++)
|
||||
for (i = 0; i < countof(rendererinfo); i++)
|
||||
{
|
||||
if (!rendererinfo[i] || !rendererinfo[i]->description)
|
||||
continue; //not valid in this build. :(
|
||||
|
@ -1986,7 +1989,7 @@ qboolean R_BuildRenderstate(rendererstate_t *newr, char *rendererstring)
|
|||
else
|
||||
{
|
||||
int bestpri = -2, pri;
|
||||
for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++)
|
||||
for (i = 0; i < countof(rendererinfo); i++)
|
||||
{
|
||||
if (!rendererinfo[i] || !rendererinfo[i]->description)
|
||||
continue; //not valid in this build. :(
|
||||
|
@ -1996,14 +1999,7 @@ qboolean R_BuildRenderstate(rendererstate_t *newr, char *rendererstring)
|
|||
continue;
|
||||
if (!stricmp(rendererinfo[i]->name[j], com_token))
|
||||
{
|
||||
if (rendererinfo[i]->VID_GetPriority)
|
||||
pri = rendererinfo[i]->VID_GetPriority();
|
||||
else if (rendererinfo[i]->rtype == QR_HEADLESS)
|
||||
pri = -1; //headless renderers are a really poor choice, and will make the user think it buggy.
|
||||
else if (rendererinfo[i]->rtype == QR_NONE)
|
||||
pri = 0; //dedicated servers are possible, but we really don't want to use them unless we have no other choice.
|
||||
else
|
||||
pri = 1;
|
||||
pri = R_PriorityForRenderer(rendererinfo[i]);
|
||||
|
||||
if (pri > bestpri)
|
||||
{
|
||||
|
@ -2073,6 +2069,21 @@ qboolean R_BuildRenderstate(rendererstate_t *newr, char *rendererstring)
|
|||
return newr->renderer != NULL;
|
||||
}
|
||||
|
||||
struct sortedrenderers_s
|
||||
{
|
||||
int index; //original index, to try to retain stable sort orders.
|
||||
int pri;
|
||||
rendererinfo_t *r;
|
||||
};
|
||||
static int QDECL R_SortRenderers(const void *av, const void *bv)
|
||||
{
|
||||
const struct sortedrenderers_s *a = av;
|
||||
const struct sortedrenderers_s *b = bv;
|
||||
if (a->pri == b->pri)
|
||||
return (a->index > b->index)?1:-1;
|
||||
return (a->pri < b->pri)?1:-1;
|
||||
}
|
||||
|
||||
void R_RestartRenderer (rendererstate_t *newr)
|
||||
{
|
||||
#ifndef CLIENTONLY
|
||||
|
@ -2112,6 +2123,7 @@ void R_RestartRenderer (rendererstate_t *newr)
|
|||
int i;
|
||||
qboolean failed = true;
|
||||
rendererinfo_t *skip = newr->renderer;
|
||||
struct sortedrenderers_s sorted[countof(rendererinfo)];
|
||||
|
||||
if (failed && newr->fullscreen == 1)
|
||||
{
|
||||
|
@ -2141,10 +2153,16 @@ void R_RestartRenderer (rendererstate_t *newr)
|
|||
failed = !R_ApplyRenderer(newr);
|
||||
}
|
||||
|
||||
//FIXME: query renderers for their priority and then use that. then we can favour X11 when DISPLAY is set and wayland when WAYLAND_DISPLAY is set, etc.
|
||||
for (i = 0; failed && i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++)
|
||||
for (i = 0; i < countof(sorted); i++)
|
||||
{
|
||||
newr->renderer = rendererinfo[i];
|
||||
sorted[i].index = i;
|
||||
sorted[i].r = rendererinfo[i];
|
||||
sorted[i].pri = R_PriorityForRenderer(sorted[i].r);
|
||||
}
|
||||
qsort(sorted, countof(sorted), sizeof(sorted[0]), R_SortRenderers);
|
||||
for (i = 0; failed && i < countof(sorted); i++)
|
||||
{
|
||||
newr->renderer = sorted[i].r;
|
||||
if (newr->renderer && newr->renderer != skip && newr->renderer->rtype != QR_HEADLESS)
|
||||
{
|
||||
Con_Printf(CON_NOTICE "Trying %s"CON_DEFAULT"\n", newr->renderer->description);
|
||||
|
@ -2216,11 +2234,21 @@ void R_SetRenderer_f (void)
|
|||
|
||||
if (Cmd_Argc() == 1 || !stricmp(param, "help"))
|
||||
{
|
||||
Con_Printf ("\nValid setrenderer parameters are:\n");
|
||||
for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++)
|
||||
struct sortedrenderers_s sorted[countof(rendererinfo)];
|
||||
for (i = 0; i < countof(sorted); i++)
|
||||
{
|
||||
if (rendererinfo[i] && rendererinfo[i]->description)
|
||||
Con_Printf("^[%s\\type\\/setrenderer %s^]^7: %s%s\n", rendererinfo[i]->name[0], rendererinfo[i]->name[0], rendererinfo[i]->description, (currentrendererstate.renderer == rendererinfo[i])?" ^2(current)":"");
|
||||
sorted[i].index = i;
|
||||
sorted[i].r = rendererinfo[i];
|
||||
sorted[i].pri = R_PriorityForRenderer(sorted[i].r);
|
||||
}
|
||||
qsort(sorted, countof(sorted), sizeof(sorted[0]), R_SortRenderers);
|
||||
|
||||
Con_Printf ("\nValid setrenderer parameters are:\n");
|
||||
for (i = 0; i < countof(rendererinfo); i++)
|
||||
{
|
||||
rendererinfo_t *r = sorted[i].r;
|
||||
if (r && r->description)
|
||||
Con_Printf("^[%s\\type\\/setrenderer %s^]^7: %s%s\n", r->name[0], r->name[0], r->description, (currentrendererstate.renderer == r)?" ^2(current)":"");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -2966,7 +2994,7 @@ void R_SetFrustum (float projmat[16], float viewmat[16])
|
|||
|
||||
//do far plane
|
||||
//fog will logically not actually reach 0, though precision issues will force it. we cut off at an exponant of -500
|
||||
if (r_refdef.globalfog.density)
|
||||
if (r_refdef.globalfog.density && r_fog_cullentities.ival)
|
||||
{
|
||||
float culldist;
|
||||
float fog;
|
||||
|
|
|
@ -22,7 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
typedef struct playerview_s playerview_t;
|
||||
|
||||
extern float scr_con_current;
|
||||
extern float scr_conlines; // lines of console to display
|
||||
extern float scr_con_target; // lines of console to display
|
||||
|
||||
extern int sb_lines;
|
||||
|
||||
|
@ -231,7 +231,7 @@ typedef enum uploadfmt
|
|||
#define PTI_EMULATED TF_INVALID:case TF_BGR24_FLIP:case TF_MIP4_R8:case TF_MIP4_SOLID8:case TF_MIP4_8PAL24:case TF_MIP4_8PAL24_T255:case TF_SOLID8:case TF_TRANS8:case TF_TRANS8_FULLBRIGHT:case TF_HEIGHT8:case TF_HEIGHT8PAL:case TF_H2_T7G1:case TF_H2_TRANS8_0:case TF_H2_T4A4:case TF_8PAL24:case TF_8PAL32:case PTI_LLLX8:case PTI_LLLA8
|
||||
} uploadfmt_t;
|
||||
|
||||
qboolean SCR_ScreenShot (char *filename, enum fs_relative fsroot, void **buffer, int numbuffers, int bytestride, int width, int height, enum uploadfmt fmt);
|
||||
qboolean SCR_ScreenShot (char *filename, enum fs_relative fsroot, void **buffer, int numbuffers, int bytestride, int width, int height, enum uploadfmt fmt, qboolean writemeta);
|
||||
|
||||
void SCR_DrawTwoDimensional(int uimenu, qboolean nohud);
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <alsa/asoundlib.h>
|
||||
|
||||
#include "quakedef.h"
|
||||
#ifdef HAVE_MIXER
|
||||
#include <dlfcn.h>
|
||||
|
||||
static void *alsasharedobject;
|
||||
|
@ -589,4 +590,4 @@ sounddriver_t ALSA_Output =
|
|||
ALSA_Enumerate
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -316,13 +316,13 @@ typedef struct {
|
|||
GUID SubFormat;
|
||||
} QWAVEFORMATEX;
|
||||
|
||||
const static GUID QKSDATAFORMAT_SUBTYPE_PCM = {0x00000001,0x0000,0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
|
||||
const static GUID QKSDATAFORMAT_SUBTYPE_IEEE_FLOAT = {0x00000003,0x0000,0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
|
||||
static const GUID QKSDATAFORMAT_SUBTYPE_PCM = {0x00000001,0x0000,0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
|
||||
static const GUID QKSDATAFORMAT_SUBTYPE_IEEE_FLOAT = {0x00000003,0x0000,0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
|
||||
|
||||
#ifdef _IKsPropertySet_
|
||||
//const static GUID CLSID_EAXDIRECTSOUND = {0x4ff53b81, 0x1ce0, 0x11d3,
|
||||
//{0xaa, 0xb8, 0x0, 0xa0, 0xc9, 0x59, 0x49, 0xd5}};
|
||||
const static GUID DSPROPSETID_EAX20_LISTENERPROPERTIES = {0x306a6a8, 0xb224, 0x11d2,
|
||||
static const GUID DSPROPSETID_EAX20_LISTENERPROPERTIES = {0x306a6a8, 0xb224, 0x11d2,
|
||||
{0x99, 0xe5, 0x0, 0x0, 0xe8, 0xd8, 0xc7, 0x22}};
|
||||
|
||||
typedef struct _EAXLISTENERPROPERTIES
|
||||
|
@ -399,7 +399,7 @@ typedef enum
|
|||
0x11d2,
|
||||
{0x99, 0xe5, 0x0, 0x0, 0xe8, 0xd8, 0xc7, 0x22}};*/
|
||||
|
||||
const static GUID CLSID_EAXDirectSound ={
|
||||
static const GUID CLSID_EAXDirectSound ={
|
||||
0x4ff53b81,
|
||||
0x1ce0,
|
||||
0x11d3,
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include <stdio.h>
|
||||
#include "quakedef.h"
|
||||
|
||||
#ifdef HAVE_MIXER
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
@ -458,23 +460,30 @@ static qboolean QDECL OSS_Enumerate(void (QDECL *cb) (const char *drivername, co
|
|||
int i;
|
||||
int fd;
|
||||
oss_sysinfo si;
|
||||
const char *devmixer;
|
||||
|
||||
if (COM_CheckParm("-nooss"))
|
||||
return true;
|
||||
fd = open("/dev/mixer", O_RDWR, 0);
|
||||
|
||||
devmixer = getenv("OSS_MIXERDEV");
|
||||
if (!devmixer)
|
||||
devmixer = "/dev/mixer";
|
||||
fd = open(devmixer, O_RDWR|O_NONBLOCK, 0);
|
||||
|
||||
if (fd == -1)
|
||||
return true; //oss not supported. don't list any devices.
|
||||
|
||||
if (ioctl(fd, SNDCTL_SYSINFO, &si) != -1)
|
||||
memset(&si, 0, sizeof(si)); //just in case the driver is really dodgy...
|
||||
if (ioctl(fd, SNDCTL_SYSINFO, &si) >= 0)
|
||||
{
|
||||
if ((si.versionnum>>16) >= 4)
|
||||
{ //only trust all the fields if its recent enough
|
||||
if ((si.versionnum>>16) >= 4 || si.numaudios > 128)
|
||||
{ //only trust all the fields if its recent enough and doesn't look dodgy.
|
||||
for(i = 0; i < si.numaudios; i++)
|
||||
{
|
||||
oss_audioinfo ai;
|
||||
memset(&ai, 0, sizeof(ai)); //just in case the driver is really dodgy...
|
||||
ai.dev = i;
|
||||
if (ioctl(fd, SNDCTL_AUDIOINFO, &ai) != -1)
|
||||
if (ioctl(fd, SNDCTL_AUDIOINFO, &ai) >= 0)
|
||||
cb(SDRVNAME, ai.devnode, ai.name);
|
||||
}
|
||||
close(fd);
|
||||
|
@ -497,9 +506,7 @@ sounddriver_t OSS_Output =
|
|||
OSS_Enumerate
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
#ifdef VOICECHAT //this does apparently work after all.
|
||||
#include <stdint.h>
|
||||
|
||||
|
@ -597,4 +604,3 @@ snd_capture_driver_t OSS_Capture =
|
|||
OSS_Capture_Shutdown
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -146,16 +146,16 @@ CHANNEL MIXING
|
|||
===============================================================================
|
||||
*/
|
||||
|
||||
static void SND_PaintChannel8_O2I1 (channel_t *ch, sfxcache_t *sc, int starttime, int count);
|
||||
static void SND_PaintChannel16_O2I1 (channel_t *ch, sfxcache_t *sc, int starttime, int count);
|
||||
static void SND_PaintChannel8_O4I1 (channel_t *ch, sfxcache_t *sc, int count);
|
||||
static void SND_PaintChannel16_O4I1 (channel_t *ch, sfxcache_t *sc, int count);
|
||||
static void SND_PaintChannel8_O6I1 (channel_t *ch, sfxcache_t *sc, int count);
|
||||
static void SND_PaintChannel16_O6I1 (channel_t *ch, sfxcache_t *sc, int count);
|
||||
static void SND_PaintChannel8_O8I1 (channel_t *ch, sfxcache_t *sc, int count);
|
||||
static void SND_PaintChannel16_O8I1 (channel_t *ch, sfxcache_t *sc, int count);
|
||||
static void SND_PaintChannel8_O2I2 (channel_t *ch, sfxcache_t *sc, int starttime, int count);
|
||||
static void SND_PaintChannel16_O2I2 (channel_t *ch, sfxcache_t *sc, int starttime, int count);
|
||||
static void SND_PaintChannel8_O2I1 (channel_t *ch, sfxcache_t *sc, int starttime, int count, int rate);
|
||||
static void SND_PaintChannel16_O2I1 (channel_t *ch, sfxcache_t *sc, int starttime, int count, int rate);
|
||||
static void SND_PaintChannel8_O4I1 (channel_t *ch, sfxcache_t *sc, int count, int rate);
|
||||
static void SND_PaintChannel16_O4I1 (channel_t *ch, sfxcache_t *sc, int count, int rate);
|
||||
static void SND_PaintChannel8_O6I1 (channel_t *ch, sfxcache_t *sc, int count, int rate);
|
||||
static void SND_PaintChannel16_O6I1 (channel_t *ch, sfxcache_t *sc, int count, int rate);
|
||||
static void SND_PaintChannel8_O8I1 (channel_t *ch, sfxcache_t *sc, int count, int rate);
|
||||
static void SND_PaintChannel16_O8I1 (channel_t *ch, sfxcache_t *sc, int count, int rate);
|
||||
static void SND_PaintChannel8_O2I2 (channel_t *ch, sfxcache_t *sc, int starttime, int count, int rate);
|
||||
static void SND_PaintChannel16_O2I2 (channel_t *ch, sfxcache_t *sc, int starttime, int count, int rate);
|
||||
|
||||
//NOTE: MAY NOT CALL SYS_ERROR
|
||||
void S_PaintChannels(soundcardinfo_t *sc, int endtime)
|
||||
|
@ -169,6 +169,7 @@ void S_PaintChannels(soundcardinfo_t *sc, int endtime)
|
|||
int ltime, count;
|
||||
int avail;
|
||||
unsigned int maxlen = ruleset_allow_overlongsounds.ival?0xffffffffu>>PITCHSHIFT:snd_speed*20;
|
||||
int rate;
|
||||
|
||||
while (sc->paintedtime < endtime)
|
||||
{
|
||||
|
@ -272,6 +273,11 @@ void S_PaintChannels(soundcardinfo_t *sc, int endtime)
|
|||
break;
|
||||
}
|
||||
|
||||
if (sc->sn.speed != scache->speed)
|
||||
rate = (ch->rate * scache->speed) / sc->sn.speed; //sound was loaded at the wrong speed. just play it back at a different speed and hope that all is well. this is nearest sampling, so expect it to be a little poo.
|
||||
else
|
||||
rate = ch->rate;
|
||||
|
||||
if (spos < scache->soundoffset || spos > scache->soundoffset+scache->length)
|
||||
avail = 0; //urm, we would be trying to read outside of the buffer. let mixing slip when there's no data available yet.
|
||||
else
|
||||
|
@ -280,7 +286,7 @@ void S_PaintChannels(soundcardinfo_t *sc, int endtime)
|
|||
avail = scache->length;
|
||||
if (avail > maxlen)
|
||||
avail = snd_speed*10;
|
||||
avail = (((int)(scache->soundoffset + avail)<<PITCHSHIFT) - ch->pos + (ch->rate-1)) / ch->rate;
|
||||
avail = (((int)(scache->soundoffset + avail)<<PITCHSHIFT) - ch->pos + (rate-1)) / rate;
|
||||
}
|
||||
// mix the smaller of how much is available or the time left
|
||||
count = min(avail, end - ltime);
|
||||
|
@ -293,38 +299,38 @@ void S_PaintChannels(soundcardinfo_t *sc, int endtime)
|
|||
if (count > (-ch->pos+255)>>PITCHSHIFT)
|
||||
count = ((-ch->pos+255)>>PITCHSHIFT);
|
||||
ltime += count;
|
||||
ch->pos += count*ch->rate;
|
||||
ch->pos += count*rate;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (scache->width == 1)
|
||||
{
|
||||
if (scache->numchannels==2)
|
||||
SND_PaintChannel8_O2I2(ch, scache, ltime-sc->paintedtime, count);
|
||||
SND_PaintChannel8_O2I2(ch, scache, ltime-sc->paintedtime, count, rate);
|
||||
else if (sc->sn.numchannels <= 2)
|
||||
SND_PaintChannel8_O2I1(ch, scache, ltime-sc->paintedtime, count);
|
||||
SND_PaintChannel8_O2I1(ch, scache, ltime-sc->paintedtime, count, rate);
|
||||
else if (sc->sn.numchannels <= 4)
|
||||
SND_PaintChannel8_O4I1(ch, scache, count);
|
||||
SND_PaintChannel8_O4I1(ch, scache, count, rate);
|
||||
else if (sc->sn.numchannels <= 6)
|
||||
SND_PaintChannel8_O6I1(ch, scache, count);
|
||||
SND_PaintChannel8_O6I1(ch, scache, count, rate);
|
||||
else
|
||||
SND_PaintChannel8_O8I1(ch, scache, count);
|
||||
SND_PaintChannel8_O8I1(ch, scache, count, rate);
|
||||
}
|
||||
else if (scache->width == 2)
|
||||
{
|
||||
if (scache->numchannels==2)
|
||||
SND_PaintChannel16_O2I2(ch, scache, ltime-sc->paintedtime, count);
|
||||
SND_PaintChannel16_O2I2(ch, scache, ltime-sc->paintedtime, count, rate);
|
||||
else if (sc->sn.numchannels <= 2)
|
||||
SND_PaintChannel16_O2I1(ch, scache, ltime-sc->paintedtime, count);
|
||||
SND_PaintChannel16_O2I1(ch, scache, ltime-sc->paintedtime, count, rate);
|
||||
else if (sc->sn.numchannels <= 4)
|
||||
SND_PaintChannel16_O4I1(ch, scache, count);
|
||||
SND_PaintChannel16_O4I1(ch, scache, count, rate);
|
||||
else if (sc->sn.numchannels <= 6)
|
||||
SND_PaintChannel16_O6I1(ch, scache, count);
|
||||
SND_PaintChannel16_O6I1(ch, scache, count, rate);
|
||||
else
|
||||
SND_PaintChannel16_O8I1(ch, scache, count);
|
||||
SND_PaintChannel16_O8I1(ch, scache, count, rate);
|
||||
}
|
||||
ltime += count;
|
||||
ch->pos += ch->rate * count;
|
||||
ch->pos += rate * count;
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
@ -337,20 +343,20 @@ void S_PaintChannels(soundcardinfo_t *sc, int endtime)
|
|||
}
|
||||
}
|
||||
|
||||
static void SND_PaintChannel8_O2I1 (channel_t *ch, sfxcache_t *sc, int starttime, int count)
|
||||
static void SND_PaintChannel8_O2I1 (channel_t *ch, sfxcache_t *sc, int starttime, int count, int rate)
|
||||
{
|
||||
int data;
|
||||
signed char *sfx;
|
||||
int i;
|
||||
unsigned int pos = ch->pos-(sc->soundoffset<<PITCHSHIFT);
|
||||
|
||||
if (ch->rate != (1<<PITCHSHIFT))
|
||||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
sfx = (signed char *)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
pos += ch->rate;
|
||||
pos += rate;
|
||||
paintbuffer[starttime+i].s[0] += ch->vol[0] * data;
|
||||
paintbuffer[starttime+i].s[1] += ch->vol[1] * data;
|
||||
}
|
||||
|
@ -367,21 +373,21 @@ static void SND_PaintChannel8_O2I1 (channel_t *ch, sfxcache_t *sc, int starttime
|
|||
}
|
||||
}
|
||||
|
||||
static void SND_PaintChannel8_O2I2 (channel_t *ch, sfxcache_t *sc, int starttime, int count)
|
||||
static void SND_PaintChannel8_O2I2 (channel_t *ch, sfxcache_t *sc, int starttime, int count, int rate)
|
||||
{
|
||||
// int data;
|
||||
signed char *sfx;
|
||||
int i;
|
||||
unsigned int pos = ch->pos-(sc->soundoffset<<PITCHSHIFT);
|
||||
|
||||
if (ch->rate != (1<<PITCHSHIFT))
|
||||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
sfx = (signed char *)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
paintbuffer[starttime+i].s[0] += ch->vol[0] * sfx[(pos>>(PITCHSHIFT-1))&~1];
|
||||
paintbuffer[starttime+i].s[1] += ch->vol[1] * sfx[(pos>>(PITCHSHIFT-1))|1];
|
||||
pos += ch->rate;
|
||||
pos += rate;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -395,20 +401,20 @@ static void SND_PaintChannel8_O2I2 (channel_t *ch, sfxcache_t *sc, int starttime
|
|||
}
|
||||
}
|
||||
|
||||
static void SND_PaintChannel8_O4I1 (channel_t *ch, sfxcache_t *sc, int count)
|
||||
static void SND_PaintChannel8_O4I1 (channel_t *ch, sfxcache_t *sc, int count, int rate)
|
||||
{
|
||||
signed char *sfx;
|
||||
int i;
|
||||
unsigned int pos = ch->pos-(sc->soundoffset<<PITCHSHIFT);
|
||||
|
||||
if (ch->rate != (1<<PITCHSHIFT))
|
||||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
signed char data;
|
||||
sfx = (signed char *)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
pos += ch->rate;
|
||||
pos += rate;
|
||||
paintbuffer[i].s[0] += ch->vol[0] * data;
|
||||
paintbuffer[i].s[1] += ch->vol[1] * data;
|
||||
paintbuffer[i].s[2] += ch->vol[2] * data;
|
||||
|
@ -428,20 +434,20 @@ static void SND_PaintChannel8_O4I1 (channel_t *ch, sfxcache_t *sc, int count)
|
|||
}
|
||||
}
|
||||
|
||||
static void SND_PaintChannel8_O6I1 (channel_t *ch, sfxcache_t *sc, int count)
|
||||
static void SND_PaintChannel8_O6I1 (channel_t *ch, sfxcache_t *sc, int count, int rate)
|
||||
{
|
||||
signed char *sfx;
|
||||
int i;
|
||||
unsigned int pos = ch->pos-(sc->soundoffset<<PITCHSHIFT);
|
||||
|
||||
if (ch->rate != (1<<PITCHSHIFT))
|
||||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
signed char data;
|
||||
sfx = (signed char *)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
pos += ch->rate;
|
||||
pos += rate;
|
||||
paintbuffer[i].s[0] += ch->vol[0] * data;
|
||||
paintbuffer[i].s[1] += ch->vol[1] * data;
|
||||
paintbuffer[i].s[2] += ch->vol[2] * data;
|
||||
|
@ -465,20 +471,20 @@ static void SND_PaintChannel8_O6I1 (channel_t *ch, sfxcache_t *sc, int count)
|
|||
}
|
||||
}
|
||||
|
||||
static void SND_PaintChannel8_O8I1 (channel_t *ch, sfxcache_t *sc, int count)
|
||||
static void SND_PaintChannel8_O8I1 (channel_t *ch, sfxcache_t *sc, int count, int rate)
|
||||
{
|
||||
signed char *sfx;
|
||||
int i;
|
||||
unsigned int pos = ch->pos-(sc->soundoffset<<PITCHSHIFT);
|
||||
|
||||
if (ch->rate != (1<<PITCHSHIFT))
|
||||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
signed char data;
|
||||
sfx = (signed char *)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
pos += ch->rate;
|
||||
pos += rate;
|
||||
paintbuffer[i].s[0] += ch->vol[0] * data;
|
||||
paintbuffer[i].s[1] += ch->vol[1] * data;
|
||||
paintbuffer[i].s[2] += ch->vol[2] * data;
|
||||
|
@ -507,7 +513,7 @@ static void SND_PaintChannel8_O8I1 (channel_t *ch, sfxcache_t *sc, int count)
|
|||
}
|
||||
|
||||
|
||||
static void SND_PaintChannel16_O2I1 (channel_t *ch, sfxcache_t *sc, int starttime, int count)
|
||||
static void SND_PaintChannel16_O2I1 (channel_t *ch, sfxcache_t *sc, int starttime, int count, int rate)
|
||||
{
|
||||
int data;
|
||||
int left, right;
|
||||
|
@ -519,7 +525,7 @@ static void SND_PaintChannel16_O2I1 (channel_t *ch, sfxcache_t *sc, int starttim
|
|||
leftvol = ch->vol[0];
|
||||
rightvol = ch->vol[1];
|
||||
|
||||
if (ch->rate != (1<<PITCHSHIFT))
|
||||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
signed short data;
|
||||
sfx = (signed short *)sc->data;
|
||||
|
@ -527,7 +533,7 @@ static void SND_PaintChannel16_O2I1 (channel_t *ch, sfxcache_t *sc, int starttim
|
|||
{
|
||||
float frac = pos&((1<<PITCHSHIFT)-1);
|
||||
data = sfx[pos>>PITCHSHIFT] * (1-frac) + sfx[(pos>>PITCHSHIFT)+1] * frac;
|
||||
pos += ch->rate;
|
||||
pos += rate;
|
||||
paintbuffer[starttime+i].s[0] += (leftvol * data)>>8;
|
||||
paintbuffer[starttime+i].s[1] += (rightvol * data)>>8;
|
||||
}
|
||||
|
@ -546,7 +552,7 @@ static void SND_PaintChannel16_O2I1 (channel_t *ch, sfxcache_t *sc, int starttim
|
|||
}
|
||||
}
|
||||
|
||||
static void SND_PaintChannel16_O2I2 (channel_t *ch, sfxcache_t *sc, int starttime, int count)
|
||||
static void SND_PaintChannel16_O2I2 (channel_t *ch, sfxcache_t *sc, int starttime, int count, int rate)
|
||||
{
|
||||
int leftvol, rightvol;
|
||||
signed short *sfx;
|
||||
|
@ -556,7 +562,7 @@ static void SND_PaintChannel16_O2I2 (channel_t *ch, sfxcache_t *sc, int starttim
|
|||
leftvol = ch->vol[0];
|
||||
rightvol = ch->vol[1];
|
||||
|
||||
if (ch->rate != (1<<PITCHSHIFT))
|
||||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
signed short l, r;
|
||||
sfx = (signed short *)sc->data;
|
||||
|
@ -564,7 +570,7 @@ static void SND_PaintChannel16_O2I2 (channel_t *ch, sfxcache_t *sc, int starttim
|
|||
{
|
||||
l = sfx[(pos>>(PITCHSHIFT-1))&~1];
|
||||
r = sfx[(pos>>(PITCHSHIFT-1))|1];
|
||||
pos += ch->rate;
|
||||
pos += rate;
|
||||
paintbuffer[starttime+i].s[0] += (ch->vol[0] * l)>>8;
|
||||
paintbuffer[starttime+i].s[1] += (ch->vol[1] * r)>>8;
|
||||
}
|
||||
|
@ -580,7 +586,7 @@ static void SND_PaintChannel16_O2I2 (channel_t *ch, sfxcache_t *sc, int starttim
|
|||
}
|
||||
}
|
||||
|
||||
static void SND_PaintChannel16_O4I1 (channel_t *ch, sfxcache_t *sc, int count)
|
||||
static void SND_PaintChannel16_O4I1 (channel_t *ch, sfxcache_t *sc, int count, int rate)
|
||||
{
|
||||
int vol[4];
|
||||
signed short *sfx;
|
||||
|
@ -592,14 +598,14 @@ static void SND_PaintChannel16_O4I1 (channel_t *ch, sfxcache_t *sc, int count)
|
|||
vol[2] = ch->vol[2];
|
||||
vol[3] = ch->vol[3];
|
||||
|
||||
if (ch->rate != (1<<PITCHSHIFT))
|
||||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
signed short data;
|
||||
sfx = (signed short *)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
pos += ch->rate;
|
||||
pos += rate;
|
||||
paintbuffer[i].s[0] += (vol[0] * data)>>8;
|
||||
paintbuffer[i].s[1] += (vol[1] * data)>>8;
|
||||
paintbuffer[i].s[2] += (vol[2] * data)>>8;
|
||||
|
@ -619,7 +625,7 @@ static void SND_PaintChannel16_O4I1 (channel_t *ch, sfxcache_t *sc, int count)
|
|||
}
|
||||
}
|
||||
|
||||
static void SND_PaintChannel16_O6I1 (channel_t *ch, sfxcache_t *sc, int count)
|
||||
static void SND_PaintChannel16_O6I1 (channel_t *ch, sfxcache_t *sc, int count, int rate)
|
||||
{
|
||||
int vol[6];
|
||||
signed short *sfx;
|
||||
|
@ -633,14 +639,14 @@ static void SND_PaintChannel16_O6I1 (channel_t *ch, sfxcache_t *sc, int count)
|
|||
vol[4] = ch->vol[4];
|
||||
vol[5] = ch->vol[5];
|
||||
|
||||
if (ch->rate != (1<<PITCHSHIFT))
|
||||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
signed short data;
|
||||
sfx = (signed short *)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
pos += ch->rate;
|
||||
pos += rate;
|
||||
paintbuffer[i].s[0] += (vol[0] * data)>>8;
|
||||
paintbuffer[i].s[1] += (vol[1] * data)>>8;
|
||||
paintbuffer[i].s[2] += (vol[2] * data)>>8;
|
||||
|
@ -664,7 +670,7 @@ static void SND_PaintChannel16_O6I1 (channel_t *ch, sfxcache_t *sc, int count)
|
|||
}
|
||||
}
|
||||
|
||||
static void SND_PaintChannel16_O8I1 (channel_t *ch, sfxcache_t *sc, int count)
|
||||
static void SND_PaintChannel16_O8I1 (channel_t *ch, sfxcache_t *sc, int count, int rate)
|
||||
{
|
||||
int vol[8];
|
||||
signed short *sfx;
|
||||
|
@ -680,14 +686,14 @@ static void SND_PaintChannel16_O8I1 (channel_t *ch, sfxcache_t *sc, int count)
|
|||
vol[6] = ch->vol[6];
|
||||
vol[7] = ch->vol[7];
|
||||
|
||||
if (ch->rate != (1<<PITCHSHIFT))
|
||||
if (rate != (1<<PITCHSHIFT))
|
||||
{
|
||||
signed short data;
|
||||
sfx = (signed short *)sc->data;
|
||||
for (i=0 ; i<count ; i++)
|
||||
{
|
||||
data = sfx[pos>>PITCHSHIFT];
|
||||
pos += ch->rate;
|
||||
pos += rate;
|
||||
paintbuffer[i].s[0] += (vol[0] * data)>>8;
|
||||
paintbuffer[i].s[1] += (vol[1] * data)>>8;
|
||||
paintbuffer[i].s[2] += (vol[2] * data)>>8;
|
||||
|
|
|
@ -65,6 +65,25 @@ static const char *(SDLCALL *SDL_GetError) (void);
|
|||
static uint32_t (SDLCALL *SDL_GetQueuedAudioSize) (SDL_AudioDeviceID dev);
|
||||
static uint32_t (SDLCALL *SDL_DequeueAudio) (SDL_AudioDeviceID dev, void *data, uint32_t len);
|
||||
#endif
|
||||
static dllfunction_t sdl_funcs[] =
|
||||
{
|
||||
{(void*)&SDL_Init, "SDL_Init"},
|
||||
{(void*)&SDL_InitSubSystem, "SDL_InitSubSystem"},
|
||||
{(void*)&SDL_OpenAudioDevice, "SDL_OpenAudioDevice"},
|
||||
{(void*)&SDL_PauseAudioDevice, "SDL_PauseAudioDevice"},
|
||||
{(void*)&SDL_LockAudioDevice, "SDL_LockAudioDevice"},
|
||||
{(void*)&SDL_UnlockAudioDevice, "SDL_UnlockAudioDevice"},
|
||||
{(void*)&SDL_CloseAudioDevice, "SDL_CloseAudioDevice"},
|
||||
{(void*)&SDL_GetNumAudioDevices, "SDL_GetNumAudioDevices"},
|
||||
{(void*)&SDL_GetAudioDeviceName, "SDL_GetAudioDeviceName"},
|
||||
{(void*)&SDL_GetError, "SDL_GetError"},
|
||||
#if SDL_VERSION_ATLEAST(2,0,5)
|
||||
{(void*)&SDL_GetQueuedAudioSize, "SDL_GetQueuedAudioSize"},
|
||||
{(void*)&SDL_DequeueAudio, "SDL_DequeueAudio"},
|
||||
#endif
|
||||
{NULL, NULL}
|
||||
};
|
||||
static dllhandle_t *libsdl;
|
||||
#else
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
@ -81,34 +100,17 @@ static uint32_t (SDLCALL *SDL_DequeueAudio) (SDL_AudioDeviceID dev, void *da
|
|||
static qboolean SSDL_InitAudio(void)
|
||||
{
|
||||
static qboolean inited = false;
|
||||
if (COM_CheckParm("-nosdlsnd") || COM_CheckParm("-nosdl"))
|
||||
return false;
|
||||
#ifdef DYNAMIC_SDL
|
||||
static dllfunction_t funcs[] =
|
||||
{
|
||||
{(void*)&SDL_Init, "SDL_Init"},
|
||||
{(void*)&SDL_InitSubSystem, "SDL_InitSubSystem"},
|
||||
{(void*)&SDL_OpenAudioDevice, "SDL_OpenAudioDevice"},
|
||||
{(void*)&SDL_PauseAudioDevice, "SDL_PauseAudioDevice"},
|
||||
{(void*)&SDL_LockAudioDevice, "SDL_LockAudioDevice"},
|
||||
{(void*)&SDL_UnlockAudioDevice, "SDL_UnlockAudioDevice"},
|
||||
{(void*)&SDL_CloseAudioDevice, "SDL_CloseAudioDevice"},
|
||||
{(void*)&SDL_GetNumAudioDevices, "SDL_GetNumAudioDevices"},
|
||||
{(void*)&SDL_GetAudioDeviceName, "SDL_GetAudioDeviceName"},
|
||||
{(void*)&SDL_GetError, "SDL_GetError"},
|
||||
#if SDL_VERSION_ATLEAST(2,0,5)
|
||||
{(void*)&SDL_GetQueuedAudioSize, "SDL_GetQueuedAudioSize"},
|
||||
{(void*)&SDL_DequeueAudio, "SDL_DequeueAudio"},
|
||||
#endif
|
||||
{NULL, NULL}
|
||||
};
|
||||
static dllhandle_t *libsdl;
|
||||
if (!libsdl)
|
||||
{
|
||||
libsdl = Sys_LoadLibrary("libSDL2-2.0.so.0", funcs);
|
||||
libsdl = Sys_LoadLibrary("libSDL2-2.0.so.0", sdl_funcs);
|
||||
if (!libsdl)
|
||||
libsdl = Sys_LoadLibrary("libSDL2.so", funcs); //maybe they have a dev package installed that fixes this mess.
|
||||
libsdl = Sys_LoadLibrary("libSDL2.so", sdl_funcs); //maybe they have a dev package installed that fixes this mess.
|
||||
#ifdef _WIN32
|
||||
if (!libsdl)
|
||||
libsdl = Sys_LoadLibrary("SDL2", funcs);
|
||||
libsdl = Sys_LoadLibrary("SDL2", sdl_funcs);
|
||||
#endif
|
||||
if (libsdl)
|
||||
SDL_Init(SDL_INIT_NOPARACHUTE);
|
||||
|
@ -120,9 +122,6 @@ static qboolean SSDL_InitAudio(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (COM_CheckParm("-nosndsnd"))
|
||||
return false;
|
||||
|
||||
if (!inited)
|
||||
if(SDL_InitSubSystem(SDL_INIT_AUDIO | SDL_INIT_NOPARACHUTE))
|
||||
{
|
||||
|
|
|
@ -791,7 +791,11 @@ static void Friendly_Crash_Handler(int sig, siginfo_t *info, void *vcontext)
|
|||
#endif
|
||||
|
||||
// print out all the frames to stderr
|
||||
#ifdef SVNREVISION
|
||||
fprintf(stderr, "Error: signal %s (revision "STRINGIFY(SVNREVISION)")\n", signame);
|
||||
#else
|
||||
fprintf(stderr, "Error: signal %s:\n", signame);
|
||||
#endif
|
||||
backtrace_symbols_fd(array+firstframe, size-firstframe, 2);
|
||||
|
||||
if (sig == SIGINT)
|
||||
|
|
|
@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "winquake.h"
|
||||
#include "glquake.h"
|
||||
#include "shader.h"
|
||||
|
||||
#include <ctype.h> // for isdigit();
|
||||
|
||||
|
@ -103,8 +104,8 @@ cvar_t v_gunkick = CVARD("v_gunkick", "0", "Controls the strength of view ang
|
|||
cvar_t v_gunkick_q2 = CVARD("v_gunkick_q2", "1", "Controls the strength of view angle changes when firing weapons (in Quake2).");
|
||||
cvar_t v_viewmodel_quake = CVARD("r_viewmodel_quake", "0", "Controls whether to use weird viewmodel movements from vanilla quake."); //name comes from MarkV.
|
||||
|
||||
cvar_t v_viewheight = CVAR("v_viewheight", "0");
|
||||
cvar_t v_projectionmode = CVAR("v_projectionmode", "0");
|
||||
cvar_t v_viewheight = CVARF("v_viewheight", "0", CVAR_ARCHIVE);
|
||||
cvar_t v_projectionmode = CVARF("v_projectionmode", "0", CVAR_ARCHIVE);
|
||||
|
||||
cvar_t v_depthsortentities = CVARAD("v_depthsortentities", "0", "v_reorderentitiesrandomly", "Reorder entities for transparency such that the furthest entities are drawn first, allowing nearer transparent entities to draw over the top of them.");
|
||||
|
||||
|
@ -2160,6 +2161,9 @@ void V_RenderPlayerViews(playerview_t *pv)
|
|||
R_RenderView ();
|
||||
R2D_PolyBlend ();
|
||||
R_DrawNameTags();
|
||||
#ifdef RTLIGHTS
|
||||
R_EditLights_DrawInfo();
|
||||
#endif
|
||||
|
||||
if(cl.intermissionmode == IM_NONE)
|
||||
R2D_DrawCrosshair();
|
||||
|
@ -2271,8 +2275,7 @@ void V_RenderPlayerViews(playerview_t *pv)
|
|||
r_refdef.externalview = false;
|
||||
}
|
||||
|
||||
#include "shader.h"
|
||||
void V_RenderView (void)
|
||||
void V_RenderView (qboolean no2d)
|
||||
{
|
||||
int seatnum;
|
||||
int maxseats = cl.splitclients;
|
||||
|
@ -2291,6 +2294,8 @@ void V_RenderView (void)
|
|||
for (seatnum = 0; seatnum < cl.splitclients && seatnum < maxseats; seatnum++)
|
||||
{
|
||||
V_ClearRefdef(&cl.playerview[seatnum]);
|
||||
if (no2d)
|
||||
r_refdef.drawcrosshair = r_refdef.drawsbar = 0;
|
||||
if (seatnum)
|
||||
{
|
||||
//should be enough to just hack a few things.
|
||||
|
@ -2348,7 +2353,7 @@ void V_RenderView (void)
|
|||
#ifdef QUAKEHUD
|
||||
case 0: //show a mini-console.
|
||||
{
|
||||
console_t *con = &con_main;
|
||||
console_t *con = Con_GetMain();
|
||||
extern cvar_t gl_conback;
|
||||
shader_t *conback;
|
||||
if (*gl_conback.string && (conback = R_RegisterPic(gl_conback.string, NULL)) && R_GetShaderSizes(conback, NULL, NULL, true) > 0)
|
||||
|
@ -2357,7 +2362,7 @@ void V_RenderView (void)
|
|||
R2D_Image(r_refdef.grect.x, r_refdef.grect.y, r_refdef.grect.width, r_refdef.grect.height, 0, 0, 1, 1, conback);
|
||||
else
|
||||
R2D_TileClear (r_refdef.grect.x, r_refdef.grect.y, r_refdef.grect.width, r_refdef.grect.height);
|
||||
if (!scr_conlines)
|
||||
if (!scr_con_target && con)
|
||||
{
|
||||
int gah;
|
||||
Font_BeginString(font_console, 0, 0, &gah, &gah);
|
||||
|
|
|
@ -28,7 +28,7 @@ extern float hw_blend[4];
|
|||
extern qboolean r_secondaryview;
|
||||
|
||||
void V_Init (void);
|
||||
void V_RenderView (void);
|
||||
void V_RenderView (qboolean no2d);
|
||||
float V_CalcRoll (vec3_t angles, vec3_t velocity);
|
||||
void V_UpdatePalette (qboolean force);
|
||||
void V_ClearCShifts (void);
|
||||
|
|
|
@ -835,7 +835,7 @@ void Mod_ParseInfoFromEntityLump(model_t *wmodel) //actually, this should be in
|
|||
Q_strncatz(wads, token, sizeof(wads)); //cache it for later (so that we don't play with any temp memory yet)
|
||||
#endif
|
||||
}
|
||||
else if (!strcmp("fog", key)) //q1 extension. FIXME: should be made temporary.
|
||||
else if (!strcmp("fog", key) || !strcmp("airfog", key)) //q1 extension. FIXME: should be made temporary.
|
||||
{
|
||||
key[0] = 'f';
|
||||
key[1] = 'o';
|
||||
|
|
|
@ -96,259 +96,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FILE_NAME
|
||||
#undef MULTITHREAD
|
||||
#define HEADLESSQUAKE //usable renderers are normally specified via the makefile, but HEADLESS is considered a feature rather than an actual renderer, so usually gets forgotten about...
|
||||
#undef MULTITHREAD
|
||||
#define HEADLESSQUAKE //usable renderers are normally specified via the makefile, but HEADLESS is considered a feature rather than an actual renderer, so usually gets forgotten about...
|
||||
|
||||
//yup, C89 allows this (doesn't like C's token concat though).
|
||||
#include STRINGIFY(CONFIG_FILE_NAME)
|
||||
#else
|
||||
#define QWSKINS //disables qw .pcx skins, as well as enemy/team colour forcing.
|
||||
|
||||
#ifndef NO_LIBRARIES
|
||||
#define AVAIL_OPENAL
|
||||
#define AVAIL_FREETYPE
|
||||
#endif
|
||||
|
||||
#define AVAIL_OGGVORBIS
|
||||
#if defined(__CYGWIN__)
|
||||
#define AVAIL_ZLIB
|
||||
#else
|
||||
#define AVAIL_PNGLIB
|
||||
#define AVAIL_JPEGLIB
|
||||
#define AVAIL_ZLIB
|
||||
#define AVAIL_OGGVORBIS
|
||||
#endif
|
||||
|
||||
#ifdef WINRT
|
||||
#define AVAIL_XAUDIO2
|
||||
#define AVAIL_WASAPI
|
||||
#elif !defined(NO_DIRECTX) && !defined(NODIRECTX) && defined(_WIN32)
|
||||
#define AVAIL_DINPUT
|
||||
#define AVAIL_DSOUND
|
||||
#define AVAIL_WASAPI
|
||||
//#define AVAIL_XAUDIO2 //gcc doesn't provide any headers
|
||||
#endif
|
||||
#define AVAIL_XZDEC
|
||||
|
||||
#if !defined(MINIMAL) && !defined(NPFTE) && !defined(NPQTV)
|
||||
#if defined(_WIN32) && !defined(FTE_SDL) && !defined(WINRT) && !defined(_XBOX)
|
||||
#if !defined(_MSC_VER) || _MSC_VER > 1200
|
||||
#define HAVE_WINSSPI //built in component, checks against windows' root ca database and revocations etc.
|
||||
#endif
|
||||
#elif (defined(__linux__) || defined(__CYGWIN__)) && !defined(ANDROID)
|
||||
#define HAVE_GNUTLS //currently disabled as it does not validate the server's certificate, beware the mitm attack.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//#define DYNAMIC_ZLIB
|
||||
//#define DYNAMIC_LIBPNG
|
||||
//#define DYNAMIC_LIBJPEG
|
||||
//#define LIBVORBISFILE_STATIC
|
||||
//#define SPEEX_STATIC
|
||||
|
||||
#if defined(_WIN32) && defined(GLQUAKE)
|
||||
//#define USE_EGL
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(BOTLIB_STATIC) //too lazy to fix up the makefile
|
||||
#define BOTLIB_STATIC
|
||||
#endif
|
||||
|
||||
#if (defined(_MSC_VER) && (_MSC_VER < 1500)) || defined(FTE_SDL)
|
||||
#undef AVAIL_WASAPI //wasapi is available in the vista sdk, while that's compatible with earlier versions, its not really expected until 2008
|
||||
#endif
|
||||
|
||||
#define HAVE_TCP //says we can use tcp too (either ipv4 or ipv6)
|
||||
#define HAVE_PACKET //if we have the socket api at all...
|
||||
#define HAVE_MIXER //can be disabled if you have eg openal instead.
|
||||
|
||||
//set any additional defines or libs in win32
|
||||
#define LOADERTHREAD
|
||||
|
||||
#define PACKAGE_Q1PAK
|
||||
#define PACKAGE_PK3
|
||||
#define AVAIL_GZDEC
|
||||
#define PACKAGE_TEXWAD //quake's image wad support
|
||||
|
||||
#ifdef GLQUAKE
|
||||
#define HEADLESSQUAKE
|
||||
#endif
|
||||
#define AVAIL_MP3_ACM //microsoft's Audio Compression Manager api
|
||||
|
||||
#ifdef NOLEGACY
|
||||
//these are only the features that really make sense in a more modern engine
|
||||
#define QUAKETC //skip some legacy stuff
|
||||
#define SPRMODELS //quake1 sprite models
|
||||
#define INTERQUAKEMODELS
|
||||
#define RTLIGHTS //realtime lighting
|
||||
#define Q1BSPS //quake 1 bsp support, because we're still a quake engine
|
||||
#define Q2BSPS //quake 2 bsp support (a dependancy of q3bsp)
|
||||
#define Q3BSPS //quake 3 bsp support
|
||||
// #define TERRAIN //heightmap support
|
||||
#define WEBCLIENT //http/ftp clients.
|
||||
#define IMAGEFMT_DDS //a sort of image file format.
|
||||
#define PSET_SCRIPT
|
||||
// #define PLUGINS //qvm/dll plugins.
|
||||
// #define SUPPORT_ICE //Interactive Connectivity Establishment protocol, for peer-to-peer connections
|
||||
#define CSQC_DAT //support for csqc
|
||||
// #define VOICECHAT
|
||||
|
||||
#undef AVAIL_JPEGLIB
|
||||
#undef AVAIL_XZDEC
|
||||
|
||||
#elif defined(MINIMAL)
|
||||
#define QUAKESTATS
|
||||
#define QUAKEHUD
|
||||
#define CL_MASTER //this is useful
|
||||
|
||||
#undef AVAIL_JPEGLIB //no jpeg support
|
||||
#undef AVAIL_PNGLIB //no png support
|
||||
#undef AVAIL_OPENAL //just bloat...
|
||||
#undef AVAIL_GZDEC
|
||||
|
||||
#define Q1BSPS
|
||||
#define SPRMODELS //quake1 sprite models
|
||||
#define MD1MODELS //quake ain't much use without this
|
||||
#define MD3MODELS //we DO want to use quake3 alias models. This might be a minimal build, but we still want this.
|
||||
#define PLUGINS
|
||||
#define NOQCDESCRIPTIONS 2 //trim space from no fteextensions.qc info
|
||||
|
||||
#define PSET_CLASSIC
|
||||
|
||||
//#define CSQC_DAT //support for csqc
|
||||
|
||||
#ifndef SERVERONLY //don't be stupid, stupid.
|
||||
#ifndef CLIENTONLY
|
||||
#define CLIENTONLY
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#define NETPREPARSE
|
||||
#define QUAKESTATS
|
||||
#define QUAKEHUD
|
||||
#define SVRANKING
|
||||
#define USE_SQLITE
|
||||
#ifdef SERVERONLY
|
||||
// #define USE_MYSQL //allow mysql in dedicated servers.
|
||||
#endif
|
||||
#if defined(_WIN32) && !defined(FTE_SDL) && !defined(WINRT)
|
||||
#define SUBSERVERS //use subserver code.
|
||||
#elif defined(__linux__) && !defined(ANDROID) && !defined(FTE_SDL)
|
||||
#define SUBSERVERS //use subserver code.
|
||||
#endif
|
||||
|
||||
#define SIDEVIEWS 4 //enable secondary/reverse views.
|
||||
|
||||
// #define DSPMODELS //doom sprites (only needs PACKAGE_DOOMWAD to generate the right wad file names)
|
||||
#define SPRMODELS //quake1 sprite models
|
||||
#define SP2MODELS //quake2 sprite models
|
||||
#define MD1MODELS //quake1 alias models
|
||||
#define MD2MODELS //quake2 alias models
|
||||
#define MD3MODELS //quake3 alias models
|
||||
#define MD5MODELS //doom3 models
|
||||
#define ZYMOTICMODELS //zymotic skeletal models.
|
||||
#define DPMMODELS //darkplaces model format (which I've never seen anyone use)
|
||||
// #define PSKMODELS //PSK model format (ActorX stuff from UT, though not the format the game itself uses)
|
||||
#define HALFLIFEMODELS //halflife model support (experimental)
|
||||
#define INTERQUAKEMODELS
|
||||
#define RAGDOLL
|
||||
|
||||
#define USEAREAGRID //world collision optimisation. REQUIRED for performance with xonotic. hopefully it helps a few other mods too.
|
||||
#define HUFFNETWORK //huffman network compression
|
||||
// #define PACKAGE_DOOMWAD //doom wad support (maps+sprites are separate)
|
||||
// #define MAP_DOOM //doom map support
|
||||
// #define MAP_PROC //doom3/quake4 map support
|
||||
//#define WOLF3DSUPPORT //wolfenstein3d map support (not started yet)
|
||||
#define Q1BSPS //quake 1 bsp support, because we're still a quake engine
|
||||
#define Q2BSPS //quake 2 bsp support
|
||||
#define Q3BSPS //quake 3 bsp support
|
||||
#define RFBSPS //rogue(sof+jk2o)+qfusion bsp support
|
||||
#define TERRAIN //heightmap support
|
||||
// #define SV_MASTER //starts up a master server
|
||||
#define SVCHAT //serverside npc chatting. see sv_chat.c
|
||||
#define Q2SERVER //server can run a q2 game dll and switches to q2 network and everything else.
|
||||
#define Q2CLIENT //client can connect to q2 servers
|
||||
#define Q3CLIENT
|
||||
#define Q3SERVER
|
||||
#define HEXEN2 //mostly server only, but also includes some hud+menu stuff, and effects
|
||||
// #define HLCLIENT 7 //we can run HL gamecode (not protocol compatible, set to 6 or 7)
|
||||
// #define HLSERVER 140 //we can run HL gamecode (not protocol compatible, set to 138 or 140)
|
||||
#define NQPROT //server and client are capable of using quake1/netquake protocols. (qw is still prefered. uses the command 'nqconnect')
|
||||
#define PACKAGE_DZIP //support for the dzip format, common with the speed-demos-archive site
|
||||
// #define WEBSERVER //http server
|
||||
#define FTPSERVER //ftp server
|
||||
#define WEBCLIENT //http clients.
|
||||
#define RUNTIMELIGHTING //calculate lit/lux files the first time the map is loaded and doesn't have a loadable lit.
|
||||
// #define QTERM //qterm... adds a console command that allows running programs from within quake - bit like xterm.
|
||||
#define CL_MASTER //query master servers and stuff for a dynamic server listing.
|
||||
#define R_XFLIP //allow view to be flipped horizontally
|
||||
#define TEXTEDITOR
|
||||
#define IMAGEFMT_KTX //Khronos TeXture. common on gles3 devices for etc2 compression
|
||||
#define IMAGEFMT_PKM //file format generally written by etcpack or android's etc1tool
|
||||
#define IMAGEFMT_DDS //a sort of image file format.
|
||||
#define IMAGEFMT_BLP //a sort of image file format.
|
||||
#define DECOMPRESS_ETC2 //decompress etc2(core in gles3/gl4.3) if the graphics driver doesn't support it (eg d3d or crappy gpus with vulkan).
|
||||
// #define DECOMPRESS_S3TC //allows bc1-3 to work even when drivers don't support it. This is probably only an issue on mobile chips. WARNING: not entirely sure if all patents expired yet...
|
||||
#define DECOMPRESS_RGTC //bc4+bc5
|
||||
//would be nice to have BPTC decompression too, for gl<4.2, d3d9, or d3d11_level10, but frankly its overcomplicated. I'm not going to bother with ASTC either.
|
||||
#ifndef RTLIGHTS
|
||||
#define RTLIGHTS //realtime lighting
|
||||
#endif
|
||||
//#define SHADOWDBG_COLOURNOTDEPTH //for debugging. renders shadowmaps to a colour buffer instead of a depth buffer. resulting in projected textures instead of actual shadows (the glsl only picks up the red component, but whatever)
|
||||
|
||||
// #define QWOVERQ3 //allows qw servers with q3 clients. requires specific cgame.
|
||||
|
||||
#define VM_Q1 //q1 qvm gamecode interface
|
||||
//#define VM_LUA //q1 lua gamecode interface
|
||||
|
||||
#define TCPCONNECT //a tcpconnect command, that allows the player to connect to tcp-encapsulated qw protocols.
|
||||
// #define IRCCONNECT //an ircconnect command, that allows the player to connect to irc-encapsulated qw protocols... yeah, really.
|
||||
|
||||
#define PLUGINS //qvm/dll plugins.
|
||||
#define SUPPORT_ICE //Interactive Connectivity Establishment protocol, for peer-to-peer connections
|
||||
|
||||
#define CSQC_DAT //support for csqc
|
||||
#define MENU_DAT //support for menu.dat
|
||||
|
||||
#define PSET_SCRIPT
|
||||
#define PSET_CLASSIC
|
||||
|
||||
|
||||
#define HAVE_CDPLAYER //includes cd playback. actual cds. faketracks are supported regardless.
|
||||
#define HAVE_JUKEBOX //includes built-in jukebox crap
|
||||
#define HAVE_MEDIA_DECODER //can play cin/roq, more with plugins
|
||||
#define HAVE_MEDIA_ENCODER //capture/capturedemo work.
|
||||
#define HAVE_SPEECHTOTEXT //windows speech-to-text thing
|
||||
|
||||
#define VOICECHAT
|
||||
|
||||
#if defined(_WIN32) && !defined(FTE_SDL) && !defined(MULTITHREAD) //always thread on win32 non-minimal builds
|
||||
#define MULTITHREAD
|
||||
#endif
|
||||
#endif
|
||||
//yup, C89 allows this (doesn't like C's token concat though).
|
||||
#include STRINGIFY(CONFIG_FILE_NAME)
|
||||
|
||||
|
||||
|
||||
#ifdef QUAKETC
|
||||
#define NOBUILTINMENUS //kill engine menus (should be replaced with ewither csqc or menuqc)
|
||||
#undef Q2CLIENT //not useful
|
||||
#undef Q2SERVER //not useful
|
||||
#undef Q3CLIENT //not useful
|
||||
#undef Q3SERVER //not useful
|
||||
#undef HLCLIENT //not useful
|
||||
#undef HLSERVER //not useful
|
||||
#undef VM_Q1 //not useful
|
||||
#undef VM_LUA //not useful
|
||||
#undef HALFLIFEMODELS //yuck
|
||||
#undef RUNTIMELIGHTING //presumably not useful
|
||||
#undef HEXEN2
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef MSVCLIBSPATH
|
||||
#ifndef MSVCLIBSPATH
|
||||
#ifdef MSVCLIBPATH
|
||||
#define MSVCLIBSPATH STRINGIFY(MSVCLIBPATH)
|
||||
#elif _MSC_VER == 1200
|
||||
|
@ -356,16 +112,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#else
|
||||
#define MSVCLIBSPATH "../libs/"
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(SERVERONLY) && defined(CLIENTONLY)
|
||||
#undef CLIENTONLY //impossible build. assume the config had CLIENTONLY and they tried building a dedicated server
|
||||
#endif
|
||||
#ifndef CLIENTONLY
|
||||
#define HAVE_SERVER
|
||||
#endif
|
||||
#ifndef SERVERONLY
|
||||
#define HAVE_CLIENT
|
||||
#ifndef WEBSVONLY
|
||||
#ifndef CLIENTONLY
|
||||
#define HAVE_SERVER
|
||||
#endif
|
||||
#ifndef SERVERONLY
|
||||
#define HAVE_CLIENT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SERVER
|
||||
|
@ -796,8 +554,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define IFMINIMAL(x,y) y
|
||||
#endif
|
||||
|
||||
//#define PRE_SAYONE 2.487 //FIXME: remove.
|
||||
|
||||
// defs common to client and server
|
||||
|
||||
#ifndef PLATFORM
|
||||
|
@ -863,30 +619,32 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define ARCH_DL_POSTFIX ".so"
|
||||
#endif
|
||||
|
||||
#if defined(_M_AMD64) || defined(__amd64__) || defined(__x86_64__)
|
||||
#ifdef __ILP32__
|
||||
#define ARCH_CPU_POSTFIX "x32" //32bit pointers, with 16 registers.
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
#define ARCH_CPU_POSTFIX "x64"
|
||||
#ifndef ARCH_CPU_POSTFIX
|
||||
#if defined(_M_AMD64) || defined(__amd64__) || defined(__x86_64__)
|
||||
#ifdef __ILP32__
|
||||
#define ARCH_CPU_POSTFIX "x32" //32bit pointers, with 16 registers.
|
||||
#else
|
||||
#define ARCH_CPU_POSTFIX "amd64"
|
||||
#ifdef _WIN32
|
||||
#define ARCH_CPU_POSTFIX "x64"
|
||||
#else
|
||||
#define ARCH_CPU_POSTFIX "amd64"
|
||||
#endif
|
||||
#endif
|
||||
#elif defined(_M_IX86) || defined(__i386__)
|
||||
#define ARCH_CPU_POSTFIX "x86"
|
||||
#elif defined(__powerpc__) || defined(__ppc__)
|
||||
#define ARCH_CPU_POSTFIX "ppc"
|
||||
#elif defined(__aarch64__)
|
||||
#define ARCH_CPU_POSTFIX "arm64"
|
||||
#elif defined(__arm__)
|
||||
#ifdef __SOFTFP__
|
||||
#define ARCH_CPU_POSTFIX "arm"
|
||||
#else
|
||||
#define ARCH_CPU_POSTFIX "armhf"
|
||||
#endif
|
||||
#endif
|
||||
#elif defined(_M_IX86) || defined(__i386__)
|
||||
#define ARCH_CPU_POSTFIX "x86"
|
||||
#elif defined(__powerpc__) || defined(__ppc__)
|
||||
#define ARCH_CPU_POSTFIX "ppc"
|
||||
#elif defined(__aarch64__)
|
||||
#define ARCH_CPU_POSTFIX "arm64"
|
||||
#elif defined(__arm__)
|
||||
#ifdef __SOFTFP__
|
||||
#define ARCH_CPU_POSTFIX "arm"
|
||||
#else
|
||||
#define ARCH_CPU_POSTFIX "armhf"
|
||||
#define ARCH_CPU_POSTFIX "unk"
|
||||
#endif
|
||||
#else
|
||||
#define ARCH_CPU_POSTFIX "unk"
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
|
|
@ -45,9 +45,9 @@ typedef struct cmdalias_s
|
|||
{
|
||||
struct cmdalias_s *next;
|
||||
char *value;
|
||||
int flags;
|
||||
qbyte execlevel;
|
||||
qbyte restriction;
|
||||
int flags;
|
||||
char name[1];
|
||||
} cmdalias_t;
|
||||
|
||||
|
@ -4044,11 +4044,12 @@ static void Cmd_Reset_f(void)
|
|||
// dumps current console contents to a text file
|
||||
static void Cmd_Condump_f(void)
|
||||
{
|
||||
console_t *c = Con_GetMain();
|
||||
vfsfile_t *f;
|
||||
char *filename;
|
||||
char line[8192];
|
||||
|
||||
if (!con_current)
|
||||
if (!c)
|
||||
{
|
||||
Con_Printf ("No console to dump.\n");
|
||||
return;
|
||||
|
@ -4074,13 +4075,12 @@ static void Cmd_Condump_f(void)
|
|||
// print out current contents of console
|
||||
// stripping out starting blank lines and blank spaces
|
||||
{
|
||||
console_t *curcon = &con_main;
|
||||
conline_t *l;
|
||||
conchar_t *t;
|
||||
for (l = curcon->oldest; l; l = l->newer)
|
||||
for (l = c->oldest; l; l = l->newer)
|
||||
{
|
||||
t = (conchar_t*)(l+1);
|
||||
COM_DeFunString(t, t + l->length, line, sizeof(line), true, !!(curcon->parseflags & PFS_FORCEUTF8));
|
||||
COM_DeFunString(t, t + l->length, line, sizeof(line), true, !!(c->parseflags & PFS_FORCEUTF8));
|
||||
VFS_WRITE(f, line, strlen(line));
|
||||
VFS_WRITE(f, "\n", 1);
|
||||
}
|
||||
|
|
|
@ -148,6 +148,7 @@ char *Cmd_AliasExist(const char *name, int restrictionlevel);
|
|||
void Alias_WipeStuffedAliases(void);
|
||||
|
||||
void Cmd_AddMacro(char *s, char *(*f)(void), int disputableintentions);
|
||||
#define Cmd_AddMacroD(s,f,unsafe,desc) Cmd_AddMacro(s,f,unsafe)
|
||||
|
||||
void Cmd_TokenizePunctation (char *text, char *punctuation);
|
||||
const char *Cmd_TokenizeString (const char *text, qboolean expandmacros, qboolean qctokenize);
|
||||
|
|
|
@ -33,7 +33,7 @@ cvar_t r_meshpitch = CVARCD ("r_meshpitch", "1", r_meshpitch_callback, "Sp
|
|||
cvar_t r_meshpitch = CVARCD ("r_meshpitch", "-1", r_meshpitch_callback, "Specifies the direction of the pitch angle on mesh models formats, Quake compatibility requires -1.");
|
||||
#endif
|
||||
|
||||
#ifndef SERVERONLY
|
||||
#ifdef HAVE_CLIENT
|
||||
static void Mod_UpdateCRC(void *ctx, void *data, size_t a, size_t b)
|
||||
{
|
||||
char st[40];
|
||||
|
@ -50,7 +50,7 @@ static void Mod_UpdateCRC(void *ctx, void *data, size_t a, size_t b)
|
|||
//Common loader function.
|
||||
void Mod_DoCRC(model_t *mod, char *buffer, int buffersize)
|
||||
{
|
||||
#ifndef SERVERONLY
|
||||
#ifdef HAVE_CLIENT
|
||||
//we've got to have this bit
|
||||
if (mod->engineflags & MDLF_DOCRC)
|
||||
{
|
||||
|
@ -78,7 +78,7 @@ extern cvar_t r_skin_overlays;
|
|||
extern cvar_t mod_md3flags;
|
||||
|
||||
|
||||
|
||||
#ifdef HAVE_CLIENT
|
||||
typedef struct
|
||||
{
|
||||
char *name;
|
||||
|
@ -88,7 +88,7 @@ typedef struct
|
|||
|
||||
//these should be rounded up slightly.
|
||||
//really this is only to catch spiked models. This doesn't prevent more visible models, just bigger ones.
|
||||
clampedmodel_t clampedmodel[] = {
|
||||
static clampedmodel_t clampedmodel[] = {
|
||||
{"maps/b_bh100.bsp", 3440},
|
||||
{"progs/player.mdl", 22497},
|
||||
{"progs/eyes.mdl", 755},
|
||||
|
@ -129,7 +129,7 @@ clampedmodel_t clampedmodel[] = {
|
|||
{"progs/turrbase.mdl", 3000},
|
||||
{"progs/turrgun.mdl", 3000}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
@ -240,7 +240,7 @@ void Mod_NormaliseTextureVectors(vec3_t *n, vec3_t *s, vec3_t *t, int v, qboolea
|
|||
#ifdef SKELETALMODELS
|
||||
|
||||
/*like above, but guess the quat.w*/
|
||||
static void GenMatrixPosQuat3Scale(vec3_t pos, vec3_t quat3, vec3_t scale, float result[12])
|
||||
static void GenMatrixPosQuat3Scale(vec3_t const pos, vec3_t const quat3, vec3_t const scale, float result[12])
|
||||
{
|
||||
vec4_t quat4;
|
||||
float term = 1 - DotProduct(quat3, quat3);
|
||||
|
@ -581,7 +581,7 @@ static const float *Alias_ConvertBoneData(skeltype_t sourcetype, const float *so
|
|||
for (i = 0; i < bonecount; i++)
|
||||
{
|
||||
if (bones[i].parent >= 0)
|
||||
R_ConcatTransforms((void*)(dest + bones[i].parent*12), (void*)(sourcedata+i*12), (void*)(dest+i*12));
|
||||
R_ConcatTransforms((void*)(dest + bones[i].parent*12), (const void*)(sourcedata+i*12), (void*)(dest+i*12));
|
||||
else
|
||||
{
|
||||
Vector4Copy(sourcedata+i*12+0, dest+i*12+0);
|
||||
|
@ -605,7 +605,7 @@ static const float *Alias_ConvertBoneData(skeltype_t sourcetype, const float *so
|
|||
for (i = 0; i < bonecount; i++)
|
||||
{
|
||||
Matrix3x4_Invert_Simple(bones[i].inverse, iim);
|
||||
R_ConcatTransforms((void*)(sourcedata + i*12), (void*)iim, (void*)(dest + i*12));
|
||||
R_ConcatTransforms((const void*)(sourcedata + i*12), (const void*)iim, (void*)(dest + i*12));
|
||||
}
|
||||
sourcedata = dest;
|
||||
sourcetype = SKEL_ABSOLUTE;
|
||||
|
@ -623,7 +623,7 @@ static const float *Alias_ConvertBoneData(skeltype_t sourcetype, const float *so
|
|||
if (bones[i].parent >= 0)
|
||||
{
|
||||
Matrix3x4_Invert_Simple(sourcedata+bones[i].parent*12, ip);
|
||||
R_ConcatTransforms((void*)ip, (void*)(sourcedata+i*12), (void*)(dest+i*12));
|
||||
R_ConcatTransforms((void*)ip, (const void*)(sourcedata+i*12), (void*)(dest+i*12));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -644,7 +644,7 @@ static const float *Alias_ConvertBoneData(skeltype_t sourcetype, const float *so
|
|||
{
|
||||
float *dest = (sourcedata == destbuffer)?destbufferalt:destbuffer;
|
||||
for (i = 0; i < bonecount; i++)
|
||||
R_ConcatTransforms((void*)(sourcedata + i*12), (void*)(bones[i].inverse), (void*)(dest + i*12));
|
||||
R_ConcatTransforms((const void*)(sourcedata + i*12), (void*)(bones[i].inverse), (void*)(dest + i*12));
|
||||
sourcedata = dest;
|
||||
sourcetype = SKEL_INVERSE_ABSOLUTE;
|
||||
}
|
||||
|
@ -1002,9 +1002,9 @@ typedef struct
|
|||
skeltype_t skeltype; //the skeletal type of this bone block. all blocks should have the same result or the whole thing is unusable or whatever.
|
||||
int firstbone; //first bone of interest
|
||||
int endbone; //the first bone of the next group (ie: if first is 0, this is the count)
|
||||
int lerpcount; //number of pose+frac entries.
|
||||
float frac[FRAME_BLENDS*2]; //weight of this animation (1 if lerpcount is 1)
|
||||
float *pose[FRAME_BLENDS*2]; //pointer to the raw frame data for bone 0.
|
||||
int lerpcount; //number of pose+frac entries.
|
||||
} skellerps_t;
|
||||
static qboolean Alias_BuildSkelLerps(skellerps_t *lerps, struct framestateregion_s *fs, int numbones, galiasinfo_t *inf)
|
||||
{
|
||||
|
@ -1470,7 +1470,7 @@ static void Alias_BuildGPUWeights(model_t *mod, galiasinfo_t *inf, size_t num_tr
|
|||
#endif
|
||||
|
||||
#ifndef SERVERONLY
|
||||
static void Alias_DrawSkeletalBones(galiasbone_t *bones, float *bonepose, int bonecount, int basebone)
|
||||
static void Alias_DrawSkeletalBones(galiasbone_t *bones, float const*bonepose, int bonecount, int basebone)
|
||||
{
|
||||
scenetris_t *t;
|
||||
int flags = BEF_NODLIGHT|BEF_NOSHADOWS|BEF_LINES;
|
||||
|
@ -1788,7 +1788,7 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, in
|
|||
meshcache.usebonepose = Alias_GetBoneInformation(inf, &e->framestate, meshcache.bonecachetype=SKEL_ABSOLUTE, meshcache.boneposebuffer1, meshcache.boneposebuffer2, MAX_BONES);
|
||||
#ifndef SERVERONLY
|
||||
if (inf->shares_bones != surfnum && qrenderer)
|
||||
Alias_DrawSkeletalBones(inf->ofsbones, (float *)meshcache.usebonepose, inf->numbones, e->framestate.g[0].endbone);
|
||||
Alias_DrawSkeletalBones(inf->ofsbones, (const float *)meshcache.usebonepose, inf->numbones, e->framestate.g[0].endbone);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -3104,7 +3104,7 @@ static void Q1MDL_LoadPose(galiasinfo_t *galias, dmdl_t *pq1inmodel, vecV_t *ver
|
|||
}
|
||||
}
|
||||
}
|
||||
static void Q1MDL_LoadPose16(galiasinfo_t *galias, dmdl_t *pq1inmodel, vecV_t *verts, vec3_t *normals, vec3_t *svec, vec3_t *tvec, dtrivertx_t *pinframe, int *seamremaps, int mdltype)
|
||||
static void Q1MDL_LoadPoseQF16(galiasinfo_t *galias, dmdl_t *pq1inmodel, vecV_t *verts, vec3_t *normals, vec3_t *svec, vec3_t *tvec, dtrivertx_t *pinframe, int *seamremaps, int mdltype)
|
||||
{
|
||||
//quakeforge's MD16 format has regular 8bit stuff, trailed by an extra low-order set of the verts providing the extra 8bits of precision.
|
||||
//its worth noting that the model could be rendered using the high-order parts only, if your software renderer only supports that or whatever.
|
||||
|
@ -3186,24 +3186,24 @@ static void *Q1MDL_LoadFrameGroup (galiasinfo_t *galias, dmdl_t *pq1inmodel, mod
|
|||
|
||||
if (mdltype & 16)
|
||||
{
|
||||
Q1MDL_LoadPose16(galias, pq1inmodel, verts, normals, svec, tvec, pinframe, seamremaps, mdltype);
|
||||
Q1MDL_LoadPoseQF16(galias, pq1inmodel, verts, normals, svec, tvec, pinframe, seamremaps, mdltype);
|
||||
pframetype = (daliasframetype_t *)&pinframe[pq1inmodel->numverts*2];
|
||||
}
|
||||
else
|
||||
{
|
||||
Q1MDL_LoadPose(galias, pq1inmodel, verts, normals, svec, tvec, pinframe, seamremaps, mdltype, bbox);
|
||||
pframetype = (daliasframetype_t *)&pinframe[pq1inmodel->numverts];
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
if ((bbox[3] > frameinfo->bboxmax.v[0] || bbox[4] > frameinfo->bboxmax.v[1] || bbox[5] > frameinfo->bboxmax.v[2] ||
|
||||
bbox[0] < frameinfo->bboxmin.v[0] || bbox[1] < frameinfo->bboxmin.v[1] || bbox[2] < frameinfo->bboxmin.v[2]) && !galias->warned)
|
||||
if ((bbox[3] > frameinfo->bboxmax.v[0] || bbox[4] > frameinfo->bboxmax.v[1] || bbox[5] > frameinfo->bboxmax.v[2] ||
|
||||
bbox[0] < frameinfo->bboxmin.v[0] || bbox[1] < frameinfo->bboxmin.v[1] || bbox[2] < frameinfo->bboxmin.v[2]) && !galias->warned)
|
||||
#else
|
||||
if (galias->numverts && pinframe[0].v[2] > frameinfo->bboxmax.v[2] && !galias->warned)
|
||||
if (galias->numverts && pinframe[0].v[2] > frameinfo->bboxmax.v[2] && !galias->warned)
|
||||
#endif
|
||||
{
|
||||
Con_DPrintf(CON_WARNING"%s has incorrect frame bounds\n", loadmodel->name);
|
||||
galias->warned = true;
|
||||
{
|
||||
Con_DPrintf(CON_WARNING"%s has incorrect frame bounds\n", loadmodel->name);
|
||||
galias->warned = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -3260,26 +3260,26 @@ static void *Q1MDL_LoadFrameGroup (galiasinfo_t *galias, dmdl_t *pq1inmodel, mod
|
|||
|
||||
if (mdltype & 16)
|
||||
{
|
||||
Q1MDL_LoadPose16(galias, pq1inmodel, verts, normals, svec, tvec, pinframe, seamremaps, mdltype);
|
||||
Q1MDL_LoadPoseQF16(galias, pq1inmodel, verts, normals, svec, tvec, pinframe, seamremaps, mdltype);
|
||||
pinframe += pq1inmodel->numverts*2;
|
||||
}
|
||||
else
|
||||
{
|
||||
Q1MDL_LoadPose(galias, pq1inmodel, verts, normals, svec, tvec, pinframe, seamremaps, mdltype, bbox);
|
||||
pinframe += pq1inmodel->numverts;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
if ((bbox[3] > frameinfo->bboxmax.v[0] || bbox[4] > frameinfo->bboxmax.v[1] || bbox[5] > frameinfo->bboxmax.v[2] ||
|
||||
bbox[0] < frameinfo->bboxmin.v[0] || bbox[1] < frameinfo->bboxmin.v[1] || bbox[2] < frameinfo->bboxmin.v[2] ||
|
||||
if ((bbox[3] > frameinfo->bboxmax.v[0] || bbox[4] > frameinfo->bboxmax.v[1] || bbox[5] > frameinfo->bboxmax.v[2] ||
|
||||
bbox[0] < frameinfo->bboxmin.v[0] || bbox[1] < frameinfo->bboxmin.v[1] || bbox[2] < frameinfo->bboxmin.v[2] ||
|
||||
#else
|
||||
if (galias->numverts && (pinframe[0].v[2] > frameinfo->bboxmax.v[2] ||
|
||||
if (galias->numverts && (pinframe[0].v[2] > frameinfo->bboxmax.v[2] ||
|
||||
#endif
|
||||
frameinfo->bboxmin.v[0] < ingroup->bboxmin.v[0] || frameinfo->bboxmin.v[1] < ingroup->bboxmin.v[1] || frameinfo->bboxmin.v[2] < ingroup->bboxmin.v[2] ||
|
||||
frameinfo->bboxmax.v[0] > ingroup->bboxmax.v[0] || frameinfo->bboxmax.v[1] > ingroup->bboxmax.v[1] || frameinfo->bboxmax.v[2] > ingroup->bboxmax.v[2]) && !galias->warned)
|
||||
{
|
||||
Con_DPrintf(CON_WARNING"%s has incorrect frame bounds\n", loadmodel->name);
|
||||
galias->warned = true;
|
||||
frameinfo->bboxmin.v[0] < ingroup->bboxmin.v[0] || frameinfo->bboxmin.v[1] < ingroup->bboxmin.v[1] || frameinfo->bboxmin.v[2] < ingroup->bboxmin.v[2] ||
|
||||
frameinfo->bboxmax.v[0] > ingroup->bboxmax.v[0] || frameinfo->bboxmax.v[1] > ingroup->bboxmax.v[1] || frameinfo->bboxmax.v[2] > ingroup->bboxmax.v[2]) && !galias->warned)
|
||||
{
|
||||
Con_DPrintf(CON_WARNING"%s has incorrect frame bounds\n", loadmodel->name);
|
||||
galias->warned = true;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef SERVERONLY
|
||||
|
@ -6899,7 +6899,7 @@ galisskeletaltransforms_t *IQM_ImportTransforms(int *resultcount, int inverts, f
|
|||
}
|
||||
*/
|
||||
|
||||
static qboolean IQM_ImportArray4B(const qbyte *base, const struct iqmvertexarray *src, byte_vec4_t *out, size_t count, unsigned int maxval)
|
||||
static qboolean IQM_ImportArray4B(const qbyte *fte_restrict base, const struct iqmvertexarray *fte_restrict src, byte_vec4_t *fte_restrict out, size_t count, unsigned int maxval)
|
||||
{
|
||||
size_t i;
|
||||
unsigned int j;
|
||||
|
@ -6922,7 +6922,7 @@ static qboolean IQM_ImportArray4B(const qbyte *base, const struct iqmvertexarray
|
|||
case IQM_BYTE: //FIXME: should be signed, but this makes no sense for our uses
|
||||
case IQM_UBYTE:
|
||||
{
|
||||
qbyte *in = (qbyte*)(base+offset);
|
||||
const qbyte *in = (const qbyte*)(base+offset);
|
||||
/*if (sz == 4)
|
||||
memcpy(out, in, count * sizeof(*out)); //the fast path.
|
||||
else*/ for (i = 0; i < count; i++)
|
||||
|
@ -6943,7 +6943,7 @@ static qboolean IQM_ImportArray4B(const qbyte *base, const struct iqmvertexarray
|
|||
case IQM_SHORT://FIXME: should be signed, but this makes no sense for our uses
|
||||
case IQM_USHORT:
|
||||
{
|
||||
unsigned short *in = (unsigned short*)(base+offset);
|
||||
const unsigned short *in = (const unsigned short*)(base+offset);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
for (j = 0; j < 4 && j < sz; j++)
|
||||
|
@ -6962,7 +6962,7 @@ static qboolean IQM_ImportArray4B(const qbyte *base, const struct iqmvertexarray
|
|||
case IQM_INT://FIXME: should be signed, but this makes no sense for our uses
|
||||
case IQM_UINT:
|
||||
{
|
||||
unsigned int *in = (unsigned int*)(base+offset);
|
||||
const unsigned int *in = (const unsigned int*)(base+offset);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
for (j = 0; j < 4 && j < sz; j++)
|
||||
|
@ -6993,7 +6993,7 @@ static qboolean IQM_ImportArray4B(const qbyte *base, const struct iqmvertexarray
|
|||
|
||||
return !invalid;
|
||||
}
|
||||
static void IQM_ImportArrayF(const qbyte *base, const struct iqmvertexarray *src, float *out, size_t e, size_t count, float *def)
|
||||
static void IQM_ImportArrayF(const qbyte *fte_restrict base, const struct iqmvertexarray *fte_restrict src, float *fte_restrict out, size_t e, size_t count, float *def)
|
||||
{
|
||||
size_t i;
|
||||
unsigned int j;
|
||||
|
@ -7012,7 +7012,7 @@ static void IQM_ImportArrayF(const qbyte *base, const struct iqmvertexarray *src
|
|||
break;
|
||||
case IQM_BYTE: //negatives not handled properly
|
||||
{
|
||||
signed char *in = (signed char*)(base+offset);
|
||||
const signed char *in = (const signed char*)(base+offset);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
for (j = 0; j < e && j < sz; j++)
|
||||
|
@ -7022,7 +7022,7 @@ static void IQM_ImportArrayF(const qbyte *base, const struct iqmvertexarray *src
|
|||
break;
|
||||
case IQM_UBYTE:
|
||||
{
|
||||
qbyte *in = (qbyte*)(base+offset);
|
||||
const qbyte *in = (const qbyte*)(base+offset);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
for (j = 0; j < e && j < sz; j++)
|
||||
|
@ -7032,7 +7032,7 @@ static void IQM_ImportArrayF(const qbyte *base, const struct iqmvertexarray *src
|
|||
break;
|
||||
case IQM_SHORT: //negatives not handled properly
|
||||
{
|
||||
signed short *in = (signed short*)(base+offset);
|
||||
const signed short *in = (const signed short*)(base+offset);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
for (j = 0; j < e && j < sz; j++)
|
||||
|
@ -7042,7 +7042,7 @@ static void IQM_ImportArrayF(const qbyte *base, const struct iqmvertexarray *src
|
|||
break;
|
||||
case IQM_USHORT:
|
||||
{
|
||||
unsigned short *in = (unsigned short*)(base+offset);
|
||||
const unsigned short *in = (const unsigned short*)(base+offset);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
for (j = 0; j < e && j < sz; j++)
|
||||
|
@ -7052,7 +7052,7 @@ static void IQM_ImportArrayF(const qbyte *base, const struct iqmvertexarray *src
|
|||
break;
|
||||
case IQM_INT: //negatives not handled properly
|
||||
{
|
||||
signed int *in = (signed int*)(base+offset);
|
||||
const signed int *in = (const signed int*)(base+offset);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
for (j = 0; j < e && j < sz; j++)
|
||||
|
@ -7062,7 +7062,7 @@ static void IQM_ImportArrayF(const qbyte *base, const struct iqmvertexarray *src
|
|||
break;
|
||||
case IQM_UINT:
|
||||
{
|
||||
unsigned int *in = (unsigned int*)(base+offset);
|
||||
const unsigned int *in = (const unsigned int*)(base+offset);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
for (j = 0; j < e && j < sz; j++)
|
||||
|
@ -7074,7 +7074,7 @@ static void IQM_ImportArrayF(const qbyte *base, const struct iqmvertexarray *src
|
|||
case IQM_HALF:
|
||||
#ifdef __F16C__
|
||||
{ //x86 intrinsics
|
||||
unsigned short *in = (qbyte*)(base+offset);
|
||||
const unsigned short *in = (const qbyte*)(base+offset);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
for (j = 0; j < e && j < sz; j++)
|
||||
|
@ -7083,7 +7083,7 @@ static void IQM_ImportArrayF(const qbyte *base, const struct iqmvertexarray *src
|
|||
}
|
||||
#elif 0
|
||||
{
|
||||
_Float16 *in = (qbyte*)(base+offset);
|
||||
const _Float16 *in = (const _Float16*)(base+offset);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
for (j = 0; j < e && j < sz; j++)
|
||||
|
@ -7096,7 +7096,7 @@ static void IQM_ImportArrayF(const qbyte *base, const struct iqmvertexarray *src
|
|||
break;
|
||||
case IQM_FLOAT:
|
||||
{
|
||||
float *in = (float*)(base+offset);
|
||||
const float *in = (const float*)(base+offset);
|
||||
if (e == sz)
|
||||
memcpy(out, in, e * sizeof(float) * count);
|
||||
else for (i = 0; i < count; i++)
|
||||
|
@ -7108,7 +7108,7 @@ static void IQM_ImportArrayF(const qbyte *base, const struct iqmvertexarray *src
|
|||
break;
|
||||
case IQM_DOUBLE:
|
||||
{
|
||||
double *in = (double*)(base+offset);
|
||||
const double *in = (const double*)(base+offset);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
for (j = 0; j < e && j < sz; j++)
|
||||
|
@ -7131,13 +7131,13 @@ static void IQM_ImportArrayF(const qbyte *base, const struct iqmvertexarray *src
|
|||
|
||||
static const void *IQM_FindExtension(const char *buffer, size_t buffersize, const char *extname, int index, size_t *extsize)
|
||||
{
|
||||
struct iqmheader *h = (struct iqmheader *)buffer;
|
||||
const struct iqmheader *h = (const struct iqmheader *)buffer;
|
||||
const char *strings = buffer + h->ofs_text;
|
||||
struct iqmextension *ext;
|
||||
const struct iqmextension *ext;
|
||||
int i;
|
||||
for (i = 0, ext = (struct iqmextension*)(buffer + h->ofs_extensions); i < h->num_extensions; i++, ext = (struct iqmextension*)(buffer + ext->ofs_extensions))
|
||||
for (i = 0, ext = (const struct iqmextension*)(buffer + h->ofs_extensions); i < h->num_extensions; i++, ext = (const struct iqmextension*)(buffer + ext->ofs_extensions))
|
||||
{
|
||||
if ((char*)ext > buffer+buffersize || ext->name > h->num_text || ext->ofs_data+ext->num_data>buffersize)
|
||||
if ((const char*)ext > buffer+buffersize || ext->name > h->num_text || ext->ofs_data+ext->num_data>buffersize)
|
||||
break;
|
||||
if (!Q_strcasecmp(strings + ext->name, extname) && index-->=0)
|
||||
{
|
||||
|
@ -7185,7 +7185,7 @@ static void Mod_CleanWeights(const char *modelname, size_t numverts, vec4_t *owe
|
|||
|
||||
static galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, size_t fsize)
|
||||
{
|
||||
const struct iqmheader *h = (struct iqmheader *)buffer;
|
||||
const struct iqmheader *h = (const struct iqmheader *)buffer;
|
||||
const struct iqmmesh *mesh;
|
||||
const struct iqmvertexarray *varray;
|
||||
const struct iqmtriangle *tris;
|
||||
|
@ -7197,15 +7197,15 @@ static galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, siz
|
|||
unsigned int i, j, t, numtris, numverts, firstvert, firsttri;
|
||||
size_t extsize;
|
||||
|
||||
float *vtang = NULL;
|
||||
const float *vtang = NULL;
|
||||
struct iqmvertexarray vpos = {0}, vnorm = {0}, vtcoord = {0}, vbone = {0}, vweight = {0}, vrgba = {0};
|
||||
unsigned int type, fmt, size, offset;
|
||||
unsigned short *framedata;
|
||||
const unsigned short *framedata;
|
||||
vec4_t defaultcolour = {1,1,1,1};
|
||||
vec4_t defaultweight = {0,0,0,0};
|
||||
vec4_t defaultvert = {0,0,0,1};
|
||||
|
||||
struct iqmbounds *inbounds;
|
||||
const struct iqmbounds *inbounds;
|
||||
|
||||
int memsize;
|
||||
qbyte *obase=NULL;
|
||||
|
@ -7249,7 +7249,7 @@ static galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, siz
|
|||
return NULL;
|
||||
}
|
||||
|
||||
varray = (struct iqmvertexarray*)(buffer + h->ofs_vertexarrays);
|
||||
varray = (const struct iqmvertexarray*)(buffer + h->ofs_vertexarrays);
|
||||
for (i = 0; i < h->num_vertexarrays; i++)
|
||||
{
|
||||
type = LittleLong(varray[i].type);
|
||||
|
@ -7263,7 +7263,7 @@ static galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, siz
|
|||
else if (type == IQM_NORMAL)
|
||||
vnorm = varray[i];
|
||||
else if (type == IQM_TANGENT && fmt == IQM_FLOAT && size == 4) /*yup, 4, extra is side, for the bitangent*/
|
||||
vtang = (float*)(buffer + offset);
|
||||
vtang = (const float*)(buffer + offset);
|
||||
else if (type == IQM_BLENDINDEXES)
|
||||
vbone = varray[i];
|
||||
else if (type == IQM_BLENDWEIGHTS)
|
||||
|
@ -7340,7 +7340,7 @@ static galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, siz
|
|||
numgroups = h->num_anims;
|
||||
framegroups = malloc(sizeof(*framegroups)*numgroups);
|
||||
|
||||
anim = (struct iqmanim*)(buffer + h->ofs_anims);
|
||||
anim = (const struct iqmanim*)(buffer + h->ofs_anims);
|
||||
for (i = 0; i < numgroups; i++)
|
||||
{
|
||||
framegroups[i].firstpose = LittleLong(anim[i].first_frame);
|
||||
|
@ -7363,7 +7363,7 @@ static galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, siz
|
|||
strcpy(framegroups->name, "base");
|
||||
}
|
||||
|
||||
mesh = (struct iqmmesh*)(buffer + h->ofs_meshes);
|
||||
mesh = (const struct iqmmesh*)(buffer + h->ofs_meshes);
|
||||
|
||||
#ifndef SERVERONLY
|
||||
skinfiles = Mod_CountSkinFiles(mod);
|
||||
|
@ -7414,13 +7414,13 @@ static galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, siz
|
|||
#undef dalloc
|
||||
|
||||
//no code to load animations or bones
|
||||
framedata = (unsigned short*)(buffer + h->ofs_frames);
|
||||
framedata = (const unsigned short*)(buffer + h->ofs_frames);
|
||||
|
||||
/*Version 1 supports only normalized quaternions, version 2 uses complete quaternions. Some struct sizes change for this, otherwise functionally identical.*/
|
||||
if (h->version == IQM_VERSION1)
|
||||
{
|
||||
struct iqmpose1 *p, *ipose = (struct iqmpose1*)(buffer + h->ofs_poses);
|
||||
struct iqmjoint1 *ijoint = (struct iqmjoint1*)(buffer + h->ofs_joints);
|
||||
const struct iqmpose1 *p, *ipose = (const struct iqmpose1*)(buffer + h->ofs_poses);
|
||||
const struct iqmjoint1 *ijoint = (const struct iqmjoint1*)(buffer + h->ofs_joints);
|
||||
vec3_t pos;
|
||||
vec4_t quat;
|
||||
vec3_t scale;
|
||||
|
@ -7464,8 +7464,8 @@ static galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, siz
|
|||
}
|
||||
else
|
||||
{
|
||||
struct iqmpose2 *p, *ipose = (struct iqmpose2*)(buffer + h->ofs_poses);
|
||||
struct iqmjoint2 *ijoint = (struct iqmjoint2*)(buffer + h->ofs_joints);
|
||||
const struct iqmpose2 *p, *ipose = (const struct iqmpose2*)(buffer + h->ofs_poses);
|
||||
const struct iqmjoint2 *ijoint = (const struct iqmjoint2*)(buffer + h->ofs_joints);
|
||||
vec3_t pos;
|
||||
vec4_t quat;
|
||||
vec3_t scale;
|
||||
|
@ -7564,7 +7564,7 @@ static galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, siz
|
|||
}
|
||||
|
||||
//determine the bounds
|
||||
inbounds = (struct iqmbounds*)(buffer + h->ofs_bounds);
|
||||
inbounds = (const struct iqmbounds*)(buffer + h->ofs_bounds);
|
||||
if (h->ofs_bounds)
|
||||
{
|
||||
for (i = 0; i < h->num_frames; i++)
|
||||
|
@ -7642,7 +7642,7 @@ static galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, const char *buffer, siz
|
|||
}
|
||||
#endif
|
||||
|
||||
tris = (struct iqmtriangle*)(buffer + LittleLong(h->ofs_triangles));
|
||||
tris = (const struct iqmtriangle*)(buffer + LittleLong(h->ofs_triangles));
|
||||
tris += firsttri;
|
||||
gai[i].numindexes = numtris*3;
|
||||
idx = ZG_Malloc(&mod->memgroup, sizeof(*idx)*gai[i].numindexes);
|
||||
|
|
|
@ -218,7 +218,7 @@ typedef struct modplugfuncs_s
|
|||
|
||||
void *(QDECL *ZG_Malloc)(zonegroup_t *ctx, int size); //ctx=&mod->memgroup and the data will be freed when the model is freed.
|
||||
|
||||
void (QDECL *ConcatTransforms) (float in1[3][4], float in2[3][4], float out[3][4]);
|
||||
void (QDECL *ConcatTransforms) (const float in1[3][4], const float in2[3][4], float out[3][4]);
|
||||
void (QDECL *M3x4_Invert) (const float *in1, float *out);
|
||||
void (QDECL *VectorAngles)(float *forward, float *up, float *result, qboolean meshpitch);
|
||||
void (QDECL *AngleVectors)(const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
|
||||
|
|
|
@ -84,7 +84,7 @@ glibc SUCKS. 64bit glibc is depending upon glibc 2.14 because of some implementa
|
|||
or something.
|
||||
anyway, the actual interface is the same. the old version might be slower, but when updating glibc generally results in also installing systemd, requiring the new version is NOT an option.
|
||||
*/
|
||||
#if defined(__GNUC__) && defined(__LP64__) && defined(__linux__) && !defined(FTE_SDL)
|
||||
#if defined(__GNUC__) && defined(__amd64__) && defined(__linux__) && !defined(FTE_SDL)
|
||||
#include <features.h> /* for glibc version */
|
||||
#if defined(__GLIBC__) && (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 14)
|
||||
__asm__(".symver memcpy,memcpy@GLIBC_2.2.5");
|
||||
|
@ -4790,7 +4790,7 @@ static void COM_Version_f (void)
|
|||
{
|
||||
Con_Printf("\n");
|
||||
Con_Printf("^&F0%s\n", FULLENGINENAME);
|
||||
Con_Printf("%s\n", ENGINEWEBSITE);
|
||||
Con_Printf("^[%s\\url\\%s^]\n", ENGINEWEBSITE, ENGINEWEBSITE);
|
||||
Con_Printf("%s\n", version_string());
|
||||
|
||||
Con_TPrintf ("Exe: %s %s\n", __DATE__, __TIME__);
|
||||
|
@ -4799,7 +4799,7 @@ static void COM_Version_f (void)
|
|||
Con_Printf("SVN Revision: %s\n",STRINGIFY(SVNREVISION));
|
||||
#endif
|
||||
#ifdef CONFIG_FILE_NAME
|
||||
Con_Printf("Build config: %s\n\n", STRINGIFY(CONFIG_FILE_NAME));
|
||||
Con_Printf("Build config: %s\n\n", COM_SkipPath(STRINGIFY(CONFIG_FILE_NAME)));
|
||||
#endif
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
@ -5150,8 +5150,8 @@ static void COM_ErrorMe_f(void)
|
|||
#ifdef LOADERTHREAD
|
||||
static void QDECL COM_WorkerCount_Change(cvar_t *var, char *oldvalue);
|
||||
cvar_t worker_flush = CVARD("worker_flush", "1", "If set, process the entire load queue, loading stuff faster but at the risk of stalling the main thread.");
|
||||
cvar_t worker_count = CVARFCD("worker_count", "", CVAR_NOTFROMSERVER, COM_WorkerCount_Change, "Specifies the number of worker threads to utilise.");
|
||||
cvar_t worker_sleeptime = CVARFD("worker_sleeptime", "0", CVAR_NOTFROMSERVER, "Causes workers to sleep for a period of time after each job.");
|
||||
static cvar_t worker_count = CVARFCD("worker_count", "", CVAR_NOTFROMSERVER, COM_WorkerCount_Change, "Specifies the number of worker threads to utilise.");
|
||||
static cvar_t worker_sleeptime = CVARFD("worker_sleeptime", "0", CVAR_NOTFROMSERVER, "Causes workers to sleep for a period of time after each job.");
|
||||
|
||||
#define WORKERTHREADS 16 //max
|
||||
/*multithreading worker thread stuff*/
|
||||
|
@ -6429,7 +6429,7 @@ static qboolean InfoBuf_EncodeString_Internal(const char *n, size_t s, char *out
|
|||
|
||||
for (c = n; c < n+s; c++)
|
||||
{
|
||||
base64_cur |= *(unsigned char*)c<<(16- base64_bits);//first byte fills highest bits
|
||||
base64_cur |= *(const unsigned char*)c<<(16- base64_bits);//first byte fills highest bits
|
||||
base64_bits += 8;
|
||||
|
||||
if (base64_bits == 24)
|
||||
|
|
|
@ -164,13 +164,13 @@ typedef struct sizebuf_s
|
|||
{
|
||||
qboolean allowoverflow; // if false, do a Sys_Error
|
||||
qboolean overflowed; // set to true if the buffer size failed
|
||||
qbyte *data;
|
||||
int maxsize;
|
||||
int cursize;
|
||||
int packing;
|
||||
int currentbit;
|
||||
qbyte *data;
|
||||
int maxsize; //storage size of data
|
||||
int cursize; //assigned size of data
|
||||
sbpacking_t packing; //required for q3
|
||||
int currentbit; //ignored for rawbytes
|
||||
|
||||
struct netprim_s prim;
|
||||
struct netprim_s prim; //for unsized write/read coord/angles
|
||||
} sizebuf_t;
|
||||
|
||||
void SZ_Clear (sizebuf_t *buf);
|
||||
|
@ -851,8 +851,10 @@ void Con_Log (const char *s);
|
|||
void Log_Logfile_f (void);
|
||||
void Log_Init(void);
|
||||
void Log_ShutDown(void);
|
||||
#ifdef IPLOG
|
||||
void IPLog_Add(const char *ip, const char *name); //for associating player ip addresses with names.
|
||||
qboolean IPLog_Merge_File(const char *fname);
|
||||
#endif
|
||||
qboolean CertLog_ConnectOkay(const char *hostname, void *cert, size_t certsize);
|
||||
|
||||
|
||||
|
|
|
@ -104,6 +104,8 @@
|
|||
#undef IMAGEFMT_PKM
|
||||
#undef IMAGEFMT_DDS //.dds files embed mipmaps and texture compression. faster to load.
|
||||
#undef IMAGEFMT_BLP //legacy crap
|
||||
#undef IMAGEFMT_BMP //legacy crap
|
||||
#undef IMAGEFMT_PCX //legacy crap
|
||||
#undef DECOMPRESS_ETC2
|
||||
#undef DECOMPRESS_RGTC
|
||||
#undef DECOMPRESS_S3TC
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#define TEXTEDITOR //my funky text editor! its awesome!
|
||||
#define PLUGINS //support for external plugins (like huds or fancy menus or whatever)
|
||||
#define USE_SQLITE //sql-database-as-file support
|
||||
#define IPLOG //track player's ip addresses (any decent server will hide ip addresses, so this probably isn't that useful, but nq players expect its)
|
||||
|
||||
//Filesystem formats
|
||||
#define PACKAGE_PK3
|
||||
|
@ -87,9 +88,11 @@
|
|||
#define IMAGEFMT_PKM //file format generally written by etcpack or android's etc1tool. doesn't support mips.
|
||||
#define IMAGEFMT_DDS //.dds files embed mipmaps and texture compression. faster to load.
|
||||
#define IMAGEFMT_BLP //legacy crap
|
||||
#define PACKAGE_TEXWAD //quake's image wad support
|
||||
#define IMAGEFMT_BMP //windows bmp. yuck.
|
||||
#define IMAGEFMT_PCX //paletted junk. required for qw player skins, q2 and a few old skyboxes.
|
||||
#define AVAIL_PNGLIB //.png image format support (read+screenshots)
|
||||
#define AVAIL_JPEGLIB //.jpeg image format support (read+screenshots)
|
||||
#define PACKAGE_TEXWAD //quake's image wad support
|
||||
#define AVAIL_FREETYPE //for truetype font rendering
|
||||
#define DECOMPRESS_ETC2 //decompress etc2(core in gles3/gl4.3) if the graphics driver doesn't support it (eg d3d or crappy gpus with vulkan).
|
||||
#define DECOMPRESS_S3TC //allows bc1-3 to work even when drivers don't support it. This is probably only an issue on mobile chips. WARNING: not entirely sure if all patents expired yet...
|
||||
|
|
|
@ -89,13 +89,15 @@
|
|||
//#define IMAGEFMT_PKM //file format generally written by etcpack or android's etc1tool. doesn't support mips.
|
||||
//#define IMAGEFMT_DDS //.dds files embed mipmaps and texture compression. faster to load.
|
||||
//#define IMAGEFMT_BLP //legacy crap
|
||||
#define PACKAGE_TEXWAD //quake's image wad support
|
||||
//#define IMAGEFMT_BMP //windows bmp. yuck.
|
||||
//#define IMAGEFMT_PCX //paletted junk. required for qw player skins, q2 and a few old skyboxes.
|
||||
#define AVAIL_PNGLIB //.png image format support (read+screenshots)
|
||||
//#define AVAIL_JPEGLIB //.jpeg image format support (read+screenshots)
|
||||
//#define AVAIL_FREETYPE //for truetype font rendering
|
||||
//#define DECOMPRESS_ETC2 //decompress etc2(core in gles3/gl4.3) if the graphics driver doesn't support it (eg d3d or crappy gpus with vulkan).
|
||||
////#define DECOMPRESS_S3TC //allows bc1-3 to work even when drivers don't support it. This is probably only an issue on mobile chips. WARNING: not entirely sure if all patents expired yet...
|
||||
//#define DECOMPRESS_RGTC //bc4+bc5
|
||||
#define PACKAGE_TEXWAD //quake's image wad support
|
||||
//#define AVAIL_FREETYPE //for truetype font rendering
|
||||
//#define DECOMPRESS_ETC2 //decompress etc2(core in gles3/gl4.3) if the graphics driver doesn't support it (eg d3d or crappy gpus with vulkan).
|
||||
////#define DECOMPRESS_S3TC //allows bc1-3 to work even when drivers don't support it. This is probably only an issue on mobile chips. WARNING: not entirely sure if all patents expired yet...
|
||||
//#define DECOMPRESS_RGTC //bc4+bc5
|
||||
|
||||
// Game/Gamecode Support
|
||||
//#define CSQC_DAT
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Build-Config file for FTE's standard builds, the default settings.
|
||||
// to use: make FTE_CONFIG=fteqw
|
||||
// Build-Config file for Quake-derived total-conversion mods that have chosen to break compatibility.
|
||||
// to use: make FTE_CONFIG=nocompat
|
||||
|
||||
// Features should either be commented or not. If you change undefs to defines or vice versa then expect problems.
|
||||
// Later code will disable any features if they're not supported on the current platform, so don't worry about win/lin/mac/android/web/etc here - any such issues should be fixed elsewhere.
|
||||
|
@ -86,12 +86,14 @@
|
|||
//#define IMAGEFMT_PKM //file format generally written by etcpack or android's etc1tool. doesn't support mips.
|
||||
#define IMAGEFMT_DDS //.dds files embed mipmaps and texture compression. faster to load.
|
||||
//#define IMAGEFMT_BLP //legacy crap
|
||||
//#define PACKAGE_TEXWAD //quake's image wad support
|
||||
//#define IMAGEFMT_BMP //windows bmp. yuck.
|
||||
//#define IMAGEFMT_PCX //paletted junk. required for qw player skins, q2 and a few old skyboxes.
|
||||
#define AVAIL_PNGLIB //.png image format support (read+screenshots)
|
||||
//#define AVAIL_JPEGLIB //.jpeg image format support (read+screenshots)
|
||||
//#define PACKAGE_TEXWAD //quake's image wad support
|
||||
#define AVAIL_FREETYPE //for truetype font rendering
|
||||
#define DECOMPRESS_ETC2 //decompress etc2(core in gles3/gl4.3) if the graphics driver doesn't support it (eg d3d or crappy gpus with vulkan).
|
||||
//#define DECOMPRESS_S3TC //allows bc1-3 to work even when drivers don't support it. This is probably only an issue on mobile chips. WARNING: not entirely sure if all patents expired yet...
|
||||
//#define DECOMPRESS_S3TC //allows bc1-3 to work even when drivers don't support it. This is probably only an issue on mobile chips. WARNING: not entirely sure if all patents expired yet...
|
||||
#define DECOMPRESS_RGTC //bc4+bc5
|
||||
|
||||
// Game/Gamecode Support
|
||||
|
|
|
@ -112,6 +112,8 @@
|
|||
#undef IMAGEFMT_KTX
|
||||
#undef IMAGEFMT_PKM
|
||||
#undef IMAGEFMT_BLP //legacy crap
|
||||
#undef IMAGEFMT_BMP //legacy crap
|
||||
#undef IMAGEFMT_PCX //legacy crap
|
||||
#undef NETPREPARSE //allows for running both nq+qw on the same server (if not, protocol used must match gamecode).
|
||||
#undef USE_SQLITE //sql-database-as-file support
|
||||
#undef QUAKESTATS //defines STAT_HEALTH etc. if omitted, you'll need to provide that functionality yourself.
|
||||
|
|
|
@ -200,10 +200,11 @@ typedef struct console_s
|
|||
struct console_s *next;
|
||||
} console_t;
|
||||
|
||||
extern console_t con_main;
|
||||
extern console_t *con_head;
|
||||
extern console_t *con_curwindow; // refers to a windowed console
|
||||
extern console_t *con_current; // point to either con_main or con_chat
|
||||
extern console_t *con_mouseover;
|
||||
|
||||
extern console_t *con_chat;
|
||||
|
||||
//shared between console and keys.
|
||||
|
@ -260,6 +261,7 @@ void Con_SetActive (console_t *con);
|
|||
qboolean Con_NameForNum(int num, char *buffer, int buffersize);
|
||||
console_t *Con_FindConsole(const char *name);
|
||||
console_t *Con_Create(const char *name, unsigned int flags);
|
||||
console_t *Con_GetMain(void); //retrieves the main console (creating it if needed)
|
||||
void Con_PrintCon (console_t *con, const char *txt, unsigned int parseflags);
|
||||
qboolean Con_InsertConChars (console_t *con, conline_t *line, int offset, conchar_t *c, int len);
|
||||
conline_t *Con_ResizeLineBuffer(console_t *con, conline_t *old, unsigned int length);
|
||||
|
|
|
@ -3066,7 +3066,7 @@ void COM_Gamedir (const char *dir, const struct gamepacks *packagespaths)
|
|||
/*quake requires a few settings for compatibility*/
|
||||
#define EZQUAKECOMPETITIVE "set ruleset_allow_fbmodels 1\nset sv_demoExtensions \"\"\n"
|
||||
#define QRPCOMPAT "set cl_cursor_scale 0.2\nset cl_cursor_bias_x 7.5\nset cl_cursor_bias_y 0.8"
|
||||
#define QCFG "set com_parseutf8 0\nset allow_download_refpackages 0\nset sv_bigcoords \"\"\nmap_autoopenportals 1\n" "sv_port "STRINGIFY(PORT_QWSERVER)" "STRINGIFY(PORT_NQSERVER)"\n" ZFIXHACK EZQUAKECOMPETITIVE QRPCOMPAT
|
||||
#define QCFG "set con_stayhidden 0\nset com_parseutf8 0\nset allow_download_refpackages 0\nset sv_bigcoords \"\"\nmap_autoopenportals 1\n" "sv_port "STRINGIFY(PORT_QWSERVER)" "STRINGIFY(PORT_NQSERVER)"\n" ZFIXHACK EZQUAKECOMPETITIVE QRPCOMPAT
|
||||
/*NetQuake reconfiguration, to make certain people feel more at home...*/
|
||||
#define NQCFG "//-nohome\ncfg_save_auto 1\n" QCFG "sv_nqplayerphysics 1\ncl_loopbackprotocol auto\ncl_sbar 1\nplug_sbar 0\nsv_port "STRINGIFY(PORT_NQSERVER)"\ncl_defaultport "STRINGIFY(PORT_NQSERVER)"\n"
|
||||
//nehahra has to be weird with its extra cvars, and buggy fullbrights.
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
#if !defined(NACL) && !defined(FTE_TARGET_WEB)
|
||||
|
||||
#ifdef WEBSVONLY
|
||||
#define Z_Free free
|
||||
#define Z_Malloc malloc
|
||||
#define Z_Free free
|
||||
#define Z_Malloc malloc
|
||||
#else
|
||||
#if !defined(_WIN32) || defined(FTE_SDL) || defined(WINRT) || defined(_XBOX)
|
||||
#define FSSTDIO_OpenPath VFSOS_OpenPath
|
||||
#endif
|
||||
#define FSSTDIO_OpenTemp FS_OpenTemp
|
||||
#if !defined(_WIN32) || defined(FTE_SDL) || defined(WINRT) || defined(_XBOX)
|
||||
#define FSSTDIO_OpenPath VFSOS_OpenPath
|
||||
#endif
|
||||
#define FSSTDIO_OpenTemp FS_OpenTemp
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
|
@ -148,7 +148,7 @@ vfsfile_t *FSSTDIO_OpenTemp(void)
|
|||
vfsfile_t *Sys_OpenAsset(const char *fname);
|
||||
#endif
|
||||
|
||||
static vfsfile_t *VFSSTDIO_Open(const char *osname, const char *mode, qboolean *needsflush)
|
||||
vfsfile_t *VFSSTDIO_Open(const char *osname, const char *mode, qboolean *needsflush)
|
||||
{
|
||||
FILE *f;
|
||||
vfsstdiofile_t *file;
|
||||
|
|
|
@ -254,18 +254,24 @@ typedef struct
|
|||
q2cbrushside_t *brushside;
|
||||
} q2cbrush_t;
|
||||
|
||||
#ifdef Q2BSPS
|
||||
typedef struct
|
||||
{
|
||||
int numareaportals;
|
||||
int firstareaportal;
|
||||
int floodnum; // if two areas have equal floodnums, they are connected
|
||||
int floodvalid;
|
||||
} q2carea_t;
|
||||
|
||||
#endif
|
||||
#ifdef Q3BSPS
|
||||
typedef struct
|
||||
{
|
||||
int numareaportals[MAX_CM_AREAS];
|
||||
} q3carea_t;
|
||||
#endif
|
||||
typedef struct
|
||||
{
|
||||
int floodnum; // if two areas have equal floodnums, they are connected
|
||||
int floodvalid; // flags the area as having been visited (sequence numbers matching prv->floodvalid)
|
||||
} careaflood_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -353,10 +359,22 @@ typedef struct cminfo_s
|
|||
q3dvis_t *q3phs;
|
||||
|
||||
int numareas;
|
||||
q2carea_t q2areas[MAX_Q2MAP_AREAS];
|
||||
int floodvalid;
|
||||
careaflood_t areaflood[MAX_CM_AREAS];
|
||||
#ifdef Q3BSPS
|
||||
//q3's areas are simple bidirectional area1/area2 pairs. refcounted (so two areas can have two doors/openings)
|
||||
q3carea_t q3areas[MAX_CM_AREAS];
|
||||
int numareaportals;
|
||||
q2dareaportal_t areaportals[MAX_Q2MAP_AREAPORTALS];
|
||||
#endif
|
||||
#ifdef Q2BSPS
|
||||
//q2's areas have a list of portals that open into other areas.
|
||||
q2carea_t *q2areas; //indexes into q2areaportals for flooding
|
||||
size_t numq2areaportals;
|
||||
q2dareaportal_t *q2areaportals;
|
||||
|
||||
//and this is the state that is actually changed. booleans.
|
||||
qbyte q2portalopen[MAX_Q2MAP_AREAPORTALS]; //memset will work if it's a qbyte, really it should be a qboolean
|
||||
#endif
|
||||
|
||||
|
||||
//list of mesh surfaces within the leaf
|
||||
q3cmesh_t cmeshes[MAX_CM_PATCHES];
|
||||
|
@ -374,10 +392,7 @@ typedef struct cminfo_s
|
|||
int maxleafpatches;
|
||||
//FIXME: remove the above
|
||||
|
||||
int floodvalid;
|
||||
qbyte portalopen[MAX_Q2MAP_AREAPORTALS]; //memset will work if it's a qbyte, really it should be a qboolean
|
||||
|
||||
int mapisq3;
|
||||
qboolean mapisq3;
|
||||
|
||||
|
||||
|
||||
|
@ -1964,7 +1979,7 @@ static qboolean CModQ2_LoadAreas (model_t *mod, qbyte *mod_base, lump_t *l)
|
|||
{
|
||||
cminfo_t *prv = (cminfo_t*)mod->meshinfo;
|
||||
int i;
|
||||
q2carea_t *out;
|
||||
q2carea_t *out;
|
||||
q2darea_t *in;
|
||||
int count;
|
||||
|
||||
|
@ -1982,15 +1997,13 @@ static qboolean CModQ2_LoadAreas (model_t *mod, qbyte *mod_base, lump_t *l)
|
|||
return false;
|
||||
}
|
||||
|
||||
out = prv->q2areas;
|
||||
out = prv->q2areas = ZG_Malloc(&mod->memgroup, sizeof(*out) * count);;
|
||||
prv->numareas = count;
|
||||
|
||||
for ( i=0 ; i<count ; i++, in++, out++)
|
||||
{
|
||||
out->numareaportals = LittleLong (in->numareaportals);
|
||||
out->firstareaportal = LittleLong (in->firstareaportal);
|
||||
out->floodvalid = 0;
|
||||
out->floodnum = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -2023,8 +2036,8 @@ static qboolean CModQ2_LoadAreaPortals (model_t *mod, qbyte *mod_base, lump_t *l
|
|||
return false;
|
||||
}
|
||||
|
||||
out = prv->areaportals;
|
||||
prv->numareaportals = count;
|
||||
out = prv->q2areaportals = ZG_Malloc(&mod->memgroup, sizeof(*out) * count);
|
||||
prv->numq2areaportals = count;
|
||||
|
||||
for ( i=0 ; i<count ; i++, in++, out++)
|
||||
{
|
||||
|
@ -3533,11 +3546,12 @@ static void CModQ3_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l)
|
|||
BuildLightMapGammaTable(1, (1<<(2-gl_overbright.ival)));
|
||||
|
||||
loadmodel->lightmaps.merge = 0;
|
||||
if (!samples)
|
||||
return;
|
||||
|
||||
loadmodel->engineflags |= MDLF_NEEDOVERBRIGHT;
|
||||
|
||||
if (!samples)
|
||||
return;
|
||||
|
||||
loadmodel->lightmaps.fmt = LM_RGB8;
|
||||
|
||||
if (loadmodel->lightmaps.deluxemapping)
|
||||
|
@ -4450,10 +4464,20 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
|
|||
|
||||
BSPX_LoadEnvmaps(mod, bspx, mod_base);
|
||||
|
||||
#ifdef Q3BSPS
|
||||
{
|
||||
int x, y;
|
||||
for (x = 0; x < prv->numareas; x++)
|
||||
for (y = 0; y < prv->numareas; y++)
|
||||
prv->q3areas[x].numareaportals[y] = map_autoopenportals.ival;
|
||||
}
|
||||
#endif
|
||||
#ifdef Q2BSPS
|
||||
if (map_autoopenportals.value)
|
||||
memset (prv->portalopen, 1, sizeof(prv->portalopen)); //open them all. Used for progs that havn't got a clue.
|
||||
memset (prv->q2portalopen, 1, sizeof(prv->q2portalopen)); //open them all. Used for progs that havn't got a clue.
|
||||
else
|
||||
memset (prv->portalopen, 0, sizeof(prv->portalopen)); //make them start closed.
|
||||
memset (prv->q2portalopen, 0, sizeof(prv->q2portalopen)); //make them start closed.
|
||||
#endif
|
||||
FloodAreaConnections (prv);
|
||||
|
||||
mod->checksum = mod->checksum2 = *checksum;
|
||||
|
@ -6485,36 +6509,45 @@ AREAPORTALS
|
|||
===============================================================================
|
||||
*/
|
||||
|
||||
static void FloodArea_r (cminfo_t *prv, q2carea_t *area, int floodnum)
|
||||
static void FloodArea_r (cminfo_t *prv, size_t areaidx, int floodnum)
|
||||
{
|
||||
int i;
|
||||
size_t i;
|
||||
|
||||
if (area->floodvalid == prv->floodvalid)
|
||||
careaflood_t *flood = &prv->areaflood[areaidx];
|
||||
if (flood->floodvalid == prv->floodvalid)
|
||||
{
|
||||
if (area->floodnum == floodnum)
|
||||
if (flood->floodnum == floodnum)
|
||||
return;
|
||||
Con_Printf ("FloodArea_r: reflooded\n");
|
||||
return;
|
||||
}
|
||||
|
||||
area->floodnum = floodnum;
|
||||
area->floodvalid = prv->floodvalid;
|
||||
if (prv->mapisq3)
|
||||
flood->floodnum = floodnum;
|
||||
flood->floodvalid = prv->floodvalid;
|
||||
switch(prv->mapisq3)
|
||||
{
|
||||
case true:
|
||||
#ifdef Q3BSPS
|
||||
for (i=0 ; i<prv->numareas ; i++)
|
||||
{
|
||||
if (prv->q3areas[area - prv->q2areas].numareaportals[i]>0)
|
||||
FloodArea_r (prv, &prv->q2areas[i], floodnum);
|
||||
if (prv->q3areas[areaidx].numareaportals[i]>0)
|
||||
FloodArea_r (prv, i, floodnum);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
q2dareaportal_t *p = &prv->areaportals[area->firstareaportal];
|
||||
for (i=0 ; i<area->numareaportals ; i++, p++)
|
||||
#endif
|
||||
break;
|
||||
case false:
|
||||
#ifdef Q2BSPS
|
||||
{
|
||||
if (prv->portalopen[p->portalnum])
|
||||
FloodArea_r (prv, &prv->q2areas[p->otherarea], floodnum);
|
||||
q2carea_t *area = &prv->q2areas[areaidx];
|
||||
q2dareaportal_t *p = &prv->q2areaportals[area->firstareaportal];
|
||||
for (i=0 ; i<area->numareaportals ; i++, p++)
|
||||
{
|
||||
if (prv->q2portalopen[p->portalnum])
|
||||
FloodArea_r (prv, p->otherarea, floodnum);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6527,8 +6560,7 @@ FloodAreaConnections
|
|||
*/
|
||||
static void FloodAreaConnections (cminfo_t *prv)
|
||||
{
|
||||
int i;
|
||||
q2carea_t *area;
|
||||
size_t i;
|
||||
int floodnum;
|
||||
|
||||
// all current floods are now invalid
|
||||
|
@ -6538,15 +6570,14 @@ static void FloodAreaConnections (cminfo_t *prv)
|
|||
// area 0 is not used
|
||||
for (i=0 ; i<prv->numareas ; i++)
|
||||
{
|
||||
area = &prv->q2areas[i];
|
||||
if (area->floodvalid == prv->floodvalid)
|
||||
if (prv->areaflood[i].floodvalid == prv->floodvalid)
|
||||
continue; // already flooded into
|
||||
floodnum++;
|
||||
FloodArea_r (prv, area, floodnum);
|
||||
FloodArea_r (prv, i, floodnum);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef Q2BSPS
|
||||
void CMQ2_SetAreaPortalState (model_t *mod, unsigned int portalnum, qboolean open)
|
||||
{
|
||||
cminfo_t *prv;
|
||||
|
@ -6555,17 +6586,19 @@ void CMQ2_SetAreaPortalState (model_t *mod, unsigned int portalnum, qboolean ope
|
|||
prv = (cminfo_t*)mod->meshinfo;
|
||||
if (prv->mapisq3)
|
||||
return;
|
||||
if (portalnum > prv->numareaportals)
|
||||
if (portalnum > prv->numq2areaportals)
|
||||
Host_Error ("areaportal > numareaportals");
|
||||
|
||||
if (prv->portalopen[portalnum] == open)
|
||||
if (prv->q2portalopen[portalnum] == open)
|
||||
return;
|
||||
prv->portalopen[portalnum] = open;
|
||||
prv->q2portalopen[portalnum] = open;
|
||||
FloodAreaConnections (prv);
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef Q3BSPS
|
||||
void CMQ3_SetAreaPortalState (model_t *mod, unsigned int area1, unsigned int area2, qboolean open)
|
||||
{
|
||||
cminfo_t *prv = (cminfo_t*)mod->meshinfo;
|
||||
|
@ -6589,6 +6622,7 @@ void CMQ3_SetAreaPortalState (model_t *mod, unsigned int area1, unsigned int are
|
|||
|
||||
FloodAreaConnections(prv);
|
||||
}
|
||||
#endif
|
||||
|
||||
qboolean VARGS CM_AreasConnected (model_t *mod, unsigned int area1, unsigned int area2)
|
||||
{
|
||||
|
@ -6602,7 +6636,7 @@ qboolean VARGS CM_AreasConnected (model_t *mod, unsigned int area1, unsigned int
|
|||
if (area1 > prv->numareas || area2 > prv->numareas)
|
||||
Host_Error ("area > numareas");
|
||||
|
||||
if (prv->q2areas[area1].floodnum == prv->q2areas[area2].floodnum)
|
||||
if (prv->areaflood[area1].floodnum == prv->areaflood[area2].floodnum)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@ -6637,10 +6671,10 @@ int CM_WriteAreaBits (model_t *mod, qbyte *buffer, int area, qboolean merge)
|
|||
if (!merge)
|
||||
memset (buffer, 0, bytes);
|
||||
|
||||
floodnum = prv->q2areas[area].floodnum;
|
||||
floodnum = prv->areaflood[area].floodnum;
|
||||
for (i=0 ; i<prv->numareas ; i++)
|
||||
{
|
||||
if (prv->q2areas[i].floodnum == floodnum || !area)
|
||||
if (prv->areaflood[i].floodnum == floodnum || !area)
|
||||
buffer[i>>3] |= 1<<(i&7);
|
||||
}
|
||||
}
|
||||
|
@ -6661,17 +6695,19 @@ size_t CM_WritePortalState (model_t *mod, void **data)
|
|||
|
||||
if (mod->type == mod_brush && (mod->fromgame == fg_quake2 || mod->fromgame == fg_quake3))
|
||||
{
|
||||
switch(prv->mapisq3)
|
||||
{
|
||||
#ifdef Q3BSPS
|
||||
if (prv->mapisq3)
|
||||
{ //endian issues. oh well.
|
||||
case true:
|
||||
//endian issues. oh well.
|
||||
*data = prv->q3areas;
|
||||
return sizeof(prv->q3areas);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
*data = prv->portalopen;
|
||||
return sizeof(prv->portalopen);
|
||||
#ifdef Q2BSPS
|
||||
case false:
|
||||
*data = prv->q2portalopen;
|
||||
return sizeof(prv->q2portalopen);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
*data = NULL;
|
||||
|
@ -6692,9 +6728,10 @@ qofs_t CM_ReadPortalState (model_t *mod, qbyte *ptr, qofs_t ptrsize)
|
|||
|
||||
if (mod->type == mod_brush && (mod->fromgame == fg_quake2 || mod->fromgame == fg_quake3))
|
||||
{
|
||||
#ifdef Q3BSPS
|
||||
if (prv->mapisq3)
|
||||
switch(prv->mapisq3)
|
||||
{
|
||||
#ifdef Q3BSPS
|
||||
case 1:
|
||||
if (ptrsize < sizeof(prv->q3areas))
|
||||
Con_Printf("CM_ReadPortalState() expected %u, but only %u available\n",(unsigned int)sizeof(prv->q3areas),(unsigned int)ptrsize);
|
||||
else
|
||||
|
@ -6702,21 +6739,23 @@ qofs_t CM_ReadPortalState (model_t *mod, qbyte *ptr, qofs_t ptrsize)
|
|||
memcpy(prv->q3areas, ptr, sizeof(prv->q3areas));
|
||||
|
||||
FloodAreaConnections (prv);
|
||||
return sizeof(prv->portalopen);
|
||||
return sizeof(prv->q3areas);
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
#endif
|
||||
{
|
||||
if (ptrsize < sizeof(prv->portalopen))
|
||||
Con_Printf("CM_ReadPortalState() expected %u, but only %u available\n",(unsigned int)sizeof(prv->portalopen),(unsigned int)ptrsize);
|
||||
#ifdef Q2BSPS
|
||||
case 0:
|
||||
if (ptrsize < sizeof(prv->q2portalopen))
|
||||
Con_Printf("CM_ReadPortalState() expected %u, but only %u available\n",(unsigned int)sizeof(prv->q2portalopen),(unsigned int)ptrsize);
|
||||
else
|
||||
{
|
||||
memcpy(prv->portalopen, ptr, sizeof(prv->portalopen));
|
||||
memcpy(prv->q2portalopen, ptr, sizeof(prv->q2portalopen));
|
||||
|
||||
FloodAreaConnections (prv);
|
||||
return sizeof(prv->portalopen);
|
||||
return sizeof(prv->q2portalopen);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -28,6 +28,10 @@ cvar_t log_dosformat = CVARF("log_dosformat", "0", CVAR_NOTFROMSERVER);
|
|||
#endif
|
||||
qboolean log_newline[LOG_TYPES];
|
||||
|
||||
#ifdef IPLOG
|
||||
cvar_t iplog_autodump = CVARFD("ipautodump", "1", CVAR_NOTFROMSERVER, "Enables dumping the 'iplog.txt' file, which contains a log of usernames seen for a given IP, which is useful for detecting fake-nicks.");
|
||||
#endif
|
||||
|
||||
static char log_dir[MAX_OSPATH];
|
||||
static enum fs_relative log_root = FS_GAMEONLY;
|
||||
|
||||
|
@ -335,6 +339,7 @@ void SV_Fraglogfile_f (void)
|
|||
}
|
||||
*/
|
||||
|
||||
#ifdef IPLOG
|
||||
/*for fuck sake, why can people still not write simple files. proquake is writing binary files as text ones. this function is to try to deal with that fuckup*/
|
||||
static size_t IPLog_Read_Fucked(qbyte *file, size_t *offset, size_t totalsize, qbyte *out, size_t outsize)
|
||||
{
|
||||
|
@ -356,7 +361,7 @@ static size_t IPLog_Read_Fucked(qbyte *file, size_t *offset, size_t totalsize, q
|
|||
}
|
||||
return read;
|
||||
}
|
||||
/*need to make sure any 13 bytes followed by 10s don't bug out when read back in *sigh* */
|
||||
/*need to make sure any 13 bytes are followed by 10s so that we don't bug out when read back in *sigh* */
|
||||
static size_t IPLog_Write_Fucked(vfsfile_t *file, qbyte *out, size_t outsize)
|
||||
{
|
||||
qbyte tmp[64];
|
||||
|
@ -623,6 +628,7 @@ static void IPLog_Merge_f(void)
|
|||
if (!IPLog_Merge_File(fname))
|
||||
Con_Printf("unable to read %s\n", fname);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef SERVERONLY
|
||||
struct certlog_s
|
||||
|
@ -791,7 +797,9 @@ qboolean CertLog_ConnectOkay(const char *hostname, void *cert, size_t certsize)
|
|||
|
||||
void Log_ShutDown(void)
|
||||
{
|
||||
IPLog_Dump("iplog.txt");
|
||||
#ifdef IPLOG
|
||||
if (iplog_autodump.ival)
|
||||
IPLog_Dump("iplog.txt");
|
||||
// IPLog_Dump("iplog.dat");
|
||||
|
||||
while(iplog_num > 0)
|
||||
|
@ -802,6 +810,7 @@ void Log_ShutDown(void)
|
|||
BZ_Free(iplog_entries);
|
||||
iplog_entries = NULL;
|
||||
iplog_max = iplog_num = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Log_Init(void)
|
||||
|
@ -824,9 +833,12 @@ void Log_Init(void)
|
|||
|
||||
Cmd_AddCommand("logfile", Log_Logfile_f);
|
||||
|
||||
Cmd_AddCommand("identify", IPLog_Identify_f);
|
||||
#ifdef IPLOG
|
||||
Cmd_AddCommandD("identify", IPLog_Identify_f, "Looks up a player's ip to see if they're using a different name");
|
||||
Cmd_AddCommand("ipmerge", IPLog_Merge_f);
|
||||
Cmd_AddCommand("ipdump", IPLog_Dump_f);
|
||||
Cvar_Register (&iplog_autodump, CONLOGGROUP);
|
||||
#endif
|
||||
|
||||
// cmd line options, debug options
|
||||
#ifdef CRAZYDEBUGGING
|
||||
|
|
|
@ -554,7 +554,7 @@ void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3])
|
|||
R_ConcatTransforms
|
||||
================
|
||||
*/
|
||||
void QDECL R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4])
|
||||
void QDECL R_ConcatTransforms (const float in1[3][4], const float in2[3][4], float out[3][4])
|
||||
{
|
||||
out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] +
|
||||
in1[0][2] * in2[2][0];
|
||||
|
|
|
@ -203,7 +203,7 @@ fixed16_t Mul16_30 (fixed16_t multiplier, fixed16_t multiplicand);
|
|||
int Q_log2 (int val);
|
||||
void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]);
|
||||
void R_ConcatRotationsPad (float in1[3][4], float in2[3][4], float out[3][4]);
|
||||
void QDECL R_ConcatTransforms (matrix3x4 in1, matrix3x4 in2, matrix3x4 out);
|
||||
void QDECL R_ConcatTransforms (const matrix3x4 in1, const matrix3x4 in2, matrix3x4 out);
|
||||
void R_ConcatTransformsAxis (float in1[3][3], float in2[3][4], float out[3][4]);
|
||||
void RotatePointAroundVector (vec3_t dst, const vec3_t dir, const vec3_t point, float degrees);
|
||||
void RotateLightVector(const vec3_t *axis, const vec3_t origin, const vec3_t lightpoint, vec3_t result);
|
||||
|
|
|
@ -177,6 +177,12 @@ qboolean NET_CompareAdrMasked(netadr_t *a, netadr_t *b, netadr_t *mask);
|
|||
|
||||
qboolean FTENET_AddToCollection(struct ftenet_connections_s *col, const char *name, const char *address, netadrtype_t addrtype, netproto_t addrprot);
|
||||
|
||||
enum certprops_e
|
||||
{
|
||||
QCERT_PEERFINGERPRINT
|
||||
};
|
||||
size_t NET_GetConnectionCertificate(struct ftenet_connections_s *col, netadr_t *a, enum certprops_e prop, char *out, size_t outsize);
|
||||
|
||||
#ifdef HAVE_DTLS
|
||||
qboolean NET_DTLS_Create(struct ftenet_connections_s *col, netadr_t *to);
|
||||
qboolean NET_DTLS_Decode(struct ftenet_connections_s *col);
|
||||
|
|
|
@ -2715,6 +2715,37 @@ qboolean NET_DTLS_Decode(ftenet_connections_t *col)
|
|||
#endif
|
||||
|
||||
|
||||
size_t NET_GetConnectionCertificate(struct ftenet_connections_s *col, netadr_t *a, enum certprops_e prop, char *out, size_t outsize)
|
||||
{
|
||||
if (!col)
|
||||
return 0;
|
||||
|
||||
switch(prop)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
case QCERT_PEERFINGERPRINT:
|
||||
#if 0//def HAVE_DTLS
|
||||
if (a->prot == NP_DTLS)
|
||||
{
|
||||
struct dtlspeer_s *peer;
|
||||
{
|
||||
a->prot = NP_DGRAM;
|
||||
for (peer = col->dtls; peer; peer = peer->next)
|
||||
{
|
||||
if (NET_CompareAdr(&peer->addr, a))
|
||||
break;
|
||||
}
|
||||
a->prot = NP_DTLS;
|
||||
}
|
||||
if (peer)
|
||||
return peer->funcs->GetPeerCertificate(peer->dtlsstate, data, length);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -308,6 +308,7 @@ typedef struct dtlsfuncs_s
|
|||
neterr_t (*Transmit)(void *ctx, const qbyte *data, size_t datasize);
|
||||
neterr_t (*Received)(void *ctx, qbyte *data, size_t datasize);
|
||||
neterr_t (*Timeouts)(void *ctx);
|
||||
void (*GetPeerCertificate)(void *ctx);
|
||||
} dtlsfuncs_t;
|
||||
const dtlsfuncs_t *DTLS_InitServer(void);
|
||||
const dtlsfuncs_t *DTLS_InitClient(void);
|
||||
|
|
|
@ -1640,10 +1640,10 @@ typedef struct
|
|||
char *stringdata;
|
||||
};
|
||||
} pf_hashentry_t;
|
||||
pf_hashtab_t *pf_hashtab;
|
||||
size_t pf_hash_maxtables;
|
||||
pf_hashtab_t pf_peristanthashtab; //persists over map changes.
|
||||
pf_hashtab_t pf_reverthashtab; //pf_peristanthashtab as it was at map start, for map restarts.
|
||||
static pf_hashtab_t *pf_hashtab;
|
||||
static size_t pf_hash_maxtables;
|
||||
static pf_hashtab_t pf_peristanthashtab; //persists over map changes.
|
||||
//static pf_hashtab_t pf_reverthashtab; //pf_peristanthashtab as it was at map start, for map restarts.
|
||||
static pf_hashtab_t *PF_hash_findtab(pubprogfuncs_t *prinst, int idx)
|
||||
{
|
||||
idx -= 1;
|
||||
|
@ -1664,7 +1664,7 @@ static pf_hashtab_t *PF_hash_findtab(pubprogfuncs_t *prinst, int idx)
|
|||
else
|
||||
PR_BIError(prinst, "PF_hash_findtab: invalid hash table\n");
|
||||
return NULL;
|
||||
};
|
||||
}
|
||||
|
||||
void QCBUILTIN PF_hash_getkey (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
|
@ -1734,10 +1734,10 @@ void QCBUILTIN PF_hash_get (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
|
|||
}
|
||||
else
|
||||
memcpy(G_VECTOR(OFS_RETURN), ent->data, sizeof(vec3_t));
|
||||
return;
|
||||
}
|
||||
else
|
||||
memcpy(G_VECTOR(OFS_RETURN), dflt, sizeof(vec3_t));
|
||||
}
|
||||
memcpy(G_VECTOR(OFS_RETURN), dflt, sizeof(vec3_t));
|
||||
}
|
||||
void QCBUILTIN PF_hash_getcb (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
|
@ -1904,10 +1904,10 @@ typedef struct {
|
|||
size_t bufferlen;
|
||||
size_t len;
|
||||
size_t ofs;
|
||||
int accessmode;
|
||||
pubprogfuncs_t *prinst;
|
||||
long accessmode;
|
||||
} pf_fopen_files_t;
|
||||
pf_fopen_files_t pf_fopen_files[MAX_QC_FILES];
|
||||
static pf_fopen_files_t pf_fopen_files[MAX_QC_FILES];
|
||||
|
||||
//returns false if the file is denied.
|
||||
//fallbackread can be NULL, if the qc is not allowed to read that (original) file at all.
|
||||
|
|
|
@ -775,7 +775,9 @@ enum lightfield_e
|
|||
lfield_rotation=13,
|
||||
lfield_dietime=14,
|
||||
lfield_rgbdecay=15,
|
||||
lfield_radiusdecay=16
|
||||
lfield_radiusdecay=16,
|
||||
|
||||
lfield_stylestring=17
|
||||
};
|
||||
enum csqc_input_event
|
||||
{
|
||||
|
|
|
@ -2199,7 +2199,15 @@ struct bspx_header_s {
|
|||
};
|
||||
//supported lumps:
|
||||
//RGBLIGHTING (.lit)
|
||||
//LIGHTING_E5BGR9 (hdr lit)
|
||||
//LIGHTINGDIR (.lux)
|
||||
//LMSHIFT (lightmap scaling)
|
||||
//LMOFFSET (lightmap scaling)
|
||||
//LMSTYLE (lightmap scaling)
|
||||
//VERTEXNORMALS (smooth specular)
|
||||
//BRUSHLIST (no hull size issues)
|
||||
//ENVMAP (cubemaps)
|
||||
//SURFENVMAP (cubemaps)
|
||||
void *BSPX_FindLump(bspx_header_t *bspxheader, void *mod_base, char *lumpname, int *lumpsize)
|
||||
{
|
||||
int i;
|
||||
|
@ -2424,11 +2432,11 @@ void BSPX_LoadEnvmaps(model_t *mod, bspx_header_t *bspx, void *mod_base)
|
|||
|
||||
struct bspxrw
|
||||
{
|
||||
fromgame_t fg;
|
||||
const char *fname;
|
||||
char *origfile;
|
||||
qofs_t origsize;
|
||||
int lumpofs;
|
||||
fromgame_t fg;
|
||||
|
||||
size_t corelumps;
|
||||
size_t totallumps;
|
||||
|
|
|
@ -240,7 +240,7 @@ static void memxor(char *dest, const char *src, size_t length)
|
|||
}
|
||||
}
|
||||
|
||||
typedef size_t hashfunc_t(unsigned char *digest, size_t maxdigestsize, size_t numstrings, const unsigned char **strings, size_t *stringlens);
|
||||
//typedef size_t hashfunc_t(unsigned char *digest, size_t maxdigestsize, size_t numstrings, const unsigned char **strings, size_t *stringlens);
|
||||
size_t HMAC(hashfunc_t *hashfunc, unsigned char *digest, size_t maxdigestsize,
|
||||
const unsigned char *data, size_t datalen,
|
||||
const unsigned char *key, size_t keylen)
|
||||
|
|
|
@ -122,7 +122,9 @@ typedef struct q2trace_s
|
|||
#define MOVE_NORMAL 0
|
||||
#define MOVE_NOMONSTERS (1<<0)
|
||||
#define MOVE_MISSILE (1<<1)
|
||||
#define MOVE_WORLDONLY (MOVE_NOMONSTERS|MOVE_MISSILE)
|
||||
#ifndef NOLEGACY
|
||||
#define MOVE_WORLDONLY (MOVE_NOMONSTERS|MOVE_MISSILE) //use MOVE_OTHERONLY instead
|
||||
#endif
|
||||
#define MOVE_HITMODEL (1<<2)
|
||||
#define MOVE_RESERVED (1<<3) //so we are less likly to get into tricky situations when we want to steal annother future DP extension.
|
||||
#define MOVE_TRIGGERS (1<<4) //triggers must be marked with FINDABLE_NONSOLID (an alternative to solid-corpse)
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
#include "gl_draw.h"
|
||||
#ifdef D3D9QUAKE
|
||||
#include "shader.h"
|
||||
#include <d3d9.h>
|
||||
#if !defined(HMONITOR_DECLARED) && (WINVER < 0x0500)
|
||||
#define HMONITOR_DECLARED
|
||||
DECLARE_HANDLE(HMONITOR);
|
||||
#endif
|
||||
#include <d3d9.h>
|
||||
|
||||
/*
|
||||
Things to improve:
|
||||
|
|
|
@ -1127,7 +1127,7 @@ static qboolean (D3D9_SCR_UpdateScreen) (void)
|
|||
if (uimenu != 1)
|
||||
{
|
||||
if (r_worldentity.model && cls.state == ca_active)
|
||||
V_RenderView ();
|
||||
V_RenderView (nohud);
|
||||
else
|
||||
{
|
||||
noworld = true;
|
||||
|
|
|
@ -1426,7 +1426,7 @@ static qboolean (D3D11_SCR_UpdateScreen) (void)
|
|||
if (uimenu != 1)
|
||||
{
|
||||
if (r_worldentity.model && cls.state == ca_active)
|
||||
V_RenderView ();
|
||||
V_RenderView (nohud);
|
||||
else
|
||||
{
|
||||
noworld = true;
|
||||
|
|
|
@ -1079,16 +1079,19 @@ qboolean GLBE_BeginShadowMap(int id, int w, int h, int *restorefbo)
|
|||
|
||||
if (!TEXVALID(shadowmap[id]))
|
||||
{
|
||||
shadowmap[id] = Image_CreateTexture(va("***shadowmap2d%i***", id), NULL, 0);
|
||||
qglGenTextures(1, &shadowmap[id]->num);
|
||||
GL_MTBind(0, GL_TEXTURE_2D, shadowmap[id]);
|
||||
uploadfmt_t encoding = PTI_DEPTH32;
|
||||
texid_t tex = shadowmap[id] = Image_CreateTexture(va("***shadowmap2d%i***", id), NULL, 0);
|
||||
qglGenTextures(1, &tex->num);
|
||||
GL_MTBind(0, GL_TEXTURE_2D, tex);
|
||||
#ifdef SHADOWDBG_COLOURNOTDEPTH
|
||||
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
#else
|
||||
if (gl_config.gles)
|
||||
qglTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, w, h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL);
|
||||
if (qglTexStorage2D)
|
||||
qglTexStorage2D(GL_TEXTURE_2D, 1, gl_config.formatinfo[encoding].sizedformat, w, h);
|
||||
else if (gl_config.formatinfo[encoding].type)
|
||||
qglTexImage2D (GL_TEXTURE_2D, 0, gl_config.formatinfo[encoding].sizedformat, w, h, 0, gl_config.formatinfo[encoding].format, gl_config.formatinfo[encoding].type, NULL);
|
||||
else
|
||||
qglTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16_ARB, w, h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL);
|
||||
qglCompressedTexImage2D (GL_TEXTURE_2D, 0, gl_config.formatinfo[encoding].sizedformat, w, h, 0, 0, NULL);
|
||||
#endif
|
||||
|
||||
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
@ -1614,7 +1617,16 @@ void GLBE_Init(void)
|
|||
|
||||
gl_overbright.modified = true; /*in case the d3d renderer does the same*/
|
||||
/*lock the cvar down if the backend can't actually do it*/
|
||||
if (!gl_config.tex_env_combine && !gl_config_nofixedfunc && gl_overbright.ival)
|
||||
if (
|
||||
#if 1//defined(QUAKETC)
|
||||
//TCs are expected to be using glsl and weird overbright things etc, don't take the risk.
|
||||
(!sh_config.progs_supported)
|
||||
#else
|
||||
//Q3 can get away with tex_env_combine for everything, if only because the content allows everything to be flattened to a single pass if needed...
|
||||
//some shaders might screw up from our approach though...
|
||||
(!gl_config.tex_env_combine && !gl_config_nofixedfunc)
|
||||
#endif
|
||||
&& gl_overbright.ival)
|
||||
Cvar_ApplyLatchFlag(&gl_overbright, "0", CVAR_RENDERERLATCH);
|
||||
shaderstate.shaderbits = ~SBITS_ATEST_BITS;
|
||||
BE_SendPassBlendDepthMask(0);
|
||||
|
|
|
@ -43,8 +43,6 @@ static int gl_filter_mip[3]; //everything else
|
|||
int gl_mipcap_min = 0;
|
||||
int gl_mipcap_max = 1000;
|
||||
|
||||
void Image_WriteKTXFile(const char *filename, struct pendingtextureinfo *mips);
|
||||
|
||||
void GL_DestroyTexture(texid_t tex)
|
||||
{
|
||||
if (!tex)
|
||||
|
@ -964,7 +962,7 @@ qboolean GL_LoadTextureMips(texid_t tex, const struct pendingtextureinfo *mips)
|
|||
if (i)
|
||||
{
|
||||
out.mipcount = i;
|
||||
Image_WriteKTXFile(va("textures/%s.ktx", tex->ident), &out);
|
||||
Image_WriteKTXFile(va("textures/%s.ktx", tex->ident), FS_GAMEONLY, &out);
|
||||
}
|
||||
while (i-- > 0)
|
||||
if (out.mip[i].needfree)
|
||||
|
|
|
@ -1750,15 +1750,26 @@ static texid_t Font_LoadFallbackConchars(void)
|
|||
Font_CopyGlyph('[', 128, lump);
|
||||
Font_CopyGlyph('-', 129, lump);
|
||||
Font_CopyGlyph(']', 130, lump);
|
||||
Font_CopyGlyph('o', 131, lump);
|
||||
Font_CopyGlyph('|', 131, lump);
|
||||
Font_CopyGlyph('>', 13, lump);
|
||||
}
|
||||
tex = R_LoadTexture32("charset", width, height, (void*)lump, IF_PREMULTIPLYALPHA|IF_LOADNOW|IF_UIPIC|IF_NOMIPMAP|IF_NOGAMMA);
|
||||
BZ_Free(lump);
|
||||
return tex;
|
||||
}
|
||||
|
||||
enum fontfmt_e
|
||||
{
|
||||
FMT_AUTO, //freetype, or quake
|
||||
FMT_QUAKE, //first is default
|
||||
FMT_ISO88591, //latin-1 (first 256 chars of unicode too, c1 glyphs are usually invisible)
|
||||
FMT_WINDOWS1252,//variation of latin-1 with extra glyphs
|
||||
FMT_KOI8U, //image is 16*16 koi8-u codepage.
|
||||
FMT_HORIZONTAL, //unicode, charcount=width/(height-2). single strip of chars, like halflife.
|
||||
};
|
||||
|
||||
/*loads a fallback image. not allowed to fail (use syserror if needed)*/
|
||||
static texid_t Font_LoadDefaultConchars(void)
|
||||
static texid_t Font_LoadDefaultConchars(enum fontfmt_e *fmt)
|
||||
{
|
||||
texid_t tex;
|
||||
tex = Font_LoadReplacementConchars();
|
||||
|
@ -1774,13 +1785,19 @@ static texid_t Font_LoadDefaultConchars(void)
|
|||
if (tex && tex->status == TEX_LOADING)
|
||||
COM_WorkerPartialSync(tex, &tex->status, TEX_LOADING);
|
||||
if (TEXLOADED(tex))
|
||||
{
|
||||
*fmt = FMT_ISO88591;
|
||||
return tex;
|
||||
}
|
||||
#endif
|
||||
tex = Font_LoadFallbackConchars();
|
||||
if (tex && tex->status == TEX_LOADING)
|
||||
COM_WorkerPartialSync(tex, &tex->status, TEX_LOADING);
|
||||
if (TEXLOADED(tex))
|
||||
{
|
||||
*fmt = FMT_QUAKE;
|
||||
return tex;
|
||||
}
|
||||
Sys_Error("Unable to load any conchars\n");
|
||||
}
|
||||
|
||||
|
@ -1838,15 +1855,7 @@ struct font_s *Font_LoadFont(const char *fontfilename, float vheight)
|
|||
char facename[MAX_QPATH*12];
|
||||
struct charcache_s *c;
|
||||
float aspect = 1;
|
||||
enum
|
||||
{
|
||||
FMT_AUTO, //freetype, or quake
|
||||
FMT_QUAKE, //first is default
|
||||
FMT_ISO88591, //latin-1 (first 256 chars of unicode too, c1 glyphs are usually invisible)
|
||||
FMT_WINDOWS1252,//variation of latin-1 with extra glyphs
|
||||
FMT_KOI8U, //image is 16*16 koi8-u codepage.
|
||||
FMT_HORIZONTAL, //unicode, charcount=width/(height-2). single strip of chars, like halflife.
|
||||
} fmt = FMT_AUTO;
|
||||
enum fontfmt_e fmt = FMT_AUTO;
|
||||
|
||||
Q_strncpyz(facename, fontfilename, sizeof(facename));
|
||||
|
||||
|
@ -2155,7 +2164,7 @@ struct font_s *Font_LoadFont(const char *fontfilename, float vheight)
|
|||
{
|
||||
if (!TEXLOADED(fontplanes.defaultfont))
|
||||
{
|
||||
fontplanes.defaultfont = Font_LoadDefaultConchars();
|
||||
fontplanes.defaultfont = Font_LoadDefaultConchars(&fmt);
|
||||
}
|
||||
|
||||
#ifdef HEXEN2
|
||||
|
|
|
@ -1997,23 +1997,26 @@ void Mod_LoadLighting (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base,
|
|||
#endif
|
||||
|
||||
#ifdef RUNTIMELIGHTING
|
||||
if (!lightmodel && r_loadlits.value == 2 && (!litdata || (!luxdata && r_deluxemapping)))
|
||||
{
|
||||
writelitfile = !litdata;
|
||||
numlightdata = l->filelen;
|
||||
lightmodel = loadmodel;
|
||||
relitsurface = 0;
|
||||
}
|
||||
else if (!lightmodel && r_deluxemapping_cvar.value>1 && r_deluxemapping && !luxdata
|
||||
if ((loadmodel->type == mod_brush && loadmodel->fromgame == fg_quake) || loadmodel->type == mod_heightmap)
|
||||
{ //we only support a couple of formats. :(
|
||||
if (!lightmodel && r_loadlits.value == 2 && (!litdata || (!luxdata && r_deluxemapping)))
|
||||
{
|
||||
writelitfile = !litdata;
|
||||
numlightdata = l->filelen;
|
||||
lightmodel = loadmodel;
|
||||
relitsurface = 0;
|
||||
}
|
||||
else if (!lightmodel && r_deluxemapping_cvar.value>1 && r_deluxemapping && !luxdata
|
||||
#ifdef RTLIGHTS
|
||||
&& !(r_shadow_realtime_world.ival && r_shadow_realtime_world_lightmaps.value<=0)
|
||||
&& !(r_shadow_realtime_world.ival && r_shadow_realtime_world_lightmaps.value<=0)
|
||||
#endif
|
||||
)
|
||||
{ //if deluxemapping is on, generate missing lux files a little more often, but don't bother if we have rtlights on anyway.
|
||||
writelitfile = false;
|
||||
numlightdata = l->filelen;
|
||||
lightmodel = loadmodel;
|
||||
relitsurface = 0;
|
||||
)
|
||||
{ //if deluxemapping is on, generate missing lux files a little more often, but don't bother if we have rtlights on anyway.
|
||||
writelitfile = false;
|
||||
numlightdata = l->filelen;
|
||||
lightmodel = loadmodel;
|
||||
relitsurface = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*if we're relighting, make sure there's the proper lit data to be updated*/
|
||||
|
|
|
@ -27,7 +27,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
extern cvar_t r_shadow_realtime_world, r_shadow_realtime_world_lightmaps;
|
||||
extern cvar_t r_hdr_irisadaptation, r_hdr_irisadaptation_multiplier, r_hdr_irisadaptation_minvalue, r_hdr_irisadaptation_maxvalue, r_hdr_irisadaptation_fade_down, r_hdr_irisadaptation_fade_up;
|
||||
|
||||
|
||||
int r_dlightframecount;
|
||||
int d_lightstylevalue[256]; // 8.8 fraction of base light value
|
||||
|
||||
|
@ -363,9 +362,6 @@ void R_RenderDlights (void)
|
|||
if (!r_coronas.value && !r_flashblend.value)
|
||||
return;
|
||||
|
||||
// r_dlightframecount = r_framecount + 1; // because the count hasn't
|
||||
// advanced yet for this frame
|
||||
|
||||
l = cl_dlights+rtlights_first;
|
||||
for (i=rtlights_first; i<rtlights_max; i++, l++)
|
||||
{
|
||||
|
@ -734,6 +730,25 @@ void R_PushDlights (void)
|
|||
//rtlight loading
|
||||
|
||||
#ifdef RTLIGHTS
|
||||
//These affect importing
|
||||
static cvar_t r_editlights_import_radius = CVARAD ("r_editlights_import_radius", "1", "r_editlights_quakelightsizescale", "changes size of light entities loaded from a map");
|
||||
static cvar_t r_editlights_import_ambient = CVARD ("r_editlights_import_ambient", "0", "ambient light scaler for imported lights");
|
||||
static cvar_t r_editlights_import_diffuse = CVARD ("r_editlights_import_diffuse", "1", "diffuse light scaler for imported lights");
|
||||
static cvar_t r_editlights_import_specular = CVARD ("r_editlights_import_specular", "1", "specular light scaler for imported lights"); //excessive, but noticable. its called stylized, okay? shiesh, some people
|
||||
|
||||
//these are just for the crappy editor
|
||||
static cvar_t r_editlights = CVARD ("r_editlights", "0", "enables .rtlights file editing mode. Consider using csaddon/equivelent instead.");
|
||||
static cvar_t r_editlights_cursordistance = CVARD ("r_editlights_cursordistance", "1024", "maximum distance of cursor from eye");
|
||||
static cvar_t r_editlights_cursorpushoff = CVARD ("r_editlights_cursorpushoff", "4", "how far to push the cursor off the impacted surface");
|
||||
static cvar_t r_editlights_cursorpushback = CVARD ("r_editlights_cursorpushback", "0", "how far to pull the cursor back toward the eye, for some reason");
|
||||
static cvar_t r_editlights_cursorgrid = CVARD ("r_editlights_cursorgrid", "1", "snaps cursor to this grid size");
|
||||
|
||||
//internal settings
|
||||
static qboolean r_editlights_locked = false; //don't change the selected light
|
||||
static int r_editlights_selected = -1; //the light closest to the cursor
|
||||
static vec3_t r_editlights_cursor; //the position of the crosshair/cursor (new lights will be spawned here)
|
||||
static dlight_t r_editlights_copybuffer; //written by r_editlights_copyinfo, read by r_editlights_pasteinfo. FIXME: use system clipboard?
|
||||
|
||||
qboolean R_ImportRTLights(const char *entlump)
|
||||
{
|
||||
typedef enum lighttype_e {LIGHTTYPE_MINUSX, LIGHTTYPE_RECIPX, LIGHTTYPE_RECIPXX, LIGHTTYPE_INFINITE, LIGHTTYPE_LOCALMIN, LIGHTTYPE_RECIPXX2, LIGHTTYPE_SUN} lighttype_t;
|
||||
|
@ -1103,7 +1118,8 @@ qboolean R_ImportRTLights(const char *entlump)
|
|||
break;
|
||||
|
||||
VectorCopy(origin, dl->origin);
|
||||
AngleVectors(angles, dl->axis[0], dl->axis[1], dl->axis[2]);
|
||||
VectorCopy(angles, dl->angles);
|
||||
AngleVectors(dl->angles, dl->axis[0], dl->axis[1], dl->axis[2]);
|
||||
VectorInverse(dl->axis[1]);
|
||||
dl->radius = radius;
|
||||
VectorCopy(color, dl->color);
|
||||
|
@ -1121,7 +1137,8 @@ qboolean R_ImportRTLights(const char *entlump)
|
|||
if (!dl->fov) //default is 40, supposedly
|
||||
dl->fov = 40;
|
||||
|
||||
AngleVectors(mangle, dl->axis[0], dl->axis[1], dl->axis[2]);
|
||||
VectorCopy(mangle, dl->angles);
|
||||
AngleVectors(dl->angles, dl->axis[0], dl->axis[1], dl->axis[2]);
|
||||
VectorInverse(dl->axis[1]);
|
||||
}
|
||||
else if (*target)
|
||||
|
@ -1138,6 +1155,10 @@ qboolean R_ImportRTLights(const char *entlump)
|
|||
VectorVectors(dl->axis[0], dl->axis[1], dl->axis[2]);
|
||||
VectorInverse(dl->axis[1]);
|
||||
//we don't have any control over the inner cone.
|
||||
|
||||
//so queries work properly
|
||||
VectorAngles(dl->axis[0], dl->axis[2], dl->angles, false);
|
||||
dl->angles[0] = anglemod(dl->angles[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1158,6 +1179,7 @@ qboolean R_LoadRTLights(void)
|
|||
dlight_t *dl;
|
||||
char fname[MAX_QPATH];
|
||||
char cubename[MAX_QPATH];
|
||||
char customstyle[1024];
|
||||
char *file;
|
||||
char *end;
|
||||
int style;
|
||||
|
@ -1273,6 +1295,7 @@ qboolean R_LoadRTLights(void)
|
|||
flags |= file?atoi(com_token):LFLAG_REALTIMEMODE;
|
||||
|
||||
fov = avel[0] = avel[1] = avel[2] = 0;
|
||||
*customstyle = 0;
|
||||
while(file)
|
||||
{
|
||||
file = COM_Parse(file);
|
||||
|
@ -1284,6 +1307,16 @@ qboolean R_LoadRTLights(void)
|
|||
avel[2] = file?atof(com_token+5):0;
|
||||
else if (!strncmp(com_token, "fov=", 4))
|
||||
fov = file?atof(com_token+4):0;
|
||||
else if (!strncmp(com_token, "nostencil=", 10))
|
||||
flags |= atoi(com_token+10)?LFLAG_SHADOWMAP:0;
|
||||
else if (!strncmp(com_token, "crepuscular=", 12))
|
||||
flags |= atoi(com_token+12)?LFLAG_CREPUSCULAR:0;
|
||||
else if (!strncmp(com_token, "ortho=", 6))
|
||||
flags |= atoi(com_token+6)?LFLAG_ORTHO:0;
|
||||
else if (!strncmp(com_token, "stylestring=", 12))
|
||||
Q_strncpyz(customstyle, com_token+12, sizeof(customstyle));
|
||||
else if (file)
|
||||
Con_DPrintf("Unknown .rtlights arg \"%s\"\n", com_token);
|
||||
}
|
||||
|
||||
if (radius)
|
||||
|
@ -1313,13 +1346,14 @@ qboolean R_LoadRTLights(void)
|
|||
dl->cubetexture = r_nulltex;
|
||||
|
||||
dl->style = style+1;
|
||||
dl->customstyle = (*customstyle)?Z_StrDup(customstyle):NULL;
|
||||
}
|
||||
file = end+1;
|
||||
}
|
||||
return !!file;
|
||||
}
|
||||
|
||||
void R_SaveRTLights_f(void)
|
||||
static void R_SaveRTLights_f(void)
|
||||
{
|
||||
dlight_t *light;
|
||||
vfsfile_t *f;
|
||||
|
@ -1327,6 +1361,7 @@ void R_SaveRTLights_f(void)
|
|||
char fname[MAX_QPATH];
|
||||
char sysname[MAX_OSPATH];
|
||||
vec3_t ang;
|
||||
int ver = 0;
|
||||
COM_StripExtension(cl.worldmodel->name, fname, sizeof(fname));
|
||||
strncat(fname, ".rtlights", MAX_QPATH-1);
|
||||
|
||||
|
@ -1347,24 +1382,46 @@ void R_SaveRTLights_f(void)
|
|||
if (!light->radius)
|
||||
continue;
|
||||
VectorAngles(light->axis[0], light->axis[2], ang, false);
|
||||
VFS_PUTS(f, va(
|
||||
|
||||
//the .rtlights format is defined by DP, the first few parts cannot be changed without breaking wider compat.
|
||||
//it got extended a few times. only write what we need for greater compat, just in case.
|
||||
if ((light->flags & (LFLAG_SHADOWMAP|LFLAG_CREPUSCULAR|LFLAG_ORTHO)) || light->rotation[0] || light->rotation[1] || light->rotation[2] || light->fov || light->customstyle)
|
||||
ver = 2; //one of our own flags. always spew the full DP stuff to try to avoid confusion
|
||||
else if (light->coronascale!=0.25 || light->lightcolourscales[0]!=0 || light->lightcolourscales[1]!=1 || light->lightcolourscales[2]!=1 || (light->flags&~LFLAG_NOSHADOWS) != LFLAG_REALTIMEMODE)
|
||||
ver = 2;
|
||||
else if (*light->cubemapname || light->corona || ang[0] || ang[1] || ang[2])
|
||||
ver = 1;
|
||||
else
|
||||
ver = 0;
|
||||
VFS_PRINTF(f,
|
||||
"%s%f %f %f "
|
||||
"%f %f %f %f "
|
||||
"%i "
|
||||
"\"%s\" %f "
|
||||
"%f %f %f "
|
||||
"%f %f %f %f %i "
|
||||
"rotx=%g roty=%g rotz=%g fov=%g "
|
||||
"\n"
|
||||
,
|
||||
"%i",
|
||||
(light->flags & LFLAG_NOSHADOWS)?"!":"", light->origin[0], light->origin[1], light->origin[2],
|
||||
light->radius, light->color[0], light->color[1], light->color[2],
|
||||
light->style-1,
|
||||
light->cubemapname, light->corona,
|
||||
ang[0], ang[1], ang[2],
|
||||
light->coronascale, light->lightcolourscales[0], light->lightcolourscales[1], light->lightcolourscales[2], light->flags&~(LFLAG_NOSHADOWS|LFLAG_INTERNAL),
|
||||
light->rotation[0],light->rotation[1],light->rotation[2],light->fov
|
||||
));
|
||||
light->radius, light->color[0], light->color[1], light->color[2],
|
||||
light->style-1);
|
||||
if (ver > 0)
|
||||
VFS_PRINTF(f, " \"%s\" %f %f %f %f", light->cubemapname, light->corona, ang[0], ang[1], ang[2]);
|
||||
if (ver > 1)
|
||||
VFS_PRINTF(f, " %f %f %f %f %i", light->coronascale, light->lightcolourscales[0], light->lightcolourscales[1], light->lightcolourscales[2], light->flags&(LFLAG_NORMALMODE|LFLAG_REALTIMEMODE));
|
||||
|
||||
//our weird flags
|
||||
if (light->flags&LFLAG_SHADOWMAP)
|
||||
VFS_PRINTF(f, " nostencil=1");
|
||||
if (light->flags&LFLAG_CREPUSCULAR)
|
||||
VFS_PRINTF(f, " crepuscular=1");
|
||||
if (light->flags&LFLAG_ORTHO)
|
||||
VFS_PRINTF(f, " ortho=1");
|
||||
//spinning lights (for cubemaps)
|
||||
if (light->rotation[0] || light->rotation[1] || light->rotation[2])
|
||||
VFS_PRINTF(f, " rotx=%g roty=%g rotz=%g", light->rotation[0],light->rotation[1],light->rotation[2]);
|
||||
//spotlights
|
||||
if (light->fov)
|
||||
VFS_PRINTF(f, " fov=%g", light->fov); //aka: outer cone
|
||||
if (light->customstyle)
|
||||
VFS_PRINTF(f, " \"stylestring=%s\"", light->customstyle); //aka: outer cone
|
||||
|
||||
VFS_PUTS(f, "\n");
|
||||
}
|
||||
VFS_CLOSE(f);
|
||||
|
||||
|
@ -1412,7 +1469,7 @@ void R_StaticEntityToRTLight(int i)
|
|||
R_LoadNumberedLightTexture(dl, state->skinnum);
|
||||
}
|
||||
|
||||
void R_ReloadRTLights_f(void)
|
||||
static void R_ReloadRTLights_f(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -1427,19 +1484,800 @@ void R_ReloadRTLights_f(void)
|
|||
R_ImportRTLights(Mod_GetEntitiesString(cl.worldmodel));
|
||||
else if (!strcmp(Cmd_Argv(1), "rtlights"))
|
||||
R_LoadRTLights();
|
||||
else if (!strcmp(Cmd_Argv(1), "statics"))
|
||||
{
|
||||
for (i = 0; i < cl.num_statics; i++)
|
||||
R_StaticEntityToRTLight(i);
|
||||
}
|
||||
else if (!strcmp(Cmd_Argv(1), "none"))
|
||||
;
|
||||
else
|
||||
{
|
||||
R_LoadRTLights();
|
||||
//try to load .rtlights file
|
||||
if (rtlights_first == rtlights_max)
|
||||
R_LoadRTLights();
|
||||
//if there's a static entity with rtlights set, then assume the mod is taking care of it for us.
|
||||
if (rtlights_first == rtlights_max)
|
||||
for (i = 0; i < cl.num_statics; i++)
|
||||
R_StaticEntityToRTLight(i);
|
||||
//otherwise try to import.
|
||||
if (rtlights_first == rtlights_max)
|
||||
R_ImportRTLights(Mod_GetEntitiesString(cl.worldmodel));
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < cl.num_statics; i++)
|
||||
//-1 for arg error
|
||||
static int R_EditLight(dlight_t *dl, const char *cmd, int argc, const char *x, const char *y, const char *z)
|
||||
{
|
||||
if (argc == 1)
|
||||
{
|
||||
R_StaticEntityToRTLight(i);
|
||||
y = x;
|
||||
z = x;
|
||||
}
|
||||
if (!strcmp(cmd, "origin"))
|
||||
{
|
||||
dl->origin[0] = atof(x);
|
||||
dl->origin[1] = atof(y);
|
||||
dl->origin[2] = atof(z);
|
||||
}
|
||||
else if (!strcmp(cmd, "originscale"))
|
||||
{
|
||||
dl->origin[0] *= atof(x);
|
||||
dl->origin[1] *= atof(y);
|
||||
dl->origin[2] *= atof(z);
|
||||
}
|
||||
else if (!strcmp(cmd, "originx"))
|
||||
dl->origin[0] = atof(x);
|
||||
else if (!strcmp(cmd, "originy"))
|
||||
dl->origin[1] = atof(x);
|
||||
else if (!strcmp(cmd, "originz"))
|
||||
dl->origin[2] = atof(x);
|
||||
else if (!strcmp(cmd, "move"))
|
||||
{
|
||||
dl->origin[0] += atof(x);
|
||||
dl->origin[1] += atof(y);
|
||||
dl->origin[2] += atof(z);
|
||||
}
|
||||
else if (!strcmp(cmd, "movex"))
|
||||
dl->origin[0] += atof(x);
|
||||
else if (!strcmp(cmd, "movey"))
|
||||
dl->origin[1] += atof(x);
|
||||
else if (!strcmp(cmd, "movez"))
|
||||
dl->origin[2] += atof(x);
|
||||
|
||||
else if (!strcmp(cmd, "angles"))
|
||||
{
|
||||
dl->angles[0] = atof(x);
|
||||
dl->angles[1] = atof(y);
|
||||
dl->angles[2] = atof(z);
|
||||
|
||||
AngleVectors(dl->angles, dl->axis[0], dl->axis[1], dl->axis[2]);
|
||||
VectorInverse(dl->axis[1]);
|
||||
}
|
||||
else if (!strcmp(cmd, "anglesx"))
|
||||
{
|
||||
dl->angles[0] = atof(x);
|
||||
AngleVectors(dl->angles, dl->axis[0], dl->axis[1], dl->axis[2]);
|
||||
VectorInverse(dl->axis[1]);
|
||||
}
|
||||
else if (!strcmp(cmd, "anglesy"))
|
||||
{
|
||||
dl->angles[1] = atof(x);
|
||||
AngleVectors(dl->angles, dl->axis[0], dl->axis[1], dl->axis[2]);
|
||||
VectorInverse(dl->axis[1]);
|
||||
}
|
||||
else if (!strcmp(cmd, "anglesz"))
|
||||
{
|
||||
dl->angles[2] = atof(x);
|
||||
AngleVectors(dl->angles, dl->axis[0], dl->axis[1], dl->axis[2]);
|
||||
VectorInverse(dl->axis[1]);
|
||||
}
|
||||
|
||||
else if (!strcmp(cmd, "avel"))
|
||||
{
|
||||
dl->rotation[0] = atof(x);
|
||||
dl->rotation[1] = atof(y);
|
||||
dl->rotation[2] = atof(z);
|
||||
}
|
||||
else if (!strcmp(cmd, "avelx"))
|
||||
dl->rotation[0] = atof(x);
|
||||
else if (!strcmp(cmd, "avey"))
|
||||
dl->rotation[1] = atof(x);
|
||||
else if (!strcmp(cmd, "avelz"))
|
||||
dl->rotation[2] = atof(x);
|
||||
|
||||
else if (!strcmp(cmd, "outercone") || !strcmp(cmd, "fov"))
|
||||
dl->fov = atof(x);
|
||||
else if (!strcmp(cmd, "color") || !strcmp(cmd, "colour"))
|
||||
{
|
||||
dl->color[0] = atof(x);
|
||||
dl->color[1] = atof(y);
|
||||
dl->color[2] = atof(z);
|
||||
}
|
||||
else if (!strcmp(cmd, "colorscale") || !strcmp(cmd, "colourscale"))
|
||||
{
|
||||
dl->color[0] *= atof(x);
|
||||
dl->color[1] *= atof(y);
|
||||
dl->color[2] *= atof(z);
|
||||
}
|
||||
else if (!strcmp(cmd, "radius"))
|
||||
dl->radius = atof(x);
|
||||
else if (!strcmp(cmd, "radiusscale") || !strcmp(cmd, "sizescale"))
|
||||
dl->radius *= atof(x);
|
||||
else if (!strcmp(cmd, "style"))
|
||||
dl->style = atoi(x)+1; //fte's styles are internally 1-based, with 0 being a null style that ignores lightstyles entirely, which admittedly isn't often used.
|
||||
else if (!strcmp(cmd, "stylestring"))
|
||||
{
|
||||
Z_Free(dl->customstyle);
|
||||
dl->customstyle = x?Z_StrDup(x):NULL;
|
||||
}
|
||||
else if (!strcmp(cmd, "cubemap"))
|
||||
{
|
||||
Q_strncpyz(dl->cubemapname, x, sizeof(dl->cubemapname));
|
||||
if (*dl->cubemapname)
|
||||
dl->cubetexture = R_LoadReplacementTexture(dl->cubemapname, "", IF_CUBEMAP, NULL, 0, 0, TF_INVALID);
|
||||
else
|
||||
dl->cubetexture = r_nulltex;
|
||||
}
|
||||
else if (!strcmp(cmd, "shadows"))
|
||||
dl->flags = (dl->flags&~LFLAG_NOSHADOWS) | ((*x=='y'||*x=='Y'||*x=='t'||atoi(x))?0:LFLAG_NOSHADOWS);
|
||||
else if (!strcmp(cmd, "nostencil"))
|
||||
dl->flags = (dl->flags&~LFLAG_SHADOWMAP) | ((*x=='y'||*x=='Y'||*x=='t'||atoi(x))?0:LFLAG_SHADOWMAP);
|
||||
else if (!strcmp(cmd, "crepuscular"))
|
||||
dl->flags = (dl->flags&~LFLAG_CREPUSCULAR) | ((*x=='y'||*x=='Y'||*x=='t'||atoi(x))?LFLAG_CREPUSCULAR:0);
|
||||
else if (!strcmp(cmd, "ortho"))
|
||||
dl->flags = (dl->flags&~LFLAG_ORTHO) | ((*x=='y'||*x=='Y'||*x=='t'||atoi(x))?LFLAG_ORTHO:0);
|
||||
else if (!strcmp(cmd, "corona"))
|
||||
dl->corona = atof(x);
|
||||
else if (!strcmp(cmd, "coronasize"))
|
||||
dl->coronascale = atof(x);
|
||||
else if (!strcmp(cmd, "ambient"))
|
||||
dl->lightcolourscales[0] = atof(x);
|
||||
else if (!strcmp(cmd, "diffuse"))
|
||||
dl->lightcolourscales[1] = atof(x);
|
||||
else if (!strcmp(cmd, "specular"))
|
||||
dl->lightcolourscales[2] = atof(x);
|
||||
else if (!strcmp(cmd, "normalmode"))
|
||||
dl->flags = (dl->flags&~LFLAG_NORMALMODE) | ((*x=='y'||*x=='Y'||*x=='t'||atoi(x))?LFLAG_NORMALMODE:0);
|
||||
else if (!strcmp(cmd, "realtimemode"))
|
||||
dl->flags = (dl->flags&~LFLAG_REALTIMEMODE) | ((*x=='y'||*x=='Y'||*x=='t'||atoi(x))?LFLAG_REALTIMEMODE:0);
|
||||
else
|
||||
return -2;
|
||||
dl->rebuildcache = true; //mneh, lets just flag it for everything.
|
||||
return 1;
|
||||
}
|
||||
|
||||
void R_EditLights_DrawInfo(void)
|
||||
{
|
||||
float fontscale[2] = {8,8};
|
||||
float x = vid.width - 320;
|
||||
float y = 0;
|
||||
const char *s;
|
||||
if (!r_editlights.ival)
|
||||
return;
|
||||
|
||||
if (r_editlights_selected >= RTL_FIRST && r_editlights_selected < rtlights_max)
|
||||
{
|
||||
dlight_t *dl = &cl_dlights[r_editlights_selected];
|
||||
s = va( " Origin : %.0f %.0f %.0f\n"
|
||||
" Angles : %.0f %.0f %.0f\n"
|
||||
" Colour : %.2f %.2f %.2f\n"
|
||||
" Radius : %.0f\n"
|
||||
" Corona : %.0f\n"
|
||||
" Style : %i\n"
|
||||
"Style String : %s\n"
|
||||
" Shadows : %s\n"
|
||||
" Cubemap : \"%s\"\n"
|
||||
" CoronaSize : %.2f\n"
|
||||
" Ambient : %.2f\n"
|
||||
" Diffuse : %.2f\n"
|
||||
" Specular : %.2f\n"
|
||||
" NormalMode : %s\n"
|
||||
"RealTimeMode : %s\n"
|
||||
" Spin : %.0f %.0f %.0f\n"
|
||||
" Cone : %.0f\n"
|
||||
//"NoStencil : %s\n"
|
||||
//"Crepuscular : %s\n"
|
||||
//"Ortho : %s\n"
|
||||
,dl->origin[0],dl->origin[1],dl->origin[2]
|
||||
,dl->angles[0],dl->angles[1],dl->angles[2]
|
||||
,dl->color[0],dl->color[1],dl->color[2]
|
||||
,dl->radius, dl->corona, dl->style-1, dl->customstyle?dl->customstyle:"---"
|
||||
,((dl->flags&LFLAG_NOSHADOWS)?"no":"yes"), dl->cubemapname, dl->coronascale
|
||||
,dl->lightcolourscales[0], dl->lightcolourscales[1], dl->lightcolourscales[2]
|
||||
,((dl->flags&LFLAG_NORMALMODE)?"yes":"no"), ((dl->flags&LFLAG_REALTIMEMODE)?"yes":"no")
|
||||
,dl->rotation[0],dl->rotation[1],dl->rotation[2], dl->fov
|
||||
//,((dl->flags&LFLAG_SHADOWMAP)?"no":"yes"),((dl->flags&LFLAG_CREPUSCULAR)?"yes":"no"),((dl->flags&LFLAG_ORTHO)?"yes":"no")
|
||||
);
|
||||
}
|
||||
else
|
||||
s = "No light selected";
|
||||
R2D_ImageColours(0,0,0,.35);
|
||||
R2D_FillBlock(x-4, y, 320+4, 16*8+4);
|
||||
R2D_ImageColours(1,1,1,1);
|
||||
R_DrawTextField(x, y, 320, 16*8, s, CON_WHITEMASK, CPRINT_LALIGN|CPRINT_TALIGN|CPRINT_NOWRAP, font_default, fontscale);
|
||||
}
|
||||
void R_EditLights_DrawLights(void)
|
||||
{
|
||||
const float SPRITE_SIZE = 8;
|
||||
int i;
|
||||
dlight_t *l;
|
||||
enum
|
||||
{
|
||||
// ELS_CURSOR,
|
||||
ELS_SELECTED,
|
||||
ELS_LIGHT,
|
||||
ELS_NOSHADOW,
|
||||
ELS_MAX
|
||||
};
|
||||
char *lightshaderinfo[] =
|
||||
{
|
||||
/* "gfx/editlights/cursor",
|
||||
".59..95."
|
||||
"59....95"
|
||||
"9.9..9.9"
|
||||
"...99..."
|
||||
"...99..."
|
||||
"9.9..9.9"
|
||||
"59....95"
|
||||
".59..95.",
|
||||
*/
|
||||
"gfx/editlights/selected",
|
||||
"999..999"
|
||||
"99....99"
|
||||
"9......9"
|
||||
"........"
|
||||
"........"
|
||||
"9......9"
|
||||
"99....99"
|
||||
"999..999",
|
||||
|
||||
"gfx/editlights/light",
|
||||
"..1221.."
|
||||
".245542."
|
||||
"14677641"
|
||||
"25799752"
|
||||
"25799752"
|
||||
"14677641"
|
||||
".245542."
|
||||
"..1221..",
|
||||
|
||||
"gfx/editlights/noshadow",
|
||||
"..1221.."
|
||||
".245542."
|
||||
"14644641"
|
||||
"274..472" //mmm, donuts.
|
||||
"274..472"
|
||||
"14644641"
|
||||
".247742."
|
||||
"..1221..",
|
||||
};
|
||||
shader_t *shaders[ELS_MAX], *s;
|
||||
unsigned int asciipalette[256];
|
||||
asciipalette['.'] = 0;
|
||||
for (i = 0; i < 10; i++)
|
||||
asciipalette['0'+i] = 0xff000000 | ((int)(255/9.0*i)*0x010101);
|
||||
|
||||
if (!r_editlights.ival)
|
||||
return;
|
||||
|
||||
for (i = 0; i < ELS_MAX; i++)
|
||||
{
|
||||
shaders[i] = R_RegisterShader(lightshaderinfo[i*2+0], SUF_NONE, va(
|
||||
"{\n"
|
||||
"program defaultadditivesprite\n"
|
||||
"{\n"
|
||||
"map $diffuse\n"
|
||||
"blendfunc gl_one gl_one\n"
|
||||
"rgbgen vertex\n"
|
||||
"alphagen vertex\n"
|
||||
"%s"
|
||||
"}\n"
|
||||
"}\n"
|
||||
,(i==ELS_SELECTED)?"nodepth\n":"")
|
||||
);
|
||||
if (!shaders[i]->defaulttextures->base)
|
||||
shaders[i]->defaulttextures->base = Image_GetTexture(shaders[i]->name, NULL, IF_LINEAR|IF_NOMIPMAP|IF_NOPICMIP|IF_CLAMP, lightshaderinfo[i*2+1], asciipalette, 8, 8, TF_8PAL32);
|
||||
}
|
||||
|
||||
if (!r_editlights_locked)
|
||||
{
|
||||
vec3_t targ, norm;
|
||||
int ent;
|
||||
int best = -1;
|
||||
float bestscore = 0, score;
|
||||
|
||||
VectorMA(r_refdef.vieworg, r_editlights_cursordistance.value, vpn, targ); //try to aim about 1024qu infront of the camera
|
||||
CL_TraceLine(r_refdef.vieworg, targ, r_editlights_cursor, norm, &ent); //figure out where the cursor ends up
|
||||
VectorMA(r_editlights_cursor, r_editlights_cursorpushoff.value, norm, r_editlights_cursor); //push off from the surface by 4qu.
|
||||
VectorMA(r_editlights_cursor, -r_editlights_cursorpushback.value, vpn, r_editlights_cursor);//move it back towards the camera, for no apparent reason
|
||||
if (r_editlights_cursorgrid.value)
|
||||
{ //snap to a grid, if set
|
||||
for (i =0; i < 3; i++)
|
||||
r_editlights_cursor[i] = floor(r_editlights_cursor[i] / r_editlights_cursorgrid.value + 0.5) * r_editlights_cursorgrid.value;
|
||||
}
|
||||
|
||||
// CLQ1_AddSpriteQuad(shaders[ELS_CURSOR], r_editlights_cursor, SPRITE_SIZE);
|
||||
|
||||
for (i=RTL_FIRST; i<rtlights_max; i++)
|
||||
{
|
||||
l = &cl_dlights[i];
|
||||
if (!l->radius) //dead light is dead.
|
||||
continue;
|
||||
|
||||
VectorSubtract(l->origin, r_refdef.vieworg, targ);
|
||||
score = DotProduct(vpn, targ) / sqrt(DotProduct(targ,targ));
|
||||
if (score >= .95) //there's a threshhold required for a light to be selectable.
|
||||
{
|
||||
//trace from the light to the view (so startsolid doesn't cause so many problems)
|
||||
if (score > bestscore && CL_TraceLine(l->origin, r_refdef.vieworg, r_editlights_cursor, norm, &ent) == 1.0)
|
||||
{
|
||||
bestscore = score;
|
||||
best = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
r_editlights_selected = best;
|
||||
}
|
||||
|
||||
for (i=RTL_FIRST; i<rtlights_max; i++)
|
||||
{
|
||||
l = &cl_dlights[i];
|
||||
if (!l->radius) //dead light is dead.
|
||||
continue;
|
||||
|
||||
//we should probably show spotlights with a special icon or something
|
||||
//dp has alternate icons for cubemaps.
|
||||
if (l->flags & LFLAG_NOSHADOWS)
|
||||
s = shaders[ELS_NOSHADOW];
|
||||
else
|
||||
s = shaders[ELS_LIGHT];
|
||||
CLQ1_AddSpriteQuad(s, l->origin, SPRITE_SIZE);
|
||||
}
|
||||
|
||||
if (r_editlights_selected >= RTL_FIRST && r_editlights_selected < rtlights_max)
|
||||
{
|
||||
l = &cl_dlights[r_editlights_selected];
|
||||
CLQ1_AddSpriteQuad(shaders[ELS_SELECTED], l->origin, SPRITE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
static void R_EditLights_Edit_f(void)
|
||||
{
|
||||
int i = r_editlights_selected;
|
||||
const char *cmd = Cmd_Argv(1);
|
||||
const char *x = Cmd_Argv(2);
|
||||
const char *y = Cmd_Argv(3);
|
||||
const char *z = Cmd_Argv(4);
|
||||
int argc = Cmd_Argc()-2;
|
||||
dlight_t *dl;
|
||||
if (!r_editlights.ival)
|
||||
{
|
||||
Con_Printf("Toggle r_editlights first\n");
|
||||
return;
|
||||
}
|
||||
if (i < RTL_FIRST || i >= rtlights_max)
|
||||
{
|
||||
Con_Printf("No light selected\n");
|
||||
return;
|
||||
}
|
||||
dl = &cl_dlights[i];
|
||||
if (!*cmd)
|
||||
{
|
||||
Con_Print("Selected light's properties:\n");
|
||||
Con_Printf("Origin : ^[%f %f %f\\type\\r_editlights_edit origin %g %g %g^]\n", dl->origin[0],dl->origin[1],dl->origin[2], dl->origin[0],dl->origin[1],dl->origin[2]);
|
||||
Con_Printf("Angles : ^[%f %f %f\\type\\r_editlights_edit angles %g %g %g^]\n", dl->angles[0],dl->angles[1],dl->angles[2], dl->angles[0],dl->angles[1],dl->angles[2]);
|
||||
Con_Printf("Colour : ^[%f %f %f\\type\\r_editlights_edit avel %g %g %g^]\n", dl->color[0],dl->color[1],dl->color[2], dl->color[0],dl->color[1],dl->color[2]);
|
||||
Con_Printf("Radius : ^[%f\\type\\r_editlights_edit radius %g^]\n", dl->radius, dl->radius);
|
||||
Con_Printf("Corona : ^[%f\\type\\r_editlights_edit corona %g^]\n", dl->corona, dl->corona);
|
||||
Con_Printf("Style : ^[%i\\type\\r_editlights_edit style %i^]\n", dl->style-1, dl->style-1);
|
||||
Con_Printf("Style String : ^[%s\\type\\r_editlights_edit stylestring %s^]\n", dl->customstyle?dl->customstyle:"---", dl->customstyle?dl->customstyle:"");
|
||||
Con_Printf("Shadows : ^[%s\\type\\r_editlights_edit shadows %s^]\n", ((dl->flags&LFLAG_NOSHADOWS)?"no":"yes"), ((dl->flags&LFLAG_NOSHADOWS)?"no":"yes"));
|
||||
Con_Printf("Cubemap : ^[\"%s\"\\type\\r_editlights_edit cubemap \"%s\"^]\n", dl->cubemapname, dl->cubemapname);
|
||||
Con_Printf("CoronaSize : ^[%f\\type\\r_editlights_edit coronasize %g^]\n", dl->coronascale, dl->coronascale);
|
||||
Con_Printf("Ambient : ^[%f\\type\\r_editlights_edit ambient %g^]\n", dl->lightcolourscales[0], dl->lightcolourscales[0]);
|
||||
Con_Printf("Diffuse : ^[%f\\type\\r_editlights_edit diffuse %g^]\n", dl->lightcolourscales[1], dl->lightcolourscales[1]);
|
||||
Con_Printf("Specular : ^[%f\\type\\r_editlights_edit specular %g^]\n", dl->lightcolourscales[2], dl->lightcolourscales[2]);
|
||||
Con_Printf("NormalMode : ^[%s\\type\\r_editlights_edit normalmode %s^]\n", ((dl->flags&LFLAG_NORMALMODE)?"yes":"no"), ((dl->flags&LFLAG_NORMALMODE)?"yes":"no"));
|
||||
Con_Printf("RealTimeMode : ^[%s\\type\\r_editlights_edit realtimemode %s^]\n", ((dl->flags&LFLAG_REALTIMEMODE)?"yes":"no"), ((dl->flags&LFLAG_REALTIMEMODE)?"yes":"no"));
|
||||
Con_Printf("Spin : ^[%f %f %f\\type\\r_editlights_edit avel %g %g %g^]\n", dl->rotation[0],dl->rotation[1],dl->rotation[2], dl->origin[0],dl->origin[1],dl->origin[2]);
|
||||
Con_Printf("Cone : ^[%f\\type\\r_editlights_edit outercone %g^]\n", dl->fov, dl->fov);
|
||||
// Con_Printf("NoStencil : ^[%s\\type\\r_editlights_edit nostencil %s^]\n", ((dl->flags&LFLAG_SHADOWMAP)?"no":"yes"), ((dl->flags&LFLAG_SHADOWMAP)?"no":"yes"));
|
||||
// Con_Printf("Crepuscular : ^[%s\\type\\r_editlights_edit crepuscular %s^]\n", ((dl->flags&LFLAG_CREPUSCULAR)?"yes":"no"), ((dl->flags&LFLAG_CREPUSCULAR)?"yes":"no"));
|
||||
// Con_Printf("Ortho : ^[%s\\type\\r_editlights_edit ortho %s^]\n", ((dl->flags&LFLAG_ORTHO)?"yes":"no"), ((dl->flags&LFLAG_ORTHO)?"yes":"no"));
|
||||
return;
|
||||
}
|
||||
switch(R_EditLight(dl, cmd, argc, x,y,z))
|
||||
{
|
||||
case -1:
|
||||
Con_Printf("Not enough args for %s\n", cmd);
|
||||
return;
|
||||
case -2:
|
||||
Con_Printf("Argument not known: %s\n", cmd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
static void R_EditLights_Remove_f(void)
|
||||
{
|
||||
int i = r_editlights_selected;
|
||||
dlight_t *dl;
|
||||
if (!r_editlights.ival)
|
||||
{
|
||||
Con_Printf("Toggle r_editlights first\n");
|
||||
return;
|
||||
}
|
||||
if (i < RTL_FIRST || i >= rtlights_max)
|
||||
{
|
||||
Con_Printf("No light selected\n");
|
||||
return;
|
||||
}
|
||||
dl = &cl_dlights[i];
|
||||
dl->radius = 0;
|
||||
r_editlights_selected = -1;
|
||||
}
|
||||
static void R_EditLights_EditAll_f(void)
|
||||
{
|
||||
int i = 0;
|
||||
const char *cmd = Cmd_Argv(1);
|
||||
const char *x = Cmd_Argv(2);
|
||||
const char *y = Cmd_Argv(3);
|
||||
const char *z = Cmd_Argv(4);
|
||||
int argc = Cmd_Argc()-2;
|
||||
dlight_t *dl;
|
||||
if (!r_editlights.ival)
|
||||
{
|
||||
Con_Printf("No light selected\n");
|
||||
return;
|
||||
}
|
||||
for (i = RTL_FIRST; i < rtlights_max; i++)
|
||||
{
|
||||
dl = &cl_dlights[i];
|
||||
if (dl->radius <= 0)
|
||||
continue; //don't edit dead lights back to life
|
||||
switch(R_EditLight(dl, cmd, argc, x,y,z))
|
||||
{
|
||||
case -1:
|
||||
Con_Printf("Not enough args for %s\n", cmd);
|
||||
return;
|
||||
case -2:
|
||||
Con_Printf("Argument not known: %s\n", cmd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
static void R_EditLights_Spawn_f(void)
|
||||
{
|
||||
dlight_t *dl;
|
||||
if (!r_editlights.ival)
|
||||
{
|
||||
Con_Printf("Toggle r_editlights first\n");
|
||||
return;
|
||||
}
|
||||
dl = CL_AllocSlight();
|
||||
r_editlights_selected = dl - cl_dlights;
|
||||
|
||||
VectorCopy(r_editlights_cursor, dl->origin);
|
||||
dl->radius = 200;
|
||||
|
||||
dl->style = 1; //0... gah. match DP's results.
|
||||
dl->lightcolourscales[0] = 0;
|
||||
dl->lightcolourscales[1] = 1;
|
||||
dl->lightcolourscales[2] = 1;
|
||||
}
|
||||
static void R_EditLights_Clone_f(void)
|
||||
{
|
||||
int i = r_editlights_selected;
|
||||
dlight_t *dl;
|
||||
dlight_t *src;
|
||||
if (!r_editlights.ival)
|
||||
{
|
||||
Con_Printf("Toggle r_editlights first\n");
|
||||
return;
|
||||
}
|
||||
if (i < RTL_FIRST || i >= rtlights_max)
|
||||
{
|
||||
Con_Printf("No light selected\n");
|
||||
return;
|
||||
}
|
||||
src = &cl_dlights[i];
|
||||
dl = CL_AllocSlight();
|
||||
r_editlights_selected = dl - cl_dlights;
|
||||
CL_CloneDlight(dl, src);
|
||||
|
||||
VectorCopy(r_editlights_cursor, dl->origin);
|
||||
}
|
||||
static void R_EditLights_ToggleShadow_f(void)
|
||||
{
|
||||
int i = r_editlights_selected;
|
||||
dlight_t *dl;
|
||||
if (!r_editlights.ival)
|
||||
{
|
||||
Con_Printf("Toggle r_editlights first\n");
|
||||
return;
|
||||
}
|
||||
if (i < RTL_FIRST || i >= rtlights_max)
|
||||
{
|
||||
Con_Printf("No light selected\n");
|
||||
return;
|
||||
}
|
||||
dl = &cl_dlights[i];
|
||||
dl->flags ^= LFLAG_NOSHADOWS;
|
||||
}
|
||||
static void R_EditLights_ToggleCorona_f(void)
|
||||
{
|
||||
int i = r_editlights_selected;
|
||||
dlight_t *dl;
|
||||
if (!r_editlights.ival)
|
||||
{
|
||||
Con_Printf("Toggle r_editlights first\n");
|
||||
return;
|
||||
}
|
||||
if (i < RTL_FIRST || i >= rtlights_max)
|
||||
{
|
||||
Con_Printf("No light selected\n");
|
||||
return;
|
||||
}
|
||||
dl = &cl_dlights[i];
|
||||
dl->corona = !dl->corona;
|
||||
}
|
||||
static void R_EditLights_CopyInfo_f(void)
|
||||
{
|
||||
int i = r_editlights_selected;
|
||||
dlight_t *dl;
|
||||
if (!r_editlights.ival)
|
||||
{
|
||||
Con_Printf("Toggle r_editlights first\n");
|
||||
return;
|
||||
}
|
||||
if (i < RTL_FIRST || i >= rtlights_max)
|
||||
return;
|
||||
dl = &cl_dlights[i];
|
||||
CL_CloneDlight(&r_editlights_copybuffer, dl);
|
||||
}
|
||||
static void R_EditLights_PasteInfo_f(void)
|
||||
{
|
||||
int i = r_editlights_selected;
|
||||
dlight_t *dl;
|
||||
vec3_t org;
|
||||
if (!r_editlights.ival)
|
||||
{
|
||||
Con_Printf("Toggle r_editlights first\n");
|
||||
return;
|
||||
}
|
||||
if (i < RTL_FIRST || i >= rtlights_max)
|
||||
{
|
||||
Con_Printf("No light selected\n");
|
||||
return;
|
||||
}
|
||||
dl = &cl_dlights[i];
|
||||
VectorCopy(dl->origin, org);
|
||||
CL_CloneDlight(dl, &r_editlights_copybuffer);
|
||||
VectorCopy(org, dl->origin); //undo the origin's copy.
|
||||
|
||||
//just in case its from a different map...
|
||||
if (*dl->cubemapname)
|
||||
dl->cubetexture = R_LoadReplacementTexture(dl->cubemapname, "", IF_CUBEMAP, NULL, 0, 0, TF_INVALID);
|
||||
else
|
||||
dl->cubetexture = r_nulltex;
|
||||
}
|
||||
|
||||
static void R_EditLights_Lock_f(void)
|
||||
{
|
||||
if (!r_editlights.ival)
|
||||
{
|
||||
Con_Printf("Toggle r_editlights first\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((r_editlights_selected < RTL_FIRST || r_editlights_selected >= rtlights_max) && !r_editlights_locked)
|
||||
{
|
||||
Con_Printf("No light selected\n");
|
||||
return;
|
||||
}
|
||||
r_editlights_locked = !r_editlights_locked;
|
||||
}
|
||||
|
||||
static char macro_buf[256] = "";
|
||||
static char *r_editlights_current_origin(void)
|
||||
{
|
||||
int i = r_editlights_selected;
|
||||
dlight_t *dl;
|
||||
if (i < RTL_FIRST || i >= rtlights_max)
|
||||
return "";
|
||||
dl = &cl_dlights[i];
|
||||
|
||||
Q_snprintfz (macro_buf, sizeof(macro_buf), "%g %g %g", dl->origin[0], dl->origin[1], dl->origin[2]);
|
||||
return macro_buf;
|
||||
}
|
||||
static char *r_editlights_current_angles(void)
|
||||
{
|
||||
int i = r_editlights_selected;
|
||||
dlight_t *dl;
|
||||
if (i < RTL_FIRST || i >= rtlights_max)
|
||||
return "";
|
||||
dl = &cl_dlights[i];
|
||||
|
||||
Q_snprintfz (macro_buf, sizeof(macro_buf), "%g %g %g", dl->angles[0], dl->angles[1], dl->angles[2]);
|
||||
return macro_buf;
|
||||
}
|
||||
static char *r_editlights_current_color(void)
|
||||
{
|
||||
int i = r_editlights_selected;
|
||||
dlight_t *dl;
|
||||
if (i < RTL_FIRST || i >= rtlights_max)
|
||||
return "";
|
||||
dl = &cl_dlights[i];
|
||||
|
||||
Q_snprintfz (macro_buf, sizeof(macro_buf), "%g %g %g", dl->color[0], dl->color[1], dl->color[2]);
|
||||
return macro_buf;
|
||||
}
|
||||
static char *r_editlights_current_radius(void)
|
||||
{
|
||||
int i = r_editlights_selected;
|
||||
dlight_t *dl;
|
||||
if (i < RTL_FIRST || i >= rtlights_max)
|
||||
return "";
|
||||
dl = &cl_dlights[i];
|
||||
|
||||
Q_snprintfz (macro_buf, sizeof(macro_buf), "%g", dl->radius);
|
||||
return macro_buf;
|
||||
}
|
||||
static char *r_editlights_current_corona(void)
|
||||
{
|
||||
int i = r_editlights_selected;
|
||||
dlight_t *dl;
|
||||
if (i < RTL_FIRST || i >= rtlights_max)
|
||||
return "";
|
||||
dl = &cl_dlights[i];
|
||||
|
||||
Q_snprintfz (macro_buf, sizeof(macro_buf), "%g", dl->corona);
|
||||
return macro_buf;
|
||||
}
|
||||
static char *r_editlights_current_coronasize(void)
|
||||
{
|
||||
int i = r_editlights_selected;
|
||||
dlight_t *dl;
|
||||
if (i < RTL_FIRST || i >= rtlights_max)
|
||||
return "";
|
||||
dl = &cl_dlights[i];
|
||||
|
||||
Q_snprintfz (macro_buf, sizeof(macro_buf), "%g", dl->coronascale);
|
||||
return macro_buf;
|
||||
}
|
||||
static char *r_editlights_current_style(void)
|
||||
{
|
||||
int i = r_editlights_selected;
|
||||
dlight_t *dl;
|
||||
if (i < RTL_FIRST || i >= rtlights_max)
|
||||
return "";
|
||||
dl = &cl_dlights[i];
|
||||
|
||||
Q_snprintfz (macro_buf, sizeof(macro_buf), "%i", dl->style-1);
|
||||
return macro_buf;
|
||||
}
|
||||
static char *r_editlights_current_shadows(void)
|
||||
{
|
||||
int i = r_editlights_selected;
|
||||
dlight_t *dl;
|
||||
if (i < RTL_FIRST || i >= rtlights_max)
|
||||
return "";
|
||||
dl = &cl_dlights[i];
|
||||
|
||||
if (dl->flags & LFLAG_NOSHADOWS)
|
||||
return "0";
|
||||
return "1";
|
||||
}
|
||||
static char *r_editlights_current_cubemap(void)
|
||||
{
|
||||
int i = r_editlights_selected;
|
||||
dlight_t *dl;
|
||||
if (i < RTL_FIRST || i >= rtlights_max)
|
||||
return "";
|
||||
dl = &cl_dlights[i];
|
||||
|
||||
Q_snprintfz (macro_buf, sizeof(macro_buf), "\"%s\"", dl->cubemapname);
|
||||
return macro_buf;
|
||||
}
|
||||
static char *r_editlights_current_ambient(void)
|
||||
{
|
||||
int i = r_editlights_selected;
|
||||
dlight_t *dl;
|
||||
if (i < RTL_FIRST || i >= rtlights_max)
|
||||
return "";
|
||||
dl = &cl_dlights[i];
|
||||
|
||||
Q_snprintfz (macro_buf, sizeof(macro_buf), "%g", dl->lightcolourscales[0]);
|
||||
return macro_buf;
|
||||
}
|
||||
static char *r_editlights_current_diffuse(void)
|
||||
{
|
||||
int i = r_editlights_selected;
|
||||
dlight_t *dl;
|
||||
if (i < RTL_FIRST || i >= rtlights_max)
|
||||
return "";
|
||||
dl = &cl_dlights[i];
|
||||
|
||||
Q_snprintfz (macro_buf, sizeof(macro_buf), "%g", dl->lightcolourscales[1]);
|
||||
return macro_buf;
|
||||
}
|
||||
static char *r_editlights_current_specular(void)
|
||||
{
|
||||
int i = r_editlights_selected;
|
||||
dlight_t *dl;
|
||||
if (i < RTL_FIRST || i >= rtlights_max)
|
||||
return "";
|
||||
dl = &cl_dlights[i];
|
||||
|
||||
Q_snprintfz (macro_buf, sizeof(macro_buf), "%g", dl->lightcolourscales[2]);
|
||||
return macro_buf;
|
||||
}
|
||||
static char *r_editlights_current_normalmode(void)
|
||||
{
|
||||
int i = r_editlights_selected;
|
||||
dlight_t *dl;
|
||||
if (i < RTL_FIRST || i >= rtlights_max)
|
||||
return "";
|
||||
dl = &cl_dlights[i];
|
||||
|
||||
if (dl->flags & LFLAG_NORMALMODE)
|
||||
return "1";
|
||||
return "0";
|
||||
}
|
||||
static char *r_editlights_current_realtimemode(void)
|
||||
{
|
||||
int i = r_editlights_selected;
|
||||
dlight_t *dl;
|
||||
if (i < RTL_FIRST || i >= rtlights_max)
|
||||
return "";
|
||||
dl = &cl_dlights[i];
|
||||
|
||||
if (dl->flags & LFLAG_REALTIMEMODE)
|
||||
return "1";
|
||||
return "0";
|
||||
}
|
||||
|
||||
void R_EditLights_RegisterCommands(void)
|
||||
{
|
||||
Cmd_AddCommandD ("r_editlights_reload", R_ReloadRTLights_f, "Reload static rtlights. Argument can be rtlights|statics|bsp|none to override the source.");
|
||||
Cmd_AddCommandD ("r_editlights_save", R_SaveRTLights_f, "Saves rtlights to maps/FOO.rtlights");
|
||||
Cvar_Register (&r_editlights_import_radius, "Realtime Light editing/importing");
|
||||
Cvar_Register (&r_editlights_import_ambient, "Realtime Light editing/importing");
|
||||
Cvar_Register (&r_editlights_import_diffuse, "Realtime Light editing/importing");
|
||||
Cvar_Register (&r_editlights_import_specular, "Realtime Light editing/importing");
|
||||
|
||||
Cvar_Register (&r_editlights, "Realtime Light editing/importing");
|
||||
Cvar_Register (&r_editlights_cursordistance, "Realtime Light editing/importing");
|
||||
Cvar_Register (&r_editlights_cursorpushoff, "Realtime Light editing/importing");
|
||||
Cvar_Register (&r_editlights_cursorpushback, "Realtime Light editing/importing");
|
||||
Cvar_Register (&r_editlights_cursorgrid, "Realtime Light editing/importing");
|
||||
|
||||
//the rest is optional stuff that should normally be handled via csqc instead, but hurrah for dp compat...
|
||||
Cmd_AddCommandD("r_editlights_spawn", R_EditLights_Spawn_f, "Spawn a new light with default properties");
|
||||
Cmd_AddCommandD("r_editlights_clone", R_EditLights_Clone_f, "Duplicate the current light (with a new origin)");
|
||||
Cmd_AddCommandD("r_editlights_remove", R_EditLights_Remove_f, "Removes the current light.");
|
||||
Cmd_AddCommandD("r_editlights_edit", R_EditLights_Edit_f, "Changes named properties on the current light.");
|
||||
Cmd_AddCommandD("r_editlights_editall", R_EditLights_EditAll_f, "Like r_editlights_edit, but affects all lights instead of just the selected one.");
|
||||
Cmd_AddCommandD("r_editlights_toggleshadow", R_EditLights_ToggleShadow_f, "Toggles the shadow flag on the current light.");
|
||||
Cmd_AddCommandD("r_editlights_togglecorona", R_EditLights_ToggleCorona_f, "Toggles the current light's corona field.");
|
||||
Cmd_AddCommandD("r_editlights_copyinfo", R_EditLights_CopyInfo_f, "store a copy of all properties (except origin) of the selected light");
|
||||
Cmd_AddCommandD("r_editlights_pasteinfo", R_EditLights_PasteInfo_f, "apply the stored properties onto the selected light (making it exactly identical except for origin)");
|
||||
Cmd_AddCommandD("r_editlights_lock", R_EditLights_Lock_f, "Blocks changing the current light according the crosshair.");
|
||||
|
||||
//DP has these as cvars. mneh.
|
||||
Cmd_AddMacroD("r_editlights_current_origin", r_editlights_current_origin, false, "origin of selected light");
|
||||
Cmd_AddMacroD("r_editlights_current_angles", r_editlights_current_angles, false, "angles of selected light");
|
||||
Cmd_AddMacroD("r_editlights_current_color", r_editlights_current_color, false, "color of selected light");
|
||||
Cmd_AddMacroD("r_editlights_current_radius", r_editlights_current_radius, false, "radius of selected light");
|
||||
Cmd_AddMacroD("r_editlights_current_corona", r_editlights_current_corona, false, "corona intensity of selected light");
|
||||
Cmd_AddMacroD("r_editlights_current_coronasize",r_editlights_current_coronasize,false, "corona size of selected light");
|
||||
Cmd_AddMacroD("r_editlights_current_style", r_editlights_current_style, false, "style of selected light");
|
||||
Cmd_AddMacroD("r_editlights_current_shadows", r_editlights_current_shadows, false, "shadows flag of selected light");
|
||||
Cmd_AddMacroD("r_editlights_current_cubemap", r_editlights_current_cubemap, false, "cubemap of selected light");
|
||||
Cmd_AddMacroD("r_editlights_current_ambient", r_editlights_current_ambient, false, "ambient intensity of selected light");
|
||||
Cmd_AddMacroD("r_editlights_current_diffuse", r_editlights_current_diffuse, false, "diffuse intensity of selected light");
|
||||
Cmd_AddMacroD("r_editlights_current_specular", r_editlights_current_specular, false, "specular intensity of selected light");
|
||||
Cmd_AddMacroD("r_editlights_current_normalmode",r_editlights_current_normalmode,false, "normalmode flag of selected light");
|
||||
Cmd_AddMacroD("r_editlights_current_realtimemode", r_editlights_current_realtimemode, false, "realtimemode flag of selected light");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1947,7 +1947,7 @@ void GLR_RenderView (void)
|
|||
if (dofbo)
|
||||
forcedfb = false;
|
||||
else if (renderscale != 1)
|
||||
forcedfb = true;
|
||||
forcedfb = gl_config.ext_framebuffer_objects && sh_config.texture_non_power_of_two_pic;
|
||||
|
||||
BE_Scissor(NULL);
|
||||
if (dofbo)
|
||||
|
@ -1956,6 +1956,13 @@ void GLR_RenderView (void)
|
|||
texid_t col[R_MAX_RENDERTARGETS], depth = r_nulltex;
|
||||
unsigned int cw=0, ch=0, dw=0, dh=0;
|
||||
int mrt;
|
||||
|
||||
if (!gl_config.ext_framebuffer_objects && sh_config.texture_non_power_of_two_pic)
|
||||
{
|
||||
Con_DPrintf(CON_WARNING"Render targets are not supported on this gpu.\n");
|
||||
return; //not supported on this gpu. you'll just get black textures or something.
|
||||
}
|
||||
|
||||
//3d views generally ignore source colour+depth.
|
||||
//FIXME: support depth with no colour
|
||||
for (mrt = 0; mrt < R_MAX_RENDERTARGETS; mrt++)
|
||||
|
|
|
@ -195,7 +195,7 @@ qboolean GLSCR_UpdateScreen (void)
|
|||
if (uimenu != 1)
|
||||
{
|
||||
if (r_worldentity.model && cls.state == ca_active)
|
||||
V_RenderView ();
|
||||
V_RenderView (nohud);
|
||||
else
|
||||
{
|
||||
noworld = true;
|
||||
|
|
|
@ -7298,9 +7298,7 @@ char *Shader_GetShaderBody(shader_t *s, char *fname, size_t fnamesize)
|
|||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( parsename ) {
|
||||
|
||||
if (!strchr(parsename, ':'))
|
||||
{
|
||||
//if the named shader is a .shader file then just directly load it.
|
||||
|
|
|
@ -62,10 +62,6 @@ cvar_t r_shadow_realtime_dlight_shadows = CVARFD ("r_shadow_realtime_dlight_sha
|
|||
cvar_t r_shadow_realtime_dlight_ambient = CVAR ("r_shadow_realtime_dlight_ambient", "0");
|
||||
cvar_t r_shadow_realtime_dlight_diffuse = CVAR ("r_shadow_realtime_dlight_diffuse", "1");
|
||||
cvar_t r_shadow_realtime_dlight_specular = CVAR ("r_shadow_realtime_dlight_specular", "4"); //excessive, but noticable. its called stylized, okay? shiesh, some people
|
||||
cvar_t r_editlights_import_radius = CVAR ("r_editlights_import_radius", "1");
|
||||
cvar_t r_editlights_import_ambient = CVAR ("r_editlights_import_ambient", "0");
|
||||
cvar_t r_editlights_import_diffuse = CVAR ("r_editlights_import_diffuse", "1");
|
||||
cvar_t r_editlights_import_specular = CVAR ("r_editlights_import_specular", "1"); //excessive, but noticable. its called stylized, okay? shiesh, some people
|
||||
cvar_t r_shadow_playershadows = CVARD ("r_shadow_playershadows", "1", "Controls the presence of shadows on the local player.");
|
||||
cvar_t r_shadow_shadowmapping = CVARD ("r_shadow_shadowmapping", "1", "Enables soft shadows instead of stencil shadows.");
|
||||
cvar_t r_shadow_shadowmapping_precision = CVARD ("r_shadow_shadowmapping_precision", "1", "Scales the shadowmap detail level up or down.");
|
||||
|
@ -3571,7 +3567,7 @@ void Sh_DrawCrepuscularLight(dlight_t *dl, float *colours)
|
|||
void Sh_PurgeShadowMeshes(void)
|
||||
{
|
||||
dlight_t *dl;
|
||||
int i;
|
||||
size_t i;
|
||||
for (dl = cl_dlights, i=0; i<cl_maxdlights; i++, dl++)
|
||||
{
|
||||
if (dl->worldshadowmesh)
|
||||
|
@ -3604,6 +3600,12 @@ void Sh_PreGenerateLights(void)
|
|||
qboolean okay = false;
|
||||
if (!okay)
|
||||
okay |= R_LoadRTLights();
|
||||
if (!okay)
|
||||
{
|
||||
for (i = 0; i < cl.num_statics; i++)
|
||||
R_StaticEntityToRTLight(i);
|
||||
okay |= rtlights_max != RTL_FIRST;
|
||||
}
|
||||
if (!okay)
|
||||
okay |= R_ImportRTLights(Mod_GetEntitiesString(cl.worldmodel));
|
||||
if (!okay && r_shadow_realtime_world.ival && r_shadow_realtime_world_lightmaps.value != 1)
|
||||
|
@ -3867,6 +3869,54 @@ void Sh_DrawLights(qbyte *vis)
|
|||
colour[0] = dl->color[0];
|
||||
colour[1] = dl->color[1];
|
||||
colour[2] = dl->color[2];
|
||||
if (dl->customstyle)
|
||||
{
|
||||
const char *map = dl->customstyle;
|
||||
int maplen = strlen(map);
|
||||
|
||||
int idx, v1, v2, vd;
|
||||
float frac, strength;
|
||||
|
||||
if (!maplen)
|
||||
{
|
||||
strength = ('m'-'a')*22 * r_lightstylescale.value/255.0;
|
||||
}
|
||||
else if (map[0] == '=')
|
||||
{
|
||||
strength = atof(map+1)*r_lightstylescale.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
frac = (cl.time*r_lightstylespeed.value);
|
||||
if (*map == '?' && maplen>1)
|
||||
{
|
||||
map++;
|
||||
maplen--;
|
||||
frac += i*M_PI;
|
||||
}
|
||||
frac += i*M_PI;
|
||||
if (frac < 0)
|
||||
frac = 0;
|
||||
idx = (int)frac;
|
||||
frac -= idx; //this can require updates at 1000 times a second.. Depends on your framerate of course
|
||||
|
||||
v1 = idx % maplen;
|
||||
v1 = map[v1] - 'a';
|
||||
|
||||
v2 = (idx+1) % maplen;
|
||||
v2 = map[v2] - 'a';
|
||||
|
||||
vd = v1 - v2;
|
||||
if (/*!r_lightstylesmooth.ival ||*/ vd < -r_lightstylesmooth_limit.ival || vd > r_lightstylesmooth_limit.ival)
|
||||
strength = v1*(22/255.0)*r_lightstylescale.value;
|
||||
else
|
||||
strength = (v1*(1-frac) + v2*(frac))*(22/255.0)*r_lightstylescale.value;
|
||||
}
|
||||
strength *= d_lightstylevalue[0]/255.0f; //a lot of QW mods use lightstyle 0 for a global darkening fade-in thing, so be sure to respect that.
|
||||
colour[0] *= strength;
|
||||
colour[1] *= strength;
|
||||
colour[2] *= strength;
|
||||
}
|
||||
if (dl->style)
|
||||
{
|
||||
colour[0] *= cl_lightstyle[dl->style-1].colours[0] * d_lightstylevalue[dl->style-1]/255.0f;
|
||||
|
|
|
@ -3450,7 +3450,7 @@ static qboolean X11VID_Init (rendererstate_t *info, unsigned char *palette, int
|
|||
break;
|
||||
}
|
||||
#endif
|
||||
Con_Printf("Failed to create a vulkan context.\n");
|
||||
Con_Printf(CON_ERROR "Failed to create a vulkan context.\n");
|
||||
GLVID_Shutdown();
|
||||
return false;
|
||||
#endif
|
||||
|
|
|
@ -375,26 +375,6 @@ static void WL_BindRelativePointerManager(struct wl_registry *registry, uint32_t
|
|||
w.relative_pointer_manager = pwl_registry_bind(registry, id, &zwp_relative_pointer_manager_v1_interface, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
struct zwp_locked_pointer_v1;
|
||||
static void WL_locked_pointer_locked(void *data, struct zwp_locked_pointer_v1 *locked_pointer)
|
||||
{
|
||||
}
|
||||
static void WL_locked_pointer_unlocked(void *data, struct zwp_locked_pointer_v1 *locked_pointer)
|
||||
{
|
||||
}
|
||||
struct zwp_locked_pointer_v1_listener
|
||||
{
|
||||
void (*pointer_locked)(void *data, struct zwp_locked_pointer_v1 *locked_pointer);
|
||||
void (*pointer_unlocked)(void *data, struct zwp_locked_pointer_v1 *locked_pointer);
|
||||
};
|
||||
static const struct zwp_locked_pointer_v1_listener locked_pointer_listener =
|
||||
{
|
||||
WL_locked_pointer_locked,
|
||||
WL_locked_pointer_unlocked,
|
||||
};
|
||||
*/
|
||||
|
||||
static void WL_keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int fd, uint32_t size)
|
||||
{
|
||||
}
|
||||
|
@ -490,10 +470,49 @@ static const struct wl_seat_listener seat_listener =
|
|||
WL_seat_handle_capabilities
|
||||
};
|
||||
|
||||
|
||||
#if 0
|
||||
static void WL_BindDecoraionManager(struct wl_registry *registry, uint32_t id)
|
||||
{ /*oh hey, I wrote lots of code! pay me more! fuck that shit.*/
|
||||
|
||||
static const struct wl_interface *types[3];
|
||||
static const struct wl_message zxdg_decoration_manager_v1_requests[] = {
|
||||
{ "destroy", "", types + 0 },
|
||||
{ "get_toplevel_decoration", "no", types + 1 },
|
||||
};
|
||||
static const struct wl_interface zxdg_decoration_manager_v1_interface = {
|
||||
"zxdg_decoration_manager_v1", 1,
|
||||
2, zxdg_decoration_manager_v1_requests,
|
||||
0, NULL,
|
||||
};
|
||||
static const struct wl_message zxdg_toplevel_decoration_v1_requests[] = {
|
||||
{ "destroy", "", types + 0 },
|
||||
{ "set_mode", "u", types + 0 },
|
||||
{ "unset_mode", "", types + 0 },
|
||||
};
|
||||
static const struct wl_message zxdg_toplevel_decoration_v1_events[] = {
|
||||
{ "configure", "u", types + 0 },
|
||||
};
|
||||
static const struct wl_interface zxdg_toplevel_decoration_v1_interface = {
|
||||
"zxdg_toplevel_decoration_v1", 1,
|
||||
3, zxdg_toplevel_decoration_v1_requests,
|
||||
1, zxdg_toplevel_decoration_v1_events,
|
||||
};
|
||||
|
||||
//fix up types...
|
||||
types[1] = &zxdg_toplevel_decoration_v1_interface;
|
||||
types[2] = NULL;//&xdg_toplevel_interface;
|
||||
|
||||
// pzwp_relative_pointer_v1_interface = &zxdg_toplevel_decoration_v1_interface;
|
||||
w.decoration_manager = pwl_registry_bind(registry, id, &zxdg_decoration_manager_v1_interface, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void WL_handle_global(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version)
|
||||
{
|
||||
struct wdisplay_s *d = data;
|
||||
//Sys_Printf("Interface %s id %u\n", interface, id);
|
||||
Con_DLPrintf(2, "Wayland Interface %s id %u\n", interface, id);
|
||||
if (strcmp(interface, "wl_compositor") == 0)
|
||||
d->compositor = pwl_registry_bind(registry, id, pwl_compositor_interface, 1);
|
||||
else if (strcmp(interface, "wl_shell") == 0)
|
||||
|
@ -505,6 +524,8 @@ static void WL_handle_global(void *data, struct wl_registry *registry, uint32_t
|
|||
}
|
||||
else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0)
|
||||
WL_BindRelativePointerManager(registry, id);
|
||||
// else if (strcmp(interface, "zxdg_decoration_manager_v1") == 0)
|
||||
// WL_BindDecorationManager(registry, id);
|
||||
// else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0)
|
||||
// d->shell = pwl_registry_bind(registry, id, pwl_shell_interface, 1);
|
||||
/* else if (!strcmp(interface, "input_device"))
|
||||
|
@ -659,7 +680,10 @@ static qboolean WL_Init (rendererstate_t *info, unsigned char *palette)
|
|||
case QR_VULKAN:
|
||||
{
|
||||
const char *extnames[] = {VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, NULL};
|
||||
return VK_Init(info, extnames, WLVK_SetupSurface, NULL);
|
||||
if (VK_Init(info, extnames, WLVK_SetupSurface, NULL))
|
||||
return true;
|
||||
Con_Printf(CON_ERROR "Unable to initialise vulkan-on-wayland.\n");
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
|
|
@ -405,10 +405,8 @@ void R_InitFlashblends(void);
|
|||
void GLR_MarkQ2Lights (dlight_t *light, int bit, mnode_t *node);
|
||||
#endif
|
||||
void GLQ3_LightGrid(model_t *mod, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
|
||||
void R_ReloadRTLights_f(void);
|
||||
qboolean R_LoadRTLights(void);
|
||||
qboolean R_ImportRTLights(const char *entlump);
|
||||
void R_SaveRTLights_f(void);
|
||||
|
||||
//doom
|
||||
#ifdef MAP_DOOM
|
||||
|
|
|
@ -947,6 +947,9 @@ void BE_GenerateProgram(shader_t *shader);
|
|||
|
||||
void Sh_RegisterCvars(void);
|
||||
#ifdef RTLIGHTS
|
||||
void R_EditLights_DrawLights(void); //3d light previews
|
||||
void R_EditLights_DrawInfo(void); //2d light info display.
|
||||
void R_EditLights_RegisterCommands(void);
|
||||
//
|
||||
#ifdef BEF_PUSHDEPTH
|
||||
void GLBE_PolyOffsetStencilShadow(qboolean foobar);
|
||||
|
@ -982,6 +985,7 @@ extern struct shader_field_names_s shader_unif_names[];
|
|||
extern struct shader_field_names_s shader_attr_names[];
|
||||
|
||||
|
||||
void CLQ1_AddSpriteQuad(shader_t *shader, vec3_t mid, float radius);
|
||||
void CLQ1_DrawLine(shader_t *shader, vec3_t v1, vec3_t v2, float r, float g, float b, float a);
|
||||
void CLQ1_AddOrientedCube(shader_t *shader, vec3_t mins, vec3_t maxs, float *matrix, float r, float g, float b, float a);
|
||||
void CL_DrawDebugPlane(float *normal, float dist, float r, float g, float b, qboolean enqueue);
|
||||
|
|
|
@ -91,7 +91,7 @@ struct dl_download
|
|||
|
||||
qboolean isquery; //will not be displayed in the download/progress bar stuff.
|
||||
|
||||
#ifndef SERVERONLY
|
||||
#ifdef HAVE_CLIENT
|
||||
qdownload_t qdownload;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#ifdef WEBSVONLY //we need some functions from quake
|
||||
|
||||
char *NET_SockadrToString(char *s, int slen, struct sockaddr_qstorage *addr)
|
||||
char *NET_SockadrToString(char *s, int slen, struct sockaddr_qstorage *addr, size_t sizeofaddr)
|
||||
{
|
||||
switch(((struct sockaddr*)addr)->sa_family)
|
||||
{
|
||||
|
@ -221,8 +221,14 @@ int main(int argc, char **argv)
|
|||
if (arg < argc)
|
||||
autheduserpassword = argv[arg++];
|
||||
|
||||
printf("http port %i\n", httpport);
|
||||
printf("ftp port %i\n", ftpport);
|
||||
if (httpport)
|
||||
printf("http port %i\n", httpport);
|
||||
else
|
||||
printf("http not enabled\n");
|
||||
if (ftpport)
|
||||
printf("ftp port %i\n", ftpport);
|
||||
else
|
||||
printf("ftp not enabled\n");
|
||||
if (authedusername || autheduserpassword)
|
||||
printf("Username = \"%s\"\nPassword = \"%s\"\n", authedusername, autheduserpassword);
|
||||
else
|
||||
|
|
|
@ -59,7 +59,7 @@ texa0
|
|||
|
||||
struct pkgctx_s
|
||||
{
|
||||
void (*messagecallback)(void *userctx, char *message, ...);
|
||||
void (*messagecallback)(void *userctx, const char *message, ...);
|
||||
void *userctx;
|
||||
|
||||
char *listfile;
|
||||
|
@ -1557,7 +1557,7 @@ void Packager_WriteDataset(struct pkgctx_s *ctx, char *setname)
|
|||
PKG_WriteDataset(ctx, dataset);
|
||||
}
|
||||
}
|
||||
struct pkgctx_s *Packager_Create(void (*messagecallback)(void *userctx, char *message, ...), void *userctx)
|
||||
struct pkgctx_s *Packager_Create(void (*messagecallback)(void *userctx, const char *message, ...), void *userctx)
|
||||
{
|
||||
struct pkgctx_s *ctx;
|
||||
ctx = malloc(sizeof(*ctx));
|
||||
|
|
|
@ -823,6 +823,7 @@ enum {
|
|||
WARN_COMPATIBILITYHACK, //work around old defs.qc or invalid dpextensions.qc
|
||||
WARN_REDECLARATIONMISMATCH,
|
||||
WARN_PARAMWITHNONAME,
|
||||
WARN_ARGUMENTCHECK,
|
||||
|
||||
ERR_PARSEERRORS, //caused by qcc_pr_parseerror being called.
|
||||
|
||||
|
@ -1148,7 +1149,7 @@ int WriteSourceFiles(qcc_cachedsourcefile_t *filelist, int h, pbool sourceaswell
|
|||
|
||||
|
||||
struct pkgctx_s;
|
||||
struct pkgctx_s *Packager_Create(void (*messagecallback)(void *userctx, char *message, ...), void *userctx);
|
||||
struct pkgctx_s *Packager_Create(void (*messagecallback)(void *userctx, const char *message, ...), void *userctx);
|
||||
void Packager_ParseFile(struct pkgctx_s *ctx, char *scriptfilename);
|
||||
void Packager_ParseText(struct pkgctx_s *ctx, char *scripttext);
|
||||
void Packager_WriteDataset(struct pkgctx_s *ctx, char *setname);
|
||||
|
|
|
@ -4831,6 +4831,107 @@ nolength:
|
|||
}
|
||||
}
|
||||
|
||||
static void QCC_VerifyArgs_setviewprop (const char *funcname, QCC_ref_t **arglist, unsigned int argcount)
|
||||
{
|
||||
static struct
|
||||
{
|
||||
const char *name;
|
||||
int n;
|
||||
etype_t t1;
|
||||
etype_t t2;
|
||||
etype_t t3;
|
||||
} argtypes[] =
|
||||
{
|
||||
{"VF_MIN", 1, ev_vector},
|
||||
{"VF_MIN_X", 2, ev_float},
|
||||
{"VF_MIN_Y", 3, ev_float},
|
||||
{"VF_SIZE", 4, ev_vector},
|
||||
{"VF_SIZE_X", 5, ev_float},
|
||||
{"VF_SIZE_Y", 6, ev_float},
|
||||
{"VF_VIEWPORT", 7, ev_vector},
|
||||
{"VF_FOV", 8, ev_vector},
|
||||
{"VF_FOVX", 9, ev_float},
|
||||
{"VF_FOVY", 10, ev_float},
|
||||
{"VF_ORIGIN", 11, ev_vector},
|
||||
{"VF_ORIGIN_X", 12, ev_float},
|
||||
{"VF_ORIGIN_Y", 13, ev_float},
|
||||
{"VF_ORIGIN_Z", 14, ev_float},
|
||||
{"VF_ANGLES", 15, ev_vector},
|
||||
{"VF_ANGLES_X", 16, ev_float},
|
||||
{"VF_ANGLES_Y", 17, ev_float},
|
||||
{"VF_ANGLES_Z", 18, ev_float},
|
||||
{"VF_DRAWWORLD", 19, ev_float},
|
||||
{"VF_ENGINESBAR", 20, ev_float},
|
||||
{"VF_DRAWCROSSHAIR", 21, ev_float},
|
||||
// {"VF_CARTESIAN_ANGLES", 22, ev_vector},
|
||||
{"VF_MINDIST", 23, ev_float},
|
||||
{"VF_MAXDIST", 24, ev_float},
|
||||
|
||||
{"VF_CL_VIEWANGLES_V", 33, ev_vector},
|
||||
{"VF_CL_VIEWANGLES_X", 34, ev_float},
|
||||
{"VF_CL_VIEWANGLES_X", 35, ev_float},
|
||||
{"VF_CL_VIEWANGLES_X", 36, ev_float},
|
||||
{"VF_PERSPECTIVE", 200, ev_float},
|
||||
//201
|
||||
{"VF_ACTIVESEAT", 202, ev_float},
|
||||
{"VF_AFOV", 203, ev_float},
|
||||
// {"VF_SCREENVSIZE", 204, ev_vector},
|
||||
// {"VF_SCREENPSIZE", 205, ev_vector},
|
||||
{"VF_VIEWENTITY", 206, ev_float},
|
||||
// {"VF_STATSENTITY", 207, ev_float},
|
||||
// {"VF_SCREENVOFFSET", 208, ev_float},
|
||||
{"VF_RT_SOURCECOLOUR", 209, ev_string},
|
||||
{"VF_RT_DEPTH", 210, ev_string, ev_float, ev_vector},
|
||||
{"VF_RT_RIPPLE", 211, ev_string, ev_float, ev_vector},
|
||||
{"VF_RT_DESTCOLOUR0", 212, ev_string, ev_float, ev_vector},
|
||||
{"VF_RT_DESTCOLOUR1", 213, ev_string, ev_float, ev_vector},
|
||||
{"VF_RT_DESTCOLOUR2", 214, ev_string, ev_float, ev_vector},
|
||||
{"VF_RT_DESTCOLOUR3", 215, ev_string, ev_float, ev_vector},
|
||||
{"VF_RT_DESTCOLOUR4", 216, ev_string, ev_float, ev_vector},
|
||||
{"VF_RT_DESTCOLOUR5", 217, ev_string, ev_float, ev_vector},
|
||||
{"VF_RT_DESTCOLOUR6", 218, ev_string, ev_float, ev_vector},
|
||||
{"VF_RT_DESTCOLOUR7", 219, ev_string, ev_float, ev_vector},
|
||||
{"VF_ENVMAP", 220, ev_string},
|
||||
{"VF_USERDATA", 221, ev_pointer, ev_integer},
|
||||
};
|
||||
|
||||
char temp[256];
|
||||
const QCC_eval_t *ev;
|
||||
int i, vf;
|
||||
if (!argcount)
|
||||
return; // o.O
|
||||
ev = QCC_SRef_EvalConst(arglist[0]->base);
|
||||
if (!ev) //can't check variables.
|
||||
return;
|
||||
vf = ev->_float;
|
||||
if (!qccwarningaction[WARN_ARGUMENTCHECK])
|
||||
return; //don't bother if its not relevant anyway.
|
||||
|
||||
for (i = 0; i < sizeof(argtypes)/sizeof(argtypes[0]); i++)
|
||||
{
|
||||
if (argtypes[i].n == vf)
|
||||
{
|
||||
if (argcount >= 2 && argtypes[i].t1 != arglist[1]->cast->type)
|
||||
{
|
||||
QCC_PR_ParseWarning(WARN_ARGUMENTCHECK, "%s(%s, ...): expected %s, got %s", funcname, argtypes[i].name, basictypenames[argtypes[i].t1], TypeName(arglist[1]->cast, temp, sizeof(temp)));
|
||||
return;
|
||||
}
|
||||
if (argcount >= 3 && argtypes[i].t2 != arglist[2]->cast->type)
|
||||
{
|
||||
QCC_PR_ParseWarning(WARN_ARGUMENTCHECK, "%s(%s, X, ...): expected %s, got %s", funcname, argtypes[i].name, basictypenames[argtypes[i].t2], TypeName(arglist[2]->cast, temp, sizeof(temp)));
|
||||
return;
|
||||
}
|
||||
if (argcount >= 4 && argtypes[i].t3 != arglist[3]->cast->type)
|
||||
{
|
||||
QCC_PR_ParseWarning(WARN_ARGUMENTCHECK, "%s(%s, X, Y, ...): expected %s, got %s", funcname, argtypes[i].name, basictypenames[argtypes[i].t3], TypeName(arglist[3]->cast, temp, sizeof(temp)));
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
QCC_PR_ParseWarning(WARN_ARGUMENTCHECK, "%s: unknown argument %i", funcname, vf);
|
||||
}
|
||||
|
||||
#ifdef SUPPORTINLINE
|
||||
struct inlinectx_s
|
||||
{
|
||||
|
@ -5336,6 +5437,8 @@ QCC_sref_t QCC_PR_GenerateFunctionCallRef (QCC_sref_t newself, QCC_sref_t func,
|
|||
|
||||
if (!strcmp(funcname, "sprintf"))
|
||||
QCC_VerifyFormatString(funcname, arglist, argcount);
|
||||
if (!strcmp(funcname, "setviewprop") || !strcmp(funcname, "setproperty"))
|
||||
QCC_VerifyArgs_setviewprop(funcname, arglist, argcount);
|
||||
|
||||
func.sym->timescalled++;
|
||||
|
||||
|
|
|
@ -3012,7 +3012,7 @@ static void EditorReload(editor_t *editor)
|
|||
size_t flensz;
|
||||
char *rawfile;
|
||||
char *file;
|
||||
unsigned int flen;
|
||||
size_t flen;
|
||||
pbool dofree;
|
||||
rawfile = QCC_ReadFile(editor->filename, NULL, NULL, &flensz);
|
||||
flen = flensz;
|
||||
|
|
|
@ -12022,6 +12022,7 @@ void PR_DumpPlatform_f(void)
|
|||
{"MOVETYPE_6DOF", "const float", QW|NQ|CS, D("A glorified MOVETYPE_FLY. Players using this movetype will get some flightsim-like physics, with fully independant rotations (order-dependant transforms)."), MOVETYPE_6DOF},
|
||||
{"MOVETYPE_WALLWALK", "const float", QW|NQ|CS, D("Players using this movetype will be able to orient themselves to walls, and then run up them."), MOVETYPE_WALLWALK},
|
||||
{"MOVETYPE_PHYSICS", "const float", QW|NQ|CS, D("Enable the use of ODE physics upon this entity."), MOVETYPE_PHYSICS},
|
||||
// {"MOVETYPE_FLY_WORLDONLY", "const float", QW|NQ|CS, D("A cross between noclip and fly. Basically, this prevents the player/spectator from being able to move into the void, which avoids pvs issues that are common with caulk brushes on q3bsp. ONLY the world model will be solid, all doors/etc will be non-solid."), MOVETYPE_FLY_WORLDONLY},
|
||||
|
||||
{"SOLID_NOT", "const float", QW|NQ|CS, NULL, SOLID_NOT},
|
||||
{"SOLID_TRIGGER", "const float", QW|NQ|CS, NULL, SOLID_TRIGGER},
|
||||
|
@ -12463,6 +12464,7 @@ void PR_DumpPlatform_f(void)
|
|||
{"LFIELD_DIETIME", "const float", CS, NULL, lfield_dietime},
|
||||
{"LFIELD_RGBDECAY", "const float", CS, NULL, lfield_rgbdecay},
|
||||
{"LFIELD_RADIUSDECAY", "const float", CS, NULL, lfield_radiusdecay},
|
||||
{"LFIELD_STYLESTRING", "const float", CS, NULL, lfield_stylestring},
|
||||
|
||||
{"LFLAG_NORMALMODE", "const float", CS, NULL, LFLAG_NORMALMODE},
|
||||
{"LFLAG_REALTIMEMODE", "const float", CS, NULL, LFLAG_REALTIMEMODE},
|
||||
|
@ -12614,17 +12616,17 @@ void PR_DumpPlatform_f(void)
|
|||
VFS_PRINTF(f, "#pragma noref 1\n");
|
||||
VFS_PRINTF(f, "//#pragma flag enable logicops\n");
|
||||
|
||||
VFS_PRINTF(f, "#pragma warning error Q101 /*too many parms*/\n");
|
||||
VFS_PRINTF(f, "#pragma warning error Q105 /*too few parms*/\n");
|
||||
VFS_PRINTF(f, "#pragma warning error Q106 /*assignment to constant/lvalue*/\n");
|
||||
VFS_PRINTF(f, "#pragma warning error Q208 /*system crc unknown*/\n");
|
||||
VFS_PRINTF(f, "#pragma warning error Q101 /*too many parms. The vanilla qcc didn't validate properly, hence why fteqcc normally treats it as a warning.*/\n");
|
||||
VFS_PRINTF(f, "#pragma warning error Q105 /*too few parms. The vanilla qcc didn't validate properly, hence why fteqcc normally treats it as a warning.*/\n");
|
||||
VFS_PRINTF(f, "#pragma warning error Q106 /*assignment to constant/lvalue. Define them as var if you want to initialise something.*/\n");
|
||||
VFS_PRINTF(f, "#pragma warning error Q208 /*system crc unknown. Compatibility goes out of the window if you disable this.*/\n");
|
||||
#ifdef NOLEGACY
|
||||
VFS_PRINTF(f, "#pragma warning error F211 /*system crc outdated (eg: dp's csqc)*/\n");
|
||||
VFS_PRINTF(f, "#pragma warning error F211 /*system crc outdated (eg: dp's csqc). Such mods will not run properly in FTE.*/\n");
|
||||
#else
|
||||
VFS_PRINTF(f, "#pragma warning disable F211 /*system crc outdated (eg: dp's csqc)*/\n");
|
||||
VFS_PRINTF(f, "#pragma warning disable F211 /*system crc outdated (eg: dp's csqc). Note that this may trigger emulation.*/\n");
|
||||
#endif
|
||||
VFS_PRINTF(f, "#pragma warning enable F301 /*non-utf-8 strings*/\n");
|
||||
VFS_PRINTF(f, "#pragma warning enable F302 /*uninitialised locals*/\n");
|
||||
VFS_PRINTF(f, "#pragma warning enable F301 /*non-utf-8 strings. Think of the foreigners! Also think of text editors that insist on screwing up your char encodings.*/\n");
|
||||
VFS_PRINTF(f, "#pragma warning enable F302 /*uninitialised locals. They usually default to 0 in qc (except in recursive functions), but its still probably a bug*/\n");
|
||||
|
||||
if ((targ&ALL) == H2)
|
||||
{
|
||||
|
|
|
@ -1571,7 +1571,7 @@ void SV_Savegame (const char *savename, qboolean mapchange)
|
|||
#endif
|
||||
if (!okay && r_worldentity.model)
|
||||
{
|
||||
V_RenderView ();
|
||||
V_RenderView (false);
|
||||
okay = true;
|
||||
}
|
||||
|
||||
|
@ -1583,7 +1583,7 @@ void SV_Savegame (const char *savename, qboolean mapchange)
|
|||
if (rgbbuffer)
|
||||
{
|
||||
// extern cvar_t scr_sshot_type;
|
||||
SCR_ScreenShot(savefilename, FS_GAMEONLY, &rgbbuffer, 1, stride, width, height, fmt);
|
||||
SCR_ScreenShot(savefilename, FS_GAMEONLY, &rgbbuffer, 1, stride, width, height, fmt, false);
|
||||
BZ_Free(rgbbuffer);
|
||||
|
||||
|
||||
|
|
|
@ -1310,7 +1310,9 @@ void SV_UpdateToReliableMessages (void);
|
|||
void SV_FlushBroadcasts (void);
|
||||
qboolean SV_CanTrack(client_t *client, int entity);
|
||||
|
||||
#ifdef NQPROT
|
||||
void SV_DarkPlacesDownloadChunk(client_t *cl, sizebuf_t *msg);
|
||||
#endif
|
||||
void SV_New_f (void);
|
||||
|
||||
void SV_PreRunCmd(void);
|
||||
|
|
|
@ -2639,6 +2639,9 @@ client_t *SVC_DirectConnect(void)
|
|||
}
|
||||
}
|
||||
msg_badread=false;
|
||||
|
||||
if (!*guid)
|
||||
NET_GetConnectionCertificate(svs.sockets, &net_from, QCERT_PEERFINGERPRINT, guid, sizeof(guid));
|
||||
|
||||
/*allow_splitscreen applies only to non-local clients, so that clients have only one enabler*/
|
||||
if (!sv_allow_splitscreen.ival && net_from.type != NA_LOOPBACK)
|
||||
|
@ -3303,8 +3306,10 @@ client_t *SVC_DirectConnect(void)
|
|||
SSV_SavePlayerStats(newcl, 0);
|
||||
#endif
|
||||
|
||||
#ifdef IPLOG
|
||||
if (Q_strncasecmp(newcl->name, "unconnected", 11) && Q_strncasecmp(newcl->name, "connecting", 10))
|
||||
IPLog_Add(NET_AdrToString(adrbuf,sizeof(adrbuf), &newcl->netchan.remote_address), newcl->name);
|
||||
#endif
|
||||
|
||||
return newcl;
|
||||
}
|
||||
|
@ -5799,8 +5804,10 @@ void SV_Init (quakeparms_t *parms)
|
|||
}
|
||||
#endif
|
||||
|
||||
IPLog_Merge_File("iplog.txt");
|
||||
#ifdef IPLOG
|
||||
IPLog_Merge_File("iplog.txt"); //should be compatible with DP's take on the feature.
|
||||
IPLog_Merge_File("iplog.dat"); //legacy crap, for compat with proquake
|
||||
#endif
|
||||
|
||||
// if a map wasn't specified on the command line, spawn start.map
|
||||
//aliases require that we flush the cbuf in order to actually see the results.
|
||||
|
|
|
@ -32,7 +32,7 @@ is not a staircase.
|
|||
|
||||
=============
|
||||
*/
|
||||
int c_yes, c_no;
|
||||
//int c_yes, c_no;
|
||||
|
||||
hull_t *Q1BSP_ChooseHull(model_t *model, int hullnum, vec3_t mins, vec3_t maxs, vec3_t offset);
|
||||
|
||||
|
@ -92,11 +92,11 @@ qboolean World_CheckBottom (world_t *world, wedict_t *ent, vec3_t up)
|
|||
goto realcheck;
|
||||
}
|
||||
|
||||
c_yes++;
|
||||
// c_yes++;
|
||||
return true; // we got out easy
|
||||
|
||||
realcheck:
|
||||
c_no++;
|
||||
// c_no++;
|
||||
//
|
||||
// check it for real...
|
||||
//
|
||||
|
@ -128,7 +128,7 @@ realcheck:
|
|||
return false;
|
||||
}
|
||||
|
||||
c_yes++;
|
||||
// c_yes++;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -629,7 +629,7 @@ qboolean World_MoveToGoal (world_t *world, wedict_t *ent, float dist)
|
|||
|
||||
|
||||
#ifdef ENGINE_ROUTING
|
||||
cvar_t route_shownodes = CVAR("route_shownodes", "0");
|
||||
static cvar_t route_shownodes = CVAR("route_shownodes", "0");
|
||||
|
||||
#define LF_EDGE 0x00000001
|
||||
#define LF_JUMP 0x00000002
|
||||
|
@ -648,7 +648,7 @@ struct waypointnetwork_s
|
|||
vec3_t pos;
|
||||
int linkflags;
|
||||
} *displaynode;
|
||||
int displaynodes;
|
||||
size_t displaynodes;
|
||||
|
||||
struct waypoint_s
|
||||
{
|
||||
|
@ -660,7 +660,7 @@ struct waypointnetwork_s
|
|||
float linkcost;//might be much lower in the case of teleports, or expensive if someone wanted it to be a lower priority link.
|
||||
int linkflags; //LF_*
|
||||
} *neighbour;
|
||||
int neighbours;
|
||||
size_t neighbours;
|
||||
} waypoints[1];
|
||||
};
|
||||
void WayNet_Done(struct waypointnetwork_s *net)
|
||||
|
@ -814,8 +814,8 @@ int WayNet_FindNearestNode(struct waypointnetwork_s *net, vec3_t pos)
|
|||
struct routecalc_s
|
||||
{
|
||||
world_t *world;
|
||||
int spawncount; //so we don't confuse stuff if the map gets restarted.
|
||||
wedict_t *ed;
|
||||
int spawncount; //so we don't confuse stuff if the map gets restarted.
|
||||
// float spawnid; //so the route fails if the ent is removed.
|
||||
func_t callback;
|
||||
|
||||
|
|
|
@ -2831,7 +2831,9 @@ qboolean SV_SendClientDatagram (client_t *client)
|
|||
SZ_Clear (&msg);
|
||||
}
|
||||
|
||||
#ifdef NQPROT
|
||||
SV_DarkPlacesDownloadChunk(client, &msg);
|
||||
#endif
|
||||
|
||||
// send the datagram
|
||||
sentbytes = Netchan_Transmit (&client->netchan, msg.cursize, buf, SV_RateForClient(client));
|
||||
|
@ -3693,7 +3695,9 @@ void SV_SendClientMessages (void)
|
|||
SV_SendClientDatagram (c);
|
||||
else
|
||||
{
|
||||
#ifdef NQPROT
|
||||
SV_DarkPlacesDownloadChunk(c, &c->datagram);
|
||||
#endif
|
||||
fnum = c->netchan.outgoing_sequence;
|
||||
sentbytes = Netchan_Transmit (&c->netchan, c->datagram.cursize, c->datagram.data, SV_RateForClient(c)); // just update reliable
|
||||
if (ISQWCLIENT(c) || ISNQCLIENT(c))
|
||||
|
|
|
@ -349,7 +349,7 @@ void SV_New_f (void)
|
|||
for (split = host_client; split; split = split->controlled)
|
||||
{
|
||||
playernum = split - svs.clients;// NUM_FOR_EDICT(svprogfuncs, split->edict)-1;
|
||||
if (sv.state == ss_cinematic)
|
||||
if (ISQ2CLIENT(host_client) && sv.state == ss_cinematic)
|
||||
playernum = -1;
|
||||
ClientReliableWrite_Byte (host_client, playernum);
|
||||
|
||||
|
@ -391,9 +391,6 @@ void SV_New_f (void)
|
|||
if (split->spectator)
|
||||
playernum |= 128;
|
||||
|
||||
if (sv.state == ss_cinematic)
|
||||
playernum = -1;
|
||||
|
||||
split->state = cs_connected;
|
||||
split->connection_started = realtime;
|
||||
#ifdef SVRANKING
|
||||
|
@ -403,6 +400,8 @@ void SV_New_f (void)
|
|||
|
||||
if (ISQ2CLIENT(host_client))
|
||||
{
|
||||
if (sv.state == ss_cinematic)
|
||||
playernum = -1;
|
||||
ClientReliableWrite_Short (host_client, playernum);
|
||||
break;
|
||||
}
|
||||
|
@ -462,6 +461,16 @@ void SV_New_f (void)
|
|||
|
||||
SV_LogPlayer(host_client, "new (QW)");
|
||||
|
||||
if (sv.state == ss_cinematic)
|
||||
{
|
||||
char tmp[1024];
|
||||
MSG_WriteByte (&host_client->netchan.message, svc_stufftext);
|
||||
MSG_WriteString(&host_client->netchan.message, va("\nplayfilm %s\n", COM_QuotedString(svs.name, tmp, sizeof(tmp), false)));
|
||||
host_client->prespawn_stage = PRESPAWN_INVALID;
|
||||
host_client->prespawn_idx = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
host_client->prespawn_stage = PRESPAWN_SERVERINFO;
|
||||
host_client->prespawn_idx = 0;
|
||||
}
|
||||
|
@ -718,6 +727,16 @@ void SVNQ_New_f (void)
|
|||
MSG_WriteString (&host_client->netchan.message, "cl_serverextension_download 1\n");
|
||||
}
|
||||
|
||||
if (sv.state == ss_cinematic)
|
||||
{
|
||||
MSG_WriteByte (&host_client->netchan.message, svc_stufftext);
|
||||
MSG_WriteString(&host_client->netchan.message, va("\nplayfilm %s\n", COM_QuotedString(svs.name, message, sizeof(message), false)));
|
||||
host_client->prespawn_stage = PRESPAWN_INVALID;
|
||||
host_client->prespawn_idx = 0;
|
||||
host_client->netchan.nqunreliableonly = 2;
|
||||
return;
|
||||
}
|
||||
|
||||
MSG_WriteByte (&host_client->netchan.message, svc_serverdata);
|
||||
if (protext1)
|
||||
{
|
||||
|
@ -2242,6 +2261,7 @@ void SV_Begin_f (void)
|
|||
|
||||
//=============================================================================
|
||||
|
||||
#ifdef NQPROT
|
||||
//dp downloads are a 2-stream system
|
||||
//the server->client stream is as you'd expect. except that its unreliable rather than reliable
|
||||
//the client->server stream contains no actual data.
|
||||
|
@ -2349,6 +2369,7 @@ void SV_DarkPlacesDownloadAck(client_t *cl)
|
|||
host_client->downloadsize = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void SV_NextChunkedDownload(unsigned int chunknum, int ezpercent, int ezfilenum, int chunks)
|
||||
{
|
||||
|
@ -5485,14 +5506,6 @@ void SV_DisableClientsCSQC(void)
|
|||
}
|
||||
|
||||
void SV_UserCmdMVDList_f (void);
|
||||
static void SV_STFU_f(void)
|
||||
{
|
||||
char *msg;
|
||||
SV_ClientPrintf(host_client, 255, "stfu\n");
|
||||
msg = "cl_antilag 0\n";
|
||||
ClientReliableWrite_Begin(host_client, svc_stufftext, 2+strlen(msg));
|
||||
ClientReliableWrite_String(host_client, msg);
|
||||
}
|
||||
|
||||
#ifdef NQPROT
|
||||
static void SVNQ_Spawn_f (void)
|
||||
|
@ -5975,9 +5988,6 @@ ucmd_t ucmds[] =
|
|||
{"spawn", SVQW_Spawn_f, true},
|
||||
{"begin", SV_Begin_f, true},
|
||||
|
||||
/*ezquake warning*/
|
||||
{"al", SV_STFU_f, true}, //can probably be removed now.
|
||||
|
||||
{"drop", SV_Drop_f},
|
||||
{"disconnect", SV_Drop_f},
|
||||
{"pings", SV_Pings_f},
|
||||
|
|
|
@ -43,6 +43,9 @@ void *SVQ2_GetGameAPI (void *parms)
|
|||
#endif
|
||||
"game" ARCH_CPU_POSTFIX ARCH_DL_POSTFIX,
|
||||
"game" ARCH_DL_POSTFIX,
|
||||
#if defined(__linux__) //FTE doesn't provide gamecode. Borrow someone else's. Lets just hope that its installed.
|
||||
"/usr/lib/yamagi-quake2/%s/game.so",
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
void *ret;
|
||||
|
@ -70,6 +73,12 @@ void *SVQ2_GetGameAPI (void *parms)
|
|||
continue;
|
||||
Q_snprintfz(name, sizeof(name), "%slibgame_%s"ARCH_DL_POSTFIX, host_parms.binarydir, gamepath);
|
||||
}
|
||||
else if (*gamename[o] == '/')
|
||||
{ //system path. o.O
|
||||
if (com_nogamedirnativecode.ival) //just in case they match.
|
||||
continue;
|
||||
Q_snprintfz(name, sizeof(name), gamename[o], gamepath);
|
||||
}
|
||||
else
|
||||
{ //gamedir paths as specified above.
|
||||
if (com_nogamedirnativecode.ival)
|
||||
|
|
|
@ -2237,8 +2237,6 @@ static void World_ClipToNetwork (world_t *w, moveclip_t *clip)
|
|||
trace_t trace;
|
||||
static framestate_t framestate; //meh
|
||||
|
||||
if (clip->type == MOVE_WORLDONLY)
|
||||
return;
|
||||
if (clip->type & MOVE_ENTCHAIN)
|
||||
return;
|
||||
|
||||
|
@ -2565,6 +2563,13 @@ trace_t World_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t e
|
|||
wedict_t *other = WEDICT_NUM_UB(w->progs, *w->g.other);
|
||||
return World_ClipMoveToEntity (w, other, other->v->origin, start, mins, maxs, end, hullnum, type & MOVE_HITMODEL, clip.capsule, clip.hitcontentsmask);
|
||||
}
|
||||
#ifndef NOLEGACY
|
||||
if ((type&MOVE_WORLDONLY) == MOVE_WORLDONLY)
|
||||
{ //for compat with DP
|
||||
wedict_t *other = w->edicts;
|
||||
return World_ClipMoveToEntity (w, other, other->v->origin, start, mins, maxs, end, hullnum, type & MOVE_HITMODEL, clip.capsule, clip.hitcontentsmask);
|
||||
}
|
||||
#endif
|
||||
|
||||
// clip to world
|
||||
clip.trace = World_ClipMoveToEntity (w, w->edicts, w->edicts->v->origin, start, mins, maxs, end, hullnum, false, clip.capsule, clip.hitcontentsmask);
|
||||
|
|
|
@ -1750,7 +1750,7 @@ static void T_Gen_CurrentRender(void)
|
|||
if (img->width != vid.fbpwidth || img->height != vid.fbpheight)
|
||||
{
|
||||
//FIXME: free the old image when its safe to do so.
|
||||
*img = VK_CreateTexture2DArray(vid.fbpwidth, vid.fbpheight, 1, 1, -vk.backbufformat, PTI_2D, true);
|
||||
*img = VK_CreateTexture2DArray(vid.fbpwidth, vid.fbpheight, 1, 1, -vk.backbufformat, PTI_2D, true, shaderstate.tex_currentrender->ident);
|
||||
|
||||
if (!img->sampler)
|
||||
VK_CreateSampler(shaderstate.tex_currentrender->flags, img);
|
||||
|
|
|
@ -56,8 +56,14 @@ const char *vklayerlist[] =
|
|||
|
||||
#ifdef VK_NO_PROTOTYPES
|
||||
#define VKFunc(n) PFN_vk##n vk##n;
|
||||
VKFunc(CreateDebugReportCallbackEXT)
|
||||
VKFunc(DestroyDebugReportCallbackEXT)
|
||||
#ifdef VK_EXT_debug_utils
|
||||
VKFunc(CreateDebugUtilsMessengerEXT)
|
||||
VKFunc(DestroyDebugUtilsMessengerEXT)
|
||||
#endif
|
||||
#ifdef VK_EXT_debug_report
|
||||
VKFunc(CreateDebugReportCallbackEXT)
|
||||
VKFunc(DestroyDebugReportCallbackEXT)
|
||||
#endif
|
||||
VKFuncs
|
||||
#undef VKFunc
|
||||
#endif
|
||||
|
@ -97,6 +103,133 @@ do { \
|
|||
#define DOBACKTRACE()
|
||||
#endif
|
||||
|
||||
#ifdef VK_EXT_debug_utils
|
||||
static void DebugSetName(VkObjectType objtype, uint64_t handle, const char *name)
|
||||
{
|
||||
if (vkSetDebugUtilsObjectNameEXT)
|
||||
{
|
||||
VkDebugUtilsObjectNameInfoEXT info =
|
||||
{
|
||||
VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
|
||||
NULL,
|
||||
objtype,
|
||||
handle,
|
||||
name
|
||||
};
|
||||
vkSetDebugUtilsObjectNameEXT(vk.device, &info);
|
||||
}
|
||||
}
|
||||
static VkDebugUtilsMessengerEXT vk_debugucallback;
|
||||
char *DebugAnnotObjectToString(VkObjectType t)
|
||||
{
|
||||
switch(t)
|
||||
{
|
||||
case VK_OBJECT_TYPE_UNKNOWN: return "VK_OBJECT_TYPE_UNKNOWN";
|
||||
case VK_OBJECT_TYPE_INSTANCE: return "VK_OBJECT_TYPE_INSTANCE";
|
||||
case VK_OBJECT_TYPE_PHYSICAL_DEVICE: return "VK_OBJECT_TYPE_PHYSICAL_DEVICE";
|
||||
case VK_OBJECT_TYPE_DEVICE: return "VK_OBJECT_TYPE_DEVICE";
|
||||
case VK_OBJECT_TYPE_QUEUE: return "VK_OBJECT_TYPE_QUEUE";
|
||||
case VK_OBJECT_TYPE_SEMAPHORE: return "VK_OBJECT_TYPE_SEMAPHORE";
|
||||
case VK_OBJECT_TYPE_COMMAND_BUFFER: return "VK_OBJECT_TYPE_COMMAND_BUFFER";
|
||||
case VK_OBJECT_TYPE_FENCE: return "VK_OBJECT_TYPE_FENCE";
|
||||
case VK_OBJECT_TYPE_DEVICE_MEMORY: return "VK_OBJECT_TYPE_DEVICE_MEMORY";
|
||||
case VK_OBJECT_TYPE_BUFFER: return "VK_OBJECT_TYPE_BUFFER";
|
||||
case VK_OBJECT_TYPE_IMAGE: return "VK_OBJECT_TYPE_IMAGE";
|
||||
case VK_OBJECT_TYPE_EVENT: return "VK_OBJECT_TYPE_EVENT";
|
||||
case VK_OBJECT_TYPE_QUERY_POOL: return "VK_OBJECT_TYPE_QUERY_POOL";
|
||||
case VK_OBJECT_TYPE_BUFFER_VIEW: return "VK_OBJECT_TYPE_BUFFER_VIEW";
|
||||
case VK_OBJECT_TYPE_IMAGE_VIEW: return "VK_OBJECT_TYPE_IMAGE_VIEW";
|
||||
case VK_OBJECT_TYPE_SHADER_MODULE: return "VK_OBJECT_TYPE_SHADER_MODULE";
|
||||
case VK_OBJECT_TYPE_PIPELINE_CACHE: return "VK_OBJECT_TYPE_PIPELINE_CACHE";
|
||||
case VK_OBJECT_TYPE_PIPELINE_LAYOUT: return "VK_OBJECT_TYPE_PIPELINE_LAYOUT";
|
||||
case VK_OBJECT_TYPE_RENDER_PASS: return "VK_OBJECT_TYPE_RENDER_PASS";
|
||||
case VK_OBJECT_TYPE_PIPELINE: return "VK_OBJECT_TYPE_PIPELINE";
|
||||
case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT: return "VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT";
|
||||
case VK_OBJECT_TYPE_SAMPLER: return "VK_OBJECT_TYPE_SAMPLER";
|
||||
case VK_OBJECT_TYPE_DESCRIPTOR_POOL: return "VK_OBJECT_TYPE_DESCRIPTOR_POOL";
|
||||
case VK_OBJECT_TYPE_DESCRIPTOR_SET: return "VK_OBJECT_TYPE_DESCRIPTOR_SET";
|
||||
case VK_OBJECT_TYPE_FRAMEBUFFER: return "VK_OBJECT_TYPE_FRAMEBUFFER";
|
||||
case VK_OBJECT_TYPE_COMMAND_POOL: return "VK_OBJECT_TYPE_COMMAND_POOL";
|
||||
case VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION: return "VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION";
|
||||
case VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE: return "VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE";
|
||||
case VK_OBJECT_TYPE_SURFACE_KHR: return "VK_OBJECT_TYPE_SURFACE_KHR";
|
||||
case VK_OBJECT_TYPE_SWAPCHAIN_KHR: return "VK_OBJECT_TYPE_SWAPCHAIN_KHR";
|
||||
case VK_OBJECT_TYPE_DISPLAY_KHR: return "VK_OBJECT_TYPE_DISPLAY_KHR";
|
||||
case VK_OBJECT_TYPE_DISPLAY_MODE_KHR: return "VK_OBJECT_TYPE_DISPLAY_MODE_KHR";
|
||||
case VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT: return "VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT";
|
||||
case VK_OBJECT_TYPE_OBJECT_TABLE_NVX: return "VK_OBJECT_TYPE_OBJECT_TABLE_NVX";
|
||||
case VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX: return "VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX";
|
||||
case VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT: return "VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT";
|
||||
case VK_OBJECT_TYPE_VALIDATION_CACHE_EXT: return "VK_OBJECT_TYPE_VALIDATION_CACHE_EXT";
|
||||
case VK_OBJECT_TYPE_RANGE_SIZE:
|
||||
case VK_OBJECT_TYPE_MAX_ENUM:
|
||||
break;
|
||||
}
|
||||
return "UNKNOWNTYPE";
|
||||
}
|
||||
static VKAPI_ATTR VkBool32 VKAPI_CALL mydebugutilsmessagecallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT*pCallbackData, void* pUserData)
|
||||
{
|
||||
char prefix[64];
|
||||
int l = 0; //developer level
|
||||
if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT)
|
||||
{ //spam?
|
||||
strcpy(prefix, "VERBOSE:");
|
||||
l = 2;
|
||||
}
|
||||
else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT)
|
||||
{ //generally stuff like 'object created'
|
||||
strcpy(prefix, "INFO:");
|
||||
l = 1;
|
||||
}
|
||||
else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)
|
||||
strcpy(prefix, CON_WARNING"WARNING:");
|
||||
else if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
|
||||
strcpy(prefix, CON_ERROR "ERROR:");
|
||||
|
||||
if (messageType & VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT)
|
||||
strcat(prefix, "GENERAL");
|
||||
else
|
||||
{
|
||||
if (messageType & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT)
|
||||
strcat(prefix, "SPEC");
|
||||
if (messageType & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT)
|
||||
{
|
||||
if (messageType & VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT)
|
||||
{
|
||||
strcat(prefix, "|");
|
||||
}
|
||||
strcat(prefix,"PERF");
|
||||
}
|
||||
}
|
||||
Con_DLPrintf(l, "%s[%d] %s - %s\n", prefix, pCallbackData->messageIdNumber, pCallbackData->pMessageIdName?pCallbackData->pMessageIdName:"", pCallbackData->pMessage);
|
||||
|
||||
if (pCallbackData->objectCount > 0)
|
||||
{
|
||||
uint32_t object;
|
||||
for(object = 0; object < pCallbackData->objectCount; ++object)
|
||||
Con_DLPrintf(l, " Object[%d] - Type %s, Value %"PRIx64", Name \"%s\"\n", object,
|
||||
DebugAnnotObjectToString(pCallbackData->pObjects[object].objectType),
|
||||
pCallbackData->pObjects[object].objectHandle,
|
||||
pCallbackData->pObjects[object].pObjectName);
|
||||
}
|
||||
|
||||
if (pCallbackData->cmdBufLabelCount > 0)
|
||||
{
|
||||
uint32_t label;
|
||||
for (label = 0; label < pCallbackData->cmdBufLabelCount; ++label)
|
||||
Con_DLPrintf(l, " Label[%d] - %s { %f, %f, %f, %f}\n", label,
|
||||
pCallbackData->pCmdBufLabels[label].pLabelName,
|
||||
pCallbackData->pCmdBufLabels[label].color[0],
|
||||
pCallbackData->pCmdBufLabels[label].color[1],
|
||||
pCallbackData->pCmdBufLabels[label].color[2],
|
||||
pCallbackData->pCmdBufLabels[label].color[3]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
#define DebugSetName(objtype,handle,name)
|
||||
#endif
|
||||
#ifdef VK_EXT_debug_report
|
||||
static VkDebugReportCallbackEXT vk_debugcallback;
|
||||
static VkBool32 VKAPI_PTR mydebugreportcallback(
|
||||
VkDebugReportFlagsEXT flags,
|
||||
|
@ -146,6 +279,7 @@ static VkBool32 VKAPI_PTR mydebugreportcallback(
|
|||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
//typeBits is some vulkan requirement thing (like textures must be device-local).
|
||||
//requirements_mask are things that the engine may require (like host-visible).
|
||||
|
@ -388,6 +522,7 @@ static qboolean VK_CreateSwapChain(void)
|
|||
ici.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
|
||||
VkAssert(vkCreateImage(vk.device, &ici, vkallocationcb, &images[i]));
|
||||
DebugSetName(VK_OBJECT_TYPE_IMAGE, (uint64_t)images[i], "backbuffer");
|
||||
|
||||
vkGetImageMemoryRequirements(vk.device, images[i], &mem_reqs);
|
||||
|
||||
|
@ -730,6 +865,10 @@ static qboolean VK_CreateSwapChain(void)
|
|||
for (i = 0; i < vk.backbuf_count; i++)
|
||||
{
|
||||
VkImageViewCreateInfo ivci = {VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
|
||||
|
||||
vk.backbufs[i].colour.image = images[i];
|
||||
DebugSetName(VK_OBJECT_TYPE_IMAGE, (uint64_t)vk.backbufs[i].colour.image, "backbuffer");
|
||||
|
||||
ivci.format = vk.backbufformat;
|
||||
// ivci.components.r = VK_COMPONENT_SWIZZLE_R;
|
||||
// ivci.components.g = VK_COMPONENT_SWIZZLE_G;
|
||||
|
@ -743,7 +882,6 @@ static qboolean VK_CreateSwapChain(void)
|
|||
ivci.viewType = VK_IMAGE_VIEW_TYPE_2D;
|
||||
ivci.flags = 0;
|
||||
ivci.image = images[i];
|
||||
vk.backbufs[i].colour.image = images[i];
|
||||
if (memories)
|
||||
vk.backbufs[i].colour.mem.memory = memories[i];
|
||||
vk.backbufs[i].colour.width = swapinfo.imageExtent.width;
|
||||
|
@ -773,6 +911,7 @@ static qboolean VK_CreateSwapChain(void)
|
|||
depthinfo.pQueueFamilyIndices = NULL;
|
||||
depthinfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
VkAssert(vkCreateImage(vk.device, &depthinfo, vkallocationcb, &vk.backbufs[i].depth.image));
|
||||
DebugSetName(VK_OBJECT_TYPE_IMAGE, (uint64_t)vk.backbufs[i].depth.image, "backbuffer depth");
|
||||
}
|
||||
|
||||
//depth memory
|
||||
|
@ -821,6 +960,7 @@ static qboolean VK_CreateSwapChain(void)
|
|||
mscolourinfo.pQueueFamilyIndices = NULL;
|
||||
mscolourinfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
VkAssert(vkCreateImage(vk.device, &mscolourinfo, vkallocationcb, &vk.backbufs[i].mscolour.image));
|
||||
DebugSetName(VK_OBJECT_TYPE_IMAGE, (uint64_t)vk.backbufs[i].mscolour.image, "multisample");
|
||||
}
|
||||
|
||||
//mscolour memory
|
||||
|
@ -1088,7 +1228,7 @@ qboolean VK_AllocateBindImageMemory(vk_image_t *image, qboolean dedicated)
|
|||
}
|
||||
|
||||
|
||||
vk_image_t VK_CreateTexture2DArray(uint32_t width, uint32_t height, uint32_t layers, uint32_t mips, uploadfmt_t encoding, unsigned int type, qboolean rendertarget)
|
||||
vk_image_t VK_CreateTexture2DArray(uint32_t width, uint32_t height, uint32_t layers, uint32_t mips, uploadfmt_t encoding, unsigned int type, qboolean rendertarget, const char *debugname)
|
||||
{
|
||||
vk_image_t ret;
|
||||
VkImageViewCreateInfo viewInfo = {VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
|
||||
|
@ -1235,6 +1375,7 @@ vk_image_t VK_CreateTexture2DArray(uint32_t width, uint32_t height, uint32_t lay
|
|||
ici.initialLayout = ret.layout;
|
||||
|
||||
VkAssert(vkCreateImage(vk.device, &ici, vkallocationcb, &ret.image));
|
||||
DebugSetName(VK_OBJECT_TYPE_IMAGE, (uint64_t)ret.image, debugname);
|
||||
|
||||
ret.view = VK_NULL_HANDLE;
|
||||
ret.sampler = VK_NULL_HANDLE;
|
||||
|
@ -1556,7 +1697,7 @@ qboolean VK_LoadTextureMips (texid_t tex, const struct pendingtextureinfo *mips)
|
|||
}
|
||||
else
|
||||
{
|
||||
target = VK_CreateTexture2DArray(mips->mip[0].width, mips->mip[0].height, layers, mipcount/layers, mips->encoding, mips->type, !!(tex->flags&IF_RENDERTARGET));
|
||||
target = VK_CreateTexture2DArray(mips->mip[0].width, mips->mip[0].height, layers, mipcount/layers, mips->encoding, mips->type, !!(tex->flags&IF_RENDERTARGET), tex->ident);
|
||||
|
||||
if (target.mem.memory == VK_NULL_HANDLE)
|
||||
{
|
||||
|
@ -2663,6 +2804,7 @@ char *VKVID_GetRGBInfo (int *bytestride, int *truevidwidth, int *truevidheight
|
|||
ici.pQueueFamilyIndices = NULL;
|
||||
ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
VkAssert(vkCreateImage(vk.device, &ici, vkallocationcb, &tempimage));
|
||||
DebugSetName(VK_OBJECT_TYPE_IMAGE, (uint64_t)tempimage, "VKVID_GetRGBInfo staging");
|
||||
vkGetImageMemoryRequirements(vk.device, tempimage, &mem_reqs);
|
||||
memAllocInfo.allocationSize = mem_reqs.size;
|
||||
memAllocInfo.memoryTypeIndex = vk_find_memory_require(mem_reqs.memoryTypeBits, 0);
|
||||
|
@ -2880,7 +3022,7 @@ static void VK_PaintScreen(void)
|
|||
if (uimenu != 1)
|
||||
{
|
||||
if (r_worldentity.model && cls.state == ca_active)
|
||||
V_RenderView ();
|
||||
V_RenderView (nohud);
|
||||
else
|
||||
{
|
||||
noworld = true;
|
||||
|
@ -3844,14 +3986,26 @@ qboolean VK_Init(rendererstate_t *info, const char **sysextnames, qboolean (*cre
|
|||
qboolean surfext = false;
|
||||
uint32_t count, i, j;
|
||||
VkExtensionProperties *ext;
|
||||
#ifdef VK_EXT_debug_utils
|
||||
qboolean havedebugutils = false;
|
||||
#endif
|
||||
#ifdef VK_EXT_debug_report
|
||||
qboolean havedebugreport = false;
|
||||
#endif
|
||||
vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
|
||||
ext = malloc(sizeof(*ext)*count);
|
||||
vkEnumerateInstanceExtensionProperties(NULL, &count, ext);
|
||||
for (i = 0; i < count && extensions_count < countof(extensions); i++)
|
||||
{
|
||||
if (!strcmp(ext[i].extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME) && vk_debug.ival)
|
||||
extensions[extensions_count++] = VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
|
||||
else if (!strcmp(ext[i].extensionName, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME))
|
||||
#ifdef VK_EXT_debug_utils
|
||||
if (!strcmp(ext[i].extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME))
|
||||
havedebugutils = true;
|
||||
#endif
|
||||
#ifdef VK_EXT_debug_report
|
||||
if (!strcmp(ext[i].extensionName, VK_EXT_DEBUG_REPORT_EXTENSION_NAME))
|
||||
havedebugreport = true;
|
||||
#endif
|
||||
if (!strcmp(ext[i].extensionName, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME))
|
||||
extensions[extensions_count++] = VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME;
|
||||
else if (sysextnames && !strcmp(ext[i].extensionName, VK_KHR_SURFACE_EXTENSION_NAME))
|
||||
{
|
||||
|
@ -3871,9 +4025,21 @@ qboolean VK_Init(rendererstate_t *info, const char **sysextnames, qboolean (*cre
|
|||
}
|
||||
}
|
||||
free(ext);
|
||||
|
||||
if (!vk_debug.ival)
|
||||
;
|
||||
#ifdef VK_EXT_debug_utils
|
||||
else if (havedebugutils)
|
||||
extensions[extensions_count++] = VK_EXT_DEBUG_UTILS_EXTENSION_NAME;
|
||||
#endif
|
||||
#ifdef VK_EXT_debug_report
|
||||
else if (havedebugreport)
|
||||
extensions[extensions_count++] = VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
|
||||
#endif
|
||||
|
||||
if (sysextnames && (!vk.khr_swapchain || !surfext))
|
||||
{
|
||||
Con_Printf("Vulkan instance driver lacks support for %s\n", sysextnames[0]);
|
||||
Con_Printf("Vulkan instance lacks driver support for %s\n", sysextnames[0]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -3926,6 +4092,27 @@ qboolean VK_Init(rendererstate_t *info, const char **sysextnames, qboolean (*cre
|
|||
//set up debug callbacks
|
||||
if (vk_debug.ival)
|
||||
{
|
||||
#ifdef VK_EXT_debug_utils
|
||||
vkCreateDebugUtilsMessengerEXT = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(vk.instance, "vkCreateDebugUtilsMessengerEXT");
|
||||
vkDestroyDebugUtilsMessengerEXT = (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(vk.instance, "vkDestroyDebugUtilsMessengerEXT");
|
||||
if (vkCreateDebugUtilsMessengerEXT)
|
||||
{
|
||||
VkDebugUtilsMessengerCreateInfoEXT dbgCreateInfo;
|
||||
memset(&dbgCreateInfo, 0, sizeof(dbgCreateInfo));
|
||||
dbgCreateInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
|
||||
dbgCreateInfo.pfnUserCallback = mydebugutilsmessagecallback;
|
||||
dbgCreateInfo.pUserData = NULL;
|
||||
dbgCreateInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
|
||||
dbgCreateInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
|
||||
vkCreateDebugUtilsMessengerEXT(vk.instance, &dbgCreateInfo, vkallocationcb, &vk_debugucallback);
|
||||
}
|
||||
#endif
|
||||
#ifdef VK_EXT_debug_report
|
||||
vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(vk.instance, "vkCreateDebugReportCallbackEXT");
|
||||
vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(vk.instance, "vkDestroyDebugReportCallbackEXT");
|
||||
if (vkCreateDebugReportCallbackEXT && vkDestroyDebugReportCallbackEXT)
|
||||
|
@ -3942,6 +4129,7 @@ qboolean VK_Init(rendererstate_t *info, const char **sysextnames, qboolean (*cre
|
|||
VK_DEBUG_REPORT_DEBUG_BIT_EXT;
|
||||
vkCreateDebugReportCallbackEXT(vk.instance, &dbgCreateInfo, vkallocationcb, &vk_debugcallback);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//create the platform-specific surface
|
||||
|
@ -4461,11 +4649,20 @@ void VK_Shutdown(void)
|
|||
|
||||
if (vk.device)
|
||||
vkDestroyDevice(vk.device, vkallocationcb);
|
||||
#ifdef VK_EXT_debug_utils
|
||||
if (vk_debugucallback)
|
||||
{
|
||||
vkDestroyDebugUtilsMessengerEXT(vk.instance, vk_debugucallback, vkallocationcb);
|
||||
vk_debugucallback = VK_NULL_HANDLE;
|
||||
}
|
||||
#endif
|
||||
#ifdef VK_EXT_debug_report
|
||||
if (vk_debugcallback)
|
||||
{
|
||||
vkDestroyDebugReportCallbackEXT(vk.instance, vk_debugcallback, vkallocationcb);
|
||||
vk_debugcallback = VK_NULL_HANDLE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (vk.surface)
|
||||
vkDestroySurfaceKHR(vk.instance, vk.surface, vkallocationcb);
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#endif
|
||||
|
||||
#define VK_NO_PROTOTYPES
|
||||
#include "../vulkan/vulkan.h"
|
||||
#include <vulkan/vulkan.h>
|
||||
|
||||
#if defined(_MSC_VER) && !defined(UINT64_MAX)
|
||||
#define UINT64_MAX _UI64_MAX
|
||||
|
@ -51,6 +51,12 @@
|
|||
#endif
|
||||
#define VKInstArchFuncs VKInstWin32Funcs VKInstXLibFuncs VKInstXCBFuncs VKInstWaylandFuncs
|
||||
|
||||
#ifdef VK_EXT_debug_utils
|
||||
#define VKDebugFuncs \
|
||||
VKFunc(SetDebugUtilsObjectNameEXT)
|
||||
#else
|
||||
#define VKDebugFuncs
|
||||
#endif
|
||||
|
||||
//funcs needed for creating an instance
|
||||
#define VKInstFuncs \
|
||||
|
@ -61,7 +67,6 @@
|
|||
//funcs specific to an instance
|
||||
#define VKInst2Funcs \
|
||||
VKFunc(EnumeratePhysicalDevices) \
|
||||
VKFunc(EnumeratePhysicalDeviceGroupsKHX) \
|
||||
VKFunc(EnumerateDeviceExtensionProperties) \
|
||||
VKFunc(GetPhysicalDeviceProperties) \
|
||||
VKFunc(GetPhysicalDeviceQueueFamilyProperties) \
|
||||
|
@ -75,6 +80,7 @@
|
|||
VKFunc(DestroySurfaceKHR) \
|
||||
VKFunc(CreateDevice) \
|
||||
VKFunc(DestroyInstance) \
|
||||
VKDebugFuncs \
|
||||
VKInstArchFuncs
|
||||
|
||||
//funcs specific to a device
|
||||
|
@ -169,7 +175,6 @@
|
|||
VKFunc(CreateImageView) \
|
||||
VKFunc(DestroyImageView)
|
||||
|
||||
|
||||
//all vulkan funcs
|
||||
#define VKFuncs \
|
||||
VKInstFuncs \
|
||||
|
@ -488,7 +493,7 @@ struct stagingbuf
|
|||
size_t size;
|
||||
VkBufferUsageFlags usage;
|
||||
};
|
||||
vk_image_t VK_CreateTexture2DArray(uint32_t width, uint32_t height, uint32_t layers, uint32_t mips, uploadfmt_t encoding, unsigned int type, qboolean rendertarget);
|
||||
vk_image_t VK_CreateTexture2DArray(uint32_t width, uint32_t height, uint32_t layers, uint32_t mips, uploadfmt_t encoding, unsigned int type, qboolean rendertarget, const char *debugname);
|
||||
void set_image_layout(VkCommandBuffer cmd, VkImage image, VkImageAspectFlags aspectMask, VkImageLayout old_image_layout, VkAccessFlags srcaccess, VkPipelineStageFlagBits srcstagemask, VkImageLayout new_image_layout, VkAccessFlags dstaccess, VkPipelineStageFlagBits dststagemask);
|
||||
void VK_CreateSampler(unsigned int flags, vk_image_t *img);
|
||||
void *VKBE_CreateStagingBuffer(struct stagingbuf *n, size_t size, VkBufferUsageFlags usage);
|
||||
|
|
|
@ -20,7 +20,10 @@ Unless you're doing complex stuff like any of the above, there's probably not al
|
|||
|
||||
|
||||
Command File Format:
|
||||
output <FILENAME> - specified the output file name. you should only have one of these.
|
||||
output <FILENAME> - specifies the output file name. you should only have one of each type of output.
|
||||
output_qmdl <FILENAME> - specifies which file to write a quake1-format model. May only occur once.
|
||||
output_md16 <FILENAME> - specifies the filename to write a quakeforge 16-bit md16 model to (a upgraded variation of quake's format). May only occur once.
|
||||
output_md3 <FILENAME> - specifies the filename to write a quake3 md3 file to. May only occur once.
|
||||
exec <FILENAME> - exec the specified command file, before parsing the rest of the current file.
|
||||
hitbox <BODY NUM> <BONE NAME> <MIN POS VECTOR> <MAX POS VECTOR> - generates a hitmesh as a bbox centered around the bone in the base pose (the hitbox will rotate/move with animations). The bodynum will be visible to gamecode, and may merge with other hitboxes with the same group.
|
||||
modelflags <NAME OR HEX> - enables the specified bit in the iqm header. supported names include q1_rocket, q1_grenade, q1_gib, q1_rotate, q1_tracer1, q1_zomgib, q1_tracer2, q1_tracer3
|
||||
|
@ -53,4 +56,4 @@ Anim/Import Properties:
|
|||
scale <SCALER> - rescales the model
|
||||
origin <X> <Y> <Z> - moves the thing
|
||||
event [ANIM,]<POSE[.FRAC]> <EVENTCODE> <"EVENTDATA"> - embeds event info within the animation, for stuff like footsteps. How this is used depends on the engine... If used at global scope, can be reset with 'event reset' in order to not apply to later files.
|
||||
|
||||
|
||||
|
|
319
iqm/iqm.cpp
319
iqm/iqm.cpp
|
@ -4283,6 +4283,243 @@ bool writeiqm(const char *filename)
|
|||
}
|
||||
|
||||
|
||||
uchar qmdl_bestnorm(Vec3 &v)
|
||||
{
|
||||
//FIXME
|
||||
return 0;
|
||||
}
|
||||
struct qmdl_vertex_t
|
||||
{
|
||||
unsigned char v[3];
|
||||
unsigned char normalIndex;
|
||||
};
|
||||
template<int md16> bool writemdl(const char *filename)
|
||||
{
|
||||
if (meshes.length() != 1)
|
||||
{
|
||||
conoutf("warning: mdl output requires exactly one mesh");
|
||||
return false; //must have ONE mesh only.
|
||||
}
|
||||
auto mesh = meshes[0];
|
||||
vertexarray *texcoords = NULL;
|
||||
vertexarray *vertcoords = NULL;
|
||||
vertexarray *vertnorm = NULL;
|
||||
uint skinwidth = 0;
|
||||
uint skinheight = 0;
|
||||
Vec3 offset={0,0,0};
|
||||
Vec3 scale={1,1,1};
|
||||
uint numskins = 0;
|
||||
vector<uchar> skindata;
|
||||
|
||||
loopv(varrays)
|
||||
{
|
||||
if(varrays[i].type == IQM_TEXCOORD && varrays[i].format == IQM_FLOAT && varrays[i].count == 2)
|
||||
texcoords = &varrays[i];
|
||||
if(varrays[i].type == IQM_POSITION && varrays[i].format == IQM_FLOAT && varrays[i].count == 3)
|
||||
vertcoords = &varrays[i];
|
||||
if(varrays[i].type == IQM_NORMAL && varrays[i].format == IQM_FLOAT && varrays[i].count == 3)
|
||||
vertnorm = &varrays[i];
|
||||
// if(varrays[i].type == IQM_BLENDINDEXES && varrays[i].format == IQM_BYTE && varrays[i].count == 4)
|
||||
// vertbones = &varrays[i];
|
||||
// if(varrays[i].type == IQM_BLENDWEIGHTS && varrays[i].format == IQM_FLOAT && varrays[i].count == 4)
|
||||
// vertweights = &varrays[i];
|
||||
}
|
||||
if (!texcoords)
|
||||
{
|
||||
conoutf("warning: mdl output requires a float texcoord array");
|
||||
return false; //must have some vertex coords...
|
||||
}
|
||||
float *tcdata = (float*)texcoords->vdata.getbuf();
|
||||
|
||||
skinwidth = 4;
|
||||
skinheight = 4;
|
||||
memset(skindata.reserve(skinwidth*skinheight), 15, skinwidth*skinheight);
|
||||
skindata.advance(skinwidth*skinheight);
|
||||
numskins++;
|
||||
|
||||
//we're going to need the transformed pose data, without any bone weights getting in the way.
|
||||
vector<Vec3> vpos, vnorm;
|
||||
Vec3 min={FLT_MAX,FLT_MAX,FLT_MAX}, max={-FLT_MAX,-FLT_MAX,-FLT_MAX};
|
||||
loopv(anims)
|
||||
{
|
||||
anim &a = anims[i];
|
||||
Vec3 *outv = vpos.reserve(mesh.numverts*a.numframes);
|
||||
Vec3 *outn = vnorm.reserve(mesh.numverts*a.numframes);
|
||||
|
||||
Vec3 *invert = (Vec3*)vertcoords->vdata.getbuf();
|
||||
Vec3 *innorm = (Vec3*)vertnorm->vdata.getbuf();
|
||||
// uchar *inbones = (uchar*)vertbones->vdata.getbuf();
|
||||
// Vec4 *inweights = (Vec4*)vertweights->vdata.getbuf();
|
||||
|
||||
for (int j = 0; j < a.numframes; j++)
|
||||
{
|
||||
//FIXME: generate bone matricies
|
||||
for (int i = mesh.firstvert; i < mesh.numverts; i++, outv++, outn++)
|
||||
{
|
||||
//FIXME: generate vert's matrix
|
||||
|
||||
//transform each vert
|
||||
*outv = invert[i];
|
||||
|
||||
//bound it to find the model's extents
|
||||
for (uint c = 0; c < 3; c++)
|
||||
{
|
||||
if (min.v[c] > outv->v[c])
|
||||
min.v[c] = outv->v[c];
|
||||
if (max.v[c] < outv->v[c])
|
||||
max.v[c] = outv->v[c];
|
||||
}
|
||||
|
||||
*outn = innorm[i];
|
||||
}
|
||||
vpos.advance(mesh.numverts);
|
||||
vnorm.advance(mesh.numverts);
|
||||
}
|
||||
}
|
||||
|
||||
offset = -min;
|
||||
scale = (max-min)/255; //ignore low order info here
|
||||
|
||||
stream *f = openfile(filename, "wb");
|
||||
if(!f) return false;
|
||||
|
||||
if (md16)
|
||||
f->putlil((uint)(('M'<<0)|('D'<<8)|('1'<<16)|('6'<<24)));
|
||||
else
|
||||
f->putlil((uint)(('I'<<0)|('D'<<8)|('P'<<16)|('O'<<24)));
|
||||
f->putlil((uint)6); //version
|
||||
f->putlil((float)scale[0]);
|
||||
f->putlil((float)scale[1]);
|
||||
f->putlil((float)scale[2]);
|
||||
f->putlil((float)offset[0]);
|
||||
f->putlil((float)offset[1]);
|
||||
f->putlil((float)offset[2]);
|
||||
f->putlil(0.f); //radius
|
||||
f->putlil(0.f); //eyeposx, never used afaik
|
||||
f->putlil(0.f); //eyeposy
|
||||
f->putlil(0.f); //eyeposz
|
||||
|
||||
f->putlil((uint)numskins);
|
||||
f->putlil((uint)skinwidth);
|
||||
f->putlil((uint)skinheight);
|
||||
|
||||
f->putlil((uint)mesh.numverts);
|
||||
f->putlil((uint)mesh.numtris);
|
||||
f->putlil((uint)anims.length()); //numanims
|
||||
|
||||
f->putlil((uint)0); //synctype
|
||||
f->putlil((uint)modelflags); //flags
|
||||
f->putlil(0.f); //size
|
||||
|
||||
//skins
|
||||
for (int i = 0; i < numskins; i++)
|
||||
{
|
||||
f->putlil((uint)0); //ALIAS_SKIN_SINGLE
|
||||
f->write(skindata.getbuf()+i*skinwidth*skinheight, skinwidth*skinheight);
|
||||
}
|
||||
//texcoords
|
||||
for (int i = mesh.firstvert; i < mesh.numverts; i++)
|
||||
{
|
||||
f->putlil((uint)(0?32:0)); //onseam. no verts are ever onseam for us, as we don't do that nonsense here.
|
||||
f->putlil((int)((tcdata[i*2+0]+.5)*skinwidth)); //mdl texcoords are ints, in texels. which sucks, but what can you do...
|
||||
f->putlil((int)((tcdata[i*2+1]+.5)*skinheight));
|
||||
}
|
||||
//tris
|
||||
for (int i = mesh.firsttri; i < mesh.firsttri+mesh.numtris; i++)
|
||||
{
|
||||
f->putlil((uint)1); //faces front. All are effectively front-facing for us. This avoids annoying tc additions.
|
||||
f->putlil((uint)triangles[i].vert[0]);
|
||||
f->putlil((uint)triangles[i].vert[1]);
|
||||
f->putlil((uint)triangles[i].vert[2]);
|
||||
}
|
||||
//animations
|
||||
vector<qmdl_vertex_t> high, low;
|
||||
size_t voffset = 0;
|
||||
loopv(anims)
|
||||
{
|
||||
anim &a = anims[i];
|
||||
for (int j = 0; j < a.numframes; j++)
|
||||
{
|
||||
qmdl_vertex_t *th=high.reserve(mesh.numverts),*tl=low.reserve(mesh.numverts);
|
||||
for (int i = mesh.firstvert; i < mesh.numverts; i++, th++, tl++)
|
||||
{
|
||||
int l;
|
||||
for (uint c = 0; c < 3; c++)
|
||||
{
|
||||
l = (((vpos[voffset][c]-offset[c])*256) / scale[c]);
|
||||
if (l<0) l = 0;
|
||||
if (l > 0xff00) l = 0xff00; //0xffff would exceed the bounds values, so don't use it.
|
||||
th->v[c] = l>>8;
|
||||
tl->v[c] = l&0xff;
|
||||
}
|
||||
tl->normalIndex = th->normalIndex = qmdl_bestnorm(vnorm[voffset]);
|
||||
|
||||
voffset++;
|
||||
}
|
||||
high.advance(mesh.numverts);
|
||||
low.advance(mesh.numverts);
|
||||
}
|
||||
}
|
||||
voffset = 0;
|
||||
loopv(anims)
|
||||
{
|
||||
anim &a = anims[i];
|
||||
if (a.numframes == 1)
|
||||
f->putlil((uint)0); //single-pose type
|
||||
else
|
||||
{
|
||||
f->putlil((uint)1); //anim type
|
||||
f->putlil((uint)a.numframes);
|
||||
|
||||
qmdl_vertex_t min={{255,255,255}}, max={{0,0,0}};
|
||||
for (uint k = 0; k < mesh.numverts*a.numframes; k++)
|
||||
{
|
||||
for (uint c = 0; c < 3; c++)
|
||||
{
|
||||
if (min.v[c] > high[voffset+k].v[c])
|
||||
min.v[c] = high[voffset+k].v[c];
|
||||
if (max.v[c] < high[voffset+k].v[c])
|
||||
max.v[c] = high[voffset+k].v[c];
|
||||
}
|
||||
}
|
||||
f->put(min);
|
||||
f->put(max);
|
||||
for (int j = 0; j < a.numframes; j++)
|
||||
f->putlil(1.0f/a.fps); //intervals. we use the same value for each
|
||||
}
|
||||
|
||||
for (int j = 0; j < a.numframes; j++)
|
||||
{
|
||||
char name[16]={0};
|
||||
qmdl_vertex_t min={{255,255,255}}, max={{0,0,0}};
|
||||
for (uint k = 0; k < mesh.numverts; k++)
|
||||
{
|
||||
for (uint c = 0; c < 3; c++)
|
||||
{
|
||||
if (min.v[c] > high[voffset+k].v[c])
|
||||
min.v[c] = high[voffset+k].v[c];
|
||||
if (max.v[c] < high[voffset+k].v[c])
|
||||
max.v[c] = high[voffset+k].v[c];
|
||||
}
|
||||
}
|
||||
f->put(min);
|
||||
f->put(max);
|
||||
|
||||
strncpy(name, &stringdata[a.name], sizeof(name));
|
||||
f->put(name);
|
||||
|
||||
f->write(&high[voffset], sizeof(qmdl_vertex_t)*mesh.numverts);
|
||||
if (md16)
|
||||
f->write(&low[voffset], sizeof(qmdl_vertex_t)*mesh.numverts);
|
||||
voffset += mesh.numverts;
|
||||
}
|
||||
}
|
||||
|
||||
delete f;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void help(bool exitstatus = EXIT_SUCCESS)
|
||||
{
|
||||
fprintf(exitstatus != EXIT_SUCCESS ? stderr : stdout,
|
||||
|
@ -4568,7 +4805,20 @@ bool parseanimfield(const char *tok, char **line, filespec &spec, bool defaults)
|
|||
return true;
|
||||
}
|
||||
|
||||
void parsecommands(char *filename, const char *&outfile, vector<filespec> &infiles, vector<hitbox> &hitboxes)
|
||||
struct
|
||||
{
|
||||
bool (*write)(const char *filename);
|
||||
const char *cmdname;
|
||||
const char *altcmdname;
|
||||
} outputtypes[] =
|
||||
{
|
||||
{writeiqm, "output_iqm"},
|
||||
{writemdl<0>, "output_qmdl"},
|
||||
{writemdl<1>, "output_md16"},
|
||||
// {writemd3, "output_md3"},
|
||||
};
|
||||
|
||||
void parsecommands(char *filename, const char *outfiles[countof(outputtypes)], vector<filespec> &infiles, vector<hitbox> &hitboxes)
|
||||
{
|
||||
filespec defaultspec;
|
||||
defaultspec.reset();
|
||||
|
@ -4586,7 +4836,7 @@ void parsecommands(char *filename, const char *&outfile, vector<filespec> &infil
|
|||
char buf[2048];
|
||||
while(f->getline(buf, sizeof(buf)))
|
||||
{
|
||||
char *tok;
|
||||
const char *tok;
|
||||
char *line = buf;
|
||||
tok = mystrtok(&line);
|
||||
if (tok && *tok == '$')
|
||||
|
@ -4600,8 +4850,6 @@ void parsecommands(char *filename, const char *&outfile, vector<filespec> &infil
|
|||
}
|
||||
// else if (!strcasecmp(tok, "outputdir"))
|
||||
// (void)mystrtok(&line);
|
||||
else if (!strcasecmp(tok, "output"))
|
||||
outfile = newstring(mystrtok(&line));
|
||||
else if (!strcasecmp(tok, "hitbox") || !strcasecmp(tok, "hbox"))
|
||||
{
|
||||
hitbox &hb = hitboxes.add();
|
||||
|
@ -4613,7 +4861,7 @@ void parsecommands(char *filename, const char *&outfile, vector<filespec> &infil
|
|||
hb.maxs[i] = atof(mystrtok(&line));
|
||||
}
|
||||
else if (!strcasecmp(tok, "exec"))
|
||||
parsecommands(mystrtok(&line), outfile, infiles, hitboxes);
|
||||
parsecommands(mystrtok(&line), outfiles, infiles, hitboxes);
|
||||
else if (!strcasecmp(tok, "modelflags"))
|
||||
{
|
||||
bitnames modelflagnames[] = {
|
||||
|
@ -4691,10 +4939,34 @@ void parsecommands(char *filename, const char *&outfile, vector<filespec> &infil
|
|||
|
||||
infiles.add(inspec);
|
||||
}
|
||||
else if (*tok)
|
||||
else
|
||||
{
|
||||
printf("unsupported command \"%s\"\n", tok);
|
||||
continue;
|
||||
size_t n, j;
|
||||
if (!strcasecmp(tok, "output"))
|
||||
tok = "output_iqm";
|
||||
for (n = 0; n < countof(outputtypes); n++)
|
||||
{
|
||||
if (!strcasecmp(tok, outputtypes[n].cmdname))
|
||||
{
|
||||
outfiles[n] = newstring(mystrtok(&line));
|
||||
for (j = 0; j < countof(outputtypes); j++)
|
||||
{
|
||||
if (n!=j && outfiles[j] && !strcasecmp(outfiles[n], outfiles[j]))
|
||||
{
|
||||
printf("cancelling %s\n", outputtypes[j].cmdname);
|
||||
outfiles[j] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
tok = "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*tok)
|
||||
{
|
||||
printf("unsupported command \"%s\"\n", tok);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ((tok=mystrtok(&line)))
|
||||
|
@ -4711,14 +4983,14 @@ int main(int argc, char **argv)
|
|||
vector<filespec> infiles;
|
||||
vector<hitbox> hitboxes;
|
||||
filespec inspec;
|
||||
const char *outfile = NULL;
|
||||
const char *outfiles[countof(outputtypes)] = {};
|
||||
for(int i = 1; i < argc; i++)
|
||||
{
|
||||
if(argv[i][0] == '-')
|
||||
{
|
||||
if(argv[i][1] == '-')
|
||||
{
|
||||
if(!strcasecmp(&argv[i][2], "cmd")) { if(i + 1 < argc) parsecommands(argv[++i], outfile, infiles, hitboxes); }
|
||||
if(!strcasecmp(&argv[i][2], "cmd")) { if(i + 1 < argc) parsecommands(argv[++i], outfiles, infiles, hitboxes); }
|
||||
else if(!strcasecmp(&argv[i][2], "noext")) noext = true;
|
||||
else if(!strcasecmp(&argv[i][2], "fps")) { if(i + 1 < argc) inspec.fps = atof(argv[++i]); }
|
||||
else if(!strcasecmp(&argv[i][2], "name")) { if(i + 1 < argc) inspec.name = argv[++i]; }
|
||||
|
@ -4762,9 +5034,9 @@ int main(int argc, char **argv)
|
|||
{
|
||||
const char *type = strrchr(argv[i], '.');
|
||||
if (type && (!strcasecmp(type, ".cmd")||!strcasecmp(type, ".cfg")||!strcasecmp(type, ".txt")||!strcasecmp(type, ".qc"))) //.qc to humour halflife fanboys
|
||||
parsecommands(argv[i], outfile, infiles, hitboxes);
|
||||
else if(!outfile)
|
||||
outfile = argv[i];
|
||||
parsecommands(argv[i], outfiles, infiles, hitboxes);
|
||||
else if(!outfiles[0] && !outfiles[1] && !outfiles[2])
|
||||
outfiles[0] = argv[i]; //first arg is the output name, if its not an export script thingie.
|
||||
else
|
||||
{
|
||||
infiles.add(inspec).file = argv[i];
|
||||
|
@ -4773,8 +5045,10 @@ int main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
if(!outfile) fatal("no output file specified");
|
||||
else if(infiles.empty()) fatal("no input files specified");
|
||||
size_t n;
|
||||
for (n = 0; n < countof(outputtypes) && !outfiles[n]; n++);
|
||||
if(n == countof(outfiles)) fatal("no output file specified");
|
||||
if(infiles.empty()) fatal("no input files specified");
|
||||
|
||||
if(gscale != 1) printf("scale: %f\n", escale);
|
||||
if(gmeshtrans != Vec3(0, 0, 0)) printf("mesh translate: %f, %f, %f\n", gmeshtrans.x, gmeshtrans.y, gmeshtrans.z);
|
||||
|
@ -4833,13 +5107,18 @@ int main(int argc, char **argv)
|
|||
if (!quiet)
|
||||
conoutf("");
|
||||
|
||||
if(writeiqm(outfile))
|
||||
for (size_t n = 0; n < countof(outputtypes); n++)
|
||||
{
|
||||
if (!quiet)
|
||||
conoutf("exported: %s", outfile);
|
||||
if (outfiles[n] != NULL)
|
||||
{
|
||||
if(outputtypes[n].write(outfiles[n]))
|
||||
{
|
||||
if (!quiet)
|
||||
conoutf("exported: %s", outfiles[n]);
|
||||
}
|
||||
else fatal("failed writing: %s", outfiles[n]);
|
||||
}
|
||||
}
|
||||
else fatal("failed writing: %s", outfile);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <stdarg.h>
|
||||
#include <limits.h>
|
||||
#include <assert.h>
|
||||
#include <float.h>
|
||||
#include "iqm.h"
|
||||
|
||||
#define ASSERT(c) if(c) {}
|
||||
|
@ -76,6 +77,7 @@ static inline T min(T a, T b)
|
|||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
#define countof(n) (sizeof(n)/sizeof(n[0]))
|
||||
#define clamp(a,b,c) (max(b, min(a, c)))
|
||||
|
||||
#define loop(v,m) for(int v = 0; v<int(m); v++)
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
static cvar_t *ffmpeg_audiodecoder;
|
||||
|
||||
#define HAVE_DECOUPLED_API (LIBAVCODEC_VERSION_MAJOR>57 || (LIBAVCODEC_VERSION_MAJOR==57&&LIBAVCODEC_VERSION_MINOR>=36))
|
||||
|
||||
struct avaudioctx
|
||||
{
|
||||
//raw file
|
||||
|
@ -56,6 +58,127 @@ static void S_AV_Purge(sfx_t *s)
|
|||
|
||||
memset(&s->decoder, 0, sizeof(s->decoder));
|
||||
}
|
||||
static void S_AV_ReadFrame(struct avaudioctx *ctx)
|
||||
{ //reads an audioframe and spits its data into the output sound file for the game engine to use.
|
||||
int width = 2;
|
||||
int channels = ctx->pACodecCtx->channels;
|
||||
unsigned int auddatasize = av_samples_get_buffer_size(NULL, ctx->pACodecCtx->channels, ctx->pAFrame->nb_samples, ctx->pACodecCtx->sample_fmt, 1);
|
||||
void *auddata = ctx->pAFrame->data[0];
|
||||
switch(ctx->pACodecCtx->sample_fmt)
|
||||
{ //we don't support planar audio. we just treat it as mono instead.
|
||||
default:
|
||||
auddatasize = 0;
|
||||
break;
|
||||
case AV_SAMPLE_FMT_U8P:
|
||||
auddatasize /= channels;
|
||||
channels = 1;
|
||||
case AV_SAMPLE_FMT_U8:
|
||||
width = 1;
|
||||
break;
|
||||
case AV_SAMPLE_FMT_S16P:
|
||||
auddatasize /= channels;
|
||||
channels = 1;
|
||||
case AV_SAMPLE_FMT_S16:
|
||||
width = 2;
|
||||
break;
|
||||
|
||||
case AV_SAMPLE_FMT_FLTP:
|
||||
//FIXME: support float audio internally.
|
||||
{
|
||||
float *in[2] = {(float*)ctx->pAFrame->data[0],(float*)ctx->pAFrame->data[1]};
|
||||
signed short *out = (void*)auddata;
|
||||
int v;
|
||||
unsigned int i, c;
|
||||
unsigned int frames = ctx->pAFrame->nb_samples;
|
||||
if (channels > 2)
|
||||
channels = 2;
|
||||
for (i = 0; i < frames; i++)
|
||||
{
|
||||
for (c = 0; c < channels; c++)
|
||||
{
|
||||
v = (short)(in[c][i]*32767);
|
||||
if (v < -32767)
|
||||
v = -32767;
|
||||
else if (v > 32767)
|
||||
v = 32767;
|
||||
*out++ = v;
|
||||
}
|
||||
}
|
||||
width = sizeof(*out);
|
||||
auddatasize = frames*width*channels;
|
||||
}
|
||||
break;
|
||||
case AV_SAMPLE_FMT_FLT:
|
||||
//FIXME: support float audio internally.
|
||||
{
|
||||
float *in = (void*)auddata;
|
||||
signed short *out = (void*)auddata;
|
||||
int v;
|
||||
unsigned int i;
|
||||
for (i = 0; i < auddatasize/sizeof(*in); i++)
|
||||
{
|
||||
v = (short)(in[i]*32767);
|
||||
if (v < -32767)
|
||||
v = -32767;
|
||||
else if (v > 32767)
|
||||
v = 32767;
|
||||
out[i] = v;
|
||||
}
|
||||
auddatasize/=2;
|
||||
width = 2;
|
||||
}
|
||||
|
||||
case AV_SAMPLE_FMT_DBLP:
|
||||
auddatasize /= channels;
|
||||
channels = 1;
|
||||
case AV_SAMPLE_FMT_DBL:
|
||||
{
|
||||
double *in = (double*)auddata;
|
||||
signed short *out = (void*)auddata;
|
||||
int v;
|
||||
unsigned int i;
|
||||
for (i = 0; i < auddatasize/sizeof(*in); i++)
|
||||
{
|
||||
v = (short)(in[i]*32767);
|
||||
if (v < -32767)
|
||||
v = -32767;
|
||||
else if (v > 32767)
|
||||
v = 32767;
|
||||
out[i] = v;
|
||||
}
|
||||
auddatasize/=4;
|
||||
width = 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (ctx->samples_channels != channels || ctx->samples_speed != ctx->pACodecCtx->sample_rate || ctx->samples_width != width)
|
||||
{ //something changed, update
|
||||
ctx->samples_channels = channels;
|
||||
ctx->samples_speed = ctx->pACodecCtx->sample_rate;
|
||||
ctx->samples_width = width;
|
||||
|
||||
//and discard any decoded audio. this might loose some.
|
||||
ctx->samples_start += ctx->samples_count;
|
||||
ctx->samples_count = 0;
|
||||
}
|
||||
if (ctx->samples_max < (ctx->samples_count*ctx->samples_width*ctx->samples_channels)+auddatasize)
|
||||
{
|
||||
ctx->samples_max = (ctx->samples_count*ctx->samples_width*ctx->samples_channels)+auddatasize;
|
||||
ctx->samples_max *= 2; //slop
|
||||
ctx->samples_buffer = realloc(ctx->samples_buffer, ctx->samples_max);
|
||||
}
|
||||
if (width == 1)
|
||||
{ //FTE uses signed 8bit audio. ffmpeg uses unsigned 8bit audio. *sigh*.
|
||||
char *out = (char*)(ctx->samples_buffer + ctx->samples_count*(ctx->samples_width*ctx->samples_channels));
|
||||
unsigned char *in = auddata;
|
||||
int i;
|
||||
for (i = 0; i < auddatasize; i++)
|
||||
out[i] = in[i]-128;
|
||||
}
|
||||
else
|
||||
memcpy(ctx->samples_buffer + ctx->samples_count*(ctx->samples_width*ctx->samples_channels), auddata, auddatasize);
|
||||
ctx->samples_count += auddatasize/(ctx->samples_width*ctx->samples_channels);
|
||||
}
|
||||
static sfxcache_t *S_AV_Locate(sfx_t *sfx, sfxcache_t *buf, ssamplepos_t start, int length)
|
||||
{ //warning: can be called on a different thread.
|
||||
struct avaudioctx *ctx = (struct avaudioctx*)sfx->decoder.buf;
|
||||
|
@ -67,12 +190,21 @@ static sfxcache_t *S_AV_Locate(sfx_t *sfx, sfxcache_t *buf, ssamplepos_t start,
|
|||
|
||||
curtime = start + length;
|
||||
|
||||
// curtime = (mediatime * ctx->denum) / ctx->num;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (ctx->lasttime > curtime)
|
||||
break;
|
||||
if (start < ctx->samples_start)
|
||||
break; //o.O rewind!
|
||||
|
||||
if (ctx->samples_start+ctx->samples_count > curtime)
|
||||
break; //no need yet.
|
||||
|
||||
#ifdef HAVE_DECOUPLED_API
|
||||
if(0==avcodec_receive_frame(ctx->pACodecCtx, ctx->pAFrame))
|
||||
{
|
||||
S_AV_ReadFrame(ctx);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
// We're ahead of the previous frame. try and read the next.
|
||||
if (av_read_frame(ctx->pFormatCtx, &packet) < 0)
|
||||
|
@ -81,11 +213,14 @@ static sfxcache_t *S_AV_Locate(sfx_t *sfx, sfxcache_t *buf, ssamplepos_t start,
|
|||
// Is this a packet from the video stream?
|
||||
if(packet.stream_index==ctx->audioStream)
|
||||
{
|
||||
#ifdef HAVE_DECOUPLED_API
|
||||
avcodec_send_packet(ctx->pACodecCtx, &packet);
|
||||
#else
|
||||
int okay;
|
||||
int len;
|
||||
void *odata = packet.data;
|
||||
while (packet.size > 0)
|
||||
{
|
||||
{ //this old api only decodes part of the packet with each itteration, so keep reading until we decoded the entire thing.
|
||||
okay = false;
|
||||
len = avcodec_decode_audio4(ctx->pACodecCtx, ctx->pAFrame, &okay, &packet);
|
||||
if (len < 0)
|
||||
|
@ -93,105 +228,10 @@ static sfxcache_t *S_AV_Locate(sfx_t *sfx, sfxcache_t *buf, ssamplepos_t start,
|
|||
packet.size -= len;
|
||||
packet.data += len;
|
||||
if (okay)
|
||||
{
|
||||
int width = 2;
|
||||
int channels = ctx->pACodecCtx->channels;
|
||||
unsigned int auddatasize = av_samples_get_buffer_size(NULL, ctx->pACodecCtx->channels, ctx->pAFrame->nb_samples, ctx->pACodecCtx->sample_fmt, 1);
|
||||
void *auddata = ctx->pAFrame->data[0];
|
||||
switch(ctx->pACodecCtx->sample_fmt)
|
||||
{ //we don't support planar audio. we just treat it as mono instead.
|
||||
default:
|
||||
auddatasize = 0;
|
||||
break;
|
||||
case AV_SAMPLE_FMT_U8P:
|
||||
auddatasize /= channels;
|
||||
channels = 1;
|
||||
case AV_SAMPLE_FMT_U8:
|
||||
width = 1;
|
||||
break;
|
||||
case AV_SAMPLE_FMT_S16P:
|
||||
auddatasize /= channels;
|
||||
channels = 1;
|
||||
case AV_SAMPLE_FMT_S16:
|
||||
width = 2;
|
||||
break;
|
||||
|
||||
case AV_SAMPLE_FMT_FLTP:
|
||||
auddatasize /= channels;
|
||||
channels = 1;
|
||||
case AV_SAMPLE_FMT_FLT:
|
||||
//FIXME: support float audio internally.
|
||||
{
|
||||
float *in = (void*)auddata;
|
||||
signed short *out = (void*)auddata;
|
||||
int v;
|
||||
unsigned int i;
|
||||
for (i = 0; i < auddatasize/sizeof(*in); i++)
|
||||
{
|
||||
v = (short)(in[i]*32767);
|
||||
if (v < -32767)
|
||||
v = -32767;
|
||||
else if (v > 32767)
|
||||
v = 32767;
|
||||
out[i] = v;
|
||||
}
|
||||
auddatasize/=2;
|
||||
width = 2;
|
||||
}
|
||||
|
||||
case AV_SAMPLE_FMT_DBLP:
|
||||
auddatasize /= channels;
|
||||
channels = 1;
|
||||
case AV_SAMPLE_FMT_DBL:
|
||||
{
|
||||
double *in = (double*)auddata;
|
||||
signed short *out = (void*)auddata;
|
||||
int v;
|
||||
unsigned int i;
|
||||
for (i = 0; i < auddatasize/sizeof(*in); i++)
|
||||
{
|
||||
v = (short)(in[i]*32767);
|
||||
if (v < -32767)
|
||||
v = -32767;
|
||||
else if (v > 32767)
|
||||
v = 32767;
|
||||
out[i] = v;
|
||||
}
|
||||
auddatasize/=4;
|
||||
width = 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (ctx->samples_channels != channels || ctx->samples_speed != ctx->pACodecCtx->sample_rate || ctx->samples_width != width)
|
||||
{ //something changed, update
|
||||
ctx->samples_channels = channels;
|
||||
ctx->samples_speed = ctx->pACodecCtx->sample_rate;
|
||||
ctx->samples_width = width;
|
||||
|
||||
//and discard any decoded audio. this might loose some.
|
||||
ctx->samples_start += ctx->samples_count;
|
||||
ctx->samples_count = 0;
|
||||
}
|
||||
if (ctx->samples_max < (ctx->samples_count*ctx->samples_width*ctx->samples_channels)+auddatasize)
|
||||
{
|
||||
ctx->samples_max = (ctx->samples_count*ctx->samples_width*ctx->samples_channels)+auddatasize;
|
||||
ctx->samples_max *= 2; //slop
|
||||
ctx->samples_buffer = realloc(ctx->samples_buffer, ctx->samples_max);
|
||||
}
|
||||
if (width == 1)
|
||||
{ //FTE uses signed 8bit audio. ffmpeg uses unsigned 8bit audio. *sigh*.
|
||||
char *out = (char*)(ctx->samples_buffer + ctx->samples_count*(ctx->samples_width*ctx->samples_channels));
|
||||
unsigned char *in = auddata;
|
||||
int i;
|
||||
for (i = 0; i < auddatasize; i++)
|
||||
out[i] = in[i]-128;
|
||||
}
|
||||
else
|
||||
memcpy(ctx->samples_buffer + ctx->samples_count*(ctx->samples_width*ctx->samples_channels), auddata, auddatasize);
|
||||
ctx->samples_count += auddatasize/(ctx->samples_width*ctx->samples_channels);
|
||||
}
|
||||
S_AV_ReadFrame(ctx);
|
||||
}
|
||||
packet.data = odata;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Free the packet that was allocated by av_read_frame
|
||||
|
@ -319,16 +359,29 @@ static qboolean QDECL S_LoadAVSound (sfx_t *s, qbyte *data, size_t datalen, int
|
|||
{
|
||||
ctx->audioStream=-1;
|
||||
for(i=0; i<ctx->pFormatCtx->nb_streams; i++)
|
||||
#if LIBAVFORMAT_VERSION_MAJOR >= 57
|
||||
if(ctx->pFormatCtx->streams[i]->codecpar->codec_type==AVMEDIA_TYPE_AUDIO)
|
||||
#else
|
||||
if(ctx->pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO)
|
||||
#endif
|
||||
{
|
||||
ctx->audioStream=i;
|
||||
break;
|
||||
}
|
||||
if(ctx->audioStream!=-1)
|
||||
{
|
||||
#if LIBAVFORMAT_VERSION_MAJOR >= 57
|
||||
pCodec=avcodec_find_decoder(ctx->pFormatCtx->streams[ctx->audioStream]->codecpar->codec_id);
|
||||
ctx->pACodecCtx = avcodec_alloc_context3(pCodec);
|
||||
if (avcodec_parameters_to_context(ctx->pACodecCtx, ctx->pFormatCtx->streams[ctx->audioStream]->codecpar) < 0)
|
||||
{
|
||||
avcodec_free_context(&ctx->pACodecCtx);
|
||||
pCodec = NULL;
|
||||
}
|
||||
#else
|
||||
ctx->pACodecCtx=ctx->pFormatCtx->streams[ctx->audioStream]->codec;
|
||||
pCodec=avcodec_find_decoder(ctx->pACodecCtx->codec_id);
|
||||
|
||||
#endif
|
||||
ctx->pAFrame=av_frame_alloc();
|
||||
if(pCodec!=NULL && ctx->pAFrame && avcodec_open2(ctx->pACodecCtx, pCodec, NULL) >= 0)
|
||||
{ //success
|
||||
|
@ -358,11 +411,10 @@ static qboolean AVAudio_Init(void)
|
|||
{
|
||||
if (!pPlug_ExportNative("S_LoadSound", S_LoadAVSound))
|
||||
{
|
||||
ffmpeg_audiodecoder = pCvar_GetNVFDG("ffmpeg_audiodecoder_wip", "0", 0, "Enables the use of ffmpeg's decoder for pure audio files.", "ffmpeg");
|
||||
|
||||
Con_Printf("avplug: Engine doesn't support audio decoder plugins\n");
|
||||
return false;
|
||||
}
|
||||
ffmpeg_audiodecoder = pCvar_GetNVFDG("ffmpeg_audiodecoder_wip", "0", 0, "Enables the use of ffmpeg's decoder for pure audio files.", "ffmpeg");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -389,8 +441,10 @@ qintptr_t Plug_Init(qintptr_t *args)
|
|||
okay |= AVEnc_Init();
|
||||
if (okay)
|
||||
{
|
||||
#if ( LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(58,9,100) )
|
||||
av_register_all();
|
||||
avcodec_register_all();
|
||||
#endif
|
||||
|
||||
av_log_set_level(AV_LOG_WARNING);
|
||||
av_log_set_callback(AVLogCallback);
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#define PASSFLOAT(f) *(int*)&(f)
|
||||
|
||||
#define ARGNAMES ,sourceid, data, speed, samples, channels, width, PASSFLOAT(volume)
|
||||
BUILTIN(void, S_RawAudio, (int sourceid, void *data, int speed, int samples, int channels, int width, float volume));
|
||||
BUILTIN(void, S_RawAudio, (int sourceid, void *data, int speed, int samples, int channels, int width, float volume))
|
||||
#undef ARGNAMES
|
||||
|
||||
/*should probably try threading this, though I suppose it should be the engine doing that.*/
|
||||
|
|
|
@ -119,7 +119,7 @@ static AVStream *add_video_stream(struct encctx *ctx, AVCodec *codec, int fps, i
|
|||
return NULL;
|
||||
|
||||
st->id = ctx->fc->nb_streams-1;
|
||||
#if 1//LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 48, 0)
|
||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 48, 101)
|
||||
c = st->codec;
|
||||
#else
|
||||
c = avcodec_alloc_context3(codec);
|
||||
|
@ -304,7 +304,7 @@ static AVStream *add_audio_stream(struct encctx *ctx, AVCodec *codec, int *sampl
|
|||
return NULL;
|
||||
|
||||
st->id = ctx->fc->nb_streams-1;
|
||||
#if 1//LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 48, 0)
|
||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 48, 101)
|
||||
c = st->codec;
|
||||
#else
|
||||
c = avcodec_alloc_context3(codec);
|
||||
|
@ -613,7 +613,7 @@ static void *AVEnc_Begin (char *streamname, int videorate, int width, int height
|
|||
|
||||
ctx->fc = avformat_alloc_context();
|
||||
ctx->fc->oformat = fmt;
|
||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 6, 100) || defined(FF_API_FORMAT_FILENAME)
|
||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 6, 100)
|
||||
Q_strncatz(ctx->fc->filename, streamname, sizeof(ctx->fc->filename));
|
||||
#else
|
||||
ctx->fc->url = av_strdup(streamname);
|
||||
|
@ -684,6 +684,10 @@ static void *AVEnc_Begin (char *streamname, int videorate, int width, int height
|
|||
}
|
||||
}
|
||||
|
||||
//different formats have different metadata formats. there's no standards here.
|
||||
//av_dict_set(&ctx->fc->metadata, "TPFL", "testtest", 0);
|
||||
//FIXME: use ffmpeg's sidedata stuff, which should handle it in a generic way
|
||||
|
||||
//nearly complete, can make the file dirty now.
|
||||
err = avformat_write_header(ctx->fc, NULL);
|
||||
if (err < 0)
|
||||
|
@ -742,12 +746,13 @@ static media_encoder_funcs_t encoderfuncs =
|
|||
AVEnc_End
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
qintptr_t AVEnc_ExecuteCommand(qintptr_t *args)
|
||||
{
|
||||
char cmd[256];
|
||||
Cmd_Argv(0, cmd, sizeof(cmd));
|
||||
if (!strcmp(cmd, "avcapture"))
|
||||
pCmd_Argv(0, cmd, sizeof(cmd));
|
||||
/*
|
||||
if (!strcmp(cmd, ENCODERNAME"_configure"))
|
||||
{
|
||||
menuclear
|
||||
menualias menucallback
|
||||
|
@ -762,9 +767,48 @@ menutext 0 24 "Report in" "radio26"
|
|||
menutext 0 24 "Cancel"
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
if (!strcmp(cmd, ENCODERNAME"_nvidia"))
|
||||
{
|
||||
pCvar_SetString("capturedriver", ENCODERNAME); //be sure to use our encoder
|
||||
pCvar_SetString(ENCODERNAME"_videocodec", "h264_nvenc");
|
||||
pCvar_SetString("capturerate", "60"); //we should be able to cope with it, and the default of 30 sucks
|
||||
pCvar_SetString("capturedemowidth", "1920"); //force a specific size, some codecs need multiples of 16 or whatever.
|
||||
pCvar_SetString("capturedemoheight", "1080"); //so this avoids issues with various video codecs.
|
||||
|
||||
pCvar_SetString("capturesound", "1");
|
||||
pCvar_SetString("capturesoundchannels", "2");
|
||||
pCvar_SetString("capturesoundbits", "16");
|
||||
|
||||
Con_Printf(ENCODERNAME": now configured for nvidia's hardware encoder\n");
|
||||
Con_Printf(ENCODERNAME": use ^[/capture foo.mp4^] or ^[/capturedemo foo.mvd foo.mkv^] commands to begin capturing\n");
|
||||
}
|
||||
if (!strcmp(cmd, ENCODERNAME"_defaults"))
|
||||
{ //most formats will end up using the x264 encoder or something
|
||||
pCvar_SetString(ENCODERNAME"_format_force", "");
|
||||
pCvar_SetString(ENCODERNAME"_videocodec", "");
|
||||
pCvar_SetString(ENCODERNAME"_videobitrate", "");
|
||||
pCvar_SetString(ENCODERNAME"_videoforcewidth", "");
|
||||
pCvar_SetString(ENCODERNAME"_videoforceheight", "");
|
||||
pCvar_SetString(ENCODERNAME"_videopreset", "veryfast");
|
||||
pCvar_SetString(ENCODERNAME"_video_crf", "");
|
||||
pCvar_SetString(ENCODERNAME"_audiocodec", "");
|
||||
pCvar_SetString(ENCODERNAME"_audiobitrate", "");
|
||||
|
||||
pCvar_SetString("capturedriver", ENCODERNAME);
|
||||
pCvar_SetString("capturerate", "30");
|
||||
pCvar_SetString("capturedemowidth", "0");
|
||||
pCvar_SetString("capturedemoheight", "0");
|
||||
pCvar_SetString("capturesound", "1");
|
||||
pCvar_SetString("capturesoundchannels", "2");
|
||||
pCvar_SetString("capturesoundbits", "16");
|
||||
|
||||
Con_Printf(ENCODERNAME": capture settings reset to "ENCODERNAME" defaults\n");
|
||||
Con_Printf(ENCODERNAME": Note that some codecs may have restrictions on video sizes\n");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
qboolean AVEnc_Init(void)
|
||||
{
|
||||
|
@ -790,8 +834,11 @@ qboolean AVEnc_Init(void)
|
|||
ffmpeg_audiocodec = pCvar_GetNVFDG(ENCODERNAME"_audiocodec", "", 0, "Forces which audio encoder to use. If blank, guesses based upon container defaults.", ENCODERNAME);
|
||||
ffmpeg_audiobitrate = pCvar_GetNVFDG(ENCODERNAME"_audiobitrate", "", 0, "Specifies the target audio bitrate", ENCODERNAME);
|
||||
|
||||
// if (Plug_Export("ExecuteCommand", AVEnc_ExecuteCommand))
|
||||
// Cmd_AddCommand("avcapture");
|
||||
if (Plug_Export("ExecuteCommand", AVEnc_ExecuteCommand))
|
||||
{
|
||||
// pCmd_AddCommand(ENCODERNAME"_configure");
|
||||
pCmd_AddCommand(ENCODERNAME"_nvidia");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -162,3 +162,65 @@ void Draw_Polygon(int x, int y, vec3_t *vertices, int num_vertices, qbool fill,
|
|||
|
||||
//glue
|
||||
EBUILTIN(cvar_t*, Cvar_GetNVFDG, (const char *name, const char *defaultval, unsigned int flags, const char *description, const char *groupname));
|
||||
|
||||
|
||||
#undef sb_lines //just in case.
|
||||
#ifndef SBAR_HEIGHT
|
||||
#define SBAR_HEIGHT 24
|
||||
#define STAT_HEALTH 0
|
||||
#define STAT_WEAPONMODELI 2
|
||||
#define STAT_AMMO 3
|
||||
#define STAT_ARMOR 4
|
||||
#define STAT_WEAPONFRAME 5
|
||||
#define STAT_SHELLS 6
|
||||
#define STAT_NAILS 7
|
||||
#define STAT_ROCKETS 8
|
||||
#define STAT_CELLS 9
|
||||
#define STAT_ACTIVEWEAPON 10
|
||||
#define STAT_TOTALSECRETS 11
|
||||
#define STAT_TOTALMONSTERS 12
|
||||
#define STAT_SECRETS 13 // bumped on client side by svc_foundsecret
|
||||
#define STAT_MONSTERS 14 // bumped by svc_killedmonster
|
||||
#define STAT_ITEMS 15
|
||||
#define STAT_VIEWHEIGHT 16 //same as zquake
|
||||
#define STAT_TIME 17 //zquake
|
||||
#define STAT_MATCHSTARTTIME 18
|
||||
|
||||
#define IT_SHOTGUN (1u<<0)
|
||||
#define IT_SUPER_SHOTGUN (1u<<1)
|
||||
#define IT_NAILGUN (1u<<2)
|
||||
#define IT_SUPER_NAILGUN (1u<<3)
|
||||
|
||||
#define IT_GRENADE_LAUNCHER (1u<<4)
|
||||
#define IT_ROCKET_LAUNCHER (1u<<5)
|
||||
#define IT_LIGHTNING (1u<<6)
|
||||
#define IT_SUPER_LIGHTNING (1u<<7)
|
||||
|
||||
#define IT_SHELLS (1u<<8)
|
||||
#define IT_NAILS (1u<<9)
|
||||
#define IT_ROCKETS (1u<<10)
|
||||
#define IT_CELLS (1u<<11)
|
||||
|
||||
#define IT_AXE (1u<<12)
|
||||
|
||||
#define IT_ARMOR1 (1u<<13)
|
||||
#define IT_ARMOR2 (1u<<14)
|
||||
#define IT_ARMOR3 (1u<<15)
|
||||
|
||||
#define IT_SUPERHEALTH (1u<<16)
|
||||
|
||||
#define IT_KEY1 (1u<<17)
|
||||
#define IT_KEY2 (1u<<18)
|
||||
|
||||
#define IT_INVISIBILITY (1u<<19)
|
||||
|
||||
#define IT_INVULNERABILITY (1u<<20)
|
||||
#define IT_SUIT (1u<<21)
|
||||
#define IT_QUAD (1u<<22)
|
||||
|
||||
#define IT_SIGIL1 (1u<<28)
|
||||
|
||||
#define IT_SIGIL2 (1u<<29)
|
||||
#define IT_SIGIL3 (1u<<30)
|
||||
#define IT_SIGIL4 (1u<<31)
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue