diff --git a/.gitignore b/.gitignore index 3090417dd..7023aaa80 100644 --- a/.gitignore +++ b/.gitignore @@ -13,11 +13,11 @@ Win32_LIB_ASM_Release *.dgb *.debug *.debug.txt -/bin/VC10/ -/objs/VC10/ *.user *.db *.opendb /.vs /debian /assets/debian +/make +/bin diff --git a/CMakeLists.txt b/CMakeLists.txt index 39ad80698..bc4f6ec6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.13) # Enable CCache early set(SRB2_USE_CCACHE OFF CACHE BOOL "Use CCache") @@ -34,12 +34,11 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") ### Useful functions -# Prepend sources with current source directory -function(prepend_sources SOURCE_FILES) - foreach(SOURCE_FILE ${${SOURCE_FILES}}) - set(MODIFIED ${MODIFIED} ${CMAKE_CURRENT_SOURCE_DIR}/${SOURCE_FILE}) - endforeach() - set(${SOURCE_FILES} ${MODIFIED} PARENT_SCOPE) +# Add sources from Sourcefile +function(target_sourcefile type) + file(STRINGS Sourcefile list + REGEX "[-0-9A-Za-z_]+\.${type}") + target_sources(SRB2SDL2 PRIVATE ${list}) endfunction() # Macro to add OSX framework @@ -119,8 +118,9 @@ set(SRB2_SDL2_EXE_NAME srb2kart CACHE STRING "Executable binary output name") include_directories(${CMAKE_CURRENT_BINARY_DIR}/src) add_subdirectory(src) -add_subdirectory(assets) - +if(NOT ${SRB2_CONFIG_DEV_BUILD}) + add_subdirectory(assets) +endif() ## config.h generation set(GIT_EXECUTABLE "git" CACHE FILEPATH "Path to git binary") diff --git a/appveyor.yml b/appveyor.yml index aa7a4c7cd..474a2adb3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,15 +2,11 @@ version: 2.0.{branch}-{build} os: MinGW environment: - CC: ccache - CCACHE_CC: i686-w64-mingw32-gcc - CCACHE_CC_64: x86_64-w64-mingw32-gcc + CC: i686-w64-mingw32-gcc WINDRES: windres # c:\mingw-w64 i686 has gcc 6.3.0, so use c:\msys64 7.3.0 instead MINGW_SDK: c:\msys64\mingw32 - # 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-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: -Wno-implicit-fallthrough 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 UPX_ZIP: upx391w @@ -19,8 +15,6 @@ environment: CCACHE_URL: http://alam.srb2.org/ccache.exe CCACHE_COMPRESS: true CCACHE_DIR: C:\Users\appveyor\.ccache - # Disable UPX by default. The user can override this in their Appveyor project settings - NOUPX: 1 ############################## # DEPLOYER VARIABLES # DPL_ENABLED=1 builds installers for branch names starting with `deployer`. @@ -53,11 +47,6 @@ cache: - C:\Users\appveyor\srb2_cache install: -- if [%CONFIGURATION%] == [SDL64] ( set "X86_64=1" ) -- if [%CONFIGURATION%] == [SDL64] ( set "CONFIGURATION=SDL" ) -- if [%X86_64%] == [1] ( set "MINGW_SDK=%MINGW_SDK_64%" ) -- if [%X86_64%] == [1] ( set "CCACHE_CC=%CCACHE_CC_64%" ) - - if not exist "%NASM_ZIP%.zip" appveyor DownloadFile "%NASM_URL%" -FileName "%NASM_ZIP%.zip" - 7z x -y "%NASM_ZIP%.zip" -o%TMP% >null - robocopy /S /xx /ns /nc /nfl /ndl /np /njh /njs "%TMP%\%NASM_ZIP%" "%MINGW_SDK%\bin" nasm.exe || exit 0 @@ -72,39 +61,27 @@ install: configuration: - SDL -- SDL64 before_build: - set "Path=%MINGW_SDK%\bin;%Path%" -- if [%X86_64%] == [1] ( x86_64-w64-mingw32-gcc --version ) else ( i686-w64-mingw32-gcc --version ) - mingw32-make --version -- if not [%X86_64%] == [1] ( nasm -v ) +- nasm -v - if not [%NOUPX%] == [1] ( upx -V ) - ccache -V - ccache -s -- if [%NOUPX%] == [1] ( set "NOUPX=NOUPX=1" ) else ( set "NOUPX=" ) - if defined [%APPVEYOR_PULL_REQUEST_HEAD_COMMIT%] ( set "COMMIT=%APPVEYOR_PULL_REQUEST_HEAD_COMMIT%" ) else ( set "COMMIT=%APPVEYOR_REPO_COMMIT%" ) - 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=-C src NOECHOFILENAMES=1 CCACHE=1 EXENAME=srb2win-%REPO%-%GITSHORT%.exe" build_script: - cmd: mingw32-make.exe %SRB2_MFLAGS% clean - cmd: mingw32-make.exe %SRB2_MFLAGS% ERRORMODE=1 -k after_build: -- if [%X86_64%] == [1] ( - set "BUILD_PATH=bin\Mingw64\Release" - ) else ( - set "BUILD_PATH=bin\Mingw\Release" - ) -- if [%X86_64%] == [1] ( set "CONFIGURATION=%CONFIGURATION%64" ) - ccache -s - set BUILD_ARCHIVE=%REPO%-%GITSHORT%-%CONFIGURATION%.7z - set BUILDSARCHIVE=%REPO%-%CONFIGURATION%.7z @@ -139,3 +116,4 @@ test: off on_finish: #- cmd: echo xfreerdp /u:appveyor /cert-ignore +clipboard /v:: #- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) +# vim: et ts=1 diff --git a/bin/FreeBSD/Debug/.gitignore b/bin/FreeBSD/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/bin/FreeBSD/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/FreeBSD/Release/.gitignore b/bin/FreeBSD/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/bin/FreeBSD/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/Linux/Debug/.gitignore b/bin/Linux/Debug/.gitignore deleted file mode 100644 index 56dee6f95..000000000 --- a/bin/Linux/Debug/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/lsdlsrb2 diff --git a/bin/Linux/Release/.gitignore b/bin/Linux/Release/.gitignore deleted file mode 100644 index 5b5c54a54..000000000 --- a/bin/Linux/Release/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/lsdlsrb2 -/pnd -/*.mo diff --git a/bin/Linux64/Debug/.gitignore b/bin/Linux64/Debug/.gitignore deleted file mode 100644 index 56dee6f95..000000000 --- a/bin/Linux64/Debug/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/lsdlsrb2 diff --git a/bin/Linux64/Release/.gitignore b/bin/Linux64/Release/.gitignore deleted file mode 100644 index 56dee6f95..000000000 --- a/bin/Linux64/Release/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/lsdlsrb2 diff --git a/bin/Mingw/Debug/.gitignore b/bin/Mingw/Debug/.gitignore deleted file mode 100644 index 3458ff764..000000000 --- a/bin/Mingw/Debug/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*.exe -*.mo -r_opengl.dll -*.bat diff --git a/bin/Mingw/Release/.gitignore b/bin/Mingw/Release/.gitignore deleted file mode 100644 index 3458ff764..000000000 --- a/bin/Mingw/Release/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*.exe -*.mo -r_opengl.dll -*.bat diff --git a/bin/Mingw64/Debug/.gitignore b/bin/Mingw64/Debug/.gitignore deleted file mode 100644 index e431dca5d..000000000 --- a/bin/Mingw64/Debug/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/srb2sdl.exe -/srb2win.exe -/r_opengl.dll diff --git a/bin/Mingw64/Release/.gitignore b/bin/Mingw64/Release/.gitignore deleted file mode 100644 index e431dca5d..000000000 --- a/bin/Mingw64/Release/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/srb2sdl.exe -/srb2win.exe -/r_opengl.dll diff --git a/bin/SDL/Debug/.gitignore b/bin/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/bin/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/SDL/Release/.gitignore b/bin/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/bin/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/bin/VC/.gitignore b/bin/VC/.gitignore deleted file mode 100644 index e52f825b2..000000000 --- a/bin/VC/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/Release -/Debug diff --git a/bin/VC9/.gitignore b/bin/VC9/.gitignore deleted file mode 100644 index 205fe45de..000000000 --- a/bin/VC9/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/Win32 -/x64 diff --git a/bin/dummy/.gitignore b/bin/dummy/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/bin/dummy/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/.gitignore b/dep/.gitignore deleted file mode 100644 index fb941664f..000000000 --- a/dep/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -#All folders -*.d diff --git a/dep/FreeBSD/SDL/Debug/.gitignore b/dep/FreeBSD/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/FreeBSD/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/FreeBSD/SDL/Release/.gitignore b/dep/FreeBSD/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/FreeBSD/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Linux/SDL/Debug/.gitignore b/dep/Linux/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Linux/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Linux/SDL/Release/.gitignore b/dep/Linux/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Linux/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Linux64/SDL/Debug/.gitignore b/dep/Linux64/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Linux64/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Linux64/SDL/Release/.gitignore b/dep/Linux64/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Linux64/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/MasterClient/.gitignore b/dep/MasterClient/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/MasterClient/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/MasterServer/.gitignore b/dep/MasterServer/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/MasterServer/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw/Debug/.gitignore b/dep/Mingw/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw/Release/.gitignore b/dep/Mingw/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw/SDL/Debug/.gitignore b/dep/Mingw/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw/SDL/Release/.gitignore b/dep/Mingw/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw64/Debug/.gitignore b/dep/Mingw64/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw64/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw64/Release/.gitignore b/dep/Mingw64/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw64/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw64/SDL/Debug/.gitignore b/dep/Mingw64/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw64/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/Mingw64/SDL/Release/.gitignore b/dep/Mingw64/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/Mingw64/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/SDL/Release/.gitignore b/dep/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/VC/.gitignore b/dep/VC/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/VC/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/VC9/.gitignore b/dep/VC9/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/VC9/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/cygwin/Debug/.gitignore b/dep/cygwin/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/cygwin/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/cygwin/Release/.gitignore b/dep/cygwin/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/cygwin/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/dep/dummy/.gitignore b/dep/dummy/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/dep/dummy/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/.gitignore b/objs/.gitignore deleted file mode 100644 index 35ecd6def..000000000 --- a/objs/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -#All folders -SRB2.res -depend.dep -depend.ped -*.o -#VC9 folder only -/VC9/Win32 -/VC9/x64 diff --git a/objs/FreeBSD/SDL/Debug/.gitignore b/objs/FreeBSD/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/FreeBSD/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/FreeBSD/SDL/Release/.gitignore b/objs/FreeBSD/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/FreeBSD/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Linux/SDL/Debug/.gitignore b/objs/Linux/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Linux/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Linux/SDL/Release/.gitignore b/objs/Linux/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Linux/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Linux64/SDL/Debug/.gitignore b/objs/Linux64/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Linux64/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Linux64/SDL/Release/.gitignore b/objs/Linux64/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Linux64/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/MasterClient/.gitignore b/objs/MasterClient/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/MasterClient/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/MasterServer/.gitignore b/objs/MasterServer/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/MasterServer/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw/Debug/.gitignore b/objs/Mingw/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw/Release/.gitignore b/objs/Mingw/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw/SDL/Debug/.gitignore b/objs/Mingw/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw/SDL/Release/.gitignore b/objs/Mingw/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw64/Debug/.gitignore b/objs/Mingw64/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw64/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw64/Release/.gitignore b/objs/Mingw64/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw64/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw64/SDL/Debug/.gitignore b/objs/Mingw64/SDL/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw64/SDL/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/Mingw64/SDL/Release/.gitignore b/objs/Mingw64/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/Mingw64/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/SDL/Release/.gitignore b/objs/SDL/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/SDL/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/VC/.gitignore b/objs/VC/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/VC/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/VC9/.gitignore b/objs/VC9/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/VC9/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/cygwin/Debug/.gitignore b/objs/cygwin/Debug/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/cygwin/Debug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/cygwin/Release/.gitignore b/objs/cygwin/Release/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/cygwin/Release/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/objs/dummy/.gitignore b/objs/dummy/.gitignore deleted file mode 100644 index 42c6dc2c6..000000000 --- a/objs/dummy/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# DON'T REMOVE -# This keeps the folder from disappearing diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d2678bb31..1355c85ee 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,269 +1,14 @@ # SRB2 Core +add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32) + # Core sources -set(SRB2_CORE_SOURCES - am_map.c - command.c - comptime.c - console.c - d_clisrv.c - d_main.c - d_net.c - d_netcmd.c - d_netfil.c - dehacked.c - deh_soc.c - deh_lua.c - deh_tables.c - f_finale.c - f_wipe.c - filesrch.c - g_demo.c - g_game.c - g_input.c - g_splitscreen.c - font.c - hu_stuff.c - i_tcp.c - info.c - lzf.c - m_aatree.c - m_anigif.c - m_argv.c - m_bbox.c - m_cheat.c - m_cond.c - m_fixed.c - m_menu.c - m_misc.c - m_perfstats.c - m_queue.c - m_random.c - md5.c - mserv.c - http-mserv.c - s_sound.c - screen.c - sounds.c - st_stuff.c - #string.c - tables.c - v_video.c - w_wad.c - y_inter.c - z_zone.c -) +target_sourcefile(c) +target_sources(SRB2SDL2 PRIVATE comptime.c md5.c config.h.in) -set(SRB2_CORE_HEADERS - am_map.h - byteptr.h - command.h - console.h - d_clisrv.h - d_event.h - d_main.h - d_net.h - d_netcmd.h - d_netfil.h - d_player.h - d_think.h - d_ticcmd.h - dehacked.h - deh_soc.h - deh_lua.h - deh_tables.h - doomdata.h - doomdef.h - doomstat.h - doomtype.h - endian.h - f_finale.h - fastcmp.h - filesrch.h - g_demo.h - g_game.h - g_input.h - g_state.h - font.h - hu_stuff.h - i_joy.h - i_net.h - i_sound.h - i_system.h - i_tcp.h - i_video.h - info.h - keys.h - lzf.h - m_aatree.h - m_anigif.h - m_argv.h - m_bbox.h - m_cheat.h - m_cond.h - m_dllist.h - m_fixed.h - m_menu.h - m_misc.h - m_perfstats.h - m_queue.h - m_random.h - m_swap.h - md5.h - mserv.h - p5prof.h - s_sound.h - screen.h - sounds.h - st_stuff.h - tables.h - v_video.h - w_wad.h - y_inter.h - z_zone.h - - config.h.in -) - -set(SRB2_CORE_RENDER_SOURCES - r_bsp.c - r_data.c - r_draw.c - r_main.c - r_plane.c - r_segs.c - r_skins.c - r_sky.c - r_splats.c - r_things.c - r_textures.c - r_patch.c - r_patchrotation.c - r_picformats.c - r_portal.c - - r_bsp.h - r_data.h - r_defs.h - r_draw.h - r_local.h - r_main.h - r_plane.h - r_segs.h - r_skins.h - r_sky.h - r_splats.h - r_state.h - r_things.h - r_textures.h - r_patch.h - r_patchrotation.h - r_picformats.h - r_portal.h -) - -set(SRB2_CORE_GAME_SOURCES - p_ceilng.c - p_enemy.c - p_floor.c - p_inter.c - p_lights.c - p_map.c - p_maputl.c - p_mobj.c - p_polyobj.c - p_saveg.c - p_setup.c - p_sight.c - p_slopes.c - p_spec.c - p_telept.c - p_tick.c - p_user.c - taglist.c - - k_race.c - k_battle.c - k_bheap.c - k_collide.c - k_kart.c - k_pathfind.c - k_pwrlv.c - k_waypoint.c - k_color.c - k_bot.c - k_botitem.c - k_botsearch.c - k_respawn.c - k_grandprix.c - k_hud.c - - p_local.h - p_maputl.h - p_mobj.h - p_polyobj.h - p_pspr.h - p_saveg.h - p_setup.h - p_slopes.h - p_spec.h - p_tick.h - taglist.h - - k_race.h - k_battle.h - k_bheap.h - k_collide.h - k_kart.h - k_pathfind.h - k_pwrlv.h - k_waypoint.h - k_color.h - k_bot.h - k_respawn.h - k_grandprix.h - k_hud.h -) - -if(NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) - set(SRB2_CORE_SOURCES ${SRB2_CORE_SOURCES} string.c) -endif() - -prepend_sources(SRB2_CORE_SOURCES) -prepend_sources(SRB2_CORE_HEADERS) -prepend_sources(SRB2_CORE_RENDER_SOURCES) -prepend_sources(SRB2_CORE_GAME_SOURCES) - -set(SRB2_CORE_HEADERS ${SRB2_CORE_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/config.h) -source_group("Main" FILES ${SRB2_CORE_SOURCES} ${SRB2_CORE_HEADERS}) -source_group("Renderer" FILES ${SRB2_CORE_RENDER_SOURCES}) -source_group("Game" FILES ${SRB2_CORE_GAME_SOURCES}) - - -set(SRB2_ASM_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/vid_copy.s -) - -set(SRB2_NASM_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/tmap_mmx.nas - ${CMAKE_CURRENT_SOURCE_DIR}/tmap.nas -) - -if(MSVC) - list(APPEND SRB2_NASM_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/tmap_vc.nas) -endif() - -set(SRB2_NASM_OBJECTS - ${CMAKE_CURRENT_BINARY_DIR}/tmap_mmx.obj - ${CMAKE_CURRENT_BINARY_DIR}/tmap.obj -) - -if(MSVC) - list(APPEND SRB2_NASM_OBJECTS ${CMAKE_CURRENT_BINARY_DIR}/tmap_vc.obj) -endif() - -source_group("Assembly" FILES ${SRB2_ASM_SOURCES} ${SRB2_NASM_SOURCES}) +set(SRB2_ASM_SOURCES vid_copy.s) +set(SRB2_NASM_SOURCES tmap_mmx.nas tmap.nas) ### Configuration set(SRB2_CONFIG_HAVE_PNG ON CACHE BOOL @@ -296,6 +41,8 @@ set(SRB2_CONFIG_YASM OFF CACHE BOOL "Use YASM in place of NASM.") set(SRB2_CONFIG_STATIC_OPENGL OFF CACHE BOOL "Use statically linked OpenGL. NOT RECOMMENDED.") +set(SRB2_CONFIG_DEV_BUILD OFF CACHE BOOL + "Compile a development build of SRB2Kart.") ### use internal libraries? if(${CMAKE_SYSTEM} MATCHES "Windows") ###set on Windows only @@ -303,92 +50,7 @@ if(${CMAKE_SYSTEM} MATCHES "Windows") ###set on Windows only "Use SRB2Kart's internal copies of required dependencies (SDL2, PNG, zlib, GME, OpenMPT, cURL).") endif() -set(SRB2_LUA_SOURCES - lua_baselib.c - lua_blockmaplib.c - lua_consolelib.c - lua_hooklib.c - lua_hudlib.c - lua_infolib.c - lua_maplib.c - lua_taglib.c - lua_mathlib.c - lua_mobjlib.c - lua_playerlib.c - lua_polyobjlib.c - lua_script.c - lua_skinlib.c - lua_thinkerlib.c -) -set(SRB2_LUA_HEADERS - lua_hook.h - lua_hud.h - lua_libs.h - lua_script.h -) - -prepend_sources(SRB2_LUA_SOURCES) -prepend_sources(SRB2_LUA_HEADERS) - -source_group("LUA" FILES ${SRB2_LUA_SOURCES} ${SRB2_LUA_HEADERS}) - -set(SRB2_BLUA_SOURCES - blua/lapi.c - blua/lauxlib.c - blua/lbaselib.c - blua/lcode.c - blua/ldebug.c - blua/ldo.c - blua/ldump.c - blua/lfunc.c - blua/lgc.c - blua/linit.c - blua/liolib.c - blua/llex.c - blua/lmem.c - blua/lobject.c - blua/lopcodes.c - blua/lparser.c - blua/lstate.c - blua/lstring.c - blua/lstrlib.c - blua/ltable.c - blua/ltablib.c - blua/ltm.c - blua/lundump.c - blua/lvm.c - blua/lzio.c -) -set(SRB2_BLUA_HEADERS - blua/lapi.h - blua/lauxlib.h - blua/lcode.h - blua/ldebug.h - blua/ldo.h - blua/lfunc.h - blua/lgc.h - blua/llex.h - blua/llimits.h - blua/lmem.h - blua/lobject.h - blua/lopcodes.h - blua/lparser.h - blua/lstate.h - blua/lstring.h - blua/ltable.h - blua/ltm.h - blua/lua.h - blua/luaconf.h - blua/lualib.h - blua/lundump.h - blua/lvm.h - blua/lzio.h -) - -prepend_sources(SRB2_BLUA_SOURCES) -prepend_sources(SRB2_BLUA_HEADERS) - -source_group("LUA\\Interpreter" FILES ${SRB2_BLUA_SOURCES} ${SRB2_BLUA_HEADERS}) +add_subdirectory(blua) if(${SRB2_CONFIG_HAVE_GME}) if(${SRB2_CONFIG_USE_INTERNAL_LIBRARIES}) @@ -404,7 +66,7 @@ if(${SRB2_CONFIG_HAVE_GME}) endif() if(${GME_FOUND}) set(SRB2_HAVE_GME ON) - add_definitions(-DHAVE_LIBGME) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_GME) else() message(WARNING "You have specified that GME is available but it was not found.") endif() @@ -424,7 +86,7 @@ if(${SRB2_CONFIG_HAVE_OPENMPT}) endif() if(${OPENMPT_FOUND}) set(SRB2_HAVE_OPENMPT ON) - add_definitions(-DHAVE_OPENMPT) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_OPENMPT) else() message(WARNING "You have specified that OpenMPT is available but it was not found.") endif() @@ -447,8 +109,7 @@ if(${SRB2_CONFIG_HAVE_MIXERX}) endif() if(${MIXERX_FOUND}) set(SRB2_HAVE_MIXERX ON) - set(SRB2_SDL2_SOUNDIMPL mixer_sound.c) - add_definitions(-DHAVE_MIXERX) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_MIXERX) else() message(WARNING "You have specified that SDL Mixer X is available but it was not found.") endif() @@ -469,13 +130,9 @@ if(${SRB2_CONFIG_HAVE_DISCORDRPC}) endif() if(${DISCORDRPC_FOUND}) set(SRB2_HAVE_DISCORDRPC ON) - add_definitions(-DHAVE_DISCORDRPC) - add_definitions(-DUSE_STUN) - set(SRB2_DISCORDRPC_SOURCES discord.c stun.c) - set(SRB2_DISCORDRPC_HEADERS discord.h stun.h) - prepend_sources(SRB2_DISCORDRPC_SOURCES) - prepend_sources(SRB2_DISCORDRPC_HEADERS) - source_group("Discord Rich Presence" FILES ${SRB2_DISCORDRPC_SOURCES} ${SRB2_DISCORDRPC_HEADERS}) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_DISCORDRPC) + target_compile_definitions(SRB2SDL2 PRIVATE -DUSE_STUN) + target_sources(SRB2SDL2 PRIVATE discord.c stun.c) else() message(WARNING "You have specified that Discord Rich Presence is available but it was not found.") endif() @@ -495,7 +152,7 @@ if(${SRB2_CONFIG_HAVE_ZLIB}) endif() if(${ZLIB_FOUND}) set(SRB2_HAVE_ZLIB ON) - add_definitions(-DHAVE_ZLIB) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_ZLIB) else() message(WARNING "You have specified that ZLIB is available but it was not found. SRB2Kart may not compile correctly.") endif() @@ -516,14 +173,9 @@ if(${SRB2_CONFIG_HAVE_PNG} AND ${SRB2_CONFIG_HAVE_ZLIB}) endif() if(${PNG_FOUND}) set(SRB2_HAVE_PNG ON) - add_definitions(-DHAVE_PNG) - add_definitions(-D_LARGEFILE64_SOURCE) - set(SRB2_PNG_SOURCES apng.c) - set(SRB2_PNG_HEADERS apng.h) - prepend_sources(SRB2_PNG_SOURCES) - prepend_sources(SRB2_PNG_HEADERS) - source_group("Main" FILES ${SRB2_CORE_SOURCES} ${SRB2_CORE_HEADERS} - ${SRB2_PNG_SOURCES} ${SRB2_PNG_HEADERS}) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_PNG) + target_compile_definitions(SRB2SDL2 PRIVATE -D_LARGEFILE64_SOURCE) + target_sources(SRB2SDL2 PRIVATE apng.c) else() message(WARNING "You have specified that PNG is available but it was not found. SRB2Kart may not compile correctly.") endif() @@ -544,7 +196,7 @@ if(${SRB2_CONFIG_HAVE_CURL}) endif() if(${CURL_FOUND}) set(SRB2_HAVE_CURL ON) - add_definitions(-DHAVE_CURL) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_CURL) else() message(WARNING "You have specified that CURL is available but it was not found. SRB2Kart may not compile correctly.") endif() @@ -552,59 +204,19 @@ endif() if(${SRB2_CONFIG_HAVE_THREADS}) set(SRB2_HAVE_THREADS ON) - set(SRB2_CORE_HEADERS ${SRB2_CORE_HEADERS} ${CMAKE_CURRENT_SOURCE_DIR}/i_threads.h) - add_definitions(-DHAVE_THREADS) + target_compile_definitions(SRB2SDL2 PRIVATE -DHAVE_THREADS) endif() if(${SRB2_CONFIG_HWRENDER}) - add_definitions(-DHWRENDER) - set(SRB2_HWRENDER_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_batching.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_bsp.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_cache.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_draw.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2load.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md3load.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_model.c - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/u_list.c - ) - - set (SRB2_HWRENDER_HEADERS - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_batching.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_clip.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_data.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_defs.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_dll.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_drv.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_glob.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2load.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md3load.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_model.h - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/u_list.h - ) - - set(SRB2_R_OPENGL_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/r_opengl/r_opengl.c - ) - - set(SRB2_R_OPENGL_HEADERS - ${CMAKE_CURRENT_SOURCE_DIR}/hardware/r_opengl/r_opengl.h - ) - + target_compile_definitions(SRB2SDL2 PRIVATE -DHWRENDER) + add_subdirectory(hardware) endif() if(${SRB2_CONFIG_HWRENDER} AND ${SRB2_CONFIG_STATIC_OPENGL}) find_package(OpenGL) if(${OPENGL_FOUND}) - add_definitions(-DHWRENDER) - add_definitions(-DSTATIC_OPENGL) + target_compile_definitions(SRB2SDL2 PRIVATE -DHWRENDER) + target_compile_definitions(SRB2SDL2 PRIVATE -DSTATIC_OPENGL) else() message(WARNING "You have specified static opengl but opengl was not found. Not setting HWRENDER.") endif() @@ -625,12 +237,16 @@ if(${SRB2_CONFIG_USEASM}) set(CMAKE_ASM_NASM_FLAGS "${SRB2_ASM_FLAGS}" CACHE STRING "Flags used by the assembler during all build types.") enable_language(ASM_NASM) endif() + set(SRB2_USEASM ON) - add_definitions(-DUSEASM) + target_compile_definitions(SRB2SDL2 PRIVATE -DUSEASM) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse3 -mfpmath=sse") + + target_sources(SRB2SDL2 PRIVATE ${SRB2_ASM_SOURCES} + ${SRB2_NASM_SOURCES}) else() set(SRB2_USEASM OFF) - add_definitions(-DNONX86 -DNORUSEASM) + target_compile_definitions(SRB2SDL2 PRIVATE -DNONX86 -DNORUSEASM) endif() # Targets @@ -666,7 +282,13 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -Wno-absolute-value) endif() -add_definitions(-DCMAKECONFIG) +if(${SRB2_CONFIG_DEV_BUILD}) + target_compile_definitions(SRB2SDL2 PRIVATE -DDEVELOP) +endif() + +set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -Wno-trigraphs) + +target_compile_definitions(SRB2SDL2 PRIVATE -DCMAKECONFIG) #add_library(SRB2Core STATIC # ${SRB2_CORE_SOURCES} diff --git a/src/Makefile b/src/Makefile index a390557a6..9659a4994 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,861 +1,416 @@ - -# GNU Make makefile for SRB2 -############################################################################# -# Copyright (C) 1998-2000 by DooM Legacy Team. -# Copyright (C) 2003-2021 by Sonic Team Junior. +# GNU Makefile for SRB2 +# the poly3 Makefile adapted over and over... +# +# Copyright 1998-2000 DooM Legacy Team. +# Copyright 2020-2021 James R. +# Copyright 2003-2021 Sonic Team Junior. # # This program is free software distributed under the # terms of the GNU General Public License, version 2. # See the 'LICENSE' file for more details. # -# -DLINUX -> use for the GNU/Linux specific -# -D_WINDOWS -> use for the Win32/DirectX specific -# -DHAVE_SDL -> use for the SDL interface +# Special targets: # -# Sets: -# Compile the SDL/Mingw version with 'make MINGW=1' -# Compile the SDL/Linux version with 'make LINUX=1' -# Compile the SDL/Solaris version with 'make SOLARIS=1' -# Compile the SDL/FreeBSD version with 'gmake FREEBSD=1' -# Compile the SDL/Cygwin version with 'make CYGWIN32=1' -# Compile the SDL/other version try with 'make SDL=1' +# clean - remove executables and objects for this build +# cleandep - remove dependency files for this build +# distclean - remove entire executable, object and +# dependency file directory structure. +# dump - disassemble executable +# info - print settings # -# 'Targets': -# clean -# Remove all object files -# cleandep -# Remove dependency files -# distclean -# Remove autogenerated files -# dll -# compile primary HW render DLL/SO -# all_dll -# compile all HW render and 3D sound DLLs for the set -# opengl_dll -# Pure Mingw only, compile OpenGL HW render DLL -# ds3d_dll -# Pure Mingw only, compile DirectX DirectSound HW sound DLL -# fmod_dll -# Pure Mingw only, compile FMOD HW sound DLL -# openal_dll -# Pure Mingw only, compile OpenAL HW sound DLL -# fmod_so -# Non-Mingw, compile FMOD HW sound SO -# openal_so -# Non-Mingw, compile OpenAL HW sound SO +# This Makefile can automatically detect the host system +# as well as the compiler version. If system or compiler +# version cannot be detected, you may need to set a flag +# manually. # +# On Windows machines, 32-bit Windows is always targetted. # -# Addon: -# To Cross-Compile, CC=gcc-version make * PREFIX= -# Compile with GCC 2.97 version, add 'GCC29=1' -# Compile with GCC 4.0x version, add 'GCC40=1' -# Compile with GCC 4.1x version, add 'GCC41=1' -# Compile with GCC 4.2x version, add 'GCC42=1' -# Compile with GCC 4.3x version, add 'GCC43=1' -# Compile with GCC 4.4x version, add 'GCC44=1' -# Compile with GCC 4.5x version, add 'GCC45=1' -# Compile with GCC 4.6x version, add 'GCC46=1' -# Compile a profile version, add 'PROFILEMODE=1' -# Compile a debug version, add 'DEBUGMODE=1' -# Compile for the testers group (they don't get to play unless we're watching *wink*), add 'TESTERS=1' -# Compile with less warnings, add 'RELAXWARNINGS=1' -# Generate compiler errors for most compiler warnings, add 'ERRORMODE=1' -# Compile without NASM's tmap.nas, add 'NOASM=1' -# Compile without 3D hardware support, add 'NOHW=1' -# Compile with GDBstubs, add 'RDB=1' -# Compile without PNG, add 'NOPNG=1' -# Compile without zlib, add 'NOZLIB=1' +# Platform/system flags: # -# Addon for SDL: -# To Cross-Compile, add 'SDL_CONFIG=/usr/*/bin/sdl-config' -# Compile without SDL_Mixer, add 'NOMIXER=1' -# Compile without SDL_Mixer_X, add 'NOMIXERX=1' (Win32 only) -# Compile without GME, add 'NOGME=1' -# Compile without BSD API, add 'NONET=1' -# Compile without IPX/SPX, add 'NOIPX=1' -# Compile Mingw/SDL with S_DS3S, add 'DS3D=1' -# Compile without libopenmpt, add 'NOOPENMPT=1' -# Compile with S_FMOD3D, add 'FMOD=1' (WIP) -# Compile with S_OPENAL, add 'OPENAL=1' (WIP) -# To link with the whole SDL_Image lib to load Icons, add 'SDL_IMAGE=1' but it isn't not realy needed -# To link with SDLMain to hide console or make on a console-less binary, add 'SDLMAIN=1' +# LINUX=1, LINUX64=1 +# MINGW=1, MINGW64=1 - Windows (MinGW toolchain) +# UNIX=1 - Generic Unix like system +# FREEBSD=1 +# SDL=1 - Use SDL backend. SDL is the only backend though +# and thus, always enabled. # -############################################################################# +# A list of supported GCC versions can be found in +# Makefile.d/detect.mk -- search 'gcc_versions'. +# +# Feature flags: +# +# Safe to use online +# ------------------ +# NO_IPV6=1 - Disable IPv6 address support. +# NOHW=1 - Disable OpenGL renderer. +# ZDEBUG=1 - Enable more detailed memory debugging +# HAVE_MINIUPNPC=1 - Enable automated port forwarding. +# Already enabled by default for 32-bit +# Windows. +# NOASM=1 - Disable hand optimized assembly code for the +# Software renderer. +# NOPNG=1 - Disable PNG graphics support. (TODO: double +# check netplay compatible.) +# NOCURL=1 - Disable libcurl--HTTP capability. +# NOGME=1 - Disable game music emu, retro VGM support. +# NOOPENMPT=1 - Disable module (tracker) music support. +# NOMIXER=1 - Disable SDL Mixer (audio playback). +# NOMIXERX=1 - Forgo SDL Mixer X--revert to standard SDL +# Mixer. Mixer X is the default for Windows +# builds. +# HAVE_MIXERX=1 - Enable SDL Mixer X. Outside of Windows +# builds, SDL Mixer X is not the default. +# NOTHREADS=1 - Disable multithreading. +# +# Netplay incompatible +# -------------------- +# NONET=1 - Disable online capability. +# NOMD5=1 - Disable MD5 checksum (validation tool). +# NOPOSTPROCESSING=1 - ? +# MOBJCONSISTANCY=1 - ?? +# PACKETDROP=1 - ?? +# DEBUGMODE=1 - Enable various debugging capabilities. +# Also disables optimizations. +# NOZLIB=1 - Disable some compression capability. Implies +# NOPNG=1. +# +# Development flags: +# +# VALGRIND=1 - Enable Valgrind memory debugging support. +# PROFILEMODE=1 - Enable performance profiling (gprof). +# +# General flags for building: +# +# STATIC=1 - Use static linking. +# DISTCC=1 +# CCACHE=1 +# UPX= - UPX command to use for compressing final +# executable. +# WINDOWSHELL=1 - Use Windows commands. +# PREFIX= - Prefix to many commands, for cross compiling. +# YASM=1 - Use Yasm instead of NASM assembler. +# STABS=1 - ? +# ECHO=1 - Print out each command in the build process. +# NOECHOFILENAMES=1 - Don't print out each that is being +# worked on. +# SILENT=1 - Print absolutely nothing except errors. +# RELAXWARNINGS=1 - Use less compiler warnings/errors. +# ERRORMODE=1 - Treat most compiler warnings as errors. +# NOCASTALIGNWARN=1 - ? +# NOLDWARNING=1 - ? +# NOSDLMAIN=1 - ? +# SDLMAIN=1 - ? +# +# Library configuration flags: +# Everything here is an override. +# +# PNG_PKGCONFIG= - libpng-config command. +# PNG_CFLAGS=, PNG_LDFLAGS= +# +# CURLCONFIG= - curl-config command. +# CURL_CFLAGS=, CURL_LDFLAGS= +# +# VALGRIND_PKGCONFIG= - pkg-config package name. +# VALGRIND_CFLAGS=, VALGRIND_LDFLAGS= +# +# LIBGME_PKGCONFIG=, LIBGME_CFLAGS=, LIBGME_LDFLAGS= -,=, +# LIBOPENMPT_PKGCONFIG= +# LIBOPENMPT_CFLAGS=, LIBOPENMPT_LDFLAGS= +# +# ZLIB_PKGCONFIG=, ZLIB_CFLAGS=, ZLIB_LDFLAGS= +# +# SDL_PKGCONFIG= +# SDL_CONFIG= - sdl-config command. +# SDL_CFLAGS=, SDL_LDFLAGS= -ifeq (,$(filter-out cleandep clean distclean,$(or $(MAKECMDGOALS),all))) -CLEANONLY=1 -else ifndef SILENT -echo=@echo "$(1)" -ifndef MAKE_RESTARTS -print=$(info $(1)) -endif +clean_targets=cleandep clean distclean info + +.PHONY : $(clean_targets) all + +goals:=$(or $(MAKECMDGOALS),all) +cleanonly:=$(filter $(clean_targets),$(goals)) +destructive:=$(filter-out info,$(cleanonly)) + +ifndef cleanonly +include Makefile.d/old.mk endif -ALL_SYSTEMS=\ - PANDORA\ - LINUX64\ - MINGW64\ - HAIKU\ - DUMMY\ - DJGPPDOS\ - MINGW\ - UNIX\ - LINUX\ - SOLARIS\ - FREEBSD\ - MACOSX\ - SDL\ +include Makefile.d/util.mk -# check for user specified system -ifeq (,$(filter $(ALL_SYSTEMS),$(.VARIABLES))) -ifeq ($(OS),Windows_NT) # all windows are Windows_NT... - - $(call print,Detected a Windows system$(,) compiling for 32-bit MinGW SDL2...) - - # go for a 32-bit sdl mingw exe by default - MINGW=1 - WINDOWSHELL=1 - -else # if you on the *nix - - system:=$(shell uname -s) - - ifeq ($(system),Linux) - new_system=LINUX - else - - $(error \ - Could not automatically detect your system,\ - try specifying a system manually) - - endif - - ifeq ($(shell getconf LONG_BIT),64) - system+=64-bit - new_system:=$(new_system)64 - endif - - $(call print,Detected $(system) ($(new_system))...) - $(new_system)=1 - -endif -endif - - -# SRB2 data files -D_DIR?=../bin/Resources -D_FILES=$(D_DIR)/main.kart \ - $(D_DIR)/gfx.pk3 \ - $(D_DIR)/textures.pk3 \ - $(D_DIR)/chars.pk3 \ - $(D_DIR)/maps.wad \ - $(D_DIR)/patch.pk3 \ - $(D_DIR)/sounds.wad \ - $(D_DIR)/music.wad \ - -PKG_CONFIG?=pkg-config - -ifdef PANDORA -LINUX=1 -endif - -ifdef LINUX64 -LINUX=1 -NONX86=1 -# LINUX64 does not imply X86_64=1; could mean ARM64 or Itanium -endif - -ifdef MINGW64 -MINGW=1 -NONX86=1 -NOASM=1 -# MINGW64 should not necessarily imply X86_64=1, but we make that assumption elsewhere -# Once that changes, remove this -X86_64=1 -endif #ifdef MINGW64 - -ifdef HAIKU -SDL=1 -endif - -include Makefile.cfg - -ifdef DUMMY -NOPNG=1 -NOZLIB=1 -NONET=1 -NOHW=1 -NOASM=1 -NOIPX=1 -EXENAME?=srb2dummy -OBJS=$(OBJDIR)/i_video.o -LIBS=-lm -endif - -ifdef HAIKU -NOIPX=1 -NOASM=1 -ifndef NONET -LIBS=-lnetwork -endif -CFLAGS+=-DUNIXCOMMON -PNG_CFLAGS?= -PNG_LDFLAGS?=-lpng -endif - -ifdef PANDORA -NONX86=1 -NOHW=1 -endif - -ifndef NOOPENMPT -HAVE_OPENMPT=1 -endif - -ifdef MINGW -include win32/Makefile.cfg -endif #ifdef MINGW - -ifdef UNIX -UNIXCOMMON=1 -endif - -ifdef LINUX -UNIXCOMMON=1 -ifndef NOGME -HAVE_LIBGME=1 -endif -endif - -ifdef SOLARIS -UNIXCOMMON=1 -endif - -ifdef FREEBSD -UNIXCOMMON=1 -endif - -ifdef MACOSX -UNIXCOMMON=1 -endif - -ifdef SDL - include sdl/Makefile.cfg -endif #ifdef SDL - -ifdef DISTCC - CC:=distcc $(CC) -endif - -ifdef CCACHE - CC:=ccache $(CC) -endif - -MSGFMT?=msgfmt - -ifdef WINDOWSHELL - COMPTIME=-..\comptime.bat -else - COMPTIME=-../comptime.sh -endif - -ifndef ECHO - NASM:=@$(NASM) - REMOVE:=@$(REMOVE) - CC:=@$(CC) - CXX:=@$(CXX) - OBJCOPY:=@$(OBJCOPY) - OBJDUMP:=@$(OBJDUMP) - STRIP:=@$(STRIP) - WINDRES:=@$(WINDRES) - MKDIR:=@$(MKDIR) - GZIP:=@$(GZIP) - MSGFMT:=@$(MSGFMT) - UPX:=@$(UPX) - UPX_OPTS+=-q - COMPTIME:=@$(COMPTIME) -endif - -ifdef NONET - OPTS+=-DNONET - NOCURL=1 -else -ifdef NO_IPV6 - OPTS+=-DNO_IPV6 -endif -endif - -ifdef NOHW - OPTS+=-DNOHW -else - OPTS+=-DHWRENDER - OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o $(OBJDIR)/hw_light.o \ - $(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o \ - $(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o $(OBJDIR)/hw_batching.o -endif - -OPTS += -DCOMPVERSION - -ifndef NONX86 -ifndef GCC29 - ARCHOPTS?=-msse3 -mfpmath=sse -else - ARCHOPTS?=-mpentium -endif -else -ifdef X86_64 - ARCHOPTS?=-march=nocona -endif -endif - -ifndef NOASM -ifndef NONX86 - OBJS+=$(OBJDIR)/tmap.o $(OBJDIR)/tmap_mmx.o - OPTS+=-DUSEASM -endif -endif - -ifndef NOPNG -OPTS+=-DHAVE_PNG - -ifdef PNG_PKGCONFIG -PNG_CFLAGS?=$(shell $(PKG_CONFIG) $(PNG_PKGCONFIG) --cflags) -PNG_LDFLAGS?=$(shell $(PKG_CONFIG) $(PNG_PKGCONFIG) --libs) -else ifdef PREFIX -PNG_CONFIG?=$(PREFIX)-libpng-config +CC:=$(PREFIX)-gcc +endif + +OBJDUMP_OPTS?=--wide --source --line-numbers + +OBJCOPY:=$(call Prefix,objcopy) +OBJDUMP:=$(call Prefix,objdump) +WINDRES:=$(call Prefix,windres) + +ifdef YASM +NASM?=yasm else -PNG_CONFIG?=libpng-config -endif - -ifdef PNG_STATIC -PNG_CFLAGS?=$(shell $(PNG_CONFIG) --static --cflags) -PNG_LDFLAGS?=$(shell $(PNG_CONFIG) --static --ldflags) -else -PNG_CFLAGS?=$(shell $(PNG_CONFIG) --cflags) -PNG_LDFLAGS?=$(shell $(PNG_CONFIG) --ldflags) -endif -endif - -ifdef LINUX -PNG_CFLAGS+=-D_LARGEFILE64_SOURCE -endif - -LIBS+=$(PNG_LDFLAGS) -CFLAGS+=$(PNG_CFLAGS) - -OBJS+=$(OBJDIR)/apng.o -endif - -ifdef HAVE_LIBGME -OPTS+=-DHAVE_LIBGME - -LIBGME_PKGCONFIG?=libgme -LIBGME_CFLAGS?=$(shell $(PKG_CONFIG) $(LIBGME_PKGCONFIG) --cflags) -LIBGME_LDFLAGS?=$(shell $(PKG_CONFIG) $(LIBGME_PKGCONFIG) --libs) - -LIBS+=$(LIBGME_LDFLAGS) -CFLAGS+=$(LIBGME_CFLAGS) -endif - -ifdef HAVE_OPENMPT -OPTS+=-DHAVE_OPENMPT - -LIBOPENMPT_PKGCONFIG?=libopenmpt -LIBOPENMPT_CFLAGS?=$(shell $(PKG_CONFIG) $(LIBOPENMPT_PKGCONFIG) --cflags) -LIBOPENMPT_LDFLAGS?=$(shell $(PKG_CONFIG) $(LIBOPENMPT_PKGCONFIG) --libs) - -LIBS+=$(LIBOPENMPT_LDFLAGS) -CFLAGS+=$(LIBOPENMPT_CFLAGS) -endif - -ifndef NOZLIB -OPTS+=-DHAVE_ZLIB -ZLIB_PKGCONFIG?=zlib -ZLIB_CFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --cflags) -ZLIB_LDFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --libs) - -LIBS+=$(ZLIB_LDFLAGS) -CFLAGS+=$(ZLIB_CFLAGS) -else -NOPNG=1 -endif - -ifndef NOCURL -OPTS+=-DHAVE_CURL -CURLCONFIG?=curl-config -CURL_CFLAGS?=$(shell $(CURLCONFIG) --cflags) -CURL_LDFLAGS?=$(shell $(CURLCONFIG) --libs) - -LIBS+=$(CURL_LDFLAGS) -CFLAGS+=$(CURL_CFLAGS) -endif - -ifdef STATIC -LIBS:=-static $(LIBS) -endif - -ifdef HAVE_MINIUPNPC -ifdef NONET -HAVE_MINIUPNPC='' -else -LIBS+=-lminiupnpc -ifdef MINGW -LIBS+=-lws2_32 -liphlpapi -endif -CFLAGS+=-DHAVE_MINIUPNPC -endif -endif - -ifdef HAVE_DISCORDRPC -LIBS+=-ldiscord-rpc -CFLAGS+=-DHAVE_DISCORDRPC -DUSE_STUN -OBJS+=$(OBJDIR)/discord.o $(OBJDIR)/stun.o -endif - -include blua/Makefile.cfg - -ifdef NOMD5 - OPTS+=-DNOMD5 -else - OBJS:=$(OBJDIR)/md5.o $(OBJS) -endif - -ifdef NOPOSTPROCESSING - OPTS+=-DNOPOSTPROCESSING -endif - - OPTS:=-fno-exceptions $(OPTS) - -ifdef MOBJCONSISTANCY - OPTS+=-DMOBJCONSISTANCY -endif - -ifdef PACKETDROP - OPTS+=-DPACKETDROP -endif - -ifdef DEBUGMODE - - # build with debugging information - WINDRESFLAGS = -D_DEBUG -ifdef GCC48 - CFLAGS+=-Og -else - CFLAGS+=-O0 -endif - CFLAGS+= -Wall -DPARANOIA -DRANGECHECK -DPACKETDROP -else - - - # build a normal optimised version - WINDRESFLAGS = -DNDEBUG - CFLAGS+=-O3 -endif - CFLAGS+=-g $(OPTS) $(ARCHOPTS) $(WINDRESFLAGS) - -ifdef TESTERS - OPTS+=-DTESTERS +NASM?=nasm endif ifdef YASM ifdef STABS - NASMOPTS?= -g stabs +NASMOPTS?=-g stabs else - NASMOPTS?= -g dwarf2 +NASMOPTS?=-g dwarf2 endif else - NASMOPTS?= -g +NASMOPTS?=-g endif -ifdef PROFILEMODE - # build with profiling information - CFLAGS+=-pg - LDFLAGS+=-pg +GZIP?=gzip +GZIP_OPTS?=-9 -f -n +ifdef WINDOWSHELL +GZIP_OPTS+=--rsyncable endif -ifdef ZDEBUG - CPPFLAGS+=-DZDEBUG +UPX_OPTS?=--best --preserve-build-id +ifndef ECHO +UPX_OPTS+=-qq endif -ifdef DEVELOP - CPPFLAGS+=-DDEVELOP +include Makefile.d/detect.mk + +# make would try to remove the implicitly made directories +.PRECIOUS : %/ comptime.c + +sources:= +makedir:=../make + +# -DCOMPVERSION: flag to use comptime.h +opts:=-DCOMPVERSION -g +libs:= + +nasm_format:= + +# This is a list of variables names, of which if defined, +# also defines the name as a macro to the compiler. +passthru_opts:= + +include Makefile.d/platform.mk +include Makefile.d/features.mk +include Makefile.d/versions.mk + +ifdef DEBUGMODE +makedir:=$(makedir)/debug endif -OPTS+=$(CPPFLAGS) +depdir:=$(makedir)/deps +objdir:=$(makedir)/objs -# default EXENAME if all else fails +# very sophisticated dependency +sources+=\ + $(call List,Sourcefile)\ + $(call List,blua/Sourcefile)\ + +depends:=$(basename $(filter %.c %.s,$(sources))) +objects:=$(basename $(filter %.c %.s %.nas,$(sources))) + +depends:=$(depends:%=$(depdir)/%.d) + +# comptime.o added directly to objects instead of thru +# sources because comptime.c includes comptime.h, but +# comptime.h may not exist yet. It's a headache so this is +# easier. +objects:=$(objects:=.o) comptime.o + +# windows resource file +rc_file:=$(basename $(filter %.rc,$(sources))) +ifdef rc_file +objects+=$(rc_file:=.res) +endif + +objects:=$(addprefix $(objdir)/,$(objects)) + +ifdef DEBUGMODE +bin:=../bin/debug +else +bin:=../bin +endif + +# default EXENAME (usually set by platform) EXENAME?=srb2 DBGNAME?=$(EXENAME).debug -# $(OBJDIR)/dstrings.o \ +exe:=$(bin)/$(EXENAME) +dbg:=$(bin)/$(DBGNAME) -# not too sophisticated dependency -# SRB2kart kart.o on line 433 below -OBJS:=$(i_main_o) \ - $(OBJDIR)/string.o \ - $(OBJDIR)/d_main.o \ - $(OBJDIR)/d_clisrv.o \ - $(OBJDIR)/d_net.o \ - $(OBJDIR)/d_netfil.o \ - $(OBJDIR)/d_netcmd.o \ - $(OBJDIR)/dehacked.o \ - $(OBJDIR)/deh_soc.o \ - $(OBJDIR)/deh_lua.o \ - $(OBJDIR)/deh_tables.o \ - $(OBJDIR)/z_zone.o \ - $(OBJDIR)/f_finale.o \ - $(OBJDIR)/f_wipe.o \ - $(OBJDIR)/g_demo.o \ - $(OBJDIR)/g_game.o \ - $(OBJDIR)/g_input.o \ - $(OBJDIR)/g_splitscreen.o\ - $(OBJDIR)/am_map.o \ - $(OBJDIR)/command.o \ - $(OBJDIR)/console.o \ - $(OBJDIR)/font.o \ - $(OBJDIR)/hu_stuff.o \ - $(OBJDIR)/y_inter.o \ - $(OBJDIR)/st_stuff.o \ - $(OBJDIR)/m_aatree.o \ - $(OBJDIR)/m_anigif.o \ - $(OBJDIR)/m_argv.o \ - $(OBJDIR)/m_bbox.o \ - $(OBJDIR)/m_cheat.o \ - $(OBJDIR)/m_cond.o \ - $(OBJDIR)/m_fixed.o \ - $(OBJDIR)/m_menu.o \ - $(OBJDIR)/m_misc.o \ - $(OBJDIR)/m_perfstats.o \ - $(OBJDIR)/m_random.o \ - $(OBJDIR)/m_queue.o \ - $(OBJDIR)/info.o \ - $(OBJDIR)/p_ceilng.o \ - $(OBJDIR)/p_enemy.o \ - $(OBJDIR)/p_floor.o \ - $(OBJDIR)/p_inter.o \ - $(OBJDIR)/p_lights.o \ - $(OBJDIR)/p_map.o \ - $(OBJDIR)/p_maputl.o \ - $(OBJDIR)/p_mobj.o \ - $(OBJDIR)/p_polyobj.o\ - $(OBJDIR)/p_saveg.o \ - $(OBJDIR)/p_setup.o \ - $(OBJDIR)/p_sight.o \ - $(OBJDIR)/p_spec.o \ - $(OBJDIR)/p_telept.o \ - $(OBJDIR)/p_tick.o \ - $(OBJDIR)/p_user.o \ - $(OBJDIR)/p_slopes.o \ - $(OBJDIR)/tables.o \ - $(OBJDIR)/r_bsp.o \ - $(OBJDIR)/r_data.o \ - $(OBJDIR)/r_draw.o \ - $(OBJDIR)/r_main.o \ - $(OBJDIR)/r_plane.o \ - $(OBJDIR)/r_segs.o \ - $(OBJDIR)/r_skins.o \ - $(OBJDIR)/r_sky.o \ - $(OBJDIR)/r_splats.o \ - $(OBJDIR)/r_things.o \ - $(OBJDIR)/r_textures.o \ - $(OBJDIR)/r_patch.o \ - $(OBJDIR)/r_patchrotation.o \ - $(OBJDIR)/r_picformats.o \ - $(OBJDIR)/r_portal.o \ - $(OBJDIR)/screen.o \ - $(OBJDIR)/taglist.o \ - $(OBJDIR)/v_video.o \ - $(OBJDIR)/s_sound.o \ - $(OBJDIR)/sounds.o \ - $(OBJDIR)/w_wad.o \ - $(OBJDIR)/filesrch.o \ - $(OBJDIR)/mserv.o \ - $(OBJDIR)/http-mserv.o\ - $(OBJDIR)/i_tcp.o \ - $(OBJDIR)/lzf.o \ - $(OBJDIR)/vid_copy.o \ - $(OBJDIR)/k_kart.o \ - $(OBJDIR)/k_respawn.o\ - $(OBJDIR)/k_collide.o\ - $(OBJDIR)/k_color.o \ - $(OBJDIR)/k_race.o \ - $(OBJDIR)/k_battle.o \ - $(OBJDIR)/k_pwrlv.o \ - $(OBJDIR)/k_waypoint.o\ - $(OBJDIR)/k_pathfind.o\ - $(OBJDIR)/k_bheap.o \ - $(OBJDIR)/k_bot.o \ - $(OBJDIR)/k_botitem.o\ - $(OBJDIR)/k_botsearch.o\ - $(OBJDIR)/k_grandprix.o\ - $(OBJDIR)/k_hud.o \ - $(i_cdmus_o) \ - $(i_net_o) \ - $(i_system_o) \ - $(i_sound_o) \ - $(OBJS) +build_done==== Build is done, look for \ + $( $@ + $(.)$(GZIP) $(GZIP_OPTS) $@ -ifdef SDL -all: $(BIN)/$(EXENAME) -endif - -ifdef DUMMY -all: $(BIN)/$(EXENAME) -endif - -cleandep: - $(REMOVE) $(DEPS) - $(REMOVE) comptime.h - -clean: - $(REMOVE) *~ *.flc - $(REMOVE) $(OBJDIR)/*.o - -distclean: clean cleandep - -ifdef MINGW - $(REMOVE) $(OBJDIR)/*.res -endif - -ifdef CYGWIN32 - $(REMOVE) $(OBJDIR)/*.res -endif - -#make a big srb2.s that is the disasm of the exe (dos only ?) -asm: - $(CC) $(LDFLAGS) $(OBJS) -o $(OBJDIR)/tmp.exe $(LIBS) - $(OBJDUMP) -d $(OBJDIR)/tmp.exe --no-show-raw-insn > srb2.s - $(REMOVE) $(OBJDIR)/tmp.exe - -# executable -# NOTE: DJGPP's objcopy do not have --add-gnu-debuglink - -$(BIN)/$(EXENAME): $(POS) $(OBJS) - -$(MKDIR) $(BIN) - $(call echo,Linking $(EXENAME)...) - $(LD) $(LDFLAGS) $(OBJS) -o $(BIN)/$(EXENAME) $(LIBS) -ifndef VALGRIND -ifndef NOOBJDUMP - $(call echo,Dumping debugging info) - $(OBJDUMP) $(OBJDUMP_OPTS) $(BIN)/$(EXENAME) > $(BIN)/$(DBGNAME).txt +# '::' means run unconditionally +# this really updates comptime.h +comptime.c :: ifdef WINDOWSHELL - -$(GZIP) $(GZIP_OPTS) $(BIN)/$(DBGNAME).txt + $(.)..\comptime.bat . else - -$(GZIP) $(GZIP_OPT2) $(BIN)/$(DBGNAME).txt -endif + $(.)../comptime.sh . endif -# mac os x lsdlsrb2 does not like objcopy -ifndef MACOSX - $(OBJCOPY) $(BIN)/$(EXENAME) $(BIN)/$(DBGNAME) - $(OBJCOPY) --strip-debug $(BIN)/$(EXENAME) - -$(OBJCOPY) --add-gnu-debuglink=$(BIN)/$(DBGNAME) $(BIN)/$(EXENAME) -endif -ifndef NOUPX - -$(UPX) $(UPX_OPTS) $(BIN)/$(EXENAME) -endif -endif - $(call echo,Build is done$(,) please look for $(EXENAME) in $(BIN)$(,) (checking for post steps)) +# I wish I could make dependencies out of rc files :( +$(objdir)/win32/Srb2win.res : \ + win32/afxres.h win32/resource.h -reobjdump: - $(call echo,Redumping debugging info) - $(OBJDUMP) $(OBJDUMP_OPTS) $(BIN)/$(DBGNAME) > $(BIN)/$(DBGNAME).txt -ifdef WINDOWSHELL - -$(GZIP) $(GZIP_OPTS) $(BIN)/$(DBGNAME).txt -else - -$(GZIP) $(GZIP_OPT2) $(BIN)/$(DBGNAME).txt -endif - -$(OBJDIR): - -$(MKDIR) $(OBJDIR) - -ifdef SDL -ifdef MINGW -$(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 \ - command.h hardware/hw_data.h hardware/hw_defs.h \ - hardware/hw_md2.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 \ - 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 - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ -else -$(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 \ - command.h hardware/hw_data.h hardware/hw_defs.h \ - hardware/hw_md2.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 \ - 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 - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -I/usr/X11R6/include -c $< -o $@ -endif -endif - -#dependecy made by gcc itself ! -ifndef DUMMY -ifndef CLEANONLY -$(call print,Checking dependency files...) --include $(DEPS) -endif -endif - -undefine deps_rule - -# windows makes it too hard ! +# dependency recipe template +# 1: source file suffix +# 2: extra flags to gcc +define _recipe = +$(depdir)/%.d : %.$(1) | $$$$(@D)/ ifndef WINDOWSHELL -ifdef echoName -define deps_rule = - @printf "%-20.20s\r" $< - -endef +ifdef Echo_name + @printf '%-20.20s\r' $$< endif endif - -define deps_rule += - $(CC) $(CFLAGS) -M -MF $@ -MT $(OBJDIR)/$(<:.c=.o) $< + $(.)$(cc) -MM -MF $$@ -MT $(objdir)/$$*.o $(2) $$< endef -$(DEPDIR)/%.d: %.c - $(deps_rule) +$(eval $(call _recipe,c)) +$(eval $(call _recipe,s,$(asflags))) -$(DEPDIR)/%.d: $(INTERFACE)/%.c - $(deps_rule) +# compiling recipe template +# 1: target file suffix +# 2: source file suffix +# 3: compile command +define _recipe = +$(objdir)/%.$(1) : %.$(2) | $$$$(@D)/ + $(call Echo_name,$$<) + $(.)$(3) +endef -$(DEPDIR)/%.d: hardware/%.c - $(deps_rule) +$(eval $(call _recipe,o,c,$(cc) -c -o $$@ $$<)) +$(eval $(call _recipe,o,nas,$(nasm) -o $$@ $$<)) +$(eval $(call _recipe,o,s,$(cc) $(asflags) -c -o $$@ $$<)) +$(eval $(call _recipe,res,rc,$(windres) -i $$< -o $$@)) -$(DEPDIR)/%.d: blua/%.c - $(deps_rule) +_rm=$(.)$(rmrf) $(call Windows_path,$(1)) -ifdef VALGRIND -$(OBJDIR)/z_zone.o: z_zone.c - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -DHAVE_VALGRIND $(VALGRIND_CFLAGS) -c $< -o $@ -endif +cleandep : + $(call _rm,$(depends) comptime.h) -$(OBJDIR)/comptime.o:: -ifdef echoName - @echo -- comptime.c ... -endif - $(COMPTIME) . - $(CC) $(CFLAGS) $(WFLAGS) -c comptime.c -o $@ +clean : + $(call _rm,$(exe) $(dbg) $(dbg).txt $(objects)) -$(BIN)/%.mo: locale/%.po - -$(MKDIR) $(BIN) - $(echoName) - $(MSGFMT) -f -o $@ $< +distclean : + $(call _rm,../bin ../objs ../dep ../make comptime.h) -$(OBJDIR)/%.o: %.c - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -$(OBJDIR)/%.o: $(INTERFACE)/%.c - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -ifdef MACOSX -$(OBJDIR)/%.o: sdl/macosx/%.c - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ -endif - -$(OBJDIR)/%.o: hardware/%.c - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -$(OBJDIR)/%.o: blua/%.c - $(echoName) - $(CC) $(CFLAGS) $(LUA_CFLAGS) $(WFLAGS) -c $< -o $@ - -$(OBJDIR)/%.o: %.nas - $(echoName) - $(NASM) $(NASMOPTS) -o $@ -f $(NASMFORMAT) $< - -$(OBJDIR)/vid_copy.o: vid_copy.s asm_defs.inc - $(echoName) - $(CC) $(OPTS) $(ASFLAGS) -x assembler-with-cpp -c $< -o $@ - -$(OBJDIR)/%.o: %.s - $(echoName) - $(CC) $(OPTS) -x assembler-with-cpp -c $< -o $@ - -$(OBJDIR)/SRB2.res: win32/Srb2win.rc win32/afxres.h win32/resource.h - $(echoName) - $(WINDRES) -i $< -O rc $(WINDRESFLAGS) --include-dir=win32 -o $@ -O coff - - -ifdef SDL - -ifdef MINGW -$(OBJDIR)/win_dbg.o: win32/win_dbg.c - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ -endif - -ifdef STATICHS -$(OBJDIR)/s_openal.o: hardware/s_openal/s_openal.c hardware/hw3dsdrv.h \ - hardware/hw_dll.h - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -$(OBJDIR)/s_fmod.o: hardware/s_fmod/s_fmod.c hardware/hw3dsdrv.h \ - hardware/hw_dll.h - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ - -ifdef MINGW -$(OBJDIR)/s_ds3d.o: hardware/s_ds3d/s_ds3d.c hardware/hw3dsdrv.h \ - hardware/hw_dll.h - $(echoName) - $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ -endif +info: +ifdef WINDOWSHELL + @REM else - -$(OBJDIR)/s_fmod.o: hardware/s_fmod/s_fmod.c hardware/hw3dsdrv.h \ - hardware/hw_dll.h - $(echoName) - $(CC) $(ARCHOPTS) -Os -o $(OBJDIR)/s_fmod.o -DHW3SOUND -DUNIXCOMMON -shared -nostartfiles -c hardware/s_fmod/s_fmod.c - -$(OBJDIR)/s_openal.o: hardware/s_openal/s_openal.c hardware/hw3dsdrv.h \ - hardware/hw_dll.h - $(echoName) - $(CC) $(ARCHOPTS) -Os -o $(OBJDIR)/s_openal.o -DHW3SOUND -DUNIXCOMMON -shared -nostartfiles -c hardware/s_openal/s_openal.c + @: endif -endif - -############################################################# -# -############################################################# diff --git a/src/Makefile.cfg b/src/Makefile.cfg deleted file mode 100644 index a4fef3c3e..000000000 --- a/src/Makefile.cfg +++ /dev/null @@ -1,482 +0,0 @@ -# vim: ft=make -# -# Makefile.cfg for SRB2 -# - -# -# GNU compiler & tools' flags -# and other things -# - -# See the following variable don't start with 'GCC'. This is -# to avoid a false positive with the version detection... - -SUPPORTED_GCC_VERSIONS:=\ - 101 102\ - 91 92 93\ - 81 82 83 84\ - 71 72 73 74 75\ - 61 62 63 64\ - 51 52 53 54 55\ - 40 41 42 43 44 45 46 47 48 49 - -LATEST_GCC_VERSION=10.2 - -# gcc or g++ -ifdef PREFIX - CC=$(PREFIX)-gcc - CXX=$(PREFIX)-g++ - OBJCOPY=$(PREFIX)-objcopy - OBJDUMP=$(PREFIX)-objdump - STRIP=$(PREFIX)-strip - WINDRES=$(PREFIX)-windres -else - OBJCOPY=objcopy - OBJDUMP=objdump - STRIP=strip - WINDRES=windres -endif - -# because Apple screws with us on this -# need to get bintools from homebrew -ifdef MACOSX - CC=clang - CXX=clang - OBJCOPY=gobjcopy - OBJDUMP=gobjdump -endif - -# Automatically set version flag, but not if one was manually set -# And don't bother if this is a clean only run -ifeq (,$(filter GCC% CLEANONLY,$(.VARIABLES))) - version:=$(shell $(CC) --version) - # check if this is in fact GCC - ifneq (,$(or $(findstring gcc,$(version)),$(findstring GCC,$(version)))) - version:=$(shell $(CC) -dumpversion) - - # Turn version into words of major, minor - v:=$(subst ., ,$(version)) - # concat. major minor - v:=$(word 1,$(v))$(word 2,$(v)) - - # If this version is not in the list, default to the latest supported - ifeq (,$(filter $(v),$(SUPPORTED_GCC_VERSIONS))) - define line = - Your compiler version, GCC $(version), is not supported by the Makefile. - The Makefile will assume GCC $(LATEST_GCC_VERSION).)) - endef - $(call print,$(line)) - GCC$(subst .,,$(LATEST_GCC_VERSION))=1 - else - $(call print,Detected GCC $(version) (GCC$(v))) - GCC$(v)=1 - endif - endif -endif - -ifdef GCC102 -GCC101=1 -endif - -ifdef GCC101 -GCC93=1 -endif - -ifdef GCC93 -GCC92=1 -endif - -ifdef GCC92 -GCC91=1 -endif - -ifdef GCC91 -GCC84=1 -endif - -ifdef GCC84 -GCC83=1 -endif - -ifdef GCC83 -GCC82=1 -endif - -ifdef GCC82 -GCC81=1 -endif - -ifdef GCC81 -GCC75=1 -endif - -ifdef GCC75 -GCC74=1 -endif - -ifdef GCC74 -GCC73=1 -endif - -ifdef GCC73 -GCC72=1 -endif - -ifdef GCC72 -GCC71=1 -endif - -ifdef GCC71 -GCC64=1 -endif - -ifdef GCC64 -GCC63=1 -endif - -ifdef GCC63 -GCC62=1 -endif - -ifdef GCC62 -GCC61=1 -endif - -ifdef GCC61 -GCC55=1 -endif - -ifdef GCC55 -GCC54=1 -endif - -ifdef GCC54 -GCC53=1 -endif - -ifdef GCC53 -GCC52=1 -endif - -ifdef GCC52 -GCC51=1 -endif - -ifdef GCC51 -GCC49=1 -endif - -ifdef GCC49 -GCC48=1 -endif - -ifdef GCC48 -GCC47=1 -endif - -ifdef GCC47 -GCC46=1 -endif - -ifdef GCC46 -GCC45=1 -endif - -ifdef GCC45 -GCC44=1 -endif - -ifdef GCC44 -GCC43=1 -endif - -ifdef GCC43 -GCC42=1 -endif - -ifdef GCC42 -GCC41=1 -endif - -ifdef GCC41 -GCC40=1 -VCHELP=1 -endif - -ifdef GCC295 -GCC29=1 -endif - -OLDWFLAGS:=$(WFLAGS) -# -W -Wno-unused -WFLAGS=-Wall -ifndef GCC295 -#WFLAGS+=-Wno-packed -endif -ifndef RELAXWARNINGS - WFLAGS+=-W -#WFLAGS+=-Wno-sign-compare -ifndef GCC295 - WFLAGS+=-Wno-div-by-zero -endif -#WFLAGS+=-Wsystem-headers -WFLAGS+=-Wfloat-equal -#WFLAGS+=-Wtraditional -ifdef VCHELP - WFLAGS+=-Wdeclaration-after-statement - WFLAGS+=-Wno-error=declaration-after-statement -endif - WFLAGS+=-Wundef -ifndef GCC295 - WFLAGS+=-Wendif-labels -endif -ifdef GCC40 - WFLAGS+=-std=gnu89 -endif -ifdef GCC41 - WFLAGS+=-Wshadow -endif -#WFLAGS+=-Wlarger-than-%len% - WFLAGS+=-Wpointer-arith -Wbad-function-cast -ifdef GCC45 -#WFLAGS+=-Wc++-compat -endif - WFLAGS+=-Wcast-qual -ifndef NOCASTALIGNWARN - WFLAGS+=-Wcast-align -endif - WFLAGS+=-Wwrite-strings -ifndef ERRORMODE -#WFLAGS+=-Wconversion -ifdef GCC43 - #WFLAGS+=-Wno-sign-conversion -endif -endif - WFLAGS+=-Wsign-compare -ifdef GCC91 - WFLAGS+=-Wno-error=address-of-packed-member -endif -ifdef GCC45 - WFLAGS+=-Wlogical-op -endif - WFLAGS+=-Waggregate-return -ifdef HAIKU -ifdef GCC41 - #WFLAGS+=-Wno-attributes -endif -endif -#WFLAGS+=-Wstrict-prototypes -ifdef GCC40 - WFLAGS+=-Wold-style-definition -endif - WFLAGS+=-Wmissing-prototypes -Wmissing-declarations -ifdef GCC40 - WFLAGS+=-Wmissing-field-initializers -endif - WFLAGS+=-Wmissing-noreturn -#WFLAGS+=-Wmissing-format-attribute -#WFLAGS+=-Wno-multichar -#WFLAGS+=-Wno-deprecated-declarations -#WFLAGS+=-Wpacked -#WFLAGS+=-Wpadded -#WFLAGS+=-Wredundant-decls - WFLAGS+=-Wnested-externs -#WFLAGS+=-Wunreachable-code - WFLAGS+=-Winline -ifdef GCC43 - WFLAGS+=-funit-at-a-time - WFLAGS+=-Wlogical-op -endif -ifndef GCC295 - WFLAGS+=-Wdisabled-optimization -endif -endif -WFLAGS+=-Wformat-y2k -ifdef GCC71 -WFLAGS+=-Wno-error=format-overflow=2 -endif -WFLAGS+=-Wformat-security -ifndef GCC29 -#WFLAGS+=-Winit-self -endif -ifdef GCC46 -WFLAGS+=-Wno-suggest-attribute=noreturn -endif - -ifdef NOLDWARNING -LDFLAGS+=-Wl,--as-needed -endif - -ifdef ERRORMODE -WFLAGS+=-Werror -endif - -WFLAGS+=$(OLDWFLAGS) - -ifdef GCC43 - #WFLAGS+=-Wno-error=clobbered -endif -ifdef GCC44 - WFLAGS+=-Wno-error=array-bounds -endif -ifdef GCC46 - WFLAGS+=-Wno-error=suggest-attribute=noreturn -endif -ifdef GCC54 - WFLAGS+=-Wno-logical-op -Wno-error=logical-op -endif -ifdef GCC61 - WFLAGS+=-Wno-tautological-compare -Wno-error=tautological-compare -endif -ifdef GCC71 - WFLAGS+=-Wimplicit-fallthrough=4 - WFLAGS+=-Wno-format-truncation -endif -ifdef GCC81 - WFLAGS+=-Wno-error=format-overflow - WFLAGS+=-Wno-error=stringop-truncation - WFLAGS+=-Wno-error=stringop-overflow - WFLAGS+=-Wno-format-overflow - WFLAGS+=-Wno-stringop-truncation - WFLAGS+=-Wno-stringop-overflow - WFLAGS+=-Wno-error=multistatement-macros -endif - - -#indicate platform and what interface use with -ifndef LINUX -ifndef FREEBSD -ifndef CYGWIN32 -ifndef MINGW -ifndef MINGW64 -ifndef SDL -ifndef DUMMY -$(error No interface or platform flag defined) -endif -endif -endif -endif -endif -endif -endif - -#determine the interface directory (where you put all i_*.c) -i_net_o=$(OBJDIR)/i_net.o -i_system_o=$(OBJDIR)/i_system.o -i_sound_o=$(OBJDIR)/i_sound.o -i_main_o=$(OBJDIR)/i_main.o -#set OBJDIR and BIN's starting place -OBJDIR=../objs -BIN=../bin -DEPDIR=../dep -#Nasm ASM and rm -ifdef YASM -NASM?=yasm -else -NASM?=nasm -endif -REMOVE?=rm -f -MKDIR?=mkdir -p -GZIP?=gzip -GZIP_OPTS?=-9 -f -n -GZIP_OPT2=$(GZIP_OPTS) --rsyncable -UPX?=upx -UPX_OPTS?=--best --preserve-build-id -ifndef ECHO -UPX_OPTS+=-q -endif - -#Interface Setup -ifdef DUMMY - INTERFACE=dummy - OBJDIR:=$(OBJDIR)/dummy - BIN:=$(BIN)/dummy - DEPDIR:=$(DEPDIR)/dummy -else -ifdef LINUX - NASMFORMAT=elf -DLINUX - SDL=1 -ifdef LINUX64 - OBJDIR:=$(OBJDIR)/Linux64 - BIN:=$(BIN)/Linux64 - DEPDIR:=$(DEPDIR)/Linux64 -else - OBJDIR:=$(OBJDIR)/Linux - BIN:=$(BIN)/Linux - DEPDIR:=$(DEPDIR)/Linux -endif -else -ifdef FREEBSD - INTERFACE=sdl - NASMFORMAT=elf -DLINUX - SDL=1 - - OBJDIR:=$(OBJDIR)/FreeBSD - BIN:=$(BIN)/FreeBSD - DEPDIR:=$(DEPDIR)/Linux -else -ifdef SOLARIS - INTERFACE=sdl - NASMFORMAT=elf -DLINUX - SDL=1 - - OBJDIR:=$(OBJDIR)/Solaris - BIN:=$(BIN)/Solaris - DEPDIR:=$(DEPDIR)/Solaris -else -ifdef CYGWIN32 - INTERFACE=sdl - NASMFORMAT=win32 - SDL=1 - - OBJDIR:=$(OBJDIR)/cygwin - BIN:=$(BIN)/Cygwin - DEPDIR:=$(DEPDIR)/Cygwin -else -ifdef MINGW64 - #NASMFORMAT=win64 - SDL=1 - OBJDIR:=$(OBJDIR)/Mingw64 - BIN:=$(BIN)/Mingw64 - DEPDIR:=$(DEPDIR)/Mingw64 -else -ifdef MINGW - NASMFORMAT=win32 - SDL=1 - OBJDIR:=$(OBJDIR)/Mingw - BIN:=$(BIN)/Mingw - DEPDIR:=$(DEPDIR)/Mingw -endif -endif -endif -endif -endif -endif -endif - -ifdef ARCHNAME - OBJDIR:=$(OBJDIR)/$(ARCHNAME) - BIN:=$(BIN)/$(ARCHNAME) - DEPDIR:=$(DEPDIR)/$(ARCHNAME) -endif - -OBJDUMP_OPTS?=--wide --source --line-numbers -LD=$(CC) - -ifdef SDL - INTERFACE=sdl - OBJDIR:=$(OBJDIR)/SDL - DEPDIR:=$(DEPDIR)/SDL -endif - -ifndef DUMMY -ifdef DEBUGMODE - OBJDIR:=$(OBJDIR)/Debug - BIN:=$(BIN)/Debug - DEPDIR:=$(DEPDIR)/Debug -else - OBJDIR:=$(OBJDIR)/Release - BIN:=$(BIN)/Release - DEPDIR:=$(DEPDIR)/Release -endif -endif diff --git a/src/Makefile.d/detect.mk b/src/Makefile.d/detect.mk new file mode 100644 index 000000000..f458b044c --- /dev/null +++ b/src/Makefile.d/detect.mk @@ -0,0 +1,107 @@ +# +# Detect the host system and compiler version. +# + +# Previously featured:\ + PANDORA\ + HAIKU\ + DUMMY\ + DJGPPDOS\ + SOLARIS\ + MACOSX\ + +all_systems:=\ + LINUX64\ + MINGW64\ + MINGW\ + UNIX\ + LINUX\ + FREEBSD\ + SDL\ + +# check for user specified system +ifeq (,$(filter $(all_systems),$(.VARIABLES))) +ifeq ($(OS),Windows_NT) # all windows are Windows_NT... + +_m=Detected a Windows system,\ + compiling for 32-bit MinGW SDL...) +$(call Print,$(_m)) + +# go for a 32-bit sdl mingw exe by default +MINGW:=1 + +else # if you on the *nix + +system:=$(shell uname -s) + +ifeq ($(system),Linux) +new_system:=LINUX +else + +$(error \ + Could not automatically detect your system,\ + try specifying a system manually) + +endif + +ifeq ($(shell getconf LONG_BIT),64) +system+=64-bit +new_system:=$(new_system)64 +endif + +$(call Print,Detected $(system) ($(new_system))...) +$(new_system):=1 + +endif +endif + +# This must have high to low order. +gcc_versions:=\ + 102 101\ + 93 92 91\ + 84 83 82 81\ + 75 74 73 72 71\ + 64 63 62 61\ + 55 54 53 52 51\ + 49 48 47 46 45 44 43 42 41 40 + +latest_gcc_version:=10.2 + +# Automatically set version flag, but not if one was +# manually set. And don't bother if this is a clean only +# run. +ifeq (,$(call Wildvar,GCC% destructive)) + +# can't use $(CC) --version here since that uses argv[0] to display the name +# also gcc outputs the information to stderr, so I had to do 2>&1 +# this program really doesn't like identifying itself +version:=$(shell $(CC) -v 2>&1) + +# check if this is in fact GCC +ifneq (,$(findstring gcc version,$(version))) + +# in stark contrast to the name, gcc will give me a nicely formatted version number for free +version:=$(shell $(CC) -dumpfullversion) + +# Turn version into words of major, minor +v:=$(subst ., ,$(version)) +# concat. major minor +v:=$(word 1,$(v))$(word 2,$(v)) + +# If this version is not in the list, +# default to the latest supported +ifeq (,$(filter $(v),$(gcc_versions))) +define line = +Your compiler version, GCC $(version), \ +is not supported by the Makefile. +The Makefile will assume GCC $(latest_gcc_version). +endef +$(call Print,$(line)) +GCC$(subst .,,$(latest_gcc_version)):=1 +else +$(call Print,Detected GCC $(version) (GCC$(v))) +GCC$(v):=1 +endif + +endif +endif diff --git a/src/Makefile.d/features.mk b/src/Makefile.d/features.mk new file mode 100644 index 000000000..a29a8a153 --- /dev/null +++ b/src/Makefile.d/features.mk @@ -0,0 +1,84 @@ +# +# Makefile for feature flags. +# + +passthru_opts+=\ + NONET NO_IPV6 NOHW NOMD5 NOPOSTPROCESSING\ + MOBJCONSISTANCY PACKETDROP ZDEBUG\ + HAVE_MINIUPNPC\ + HAVE_DISCORDRPC TESTERS DEVELOP + +# build with debugging information +ifdef DEBUGMODE +MOBJCONSISTANCY=1 +PACKETDROP=1 +opts+=-DPARANOIA -DRANGECHECK +endif + +ifndef NOHW +opts+=-DHWRENDER +sources+=$(call List,hardware/Sourcefile) +endif + +ifndef NOASM +ifndef NONX86 +sources+=tmap.nas tmap_mmx.nas +opts+=-DUSEASM +endif +endif + +ifndef NOMD5 +sources+=md5.c +endif + +ifndef NOZLIB +ifndef NOPNG +ifdef PNG_PKGCONFIG +$(eval $(call Use_pkg_config,PNG_PKGCONFIG)) +else +PNG_CONFIG?=$(call Prefix,libpng-config) +$(eval $(call Configure,PNG,$(PNG_CONFIG) \ + $(if $(PNG_STATIC),--static),,--ldflags)) +endif +ifdef LINUX +opts+=-D_LARGFILE64_SOURCE +endif +opts+=-DHAVE_PNG +sources+=apng.c +endif +endif + +ifndef NONET +ifndef NOCURL +CURLCONFIG?=curl-config +$(eval $(call Configure,CURL,$(CURLCONFIG))) +opts+=-DHAVE_CURL +endif +endif + +ifdef HAVE_MINIUPNPC +libs+=-lminiupnpc +endif + +ifdef HAVE_DISCORDRPC +$(eval $(call Propogate_flags,DISCORDRPC)) +libs+=-ldiscord-rpc +opts+=-DUSE_STUN +sources+=discord.c stun.c +endif + +# (Valgrind is a memory debugger.) +ifdef VALGRIND +VALGRIND_PKGCONFIG?=valgrind +$(eval $(call Use_pkg_config,VALGRIND)) +ZDEBUG=1 +opts+=-DHAVE_VALGRIND +endif + +default_packages:=\ + GME/libgme/LIBGME\ + OPENMPT/libopenmpt/LIBOPENMPT\ + ZLIB/zlib\ + +$(foreach p,$(default_packages),\ + $(eval $(call Check_pkg_config,$(p)))) diff --git a/src/Makefile.d/nix.mk b/src/Makefile.d/nix.mk new file mode 100644 index 000000000..98703e769 --- /dev/null +++ b/src/Makefile.d/nix.mk @@ -0,0 +1,40 @@ +# +# Makefile options for unices (linux, bsd...) +# + +EXENAME?=lsdl2srb2kart + +opts+=-DUNIXCOMMON -DLUA_USE_POSIX +libs+=-lm + +ifndef nasm_format +nasm_format:=elf -DLINUX +endif + +ifndef NOHW +opts+=-I/usr/X11R6/include +libs+=-L/usr/X11R6/lib +endif + +SDL=1 + +# In common usage. +ifdef LINUX +libs+=-lrt +passthru_opts+=NOTERMIOS +endif + +# Tested by Steel, as of release 2.2.8. +ifdef FREEBSD +opts+=-I/usr/X11R6/include -DLINUX -DFREEBSD +libs+=-L/usr/X11R6/lib -lipx -lkvm +endif + +# FIXME: UNTESTED +#ifdef SOLARIS +#NOIPX=1 +#NOASM=1 +#opts+=-I/usr/local/include -I/opt/sfw/include \ +# -DSOLARIS -DINADDR_NONE=INADDR_ANY -DBSD_COMP +#libs+=-L/opt/sfw/lib -lsocket -lnsl +#endif diff --git a/src/Makefile.d/old.mk b/src/Makefile.d/old.mk new file mode 100644 index 000000000..ec9b6d776 --- /dev/null +++ b/src/Makefile.d/old.mk @@ -0,0 +1,16 @@ +# +# Warn about old build directories and offer to purge. +# + +_old:=$(wildcard $(addprefix ../bin/,FreeBSD Linux \ + Linux64 Mingw Mingw64 SDL dummy) ../objs ../dep) + +ifdef _old +$(foreach v,$(_old),$(info $(abspath $(v)))) +$(info ) +$(info These directories are no longer\ + required and should be removed.) +$(info You may remove them manually or\ + by using 'make distclean') +$(error ) +endif diff --git a/src/Makefile.d/platform.mk b/src/Makefile.d/platform.mk new file mode 100644 index 000000000..fad4be191 --- /dev/null +++ b/src/Makefile.d/platform.mk @@ -0,0 +1,69 @@ +# +# Platform specific options. +# + +PKG_CONFIG?=pkg-config + +ifdef WINDOWSHELL +rmrf=-2>NUL DEL /S /Q +mkdir=-2>NUL MD +cat=TYPE +else +rmrf=rm -rf +mkdir=mkdir -p +cat=cat +endif + +ifdef LINUX64 +LINUX=1 +endif + +ifdef MINGW64 +MINGW=1 +endif + +ifdef LINUX +UNIX=1 +ifdef LINUX64 +NONX86=1 +# LINUX64 does not imply X86_64=1; +# could mean ARM64 or Itanium +platform=linux/64 +else +platform=linux +endif +else ifdef FREEBSD +UNIX=1 +platform=freebsd +else ifdef SOLARIS # FIXME: UNTESTED +UNIX=1 +platform=solaris +else ifdef CYGWIN32 # FIXME: UNTESTED +nasm_format=win32 +platform=cygwin +else ifdef MINGW +ifdef MINGW64 +NONX86=1 +NOASM=1 +# MINGW64 should not necessarily imply X86_64=1, +# but we make that assumption elsewhere +# Once that changes, remove this +X86_64=1 +platform=mingw/64 +else +platform=mingw +endif +include Makefile.d/win32.mk +endif + +ifdef platform +makedir:=$(makedir)/$(platform) +endif + +ifdef UNIX +include Makefile.d/nix.mk +endif + +ifdef SDL +include Makefile.d/sdl.mk +endif diff --git a/src/Makefile.d/sdl.mk b/src/Makefile.d/sdl.mk new file mode 100644 index 000000000..99ca624e6 --- /dev/null +++ b/src/Makefile.d/sdl.mk @@ -0,0 +1,79 @@ +# +# Makefile options for SDL2 backend. +# + +# +# SDL...., *looks at Alam*, THIS IS A MESS! +# +# ...a little bird flexes its muscles... +# + +makedir:=$(makedir)/SDL + +sources+=$(call List,sdl/Sourcefile) +opts+=-DDIRECTFULLSCREEN -DHAVE_SDL + +# FIXME: UNTESTED +#ifdef PANDORA +#include sdl/SRB2Pandora/Makefile.cfg +#endif #ifdef PANDORA + +# FIXME: UNTESTED +#ifdef CYGWIN32 +#include sdl/MakeCYG.cfg +#endif #ifdef CYGWIN32 + +ifndef NOHW +sources+=sdl/ogl_sdl.c +endif + +ifdef NOMIXER +sources+=sdl/sdl_sound.c +else +opts+=-DHAVE_MIXER +sources+=sdl/mixer_sound.c + + ifdef HAVE_MIXERX + opts+=-DHAVE_MIXERX + libs+=-lSDL2_mixer_ext + else + libs+=-lSDL2_mixer + endif +endif + +ifndef NOTHREADS +opts+=-DHAVE_THREADS +sources+=sdl/i_threads.c +endif + +ifdef SDL_PKGCONFIG +$(eval $(call Use_pkg_config,SDL)) +else +SDL_CONFIG?=$(call Prefix,sdl2-config) +SDL_CFLAGS?=$(shell $(SDL_CONFIG) --cflags) +SDL_LDFLAGS?=$(shell $(SDL_CONFIG) \ + $(if $(STATIC),--static-libs,--libs)) +$(eval $(call Propogate_flags,SDL)) +endif + +# use the x86 asm code +ifndef CYGWIN32 +ifndef NOASM +USEASM=1 +endif +endif + +ifdef MINGW +ifndef NOSDLMAIN +SDLMAIN=1 +endif +endif + +ifdef SDLMAIN +opts+=-DSDLMAIN +else +ifdef MINGW +opts+=-Umain +libs+=-mconsole +endif +endif diff --git a/src/Makefile.d/util.mk b/src/Makefile.d/util.mk new file mode 100644 index 000000000..bda68df13 --- /dev/null +++ b/src/Makefile.d/util.mk @@ -0,0 +1,93 @@ +# +# Utility macros for the rest of the Makefiles. +# + +Ifnot=$(if $(1),$(3),$(2)) +Ifndef=$(call Ifnot,$($(1)),$(2),$(3)) + +# Match and expand a list of variables by pattern. +Wildvar=$(foreach v,$(filter $(1),$(.VARIABLES)),$($(v))) + +# Read a list of words from file and prepend each with the +# directory of the file. +_cat=$(shell $(cat) $(call Windows_path,$(1))) +List=$(addprefix $(dir $(1)),$(call _cat,$(1))) + +# Convert path separators to backslash on Windows. +Windows_path=$(if $(WINDOWSHELL),$(subst /,\,$(1)),$(1)) + +define Propogate_flags = +opts+=$$($(1)_CFLAGS) +libs+=$$($(1)_LDFLAGS) +endef + +# Set library's _CFLAGS and _LDFLAGS from some command. +# Automatically propogates the flags too. +# 1: variable prefix (e.g. CURL) +# 2: start of command (e.g. curl-config) +# --- optional ---- +# 3: CFLAGS command arguments, default '--cflags' +# 4: LDFLAGS command arguments, default '--libs' +# 5: common command arguments at the end of command +define Configure = +$(1)_CFLAGS?=$$(shell $(2) $(or $(3),--cflags) $(5)) +$(1)_LDFLAGS?=$$(shell $(2) $(or $(4),--libs) $(5)) +$(call Propogate_flags,$(1)) +endef + +# Configure library with pkg-config. The package name is +# taken from a _PKGCONFIG variable. +# 1: variable prefix +# +# LIBGME_PKGCONFIG=libgme +# $(eval $(call Use_pkg_config,LIBGME)) +define Use_pkg_config = +$(call Configure,$(1),$(PKG_CONFIG),,,$($(1)_PKGCONFIG)) +endef + +# Check disabling flag and configure package in one step +# according to delimited argument. +# (There is only one argument, but it split by slash.) +# 1/: short form library name (uppercase). This is +# prefixed with 'NO' and 'HAVE_'. E.g. NOGME, HAVE_GME +# /2: package name (e.g. libgme) +# /3: variable prefix +# +# The following example would check if NOGME is not +# defined before attempting to define LIBGME_CFLAGS and +# LIBGME_LDFLAGS as with Use_pkg_config. +# +# $(eval $(call Check_pkg_config,GME/libgme/LIBGME)) +define Check_pkg_config = +_p:=$(subst /, ,$(1)) +_v1:=$$(word 1,$$(_p)) +_v2:=$$(or $$(word 3,$$(_p)),$$(_v1)) +ifndef NO$$(_v1) +$$(_v2)_PKGCONFIG?=$$(word 2,$$(_p)) +$$(eval $$(call Use_pkg_config,$$(_v2))) +opts+=-DHAVE_$$(_v1) +endif +endef + +# $(call Prefix,gcc) +Prefix=$(if $(PREFIX),$(PREFIX)-)$(1) + +Echo= +Echo_name= +Print= + +ifndef SILENT +Echo=@echo $(1) +ifndef ECHO +ifndef NOECHOFILENAMES +Echo_name=$(call Echo,-- $(1) ...) +endif +endif +ifndef MAKE_RESTARTS +ifndef destructive +Print=$(info $(1)) +endif +endif +endif + +.=$(call Ifndef,ECHO,@) diff --git a/src/Makefile.d/versions.mk b/src/Makefile.d/versions.mk new file mode 100644 index 000000000..27ac64e78 --- /dev/null +++ b/src/Makefile.d/versions.mk @@ -0,0 +1,181 @@ +# +# Flags to put a sock in GCC! +# + +# See the versions list in detect.mk +# This will define all version flags going backward. +# Yes, it's magic. +define _predecessor = +ifdef GCC$(firstword $(1)) +GCC$(lastword $(1)):=1 +endif +endef +_n:=$(words $(gcc_versions)) +$(foreach v,$(join $(wordlist 2,$(_n),- $(gcc_versions)),\ + $(addprefix =,$(wordlist 2,$(_n),$(gcc_versions)))),\ + $(and $(findstring =,$(v)),\ + $(eval $(call _predecessor,$(subst =, ,$(v)))))) + +# -W -Wno-unused +WFLAGS:=-Wall -Wno-trigraphs +ifndef GCC295 +#WFLAGS+=-Wno-packed +endif +ifndef RELAXWARNINGS + WFLAGS+=-W +#WFLAGS+=-Wno-sign-compare +ifndef GCC295 + WFLAGS+=-Wno-div-by-zero +endif +#WFLAGS+=-Wsystem-headers +WFLAGS+=-Wfloat-equal +#WFLAGS+=-Wtraditional + WFLAGS+=-Wundef +ifndef GCC295 + WFLAGS+=-Wendif-labels +endif +ifdef GCC40 + WFLAGS+=-std=gnu89 +endif +ifdef GCC41 + WFLAGS+=-Wdeclaration-after-statement + WFLAGS+=-Wno-error=declaration-after-statement + WFLAGS+=-Wshadow +endif +#WFLAGS+=-Wlarger-than-%len% + WFLAGS+=-Wpointer-arith -Wbad-function-cast +ifdef GCC45 +#WFLAGS+=-Wc++-compat +endif + WFLAGS+=-Wcast-qual +ifndef NOCASTALIGNWARN + WFLAGS+=-Wcast-align +endif + WFLAGS+=-Wwrite-strings +ifndef ERRORMODE +#WFLAGS+=-Wconversion +ifdef GCC43 + #WFLAGS+=-Wno-sign-conversion +endif +endif + WFLAGS+=-Wsign-compare +ifdef GCC91 + WFLAGS+=-Wno-error=address-of-packed-member +endif +ifdef GCC45 + WFLAGS+=-Wlogical-op +endif + WFLAGS+=-Waggregate-return +ifdef HAIKU +ifdef GCC41 + #WFLAGS+=-Wno-attributes +endif +endif +#WFLAGS+=-Wstrict-prototypes +ifdef GCC40 + WFLAGS+=-Wold-style-definition +endif + WFLAGS+=-Wmissing-prototypes -Wmissing-declarations +ifdef GCC40 + WFLAGS+=-Wmissing-field-initializers +endif + WFLAGS+=-Wmissing-noreturn +#WFLAGS+=-Wmissing-format-attribute +#WFLAGS+=-Wno-multichar +#WFLAGS+=-Wno-deprecated-declarations +#WFLAGS+=-Wpacked +#WFLAGS+=-Wpadded +#WFLAGS+=-Wredundant-decls + WFLAGS+=-Wnested-externs +#WFLAGS+=-Wunreachable-code + WFLAGS+=-Winline +ifdef GCC43 + WFLAGS+=-funit-at-a-time + WFLAGS+=-Wlogical-op +endif +ifndef GCC295 + WFLAGS+=-Wdisabled-optimization +endif +endif +WFLAGS+=-Wformat-y2k +ifdef GCC71 +WFLAGS+=-Wno-error=format-overflow=2 +endif +WFLAGS+=-Wformat-security +ifndef GCC29 +#WFLAGS+=-Winit-self +endif +ifdef GCC46 +WFLAGS+=-Wno-suggest-attribute=noreturn +endif + +ifdef NOLDWARNING +LDFLAGS+=-Wl,--as-needed +endif + +ifdef ERRORMODE +WFLAGS+=-Werror +endif + +ifdef GCC43 + #WFLAGS+=-Wno-error=clobbered +endif +ifdef GCC44 + WFLAGS+=-Wno-error=array-bounds +endif +ifdef GCC46 + WFLAGS+=-Wno-error=suggest-attribute=noreturn +endif +ifdef GCC54 + WFLAGS+=-Wno-logical-op -Wno-error=logical-op +endif +ifdef GCC61 + WFLAGS+=-Wno-tautological-compare -Wno-error=tautological-compare +endif +ifdef GCC71 + WFLAGS+=-Wimplicit-fallthrough=4 + WFLAGS+=-Wno-format-truncation +endif +ifdef GCC81 + WFLAGS+=-Wno-error=format-overflow + WFLAGS+=-Wno-error=stringop-truncation + WFLAGS+=-Wno-error=stringop-overflow + WFLAGS+=-Wno-format-overflow + WFLAGS+=-Wno-stringop-truncation + WFLAGS+=-Wno-stringop-overflow + WFLAGS+=-Wno-error=multistatement-macros +endif + +ifdef NONX86 + ifdef X86_64 # yeah that SEEMS contradictory + opts+=-march=nocona + endif +else + ifndef GCC29 + opts+=-msse3 -mfpmath=sse + else + opts+=-mpentium + endif +endif + +ifdef DEBUGMODE +ifdef GCC48 +opts+=-Og +else +opts+=-O0 +endif +endif + +ifdef VALGRIND +ifdef GCC46 +WFLAGS+=-Wno-error=unused-but-set-variable +WFLAGS+=-Wno-unused-but-set-variable +endif +endif + +# Lua +ifdef GCC43 +ifndef GCC44 +WFLAGS+=-Wno-logical-op +endif +endif diff --git a/src/Makefile.d/win32.mk b/src/Makefile.d/win32.mk new file mode 100644 index 000000000..ec66107d4 --- /dev/null +++ b/src/Makefile.d/win32.mk @@ -0,0 +1,117 @@ +# +# Mingw, if you don't know, that's Win32/Win64 +# + +ifndef MINGW64 +EXENAME?=srb2kart.exe +else +EXENAME?=srb2kart64.exe +endif + +sources+=win32/Srb2win.rc +opts+=-DSTDC_HEADERS +libs+=-ladvapi32 -lkernel32 -lmsvcrt -luser32 + +nasm_format:=win32 + +SDL=1 + +ifndef NOHW +opts+=-DUSE_WGL_SWAP +endif + +ifdef MINGW64 +libs+=-lws2_32 +else +ifdef NO_IPV6 +libs+=-lwsock32 +else +libs+=-lws2_32 +endif +endif + +ifndef MINGW64 +opts+=-I../libs/drmingw/include +libs+=-L../libs/drmingw/lib/win32 -lmgwhelp -lexchndl +endif + +ifndef MINGW64 +libs+=-Wl,--large-address-aware +endif + +ifndef NONET +ifndef MINGW64 # miniupnc is broken with MINGW64 +opts+=-I../libs -DSTATIC_MINIUPNPC +libs+=-L../libs/miniupnpc/mingw$(32) -lws2_32 -liphlpapi +endif +endif + +ifndef NO_DISCORDRPC +HAVE_DISCORDRPC=1 +endif + +ifndef MINGW64 +32=32 +x86=x86 +i686=i686 +else +32=64 +x86=x86_64 +i686=x86_64 +endif + +mingw:=$(i686)-w64-mingw32 + +define _set = +$(1)_CFLAGS?=$($(1)_opts) +$(1)_LDFLAGS?=$($(1)_libs) +endef + +lib:=../libs/gme +LIBGME_opts:=-I$(lib)/include +LIBGME_libs:=-L$(lib)/win$(32) -lgme +$(eval $(call _set,LIBGME)) + +lib:=../libs/libopenmpt +LIBOPENMPT_opts:=-I$(lib)/inc +LIBOPENMPT_libs:=-L$(lib)/lib/$(x86)/mingw -lopenmpt +$(eval $(call _set,LIBOPENMPT)) + +ifndef NOMIXERX +HAVE_MIXERX=1 +lib:=../libs/SDLMixerX/$(mingw) +else +lib:=../libs/SDL2_mixer/$(mingw) +endif + +mixer_opts:=-I$(lib)/include/SDL2 +mixer_libs:=-L$(lib)/lib + +lib:=../libs/SDL2/$(mingw) +SDL_opts:=-I$(lib)/include/SDL2\ + $(mixer_opts) -Dmain=SDL_main +SDL_libs:=-L$(lib)/lib $(mixer_libs)\ + -lmingw32 -lSDL2main -lSDL2 -mwindows +$(eval $(call _set,SDL)) + +lib:=../libs/zlib +ZLIB_opts:=-I$(lib) +ZLIB_libs:=-L$(lib)/win32 -lz$(32) +$(eval $(call _set,ZLIB)) + +ifndef PNG_CONFIG +lib:=../libs/libpng-src +PNG_opts:=-I$(lib) +PNG_libs:=-L$(lib)/projects -lpng$(32) +$(eval $(call _set,PNG)) +endif + +lib:=../libs/curl +CURL_opts:=-I$(lib)/include +CURL_libs:=-L$(lib)/lib$(32) -lcurl +$(eval $(call _set,CURL)) + +lib:=../libs/discord-rpc/win$(32)-dynamic +DISCORDRPC_opts:=-I$(lib)/include +DISCORDRPC_libs:=-L$(lib)/lib +$(eval $(call _set,DISCORDRPC)) diff --git a/src/Sourcefile b/src/Sourcefile new file mode 100644 index 000000000..e142ebcc1 --- /dev/null +++ b/src/Sourcefile @@ -0,0 +1,114 @@ +string.c +d_main.c +d_clisrv.c +d_net.c +d_netfil.c +d_netcmd.c +dehacked.c +deh_soc.c +deh_lua.c +deh_tables.c +z_zone.c +f_finale.c +f_wipe.c +g_demo.c +g_game.c +g_input.c +g_splitscreen.c +am_map.c +command.c +console.c +font.c +hu_stuff.c +y_inter.c +st_stuff.c +m_aatree.c +m_anigif.c +m_argv.c +m_bbox.c +m_cheat.c +m_cond.c +m_fixed.c +m_menu.c +m_misc.c +m_perfstats.c +m_random.c +m_queue.c +info.c +p_ceilng.c +p_enemy.c +p_floor.c +p_inter.c +p_lights.c +p_map.c +p_maputl.c +p_mobj.c +p_polyobj.c +p_saveg.c +p_setup.c +p_sight.c +p_spec.c +p_telept.c +p_tick.c +p_user.c +p_slopes.c +tables.c +r_bsp.c +r_data.c +r_draw.c +r_fps.c +r_main.c +r_plane.c +r_segs.c +r_skins.c +r_sky.c +r_splats.c +r_things.c +r_textures.c +r_patch.c +r_patchrotation.c +r_picformats.c +r_portal.c +screen.c +taglist.c +v_video.c +s_sound.c +sounds.c +w_wad.c +filesrch.c +mserv.c +http-mserv.c +i_tcp.c +lzf.c +vid_copy.s +lua_script.c +lua_baselib.c +lua_mathlib.c +lua_hooklib.c +lua_consolelib.c +lua_infolib.c +lua_mobjlib.c +lua_playerlib.c +lua_skinlib.c +lua_thinkerlib.c +lua_maplib.c +lua_taglib.c +lua_polyobjlib.c +lua_blockmaplib.c +lua_hudlib.c +k_kart.c +k_respawn.c +k_collide.c +k_color.c +k_race.c +k_battle.c +k_pwrlv.c +k_waypoint.c +k_pathfind.c +k_bheap.c +k_bot.c +k_botitem.c +k_botsearch.c +k_grandprix.c +k_hud.c +k_brightmap.c diff --git a/src/android/i_system.c b/src/android/i_system.c index 908629bea..d8b81dcec 100644 --- a/src/android/i_system.c +++ b/src/android/i_system.c @@ -88,6 +88,12 @@ tic_t I_GetTime(void) return (since_start*TICRATE)/1000000; } +fixed_t I_GetTimeFrac(void) +{ + //stub + return 0; +} + void I_Sleep(void){} void I_GetEvent(void){} diff --git a/src/blua/CMakeLists.txt b/src/blua/CMakeLists.txt new file mode 100644 index 000000000..4e9c67d2f --- /dev/null +++ b/src/blua/CMakeLists.txt @@ -0,0 +1 @@ +target_sourcefile(c) diff --git a/src/blua/Makefile.cfg b/src/blua/Makefile.cfg deleted file mode 100644 index 3a2962e65..000000000 --- a/src/blua/Makefile.cfg +++ /dev/null @@ -1,53 +0,0 @@ -ifdef UNIXCOMMON -LUA_CFLAGS+=-DLUA_USE_POSIX -endif -ifdef LINUX -LUA_CFLAGS+=-DLUA_USE_POSIX -endif -ifdef GCC43 -ifndef GCC44 -WFLAGS+=-Wno-logical-op -endif -endif - -OBJS:=$(OBJS) \ - $(OBJDIR)/lapi.o \ - $(OBJDIR)/lbaselib.o \ - $(OBJDIR)/ldo.o \ - $(OBJDIR)/lfunc.o \ - $(OBJDIR)/linit.o \ - $(OBJDIR)/liolib.o \ - $(OBJDIR)/llex.o \ - $(OBJDIR)/lmem.o \ - $(OBJDIR)/lobject.o \ - $(OBJDIR)/lstate.o \ - $(OBJDIR)/lstrlib.o \ - $(OBJDIR)/ltablib.o \ - $(OBJDIR)/lundump.o \ - $(OBJDIR)/lzio.o \ - $(OBJDIR)/lauxlib.o \ - $(OBJDIR)/lcode.o \ - $(OBJDIR)/ldebug.o \ - $(OBJDIR)/ldump.o \ - $(OBJDIR)/lgc.o \ - $(OBJDIR)/lopcodes.o \ - $(OBJDIR)/lparser.o \ - $(OBJDIR)/lstring.o \ - $(OBJDIR)/ltable.o \ - $(OBJDIR)/ltm.o \ - $(OBJDIR)/lvm.o \ - $(OBJDIR)/lua_script.o \ - $(OBJDIR)/lua_baselib.o \ - $(OBJDIR)/lua_mathlib.o \ - $(OBJDIR)/lua_hooklib.o \ - $(OBJDIR)/lua_consolelib.o \ - $(OBJDIR)/lua_infolib.o \ - $(OBJDIR)/lua_mobjlib.o \ - $(OBJDIR)/lua_playerlib.o \ - $(OBJDIR)/lua_skinlib.o \ - $(OBJDIR)/lua_thinkerlib.o \ - $(OBJDIR)/lua_maplib.o \ - $(OBJDIR)/lua_taglib.o \ - $(OBJDIR)/lua_polyobjlib.o \ - $(OBJDIR)/lua_blockmaplib.o \ - $(OBJDIR)/lua_hudlib.o diff --git a/src/blua/Sourcefile b/src/blua/Sourcefile new file mode 100644 index 000000000..f99c89c8d --- /dev/null +++ b/src/blua/Sourcefile @@ -0,0 +1,25 @@ +lapi.c +lbaselib.c +ldo.c +lfunc.c +linit.c +liolib.c +llex.c +lmem.c +lobject.c +lstate.c +lstrlib.c +ltablib.c +lundump.c +lzio.c +lauxlib.c +lcode.c +ldebug.c +ldump.c +lgc.c +lopcodes.c +lparser.c +lstring.c +ltable.c +ltm.c +lvm.c diff --git a/src/console.c b/src/console.c index 5eda4f7fa..4d71e74d3 100644 --- a/src/console.c +++ b/src/console.c @@ -1916,6 +1916,8 @@ void CON_SetLoadingProgress(con_loadprogress_t newStep) if (con_startup_loadprogress < LOADED_ISTARTUPGRAPHICS) // rendering not possible? return; CON_DrawLoadBar(); // here we display the console text + I_OsPolling(); + I_UpdateNoBlit(); I_FinishUpdate(); // page flip or blit buffer } diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 5b4141328..e6fcb6643 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -141,7 +141,7 @@ UINT8 adminpassmd5[16]; boolean adminpasswordset = false; // Client specific -static ticcmd_t localcmds[MAXSPLITSCREENPLAYERS]; +static ticcmd_t localcmds[MAXSPLITSCREENPLAYERS][MAXGENTLEMENDELAY]; static boolean cl_packetmissed; // here it is for the secondary local player (splitscreen) static UINT8 mynode; // my address pointofview server @@ -440,10 +440,15 @@ static void D_Clearticcmd(tic_t tic) void D_ResetTiccmds(void) { - INT32 i; + INT32 i, j; for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) - memset(&localcmds[i], 0, sizeof(ticcmd_t)); + { + for (j = 0; j < MAXGENTLEMENDELAY; j++) + { + memset(&localcmds[i][j], 0, sizeof(ticcmd_t)); + } + } // Reset the net command list for (i = 0; i < TEXTCMD_HASH_SIZE; i++) @@ -790,10 +795,14 @@ static boolean CL_SendJoin(void) sizeof netbuffer->u.clientcfg.application); for (i = 0; i <= splitscreen; i++) - CleanupPlayerName(g_localplayers[i], cv_playername[i].zstring); - - for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) + { + // the MAXPLAYERS addition is necessary to communicate that g_localplayers is not yet safe to reference + CleanupPlayerName(MAXPLAYERS+i, cv_playername[i].zstring); strncpy(netbuffer->u.clientcfg.names[i], cv_playername[i].zstring, MAXPLAYERNAME); + } + // privacy shield for the local players not joining this session + for (; i < MAXSPLITSCREENPLAYERS; i++) + strncpy(netbuffer->u.clientcfg.names[i], va("Player %c", 'A' + i), MAXPLAYERNAME); return HSendPacket(servernode, false, 0, sizeof (clientconfig_pak)); } @@ -1329,7 +1338,7 @@ static void CL_ReloadReceivedSavegame(void) for (i = 0; i < MAXPLAYERS; i++) { LUA_InvalidatePlayer(&players[i]); - sprintf(player_names[i], "Player %d", i + 1); + sprintf(player_names[i], "Player %c", 'A' + i); } CL_LoadReceivedSavegame(true); @@ -2390,12 +2399,13 @@ void CL_RemovePlayer(INT32 playernum, kickreason_t reason) // remove avatar of player playeringame[playernum] = false; + demo_extradata[playernum] |= DXD_PLAYSTATE; playernode[playernum] = UINT8_MAX; while (!playeringame[doomcom->numslots-1] && doomcom->numslots > 1) doomcom->numslots--; // Reset the name - sprintf(player_names[playernum], "Player %d", playernum+1); + sprintf(player_names[playernum], "Player %c", 'A' + playernum); player_name_changes[playernum] = 0; @@ -3207,7 +3217,7 @@ void SV_ResetServer(void) playeringame[i] = false; playernode[i] = UINT8_MAX; memset(playeraddress[i], 0, sizeof(*playeraddress)); - sprintf(player_names[i], "Player %d", i + 1); + sprintf(player_names[i], "Player %c", 'A' + i); adminplayers[i] = -1; // Populate the entire adminplayers array with -1. K_ClearClientPowerLevels(); splitscreen_invitations[i] = -1; @@ -3406,7 +3416,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) P_ForceLocalAngle(newplayer, newplayer->angleturn); - D_SendPlayerConfig(); + D_SendPlayerConfig(splitscreenplayer); addedtogame = true; if (rejoined) @@ -3552,14 +3562,13 @@ static void Got_AddBot(UINT8 **p, INT32 playernum) LUAh_PlayerJoin(newplayernum); } -static boolean SV_AddWaitingPlayers(const char *name, const char *name2, const char *name3, const char *name4) +static boolean SV_AddWaitingPlayers(SINT8 node, const char *name, const char *name2, const char *name3, const char *name4) { - INT32 node, n, newplayer = false; + INT32 n, newplayernum; UINT8 buf[4 + MAXPLAYERNAME]; UINT8 *buf_p = buf; - INT32 newplayernum; + boolean newplayer = false; - for (node = 0; node < MAXNETNODES; node++) { // splitscreen can allow 2+ players in one node for (; nodewaiting[node] > 0; nodewaiting[node]--) @@ -3678,6 +3687,7 @@ boolean SV_SpawnServer(void) I_Error("What do you think you're doing?"); return false; #else + boolean result = false; if (demo.playback) G_StopDemo(); // reset engine parameter if (metalplayback) @@ -3704,7 +3714,14 @@ boolean SV_SpawnServer(void) else doomcom->numslots = 1; } - return SV_AddWaitingPlayers(cv_playername[0].zstring, cv_playername[1].zstring, cv_playername[2].zstring, cv_playername[3].zstring); + // strictly speaking, i'm not convinced the following is necessary + // but I'm not confident enough to remove it entirely in case it breaks something + { + SINT8 node = 0; + for (; node < MAXNETNODES; node++) + result |= SV_AddWaitingPlayers(node, cv_playername[0].zstring, cv_playername[1].zstring, cv_playername[2].zstring, cv_playername[3].zstring); + } + return result; #endif } @@ -3876,7 +3893,7 @@ static void HandleConnect(SINT8 node) SV_SendSaveGame(node, false); // send a complete game state DEBFILE("send savegame\n"); } - SV_AddWaitingPlayers(names[0], names[1], names[2], names[3]); + SV_AddWaitingPlayers(node, names[0], names[1], names[2], names[3]); joindelay += cv_joindelay.value * TICRATE; player_joining = true; } @@ -4934,12 +4951,6 @@ static void CL_SendClientCmd(void) size_t packetsize = 0; boolean mis = false; - if (lowest_lag && ( gametic % lowest_lag )) - { - cl_packetmissed = true; - return; - } - netbuffer->packettype = PT_CLIENTCMD; if (cl_packetmissed) @@ -4960,27 +4971,35 @@ static void CL_SendClientCmd(void) } else if (gamestate != GS_NULL && (addedtogame || dedicated)) { + UINT8 lagDelay = 0; + + if (lowest_lag > 0) + { + // Gentlemens' ping. + lagDelay = min(lowest_lag, MAXGENTLEMENDELAY); + } + packetsize = sizeof (clientcmd_pak); - G_MoveTiccmd(&netbuffer->u.clientpak.cmd, &localcmds[0], 1); - netbuffer->u.clientpak.consistancy = SHORT(consistancy[gametic%TICQUEUE]); + G_MoveTiccmd(&netbuffer->u.clientpak.cmd, &localcmds[0][lagDelay], 1); + netbuffer->u.clientpak.consistancy = SHORT(consistancy[gametic % TICQUEUE]); if (splitscreen) // Send a special packet with 2 cmd for splitscreen { netbuffer->packettype = (mis ? PT_CLIENT2MIS : PT_CLIENT2CMD); packetsize = sizeof (client2cmd_pak); - G_MoveTiccmd(&netbuffer->u.client2pak.cmd2, &localcmds[1], 1); + G_MoveTiccmd(&netbuffer->u.client2pak.cmd2, &localcmds[1][lagDelay], 1); if (splitscreen > 1) { netbuffer->packettype = (mis ? PT_CLIENT3MIS : PT_CLIENT3CMD); packetsize = sizeof (client3cmd_pak); - G_MoveTiccmd(&netbuffer->u.client3pak.cmd3, &localcmds[2], 1); + G_MoveTiccmd(&netbuffer->u.client3pak.cmd3, &localcmds[2][lagDelay], 1); if (splitscreen > 2) { netbuffer->packettype = (mis ? PT_CLIENT4MIS : PT_CLIENT4CMD); packetsize = sizeof (client4cmd_pak); - G_MoveTiccmd(&netbuffer->u.client4pak.cmd4, &localcmds[3], 1); + G_MoveTiccmd(&netbuffer->u.client4pak.cmd4, &localcmds[3][lagDelay], 1); } } } @@ -5143,8 +5162,23 @@ static void SV_SendTics(void) // // TryRunTics // +static void CreateNewLocalCMD(UINT8 p, INT32 realtics) +{ + INT32 i; + + for (i = MAXGENTLEMENDELAY-1; i > 0; i--) + { + G_MoveTiccmd(&localcmds[p][i], &localcmds[p][i-1], 1); + } + + G_BuildTiccmd(&localcmds[p][0], realtics, p+1); + localcmds[p][0].flags |= TICCMD_RECEIVED; +} + static void Local_Maketic(INT32 realtics) { + INT32 i; + I_OsPolling(); // I_Getevent D_ProcessEvents(); // menu responder, cons responder, // game responder calls HU_Responder, AM_Responder, @@ -5153,25 +5187,9 @@ static void Local_Maketic(INT32 realtics) if (!dedicated) rendergametic = gametic; // translate inputs (keyboard/mouse/joystick) into game controls - G_BuildTiccmd(&localcmds[0], realtics, 1); - localcmds[0].flags |= TICCMD_RECEIVED; - - if (splitscreen) + for (i = 0; i <= splitscreen; i++) { - G_BuildTiccmd(&localcmds[1], realtics, 2); - localcmds[1].flags |= TICCMD_RECEIVED; - - if (splitscreen > 1) - { - G_BuildTiccmd(&localcmds[2], realtics, 3); - localcmds[2].flags |= TICCMD_RECEIVED; - - if (splitscreen > 2) - { - G_BuildTiccmd(&localcmds[3], realtics, 4); - localcmds[3].flags |= TICCMD_RECEIVED; - } - } + CreateNewLocalCMD(i, realtics); } } @@ -5264,12 +5282,14 @@ void TryRunTics(tic_t realtics) if (neededtic > gametic) { - hu_stopped = false; + if (realtics) + hu_stopped = false; } if (player_joining) { - hu_stopped = true; + if (realtics) + hu_stopped = true; return; } @@ -5288,6 +5308,7 @@ void TryRunTics(tic_t realtics) while (neededtic > gametic) { DEBFILE(va("============ Running tic %d (local %d)\n", gametic, localgametic)); + prev_tics = I_GetTime(); ps_tictime = I_GetPreciseTime(); @@ -5306,7 +5327,8 @@ void TryRunTics(tic_t realtics) } else { - hu_stopped = true; + if (realtics) + hu_stopped = true; } } diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 93593d736..88712f01c 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -39,6 +39,15 @@ applications may follow different packet versions. // Networking and tick handling related. #define TICQUEUE 512 // more than enough for most timeouts.... #define MAXTEXTCMD 256 + +// No. of tics your controls can be delayed by. + +// TODO: Instead of storing a ton of extra cmds for gentlemens' delay, +// keep them in a linked-list, with timestamps to discard everything that's older than already sent. +// That will support any amount of lag, and be less wasteful for clients who don't use it. +// This just works as a quick implementation. +#define MAXGENTLEMENDELAY TICRATE + // // Packet structure // diff --git a/src/d_main.c b/src/d_main.c index 5ded2bf14..27ee40926 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -63,6 +63,7 @@ #include "deh_tables.h" // Dehacked list test #include "m_cond.h" // condition initialization #include "fastcmp.h" +#include "r_fps.h" // Frame interpolation/uncapped #include "keys.h" #include "filesrch.h" // refreshdirmenu #include "g_input.h" // tutorial mode control scheming @@ -755,7 +756,7 @@ void D_SRB2Loop(void) debugload--; #endif - if (!realtics && !singletics) + if (!realtics && !singletics && cv_frameinterpolation.value != 1) { I_Sleep(); continue; @@ -773,13 +774,37 @@ void D_SRB2Loop(void) // process tics (but maybe not if realtic == 0) TryRunTics(realtics); + if (cv_frameinterpolation.value == 1 && !(paused || P_AutoPause() || hu_stopped)) + { + fixed_t entertimefrac = I_GetTimeFrac(); + // renderdeltatics is a bit awkard to evaluate, since the system time interface is whole tic-based + renderdeltatics = realtics * FRACUNIT; + if (entertimefrac > rendertimefrac) + renderdeltatics += entertimefrac - rendertimefrac; + else + renderdeltatics -= rendertimefrac - entertimefrac; + + rendertimefrac = entertimefrac; + } + else + { + rendertimefrac = FRACUNIT; + renderdeltatics = realtics * FRACUNIT; + } + + if (cv_frameinterpolation.value == 1) + { + D_Display(); + } + if (lastdraw || singletics || gametic > rendergametic) { rendergametic = gametic; rendertimeout = entertic+TICRATE/17; // Update display, next frame, with current state. - D_Display(); + // (Only display if not already done for frame interp) + cv_frameinterpolation.value == 0 ? D_Display() : 0; if (moviemode) M_SaveFrame(); @@ -788,7 +813,8 @@ void D_SRB2Loop(void) } else if (rendertimeout < entertic) // in case the server hang or netsplit { - D_Display(); + // (Only display if not already done for frame interp) + cv_frameinterpolation.value == 0 ? D_Display() : 0; if (moviemode) M_SaveFrame(); @@ -1391,6 +1417,9 @@ void D_SRB2Main(void) // setup loading screen SCR_Startup(); + // Do this in background; lots of number crunching + R_InitTranslucencyTables(); + CON_SetLoadingProgress(LOADED_ISTARTUPGRAPHICS); CONS_Printf("HU_Init()...\n"); @@ -1639,6 +1668,8 @@ void D_SRB2Main(void) // as having been modified for the first game. M_PushSpecialParameters(); // push all "+" parameter at the command buffer + COM_BufExecute(); // ensure the command buffer gets executed before the map starts (+skin) + strncpy(connectedservername, cv_servername.string, MAXSERVERNAME); if (M_CheckParm("-gametype") && M_IsNextParm()) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 4ed110f35..c221aee90 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -222,8 +222,6 @@ static void Command_KartGiveItem_f(void); // CLIENT VARIABLES // ========================================================================= -void SendWeaponPref(UINT8 n); - static CV_PossibleValue_t usemouse_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Force"}, {0, NULL}}; #ifdef LJOYSTICK @@ -768,15 +766,21 @@ void D_RegisterClientCommands(void) for (i = 0; i < MAXSKINCOLORS; i++) { - Color_cons_t[i].value = Followercolor_cons_t[i].value = i; - Color_cons_t[i].strvalue = Followercolor_cons_t[i].strvalue = skincolors[i].name; + Color_cons_t[i].value = i; + Color_cons_t[i].strvalue = skincolors[i].name; } - Followercolor_cons_t[MAXSKINCOLORS].value = MAXSKINCOLORS; - Followercolor_cons_t[MAXSKINCOLORS].strvalue = "Match"; // Add "Match" option, which will make the follower color match the player's + for (i = 2; i < MAXSKINCOLORS; i++) + { + Followercolor_cons_t[i].value = i-2; + Followercolor_cons_t[i].strvalue = skincolors[i-2].name; + } - Followercolor_cons_t[MAXSKINCOLORS+1].value = MAXSKINCOLORS+1; - Followercolor_cons_t[MAXSKINCOLORS+1].strvalue = "Opposite"; // Add "Opposite" option, ...which is like "Match", but for coloropposite. + Followercolor_cons_t[1].value = -1; + Followercolor_cons_t[1].strvalue = "Match"; // Add "Match" option, which will make the follower color match the player's + + Followercolor_cons_t[0].value = -2; + Followercolor_cons_t[0].strvalue = "Opposite"; // Add "Opposite" option, ...which is like "Match", but for coloropposite. Color_cons_t[MAXSKINCOLORS].value = Followercolor_cons_t[MAXSKINCOLORS+2].value = 0; Color_cons_t[MAXSKINCOLORS].strvalue = Followercolor_cons_t[MAXSKINCOLORS+2].strvalue = NULL; @@ -1110,6 +1114,7 @@ boolean EnsurePlayerNameIsGood(char *name, INT32 playernum) * is restored to what it was before. * * We assume that if playernum is in ::g_localplayers + * (unless clientjoin is true, a necessary evil) * the console variable ::cv_playername[n] is * already set to newname. However, the player name table is assumed to * contain the old name. @@ -1128,6 +1133,10 @@ void CleanupPlayerName(INT32 playernum, const char *newname) char *tmpname = NULL; INT32 i; boolean namefailed = true; + boolean clientjoin = !!(playernum >= MAXPLAYERS); + + if (clientjoin) + playernum -= MAXPLAYERS; buf = Z_StrDup(newname); @@ -1185,17 +1194,20 @@ void CleanupPlayerName(INT32 playernum, const char *newname) } // no stealing another player's name - for (i = 0; i < MAXPLAYERS; i++) + if (!clientjoin) { - if (i != playernum && playeringame[i] - && strcasecmp(tmpname, player_names[i]) == 0) + for (i = 0; i < MAXPLAYERS; i++) { - break; + if (i != playernum && playeringame[i] + && strcasecmp(tmpname, player_names[i]) == 0) + { + break; + } } - } - if (i < MAXPLAYERS) - break; + if (i < MAXPLAYERS) + break; + } // name is okay then namefailed = false; @@ -1206,18 +1218,23 @@ void CleanupPlayerName(INT32 playernum, const char *newname) // set consvars whether namefailed or not, because even if it succeeded, // spaces may have been removed - for (i = 0; i <= splitscreen; i++) + if (clientjoin) + CV_StealthSet(&cv_playername[playernum], tmpname); + else { - if (playernum == g_localplayers[i]) + for (i = 0; i <= splitscreen; i++) { - CV_StealthSet(&cv_playername[i], tmpname); - break; + if (playernum == g_localplayers[i]) + { + CV_StealthSet(&cv_playername[i], tmpname); + break; + } } - } - if (i > splitscreen) - { - I_Assert(((void)"CleanupPlayerName used on non-local player", 0)); + if (i > splitscreen) + { + I_Assert(((void)"CleanupPlayerName used on non-local player", 0)); + } } Z_Free(buf); @@ -1398,7 +1415,9 @@ static void SendNameAndColor(UINT8 n) if (!strcmp(cv_playername[n].string, player_names[playernum]) && cv_playercolor[n].value == player->skincolor - && !strcmp(cv_skin[n].string, skins[player->skin].name)) + && !strcmp(cv_skin[n].string, skins[player->skin].name) + && cv_follower[n].value == player->followerskin + && cv_followercolor[n].value == player->followercolor) return; player->availabilities = R_GetSkinAvailabilities(); @@ -1811,33 +1830,28 @@ static void Got_LeaveParty(UINT8 **cp,INT32 playernum) } } -void D_SendPlayerConfig(void) +void D_SendPlayerConfig(UINT8 n) { - UINT8 i; + UINT8 buf[4]; + UINT8 *p = buf; - for (i = 0; i <= splitscreen; i++) + SendNameAndColor(n); + SendWeaponPref(n); + + if (n == 0) { - UINT8 buf[4]; - UINT8 *p = buf; - - SendNameAndColor(i); - SendWeaponPref(i); - - if (i == 0) - { - // Send it over - WRITEUINT16(p, vspowerlevel[PWRLV_RACE]); - WRITEUINT16(p, vspowerlevel[PWRLV_BATTLE]); - } - else - { - // Splitscreen players have invalid powerlevel - WRITEUINT16(p, 0); - WRITEUINT16(p, 0); - } - - SendNetXCmdForPlayer(i, XD_POWERLEVEL, buf, p-buf); + // Send it over + WRITEUINT16(p, vspowerlevel[PWRLV_RACE]); + WRITEUINT16(p, vspowerlevel[PWRLV_BATTLE]); } + else + { + // Splitscreen players have invalid powerlevel + WRITEUINT16(p, 0); + WRITEUINT16(p, 0); + } + + SendNetXCmdForPlayer(n, XD_POWERLEVEL, buf, p-buf); } // Only works for displayplayer, sorry! diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 41dc3fdf7..0e8ef25e2 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -207,7 +207,8 @@ void D_RegisterServerCommands(void); void D_RegisterClientCommands(void); void CleanupPlayerName(INT32 playernum, const char *newname); boolean EnsurePlayerNameIsGood(char *name, INT32 playernum); -void D_SendPlayerConfig(void); +void SendWeaponPref(UINT8 n); +void D_SendPlayerConfig(UINT8 n); void Command_ExitGame_f(void); void Command_Retry_f(void); void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore diff --git a/src/d_netfil.c b/src/d_netfil.c index 5714c39cd..7aec8d13e 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -161,10 +161,16 @@ UINT8 *PutFileNeeded(UINT16 firstfile) char wadfilename[MAX_WADPATH] = ""; UINT8 filestatus; - for (i = mainwads+1; i < numwadfiles; i++) //mainwads+1, otherwise we start on the first mainwad +#ifdef DEVELOP + i = 0; +#else + i = mainwads + 1; +#endif + + for (; i < numwadfiles; i++) //mainwads+1, otherwise we start on the first mainwad { // If it has only music/sound lumps, don't put it in the list - if (!wadfiles[i]->important) + if (i > mainwads && !wadfiles[i]->important) continue; if (firstfile) @@ -276,11 +282,16 @@ boolean CL_CheckDownloadable(void) } // Downloading locally disabled +#if 0 if (!dlstatus && M_CheckParm("-nodownload")) dlstatus = 3; if (!dlstatus) return true; +#else + if (!dlstatus) + dlstatus = 3; +#endif // not downloadable, put reason in console CONS_Alert(CONS_NOTICE, M_GetText("You need additional files to connect to this server:\n")); @@ -489,7 +500,12 @@ INT32 CL_CheckFiles(void) CONS_Debug(DBG_NETPLAY, "searching for '%s' ", fileneeded[i].filename); // Check in already loaded files - for (j = mainwads+1; wadfiles[j]; j++) +#ifdef DEVELOP + j = 0; +#else + j = mainwads + 1; +#endif + for (; wadfiles[j]; j++) { nameonly(strcpy(wadfilename, wadfiles[j]->filename)); if (!stricmp(wadfilename, fileneeded[i].filename) && diff --git a/src/d_player.h b/src/d_player.h index 3bd99cecb..738f8240b 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -62,7 +62,7 @@ typedef enum PF_ATTACKDOWN = 1, PF_ACCELDOWN = 1<<1, PF_BRAKEDOWN = 1<<2, - PF_WPNDOWN = 1<<3, // reserved - gonna turn this into lookback when i'm done with all the major reengineering + PF_LOOKDOWN = 1<<3, // Accessibility and cheats PF_KICKSTARTACCEL = 1<<4, // Is accelerate in kickstart mode? @@ -198,11 +198,18 @@ typedef enum #undef KSPIN_TYPE } kartspinoutflags_t; +typedef enum +{ + TRIP_NONE, + TRIP_PASSED, + TRIP_BLOCKED, +} tripwirestate_t; + typedef enum { // Unsynced, HUD or clientsided effects // Item box - khud_itemblink, // Item flashing after roulette, prevents Hyudoro stealing AND serves as a mashing indicator + khud_itemblink, // Item flashing after roulette, serves as a mashing indicator khud_itemblinkmode, // Type of flashing: 0 = white (normal), 1 = red (mashing), 2 = rainbow (enhanced items) // Rings @@ -263,6 +270,7 @@ typedef struct respawnvars_s fixed_t pointz; boolean flip; // Flip upside down or not tic_t timer; // Time left on respawn animation once you're there + tic_t airtimer; // Time spent in the air before respawning UINT32 distanceleft; // How far along the course to respawn you tic_t dropdash; // Drop Dash charge timer } respawnvars_t; @@ -304,6 +312,7 @@ typedef struct player_s fixed_t bob; angle_t viewrollangle; + angle_t old_viewrollangle; // camera tilt // TODO: expose to lua angle_t tilt; @@ -317,6 +326,7 @@ typedef struct player_s // fun thing for player sprite angle_t drawangle; + angle_t old_drawangle; // interp // Bit flags. // See pflags_t, above. @@ -375,7 +385,7 @@ typedef struct player_s UINT8 wipeoutslow; // Timer before you slowdown when getting wiped out UINT8 justbumped; // Prevent players from endlessly bumping into each other UINT8 tumbleBounces; - UINT16 tumbleHeight; + UINT16 tumbleHeight; // In *mobjscaled* fracunits, or mfu, not raw fu SINT8 drift; // (-5 to 5) - Drifting Left or Right, plus a bigger counter = sharper turn fixed_t driftcharge; // Charge your drift so you can release a burst of speed @@ -386,10 +396,12 @@ typedef struct player_s INT32 aizdrifttilt; INT32 aizdriftturn; + INT32 underwatertilt; + fixed_t offroad; // In Super Mario Kart, going offroad has lee-way of about 1 second before you start losing speed UINT8 waterskip; // Water skipping counter - UINT16 tiregrease; // Reduced friction timer after hitting a horizontal spring + UINT16 tiregrease; // Reduced friction timer after hitting a spring UINT16 springstars; // Spawn stars around a player when they hit a spring UINT16 springcolor; // Color of spring stars UINT8 dashpadcooldown; // Separate the vanilla SA-style dash pads from using flashing @@ -455,9 +467,6 @@ typedef struct player_s UINT8 trickpanel; // Trick panel state UINT8 tricktime; // Increases while you're tricking. You can't input any trick until it's reached a certain threshold - fixed_t trickmomx; - fixed_t trickmomy; - fixed_t trickmomz; fixed_t trickboostpower; // Save the rough speed multiplier. Used for upwards tricks. UINT8 trickboostdecay; // used to know how long you've waited UINT8 trickboost; // Trick boost. This one is weird and has variable speed. Dear god. @@ -467,10 +476,13 @@ typedef struct player_s UINT8 emeralds; UINT8 bumpers; INT16 karmadelay; + tic_t overtimekarma; // time to live in overtime comeback INT16 spheres; SINT8 glanceDir; // Direction the player is trying to look backwards in + UINT8 tripWireState; // see tripwirestate_t + // SINT8 lives; diff --git a/src/deh_soc.c b/src/deh_soc.c index 7b5318f2b..4ab4a29aa 100644 --- a/src/deh_soc.c +++ b/src/deh_soc.c @@ -2683,6 +2683,10 @@ void readsound(MYFILE *f, INT32 num) { S_sfx[num].pitch = value; } + else if (fastcmp(word, "VOLUME")) + { + S_sfx[num].volume = value; + } else if (fastcmp(word, "CAPTION") || fastcmp(word, "DESCRIPTION")) { deh_strlcpy(S_sfx[num].caption, word2, diff --git a/src/deh_tables.c b/src/deh_tables.c index a97d56865..e7e211f0c 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -323,6 +323,7 @@ actionpointer_t actionpointers[] = {{A_SPBChase}, "A_SPBCHASE"}, {{A_SSMineSearch}, "A_SSMINESEARCH"}, {{A_SSMineExplode}, "A_SSMINEEXPLODE"}, + {{A_LandMineExplode}, "A_LANDMINEEXPLODE"}, {{A_BallhogExplode}, "A_BALLHOGEXPLODE"}, {{A_LightningFollowPlayer}, "A_LIGHTNINGFOLLOWPLAYER"}, {{A_FZBoomFlash}, "A_FZBOOMFLASH"}, @@ -334,7 +335,6 @@ actionpointer_t actionpointers[] = {{A_ReaperThinker}, "A_REAPERTHINKER"}, {{A_FlameShieldPaper}, "A_FLAMESHIELDPAPER"}, {{A_InvincSparkleRotate}, "A_INVINCSPARKLEROTATE"}, - {{A_SpawnItemCapsuleParts}, "A_SPAWNITEMCAPSULEPARTS"}, {{NULL}, "NONE"}, @@ -3476,6 +3476,21 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_RANDOMITEM12", "S_DEADRANDOMITEM", + // Sphere Box (for Battle) + "S_SPHEREBOX1", + "S_SPHEREBOX2", + "S_SPHEREBOX3", + "S_SPHEREBOX4", + "S_SPHEREBOX5", + "S_SPHEREBOX6", + "S_SPHEREBOX7", + "S_SPHEREBOX8", + "S_SPHEREBOX9", + "S_SPHEREBOX10", + "S_SPHEREBOX11", + "S_SPHEREBOX12", + "S_DEADSPHEREBOX", + // Random Item Pop "S_RANDOMITEMPOP1", "S_RANDOMITEMPOP2", @@ -3490,9 +3505,9 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_ITEMCAPSULE_TOP_SIDE", "S_ITEMCAPSULE_BOTTOM_SIDE_AIR", "S_ITEMCAPSULE_BOTTOM_SIDE_GROUND", - "S_ITEMCAPSULE_TOP", - "S_ITEMCAPSULE_BOTTOM", - "S_ITEMCAPSULE_INSIDE", + //"S_ITEMCAPSULE_TOP", + //"S_ITEMCAPSULE_BOTTOM", + //"S_ITEMCAPSULE_INSIDE", // Signpost sparkles "S_SIGNSPARK1", @@ -4593,6 +4608,11 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_RINGSPARKS14", "S_RINGSPARKS15", + "S_GAINAX_TINY", + "S_GAINAX_HUGE", + "S_GAINAX_MID1", + "S_GAINAX_MID2", + "S_DRAFTDUST1", "S_DRAFTDUST2", "S_DRAFTDUST3", @@ -5730,6 +5750,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_KARMAFIREWORK", "MT_RINGSPARKS", + "MT_GAINAX", "MT_DRAFTDUST", "MT_SPBDUST", "MT_TIREGREASE", @@ -5852,7 +5873,7 @@ const char *const PLAYERFLAG_LIST[] = { "ATTACKDOWN", "ACCELDOWN", "BRAKEDOWN", - "WPNDOWN", // reserved - gonna turn this into lookback when i'm done with all the major reengineering + "LOOKDOWN", // Accessibility and cheats "KICKSTARTACCEL", // Is accelerate in kickstart mode? @@ -6839,6 +6860,7 @@ struct int_const_s const INT_CONST[] = { {"TC_RAINBOW",TC_RAINBOW}, {"TC_BLINK",TC_BLINK}, {"TC_DASHMODE",TC_DASHMODE}, + {"TC_HITLAG",TC_HITLAG}, // marathonmode flags {"MA_INIT",MA_INIT}, diff --git a/src/dummy/i_system.c b/src/dummy/i_system.c index 4a657ed19..f3d0bc5e8 100644 --- a/src/dummy/i_system.c +++ b/src/dummy/i_system.c @@ -16,7 +16,7 @@ tic_t I_GetTime(void) return 0; } -int I_GetTimeMicros(void) +fixed_t I_GetTimeFrac(void) { return 0; } diff --git a/src/f_finale.c b/src/f_finale.c index 099fa422d..eff9ed3f7 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -108,8 +108,12 @@ static patch_t *ttcheckers; // *vroom* KART static patch_t *ttkflash; // flash screen */ +#define NOWAY + +#ifdef NOWAY static patch_t *driver[2]; // Driving character on the waiting screen static UINT8 *waitcolormap; // colormap for the spinning character +#endif // ttmode user static patch_t *ttuser[TTMAX_USER]; @@ -2188,14 +2192,17 @@ void F_TitleDemoTicker(void) void F_StartWaitingPlayers(void) { +#ifdef NOWAY INT32 i; INT32 randskin; spritedef_t *sprdef; spriteframe_t *sprframe; +#endif wipegamestate = GS_TITLESCREEN; // technically wiping from title screen finalecount = 0; +#ifdef NOWAY randskin = M_RandomKey(numskins); if (waitcolormap) @@ -2208,8 +2215,9 @@ void F_StartWaitingPlayers(void) for (i = 0; i < 2; i++) { sprframe = &sprdef->spriteframes[i]; - driver[i] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL); + driver[i] = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); } +#endif } void F_WaitingPlayersTicker(void) @@ -2226,14 +2234,17 @@ void F_WaitingPlayersTicker(void) void F_WaitingPlayersDrawer(void) { +#ifdef NOWAY UINT32 frame = (finalecount % 8) / 4; // The game only tics every other frame while waitingplayers - INT32 flags = V_FLIP; +#endif const char *waittext1 = "You will join"; const char *waittext2 = "the next race..."; V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); V_DrawCreditString((160 - (V_CreditStringWidth(waittext1)>>1))<>1))<width / 2, 150<width / 2, 150<forwardmove != oldcmd[playernum].forwardmove) { - WRITEUINT8(demo_p,cmd->forwardmove); + WRITESINT8(demo_p,cmd->forwardmove); oldcmd[playernum].forwardmove = cmd->forwardmove; ziptic |= ZT_FWD; } @@ -621,7 +629,7 @@ void G_GhostAddHit(INT32 playernum, mobj_t *victim) ghostext[playernum].flags |= EZT_HIT; ghostext[playernum].hits++; ghostext[playernum].hitlist = Z_Realloc(ghostext[playernum].hitlist, ghostext[playernum].hits * sizeof(mobj_t *), PU_LEVEL, NULL); - ghostext[playernum].hitlist[ghostext[playernum].hits-1] = victim; + P_SetTarget(ghostext[playernum].hitlist + (ghostext[playernum].hits-1), victim); } void G_WriteAllGhostTics(void) @@ -793,6 +801,7 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum) WRITEFIXED(demo_p,mo->y); WRITEFIXED(demo_p,mo->z); WRITEANGLE(demo_p,mo->angle); + P_SetTarget(ghostext[playernum].hitlist+i, NULL); } Z_Free(ghostext[playernum].hitlist); ghostext[playernum].hits = 0; @@ -862,7 +871,12 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum) void G_ConsAllGhostTics(void) { - UINT8 p = READUINT8(demo_p); + UINT8 p; + + if (!demo_p || !demo.deferstart) + return; + + p = READUINT8(demo_p); while (p != 0xFF) { @@ -887,8 +901,6 @@ void G_ConsGhostTic(INT32 playernum) mobj_t *testmo; UINT32 syncleeway; - if (!demo_p || !demo.deferstart) - return; if (!(demoflags & DF_GHOST)) return; // No ghost data to use. @@ -965,7 +977,7 @@ void G_ConsGhostTic(INT32 playernum) if (th != &thlist[THINK_MOBJ] && mobj->health != health) // Wasn't damaged?! This is desync! Fix it! { if (demosynced) - CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n")); + CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced (health)!\n")); demosynced = false; P_DamageMobj(mobj, players[0].mo, players[0].mo, 1, DMG_NORMAL); } @@ -1018,7 +1030,7 @@ void G_ConsGhostTic(INT32 playernum) if (ghostext[playernum].desyncframes >= 2) { if (demosynced) - CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n")); + CONS_Alert(CONS_WARNING, "Demo playback has desynced (player %s)!\n", player_names[playernum]); demosynced = false; P_UnsetThingPosition(testmo); @@ -1041,7 +1053,7 @@ void G_ConsGhostTic(INT32 playernum) || players[playernum].bumpers != ghostext[playernum].kartbumpers) { if (demosynced) - CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n")); + CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced (item/bumpers)!\n")); demosynced = false; players[playernum].itemtype = ghostext[playernum].kartitem; @@ -1579,7 +1591,7 @@ void G_ReadMetalTic(mobj_t *metal) oldmetal.x = READFIXED(metal_p); oldmetal.y = READFIXED(metal_p); oldmetal.z = READFIXED(metal_p); - P_TeleportMove(metal, oldmetal.x, oldmetal.y, oldmetal.z); + P_MoveOrigin(metal, oldmetal.x, oldmetal.y, oldmetal.z); oldmetal.x = metal->x; oldmetal.y = metal->y; oldmetal.z = metal->z; @@ -1920,6 +1932,9 @@ void G_BeginRecording(void) demo_p = demobuffer; demoflags = DF_GHOST|(multiplayer ? DF_MULTIPLAYER : (modeattacking<>DF_ATTACKSHIFT; multiplayer = !!(demoflags & DF_MULTIPLAYER); + demo.netgame = (multiplayer && !(demoflags & DF_NONETMP)); CON_ToggleOff(); hu_demotime = UINT32_MAX; @@ -2926,7 +2943,7 @@ void G_DoPlayDemo(char *defdemoname) while (p != 0xFF) { - if ((spectator = (p & DEMO_SPECTATOR))) + if ((spectator = !!(p & DEMO_SPECTATOR))) { p &= ~DEMO_SPECTATOR; @@ -2974,6 +2991,11 @@ void G_DoPlayDemo(char *defdemoname) M_Memcpy(player_names[p],demo_p,16); demo_p += 16; + /*if (players[p].spectator) + { + CONS_Printf("player %s is spectator at start\n", player_names[p]); + }*/ + // Skin M_Memcpy(skin,demo_p,16); demo_p += 16; diff --git a/src/g_demo.h b/src/g_demo.h index 03d75cf4b..53f49be4d 100644 --- a/src/g_demo.h +++ b/src/g_demo.h @@ -41,6 +41,7 @@ struct demovars_s { boolean inreplayhut; // Go back to replayhut after demos boolean quitafterplaying; // quit after playing a demo from cmdline boolean deferstart; // don't start playing demo right away + boolean netgame; // multiplayer netgame tic_t savebutton; // Used to determine when the local player can choose to save the replay while the race is still going enum { diff --git a/src/g_game.c b/src/g_game.c index 580b3bf0d..e4fd7d209 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -45,8 +45,8 @@ #include "y_inter.h" #include "v_video.h" #include "lua_hook.h" -#include "k_bot.h" #include "m_cond.h" // condition sets +#include "r_fps.h" // frame interpolation/uncapped #include "lua_hud.h" // SRB2kart @@ -56,6 +56,7 @@ #include "k_color.h" #include "k_respawn.h" #include "k_grandprix.h" +#include "k_bot.h" #include "doomstat.h" #ifdef HAVE_DISCORDRPC @@ -345,7 +346,6 @@ static void kickstartaccel_OnChange(void); static void kickstartaccel2_OnChange(void); static void kickstartaccel3_OnChange(void); static void kickstartaccel4_OnChange(void); -void SendWeaponPref(UINT8 n); static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"}, {1, "X-Axis"}, {2, "Y-Axis"}, {-1, "X-Axis-"}, {-2, "Y-Axis-"}, @@ -1920,6 +1920,8 @@ void G_Ticker(boolean run) F_TextPromptTicker(); AM_Ticker(); HU_Ticker(); + R_UpdateViewInterpolation(); + break; case GS_INTERMISSION: @@ -1976,7 +1978,12 @@ void G_Ticker(boolean run) break; case GS_TITLESCREEN: - if (titlemapinaction) P_Ticker(run); + if (titlemapinaction) + { + P_Ticker(run); + R_UpdateViewInterpolation(); + } + F_TitleScreenTicker(run); break; @@ -2281,11 +2288,13 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->growshrinktimer = growshrinktimer; p->bumpers = bumper; p->karmadelay = comebacktime; + p->overtimekarma = 0; p->eggmanblame = -1; p->lastdraft = -1; p->karthud[khud_fault] = khudfault; p->nocontrol = nocontrol; p->kickstartaccel = kickstartaccel; + p->tripWireState = TRIP_NONE; memcpy(&p->respawn, &respawn, sizeof (p->respawn)); @@ -2550,7 +2559,7 @@ mapthing_t *G_FindRaceStart(INT32 playernum) if (j == i) continue; - if (netgame && cv_kartusepwrlv.value) + if ((netgame || (demo.playback && demo.netgame)) && cv_kartusepwrlv.value) { if (clientpowerlevels[j][PWRLV_RACE] == clientpowerlevels[i][PWRLV_RACE]) num++; @@ -2571,7 +2580,7 @@ mapthing_t *G_FindRaceStart(INT32 playernum) pos++; else { - if (netgame && cv_kartusepwrlv.value) + if ((netgame || (demo.playback && demo.netgame)) && cv_kartusepwrlv.value) { if (clientpowerlevels[i][PWRLV_RACE] > clientpowerlevels[playernum][PWRLV_RACE]) pos++; @@ -3111,7 +3120,7 @@ boolean G_GametypeHasTeams(void) // boolean G_GametypeHasSpectators(void) { - return (netgame || (multiplayer && demo.playback)); + return (netgame || (multiplayer && demo.netgame)); } // diff --git a/src/hardware/CMakeLists.txt b/src/hardware/CMakeLists.txt new file mode 100644 index 000000000..4e9c67d2f --- /dev/null +++ b/src/hardware/CMakeLists.txt @@ -0,0 +1 @@ +target_sourcefile(c) diff --git a/src/hardware/Sourcefile b/src/hardware/Sourcefile new file mode 100644 index 000000000..1c05de76c --- /dev/null +++ b/src/hardware/Sourcefile @@ -0,0 +1,13 @@ +hw_bsp.c +hw_draw.c +hw_light.c +hw_main.c +hw_clip.c +hw_md2.c +hw_cache.c +hw_md2load.c +hw_md3load.c +hw_model.c +u_list.c +hw_batching.c +r_opengl/r_opengl.c diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index f6842dca0..df3c663ff 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -452,7 +452,9 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex) UINT8 *pdata; INT32 blockwidth, blockheight, blocksize; +#ifdef GLENCORE UINT8 *colormap = colormaps; +#endif INT32 i; boolean skyspecial = false; //poor hack for Legacy large skies.. @@ -477,12 +479,14 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex) grtex->mipmap.height = (UINT16)texture->height; grtex->mipmap.format = textureformat; +#ifdef GLENCORE if (encoremap) colormap += COLORMAP_REMAPOFFSET; grtex->mipmap.colormap = Z_Calloc(sizeof(*grtex->mipmap.colormap), PU_HWRPATCHCOLMIPMAP, NULL); grtex->mipmap.colormap->source = colormap; M_Memcpy(grtex->mipmap.colormap->data, colormap, 256 * sizeof(UINT8)); +#endif blockwidth = texture->width; blockheight = texture->height; @@ -891,7 +895,9 @@ void HWR_GetRawFlat(lumpnum_t flatlumpnum, boolean noencoremap) GLMipmap_t *grmip; patch_t *patch; +#ifdef GLENCORE UINT8 *colormap = colormaps; +#endif if (flatlumpnum == LUMPERROR) return; @@ -899,12 +905,16 @@ void HWR_GetRawFlat(lumpnum_t flatlumpnum, boolean noencoremap) patch = HWR_GetCachedGLPatch(flatlumpnum); grmip = ((GLPatch_t *)Patch_AllocateHardwarePatch(patch))->mipmap; +#ifdef GLENCORE if (!noencoremap && encoremap) colormap += COLORMAP_REMAPOFFSET; grmip->colormap = Z_Calloc(sizeof(*grmip->colormap), PU_HWRPATCHCOLMIPMAP, NULL); grmip->colormap->source = colormap; M_Memcpy(grmip->colormap->data, colormap, 256 * sizeof(UINT8)); +#else + (void)noencoremap; +#endif if (!grmip->downloaded && !grmip->data) HWR_CacheFlat(grmip, flatlumpnum); diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 3f6ad01e5..2cdbd02c3 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -113,7 +113,7 @@ typedef struct UINT8 splitscreen; boolean flip; // screenflip boolean shearing; // 14042019 - angle_t viewaiming; // 17052019 + float viewaiming; // 17052019 boolean roll; FLOAT rollangle; // done to not override USE_FTRANSFORM_ANGLEZ FLOAT centerx, centery; @@ -284,7 +284,7 @@ struct FSurfaceInfo typedef struct FSurfaceInfo FSurfaceInfo; #define GL_DEFAULTMIX 0x00000000 -#define GL_DEFAULTFOG 0xFF000000 +#define GL_DEFAULTFOG 0x19000000 //Hurdler: added for backward compatibility enum hwdsetspecialstate diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index b48d39b9c..4f6046123 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -51,7 +51,7 @@ EXPORT void HWRAPI(ClearMipMapCache) (void); EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value); //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 hflipped, FSurfaceInfo *Surface); +EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float hscale, float vscale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface); EXPORT void HWRAPI(CreateModelVBOs) (model_t *model); EXPORT void HWRAPI(SetTransform) (FTransform *stransform); EXPORT INT32 HWRAPI(GetTextureUsed) (void); @@ -136,4 +136,4 @@ extern struct hwdriver_s hwdriver; #endif //not defined _CREATE_DLL_ -#endif //__HWR_DRV_H__ \ No newline at end of file +#endif //__HWR_DRV_H__ diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index aafef9eb4..79cdba4f3 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -26,7 +26,7 @@ //#define HWR_LOADING_SCREEN // SRB2Kart -#define GLENCORE +//#define GLENCORE // ----------- // structures diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index ed0523119..0da791279 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -38,7 +38,9 @@ #include "../m_cheat.h" #include "../f_finale.h" #include "../r_things.h" // R_GetShadowZ +#include "../d_main.h" #include "../p_slopes.h" +#include "../k_kart.h" // HITLAGJITTERS #include "hw_md2.h" #ifdef NEWCLIP @@ -1478,7 +1480,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom transnum_t transtable = R_GetLinedefTransTable(gl_linedef); if (transtable == NUMTRANSMAPS) transtable = 0; - if (gl_linedef->special == 910) + if (gl_linedef->special == 910 || + P_IsLineTripWire(gl_linedef)) blend = AST_ADD; else if (gl_linedef->special == 911) blend = AST_SUBTRACT; @@ -3622,70 +3625,82 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) { - fixed_t thingxpos = thing->x + thing->sprxoff; - fixed_t thingypos = thing->y + thing->spryoff; - fixed_t thingzpos = thing->z + thing->sprzoff; - patch_t *gpatch; FOutVector shadowVerts[4]; FSurfaceInfo sSurf; float fscale; float fx; float fy; float offset; + float ph; extracolormap_t *colormap = NULL; UINT8 i; SINT8 flip = P_MobjFlip(thing); + UINT32 tFlag = PF_ReverseSubtract; INT32 light; fixed_t scalemul; - UINT16 alpha; - fixed_t floordiff; fixed_t groundz; fixed_t slopez; pslope_t *groundslope; - // hitlag vibrating - if (thing->hitlag > 0) + fixed_t interpx = thing->x; + fixed_t interpy = thing->y; + fixed_t interpz = thing->z; + + // do interpolation + if (cv_frameinterpolation.value == 1) { - fixed_t mul = thing->hitlag * (FRACUNIT / 10); + interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x); + interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y); + interpz = thing->old_z + FixedMul(rendertimefrac, thing->z - thing->old_z); + } + + // hitlag vibrating (todo: interp somehow?) + if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG)) + { + fixed_t mul = thing->hitlag * HITLAGJITTERS; if (leveltime & 1) { mul = -mul; } - thingxpos += FixedMul(thing->momx, mul); - thingypos += FixedMul(thing->momy, mul); - thingzpos += FixedMul(thing->momz, mul); + interpx += FixedMul(thing->momx, mul); + interpy += FixedMul(thing->momy, mul); + interpz += FixedMul(thing->momz, mul); } + // sprite offset + interpx += thing->sprxoff; + interpy += thing->spryoff; + interpz += thing->sprzoff; + groundz = R_GetShadowZ(thing, &groundslope); - floordiff = abs((flip < 0 ? thing->height : 0) + thingzpos - groundz); - - alpha = floordiff / (4*FRACUNIT) + 75; - if (alpha >= 255) return; - alpha = 255 - alpha; - gpatch = (patch_t *)W_CachePatchName("DSHADOW", PU_SPRITE); if (!(gpatch && ((GLPatch_t *)gpatch->hardware)->mipmap->format)) return; HWR_GetPatch(gpatch); - scalemul = FixedMul(FRACUNIT - floordiff/640, scale); - scalemul = FixedMul(scalemul, (thing->radius*2) / gpatch->height); + scalemul = FixedMul(scale, (thing->radius * 2) / gpatch->height); + + ph = (float)gpatch->height; fscale = FIXED_TO_FLOAT(scalemul); - fx = FIXED_TO_FLOAT(thingxpos); - fy = FIXED_TO_FLOAT(thingypos); + fx = FIXED_TO_FLOAT(interpx); + fy = FIXED_TO_FLOAT(interpy); + + if (fscale > 0.0) + { + offset = (ph / 2) * fscale; + } + else + { + return; + } // 3--2 // | /| // |/ | // 0--1 - if (thing && fabsf(fscale - 1.0f) > 1.0E-36f) - offset = ((gpatch->height)/2) * fscale; - else - offset = (float)((gpatch->height)/2); - shadowVerts[2].x = shadowVerts[3].x = fx + offset; shadowVerts[1].x = shadowVerts[0].x = fx - offset; shadowVerts[1].z = shadowVerts[2].z = fy - offset; @@ -3733,10 +3748,15 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) colormap = thing->subsector->sector->extra_colormap; } - HWR_Lighting(&sSurf, 0, colormap); - sSurf.PolyColor.s.alpha = alpha; + HWR_Lighting(&sSurf, 255, colormap); + sSurf.PolyColor.s.alpha = 255; - HWR_ProcessPolygon(&sSurf, shadowVerts, 4, PF_Translucent|PF_Modulated, SHADER_SPRITE, false); // sprite shader + if (thing->whiteshadow == true) + { + tFlag = PF_Additive; + } + + HWR_ProcessPolygon(&sSurf, shadowVerts, 4, tFlag|PF_Modulated, SHADER_SPRITE, false); // sprite shader } // This is expecting a pointer to an array containing 4 wallVerts for a sprite @@ -5012,10 +5032,6 @@ static void HWR_AddSprites(sector_t *sec) // BP why not use xtoviexangle/viewangletox like in bsp ?.... static void HWR_ProjectSprite(mobj_t *thing) { - fixed_t thingxpos = thing->x + thing->sprxoff; - fixed_t thingypos = thing->y + thing->spryoff; - fixed_t thingzpos = thing->z + thing->sprzoff; - gl_vissprite_t *vis; float tr_x, tr_y; float tz; @@ -5044,7 +5060,6 @@ static void HWR_ProjectSprite(mobj_t *thing) INT32 heightsec, phs; const boolean splat = R_ThingIsFloorSprite(thing); const boolean papersprite = (R_ThingIsPaperSprite(thing) && !splat); - angle_t mobjangle = (thing->player ? thing->player->drawangle : thing->angle); float z1, z2; fixed_t spr_width, spr_height; @@ -5055,36 +5070,68 @@ static void HWR_ProjectSprite(mobj_t *thing) angle_t spriterotangle = 0; #endif + // uncapped/interpolation + fixed_t interpx; + fixed_t interpy; + fixed_t interpz; + angle_t interpangle; + if (!thing) return; if (thing->spritexscale < 1 || thing->spriteyscale < 1) return; - // hitlag vibrating - if (thing->hitlag > 0) + dispoffset = thing->info->dispoffset; + + interpx = thing->x; + interpy = thing->y; + interpz = thing->z; + interpangle = (thing->player ? thing->player->drawangle : thing->angle); + + if (cv_frameinterpolation.value == 1) { - fixed_t mul = thing->hitlag * (FRACUNIT / 10); + interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x); + interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y); + interpz = thing->old_z + FixedMul(rendertimefrac, thing->z - thing->old_z); + + if (thing->player) + { + interpangle = thing->player->old_drawangle + FixedMul(rendertimefrac, thing->player->drawangle - thing->player->old_drawangle); + } + else + { + interpangle = thing->old_angle + FixedMul(rendertimefrac, thing->angle - thing->old_angle); + } + } + + // hitlag vibrating (todo: interp somehow?) + if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG)) + { + fixed_t mul = thing->hitlag * HITLAGJITTERS; if (leveltime & 1) { mul = -mul; } - thingxpos += FixedMul(thing->momx, mul); - thingypos += FixedMul(thing->momy, mul); - thingzpos += FixedMul(thing->momz, mul); + interpx += FixedMul(thing->momx, mul); + interpy += FixedMul(thing->momy, mul); + interpz += FixedMul(thing->momz, mul); } - dispoffset = thing->info->dispoffset; + // sprite offset + interpx += thing->sprxoff; + interpy += thing->spryoff; + interpz += thing->sprzoff; this_scale = FIXED_TO_FLOAT(thing->scale); spritexscale = FIXED_TO_FLOAT(thing->spritexscale); spriteyscale = FIXED_TO_FLOAT(thing->spriteyscale); // transform the origin point - tr_x = FIXED_TO_FLOAT(thingxpos) - gl_viewx; - tr_y = FIXED_TO_FLOAT(thingypos) - gl_viewy; + tr_x = FIXED_TO_FLOAT(interpx) - gl_viewx; + tr_y = FIXED_TO_FLOAT(interpy) - gl_viewy; // rotation around vertical axis tz = (tr_x * gl_viewcos) + (tr_y * gl_viewsin); @@ -5107,8 +5154,8 @@ static void HWR_ProjectSprite(mobj_t *thing) } // The above can stay as it works for cutting sprites that are too close - tr_x = FIXED_TO_FLOAT(thingxpos); - tr_y = FIXED_TO_FLOAT(thingypos); + tr_x = FIXED_TO_FLOAT(interpx); + tr_y = FIXED_TO_FLOAT(interpy); // decide which patch to use for sprite relative to player #ifdef RANGECHECK @@ -5156,7 +5203,7 @@ static void HWR_ProjectSprite(mobj_t *thing) I_Error("sprframes NULL for sprite %d\n", thing->sprite); #endif - ang = R_PointToAngle (thingxpos, thingypos) - mobjangle; + ang = R_PointToAngle (interpx, interpy) - interpangle; if (mirrored) ang = InvAngle(ang); @@ -5202,6 +5249,8 @@ static void HWR_ProjectSprite(mobj_t *thing) spr_topoffset = spritecachedinfo[lumpoff].topoffset; #ifdef ROTSPRITE + spriterotangle = R_SpriteRotationAngle(thing, NULL); + if (spriterotangle != 0 && !(splat && !(thing->renderflags & RF_NOSPLATROLLANGLE))) { @@ -5241,8 +5290,8 @@ static void HWR_ProjectSprite(mobj_t *thing) if (papersprite) { - rightsin = FIXED_TO_FLOAT(FINESINE((mobjangle)>>ANGLETOFINESHIFT)); - rightcos = FIXED_TO_FLOAT(FINECOSINE((mobjangle)>>ANGLETOFINESHIFT)); + rightsin = FIXED_TO_FLOAT(FINESINE((interpangle)>>ANGLETOFINESHIFT)); + rightcos = FIXED_TO_FLOAT(FINECOSINE((interpangle)>>ANGLETOFINESHIFT)); } else { @@ -5303,12 +5352,12 @@ static void HWR_ProjectSprite(mobj_t *thing) if (vflip) { - gz = FIXED_TO_FLOAT(thingzpos + thing->height) - (FIXED_TO_FLOAT(spr_topoffset) * this_yscale); + gz = FIXED_TO_FLOAT(interpz + thing->height) - (FIXED_TO_FLOAT(spr_topoffset) * this_yscale); gzt = gz + (FIXED_TO_FLOAT(spr_height) * this_yscale); } else { - gzt = FIXED_TO_FLOAT(thingzpos) + (FIXED_TO_FLOAT(spr_topoffset) * this_yscale); + gzt = FIXED_TO_FLOAT(interpz) + (FIXED_TO_FLOAT(spr_topoffset) * this_yscale); gz = gzt - (FIXED_TO_FLOAT(spr_height) * this_yscale); } @@ -5319,7 +5368,7 @@ static void HWR_ProjectSprite(mobj_t *thing) } heightsec = thing->subsector->sector->heightsec; - if (viewplayer->mo && viewplayer->mo->subsector) + if (viewplayer && viewplayer->mo && viewplayer->mo->subsector) phs = viewplayer->mo->subsector->sector->heightsec; else phs = -1; @@ -5327,12 +5376,12 @@ static void HWR_ProjectSprite(mobj_t *thing) if (heightsec != -1 && phs != -1) // only clip things which are in special sectors { if (gl_viewz < FIXED_TO_FLOAT(sectors[phs].floorheight) ? - FIXED_TO_FLOAT(thingzpos) >= FIXED_TO_FLOAT(sectors[heightsec].floorheight) : + FIXED_TO_FLOAT(interpz) >= FIXED_TO_FLOAT(sectors[heightsec].floorheight) : gzt < FIXED_TO_FLOAT(sectors[heightsec].floorheight)) return; if (gl_viewz > FIXED_TO_FLOAT(sectors[phs].ceilingheight) ? gzt < FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) && gl_viewz >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight) : - FIXED_TO_FLOAT(thingzpos) >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight)) + FIXED_TO_FLOAT(interpz) >= FIXED_TO_FLOAT(sectors[heightsec].ceilingheight)) return; } @@ -5401,7 +5450,11 @@ static void HWR_ProjectSprite(mobj_t *thing) vis->mobj = thing; //Hurdler: 25/04/2000: now support colormap in hardware mode - if ((vis->mobj->flags & (MF_ENEMY|MF_BOSS)) && (vis->mobj->flags2 & MF2_FRET) && !(vis->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash" + if (vis->mobj->hitlag > 0 && (vis->mobj->eflags & MFE_DAMAGEHITLAG)) + { + vis->colormap = R_GetTranslationColormap(TC_HITLAG, 0, GTC_CACHE); + } + else if ((vis->mobj->flags & (MF_ENEMY|MF_BOSS)) && (vis->mobj->flags2 & MF2_FRET) && !(vis->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash" { if (vis->mobj->type == MT_CYBRAKDEMON || vis->mobj->colorized) vis->colormap = R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE); @@ -5431,8 +5484,10 @@ static void HWR_ProjectSprite(mobj_t *thing) { vis->colormap = colormaps; +#ifdef GLENCORE if (encoremap && (thing->flags & (MF_SCENERY|MF_NOTHINK)) && !(thing->flags & MF_DONTENCOREMAP)) vis->colormap += COLORMAP_REMAPOFFSET; +#endif } // set top/bottom coords @@ -5463,9 +5518,29 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) unsigned rot = 0; UINT8 flip; + // uncapped/interpolation + fixed_t interpx; + fixed_t interpy; + fixed_t interpz; + + if (!thing) + return; + + interpx = thing->x; + interpy = thing->y; + interpz = thing->z; + + // do interpolation + if (cv_frameinterpolation.value == 1) + { + interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x); + interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y); + interpz = thing->old_z + FixedMul(rendertimefrac, thing->z - thing->old_z); + } + // transform the origin point - tr_x = FIXED_TO_FLOAT(thing->x) - gl_viewx; - tr_y = FIXED_TO_FLOAT(thing->y) - gl_viewy; + tr_x = FIXED_TO_FLOAT(interpx) - gl_viewx; + tr_y = FIXED_TO_FLOAT(interpy) - gl_viewy; // rotation around vertical axis tz = (tr_x * gl_viewcos) + (tr_y * gl_viewsin); @@ -5474,8 +5549,8 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) if (tz < ZCLIP_PLANE) return; - tr_x = FIXED_TO_FLOAT(thing->x); - tr_y = FIXED_TO_FLOAT(thing->y); + tr_x = FIXED_TO_FLOAT(interpx); + tr_y = FIXED_TO_FLOAT(interpy); // decide which patch to use for sprite relative to player if ((unsigned)thing->sprite >= numsprites) @@ -5542,7 +5617,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) #endif // set top/bottom coords - vis->gzt = FIXED_TO_FLOAT(thing->z + spritecachedinfo[lumpoff].topoffset); + vis->gzt = FIXED_TO_FLOAT(interpz + spritecachedinfo[lumpoff].topoffset); vis->gz = vis->gzt - FIXED_TO_FLOAT(spritecachedinfo[lumpoff].height); vis->precip = true; @@ -5744,8 +5819,7 @@ static void HWR_DrawSkyBackground(player_t *player) dometransform.scalez = 1; dometransform.fovxangle = fpov; // Tails dometransform.fovyangle = fpov; // Tails - HWR_RollTransform(&dometransform, - R_ViewRollAngle(player)); + HWR_RollTransform(&dometransform, viewroll); dometransform.splitscreen = r_splitscreen; HWR_GetTexture(texturetranslation[skytexture]); @@ -6037,7 +6111,7 @@ void HWR_RenderSkyboxView(player_t *player) atransform.fovxangle = fpov; // Tails atransform.fovyangle = fpov; // Tails - HWR_RollTransform(&atransform, R_ViewRollAngle(player)); + HWR_RollTransform(&atransform, viewroll); atransform.splitscreen = r_splitscreen; gl_fovlud = (float)(1.0l/tan((double)(fpov*M_PIl/360l))); @@ -6249,7 +6323,7 @@ void HWR_RenderPlayerView(void) atransform.fovxangle = fpov; // Tails atransform.fovyangle = fpov; // Tails - HWR_RollTransform(&atransform, R_ViewRollAngle(player)); + HWR_RollTransform(&atransform, viewroll); atransform.splitscreen = r_splitscreen; gl_fovlud = (float)(1.0l/tan((double)(fpov*M_PIl/360l))); @@ -6697,6 +6771,8 @@ void HWR_DoPostProcessor(player_t *player) // 10 by 10 grid. 2 coordinates (xy) float v[SCREENVERTS][SCREENVERTS][2]; static double disStart = 0; + static fixed_t last_fractime = 0; + UINT8 x, y; INT32 WAVELENGTH; INT32 AMPLITUDE; @@ -6728,6 +6804,15 @@ void HWR_DoPostProcessor(player_t *player) HWD.pfnPostImgRedraw(v); if (!(paused || P_AutoPause())) disStart += 1; + if (renderdeltatics > FRACUNIT) + { + disStart = disStart - FIXED_TO_FLOAT(last_fractime) + 1 + FIXED_TO_FLOAT(rendertimefrac); + } + else + { + disStart = disStart - FIXED_TO_FLOAT(last_fractime) + FIXED_TO_FLOAT(rendertimefrac); + } + last_fractime = rendertimefrac; // Capture the screen again for screen waving on the intermission if(gamestate != GS_INTERMISSION) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index f6c18db97..95077a54a 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -45,6 +45,7 @@ // SRB2Kart #include "../k_color.h" +#include "../k_kart.h" // HITLAGJITTERS #ifdef HAVE_PNG @@ -819,7 +820,12 @@ static void HWR_CreateBlendedTexture(patch_t *gpatch, patch_t *blendgpatch, GLMi while (size--) { - if (skinnum == TC_BOSS) + if (skinnum == TC_HITLAG) + { + cur->s.red = cur->s.green = cur->s.blue = K_HitlagColorValue(*image); + cur->s.alpha = image->s.alpha; + } + else 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) @@ -1350,10 +1356,6 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) // Look at HWR_ProjectSprite for more { - fixed_t thingxpos = spr->mobj->x + spr->mobj->sprxoff; - fixed_t thingypos = spr->mobj->y + spr->mobj->spryoff; - fixed_t thingzpos = spr->mobj->z + spr->mobj->sprzoff; - patch_t *gpatch, *blendgpatch; GLPatch_t *hwrPatch = NULL, *hwrBlendPatch = NULL; INT32 durs = spr->mobj->state->tics; @@ -1366,21 +1368,38 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) INT32 mod; float finalscale; - // hitlag vibrating - if (spr->mobj->hitlag > 0) + fixed_t interpx = spr->mobj->x; + fixed_t interpy = spr->mobj->y; + fixed_t interpz = spr->mobj->z; + + // do interpolation + if (cv_frameinterpolation.value == 1) { - fixed_t mul = spr->mobj->hitlag * (FRACUNIT / 10); + interpx = spr->mobj->old_x + FixedMul(rendertimefrac, spr->mobj->x - spr->mobj->old_x); + interpy = spr->mobj->old_y + FixedMul(rendertimefrac, spr->mobj->y - spr->mobj->old_y); + interpz = spr->mobj->old_z + FixedMul(rendertimefrac, spr->mobj->z - spr->mobj->old_z); + } + + // hitlag vibrating + if (spr->mobj->hitlag > 0 && (spr->mobj->eflags & MFE_DAMAGEHITLAG)) + { + fixed_t mul = spr->mobj->hitlag * HITLAGJITTERS; if (leveltime & 1) { mul = -mul; } - thingxpos += FixedMul(spr->mobj->momx, mul); - thingypos += FixedMul(spr->mobj->momy, mul); - thingzpos += FixedMul(spr->mobj->momz, mul); + interpx += FixedMul(spr->mobj->momx, mul); + interpy += FixedMul(spr->mobj->momy, mul); + interpy += FixedMul(spr->mobj->momz, mul); } + // sprite offset + interpx += spr->mobj->sprxoff; + interpy += spr->mobj->spryoff; + interpz += spr->mobj->sprzoff; + // Apparently people don't like jump frames like that, so back it goes //if (tics > durs) //durs = tics; @@ -1486,7 +1505,11 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) { INT32 skinnum = TC_DEFAULT; - if ((spr->mobj->flags & (MF_ENEMY|MF_BOSS)) && (spr->mobj->flags2 & MF2_FRET) && !(spr->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash" + if (spr->mobj->hitlag > 0 && (spr->mobj->eflags & MFE_DAMAGEHITLAG)) + { + skinnum = TC_HITLAG; + } + else if ((spr->mobj->flags & (MF_ENEMY|MF_BOSS)) && (spr->mobj->flags2 & MF2_FRET) && !(spr->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash" { if (spr->mobj->type == MT_CYBRAKDEMON || spr->mobj->colorized) skinnum = TC_ALLWHITE; @@ -1596,13 +1619,13 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) #endif //Hurdler: it seems there is still a small problem with mobj angle - p.x = FIXED_TO_FLOAT(thingxpos); - p.y = FIXED_TO_FLOAT(thingypos) + md2->offset; + p.x = FIXED_TO_FLOAT(interpx); + p.y = FIXED_TO_FLOAT(interpy) + md2->offset; if (flip) p.z = FIXED_TO_FLOAT(spr->mobj->z + spr->mobj->height); else - p.z = FIXED_TO_FLOAT(thingzpos); + p.z = FIXED_TO_FLOAT(interpz); if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) sprdef = &((skin_t *)spr->mobj->skin)->sprites[spr->mobj->sprite2]; @@ -1622,27 +1645,30 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) } else { - const fixed_t anglef = AngleFixed((R_PointToAngle(thingxpos, thingypos))-ANGLE_180); + const fixed_t anglef = AngleFixed((R_PointToAngle(interpx, interpy))-ANGLE_180); p.angley = FIXED_TO_FLOAT(anglef); } - p.rollangle = 0.0f; - - if (spr->mobj->rollangle) { - fixed_t camAngleDiff = AngleFixed(viewangle) - FLOAT_TO_FIXED(p.angley); // dumb reconversion back, I know - fixed_t anglef = AngleFixed(spr->mobj->rollangle); + fixed_t anglef = AngleFixed(R_ModelRotationAngle(spr->mobj, NULL)); - p.rollangle = FIXED_TO_FLOAT(anglef); - p.roll = true; + p.rollangle = 0.0f; - // rotation pivot - p.centerx = FIXED_TO_FLOAT(spr->mobj->radius / 2); - p.centery = FIXED_TO_FLOAT(spr->mobj->height / 2); + if (anglef) + { + fixed_t camAngleDiff = AngleFixed(viewangle) - FLOAT_TO_FIXED(p.angley); // dumb reconversion back, I know - // rotation axes relative to camera - p.rollx = FIXED_TO_FLOAT(FINECOSINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT)); - p.rollz = FIXED_TO_FLOAT(FINESINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT)); + p.rollangle = FIXED_TO_FLOAT(anglef); + p.roll = true; + + // rotation pivot + p.centerx = FIXED_TO_FLOAT(spr->mobj->radius / 2); + p.centery = FIXED_TO_FLOAT(spr->mobj->height / 2); + + // rotation axes relative to camera + p.rollx = FIXED_TO_FLOAT(FINECOSINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT)); + p.rollz = FIXED_TO_FLOAT(FINESINE(FixedAngle(camAngleDiff) >> ANGLETOFINESHIFT)); + } } p.anglez = FIXED_TO_FLOAT(AngleFixed(spr->mobj->pitch)); @@ -1655,7 +1681,11 @@ boolean HWR_DrawModel(gl_vissprite_t *spr) p.mirror = atransform.mirror; HWD.pfnSetShader(SHADER_MODEL); // model shader - HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, hflip, &Surf); + { + float xs = finalscale * FIXED_TO_FLOAT(spr->mobj->spritexscale); + float ys = finalscale * FIXED_TO_FLOAT(spr->mobj->spriteyscale); + HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, xs, ys, flip, hflip, &Surf); + } } return true; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 367ce8331..b2762dcbf 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -715,14 +715,15 @@ static GLRGBAFloat shader_defaultcolor = {1.0f, 1.0f, 1.0f, 1.0f}; "float colorBrightness = sqrt((final_color.r * final_color.r) + (final_color.g * final_color.g) + (final_color.b * final_color.b));\n" \ "float fogBrightness = sqrt((fade_color.r * fade_color.r) + (fade_color.g * fade_color.g) + (fade_color.b * fade_color.b));\n" \ "float colorIntensity = 0.0;\n" \ - "if (fogBrightness > colorBrightness) {\n" \ + "if (colorBrightness < fogBrightness) {\n" \ "colorIntensity = 1.0 - min(final_color.r, min(final_color.g, final_color.b));\n" \ - "colorIntensity = abs(colorIntensity - (1.0 - fogBrightness));\n" \ + "colorIntensity = abs(colorIntensity - (1.0 - max(fade_color.r, max(fade_color.g, fade_color.b))));\n" \ "} else {\n" \ "colorIntensity = max(final_color.r, max(final_color.g, final_color.b));\n" \ - "colorIntensity = abs(colorIntensity - (fogBrightness));\n" \ + "colorIntensity = abs(colorIntensity - min(fade_color.r, min(fade_color.g, fade_color.b)));\n" \ "}\n" \ "colorIntensity *= darkness;\n" \ + "colorIntensity *= fade_color.a * 10.0;\n" \ "if (abs(final_color.r - fade_color.r) <= colorIntensity) {\n" \ "final_color.r = fade_color.r;\n" \ "} else if (final_color.r < fade_color.r) {\n" \ @@ -2687,7 +2688,7 @@ EXPORT void HWRAPI(CreateModelVBOs) (model_t *model) #define BUFFER_OFFSET(i) ((void*)(i)) -static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface) +static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float hscale, float vscale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface) { static GLRGBAFloat poly = {0,0,0,0}; static GLRGBAFloat tint = {0,0,0,0}; @@ -2711,10 +2712,11 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 #endif // Affect input model scaling - scale *= 0.5f; - scalex = scale; - scaley = scale; - scalez = scale; + hscale *= 0.5f; + vscale *= 0.5f; + scalex = hscale; + scaley = vscale; + scalez = hscale; if (duration != 0 && duration != -1 && tics != -1) // don't interpolate if instantaneous or infinite in length { @@ -2972,9 +2974,9 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 // -----------------+ // HWRAPI DrawModel : Draw a model // -----------------+ -EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface) +EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float hscale, float vscale, UINT8 flipped, UINT8 hflipped, FSurfaceInfo *Surface) { - DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, scale, flipped, hflipped, Surface); + DrawModelEx(model, frameIndex, duration, tics, nextFrameIndex, pos, hscale, vscale, flipped, hflipped, Surface); } // -----------------+ diff --git a/src/i_system.h b/src/i_system.h index 0d5898a72..789117eaa 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -46,13 +46,17 @@ UINT32 I_GetFreeMem(UINT32 *total); */ tic_t I_GetTime(void); +/** \brief Get the current time as a fraction of a tic since the last tic. +*/ +fixed_t I_GetTimeFrac(void); + /** \brief Returns precise time value for performance measurement. */ precise_t I_GetPreciseTime(void); /** \brief Returns the difference between precise times as microseconds. */ -int I_PreciseToMicros(precise_t); +int I_PreciseToMicros(precise_t d); /** \brief The I_Sleep function diff --git a/src/info.c b/src/info.c index 7f2e06f56..062d1fbb2 100644 --- a/src/info.c +++ b/src/info.c @@ -526,6 +526,7 @@ char sprnames[NUMSPRITES + 1][5] = //SRB2kart Sprites (sort later) "RNDM", // Random Item Box + "SBOX", // Sphere Box (for Battle) "RPOP", // Random Item Box Pop "SGNS", // Signpost sparkle "FAST", // Speed boost trail @@ -727,6 +728,7 @@ char sprnames[NUMSPRITES + 1][5] = "FWRK", "MXCL", "RGSP", + "LENS", "DRAF", "GRES", @@ -4060,6 +4062,20 @@ state_t states[NUMSTATES] = {SPR_RNDM, 22|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_RANDOMITEM1}, // S_RANDOMITEM12 {SPR_NULL, 0, 0, {A_ItemPop}, 0, 0, S_NULL}, // S_DEADRANDOMITEM + {SPR_SBOX, FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX2}, // S_SPHEREBOX1 + {SPR_SBOX, 2|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX3}, // S_SPHEREBOX2 + {SPR_SBOX, 4|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX4}, // S_SPHEREBOX3 + {SPR_SBOX, 6|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX5}, // S_SPHEREBOX4 + {SPR_SBOX, 8|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX6}, // S_SPHEREBOX5 + {SPR_SBOX, 10|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX7}, // S_SPHEREBOX6 + {SPR_SBOX, 12|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX8}, // S_SPHEREBOX7 + {SPR_SBOX, 14|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX9}, // S_SPHEREBOX8 + {SPR_SBOX, 16|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX10}, // S_SPHEREBOX9 + {SPR_SBOX, 18|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX11}, // S_SPHEREBOX10 + {SPR_SBOX, 20|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX12}, // S_SPHEREBOX11 + {SPR_SBOX, 22|FF_FULLBRIGHT|FF_ANIMATE|FF_GLOBALANIM, 4, {NULL}, 1, 1, S_SPHEREBOX1}, // S_SPHEREBOX12 + {SPR_NULL, 0, 0, {A_ItemPop}, 1, 0, S_NULL}, // S_DEADSPHEREBOX + {SPR_RPOP, FF_FULLBRIGHT, 5, {NULL}, 0, 0, S_RANDOMITEMPOP2}, // S_RANDOMITEMPOP1 {SPR_RPOP, FF_FULLBRIGHT|1, 5, {NULL}, 0, 0, S_RANDOMITEMPOP3}, // S_RANDOMITEMPOP2 {SPR_RPOP, FF_FULLBRIGHT|2, 5, {NULL}, 0, 0, S_RANDOMITEMPOP4}, // S_RANDOMITEMPOP3 @@ -4067,25 +4083,25 @@ state_t states[NUMSTATES] = {SPR_NULL, FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMICON - {SPR_ICAP, FF_ADD|0, -1, {A_SpawnItemCapsuleParts}, 0, 0, S_NULL}, // S_ITEMCAPSULE + {SPR_ICAP, FF_ADD|0, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE {SPR_ICAP, FF_PAPERSPRITE|1, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_TOP_SIDE {SPR_ICAP, FF_VERTICALFLIP|FF_PAPERSPRITE|1, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_BOTTOM_SIDE_AIR {SPR_ICAP, FF_PAPERSPRITE|2, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_BOTTOM_SIDE_GROUND - {SPR_ICAP, FF_FLOORSPRITE|3, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_TOP - {SPR_ICAP, FF_FLOORSPRITE|4, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_BOTTOM - {SPR_ICAP, FF_FLOORSPRITE|5, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_INSIDE + //{SPR_ICAP, FF_FLOORSPRITE|3, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_TOP + //{SPR_ICAP, FF_FLOORSPRITE|4, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_BOTTOM + //{SPR_ICAP, FF_FLOORSPRITE|5, -1, {NULL}, 0, 0, S_NULL}, // S_ITEMCAPSULE_INSIDE - {SPR_SGNS, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_SIGNSPARK2}, // S_SIGNSPARK1 - {SPR_SGNS, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_SIGNSPARK3}, // S_SIGNSPARK2 - {SPR_SGNS, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_SIGNSPARK4}, // S_SIGNSPARK3 - {SPR_SGNS, FF_FULLBRIGHT|3, 1, {NULL}, 0, 0, S_SIGNSPARK5}, // S_SIGNSPARK4 - {SPR_SGNS, FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_SIGNSPARK6}, // S_SIGNSPARK5 - {SPR_SGNS, FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_SIGNSPARK7}, // S_SIGNSPARK6 - {SPR_SGNS, FF_FULLBRIGHT|6, 1, {NULL}, 0, 0, S_SIGNSPARK8}, // S_SIGNSPARK7 - {SPR_SGNS, FF_FULLBRIGHT|7, 1, {NULL}, 0, 0, S_SIGNSPARK9}, // S_SIGNSPARK8 - {SPR_SGNS, FF_FULLBRIGHT|8, 1, {NULL}, 0, 0, S_SIGNSPARK10}, // S_SIGNSPARK9 - {SPR_SGNS, FF_FULLBRIGHT|3, 1, {NULL}, 0, 0, S_SIGNSPARK11}, // S_SIGNSPARK10 - {SPR_SGNS, FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_NULL}, // S_SIGNSPARK11 + {SPR_SGNS, FF_ADD|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_SIGNSPARK2}, // S_SIGNSPARK1 + {SPR_SGNS, FF_ADD|FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_SIGNSPARK3}, // S_SIGNSPARK2 + {SPR_SGNS, FF_ADD|FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_SIGNSPARK4}, // S_SIGNSPARK3 + {SPR_SGNS, FF_ADD|FF_FULLBRIGHT|3, 1, {NULL}, 0, 0, S_SIGNSPARK5}, // S_SIGNSPARK4 + {SPR_SGNS, FF_ADD|FF_FULLBRIGHT|4, 1, {NULL}, 0, 0, S_SIGNSPARK6}, // S_SIGNSPARK5 + {SPR_SGNS, FF_ADD|FF_FULLBRIGHT|5, 1, {NULL}, 0, 0, S_SIGNSPARK7}, // S_SIGNSPARK6 + {SPR_SGNS, FF_ADD|FF_FULLBRIGHT|6, 1, {NULL}, 0, 0, S_SIGNSPARK8}, // S_SIGNSPARK7 + {SPR_SGNS, FF_ADD|FF_FULLBRIGHT|7, 1, {NULL}, 0, 0, S_SIGNSPARK9}, // S_SIGNSPARK8 + {SPR_SGNS, FF_ADD|FF_FULLBRIGHT|8, 1, {NULL}, 0, 0, S_SIGNSPARK10}, // S_SIGNSPARK9 + {SPR_SGNS, FF_ADD|FF_FULLBRIGHT|3, 1, {NULL}, 0, 0, S_SIGNSPARK11}, // S_SIGNSPARK10 + {SPR_SGNS, FF_ADD|FF_FULLBRIGHT|2, 1, {NULL}, 0, 0, S_NULL}, // S_SIGNSPARK11 {SPR_DRIF, FF_FULLBRIGHT|2, 2, {NULL}, 0, 0, S_DRIFTSPARK_A2}, // S_DRIFTSPARK_A1 {SPR_DRIF, FF_FULLBRIGHT|FF_TRANS20|1, 1, {NULL}, 0, 0, S_DRIFTSPARK_A3}, // S_DRIFTSPARK_A2 @@ -4357,7 +4373,7 @@ state_t states[NUMSTATES] = {SPR_KRBM, FF_FULLBRIGHT|9, 5, {NULL}, 0, 0, S_NULL}, // S_SLOWBOOM10 {SPR_LNDM, 0, -1, {NULL}, 0, 0, S_LANDMINE}, // S_LANDMINE - {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_LANDMINE_EXPLODE + {SPR_NULL, 0, 1, {A_LandMineExplode}, 0, 0, S_NULL}, // S_LANDMINE_EXPLODE {SPR_BHOG, 0, 3, {A_PlaySound}, sfx_s1bd, 1, S_BALLHOG2}, // S_BALLHOG1 {SPR_BHOG, FF_FULLBRIGHT|1, 1, {NULL}, 0, 0, S_BALLHOG3}, // S_BALLHOG2 @@ -5178,6 +5194,11 @@ state_t states[NUMSTATES] = {SPR_RGSP, FF_PAPERSPRITE|FF_FULLBRIGHT|13, 1, {NULL}, 0, 0, S_RINGSPARKS15}, // S_RINGSPARKS14 {SPR_RGSP, FF_PAPERSPRITE|FF_FULLBRIGHT|14, 1, {NULL}, 0, 0, S_NULL}, // S_RINGSPARKS15 + {SPR_LENS, FF_FULLBRIGHT|FF_ADD|FF_TRANS10|FF_ANIMATE|11, -1, {NULL}, 3, 1, S_NULL}, // S_GAINAX_TINY + {SPR_LENS, FF_FULLBRIGHT|FF_ADD|FF_TRANS10|FF_ANIMATE, 5, {NULL}, 5, 1, S_GAINAX_MID1}, // S_GAINAX_HUGE + {SPR_LENS, FF_FULLBRIGHT|FF_ADD|FF_TRANS10|FF_ANIMATE|5, 14, {NULL}, 14, 1, S_GAINAX_MID2}, // S_GAINAX_MID1 + {SPR_LENS, FF_FULLBRIGHT|FF_ADD|FF_TRANS10|FF_ANIMATE|19, -1, {NULL}, 1, 1, S_NULL}, // S_GAINAX_MID2 + {SPR_DRAF, 0, 2, {NULL}, 0, 0, S_DRAFTDUST2}, // S_DRAFTDUST1 {SPR_DRAF, 1, 1, {NULL}, 0, 0, S_DRAFTDUST3}, // S_DRAFTDUST2 {SPR_DRAF, 2, 1, {NULL}, 0, 0, S_DRAFTDUST4}, // S_DRAFTDUST3 @@ -8680,7 +8701,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 20*FRACUNIT, // mass 0, // damage sfx_None, // activesound - MF_NOGRAVITY, // flags + MF_SPECIAL|MF_NOGRAVITY, // flags S_BALLOONPOP1 // raisestate }, @@ -9193,7 +9214,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // mass 0, // damage sfx_None, // activesound - MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_NOTHINK|MF_DONTENCOREMAP, // flags + MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags S_NULL // raisestate }, @@ -23011,6 +23032,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_SPHEREBOX + -1, // doomednum + S_SPHEREBOX1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_DEADSPHEREBOX, // deathstate + S_NULL, // xdeathstate + sfx_kc2e, // deathsound + 60*FRACUNIT, // speed + 48*FRACUNIT, // radius + 48*FRACUNIT, // height + 0, // display offset + 100, // mass + MT_RANDOMITEMPOP, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + { // MT_RANDOMITEMPOP -1, // doomednum S_INVISIBLE, // spawnstate @@ -23088,7 +23136,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_SLIDEME|MF_SPECIAL|MF_RUNSPAWNFUNC|MF_DONTENCOREMAP, // flags + MF_SLIDEME|MF_SPECIAL|MF_DONTENCOREMAP, // flags S_NULL // raisestate }, @@ -28683,6 +28731,32 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_NOBLOCKMAP|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_NULL // raisestate }, + { // MT_GAINAX + -1, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8<momz = flip * 24 * mapobjectscale; if (emerald->eflags & MFE_UNDERWATER) @@ -229,6 +229,28 @@ mobj_t *K_SpawnChaosEmerald(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT return emerald; } +mobj_t *K_SpawnSphereBox(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT8 amount) +{ + mobj_t *drop = P_SpawnMobj(x, y, z, MT_SPHEREBOX); + + (void)amount; + + drop->angle = angle; + P_Thrust(drop, + FixedAngle(P_RandomFixed() * 180) + angle, + P_RandomRange(4, 12) * mapobjectscale); + + drop->momz = flip * 12 * mapobjectscale; + if (drop->eflags & MFE_UNDERWATER) + drop->momz = (117 * drop->momz) / 200; + + drop->flags &= ~(MF_NOGRAVITY|MF_NOCLIPHEIGHT); + + drop->extravalue1 = amount; + + return drop; +} + void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType) { UINT8 i; @@ -288,12 +310,6 @@ void K_RunPaperItemSpawners(void) if (overtime == true) { - if (battleovertime.radius < 512*mapobjectscale) - { - // Barrier has closed in too much - return; - } - // Double frequency of items interval /= 2; } @@ -365,6 +381,12 @@ void K_RunPaperItemSpawners(void) FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, 0, 0 ); + + K_SpawnSphereBox( + battleovertime.x, battleovertime.y, battleovertime.z + (128 * mapobjectscale * flip), + FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, + 10 + ); } } else @@ -447,6 +469,14 @@ void K_RunPaperItemSpawners(void) firstUnspawnedEmerald ); } + else if (P_RandomChance(FRACUNIT/3)) + { + drop = K_SpawnSphereBox( + spotList[r]->x, spotList[r]->y, spotList[r]->z + (128 * mapobjectscale * flip), + FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip, + 10 + ); + } else { drop = K_CreatePaperItem( @@ -557,10 +587,12 @@ void K_RunBattleOvertime(void) } else if (battleovertime.radius > 0) { - if (battleovertime.radius > 2*mapobjectscale) + const fixed_t minradius = 768 * mapobjectscale; + + if (battleovertime.radius > minradius) battleovertime.radius -= 2*mapobjectscale; else - battleovertime.radius = 0; + battleovertime.radius = minradius; } if (battleovertime.radius > 0) diff --git a/src/k_battle.h b/src/k_battle.h index 221873b04..c56c576d6 100644 --- a/src/k_battle.h +++ b/src/k_battle.h @@ -22,6 +22,7 @@ void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount); void K_CheckBumpers(void); void K_CheckEmeralds(player_t *player); mobj_t *K_SpawnChaosEmerald(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT32 emeraldType); +mobj_t *K_SpawnSphereBox(fixed_t x, fixed_t y, fixed_t z, angle_t angle, SINT8 flip, UINT8 amount); void K_DropEmeraldsFromPlayer(player_t *player, UINT32 emeraldType); UINT8 K_NumEmeralds(player_t *player); void K_RunPaperItemSpawners(void); diff --git a/src/k_bot.c b/src/k_bot.c index 29aa4f177..24f3517a2 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -273,16 +273,94 @@ boolean K_PlayerUsesBotMovement(player_t *player) --------------------------------------------------*/ boolean K_BotCanTakeCut(player_t *player) { - if (!K_ApplyOffroad(player) + if ( +#if 1 + K_TripwirePass(player) == true +#else + K_ApplyOffroad(player) == false +#endif || player->itemtype == KITEM_SNEAKER || player->itemtype == KITEM_ROCKETSNEAKER || player->itemtype == KITEM_INVINCIBILITY - || player->itemtype == KITEM_HYUDORO) + ) + { return true; + } return false; } +/*-------------------------------------------------- + static line_t *K_FindBotController(mobj_t *mo) + + Finds if any bot controller linedefs are tagged to the bot's sector. + + Input Arguments:- + mo - The bot player's mobj. + + Return:- + Linedef of the bot controller. NULL if it doesn't exist. +--------------------------------------------------*/ +static line_t *K_FindBotController(mobj_t *mo) +{ + msecnode_t *node; + ffloor_t *rover; + INT16 lineNum = -1; + mtag_t tag; + + I_Assert(mo != NULL); + I_Assert(!P_MobjWasRemoved(mo)); + + for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) + { + if (!node->m_sector) + { + continue; + } + + tag = Tag_FGet(&node->m_sector->tags); + lineNum = P_FindSpecialLineFromTag(2004, tag, -1); // todo: needs to not use P_FindSpecialLineFromTag + + if (lineNum != -1) + { + break; + } + + for (rover = node->m_sector->ffloors; rover; rover = rover->next) + { + sector_t *rs = NULL; + + if (!(rover->flags & FF_EXISTS)) + { + continue; + } + + if (mo->z > *rover->topheight || mo->z + mo->height < *rover->bottomheight) + { + continue; + } + + rs = §ors[rover->secnum]; + tag = Tag_FGet(&rs->tags); + lineNum = P_FindSpecialLineFromTag(2004, tag, -1); + + if (lineNum != -1) + { + break; + } + } + } + + if (lineNum != -1) + { + return &lines[lineNum]; + } + else + { + return NULL; + } +} + /*-------------------------------------------------- static UINT32 K_BotRubberbandDistance(player_t *player) @@ -346,6 +424,7 @@ fixed_t K_BotRubberband(player_t *player) fixed_t rubberband = FRACUNIT; fixed_t max, min; player_t *firstplace = NULL; + line_t *botController = NULL; UINT8 i; if (player->exiting) @@ -354,6 +433,17 @@ fixed_t K_BotRubberband(player_t *player) return FRACUNIT; } + botController = K_FindBotController(player->mo); + + if (botController != NULL) + { + // No Climb Flag: Disable rubberbanding + if (botController->flags & ML_NOCLIMB) + { + return FRACUNIT; + } + } + for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i] || players[i].spectator) @@ -430,8 +520,8 @@ fixed_t K_BotTopSpeedRubberband(player_t *player) } else { - // Max at +10% for level 9 bots - rubberband = FRACUNIT + ((rubberband - FRACUNIT) / 10); + // Max at +20% for level 9 bots + rubberband = FRACUNIT + ((rubberband - FRACUNIT) / 5); } // Only allow you to go faster than your regular top speed if you're facing the right direction @@ -488,6 +578,14 @@ fixed_t K_BotFrictionRubberband(player_t *player, fixed_t frict) return frict; } + if (player->tiregrease > 0) + { + // This isn't great -- it means rubberbanding will slow down when they hit a spring + // But it's better than the opposite where they accelerate into hyperspace :V + // (would appreciate an actual fix though ... could try being additive instead of multiplicative) + return frict; + } + origFrict = FixedDiv(ORIG_FRICTION, FRACUNIT + (rubberband / 2)); if (frict == ORIG_FRICTION) @@ -567,14 +665,11 @@ static botprediction_t *K_CreateBotPrediction(player_t *player) const INT16 handling = K_GetKartTurnValue(player, KART_FULLTURN); // Reduce prediction based on how fast you can turn const INT16 normal = KART_FULLTURN; // "Standard" handling to compare to - const fixed_t distreduce = K_BotReducePrediction(player); - const fixed_t radreduce = min(distreduce + FRACUNIT/4, FRACUNIT); - const tic_t futuresight = (TICRATE * normal) / max(1, handling); // How far ahead into the future to try and predict - const fixed_t speed = max(P_AproxDistance(player->mo->momx, player->mo->momy), K_GetKartSpeed(player, false) / 4); + const fixed_t speed = P_AproxDistance(player->mo->momx, player->mo->momy); const INT32 startDist = (768 * mapobjectscale) / FRACUNIT; - const INT32 distance = ((FixedMul(speed, distreduce) / FRACUNIT) * futuresight) + startDist; + const INT32 distance = ((speed / FRACUNIT) * futuresight) + startDist; botprediction_t *predict = Z_Calloc(sizeof(botprediction_t), PU_STATIC, NULL); waypoint_t *wp = player->nextwaypoint; @@ -583,6 +678,9 @@ static botprediction_t *K_CreateBotPrediction(player_t *player) fixed_t smallestradius = INT32_MAX; angle_t angletonext = ANGLE_MAX; + // Halves radius when encountering a wall on your way to your destination. + fixed_t radreduce = FRACUNIT; + size_t nwp; size_t i; @@ -595,7 +693,7 @@ static botprediction_t *K_CreateBotPrediction(player_t *player) { predict->x = wp->mobj->x; predict->y = wp->mobj->y; - predict->radius = FixedMul(wp->mobj->radius, radreduce); + predict->radius = wp->mobj->radius; return predict; } @@ -635,12 +733,12 @@ static botprediction_t *K_CreateBotPrediction(player_t *player) for (i = 0; i < wp->numnextwaypoints; i++) { - if (!K_GetWaypointIsEnabled(wp->nextwaypoints[i])) + if (K_GetWaypointIsEnabled(wp->nextwaypoints[i]) == false) { continue; } - if (K_GetWaypointIsShortcut(wp->nextwaypoints[i]) && !K_BotCanTakeCut(player)) + if (K_GetWaypointIsShortcut(wp->nextwaypoints[i]) == true && K_BotCanTakeCut(player) == false) { continue; } @@ -673,6 +771,13 @@ static botprediction_t *K_CreateBotPrediction(player_t *player) disttonext = (INT32)wp->nextwaypointdistances[nwp]; + if (P_TraceBotTraversal(player->mo, wp->nextwaypoints[nwp]->mobj) == false) + { + // If we can't get a direct path to this waypoint, we don't want to check much further... + disttonext *= 2; + radreduce = FRACUNIT/2; + } + if (disttonext > distanceleft) { break; @@ -761,7 +866,7 @@ static UINT8 K_TrySpindash(player_t *player) return 0; } - if (speedDiff < (3 * baseAccel / 4)) + if (speedDiff < (baseAccel / 4)) { if (player->botvars.spindashconfirm < BOTSPINDASHCONFIRM) { @@ -797,70 +902,6 @@ static UINT8 K_TrySpindash(player_t *player) return 0; } -/*-------------------------------------------------- - static INT16 K_FindBotController(mobj_t *mo) - - Finds if any bot controller linedefs are tagged to the bot's sector. - - Input Arguments:- - mo - The bot player's mobj. - - Return:- - Line number of the bot controller. -1 if it doesn't exist. ---------------------------------------------------*/ -static INT16 K_FindBotController(mobj_t *mo) -{ - msecnode_t *node; - ffloor_t *rover; - INT16 lineNum = -1; - mtag_t tag; - - I_Assert(mo != NULL); - I_Assert(!P_MobjWasRemoved(mo)); - - for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) - { - if (!node->m_sector) - { - continue; - } - - tag = Tag_FGet(&node->m_sector->tags); - lineNum = P_FindSpecialLineFromTag(2004, tag, -1); // todo: needs to not use P_FindSpecialLineFromTag - - if (lineNum != -1) - { - return lineNum; - } - - for (rover = node->m_sector->ffloors; rover; rover = rover->next) - { - sector_t *rs = NULL; - - if (!(rover->flags & FF_EXISTS)) - { - continue; - } - - if (mo->z > *rover->topheight || mo->z + mo->height < *rover->bottomheight) - { - continue; - } - - rs = §ors[rover->secnum]; - tag = Tag_FGet(&rs->tags); - lineNum = P_FindSpecialLineFromTag(2004, tag, -1); - - if (lineNum != -1) - { - return lineNum; - } - } - } - - return -1; -} - /*-------------------------------------------------- static void K_DrawPredictionDebug(botprediction_t *predict, player_t *player) @@ -925,6 +966,50 @@ static void K_DrawPredictionDebug(botprediction_t *predict, player_t *player) } } +/*-------------------------------------------------- + static void K_BotTrick(player_t *player, ticcmd_t *cmd, line_t *botController) + + Determines inputs for trick panels. + + Input Arguments:- + player - Player to generate the ticcmd for. + cmd - The player's ticcmd to modify. + botController - Linedef for the bot controller. + + Return:- + None +--------------------------------------------------*/ +static void K_BotTrick(player_t *player, ticcmd_t *cmd, line_t *botController) +{ + // Trick panel state -- do nothing until a controller line is found, in which case do a trick. + if (botController == NULL) + { + return; + } + + if (player->trickpanel == 1) + { + INT32 type = (sides[botController->sidenum[0]].rowoffset / FRACUNIT); + + // Y Offset: Trick type + switch (type) + { + case 1: + cmd->turning = KART_FULLTURN; + break; + case 2: + cmd->turning = -KART_FULLTURN; + break; + case 3: + cmd->buttons |= BT_FORWARD; + break; + case 4: + cmd->buttons |= BT_BACKWARD; + break; + } + } +} + /*-------------------------------------------------- void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) @@ -936,7 +1021,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) boolean trySpindash = true; UINT8 spindash = 0; INT32 turnamt = 0; - INT16 botController = -1; + line_t *botController = NULL; // Can't build a ticcmd if we aren't spawned... if (!player->mo) @@ -959,7 +1044,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) } // Complete override of all ticcmd functionality - if (LUAh_BotTiccmd(player, cmd)) + if (LUAh_BotTiccmd(player, cmd) == true) { return; } @@ -968,30 +1053,7 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) if (player->trickpanel != 0) { - // Trick panel state -- do nothing until a controller line is found, in which case do a trick. - - if (player->trickpanel == 1 && botController != -1) - { - line_t *controllerLine = &lines[botController]; - INT32 type = (sides[controllerLine->sidenum[0]].rowoffset / FRACUNIT); - - // Y Offset: Trick type - switch (type) - { - case 1: - cmd->turning = KART_FULLTURN; - break; - case 2: - cmd->turning = -KART_FULLTURN; - break; - case 3: - cmd->buttons |= BT_FORWARD; - break; - case 4: - cmd->buttons |= BT_BACKWARD; - break; - } - } + K_BotTrick(player, cmd, botController); // Don't do anything else. return; @@ -1000,20 +1062,19 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) if ((player->nextwaypoint != NULL && player->nextwaypoint->mobj != NULL && !P_MobjWasRemoved(player->nextwaypoint->mobj)) - || (botController != -1)) + || (botController != NULL)) { // Handle steering towards waypoints! SINT8 turnsign = 0; angle_t destangle, moveangle, angle; INT16 anglediff; - if (botController != -1) + if (botController != NULL && (botController->flags & ML_EFFECT1)) { const fixed_t dist = (player->mo->radius * 4); - line_t *controllerLine = &lines[botController]; // X Offset: Movement direction - destangle = FixedAngle(sides[controllerLine->sidenum[0]].textureoffset); + destangle = FixedAngle(sides[botController->sidenum[0]].textureoffset); // Overwritten prediction predict = Z_Calloc(sizeof(botprediction_t), PU_STATIC, NULL); @@ -1112,18 +1173,6 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd) // Don't turn at all turnamt = 0; } - else - { - // Make minor adjustments - turnamt /= 4; - } - } - - if (anglediff > 60) - { - // Actually, don't go too fast... - cmd->forwardmove /= 2; - cmd->buttons |= BT_BRAKE; } } } diff --git a/src/k_bot.h b/src/k_bot.h index 94694c2dd..a04d5c174 100644 --- a/src/k_bot.h +++ b/src/k_bot.h @@ -15,6 +15,7 @@ #include "k_waypoint.h" #include "d_player.h" +#include "r_defs.h" // Maximum value of botvars.difficulty #define MAXBOTDIFFICULTY 9 @@ -185,19 +186,22 @@ UINT8 K_EggboxStealth(fixed_t x, fixed_t y); /*-------------------------------------------------- - fixed_t K_BotReducePrediction(player_t *player); + boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t y) - Finds walls nearby the specified player, to create a multiplier - to pull bot predictions back by. + Tells us if a bot will play more careful around + this sector. Checks FOFs in the sector, as well. Input Arguments:- - player - Player to compare. + player - Player to check against. + sec - Sector to check against. + x - Linedef cross X position, for slopes + y - Linedef cross Y position, for slopes Return:- - Multiplier in fixed point scale. + true if avoiding this sector, false otherwise. --------------------------------------------------*/ -fixed_t K_BotReducePrediction(player_t *player); +boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t y); /*-------------------------------------------------- @@ -219,8 +223,8 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player) /*-------------------------------------------------- void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd); - Gives a multiplier for a bot's rubberbanding. Meant to be used for top speed, - acceleration, and handling. + Creates a bot's ticcmd, looking at its surroundings to + try and figure out what it should do. Input Arguments:- player - Player to generate the ticcmd for. diff --git a/src/k_botitem.c b/src/k_botitem.c index 212a84929..4bb83931c 100644 --- a/src/k_botitem.c +++ b/src/k_botitem.c @@ -86,7 +86,7 @@ static boolean K_BotUseItemNearPlayer(player_t *player, ticcmd_t *cmd, fixed_t r } /*-------------------------------------------------- - static boolean K_PlayerNearSpot(player_t *player, fixed_t x, fixed_t y, fixed_t radius) + static player_t *K_PlayerNearSpot(player_t *player, fixed_t x, fixed_t y, fixed_t radius) Looks for players around a specified x/y coordinate. @@ -97,9 +97,9 @@ static boolean K_BotUseItemNearPlayer(player_t *player, ticcmd_t *cmd, fixed_t r radius - The radius to look for players in. Return:- - true if a player was found around the coordinate, otherwise false. + The player we found, NULL if nothing was found. --------------------------------------------------*/ -static boolean K_PlayerNearSpot(player_t *player, fixed_t x, fixed_t y, fixed_t radius) +static player_t *K_PlayerNearSpot(player_t *player, fixed_t x, fixed_t y, fixed_t radius) { UINT8 i; @@ -129,15 +129,15 @@ static boolean K_PlayerNearSpot(player_t *player, fixed_t x, fixed_t y, fixed_t if (dist <= radius) { - return true; + return target; } } - return false; + return NULL; } /*-------------------------------------------------- - static boolean K_PlayerPredictThrow(player_t *player, UINT8 extra) + static player_t *K_PlayerPredictThrow(player_t *player, UINT8 extra) Looks for players around the predicted coordinates of their thrown item. @@ -146,9 +146,9 @@ static boolean K_PlayerNearSpot(player_t *player, fixed_t x, fixed_t y, fixed_t extra - Extra throwing distance, for aim forward on mines. Return:- - true if a player was found around the coordinate, otherwise false. + The player we're trying to throw at, NULL if none was found. --------------------------------------------------*/ -static boolean K_PlayerPredictThrow(player_t *player, UINT8 extra) +static player_t *K_PlayerPredictThrow(player_t *player, UINT8 extra) { const fixed_t dist = (30 + (extra * 10)) * player->mo->scale; const UINT32 airtime = FixedDiv(dist + player->mo->momz, gravity); @@ -159,7 +159,7 @@ static boolean K_PlayerPredictThrow(player_t *player, UINT8 extra) } /*-------------------------------------------------- - static boolean K_PlayerInCone(player_t *player, UINT16 cone, boolean flip) + static player_t *K_PlayerInCone(player_t *player, UINT16 cone, boolean flip) Looks for players in the . @@ -172,7 +172,7 @@ static boolean K_PlayerPredictThrow(player_t *player, UINT8 extra) Return:- true if a player was found in the cone, otherwise false. --------------------------------------------------*/ -static boolean K_PlayerInCone(player_t *player, fixed_t radius, UINT16 cone, boolean flip) +static player_t *K_PlayerInCone(player_t *player, fixed_t radius, UINT16 cone, boolean flip) { UINT8 i; @@ -222,22 +222,96 @@ static boolean K_PlayerInCone(player_t *player, fixed_t radius, UINT16 cone, boo { if (ad >= 180-cone) { - return true; + return target; } } else { if (ad <= cone) { - return true; + return target; } } } } + return NULL; +} + +/*-------------------------------------------------- + static boolean K_RivalBotAggression(player_t *bot, player_t *target) + + Returns if a bot is a rival & wants to be aggressive to a player. + + Input Arguments:- + bot - Bot to check. + target - Who the bot wants to attack. + + Return:- + false if not the rival. false if the target is another bot. Otherwise, true. +--------------------------------------------------*/ +static boolean K_RivalBotAggression(player_t *bot, player_t *target) +{ + if (bot == NULL || target == NULL) + { + // Invalid. + return false; + } + + if (bot->bot == false) + { + // lol + return false; + } + + if (bot->botvars.rival == false) + { + // Not the rival, we aren't self-aware. + return false; + } + + if (target->bot == false) + { + // This bot knows that the real threat is the player. + return true; + } + + // Calling them your friends is misleading, but you'll at least spare them. return false; } +/*-------------------------------------------------- + static void K_ItemConfirmForTarget(player_t *bot, player_t *target, UINT16 amount) + + Handles updating item confirm values for offense items. + + Input Arguments:- + bot - Bot to check. + target - Who the bot wants to attack. + amount - Amount to increase item confirm time by. + + Return:- + None +--------------------------------------------------*/ +static void K_ItemConfirmForTarget(player_t *bot, player_t *target, UINT16 amount) +{ + if (bot == NULL || target == NULL) + { + return; + } + + if (K_RivalBotAggression(bot, target) == true) + { + // Double the rate when you're aggressive. + bot->botvars.itemconfirm += amount << 1; + } + else + { + // Do as normal. + bot->botvars.itemconfirm += amount; + } +} + /*-------------------------------------------------- static boolean K_BotGenericPressItem(player_t *player, ticcmd_t *cmd, SINT8 dir) @@ -316,21 +390,21 @@ static boolean K_BotRevealsGenericTrap(player_t *player, INT16 turnamt, boolean } // Check the predicted throws. - if (K_PlayerPredictThrow(player, 0)) + if (K_PlayerPredictThrow(player, 0) != NULL) { return true; } if (mine) { - if (K_PlayerPredictThrow(player, 1)) + if (K_PlayerPredictThrow(player, 1) != NULL) { return true; } } // Check your behind. - if (K_PlayerInCone(player, player->mo->radius * 16, 10, true)) + if (K_PlayerInCone(player, player->mo->radius * 16, 10, true) != NULL) { return true; } @@ -447,7 +521,6 @@ static void K_BotItemRocketSneaker(player_t *player, ticcmd_t *cmd) } } - /*-------------------------------------------------- static void K_BotItemBanana(player_t *player, ticcmd_t *cmd, INT16 turnamt) @@ -464,9 +537,17 @@ static void K_BotItemRocketSneaker(player_t *player, ticcmd_t *cmd) static void K_BotItemBanana(player_t *player, ticcmd_t *cmd, INT16 turnamt) { SINT8 throwdir = -1; + player_t *target = NULL; player->botvars.itemconfirm++; + target = K_PlayerInCone(player, player->mo->radius * 16, 10, true); + if (target != NULL) + { + K_ItemConfirmForTarget(player, target, player->botvars.difficulty); + throwdir = -1; + } + if (abs(turnamt) >= KART_FULLTURN/2) { player->botvars.itemconfirm += player->botvars.difficulty / 2; @@ -474,19 +555,15 @@ static void K_BotItemBanana(player_t *player, ticcmd_t *cmd, INT16 turnamt) } else { - if (K_PlayerPredictThrow(player, 0)) + target = K_PlayerPredictThrow(player, 0); + + if (target != NULL) { - player->botvars.itemconfirm += player->botvars.difficulty * 2; + K_ItemConfirmForTarget(player, target, player->botvars.difficulty * 2); throwdir = 1; } } - if (K_PlayerInCone(player, player->mo->radius * 16, 10, true)) - { - player->botvars.itemconfirm += player->botvars.difficulty; - throwdir = -1; - } - if (player->botvars.itemconfirm > 2*TICRATE || player->bananadrag >= TICRATE) { K_BotGenericPressItem(player, cmd, throwdir); @@ -509,12 +586,14 @@ static void K_BotItemBanana(player_t *player, ticcmd_t *cmd, INT16 turnamt) static void K_BotItemMine(player_t *player, ticcmd_t *cmd, INT16 turnamt) { SINT8 throwdir = 0; + player_t *target = NULL; player->botvars.itemconfirm++; - if (K_PlayerInCone(player, player->mo->radius * 16, 10, true)) + target = K_PlayerInCone(player, player->mo->radius * 16, 10, true); + if (target != NULL) { - player->botvars.itemconfirm += player->botvars.difficulty; + K_ItemConfirmForTarget(player, target, player->botvars.difficulty); throwdir = -1; } @@ -525,27 +604,63 @@ static void K_BotItemMine(player_t *player, ticcmd_t *cmd, INT16 turnamt) } else { - if (K_PlayerPredictThrow(player, 0)) + target = K_PlayerPredictThrow(player, 0); + if (target != NULL) { - player->botvars.itemconfirm += player->botvars.difficulty * 2; + K_ItemConfirmForTarget(player, target, player->botvars.difficulty * 2); throwdir = 0; } - if (K_PlayerPredictThrow(player, 1)) + target = K_PlayerPredictThrow(player, 1); + if (target != NULL) { - player->botvars.itemconfirm += player->botvars.difficulty * 2; + K_ItemConfirmForTarget(player, target, player->botvars.difficulty * 2); throwdir = 1; } } - - if (player->botvars.itemconfirm > 2*TICRATE || player->bananadrag >= TICRATE) { K_BotGenericPressItem(player, cmd, throwdir); } } +/*-------------------------------------------------- + static void K_BotItemLandmine(player_t *player, ticcmd_t *cmd, INT16 turnamt) + + Item usage for landmine tossing. + + Input Arguments:- + player - Bot to do this for. + cmd - Bot's ticcmd to edit. + turnamt - How hard they currently are turning. + + Return:- + None +--------------------------------------------------*/ +static void K_BotItemLandmine(player_t *player, ticcmd_t *cmd, INT16 turnamt) +{ + player_t *target = NULL; + + player->botvars.itemconfirm++; + + if (abs(turnamt) >= KART_FULLTURN/2) + { + player->botvars.itemconfirm += player->botvars.difficulty / 2; + } + + target = K_PlayerInCone(player, player->mo->radius * 16, 10, true); + if (target != NULL) + { + K_ItemConfirmForTarget(player, target, player->botvars.difficulty); + } + + if (player->botvars.itemconfirm > 2*TICRATE) + { + K_BotGenericPressItem(player, cmd, -1); + } +} + /*-------------------------------------------------- static void K_BotItemEggman(player_t *player, ticcmd_t *cmd) @@ -562,18 +677,21 @@ static void K_BotItemEggman(player_t *player, ticcmd_t *cmd) { const UINT8 stealth = K_EggboxStealth(player->mo->x, player->mo->y); SINT8 throwdir = -1; + player_t *target = NULL; player->botvars.itemconfirm++; - if (K_PlayerPredictThrow(player, 0)) + target = K_PlayerPredictThrow(player, 0); + if (target != NULL) { - player->botvars.itemconfirm += player->botvars.difficulty / 2; + K_ItemConfirmForTarget(player, target, player->botvars.difficulty / 2); throwdir = 1; } - if (K_PlayerInCone(player, player->mo->radius * 16, 10, true)) + target = K_PlayerInCone(player, player->mo->radius * 16, 10, true); + if (target != NULL) { - player->botvars.itemconfirm += player->botvars.difficulty; + K_ItemConfirmForTarget(player, target, player->botvars.difficulty); throwdir = -1; } @@ -603,6 +721,7 @@ static void K_BotItemEggman(player_t *player, ticcmd_t *cmd) static boolean K_BotRevealsEggbox(player_t *player) { const UINT8 stealth = K_EggboxStealth(player->mo->x, player->mo->y); + player_t *target = NULL; // This is a stealthy spot for an eggbox, lets reveal it! if (stealth > 1) @@ -611,13 +730,15 @@ static boolean K_BotRevealsEggbox(player_t *player) } // Check the predicted throws. - if (K_PlayerPredictThrow(player, 0)) + target = K_PlayerPredictThrow(player, 0); + if (target != NULL) { return true; } // Check your behind. - if (K_PlayerInCone(player, player->mo->radius * 16, 10, true)) + target = K_PlayerInCone(player, player->mo->radius * 16, 10, true); + if (target != NULL) { return true; } @@ -644,7 +765,7 @@ static void K_BotItemEggmanShield(player_t *player, ticcmd_t *cmd) return; } - if (K_BotRevealsEggbox(player) || (player->botvars.itemconfirm++ > 20*TICRATE)) + if (K_BotRevealsEggbox(player) == true || (player->botvars.itemconfirm++ > 20*TICRATE)) { K_BotGenericPressItem(player, cmd, 0); } @@ -666,8 +787,9 @@ static void K_BotItemEggmanExplosion(player_t *player, ticcmd_t *cmd) { if (player->position == 1) { + // Hey, we aren't gonna find anyone up here... + // why don't we slow down a bit? :) cmd->forwardmove /= 2; - cmd->buttons |= BT_BRAKE; } K_BotUseItemNearPlayer(player, cmd, 128*player->mo->scale); @@ -690,23 +812,32 @@ static void K_BotItemOrbinaut(player_t *player, ticcmd_t *cmd) const fixed_t topspeed = K_GetKartSpeed(player, false); fixed_t radius = (player->mo->radius * 32); SINT8 throwdir = -1; + UINT8 snipeMul = 2; + player_t *target = NULL; if (player->speed > topspeed) { radius = FixedMul(radius, FixedDiv(player->speed, topspeed)); + snipeMul = 3; // Confirm faster when you'll throw it with a bunch of extra speed!! } player->botvars.itemconfirm++; - if (K_PlayerInCone(player, radius, 10, false)) + target = K_PlayerInCone(player, radius, 10, false); + if (target != NULL) { - player->botvars.itemconfirm += player->botvars.difficulty * 2; + K_ItemConfirmForTarget(player, target, player->botvars.difficulty * snipeMul); throwdir = 1; } else if (K_PlayerInCone(player, radius, 10, true)) { - player->botvars.itemconfirm += player->botvars.difficulty; - throwdir = -1; + target = K_PlayerInCone(player, radius, 10, true); + + if (target != NULL) + { + K_ItemConfirmForTarget(player, target, player->botvars.difficulty); + throwdir = -1; + } } if (player->botvars.itemconfirm > 5*TICRATE) @@ -732,24 +863,54 @@ static void K_BotItemJawz(player_t *player, ticcmd_t *cmd) const fixed_t topspeed = K_GetKartSpeed(player, false); fixed_t radius = (player->mo->radius * 32); SINT8 throwdir = 1; + UINT8 snipeMul = 2; + INT32 lastTarg = player->lastjawztarget; + player_t *target = NULL; if (player->speed > topspeed) { radius = FixedMul(radius, FixedDiv(player->speed, topspeed)); + snipeMul = 3; // Confirm faster when you'll throw it with a bunch of extra speed!! } player->botvars.itemconfirm++; - if (K_PlayerInCone(player, radius, 10, true)) + target = K_PlayerInCone(player, radius, 10, true); + if (target != NULL) { - player->botvars.itemconfirm += player->botvars.difficulty; + K_ItemConfirmForTarget(player, target, player->botvars.difficulty); throwdir = -1; } - if (player->lastjawztarget != -1) + if (lastTarg != -1 + && playeringame[lastTarg] == true + && players[lastTarg].spectator == false + && players[lastTarg].mo != NULL + && P_MobjWasRemoved(players[lastTarg].mo) == false) { - player->botvars.itemconfirm += player->botvars.difficulty * 2; - throwdir = 1; + mobj_t *targMo = players[lastTarg].mo; + mobj_t *mobj = NULL, *next = NULL; + boolean targettedAlready = false; + + target = &players[lastTarg]; + + // Make sure no other Jawz are targetting this player. + for (mobj = kitemcap; mobj; mobj = next) + { + next = mobj->itnext; + + if (mobj->type == MT_JAWZ && mobj->target == targMo) + { + targettedAlready = true; + break; + } + } + + if (targettedAlready == false) + { + K_ItemConfirmForTarget(player, target, player->botvars.difficulty * snipeMul); + throwdir = 1; + } } if (player->botvars.itemconfirm > 5*TICRATE) @@ -772,7 +933,7 @@ static void K_BotItemJawz(player_t *player, ticcmd_t *cmd) --------------------------------------------------*/ static void K_BotItemThunder(player_t *player, ticcmd_t *cmd) { - if (!K_BotUseItemNearPlayer(player, cmd, 192*player->mo->scale)) + if (K_BotUseItemNearPlayer(player, cmd, 192*player->mo->scale) == false) { if (player->botvars.itemconfirm > 10*TICRATE) { @@ -1036,7 +1197,6 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt) K_BotItemSneaker(player, cmd); break; case KITEM_BANANA: - case KITEM_LANDMINE: if (!(player->pflags & PF_ITEMOUT)) { K_BotItemGenericTrapShield(player, cmd, turnamt, false); @@ -1081,6 +1241,9 @@ void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt) K_BotItemMine(player, cmd, turnamt); } break; + case KITEM_LANDMINE: + K_BotItemLandmine(player, cmd, turnamt); + break; case KITEM_THUNDERSHIELD: K_BotItemThunder(player, cmd); break; diff --git a/src/k_botsearch.c b/src/k_botsearch.c index 55533d02a..846521e6f 100644 --- a/src/k_botsearch.c +++ b/src/k_botsearch.c @@ -122,7 +122,7 @@ UINT8 K_EggboxStealth(fixed_t x, fixed_t y) } } - return (globalsmuggle.randomitems * globalsmuggle.eggboxes); + return (globalsmuggle.randomitems * (globalsmuggle.eggboxes + 1)); } /*-------------------------------------------------- @@ -162,21 +162,11 @@ static boolean K_BotHatesThisSectorsSpecial(player_t *player, sector_t *sec) } /*-------------------------------------------------- - static boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t y) + boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t y) - Tells us if a bot will play more careful around - this sector. Checks FOFs in the sector, as well. - - Input Arguments:- - player - Player to check against. - sec - Sector to check against. - x - Linedef cross X position, for slopes - y - Linedef cross Y position, for slopes - - Return:- - true if avoiding this sector, false otherwise. + See header file for description. --------------------------------------------------*/ -static boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t y) +boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t y) { const boolean flip = (player->mo->eflags & MFE_VERTICALFLIP); INT32 specialflag = 0; @@ -257,171 +247,6 @@ static boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, return K_BotHatesThisSectorsSpecial(player, bestsector); } -/*-------------------------------------------------- - static boolean K_FindBlockingWalls(line_t *line) - - Blockmap search function. - Reels the bot prediction back in based on solid walls - or other obstacles surrounding the bot. - - Input Arguments:- - line - Linedef passed in from iteration. - - Return:- - true continues searching, false ends the search early. ---------------------------------------------------*/ -static boolean K_FindBlockingWalls(line_t *line) -{ - // Condensed version of PIT_CheckLine - const fixed_t maxstepmove = FixedMul(MAXSTEPMOVE, mapobjectscale); - fixed_t maxstep = maxstepmove; - fixed_t linedist = INT32_MAX; - INT32 lineside = 0; - vertex_t pos; - - if (!globalsmuggle.botmo || P_MobjWasRemoved(globalsmuggle.botmo) || !globalsmuggle.botmo->player) - { - return false; - } - - if (line->polyobj && !(line->polyobj->flags & POF_SOLID)) - { - return true; - } - - if (tmbbox[BOXRIGHT] <= line->bbox[BOXLEFT] || tmbbox[BOXLEFT] >= line->bbox[BOXRIGHT] - || tmbbox[BOXTOP] <= line->bbox[BOXBOTTOM] || tmbbox[BOXBOTTOM] >= line->bbox[BOXTOP]) - { - return true; - } - - if (P_BoxOnLineSide(tmbbox, line) != -1) - { - return true; - } - - lineside = P_PointOnLineSide(globalsmuggle.botmo->x, globalsmuggle.botmo->y, line); - - // one sided line - if (!line->backsector) - { - if (lineside) - { - // don't hit the back side - return true; - } - - goto blocked; - } - - if ((line->flags & ML_IMPASSABLE) || (line->flags & ML_BLOCKPLAYERS)) - { - goto blocked; - } - - // set openrange, opentop, openbottom - P_LineOpening(line, globalsmuggle.botmo); - - if (globalsmuggle.botmo->player->waterskip) - maxstep += maxstepmove; - - if (P_MobjTouchingSectorSpecial(globalsmuggle.botmo, 1, 13, false)) - maxstep <<= 1; - else if (P_MobjTouchingSectorSpecial(globalsmuggle.botmo, 1, 12, false)) - maxstep = 0; - - if ((openrange < globalsmuggle.botmo->height) // doesn't fit - || (opentop - globalsmuggle.botmo->z < globalsmuggle.botmo->height) // mobj is too high - || (openbottom - globalsmuggle.botmo->z > maxstep)) // too big a step up - { - goto blocked; - } - - // Treat damage sectors like walls - P_ClosestPointOnLine(globalsmuggle.botmo->x, globalsmuggle.botmo->y, line, &pos); - - if (lineside) - { - if (K_BotHatesThisSector(globalsmuggle.botmo->player, line->frontsector, pos.x, pos.y)) - goto blocked; - } - else - { - if (K_BotHatesThisSector(globalsmuggle.botmo->player, line->backsector, pos.x, pos.y)) - goto blocked; - } - - // We weren't blocked! - return true; - -blocked: - linedist = K_DistanceOfLineFromPoint(line->v1->x, line->v1->y, line->v2->x, line->v2->y, globalsmuggle.botmo->x, globalsmuggle.botmo->y); - linedist -= (globalsmuggle.botmo->radius * 8); // Maintain a reasonable distance away from it - - if (linedist > globalsmuggle.distancetocheck) - { - return true; - } - - if (linedist <= 0) - { - globalsmuggle.closestlinedist = 0; - return false; - } - - if (linedist < globalsmuggle.closestlinedist) - { - globalsmuggle.closestlinedist = linedist; - } - - return true; -} - -/*-------------------------------------------------- - fixed_t K_BotReducePrediction(player_t *player) - - See header file for description. ---------------------------------------------------*/ -fixed_t K_BotReducePrediction(player_t *player) -{ - INT32 xl, xh, yl, yh, bx, by; - - globalsmuggle.botmo = player->mo; - globalsmuggle.distancetocheck = (player->mo->radius * 32); - globalsmuggle.closestlinedist = INT32_MAX; - - tmx = player->mo->x; - tmy = player->mo->y; - - xl = (unsigned)(tmx - globalsmuggle.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT; - xh = (unsigned)(tmx + globalsmuggle.distancetocheck - bmaporgx)>>MAPBLOCKSHIFT; - yl = (unsigned)(tmy - globalsmuggle.distancetocheck - bmaporgy)>>MAPBLOCKSHIFT; - yh = (unsigned)(tmy + globalsmuggle.distancetocheck - bmaporgy)>>MAPBLOCKSHIFT; - - BMBOUNDFIX(xl, xh, yl, yh); - - tmbbox[BOXTOP] = tmy + globalsmuggle.distancetocheck; - tmbbox[BOXBOTTOM] = tmy - globalsmuggle.distancetocheck; - tmbbox[BOXRIGHT] = tmx + globalsmuggle.distancetocheck; - tmbbox[BOXLEFT] = tmx - globalsmuggle.distancetocheck; - - // Check for lines that the bot might collide with - for (bx = xl; bx <= xh; bx++) - { - for (by = yl; by <= yh; by++) - { - P_BlockLinesIterator(bx, by, K_FindBlockingWalls); - } - } - - if (globalsmuggle.closestlinedist == INT32_MAX) - { - return FRACUNIT; - } - - return (FRACUNIT/2) + (FixedDiv(globalsmuggle.closestlinedist, globalsmuggle.distancetocheck) / 2); -} - /*-------------------------------------------------- static void K_AddAttackObject(mobj_t *thing, UINT8 side, UINT8 weight) diff --git a/src/k_brightmap.c b/src/k_brightmap.c new file mode 100644 index 000000000..f481938f2 --- /dev/null +++ b/src/k_brightmap.c @@ -0,0 +1,256 @@ +// DR. ROBOTNIK'S RING RACERS +//----------------------------------------------------------------------------- +// Copyright (C) 2021 by Sally "TehRealSalt" Cochenour +// Copyright (C) 2021 by Kart Krew +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file k_brightmap.c +/// \brief Brightmap texture loading. + +#include "k_brightmap.h" + +#include "doomdata.h" +#include "doomdef.h" +#include "doomtype.h" +#include "fastcmp.h" +#include "r_textures.h" +#include "w_wad.h" +#include "z_zone.h" + +static brightmapStorage_t *brightmapStorage = NULL; +static size_t maxBrightmapStorage = 0; + +/*-------------------------------------------------- + static brightmapStorage_t *K_NewBrightmap(void) + + Increases the size of maxBrightmapStorage by 1. + + Input Arguments:- + None + + Return:- + The new brightmap storage struct. +--------------------------------------------------*/ +static brightmapStorage_t *K_NewBrightmap(void) +{ + maxBrightmapStorage++; + brightmapStorage = (brightmapStorage_t *)Z_Realloc(brightmapStorage, sizeof(brightmapStorage_t) * (maxBrightmapStorage + 1), PU_STATIC, NULL); + return &brightmapStorage[ maxBrightmapStorage - 1 ]; +} + +/*-------------------------------------------------- + static brightmapStorage_t *K_GetBrightmapStorageByIndex(size_t checkIndex) + + See header file for description. +--------------------------------------------------*/ +static brightmapStorage_t *K_GetBrightmapStorageByIndex(size_t checkIndex) +{ + if (checkIndex >= maxBrightmapStorage) + { + return NULL; + } + + return &brightmapStorage[checkIndex]; +} + +/*-------------------------------------------------- + static brightmapStorage_t *K_GetBrightmapStorageByTextureName(const char *checkName) + + See header file for description. +--------------------------------------------------*/ +static brightmapStorage_t *K_GetBrightmapStorageByTextureName(const char *checkName) +{ + size_t i; + + if (maxBrightmapStorage == 0) + { + return NULL; + } + + for (i = 0; i < maxBrightmapStorage; i++) + { + brightmapStorage_t *bms = &brightmapStorage[i]; + + if (stricmp(checkName, bms->textureName) == 0) + { + // Name matches. + return bms; + } + } + + return NULL; +} + +/*-------------------------------------------------- + static boolean K_BRIGHTLumpParser(UINT8 *data, size_t size) + + Parses inputted lump data as a BRIGHT lump. + + Input Arguments:- + data - Pointer to lump data. + size - The length of the lump data. + + Return:- + false if any errors occured, otherwise true. +--------------------------------------------------*/ +static boolean K_BRIGHTLumpParser(UINT8 *data, size_t size) +{ + char *tkn = M_GetToken((char *)data); + size_t pos = 0; + + while (tkn && (pos = M_GetTokenPos()) < size) + { + boolean valid = true; + + if (stricmp(tkn, "texture") == 0) + { + Z_Free(tkn); + tkn = M_GetToken(NULL); + pos = M_GetTokenPos(); + + if (tkn && pos < size) + { + brightmapStorage_t *bms = K_GetBrightmapStorageByTextureName(tkn); + + if (bms == NULL) + { + bms = K_NewBrightmap(); + strncpy(bms->textureName, tkn, 9); + } + + Z_Free(tkn); + tkn = M_GetToken(NULL); + pos = M_GetTokenPos(); + + if (tkn && pos < size) + { + strncpy(bms->brightmapName, tkn, 9); + } + else + { + CONS_Alert(CONS_ERROR, "No brightmap for brightmap definition.\n"); + valid = false; + } + } + else + { + CONS_Alert(CONS_ERROR, "No texture for brightmap definition.\n"); + valid = false; + } + } + // todo: SPRITE brightmaps?! + else + { + CONS_Alert(CONS_ERROR, "Unknown keyword '%s' found in BRIGHT lump.\n", tkn); + valid = false; + } + + Z_Free(tkn); + + if (valid == false) + { + return false; + } + + tkn = M_GetToken(NULL); + } + + Z_Free(tkn); + return true; +} + +/*-------------------------------------------------- + void K_InitBrightmaps(void) + + See header file for description. +--------------------------------------------------*/ +void K_InitBrightmaps(void) +{ + INT32 wadNum; + size_t i; + + I_Assert(brightmapStorage == NULL); + maxBrightmapStorage = 0; + + for (wadNum = 0; wadNum < numwadfiles; wadNum++) + { + UINT16 lumpNum; + + // Find BRIGHT lump in the WAD + lumpNum = W_CheckNumForNamePwad("BRIGHT", wadNum, 0); + + while (lumpNum != INT16_MAX) + { + UINT8 *data; + data = (UINT8 *)W_CacheLumpNumPwad(wadNum, lumpNum, PU_STATIC); + + // If that didn't exist, we have nothing to do here. + if (data == NULL) + { + lumpNum = W_CheckNumForNamePwad("BRIGHT", (UINT16)wadNum, lumpNum + 1); + continue; + } + else + { + lumpinfo_t *lump_p = &wadfiles[wadNum]->lumpinfo[lumpNum]; + size_t size = W_LumpLengthPwad(wadNum, lumpNum); + + size_t nameLength = strlen(wadfiles[wadNum]->filename) + 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name + char *name = malloc(nameLength + 1); + + sprintf(name, "%s|%s", wadfiles[wadNum]->filename, lump_p->fullname); + name[nameLength] = '\0'; + + size = W_LumpLengthPwad(wadNum, lumpNum); + + CONS_Printf(M_GetText("Loading BRIGHT from %s\n"), name); + K_BRIGHTLumpParser(data, size); + + free(name); + } + + lumpNum = W_CheckNumForNamePwad("BRIGHT", (UINT16)wadNum, lumpNum + 1); + } + } + + if (maxBrightmapStorage == 0) + { + // No brightmaps were defined. + return; + } + + for (i = 0; i < maxBrightmapStorage; i++) + { + brightmapStorage_t *bms = K_GetBrightmapStorageByIndex(i); + INT32 texNum, bmNum; + + if (bms == NULL) + { + // Shouldn't happen. + break; + } + + texNum = R_CheckTextureNumForName(bms->textureName); + if (texNum != -1) + { + bmNum = R_CheckTextureNumForName(bms->brightmapName); + if (bmNum == -1) + { + texturebrightmaps[texNum] = 0; + } + else + { + texturebrightmaps[texNum] = bmNum; + } + } + } + + R_ClearTextureNumCache(false); + + // Clear brightmapStorage now that we're done with it. + Z_Free(brightmapStorage); + brightmapStorage = NULL; +} diff --git a/src/k_brightmap.h b/src/k_brightmap.h new file mode 100644 index 000000000..8d33ae5cb --- /dev/null +++ b/src/k_brightmap.h @@ -0,0 +1,38 @@ +// DR. ROBOTNIK'S RING RACERS +//----------------------------------------------------------------------------- +// Copyright (C) 2021 by Sally "TehRealSalt" Cochenour +// Copyright (C) 2021 by Kart Krew +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file k_brightmap.h +/// \brief Brightmap texture loading. + +#ifndef __K_BRIGHTMAP_H__ +#define __K_BRIGHTMAP_H__ + +#include "doomdata.h" +#include "doomdef.h" +#include "doomtype.h" + +typedef struct brightmapStorage_s +{ + // Brightmap storage struct. + // Stores data for brightmap definitions, + // before putting them into texturebrightmaps. + + char textureName[9]; // The texture's name. + char brightmapName[9]; // The brightmap's name. +} brightmapStorage_t; + +/*-------------------------------------------------- + void K_InitBrightmaps(void); + + Finds all BRIGHT lumps and processes them. +--------------------------------------------------*/ + +void K_InitBrightmaps(void); + +#endif // __K_BRIGHTMAP_H__ diff --git a/src/k_color.c b/src/k_color.c index 6cfe4d5a8..0821c4437 100644 --- a/src/k_color.c +++ b/src/k_color.c @@ -90,6 +90,59 @@ void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor) } } +/*-------------------------------------------------- + UINT8 K_HitlagColorValue(RGBA_t color) + + See header file for description. +--------------------------------------------------*/ +UINT8 K_HitlagColorValue(RGBA_t color) +{ + // Outputs a raw brightness value (makes OGL support easier) + INT32 output = K_ColorRelativeLuminance(color.s.red, color.s.green, color.s.blue); + + // Invert the color + output = 255 - output; + + // Increase the contrast + output = ((output-128) * 2) + 128; + + // Make sure to cap it. + if (output > 255) + { + output = 255; + } + else if (output < 0) + { + output = 0; + } + + return output; +} + +/*-------------------------------------------------- + void K_HitlagColormap(UINT8 *dest_colormap) + + See header file for description. +--------------------------------------------------*/ +void K_HitlagColormap(UINT8 *dest_colormap) +{ + RGBA_t color; + UINT8 v, offset; + INT32 i; + + // for every colour in the palette, invert, greyscale, and increase the contrast. + for (i = 0; i < NUM_PALETTE_ENTRIES; i++) + { + color = V_GetColor(i); + v = K_HitlagColorValue(color); + + // Convert raw brightness value to an offset from the greyscale palette line + offset = (255 - v) / 8; + + dest_colormap[i] = offset; // Starts from 0, add it if greyscale moves. + } +} + /*-------------------------------------------------- void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color) @@ -100,13 +153,18 @@ void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color) INT32 i; INT32 starttranscolor; - // Handle a couple of simple special cases - if (skinnum == TC_BOSS + if (skinnum == TC_HITLAG) + { + K_HitlagColormap(dest_colormap); + return; + } + else if (skinnum == TC_BOSS || skinnum == TC_ALLWHITE || skinnum == TC_METALSONIC || skinnum == TC_BLINK || color == SKINCOLOR_NONE) { + // Handle a couple of simple special cases for (i = 0; i < NUM_PALETTE_ENTRIES; i++) { if (skinnum == TC_ALLWHITE) diff --git a/src/k_color.h b/src/k_color.h index e90ab0fc4..6e6778d75 100644 --- a/src/k_color.h +++ b/src/k_color.h @@ -66,6 +66,35 @@ UINT16 K_RainbowColor(tic_t time); void K_RainbowColormap(UINT8 *dest_colormap, UINT8 skincolor); +/*-------------------------------------------------- + UINT8 K_HitlagColorValue(RGBA_t color); + + Gets the new replacement brightness value for the hitlag effect. + + Input Arguments:- + color - Input color we intend to replace. + + Return:- + 0 to 255 brightness value. +--------------------------------------------------*/ + +UINT8 K_HitlagColorValue(RGBA_t color); + +/*-------------------------------------------------- + void K_HitlagColormap(UINT8 *dest_colormap); + + Generates a inverted hi-contrast greyscale colormap, + for the hitlag effect. + + Input Arguments:- + dest_colormap - Colormap to populate. + + Return:- + None +--------------------------------------------------*/ + +void K_HitlagColormap(UINT8 *dest_colormap); + /*-------------------------------------------------- void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color); diff --git a/src/k_hud.c b/src/k_hud.c index 1b7894da9..7f54abd49 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -761,9 +761,14 @@ void K_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dupx, INT32 du if (lt_exitticker < length) { - INT32 offset = screenwidth - ((lt_exitticker * screenwidth) / length); boolean slidefromright = false; + const INT32 offsetAmount = (screenwidth * FRACUNIT) / length; + fixed_t offset = (screenwidth * FRACUNIT) - (lt_exitticker * offsetAmount); + + offset += FixedMul(offsetAmount, renderdeltatics); + offset /= FRACUNIT; + if (r_splitscreen > 1) { if (stplyr == &players[displayplayers[1]] || stplyr == &players[displayplayers[3]]) @@ -796,7 +801,7 @@ void K_ObjectTracking(trackingResult_t *result, vector3_t *point, UINT8 cameraNu player_t *player; fixed_t viewpointX, viewpointY, viewpointZ; - angle_t viewpointAngle, viewpointAiming; + angle_t viewpointAngle, viewpointAiming, viewpointRoll; INT32 screenWidth, screenHeight; fixed_t screenHalfW, screenHalfH; @@ -824,12 +829,13 @@ void K_ObjectTracking(trackingResult_t *result, vector3_t *point, UINT8 cameraNu cam = &camera[cameraNum]; player = &players[displayplayers[cameraNum]]; - if (cam == NULL || player == NULL) + if (cam == NULL || player == NULL || player->mo == NULL || P_MobjWasRemoved(player->mo) == true) { // Shouldn't be possible? return; } + // TODO: needs da interp if (cam->chase == true && !player->spectator) { // Use the camera's properties. @@ -838,26 +844,45 @@ void K_ObjectTracking(trackingResult_t *result, vector3_t *point, UINT8 cameraNu viewpointZ = cam->z - point->z; viewpointAngle = (INT32)cam->angle; viewpointAiming = (INT32)cam->aiming; + viewpointRoll = (INT32)player->viewrollangle; + + if (cv_frameinterpolation.value == 1) + { + viewpointX = cam->old_x + FixedMul(rendertimefrac, cam->x - cam->old_x); + viewpointY = cam->old_y + FixedMul(rendertimefrac, cam->y - cam->old_y); + viewpointZ = (cam->old_z + FixedMul(rendertimefrac, cam->z - cam->old_z)) - point->z; + + viewpointAngle = (INT32)(cam->old_angle + FixedMul(rendertimefrac, cam->angle - cam->old_angle)); + viewpointAiming = (INT32)(cam->old_aiming + FixedMul(rendertimefrac, cam->aiming - cam->old_aiming)); + viewpointRoll = (INT32)(player->old_viewrollangle + FixedMul(rendertimefrac, player->viewrollangle - player->old_viewrollangle)); + } } else { // Use player properties. - - if (player->mo == NULL || P_MobjWasRemoved(player->mo) == true) - { - // This shouldn't happen. - return; - } - viewpointX = player->mo->x; viewpointY = player->mo->y; viewpointZ = player->viewz - point->z; viewpointAngle = (INT32)player->mo->angle; viewpointAiming = (INT32)player->aiming; + viewpointRoll = (INT32)player->viewrollangle; + + if (cv_frameinterpolation.value == 1) + { + viewpointX = player->mo->old_x + FixedMul(rendertimefrac, player->mo->x - player->mo->old_x); + viewpointY = player->mo->old_y + FixedMul(rendertimefrac, player->mo->y - player->mo->old_y); + viewpointZ = (player->mo->old_z + FixedMul(rendertimefrac, player->viewz - player->mo->old_z)) - point->z; //player->old_viewz + + viewpointAngle = (INT32)(player->mo->old_angle + FixedMul(rendertimefrac, player->mo->angle - player->mo->old_angle)); + //viewpointAiming = (INT32)(player->mo->old_aiming + FixedMul(rendertimefrac, player->mo->aiming - player->mo->old_aiming)); + viewpointRoll = (INT32)(player->old_viewrollangle + FixedMul(rendertimefrac, player->viewrollangle - player->old_viewrollangle)); + } } viewpointAngle += (INT32)angleOffset; + (void)viewpointRoll; // will be used later... + // Calculate screen size adjustments. // TODO: Anyone want to make this support non-green resolutions somehow? :V screenWidth = BASEVIDWIDTH; @@ -2460,7 +2485,8 @@ static void K_drawKartBumpersOrKarma(void) else V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumpersticker, colormap); - V_DrawKartString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", stplyr->bumpers, maxbumper)); + // TODO BETTER HUD + V_DrawKartString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d %d", stplyr->bumpers, maxbumper, stplyr->overtimekarma / TICRATE)); } } } @@ -2584,6 +2610,7 @@ static void K_drawKartPlayerCheck(void) UINT8 *colormap = NULL; UINT8 pnum = 0; vector3_t v; + vector3_t pPos; trackingResult_t result; if (!playeringame[i] || checkplayer->spectator) @@ -2608,7 +2635,22 @@ static void K_drawKartPlayerCheck(void) v.y = checkplayer->mo->y; v.z = checkplayer->mo->z; - distance = R_PointToDist2(stplyr->mo->x, stplyr->mo->y, v.x, v.y); + pPos.x = stplyr->mo->x; + pPos.y = stplyr->mo->y; + pPos.z = stplyr->mo->z; + + if (cv_frameinterpolation.value == 1) + { + v.x = checkplayer->mo->old_x + FixedMul(rendertimefrac, checkplayer->mo->x - checkplayer->mo->old_x); + v.y = checkplayer->mo->old_y + FixedMul(rendertimefrac, checkplayer->mo->y - checkplayer->mo->old_y); + v.z = checkplayer->mo->old_z + FixedMul(rendertimefrac, checkplayer->mo->z - checkplayer->mo->old_z); + + pPos.x = stplyr->mo->old_x + FixedMul(rendertimefrac, stplyr->mo->x - stplyr->mo->old_x); + pPos.y = stplyr->mo->old_y + FixedMul(rendertimefrac, stplyr->mo->y - stplyr->mo->old_y); + pPos.z = stplyr->mo->old_z + FixedMul(rendertimefrac, stplyr->mo->z - stplyr->mo->old_z); + } + + distance = R_PointToDist2(pPos.x, pPos.y, v.x, v.y); if (distance > maxdistance) { @@ -2795,12 +2837,26 @@ static void K_drawKartNameTags(void) c.x = thiscam->x; c.y = thiscam->y; c.z = thiscam->z; + + if (cv_frameinterpolation.value == 1) + { + c.x = thiscam->old_x + FixedMul(rendertimefrac, thiscam->x - thiscam->old_x); + c.y = thiscam->old_y + FixedMul(rendertimefrac, thiscam->y - thiscam->old_y); + c.z = thiscam->old_z + FixedMul(rendertimefrac, thiscam->z - thiscam->old_z); + } } else { c.x = stplyr->mo->x; c.y = stplyr->mo->y; c.z = stplyr->mo->z; + + if (cv_frameinterpolation.value == 1) + { + c.x = stplyr->mo->old_x + FixedMul(rendertimefrac, stplyr->mo->x - stplyr->mo->old_x); + c.y = stplyr->mo->old_y + FixedMul(rendertimefrac, stplyr->mo->y - stplyr->mo->old_y); + c.z = stplyr->mo->old_z + FixedMul(rendertimefrac, stplyr->mo->z - stplyr->mo->old_z); + } } for (i = 0; i < MAXPLAYERS; i++) @@ -2843,6 +2899,13 @@ static void K_drawKartNameTags(void) v.y = ntplayer->mo->y; v.z = ntplayer->mo->z; + if (cv_frameinterpolation.value == 1) + { + v.x = ntplayer->mo->old_x + FixedMul(rendertimefrac, ntplayer->mo->x - ntplayer->mo->old_x); + v.y = ntplayer->mo->old_y + FixedMul(rendertimefrac, ntplayer->mo->y - ntplayer->mo->old_y); + v.z = ntplayer->mo->old_z + FixedMul(rendertimefrac, ntplayer->mo->z - ntplayer->mo->old_z); + } + if (!(ntplayer->mo->eflags & MFE_VERTICALFLIP)) { v.z += ntplayer->mo->height; @@ -2898,7 +2961,16 @@ static void K_drawKartNameTags(void) v.x = ntplayer->mo->x; v.y = ntplayer->mo->y; - v.z = ntplayer->mo->z + (ntplayer->mo->height / 2); + v.z = ntplayer->mo->z; + + if (cv_frameinterpolation.value == 1) + { + v.x = ntplayer->mo->old_x + FixedMul(rendertimefrac, ntplayer->mo->x - ntplayer->mo->old_x); + v.y = ntplayer->mo->old_y + FixedMul(rendertimefrac, ntplayer->mo->y - ntplayer->mo->old_y); + v.z = ntplayer->mo->old_z + FixedMul(rendertimefrac, ntplayer->mo->z - ntplayer->mo->old_z); + } + + v.z += (ntplayer->mo->height / 2); if (stplyr->mo->eflags & MFE_VERTICALFLIP) { @@ -3040,6 +3112,7 @@ static void K_drawKartMinimap(void) SINT8 numlocalplayers = 0; INT32 hyu = hyudorotime; mobj_t *mobj, *next; // for SPB drawing (or any other item(s) we may wanna draw, I dunno!) + fixed_t interpx, interpy; // Draw the HUD only when playing in a level. // hu_stuff needs this, unlike st_stuff. @@ -3134,7 +3207,17 @@ static void K_drawKartMinimap(void) } else colormap = NULL; - K_drawKartMinimapIcon(g->mo->x, g->mo->y, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic); + + interpx = g->mo->x; + interpy = g->mo->y; + + if (cv_frameinterpolation.value == 1) + { + interpx = g->mo->old_x + FixedMul(rendertimefrac, g->mo->x - g->mo->old_x); + interpy = g->mo->old_y + FixedMul(rendertimefrac, g->mo->y - g->mo->old_y); + } + + K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic); g = g->next; } @@ -3190,11 +3273,22 @@ static void K_drawKartMinimap(void) else colormap = NULL; - K_drawKartMinimapIcon(players[i].mo->x, players[i].mo->y, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic); + interpx = players[i].mo->x; + interpy = players[i].mo->y; + + if (cv_frameinterpolation.value == 1) + { + interpx = players[i].mo->old_x + FixedMul(rendertimefrac, players[i].mo->x - players[i].mo->old_x); + interpy = players[i].mo->old_y + FixedMul(rendertimefrac, players[i].mo->y - players[i].mo->old_y); + } + + K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic); // Target reticule if ((gametype == GT_RACE && players[i].position == spbplace) - || (gametype == GT_BATTLE && K_IsPlayerWanted(&players[i]))) - K_drawKartMinimapIcon(players[i].mo->x, players[i].mo->y, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic); + || (gametype == GT_BATTLE && K_IsPlayerWanted(&players[i]))) + { + K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic); + } } } @@ -3214,7 +3308,16 @@ static void K_drawKartMinimap(void) colormap = R_GetTranslationColormap(TC_RAINBOW, mobj->color, GTC_CACHE); } - K_drawKartMinimapIcon(mobj->x, mobj->y, x, y, splitflags, kp_spbminimap, colormap, AutomapPic); + interpx = mobj->x; + interpy = mobj->y; + + if (cv_frameinterpolation.value == 1) + { + interpx = mobj->old_x + FixedMul(rendertimefrac, mobj->x - mobj->old_x); + interpy = mobj->old_y + FixedMul(rendertimefrac, mobj->y - mobj->old_y); + } + + K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_spbminimap, colormap, AutomapPic); } } @@ -3242,12 +3345,23 @@ static void K_drawKartMinimap(void) else colormap = NULL; - K_drawKartMinimapIcon(players[localplayers[i]].mo->x, players[localplayers[i]].mo->y, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic); + interpx = players[localplayers[i]].mo->x; + interpy = players[localplayers[i]].mo->y; + + if (cv_frameinterpolation.value == 1) + { + interpx = players[localplayers[i]].mo->old_x + FixedMul(rendertimefrac, players[localplayers[i]].mo->x - players[localplayers[i]].mo->old_x); + interpy = players[localplayers[i]].mo->old_y + FixedMul(rendertimefrac, players[localplayers[i]].mo->y - players[localplayers[i]].mo->old_y); + } + + K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap, AutomapPic); // Target reticule if ((gametype == GT_RACE && players[localplayers[i]].position == spbplace) - || (gametype == GT_BATTLE && K_IsPlayerWanted(&players[localplayers[i]]))) - K_drawKartMinimapIcon(players[localplayers[i]].mo->x, players[localplayers[i]].mo->y, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic); + || (gametype == GT_BATTLE && K_IsPlayerWanted(&players[localplayers[i]]))) + { + K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic); + } } } @@ -3507,7 +3621,7 @@ static void K_drawKartFinish(void) //else -- 1/2p, scrolling FINISH { - INT32 x, xval; + INT32 x, xval, ox, interpx; if (r_splitscreen) // wide splitscreen pnum += 4; @@ -3515,11 +3629,14 @@ static void K_drawKartFinish(void) x = ((vid.width<width)<karthud[khud_cardanimation])*(xval > x ? xval : x))/TICRATE; + ox = ((TICRATE - (stplyr->karthud[khud_cardanimation] - 1))*(xval > x ? xval : x))/TICRATE; + + interpx = ox + FixedMul(rendertimefrac, x - ox); if (r_splitscreen && stplyr == &players[displayplayers[1]]) - x = -x; + interpx = -interpx; - V_DrawFixedPatch(x + (STCD_X<>1), + V_DrawFixedPatch(interpx + (STCD_X<>1), (STCD_Y<height)<<(FRACBITS-1)), FRACUNIT, splitflags, kp_racefinish[pnum], NULL); @@ -3742,9 +3859,9 @@ static void K_drawKartFirstPerson(void) fixed_t yoffs = -P_ReturnThrustX(stplyr->mo, ang, 4*FRACUNIT); // hitlag vibrating - if (stplyr->mo->hitlag > 0) + if (stplyr->mo->hitlag > 0 && (stplyr->mo->eflags & MFE_DAMAGEHITLAG)) { - fixed_t mul = stplyr->mo->hitlag * (FRACUNIT / 10); + fixed_t mul = stplyr->mo->hitlag * HITLAGJITTERS; if (r_splitscreen && mul > FRACUNIT) mul = FRACUNIT; @@ -3908,33 +4025,63 @@ static void K_drawChallengerScreen(void) static void K_drawLapStartAnim(void) { // This is an EVEN MORE insanely complicated animation. - const UINT8 progress = 80-stplyr->karthud[khud_lapanimation]; + const UINT8 t = stplyr->karthud[khud_lapanimation]; + const UINT8 progress = 80 - t; + + const UINT8 tOld = t - 1; + const UINT8 progressOld = 80 - tOld; + + const tic_t leveltimeOld = leveltime - 1; + UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, stplyr->skincolor, GTC_CACHE); - V_DrawFixedPatch((BASEVIDWIDTH/2 + (32*max(0, stplyr->karthud[khud_lapanimation]-76)))*FRACUNIT, - (48 - (32*max(0, progress-76)))*FRACUNIT, + fixed_t interpx, interpy, newval, oldval; + + newval = (BASEVIDWIDTH/2 + (32 * max(0, t - 76))) * FRACUNIT; + oldval = (BASEVIDWIDTH/2 + (32 * max(0, tOld - 76))) * FRACUNIT; + interpx = oldval + FixedMul(rendertimefrac, newval - oldval); + + newval = (48 - (32 * max(0, progress - 76))) * FRACUNIT; + oldval = (48 - (32 * max(0, progressOld - 76))) * FRACUNIT; + interpy = oldval + FixedMul(rendertimefrac, newval - oldval); + + V_DrawFixedPatch( + interpx, interpy, FRACUNIT, V_SNAPTOTOP|V_HUDTRANS, (modeattacking ? kp_lapanim_emblem[1] : kp_lapanim_emblem[0]), colormap); if (stplyr->karthud[khud_laphand] >= 1 && stplyr->karthud[khud_laphand] <= 3) { - V_DrawFixedPatch((BASEVIDWIDTH/2 + (32*max(0, stplyr->karthud[khud_lapanimation]-76)))*FRACUNIT, - (48 - (32*max(0, progress-76)) - + 4 - abs((signed)((leveltime % 8) - 4)))*FRACUNIT, + newval = (4 - abs((signed)((leveltime % 8) - 4))) * FRACUNIT; + oldval = (4 - abs((signed)((leveltimeOld % 8) - 4))) * FRACUNIT; + interpy += oldval + FixedMul(rendertimefrac, newval - oldval); + + V_DrawFixedPatch( + interpx, interpy, FRACUNIT, V_SNAPTOTOP|V_HUDTRANS, kp_lapanim_hand[stplyr->karthud[khud_laphand]-1], NULL); } if (stplyr->laps == (UINT8)(cv_numlaps.value)) { - V_DrawFixedPatch((62 - (32*max(0, progress-76)))*FRACUNIT, // 27 + newval = (62 - (32 * max(0, progress - 76))) * FRACUNIT; + oldval = (62 - (32 * max(0, progressOld - 76))) * FRACUNIT; + interpx = oldval + FixedMul(rendertimefrac, newval - oldval); + + V_DrawFixedPatch( + interpx, // 27 30*FRACUNIT, // 24 FRACUNIT, V_SNAPTOTOP|V_HUDTRANS, kp_lapanim_final[min(progress/2, 10)], NULL); if (progress/2-12 >= 0) { - V_DrawFixedPatch((188 + (32*max(0, progress-76)))*FRACUNIT, // 194 + newval = (188 + (32 * max(0, progress - 76))) * FRACUNIT; + oldval = (188 + (32 * max(0, progressOld - 76))) * FRACUNIT; + interpx = oldval + FixedMul(rendertimefrac, newval - oldval); + + V_DrawFixedPatch( + interpx, // 194 30*FRACUNIT, // 24 FRACUNIT, V_SNAPTOTOP|V_HUDTRANS, kp_lapanim_lap[min(progress/2-12, 6)], NULL); @@ -3942,21 +4089,36 @@ static void K_drawLapStartAnim(void) } else { - V_DrawFixedPatch((82 - (32*max(0, progress-76)))*FRACUNIT, // 61 + newval = (82 - (32 * max(0, progress - 76))) * FRACUNIT; + oldval = (82 - (32 * max(0, progressOld - 76))) * FRACUNIT; + interpx = oldval + FixedMul(rendertimefrac, newval - oldval); + + V_DrawFixedPatch( + interpx, // 61 30*FRACUNIT, // 24 FRACUNIT, V_SNAPTOTOP|V_HUDTRANS, kp_lapanim_lap[min(progress/2, 6)], NULL); if (progress/2-8 >= 0) { - V_DrawFixedPatch((188 + (32*max(0, progress-76)))*FRACUNIT, // 194 + newval = (188 + (32 * max(0, progress - 76))) * FRACUNIT; + oldval = (188 + (32 * max(0, progressOld - 76))) * FRACUNIT; + interpx = oldval + FixedMul(rendertimefrac, newval - oldval); + + V_DrawFixedPatch( + interpx, // 194 30*FRACUNIT, // 24 FRACUNIT, V_SNAPTOTOP|V_HUDTRANS, kp_lapanim_number[(((UINT32)stplyr->laps) / 10)][min(progress/2-8, 2)], NULL); if (progress/2-10 >= 0) { - V_DrawFixedPatch((208 + (32*max(0, progress-76)))*FRACUNIT, // 221 + newval = (208 + (32 * max(0, progress - 76))) * FRACUNIT; + oldval = (208 + (32 * max(0, progressOld - 76))) * FRACUNIT; + interpx = oldval + FixedMul(rendertimefrac, newval - oldval); + + V_DrawFixedPatch( + interpx, // 221 30*FRACUNIT, // 24 FRACUNIT, V_SNAPTOTOP|V_HUDTRANS, kp_lapanim_number[(((UINT32)stplyr->laps) % 10)][min(progress/2-10, 2)], NULL); diff --git a/src/k_kart.c b/src/k_kart.c index 44d02c0eb..08b54f30b 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -52,7 +52,7 @@ void K_TimerReset(void) void K_TimerInit(void) { UINT8 i; - UINT8 numPlayers = 0; + UINT8 numPlayers = 0;//, numspec = 0; for (i = 0; i < MAXPLAYERS; i++) { @@ -63,6 +63,7 @@ void K_TimerInit(void) if (players[i].spectator == true) { + //numspec++; continue; } @@ -98,6 +99,7 @@ void K_TimerInit(void) // NOW you can try to spawn in the Battle capsules, if there's not enough players for a match K_SpawnBattleCapsules(); + //CONS_Printf("numbulbs set to %d (%d players, %d spectators) on tic %d\n", numbulbs, numPlayers, numspec, leveltime); } UINT32 K_GetPlayerDontDrawFlag(player_t *player) @@ -696,7 +698,7 @@ INT32 K_KartGetItemOdds( } else { - const INT32 distFromStart = max(0, secondToFirst - SPBSTARTDIST); + const INT32 distFromStart = max(0, (INT32)secondToFirst - SPBSTARTDIST); const INT32 distRange = SPBFORCEDIST - SPBSTARTDIST; const INT32 mulMax = 3; @@ -2078,6 +2080,18 @@ void K_SpawnInvincibilitySpeedLines(mobj_t *mo) fast->destscale = 6*((mo->player->invincibilitytimer/TICRATE)*FRACUNIT)/8; } +void K_SpawnBumpEffect(mobj_t *mo) +{ + mobj_t *fx = P_SpawnMobj(mo->x, mo->y, mo->z, MT_BUMP); + if (mo->eflags & MFE_VERTICALFLIP) + fx->eflags |= MFE_VERTICALFLIP; + else + fx->eflags &= ~MFE_VERTICALFLIP; + fx->scale = mo->scale; + + S_StartSound(mo, sfx_s3k49); +} + static SINT8 K_GlanceAtPlayers(player_t *glancePlayer) { const fixed_t maxdistance = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)); @@ -2207,7 +2221,11 @@ void K_KartMoveAnimation(player_t *player) turndir = 1; } - if (lookback == true && drift == 0) + if (!lookback) + { + player->pflags &= ~PF_LOOKDOWN; + } + else if (drift == 0) { // Prioritize looking back frames over turning turndir = 0; @@ -2219,6 +2237,7 @@ void K_KartMoveAnimation(player_t *player) destGlanceDir = -(2*intsign(player->aizdriftturn)); player->glanceDir = destGlanceDir; drift = turndir = 0; + player->pflags &= ~PF_LOOKDOWN; } else if (player->aizdriftturn) { @@ -2233,6 +2252,7 @@ void K_KartMoveAnimation(player_t *player) if (lookback == true) { + statenum_t gainaxstate = S_GAINAX_TINY; if (destGlanceDir == 0) { if (player->glanceDir != 0) @@ -2257,6 +2277,20 @@ void K_KartMoveAnimation(player_t *player) { // Looking back AND glancing? Amplify the look! destGlanceDir *= 2; + if (player->itemamount && player->itemtype) + gainaxstate = S_GAINAX_HUGE; + else + gainaxstate = S_GAINAX_MID1; + } + + if (destGlanceDir && !(player->pflags & PF_LOOKDOWN)) + { + mobj_t *gainax = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_GAINAX); + gainax->movedir = (destGlanceDir < 0) ? (ANGLE_270-ANG10) : (ANGLE_90+ANG10); + P_SetTarget(&gainax->target, player->mo); + P_SetMobjState(gainax, gainaxstate); + gainax->flags2 |= MF2_AMBUSH; + player->pflags |= PF_LOOKDOWN; } } else if (K_GetForwardMove(player) < 0 && destGlanceDir == 0) @@ -2512,6 +2546,9 @@ void K_KartMoveAnimation(player_t *player) player->glanceDir++; } + if (!player->glanceDir) + player->pflags &= ~PF_LOOKDOWN; + // Update lastspeed value -- we use to display slow driving frames instead of fast driving when slowing down. player->lastspeed = player->speed; } @@ -2646,7 +2683,33 @@ boolean K_ApplyOffroad(player_t *player) boolean K_SlopeResistance(player_t *player) { - if (player->invincibilitytimer || player->sneakertimer || player->tiregrease) + if (player->invincibilitytimer || player->sneakertimer || player->tiregrease || player->flamedash) + return true; + return false; +} + +boolean K_TripwirePass(player_t *player) +{ + if ( + player->invincibilitytimer || + player->sneakertimer || + player->growshrinktimer > 0 || + player->flamedash || + player->speed > 2 * K_GetKartSpeed(player, false) + ) + return true; + return false; +} + +boolean K_WaterRun(player_t *player) +{ + if ( + player->invincibilitytimer || + player->sneakertimer || + player->tiregrease || + player->flamedash || + player->speed > 2 * K_GetKartSpeed(player, false) + ) return true; return false; } @@ -2999,74 +3062,66 @@ angle_t K_MomentumAngle(mobj_t *mo) } } -void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics) +void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage) { - boolean mo1valid = (mo1 && !P_MobjWasRemoved(mo1)); - boolean mo2valid = (mo2 && !P_MobjWasRemoved(mo2)); + if (mo == NULL || P_MobjWasRemoved(mo)) + { + return; + } - INT32 tics1 = tics; - INT32 tics2 = tics; + mo->hitlag += tics; + mo->hitlag = min(mo->hitlag, MAXHITLAGTICS); + + if (fromDamage == true) + { + // Dunno if this should flat-out &~ the flag out too. + // Decided it probably just just keep it since it's "adding" hitlag. + mo->eflags |= MFE_DAMAGEHITLAG; + } +} + +void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics, boolean fromDamage) +{ + INT32 finalTics = tics; if (tics <= 0) { return; } - if (mo1valid == true && mo2valid == true) + if ((mo1 && !P_MobjWasRemoved(mo1)) == true && (mo2 && !P_MobjWasRemoved(mo2)) == true) { - const INT32 mintics = tics; - const fixed_t ticaddfactor = mapobjectscale * 8; + const fixed_t speedTicFactor = (mapobjectscale * 8); + const INT32 angleTicFactor = ANGLE_22h; const fixed_t mo1speed = FixedHypot(FixedHypot(mo1->momx, mo1->momy), mo1->momz); const fixed_t mo2speed = FixedHypot(FixedHypot(mo2->momx, mo2->momy), mo2->momz); - const fixed_t speeddiff = mo2speed - mo1speed; + const fixed_t speedDiff = abs(mo2speed - mo1speed); - const fixed_t scalediff = mo2->scale - mo1->scale; + const fixed_t scaleDiff = abs(mo2->scale - mo1->scale); - const angle_t mo1angle = K_MomentumAngle(mo1); - const angle_t mo2angle = K_MomentumAngle(mo2); + angle_t mo1angle = K_MomentumAngle(mo1); + angle_t mo2angle = K_MomentumAngle(mo2); + INT32 angleDiff = 0; - angle_t anglediff = mo1angle - mo2angle; - fixed_t anglemul = FRACUNIT; - - if (anglediff > ANGLE_180) + if (mo1speed > 0 && mo2speed > 0) { - anglediff = InvAngle(anglediff); + // If either object is completely not moving, their speed doesn't matter. + angleDiff = AngleDelta(mo1angle, mo2angle); } - anglemul = FRACUNIT + (AngleFixed(anglediff) / 180); // x1.0 at 0, x1.5 at 90, x2.0 at 180 + // Add extra "damage" based on what was happening to the objects on impact. + finalTics += (FixedMul(speedDiff, FRACUNIT + scaleDiff) / speedTicFactor) + (angleDiff / angleTicFactor); - /* - CONS_Printf("anglemul: %f\n", FIXED_TO_FLOAT(anglemul)); - CONS_Printf("speeddiff: %f\n", FIXED_TO_FLOAT(speeddiff)); - CONS_Printf("scalediff: %f\n", FIXED_TO_FLOAT(scalediff)); - */ - - tics1 += FixedMul(speeddiff, FixedMul(anglemul, FRACUNIT + scalediff)) / ticaddfactor; - tics2 += FixedMul(-speeddiff, FixedMul(anglemul, FRACUNIT - scalediff)) / ticaddfactor; - - if (tics1 < mintics) + // This shouldn't happen anymore, but just in case something funky happens. + if (finalTics < tics) { - tics1 = mintics; - } - - if (tics2 < mintics) - { - tics2 = mintics; + finalTics = tics; } } - //CONS_Printf("tics1: %d, tics2: %d\n", tics1, tics2); - - if (mo1valid == true) - { - mo1->hitlag = max(tics1, mo1->hitlag); - } - - if (mo2valid == true) - { - mo2->hitlag = max(tics2, mo2->hitlag); - } + K_AddHitLag(mo1, finalTics, fromDamage); + K_AddHitLag(mo2, finalTics, fromDamage); } void K_DoInstashield(player_t *player) @@ -3183,10 +3238,18 @@ void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) player->tumbleBounces = 1; - player->mo->momx = 2 * player->mo->momx / 3; - player->mo->momy = 2 * player->mo->momy / 3; + if (player->tripWireState == TRIP_PASSED) + { + player->tumbleHeight = 50; + } + else + { + player->mo->momx = 2 * player->mo->momx / 3; + player->mo->momy = 2 * player->mo->momy / 3; + + player->tumbleHeight = 30; + } - player->tumbleHeight = 30; player->pflags &= ~PF_TUMBLESOUND; if (inflictor && !P_MobjWasRemoved(inflictor)) @@ -3216,14 +3279,14 @@ void K_TumblePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) static boolean K_LastTumbleBounceCondition(player_t *player) { - return (player->tumbleBounces > TUMBLEBOUNCES && player->tumbleHeight < 40); + return (player->tumbleBounces > TUMBLEBOUNCES && player->tumbleHeight < 60); } static void K_HandleTumbleBounce(player_t *player) { fixed_t gravityadjust; player->tumbleBounces++; - player->tumbleHeight = (player->tumbleHeight * 4) / 5; + player->tumbleHeight = (player->tumbleHeight * ((player->tumbleHeight > 100) ? 3 : 4)) / 5; player->pflags &= ~PF_TUMBLESOUND; if (player->tumbleHeight < 10) @@ -3286,6 +3349,23 @@ static void K_HandleTumbleSound(player_t *player) } } +void K_ApplyTripWire(player_t *player, tripwirestate_t state) +{ + if (state == TRIP_PASSED) + S_StartSound(player->mo, sfx_ssa015); + else if (state == TRIP_BLOCKED) + S_StartSound(player->mo, sfx_kc40); + + player->tripWireState = state; + K_AddHitLag(player->mo, 10, false); + + if (state == TRIP_PASSED && player->spinouttimer && + player->speed > 2* K_GetKartSpeed(player, false)) + { + K_TumblePlayer(player, NULL, NULL); + } +} + INT32 K_ExplodePlayer(player_t *player, mobj_t *inflictor, mobj_t *source) // A bit of a hack, we just throw the player up higher here and extend their spinout timer { INT32 ringburst = 10; @@ -3557,14 +3637,9 @@ void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 #define MINEQUAKEDIST 4096 -// Spawns the purely visual explosion -void K_SpawnMineExplosion(mobj_t *source, UINT8 color) +// Does the proximity screen flash and quake for explosions +void K_MineFlashScreen(mobj_t *source) { - INT32 i, radius, height; - mobj_t *smoldering = P_SpawnMobj(source->x, source->y, source->z, MT_SMOLDERING); - mobj_t *dust; - mobj_t *truc; - INT32 speed, speed2; INT32 pnum; player_t *p; @@ -3587,6 +3662,18 @@ void K_SpawnMineExplosion(mobj_t *source, UINT8 color) break; // we can break right now because quakes are global to all split players somehow. } } +} + +// Spawns the purely visual explosion +void K_SpawnMineExplosion(mobj_t *source, UINT8 color) +{ + INT32 i, radius, height; + mobj_t *smoldering = P_SpawnMobj(source->x, source->y, source->z, MT_SMOLDERING); + mobj_t *dust; + mobj_t *truc; + INT32 speed, speed2; + + K_MineFlashScreen(source); K_MatchGenericExtraFlags(smoldering, source); smoldering->tics = TICRATE*3; @@ -3702,7 +3789,7 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I { // floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn // This should set it for FOFs - P_TeleportMove(th, th->x, th->y, th->z); + P_SetOrigin(th, th->x, th->y, th->z); // spawn on the ground if the player is on the ground if (P_MobjFlip(source) < 0) { @@ -4457,6 +4544,47 @@ void K_DriftDustHandling(mobj_t *spawner) } } +void K_Squish(mobj_t *mo) +{ + const fixed_t maxstretch = 4*FRACUNIT; + const fixed_t factor = 5 * mo->height / 4; + const fixed_t threshold = factor / 6; + + fixed_t old3dspeed = abs(mo->lastmomz); + fixed_t new3dspeed = abs(mo->momz); + + fixed_t delta = abs(old3dspeed - new3dspeed); + fixed_t grav = mo->height/3; + fixed_t add = abs(grav - new3dspeed); + + if (delta < 2 * add && new3dspeed > grav) + delta += add; + + if (delta > threshold) + { + mo->spritexscale = + FRACUNIT + FixedDiv(delta, factor); + + if (mo->spritexscale > maxstretch) + mo->spritexscale = maxstretch; + + if (new3dspeed > old3dspeed || new3dspeed > grav) + { + mo->spritexscale = + FixedDiv(FRACUNIT, mo->spritexscale); + } + } + else + { + mo->spritexscale -= + (mo->spritexscale - FRACUNIT) + / (mo->spritexscale < FRACUNIT ? 8 : 3); + } + + mo->spriteyscale = + FixedDiv(FRACUNIT, mo->spritexscale); +} + static mobj_t *K_FindLastTrailMobj(player_t *player) { mobj_t *trail; @@ -4666,7 +4794,7 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing, { // floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn // This should set it for FOFs - P_TeleportMove(mo, mo->x, mo->y, mo->z); // however, THIS can fuck up your day. just absolutely ruin you. + P_SetOrigin(mo, mo->x, mo->y, mo->z); // however, THIS can fuck up your day. just absolutely ruin you. if (P_MobjWasRemoved(mo)) return NULL; @@ -4872,8 +5000,7 @@ static void K_DoHyudoroSteal(player_t *player) // Has an item && (players[i].itemtype && players[i].itemamount - && !(players[i].pflags & PF_ITEMOUT) - && !players[i].karthud[khud_itemblink])) + && !(players[i].pflags & PF_ITEMOUT))) { playerswappable[numplayers] = i; numplayers++; @@ -5100,7 +5227,7 @@ void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound) thrust = FixedMul(thrust, 9*FRACUNIT/8); } - mo->player->trickmomx = mo->player->trickmomy = mo->player->trickmomz = mo->player->tricktime = 0; // Reset post-hitlag momentums and timer + mo->player->tricktime = 0; // Reset post-hitlag timer // Setup the boost for potential upwards trick, at worse, make it your regular max speed. (boost = curr speed*1.25) mo->player->trickboostpower = max(FixedDiv(mo->player->speed, K_GetKartSpeed(mo->player, false)) - FRACUNIT, 0)*125/100; //CONS_Printf("Got boost: %d%\n", mo->player->trickboostpower*100 / FRACUNIT); @@ -5296,7 +5423,7 @@ void K_DropHnextList(player_t *player, boolean keepshields) { // floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn // This should set it for FOFs - //P_TeleportMove(dropwork, dropwork->x, dropwork->y, dropwork->z); -- handled better by above floorz/ceilingz passing + //P_SetOrigin(dropwork, dropwork->x, dropwork->y, dropwork->z); -- handled better by above floorz/ceilingz passing if (flip == 1) { @@ -5822,7 +5949,7 @@ static void K_MoveHeldObjects(player_t *player) z = player->mo->z + player->mo->height - cur->height; cur->flags |= MF_NOCLIPTHING; // temporarily make them noclip other objects so they can't hit anyone while in the player - P_TeleportMove(cur, player->mo->x, player->mo->y, z); + P_MoveOrigin(cur, player->mo->x, player->mo->y, z); cur->momx = FixedMul(FINECOSINE(cur->angle>>ANGLETOFINESHIFT), cur->extravalue1); cur->momy = FixedMul(FINESINE(cur->angle>>ANGLETOFINESHIFT), cur->extravalue1); cur->flags &= ~MF_NOCLIPTHING; @@ -5935,7 +6062,7 @@ static void K_MoveHeldObjects(player_t *player) P_SetObjectMomZ(cur, FixedMul(targz - cur->z, 7*FRACUNIT/8) - gravity, false); if (R_PointToDist2(cur->x, cur->y, targx, targy) > 768*FRACUNIT) - P_TeleportMove(cur, targx, targy, cur->z); + P_MoveOrigin(cur, targx, targy, cur->z); if (P_IsObjectOnGround(cur)) { @@ -6025,12 +6152,12 @@ static void K_MoveHeldObjects(player_t *player) diffy = targy - cur->y; diffz = targz - cur->z; - P_TeleportMove(cur->tracer, cur->tracer->x + diffx + P_ReturnThrustX(cur, cur->angle + angoffset, 6*cur->scale), + P_MoveOrigin(cur->tracer, cur->tracer->x + diffx + P_ReturnThrustX(cur, cur->angle + angoffset, 6*cur->scale), cur->tracer->y + diffy + P_ReturnThrustY(cur, cur->angle + angoffset, 6*cur->scale), cur->tracer->z + diffz); P_SetScale(cur->tracer, (cur->tracer->destscale = 3*cur->scale/4)); } - P_TeleportMove(cur, targx, targy, targz); + P_MoveOrigin(cur, targx, targy, targz); K_FlipFromObject(cur, player->mo); // Update graviflip in real time thanks. cur->roll = player->mo->roll; @@ -6342,6 +6469,12 @@ void K_KartPlayerHUDUpdate(player_t *player) else if (player->karthud[khud_fault] > 0 && player->karthud[khud_fault] < 2*TICRATE) player->karthud[khud_fault]++; + if (player->karthud[khud_itemblink] && player->karthud[khud_itemblink]-- <= 0) + { + player->karthud[khud_itemblinkmode] = 0; + player->karthud[khud_itemblink] = 0; + } + if (gametype == GT_RACE) { // 0 is the fast spin animation, set at 30 tics of ring boost or higher! @@ -6860,15 +6993,16 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) K_HandleTumbleBounce(player); } - // This doesn't go in HUD update because it has potential gameplay ramifications - if (player->karthud[khud_itemblink] && player->karthud[khud_itemblink]-- <= 0) - { - player->karthud[khud_itemblinkmode] = 0; - player->karthud[khud_itemblink] = 0; - } - K_KartPlayerHUDUpdate(player); + if (battleovertime.enabled && !(player->pflags & PF_ELIMINATED) && player->bumpers <= 0 && player->karmadelay <= 0) + { + if (player->overtimekarma) + player->overtimekarma--; + else + P_DamageMobj(player->mo, NULL, NULL, 1, DMG_TIMEOVER); + } + if ((battleovertime.enabled >= 10*TICRATE) && !(player->pflags & PF_ELIMINATED)) { fixed_t distanceToBarrier = 0; @@ -6963,11 +7097,14 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) // Handle invincibility sfx K_UpdateInvincibilitySounds(player); // Also thanks, VAda! - // Plays the music after the starting countdown. - if (P_IsLocalPlayer(player) && leveltime == (starttime + (TICRATE/2))) + if (player->tripWireState != TRIP_NONE) { - S_ChangeMusic(mapmusname, mapmusflags, true); - S_ShowMusicCredit(); + if (player->tripWireState == TRIP_PASSED) + S_StartSound(player->mo, sfx_cdfm63); + else if (player->tripWireState == TRIP_BLOCKED) + S_StartSound(player->mo, sfx_kc4c); + + player->tripWireState = TRIP_NONE; } } @@ -7455,10 +7592,12 @@ static INT16 K_GetKartDriftValue(player_t *player, fixed_t countersteer) basedrift += (basedrift / greasetics) * player->tiregrease; } - if (player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) +#if 0 + if (player->mo->eflags & MFE_UNDERWATER) { countersteer = FixedMul(countersteer, 3*FRACUNIT/2); } +#endif return basedrift + (FixedMul(driftadjust * FRACUNIT, countersteer) / FRACUNIT); } @@ -7562,9 +7701,10 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue) turnfixed = FixedMul(turnfixed, FRACUNIT + player->handleboost); } - if (player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) + if ((player->mo->eflags & MFE_UNDERWATER) && + player->speed > 11 * player->mo->scale) { - turnfixed = FixedMul(turnfixed, 3*FRACUNIT/2); + turnfixed /= 2; } // Weight has a small effect on turning @@ -7573,6 +7713,24 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue) return (turnfixed / FRACUNIT); } +INT32 K_GetUnderwaterTurnAdjust(player_t *player) +{ + if ((player->mo->eflags & MFE_UNDERWATER) && + player->speed > 11 * player->mo->scale) + { + INT32 steer = (K_GetKartTurnValue(player, + player->steering) << TICCMD_REDUCE); + + if (!player->drift) + steer = 9 * steer / 5; + + return FixedMul(steer, 8 * FixedDiv(player->speed, + 2 * K_GetKartSpeed(player, false) / 3)); + } + else + return 0; +} + INT32 K_GetKartDriftSparkValue(player_t *player) { return (26*4 + player->kartspeed*2 + (9 - player->kartweight))*8; @@ -8321,7 +8479,7 @@ void K_AdjustPlayerFriction(player_t *player) return; } - // Reduce friction after hitting a horizontal spring + // Reduce friction after hitting a spring if (player->tiregrease) { player->mo->friction += ((FRACUNIT - prevfriction) / greasetics) * player->tiregrease; @@ -8339,10 +8497,15 @@ void K_AdjustPlayerFriction(player_t *player) */ // Water gets ice physics too - if (player->mo->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER)) + if ((player->mo->eflags & MFE_TOUCHWATER) && + !player->offroad) { player->mo->friction += 614; } + else if (player->mo->eflags & MFE_UNDERWATER) + { + player->mo->friction += 312; + } // Wipeout slowdown if (player->spinouttimer && player->wipeoutslow) @@ -8418,7 +8581,12 @@ static void K_trickPanelTimingVisual(player_t *player, fixed_t momz) flame->frame = i|FF_FULLBRIGHT; if (player->trickpanel <= 1 && !player->tumbleBounces) + { flame->tics = 2; + flame->momx = player->mo->momx; + flame->momy = player->mo->momy; + flame->momz = player->mo->momz; + } else { flame->tics = TICRATE; @@ -8468,8 +8636,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) boolean HOLDING_ITEM = (player->pflags & (PF_ITEMOUT|PF_EGGMANOUT)); boolean NO_HYUDORO = (player->stealingtimer == 0); - player->pflags &= ~PF_HITFINISHLINE; - if (!player->exiting) { if (player->oldposition < player->position) // But first, if you lost a place, @@ -9187,29 +9353,21 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (cmd->turning > 0) { P_InstaThrust(player->mo, player->mo->angle + lr, max(basespeed, speed*5/2)); - - player->trickmomx = player->mo->momx; - player->trickmomy = player->mo->momy; - player->trickmomz = player->mo->momz; - P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :) - player->mo->momz = 0; - player->trickpanel = 2; + player->mo->hitlag = TRICKLAG; + player->mo->eflags &= ~MFE_DAMAGEHITLAG; + K_trickPanelTimingVisual(player, momz); } else if (cmd->turning < 0) { P_InstaThrust(player->mo, player->mo->angle - lr, max(basespeed, speed*5/2)); - - player->trickmomx = player->mo->momx; - player->trickmomy = player->mo->momy; - player->trickmomz = player->mo->momz; - P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :) - player->mo->momz = 0; - player->trickpanel = 3; + player->mo->hitlag = TRICKLAG; + player->mo->eflags &= ~MFE_DAMAGEHITLAG; + K_trickPanelTimingVisual(player, momz); } else if (player->throwdir == 1) @@ -9220,15 +9378,11 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } P_InstaThrust(player->mo, player->mo->angle, max(basespeed, speed*3)); - - player->trickmomx = player->mo->momx; - player->trickmomy = player->mo->momy; - player->trickmomz = player->mo->momz; - P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :) - player->mo->momz = 0; - player->trickpanel = 2; + player->mo->hitlag = TRICKLAG; + player->mo->eflags &= ~MFE_DAMAGEHITLAG; + K_trickPanelTimingVisual(player, momz); } else if (player->throwdir == -1) @@ -9250,30 +9404,15 @@ void K_MoveKartPlayer(player_t *player, boolean onground) //CONS_Printf("decay: %d\n", player->trickboostdecay); P_SetObjectMomZ(player->mo, 48*FRACUNIT, relative); - - player->trickmomx = player->mo->momx; - player->trickmomy = player->mo->momy; - player->trickmomz = player->mo->momz; - P_InstaThrust(player->mo, 0, 0); // Sike, you have no speed :) - player->mo->momz = 0; - player->trickpanel = 4; + player->mo->hitlag = TRICKLAG; + player->mo->eflags &= ~MFE_DAMAGEHITLAG; + K_trickPanelTimingVisual(player, momz); } } } - // After hitlag, we will get here and will be able to apply the desired momentums! - else if (player->trickmomx || player->trickmomy || player->trickmomz) - { - player->mo->momx = player->trickmomx; - player->mo->momy = player->trickmomy; - player->mo->momz = player->trickmomz; - - player->trickmomx = player->trickmomy = player->trickmomz = 0; - - } - else if (player->trickpanel == 4 && P_IsObjectOnGround(player->mo)) // Upwards trick landed! { //CONS_Printf("apply boost\n"); @@ -9400,6 +9539,7 @@ void K_CheckSpectateStatus(void) { if (cv_ingamecap.value && numingame+i >= cv_ingamecap.value) // Hit the in-game player cap while adding people? break; + //CONS_Printf("player %s is joining on tic %d\n", player_names[respawnlist[i]], leveltime); P_SpectatorJoinGame(&players[respawnlist[i]]); } diff --git a/src/k_kart.h b/src/k_kart.h index 0694488d3..dffc1cedf 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -19,6 +19,8 @@ Make sure this matches the actual number of states */ #define KART_NUMINVSPARKLESANIM 12 +#define MAXHITLAGTICS 18 //12 +#define HITLAGJITTERS (FRACUNIT / 20) player_t *K_GetItemBoxPlayer(mobj_t *mobj); angle_t K_ReflectAngle(angle_t angle, angle_t against, fixed_t maxspeed, fixed_t yourspeed); @@ -50,12 +52,14 @@ void K_SpawnDriftBoostClip(player_t *player); void K_SpawnDriftBoostClipSpark(mobj_t *clip); void K_SpawnNormalSpeedLines(player_t *player); void K_SpawnInvincibilitySpeedLines(mobj_t *mo); +void K_SpawnBumpEffect(mobj_t *mo); void K_KartMoveAnimation(player_t *player); void K_KartPlayerHUDUpdate(player_t *player); void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); void K_KartPlayerAfterThink(player_t *player); angle_t K_MomentumAngle(mobj_t *mo); -void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics); +void K_AddHitLag(mobj_t *mo, INT32 tics, boolean fromDamage); +void K_SetHitLagForObjects(mobj_t *mo1, mobj_t *mo2, INT32 tics, boolean fromDamage); void K_DoInstashield(player_t *player); void K_BattleAwardHit(player_t *player, player_t *victim, mobj_t *inflictor, UINT8 bumpersRemoved); void K_SpinPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, INT32 type); @@ -66,6 +70,7 @@ void K_HandleBumperChanges(player_t *player, UINT8 prevBumpers); void K_DestroyBumpers(player_t *player, UINT8 amount); void K_TakeBumpersFromPlayer(player_t *player, player_t *victim, UINT8 amount); void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit, mobj_t *source); +void K_MineFlashScreen(mobj_t *source); void K_SpawnMineExplosion(mobj_t *source, UINT8 color); void K_RunFinishLineBeam(void); UINT16 K_DriftSparkColor(player_t *player, INT32 charge); @@ -74,6 +79,7 @@ void K_SpawnSparkleTrail(mobj_t *mo); void K_SpawnWipeoutTrail(mobj_t *mo, boolean offroad); void K_SpawnDraftDust(mobj_t *mo); void K_DriftDustHandling(mobj_t *spawner); +void K_Squish(mobj_t *mo); mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing, INT32 defaultDir, INT32 altthrow); void K_PuntMine(mobj_t *mine, mobj_t *punter); void K_DoSneaker(player_t *player, INT32 type); @@ -88,6 +94,7 @@ void K_UpdateDistanceFromFinishLine(player_t *const player); boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y); void K_UpdateSteeringValue(player_t *player, INT16 destSteering); INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue); +INT32 K_GetUnderwaterTurnAdjust(player_t *player); INT32 K_GetKartDriftSparkValue(player_t *player); INT32 K_StairJankFlip(INT32 value); INT32 K_GetKartDriftSparkValueForStage(player_t *player, UINT8 stage); @@ -103,6 +110,9 @@ void K_StripOther(player_t *player); void K_MomentumToFacing(player_t *player); boolean K_ApplyOffroad(player_t *player); boolean K_SlopeResistance(player_t *player); +boolean K_TripwirePass(player_t *player); +boolean K_WaterRun(player_t *player); +void K_ApplyTripWire(player_t *player, tripwirestate_t state); INT16 K_GetSpindashChargeTime(player_t *player); fixed_t K_GetSpindashChargeSpeed(player_t *player); fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed); diff --git a/src/k_pwrlv.c b/src/k_pwrlv.c index ac2d009bc..860727184 100644 --- a/src/k_pwrlv.c +++ b/src/k_pwrlv.c @@ -30,7 +30,7 @@ SINT8 K_UsingPowerLevels(void) { SINT8 pt = PWRLV_DISABLED; - if (!cv_kartusepwrlv.value || !netgame || grandprixinfo.gp == true) + if (!cv_kartusepwrlv.value || !(netgame || (demo.playback && demo.netgame)) || grandprixinfo.gp == true) { return PWRLV_DISABLED; } @@ -346,7 +346,7 @@ void K_PlayerForfeit(UINT8 playernum, boolean pointloss) clientpowerlevels[playernum][powertype] += inc; - if (playernum == consoleplayer) + if (!demo.playback && playernum == consoleplayer) { vspowerlevel[powertype] = clientpowerlevels[playernum][powertype]; if (M_UpdateUnlockablesAndExtraEmblems()) diff --git a/src/k_respawn.c b/src/k_respawn.c index fcce1b632..2e93a57d8 100644 --- a/src/k_respawn.c +++ b/src/k_respawn.c @@ -155,9 +155,12 @@ void K_DoIngameRespawn(player_t *player) // If player was tumbling, set variables so that they don't tumble like crazy after they're done respawning if (player->tumbleBounces > 0) { - player->tumbleBounces = TUMBLEBOUNCES-1; // Max # of bounces-1 (so you still tumble once) - player->pflags &= ~PF_TUMBLELASTBOUNCE; // Still force them to bounce at least once for the funny - players->tumbleHeight = 20; // force tumble height + player->tumbleBounces = 0; // MAXBOUNCES-1; + player->pflags &= ~PF_TUMBLELASTBOUNCE; + //players->tumbleHeight = 20; + players->mo->rollangle = 0; + player->spinouttype = KSPIN_WIPEOUT; + player->spinouttimer = player->wipeoutslow = (3*TICRATE/2)+2; } P_ResetPlayer(player); @@ -273,6 +276,8 @@ void K_DoIngameRespawn(player_t *player) player->respawn.timer = RESPAWN_TIME; player->respawn.state = RESPAWNST_MOVE; + + player->respawn.airtimer = player->airtime; } /*-------------------------------------------------- @@ -315,8 +320,9 @@ size_t K_NextRespawnWaypointIndex(waypoint_t *waypoint) --------------------------------------------------*/ static void K_MovePlayerToRespawnPoint(player_t *player) { - const fixed_t realstepamt = (64 * mapobjectscale); - fixed_t stepamt = realstepamt; + const int airCompensation = 128; + fixed_t realstepamt = (64 * mapobjectscale); + fixed_t stepamt; vector3_t dest, step, laser; angle_t stepha, stepva; @@ -327,6 +333,13 @@ static void K_MovePlayerToRespawnPoint(player_t *player) waypoint_t *laserwp; boolean laserflip; + /* speed up if in the air for a long time */ + realstepamt += FixedMul(realstepamt, + (player->respawn.airtimer * FRACUNIT) + / airCompensation); + + stepamt = realstepamt; + player->mo->momx = player->mo->momy = player->mo->momz = 0; player->flashing = 2; diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 0ce78b6f9..e07c41bd4 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1415,7 +1415,42 @@ static int lib_pTeleportMove(lua_State *L) INLEVEL if (!thing) return LUA_ErrInvalid(L, "mobj_t"); - lua_pushboolean(L, P_TeleportMove(thing, x, y, z)); + LUA_Deprecated(L, "P_TeleportMove", "P_SetOrigin or P_MoveOrigin"); + lua_pushboolean(L, P_SetOrigin(thing, x, y, z)); + LUA_PushUserdata(L, tmthing, META_MOBJ); + P_SetTarget(&tmthing, ptmthing); + return 2; +} + +static int lib_pSetOrigin(lua_State *L) +{ + mobj_t *ptmthing = tmthing; + mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + fixed_t x = luaL_checkfixed(L, 2); + fixed_t y = luaL_checkfixed(L, 3); + fixed_t z = luaL_checkfixed(L, 4); + NOHUD + INLEVEL + if (!thing) + return LUA_ErrInvalid(L, "mobj_t"); + lua_pushboolean(L, P_SetOrigin(thing, x, y, z)); + LUA_PushUserdata(L, tmthing, META_MOBJ); + P_SetTarget(&tmthing, ptmthing); + return 2; +} + +static int lib_pMoveOrigin(lua_State *L) +{ + mobj_t *ptmthing = tmthing; + mobj_t *thing = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); + fixed_t x = luaL_checkfixed(L, 2); + fixed_t y = luaL_checkfixed(L, 3); + fixed_t z = luaL_checkfixed(L, 4); + NOHUD + INLEVEL + if (!thing) + return LUA_ErrInvalid(L, "mobj_t"); + lua_pushboolean(L, P_MoveOrigin(thing, x, y, z)); LUA_PushUserdata(L, tmthing, META_MOBJ); P_SetTarget(&tmthing, ptmthing); return 2; @@ -3835,6 +3870,8 @@ static luaL_Reg lib[] = { {"P_TryMove",lib_pTryMove}, {"P_Move",lib_pMove}, {"P_TeleportMove",lib_pTeleportMove}, + {"P_SetOrigin",lib_pSetOrigin}, + {"P_MoveOrigin",lib_pMoveOrigin}, {"P_SlideMove",lib_pSlideMove}, {"P_BounceMove",lib_pBounceMove}, {"P_CheckSight", lib_pCheckSight}, diff --git a/src/lua_infolib.c b/src/lua_infolib.c index bbf640b85..880496770 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -41,6 +41,7 @@ enum sfxinfo_read { sfxinfor_singular, sfxinfor_priority, sfxinfor_flags, // "pitch" + sfxinfor_volume, sfxinfor_caption, sfxinfor_skinsound }; @@ -49,6 +50,7 @@ const char *const sfxinfo_ropt[] = { "singular", "priority", "flags", + "volume", "caption", "skinsound", NULL}; @@ -57,12 +59,14 @@ enum sfxinfo_write { sfxinfow_singular = 0, sfxinfow_priority, sfxinfow_flags, // "pitch" + sfxinfow_volume, sfxinfow_caption }; const char *const sfxinfo_wopt[] = { "singular", "priority", "flags", + "volume", "caption", NULL}; @@ -1328,6 +1332,9 @@ static int lib_setSfxInfo(lua_State *L) case sfxinfow_flags: info->pitch = (INT32)luaL_checkinteger(L, 3); break; + case sfxinfow_volume: + info->volume = (INT32)luaL_checkinteger(L, 3); + break; case sfxinfow_caption: strlcpy(info->caption, luaL_checkstring(L, 3), sizeof(info->caption)); break; @@ -1368,6 +1375,9 @@ static int sfxinfo_get(lua_State *L) case sfxinfor_flags: lua_pushinteger(L, sfx->pitch); return 1; + case sfxinfor_volume: + lua_pushinteger(L, sfx->volume); + return 1; case sfxinfor_caption: lua_pushstring(L, sfx->caption); return 1; @@ -1408,6 +1418,9 @@ static int sfxinfo_set(lua_State *L) case sfxinfow_flags: sfx->pitch = luaL_checkinteger(L, 1); break; + case sfxinfow_volume: + sfx->volume = luaL_checkinteger(L, 1); + break; case sfxinfow_caption: strlcpy(sfx->caption, luaL_checkstring(L, 1), sizeof(sfx->caption)); break; diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 0821cac6d..8a4a1e7a5 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -477,7 +477,7 @@ static int mobj_get(lua_State *L) } #define NOSET luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " should not be set directly.", mobj_opt[field]) -#define NOSETPOS luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " should not be set directly. Use " LUA_QL("P_Move") ", " LUA_QL("P_TryMove") ", or " LUA_QL("P_TeleportMove") " instead.", mobj_opt[field]) +#define NOSETPOS luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " should not be set directly. Use " LUA_QL("P_Move") ", " LUA_QL("P_TryMove") ", or " LUA_QL("P_SetOrigin") ", or " LUA_QL("P_MoveOrigin") " instead.", mobj_opt[field]) static int mobj_set(lua_State *L) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index d628b7016..f7c20ab64 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -356,12 +356,6 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->trickpanel); else if (fastcmp(field,"tricktime")) lua_pushinteger(L, plr->tricktime); - else if (fastcmp(field,"trickmomx")) - lua_pushfixed(L, plr->trickmomx); - else if (fastcmp(field,"trickmomy")) - lua_pushfixed(L, plr->trickmomy); - else if (fastcmp(field,"trickmomz")) - lua_pushfixed(L, plr->trickmomz); else if (fastcmp(field,"trickboostpower")) lua_pushfixed(L, plr->trickboostpower); else if (fastcmp(field,"trickboostdecay")) @@ -707,12 +701,6 @@ static int player_set(lua_State *L) plr->trickpanel = luaL_checkinteger(L, 3); else if (fastcmp(field,"tricktime")) plr->tricktime = luaL_checkinteger(L, 3); - else if (fastcmp(field,"trickmomx")) - plr->trickmomx = luaL_checkfixed(L, 3); - else if (fastcmp(field,"trickmomy")) - plr->trickmomy = luaL_checkfixed(L, 3); - else if (fastcmp(field,"trickmomz")) - plr->trickmomz = luaL_checkfixed(L, 3); else if (fastcmp(field,"trickboostpower")) plr->trickboostpower = luaL_checkfixed(L, 3); else if (fastcmp(field,"trickboostdecay")) diff --git a/src/m_cheat.c b/src/m_cheat.c index b45a7cbb6..384edbba2 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -420,7 +420,7 @@ void Command_RTeleport_f(void) CONS_Printf(M_GetText("Teleporting by %d, %d, %d...\n"), intx, inty, FixedInt((intz-p->mo->z))); P_MapStart(); - if (!P_TeleportMove(p->mo, p->mo->x+intx*FRACUNIT, p->mo->y+inty*FRACUNIT, intz)) + if (!P_SetOrigin(p->mo, p->mo->x+intx*FRACUNIT, p->mo->y+inty*FRACUNIT, intz)) CONS_Alert(CONS_WARNING, M_GetText("Unable to teleport to that spot!\n")); else S_StartSound(p->mo, sfx_mixup); @@ -641,7 +641,7 @@ void Command_Teleport_f(void) } P_MapStart(); - if (!P_TeleportMove(p->mo, intx, inty, intz)) + if (!P_SetOrigin(p->mo, intx, inty, intz)) CONS_Alert(CONS_WARNING, M_GetText("Unable to teleport to that spot!\n")); else S_StartSound(p->mo, sfx_mixup); @@ -1039,7 +1039,7 @@ void OP_ObjectplaceMovement(player_t *player) if (cmd->forwardmove != 0) { P_Thrust(player->mo, player->mo->angle, (cmd->forwardmove*player->mo->scale/MAXPLMOVE)*cv_speed.value); - P_TeleportMove(player->mo, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, player->mo->z); + P_MoveOrigin(player->mo, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, player->mo->z); player->mo->momx = player->mo->momy = 0; } diff --git a/src/p_enemy.c b/src/p_enemy.c index 9f5fc86d8..749d0dc09 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -310,6 +310,7 @@ void A_JawzExplode(mobj_t *actor); void A_SPBChase(mobj_t *actor); void A_SSMineSearch(mobj_t *actor); void A_SSMineExplode(mobj_t *actor); +void A_LandMineExplode(mobj_t *actor); void A_BallhogExplode(mobj_t *actor); void A_LightningFollowPlayer(mobj_t *actor); void A_FZBoomFlash(mobj_t *actor); @@ -321,7 +322,6 @@ void A_ReaperThinker(mobj_t *actor); void A_MementosTPParticles(mobj_t *actor); void A_FlameShieldPaper(mobj_t *actor); void A_InvincSparkleRotate(mobj_t *actor); -void A_SpawnItemCapsuleParts(mobj_t *actor); //for p_enemy.c @@ -1145,7 +1145,7 @@ void A_FaceStabHurl(mobj_t *actor) hwork->destscale = FixedSqrt(step*basesize); P_SetScale(hwork, hwork->destscale); hwork->fuse = 2; - P_TeleportMove(hwork, actor->x + xo*(15-step), actor->y + yo*(15-step), actor->z + (actor->height - hwork->height)/2 + (P_MobjFlip(actor)*(8<x + xo*(15-step), actor->y + yo*(15-step), actor->z + (actor->height - hwork->height)/2 + (P_MobjFlip(actor)*(8<x + P_ReturnThrustX(actor, actor->angle, locvar1*crab->scale), crab->y + P_ReturnThrustY(actor, actor->angle, locvar1*crab->scale), crab->z + locvar2*crab->scale); @@ -2043,7 +2043,7 @@ void A_CrushclawLaunch(mobj_t *actor) fixed_t idx = dx, idy = dy, idz = dz; while (chain) { - P_TeleportMove(chain, actor->target->x + idx, actor->target->y + idy, actor->target->z + idz); + P_MoveOrigin(chain, actor->target->x + idx, actor->target->y + idy, actor->target->z + idz); chain->movefactor = chain->z; idx += dx; idy += dy; @@ -4023,7 +4023,7 @@ void A_AttractChase(mobj_t *actor) //P_SetScale(actor, (actor->destscale = actor->target->scale)); actor->z = actor->target->z; K_MatchGenericExtraFlags(actor, actor->target); - P_TeleportMove(actor, actor->target->x, actor->target->y, + P_MoveOrigin(actor, actor->target->x, actor->target->y, actor->z + ( actor->target->height + offz )* P_MobjFlip(actor)); actor->extravalue1++; @@ -4052,7 +4052,7 @@ void A_AttractChase(mobj_t *actor) P_SetScale(actor, (actor->destscale = actor->target->scale - ((actor->target->scale/14) * actor->extravalue1))); actor->z = actor->target->z; K_MatchGenericExtraFlags(actor, actor->target); - P_TeleportMove(actor, + P_MoveOrigin(actor, actor->target->x + FixedMul(dist, FINECOSINE(actor->angle >> ANGLETOFINESHIFT)), actor->target->y + FixedMul(dist, FINESINE(actor->angle >> ANGLETOFINESHIFT)), actor->z + actor->target->scale * 24 * P_MobjFlip(actor)); @@ -9911,7 +9911,7 @@ void A_VileAttack(mobj_t *actor) // move the fire between the vile and the player //fire->x = actor->target->x - FixedMul (24*FRACUNIT, finecosine[an]); //fire->y = actor->target->y - FixedMul (24*FRACUNIT, finesine[an]); - P_TeleportMove(fire, + P_MoveOrigin(fire, actor->target->x - P_ReturnThrustX(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)), actor->target->y - P_ReturnThrustY(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)), fire->z); @@ -9956,7 +9956,7 @@ void A_VileAttack(mobj_t *actor) // move the fire between the vile and the player //fire->x = actor->target->x - FixedMul (24*FRACUNIT, finecosine[an]); //fire->y = actor->target->y - FixedMul (24*FRACUNIT, finesine[an]); - P_TeleportMove(fire, + P_MoveOrigin(fire, actor->target->x - P_ReturnThrustX(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)), actor->target->y - P_ReturnThrustY(fire, actor->angle, FixedMul(24*FRACUNIT, fire->scale)), fire->z); @@ -10629,13 +10629,13 @@ void A_FlickyCenter(mobj_t *actor) if (actor->target && P_AproxDistance(actor->target->x - originx, actor->target->y - originy) < actor->extravalue1) { actor->extravalue2 = 1; - P_TeleportMove(actor, actor->target->x, actor->target->y, actor->target->z); + P_SetOrigin(actor, actor->target->x, actor->target->y, actor->target->z); tmthing = NULL; } else if(actor->extravalue2) { actor->extravalue2 = 0; - P_TeleportMove(actor, originx, originy, originz); + P_SetOrigin(actor, originx, originy, originz); tmthing = NULL; } } @@ -11172,7 +11172,7 @@ void A_LightBeamReset(mobj_t *actor) actor->momy = (P_SignedRandom()*FINECOSINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/128; actor->momz = (P_SignedRandom()*FRACUNIT)/128; - P_TeleportMove(actor, + P_SetOrigin(actor, actor->spawnpoint->x*FRACUNIT - (P_SignedRandom()*FINESINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/2, actor->spawnpoint->y*FRACUNIT + (P_SignedRandom()*FINECOSINE(((actor->spawnpoint->angle*ANG1)>>ANGLETOFINESHIFT) & FINEMASK))/2, actor->spawnpoint->z*FRACUNIT + (P_SignedRandom()*FRACUNIT)/2); @@ -11195,10 +11195,13 @@ void A_MineExplode(mobj_t *actor) A_Scream(actor); actor->flags = MF_NOGRAVITY|MF_NOCLIP; + /* quake.epicenter = NULL; quake.radius = 512*FRACUNIT; quake.intensity = 8*FRACUNIT; quake.time = TICRATE/3; + */ + P_StartQuake(8<tracer, 192*FRACUNIT, 0, true); P_MobjCheckWater(actor); @@ -11757,7 +11760,7 @@ void A_DoNPCSkid(mobj_t *actor) actor->momy = (2*actor->momy)/3; } - P_TeleportMove(actor, x, y, z); + P_MoveOrigin(actor, x, y, z); // Spawn a particle every 3 tics. if (!(leveltime % 3)) @@ -12098,7 +12101,7 @@ void A_Boss5MakeJunk(mobj_t *actor) if (locvar1 > 0) P_SetMobjState(broked, locvar1); if (!P_MobjWasRemoved(broked)) - P_TeleportMove(broked, broked->x + broked->momx, broked->y + broked->momy, broked->z); + P_MoveOrigin(broked, broked->x + broked->momx, broked->y + broked->momy, broked->z); ang += ANGLE_45; } @@ -12205,9 +12208,9 @@ void A_Boss5BombExplode(mobj_t *actor) P_DustRing(locvar1, 4, actor->x, actor->y, actor->z+actor->height, 2*actor->radius, 0, FRACUNIT, actor->scale); P_DustRing(locvar1, 6, actor->x, actor->y, actor->z+actor->height/2, 3*actor->radius, FRACUNIT, FRACUNIT, actor->scale); - //P_StartQuake(9*actor->scale, TICRATE/6, {actor->x, actor->y, actor->z}, 20*actor->radius); + //P_StartQuake(9*FRACUNIT, TICRATE/6, {actor->x, actor->y, actor->z}, 20*actor->radius); // the above does not exist, so we set the quake values directly instead - quake.intensity = 9*actor->scale; + quake.intensity = 9*FRACUNIT; quake.time = TICRATE/6; // the following quake values have no effect atm? ah well, may as well set them anyway { @@ -13161,7 +13164,7 @@ void A_DragonWing(mobj_t *actor) actor->angle = target->angle + actor->movedir; x = target->x + P_ReturnThrustX(actor, actor->angle, -target->radius); y = target->y + P_ReturnThrustY(actor, actor->angle, -target->radius); - P_TeleportMove(actor, x, y, target->z); + P_MoveOrigin(actor, x, y, target->z); } // Function: A_DragonSegment @@ -13202,7 +13205,7 @@ void A_DragonSegment(mobj_t *actor) zdist = P_ReturnThrustY(target, zangle, radius); actor->angle = hangle; - P_TeleportMove(actor, target->x + xdist, target->y + ydist, target->z + zdist); + P_MoveOrigin(actor, target->x + xdist, target->y + ydist, target->z + zdist); } // Function: A_ChangeHeight @@ -13251,6 +13254,8 @@ void A_ChangeHeight(mobj_t *actor) void A_ItemPop(mobj_t *actor) { + INT32 locvar1 = var1; + mobj_t *remains; mobjtype_t explode; @@ -13305,7 +13310,9 @@ void A_ItemPop(mobj_t *actor) if (actor->info->deathsound) S_StartSound(remains, actor->info->deathsound); - if (!((gametyperules & GTR_BUMPERS) && actor->target->player->bumpers <= 0)) + if (locvar1 == 1) + P_GivePlayerSpheres(actor->target->player, actor->extravalue1); + else if (locvar1 == 0) actor->target->player->itemroulette = 1; remains->flags2 &= ~MF2_AMBUSH; @@ -14133,6 +14140,50 @@ void A_SSMineExplode(mobj_t *actor) actor->flags2 |= MF2_DEBRIS; // Set this flag to ensure that the explosion won't be effective more than 1 frame. } +void A_LandMineExplode(mobj_t *actor) +{ + + mobj_t *expl; + INT32 colour = SKINCOLOR_KETCHUP; // we spell words properly here + INT32 i; + mobj_t *smoldering; + + if (LUA_CallAction(A_LANDMINEEXPLODE, actor)) + return; + + // we'll base the explosion "timer" off of some stupid variable like uh... cvmem! + // Yeah let's use cvmem since nobody uses that + + if (actor->target && !P_MobjWasRemoved(actor->target)) + colour = actor->target->color; + + K_MineFlashScreen(actor); + + // Spawn smoke remains: + smoldering = P_SpawnMobj(actor->x, actor->y, actor->z, MT_SMOLDERING); + P_SetScale(smoldering, actor->scale); + smoldering->tics = TICRATE*3; + + actor->fuse = actor->tics; // disappear when this state ends. + + // spawn a few physics explosions + for (i = 0; i < 15; i++) + { + expl = P_SpawnMobj(actor->x, actor->y, actor->z + actor->scale, MT_BOOMEXPLODE); + expl->color = colour; + expl->tics = (i+1); + + //K_MatchGenericExtraFlags(expl, actor); + P_SetScale(expl, actor->scale*4); + + expl->momx = P_RandomRange(-3, 3)*actor->scale/2; + expl->momy = P_RandomRange(-3, 3)*actor->scale/2; + + // 100/45 = 2.22 fu/t + expl->momz = ((i+1)*actor->scale*5/2)*P_MobjFlip(expl); + } +} + void A_BallhogExplode(mobj_t *actor) { mobj_t *mo2; @@ -14164,10 +14215,10 @@ void A_LightningFollowPlayer(mobj_t *actor) { sx = actor->target->x + FixedMul((actor->target->scale*actor->extravalue1), FINECOSINE((actor->angle)>>ANGLETOFINESHIFT)); sy = actor->target->y + FixedMul((actor->target->scale*actor->extravalue1), FINESINE((actor->angle)>>ANGLETOFINESHIFT)); - P_TeleportMove(actor, sx, sy, actor->target->z); + P_MoveOrigin(actor, sx, sy, actor->target->z); } else // else just teleport to player directly - P_TeleportMove(actor, actor->target->x, actor->target->y, actor->target->z); + P_MoveOrigin(actor, actor->target->x, actor->target->y, actor->target->z); K_MatchGenericExtraFlags(actor, actor->target); // copy our target for graviflip actor->momx = actor->target->momx; @@ -14644,7 +14695,7 @@ void A_InvincSparkleRotate(mobj_t *actor) sx = actor->target->x + FixedMul((actor->movefactor), FINECOSINE((actor->angle)>>ANGLETOFINESHIFT)); sy = actor->target->y + FixedMul((actor->movefactor), FINESINE((actor->angle)>>ANGLETOFINESHIFT)); sz = actor->target->z + (actor->extravalue1) + FixedMul((actor->cvmem), FINECOSINE((leveltime*ANG1*10 + actor->angle)>>ANGLETOFINESHIFT)); - P_TeleportMove(actor, sx, sy, sz); + P_MoveOrigin(actor, sx, sy, sz); actor->momx = actor->target->momx; actor->momy = actor->target->momy; @@ -14652,191 +14703,3 @@ void A_InvincSparkleRotate(mobj_t *actor) actor->angle += ANG1*10*(actor->extravalue2); // Arbitrary value, change this if you want, I suppose. } - -void P_RefreshItemCapsuleParts(mobj_t *mobj) -{ - UINT8 numNumbers = 0; - INT32 count = 0; - INT32 itemType = mobj->threshold; - mobj_t *part; - skincolornum_t color; - UINT32 newRenderFlags = 0; - boolean colorized; - - if (itemType < 1 || itemType >= NUMKARTITEMS) - itemType = KITEM_SAD; - - // update invincibility properties - if (itemType == KITEM_INVINCIBILITY) - { - mobj->renderflags = (mobj->renderflags & ~RF_BRIGHTMASK) | RF_FULLBRIGHT; - mobj->colorized = true; - } - else - { - mobj->renderflags = (mobj->renderflags & ~RF_BRIGHTMASK) | RF_SEMIBRIGHT; - mobj->color = SKINCOLOR_NONE; - mobj->colorized = false; - } - - // update cap colors - if (itemType == KITEM_SUPERRING) - { - color = SKINCOLOR_GOLD; - newRenderFlags |= RF_SEMIBRIGHT; - } - else if (mobj->spawnpoint && (mobj->spawnpoint->options & MTF_EXTRA)) - color = SKINCOLOR_SAPPHIRE; - else if (itemType == KITEM_SPB) - color = SKINCOLOR_JET; - else - color = SKINCOLOR_NONE; - - colorized = (color != SKINCOLOR_NONE); - part = mobj; - while (!P_MobjWasRemoved(part->hnext)) - { - part = part->hnext; - part->color = color; - part->colorized = colorized; - part->renderflags = (part->renderflags & ~RF_BRIGHTMASK) | newRenderFlags; - } - - // update inside item frame - part = mobj->tracer; - if (P_MobjWasRemoved(part)) - return; - - part->threshold = mobj->threshold; - part->movecount = mobj->movecount; - - switch (itemType) - { - case KITEM_ORBINAUT: - part->sprite = SPR_ITMO; - part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetOrbinautItemFrame(mobj->movecount); - break; - case KITEM_INVINCIBILITY: - part->sprite = SPR_ITMI; - part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetInvincibilityItemFrame(); - break; - case KITEM_SAD: - part->sprite = SPR_ITEM; - part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE; - break; - default: - part->sprite = SPR_ITEM; - part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|(itemType); - break; - } - - // update number frame - if (K_GetShieldFromItem(itemType) != KSHIELD_NONE) // shields don't stack, so don't show a number - ; - else - { - switch (itemType) - { - case KITEM_ORBINAUT: // only display the number when the sprite no longer changes - if (mobj->movecount - 1 > K_GetOrbinautItemFrame(mobj->movecount)) - count = mobj->movecount; - break; - case KITEM_SUPERRING: // always display the number, and multiply it by 5 - count = mobj->movecount * 5; - break; - case KITEM_SAD: // never display the number - case KITEM_SPB: - break; - default: - if (mobj->movecount > 1) - count = mobj->movecount; - break; - } - } - - while (count > 0) - { - if (P_MobjWasRemoved(part->tracer)) - { - P_SetTarget(&part->tracer, P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_OVERLAY)); - P_SetTarget(&part->tracer->target, part); - P_SetMobjState(part->tracer, S_INVISIBLE); - part->tracer->spriteyoffset = 10*FRACUNIT; - part->tracer->spritexoffset = 13*numNumbers*FRACUNIT; - } - part = part->tracer; - part->sprite = SPR_ITMN; - part->frame = FF_FULLBRIGHT|(count % 10); - count /= 10; - numNumbers++; - } - - // delete any extra overlays (I guess in case the number changes?) - if (part->tracer) - { - P_RemoveMobj(part->tracer); - P_SetTarget(&part->tracer, NULL); - } -} - -#define CAPSULESIDES 5 -#define ANG_CAPSULE (UINT32_MAX / CAPSULESIDES) -#define ROTATIONSPEED (2*ANG2) -void A_SpawnItemCapsuleParts(mobj_t *actor) -{ - UINT8 i; - mobj_t *part; - fixed_t buttScale = 0; - statenum_t buttState = S_ITEMCAPSULE_BOTTOM_SIDE_AIR; - angle_t spin = ANGLE_MAX - ROTATIONSPEED; - - if (LUA_CallAction(A_SPAWNITEMCAPSULEPARTS, actor)) - return; - - if (P_IsObjectOnGround(actor)) - { - buttScale = 13*FRACUNIT/10; - buttState = S_ITEMCAPSULE_BOTTOM_SIDE_GROUND; - spin = 0; - } - - // inside item - part = P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_ITEMCAPSULE_PART); - P_SetTarget(&part->target, actor); - P_SetMobjState(part, S_ITEMICON); - part->movedir = ROTATIONSPEED; // rotation speed - part->extravalue1 = 175*FRACUNIT/100; // relative scale - part->flags2 |= MF2_CLASSICPUSH; // classicpush = centered horizontally - P_SetTarget(&actor->tracer, part); // pointer to this item, so we can modify its sprite/frame - - // capsule caps - part = actor; - for (i = 0; i < CAPSULESIDES; i++) - { - // a bottom side - P_SetTarget(&part->hnext, P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_ITEMCAPSULE_PART)); - P_SetTarget(&part->hnext->hprev, part); - part = part->hnext; - P_SetTarget(&part->target, actor); - P_SetMobjState(part, buttState); - part->angle = i * ANG_CAPSULE; - part->movedir = spin; // rotation speed - part->movefactor = 0; // z offset - part->extravalue1 = buttScale; // relative scale - - // a top side - P_SetTarget(&part->hnext, P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_ITEMCAPSULE_PART)); - P_SetTarget(&part->hnext->hprev, part); - part = part->hnext; - P_SetTarget(&part->target, actor); - P_SetMobjState(part, S_ITEMCAPSULE_TOP_SIDE); - part->angle = i * ANG_CAPSULE; - part->movedir = spin; // rotation speed - part->movefactor = actor->info->height - part->info->height; // z offset - } - - P_RefreshItemCapsuleParts(actor); -} -#undef CAPSULESIDES -#undef ANG_CAPSULE -#undef ROTATIONSPEED diff --git a/src/p_inter.c b/src/p_inter.c index 968357096..4dafa91c2 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -237,7 +237,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (!special->target) return; // foolproof crash prevention check!!!!! - P_TeleportMove(player->mo, special->target->x, special->target->y, special->target->z + (48<mo, special->target->x, special->target->y, special->target->z + (48<mo->angle = special->target->angle; P_SetObjectMomZ(player->mo, 12<mo, player->mo->angle, 20<bumpers <= 0) - { - return; - } - special->momx = special->momy = special->momz = 0; P_SetTarget(&special->target, toucher); P_KillMobj(special, toucher, toucher, DMG_NORMAL); break; - case MT_ITEMCAPSULE: - if (special->threshold != KITEM_SUPERRING - && special->threshold != KITEM_SPB - && !P_CanPickupItem(player, 1)) - return; + case MT_SPHEREBOX: + if (player->bumpers <= 0) + return; + P_SetTarget(&special->target, toucher); + P_KillMobj(special, toucher, toucher, DMG_NORMAL); + break; + case MT_ITEMCAPSULE: if ((gametyperules & GTR_BUMPERS) && player->bumpers <= 0) return; if (special->scale < special->extravalue1) // don't break it while it's respawning return; - if (special->threshold == KITEM_SPB && K_IsSPBInGame()) // don't spawn a second SPB - return; + switch (special->threshold) + { + case KITEM_SPB: + if (K_IsSPBInGame()) // don't spawn a second SPB + return; + break; + case KITEM_SUPERRING: + if (player->pflags & PF_RINGLOCK) // no cheaty rings + return; + break; + default: + if (!P_CanPickupItem(player, 1)) + return; + break; + } S_StartSound(toucher, special->info->deathsound); P_KillMobj(special, toucher, toucher, DMG_NORMAL); @@ -502,16 +512,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (!(P_CanPickupItem(player, 0))) return; - // Reached the cap, don't waste 'em! - if (player->spheres >= 40) - return; - - // Not alive - if ((gametyperules & GTR_BUMPERS) && (player->bumpers <= 0)) - return; - - special->momx = special->momy = special->momz = 0; - player->spheres++; + P_GivePlayerSpheres(player, 1); break; // Secret emblem thingy @@ -960,7 +961,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (LUAh_MobjDeath(target, inflictor, source, damagetype) || P_MobjWasRemoved(target)) return; - //K_SetHitLagForObjects(target, inflictor, 15); + //K_SetHitLagForObjects(target, inflictor, MAXHITLAGTICS, true); // SRB2kart // I wish I knew a better way to do this @@ -1247,6 +1248,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget kart->angle = target->angle; kart->color = target->color; kart->hitlag = target->hitlag; + kart->eflags |= MFE_DAMAGEHITLAG; P_SetObjectMomZ(kart, 6*FRACUNIT, false); kart->extravalue1 = target->player->kartweight; } @@ -1737,7 +1739,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, } K_DropEmeraldsFromPlayer(player, player->emeralds); - K_SetHitLagForObjects(player->mo, inflictor, 15); + K_SetHitLagForObjects(player->mo, inflictor, MAXHITLAGTICS, true); player->carry = CR_NONE; @@ -1797,7 +1799,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da player_t *player; boolean force = false; - INT32 laglength = 10; + INT32 laglength = 6; INT32 kinvextend = 0; if (objectplacing) @@ -1816,7 +1818,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (((damagetype & DMG_TYPEMASK) == DMG_STING) || ((inflictor && !P_MobjWasRemoved(inflictor)) && inflictor->type == MT_BANANA && inflictor->health <= 1)) { - laglength = 5; + laglength = 2; } // Everything above here can't be forced. @@ -1972,6 +1974,10 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da // Destroy any remainder bumpers from the player for karma comeback damage K_DestroyBumpers(player, player->bumpers); } + else + { + source->player->overtimekarma += 5*TICRATE; + } if (damagetype & DMG_STEAL) { @@ -1996,6 +2002,8 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da player->sneakertimer = player->numsneakers = 0; player->driftboost = player->strongdriftboost = 0; player->ringboost = 0; + player->glanceDir = 0; + player->pflags &= ~PF_LOOKDOWN; switch (type) { @@ -2048,7 +2056,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } player->instashield = 15; - K_SetHitLagForObjects(target, inflictor, laglength); + K_SetHitLagForObjects(target, inflictor, laglength, true); return true; } } @@ -2070,7 +2078,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da if (source && source->player && target) G_GhostAddHit((INT32) (source->player - players), target); - K_SetHitLagForObjects(target, inflictor, laglength); + K_SetHitLagForObjects(target, inflictor, laglength, true); if (target->health <= 0) { @@ -2078,7 +2086,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return true; } - //K_SetHitLagForObjects(target, inflictor, laglength); + //K_SetHitLagForObjects(target, inflictor, laglength, true); if (player) P_ResetPlayer(target->player); diff --git a/src/p_local.h b/src/p_local.h index 9ade55ce1..bfe8d9e08 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -112,6 +112,10 @@ typedef struct camera_s fixed_t pan; // SRB2Kart: camera pitches on slopes angle_t pitch; + + // Interpolation data + fixed_t old_x, old_y, old_z; + angle_t old_angle, old_aiming; } camera_t; // demo freecam or something before i commit die @@ -171,7 +175,7 @@ void P_RestoreMusic(player_t *player); boolean P_EndingMusic(player_t *player); mobj_t *P_SpawnGhostMobj(mobj_t *mobj); INT32 P_GivePlayerRings(player_t *player, INT32 num_rings); -void P_GivePlayerSpheres(player_t *player, INT32 num_spheres); +INT32 P_GivePlayerSpheres(player_t *player, INT32 num_spheres); void P_GivePlayerLives(player_t *player, INT32 numlives); UINT8 P_GetNextEmerald(void); void P_GiveEmerald(boolean spawnObj); @@ -329,6 +333,7 @@ void P_Attract(mobj_t *source, mobj_t *enemy, boolean nightsgrab); mobj_t *P_GetClosestAxis(mobj_t *source); boolean P_CanRunOnWater(player_t *player, ffloor_t *rover); +boolean P_CheckSolidFFloorSurface(player_t *player, ffloor_t *rover); void P_MaceRotate(mobj_t *center, INT32 baserot, INT32 baseprevrot); @@ -365,8 +370,6 @@ void P_InternalFlickyBubble(mobj_t *actor); void P_InternalFlickyFly(mobj_t *actor, fixed_t flyspeed, fixed_t targetdist, fixed_t chasez); void P_InternalFlickyHop(mobj_t *actor, fixed_t momz, fixed_t momh, angle_t angle); -void P_RefreshItemCapsuleParts(mobj_t *mobj); - // // P_MAP // @@ -398,16 +401,21 @@ void P_SetThingPosition(mobj_t *thing); void P_SetUnderlayPosition(mobj_t *thing); boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing); +boolean P_IsLineTripWire(const line_t *ld); boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y); boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam); +fixed_t P_BaseStepUp(void); +fixed_t P_GetThingStepUp(mobj_t *thing); boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff); boolean P_Move(mobj_t *actor, fixed_t speed); -boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z); +boolean P_SetOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z); +boolean P_MoveOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z); void P_SlideMove(mobj_t *mo); void P_BouncePlayerMove(mobj_t *mo); void P_BounceMove(mobj_t *mo); boolean P_CheckSight(mobj_t *t1, mobj_t *t2); boolean P_TraceBlockingLines(mobj_t *t1, mobj_t *t2); +boolean P_TraceBotTraversal(mobj_t *t1, mobj_t *t2); void P_CheckHoopPosition(mobj_t *hoopthing, fixed_t x, fixed_t y, fixed_t z, fixed_t radius); boolean P_CheckSector(sector_t *sector, boolean crunch); diff --git a/src/p_map.c b/src/p_map.c index 829393d32..28487e2e3 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -96,7 +96,7 @@ camera_t *mapcampointer; // // P_TeleportMove // -boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z) +static boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z) { numspechit = 0U; @@ -130,6 +130,31 @@ boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z) return true; } +// +// P_SetOrigin - P_TeleportMove which RESETS interpolation values. +// +boolean P_SetOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z) +{ + boolean result = P_TeleportMove(thing, x, y, z); + + if (result == true) + { + thing->old_x = thing->x; + thing->old_y = thing->y; + thing->old_z = thing->z; + } + + return result; +} + +// +// P_MoveOrigin - P_TeleportMove which KEEPS interpolation values. +// +boolean P_MoveOrigin(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z) +{ + return P_TeleportMove(thing, x, y, z); +} + // ========================================================================= // MOVEMENT ITERATOR FUNCTIONS // ========================================================================= @@ -206,11 +231,14 @@ static void add_spechit(line_t *ld) numspechit++; } -static boolean P_SpecialIsLinedefCrossType(UINT16 ldspecial) +static boolean P_SpecialIsLinedefCrossType(line_t *ld) { boolean linedefcrossspecial = false; - switch (ldspecial) + if (P_IsLineTripWire(ld)) + return true; + + switch (ld->special) { case 2001: // Finish line case 2003: // Respawn line @@ -282,6 +310,9 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) if (spring->eflags & MFE_VERTICALFLIP) vertispeed *= -1; + if ((spring->eflags ^ object->eflags) & MFE_VERTICALFLIP) + vertispeed *= 2; + // Vertical springs teleport you on TOP of them. if (vertispeed > 0) { @@ -345,28 +376,6 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) } } - if (object->player) - { - // Less friction when hitting horizontal springs - if (!vertispeed) - { - if (!object->player->tiregrease) - { - UINT8 i; - for (i = 0; i < 2; i++) - { - mobj_t *grease; - grease = P_SpawnMobj(object->x, object->y, object->z, MT_TIREGREASE); - P_SetTarget(&grease->target, object); - grease->angle = K_MomentumAngle(object); - grease->extravalue1 = i; - } - } - - object->player->tiregrease = greasetics; //FixedMul(greasetics << FRACBITS, finalSpeed/72) >> FRACBITS - } - } - // Horizontal speed is used as a minimum thrust, not a direct replacement finalSpeed = max(objectSpeed, finalSpeed); @@ -389,6 +398,22 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) object->player->springstars = max(vertispeed, horizspeed) / FRACUNIT / 2; object->player->springcolor = starcolor; + + // Less friction when hitting springs + if (!object->player->tiregrease) + { + UINT8 i; + for (i = 0; i < 2; i++) + { + mobj_t *grease; + grease = P_SpawnMobj(object->x, object->y, object->z, MT_TIREGREASE); + P_SetTarget(&grease->target, object); + grease->angle = K_MomentumAngle(object); + grease->extravalue1 = i; + } + + object->player->tiregrease = greasetics; //FixedMul(greasetics << FRACBITS, finalSpeed/72) >> FRACBITS + } } return true; @@ -485,6 +510,10 @@ static boolean PIT_CheckThing(mobj_t *thing) || (thing->player && thing->player->spectator)) return true; + // Ignore the collision if BOTH things are in hitlag. + if (thing->hitlag > 0 && tmthing->hitlag > 0) + return true; + if ((thing->flags & MF_NOCLIPTHING) || !(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE|MF_SPRING))) return true; @@ -1554,6 +1583,11 @@ boolean P_IsLineBlocking(const line_t *ld, const mobj_t *thing) } } +boolean P_IsLineTripWire(const line_t *ld) +{ + return ld->tripwire; +} + // // PIT_CheckLine // Adjusts tmfloorz and tmceilingz as lines are contacted @@ -1592,7 +1626,7 @@ static boolean PIT_CheckLine(line_t *ld) cosradius = FixedMul(dist, FINECOSINE(langle>>ANGLETOFINESHIFT)); sinradius = FixedMul(dist, FINESINE(langle>>ANGLETOFINESHIFT)); tmthing->flags |= MF_NOCLIP; - P_TeleportMove(tmthing, result.x + cosradius - tmthing->momx, result.y + sinradius - tmthing->momy, tmthing->z); + P_MoveOrigin(tmthing, result.x + cosradius - tmthing->momx, result.y + sinradius - tmthing->momy, tmthing->z); tmthing->flags &= ~MF_NOCLIP; } #endif @@ -1668,7 +1702,7 @@ static boolean PIT_CheckLine(line_t *ld) tmdropoffz = lowfloor; // we've crossed the line - if (P_SpecialIsLinedefCrossType(ld->special)) + if (P_SpecialIsLinedefCrossType(ld)) { add_spechit(ld); } @@ -1817,7 +1851,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) continue; } - if (thing->player && P_CheckSolidLava(rover)) + if (thing->player && P_CheckSolidFFloorSurface(thing->player, rover)) ; else if (thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE)) ; @@ -2383,6 +2417,56 @@ boolean PIT_PushableMoved(mobj_t *thing) return true; } +static boolean P_WaterRunning(mobj_t *thing) +{ + ffloor_t *rover = thing->floorrover; + return rover && (rover->flags & FF_SWIMMABLE) && + P_IsObjectOnGround(thing); +} + +static boolean P_WaterStepUp(mobj_t *thing) +{ + player_t *player = thing->player; + return (player && player->waterskip) || + P_WaterRunning(thing); +} + +fixed_t P_BaseStepUp(void) +{ + return FixedMul(MAXSTEPMOVE, mapobjectscale); +} + +fixed_t P_GetThingStepUp(mobj_t *thing) +{ + const fixed_t maxstepmove = P_BaseStepUp(); + fixed_t maxstep = maxstepmove; + + if (thing->type == MT_SKIM) + { + // Skim special (not needed for kart?) + return 0; + } + + if (P_WaterStepUp(thing) == true) + { + // Add some extra stepmove when waterskipping + maxstep += maxstepmove; + } + + if (P_MobjTouchingSectorSpecial(thing, 1, 13, false)) + { + // If using type Section1:13, double the maxstep. + maxstep <<= 1; + } + else if (P_MobjTouchingSectorSpecial(thing, 1, 12, false)) + { + // If using type Section1:12, no maxstep. For short walls, like Egg Zeppelin + maxstep = 0; + } + + return maxstep; +} + // // P_TryMove // Attempt to move to a new position. @@ -2408,11 +2492,13 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (radius < mapobjectscale) radius = mapobjectscale; +#if 0 if (thing->hitlag > 0) { // Do not move during hitlag return false; } +#endif do { if (thing->flags & MF_NOCLIP) { @@ -2442,21 +2528,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (!(thing->flags & MF_NOCLIP)) { //All things are affected by their scale. - const fixed_t maxstepmove = FixedMul(MAXSTEPMOVE, mapobjectscale); - fixed_t maxstep = maxstepmove; - - if (thing->player && thing->player->waterskip) - maxstep += maxstepmove; // Add some extra stepmove when waterskipping - - // If using type Section1:13, double the maxstep. - if (P_MobjTouchingSectorSpecial(thing, 1, 13, false)) - maxstep <<= 1; - // If using type Section1:12, no maxstep. For short walls, like Egg Zeppelin - else if (P_MobjTouchingSectorSpecial(thing, 1, 12, false)) - maxstep = 0; - - if (thing->type == MT_SKIM) - maxstep = 0; + fixed_t maxstep = P_GetThingStepUp(thing); if (tmceilingz - tmfloorz < thing->height) { @@ -2660,10 +2732,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) oldside = P_PointOnLineSide(oldx, oldy, ld); if (side != oldside) { - if (ld->special) - { - P_CrossSpecialLine(ld, oldside, thing); - } + P_CrossSpecialLine(ld, oldside, thing); } } } @@ -2696,7 +2765,7 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y) if (!(thing->flags & MF_NOCLIP)) { - const fixed_t maxstep = FixedMul(MAXSTEPMOVE, mapobjectscale); + const fixed_t maxstep = P_BaseStepUp(); if (tmceilingz - tmfloorz < thing->height) return false; // doesn't fit @@ -2745,7 +2814,7 @@ static boolean PTR_GetSpecialLines(intercept_t *in) return true; } - if (P_SpecialIsLinedefCrossType(ld->special)) + if (P_SpecialIsLinedefCrossType(ld)) { add_spechit(ld); } @@ -2815,10 +2884,7 @@ void P_HitSpecialLines(mobj_t *thing, fixed_t x, fixed_t y, fixed_t momx, fixed_ oldside = P_PointOnLineSide(x, y, ld); if (side != oldside) { - if (ld->special) - { - P_CrossSpecialLine(ld, oldside, thing); - } + P_CrossSpecialLine(ld, oldside, thing); } } } @@ -3022,6 +3088,7 @@ static void P_PlayerHitBounceLine(line_t *ld) INT32 side; angle_t lineangle; fixed_t movelen; + fixed_t x, y; side = P_PointOnLineSide(slidemo->x, slidemo->y, ld); lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy)-ANGLE_90; @@ -3036,8 +3103,19 @@ static void P_PlayerHitBounceLine(line_t *ld) if (slidemo->player && movelen < (15*mapobjectscale)) movelen = (15*mapobjectscale); - tmxmove += FixedMul(movelen, FINECOSINE(lineangle)); - tmymove += FixedMul(movelen, FINESINE(lineangle)); + x = FixedMul(movelen, FINECOSINE(lineangle)); + y = FixedMul(movelen, FINESINE(lineangle)); + + if (P_IsLineTripWire(ld)) + { + tmxmove = x * 4; + tmymove = y * 4; + } + else + { + tmxmove += x; + tmymove += y; + } } // @@ -3149,7 +3227,7 @@ static boolean PTR_LineIsBlocking(line_t *li) if (opentop - slidemo->z < slidemo->height) return true; // mobj is too high - if (openbottom - slidemo->z > FixedMul(MAXSTEPMOVE, mapobjectscale)) + if (openbottom - slidemo->z > P_GetThingStepUp(slidemo)) return true; // too big a step up return false; @@ -3675,15 +3753,13 @@ void P_BouncePlayerMove(mobj_t *mo) tmymove = FixedMul(mmomy, (FRACUNIT - (FRACUNIT>>2) - (FRACUNIT>>3))); } + if (P_IsLineTripWire(bestslideline)) { - mobj_t *fx = P_SpawnMobj(mo->x, mo->y, mo->z, MT_BUMP); - if (mo->eflags & MFE_VERTICALFLIP) - fx->eflags |= MFE_VERTICALFLIP; - else - fx->eflags &= ~MFE_VERTICALFLIP; - fx->scale = mo->scale; - - S_StartSound(mo, sfx_s3k49); + K_ApplyTripWire(mo->player, TRIP_BLOCKED); + } + else + { + K_SpawnBumpEffect(mo); } P_PlayerHitBounceLine(bestslideline); @@ -3694,8 +3770,11 @@ void P_BouncePlayerMove(mobj_t *mo) mo->player->cmomx = tmxmove; mo->player->cmomy = tmymove; - if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true)) { - P_TryMove(mo, mo->x - oldmomx, mo->y - oldmomy, true); + if (!P_IsLineTripWire(bestslideline)) + { + if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true)) { + P_TryMove(mo, mo->x - oldmomx, mo->y - oldmomy, true); + } } } diff --git a/src/p_maputl.c b/src/p_maputl.c index 5cf2e81fe..5acddf09c 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -15,6 +15,7 @@ #include "doomdef.h" #include "doomstat.h" +#include "k_kart.h" #include "p_local.h" #include "r_main.h" #include "r_data.h" @@ -588,7 +589,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) if (mobj) { // Check for collision with front side's midtexture if Effect 4 is set - if (linedef->flags & ML_EFFECT4 + if ((linedef->flags & ML_EFFECT4 || (mobj->player && P_IsLineTripWire(linedef) && !K_TripwirePass(mobj->player))) && !linedef->polyobj // don't do anything for polyobjects! ...for now ) { side_t *side = &sides[linedef->sidenum[0]]; @@ -729,7 +730,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) if (!(rover->flags & FF_EXISTS)) continue; - if (mobj->player && P_CheckSolidLava(rover)) + if (mobj->player && P_CheckSolidFFloorSurface(mobj->player, rover)) ; else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player) || (rover->flags & FF_BLOCKOTHERS && !mobj->player))) @@ -771,7 +772,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) if (!(rover->flags & FF_EXISTS)) continue; - if (mobj->player && P_CheckSolidLava(rover)) + if (mobj->player && P_CheckSolidFFloorSurface(mobj->player, rover)) ; else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player) || (rover->flags & FF_BLOCKOTHERS && !mobj->player))) diff --git a/src/p_mobj.c b/src/p_mobj.c index 17f526063..3cd2d22ca 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1879,7 +1879,7 @@ void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype) topheight = P_GetFOFTopZ(mo, sector, rover, mo->x, mo->y, NULL); bottomheight = P_GetFOFBottomZ(mo, sector, rover, mo->x, mo->y, NULL); - if (mo->player && P_CheckSolidLava(rover)) // only the player should stand on lava + if (mo->player && P_CheckSolidFFloorSurface(mo->player, rover)) // only the player should stand on lava or run on water ; else if (motype != 0 && rover->flags & FF_SWIMMABLE) // "scenery" only continue; @@ -2295,7 +2295,7 @@ boolean P_ZMovement(mobj_t *mo) S_StartSound(mo, sfx_tink); } else - mo->flags2 ^= RF_DONTDRAW; + mo->renderflags ^= RF_DONTDRAW; } else if (mo->type == MT_DEBTSPIKE) { @@ -2775,6 +2775,15 @@ void P_PlayerZMovement(mobj_t *mo) P_CheckMarioBlocks(mo); mo->momz = 0; + P_CheckGravity(mo, true); + + if (abs(mo->momz) < 15 * mapobjectscale) + { + mo->momz = 15 * mapobjectscale + * -(P_MobjFlip(mo)); + } + + K_SpawnBumpEffect(mo); } } } @@ -2931,6 +2940,33 @@ boolean P_SceneryZMovement(mobj_t *mo) return true; } +// P_CanRunOnWater +// +// Returns true if player can waterrun on the 3D floor +// +boolean P_CanRunOnWater(player_t *player, ffloor_t *rover) +{ + boolean flip = player->mo->eflags & MFE_VERTICALFLIP; + fixed_t surfaceheight = flip ? player->mo->waterbottom : player->mo->watertop; + fixed_t playerbottom = flip ? (player->mo->z + player->mo->height) : player->mo->z; + fixed_t clip = flip ? (surfaceheight - playerbottom) : (playerbottom - surfaceheight); + fixed_t span = player->mo->watertop - player->mo->waterbottom; + + return + clip > -(player->mo->height / 2) && + span > player->mo->height && + player->speed / 5 > abs(player->mo->momz) && + player->speed > K_GetKartSpeed(player, false) && + K_WaterRun(player) && + (rover->flags & FF_SWIMMABLE); +} + +boolean P_CheckSolidFFloorSurface(player_t *player, ffloor_t *rover) +{ + return P_CheckSolidLava(rover) || + P_CanRunOnWater(player, rover); +} + // // P_MobjCheckWater // @@ -2946,7 +2982,10 @@ void P_MobjCheckWater(mobj_t *mobj) ffloor_t *rover; player_t *p = mobj->player; // Will just be null if not a player. fixed_t height = mobj->height; + fixed_t halfheight = height / 2; boolean wasgroundpounding = false; + fixed_t top2 = P_GetSectorCeilingZAt(sector, mobj->x, mobj->y); + fixed_t bot2 = P_GetSectorFloorZAt(sector, mobj->x, mobj->y); // Default if no water exists. mobj->watertop = mobj->waterbottom = mobj->z - 1000*FRACUNIT; @@ -2957,24 +2996,31 @@ void P_MobjCheckWater(mobj_t *mobj) for (rover = sector->ffloors; rover; rover = rover->next) { fixed_t topheight, bottomheight; - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) - || (((rover->flags & FF_BLOCKPLAYER) && mobj->player) - || ((rover->flags & FF_BLOCKOTHERS) && !mobj->player))) - continue; topheight = P_GetFFloorTopZAt (rover, mobj->x, mobj->y); bottomheight = P_GetFFloorBottomZAt(rover, mobj->x, mobj->y); + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) + || (((rover->flags & FF_BLOCKPLAYER) && mobj->player) + || ((rover->flags & FF_BLOCKOTHERS) && !mobj->player))) + { + if (topheight < top2 && topheight > thingtop) + top2 = topheight; + if (bottomheight > bot2 && bottomheight < mobj->z) + bot2 = bottomheight; + continue; + } + if (mobj->eflags & MFE_VERTICALFLIP) { - if (topheight < (thingtop - (height>>1)) - || bottomheight > thingtop) + if (topheight < (thingtop - halfheight) + || bottomheight > (thingtop + halfheight)) continue; } else { - if (topheight < mobj->z - || bottomheight > (mobj->z + (height>>1))) + if (topheight < (mobj->z - halfheight) + || bottomheight > (mobj->z + halfheight)) continue; } @@ -3002,19 +3048,87 @@ void P_MobjCheckWater(mobj_t *mobj) } } + if (mobj->watertop > top2) + mobj->watertop = top2; + + if (mobj->waterbottom < bot2) + mobj->waterbottom = bot2; + // Spectators and dead players don't get to do any of the things after this. if (p && (p->spectator || p->playerstate != PST_LIVE)) return; // The rest of this code only executes on a water state change. - if (waterwasnotset || !!(mobj->eflags & MFE_UNDERWATER) == wasinwater) + if (!!(mobj->eflags & MFE_UNDERWATER) == wasinwater) return; + if (p && !p->waterskip && + p->curshield != KSHIELD_BUBBLE && wasinwater) + { + S_StartSound(mobj, sfx_s3k38); + } + if ((p) // Players || (mobj->flags & MF_PUSHABLE) // Pushables || ((mobj->info->flags & MF_PUSHABLE) && mobj->fuse) // Previously pushable, might be moving still ) { + // Time to spawn the bubbles! + { + INT32 i; + INT32 bubblecount; + UINT8 prandom[4]; + mobj_t *bubble; + mobjtype_t bubbletype; + + if (mobj->eflags & MFE_GOOWATER || wasingoo) + S_StartSound(mobj, sfx_ghit); + else if (mobj->eflags & MFE_TOUCHLAVA) + S_StartSound(mobj, sfx_splash); + else + S_StartSound(mobj, sfx_splish); // And make a sound! + + bubblecount = FixedDiv(abs(mobj->momz), mobj->scale)>>(FRACBITS-1); + // Max bubble count + if (bubblecount > 128) + bubblecount = 128; + + // Create tons of bubbles + for (i = 0; i < bubblecount; i++) + { + // P_RandomByte()s are called individually to allow consistency + // across various compilers, since the order of function calls + // in C is not part of the ANSI specification. + prandom[0] = P_RandomByte(); + prandom[1] = P_RandomByte(); + prandom[2] = P_RandomByte(); + prandom[3] = P_RandomByte(); + + bubbletype = MT_SMALLBUBBLE; + if (!(prandom[0] & 0x3)) // medium bubble chance up to 64 from 32 + bubbletype = MT_MEDIUMBUBBLE; + + bubble = P_SpawnMobj( + mobj->x + FixedMul((prandom[1]<<(FRACBITS-3)) * (prandom[0]&0x80 ? 1 : -1), mobj->scale), + mobj->y + FixedMul((prandom[2]<<(FRACBITS-3)) * (prandom[0]&0x40 ? 1 : -1), mobj->scale), + mobj->z + FixedMul((prandom[3]<<(FRACBITS-2)), mobj->scale), bubbletype); + + if (bubble) + { + if (P_MobjFlip(mobj)*mobj->momz < 0) + bubble->momz = mobj->momz >> 4; + else + bubble->momz = 0; + + bubble->destscale = mobj->scale; + P_SetScale(bubble, mobj->scale); + } + } + } + + if (waterwasnotset) + return; + // Check to make sure you didn't just cross into a sector to jump out of // that has shallower water than the block you were originally in. if ((!(mobj->eflags & MFE_VERTICALFLIP) && mobj->watertop-mobj->floorz <= height>>1) @@ -3099,59 +3213,6 @@ void P_MobjCheckWater(mobj_t *mobj) P_SetScale(splish, mobj->scale); } } - - // Time to spawn the bubbles! - { - INT32 i; - INT32 bubblecount; - UINT8 prandom[4]; - mobj_t *bubble; - mobjtype_t bubbletype; - - if (mobj->eflags & MFE_GOOWATER || wasingoo) - S_StartSound(mobj, sfx_ghit); - else if (mobj->eflags & MFE_TOUCHLAVA) - S_StartSound(mobj, sfx_splash); - else - S_StartSound(mobj, sfx_splish); // And make a sound! - - bubblecount = FixedDiv(abs(mobj->momz), mobj->scale)>>(FRACBITS-1); - // Max bubble count - if (bubblecount > 128) - bubblecount = 128; - - // Create tons of bubbles - for (i = 0; i < bubblecount; i++) - { - // P_RandomByte()s are called individually to allow consistency - // across various compilers, since the order of function calls - // in C is not part of the ANSI specification. - prandom[0] = P_RandomByte(); - prandom[1] = P_RandomByte(); - prandom[2] = P_RandomByte(); - prandom[3] = P_RandomByte(); - - bubbletype = MT_SMALLBUBBLE; - if (!(prandom[0] & 0x3)) // medium bubble chance up to 64 from 32 - bubbletype = MT_MEDIUMBUBBLE; - - bubble = P_SpawnMobj( - mobj->x + FixedMul((prandom[1]<<(FRACBITS-3)) * (prandom[0]&0x80 ? 1 : -1), mobj->scale), - mobj->y + FixedMul((prandom[2]<<(FRACBITS-3)) * (prandom[0]&0x40 ? 1 : -1), mobj->scale), - mobj->z + FixedMul((prandom[3]<<(FRACBITS-2)), mobj->scale), bubbletype); - - if (bubble) - { - if (P_MobjFlip(mobj)*mobj->momz < 0) - bubble->momz = mobj->momz >> 4; - else - bubble->momz = 0; - - bubble->destscale = mobj->scale; - P_SetScale(bubble, mobj->scale); - } - } - } } } @@ -3511,6 +3572,16 @@ static void P_CheckFloatbobPlatforms(mobj_t *mobj) } } +static void P_SquishThink(mobj_t *mobj) +{ + if (!(mobj->eflags & MFE_SLOPELAUNCHED)) + { + K_Squish(mobj); + } + + mobj->lastmomz = mobj->momz; +} + static void P_PlayerMobjThinker(mobj_t *mobj) { I_Assert(mobj != NULL); @@ -3576,6 +3647,8 @@ static void P_PlayerMobjThinker(mobj_t *mobj) mobj->eflags &= ~MFE_JUSTHITFLOOR; } + P_SquishThink(mobj); + animonly: P_CyclePlayerMobjState(mobj); } @@ -3636,6 +3709,14 @@ void P_NullPrecipThinker(precipmobj_t *mobj) void P_PrecipThinker(precipmobj_t *mobj) { + // reset old state (for interpolation) + mobj->old_x = mobj->x; + mobj->old_y = mobj->y; + mobj->old_z = mobj->z; + mobj->old_angle = mobj->angle; + mobj->old_pitch = mobj->pitch; + mobj->old_roll = mobj->roll; + P_CycleStateAnimation((mobj_t *)mobj); if (mobj->state == &states[S_RAINRETURN]) @@ -3781,8 +3862,12 @@ static void P_ItemCapsulePartThinker(mobj_t *mobj) P_SetScale(mobj, mobj->destscale = targetScale); // find z position - K_GenericExtraFlagsNoZAdjust(mobj, target); - if (mobj->flags & MFE_VERTICALFLIP) + if (mobj->flags2 & MF2_CLASSICPUSH) // centered items should not be flipped + mobj->renderflags = (mobj->renderflags & ~RF_DONTDRAW) | (target->renderflags & RF_DONTDRAW); + else + K_GenericExtraFlagsNoZAdjust(mobj, target); + + if (mobj->eflags & MFE_VERTICALFLIP) z = target->z + target->height - mobj->height - FixedMul(mobj->scale, mobj->movefactor); else z = target->z + FixedMul(mobj->scale, mobj->movefactor); @@ -3790,15 +3875,202 @@ static void P_ItemCapsulePartThinker(mobj_t *mobj) // rotate & move to capsule mobj->angle += mobj->movedir; if (mobj->flags2 & MF2_CLASSICPUSH) // centered - P_TeleportMove(mobj, target->x, target->y, z); + P_MoveOrigin(mobj, target->x, target->y, z); else - P_TeleportMove(mobj, + P_MoveOrigin(mobj, target->x + P_ReturnThrustX(mobj, mobj->angle + ANGLE_90, mobj->radius), target->y + P_ReturnThrustY(mobj, mobj->angle + ANGLE_90, mobj->radius), z); } } +static void P_RefreshItemCapsuleParts(mobj_t *mobj) +{ + UINT8 numNumbers = 0; + INT32 count = 0; + INT32 itemType = mobj->threshold; + mobj_t *part; + skincolornum_t color; + UINT32 newRenderFlags = 0; + boolean colorized; + + if (itemType < 1 || itemType >= NUMKARTITEMS) + itemType = KITEM_SAD; + + // update invincibility properties + if (itemType == KITEM_INVINCIBILITY) + { + mobj->renderflags = (mobj->renderflags & ~RF_BRIGHTMASK) | RF_FULLBRIGHT; + mobj->colorized = true; + } + else + { + mobj->renderflags = (mobj->renderflags & ~RF_BRIGHTMASK) | RF_SEMIBRIGHT; + mobj->color = SKINCOLOR_NONE; + mobj->colorized = false; + } + + // update cap colors + if (itemType == KITEM_SUPERRING) + { + color = SKINCOLOR_GOLD; + newRenderFlags |= RF_SEMIBRIGHT; + } + else if (mobj->spawnpoint && (mobj->spawnpoint->options & MTF_EXTRA)) + color = SKINCOLOR_SAPPHIRE; + else if (itemType == KITEM_SPB) + color = SKINCOLOR_JET; + else + color = SKINCOLOR_NONE; + + colorized = (color != SKINCOLOR_NONE); + part = mobj; + while (!P_MobjWasRemoved(part->hnext)) + { + part = part->hnext; + part->color = color; + part->colorized = colorized; + part->renderflags = (part->renderflags & ~RF_BRIGHTMASK) | newRenderFlags; + } + + // update inside item frame + part = mobj->tracer; + if (P_MobjWasRemoved(part)) + return; + + part->threshold = mobj->threshold; + part->movecount = mobj->movecount; + + switch (itemType) + { + case KITEM_ORBINAUT: + part->sprite = SPR_ITMO; + part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetOrbinautItemFrame(mobj->movecount); + break; + case KITEM_INVINCIBILITY: + part->sprite = SPR_ITMI; + part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|K_GetInvincibilityItemFrame(); + break; + case KITEM_SAD: + part->sprite = SPR_ITEM; + part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE; + break; + default: + part->sprite = SPR_ITEM; + part->frame = FF_FULLBRIGHT|FF_PAPERSPRITE|(itemType); + break; + } + + // update number frame + if (K_GetShieldFromItem(itemType) != KSHIELD_NONE) // shields don't stack, so don't show a number + ; + else + { + switch (itemType) + { + case KITEM_ORBINAUT: // only display the number when the sprite no longer changes + if (mobj->movecount - 1 > K_GetOrbinautItemFrame(mobj->movecount)) + count = mobj->movecount; + break; + case KITEM_SUPERRING: // always display the number, and multiply it by 5 + count = mobj->movecount * 5; + break; + case KITEM_SAD: // never display the number + case KITEM_SPB: + break; + default: + if (mobj->movecount > 1) + count = mobj->movecount; + break; + } + } + + while (count > 0) + { + if (P_MobjWasRemoved(part->tracer)) + { + P_SetTarget(&part->tracer, P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_OVERLAY)); + P_SetTarget(&part->tracer->target, part); + P_SetMobjState(part->tracer, S_INVISIBLE); + part->tracer->spriteyoffset = 10*FRACUNIT; + part->tracer->spritexoffset = 13*numNumbers*FRACUNIT; + } + part = part->tracer; + part->sprite = SPR_ITMN; + part->frame = FF_FULLBRIGHT|(count % 10); + count /= 10; + numNumbers++; + } + + // delete any extra overlays (I guess in case the number changes?) + if (part->tracer) + { + P_RemoveMobj(part->tracer); + P_SetTarget(&part->tracer, NULL); + } +} + +#define CAPSULESIDES 5 +#define ANG_CAPSULE (UINT32_MAX / CAPSULESIDES) +#define ROTATIONSPEED (2*ANG2) +static void P_SpawnItemCapsuleParts(mobj_t *mobj) +{ + UINT8 i; + mobj_t *part; + fixed_t buttScale = 0; + statenum_t buttState = S_ITEMCAPSULE_BOTTOM_SIDE_AIR; + angle_t spin = ANGLE_MAX - ROTATIONSPEED; + + if (P_IsObjectOnGround(mobj)) + { + buttScale = 13*FRACUNIT/10; + buttState = S_ITEMCAPSULE_BOTTOM_SIDE_GROUND; + spin = 0; + } + + // inside item + part = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_ITEMCAPSULE_PART); + P_SetTarget(&part->target, mobj); + P_SetMobjState(part, S_ITEMICON); + part->movedir = ROTATIONSPEED; // rotation speed + part->extravalue1 = 175*FRACUNIT/100; // relative scale + part->flags2 |= MF2_CLASSICPUSH; // classicpush = centered horizontally + part->flags2 &= ~MF2_OBJECTFLIP; // centered item should not be flipped + part->eflags &= ~MFE_VERTICALFLIP; + P_SetTarget(&mobj->tracer, part); // pointer to this item, so we can modify its sprite/frame + + // capsule caps + part = mobj; + for (i = 0; i < CAPSULESIDES; i++) + { + // a bottom side + P_SetTarget(&part->hnext, P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_ITEMCAPSULE_PART)); + P_SetTarget(&part->hnext->hprev, part); + part = part->hnext; + P_SetTarget(&part->target, mobj); + P_SetMobjState(part, buttState); + part->angle = i * ANG_CAPSULE; + part->movedir = spin; // rotation speed + part->movefactor = 0; // z offset + part->extravalue1 = buttScale; // relative scale + + // a top side + P_SetTarget(&part->hnext, P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_ITEMCAPSULE_PART)); + P_SetTarget(&part->hnext->hprev, part); + part = part->hnext; + P_SetTarget(&part->target, mobj); + P_SetMobjState(part, S_ITEMCAPSULE_TOP_SIDE); + part->angle = i * ANG_CAPSULE; + part->movedir = spin; // rotation speed + part->movefactor = mobj->info->height - part->info->height; // z offset + } + + P_RefreshItemCapsuleParts(mobj); +} +#undef CAPSULESIDES +#undef ANG_CAPSULE +#undef ROTATIONSPEED + // // P_BossTargetPlayer // If closest is true, find the closest player. @@ -3832,7 +4104,7 @@ boolean P_BossTargetPlayer(mobj_t *actor, boolean closest) player = &players[actor->lastlook]; - if (player->bot || player->spectator) + if (player->spectator) continue; // ignore notarget if (!player->mo || P_MobjWasRemoved(player->mo)) @@ -4211,7 +4483,7 @@ void P_Attract(mobj_t *source, mobj_t *dest, boolean nightsgrab) // Home in on y if (dist < source->movefactor) { source->momx = source->momy = source->momz = 0; - P_TeleportMove(source, tx, ty, tz); + P_MoveOrigin(source, tx, ty, tz); } else { @@ -6153,6 +6425,14 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->z -= (mobj->height - oldHeight); } + // spawn parts if not done yet + // (this SHOULD be done when the capsule is spawned, but gravflip isn't set up at that point) + if (!(mobj->flags2 & MF2_JUSTATTACKED)) + { + mobj->flags2 |= MF2_JUSTATTACKED; + P_SpawnItemCapsuleParts(mobj); + } + // update & animate capsule if (!P_MobjWasRemoved(mobj->tracer)) { @@ -6542,7 +6822,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->angle += ANGLE_90; } - P_TeleportMove(mobj, + P_MoveOrigin(mobj, mobj->target->x + P_ReturnThrustX(mobj, angle + ANGLE_180, nudge), mobj->target->y + P_ReturnThrustY(mobj, angle + ANGLE_180, nudge), mobj->target->z); @@ -6621,7 +6901,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) } mobj->angle = mobj->target->angle; - P_TeleportMove(mobj, mobj->target->x + P_ReturnThrustX(mobj, mobj->angle+ANGLE_180, mobj->target->radius), + P_MoveOrigin(mobj, mobj->target->x + P_ReturnThrustX(mobj, mobj->angle+ANGLE_180, mobj->target->radius), mobj->target->y + P_ReturnThrustY(mobj, mobj->angle+ANGLE_180, mobj->target->radius), mobj->target->z); P_SetScale(mobj, mobj->target->scale); @@ -6673,7 +6953,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) P_RemoveMobj(mobj); return false; } - P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z); + P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z); break; case MT_BRAKEDRIFT: if ((!mobj->target || !mobj->target->health || !mobj->target->player || !P_IsObjectOnGround(mobj->target)) @@ -6694,7 +6974,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) newx = mobj->target->x + P_ReturnThrustX(mobj->target, travelangle+ANGLE_180, 24*mobj->target->scale); newy = mobj->target->y + P_ReturnThrustY(mobj->target, travelangle+ANGLE_180, 24*mobj->target->scale); - P_TeleportMove(mobj, newx, newy, mobj->target->z); + P_MoveOrigin(mobj, newx, newy, mobj->target->z); mobj->angle = travelangle - ((ANGLE_90/5)*mobj->target->player->drift); P_SetScale(mobj, (mobj->destscale = mobj->target->scale)); @@ -6723,7 +7003,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) { mobj->fuse = 9; } - P_TeleportMove(mobj, mobj->target->x, + P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z); mobj->angle = mobj->target->angle + mobj->cusval; break; @@ -6733,7 +7013,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) P_RemoveMobj(mobj); return false; } - P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z); + P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z); break; case MT_INSTASHIELDB: mobj->renderflags ^= RF_DONTDRAW; @@ -6745,7 +7025,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) P_RemoveMobj(mobj); return false; } - P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z); + P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z); K_MatchGenericExtraFlags(mobj, mobj->target); break; case MT_BATTLEPOINT: @@ -6768,7 +7048,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->movefactor = mobj->target->height; } K_MatchGenericExtraFlags(mobj, mobj->target); - P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z + (mobj->target->height/2) + mobj->movefactor); + P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z + (mobj->target->height/2) + mobj->movefactor); break; case MT_RINGSPARKS: if (!mobj->target || P_MobjWasRemoved(mobj->target)) @@ -6781,9 +7061,53 @@ static boolean P_MobjRegularThink(mobj_t *mobj) K_MatchGenericExtraFlags(mobj, mobj->target); - P_TeleportMove(mobj, mobj->target->x + FINECOSINE(mobj->angle >> ANGLETOFINESHIFT), + P_MoveOrigin(mobj, mobj->target->x + FINECOSINE(mobj->angle >> ANGLETOFINESHIFT), mobj->target->y + FINESINE(mobj->angle >> ANGLETOFINESHIFT), - mobj->z + mobj->target->height * P_MobjFlip(mobj)); + mobj->z + (mobj->target->height * P_MobjFlip(mobj))); + break; + case MT_GAINAX: + if (!mobj->target || P_MobjWasRemoved(mobj->target) // sanity + || !mobj->target->player // ditto + || !mobj->target->player->glanceDir // still glancing? + || mobj->target->player->aizdriftturn // only other circumstance where can glance + || ((K_GetKartButtons(mobj->target->player) & BT_LOOKBACK) != BT_LOOKBACK)) // it's a lookback indicator... + { + P_RemoveMobj(mobj); + return false; + } + + mobj->angle = mobj->target->player->drawangle; + mobj->z = mobj->target->z; + + K_MatchGenericExtraFlags(mobj, mobj->target); + mobj->renderflags = (mobj->renderflags & ~RF_DONTDRAW)|K_GetPlayerDontDrawFlag(mobj->target->player); + + P_MoveOrigin(mobj, mobj->target->x + FixedMul(34 * mapobjectscale, FINECOSINE((mobj->angle + mobj->movedir) >> ANGLETOFINESHIFT)), + mobj->target->y + FixedMul(34 * mapobjectscale, FINESINE((mobj->angle + mobj->movedir) >> ANGLETOFINESHIFT)), + mobj->z + (32 * mapobjectscale * P_MobjFlip(mobj))); + + { + statenum_t gainaxstate = mobj->state-states; + if (gainaxstate == S_GAINAX_TINY) + { + if (abs(mobj->target->player->glanceDir) > 1) + { + if (mobj->target->player->itemamount && mobj->target->player->itemtype) + gainaxstate = S_GAINAX_HUGE; + else + gainaxstate = S_GAINAX_MID1; + P_SetMobjState(mobj, gainaxstate); + } + } + else if (abs(mobj->target->player->glanceDir) <= 1) + { + if (mobj->flags2 & MF2_AMBUSH) + mobj->flags2 &= ~MF2_AMBUSH; + else + P_SetMobjState(mobj, S_GAINAX_TINY); + } + } + break; case MT_FLAMESHIELDPAPER: if (!mobj->target || P_MobjWasRemoved(mobj->target)) @@ -6801,7 +7125,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) fixed_t newx = mobj->target->x + P_ReturnThrustX(NULL, mobj->target->angle + perpendicular, 8*mobj->target->scale); fixed_t newy = mobj->target->y + P_ReturnThrustY(NULL, mobj->target->angle + perpendicular, 8*mobj->target->scale); - P_TeleportMove(mobj, newx, newy, mobj->target->z); + P_MoveOrigin(mobj, newx, newy, mobj->target->z); if (mobj->extravalue1 & 1) mobj->angle = mobj->target->angle - ANGLE_45; @@ -6839,12 +7163,15 @@ static boolean P_MobjRegularThink(mobj_t *mobj) else ang = (signed)(ang + off); - P_TeleportMove(mobj, + P_MoveOrigin(mobj, mobj->target->x - FixedMul(mobj->target->radius, FINECOSINE(ang >> ANGLETOFINESHIFT)), mobj->target->y - FixedMul(mobj->target->radius, FINESINE(ang >> ANGLETOFINESHIFT)), z); mobj->angle = ang; + if (!P_IsObjectOnGround(mobj->target)) + mobj->renderflags |= RF_DONTDRAW; + if (leveltime & 1) mobj->renderflags |= RF_DONTDRAW; @@ -6891,7 +7218,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) desty = mobj->target->y; } - P_TeleportMove(mobj, destx, desty, mobj->target->z); + P_MoveOrigin(mobj, destx, desty, mobj->target->z); break; } case MT_BUBBLESHIELD: @@ -7019,7 +7346,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) desty = mobj->target->y; } - P_TeleportMove(mobj, destx, desty, mobj->target->z); + P_MoveOrigin(mobj, destx, desty, mobj->target->z); break; } case MT_FLAMESHIELD: @@ -7127,7 +7454,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) desty = mobj->target->y; } - P_TeleportMove(mobj, destx, desty, mobj->target->z); + P_MoveOrigin(mobj, destx, desty, mobj->target->z); mobj->angle = K_MomentumAngle(mobj->target); if (underlayst != S_NULL) @@ -7171,7 +7498,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) return false; } - P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z); + P_MoveOrigin(mobj, mobj->target->x, mobj->target->y, mobj->target->z); mobj->angle = mobj->target->angle; mobj->scalespeed = mobj->target->scalespeed; mobj->destscale = mobj->target->destscale; @@ -7221,7 +7548,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) if (cur->lastlook == 2 || cur->lastlook == 3) offy *= -1; - P_TeleportMove(cur, mobj->x + offx, mobj->y + offy, mobj->z); + P_MoveOrigin(cur, mobj->x + offx, mobj->y + offy, mobj->z); cur->scalespeed = mobj->target->scalespeed; cur->destscale = mobj->target->destscale; P_SetScale(cur, mobj->target->scale); @@ -7360,7 +7687,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) amt += 1; } - P_TeleportMove( + P_MoveOrigin( cur, mobj->x + FixedMul(amt, FINECOSINE(dir >> ANGLETOFINESHIFT)), mobj->y + FixedMul(amt, FINESINE(dir >> ANGLETOFINESHIFT)), @@ -7450,7 +7777,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) while (cur && !P_MobjWasRemoved(cur)) { cur->angle += FixedAngle(mobj->info->speed); - P_TeleportMove(cur, mobj->x + FINECOSINE((cur->angle*8)>>ANGLETOFINESHIFT), + P_MoveOrigin(cur, mobj->x + FINECOSINE((cur->angle*8)>>ANGLETOFINESHIFT), mobj->y + FINESINE((cur->angle*8)>>ANGLETOFINESHIFT), mobj->z); //P_SpawnGhostMobj(cur)->tics = 2; @@ -7583,7 +7910,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) fixed_t wz = mobj->tracer->z + (joint * ((mobj->z + (mobj->height/2)) - mobj->tracer->z) / (numjoints+1)); if (cur && !P_MobjWasRemoved(cur)) - P_TeleportMove(cur, wx, wy, wz); + P_MoveOrigin(cur, wx, wy, wz); else cur = P_SpawnMobj(wx, wy, wz, MT_FROGTONGUE_JOINT); @@ -7694,7 +8021,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) continue; } else // Move into place - P_TeleportMove(cur, mobj->x, mobj->y, segz); + P_MoveOrigin(cur, mobj->x, mobj->y, segz); } else { @@ -7768,7 +8095,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->extravalue1 = 1; player->offroad += 2<mo->x + P_ReturnThrustX(NULL, player->mo->angle, player->mo->radius) + P_ReturnThrustX(NULL, player->mo->angle+ANGLE_90, (mobj->threshold)<mo->y + P_ReturnThrustY(NULL, player->mo->angle, player->mo->radius) @@ -7929,7 +8256,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->tracer->momx = mobj->tracer->momy = 0; } - P_TeleportMove(mobj, + P_MoveOrigin(mobj, mobj->tracer->x + P_ReturnThrustX(NULL, mobj->tracer->angle+ANGLE_90, (mobj->cvmem)<tracer->y + P_ReturnThrustY(NULL, mobj->tracer->angle+ANGLE_90, (mobj->cvmem)<tracer->z - (4*mobj->tracer->scale) + (P_RandomRange(-abs(mobj->cvmem), abs(mobj->cvmem))<angle = angle + ANGLE_90; } - P_TeleportMove(cur, newx, newy, newz); + P_MoveOrigin(cur, newx, newy, newz); cur = cur->hnext; } } break; case MT_RANDOMITEM: + case MT_SPHEREBOX: if (gametype == GT_BATTLE && mobj->threshold == 70) { mobj->color = K_RainbowColor(leveltime); @@ -8298,7 +8626,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) mobj->extravalue1++; dist = mobj->extravalue1 * mapobjectscale; - P_TeleportMove(mobj, battleovertime.x + P_ReturnThrustX(NULL, ang, dist), + P_MoveOrigin(mobj, battleovertime.x + P_ReturnThrustX(NULL, ang, dist), battleovertime.y + P_ReturnThrustY(NULL, ang, dist), z); ghost = P_SpawnGhostMobj(mobj); @@ -8546,6 +8874,14 @@ void P_MobjThinker(mobj_t *mobj) I_Assert(mobj != NULL); I_Assert(!P_MobjWasRemoved(mobj)); + // Set old position (for interpolation) + mobj->old_x = mobj->x; + mobj->old_y = mobj->y; + mobj->old_z = mobj->z; + mobj->old_angle = mobj->angle; + mobj->old_pitch = mobj->pitch; + mobj->old_roll = mobj->roll; + // Remove dead target/tracer. if (mobj->target && P_MobjWasRemoved(mobj->target)) P_SetTarget(&mobj->target, NULL); @@ -8569,7 +8905,7 @@ void P_MobjThinker(mobj_t *mobj) return; } - mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG|MFE_JUSTBOUNCEDWALL); + mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG|MFE_JUSTBOUNCEDWALL|MFE_DAMAGEHITLAG|MFE_SLOPELAUNCHED); tmfloorthing = tmhitthing = NULL; @@ -8758,6 +9094,8 @@ void P_MobjThinker(mobj_t *mobj) P_ButteredSlope(mobj); } + P_SquishThink(mobj); + if (mobj->flags & (MF_ENEMY|MF_BOSS) && mobj->health && P_CheckDeathPitCollide(mobj)) // extra pit check in case these didn't have momz { @@ -9049,6 +9387,7 @@ static void P_DefaultMobjShadowScale(mobj_t *thing) thing->shadowscale = 12*FRACUNIT/5; break; case MT_RANDOMITEM: + case MT_SPHEREBOX: thing->shadowscale = FRACUNIT/2; thing->whiteshadow = false; break; @@ -9433,8 +9772,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) // SRB2Kart case MT_ITEMCAPSULE: { - fixed_t oldHeight = mobj->height; - // set default item & count #if 0 // set to 1 to test capsules with random items, e.g. with objectplace if (P_RandomChance(FRACUNIT/3)) @@ -9451,17 +9788,10 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->movecount = 1; #endif - // grounded/aerial properties - P_AdjustMobjFloorZ_FFloors(mobj, mobj->subsector->sector, 0); - if (!P_IsObjectOnGround(mobj)) - mobj->flags |= MF_NOGRAVITY; - // set starting scale mobj->extravalue1 = mobj->scale; // this acts as the capsule's destscale; we're avoiding P_MobjScaleThink because we want aerial capsules not to scale from their center mobj->scalespeed >>= 1; P_SetScale(mobj, mobj->destscale = mapobjectscale >> 4); - if (mobj->eflags & MFE_VERTICALFLIP) - mobj->z += (oldHeight - mobj->height); break; } @@ -9623,7 +9953,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) cur = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SMK_ICEBLOCK_SIDE); P_SetTarget(&cur->target, mobj); cur->threshold = i; - P_TeleportMove(cur, cur->x + ((cur->radius>>FRACBITS) * FINECOSINE((FixedAngle((90*cur->threshold)<>ANGLETOFINESHIFT) & FINEMASK)), + P_MoveOrigin(cur, cur->x + ((cur->radius>>FRACBITS) * FINECOSINE((FixedAngle((90*cur->threshold)<>ANGLETOFINESHIFT) & FINEMASK)), cur->y + ((cur->radius>>FRACBITS) * FINESINE((FixedAngle((90*cur->threshold)<>ANGLETOFINESHIFT) & FINEMASK)), cur->z); cur->angle = ANGLE_90*(cur->threshold+1); @@ -9660,7 +9990,13 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) } } + // OK so we kind of need NOTHINK objects to still think + // because otherwise they can never update their + // interpolation values. They might need some other kind + // of system, so consider this temporary... +#if 0 if (!(mobj->flags & MF_NOTHINK)) +#endif P_AddThinker(THINK_MOBJ, &mobj->thinker); if (mobj->skin) // correct inadequecies above. @@ -9696,6 +10032,14 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) if (CheckForReverseGravity && !(mobj->flags & MF_NOBLOCKMAP)) P_CheckGravity(mobj, false); + // set initial old positions (for interpolation) + mobj->old_x = mobj->x; + mobj->old_y = mobj->y; + mobj->old_z = mobj->z; + mobj->old_angle = mobj->angle; + mobj->old_pitch = mobj->pitch; + mobj->old_roll = mobj->roll; + return mobj; } @@ -9747,6 +10091,14 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype || mobj->subsector->sector->floorpic == skyflatnum) mobj->precipflags |= PCF_PIT; + // set initial old positions (for interpolation) + mobj->old_x = mobj->x; + mobj->old_y = mobj->y; + mobj->old_z = mobj->z; + mobj->old_angle = mobj->angle; + mobj->old_pitch = mobj->pitch; + mobj->old_roll = mobj->roll; + return mobj; } @@ -11721,6 +12073,22 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean } case MT_ITEMCAPSULE: { + // we have to adjust for reverse gravity early so that the below grounded checks work + if (mthing->options & MTF_OBJECTFLIP) + { + mobj->eflags |= MFE_VERTICALFLIP; + mobj->flags2 |= MF2_OBJECTFLIP; + mobj->z += FixedMul(mobj->extravalue1, mobj->info->height) - mobj->height; + } + + // determine whether this capsule is grounded or aerial + if (mobj->subsector->sector->ffloors) + P_AdjustMobjFloorZ_FFloors(mobj, mobj->subsector->sector, 0); + if (mobj->subsector->polyList) + P_AdjustMobjFloorZ_PolyObjs(mobj, mobj->subsector); + if (!P_IsObjectOnGround(mobj)) + mobj->flags |= MF_NOGRAVITY; + // Angle = item type if (mthing->angle > 0 && mthing->angle < NUMKARTITEMS) mobj->threshold = mthing->angle; diff --git a/src/p_mobj.h b/src/p_mobj.h index 997b00f65..2373bdca4 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -247,6 +247,10 @@ typedef enum MFE_TRACERANGLE = 1<<11, // SRB2Kart: The mobj just hit & bounced off a wall, this is cleared on next frame MFE_JUSTBOUNCEDWALL = 1<<12, + // SRB2Kart: In damage hitlag (displays different visual efx) + MFE_DAMAGEHITLAG = 1<<13, + // Slope physics sent you airborne + MFE_SLOPELAUNCHED = 1<<14, // free: to and including 1<<15 } mobjeflag_t; @@ -273,6 +277,7 @@ typedef struct mobj_s // Info for drawing: position. fixed_t x, y, z; + fixed_t old_x, old_y, old_z; // position interpolation // More list: links in sector (if needed) struct mobj_s *snext; @@ -280,6 +285,7 @@ typedef struct mobj_s // More drawing info: to determine current sprite. angle_t angle, pitch, roll; // orientation + angle_t old_angle, old_pitch, old_roll; // orientation interpolation angle_t rollangle; spritenum_t sprite; // used to find patch_t and flip value UINT32 frame; // frame number, plus bits see p_pspr.h @@ -358,6 +364,7 @@ typedef struct mobj_s fixed_t friction; fixed_t movefactor; + fixed_t lastmomz; INT32 fuse; // Does something in P_MobjThinker on reaching 0. fixed_t watertop; // top of the water FOF the mobj is in @@ -410,6 +417,7 @@ typedef struct precipmobj_s // Info for drawing: position. fixed_t x, y, z; + fixed_t old_x, old_y, old_z; // position interpolation // More list: links in sector (if needed) struct precipmobj_s *snext; @@ -417,6 +425,7 @@ typedef struct precipmobj_s // More drawing info: to determine current sprite. angle_t angle, pitch, roll; // orientation + angle_t old_angle, old_pitch, old_roll; // orientation interpolation angle_t rollangle; spritenum_t sprite; // used to find patch_t and flip value UINT32 frame; // frame number, plus bits see p_pspr.h diff --git a/src/p_saveg.c b/src/p_saveg.c index 27e100ccd..39a4fec28 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -239,6 +239,8 @@ static void P_NetArchivePlayers(void) WRITEINT32(save_p, players[i].aizdrifttilt); WRITEINT32(save_p, players[i].aizdriftturn); + WRITEINT32(save_p, players[i].underwatertilt); + WRITEFIXED(save_p, players[i].offroad); WRITEUINT8(save_p, players[i].waterskip); @@ -306,9 +308,6 @@ static void P_NetArchivePlayers(void) WRITEUINT8(save_p, players[i].trickpanel); WRITEUINT8(save_p, players[i].tricktime); - WRITEUINT32(save_p, players[i].trickmomx); - WRITEUINT32(save_p, players[i].trickmomy); - WRITEUINT32(save_p, players[i].trickmomz); WRITEUINT32(save_p, players[i].trickboostpower); WRITEUINT8(save_p, players[i].trickboostdecay); WRITEUINT8(save_p, players[i].trickboost); @@ -317,9 +316,11 @@ static void P_NetArchivePlayers(void) WRITEUINT8(save_p, players[i].emeralds); WRITEUINT8(save_p, players[i].bumpers); WRITEINT16(save_p, players[i].karmadelay); + WRITEUINT32(save_p, players[i].overtimekarma); WRITEINT16(save_p, players[i].spheres); WRITESINT8(save_p, players[i].glanceDir); + WRITEUINT8(save_p, players[i].tripWireState); WRITEUINT8(save_p, players[i].typing_timer); WRITEUINT8(save_p, players[i].typing_duration); @@ -334,6 +335,7 @@ static void P_NetArchivePlayers(void) WRITEFIXED(save_p, players[i].respawn.pointz); WRITEUINT8(save_p, players[i].respawn.flip); WRITEUINT32(save_p, players[i].respawn.timer); + WRITEUINT32(save_p, players[i].respawn.airtimer); WRITEUINT32(save_p, players[i].respawn.distanceleft); WRITEUINT32(save_p, players[i].respawn.dropdash); @@ -495,6 +497,8 @@ static void P_NetUnArchivePlayers(void) players[i].aizdrifttilt = READINT32(save_p); players[i].aizdriftturn = READINT32(save_p); + players[i].underwatertilt = READINT32(save_p); + players[i].offroad = READFIXED(save_p); players[i].waterskip = READUINT8(save_p); @@ -562,9 +566,6 @@ static void P_NetUnArchivePlayers(void) players[i].trickpanel = READUINT8(save_p); players[i].tricktime = READUINT8(save_p); - players[i].trickmomx = READUINT32(save_p); - players[i].trickmomy = READUINT32(save_p); - players[i].trickmomz = READUINT32(save_p); players[i].trickboostpower = READUINT32(save_p); players[i].trickboostdecay = READUINT8(save_p); players[i].trickboost = READUINT8(save_p); @@ -573,9 +574,11 @@ static void P_NetUnArchivePlayers(void) players[i].emeralds = READUINT8(save_p); players[i].bumpers = READUINT8(save_p); players[i].karmadelay = READINT16(save_p); + players[i].overtimekarma = READUINT32(save_p); players[i].spheres = READINT16(save_p); players[i].glanceDir = READSINT8(save_p); + players[i].tripWireState = READUINT8(save_p); players[i].typing_timer = READUINT8(save_p); players[i].typing_duration = READUINT8(save_p); @@ -590,6 +593,7 @@ static void P_NetUnArchivePlayers(void) players[i].respawn.pointz = READFIXED(save_p); players[i].respawn.flip = (boolean)READUINT8(save_p); players[i].respawn.timer = READUINT32(save_p); + players[i].respawn.airtimer = READUINT32(save_p); players[i].respawn.distanceleft = READUINT32(save_p); players[i].respawn.dropdash = READUINT32(save_p); @@ -1534,7 +1538,8 @@ typedef enum MD2_HITLAG = 1<<24, MD2_WAYPOINTCAP = 1<<25, MD2_KITEMCAP = 1<<26, - MD2_ITNEXT = 1<<27 + MD2_ITNEXT = 1<<27, + MD2_LASTMOMZ = 1<<28, } mobj_diff2_t; typedef enum @@ -1775,6 +1780,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff2 |= MD2_KITEMCAP; if (mobj->itnext) diff2 |= MD2_ITNEXT; + if (mobj->lastmomz) + diff2 |= MD2_LASTMOMZ; if (diff2 != 0) diff |= MD_MORE; @@ -1965,7 +1972,13 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEFIXED(save_p, slope->normal.z); } if (diff2 & MD2_HITLAG) + { WRITEINT32(save_p, mobj->hitlag); + } + if (diff2 & MD2_LASTMOMZ) + { + WRITEINT32(save_p, mobj->lastmomz); + } WRITEUINT32(save_p, mobj->mobjnum); } @@ -3057,7 +3070,13 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) slope->normal.z = READFIXED(save_p); } if (diff2 & MD2_HITLAG) + { mobj->hitlag = READINT32(save_p); + } + if (diff2 & MD2_LASTMOMZ) + { + mobj->lastmomz = READINT32(save_p); + } if (diff & MD_REDFLAG) { diff --git a/src/p_setup.c b/src/p_setup.c index 654eb6eb1..db9a35a11 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -91,6 +91,7 @@ #include "k_waypoint.h" #include "k_bot.h" #include "k_grandprix.h" +#include "k_brightmap.h" // Replay names have time #if !defined (UNDER_CE) @@ -1044,6 +1045,8 @@ static void P_InitializeLinedef(line_t *ld) ld->validcount = 0; ld->polyobj = NULL; + ld->tripwire = false; + ld->text = NULL; ld->callcount = 0; @@ -1936,11 +1939,23 @@ static void P_ProcessLinedefsAfterSidedefs(void) { size_t i = numlines; register line_t *ld = lines; + + const INT32 TEX_TRIPWIRE = R_TextureNumForName("TRIPWIRE"); + const INT32 TEX_4RIPWIRE = R_TextureNumForName("4RIPWIRE"); + for (; i--; ld++) { + INT32 midtexture = sides[ld->sidenum[0]].midtexture; + ld->frontsector = sides[ld->sidenum[0]].sector; //e6y: Can't be -1 here ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : 0; + if (midtexture == TEX_TRIPWIRE || + midtexture == TEX_4RIPWIRE) + { + ld->tripwire = true; + } + switch (ld->special) { // Compile linedef 'text' from both sidedefs 'text' for appropriate specials. @@ -4443,6 +4458,9 @@ boolean P_AddWadFile(const char *wadfilename) // Reload ANIMDEFS P_InitPicAnims(); + // Reload BRIGHT + K_InitBrightmaps(); + // Flush and reload HUD graphics ST_UnloadGraphics(); HU_LoadGraphics(); diff --git a/src/p_sight.c b/src/p_sight.c index 38a50df36..cdc8df864 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -18,6 +18,9 @@ #include "r_main.h" #include "r_state.h" +#include "k_bot.h" // K_BotHatesThisSector +#include "k_kart.h" // K_TripwirePass + // // P_CheckSight // @@ -572,7 +575,7 @@ static boolean P_CrossBlockingSubsector(size_t num, register traceblocking_t *tb if (P_IsLineBlocking(line, tb->compareThing) == true) { - // This line will block us + // This line will always block us return false; } } @@ -656,3 +659,192 @@ boolean P_TraceBlockingLines(mobj_t *t1, mobj_t *t2) // the head node is the last node output return P_CrossBSPNodeBlocking((INT32)numnodes - 1, &tb); } + +// +// ANOTHER version, this time for bot traversal. +// (TODO: since we have so many versions of this function, the differences +// should maybe just be a function var that gets called?) +// + +static boolean P_CrossBotTraversalSubsector(size_t num, register traceblocking_t *tb) +{ + seg_t *seg; + INT32 count; + +#ifdef RANGECHECK + if (num >= numsubsectors) + I_Error("P_CrossBotTraversalSubsector: ss %s with numss = %s\n", sizeu1(num), sizeu2(numsubsectors)); +#endif + + // haleyjd 02/23/06: this assignment should be after the above check + seg = segs + subsectors[num].firstline; + + for (count = subsectors[num].numlines; --count >= 0; seg++) // check lines + { + line_t *line = seg->linedef; + divline_t divl; + const vertex_t *v1,*v2; + fixed_t maxstep = INT32_MAX; + + if (seg->glseg) + continue; + + // already checked other side? + if (line->validcount == validcount) + continue; + + line->validcount = validcount; + + // OPTIMIZE: killough 4/20/98: Added quick bounding-box rejection test + if (line->bbox[BOXLEFT ] > tb->bbox[BOXRIGHT ] || + line->bbox[BOXRIGHT ] < tb->bbox[BOXLEFT ] || + line->bbox[BOXBOTTOM] > tb->bbox[BOXTOP ] || + line->bbox[BOXTOP] < tb->bbox[BOXBOTTOM]) + continue; + + v1 = line->v1; + v2 = line->v2; + + // line isn't crossed? + if (P_DivlineSide(v1->x, v1->y, &tb->strace) == + P_DivlineSide(v2->x, v2->y, &tb->strace)) + continue; + + // stop because it is not two sided anyway + if (!(line->flags & ML_TWOSIDED)) + return false; + + divl.dx = v2->x - (divl.x = v1->x); + divl.dy = v2->y - (divl.y = v1->y); + + // line isn't crossed? + if (P_DivlineSide(tb->strace.x, tb->strace.y, &divl) == + P_DivlineSide(tb->t2x, tb->t2y, &divl)) + continue; + + if (P_IsLineBlocking(line, tb->compareThing) == true) + { + // This line will always block us + return false; + } + + // set openrange, opentop, openbottom + P_LineOpening(line, tb->compareThing); + maxstep = P_GetThingStepUp(tb->compareThing); + + if ((openrange < tb->compareThing->height) // doesn't fit + || (opentop - tb->compareThing->z < tb->compareThing->height) // mobj is too high + || (openbottom - tb->compareThing->z > maxstep)) // too big a step up + { + // This line situationally blocks us + return false; + } + + // Treat damage sectors like walls + if (tb->compareThing->player != NULL) + { + boolean alreadyHates = K_BotHatesThisSector(tb->compareThing->player, tb->compareThing->subsector->sector, tb->compareThing->x, tb->compareThing->y); + + if (alreadyHates == false) + { + INT32 lineside = 0; + vertex_t pos; + + P_ClosestPointOnLine(tb->compareThing->x, tb->compareThing->y, line, &pos); + lineside = P_PointOnLineSide(tb->compareThing->x, tb->compareThing->y, line); + + if (K_BotHatesThisSector(tb->compareThing->player, ((lineside == 1) ? line->frontsector : line->backsector), pos.x, pos.y)) + { + // This line does not block us, but we don't want to be in it. + return false; + } + } + + if (P_IsLineTripWire(line) == true && K_TripwirePass(tb->compareThing->player) == false) + { + // Can't go through trip wire. + return false; + } + } + } + + // passed the subsector ok + return true; +} + +static boolean P_CrossBSPNodeBotTraversal(INT32 bspnum, register traceblocking_t *tb) +{ + while (!(bspnum & NF_SUBSECTOR)) + { + register node_t *bsp = nodes + bspnum; + INT32 side = P_DivlineSide(tb->strace.x,tb->strace.y,(divline_t *)bsp)&1; + if (side == P_DivlineSide(tb->t2x, tb->t2y, (divline_t *) bsp)) + bspnum = bsp->children[side]; // doesn't touch the other side + else // the partition plane is crossed here + { + if (!P_CrossBSPNodeBotTraversal(bsp->children[side], tb)) + return false; // cross the starting side + else + bspnum = bsp->children[side^1]; // cross the ending side + } + } + + return P_CrossBotTraversalSubsector((bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR), tb); +} + +boolean P_TraceBotTraversal(mobj_t *t1, mobj_t *t2) +{ + const sector_t *s1, *s2; + size_t pnum; + traceblocking_t tb; + + // First check for trivial rejection. + if (!t1 || !t2) + return false; + + I_Assert(!P_MobjWasRemoved(t1)); + I_Assert(!P_MobjWasRemoved(t2)); + + if (!t1->subsector || !t2->subsector + || !t1->subsector->sector || !t2->subsector->sector) + return false; + + s1 = t1->subsector->sector; + s2 = t2->subsector->sector; + pnum = (s1-sectors)*numsectors + (s2-sectors); + + if (rejectmatrix != NULL) + { + // Check in REJECT table. + if (rejectmatrix[pnum>>3] & (1 << (pnum&7))) // can't possibly be connected + return false; + } + + // killough 11/98: shortcut for melee situations + // same subsector? obviously visible + // haleyjd 02/23/06: can't do this if there are polyobjects in the subsec + if (!t1->subsector->polyList && + t1->subsector == t2->subsector) + return true; + + validcount++; + + tb.strace.dx = (tb.t2x = t2->x) - (tb.strace.x = t1->x); + tb.strace.dy = (tb.t2y = t2->y) - (tb.strace.y = t1->y); + + if (t1->x > t2->x) + tb.bbox[BOXRIGHT] = t1->x, tb.bbox[BOXLEFT] = t2->x; + else + tb.bbox[BOXRIGHT] = t2->x, tb.bbox[BOXLEFT] = t1->x; + + if (t1->y > t2->y) + tb.bbox[BOXTOP] = t1->y, tb.bbox[BOXBOTTOM] = t2->y; + else + tb.bbox[BOXTOP] = t2->y, tb.bbox[BOXBOTTOM] = t1->y; + + tb.compareThing = t1; + + // the head node is the last node output + return P_CrossBSPNodeBotTraversal((INT32)numnodes - 1, &tb); +} + diff --git a/src/p_slopes.c b/src/p_slopes.c index d1e8f5f54..1bde8f4ee 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -844,6 +844,8 @@ void P_SlopeLaunch(mobj_t *mo) mo->momy = slopemom.y; mo->momz = slopemom.z; #endif + + mo->eflags |= MFE_SLOPELAUNCHED; } //CONS_Printf("Launched off of slope.\n"); diff --git a/src/p_spec.c b/src/p_spec.c index 16823916e..caf4704d2 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2018,6 +2018,12 @@ void P_CrossSpecialLine(line_t *line, INT32 side, mobj_t *thing) return; { player_t *player = thing->player; + + if (P_IsLineTripWire(line)) + { + K_ApplyTripWire(player, TRIP_PASSED); + } + switch (line->special) { case 2001: // Finish Line @@ -2976,9 +2982,9 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) // reasonable defaults. if (!quake.intensity) - quake.intensity = 8<drift = player->driftcharge = 0; player->trickpanel = 0; + player->glanceDir = 0; } // @@ -499,6 +500,26 @@ INT32 P_GivePlayerRings(player_t *player, INT32 num_rings) return num_rings; } +INT32 P_GivePlayerSpheres(player_t *player, INT32 num_spheres) +{ + num_spheres += player->spheres; + + // Not alive + if ((gametyperules & GTR_BUMPERS) && (player->bumpers <= 0)) + return 0; + + if (num_spheres > 40) // Reached the cap, don't waste 'em! + num_spheres = 40; + else if (num_spheres < 0) + num_spheres = 0; + + num_spheres -= player->spheres; + + player->spheres += num_spheres; + + return num_spheres; +} + // // P_GivePlayerLives // @@ -1057,6 +1078,9 @@ boolean P_IsLocalPlayer(player_t *player) { UINT8 i; + if (demo.playback) + return P_IsDisplayPlayer(player); + for (i = 0; i <= r_splitscreen; i++) // DON'T skip P1 { if (player == &players[g_localplayers[i]]) @@ -1137,6 +1161,14 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost2->flags2 |= (mobj->player->followmobj->flags2 & MF2_LINKDRAW); } + // Copy interpolation data :) + ghost->old_x = mobj->old_x; + ghost->old_y = mobj->old_y; + ghost->old_z = mobj->old_z; + ghost->old_angle = (mobj->player ? mobj->player->old_drawangle : mobj->old_angle); + ghost->old_pitch = mobj->old_pitch; + ghost->old_roll = mobj->old_roll; + return ghost; } @@ -1760,6 +1792,55 @@ static void P_3dMovement(player_t *player) if (player->mo->movefactor != FRACUNIT) // Friction-scaled acceleration... movepushforward = FixedMul(movepushforward, player->mo->movefactor); + { + INT32 a = K_GetUnderwaterTurnAdjust(player); + INT32 adj = 0; + + if (a) + { + const fixed_t maxadj = ANG10/4; + + adj = a / 4; + + if (adj > 0) + { + if (adj > maxadj) + adj = maxadj; + } + else if (adj < 0) + { + if (adj < -(maxadj)) + adj = -(maxadj); + } + + if (abs(player->underwatertilt + adj) > abs(a)) + adj = (a - player->underwatertilt); + + if (abs(a) < abs(player->underwatertilt)) + adj = 0; + + movepushangle += a; + } + + if (adj) + { + player->underwatertilt += adj; + + if (abs(player->underwatertilt) > ANG30) + { + player->underwatertilt = + player->underwatertilt > 0 ? ANG30 + : -(ANG30); + } + } + else + { + player->underwatertilt = + FixedMul(player->underwatertilt, + 7*FRACUNIT/8); + } + } + totalthrust.x += P_ReturnThrustX(player->mo, movepushangle, movepushforward); totalthrust.y += P_ReturnThrustY(player->mo, movepushangle, movepushforward); } @@ -2003,6 +2084,8 @@ void P_MovePlayer(player_t *player) P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); player->drawangle -= ANGLE_22h; player->mo->rollangle = 0; + player->glanceDir = 0; + player->pflags &= ~PF_LOOKDOWN; } else if ((player->pflags & PF_FAULT) || (player->spinouttimer > 0)) { @@ -2021,17 +2104,6 @@ void P_MovePlayer(player_t *player) player->mo->rollangle = 0; } - /*else if (player->pflags & PF_FAULT) -- v1 fault - { - P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); - - if (((player->nocontrol + 5) % 20) < 10) - player->drawangle += ANGLE_11hh; - else - player->drawangle -= ANGLE_11hh; - - player->mo->rollangle = 0; - }*/ else { K_KartMoveAnimation(player); @@ -2055,6 +2127,10 @@ void P_MovePlayer(player_t *player) else if (player->drift != 0) { INT32 a = (ANGLE_45 / 5) * player->drift; + + if (player->mo->eflags & MFE_UNDERWATER) + a /= 2; + player->drawangle += a; } } @@ -2123,6 +2199,9 @@ void P_MovePlayer(player_t *player) ((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAILUNDERLAY); water->angle = forwardangle - ANGLE_180 - ANGLE_22h; water->destscale = trailScale; + water->momx = player->mo->momx; + water->momy = player->mo->momy; + water->momz = player->mo->momz; P_SetScale(water, trailScale); P_SetMobjState(water, curUnderlayFrame); @@ -2131,6 +2210,9 @@ void P_MovePlayer(player_t *player) ((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAIL); water->angle = forwardangle - ANGLE_180 - ANGLE_22h; water->destscale = trailScale; + water->momx = player->mo->momx; + water->momy = player->mo->momy; + water->momz = player->mo->momz; P_SetScale(water, trailScale); P_SetMobjState(water, curOverlayFrame); @@ -2140,6 +2222,9 @@ void P_MovePlayer(player_t *player) ((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAILUNDERLAY].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAILUNDERLAY); water->angle = forwardangle - ANGLE_180 + ANGLE_22h; water->destscale = trailScale; + water->momx = player->mo->momx; + water->momy = player->mo->momy; + water->momz = player->mo->momz; P_SetScale(water, trailScale); P_SetMobjState(water, curUnderlayFrame); @@ -2148,6 +2233,9 @@ void P_MovePlayer(player_t *player) ((player->mo->eflags & MFE_VERTICALFLIP) ? player->mo->waterbottom - FixedMul(mobjinfo[MT_WATERTRAIL].height, player->mo->scale) : player->mo->watertop), MT_WATERTRAIL); water->angle = forwardangle - ANGLE_180 + ANGLE_22h; water->destscale = trailScale; + water->momx = player->mo->momx; + water->momy = player->mo->momy; + water->momz = player->mo->momz; P_SetScale(water, trailScale); P_SetMobjState(water, curOverlayFrame); @@ -2434,6 +2522,8 @@ static void P_ConsiderAllGone(void) // static void P_DeathThink(player_t *player) { + boolean playerGone = false; + player->deltaviewheight = 0; if (player->deadtimer < INT32_MAX) @@ -2454,7 +2544,19 @@ static void P_DeathThink(player_t *player) K_KartPlayerHUDUpdate(player); - if (player->lives > 0 && !(player->pflags & PF_NOCONTEST) && player->deadtimer > TICRATE) + if (player->pflags & PF_NOCONTEST) + { + playerGone = true; + } + else if (player->bot == false) + { + if (G_GametypeUsesLives() == true && player->lives == 0) + { + playerGone = true; + } + } + + if (playerGone == false && player->deadtimer > TICRATE) { player->playerstate = PST_REBORN; } @@ -2836,6 +2938,12 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall subsector_t *newsubsec; #endif + thiscam->old_x = thiscam->x; + thiscam->old_y = thiscam->y; + thiscam->old_z = thiscam->z; + thiscam->old_angle = thiscam->angle; + thiscam->old_aiming = thiscam->aiming; + 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 @@ -2974,6 +3082,10 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall else lookbackdelay[num]--; } + else if (player->respawn.state != RESPAWNST_NONE) + { + camspeed = 3*FRACUNIT/4; + } lookbackdown = (lookbackdelay[num] == MAXLOOKBACKDELAY) != lookbackactive[num]; lookbackactive[num] = (lookbackdelay[num] == MAXLOOKBACKDELAY); #undef MAXLOOKBACKDELAY @@ -3851,13 +3963,12 @@ static void P_HandleFollower(player_t *player) } // Set follower colour - switch (player->followercolor) { - case MAXSKINCOLORS: // "Match" + case 255: // "Match" (-1) color = player->skincolor; break; - case MAXSKINCOLORS+1: // "Opposite" + case 254: // "Opposite" (-2) color = skincolors[player->skincolor].invcolor; break; default: @@ -3918,9 +4029,10 @@ static void P_HandleFollower(player_t *player) P_SetFollowerState(player->follower, player->follower->state->nextstate); // move the follower next to us (yes, this is really basic maths but it looks pretty damn clean in practice)! - player->follower->momx = (sx - player->follower->x)/fl.horzlag; - player->follower->momy = (sy - player->follower->y)/fl.horzlag; - player->follower->momz = (sz - player->follower->z)/fl.vertlag; + // 02/09/2021: cast lag to int32 otherwise funny things happen since it was changed to uint32 in the struct + player->follower->momx = (sx - player->follower->x)/ (INT32)fl.horzlag; + player->follower->momy = (sy - player->follower->y)/ (INT32)fl.horzlag; + player->follower->momz = (sz - player->follower->z)/ (INT32)fl.vertlag; player->follower->angle = player->mo->angle; if (player->mo->colorized) @@ -4098,6 +4210,12 @@ DoABarrelRoll (player_t *player) fixed_t smoothing; + if (player->respawn.state != RESPAWNST_NONE) + { + player->tilt = 0; + return; + } + if (player->exiting) { return; @@ -4150,10 +4268,10 @@ void P_PlayerThink(player_t *player) player->playerstate = PST_DEAD; } - if (player->mo->hitlag > 0) - { - return; - } + player->old_drawangle = player->drawangle; + player->old_viewrollangle = player->viewrollangle; + + player->pflags &= ~PF_HITFINISHLINE; if (player->awayviewmobj && P_MobjWasRemoved(player->awayviewmobj)) { @@ -4170,6 +4288,11 @@ void P_PlayerThink(player_t *player) if (player->awayviewtics && player->awayviewtics != -1) player->awayviewtics--; + if (player->mo->hitlag > 0) + { + return; + } + // Track airtime if (P_IsObjectOnGround(player->mo)) { @@ -4350,6 +4473,7 @@ void P_PlayerThink(player_t *player) player->flashing = TICRATE/2 + 1; /*if (P_SpectatorJoinGame(player)) return; // player->mo was removed.*/ + //CONS_Printf("player %s wants to join on tic %d\n", player_names[player-players], leveltime); } if (player->respawn.state != RESPAWNST_NONE) @@ -4406,6 +4530,8 @@ void P_PlayerThink(player_t *player) else player->pflags &= ~PF_BRAKEDOWN; + // PF_LOOKDOWN handled in K_KartMoveAnimation + // Counters, time dependent power ups. // Time Bonus & Ring Bonus count settings diff --git a/src/r_data.c b/src/r_data.c index 04b6c232b..ddeb5e3b5 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -30,6 +30,9 @@ #include "byteptr.h" #include "dehacked.h" +// DRRR +#include "k_brightmap.h" + // // Graphics. // SRB2 graphics for walls and sprites @@ -615,6 +618,7 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap) { double cmaskr, cmaskg, cmaskb, cdestr, cdestg, cdestb, cdestbright; double maskamt = 0, othermask = 0; + double fmaskamt = 0, fothermask = 0; UINT8 cr = R_GetRgbaR(extra_colormap->rgba), cg = R_GetRgbaG(extra_colormap->rgba), @@ -622,8 +626,8 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap) ca = R_GetRgbaA(extra_colormap->rgba), cfr = R_GetRgbaR(extra_colormap->fadergba), cfg = R_GetRgbaG(extra_colormap->fadergba), - cfb = R_GetRgbaB(extra_colormap->fadergba); -// cfa = R_GetRgbaA(extra_colormap->fadergba); // unused in software + cfb = R_GetRgbaB(extra_colormap->fadergba), + cfa = R_GetRgbaA(extra_colormap->fadergba); UINT8 fadestart = extra_colormap->fadestart, fadedist = extra_colormap->fadeend - extra_colormap->fadestart; @@ -654,14 +658,11 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap) cdestb = cfb; cdestbright = sqrt((cfr*cfr) + (cfg*cfg) + (cfb*cfb)); - // fade alpha unused in software - // maskamt = (double)(cfa/24.0l); - // othermask = 1 - maskamt; - // maskamt /= 0xff; + fmaskamt = (double)(cfa/24.0l); + fothermask = 1 - fmaskamt; + //fmaskamt /= 0xff; - // cdestr *= maskamt; - // cdestg *= maskamt; - // cdestb *= maskamt; + (void)fothermask; // unused, but don't feel like commenting it out ///////////////////// // This code creates the colormap array used by software renderer @@ -701,16 +702,16 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap) if (cbrightness < cdestbright) { cbest = 255.0l - min(r, min(g, b)); - cdist = 255.0l - cdestbright; + cdist = 255.0l - max(cdestr, max(cdestg, cdestb)); } else { cbest = max(r, max(g, b)); - cdist = cdestbright; + cdist = min(cdestr, min(cdestg, cdestb)); } // Add/subtract this value during fading. - brightChange[i] = fabs(cbest - cdist) / (double)fadedist; + brightChange[i] = (fabs(cbest - cdist) / (double)fadedist) * fmaskamt; } // Now allocate memory for the actual colormap array itself! @@ -1177,6 +1178,9 @@ void R_InitTextureData(void) CONS_Printf("P_InitPicAnims()...\n"); P_InitPicAnims(); + + CONS_Printf("K_InitBrightmaps()...\n"); + K_InitBrightmaps(); } // diff --git a/src/r_defs.h b/src/r_defs.h index 41b0cdaab..7decdfeab 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -420,6 +420,8 @@ typedef struct line_s size_t validcount; // if == validcount, already checked polyobj_t *polyobj; // Belongs to a polyobject? + boolean tripwire; + char *text; // a concatenation of all front and back texture names, for linedef specials that require a string. INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0 } line_t; diff --git a/src/r_draw.c b/src/r_draw.c index 565d4a1fa..946763a6e 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -26,6 +26,7 @@ #include "z_zone.h" #include "console.h" // Until buffering gets finished #include "k_color.h" // SRB2kart +#include "i_threads.h" #ifdef HWRENDER #include "hardware/hw_main.h" @@ -71,12 +72,14 @@ UINT8 *topleft; // ========================================================================= lighttable_t *dc_colormap; +lighttable_t *dc_fullbright; INT32 dc_x = 0, dc_yl = 0, dc_yh = 0; fixed_t dc_iscale, dc_texturemid; UINT8 dc_hires; // under MSVC boolean is a byte, while on other systems, it a bit, // soo lets make it a byte on all system for the ASM code UINT8 *dc_source; +UINT8 *dc_brightmap; // ----------------------- // translucency stuff here @@ -108,6 +111,7 @@ INT32 dc_numlights = 0, dc_maxlights, dc_texheight; INT32 ds_y, ds_x1, ds_x2; lighttable_t *ds_colormap; +lighttable_t *ds_fullbright; lighttable_t *ds_translation; // Lactozilla: Sprite splat drawer fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep; @@ -117,6 +121,7 @@ UINT16 ds_flatwidth, ds_flatheight; boolean ds_powersoftwo; UINT8 *ds_source; // points to the start of a flat +UINT8 *ds_brightmap; // start of brightmap flat UINT8 *ds_transmap; // one of the translucency tables // Vectors for Software's tilted slope drawers @@ -141,7 +146,9 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask; #define RAINBOW_TT_CACHE_INDEX (MAXSKINS + 4) #define BLINK_TT_CACHE_INDEX (MAXSKINS + 5) #define DASHMODE_TT_CACHE_INDEX (MAXSKINS + 6) -#define TT_CACHE_SIZE (MAXSKINS + 7) +#define HITLAG_TT_CACHE_INDEX (MAXSKINS + 7) +#define TT_CACHE_SIZE (MAXSKINS + 8) + #define SKIN_RAMP_LENGTH 16 #define DEFAULT_STARTTRANSCOLOR 96 #define NUM_PALETTE_ENTRIES 256 @@ -160,6 +167,7 @@ static INT32 SkinToCacheIndex(INT32 skinnum) case TC_RAINBOW: return RAINBOW_TT_CACHE_INDEX; case TC_BLINK: return BLINK_TT_CACHE_INDEX; case TC_DASHMODE: return DASHMODE_TT_CACHE_INDEX; + case TC_HITLAG: return HITLAG_TT_CACHE_INDEX; default: break; } @@ -177,6 +185,7 @@ static INT32 CacheIndexToSkin(INT32 ttc) case RAINBOW_TT_CACHE_INDEX: return TC_RAINBOW; case BLINK_TT_CACHE_INDEX: return TC_BLINK; case DASHMODE_TT_CACHE_INDEX: return TC_DASHMODE; + case HITLAG_TT_CACHE_INDEX: return TC_HITLAG; default: break; } @@ -188,6 +197,29 @@ CV_PossibleValue_t Followercolor_cons_t[MAXSKINCOLORS+3]; // +3 to account for " #define TRANSTAB_AMTMUL10 (255.0f / 10.0f) +static void R_AllocateBlendTables(void) +{ + INT32 i; + + for (i = 0; i < NUMBLENDMAPS; i++) + { + if (i == blendtab_modulate) + continue; + blendtables[i] = Z_MallocAlign((NUMTRANSTABLES + 1) * 0x10000, PU_STATIC, NULL, 16); + } + + // Modulation blending only requires a single table + blendtables[blendtab_modulate] = Z_MallocAlign(0x10000, PU_STATIC, NULL, 16); +} + +#ifdef HAVE_THREADS +static void R_GenerateBlendTables_Thread(void *userdata) +{ + (void)userdata; + R_GenerateBlendTables(); +} +#endif + /** \brief Initializes the translucency tables used by the Software renderer. */ void R_InitTranslucencyTables(void) @@ -208,20 +240,20 @@ void R_InitTranslucencyTables(void) W_ReadLump(W_GetNumForName("TRANS80"), transtables+0x70000); W_ReadLump(W_GetNumForName("TRANS90"), transtables+0x80000); + R_AllocateBlendTables(); + +#ifdef HAVE_THREADS + I_spawn_thread("blend-tables", + R_GenerateBlendTables_Thread, NULL); +#else R_GenerateBlendTables(); +#endif } void R_GenerateBlendTables(void) { INT32 i; - for (i = 0; i < NUMBLENDMAPS; i++) - { - if (i == blendtab_modulate) - continue; - blendtables[i] = Z_MallocAlign((NUMTRANSTABLES + 1) * 0x10000, PU_STATIC, NULL, 16); - } - for (i = 0; i <= 9; i++) { const size_t offs = (0x10000 * i); @@ -232,8 +264,6 @@ void R_GenerateBlendTables(void) R_GenerateTranslucencyTable(blendtables[blendtab_reversesubtract] + offs, AST_REVERSESUBTRACT, alpha); } - // Modulation blending only requires a single table - blendtables[blendtab_modulate] = Z_MallocAlign(0x10000, PU_STATIC, NULL, 16); R_GenerateTranslucencyTable(blendtables[blendtab_modulate], AST_MODULATE, 0); } diff --git a/src/r_draw.h b/src/r_draw.h index 687448c98..7b44d6185 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -32,11 +32,13 @@ extern UINT8 *topleft; // ------------------------- extern lighttable_t *dc_colormap; +extern lighttable_t *dc_fullbright; extern INT32 dc_x, dc_yl, dc_yh; extern fixed_t dc_iscale, dc_texturemid; extern UINT8 dc_hires; extern UINT8 *dc_source; // first pixel in a column +extern UINT8 *dc_brightmap; // brightmap texture column, can be NULL // translucency stuff here extern UINT8 *dc_transmap; @@ -57,6 +59,7 @@ extern INT32 dc_texheight; extern INT32 ds_y, ds_x1, ds_x2; extern lighttable_t *ds_colormap; +extern lighttable_t *ds_fullbright; extern lighttable_t *ds_translation; extern fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep; @@ -66,6 +69,7 @@ extern UINT16 ds_flatwidth, ds_flatheight; extern boolean ds_powersoftwo; extern UINT8 *ds_source; +extern UINT8 *ds_brightmap; extern UINT8 *ds_transmap; typedef struct { @@ -119,6 +123,7 @@ enum TC_RAINBOW, // For single colour TC_BLINK, // For item blinking, according to kart TC_DASHMODE, // For Metal Sonic's dashmode + TC_HITLAG, // Damage hitlag effect TC_DEFAULT }; @@ -166,6 +171,7 @@ void R_DrawViewBorder(void); #endif #define TRANSPARENTPIXEL 255 +#define BRIGHTPIXEL 0 // ----------------- // 8bpp DRAWING CODE diff --git a/src/r_draw8.c b/src/r_draw8.c index af64edbce..0dd8463f6 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -57,7 +57,9 @@ void R_DrawColumn_8(void) // This is as fast as it gets. { register const UINT8 *source = dc_source; + register const UINT8 *brightmap = dc_brightmap; register const lighttable_t *colormap = dc_colormap; + register const lighttable_t *fullbright = dc_fullbright; register INT32 heightmask = dc_texheight-1; if (dc_texheight & heightmask) // not a power of 2 -- killough { @@ -75,7 +77,14 @@ void R_DrawColumn_8(void) // Re-map color indices from wall texture column // using a lighting/special effects LUT. // heightmask is the Tutti-Frutti fix - *dest = colormap[source[frac>>FRACBITS]]; + if (brightmap != NULL && brightmap[frac>>FRACBITS] == BRIGHTPIXEL) + { + *dest = fullbright[source[frac>>FRACBITS]]; + } + else + { + *dest = colormap[source[frac>>FRACBITS]]; + } dest += vid.width; // Avoid overflow. @@ -92,15 +101,42 @@ void R_DrawColumn_8(void) { while ((count -= 2) >= 0) // texture height is a power of 2 { - *dest = colormap[source[(frac>>FRACBITS) & heightmask]]; + if (brightmap != NULL && brightmap[(frac>>FRACBITS) & heightmask] == BRIGHTPIXEL) + { + *dest = fullbright[source[(frac>>FRACBITS) & heightmask]]; + } + else + { + *dest = colormap[source[(frac>>FRACBITS) & heightmask]]; + } + dest += vid.width; frac += fracstep; - *dest = colormap[source[(frac>>FRACBITS) & heightmask]]; + + if (brightmap != NULL && brightmap[(frac>>FRACBITS) & heightmask] == BRIGHTPIXEL) + { + *dest = fullbright[source[(frac>>FRACBITS) & heightmask]]; + } + else + { + *dest = colormap[source[(frac>>FRACBITS) & heightmask]]; + } + dest += vid.width; frac += fracstep; } + if (count & 1) - *dest = colormap[source[(frac>>FRACBITS) & heightmask]]; + { + if (brightmap != NULL && brightmap[(frac>>FRACBITS) & heightmask] == BRIGHTPIXEL) + { + *dest = fullbright[source[(frac>>FRACBITS) & heightmask]]; + } + else + { + *dest = colormap[source[(frac>>FRACBITS) & heightmask]]; + } + } } } } @@ -140,7 +176,9 @@ void R_Draw2sMultiPatchColumn_8(void) // This is as fast as it gets. { register const UINT8 *source = dc_source; + register const UINT8 *brightmap = dc_brightmap; register const lighttable_t *colormap = dc_colormap; + register const lighttable_t *fullbright = dc_fullbright; register INT32 heightmask = dc_texheight-1; register UINT8 val; if (dc_texheight & heightmask) // not a power of 2 -- killough @@ -160,9 +198,17 @@ void R_Draw2sMultiPatchColumn_8(void) // using a lighting/special effects LUT. // heightmask is the Tutti-Frutti fix val = source[frac>>FRACBITS]; - if (val != TRANSPARENTPIXEL) - *dest = colormap[val]; + { + if (brightmap != NULL && brightmap[frac>>FRACBITS] == BRIGHTPIXEL) + { + *dest = fullbright[val]; + } + else + { + *dest = colormap[val]; + } + } dest += vid.width; @@ -182,20 +228,51 @@ void R_Draw2sMultiPatchColumn_8(void) { val = source[(frac>>FRACBITS) & heightmask]; if (val != TRANSPARENTPIXEL) - *dest = colormap[val]; + { + if (brightmap != NULL && brightmap[(frac>>FRACBITS) & heightmask] == BRIGHTPIXEL) + { + *dest = fullbright[val]; + } + else + { + *dest = colormap[val]; + } + } + dest += vid.width; frac += fracstep; + val = source[(frac>>FRACBITS) & heightmask]; if (val != TRANSPARENTPIXEL) - *dest = colormap[val]; + { + if (brightmap != NULL && brightmap[(frac>>FRACBITS) & heightmask] == BRIGHTPIXEL) + { + *dest = fullbright[val]; + } + else + { + *dest = colormap[val]; + } + } + dest += vid.width; frac += fracstep; } + if (count & 1) { val = source[(frac>>FRACBITS) & heightmask]; if (val != TRANSPARENTPIXEL) - *dest = colormap[val]; + { + if (brightmap != NULL && brightmap[(frac>>FRACBITS) & heightmask] == BRIGHTPIXEL) + { + *dest = fullbright[val]; + } + else + { + *dest = colormap[val]; + } + } } } } @@ -236,8 +313,10 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void) // This is as fast as it gets. { register const UINT8 *source = dc_source; + register const UINT8 *brightmap = dc_brightmap; register const UINT8 *transmap = dc_transmap; register const lighttable_t *colormap = dc_colormap; + register const lighttable_t *fullbright = dc_fullbright; register INT32 heightmask = dc_texheight-1; register UINT8 val; if (dc_texheight & heightmask) // not a power of 2 -- killough @@ -257,9 +336,17 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void) // using a lighting/special effects LUT. // heightmask is the Tutti-Frutti fix val = source[frac>>FRACBITS]; - if (val != TRANSPARENTPIXEL) - *dest = *(transmap + (colormap[val]<<8) + (*dest)); + { + if (brightmap != NULL && brightmap[frac>>FRACBITS] == BRIGHTPIXEL) + { + *dest = *(transmap + (fullbright[val]<<8) + (*dest)); + } + else + { + *dest = *(transmap + (colormap[val]<<8) + (*dest)); + } + } dest += vid.width; @@ -279,12 +366,33 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void) { val = source[(frac>>FRACBITS) & heightmask]; if (val != TRANSPARENTPIXEL) - *dest = *(transmap + (colormap[val]<<8) + (*dest)); + { + if (brightmap != NULL && brightmap[(frac>>FRACBITS) & heightmask] == BRIGHTPIXEL) + { + *dest = *(transmap + (fullbright[val]<<8) + (*dest)); + } + else + { + *dest = *(transmap + (colormap[val]<<8) + (*dest)); + } + } + dest += vid.width; frac += fracstep; + val = source[(frac>>FRACBITS) & heightmask]; if (val != TRANSPARENTPIXEL) - *dest = *(transmap + (colormap[val]<<8) + (*dest)); + { + if (brightmap != NULL && brightmap[(frac>>FRACBITS) & heightmask] == BRIGHTPIXEL) + { + *dest = *(transmap + (fullbright[val]<<8) + (*dest)); + } + else + { + *dest = *(transmap + (colormap[val]<<8) + (*dest)); + } + } + dest += vid.width; frac += fracstep; } @@ -292,7 +400,16 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void) { val = source[(frac>>FRACBITS) & heightmask]; if (val != TRANSPARENTPIXEL) - *dest = *(transmap + (colormap[val]<<8) + (*dest)); + { + if (brightmap != NULL && brightmap[(frac>>FRACBITS) & heightmask] == BRIGHTPIXEL) + { + *dest = *(transmap + (fullbright[val]<<8) + (*dest)); + } + else + { + *dest = *(transmap + (colormap[val]<<8) + (*dest)); + } + } } } } @@ -372,8 +489,10 @@ void R_DrawTranslucentColumn_8(void) // This is as fast as it gets. { register const UINT8 *source = dc_source; + register const UINT8 *brightmap = dc_brightmap; register const UINT8 *transmap = dc_transmap; register const lighttable_t *colormap = dc_colormap; + register const lighttable_t *fullbright = dc_fullbright; register INT32 heightmask = dc_texheight - 1; if (dc_texheight & heightmask) { @@ -392,7 +511,14 @@ void R_DrawTranslucentColumn_8(void) // Re-map color indices from wall texture column // using a lighting/special effects LUT. // heightmask is the Tutti-Frutti fix - *dest = *(transmap + (colormap[source[frac>>FRACBITS]]<<8) + (*dest)); + if (brightmap != NULL && brightmap[frac>>FRACBITS] == BRIGHTPIXEL) + { + *dest = *(transmap + (fullbright[source[frac>>FRACBITS]]<<8) + (*dest)); + } + else + { + *dest = *(transmap + (colormap[source[frac>>FRACBITS]]<<8) + (*dest)); + } dest += vid.width; if ((frac += fracstep) >= heightmask) frac -= heightmask; @@ -403,15 +529,39 @@ void R_DrawTranslucentColumn_8(void) { while ((count -= 2) >= 0) // texture height is a power of 2 { - *dest = *(transmap + (colormap[source[(frac>>FRACBITS)&heightmask]]<<8) + (*dest)); + if (brightmap != NULL && brightmap[(frac>>FRACBITS)&heightmask] == BRIGHTPIXEL) + { + *dest = *(transmap + (fullbright[source[(frac>>FRACBITS)&heightmask]]<<8) + (*dest)); + } + else + { + *dest = *(transmap + (colormap[source[(frac>>FRACBITS)&heightmask]]<<8) + (*dest)); + } dest += vid.width; frac += fracstep; - *dest = *(transmap + (colormap[source[(frac>>FRACBITS)&heightmask]]<<8) + (*dest)); + + if (brightmap != NULL && brightmap[(frac>>FRACBITS)&heightmask] == BRIGHTPIXEL) + { + *dest = *(transmap + (fullbright[source[(frac>>FRACBITS)&heightmask]]<<8) + (*dest)); + } + else + { + *dest = *(transmap + (colormap[source[(frac>>FRACBITS)&heightmask]]<<8) + (*dest)); + } dest += vid.width; frac += fracstep; } if (count & 1) - *dest = *(transmap + (colormap[source[(frac>>FRACBITS)&heightmask]]<<8) + (*dest)); + { + if (brightmap != NULL && brightmap[(frac>>FRACBITS)&heightmask] == BRIGHTPIXEL) + { + *dest = *(transmap + (fullbright[source[(frac>>FRACBITS)&heightmask]]<<8) + (*dest)); + } + else + { + *dest = *(transmap + (colormap[source[(frac>>FRACBITS)&heightmask]]<<8) + (*dest)); + } + } } } } @@ -462,7 +612,14 @@ void R_DrawTranslatedTranslucentColumn_8(void) // using a lighting/special effects LUT. // heightmask is the Tutti-Frutti fix - *dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]<<8) + (*dest)); + if (dc_brightmap != NULL && dc_brightmap[frac>>FRACBITS] == BRIGHTPIXEL) + { + *dest = *(dc_transmap + (dc_fullbright[dc_translation[dc_source[frac>>FRACBITS]]]<<8) + (*dest)); + } + else + { + *dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]<<8) + (*dest)); + } dest += vid.width; if ((frac += fracstep) >= heightmask) @@ -474,15 +631,41 @@ void R_DrawTranslatedTranslucentColumn_8(void) { while ((count -= 2) >= 0) // texture height is a power of 2 { - *dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); + if (dc_brightmap != NULL && dc_brightmap[(frac>>FRACBITS)&heightmask] == BRIGHTPIXEL) + { + *dest = *(dc_transmap + (dc_fullbright[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); + } + else + { + *dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); + } + dest += vid.width; frac += fracstep; - *dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); + + if (dc_brightmap != NULL && dc_brightmap[(frac>>FRACBITS)&heightmask] == BRIGHTPIXEL) + { + *dest = *(dc_transmap + (dc_fullbright[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); + } + else + { + *dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); + } + dest += vid.width; frac += fracstep; } if (count & 1) - *dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); + { + if (dc_brightmap != NULL && dc_brightmap[(frac>>FRACBITS)&heightmask] == BRIGHTPIXEL) + { + *dest = *(dc_transmap + (dc_fullbright[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); + } + else + { + *dest = *(dc_transmap + (dc_colormap[dc_translation[dc_source[(frac>>FRACBITS)&heightmask]]]<<8) + (*dest)); + } + } } } } @@ -524,7 +707,14 @@ void R_DrawTranslatedColumn_8(void) // used with PLAY sprites. // Thus the "green" ramp of the player 0 sprite // is mapped to gray, red, black/indigo. - *dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]; + if (dc_brightmap != NULL && dc_brightmap[frac>>FRACBITS] == BRIGHTPIXEL) + { + *dest = dc_fullbright[dc_translation[dc_source[frac>>FRACBITS]]]; + } + else + { + *dest = dc_colormap[dc_translation[dc_source[frac>>FRACBITS]]]; + } dest += vid.width; @@ -539,6 +729,9 @@ void R_DrawTranslatedColumn_8(void) #define SPANSIZE 16 #define INVSPAN 0.0625f +// 4194303 = (2048x2048)-1 (2048x2048 is maximum flat size) +#define MAXFLATBYTES 4194303 + /** \brief The R_DrawSpan_8 function Draws the actual span. */ @@ -547,13 +740,17 @@ void R_DrawSpan_8 (void) fixed_t xposition; fixed_t yposition; fixed_t xstep, ystep; + UINT32 bit; UINT8 *source; + UINT8 *brightmap; UINT8 *colormap; + UINT8 *fullbright; UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; size_t count = (ds_x2 - ds_x1 + 1); + size_t i; xposition = ds_xfrac; yposition = ds_yfrac; xstep = ds_xstep; ystep = ds_ystep; @@ -569,7 +766,9 @@ void R_DrawSpan_8 (void) xstep <<= nflatshiftup; ystep <<= nflatshiftup; source = ds_source; + brightmap = ds_brightmap; colormap = ds_colormap; + fullbright = ds_fullbright; dest = ylookup[ds_y] + columnofs[ds_x1]; if (dest+8 > deststop) @@ -580,44 +779,37 @@ void R_DrawSpan_8 (void) // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't // have the uber complicated math to calculate it now, so that was a memory write we didn't // need! - dest[0] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; - dest[1] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; - - dest[2] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; - - dest[3] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; - - dest[4] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; - - dest[5] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; - - dest[6] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; - - dest[7] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; + for (i = 0; i < 8; i++) + { + bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + dest[i] = fullbright[source[bit]]; + } + else + { + dest[i] = colormap[source[bit]]; + } + xposition += xstep; + yposition += ystep; + } dest += 8; count -= 8; } while (count-- && dest <= deststop) { - *dest++ = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest++ = fullbright[source[bit]]; + } + else + { + *dest++ = colormap[source[bit]]; + } + xposition += xstep; yposition += ystep; } @@ -658,13 +850,16 @@ void R_DrawTiltedSpan_8(void) int i; UINT8 *source; + UINT8 *brightmap; UINT8 *colormap; + UINT8 *fullbright; UINT8 *dest; double startz, startu, startv; double izstep, uzstep, vzstep; double endz, endu, endv; UINT32 stepu, stepv; + UINT32 bit; iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); @@ -684,8 +879,11 @@ void R_DrawTiltedSpan_8(void) vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds_source; + brightmap = ds_brightmap; //colormap = ds_colormap; + fullbright = ds_fullbright; #if 0 // The "perfect" reference version of this routine. Pretty slow. // Use it only to see how things are supposed to look. @@ -695,10 +893,16 @@ void R_DrawTiltedSpan_8(void) double z = 1.f/iz; u = (INT64)(uz*z) + viewx; v = (INT64)(vz*z) + viewy; - - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - - *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = fullbright[source[bit]]; + } + else + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[source[bit]]; + } dest++; iz += ds_szp->x; uz += ds_sup->x; @@ -731,8 +935,16 @@ void R_DrawTiltedSpan_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = fullbright[source[bit]]; + } + else + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[source[bit]]; + } dest++; u += stepu; v += stepv; @@ -747,8 +959,16 @@ void R_DrawTiltedSpan_8(void) { u = (INT64)(startu); v = (INT64)(startv); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = fullbright[source[bit]]; + } + else + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[source[bit]]; + } } else { @@ -768,8 +988,16 @@ void R_DrawTiltedSpan_8(void) for (; width != 0; width--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = fullbright[source[bit]]; + } + else + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[source[bit]]; + } dest++; u += stepu; v += stepv; @@ -791,13 +1019,16 @@ void R_DrawTiltedTranslucentSpan_8(void) int i; UINT8 *source; + UINT8 *brightmap; UINT8 *colormap; + UINT8 *fullbright; UINT8 *dest; double startz, startu, startv; double izstep, uzstep, vzstep; double endz, endu, endv; UINT32 stepu, stepv; + UINT32 bit; iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); @@ -817,8 +1048,11 @@ void R_DrawTiltedTranslucentSpan_8(void) vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds_source; + brightmap = ds_brightmap; //colormap = ds_colormap; + fullbright = ds_fullbright; #if 0 // The "perfect" reference version of this routine. Pretty slow. // Use it only to see how things are supposed to look. @@ -829,8 +1063,16 @@ void R_DrawTiltedTranslucentSpan_8(void) u = (INT64)(uz*z) + viewx; v = (INT64)(vz*z) + viewy; - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = *(ds_transmap + (fullbright[source[bit]] << 8) + *dest); + } + else + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dest); + } dest++; iz += ds_szp->x; uz += ds_sup->x; @@ -863,8 +1105,16 @@ void R_DrawTiltedTranslucentSpan_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = *(ds_transmap + (fullbright[source[bit]] << 8) + *dest); + } + else + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dest); + } dest++; u += stepu; v += stepv; @@ -879,8 +1129,16 @@ void R_DrawTiltedTranslucentSpan_8(void) { u = (INT64)(startu); v = (INT64)(startv); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = *(ds_transmap + (fullbright[source[bit]] << 8) + *dest); + } + else + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dest); + } } else { @@ -900,8 +1158,16 @@ void R_DrawTiltedTranslucentSpan_8(void) for (; width != 0; width--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = *(ds_transmap + (fullbright[source[bit]] << 8) + *dest); + } + else + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dest); + } dest++; u += stepu; v += stepv; @@ -923,7 +1189,9 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) int i; UINT8 *source; + UINT8 *brightmap; UINT8 *colormap; + UINT8 *fullbright; UINT8 *dest; UINT8 *dsrc; @@ -931,6 +1199,7 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) double izstep, uzstep, vzstep; double endz, endu, endv; UINT32 stepu, stepv; + UINT32 bit; iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); @@ -952,7 +1221,9 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) dest = ylookup[ds_y] + columnofs[ds_x1]; dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1; source = ds_source; + brightmap = ds_brightmap; //colormap = ds_colormap; + fullbright = ds_fullbright; #if 0 // The "perfect" reference version of this routine. Pretty slow. // Use it only to see how things are supposed to look. @@ -963,8 +1234,16 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) u = (INT64)(uz*z) + viewx; v = (INT64)(vz*z) + viewy; - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++); + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = *(ds_transmap + (fullbright[source[bit]] << 8) + *dsrc++); + } + else + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dsrc++); + } dest++; iz += ds_szp->x; uz += ds_sup->x; @@ -997,8 +1276,16 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++); + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = *(ds_transmap + (fullbright[source[bit]] << 8) + *dsrc++); + } + else + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dsrc++); + } dest++; u += stepu; v += stepv; @@ -1013,8 +1300,16 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) { u = (INT64)(startu); v = (INT64)(startv); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++); + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = *(ds_transmap + (fullbright[source[bit]] << 8) + *dsrc++); + } + else + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dsrc++); + } } else { @@ -1034,8 +1329,16 @@ void R_DrawTiltedTranslucentWaterSpan_8(void) for (; width != 0; width--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++); + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = *(ds_transmap + (fullbright[source[bit]] << 8) + *dsrc++); + } + else + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dsrc++); + } dest++; u += stepu; v += stepv; @@ -1054,7 +1357,9 @@ void R_DrawTiltedSplat_8(void) int i; UINT8 *source; + UINT8 *brightmap; UINT8 *colormap; + UINT8 *fullbright; UINT8 *dest; UINT8 val; @@ -1063,6 +1368,7 @@ void R_DrawTiltedSplat_8(void) double izstep, uzstep, vzstep; double endz, endu, endv; UINT32 stepu, stepv; + UINT32 bit; iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); @@ -1082,8 +1388,11 @@ void R_DrawTiltedSplat_8(void) vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds_source; + brightmap = ds_brightmap; //colormap = ds_colormap; + fullbright = ds_fullbright; #if 0 // The "perfect" reference version of this routine. Pretty slow. // Use it only to see how things are supposed to look. @@ -1094,11 +1403,20 @@ void R_DrawTiltedSplat_8(void) u = (INT64)(uz*z) + viewx; v = (INT64)(vz*z) + viewy; - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + val = source[bit]; if (val != TRANSPARENTPIXEL) - *dest = colormap[val]; + { + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = fullbright[val]; + } + else + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[val]; + } + } dest++; iz += ds_szp->x; @@ -1132,10 +1450,20 @@ void R_DrawTiltedSplat_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + val = source[bit]; if (val != TRANSPARENTPIXEL) - *dest = colormap[val]; + { + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = fullbright[val]; + } + else + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[val]; + } + } dest++; u += stepu; v += stepv; @@ -1150,10 +1478,20 @@ void R_DrawTiltedSplat_8(void) { u = (INT64)(startu); v = (INT64)(startv); - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + val = source[bit]; if (val != TRANSPARENTPIXEL) - *dest = colormap[val]; + { + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = fullbright[val]; + } + else + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[val]; + } + } } else { @@ -1173,10 +1511,20 @@ void R_DrawTiltedSplat_8(void) for (; width != 0; width--) { - colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + val = source[bit]; if (val != TRANSPARENTPIXEL) - *dest = colormap[val]; + { + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = fullbright[val]; + } + else + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[val]; + } + } dest++; u += stepu; v += stepv; @@ -1194,13 +1542,17 @@ void R_DrawSplat_8 (void) fixed_t xposition; fixed_t yposition; fixed_t xstep, ystep; + UINT32 bit; UINT8 *source; + UINT8 *brightmap; UINT8 *colormap; + UINT8 *fullbright; UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; size_t count = (ds_x2 - ds_x1 + 1); + size_t i; UINT32 val; xposition = ds_xfrac; yposition = ds_yfrac; @@ -1217,7 +1569,9 @@ void R_DrawSplat_8 (void) xstep <<= nflatshiftup; ystep <<= nflatshiftup; source = ds_source; + brightmap = ds_brightmap; colormap = ds_colormap; + fullbright = ds_fullbright; dest = ylookup[ds_y] + columnofs[ds_x1]; while (count >= 8) @@ -1225,80 +1579,44 @@ void R_DrawSplat_8 (void) // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't // have the uber complicated math to calculate it now, so that was a memory write we didn't // need! - // - // 4194303 = (2048x2048)-1 (2048x2048 is maximum flat size) - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[0] = colormap[val]; - xposition += xstep; - yposition += ystep; - - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[1] = colormap[val]; - xposition += xstep; - yposition += ystep; - - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[2] = colormap[val]; - xposition += xstep; - yposition += ystep; - - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[3] = colormap[val]; - xposition += xstep; - yposition += ystep; - - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[4] = colormap[val]; - xposition += xstep; - yposition += ystep; - - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[5] = colormap[val]; - xposition += xstep; - yposition += ystep; - - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[6] = colormap[val]; - xposition += xstep; - yposition += ystep; - - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[7] = colormap[val]; - xposition += xstep; - yposition += ystep; + for (i = 0; i < 8; i++) + { + bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + bit &= MAXFLATBYTES; + val = source[bit]; + if (val != TRANSPARENTPIXEL) + { + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + dest[i] = fullbright[val]; + } + else + { + dest[i] = colormap[val]; + } + } + xposition += xstep; + yposition += ystep; + } dest += 8; count -= 8; } while (count-- && dest <= deststop) { - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = source[bit]; if (val != TRANSPARENTPIXEL) - *dest = colormap[val]; + { + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = fullbright[val]; + } + else + { + *dest = colormap[val]; + } + } dest++; xposition += xstep; yposition += ystep; @@ -1313,13 +1631,17 @@ void R_DrawTranslucentSplat_8 (void) fixed_t xposition; fixed_t yposition; fixed_t xstep, ystep; + UINT32 bit; UINT8 *source; + UINT8 *brightmap; UINT8 *colormap; + UINT8 *fullbright; UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; size_t count = (ds_x2 - ds_x1 + 1); + size_t i; UINT32 val; xposition = ds_xfrac; yposition = ds_yfrac; @@ -1336,7 +1658,9 @@ void R_DrawTranslucentSplat_8 (void) xstep <<= nflatshiftup; ystep <<= nflatshiftup; source = ds_source; + brightmap = ds_brightmap; colormap = ds_colormap; + fullbright = ds_fullbright; dest = ylookup[ds_y] + columnofs[ds_x1]; while (count >= 8) @@ -1344,62 +1668,45 @@ void R_DrawTranslucentSplat_8 (void) // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't // have the uber complicated math to calculate it now, so that was a memory write we didn't // need! - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[0] = *(ds_transmap + (colormap[val] << 8) + dest[0]); - xposition += xstep; - yposition += ystep; - - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[1] = *(ds_transmap + (colormap[val] << 8) + dest[1]); - xposition += xstep; - yposition += ystep; - - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[2] = *(ds_transmap + (colormap[val] << 8) + dest[2]); - xposition += xstep; - yposition += ystep; - - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[3] = *(ds_transmap + (colormap[val] << 8) + dest[3]); - xposition += xstep; - yposition += ystep; - - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[4] = *(ds_transmap + (colormap[val] << 8) + dest[4]); - xposition += xstep; - yposition += ystep; - - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[5] = *(ds_transmap + (colormap[val] << 8) + dest[5]); - xposition += xstep; - yposition += ystep; - - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[6] = *(ds_transmap + (colormap[val] << 8) + dest[6]); - xposition += xstep; - yposition += ystep; - - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[7] = *(ds_transmap + (colormap[val] << 8) + dest[7]); - xposition += xstep; - yposition += ystep; + for (i = 0; i < 8; i++) + { + bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = source[bit]; + if (val != TRANSPARENTPIXEL) + { + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + dest[i] = *(ds_transmap + (fullbright[val] << 8) + dest[i]); + } + else + { + dest[i] = *(ds_transmap + (colormap[val] << 8) + dest[i]); + } + + } + xposition += xstep; + yposition += ystep; + } dest += 8; count -= 8; } while (count-- && dest <= deststop) { - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = source[bit]; if (val != TRANSPARENTPIXEL) - *dest = *(ds_transmap + (colormap[val] << 8) + *dest); + { + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = *(ds_transmap + (fullbright[val] << 8) + *dest); + } + else + { + *dest = *(ds_transmap + (colormap[val] << 8) + *dest); + } + + } dest++; xposition += xstep; yposition += ystep; @@ -1414,14 +1721,18 @@ void R_DrawFloorSprite_8 (void) fixed_t xposition; fixed_t yposition; fixed_t xstep, ystep; + UINT32 bit; UINT16 *source; + UINT16 *brightmap; UINT8 *colormap; + UINT8 *fullbright; UINT8 *translation; UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; size_t count = (ds_x2 - ds_x1 + 1); + size_t i; UINT32 val; xposition = ds_xfrac; yposition = ds_yfrac; @@ -1438,7 +1749,9 @@ void R_DrawFloorSprite_8 (void) xstep <<= nflatshiftup; ystep <<= nflatshiftup; source = (UINT16 *)ds_source; + brightmap = (UINT16 *)ds_brightmap; colormap = ds_colormap; + fullbright = ds_fullbright; translation = ds_translation; dest = ylookup[ds_y] + columnofs[ds_x1]; @@ -1447,70 +1760,43 @@ void R_DrawFloorSprite_8 (void) // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't // have the uber complicated math to calculate it now, so that was a memory write we didn't // need! - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val = source[val]; - if (val & 0xFF00) - dest[0] = colormap[translation[val & 0xFF]]; - xposition += xstep; - yposition += ystep; - - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val = source[val]; - if (val & 0xFF00) - dest[1] = colormap[translation[val & 0xFF]]; - xposition += xstep; - yposition += ystep; - - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val = source[val]; - if (val & 0xFF00) - dest[2] = colormap[translation[val & 0xFF]]; - xposition += xstep; - yposition += ystep; - - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val = source[val]; - if (val & 0xFF00) - dest[3] = colormap[translation[val & 0xFF]]; - xposition += xstep; - yposition += ystep; - - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val = source[val]; - if (val & 0xFF00) - dest[4] = colormap[translation[val & 0xFF]]; - xposition += xstep; - yposition += ystep; - - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val = source[val]; - if (val & 0xFF00) - dest[5] = colormap[translation[val & 0xFF]]; - xposition += xstep; - yposition += ystep; - - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val = source[val]; - if (val & 0xFF00) - dest[6] = colormap[translation[val & 0xFF]]; - xposition += xstep; - yposition += ystep; - - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val = source[val]; - if (val & 0xFF00) - dest[7] = colormap[translation[val & 0xFF]]; - xposition += xstep; - yposition += ystep; + for (i = 0; i < 8; i++) + { + bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = source[bit]; + if (val & 0xFF00) + { + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = fullbright[translation[val & 0xFF]]; + } + else + { + *dest = colormap[translation[val & 0xFF]]; + } + } + xposition += xstep; + yposition += ystep; + } dest += 8; count -= 8; } while (count-- && dest <= deststop) { - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = source[bit]; if (val & 0xFF00) - *dest = colormap[translation[val & 0xFF]]; + { + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = fullbright[translation[val & 0xFF]]; + } + else + { + *dest = colormap[translation[val & 0xFF]]; + } + } dest++; xposition += xstep; yposition += ystep; @@ -1525,14 +1811,18 @@ void R_DrawTranslucentFloorSprite_8 (void) fixed_t xposition; fixed_t yposition; fixed_t xstep, ystep; + UINT32 bit; UINT16 *source; + UINT16 *brightmap; UINT8 *colormap; + UINT8 *fullbright; UINT8 *translation; UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; size_t count = (ds_x2 - ds_x1 + 1); + size_t i; UINT32 val; xposition = ds_xfrac; yposition = ds_yfrac; @@ -1549,7 +1839,9 @@ void R_DrawTranslucentFloorSprite_8 (void) xstep <<= nflatshiftup; ystep <<= nflatshiftup; source = (UINT16 *)ds_source; + brightmap = (UINT16 *)ds_brightmap; colormap = ds_colormap; + fullbright = ds_fullbright; translation = ds_translation; dest = ylookup[ds_y] + columnofs[ds_x1]; @@ -1558,62 +1850,43 @@ void R_DrawTranslucentFloorSprite_8 (void) // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't // have the uber complicated math to calculate it now, so that was a memory write we didn't // need! - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val & 0xFF00) - dest[0] = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + dest[0]); - xposition += xstep; - yposition += ystep; - - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val & 0xFF00) - dest[1] = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + dest[1]); - xposition += xstep; - yposition += ystep; - - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val & 0xFF00) - dest[2] = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + dest[2]); - xposition += xstep; - yposition += ystep; - - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val & 0xFF00) - dest[3] = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + dest[3]); - xposition += xstep; - yposition += ystep; - - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val & 0xFF00) - dest[4] = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + dest[4]); - xposition += xstep; - yposition += ystep; - - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val & 0xFF00) - dest[5] = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + dest[5]); - xposition += xstep; - yposition += ystep; - - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val & 0xFF00) - dest[6] = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + dest[6]); - xposition += xstep; - yposition += ystep; - - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val & 0xFF00) - dest[7] = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + dest[7]); - xposition += xstep; - yposition += ystep; + for (i = 0; i < 8; i++) + { + bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = source[bit]; + if (val & 0xFF00) + { + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + dest[i] = *(ds_transmap + (fullbright[translation[val & 0xFF]] << 8) + dest[i]); + } + else + { + dest[i] = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + dest[i]); + } + } + xposition += xstep; + yposition += ystep; + } dest += 8; count -= 8; } while (count-- && dest <= deststop) { - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val = source[bit]; if (val & 0xFF00) - *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + { + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = *(ds_transmap + (fullbright[translation[val & 0xFF]] << 8) + *dest); + } + else + { + *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + } + } dest++; xposition += xstep; yposition += ystep; @@ -1632,7 +1905,9 @@ void R_DrawTiltedFloorSprite_8(void) int i; UINT16 *source; + UINT16 *brightmap; UINT8 *colormap; + UINT8 *fullbright; UINT8 *translation; UINT8 *dest; UINT16 val; @@ -1641,6 +1916,7 @@ void R_DrawTiltedFloorSprite_8(void) double izstep, uzstep, vzstep; double endz, endu, endv; UINT32 stepu, stepv; + UINT32 bit; iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); @@ -1648,7 +1924,9 @@ void R_DrawTiltedFloorSprite_8(void) dest = ylookup[ds_y] + columnofs[ds_x1]; source = (UINT16 *)ds_source; + brightmap = (UINT16 *)ds_brightmap; colormap = ds_colormap; + fullbright = ds_fullbright; translation = ds_translation; startz = 1.f/iz; @@ -1677,9 +1955,19 @@ void R_DrawTiltedFloorSprite_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + val = source[bit]; if (val & 0xFF00) - *dest = colormap[translation[val & 0xFF]]; + { + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = fullbright[translation[val & 0xFF]]; + } + else + { + *dest = colormap[translation[val & 0xFF]]; + } + } dest++; u += stepu; @@ -1695,9 +1983,19 @@ void R_DrawTiltedFloorSprite_8(void) { u = (INT64)(startu); v = (INT64)(startv); - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + val = source[bit]; if (val & 0xFF00) - *dest = colormap[translation[val & 0xFF]]; + { + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = fullbright[translation[val & 0xFF]]; + } + else + { + *dest = colormap[translation[val & 0xFF]]; + } + } } else { @@ -1717,9 +2015,19 @@ void R_DrawTiltedFloorSprite_8(void) for (; width != 0; width--) { - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + val = source[bit]; if (val & 0xFF00) - *dest = colormap[translation[val & 0xFF]]; + { + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = fullbright[translation[val & 0xFF]]; + } + else + { + *dest = colormap[translation[val & 0xFF]]; + } + } dest++; u += stepu; @@ -1741,7 +2049,9 @@ void R_DrawTiltedTranslucentFloorSprite_8(void) int i; UINT16 *source; + UINT16 *brightmap; UINT8 *colormap; + UINT8 *fullbright; UINT8 *translation; UINT8 *dest; UINT16 val; @@ -1750,6 +2060,7 @@ void R_DrawTiltedTranslucentFloorSprite_8(void) double izstep, uzstep, vzstep; double endz, endu, endv; UINT32 stepu, stepv; + UINT32 bit; iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); @@ -1757,7 +2068,9 @@ void R_DrawTiltedTranslucentFloorSprite_8(void) dest = ylookup[ds_y] + columnofs[ds_x1]; source = (UINT16 *)ds_source; + brightmap = (UINT16 *)ds_brightmap; colormap = ds_colormap; + fullbright = ds_fullbright; translation = ds_translation; startz = 1.f/iz; @@ -1786,9 +2099,19 @@ void R_DrawTiltedTranslucentFloorSprite_8(void) for (i = SPANSIZE-1; i >= 0; i--) { - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + val = source[bit]; if (val & 0xFF00) - *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + { + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = *(ds_transmap + (fullbright[translation[val & 0xFF]] << 8) + *dest); + } + else + { + *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + } + } dest++; u += stepu; @@ -1804,9 +2127,19 @@ void R_DrawTiltedTranslucentFloorSprite_8(void) { u = (INT64)(startu); v = (INT64)(startv); - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + val = source[bit]; if (val & 0xFF00) - *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + { + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = *(ds_transmap + (fullbright[translation[val & 0xFF]] << 8) + *dest); + } + else + { + *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + } + } } else { @@ -1826,9 +2159,19 @@ void R_DrawTiltedTranslucentFloorSprite_8(void) for (; width != 0; width--) { - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + bit = ((v >> nflatyshift) & nflatmask) | (u >> nflatxshift); + val = source[bit]; if (val & 0xFF00) - *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + { + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = *(ds_transmap + (fullbright[translation[val & 0xFF]] << 8) + *dest); + } + else + { + *dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest); + } + } dest++; u += stepu; @@ -1846,14 +2189,17 @@ void R_DrawTranslucentSpan_8 (void) fixed_t xposition; fixed_t yposition; fixed_t xstep, ystep; + UINT32 bit; UINT8 *source; + UINT8 *brightmap; UINT8 *colormap; + UINT8 *fullbright; UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; size_t count = (ds_x2 - ds_x1 + 1); - UINT32 val; + size_t i; xposition = ds_xfrac; yposition = ds_yfrac; xstep = ds_xstep; ystep = ds_ystep; @@ -1869,7 +2215,9 @@ void R_DrawTranslucentSpan_8 (void) xstep <<= nflatshiftup; ystep <<= nflatshiftup; source = ds_source; + brightmap = ds_brightmap; colormap = ds_colormap; + fullbright = ds_fullbright; dest = ylookup[ds_y] + columnofs[ds_x1]; while (count >= 8) @@ -1877,45 +2225,35 @@ void R_DrawTranslucentSpan_8 (void) // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't // have the uber complicated math to calculate it now, so that was a memory write we didn't // need! - dest[0] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[0]); - xposition += xstep; - yposition += ystep; - - dest[1] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[1]); - xposition += xstep; - yposition += ystep; - - dest[2] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[2]); - xposition += xstep; - yposition += ystep; - - dest[3] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[3]); - xposition += xstep; - yposition += ystep; - - dest[4] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[4]); - xposition += xstep; - yposition += ystep; - - dest[5] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[5]); - xposition += xstep; - yposition += ystep; - - dest[6] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[6]); - xposition += xstep; - yposition += ystep; - - dest[7] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[7]); - xposition += xstep; - yposition += ystep; + for (i = 0; i < 8; i++) + { + bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + dest[i] = *(ds_transmap + (fullbright[source[bit]] << 8) + dest[i]); + } + else + { + dest[i] = *(ds_transmap + (colormap[source[bit]] << 8) + dest[i]); + } + xposition += xstep; + yposition += ystep; + } dest += 8; count -= 8; } while (count-- && dest <= deststop) { - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - *dest = *(ds_transmap + (colormap[source[val]] << 8) + *dest); + bit = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest = *(ds_transmap + (fullbright[source[bit]] << 8) + *dest); + } + else + { + *dest = *(ds_transmap + (colormap[source[bit]] << 8) + *dest); + } dest++; xposition += xstep; yposition += ystep; @@ -1927,13 +2265,17 @@ void R_DrawTranslucentWaterSpan_8(void) UINT32 xposition; UINT32 yposition; UINT32 xstep, ystep; + UINT32 bit; UINT8 *source; + UINT8 *brightmap; UINT8 *colormap; + UINT8 *fullbright; UINT8 *dest; UINT8 *dsrc; size_t count; + size_t i; // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest // can be used for the fraction part. This allows calculation of the memory address in the @@ -1946,7 +2288,9 @@ void R_DrawTranslucentWaterSpan_8(void) xstep = ds_xstep << nflatshiftup; ystep = ds_ystep << nflatshiftup; source = ds_source; + brightmap = ds_brightmap; colormap = ds_colormap; + fullbright = ds_fullbright; dest = ylookup[ds_y] + columnofs[ds_x1]; dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1; count = ds_x2 - ds_x1 + 1; @@ -1956,44 +2300,35 @@ void R_DrawTranslucentWaterSpan_8(void) // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't // have the uber complicated math to calculate it now, so that was a memory write we didn't // need! - dest[0] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; - xposition += xstep; - yposition += ystep; - - dest[1] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; - xposition += xstep; - yposition += ystep; - - dest[2] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; - xposition += xstep; - yposition += ystep; - - dest[3] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; - xposition += xstep; - yposition += ystep; - - dest[4] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; - xposition += xstep; - yposition += ystep; - - dest[5] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; - xposition += xstep; - yposition += ystep; - - dest[6] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; - xposition += xstep; - yposition += ystep; - - dest[7] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; - xposition += xstep; - yposition += ystep; + for (i = 0; i < 8; i++) + { + bit = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift); + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + dest[i] = fullbright[*(ds_transmap + (source[bit] << 8) + *dsrc++)]; + } + else + { + dest[i] = colormap[*(ds_transmap + (source[bit] << 8) + *dsrc++)]; + } + xposition += xstep; + yposition += ystep; + } dest += 8; count -= 8; } while (count--) { - *dest++ = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; + bit = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift); + if (brightmap != NULL && brightmap[bit] == BRIGHTPIXEL) + { + *dest++ = fullbright[*(ds_transmap + (source[bit] << 8) + *dsrc++)]; + } + else + { + *dest++ = colormap[*(ds_transmap + (source[bit] << 8) + *dsrc++)]; + } xposition += xstep; yposition += ystep; } @@ -2114,8 +2449,12 @@ void R_DrawColumnShadowed_8(void) if (height <= dc_yl) { dc_colormap = dc_lightlist[i].rcolormap; + dc_fullbright = colormaps; if (encoremap) + { dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } if (solid && dc_yl < bheight) dc_yl = bheight; continue; @@ -2132,8 +2471,12 @@ void R_DrawColumnShadowed_8(void) dc_yl = dc_yh + 1; dc_colormap = dc_lightlist[i].rcolormap; + dc_fullbright = colormaps; if (encoremap) + { dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } } dc_yh = realyh; if (dc_yl <= realyh) diff --git a/src/r_fps.c b/src/r_fps.c new file mode 100644 index 000000000..7258d3b75 --- /dev/null +++ b/src/r_fps.c @@ -0,0 +1,149 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1993-1996 by id Software, Inc. +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2000 by Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze, Andrey Budko (prboom) +// Copyright (C) 1999-2019 by Sonic Team Junior. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file r_fps.h +/// \brief Uncapped framerate stuff. + +#include "r_fps.h" + +#include "r_main.h" +#include "g_game.h" +#include "i_video.h" +#include "r_plane.h" +#include "p_spec.h" +#include "r_state.h" +#ifdef HWRENDER +#include "hardware/hw_main.h" // for cv_glshearing +#endif + +static viewvars_t pview_old[MAXSPLITSCREENPLAYERS]; +static viewvars_t pview_new[MAXSPLITSCREENPLAYERS]; +static viewvars_t skyview_old[MAXSPLITSCREENPLAYERS]; +static viewvars_t skyview_new[MAXSPLITSCREENPLAYERS]; + +static viewvars_t *oldview = &pview_old[0]; +viewvars_t *newview = &pview_new[0]; + + +enum viewcontext_e viewcontext = VIEWCONTEXT_PLAYER1; + +static fixed_t R_LerpFixed(fixed_t from, fixed_t to, fixed_t frac) +{ + return FixedMul(frac, to - from); +} + +static angle_t R_LerpAngle(angle_t from, angle_t to, fixed_t frac) +{ + return FixedMul(frac, to - from); +} + +// recalc necessary stuff for mouseaiming +// 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) +static void R_SetupFreelook(player_t *player, boolean skybox) +{ +#ifndef HWRENDER + (void)player; + (void)skybox; +#endif + + // clip it in the case we are looking a hardware 90 degrees full aiming + // (lmps, network and use F12...) + if (rendermode == render_soft +#ifdef HWRENDER + || (rendermode == render_opengl + && (cv_glshearing.value == 1 + || (cv_glshearing.value == 2 && R_IsViewpointThirdPerson(player, skybox)))) +#endif + ) + { + G_SoftwareClipAimingPitch((INT32 *)&aimingangle); + } + + centeryfrac = (viewheight/2)< FRACUNIT) + frac = FRACUNIT; + + viewx = oldview->x + R_LerpFixed(oldview->x, newview->x, frac); + viewy = oldview->y + R_LerpFixed(oldview->y, newview->y, frac); + viewz = oldview->z + R_LerpFixed(oldview->z, newview->z, frac); + + viewangle = oldview->angle + R_LerpAngle(oldview->angle, newview->angle, frac); + aimingangle = oldview->aim + R_LerpAngle(oldview->aim, newview->aim, frac); + viewroll = oldview->roll + R_LerpAngle(oldview->roll, newview->roll, frac); + + viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); + viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); + + viewplayer = newview->player; + viewsector = R_PointInSubsector(viewx, viewy)->sector; + + R_SetupFreelook(newview->player, newview->sky); +} + +void R_UpdateViewInterpolation(void) +{ + UINT8 i; + + for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) + { + pview_old[i] = pview_new[i]; + skyview_old[i] = skyview_new[i]; + } +} + +void R_SetViewContext(enum viewcontext_e _viewcontext) +{ + UINT8 i = 0; + + I_Assert(_viewcontext >= VIEWCONTEXT_PLAYER1 + && _viewcontext <= VIEWCONTEXT_SKY4); + viewcontext = _viewcontext; + + switch (viewcontext) + { + case VIEWCONTEXT_PLAYER1: + case VIEWCONTEXT_PLAYER2: + case VIEWCONTEXT_PLAYER3: + case VIEWCONTEXT_PLAYER4: + i = viewcontext - VIEWCONTEXT_PLAYER1; + oldview = &pview_old[i]; + newview = &pview_new[i]; + break; + case VIEWCONTEXT_SKY1: + case VIEWCONTEXT_SKY2: + case VIEWCONTEXT_SKY3: + case VIEWCONTEXT_SKY4: + i = viewcontext - VIEWCONTEXT_SKY1; + oldview = &skyview_old[i]; + newview = &skyview_new[i]; + break; + default: + I_Error("viewcontext value is invalid: we should never get here without an assert!!"); + break; + } +} diff --git a/src/r_fps.h b/src/r_fps.h new file mode 100644 index 000000000..eb674b142 --- /dev/null +++ b/src/r_fps.h @@ -0,0 +1,59 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1993-1996 by id Software, Inc. +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2000 by Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze, Andrey Budko (prboom) +// Copyright (C) 1999-2019 by Sonic Team Junior. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file r_fps.h +/// \brief Uncapped framerate stuff. + +#ifndef __R_FPS_H__ +#define __R_FPS_H__ + +#include "m_fixed.h" +#include "p_local.h" +#include "r_state.h" + +enum viewcontext_e +{ + VIEWCONTEXT_PLAYER1 = 0, + VIEWCONTEXT_PLAYER2, + VIEWCONTEXT_PLAYER3, + VIEWCONTEXT_PLAYER4, + VIEWCONTEXT_SKY1, + VIEWCONTEXT_SKY2, + VIEWCONTEXT_SKY3, + VIEWCONTEXT_SKY4 +}; + +typedef struct { + fixed_t x; + fixed_t y; + fixed_t z; + boolean sky; + sector_t *sector; + player_t *player; + + angle_t angle; + angle_t aim; + angle_t roll; + fixed_t cos; + fixed_t sin; + mobj_t *mobj; +} viewvars_t; + +extern viewvars_t *newview; + +// Interpolates the current view variables (r_state.h) against the selected view context in R_SetViewContext +void R_InterpolateView(fixed_t frac); +// Buffer the current new views into the old views. Call once after each real tic. +void R_UpdateViewInterpolation(void); +// Set the current view context (the viewvars pointed to by newview) +void R_SetViewContext(enum viewcontext_e _viewcontext); + +#endif diff --git a/src/r_main.c b/src/r_main.c index dfc11ab4a..c3e044ef2 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -36,6 +36,7 @@ #include "r_main.h" #include "i_system.h" // I_GetPreciseTime #include "doomstat.h" // MAXSPLITSCREENPLAYERS +#include "r_fps.h" // Frame interpolation/uncapped #ifdef HWRENDER #include "hardware/hw_main.h" @@ -70,7 +71,7 @@ size_t framecount; size_t loopcount; fixed_t viewx, viewy, viewz; -angle_t viewangle, aimingangle; +angle_t viewangle, aimingangle, viewroll; UINT8 viewssnum; fixed_t viewcos, viewsin; sector_t *viewsector; @@ -79,6 +80,9 @@ mobj_t *r_viewmobj; int r_splitscreen; +fixed_t rendertimefrac; +fixed_t renderdeltatics; + // // precalculated math tables // @@ -100,6 +104,9 @@ lighttable_t *scalelight[LIGHTLEVELS][MAXLIGHTSCALE]; lighttable_t *scalelightfixed[MAXLIGHTSCALE]; lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ]; +// Frame interpolation/uncapped +tic_t prev_tics; + // Hack to support extra boom colormaps. extracolormap_t *extra_colormaps = NULL; @@ -142,10 +149,6 @@ static void ChaseCam_OnChange(void); static void ChaseCam2_OnChange(void); static void ChaseCam3_OnChange(void); static void ChaseCam4_OnChange(void); -void SendWeaponPref(void); -void SendWeaponPref2(void); -void SendWeaponPref3(void); -void SendWeaponPref4(void); consvar_t cv_tailspickup = CVAR_INIT ("tailspickup", "On", CV_NETVAR|CV_NOSHOWHELP, CV_OnOff, NULL); consvar_t cv_chasecam[MAXSPLITSCREENPLAYERS] = { @@ -172,6 +175,9 @@ consvar_t cv_fov[MAXSPLITSCREENPLAYERS] = { CVAR_INIT ("fov4", "90", CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange) }; +// Frame interpolation/uncapped +consvar_t cv_frameinterpolation = CVAR_INIT ("frameinterpolation", "On", CV_SAVE, CV_OnOff, NULL); + // Okay, whoever said homremoval causes a performance hit should be shot. consvar_t cv_homremoval = CVAR_INIT ("homremoval", "Yes", CV_SAVE, homremoval_cons_t, NULL); @@ -646,7 +652,7 @@ void R_CheckViewMorph(int s) float fisheyemap[MAXVIDWIDTH/2 + 1]; #endif - angle_t rollangle = R_ViewRollAngle(&players[displayplayers[s]]); + angle_t rollangle = viewroll; #ifdef WOUGHMP_WOUGHMP fixed_t fisheye = cv_cam2_turnmultiplier.value; // temporary test value #endif @@ -1131,7 +1137,7 @@ void R_Init(void) R_InitLightTables(); //I_OutputMsg("\nR_InitTranslucencyTables\n"); - R_InitTranslucencyTables(); + //R_InitTranslucencyTables(); R_InitDrawNodes(); @@ -1193,45 +1199,11 @@ subsector_t *R_PointInSubsectorOrNull(fixed_t x, fixed_t y) // R_SetupFrame // -// recalc necessary stuff for mouseaiming -// 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) -static void R_SetupFreelook(player_t *player, boolean skybox) -{ -#ifndef HWRENDER - (void)player; - (void)skybox; -#endif - - // clip it in the case we are looking a hardware 90 degrees full aiming - // (lmps, network and use F12...) - if (rendermode == render_soft -#ifdef HWRENDER - || (rendermode == render_opengl - && (cv_glshearing.value == 1 - || (cv_glshearing.value == 2 && R_IsViewpointThirdPerson(player, skybox)))) -#endif - ) - { - G_SoftwareClipAimingPitch((INT32 *)&aimingangle); - } - - centeryfrac = (viewheight/2)< r_splitscreen) - return; // shouldn't be possible, but just in case + { + i = 0; // Shouldn't be possible, but just in case. + thiscam = &camera[0]; + chasecam = (cv_chasecam[0].value != 0); + R_SetViewContext(VIEWCONTEXT_PLAYER1); + } if (player->spectator) // no spectator chasecam chasecam = false; // force chasecam off - if (chasecam && !thiscam->chase) + if (chasecam && (thiscam && !thiscam->chase)) { P_ResetCamera(player, thiscam); thiscam->chase = true; @@ -1257,73 +1235,76 @@ void R_SetupFrame(player_t *player) else if (!chasecam) thiscam->chase = false; + newview->sky = false; + if (player->awayviewtics) { // cut-away view stuff r_viewmobj = player->awayviewmobj; // should be a MT_ALTVIEWMAN I_Assert(r_viewmobj != NULL); - viewz = r_viewmobj->z + 20*FRACUNIT; - aimingangle = player->awayviewaiming; - viewangle = r_viewmobj->angle; + newview->z = r_viewmobj->z + 20*FRACUNIT; + newview->aim = player->awayviewaiming; + newview->angle = r_viewmobj->angle; } else if (!player->spectator && chasecam) // use outside cam view { r_viewmobj = NULL; - viewz = thiscam->z + (thiscam->height>>1); - aimingangle = thiscam->aiming; - viewangle = thiscam->angle; + newview->z = thiscam->z + (thiscam->height>>1); + newview->aim = thiscam->aiming; + newview->angle = thiscam->angle; } else // use the player's eyes view { - viewz = player->viewz; + newview->z = player->viewz; r_viewmobj = player->mo; I_Assert(r_viewmobj != NULL); - aimingangle = player->aiming; - viewangle = r_viewmobj->angle; + newview->aim = player->aiming; + newview->angle = r_viewmobj->angle; if (!demo.playback && player->playerstate != PST_DEAD) { - viewangle = localangle[i]; // WARNING: camera uses this - aimingangle = localaiming[i]; + newview->angle = localangle[i]; // WARNING: camera uses this + newview->aim = localaiming[i]; } } - viewz += quake.z; + newview->roll = R_ViewRollAngle(player); + newview->z += quake.z; - viewplayer = player; + newview->player = player; if (chasecam && !player->awayviewtics && !player->spectator) { - viewx = thiscam->x; - viewy = thiscam->y; - viewx += quake.x; - viewy += quake.y; + newview->x = thiscam->x; + newview->y = thiscam->y; + newview->x += quake.x; + newview->y += quake.y; if (thiscam->subsector) - viewsector = thiscam->subsector->sector; + newview->sector = thiscam->subsector->sector; else - viewsector = R_PointInSubsector(viewx, viewy)->sector; + newview->sector = R_PointInSubsector(newview->x, newview->y)->sector; } else { - viewx = r_viewmobj->x; - viewy = r_viewmobj->y; - viewx += quake.x; - viewy += quake.y; + newview->x = r_viewmobj->x; + newview->y = r_viewmobj->y; + newview->x += quake.x; + newview->y += quake.y; if (r_viewmobj->subsector) - viewsector = r_viewmobj->subsector->sector; + newview->sector = r_viewmobj->subsector->sector; else - viewsector = R_PointInSubsector(viewx, viewy)->sector; + newview->sector = R_PointInSubsector(newview->x, newview->y)->sector; } - viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); - viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); + // newview->sin = FINESINE(viewangle>>ANGLETOFINESHIFT); + // newview->cos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); - R_SetupFreelook(player, false); + R_InterpolateView(rendertimefrac); } void R_SkyboxFrame(player_t *player) @@ -1331,24 +1312,25 @@ void R_SkyboxFrame(player_t *player) camera_t *thiscam = &camera[0]; UINT8 i = 0; - if (r_splitscreen) + for (i = 0; i <= r_splitscreen; i++) { - for (i = 1; i <= r_splitscreen; i++) + if (player == &players[displayplayers[i]]) { - if (player == &players[displayplayers[i]]) - { - thiscam = &camera[i]; - break; - } - } - - if (i > r_splitscreen) - { - i = 0; + thiscam = &camera[i]; + R_SetViewContext(VIEWCONTEXT_SKY1 + i); + break; } } + if (i > r_splitscreen) + { + i = 0; // Shouldn't be possible, but just in case. + thiscam = &camera[0]; + R_SetViewContext(VIEWCONTEXT_SKY1); + } + // cut-away view stuff + newview->sky = true; r_viewmobj = skyboxmo[0]; #ifdef PARANOIA if (!r_viewmobj) @@ -1359,31 +1341,32 @@ void R_SkyboxFrame(player_t *player) #endif if (player->awayviewtics) { - aimingangle = player->awayviewaiming; - viewangle = player->awayviewmobj->angle; + newview->aim = player->awayviewaiming; + newview->angle = player->awayviewmobj->angle; } - else if (thiscam->chase) + else if (thiscam && thiscam->chase) { - aimingangle = thiscam->aiming; - viewangle = thiscam->angle; + newview->aim = thiscam->aiming; + newview->angle = thiscam->angle; } else { - aimingangle = player->aiming; - viewangle = player->mo->angle; + newview->aim = player->aiming; + newview->angle = player->mo->angle; if (/*!demo.playback && */player->playerstate != PST_DEAD) { - viewangle = localangle[i]; - aimingangle = localaiming[i]; + newview->angle = localangle[i]; + newview->aim = localaiming[i]; } } - viewangle += r_viewmobj->angle; + newview->angle += r_viewmobj->angle; + newview->roll = R_ViewRollAngle(player); - viewplayer = player; + newview->player = player; - viewx = r_viewmobj->x; - viewy = r_viewmobj->y; - viewz = r_viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle! + newview->x = r_viewmobj->x; + newview->y = r_viewmobj->y; + newview->z = r_viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle! if (mapheaderinfo[gamemap-1]) { @@ -1425,46 +1408,46 @@ void R_SkyboxFrame(player_t *player) if (r_viewmobj->angle == 0) { - viewx += x; - viewy += y; + newview->x += x; + newview->y += y; } else if (r_viewmobj->angle == ANGLE_90) { - viewx -= y; - viewy += x; + newview->x -= y; + newview->y += x; } else if (r_viewmobj->angle == ANGLE_180) { - viewx -= x; - viewy -= y; + newview->x -= x; + newview->y -= y; } else if (r_viewmobj->angle == ANGLE_270) { - viewx += y; - viewy -= x; + newview->x += y; + newview->y -= x; } else { angle_t ang = r_viewmobj->angle>>ANGLETOFINESHIFT; - viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang)); - viewy += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang)); + newview->x += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang)); + newview->y += FixedMul(x, FINESINE(ang)) + FixedMul(y,FINECOSINE(ang)); } } if (mh->skybox_scalez > 0) - viewz += campos.z / mh->skybox_scalez; + newview->z += campos.z / mh->skybox_scalez; else if (mh->skybox_scalez < 0) - viewz += campos.z * -mh->skybox_scalez; + newview->z += campos.z * -mh->skybox_scalez; } if (r_viewmobj->subsector) - viewsector = r_viewmobj->subsector->sector; + newview->sector = r_viewmobj->subsector->sector; else - viewsector = R_PointInSubsector(viewx, viewy)->sector; + newview->sector = R_PointInSubsector(newview->x, newview->y)->sector; - viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); - viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); + // newview->sin = FINESINE(viewangle>>ANGLETOFINESHIFT); + // newview->cos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); - R_SetupFreelook(player, true); + R_InterpolateView(rendertimefrac); } boolean R_ViewpointHasChasecam(player_t *player) @@ -1737,4 +1720,7 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_maxportals); CV_RegisterVar(&cv_movebob); + + // Frame interpolation/uncapped + CV_RegisterVar(&cv_frameinterpolation); } diff --git a/src/r_main.h b/src/r_main.h index 5208b52a3..a2acf60d9 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -33,6 +33,11 @@ extern fixed_t fovtan[MAXSPLITSCREENPLAYERS]; extern size_t validcount, linecount, loopcount, framecount; +// The fraction of a tic being drawn (for interpolation between two tics) +extern fixed_t rendertimefrac; +// Evaluated delta tics for this frame (how many tics since the last frame) +extern fixed_t renderdeltatics;; + // // Lighting LUT. // Used for z-depth cuing per column/row, @@ -111,6 +116,10 @@ extern consvar_t cv_fov[MAXSPLITSCREENPLAYERS]; extern consvar_t cv_skybox; extern consvar_t cv_tailspickup; +// Frame interpolation (uncapped framerate) +extern tic_t prev_tics; +extern consvar_t cv_frameinterpolation; + // Called by startup code. void R_Init(void); diff --git a/src/r_patch.h b/src/r_patch.h index 601144a1d..b86908281 100644 --- a/src/r_patch.h +++ b/src/r_patch.h @@ -42,6 +42,7 @@ patch_t *Patch_GetRotatedSprite( INT32 R_GetRollAngle(angle_t rollangle); angle_t R_GetPitchRollAngle(mobj_t *mobj, player_t *viewPlayer); +angle_t R_ModelRotationAngle(mobj_t *mobj, player_t *viewPlayer); angle_t R_SpriteRotationAngle(mobj_t *mobj, player_t *viewPlayer); #endif diff --git a/src/r_patchrotation.c b/src/r_patchrotation.c index 3744dfce2..74afeb396 100644 --- a/src/r_patchrotation.c +++ b/src/r_patchrotation.c @@ -42,7 +42,11 @@ static angle_t R_PlayerSpriteRotation(player_t *player, player_t *viewPlayer) angle_t rollAngle = 0; - if (sliptideLift) + if (player->mo->eflags & MFE_UNDERWATER) + { + rollAngle -= player->underwatertilt; + } + else if (sliptideLift) { /* (from side) tilt downward if turning toward camera, upward if away. */ @@ -60,10 +64,9 @@ static angle_t R_PlayerSpriteRotation(player_t *player, player_t *viewPlayer) return rollAngle; } -angle_t R_SpriteRotationAngle(mobj_t *mobj, player_t *viewPlayer) +angle_t R_ModelRotationAngle(mobj_t *mobj, player_t *viewPlayer) { - angle_t rollOrPitch = R_GetPitchRollAngle(mobj, viewPlayer); - angle_t rollAngle = (rollOrPitch + mobj->rollangle); + angle_t rollAngle = mobj->rollangle; if (mobj->player) { @@ -73,6 +76,12 @@ angle_t R_SpriteRotationAngle(mobj_t *mobj, player_t *viewPlayer) return rollAngle; } +angle_t R_SpriteRotationAngle(mobj_t *mobj, player_t *viewPlayer) +{ + angle_t rollOrPitch = R_GetPitchRollAngle(mobj, viewPlayer); + return (rollOrPitch + R_ModelRotationAngle(mobj, viewPlayer)); +} + INT32 R_GetRollAngle(angle_t rollangle) { INT32 ra = AngleFixed(rollangle)>>FRACBITS; diff --git a/src/r_picformats.h b/src/r_picformats.h index 8d3999013..0a822cc48 100644 --- a/src/r_picformats.h +++ b/src/r_picformats.h @@ -105,6 +105,7 @@ typedef struct } spriteinfo_t; // Portable Network Graphics +#define PNG_HEADER_SIZE (8) boolean Picture_IsLumpPNG(const UINT8 *d, size_t s); #define Picture_ThrowPNGError(lumpname, wadfilename) I_Error("W_Wad: Lump \"%s\" in file \"%s\" is a .png - please convert to either Doom or Flat (raw) image format.", lumpname, wadfilename); // Fears Of LJ Sonic diff --git a/src/r_plane.c b/src/r_plane.c index 648a9ee01..d2f294cdc 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -235,7 +235,9 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2) } if (currentplane->slope) + { ds_colormap = colormaps; + } else { pindex = distance >> LIGHTZSHIFT; @@ -244,8 +246,13 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2) ds_colormap = planezlight[pindex]; } + ds_fullbright = colormaps; + if (encoremap && !currentplane->noencore) + { ds_colormap += COLORMAP_REMAPOFFSET; + ds_fullbright += COLORMAP_REMAPOFFSET; + } if (currentplane->extra_colormap) ds_colormap = currentplane->extra_colormap->colormap + (ds_colormap - colormaps); @@ -641,7 +648,7 @@ static void R_DrawSkyPlane(visplane_t *pl) // Reset column drawer function (note: couldn't we just call walldrawerfunc directly?) // (that is, unless we'll need to switch drawers in future for some reason) - colfunc = colfuncs[BASEDRAWFUNC]; + R_SetColumnFunc(BASEDRAWFUNC, false); // use correct aspect ratio scale dc_iscale = skyscale[viewssnum]; @@ -651,8 +658,12 @@ static void R_DrawSkyPlane(visplane_t *pl) // Because of this hack, sky is not affected // by sector colormaps (INVUL inverse mapping is not implemented in SRB2 so is irrelevant). dc_colormap = colormaps; + dc_fullbright = colormaps; if (encoremap) + { dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } dc_texturemid = skytexturemid; dc_texheight = textureheight[skytexture] >>FRACBITS; @@ -669,6 +680,7 @@ static void R_DrawSkyPlane(visplane_t *pl) dc_source = R_GetColumn(texturetranslation[skytexture], -angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18 + dc_brightmap = NULL; colfunc(); } } @@ -808,7 +820,8 @@ void R_DrawSinglePlane(visplane_t *pl) } planeripple.active = false; - spanfunc = spanfuncs[BASEDRAWFUNC]; + ds_brightmap = NULL; + R_SetSpanFunc(BASEDRAWFUNC, false, false); if (pl->polyobj) { @@ -883,12 +896,12 @@ void R_DrawSinglePlane(visplane_t *pl) { INT32 top, bottom; + planeripple.active = true; if (spanfunctype == SPANDRAWFUNC_TRANS) { UINT8 i; spanfunctype = SPANDRAWFUNC_WATER; - planeripple.active = true; // Copy the current scene, ugh top = pl->high-8; @@ -965,6 +978,17 @@ void R_DrawSinglePlane(visplane_t *pl) R_CheckFlatLength(ds_flatwidth * ds_flatheight); } + if (type == LEVELFLAT_TEXTURE) + { + // Get the span's brightmap. + // FLATS not supported, SORRY!! + INT32 bmNum = R_GetTextureBrightmap(levelflat->u.texture.num); + if (bmNum != 0) + { + ds_brightmap = (UINT8 *)R_GenerateTextureAsFlat(bmNum); + } + } + if (!pl->slope // Don't mess with angle on slopes! We'll handle this ourselves later && viewangle != pl->viewangle+pl->plangle) { @@ -1080,15 +1104,7 @@ void R_DrawSinglePlane(visplane_t *pl) planezlight = zlight[light]; // Use the correct span drawer depending on the powers-of-twoness - if (!ds_powersoftwo) - { - if (spanfuncs_npo2[spanfunctype]) - spanfunc = spanfuncs_npo2[spanfunctype]; - else - spanfunc = spanfuncs[spanfunctype]; - } - else - spanfunc = spanfuncs[spanfunctype]; + R_SetSpanFunc(spanfunctype, !ds_powersoftwo, ds_brightmap != NULL); // set the maximum value for unsigned pl->top[pl->maxx+1] = 0xffff; diff --git a/src/r_segs.c b/src/r_segs.c index 8d056a295..5a8172615 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -36,6 +36,7 @@ static boolean markceiling; static boolean maskedtexture; static INT32 toptexture, bottomtexture, midtexture; +static INT32 topbrightmap, bottombrightmap, midbrightmap; static INT32 numthicksides, numbackffloors; angle_t rw_normalangle; @@ -83,7 +84,7 @@ static fixed_t *maskedtextureheight = NULL; // multi-patch textures. They are not normally needed as multi-patch // textures don't have holes in it. At least not for now. -static void R_Render2sidedMultiPatchColumn(column_t *column) +static void R_Render2sidedMultiPatchColumn(column_t *column, column_t *brightmap) { INT32 topscreen, bottomscreen; @@ -93,6 +94,8 @@ static void R_Render2sidedMultiPatchColumn(column_t *column) dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS; dc_yh = (bottomscreen-1)>>FRACBITS; + dc_brightmap = NULL; + if (windowtop != INT32_MAX && windowbottom != INT32_MAX) { dc_yl = ((windowtop + FRACUNIT)>>FRACBITS); @@ -110,10 +113,14 @@ static void R_Render2sidedMultiPatchColumn(column_t *column) if (dc_yl <= dc_yh && dc_yh < vid.height && dc_yh > 0) { dc_source = (UINT8 *)column + 3; + if (brightmap != NULL) + { + dc_brightmap = (UINT8 *)brightmap + 3; + } - if (colfunc == colfuncs[BASEDRAWFUNC]) + if (R_CheckColumnFunc(BASEDRAWFUNC) == true) (colfuncs[COLDRAWFUNC_TWOSMULTIPATCH])(); - else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) + else if (R_CheckColumnFunc(COLDRAWFUNC_FUZZY) == true) (colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS])(); else colfunc(); @@ -132,12 +139,12 @@ transnum_t R_GetLinedefTransTable(line_t *ldef) void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) { size_t pindex; - column_t *col; - INT32 lightnum, texnum, i; + column_t *col, *bmCol = NULL; + INT32 lightnum, texnum, bmnum, i; fixed_t height, realbot; lightlist_t *light; r_lightlist_t *rlight; - void (*colfunc_2s)(column_t *); + void (*colfunc_2s)(column_t *, column_t *); line_t *ldef; sector_t *front, *back; INT32 times, repeats; @@ -155,6 +162,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) frontsector = curline->frontsector; backsector = curline->backsector; texnum = R_GetTextureNum(curline->sidedef->midtexture); + bmnum = R_GetTextureBrightmap(texnum); windowbottom = windowtop = sprbotscreen = INT32_MAX; ldef = curline->linedef; @@ -162,7 +170,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) return; transtable = R_GetLinedefTransTable(ldef); - if (ldef->special == 910) + if (ldef->special == 910 || P_IsLineTripWire(ldef)) { if (transtable == NUMTRANSMAPS) transtable = 0; @@ -188,16 +196,18 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) if (transtable != NUMTRANSMAPS && (blendmode || transtable)) { dc_transmap = R_GetBlendTable(blendmode, transtable); - colfunc = colfuncs[COLDRAWFUNC_FUZZY]; + R_SetColumnFunc(COLDRAWFUNC_FUZZY, bmnum != 0); } else if (ldef->special == 909) { - colfunc = colfuncs[COLDRAWFUNC_FOG]; + R_SetColumnFunc(COLDRAWFUNC_FOG, bmnum != 0); windowtop = frontsector->ceilingheight; windowbottom = frontsector->floorheight; } else - colfunc = colfuncs[BASEDRAWFUNC]; + { + R_SetColumnFunc(BASEDRAWFUNC, bmnum != 0); + } if (curline->polyseg && curline->polyseg->translucency > 0) { @@ -205,7 +215,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) return; dc_transmap = R_GetTranslucencyTable(curline->polyseg->translucency); - colfunc = colfuncs[COLDRAWFUNC_FUZZY]; + R_SetColumnFunc(COLDRAWFUNC_FUZZY, bmnum != 0); } range = max(ds->x2-ds->x1, 1); @@ -215,6 +225,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) // Texture must be cached before setting colfunc_2s, // otherwise texture[texnum]->holes may be false when it shouldn't be R_CheckTextureCache(texnum); + if (bmnum) { R_CheckTextureCache(bmnum); } + // handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures // are not stored per-column with post info in SRB2 if (textures[texnum]->holes) @@ -265,7 +277,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) rlight->extra_colormap = *light->extra_colormap; rlight->flags = light->flags; - if ((colfunc != colfuncs[COLDRAWFUNC_FUZZY]) + if ((R_CheckColumnFunc(COLDRAWFUNC_FUZZY) == false) || (rlight->flags & FF_FOG) || (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG))) lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); @@ -282,13 +294,13 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) } else { - if ((colfunc != colfuncs[COLDRAWFUNC_FUZZY]) + if ((R_CheckColumnFunc(COLDRAWFUNC_FUZZY) == false) || (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG))) lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); else lightnum = LIGHTLEVELS - 1; - if (colfunc == colfuncs[COLDRAWFUNC_FOG] + if ((R_CheckColumnFunc(COLDRAWFUNC_FOG) == true) || (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG))) ; else @@ -400,6 +412,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) // draw the texture col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); + if (bmnum) { bmCol = (column_t *)((UINT8 *)R_GetColumn(bmnum, maskedtexturecol[dc_x]) - 3); } for (i = 0; i < dc_numlights; i++) { @@ -431,8 +444,12 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) if (height <= windowtop) { dc_colormap = rlight->rcolormap; + dc_fullbright = colormaps; if (encoremap && !(ldef->flags & ML_TFERLINE)) + { dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } continue; } @@ -440,7 +457,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) if (windowbottom >= realbot) { windowbottom = realbot; - colfunc_2s(col); + colfunc_2s(col, bmCol); for (i++; i < dc_numlights; i++) { rlight = &dc_lightlist[i]; @@ -449,15 +466,19 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) continue; } - colfunc_2s(col); + colfunc_2s(col, bmCol); windowtop = windowbottom + 1; dc_colormap = rlight->rcolormap; + dc_fullbright = colormaps; if (encoremap && !(ldef->flags & ML_TFERLINE)) + { dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } } windowbottom = realbot; if (windowtop < windowbottom) - colfunc_2s(col); + colfunc_2s(col, bmCol); spryscale += rw_scalestep; continue; @@ -470,8 +491,12 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) pindex = MAXLIGHTSCALE - 1; dc_colormap = walllights[pindex]; + dc_fullbright = colormaps; if (encoremap && !(ldef->flags & ML_TFERLINE)) + { dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } if (frontsector->extra_colormap) dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); @@ -481,6 +506,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) // draw the texture col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); + if (bmnum) { bmCol = (column_t *)((UINT8 *)R_GetColumn(bmnum, maskedtexturecol[dc_x]) - 3); } #if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES)) @@ -535,19 +561,20 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) } else #endif - colfunc_2s(col); + colfunc_2s(col, bmCol); } spryscale += rw_scalestep; } } - colfunc = colfuncs[BASEDRAWFUNC]; + + R_SetColumnFunc(BASEDRAWFUNC, false); } // Loop through R_DrawMaskedColumn calls -static void R_DrawRepeatMaskedColumn(column_t *col) +static void R_DrawRepeatMaskedColumn(column_t *col, column_t *bm) { while (sprtopscreen < sprbotscreen) { - R_DrawMaskedColumn(col); + R_DrawMaskedColumn(col, bm); if ((INT64)sprtopscreen + dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow sprtopscreen = INT32_MAX; else @@ -555,10 +582,10 @@ static void R_DrawRepeatMaskedColumn(column_t *col) } } -static void R_DrawRepeatFlippedMaskedColumn(column_t *col) +static void R_DrawRepeatFlippedMaskedColumn(column_t *col, column_t *bm) { do { - R_DrawFlippedMaskedColumn(col); + R_DrawFlippedMaskedColumn(col, bm); sprtopscreen += dc_texheight*spryscale; } while (sprtopscreen < sprbotscreen); } @@ -582,9 +609,9 @@ static boolean R_IsFFloorTranslucent(visffloor_t *pfloor) void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { size_t pindex; - column_t * col; + column_t * col, *bmCol = NULL; INT32 lightnum; - INT32 texnum; + INT32 texnum, bmnum; sector_t tempsec; INT32 templight; INT32 i, p; @@ -605,7 +632,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) fixed_t left_top, left_bottom; // needed here for slope skewing pslope_t *skewslope = NULL; - void (*colfunc_2s) (column_t *); + void (*colfunc_2s) (column_t *, column_t *); // Calculate light table. // Use different light tables @@ -616,14 +643,16 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) backsector = pfloor->target; frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector; texnum = R_GetTextureNum(sides[pfloor->master->sidenum[0]].midtexture); + bmnum = R_GetTextureBrightmap(texnum); - colfunc = colfuncs[BASEDRAWFUNC]; + R_SetColumnFunc(BASEDRAWFUNC, bmnum != 0); if (pfloor->master->flags & ML_TFERLINE) { size_t linenum = curline->linedef-backsector->lines[0]; newline = pfloor->master->frontsector->lines[0] + linenum; texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); + bmnum = R_GetTextureBrightmap(texnum); } if (pfloor->flags & FF_TRANSLUCENT) @@ -641,10 +670,14 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) } if (fuzzy) - colfunc = colfuncs[COLDRAWFUNC_FUZZY]; + { + R_SetColumnFunc(COLDRAWFUNC_FUZZY, bmnum != 0); + } } else if (pfloor->flags & FF_FOG) - colfunc = colfuncs[COLDRAWFUNC_FOG]; + { + R_SetColumnFunc(COLDRAWFUNC_FOG, bmnum != 0); + } range = max(ds->x2-ds->x1, 1); //SoM: Moved these up here so they are available for my lightlist calculations @@ -752,7 +785,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); else if (pfloor->flags & FF_FOG) lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT); - else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) + else if (R_CheckColumnFunc(COLDRAWFUNC_FUZZY) == true) lightnum = LIGHTLEVELS-1; else lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false) @@ -833,6 +866,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) // Texture must be cached before setting colfunc_2s, // otherwise texture[texnum]->holes may be false when it shouldn't be R_CheckTextureCache(texnum); + if (bmnum) { R_CheckTextureCache(bmnum); } + //faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures // are not stored per-column with post info anymore in Doom Legacy if (textures[texnum]->holes) @@ -916,6 +951,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) // Get data for the column col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3); + if (bmnum) { bmCol = (column_t *)((UINT8 *)R_GetColumn(bmnum, maskedtexturecol[dc_x]) - 3); } // SoM: New code does not rely on R_DrawColumnShadowed_8 which // will (hopefully) put less strain on the stack. @@ -998,8 +1034,12 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (lighteffect) { dc_colormap = rlight->rcolormap; + dc_fullbright = colormaps; if (encoremap && !(curline->linedef->flags & ML_TFERLINE)) + { dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } } if (solid && windowtop < bheight) windowtop = bheight; @@ -1011,7 +1051,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { windowbottom = sprbotscreen; // draw the texture - colfunc_2s (col); + colfunc_2s (col, bmCol); for (i++; i < dc_numlights; i++) { rlight = &dc_lightlist[i]; @@ -1022,7 +1062,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) continue; } // draw the texture - colfunc_2s (col); + colfunc_2s (col, bmCol); if (solid) windowtop = bheight; else @@ -1030,14 +1070,18 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (lighteffect) { dc_colormap = rlight->rcolormap; + dc_fullbright = colormaps; if (encoremap && !(curline->linedef->flags & ML_TFERLINE)) + { dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } } } windowbottom = sprbotscreen; // draw the texture, if there is any space left if (windowtop < windowbottom) - colfunc_2s (col); + colfunc_2s (col, bmCol); spryscale += rw_scalestep; continue; @@ -1050,9 +1094,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) pindex = MAXLIGHTSCALE - 1; dc_colormap = walllights[pindex]; + dc_fullbright = colormaps; if (encoremap && !(curline->linedef->flags & ML_TFERLINE)) + { dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap) dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); @@ -1060,11 +1108,12 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); // draw the texture - colfunc_2s (col); + colfunc_2s (col, bmCol); spryscale += rw_scalestep; } } - colfunc = colfuncs[BASEDRAWFUNC]; + + R_SetColumnFunc(BASEDRAWFUNC, false); #undef CLAMPMAX #undef CLAMPMIN @@ -1311,8 +1360,12 @@ static void R_RenderSegLoop (void) pindex = MAXLIGHTSCALE-1; dc_colormap = walllights[pindex]; + dc_fullbright = colormaps; if (encoremap && !(curline->linedef->flags & ML_TFERLINE)) + { dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } dc_x = rw_x; dc_iscale = 0xffffffffu / (unsigned)rw_scale; @@ -1350,7 +1403,7 @@ static void R_RenderSegLoop (void) else dc_lightlist[i].rcolormap = xwalllights[pindex]; - colfunc = colfuncs[COLDRAWFUNC_SHADOWED]; + R_SetColumnFunc(COLDRAWFUNC_SHADOWED, false); } } @@ -1366,8 +1419,11 @@ static void R_RenderSegLoop (void) dc_yh = yh; dc_texturemid = rw_midtexturemid; dc_source = R_GetColumn(midtexture,texturecolumn); + dc_brightmap = (midbrightmap ? R_GetColumn(midbrightmap, texturecolumn) : NULL); dc_texheight = textureheight[midtexture]>>FRACBITS; + R_SetColumnFunc(colfunctype, dc_brightmap != NULL); + //profile stuff --------------------------------------------------------- #ifdef TIMING ProfZeroTimer(); @@ -1427,7 +1483,9 @@ static void R_RenderSegLoop (void) dc_yh = mid; dc_texturemid = rw_toptexturemid; dc_source = R_GetColumn(toptexture,texturecolumn); + dc_brightmap = (topbrightmap ? R_GetColumn(topbrightmap, texturecolumn) : NULL); dc_texheight = textureheight[toptexture]>>FRACBITS; + R_SetColumnFunc(colfunctype, dc_brightmap != NULL); colfunc(); ceilingclip[rw_x] = (INT16)mid; } @@ -1462,9 +1520,10 @@ static void R_RenderSegLoop (void) dc_yl = mid; dc_yh = yh; dc_texturemid = rw_bottomtexturemid; - dc_source = R_GetColumn(bottomtexture, - texturecolumn); + dc_source = R_GetColumn(bottomtexture,texturecolumn); + dc_brightmap = (bottombrightmap ? R_GetColumn(bottombrightmap, texturecolumn) : NULL); dc_texheight = textureheight[bottomtexture]>>FRACBITS; + R_SetColumnFunc(colfunctype, dc_brightmap != NULL); colfunc(); floorclip[rw_x] = (INT16)mid; } @@ -1558,7 +1617,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) memset(&segleft, 0x00, sizeof(segleft)); memset(&segright, 0x00, sizeof(segright)); - colfunc = colfuncs[BASEDRAWFUNC]; + R_SetColumnFunc(BASEDRAWFUNC, false); if (ds_p == drawsegs+maxdrawsegs) { @@ -1738,6 +1797,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) worldbottomslope -= viewz; midtexture = toptexture = bottomtexture = maskedtexture = 0; + midbrightmap = topbrightmap = bottombrightmap = 0; ds_p->maskedtexturecol = NULL; ds_p->numthicksides = numthicksides = 0; ds_p->thicksidecol = NULL; @@ -1785,6 +1845,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) fixed_t texheight; // single sided line midtexture = R_GetTextureNum(sidedef->midtexture); + midbrightmap = R_GetTextureBrightmap(midtexture); texheight = textureheight[midtexture]; // a single sided line is terminal, so it must mark ends markfloor = markceiling = true; @@ -2021,11 +2082,14 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (!toptexture) //Second side has no texture, use the first side's instead. toptexture = R_GetTextureNum(sidedef->toptexture); + + topbrightmap = R_GetTextureBrightmap(toptexture); texheight = textureheight[toptexture]; } else { toptexture = R_GetTextureNum(sidedef->toptexture); + topbrightmap = R_GetTextureBrightmap(toptexture); texheight = textureheight[toptexture]; } if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked @@ -2052,6 +2116,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) { // bottom texture bottomtexture = R_GetTextureNum(sidedef->bottomtexture); + bottombrightmap = R_GetTextureBrightmap(bottomtexture); if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked if (linedef->flags & ML_DONTPEGBOTTOM) @@ -2772,7 +2837,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) rw_bsilheight = &(ds_p->bsilheight); R_RenderSegLoop(); - colfunc = colfuncs[BASEDRAWFUNC]; + R_SetColumnFunc(BASEDRAWFUNC, false); if (portalline) // if curline is a portal, set portalrender for drawseg ds_p->portalpass = portalrender+1; diff --git a/src/r_skins.c b/src/r_skins.c index 1e80e18ce..ba7ed0811 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -311,11 +311,6 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) } player->skincolor = newcolor = skin->prefcolor; - if (player->bot && botingame) - { - botskin = (UINT8)(skinnum + 1); - botcolor = skin->prefcolor; - } } #endif diff --git a/src/r_splats.c b/src/r_splats.c index 63052049e..28acd0ab0 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -444,6 +444,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr } ds_colormap = vis->colormap; + ds_fullbright = colormaps; ds_translation = R_GetSpriteTranslation(vis); if (ds_translation == NULL) ds_translation = colormaps; @@ -468,10 +469,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr else ds_transmap = NULL; - if (ds_powersoftwo) - spanfunc = spanfuncs[spanfunctype]; - else - spanfunc = spanfuncs_npo2[spanfunctype]; + R_SetSpanFunc(spanfunctype, !ds_powersoftwo, false); if (maxy >= vid.height) maxy = vid.height-1; diff --git a/src/r_state.h b/src/r_state.h index cb55e2c2b..dc577448e 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -54,6 +54,9 @@ extern extracolormap_t *extra_colormaps; // for global animation extern INT32 *texturetranslation; +// for brightmaps +extern INT32 *texturebrightmaps; + // Sprites extern size_t numspritelumps, max_spritelumps; @@ -93,7 +96,7 @@ extern side_t *spawnsides; // POV data. // extern fixed_t viewx, viewy, viewz; -extern angle_t viewangle, aimingangle; +extern angle_t viewangle, aimingangle, viewroll; extern UINT8 viewssnum; // splitscreen view number extern boolean viewsky, skyVisible; extern boolean skyVisiblePerPlayer[MAXSPLITSCREENPLAYERS]; // saved values of skyVisible of each splitscreen player diff --git a/src/r_textures.c b/src/r_textures.c index 9716724b5..9254cb91b 100644 --- a/src/r_textures.c +++ b/src/r_textures.c @@ -55,6 +55,7 @@ INT32 *texturewidth; fixed_t *textureheight; // needed for texture pegging INT32 *texturetranslation; +INT32 *texturebrightmaps; // Painfully simple texture id cacheing to make maps load faster. :3 static struct { @@ -500,6 +501,20 @@ INT32 R_GetTextureNum(INT32 texnum) return texturetranslation[texnum]; } +// +// R_GetTextureBrightmap +// +// Returns the actual texture id that we should use. +// This can either be the texture's brightmap, +// or 0 if not valid. +// +INT32 R_GetTextureBrightmap(INT32 texnum) +{ + if (texnum < 0 || texnum >= numtextures) + return 0; + return texturebrightmaps[texnum]; +} + // // R_CheckTextureCache // @@ -725,6 +740,7 @@ Rloadflats (INT32 i, INT32 w) UINT16 texstart, texend; texture_t *texture; texpatch_t *patch; + UINT8 header[PNG_HEADER_SIZE]; // Yes if (wadfiles[w]->type == RET_PK3) @@ -743,7 +759,6 @@ Rloadflats (INT32 i, INT32 w) // Work through each lump between the markers in the WAD. for (j = 0; j < (texend - texstart); j++) { - UINT8 *flatlump; UINT16 wadnum = (UINT16)w; lumpnum_t lumpnum = texstart + j; size_t lumplength; @@ -755,7 +770,7 @@ Rloadflats (INT32 i, INT32 w) continue; // If it is then SKIP IT } - flatlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); + W_ReadLumpHeaderPwad(wadnum, lumpnum, header, sizeof header, 0); lumplength = W_LumpLengthPwad(wadnum, lumpnum); switch (lumplength) @@ -790,12 +805,14 @@ Rloadflats (INT32 i, INT32 w) M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name)); #ifndef NO_PNG_LUMPS - if (Picture_IsLumpPNG((UINT8 *)flatlump, lumplength)) + if (Picture_IsLumpPNG(header, lumplength)) { + UINT8 *flatlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); INT32 width, height; Picture_PNGDimensions((UINT8 *)flatlump, &width, &height, NULL, NULL, lumplength); texture->width = (INT16)width; texture->height = (INT16)height; + Z_Free(flatlump); } else #endif @@ -814,8 +831,6 @@ Rloadflats (INT32 i, INT32 w) patch->lump = texstart + j; patch->flip = 0; - Z_Unlock(flatlump); - texturewidth[i] = texture->width; textureheight[i] = texture->height << FRACBITS; i++; @@ -835,8 +850,8 @@ Rloadtextures (INT32 i, INT32 w) UINT16 j; UINT16 texstart, texend, texturesLumpPos; texture_t *texture; - softwarepatch_t *patchlump; texpatch_t *patch; + softwarepatch_t patchlump; // Get the lump numbers for the markers in the WAD, if they exist. if (wadfiles[w]->type == RET_PK3) @@ -876,7 +891,7 @@ Rloadtextures (INT32 i, INT32 w) continue; // If it is then SKIP IT } - patchlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); + W_ReadLumpHeaderPwad(wadnum, lumpnum, &patchlump, PNG_HEADER_SIZE, 0); #ifndef NO_PNG_LUMPS lumplength = W_LumpLengthPwad(wadnum, lumpnum); #endif @@ -888,18 +903,20 @@ Rloadtextures (INT32 i, INT32 w) M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name)); #ifndef NO_PNG_LUMPS - if (Picture_IsLumpPNG((UINT8 *)patchlump, lumplength)) + if (Picture_IsLumpPNG((UINT8 *)&patchlump, lumplength)) { + UINT8 *png = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); INT32 width, height; - Picture_PNGDimensions((UINT8 *)patchlump, &width, &height, NULL, NULL, lumplength); + Picture_PNGDimensions(png, &width, &height, NULL, NULL, lumplength); texture->width = (INT16)width; texture->height = (INT16)height; + Z_Free(png); } else #endif { - texture->width = SHORT(patchlump->width); - texture->height = SHORT(patchlump->height); + texture->width = SHORT(patchlump.width); + texture->height = SHORT(patchlump.height); } texture->type = TEXTURETYPE_SINGLEPATCH; @@ -915,8 +932,6 @@ Rloadtextures (INT32 i, INT32 w) patch->lump = texstart + j; patch->flip = 0; - Z_Unlock(patchlump); - texturewidth[i] = texture->width; textureheight[i] = texture->height << FRACBITS; i++; @@ -944,6 +959,7 @@ void R_LoadTextures(void) Z_Free(textures[i]); Z_Free(texturecache[i]); } + Z_Free(texturebrightmaps); Z_Free(texturetranslation); Z_Free(textures); } @@ -1044,9 +1060,14 @@ void R_LoadTextures(void) textureheight = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 4)); // Create translation table for global animation. texturetranslation = Z_Malloc((numtextures + 1) * sizeof(*texturetranslation), PU_STATIC, NULL); + // Create brightmap texture table. + texturebrightmaps = Z_Malloc((numtextures + 1) * sizeof(*texturebrightmaps), PU_STATIC, NULL); for (i = 0; i < numtextures; i++) + { texturetranslation[i] = i; + texturebrightmaps[i] = 0; + } for (i = 0, w = 0; w < numwadfiles; w++) { diff --git a/src/r_textures.h b/src/r_textures.h index 6e0cc168a..dada043a6 100644 --- a/src/r_textures.h +++ b/src/r_textures.h @@ -82,6 +82,7 @@ void R_FlushTextureCache(void); UINT8 *R_GenerateTexture(size_t texnum); UINT8 *R_GenerateTextureAsFlat(size_t texnum); INT32 R_GetTextureNum(INT32 texnum); +INT32 R_GetTextureBrightmap(INT32 texnum); void R_CheckTextureCache(INT32 tex); void R_ClearTextureNumCache(boolean btell); diff --git a/src/r_things.c b/src/r_things.c index 21e0228a3..bbfd15928 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -35,7 +35,6 @@ #include "p_slopes.h" #include "d_netfil.h" // blargh. for nameonly(). #include "m_cheat.h" // objectplace -#include "k_color.h" // SRB2kart #include "p_local.h" // stplyr #ifdef HWRENDER #include "hardware/hw_md2.h" @@ -44,6 +43,10 @@ #include "hardware/hw_drv.h" #endif +// SRB2kart +#include "k_color.h" +#include "k_kart.h" // HITLAGJITTERS + #define MINZ (FRACUNIT*4) #define BASEYCENTER (BASEVIDHEIGHT/2) @@ -283,16 +286,18 @@ boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, UINT16 #ifndef NO_PNG_LUMPS { - softwarepatch_t *png = W_CacheLumpNumPwad(wadnum, l, PU_STATIC); + UINT8 header[PNG_HEADER_SIZE]; size_t len = W_LumpLengthPwad(wadnum, l); - if (Picture_IsLumpPNG((UINT8 *)png, len)) + W_ReadLumpHeaderPwad(wadnum, l, header, sizeof header, 0); + + if (Picture_IsLumpPNG(header, len)) { + UINT8 *png = W_CacheLumpNumPwad(wadnum, l, PU_STATIC); Picture_PNGDimensions((UINT8 *)png, &width, &height, &topoffset, &leftoffset, len); isPNG = true; + Z_Free(png); } - - Z_Free(png); } if (!isPNG) @@ -599,7 +604,7 @@ INT16 *mceilingclip; fixed_t spryscale = 0, sprtopscreen = 0, sprbotscreen = 0; fixed_t windowtop = 0, windowbottom = 0; -void R_DrawMaskedColumn(column_t *column) +void R_DrawMaskedColumn(column_t *column, column_t *brightmap) { INT32 topscreen; INT32 bottomscreen; @@ -608,6 +613,9 @@ void R_DrawMaskedColumn(column_t *column) basetexturemid = dc_texturemid; + R_SetColumnFunc(colfunctype, brightmap != NULL); + dc_brightmap = NULL; + for (; column->topdelta != 0xff ;) { // calculate unclipped screen coordinates @@ -642,6 +650,11 @@ void R_DrawMaskedColumn(column_t *column) if (dc_yl <= dc_yh && dc_yh > 0) { dc_source = (UINT8 *)column + 3; + if (brightmap != NULL) + { + dc_brightmap = (UINT8 *)brightmap + 3; + } + dc_texturemid = basetexturemid - (topdelta<length + 4); + if (brightmap != NULL) + { + brightmap = (column_t *)((UINT8 *)brightmap + brightmap->length + 4); + } } dc_texturemid = basetexturemid; @@ -663,7 +680,7 @@ void R_DrawMaskedColumn(column_t *column) INT32 lengthcol; // column->length : for flipped column function pointers and multi-patch on 2sided wall = texture->height -void R_DrawFlippedMaskedColumn(column_t *column) +void R_DrawFlippedMaskedColumn(column_t *column, column_t *brightmap) { INT32 topscreen; INT32 bottomscreen; @@ -671,6 +688,9 @@ void R_DrawFlippedMaskedColumn(column_t *column) INT32 topdelta, prevdelta = -1; UINT8 *d,*s; + R_SetColumnFunc(colfunctype, brightmap != NULL); + dc_brightmap = NULL; + for (; column->topdelta != 0xff ;) { // calculate unclipped screen coordinates @@ -709,6 +729,14 @@ void R_DrawFlippedMaskedColumn(column_t *column) dc_source = ZZ_Alloc(column->length); for (s = (UINT8 *)column+2+column->length, d = dc_source; d < dc_source+column->length; --s) *d++ = *s; + + if (brightmap != NULL) + { + dc_brightmap = ZZ_Alloc(brightmap->length); + for (s = (UINT8 *)brightmap+2+brightmap->length, d = dc_brightmap; d < dc_brightmap+brightmap->length; --s) + *d++ = *s; + } + dc_texturemid = basetexturemid - (topdelta<length + 4); + if (brightmap != NULL) + { + brightmap = (column_t *)((UINT8 *)brightmap + brightmap->length + 4); + } } dc_texturemid = basetexturemid; @@ -737,7 +769,11 @@ boolean R_SpriteIsFlashing(vissprite_t *vis) UINT8 *R_GetSpriteTranslation(vissprite_t *vis) { - if (R_SpriteIsFlashing(vis)) // Bosses "flash" + if (vis->mobj->hitlag > 0 && (vis->mobj->eflags & MFE_DAMAGEHITLAG)) + { + return R_GetTranslationColormap(TC_HITLAG, 0, GTC_CACHE); + } + else if (R_SpriteIsFlashing(vis)) // Bosses "flash" { if (vis->mobj->type == MT_CYBRAKDEMON || vis->mobj->colorized) return R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE); @@ -772,7 +808,7 @@ UINT8 *R_GetSpriteTranslation(vissprite_t *vis) static void R_DrawVisSprite(vissprite_t *vis) { column_t *column; - void (*localcolfunc)(column_t *); + void (*localcolfunc)(column_t *, column_t *); INT32 texturecolumn; INT32 pwidth; fixed_t frac; @@ -796,26 +832,27 @@ static void R_DrawVisSprite(vissprite_t *vis) if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) return; // ditto } - colfunc = colfuncs[BASEDRAWFUNC]; // hack: this isn't resetting properly somewhere. + R_SetColumnFunc(BASEDRAWFUNC, false); // hack: this isn't resetting properly somewhere. dc_colormap = vis->colormap; + dc_fullbright = colormaps; dc_translation = R_GetSpriteTranslation(vis); if (R_SpriteIsFlashing(vis)) // Bosses "flash" - colfunc = colfuncs[COLDRAWFUNC_TRANS]; // translate certain pixels to white + R_SetColumnFunc(COLDRAWFUNC_TRANS, false); // translate certain pixels to white else if (vis->mobj->color && vis->transmap) // Color mapping { - colfunc = colfuncs[COLDRAWFUNC_TRANSTRANS]; + R_SetColumnFunc(COLDRAWFUNC_TRANSTRANS, false); dc_transmap = vis->transmap; } else if (vis->transmap) { - colfunc = colfuncs[COLDRAWFUNC_FUZZY]; + R_SetColumnFunc(COLDRAWFUNC_FUZZY, false); dc_transmap = vis->transmap; //Fab : 29-04-98: translucency table } else if (vis->mobj->color) // translate green skin to another color - colfunc = colfuncs[COLDRAWFUNC_TRANS]; + R_SetColumnFunc(COLDRAWFUNC_TRANS, false); else if (vis->mobj->sprite == SPR_PLAY) // Looks like a player, but doesn't have a color? Get rid of green sonic syndrome. - colfunc = colfuncs[COLDRAWFUNC_TRANS]; + R_SetColumnFunc(COLDRAWFUNC_TRANS, false); if (vis->extra_colormap && !(vis->renderflags & RF_NOCOLORMAPS)) { @@ -827,8 +864,13 @@ static void R_DrawVisSprite(vissprite_t *vis) if (!dc_colormap) dc_colormap = colormaps; + dc_fullbright = colormaps; + if (encoremap && !vis->mobj->color && !(vis->mobj->flags & MF_DONTENCOREMAP)) - dc_colormap += COLORMAP_REMAPOFFSET; + { + dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } dc_texturemid = vis->texturemid; dc_texheight = 0; @@ -901,7 +943,7 @@ static void R_DrawVisSprite(vissprite_t *vis) column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn])); - localcolfunc (column); + localcolfunc (column, NULL); } } else if (vis->cut & SC_SHEAR) @@ -923,7 +965,7 @@ static void R_DrawVisSprite(vissprite_t *vis) #endif sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); - localcolfunc (column); + localcolfunc (column, NULL); } } else @@ -943,11 +985,11 @@ static void R_DrawVisSprite(vissprite_t *vis) #else column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[frac>>FRACBITS])); #endif - localcolfunc (column); + localcolfunc (column, NULL); } } - colfunc = colfuncs[BASEDRAWFUNC]; + R_SetColumnFunc(BASEDRAWFUNC, false); dc_hires = 0; vis->x1 = x1; @@ -977,13 +1019,17 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis) if (vis->transmap) { - colfunc = colfuncs[COLDRAWFUNC_FUZZY]; + R_SetColumnFunc(COLDRAWFUNC_FUZZY, false); dc_transmap = vis->transmap; //Fab : 29-04-98: translucency table } dc_colormap = colormaps; + dc_fullbright = colormaps; if (encoremap) + { dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } dc_iscale = FixedDiv(FRACUNIT, vis->scale); dc_texturemid = vis->texturemid; @@ -1012,10 +1058,10 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis) #else column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[frac>>FRACBITS])); #endif - R_DrawMaskedColumn(column); + R_DrawMaskedColumn(column, NULL); } - colfunc = colfuncs[BASEDRAWFUNC]; + R_SetColumnFunc(BASEDRAWFUNC, false); } // @@ -1357,16 +1403,8 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, // static void R_ProjectSprite(mobj_t *thing) { - fixed_t thingxpos = thing->x + thing->sprxoff; - fixed_t thingypos = thing->y + thing->spryoff; - fixed_t thingzpos = thing->z + thing->sprzoff; - mobj_t *oldthing = thing; - //const fixed_t oldthingxpos = oldthing->x + oldthing->sprxoff; - //const fixed_t oldthingypos = oldthing->y + oldthing->spryoff; - const fixed_t oldthingzpos = oldthing->z + oldthing->sprzoff; - fixed_t tr_x, tr_y; fixed_t tx, tz; fixed_t xscale, yscale; //added : 02-02-98 : aaargll..if I were a math-guy!!! @@ -1431,24 +1469,52 @@ static void R_ProjectSprite(mobj_t *thing) angle_t spriterotangle = 0; #endif - // hitlag vibrating - if (thing->hitlag > 0) + // uncapped/interpolation + fixed_t interpx = thing->x; + fixed_t interpy = thing->y; + fixed_t interpz = thing->z; + angle_t interpangle = (thing->player ? thing->player->drawangle : thing->angle); + + // do interpolation + if (cv_frameinterpolation.value == 1) { - fixed_t mul = thing->hitlag * (FRACUNIT / 10); + interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x); + interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y); + interpz = thing->old_z + FixedMul(rendertimefrac, thing->z - thing->old_z); + + if (thing->player) + { + interpangle = thing->player->old_drawangle + FixedMul(rendertimefrac, thing->player->drawangle - thing->player->old_drawangle); + } + else + { + interpangle = thing->old_angle + FixedMul(rendertimefrac, thing->angle - thing->old_angle); + } + } + + // hitlag vibrating (todo: interp somehow?) + if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG)) + { + fixed_t mul = thing->hitlag * HITLAGJITTERS; if (leveltime & 1) { mul = -mul; } - thingxpos += FixedMul(thing->momx, mul); - thingypos += FixedMul(thing->momy, mul); - thingzpos += FixedMul(thing->momz, mul); + interpx += FixedMul(thing->momx, mul); + interpy += FixedMul(thing->momy, mul); + interpz += FixedMul(thing->momz, mul); } + // sprite offset + interpx += thing->sprxoff; + interpy += thing->spryoff; + interpz += thing->sprzoff; + // transform the origin point - tr_x = thingxpos - viewx; - tr_y = thingypos - viewy; + tr_x = interpx - viewx; + tr_y = interpy - viewy; basetz = tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance @@ -1525,7 +1591,7 @@ static void R_ProjectSprite(mobj_t *thing) if (sprframe->rotate != SRF_SINGLE || papersprite) { - ang = R_PointToAngle (thingxpos, thingypos) - (thing->player ? thing->player->drawangle : thing->angle); + ang = R_PointToAngle (interpx, interpy) - interpangle; if (mirrored) ang = InvAngle(ang); } @@ -1540,7 +1606,7 @@ static void R_ProjectSprite(mobj_t *thing) else { // choose a different rotation based on player view - //ang = R_PointToAngle (thingxpos, thingypos) - thing->angle; + //ang = R_PointToAngle (interpx, interpy) - interpangle; if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right rot = 6; // F7 slot @@ -1751,12 +1817,37 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t linkscale; thing = thing->tracer; + if (cv_frameinterpolation.value == 1) + { + interpx = thing->old_x + FixedMul(thing->x - thing->old_x, rendertimefrac); + interpy = thing->old_y + FixedMul(thing->y - thing->old_y, rendertimefrac); + } + + // hitlag vibrating (todo: interp somehow?) + if (thing->hitlag > 0 && (thing->eflags & MFE_DAMAGEHITLAG)) + { + fixed_t mul = thing->hitlag * (FRACUNIT / 10); + + if (leveltime & 1) + { + mul = -mul; + } + + interpx += FixedMul(thing->momx, mul); + interpy += FixedMul(thing->momy, mul); + interpz += FixedMul(thing->momz, mul); + } + + // sprite offset + interpx += thing->sprxoff; + interpy += thing->spryoff; + interpz += thing->sprzoff; if (! R_ThingVisible(thing)) return; - tr_x = (thingxpos + sort_x) - viewx; - tr_y = (thingypos + sort_y) - viewy; + tr_x = (interpx + sort_x) - viewx; + tr_y = (interpy + sort_y) - viewy; tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); linkscale = FixedDiv(projectiony[viewssnum], tz); @@ -1771,8 +1862,8 @@ static void R_ProjectSprite(mobj_t *thing) } else if (splat) { - tr_x = (thingxpos + sort_x) - viewx; - tr_y = (thingypos + sort_y) - viewy; + tr_x = (interpx + sort_x) - viewx; + tr_y = (interpy + sort_y) - viewy; sort_z = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); sortscale = FixedDiv(projectiony[viewssnum], sort_z); } @@ -1792,7 +1883,7 @@ static void R_ProjectSprite(mobj_t *thing) if (x2 < portalclipstart || x1 >= portalclipend) return; - if (P_PointOnLineSide(thingxpos, thingypos, portalclipline) != 0) + if (P_PointOnLineSide(interpx, interpy, portalclipline) != 0) return; } @@ -1861,12 +1952,12 @@ static void R_ProjectSprite(mobj_t *thing) // When vertical flipped, draw sprites from the top down, at least as far as offsets are concerned. // sprite height - sprite topoffset is the proper inverse of the vertical offset, of course. // remember gz and gzt should be seperated by sprite height, not thing height - thing height can be shorter than the sprite itself sometimes! - gz = oldthingzpos + oldthing->height - FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale)); + gz = interpz + oldthing->height - FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale)); gzt = gz + FixedMul(spr_height, FixedMul(spriteyscale, this_scale)); } else { - gzt = oldthingzpos + FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale)); + gzt = interpz + FixedMul(spr_topoffset, FixedMul(spriteyscale, this_scale)); gz = gzt - FixedMul(spr_height, FixedMul(spriteyscale, this_scale)); } } @@ -1885,7 +1976,7 @@ static void R_ProjectSprite(mobj_t *thing) // R_GetPlaneLight won't work on sloped lights! for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) { - fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], thingxpos, thingypos); + fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], interpx, interpy); if (h <= top) { light = lightnum - 1; break; @@ -1903,7 +1994,7 @@ static void R_ProjectSprite(mobj_t *thing) } heightsec = thing->subsector->sector->heightsec; - if (viewplayer->mo && viewplayer->mo->subsector) + if (viewplayer && viewplayer->mo && viewplayer->mo->subsector) phs = viewplayer->mo->subsector->sector->heightsec; else phs = -1; @@ -1911,12 +2002,12 @@ static void R_ProjectSprite(mobj_t *thing) if (heightsec != -1 && phs != -1) // only clip things which are in special sectors { if (viewz < sectors[phs].floorheight ? - thingzpos >= sectors[heightsec].floorheight : + interpz >= sectors[heightsec].floorheight : gzt < sectors[heightsec].floorheight) return; if (viewz > sectors[phs].ceilingheight ? gzt < sectors[heightsec].ceilingheight && viewz >= sectors[heightsec].ceilingheight : - thingzpos >= sectors[heightsec].ceilingheight) + interpz >= sectors[heightsec].ceilingheight) return; } @@ -1929,12 +2020,12 @@ static void R_ProjectSprite(mobj_t *thing) vis->sortscale = sortscale; vis->sortsplat = sortsplat; vis->dispoffset = dispoffset; // Monster Iestyn: 23/11/15 - vis->gx = thingxpos; - vis->gy = thingypos; + vis->gx = interpx; + vis->gy = interpy; vis->gz = gz; vis->gzt = gzt; vis->thingheight = thing->height; - vis->pz = thingzpos; + vis->pz = interpz; vis->pzt = vis->pz + vis->thingheight; vis->texturemid = FixedDiv(gzt - viewz, spriteyscale); vis->scalestep = scalestep; @@ -2069,9 +2160,22 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) //SoM: 3/17/2000 fixed_t gz, gzt; + // uncapped/interpolation + fixed_t interpx = thing->x; + fixed_t interpy = thing->y; + fixed_t interpz = thing->z; + + // do interpolation + if (cv_frameinterpolation.value == 1) + { + interpx = thing->old_x + FixedMul(rendertimefrac, thing->x - thing->old_x); + interpy = thing->old_y + FixedMul(rendertimefrac, thing->y - thing->old_y); + interpz = thing->old_z + FixedMul(rendertimefrac, thing->z - thing->old_z); + } + // transform the origin point - tr_x = thing->x - viewx; - tr_y = thing->y - viewy; + tr_x = interpx - viewx; + tr_y = interpy - viewy; tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin); // near/far distance @@ -2135,12 +2239,12 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) if (x2 < portalclipstart || x1 >= portalclipend) return; - if (P_PointOnLineSide(thing->x, thing->y, portalclipline) != 0) + if (P_PointOnLineSide(interpx, interpy, portalclipline) != 0) return; } //SoM: 3/17/2000: Disregard sprites that are out of view.. - gzt = thing->z + spritecachedinfo[lump].topoffset; + gzt = interpz + spritecachedinfo[lump].topoffset; gz = gzt - spritecachedinfo[lump].height; if (thing->subsector->sector->cullheight) @@ -2153,10 +2257,13 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) vis = R_NewVisSprite(); vis->scale = vis->sortscale = yscale; //<dispoffset = 0; // Monster Iestyn: 23/11/15 - vis->gx = thing->x; - vis->gy = thing->y; + vis->gx = interpx; + vis->gy = interpy; vis->gz = gz; vis->gzt = gzt; + vis->thingheight = 4*FRACUNIT; + vis->pz = interpz; + vis->pzt = vis->pz + vis->thingheight; vis->texturemid = vis->gzt - viewz; vis->scalestep = 0; vis->paperdistance = 0; diff --git a/src/r_things.h b/src/r_things.h index cbbb0f2d8..7ff1bd4c7 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -47,8 +47,8 @@ extern fixed_t windowtop; extern fixed_t windowbottom; extern INT32 lengthcol; -void R_DrawMaskedColumn(column_t *column); -void R_DrawFlippedMaskedColumn(column_t *column); +void R_DrawMaskedColumn(column_t *column, column_t *brightmap); +void R_DrawFlippedMaskedColumn(column_t *column, column_t *brightmap); // ---------------- // SPRITE RENDERING diff --git a/src/s_sound.c b/src/s_sound.c index 71e97c27b..7e44bb207 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -678,9 +678,6 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) sep = (~sep) & 255; } - // Handle closed caption input. - S_StartCaption(actual_id, cnum, MAXCAPTIONTICS); - // At this point it is determined that a sound can and should be played, so find a free channel to play it on cnum = S_getChannel(origin, sfx); @@ -689,11 +686,14 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) return; // If there's no free channels, there won't be any for anymore players either } + // Handle closed caption input. + S_StartCaption(actual_id, cnum, MAXCAPTIONTICS); + // Now that we know we are going to play a sound, fill out this info channels[cnum].sfxinfo = sfx; channels[cnum].origin = origin; channels[cnum].volume = initial_volume; - channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum); + channels[cnum].handle = I_StartSound(sfx_id, S_GetSoundVolume(sfx, volume), sep, pitch, priority, cnum); } } @@ -899,7 +899,7 @@ void S_UpdateSounds(void) } if (audible) - I_UpdateSoundParams(c->handle, volume, sep, pitch); + I_UpdateSoundParams(c->handle, S_GetSoundVolume(c->sfxinfo, volume), sep, pitch); else S_StopChannel(cnum); } @@ -1011,6 +1011,14 @@ fixed_t S_CalculateSoundDistance(fixed_t sx1, fixed_t sy1, fixed_t sz1, fixed_t return FixedDiv(approx_dist, mapobjectscale); // approx_dist } +INT32 S_GetSoundVolume(sfxinfo_t *sfx, INT32 volume) +{ + if (sfx->volume > 0) + return (volume * sfx->volume) / 100; + + return volume; +} + // // Changes volume, stereo-separation, and pitch variables // from the norm of a sound effect to be played. diff --git a/src/s_sound.h b/src/s_sound.h index 80a53fb3e..816a90fb5 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -295,6 +295,8 @@ void S_UpdateClosedCaptions(void); FUNCMATH fixed_t S_CalculateSoundDistance(fixed_t px1, fixed_t py1, fixed_t pz1, fixed_t px2, fixed_t py2, fixed_t pz2); +INT32 S_GetSoundVolume(sfxinfo_t *sfx, INT32 volume); + void S_SetSfxVolume(INT32 volume); void S_SetMusicVolume(INT32 digvolume); #define S_SetDigMusicVolume S_SetMusicVolume diff --git a/src/screen.c b/src/screen.c index abc302748..25dcbb1f7 100644 --- a/src/screen.c +++ b/src/screen.c @@ -49,10 +49,17 @@ // -------------------------------------------- void (*colfunc)(void); void (*colfuncs[COLDRAWFUNC_MAX])(void); +#ifdef USE_COL_SPAN_ASM +void (*colfuncs_asm[COLDRAWFUNC_MAX])(void); +#endif +int colfunctype; void (*spanfunc)(void); void (*spanfuncs[SPANDRAWFUNC_MAX])(void); void (*spanfuncs_npo2[SPANDRAWFUNC_MAX])(void); +#ifdef USE_COL_SPAN_ASM +void (*spanfuncs_asm[SPANDRAWFUNC_MAX])(void); +#endif // ------------------ // global video state @@ -118,9 +125,6 @@ void SCR_SetDrawFuncs(void) colfuncs[BASEDRAWFUNC] = R_DrawColumn_8; spanfuncs[BASEDRAWFUNC] = R_DrawSpan_8; - colfunc = colfuncs[BASEDRAWFUNC]; - spanfunc = spanfuncs[BASEDRAWFUNC]; - colfuncs[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8; colfuncs[COLDRAWFUNC_TRANS] = R_DrawTranslatedColumn_8; colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8; @@ -160,26 +164,29 @@ void SCR_SetDrawFuncs(void) spanfuncs_npo2[SPANDRAWFUNC_TILTEDWATER] = R_DrawTiltedTranslucentWaterSpan_NPO2_8; spanfuncs_npo2[SPANDRAWFUNC_FOG] = NULL; // Not needed -#ifdef RUSEASM +#if (defined(RUSEASM) && defined(USE_COL_SPAN_ASM)) if (R_ASM) { if (R_MMX) { - colfuncs[BASEDRAWFUNC] = R_DrawColumn_8_MMX; - //colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8_ASM; - //colfuncs[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8_ASM; - colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8_MMX; - spanfuncs[BASEDRAWFUNC] = R_DrawSpan_8_MMX; + colfuncs_asm[BASEDRAWFUNC] = R_DrawColumn_8_MMX; + //colfuncs_asm[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8_ASM; + //colfuncs_asm[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8_ASM; + colfuncs_asm[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8_MMX; + spanfuncs_asm[BASEDRAWFUNC] = R_DrawSpan_8_MMX; } else { - colfuncs[BASEDRAWFUNC] = R_DrawColumn_8_ASM; - //colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8_ASM; - //colfuncs[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8_ASM; - colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8_ASM; + colfuncs_asm[BASEDRAWFUNC] = R_DrawColumn_8_ASM; + //colfuncs_asm[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8_ASM; + //colfuncs_asm[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8_ASM; + colfuncs_asm[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8_ASM; } } #endif + + R_SetColumnFunc(BASEDRAWFUNC, false); + R_SetSpanFunc(BASEDRAWFUNC, false, false); } /* else if (vid.bpp > 1) { @@ -201,6 +208,65 @@ void SCR_SetDrawFuncs(void) */ } +void R_SetColumnFunc(size_t id, boolean brightmapped) +{ + I_Assert(id < COLDRAWFUNC_MAX); + + colfunctype = id; + +#ifdef USE_COL_SPAN_ASM + if (colfuncs_asm[id] != NULL && brightmapped == false) + { + colfunc = colfuncs_asm[id]; + } + else +#endif + { + colfunc = colfuncs[id]; + } +} + +void R_SetSpanFunc(size_t id, boolean npo2, boolean brightmapped) +{ + I_Assert(id < COLDRAWFUNC_MAX); + + if (spanfuncs_npo2[id] != NULL && npo2 == true) + { + spanfunc = spanfuncs_npo2[id]; + } +#ifdef USE_COL_SPAN_ASM + else if (spanfuncs_asm[id] != NULL && brightmapped == false) + { + spanfunc = spanfuncs_asm[id]; + } +#endif + else + { + spanfunc = spanfuncs[id]; + } +} + +boolean R_CheckColumnFunc(size_t id) +{ + size_t i; + + if (colfunc == NULL) + { + // Shouldn't happen. + return false; + } + + for (i = 0; i < COLDRAWFUNC_MAX; i++) + { + if (colfunc == colfuncs[id] || colfunc == colfuncs_asm[id]) + { + return true; + } + } + + return false; +} + void SCR_SetMode(void) { if (dedicated) @@ -453,9 +519,46 @@ boolean SCR_IsAspectCorrect(INT32 width, INT32 height) // XMOD FPS display // moved out of os-specific code for consistency -static boolean fpsgraph[TICRATE]; +static boolean ticsgraph[TICRATE]; static tic_t lasttic; +static UINT32 fpstime = 0; +static UINT32 lastupdatetime = 0; + +#define FPSUPDATERATE 1/20 // What fraction of a second to update at. The fraction will not simplify to 0, trust me. +#define FPSMAXSAMPLES 16 + +static UINT32 fpssamples[FPSMAXSAMPLES]; +static UINT32 fpssampleslen = 0; +static UINT32 fpssum = 0; +double aproxfps = 0.0f; + +void SCR_CalcAproxFps(void) +{ + tic_t i = 0; + if (I_PreciseToMicros(fpstime - lastupdatetime) > 1000000 * FPSUPDATERATE) + { + if (fpssampleslen == FPSMAXSAMPLES) + { + fpssum -= fpssamples[0]; + + for (i = 1; i < fpssampleslen; i++) + fpssamples[i-1] = fpssamples[i]; + } + else + fpssampleslen++; + + fpssamples[fpssampleslen-1] = I_GetPreciseTime() - fpstime; + fpssum += fpssamples[fpssampleslen-1]; + + aproxfps = 1000000 / (I_PreciseToMicros(fpssum) / (double)fpssampleslen); + + lastupdatetime = I_GetPreciseTime(); + } + + fpstime = I_GetPreciseTime(); +} + void SCR_DisplayTicRate(void) { tic_t i; @@ -464,25 +567,51 @@ void SCR_DisplayTicRate(void) const UINT8 *ticcntcolor = NULL; for (i = lasttic + 1; i < TICRATE+lasttic && i < ontic; ++i) - fpsgraph[i % TICRATE] = false; + ticsgraph[i % TICRATE] = false; - fpsgraph[ontic % TICRATE] = true; + ticsgraph[ontic % TICRATE] = true; for (i = 0;i < TICRATE;++i) - if (fpsgraph[i]) + if (ticsgraph[i]) ++totaltics; - if (totaltics <= TICRATE/2) ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_RASPBERRY, GTC_CACHE); - else if (totaltics == TICRATE) ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_MINT, GTC_CACHE); - // draw "FPS" V_DrawFixedPatch(306<= 60.0f) ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_MINT, GTC_CACHE); + + /* + if (cv_fpscap.value != 0) + { + // draw total frame: + //V_DrawPingNum(318, 190, V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS, cv_fpscap.value, ticcntcolor); + // draw "/" + //V_DrawFixedPatch(306<= TICRATE) ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_MINT, GTC_CACHE); + + // draw total frame: + V_DrawPingNum(318, 190, V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS, TICRATE, ticcntcolor); + // draw "/" + V_DrawFixedPatch(306< #endif // HAVE_ZLIB -#endif // HAVE_LIBGME +#endif // HAVE_GME #include "../doomdef.h" #include "../doomstat.h" // menuactive @@ -79,11 +79,11 @@ write netcode into the sound code, OKAY? #define MUS_MODPLUG MUS_MODPLUG_UNUSED #endif -#ifdef HAVE_LIBGME +#ifdef HAVE_GME #include "gme/gme.h" #define GME_TREBLE 5.0f #define GME_BASS 1.0f -#endif // HAVE_LIBGME +#endif // HAVE_GME static UINT16 BUFFERSIZE = 2048; static UINT16 SAMPLERATE = 44100; @@ -123,7 +123,7 @@ static INT32 fading_id; static void (*fading_callback)(void); static boolean fading_nocleanup; -#ifdef HAVE_LIBGME +#ifdef HAVE_GME static Music_Emu *gme; static UINT16 current_track; #endif @@ -157,7 +157,7 @@ static void var_cleanup(void) internal_volume = 100; } -#if defined (HAVE_LIBGME) && defined (HAVE_ZLIB) +#if defined (HAVE_GME) && defined (HAVE_ZLIB) static const char* get_zlib_error(int zErr) { switch (zErr) @@ -250,7 +250,7 @@ void I_ShutdownSound(void) SDL_QuitSubSystem(SDL_INIT_AUDIO); -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) gme_delete(gme); #endif @@ -394,7 +394,7 @@ void *I_GetSfx(sfxinfo_t *sfx) void *lump; Mix_Chunk *chunk; SDL_RWops *rw; -#ifdef HAVE_LIBGME +#ifdef HAVE_GME Music_Emu *emu; gme_info_t *info; #endif @@ -414,7 +414,7 @@ void *I_GetSfx(sfxinfo_t *sfx) } // Not a doom sound? Try something else. -#ifdef HAVE_LIBGME +#ifdef HAVE_GME // VGZ format if (((UINT8 *)lump)[0] == 0x1F && ((UINT8 *)lump)[1] == 0x8B) @@ -700,7 +700,7 @@ static UINT32 music_fade(UINT32 interval, void *param) } } -#ifdef HAVE_LIBGME +#ifdef HAVE_GME static void mix_gme(void *udata, Uint8 *stream, int len) { int i; @@ -760,7 +760,7 @@ void I_ShutdownMusic(void) musictype_t I_SongType(void) { -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) return MU_GME; else @@ -791,7 +791,7 @@ musictype_t I_SongType(void) boolean I_SongPlaying(void) { return ( -#ifdef HAVE_LIBGME +#ifdef HAVE_GME (I_SongType() == MU_GME && gme) || #endif #ifdef HAVE_OPENMPT @@ -814,7 +814,7 @@ boolean I_SetSongSpeed(float speed) { if (speed > 250.0f) speed = 250.0f; //limit speed up to 250x -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { SDL_LockAudio(); @@ -856,7 +856,7 @@ UINT32 I_GetSongLength(void) { INT32 length; -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { gme_info_t *info; @@ -926,7 +926,7 @@ boolean I_SetSongLoopPoint(UINT32 looppoint) UINT32 I_GetSongLoopPoint(void) { -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { INT32 looppoint; @@ -955,7 +955,7 @@ UINT32 I_GetSongLoopPoint(void) boolean I_SetSongPosition(UINT32 position) { UINT32 length; -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { // this is unstable, so fail silently @@ -1020,7 +1020,7 @@ boolean I_SetSongPosition(UINT32 position) UINT32 I_GetSongPosition(void) { -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { INT32 position = gme_tell(gme); @@ -1105,7 +1105,7 @@ boolean I_LoadSong(char *data, size_t len) SDL_RWops *rw; if (music -#ifdef HAVE_LIBGME +#ifdef HAVE_GME || gme #endif #ifdef HAVE_OPENMPT @@ -1117,7 +1117,7 @@ boolean I_LoadSong(char *data, size_t len) // always do this whether or not a music already exists var_cleanup(); -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if ((UINT8)data[0] == 0x1F && (UINT8)data[1] == 0x8B) { @@ -1244,7 +1244,7 @@ void I_UnloadSong(void) { I_StopSong(); -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { gme_delete(gme); @@ -1267,7 +1267,7 @@ void I_UnloadSong(void) boolean I_PlaySong(boolean looping) { -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { gme_equalizer_t eq = {GME_TREBLE, GME_BASS, 0,0,0,0,0,0,0,0}; @@ -1333,7 +1333,7 @@ void I_StopSong(void) if (!fading_nocleanup) I_StopFadingSong(); -#ifdef HAVE_LIBGME +#ifdef HAVE_GME if (gme) { Mix_HookMusic(NULL, NULL); @@ -1395,7 +1395,7 @@ void I_SetMusicVolume(int volume) boolean I_SetSongTrack(int track) { -#ifdef HAVE_LIBGME +#ifdef HAVE_GME // If the specified track is within the number of tracks playing, then change it if (gme) { diff --git a/src/sounds.c b/src/sounds.c index b46e11ba1..e9a13da77 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -908,6 +908,138 @@ sfxinfo_t S_sfx[NUMSFX] = {"mbv96", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"mbv97", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + // SegaSonic Arcade sounds + {"ssa001", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa002", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa003", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa004", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa005", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa006", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa007", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa008", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa009", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa010", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa011", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa012", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa013", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa014", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa015", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa016", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa017", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa018", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa019", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa020", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa021", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa022", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa023", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa024", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa025", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa026", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa027", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa028", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa029", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa030", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa031", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa032", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa033", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa034", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa035", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa036", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa037", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa038", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa039", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa040", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa041", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa042", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa043", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa044", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa045", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa046", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa047", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa048", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa049", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa050", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa051", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa052", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa053", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa054", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa055", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa056", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa057", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa058", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa059", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa060", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa061", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa062", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa063", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa064", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa065", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa066", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa067", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa068", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa069", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa070", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa071", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa072", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa073", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa074", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa075", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa076", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa077", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa078", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa079", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa080", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa081", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa082", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa083", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa084", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa085", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa086", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa087", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa088", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa089", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa090", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa091", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa092", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa093", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa094", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa095", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa096", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa097", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa098", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa099", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa100", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa101", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa102", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa103", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa104", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa105", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa106", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa107", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa108", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa109", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa110", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa111", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa112", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa113", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa114", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa115", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa116", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa117", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa118", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa119", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa120", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa121", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa122", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa123", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa124", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa125", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa126", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa127", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa128", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa129", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + {"ssa130", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, + // SRB2kart {"slip", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Spinout {"screec", false, 48, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Tight turning screech diff --git a/src/sounds.h b/src/sounds.h index 8d81aae20..9abf99117 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -972,6 +972,138 @@ typedef enum sfx_mbv96, sfx_mbv97, + // SegaSonic Arcade sounds + sfx_ssa001, + sfx_ssa002, + sfx_ssa003, + sfx_ssa004, + sfx_ssa005, + sfx_ssa006, + sfx_ssa007, + sfx_ssa008, + sfx_ssa009, + sfx_ssa010, + sfx_ssa011, + sfx_ssa012, + sfx_ssa013, + sfx_ssa014, + sfx_ssa015, + sfx_ssa016, + sfx_ssa017, + sfx_ssa018, + sfx_ssa019, + sfx_ssa020, + sfx_ssa021, + sfx_ssa022, + sfx_ssa023, + sfx_ssa024, + sfx_ssa025, + sfx_ssa026, + sfx_ssa027, + sfx_ssa028, + sfx_ssa029, + sfx_ssa030, + sfx_ssa031, + sfx_ssa032, + sfx_ssa033, + sfx_ssa034, + sfx_ssa035, + sfx_ssa036, + sfx_ssa037, + sfx_ssa038, + sfx_ssa039, + sfx_ssa040, + sfx_ssa041, + sfx_ssa042, + sfx_ssa043, + sfx_ssa044, + sfx_ssa045, + sfx_ssa046, + sfx_ssa047, + sfx_ssa048, + sfx_ssa049, + sfx_ssa050, + sfx_ssa051, + sfx_ssa052, + sfx_ssa053, + sfx_ssa054, + sfx_ssa055, + sfx_ssa056, + sfx_ssa057, + sfx_ssa058, + sfx_ssa059, + sfx_ssa060, + sfx_ssa061, + sfx_ssa062, + sfx_ssa063, + sfx_ssa064, + sfx_ssa065, + sfx_ssa066, + sfx_ssa067, + sfx_ssa068, + sfx_ssa069, + sfx_ssa070, + sfx_ssa071, + sfx_ssa072, + sfx_ssa073, + sfx_ssa074, + sfx_ssa075, + sfx_ssa076, + sfx_ssa077, + sfx_ssa078, + sfx_ssa079, + sfx_ssa080, + sfx_ssa081, + sfx_ssa082, + sfx_ssa083, + sfx_ssa084, + sfx_ssa085, + sfx_ssa086, + sfx_ssa087, + sfx_ssa088, + sfx_ssa089, + sfx_ssa090, + sfx_ssa091, + sfx_ssa092, + sfx_ssa093, + sfx_ssa094, + sfx_ssa095, + sfx_ssa096, + sfx_ssa097, + sfx_ssa098, + sfx_ssa099, + sfx_ssa100, + sfx_ssa101, + sfx_ssa102, + sfx_ssa103, + sfx_ssa104, + sfx_ssa105, + sfx_ssa106, + sfx_ssa107, + sfx_ssa108, + sfx_ssa109, + sfx_ssa110, + sfx_ssa111, + sfx_ssa112, + sfx_ssa113, + sfx_ssa114, + sfx_ssa115, + sfx_ssa116, + sfx_ssa117, + sfx_ssa118, + sfx_ssa119, + sfx_ssa120, + sfx_ssa121, + sfx_ssa122, + sfx_ssa123, + sfx_ssa124, + sfx_ssa125, + sfx_ssa126, + sfx_ssa127, + sfx_ssa128, + sfx_ssa129, + sfx_ssa130, + // SRB2kart sfx_slip, sfx_screec, diff --git a/src/st_stuff.c b/src/st_stuff.c index ee03a07a4..3e0788f4d 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1260,6 +1260,7 @@ void ST_Drawer(void) if (rendermode != render_none) ST_doPaletteStuff(); { +#if 0 const tic_t length = TICRATE/2; if (lt_exitticker) @@ -1270,6 +1271,9 @@ void ST_Drawer(void) } else st_translucency = 0; +#else + st_translucency = cv_translucenthud.value; +#endif } // Check for a valid level title diff --git a/src/w_wad.c b/src/w_wad.c index 4e7e97dbb..60339c426 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1480,10 +1480,10 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si int zErr; // Helper var. z_stream strm; unsigned long rawSize = l->disksize; - unsigned long decSize = l->size; + unsigned long decSize = size; rawData = Z_Malloc(rawSize, PU_STATIC, NULL); - decData = Z_Malloc(decSize, PU_STATIC, NULL); + decData = dest; if (fread(rawData, 1, rawSize, handle) < rawSize) I_Error("wad %d, lump %d: cannot read compressed data", wad, lump); @@ -1501,12 +1501,8 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si zErr = inflateInit2(&strm, -15); if (zErr == Z_OK) { - zErr = inflate(&strm, Z_FINISH); - if (zErr == Z_STREAM_END) - { - M_Memcpy(dest, decData, size); - } - else + zErr = inflate(&strm, Z_SYNC_FLUSH); + if (zErr != Z_OK && zErr != Z_STREAM_END) { size = 0; zerr(zErr); @@ -1520,7 +1516,6 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si } Z_Free(rawData); - Z_Free(decData); #ifdef NO_PNG_LUMPS if (Picture_IsLumpPNG((UINT8 *)dest, size)) diff --git a/src/win32/Makefile.cfg b/src/win32/Makefile.cfg deleted file mode 100644 index 85ee0d6b5..000000000 --- a/src/win32/Makefile.cfg +++ /dev/null @@ -1,161 +0,0 @@ -# -# win32/Makefile.cfg for SRB2/Minwgw -# - -# -#Mingw, if you don't know, that's Win32/Win64 -# - -ifdef MINGW64 - HAVE_LIBGME=1 - LIBGME_CFLAGS=-I../libs/gme/include - LIBGME_LDFLAGS=-L../libs/gme/win64 -lgme -ifdef HAVE_OPENMPT - LIBOPENMPT_CFLAGS?=-I../libs/libopenmpt/inc - LIBOPENMPT_LDFLAGS?=-L../libs/libopenmpt/lib/x86_64/mingw -lopenmpt -endif -ifndef NOMIXERX - HAVE_MIXERX=1 - SDL_CFLAGS?=-I../libs/SDL2/x86_64-w64-mingw32/include/SDL2 -I../libs/SDLMixerX/x86_64-w64-mingw32/include/SDL2 -Dmain=SDL_main - SDL_LDFLAGS?=-L../libs/SDL2/x86_64-w64-mingw32/lib -L../libs/SDLMixerX/x86_64-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows -else - SDL_CFLAGS?=-I../libs/SDL2/x86_64-w64-mingw32/include/SDL2 -I../libs/SDL2_mixer/x86_64-w64-mingw32/include/SDL2 -Dmain=SDL_main - SDL_LDFLAGS?=-L../libs/SDL2/x86_64-w64-mingw32/lib -L../libs/SDL2_mixer/x86_64-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows -endif -else - HAVE_LIBGME=1 - LIBGME_CFLAGS=-I../libs/gme/include - LIBGME_LDFLAGS=-L../libs/gme/win32 -lgme -ifdef HAVE_OPENMPT - LIBOPENMPT_CFLAGS?=-I../libs/libopenmpt/inc - LIBOPENMPT_LDFLAGS?=-L../libs/libopenmpt/lib/x86/mingw -lopenmpt -endif -ifndef NOMIXERX - HAVE_MIXERX=1 - SDL_CFLAGS?=-I../libs/SDL2/i686-w64-mingw32/include/SDL2 -I../libs/SDLMixerX/i686-w64-mingw32/include/SDL2 -Dmain=SDL_main - SDL_LDFLAGS?=-L../libs/SDL2/i686-w64-mingw32/lib -L../libs/SDLMixerX/i686-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows -else - SDL_CFLAGS?=-I../libs/SDL2/i686-w64-mingw32/include/SDL2 -I../libs/SDL2_mixer/i686-w64-mingw32/include/SDL2 -Dmain=SDL_main - SDL_LDFLAGS?=-L../libs/SDL2/i686-w64-mingw32/lib -L../libs/SDL2_mixer/i686-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows -endif -endif - -ifndef NOASM - USEASM=1 -endif - -ifndef NONET -ifndef MINGW64 #miniupnc is broken with MINGW64 - HAVE_MINIUPNPC=1 -endif -endif - -ifndef NO_DISCORDRPC - HAVE_DISCORDRPC=1 -endif - - OPTS=-DSTDC_HEADERS - -ifndef GCC44 - #OPTS+=-mms-bitfields -endif - - LIBS+=-ladvapi32 -lkernel32 -lmsvcrt -luser32 -ifdef MINGW64 - LIBS+=-lws2_32 -else -ifdef NO_IPV6 - LIBS+=-lwsock32 -else - LIBS+=-lws2_32 -endif -endif - -ifndef MINGW64 - CPPFLAGS+=-I../libs/drmingw/include - LDFLAGS+=-L../libs/drmingw/lib/win32 - LIBS+=-lmgwhelp -lexchndl -endif - - # name of the exefile - EXENAME?=srb2kart.exe - -ifdef SDL - i_system_o+=$(OBJDIR)/SRB2.res - #i_main_o+=$(OBJDIR)/win_dbg.o -ifndef NOHW - OPTS+=-DUSE_WGL_SWAP -endif -endif - - -ZLIB_CFLAGS?=-I../libs/zlib -ifdef MINGW64 -ZLIB_LDFLAGS?=-L../libs/zlib/win32 -lz64 -else -ZLIB_LDFLAGS?=-L../libs/zlib/win32 -lz32 -endif - -ifndef NOPNG -ifndef PNG_CONFIG - PNG_CFLAGS?=-I../libs/libpng-src -ifdef MINGW64 - PNG_LDFLAGS?=-L../libs/libpng-src/projects -lpng64 -else - PNG_LDFLAGS?=-L../libs/libpng-src/projects -lpng32 -endif #MINGW64 -endif #PNG_CONFIG -endif #NOPNG - -ifdef GETTEXT -ifndef CCBS - MSGFMT?=../libs/gettext/bin32/msgfmt.exe -endif -ifdef MINGW64 - CPPFLAGS+=-I../libs/gettext/include64 - LDFLAGS+=-L../libs/gettext/lib64 - LIBS+=-lmingwex -else - CPPFLAGS+=-I../libs/gettext/include32 - LDFLAGS+=-L../libs/gettext/lib32 - STATIC_GETTEXT=1 -endif #MINGW64 -ifdef STATIC_GETTEXT - LIBS+=-lasprintf -lintl -else - LIBS+=-lintl.dll -endif #STATIC_GETTEXT -endif #GETTEXT - -ifdef HAVE_MINIUPNPC - CPPFLAGS+=-I../libs/ -DSTATIC_MINIUPNPC -ifdef MINGW64 - LDFLAGS+=-L../libs/miniupnpc/mingw64 -else - LDFLAGS+=-L../libs/miniupnpc/mingw32 -endif #MINGW64 -endif - -ifndef NOCURL - CURL_CFLAGS+=-I../libs/curl/include -ifdef MINGW64 - CURL_LDFLAGS+=-L../libs/curl/lib64 -lcurl -else - CURL_LDFLAGS+=-L../libs/curl/lib32 -lcurl -endif #MINGW64 -endif - -ifdef HAVE_DISCORDRPC -ifdef MINGW64 - CPPFLAGS+=-I../libs/discord-rpc/win64-dynamic/include - LDFLAGS+=-L../libs/discord-rpc/win64-dynamic/lib -else - CPPFLAGS+=-I../libs/discord-rpc/win32-dynamic/include - LDFLAGS+=-L../libs/discord-rpc/win32-dynamic/lib -endif - LIBS+=-ldiscord-rpc -endif - -ifndef MINGW64 - LDFLAGS+=-Wl,--large-address-aware -endif diff --git a/src/win32/win_sys.c b/src/win32/win_sys.c index 2609c3e31..9b2c5bd07 100644 --- a/src/win32/win_sys.c +++ b/src/win32/win_sys.c @@ -45,6 +45,7 @@ #include "../d_main.h" #include "../m_argv.h" +#include "../m_fixed.h" #include "../w_wad.h" #include "../z_zone.h" @@ -261,6 +262,11 @@ tic_t I_GetTime(void) return newtics; } +fixed_t I_GetTimeFrac(void) +{ + return 0; +} + void I_Sleep(void) { if (cv_sleep.value > 0) diff --git a/src/y_inter.c b/src/y_inter.c index 68a6019ad..415672713 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -481,7 +481,7 @@ void Y_IntermissionDrawer(void) else hilicol = ((intertype == int_race) ? V_SKYMAP : V_REDMAP); - if (sorttic != -1 && intertic > sorttic && !demo.playback) + if (sorttic != -1 && intertic > sorttic && multiplayer) { INT32 count = (intertic - sorttic); @@ -586,7 +586,7 @@ void Y_IntermissionDrawer(void) y2 = y; - if (netgame && playerconsole[data.num[i]] == 0 && server_lagless && !players[data.num[i]].bot) + if ((netgame || (demo.playback && demo.netgame)) && playerconsole[data.num[i]] == 0 && server_lagless && !players[data.num[i]].bot) { static int alagles_timer = 0; patch_t *alagles; @@ -799,7 +799,7 @@ void Y_Ticker(void) if (intertype == int_race || intertype == int_battle) { - if (!(multiplayer && demo.playback)) // Don't advance to rankings in replays + //if (!(multiplayer && demo.playback)) // Don't advance to rankings in replays { if (!data.rankingsmode && (intertic >= sorttic + 8)) { @@ -868,8 +868,6 @@ void Y_Ticker(void) endtic = intertic + 3*TICRATE; // 3 second pause after end of tally } } - else if (!(intertic & 1)) - S_StartSound(NULL, sfx_ptally); // tally sound effect } } @@ -1013,7 +1011,7 @@ static void K_UpdatePowerLevels(void) data.increase[i] = increment[i]; clientpowerlevels[i][powertype] += data.increase[i]; - if (i == consoleplayer) + if (!demo.playback && i == consoleplayer) { CONS_Debug(DBG_GAMELOGIC, "Player %d is you! Saving...\n", i); vspowerlevel[powertype] = clientpowerlevels[i][powertype]; @@ -1069,7 +1067,7 @@ void Y_StartIntermission(void) { if (cv_inttime.value == 0) timer = 0; - else if (demo.playback) // Override inttime (which is pulled from the replay anyway + else if (demo.playback && !multiplayer) // Override inttime (which is pulled from the replay anyway timer = 10*TICRATE; else { @@ -1461,7 +1459,7 @@ static void Y_VoteStops(SINT8 pick, SINT8 level) if (gametype != votelevels[level][1]) { INT16 lastgametype = gametype; - gametype = votelevels[level][1]; + G_SetGametype(votelevels[level][1]); D_GameTypeChanged(lastgametype); forceresetplayers = true; }