Merge remote-tracking branch 'origin/master' into http-mserv

This commit is contained in:
James R 2020-05-12 17:50:32 -07:00
commit 233e6627de
133 changed files with 6962 additions and 8622 deletions

View file

@ -36,7 +36,7 @@ jobs:
- v1-SRB2-APT - v1-SRB2-APT
- run: - run:
name: Install SDK name: Install SDK
command: apt-get -qq -y --no-install-recommends install git build-essential nasm libpng-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 gettext ccache wget gcc-multilib upx openssh-client command: apt-get -qq -y --no-install-recommends install git build-essential nasm libpng-dev:i386 libsdl2-mixer-dev:i386 libgme-dev:i386 libcurl4-openssl-dev:i386 gettext ccache wget gcc-multilib upx openssh-client
- save_cache: - save_cache:
key: v1-SRB2-APT key: v1-SRB2-APT
paths: paths:

View file

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0)
# DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string. # DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string.
# Version change is fine. # Version change is fine.
project(SRB2 project(SRB2
VERSION 1.1.0 VERSION 1.2
LANGUAGES C) LANGUAGES C)
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR}) if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})

View file

@ -1,4 +1,4 @@
version: 1.1.0.{branch}-{build} version: 1.2.{branch}-{build}
os: MinGW os: MinGW
environment: environment:
@ -9,7 +9,7 @@ environment:
# c:\mingw-w64 i686 has gcc 6.3.0, so use c:\msys64 7.3.0 instead # c:\mingw-w64 i686 has gcc 6.3.0, so use c:\msys64 7.3.0 instead
MINGW_SDK: c:\msys64\mingw32 MINGW_SDK: c:\msys64\mingw32
# c:\msys64 x86_64 has gcc 8.2.0, so use c:\mingw-w64 7.3.0 instead # c:\msys64 x86_64 has gcc 8.2.0, so use c:\mingw-w64 7.3.0 instead
MINGW_SDK_64: C:\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev0\mingw64 MINGW_SDK_64: C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64
CFLAGS: -Wall -W -Werror -Wno-error=implicit-fallthrough -Wimplicit-fallthrough=3 -Wno-tautological-compare -Wno-error=suggest-attribute=noreturn CFLAGS: -Wall -W -Werror -Wno-error=implicit-fallthrough -Wimplicit-fallthrough=3 -Wno-tautological-compare -Wno-error=suggest-attribute=noreturn
NASM_ZIP: nasm-2.12.01 NASM_ZIP: nasm-2.12.01
NASM_URL: http://www.nasm.us/pub/nasm/releasebuilds/2.12.01/win64/nasm-2.12.01-win64.zip NASM_URL: http://www.nasm.us/pub/nasm/releasebuilds/2.12.01/win64/nasm-2.12.01-win64.zip
@ -29,7 +29,7 @@ environment:
############################## ##############################
DPL_ENABLED: 0 DPL_ENABLED: 0
DPL_TAG_ENABLED: 0 DPL_TAG_ENABLED: 0
DPL_INSTALLER_NAME: srb2kart-v110 DPL_INSTALLER_NAME: srb2kart-v12
# Asset handling is barebones vs. Travis Deployer. We operate on 7z only. # Asset handling is barebones vs. Travis Deployer. We operate on 7z only.
# Include the README files and the OpenGL batch in the main and patch archives. # Include the README files and the OpenGL batch in the main and patch archives.
# The x86/x64 archives contain the DLL binaries. # The x86/x64 archives contain the DLL binaries.
@ -55,8 +55,6 @@ cache:
install: install:
- if [%CONFIGURATION%] == [SDL64] ( set "X86_64=1" ) - if [%CONFIGURATION%] == [SDL64] ( set "X86_64=1" )
- if [%CONFIGURATION%] == [SDL64] ( set "CONFIGURATION=SDL" ) - if [%CONFIGURATION%] == [SDL64] ( set "CONFIGURATION=SDL" )
- if [%CONFIGURATION%] == [DD64] ( set "X86_64=1" )
- if [%CONFIGURATION%] == [DD64] ( set "CONFIGURATION=DD" )
- if [%X86_64%] == [1] ( set "MINGW_SDK=%MINGW_SDK_64%" ) - if [%X86_64%] == [1] ( set "MINGW_SDK=%MINGW_SDK_64%" )
- if [%X86_64%] == [1] ( set "CCACHE_CC=%CCACHE_CC_64%" ) - if [%X86_64%] == [1] ( set "CCACHE_CC=%CCACHE_CC_64%" )
@ -74,14 +72,7 @@ install:
configuration: configuration:
- SDL - SDL
- SDL64 #- SDL64
#- DD
#- DD64
matrix:
allow_failures:
- configuration: DD
- configuration: DD64
before_build: before_build:
- set "Path=%MINGW_SDK%\bin;%Path%" - set "Path=%MINGW_SDK%\bin;%Path%"
@ -92,8 +83,15 @@ before_build:
- ccache -V - ccache -V
- ccache -s - ccache -s
- if [%NOUPX%] == [1] ( set "NOUPX=NOUPX=1" ) else ( set "NOUPX=" ) - if [%NOUPX%] == [1] ( set "NOUPX=NOUPX=1" ) else ( set "NOUPX=" )
- set "SRB2_MFLAGS=-C src WARNINGMODE=1 CCACHE=1 GCC72=1 NOOBJDUMP=1 %NOUPX%" - if defined [%APPVEYOR_PULL_REQUEST_HEAD_COMMIT%] ( set "COMMIT=%APPVEYOR_PULL_REQUEST_HEAD_COMMIT%" ) else ( set "COMMIT=%APPVEYOR_REPO_COMMIT%" )
- if [%X86_64%] == [1] ( set "MINGW_FLAGS=MINGW64=1 X86_64=1" ) else ( set "MINGW_FLAGS=MINGW=1" ) - cmd: git rev-parse --short %COMMIT%>%TMP%/gitshort.txt
- cmd: set /P GITSHORT=<%TMP%/gitshort.txt
# for pull requests, take the owner's name only, if this isn't the same repo of course
- set "REPO=%APPVEYOR_REPO_BRANCH%"
- if not [%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%] == [] ( if not [%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%] == [%APPVEYOR_REPO_NAME%] ( for /f "delims=/" %%a in ("%APPVEYOR_PULL_REQUEST_HEAD_REPO_NAME%") do set "REPO=%%a-%APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH%" ) )
- set "EXENAME=EXENAME=srb2win-%REPO%-%GITSHORT%.exe"
- set "SRB2_MFLAGS=-C src WARNINGMODE=1 CCACHE=1 NOOBJDUMP=1 %NOUPX% %EXENAME%"
- if [%X86_64%] == [1] ( set "MINGW_FLAGS=MINGW64=1 X86_64=1 GCC81=1" ) else ( set "MINGW_FLAGS=MINGW=1 GCC91=1" )
- set "SRB2_MFLAGS=%SRB2_MFLAGS% %MINGW_FLAGS% %CONFIGURATION%=1" - set "SRB2_MFLAGS=%SRB2_MFLAGS% %MINGW_FLAGS% %CONFIGURATION%=1"
build_script: build_script:
@ -108,10 +106,8 @@ after_build:
) )
- if [%X86_64%] == [1] ( set "CONFIGURATION=%CONFIGURATION%64" ) - if [%X86_64%] == [1] ( set "CONFIGURATION=%CONFIGURATION%64" )
- ccache -s - ccache -s
- cmd: git rev-parse --short %APPVEYOR_REPO_COMMIT%>%TMP%/gitshort.txt - set BUILD_ARCHIVE=%REPO%-%GITSHORT%-%CONFIGURATION%.7z
- cmd: set /P GITSHORT=<%TMP%/gitshort.txt - set BUILDSARCHIVE=%REPO%-%CONFIGURATION%.7z
- set BUILD_ARCHIVE=%APPVEYOR_REPO_BRANCH%-%GITSHORT%-%CONFIGURATION%.7z
- set BUILDSARCHIVE=%APPVEYOR_REPO_BRANCH%-%CONFIGURATION%.7z
- cmd: 7z a %BUILD_ARCHIVE% %BUILD_PATH% -xr!.gitignore - cmd: 7z a %BUILD_ARCHIVE% %BUILD_PATH% -xr!.gitignore
- appveyor PushArtifact %BUILD_ARCHIVE% - appveyor PushArtifact %BUILD_ARCHIVE%
- cmd: copy %BUILD_ARCHIVE% %BUILDSARCHIVE% - cmd: copy %BUILD_ARCHIVE% %BUILDSARCHIVE%

View file

@ -25,6 +25,7 @@ Depends: ${SHLIBS_DEPENDS}, ${MISC_DEPENDS},
libsdl2-mixer-2.0-0, libsdl2-mixer-2.0-0,
zlib1g, zlib1g,
libgme0, libgme0,
libcurl4,
libpng | libpng16-16 | libpng12-0 libpng | libpng16-16 | libpng12-0
Description: A cross-platform 3D Sonic fangame Description: A cross-platform 3D Sonic fangame
Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog

View file

@ -2,7 +2,10 @@ tar-ignore = "assets/*.srb"
tar-ignore = "assets/*.pk3" tar-ignore = "assets/*.pk3"
tar-ignore = "assets/*.dta" tar-ignore = "assets/*.dta"
tar-ignore = "assets/*.wad" tar-ignore = "assets/*.wad"
<<<<<<< HEAD:debian-template/source/options
tar-ignore = "assets/*.kart" tar-ignore = "assets/*.kart"
=======
>>>>>>> e251f9c230beda984cdcdea7e903d765f1c68f6f:debian-template/source/options
tar-ignore = "assets/debian/${PACKAGE_NAME}-data/*" tar-ignore = "assets/debian/${PACKAGE_NAME}-data/*"
tar-ignore = "assets/debian/tmp/*" tar-ignore = "assets/debian/tmp/*"
tar-ignore = "*.obj" tar-ignore = "*.obj"

16
libs/libgme.props Normal file
View file

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Platform)' == 'Win32' OR '$(Platform)' == 'x64'">
<IncludePath>$(SolutionDir)libs\gme\include;$(IncludePath)</IncludePath>
<LibraryPath Condition="'$(Platform)' == 'Win32'">$(SolutionDir)libs\gme\win32;$(LibraryPath)</LibraryPath>
<LibraryPath Condition="'$(Platform)' == 'x64'">$(SolutionDir)libs\gme\win64;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Platform)' == 'Win32' OR '$(Platform)' == 'x64'">
<Link>
<AdditionalDependencies>libgme.dll.a;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup />
</Project>

View file

@ -220,7 +220,7 @@ set(SRB2_CONFIG_HAVE_ZLIB ON CACHE BOOL
"Enable zlib support.") "Enable zlib support.")
set(SRB2_CONFIG_HAVE_GME ON CACHE BOOL set(SRB2_CONFIG_HAVE_GME ON CACHE BOOL
"Enable GME support.") "Enable GME support.")
set(SRB2_CONFIG_HAVE_GME ON CACHE BOOL set(SRB2_CONFIG_HAVE_CURL ON CACHE BOOL
"Enable curl support, used for downloading files via HTTP.") "Enable curl support, used for downloading files via HTTP.")
set(SRB2_CONFIG_HWRENDER ON CACHE BOOL set(SRB2_CONFIG_HWRENDER ON CACHE BOOL
"Enable hardware rendering through OpenGL.") "Enable hardware rendering through OpenGL.")
@ -398,9 +398,9 @@ if(${SRB2_CONFIG_HAVE_CURL})
set(CURL_FOUND ON) set(CURL_FOUND ON)
set(CURL_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/curl) set(CURL_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/libs/curl)
if(${SRB2_SYSTEM_BITS} EQUAL 64) if(${SRB2_SYSTEM_BITS} EQUAL 64)
set(CURL_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/curl/lib32 -lcurl")
else() # 32-bit
set(CURL_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/curl/lib64 -lcurl") set(CURL_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/curl/lib64 -lcurl")
else() # 32-bit
set(CURL_LIBRARIES "-L${CMAKE_SOURCE_DIR}/libs/curl/lib32 -lcurl")
endif() endif()
else() else()
find_package(CURL) find_package(CURL)
@ -436,7 +436,6 @@ if(${SRB2_CONFIG_HWRENDER})
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_defs.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_defs.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_dll.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_dll.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_drv.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_drv.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_glide.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_glob.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_glob.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.h ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.h

View file

@ -753,8 +753,8 @@ ifdef SDL
ifdef MINGW ifdef MINGW
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ command.h hardware/hw_data.h hardware/hw_defs.h hardware/hw_md2.h \
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
@ -762,8 +762,8 @@ $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h
else else
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ command.h hardware/hw_data.h hardware/hw_defs.h hardware/hw_md2.h \
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
@ -916,8 +916,8 @@ ifndef SDL
ifndef NOHW ifndef NOHW
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \ $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ command.h hardware/hw_data.h hardware/hw_defs.h hardware/hw_md2.h \
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
@ -925,8 +925,8 @@ $(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h
$(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \ $(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ command.h hardware/hw_data.h hardware/hw_defs.h hardware/hw_md2.h \
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
@ -934,8 +934,8 @@ $(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \
$(OBJDIR)/r_minigl.o: hardware/r_minigl/r_minigl.c hardware/r_opengl/r_opengl.h \ $(OBJDIR)/r_minigl.o: hardware/r_minigl/r_minigl.c hardware/r_opengl/r_opengl.h \
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \ doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \ command.h hardware/hw_data.h hardware/hw_defs.h hardware/hw_md2.h \
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \ hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \ hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \ am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h

View file

@ -7,11 +7,19 @@
# and other things # and other things
# #
ifdef GCC81 ifdef GCC91
GCC80=1 GCC83=1
endif endif
ifdef GCC80 ifdef GCC83
GCC82=1
endif
ifdef GCC82
GCC81=1
endif
ifdef GCC81
GCC72=1 GCC72=1
endif endif
@ -186,6 +194,9 @@ ifndef GCC295
endif endif
endif endif
WFLAGS+=-Wformat-y2k WFLAGS+=-Wformat-y2k
ifdef GCC71
WFLAGS+=-Wno-error=format-overflow=2
endif
WFLAGS+=-Wformat-security WFLAGS+=-Wformat-security
ifndef GCC29 ifndef GCC29
#WFLAGS+=-Winit-self #WFLAGS+=-Winit-self
@ -222,9 +233,9 @@ endif
ifdef GCC71 ifdef GCC71
WFLAGS+=-Wno-error=implicit-fallthrough WFLAGS+=-Wno-error=implicit-fallthrough
WFLAGS+=-Wno-implicit-fallthrough WFLAGS+=-Wno-implicit-fallthrough
WFLAGS+=-Wno-error=format-truncation WFLAGS+=-Wno-format-truncation
endif endif
ifdef GCC80 ifdef GCC81
WFLAGS+=-Wno-error=format-overflow WFLAGS+=-Wno-error=format-overflow
WFLAGS+=-Wno-error=stringop-truncation WFLAGS+=-Wno-error=stringop-truncation
WFLAGS+=-Wno-error=stringop-overflow WFLAGS+=-Wno-error=stringop-overflow

View file

@ -56,7 +56,7 @@ static void CV_EnforceExecVersion(void);
static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr); static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr);
static boolean CV_Command(void); static boolean CV_Command(void);
static consvar_t *CV_FindVar(const char *name); consvar_t *CV_FindVar(const char *name);
static const char *CV_StringValue(const char *var_name); static const char *CV_StringValue(const char *var_name);
static consvar_t *consvar_vars; // list of registered console variables static consvar_t *consvar_vars; // list of registered console variables
@ -86,7 +86,7 @@ static boolean joyaxis_default[4] = {false,false,false,false};
static INT32 joyaxis_count[4] = {0,0,0,0}; static INT32 joyaxis_count[4] = {0,0,0,0};
#endif #endif
#define COM_BUF_SIZE 8192 // command buffer size #define COM_BUF_SIZE 0x4000 // command buffer size, 0x4000 = 16384
#define MAX_ALIAS_RECURSION 100 // max recursion allowed for aliases #define MAX_ALIAS_RECURSION 100 // max recursion allowed for aliases
static INT32 com_wait; // one command per frame (for cmd sequences) static INT32 com_wait; // one command per frame (for cmd sequences)
@ -532,7 +532,6 @@ static void COM_ExecuteString(char *ptext)
{ {
if (!stricmp(com_argv[0], cmd->name)) //case insensitive now that we have lower and uppercase! if (!stricmp(com_argv[0], cmd->name)) //case insensitive now that we have lower and uppercase!
{ {
recursion = 0;
cmd->function(); cmd->function();
return; return;
} }
@ -586,8 +585,6 @@ static void COM_ExecuteString(char *ptext)
} }
} }
recursion = 0;
// check cvars // check cvars
// Hurdler: added at Ebola's request ;) // Hurdler: added at Ebola's request ;)
// (don't flood the console in software mode with bad gr_xxx command) // (don't flood the console in software mode with bad gr_xxx command)
@ -1027,7 +1024,7 @@ static const char *cv_null_string = "";
* \return Pointer to the variable if found, or NULL. * \return Pointer to the variable if found, or NULL.
* \sa CV_FindNetVar * \sa CV_FindNetVar
*/ */
static consvar_t *CV_FindVar(const char *name) consvar_t *CV_FindVar(const char *name)
{ {
consvar_t *cvar; consvar_t *cvar;
@ -1307,8 +1304,7 @@ found:
var->string = var->zstring = Z_StrDup(valstr); var->string = var->zstring = Z_StrDup(valstr);
if (var->flags & CV_PASSWORD); // Don't change value for password field if (override)
else if (override)
var->value = overrideval; var->value = overrideval;
else if (var->flags & CV_FLOAT) else if (var->flags & CV_FLOAT)
{ {

View file

@ -98,8 +98,7 @@ typedef enum
CV_HIDEN = 1024, // variable is not part of the cvar list so cannot be accessed by the console CV_HIDEN = 1024, // variable is not part of the cvar list so cannot be accessed by the console
// can only be set when we have the pointer to it // can only be set when we have the pointer to it
// used on menus // used on menus
CV_CHEAT = 2048, // Don't let this be used in multiplayer unless cheats are on. CV_CHEAT = 2048 // Don't let this be used in multiplayer unless cheats are on.
CV_PASSWORD = 4096 // Password field
} cvflags_t; } cvflags_t;
typedef struct CV_PossibleValue_s typedef struct CV_PossibleValue_s
@ -173,4 +172,7 @@ void CV_ResetCheatNetVars(void);
boolean CV_IsSetToDefault(consvar_t *v); boolean CV_IsSetToDefault(consvar_t *v);
UINT8 CV_CheatsEnabled(void); UINT8 CV_CheatsEnabled(void);
// Returns cvar by name. Exposed here for Lua.
consvar_t *CV_FindVar(const char *name);
#endif // __COMMAND_H__ #endif // __COMMAND_H__

View file

@ -37,7 +37,7 @@
* Last updated 2015 / 05 / 03 - SRB2 v2.1.15 - srb2.srb * Last updated 2015 / 05 / 03 - SRB2 v2.1.15 - srb2.srb
* Last updated 2018 / 12 / 23 - SRB2 v2.1.22 - patch.dta * Last updated 2018 / 12 / 23 - SRB2 v2.1.22 - patch.dta
* Last updated 2019 / 01 / 18 - Kart v1.0.2 - Main assets * Last updated 2019 / 01 / 18 - Kart v1.0.2 - Main assets
* Last updated 2019 / 05 / 06 - Kart v1.1.0 - patch.kart * Last updated 2020 / 05 / 09 - Kart v1.2 - patch.kart
*/ */
// Base SRB2 hashes // Base SRB2 hashes
@ -52,7 +52,7 @@
#define ASSET_HASH_CHARS_KART "e2c428347dde52858a3dacd29fc5b964" #define ASSET_HASH_CHARS_KART "e2c428347dde52858a3dacd29fc5b964"
#define ASSET_HASH_MAPS_KART "1335cd064656aedca359cfbb5233ac4a" #define ASSET_HASH_MAPS_KART "1335cd064656aedca359cfbb5233ac4a"
#ifdef USE_PATCH_KART #ifdef USE_PATCH_KART
#define ASSET_HASH_PATCH_KART "7093231f2c3c1cca1a909a708be85d9a" #define ASSET_HASH_PATCH_KART "2a556446ab428492110e7544841e1f42"
#endif #endif
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -13,14 +13,19 @@
#ifndef __D_CLISRV__ #ifndef __D_CLISRV__
#define __D_CLISRV__ #define __D_CLISRV__
#include "d_event.h"
#include "d_ticcmd.h" #include "d_ticcmd.h"
#include "d_net.h"
#include "d_netcmd.h" #include "d_netcmd.h"
#include "tables.h" #include "tables.h"
#include "d_player.h" #include "d_player.h"
#include "mserv.h" #include "mserv.h"
#include "md5.h" /*
The 'packet version' is used to distinguish packet formats.
This version is independent of VERSION and SUBVERSION. Different
applications may follow different packet versions.
*/
#define PACKETVERSION 0
// Network play related stuff. // Network play related stuff.
// There is a data struct that stores network // There is a data struct that stores network
@ -30,7 +35,9 @@
// SOME numpty changed all the gametype constants and it fell out of sync with vanilla and now we have to pretend to be vanilla when talking to the master server... // SOME numpty changed all the gametype constants and it fell out of sync with vanilla and now we have to pretend to be vanilla when talking to the master server...
#define VANILLA_GT_RACE 2 #define VANILLA_GT_RACE 2
#if VERSION < 210 // Woah, what do these numbers mean? 200 refers to SRB2 2.0, 246 refers to
// SRB2Riders. Both use the old 2.0 gametype numbers.
#if VERSION == 200 || VERSION == 246
#define VANILLA_GT_MATCH 1 #define VANILLA_GT_MATCH 1
#else #else
#define VANILLA_GT_MATCH 3 #define VANILLA_GT_MATCH 3
@ -38,6 +45,7 @@
// Networking and tick handling related. // Networking and tick handling related.
#define BACKUPTICS 32 #define BACKUPTICS 32
#define TICQUEUE 512 // more than enough for most timeouts....
#define MAXTEXTCMD 256 #define MAXTEXTCMD 256
// //
// Packet structure // Packet structure
@ -77,9 +85,6 @@ typedef enum
PT_CLIENT4MIS, PT_CLIENT4MIS,
PT_BASICKEEPALIVE,// Keep the network alive during wipes, as tics aren't advanced and NetUpdate isn't called PT_BASICKEEPALIVE,// Keep the network alive during wipes, as tics aren't advanced and NetUpdate isn't called
PT_JOINCHALLENGE, // You must give a password to joinnnnn
PT_DOWNLOADFILESOKAY, // You can download files from the server....
PT_CANFAIL, // This is kind of a priority. Anything bigger than CANFAIL PT_CANFAIL, // This is kind of a priority. Anything bigger than CANFAIL
// allows HSendPacket(*, true, *, *) to return false. // allows HSendPacket(*, true, *, *) to return false.
// In addition, this packet can't occupy all the available slots. // In addition, this packet can't occupy all the available slots.
@ -343,32 +348,37 @@ typedef struct {
#pragma warning(default : 4200) #pragma warning(default : 4200)
#endif #endif
#define MAXAPPLICATION 16
typedef struct typedef struct
{ {
UINT8 _255;/* see serverinfo_pak */
UINT8 packetversion;
char application[MAXAPPLICATION];
UINT8 version; // Different versions don't work UINT8 version; // Different versions don't work
UINT8 subversion; // Contains build version UINT8 subversion; // Contains build version
UINT8 localplayers; UINT8 localplayers; // number of splitscreen players
UINT8 needsdownload; UINT8 mode;
UINT8 challengenum; // Non-zero if trying to join with a password attempt
UINT8 challengeanswer[MD5_LEN]; // Join challenge
} ATTRPACK clientconfig_pak; } ATTRPACK clientconfig_pak;
typedef struct #define SV_SPEEDMASK 0x03 // used to send kartspeed
{ #define SV_DEDICATED 0x40 // server is dedicated
UINT8 challengenum; // Number to send back in join attempt #define SV_LOTSOFADDONS 0x20 // flag used to ask for full file list in d_netfil
UINT8 question[MD5_LEN]; // Challenge data to be manipulated and answered with
} ATTRPACK joinchallenge_pak;
#define SV_SPEEDMASK 0x03
#define SV_LOTSOFADDONS 0x20
#define SV_DEDICATED 0x40
#define SV_PASSWORD 0x80
#define MAXSERVERNAME 32 #define MAXSERVERNAME 32
#define MAXFILENEEDED 915 #define MAXFILENEEDED 915
#define MAX_MIRROR_LENGTH 256
// This packet is too large // This packet is too large
typedef struct typedef struct
{ {
/*
In the old packet, 'version' is the first field. Now that field is set
to 255 always, so older versions won't be confused with the new
versions or vice-versa.
*/
UINT8 _255;
UINT8 packetversion;
char application[MAXAPPLICATION];
UINT8 version; UINT8 version;
UINT8 subversion; UINT8 subversion;
UINT8 numberofplayer; UINT8 numberofplayer;
@ -378,7 +388,6 @@ typedef struct
UINT8 cheatsenabled; UINT8 cheatsenabled;
UINT8 kartvars; // Previously isdedicated, now appropriated for our own nefarious purposes UINT8 kartvars; // Previously isdedicated, now appropriated for our own nefarious purposes
UINT8 fileneedednum; UINT8 fileneedednum;
SINT8 adminplayer;
tic_t time; tic_t time;
tic_t leveltime; tic_t leveltime;
char servername[MAXSERVERNAME]; char servername[MAXSERVERNAME];
@ -387,6 +396,7 @@ typedef struct
unsigned char mapmd5[16]; unsigned char mapmd5[16];
UINT8 actnum; UINT8 actnum;
UINT8 iszone; UINT8 iszone;
char httpsource[MAX_MIRROR_LENGTH]; // HTTP URL to download from, always defined for compatibility
UINT8 fileneeded[MAXFILENEEDED]; // is filled with writexxx (byteptr.h) UINT8 fileneeded[MAXFILENEEDED]; // is filled with writexxx (byteptr.h)
} ATTRPACK serverinfo_pak; } ATTRPACK serverinfo_pak;
@ -464,7 +474,6 @@ typedef struct
UINT8 textcmd[MAXTEXTCMD+1]; // 66049 bytes (wut??? 64k??? More like 257 bytes...) UINT8 textcmd[MAXTEXTCMD+1]; // 66049 bytes (wut??? 64k??? More like 257 bytes...)
filetx_pak filetxpak; // 139 bytes filetx_pak filetxpak; // 139 bytes
clientconfig_pak clientcfg; // 153 bytes clientconfig_pak clientcfg; // 153 bytes
joinchallenge_pak joinchallenge; // 17 bytes
serverinfo_pak serverinfo; // 1024 bytes serverinfo_pak serverinfo; // 1024 bytes
serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...) serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...)
askinfo_pak askinfo; // 61 bytes askinfo_pak askinfo; // 61 bytes
@ -481,7 +490,7 @@ typedef struct
#pragma pack() #pragma pack()
#endif #endif
#define MAXSERVERLIST 64 // Depends only on the display #define MAXSERVERLIST (MAXNETNODES-1)
typedef struct typedef struct
{ {
SINT8 node; SINT8 node;
@ -494,7 +503,7 @@ extern INT32 mapchangepending;
// Points inside doomcom // Points inside doomcom
extern doomdata_t *netbuffer; extern doomdata_t *netbuffer;
extern consvar_t cv_httpsource;
extern consvar_t cv_showjoinaddress; extern consvar_t cv_showjoinaddress;
extern consvar_t cv_playbackspeed; extern consvar_t cv_playbackspeed;
@ -546,7 +555,7 @@ extern consvar_t
cv_netticbuffer, cv_allownewplayer, cv_maxplayers, cv_resynchattempts, cv_blamecfail, cv_maxsend, cv_noticedownload, cv_downloadspeed; cv_netticbuffer, cv_allownewplayer, cv_maxplayers, cv_resynchattempts, cv_blamecfail, cv_maxsend, cv_noticedownload, cv_downloadspeed;
// Used in d_net, the only dependence // Used in d_net, the only dependence
tic_t ExpandTics(INT32 low); tic_t ExpandTics(INT32 low, tic_t basetic);
void D_ClientServerInit(void); void D_ClientServerInit(void);
// Initialise the other field // Initialise the other field
@ -572,7 +581,6 @@ void CL_ClearPlayer(INT32 playernum);
void CL_RemovePlayer(INT32 playernum, INT32 reason); void CL_RemovePlayer(INT32 playernum, INT32 reason);
void CL_QueryServerList(msg_server_t *list); void CL_QueryServerList(msg_server_t *list);
void CL_UpdateServerList(boolean internetsearch, INT32 room); void CL_UpdateServerList(boolean internetsearch, INT32 room);
boolean CL_Responder(event_t *ev);
// Is there a game running // Is there a game running
boolean Playing(void); boolean Playing(void);
@ -605,4 +613,19 @@ UINT8 GetFreeXCmdSize(void);
extern UINT8 hu_resynching; extern UINT8 hu_resynching;
extern UINT8 hu_stopped; // kart, true when the game is stopped for players due to a disconnecting or connecting player extern UINT8 hu_stopped; // kart, true when the game is stopped for players due to a disconnecting or connecting player
typedef struct rewind_s {
UINT8 savebuffer[(768*1024)];
tic_t leveltime;
size_t demopos;
ticcmd_t oldcmd[MAXPLAYERS];
mobj_t oldghost[MAXPLAYERS];
struct rewind_s *next;
} rewind_t;
void CL_ClearRewinds(void);
rewind_t *CL_SaveRewindPoint(size_t demopos);
rewind_t *CL_RewindToTime(tic_t time);
#endif #endif

View file

@ -181,6 +181,7 @@ void D_PostEvent_end(void) {};
#endif #endif
// modifier keys // modifier keys
// Now handled in I_OsPolling
UINT8 shiftdown = 0; // 0x1 left, 0x2 right UINT8 shiftdown = 0; // 0x1 left, 0x2 right
UINT8 ctrldown = 0; // 0x1 left, 0x2 right UINT8 ctrldown = 0; // 0x1 left, 0x2 right
UINT8 altdown = 0; // 0x1 left, 0x2 right UINT8 altdown = 0; // 0x1 left, 0x2 right
@ -229,16 +230,10 @@ void D_ProcessEvents(void)
{ {
ev = &events[eventtail]; ev = &events[eventtail];
// Set global shift/ctrl/alt down variables
D_ModifierKeyResponder(ev); // never eats events
// Screenshots over everything so that they can be taken anywhere. // Screenshots over everything so that they can be taken anywhere.
if (M_ScreenshotResponder(ev)) if (M_ScreenshotResponder(ev))
continue; // ate the event continue; // ate the event
if (CL_Responder(ev))
continue;
if (gameaction == ga_nothing && gamestate == GS_TITLESCREEN) if (gameaction == ga_nothing && gamestate == GS_TITLESCREEN)
{ {
if (cht_Responder(ev)) if (cht_Responder(ev))
@ -265,6 +260,11 @@ void D_ProcessEvents(void)
if (eaten) if (eaten)
continue; // menu ate the event continue; // menu ate the event
// Demo input:
if (demo.playback)
if (M_DemoResponder(ev))
continue; // demo ate the event
// console input // console input
#ifdef HAVE_THREADS #ifdef HAVE_THREADS
I_lock_mutex(&con_mutex); I_lock_mutex(&con_mutex);
@ -299,9 +299,8 @@ static void D_Display(void)
INT32 wipedefindex = 0; INT32 wipedefindex = 0;
UINT8 i; UINT8 i;
if (dedicated) if (!dedicated)
return; {
if (nodrawers) if (nodrawers)
return; // for comparative timing/profiling return; // for comparative timing/profiling
@ -322,6 +321,7 @@ static void D_Display(void)
// draw buffered stuff to screen // draw buffered stuff to screen
// Used only by linux GGI version // Used only by linux GGI version
I_UpdateNoBlit(); I_UpdateNoBlit();
}
// save the current screen if about to wipe // save the current screen if about to wipe
wipe = (gamestate != wipegamestate); wipe = (gamestate != wipegamestate);
@ -339,7 +339,7 @@ static void D_Display(void)
wipedefindex = wipe_multinter_toblack; wipedefindex = wipe_multinter_toblack;
} }
if (rendermode != render_none) if (!dedicated)
{ {
// Fade to black first // Fade to black first
if (gamestate != GS_LEVEL // fades to black on its own timing, always if (gamestate != GS_LEVEL // fades to black on its own timing, always
@ -359,7 +359,15 @@ static void D_Display(void)
F_WipeStartScreen(); F_WipeStartScreen();
} }
else //dedicated servers
{
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK);
wipegamestate = gamestate;
} }
}
if (dedicated) //bail out after wipe logic
return;
// do buffered drawing // do buffered drawing
switch (gamestate) switch (gamestate)
@ -642,9 +650,6 @@ void D_SRB2Loop(void)
// Pushing of + parameters is now done back in D_SRB2Main, not here. // Pushing of + parameters is now done back in D_SRB2Main, not here.
CONS_Printf("I_StartupKeyboard()...\n");
I_StartupKeyboard();
#ifdef _WINDOWS #ifdef _WINDOWS
CONS_Printf("I_StartupMouse()...\n"); CONS_Printf("I_StartupMouse()...\n");
I_DoStartupMouse(); I_DoStartupMouse();
@ -1330,6 +1335,14 @@ void D_SRB2Main(void)
CONS_Printf("I_StartupGraphics()...\n"); CONS_Printf("I_StartupGraphics()...\n");
I_StartupGraphics(); I_StartupGraphics();
#ifdef HWRENDER
if (rendermode == render_opengl)
{
for (i = 0; i < numwadfiles; i++)
HWR_LoadShaders(i, (wadfiles[i]->type == RET_PK3));
}
#endif
//--------------------------------------------------------- CONSOLE //--------------------------------------------------------- CONSOLE
// setup loading screen // setup loading screen
SCR_Startup(); SCR_Startup();

View file

@ -805,9 +805,6 @@ static const char *packettypename[NUMPACKETTYPE] =
"CLIENT4MIS", "CLIENT4MIS",
"BASICKEEPALIVE", "BASICKEEPALIVE",
"JOINCHALLENGE",
"DOWNLOADFILESOKAY",
"FILEFRAGMENT", "FILEFRAGMENT",
"TEXTCMD", "TEXTCMD",
"TEXTCMD2", "TEXTCMD2",
@ -833,7 +830,7 @@ static void DebugPrintpacket(const char *header)
break; break;
case PT_CLIENTJOIN: case PT_CLIENTJOIN:
fprintf(debugfile, " number %d mode %d\n", netbuffer->u.clientcfg.localplayers, fprintf(debugfile, " number %d mode %d\n", netbuffer->u.clientcfg.localplayers,
netbuffer->u.clientcfg.needsdownload); netbuffer->u.clientcfg.mode);
break; break;
case PT_SERVERTICS: case PT_SERVERTICS:
{ {
@ -842,7 +839,7 @@ static void DebugPrintpacket(const char *header)
size_t ntxtcmd = &((UINT8 *)netbuffer)[doomcom->datalength] - cmd; size_t ntxtcmd = &((UINT8 *)netbuffer)[doomcom->datalength] - cmd;
fprintf(debugfile, " firsttic %u ply %d tics %d ntxtcmd %s\n ", fprintf(debugfile, " firsttic %u ply %d tics %d ntxtcmd %s\n ",
(UINT32)ExpandTics(serverpak->starttic), serverpak->numslots, serverpak->numtics, sizeu1(ntxtcmd)); (UINT32)serverpak->starttic, serverpak->numslots, serverpak->numtics, sizeu1(ntxtcmd));
/// \todo Display more readable information about net commands /// \todo Display more readable information about net commands
fprintfstringnewline((char *)cmd, ntxtcmd); fprintfstringnewline((char *)cmd, ntxtcmd);
/*fprintfstring((char *)cmd, 3); /*fprintfstring((char *)cmd, 3);
@ -865,8 +862,8 @@ static void DebugPrintpacket(const char *header)
case PT_NODEKEEPALIVE: case PT_NODEKEEPALIVE:
case PT_NODEKEEPALIVEMIS: case PT_NODEKEEPALIVEMIS:
fprintf(debugfile, " tic %4u resendfrom %u\n", fprintf(debugfile, " tic %4u resendfrom %u\n",
(UINT32)ExpandTics(netbuffer->u.clientpak.client_tic), (UINT32)netbuffer->u.clientpak.client_tic,
(UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom)); (UINT32)netbuffer->u.clientpak.resendfrom);
break; break;
case PT_BASICKEEPALIVE: case PT_BASICKEEPALIVE:
fprintf(debugfile, " keep alive\n"); fprintf(debugfile, " keep alive\n");

View file

@ -19,7 +19,7 @@
#define __D_NET__ #define __D_NET__
// Max computers in a game // Max computers in a game
#define MAXNETNODES (MAXPLAYERS+4) #define MAXNETNODES 64
#define BROADCASTADDR MAXNETNODES #define BROADCASTADDR MAXNETNODES
#define NETSPLITSCREEN // Kart's splitscreen netgame feature #define NETSPLITSCREEN // Kart's splitscreen netgame feature

View file

@ -172,7 +172,6 @@ static void Got_Verification(UINT8 **cp, INT32 playernum);
static void Got_Removal(UINT8 **cp, INT32 playernum); static void Got_Removal(UINT8 **cp, INT32 playernum);
static void Command_Verify_f(void); static void Command_Verify_f(void);
static void Command_RemoveAdmin_f(void); static void Command_RemoveAdmin_f(void);
static void Command_ChangeJoinPassword_f(void);
static void Command_MotD_f(void); static void Command_MotD_f(void);
static void Got_MotD_f(UINT8 **cp, INT32 playernum); static void Got_MotD_f(UINT8 **cp, INT32 playernum);
@ -554,8 +553,6 @@ void D_RegisterServerCommands(void)
RegisterNetXCmd(XD_PICKVOTE, Got_PickVotecmd); RegisterNetXCmd(XD_PICKVOTE, Got_PickVotecmd);
// Remote Administration // Remote Administration
CV_RegisterVar(&cv_dummyjoinpassword);
COM_AddCommand("joinpassword", Command_ChangeJoinPassword_f);
COM_AddCommand("password", Command_Changepassword_f); COM_AddCommand("password", Command_Changepassword_f);
RegisterNetXCmd(XD_LOGIN, Got_Login); RegisterNetXCmd(XD_LOGIN, Got_Login);
COM_AddCommand("login", Command_Login_f); // useful in dedicated to kick off remote admin COM_AddCommand("login", Command_Login_f); // useful in dedicated to kick off remote admin
@ -686,6 +683,7 @@ void D_RegisterServerCommands(void)
CV_RegisterVar(&cv_maxsend); CV_RegisterVar(&cv_maxsend);
CV_RegisterVar(&cv_noticedownload); CV_RegisterVar(&cv_noticedownload);
CV_RegisterVar(&cv_downloadspeed); CV_RegisterVar(&cv_downloadspeed);
CV_RegisterVar(&cv_httpsource);
#ifndef NONET #ifndef NONET
CV_RegisterVar(&cv_allownewplayer); CV_RegisterVar(&cv_allownewplayer);
#ifdef VANILLAJOINNEXTROUND #ifdef VANILLAJOINNEXTROUND
@ -2040,6 +2038,9 @@ static void Command_View_f(void)
return; return;
} }
if (demo.freecam)
return;
displayplayerp = &displayplayers[viewnum-1]; displayplayerp = &displayplayers[viewnum-1];
if (COM_Argc() > 1)/* switch to player */ if (COM_Argc() > 1)/* switch to player */
@ -2688,11 +2689,17 @@ static void Command_Pause(void)
if (cv_pause.value || server || (IsPlayerAdmin(consoleplayer))) if (cv_pause.value || server || (IsPlayerAdmin(consoleplayer)))
{ {
if (!paused && (modeattacking || !(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_VOTING || gamestate == GS_WAITINGPLAYERS))) if (!paused && (!(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_VOTING || gamestate == GS_WAITINGPLAYERS)))
{ {
CONS_Printf(M_GetText("You can't pause here.\n")); CONS_Printf(M_GetText("You can't pause here.\n"));
return; return;
} }
else if (modeattacking) // in time attack, pausing restarts the map
{
M_ModeAttackRetry(0); // directly call from m_menu;
return;
}
SendNetXCmd(XD_PAUSE, &buf, 2); SendNetXCmd(XD_PAUSE, &buf, 2);
} }
else else
@ -2769,6 +2776,12 @@ static void Command_Respawn(void)
return; return;
} }
if (players[consoleplayer].mo && (players[consoleplayer].kartstuff[k_spinouttimer] || spbplace == players[consoleplayer].kartstuff[k_position])) // KART: Nice try, but no, you won't be cheesing spb anymore (x2)
{
CONS_Printf(M_GetText("Nice try.\n"));
return;
}
/*if (!G_RaceGametype()) // srb2kart: not necessary, respawning makes you lose a bumper in battle, so it's not desirable to use as a way to escape a hit /*if (!G_RaceGametype()) // srb2kart: not necessary, respawning makes you lose a bumper in battle, so it's not desirable to use as a way to escape a hit
{ {
CONS_Printf(M_GetText("You may only use this in co-op, race, and competition!\n")); CONS_Printf(M_GetText("You may only use this in co-op, race, and competition!\n"));
@ -2791,7 +2804,7 @@ static void Got_Respawn(UINT8 **cp, INT32 playernum)
INT32 respawnplayer = READINT32(*cp); INT32 respawnplayer = READINT32(*cp);
// You can't respawn someone else. Nice try, there. // You can't respawn someone else. Nice try, there.
if (respawnplayer != playernum) // srb2kart: "|| (!G_RaceGametype())" if (respawnplayer != playernum || players[respawnplayer].kartstuff[k_spinouttimer] || spbplace == players[respawnplayer].kartstuff[k_position]) // srb2kart: "|| (!G_RaceGametype())"
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal respawn command received from %s\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal respawn command received from %s\n"), player_names[playernum]);
if (server) if (server)
@ -3956,131 +3969,6 @@ static void Got_Removal(UINT8 **cp, INT32 playernum)
CONS_Printf(M_GetText("You are no longer a server administrator.\n")); CONS_Printf(M_GetText("You are no longer a server administrator.\n"));
} }
// Join password stuff
consvar_t cv_dummyjoinpassword = {"dummyjoinpassword", "", CV_HIDEN|CV_NOSHOWHELP|CV_PASSWORD, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
#define NUMJOINCHALLENGES 32
static UINT8 joinpassmd5[MD5_LEN+1];
boolean joinpasswordset = false;
static UINT8 joinpasschallenges[NUMJOINCHALLENGES][MD5_LEN];
static tic_t joinpasschallengeson[NUMJOINCHALLENGES];
boolean D_IsJoinPasswordOn(void)
{
return joinpasswordset;
}
static inline void GetChallengeAnswer(UINT8 *question, UINT8 *passwordmd5, UINT8 *answer)
{
D_MD5PasswordPass(question, MD5_LEN, (char *) passwordmd5, answer);
}
void D_ComputeChallengeAnswer(UINT8 *question, const char *pw, UINT8 *answer)
{
static UINT8 passwordmd5[MD5_LEN+1];
memset(passwordmd5, 0x00, MD5_LEN+1);
D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &passwordmd5);
GetChallengeAnswer(question, passwordmd5, answer);
}
void D_SetJoinPassword(const char *pw)
{
memset(joinpassmd5, 0x00, MD5_LEN+1);
D_MD5PasswordPass((const UINT8 *)pw, strlen(pw), BASESALT, &joinpassmd5);
joinpasswordset = true;
}
boolean D_VerifyJoinPasswordChallenge(UINT8 num, UINT8 *answer)
{
boolean passed = false;
num %= NUMJOINCHALLENGES;
//@TODO use a constant-time memcmp....
if (joinpasschallengeson[num] > 0 && memcmp(answer, joinpasschallenges[num], MD5_LEN) == 0)
passed = true;
// Wipe and reset the challenge so that it can't be tried against again, as a small measure against brute-force attacks.
memset(joinpasschallenges[num], 0x00, MD5_LEN);
joinpasschallengeson[num] = 0;
return passed;
}
void D_MakeJoinPasswordChallenge(UINT8 *num, UINT8 *question)
{
size_t i;
for (i = 0; i < NUMJOINCHALLENGES; i++)
{
(*num) = M_RandomKey(NUMJOINCHALLENGES);
if (joinpasschallengeson[(*num)] == 0)
break;
}
if (joinpasschallengeson[(*num)] > 0)
{
// Ugh, all challenges are (probably) taken. Let's find the oldest one and overwrite it.
tic_t oldesttic = INT32_MAX;
for (i = 0; i < NUMJOINCHALLENGES; i++)
{
if (joinpasschallengeson[i] < oldesttic)
{
(*num) = i;
oldesttic = joinpasschallengeson[i];
}
}
}
joinpasschallengeson[(*num)] = I_GetTime();
memset(question, 0x00, MD5_LEN);
for (i = 0; i < MD5_LEN; i++)
question[i] = M_RandomByte();
// Store the answer in memory. What was the question again?
GetChallengeAnswer(question, joinpassmd5, joinpasschallenges[(*num)]);
// This ensures that num is always non-zero and will be valid when used for the answer
if ((*num) == 0)
(*num) = NUMJOINCHALLENGES;
}
// Remote Administration
static void Command_ChangeJoinPassword_f(void)
{
#ifdef NOMD5
// If we have no MD5 support then completely disable XD_LOGIN responses for security.
CONS_Alert(CONS_NOTICE, "Remote administration commands are not supported in this build.\n");
#else
if (client) // cannot change remotely
{
CONS_Printf(M_GetText("Only the server can use this.\n"));
return;
}
if (COM_Argc() != 2)
{
CONS_Printf(M_GetText("joinpassword <password>: set a password to join the server\nUse -remove to disable the password.\n"));
return;
}
if (strcmp(COM_Argv(1), "-remove") == 0)
{
joinpasswordset = false;
CONS_Printf(M_GetText("Join password removed.\n"));
}
else
{
D_SetJoinPassword(COM_Argv(1));
CONS_Printf(M_GetText("Join password set.\n"));
}
#endif
}
static void Command_MotD_f(void) static void Command_MotD_f(void)
{ {
size_t i, j; size_t i, j;
@ -5325,11 +5213,11 @@ static void Fishcake_OnChange(void)
static void Command_Isgamemodified_f(void) static void Command_Isgamemodified_f(void)
{ {
if (majormods) if (majormods)
CONS_Printf("The game has been modified with major add-ons, so you cannot play Record Attack.\n"); CONS_Printf("The game has been modified with major addons, so you cannot play Record Attack.\n");
else if (savemoddata) else if (savemoddata)
CONS_Printf("The game has been modified with an add-on with its own save data, so you can play Record Attack and earn medals.\n"); CONS_Printf("The game has been modified with an addon with its own save data, so you can play Record Attack and earn medals.\n");
else if (modifiedgame) else if (modifiedgame)
CONS_Printf("The game has been modified with only minor add-ons. You can play Record Attack, earn medals and unlock extras.\n"); CONS_Printf("The game has been modified with only minor addons. You can play Record Attack, earn medals and unlock extras.\n");
else else
CONS_Printf("The game has not been modified. You can play Record Attack, earn medals and unlock extras.\n"); CONS_Printf("The game has not been modified. You can play Record Attack, earn medals and unlock extras.\n");
} }

View file

@ -246,14 +246,6 @@ void RemoveAdminPlayer(INT32 playernum);
void ItemFinder_OnChange(void); void ItemFinder_OnChange(void);
void D_SetPassword(const char *pw); void D_SetPassword(const char *pw);
extern consvar_t cv_dummyjoinpassword;
extern boolean joinpasswordset;
boolean D_IsJoinPasswordOn(void);
void D_ComputeChallengeAnswer(UINT8 *question, const char *pw, UINT8 *answer);
void D_SetJoinPassword(const char *pw);
boolean D_VerifyJoinPasswordChallenge(UINT8 num, UINT8 *answer);
void D_MakeJoinPasswordChallenge(UINT8 *num, UINT8 *question);
// used for the player setup menu // used for the player setup menu
UINT8 CanChangeSkin(INT32 playernum); UINT8 CanChangeSkin(INT32 playernum);

View file

@ -42,6 +42,10 @@
#include <utime.h> #include <utime.h>
#endif #endif
#ifdef HAVE_CURL
#include "curl/curl.h"
#endif
#include "doomdef.h" #include "doomdef.h"
#include "doomstat.h" #include "doomstat.h"
#include "d_main.h" #include "d_main.h"
@ -65,6 +69,11 @@
// Prototypes // Prototypes
static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid); static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid);
#ifdef HAVE_CURL
size_t curlwrite_data(void *ptr, size_t size, size_t nmemb, FILE *stream);
int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);
#endif
// Sender structure // Sender structure
typedef struct filetx_s typedef struct filetx_s
{ {
@ -101,6 +110,22 @@ char downloaddir[512] = "DOWNLOAD";
INT32 lastfilenum = -1; INT32 lastfilenum = -1;
#endif #endif
#ifdef HAVE_CURL
static CURL *http_handle;
static CURLM *multi_handle;
boolean curl_running = false;
boolean curl_failedwebdownload = false;
static double curl_dlnow;
static double curl_dltotal;
static time_t curl_starttime;
INT32 curl_transfers = 0;
static int curl_runninghandles = 0;
static UINT32 curl_origfilesize;
static UINT32 curl_origtotalfilesize;
static char *curl_realname = NULL;
fileneeded_t *curl_curfile = NULL;
#endif
/** Fills a serverinfo packet with information about wad files loaded. /** Fills a serverinfo packet with information about wad files loaded.
* *
* \todo Give this function a better name since it is in global scope. * \todo Give this function a better name since it is in global scope.
@ -238,10 +263,10 @@ boolean CL_CheckDownloadable(void)
{ {
CONS_Printf(" * \"%s\" (%dK)", fileneeded[i].filename, fileneeded[i].totalsize >> 10); CONS_Printf(" * \"%s\" (%dK)", fileneeded[i].filename, fileneeded[i].totalsize >> 10);
if (fileneeded[i].status == FS_NOTFOUND) if (fileneeded[i].status == FS_MD5SUMBAD)
CONS_Printf(M_GetText(" not found, md5: "));
else if (fileneeded[i].status == FS_MD5SUMBAD)
CONS_Printf(M_GetText(" wrong version, md5: ")); CONS_Printf(M_GetText(" wrong version, md5: "));
else
CONS_Printf(M_GetText(" not found, md5: "));
{ {
INT32 j; INT32 j;
@ -296,7 +321,7 @@ boolean CL_SendRequestFile(void)
netbuffer->packettype = PT_REQUESTFILE; netbuffer->packettype = PT_REQUESTFILE;
p = (char *)netbuffer->u.textcmd; p = (char *)netbuffer->u.textcmd;
for (i = 0; i < fileneedednum; i++) for (i = 0; i < fileneedednum; i++)
if ((fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD)) if ((fileneeded[i].status == FS_NOTFOUND || fileneeded[i].status == FS_MD5SUMBAD || fileneeded[i].status == FS_FALLBACK))
{ {
totalfreespaceneeded += fileneeded[i].totalsize; totalfreespaceneeded += fileneeded[i].totalsize;
nameonly(fileneeded[i].filename); nameonly(fileneeded[i].filename);
@ -1015,3 +1040,153 @@ filestatus_t findfile(char *filename, const UINT8 *wantedmd5sum, boolean complet
return (badmd5 ? FS_MD5SUMBAD : FS_NOTFOUND); // md5 sum bad or file not found return (badmd5 ? FS_MD5SUMBAD : FS_NOTFOUND); // md5 sum bad or file not found
} }
#ifdef HAVE_CURL
size_t curlwrite_data(void *ptr, size_t size, size_t nmemb, FILE *stream)
{
size_t written;
written = fwrite(ptr, size, nmemb, stream);
return written;
}
int curlprogress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
{
(void)clientp;
(void)ultotal;
(void)ulnow; // Function prototype requires these but we won't use, so just discard
curl_dlnow = dlnow;
curl_dltotal = dltotal;
getbytes = curl_dlnow / (time(NULL) - curl_starttime); // To-do: Make this more accurate???
return 0;
}
void CURLPrepareFile(const char* url, int dfilenum)
{
#ifdef PARANOIA
if (M_CheckParm("-nodownload"))
I_Error("Attempted to download files in -nodownload mode");
#endif
curl_global_init(CURL_GLOBAL_ALL);
http_handle = curl_easy_init();
multi_handle = curl_multi_init();
if (http_handle && multi_handle)
{
I_mkdir(downloaddir, 0755);
curl_curfile = &fileneeded[dfilenum];
curl_realname = curl_curfile->filename;
nameonly(curl_realname);
curl_origfilesize = curl_curfile->currentsize;
curl_origtotalfilesize = curl_curfile->totalsize;
curl_easy_setopt(http_handle, CURLOPT_URL, va("%s/%s", url, curl_realname));
// Only allow HTTP and HTTPS
curl_easy_setopt(http_handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS);
curl_easy_setopt(http_handle, CURLOPT_USERAGENT, va("SRB2Kart/v%d.%d.%d", VERSION/100, VERSION%100, SUBVERSION)); // Set user agent as some servers won't accept invalid user agents.
// Follow a redirect request, if sent by the server.
curl_easy_setopt(http_handle, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(http_handle, CURLOPT_FAILONERROR, 1L);
CONS_Printf("Downloading %s from %s\n", curl_realname, url);
strcatbf(curl_curfile->filename, downloaddir, "/");
curl_curfile->file = fopen(curl_curfile->filename, "wb");
curl_easy_setopt(http_handle, CURLOPT_WRITEDATA, curl_curfile->file);
curl_easy_setopt(http_handle, CURLOPT_WRITEFUNCTION, curlwrite_data);
curl_easy_setopt(http_handle, CURLOPT_NOPROGRESS, 0L);
curl_easy_setopt(http_handle, CURLOPT_PROGRESSFUNCTION, curlprogress_callback);
curl_curfile->status = FS_DOWNLOADING;
lastfilenum = dfilenum;
curl_multi_add_handle(multi_handle, http_handle);
curl_multi_perform(multi_handle, &curl_runninghandles);
curl_starttime = time(NULL);
curl_running = true;
}
}
void CURLGetFile(void)
{
CURLMcode mc; /* return code used by curl_multi_wait() */
CURLcode easyres; /* Return from easy interface */
int numfds;
CURLMsg *m; /* for picking up messages with the transfer status */
CURL *e;
int msgs_left; /* how many messages are left */
const char *easy_handle_error;
long response_code = 0;
if (curl_runninghandles)
{
curl_multi_perform(multi_handle, &curl_runninghandles);
/* wait for activity, timeout or "nothing" */
mc = curl_multi_wait(multi_handle, NULL, 0, 1000, &numfds);
if (mc != CURLM_OK)
{
CONS_Alert(CONS_WARNING, "curl_multi_wait() failed, code %d.\n", mc);
return;
}
curl_curfile->currentsize = curl_dlnow;
curl_curfile->totalsize = curl_dltotal;
}
/* See how the transfers went */
while ((m = curl_multi_info_read(multi_handle, &msgs_left)))
{
if (m && (m->msg == CURLMSG_DONE))
{
e = m->easy_handle;
easyres = m->data.result;
if (easyres != CURLE_OK)
{
if (easyres == CURLE_HTTP_RETURNED_ERROR)
curl_easy_getinfo(e, CURLINFO_RESPONSE_CODE, &response_code);
easy_handle_error = (response_code) ? va("HTTP reponse code %ld", response_code) : curl_easy_strerror(easyres);
curl_curfile->status = FS_FALLBACK;
curl_curfile->currentsize = curl_origfilesize;
curl_curfile->totalsize = curl_origtotalfilesize;
curl_failedwebdownload = true;
fclose(curl_curfile->file);
remove(curl_curfile->filename);
curl_curfile->file = NULL;
//nameonly(curl_curfile->filename);
nameonly(curl_realname);
CONS_Printf(M_GetText("Failed to download %s (%s)\n"), curl_realname, easy_handle_error);
}
else
{
nameonly(curl_realname);
CONS_Printf(M_GetText("Finished downloading %s\n"), curl_realname);
curl_curfile->status = FS_FOUND;
fclose(curl_curfile->file);
}
curl_running = false;
curl_transfers--;
curl_multi_remove_handle(multi_handle, e);
curl_easy_cleanup(e);
if (!curl_transfers)
break;
}
}
if (!curl_transfers)
{
curl_multi_cleanup(multi_handle);
curl_global_cleanup();
}
}
#endif

View file

@ -30,7 +30,8 @@ typedef enum
FS_REQUESTED, FS_REQUESTED,
FS_DOWNLOADING, FS_DOWNLOADING,
FS_OPEN, // Is opened and used in w_wad FS_OPEN, // Is opened and used in w_wad
FS_MD5SUMBAD FS_MD5SUMBAD,
FS_FALLBACK, // HTTP failed
} filestatus_t; } filestatus_t;
typedef struct typedef struct
@ -53,6 +54,12 @@ extern char downloaddir[512];
extern INT32 lastfilenum; extern INT32 lastfilenum;
#endif #endif
#ifdef HAVE_CURL
extern boolean curl_failedwebdownload;
extern boolean curl_running;
extern INT32 curl_transfers;
#endif
UINT8 *PutFileNeeded(UINT16 firstfile); UINT8 *PutFileNeeded(UINT16 firstfile);
void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 firstfile); void D_ParseFileneeded(INT32 fileneedednum_parm, UINT8 *fileneededstr, UINT16 firstfile);
void CL_PrepareDownloadSaveGame(const char *tmpsave); void CL_PrepareDownloadSaveGame(const char *tmpsave);
@ -83,4 +90,9 @@ filestatus_t checkfilemd5(char *filename, const UINT8 *wantedmd5sum);
void nameonly(char *s); void nameonly(char *s);
size_t nameonlylength(const char *s); size_t nameonlylength(const char *s);
#ifdef HAVE_CURL
void CURLPrepareFile(const char* url, int dfilenum);
void CURLGetFile(void);
#endif
#endif // __D_NETFIL__ #endif // __D_NETFIL__

View file

@ -42,10 +42,6 @@
#include "r_draw.h" // translation colormap consts (for lua) #include "r_draw.h" // translation colormap consts (for lua)
#endif #endif
#ifdef HWRENDER
#include "hardware/hw_light.h"
#endif
#ifdef PC_DOS #ifdef PC_DOS
#include <stdio.h> // for snprintf #include <stdio.h> // for snprintf
//int snprintf(char *str, size_t n, const char *fmt, ...); //int snprintf(char *str, size_t n, const char *fmt, ...);
@ -335,21 +331,6 @@ static INT32 searchvalue(const char *s)
} }
} }
#ifdef HWRENDER
static float searchfvalue(const char *s)
{
while (s[0] != '=' && s[0])
s++;
if (s[0] == '=')
return (float)atof(&s[1]);
else
{
deh_warning("No value found");
return 0;
}
}
#endif
// These are for clearing all of various things // These are for clearing all of various things
static void clear_conditionsets(void) static void clear_conditionsets(void)
{ {
@ -854,128 +835,6 @@ static void readthing(MYFILE *f, INT32 num)
Z_Free(s); Z_Free(s);
} }
#ifdef HWRENDER
static void readlight(MYFILE *f, INT32 num)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
char *word;
char *tmp;
INT32 value;
float fvalue;
do
{
if (myfgets(s, MAXLINELEN, f))
{
if (s[0] == '\n')
break;
tmp = strchr(s, '#');
if (tmp)
*tmp = '\0';
if (s == tmp)
continue; // Skip comment lines, but don't break.
fvalue = searchfvalue(s);
value = searchvalue(s);
word = strtok(s, " ");
if (word)
strupr(word);
else
break;
if (fastcmp(word, "TYPE"))
{
DEH_WriteUndoline(word, va("%d", lspr[num].type), UNDO_NONE);
lspr[num].type = (UINT16)value;
}
else if (fastcmp(word, "OFFSETX"))
{
DEH_WriteUndoline(word, va("%f", lspr[num].light_xoffset), UNDO_NONE);
lspr[num].light_xoffset = fvalue;
}
else if (fastcmp(word, "OFFSETY"))
{
DEH_WriteUndoline(word, va("%f", lspr[num].light_yoffset), UNDO_NONE);
lspr[num].light_yoffset = fvalue;
}
else if (fastcmp(word, "CORONACOLOR"))
{
DEH_WriteUndoline(word, va("%u", lspr[num].corona_color), UNDO_NONE);
lspr[num].corona_color = value;
}
else if (fastcmp(word, "CORONARADIUS"))
{
DEH_WriteUndoline(word, va("%f", lspr[num].corona_radius), UNDO_NONE);
lspr[num].corona_radius = fvalue;
}
else if (fastcmp(word, "DYNAMICCOLOR"))
{
DEH_WriteUndoline(word, va("%u", lspr[num].dynamic_color), UNDO_NONE);
lspr[num].dynamic_color = value;
}
else if (fastcmp(word, "DYNAMICRADIUS"))
{
DEH_WriteUndoline(word, va("%f", lspr[num].dynamic_radius), UNDO_NONE);
lspr[num].dynamic_radius = fvalue;
/// \note Update the sqrradius! unnecessary?
lspr[num].dynamic_sqrradius = fvalue * fvalue;
}
else
deh_warning("Light %d: unknown word '%s'", num, word);
}
} while (!myfeof(f)); // finish when the line is empty
Z_Free(s);
}
static void readspritelight(MYFILE *f, INT32 num)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
char *word;
char *tmp;
INT32 value;
do
{
if (myfgets(s, MAXLINELEN, f))
{
if (s[0] == '\n')
break;
tmp = strchr(s, '#');
if (tmp)
*tmp = '\0';
if (s == tmp)
continue; // Skip comment lines, but don't break.
value = searchvalue(s);
word = strtok(s, " ");
if (word)
strupr(word);
else
break;
if (fastcmp(word, "LIGHTTYPE"))
{
INT32 oldvar;
for (oldvar = 0; t_lspr[num] != &lspr[oldvar]; oldvar++)
;
DEH_WriteUndoline(word, va("%d", oldvar), UNDO_NONE);
t_lspr[num] = &lspr[value];
}
else
deh_warning("Sprite %d: unknown word '%s'", num, word);
}
} while (!myfeof(f)); // finish when the line is empty
Z_Free(s);
}
#endif // HWRENDER
static const struct { static const struct {
const char *name; const char *name;
const UINT16 flag; const UINT16 flag;
@ -3513,37 +3372,6 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
readAnimTex(f, i); readAnimTex(f, i);
// This is not a major mod. // This is not a major mod.
}*/ }*/
else if (fastcmp(word, "LIGHT"))
{
#ifdef HWRENDER
// TODO: Read lights by name
if (i > 0 && i < NUMLIGHTS)
readlight(f, i);
else
{
deh_warning("Light number %d out of range (1 - %d)", i, NUMLIGHTS-1);
ignorelines(f);
}
DEH_WriteUndoline(word, word2, UNDO_HEADER);
// This is not a major mod.
#endif
}
else if (fastcmp(word, "SPRITE"))
{
#ifdef HWRENDER
if (i == 0 && word2[0] != '0') // If word2 isn't a number
i = get_sprite(word2); // find a sprite by name
if (i < NUMSPRITES && i >= 0)
readspritelight(f, i);
else
{
deh_warning("Sprite number %d out of range (0 - %d)", i, NUMSPRITES-1);
ignorelines(f);
}
DEH_WriteUndoline(word, word2, UNDO_HEADER);
// This is not a major mod.
#endif
}
else if (fastcmp(word, "LEVEL")) else if (fastcmp(word, "LEVEL"))
{ {
// Support using the actual map name, // Support using the actual map name,
@ -7391,7 +7219,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
// Castle Eggman Scenery // Castle Eggman Scenery
"MT_CHAIN", // CEZ Chain "MT_CHAIN", // CEZ Chain
"MT_FLAME", // Flame (has corona) "MT_FLAME", // Flame
"MT_EGGSTATUE", // Eggman Statue "MT_EGGSTATUE", // Eggman Statue
"MT_MACEPOINT", // Mace rotation point "MT_MACEPOINT", // Mace rotation point
"MT_SWINGMACEPOINT", // Mace swinging point "MT_SWINGMACEPOINT", // Mace swinging point
@ -9799,8 +9627,7 @@ static inline int lib_getenum(lua_State *L)
if (mathlib) return luaL_error(L, "constant '%s' could not be parsed.\n", word); if (mathlib) return luaL_error(L, "constant '%s' could not be parsed.\n", word);
// DYNAMIC variables too!! // DYNAMIC variables too!!
// Try not to add anything that would break netgames or timeattack replays here.
// You know, like consoleplayer, displayplayers, or gametime.
if (fastcmp(word,"gamemap")) { if (fastcmp(word,"gamemap")) {
lua_pushinteger(L, gamemap); lua_pushinteger(L, gamemap);
return 1; return 1;
@ -9881,24 +9708,23 @@ static inline int lib_getenum(lua_State *L)
return 0; return 0;
LUA_PushUserdata(L, &players[serverplayer], META_PLAYER); LUA_PushUserdata(L, &players[serverplayer], META_PLAYER);
return 1; return 1;
} else if (fastcmp(word,"consoleplayer")) { // Player controlling the console, basically our local player
if (consoleplayer < 0 || !playeringame[consoleplayer])
return 0;
LUA_PushUserdata(L, &players[consoleplayer], META_PLAYER);
return 1;
/*} else if (fastcmp(word,"admin")) { /*} else if (fastcmp(word,"admin")) {
LUA_Deprecated(L, "admin", "IsPlayerAdmin(player)"); LUA_Deprecated(L, "admin", "IsPlayerAdmin(player)");
if (!playeringame[adminplayers[0]] || IsPlayerAdmin(serverplayer)) if (!playeringame[adminplayers[0]] || IsPlayerAdmin(serverplayer))
return 0; return 0;
LUA_PushUserdata(L, &players[adminplayers[0]], META_PLAYER); LUA_PushUserdata(L, &players[adminplayers[0]], META_PLAYER);
return 1;*/ return 1;*/
} else if (fastcmp(word,"emeralds")) {
lua_pushinteger(L, emeralds);
return 1;
} else if (fastcmp(word,"gravity")) { } else if (fastcmp(word,"gravity")) {
lua_pushinteger(L, gravity); lua_pushinteger(L, gravity);
return 1; return 1;
} else if (fastcmp(word,"VERSIONSTRING")) { } else if (fastcmp(word,"VERSIONSTRING")) {
lua_pushstring(L, VERSIONSTRING); lua_pushstring(L, VERSIONSTRING);
return 1; return 1;
} else if (fastcmp(word, "token")) {
lua_pushinteger(L, token);
return 1;
} else if (fastcmp(word,"gamespeed")) { } else if (fastcmp(word,"gamespeed")) {
lua_pushinteger(L, gamespeed); lua_pushinteger(L, gamespeed);
return 1; return 1;
@ -9932,6 +9758,12 @@ static inline int lib_getenum(lua_State *L)
} else if (fastcmp(word,"numlaps")) { } else if (fastcmp(word,"numlaps")) {
lua_pushinteger(L, cv_numlaps.value); lua_pushinteger(L, cv_numlaps.value);
return 1; return 1;
} else if (fastcmp(word,"racecountdown")) {
lua_pushinteger(L, racecountdown);
return 1;
} else if (fastcmp(word,"exitcountdown")) {
lua_pushinteger(L, exitcountdown); // This name is pretty dumb. Hence why we'll prefer more descriptive names at least in Lua...
return 1;
} }
return 0; return 0;
} }

View file

@ -138,8 +138,12 @@
#ifdef LOGMESSAGES #ifdef LOGMESSAGES
extern FILE *logstream; extern FILE *logstream;
extern char logfilename[1024];
#endif #endif
/* A mod name to further distinguish versions. */
#define SRB2APPLICATION "SRB2Kart"
//#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3 //#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3
#ifdef DEVELOP #ifdef DEVELOP
#define VERSION 0 // Game version #define VERSION 0 // Game version
@ -149,10 +153,10 @@ extern FILE *logstream;
// most interface strings are ignored in development mode. // most interface strings are ignored in development mode.
// we use comprevision and compbranch instead. // we use comprevision and compbranch instead.
#else #else
#define VERSION 110 // Game version #define VERSION 1 // Game version
#define SUBVERSION 0 // more precise version number #define SUBVERSION 2 // more precise version number
#define VERSIONSTRING "v1.1" #define VERSIONSTRING "v1.2"
#define VERSIONSTRINGW L"v1.1" #define VERSIONSTRINGW L"v1.2"
// Hey! If you change this, add 1 to the MODVERSION below! Otherwise we can't force updates! // Hey! If you change this, add 1 to the MODVERSION below! Otherwise we can't force updates!
// And change CMakeLists.txt, for CMake users! // And change CMakeLists.txt, for CMake users!
// AND appveyor.yml, for the build bots! // AND appveyor.yml, for the build bots!
@ -225,7 +229,7 @@ extern FILE *logstream;
// it's only for detection of the version the player is using so the MS can alert them of an update. // it's only for detection of the version the player is using so the MS can alert them of an update.
// Only set it higher, not lower, obviously. // Only set it higher, not lower, obviously.
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1". // Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
#define MODVERSION 5 #define MODVERSION 6
// Filter consvars by version // Filter consvars by version
// To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically. // To version config.cfg, MAJOREXECVERSION is set equal to MODVERSION automatically.
@ -548,6 +552,9 @@ extern INT32 cv_debug;
extern UINT8 shiftdown, ctrldown, altdown; extern UINT8 shiftdown, ctrldown, altdown;
extern boolean capslock; extern boolean capslock;
// WARNING: a should be unsigned but to add with 2048, it isn't!
#define AIMINGTODY(a) (FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160)
// if we ever make our alloc stuff... // if we ever make our alloc stuff...
#define ZZ_Alloc(x) Z_Malloc(x, PU_STATIC, NULL) #define ZZ_Alloc(x) Z_Malloc(x, PU_STATIC, NULL)
@ -633,11 +640,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Most modifications should probably enable this. /// Most modifications should probably enable this.
//#define SAVEGAME_OTHERVERSIONS //#define SAVEGAME_OTHERVERSIONS
#if !defined (_NDS) && !defined (_PSP)
/// Shuffle's incomplete OpenGL sorting code.
#define SHUFFLE // This has nothing to do with sorting, why was it disabled?
#endif
#if !defined (_NDS) && !defined (_PSP) #if !defined (_NDS) && !defined (_PSP)
/// Allow the use of the SOC RESETINFO command. /// Allow the use of the SOC RESETINFO command.
/// \note Builds that are tight on memory should disable this. /// \note Builds that are tight on memory should disable this.
@ -674,6 +676,9 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// on the bright side it fixes some weird issues with translucent walls /// on the bright side it fixes some weird issues with translucent walls
/// \note SRB2CB port. /// \note SRB2CB port.
/// SRB2CB itself ported this from PrBoom+ /// SRB2CB itself ported this from PrBoom+
#define NEWCLIP //#define NEWCLIP
/// Hardware renderer: OpenGL
#define GL_SHADERS
#endif // __DOOMDEF__ #endif // __DOOMDEF__

View file

@ -448,7 +448,7 @@ extern UINT8 maxXtraLife; // Max extra lives from rings
extern mobj_t *hunt1, *hunt2, *hunt3; // Emerald hunt locations extern mobj_t *hunt1, *hunt2, *hunt3; // Emerald hunt locations
// For racing // For racing
extern UINT32 countdown, countdown2; extern tic_t racecountdown, exitcountdown;
extern fixed_t gravity; extern fixed_t gravity;
extern fixed_t mapobjectscale; extern fixed_t mapobjectscale;
@ -549,7 +549,7 @@ extern consvar_t cv_downloading; // allow clients to downloading WADs.
extern consvar_t cv_nettimeout; // SRB2Kart: Advanced server options menu extern consvar_t cv_nettimeout; // SRB2Kart: Advanced server options menu
extern consvar_t cv_jointimeout; extern consvar_t cv_jointimeout;
extern consvar_t cv_maxping; extern consvar_t cv_maxping;
extern ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS]; extern ticcmd_t netcmds[TICQUEUE][MAXPLAYERS];
extern INT32 serverplayer; extern INT32 serverplayer;
extern INT32 adminplayers[MAXPLAYERS]; extern INT32 adminplayers[MAXPLAYERS];

View file

@ -449,6 +449,7 @@ static const char *credits[] = {
"\"Lat\'\"", "\"Lat\'\"",
"\"Monster Iestyn\"", "\"Monster Iestyn\"",
"\"Shuffle\"", "\"Shuffle\"",
"\"SteelT\"",
"", "",
"\1Lead Artists", "\1Lead Artists",
"Desmond \"Blade\" DesJardins", "Desmond \"Blade\" DesJardins",
@ -473,17 +474,17 @@ static const char *credits[] = {
"\"DirkTheHusky\"", "\"DirkTheHusky\"",
"\"LJSTAR\"", "\"LJSTAR\"",
"\"MotorRoach\"", "\"MotorRoach\"",
"\"Mr. McScrewup\"",
"\"Nev3r\"", "\"Nev3r\"",
"\"rairai104n\"",
"\"Ritz\"", "\"Ritz\"",
"\"Rob\"", "\"Rob\"",
"\"SmithyGNC\"", "\"SmithyGNC\"",
"\"Snu\"", "\"Snu\"",
"\"Spherallic\"", "\"Spherallic\"",
"\"TelosTurntable\"",
"\"VAdaPEGA\"", "\"VAdaPEGA\"",
"\"Virt\"", "\"Virt\"",
"\"Voltrix\"", "\"Voltrix\"",
"\"zxyspku\"",
"", "",
"\1Sound Design", "\1Sound Design",
"James \"SeventhSentinel\" Hall", "James \"SeventhSentinel\" Hall",
@ -511,6 +512,7 @@ static const char *credits[] = {
"Sherman \"CoatRack\" DesJardins", "Sherman \"CoatRack\" DesJardins",
"Colette \"fickleheart\" Bordelon", "Colette \"fickleheart\" Bordelon",
"Vivian \"toaster\" Grannell", "Vivian \"toaster\" Grannell",
"\"Gunla\"",
"James \"SeventhSentinel\" Hall", "James \"SeventhSentinel\" Hall",
"\"Lat\'\"", "\"Lat\'\"",
"\"MK\"", "\"MK\"",
@ -573,7 +575,7 @@ static struct {
// This Tyler52 gag is troublesome // This Tyler52 gag is troublesome
// Alignment should be ((spaces+1 * 100) + (headers+1 * 38) + (lines * 15)) // Alignment should be ((spaces+1 * 100) + (headers+1 * 38) + (lines * 15))
// Current max image spacing: (200*17) // Current max image spacing: (200*17)
{112, (15*100)+(17*38)+(86*15), "TYLER52", SKINCOLOR_NONE}, {112, (15*100)+(17*38)+(88*15), "TYLER52", SKINCOLOR_NONE},
{0, 0, NULL, SKINCOLOR_NONE} {0, 0, NULL, SKINCOLOR_NONE}
}; };

View file

@ -373,7 +373,9 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
HWR_DoWipe(wipetype, wipeframe-1); // send in the wipe type and wipeframe because we need to cache the graphic HWR_DoWipe(wipetype, wipeframe-1); // send in the wipe type and wipeframe because we need to cache the graphic
else else
#endif #endif
if (rendermode != render_none) //this allows F_RunWipe to be called in dedicated servers
F_DoWipe(fmask); F_DoWipe(fmask);
I_OsPolling(); I_OsPolling();
I_UpdateNoBlit(); I_UpdateNoBlit();

View file

@ -43,7 +43,9 @@
#include "y_inter.h" #include "y_inter.h"
#include "v_video.h" #include "v_video.h"
#include "dehacked.h" // get_number (for ghost thok) #include "dehacked.h" // get_number (for ghost thok)
#include "lua_script.h" // LUA_ArchiveDemo and LUA_UnArchiveDemo
#include "lua_hook.h" #include "lua_hook.h"
#include "lua_libs.h" // gL (Lua state)
#include "b_bot.h" #include "b_bot.h"
#include "m_cond.h" // condition sets #include "m_cond.h" // condition sets
#include "md5.h" // demo checksums #include "md5.h" // demo checksums
@ -233,7 +235,7 @@ mobj_t *hunt1;
mobj_t *hunt2; mobj_t *hunt2;
mobj_t *hunt3; mobj_t *hunt3;
UINT32 countdown, countdown2; // for racing tic_t racecountdown, exitcountdown; // for racing
fixed_t gravity; fixed_t gravity;
fixed_t mapobjectscale; fixed_t mapobjectscale;
@ -287,7 +289,8 @@ UINT32 timesBeatenWithEmeralds;
//@TODO put these all in a struct for namespacing purposes? //@TODO put these all in a struct for namespacing purposes?
static char demoname[128]; static char demoname[128];
static UINT8 *demobuffer = NULL; static UINT8 *demobuffer = NULL;
static UINT8 *demo_p, *demotime_p, *demoinfo_p; static UINT8 *demotime_p, *demoinfo_p;
UINT8 *demo_p;
static UINT8 *demoend; static UINT8 *demoend;
static UINT8 demoflags; static UINT8 demoflags;
static boolean demosynced = true; // console warning message static boolean demosynced = true; // console warning message
@ -782,7 +785,7 @@ void G_SetGameModified(boolean silent, boolean major)
majormods = true; majormods = true;
if (!silent) if (!silent)
CONS_Alert(CONS_NOTICE, M_GetText("Game must be restarted to play record attack.\n")); CONS_Alert(CONS_NOTICE, M_GetText("Game must be restarted to play Record Attack.\n"));
// If in record attack recording, cancel it. // If in record attack recording, cancel it.
if (modeattacking) if (modeattacking)
@ -1884,7 +1887,7 @@ boolean G_Responder(event_t *ev)
} }
} }
if (gamestate == GS_LEVEL && ev->type == ev_keydown && multiplayer && demo.playback) if (gamestate == GS_LEVEL && ev->type == ev_keydown && multiplayer && demo.playback && !demo.freecam)
{ {
if (ev->data1 == gamecontrolbis[gc_viewpoint][0] || ev->data1 == gamecontrolbis[gc_viewpoint][1]) if (ev->data1 == gamecontrolbis[gc_viewpoint][0] || ev->data1 == gamecontrolbis[gc_viewpoint][1])
{ {
@ -1928,11 +1931,8 @@ boolean G_Responder(event_t *ev)
return true; return true;
} }
// Anything else opens the menu if not already open, except for a few keys... // open menu but only w/ esc
if (!( if (ev->data1 == 32)
// Rankings
ev->data1 == gamecontrol[gc_scores][0] || ev->data1 == gamecontrol[gc_scores][1]
))
{ {
M_StartControlPanel(); M_StartControlPanel();
@ -2320,6 +2320,12 @@ void G_Ticker(boolean run)
UINT32 i; UINT32 i;
INT32 buf; INT32 buf;
ticcmd_t *cmd; ticcmd_t *cmd;
UINT32 ra_timeskip = (modeattacking && !demo.playback && leveltime < starttime - TICRATE*4) ? 0 : (starttime - TICRATE*4 - 1);
// starttime - TICRATE*4 is where we want RA to start when we PLAY IT, so we will loop the main thinker on RA start to get it to this point,
// the reason this is done is to ensure that ghosts won't look out of synch with other map elements (objects, moving platforms...)
// when we REPLAY, don't skip, let the camera spin, do its thing etc~
// also the -1 is to ensure that the thinker runs in the loop below.
P_MapStart(); P_MapStart();
// do player reborns if needed // do player reborns if needed
@ -2358,7 +2364,7 @@ void G_Ticker(boolean run)
default: I_Error("gameaction = %d\n", gameaction); default: I_Error("gameaction = %d\n", gameaction);
} }
buf = gametic % BACKUPTICS; buf = gametic % TICQUEUE;
if (!demo.playback) if (!demo.playback)
// read/write demo and check turbo cheat // read/write demo and check turbo cheat
@ -2392,12 +2398,16 @@ void G_Ticker(boolean run)
switch (gamestate) switch (gamestate)
{ {
case GS_LEVEL: case GS_LEVEL:
for (; ra_timeskip < starttime - TICRATE*4; ra_timeskip++) // this looks weird but this is done to not break compability with older demos for now.
{
if (demo.title) if (demo.title)
F_TitleDemoTicker(); F_TitleDemoTicker();
P_Ticker(run); // tic the game P_Ticker(run); // tic the game
ST_Ticker(); ST_Ticker();
AM_Ticker(); AM_Ticker();
HU_Ticker(); HU_Ticker();
}
break; break;
case GS_INTERMISSION: case GS_INTERMISSION:
@ -4583,7 +4593,7 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool
{ {
// Clear a bunch of variables // Clear a bunch of variables
tokenlist = token = sstimer = redscore = bluescore = lastmap = 0; tokenlist = token = sstimer = redscore = bluescore = lastmap = 0;
countdown = countdown2 = mapreset = 0; racecountdown = exitcountdown = mapreset = 0;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {
@ -4737,6 +4747,11 @@ char *G_BuildMapTitle(INT32 mapnum)
#define DF_RECORDATTACK 0x02 // This demo is from record attack and contains its final completion time! #define DF_RECORDATTACK 0x02 // This demo is from record attack and contains its final completion time!
#define DF_NIGHTSATTACK 0x04 // This demo is from NiGHTS attack and contains its time left, score, and mares! #define DF_NIGHTSATTACK 0x04 // This demo is from NiGHTS attack and contains its time left, score, and mares!
#define DF_ATTACKMASK 0x06 // This demo is from ??? attack and contains ??? #define DF_ATTACKMASK 0x06 // This demo is from ??? attack and contains ???
#ifdef HAVE_BLUA
#define DF_LUAVARS 0x20 // this demo contains extra lua vars; this is mostly used for backwards compability
#endif
#define DF_ATTACKSHIFT 1 #define DF_ATTACKSHIFT 1
#define DF_ENCORE 0x40 #define DF_ENCORE 0x40
#define DF_MULTIPLAYER 0x80 // This demo was recorded in multiplayer mode! #define DF_MULTIPLAYER 0x80 // This demo was recorded in multiplayer mode!
@ -4863,6 +4878,16 @@ void G_ReadDemoExtraData(void)
INT32 p, extradata, i; INT32 p, extradata, i;
char name[17]; char name[17];
if (leveltime > starttime)
{
rewind_t *rewind = CL_SaveRewindPoint(demo_p - demobuffer);
if (rewind)
{
memcpy(rewind->oldcmd, oldcmd, sizeof (oldcmd));
memcpy(rewind->oldghost, oldghost, sizeof (oldghost));
}
}
memset(name, '\0', 17); memset(name, '\0', 17);
p = READUINT8(demo_p); p = READUINT8(demo_p);
@ -5901,6 +5926,8 @@ static rewindinfo_t *rewindhead = NULL; // Reverse chronological order
void G_InitDemoRewind(void) void G_InitDemoRewind(void)
{ {
CL_ClearRewinds();
while (rewindhead) while (rewindhead)
{ {
rewindinfo_t *p = rewindhead->prev; rewindinfo_t *p = rewindhead->prev;
@ -6022,19 +6049,35 @@ void G_ConfirmRewind(tic_t rewindtime)
CV_StealthSetValue(&cv_renderview, 0); CV_StealthSetValue(&cv_renderview, 0);
if (rewindtime > starttime) if (rewindtime <= starttime)
{ {
sound_disabled = true; // Prevent sound spam demo.rewinding = false;
demo.rewinding = true; G_DoPlayDemo(NULL); // Restart the current demo
} }
else else
demo.rewinding = false; {
rewind_t *rewind;
sound_disabled = true; // Prevent sound spam
demo.rewinding = true;
rewind = CL_RewindToTime(rewindtime);
if (rewind)
{
demo_p = demobuffer + rewind->demopos;
memcpy(oldcmd, rewind->oldcmd, sizeof (oldcmd));
memcpy(oldghost, rewind->oldghost, sizeof (oldghost));
paused = false;
}
else
{
demo.rewinding = true;
G_DoPlayDemo(NULL); // Restart the current demo G_DoPlayDemo(NULL); // Restart the current demo
}
}
for (j = 0; j < rewindtime && leveltime < rewindtime; j++) for (j = 0; j < rewindtime && leveltime < rewindtime; j++)
{ {
//TryRunTics(1);
G_Ticker((j % NEWTICRATERATIO) == 0); G_Ticker((j % NEWTICRATERATIO) == 0);
} }
@ -6046,6 +6089,9 @@ void G_ConfirmRewind(tic_t rewindtime)
COM_BufInsertText("renderview on\n"); COM_BufInsertText("renderview on\n");
if (demo.freecam)
return; // don't touch from there
splitscreen = oldss; splitscreen = oldss;
displayplayers[0] = olddp1; displayplayers[0] = olddp1;
displayplayers[1] = olddp2; displayplayers[1] = olddp2;
@ -6321,6 +6367,10 @@ void G_BeginRecording(void)
if (encoremode) if (encoremode)
demoflags |= DF_ENCORE; demoflags |= DF_ENCORE;
#ifdef HAVE_BLUA
demoflags |= DF_LUAVARS;
#endif
// Setup header. // Setup header.
M_Memcpy(demo_p, DEMOHEADER, 12); demo_p += 12; M_Memcpy(demo_p, DEMOHEADER, 12); demo_p += 12;
WRITEUINT8(demo_p,VERSION); WRITEUINT8(demo_p,VERSION);
@ -6417,11 +6467,17 @@ void G_BeginRecording(void)
// Kart speed and weight // Kart speed and weight
WRITEUINT8(demo_p, skins[player->skin].kartspeed); WRITEUINT8(demo_p, skins[player->skin].kartspeed);
WRITEUINT8(demo_p, skins[player->skin].kartweight); WRITEUINT8(demo_p, skins[player->skin].kartweight);
} }
} }
WRITEUINT8(demo_p, 0xFF); // Denote the end of the player listing WRITEUINT8(demo_p, 0xFF); // Denote the end of the player listing
#ifdef HAVE_BLUA
// player lua vars, always saved even if empty
LUA_ArchiveDemo();
#endif
memset(&oldcmd,0,sizeof(oldcmd)); memset(&oldcmd,0,sizeof(oldcmd));
memset(&oldghost,0,sizeof(oldghost)); memset(&oldghost,0,sizeof(oldghost));
memset(&ghostext,0,sizeof(ghostext)); memset(&ghostext,0,sizeof(ghostext));
@ -6573,7 +6629,7 @@ static void G_LoadDemoExtraFiles(UINT8 **pp)
{ {
CONS_Alert(CONS_WARNING, M_GetText("Too many files loaded to add anymore for demo playback\n")); CONS_Alert(CONS_WARNING, M_GetText("Too many files loaded to add anymore for demo playback\n"));
if (!CON_Ready()) if (!CON_Ready())
M_StartMessage(M_GetText("There are too many files loaded to add this demo's add-ons.\n\nDemo playback may desync.\n\nPress ESC\n"), NULL, MM_NOTHING); M_StartMessage(M_GetText("There are too many files loaded to add this demo's addons.\n\nDemo playback may desync.\n\nPress ESC\n"), NULL, MM_NOTHING);
} }
else if (ncs != FS_FOUND) else if (ncs != FS_FOUND)
{ {
@ -6585,7 +6641,7 @@ static void G_LoadDemoExtraFiles(UINT8 **pp)
CONS_Alert(CONS_NOTICE, M_GetText("Unknown error finding file %s\n"), filename); CONS_Alert(CONS_NOTICE, M_GetText("Unknown error finding file %s\n"), filename);
if (!CON_Ready()) if (!CON_Ready())
M_StartMessage(M_GetText("There were errors trying to add this demo's add-ons. Check the console for more information.\n\nDemo playback may desync.\n\nPress ESC\n"), NULL, MM_NOTHING); M_StartMessage(M_GetText("There were errors trying to add this demo's addons. Check the console for more information.\n\nDemo playback may desync.\n\nPress ESC\n"), NULL, MM_NOTHING);
} }
else else
{ {
@ -7416,7 +7472,7 @@ void G_DoPlayDemo(char *defdemoname)
if (modeattacking) if (modeattacking)
{ {
snprintf(msg, 1024, M_GetText("%s is a record attack replay with spectators, and is thus invalid.\n"), pdemoname); snprintf(msg, 1024, M_GetText("%s is a Record Attack replay with spectators, and is thus invalid.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg); CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, NULL, MM_NOTHING); M_StartMessage(msg, NULL, MM_NOTHING);
Z_Free(pdemoname); Z_Free(pdemoname);
@ -7430,7 +7486,7 @@ void G_DoPlayDemo(char *defdemoname)
if (modeattacking && numslots > 1) if (modeattacking && numslots > 1)
{ {
snprintf(msg, 1024, M_GetText("%s is a record attack replay with multiple players, and is thus invalid.\n"), pdemoname); snprintf(msg, 1024, M_GetText("%s is a Record Attack replay with multiple players, and is thus invalid.\n"), pdemoname);
CONS_Alert(CONS_ERROR, "%s", msg); CONS_Alert(CONS_ERROR, "%s", msg);
M_StartMessage(msg, NULL, MM_NOTHING); M_StartMessage(msg, NULL, MM_NOTHING);
Z_Free(pdemoname); Z_Free(pdemoname);
@ -7479,6 +7535,18 @@ void G_DoPlayDemo(char *defdemoname)
p = READUINT8(demo_p); p = READUINT8(demo_p);
} }
// end of player read (the 0xFF marker)
// so this is where we are to read our lua variables (if possible!)
#ifdef HAVE_BLUA
if (demoflags & DF_LUAVARS) // again, used for compability, lua shit will be saved to replays regardless of if it's even been loaded
{
if (!gL) // No Lua state! ...I guess we'll just start one...
LUA_ClearState();
LUA_UnArchiveDemo();
}
#endif
splitscreen = 0; splitscreen = 0;
if (demo.title) if (demo.title)
@ -8091,8 +8159,18 @@ void G_StopDemo(void)
demo.timing = false; demo.timing = false;
singletics = false; singletics = false;
demo.freecam = false;
// reset democam shit too:
democam.cam = NULL;
democam.soundmobj = NULL;
democam.localangle = 0;
democam.localaiming = 0;
democam.turnheld = false;
democam.keyboardlook = false;
CV_SetValue(&cv_playbackspeed, 1); CV_SetValue(&cv_playbackspeed, 1);
demo.rewinding = false; demo.rewinding = false;
CL_ClearRewinds();
if (gamestate == GS_LEVEL && rendermode != render_none) if (gamestate == GS_LEVEL && rendermode != render_none)
{ {

View file

@ -31,6 +31,8 @@ extern char player_names[MAXPLAYERS][MAXPLAYERNAME+1];
extern player_t players[MAXPLAYERS]; extern player_t players[MAXPLAYERS];
extern boolean playeringame[MAXPLAYERS]; extern boolean playeringame[MAXPLAYERS];
extern UINT8 *demo_p;
// ====================================== // ======================================
// DEMO playback/recording related stuff. // DEMO playback/recording related stuff.
// ====================================== // ======================================
@ -60,6 +62,9 @@ struct demovars_s {
DSM_WILLSAVE, DSM_WILLSAVE,
DSM_SAVED DSM_SAVED
} savemode; } savemode;
boolean freecam;
}; };
extern struct demovars_s demo; extern struct demovars_s demo;

View file

@ -1,17 +1,12 @@
// Emacs style mode select -*- C++ -*- // SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// // Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2019 by Sonic Team Junior.
// //
// This program is free software; you can redistribute it and/or // This program is free software distributed under the
// modify it under the terms of the GNU General Public License // terms of the GNU General Public License, version 2.
// as published by the Free Software Foundation; either version 2 // See the 'LICENSE' file for more details.
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/// \file /// \file
/// \brief convert SRB2 map /// \brief convert SRB2 map
@ -19,6 +14,7 @@
#include "../doomdef.h" #include "../doomdef.h"
#include "../doomstat.h" #include "../doomstat.h"
#ifdef HWRENDER #ifdef HWRENDER
#include "hw_main.h"
#include "hw_glob.h" #include "hw_glob.h"
#include "../r_local.h" #include "../r_local.h"
#include "../z_zone.h" #include "../z_zone.h"
@ -60,77 +56,12 @@ static INT32 totalsubsecpolys = 0;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Polygon fast alloc / free // Polygon fast alloc / free
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
//hurdler: quick fix for those who wants to play with larger wad
#define ZPLANALLOC
#ifndef ZPLANALLOC
//#define POLYPOOLSIZE 1024000 // may be much over what is needed
/// \todo check out how much is used
static size_t POLYPOOLSIZE = 1024000;
static UINT8 *gr_polypool = NULL;
static UINT8 *gr_ppcurrent;
static size_t gr_ppfree;
#endif
// only between levels, clear poly pool
static void HWR_ClearPolys(void)
{
#ifndef ZPLANALLOC
gr_ppcurrent = gr_polypool;
gr_ppfree = POLYPOOLSIZE;
#endif
}
// allocate pool for fast alloc of polys
void HWR_InitPolyPool(void)
{
#ifndef ZPLANALLOC
INT32 pnum;
//hurdler: quick fix for those who wants to play with larger wad
if ((pnum = M_CheckParm("-polypoolsize")))
POLYPOOLSIZE = atoi(myargv[pnum+1])*1024; // (in kb)
CONS_Debug(DBG_RENDER, "HWR_InitPolyPool(): allocating %d bytes\n", POLYPOOLSIZE);
gr_polypool = malloc(POLYPOOLSIZE);
if (!gr_polypool)
I_Error("HWR_InitPolyPool(): couldn't malloc polypool\n");
HWR_ClearPolys();
#endif
}
void HWR_FreePolyPool(void)
{
#ifndef ZPLANALLOC
if (gr_polypool)
free(gr_polypool);
gr_polypool = NULL;
#endif
}
static poly_t *HWR_AllocPoly(INT32 numpts) static poly_t *HWR_AllocPoly(INT32 numpts)
{ {
poly_t *p; poly_t *p;
size_t size = sizeof (poly_t) + sizeof (polyvertex_t) * numpts; size_t size = sizeof (poly_t) + sizeof (polyvertex_t) * numpts;
#ifdef ZPLANALLOC
p = Z_Malloc(size, PU_HWRPLANE, NULL); p = Z_Malloc(size, PU_HWRPLANE, NULL);
#else
#ifdef PARANOIA
if (!gr_polypool)
I_Error("Used gr_polypool without init!\n");
if (!gr_ppcurrent)
I_Error("gr_ppcurrent == NULL!\n");
#endif
if (gr_ppfree < size)
I_Error("HWR_AllocPoly(): no more memory %u bytes left, %u bytes needed\n\n%s\n",
gr_ppfree, size, "You can try the param -polypoolsize 2048 (or higher if needed)");
p = (poly_t *)gr_ppcurrent;
gr_ppcurrent += size;
gr_ppfree -= size;
#endif
p->numpts = numpts; p->numpts = numpts;
return p; return p;
} }
@ -139,17 +70,7 @@ static polyvertex_t *HWR_AllocVertex(void)
{ {
polyvertex_t *p; polyvertex_t *p;
size_t size = sizeof (polyvertex_t); size_t size = sizeof (polyvertex_t);
#ifdef ZPLANALLOC
p = Z_Malloc(size, PU_HWRPLANE, NULL); p = Z_Malloc(size, PU_HWRPLANE, NULL);
#else
if (gr_ppfree < size)
I_Error("HWR_AllocVertex(): no more memory %u bytes left, %u bytes needed\n\n%s\n",
gr_ppfree, size, "You can try the param -polypoolsize 2048 (or higher if needed)");
p = (polyvertex_t *)gr_ppcurrent;
gr_ppcurrent += size;
gr_ppfree -= size;
#endif
return p; return p;
} }
@ -157,16 +78,9 @@ static polyvertex_t *HWR_AllocVertex(void)
/// for now don't free because it doesn't free in reverse order /// for now don't free because it doesn't free in reverse order
static void HWR_FreePoly(poly_t *poly) static void HWR_FreePoly(poly_t *poly)
{ {
#ifdef ZPLANALLOC
Z_Free(poly); Z_Free(poly);
#else
const size_t size = sizeof (poly_t) + sizeof (polyvertex_t) * poly->numpts;
memset(poly, 0x00, size);
//mempoly -= polysize;
#endif
} }
// Return interception along bsp line, // Return interception along bsp line,
// with the polygon segment // with the polygon segment
// //
@ -577,8 +491,8 @@ static inline void SearchDivline(node_t *bsp, fdivline_t *divline)
divline->dy = FIXED_TO_FLOAT(bsp->dy); divline->dy = FIXED_TO_FLOAT(bsp->dy);
} }
#ifdef HWR_LOADING_SCREEN
//Hurdler: implement a loading status //Hurdler: implement a loading status
#ifdef HWR_LOADING_SCREEN
static size_t ls_count = 0; static size_t ls_count = 0;
static UINT8 ls_percent = 0; static UINT8 ls_percent = 0;
@ -836,8 +750,6 @@ static INT32 SolveTProblem(void)
return 0; return 0;
CONS_Debug(DBG_RENDER, "Solving T-joins. This may take a while. Please wait...\n"); CONS_Debug(DBG_RENDER, "Solving T-joins. This may take a while. Please wait...\n");
CON_Drawer(); //let the user know what we are doing
I_FinishUpdate(); // page flip or blit buffer
numsplitpoly = 0; numsplitpoly = 0;
@ -964,11 +876,9 @@ void HWR_CreatePlanePolygons(INT32 bspnum)
CONS_Debug(DBG_RENDER, "Creating polygons, please wait...\n"); CONS_Debug(DBG_RENDER, "Creating polygons, please wait...\n");
#ifdef HWR_LOADING_SCREEN #ifdef HWR_LOADING_SCREEN
ls_count = ls_percent = 0; // reset the loading status ls_count = ls_percent = 0; // reset the loading status
#endif
CON_Drawer(); //let the user know what we are doing CON_Drawer(); //let the user know what we are doing
I_FinishUpdate(); // page flip or blit buffer I_FinishUpdate(); // page flip or blit buffer
#endif
HWR_ClearPolys();
// find min/max boundaries of map // find min/max boundaries of map
//CONS_Debug(DBG_RENDER, "Looking for boundaries of map...\n"); //CONS_Debug(DBG_RENDER, "Looking for boundaries of map...\n");

View file

@ -1,18 +1,12 @@
// Emacs style mode select -*- C++ -*- // SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// // Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2019 by Sonic Team Junior.
// //
// This program is free software; you can redistribute it and/or // This program is free software distributed under the
// modify it under the terms of the GNU General Public License // terms of the GNU General Public License, version 2.
// as published by the Free Software Foundation; either version 2 // See the 'LICENSE' file for more details.
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/// \file /// \file
/// \brief load and convert graphics to the hardware format /// \brief load and convert graphics to the hardware format
@ -20,6 +14,7 @@
#include "../doomdef.h" #include "../doomdef.h"
#ifdef HWRENDER #ifdef HWRENDER
#include "hw_main.h"
#include "hw_glob.h" #include "hw_glob.h"
#include "hw_drv.h" #include "hw_drv.h"
@ -31,10 +26,6 @@
#include "../v_video.h" #include "../v_video.h"
#include "../r_draw.h" #include "../r_draw.h"
//Hurdler: 25/04/2000: used for new colormap code in hardware mode
//static UINT8 *gr_colormap = NULL; // by default it must be NULL ! (because colormap tables are not initialized)
boolean firetranslucent = false;
// Values set after a call to HWR_ResizeBlock() // Values set after a call to HWR_ResizeBlock()
static INT32 blocksize, blockwidth, blockheight; static INT32 blocksize, blockwidth, blockheight;
@ -139,17 +130,17 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
count--; count--;
texel = source[yfrac>>FRACBITS]; texel = source[yfrac>>FRACBITS];
if (firetranslucent && (transtables[(texel<<8)+0x40000]!=texel))
alpha = 0x80;
else
alpha = 0xff; alpha = 0xff;
//Hurdler: not perfect, but better than holes //Hurdler: not perfect, but better than holes
if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX && (mipmap->flags & TF_CHROMAKEYED)) if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX && (mipmap->flags & TF_CHROMAKEYED))
texel = HWR_CHROMAKEY_EQUIVALENTCOLORINDEX; alpha = 0x00;
//texel = HWR_CHROMAKEY_EQUIVALENTCOLORINDEX;
// Lat: Don't do that, some weirdos still use CYAN on their WALLTEXTURES for translucency :V
//Hurdler: 25/04/2000: now support colormap in hardware mode //Hurdler: 25/04/2000: now support colormap in hardware mode
else if (mipmap->colormap) if (mipmap->colormap)
texel = mipmap->colormap[texel]; texel = mipmap->colormap[texel];
// hope compiler will get this switch out of the loops (dreams...) // hope compiler will get this switch out of the loops (dreams...)
@ -181,16 +172,16 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
} }
// resize the patch to be 3dfx compliant // resize the patch
// set : blocksize = blockwidth * blockheight (no bpp used) // set : blocksize = blockwidth * blockheight (no bpp used)
// blockwidth // blockwidth
// blockheight // blockheight
//note : 8bit (1 byte per pixel) palettized format //note : 8bit (1 byte per pixel) palettized format
static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight, static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight,
GrTexInfo *grInfo) GLTexInfo *grInfo)
{ {
// Build the full textures from patches. // Build the full textures from patches.
static const GrLOD_t gr_lods[9] = static const GLlod_t gr_lods[9] =
{ {
GR_LOD_LOG2_256, GR_LOD_LOG2_256,
GR_LOD_LOG2_128, GR_LOD_LOG2_128,
@ -205,7 +196,7 @@ static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight,
typedef struct typedef struct
{ {
GrAspectRatio_t aspect; GLAspectRatio_t aspect;
float max_s; float max_s;
float max_t; float max_t;
} booring_aspect_t; } booring_aspect_t;
@ -226,41 +217,21 @@ static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight,
INT32 j,k; INT32 j,k;
INT32 max,min; INT32 max,min;
// find a power of 2 width/height
if (cv_grrounddown.value)
{
blockwidth = 256;
while (originalwidth < blockwidth)
blockwidth >>= 1;
if (blockwidth < 1)
I_Error("3D GenerateTexture : too small");
blockheight = 256;
while (originalheight < blockheight)
blockheight >>= 1;
if (blockheight < 1)
I_Error("3D GenerateTexture : too small");
}
else
{
// size up to nearest power of 2 // size up to nearest power of 2
blockwidth = 1; blockwidth = 1;
while (blockwidth < originalwidth) while (blockwidth < originalwidth)
blockwidth <<= 1; blockwidth <<= 1;
// scale down the original graphics to fit in 256 // scale down the original graphics to fit in 2048
if (blockwidth > 2048) if (blockwidth > 2048)
blockwidth = 2048; blockwidth = 2048;
//I_Error("3D GenerateTexture : too big");
// size up to nearest power of 2 // size up to nearest power of 2
blockheight = 1; blockheight = 1;
while (blockheight < originalheight) while (blockheight < originalheight)
blockheight <<= 1; blockheight <<= 1;
// scale down the original graphics to fit in 256 // scale down the original graphics to fit in 2048
if (blockheight > 2048) if (blockheight > 2048)
blockheight = 2048; blockheight = 2048;
//I_Error("3D GenerateTexture : too big");
}
// do the boring LOD stuff.. blech! // do the boring LOD stuff.. blech!
if (blockwidth >= blockheight) if (blockwidth >= blockheight)
@ -324,7 +295,7 @@ static UINT8 *MakeBlock(GLMipmap_t *grMipmap)
{ {
UINT8 *block; UINT8 *block;
INT32 bpp, i; INT32 bpp, i;
UINT16 bu16 = ((0x00 <<8) | HWR_CHROMAKEY_EQUIVALENTCOLORINDEX); UINT16 bu16 = ((0x00 <<8) | HWR_PATCHES_CHROMAKEY_COLORINDEX);
bpp = format2bpp[grMipmap->grInfo.format]; bpp = format2bpp[grMipmap->grInfo.format];
block = Z_Malloc(blocksize*bpp, PU_HWRCACHE, &(grMipmap->grInfo.data)); block = Z_Malloc(blocksize*bpp, PU_HWRCACHE, &(grMipmap->grInfo.data));
@ -335,8 +306,8 @@ static UINT8 *MakeBlock(GLMipmap_t *grMipmap)
case 2: case 2:
// fill background with chromakey, alpha = 0 // fill background with chromakey, alpha = 0
for (i = 0; i < blocksize; i++) for (i = 0; i < blocksize; i++)
//[segabor]
memcpy(block+i*sizeof(UINT16), &bu16, sizeof(UINT16)); memcpy(block+i*sizeof(UINT16), &bu16, sizeof(UINT16));
break; break;
case 4: memset(block, 0x00, blocksize*sizeof(UINT32)); break; case 4: memset(block, 0x00, blocksize*sizeof(UINT32)); break;
} }
@ -379,6 +350,13 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex)
grtex->mipmap.height = (UINT16)blockheight; grtex->mipmap.height = (UINT16)blockheight;
grtex->mipmap.grInfo.format = textureformat; grtex->mipmap.grInfo.format = textureformat;
grtex->mipmap.colormap = colormaps;
#ifdef GLENCORE
if (encoremap)
grtex->mipmap.colormap += (256*32);
#endif
block = MakeBlock(&grtex->mipmap); block = MakeBlock(&grtex->mipmap);
if (skyspecial) //Hurdler: not efficient, but better than holes in the sky (and it's done only at level loading) if (skyspecial) //Hurdler: not efficient, but better than holes in the sky (and it's done only at level loading)
@ -430,7 +408,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex)
} }
// patch may be NULL if grMipmap has been initialised already and makebitmap is false // patch may be NULL if grMipmap has been initialised already and makebitmap is false
void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap) void HWR_MakePatch (patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap)
{ {
INT32 newwidth, newheight; INT32 newwidth, newheight;
@ -445,7 +423,7 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm
grPatch->leftoffset = SHORT(patch->leftoffset); grPatch->leftoffset = SHORT(patch->leftoffset);
grPatch->topoffset = SHORT(patch->topoffset); grPatch->topoffset = SHORT(patch->topoffset);
// find the good 3dfx size (boring spec) // resize patch
HWR_ResizeBlock(SHORT(patch->width), SHORT(patch->height), &grMipmap->grInfo); HWR_ResizeBlock(SHORT(patch->width), SHORT(patch->height), &grMipmap->grInfo);
grMipmap->width = (UINT16)blockwidth; grMipmap->width = (UINT16)blockwidth;
grMipmap->height = (UINT16)blockheight; grMipmap->height = (UINT16)blockheight;
@ -465,23 +443,12 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm
Z_Free(grMipmap->grInfo.data); Z_Free(grMipmap->grInfo.data);
grMipmap->grInfo.data = NULL; grMipmap->grInfo.data = NULL;
// if rounddown, rounddown patches as well as textures
if (cv_grrounddown.value)
{
newwidth = blockwidth;
newheight = blockheight;
}
else
{
// no rounddown, do not size up patches, so they don't look 'scaled'
newwidth = min(grPatch->width, blockwidth); newwidth = min(grPatch->width, blockwidth);
newheight = min(grPatch->height, blockheight); newheight = min(grPatch->height, blockheight);
}
if (makebitmap) if (makebitmap)
{ {
MakeBlock(grMipmap); MakeBlock(grMipmap);
HWR_DrawPatchInCache(grMipmap, HWR_DrawPatchInCache(grMipmap,
newwidth, newheight, newwidth, newheight,
blockwidth*format2bpp[grMipmap->grInfo.format], blockwidth*format2bpp[grMipmap->grInfo.format],
@ -495,7 +462,6 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm
grPatch->max_t = (float)newheight / (float)blockheight; grPatch->max_t = (float)newheight / (float)blockheight;
} }
// ================================================= // =================================================
// CACHING HANDLING // CACHING HANDLING
// ================================================= // =================================================
@ -515,10 +481,10 @@ static void FreeMipmapColormap(INT32 patchnum, void *patch)
{ {
GLPatch_t* const grpatch = patch; GLPatch_t* const grpatch = patch;
(void)patchnum; //unused (void)patchnum; //unused
while (grpatch->mipmap.nextcolormap) while (grpatch->mipmap->nextcolormap)
{ {
GLMipmap_t *grmip = grpatch->mipmap.nextcolormap; GLMipmap_t *grmip = grpatch->mipmap->nextcolormap;
grpatch->mipmap.nextcolormap = grmip->nextcolormap; grpatch->mipmap->nextcolormap = grmip->nextcolormap;
if (grmip->grInfo.data) Z_Free(grmip->grInfo.data); if (grmip->grInfo.data) Z_Free(grmip->grInfo.data);
free(grmip); free(grmip);
} }
@ -562,7 +528,7 @@ void HWR_PrepLevelCache(size_t pnumtextures)
gr_numtextures = pnumtextures; gr_numtextures = pnumtextures;
gr_textures = calloc(pnumtextures, sizeof (*gr_textures)); gr_textures = calloc(pnumtextures, sizeof (*gr_textures));
if (gr_textures == NULL) if (gr_textures == NULL)
I_Error("3D can't alloc gr_textures"); I_Error("HWR_PrepLevelCache: can't alloc gr_textures");
} }
void HWR_SetPalette(RGBA_t *palette) void HWR_SetPalette(RGBA_t *palette)
@ -611,8 +577,13 @@ GLTexture_t *HWR_GetTexture(INT32 tex)
static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
{ {
#ifdef GLENCORE
UINT8 *flat;
size_t steppy;
#endif
size_t size, pflatsize; size_t size, pflatsize;
// setup the texture info // setup the texture info
grMipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_64; grMipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_64;
grMipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_64; grMipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_64;
@ -652,15 +623,37 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum)
// the flat raw data needn't be converted with palettized textures // the flat raw data needn't be converted with palettized textures
W_ReadLump(flatlumpnum, Z_Malloc(W_LumpLength(flatlumpnum), W_ReadLump(flatlumpnum, Z_Malloc(W_LumpLength(flatlumpnum),
PU_HWRCACHE, &grMipmap->grInfo.data)); PU_HWRCACHE, &grMipmap->grInfo.data));
#ifdef GLENCORE
flat = grMipmap->grInfo.data;
for (steppy = 0; steppy < size; steppy++)
if (flat[steppy] != HWR_PATCHES_CHROMAKEY_COLORINDEX)
flat[steppy] = grMipmap->colormap[flat[steppy]];
#endif
} }
// Download a Doom 'flat' to the hardware cache and make it ready for use // Download a Doom 'flat' to the hardware cache and make it ready for use
void HWR_GetFlat(lumpnum_t flatlumpnum) void HWR_GetFlat(lumpnum_t flatlumpnum, boolean noencoremap)
{ {
GLMipmap_t *grmip; GLMipmap_t *grmip;
grmip = &HWR_GetCachedGLPatch(flatlumpnum)->mipmap; grmip = HWR_GetCachedGLPatch(flatlumpnum)->mipmap;
grmip->colormap = colormaps;
#ifdef GLENCORE
if (!noencoremap && encoremap)
grmip->colormap += (256*32);
#endif
grmip->colormap = colormaps;
#ifdef GLENCORE
if (!noencoremap && encoremap)
grmip->colormap += (256*32);
#endif
if (!grmip->downloaded && !grmip->grInfo.data) if (!grmip->downloaded && !grmip->grInfo.data)
HWR_CacheFlat(grmip, flatlumpnum); HWR_CacheFlat(grmip, flatlumpnum);
@ -697,22 +690,22 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch)
void HWR_GetPatch(GLPatch_t *gpatch) void HWR_GetPatch(GLPatch_t *gpatch)
{ {
// is it in hardware cache // is it in hardware cache
if (!gpatch->mipmap.downloaded && !gpatch->mipmap.grInfo.data) if (!gpatch->mipmap->downloaded && !gpatch->mipmap->grInfo.data)
{ {
// load the software patch, PU_STATIC or the Z_Malloc for hardware patch will // load the software patch, PU_STATIC or the Z_Malloc for hardware patch will
// flush the software patch before the conversion! oh yeah I suffered // flush the software patch before the conversion! oh yeah I suffered
patch_t *ptr = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); patch_t *patch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
HWR_MakePatch(ptr, gpatch, &gpatch->mipmap, true); HWR_MakePatch(patch, gpatch, gpatch->mipmap, true);
// this is inefficient.. but the hardware patch in heap is purgeable so it should // this is inefficient.. but the hardware patch in heap is purgeable so it should
// not fragment memory, and besides the REAL cache here is the hardware memory // not fragment memory, and besides the REAL cache here is the hardware memory
Z_Free(ptr); Z_Free(patch);
} }
HWD.pfnSetTexture(&gpatch->mipmap); HWD.pfnSetTexture(gpatch->mipmap);
// The system-memory patch data can be purged now. // The system-memory patch data can be purged now.
Z_ChangeTag(gpatch->mipmap.grInfo.data, PU_HWRCACHE_UNLOCKED); Z_ChangeTag(gpatch->mipmap->grInfo.data, PU_HWRCACHE_UNLOCKED);
} }
@ -732,7 +725,7 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap)
// search for the mimmap // search for the mimmap
// skip the first (no colormap translated) // skip the first (no colormap translated)
for (grmip = &gpatch->mipmap; grmip->nextcolormap; ) for (grmip = gpatch->mipmap; grmip->nextcolormap; )
{ {
grmip = grmip->nextcolormap; grmip = grmip->nextcolormap;
if (grmip->colormap == colormap) if (grmip->colormap == colormap)
@ -762,164 +755,10 @@ void HWR_UnlockCachedPatch(GLPatch_t *gpatch)
if (!gpatch) if (!gpatch)
return; return;
Z_ChangeTag(gpatch->mipmap.grInfo.data, PU_HWRCACHE_UNLOCKED); Z_ChangeTag(gpatch->mipmap->grInfo.data, PU_HWRCACHE_UNLOCKED);
Z_ChangeTag(gpatch, PU_HWRPATCHINFO_UNLOCKED); Z_ChangeTag(gpatch, PU_HWRPATCHINFO_UNLOCKED);
} }
static const INT32 picmode2GR[] =
{
GR_TEXFMT_P_8, // PALETTE
0, // INTENSITY (unsupported yet)
GR_TEXFMT_ALPHA_INTENSITY_88, // INTENSITY_ALPHA (corona use this)
0, // RGB24 (unsupported yet)
GR_RGBA, // RGBA32 (opengl only)
};
static void HWR_DrawPicInCache(UINT8 *block, INT32 pblockwidth, INT32 pblockheight,
INT32 blockmodulo, pic_t *pic, INT32 bpp)
{
INT32 i,j;
fixed_t posx, posy, stepx, stepy;
UINT8 *dest, *src, texel;
UINT16 texelu16;
INT32 picbpp;
RGBA_t col;
stepy = ((INT32)SHORT(pic->height)<<FRACBITS)/pblockheight;
stepx = ((INT32)SHORT(pic->width)<<FRACBITS)/pblockwidth;
picbpp = format2bpp[picmode2GR[pic->mode]];
posy = 0;
for (j = 0; j < pblockheight; j++)
{
posx = 0;
dest = &block[j*blockmodulo];
src = &pic->data[(posy>>FRACBITS)*SHORT(pic->width)*picbpp];
for (i = 0; i < pblockwidth;i++)
{
switch (pic->mode)
{ // source bpp
case PALETTE :
texel = src[(posx+FRACUNIT/2)>>FRACBITS];
switch (bpp)
{ // destination bpp
case 1 :
*dest++ = texel; break;
case 2 :
texelu16 = (UINT16)(texel | 0xff00);
memcpy(dest, &texelu16, sizeof(UINT16));
dest += sizeof(UINT16);
break;
case 3 :
col = V_GetColor(texel);
memcpy(dest, &col, sizeof(RGBA_t)-sizeof(UINT8));
dest += sizeof(RGBA_t)-sizeof(UINT8);
break;
case 4 :
memcpy(dest, &V_GetColor(texel), sizeof(RGBA_t));
dest += sizeof(RGBA_t);
break;
}
break;
case INTENSITY :
*dest++ = src[(posx+FRACUNIT/2)>>FRACBITS];
break;
case INTENSITY_ALPHA : // assume dest bpp = 2
memcpy(dest, src + ((posx+FRACUNIT/2)>>FRACBITS)*sizeof(UINT16), sizeof(UINT16));
dest += sizeof(UINT16);
break;
case RGB24 :
break; // not supported yet
case RGBA32 : // assume dest bpp = 4
dest += sizeof(UINT32);
memcpy(dest, src + ((posx+FRACUNIT/2)>>FRACBITS)*sizeof(UINT32), sizeof(UINT32));
break;
}
posx += stepx;
}
posy += stepy;
}
}
// -----------------+
// HWR_GetPic : Download a Doom pic (raw row encoded with no 'holes')
// Returns :
// -----------------+
GLPatch_t *HWR_GetPic(lumpnum_t lumpnum)
{
GLPatch_t *grpatch;
grpatch = HWR_GetCachedGLPatch(lumpnum);
if (!grpatch->mipmap.downloaded && !grpatch->mipmap.grInfo.data)
{
pic_t *pic;
UINT8 *block;
size_t len;
INT32 newwidth, newheight;
pic = W_CacheLumpNum(lumpnum, PU_CACHE);
grpatch->width = SHORT(pic->width);
grpatch->height = SHORT(pic->height);
len = W_LumpLength(lumpnum) - sizeof (pic_t);
grpatch->leftoffset = 0;
grpatch->topoffset = 0;
// find the good 3dfx size (boring spec)
HWR_ResizeBlock (grpatch->width, grpatch->height, &grpatch->mipmap.grInfo);
grpatch->mipmap.width = (UINT16)blockwidth;
grpatch->mipmap.height = (UINT16)blockheight;
if (pic->mode == PALETTE)
grpatch->mipmap.grInfo.format = textureformat; // can be set by driver
else
grpatch->mipmap.grInfo.format = picmode2GR[pic->mode];
Z_Free(grpatch->mipmap.grInfo.data);
// allocate block
block = MakeBlock(&grpatch->mipmap);
// if rounddown, rounddown patches as well as textures
if (cv_grrounddown.value)
{
newwidth = blockwidth;
newheight = blockheight;
}
else
{
// no rounddown, do not size up patches, so they don't look 'scaled'
newwidth = min(SHORT(pic->width),blockwidth);
newheight = min(SHORT(pic->height),blockheight);
}
if (grpatch->width == blockwidth &&
grpatch->height == blockheight &&
format2bpp[grpatch->mipmap.grInfo.format] == format2bpp[picmode2GR[pic->mode]])
{
// no conversion needed
M_Memcpy(grpatch->mipmap.grInfo.data, pic->data,len);
}
else
HWR_DrawPicInCache(block, newwidth, newheight,
blockwidth*format2bpp[grpatch->mipmap.grInfo.format],
pic,
format2bpp[grpatch->mipmap.grInfo.format]);
Z_Unlock(pic);
Z_ChangeTag(block, PU_HWRCACHE_UNLOCKED);
grpatch->mipmap.flags = 0;
grpatch->max_s = (float)newwidth / (float)blockwidth;
grpatch->max_t = (float)newheight / (float)blockheight;
}
HWD.pfnSetTexture(&grpatch->mipmap);
//CONS_Debug(DBG_RENDER, "picloaded at %x as texture %d\n",grpatch->mipmap.grInfo.data, grpatch->mipmap.downloaded);
return grpatch;
}
GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wadnum, UINT16 lumpnum) GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wadnum, UINT16 lumpnum)
{ {
aatree_t *hwrcache = wadfiles[wadnum]->hwrcache; aatree_t *hwrcache = wadfiles[wadnum]->hwrcache;
@ -930,6 +769,7 @@ GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wadnum, UINT16 lumpnum)
grpatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, NULL); grpatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, NULL);
grpatch->wadnum = wadnum; grpatch->wadnum = wadnum;
grpatch->lumpnum = lumpnum; grpatch->lumpnum = lumpnum;
grpatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, NULL);
M_AATreeSet(hwrcache, lumpnum, grpatch); M_AATreeSet(hwrcache, lumpnum, grpatch);
} }
@ -1033,7 +873,7 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum)
{ {
GLMipmap_t *grmip; GLMipmap_t *grmip;
grmip = &HWR_GetCachedGLPatch(fademasklumpnum)->mipmap; grmip = HWR_GetCachedGLPatch(fademasklumpnum)->mipmap;
if (!grmip->downloaded && !grmip->grInfo.data) if (!grmip->downloaded && !grmip->grInfo.data)
HWR_CacheFadeMask(grmip, fademasklumpnum); HWR_CacheFadeMask(grmip, fademasklumpnum);

View file

@ -70,16 +70,17 @@
#include <math.h> #include <math.h>
#include "../v_video.h" #include "../v_video.h"
#include "hw_main.h"
#include "hw_clip.h" #include "hw_clip.h"
#include "hw_glob.h" #include "hw_glob.h"
#include "../r_main.h"
#include "../r_state.h" #include "../r_state.h"
#include "../tables.h" #include "../tables.h"
#include "r_opengl/r_opengl.h" #include "r_opengl/r_opengl.h"
#include "../r_main.h" // for cv_fov
#ifdef HAVE_SPHEREFRUSTRUM #ifdef HAVE_SPHEREFRUSTRUM
static GLfloat viewMatrix[16]; static GLdouble viewMatrix[16];
static GLfloat projMatrix[16]; static GLdouble projMatrix[16];
float frustum[6][4]; float frustum[6][4];
#endif #endif
@ -320,12 +321,12 @@ void gld_clipper_Clear(void)
#define RMUL (1.6f/1.333333f) #define RMUL (1.6f/1.333333f)
angle_t gld_FrustumAngle(void) angle_t gld_FrustumAngle(angle_t tiltangle)
{ {
double floatangle; double floatangle;
angle_t a1; angle_t a1;
float tilt = (float)fabs(((double)(int)aimingangle) / ANG1); float tilt = (float)fabs(((double)(int)tiltangle) / ANG1);
// NEWCLIP TODO: SRB2CBTODO: make a global render_fov for this function // NEWCLIP TODO: SRB2CBTODO: make a global render_fov for this function
@ -334,12 +335,10 @@ angle_t gld_FrustumAngle(void)
float render_multiplier = 64.0f / render_fovratio / RMUL; float render_multiplier = 64.0f / render_fovratio / RMUL;
if (tilt > 90.0f) if (tilt > 90.0f)
{
tilt = 90.0f; tilt = 90.0f;
}
// If the pitch is larger than this you can look all around at a FOV of 90 // If the pitch is larger than this you can look all around at a FOV of 90
if (abs((signed)aimingangle) > 46 * ANG1) if (abs((signed)tiltangle) > 46 * ANG1)
return 0xffffffff; return 0xffffffff;
// ok, this is a gross hack that barely works... // ok, this is a gross hack that barely works...
@ -352,7 +351,7 @@ angle_t gld_FrustumAngle(void)
} }
// SRB2CB I don't think used any of this stuff, let's disable for now since SRB2 probably doesn't want it either // SRB2CB I don't think used any of this stuff, let's disable for now since SRB2 probably doesn't want it either
// compiler complains about (p)glGetDoublev anyway, in case anyone wants this // compiler complains about (p)glGetFloatv anyway, in case anyone wants this
// only r_opengl.c can use the base gl funcs as it turns out, that's a problem for whoever wants sphere frustum checks // only r_opengl.c can use the base gl funcs as it turns out, that's a problem for whoever wants sphere frustum checks
// btw to renable define HAVE_SPHEREFRUSTRUM in hw_clip.h // btw to renable define HAVE_SPHEREFRUSTRUM in hw_clip.h
#ifdef HAVE_SPHEREFRUSTRUM #ifdef HAVE_SPHEREFRUSTRUM
@ -381,7 +380,7 @@ void gld_FrustrumSetup(void)
float t; float t;
float clip[16]; float clip[16];
pglGeFloatv(GL_PROJECTION_MATRIX, projMatrix); pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix);
pglGetFloatv(GL_MODELVIEW_MATRIX, viewMatrix); pglGetFloatv(GL_MODELVIEW_MATRIX, viewMatrix);
clip[0] = CALCMATRIX(0, 0, 1, 4, 2, 8, 3, 12); clip[0] = CALCMATRIX(0, 0, 1, 4, 2, 8, 3, 12);

View file

@ -17,7 +17,7 @@
boolean gld_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle); boolean gld_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle);
void gld_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle); void gld_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle);
void gld_clipper_Clear(void); void gld_clipper_Clear(void);
angle_t gld_FrustumAngle(void); angle_t gld_FrustumAngle(angle_t tiltangle);
#ifdef HAVE_SPHEREFRUSTRUM #ifdef HAVE_SPHEREFRUSTRUM
void gld_FrustrumSetup(void); void gld_FrustrumSetup(void);
boolean gld_SphereInFrustum(float x, float y, float z, float radius); boolean gld_SphereInFrustum(float x, float y, float z, float radius);

View file

@ -1,60 +1,86 @@
// Emacs style mode select -*- C++ -*- // SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// // Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2019 by Sonic Team Junior.
// //
// This program is free software; you can redistribute it and/or // This program is free software distributed under the
// modify it under the terms of the GNU General Public License // terms of the GNU General Public License, version 2.
// as published by the Free Software Foundation; either version 2 // See the 'LICENSE' file for more details.
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/// \file /// \file
/// \brief defines structures and exports for the standard 3D driver DLL used by Doom Legacy /// \brief defines structures and exports for the standard GPU driver
#ifndef _HWR_DATA_ #ifndef _HWR_DATA_
#define _HWR_DATA_ #define _HWR_DATA_
#if defined (_WIN32) && !defined (__CYGWIN__) && !defined (_XBOX)
//#define WIN32_LEAN_AND_MEAN
#define RPC_NO_WINDOWS_H
#include <windows.h>
#endif
#include "../doomdef.h" #include "../doomdef.h"
//THIS MUST DISAPPEAR!!!
#include "hw_glide.h"
#include "../screen.h" #include "../screen.h"
// ========================================================================== // ==========================================================================
// TEXTURE INFO // TEXTURE INFO
// ========================================================================== // ==========================================================================
//
// hw_glide.h
//
typedef long GLAspectRatio_t;
#define GR_ASPECT_LOG2_8x1 3 /* 8W x 1H */
#define GR_ASPECT_LOG2_4x1 2 /* 4W x 1H */
#define GR_ASPECT_LOG2_2x1 1 /* 2W x 1H */
#define GR_ASPECT_LOG2_1x1 0 /* 1W x 1H */
#define GR_ASPECT_LOG2_1x2 -1 /* 1W x 2H */
#define GR_ASPECT_LOG2_1x4 -2 /* 1W x 4H */
#define GR_ASPECT_LOG2_1x8 -3 /* 1W x 8H */
typedef long GLlod_t;
#define GR_LOD_LOG2_256 0x8
#define GR_LOD_LOG2_128 0x7
#define GR_LOD_LOG2_64 0x6
#define GR_LOD_LOG2_32 0x5
#define GR_LOD_LOG2_16 0x4
#define GR_LOD_LOG2_8 0x3
#define GR_LOD_LOG2_4 0x2
#define GR_LOD_LOG2_2 0x1
#define GR_LOD_LOG2_1 0x0
typedef long GLTextureFormat_t;
#define GR_TEXFMT_ALPHA_8 0x2 /* (0..0xFF) alpha */
#define GR_TEXFMT_INTENSITY_8 0x3 /* (0..0xFF) intensity */
#define GR_TEXFMT_ALPHA_INTENSITY_44 0x4
#define GR_TEXFMT_P_8 0x5 /* 8-bit palette */
#define GR_TEXFMT_RGB_565 0xa
#define GR_TEXFMT_ARGB_1555 0xb
#define GR_TEXFMT_ARGB_4444 0xc
#define GR_TEXFMT_ALPHA_INTENSITY_88 0xd
#define GR_TEXFMT_AP_88 0xe /* 8-bit alpha 8-bit palette */
#define GR_RGBA 0x6 // 32 bit RGBA !
typedef struct
{
GLlod_t smallLodLog2;
GLlod_t largeLodLog2;
GLAspectRatio_t aspectRatioLog2;
GLTextureFormat_t format;
void *data;
} GLTexInfo;
// grInfo.data holds the address of the graphics data cached in heap memory // grInfo.data holds the address of the graphics data cached in heap memory
// NULL if the texture is not in Doom heap cache. // NULL if the texture is not in Doom heap cache.
struct GLMipmap_s struct GLMipmap_s
{ {
GrTexInfo grInfo; //for TexDownloadMipMap GLTexInfo grInfo;
FxU32 flags; unsigned long flags;
UINT16 height; UINT16 width, height;
UINT16 width; UINT32 downloaded; // tex_downloaded
UINT32 downloaded; // the dll driver have it in there cache ?
struct GLMipmap_s *nextmipmap;
struct GLMipmap_s *nextcolormap; struct GLMipmap_s *nextcolormap;
const UINT8 *colormap; const UINT8 *colormap;
// opengl
struct GLMipmap_s *nextmipmap; // opengl : liste of all texture in opengl driver
}; };
typedef struct GLMipmap_s GLMipmap_t; typedef struct GLMipmap_s GLMipmap_t;
// //
// Doom texture info, as cached for hardware rendering // Doom texture info, as cached for hardware rendering
// //
@ -66,12 +92,10 @@ struct GLTexture_s
}; };
typedef struct GLTexture_s GLTexture_t; typedef struct GLTexture_s GLTexture_t;
// a cached patch as converted to hardware format, holding the original patch_t // a cached patch as converted to hardware format, holding the original patch_t
// header so that the existing code can retrieve ->width, ->height as usual // header so that the existing code can retrieve ->width, ->height as usual
// This is returned by W_CachePatchNum()/W_CachePatchName(), when rendermode // This is returned by W_CachePatchNum()/W_CachePatchName(), when rendermode
// is 'render_opengl'. Else it returns the normal patch_t data. // is 'render_opengl'. Else it returns the normal patch_t data.
struct GLPatch_s struct GLPatch_s
{ {
// the 4 first fields come right away from the original patch_t // the 4 first fields come right away from the original patch_t
@ -83,8 +107,10 @@ struct GLPatch_s
float max_s,max_t; float max_s,max_t;
UINT16 wadnum; // the software patch lump num for when the hardware patch UINT16 wadnum; // the software patch lump num for when the hardware patch
UINT16 lumpnum; // was flushed, and we need to re-create it UINT16 lumpnum; // was flushed, and we need to re-create it
GLMipmap_t mipmap; GLMipmap_t *mipmap;
};
boolean notfound; // if the texture file was not found, mark it here (used in model texture loading)
} ATTRPACK;
typedef struct GLPatch_s GLPatch_t; typedef struct GLPatch_s GLPatch_t;
#endif //_HWR_DATA_ #endif //_HWR_DATA_

View file

@ -19,6 +19,7 @@
#ifndef _HWR_DEFS_ #ifndef _HWR_DEFS_
#define _HWR_DEFS_ #define _HWR_DEFS_
#include "../doomtype.h" #include "../doomtype.h"
#include "../r_defs.h"
#define ZCLIP_PLANE 4.0f // Used for the actual game drawing #define ZCLIP_PLANE 4.0f // Used for the actual game drawing
#define NZCLIP_PLANE 0.9f // Seems to be only used for the HUD and screen textures #define NZCLIP_PLANE 0.9f // Seems to be only used for the HUD and screen textures
@ -41,17 +42,8 @@ typedef unsigned char FBOOLEAN;
// ========================================================================== // ==========================================================================
// byte value for paletted graphics, which represent the transparent color // byte value for paletted graphics, which represent the transparent color
#ifdef _NDS
// NDS is hardwired to use zero as transparent color
#define HWR_PATCHES_CHROMAKEY_COLORINDEX 0
#define HWR_CHROMAKEY_EQUIVALENTCOLORINDEX 1
#else
#define HWR_PATCHES_CHROMAKEY_COLORINDEX 247 #define HWR_PATCHES_CHROMAKEY_COLORINDEX 247
#define HWR_CHROMAKEY_EQUIVALENTCOLORINDEX 220 #define HWR_CHROMAKEY_EQUIVALENTCOLORINDEX 220
#endif
// the chroma key color shows on border sprites, set it to black
#define HWR_PATCHES_CHROMAKEY_COLORVALUE (0x00000000) //RGBA format as in grSstWinOpen()
// RGBA Color components with float type ranging [ 0 ... 1 ] // RGBA Color components with float type ranging [ 0 ... 1 ]
struct FRGBAFloat struct FRGBAFloat
@ -73,8 +65,6 @@ struct FColorARGB
typedef struct FColorARGB ARGB_t; typedef struct FColorARGB ARGB_t;
typedef struct FColorARGB FColorARGB; typedef struct FColorARGB FColorARGB;
// ========================================================================== // ==========================================================================
// VECTORS // VECTORS
// ========================================================================== // ==========================================================================
@ -85,22 +75,65 @@ typedef struct
FLOAT x,y; FLOAT x,y;
} F2DCoord, v2d_t; } F2DCoord, v2d_t;
// Simple 3D vector // ======================
typedef struct FVector // wallVert3D
{ // ----------------------
FLOAT x,y,z; // :crab: IS GONE! :crab:
} FVector; // ======================
// 3D model vector (coords + texture coords) // -----------
// structures
// -----------
// a vertex of a Doom 'plane' polygon
typedef struct typedef struct
{ {
//FVector Point; float x;
FLOAT x,y,z; float y;
FLOAT s,t,w; // texture coordinates float z;
} v3d_t, wallVert3D; } polyvertex_t;
//Hurdler: Transform (coords + angles) #ifdef _MSC_VER
//BP: transform order : scale(rotation_x(rotation_y(translation(v)))) #pragma warning(disable : 4200)
#endif
// a convex 'plane' polygon, clockwise order
typedef struct
{
INT32 numpts;
polyvertex_t pts[0];
} poly_t;
#ifdef _MSC_VER
#pragma warning(default : 4200)
#endif
// holds extra info for 3D render, for each subsector in subsectors[]
typedef struct
{
poly_t *planepoly; // the generated convex polygon
} extrasubsector_t;
// needed for sprite rendering
// equivalent of the software renderer's vissprites
typedef struct gr_vissprite_s
{
// Doubly linked list
struct gr_vissprite_s *prev;
struct gr_vissprite_s *next;
float x1, x2;
float z1, z2;
float tz, ty;
lumpnum_t patchlumpnum;
boolean flip;
UINT8 translucency; //alpha level 0-255
mobj_t *mobj;
boolean precip; // Tails 08-25-2002
boolean vflip;
//Hurdler: 25/04/2000: now support colormap in hardware mode
UINT8 *colormap;
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
} gr_vissprite_t;
// Kart features // Kart features
#define USE_FTRANSFORM_ANGLEZ #define USE_FTRANSFORM_ANGLEZ
@ -124,18 +157,17 @@ typedef struct
#ifdef USE_FTRANSFORM_MIRROR #ifdef USE_FTRANSFORM_MIRROR
boolean mirror; // SRB2Kart: Encore Mode boolean mirror; // SRB2Kart: Encore Mode
#endif #endif
boolean shearing; // 14042019
angle_t viewaiming; // 17052019
} FTransform; } FTransform;
// Transformed vector, as passed to HWR API // Transformed vector, as passed to HWR API
typedef struct typedef struct
{ {
FLOAT x,y,z; FLOAT x,y,z;
FUINT argb; // flat-shaded color FLOAT s,t;
FLOAT sow; // s texture ordinate (s over w)
FLOAT tow; // t texture ordinate (t over w)
} FOutVector; } FOutVector;
// ========================================================================== // ==========================================================================
// RENDER MODES // RENDER MODES
// ========================================================================== // ==========================================================================
@ -164,21 +196,15 @@ enum EPolyFlags
PF_Decal = 0x00000800, // Enable polygon offset PF_Decal = 0x00000800, // Enable polygon offset
PF_Modulated = 0x00001000, // Modulation (multiply output with constant ARGB) PF_Modulated = 0x00001000, // Modulation (multiply output with constant ARGB)
// When set, pass the color constant into the FSurfaceInfo -> FlatColor // When set, pass the color constant into the FSurfaceInfo -> FlatColor
PF_NoTexture = 0x00002000, // Use the small white texture PF_NoTexture = 0x00002000, // Disable texture
PF_Corona = 0x00004000, // Tell the rendrer we are drawing a corona PF_Ripple = 0x00004000, // Water shader effect
PF_Unused = 0x00008000, // Unused // 0x00008000
PF_RemoveYWrap = 0x00010000, // Force clamp texture on Y PF_RemoveYWrap = 0x00010000, // Force clamp texture on Y
PF_ForceWrapX = 0x00020000, // Force repeat texture on X PF_ForceWrapX = 0x00020000, // Force repeat texture on X
PF_ForceWrapY = 0x00040000, // Force repeat texture on Y PF_ForceWrapY = 0x00040000, // Force repeat texture on Y
PF_Clip = 0x40000000, // clip to frustum and nearz plane (glide only, automatic in opengl) // 0x20000000
PF_NoZClip = 0x20000000, // in conjonction with PF_Clip // 0x40000000
PF_Debug = 0x80000000 // print debug message in driver :) // 0x80000000
};
enum ESurfFlags
{
SF_DYNLIGHT = 0x00000001,
}; };
@ -191,46 +217,42 @@ enum ETextureFlags
TF_TRANSPARENT = 0x00000040, // texture with some alpha == 0 TF_TRANSPARENT = 0x00000040, // texture with some alpha == 0
}; };
#ifdef TODO
struct FTextureInfo
{
FUINT Width; // Pixels
FUINT Height; // Pixels
FUBYTE *TextureData; // Image data
FUINT Format; // FORMAT_RGB, ALPHA ...
FBITFIELD Flags; // Flags to tell driver about texture (see ETextureFlags)
void DriverExtra; // (OpenGL texture object nr, ...)
// chromakey enabled,...
struct FTextureInfo *Next; // Manage list of downloaded textures.
};
#else
typedef struct GLMipmap_s FTextureInfo; typedef struct GLMipmap_s FTextureInfo;
#endif
// jimita 14032019
struct FLightInfo
{
FUINT light_level;
FUINT fade_start;
FUINT fade_end;
};
typedef struct FLightInfo FLightInfo;
// Description of a renderable surface // Description of a renderable surface
struct FSurfaceInfo struct FSurfaceInfo
{ {
FUINT PolyFlags; // Surface flags -- UNUSED YET -- FUINT PolyFlags;
RGBA_t FlatColor; // Flat-shaded color used with PF_Modulated mode RGBA_t PolyColor;
RGBA_t TintColor;
RGBA_t FadeColor;
FLightInfo LightInfo; // jimita 14032019
}; };
typedef struct FSurfaceInfo FSurfaceInfo; typedef struct FSurfaceInfo FSurfaceInfo;
//Hurdler: added for backward compatibility
enum hwdsetspecialstate enum hwdsetspecialstate
{ {
HWD_SET_FOG_TABLE = 1, HWD_SET_SHADERS,
HWD_SET_FOG_MODE,
HWD_SET_FOG_COLOR,
HWD_SET_FOG_DENSITY,
HWD_SET_FOV,
HWD_SET_TEXTUREFILTERMODE, HWD_SET_TEXTUREFILTERMODE,
HWD_SET_TEXTUREANISOTROPICMODE, HWD_SET_TEXTUREANISOTROPICMODE,
HWD_NUMSTATE HWD_NUMSTATE
}; };
typedef enum hwdsetspecialstate hwdspecialstate_t; typedef enum hwdsetspecialstate hwdspecialstate_t;
#define GL_DEFAULTMIX 0x00000000
#define GL_DEFAULTFOG 0xFF000000
enum hwdfiltermode enum hwdfiltermode
{ {
HWD_SET_TEXTUREFILTER_POINTSAMPLED, HWD_SET_TEXTUREFILTER_POINTSAMPLED,
@ -241,5 +263,4 @@ enum hwdfiltermode
HWD_SET_TEXTUREFILTER_MIXED3, HWD_SET_TEXTUREFILTER_MIXED3,
}; };
#endif //_HWR_DEFS_ #endif //_HWR_DEFS_

View file

@ -54,8 +54,6 @@
#endif #endif
#endif #endif
typedef void (*I_Error_t) (const char *error, ...) FUNCIERROR;
// ========================================================================== // ==========================================================================
// MATHS // MATHS
// ========================================================================== // ==========================================================================
@ -63,7 +61,8 @@ typedef void (*I_Error_t) (const char *error, ...) FUNCIERROR;
// Constants // Constants
#define DEGREE (0.017453292519943295769236907684883l) // 2*PI/360 #define DEGREE (0.017453292519943295769236907684883l) // 2*PI/360
void DBG_Printf(const char *lpFmt, ...) /*FUNCPRINTF*/; void GL_DBG_Printf(const char *format, ...) /*FUNCPRINTF*/;
#define DBG_Printf GL_DBG_Printf
#ifdef _WINDOWS #ifdef _WINDOWS
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved); BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);

View file

@ -1,17 +1,12 @@
// Emacs style mode select -*- C++ -*- // SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// // Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2019 by Sonic Team Junior.
// //
// This program is free software; you can redistribute it and/or // This program is free software distributed under the
// modify it under the terms of the GNU General Public License // terms of the GNU General Public License, version 2.
// as published by the Free Software Foundation; either version 2 // See the 'LICENSE' file for more details.
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/// \file /// \file
/// \brief miscellaneous drawing (mainly 2d) /// \brief miscellaneous drawing (mainly 2d)
@ -23,6 +18,7 @@
#include "../doomdef.h" #include "../doomdef.h"
#ifdef HWRENDER #ifdef HWRENDER
#include "hw_main.h"
#include "hw_glob.h" #include "hw_glob.h"
#include "hw_drv.h" #include "hw_drv.h"
@ -41,9 +37,6 @@
#define O_BINARY 0 #define O_BINARY 0
#endif #endif
float gr_patch_scalex;
float gr_patch_scaley;
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma pack(1) #pragma pack(1)
#endif #endif
@ -63,9 +56,6 @@ typedef struct
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma pack() #pragma pack()
#endif #endif
typedef UINT8 GLRGB[3];
#define BLENDMODE PF_Translucent
static UINT8 softwaretranstogl[11] = { 0, 25, 51, 76,102,127,153,178,204,229,255}; static UINT8 softwaretranstogl[11] = { 0, 25, 51, 76,102,127,153,178,204,229,255};
static UINT8 softwaretranstogl_hi[11] = { 0, 51,102,153,204,255,255,255,255,255,255}; static UINT8 softwaretranstogl_hi[11] = { 0, 51,102,153,204,255,255,255,255,255,255};
@ -119,12 +109,12 @@ void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option)
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].sow = v[3].sow = 0.0f; v[0].s = v[3].s = 0.0f;
v[2].sow = v[1].sow = gpatch->max_s; v[2].s = v[1].s = gpatch->max_s;
v[0].tow = v[1].tow = 0.0f; v[0].t = v[1].t = 0.0f;
v[2].tow = v[3].tow = gpatch->max_t; v[2].t = v[3].t = gpatch->max_t;
flags = BLENDMODE|PF_Clip|PF_NoZClip|PF_NoDepthTest; flags = PF_Translucent|PF_NoDepthTest;
if (option & V_WRAPX) if (option & V_WRAPX)
flags |= PF_ForceWrapX; flags |= PF_ForceWrapX;
@ -220,7 +210,7 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
// if it's meant to cover the whole screen, black out the rest // if it's meant to cover the whole screen, black out the rest
// cx and cy are possibly *slightly* off from float maths // cx and cy are possibly *slightly* off from float maths
// This is done before here compared to software because we directly alter cx and cy to centre // This is done before here compared to software because we directly alter cx and cy to centre
/*if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT)
{ {
// Need to temporarily cache the real patch to get the colour of the top left pixel // Need to temporarily cache the real patch to get the colour of the top left pixel
patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
@ -228,7 +218,7 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
const UINT8 *source = (const UINT8 *)(column) + 3; const UINT8 *source = (const UINT8 *)(column) + 3;
HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
Z_Free(realpatch); Z_Free(realpatch);
}*/ }
// centre screen // centre screen
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f) if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
{ {
@ -279,19 +269,19 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
if (option & V_FLIP) if (option & V_FLIP)
{ {
v[0].sow = v[3].sow = gpatch->max_s; v[0].s = v[3].s = gpatch->max_s;
v[2].sow = v[1].sow = 0.0f; v[2].s = v[1].s = 0.0f;
} }
else else
{ {
v[0].sow = v[3].sow = 0.0f; v[0].s = v[3].s = 0.0f;
v[2].sow = v[1].sow = gpatch->max_s; v[2].s = v[1].s = gpatch->max_s;
} }
v[0].tow = v[1].tow = 0.0f; v[0].t = v[1].t = 0.0f;
v[2].tow = v[3].tow = gpatch->max_t; v[2].t = v[3].t = gpatch->max_t;
flags = BLENDMODE|PF_Clip|PF_NoZClip|PF_NoDepthTest; flags = PF_Translucent|PF_NoDepthTest;
if (option & V_WRAPX) if (option & V_WRAPX)
flags |= PF_ForceWrapX; flags |= PF_ForceWrapX;
@ -302,11 +292,11 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
if (alphalevel) if (alphalevel)
{ {
FSurfaceInfo Surf; FSurfaceInfo Surf;
Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = 0xff; Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff;
if (alphalevel == 13) Surf.FlatColor.s.alpha = softwaretranstogl_lo[hudtrans]; if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[hudtrans];
else if (alphalevel == 14) Surf.FlatColor.s.alpha = softwaretranstogl[hudtrans]; else if (alphalevel == 14) Surf.PolyColor.s.alpha = softwaretranstogl[hudtrans];
else if (alphalevel == 15) Surf.FlatColor.s.alpha = softwaretranstogl_hi[hudtrans]; else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[hudtrans];
else Surf.FlatColor.s.alpha = softwaretranstogl[10-alphalevel]; else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel];
flags |= PF_Modulated; flags |= PF_Modulated;
HWD.pfnDrawPolygon(&Surf, v, 4, flags); HWD.pfnDrawPolygon(&Surf, v, 4, flags);
} }
@ -368,7 +358,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
// if it's meant to cover the whole screen, black out the rest // if it's meant to cover the whole screen, black out the rest
// cx and cy are possibly *slightly* off from float maths // cx and cy are possibly *slightly* off from float maths
// This is done before here compared to software because we directly alter cx and cy to centre // This is done before here compared to software because we directly alter cx and cy to centre
/*if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT) if (cx >= -0.1f && cx <= 0.1f && SHORT(gpatch->width) == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && SHORT(gpatch->height) == BASEVIDHEIGHT)
{ {
// Need to temporarily cache the real patch to get the colour of the top left pixel // Need to temporarily cache the real patch to get the colour of the top left pixel
patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC); patch_t *realpatch = W_CacheLumpNumPwad(gpatch->wadnum, gpatch->lumpnum, PU_STATIC);
@ -376,7 +366,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
const UINT8 *source = (const UINT8 *)(column) + 3; const UINT8 *source = (const UINT8 *)(column) + 3;
HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0])); HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
Z_Free(realpatch); Z_Free(realpatch);
}*/ }
// centre screen // centre screen
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f) if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
{ {
@ -440,12 +430,12 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].sow = v[3].sow = ((sx)/(float)SHORT(gpatch->width) )*gpatch->max_s; v[0].s = v[3].s = ((sx)/(float)SHORT(gpatch->width) )*gpatch->max_s;
v[2].sow = v[1].sow = ((w )/(float)SHORT(gpatch->width) )*gpatch->max_s; v[2].s = v[1].s = ((w )/(float)SHORT(gpatch->width) )*gpatch->max_s;
v[0].tow = v[1].tow = ((sy)/(float)SHORT(gpatch->height))*gpatch->max_t; v[0].t = v[1].t = ((sy)/(float)SHORT(gpatch->height))*gpatch->max_t;
v[2].tow = v[3].tow = ((h )/(float)SHORT(gpatch->height))*gpatch->max_t; v[2].t = v[3].t = ((h )/(float)SHORT(gpatch->height))*gpatch->max_t;
flags = BLENDMODE|PF_Clip|PF_NoZClip|PF_NoDepthTest; flags = PF_Translucent|PF_NoDepthTest;
if (option & V_WRAPX) if (option & V_WRAPX)
flags |= PF_ForceWrapX; flags |= PF_ForceWrapX;
@ -456,11 +446,11 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
if (alphalevel) if (alphalevel)
{ {
FSurfaceInfo Surf; FSurfaceInfo Surf;
Surf.FlatColor.s.red = Surf.FlatColor.s.green = Surf.FlatColor.s.blue = 0xff; Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff;
if (alphalevel == 13) Surf.FlatColor.s.alpha = softwaretranstogl_lo[hudtrans]; if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[cv_translucenthud.value];
else if (alphalevel == 14) Surf.FlatColor.s.alpha = softwaretranstogl[hudtrans]; else if (alphalevel == 14) Surf.PolyColor.s.alpha = softwaretranstogl[cv_translucenthud.value];
else if (alphalevel == 15) Surf.FlatColor.s.alpha = softwaretranstogl_hi[hudtrans]; else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[cv_translucenthud.value];
else Surf.FlatColor.s.alpha = softwaretranstogl[10-alphalevel]; else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel];
flags |= PF_Modulated; flags |= PF_Modulated;
HWD.pfnDrawPolygon(&Surf, v, 4, flags); HWD.pfnDrawPolygon(&Surf, v, 4, flags);
} }
@ -468,41 +458,6 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
HWD.pfnDrawPolygon(NULL, v, 4, flags); HWD.pfnDrawPolygon(NULL, v, 4, flags);
} }
void HWR_DrawPic(INT32 x, INT32 y, lumpnum_t lumpnum)
{
FOutVector v[4];
const GLPatch_t *patch;
// make pic ready in hardware cache
patch = HWR_GetPic(lumpnum);
// 3--2
// | /|
// |/ |
// 0--1
v[0].x = v[3].x = 2.0f * (float)x/vid.width - 1;
v[2].x = v[1].x = 2.0f * (float)(x + patch->width*FIXED_TO_FLOAT(vid.fdupx))/vid.width - 1;
v[0].y = v[1].y = 1.0f - 2.0f * (float)y/vid.height;
v[2].y = v[3].y = 1.0f - 2.0f * (float)(y + patch->height*FIXED_TO_FLOAT(vid.fdupy))/vid.height;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].sow = v[3].sow = 0;
v[2].sow = v[1].sow = patch->max_s;
v[0].tow = v[1].tow = 0;
v[2].tow = v[3].tow = patch->max_t;
//Hurdler: Boris, the same comment as above... but maybe for pics
// it not a problem since they don't have any transparent pixel
// if I'm right !?
// But then, the question is: why not 0 instead of PF_Masked ?
// or maybe PF_Environment ??? (like what I said above)
// BP: PF_Environment don't change anything ! and 0 is undifined
HWD.pfnDrawPolygon(NULL, v, 4, BLENDMODE | PF_NoDepthTest | PF_Clip | PF_NoZClip);
}
// ========================================================================== // ==========================================================================
// V_VIDEO.C STUFF // V_VIDEO.C STUFF
// ========================================================================== // ==========================================================================
@ -563,12 +518,12 @@ void HWR_DrawFlatFill (INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
// flat is 64x64 lod and texture offsets are [0.0, 1.0] // flat is 64x64 lod and texture offsets are [0.0, 1.0]
v[0].sow = v[3].sow = (float)((x & flatflag)/dflatsize); v[0].s = v[3].s = (float)((x & flatflag)/dflatsize);
v[2].sow = v[1].sow = (float)(v[0].sow + w/dflatsize); v[2].s = v[1].s = (float)(v[0].s + w/dflatsize);
v[0].tow = v[1].tow = (float)((y & flatflag)/dflatsize); v[0].t = v[1].t = (float)((y & flatflag)/dflatsize);
v[2].tow = v[3].tow = (float)(v[0].tow + h/dflatsize); v[2].t = v[3].t = (float)(v[0].t + h/dflatsize);
HWR_GetFlat(flatlumpnum); HWR_GetFlat(flatlumpnum, false); // Never Encore map drawflatfill, duh.
//Hurdler: Boris, the same comment as above... but maybe for pics //Hurdler: Boris, the same comment as above... but maybe for pics
// it not a problem since they don't have any transparent pixel // it not a problem since they don't have any transparent pixel
@ -598,20 +553,20 @@ void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength)
v[2].y = v[3].y = 1.0f; v[2].y = v[3].y = 1.0f;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].sow = v[3].sow = 0.0f; v[0].s = v[3].s = 0.0f;
v[2].sow = v[1].sow = 1.0f; v[2].s = v[1].s = 1.0f;
v[0].tow = v[1].tow = 1.0f; v[0].t = v[1].t = 1.0f;
v[2].tow = v[3].tow = 0.0f; v[2].t = v[3].t = 0.0f;
if (color & 0xFF00) // Do COLORMAP fade. if (color & 0xFF00) // Do COLORMAP fade.
{ {
Surf.FlatColor.rgba = UINT2RGBA(0x01010160); Surf.PolyColor.rgba = UINT2RGBA(0x01010160);
Surf.FlatColor.s.alpha = (strength*8); Surf.PolyColor.s.alpha = (strength*8);
} }
else // Do TRANSMAP** fade. else // Do TRANSMAP** fade.
{ {
Surf.FlatColor.rgba = pLocalPalette[color].rgba; Surf.PolyColor.rgba = pLocalPalette[color].rgba;
Surf.FlatColor.s.alpha = (UINT8)(strength*25.5f); Surf.PolyColor.s.alpha = (UINT8)(strength*25.5f);
} }
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
} }
@ -632,13 +587,13 @@ void HWR_DrawConsoleBack(UINT32 color, INT32 height)
v[2].y = v[3].y = 1.0f; v[2].y = v[3].y = 1.0f;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].sow = v[3].sow = 0.0f; v[0].s = v[3].s = 0.0f;
v[2].sow = v[1].sow = 1.0f; v[2].s = v[1].s = 1.0f;
v[0].tow = v[1].tow = 1.0f; v[0].t = v[1].t = 1.0f;
v[2].tow = v[3].tow = 0.0f; v[2].t = v[3].t = 0.0f;
Surf.FlatColor.rgba = UINT2RGBA(color); Surf.PolyColor.rgba = UINT2RGBA(color);
Surf.FlatColor.s.alpha = 0x80; Surf.PolyColor.s.alpha = 0x80;
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest); HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
} }
@ -773,6 +728,7 @@ void HWR_DrawViewBorder(INT32 clearlines)
} }
// ========================================================================== // ==========================================================================
// AM_MAP.C DRAWING STUFF // AM_MAP.C DRAWING STUFF
// ========================================================================== // ==========================================================================
@ -797,225 +753,6 @@ void HWR_drawAMline(const fline_t *fl, INT32 color)
HWD.pfnDraw2DLine(&v1, &v2, color_rgba); HWD.pfnDraw2DLine(&v1, &v2, color_rgba);
} }
// -----------------+
// HWR_DrawFill : draw flat coloured rectangle, with no texture
// -----------------+
void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
{
FOutVector v[4];
FSurfaceInfo Surf;
float fx, fy, fw, fh;
if (w < 0 || h < 0)
return; // consistency w/ software
// 3--2
// | /|
// |/ |
// 0--1
fx = (float)x;
fy = (float)y;
fw = (float)w;
fh = (float)h;
if (!(color & V_NOSCALESTART))
{
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
{
RGBA_t rgbaColour = V_GetColor(color);
FRGBAFloat clearColour;
clearColour.red = (float)rgbaColour.s.red / 255;
clearColour.green = (float)rgbaColour.s.green / 255;
clearColour.blue = (float)rgbaColour.s.blue / 255;
clearColour.alpha = 1;
HWD.pfnClearBuffer(true, false, &clearColour);
return;
}
fx *= dupx;
fy *= dupy;
fw *= dupx;
fh *= dupy;
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
{
if (color & V_SNAPTORIGHT)
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(color & V_SNAPTOLEFT))
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
}
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
{
// same thing here
if (color & V_SNAPTOBOTTOM)
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(color & V_SNAPTOTOP))
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
}
if (color & V_SPLITSCREEN)
fy += ((float)BASEVIDHEIGHT * dupy)/2;
if (color & V_HORZSCREEN)
fx += ((float)BASEVIDWIDTH * dupx)/2;
}
if (fx >= vid.width || fy >= vid.height)
return;
if (fx < 0)
{
fw += fx;
fx = 0;
}
if (fy < 0)
{
fh += fy;
fy = 0;
}
if (fw <= 0 || fh <= 0)
return;
if (fx + fw > vid.width)
fw = (float)vid.width - fx;
if (fy + fh > vid.height)
fh = (float)vid.height - fy;
fx = -1 + fx / (vid.width / 2);
fy = 1 - fy / (vid.height / 2);
fw = fw / (vid.width / 2);
fh = fh / (vid.height / 2);
v[0].x = v[3].x = fx;
v[2].x = v[1].x = fx + fw;
v[0].y = v[1].y = fy;
v[2].y = v[3].y = fy - fh;
//Hurdler: do we still use this argb color? if not, we should remove it
v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].sow = v[3].sow = 0.0f;
v[2].sow = v[1].sow = 1.0f;
v[0].tow = v[1].tow = 0.0f;
v[2].tow = v[3].tow = 1.0f;
Surf.FlatColor = V_GetColor(color);
HWD.pfnDrawPolygon(&Surf, v, 4,
PF_Modulated|PF_NoTexture|PF_NoDepthTest);
}
// -------------------+
// HWR_DrawConsoleFill : draw flat coloured transparent rectangle because that's cool, and hw sucks less than sw for that.
// -------------------+
void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 options)
{
FOutVector v[4];
FSurfaceInfo Surf;
float fx, fy, fw, fh;
if (w < 0 || h < 0)
return; // consistency w/ software
// 3--2
// | /|
// |/ |
// 0--1
fx = (float)x;
fy = (float)y;
fw = (float)w;
fh = (float)h;
if (!(options & V_NOSCALESTART))
{
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
{
RGBA_t rgbaColour = V_GetColor(color);
FRGBAFloat clearColour;
clearColour.red = (float)rgbaColour.s.red / 255;
clearColour.green = (float)rgbaColour.s.green / 255;
clearColour.blue = (float)rgbaColour.s.blue / 255;
clearColour.alpha = 1;
HWD.pfnClearBuffer(true, false, &clearColour);
return;
}
fx *= dupx;
fy *= dupy;
fw *= dupx;
fh *= dupy;
if (fabsf((float)vid.width - ((float)BASEVIDWIDTH * dupx)) > 1.0E-36f)
{
if (options & V_SNAPTORIGHT)
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(options & V_SNAPTOLEFT))
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
}
if (fabsf((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) > 1.0E-36f)
{
// same thing here
if (options & V_SNAPTOBOTTOM)
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(options & V_SNAPTOTOP))
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
}
if (options & V_SPLITSCREEN)
fy += ((float)BASEVIDHEIGHT * dupy)/2;
if (options & V_HORZSCREEN)
fx += ((float)BASEVIDWIDTH * dupx)/2;
}
if (fx >= vid.width || fy >= vid.height)
return;
if (fx < 0)
{
fw += fx;
fx = 0;
}
if (fy < 0)
{
fh += fy;
fy = 0;
}
if (fw <= 0 || fh <= 0)
return;
if (fx + fw > vid.width)
fw = (float)vid.width - fx;
if (fy + fh > vid.height)
fh = (float)vid.height - fy;
fx = -1 + fx / (vid.width / 2);
fy = 1 - fy / (vid.height / 2);
fw = fw / (vid.width / 2);
fh = fh / (vid.height / 2);
v[0].x = v[3].x = fx;
v[2].x = v[1].x = fx + fw;
v[0].y = v[1].y = fy;
v[2].y = v[3].y = fy - fh;
//Hurdler: do we still use this argb color? if not, we should remove it
v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].sow = v[3].sow = 0.0f;
v[2].sow = v[1].sow = 1.0f;
v[0].tow = v[1].tow = 0.0f;
v[2].tow = v[3].tow = 1.0f;
Surf.FlatColor.rgba = UINT2RGBA(color);
Surf.FlatColor.s.alpha = 0x80;
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
}
// -----------------+ // -----------------+
// HWR_DrawDiag : draw flat coloured rectangle, with no texture // HWR_DrawDiag : draw flat coloured rectangle, with no texture
// -----------------+ // -----------------+
@ -1097,22 +834,234 @@ void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color)
v[3].y = fy - fh; v[3].y = fy - fh;
v[2].y = fy - fwait; v[2].y = fy - fwait;
//Hurdler: do we still use this argb color? if not, we should remove it
v[0].argb = v[1].argb = v[2].argb = v[3].argb = 0xff00ff00; //;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f; v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].sow = v[3].sow = 0.0f; v[0].s = v[3].s = 0.0f;
v[2].sow = v[1].sow = 1.0f; v[2].s = v[1].s = 1.0f;
v[0].tow = v[1].tow = 0.0f; v[0].t = v[1].t = 0.0f;
v[2].tow = v[3].tow = 1.0f; v[2].t = v[3].t = 1.0f;
Surf.FlatColor = V_GetColor(color); Surf.PolyColor = V_GetColor(color);
HWD.pfnDrawPolygon(&Surf, v, 4, HWD.pfnDrawPolygon(&Surf, v, 4,
PF_Modulated|PF_NoTexture|PF_NoDepthTest); PF_Modulated|PF_NoTexture|PF_NoDepthTest);
} }
// -------------------+
// HWR_DrawConsoleFill : draw flat coloured transparent rectangle because that's cool, and hw sucks less than sw for that.
// -------------------+
void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 options)
{
FOutVector v[4];
FSurfaceInfo Surf;
float fx, fy, fw, fh;
if (w < 0 || h < 0)
return; // consistency w/ software
// 3--2
// | /|
// |/ |
// 0--1
fx = (float)x;
fy = (float)y;
fw = (float)w;
fh = (float)h;
if (!(options & V_NOSCALESTART))
{
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
{
RGBA_t rgbaColour = V_GetColor(color);
FRGBAFloat clearColour;
clearColour.red = (float)rgbaColour.s.red / 255;
clearColour.green = (float)rgbaColour.s.green / 255;
clearColour.blue = (float)rgbaColour.s.blue / 255;
clearColour.alpha = 1;
HWD.pfnClearBuffer(true, false, &clearColour);
return;
}
fx *= dupx;
fy *= dupy;
fw *= dupx;
fh *= dupy;
if (fabsf((float)vid.width - ((float)BASEVIDWIDTH * dupx)) > 1.0E-36f)
{
if (options & V_SNAPTORIGHT)
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(options & V_SNAPTOLEFT))
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
}
if (fabsf((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) > 1.0E-36f)
{
// same thing here
if (options & V_SNAPTOBOTTOM)
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(options & V_SNAPTOTOP))
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
}
if (options & V_SPLITSCREEN)
fy += ((float)BASEVIDHEIGHT * dupy)/2;
if (options & V_HORZSCREEN)
fx += ((float)BASEVIDWIDTH * dupx)/2;
}
if (fx >= vid.width || fy >= vid.height)
return;
if (fx < 0)
{
fw += fx;
fx = 0;
}
if (fy < 0)
{
fh += fy;
fy = 0;
}
if (fw <= 0 || fh <= 0)
return;
if (fx + fw > vid.width)
fw = (float)vid.width - fx;
if (fy + fh > vid.height)
fh = (float)vid.height - fy;
fx = -1 + fx / (vid.width / 2);
fy = 1 - fy / (vid.height / 2);
fw = fw / (vid.width / 2);
fh = fh / (vid.height / 2);
v[0].x = v[3].x = fx;
v[2].x = v[1].x = fx + fw;
v[0].y = v[1].y = fy;
v[2].y = v[3].y = fy - fh;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].s = v[3].s = 0.0f;
v[2].s = v[1].s = 1.0f;
v[0].t = v[1].t = 0.0f;
v[2].t = v[3].t = 1.0f;
Surf.PolyColor.rgba = UINT2RGBA(color);
Surf.PolyColor.s.alpha = 0x80;
HWD.pfnDrawPolygon(&Surf, v, 4, PF_NoTexture|PF_Modulated|PF_Translucent|PF_NoDepthTest);
}
// -----------------+
// HWR_DrawFill : draw flat coloured rectangle, with no texture
// -----------------+
void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
{
FOutVector v[4];
FSurfaceInfo Surf;
float fx, fy, fw, fh;
if (w < 0 || h < 0)
return; // consistency w/ software
// 3--2
// | /|
// |/ |
// 0--1
fx = (float)x;
fy = (float)y;
fw = (float)w;
fh = (float)h;
if (!(color & V_NOSCALESTART))
{
float dupx = (float)vid.dupx, dupy = (float)vid.dupy;
if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
{
RGBA_t rgbaColour = V_GetColor(color);
FRGBAFloat clearColour;
clearColour.red = (float)rgbaColour.s.red / 255;
clearColour.green = (float)rgbaColour.s.green / 255;
clearColour.blue = (float)rgbaColour.s.blue / 255;
clearColour.alpha = 1;
HWD.pfnClearBuffer(true, false, &clearColour);
return;
}
fx *= dupx;
fy *= dupy;
fw *= dupx;
fh *= dupy;
if (fabsf((float)vid.width - (float)BASEVIDWIDTH * dupx) > 1.0E-36f)
{
if (color & V_SNAPTORIGHT)
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
else if (!(color & V_SNAPTOLEFT))
fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
}
if (fabsf((float)vid.height - (float)BASEVIDHEIGHT * dupy) > 1.0E-36f)
{
// same thing here
if (color & V_SNAPTOBOTTOM)
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy));
else if (!(color & V_SNAPTOTOP))
fy += ((float)vid.height - ((float)BASEVIDHEIGHT * dupy)) / 2;
}
if (color & V_SPLITSCREEN)
fy += ((float)BASEVIDHEIGHT * dupy)/2;
if (color & V_HORZSCREEN)
fx += ((float)BASEVIDWIDTH * dupx)/2;
}
if (fx >= vid.width || fy >= vid.height)
return;
if (fx < 0)
{
fw += fx;
fx = 0;
}
if (fy < 0)
{
fh += fy;
fy = 0;
}
if (fw <= 0 || fh <= 0)
return;
if (fx + fw > vid.width)
fw = (float)vid.width - fx;
if (fy + fh > vid.height)
fh = (float)vid.height - fy;
fx = -1 + fx / (vid.width / 2);
fy = 1 - fy / (vid.height / 2);
fw = fw / (vid.width / 2);
fh = fh / (vid.height / 2);
v[0].x = v[3].x = fx;
v[2].x = v[1].x = fx + fw;
v[0].y = v[1].y = fy;
v[2].y = v[3].y = fy - fh;
v[0].z = v[1].z = v[2].z = v[3].z = 1.0f;
v[0].s = v[3].s = 0.0f;
v[2].s = v[1].s = 1.0f;
v[0].t = v[1].t = 0.0f;
v[2].t = v[3].t = 1.0f;
Surf.PolyColor = V_GetColor(color);
HWD.pfnDrawPolygon(&Surf, v, 4,
PF_Modulated|PF_NoTexture|PF_NoDepthTest);
}
#ifdef HAVE_PNG #ifdef HAVE_PNG
@ -1196,21 +1145,24 @@ UINT8 *HWR_GetScreenshot(void)
return buf; return buf;
} }
boolean HWR_Screenshot(const char *lbmname) boolean HWR_Screenshot(const char *pathname)
{ {
boolean ret; boolean ret;
UINT8 *buf = malloc(vid.width * vid.height * 3 * sizeof (*buf)); UINT8 *buf = malloc(vid.width * vid.height * 3 * sizeof (*buf));
if (!buf) if (!buf)
{
CONS_Debug(DBG_RENDER, "HWR_Screenshot: Failed to allocate memory\n");
return false; return false;
}
// returns 24bit 888 RGB // returns 24bit 888 RGB
HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf); HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf);
#ifdef USE_PNG #ifdef USE_PNG
ret = M_SavePNG(lbmname, buf, vid.width, vid.height, NULL); ret = M_SavePNG(pathname, buf, vid.width, vid.height, NULL);
#else #else
ret = saveTGA(lbmname, buf, vid.width, vid.height); ret = saveTGA(pathname, buf, vid.width, vid.height);
#endif #endif
free(buf); free(buf);
return ret; return ret;

View file

@ -1,21 +1,15 @@
// Emacs style mode select -*- C++ -*- // SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// // Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2019 by Sonic Team Junior.
// //
// This program is free software; you can redistribute it and/or // This program is free software distributed under the
// modify it under the terms of the GNU General Public License // terms of the GNU General Public License, version 2.
// as published by the Free Software Foundation; either version 2 // See the 'LICENSE' file for more details.
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/// \file /// \file
/// \brief imports/exports for the 3D hardware low-level interface API /// \brief imports/exports for the GPU hardware low-level interface API
#ifndef __HWR_DRV_H__ #ifndef __HWR_DRV_H__
#define __HWR_DRV_H__ #define __HWR_DRV_H__
@ -32,13 +26,7 @@
// STANDARD DLL EXPORTS // STANDARD DLL EXPORTS
// ========================================================================== // ==========================================================================
EXPORT boolean HWRAPI(Init) (I_Error_t ErrorFunction); EXPORT boolean HWRAPI(Init) (void);
#ifndef HAVE_SDL
EXPORT void HWRAPI(Shutdown) (void);
#endif
#ifdef _WINDOWS
EXPORT void HWRAPI(GetModeList) (vmode_t **pvidmodes, INT32 *numvidmodes);
#endif
#if defined (PURESDL) || defined (macintosh) #if defined (PURESDL) || defined (macintosh)
EXPORT void HWRAPI(SetPalette) (INT32 *, RGBA_t *gamma); EXPORT void HWRAPI(SetPalette) (INT32 *, RGBA_t *gamma);
#else #else
@ -58,14 +46,13 @@ EXPORT void HWRAPI(ClearMipMapCache) (void);
EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value); EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value);
//Hurdler: added for new development //Hurdler: added for new development
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 *color); EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, FSurfaceInfo *Surface);
EXPORT void HWRAPI(CreateModelVBOs) (model_t *model); EXPORT void HWRAPI(CreateModelVBOs) (model_t *model);
EXPORT void HWRAPI(SetTransform) (FTransform *ptransform); EXPORT void HWRAPI(SetTransform) (FTransform *stransform);
EXPORT INT32 HWRAPI(GetTextureUsed) (void); EXPORT INT32 HWRAPI(GetTextureUsed) (void);
EXPORT INT32 HWRAPI(GetRenderVersion) (void);
#define SCREENVERTS 10 EXPORT void HWRAPI(RenderSkyDome) (INT32 tex, INT32 texture_width, INT32 texture_height, FTransform transform);
EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]);
EXPORT void HWRAPI(FlushScreenTextures) (void); EXPORT void HWRAPI(FlushScreenTextures) (void);
EXPORT void HWRAPI(StartScreenWipe) (void); EXPORT void HWRAPI(StartScreenWipe) (void);
EXPORT void HWRAPI(EndScreenWipe) (void); EXPORT void HWRAPI(EndScreenWipe) (void);
@ -74,6 +61,22 @@ EXPORT void HWRAPI(DrawIntermissionBG) (void);
EXPORT void HWRAPI(MakeScreenTexture) (void); EXPORT void HWRAPI(MakeScreenTexture) (void);
EXPORT void HWRAPI(MakeScreenFinalTexture) (void); EXPORT void HWRAPI(MakeScreenFinalTexture) (void);
EXPORT void HWRAPI(DrawScreenFinalTexture) (int width, int height); EXPORT void HWRAPI(DrawScreenFinalTexture) (int width, int height);
#define SCREENVERTS 10
EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]);
// jimita
EXPORT boolean HWRAPI(LoadShaders) (void);
EXPORT void HWRAPI(KillShaders) (void);
EXPORT void HWRAPI(SetShader) (int shader);
EXPORT void HWRAPI(UnSetShader) (void);
EXPORT void HWRAPI(LoadCustomShader) (int number, char *shader, size_t size, boolean fragment);
EXPORT void HWRAPI(InitCustomShaders) (void);
EXPORT void HWRAPI(StartBatching) (void);
EXPORT void HWRAPI(RenderBatches) (int *sNumPolys, int *sNumVerts, int *sNumCalls, int *sNumShaders, int *sNumTextures, int *sNumPolyFlags, int *sNumColors);
// ========================================================================== // ==========================================================================
// HWR DRIVER OBJECT, FOR CLIENT PROGRAM // HWR DRIVER OBJECT, FOR CLIENT PROGRAM
// ========================================================================== // ==========================================================================
@ -93,18 +96,11 @@ struct hwdriver_s
ReadRect pfnReadRect; ReadRect pfnReadRect;
GClipRect pfnGClipRect; GClipRect pfnGClipRect;
ClearMipMapCache pfnClearMipMapCache; ClearMipMapCache pfnClearMipMapCache;
SetSpecialState pfnSetSpecialState;//Hurdler: added for backward compatibility SetSpecialState pfnSetSpecialState;
DrawModel pfnDrawModel; DrawModel pfnDrawModel;
CreateModelVBOs pfnCreateModelVBOs; CreateModelVBOs pfnCreateModelVBOs;
SetTransform pfnSetTransform; SetTransform pfnSetTransform;
GetTextureUsed pfnGetTextureUsed; GetTextureUsed pfnGetTextureUsed;
GetRenderVersion pfnGetRenderVersion;
#ifdef _WINDOWS
GetModeList pfnGetModeList;
#endif
#ifndef HAVE_SDL
Shutdown pfnShutdown;
#endif
PostImgRedraw pfnPostImgRedraw; PostImgRedraw pfnPostImgRedraw;
FlushScreenTextures pfnFlushScreenTextures; FlushScreenTextures pfnFlushScreenTextures;
StartScreenWipe pfnStartScreenWipe; StartScreenWipe pfnStartScreenWipe;
@ -114,16 +110,25 @@ struct hwdriver_s
MakeScreenTexture pfnMakeScreenTexture; MakeScreenTexture pfnMakeScreenTexture;
MakeScreenFinalTexture pfnMakeScreenFinalTexture; MakeScreenFinalTexture pfnMakeScreenFinalTexture;
DrawScreenFinalTexture pfnDrawScreenFinalTexture; DrawScreenFinalTexture pfnDrawScreenFinalTexture;
RenderSkyDome pfnRenderSkyDome;
LoadShaders pfnLoadShaders;
KillShaders pfnKillShaders;
SetShader pfnSetShader;
UnSetShader pfnUnSetShader;
LoadCustomShader pfnLoadCustomShader;
InitCustomShaders pfnInitCustomShaders;
StartBatching pfnStartBatching;
RenderBatches pfnRenderBatches;
}; };
extern struct hwdriver_s hwdriver; extern struct hwdriver_s hwdriver;
//Hurdler: 16/10/99: added for OpenGL gamma correction
//extern RGBA_t gamma_correction;
#define HWD hwdriver #define HWD hwdriver
#endif //not defined _CREATE_DLL_ #endif //not defined _CREATE_DLL_
#endif //__HWR_DRV_H__ #endif //__HWR_DRV_H__

View file

@ -1,71 +0,0 @@
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright (C) 1998-2000 by DooM Legacy Team.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//-----------------------------------------------------------------------------
/// \file
/// \brief Declaration needed by Glide renderer
/// !!! To be replaced by our own def in the future !!!
#ifndef _GLIDE_H_
#define _GLIDE_H_
#ifndef __GLIDE_H__
typedef unsigned long FxU32;
typedef long FxI32;
typedef FxI32 GrAspectRatio_t;
#define GR_ASPECT_LOG2_8x1 3 /* 8W x 1H */
#define GR_ASPECT_LOG2_4x1 2 /* 4W x 1H */
#define GR_ASPECT_LOG2_2x1 1 /* 2W x 1H */
#define GR_ASPECT_LOG2_1x1 0 /* 1W x 1H */
#define GR_ASPECT_LOG2_1x2 -1 /* 1W x 2H */
#define GR_ASPECT_LOG2_1x4 -2 /* 1W x 4H */
#define GR_ASPECT_LOG2_1x8 -3 /* 1W x 8H */
typedef FxI32 GrLOD_t;
#define GR_LOD_LOG2_256 0x8
#define GR_LOD_LOG2_128 0x7
#define GR_LOD_LOG2_64 0x6
#define GR_LOD_LOG2_32 0x5
#define GR_LOD_LOG2_16 0x4
#define GR_LOD_LOG2_8 0x3
#define GR_LOD_LOG2_4 0x2
#define GR_LOD_LOG2_2 0x1
#define GR_LOD_LOG2_1 0x0
typedef FxI32 GrTextureFormat_t;
#define GR_TEXFMT_ALPHA_8 0x2 /* (0..0xFF) alpha */
#define GR_TEXFMT_INTENSITY_8 0x3 /* (0..0xFF) intensity */
#define GR_TEXFMT_ALPHA_INTENSITY_44 0x4
#define GR_TEXFMT_P_8 0x5 /* 8-bit palette */
#define GR_TEXFMT_RGB_565 0xa
#define GR_TEXFMT_ARGB_1555 0xb
#define GR_TEXFMT_ARGB_4444 0xc
#define GR_TEXFMT_ALPHA_INTENSITY_88 0xd
#define GR_TEXFMT_AP_88 0xe /* 8-bit alpha 8-bit palette */
#define GR_RGBA 0x6 // 32 bit RGBA !
typedef struct
{
GrLOD_t smallLodLog2;
GrLOD_t largeLodLog2;
GrAspectRatio_t aspectRatioLog2;
GrTextureFormat_t format;
void *data;
} GrTexInfo;
#endif // __GLIDE_H__ (defined in <glide.h>)
#endif // _GLIDE_H_

View file

@ -1,18 +1,12 @@
// Emacs style mode select -*- C++ -*- // SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// // Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2019 by Sonic Team Junior.
// //
// This program is free software; you can redistribute it and/or // This program is free software distributed under the
// modify it under the terms of the GNU General Public License // terms of the GNU General Public License, version 2.
// as published by the Free Software Foundation; either version 2 // See the 'LICENSE' file for more details.
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/// \file /// \file
/// \brief globals (shared data & code) for hw_ modules /// \brief globals (shared data & code) for hw_ modules
@ -21,78 +15,18 @@
#define _HWR_GLOB_H_ #define _HWR_GLOB_H_
#include "hw_defs.h" #include "hw_defs.h"
#include "hw_main.h"
#include "../m_misc.h" #include "../m_misc.h"
#include "../r_defs.h"
// the original aspect ratio of Doom graphics isn't square
#define ORIGINAL_ASPECT (320.0f/200.0f)
// Uncomment this to enable the OpenGL loading screen // Uncomment this to enable the OpenGL loading screen
//#define HWR_LOADING_SCREEN //#define HWR_LOADING_SCREEN
// -----------
// structures
// -----------
// a vertex of a Doom 'plane' polygon
typedef struct
{
float x;
float y;
float z;
} polyvertex_t;
#ifdef _MSC_VER
#pragma warning(disable : 4200)
#endif
// a convex 'plane' polygon, clockwise order
typedef struct
{
INT32 numpts;
polyvertex_t pts[0];
} poly_t;
#ifdef _MSC_VER
#pragma warning(default : 4200)
#endif
// holds extra info for 3D render, for each subsector in subsectors[]
typedef struct
{
poly_t *planepoly; // the generated convex polygon
} extrasubsector_t;
// needed for sprite rendering
// equivalent of the software renderer's vissprites
typedef struct gr_vissprite_s
{
// Doubly linked list
struct gr_vissprite_s *prev;
struct gr_vissprite_s *next;
float x1, x2;
float tz, ty;
lumpnum_t patchlumpnum;
boolean flip;
UINT8 translucency; //alpha level 0-255
mobj_t *mobj;
boolean precip; // Tails 08-25-2002
boolean vflip;
//Hurdler: 25/04/2000: now support colormap in hardware mode
UINT8 *colormap;
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
float z1, z2;
} gr_vissprite_t;
// -------- // --------
// hw_bsp.c // hw_bsp.c
// -------- // --------
extern extrasubsector_t *extrasubsectors; extern extrasubsector_t *extrasubsectors;
extern size_t addsubsector; extern size_t addsubsector;
void HWR_InitPolyPool(void);
void HWR_FreePolyPool(void);
// -------- // --------
// hw_cache.c // hw_cache.c
// -------- // --------
@ -100,12 +34,14 @@ void HWR_InitTextureCache(void);
void HWR_FreeTextureCache(void); void HWR_FreeTextureCache(void);
void HWR_FreeExtraSubsectors(void); void HWR_FreeExtraSubsectors(void);
void HWR_GetFlat(lumpnum_t flatlumpnum); void HWR_GetFlat(lumpnum_t flatlumpnum, boolean noencoremap);
// ^ some flats must NOT be remapped to encore, since we remap them as we cache them for ease, adding a toggle here seems wise.
GLTexture_t *HWR_GetTexture(INT32 tex); GLTexture_t *HWR_GetTexture(INT32 tex);
void HWR_GetPatch(GLPatch_t *gpatch); void HWR_GetPatch(GLPatch_t *gpatch);
void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap); void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap);
void HWR_MakePatch(patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap);
void HWR_UnlockCachedPatch(GLPatch_t *gpatch); void HWR_UnlockCachedPatch(GLPatch_t *gpatch);
GLPatch_t *HWR_GetPic(lumpnum_t lumpnum);
void HWR_SetPalette(RGBA_t *palette); void HWR_SetPalette(RGBA_t *palette);
GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wad, UINT16 lump); GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wad, UINT16 lump);
GLPatch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum); GLPatch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum);
@ -114,13 +50,9 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum);
// -------- // --------
// hw_draw.c // hw_draw.c
// -------- // --------
extern float gr_patch_scalex;
extern float gr_patch_scaley;
extern consvar_t cv_grrounddown; // on/off extern consvar_t cv_grrounddown; // on/off
extern INT32 patchformat; extern INT32 patchformat;
extern INT32 textureformat; extern INT32 textureformat;
extern boolean firetranslucent;
#endif //_HW_GLOB_ #endif //_HW_GLOB_

File diff suppressed because it is too large Load diff

View file

@ -1,17 +1,12 @@
// Emacs style mode select -*- C++ -*- // SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// // Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2019 by Sonic Team Junior.
// //
// This program is free software; you can redistribute it and/or // This program is free software distributed under the
// modify it under the terms of the GNU General Public License // terms of the GNU General Public License, version 2.
// as published by the Free Software Foundation; either version 2 // See the 'LICENSE' file for more details.
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/// \file /// \file
/// \brief Dynamic lighting & coronas add on by Hurdler /// \brief Dynamic lighting & coronas add on by Hurdler
@ -22,79 +17,4 @@
#include "hw_glob.h" #include "hw_glob.h"
#include "hw_defs.h" #include "hw_defs.h"
#define NUMLIGHTFREESLOTS 32 // Free light slots (for SOCs)
#ifdef ALAM_LIGHTING
#define NEWCORONAS
#define DL_MAX_LIGHT 256 // maximum number of lights (extra lights are ignored)
void HWR_InitLight(void);
void HWR_DL_AddLight(gr_vissprite_t *spr, GLPatch_t *patch);
void HWR_PlaneLighting(FOutVector *clVerts, int nrClipVerts);
void HWR_WallLighting(FOutVector *wlVerts);
void HWR_ResetLights(void);
void HWR_SetLights(int viewnumber);
#ifdef NEWCORONAS
void HWR_DrawCoronas(void);
#else
void HWR_DoCoronasLighting(FOutVector *outVerts, gr_vissprite_t *spr);
#endif
typedef struct
{
int nb;
light_t *p_lspr[DL_MAX_LIGHT];
FVector position[DL_MAX_LIGHT]; // actually maximum DL_MAX_LIGHT lights
mobj_t *mo[DL_MAX_LIGHT];
} dynlights_t;
#endif
typedef enum
{
NOLIGHT = 0,
RINGSPARK_L,
SUPERSONIC_L, // Cool. =)
SUPERSPARK_L,
INVINCIBLE_L,
GREENSHIELD_L,
BLUESHIELD_L,
YELLOWSHIELD_L,
REDSHIELD_L,
BLACKSHIELD_L,
WHITESHIELD_L,
SMALLREDBALL_L,
RINGLIGHT_L,
GREENSMALL_L,
REDSMALL_L,
GREENSHINE_L,
ORANGESHINE_L,
PINKSHINE_L,
BLUESHINE_L,
REDSHINE_L,
LBLUESHINE_L,
GREYSHINE_L,
REDBALL_L,
GREENBALL_L,
BLUEBALL_L,
NIGHTSLIGHT_L,
JETLIGHT_L,
GOOPLIGHT_L,
STREETLIGHT_L,
// free slots for SOCs at run-time --------------------
FREESLOT0_L,
//
// ... 32 free lights here ...
//
LASTFREESLOT_L = (FREESLOT0_L+NUMLIGHTFREESLOTS-1),
// end of freeslots ---------------------------------------------
NUMLIGHTS
} lightspritenum_t;
extern light_t lspr[NUMLIGHTS];
extern light_t *t_lspr[NUMSPRITES];
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -17,9 +17,12 @@
/// \file /// \file
/// \brief 3D render mode functions /// \brief 3D render mode functions
#define GLENCORE
#ifndef __HWR_MAIN_H__ #ifndef __HWR_MAIN_H__
#define __HWR_MAIN_H__ #define __HWR_MAIN_H__
#include "hw_glob.h"
#include "hw_data.h" #include "hw_data.h"
#include "hw_defs.h" #include "hw_defs.h"
@ -27,38 +30,51 @@
#include "../d_player.h" #include "../d_player.h"
#include "../r_defs.h" #include "../r_defs.h"
#define GLENCORE
// Startup & Shutdown the hardware mode renderer // Startup & Shutdown the hardware mode renderer
void HWR_Startup(void); void HWR_Startup(void);
void HWR_Shutdown(void); void HWR_Shutdown(void);
void HWR_drawAMline(const fline_t *fl, INT32 color); extern float gr_viewwidth, gr_viewheight, gr_baseviewwindowx, gr_baseviewwindowy;
void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength);
void HWR_DrawConsoleBack(UINT32 color, INT32 height); extern float gr_basewindowcenterx, gr_basewindowcentery;
void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player);
void HWR_RenderPlayerView(INT32 viewnumber, player_t *player); extern FTransform atransform;
void HWR_DrawViewBorder(INT32 clearlines);
void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum); // hw_draw.c
UINT8 *HWR_GetScreenshot(void);
boolean HWR_Screenshot(const char *lbmname);
void HWR_InitTextureMapping(void);
void HWR_SetViewSize(void);
void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option); void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option);
void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t scale, INT32 option, const UINT8 *colormap); void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t scale, INT32 option, const UINT8 *colormap);
void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t scale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h); void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h);
void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap);
void HWR_CreatePlanePolygons(INT32 bspnum);
void HWR_CreateStaticLightmaps(INT32 bspnum);
void HWR_PrepLevelCache(size_t pnumtextures);
void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color); void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color);
void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 options); // Lat: separate flags from color since color needs to be an uint to work right. void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 options); // Lat: separate flags from color since color needs to be an uint to work right.
void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color); void HWR_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 color);
void HWR_DrawPic(INT32 x,INT32 y,lumpnum_t lumpnum); void HWR_drawAMline(const fline_t *fl, INT32 color);
void HWR_FadeScreenMenuBack(UINT16 color, UINT8 strength);
void HWR_DrawConsoleBack(UINT32 color, INT32 height);
void HWR_DrawViewBorder(INT32 clearlines);
void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum);
UINT8 *HWR_GetScreenshot(void);
boolean HWR_Screenshot(const char *lbmname);
// hw_main.c
void HWR_RenderFrame(INT32 viewnumber, player_t *player, boolean skybox);
void HWR_RenderPlayerView(INT32 viewnumber, player_t *player);
void HWR_LoadShaders(UINT16 wadnum, boolean PK3);
void HWR_SetViewSize(void);
void HWR_AddCommands(void); void HWR_AddCommands(void);
void HWR_CorrectSWTricks(void);
void transform(float *cx, float *cy, float *cz); // My original intention was to split hw_main.c
// into files like hw_bsp.c, hw_sprites.c...
// hw_main.c: Lighting and fog
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap);
UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap); // Let's see if this can work
FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf); FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf);
INT32 HWR_GetTextureUsed(void);
// hw_main.c: Post-rendering
void HWR_DoPostProcessor(player_t *player); void HWR_DoPostProcessor(player_t *player);
void HWR_StartScreenWipe(void); void HWR_StartScreenWipe(void);
void HWR_EndScreenWipe(void); void HWR_EndScreenWipe(void);
@ -67,24 +83,60 @@ void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum);
void HWR_MakeScreenFinalTexture(void); void HWR_MakeScreenFinalTexture(void);
void HWR_DrawScreenFinalTexture(int width, int height); void HWR_DrawScreenFinalTexture(int width, int height);
// This stuff is put here so MD2's can use them // hw_main.c: Planes
UINT32 HWR_Lighting(INT32 light, UINT32 color, UINT32 fadecolor, boolean fogblockpoly, boolean plane); void HWR_RenderPlane(extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap);
FUNCMATH UINT8 LightLevelToLum(INT32 l); void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap);
extern CV_PossibleValue_t granisotropicmode_cons_t[]; #ifdef POLYOBJECTS
#ifdef POLYOBJECTS_PLANES
#ifdef ALAM_LIGHTING void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap);
extern consvar_t cv_grdynamiclighting; void HWR_AddPolyObjectPlanes(void);
extern consvar_t cv_grstaticlighting; void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap);
extern consvar_t cv_grcoronas;
extern consvar_t cv_grcoronasize;
#endif #endif
#endif
// hw_main.c: Segs
void HWR_ProcessSeg(void); // Sort of like GLWall::Process in GZDoom
void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap);
void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blendmode, INT32 lightlevel, extracolormap_t *wallcolormap);
void HWR_AddTransparentWall(FOutVector *wallVerts, FSurfaceInfo * pSurf, INT32 texnum, FBITFIELD blend, boolean fogwall, INT32 lightlevel, extracolormap_t *wallcolormap);
void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor);
void HWR_DrawSkyWall(FOutVector *wallVerts, FSurfaceInfo *Surf);
void HWR_DrawSkyBackground(float fpov);
#ifdef POLYOBJECTS
void HWR_AddPolyObjectSegs(void);
#endif
// hw_main.c: BSP
void HWR_RenderBSPNode(INT32 bspnum);
void HWR_Subsector(size_t num);
void HWR_AddLine(seg_t *line);
boolean HWR_CheckBBox(fixed_t *bspcoord);
void HWR_RenderDrawNodes(void);
// hw_main.c: Sprites
void HWR_AddSprites(sector_t *sec);
void HWR_ProjectSprite(mobj_t *thing);
void HWR_ProjectPrecipitationSprite(precipmobj_t *thing);
void HWR_DrawSprites(void);
// hw_bsp.c
void HWR_CreatePlanePolygons(INT32 bspnum);
// hw_cache.c
void HWR_PrepLevelCache(size_t pnumtextures);
// hw_trick.c
void HWR_CorrectSWTricks(void);
// Console variables
extern consvar_t cv_grshaders;
extern consvar_t cv_grshearing;
extern consvar_t cv_grfov;
extern consvar_t cv_grmdls; extern consvar_t cv_grmdls;
extern consvar_t cv_grfallbackplayermodel;
extern consvar_t cv_grfog; extern consvar_t cv_grfog;
extern consvar_t cv_grfogcolor;
extern consvar_t cv_grfogdensity; extern consvar_t cv_grfogdensity;
extern consvar_t cv_grsoftwarefog;
extern consvar_t cv_grgammared; extern consvar_t cv_grgammared;
extern consvar_t cv_grgammagreen; extern consvar_t cv_grgammagreen;
extern consvar_t cv_grgammablue; extern consvar_t cv_grgammablue;
@ -94,22 +146,9 @@ extern consvar_t cv_grcorrecttricks;
extern consvar_t cv_grfovchange; extern consvar_t cv_grfovchange;
extern consvar_t cv_grsolvetjoin; extern consvar_t cv_grsolvetjoin;
extern consvar_t cv_grspritebillboarding; extern consvar_t cv_grspritebillboarding;
extern consvar_t cv_grfakecontrast;
extern consvar_t cv_grfallbackplayermodel;
extern float gr_viewwidth, gr_viewheight, gr_baseviewwindowx, gr_baseviewwindowy; extern CV_PossibleValue_t granisotropicmode_cons_t[];
extern float gr_basewindowcenterx, gr_basewindowcentery;
// BP: big hack for a test in lighting ref : 1249753487AB
extern fixed_t *hwbbox;
extern FTransform atransform;
typedef struct
{
wallVert3D floorVerts[4];
FSurfaceInfo Surf;
INT32 texnum;
INT32 blend;
INT32 drawcount;
} floorinfo_t;
#endif #endif

View file

@ -1,17 +1,12 @@
// Emacs style mode select -*- C++ -*- // SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// // Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2019 by Sonic Team Junior.
// //
// This program is free software; you can redistribute it and/or // This program is free software distributed under the
// modify it under the terms of the GNU General Public License // terms of the GNU General Public License, version 2.
// as published by the Free Software Foundation; either version 2 // See the 'LICENSE' file for more details.
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/// \file /// \file
/// \brief MD2 Handling /// \brief MD2 Handling
@ -90,7 +85,6 @@ static void md2_freeModel (model_t *model)
} }
#endif #endif
// //
// load model // load model
// //
@ -151,7 +145,7 @@ static void PNG_warn(png_structp PNG, png_const_charp pngtext)
CONS_Debug(DBG_RENDER, "libpng warning at %p: %s", PNG, pngtext); CONS_Debug(DBG_RENDER, "libpng warning at %p: %s", PNG, pngtext);
} }
static GrTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_t *grpatch) static GLTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_t *grpatch)
{ {
png_structp png_ptr; png_structp png_ptr;
png_infop png_info_ptr; png_infop png_info_ptr;
@ -205,7 +199,7 @@ static GrTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_
//CONS_Debug(DBG_RENDER, "libpng load error on %s\n", filename); //CONS_Debug(DBG_RENDER, "libpng load error on %s\n", filename);
png_destroy_read_struct(&png_ptr, &png_info_ptr, NULL); png_destroy_read_struct(&png_ptr, &png_info_ptr, NULL);
fclose(png_FILE); fclose(png_FILE);
Z_Free(grpatch->mipmap.grInfo.data); Z_Free(grpatch->mipmap->grInfo.data);
return 0; return 0;
} }
#ifdef USE_FAR_KEYWORD #ifdef USE_FAR_KEYWORD
@ -246,7 +240,7 @@ static GrTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_
{ {
png_uint_32 i, pitch = png_get_rowbytes(png_ptr, png_info_ptr); png_uint_32 i, pitch = png_get_rowbytes(png_ptr, png_info_ptr);
png_bytep PNG_image = Z_Malloc(pitch*height, PU_HWRCACHE, &grpatch->mipmap.grInfo.data); png_bytep PNG_image = Z_Malloc(pitch*height, PU_HWRCACHE, &grpatch->mipmap->grInfo.data);
png_bytepp row_pointers = png_malloc(png_ptr, height * sizeof (png_bytep)); png_bytepp row_pointers = png_malloc(png_ptr, height * sizeof (png_bytep));
for (i = 0; i < height; i++) for (i = 0; i < height; i++)
row_pointers[i] = PNG_image + i*pitch; row_pointers[i] = PNG_image + i*pitch;
@ -285,7 +279,7 @@ typedef struct
UINT8 filler[54]; UINT8 filler[54];
} PcxHeader; } PcxHeader;
static GrTextureFormat_t PCX_Load(const char *filename, int *w, int *h, static GLTextureFormat_t PCX_Load(const char *filename, int *w, int *h,
GLPatch_t *grpatch) GLPatch_t *grpatch)
{ {
PcxHeader header; PcxHeader header;
@ -326,7 +320,7 @@ static GrTextureFormat_t PCX_Load(const char *filename, int *w, int *h,
pw = *w = header.xmax - header.xmin + 1; pw = *w = header.xmax - header.xmin + 1;
ph = *h = header.ymax - header.ymin + 1; ph = *h = header.ymax - header.ymin + 1;
image = Z_Malloc(pw*ph*4, PU_HWRCACHE, &grpatch->mipmap.grInfo.data); image = Z_Malloc(pw*ph*4, PU_HWRCACHE, &grpatch->mipmap->grInfo.data);
if (fread(palette, sizeof (UINT8), PALSIZE, file) != PALSIZE) if (fread(palette, sizeof (UINT8), PALSIZE, file) != PALSIZE)
{ {
@ -374,37 +368,43 @@ static void md2_loadTexture(md2_t *model)
if (model->grpatch) if (model->grpatch)
{ {
grpatch = model->grpatch; grpatch = model->grpatch;
Z_Free(grpatch->mipmap.grInfo.data); Z_Free(grpatch->mipmap->grInfo.data);
} }
else else
{
grpatch = Z_Calloc(sizeof *grpatch, PU_HWRPATCHINFO, grpatch = Z_Calloc(sizeof *grpatch, PU_HWRPATCHINFO,
&(model->grpatch)); &(model->grpatch));
grpatch->mipmap = Z_Calloc(sizeof (GLMipmap_t), PU_HWRPATCHINFO, NULL);
}
if (!grpatch->mipmap.downloaded && !grpatch->mipmap.grInfo.data) if (!grpatch->mipmap->downloaded && !grpatch->mipmap->grInfo.data)
{ {
int w = 0, h = 0; int w = 0, h = 0;
#ifdef HAVE_PNG #ifdef HAVE_PNG
grpatch->mipmap.grInfo.format = PNG_Load(filename, &w, &h, grpatch); grpatch->mipmap->grInfo.format = PNG_Load(filename, &w, &h, grpatch);
if (grpatch->mipmap.grInfo.format == 0) if (grpatch->mipmap->grInfo.format == 0)
#endif #endif
grpatch->mipmap.grInfo.format = PCX_Load(filename, &w, &h, grpatch); grpatch->mipmap->grInfo.format = PCX_Load(filename, &w, &h, grpatch);
if (grpatch->mipmap.grInfo.format == 0) if (grpatch->mipmap->grInfo.format == 0)
{
grpatch->notfound = true;// mark it so its not searched for again repeatedly
return; return;
}
grpatch->mipmap.downloaded = 0; grpatch->mipmap->downloaded = 0;
grpatch->mipmap.flags = 0; grpatch->mipmap->flags = 0;
grpatch->width = (INT16)w; grpatch->width = (INT16)w;
grpatch->height = (INT16)h; grpatch->height = (INT16)h;
grpatch->mipmap.width = (UINT16)w; grpatch->mipmap->width = (UINT16)w;
grpatch->mipmap.height = (UINT16)h; grpatch->mipmap->height = (UINT16)h;
// not correct! // not correct!
grpatch->mipmap.grInfo.smallLodLog2 = GR_LOD_LOG2_256; grpatch->mipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_256;
grpatch->mipmap.grInfo.largeLodLog2 = GR_LOD_LOG2_256; grpatch->mipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_256;
grpatch->mipmap.grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; grpatch->mipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
} }
HWD.pfnSetTexture(&grpatch->mipmap); HWD.pfnSetTexture(grpatch->mipmap);
HWR_UnlockCachedPatch(grpatch); HWR_UnlockCachedPatch(grpatch);
} }
@ -422,40 +422,44 @@ static void md2_loadBlendTexture(md2_t *model)
if (model->blendgrpatch) if (model->blendgrpatch)
{ {
grpatch = model->blendgrpatch; grpatch = model->blendgrpatch;
Z_Free(grpatch->mipmap.grInfo.data); Z_Free(grpatch->mipmap->grInfo.data);
} }
else else
{
grpatch = Z_Calloc(sizeof *grpatch, PU_HWRPATCHINFO, grpatch = Z_Calloc(sizeof *grpatch, PU_HWRPATCHINFO,
&(model->blendgrpatch)); &(model->blendgrpatch));
grpatch->mipmap = Z_Calloc(sizeof (GLMipmap_t), PU_HWRPATCHINFO, NULL);
}
if (!grpatch->mipmap.downloaded && !grpatch->mipmap.grInfo.data) if (!grpatch->mipmap->downloaded && !grpatch->mipmap->grInfo.data)
{ {
int w = 0, h = 0; int w = 0, h = 0;
#ifdef HAVE_PNG #ifdef HAVE_PNG
grpatch->mipmap.grInfo.format = PNG_Load(filename, &w, &h, grpatch); grpatch->mipmap->grInfo.format = PNG_Load(filename, &w, &h, grpatch);
if (grpatch->mipmap.grInfo.format == 0) if (grpatch->mipmap->grInfo.format == 0)
#endif #endif
grpatch->mipmap.grInfo.format = PCX_Load(filename, &w, &h, grpatch); grpatch->mipmap->grInfo.format = PCX_Load(filename, &w, &h, grpatch);
if (grpatch->mipmap.grInfo.format == 0) if (grpatch->mipmap->grInfo.format == 0)
{ {
grpatch->notfound = true;// mark it so its not searched for again repeatedly
Z_Free(filename); Z_Free(filename);
return; return;
} }
grpatch->mipmap.downloaded = 0; grpatch->mipmap->downloaded = 0;
grpatch->mipmap.flags = 0; grpatch->mipmap->flags = 0;
grpatch->width = (INT16)w; grpatch->width = (INT16)w;
grpatch->height = (INT16)h; grpatch->height = (INT16)h;
grpatch->mipmap.width = (UINT16)w; grpatch->mipmap->width = (UINT16)w;
grpatch->mipmap.height = (UINT16)h; grpatch->mipmap->height = (UINT16)h;
// not correct! // not correct!
grpatch->mipmap.grInfo.smallLodLog2 = GR_LOD_LOG2_256; grpatch->mipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_256;
grpatch->mipmap.grInfo.largeLodLog2 = GR_LOD_LOG2_256; grpatch->mipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_256;
grpatch->mipmap.grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; grpatch->mipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
} }
HWD.pfnSetTexture(&grpatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary HWD.pfnSetTexture(grpatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary
HWR_UnlockCachedPatch(grpatch); HWR_UnlockCachedPatch(grpatch);
Z_Free(filename); Z_Free(filename);
@ -544,7 +548,7 @@ void HWR_InitMD2(void)
goto md2found; goto md2found;
} }
} }
// no sprite/player skin name found?!? // no sprite/player skin name found?!?D
CONS_Printf("Unknown sprite/player skin %s detected in mdls.dat\n", name); CONS_Printf("Unknown sprite/player skin %s detected in mdls.dat\n", name);
md2found: md2found:
// move on to next line... // move on to next line...
@ -579,7 +583,7 @@ void HWR_AddPlayerMD2(int skin) // For MD2's that were added after startup
} }
} }
// Check for any MD2s that match the names of player skins! // Check for any MD2s that match the names of sprite names!
while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4) while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4)
{ {
if (stricmp(name, skins[skin].name) == 0) if (stricmp(name, skins[skin].name) == 0)
@ -655,18 +659,26 @@ spritemd2found:
// 0.0722 to blue // 0.0722 to blue
// (See this same define in k_kart.c!) // (See this same define in k_kart.c!)
#define SETBRIGHTNESS(brightness,r,g,b) \ #define SETBRIGHTNESS(brightness,r,g,b) \
brightness = (UINT8)(((1063*((UINT16)r)/5000) + (3576*((UINT16)g)/5000) + (361*((UINT16)b)/5000)) / 3) brightness = (UINT8)(((1063*(UINT16)(r))/5000) + ((3576*(UINT16)(g))/5000) + ((361*(UINT16)(b))/5000))
static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, INT32 skinnum, skincolors_t color) static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, INT32 skinnum, skincolors_t color)
{ {
UINT8 i;
UINT16 w = gpatch->width, h = gpatch->height; UINT16 w = gpatch->width, h = gpatch->height;
UINT32 size = w*h; UINT32 size = w*h;
RGBA_t *image, *blendimage, *cur, blendcolor; RGBA_t *image, *blendimage, *cur, blendcolor;
UINT8 translation[16]; // First the color index
UINT8 cutoff[16]; // Brightness cutoff before using the next color
UINT8 translen = 0;
UINT8 i;
UINT8 colorbrightnesses[16];
UINT8 color_match_lookup[256]; // optimization attempt
blendcolor = V_GetColor(0); // initialize
memset(translation, 0, sizeof(translation));
memset(cutoff, 0, sizeof(cutoff));
if (grmip->width == 0) if (grmip->width == 0)
{ {
grmip->width = gpatch->width; grmip->width = gpatch->width;
grmip->height = gpatch->height; grmip->height = gpatch->height;
@ -676,110 +688,323 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
grmip->grInfo.format = GR_RGBA; grmip->grInfo.format = GR_RGBA;
} }
if (grmip->grInfo.data)
{
Z_Free(grmip->grInfo.data); Z_Free(grmip->grInfo.data);
grmip->grInfo.data = NULL; grmip->grInfo.data = NULL;
}
cur = Z_Malloc(size*4, PU_HWRCACHE, &grmip->grInfo.data); cur = Z_Malloc(size*4, PU_HWRCACHE, &grmip->grInfo.data);
memset(cur, 0x00, size*4); memset(cur, 0x00, size*4);
image = gpatch->mipmap.grInfo.data; image = gpatch->mipmap->grInfo.data;
blendimage = blendgpatch->mipmap.grInfo.data; blendimage = blendgpatch->mipmap->grInfo.data;
// Average all of the translation's colors // TC_METALSONIC includes an actual skincolor translation, on top of its flashing.
if (skinnum == TC_METALSONIC)
color = SKINCOLOR_BLUEBERRY;
if (color != SKINCOLOR_NONE)
{ {
const UINT8 div = 6; UINT8 numdupes = 1;
const UINT8 start = 4; UINT8 prevdupes = numdupes;
UINT32 r, g, b;
blendcolor = V_GetColor(colortranslations[color][start]); translation[translen] = colortranslations[color][0];
r = (UINT32)(blendcolor.s.red*blendcolor.s.red); cutoff[translen] = 255;
g = (UINT32)(blendcolor.s.green*blendcolor.s.green);
b = (UINT32)(blendcolor.s.blue*blendcolor.s.blue);
for (i = 1; i < div; i++) for (i = 1; i < 16; i++)
{ {
RGBA_t nextcolor = V_GetColor(colortranslations[color][start+i]); if (translation[translen] == colortranslations[color][i])
r += (UINT32)(nextcolor.s.red*nextcolor.s.red); {
g += (UINT32)(nextcolor.s.green*nextcolor.s.green); numdupes++;
b += (UINT32)(nextcolor.s.blue*nextcolor.s.blue); continue;
} }
blendcolor.s.red = (UINT8)(FixedSqrt((r/div)<<FRACBITS)>>FRACBITS); if (translen > 0)
blendcolor.s.green = (UINT8)(FixedSqrt((g/div)<<FRACBITS)>>FRACBITS); {
blendcolor.s.blue = (UINT8)(FixedSqrt((b/div)<<FRACBITS)>>FRACBITS); INT16 newcutoff = cutoff[translen-1] - (255 / (16 / prevdupes));
if (newcutoff < 0)
newcutoff = 0;
cutoff[translen] = (UINT8)newcutoff;
} }
// rainbow support, could theoretically support boss ones too prevdupes = numdupes;
if (skinnum == TC_RAINBOW) numdupes = 1;
translen++;
translation[translen] = (UINT8)colortranslations[color][i];
}
translen++;
}
if (skinnum == TC_RAINBOW && translen > 0)
{ {
UINT16 b;
INT32 compare;
for (i = 0; i < translen; i++) // moved from inside the loop to here
{
RGBA_t tempc = V_GetColor(translation[i]);
SETBRIGHTNESS(colorbrightnesses[i], tempc.s.red, tempc.s.green, tempc.s.blue); // store brightnesses for comparison
}
// generate lookup table for color brightness matching
for (b = 0; b < 256; b++)
{
UINT16 brightdif = 256;
color_match_lookup[i] = 0;
for (i = 0; i < translen; i++)
{
if (b > colorbrightnesses[i]) // don't allow greater matches (because calculating a makeshift gradient for this is already a huge mess as is)
continue;
compare = abs((INT16)(colorbrightnesses[i]) - (INT16)(b));
if (compare < brightdif)
{
brightdif = (UINT16)compare;
color_match_lookup[b] = i; // best matching color that's equal brightness or darker
}
}
}
}
while (size--) while (size--)
{
if (skinnum == TC_BOSS)
{
// Turn everything below a certain threshold white
if ((image->s.red == image->s.green) && (image->s.green == image->s.blue) && image->s.blue < 127)
{
// Lactozilla: Invert the colors
cur->s.red = cur->s.green = cur->s.blue = (255 - image->s.blue);
}
else
{
cur->s.red = image->s.red;
cur->s.green = image->s.green;
cur->s.blue = image->s.blue;
}
cur->s.alpha = image->s.alpha;
}
else if (skinnum == TC_ALLWHITE)
{
// Turn everything white
cur->s.red = cur->s.green = cur->s.blue = 255;
cur->s.alpha = image->s.alpha;
}
else
{
// All settings that use skincolors!
UINT16 brightness;
// Everything below requires a blend image
if (blendimage == NULL)
{
cur->rgba = image->rgba;
goto skippixel;
}
if (translen <= 0)
{
cur->rgba = image->rgba;
goto skippixel;
}
// Don't bother with blending the pixel if the alpha of the blend pixel is 0
if (skinnum == TC_RAINBOW)
{ {
if (image->s.alpha == 0 && blendimage->s.alpha == 0) if (image->s.alpha == 0 && blendimage->s.alpha == 0)
{ {
// Don't bother with blending the pixel if the alpha of the blend pixel is 0
cur->rgba = image->rgba; cur->rgba = image->rgba;
goto skippixel;
} }
else else
{ {
UINT32 tempcolor; UINT16 imagebright, blendbright;
UINT16 imagebright, blendbright, finalbright, colorbright;
SETBRIGHTNESS(imagebright,image->s.red,image->s.green,image->s.blue); SETBRIGHTNESS(imagebright,image->s.red,image->s.green,image->s.blue);
SETBRIGHTNESS(blendbright,blendimage->s.red,blendimage->s.green,blendimage->s.blue); SETBRIGHTNESS(blendbright,blendimage->s.red,blendimage->s.green,blendimage->s.blue);
// slightly dumb average between the blend image color and base image colour, usually one or the other will be fully opaque anyway // slightly dumb average between the blend image color and base image colour, usually one or the other will be fully opaque anyway
finalbright = (imagebright*(255-blendimage->s.alpha))/255 + (blendbright*blendimage->s.alpha)/255; brightness = (imagebright*(255-blendimage->s.alpha))/255 + (blendbright*blendimage->s.alpha)/255;
SETBRIGHTNESS(colorbright,blendcolor.s.red,blendcolor.s.green,blendcolor.s.blue);
tempcolor = (finalbright*blendcolor.s.red)/colorbright;
tempcolor = min(255, tempcolor);
cur->s.red = (UINT8)tempcolor;
tempcolor = (finalbright*blendcolor.s.green)/colorbright;
tempcolor = min(255, tempcolor);
cur->s.green = (UINT8)tempcolor;
tempcolor = (finalbright*blendcolor.s.blue)/colorbright;
tempcolor = min(255, tempcolor);
cur->s.blue = (UINT8)tempcolor;
cur->s.alpha = image->s.alpha;
}
cur++; image++; blendimage++;
} }
} }
else else
{
while (size--)
{ {
if (blendimage->s.alpha == 0) if (blendimage->s.alpha == 0)
{ {
// Don't bother with blending the pixel if the alpha of the blend pixel is 0
cur->rgba = image->rgba; cur->rgba = image->rgba;
goto skippixel; // for metal sonic blend
} }
else else
{ {
INT32 tempcolor; SETBRIGHTNESS(brightness,blendimage->s.red,blendimage->s.green,blendimage->s.blue);
INT16 tempmult, tempalpha; }
tempalpha = -(abs(blendimage->s.red-127)-127)*2; }
if (tempalpha > 255)
tempalpha = 255;
else if (tempalpha < 0)
tempalpha = 0;
tempmult = (blendimage->s.red-127)*2; // Calculate a sort of "gradient" for the skincolor
if (tempmult > 255) // (Me splitting this into a function didn't work, so I had to ruin this entire function's groove...)
tempmult = 255; {
else if (tempmult < 0) RGBA_t nextcolor;
tempmult = 0; UINT8 firsti, secondi, mul, mulmax;
INT32 r, g, b;
tempcolor = (image->s.red*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.red)/255)) * blendimage->s.alpha)/255; // Rainbow needs to find the closest match to the textures themselves, instead of matching brightnesses to other colors.
// Ensue horrible mess.
if (skinnum == TC_RAINBOW)
{
//UINT16 brightdif = 256;
INT32 /*compare,*/ m, d;
// Ignore pure white & pitch black
if (brightness > 253 || brightness < 2)
{
cur->rgba = image->rgba;
cur++; image++; blendimage++;
continue;
}
firsti = 0;
mul = 0;
mulmax = 1;
/*for (i = 0; i < translen; i++)
{
if (brightness > colorbrightnesses[i]) // don't allow greater matches (because calculating a makeshift gradient for this is already a huge mess as is)
continue;
compare = abs((INT16)(colorbrightnesses[i]) - (INT16)(brightness));
if (compare < brightdif)
{
brightdif = (UINT16)compare;
firsti = i; // best matching color that's equal brightness or darker
}
}*/
firsti = color_match_lookup[brightness];
secondi = firsti+1; // next color in line
m = (INT16)brightness - (INT16)colorbrightnesses[secondi];
d = (INT16)colorbrightnesses[firsti] - (INT16)colorbrightnesses[secondi];
if (m >= d)
m = d-1;
mulmax = 16;
// calculate the "gradient" multiplier based on how close this color is to the one next in line
if (m <= 0 || d <= 0)
mul = 0;
else
mul = (mulmax-1) - ((m * mulmax) / d);
}
else
{
// Just convert brightness to a skincolor value, use distance to next position to find the gradient multipler
firsti = 0;
for (i = 1; i < translen; i++)
{
if (brightness >= cutoff[i])
break;
firsti = i;
}
secondi = firsti+1;
mulmax = cutoff[firsti] - cutoff[secondi];
mul = cutoff[firsti] - brightness;
}
blendcolor = V_GetColor(translation[firsti]);
if (mul > 0) // If it's 0, then we only need the first color.
{
nextcolor = V_GetColor(translation[secondi]);
// Find difference between points
r = (INT32)(nextcolor.s.red - blendcolor.s.red);
g = (INT32)(nextcolor.s.green - blendcolor.s.green);
b = (INT32)(nextcolor.s.blue - blendcolor.s.blue);
// Find the gradient of the two points
r = ((mul * r) / mulmax);
g = ((mul * g) / mulmax);
b = ((mul * b) / mulmax);
// Add gradient value to color
blendcolor.s.red += r;
blendcolor.s.green += g;
blendcolor.s.blue += b;
}
}
if (skinnum == TC_RAINBOW)
{
UINT32 tempcolor;
UINT16 colorbright;
SETBRIGHTNESS(colorbright,blendcolor.s.red,blendcolor.s.green,blendcolor.s.blue);
if (colorbright == 0)
colorbright = 1; // no dividing by 0 please
tempcolor = (brightness * blendcolor.s.red) / colorbright;
tempcolor = min(255, tempcolor);
cur->s.red = (UINT8)tempcolor; cur->s.red = (UINT8)tempcolor;
tempcolor = (image->s.green*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.green)/255)) * blendimage->s.alpha)/255;
tempcolor = (brightness * blendcolor.s.green) / colorbright;
tempcolor = min(255, tempcolor);
cur->s.green = (UINT8)tempcolor; cur->s.green = (UINT8)tempcolor;
tempcolor = (image->s.blue*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.blue)/255)) * blendimage->s.alpha)/255;
tempcolor = (brightness * blendcolor.s.blue) / colorbright;
tempcolor = min(255, tempcolor);
cur->s.blue = (UINT8)tempcolor;
cur->s.alpha = image->s.alpha;
}
else
{
// Color strength depends on image alpha
INT32 tempcolor;
tempcolor = ((image->s.red * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.red * blendimage->s.alpha) / 255);
tempcolor = min(255, tempcolor);
cur->s.red = (UINT8)tempcolor;
tempcolor = ((image->s.green * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.green * blendimage->s.alpha) / 255);
tempcolor = min(255, tempcolor);
cur->s.green = (UINT8)tempcolor;
tempcolor = ((image->s.blue * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.blue * blendimage->s.alpha) / 255);
tempcolor = min(255, tempcolor);
cur->s.blue = (UINT8)tempcolor; cur->s.blue = (UINT8)tempcolor;
cur->s.alpha = image->s.alpha; cur->s.alpha = image->s.alpha;
} }
cur++; image++; blendimage++; skippixel:
// *Now* we can do Metal Sonic's flashing
if (skinnum == TC_METALSONIC)
{
// Blend dark blue into white
if (cur->s.alpha > 0 && cur->s.red == 0 && cur->s.green == 0 && cur->s.blue < 255 && cur->s.blue > 31)
{
// Sal: Invert non-blue
cur->s.red = cur->s.green = (255 - cur->s.blue);
cur->s.blue = 255;
} }
cur->s.alpha = image->s.alpha;
}
}
cur++; image++;
if (blendimage != NULL)
blendimage++;
} }
return; return;
@ -795,13 +1020,13 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT
if (colormap == colormaps || colormap == NULL) if (colormap == colormaps || colormap == NULL)
{ {
// Don't do any blending // Don't do any blending
HWD.pfnSetTexture(&gpatch->mipmap); HWD.pfnSetTexture(gpatch->mipmap);
return; return;
} }
// search for the mimmap // search for the mimmap
// skip the first (no colormap translated) // skip the first (no colormap translated)
for (grmip = &gpatch->mipmap; grmip->nextcolormap; ) for (grmip = gpatch->mipmap; grmip->nextcolormap; )
{ {
grmip = grmip->nextcolormap; grmip = grmip->nextcolormap;
if (grmip->colormap == colormap) if (grmip->colormap == colormap)
@ -837,35 +1062,19 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT
// -----------------+ // -----------------+
// HWR_DrawMD2 : Draw MD2 // HWR_DrawMD2 : Draw MD2
// : (monsters, bonuses, weapons, lights, ...) // :
// Returns : // Returns :
// -----------------+ // -----------------+
/*
wait/stand
death
pain
walk
shoot/fire
die?
atka?
atkb?
attacka/b/c/d?
res?
run?
*/
#define NORMALFOG 0x00000000
#define FADEFOG 0x19000000
void HWR_DrawMD2(gr_vissprite_t *spr) void HWR_DrawMD2(gr_vissprite_t *spr)
{ {
FSurfaceInfo Surf; md2_t *md2;
char filename[64]; char filename[64];
INT32 frame = 0; INT32 frame = 0;
INT32 nextFrame = -1; INT32 nextFrame = -1;
FTransform p; FTransform p;
md2_t *md2; FSurfaceInfo Surf;
UINT8 color[4];
if (!cv_grmdls.value) if (!cv_grmdls.value)
return; return;
@ -878,8 +1087,8 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
if (spr->mobj->subsector) if (spr->mobj->subsector)
{ {
sector_t *sector = spr->mobj->subsector->sector; sector_t *sector = spr->mobj->subsector->sector;
UINT8 lightlevel = 255;
extracolormap_t *colormap = sector->extra_colormap; extracolormap_t *colormap = sector->extra_colormap;
UINT8 lightlevel = 255;
if (sector->numlights) if (sector->numlights)
{ {
@ -902,14 +1111,11 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
colormap = sector->extra_colormap; colormap = sector->extra_colormap;
} }
if (colormap) HWR_Lighting(&Surf, lightlevel, colormap);
Surf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false);
else
Surf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false);
} }
else else
{ {
Surf.FlatColor.rgba = 0xFFFFFFFF; Surf.PolyColor.rgba = 0xFFFFFFFF;
} }
// Look at HWR_ProjectSprite for more // Look at HWR_ProjectSprite for more
@ -928,11 +1134,11 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
//durs = tics; //durs = tics;
if (spr->mobj->flags2 & MF2_SHADOW) if (spr->mobj->flags2 & MF2_SHADOW)
Surf.FlatColor.s.alpha = 0x40; Surf.PolyColor.s.alpha = 0x40;
else if (spr->mobj->frame & FF_TRANSMASK) else if (spr->mobj->frame & FF_TRANSMASK)
HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf); HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
else else
Surf.FlatColor.s.alpha = 0xFF; Surf.PolyColor.s.alpha = 0xFF;
// dont forget to enabled the depth test because we can't do this like // dont forget to enabled the depth test because we can't do this like
// before: polygons models are not sorted // before: polygons models are not sorted
@ -967,22 +1173,23 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
return; return;
} }
} }
//HWD.pfnSetBlend(blend); // This seems to actually break translucency?
finalscale = md2->scale; finalscale = md2->scale;
//Hurdler: arf, I don't like that implementation at all... too much crappy //Hurdler: arf, I don't like that implementation at all... too much crappy
gpatch = md2->grpatch; gpatch = md2->grpatch;
if (!gpatch || !gpatch->mipmap.grInfo.format || !gpatch->mipmap.downloaded) if (!gpatch || ((!gpatch->mipmap->grInfo.format || !gpatch->mipmap->downloaded) && !gpatch->notfound))
md2_loadTexture(md2); md2_loadTexture(md2);
gpatch = md2->grpatch; // Load it again, because it isn't being loaded into gpatch after md2_loadtexture... gpatch = md2->grpatch; // Load it again, because it isn't being loaded into gpatch after md2_loadtexture...
if ((gpatch && gpatch->mipmap.grInfo.format) // don't load the blend texture if the base texture isn't available if ((gpatch && gpatch->mipmap->grInfo.format) // don't load the blend texture if the base texture isn't available
&& (!md2->blendgrpatch || !((GLPatch_t *)md2->blendgrpatch)->mipmap.grInfo.format || !((GLPatch_t *)md2->blendgrpatch)->mipmap.downloaded)) && (!md2->blendgrpatch
|| ((!((GLPatch_t *)md2->blendgrpatch)->mipmap->grInfo.format || !((GLPatch_t *)md2->blendgrpatch)->mipmap->downloaded)
&& !((GLPatch_t *)md2->blendgrpatch)->notfound)))
md2_loadBlendTexture(md2); md2_loadBlendTexture(md2);
if (gpatch && gpatch->mipmap.grInfo.format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture if (gpatch && gpatch->mipmap->grInfo.format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture
{ {
if ((skincolors_t)spr->mobj->color != SKINCOLOR_NONE && if ((skincolors_t)spr->mobj->color != SKINCOLOR_NONE &&
md2->blendgrpatch && ((GLPatch_t *)md2->blendgrpatch)->mipmap.grInfo.format md2->blendgrpatch && ((GLPatch_t *)md2->blendgrpatch)->mipmap->grInfo.format
&& gpatch->width == ((GLPatch_t *)md2->blendgrpatch)->width && gpatch->height == ((GLPatch_t *)md2->blendgrpatch)->height) && gpatch->width == ((GLPatch_t *)md2->blendgrpatch)->width && gpatch->height == ((GLPatch_t *)md2->blendgrpatch)->height)
{ {
INT32 skinnum = TC_DEFAULT; INT32 skinnum = TC_DEFAULT;
@ -1013,7 +1220,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
else else
{ {
// This is safe, since we know the texture has been downloaded // This is safe, since we know the texture has been downloaded
HWD.pfnSetTexture(&gpatch->mipmap); HWD.pfnSetTexture(gpatch->mipmap);
} }
} }
else else
@ -1103,11 +1310,6 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
} }
#endif #endif
color[0] = Surf.FlatColor.s.red;
color[1] = Surf.FlatColor.s.green;
color[2] = Surf.FlatColor.s.blue;
color[3] = Surf.FlatColor.s.alpha;
// SRB2CBTODO: MD2 scaling support // SRB2CBTODO: MD2 scaling support
finalscale *= FIXED_TO_FLOAT(spr->mobj->scale); finalscale *= FIXED_TO_FLOAT(spr->mobj->scale);
@ -1116,7 +1318,8 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
p.mirror = atransform.mirror; // from Kart p.mirror = atransform.mirror; // from Kart
#endif #endif
HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, color); HWD.pfnSetShader(4); // model shader
HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, &Surf);
} }
} }

View file

@ -1,18 +1,12 @@
// Emacs style mode select -*- C++ -*- // SONIC ROBO BLAST 2
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// // Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team. // Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2019 by Sonic Team Junior.
// //
// This program is free software; you can redistribute it and/or // This program is free software distributed under the
// modify it under the terms of the GNU General Public License // terms of the GNU General Public License, version 2.
// as published by the Free Software Foundation; either version 2 // See the 'LICENSE' file for more details.
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
/// \file /// \file
/// \brief MD2 Handling /// \brief MD2 Handling

View file

@ -44,6 +44,7 @@
#include "../doomstat.h" #include "../doomstat.h"
#ifdef HWRENDER #ifdef HWRENDER
#include "hw_main.h"
#include "hw_glob.h" #include "hw_glob.h"
#include "hw_dll.h" #include "hw_dll.h"
#include "../r_local.h" #include "../r_local.h"

File diff suppressed because it is too large Load diff

View file

@ -57,23 +57,10 @@
#undef DEBUG_TO_FILE // maybe defined in previous *.h #undef DEBUG_TO_FILE // maybe defined in previous *.h
#define DEBUG_TO_FILE // output debugging msgs to ogllog.txt #define DEBUG_TO_FILE // output debugging msgs to ogllog.txt
// todo: find some way of getting SDL to log to ogllog.txt, without
// interfering with r_opengl.dll
#ifdef HAVE_SDL
#undef DEBUG_TO_FILE
#endif
//#if defined(HAVE_SDL) && !defined(_DEBUG)
//#undef DEBUG_TO_FILE
//#endif
#ifdef DEBUG_TO_FILE #ifdef DEBUG_TO_FILE
extern FILE *gllogstream; extern FILE *gllogstream;
#endif #endif
#ifndef DRIVER_STRING
#define DRIVER_STRING "HWRAPI Init(): SRB2Kart OpenGL renderer" // Tails
#endif
// ========================================================================== // ==========================================================================
// PROTOS // PROTOS
// ========================================================================== // ==========================================================================
@ -81,13 +68,15 @@ extern FILE *gllogstream;
boolean LoadGL(void); boolean LoadGL(void);
void *GetGLFunc(const char *proc); void *GetGLFunc(const char *proc);
boolean SetupGLfunc(void); boolean SetupGLfunc(void);
boolean SetupGLFunc13(void); void SetupGLFunc4(void);
void Flush(void); void Flush(void);
INT32 isExtAvailable(const char *extension, const GLubyte *start); INT32 isExtAvailable(const char *extension, const GLubyte *start);
int SetupPixelFormat(INT32 WantColorBits, INT32 WantStencilBits, INT32 WantDepthBits);
void SetModelView(GLint w, GLint h); void SetModelView(GLint w, GLint h);
void SetStates(void); void SetStates(void);
FUNCMATH float byteasfloat(UINT8 fbyte); #ifdef USE_PALETTED_TEXTURE
extern PFNGLCOLORTABLEEXTPROC glColorTableEXT;
extern GLubyte palette_tex[256*3];
#endif
#ifndef GL_EXT_texture_filter_anisotropic #ifndef GL_EXT_texture_filter_anisotropic
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
@ -123,7 +112,10 @@ static PFNglEnableClientState pglEnableClientState;
// GLOBAL // GLOBAL
// ========================================================================== // ==========================================================================
extern const GLubyte *gl_version;
extern const GLubyte *gl_renderer;
extern const GLubyte *gl_extensions; extern const GLubyte *gl_extensions;
extern RGBA_t myPaletteData[]; extern RGBA_t myPaletteData[];
extern GLint screen_width; extern GLint screen_width;
extern GLint screen_height; extern GLint screen_height;

View file

@ -1482,7 +1482,7 @@ static void HU_drawMiniChat(void)
for (; i>0; i--) for (; i>0; i--)
{ {
const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]); char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]);
size_t j = 0; size_t j = 0;
INT32 linescount = 0; INT32 linescount = 0;
@ -1524,6 +1524,8 @@ static void HU_drawMiniChat(void)
dy = 0; dy = 0;
dx = 0; dx = 0;
msglines += linescount+1; msglines += linescount+1;
if (msg)
Z_Free(msg);
} }
y = chaty - charheight*(msglines+1); y = chaty - charheight*(msglines+1);
@ -1550,7 +1552,7 @@ static void HU_drawMiniChat(void)
INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below... INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below...
INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one. INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one.
size_t j = 0; size_t j = 0;
const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it. char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
UINT8 *colormap = NULL; UINT8 *colormap = NULL;
while(msg[j]) // iterate through msg while(msg[j]) // iterate through msg
@ -1596,6 +1598,8 @@ static void HU_drawMiniChat(void)
} }
dy += charheight; dy += charheight;
dx = 0; dx = 0;
if (msg)
Z_Free(msg);
} }
// decrement addy and make that shit smooth: // decrement addy and make that shit smooth:
@ -1651,7 +1655,7 @@ static void HU_drawChatLog(INT32 offset)
{ {
INT32 clrflag = 0; INT32 clrflag = 0;
INT32 j = 0; INT32 j = 0;
const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it. char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
UINT8 *colormap = NULL; UINT8 *colormap = NULL;
while(msg[j]) // iterate through msg while(msg[j]) // iterate through msg
{ {
@ -1691,6 +1695,8 @@ static void HU_drawChatLog(INT32 offset)
} }
dy += charheight; dy += charheight;
dx = 0; dx = 0;
if (msg)
Z_Free(msg);
} }

View file

@ -74,10 +74,10 @@ static int inet_aton(const char *cp, struct in_addr *addr)
#ifdef USE_WINSOCK2 #ifdef USE_WINSOCK2
static HMODULE ipv6dll = NULL; static HMODULE ipv6dll = NULL;
typedef int (WSAAPI *p_getaddrinfo) (const char *node, const char *service, typedef int (WSAAPI *p_getaddrinfo) (const char *, const char *,
const struct my_addrinfo *hints, const struct my_addrinfo *,
struct my_addrinfo **res); struct my_addrinfo **);
typedef void (WSAAPI *p_freeaddrinfo) (struct my_addrinfo *res); typedef void (WSAAPI *p_freeaddrinfo) (struct my_addrinfo *);
static p_getaddrinfo WS_getaddrinfo = NULL; static p_getaddrinfo WS_getaddrinfo = NULL;
static p_freeaddrinfo WS_freeaddrinfo = NULL; static p_freeaddrinfo WS_freeaddrinfo = NULL;
@ -86,10 +86,10 @@ static HMODULE WS_getfunctions(HMODULE tmp)
{ {
if (tmp != NULL) if (tmp != NULL)
{ {
WS_getaddrinfo = (p_getaddrinfo)((void *)GetProcAddress(tmp, "getaddrinfo")); WS_getaddrinfo = (p_getaddrinfo)(LPVOID)GetProcAddress(tmp, "getaddrinfo");
if (WS_getaddrinfo == NULL) if (WS_getaddrinfo == NULL)
return NULL; return NULL;
WS_freeaddrinfo = (p_freeaddrinfo)((void *)GetProcAddress(tmp, "freeaddrinfo")); WS_freeaddrinfo = (p_freeaddrinfo)(LPVOID)GetProcAddress(tmp, "freeaddrinfo");
if (WS_freeaddrinfo == NULL) if (WS_freeaddrinfo == NULL)
{ {
WS_getaddrinfo = NULL; WS_getaddrinfo = NULL;

View file

@ -226,10 +226,6 @@ void I_StartupMouse(void);
*/ */
void I_StartupMouse2(void); void I_StartupMouse2(void);
/** \brief keyboard startup, shutdown, handler
*/
void I_StartupKeyboard(void);
/** \brief setup timer irq and user timer routine. /** \brief setup timer irq and user timer routine.
*/ */
void I_StartupTimer(void); void I_StartupTimer(void);

View file

@ -20,9 +20,6 @@
#include "z_zone.h" #include "z_zone.h"
#include "d_player.h" #include "d_player.h"
#include "lzf.h" #include "lzf.h"
#ifdef HWRENDER
#include "hardware/hw_light.h"
#endif
// Hey, moron! If you change this table, don't forget about the sprite enum in info.h and the sprite lights in hw_light.c! // Hey, moron! If you change this table, don't forget about the sprite enum in info.h and the sprite lights in hw_light.c!
char sprnames[NUMSPRITES + 1][5] = char sprnames[NUMSPRITES + 1][5] =
@ -20101,7 +20098,7 @@ void P_PatchInfoTables(void)
char *tempname; char *tempname;
#if NUMSPRITEFREESLOTS > 1000 #if NUMSPRITEFREESLOTS > 1000
"Update P_PatchInfoTables, you big dumb head" #error "Update P_PatchInfoTables, you big dumb head"
#endif #endif
// empty out free slots // empty out free slots
@ -20113,9 +20110,6 @@ void P_PatchInfoTables(void)
tempname[2] = (char)('0' + (char)(((i-SPR_FIRSTFREESLOT+1)/10)%10)); tempname[2] = (char)('0' + (char)(((i-SPR_FIRSTFREESLOT+1)/10)%10));
tempname[3] = (char)('0' + (char)((i-SPR_FIRSTFREESLOT+1)%10)); tempname[3] = (char)('0' + (char)((i-SPR_FIRSTFREESLOT+1)%10));
tempname[4] = '\0'; tempname[4] = '\0';
#ifdef HWRENDER
t_lspr[i] = &lspr[NOLIGHT];
#endif
} }
sprnames[i][0] = '\0'; // i == NUMSPRITES sprnames[i][0] = '\0'; // i == NUMSPRITES
memset(&states[S_FIRSTFREESLOT], 0, sizeof (state_t) * NUMSTATEFREESLOTS); memset(&states[S_FIRSTFREESLOT], 0, sizeof (state_t) * NUMSTATEFREESLOTS);

View file

@ -226,7 +226,7 @@ void A_NapalmScatter();
void A_SpawnFreshCopy(); void A_SpawnFreshCopy();
// ratio of states to sprites to mobj types is roughly 6 : 1 : 1 // ratio of states to sprites to mobj types is roughly 6 : 1 : 1
#define NUMMOBJFREESLOTS 256 #define NUMMOBJFREESLOTS 512
#define NUMSPRITEFREESLOTS NUMMOBJFREESLOTS #define NUMSPRITEFREESLOTS NUMMOBJFREESLOTS
#define NUMSTATEFREESLOTS (NUMMOBJFREESLOTS*8) #define NUMSTATEFREESLOTS (NUMMOBJFREESLOTS*8)
@ -4301,7 +4301,7 @@ typedef enum mobj_type
// Castle Eggman Scenery // Castle Eggman Scenery
MT_CHAIN, // CEZ Chain MT_CHAIN, // CEZ Chain
MT_FLAME, // Flame (has corona) MT_FLAME, // Flame
MT_EGGSTATUE, // Eggman Statue MT_EGGSTATUE, // Eggman Statue
MT_MACEPOINT, // Mace rotation point MT_MACEPOINT, // Mace rotation point
MT_SWINGMACEPOINT, // Mace swinging point MT_SWINGMACEPOINT, // Mace swinging point

View file

@ -409,7 +409,7 @@ UINT8 colortranslations[MAXTRANSLATIONS][16] = {
// 0.0722 to blue // 0.0722 to blue
// (See this same define in hw_md2.c!) // (See this same define in hw_md2.c!)
#define SETBRIGHTNESS(brightness,r,g,b) \ #define SETBRIGHTNESS(brightness,r,g,b) \
brightness = (UINT8)(((1063*((UINT16)r)/5000) + (3576*((UINT16)g)/5000) + (361*((UINT16)b)/5000)) / 3) brightness = (UINT8)(((1063*(UINT16)(r))/5000) + ((3576*(UINT16)(g))/5000) + ((361*(UINT16)(b))/5000))
/** \brief Generates the rainbow colourmaps that are used when a player has the invincibility power /** \brief Generates the rainbow colourmaps that are used when a player has the invincibility power
@ -1062,7 +1062,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
} }
// This makes the roulette produce the random noises. // This makes the roulette produce the random noises.
if ((player->kartstuff[k_itemroulette] % 3) == 1 && P_IsDisplayPlayer(player)) if ((player->kartstuff[k_itemroulette] % 3) == 1 && P_IsDisplayPlayer(player) && !demo.freecam)
{ {
#define PLAYROULETTESND S_StartSound(NULL, sfx_itrol1 + ((player->kartstuff[k_itemroulette] / 3) % 8)) #define PLAYROULETTESND S_StartSound(NULL, sfx_itrol1 + ((player->kartstuff[k_itemroulette] / 3) % 8))
for (i = 0; i <= splitscreen; i++) for (i = 0; i <= splitscreen; i++)
@ -1096,7 +1096,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
//player->kartstuff[k_itemblinkmode] = 1; //player->kartstuff[k_itemblinkmode] = 1;
player->kartstuff[k_itemroulette] = 0; player->kartstuff[k_itemroulette] = 0;
player->kartstuff[k_roulettetype] = 0; player->kartstuff[k_roulettetype] = 0;
if (P_IsDisplayPlayer(player)) if (P_IsDisplayPlayer(player) && !demo.freecam)
S_StartSound(NULL, sfx_itrole); S_StartSound(NULL, sfx_itrole);
return; return;
} }
@ -1109,7 +1109,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
player->kartstuff[k_itemblinkmode] = 2; player->kartstuff[k_itemblinkmode] = 2;
player->kartstuff[k_itemroulette] = 0; player->kartstuff[k_itemroulette] = 0;
player->kartstuff[k_roulettetype] = 0; player->kartstuff[k_roulettetype] = 0;
if (P_IsDisplayPlayer(player)) if (P_IsDisplayPlayer(player) && !demo.freecam)
S_StartSound(NULL, sfx_dbgsal); S_StartSound(NULL, sfx_dbgsal);
return; return;
} }
@ -1141,7 +1141,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
player->kartstuff[k_itemamount] = 1; player->kartstuff[k_itemamount] = 1;
} }
if (P_IsDisplayPlayer(player)) if (P_IsDisplayPlayer(player) && !demo.freecam)
S_StartSound(NULL, ((player->kartstuff[k_roulettetype] == 1) ? sfx_itrolk : (mashed ? sfx_itrolm : sfx_itrolf))); S_StartSound(NULL, ((player->kartstuff[k_roulettetype] == 1) ? sfx_itrolk : (mashed ? sfx_itrolm : sfx_itrolf)));
player->kartstuff[k_itemblink] = TICRATE; player->kartstuff[k_itemblink] = TICRATE;
@ -3159,11 +3159,11 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map
if (dir == -1) if (dir == -1)
{ {
// Shoot backward // Shoot backward
mo = K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + ANGLE_180 - 0x06000000, 0, PROJSPEED/4); mo = K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + ANGLE_180 - 0x06000000, 0, PROJSPEED/16);
K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + ANGLE_180 - 0x03000000, 0, PROJSPEED/4); K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + ANGLE_180 - 0x03000000, 0, PROJSPEED/16);
K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + ANGLE_180, 0, PROJSPEED/4); K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + ANGLE_180, 0, PROJSPEED/16);
K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + ANGLE_180 + 0x03000000, 0, PROJSPEED/4); K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + ANGLE_180 + 0x03000000, 0, PROJSPEED/16);
K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + ANGLE_180 + 0x06000000, 0, PROJSPEED/4); K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + ANGLE_180 + 0x06000000, 0, PROJSPEED/16);
} }
else else
{ {
@ -3180,7 +3180,7 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map
if (dir == -1 && mapthing != MT_SPB) if (dir == -1 && mapthing != MT_SPB)
{ {
// Shoot backward // Shoot backward
mo = K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + ANGLE_180, 0, PROJSPEED/2); mo = K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + ANGLE_180, 0, PROJSPEED/8);
} }
else else
{ {
@ -8750,6 +8750,7 @@ void K_drawKartHUD(void)
{ {
boolean isfreeplay = false; boolean isfreeplay = false;
boolean battlefullscreen = false; boolean battlefullscreen = false;
boolean freecam = demo.freecam; //disable some hud elements w/ freecam
UINT8 i; UINT8 i;
// Define the X and Y for each drawn object // Define the X and Y for each drawn object
@ -8759,7 +8760,7 @@ void K_drawKartHUD(void)
// Draw that fun first person HUD! Drawn ASAP so it looks more "real". // Draw that fun first person HUD! Drawn ASAP so it looks more "real".
for (i = 0; i <= splitscreen; i++) for (i = 0; i <= splitscreen; i++)
{ {
if (stplyr == &players[displayplayers[i]] && !camera[i].chase) if (stplyr == &players[displayplayers[i]] && !camera[i].chase && !freecam)
K_drawKartFirstPerson(); K_drawKartFirstPerson();
} }
@ -8780,7 +8781,10 @@ void K_drawKartHUD(void)
if (!demo.title && (!battlefullscreen || splitscreen)) if (!demo.title && (!battlefullscreen || splitscreen))
{ {
// Draw the CHECK indicator before the other items, so it's overlapped by everything else // Draw the CHECK indicator before the other items, so it's overlapped by everything else
if (cv_kartcheck.value && !splitscreen && !players[displayplayers[0]].exiting) #ifdef HAVE_BLUA
if (LUA_HudEnabled(hud_check)) // delete lua when?
#endif
if (cv_kartcheck.value && !splitscreen && !players[displayplayers[0]].exiting && !freecam)
K_drawKartPlayerCheck(); K_drawKartPlayerCheck();
// Draw WANTED status // Draw WANTED status
@ -8801,7 +8805,7 @@ void K_drawKartHUD(void)
} }
} }
if (battlefullscreen) if (battlefullscreen && !freecam)
{ {
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
if (LUA_HudEnabled(hud_battlefullscreen)) if (LUA_HudEnabled(hud_battlefullscreen))
@ -8812,7 +8816,7 @@ void K_drawKartHUD(void)
// Draw the item window // Draw the item window
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
if (LUA_HudEnabled(hud_item)) if (LUA_HudEnabled(hud_item) && !freecam)
#endif #endif
K_drawKartItem(); K_drawKartItem();
@ -8835,7 +8839,7 @@ void K_drawKartHUD(void)
} }
} }
if (!stplyr->spectator) // Bottom of the screen elements, don't need in spectate mode if (!stplyr->spectator && !demo.freecam) // Bottom of the screen elements, don't need in spectate mode
{ {
if (demo.title) // Draw title logo instead in demo.titles if (demo.title) // Draw title logo instead in demo.titles
{ {
@ -8910,9 +8914,9 @@ void K_drawKartHUD(void)
if (leveltime >= starttime-(3*TICRATE) if (leveltime >= starttime-(3*TICRATE)
&& leveltime < starttime+TICRATE) && leveltime < starttime+TICRATE)
K_drawKartStartCountdown(); K_drawKartStartCountdown();
else if (countdown && (!splitscreen || !stplyr->exiting)) else if (racecountdown && (!splitscreen || !stplyr->exiting))
{ {
char *countstr = va("%d", countdown/TICRATE); char *countstr = va("%d", racecountdown/TICRATE);
if (splitscreen > 1) if (splitscreen > 1)
V_DrawCenteredString(BASEVIDWIDTH/4, LAPS_Y+1, K_calcSplitFlags(0), countstr); V_DrawCenteredString(BASEVIDWIDTH/4, LAPS_Y+1, K_calcSplitFlags(0), countstr);
@ -8924,7 +8928,7 @@ void K_drawKartHUD(void)
} }
// Race overlays // Race overlays
if (G_RaceGametype()) if (G_RaceGametype() && !freecam)
{ {
if (stplyr->exiting) if (stplyr->exiting)
K_drawKartFinish(); K_drawKartFinish();
@ -8932,7 +8936,7 @@ void K_drawKartHUD(void)
K_drawLapStartAnim(); K_drawLapStartAnim();
} }
if (modeattacking) // everything after here is MP and debug only if (modeattacking || freecam) // everything after here is MP and debug only
return; return;
if (G_BattleGametype() && !splitscreen && (stplyr->kartstuff[k_yougotem] % 2)) // * YOU GOT EM * if (G_BattleGametype() && !splitscreen && (stplyr->kartstuff[k_yougotem] % 2)) // * YOU GOT EM *

View file

@ -774,11 +774,14 @@ static int lib_pRestoreMusic(lua_State *L)
{ {
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD NOHUD
if (!player) if (!player || P_IsLocalPlayer(player))
return LUA_ErrInvalid(L, "player_t"); {
if (P_IsLocalPlayer(player))
P_RestoreMusic(player); P_RestoreMusic(player);
return 0; lua_pushboolean(L, true);
}
else
lua_pushnil(L);
return 1;
} }
static int lib_pSpawnShieldOrb(lua_State *L) static int lib_pSpawnShieldOrb(lua_State *L)
@ -1867,8 +1870,13 @@ static int lib_sChangeMusic(lua_State *L)
fadeinms = (UINT32)luaL_optinteger(L, 7, 0); fadeinms = (UINT32)luaL_optinteger(L, 7, 0);
if (!player || P_IsLocalPlayer(player)) if (!player || P_IsLocalPlayer(player))
{
S_ChangeMusicEx(music_name, music_flags, looping, position, prefadems, fadeinms); S_ChangeMusicEx(music_name, music_flags, looping, position, prefadems, fadeinms);
return 0; lua_pushboolean(L, true);
}
else
lua_pushnil(L);
return 1;
} }
static int lib_sSpeedMusic(lua_State *L) static int lib_sSpeedMusic(lua_State *L)
@ -1884,8 +1892,230 @@ static int lib_sSpeedMusic(lua_State *L)
return LUA_ErrInvalid(L, "player_t"); return LUA_ErrInvalid(L, "player_t");
} }
if (!player || P_IsLocalPlayer(player)) if (!player || P_IsLocalPlayer(player))
S_SpeedMusic(speed); lua_pushboolean(L, S_SpeedMusic(speed));
return 0; else
lua_pushnil(L);
return 1;
}
static int lib_sMusicType(lua_State *L)
{
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
{
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
lua_pushinteger(L, S_MusicType());
else
lua_pushnil(L);
return 1;
}
static int lib_sMusicPlaying(lua_State *L)
{
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
{
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
lua_pushboolean(L, S_MusicPlaying());
else
lua_pushnil(L);
return 1;
}
static int lib_sMusicPaused(lua_State *L)
{
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
{
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
lua_pushboolean(L, S_MusicPaused());
else
lua_pushnil(L);
return 1;
}
static int lib_sMusicName(lua_State *L)
{
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
{
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
lua_pushstring(L, S_MusicName());
else
lua_pushnil(L);
return 1;
}
static int lib_sMusicInfo(lua_State *L)
{
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
{
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
{
char mname[7];
UINT16 mflags;
boolean looping;
if (S_MusicInfo(mname, &mflags, &looping))
{
lua_pushstring(L, mname);
lua_pushinteger(L, mflags);
lua_pushboolean(L, looping);
}
else
lua_pushboolean(L, false);
}
else
lua_pushnil(L);
return 1;
}
static int lib_sMusicExists(lua_State *L)
{
boolean checkMIDI = lua_opttrueboolean(L, 2);
boolean checkDigi = lua_opttrueboolean(L, 3);
#ifdef MUSICSLOT_COMPATIBILITY
const char *music_name;
UINT32 music_num;
char music_compat_name[7];
UINT16 music_flags = 0;
NOHUD
if (lua_isnumber(L, 1))
{
music_num = (UINT32)luaL_checkinteger(L, 1);
music_flags = (UINT16)(music_num & 0x0000FFFF);
if (music_flags && music_flags <= 1035)
snprintf(music_compat_name, 7, "%sM", G_BuildMapName((INT32)music_flags));
else if (music_flags && music_flags <= 1050)
strncpy(music_compat_name, compat_special_music_slots[music_flags - 1036], 7);
else
music_compat_name[0] = 0; // becomes empty string
music_compat_name[6] = 0;
music_name = (const char *)&music_compat_name;
}
else
{
music_num = 0;
music_name = luaL_checkstring(L, 1);
}
#else
const char *music_name = luaL_checkstring(L, 1);
#endif
NOHUD
lua_pushboolean(L, S_MusicExists(music_name, checkMIDI, checkDigi));
return 1;
}
static int lib_sGetMusicLength(lua_State *L)
{
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
{
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
lua_pushinteger(L, (int)S_GetMusicLength());
else
lua_pushnil(L);
return 1;
}
static int lib_sSetMusicLoopPoint(lua_State *L)
{
UINT32 looppoint = (UINT32)luaL_checkinteger(L, 1);
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 2) && lua_isuserdata(L, 2))
{
player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
lua_pushboolean(L, S_SetMusicLoopPoint(looppoint));
else
lua_pushnil(L);
return 1;
}
static int lib_sGetMusicLoopPoint(lua_State *L)
{
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
{
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
lua_pushinteger(L, (int)S_GetMusicLoopPoint());
else
lua_pushnil(L);
return 1;
}
static int lib_sSetMusicPosition(lua_State *L)
{
UINT32 position = (UINT32)luaL_checkinteger(L, 1);
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 2) && lua_isuserdata(L, 2))
{
player = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
lua_pushboolean(L, S_SetMusicPosition(position));
else
lua_pushnil(L);
return 1;
}
static int lib_sGetMusicPosition(lua_State *L)
{
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
{
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
lua_pushinteger(L, (int)S_GetMusicPosition());
else
lua_pushnil(L);
return 1;
} }
static int lib_sStopMusic(lua_State *L) static int lib_sStopMusic(lua_State *L)
@ -1899,8 +2129,53 @@ static int lib_sStopMusic(lua_State *L)
return LUA_ErrInvalid(L, "player_t"); return LUA_ErrInvalid(L, "player_t");
} }
if (!player || P_IsLocalPlayer(player)) if (!player || P_IsLocalPlayer(player))
{
S_StopMusic(); S_StopMusic();
return 0; lua_pushboolean(L, true);
}
else
lua_pushnil(L);
return 1;
}
static int lib_sPauseMusic(lua_State *L)
{
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
{
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
{
S_PauseAudio();
lua_pushboolean(L, true);
}
else
lua_pushnil(L);
return 1;
}
static int lib_sResumeMusic(lua_State *L)
{
player_t *player = NULL;
NOHUD
if (!lua_isnone(L, 1) && lua_isuserdata(L, 1))
{
player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
if (!player)
return LUA_ErrInvalid(L, "player_t");
}
if (!player || P_IsLocalPlayer(player))
{
S_ResumeAudio();
lua_pushboolean(L, true);
}
else
lua_pushnil(L);
return 1;
} }
static int lib_sSetInternalMusicVolume(lua_State *L) static int lib_sSetInternalMusicVolume(lua_State *L)
@ -2641,6 +2916,41 @@ static int lib_kGetItemPatch(lua_State *L)
return 1; return 1;
} }
// sets the remaining time before players blow up
static int lib_kSetRaceCountdown(lua_State *L)
{
tic_t c = (tic_t)luaL_checkinteger(L, 1);
racecountdown = c;
return 0;
}
// sets the remaining time before the race ends after everyone finishes
static int lib_kSetExitCountdown(lua_State *L)
{
tic_t c = (tic_t)luaL_checkinteger(L, 1);
NOHUD
exitcountdown = c;
return 0;
}
// Sets the item cooldown before another shrink / SPB can be rolled
static int lib_kSetIndirectItemCountdown(lua_State *L)
{
tic_t c = (tic_t)luaL_checkinteger(L, 1);
NOHUD
indirectitemcooldown = c;
return 0;
}
// Sets the item cooldown before another shrink / SPB can be rolled
static int lib_kSetHyuCountdown(lua_State *L)
{
tic_t c = (tic_t)luaL_checkinteger(L, 1);
NOHUD
hyubgone = c;
return 0;
}
static luaL_Reg lib[] = { static luaL_Reg lib[] = {
{"print", lib_print}, {"print", lib_print},
{"chatprint", lib_chatprint}, {"chatprint", lib_chatprint},
@ -2802,6 +3112,19 @@ static luaL_Reg lib[] = {
{"S_ShowMusicCredit",lib_sShowMusicCredit}, {"S_ShowMusicCredit",lib_sShowMusicCredit},
{"S_ChangeMusic",lib_sChangeMusic}, {"S_ChangeMusic",lib_sChangeMusic},
{"S_SpeedMusic",lib_sSpeedMusic}, {"S_SpeedMusic",lib_sSpeedMusic},
{"S_MusicType",lib_sMusicType},
{"S_MusicPlaying",lib_sMusicPlaying},
{"S_MusicPaused",lib_sMusicPaused},
{"S_MusicName",lib_sMusicName},
{"S_MusicInfo",lib_sMusicInfo},
{"S_MusicExists",lib_sMusicExists},
{"S_GetMusicLength",lib_sGetMusicLength},
{"S_SetMusicLoopPoint",lib_sSetMusicLoopPoint},
{"S_GetMusicLoopPoint",lib_sGetMusicLoopPoint},
{"S_SetMusicPosition",lib_sSetMusicPosition},
{"S_GetMusicPosition",lib_sGetMusicPosition},
{"S_PauseMusic",lib_sPauseMusic},
{"S_ResumeMusic",lib_sResumeMusic},
{"S_StopMusic",lib_sStopMusic}, {"S_StopMusic",lib_sStopMusic},
{"S_SetInternalMusicVolume", lib_sSetInternalMusicVolume}, {"S_SetInternalMusicVolume", lib_sSetInternalMusicVolume},
{"S_StopFadingMusic",lib_sStopFadingMusic}, {"S_StopFadingMusic",lib_sStopFadingMusic},
@ -2868,6 +3191,10 @@ static luaL_Reg lib[] = {
{"K_GetKartAccel",lib_kGetKartAccel}, {"K_GetKartAccel",lib_kGetKartAccel},
{"K_GetKartFlashing",lib_kGetKartFlashing}, {"K_GetKartFlashing",lib_kGetKartFlashing},
{"K_GetItemPatch",lib_kGetItemPatch}, {"K_GetItemPatch",lib_kGetItemPatch},
{"K_SetRaceCountdown",lib_kSetRaceCountdown},
{"K_SetExitCountdown",lib_kSetExitCountdown},
{"K_SetIndirectItemCooldown",lib_kSetIndirectItemCountdown},
{"K_SetHyudoroCooldown",lib_kSetHyuCountdown},
{NULL, NULL} {NULL, NULL}
}; };

View file

@ -413,6 +413,30 @@ static int lib_cvRegisterVar(lua_State *L)
return 1; return 1;
} }
// For some reason I couldn't cherry pick this.
// Credits for this function go to james. All hail birb. -Lat'
static int lib_cvFindVar(lua_State *L)
{
consvar_t *cv;
if (( cv = CV_FindVar(luaL_checkstring(L,1)) ))
{
lua_settop(L,1);/* We only want one argument in the stack. */
lua_pushlightuserdata(L, cv);/* Now the second value on stack. */
luaL_getmetatable(L, META_CVAR);
/*
The metatable is the last value on the stack, so this
applies it to the second value, which is the cvar.
*/
lua_setmetatable(L,2);
lua_pushvalue(L,2);
return 1;
}
else
return 0;
}
// CONS_Printf for a single player // CONS_Printf for a single player
// Use 'print' in baselib for a global message. // Use 'print' in baselib for a global message.
static int lib_consPrintf(lua_State *L) static int lib_consPrintf(lua_State *L)
@ -452,6 +476,7 @@ static luaL_Reg lib[] = {
{"COM_BufInsertText", lib_comBufInsertText}, {"COM_BufInsertText", lib_comBufInsertText},
{"CV_RegisterVar", lib_cvRegisterVar}, {"CV_RegisterVar", lib_cvRegisterVar},
{"CONS_Printf", lib_consPrintf}, {"CONS_Printf", lib_consPrintf},
{"CV_FindVar", lib_cvFindVar},
{NULL, NULL} {NULL, NULL}
}; };

View file

@ -44,6 +44,7 @@ enum hook {
hook_HurtMsg, hook_HurtMsg,
hook_PlayerSpawn, hook_PlayerSpawn,
hook_PlayerQuit, hook_PlayerQuit,
hook_MusicChange,
hook_ShouldSpin, //SRB2KART hook_ShouldSpin, //SRB2KART
hook_ShouldExplode, //SRB2KART hook_ShouldExplode, //SRB2KART
hook_ShouldSquish, //SRB2KART hook_ShouldSquish, //SRB2KART
@ -52,6 +53,7 @@ enum hook {
hook_PlayerSquish, //SRB2KART hook_PlayerSquish, //SRB2KART
hook_PlayerCmd, //SRB2KART hook_PlayerCmd, //SRB2KART
hook_IntermissionThinker, //SRB2KART hook_IntermissionThinker, //SRB2KART
hook_VoteThinker, //SRB2KART
hook_MAX // last hook hook_MAX // last hook
}; };
@ -89,6 +91,8 @@ boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg, int mute);
boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source); // Hook for hurt messages boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source); // Hook for hurt messages
#define LUAh_PlayerSpawn(player) LUAh_PlayerHook(player, hook_PlayerSpawn) // Hook for G_SpawnPlayer #define LUAh_PlayerSpawn(player) LUAh_PlayerHook(player, hook_PlayerSpawn) // Hook for G_SpawnPlayer
void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting
boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boolean *looping,
UINT32 *position, UINT32 *prefadems, UINT32 *fadeinms); // Hook for music changes
UINT8 LUAh_ShouldSpin(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Should player be spun out? UINT8 LUAh_ShouldSpin(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Should player be spun out?
UINT8 LUAh_ShouldExplode(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Should player be exploded? UINT8 LUAh_ShouldExplode(player_t *player, mobj_t *inflictor, mobj_t *source); // SRB2KART: Should player be exploded?
@ -101,5 +105,6 @@ boolean LUAh_PlayerSquish(player_t *player, mobj_t *inflictor, mobj_t *source);
boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Allows to write to player cmd before the game does anything with them. boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Allows to write to player cmd before the game does anything with them.
void LUAh_IntermissionThinker(void); // Hook for Y_Ticker void LUAh_IntermissionThinker(void); // Hook for Y_Ticker
void LUAh_VoteThinker(void); // Hook for Y_VoteTicker
#endif #endif

View file

@ -55,6 +55,7 @@ const char *const hookNames[hook_MAX+1] = {
"HurtMsg", "HurtMsg",
"PlayerSpawn", "PlayerSpawn",
"PlayerQuit", "PlayerQuit",
"MusicChange",
"ShouldSpin", "ShouldSpin",
"ShouldExplode", "ShouldExplode",
"ShouldSquish", "ShouldSquish",
@ -63,6 +64,7 @@ const char *const hookNames[hook_MAX+1] = {
"PlayerSquish", "PlayerSquish",
"PlayerCmd", "PlayerCmd",
"IntermissionThinker", "IntermissionThinker",
"VoteThinker",
NULL NULL
}; };
@ -442,6 +444,27 @@ void LUAh_IntermissionThinker(void)
} }
} }
// Hook for Y_VoteTicker
void LUAh_VoteThinker(void)
{
hook_p hookp;
if (!gL || !(hooksAvailable[hook_VoteThinker/8] & (1<<(hook_VoteThinker%8))))
return;
for (hookp = roothook; hookp; hookp = hookp->next)
if (hookp->type == hook_VoteThinker)
{
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
lua_gettable(gL, LUA_REGISTRYINDEX);
if (lua_pcall(gL, 0, 0, 0)) {
if (!hookp->error || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
hookp->error = true;
}
}
}
// Hook for mobj collisions // Hook for mobj collisions
UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which) UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which)
@ -1191,6 +1214,65 @@ void LUAh_PlayerQuit(player_t *plr, int reason)
lua_settop(gL, 0); lua_settop(gL, 0);
} }
// Hook for music changes
boolean LUAh_MusicChange(const char *oldname, char *newname, UINT16 *mflags, boolean *looping,
UINT32 *position, UINT32 *prefadems, UINT32 *fadeinms)
{
hook_p hookp;
boolean hooked = false;
if (!gL || !(hooksAvailable[hook_MusicChange/8] & (1<<(hook_MusicChange%8))))
return false;
lua_settop(gL, 0);
for (hookp = roothook; hookp; hookp = hookp->next)
if (hookp->type == hook_MusicChange)
{
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
lua_gettable(gL, LUA_REGISTRYINDEX);
lua_pushstring(gL, oldname);
lua_pushstring(gL, newname);
lua_pushinteger(gL, *mflags);
lua_pushboolean(gL, *looping);
lua_pushinteger(gL, *position);
lua_pushinteger(gL, *prefadems);
lua_pushinteger(gL, *fadeinms);
if (lua_pcall(gL, 7, 6, 0)) {
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
lua_pop(gL, 1);
continue;
}
// output 1: true, false, or string musicname override
if (lua_isboolean(gL, -6) && lua_toboolean(gL, -6))
hooked = true;
else if (lua_isstring(gL, -6))
strncpy(newname, lua_tostring(gL, -6), 7);
// output 2: mflags override
if (lua_isnumber(gL, -5))
*mflags = lua_tonumber(gL, -5);
// output 3: looping override
if (lua_isboolean(gL, -4))
*looping = lua_toboolean(gL, -4);
// output 4: position override
if (lua_isboolean(gL, -3))
*position = lua_tonumber(gL, -3);
// output 5: prefadems override
if (lua_isboolean(gL, -2))
*prefadems = lua_tonumber(gL, -2);
// output 6: fadeinms override
if (lua_isboolean(gL, -1))
*fadeinms = lua_tonumber(gL, -1);
lua_pop(gL, 6);
}
lua_settop(gL, 0);
newname[6] = 0;
return hooked;
}
// Hook for K_SpinPlayer. Determines if yes or no we should get damaged reguardless of circumstances. // Hook for K_SpinPlayer. Determines if yes or no we should get damaged reguardless of circumstances.
UINT8 LUAh_ShouldSpin(player_t *player, mobj_t *inflictor, mobj_t *source) UINT8 LUAh_ShouldSpin(player_t *player, mobj_t *inflictor, mobj_t *source)
{ {

View file

@ -19,6 +19,7 @@ enum hud {
hud_minimap, hud_minimap,
hud_item, hud_item,
hud_position, hud_position,
hud_check, // "CHECK" f-zero indicator
hud_minirankings, // Rankings to the left hud_minirankings, // Rankings to the left
hud_battlebumpers, // mini rankings battle bumpers. hud_battlebumpers, // mini rankings battle bumpers.
hud_battlefullscreen, // battle huge text (WAIT, WIN, LOSE ...) + karma comeback time hud_battlefullscreen, // battle huge text (WAIT, WIN, LOSE ...) + karma comeback time

View file

@ -46,6 +46,7 @@ static const char *const hud_disable_options[] = {
"minimap", "minimap",
"item", "item",
"position", "position",
"check", // "CHECK" f-zero indicator
"minirankings", // Gametype rankings to the left "minirankings", // Gametype rankings to the left
"battlerankingsbumpers", // bumper drawer for battle. Useful if you want to make a custom battle gamemode without bumpers being involved. "battlerankingsbumpers", // bumper drawer for battle. Useful if you want to make a custom battle gamemode without bumpers being involved.
"battlefullscreen", // battlefullscreen func (WAIT, ATTACK OR PROTECT ...) "battlefullscreen", // battlefullscreen func (WAIT, ATTACK OR PROTECT ...)

View file

@ -81,6 +81,88 @@ static int lib_lenPlayer(lua_State *L)
return 1; return 1;
} }
// Same deal as the three functions above but for displayplayers
static int lib_iterateDisplayplayers(lua_State *L)
{
INT32 i = -1;
INT32 temp = -1;
INT32 iter = 0;
if (lua_gettop(L) < 2)
{
//return luaL_error(L, "Don't call displayplayers.iterate() directly, use it as 'for player in displayplayers.iterate do <block> end'.");
lua_pushcfunction(L, lib_iterateDisplayplayers);
return 1;
}
lua_settop(L, 2);
lua_remove(L, 1); // state is unused.
if (!lua_isnil(L, 1))
{
temp = (INT32)(*((player_t **)luaL_checkudata(L, 1, META_PLAYER)) - players); // get the player # of the last iterated player.
// @FIXME:
// I didn't quite find a better way for this; Here, we go back to which player in displayplayers we last iterated to resume the for loop below for this new function call
// I don't understand enough about how the Lua stacks work to get this to work in possibly a single line.
// So anyone feel free to correct this!
for (; iter < MAXSPLITSCREENPLAYERS; iter++)
{
if (displayplayers[iter] == temp)
{
i = iter;
break;
}
}
}
for (i++; i < MAXSPLITSCREENPLAYERS; i++)
{
if (!playeringame[displayplayers[i]] || i > splitscreen)
return 0; // Stop! There are no more players for us to go through. There will never be a player gap in displayplayers.
if (!players[displayplayers[i]].mo)
continue;
LUA_PushUserdata(L, &players[displayplayers[i]], META_PLAYER);
lua_pushinteger(L, i); // push this to recall what number we were on for the next function call. I suppose this also means you can retrieve the splitscreen player number with 'for p, n in displayplayers.iterate'!
return 2;
}
return 0;
}
static int lib_getDisplayplayers(lua_State *L)
{
const char *field;
// i -> players[i]
if (lua_type(L, 2) == LUA_TNUMBER)
{
lua_Integer i = luaL_checkinteger(L, 2);
if (i < 0 || i >= MAXSPLITSCREENPLAYERS)
return luaL_error(L, "displayplayers[] index %d out of range (0 - %d)", i, MAXSPLITSCREENPLAYERS-1);
if (!playeringame[displayplayers[i]])
return 0;
if (!players[displayplayers[i]].mo)
return 0;
LUA_PushUserdata(L, &players[displayplayers[i]], META_PLAYER);
return 1;
}
field = luaL_checkstring(L, 2);
if (fastcmp(field,"iterate"))
{
lua_pushcfunction(L, lib_iterateDisplayplayers);
return 1;
}
return 0;
}
// #displayplayers -> MAXSPLITSCREENPLAYERS
static int lib_lenDisplayplayers(lua_State *L)
{
lua_pushinteger(L, MAXSPLITSCREENPLAYERS);
return 1;
}
static int player_get(lua_State *L) static int player_get(lua_State *L)
{ {
player_t *plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); player_t *plr = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@ -777,6 +859,18 @@ int LUA_PlayerLib(lua_State *L)
lua_setfield(L, -2, "__len"); lua_setfield(L, -2, "__len");
lua_setmetatable(L, -2); lua_setmetatable(L, -2);
lua_setglobal(L, "players"); lua_setglobal(L, "players");
// push displayplayers in the same fashion
lua_newuserdata(L, 0);
lua_createtable(L, 0, 2);
lua_pushcfunction(L, lib_getDisplayplayers);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, lib_lenDisplayplayers);
lua_setfield(L, -2, "__len");
lua_setmetatable(L, -2);
lua_setglobal(L, "displayplayers");
return 0; return 0;
} }

View file

@ -112,7 +112,7 @@ static int noglobals(lua_State *L)
// Clear and create a new Lua state, laddo! // Clear and create a new Lua state, laddo!
// There's SCRIPTIN to be had! // There's SCRIPTIN to be had!
static void LUA_ClearState(void) void LUA_ClearState(void)
{ {
lua_State *L; lua_State *L;
int i; int i;
@ -734,6 +734,220 @@ static UINT8 ArchiveValue(int TABLESINDEX, int myindex)
return 0; return 0;
} }
// because of how this function works it has to be pasted allll over again just to save to demo_p since it returns an uint8 to begin with
static UINT8 ArchiveValueDemo(int TABLESINDEX, int myindex)
{
if (myindex < 0)
myindex = lua_gettop(gL)+1+myindex;
switch (lua_type(gL, myindex))
{
case LUA_TNONE:
case LUA_TNIL:
WRITEUINT8(demo_p, ARCH_NULL);
break;
// This might be a problem. D:
case LUA_TLIGHTUSERDATA:
case LUA_TTHREAD:
case LUA_TFUNCTION:
WRITEUINT8(demo_p, ARCH_NULL);
return 2;
case LUA_TBOOLEAN:
WRITEUINT8(demo_p, ARCH_BOOLEAN);
WRITEUINT8(demo_p, lua_toboolean(gL, myindex));
break;
case LUA_TNUMBER:
{
lua_Integer number = lua_tointeger(gL, myindex);
WRITEUINT8(demo_p, ARCH_SIGNED);
WRITEFIXED(demo_p, number);
break;
}
case LUA_TSTRING:
{
UINT16 len = (UINT16)lua_objlen(gL, myindex); // get length of string, including embedded zeros
const char *s = lua_tostring(gL, myindex);
UINT16 i = 0;
WRITEUINT8(demo_p, ARCH_STRING);
// if you're wondering why we're writing a string to demo_p this way,
// it turns out that Lua can have embedded zeros ('\0') in the strings,
// so we can't use WRITESTRING as that cuts off when it finds a '\0'.
// Saving the size of the string also allows us to get the size of the string on the other end,
// fixing the awful crashes previously encountered for reading strings longer than 1024
// (yes I know that's kind of a stupid thing to care about, but it'd be evil to trim or ignore them?)
// -- Monster Iestyn 05/08/18
WRITEUINT16(demo_p, len); // save size of string
while (i < len)
WRITECHAR(demo_p, s[i++]); // write chars individually, including the embedded zeros
break;
}
case LUA_TTABLE:
{
boolean found = false;
INT32 i;
UINT16 t = (UINT16)lua_objlen(gL, TABLESINDEX);
for (i = 1; i <= t && !found; i++)
{
lua_rawgeti(gL, TABLESINDEX, i);
if (lua_rawequal(gL, myindex, -1))
{
t = i;
found = true;
}
lua_pop(gL, 1);
}
if (!found)
t++;
WRITEUINT8(demo_p, ARCH_TABLE);
WRITEUINT16(demo_p, t);
if (!found)
{
lua_pushvalue(gL, myindex);
lua_rawseti(gL, TABLESINDEX, t);
return 1;
}
break;
}
case LUA_TUSERDATA:
switch (GetUserdataArchType(myindex))
{
case ARCH_MOBJINFO:
{
mobjinfo_t *info = *((mobjinfo_t **)lua_touserdata(gL, myindex));
WRITEUINT8(demo_p, ARCH_MOBJINFO);
WRITEUINT16(demo_p, info - mobjinfo);
break;
}
case ARCH_STATE:
{
state_t *state = *((state_t **)lua_touserdata(gL, myindex));
WRITEUINT8(demo_p, ARCH_STATE);
WRITEUINT16(demo_p, state - states);
break;
}
case ARCH_MOBJ:
{
mobj_t *mobj = *((mobj_t **)lua_touserdata(gL, myindex));
if (!mobj)
WRITEUINT8(demo_p, ARCH_NULL);
else {
WRITEUINT8(demo_p, ARCH_MOBJ);
WRITEUINT32(demo_p, mobj->mobjnum);
}
break;
}
case ARCH_PLAYER:
{
player_t *player = *((player_t **)lua_touserdata(gL, myindex));
if (!player)
WRITEUINT8(demo_p, ARCH_NULL);
else {
WRITEUINT8(demo_p, ARCH_PLAYER);
WRITEUINT8(demo_p, player - players);
}
break;
}
case ARCH_MAPTHING:
{
mapthing_t *mapthing = *((mapthing_t **)lua_touserdata(gL, myindex));
if (!mapthing)
WRITEUINT8(demo_p, ARCH_NULL);
else {
WRITEUINT8(demo_p, ARCH_MAPTHING);
WRITEUINT16(demo_p, mapthing - mapthings);
}
break;
}
case ARCH_VERTEX:
{
vertex_t *vertex = *((vertex_t **)lua_touserdata(gL, myindex));
if (!vertex)
WRITEUINT8(demo_p, ARCH_NULL);
else {
WRITEUINT8(demo_p, ARCH_VERTEX);
WRITEUINT16(demo_p, vertex - vertexes);
}
break;
}
case ARCH_LINE:
{
line_t *line = *((line_t **)lua_touserdata(gL, myindex));
if (!line)
WRITEUINT8(demo_p, ARCH_NULL);
else {
WRITEUINT8(demo_p, ARCH_LINE);
WRITEUINT16(demo_p, line - lines);
}
break;
}
case ARCH_SIDE:
{
side_t *side = *((side_t **)lua_touserdata(gL, myindex));
if (!side)
WRITEUINT8(demo_p, ARCH_NULL);
else {
WRITEUINT8(demo_p, ARCH_SIDE);
WRITEUINT16(demo_p, side - sides);
}
break;
}
case ARCH_SUBSECTOR:
{
subsector_t *subsector = *((subsector_t **)lua_touserdata(gL, myindex));
if (!subsector)
WRITEUINT8(demo_p, ARCH_NULL);
else {
WRITEUINT8(demo_p, ARCH_SUBSECTOR);
WRITEUINT16(demo_p, subsector - subsectors);
}
break;
}
case ARCH_SECTOR:
{
sector_t *sector = *((sector_t **)lua_touserdata(gL, myindex));
if (!sector)
WRITEUINT8(demo_p, ARCH_NULL);
else {
WRITEUINT8(demo_p, ARCH_SECTOR);
WRITEUINT16(demo_p, sector - sectors);
}
break;
}
#ifdef ESLOPE
case ARCH_SLOPE:
{
pslope_t *slope = *((pslope_t **)lua_touserdata(gL, myindex));
if (!slope)
WRITEUINT8(demo_p, ARCH_NULL);
else {
WRITEUINT8(demo_p, ARCH_SLOPE);
WRITEUINT16(demo_p, slope->id);
}
break;
}
#endif
case ARCH_MAPHEADER:
{
mapheader_t *header = *((mapheader_t **)lua_touserdata(gL, myindex));
if (!header)
WRITEUINT8(demo_p, ARCH_NULL);
else {
WRITEUINT8(demo_p, ARCH_MAPHEADER);
WRITEUINT16(demo_p, header - *mapheaderinfo);
}
break;
}
default:
WRITEUINT8(demo_p, ARCH_NULL);
return 2;
}
break;
}
return 0;
}
static void ArchiveExtVars(void *pointer, const char *ptype) static void ArchiveExtVars(void *pointer, const char *ptype)
{ {
int TABLESINDEX; int TABLESINDEX;
@ -790,6 +1004,63 @@ static void ArchiveExtVars(void *pointer, const char *ptype)
lua_pop(gL, 1); lua_pop(gL, 1);
} }
// simplified for demos
static void ArchiveExtVarsDemo(void *pointer, const char *ptype)
{
int TABLESINDEX;
UINT16 i;
if (!gL) {
if (fastcmp(ptype,"player")) // players must always be included, even if no vars
WRITEUINT16(demo_p, 0);
return;
}
TABLESINDEX = lua_gettop(gL);
lua_getfield(gL, LUA_REGISTRYINDEX, LREG_EXTVARS);
I_Assert(lua_istable(gL, -1));
lua_pushlightuserdata(gL, pointer);
lua_rawget(gL, -2);
lua_remove(gL, -2); // pop LREG_EXTVARS
if (!lua_istable(gL, -1))
{ // no extra values table
lua_pop(gL, 1);
if (fastcmp(ptype,"player")) // players must always be included, even if no vars
WRITEUINT16(demo_p, 0);
return;
}
lua_pushnil(gL);
for (i = 0; lua_next(gL, -2); i++)
lua_pop(gL, 1);
// skip anything that has an empty table and isn't a player.
if (i == 0)
{
if (fastcmp(ptype,"player")) // always include players even if they have no extra variables
WRITEUINT16(demo_p, 0);
lua_pop(gL, 1);
return;
}
if (fastcmp(ptype,"mobj")) // mobjs must write their mobjnum as a header
WRITEUINT32(demo_p, ((mobj_t *)pointer)->mobjnum);
WRITEUINT16(demo_p, i);
lua_pushnil(gL);
while (lua_next(gL, -2))
{
I_Assert(lua_type(gL, -2) == LUA_TSTRING);
WRITESTRING(demo_p, lua_tostring(gL, -2));
if (ArchiveValueDemo(TABLESINDEX, -1) == 2)
CONS_Alert(CONS_ERROR, "Type of value for %s entry '%s' (%s) could not be archived!\n", ptype, lua_tostring(gL, -2), luaL_typename(gL, -1));
lua_pop(gL, 1);
}
lua_pop(gL, 1);
}
static int NetArchive(lua_State *L) static int NetArchive(lua_State *L)
{ {
int TABLESINDEX = lua_upvalueindex(1); int TABLESINDEX = lua_upvalueindex(1);
@ -843,6 +1114,50 @@ static void ArchiveTables(void)
} }
} }
static void ArchiveTablesDemo(void)
{
int TABLESINDEX;
UINT16 i, n;
UINT8 e;
if (!gL)
return;
TABLESINDEX = lua_gettop(gL);
n = (UINT16)lua_objlen(gL, TABLESINDEX);
for (i = 1; i <= n; i++)
{
lua_rawgeti(gL, TABLESINDEX, i);
lua_pushnil(gL);
while (lua_next(gL, -2))
{
// Write key
e = ArchiveValueDemo(TABLESINDEX, -2); // key should be either a number or a string, ArchiveValue can handle this.
if (e == 2) // invalid key type (function, thread, lightuserdata, or anything we don't recognise)
{
lua_pushvalue(gL, -2);
CONS_Alert(CONS_ERROR, "Index '%s' (%s) of table %d could not be archived!\n", lua_tostring(gL, -1), luaL_typename(gL, -1), i);
lua_pop(gL, 1);
}
// Write value
e = ArchiveValueDemo(TABLESINDEX, -1);
if (e == 1)
n++; // the table contained a new table we'll have to archive. :(
else if (e == 2) // invalid value type
{
lua_pushvalue(gL, -2);
CONS_Alert(CONS_ERROR, "Type of value for table %d entry '%s' (%s) could not be archived!\n", i, lua_tostring(gL, -1), luaL_typename(gL, -1));
lua_pop(gL, 1);
}
lua_pop(gL, 1);
}
lua_pop(gL, 1);
WRITEUINT8(demo_p, ARCH_TEND);
}
}
static UINT8 UnArchiveValue(int TABLESINDEX) static UINT8 UnArchiveValue(int TABLESINDEX)
{ {
UINT8 type = READUINT8(save_p); UINT8 type = READUINT8(save_p);
@ -932,6 +1247,109 @@ static UINT8 UnArchiveValue(int TABLESINDEX)
return 0; return 0;
} }
// Unarchives from demo_p:
// Return values:
// 0: Normal
// 1: Read table key
// 2: Read table value
// 3: Don't use setfield
static UINT8 UnArchiveValueDemo(int TABLESINDEX, char field[1024])
{
UINT8 type = READUINT8(demo_p);
switch (type)
{
case ARCH_NULL:
lua_pushnil(gL);
break;
case ARCH_BOOLEAN:
lua_pushboolean(gL, READUINT8(demo_p));
break;
case ARCH_SIGNED:
lua_pushinteger(gL, READFIXED(demo_p));
break;
case ARCH_STRING:
{
UINT16 len = READUINT16(demo_p); // length of string, including embedded zeros
char *value;
UINT16 i = 0;
// See my comments in the ArchiveValue function;
// it's much the same for reading strings as writing them!
// (i.e. we can't use READSTRING either)
// -- Monster Iestyn 05/08/18
value = malloc(len); // make temp buffer of size len
// now read the actual string
while (i < len)
value[i++] = READCHAR(demo_p); // read chars individually, including the embedded zeros
lua_pushlstring(gL, value, len); // push the string (note: this function supports embedded zeros)
free(value); // free the buffer
break;
}
case ARCH_TABLE:
{
UINT16 tid = READUINT16(demo_p);
lua_rawgeti(gL, TABLESINDEX, tid);
if (lua_isnil(gL, -1))
{
lua_pop(gL, 1);
lua_newtable(gL);
lua_pushvalue(gL, -1);
lua_rawseti(gL, TABLESINDEX, tid);
return 2;
}
break;
}
case ARCH_MOBJINFO:
LUA_PushUserdata(gL, &mobjinfo[READUINT16(demo_p)], META_MOBJINFO);
break;
case ARCH_STATE:
LUA_PushUserdata(gL, &states[READUINT16(demo_p)], META_STATE);
break;
case ARCH_MOBJ:
demo_p += sizeof(UINT32); // Skip this data, we can't read a mobj here, it'd point to garbage and crash the game.
if (field)
CONS_Alert(CONS_WARNING,"Cannot read mobj_t stored in player variable \'%s\'. Desyncs may occur.\n", field);
else
CONS_Alert(CONS_WARNING,"Couldn't read mobj_t\n");
return 3; // Don't set the field
case ARCH_PLAYER:
LUA_PushUserdata(gL, &players[READUINT8(demo_p)], META_PLAYER);
break;
case ARCH_MAPTHING:
LUA_PushUserdata(gL, &mapthings[READUINT16(demo_p)], META_MAPTHING);
break;
case ARCH_VERTEX:
LUA_PushUserdata(gL, &vertexes[READUINT16(demo_p)], META_VERTEX);
break;
case ARCH_LINE:
LUA_PushUserdata(gL, &lines[READUINT16(demo_p)], META_LINE);
break;
case ARCH_SIDE:
LUA_PushUserdata(gL, &sides[READUINT16(demo_p)], META_SIDE);
break;
case ARCH_SUBSECTOR:
LUA_PushUserdata(gL, &subsectors[READUINT16(demo_p)], META_SUBSECTOR);
break;
case ARCH_SECTOR:
LUA_PushUserdata(gL, &sectors[READUINT16(demo_p)], META_SECTOR);
break;
#ifdef ESLOPE
case ARCH_SLOPE:
LUA_PushUserdata(gL, P_SlopeById(READUINT16(demo_p)), META_SLOPE);
break;
#endif
case ARCH_MAPHEADER:
LUA_PushUserdata(gL, mapheaderinfo[READUINT16(demo_p)], META_MAPHEADER);
break;
case ARCH_TEND:
return 1;
}
return 0;
}
static void UnArchiveExtVars(void *pointer) static void UnArchiveExtVars(void *pointer)
{ {
int TABLESINDEX; int TABLESINDEX;
@ -961,6 +1379,35 @@ static void UnArchiveExtVars(void *pointer)
lua_pop(gL, 2); // pop LREG_EXTVARS and pointer's subtable lua_pop(gL, 2); // pop LREG_EXTVARS and pointer's subtable
} }
static void UnArchiveExtVarsDemo(void *pointer)
{
int TABLESINDEX;
UINT16 field_count = READUINT16(demo_p);
UINT16 i;
char field[1024];
if (field_count == 0)
return;
I_Assert(gL != NULL);
TABLESINDEX = lua_gettop(gL);
lua_createtable(gL, 0, field_count); // pointer's ext vars subtable
for (i = 0; i < field_count; i++)
{
READSTRING(demo_p, field);
if (UnArchiveValueDemo(TABLESINDEX, field) != 3) // This will return 3 if we shouldn't set this field.
lua_setfield(gL, -2, field);
}
lua_getfield(gL, LUA_REGISTRYINDEX, LREG_EXTVARS);
I_Assert(lua_istable(gL, -1));
lua_pushlightuserdata(gL, pointer);
lua_pushvalue(gL, -3); // pointer's ext vars subtable
lua_rawset(gL, -3);
lua_pop(gL, 2); // pop LREG_EXTVARS and pointer's subtable
}
static int NetUnArchive(lua_State *L) static int NetUnArchive(lua_State *L)
{ {
int TABLESINDEX = lua_upvalueindex(1); int TABLESINDEX = lua_upvalueindex(1);
@ -1002,6 +1449,38 @@ static void UnArchiveTables(void)
} }
} }
static void UnArchiveTablesDemo(void)
{
int TABLESINDEX;
UINT16 i, n;
if (!gL)
return;
TABLESINDEX = lua_gettop(gL);
n = (UINT16)lua_objlen(gL, TABLESINDEX);
for (i = 1; i <= n; i++)
{
lua_rawgeti(gL, TABLESINDEX, i);
while (true)
{
if (UnArchiveValueDemo(TABLESINDEX, NULL) == 1) // read key
break;
if (UnArchiveValueDemo(TABLESINDEX, NULL) == 2) // read value
n++;
if (lua_isnil(gL, -2)) // if key is nil (if a function etc was accidentally saved)
{
CONS_Alert(CONS_ERROR, "A nil key in table %d was found! (Invalid key type or corrupted save?)\n", i);
lua_pop(gL, 2); // pop key and value instead of setting them in the table, to prevent Lua panic errors
}
else
lua_rawset(gL, -3);
}
lua_pop(gL, 1);
}
}
void LUA_Step(void) void LUA_Step(void)
{ {
if (!gL) if (!gL)
@ -1076,6 +1555,49 @@ void LUA_UnArchive(void)
lua_pop(gL, 1); // pop tables lua_pop(gL, 1); // pop tables
} }
// simplified versions of LUA_Archive for demos
void LUA_ArchiveDemo(void)
{
INT32 i;
if (gL)
lua_newtable(gL); // tables to be archived.
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] && i > 0) // NEVER skip player 0, this is for dedi servs.
continue;
// all players in game will be archived, even if they just add a 0.
ArchiveExtVarsDemo(&players[i], "player");
}
ArchiveTablesDemo();
if (gL)
lua_pop(gL, 1); // pop tables
}
// this time make sure we read from demo_p
void LUA_UnArchiveDemo(void)
{
INT32 i;
if (gL)
lua_newtable(gL); // tables to be read
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] && i > 0) // same here, this is to synch dediservs properly.
continue;
UnArchiveExtVarsDemo(&players[i]);
}
UnArchiveTablesDemo();
if (gL)
lua_pop(gL, 1); // pop tables
}
// For mobj_t, player_t, etc. to take custom variables. // For mobj_t, player_t, etc. to take custom variables.
int Lua_optoption(lua_State *L, int narg, int Lua_optoption(lua_State *L, int narg,
const char *def, const char *const lst[]) const char *def, const char *const lst[])

View file

@ -38,6 +38,8 @@
void LUA_ClearExtVars(void); void LUA_ClearExtVars(void);
#endif #endif
void LUA_ClearState(void);
void LUA_LoadLump(UINT16 wad, UINT16 lump); void LUA_LoadLump(UINT16 wad, UINT16 lump);
#ifdef LUA_ALLOW_BYTECODE #ifdef LUA_ALLOW_BYTECODE
void LUA_DumpFile(const char *filename); void LUA_DumpFile(const char *filename);
@ -51,6 +53,10 @@ void LUA_InvalidatePlayer(player_t *player);
void LUA_Step(void); void LUA_Step(void);
void LUA_Archive(void); void LUA_Archive(void);
void LUA_UnArchive(void); void LUA_UnArchive(void);
void LUA_ArchiveDemo(void);
void LUA_UnArchiveDemo(void);
void Got_Luacmd(UINT8 **cp, INT32 playernum); // lua_consolelib.c void Got_Luacmd(UINT8 **cp, INT32 playernum); // lua_consolelib.c
void LUA_CVarChanged(const char *name); // lua_consolelib.c void LUA_CVarChanged(const char *name); // lua_consolelib.c
int Lua_optoption(lua_State *L, int narg, int Lua_optoption(lua_State *L, int narg,

View file

@ -19,6 +19,10 @@
#include "v_video.h" #include "v_video.h"
#include "i_video.h" #include "i_video.h"
#ifdef HWRENDER
#include "hardware/hw_main.h"
#endif
// GIFs are always little-endian // GIFs are always little-endian
#include "byteptr.h" #include "byteptr.h"
@ -452,6 +456,32 @@ const UINT8 gifframe_gchead[4] = {0x21,0xF9,0x04,0x04}; // GCE, bytes, packed by
static UINT8 *gifframe_data = NULL; static UINT8 *gifframe_data = NULL;
static size_t gifframe_size = 8192; static size_t gifframe_size = 8192;
#ifdef HWRENDER
static void hwrconvert(void)
{
UINT8 *linear = HWR_GetScreenshot();
UINT8 *dest = screens[2];
UINT8 r, g, b;
INT32 x, y;
size_t i = 0;
InitColorLUT();
for (y = 0; y < vid.height; y++)
{
for (x = 0; x < vid.width; x++, i += 3)
{
r = (UINT8)linear[i];
g = (UINT8)linear[i + 1];
b = (UINT8)linear[i + 2];
dest[(y * vid.width) + x] = colorlookup[r >> SHIFTCOLORBITS][g >> SHIFTCOLORBITS][b >> SHIFTCOLORBITS];
}
}
free(linear);
}
#endif
// //
// GIF_framewrite // GIF_framewrite
// writes a frame into the file. // writes a frame into the file.
@ -477,7 +507,12 @@ static void GIF_framewrite(void)
GIF_optimizeregion(cur_screen, movie_screen, &blitx, &blity, &blitw, &blith); GIF_optimizeregion(cur_screen, movie_screen, &blitx, &blity, &blitw, &blith);
// blit to temp screen // blit to temp screen
if (rendermode == render_soft)
I_ReadScreen(movie_screen); I_ReadScreen(movie_screen);
#ifdef HWRENDER
else if (rendermode == render_opengl)
hwrconvert();
#endif
} }
else else
{ {
@ -486,7 +521,18 @@ static void GIF_framewrite(void)
blith = vid.height; blith = vid.height;
if (gif_frames == 0) if (gif_frames == 0)
{
if (rendermode == render_soft)
I_ReadScreen(movie_screen); I_ReadScreen(movie_screen);
#ifdef HWRENDER
else if (rendermode == render_opengl)
{
hwrconvert();
VID_BlitLinearScreen(screens[2], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes);
}
#endif
}
movie_screen = screens[0]; movie_screen = screens[0];
} }
@ -575,7 +621,7 @@ static void GIF_framewrite(void)
// //
INT32 GIF_open(const char *filename) INT32 GIF_open(const char *filename)
{ {
#ifdef HWRENDER #if 0
if (rendermode != render_soft) if (rendermode != render_soft)
{ {
CONS_Alert(CONS_WARNING, M_GetText("GIFs cannot be taken in non-software modes!\n")); CONS_Alert(CONS_WARNING, M_GetText("GIFs cannot be taken in non-software modes!\n"));

View file

@ -411,6 +411,19 @@ boolean FV3_Equal(const vector3_t *a_1, const vector3_t *a_2)
return false; return false;
} }
// ClosestPointOnVector
//
// Similar to ClosestPointOnLine, but uses a vector instead of two points.
//
void FV3_ClosestPointOnVector(const vector3_t *dir, const vector3_t *p, vector3_t *out)
{
fixed_t t = FV3_Dot(dir, p);
// Return the point on the line closest
FV3_MulEx(dir, t, out);
return;
}
fixed_t FV3_Dot(const vector3_t *a_1, const vector3_t *a_2) fixed_t FV3_Dot(const vector3_t *a_1, const vector3_t *a_2)
{ {
return (FixedMul(a_1->x, a_2->x) + FixedMul(a_1->y, a_2->y) + FixedMul(a_1->z, a_2->z)); return (FixedMul(a_1->x, a_2->x) + FixedMul(a_1->y, a_2->y) + FixedMul(a_1->z, a_2->z));
@ -458,19 +471,6 @@ vector3_t *FV3_ClosestPointOnLine(const vector3_t *Line, const vector3_t *p, vec
return FV3_AddEx(&Line[0], &V, out); return FV3_AddEx(&Line[0], &V, out);
} }
//
// ClosestPointOnVector
//
// Similar to ClosestPointOnLine, but uses a vector instead of two points.
//
void FV3_ClosestPointOnVector(const vector3_t *dir, const vector3_t *p, vector3_t *out)
{
fixed_t t = FV3_Dot(dir, p);
// Return the point on the line closest
FV3_MulEx(dir, t, out);
return;
}
// //
// ClosestPointOnTriangle // ClosestPointOnTriangle

View file

@ -238,7 +238,6 @@ static void M_HandleStaffReplay(INT32 choice);
static void M_ReplayTimeAttack(INT32 choice); static void M_ReplayTimeAttack(INT32 choice);
static void M_ChooseTimeAttack(INT32 choice); static void M_ChooseTimeAttack(INT32 choice);
//static void M_ChooseNightsAttack(INT32 choice); //static void M_ChooseNightsAttack(INT32 choice);
static void M_ModeAttackRetry(INT32 choice);
static void M_ModeAttackEndGame(INT32 choice); static void M_ModeAttackEndGame(INT32 choice);
static void M_SetGuestReplay(INT32 choice); static void M_SetGuestReplay(INT32 choice);
//static void M_ChoosePlayer(INT32 choice); //static void M_ChoosePlayer(INT32 choice);
@ -287,7 +286,7 @@ static void M_ResetControls(INT32 choice);
// Video & Sound // Video & Sound
menu_t OP_VideoOptionsDef, OP_VideoModeDef; menu_t OP_VideoOptionsDef, OP_VideoModeDef;
#ifdef HWRENDER #ifdef HWRENDER
menu_t OP_OpenGLOptionsDef, OP_OpenGLFogDef, OP_OpenGLColorDef; menu_t OP_OpenGLOptionsDef, OP_OpenGLColorDef;
#endif #endif
menu_t OP_SoundOptionsDef; menu_t OP_SoundOptionsDef;
//static void M_RestartAudio(void); //static void M_RestartAudio(void);
@ -326,6 +325,7 @@ static void M_PlaybackFastForward(INT32 choice);
static void M_PlaybackAdvance(INT32 choice); static void M_PlaybackAdvance(INT32 choice);
static void M_PlaybackSetViews(INT32 choice); static void M_PlaybackSetViews(INT32 choice);
static void M_PlaybackAdjustView(INT32 choice); static void M_PlaybackAdjustView(INT32 choice);
static void M_PlaybackToggleFreecam(INT32 choice);
static void M_PlaybackQuit(INT32 choice); static void M_PlaybackQuit(INT32 choice);
static UINT8 playback_enterheld = 0; // horrid hack to prevent holding the button from being extremely fucked static UINT8 playback_enterheld = 0; // horrid hack to prevent holding the button from being extremely fucked
@ -353,7 +353,6 @@ static void M_DrawHUDOptions(void);
static void M_DrawVideoMode(void); static void M_DrawVideoMode(void);
static void M_DrawMonitorToggles(void); static void M_DrawMonitorToggles(void);
#ifdef HWRENDER #ifdef HWRENDER
static void M_OGL_DrawFogMenu(void);
static void M_OGL_DrawColorMenu(void); static void M_OGL_DrawColorMenu(void);
#endif #endif
static void M_DrawMPMainMenu(void); static void M_DrawMPMainMenu(void);
@ -379,9 +378,6 @@ static void M_HandleLevelStats(INT32 choice);
static void M_HandleConnectIP(INT32 choice); static void M_HandleConnectIP(INT32 choice);
#endif #endif
static void M_HandleSetupMultiPlayer(INT32 choice); static void M_HandleSetupMultiPlayer(INT32 choice);
#ifdef HWRENDER
static void M_HandleFogColor(INT32 choice);
#endif
static void M_HandleVideoMode(INT32 choice); static void M_HandleVideoMode(INT32 choice);
static void M_HandleMonitorToggles(INT32 choice); static void M_HandleMonitorToggles(INT32 choice);
@ -523,26 +519,26 @@ static menuitem_t MISC_ReplayOptionsMenu[] =
{IT_CVAR|IT_STRING, NULL, "Sync Check Interval", &cv_netdemosyncquality, 10}, {IT_CVAR|IT_STRING, NULL, "Sync Check Interval", &cv_netdemosyncquality, 10},
}; };
static tic_t playback_last_menu_interaction_leveltime = 0;
static menuitem_t PlaybackMenu[] = static menuitem_t PlaybackMenu[] =
{ {
{IT_CALL | IT_STRING, "M_PHIDE", "Hide Menu", M_SelectableClearMenus, 0}, {IT_CALL | IT_STRING, "M_PHIDE", "Hide Menu (Esc)", M_SelectableClearMenus, 0},
{IT_CALL | IT_STRING, "M_PREW", "Rewind", M_PlaybackRewind, 20}, {IT_CALL | IT_STRING, "M_PREW", "Rewind ([)", M_PlaybackRewind, 20},
{IT_CALL | IT_STRING, "M_PPAUSE", "Pause", M_PlaybackPause, 36}, {IT_CALL | IT_STRING, "M_PPAUSE", "Pause (\\)", M_PlaybackPause, 36},
{IT_CALL | IT_STRING, "M_PFFWD", "Fast-Forward", M_PlaybackFastForward, 52}, {IT_CALL | IT_STRING, "M_PFFWD", "Fast-Forward (])", M_PlaybackFastForward, 52},
{IT_CALL | IT_STRING, "M_PSTEPB", "Backup Frame", M_PlaybackRewind, 20}, {IT_CALL | IT_STRING, "M_PSTEPB", "Backup Frame ([)", M_PlaybackRewind, 20},
{IT_CALL | IT_STRING, "M_PRESUM", "Resume", M_PlaybackPause, 36}, {IT_CALL | IT_STRING, "M_PRESUM", "Resume", M_PlaybackPause, 36},
{IT_CALL | IT_STRING, "M_PFADV", "Advance Frame", M_PlaybackAdvance, 52}, {IT_CALL | IT_STRING, "M_PFADV", "Advance Frame (])", M_PlaybackAdvance, 52},
{IT_ARROWS | IT_STRING, "M_PVIEWS", "View Count", M_PlaybackSetViews, 72}, {IT_ARROWS | IT_STRING, "M_PVIEWS", "View Count (- and =)", M_PlaybackSetViews, 72},
{IT_ARROWS | IT_STRING, "M_PNVIEW", "Viewpoint", M_PlaybackAdjustView, 88}, {IT_ARROWS | IT_STRING, "M_PNVIEW", "Viewpoint (1)", M_PlaybackAdjustView, 88},
{IT_ARROWS | IT_STRING, "M_PNVIEW", "Viewpoint 2", M_PlaybackAdjustView, 104}, {IT_ARROWS | IT_STRING, "M_PNVIEW", "Viewpoint 2 (2)", M_PlaybackAdjustView, 104},
{IT_ARROWS | IT_STRING, "M_PNVIEW", "Viewpoint 3", M_PlaybackAdjustView, 120}, {IT_ARROWS | IT_STRING, "M_PNVIEW", "Viewpoint 3 (3)", M_PlaybackAdjustView, 120},
{IT_ARROWS | IT_STRING, "M_PNVIEW", "Viewpoint 4", M_PlaybackAdjustView, 136}, {IT_ARROWS | IT_STRING, "M_PNVIEW", "Viewpoint 4 (4)", M_PlaybackAdjustView, 136},
//{IT_CALL | IT_STRING, "M_POPTS", "More Options...", M_ReplayHut, 156}, {IT_CALL | IT_STRING, "M_PVIEWS", "Toggle Free Camera (')", M_PlaybackToggleFreecam, 156},
//{IT_CALL | IT_STRING, "M_PEXIT", "Stop Playback", M_PlaybackQuit, 172}, {IT_CALL | IT_STRING, "M_PEXIT", "Stop Playback", M_PlaybackQuit, 172},
{IT_CALL | IT_STRING, "M_PEXIT", "Stop Playback", M_PlaybackQuit, 156},
}; };
typedef enum typedef enum
{ {
@ -558,6 +554,7 @@ typedef enum
playback_view2, playback_view2,
playback_view3, playback_view3,
playback_view4, playback_view4,
playback_freecamera,
//playback_moreoptions, //playback_moreoptions,
playback_quit playback_quit
} playback_e; } playback_e;
@ -584,7 +581,7 @@ typedef enum
// --------------------- // ---------------------
static menuitem_t MPauseMenu[] = static menuitem_t MPauseMenu[] =
{ {
{IT_STRING | IT_CALL, NULL, "Add-ons...", M_Addons, 8}, {IT_STRING | IT_CALL, NULL, "Addons...", M_Addons, 8},
{IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16}, {IT_STRING | IT_SUBMENU, NULL, "Scramble Teams...", &MISC_ScrambleTeamDef, 16},
{IT_STRING | IT_CALL, NULL, "Switch Map..." , M_MapChange, 24}, {IT_STRING | IT_CALL, NULL, "Switch Map..." , M_MapChange, 24},
@ -991,10 +988,9 @@ static menuitem_t MP_MainMenu[] =
static menuitem_t MP_ServerMenu[] = static menuitem_t MP_ServerMenu[] =
{ {
{IT_STRING|IT_CVAR, NULL, "Max. Player Count", &cv_maxplayers, 0}, {IT_STRING|IT_CVAR, NULL, "Max. Player Count", &cv_maxplayers, 10},
{IT_STRING|IT_CALL, NULL, "Room...", M_RoomMenu, 10}, {IT_STRING|IT_CALL, NULL, "Room...", M_RoomMenu, 20},
{IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Server Name", &cv_servername, 20}, {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Server Name", &cv_servername, 30},
{IT_STRING|IT_CVAR|IT_CV_PASSWORD, NULL, "Password", &cv_dummyjoinpassword, 44},
{IT_STRING|IT_CVAR, NULL, "Game Type", &cv_newgametype, 68}, {IT_STRING|IT_CVAR, NULL, "Game Type", &cv_newgametype, 68},
{IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 78}, {IT_STRING|IT_CVAR, NULL, "Level", &cv_nextmap, 78},
@ -1257,9 +1253,7 @@ static menuitem_t OP_VideoOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 100}, {IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 100},
#ifdef HWRENDER #ifdef HWRENDER
{IT_STRING | IT_CVAR, NULL, "3D models", &cv_grmdls, 115}, {IT_SUBMENU|IT_STRING, NULL, "OpenGL Options...", &OP_OpenGLOptionsDef, 120},
{IT_STRING | IT_CVAR, NULL, "Fallback Player 3D Model", &cv_grfallbackplayermodel, 125},
{IT_SUBMENU|IT_STRING, NULL, "OpenGL Options...", &OP_OpenGLOptionsDef, 135},
#endif #endif
}; };
@ -1278,8 +1272,6 @@ enum
op_video_fps, op_video_fps,
op_video_vsync, op_video_vsync,
#ifdef HWRENDER #ifdef HWRENDER
op_video_md2,
op_video_kartman,
op_video_ogl, op_video_ogl,
#endif #endif
}; };
@ -1292,36 +1284,19 @@ static menuitem_t OP_VideoModeMenu[] =
#ifdef HWRENDER #ifdef HWRENDER
static menuitem_t OP_OpenGLOptionsMenu[] = static menuitem_t OP_OpenGLOptionsMenu[] =
{ {
{IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 10}, {IT_STRING | IT_CVAR, NULL, "3D Models", &cv_grmdls, 10},
{IT_SUBMENU|IT_STRING, NULL, "Gamma...", &OP_OpenGLColorDef, 20}, {IT_STRING | IT_CVAR, NULL, "Fallback Player 3D Model", &cv_grfallbackplayermodel, 20},
{IT_STRING|IT_CVAR, NULL, "Shaders", &cv_grshaders, 30},
{IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 35}, {IT_STRING|IT_CVAR, NULL, "Texture Quality", &cv_scr_depth, 50},
{IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 45}, {IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 60},
{IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode, 55}, {IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode, 70},
/*#ifdef _WINDOWS
{IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 50},
#endif
#ifdef ALAM_LIGHTING
{IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 70},
#endif*/
};
#ifdef ALAM_LIGHTING {IT_STRING|IT_CVAR, NULL, "Wall Contrast Style", &cv_grfakecontrast, 90},
static menuitem_t OP_OpenGLLightingMenu[] = {IT_STRING|IT_CVAR, NULL, "Sprite Billboarding", &cv_grspritebillboarding, 100},
{ {IT_STRING|IT_CVAR, NULL, "Software Perspective", &cv_grshearing, 110},
{IT_STRING|IT_CVAR, NULL, "Coronas", &cv_grcoronas, 0},
{IT_STRING|IT_CVAR, NULL, "Coronas size", &cv_grcoronasize, 10},
{IT_STRING|IT_CVAR, NULL, "Dynamic lighting", &cv_grdynamiclighting, 20},
{IT_STRING|IT_CVAR, NULL, "Static lighting", &cv_grstaticlighting, 30},
};
#endif
static menuitem_t OP_OpenGLFogMenu[] = {IT_SUBMENU|IT_STRING, NULL, "Gamma...", &OP_OpenGLColorDef, 130},
{
{IT_STRING|IT_CVAR, NULL, "Fog", &cv_grfog, 10},
{IT_STRING|IT_KEYHANDLER, NULL, "Fog Color", M_HandleFogColor, 20},
{IT_STRING|IT_CVAR, NULL, "Fog Density", &cv_grfogdensity, 30},
{IT_STRING|IT_CVAR, NULL, "Software Fog",&cv_grsoftwarefog,40},
}; };
static menuitem_t OP_OpenGLColorMenu[] = static menuitem_t OP_OpenGLColorMenu[] =
@ -1369,7 +1344,7 @@ static menuitem_t OP_SoundOptionsMenu[] =
static menuitem_t OP_DataOptionsMenu[] = static menuitem_t OP_DataOptionsMenu[] =
{ {
{IT_STRING | IT_CALL, NULL, "Screenshot Options...", M_ScreenshotOptions, 10}, {IT_STRING | IT_CALL, NULL, "Screenshot Options...", M_ScreenshotOptions, 10},
{IT_STRING | IT_CALL, NULL, "Add-on Options...", M_AddonsOptions, 20}, {IT_STRING | IT_CALL, NULL, "Addon Options...", M_AddonsOptions, 20},
{IT_STRING | IT_SUBMENU, NULL, "Replay Options...", &MISC_ReplayOptionsDef, 30}, {IT_STRING | IT_SUBMENU, NULL, "Replay Options...", &MISC_ReplayOptionsDef, 30},
{IT_STRING | IT_SUBMENU, NULL, "Erase Data...", &OP_EraseDataDef, 50}, {IT_STRING | IT_SUBMENU, NULL, "Erase Data...", &OP_EraseDataDef, 50},
@ -1421,7 +1396,7 @@ static menuitem_t OP_AddonsOptionsMenu[] =
{IT_HEADER, NULL, "Menu", NULL, 0}, {IT_HEADER, NULL, "Menu", NULL, 0},
{IT_STRING|IT_CVAR, NULL, "Location", &cv_addons_option, 10}, {IT_STRING|IT_CVAR, NULL, "Location", &cv_addons_option, 10},
{IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_addons_folder, 20}, {IT_STRING|IT_CVAR|IT_CV_STRING, NULL, "Custom Folder", &cv_addons_folder, 20},
{IT_STRING|IT_CVAR, NULL, "Identify add-ons via", &cv_addons_md5, 48}, {IT_STRING|IT_CVAR, NULL, "Identify addons via", &cv_addons_md5, 48},
{IT_STRING|IT_CVAR, NULL, "Show unsupported file types", &cv_addons_showall, 58}, {IT_STRING|IT_CVAR, NULL, "Show unsupported file types", &cv_addons_showall, 58},
{IT_HEADER, NULL, "Search", NULL, 76}, {IT_HEADER, NULL, "Search", NULL, 76},
@ -1508,7 +1483,7 @@ static menuitem_t OP_ServerOptionsMenu[] =
#ifndef NONET #ifndef NONET
{IT_STRING | IT_CVAR, NULL, "Max. Player Count", &cv_maxplayers, 90}, {IT_STRING | IT_CVAR, NULL, "Max. Player Count", &cv_maxplayers, 90},
{IT_STRING | IT_CVAR, NULL, "Allow Players to Join", &cv_allownewplayer, 100}, {IT_STRING | IT_CVAR, NULL, "Allow Players to Join", &cv_allownewplayer, 100},
{IT_STRING | IT_CVAR, NULL, "Allow Add-on Downloading", &cv_downloading, 110}, {IT_STRING | IT_CVAR, NULL, "Allow Addon Downloading", &cv_downloading, 110},
{IT_STRING | IT_CVAR, NULL, "Pause Permission", &cv_pause, 120}, {IT_STRING | IT_CVAR, NULL, "Pause Permission", &cv_pause, 120},
{IT_STRING | IT_CVAR, NULL, "Mute All Chat", &cv_mute, 130}, {IT_STRING | IT_CVAR, NULL, "Mute All Chat", &cv_mute, 130},
@ -2085,20 +2060,6 @@ menu_t OP_MonitorToggleDef =
#ifdef HWRENDER #ifdef HWRENDER
menu_t OP_OpenGLOptionsDef = DEFAULTMENUSTYLE("M_VIDEO", OP_OpenGLOptionsMenu, &OP_VideoOptionsDef, 30, 30); menu_t OP_OpenGLOptionsDef = DEFAULTMENUSTYLE("M_VIDEO", OP_OpenGLOptionsMenu, &OP_VideoOptionsDef, 30, 30);
#ifdef ALAM_LIGHTING
menu_t OP_OpenGLLightingDef = DEFAULTMENUSTYLE("M_VIDEO", OP_OpenGLLightingMenu, &OP_OpenGLOptionsDef, 60, 40);
#endif
menu_t OP_OpenGLFogDef =
{
"M_VIDEO",
sizeof (OP_OpenGLFogMenu)/sizeof (menuitem_t),
&OP_OpenGLOptionsDef,
OP_OpenGLFogMenu,
M_OGL_DrawFogMenu,
60, 40,
0,
NULL
};
menu_t OP_OpenGLColorDef = menu_t OP_OpenGLColorDef =
{ {
"M_VIDEO", "M_VIDEO",
@ -2471,9 +2432,6 @@ static void M_NextOpt(void)
{ {
INT16 oldItemOn = itemOn; // prevent infinite loop INT16 oldItemOn = itemOn; // prevent infinite loop
if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_PASSWORD)
((consvar_t *)currentMenu->menuitems[itemOn].itemaction)->value = 0;
do do
{ {
if (itemOn + 1 > currentMenu->numitems - 1) if (itemOn + 1 > currentMenu->numitems - 1)
@ -2487,9 +2445,6 @@ static void M_PrevOpt(void)
{ {
INT16 oldItemOn = itemOn; // prevent infinite loop INT16 oldItemOn = itemOn; // prevent infinite loop
if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_PASSWORD)
((consvar_t *)currentMenu->menuitems[itemOn].itemaction)->value = 0;
do do
{ {
if (!itemOn) if (!itemOn)
@ -2774,10 +2729,8 @@ boolean M_Responder(event_t *ev)
// BP: one of the more big hack i have never made // BP: one of the more big hack i have never made
if (routine && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR) if (routine && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR)
{ {
if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING || (currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_PASSWORD) if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING)
{ {
if (ch == KEY_TAB && (currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_PASSWORD)
((consvar_t *)currentMenu->menuitems[itemOn].itemaction)->value ^= 1;
if (shiftdown && ch >= 32 && ch <= 127) if (shiftdown && ch >= 32 && ch <= 127)
ch = shiftxform[ch]; ch = shiftxform[ch];
@ -2790,8 +2743,9 @@ boolean M_Responder(event_t *ev)
routine = M_ChangeCvar; routine = M_ChangeCvar;
} }
if (currentMenu == &PlaybackMenuDef) if (currentMenu == &PlaybackMenuDef && !con_destlines)
{ {
playback_last_menu_interaction_leveltime = leveltime;
// Flip left/right with up/down for the playback menu, since it's a horizontal icon row. // Flip left/right with up/down for the playback menu, since it's a horizontal icon row.
switch (ch) switch (ch)
{ {
@ -2799,6 +2753,56 @@ boolean M_Responder(event_t *ev)
case KEY_UPARROW: ch = KEY_RIGHTARROW; break; case KEY_UPARROW: ch = KEY_RIGHTARROW; break;
case KEY_RIGHTARROW: ch = KEY_DOWNARROW; break; case KEY_RIGHTARROW: ch = KEY_DOWNARROW; break;
case KEY_DOWNARROW: ch = KEY_LEFTARROW; break; case KEY_DOWNARROW: ch = KEY_LEFTARROW; break;
// arbitrary keyboard shortcuts because fuck you
case '\'': // toggle freecam
M_PlaybackToggleFreecam(0);
break;
case ']': // ffw / advance frame (depends on if paused or not)
if (paused)
M_PlaybackAdvance(0);
else
M_PlaybackFastForward(0);
break;
case '[': // rewind /backupframe, uses the same function
M_PlaybackRewind(0);
break;
case '\\': // pause
M_PlaybackPause(0);
break;
// viewpoints, an annoyance (tm)
case '-': // viewpoint minus
M_PlaybackSetViews(-1); // yeah lol.
break;
case '=': // viewpoint plus
M_PlaybackSetViews(1); // yeah lol.
break;
// switch viewpoints:
case '1': // viewpoint for p1 (also f12)
// maximum laziness:
if (!demo.freecam)
G_AdjustView(1, 1, true);
break;
case '2': // viewpoint for p2
if (!demo.freecam)
G_AdjustView(2, 1, true);
break;
case '3': // viewpoint for p3
if (!demo.freecam)
G_AdjustView(3, 1, true);
break;
case '4': // viewpoint for p4
if (!demo.freecam)
G_AdjustView(4, 1, true);
break;
default: break; default: break;
} }
} }
@ -2853,9 +2857,9 @@ boolean M_Responder(event_t *ev)
if (currentMenu == &PlaybackMenuDef) if (currentMenu == &PlaybackMenuDef)
{ {
boolean held = (boolean)playback_enterheld; boolean held = (boolean)playback_enterheld;
playback_enterheld = TICRATE/7;
if (held) if (held)
return true; return true;
playback_enterheld = 3;
} }
if (routine) if (routine)
@ -2867,7 +2871,7 @@ boolean M_Responder(event_t *ev)
if (((currentMenu->menuitems[itemOn].status & IT_CALLTYPE) & IT_CALL_NOTMODIFIED) && majormods) if (((currentMenu->menuitems[itemOn].status & IT_CALLTYPE) & IT_CALL_NOTMODIFIED) && majormods)
{ {
S_StartSound(NULL, sfx_menu1); S_StartSound(NULL, sfx_menu1);
M_StartMessage(M_GetText("This cannot be done with complex add-ons\nor in a cheated game.\n\n(Press a key)\n"), NULL, MM_NOTHING); M_StartMessage(M_GetText("This cannot be done with complex addons\nor in a cheated game.\n\n(Press a key)\n"), NULL, MM_NOTHING);
return true; return true;
} }
} }
@ -2956,6 +2960,93 @@ boolean M_Responder(event_t *ev)
return true; return true;
} }
// special responder for demos
boolean M_DemoResponder(event_t *ev)
{
INT32 ch = -1; // cur event data
boolean eatinput = false; // :omnom:
//should be accounted for beforehand but just to be safe...
if (!demo.playback || demo.title)
return false;
if (noFurtherInput)
{
// Ignore input after enter/escape/other buttons
// (but still allow shift keyup so caps doesn't get stuck)
return false;
}
else if (ev->type == ev_keydown && !con_destlines) // not while the console is on please
{
ch = ev->data1;
// since this is ONLY for demos, there isn't MUCH for us to do.
// mirrored from m_responder
switch (ch)
{
// arbitrary keyboard shortcuts because fuck you
case '\'': // toggle freecam
M_PlaybackToggleFreecam(0);
eatinput = true;
break;
case ']': // ffw / advance frame (depends on if paused or not)
if (paused)
M_PlaybackAdvance(0);
else
M_PlaybackFastForward(0);
eatinput = true;
break;
case '[': // rewind /backupframe, uses the same function
M_PlaybackRewind(0);
break;
case '\\': // pause
M_PlaybackPause(0);
eatinput = true;
break;
// viewpoints, an annoyance (tm)
case '-': // viewpoint minus
M_PlaybackSetViews(-1); // yeah lol.
eatinput = true;
break;
case '=': // viewpoint plus
M_PlaybackSetViews(1); // yeah lol.
eatinput = true;
break;
// switch viewpoints:
case '1': // viewpoint for p1 (also f12)
// maximum laziness:
if (!demo.freecam)
G_AdjustView(1, 1, true);
break;
case '2': // viewpoint for p2
if (!demo.freecam)
G_AdjustView(2, 1, true);
break;
case '3': // viewpoint for p3
if (!demo.freecam)
G_AdjustView(3, 1, true);
break;
case '4': // viewpoint for p4
if (!demo.freecam)
G_AdjustView(4, 1, true);
break;
default: break;
}
}
return eatinput;
}
// //
// M_Drawer // M_Drawer
// Called after the view has been rendered, // Called after the view has been rendered,
@ -3027,6 +3118,7 @@ void M_StartControlPanel(void)
if (demo.playback) if (demo.playback)
{ {
currentMenu = &PlaybackMenuDef; currentMenu = &PlaybackMenuDef;
playback_last_menu_interaction_leveltime = leveltime;
} }
else if (!Playing()) else if (!Playing())
{ {
@ -3379,9 +3471,7 @@ void M_Init(void)
#ifdef HWRENDER #ifdef HWRENDER
// Permanently hide some options based on render mode // Permanently hide some options based on render mode
if (rendermode == render_soft) if (rendermode == render_soft)
OP_VideoOptionsMenu[op_video_ogl].status = OP_VideoOptionsMenu[op_video_ogl].status = IT_DISABLED;
OP_VideoOptionsMenu[op_video_kartman].status =
OP_VideoOptionsMenu[op_video_md2] .status = IT_DISABLED;
#endif #endif
#ifndef NONET #ifndef NONET
@ -3765,8 +3855,6 @@ static void M_DrawGenericMenu(void)
case IT_CVAR: case IT_CVAR:
{ {
consvar_t *cv = (consvar_t *)currentMenu->menuitems[i].itemaction; consvar_t *cv = (consvar_t *)currentMenu->menuitems[i].itemaction;
char asterisks[MAXSTRINGLENGTH+1];
size_t sl;
switch (currentMenu->menuitems[i].status & IT_CVARTYPE) switch (currentMenu->menuitems[i].status & IT_CVARTYPE)
{ {
case IT_CV_SLIDER: case IT_CV_SLIDER:
@ -3774,27 +3862,6 @@ static void M_DrawGenericMenu(void)
case IT_CV_NOPRINT: // color use this case IT_CV_NOPRINT: // color use this
case IT_CV_INVISSLIDER: // monitor toggles use this case IT_CV_INVISSLIDER: // monitor toggles use this
break; break;
case IT_CV_PASSWORD:
if (i == itemOn)
{
V_DrawRightAlignedThinString(x + MAXSTRINGLENGTH*8 + 10, y, V_ALLOWLOWERCASE, va(M_GetText("Tab: %s password"), cv->value ? "hide" : "show"));
}
if (!cv->value || i != itemOn)
{
sl = strlen(cv->string);
memset(asterisks, '*', sl);
memset(asterisks + sl, 0, MAXSTRINGLENGTH+1-sl);
M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1);
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, asterisks);
if (skullAnimCounter < 4 && i == itemOn)
V_DrawCharacter(x + 8 + V_StringWidth(asterisks, 0), y + 12,
'_' | 0x80, false);
y += 16;
break;
}
/* fallthru */
case IT_CV_STRING: case IT_CV_STRING:
M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1); M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1);
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string); V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string);
@ -4545,22 +4612,12 @@ static void M_StopMessage(INT32 choice)
// Defines what image is used in (menuitem_t)->text. // Defines what image is used in (menuitem_t)->text.
// You can even put multiple images in one menu! // You can even put multiple images in one menu!
static void M_DrawImageDef(void) static void M_DrawImageDef(void)
{
// this is probably what the V_DrawFixedPatch screen-fill bullshit was for, right
//V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); -- never mind, screen fade
// Grr. Need to autodetect for pic_ts.
pic_t *pictest = (pic_t *)W_CachePatchName(currentMenu->menuitems[itemOn].text,PU_CACHE);
if (!pictest->zero)
V_DrawScaledPic(0,0,0,W_GetNumForName(currentMenu->menuitems[itemOn].text));
else
{ {
patch_t *patch = W_CachePatchName(currentMenu->menuitems[itemOn].text,PU_CACHE); patch_t *patch = W_CachePatchName(currentMenu->menuitems[itemOn].text,PU_CACHE);
if (patch->height <= BASEVIDHEIGHT) if (patch->width <= BASEVIDWIDTH)
V_DrawScaledPatch(0,0,0,patch); V_DrawScaledPatch(0,0,0,patch);
else else
V_DrawSmallScaledPatch(0,0,0,patch); V_DrawSmallScaledPatch(0,0,0,patch);
}
if (currentMenu->menuitems[itemOn].alphaKey) if (currentMenu->menuitems[itemOn].alphaKey)
{ {
@ -4630,8 +4687,8 @@ static void M_AddonsOptions(INT32 choice)
M_SetupNextMenu(&OP_AddonsOptionsDef); M_SetupNextMenu(&OP_AddonsOptionsDef);
} }
#define LOCATIONSTRING1 "Visit \x83SRB2.ORG/MODS\x80 to get & make add-ons!" #define LOCATIONSTRING1 "Visit \x83SRB2.ORG/MODS\x80 to get & make addons!"
#define LOCATIONSTRING2 "Visit \x88SRB2.ORG/MODS\x80 to get & make add-ons!" #define LOCATIONSTRING2 "Visit \x88SRB2.ORG/MODS\x80 to get & make addons!"
static void M_Addons(INT32 choice) static void M_Addons(INT32 choice)
{ {
@ -4807,7 +4864,7 @@ static boolean M_AddonsRefresh(void)
{ {
S_StartSound(NULL, sfx_s26d); S_StartSound(NULL, sfx_s26d);
if (refreshdirmenu & REFRESHDIR_MAX) if (refreshdirmenu & REFRESHDIR_MAX)
message = va("%c%s\x80\nMaximum number of add-ons reached.\nA file could not be loaded.\nIf you wish to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); message = va("%c%s\x80\nMaximum number of addons reached.\nA file could not be loaded.\nIf you wish to play with this addon, restart the game to clear existing ones.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
else else
message = va("%c%s\x80\nA file was not loaded.\nCheck the console log for more information.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); message = va("%c%s\x80\nA file was not loaded.\nCheck the console log for more information.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
} }
@ -4819,7 +4876,7 @@ static boolean M_AddonsRefresh(void)
else if (majormods && !prevmajormods) else if (majormods && !prevmajormods)
{ {
S_StartSound(NULL, sfx_s221); S_StartSound(NULL, sfx_s221);
message = va("%c%s\x80\nGameplay has now been modified.\nIf you wish to play Record Attack mode, restart the game to clear existing add-ons.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); message = va("%c%s\x80\nGameplay has now been modified.\nIf you wish to play Record Attack mode, restart the game to clear existing addons.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
prevmajormods = majormods; prevmajormods = majormods;
} }
@ -5236,6 +5293,7 @@ void M_ReplayHut(INT32 choice)
G_SetGamestate(GS_TIMEATTACK); G_SetGamestate(GS_TIMEATTACK);
demo.rewinding = false; demo.rewinding = false;
CL_ClearRewinds();
S_ChangeMusicInternal("replst", true); S_ChangeMusicInternal("replst", true);
} }
@ -5248,7 +5306,8 @@ static void M_HandleReplayHutList(INT32 choice)
if (dir_on[menudepthleft]) if (dir_on[menudepthleft])
dir_on[menudepthleft]--; dir_on[menudepthleft]--;
else else
M_PrevOpt(); return;
//M_PrevOpt();
S_StartSound(NULL, sfx_menu1); S_StartSound(NULL, sfx_menu1);
replayScrollTitle = 0; replayScrollDelay = TICRATE; replayScrollDir = 1; replayScrollTitle = 0; replayScrollDelay = TICRATE; replayScrollDir = 1;
@ -5258,7 +5317,8 @@ static void M_HandleReplayHutList(INT32 choice)
if (dir_on[menudepthleft] < sizedirmenu-1) if (dir_on[menudepthleft] < sizedirmenu-1)
dir_on[menudepthleft]++; dir_on[menudepthleft]++;
else else
itemOn = 0; // Not M_NextOpt because that would take us to the extra dummy item return;
//itemOn = 0; // Not M_NextOpt because that would take us to the extra dummy item
S_StartSound(NULL, sfx_menu1); S_StartSound(NULL, sfx_menu1);
replayScrollTitle = 0; replayScrollDelay = TICRATE; replayScrollDir = 1; replayScrollTitle = 0; replayScrollDelay = TICRATE; replayScrollDir = 1;
@ -5711,7 +5771,7 @@ static void M_DrawReplayStartMenu(void)
case DFILE_ERROR_NOTLOADED: case DFILE_ERROR_NOTLOADED:
case DFILE_ERROR_INCOMPLETEOUTOFORDER: case DFILE_ERROR_INCOMPLETEOUTOFORDER:
warning = "Loading addons will mark your game as modified, and record attack may be unavailable.\nYou can watch without loading addons, but desyncs may occur."; warning = "Loading addons will mark your game as modified, and Record Attack may be unavailable.\nYou can watch without loading addons, but desyncs may occur.";
break; break;
case DFILE_ERROR_EXTRAFILES: case DFILE_ERROR_EXTRAFILES:
@ -5765,6 +5825,11 @@ static void M_DrawPlaybackMenu(void)
INT16 i; INT16 i;
patch_t *icon; patch_t *icon;
UINT8 *activemap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_GOLD, GTC_MENUCACHE); UINT8 *activemap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_GOLD, GTC_MENUCACHE);
UINT32 transmap = max(0, (INT32)(leveltime - playback_last_menu_interaction_leveltime - 4*TICRATE)) / 5;
transmap = min(8, transmap) << V_ALPHASHIFT;
if (leveltime - playback_last_menu_interaction_leveltime >= 6*TICRATE)
playback_last_menu_interaction_leveltime = leveltime - 6*TICRATE;
// Toggle items // Toggle items
if (paused && !demo.rewinding) if (paused && !demo.rewinding)
@ -5788,13 +5853,10 @@ static void M_DrawPlaybackMenu(void)
{ {
for (i = playback_viewcount; i <= playback_view4; i++) for (i = playback_viewcount; i <= playback_view4; i++)
PlaybackMenu[i].status = IT_DISABLED; PlaybackMenu[i].status = IT_DISABLED;
PlaybackMenu[playback_freecamera].alphaKey = 72;
PlaybackMenu[playback_quit].alphaKey = 88;
//PlaybackMenu[playback_moreoptions].alphaKey = 72; currentMenu->x = BASEVIDWIDTH/2 - 52;
//PlaybackMenu[playback_quit].alphaKey = 88;
PlaybackMenu[playback_quit].alphaKey = 72;
//currentMenu->x = BASEVIDWIDTH/2 - 52;
currentMenu->x = BASEVIDWIDTH/2 - 44;
} }
else else
{ {
@ -5805,11 +5867,8 @@ static void M_DrawPlaybackMenu(void)
for (i = splitscreen+1; i < 4; i++) for (i = splitscreen+1; i < 4; i++)
PlaybackMenu[playback_view1+i].status = IT_DISABLED; PlaybackMenu[playback_view1+i].status = IT_DISABLED;
//PlaybackMenu[playback_moreoptions].alphaKey = 156; PlaybackMenu[playback_freecamera].alphaKey = 156;
//PlaybackMenu[playback_quit].alphaKey = 172; PlaybackMenu[playback_quit].alphaKey = 172;
PlaybackMenu[playback_quit].alphaKey = 156;
//currentMenu->x = BASEVIDWIDTH/2 - 94;
currentMenu->x = BASEVIDWIDTH/2 - 88; currentMenu->x = BASEVIDWIDTH/2 - 88;
} }
@ -5846,16 +5905,16 @@ static void M_DrawPlaybackMenu(void)
icon = W_CachePatchName("PLAYRANK", PU_CACHE); // temp icon = W_CachePatchName("PLAYRANK", PU_CACHE); // temp
if ((i == playback_fastforward && cv_playbackspeed.value > 1) || (i == playback_rewind && demo.rewinding)) if ((i == playback_fastforward && cv_playbackspeed.value > 1) || (i == playback_rewind && demo.rewinding))
V_DrawMappedPatch(currentMenu->x + currentMenu->menuitems[i].alphaKey, currentMenu->y, V_SNAPTOTOP, icon, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_JAWZ, GTC_MENUCACHE)); V_DrawMappedPatch(currentMenu->x + currentMenu->menuitems[i].alphaKey, currentMenu->y, transmap|V_SNAPTOTOP, icon, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_JAWZ, GTC_MENUCACHE));
else else
V_DrawMappedPatch(currentMenu->x + currentMenu->menuitems[i].alphaKey, currentMenu->y, V_SNAPTOTOP, icon, (i == itemOn) ? activemap : inactivemap); V_DrawMappedPatch(currentMenu->x + currentMenu->menuitems[i].alphaKey, currentMenu->y, transmap|V_SNAPTOTOP, icon, (i == itemOn) ? activemap : inactivemap);
if (i == itemOn) if (i == itemOn)
{ {
V_DrawCharacter(currentMenu->x + currentMenu->menuitems[i].alphaKey + 4, currentMenu->y + 14, V_DrawCharacter(currentMenu->x + currentMenu->menuitems[i].alphaKey + 4, currentMenu->y + 14,
'\x1A' | V_SNAPTOTOP|highlightflags, false); '\x1A' | transmap|V_SNAPTOTOP|highlightflags, false);
V_DrawCenteredString(BASEVIDWIDTH/2, currentMenu->y + 18, V_SNAPTOTOP|V_ALLOWLOWERCASE, currentMenu->menuitems[i].text); V_DrawCenteredString(BASEVIDWIDTH/2, currentMenu->y + 18, transmap|V_SNAPTOTOP|V_ALLOWLOWERCASE, currentMenu->menuitems[i].text);
if ((currentMenu->menuitems[i].status & IT_TYPE) == IT_ARROWS) if ((currentMenu->menuitems[i].status & IT_TYPE) == IT_ARROWS)
{ {
@ -5863,11 +5922,11 @@ static void M_DrawPlaybackMenu(void)
if (!(i == playback_viewcount && splitscreen == 3)) if (!(i == playback_viewcount && splitscreen == 3))
V_DrawCharacter(BASEVIDWIDTH/2 - 4, currentMenu->y + 28 - (skullAnimCounter/5), V_DrawCharacter(BASEVIDWIDTH/2 - 4, currentMenu->y + 28 - (skullAnimCounter/5),
'\x1A' | V_SNAPTOTOP|highlightflags, false); // up arrow '\x1A' | transmap|V_SNAPTOTOP|highlightflags, false); // up arrow
if (!(i == playback_viewcount && splitscreen == 0)) if (!(i == playback_viewcount && splitscreen == 0))
V_DrawCharacter(BASEVIDWIDTH/2 - 4, currentMenu->y + 48 + (skullAnimCounter/5), V_DrawCharacter(BASEVIDWIDTH/2 - 4, currentMenu->y + 48 + (skullAnimCounter/5),
'\x1B' | V_SNAPTOTOP|highlightflags, false); // down arrow '\x1B' | transmap|V_SNAPTOTOP|highlightflags, false); // down arrow
switch (i) switch (i)
{ {
@ -5886,7 +5945,7 @@ static void M_DrawPlaybackMenu(void)
continue; continue;
} }
V_DrawCenteredString(BASEVIDWIDTH/2, currentMenu->y + 38, V_SNAPTOTOP|V_ALLOWLOWERCASE|highlightflags, str); V_DrawCenteredString(BASEVIDWIDTH/2, currentMenu->y + 38, transmap|V_SNAPTOTOP|V_ALLOWLOWERCASE|highlightflags, str);
} }
} }
} }
@ -5963,6 +6022,10 @@ static void M_PlaybackAdvance(INT32 choice)
static void M_PlaybackSetViews(INT32 choice) static void M_PlaybackSetViews(INT32 choice)
{ {
if (demo.freecam)
return; // not here.
if (choice > 0) if (choice > 0)
{ {
if (splitscreen < 3) if (splitscreen < 3)
@ -5980,6 +6043,33 @@ static void M_PlaybackAdjustView(INT32 choice)
G_AdjustView(itemOn - playback_viewcount, (choice > 0) ? 1 : -1, true); G_AdjustView(itemOn - playback_viewcount, (choice > 0) ? 1 : -1, true);
} }
// this one's rather tricky
static void M_PlaybackToggleFreecam(INT32 choice)
{
(void)choice;
M_ClearMenus(true);
// remove splitscreen:
splitscreen = 0;
R_ExecuteSetViewSize();
P_InitCameraCmd(); // init camera controls
if (!demo.freecam) // toggle on
{
demo.freecam = true;
democam.cam = &camera[0]; // this is rather useful
}
else // toggle off
{
demo.freecam = false;
// reset democam vars:
democam.cam = NULL;
democam.turnheld = false;
democam.keyboardlook = false; // reset only these. localangle / aiming gets set before the cam does anything anyway
}
}
static void M_PlaybackQuit(INT32 choice) static void M_PlaybackQuit(INT32 choice)
{ {
(void)choice; (void)choice;
@ -8128,7 +8218,7 @@ static void M_SetGuestReplay(INT32 choice)
which(0); which(0);
} }
static void M_ModeAttackRetry(INT32 choice) void M_ModeAttackRetry(INT32 choice)
{ {
(void)choice; (void)choice;
G_CheckDemoStatus(); // Cancel recording G_CheckDemoStatus(); // Cancel recording
@ -8398,6 +8488,7 @@ static void M_DrawConnectMenu(void)
V_DrawSmallString(currentMenu->x+112, S_LINEY(i)+8, globalflags, gt); V_DrawSmallString(currentMenu->x+112, S_LINEY(i)+8, globalflags, gt);
// display game speed for race gametypes
if (serverlist[slindex].info.gametype == GT_RACE) if (serverlist[slindex].info.gametype == GT_RACE)
{ {
spd = kartspeed_cons_t[serverlist[slindex].info.kartvars & SV_SPEEDMASK].strvalue; spd = kartspeed_cons_t[serverlist[slindex].info.kartvars & SV_SPEEDMASK].strvalue;
@ -8405,9 +8496,6 @@ static void M_DrawConnectMenu(void)
V_DrawSmallString(currentMenu->x+132, S_LINEY(i)+8, globalflags, va("(%s Speed)", spd)); V_DrawSmallString(currentMenu->x+132, S_LINEY(i)+8, globalflags, va("(%s Speed)", spd));
} }
if (serverlist[slindex].info.kartvars & SV_PASSWORD)
V_DrawFixedPatch((currentMenu->x - 9) << FRACBITS, (S_LINEY(i)) << FRACBITS, FRACUNIT, globalflags & (~V_ALLOWLOWERCASE), W_CachePatchName("SERVLOCK", PU_CACHE), NULL);
MP_ConnectMenu[i+FIRSTSERVERLINE].status = IT_STRING | IT_CALL; MP_ConnectMenu[i+FIRSTSERVERLINE].status = IT_STRING | IT_CALL;
} }
@ -8599,7 +8687,7 @@ static void M_ConnectMenuModChecks(INT32 choice)
if (modifiedgame) if (modifiedgame)
{ {
M_StartMessage(M_GetText("Add-ons are currently loaded.\n\nYou will only be able to join a server if\nit has the same ones loaded in the same order, which may be unlikely.\n\nIf you wish to play on other servers,\nrestart the game to clear existing add-ons.\n\n(Press a key)\n"),M_ConnectMenu,MM_EVENTHANDLER); M_StartMessage(M_GetText("Addons are currently loaded.\n\nYou will only be able to join a server if\nit has the same ones loaded in the same order, which may be unlikely.\n\nIf you wish to play on other servers,\nrestart the game to clear existing addons.\n\n(Press a key)\n"),M_ConnectMenu,MM_EVENTHANDLER);
return; return;
} }
@ -8737,11 +8825,6 @@ static void M_StartServer(INT32 choice)
// Still need to reset devmode // Still need to reset devmode
cv_debug = 0; cv_debug = 0;
if (strlen(cv_dummyjoinpassword.string) > 0)
D_SetJoinPassword(cv_dummyjoinpassword.string);
else
joinpasswordset = false;
if (demo.playback) if (demo.playback)
G_StopDemo(); G_StopDemo();
if (metalrecording) if (metalrecording)
@ -11157,25 +11240,6 @@ static void M_QuitSRB2(INT32 choice)
// OpenGL specific options // OpenGL specific options
// ===================================================================== // =====================================================================
#define FOG_COLOR_ITEM 1
// ===================
// M_OGL_DrawFogMenu()
// ===================
static void M_OGL_DrawFogMenu(void)
{
INT32 mx, my;
mx = currentMenu->x;
my = currentMenu->y;
M_DrawGenericMenu(); // use generic drawer for cursor, items and title
V_DrawString(BASEVIDWIDTH - mx - V_StringWidth(cv_grfogcolor.string, 0),
my + currentMenu->menuitems[FOG_COLOR_ITEM].alphaKey, highlightflags, cv_grfogcolor.string);
// blink cursor on FOG_COLOR_ITEM if selected
if (itemOn == FOG_COLOR_ITEM && skullAnimCounter < 4)
V_DrawCharacter(BASEVIDWIDTH - mx,
my + currentMenu->menuitems[FOG_COLOR_ITEM].alphaKey, '_' | 0x80,false);
}
// ===================== // =====================
// M_OGL_DrawColorMenu() // M_OGL_DrawColorMenu()
// ===================== // =====================
@ -11189,61 +11253,4 @@ static void M_OGL_DrawColorMenu(void)
V_DrawString(mx, my + currentMenu->menuitems[0].alphaKey - 10, V_DrawString(mx, my + currentMenu->menuitems[0].alphaKey - 10,
highlightflags, "Gamma correction"); highlightflags, "Gamma correction");
} }
//===================
// M_HandleFogColor()
//===================
static void M_HandleFogColor(INT32 choice)
{
size_t i, l;
char temp[8];
boolean exitmenu = false; // exit to previous menu and send name change
switch (choice)
{
case KEY_DOWNARROW:
S_StartSound(NULL, sfx_menu1);
itemOn++;
break;
case KEY_UPARROW:
S_StartSound(NULL, sfx_menu1);
itemOn--;
break;
case KEY_ESCAPE:
exitmenu = true;
break;
case KEY_BACKSPACE:
S_StartSound(NULL, sfx_menu1);
strcpy(temp, cv_grfogcolor.string);
strcpy(cv_grfogcolor.zstring, "000000");
l = strlen(temp)-1;
for (i = 0; i < l; i++)
cv_grfogcolor.zstring[i + 6 - l] = temp[i];
break;
default:
if ((choice >= '0' && choice <= '9') || (choice >= 'a' && choice <= 'f')
|| (choice >= 'A' && choice <= 'F'))
{
S_StartSound(NULL, sfx_menu1);
strcpy(temp, cv_grfogcolor.string);
strcpy(cv_grfogcolor.zstring, "000000");
l = strlen(temp);
for (i = 0; i < l; i++)
cv_grfogcolor.zstring[5 - i] = temp[l - i];
cv_grfogcolor.zstring[5] = (char)choice;
}
break;
}
if (exitmenu)
{
if (currentMenu->prevMenu)
M_SetupNextMenu(currentMenu->prevMenu);
else
M_ClearMenus(true);
}
}
#endif #endif

View file

@ -31,6 +31,9 @@
// Does all the real work of the menu interaction. // Does all the real work of the menu interaction.
boolean M_Responder(event_t *ev); boolean M_Responder(event_t *ev);
// Called by main loop, runs for demo playback. If this returns true, nullify any further user input.
boolean M_DemoResponder(event_t *ev);
// Called by main loop, only used for menu (skull cursor) animation. // Called by main loop, only used for menu (skull cursor) animation.
void M_Ticker(void); void M_Ticker(void);
@ -56,6 +59,9 @@ void M_SortServerList(void);
// Draws a box with a texture inside as background for messages // Draws a box with a texture inside as background for messages
void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines); void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines);
// Used in d_netcmd to restart time attack
void M_ModeAttackRetry(INT32 choice);
// the function to show a message box typing with the string inside // the function to show a message box typing with the string inside
// string must be static (not in the stack) // string must be static (not in the stack)
// routine is a function taking a INT32 in parameter // routine is a function taking a INT32 in parameter
@ -121,7 +127,6 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
#define IT_CV_NOPRINT 1536 #define IT_CV_NOPRINT 1536
#define IT_CV_NOMOD 2048 #define IT_CV_NOMOD 2048
#define IT_CV_INVISSLIDER 2560 #define IT_CV_INVISSLIDER 2560
#define IT_CV_PASSWORD 3072
//call/submenu specific //call/submenu specific
// There used to be a lot more here but ... // There used to be a lot more here but ...

View file

@ -30,6 +30,7 @@
#include "g_game.h" #include "g_game.h"
#include "m_misc.h" #include "m_misc.h"
#include "hu_stuff.h" #include "hu_stuff.h"
#include "st_stuff.h"
#include "v_video.h" #include "v_video.h"
#include "z_zone.h" #include "z_zone.h"
#include "g_input.h" #include "g_input.h"
@ -57,7 +58,7 @@ typedef off_t off64_t;
#endif #endif
#endif #endif
#if defined(__MINGW32__) && ((__GNUC__ > 7) || (__GNUC__ == 6 && __GNUC_MINOR__ >= 3)) #if defined(__MINGW32__) && ((__GNUC__ > 7) || (__GNUC__ == 6 && __GNUC_MINOR__ >= 3)) && (__GNUC__ < 8)
#define PRIdS "u" #define PRIdS "u"
#elif defined (_WIN32) #elif defined (_WIN32)
#define PRIdS "Iu" #define PRIdS "Iu"
@ -586,6 +587,21 @@ void M_SaveConfig(const char *filename)
fclose(f); fclose(f);
} }
// ==========================================================================
// SCREENSHOTS
// ==========================================================================
static UINT8 screenshot_palette[768];
static void M_CreateScreenShotPalette(void)
{
size_t i, j;
for (i = 0, j = 0; i < 768; i += 3, j++)
{
RGBA_t locpal = pLocalPalette[(max(st_palette,0)*256)+j];
screenshot_palette[i] = locpal.s.red;
screenshot_palette[i+1] = locpal.s.green;
screenshot_palette[i+2] = locpal.s.blue;
}
}
#if NUMSCREENS > 2 #if NUMSCREENS > 2
static const char *Newsnapshotfile(const char *pathname, const char *ext) static const char *Newsnapshotfile(const char *pathname, const char *ext)
@ -1017,6 +1033,7 @@ static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal)
static inline moviemode_t M_StartMovieAPNG(const char *pathname) static inline moviemode_t M_StartMovieAPNG(const char *pathname)
{ {
#ifdef USE_APNG #ifdef USE_APNG
UINT8 *palette;
const char *freename = NULL; const char *freename = NULL;
boolean ret = false; boolean ret = false;
@ -1032,10 +1049,8 @@ static inline moviemode_t M_StartMovieAPNG(const char *pathname)
return MM_OFF; return MM_OFF;
} }
if (rendermode == render_soft) if (rendermode == render_soft) M_CreateScreenShotPalette();
ret = M_SetupaPNG(va(pandf,pathname,freename), W_CacheLumpName(GetPalette(), PU_CACHE)); ret = M_SetupaPNG(va(pandf,pathname,freename), (palette = screenshot_palette));
else
ret = M_SetupaPNG(va(pandf,pathname,freename), NULL);
if (!ret) if (!ret)
{ {
@ -1100,12 +1115,8 @@ void M_StartMovie(void)
switch (cv_moviemode.value) switch (cv_moviemode.value)
{ {
case MM_GIF: case MM_GIF:
if (rendermode == render_soft)
{
moviemode = M_StartMovieGIF(pathname); moviemode = M_StartMovieGIF(pathname);
break; break;
}
/* FALLTHRU */
case MM_APNG: case MM_APNG:
moviemode = M_StartMovieAPNG(pathname); moviemode = M_StartMovieAPNG(pathname);
break; break;
@ -1238,7 +1249,7 @@ void M_StopMovie(void)
* \param data The image data. * \param data The image data.
* \param width Width of the picture. * \param width Width of the picture.
* \param height Height of the picture. * \param height Height of the picture.
* \param palette Palette of image data * \param palette Palette of image data.
* \note if palette is NULL, BGR888 format * \note if palette is NULL, BGR888 format
*/ */
boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette) boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette)
@ -1260,8 +1271,7 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const
return false; return false;
} }
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, PNG_error, PNG_warn);
PNG_error, PNG_warn);
if (!png_ptr) if (!png_ptr)
{ {
CONS_Debug(DBG_RENDER, "M_SavePNG: Error on initialize libpng\n"); CONS_Debug(DBG_RENDER, "M_SavePNG: Error on initialize libpng\n");
@ -1415,9 +1425,8 @@ void M_ScreenShot(void)
} }
/** Takes a screenshot. /** Takes a screenshot.
* The screenshot is saved as "kartxxxx.pcx" (or "kartxxxx.tga" in hardware * The screenshot is saved as "srb2xxxx.png" where xxxx is the lowest
* rendermode) where xxxx is the lowest four-digit number for which a file * four-digit number for which a file does not already exist.
* does not already exist.
* *
* \sa HWR_ScreenShot * \sa HWR_ScreenShot
*/ */
@ -1431,6 +1440,10 @@ void M_DoScreenShot(void)
// Don't take multiple screenshots, obviously // Don't take multiple screenshots, obviously
takescreenshot = false; takescreenshot = false;
// how does one take a screenshot without a render system?
if (rendermode == render_none)
return;
if (cv_screenshot_option.value == 0) if (cv_screenshot_option.value == 0)
pathname = usehome ? srb2home : srb2path; pathname = usehome ? srb2home : srb2path;
else if (cv_screenshot_option.value == 1) else if (cv_screenshot_option.value == 1)
@ -1441,16 +1454,13 @@ void M_DoScreenShot(void)
pathname = cv_screenshot_folder.string; pathname = cv_screenshot_folder.string;
#ifdef USE_PNG #ifdef USE_PNG
if (rendermode != render_none)
freename = Newsnapshotfile(pathname,"png"); freename = Newsnapshotfile(pathname,"png");
#else #else
if (rendermode == render_soft) if (rendermode == render_soft)
freename = Newsnapshotfile(pathname,"pcx"); freename = Newsnapshotfile(pathname,"pcx");
else if (rendermode != render_none) else if (rendermode == render_opengl)
freename = Newsnapshotfile(pathname,"tga"); freename = Newsnapshotfile(pathname,"tga");
#endif #endif
else
I_Error("Can't take a screenshot without a render system");
if (rendermode == render_soft) if (rendermode == render_soft)
{ {
@ -1464,18 +1474,16 @@ void M_DoScreenShot(void)
// save the pcx file // save the pcx file
#ifdef HWRENDER #ifdef HWRENDER
if (rendermode != render_soft) if (rendermode == render_opengl)
ret = HWR_Screenshot(va(pandf,pathname,freename)); ret = HWR_Screenshot(va(pandf,pathname,freename));
else else
#endif #endif
if (rendermode != render_none)
{ {
M_CreateScreenShotPalette();
#ifdef USE_PNG #ifdef USE_PNG
ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, screenshot_palette);
W_CacheLumpName(GetPalette(), PU_CACHE));
#else #else
ret = WritePCXfile(va(pandf,pathname,freename), linear, vid.width, vid.height, ret = WritePCXfile(va(pandf,pathname,freename), linear, vid.width, vid.height, screenshot_palette);
W_CacheLumpName(GetPalette(), PU_CACHE));
#endif #endif
} }
@ -1483,14 +1491,14 @@ failure:
if (ret) if (ret)
{ {
if (moviemode != MM_SCREENSHOT) if (moviemode != MM_SCREENSHOT)
CONS_Printf(M_GetText("screen shot %s saved in %s\n"), freename, pathname); CONS_Printf(M_GetText("Screen shot %s saved in %s\n"), freename, pathname);
} }
else else
{ {
if (freename) if (freename)
CONS_Printf(M_GetText("Couldn't create screen shot %s in %s\n"), freename, pathname); CONS_Alert(CONS_ERROR, M_GetText("Couldn't create screen shot %s in %s\n"), freename, pathname);
else else
CONS_Printf(M_GetText("Couldn't create screen shot (all 10000 slots used!) in %s\n"), pathname); CONS_Alert(CONS_ERROR, M_GetText("Couldn't create screen shot in %s (all 10000 slots used!)\n"), pathname);
if (moviemode == MM_SCREENSHOT) if (moviemode == MM_SCREENSHOT)
M_StopMovie(); M_StopMovie();

View file

@ -160,7 +160,7 @@ void NDS3D_DrawPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts
z = pOutVerts[index].z; z = pOutVerts[index].z;
} }
glTexCoord2f(pOutVerts[index].sow, pOutVerts[index].tow); glTexCoord2f(pOutVerts[index].s, pOutVerts[index].tow);
glVertex3f(x,y,z); glVertex3f(x,y,z);
} }
glEnd(); glEnd();

View file

@ -3929,6 +3929,9 @@ static inline boolean PIT_GrenadeRing(mobj_t *thing)
if (!grenade) if (!grenade)
return false; return false;
if (grenade->flags2 & MF2_DEBRIS)
return false;
if (thing->type != MT_PLAYER) // Don't explode for anything but an actual player. if (thing->type != MT_PLAYER) // Don't explode for anything but an actual player.
return true; return true;
@ -3977,6 +3980,9 @@ void A_GrenadeRing(mobj_t *actor)
return; return;
#endif #endif
if (actor->flags2 & MF2_DEBRIS)
return;
if (actor->state == &states[S_SSMINE_DEPLOY8]) if (actor->state == &states[S_SSMINE_DEPLOY8])
explodedist = (3*explodedist)/2; explodedist = (3*explodedist)/2;
@ -4001,6 +4007,9 @@ static inline boolean PIT_MineExplode(mobj_t *thing)
if (!grenade || P_MobjWasRemoved(grenade)) if (!grenade || P_MobjWasRemoved(grenade))
return false; // There's the possibility these can chain react onto themselves after they've already died if there are enough all in one spot return false; // There's the possibility these can chain react onto themselves after they've already died if there are enough all in one spot
if (grenade->flags2 & MF2_DEBRIS) // don't explode twice
return false;
if (thing == grenade || thing->type == MT_MINEEXPLOSIONSOUND) // Don't explode yourself! Endless loop! if (thing == grenade || thing->type == MT_MINEEXPLOSIONSOUND) // Don't explode yourself! Endless loop!
return true; return true;
@ -4023,8 +4032,6 @@ static inline boolean PIT_MineExplode(mobj_t *thing)
thing->z - grenade->z) > explodedist) thing->z - grenade->z) > explodedist)
return true; // Too far away return true; // Too far away
grenade->flags2 |= MF2_DEBRIS;
if (thing->player) // Looks like we're going to have to need a seperate function for this too if (thing->player) // Looks like we're going to have to need a seperate function for this too
K_ExplodePlayer(thing->player, grenade->target, grenade); K_ExplodePlayer(thing->player, grenade->target, grenade);
else else
@ -4045,6 +4052,9 @@ void A_MineExplode(mobj_t *actor)
return; return;
#endif #endif
if (actor->flags2 & MF2_DEBRIS)
return;
type = (mobjtype_t)locvar1; type = (mobjtype_t)locvar1;
// Use blockmap to check for nearby shootables // Use blockmap to check for nearby shootables
@ -4053,6 +4063,8 @@ void A_MineExplode(mobj_t *actor)
xh = (unsigned)(actor->x + explodedist - bmaporgx)>>MAPBLOCKSHIFT; xh = (unsigned)(actor->x + explodedist - bmaporgx)>>MAPBLOCKSHIFT;
xl = (unsigned)(actor->x - explodedist - bmaporgx)>>MAPBLOCKSHIFT; xl = (unsigned)(actor->x - explodedist - bmaporgx)>>MAPBLOCKSHIFT;
BMBOUNDFIX (xl, xh, yl, yh);
grenade = actor; grenade = actor;
for (by = yl; by <= yh; by++) for (by = yl; by <= yh; by++)
@ -4068,6 +4080,8 @@ void A_MineExplode(mobj_t *actor)
K_SpawnMineExplosion(actor, SKINCOLOR_KETCHUP); K_SpawnMineExplosion(actor, SKINCOLOR_KETCHUP);
P_SpawnMobj(actor->x, actor->y, actor->z, MT_MINEEXPLOSIONSOUND); P_SpawnMobj(actor->x, actor->y, actor->z, MT_MINEEXPLOSIONSOUND);
actor->flags2 |= MF2_DEBRIS; // Set this flag to ensure that the explosion won't be effective more than 1 frame.
} }
//} //}

View file

@ -2036,7 +2036,7 @@ boolean P_CheckRacers(void)
if (i == MAXPLAYERS) // finished if (i == MAXPLAYERS) // finished
{ {
countdown = countdown2 = 0; racecountdown = exitcountdown = 0;
return true; return true;
} }
@ -2063,13 +2063,13 @@ boolean P_CheckRacers(void)
if (j == MAXPLAYERS) // finish anyways, force a time over if (j == MAXPLAYERS) // finish anyways, force a time over
{ {
P_DoTimeOver(&players[i]); P_DoTimeOver(&players[i]);
countdown = countdown2 = 0; racecountdown = exitcountdown = 0;
return true; return true;
} }
} }
} }
if (!countdown) // Check to see if the winners have finished, to set countdown. if (!racecountdown) // Check to see if the winners have finished, to set countdown.
{ {
UINT8 numingame = 0, numexiting = 0; UINT8 numingame = 0, numexiting = 0;
UINT8 winningpos = 1; UINT8 winningpos = 1;
@ -2088,7 +2088,7 @@ boolean P_CheckRacers(void)
winningpos++; winningpos++;
if (numexiting >= winningpos) if (numexiting >= winningpos)
countdown = (((netgame || multiplayer) ? cv_countdowntime.value : 30)*TICRATE) + 1; // 30 seconds to finish, get going! racecountdown = (((netgame || multiplayer) ? cv_countdowntime.value : 30)*TICRATE) + 1; // 30 seconds to finish, get going!
} }
return false; return false;

View file

@ -109,6 +109,20 @@ typedef struct camera_s
fixed_t pan; fixed_t pan;
} camera_t; } camera_t;
// demo freecam or something before i commit die
struct demofreecam_s {
camera_t *cam; // this is useful when the game is paused, notably
mobj_t *soundmobj; // mobj to play sound from, used in s_sound
angle_t localangle; // keeps track of the cam angle for cmds
angle_t localaiming; // ditto with aiming
boolean turnheld; // holding turn button for gradual turn speed
boolean keyboardlook; // keyboard look
};
extern struct demofreecam_s democam;
extern camera_t camera[MAXSPLITSCREENPLAYERS]; extern camera_t camera[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_cam_dist, cv_cam_still, cv_cam_height; extern consvar_t cv_cam_dist, cv_cam_still, cv_cam_height;
extern consvar_t cv_cam_speed, cv_cam_rotate, cv_cam_rotspeed; extern consvar_t cv_cam_speed, cv_cam_rotate, cv_cam_rotspeed;
@ -133,7 +147,9 @@ void P_AddPlayerScore(player_t *player, UINT32 amount);
void P_ResetCamera(player_t *player, camera_t *thiscam); void P_ResetCamera(player_t *player, camera_t *thiscam);
boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam); boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam);
void P_SlideCameraMove(camera_t *thiscam); void P_SlideCameraMove(camera_t *thiscam);
void P_DemoCameraMovement(camera_t *cam);
boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled); boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled);
void P_InitCameraCmd(void);
boolean P_PlayerInPain(player_t *player); boolean P_PlayerInPain(player_t *player);
void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor); void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor);
void P_ResetPlayer(player_t *player); void P_ResetPlayer(player_t *player);

View file

@ -732,7 +732,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (tmthing->z + tmthing->height < thing->z) if (tmthing->z + tmthing->height < thing->z)
return true; // underneath return true; // underneath
if (((tmthing->target == thing) || (tmthing->target == thing->target)) && (tmthing->threshold > 0 || (thing->type != MT_PLAYER && thing->threshold > 0))) if (((tmthing->target == thing) || (tmthing->target == thing->target)) && ((tmthing->threshold > 0 && thing->type == MT_PLAYER) || (thing->type != MT_PLAYER && thing->threshold > 0)))
return true; return true;
if (tmthing->health <= 0 || thing->health <= 0) if (tmthing->health <= 0 || thing->health <= 0)

View file

@ -3264,8 +3264,8 @@ static void P_NetArchiveMisc(void)
WRITEINT16(save_p, scrambletotal); WRITEINT16(save_p, scrambletotal);
WRITEINT16(save_p, scramblecount); WRITEINT16(save_p, scramblecount);
WRITEUINT32(save_p, countdown); WRITEUINT32(save_p, racecountdown);
WRITEUINT32(save_p, countdown2); WRITEUINT32(save_p, exitcountdown);
WRITEFIXED(save_p, gravity); WRITEFIXED(save_p, gravity);
WRITEFIXED(save_p, mapobjectscale); WRITEFIXED(save_p, mapobjectscale);
@ -3373,8 +3373,8 @@ static inline boolean P_NetUnArchiveMisc(void)
scrambletotal = READINT16(save_p); scrambletotal = READINT16(save_p);
scramblecount = READINT16(save_p); scramblecount = READINT16(save_p);
countdown = READUINT32(save_p); racecountdown = READUINT32(save_p);
countdown2 = READUINT32(save_p); exitcountdown = READUINT32(save_p);
gravity = READFIXED(save_p); gravity = READFIXED(save_p);
mapobjectscale = READFIXED(save_p); mapobjectscale = READFIXED(save_p);

View file

@ -465,11 +465,7 @@ static void P_LoadRawSegs(UINT8 *data, size_t i)
li->length = P_SegLength(li); li->length = P_SegLength(li);
#ifdef HWRENDER #ifdef HWRENDER
if (rendermode == render_opengl) if (rendermode == render_opengl)
{
li->flength = P_SegLengthFloat(li); li->flength = P_SegLengthFloat(li);
//Hurdler: 04/12/2000: for now, only used in hardware mode
li->lightmaps = NULL; // list of static lightmap for this seg
}
li->pv1 = li->pv2 = NULL; li->pv1 = li->pv2 = NULL;
#endif #endif
@ -1407,11 +1403,12 @@ static inline void P_LoadSideDefs(lumpnum_t lumpnum)
P_LoadRawSideDefs(W_LumpLength(lumpnum)); P_LoadRawSideDefs(W_LumpLength(lumpnum));
} }
static void P_LoadRawSideDefs2(void *data) static void P_LoadRawSideDefs2(void *data)
{ {
UINT16 i; UINT16 i;
INT32 num; INT32 num;
size_t j;
UINT32 cr, cg, cb;
for (i = 0; i < numsides; i++) for (i = 0; i < numsides; i++)
{ {
@ -1490,16 +1487,43 @@ static void P_LoadRawSideDefs2(void *data)
{ {
col = msd->toptexture; col = msd->toptexture;
sec->extra_colormap->rgba = // encore mode colormaps!
(HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0) + // do it like software by aproximating a color to a palette index, and then convert it to its encore variant and then back to a color code.
(HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8) + // do this for both the start and fade colormaps.
(HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16);
cr = (HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0);
cg = (HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8);
cb = (HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16);
#ifdef GLENCORE
if (encoremap)
{
j = encoremap[NearestColor((UINT8)cr, (UINT8)cg, (UINT8)cb)];
//CONS_Printf("R_CreateColormap: encoremap[%d] = %d\n", j, encoremap[j]); -- moved encoremap upwards for optimisation
cr = pLocalPalette[j].s.red;
cg = pLocalPalette[j].s.green;
cb = pLocalPalette[j].s.blue;
}
#endif
sec->extra_colormap->rgba = cr + cg + cb;
// alpha // alpha
if (msd->toptexture[7]) if (msd->toptexture[7])
sec->extra_colormap->rgba += (ALPHA2INT(col[7]) << 24); sec->extra_colormap->rgba += (ALPHA2INT(col[7]) << 24);
else else
sec->extra_colormap->rgba += (25 << 24); sec->extra_colormap->rgba += (25 << 24);
/*nearest = NearestColor(
(HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0),
(HEX2INT(col[3]) << 4) + (HEX2INT(col[4]) << 0),
(HEX2INT(col[5]) << 4) + (HEX2INT(col[6]) << 0)
);
sec->extra_colormap->rgba =
pLocalPalette[nearest].s.red +
(pLocalPalette[nearest].s.green << 8) +
(pLocalPalette[nearest].s.blue << 16);*/
} }
else else
sec->extra_colormap->rgba = 0; sec->extra_colormap->rgba = 0;
@ -1508,10 +1532,24 @@ static void P_LoadRawSideDefs2(void *data)
{ {
col = msd->bottomtexture; col = msd->bottomtexture;
sec->extra_colormap->fadergba = // do the exact same thing as above here.
(HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0) +
(HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8) + cr = (HEX2INT(col[1]) << 4) + (HEX2INT(col[2]) << 0);
(HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16); cg = (HEX2INT(col[3]) << 12) + (HEX2INT(col[4]) << 8);
cb = (HEX2INT(col[5]) << 20) + (HEX2INT(col[6]) << 16);
#ifdef GLENCORE
if (encoremap)
{
j = encoremap[NearestColor((UINT8)cr, (UINT8)cg, (UINT8)cb)];
//CONS_Printf("R_CreateColormap: encoremap[%d] = %d\n", j, encoremap[j]); -- moved encoremap upwards for optimisation
cr = pLocalPalette[j].s.red;
cg = pLocalPalette[j].s.green;
cb = pLocalPalette[j].s.blue;
}
#endif
sec->extra_colormap->fadergba = cr + cg + cb;
// alpha // alpha
if (msd->bottomtexture[7]) if (msd->bottomtexture[7])
@ -1658,6 +1696,7 @@ static void P_LoadRawSideDefs2(void *data)
R_ClearTextureNumCache(true); R_ClearTextureNumCache(true);
} }
// Delay loading texture names until after loaded linedefs. // Delay loading texture names until after loaded linedefs.
static void P_LoadSideDefs2(lumpnum_t lumpnum) static void P_LoadSideDefs2(lumpnum_t lumpnum)
{ {
@ -2344,7 +2383,7 @@ static void P_LevelInitStuff(void)
players[i].lives = 1; // SRB2Kart players[i].lives = 1; // SRB2Kart
#endif #endif
players[i].realtime = countdown = countdown2 = 0; players[i].realtime = racecountdown = exitcountdown = 0;
curlap = bestlap = 0; // SRB2Kart curlap = bestlap = 0; // SRB2Kart
players[i].gotcontinue = false; players[i].gotcontinue = false;
@ -2850,10 +2889,12 @@ boolean P_SetupLevel(boolean skipprecip)
// Encore mode fade to pink to white // Encore mode fade to pink to white
// This is handled BEFORE sounds are stopped. // This is handled BEFORE sounds are stopped.
if (rendermode != render_none && encoremode && !prevencoremode && !demo.rewinding) if (encoremode && !prevencoremode && !demo.rewinding)
{ {
tic_t locstarttime, endtime, nowtime; tic_t locstarttime, endtime, nowtime;
if (rendermode != render_none)
{
S_StopMusic(); // er, about that... S_StopMusic(); // er, about that...
S_StartSound(NULL, sfx_ruby1); S_StartSound(NULL, sfx_ruby1);
@ -2869,6 +2910,12 @@ boolean P_SetupLevel(boolean skipprecip)
F_WipeEndScreen(); F_WipeEndScreen();
F_RunWipe(wipedefs[wipe_level_final], false); F_RunWipe(wipedefs[wipe_level_final], false);
}
else //dedicated servers can call this now, to wait the appropriate amount of time for clients to wipe
{
F_RunWipe(wipedefs[wipe_speclevel_towhite], false);
F_RunWipe(wipedefs[wipe_level_final], false);
}
locstarttime = nowtime = lastwipetic; locstarttime = nowtime = lastwipetic;
endtime = locstarttime + (3*TICRATE)/2; endtime = locstarttime + (3*TICRATE)/2;
@ -2902,7 +2949,9 @@ boolean P_SetupLevel(boolean skipprecip)
// Let's fade to white here // Let's fade to white here
// But only if we didn't do the encore startup wipe // But only if we didn't do the encore startup wipe
if (rendermode != render_none && !ranspecialwipe && !demo.rewinding) if (!ranspecialwipe && !demo.rewinding)
{
if(rendermode != render_none)
{ {
F_WipeStartScreen(); F_WipeStartScreen();
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol);
@ -2910,6 +2959,11 @@ boolean P_SetupLevel(boolean skipprecip)
F_WipeEndScreen(); F_WipeEndScreen();
F_RunWipe(wipedefs[(encoremode ? wipe_level_final : wipe_level_toblack)], false); F_RunWipe(wipedefs[(encoremode ? wipe_level_final : wipe_level_toblack)], false);
} }
else //dedicated servers
{
F_RunWipe(wipedefs[(encoremode ? wipe_level_final : wipe_level_toblack)], false);
}
}
// Reset the palette now all fades have been done // Reset the palette now all fades have been done
if (rendermode != render_none) if (rendermode != render_none)
@ -3089,10 +3143,6 @@ boolean P_SetupLevel(boolean skipprecip)
#ifdef HWRENDER // not win32 only 19990829 by Kin #ifdef HWRENDER // not win32 only 19990829 by Kin
if (rendermode != render_soft && rendermode != render_none) if (rendermode != render_soft && rendermode != render_none)
{ {
#ifdef ALAM_LIGHTING
// BP: reset light between levels (we draw preview frame lights on current frame)
HWR_ResetLights();
#endif
// Correct missing sidedefs & deep water trick // Correct missing sidedefs & deep water trick
HWR_CorrectSWTricks(); HWR_CorrectSWTricks();
HWR_CreatePlanePolygons((INT32)numnodes - 1); HWR_CreatePlanePolygons((INT32)numnodes - 1);
@ -3201,6 +3251,7 @@ boolean P_SetupLevel(boolean skipprecip)
if (!dedicated) if (!dedicated)
{ {
if (!demo.freecam)
for (i = 0; i <= splitscreen; i++) for (i = 0; i <= splitscreen; i++)
P_SetupCamera(displayplayers[i], &camera[i]); P_SetupCamera(displayplayers[i], &camera[i]);
@ -3328,7 +3379,7 @@ boolean P_SetupLevel(boolean skipprecip)
if (loadprecip) // uglier hack if (loadprecip) // uglier hack
{ // to make a newly loaded level start on the second frame. { // to make a newly loaded level start on the second frame.
INT32 buf = gametic % BACKUPTICS; INT32 buf = gametic % TICQUEUE;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {
if (playeringame[i]) if (playeringame[i])

View file

@ -1944,6 +1944,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
|| specialtype == 318 // Unlockable trigger - Once || specialtype == 318 // Unlockable trigger - Once
|| specialtype == 320 // Unlockable - Once || specialtype == 320 // Unlockable - Once
|| specialtype == 321 || specialtype == 322 // Trigger on X calls - Continuous + Each Time || specialtype == 321 || specialtype == 322 // Trigger on X calls - Continuous + Each Time
|| specialtype == 323 // Record attack only - Once
|| specialtype == 328 // Encore Load || specialtype == 328 // Encore Load
|| specialtype == 399) // Level Load || specialtype == 399) // Level Load
triggerline->special = 0; // Clear it out triggerline->special = 0; // Clear it out
@ -1981,6 +1982,7 @@ void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller)
if (lines[masterline].special == 313 if (lines[masterline].special == 313
|| lines[masterline].special == 399 || lines[masterline].special == 399
|| lines[masterline].special == 328 || lines[masterline].special == 328
|| lines[masterline].special == 323
// Each-time executors handle themselves, too // Each-time executors handle themselves, too
|| lines[masterline].special == 301 // Each time || lines[masterline].special == 301 // Each time
|| lines[masterline].special == 306 // Character ability - Each time || lines[masterline].special == 306 // Character ability - Each time
@ -3812,12 +3814,14 @@ DoneSection2:
{ {
const fixed_t hscale = mapobjectscale + (mapobjectscale - player->mo->scale); const fixed_t hscale = mapobjectscale + (mapobjectscale - player->mo->scale);
const fixed_t minspeed = 24*hscale; const fixed_t minspeed = 24*hscale;
angle_t pushangle = FixedHypot(player->mo->momx, player->mo->momy) ? R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy) : player->mo->angle;
// if we have no speed for SOME REASON, use the player's angle, otherwise we'd be forcefully thrusted to what I can only assume is angle 0
if (player->mo->eflags & MFE_SPRUNG) if (player->mo->eflags & MFE_SPRUNG)
break; break;
if (player->speed < minspeed) // Push forward to prevent getting stuck if (player->speed < minspeed) // Push forward to prevent getting stuck
P_InstaThrust(player->mo, player->mo->angle, minspeed); P_InstaThrust(player->mo, pushangle, minspeed);
player->kartstuff[k_pogospring] = 1; player->kartstuff[k_pogospring] = 1;
K_DoPogoSpring(player->mo, 0, 1); K_DoPogoSpring(player->mo, 0, 1);
@ -3833,14 +3837,16 @@ DoneSection2:
const fixed_t hscale = mapobjectscale + (mapobjectscale - player->mo->scale); const fixed_t hscale = mapobjectscale + (mapobjectscale - player->mo->scale);
const fixed_t minspeed = 24*hscale; const fixed_t minspeed = 24*hscale;
const fixed_t maxspeed = 28*hscale; const fixed_t maxspeed = 28*hscale;
angle_t pushangle = FixedHypot(player->mo->momx, player->mo->momy) ? R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy) : player->mo->angle;
// if we have no speed for SOME REASON, use the player's angle, otherwise we'd be forcefully thrusted to what I can only assume is angle 0
if (player->mo->eflags & MFE_SPRUNG) if (player->mo->eflags & MFE_SPRUNG)
break; break;
if (player->speed > maxspeed) // Prevent overshooting jumps if (player->speed > maxspeed) // Prevent overshooting jumps
P_InstaThrust(player->mo, R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy), maxspeed); P_InstaThrust(player->mo, pushangle, maxspeed);
else if (player->speed < minspeed) // Push forward to prevent getting stuck else if (player->speed < minspeed) // Push forward to prevent getting stuck
P_InstaThrust(player->mo, player->mo->angle, minspeed); P_InstaThrust(player->mo, pushangle, minspeed);
player->kartstuff[k_pogospring] = 2; player->kartstuff[k_pogospring] = 2;
K_DoPogoSpring(player->mo, 0, 1); K_DoPogoSpring(player->mo, 0, 1);
@ -5654,7 +5660,7 @@ static void P_RunLevelLoadExecutors(void)
for (i = 0; i < numlines; i++) for (i = 0; i < numlines; i++)
{ {
if (lines[i].special == 399 || lines[i].special == 328) if (lines[i].special == 399 || lines[i].special == 328 || lines[i].special == 323)
P_RunTriggerLinedef(&lines[i], NULL, NULL); P_RunTriggerLinedef(&lines[i], NULL, NULL);
} }
} }
@ -6554,6 +6560,11 @@ void P_SpawnSpecials(INT32 fromnetsave)
P_AddEachTimeThinker(&sectors[sec], &lines[i]); P_AddEachTimeThinker(&sectors[sec], &lines[i]);
} }
break; break;
// Record attack only linedef exec
case 323:
if (!modeattacking)
lines[i].special = 0;
break;
case 328: // Encore-only linedef execute on map load case 328: // Encore-only linedef execute on map load
if (!encoremode) if (!encoremode)

View file

@ -597,6 +597,8 @@ void P_Ticker(boolean run)
leveltime = (leveltime-1) & ~3; leveltime = (leveltime-1) & ~3;
G_PreviewRewind(leveltime); G_PreviewRewind(leveltime);
} }
else if (demo.freecam && democam.cam) // special case: allow freecam to MOVE during pause!
P_DemoCameraMovement(democam.cam);
return; return;
} }
@ -689,6 +691,9 @@ void P_Ticker(boolean run)
if (run) if (run)
leveltime++; leveltime++;
// as this is mostly used for HUD stuff, add the record attack specific hack to it as well!
if (!(modeattacking && !demo.playback) || leveltime >= starttime - TICRATE*4)
timeinmap++; timeinmap++;
/*if (G_TagGametype()) /*if (G_TagGametype())
@ -715,15 +720,15 @@ void P_Ticker(boolean run)
} }
} }
if (countdown > 1) if (racecountdown > 1)
countdown--; racecountdown--;
if (countdown2) if (exitcountdown > 1)
countdown2--; exitcountdown--;
if (indirectitemcooldown) if (indirectitemcooldown > 1)
indirectitemcooldown--; indirectitemcooldown--;
if (hyubgone) if (hyubgone > 1)
hyubgone--; hyubgone--;
if (G_BattleGametype()) if (G_BattleGametype())

View file

@ -29,6 +29,7 @@
#include "m_random.h" #include "m_random.h"
#include "m_misc.h" #include "m_misc.h"
#include "i_video.h" #include "i_video.h"
#include "i_joy.h"
#include "p_slopes.h" #include "p_slopes.h"
#include "p_spec.h" #include "p_spec.h"
#include "r_splats.h" #include "r_splats.h"
@ -1726,8 +1727,8 @@ void P_DoPlayerExit(player_t *player)
P_EndingMusic(player); P_EndingMusic(player);
// SRB2kart 120217 // SRB2kart 120217
//if (!countdown2) //if (!exitcountdown)
//countdown2 = countdown + 8*TICRATE; //exitcountdown = racecountdown + 8*TICRATE;
if (P_CheckRacers()) if (P_CheckRacers())
player->exiting = raceexittime+1; player->exiting = raceexittime+1;
@ -7087,7 +7088,7 @@ static void P_DeathThink(player_t *player)
} }
// Keep time rolling // Keep time rolling
if (!(countdown2 && !countdown) && !(player->exiting || mapreset) && !(player->pflags & PF_TIMEOVER)) if (!(exitcountdown && !racecountdown) && !(player->exiting || mapreset) && !(player->pflags & PF_TIMEOVER))
{ {
if (leveltime >= starttime) if (leveltime >= starttime)
{ {
@ -7204,11 +7205,249 @@ fixed_t t_cam4_rotate = -42;
#define MAXCAMERADIST 140*FRACUNIT // Max distance the camera can be in front of the player (2D mode) #define MAXCAMERADIST 140*FRACUNIT // Max distance the camera can be in front of the player (2D mode)
// Heavily simplified version of G_BuildTicCmd that only takes the local first player's control input and converts it to readable ticcmd_t
// we then throw that ticcmd garbage in the camera and make it move
// redefine this
static fixed_t forwardmove[2] = {25<<FRACBITS>>16, 50<<FRACBITS>>16};
static fixed_t sidemove[2] = {2<<FRACBITS>>16, 4<<FRACBITS>>16};
static fixed_t angleturn[3] = {KART_FULLTURN/2, KART_FULLTURN, KART_FULLTURN/4}; // + slow turn
static ticcmd_t cameracmd;
struct demofreecam_s democam;
// called by m_menu to reinit cam input every time it's toggled
void P_InitCameraCmd(void)
{
memset(&cameracmd, 0, sizeof(ticcmd_t)); // initialize cmd
}
static ticcmd_t *P_CameraCmd(camera_t *cam)
{
INT32 laim, th, tspeed, forward, side, axis; //i
const INT32 speed = 1;
// these ones used for multiple conditions
boolean turnleft, turnright, mouseaiming;
boolean invertmouse, lookaxis, usejoystick, kbl;
angle_t lang;
INT32 player_invert;
INT32 screen_invert;
ticcmd_t *cmd = &cameracmd;
(void)cam;
if (!demo.playback)
return cmd; // empty cmd, no.
lang = democam.localangle;
laim = democam.localaiming;
th = democam.turnheld;
kbl = democam.keyboardlook;
G_CopyTiccmd(cmd, I_BaseTiccmd(), 1); // empty, or external driver
cmd->angleturn = (INT16)(lang >> 16);
cmd->aiming = G_ClipAimingPitch(&laim);
mouseaiming = true;
invertmouse = cv_invertmouse.value;
lookaxis = cv_lookaxis.value;
usejoystick = true;
turnright = InputDown(gc_turnright, 1);
turnleft = InputDown(gc_turnleft, 1);
axis = JoyAxis(AXISTURN, 1);
if (encoremode)
{
turnright ^= turnleft; // swap these using three XORs
turnleft ^= turnright;
turnright ^= turnleft;
axis = -axis;
}
if (axis != 0)
{
turnright = turnright || (axis > 0);
turnleft = turnleft || (axis < 0);
}
forward = side = 0;
// use two stage accelerative turning
// on the keyboard and joystick
if (turnleft || turnright)
th += 1;
else
th = 0;
if (th < SLOWTURNTICS)
tspeed = 2; // slow turn
else
tspeed = speed;
// let movement keys cancel each other out
if (turnright && !(turnleft))
{
cmd->angleturn = (INT16)(cmd->angleturn - (angleturn[tspeed]));
side += sidemove[1];
}
else if (turnleft && !(turnright))
{
cmd->angleturn = (INT16)(cmd->angleturn + (angleturn[tspeed]));
side -= sidemove[1];
}
cmd->angleturn = (INT16)(cmd->angleturn - ((mousex*(encoremode ? -1 : 1)*8)));
axis = JoyAxis(AXISMOVE, 1);
if (InputDown(gc_accelerate, 1) || (usejoystick && axis > 0))
cmd->buttons |= BT_ACCELERATE;
axis = JoyAxis(AXISBRAKE, 1);
if (InputDown(gc_brake, 1) || (usejoystick && axis > 0))
cmd->buttons |= BT_BRAKE;
axis = JoyAxis(AXISAIM, 1);
if (InputDown(gc_aimforward, 1) || (usejoystick && axis < 0))
forward += forwardmove[1];
if (InputDown(gc_aimbackward, 1) || (usejoystick && axis > 0))
forward -= forwardmove[1];
// fire with any button/key
axis = JoyAxis(AXISFIRE, 1);
if (InputDown(gc_fire, 1) || (usejoystick && axis > 0))
cmd->buttons |= BT_ATTACK;
// spectator aiming shit, ahhhh...
player_invert = invertmouse ? -1 : 1;
screen_invert = 1; // nope
// mouse look stuff (mouse look is not the same as mouse aim)
kbl = false;
// looking up/down
laim += (mlooky<<19)*player_invert*screen_invert;
axis = JoyAxis(AXISLOOK, 1);
// spring back if not using keyboard neither mouselookin'
if (!kbl && !lookaxis && !mouseaiming)
laim = 0;
if (InputDown(gc_lookup, 1) || (axis < 0))
{
laim += KB_LOOKSPEED * screen_invert;
kbl = true;
}
else if (InputDown(gc_lookdown, 1) || (axis > 0))
{
laim -= KB_LOOKSPEED * screen_invert;
kbl = true;
}
if (InputDown(gc_centerview, 1)) // No need to put a spectator limit on this one though :V
laim = 0;
cmd->aiming = G_ClipAimingPitch(&laim);
mousex = mousey = mlooky = 0;
if (forward > MAXPLMOVE)
forward = MAXPLMOVE;
else if (forward < -MAXPLMOVE)
forward = -MAXPLMOVE;
if (side > MAXPLMOVE)
side = MAXPLMOVE;
else if (side < -MAXPLMOVE)
side = -MAXPLMOVE;
if (forward || side)
{
cmd->forwardmove = (SINT8)(cmd->forwardmove + forward);
cmd->sidemove = (SINT8)(cmd->sidemove + side);
}
lang += (cmd->angleturn<<16);
democam.localangle = lang;
democam.localaiming = laim;
democam.turnheld = th;
democam.keyboardlook = kbl;
return cmd;
}
void P_DemoCameraMovement(camera_t *cam)
{
ticcmd_t *cmd;
angle_t thrustangle;
mobj_t *awayviewmobj_hack;
player_t *lastp;
// update democam stuff with what we got here:
democam.cam = cam;
democam.localangle = cam->angle;
democam.localaiming = cam->aiming;
// first off we need to get button input
cmd = P_CameraCmd(cam);
cam->aiming = cmd->aiming<<FRACBITS;
cam->angle = cmd->angleturn<<16;
// camera movement:
if (cmd->buttons & BT_ACCELERATE)
cam->z += 32*mapobjectscale;
else if (cmd->buttons & BT_BRAKE)
cam->z -= 32*mapobjectscale;
// if you hold item, you will lock on to displayplayer. (The last player you were ""f12-ing"")
if (cmd->buttons & BT_ATTACK)
{
lastp = &players[displayplayers[0]]; // Fun fact, I was trying displayplayers[0]->mo as if it was Lua like an absolute idiot.
cam->angle = R_PointToAngle2(cam->x, cam->y, lastp->mo->x, lastp->mo->y);
cam->aiming = R_PointToAngle2(0, cam->z, R_PointToDist2(cam->x, cam->y, lastp->mo->x, lastp->mo->y), lastp->mo->z + lastp->mo->scale*128*P_MobjFlip(lastp->mo)); // This is still unholy. Aim a bit above their heads.
}
cam->momx = cam->momy = cam->momz = 0;
if (cmd->forwardmove != 0)
{
thrustangle = cam->angle >> ANGLETOFINESHIFT;
cam->x += FixedMul(cmd->forwardmove*mapobjectscale, FINECOSINE(thrustangle));
cam->y += FixedMul(cmd->forwardmove*mapobjectscale, FINESINE(thrustangle));
cam->z += FixedMul(cmd->forwardmove*mapobjectscale, AIMINGTOSLOPE(cam->aiming));
// momentums are useless here, directly add to the coordinates
// this.......... doesn't actually check for floors and walls and whatnot but the function to do that is a pure mess so fuck that.
// besides freecam going inside walls sounds pretty cool on paper.
}
// awayviewmobj hack; this is to prevent us from hearing sounds from the player's perspective
awayviewmobj_hack = P_SpawnMobj(cam->x, cam->y, cam->z, MT_THOK);
awayviewmobj_hack->tics = 2;
awayviewmobj_hack->flags2 |= MF2_DONTDRAW;
democam.soundmobj = awayviewmobj_hack;
// update subsector to avoid crashes;
cam->subsector = R_PointInSubsector(cam->x, cam->y);
}
void P_ResetCamera(player_t *player, camera_t *thiscam) void P_ResetCamera(player_t *player, camera_t *thiscam)
{ {
tic_t tries = 0; tic_t tries = 0;
fixed_t x, y, z; fixed_t x, y, z;
if (demo.freecam)
return; // do not reset the camera there.
if (!player->mo) if (!player->mo)
return; return;
@ -7263,6 +7502,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
subsector_t *newsubsec; subsector_t *newsubsec;
#endif #endif
democam.soundmobj = NULL; // reset this each frame, we don't want the game crashing for stupid reasons now do we
// We probably shouldn't move the camera if there is no player or player mobj somehow // We probably shouldn't move the camera if there is no player or player mobj somehow
if (!player || !player->mo) if (!player || !player->mo)
return true; return true;
@ -7271,6 +7512,12 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
if (thiscam->subsector == NULL || thiscam->subsector->sector == NULL) if (thiscam->subsector == NULL || thiscam->subsector->sector == NULL)
return true; return true;
if (demo.freecam)
{
P_DemoCameraMovement(thiscam);
return true;
}
mo = player->mo; mo = player->mo;
#ifndef NOCLIPCAM #ifndef NOCLIPCAM
@ -7426,7 +7673,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
const INT32 timeovercam = max(0, min(180, (player->kartstuff[k_timeovercam] - 2*TICRATE)*15)); const INT32 timeovercam = max(0, min(180, (player->kartstuff[k_timeovercam] - 2*TICRATE)*15));
camrotate += timeovercam; camrotate += timeovercam;
} }
else if (leveltime < introtime) // Whoooshy camera! else if (leveltime < introtime && !(modeattacking && !demo.playback)) // Whoooshy camera! (don't do this in RA when we PLAY, still do it in replays however~)
{ {
const INT32 introcam = (introtime - leveltime); const INT32 introcam = (introtime - leveltime);
camrotate += introcam*5; camrotate += introcam*5;
@ -8057,8 +8304,8 @@ void P_DoTimeOver(player_t *player)
P_EndingMusic(player); P_EndingMusic(player);
if (!countdown2) if (!exitcountdown)
countdown2 = 5*TICRATE; exitcountdown = 5*TICRATE;
} }
// //
@ -8201,7 +8448,7 @@ void P_PlayerThink(player_t *player)
// begin the drown music for countdown! // begin the drown music for countdown!
// SRB2Kart: despite how perfect this is, it's disabled FOR A REASON // SRB2Kart: despite how perfect this is, it's disabled FOR A REASON
/*if (countdown == 11*TICRATE - 1) /*if (racecountdown == 11*TICRATE - 1)
{ {
if (P_IsLocalPlayer(player)) if (P_IsLocalPlayer(player))
S_ChangeMusicInternal("drown", false); S_ChangeMusicInternal("drown", false);
@ -8209,7 +8456,7 @@ void P_PlayerThink(player_t *player)
// If you've hit the countdown and you haven't made // If you've hit the countdown and you haven't made
// it to the exit, you're a goner! // it to the exit, you're a goner!
else if (countdown == 1 && !player->exiting && !player->spectator && player->lives > 0) else if (racecountdown == 1 && !player->exiting && !player->spectator && player->lives > 0)
{ {
P_DoTimeOver(player); P_DoTimeOver(player);
@ -8223,10 +8470,10 @@ void P_PlayerThink(player_t *player)
if (player->exiting > 1 && (player->exiting < raceexittime+2 || !G_RaceGametype())) // SRB2kart - "&& player->exiting > 1" if (player->exiting > 1 && (player->exiting < raceexittime+2 || !G_RaceGametype())) // SRB2kart - "&& player->exiting > 1"
player->exiting--; player->exiting--;
if (player->exiting && countdown2) if (player->exiting && exitcountdown)
player->exiting = 99; // SRB2kart player->exiting = 99; // SRB2kart
if (player->exiting == 2 || countdown2 == 2) if (player->exiting == 2 || exitcountdown == 2)
{ {
if (cv_playersforexit.value) // Count to be sure everyone's exited if (cv_playersforexit.value) // Count to be sure everyone's exited
{ {

View file

@ -37,7 +37,7 @@ drawseg_t *ds_p = NULL;
// indicates doors closed wrt automap bugfix: // indicates doors closed wrt automap bugfix:
INT32 doorclosed; INT32 doorclosed;
static boolean R_NoEncore(sector_t *sector, boolean ceiling) boolean R_NoEncore(sector_t *sector, boolean ceiling)
{ {
boolean invertencore = (GETSECSPECIAL(sector->special, 2) == 15); boolean invertencore = (GETSECSPECIAL(sector->special, 2) == 15);
#if 0 // perfect implementation #if 0 // perfect implementation

View file

@ -40,6 +40,10 @@ void R_ClearDrawSegs(void);
void R_RenderBSPNode(INT32 bspnum); void R_RenderBSPNode(INT32 bspnum);
void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2); void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2);
// determines when a given sector shouldn't abide by the encoremap's palette.
// no longer a static since this is used for encore in hw_main.c as well now:
boolean R_NoEncore(sector_t *sector, boolean ceiling);
#ifdef POLYOBJECTS #ifdef POLYOBJECTS
void R_SortPolyObjects(subsector_t *sub); void R_SortPolyObjects(subsector_t *sub);

View file

@ -198,7 +198,7 @@ static UINT8 *R_GenerateTexture(size_t texnum)
int x, x1, x2, i; int x, x1, x2, i;
size_t blocksize; size_t blocksize;
column_t *patchcol; column_t *patchcol;
UINT32 *colofs; UINT8 *colofs;
I_Assert(texnum <= (size_t)numtextures); I_Assert(texnum <= (size_t)numtextures);
texture = textures[texnum]; texture = textures[texnum];
@ -219,10 +219,10 @@ static UINT8 *R_GenerateTexture(size_t texnum)
// Check the patch for holes. // Check the patch for holes.
if (texture->width > SHORT(realpatch->width) || texture->height > SHORT(realpatch->height)) if (texture->width > SHORT(realpatch->width) || texture->height > SHORT(realpatch->height))
holey = true; holey = true;
colofs = (UINT32 *)realpatch->columnofs; colofs = (UINT8 *)realpatch->columnofs;
for (x = 0; x < texture->width && !holey; x++) for (x = 0; x < texture->width && !holey; x++)
{ {
column_t *col = (column_t *)((UINT8 *)realpatch + LONG(colofs[x])); column_t *col = (column_t *)((UINT8 *)realpatch + LONG(*(UINT32 *)&colofs[x<<2]));
INT32 topdelta, prevdelta = -1, y = 0; INT32 topdelta, prevdelta = -1, y = 0;
while (col->topdelta != 0xff) while (col->topdelta != 0xff)
{ {
@ -250,11 +250,11 @@ static UINT8 *R_GenerateTexture(size_t texnum)
texturememory += blocksize; texturememory += blocksize;
// use the patch's column lookup // use the patch's column lookup
colofs = (UINT32 *)(void *)(block + 8); colofs = (block + 8);
texturecolumnofs[texnum] = colofs; texturecolumnofs[texnum] = (UINT32 *)colofs;
blocktex = block; blocktex = block;
for (x = 0; x < texture->width; x++) for (x = 0; x < texture->width; x++)
colofs[x] = LONG(LONG(colofs[x]) + 3); *(UINT32 *)&colofs[x<<2] = LONG(LONG(*(UINT32 *)&colofs[x<<2]) + 3);
goto done; goto done;
} }
@ -270,8 +270,8 @@ static UINT8 *R_GenerateTexture(size_t texnum)
memset(block, 0xF7, blocksize+1); // Transparency hack memset(block, 0xF7, blocksize+1); // Transparency hack
// columns lookup table // columns lookup table
colofs = (UINT32 *)(void *)block; colofs = block;
texturecolumnofs[texnum] = colofs; texturecolumnofs[texnum] = (UINT32 *)colofs;
// texture data after the lookup table // texture data after the lookup table
blocktex = block + (texture->width*4); blocktex = block + (texture->width*4);
@ -296,8 +296,8 @@ static UINT8 *R_GenerateTexture(size_t texnum)
patchcol = (column_t *)((UINT8 *)realpatch + LONG(realpatch->columnofs[x-x1])); patchcol = (column_t *)((UINT8 *)realpatch + LONG(realpatch->columnofs[x-x1]));
// generate column ofset lookup // generate column ofset lookup
colofs[x] = LONG((x * texture->height) + (texture->width*4)); *(UINT32 *)&colofs[x<<2] = LONG((x * texture->height) + (texture->width*4));
R_DrawColumnInCache(patchcol, block + LONG(colofs[x]), patch->originy, texture->height); R_DrawColumnInCache(patchcol, block + LONG(*(UINT32 *)&colofs[x<<2]), patch->originy, texture->height);
} }
} }
@ -1177,7 +1177,6 @@ void R_ClearColormaps(void)
// //
static double deltas[256][3], map[256][3]; static double deltas[256][3], map[256][3];
static UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);
static int RoundUp(double number); static int RoundUp(double number);
#ifdef HASINVERT #ifdef HASINVERT
@ -1403,7 +1402,7 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3)
// Thanks to quake2 source! // Thanks to quake2 source!
// utils3/qdata/images.c // utils3/qdata/images.c
static UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b) UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b)
{ {
int dr, dg, db; int dr, dg, db;
int distortion, bestdistortion = 256 * 256 * 4, bestcolor = 0, i; int distortion, bestdistortion = 256 * 256 * 4, bestcolor = 0, i;

View file

@ -98,6 +98,10 @@ void R_MakeInvertmap(void);
#endif #endif
const char *R_ColormapNameForNum(INT32 num); const char *R_ColormapNameForNum(INT32 num);
UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);
extern INT32 numtextures; extern INT32 numtextures;
UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);
#endif #endif

View file

@ -526,31 +526,6 @@ typedef struct mprecipsecnode_s
boolean visited; // used in search algorithms boolean visited; // used in search algorithms
} mprecipsecnode_t; } mprecipsecnode_t;
// for now, only used in hardware mode
// maybe later for software as well?
// that's why it's moved here
typedef struct light_s
{
UINT16 type; // light,... (cfr #define in hwr_light.c)
float light_xoffset;
float light_yoffset; // y offset to adjust corona's height
UINT32 corona_color; // color of the light for static lighting
float corona_radius; // radius of the coronas
UINT32 dynamic_color; // color of the light for dynamic lighting
float dynamic_radius; // radius of the light ball
float dynamic_sqrradius; // radius^2 of the light ball
} light_t;
typedef struct lightmap_s
{
float s[2], t[2];
light_t *light;
struct lightmap_s *next;
} lightmap_t;
// //
// The lineseg. // The lineseg.
// //
@ -579,8 +554,6 @@ typedef struct seg_s
void *pv1; // polyvertex_t void *pv1; // polyvertex_t
void *pv2; // polyvertex_t void *pv2; // polyvertex_t
float flength; // length of the seg, used by hardware renderer float flength; // length of the seg, used by hardware renderer
lightmap_t *lightmaps; // for static lightmap
#endif #endif
// Why slow things down by calculating lightlists for every thick side? // Why slow things down by calculating lightlists for every thick side?

View file

@ -137,7 +137,7 @@ static CV_PossibleValue_t drawdist_precip_cons_t[] = {
{1024, "1024"}, {1536, "1536"}, {2048, "2048"}, {1024, "1024"}, {1536, "1536"}, {2048, "2048"},
{0, "None"}, {0, NULL}}; {0, "None"}, {0, NULL}};
static CV_PossibleValue_t fov_cons_t[] = {{0, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}}; static CV_PossibleValue_t fov_cons_t[] = {{5*FRACUNIT, "MIN"}, {178*FRACUNIT, "MAX"}, {0, NULL}};
//static CV_PossibleValue_t precipdensity_cons_t[] = {{0, "None"}, {1, "Light"}, {2, "Moderate"}, {4, "Heavy"}, {6, "Thick"}, {8, "V.Thick"}, {0, NULL}}; //static CV_PossibleValue_t precipdensity_cons_t[] = {{0, "None"}, {1, "Light"}, {2, "Moderate"}, {4, "Heavy"}, {6, "Thick"}, {8, "V.Thick"}, {0, NULL}};
static CV_PossibleValue_t translucenthud_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}}; static CV_PossibleValue_t translucenthud_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}};
@ -181,7 +181,9 @@ consvar_t cv_drawdist = {"drawdist", "Infinite", CV_SAVE, drawdist_cons_t, NULL,
//consvar_t cv_drawdist_nights = {"drawdist_nights", "2048", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; //consvar_t cv_drawdist_nights = {"drawdist_nights", "2048", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_drawdist_precip = {"drawdist_precip", "1024", CV_SAVE, drawdist_precip_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_drawdist_precip = {"drawdist_precip", "1024", CV_SAVE, drawdist_precip_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
//consvar_t cv_precipdensity = {"precipdensity", "Moderate", CV_SAVE, precipdensity_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; //consvar_t cv_precipdensity = {"precipdensity", "Moderate", CV_SAVE, precipdensity_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_fov = {"fov", "90", CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange, 0, NULL, NULL, 0, 0, NULL};
// cap fov, fov too high tears software apart.
consvar_t cv_fov = {"fov", "90", CV_FLOAT|CV_CALL|CV_SAVE, fov_cons_t, Fov_OnChange, 0, NULL, NULL, 0, 0, NULL};
// Okay, whoever said homremoval causes a performance hit should be shot. // Okay, whoever said homremoval causes a performance hit should be shot.
consvar_t cv_homremoval = {"homremoval", "Yes", CV_SAVE, homremoval_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_homremoval = {"homremoval", "Yes", CV_SAVE, homremoval_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -540,9 +542,9 @@ static void R_InitTextureMapping(void)
for (i = 0; i < FINEANGLES/2; i++) for (i = 0; i < FINEANGLES/2; i++)
{ {
if (FINETANGENT(i) > FRACUNIT*2) if (FINETANGENT(i) > fovtan*2)
t = -1; t = -1;
else if (FINETANGENT(i) < -FRACUNIT*2) else if (FINETANGENT(i) < -fovtan*2)
t = viewwidth+1; t = viewwidth+1;
else else
{ {
@ -686,11 +688,6 @@ void R_ExecuteSetViewSize(void)
R_InitTextureMapping(); R_InitTextureMapping();
#ifdef HWRENDER
if (rendermode != render_soft)
HWR_InitTextureMapping();
#endif
// thing clipping // thing clipping
for (i = 0; i < viewwidth; i++) for (i = 0; i < viewwidth; i++)
screenheightarray[i] = (INT16)viewheight; screenheightarray[i] = (INT16)viewheight;
@ -820,29 +817,31 @@ subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y)
static mobj_t *viewmobj; static mobj_t *viewmobj;
// WARNING: a should be unsigned but to add with 2048, it isn't!
#define AIMINGTODY(a) FixedDiv((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160)>>FRACBITS, fovtan)
// recalc necessary stuff for mouseaiming // recalc necessary stuff for mouseaiming
// slopes are already calculated for the full possible view (which is 4*viewheight). // slopes are already calculated for the full possible view (which is 4*viewheight).
// 18/08/18: (No it's actually 16*viewheight, thanks Jimita for finding this out) // 18/08/18: (No it's actually 16*viewheight, thanks Jimita for finding this out)
static void R_SetupFreelook(void) static void R_SetupFreelook(void)
{ {
INT32 dy = 0; INT32 dy = 0;
if (rendermode == render_soft)
{
// clip it in the case we are looking a hardware 90 degrees full aiming // clip it in the case we are looking a hardware 90 degrees full aiming
// (lmps, network and use F12...) // (lmps, network and use F12...)
if (rendermode == render_soft
#ifdef HWRENDER
|| cv_grshearing.value
#endif
)
G_SoftwareClipAimingPitch((INT32 *)&aimingangle); G_SoftwareClipAimingPitch((INT32 *)&aimingangle);
dy = AIMINGTODY(aimingangle) * viewwidth/BASEVIDWIDTH;
if (rendermode == render_soft)
{
dy = (AIMINGTODY(aimingangle)/fovtan) * viewwidth/BASEVIDWIDTH;
yslope = &yslopetab[viewheight*8 - (viewheight/2 + dy)]; yslope = &yslopetab[viewheight*8 - (viewheight/2 + dy)];
} }
centery = (viewheight/2) + dy; centery = (viewheight/2) + dy;
centeryfrac = centery<<FRACBITS; centeryfrac = centery<<FRACBITS;
} }
#undef AIMINGTODY
void R_SkyboxFrame(player_t *player) void R_SkyboxFrame(player_t *player)
{ {
camera_t *thiscam = &camera[0]; camera_t *thiscam = &camera[0];
@ -1176,7 +1175,7 @@ void R_SetupFrame(player_t *player, boolean skybox)
viewx += quake.x; viewx += quake.x;
viewy += quake.y; viewy += quake.y;
if (thiscam->subsector) if (thiscam->subsector && thiscam->subsector->sector)
viewsector = thiscam->subsector->sector; viewsector = thiscam->subsector->sector;
else else
viewsector = R_PointInSubsector(viewx, viewy)->sector; viewsector = R_PointInSubsector(viewx, viewy)->sector;
@ -1188,7 +1187,7 @@ void R_SetupFrame(player_t *player, boolean skybox)
viewx += quake.x; viewx += quake.x;
viewy += quake.y; viewy += quake.y;
if (viewmobj->subsector) if (viewmobj->subsector && thiscam->subsector->sector)
viewsector = viewmobj->subsector->sector; viewsector = viewmobj->subsector->sector;
else else
viewsector = R_PointInSubsector(viewx, viewy)->sector; viewsector = R_PointInSubsector(viewx, viewy)->sector;
@ -1551,9 +1550,6 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_grgammagreen); CV_RegisterVar(&cv_grgammagreen);
CV_RegisterVar(&cv_grgammared); CV_RegisterVar(&cv_grgammared);
CV_RegisterVar(&cv_grfovchange); CV_RegisterVar(&cv_grfovchange);
CV_RegisterVar(&cv_grfog);
CV_RegisterVar(&cv_grfogcolor);
CV_RegisterVar(&cv_grsoftwarefog);
#ifdef ALAM_LIGHTING #ifdef ALAM_LIGHTING
CV_RegisterVar(&cv_grstaticlighting); CV_RegisterVar(&cv_grstaticlighting);
CV_RegisterVar(&cv_grdynamiclighting); CV_RegisterVar(&cv_grdynamiclighting);
@ -1563,6 +1559,9 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_grmdls); CV_RegisterVar(&cv_grmdls);
CV_RegisterVar(&cv_grfallbackplayermodel); CV_RegisterVar(&cv_grfallbackplayermodel);
CV_RegisterVar(&cv_grspritebillboarding); CV_RegisterVar(&cv_grspritebillboarding);
CV_RegisterVar(&cv_grfakecontrast);
CV_RegisterVar(&cv_grshearing);
CV_RegisterVar(&cv_grshaders);
#endif #endif
#ifdef HWRENDER #ifdef HWRENDER

View file

@ -259,6 +259,7 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef,
//BP: we cannot use special tric in hardware mode because feet in ground caused by z-buffer //BP: we cannot use special tric in hardware mode because feet in ground caused by z-buffer
if (rendermode != render_none) // not for psprite if (rendermode != render_none) // not for psprite
spritecachedinfo[numspritelumps].topoffset += 4<<FRACBITS; spritecachedinfo[numspritelumps].topoffset += 4<<FRACBITS;
// Being selective with this causes bad things. :( Like the special stage tokens breaking apart. // Being selective with this causes bad things. :( Like the special stage tokens breaking apart.
/*if (rendermode != render_none // not for psprite /*if (rendermode != render_none // not for psprite
&& SHORT(patch.topoffset)>0 && SHORT(patch.topoffset)<SHORT(patch.height)) && SHORT(patch.topoffset)>0 && SHORT(patch.topoffset)<SHORT(patch.height))
@ -1711,6 +1712,9 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
INT32 lightnum; INT32 lightnum;
fixed_t approx_dist, limit_dist; fixed_t approx_dist, limit_dist;
INT32 splitflags; // check if a mobj has spliscreen flags
boolean split_drawsprite; // used for splitscreen flags
if (rendermode != render_soft) if (rendermode != render_soft)
return; return;
@ -1744,27 +1748,36 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
{ {
for (thing = sec->thinglist; thing; thing = thing->snext) for (thing = sec->thinglist; thing; thing = thing->snext)
{ {
split_drawsprite = false;
if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW) if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)
continue; continue;
if (splitscreen) splitflags = thing->eflags & (MFE_DRAWONLYFORP1|MFE_DRAWONLYFORP2|MFE_DRAWONLYFORP3|MFE_DRAWONLYFORP4);
if (splitscreen && splitflags)
{ {
if (thing->eflags & MFE_DRAWONLYFORP1) if (thing->eflags & MFE_DRAWONLYFORP1)
if (viewssnum != 0) if (viewssnum == 0)
continue; split_drawsprite = true;
if (thing->eflags & MFE_DRAWONLYFORP2) if (thing->eflags & MFE_DRAWONLYFORP2)
if (viewssnum != 1) if (viewssnum == 1)
continue; split_drawsprite = true;
if (thing->eflags & MFE_DRAWONLYFORP3 && splitscreen > 1) if (thing->eflags & MFE_DRAWONLYFORP3 && splitscreen > 1)
if (viewssnum != 2) if (viewssnum == 2)
continue; split_drawsprite = true;
if (thing->eflags & MFE_DRAWONLYFORP4 && splitscreen > 2) if (thing->eflags & MFE_DRAWONLYFORP4 && splitscreen > 2)
if (viewssnum != 3) if (viewssnum == 3)
continue; split_drawsprite = true;
} }
else
split_drawsprite = true;
if (!split_drawsprite)
continue;
approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y); approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
@ -1779,27 +1792,37 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
// Draw everything in sector, no checks // Draw everything in sector, no checks
for (thing = sec->thinglist; thing; thing = thing->snext) for (thing = sec->thinglist; thing; thing = thing->snext)
{ {
split_drawsprite = false;
if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW) if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)
continue; continue;
if (splitscreen) splitflags = thing->eflags & (MFE_DRAWONLYFORP1|MFE_DRAWONLYFORP2|MFE_DRAWONLYFORP3|MFE_DRAWONLYFORP4);
if (splitscreen && splitflags)
{ {
if (thing->eflags & MFE_DRAWONLYFORP1) if (thing->eflags & MFE_DRAWONLYFORP1)
if (viewssnum != 0) if (viewssnum == 0)
continue; split_drawsprite = true;
if (thing->eflags & MFE_DRAWONLYFORP2) if (thing->eflags & MFE_DRAWONLYFORP2)
if (viewssnum != 1) if (viewssnum == 1)
continue; split_drawsprite = true;
if (thing->eflags & MFE_DRAWONLYFORP3 && splitscreen > 1) if (thing->eflags & MFE_DRAWONLYFORP3 && splitscreen > 1)
if (viewssnum != 2) if (viewssnum == 2)
continue; split_drawsprite = true;
if (thing->eflags & MFE_DRAWONLYFORP4 && splitscreen > 2) if (thing->eflags & MFE_DRAWONLYFORP4 && splitscreen > 2)
if (viewssnum != 3) if (viewssnum == 3)
continue; split_drawsprite = true;
} }
else
split_drawsprite = true;
if (!split_drawsprite)
continue;
R_ProjectSprite(thing); R_ProjectSprite(thing);
} }

View file

@ -38,7 +38,7 @@ extern INT32 msg_id;
#include "p_local.h" // camera info #include "p_local.h" // camera info
#include "m_misc.h" // for tunes command #include "m_misc.h" // for tunes command
#if defined(HAVE_BLUA) && defined(HAVE_LUA_MUSICPLUS) #ifdef HAVE_BLUA
#include "lua_hook.h" // MusicChange hook #include "lua_hook.h" // MusicChange hook
#endif #endif
@ -442,7 +442,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
listener_t listener3 = {0,0,0,0}; listener_t listener3 = {0,0,0,0};
listener_t listener4 = {0,0,0,0}; listener_t listener4 = {0,0,0,0};
mobj_t *listenmobj = players[displayplayers[0]].mo; mobj_t *listenmobj = democam.soundmobj ? : players[displayplayers[0]].mo;
mobj_t *listenmobj2 = NULL; mobj_t *listenmobj2 = NULL;
mobj_t *listenmobj3 = NULL; mobj_t *listenmobj3 = NULL;
mobj_t *listenmobj4 = NULL; mobj_t *listenmobj4 = NULL;
@ -903,7 +903,7 @@ void S_UpdateSounds(void)
listener_t listener3; listener_t listener3;
listener_t listener4; listener_t listener4;
mobj_t *listenmobj = players[displayplayers[0]].mo; mobj_t *listenmobj = democam.soundmobj ? : players[displayplayers[0]].mo;
mobj_t *listenmobj2 = NULL; mobj_t *listenmobj2 = NULL;
mobj_t *listenmobj3 = NULL; mobj_t *listenmobj3 = NULL;
mobj_t *listenmobj4 = NULL; mobj_t *listenmobj4 = NULL;
@ -1989,7 +1989,7 @@ void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32
return; return;
strncpy(newmusic, mmusic, 7); strncpy(newmusic, mmusic, 7);
#if defined(HAVE_BLUA) && defined(HAVE_LUA_MUSICPLUS) #ifdef HAVE_BLUA
if(LUAh_MusicChange(music_name, newmusic, &mflags, &looping, &position, &prefadems, &fadeinms)) if(LUAh_MusicChange(music_name, newmusic, &mflags, &looping, &position, &prefadems, &fadeinms))
return; return;
#endif #endif

View file

@ -93,6 +93,7 @@
<Import Project="..\..\libs\libpng.props" /> <Import Project="..\..\libs\libpng.props" />
<Import Project="..\..\libs\SDL2.props" /> <Import Project="..\..\libs\SDL2.props" />
<Import Project="..\..\libs\SDL_mixer.props" /> <Import Project="..\..\libs\SDL_mixer.props" />
<Import Project="..\..\libs\libgme.props" />
<Import Project="Srb2SDL.props" /> <Import Project="Srb2SDL.props" />
</ImportGroup> </ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
@ -222,7 +223,6 @@
<ClInclude Include="..\hardware\hw_defs.h" /> <ClInclude Include="..\hardware\hw_defs.h" />
<ClInclude Include="..\hardware\hw_dll.h" /> <ClInclude Include="..\hardware\hw_dll.h" />
<ClInclude Include="..\hardware\hw_drv.h" /> <ClInclude Include="..\hardware\hw_drv.h" />
<ClInclude Include="..\hardware\hw_glide.h" />
<ClInclude Include="..\hardware\hw_glob.h" /> <ClInclude Include="..\hardware\hw_glob.h" />
<ClInclude Include="..\hardware\hw_light.h" /> <ClInclude Include="..\hardware\hw_light.h" />
<ClInclude Include="..\hardware\hw_main.h" /> <ClInclude Include="..\hardware\hw_main.h" />

View file

@ -231,9 +231,6 @@
<ClInclude Include="..\hardware\hw_drv.h"> <ClInclude Include="..\hardware\hw_drv.h">
<Filter>Hw_Hardware</Filter> <Filter>Hw_Hardware</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\hardware\hw_glide.h">
<Filter>Hw_Hardware</Filter>
</ClInclude>
<ClInclude Include="..\hardware\hw_glob.h"> <ClInclude Include="..\hardware\hw_glob.h">
<Filter>Hw_Hardware</Filter> <Filter>Hw_Hardware</Filter>
</ClInclude> </ClInclude>

View file

@ -2410,10 +2410,6 @@
RelativePath="..\hardware\hw_drv.h" RelativePath="..\hardware\hw_drv.h"
> >
</File> </File>
<File
RelativePath="..\hardware\hw_glide.h"
>
</File>
<File <File
RelativePath="..\hardware\hw_glob.h" RelativePath="..\hardware\hw_glob.h"
> >

View file

@ -576,10 +576,6 @@ SOURCE=..\hardware\hw_drv.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\hardware\hw_glide.h
# End Source File
# Begin Source File
SOURCE=..\hardware\hw_glob.h SOURCE=..\hardware\hw_glob.h
# End Source File # End Source File
# Begin Source File # Begin Source File

View file

@ -5,7 +5,10 @@
<PropertyGroup /> <PropertyGroup />
<ItemDefinitionGroup> <ItemDefinitionGroup>
<ClCompile> <ClCompile>
<PreprocessorDefinitions>USE_WGL_SWAP;DIRECTFULLSCREEN;HAVE_SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;SDLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions> <!-- x86/x64 defines: has specific libraries that ARM does not -->
<PreprocessorDefinitions Condition="'$(Platform)' == 'Win32' OR '$(Platform)' == 'x64'">HAVE_ZLIB;HAVE_LIBGME;USE_WGL_SWAP;DIRECTFULLSCREEN;HAVE_SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;SDLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<!-- ARM defines -->
<PreprocessorDefinitions Condition="'$(Platform)' != 'Win32' AND '$(Platform)' != 'x64'">USE_WGL_SWAP;DIRECTFULLSCREEN;HAVE_SDL;HWRENDER;HW3SOUND;HAVE_FILTER;HAVE_MIXER;SDLMAIN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile> </ClCompile>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup /> <ItemGroup />

View file

@ -76,6 +76,7 @@ void *hwSym(const char *funcName,void *handle)
#ifdef HWRENDER #ifdef HWRENDER
if (0 == strcmp("SetPalette", funcName)) if (0 == strcmp("SetPalette", funcName))
funcPointer = &OglSdlSetPalette; funcPointer = &OglSdlSetPalette;
GETFUNC(Init); GETFUNC(Init);
GETFUNC(Draw2DLine); GETFUNC(Draw2DLine);
GETFUNC(DrawPolygon); GETFUNC(DrawPolygon);
@ -90,7 +91,6 @@ void *hwSym(const char *funcName,void *handle)
GETFUNC(DrawModel); GETFUNC(DrawModel);
GETFUNC(CreateModelVBOs); GETFUNC(CreateModelVBOs);
GETFUNC(SetTransform); GETFUNC(SetTransform);
GETFUNC(GetRenderVersion);
GETFUNC(PostImgRedraw); GETFUNC(PostImgRedraw);
GETFUNC(FlushScreenTextures); GETFUNC(FlushScreenTextures);
GETFUNC(StartScreenWipe); GETFUNC(StartScreenWipe);
@ -100,6 +100,20 @@ void *hwSym(const char *funcName,void *handle)
GETFUNC(MakeScreenTexture); GETFUNC(MakeScreenTexture);
GETFUNC(MakeScreenFinalTexture); GETFUNC(MakeScreenFinalTexture);
GETFUNC(DrawScreenFinalTexture); GETFUNC(DrawScreenFinalTexture);
GETFUNC(RenderSkyDome);
GETFUNC(LoadShaders);
GETFUNC(KillShaders);
GETFUNC(SetShader);
GETFUNC(UnSetShader);
GETFUNC(LoadCustomShader);
GETFUNC(InitCustomShaders);
GETFUNC(StartBatching);
GETFUNC(RenderBatches);
#else //HWRENDER #else //HWRENDER
if (0 == strcmp("FinishUpdate", funcName)) if (0 == strcmp("FinishUpdate", funcName))
return funcPointer; //&FinishUpdate; return funcPointer; //&FinishUpdate;

View file

@ -45,6 +45,7 @@ extern int SDL_main(int argc, char *argv[]);
#ifdef LOGMESSAGES #ifdef LOGMESSAGES
FILE *logstream = NULL; FILE *logstream = NULL;
char logfilename[1024];
#endif #endif
#ifndef DOXYGEN #ifndef DOXYGEN
@ -130,10 +131,12 @@ int main(int argc, char **argv)
#ifdef LOGMESSAGES #ifdef LOGMESSAGES
#ifdef DEFAULTDIR #ifdef DEFAULTDIR
if (logdir) if (logdir)
logstream = fopen(va("%s/"DEFAULTDIR"/log.txt",logdir), "wt"); strcpy(logfilename, va("%s/"DEFAULTDIR"/log.txt",logdir));
else else
#endif #endif
logstream = fopen("./log.txt", "wt"); strcpy(logfilename, "./log.txt");
logstream = fopen(logfilename, "wt");
#endif #endif
//I_OutputMsg("I_StartupSystem() ...\n"); //I_OutputMsg("I_StartupSystem() ...\n");
@ -157,6 +160,7 @@ int main(int argc, char **argv)
#endif #endif
MakeCodeWritable(); MakeCodeWritable();
#endif #endif
// startup SRB2 // startup SRB2
CONS_Printf("Setting up SRB2Kart...\n"); CONS_Printf("Setting up SRB2Kart...\n");
D_SRB2Main(); D_SRB2Main();

View file

@ -102,6 +102,12 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#endif #endif
#endif #endif
#if (defined (__unix__) && !defined (_MSDOS)) || defined (UNIXCOMMON)
#include <errno.h>
#include <sys/wait.h>
#define NEWSIGNALHANDLER
#endif
#ifndef NOMUMBLE #ifndef NOMUMBLE
#ifdef __linux__ // need -lrt #ifdef __linux__ // need -lrt
#include <sys/mman.h> #include <sys/mman.h>
@ -247,13 +253,11 @@ SDL_bool framebuffer = SDL_FALSE;
UINT8 keyboard_started = false; UINT8 keyboard_started = false;
FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num) static void I_ReportSignal(int num, int coredumped)
{ {
//static char msg[] = "oh no! back to reality!\r\n"; //static char msg[] = "oh no! back to reality!\r\n";
const char * sigmsg; const char * sigmsg;
char sigdef[32]; char msg[128];
D_QuitNetGame(); // Fix server freezes
switch (num) switch (num)
{ {
@ -279,20 +283,41 @@ FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num)
sigmsg = "SIGABRT - abnormal termination triggered by abort call"; sigmsg = "SIGABRT - abnormal termination triggered by abort call";
break; break;
default: default:
sprintf(sigdef,"signal number %d", num); sprintf(msg,"signal number %d", num);
sigmsg = sigdef; if (coredumped)
sigmsg = 0;
else
sigmsg = msg;
} }
I_OutputMsg("\nsignal_handler() error: %s\n", sigmsg); if (coredumped)
{
if (sigmsg)
sprintf(msg, "%s (core dumped)", sigmsg);
else
strcat(msg, " (core dumped)");
sigmsg = msg;
}
I_OutputMsg("\nProcess killed by signal: %s\n\n", sigmsg);
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
"Signal caught", "Process killed by signal",
sigmsg, NULL); sigmsg, NULL);
}
#ifndef NEWSIGNALHANDLER
FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num)
{
D_QuitNetGame(); // Fix server freezes
I_ReportSignal(num, 0);
I_ShutdownSystem(); I_ShutdownSystem();
signal(num, SIG_DFL); //default signal action signal(num, SIG_DFL); //default signal action
raise(num); raise(num);
I_Quit(); I_Quit();
} }
#endif
FUNCNORETURN static ATTRNORETURN void quit_handler(int num) FUNCNORETURN static ATTRNORETURN void quit_handler(int num)
{ {
@ -668,7 +693,7 @@ static inline void I_ShutdownConsole(void){}
// //
// StartupKeyboard // StartupKeyboard
// //
void I_StartupKeyboard (void) static void I_RegisterSignals (void)
{ {
#ifdef SIGINT #ifdef SIGINT
signal(SIGINT , quit_handler); signal(SIGINT , quit_handler);
@ -682,10 +707,12 @@ void I_StartupKeyboard (void)
// If these defines don't exist, // If these defines don't exist,
// then compilation would have failed above us... // then compilation would have failed above us...
#ifndef NEWSIGNALHANDLER
signal(SIGILL , signal_handler); signal(SIGILL , signal_handler);
signal(SIGSEGV , signal_handler); signal(SIGSEGV , signal_handler);
signal(SIGABRT , signal_handler); signal(SIGABRT , signal_handler);
signal(SIGFPE , signal_handler); signal(SIGFPE , signal_handler);
#endif
} }
// //
@ -2961,7 +2988,7 @@ static void I_ShutdownTimer(void)
pfntimeGetTime = NULL; pfntimeGetTime = NULL;
if (winmm) if (winmm)
{ {
p_timeEndPeriod pfntimeEndPeriod = (p_timeEndPeriod)GetProcAddress(winmm, "timeEndPeriod"); p_timeEndPeriod pfntimeEndPeriod = (p_timeEndPeriod)(LPVOID)GetProcAddress(winmm, "timeEndPeriod");
if (pfntimeEndPeriod) if (pfntimeEndPeriod)
pfntimeEndPeriod(1); pfntimeEndPeriod(1);
FreeLibrary(winmm); FreeLibrary(winmm);
@ -3006,10 +3033,10 @@ void I_StartupTimer(void)
winmm = LoadLibraryA("winmm.dll"); winmm = LoadLibraryA("winmm.dll");
if (winmm) if (winmm)
{ {
p_timeEndPeriod pfntimeBeginPeriod = (p_timeEndPeriod)GetProcAddress(winmm, "timeBeginPeriod"); p_timeEndPeriod pfntimeBeginPeriod = (p_timeEndPeriod)(LPVOID)GetProcAddress(winmm, "timeBeginPeriod");
if (pfntimeBeginPeriod) if (pfntimeBeginPeriod)
pfntimeBeginPeriod(1); pfntimeBeginPeriod(1);
pfntimeGetTime = (p_timeGetTime)GetProcAddress(winmm, "timeGetTime"); pfntimeGetTime = (p_timeGetTime)(LPVOID)GetProcAddress(winmm, "timeGetTime");
} }
I_AddExitFunc(I_ShutdownTimer); I_AddExitFunc(I_ShutdownTimer);
#endif #endif
@ -3023,6 +3050,85 @@ void I_Sleep(void)
SDL_Delay(cv_sleep.value); SDL_Delay(cv_sleep.value);
} }
#ifdef NEWSIGNALHANDLER
static void newsignalhandler_Warn(const char *pr)
{
char text[128];
snprintf(text, sizeof text,
"Error while setting up signal reporting: %s: %s",
pr,
strerror(errno)
);
I_OutputMsg("%s\n", text);
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
"Startup error",
text, NULL);
I_ShutdownConsole();
exit(-1);
}
static void I_Fork(void)
{
int child;
int status;
int signum;
int c;
child = fork();
switch (child)
{
case -1:
newsignalhandler_Warn("fork()");
break;
case 0:
break;
default:
if (logstream)
fclose(logstream);/* the child has this */
c = wait(&status);
#ifdef LOGMESSAGES
/* By the way, exit closes files. */
logstream = fopen(logfilename, "at");
#else
logstream = 0;
#endif
if (c == -1)
{
kill(child, SIGKILL);
newsignalhandler_Warn("wait()");
}
else
{
if (WIFSIGNALED (status))
{
signum = WTERMSIG (status);
#ifdef WCOREDUMP
I_ReportSignal(signum, WCOREDUMP (status));
#else
I_ReportSignal(signum, 0);
#endif
status = 128 + signum;
}
else if (WIFEXITED (status))
{
status = WEXITSTATUS (status);
}
I_ShutdownConsole();
exit(status);
}
}
}
#endif/*NEWSIGNALHANDLER*/
INT32 I_StartupSystem(void) INT32 I_StartupSystem(void)
{ {
SDL_version SDLcompiled; SDL_version SDLcompiled;
@ -3034,6 +3140,10 @@ INT32 I_StartupSystem(void)
I_AddExitFunc(I_stop_threads); I_AddExitFunc(I_stop_threads);
#endif #endif
I_StartupConsole(); I_StartupConsole();
#ifdef NEWSIGNALHANDLER
I_Fork();
#endif
I_RegisterSignals();
I_OutputMsg("Compiled for SDL version: %d.%d.%d\n", I_OutputMsg("Compiled for SDL version: %d.%d.%d\n",
SDLcompiled.major, SDLcompiled.minor, SDLcompiled.patch); SDLcompiled.major, SDLcompiled.minor, SDLcompiled.patch);
I_OutputMsg("Linked with SDL version: %d.%d.%d\n", I_OutputMsg("Linked with SDL version: %d.%d.%d\n",
@ -3276,6 +3386,10 @@ void I_ShutdownSystem(void)
{ {
INT32 c; INT32 c;
#ifndef NEWSIGNALHANDLER
I_ShutdownConsole();
#endif
for (c = MAX_QUIT_FUNCS-1; c >= 0; c--) for (c = MAX_QUIT_FUNCS-1; c >= 0; c--)
if (quit_funcs[c]) if (quit_funcs[c])
(*quit_funcs[c])(); (*quit_funcs[c])();
@ -3312,7 +3426,7 @@ void I_GetDiskFreeSpace(INT64 *freespace)
if (!testwin95) if (!testwin95)
{ {
pfnGetDiskFreeSpaceEx = (p_GetDiskFreeSpaceExA)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetDiskFreeSpaceExA"); pfnGetDiskFreeSpaceEx = (p_GetDiskFreeSpaceExA)(LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "GetDiskFreeSpaceExA");
testwin95 = true; testwin95 = true;
} }
if (pfnGetDiskFreeSpaceEx) if (pfnGetDiskFreeSpaceEx)
@ -3336,7 +3450,7 @@ void I_GetDiskFreeSpace(INT64 *freespace)
char *I_GetUserName(void) char *I_GetUserName(void)
{ {
static char username[MAXPLAYERNAME]; static char username[MAXPLAYERNAME+1];
char *p; char *p;
#ifdef _WIN32 #ifdef _WIN32
DWORD i = MAXPLAYERNAME; DWORD i = MAXPLAYERNAME;
@ -3832,7 +3946,7 @@ const CPUInfoFlags *I_CPUInfo(void)
#if defined (_WIN32) #if defined (_WIN32)
static CPUInfoFlags WIN_CPUInfo; static CPUInfoFlags WIN_CPUInfo;
SYSTEM_INFO SI; SYSTEM_INFO SI;
p_IsProcessorFeaturePresent pfnCPUID = (p_IsProcessorFeaturePresent)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsProcessorFeaturePresent"); p_IsProcessorFeaturePresent pfnCPUID = (p_IsProcessorFeaturePresent)(LPVOID)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsProcessorFeaturePresent");
ZeroMemory(&WIN_CPUInfo,sizeof (WIN_CPUInfo)); ZeroMemory(&WIN_CPUInfo,sizeof (WIN_CPUInfo));
if (pfnCPUID) if (pfnCPUID)

View file

@ -351,11 +351,6 @@ static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code)
case SDL_SCANCODE_RGUI: return KEY_RIGHTWIN; case SDL_SCANCODE_RGUI: return KEY_RIGHTWIN;
default: break; default: break;
} }
#ifdef HWRENDER
DBG_Printf("Unknown incoming scancode: %d, represented %c\n",
code,
SDL_GetKeyName(SDL_GetKeyFromScancode(code)));
#endif
return 0; return 0;
} }
@ -635,11 +630,6 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
if (cv_usemouse.value) I_StartupMouse(); if (cv_usemouse.value) I_StartupMouse();
} }
//else firsttimeonmouse = SDL_FALSE; //else firsttimeonmouse = SDL_FALSE;
capslock = !!( SDL_GetModState() & KMOD_CAPS );// in case CL changes
if (USE_MOUSEINPUT)
SDLdoGrabMouse();
} }
else if (!mousefocus && !kbfocus) else if (!mousefocus && !kbfocus)
{ {
@ -1296,6 +1286,8 @@ void I_StartupMouse(void)
// //
void I_OsPolling(void) void I_OsPolling(void)
{ {
SDL_Keymod mod;
if (consolevent) if (consolevent)
I_GetConsoleEvents(); I_GetConsoleEvents();
if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK) if (SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
@ -1310,6 +1302,18 @@ void I_OsPolling(void)
I_GetMouseEvents(); I_GetMouseEvents();
I_GetEvent(); I_GetEvent();
mod = SDL_GetModState();
/* Handle here so that our state is always synched with the system. */
shiftdown = ctrldown = altdown = 0;
capslock = false;
if (mod & KMOD_LSHIFT) shiftdown |= 1;
if (mod & KMOD_RSHIFT) shiftdown |= 2;
if (mod & KMOD_LCTRL) ctrldown |= 1;
if (mod & KMOD_RCTRL) ctrldown |= 2;
if (mod & KMOD_LALT) altdown |= 1;
if (mod & KMOD_RALT) altdown |= 2;
if (mod & KMOD_CAPS) capslock = true;
} }
// //
@ -1641,6 +1645,7 @@ INT32 VID_SetMode(INT32 modeNum)
//Impl_SetWindowName("SRB2Kart "VERSIONSTRING); //Impl_SetWindowName("SRB2Kart "VERSIONSTRING);
SDLSetMode(vid.width, vid.height, USE_FULLSCREEN); SDLSetMode(vid.width, vid.height, USE_FULLSCREEN);
Impl_VideoSetupBuffer();
if (rendermode == render_soft) if (rendermode == render_soft)
{ {
@ -1649,8 +1654,6 @@ INT32 VID_SetMode(INT32 modeNum)
SDL_FreeSurface(bufSurface); SDL_FreeSurface(bufSurface);
bufSurface = NULL; bufSurface = NULL;
} }
Impl_VideoSetupBuffer();
} }
return SDL_TRUE; return SDL_TRUE;
@ -1773,7 +1776,7 @@ static void Impl_VideoSetupSDLBuffer(void)
static void Impl_VideoSetupBuffer(void) static void Impl_VideoSetupBuffer(void)
{ {
// Set up game's software render buffer // Set up game's software render buffer
if (rendermode == render_soft) //if (rendermode == render_soft)
{ {
vid.rowbytes = vid.width * vid.bpp; vid.rowbytes = vid.width * vid.bpp;
vid.direct = NULL; vid.direct = NULL;
@ -1828,9 +1831,11 @@ void I_StartupGraphics(void)
framebuffer = SDL_TRUE; framebuffer = SDL_TRUE;
} }
if (M_CheckParm("-software")) if (M_CheckParm("-software"))
{
rendermode = render_soft; rendermode = render_soft;
} #ifdef HWRENDER
else if (M_CheckParm("-opengl"))
rendermode = render_opengl;
#endif
usesdl2soft = M_CheckParm("-softblit"); usesdl2soft = M_CheckParm("-softblit");
borderlesswindow = M_CheckParm("-borderless"); borderlesswindow = M_CheckParm("-borderless");
@ -1838,9 +1843,8 @@ void I_StartupGraphics(void)
//SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2); //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2);
VID_Command_ModeList_f(); VID_Command_ModeList_f();
#ifdef HWRENDER #ifdef HWRENDER
if (M_CheckParm("-opengl") || rendermode == render_opengl) if (rendermode == render_opengl)
{ {
rendermode = render_opengl;
HWD.pfnInit = hwSym("Init",NULL); HWD.pfnInit = hwSym("Init",NULL);
HWD.pfnFinishUpdate = NULL; HWD.pfnFinishUpdate = NULL;
HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL);
@ -1857,7 +1861,6 @@ void I_StartupGraphics(void)
HWD.pfnDrawModel = hwSym("DrawModel",NULL); HWD.pfnDrawModel = hwSym("DrawModel",NULL);
HWD.pfnCreateModelVBOs = hwSym("CreateModelVBOs",NULL); HWD.pfnCreateModelVBOs = hwSym("CreateModelVBOs",NULL);
HWD.pfnSetTransform = hwSym("SetTransform",NULL); HWD.pfnSetTransform = hwSym("SetTransform",NULL);
HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL);
HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL);
HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL);
HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL);
@ -1867,14 +1870,23 @@ void I_StartupGraphics(void)
HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL);
HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL); HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL);
HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL);
// check gl renderer lib
if (HWD.pfnGetRenderVersion() != VERSION) HWD.pfnRenderSkyDome = hwSym("RenderSkyDome",NULL);
I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2Kart properly.\n"));
if (!HWD.pfnInit(I_Error)) // let load the OpenGL library HWD.pfnLoadShaders = hwSym("LoadShaders",NULL);
{ HWD.pfnKillShaders = hwSym("KillShaders",NULL);
HWD.pfnSetShader = hwSym("SetShader",NULL);
HWD.pfnUnSetShader = hwSym("UnSetShader",NULL);
HWD.pfnLoadCustomShader = hwSym("LoadCustomShader",NULL);
HWD.pfnInitCustomShaders = hwSym("InitCustomShaders",NULL);
HWD.pfnStartBatching = hwSym("StartBatching",NULL);
HWD.pfnRenderBatches = hwSym("RenderBatches",NULL);
if (!HWD.pfnInit()) // load the OpenGL library
rendermode = render_soft; rendermode = render_soft;
} }
}
#endif #endif
// Fury: we do window initialization after GL setup to allow // Fury: we do window initialization after GL setup to allow

View file

@ -1064,13 +1064,6 @@
path = ../../hardware/hw_drv.h; path = ../../hardware/hw_drv.h;
refType = 2; refType = 2;
}; };
8417773B085A106C000C01D8 = {
fileEncoding = 30;
isa = PBXFileReference;
name = hw_glide.h;
path = ../../hardware/hw_glide.h;
refType = 2;
};
8417773C085A106C000C01D8 = { 8417773C085A106C000C01D8 = {
fileEncoding = 30; fileEncoding = 30;
isa = PBXFileReference; isa = PBXFileReference;

View file

@ -181,7 +181,6 @@
1E44AE640B67CC2B00BAD059 /* hw_cache.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw_cache.c; path = ../../hardware/hw_cache.c; sourceTree = SOURCE_ROOT; }; 1E44AE640B67CC2B00BAD059 /* hw_cache.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw_cache.c; path = ../../hardware/hw_cache.c; sourceTree = SOURCE_ROOT; };
1E44AE650B67CC2B00BAD059 /* hw_dll.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_dll.h; path = ../../hardware/hw_dll.h; sourceTree = SOURCE_ROOT; }; 1E44AE650B67CC2B00BAD059 /* hw_dll.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_dll.h; path = ../../hardware/hw_dll.h; sourceTree = SOURCE_ROOT; };
1E44AE660B67CC2B00BAD059 /* hw_drv.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_drv.h; path = ../../hardware/hw_drv.h; sourceTree = SOURCE_ROOT; }; 1E44AE660B67CC2B00BAD059 /* hw_drv.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_drv.h; path = ../../hardware/hw_drv.h; sourceTree = SOURCE_ROOT; };
1E44AE670B67CC2B00BAD059 /* hw_glide.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_glide.h; path = ../../hardware/hw_glide.h; sourceTree = SOURCE_ROOT; };
1E44AE680B67CC2B00BAD059 /* hw_light.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw_light.c; path = ../../hardware/hw_light.c; sourceTree = SOURCE_ROOT; }; 1E44AE680B67CC2B00BAD059 /* hw_light.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = hw_light.c; path = ../../hardware/hw_light.c; sourceTree = SOURCE_ROOT; };
1E44AE690B67CC2B00BAD059 /* hw_light.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_light.h; path = ../../hardware/hw_light.h; sourceTree = SOURCE_ROOT; }; 1E44AE690B67CC2B00BAD059 /* hw_light.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw_light.h; path = ../../hardware/hw_light.h; sourceTree = SOURCE_ROOT; };
1E44AE6A0B67CC2B00BAD059 /* hw3sound.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw3sound.h; path = ../../hardware/hw3sound.h; sourceTree = SOURCE_ROOT; }; 1E44AE6A0B67CC2B00BAD059 /* hw3sound.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hw3sound.h; path = ../../hardware/hw3sound.h; sourceTree = SOURCE_ROOT; };
@ -535,7 +534,6 @@
1E44AE640B67CC2B00BAD059 /* hw_cache.c */, 1E44AE640B67CC2B00BAD059 /* hw_cache.c */,
1E44AE650B67CC2B00BAD059 /* hw_dll.h */, 1E44AE650B67CC2B00BAD059 /* hw_dll.h */,
1E44AE660B67CC2B00BAD059 /* hw_drv.h */, 1E44AE660B67CC2B00BAD059 /* hw_drv.h */,
1E44AE670B67CC2B00BAD059 /* hw_glide.h */,
1E44AE680B67CC2B00BAD059 /* hw_light.c */, 1E44AE680B67CC2B00BAD059 /* hw_light.c */,
1E44AE690B67CC2B00BAD059 /* hw_light.h */, 1E44AE690B67CC2B00BAD059 /* hw_light.h */,
1E44AE6A0B67CC2B00BAD059 /* hw3sound.h */, 1E44AE6A0B67CC2B00BAD059 /* hw3sound.h */,
@ -1219,7 +1217,7 @@
C01FCF4B08A954540054247B /* Debug */ = { C01FCF4B08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.23; CURRENT_PROJECT_VERSION = 2.1.24;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)", "$(inherited)",
NORMALSRB2, NORMALSRB2,
@ -1231,7 +1229,7 @@
C01FCF4C08A954540054247B /* Release */ = { C01FCF4C08A954540054247B /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.23; CURRENT_PROJECT_VERSION = 2.1.24;
GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (

View file

@ -36,6 +36,7 @@
#ifdef HWRENDER #ifdef HWRENDER
#include "../hardware/r_opengl/r_opengl.h" #include "../hardware/r_opengl/r_opengl.h"
#include "../hardware/hw_main.h"
#include "ogl_sdl.h" #include "ogl_sdl.h"
#include "../i_system.h" #include "../i_system.h"
#include "hwsym_sdl.h" #include "hwsym_sdl.h"
@ -94,10 +95,10 @@ boolean LoadGL(void)
if (SDL_GL_LoadLibrary(OGLLibname) != 0) if (SDL_GL_LoadLibrary(OGLLibname) != 0)
{ {
I_OutputMsg("Could not load OpenGL Library: %s\n" CONS_Alert(CONS_ERROR, "Could not load OpenGL Library: %s\n"
"Falling back to Software mode.\n", SDL_GetError()); "Falling back to Software mode.\n", SDL_GetError());
if (!M_CheckParm("-OGLlib")) if (!M_CheckParm("-OGLlib"))
I_OutputMsg("If you know what is the OpenGL library's name, use -OGLlib\n"); CONS_Printf("If you know what is the OpenGL library's name, use -OGLlib\n");
return 0; return 0;
} }
@ -127,15 +128,15 @@ boolean LoadGL(void)
return SetupGLfunc(); return SetupGLfunc();
else else
{ {
I_OutputMsg("Could not load GLU Library: %s\n", GLULibname); CONS_Alert(CONS_ERROR, "Could not load GLU Library: %s\n", GLULibname);
if (!M_CheckParm("-GLUlib")) if (!M_CheckParm("-GLUlib"))
I_OutputMsg("If you know what is the GLU library's name, use -GLUlib\n"); CONS_Printf("If you know what is the GLU library's name, use -GLUlib\n");
} }
} }
else else
{ {
I_OutputMsg("Could not load GLU Library\n"); CONS_Alert(CONS_ERROR, "Could not load GLU Library\n");
I_OutputMsg("If you know what is the GLU library's name, use -GLUlib\n"); CONS_Printf("If you know what is the GLU library's name, use -GLUlib\n");
} }
#endif #endif
return SetupGLfunc(); return SetupGLfunc();
@ -151,31 +152,29 @@ boolean LoadGL(void)
*/ */
boolean OglSdlSurface(INT32 w, INT32 h) boolean OglSdlSurface(INT32 w, INT32 h)
{ {
INT32 cbpp; INT32 cbpp = cv_scr_depth.value < 16 ? 16 : cv_scr_depth.value;
const GLvoid *glvendor = NULL, *glrenderer = NULL, *glversion = NULL; static boolean first_init = false;
cbpp = cv_scr_depth.value < 16 ? 16 : cv_scr_depth.value; oglflags = 0;
glvendor = pglGetString(GL_VENDOR); if (!first_init)
// Get info and extensions. {
//BP: why don't we make it earlier ? gl_version = pglGetString(GL_VERSION);
//Hurdler: we cannot do that before intialising gl context gl_renderer = pglGetString(GL_RENDERER);
glrenderer = pglGetString(GL_RENDERER);
glversion = pglGetString(GL_VERSION);
gl_extensions = pglGetString(GL_EXTENSIONS); gl_extensions = pglGetString(GL_EXTENSIONS);
DBG_Printf("Vendor : %s\n", glvendor); GL_DBG_Printf("OpenGL %s\n", gl_version);
DBG_Printf("Renderer : %s\n", glrenderer); GL_DBG_Printf("GPU: %s\n", gl_renderer);
DBG_Printf("Version : %s\n", glversion); GL_DBG_Printf("Extensions: %s\n", gl_extensions);
DBG_Printf("Extensions : %s\n", gl_extensions); }
oglflags = 0; first_init = true;
if (isExtAvailable("GL_EXT_texture_filter_anisotropic", gl_extensions)) if (isExtAvailable("GL_EXT_texture_filter_anisotropic", gl_extensions))
pglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maximumAnisotropy); pglGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maximumAnisotropy);
else else
maximumAnisotropy = 1; maximumAnisotropy = 1;
SetupGLFunc13(); SetupGLFunc4();
granisotropicmode_cons_t[1].value = maximumAnisotropy; granisotropicmode_cons_t[1].value = maximumAnisotropy;

View file

@ -1375,7 +1375,6 @@
<ClInclude Include="..\hardware\hw_defs.h" /> <ClInclude Include="..\hardware\hw_defs.h" />
<ClInclude Include="..\hardware\hw_dll.h" /> <ClInclude Include="..\hardware\hw_dll.h" />
<ClInclude Include="..\hardware\hw_drv.h" /> <ClInclude Include="..\hardware\hw_drv.h" />
<ClInclude Include="..\hardware\hw_glide.h" />
<ClInclude Include="..\hardware\hw_glob.h" /> <ClInclude Include="..\hardware\hw_glob.h" />
<ClInclude Include="..\hardware\hw_light.h" /> <ClInclude Include="..\hardware\hw_light.h" />
<ClInclude Include="..\hardware\hw_main.h" /> <ClInclude Include="..\hardware\hw_main.h" />

View file

@ -2410,10 +2410,6 @@
RelativePath="..\hardware\hw_drv.h" RelativePath="..\hardware\hw_drv.h"
> >
</File> </File>
<File
RelativePath="..\hardware\hw_glide.h"
>
</File>
<File <File
RelativePath="..\hardware\hw_glob.h" RelativePath="..\hardware\hw_glob.h"
> >

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