diff --git a/.gitattributes b/.gitattributes index 777bf189a..ef775b912 100644 --- a/.gitattributes +++ b/.gitattributes @@ -29,4 +29,6 @@ /libs/zlib/nintendods/README -whitespace /libs/zlib/watcom/watcom_f.mak -crlf -whitespace /libs/zlib/watcom/watcom_l.mak -crlf -whitespace +#Appveyor +/appveyor.yml -crlf -whitespace # Other diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..c652584f8 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,33 @@ +language: c +sudo: required +dist: trusty + +env: +- CFLAGS=-Wno-absolute-value -Werror + +compiler: + - gcc + - clang + +cache: + directories: + - $HOME/srb2_cache + +addons: + apt: + packages: + - libsdl2-mixer-dev + - libpng-dev + - libgl1-mesa-dev + - libgme-dev + - p7zip-full + +before_script: + - mkdir -p $HOME/srb2_cache + - wget --verbose --server-response -c http://rosenthalcastle.org/srb2/SRB2-v2114-assets.7z -O $HOME/srb2_cache/SRB2-v2114-assets.7z + - 7z x $HOME/srb2_cache/SRB2-v2114-assets.7z -oassets + - mkdir build + - cd build + - cmake .. + +script: make diff --git a/CMakeLists.txt b/CMakeLists.txt index 0fb5cb28f..cb93d22f0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,13 +23,13 @@ endfunction() # Macro to add OSX framework macro(add_framework fwname appname) find_library(FRAMEWORK_${fwname} - NAMES ${fwname} - PATHS ${CMAKE_OSX_SYSROOT}/System/Library - ${CMAKE_OSX_SYSROOT}/Library - /System/Library - /Library - PATH_SUFFIXES Frameworks - NO_DEFAULT_PATH) + NAMES ${fwname} + PATHS ${CMAKE_OSX_SYSROOT}/System/Library + ${CMAKE_OSX_SYSROOT}/Library + /System/Library + /Library + ATH_SUFFIXES Frameworks + NO_DEFAULT_PATH) if( ${FRAMEWORK_${fwname}} STREQUAL FRAMEWORK_${fwname}-NOTFOUND) MESSAGE(ERROR ": Framework ${fwname} not found") else() @@ -80,9 +80,6 @@ endif() if(${CMAKE_SYSTEM} MATCHES "Darwin") add_definitions(-DMACOSX) - if(${CMAKE_C_COMPILER_ID} MATCHES "Clang") - set(CLANG ON) - endif() endif() set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") @@ -103,7 +100,8 @@ set(GIT_EXECUTABLE "git" CACHE FILEPATH "Path to git binary") include(GitUtilities) git_describe(SRB2_GIT_DESCRIBE "${CMAKE_SOURCE_DIR}") git_current_branch(SRB2_GIT_BRANCH "${CMAKE_SOURCE_DIR}") -set(SRB2_COMP_REVISION "${SRB2_GIT_DESCRIBE}-<${SRB2_GIT_BRANCH}>") +set(SRB2_COMP_BRANCH "${SRB2_GIT_BRANCH}") +set(SRB2_COMP_REVISION "${SRB2_GIT_DESCRIBE}") configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/src/config.h) ##### PACKAGE CONFIGURATION ##### diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 000000000..4edcd7a7f --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,71 @@ +version: 2.1.14.{branch}-{build} +os: MinGW + +environment: + CC: i686-w64-mingw32-gcc + WINDRES: windres + MINGW_SDK: c:\msys64\mingw32 + SDL2_URL: http://libsdl.org/release/SDL2-devel-2.0.4-mingw.tar.gz + SDL2_ARCHIVE: SDL2-devel-2.0.4-mingw.tar + SDL2_MOVE: SDL2-2.0.4\i686-w64-mingw32 + SDL2_MIXER_URL: https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-devel-2.0.1-mingw.tar.gz + SDL2_MIXER_ARCHIVE: SDL2_mixer-devel-2.0.1-mingw.tar + SDL2_MIXER_MOVE: SDL2_mixer-2.0.1\i686-w64-mingw32 + +cache: +- SDL2-devel-2.0.4-mingw.tar.gz +- SDL2_mixer-devel-2.0.1-mingw.tar.gz + +install: +#Download SDL2 +- if not exist "%SDL2_ARCHIVE%.gz" appveyor DownloadFile "%SDL2_URL%" -FileName "%SDL2_ARCHIVE%.gz" +- 7z x -y "%SDL2_ARCHIVE%.gz" -o%TMP% >null +- 7z x -y "%TMP%\%SDL2_ARCHIVE%" -o%TMP% >null +- robocopy /S /xx /ns /nc /nfl /ndl /np /njh /njs %TMP%\%SDL2_MOVE% %MINGW_SDK% || exit 0 +- ps: (Get-Content ([System.Environment]::ExpandEnvironmentVariables("%TMP%\%SDL2_MOVE%\bin\sdl2-config"))) | ForEach-Object { $_ -replace "/usr/local/cross-tools/i686-w64-mingw32", ([System.Environment]::ExpandEnvironmentVariables("%MINGW_SDK%")) } | Set-Content ([System.Environment]::ExpandEnvironmentVariables("%MINGW_SDK%\bin\sdl2-config")) +- ps: (Get-Content ([System.Environment]::ExpandEnvironmentVariables("%TMP%\%SDL2_MOVE%\lib\cmake\SDL2\sdl2-config.cmake"))) | ForEach-Object { $_ -replace "/usr/local/cross-tools/i686-w64-mingw32", ([System.Environment]::ExpandEnvironmentVariables("%MINGW_SDK%")) } | Set-Content ([System.Environment]::ExpandEnvironmentVariables("%MINGW_SDK%\lib\cmake\SDL2\sdl2-config.cmake")) +- ps: (Get-Content ([System.Environment]::ExpandEnvironmentVariables("%TMP%\%SDL2_MOVE%\lib\pkgconfig\sdl2.pc"))) | ForEach-Object { $_ -replace "/usr/local/cross-tools/i686-w64-mingw32", ([System.Environment]::ExpandEnvironmentVariables("%MINGW_SDK%")) } | Set-Content ([System.Environment]::ExpandEnvironmentVariables("%MINGW_SDK%\lib\pkgconfig\sdl2.pc")) +#Download SDL2_Mixer +- if not exist "%SDL2_MIXER_ARCHIVE%.gz" appveyor DownloadFile "%SDL2_MIXER_URL%" -FileName "%SDL2_MIXER_ARCHIVE%.gz" +- 7z x -y "%SDL2_MIXER_ARCHIVE%.gz" -o%TMP% >null +- 7z x -y "%TMP%\%SDL2_MIXER_ARCHIVE%" -o%TMP% >null +- robocopy /S /xx /ns /nc /nfl /ndl /np /njh /njs %TMP%\%SDL2_MIXER_MOVE% %MINGW_SDK% || exit 0 +- ps: (Get-Content ([System.Environment]::ExpandEnvironmentVariables("%TMP%\%SDL2_MIXER_MOVE%\lib\pkgconfig\SDL2_mixer.pc")))| ForEach-Object { $_ -replace "/usr/local/cross-tools/i686-w64-mingw32", ([System.Environment]::ExpandEnvironmentVariables("%MINGW_SDK%")) } | Set-Content ([System.Environment]::ExpandEnvironmentVariables("%MINGW_SDK%\lib\pkgconfig\SDL2_mixer.pc")) + +before_build: +- set SDL_PKGCONFIG=%MINGW_SDK%\lib\pkgconfig\sdl2.pc +- set Path=%MINGW_SDK%\bin;%Path% +- i686-w64-mingw32-gcc --version +- mingw32-make --version +- set SRB2_MFLAGS=-C src MINGW=1 WARNINGMODE=1 NOASM=1 NOUPX=1 GCC53=1 + +build_script: +- cmd: mingw32-make.exe %SRB2_MFLAGS% SDL=1 clean +- cmd: mingw32-make.exe %SRB2_MFLAGS% SDL=1 ERRORMODE=1 + +after_build: +- cmd: git rev-parse --short %APPVEYOR_REPO_COMMIT%>%TMP%/gitshort.txt +- cmd: set /P GITSHORT=<%TMP%/gitshort.txt +- set BUILD_ARCHIVE=%APPVEYOR_REPO_BRANCH%-%GITSHORT%.7z +- cmd: 7z a %BUILD_ARCHIVE% bin\Mingw\Release -xr!.gitignore +- appveyor PushArtifact %BUILD_ARCHIVE% + +test: off + +deploy: + - provider: FTP + protocol: ftps + host: + secure: NsLJEPIBvmwCOj8Tg8RoRQ== + username: + secure: ejxi5mvk7oLYu7QtbYojajEPigMy0mokaKhuEVuDZcA= + password: + secure: Hbn6Uy3lT0YZ88yFJ3aW4w== + folder: appveyor + application: + active_mode: false + + +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')) diff --git a/bin/Resources/debian/README.Debian b/assets/debian/README.Debian similarity index 100% rename from bin/Resources/debian/README.Debian rename to assets/debian/README.Debian diff --git a/bin/Resources/debian/README.source b/assets/debian/README.source similarity index 100% rename from bin/Resources/debian/README.source rename to assets/debian/README.source diff --git a/assets/debian/changelog b/assets/debian/changelog new file mode 100644 index 000000000..a316b7df7 --- /dev/null +++ b/assets/debian/changelog @@ -0,0 +1,12 @@ +srb2-data (2.1.14~1) unstable; urgency=low + + * Updated for SRB2 v2.1.14 + + -- Alam Arias Sat, 6 Jan 2016 11:00:00 -0500 + + +srb2-data (2.0.6-2) maverick; urgency=high + + * Initial proper release.. + + -- Callum Dickinson Sat, 29 Jan 2011 01:18:42 +1300 diff --git a/bin/Resources/debian/compat b/assets/debian/compat similarity index 100% rename from bin/Resources/debian/compat rename to assets/debian/compat diff --git a/bin/Resources/debian/control b/assets/debian/control similarity index 100% rename from bin/Resources/debian/control rename to assets/debian/control diff --git a/bin/Resources/debian/copyright b/assets/debian/copyright similarity index 100% rename from bin/Resources/debian/copyright rename to assets/debian/copyright diff --git a/bin/Resources/debian/rules b/assets/debian/rules similarity index 95% rename from bin/Resources/debian/rules rename to assets/debian/rules index 514d8e07c..d86f92af2 100755 --- a/bin/Resources/debian/rules +++ b/assets/debian/rules @@ -37,7 +37,7 @@ RM := rm -rf DIR := $(shell pwd) PACKAGE := $(shell cat $(DIR)/debian/control | grep 'Package:' | sed -e 's/Package: //g') -DATAFILES := drill.dta music.dta soar.dta zones.dta player.dta rings.wpn srb2.wad +DATAFILES := srb2.srb zones.dta player.dta rings.dta music.dta DATADIR := usr/games/SRB2 RESOURCEDIR := . @@ -48,7 +48,7 @@ build: # This will need to be updated every time SRB2 official version is # Copy data files to their install locations, and add data files to include-binaries for file in $(DATAFILES); do \ - $(WGET) http://alam.srb2.org/SRB2/2.0.6-Final/Resources/$$file; \ + $(WGET) http://alam.srb2.org/SRB2/2.1.14-Final/Resources/$$file; \ if test "$$file" = "srb2.wad"; then \ $(INSTALL) $(RESOURCEDIR)/$$file $(DIR)/debian/tmp/$(DATADIR)/srb2.srb; \ else \ diff --git a/assets/debian/source/format b/assets/debian/source/format new file mode 100644 index 000000000..89ae9db8f --- /dev/null +++ b/assets/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/bin/Resources/debian/changelog b/bin/Resources/debian/changelog deleted file mode 100644 index 0c514d4d2..000000000 --- a/bin/Resources/debian/changelog +++ /dev/null @@ -1,5 +0,0 @@ -srb2-data (2.0.6-2) maverick; urgency=high - - * Initial proper release.. - - -- Callum Dickinson Sat, 29 Jan 2011 01:18:42 +1300 diff --git a/bin/Resources/debian/source/format b/bin/Resources/debian/source/format deleted file mode 100644 index 163aaf8d8..000000000 --- a/bin/Resources/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (quilt) diff --git a/cmake/Modules/FindSDL2.cmake b/cmake/Modules/FindSDL2.cmake index 9e789e19c..2fc833cef 100644 --- a/cmake/Modules/FindSDL2.cmake +++ b/cmake/Modules/FindSDL2.cmake @@ -1,6 +1,6 @@ # Find SDL2 # Once done, this will define -# +# # SDL2_FOUND - system has SDL2 # SDL2_INCLUDE_DIRS - SDL2 include directories # SDL2_LIBRARIES - link libraries diff --git a/cmake/Modules/FindSDL2_main.cmake b/cmake/Modules/FindSDL2_main.cmake index 280e51e2e..d4cbdeb11 100644 --- a/cmake/Modules/FindSDL2_main.cmake +++ b/cmake/Modules/FindSDL2_main.cmake @@ -1,6 +1,6 @@ # Find SDL2 # Once done, this will define -# +# # SDL2_MAIN_FOUND - system has SDL2 # SDL2_MAIN_INCLUDE_DIRS - SDL2 include directories # SDL2_MAIN_LIBRARIES - link libraries diff --git a/cmake/Modules/FindSDL2_mixer.cmake b/cmake/Modules/FindSDL2_mixer.cmake index 59b4823ed..9af3e26dd 100644 --- a/cmake/Modules/FindSDL2_mixer.cmake +++ b/cmake/Modules/FindSDL2_mixer.cmake @@ -1,6 +1,6 @@ # Find SDL2 # Once done, this will define -# +# # SDL2_MIXER_FOUND - system has SDL2 # SDL2_MIXER_INCLUDE_DIRS - SDL2 include directories # SDL2_MIXER_LIBRARIES - link libraries diff --git a/cmake/Modules/LibFindMacros.cmake b/cmake/Modules/LibFindMacros.cmake index f6800aa7b..81fef7d8e 100644 --- a/cmake/Modules/LibFindMacros.cmake +++ b/cmake/Modules/LibFindMacros.cmake @@ -123,7 +123,7 @@ function (libfind_process PREFIX) set(includeopts ${${PREFIX}_PROCESS_INCLUDES}) set(libraryopts ${${PREFIX}_PROCESS_LIBS}) - # Process deps to add to + # Process deps to add to foreach (i ${PREFIX} ${${PREFIX}_DEPENDENCIES}) if (DEFINED ${i}_INCLUDE_OPTS OR DEFINED ${i}_LIBRARY_OPTS) # The package seems to export option lists that we can use, woohoo! @@ -146,11 +146,11 @@ function (libfind_process PREFIX) endif() endif() endforeach() - + if (includeopts) list(REMOVE_DUPLICATES includeopts) endif() - + if (libraryopts) list(REMOVE_DUPLICATES libraryopts) endif() @@ -215,7 +215,7 @@ function (libfind_process PREFIX) set (${PREFIX}_LIBRARIES ${libs} PARENT_SCOPE) set (${PREFIX}_FOUND TRUE PARENT_SCOPE) endif() - return() + return() endif() # Format messages for debug info and the type of error diff --git a/comptime.bat b/comptime.bat index 23ee7ea55..9e127f001 100644 --- a/comptime.bat +++ b/comptime.bat @@ -1,10 +1,32 @@ @ECHO OFF -set REV=Unknown +set BRA=Unknown +set REV=illegal + copy nul: /b +%1\comptime.c tmp.$$$ > nul move tmp.$$$ %1\comptime.c > nul -SET REV=illegal -FOR /F "usebackq" %%s IN (`svnversion %1`) DO @SET REV=%%s + +if exist .git goto gitrev +if exist ..\.git goto gitrev +if exist .svn goto svnrev +goto filwri + +:gitrev +set GIT=%2 +if "%GIT%"=="" set GIT=git +FOR /F "usebackq" %%s IN (`%GIT% rev-parse --abbrev-ref HEAD`) DO @SET BRA=%%s +FOR /F "usebackq" %%s IN (`%GIT% rev-parse HEAD`) DO @SET REV=%%s +set REV=%REV:~0,8% +goto filwri + +:svnrev +set BRA=Subversion +FOR /F "usebackq" %%s IN (`svnversion .`) DO @SET REV=%%s +set REV=r%REV% +goto filwri + +:filwri ECHO // Do not edit! This file was autogenerated > %1\comptime.h ECHO // by the %0 batch file >> %1\comptime.h ECHO // >> %1\comptime.h -ECHO const char* comprevision = "r%REV%"; >> %1\comptime.h +ECHO const char* compbranch = "%BRA%"; >> %1\comptime.h +ECHO const char* comprevision = "%REV%"; >> %1\comptime.h diff --git a/comptime.sh b/comptime.sh index 703bb2d35..71c5f08aa 100755 --- a/comptime.sh +++ b/comptime.sh @@ -5,13 +5,15 @@ if [ x"$1" != x ]; then fi versiongit() { - gitversion=`git describe` + gitbranch=`git rev-parse --abbrev-ref HEAD` + gitversion=`git rev-parse HEAD` cat < $path/comptime.h // Do not edit! This file was autogenerated -// by the $0 script with git svn +// by the $0 script with git // -const char* comprevision = "$gitversion"; +const char* compbranch = "$gitbranch"; +const char* comprevision = "${gitversion:0:8}"; EOF exit 0 } @@ -23,6 +25,7 @@ versionsvn() { // Do not edit! This file was autogenerated // by the $0 script with subversion // +const char* compbranch = "Subversion"; const char* comprevision = "r$svnrevision"; EOF exit 0 @@ -34,6 +37,7 @@ versionfake() { // Do not edit! This file was autogenerated // by the $0 script with an unknown or nonexist SCM // +const char* compbranch = "Unknown"; const char* comprevision = "illegal"; EOF } diff --git a/debian/control b/debian/control index c64a85c48..63b075f17 100644 --- a/debian/control +++ b/debian/control @@ -4,13 +4,19 @@ Source: srb2 Section: games Priority: extra Maintainer: Callum Dickinson -Build-Depends: debhelper (>= 7.0.50~), libsdl1.2-dev (>= 1.2.7), libsdl-mixer1.2-dev (>= 1.2.7), libpng12-dev (>= 1.2.7), libglu1-dev | libglu-dev, libosmesa6-dev | libgl-dev, nasm [i386] +Build-Depends: debhelper (>= 7.0.50~), + libsdl2-dev, + libsdl2-mixer-dev, + libpng12-dev (>= 1.2.7), + libglu1-dev | libglu-dev, + libosmesa6-dev | libgl-dev, + nasm [i386] Standards-Version: 3.8.4 Homepage: http://www.srb2.org Package: srb2 Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, srb2-data (= 2.0.6) +Depends: ${shlibs:Depends}, ${misc:Depends}, srb2-data (= 2.1.14) Description: A cross-platform 3D Sonic fangame Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog fangame built using a modified version of the Doom Legacy @@ -22,8 +28,8 @@ Description: A cross-platform 3D Sonic fangame Package: srb2-dbg Architecture: any -# FIXME: should be Depends: ${shlibs:Depends}, ${misc:Depends}, srb2-data (= 2.0.6), srb2 but dh_shlibdeps is being an asshat -Depends: libc6, ${misc:Depends}, srb2-data (= 2.0.6), srb2 +# FIXME: should be Depends: ${shlibs:Depends}, ${misc:Depends}, srb2-data (= 2.1.14), srb2 but dh_shlibdeps is being an asshat +Depends: libc6, ${misc:Depends}, srb2-data (= 2.1.14), srb2 Description: A cross-platform 3D Sonic fangame Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog fangame built using a modified version of the Doom Legacy diff --git a/debian/rules b/debian/rules index 33ade54c8..e49784a0f 100755 --- a/debian/rules +++ b/debian/rules @@ -59,16 +59,18 @@ DBGNAME = debug/$(EXENAME) PKGDIR = usr/games DBGDIR = usr/lib/debug/$(PKGDIR) +PIXMAPS_DIR = usr/share/pixmaps +DESKTOP_DIR = usr/share/applications PREFIX = $(shell test "$(CROSS_COMPILE_BUILD)" != "$(CROSS_COMPILE_HOST)" && echo "PREFIX=$(CROSS_COMPILE_HOST)") OS = LINUX=1 NONX86 = $(shell test "`echo $(CROSS_COMPILE_HOST) | grep 'i[3-6]86'`" || echo "NONX86=1") -MAKEARGS = $(OS) $(NONX86) $(PREFIX) EXENAME=$(EXENAME) DBGNAME=$(DBGNAME) SDL_PKGCONFIG=sdl PNG_PKGCONFIG=libpng NOOBJDUMP=1 +MAKEARGS = $(OS) $(NONX86) $(PREFIX) EXENAME=$(EXENAME) DBGNAME=$(DBGNAME) SDL_PKGCONFIG=sdl2 PNG_PKGCONFIG=libpng NOOBJDUMP=1 MENUFILE1 = ?package($(PACKAGE)):needs="X11" section="$(SECTION)" MENUFILE2 = title="$(TITLE)" command="/$(PKGDIR)/$(PACKAGE)" # FIXME pkg-config dir hacks -export PKG_CONFIG_LIBDIR = /usr/$(CROSS_COMPILE_HOST)/lib/pkgconfig +export PKG_CONFIG_LIBDIR = /usr/lib/$(CROSS_COMPILE_HOST)/pkgconfig BINDIR := $(DIR)/bin/Linux/Release -LDFLAGS += "-Wl,-rpath=/usr/$(CROSS_COMPILE_HOST)/lib/" +LDFLAGS += "-Wl,-rpath=/usr/lib/$(CROSS_COMPILE_HOST)" build: $(MKDIR) $(BINDIR)/debug @@ -80,14 +82,23 @@ binary-indep: echo "no need to do any arch-independent stuff" binary-arch: + # create ddirs $(MKDIR) $(DIR)/debian/tmp/$(PKGDIR) $(DIR)/debian/tmp/$(DBGDIR) + $(MKDIR) $(DIR)/debian/tmp/$(PKGDIR) $(DIR)/debian/tmp/$(DESKTOP_DIR) + $(MKDIR) $(DIR)/debian/tmp/$(PKGDIR) $(DIR)/debian/tmp/$(PIXMAPS_DIR) + # install main binaries $(INSTALL) $(BINDIR)/$(EXENAME) $(DIR)/debian/tmp/$(PKGDIR)/$(PACKAGE) $(INSTALL) $(BINDIR)/$(DBGNAME) $(DIR)/debian/tmp/$(DBGDIR)/$(PACKAGE) + # Install desktop file and banner image + $(INSTALL) $(DIR)/srb2.png $(DIR)/debian/tmp/usr/share/pixmaps + $(INSTALL) $(DIR)/debian/srb2.desktop $(DIR)/debian/tmp/usr/share/applications # add compiled binaries to include-binaries echo $(BINDIR)/$(EXENAME) >> $(DIR)/debian/source/include-binaries echo $(BINDIR)/$(EXENAME) >> $(DIR)/debian/source/include-binaries # Generate install folder files echo $(PKGDIR) > $(DIR)/debian/$(PACKAGE).install + echo $(DESKTOP_DIR) >> $(DIR)/debian/$(PACKAGE).install + echo $(PIXMAPS_DIR) >> $(DIR)/debian/$(PACKAGE).install echo $(DBGDIR) > $(DIR)/debian/$(DBGPKG).install binary: binary-arch diff --git a/debian/srb2.desktop b/debian/srb2.desktop new file mode 100644 index 000000000..661832b93 --- /dev/null +++ b/debian/srb2.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Name=Sonic Robo Blast 2 +Comment=A free 3D Sonic the Hedgehog fan-game built using a modified ver. of the Doom Legacy source port +Encoding=UTF-8 +Exec=srb2 +Icon=/usr/share/pixmaps/srb2.png +Terminal=false +Type=Application +StartupNotify=false +Categories=Application;Game; diff --git a/srb2.png b/srb2.png new file mode 100644 index 000000000..9c13eae9a Binary files /dev/null and b/srb2.png differ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6859e27c3..54a08ea0b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -150,6 +150,7 @@ set(SRB2_CORE_GAME_SOURCES p_saveg.c p_setup.c p_sight.c + p_slopes.c p_spec.c p_telept.c p_tick.c @@ -162,11 +163,12 @@ set(SRB2_CORE_GAME_SOURCES p_pspr.h p_saveg.h p_setup.h + p_slopes.h p_spec.h p_tick.h ) -if(NOT CLANG) +if(NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang")) set(SRB2_CORE_SOURCES ${SRB2_CORE_SOURCES} string.c) endif() @@ -404,10 +406,14 @@ endif() # Compatibility flag with later versions of GCC # We should really fix our code to not need this -if(NOT CLANG AND NOT MSVC) +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -mno-ms-bitfields) endif() +if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -Wno-absolute-value) +endif() + add_definitions(-DCMAKECONFIG) #add_library(SRB2Core STATIC @@ -429,4 +435,4 @@ endif() if(NOT ${SRB2_SDL2_AVAILABLE} AND NOT ${SRB2_WIN32_AVAILABLE}) message(FATAL_ERROR "There are no targets available to build an SRB2 executable. :(") -endif() \ No newline at end of file +endif() diff --git a/src/Makefile b/src/Makefile index d4cc64a4b..bee608047 100644 --- a/src/Makefile +++ b/src/Makefile @@ -454,6 +454,7 @@ OBJS:=$(i_main_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 \ diff --git a/src/Makefile.cfg b/src/Makefile.cfg index 1ea96df92..fa8896a7c 100644 --- a/src/Makefile.cfg +++ b/src/Makefile.cfg @@ -7,6 +7,22 @@ # and other things # +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 @@ -139,6 +155,10 @@ WFLAGS+=-Wformat-security ifndef GCC29 #WFLAGS+=-Winit-self endif +ifdef GCC46 +WFLAGS+=-Wno-suggest-attribute=noreturn +endif + ifndef MINGW ifdef GCC45 WFLAGS+=-Wunsuffixed-float-constants @@ -155,6 +175,7 @@ ifdef GCC43 endif WFLAGS+=$(OLDWFLAGS) + #indicate platform and what interface use with ifndef WINCE ifndef XBOX diff --git a/src/b_bot.c b/src/b_bot.c index 0636d9366..7f55b50b1 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -49,7 +49,7 @@ static inline void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cm if (sonic->player->pflags & (PF_MACESPIN|PF_ITEMHANG)) { cmd->forwardmove = sonic->player->cmd.forwardmove; - cmd->angleturn = abs(tails->angle - sonic->angle)>>16; + cmd->angleturn = abs((tails->angle - sonic->angle))>>16; if (sonic->angle < tails->angle) cmd->angleturn = -cmd->angleturn; } else if (dist > FixedMul(512*FRACUNIT, tails->scale)) diff --git a/src/comptime.c b/src/comptime.c index a4dc5b0f9..398eda074 100644 --- a/src/comptime.c +++ b/src/comptime.c @@ -9,12 +9,14 @@ #if (defined(CMAKECONFIG)) #include "config.h" +const char *compbranch = SRB2_COMP_BRANCH; const char *comprevision = SRB2_COMP_REVISION; #elif (defined(COMPVERSION)) #include "comptime.h" #else +const char *compbranch = "Unknown"; const char *comprevision = "illegal"; #endif diff --git a/src/config.h.in b/src/config.h.in index 2ed7aec3e..5cd75fa5a 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -18,6 +18,7 @@ #define ASSET_HASH_PATCH_DTA "${SRB2_ASSET_patch.dta_HASH}" #define SRB2_COMP_REVISION "${SRB2_COMP_REVISION}" +#define SRB2_COMP_BRANCH "${SRB2_COMP_BRANCH}" #define SRB2_GIT_DESCRIBE "${SRB2_GIT_DESCRIBE}" #define SRB2_GIT_BRANCH "${SRB2_GIT_BRANCH}" diff --git a/src/console.c b/src/console.c index e77c400b3..a07aeea39 100644 --- a/src/console.c +++ b/src/console.c @@ -202,7 +202,7 @@ static void CONS_Bind_f(void) } key = G_KeyStringtoNum(COM_Argv(1)); - if (!key) + if (key <= 0 || key >= NUMINPUTS) { CONS_Alert(CONS_NOTICE, M_GetText("Invalid key name\n")); return; @@ -248,11 +248,11 @@ void CON_ReSetupBackColormap(UINT16 num) { j = pal[i] + pal[i+1] + pal[i+2]; cwhitemap[k] = (UINT8)(15 - (j>>6)); - corangemap[k] = (UINT8)(95 - (j>>6)); - cbluemap[k] = (UINT8)(239 - (j>>6)); - cgreenmap[k] = (UINT8)(175 - (j>>6)); + corangemap[k] = (UINT8)(63 - (j>>6)); + cbluemap[k] = (UINT8)(159 - (j>>6)); + cgreenmap[k] = (UINT8)(111 - (j>>6)); cgraymap[k] = (UINT8)(31 - (j>>6)); - credmap[k] = (UINT8)(143 - (j>>6)); + credmap[k] = (UINT8)(47 - (j>>6)); } } @@ -283,11 +283,11 @@ static void CON_SetupBackColormap(void) { j = pal[i] + pal[i+1] + pal[i+2]; cwhitemap[k] = (UINT8)(15 - (j>>6)); - corangemap[k] = (UINT8)(95 - (j>>6)); - cbluemap[k] = (UINT8)(239 - (j>>6)); - cgreenmap[k] = (UINT8)(175 - (j>>6)); + corangemap[k] = (UINT8)(63 - (j>>6)); + cbluemap[k] = (UINT8)(159 - (j>>6)); + cgreenmap[k] = (UINT8)(111 - (j>>6)); cgraymap[k] = (UINT8)(31 - (j>>6)); - credmap[k] = (UINT8)(143 - (j>>6)); + credmap[k] = (UINT8)(47 - (j>>6)); } // setup the other colormaps, for console text @@ -306,20 +306,20 @@ static void CON_SetupBackColormap(void) orangemap[i] = (UINT8)i; } - yellowmap[3] = (UINT8)103; - yellowmap[9] = (UINT8)115; - purplemap[3] = (UINT8)195; - purplemap[9] = (UINT8)198; - lgreenmap[3] = (UINT8)162; - lgreenmap[9] = (UINT8)170; - bluemap[3] = (UINT8)228; - bluemap[9] = (UINT8)238; + yellowmap[3] = (UINT8)73; + yellowmap[9] = (UINT8)66; + purplemap[3] = (UINT8)184; + purplemap[9] = (UINT8)186; + lgreenmap[3] = (UINT8)98; + lgreenmap[9] = (UINT8)106; + bluemap[3] = (UINT8)147; + bluemap[9] = (UINT8)158; graymap[3] = (UINT8)10; graymap[9] = (UINT8)15; - redmap[3] = (UINT8)124; - redmap[9] = (UINT8)127; - orangemap[3] = (UINT8)85; - orangemap[9] = (UINT8)90; + redmap[3] = (UINT8)210; + redmap[9] = (UINT8)32; + orangemap[3] = (UINT8)52; + orangemap[9] = (UINT8)57; } // Setup the console text buffer diff --git a/src/d_clisrv.c b/src/d_clisrv.c index d08badd4a..4af0f32c2 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1100,7 +1100,7 @@ static inline void CL_DrawConnectionStatus(void) if (cl_mode != cl_downloadfiles) { INT32 i, animtime = ((ccstime / 4) & 15) + 16; - UINT8 palstart = (cl_mode == cl_searching) ? 128 : 160; + UINT8 palstart = (cl_mode == cl_searching) ? 32 : 96; // 15 pal entries total. const char *cltext; @@ -1138,8 +1138,8 @@ static inline void CL_DrawConnectionStatus(void) dldlength = (INT32)((fileneeded[lastfilenum].currentsize/(double)fileneeded[lastfilenum].totalsize) * 256); if (dldlength > 256) dldlength = 256; - V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, 256, 8, 175); - V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, dldlength, 8, 160); + V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, 256, 8, 111); + V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, dldlength, 8, 96); memset(tempname, 0, sizeof(tempname)); nameonly(strncpy(tempname, fileneeded[lastfilenum].filename, 31)); diff --git a/src/d_main.c b/src/d_main.c index 3918d8118..c5f0d0b39 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1129,10 +1129,10 @@ void D_SRB2Main(void) #ifndef DEVELOP // md5s last updated 12/14/14 // Check MD5s of autoloaded files - W_VerifyFileMD5(0, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad - W_VerifyFileMD5(1, ASSET_HASH_ZONES_DTA); // zones.dta - W_VerifyFileMD5(2, ASSET_HASH_PLAYER_DTA); // player.dta - W_VerifyFileMD5(3, ASSET_HASH_RINGS_DTA); // rings.dta + //W_VerifyFileMD5(0, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad + //W_VerifyFileMD5(1, ASSET_HASH_ZONES_DTA); // zones.dta + //W_VerifyFileMD5(2, ASSET_HASH_PLAYER_DTA); // player.dta + //W_VerifyFileMD5(3, ASSET_HASH_RINGS_DTA); // rings.dta //W_VerifyFileMD5(4, "0c66790502e648bfce90fdc5bb15722e"); // patch.dta // don't check music.dta because people like to modify it, and it doesn't matter if they do // ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for. diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 537588e4b..b0f77c546 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1854,10 +1854,10 @@ static void Got_Pause(UINT8 **cp, INT32 playernum) if (paused) { if (!menuactive || netgame) - S_PauseSound(); + S_PauseAudio(); } else - S_ResumeSound(); + S_ResumeAudio(); } } @@ -3179,7 +3179,11 @@ static void Command_ListWADS_f(void) */ static void Command_Version_f(void) { +#ifdef DEVELOP + CONS_Printf("Sonic Robo Blast 2 %s-%s (%s %s)\n", compbranch, comprevision, compdate, comptime); +#else CONS_Printf("Sonic Robo Blast 2 %s (%s %s %s)\n", VERSIONSTRING, compdate, comptime, comprevision); +#endif } #ifdef UPDATE_ALERT @@ -3757,50 +3761,66 @@ static void Command_Displayplayer_f(void) static void Command_Tunes_f(void) { const char *tunearg; - UINT16 tune, track = 0; + UINT16 tunenum, track = 0; const size_t argc = COM_Argc(); if (argc < 2) //tunes slot ... { - CONS_Printf("tunes :\n"); - CONS_Printf(M_GetText("Play a music slot at a set speed (\"1\" being normal speed).\n")); - CONS_Printf(M_GetText("If the format supports multiple songs, you can specify which one to play.\n")); - CONS_Printf(M_GetText("The current tune is: %d\nThe current track is: %d\n"), - (mapmusic & MUSIC_SONGMASK), ((mapmusic & MUSIC_TRACKMASK) >> MUSIC_TRACKSHIFT)); + CONS_Printf("tunes [track] [speed] / <-show> / <-default> / <-none>:\n"); + CONS_Printf(M_GetText("Play an arbitrary music lump. If a map number is used, 'MAP##M' is played.\n")); + CONS_Printf(M_GetText("If the format supports multiple songs, you can specify which one to play.\n\n")); + CONS_Printf(M_GetText("* With \"-show\", shows the currently playing tune and track.\n")); + CONS_Printf(M_GetText("* With \"-default\", returns to the default music for the map.\n")); + CONS_Printf(M_GetText("* With \"-none\", any music playing will be stopped.\n")); return; } tunearg = COM_Argv(1); - tune = (UINT16)atoi(tunearg); + tunenum = (UINT16)atoi(tunearg); track = 0; - if (!strcasecmp(tunearg, "default")) + if (!strcasecmp(tunearg, "-show")) { - tune = mapheaderinfo[gamemap-1]->musicslot; - track = mapheaderinfo[gamemap-1]->musicslottrack; - } - else if (toupper(tunearg[0]) >= 'A' && toupper(tunearg[0]) <= 'Z') - tune = (UINT16)M_MapNumber(tunearg[0], tunearg[1]); - - if (tune >= NUMMUSIC) - { - CONS_Alert(CONS_NOTICE, M_GetText("Valid slots are 1 to %d, or 0 to stop music\n"), NUMMUSIC - 1); + CONS_Printf(M_GetText("The current tune is: %s [track %d]\n"), + mapmusname, (mapmusflags & MUSIC_TRACKMASK)); return; } - - if (argc > 3) - track = (UINT16)atoi(COM_Argv(3))-1; - - mapmusic = tune | (track << MUSIC_TRACKSHIFT); - - if (tune == mus_None) + if (!strcasecmp(tunearg, "-none")) + { S_StopMusic(); - else - S_ChangeMusic(mapmusic, true); + return; + } + else if (!strcasecmp(tunearg, "-default")) + { + tunearg = mapheaderinfo[gamemap-1]->musname; + track = mapheaderinfo[gamemap-1]->mustrack; + } + else if (!tunearg[2] && toupper(tunearg[0]) >= 'A' && toupper(tunearg[0]) <= 'Z') + tunenum = (UINT16)M_MapNumber(tunearg[0], tunearg[1]); + + if (tunenum && tunenum >= 1036) + { + CONS_Alert(CONS_NOTICE, M_GetText("Valid music slots are 1 to 1035.\n")); + return; + } + if (!tunenum && strlen(tunearg) > 6) // This is automatic -- just show the error just in case + CONS_Alert(CONS_NOTICE, M_GetText("Music name too long - truncated to six characters.\n")); if (argc > 2) + track = (UINT16)atoi(COM_Argv(2))-1; + + if (tunenum) + snprintf(mapmusname, 7, "%sM", G_BuildMapName(tunenum)); + else + strncpy(mapmusname, tunearg, 7); + mapmusname[6] = 0; + mapmusflags = (track & MUSIC_TRACKMASK); + + S_ChangeMusic(mapmusname, mapmusflags, true); + + if (argc > 3) { - float speed = (float)atof(COM_Argv(2)); + float speed = (float)atof(COM_Argv(3)); if (speed > 0.0f) S_SpeedMusic(speed); } diff --git a/src/d_player.h b/src/d_player.h index 8c3df4883..e7d9dcce9 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -166,7 +166,7 @@ typedef enum PA_RUN, PA_PAIN, PA_ROLL, - PA_JUMP, + PA_SPRING, PA_FALL, PA_ABILITY, PA_RIDE diff --git a/src/dehacked.c b/src/dehacked.c index 0ba054f07..6747f2c59 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -65,7 +65,9 @@ static mobjtype_t get_mobjtype(const char *word); static statenum_t get_state(const char *word); static spritenum_t get_sprite(const char *word); static sfxenum_t get_sfx(const char *word); -static UINT16 get_mus(const char *word); +#ifdef MUSICSLOT_COMPATIBILITY +static UINT16 get_mus(const char *word, UINT8 dehacked_mode); +#endif static hudnum_t get_huditem(const char *word); #ifndef HAVE_BLUA static powertype_t get_power(const char *word); @@ -1132,6 +1134,10 @@ static void readlevelheader(MYFILE *f, INT32 num) } else if (fastcmp(word, "NEXTLEVEL")) { + if (fastcmp(word2, "TITLE")) i = 1100; + else if (fastcmp(word2, "EVALUATION")) i = 1101; + else if (fastcmp(word2, "CREDITS")) i = 1102; + else // Support using the actual map name, // i.e., Nextlevel = AB, Nextlevel = FZ, etc. @@ -1160,19 +1166,31 @@ static void readlevelheader(MYFILE *f, INT32 num) mapheaderinfo[num-1]->typeoflevel = tol; } } + else if (fastcmp(word, "MUSIC")) + { + if (fastcmp(word2, "NONE")) + mapheaderinfo[num-1]->musname[0] = 0; // becomes empty string + else + { + deh_strlcpy(mapheaderinfo[num-1]->musname, word2, + sizeof(mapheaderinfo[num-1]->musname), va("Level header %d: music", num)); + } + } +#ifdef MUSICSLOT_COMPATIBILITY else if (fastcmp(word, "MUSICSLOT")) { - // Convert to map number - if (word2[0] >= 'A' && word2[0] <= 'Z' && word2[2] == '\0') - i = M_MapNumber(word2[0], word2[1]); - - if (i) // it's just a number - mapheaderinfo[num-1]->musicslot = (UINT16)i; - else // No? Okay, now we'll get technical. - mapheaderinfo[num-1]->musicslot = get_mus(word2); // accepts all of O_CHRSEL, mus_chrsel, or just plain ChrSel + i = get_mus(word2, true); + if (i && i <= 1035) + snprintf(mapheaderinfo[num-1]->musname, 7, "%sM", G_BuildMapName(i)); + else if (i && i <= 1050) + strncpy(mapheaderinfo[num-1]->musname, compat_special_music_slots[i - 1036], 7); + else + mapheaderinfo[num-1]->musname[0] = 0; // becomes empty string + mapheaderinfo[num-1]->musname[6] = 0; } - else if (fastcmp(word, "MUSICSLOTTRACK")) - mapheaderinfo[num-1]->musicslottrack = ((UINT16)i - 1); +#endif + else if (fastcmp(word, "MUSICTRACK")) + mapheaderinfo[num-1]->mustrack = ((UINT16)i - 1); else if (fastcmp(word, "FORCECHARACTER")) { strlcpy(mapheaderinfo[num-1]->forcecharacter, word2, SKINNAMESIZE+1); @@ -1439,10 +1457,30 @@ static void readcutscenescene(MYFILE *f, INT32 num, INT32 scenenum) else deh_warning("CutSceneScene %d: unknown word '%s'", num, word); } + else if (fastcmp(word, "MUSIC")) + { + DEH_WriteUndoline(word, cutscenes[num]->scene[scenenum].musswitch, UNDO_NONE); + strncpy(cutscenes[num]->scene[scenenum].musswitch, word2, 7); + cutscenes[num]->scene[scenenum].musswitch[6] = 0; + } +#ifdef MUSICSLOT_COMPATIBILITY else if (fastcmp(word, "MUSICSLOT")) { - DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].musicslot), UNDO_NONE); - cutscenes[num]->scene[scenenum].musicslot = get_mus(word2); // accepts all of O_MAP01M, mus_map01m, or just plain MAP01M + DEH_WriteUndoline(word, cutscenes[num]->scene[scenenum].musswitch, UNDO_NONE); + i = get_mus(word2, true); + if (i && i <= 1035) + snprintf(cutscenes[num]->scene[scenenum].musswitch, 7, "%sM", G_BuildMapName(i)); + else if (i && i <= 1050) + strncpy(cutscenes[num]->scene[scenenum].musswitch, compat_special_music_slots[i - 1036], 7); + else + cutscenes[num]->scene[scenenum].musswitch[0] = 0; // becomes empty string + cutscenes[num]->scene[scenenum].musswitch[6] = 0; + } +#endif + else if (fastcmp(word, "MUSICTRACK")) + { + DEH_WriteUndoline(word, va("%u", cutscenes[num]->scene[scenenum].musswitchflags), UNDO_NONE); + cutscenes[num]->scene[scenenum].musswitchflags = ((UINT16)i) & MUSIC_TRACKMASK; } else if (fastcmp(word, "MUSICLOOP")) { @@ -3183,6 +3221,12 @@ static void readwipes(MYFILE *f) else if (fastcmp(pword, "FINAL")) wipeoffset = wipe_gameend_final; } + else if (fastncmp(word, "SPECLEVEL_", 10)) + { + pword = word + 10; + if (fastcmp(pword, "TOWHITE")) + wipeoffset = wipe_speclevel_towhite; + } if (wipeoffset < 0) { @@ -3190,9 +3234,11 @@ static void readwipes(MYFILE *f) continue; } - if (value == UINT8_MAX // Cannot disable non-toblack wipes (or the level toblack wipe) - && (wipeoffset <= wipe_level_toblack || wipeoffset >= wipe_level_final)) + if (value == UINT8_MAX + && (wipeoffset <= wipe_level_toblack || wipeoffset >= wipe_speclevel_towhite)) { + // Cannot disable non-toblack wipes + // (or the level toblack wipe, or the special towhite wipe) deh_warning("Wipes: can't disable wipe of type '%s'", word); continue; } @@ -3755,6 +3801,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_PLAY_DASH", "S_PLAY_GASP", "S_PLAY_JUMP", + "S_PLAY_SPRING", "S_PLAY_FALL", "S_PLAY_EDGE", "S_PLAY_RIDE", @@ -3779,6 +3826,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_PLAY_SUPER_SPIN", "S_PLAY_SUPER_GASP", "S_PLAY_SUPER_JUMP", + "S_PLAY_SUPER_SPRING", "S_PLAY_SUPER_FALL", "S_PLAY_SUPER_EDGE", "S_PLAY_SUPER_RIDE", @@ -4580,30 +4628,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_MSSHIELD_F12", // Ring - "S_RING1", - "S_RING2", - "S_RING3", - "S_RING4", - "S_RING5", - "S_RING6", - "S_RING7", - "S_RING8", - "S_RING9", - "S_RING10", - "S_RING11", - "S_RING12", - "S_RING13", - "S_RING14", - "S_RING15", - "S_RING16", - "S_RING17", - "S_RING18", - "S_RING19", - "S_RING20", - "S_RING21", - "S_RING22", - "S_RING23", - "S_RING24", + "S_RING", // Blue Sphere for special stages "S_BLUEBALL", @@ -4619,39 +4644,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_GRAVWELLRED3", // Individual Team Rings - "S_TEAMRING1", - "S_TEAMRING2", - "S_TEAMRING3", - "S_TEAMRING4", - "S_TEAMRING5", - "S_TEAMRING6", - "S_TEAMRING7", - "S_TEAMRING8", - "S_TEAMRING9", - "S_TEAMRING10", - "S_TEAMRING11", - "S_TEAMRING12", - "S_TEAMRING13", - "S_TEAMRING14", - "S_TEAMRING15", - "S_TEAMRING16", - "S_TEAMRING17", - "S_TEAMRING18", - "S_TEAMRING19", - "S_TEAMRING20", - "S_TEAMRING21", - "S_TEAMRING22", - "S_TEAMRING23", - "S_TEAMRING24", + "S_TEAMRING", // Special Stage Token - "S_EMMY1", - "S_EMMY2", - "S_EMMY3", - "S_EMMY4", - "S_EMMY5", - "S_EMMY6", - "S_EMMY7", + "S_EMMY", // Special Stage Token "S_TOKEN", @@ -4805,40 +4801,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_SPIKED2", // Starpost - "S_STARPOST1", - "S_STARPOST2", - "S_STARPOST3", - "S_STARPOST4", - "S_STARPOST5", - "S_STARPOST6", - "S_STARPOST7", - "S_STARPOST8", - "S_STARPOST9", - "S_STARPOST10", - "S_STARPOST11", - "S_STARPOST12", - "S_STARPOST13", - "S_STARPOST14", - "S_STARPOST15", - "S_STARPOST16", - "S_STARPOST17", - "S_STARPOST18", - "S_STARPOST19", - "S_STARPOST20", - "S_STARPOST21", - "S_STARPOST22", - "S_STARPOST23", - "S_STARPOST24", - "S_STARPOST25", - "S_STARPOST26", - "S_STARPOST27", - "S_STARPOST28", - "S_STARPOST29", - "S_STARPOST30", - "S_STARPOST31", - "S_STARPOST32", - "S_STARPOST33", - "S_STARPOST34", + "S_STARPOST_IDLE", + "S_STARPOST_FLASH", + "S_STARPOST_SPIN", // Big floating mine "S_BIGMINE1", @@ -5446,38 +5411,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_PITY10", // Invincibility Sparkles - "S_IVSP1", - "S_IVSP2", - "S_IVSP3", - "S_IVSP4", - "S_IVSP5", - "S_IVSP6", - "S_IVSP7", - "S_IVSP8", - "S_IVSP9", - "S_IVSP10", - "S_IVSP11", - "S_IVSP12", - "S_IVSP13", - "S_IVSP14", - "S_IVSP15", - "S_IVSP16", - "S_IVSP17", - "S_IVSP18", - "S_IVSP19", - "S_IVSP20", - "S_IVSP21", - "S_IVSP22", - "S_IVSP23", - "S_IVSP24", - "S_IVSP25", - "S_IVSP26", - "S_IVSP27", - "S_IVSP28", - "S_IVSP29", - "S_IVSP30", - "S_IVSP31", - "S_IVSP32", + "S_IVSP", // Super Sonic Spark "S_SSPK1", @@ -5664,283 +5598,17 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_RRNG6", "S_RRNG7", - // Bounce Ring - "S_BOUNCERING1", - "S_BOUNCERING2", - "S_BOUNCERING3", - "S_BOUNCERING4", - "S_BOUNCERING5", - "S_BOUNCERING6", - "S_BOUNCERING7", - "S_BOUNCERING8", - "S_BOUNCERING9", - "S_BOUNCERING10", - "S_BOUNCERING11", - "S_BOUNCERING12", - "S_BOUNCERING13", - "S_BOUNCERING14", - "S_BOUNCERING15", - "S_BOUNCERING16", - "S_BOUNCERING17", - "S_BOUNCERING18", - "S_BOUNCERING19", - "S_BOUNCERING20", - "S_BOUNCERING21", - "S_BOUNCERING22", - "S_BOUNCERING23", - "S_BOUNCERING24", - "S_BOUNCERING25", - "S_BOUNCERING26", - "S_BOUNCERING27", - "S_BOUNCERING28", - "S_BOUNCERING29", - "S_BOUNCERING30", - "S_BOUNCERING31", - "S_BOUNCERING32", - "S_BOUNCERING33", - "S_BOUNCERING34", - "S_BOUNCERING35", - - // Rail Ring - "S_RAILRING1", - "S_RAILRING2", - "S_RAILRING3", - "S_RAILRING4", - "S_RAILRING5", - "S_RAILRING6", - "S_RAILRING7", - "S_RAILRING8", - "S_RAILRING9", - "S_RAILRING10", - "S_RAILRING11", - "S_RAILRING12", - "S_RAILRING13", - "S_RAILRING14", - "S_RAILRING15", - "S_RAILRING16", - "S_RAILRING17", - "S_RAILRING18", - "S_RAILRING19", - "S_RAILRING20", - "S_RAILRING21", - "S_RAILRING22", - "S_RAILRING23", - "S_RAILRING24", - "S_RAILRING25", - "S_RAILRING26", - "S_RAILRING27", - "S_RAILRING28", - "S_RAILRING29", - "S_RAILRING30", - "S_RAILRING31", - "S_RAILRING32", - "S_RAILRING33", - "S_RAILRING34", - "S_RAILRING35", - - // Infinity ring - "S_INFINITYRING1", - "S_INFINITYRING2", - "S_INFINITYRING3", - "S_INFINITYRING4", - "S_INFINITYRING5", - "S_INFINITYRING6", - "S_INFINITYRING7", - "S_INFINITYRING8", - "S_INFINITYRING9", - "S_INFINITYRING10", - "S_INFINITYRING11", - "S_INFINITYRING12", - "S_INFINITYRING13", - "S_INFINITYRING14", - "S_INFINITYRING15", - "S_INFINITYRING16", - "S_INFINITYRING17", - "S_INFINITYRING18", - "S_INFINITYRING19", - "S_INFINITYRING20", - "S_INFINITYRING21", - "S_INFINITYRING22", - "S_INFINITYRING23", - "S_INFINITYRING24", - "S_INFINITYRING25", - "S_INFINITYRING26", - "S_INFINITYRING27", - "S_INFINITYRING28", - "S_INFINITYRING29", - "S_INFINITYRING30", - "S_INFINITYRING31", - "S_INFINITYRING32", - "S_INFINITYRING33", - "S_INFINITYRING34", - "S_INFINITYRING35", - - // Automatic Ring - "S_AUTOMATICRING1", - "S_AUTOMATICRING2", - "S_AUTOMATICRING3", - "S_AUTOMATICRING4", - "S_AUTOMATICRING5", - "S_AUTOMATICRING6", - "S_AUTOMATICRING7", - "S_AUTOMATICRING8", - "S_AUTOMATICRING9", - "S_AUTOMATICRING10", - "S_AUTOMATICRING11", - "S_AUTOMATICRING12", - "S_AUTOMATICRING13", - "S_AUTOMATICRING14", - "S_AUTOMATICRING15", - "S_AUTOMATICRING16", - "S_AUTOMATICRING17", - "S_AUTOMATICRING18", - "S_AUTOMATICRING19", - "S_AUTOMATICRING20", - "S_AUTOMATICRING21", - "S_AUTOMATICRING22", - "S_AUTOMATICRING23", - "S_AUTOMATICRING24", - "S_AUTOMATICRING25", - "S_AUTOMATICRING26", - "S_AUTOMATICRING27", - "S_AUTOMATICRING28", - "S_AUTOMATICRING29", - "S_AUTOMATICRING30", - "S_AUTOMATICRING31", - "S_AUTOMATICRING32", - "S_AUTOMATICRING33", - "S_AUTOMATICRING34", - "S_AUTOMATICRING35", - - // Explosion Ring - "S_EXPLOSIONRING1", - "S_EXPLOSIONRING2", - "S_EXPLOSIONRING3", - "S_EXPLOSIONRING4", - "S_EXPLOSIONRING5", - "S_EXPLOSIONRING6", - "S_EXPLOSIONRING7", - "S_EXPLOSIONRING8", - "S_EXPLOSIONRING9", - "S_EXPLOSIONRING10", - "S_EXPLOSIONRING11", - "S_EXPLOSIONRING12", - "S_EXPLOSIONRING13", - "S_EXPLOSIONRING14", - "S_EXPLOSIONRING15", - "S_EXPLOSIONRING16", - "S_EXPLOSIONRING17", - "S_EXPLOSIONRING18", - "S_EXPLOSIONRING19", - "S_EXPLOSIONRING20", - "S_EXPLOSIONRING21", - "S_EXPLOSIONRING22", - "S_EXPLOSIONRING23", - "S_EXPLOSIONRING24", - "S_EXPLOSIONRING25", - "S_EXPLOSIONRING26", - "S_EXPLOSIONRING27", - "S_EXPLOSIONRING28", - "S_EXPLOSIONRING29", - "S_EXPLOSIONRING30", - "S_EXPLOSIONRING31", - "S_EXPLOSIONRING32", - "S_EXPLOSIONRING33", - "S_EXPLOSIONRING34", - "S_EXPLOSIONRING35", - - // Scatter Ring - "S_SCATTERRING1", - "S_SCATTERRING2", - "S_SCATTERRING3", - "S_SCATTERRING4", - "S_SCATTERRING5", - "S_SCATTERRING6", - "S_SCATTERRING7", - "S_SCATTERRING8", - "S_SCATTERRING9", - "S_SCATTERRING10", - "S_SCATTERRING11", - "S_SCATTERRING12", - "S_SCATTERRING13", - "S_SCATTERRING14", - "S_SCATTERRING15", - "S_SCATTERRING16", - "S_SCATTERRING17", - "S_SCATTERRING18", - "S_SCATTERRING19", - "S_SCATTERRING20", - "S_SCATTERRING21", - "S_SCATTERRING22", - "S_SCATTERRING23", - "S_SCATTERRING24", - "S_SCATTERRING25", - "S_SCATTERRING26", - "S_SCATTERRING27", - "S_SCATTERRING28", - "S_SCATTERRING29", - "S_SCATTERRING30", - "S_SCATTERRING31", - "S_SCATTERRING32", - "S_SCATTERRING33", - "S_SCATTERRING34", - "S_SCATTERRING35", - - // Grenade Ring - "S_GRENADERING1", - "S_GRENADERING2", - "S_GRENADERING3", - "S_GRENADERING4", - "S_GRENADERING5", - "S_GRENADERING6", - "S_GRENADERING7", - "S_GRENADERING8", - "S_GRENADERING9", - "S_GRENADERING10", - "S_GRENADERING11", - "S_GRENADERING12", - "S_GRENADERING13", - "S_GRENADERING14", - "S_GRENADERING15", - "S_GRENADERING16", - "S_GRENADERING17", - "S_GRENADERING18", - "S_GRENADERING19", - "S_GRENADERING20", - "S_GRENADERING21", - "S_GRENADERING22", - "S_GRENADERING23", - "S_GRENADERING24", - "S_GRENADERING25", - "S_GRENADERING26", - "S_GRENADERING27", - "S_GRENADERING28", - "S_GRENADERING29", - "S_GRENADERING30", - "S_GRENADERING31", - "S_GRENADERING32", - "S_GRENADERING33", - "S_GRENADERING34", - "S_GRENADERING35", + // Weapon Ring Ammo + "S_BOUNCERINGAMMO", + "S_RAILRINGAMMO", + "S_INFINITYRINGAMMO", + "S_AUTOMATICRINGAMMO", + "S_EXPLOSIONRINGAMMO", + "S_SCATTERRINGAMMO", + "S_GRENADERINGAMMO", // Weapon pickup - "S_BOUNCEPICKUP1", - "S_BOUNCEPICKUP2", - "S_BOUNCEPICKUP3", - "S_BOUNCEPICKUP4", - "S_BOUNCEPICKUP5", - "S_BOUNCEPICKUP6", - "S_BOUNCEPICKUP7", - "S_BOUNCEPICKUP8", - "S_BOUNCEPICKUP9", - "S_BOUNCEPICKUP10", - "S_BOUNCEPICKUP11", - "S_BOUNCEPICKUP12", - "S_BOUNCEPICKUP13", - "S_BOUNCEPICKUP14", - "S_BOUNCEPICKUP15", - "S_BOUNCEPICKUP16", - + "S_BOUNCEPICKUP", "S_BOUNCEPICKUPFADE1", "S_BOUNCEPICKUPFADE2", "S_BOUNCEPICKUPFADE3", @@ -5950,23 +5618,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_BOUNCEPICKUPFADE7", "S_BOUNCEPICKUPFADE8", - "S_RAILPICKUP1", - "S_RAILPICKUP2", - "S_RAILPICKUP3", - "S_RAILPICKUP4", - "S_RAILPICKUP5", - "S_RAILPICKUP6", - "S_RAILPICKUP7", - "S_RAILPICKUP8", - "S_RAILPICKUP9", - "S_RAILPICKUP10", - "S_RAILPICKUP11", - "S_RAILPICKUP12", - "S_RAILPICKUP13", - "S_RAILPICKUP14", - "S_RAILPICKUP15", - "S_RAILPICKUP16", - + "S_RAILPICKUP", "S_RAILPICKUPFADE1", "S_RAILPICKUPFADE2", "S_RAILPICKUPFADE3", @@ -5976,23 +5628,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_RAILPICKUPFADE7", "S_RAILPICKUPFADE8", - "S_AUTOPICKUP1", - "S_AUTOPICKUP2", - "S_AUTOPICKUP3", - "S_AUTOPICKUP4", - "S_AUTOPICKUP5", - "S_AUTOPICKUP6", - "S_AUTOPICKUP7", - "S_AUTOPICKUP8", - "S_AUTOPICKUP9", - "S_AUTOPICKUP10", - "S_AUTOPICKUP11", - "S_AUTOPICKUP12", - "S_AUTOPICKUP13", - "S_AUTOPICKUP14", - "S_AUTOPICKUP15", - "S_AUTOPICKUP16", - + "S_AUTOPICKUP", "S_AUTOPICKUPFADE1", "S_AUTOPICKUPFADE2", "S_AUTOPICKUPFADE3", @@ -6002,23 +5638,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_AUTOPICKUPFADE7", "S_AUTOPICKUPFADE8", - "S_EXPLODEPICKUP1", - "S_EXPLODEPICKUP2", - "S_EXPLODEPICKUP3", - "S_EXPLODEPICKUP4", - "S_EXPLODEPICKUP5", - "S_EXPLODEPICKUP6", - "S_EXPLODEPICKUP7", - "S_EXPLODEPICKUP8", - "S_EXPLODEPICKUP9", - "S_EXPLODEPICKUP10", - "S_EXPLODEPICKUP11", - "S_EXPLODEPICKUP12", - "S_EXPLODEPICKUP13", - "S_EXPLODEPICKUP14", - "S_EXPLODEPICKUP15", - "S_EXPLODEPICKUP16", - + "S_EXPLODEPICKUP", "S_EXPLODEPICKUPFADE1", "S_EXPLODEPICKUPFADE2", "S_EXPLODEPICKUPFADE3", @@ -6028,23 +5648,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_EXPLODEPICKUPFADE7", "S_EXPLODEPICKUPFADE8", - "S_SCATTERPICKUP1", - "S_SCATTERPICKUP2", - "S_SCATTERPICKUP3", - "S_SCATTERPICKUP4", - "S_SCATTERPICKUP5", - "S_SCATTERPICKUP6", - "S_SCATTERPICKUP7", - "S_SCATTERPICKUP8", - "S_SCATTERPICKUP9", - "S_SCATTERPICKUP10", - "S_SCATTERPICKUP11", - "S_SCATTERPICKUP12", - "S_SCATTERPICKUP13", - "S_SCATTERPICKUP14", - "S_SCATTERPICKUP15", - "S_SCATTERPICKUP16", - + "S_SCATTERPICKUP", "S_SCATTERPICKUPFADE1", "S_SCATTERPICKUPFADE2", "S_SCATTERPICKUPFADE3", @@ -6054,23 +5658,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_SCATTERPICKUPFADE7", "S_SCATTERPICKUPFADE8", - "S_GRENADEPICKUP1", - "S_GRENADEPICKUP2", - "S_GRENADEPICKUP3", - "S_GRENADEPICKUP4", - "S_GRENADEPICKUP5", - "S_GRENADEPICKUP6", - "S_GRENADEPICKUP7", - "S_GRENADEPICKUP8", - "S_GRENADEPICKUP9", - "S_GRENADEPICKUP10", - "S_GRENADEPICKUP11", - "S_GRENADEPICKUP12", - "S_GRENADEPICKUP13", - "S_GRENADEPICKUP14", - "S_GRENADEPICKUP15", - "S_GRENADEPICKUP16", - + "S_GRENADEPICKUP", "S_GRENADEPICKUPFADE1", "S_GRENADEPICKUPFADE2", "S_GRENADEPICKUPFADE3", @@ -6451,101 +6039,22 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_ROCKSPAWN", - "S_ROCKCRUMBLEA1", - "S_ROCKCRUMBLEA2", - "S_ROCKCRUMBLEA3", - "S_ROCKCRUMBLEA4", - "S_ROCKCRUMBLEA5", - - "S_ROCKCRUMBLEB1", - "S_ROCKCRUMBLEB2", - "S_ROCKCRUMBLEB3", - "S_ROCKCRUMBLEB4", - "S_ROCKCRUMBLEB5", - - "S_ROCKCRUMBLEC1", - "S_ROCKCRUMBLEC2", - "S_ROCKCRUMBLEC3", - "S_ROCKCRUMBLEC4", - "S_ROCKCRUMBLEC5", - - "S_ROCKCRUMBLED1", - "S_ROCKCRUMBLED2", - "S_ROCKCRUMBLED3", - "S_ROCKCRUMBLED4", - "S_ROCKCRUMBLED5", - - "S_ROCKCRUMBLEE1", - "S_ROCKCRUMBLEE2", - "S_ROCKCRUMBLEE3", - "S_ROCKCRUMBLEE4", - "S_ROCKCRUMBLEE5", - - "S_ROCKCRUMBLEF1", - "S_ROCKCRUMBLEF2", - "S_ROCKCRUMBLEF3", - "S_ROCKCRUMBLEF4", - "S_ROCKCRUMBLEF5", - - "S_ROCKCRUMBLEG1", - "S_ROCKCRUMBLEG2", - "S_ROCKCRUMBLEG3", - "S_ROCKCRUMBLEG4", - "S_ROCKCRUMBLEG5", - - "S_ROCKCRUMBLEH1", - "S_ROCKCRUMBLEH2", - "S_ROCKCRUMBLEH3", - "S_ROCKCRUMBLEH4", - "S_ROCKCRUMBLEH5", - - "S_ROCKCRUMBLEI1", - "S_ROCKCRUMBLEI2", - "S_ROCKCRUMBLEI3", - "S_ROCKCRUMBLEI4", - "S_ROCKCRUMBLEI5", - - "S_ROCKCRUMBLEJ1", - "S_ROCKCRUMBLEJ2", - "S_ROCKCRUMBLEJ3", - "S_ROCKCRUMBLEJ4", - "S_ROCKCRUMBLEJ5", - - "S_ROCKCRUMBLEK1", - "S_ROCKCRUMBLEK2", - "S_ROCKCRUMBLEK3", - "S_ROCKCRUMBLEK4", - "S_ROCKCRUMBLEK5", - - "S_ROCKCRUMBLEL1", - "S_ROCKCRUMBLEL2", - "S_ROCKCRUMBLEL3", - "S_ROCKCRUMBLEL4", - "S_ROCKCRUMBLEL5", - - "S_ROCKCRUMBLEM1", - "S_ROCKCRUMBLEM2", - "S_ROCKCRUMBLEM3", - "S_ROCKCRUMBLEM4", - "S_ROCKCRUMBLEM5", - - "S_ROCKCRUMBLEN1", - "S_ROCKCRUMBLEN2", - "S_ROCKCRUMBLEN3", - "S_ROCKCRUMBLEN4", - "S_ROCKCRUMBLEN5", - - "S_ROCKCRUMBLEO1", - "S_ROCKCRUMBLEO2", - "S_ROCKCRUMBLEO3", - "S_ROCKCRUMBLEO4", - "S_ROCKCRUMBLEO5", - - "S_ROCKCRUMBLEP1", - "S_ROCKCRUMBLEP2", - "S_ROCKCRUMBLEP3", - "S_ROCKCRUMBLEP4", - "S_ROCKCRUMBLEP5", + "S_ROCKCRUMBLEA", + "S_ROCKCRUMBLEB", + "S_ROCKCRUMBLEC", + "S_ROCKCRUMBLED", + "S_ROCKCRUMBLEE", + "S_ROCKCRUMBLEF", + "S_ROCKCRUMBLEG", + "S_ROCKCRUMBLEH", + "S_ROCKCRUMBLEI", + "S_ROCKCRUMBLEJ", + "S_ROCKCRUMBLEK", + "S_ROCKCRUMBLEL", + "S_ROCKCRUMBLEM", + "S_ROCKCRUMBLEN", + "S_ROCKCRUMBLEO", + "S_ROCKCRUMBLEP", "S_SRB1_CRAWLA1", "S_SRB1_CRAWLA2", @@ -6718,9 +6227,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s // Collectible Items "MT_RING", "MT_FLINGRING", // Lost ring -#ifdef BLUE_SPHERES "MT_BLUEBALL", // Blue sphere replacement for special stages -#endif "MT_REDTEAMRING", //Rings collectable by red team. "MT_BLUETEAMRING", //Rings collectable by blue team. "MT_EMMY", // emerald token for special stage @@ -7313,27 +6820,31 @@ static const char *COLOR_ENUMS[] = { "SILVER", // SKINCOLOR_SILVER "GREY", // SKINCOLOR_GREY "BLACK", // SKINCOLOR_BLACK - "CYAN", // SKINCOLOR_CYAN - "TEAL", // SKINCOLOR_TEAL - "STEELBLUE", // SKINCOLOR_STEELBLUE - "BLUE", // SKINCOLOR_BLUE - "PEACH", // SKINCOLOR_PEACH - "TAN", // SKINCOLOR_TAN - "PINK", // SKINCOLOR_PINK - "LAVENDER", // SKINCOLOR_LAVENDER - "PURPLE", // SKINCOLOR_PURPLE - "ORANGE", // SKINCOLOR_ORANGE - "ROSEWOOD", // SKINCOLOR_ROSEWOOD "BEIGE", // SKINCOLOR_BEIGE + "PEACH", // SKINCOLOR_PEACH "BROWN", // SKINCOLOR_BROWN "RED", // SKINCOLOR_RED - "DARKRED", // SKINCOLOR_DARKRED - "NEONGREEN", // SKINCOLOR_NEONGREEN - "GREEN", // SKINCOLOR_GREEN - "ZIM", // SKINCOLOR_ZIM - "OLIVE", // SKINCOLOR_OLIVE + "CRIMSON", // SKINCOLOR_CRIMSON + "ORANGE", // SKINCOLOR_ORANGE + "RUST", // SKINCOLOR_RUST + "GOLD", // SKINCOLOR_GOLD "YELLOW", // SKINCOLOR_YELLOW - "GOLD", // SKINCOLOR_GOLD + "TAN", // SKINCOLOR_TAN + "MOSS", // SKINCOLOR_MOSS + "PERIDOT", // SKINCOLOR_PERIDOT + "GREEN", // SKINCOLOR_GREEN + "EMERALD", // SKINCOLOR_EMERALD + "AQUA", // SKINCOLOR_AQUA + "TEAL", // SKINCOLOR_TEAL + "CYAN", // SKINCOLOR_CYAN + "BLUE", // SKINCOLOR_BLUE + "AZURE", // SKINCOLOR_AZURE + "PASTEL", // SKINCOLOR_PASTEL + "PURPLE", // SKINCOLOR_PURPLE + "LAVENDER", // SKINCOLOR_LAVENDER + "MAGENTA", // SKINCOLOR_MAGENTA + "PINK", // SKINCOLOR_PINK + "ROSY", // SKINCOLOR_ROSY // Super special awesome Super flashing colors! "SUPER1", // SKINCOLOR_SUPER1 "SUPER2", // SKINCOLOR_SUPER2, @@ -7464,6 +6975,8 @@ struct { {"PUSHACCEL",PUSHACCEL}, {"MODID",MODID}, // I don't know, I just thought it would be cool for a wad to potentially know what mod it was loaded into. {"CODEBASE",CODEBASE}, // or what release of SRB2 this is. + {"VERSION",VERSION}, // Grab the game's version! + {"SUBVERSION",SUBVERSION}, // more precise version number // Special linedef executor tag numbers! {"LE_PINCHPHASE",LE_PINCHPHASE}, // A boss entered pinch phase (and, in most cases, is preparing their pinch phase attack!) @@ -7476,6 +6989,7 @@ struct { // Frame settings {"FF_FRAMEMASK",FF_FRAMEMASK}, + {"FF_ANIMATE",FF_ANIMATE}, {"FF_FULLBRIGHT",FF_FULLBRIGHT}, {"FF_TRANSMASK",FF_TRANSMASK}, {"FF_TRANSSHIFT",FF_TRANSSHIFT}, @@ -7675,7 +7189,7 @@ struct { {"PA_RUN",PA_RUN}, {"PA_PAIN",PA_PAIN}, {"PA_ROLL",PA_ROLL}, - {"PA_JUMP",PA_JUMP}, + {"PA_SPRING",PA_SPRING}, {"PA_FALL",PA_FALL}, {"PA_ABILITY",PA_ABILITY}, {"PA_RIDE",PA_RIDE}, @@ -7954,21 +7468,45 @@ static sfxenum_t get_sfx(const char *word) return sfx_None; } -static UINT16 get_mus(const char *word) -{ // Returns the value of SFX_ enumerations +#ifdef MUSICSLOT_COMPATIBILITY +static UINT16 get_mus(const char *word, UINT8 dehacked_mode) +{ // Returns the value of MUS_ enumerations UINT16 i; + char lumptmp[4]; + if (*word >= '0' && *word <= '9') return atoi(word); + if (!word[2] && toupper(word[0]) >= 'A' && toupper(word[0]) <= 'Z') + return (UINT16)M_MapNumber(word[0], word[1]); + if (fastncmp("MUS_",word,4)) word += 4; // take off the MUS_ else if (fastncmp("O_",word,2) || fastncmp("D_",word,2)) word += 2; // take off the O_ or D_ - for (i = 0; i < NUMMUSIC; i++) - if (S_music[i].name && fasticmp(word, S_music[i].name)) + + strncpy(lumptmp, word, 4); + lumptmp[3] = 0; + if (fasticmp("MAP",lumptmp)) + { + word += 3; + if (toupper(word[0]) >= 'A' && toupper(word[0]) <= 'Z') + return (UINT16)M_MapNumber(word[0], word[1]); + else if ((i = atoi(word))) return i; - deh_warning("Couldn't find music named 'MUS_%s'",word); - return mus_None; + + word -= 3; + if (dehacked_mode) + deh_warning("Couldn't find music named 'MUS_%s'",word); + return 0; + } + for (i = 0; compat_special_music_slots[i][0]; ++i) + if (fasticmp(word, compat_special_music_slots[i])) + return i + 1036; + if (dehacked_mode) + deh_warning("Couldn't find music named 'MUS_%s'",word); + return 0; } +#endif static hudnum_t get_huditem(const char *word) { // Returns the value of HUD_ enumerations @@ -8168,11 +7706,13 @@ static fixed_t find_const(const char **rword) free(word); return r; } +#ifdef MUSICSLOT_COMPATIBILITY else if (fastncmp("MUS_",word,4) || fastncmp("O_",word,2)) { - r = get_mus(word); + r = get_mus(word, true); free(word); return r; } +#endif else if (fastncmp("PW_",word,3)) { r = get_power(word); free(word); @@ -8563,33 +8103,29 @@ static inline int lib_getenum(lua_State *L) if (mathlib) return luaL_error(L, "sfx '%s' could not be found.\n", word); return 0; } +#ifdef MUSICSLOT_COMPATIBILITY else if (!mathlib && fastncmp("mus_",word,4)) { p = word+4; - for (i = 0; i < NUMMUSIC; i++) - if (S_music[i].name && fastcmp(p, S_music[i].name)) { - lua_pushinteger(L, i); - return 1; - } - return 0; + if ((i = get_mus(p, false)) == 0) + return 0; + lua_pushinteger(L, i); + return 1; } else if (mathlib && fastncmp("MUS_",word,4)) { // SOCs are ALL CAPS! p = word+4; - for (i = 0; i < NUMMUSIC; i++) - if (S_music[i].name && fasticmp(p, S_music[i].name)) { - lua_pushinteger(L, i); - return 1; - } - return luaL_error(L, "music '%s' could not be found.\n", word); + if ((i = get_mus(p, false)) == 0) + return luaL_error(L, "music '%s' could not be found.\n", word); + lua_pushinteger(L, i); + return 1; } else if (mathlib && (fastncmp("O_",word,2) || fastncmp("D_",word,2))) { p = word+2; - for (i = 0; i < NUMMUSIC; i++) - if (S_music[i].name && fasticmp(p, S_music[i].name)) { - lua_pushinteger(L, i); - return 1; - } - return luaL_error(L, "music '%s' could not be found.\n", word); + if ((i = get_mus(p, false)) == 0) + return luaL_error(L, "music '%s' could not be found.\n", word); + lua_pushinteger(L, i); + return 1; } +#endif else if (!mathlib && fastncmp("pw_",word,3)) { p = word+3; for (i = 0; i < NUMPOWERS; i++) @@ -8741,8 +8277,11 @@ static inline int lib_getenum(lua_State *L) } else if (fastcmp(word,"globallevelskynum")) { lua_pushinteger(L, globallevelskynum); return 1; - } else if (fastcmp(word,"mapmusic")) { - lua_pushinteger(L, mapmusic); + } else if (fastcmp(word,"mapmusname")) { + lua_pushstring(L, mapmusname); + return 1; + } else if (fastcmp(word,"mapmusflags")) { + lua_pushinteger(L, mapmusflags); return 1; } else if (fastcmp(word,"server")) { if ((!multiplayer || !netgame) && !playeringame[serverplayer]) @@ -8760,6 +8299,9 @@ static inline int lib_getenum(lua_State *L) } else if (fastcmp(word,"gravity")) { lua_pushinteger(L, gravity); return 1; + } else if (fastcmp(word,"VERSIONSTRING")) { + lua_pushstring(L, VERSIONSTRING); + return 1; } return 0; diff --git a/src/doomdef.h b/src/doomdef.h index 83702ad75..f0cb88e71 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -142,8 +142,10 @@ extern FILE *logstream; #ifdef DEVELOP #define VERSION 0 // Game version #define SUBVERSION 0 // more precise version number -#define VERSIONSTRING "Trunk" -#define VERSIONSTRINGW L"Trunk" +#define VERSIONSTRING "Development EXE" +#define VERSIONSTRINGW L"Development EXE" +// most interface strings are ignored in development mode. +// we use comprevision and compbranch instead. #else #define VERSION 202 // Game version #define SUBVERSION 0 // more precise version number @@ -208,13 +210,6 @@ extern FILE *logstream; // Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1". #define MODVERSION 20 - - - - -// some tests, enable or disable it if it run or not -#define SPLITSCREEN - // ========================================================================= // The maximum number of players, multiplayer/networking. @@ -232,27 +227,31 @@ typedef enum SKINCOLOR_SILVER, SKINCOLOR_GREY, SKINCOLOR_BLACK, - SKINCOLOR_CYAN, - SKINCOLOR_TEAL, - SKINCOLOR_STEELBLUE, - SKINCOLOR_BLUE, - SKINCOLOR_PEACH, - SKINCOLOR_TAN, - SKINCOLOR_PINK, - SKINCOLOR_LAVENDER, - SKINCOLOR_PURPLE, - SKINCOLOR_ORANGE, - SKINCOLOR_ROSEWOOD, SKINCOLOR_BEIGE, + SKINCOLOR_PEACH, SKINCOLOR_BROWN, SKINCOLOR_RED, - SKINCOLOR_DARKRED, - SKINCOLOR_NEONGREEN, - SKINCOLOR_GREEN, - SKINCOLOR_ZIM, - SKINCOLOR_OLIVE, - SKINCOLOR_YELLOW, + SKINCOLOR_CRIMSON, + SKINCOLOR_ORANGE, + SKINCOLOR_RUST, SKINCOLOR_GOLD, + SKINCOLOR_YELLOW, + SKINCOLOR_TAN, + SKINCOLOR_MOSS, + SKINCOLOR_PERIDOT, + SKINCOLOR_GREEN, + SKINCOLOR_EMERALD, + SKINCOLOR_AQUA, + SKINCOLOR_TEAL, + SKINCOLOR_CYAN, + SKINCOLOR_BLUE, + SKINCOLOR_AZURE, + SKINCOLOR_PASTEL, + SKINCOLOR_PURPLE, + SKINCOLOR_LAVENDER, + SKINCOLOR_MAGENTA, + SKINCOLOR_PINK, + SKINCOLOR_ROSY, // Careful! MAXSKINCOLORS cannot be greater than 0x20! MAXSKINCOLORS, @@ -350,11 +349,7 @@ void CONS_Debug(INT32 debugflags, const char *fmt, ...) FUNCDEBUG; #include "m_swap.h" // Things that used to be in dstrings.h -#define DEVMAPS "devmaps" -#define DEVDATA "devdata" - #define SAVEGAMENAME "srb2sav" - char savegamename[256]; // m_misc.h @@ -426,7 +421,7 @@ INT32 I_GetKey(void); #endif // Compile date and time and revision. -extern const char *compdate, *comptime, *comprevision; +extern const char *compdate, *comptime, *comprevision, *compbranch; // Disabled code and code under testing // None of these that are disabled in the normal build are guaranteed to work perfectly @@ -436,8 +431,8 @@ extern const char *compdate, *comptime, *comprevision; /// \note obsoleted by cv_maxportals //#define PORTAL_LIMIT 8 -/// Fun experimental slope stuff! -//#define SLOPENESS +/// Kalaron/Eternity Engine slope code (SRB2CB ported) +#define ESLOPE /// Delete file while the game is running. /// \note EXTREMELY buggy, tends to crash game. @@ -455,10 +450,6 @@ extern const char *compdate, *comptime, *comprevision; /// Polyobject fake flat code #define POLYOBJECTS_PLANES -/// Blue spheres for future use. -/// \todo Remove this define. -#define BLUE_SPHERES // Blue spheres for future use. - /// Improved way of dealing with ping values and a ping limit. #define NEWPING @@ -496,4 +487,8 @@ extern const char *compdate, *comptime, *comprevision; /// Experimental tweaks to analog mode. (Needs a lot of work before it's ready for primetime.) //#define REDSANALOG +/// Backwards compatibility with musicslots. +/// \note You should leave this enabled unless you're working with a future SRB2 version. +#define MUSICSLOT_COMPATIBILITY + #endif // __DOOMDEF__ diff --git a/src/doomstat.h b/src/doomstat.h index 44cf6feaa..ffdbcaecd 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -31,15 +31,11 @@ // Selected by user. extern INT16 gamemap; - -// ----------------xxxxxxxxxxxxxxxx = music slot -// -xxxxxxxxxxxxxxx---------------- = track slot -// x------------------------------- = reset music bit -extern UINT32 mapmusic; -#define MUSIC_TRACKSHIFT 16 -#define MUSIC_SONGMASK 0x0000FFFF -#define MUSIC_TRACKMASK 0x7FFF0000 -#define MUSIC_RELOADRESET 0x80000000 +extern char mapmusname[7]; +extern UINT16 mapmusflags; +#define MUSIC_TRACKMASK 0x0FFF // ----************ +#define MUSIC_RELOADRESET 0x8000 // *--------------- +// Use other bits if necessary. extern INT16 maptol; extern UINT8 globalweather; @@ -146,11 +142,13 @@ typedef struct UINT16 xcoord[8]; UINT16 ycoord[8]; UINT16 picduration[8]; - UINT16 musicslot; UINT8 musicloop; UINT16 textxpos; UINT16 textypos; + char musswitch[7]; + UINT16 musswitchflags; + UINT8 fadecolor; // Color number for fade, 0 means don't do the first fade UINT8 fadeinid; // ID of the first fade, to a color -- ignored if fadecolor is 0 UINT8 fadeoutid; // ID of the second fade, to the new screen @@ -218,8 +216,8 @@ typedef struct UINT8 actnum; ///< Act number or 0 for none. UINT16 typeoflevel; ///< Combination of typeoflevel flags. INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end. - UINT16 musicslot; ///< Music slot number to play. 0 for no music. - UINT16 musicslottrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore. + char musname[7]; ///< Music track to play. "" for no music. + UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore. char forcecharacter[17]; ///< (SKINNAMESIZE+1) Skin to switch to or "" to disable. UINT8 weather; ///< 0 = sunny day, 1 = storm, 2 = snow, 3 = rain, 4 = blank, 5 = thunder w/o rain, 6 = rain w/o lightning, 7 = heat wave. INT16 skynum; ///< Sky number to use. diff --git a/src/doomtype.h b/src/doomtype.h index ff4199775..8e7da6881 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -100,11 +100,13 @@ typedef long ssize_t; #if defined (_MSC_VER) || defined (__OS2__) // Microsoft VisualC++ +#ifdef _MSC_VER #if (_MSC_VER <= 1800) // MSVC 2013 and back #define snprintf _snprintf #if (_MSC_VER <= 1200) // MSVC 2012 and back #define vsnprintf _vsnprintf #endif +#endif #endif #define strncasecmp strnicmp #define strcasecmp stricmp @@ -177,6 +179,8 @@ size_t strlcpy(char *dst, const char *src, size_t siz); // not the number of bytes in the buffer. #define STRBUFCPY(dst,src) strlcpy(dst, src, sizeof dst) +// \note __BYTEBOOL__ used to be set above if "macintosh" was defined, +// if macintosh's version of boolean type isn't needed anymore, then isn't this macro pointless now? #ifndef __BYTEBOOL__ #define __BYTEBOOL__ @@ -193,7 +197,6 @@ size_t strlcpy(char *dst, const char *src, size_t siz); #else typedef enum {false, true} boolean; #endif - //#endif // __cplusplus #endif // __BYTEBOOL__ /* 7.18.2.1 Limits of exact-width integer types */ diff --git a/src/f_finale.c b/src/f_finale.c index f541995d4..17a288631 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -559,7 +559,7 @@ static void F_IntroDrawScene(void) if (finalecount < 4) S_StopMusic(); if (finalecount == 4) - S_ChangeMusic(mus_stjr, false); + S_ChangeMusicInternal("stjr", false); x = (BASEVIDWIDTH<)", // For his MSPaint sprite that we nicked + "Randi Heit ()", // For their MSPaint sprite that we nicked "", "\1Produced By", "Sonic Team Junior", @@ -1124,7 +1129,7 @@ void F_StartCredits(void) CON_ClearHUD(); S_StopMusic(); - S_ChangeMusic(mus_credit, false); + S_ChangeMusicInternal("credit", false); finalecount = 0; animtimer = 0; @@ -1421,7 +1426,7 @@ void F_StartTitleScreen(void) // IWAD dependent stuff. - S_ChangeMusic(mus_titles, looptitle); + S_ChangeMusicInternal("titles", looptitle); animtimer = 0; @@ -1587,7 +1592,7 @@ void F_StartContinue(void) // In case menus are still up?!! M_ClearMenus(true); - S_ChangeMusic(mus_contsc, false); + S_ChangeMusicInternal("contsc", false); S_StopSounds(); timetonext = TICRATE*11; @@ -1701,8 +1706,10 @@ static void F_AdvanceToNextScene(void) picxpos = cutscenes[cutnum]->scene[scenenum].xcoord[picnum]; picypos = cutscenes[cutnum]->scene[scenenum].ycoord[picnum]; - if (cutscenes[cutnum]->scene[scenenum].musicslot != 0) - S_ChangeMusic(cutscenes[cutnum]->scene[scenenum].musicslot, cutscenes[cutnum]->scene[scenenum].musicloop); + if (cutscenes[cutnum]->scene[scenenum].musswitch[0]) + S_ChangeMusic(cutscenes[cutnum]->scene[scenenum].musswitch, + cutscenes[cutnum]->scene[scenenum].musswitchflags, + cutscenes[cutnum]->scene[scenenum].musicloop); // Fade to the next dofadenow = true; @@ -1773,8 +1780,10 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset animtimer = cutscenes[cutnum]->scene[0].picduration[0]; // Picture duration stoptimer = 0; - if (cutscenes[cutnum]->scene[scenenum].musicslot != 0) - S_ChangeMusic(cutscenes[cutnum]->scene[scenenum].musicslot, cutscenes[cutnum]->scene[scenenum].musicloop); + if (cutscenes[cutnum]->scene[0].musswitch[0]) + S_ChangeMusic(cutscenes[cutnum]->scene[0].musswitch, + cutscenes[cutnum]->scene[0].musswitchflags, + cutscenes[cutnum]->scene[0].musicloop); else S_StopMusic(); } diff --git a/src/f_finale.h b/src/f_finale.h index 97a26f4c4..e263a3797 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -90,6 +90,7 @@ enum // custom intermissions wipe_specinter_toblack, wipe_multinter_toblack, + wipe_speclevel_towhite, wipe_level_final, wipe_intermission_final, @@ -108,7 +109,7 @@ enum NUMWIPEDEFS }; -#define WIPEFINALSHIFT 12 +#define WIPEFINALSHIFT 13 extern UINT8 wipedefs[NUMWIPEDEFS]; #endif diff --git a/src/f_wipe.c b/src/f_wipe.c index 8e7c622c4..e0578949e 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -58,6 +58,7 @@ UINT8 wipedefs[NUMWIPEDEFS] = { 0, // wipe_specinter_toblack 0, // wipe_multinter_toblack + 0, // wipe_speclevel_towhite 0, // wipe_level_final 0, // wipe_intermission_final @@ -231,34 +232,52 @@ static void F_DoWipe(fademask_t *fademask) maskx = masky = 0; do { - // pointer to transtable that this mask would use - transtbl = transtables + ((9 - *mask)<= fademask->width) ++masky, maskx = 0; diff --git a/src/g_game.c b/src/g_game.c index e7456ca22..af70ce424 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -69,8 +69,10 @@ static void G_DoStartContinue(void); static void G_DoContinued(void); static void G_DoWorldDone(void); +char mapmusname[7]; // Music name +UINT16 mapmusflags; // Track and reset bit + INT16 gamemap = 1; -UINT32 mapmusic; // music, track, and reset bit INT16 maptol; UINT8 globalweather = 0; INT32 curWeather = PRECIP_NONE; @@ -124,7 +126,7 @@ boolean useNightsSS = false; UINT8 skincolor_redteam = SKINCOLOR_RED; UINT8 skincolor_blueteam = SKINCOLOR_BLUE; UINT8 skincolor_redring = SKINCOLOR_RED; -UINT8 skincolor_bluering = SKINCOLOR_STEELBLUE; +UINT8 skincolor_bluering = SKINCOLOR_AZURE; tic_t countdowntimer = 0; boolean countdowntimeup = false; @@ -298,9 +300,6 @@ static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"}, #if JOYAXISSET > 3 {7, "Pitch"}, {8, "Roll"}, {-7, "Pitch-"}, {-8, "Roll-"}, #endif -#if JOYAXISSET > 3 -{7, "Pitch"}, {8, "Roll"}, {-7, "Pitch-"}, {-8, "Roll-"}, -#endif #if JOYAXISSET > 4 {7, "Yaw"}, {8, "Dummy"}, {-7, "Yaw-"}, {-8, "Dummy-"}, #endif @@ -2186,12 +2185,13 @@ void G_PlayerReborn(INT32 player) if (p-players == consoleplayer) { - if (mapmusic & MUSIC_RELOADRESET) // TODO: Might not need this here + if (mapmusflags & MUSIC_RELOADRESET) { - mapmusic = mapheaderinfo[gamemap-1]->musicslot - | (mapheaderinfo[gamemap-1]->musicslottrack << MUSIC_TRACKSHIFT); + strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7); + mapmusname[6] = 0; + mapmusflags = mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK; } - S_ChangeMusic(mapmusic, true); + S_ChangeMusic(mapmusname, mapmusflags, true); } if (gametype == GT_COOP) @@ -2332,6 +2332,11 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost) } } P_MovePlayerToSpawn(playernum, spawnpoint); + +#ifdef HAVE_BLUA + LUAh_PlayerSpawn(&players[playernum]); // Lua hook for player spawning :) +#endif + } mapthing_t *G_FindCTFStart(INT32 playernum) @@ -2875,7 +2880,8 @@ static void G_DoCompleted(void) // We are committed to this map now. // We may as well allocate its header if it doesn't exist - if(!mapheaderinfo[nextmap]) + // (That is, if it's a real map) + if (nextmap < NUMMAPS && !mapheaderinfo[nextmap]) P_AllocMapHeader(nextmap); if (skipstats) @@ -3525,7 +3531,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean if (paused) { paused = false; - S_ResumeSound(); + S_ResumeAudio(); } if (netgame || multiplayer) // Nice try, haxor. @@ -3599,7 +3605,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean globalweather = mapheaderinfo[gamemap-1]->weather; // Don't carry over custom music change to another map. - mapmusic |= MUSIC_RELOADRESET; + mapmusflags |= MUSIC_RELOADRESET; ultimatemode = pultmode; playerdeadview = false; @@ -4340,10 +4346,8 @@ void G_GhostTicker(void) switch(g->color) { case GHC_SUPER: // Super Sonic (P_DoSuperStuff) - if (leveltime % 9 < 5) - g->mo->color = SKINCOLOR_SUPER1 + leveltime % 9; - else - g->mo->color = SKINCOLOR_SUPER1 + 9 - leveltime % 9; + g->mo->color = SKINCOLOR_SUPER1; + g->mo->color += abs( ( ( leveltime >> 1 ) % 9) - 4); break; case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer) g->mo->color = (UINT8)(leveltime % MAXSKINCOLORS); @@ -5587,7 +5591,7 @@ boolean G_CheckDemoStatus(void) free(demobuffer); demorecording = false; - if (!modeattacking == ATTACKING_RECORD) + if (modeattacking != ATTACKING_RECORD) { if (saved) CONS_Printf(M_GetText("Demo %s recorded\n"), demoname); diff --git a/src/g_input.c b/src/g_input.c index f12ddb711..e9010b39d 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -16,7 +16,6 @@ #include "g_input.h" #include "keys.h" #include "hu_stuff.h" // need HUFONT start & end -#include "keys.h" #include "d_net.h" #include "console.h" @@ -1042,13 +1041,13 @@ INT32 G_KeyStringtoNum(const char *keystr) if (!keystr[1] && keystr[0] > ' ' && keystr[0] <= 'z') return keystr[0]; + if (!strncmp(keystr, "KEY", 3) && keystr[3] >= '0' && keystr[3] <= '9') + return atoi(&keystr[3]); + for (j = 0; j < NUMKEYNAMES; j++) if (!stricmp(keynames[j].name, keystr)) return keynames[j].keynum; - if (strlen(keystr) > 3) - return atoi(&keystr[3]); - return 0; } diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 70d776d9e..52110121b 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -46,8 +46,8 @@ typedef unsigned char FBOOLEAN; #define HWR_PATCHES_CHROMAKEY_COLORINDEX 0 #define HWR_CHROMAKEY_EQUIVALENTCOLORINDEX 1 #else -#define HWR_PATCHES_CHROMAKEY_COLORINDEX 247 -#define HWR_CHROMAKEY_EQUIVALENTCOLORINDEX 220 +#define HWR_PATCHES_CHROMAKEY_COLORINDEX 255 +#define HWR_CHROMAKEY_EQUIVALENTCOLORINDEX 130 #endif // the chroma key color shows on border sprites, set it to black diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 88786bc11..94eef1d3e 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -36,9 +36,7 @@ typedef struct { float x; float y; -//#ifdef SLOPENESS float z; -//#endif } polyvertex_t; #ifdef _MSC_VER @@ -79,6 +77,7 @@ typedef struct gr_vissprite_s boolean vflip; //Hurdler: 25/04/2000: now support colormap in hardware mode UINT8 *colormap; + INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing } gr_vissprite_t; // -------- diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 820eb25fc..ac54cc130 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -539,6 +539,8 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fi static FOutVector *planeVerts = NULL; static UINT16 numAllocedPlaneVerts = 0; + (void)sector; + // no convex poly were generated for this subsector if (!xsub->planepoly) return; @@ -678,25 +680,6 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fi v3d->x = pv->x; v3d->y = height; v3d->z = pv->y; -#ifdef SLOPENESS - if (sector && sector->special == 65535) - { - size_t q; - for (q = 0; q < sector->linecount; q++) - { - if (v3d->x == sector->lines[q]->v1->x>>FRACBITS) - { - if (v3d->z == sector->lines[q]->v1->y>>FRACBITS) - { - v3d->y += sector->lines[q]->v1->z>>FRACBITS; - break; - } - } - } - } -#else - (void)sector; -#endif } // only useful for flat coloured triangles @@ -2856,7 +2839,6 @@ static void HWR_AddPolyObjectPlanes(void) // : Draw one or more line segments. // Notes : Sets gr_cursectorlight to the light of the parent sector, to modulate wall textures // -----------------+ -static lumpnum_t doomwaterflat; //set by R_InitFlats hack static void HWR_Subsector(size_t num) { INT16 count; @@ -2867,7 +2849,6 @@ static void HWR_Subsector(size_t num) INT32 ceilinglightlevel; INT32 locFloorHeight, locCeilingHeight; INT32 light = 0; - fixed_t wh; extracolormap_t *floorcolormap; extracolormap_t *ceilingcolormap; @@ -3193,26 +3174,6 @@ static void HWR_Subsector(size_t num) } } -//20/08/99: Changed by Hurdler (taken from faB's code) -#ifdef DOPLANES - // -------------------- WATER IN DEV. TEST ------------------------ - //dck hack : use abs(tag) for waterheight - //ilag : Since we changed to UINT16 for sector tags, simulate INT16 - if (gr_frontsector->tag > 32767) - { - wh = ((65535-gr_frontsector->tag) < gr_frontsector->floorheight && - wh < gr_frontsector->ceilingheight) - { - HWR_GetFlat(doomwaterflat); - HWR_RenderPlane(gr_frontsector, - &extrasubsectors[num], wh, PF_Translucent, - gr_frontsector->lightlevel, doomwaterflat, - NULL, 255, false, gr_frontsector->lightlist[light].extra_colormap); - } - } - // -------------------- WATER IN DEV. TEST ------------------------ -#endif sub->validcount = validcount; } @@ -3998,6 +3959,7 @@ static void HWR_SortVisSprites(void) gr_vissprite_t *best = NULL; gr_vissprite_t unsorted; float bestdist; + INT32 bestdispoffset; if (!gr_visspritecount) return; @@ -4025,11 +3987,19 @@ static void HWR_SortVisSprites(void) for (i = 0; i < gr_visspritecount; i++) { bestdist = ZCLIP_PLANE-1; + bestdispoffset = INT32_MAX; for (ds = unsorted.next; ds != &unsorted; ds = ds->next) { if (ds->tz > bestdist) { bestdist = ds->tz; + bestdispoffset = ds->dispoffset; + best = ds; + } + // order visprites of same scale by dispoffset, smallest first + else if (ds->tz == bestdist && ds->dispoffset < bestdispoffset) + { + bestdispoffset = ds->dispoffset; best = ds; } } @@ -4653,6 +4623,7 @@ static void HWR_ProjectSprite(mobj_t *thing) #endif vis->x2 = tx; vis->tz = tz; + vis->dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST vis->patchlumpnum = sprframe->lumppat[rot]; vis->flip = flip; vis->mobj = thing; @@ -4769,6 +4740,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) vis->x1 = x1; vis->x2 = tx; vis->tz = tz; + vis->dispoffset = 0; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST vis->patchlumpnum = sprframe->lumppat[rot]; vis->flip = flip; vis->mobj = (mobj_t *)thing; @@ -5488,11 +5460,6 @@ void HWR_Startup(void) HWR_AddEngineCommands(); HWR_InitTextureCache(); - // for test water translucent surface - doomwaterflat = W_CheckNumForName("FWATER1"); - if (doomwaterflat == LUMPERROR) // if FWATER1 not found (in doom shareware) - doomwaterflat = W_GetNumForName("WATER0"); - HWR_InitMD2(); #ifdef ALAM_LIGHTING diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 8d578a1ec..ea175dbea 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -41,6 +41,7 @@ #include "../r_things.h" #include "hw_main.h" +#include "../v_video.h" #ifdef HAVE_PNG #ifndef _MSC_VER @@ -881,6 +882,59 @@ static void md2_loadTexture(md2_t *model) HWR_UnlockCachedPatch(grpatch); } +// -----------------+ +// md2_loadBlendTexture : Download a pcx or png texture for blending MD2 models +// -----------------+ +static void md2_loadBlendTexture(md2_t *model) +{ + GLPatch_t *grpatch; + char *filename = Z_Malloc(strlen(model->filename)+7, PU_STATIC, NULL); + strcpy(filename, model->filename); + + FIL_ForceExtension(filename, "_blend.png"); + + if (model->blendgrpatch) + { + grpatch = model->blendgrpatch; + Z_Free(grpatch->mipmap.grInfo.data); + } + else + grpatch = Z_Calloc(sizeof *grpatch, PU_HWRPATCHINFO, + &(model->blendgrpatch)); + + if (!grpatch->mipmap.downloaded && !grpatch->mipmap.grInfo.data) + { + int w = 0, h = 0; +#ifdef HAVE_PNG + grpatch->mipmap.grInfo.format = PNG_Load(filename, &w, &h, grpatch); + if (grpatch->mipmap.grInfo.format == 0) +#endif + grpatch->mipmap.grInfo.format = PCX_Load(filename, &w, &h, grpatch); + if (grpatch->mipmap.grInfo.format == 0) + { + Z_Free(filename); + return; + } + + grpatch->mipmap.downloaded = 0; + grpatch->mipmap.flags = 0; + + grpatch->width = (INT16)w; + grpatch->height = (INT16)h; + grpatch->mipmap.width = (UINT16)w; + grpatch->mipmap.height = (UINT16)h; + + // not correct! + grpatch->mipmap.grInfo.smallLodLog2 = GR_LOD_LOG2_256; + grpatch->mipmap.grInfo.largeLodLog2 = GR_LOD_LOG2_256; + grpatch->mipmap.grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; + } + HWD.pfnSetTexture(&grpatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary + HWR_UnlockCachedPatch(grpatch); + + Z_Free(filename); +} + // Don't spam the console, or the OS with fopen requests! static boolean nomd2s = false; @@ -1050,6 +1104,238 @@ spritemd2found: fclose(f); } +static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, skincolors_t color) +{ + UINT16 w = gpatch->width, h = gpatch->height; + UINT32 size = w*h; + RGBA_t *image, *blendimage, *cur, blendcolor; + + if (grmip->width == 0) + { + + grmip->width = gpatch->width; + grmip->height = gpatch->height; + + // no wrap around, no chroma key + grmip->flags = 0; + // setup the texture info + grmip->grInfo.format = GR_RGBA; + } + + Z_Free(grmip->grInfo.data); + grmip->grInfo.data = NULL; + + cur = Z_Malloc(size*4, PU_HWRCACHE, &grmip->grInfo.data); + memset(cur, 0x00, size*4); + + image = gpatch->mipmap.grInfo.data; + blendimage = blendgpatch->mipmap.grInfo.data; + + switch (color) + { + case SKINCOLOR_WHITE: + blendcolor = V_GetColor(3); + break; + case SKINCOLOR_SILVER: + blendcolor = V_GetColor(10); + break; + case SKINCOLOR_GREY: + blendcolor = V_GetColor(15); + break; + case SKINCOLOR_BLACK: + blendcolor = V_GetColor(27); + break; + case SKINCOLOR_BEIGE: + blendcolor = V_GetColor(247); + break; + case SKINCOLOR_PEACH: + blendcolor = V_GetColor(218); + break; + case SKINCOLOR_BROWN: + blendcolor = V_GetColor(234); + break; + case SKINCOLOR_RED: + blendcolor = V_GetColor(38); + break; + case SKINCOLOR_CRIMSON: + blendcolor = V_GetColor(45); + break; + case SKINCOLOR_ORANGE: + blendcolor = V_GetColor(54); + break; + case SKINCOLOR_RUST: + blendcolor = V_GetColor(60); + break; + case SKINCOLOR_GOLD: + blendcolor = V_GetColor(67); + break; + case SKINCOLOR_YELLOW: + blendcolor = V_GetColor(73); + break; + case SKINCOLOR_TAN: + blendcolor = V_GetColor(85); + break; + case SKINCOLOR_MOSS: + blendcolor = V_GetColor(92); + break; + case SKINCOLOR_PERIDOT: + blendcolor = V_GetColor(188); + break; + case SKINCOLOR_GREEN: + blendcolor = V_GetColor(101); + break; + case SKINCOLOR_EMERALD: + blendcolor = V_GetColor(112); + break; + case SKINCOLOR_AQUA: + blendcolor = V_GetColor(122); + break; + case SKINCOLOR_TEAL: + blendcolor = V_GetColor(141); + break; + case SKINCOLOR_CYAN: + blendcolor = V_GetColor(131); + break; + case SKINCOLOR_BLUE: + blendcolor = V_GetColor(152); + break; + case SKINCOLOR_AZURE: + blendcolor = V_GetColor(171); + break; + case SKINCOLOR_PASTEL: + blendcolor = V_GetColor(161); + break; + case SKINCOLOR_PURPLE: + blendcolor = V_GetColor(165); + break; + case SKINCOLOR_LAVENDER: + blendcolor = V_GetColor(195); + break; + case SKINCOLOR_MAGENTA: + blendcolor = V_GetColor(183); + break; + case SKINCOLOR_PINK: + blendcolor = V_GetColor(211); + break; + case SKINCOLOR_ROSY: + blendcolor = V_GetColor(202); + break; + case SKINCOLOR_SUPER1: + blendcolor = V_GetColor(80); + break; + case SKINCOLOR_SUPER2: + blendcolor = V_GetColor(83); + break; + case SKINCOLOR_SUPER3: + blendcolor = V_GetColor(73); + break; + case SKINCOLOR_SUPER4: + blendcolor = V_GetColor(64); + break; + case SKINCOLOR_SUPER5: + blendcolor = V_GetColor(67); + break; + + case SKINCOLOR_TSUPER1: + case SKINCOLOR_TSUPER2: + case SKINCOLOR_TSUPER3: + case SKINCOLOR_TSUPER4: + case SKINCOLOR_TSUPER5: + case SKINCOLOR_KSUPER1: + case SKINCOLOR_KSUPER2: + case SKINCOLOR_KSUPER3: + case SKINCOLOR_KSUPER4: + case SKINCOLOR_KSUPER5: + default: + blendcolor = V_GetColor(255); + break; + } + + while (size--) + { + if (blendimage->s.alpha == 0) + { + // Don't bother with blending the pixel if the alpha of the blend pixel is 0 + cur->rgba = image->rgba; + } + else + { + INT32 tempcolor; + INT16 tempmult, tempalpha; + tempalpha = -(abs(blendimage->s.red-127)-127)*2; + if (tempalpha > 255) + tempalpha = 255; + else if (tempalpha < 0) + tempalpha = 0; + + tempmult = (blendimage->s.red-127)*2; + if (tempmult > 255) + tempmult = 255; + else if (tempmult < 0) + tempmult = 0; + + tempcolor = (image->s.red*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.red)/255)) * blendimage->s.alpha)/255; + cur->s.red = (UINT8)tempcolor; + tempcolor = (image->s.green*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.green)/255)) * blendimage->s.alpha)/255; + cur->s.green = (UINT8)tempcolor; + tempcolor = (image->s.blue*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.blue)/255)) * blendimage->s.alpha)/255; + cur->s.blue = (UINT8)tempcolor; + cur->s.alpha = image->s.alpha; + } + + cur++; image++; blendimage++; + } + + return; +} + +static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, const UINT8 *colormap, skincolors_t color) +{ + // mostly copied from HWR_GetMappedPatch, hence the similarities and comment + GLMipmap_t *grmip, *newmip; + + if (colormap == colormaps || colormap == NULL) + { + // Don't do any blending + HWD.pfnSetTexture(&gpatch->mipmap); + return; + } + + // search for the mimmap + // skip the first (no colormap translated) + for (grmip = &gpatch->mipmap; grmip->nextcolormap; ) + { + grmip = grmip->nextcolormap; + if (grmip->colormap == colormap) + { + if (grmip->downloaded && grmip->grInfo.data) + { + HWD.pfnSetTexture(grmip); // found the colormap, set it to the correct texture + Z_ChangeTag(grmip->grInfo.data, PU_HWRCACHE_UNLOCKED); + return; + } + } + } + + // If here, the blended texture has not been created + // So we create it + + //BP: WARNING: don't free it manually without clearing the cache of harware renderer + // (it have a liste of mipmap) + // this malloc is cleared in HWR_FreeTextureCache + // (...) unfortunately z_malloc fragment alot the memory :(so malloc is better + newmip = calloc(1, sizeof (*newmip)); + if (newmip == NULL) + I_Error("%s: Out of memory", "HWR_GetMappedPatch"); + grmip->nextcolormap = newmip; + newmip->colormap = colormap; + + HWR_CreateBlendedTexture(gpatch, blendgpatch, newmip, color); + + HWD.pfnSetTexture(newmip); + Z_ChangeTag(newmip->grInfo.data, PU_HWRCACHE_UNLOCKED); +} + // -----------------+ // HWR_DrawMD2 : Draw MD2 @@ -1085,7 +1371,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) if (!cv_grmd2.value) return; - if (!spr->precip) + if (spr->precip) return; // MD2 colormap fix @@ -1180,13 +1466,25 @@ void HWR_DrawMD2(gr_vissprite_t *spr) gpatch = md2->grpatch; if (!gpatch || !gpatch->mipmap.grInfo.format || !gpatch->mipmap.downloaded) md2_loadTexture(md2); - gpatch = md2->grpatch; // Load it again, because it isn't being loaded into gpatch after md2_loadtexture... + if ((gpatch && gpatch->mipmap.grInfo.format) // don't load the blend texture if the base texture isn't available + && (!md2->blendgrpatch || !((GLPatch_t *)md2->blendgrpatch)->mipmap.grInfo.format || !((GLPatch_t *)md2->blendgrpatch)->mipmap.downloaded)) + md2_loadBlendTexture(md2); + if (gpatch && gpatch->mipmap.grInfo.format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture { - // This is safe, since we know the texture has been downloaded - HWD.pfnSetTexture(&gpatch->mipmap); + if ((skincolors_t)spr->mobj->color != SKINCOLOR_NONE && + md2->blendgrpatch && ((GLPatch_t *)md2->blendgrpatch)->mipmap.grInfo.format + && gpatch->width == ((GLPatch_t *)md2->blendgrpatch)->width && gpatch->height == ((GLPatch_t *)md2->blendgrpatch)->height) + { + HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, spr->colormap, (skincolors_t)spr->mobj->color); + } + else + { + // This is safe, since we know the texture has been downloaded + HWD.pfnSetTexture(&gpatch->mipmap); + } } else { @@ -1195,16 +1493,37 @@ void HWR_DrawMD2(gr_vissprite_t *spr) HWR_GetMappedPatch(gpatch, spr->colormap); } + if (spr->mobj->frame & FF_ANIMATE) + { + // set duration and tics to be the correct values for FF_ANIMATE states + durs = spr->mobj->state->var2; + tics = spr->mobj->anim_duration; + } + //FIXME: this is not yet correct frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->header.numFrames; buff = md2->model->glCommandBuffer; curr = &md2->model->frames[frame]; - if (cv_grmd2.value == 1 - && spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL - && !(spr->mobj->player && spr->mobj->state->nextstate == S_PLAY_WAIT && spr->mobj->state == &states[S_PLAY_STND])) + if (cv_grmd2.value == 1) { - const INT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames; - next = &md2->model->frames[nextframe]; + // frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation + if (spr->mobj->frame & FF_ANIMATE) + { + UINT32 nextframe = (spr->mobj->frame & FF_FRAMEMASK) + 1; + if (nextframe >= (UINT32)spr->mobj->state->var1) + nextframe = (spr->mobj->state->frame & FF_FRAMEMASK); + nextframe %= md2->model->header.numFrames; + next = &md2->model->frames[nextframe]; + } + else + { + if (spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL + && !(spr->mobj->player && spr->mobj->state->nextstate == S_PLAY_WAIT && spr->mobj->state == &states[S_PLAY_STND])) + { + const UINT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames; + next = &md2->model->frames[nextframe]; + } + } } //Hurdler: it seems there is still a small problem with mobj angle diff --git a/src/hardware/hw_md2.h b/src/hardware/hw_md2.h index 0fb486ea0..36078268b 100644 --- a/src/hardware/hw_md2.h +++ b/src/hardware/hw_md2.h @@ -120,6 +120,7 @@ typedef struct float offset; md2_model_t *model; void *grpatch; + void *blendgrpatch; boolean notfound; INT32 skin; } md2_t; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index d14324c30..e23b3eebf 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2371,7 +2371,7 @@ EXPORT void HWRAPI(MakeScreenTexture) (void) Clamp2D(GL_TEXTURE_WRAP_S); Clamp2D(GL_TEXTURE_WRAP_T); #ifndef KOS_GL_COMPATIBILITY - pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, texsize, texsize, 0); + pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); #endif tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now @@ -2399,7 +2399,7 @@ EXPORT void HWRAPI(MakeScreenFinalTexture) (void) Clamp2D(GL_TEXTURE_WRAP_S); Clamp2D(GL_TEXTURE_WRAP_T); #ifndef KOS_GL_COMPATIBILITY - pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, texsize, texsize, 0); + pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0); #endif tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now diff --git a/src/info.c b/src/info.c index 8d7c249ad..04746848b 100644 --- a/src/info.c +++ b/src/info.c @@ -69,6 +69,7 @@ char spr2names[NUMPLAYERSPRITES][5] = "DASH", "GASP", "JUMP", + "SPNG", "FALL", "EDGE", "RIDE", @@ -94,6 +95,7 @@ char spr2names[NUMPLAYERSPRITES][5] = "SSPN", "SGSP", "SJMP", + "SSPG", "SFAL", "SEDG", "SRID", @@ -104,6 +106,7 @@ char spr2names[NUMPLAYERSPRITES][5] = state_t states[NUMSTATES] = { // frame is masked through FF_FRAMEMASK + // FF_ANIMATE (0x4000) makes simple state animations (var1 #frames, var2 tic delay) // FF_FULLBRIGHT (0x8000) activates the fullbright colormap // use FF_TRANS10 - FF_TRANS90 for easy translucency // (or tr_trans10<> 16); + else +#endif + music_flags = (UINT16)luaL_optinteger(L, 4, 0); + if (!player || P_IsLocalPlayer(player)) - S_ChangeMusic(music_num, looping); + S_ChangeMusic(music_name, music_flags, looping); return 0; } diff --git a/src/lua_hook.h b/src/lua_hook.h index da2dcdc38..4eb083780 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -42,6 +42,7 @@ enum hook { hook_LinedefExecute, hook_PlayerMsg, hook_HurtMsg, + hook_PlayerSpawn, hook_MAX // last hook }; @@ -75,5 +76,6 @@ boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_B boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook for linedef executors boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg); // Hook for chat messages boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source); // Hook for hurt messages +#define LUAh_PlayerSpawn(player) LUAh_PlayerHook(player, hook_PlayerSpawn) // Hook for G_SpawnPlayer #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 0415d23e6..2c1aa1cea 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -53,6 +53,7 @@ const char *const hookNames[hook_MAX+1] = { "LinedefExecute", "PlayerMsg", "HurtMsg", + "PlayerSpawn", NULL }; @@ -768,4 +769,33 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source) return hooked; } +void LUAh_NetArchiveHook(lua_CFunction archFunc) +{ + hook_p hookp; + + if (!gL || !(hooksAvailable[hook_NetVars/8] & (1<<(hook_NetVars%8)))) + return; + + // stack: tables + I_Assert(lua_gettop(gL) > 0); + I_Assert(lua_istable(gL, -1)); + + // tables becomes an upvalue of archFunc + lua_pushvalue(gL, -1); + lua_pushcclosure(gL, archFunc, 1); + // stack: tables, archFunc + + for (hookp = roothook; hookp; hookp = hookp->next) + if (hookp->type == hook_NetVars) + { + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -2); // archFunc + LUA_Call(gL, 1); + } + + lua_pop(gL, 1); // pop archFunc + // stack: tables +} + #endif diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 5a83d95b5..325f00b01 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -16,7 +16,9 @@ #include "r_local.h" #include "st_stuff.h" // hudinfo[] #include "g_game.h" +#include "i_video.h" // rendermode #include "p_local.h" // camera_t +#include "screen.h" // screen width/height #include "v_video.h" #include "w_wad.h" #include "z_zone.h" @@ -486,7 +488,7 @@ static int libd_getColormap(lua_State *L) INT32 skinnum = TC_DEFAULT; skincolors_t color = luaL_optinteger(L, 2, 0); UINT8* colormap = NULL; - //HUDSAFE + HUDONLY if (lua_isnoneornil(L, 1)) ; // defaults to TC_DEFAULT else if (lua_type(L, 1) == LUA_TNUMBER) // skin number @@ -510,6 +512,31 @@ static int libd_getColormap(lua_State *L) return 1; } +static int libd_width(lua_State *L) +{ + HUDONLY + lua_pushinteger(L, vid.width); // push screen width + return 1; +} + +static int libd_height(lua_State *L) +{ + HUDONLY + lua_pushinteger(L, vid.height); // push screen height + return 1; +} + +static int libd_renderer(lua_State *L) +{ + HUDONLY + switch (rendermode) { + case render_opengl: lua_pushliteral(L, "opengl"); break; // OpenGL renderer + case render_soft: lua_pushliteral(L, "software"); break; // Software renderer + default: lua_pushliteral(L, "none"); break; // render_none (for dedicated), in case there's any reason this should be run + } + return 1; +} + static luaL_Reg lib_draw[] = { {"patchExists", libd_patchExists}, {"cachePatch", libd_cachePatch}, @@ -521,6 +548,9 @@ static luaL_Reg lib_draw[] = { {"drawString", libd_drawString}, {"stringWidth", libd_stringWidth}, {"getColormap", libd_getColormap}, + {"width", libd_width}, + {"height", libd_height}, + {"renderer", libd_renderer}, {NULL, NULL} }; diff --git a/src/lua_libs.h b/src/lua_libs.h index d19ad8857..25552eacb 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -42,6 +42,7 @@ extern lua_State *gL; #define META_CVAR "CONSVAR_T*" +#define META_SECTORLINES "SECTOR_T*LINES" #define META_SIDENUM "LINE_T*SIDENUM" #define META_HUDINFO "HUDINFO_T*" diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 0a12478ca..b6b5147a9 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -37,6 +37,7 @@ enum sector_e { sector_thinglist, sector_heightsec, sector_camsec, + sector_lines, sector_ffloors }; @@ -52,6 +53,7 @@ static const char *const sector_opt[] = { "thinglist", "heightsec", "camsec", + "lines", "ffloors", NULL}; @@ -260,6 +262,67 @@ static int sector_iterate(lua_State *L) return 3; } +// sector.lines, i -> sector.lines[i] +// sector.lines.valid, for validity checking +static int sectorlines_get(lua_State *L) +{ + line_t **seclines = *((line_t ***)luaL_checkudata(L, 1, META_SECTORLINES)); + size_t i; + size_t numoflines = 0; + lua_settop(L, 2); + if (!lua_isnumber(L, 2)) + { + int field = luaL_checkoption(L, 2, NULL, valid_opt); + if (!seclines) + { + if (field == 0) { + lua_pushboolean(L, 0); + return 1; + } + return luaL_error(L, "accessed sector_t doesn't exist anymore."); + } else if (field == 0) { + lua_pushboolean(L, 1); + return 1; + } + } + + // check first linedef to figure which of its sectors owns this sector->lines pointer + // then check that sector's linecount to get a maximum index + //if (!seclines[0]) + //return luaL_error(L, "no lines found!"); // no first linedef????? + if (seclines[0]->frontsector->lines == seclines) + numoflines = seclines[0]->frontsector->linecount; + else if (seclines[0]->backsector && seclines[0]->backsector->lines == seclines) // check backsector exists first + numoflines = seclines[0]->backsector->linecount; + //if neither sector has it then ??? + + if (!numoflines) + return luaL_error(L, "no lines found!"); + + i = (size_t)lua_tointeger(L, 2); + if (i >= numoflines) + return 0; + LUA_PushUserdata(L, seclines[i], META_LINE); + return 1; +} + +static int sectorlines_num(lua_State *L) +{ + line_t **seclines = *((line_t ***)luaL_checkudata(L, 1, META_SECTORLINES)); + size_t numoflines = 0; + // check first linedef to figure which of its sectors owns this sector->lines pointer + // then check that sector's linecount to get a maximum index + //if (!seclines[0]) + //return luaL_error(L, "no lines found!"); // no first linedef????? + if (seclines[0]->frontsector->lines == seclines) + numoflines = seclines[0]->frontsector->linecount; + else if (seclines[0]->backsector && seclines[0]->backsector->lines == seclines) // check backsector exists first + numoflines = seclines[0]->backsector->linecount; + //if neither sector has it then ??? + lua_pushinteger(L, numoflines); + return 1; +} + static int sector_get(lua_State *L) { sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); @@ -325,6 +388,9 @@ static int sector_get(lua_State *L) return 0; LUA_PushUserdata(L, §ors[sector->camsec], META_SECTOR); return 1; + case sector_lines: // lines + LUA_PushUserdata(L, sector->lines, META_SECTORLINES); + return 1; case sector_ffloors: // ffloors lua_pushcfunction(L, lib_iterateSectorFFloors); LUA_PushUserdata(L, sector->ffloors, META_FFLOOR); @@ -1111,9 +1177,13 @@ static int ffloor_set(lua_State *L) case ffloor_bottompic: *ffloor->bottompic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3)); break; - case ffloor_flags: + case ffloor_flags: { + ffloortype_e oldflags = ffloor->flags; // store FOF's old flags ffloor->flags = luaL_checkinteger(L, 3); + if (ffloor->flags != oldflags) + ffloor->target->moved = true; // reset target sector's lightlist break; + } case ffloor_alpha: ffloor->alpha = (INT32)luaL_checkinteger(L, 3); break; @@ -1157,26 +1227,23 @@ static int mapheaderinfo_get(lua_State *L) { mapheader_t *header = *((mapheader_t **)luaL_checkudata(L, 1, META_MAPHEADER)); const char *field = luaL_checkstring(L, 2); - //INT16 i; - if (fastcmp(field,"lvlttl")) { - //for (i = 0; i < 21; i++) - // if (!header->lvlttl[i]) - // break; - lua_pushlstring(L, header->lvlttl, 21); - } else if (fastcmp(field,"subttl")) - lua_pushlstring(L, header->subttl, 32); + INT16 i; + if (fastcmp(field,"lvlttl")) + lua_pushstring(L, header->lvlttl); + else if (fastcmp(field,"subttl")) + lua_pushstring(L, header->subttl); else if (fastcmp(field,"actnum")) lua_pushinteger(L, header->actnum); else if (fastcmp(field,"typeoflevel")) lua_pushinteger(L, header->typeoflevel); else if (fastcmp(field,"nextlevel")) lua_pushinteger(L, header->nextlevel); - else if (fastcmp(field,"musicslot")) - lua_pushinteger(L, header->musicslot); - else if (fastcmp(field,"musicslottrack")) - lua_pushinteger(L, header->musicslottrack); + else if (fastcmp(field,"musname")) + lua_pushstring(L, header->musname); + else if (fastcmp(field,"mustrack")) + lua_pushinteger(L, header->mustrack); else if (fastcmp(field,"forcecharacter")) - lua_pushlstring(L, header->forcecharacter, 16); + lua_pushstring(L, header->forcecharacter); else if (fastcmp(field,"weather")) lua_pushinteger(L, header->weather); else if (fastcmp(field,"skynum")) @@ -1187,12 +1254,15 @@ static int mapheaderinfo_get(lua_State *L) lua_pushinteger(L, header->skybox_scaley); else if (fastcmp(field,"skybox_scalez")) lua_pushinteger(L, header->skybox_scalez); - else if (fastcmp(field,"interscreen")) - lua_pushlstring(L, header->interscreen, 8); - else if (fastcmp(field,"runsoc")) - lua_pushlstring(L, header->runsoc, 32); + else if (fastcmp(field,"interscreen")) { + for (i = 0; i < 8; i++) + if (!header->interscreen[i]) + break; + lua_pushlstring(L, header->interscreen, i); + } else if (fastcmp(field,"runsoc")) + lua_pushstring(L, header->runsoc); else if (fastcmp(field,"scriptname")) - lua_pushlstring(L, header->scriptname, 32); + lua_pushstring(L, header->scriptname); else if (fastcmp(field,"precutscenenum")) lua_pushinteger(L, header->precutscenenum); else if (fastcmp(field,"cutscenenum")) @@ -1217,11 +1287,11 @@ static int mapheaderinfo_get(lua_State *L) else { // Read custom vars now // (note: don't include the "LUA." in your lua scripts!) - UINT8 i = 0; - for (;i < header->numCustomOptions && !fastcmp(field, header->customopts[i].option); ++i); + UINT8 j = 0; + for (;j < header->numCustomOptions && !fastcmp(field, header->customopts[j].option); ++j); - if(i < header->numCustomOptions) - lua_pushlstring(L, header->customopts[i].value, 255); + if(j < header->numCustomOptions) + lua_pushstring(L, header->customopts[j].value); else lua_pushnil(L); } @@ -1230,6 +1300,14 @@ static int mapheaderinfo_get(lua_State *L) int LUA_MapLib(lua_State *L) { + luaL_newmetatable(L, META_SECTORLINES); + lua_pushcfunction(L, sectorlines_get); + lua_setfield(L, -2, "__index"); + + lua_pushcfunction(L, sectorlines_num); + lua_setfield(L, -2, "__len"); + lua_pop(L, 1); + luaL_newmetatable(L, META_SECTOR); lua_pushcfunction(L, sector_get); lua_setfield(L, -2, "__index"); diff --git a/src/lua_mathlib.c b/src/lua_mathlib.c index 8ca2e17af..fd00180d5 100644 --- a/src/lua_mathlib.c +++ b/src/lua_mathlib.c @@ -77,7 +77,9 @@ static int lib_finecosine(lua_State *L) static int lib_finetangent(lua_State *L) { - lua_pushfixed(L, FINETANGENT((luaL_checkangle(L, 1)>>ANGLETOFINESHIFT) & FINEMASK)); + // HACK: add ANGLE_90 to make tan() in Lua start at 0 like it should + // use & 4095 instead of & FINEMASK (8191), so it doesn't go out of the array's bounds + lua_pushfixed(L, FINETANGENT(((luaL_checkangle(L, 1)+ANGLE_90)>>ANGLETOFINESHIFT) & 4095)); return 1; } @@ -164,7 +166,7 @@ static int lib_all7emeralds(lua_State *L) // Returns both color and frame numbers! static int lib_coloropposite(lua_State *L) { - int colornum = ((int)luaL_checkinteger(L, 1)) & MAXSKINCOLORS; + int colornum = ((int)luaL_checkinteger(L, 1)) % MAXSKINCOLORS; lua_pushinteger(L, Color_Opposite[colornum*2]); // push color lua_pushinteger(L, Color_Opposite[colornum*2+1]); // push frame return 2; diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 83e7039e4..bf4ee0b28 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -34,6 +34,7 @@ enum mobj_e { mobj_angle, mobj_sprite, mobj_frame, + mobj_anim_duration, mobj_touching_sectorlist, mobj_subsector, mobj_floorz, @@ -92,6 +93,7 @@ static const char *const mobj_opt[] = { "angle", "sprite", "frame", + "anim_duration", "touching_sectorlist", "subsector", "floorz", @@ -187,6 +189,9 @@ static int mobj_get(lua_State *L) case mobj_frame: lua_pushinteger(L, mo->frame); break; + case mobj_anim_duration: + lua_pushinteger(L, mo->anim_duration); + break; case mobj_touching_sectorlist: return UNIMPLEMENTED; case mobj_subsector: @@ -406,6 +411,9 @@ static int mobj_set(lua_State *L) case mobj_frame: mo->frame = (UINT32)luaL_checkinteger(L, 3); break; + case mobj_anim_duration: + mo->anim_duration = (UINT16)luaL_checkinteger(L, 3); + break; case mobj_touching_sectorlist: return UNIMPLEMENTED; case mobj_subsector: diff --git a/src/lua_script.c b/src/lua_script.c index 145104d9a..9925bac02 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -737,7 +737,7 @@ static int NetArchive(lua_State *L) { int TABLESINDEX = lua_upvalueindex(1); int i, n = lua_gettop(L); - for (i = 0; i < n; i++) + for (i = 1; i <= n; i++) ArchiveValue(TABLESINDEX, i); return n; } @@ -884,7 +884,7 @@ static int NetUnArchive(lua_State *L) { int TABLESINDEX = lua_upvalueindex(1); int i, n = lua_gettop(L); - for (i = 0; i < n; i++) + for (i = 1; i <= n; i++) UnArchiveValue(TABLESINDEX); return n; } @@ -915,30 +915,6 @@ static void UnArchiveTables(void) } } -static void NetArchiveHook(lua_CFunction archFunc) -{ - int TABLESINDEX; - - if (!gL) - return; - - TABLESINDEX = lua_gettop(gL); - lua_getfield(gL, LUA_REGISTRYINDEX, "hook"); - I_Assert(lua_istable(gL, -1)); - lua_rawgeti(gL, -1, hook_NetVars); - lua_remove(gL, -2); - I_Assert(lua_istable(gL, -1)); - - lua_pushvalue(gL, TABLESINDEX); - lua_pushcclosure(gL, archFunc, 1); - lua_pushnil(gL); - while (lua_next(gL, -3) != 0) { - lua_pushvalue(gL, -3); // function - LUA_Call(gL, 1); - } - lua_pop(gL, 2); -} - void LUA_Step(void) { if (!gL) @@ -972,7 +948,7 @@ void LUA_Archive(void) } WRITEUINT32(save_p, UINT32_MAX); // end of mobjs marker, replaces mobjnum. - NetArchiveHook(NetArchive); // call the NetArchive hook in archive mode + LUAh_NetArchiveHook(NetArchive); // call the NetArchive hook in archive mode ArchiveTables(); if (gL) @@ -1003,7 +979,7 @@ void LUA_UnArchive(void) UnArchiveExtVars(th); // apply variables } while(mobjnum != UINT32_MAX); // repeat until end of mobjs marker. - NetArchiveHook(NetUnArchive); // call the NetArchive hook in unarchive mode + LUAh_NetArchiveHook(NetUnArchive); // call the NetArchive hook in unarchive mode UnArchiveTables(); if (gL) diff --git a/src/lua_script.h b/src/lua_script.h index 292160a0b..96f832e2c 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -55,6 +55,7 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum); // lua_consolelib.c void LUA_CVarChanged(const char *name); // lua_consolelib.c int Lua_optoption(lua_State *L, int narg, const char *def, const char *const lst[]); +void LUAh_NetArchiveHook(lua_CFunction archFunc); // Console wrapper void COM_Lua_f(void); @@ -69,4 +70,15 @@ void COM_Lua_f(void); #define LUA_ErrInvalid(L, type) luaL_error(L, "accessed " type " doesn't exist anymore, please check 'valid' before using " type "."); +// Deprecation warnings +// Shows once upon use. Then doesn't show again. +#define LUA_Deprecated(L,this_func,use_instead)\ +{\ + static UINT8 seen = 0;\ + if (!seen) {\ + seen = 1;\ + CONS_Alert(CONS_WARNING,"\"%s\" is deprecated and will be removed.\nUse \"%s\" instead.\n", this_func, use_instead);\ + }\ +} + #endif diff --git a/src/m_cheat.c b/src/m_cheat.c index dde3376f8..929945ecf 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -108,7 +108,7 @@ static UINT8 cheatf_devmode(void) G_SetGameModified(false); for (i = 0; i < MAXUNLOCKABLES; i++) unlockables[i].unlocked = true; - devparm = TRUE; + devparm = true; cv_debug |= 0x8000; // Refresh secrets menu existing. @@ -880,12 +880,33 @@ static boolean OP_HeightOkay(player_t *player, UINT8 ceiling) static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean ceiling) { - mapthing_t *mt; + mapthing_t *mt = mapthings; + #ifdef HAVE_BLUA LUA_InvalidateMapthings(); #endif mapthings = Z_Realloc(mapthings, ++nummapthings * sizeof (*mapthings), PU_LEVEL, NULL); + + // as Z_Realloc can relocate mapthings, quickly go through thinker list and correct + // the spawnpoints of any objects that have them to the new location + if (mt != mapthings) + { + thinker_t *th; + mobj_t *mo; + + for (th = thinkercap.next; th != &thinkercap; th = th->next) + { + if (th->function.acp1 != (actionf_p1)P_MobjThinker) + continue; + + mo = (mobj_t *)th; + // get offset from mt, which points to old mapthings, then add new location + if (mo->spawnpoint) + mo->spawnpoint = (mo->spawnpoint - mt) + mapthings; + } + } + mt = (mapthings+nummapthings-1); mt->type = type; diff --git a/src/m_cond.c b/src/m_cond.c index 17f755120..7ef192f7b 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -49,7 +49,7 @@ emblem_t emblemlocations[MAXEMBLEMS] = "Streams come to an end\n" "where they can no longer fall.\n" "But if you went up...", 0}, - {0, -336, 2064, 195, 1, 'E', SKINCOLOR_NEONGREEN, 0, + {0, -336, 2064, 195, 1, 'E', SKINCOLOR_EMERALD, 0, "This one's in plain sight.\n" "Why haven't you claimed it?\n" "Surely you saw it.", 0}, @@ -77,7 +77,7 @@ emblem_t emblemlocations[MAXEMBLEMS] = "Near the level's end,\n" "another bridge spans a lake.\n" "What could be under...?", 0}, - {0, -170, 491, 3821, 2, 'E', SKINCOLOR_NEONGREEN, 0, + {0, -170, 491, 3821, 2, 'E', SKINCOLOR_EMERALD, 0, "An ivied tunnel\n" "has a corner that's sunlit.\n" "Go reach for the sky!", 0}, @@ -110,7 +110,7 @@ emblem_t emblemlocations[MAXEMBLEMS] = "Spinning through small gaps\n" "can slip you into a cave.\n" "In that cave's first stretch...", 0}, - {0, 2848, -9088, 488, 4, 'E', SKINCOLOR_NEONGREEN, 0, + {0, 2848, -9088, 488, 4, 'E', SKINCOLOR_EMERALD, 0, "The slime lake is deep,\n" "but reaching the floor takes height.\n" "Scream \"Geronimo!\"...", 0}, @@ -138,7 +138,7 @@ emblem_t emblemlocations[MAXEMBLEMS] = "There is a hallway\n" "that a button floods with slime.\n" "Go through it again!", 0}, - {0, -2468,-12128, 1312, 5, 'E', SKINCOLOR_NEONGREEN, 0, + {0, -2468,-12128, 1312, 5, 'E', SKINCOLOR_EMERALD, 0, "Jumping on turtles\n" "will send you springing skyward.\n" "Now, do that six times...", 0}, @@ -171,7 +171,7 @@ emblem_t emblemlocations[MAXEMBLEMS] = "A caved-in hallway?\n" "The floor falls; the path goes down.\n" "But those rocks looked weak...", 0}, - {0, 12576, 16096, -992, 7, 'E', SKINCOLOR_NEONGREEN, 0, + {0, 12576, 16096, -992, 7, 'E', SKINCOLOR_EMERALD, 0, "The end is quite dry.\n" "Some rocks dam the water in.\n" "Knuckles can fix that...", 0}, @@ -199,7 +199,7 @@ emblem_t emblemlocations[MAXEMBLEMS] = "In the current maze\n" "hides a dark room of columns.\n" "Find it, then look up.", 0}, - {0, 3104, 16192, 2408, 8, 'E', SKINCOLOR_NEONGREEN, 0, + {0, 3104, 16192, 2408, 8, 'E', SKINCOLOR_EMERALD, 0, "That same dragon's eye\n" "hides another secret room.\n" "There, solve its riddle.", 0}, @@ -232,7 +232,7 @@ emblem_t emblemlocations[MAXEMBLEMS] = "The final approach!\n" "A tower holds the emblem\n" "near a ring arrow.", 0}, - {0, 9472, -5890, 710, 10, 'E', SKINCOLOR_NEONGREEN, 0, + {0, 9472, -5890, 710, 10, 'E', SKINCOLOR_EMERALD, 0, "The right starting path\n" "hides this near a canopy,\n" "high, where two trees meet.", 0}, @@ -260,7 +260,7 @@ emblem_t emblemlocations[MAXEMBLEMS] = "Some of these bookshelves\n" "are not flush against the walls.\n" "Wonder why that is?", 0}, - {0, 12708,-13536, 4768, 11, 'E', SKINCOLOR_NEONGREEN, 0, + {0, 12708,-13536, 4768, 11, 'E', SKINCOLOR_EMERALD, 0, "The ending's towers\n" "are hiding a small alcove.\n" "Check around outside.", 0}, @@ -293,7 +293,7 @@ emblem_t emblemlocations[MAXEMBLEMS] = "Not far from the start,\n" "if you climb toward the sky,\n" "the cliffs hide something.", 0}, - {0, 12504, 6848, 3424, 13, 'E', SKINCOLOR_NEONGREEN, 0, + {0, 12504, 6848, 3424, 13, 'E', SKINCOLOR_EMERALD, 0, "Right by the exit,\n" "an emblem lies on a cliff.\n" "Ride ropes to reach it.", 0}, @@ -321,7 +321,7 @@ emblem_t emblemlocations[MAXEMBLEMS] = "Where once a bridge stood,\n" "now magma falls from above.\n" "The bridge dropped something...", 0}, - {0, 8287,-11043, 1328, 16, 'E', SKINCOLOR_NEONGREEN, 0, + {0, 8287,-11043, 1328, 16, 'E', SKINCOLOR_EMERALD, 0, "A lake of magma\n" "ebbs and flows unendingly.\n" "Wait for its nadir.", 0}, @@ -349,7 +349,7 @@ emblem_t emblemlocations[MAXEMBLEMS] = "Don't jump too high here!\n" "No conveyor will catch you;\n" "you'd fall to your death.", 0}, - {0, -6432, -6192, 584, 22, 'E', SKINCOLOR_NEONGREEN, 0, + {0, -6432, -6192, 584, 22, 'E', SKINCOLOR_EMERALD, 0, "Conveyors! Magma!\n" "What an intense room this is!\n" "But, what brought you here?", 0}, @@ -377,7 +377,7 @@ emblem_t emblemlocations[MAXEMBLEMS] = "Gears with missing teeth\n" "can hide a clever secret!\n" "Think Green Hill Zone boss.", 0}, - {0, 1920, 20608, 1064, 23, 'E', SKINCOLOR_NEONGREEN, 0, + {0, 1920, 20608, 1064, 23, 'E', SKINCOLOR_EMERALD, 0, "Just before you reach\n" "the defective cargo bay,\n" "fly under a bridge.", 0}, @@ -398,7 +398,7 @@ emblem_t emblemlocations[MAXEMBLEMS] = "[PH] In the ceiling of the conveyor belt + laser hallway.", 0}, {0,-13728,-13728, 1552, 24, 'D', SKINCOLOR_ORANGE, 0, "[PH] On top of the platform with rows of spikes in reverse gravity.", 0}, - {0,-14944, 768, 1232, 24, 'E', SKINCOLOR_NEONGREEN, 0, + {0,-14944, 768, 1232, 24, 'E', SKINCOLOR_EMERALD, 0, "Follow the leader.", 0}, */ @@ -430,7 +430,7 @@ emblem_t emblemlocations[MAXEMBLEMS] = "The underground room\n" "with platforms that fall and rise\n" "only LOOKS empty...", 0}, - {0 , 4960, -6112, 1312, 30, 'E', SKINCOLOR_NEONGREEN, 0, + {0 , 4960, -6112, 1312, 30, 'E', SKINCOLOR_EMERALD, 0, "This one's straightforward.\n" "What comes to mind when I say:\n" "\"WELCOME TO WARP ZONE!\"?", 0}, @@ -458,7 +458,7 @@ emblem_t emblemlocations[MAXEMBLEMS] = "Much like the last one,\n" "you need to find some switches.\n" "Only two, this time.", 0}, - {0, 13184, 18880, 6672, 40, 'E', SKINCOLOR_NEONGREEN, 0, + {0, 13184, 18880, 6672, 40, 'E', SKINCOLOR_EMERALD, 0, "The inner sanctum!\n" "Teleport to its switches;\n" "then, check near the goal.", 0}, @@ -486,7 +486,7 @@ emblem_t emblemlocations[MAXEMBLEMS] = "A room of currents;\n" "most of them are marked by spikes.\n" "This one? A corner.", 0}, - {0, -4128, 21344, 1120, 41, 'E', SKINCOLOR_NEONGREEN, 0, + {0, -4128, 21344, 1120, 41, 'E', SKINCOLOR_EMERALD, 0, "The only way to hit\n" "all those gems at once is with\n" "a radial blast.", 0}, @@ -498,63 +498,63 @@ emblem_t emblemlocations[MAXEMBLEMS] = // FLORAL FIELD // --- - {0, 5394, -996, 160, 50, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0}, + {0, 5394, -996, 160, 50, 'N', SKINCOLOR_RUST, 0, "", 0}, {ET_NGRADE, 0,0,0, 50, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, {ET_NTIME, 0,0,0, 50, 'T', SKINCOLOR_GREY, 40*TICRATE, "", 0}, // TOXIC PLATEAU // --- - {0, 780, -1664, 32, 51, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0}, + {0, 780, -1664, 32, 51, 'N', SKINCOLOR_RUST, 0, "", 0}, {ET_NGRADE, 0,0,0, 51, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, {ET_NTIME, 0,0,0, 51, 'T', SKINCOLOR_GREY, 50*TICRATE, "", 0}, // FLOODED COVE // --- - {0, 1824, -1888, 2448, 52, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0}, + {0, 1824, -1888, 2448, 52, 'N', SKINCOLOR_RUST, 0, "", 0}, {ET_NGRADE, 0,0,0, 52, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, {ET_NTIME, 0,0,0, 52, 'T', SKINCOLOR_GREY, 90*TICRATE, "", 0}, // CAVERN FORTRESS // --- - {0, -3089, -431, 1328, 53, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0}, + {0, -3089, -431, 1328, 53, 'N', SKINCOLOR_RUST, 0, "", 0}, {ET_NGRADE, 0,0,0, 53, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, {ET_NTIME, 0,0,0, 53, 'T', SKINCOLOR_GREY, 75*TICRATE, "", 0}, // DUSTY WASTELAND // --- - {0, 957, 924, 2956, 54, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0}, + {0, 957, 924, 2956, 54, 'N', SKINCOLOR_RUST, 0, "", 0}, {ET_NGRADE, 0,0,0, 54, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, {ET_NTIME, 0,0,0, 54, 'T', SKINCOLOR_GREY, 65*TICRATE, "", 0}, // MAGMA CAVES // --- - {0, -2752, 3104, 1800, 55, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0}, + {0, -2752, 3104, 1800, 55, 'N', SKINCOLOR_RUST, 0, "", 0}, {ET_NGRADE, 0,0,0, 55, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, {ET_NTIME, 0,0,0, 55, 'T', SKINCOLOR_GREY, 80*TICRATE, "", 0}, // EGG SATELLITE // --- - {0, 5334, -609, 3426, 56, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0}, + {0, 5334, -609, 3426, 56, 'N', SKINCOLOR_RUST, 0, "", 0}, {ET_NGRADE, 0,0,0, 56, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, {ET_NTIME, 0,0,0, 56, 'T', SKINCOLOR_GREY, 120*TICRATE, "", 0}, // BLACK HOLE // --- - {0, 2108, 3776, 32, 57, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0}, + {0, 2108, 3776, 32, 57, 'N', SKINCOLOR_RUST, 0, "", 0}, {ET_NGRADE, 0,0,0, 57, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, {ET_NTIME, 0,0,0, 57, 'T', SKINCOLOR_GREY, 150*TICRATE, "", 0}, // SPRING HILL // --- - {0, -1840, -1024, 1644, 58, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0}, + {0, -1840, -1024, 1644, 58, 'N', SKINCOLOR_RUST, 0, "", 0}, {ET_NGRADE, 0,0,0, 58, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0}, {ET_NTIME, 0,0,0, 58, 'T', SKINCOLOR_GREY, 60*TICRATE, "", 0}, }; @@ -565,7 +565,7 @@ extraemblem_t extraemblems[MAXEXTRAEMBLEMS] = {"Game Complete", "Complete 1P Mode", 10, 'X', SKINCOLOR_BLUE, 0}, {"All Emeralds", "Complete 1P Mode with all Emeralds", 11, 'V', SKINCOLOR_GREY, 0}, {"Perfect Bonus", "Perfect Bonus on a non-secret stage", 30, 'P', SKINCOLOR_GOLD, 0}, - {"SRB1 Remake", "Complete SRB1 Remake", 21, 'O', SKINCOLOR_ROSEWOOD, 0}, + {"SRB1 Remake", "Complete SRB1 Remake", 21, 'O', SKINCOLOR_RUST, 0}, {"NiGHTS Mastery", "Show your mastery of NiGHTS!", 22, 'W', SKINCOLOR_TEAL, 0}, }; diff --git a/src/m_fixed.c b/src/m_fixed.c index 25a25a966..53974936e 100644 --- a/src/m_fixed.c +++ b/src/m_fixed.c @@ -119,8 +119,6 @@ fixed_t FixedHypot(fixed_t x, fixed_t y) return FixedMul(ax, yx1); // |x|*((1 + (x/y)^2)^1/2) } -#ifdef NEED_FIXED_VECTOR - vector2_t *FV2_Load(vector2_t *vec, fixed_t x, fixed_t y) { vec->x = x; @@ -863,8 +861,6 @@ void FM_Scale(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z) #undef M } -#endif - #ifdef M_TESTCASE //#define MULDIV_TEST #define SQRT_TEST diff --git a/src/m_fixed.h b/src/m_fixed.h index e68de0308..cd22d483f 100644 --- a/src/m_fixed.h +++ b/src/m_fixed.h @@ -357,8 +357,6 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedRound(fixed_t x) return INT32_MAX; } -#ifdef NEED_FIXED_VECTOR - typedef struct { fixed_t x; @@ -437,6 +435,4 @@ void FM_MultMatrix(matrix_t *dest, const matrix_t *multme); void FM_Translate(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z); void FM_Scale(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z); -#endif // defined NEED_FIXED_VECTOR - #endif //m_fixed.h diff --git a/src/m_menu.c b/src/m_menu.c index f19c4da3d..e80634b2c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2203,6 +2203,7 @@ boolean M_Responder(event_t *ev) if (modeattacking) return true; M_StartControlPanel(); + M_Options(0); currentMenu = &OP_SoundOptionsDef; itemOn = 0; return true; @@ -2212,6 +2213,7 @@ boolean M_Responder(event_t *ev) if (modeattacking) return true; M_StartControlPanel(); + M_Options(0); M_VideoModeMenu(0); return true; #endif @@ -2223,6 +2225,7 @@ boolean M_Responder(event_t *ev) if (modeattacking) return true; M_StartControlPanel(); + M_Options(0); M_SetupNextMenu(&OP_MainDef); return true; @@ -2460,11 +2463,14 @@ void M_Drawer(void) V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, customversionstring); } else -#if VERSION > 0 || SUBVERSION > 0 + { +#ifdef DEVELOP // Development -- show revision / branch info + V_DrawThinString(vid.dupx, vid.height - 17*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, compbranch); + V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, comprevision); +#else // Regular build V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, va("%s", VERSIONSTRING)); -#else // Trunk build, show revision info - V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, va("%s (%s)", VERSIONSTRING, comprevision)); #endif + } } } @@ -2820,7 +2826,7 @@ static void M_DrawSlider(INT32 x, INT32 y, const consvar_t *cv) void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines) { // Solid color textbox. - V_DrawFill(x+5, y+5, width*8+6, boxlines*8+6, 239); + V_DrawFill(x+5, y+5, width*8+6, boxlines*8+6, 159); //V_DrawFill(x+8, y+8, width*8, boxlines*8, 31); /* patch_t *p; @@ -4745,7 +4751,7 @@ static void M_SetupChoosePlayer(INT32 choice) if (Playing() == false) { S_StopMusic(); - S_ChangeMusic(mus_chrsel, true); + S_ChangeMusicInternal("chrsel", true); } SP_PlayerDef.prevMenu = currentMenu; @@ -5196,7 +5202,7 @@ void M_DrawTimeAttackMenu(void) lumpnum_t lumpnum; char beststr[40]; - S_ChangeMusic(mus_racent, true); // Eww, but needed for when user hits escape during demo playback + S_ChangeMusicInternal("racent", true); // Eww, but needed for when user hits escape during demo playback V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); @@ -5359,7 +5365,7 @@ static void M_TimeAttack(INT32 choice) itemOn = tastart; // "Start" is selected. G_SetGamestate(GS_TIMEATTACK); - S_ChangeMusic(mus_racent, true); + S_ChangeMusicInternal("racent", true); } // Drawing function for Nights Attack @@ -5369,7 +5375,7 @@ void M_DrawNightsAttackMenu(void) lumpnum_t lumpnum; char beststr[40]; - S_ChangeMusic(mus_racent, true); // Eww, but needed for when user hits escape during demo playback + S_ChangeMusicInternal("racent", true); // Eww, but needed for when user hits escape during demo playback V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); @@ -5492,7 +5498,7 @@ static void M_NightsAttack(INT32 choice) itemOn = nastart; // "Start" is selected. G_SetGamestate(GS_TIMEATTACK); - S_ChangeMusic(mus_racent, true); + S_ChangeMusicInternal("racent", true); } // Player has selected the "START" from the nights attack screen @@ -5726,7 +5732,7 @@ static void M_ModeAttackEndGame(INT32 choice) itemOn = currentMenu->lastOn; G_SetGamestate(GS_TIMEATTACK); modeattacking = ATTACKING_NONE; - S_ChangeMusic(mus_racent, true); + S_ChangeMusicInternal("racent", true); // Update replay availability. CV_AddValue(&cv_nextmap, 1); CV_AddValue(&cv_nextmap, -1); @@ -6068,7 +6074,7 @@ static void M_RoomMenu(INT32 choice) for (i = 0; room_list[i].header.buffer[0]; i++) { - if(room_list[i].name != '\0') + if(*room_list[i].name != '\0') { MP_RoomMenu[i+1].text = room_list[i].name; roomIds[i] = room_list[i].id; @@ -6932,7 +6938,7 @@ static void M_ToggleDigital(void) if (nodigimusic) return; S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); S_StopMusic(); - S_ChangeMusic(mus_lclear, false); + S_ChangeMusicInternal("lclear", false); M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING); } else @@ -6959,7 +6965,7 @@ static void M_ToggleMIDI(void) I_InitMIDIMusic(); if (nomidimusic) return; S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); - S_ChangeMusic(mus_lclear, false); + S_ChangeMusicInternal("lclear", false); M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING); } else diff --git a/src/m_misc.c b/src/m_misc.c index 57b8c4585..22effdddf 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -677,7 +677,7 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png else snprintf(maptext, 8, "Unknown"); - if (gamestate == GS_LEVEL && mapheaderinfo[gamemap-1]->lvlttl) + if (gamestate == GS_LEVEL && mapheaderinfo[gamemap-1]->lvlttl[0] != '\0') snprintf(lvlttltext, 48, "%s%s%s", mapheaderinfo[gamemap-1]->lvlttl, (mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE", @@ -1800,16 +1800,14 @@ UINT8 M_HighestBit(UINT32 num) const char *GetRevisionString(void) { - INT32 vinfo; - static char rev[8] = {0}; + static char rev[9] = {0}; if (rev[0]) return rev; - vinfo = atoi(&comprevision[1]); - if (vinfo) - snprintf(rev, 7, "r%d", vinfo); + if (comprevision[0] == 'r') + strncpy(rev, comprevision, 7); else - strcpy(rev, "rNULL"); + snprintf(rev, 7, "r%s", comprevision); rev[7] = '\0'; return rev; diff --git a/src/p_enemy.c b/src/p_enemy.c index 303e74880..373190cfe 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3063,12 +3063,8 @@ void A_Invincibility(mobj_t *actor) { S_StopMusic(); if (mariomode) - { - S_ChangeMusic(mus_minvnc, false); G_GhostAddColor(GHC_INVINCIBLE); - } - else - S_ChangeMusic(mus_invinc, false); + S_ChangeMusicInternal((mariomode) ? "minvnc" : "invinc", false); } } @@ -3104,7 +3100,7 @@ void A_SuperSneakers(mobj_t *actor) else { S_StopMusic(); - S_ChangeMusic(mus_shoes, false); + S_ChangeMusicInternal("shoes", false); } } } @@ -5606,8 +5602,13 @@ void A_MixUp(mobj_t *actor) P_SetThingPosition(players[i].mo); +#ifdef ESLOPE + players[i].mo->floorz = P_GetFloorZ(players[i].mo, players[i].mo->subsector->sector, players[i].mo->x, players[i].mo->y, NULL); + players[i].mo->ceilingz = P_GetCeilingZ(players[i].mo, players[i].mo->subsector->sector, players[i].mo->x, players[i].mo->y, NULL); +#else players[i].mo->floorz = players[i].mo->subsector->sector->floorheight; players[i].mo->ceilingz = players[i].mo->subsector->sector->ceilingheight; +#endif P_CheckPosition(players[i].mo, players[i].mo->x, players[i].mo->y); } @@ -6357,7 +6358,7 @@ void A_Boss2PogoTarget(mobj_t *actor) if (actor->info->missilestate) // spawn the pogo stick collision box { - mobj_t *pogo = P_SpawnMobj(actor->x, actor->y, actor->z - mobjinfo[actor->info->missilestate].height, actor->info->missilestate); + mobj_t *pogo = P_SpawnMobj(actor->x, actor->y, actor->z - mobjinfo[actor->info->missilestate].height, (mobjtype_t)actor->info->missilestate); pogo->target = actor; } @@ -7592,48 +7593,35 @@ void A_SetTargetsTarget(mobj_t *actor) { INT32 locvar1 = var1; INT32 locvar2 = var2; - mobj_t *targetedmobj = NULL; - thinker_t *th; - mobj_t *mo2; + mobj_t *oldtarg = NULL, *newtarg = NULL; #ifdef HAVE_BLUA if (LUA_CallAction("A_SetTargetsTarget", actor)) return; #endif - if ((!locvar1 && (!actor->target)) || (locvar1 && (!actor->tracer))) + // actor's target + if (locvar1) // or tracer + oldtarg = actor->tracer; + else + oldtarg = actor->target; + + if (P_MobjWasRemoved(oldtarg)) return; - if ((!locvar1 && !locvar2 && (!actor->target->target)) - || (!locvar1 && locvar2 && (!actor->target->tracer)) - || (locvar1 && !locvar2 && (!actor->tracer->target)) - || (locvar1 && locvar2 && (!actor->tracer->tracer))) - return; // Don't search for nothing. - - // scan the thinkers - for (th = thinkercap.next; th != &thinkercap; th = th->next) - { - if (th->function.acp1 != (actionf_p1)P_MobjThinker) - continue; - - mo2 = (mobj_t *)th; - - if ((!locvar1 && !locvar2 && (mo2 == actor->target->target)) - || (!locvar1 && locvar2 && (mo2 == actor->target->tracer)) - || (locvar1 && !locvar2 && (mo2 == actor->tracer->target)) - || (locvar1 && locvar2 && (mo2 == actor->tracer->tracer))) - { - targetedmobj = mo2; - break; - } - } - - if (!targetedmobj) - return; // Oops, nothing found.. - - if (!locvar1) - P_SetTarget(&actor->target, targetedmobj); + // actor's target's target! + if (locvar2) // or tracer + newtarg = oldtarg->tracer; else - P_SetTarget(&actor->tracer, targetedmobj); + newtarg = oldtarg->target; + + if (P_MobjWasRemoved(newtarg)) + return; + + // set actor's new target + if (locvar1) // or tracer + P_SetTarget(&actor->tracer, newtarg); + else + P_SetTarget(&actor->target, newtarg); } // Function: A_SetObjectFlags diff --git a/src/p_floor.c b/src/p_floor.c index fd85fd2cc..ec52abeb9 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1174,12 +1174,15 @@ void T_SpikeSector(levelspecthink_t *spikes) if (affectsec == spikes->sector) // Applied to an actual sector { + fixed_t affectfloor = P_GetSpecialBottomZ(thing, affectsec, affectsec); + fixed_t affectceil = P_GetSpecialTopZ(thing, affectsec, affectsec); + if (affectsec->flags & SF_FLIPSPECIAL_FLOOR) { if (!(thing->eflags & MFE_VERTICALFLIP) && thing->momz > 0) continue; - if (thing->z == affectsec->floorheight) + if (thing->z == affectfloor) dothepain = true; } @@ -1188,18 +1191,20 @@ void T_SpikeSector(levelspecthink_t *spikes) if ((thing->eflags & MFE_VERTICALFLIP) && thing->momz < 0) continue; - if (thing->z + thing->height == affectsec->ceilingheight) + if (thing->z + thing->height == affectceil) dothepain = true; } } else { + fixed_t affectfloor = P_GetSpecialBottomZ(thing, affectsec, spikes->sector); + fixed_t affectceil = P_GetSpecialTopZ(thing, affectsec, spikes->sector); if (affectsec->flags & SF_FLIPSPECIAL_FLOOR) { if (!(thing->eflags & MFE_VERTICALFLIP) && thing->momz > 0) continue; - if (thing->z == affectsec->ceilingheight) + if (thing->z == affectceil) dothepain = true; } @@ -1208,7 +1213,7 @@ void T_SpikeSector(levelspecthink_t *spikes) if ((thing->eflags & MFE_VERTICALFLIP) && thing->momz < 0) continue; - if (thing->z + thing->height == affectsec->floorheight) + if (thing->z + thing->height == affectfloor) dothepain = true; } } @@ -2085,6 +2090,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime) boolean FOFsector = false; boolean inAndOut = false; boolean floortouch = false; + fixed_t bottomheight, topheight; for (i = 0; i < MAXPLAYERS; i++) { @@ -2149,10 +2155,13 @@ void T_EachTimeThinker(levelspecthink_t *eachtime) if (players[j].mo->subsector->sector != targetsec) continue; - if (players[j].mo->z > sec->ceilingheight) + topheight = P_GetSpecialTopZ(players[j].mo, sec, targetsec); + bottomheight = P_GetSpecialBottomZ(players[j].mo, sec, targetsec); + + if (players[j].mo->z > topheight) continue; - if (players[j].mo->z + players[j].mo->height < sec->floorheight) + if (players[j].mo->z + players[j].mo->height < bottomheight) continue; if (floortouch == true && P_IsObjectOnGroundIn(players[j].mo, targetsec)) @@ -2312,7 +2321,7 @@ void T_RaiseSector(levelspecthink_t *raise) if (raise->vars[1] && !(thing->player->pflags & PF_STARTDASH)) continue; - if (!(thing->z == raise->sector->ceilingheight)) + if (!(thing->z == P_GetSpecialTopZ(thing, raise->sector, sector))) continue; playeronme = true; diff --git a/src/p_inter.c b/src/p_inter.c index d5eff8d2a..2a6c0bd21 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -472,7 +472,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if ((maptol & TOL_NIGHTS) && special->type != MT_FLINGCOIN) P_DoNightsScore(player); break; -#ifdef BLUE_SPHERES case MT_BLUEBALL: if (!(P_CanPickupItem(player, false))) return; @@ -489,7 +488,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (maptol & TOL_NIGHTS) P_DoNightsScore(player); break; -#endif case MT_AUTOPICKUP: case MT_BOUNCEPICKUP: case MT_SCATTERPICKUP: @@ -837,10 +835,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } if (!(mo2->type == MT_NIGHTSWING || mo2->type == MT_RING || mo2->type == MT_COIN -#ifdef BLUE_SPHERES - || mo2->type == MT_BLUEBALL -#endif - )) + || mo2->type == MT_BLUEBALL)) continue; // Yay! The thing's in reach! Pull it in! @@ -1408,6 +1403,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } else player->pflags |= PF_ITEMHANG; + + // Can't jump first frame + player->pflags |= PF_JUMPSTASIS; return; case MT_BIGMINE: case MT_BIGAIRMINE: @@ -1719,11 +1717,126 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour CONS_Printf(str, targetname, deadtarget ? M_GetText("killed") : M_GetText("hit")); } +/** Checks if the level timer is over the timelimit and the round should end, + * unless you are in overtime. In which case leveltime may stretch out beyond + * timelimitintics and overtime's status will be checked here each tick. + * Verify that the value of ::cv_timelimit is greater than zero before + * calling this function. + * + * \sa cv_timelimit, P_CheckPointLimit, P_UpdateSpecials + */ +void P_CheckTimeLimit(void) +{ + INT32 i, k; + + if (!cv_timelimit.value) + return; + + if (!(multiplayer || netgame)) + return; + + if (G_PlatformGametype()) + return; + + if (leveltime < timelimitintics) + return; + + if (gameaction == ga_completed) + return; + + //Tagmode round end but only on the tic before the + //XD_EXITLEVEL packet is recieved by all players. + if (G_TagGametype()) + { + if (leveltime == (timelimitintics + 1)) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator + || (players[i].pflags & PF_TAGGED) || (players[i].pflags & PF_TAGIT)) + continue; + + CONS_Printf(M_GetText("%s recieved double points for surviving the round.\n"), player_names[i]); + P_AddPlayerScore(&players[i], players[i].score); + } + } + + if (server) + SendNetXCmd(XD_EXITLEVEL, NULL, 0); + } + + //Optional tie-breaker for Match/CTF + else if (cv_overtime.value) + { + INT32 playerarray[MAXPLAYERS]; + INT32 tempplayer = 0; + INT32 spectators = 0; + INT32 playercount = 0; + + //Figure out if we have enough participating players to care. + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && players[i].spectator) + spectators++; + } + + if ((D_NumPlayers() - spectators) > 1) + { + // Play the starpost sfx after the first second of overtime. + if (gamestate == GS_LEVEL && (leveltime == (timelimitintics + TICRATE))) + S_StartSound(NULL, sfx_strpst); + + // Normal Match + if (!G_GametypeHasTeams()) + { + //Store the nodes of participating players in an array. + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && !players[i].spectator) + { + playerarray[playercount] = i; + playercount++; + } + } + + //Sort 'em. + for (i = 1; i < playercount; i++) + { + for (k = i; k < playercount; k++) + { + if (players[playerarray[i-1]].score < players[playerarray[k]].score) + { + tempplayer = playerarray[i-1]; + playerarray[i-1] = playerarray[k]; + playerarray[k] = tempplayer; + } + } + } + + //End the round if the top players aren't tied. + if (players[playerarray[0]].score == players[playerarray[1]].score) + return; + } + else + { + //In team match and CTF, determining a tie is much simpler. =P + if (redscore == bluescore) + return; + } + } + if (server) + SendNetXCmd(XD_EXITLEVEL, NULL, 0); + } + + if (server) + SendNetXCmd(XD_EXITLEVEL, NULL, 0); +} + /** Checks if a player's score is over the pointlimit and the round should end. * Verify that the value of ::cv_pointlimit is greater than zero before * calling this function. * - * \sa cv_pointlimit, P_UpdateSpecials + * \sa cv_pointlimit, P_CheckTimeLimit, P_UpdateSpecials */ void P_CheckPointLimit(void) { @@ -2037,7 +2150,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (P_IsLocalPlayer(target->player) && target->player == &players[consoleplayer]) { S_StopMusic(); // Stop the Music! Tails 03-14-2000 - S_ChangeMusic(mus_gmover, false); // Yousa dead now, Okieday? Tails 03-14-2000 + S_ChangeMusicInternal("gmover", false); // Yousa dead now, Okieday? Tails 03-14-2000 } } } @@ -2067,7 +2180,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget // allow them to try again, rather than sitting the whole thing out. if (leveltime >= hidetime * TICRATE) { - if (gametype == GT_HIDEANDSEEK)//suiciding in survivor makes you IT. + if (gametype == GT_TAG)//suiciding in survivor makes you IT. { target->player->pflags |= PF_TAGIT; CONS_Printf(M_GetText("%s is now IT!\n"), player_names[target->player-players]); // Tell everyone who is it! @@ -2433,7 +2546,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source) && player->nightstime < 10*TICRATE) { //S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH - S_ChangeMusic(mus_drown,false); + S_ChangeMusicInternal("drown",false); } } } diff --git a/src/p_local.h b/src/p_local.h index 30582ba1a..583f115ef 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -213,11 +213,29 @@ void P_RemoveSavegameMobj(mobj_t *th); boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state); boolean P_SetMobjState(mobj_t *mobj, statenum_t state); void P_RunShields(void); +void P_RunOverlays(void); void P_MobjThinker(mobj_t *mobj); boolean P_RailThinker(mobj_t *mobj); void P_PushableThinker(mobj_t *mobj); void P_SceneryThinker(mobj_t *mobj); + +fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect); +fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect); +#define P_GetFloorZ(mobj, sector, x, y, line) P_MobjFloorZ(mobj, sector, NULL, x, y, line, false, false) +#define P_GetCeilingZ(mobj, sector, x, y, line) P_MobjCeilingZ(mobj, sector, NULL, x, y, line, true, false) +#define P_GetFOFTopZ(mobj, sector, fof, x, y, line) P_MobjCeilingZ(mobj, sectors + fof->secnum, sector, x, y, line, false, false) +#define P_GetFOFBottomZ(mobj, sector, fof, x, y, line) P_MobjFloorZ(mobj, sectors + fof->secnum, sector, x, y, line, true, false) +#define P_GetSpecialBottomZ(mobj, src, bound) P_MobjFloorZ(mobj, src, bound, mobj->x, mobj->y, NULL, src != bound, true) +#define P_GetSpecialTopZ(mobj, src, bound) P_MobjCeilingZ(mobj, src, bound, mobj->x, mobj->y, NULL, src == bound, true) + +fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect); +fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect); +#define P_CameraGetFloorZ(mobj, sector, x, y, line) P_CameraFloorZ(mobj, sector, NULL, x, y, line, false, false) +#define P_CameraGetCeilingZ(mobj, sector, x, y, line) P_CameraCeilingZ(mobj, sector, NULL, x, y, line, true, false) +#define P_CameraGetFOFTopZ(mobj, sector, fof, x, y, line) P_CameraCeilingZ(mobj, sectors + fof->secnum, sector, x, y, line, false, false) +#define P_CameraGetFOFBottomZ(mobj, sector, fof, x, y, line) P_CameraFloorZ(mobj, sectors + fof->secnum, sector, x, y, line, true, false) + boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover); boolean P_CheckDeathPitCollide(mobj_t *mo); boolean P_CheckSolidLava(mobj_t *mo, ffloor_t *rover); @@ -279,6 +297,11 @@ extern fixed_t tmfloorz; extern fixed_t tmceilingz; extern mobj_t *tmfloorthing, *tmhitthing, *tmthing; extern camera_t *mapcampointer; +extern fixed_t tmx; +extern fixed_t tmy; +#ifdef ESLOPE +extern pslope_t *tmfloorslope, *tmceilingslope; +#endif /* cphipps 2004/08/30 */ extern void P_MapStart(void); @@ -317,7 +340,7 @@ void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist); fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height); boolean PIT_PushableMoved(mobj_t *thing); -void P_DoSpring(mobj_t *spring, mobj_t *object); +boolean P_DoSpring(mobj_t *spring, mobj_t *object); // // P_SETUP @@ -377,6 +400,7 @@ void P_PlayerEmeraldBurst(player_t *player, boolean toss); void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck); void P_PlayerFlagBurst(player_t *player, boolean toss); +void P_CheckTimeLimit(void); void P_CheckPointLimit(void); void P_CheckSurvivors(void); boolean P_CheckRacers(void); diff --git a/src/p_map.c b/src/p_map.c index 99a408569..e603aaa75 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -27,6 +27,10 @@ #include "r_splats.h" +#ifdef ESLOPE +#include "p_slopes.h" +#endif + #include "z_zone.h" #include "lua_hook.h" @@ -34,8 +38,8 @@ fixed_t tmbbox[4]; mobj_t *tmthing; static INT32 tmflags; -static fixed_t tmx; -static fixed_t tmy; +fixed_t tmx; +fixed_t tmy; static precipmobj_t *tmprecipthing; static fixed_t preciptmbbox[4]; @@ -48,6 +52,9 @@ fixed_t tmfloorz, tmceilingz; static fixed_t tmdropoffz, tmdrpoffceilz; // drop-off floor/ceiling heights mobj_t *tmfloorthing; // the thing corresponding to tmfloorz or NULL if tmfloorz is from a sector mobj_t *tmhitthing; // the solid thing you bumped into (for collisions) +#ifdef ESLOPE +pslope_t *tmfloorslope, *tmceilingslope; +#endif // keep track of the line that lowers the ceiling, // so missiles don't explode against sky hack walls @@ -102,7 +109,7 @@ boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z) // MOVEMENT ITERATOR FUNCTIONS // ========================================================================= -void P_DoSpring(mobj_t *spring, mobj_t *object) +boolean P_DoSpring(mobj_t *spring, mobj_t *object) { INT32 pflags; fixed_t offx, offy; @@ -110,16 +117,16 @@ void P_DoSpring(mobj_t *spring, mobj_t *object) fixed_t horizspeed = spring->info->damage; if (object->eflags & MFE_SPRUNG) // Object was already sprung this tic - return; + return false; // Spectators don't trigger springs. if (object->player && object->player->spectator) - return; + return false; if (object->player && (object->player->pflags & PF_NIGHTSMODE)) { /*Someone want to make these work like bumpers?*/ - return; + return false; } object->eflags |= MFE_SPRUNG; // apply this flag asap! @@ -192,7 +199,7 @@ void P_DoSpring(mobj_t *spring, mobj_t *object) P_ResetPlayer(object->player); if (P_MobjFlip(object)*vertispeed > 0) - P_SetPlayerMobjState(object, S_PLAY_JUMP); + P_SetPlayerMobjState(object, S_PLAY_SPRING); else if (P_MobjFlip(object)*vertispeed < 0) P_SetPlayerMobjState(object, S_PLAY_FALL); else // horizontal spring @@ -206,9 +213,10 @@ void P_DoSpring(mobj_t *spring, mobj_t *object) if (spring->info->painchance) { object->player->pflags |= PF_JUMPED; - P_SetPlayerMobjState(object, S_PLAY_SPIN); + P_SetPlayerMobjState(object, S_PLAY_JUMP); } } + return true; } static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object) @@ -365,6 +373,7 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) static boolean PIT_CheckThing(mobj_t *thing) { fixed_t blockdist; + boolean iwassprung = false; // don't clip against self if (thing == tmthing) @@ -494,7 +503,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; // overhead if (thing->z + thing->height < tmthing->z) return true; // underneath - if (tmthing->player && tmthing->flags & MF_SHOOTABLE) + if (tmthing->player && tmthing->flags & MF_SHOOTABLE && thing->health > 0) { UINT8 damagetype = 0; if (thing->flags & MF_FIRE) // BURN! @@ -510,7 +519,7 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; // overhead if (tmthing->z + tmthing->height < thing->z) return true; // underneath - if (thing->player && thing->flags & MF_SHOOTABLE) + if (thing->player && thing->flags & MF_SHOOTABLE && tmthing->health > 0) { UINT8 damagetype = 0; if (tmthing->flags & MF_FIRE) // BURN! @@ -829,7 +838,7 @@ static boolean PIT_CheckThing(mobj_t *thing) { if ( thing->z <= tmthing->z + tmthing->height && tmthing->z <= thing->z + thing->height) - P_DoSpring(thing, tmthing); + iwassprung = P_DoSpring(thing, tmthing); } } @@ -916,7 +925,7 @@ static boolean PIT_CheckThing(mobj_t *thing) { if ( thing->z <= tmthing->z + tmthing->height && tmthing->z <= thing->z + thing->height) - P_DoSpring(thing, tmthing); + iwassprung = P_DoSpring(thing, tmthing); } // Are you touching the side of the object you're interacting with? else if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height @@ -938,12 +947,14 @@ static boolean PIT_CheckThing(mobj_t *thing) } } - - if (thing->flags & MF_SPRING && (tmthing->player || tmthing->flags & MF_PUSHABLE)); - else + if (thing->flags & MF_SPRING && (tmthing->player || tmthing->flags & MF_PUSHABLE)) + { + if (iwassprung) // this spring caused you to gain MFE_SPRUNG just now... + return false; // "cancel" P_TryMove via blocking so you keep your current position + } // Monitors are not treated as solid to players who are jumping, spinning or gliding, // unless it's a CTF team monitor and you're on the wrong team - if (thing->flags & MF_MONITOR && tmthing->player && tmthing->player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING) + else if (thing->flags & MF_MONITOR && tmthing->player && tmthing->player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING) && !((thing->type == MT_REDRINGBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_BLUERINGBOX && tmthing->player->ctfteam != 2))) ; // z checking at last @@ -963,6 +974,9 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->z + thing->height > tmfloorz) { tmfloorz = thing->z + thing->height; +#ifdef ESLOPE + tmfloorslope = NULL; +#endif } return true; } @@ -981,6 +995,9 @@ static boolean PIT_CheckThing(mobj_t *thing) else if (topz < tmceilingz && tmthing->z+tmthing->height <= thing->z+thing->height) { tmceilingz = topz; +#ifdef ESLOPE + tmceilingslope = NULL; +#endif tmfloorthing = thing; // thing we may stand on } } @@ -994,6 +1011,9 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->z < tmceilingz) { tmceilingz = thing->z; +#ifdef ESLOPE + tmceilingslope = NULL; +#endif } return true; } @@ -1011,6 +1031,9 @@ static boolean PIT_CheckThing(mobj_t *thing) else if (topz > tmfloorz && tmthing->z >= thing->z) { tmfloorz = topz; +#ifdef ESLOPE + tmfloorslope = NULL; +#endif tmfloorthing = thing; // thing we may stand on } } @@ -1133,11 +1156,13 @@ static boolean PIT_CheckLine(line_t *ld) { tmceilingz = opentop; ceilingline = ld; + tmceilingslope = opentopslope; } if (openbottom > tmfloorz) { tmfloorz = openbottom; + tmfloorslope = openbottomslope; } if (highceiling > tmdrpoffceilz) @@ -1214,8 +1239,12 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) // that contains the point. // Any contacted lines the step closer together // will adjust them. - tmfloorz = tmdropoffz = newsubsec->sector->floorheight; - tmceilingz = tmdrpoffceilz = newsubsec->sector->ceilingheight; + tmfloorz = tmdropoffz = P_GetFloorZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->floorheight; + tmceilingz = P_GetCeilingZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->ceilingheight; +#ifdef ESLOPE + tmfloorslope = newsubsec->sector->f_slope; + tmceilingslope = newsubsec->sector->c_slope; +#endif // Check list of fake floors and see if tmfloorz/tmceilingz need to be altered. if (newsubsec->sector->ffloors) @@ -1226,35 +1255,48 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) for (rover = newsubsec->sector->ffloors; rover; rover = rover->next) { + fixed_t topheight, bottomheight; + if (!(rover->flags & FF_EXISTS)) continue; + topheight = P_GetFOFTopZ(thing, newsubsec->sector, rover, x, y, NULL); + bottomheight = P_GetFOFBottomZ(thing, newsubsec->sector, rover, x, y, NULL); + if (rover->flags & FF_GOOWATER && !(thing->flags & MF_NOGRAVITY)) { // If you're inside goowater and slowing down fixed_t sinklevel = FixedMul(thing->info->height/6, thing->scale); fixed_t minspeed = FixedMul(thing->info->height/9, thing->scale); - if (thing->z < *rover->topheight && *rover->bottomheight < thingtop + if (thing->z < topheight && bottomheight < thingtop && abs(thing->momz) < minspeed) { // Oh no! The object is stick in between the surface of the goo and sinklevel! help them out! - if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z > *rover->topheight - sinklevel + if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z > topheight - sinklevel && thing->momz >= 0 && thing->momz < (minspeed>>2)) thing->momz += minspeed>>2; - else if (thing->eflags & MFE_VERTICALFLIP && thingtop < *rover->bottomheight + sinklevel + else if (thing->eflags & MFE_VERTICALFLIP && thingtop < bottomheight + sinklevel && thing->momz <= 0 && thing->momz > -(minspeed>>2)) thing->momz -= minspeed>>2; // Land on the top or the bottom, depending on gravity flip. - if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z >= *rover->topheight - sinklevel && thing->momz <= 0) + if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z >= topheight - sinklevel && thing->momz <= 0) { - if (tmfloorz < *rover->topheight - sinklevel) - tmfloorz = *rover->topheight - sinklevel; + if (tmfloorz < topheight - sinklevel) { + tmfloorz = topheight - sinklevel; +#ifdef ESLOPE + tmfloorslope = *rover->t_slope; +#endif + } } - else if (thing->eflags & MFE_VERTICALFLIP && thingtop <= *rover->bottomheight + sinklevel && thing->momz >= 0) + else if (thing->eflags & MFE_VERTICALFLIP && thingtop <= bottomheight + sinklevel && thing->momz >= 0) { - if (tmceilingz > *rover->bottomheight + sinklevel) - tmceilingz = *rover->bottomheight + sinklevel; + if (tmceilingz > bottomheight + sinklevel) { + tmceilingz = bottomheight + sinklevel; +#ifdef ESLOPE + tmceilingslope = *rover->b_slope; +#endif + } } } continue; @@ -1271,30 +1313,40 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) if (rover->flags & FF_QUICKSAND) { - if (thing->z < *rover->topheight && *rover->bottomheight < thingtop) + if (thing->z < topheight && bottomheight < thingtop) { - if (tmfloorz < thing->z) + if (tmfloorz < thing->z) { tmfloorz = thing->z; +#ifdef ESLOPE + tmfloorslope = NULL; +#endif + } } // Quicksand blocks never change heights otherwise. continue; } - delta1 = thing->z - (*rover->bottomheight - + ((*rover->topheight - *rover->bottomheight)/2)); - delta2 = thingtop - (*rover->bottomheight - + ((*rover->topheight - *rover->bottomheight)/2)); + delta1 = thing->z - (bottomheight + + ((topheight - bottomheight)/2)); + delta2 = thingtop - (bottomheight + + ((topheight - bottomheight)/2)); - if (*rover->topheight > tmfloorz && abs(delta1) < abs(delta2) + if (topheight > tmfloorz && abs(delta1) < abs(delta2) && !(rover->flags & FF_REVERSEPLATFORM)) { - tmfloorz = tmdropoffz = *rover->topheight; + tmfloorz = tmdropoffz = topheight; +#ifdef ESLOPE + tmfloorslope = *rover->t_slope; +#endif } - if (*rover->bottomheight < tmceilingz && abs(delta1) >= abs(delta2) + if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2) && !(rover->flags & FF_PLATFORM) && !(thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE))) { - tmceilingz = tmdrpoffceilz = *rover->bottomheight; + tmceilingz = tmdrpoffceilz = bottomheight; +#ifdef ESLOPE + tmceilingslope = *rover->b_slope; +#endif } } } @@ -1367,11 +1419,19 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) delta1 = thing->z - (polybottom + ((polytop - polybottom)/2)); delta2 = thingtop - (polybottom + ((polytop - polybottom)/2)); - if (polytop > tmfloorz && abs(delta1) < abs(delta2)) + if (polytop > tmfloorz && abs(delta1) < abs(delta2)) { tmfloorz = tmdropoffz = polytop; +#ifdef ESLOPE + tmfloorslope = NULL; +#endif + } - if (polybottom < tmceilingz && abs(delta1) >= abs(delta2)) + if (polybottom < tmceilingz && abs(delta1) >= abs(delta2)) { tmceilingz = tmdrpoffceilz = polybottom; +#ifdef ESLOPE + tmceilingslope = NULL; +#endif + } } plink = (polymaplink_t *)(plink->link.next); } @@ -1473,8 +1533,9 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) // that contains the point. // Any contacted lines the step closer together // will adjust them. - tmfloorz = tmdropoffz = newsubsec->sector->floorheight; - tmceilingz = tmdrpoffceilz = newsubsec->sector->ceilingheight; + tmfloorz = tmdropoffz = P_CameraGetFloorZ(thiscam, newsubsec->sector, x, y, NULL); + + tmceilingz = P_CameraGetCeilingZ(thiscam, newsubsec->sector, x, y, NULL); // Cameras use the heightsec's heights rather then the actual sector heights. // If you can see through it, why not move the camera through it too? @@ -1500,20 +1561,24 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam) for (rover = newsubsec->sector->ffloors; rover; rover = rover->next) { + fixed_t topheight, bottomheight; if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12) continue; - delta1 = thiscam->z - (*rover->bottomheight - + ((*rover->topheight - *rover->bottomheight)/2)); - delta2 = thingtop - (*rover->bottomheight - + ((*rover->topheight - *rover->bottomheight)/2)); - if (*rover->topheight > tmfloorz && abs(delta1) < abs(delta2)) + topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, x, y, NULL); + bottomheight = P_CameraGetFOFBottomZ(thiscam, newsubsec->sector, rover, x, y, NULL); + + delta1 = thiscam->z - (bottomheight + + ((topheight - bottomheight)/2)); + delta2 = thingtop - (bottomheight + + ((topheight - bottomheight)/2)); + if (topheight > tmfloorz && abs(delta1) < abs(delta2)) { - tmfloorz = tmdropoffz = *rover->topheight; + tmfloorz = tmdropoffz = topheight; } - if (*rover->bottomheight < tmceilingz && abs(delta1) >= abs(delta2)) + if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2)) { - tmceilingz = tmdrpoffceilz = *rover->bottomheight; + tmceilingz = tmdrpoffceilz = bottomheight; } } } @@ -1708,8 +1773,8 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam) } else { - tmfloorz = thiscam->subsector->sector->floorheight; - tmceilingz = thiscam->subsector->sector->ceilingheight; + tmfloorz = P_CameraGetFloorZ(thiscam, thiscam->subsector->sector, x, y, NULL); + tmceilingz = P_CameraGetCeilingZ(thiscam, thiscam->subsector->sector, x, y, NULL); } // the move is ok, @@ -1775,6 +1840,10 @@ boolean PIT_PushableMoved(mobj_t *thing) mobj_t *oldthing = tmthing; line_t *oldceilline = ceilingline; line_t *oldblockline = blockingline; +#ifdef ESLOPE + pslope_t *oldfslope = tmfloorslope; + pslope_t *oldcslope = tmceilingslope; +#endif // Move the player P_TryMove(thing, thing->x+stand->momx, thing->y+stand->momy, true); @@ -1787,6 +1856,10 @@ boolean PIT_PushableMoved(mobj_t *thing) P_SetTarget(&tmthing, oldthing); ceilingline = oldceilline; blockingline = oldblockline; +#ifdef ESLOPE + tmfloorslope = oldfslope; + tmceilingslope = oldcslope; +#endif thing->momz = stand->momz; } else @@ -1808,6 +1881,9 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) fixed_t tryy = thing->y; fixed_t radius = thing->radius; fixed_t thingtop = thing->z + thing->height; +#ifdef ESLOPE + fixed_t startingonground = P_IsObjectOnGround(thing); +#endif floatok = false; if (radius < MAXRADIUS/2) @@ -1853,7 +1929,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) // Don't 'step up' while springing, // Only step up "if needed". - if (thing->player->panim == PA_JUMP + if (thing->player->panim == PA_SPRING && P_MobjFlip(thing)*thing->momz > FixedMul(FRACUNIT, thing->scale)) maxstep = 0; } @@ -1896,13 +1972,23 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) { if (thingtop == thing->ceilingz && tmceilingz > thingtop && tmceilingz - thingtop <= maxstep) { - thing->z = tmceilingz - thing->height; + thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height; + thing->eflags |= MFE_JUSTSTEPPEDDOWN; + } + else if (tmceilingz < thingtop && thingtop - tmceilingz <= maxstep) + { + thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height; thing->eflags |= MFE_JUSTSTEPPEDDOWN; } } else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep) { - thing->z = tmfloorz; + thing->z = thing->floorz = tmfloorz; + thing->eflags |= MFE_JUSTSTEPPEDDOWN; + } + else if (tmfloorz > thing->z && tmfloorz - thing->z <= maxstep) + { + thing->z = thing->floorz = tmfloorz; thing->eflags |= MFE_JUSTSTEPPEDDOWN; } } @@ -1973,6 +2059,25 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) thing->floorz = tmfloorz; thing->ceilingz = tmceilingz; + +#ifdef ESLOPE + // Assign thing's standingslope if needed + if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP)) { + if (!startingonground && tmfloorslope) + P_HandleSlopeLanding(thing, tmfloorslope); + + if (thing->momz <= 0) + thing->standingslope = tmfloorslope; + } + else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) { + if (!startingonground && tmceilingslope) + P_HandleSlopeLanding(thing, tmceilingslope); + + if (thing->momz >= 0) + thing->standingslope = tmceilingslope; + } +#endif + thing->x = x; thing->y = y; @@ -1988,6 +2093,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y) { fixed_t tryx, tryy; + tryx = thing->x; tryy = thing->y; do { @@ -2310,15 +2416,25 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) { fixed_t platx, platy; subsector_t *glidesector; + fixed_t floorz, ceilingz; platx = P_ReturnThrustX(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); platy = P_ReturnThrustY(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy); +#ifdef ESLOPE + floorz = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) : glidesector->sector->floorheight; + ceilingz = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) : glidesector->sector->ceilingheight; +#else + floorz = glidesector->sector->floorheight; + ceilingz = glidesector->sector->ceilingheight; +#endif + if (glidesector->sector != player->mo->subsector->sector) { boolean floorclimb = false; + fixed_t topheight, bottomheight; if (glidesector->sector->ffloors) { @@ -2328,34 +2444,44 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER)) continue; + topheight = *rover->topheight; + bottomheight = *rover->bottomheight; + +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y); + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y); +#endif + floorclimb = true; if (player->mo->eflags & MFE_VERTICALFLIP) { - if ((*rover->topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < *rover->topheight)) + if ((topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < topheight)) { floorclimb = true; } - if (*rover->topheight < player->mo->z) // Waaaay below the ledge. + if (topheight < player->mo->z) // Waaaay below the ledge. { floorclimb = false; } - if (*rover->bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale)) + if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale)) { floorclimb = false; } } else { - if ((*rover->bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > *rover->bottomheight)) + if ((bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > bottomheight)) { floorclimb = true; } - if (*rover->bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge. + if (bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge. { floorclimb = false; } - if (*rover->topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale)) + if (topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale)) { floorclimb = false; } @@ -2368,30 +2494,30 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle) if (player->mo->eflags & MFE_VERTICALFLIP) { - if ((glidesector->sector->floorheight <= player->mo->z + player->mo->height) - && ((player->mo->z + player->mo->height - player->mo->momz) <= glidesector->sector->floorheight)) + if ((floorz <= player->mo->z + player->mo->height) + && ((player->mo->z + player->mo->height - player->mo->momz) <= floorz)) floorclimb = true; - if ((glidesector->sector->floorheight > player->mo->z) + if ((floorz > player->mo->z) && glidesector->sector->floorpic == skyflatnum) return false; - if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > glidesector->sector->ceilingheight) - || (player->mo->z + player->mo->height <= glidesector->sector->floorheight)) + if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > ceilingz) + || (player->mo->z + player->mo->height <= floorz)) floorclimb = true; } else { - if ((glidesector->sector->ceilingheight >= player->mo->z) - && ((player->mo->z - player->mo->momz) >= glidesector->sector->ceilingheight)) + if ((ceilingz >= player->mo->z) + && ((player->mo->z - player->mo->momz) >= ceilingz)) floorclimb = true; - if ((glidesector->sector->ceilingheight < player->mo->z+player->mo->height) + if ((ceilingz < player->mo->z+player->mo->height) && glidesector->sector->ceilingpic == skyflatnum) return false; - if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < glidesector->sector->floorheight) - || (player->mo->z >= glidesector->sector->ceilingheight)) + if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < ceilingz) + || (player->mo->z >= ceilingz)) floorclimb = true; } @@ -2463,6 +2589,7 @@ isblocking: line_t *checkline = li; sector_t *checksector; ffloor_t *rover; + fixed_t topheight, bottomheight; boolean fofline = false; INT32 side = P_PointOnLineSide(slidemo->x, slidemo->y, li); @@ -2478,13 +2605,23 @@ isblocking: if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) continue; - if (*rover->topheight < slidemo->z) + topheight = *rover->topheight; + bottomheight = *rover->bottomheight; + +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, slidemo->x, slidemo->y); + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, slidemo->x, slidemo->y); +#endif + + if (topheight < slidemo->z) continue; - if (*rover->bottomheight > slidemo->z + slidemo->height) + if (bottomheight > slidemo->z + slidemo->height) continue; - // Got this far, so I guess it's climbable. + // Got this far, so I guess it's climbable. // TODO: Climbing check, also, better method to do this? if (rover->master->flags & ML_TFERLINE) { size_t linenum = li-checksector->lines[0]; @@ -2509,8 +2646,8 @@ isblocking: climbangle += (ANGLE_90 * (whichside ? -1 : 1)); - if (((!slidemo->player->climbing && abs(slidemo->angle - ANGLE_90 - climbline) < ANGLE_45) - || (slidemo->player->climbing == 1 && abs(slidemo->angle - climbline) < ANGLE_135)) + if (((!slidemo->player->climbing && abs((slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45) + || (slidemo->player->climbing == 1 && abs((slidemo->angle - climbline)) < ANGLE_135)) && P_IsClimbingValid(slidemo->player, climbangle)) { slidemo->angle = climbangle; @@ -3104,6 +3241,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) if (thing->subsector->sector->ffloors && (realcrush || thing->flags & MF_PUSHABLE)) { ffloor_t *rover; + fixed_t topheight, bottomheight; fixed_t delta1, delta2; INT32 thingtop = thing->z + thing->height; @@ -3113,9 +3251,19 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush) || ((rover->flags & FF_BLOCKOTHERS) && !thing->player)) || !(rover->flags & FF_EXISTS)) continue; - delta1 = thing->z - (*rover->bottomheight + *rover->topheight)/2; - delta2 = thingtop - (*rover->bottomheight + *rover->topheight)/2; - if (*rover->bottomheight <= thing->ceilingz && abs(delta1) >= abs(delta2)) + topheight = *rover->topheight; + bottomheight = *rover->bottomheight; + +/*#ifdef ESLOPE + if (rover->t_slope) + topheight = P_GetZAt(rover->t_slope, thing->x, thing->y); + if (rover->b_slope) + bottomheight = P_GetZAt(rover->b_slope, thing->x, thing->y); +#endif*/ + + delta1 = thing->z - (bottomheight + topheight)/2; + delta2 = thingtop - (bottomheight + topheight)/2; + if (bottomheight <= thing->ceilingz && abs(delta1) >= abs(delta2)) { if (thing->flags & MF_PUSHABLE) { @@ -3786,7 +3934,7 @@ void P_MapEnd(void) } // P_FloorzAtPos -// Returns the floorz of the XYZ position +// Returns the floorz of the XYZ position // TODO: Need ceilingpos function too // Tails 05-26-2003 fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) { @@ -3801,15 +3949,26 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) for (rover = sec->ffloors; rover; rover = rover->next) { + fixed_t topheight, bottomheight; if (!(rover->flags & FF_EXISTS)) continue; if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE))) continue; + topheight = *rover->topheight; + bottomheight = *rover->bottomheight; + +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, x, y); + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, x, y); +#endif + if (rover->flags & FF_QUICKSAND) { - if (z < *rover->topheight && *rover->bottomheight < thingtop) + if (z < topheight && bottomheight < thingtop) { if (floorz < z) floorz = z; @@ -3817,10 +3976,10 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) continue; } - delta1 = z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)); - delta2 = thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)); - if (*rover->topheight > floorz && abs(delta1) < abs(delta2)) - floorz = *rover->topheight; + delta1 = z - (bottomheight + ((topheight - bottomheight)/2)); + delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2)); + if (topheight > floorz && abs(delta1) < abs(delta2)) + floorz = topheight; } } diff --git a/src/p_maputl.c b/src/p_maputl.c index a65d2fa76..8f349a2a9 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -20,6 +20,7 @@ #include "r_data.h" #include "p_maputl.h" #include "p_polyobj.h" +#include "p_slopes.h" #include "z_zone.h" // @@ -322,6 +323,9 @@ fixed_t P_InterceptVector(divline_t *v2, divline_t *v1) // OPTIMIZE: keep this precalculated // fixed_t opentop, openbottom, openrange, lowfloor, highceiling; +#ifdef ESLOPE +pslope_t *opentopslope, *openbottomslope; +#endif // P_CameraLineOpening // P_LineOpening, but for camera @@ -348,31 +352,56 @@ void P_CameraLineOpening(line_t *linedef) { frontfloor = sectors[front->camsec].floorheight; frontceiling = sectors[front->camsec].ceilingheight; +#ifdef ESLOPE + if (sectors[front->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) + frontfloor = P_GetZAt(sectors[front->camsec].f_slope, camera.x, camera.y); + if (sectors[front->camsec].c_slope) + frontceiling = P_GetZAt(sectors[front->camsec].c_slope, camera.x, camera.y); +#endif + } else if (front->heightsec >= 0) { frontfloor = sectors[front->heightsec].floorheight; frontceiling = sectors[front->heightsec].ceilingheight; +#ifdef ESLOPE + if (sectors[front->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) + frontfloor = P_GetZAt(sectors[front->heightsec].f_slope, camera.x, camera.y); + if (sectors[front->heightsec].c_slope) + frontceiling = P_GetZAt(sectors[front->heightsec].c_slope, camera.x, camera.y); +#endif } else { - frontfloor = front->floorheight; - frontceiling = front->ceilingheight; + frontfloor = P_CameraGetFloorZ(mapcampointer, front, tmx, tmy, linedef); + frontceiling = P_CameraGetCeilingZ(mapcampointer, front, tmx, tmy, linedef); } if (back->camsec >= 0) { backfloor = sectors[back->camsec].floorheight; backceiling = sectors[back->camsec].ceilingheight; +#ifdef ESLOPE + if (sectors[back->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) + frontfloor = P_GetZAt(sectors[back->camsec].f_slope, camera.x, camera.y); + if (sectors[back->camsec].c_slope) + frontceiling = P_GetZAt(sectors[back->camsec].c_slope, camera.x, camera.y); +#endif } else if (back->heightsec >= 0) { backfloor = sectors[back->heightsec].floorheight; backceiling = sectors[back->heightsec].ceilingheight; +#ifdef ESLOPE + if (sectors[back->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope) + frontfloor = P_GetZAt(sectors[back->heightsec].f_slope, camera.x, camera.y); + if (sectors[back->heightsec].c_slope) + frontceiling = P_GetZAt(sectors[back->heightsec].c_slope, camera.x, camera.y); +#endif } else { - backfloor = back->floorheight; - backceiling = back->ceilingheight; + backfloor = P_CameraGetFloorZ(mapcampointer, back, tmx, tmy, linedef); + backceiling = P_CameraGetCeilingZ(mapcampointer, back, tmx, tmy, linedef); } { @@ -414,40 +443,48 @@ void P_CameraLineOpening(line_t *linedef) if (front->ffloors) for (rover = front->ffloors; rover; rover = rover->next) { + fixed_t topheight, bottomheight; if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12) continue; - delta1 = abs(mapcampointer->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); - delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); - if (*rover->bottomheight < lowestceiling && delta1 >= delta2) - lowestceiling = *rover->bottomheight; - else if (*rover->bottomheight < highestceiling && delta1 >= delta2) - highestceiling = *rover->bottomheight; + topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tmx, tmy, linedef); + bottomheight = P_CameraGetFOFBottomZ(mapcampointer, front, rover, tmx, tmy, linedef); - if (*rover->topheight > highestfloor && delta1 < delta2) - highestfloor = *rover->topheight; - else if (*rover->topheight > lowestfloor && delta1 < delta2) - lowestfloor = *rover->topheight; + delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2))); + delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); + if (bottomheight < lowestceiling && delta1 >= delta2) + lowestceiling = bottomheight; + else if (bottomheight < highestceiling && delta1 >= delta2) + highestceiling = bottomheight; + + if (topheight > highestfloor && delta1 < delta2) + highestfloor = topheight; + else if (topheight > lowestfloor && delta1 < delta2) + lowestfloor = topheight; } // Check for backsectors fake floors if (back->ffloors) for (rover = back->ffloors; rover; rover = rover->next) { + fixed_t topheight, bottomheight; if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12) continue; - delta1 = abs(mapcampointer->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); - delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); - if (*rover->bottomheight < lowestceiling && delta1 >= delta2) - lowestceiling = *rover->bottomheight; - else if (*rover->bottomheight < highestceiling && delta1 >= delta2) - highestceiling = *rover->bottomheight; + topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tmx, tmy, linedef); + bottomheight = P_CameraGetFOFBottomZ(mapcampointer, back, rover, tmx, tmy, linedef); - if (*rover->topheight > highestfloor && delta1 < delta2) - highestfloor = *rover->topheight; - else if (*rover->topheight > lowestfloor && delta1 < delta2) - lowestfloor = *rover->topheight; + delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2))); + delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); + if (bottomheight < lowestceiling && delta1 >= delta2) + lowestceiling = bottomheight; + else if (bottomheight < highestceiling && delta1 >= delta2) + highestceiling = bottomheight; + + if (topheight > highestfloor && delta1 < delta2) + highestfloor = topheight; + else if (topheight > lowestfloor && delta1 < delta2) + lowestfloor = topheight; } if (highestceiling < highceiling) @@ -495,26 +532,40 @@ void P_LineOpening(line_t *linedef) I_Assert(front != NULL); I_Assert(back != NULL); - if (front->ceilingheight < back->ceilingheight) - { - opentop = front->ceilingheight; - highceiling = back->ceilingheight; - } - else - { - opentop = back->ceilingheight; - highceiling = front->ceilingheight; - } + { // Set open and high/low values here + fixed_t frontheight, backheight; - if (front->floorheight > back->floorheight) - { - openbottom = front->floorheight; - lowfloor = back->floorheight; - } - else - { - openbottom = back->floorheight; - lowfloor = front->floorheight; + frontheight = P_GetCeilingZ(tmthing, front, tmx, tmy, linedef); + backheight = P_GetCeilingZ(tmthing, back, tmx, tmy, linedef); + + if (frontheight < backheight) + { + opentop = frontheight; + highceiling = backheight; + opentopslope = front->c_slope; + } + else + { + opentop = backheight; + highceiling = frontheight; + opentopslope = back->c_slope; + } + + frontheight = P_GetFloorZ(tmthing, front, tmx, tmy, linedef); + backheight = P_GetFloorZ(tmthing, back, tmx, tmy, linedef); + + if (frontheight > backheight) + { + openbottom = frontheight; + lowfloor = backheight; + openbottomslope = front->f_slope; + } + else + { + openbottom = backheight; + lowfloor = frontheight; + openbottomslope = back->f_slope; + } } if (tmthing) @@ -580,10 +631,15 @@ void P_LineOpening(line_t *linedef) fixed_t highestfloor = openbottom; fixed_t lowestfloor = lowfloor; fixed_t delta1, delta2; +#ifdef ESLOPE + pslope_t *ceilingslope = opentopslope; + pslope_t *floorslope = openbottomslope; +#endif // Check for frontsector's fake floors for (rover = front->ffloors; rover; rover = rover->next) { + fixed_t topheight, bottomheight; if (!(rover->flags & FF_EXISTS)) continue; @@ -593,29 +649,41 @@ void P_LineOpening(line_t *linedef) || (rover->flags & FF_BLOCKOTHERS && !tmthing->player))) continue; - delta1 = abs(tmthing->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); - delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); + topheight = P_GetFOFTopZ(tmthing, front, rover, tmx, tmy, linedef); + bottomheight = P_GetFOFBottomZ(tmthing, front, rover, tmx, tmy, linedef); + + delta1 = abs(tmthing->z - (bottomheight + ((topheight - bottomheight)/2))); + delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF { - if (*rover->bottomheight < lowestceiling) - lowestceiling = *rover->bottomheight; - else if (*rover->bottomheight < highestceiling) - highestceiling = *rover->bottomheight; + if (bottomheight < lowestceiling) { + lowestceiling = bottomheight; +#ifdef ESLOPE + ceilingslope = *rover->b_slope; +#endif + } + else if (bottomheight < highestceiling) + highestceiling = bottomheight; } if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF { - if (*rover->topheight > highestfloor) - highestfloor = *rover->topheight; - else if (*rover->topheight > lowestfloor) - lowestfloor = *rover->topheight; + if (topheight > highestfloor) { + highestfloor = topheight; +#ifdef ESLOPE + floorslope = *rover->t_slope; +#endif + } + else if (topheight > lowestfloor) + lowestfloor = topheight; } } // Check for backsectors fake floors for (rover = back->ffloors; rover; rover = rover->next) { + fixed_t topheight, bottomheight; if (!(rover->flags & FF_EXISTS)) continue; @@ -625,23 +693,34 @@ void P_LineOpening(line_t *linedef) || (rover->flags & FF_BLOCKOTHERS && !tmthing->player))) continue; - delta1 = abs(tmthing->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); - delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); + topheight = P_GetFOFTopZ(tmthing, back, rover, tmx, tmy, linedef); + bottomheight = P_GetFOFBottomZ(tmthing, back, rover, tmx, tmy, linedef); + + delta1 = abs(tmthing->z - (bottomheight + ((topheight - bottomheight)/2))); + delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF { - if (*rover->bottomheight < lowestceiling) - lowestceiling = *rover->bottomheight; - else if (*rover->bottomheight < highestceiling) - highestceiling = *rover->bottomheight; + if (bottomheight < lowestceiling) { + lowestceiling = bottomheight; +#ifdef ESLOPE + ceilingslope = *rover->b_slope; +#endif + } + else if (bottomheight < highestceiling) + highestceiling = bottomheight; } if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF { - if (*rover->topheight > highestfloor) - highestfloor = *rover->topheight; - else if (*rover->topheight > lowestfloor) - lowestfloor = *rover->topheight; + if (topheight > highestfloor) { + highestfloor = topheight; +#ifdef ESLOPE + floorslope = *rover->t_slope; +#endif + } + else if (topheight > lowestfloor) + lowestfloor = topheight; } } @@ -653,13 +732,21 @@ void P_LineOpening(line_t *linedef) delta1 = abs(tmthing->z - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2))); delta2 = abs(thingtop - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2))); - if (polysec->floorheight < lowestceiling && delta1 >= delta2) + if (polysec->floorheight < lowestceiling && delta1 >= delta2) { lowestceiling = polysec->floorheight; +#ifdef ESLOPE + ceilingslope = NULL; +#endif + } else if (polysec->floorheight < highestceiling && delta1 >= delta2) highestceiling = polysec->floorheight; - if (polysec->ceilingheight > highestfloor && delta1 < delta2) + if (polysec->ceilingheight > highestfloor && delta1 < delta2) { highestfloor = polysec->ceilingheight; +#ifdef ESLOPE + floorslope = NULL; +#endif + } else if (polysec->ceilingheight > lowestfloor && delta1 < delta2) lowestfloor = polysec->ceilingheight; } @@ -667,11 +754,19 @@ void P_LineOpening(line_t *linedef) if (highestceiling < highceiling) highceiling = highestceiling; - if (highestfloor > openbottom) + if (highestfloor > openbottom) { openbottom = highestfloor; +#ifdef ESLOPE + openbottomslope = floorslope; +#endif + } - if (lowestceiling < opentop) + if (lowestceiling < opentop) { opentop = lowestceiling; +#ifdef ESLOPE + opentopslope = ceilingslope; +#endif + } if (lowestfloor > lowfloor) lowfloor = lowestfloor; @@ -769,6 +864,7 @@ void P_SetThingPosition(mobj_t *thing) { // link into subsector subsector_t *ss; sector_t *oldsec = NULL; + fixed_t tfloorz, tceilz; I_Assert(thing != NULL); I_Assert(!P_MobjWasRemoved(thing)); @@ -838,12 +934,15 @@ void P_SetThingPosition(mobj_t *thing) // sector's floor is the same height. if (thing->player && oldsec != NULL && thing->subsector && oldsec != thing->subsector->sector) { + tfloorz = P_GetFloorZ(thing, ss->sector, thing->x, thing->y, NULL); + tceilz = P_GetCeilingZ(thing, ss->sector, thing->x, thing->y, NULL); + if (thing->eflags & MFE_VERTICALFLIP) { - if (thing->z + thing->height >= thing->subsector->sector->ceilingheight) + if (thing->z + thing->height >= tceilz) thing->eflags |= MFE_JUSTSTEPPEDDOWN; } - else if (thing->z <= thing->subsector->sector->floorheight) + else if (thing->z <= tfloorz) thing->eflags |= MFE_JUSTSTEPPEDDOWN; } } diff --git a/src/p_maputl.h b/src/p_maputl.h index 66f7db2db..7471899cc 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -55,6 +55,9 @@ void P_CreatePrecipSecNodeList(precipmobj_t *thing, fixed_t x,fixed_t y); boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y); extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling; +#ifdef ESLOPE +extern pslope_t *opentopslope, *openbottomslope; +#endif void P_LineOpening(line_t *plinedef); diff --git a/src/p_mobj.c b/src/p_mobj.c index 5814b5d86..96d76003a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -31,6 +31,9 @@ #include "i_video.h" #include "lua_hook.h" #include "b_bot.h" +#ifdef ESLOPE +#include "p_slopes.h" +#endif // protos. static CV_PossibleValue_t viewheight_cons_t[] = {{16, "MIN"}, {56, "MAX"}, {0, NULL}}; @@ -76,11 +79,31 @@ void P_AddCachedAction(mobj_t *mobj, INT32 statenum) actioncachehead.prev = newaction; } +// +// P_CycleStateAnimation +// +FUNCINLINE static ATTRINLINE void P_CycleStateAnimation(mobj_t *mobj) +{ + // var2 determines delay between animation frames + if (!(mobj->frame & FF_ANIMATE) || --mobj->anim_duration != 0) + return; + mobj->anim_duration = (UINT16)mobj->state->var2; + + // compare the current sprite frame to the one we started from + // if more than var1 away from it, swap back to the original + // else just advance by one + if (((++mobj->frame) & FF_FRAMEMASK) - (mobj->state->frame & FF_FRAMEMASK) > (UINT32)mobj->state->var1) + mobj->frame = (mobj->state->frame & FF_FRAMEMASK) | (mobj->frame & ~FF_FRAMEMASK); +} + // // P_CycleMobjState // static void P_CycleMobjState(mobj_t *mobj) { + // state animations + P_CycleStateAnimation(mobj); + // cycle through states, // calling action functions at transitions if (mobj->tics != -1) @@ -99,6 +122,9 @@ static void P_CycleMobjState(mobj_t *mobj) // static void P_CyclePlayerMobjState(mobj_t *mobj) { + // state animations + P_CycleStateAnimation(mobj); + // cycle through states, // calling action functions at transitions if (mobj->tics != -1) @@ -160,7 +186,11 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) case S_PLAY_GASP: return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_GASP); case S_PLAY_JUMP: + if (!(player->charflags & SF_SUPERSPIN)) + return true; return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_JUMP); + case S_PLAY_SPRING: + return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_SPRING); case S_PLAY_FALL: return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_FALL); case S_PLAY_EDGE: @@ -206,12 +236,14 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) break; case S_PLAY_SPIN: case S_PLAY_DASH: + case S_PLAY_JUMP: case S_PLAY_SUPER_SPIN: + case S_PLAY_SUPER_JUMP: player->panim = PA_ROLL; break; - case S_PLAY_JUMP: - case S_PLAY_SUPER_JUMP: - player->panim = PA_JUMP; + case S_PLAY_SPRING: + case S_PLAY_SUPER_SPRING: + player->panim = PA_SPRING; break; case S_PLAY_FALL: case S_PLAY_SUPER_FALL: @@ -298,6 +330,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) boolean noalt = false; UINT8 spr2 = st->frame & FF_FRAMEMASK; UINT16 frame = (mobj->frame & FF_FRAMEMASK)+1; + mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set while (((skin_t *)mobj->skin)->sprites[spr2].numframes <= 0 && spr2 != SPR2_STND) @@ -314,9 +347,12 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) spr2 = SPR2_SPIN; break; case SPR2_GASP: - spr2 = SPR2_JUMP; + spr2 = SPR2_SPNG; break; case SPR2_JUMP: + spr2 = SPR2_SPIN; + break; + case SPR2_SPNG: // spring spr2 = SPR2_FALL; break; case SPR2_FALL: @@ -327,7 +363,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) break; case SPR2_FLY: - spr2 = SPR2_JUMP; + spr2 = SPR2_SPNG; break; case SPR2_TIRE: spr2 = SPR2_FLY; @@ -376,6 +412,9 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state) case SPR2_SJMP: spr2 = SPR2_JUMP; break; + case SPR2_SSPG: + spr2 = SPR2_SPNG; + break; case SPR2_SFAL: spr2 = SPR2_FALL; break; @@ -482,6 +521,7 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state) st = &states[state]; mobj->state = st; mobj->tics = st->tics; + mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set // Player animations if (st->sprite == SPR_PLAY) @@ -559,6 +599,8 @@ boolean P_SetMobjStateNF(mobj_t *mobj, statenum_t state) mobj->tics = st->tics; mobj->sprite = st->sprite; mobj->frame = st->frame; + mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set + return true; } @@ -576,6 +618,8 @@ static boolean P_SetPrecipMobjState(precipmobj_t *mobj, statenum_t state) mobj->tics = st->tics; mobj->sprite = st->sprite; mobj->frame = st->frame; + mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set + return true; } @@ -854,6 +898,7 @@ void P_ExplodeMissile(mobj_t *mo) // Returns TRUE if mobj is inside a non-solid 3d floor. boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover) { + fixed_t topheight, bottomheight; if (!(rover->flags & FF_EXISTS)) return false; @@ -861,15 +906,441 @@ boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover) || ((rover->flags & FF_BLOCKOTHERS) && !mobj->player))) return false; - if (mobj->z > *rover->topheight) + topheight = *rover->topheight; + bottomheight = *rover->bottomheight; + +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y); + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y); +#endif + + if (mobj->z > topheight) return false; - if (mobj->z + mobj->height < *rover->bottomheight) + if (mobj->z + mobj->height < bottomheight) return false; return true; } +// P_GetFloorZ (and its ceiling counterpart) +// Gets the floor height (or ceiling height) of the mobj's contact point in sector, assuming object's center if moved to [x, y] +// If line is supplied, it's a divider line on the sector. Set it to NULL if you're not checking for collision with a line +// Supply boundsec ONLY when checking for specials! It should be the "in-level" sector, and sector the control sector (if separate). +// If set, then this function will iterate through boundsec's linedefs to find the highest contact point on the slope. Non-special-checking +// usage will handle that later. +static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line, pslope_t *slope, boolean actuallylowest) +{ + // Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching... + // The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box + // (assuming it isn't already inside), then test each point's slope Z and return the higher of the two. + vertex_t v1, v2; + v1.x = line->v1->x; + v1.y = line->v1->y; + v2.x = line->v2->x; + v2.y = line->v2->y; + + /*CONS_Printf("BEFORE: v1 = %f %f %f\n", + FIXED_TO_FLOAT(v1.x), + FIXED_TO_FLOAT(v1.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) + ); + CONS_Printf(" v2 = %f %f %f\n", + FIXED_TO_FLOAT(v2.x), + FIXED_TO_FLOAT(v2.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) + );*/ + + if (abs(v1.x-x) > radius) { + // v1's x is out of range, so rein it in + fixed_t diff = abs(v1.x-x) - radius; + + if (v1.x < x) { // Moving right + v1.x += diff; + v1.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); + } else { // Moving left + v1.x -= diff; + v1.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); + } + } + + if (abs(v1.y-y) > radius) { + // v1's y is out of range, so rein it in + fixed_t diff = abs(v1.y-y) - radius; + + if (v1.y < y) { // Moving up + v1.y += diff; + v1.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); + } else { // Moving down + v1.y -= diff; + v1.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); + } + } + + if (abs(v2.x-x) > radius) { + // v1's x is out of range, so rein it in + fixed_t diff = abs(v2.x-x) - radius; + + if (v2.x < x) { // Moving right + v2.x += diff; + v2.y += FixedMul(diff, FixedDiv(line->dy, line->dx)); + } else { // Moving left + v2.x -= diff; + v2.y -= FixedMul(diff, FixedDiv(line->dy, line->dx)); + } + } + + if (abs(v2.y-y) > radius) { + // v2's y is out of range, so rein it in + fixed_t diff = abs(v2.y-y) - radius; + + if (v2.y < y) { // Moving up + v2.y += diff; + v2.x += FixedMul(diff, FixedDiv(line->dx, line->dy)); + } else { // Moving down + v2.y -= diff; + v2.x -= FixedMul(diff, FixedDiv(line->dx, line->dy)); + } + } + + /*CONS_Printf("AFTER: v1 = %f %f %f\n", + FIXED_TO_FLOAT(v1.x), + FIXED_TO_FLOAT(v1.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v1.x, v1.y)) + ); + CONS_Printf(" v2 = %f %f %f\n", + FIXED_TO_FLOAT(v2.x), + FIXED_TO_FLOAT(v2.y), + FIXED_TO_FLOAT(P_GetZAt(slope, v2.x, v2.y)) + );*/ + + // Return the higher of the two points + if (actuallylowest) + return min( + P_GetZAt(slope, v1.x, v1.y), + P_GetZAt(slope, v2.x, v2.y) + ); + else + return max( + P_GetZAt(slope, v1.x, v1.y), + P_GetZAt(slope, v2.x, v2.y) + ); +} + +fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) +{ + I_Assert(mobj != NULL); + I_Assert(sector != NULL); +#ifdef ESLOPE + if (sector->f_slope) { + fixed_t testx, testy; + pslope_t *slope = sector->f_slope; + + // Get the corner of the object that should be the highest on the slope + if (slope->d.x < 0) + testx = mobj->radius; + else + testx = -mobj->radius; + + if (slope->d.y < 0) + testy = mobj->radius; + else + testy = -mobj->radius; + + if ((slope->zdelta > 0) ^ !!(lowest)) { + testx = -testx; + testy = -testy; + } + + testx += x; + testy += y; + + // If the highest point is in the sector, then we have it easy! Just get the Z at that point + if (R_PointInSubsector(testx, testy)->sector == (boundsec ?: sector)) + return P_GetZAt(slope, testx, testy); + + // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point + if (perfect) { + size_t i; + line_t *ld; + fixed_t bbox[4]; + fixed_t finalheight; + + if (lowest) + finalheight = INT32_MAX; + else + finalheight = INT32_MIN; + + bbox[BOXLEFT] = x-mobj->radius; + bbox[BOXRIGHT] = x+mobj->radius; + bbox[BOXTOP] = y+mobj->radius; + bbox[BOXBOTTOM] = y-mobj->radius; + for (i = 0; i < boundsec->linecount; i++) { + ld = boundsec->lines[i]; + + if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT] + || bbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || bbox[BOXBOTTOM] >= ld->bbox[BOXTOP]) + continue; + + if (P_BoxOnLineSide(bbox, ld) != -1) + continue; + + if (lowest) + finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true)); + else + finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false)); + } + + return finalheight; + } + + // If we're just testing for base sector location (no collision line), just go for the center's spot... + // It'll get fixed when we test for collision anyway, and the final result can't be lower than this + if (line == NULL) + return P_GetZAt(slope, x, y); + + return HighestOnLine(mobj->radius, x, y, line, slope, lowest); + } else // Well, that makes it easy. Just get the floor height +#endif + return sector->floorheight; +} + +fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) +{ + I_Assert(mobj != NULL); + I_Assert(sector != NULL); +#ifdef ESLOPE + if (sector->c_slope) { + fixed_t testx, testy; + pslope_t *slope = sector->c_slope; + + // Get the corner of the object that should be the highest on the slope + if (slope->d.x < 0) + testx = mobj->radius; + else + testx = -mobj->radius; + + if (slope->d.y < 0) + testy = mobj->radius; + else + testy = -mobj->radius; + + if ((slope->zdelta > 0) ^ !!(lowest)) { + testx = -testx; + testy = -testy; + } + + testx += x; + testy += y; + + // If the highest point is in the sector, then we have it easy! Just get the Z at that point + if (R_PointInSubsector(testx, testy)->sector == (boundsec ?: sector)) + return P_GetZAt(slope, testx, testy); + + // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point + if (perfect) { + size_t i; + line_t *ld; + fixed_t bbox[4]; + fixed_t finalheight; + + if (lowest) + finalheight = INT32_MAX; + else + finalheight = INT32_MIN; + + bbox[BOXLEFT] = x-mobj->radius; + bbox[BOXRIGHT] = x+mobj->radius; + bbox[BOXTOP] = y+mobj->radius; + bbox[BOXBOTTOM] = y-mobj->radius; + for (i = 0; i < boundsec->linecount; i++) { + ld = boundsec->lines[i]; + + if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT] + || bbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || bbox[BOXBOTTOM] >= ld->bbox[BOXTOP]) + continue; + + if (P_BoxOnLineSide(bbox, ld) != -1) + continue; + + if (lowest) + finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true)); + else + finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false)); + } + + return finalheight; + } + + // If we're just testing for base sector location (no collision line), just go for the center's spot... + // It'll get fixed when we test for collision anyway, and the final result can't be lower than this + if (line == NULL) + return P_GetZAt(slope, x, y); + + return HighestOnLine(mobj->radius, x, y, line, slope, lowest); + } else // Well, that makes it easy. Just get the ceiling height +#endif + return sector->ceilingheight; +} + +// Now do the same as all above, but for cameras because apparently cameras are special? +fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) +{ + I_Assert(mobj != NULL); + I_Assert(sector != NULL); +#ifdef ESLOPE + if (sector->f_slope) { + fixed_t testx, testy; + pslope_t *slope = sector->f_slope; + + // Get the corner of the object that should be the highest on the slope + if (slope->d.x < 0) + testx = mobj->radius; + else + testx = -mobj->radius; + + if (slope->d.y < 0) + testy = mobj->radius; + else + testy = -mobj->radius; + + if ((slope->zdelta > 0) ^ !!(lowest)) { + testx = -testx; + testy = -testy; + } + + testx += x; + testy += y; + + // If the highest point is in the sector, then we have it easy! Just get the Z at that point + if (R_PointInSubsector(testx, testy)->sector == (boundsec ?: sector)) + return P_GetZAt(slope, testx, testy); + + // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point + if (perfect) { + size_t i; + line_t *ld; + fixed_t bbox[4]; + fixed_t finalheight; + + if (lowest) + finalheight = INT32_MAX; + else + finalheight = INT32_MIN; + + bbox[BOXLEFT] = x-mobj->radius; + bbox[BOXRIGHT] = x+mobj->radius; + bbox[BOXTOP] = y+mobj->radius; + bbox[BOXBOTTOM] = y-mobj->radius; + for (i = 0; i < boundsec->linecount; i++) { + ld = boundsec->lines[i]; + + if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT] + || bbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || bbox[BOXBOTTOM] >= ld->bbox[BOXTOP]) + continue; + + if (P_BoxOnLineSide(bbox, ld) != -1) + continue; + + if (lowest) + finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true)); + else + finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false)); + } + + return finalheight; + } + + // If we're just testing for base sector location (no collision line), just go for the center's spot... + // It'll get fixed when we test for collision anyway, and the final result can't be lower than this + if (line == NULL) + return P_GetZAt(slope, x, y); + + return HighestOnLine(mobj->radius, x, y, line, slope, lowest); + } else // Well, that makes it easy. Just get the floor height +#endif + return sector->floorheight; +} + +fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect) +{ + I_Assert(mobj != NULL); + I_Assert(sector != NULL); +#ifdef ESLOPE + if (sector->c_slope) { + fixed_t testx, testy; + pslope_t *slope = sector->c_slope; + + // Get the corner of the object that should be the highest on the slope + if (slope->d.x < 0) + testx = mobj->radius; + else + testx = -mobj->radius; + + if (slope->d.y < 0) + testy = mobj->radius; + else + testy = -mobj->radius; + + if ((slope->zdelta > 0) ^ !!(lowest)) { + testx = -testx; + testy = -testy; + } + + testx += x; + testy += y; + + // If the highest point is in the sector, then we have it easy! Just get the Z at that point + if (R_PointInSubsector(testx, testy)->sector == (boundsec ?: sector)) + return P_GetZAt(slope, testx, testy); + + // If boundsec is set, we're looking for specials. In that case, iterate over every line in this sector to find the TRUE highest/lowest point + if (perfect) { + size_t i; + line_t *ld; + fixed_t bbox[4]; + fixed_t finalheight; + + if (lowest) + finalheight = INT32_MAX; + else + finalheight = INT32_MIN; + + bbox[BOXLEFT] = x-mobj->radius; + bbox[BOXRIGHT] = x+mobj->radius; + bbox[BOXTOP] = y+mobj->radius; + bbox[BOXBOTTOM] = y-mobj->radius; + for (i = 0; i < boundsec->linecount; i++) { + ld = boundsec->lines[i]; + + if (bbox[BOXRIGHT] <= ld->bbox[BOXLEFT] || bbox[BOXLEFT] >= ld->bbox[BOXRIGHT] + || bbox[BOXTOP] <= ld->bbox[BOXBOTTOM] || bbox[BOXBOTTOM] >= ld->bbox[BOXTOP]) + continue; + + if (P_BoxOnLineSide(bbox, ld) != -1) + continue; + + if (lowest) + finalheight = min(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, true)); + else + finalheight = max(finalheight, HighestOnLine(mobj->radius, x, y, ld, slope, false)); + } + + return finalheight; + } + + // If we're just testing for base sector location (no collision line), just go for the center's spot... + // It'll get fixed when we test for collision anyway, and the final result can't be lower than this + if (line == NULL) + return P_GetZAt(slope, x, y); + + return HighestOnLine(mobj->radius, x, y, line, slope, lowest); + } else // Well, that makes it easy. Just get the ceiling height +#endif + return sector->ceilingheight; +} static void P_PlayerFlip(mobj_t *mo) { if (!mo->player) @@ -1136,7 +1607,11 @@ static void P_XYFriction(mobj_t *mo, fixed_t oldx, fixed_t oldy) } else if (abs(player->rmomx) < FixedMul(STOPSPEED, mo->scale) && abs(player->rmomy) < FixedMul(STOPSPEED, mo->scale) - && (!(player->cmd.forwardmove && !(twodlevel || mo->flags2 & MF2_TWOD)) && !player->cmd.sidemove && !(player->pflags & PF_SPINNING))) + && (!(player->cmd.forwardmove && !(twodlevel || mo->flags2 & MF2_TWOD)) && !player->cmd.sidemove && !(player->pflags & PF_SPINNING)) +#ifdef ESLOPE + && !(player->mo->standingslope && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2) +#endif + ) { // if in a walking frame, stop moving if (player->panim == PA_WALK) @@ -1280,6 +1755,11 @@ void P_XYMovement(mobj_t *mo) fixed_t xmove, ymove; fixed_t oldx, oldy; // reducing bobbing/momentum on ice when up against walls boolean moved; +#ifdef ESLOPE + pslope_t *oldslope = NULL; + vector3_t slopemom; + fixed_t predictedz = 0; +#endif I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); @@ -1311,6 +1791,30 @@ void P_XYMovement(mobj_t *mo) oldx = mo->x; oldy = mo->y; +#ifdef ESLOPE + // adjust various things based on slope + if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8) { + if (!P_IsObjectOnGround(mo)) { // We fell off at some point? Do the twisty thing! + P_SlopeLaunch(mo); + xmove = mo->momx; + ymove = mo->momy; + } else { // Still on the ground. + slopemom.x = xmove; + slopemom.y = ymove; + slopemom.z = 0; + P_QuantizeMomentumToSlope(&slopemom, mo->standingslope); + + xmove = slopemom.x; + ymove = slopemom.y; + + predictedz = mo->z + slopemom.z; // We'll use this later... + + oldslope = mo->standingslope; + } + } else if (P_IsObjectOnGround(mo) && !mo->momz) + predictedz = mo->z; +#endif + // Pushables can break some blocks if (CheckForBustableBlocks && mo->flags & MF_PUSHABLE) P_PushableCheckBustables(mo); @@ -1431,6 +1935,54 @@ void P_XYMovement(mobj_t *mo) if (P_MobjWasRemoved(mo)) // MF_SPECIAL touched a player! O_o;; return; +#ifdef ESLOPE + if (moved && oldslope) { // Check to see if we ran off + + if (oldslope != mo->standingslope) { // First, compare different slopes + angle_t oldangle, newangle; + angle_t moveangle = R_PointToAngle2(0, 0, mo->momx, mo->momy); + + oldangle = FixedMul((signed)oldslope->zangle, FINECOSINE((moveangle - oldslope->xydirection) >> ANGLETOFINESHIFT)); + + if (mo->standingslope) + newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT)); + else + newangle = 0; + + // Now compare the Zs of the different quantizations + if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later + mo->standingslope = oldslope; + P_SlopeLaunch(mo); + + //CONS_Printf("launched off of slope - "); + } + + /*CONS_Printf("old angle %f - new angle %f = %f\n", + FIXED_TO_FLOAT(AngleFixed(oldangle)), + FIXED_TO_FLOAT(AngleFixed(newangle)), + FIXED_TO_FLOAT(AngleFixed(oldangle-newangle)) + );*/ + } else if (predictedz-mo->z > abs(slopemom.z/2)) { // Now check if we were supposed to stick to this slope + //CONS_Printf("%d-%d > %d\n", (predictedz), (mo->z), (slopemom.z/2)); + P_SlopeLaunch(mo); + } + } else if (moved && mo->standingslope && predictedz) { + angle_t moveangle = R_PointToAngle2(0, 0, mo->momx, mo->momy); + angle_t newangle = FixedMul((signed)mo->standingslope->zangle, FINECOSINE((moveangle - mo->standingslope->xydirection) >> ANGLETOFINESHIFT)); + + /*CONS_Printf("flat to angle %f - predicted z of %f\n", + FIXED_TO_FLOAT(AngleFixed(ANGLE_MAX-newangle)), + FIXED_TO_FLOAT(predictedz) + );*/ + if (ANGLE_MAX-newangle > ANG30 && newangle > ANGLE_180) { + mo->momz = P_MobjFlip(mo)*FRACUNIT/2; + mo->z = predictedz + P_MobjFlip(mo); + mo->standingslope = NULL; + //CONS_Printf("Launched off of flat surface running into downward slope\n"); + } + } +#endif + // Check the gravity status. P_CheckGravity(mo, false); @@ -1477,6 +2029,12 @@ void P_XYMovement(mobj_t *mo) if (player && player->homing) // no friction for homing return; +#ifdef ESLOPE + if ((mo->type == MT_BIGTUMBLEWEED || mo->type == MT_LITTLETUMBLEWEED) + && (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8)) // Special exception for tumbleweeds on slopes + return; +#endif + if (((!(mo->eflags & MFE_VERTICALFLIP) && mo->z > mo->floorz) || (mo->eflags & MFE_VERTICALFLIP && mo->z+mo->height < mo->ceilingz)) && !(player && player->pflags & PF_SLIDING)) return; // no friction when airborne @@ -1533,6 +2091,7 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp { ffloor_t *rover; fixed_t delta1, delta2, thingtop; + fixed_t topheight, bottomheight; I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); @@ -1544,6 +2103,9 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp if (!(rover->flags & FF_EXISTS)) continue; + 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(mo, rover) || P_CanRunOnWater(mo->player, rover))) // only the player should be affected ; else if (motype != 0 && rover->flags & FF_SWIMMABLE) // "scenery" only @@ -1558,14 +2120,14 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp switch (motype) { case 2: // scenery does things differently for some reason - if (mo->z < *rover->topheight && *rover->bottomheight < thingtop) + if (mo->z < topheight && bottomheight < thingtop) { mo->floorz = mo->z; continue; } break; default: - if (mo->z < *rover->topheight && *rover->bottomheight < thingtop) + if (mo->z < topheight && bottomheight < thingtop) { if (mo->floorz < mo->z) mo->floorz = mo->z; @@ -1574,17 +2136,17 @@ static void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motyp } } - delta1 = mo->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)); - delta2 = thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)); - if (*rover->topheight > mo->floorz && abs(delta1) < abs(delta2) + delta1 = mo->z - (bottomheight + ((topheight - bottomheight)/2)); + delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2)); + if (topheight > mo->floorz && abs(delta1) < abs(delta2) && !(rover->flags & FF_REVERSEPLATFORM)) { - mo->floorz = *rover->topheight; + mo->floorz = topheight; } - if (*rover->bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2) + if (bottomheight < mo->ceilingz && abs(delta1) >= abs(delta2) && !(rover->flags & FF_PLATFORM)) { - mo->ceilingz = *rover->bottomheight; + mo->ceilingz = bottomheight; } } } @@ -1716,6 +2278,11 @@ static boolean P_ZMovement(mobj_t *mo) I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); +#ifdef ESLOPE + if (mo->standingslope && !P_IsObjectOnGround(mo)) + P_SlopeLaunch(mo); +#endif + // Intercept the stupid 'fall through 3dfloors' bug if (mo->subsector->sector->ffloors) P_AdjustMobjFloorZ_FFloors(mo, mo->subsector->sector, 0); @@ -1794,9 +2361,7 @@ static boolean P_ZMovement(mobj_t *mo) case MT_RING: // Ignore still rings case MT_COIN: -#ifdef BLUE_SPHERES case MT_BLUEBALL: -#endif case MT_REDTEAMRING: case MT_BLUETEAMRING: case MT_FLINGRING: @@ -1903,14 +2468,31 @@ static boolean P_ZMovement(mobj_t *mo) || (mo->z + mo->height >= mo->ceilingz && mo->eflags & MFE_VERTICALFLIP)) && !(mo->flags & MF_NOCLIPHEIGHT)) { + vector3_t mom; + mom.x = mo->momx; + mom.y = mo->momy; + mom.z = mo->momz; + if (mo->eflags & MFE_VERTICALFLIP) mo->z = mo->ceilingz - mo->height; else mo->z = mo->floorz; +#ifdef ESLOPE + P_CheckPosition(mo, mo->x, mo->y); // Sets mo->standingslope correctly + if ((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) { + mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope; + + // Reverse quantizing might could use its own function later + mo->standingslope->zangle = ANGLE_MAX-mo->standingslope->zangle; + P_QuantizeMomentumToSlope(&mom, mo->standingslope); + mo->standingslope->zangle = ANGLE_MAX-mo->standingslope->zangle; + } +#endif + // hit the floor if (mo->type == MT_FIREBALL) // special case for the fireball - mo->momz = P_MobjFlip(mo)*FixedMul(5*FRACUNIT, mo->scale); + mom.z = P_MobjFlip(mo)*FixedMul(5*FRACUNIT, mo->scale); else if (mo->type == MT_SPINFIRE) // elemental shield fire is another exception here ; else if (mo->flags & MF_MISSILE) @@ -1925,12 +2507,12 @@ static boolean P_ZMovement(mobj_t *mo) if (mo->flags & MF_GRENADEBOUNCE) { // Going down? (Or up in reverse gravity?) - if (P_MobjFlip(mo)*mo->momz < 0) + if (P_MobjFlip(mo)*mom.z < 0) { // If going slower than a fracunit, just stop. - if (abs(mo->momz) < FixedMul(FRACUNIT, mo->scale)) + if (abs(mom.z) < FixedMul(FRACUNIT, mo->scale)) { - mo->momx = mo->momy = mo->momz = 0; + mom.x = mom.y = mom.z = 0; // Napalm hack if (mo->type == MT_CYBRAKDEMON_NAPALM_BOMB_LARGE && mo->fuse) @@ -1938,7 +2520,7 @@ static boolean P_ZMovement(mobj_t *mo) } // Otherwise bounce up at half speed. else - mo->momz = -mo->momz/2; + mom.z = -mom.z/2; S_StartSound(mo, mo->info->activesound); } } @@ -1961,14 +2543,14 @@ static boolean P_ZMovement(mobj_t *mo) } } - if (P_MobjFlip(mo)*mo->momz < 0) // falling + if (P_MobjFlip(mo)*mom.z < 0) // falling { if (!tmfloorthing || tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR) || tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER) mo->eflags |= MFE_JUSTHITFLOOR; if (mo->flags2 & MF2_SKULLFLY) // the skull slammed into something - mo->momz = -mo->momz; + mom.z = -mom.z; else // Flingrings bounce if (mo->type == MT_FLINGRING @@ -1981,35 +2563,42 @@ static boolean P_ZMovement(mobj_t *mo) || mo->type == MT_FALLINGROCK) { if (maptol & TOL_NIGHTS) - mo->momz = -FixedDiv(mo->momz, 10*FRACUNIT); + mom.z = -FixedDiv(mom.z, 10*FRACUNIT); else - mo->momz = -FixedMul(mo->momz, FixedDiv(17*FRACUNIT,20*FRACUNIT)); + mom.z = -FixedMul(mom.z, FixedDiv(17*FRACUNIT,20*FRACUNIT)); if (mo->type == MT_BIGTUMBLEWEED || mo->type == MT_LITTLETUMBLEWEED) { - if (abs(mo->momx) < FixedMul(STOPSPEED, mo->scale) - && abs(mo->momy) < FixedMul(STOPSPEED, mo->scale) - && abs(mo->momz) < FixedMul(STOPSPEED*3, mo->scale)) + if (abs(mom.x) < FixedMul(STOPSPEED, mo->scale) + && abs(mom.y) < FixedMul(STOPSPEED, mo->scale) + && abs(mom.z) < FixedMul(STOPSPEED*3, mo->scale)) { - if (!(mo->flags & MF_AMBUSH)) - { - mo->momx = mo->momy = mo->momz = 0; - P_SetMobjState(mo, mo->info->spawnstate); - } - else + if (mo->flags & MF_AMBUSH) { // If deafed, give the tumbleweed another random kick if it runs out of steam. - mo->momz += P_MobjFlip(mo)*FixedMul(6*FRACUNIT, mo->scale); + mom.z += P_MobjFlip(mo)*FixedMul(6*FRACUNIT, mo->scale); if (P_Random() & 1) - mo->momx += FixedMul(6*FRACUNIT, mo->scale); + mom.x += FixedMul(6*FRACUNIT, mo->scale); else - mo->momx -= FixedMul(6*FRACUNIT, mo->scale); + mom.x -= FixedMul(6*FRACUNIT, mo->scale); if (P_Random() & 1) - mo->momy += FixedMul(6*FRACUNIT, mo->scale); + mom.y += FixedMul(6*FRACUNIT, mo->scale); else - mo->momy -= FixedMul(6*FRACUNIT, mo->scale); + mom.y -= FixedMul(6*FRACUNIT, mo->scale); + } +#ifdef ESLOPE + else if (mo->standingslope && abs(mo->standingslope->zdelta) > FRACUNIT>>8) + { + // Pop the object up a bit to encourage bounciness + //mom.z = P_MobjFlip(mo)*mo->scale; + } +#endif + else + { + mom.x = mom.y = mom.z = 0; + P_SetMobjState(mo, mo->info->spawnstate); } } @@ -2019,14 +2608,14 @@ static boolean P_ZMovement(mobj_t *mo) } else if (mo->type == MT_FALLINGROCK) { - if (P_MobjFlip(mo)*mo->momz > FixedMul(2*FRACUNIT, mo->scale)) + if (P_MobjFlip(mo)*mom.z > FixedMul(2*FRACUNIT, mo->scale)) S_StartSound(mo, mo->info->activesound + P_RandomKey(mo->info->mass)); - mo->momz /= 2; // Rocks not so bouncy + mom.z /= 2; // Rocks not so bouncy - if (abs(mo->momx) < FixedMul(STOPSPEED, mo->scale) - && abs(mo->momy) < FixedMul(STOPSPEED, mo->scale) - && abs(mo->momz) < FixedMul(STOPSPEED*3, mo->scale)) + if (abs(mom.x) < FixedMul(STOPSPEED, mo->scale) + && abs(mom.y) < FixedMul(STOPSPEED, mo->scale) + && abs(mom.z) < FixedMul(STOPSPEED*3, mo->scale)) { P_RemoveMobj(mo); return false; @@ -2034,20 +2623,30 @@ static boolean P_ZMovement(mobj_t *mo) } else if (mo->type == MT_CANNONBALLDECOR) { - mo->momz /= 2; - if (abs(mo->momz) < FixedMul(STOPSPEED*3, mo->scale)) - mo->momz = 0; + mom.z /= 2; + if (abs(mom.z) < FixedMul(STOPSPEED*3, mo->scale)) + mom.z = 0; } } else if (tmfloorthing && (tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR) || tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER)) - mo->momz = tmfloorthing->momz; + mom.z = tmfloorthing->momz; else if (!tmfloorthing) - mo->momz = 0; + mom.z = 0; } else if (tmfloorthing && (tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR) || tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER)) - mo->momz = tmfloorthing->momz; + mom.z = tmfloorthing->momz; + +#ifdef ESLOPE + if (mo->standingslope) { + P_QuantizeMomentumToSlope(&mom, mo->standingslope); + } +#endif + + mo->momx = mom.x; + mo->momy = mom.y; + mo->momz = mom.z; if (mo->type == MT_STEAM) return true; @@ -2161,6 +2760,11 @@ static void P_PlayerZMovement(mobj_t *mo) || mo->player->playerstate == PST_REBORN) return; +#ifdef ESLOPE + if (mo->standingslope && !P_IsObjectOnGround(mo)) + P_SlopeLaunch(mo); +#endif + // clip movement if (P_IsObjectOnGround(mo) && !(mo->flags & MF_NOCLIPHEIGHT)) { @@ -2182,6 +2786,13 @@ static void P_PlayerZMovement(mobj_t *mo) if (mo->player->panim == PA_PAIN) P_SetPlayerMobjState(mo, S_PLAY_STND); +#ifdef ESLOPE + if (!mo->standingslope && (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)) { + // Handle landing on slope during Z movement + P_HandleSlopeLanding(mo, (mo->eflags & MFE_VERTICALFLIP ? tmceilingslope : tmfloorslope)); + } +#endif + if (P_MobjFlip(mo)*mo->momz < 0) // falling { mo->pmomz = 0; // We're on a new floor, don't keep doing platform movement. @@ -2282,7 +2893,7 @@ static void P_PlayerZMovement(mobj_t *mo) { if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale) && mo->player->panim != PA_RUN) P_SetPlayerMobjState(mo, S_PLAY_RUN); - else if ((mo->player->rmomx || mo->player->rmomy) && mo->player->panim != PA_WALK) + else if ((mo->player->rmomx || mo->player->rmomy) && (mo->player->panim != PA_WALK || mo->state-states == S_PLAY_SUPER_FLOAT)) P_SetPlayerMobjState(mo, S_PLAY_WALK); else if (!mo->player->rmomx && !mo->player->rmomy && mo->player->panim != PA_IDLE) P_SetPlayerMobjState(mo, S_PLAY_STND); @@ -2291,7 +2902,7 @@ static void P_PlayerZMovement(mobj_t *mo) { if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale) && mo->player->panim != PA_RUN) P_SetPlayerMobjState(mo, S_PLAY_RUN); - else if ((mo->momx || mo->momy) && mo->player->panim != PA_WALK) + else if ((mo->momx || mo->momy) && (mo->player->panim != PA_WALK || mo->state-states == S_PLAY_SUPER_FLOAT)) P_SetPlayerMobjState(mo, S_PLAY_WALK); else if (!mo->momx && !mo->momy && mo->player->panim != PA_IDLE) P_SetPlayerMobjState(mo, S_PLAY_STND); @@ -2589,46 +3200,58 @@ void P_MobjCheckWater(mobj_t *mobj) player_t *p = mobj->player; // Will just be null if not a player. // Default if no water exists. - mobj->watertop = mobj->waterbottom = mobj->subsector->sector->floorheight - 1000*FRACUNIT; + mobj->watertop = mobj->waterbottom = mobj->z - 1000*FRACUNIT; // Reset water state. mobj->eflags &= ~(MFE_UNDERWATER|MFE_TOUCHWATER|MFE_GOOWATER); 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 = *rover->topheight; + bottomheight = *rover->bottomheight; + +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y); + + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y); +#endif + if (mobj->eflags & MFE_VERTICALFLIP) { - if (*rover->topheight < (thingtop - FixedMul(mobj->info->height/2, mobj->scale)) - || *rover->bottomheight > thingtop) + if (topheight < (thingtop - FixedMul(mobj->info->height/2, mobj->scale)) + || bottomheight > thingtop) continue; } else { - if (*rover->topheight < mobj->z - || *rover->bottomheight > (mobj->z + FixedMul(mobj->info->height/2, mobj->scale))) + if (topheight < mobj->z + || bottomheight > (mobj->z + FixedMul(mobj->info->height/2, mobj->scale))) continue; } // Set the watertop and waterbottom - mobj->watertop = *rover->topheight; - mobj->waterbottom = *rover->bottomheight; + mobj->watertop = topheight; + mobj->waterbottom = bottomheight; // Just touching the water? - if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height, mobj->scale) < *rover->bottomheight) - || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height, mobj->scale) > *rover->topheight)) + if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height, mobj->scale) < bottomheight) + || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height, mobj->scale) > topheight)) { mobj->eflags |= MFE_TOUCHWATER; if (rover->flags & FF_GOOWATER && !(mobj->flags & MF_NOGRAVITY)) mobj->eflags |= MFE_GOOWATER; } // Actually in the water? - if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height/2, mobj->scale) > *rover->bottomheight) - || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height/2, mobj->scale) < *rover->topheight)) + if (((mobj->eflags & MFE_VERTICALFLIP) && thingtop - FixedMul(mobj->info->height/2, mobj->scale) > bottomheight) + || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + FixedMul(mobj->info->height/2, mobj->scale) < topheight)) { mobj->eflags |= MFE_UNDERWATER; if (rover->flags & FF_GOOWATER && !(mobj->flags & MF_NOGRAVITY)) @@ -2805,7 +3428,7 @@ static void P_SceneryCheckWater(mobj_t *mobj) sector_t *sector; // Default if no water exists. - mobj->watertop = mobj->waterbottom = mobj->subsector->sector->floorheight - 1000*FRACUNIT; + mobj->watertop = mobj->waterbottom = mobj->z - 1000*FRACUNIT; // see if we are in water, and set some flags for later sector = mobj->subsector->sector; @@ -2813,6 +3436,7 @@ static void P_SceneryCheckWater(mobj_t *mobj) if (sector->ffloors) { ffloor_t *rover; + fixed_t topheight, bottomheight; mobj->eflags &= ~(MFE_UNDERWATER|MFE_TOUCHWATER); @@ -2820,20 +3444,32 @@ static void P_SceneryCheckWater(mobj_t *mobj) { if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKOTHERS) continue; - if (*rover->topheight <= mobj->z - || *rover->bottomheight > (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale))) + + topheight = *rover->topheight; + bottomheight = *rover->bottomheight; + +#ifdef ESLOPE + if (*rover->t_slope) + topheight = P_GetZAt(*rover->t_slope, mobj->x, mobj->y); + + if (*rover->b_slope) + bottomheight = P_GetZAt(*rover->b_slope, mobj->x, mobj->y); +#endif + + if (topheight <= mobj->z + || bottomheight > (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale))) continue; - if (mobj->z + FixedMul(mobj->info->height, mobj->scale) > *rover->topheight) + if (mobj->z + FixedMul(mobj->info->height, mobj->scale) > topheight) mobj->eflags |= MFE_TOUCHWATER; else mobj->eflags &= ~MFE_TOUCHWATER; // Set the watertop and waterbottom - mobj->watertop = *rover->topheight; - mobj->waterbottom = *rover->bottomheight; + mobj->watertop = topheight; + mobj->waterbottom = bottomheight; - if (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale) < *rover->topheight) + if (mobj->z + FixedMul(mobj->info->height >> 1, mobj->scale) < topheight) mobj->eflags |= MFE_UNDERWATER; else mobj->eflags &= ~MFE_UNDERWATER; @@ -2863,7 +3499,15 @@ static boolean P_CameraCheckHeat(camera_t *thiscam) if (!(rover->flags & FF_EXISTS)) continue; - if (halfheight >= *rover->topheight || halfheight <= *rover->bottomheight) + if (halfheight >= ( +#ifdef ESLOPE + *rover->t_slope ? P_GetZAt(*rover->t_slope, thiscam->x, thiscam->y) : +#endif + *rover->topheight) || halfheight <= ( +#ifdef ESLOPE + *rover->b_slope ? P_GetZAt(*rover->b_slope, thiscam->x, thiscam->y) : +#endif + *rover->bottomheight)) continue; if (P_FindSpecialLineFromTag(13, rover->master->frontsector->tag, -1) != -1) @@ -2891,7 +3535,15 @@ static boolean P_CameraCheckWater(camera_t *thiscam) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKOTHERS) continue; - if (halfheight >= *rover->topheight || halfheight <= *rover->bottomheight) + if (halfheight >= ( +#ifdef ESLOPE + *rover->t_slope ? P_GetZAt(*rover->t_slope, thiscam->x, thiscam->y) : +#endif + *rover->topheight) || halfheight <= ( +#ifdef ESLOPE + *rover->b_slope ? P_GetZAt(*rover->b_slope, thiscam->x, thiscam->y) : +#endif + *rover->bottomheight)) continue; return true; @@ -3062,6 +3714,10 @@ static void P_PlayerMobjThinker(mobj_t *mobj) P_MobjCheckWater(mobj); +#ifdef ESLOPE + P_ButteredSlope(mobj); +#endif + // momentum movement mobj->eflags &= ~MFE_JUSTSTEPPEDDOWN; @@ -3100,6 +3756,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj) // Crumbling platforms for (node = mobj->touching_sectorlist; node; node = node->m_snext) { + fixed_t topheight, bottomheight; ffloor_t *rover; for (rover = node->m_sector->ffloors; rover; rover = rover->next) @@ -3107,8 +3764,11 @@ static void P_PlayerMobjThinker(mobj_t *mobj) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_CRUMBLE)) continue; - if ((*rover->topheight == mobj->z && !(mobj->eflags & MFE_VERTICALFLIP)) - || (*rover->bottomheight == mobj->z + mobj->height && mobj->eflags & MFE_VERTICALFLIP)) // You nut. + topheight = P_GetSpecialTopZ(mobj, sectors + rover->secnum, node->m_sector); + bottomheight = P_GetSpecialBottomZ(mobj, sectors + rover->secnum, node->m_sector); + + if ((topheight == mobj->z && !(mobj->eflags & MFE_VERTICALFLIP)) + || (bottomheight == mobj->z + mobj->height && mobj->eflags & MFE_VERTICALFLIP)) // You nut. EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), mobj->player, rover->alpha, !(rover->flags & FF_NORETURN)); } } @@ -3256,6 +3916,8 @@ void P_NullPrecipThinker(precipmobj_t *mobj) void P_SnowThinker(precipmobj_t *mobj) { + P_CycleStateAnimation((mobj_t *)mobj); + // adjust height if ((mobj->z += mobj->momz) <= mobj->floorz) mobj->z = mobj->ceilingz; @@ -3263,6 +3925,8 @@ void P_SnowThinker(precipmobj_t *mobj) void P_RainThinker(precipmobj_t *mobj) { + P_CycleStateAnimation((mobj_t *)mobj); + if (mobj->state != &states[S_RAIN1]) { // cycle through states, @@ -5301,8 +5965,6 @@ static void P_NightsItemChase(mobj_t *thing) static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) { - fixed_t destx, desty; - if (!thing->target || thing->target->health <= 0 || !thing->target->player || (thing->target->player->powers[pw_shield] & SH_NOSTACK) == SH_NONE || thing->target->player->powers[pw_super] || thing->target->player->powers[pw_invulnerability] > 1) @@ -5327,26 +5989,6 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) return false; } - if (!splitscreen && rendermode != render_soft) - { - angle_t viewingangle; - - if (players[displayplayer].awayviewtics) - viewingangle = R_PointToAngle2(thing->target->x, thing->target->y, players[displayplayer].awayviewmobj->x, players[displayplayer].awayviewmobj->y); - else if (!camera.chase && players[displayplayer].mo) - viewingangle = R_PointToAngle2(thing->target->x, thing->target->y, players[displayplayer].mo->x, players[displayplayer].mo->y); - else - viewingangle = R_PointToAngle2(thing->target->x, thing->target->y, camera.x, camera.y); - - destx = thing->target->x + P_ReturnThrustX(thing->target, viewingangle, FixedMul(FRACUNIT, thing->scale)); - desty = thing->target->y + P_ReturnThrustY(thing->target, viewingangle, FixedMul(FRACUNIT, thing->scale)); - } - else - { - destx = thing->target->x; - desty = thing->target->y; - } - if (shield == SH_FORCE && thing->movecount != (thing->target->player->powers[pw_shield] & 0xFF)) { thing->movecount = (thing->target->player->powers[pw_shield] & 0xFF); @@ -5371,8 +6013,8 @@ static boolean P_ShieldLook(mobj_t *thing, shieldtype_t shield) P_SetScale(thing, thing->target->scale); P_UnsetThingPosition(thing); - thing->x = destx; - thing->y = desty; + thing->x = thing->target->x; + thing->y = thing->target->y; if (thing->eflags & MFE_VERTICALFLIP) thing->z = thing->target->z + thing->target->height - thing->height + FixedDiv(P_GetPlayerHeight(thing->target->player) - thing->target->height, 3*FRACUNIT) - FixedMul(2*FRACUNIT, thing->target->scale); else @@ -5395,8 +6037,6 @@ INT32 numshields = 0; void P_RunShields(void) { INT32 i; - mobj_t *mo, *next; - fixed_t destx,desty,zoffs; // run shields for (i = 0; i < numshields; i++) @@ -5405,60 +6045,6 @@ void P_RunShields(void) P_SetTarget(&shields[i], NULL); } numshields = 0; - - // run overlays - next = NULL; - for (mo = overlaycap; mo; mo = next) - { - I_Assert(!P_MobjWasRemoved(mo)); - - // grab next in chain, then unset the chain target - next = mo->hnext; - P_SetTarget(&mo->hnext, NULL); - - if (!mo->target) - continue; - if (!splitscreen /*&& rendermode != render_soft*/) - { - angle_t viewingangle; - - if (players[displayplayer].awayviewtics) - viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].awayviewmobj->x, players[displayplayer].awayviewmobj->y); - else if (!camera.chase && players[displayplayer].mo) - viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].mo->x, players[displayplayer].mo->y); - else - viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, camera.x, camera.y); - - if (mo->state->var1) - viewingangle += ANGLE_180; - destx = mo->target->x + P_ReturnThrustX(mo->target, viewingangle, FixedMul(FRACUNIT/4, mo->scale)); - desty = mo->target->y + P_ReturnThrustY(mo->target, viewingangle, FixedMul(FRACUNIT/4, mo->scale)); - } - else - { - destx = mo->target->x; - desty = mo->target->y; - } - - mo->eflags = (mo->eflags & ~MFE_VERTICALFLIP) | (mo->target->eflags & MFE_VERTICALFLIP); - mo->scale = mo->destscale = mo->target->scale; - zoffs = FixedMul(((signed)mo->state->var2)*FRACUNIT, mo->scale); - mo->angle = mo->target->angle; - - P_UnsetThingPosition(mo); - mo->x = destx; - mo->y = desty; - if (mo->eflags & MFE_VERTICALFLIP) - mo->z = (mo->target->z + mo->target->height - mo->height) - zoffs; - else - mo->z = mo->target->z + zoffs; - if (mo->state->var1) - P_SetUnderlayPosition(mo); - else - P_SetThingPosition(mo); - P_CheckPosition(mo, mo->x, mo->y); - } - P_SetTarget(&overlaycap, NULL); } static boolean P_AddShield(mobj_t *thing) @@ -5495,6 +6081,71 @@ static boolean P_AddShield(mobj_t *thing) return true; } +void P_RunOverlays(void) +{ + // run overlays + mobj_t *mo, *next = NULL; + fixed_t destx,desty,zoffs; + + for (mo = overlaycap; mo; mo = next) + { + I_Assert(!P_MobjWasRemoved(mo)); + + // grab next in chain, then unset the chain target + next = mo->hnext; + P_SetTarget(&mo->hnext, NULL); + + if (!mo->target) + continue; + if (!splitscreen /*&& rendermode != render_soft*/) + { + angle_t viewingangle; + + if (players[displayplayer].awayviewtics) + viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].awayviewmobj->x, players[displayplayer].awayviewmobj->y); + else if (!camera.chase && players[displayplayer].mo) + viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].mo->x, players[displayplayer].mo->y); + else + viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, camera.x, camera.y); + + if (!(mo->state->frame & FF_ANIMATE) && mo->state->var1) + viewingangle += ANGLE_180; + destx = mo->target->x + P_ReturnThrustX(mo->target, viewingangle, FixedMul(FRACUNIT/4, mo->scale)); + desty = mo->target->y + P_ReturnThrustY(mo->target, viewingangle, FixedMul(FRACUNIT/4, mo->scale)); + } + else + { + destx = mo->target->x; + desty = mo->target->y; + } + + mo->eflags = (mo->eflags & ~MFE_VERTICALFLIP) | (mo->target->eflags & MFE_VERTICALFLIP); + mo->scale = mo->destscale = mo->target->scale; + mo->angle = mo->target->angle; + + if (!(mo->state->frame & FF_ANIMATE)) + zoffs = FixedMul(((signed)mo->state->var2)*FRACUNIT, mo->scale); + // if you're using FF_ANIMATE on an overlay, + // then you're on your own. + else + zoffs = 0; + + P_UnsetThingPosition(mo); + mo->x = destx; + mo->y = desty; + if (mo->eflags & MFE_VERTICALFLIP) + mo->z = (mo->target->z + mo->target->height - mo->height) - zoffs; + else + mo->z = mo->target->z + zoffs; + if (mo->state->var1) + P_SetUnderlayPosition(mo); + else + P_SetThingPosition(mo); + P_CheckPosition(mo, mo->x, mo->y); + } + P_SetTarget(&overlaycap, NULL); +} + // Called only when MT_OVERLAY thinks. static void P_AddOverlay(mobj_t *thing) { @@ -5998,14 +6649,12 @@ void P_MobjThinker(mobj_t *mobj) else if (mobj->health <= 0) // Dead things think differently than the living. switch (mobj->type) { -#ifdef BLUE_SPHERES case MT_BLUEBALL: if ((mobj->tics>>2)+1 > 0 && (mobj->tics>>2)+1 <= tr_trans60) // tr_trans50 through tr_trans90, shifting once every second frame mobj->frame = (NUMTRANSMAPS-((mobj->tics>>2)+1))<frame = tr_trans60<z <= mobj->floorz) { @@ -6463,9 +7112,7 @@ void P_MobjThinker(mobj_t *mobj) break; case MT_RING: case MT_COIN: -#ifdef BLUE_SPHERES case MT_BLUEBALL: -#endif case MT_REDTEAMRING: case MT_BLUETEAMRING: // No need to check water. Who cares? @@ -6807,6 +7454,21 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s mobj->eflags &= ~MFE_JUSTHITFLOOR; } +#ifdef ESLOPE // Sliding physics for slidey mobjs! + if (mobj->type == MT_FLINGRING + || mobj->type == MT_FLINGCOIN + || P_WeaponOrPanel(mobj->type) + || mobj->type == MT_FLINGEMERALD + || mobj->type == MT_BIGTUMBLEWEED + || mobj->type == MT_LITTLETUMBLEWEED + || mobj->type == MT_CANNONBALLDECOR + || mobj->type == MT_FALLINGROCK) { + P_TryMove(mobj, mobj->x, mobj->y, true); // Sets mo->standingslope correctly + //if (mobj->standingslope) CONS_Printf("slope physics on mobj\n"); + P_ButteredSlope(mobj); + } +#endif + if (mobj->flags & (MF_ENEMY|MF_BOSS) && mobj->health && P_CheckDeathPitCollide(mobj)) // extra pit check in case these didn't have momz { @@ -7049,6 +7711,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->tics = st->tics; mobj->sprite = st->sprite; mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits.. + mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set + mobj->friction = ORIG_FRICTION; mobj->movefactor = ORIG_FRICTION_FACTOR; @@ -7069,8 +7733,16 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) // Make sure scale matches destscale immediately when spawned P_SetScale(mobj, mobj->destscale); - mobj->floorz = mobj->subsector->sector->floorheight; - mobj->ceilingz = mobj->subsector->sector->ceilingheight; + mobj->floorz = +#ifdef ESLOPE + mobj->subsector->sector->f_slope ? P_GetZAt(mobj->subsector->sector->f_slope, x, y) : +#endif + mobj->subsector->sector->floorheight; + mobj->ceilingz = +#ifdef ESLOPE + mobj->subsector->sector->c_slope ? P_GetZAt(mobj->subsector->sector->c_slope, x, y) : +#endif + mobj->subsector->sector->ceilingheight; // Tells MobjCheckWater that the water height was not set. mobj->watertop = INT32_MAX; @@ -7206,9 +7878,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) break; case MT_RING: case MT_COIN: -#ifdef BLUE_SPHERES case MT_BLUEBALL: -#endif nummaprings++; default: break; @@ -7266,6 +7936,7 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype mobj->tics = st->tics; mobj->sprite = st->sprite; mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits.. + mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set // set subsector and/or block links P_SetPrecipitationThingPosition(mobj); @@ -7333,9 +8004,7 @@ void P_RemoveMobj(mobj_t *mobj) if (mobj->spawnpoint && (mobj->type == MT_RING || mobj->type == MT_COIN -#ifdef BLUE_SPHERES || mobj->type == MT_BLUEBALL -#endif || mobj->type == MT_REDTEAMRING || mobj->type == MT_BLUETEAMRING || P_WeaponOrPanel(mobj->type)) @@ -8128,7 +8797,11 @@ void P_SpawnMapThing(mapthing_t *mthing) return; ss = R_PointInSubsector(mthing->x << FRACBITS, mthing->y << FRACBITS); - mthing->z = (INT16)((ss->sector->floorheight>>FRACBITS) + (mthing->options >> ZSHIFT)); + mthing->z = (INT16)((( +#ifdef ESLOPE + ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, mthing->x << FRACBITS, mthing->y << FRACBITS) : +#endif + ss->sector->floorheight)>>FRACBITS) + (mthing->options >> ZSHIFT)); if (numhuntemeralds < MAXHUNTEMERALDS) huntemeralds[numhuntemeralds++] = mthing; @@ -8246,14 +8919,22 @@ void P_SpawnMapThing(mapthing_t *mthing) ss = R_PointInSubsector(x, y); if (i == MT_NIGHTSBUMPER) - z = ss->sector->floorheight + ((mthing->options >> ZSHIFT) << FRACBITS); + z = ( +#ifdef ESLOPE + ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : +#endif + ss->sector->floorheight) + ((mthing->options >> ZSHIFT) << FRACBITS); else if (i == MT_AXIS || i == MT_AXISTRANSFER || i == MT_AXISTRANSFERLINE) z = ONFLOORZ; else if (i == MT_SPECIALSPIKEBALL || P_WeaponOrPanel(i) || i == MT_EMERALDSPAWN || i == MT_EMMY) { if (mthing->options & MTF_OBJECTFLIP) { - z = ss->sector->ceilingheight; + z = ( +#ifdef ESLOPE + ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : +#endif + ss->sector->ceilingheight); if (mthing->options & MTF_AMBUSH) // Special flag for rings z -= 24*FRACUNIT; @@ -8264,7 +8945,11 @@ void P_SpawnMapThing(mapthing_t *mthing) } else { - z = ss->sector->floorheight; + z = ( +#ifdef ESLOPE + ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : +#endif + ss->sector->floorheight); if (mthing->options & MTF_AMBUSH) // Special flag for rings z += 24*FRACUNIT; @@ -8284,9 +8969,17 @@ void P_SpawnMapThing(mapthing_t *mthing) // base positions if (flip) - z = ss->sector->ceilingheight - mobjinfo[i].height; + z = ( +#ifdef ESLOPE + ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : +#endif + ss->sector->ceilingheight) - mobjinfo[i].height; else - z = ss->sector->floorheight; + z = ( +#ifdef ESLOPE + ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : +#endif + ss->sector->floorheight); // offsetting if (mthing->options >> ZSHIFT) @@ -8800,7 +9493,11 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) // Screw these damn hoops, I need this thinker. //hoopcenter->flags |= MF_NOTHINK; - z += sec->floorheight; + z += +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight; hoopcenter->z = z - hoopcenter->height/2; @@ -8933,7 +9630,11 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER); hoopcenter->spawnpoint = mthing; - z += sec->floorheight; + z += +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight; hoopcenter->z = z - hoopcenter->height/2; P_UnsetThingPosition(hoopcenter); @@ -9045,7 +9746,11 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) // Wing logo item. else if (mthing->type == mobjinfo[MT_NIGHTSWING].doomednum) { - z = sec->floorheight; + z = +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); @@ -9086,24 +9791,30 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) ringthing = (gametype == GT_CTF) ? MT_BLUETEAMRING : MT_RING; break; default: -#ifdef BLUE_SPHERES // Spawn rings as blue spheres in special stages, ala S3+K. if (G_IsSpecialStage(gamemap) && useNightsSS) ringthing = MT_BLUEBALL; -#endif break; } // Set proper height if (mthing->options & MTF_OBJECTFLIP) { - z = sec->ceilingheight - mobjinfo[ringthing].height; + z = ( +#ifdef ESLOPE + sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : +#endif + sec->ceilingheight) - mobjinfo[ringthing].height; if (mthing->options >> ZSHIFT) z -= ((mthing->options >> ZSHIFT) << FRACBITS); } else { - z = sec->floorheight; + z = +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); } @@ -9147,23 +9858,29 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) if (ultimatemode && !(G_IsSpecialStage(gamemap) || maptol & TOL_NIGHTS)) return; -#ifdef BLUE_SPHERES // Spawn rings as blue spheres in special stages, ala S3+K. if (G_IsSpecialStage(gamemap) && useNightsSS) ringthing = MT_BLUEBALL; -#endif for (r = 1; r <= 5; r++) { if (mthing->options & MTF_OBJECTFLIP) { - z = sec->ceilingheight - mobjinfo[ringthing].height - dist*r; + z = ( +#ifdef ESLOPE + sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : +#endif + sec->ceilingheight) - mobjinfo[ringthing].height - dist*r; if (mthing->options >> ZSHIFT) z -= ((mthing->options >> ZSHIFT) << FRACBITS); } else { - z = sec->floorheight + dist*r; + z = ( +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight) + dist*r; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); } @@ -9184,7 +9901,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) // Diagonal rings (handles both types) else if (mthing->type == 602 || mthing->type == 603) // Diagonal rings (5) { - angle_t angle = ANGLE_45 * (mthing->angle/45); + angle_t angle = FixedAngle(mthing->angle*FRACUNIT); mobjtype_t ringthing = MT_RING; INT32 iterations = 5; if (mthing->type == 603) @@ -9194,11 +9911,9 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) if (ultimatemode && !(G_IsSpecialStage(gamemap) || maptol & TOL_NIGHTS)) return; -#ifdef BLUE_SPHERES // Spawn rings as blue spheres in special stages, ala S3+K. if (G_IsSpecialStage(gamemap) && useNightsSS) ringthing = MT_BLUEBALL; -#endif angle >>= ANGLETOFINESHIFT; @@ -9209,13 +9924,21 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) if (mthing->options & MTF_OBJECTFLIP) { - z = sec->ceilingheight - mobjinfo[ringthing].height - 64*FRACUNIT*r; + z = ( +#ifdef ESLOPE + sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : +#endif + sec->ceilingheight) - mobjinfo[ringthing].height - 64*FRACUNIT*r; if (mthing->options >> ZSHIFT) z -= ((mthing->options >> ZSHIFT) << FRACBITS); } else { - z = sec->floorheight + 64*FRACUNIT*r; + z = ( +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight) + 64*FRACUNIT*r; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); } @@ -9246,7 +9969,11 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) size = 192*FRACUNIT; } - z = sec->floorheight; + z = +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight; if (mthing->options >> ZSHIFT) z += ((mthing->options >> ZSHIFT) << FRACBITS); @@ -9279,11 +10006,9 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing) if (ultimatemode && !(G_IsSpecialStage(gamemap) || (maptol & TOL_NIGHTS))) continue; -#ifdef BLUE_SPHERES // Spawn rings as blue spheres in special stages, ala S3+K. if (G_IsSpecialStage(gamemap) && useNightsSS) itemToSpawn = MT_BLUEBALL; -#endif } fa = i*FINEANGLES/numitems; diff --git a/src/p_mobj.h b/src/p_mobj.h index a34319ffe..2b66af57f 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -271,6 +271,7 @@ typedef struct mobj_s spritenum_t sprite; // used to find patch_t and flip value UINT32 frame; // frame number, plus bits see p_pspr.h UINT8 sprite2; // player sprites + UINT16 anim_duration; // for FF_ANIMATE states struct msecnode_s *touching_sectorlist; // a linked list of sectors where this object appears @@ -355,6 +356,10 @@ typedef struct mobj_s INT32 cusval; INT32 cvmem; +#ifdef ESLOPE + struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) +#endif + // WARNING: New fields must be added separately to savegame and Lua. } mobj_t; @@ -380,7 +385,8 @@ typedef struct precipmobj_s // More drawing info: to determine current sprite. angle_t angle; // orientation spritenum_t sprite; // used to find patch_t and flip value - INT32 frame; // frame number, plus bits see p_pspr.h + UINT32 frame; // frame number, plus bits see p_pspr.h + UINT16 anim_duration; // for FF_ANIMATE states struct mprecipsecnode_s *touching_sectorlist; // a linked list of sectors where this object appears diff --git a/src/p_polyobj.c b/src/p_polyobj.c index ab7a63411..41616e587 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -442,6 +442,8 @@ newseg: // seg's ending vertex. for (i = 0; i < numsegs; ++i) { + if (segs[i].side != 0) // needs to be frontfacing + continue; if (segs[i].v1->x == seg->v2->x && segs[i].v1->y == seg->v2->y) { // Make sure you didn't already add this seg... @@ -610,14 +612,17 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id) INT32 poflags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES; INT32 parentID = 0, potrans = 0; + if (seg->side != 0) // needs to be frontfacing + continue; + if (seg->linedef->special != POLYOBJ_START_LINE) continue; - + if (seg->linedef->tag != po->id) continue; Polyobj_GetInfo(po->id, &poflags, &parentID, &potrans); // apply extra settings if they exist! - + // save original flags and translucency to reference later for netgames! po->spawnflags = po->flags = poflags; po->spawntrans = po->translucency = potrans; diff --git a/src/p_pspr.h b/src/p_pspr.h index e0b57675c..53ad30abd 100644 --- a/src/p_pspr.h +++ b/src/p_pspr.h @@ -36,9 +36,11 @@ #endif /// \brief Frame flags: only the frame number -#define FF_FRAMEMASK 0x7fff +#define FF_FRAMEMASK 0x3fff +/// \brief Frame flags: Simple stateless animation +#define FF_ANIMATE 0x4000 /// \brief Frame flags: frame always appears full bright -#define FF_FULLBRIGHT 0x8000 // +#define FF_FULLBRIGHT 0x8000 /// \brief Frame flags: 0 = no trans(opaque), 1-15 = transl. table #define FF_TRANSMASK 0xf0000 /// \brief shift for FF_TRANSMASK diff --git a/src/p_saveg.c b/src/p_saveg.c index 5a2da118b..2c9f3463c 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -30,6 +30,9 @@ #include "r_sky.h" #include "p_polyobj.h" #include "lua_script.h" +#ifdef ESLOPE +#include "p_slopes.h" +#endif savedata_t savedata; UINT8 *save_p; @@ -633,7 +636,7 @@ static void P_NetArchiveWorld(void) if (li->special != SHORT(mld->special)) diff |= LD_SPECIAL; - if (mld->special == 321 || mld->special == 322) // only reason li->callcount would be non-zero is if either of these are involved + if (SHORT(mld->special) == 321 || SHORT(mld->special) == 322) // only reason li->callcount would be non-zero is if either of these are involved diff |= LD_CLLCOUNT; if (li->sidenum[0] != 0xffff) @@ -921,7 +924,8 @@ typedef enum MD2_EXTVAL1 = 1<<5, MD2_EXTVAL2 = 1<<6, MD2_HNEXT = 1<<7, - MD2_HPREV = 1<<8 + MD2_HPREV = 1<<8, + MD2_SLOPE = 1<<9 } mobj_diff2_t; typedef enum @@ -1056,6 +1060,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff |= MD_SPRITE; if (mobj->frame != mobj->state->frame) diff |= MD_FRAME; + if (mobj->anim_duration != (UINT16)mobj->state->var2) + diff |= MD_FRAME; if (mobj->eflags) diff |= MD_EFLAGS; if (mobj->player) @@ -1111,6 +1117,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff2 |= MD2_HNEXT; if (mobj->hprev) diff2 |= MD2_HPREV; + if (mobj->standingslope) + diff2 |= MD2_SLOPE; if (diff2 != 0) diff |= MD_MORE; @@ -1177,7 +1185,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEUINT8(save_p, mobj->sprite2); } if (diff & MD_FRAME) + { WRITEUINT32(save_p, mobj->frame); + WRITEUINT16(save_p, mobj->anim_duration); + } if (diff & MD_EFLAGS) WRITEUINT16(save_p, mobj->eflags); if (diff & MD_PLAYER) @@ -1226,6 +1237,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, mobj->hnext->mobjnum); if (diff2 & MD2_HPREV) WRITEUINT32(save_p, mobj->hprev->mobjnum); + if (diff2 & MD2_SLOPE) + WRITEUINT16(save_p, mobj->standingslope->id); WRITEUINT32(save_p, mobj->mobjnum); } @@ -2007,9 +2020,15 @@ static void LoadMobjThinker(actionf_p1 thinker) mobj->sprite2 = mobj->state->frame&FF_FRAMEMASK; } if (diff & MD_FRAME) + { mobj->frame = READUINT32(save_p); + mobj->anim_duration = READUINT16(save_p); + } else + { mobj->frame = mobj->state->frame; + mobj->anim_duration = (UINT16)mobj->state->var2; + } if (diff & MD_EFLAGS) mobj->eflags = READUINT16(save_p); if (diff & MD_PLAYER) @@ -2079,6 +2098,9 @@ static void LoadMobjThinker(actionf_p1 thinker) mobj->hnext = (mobj_t *)(size_t)READUINT32(save_p); if (diff2 & MD2_HPREV) mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p); + if (diff2 & MD2_SLOPE) + mobj->standingslope = P_SlopeById(READUINT16(save_p)); + if (diff & MD_REDFLAG) { @@ -3192,7 +3214,7 @@ static inline boolean P_NetUnArchiveMisc(void) // tell the sound code to reset the music since we're skipping what // normally sets this flag - mapmusic |= MUSIC_RELOADRESET; + mapmusflags |= MUSIC_RELOADRESET; G_SetGamestate(READINT16(save_p)); diff --git a/src/p_setup.c b/src/p_setup.c index 9367049ce..19d5a1556 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -72,6 +72,10 @@ #include "hardware/hw_light.h" #endif +#ifdef ESLOPE +#include "p_slopes.h" +#endif + // // Map MD5, calculated on level load. // Sent to clients in PT_SERVERINFO. @@ -176,10 +180,11 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) mapheaderinfo[num]->typeoflevel = 0; DEH_WriteUndoline("NEXTLEVEL", va("%d", mapheaderinfo[num]->nextlevel), UNDO_NONE); mapheaderinfo[num]->nextlevel = (INT16)(i + 1); - DEH_WriteUndoline("MUSICSLOT", va("%d", mapheaderinfo[num]->musicslot), UNDO_NONE); - mapheaderinfo[num]->musicslot = mus_map01m + num; - DEH_WriteUndoline("MUSICSLOTTRACK", va("%d", mapheaderinfo[num]->musicslottrack), UNDO_NONE); - mapheaderinfo[num]->musicslottrack = 0; + DEH_WriteUndoline("MUSIC", mapheaderinfo[num]->musname, UNDO_NONE); + snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i)); + mapheaderinfo[num]->musname[6] = 0; + DEH_WriteUndoline("MUSICTRACK", va("%d", mapheaderinfo[num]->mustrack), UNDO_NONE); + mapheaderinfo[num]->mustrack = 0; DEH_WriteUndoline("FORCECHARACTER", va("%d", mapheaderinfo[num]->forcecharacter), UNDO_NONE); mapheaderinfo[num]->forcecharacter[0] = '\0'; DEH_WriteUndoline("WEATHER", va("%d", mapheaderinfo[num]->weather), UNDO_NONE); @@ -846,7 +851,7 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum) // // P_LoadThings // -static void P_LoadThings(lumpnum_t lumpnum) +static void P_PrepareThings(lumpnum_t lumpnum) { size_t i; mapthing_t *mt; @@ -884,13 +889,27 @@ static void P_LoadThings(lumpnum_t lumpnum) } Z_Free(datastart); +} + +static void P_LoadThings(void) +{ + size_t i; + mapthing_t *mt; + + // Loading the things lump itself into memory is now handled in P_PrepareThings, above + mt = mapthings; numhuntemeralds = 0; for (i = 0; i < nummapthings; i++, mt++) { + sector_t *mtsector = R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)->sector; + // Z for objects - mt->z = (INT16)(R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS) - ->sector->floorheight>>FRACBITS); + mt->z = (INT16)( +#ifdef ESLOPE + mtsector->f_slope ? P_GetZAt(mtsector->f_slope, mt->x << FRACBITS, mt->y << FRACBITS) : +#endif + mtsector->floorheight)>>FRACBITS; if (mt->type == 1700 // MT_AXIS || mt->type == 1701 // MT_AXISTRANSFER @@ -1421,6 +1440,29 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum) #endif case 413: // Change music + { + char process[8+1]; + + sd->toptexture = sd->midtexture = sd->bottomtexture = 0; + if (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0') + { + M_Memcpy(process,msd->bottomtexture,8); + process[8] = '\0'; + sd->bottomtexture = get_number(process)-1; + } + M_Memcpy(process,msd->toptexture,8); + process[8] = '\0'; + sd->text = Z_Malloc(7, PU_LEVEL, NULL); + + // If they type in O_ or D_ and their music name, just shrug, + // then copy the rest instead. + if ((process[0] == 'O' || process[0] == 'D') && process[7]) + M_Memcpy(sd->text, process+2, 6); + else // Assume it's a proper music name. + M_Memcpy(sd->text, process, 6); + sd->text[6] = 0; + break; + } case 414: // Play SFX { sd->toptexture = sd->midtexture = sd->bottomtexture = 0; @@ -1431,13 +1473,6 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum) process[8] = '\0'; sd->toptexture = get_number(process); } - if (sd->special == 413 && (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0')) - { - char process[8+1]; - M_Memcpy(process,msd->bottomtexture,8); - process[8] = '\0'; - sd->bottomtexture = get_number(process)-1; - } break; } @@ -2115,7 +2150,8 @@ void P_LoadThingsOnly(void) P_LevelInitStuff(); - P_LoadThings(lastloadedmaplumpnum + ML_THINGS); + P_PrepareThings(lastloadedmaplumpnum + ML_THINGS); + P_LoadThings(); P_SpawnSecretItems(true); } @@ -2351,7 +2387,7 @@ boolean P_SetupLevel(boolean skipprecip) // use gamemap to get map number. // 99% of the things already did, so. // Map header should always be in place at this point - INT32 i, loadprecip = 1; + INT32 i, loadprecip = 1, ranspecialwipe = 0; INT32 loademblems = 1; INT32 fromnetsave = 0; boolean loadedbm = false; @@ -2424,6 +2460,28 @@ boolean P_SetupLevel(boolean skipprecip) // will be set by player think. players[consoleplayer].viewz = 1; + // Special stage fade to white + // This is handled BEFORE sounds are stopped. + if (rendermode != render_none && G_IsSpecialStage(gamemap)) + { + tic_t starttime = I_GetTime(); + tic_t endtime = starttime + (3*TICRATE)/2; + + S_StartSound(NULL, sfx_s3kaf); + + F_WipeStartScreen(); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0); + + F_WipeEndScreen(); + F_RunWipe(wipedefs[wipe_speclevel_towhite], false); + + // Hold on white for extra effect. + while (I_GetTime() < endtime) + I_Sleep(); + + ranspecialwipe = 1; + } + // Make sure all sounds are stopped before Z_FreeTags. S_StopSounds(); S_ClearSfx(); @@ -2433,25 +2491,28 @@ boolean P_SetupLevel(boolean skipprecip) S_Start(); // Let's fade to black here - if (rendermode != render_none) + // But only if we didn't do the special stage wipe + if (rendermode != render_none && !ranspecialwipe) { F_WipeStartScreen(); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); F_WipeEndScreen(); F_RunWipe(wipedefs[wipe_level_toblack], false); + } + // Print "SPEEDING OFF TO [ZONE] [ACT 1]..." + if (rendermode != render_none) + { // Don't include these in the fade! - { - char tx[64]; - V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to...")); - snprintf(tx, 63, "%s%s%s", - mapheaderinfo[gamemap-1]->lvlttl, - (mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE", - (mapheaderinfo[gamemap-1]->actnum > 0) ? va(", Act %d",mapheaderinfo[gamemap-1]->actnum) : ""); - V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx); - I_UpdateNoVsync(); - } + char tx[64]; + V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to...")); + snprintf(tx, 63, "%s%s%s", + mapheaderinfo[gamemap-1]->lvlttl, + (mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE", + (mapheaderinfo[gamemap-1]->actnum > 0) ? va(", Act %d",mapheaderinfo[gamemap-1]->actnum) : ""); + V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx); + I_UpdateNoVsync(); } #ifdef HAVE_BLUA @@ -2532,7 +2593,13 @@ boolean P_SetupLevel(boolean skipprecip) P_MapStart(); - P_LoadThings(lastloadedmaplumpnum + ML_THINGS); + P_PrepareThings(lastloadedmaplumpnum + ML_THINGS); + +#ifdef ESLOPE + P_ResetDynamicSlopes(); +#endif + + P_LoadThings(); P_SpawnSecretItems(loademblems); @@ -2743,7 +2810,7 @@ boolean P_SetupLevel(boolean skipprecip) // Remove the loading shit from the screen if (rendermode != render_none) - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (ranspecialwipe) ? 0 : 31); if (precache || dedicated) R_PrecacheLevel(); diff --git a/src/p_slopes.c b/src/p_slopes.c new file mode 100644 index 000000000..2d55cf194 --- /dev/null +++ b/src/p_slopes.c @@ -0,0 +1,1139 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright(C) 2004 Stephen McGranahan +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//-------------------------------------------------------------------------- +// +// DESCRIPTION: +// Slopes +// SoM created 05/10/09 +// ZDoom + Eternity Engine Slopes, ported and enhanced by Kalaron +// +//----------------------------------------------------------------------------- + + +#include "doomdef.h" +#include "r_defs.h" +#include "r_state.h" +#include "m_bbox.h" +#include "z_zone.h" +#include "p_local.h" +#include "p_spec.h" +#include "p_slopes.h" +#include "p_setup.h" +#include "r_main.h" +#include "p_maputl.h" +#include "w_wad.h" + +#ifdef ESLOPE + +static pslope_t *slopelist = NULL; +static UINT16 slopecount = 0; + +// Calculate line normal +static void P_CalculateSlopeNormal(pslope_t *slope) { + slope->normal.z = FINECOSINE(slope->zangle>>ANGLETOFINESHIFT); + slope->normal.x = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.x); + slope->normal.y = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.y); +} + +// With a vertex slope that has its vertices set, configure relevant slope info +static void P_ReconfigureVertexSlope(pslope_t *slope) +{ + vector3_t vec1, vec2; + + // Set slope normal + vec1.x = (slope->vertices[1]->x - slope->vertices[0]->x) << FRACBITS; + vec1.y = (slope->vertices[1]->y - slope->vertices[0]->y) << FRACBITS; + vec1.z = (slope->vertices[1]->z - slope->vertices[0]->z) << FRACBITS; + + vec2.x = (slope->vertices[2]->x - slope->vertices[0]->x) << FRACBITS; + vec2.y = (slope->vertices[2]->y - slope->vertices[0]->y) << FRACBITS; + vec2.z = (slope->vertices[2]->z - slope->vertices[0]->z) << FRACBITS; + + // ugggggggh fixed-point maaaaaaath + slope->extent = max( + max(max(abs(vec1.x), abs(vec1.y)), abs(vec1.z)), + max(max(abs(vec2.x), abs(vec2.y)), abs(vec2.z)) + ) >> (FRACBITS+5); + vec1.x /= slope->extent; + vec1.y /= slope->extent; + vec1.z /= slope->extent; + vec2.x /= slope->extent; + vec2.y /= slope->extent; + vec2.z /= slope->extent; + + FV3_Cross(&vec1, &vec2, &slope->normal); + + slope->extent = R_PointToDist2(0, 0, R_PointToDist2(0, 0, slope->normal.x, slope->normal.y), slope->normal.z); + if (slope->normal.z < 0) + slope->extent = -slope->extent; + + slope->normal.x = FixedDiv(slope->normal.x, slope->extent); + slope->normal.y = FixedDiv(slope->normal.y, slope->extent); + slope->normal.z = FixedDiv(slope->normal.z, slope->extent); + + // Set origin + slope->o.x = slope->vertices[0]->x << FRACBITS; + slope->o.y = slope->vertices[0]->y << FRACBITS; + slope->o.z = slope->vertices[0]->z << FRACBITS; + + if (slope->normal.x == 0 && slope->normal.y == 0) { // Set some defaults for a non-sloped "slope" + slope->zangle = slope->xydirection = 0; + slope->zdelta = slope->d.x = slope->d.y = 0; + } else { + // Get direction vector + slope->extent = R_PointToDist2(0, 0, slope->normal.x, slope->normal.y); + slope->d.x = -FixedDiv(slope->normal.x, slope->extent); + slope->d.y = -FixedDiv(slope->normal.y, slope->extent); + + // Z delta + slope->zdelta = FixedDiv(slope->extent, slope->normal.z); + + // Get angles + slope->xydirection = R_PointToAngle2(0, 0, slope->d.x, slope->d.y)+ANGLE_180; + slope->zangle = -R_PointToAngle2(0, 0, FRACUNIT, slope->zdelta); + } +} + +// Recalculate dynamic slopes +void P_RunDynamicSlopes(void) { + pslope_t *slope; + + for (slope = slopelist; slope; slope = slope->next) { + fixed_t zdelta; + + if (slope->flags & SL_NODYNAMIC) + continue; + + switch(slope->refpos) { + case 1: // front floor + zdelta = slope->sourceline->backsector->floorheight - slope->sourceline->frontsector->floorheight; + slope->o.z = slope->sourceline->frontsector->floorheight; + break; + case 2: // front ceiling + zdelta = slope->sourceline->backsector->ceilingheight - slope->sourceline->frontsector->ceilingheight; + slope->o.z = slope->sourceline->frontsector->ceilingheight; + break; + case 3: // back floor + zdelta = slope->sourceline->frontsector->floorheight - slope->sourceline->backsector->floorheight; + slope->o.z = slope->sourceline->backsector->floorheight; + break; + case 4: // back ceiling + zdelta = slope->sourceline->frontsector->ceilingheight - slope->sourceline->backsector->ceilingheight; + slope->o.z = slope->sourceline->backsector->ceilingheight; + break; + case 5: // vertices + { + mapthing_t *mt; + size_t i; + INT32 l; + line_t *line; + + for (i = 0; i < 3; i++) { + mt = slope->vertices[i]; + l = P_FindSpecialLineFromTag(799, mt->angle, -1); + if (l != -1) { + line = &lines[l]; + mt->z = line->frontsector->floorheight >> FRACBITS; + } + } + + P_ReconfigureVertexSlope(slope); + } + continue; // TODO + + default: + I_Error("P_RunDynamicSlopes: slope has invalid type!"); + } + + if (slope->zdelta != FixedDiv(zdelta, slope->extent)) { + slope->zdelta = FixedDiv(zdelta, slope->extent); + slope->zangle = R_PointToAngle2(0, 0, slope->extent, -zdelta); + P_CalculateSlopeNormal(slope); + } + } +} + +// +// P_MakeSlope +// +// Alocates and fill the contents of a slope structure. +// +static pslope_t *P_MakeSlope(const vector3_t *o, const vector2_t *d, + const fixed_t zdelta, UINT8 flags) +{ + pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL); + memset(ret, 0, sizeof(*ret)); + + ret->o.x = o->x; + ret->o.y = o->y; + ret->o.z = o->z; + + ret->d.x = d->x; + ret->d.y = d->y; + + ret->zdelta = zdelta; + + ret->flags = flags; + + // Add to the slope list + ret->next = slopelist; + slopelist = ret; + + slopecount++; + ret->id = slopecount; + + return ret; +} + +// +// P_GetExtent +// +// Returns the distance to the first line within the sector that +// is intersected by a line parallel to the plane normal with the point (ox, oy) +// +static fixed_t P_GetExtent(sector_t *sector, line_t *line) +{ + // ZDoom code reference: v3float_t = vertex_t + fixed_t fardist = -FRACUNIT; + size_t i; + + // Find furthest vertex from the reference line. It, along with the two ends + // of the line, will define the plane. + // SRB2CBTODO: Use a formula to get the slope to slide objects depending on how steep + for(i = 0; i < sector->linecount; i++) + { + line_t *li = sector->lines[i]; + vertex_t tempv; + fixed_t dist; + + // Don't compare to the slope line. + if(li == line) + continue; + + P_ClosestPointOnLine(li->v1->x, li->v1->y, line, &tempv); + dist = R_PointToDist2(tempv.x, tempv.y, li->v1->x, li->v1->y); + if(dist > fardist) + fardist = dist; + + // Okay, maybe do it for v2 as well? + P_ClosestPointOnLine(li->v2->x, li->v2->y, line, &tempv); + dist = R_PointToDist2(tempv.x, tempv.y, li->v2->x, li->v2->y); + if(dist > fardist) + fardist = dist; + } + + return fardist; +} + + +// +// P_SpawnSlope_Line +// +// Creates one or more slopes based on the given line type and front/back +// sectors. +// Kalaron: Check if dynamic slopes need recalculation +// +void P_SpawnSlope_Line(int linenum) +{ + // With dynamic slopes, it's fine to just leave this function as normal, + // because checking to see if a slope had changed will waste more memory than + // if the slope was just updated when called + line_t *line = lines + linenum; + INT16 special = line->special; + pslope_t *fslope = NULL, *cslope = NULL; + vector3_t origin, point; + vector2_t direction; + fixed_t nx, ny, dz, extent; + + boolean frontfloor = (special == 700 || special == 702 || special == 703); + boolean backfloor = (special == 710 || special == 712 || special == 713); + boolean frontceil = (special == 701 || special == 702 || special == 713); + boolean backceil = (special == 711 || special == 712 || special == 703); + + UINT8 flags = 0; // Slope flags + if (line->flags & ML_NOSONIC) + flags |= SL_NOPHYSICS; + if (line->flags & ML_NOTAILS) + flags |= SL_NODYNAMIC; + if (line->flags & ML_NOKNUX) + flags |= SL_ANCHORVERTEX; + + if(!frontfloor && !backfloor && !frontceil && !backceil) + { + CONS_Printf("P_SpawnSlope_Line called with non-slope line special.\n"); + return; + } + + if(!line->frontsector || !line->backsector) + { + CONS_Printf("P_SpawnSlope_Line used on a line without two sides.\n"); + return; + } + + { + fixed_t len = R_PointToDist2(0, 0, line->dx, line->dy); + nx = FixedDiv(line->dy, len); + ny = -FixedDiv(line->dx, len); + } + + // SRB2CBTODO: Transform origin relative to the bounds of an individual FOF + origin.x = line->v1->x + (line->v2->x - line->v1->x)/2; + origin.y = line->v1->y + (line->v2->y - line->v1->y)/2; + + // For FOF slopes, make a special function to copy to the xy origin & direction relative to the position of the FOF on the map! + if(frontfloor || frontceil) + { + line->frontsector->hasslope = true; // Tell the software renderer that we're sloped + + origin.z = line->backsector->floorheight; + direction.x = nx; + direction.y = ny; + + extent = P_GetExtent(line->frontsector, line); + + if(extent < 0) + { + CONS_Printf("P_SpawnSlope_Line failed to get frontsector extent on line number %i\n", linenum); + return; + } + + // reposition the origin according to the extent + point.x = origin.x + FixedMul(direction.x, extent); + point.y = origin.y + FixedMul(direction.y, extent); + direction.x = -direction.x; + direction.y = -direction.y; + + // TODO: We take origin and point 's xy values and translate them to the center of an FOF! + + if(frontfloor) + { + fixed_t highest, lowest; + size_t l; + point.z = line->frontsector->floorheight; // Startz + dz = FixedDiv(origin.z - point.z, extent); // Destinationz + + // In P_SpawnSlopeLine the origin is the centerpoint of the sourcelinedef + + fslope = line->frontsector->f_slope = + P_MakeSlope(&point, &direction, dz, flags); + + // Set up some shit + fslope->extent = extent; + fslope->refpos = 1; + + // Now remember that f_slope IS a vector + // fslope->o = origin 3D point 1 of the vector + // fslope->d = destination 3D point 2 of the vector + // fslope->normal is a 3D line perpendicular to the 3D vector + + // Sync the linedata of the line that started this slope + // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? + fslope->sourceline = line; + + // To find the real highz/lowz of a slope, you need to check all the vertexes + // in the slope's sector with P_GetZAt to get the REAL lowz & highz + // Although these slopes are set by floorheights the ANGLE is what a slope is, + // so technically any slope can extend on forever (they are just bound by sectors) + // *You can use sourceline as a reference to see if two slopes really are the same + + // Default points for high and low + highest = point.z > origin.z ? point.z : origin.z; + lowest = point.z < origin.z ? point.z : origin.z; + + // Now check to see what the REAL high and low points of the slope inside the sector + // TODO: Is this really needed outside of FOFs? -Red + + for (l = 0; l < line->frontsector->linecount; l++) + { + fixed_t height = P_GetZAt(line->frontsector->f_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y); + + if (height > highest) + highest = height; + + if (height < lowest) + lowest = height; + } + + // Sets extra clipping data for the frontsector's slope + fslope->highz = highest; + fslope->lowz = lowest; + + fslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z); + fslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y); + + P_CalculateSlopeNormal(fslope); + } + if(frontceil) + { + fixed_t highest, lowest; + size_t l; + origin.z = line->backsector->ceilingheight; + point.z = line->frontsector->ceilingheight; + dz = FixedDiv(origin.z - point.z, extent); + + cslope = line->frontsector->c_slope = + P_MakeSlope(&point, &direction, dz, flags); + + // Set up some shit + cslope->extent = extent; + cslope->refpos = 2; + + // Sync the linedata of the line that started this slope + // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? + cslope->sourceline = line; + + // Remember the way the slope is formed + highest = point.z > origin.z ? point.z : origin.z; + lowest = point.z < origin.z ? point.z : origin.z; + + for (l = 0; l < line->frontsector->linecount; l++) + { + fixed_t height = P_GetZAt(line->frontsector->c_slope, line->frontsector->lines[l]->v1->x, line->frontsector->lines[l]->v1->y); + + if (height > highest) + highest = height; + + if (height < lowest) + lowest = height; + } + + // This line special sets extra clipping data for the frontsector's slope + cslope->highz = highest; + cslope->lowz = lowest; + + cslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z); + cslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y); + + P_CalculateSlopeNormal(cslope); + } + } + if(backfloor || backceil) + { + line->backsector->hasslope = true; // Tell the software renderer that we're sloped + + origin.z = line->frontsector->floorheight; + // Backsector + direction.x = -nx; + direction.y = -ny; + + extent = P_GetExtent(line->backsector, line); + + if(extent < 0) + { + CONS_Printf("P_SpawnSlope_Line failed to get backsector extent on line number %i\n", linenum); + return; + } + + // reposition the origin according to the extent + point.x = origin.x + FixedMul(direction.x, extent); + point.y = origin.y + FixedMul(direction.y, extent); + direction.x = -direction.x; + direction.y = -direction.y; + + if(backfloor) + { + fixed_t highest, lowest; + size_t l; + point.z = line->backsector->floorheight; + dz = FixedDiv(origin.z - point.z, extent); + + fslope = line->backsector->f_slope = + P_MakeSlope(&point, &direction, dz, flags); + + // Set up some shit + fslope->extent = extent; + fslope->refpos = 3; + + // Sync the linedata of the line that started this slope + // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? + fslope->sourceline = line; + + // Remember the way the slope is formed + highest = point.z > origin.z ? point.z : origin.z; + lowest = point.z < origin.z ? point.z : origin.z; + + for (l = 0; l < line->backsector->linecount; l++) + { + fixed_t height = P_GetZAt(line->backsector->f_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y); + + if (height > highest) + highest = height; + + if (height < lowest) + lowest = height; + } + + // This line special sets extra clipping data for the frontsector's slope + fslope->highz = highest; + fslope->lowz = lowest; + + fslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z); + fslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y); + + P_CalculateSlopeNormal(fslope); + } + if(backceil) + { + fixed_t highest, lowest; + size_t l; + origin.z = line->frontsector->ceilingheight; + point.z = line->backsector->ceilingheight; + dz = FixedDiv(origin.z - point.z, extent); + + cslope = line->backsector->c_slope = + P_MakeSlope(&point, &direction, dz, flags); + + // Set up some shit + cslope->extent = extent; + cslope->refpos = 4; + + // Sync the linedata of the line that started this slope + // SRB2CBTODO: Anything special for remote(control sector)-based slopes later? + cslope->sourceline = line; + + // Remember the way the slope is formed + highest = point.z > origin.z ? point.z : origin.z; + lowest = point.z < origin.z ? point.z : origin.z; + + for (l = 0; l < line->backsector->linecount; l++) + { + fixed_t height = P_GetZAt(line->backsector->c_slope, line->backsector->lines[l]->v1->x, line->backsector->lines[l]->v1->y); + + if (height > highest) + highest = height; + + if (height < lowest) + lowest = height; + } + + // This line special sets extra clipping data for the backsector's slope + cslope->highz = highest; + cslope->lowz = lowest; + + cslope->zangle = R_PointToAngle2(0, origin.z, extent, point.z); + cslope->xydirection = R_PointToAngle2(origin.x, origin.y, point.x, point.y); + + P_CalculateSlopeNormal(cslope); + } + } + + if(!line->tag) + return; +} + +// +// P_NewVertexSlope +// +// Creates a new slope from three vertices with the specified IDs +// +static pslope_t *P_NewVertexSlope(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flags) +{ + size_t i; + mapthing_t *mt = mapthings; + + pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL); + memset(ret, 0, sizeof(*ret)); + + // Start by setting flags + ret->flags = flags; + + // Now set up the vertex list + ret->vertices = Z_Malloc(3*sizeof(mapthing_t), PU_LEVEL, NULL); + memset(ret->vertices, 0, 3*sizeof(mapthing_t)); + + // And... look for the vertices in question. + for (i = 0; i < nummapthings; i++, mt++) { + if (mt->type != 750) // Haha, I'm hijacking the old Chaos Spawn thingtype for something! + continue; + + if (!ret->vertices[0] && mt->angle == tag1) + ret->vertices[0] = mt; + else if (!ret->vertices[1] && mt->angle == tag2) + ret->vertices[1] = mt; + else if (!ret->vertices[2] && mt->angle == tag3) + ret->vertices[2] = mt; + } + + if (!ret->vertices[0]) + CONS_Printf("PANIC 0\n"); + if (!ret->vertices[1]) + CONS_Printf("PANIC 1\n"); + if (!ret->vertices[2]) + CONS_Printf("PANIC 2\n"); + + // Now set heights for each vertex, because they haven't been set yet + for (i = 0; i < 3; i++) { + mt = ret->vertices[i]; + if (mt->extrainfo) + mt->z = mt->options; + else + mt->z = (R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)->sector->floorheight >> FRACBITS) + (mt->options >> ZSHIFT); + } + + P_ReconfigureVertexSlope(ret); + ret->refpos = 5; + + // Add to the slope list + ret->next = slopelist; + slopelist = ret; + + slopecount++; + ret->id = slopecount; + + return ret; +} + + + +// +// P_CopySectorSlope +// +// Searches through tagged sectors and copies +// +void P_CopySectorSlope(line_t *line) +{ + sector_t *fsec = line->frontsector; + int i, special = line->special; + + // Check for copy linedefs + for(i = -1; (i = P_FindSectorFromLineTag(line, i)) >= 0;) + { + sector_t *srcsec = sectors + i; + + if((special - 719) & 1 && !fsec->f_slope && srcsec->f_slope) + fsec->f_slope = srcsec->f_slope; //P_CopySlope(srcsec->f_slope); + if((special - 719) & 2 && !fsec->c_slope && srcsec->c_slope) + fsec->c_slope = srcsec->c_slope; //P_CopySlope(srcsec->c_slope); + } + + fsec->hasslope = true; + + line->special = 0; // Linedef was use to set slopes, it finished its job, so now make it a normal linedef +} + +// +// P_SlopeById +// +// Looks in the slope list for a slope with a specified ID. Mostly useful for netgame sync +// +pslope_t *P_SlopeById(UINT16 id) +{ + pslope_t *ret; + for (ret = slopelist; ret && ret->id != id; ret = ret->next); + return ret; +} + +#ifdef SPRINGCLEAN +#include "byteptr.h" + +#include "p_setup.h" +#include "p_local.h" + +//========================================================================== +// +// P_SetSlopesFromVertexHeights +// +//========================================================================== +void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum) +{ + mapthing_t *mt; + boolean vt_found = false; + size_t i, j, k, l, q; + + //size_t i; + //mapthing_t *mt; + char *data; + char *datastart; + + // SRB2CBTODO: WHAT IS (5 * sizeof (short))?! It = 10 + // anything else seems to make a map not load properly, + // but this hard-coded value MUST have some reason for being what it is + size_t snummapthings = W_LumpLength(lumpnum) / (5 * sizeof (short)); + mapthing_t *smapthings = Z_Calloc(snummapthings * sizeof (*smapthings), PU_LEVEL, NULL); + fixed_t x, y; + sector_t *sector; + // Spawn axis points first so they are + // at the front of the list for fast searching. + data = datastart = W_CacheLumpNum(lumpnum, PU_LEVEL); + mt = smapthings; + for (i = 0; i < snummapthings; i++, mt++) + { + mt->x = READINT16(data); + mt->y = READINT16(data); + mt->angle = READINT16(data); + mt->type = READINT16(data); + mt->options = READINT16(data); + // mt->z hasn't been set yet! + //mt->extrainfo = (byte)(mt->type >> 12); // slope things are special, they have a bigger range of types + + //mt->type &= 4095; // SRB2CBTODO: WHAT IS THIS???? Mobj type limits?!!!! + x = mt->x*FRACUNIT; + y = mt->y*FRACUNIT; + sector = R_PointInSubsector(x, y)->sector; + // Z for objects +#ifdef ESLOPE + if (sector->f_slope) + mt->z = (short)(P_GetZAt(sector->f_slope, x, y)>>FRACBITS); + else +#endif + mt->z = (short)(sector->floorheight>>FRACBITS); + + mt->z = mt->z + (mt->options >> ZSHIFT); + + if (mt->type == THING_VertexFloorZ || mt->type == THING_VertexCeilingZ) // THING_VertexFloorZ + { + for(l = 0; l < numvertexes; l++) + { + if (vertexes[l].x == mt->x*FRACUNIT && vertexes[l].y == mt->y*FRACUNIT) + { + if (mt->type == THING_VertexFloorZ) + { + vertexes[l].z = mt->z*FRACUNIT; + //I_Error("Z value: %i", vertexes[l].z/FRACUNIT); + + } + else + { + vertexes[l].z = mt->z*FRACUNIT; // celing floor + } + vt_found = true; + } + } + //mt->type = 0; // VPHYSICS: Dynamic slopes + + + + + + + if (vt_found) + { + for (k = 0; k < numsectors; k++) + { + sector_t *sec = §ors[k]; + if (sec->linecount != 3) continue; // only works with triangular sectors + + v3float_t vt1, vt2, vt3; // cross = ret->normalf + v3float_t vec1, vec2; + + int vi1, vi2, vi3; + + vi1 = (int)(sec->lines[0]->v1 - vertexes); + vi2 = (int)(sec->lines[0]->v2 - vertexes); + vi3 = (sec->lines[1]->v1 == sec->lines[0]->v1 || sec->lines[1]->v1 == sec->lines[0]->v2)? + (int)(sec->lines[1]->v2 - vertexes) : (int)(sec->lines[1]->v1 - vertexes); + + //if (vertexes[vi1].z) + // I_Error("OSNAP %i", vertexes[vi1].z/FRACUNIT); + //if (vertexes[vi2].z) + // I_Error("OSNAP %i", vertexes[vi2].z/FRACUNIT); + //if (vertexes[vi3].z) + // I_Error("OSNAP %i", vertexes[vi3].z/FRACUNIT); + + //I_Error("%i, %i", mt->z*FRACUNIT, vertexes[vi1].z); + + //I_Error("%i, %i, %i", mt->x, mt->y, mt->z); + //P_SpawnMobj(mt->x*FRACUNIT, mt->y*FRACUNIT, mt->z*FRACUNIT, MT_RING); + + // TODO: Make sure not to spawn in the same place 2x! (we need an object in every vertex of the + // triangle sector to setup the real vertex slopes + // Check for the vertexes of all sectors + for(q = 0; q < numvertexes; q++) + { + if (vertexes[q].x == mt->x*FRACUNIT && vertexes[q].y == mt->y*FRACUNIT) + { + //I_Error("yeah %i", vertexes[q].z); + P_SpawnMobj(vertexes[q].x, vertexes[q].y, vertexes[q].z, MT_RING); +#if 0 + if ((mt->y*FRACUNIT == vertexes[vi1].y && mt->x*FRACUNIT == vertexes[vi1].x && mt->z*FRACUNIT == vertexes[vi1].z) + && !(mt->y*FRACUNIT == vertexes[vi2].y && mt->x*FRACUNIT == vertexes[vi2].x && mt->z*FRACUNIT == vertexes[vi2].z) + && !(mt->y*FRACUNIT == vertexes[vi3].y && mt->x*FRACUNIT == vertexes[vi3].x && mt->z*FRACUNIT == vertexes[vi3].z)) + P_SpawnMobj(vertexes[vi1].x, vertexes[vi1].y, vertexes[vi1].z, MT_RING); + else if ((mt->y*FRACUNIT == vertexes[vi2].y && mt->x*FRACUNIT == vertexes[vi2].x && mt->z*FRACUNIT == vertexes[vi2].z) + && !(mt->y*FRACUNIT == vertexes[vi1].y && mt->x*FRACUNIT == vertexes[vi1].x && mt->z*FRACUNIT == vertexes[vi1].z) + && !(mt->y*FRACUNIT == vertexes[vi3].y && mt->x*FRACUNIT == vertexes[vi3].x && mt->z*FRACUNIT == vertexes[vi3].z)) + P_SpawnMobj(vertexes[vi2].x, vertexes[vi2].y, vertexes[vi2].z, MT_BOUNCETV); + else if ((mt->y*FRACUNIT == vertexes[vi3].y && mt->x*FRACUNIT == vertexes[vi3].x && mt->z*FRACUNIT == vertexes[vi3].z) + && !(mt->y*FRACUNIT == vertexes[vi2].y && mt->x*FRACUNIT == vertexes[vi2].x && mt->z*FRACUNIT == vertexes[vi2].z) + && !(mt->y*FRACUNIT == vertexes[vi1].y && mt->x*FRACUNIT == vertexes[vi1].x && mt->z*FRACUNIT == vertexes[vi1].z)) + P_SpawnMobj(vertexes[vi3].x, vertexes[vi3].y, vertexes[vi3].z, MT_GFZFLOWER1); + else +#endif + continue; + } + } + + vt1.x = FIXED_TO_FLOAT(vertexes[vi1].x); + vt1.y = FIXED_TO_FLOAT(vertexes[vi1].y); + vt2.x = FIXED_TO_FLOAT(vertexes[vi2].x); + vt2.y = FIXED_TO_FLOAT(vertexes[vi2].y); + vt3.x = FIXED_TO_FLOAT(vertexes[vi3].x); + vt3.y = FIXED_TO_FLOAT(vertexes[vi3].y); + + for(j = 0; j < 2; j++) + { + + fixed_t z3; + //I_Error("Lo hicimos"); + + vt1.z = mt->z;//FIXED_TO_FLOAT(j==0 ? sec->floorheight : sec->ceilingheight); + vt2.z = mt->z;//FIXED_TO_FLOAT(j==0? sec->floorheight : sec->ceilingheight); + z3 = mt->z;//j==0? sec->floorheight : sec->ceilingheight; // Destination height + vt3.z = FIXED_TO_FLOAT(z3); + + if (P_PointOnLineSide(vertexes[vi3].x, vertexes[vi3].y, sec->lines[0]) == 0) + { + vec1.x = vt2.x - vt3.x; + vec1.y = vt2.y - vt3.y; + vec1.z = vt2.z - vt3.z; + + vec2.x = vt1.x - vt3.x; + vec2.y = vt1.y - vt3.y; + vec2.z = vt1.z - vt3.z; + } + else + { + vec1.x = vt1.x - vt3.x; + vec1.y = vt1.y - vt3.y; + vec1.z = vt1.z - vt3.z; + + vec2.x = vt2.x - vt3.x; + vec2.y = vt2.y - vt3.y; + vec2.z = vt2.z - vt3.z; + } + + + pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL); + memset(ret, 0, sizeof(*ret)); + + { + M_CrossProduct3f(&ret->normalf, &vec1, &vec2); + + // Cross product length + float len = (float)sqrt(ret->normalf.x * ret->normalf.x + + ret->normalf.y * ret->normalf.y + + ret->normalf.z * ret->normalf.z); + + if (len == 0) + { + // Only happens when all vertices in this sector are on the same line. + // Let's just ignore this case. + //CONS_Printf("Slope thing at (%d,%d) lies directly on its target line.\n", (int)(x>>16), (int)(y>>16)); + return; + } + // cross/len + ret->normalf.x /= len; + ret->normalf.y /= len; + ret->normalf.z /= len; + + // ZDoom cross = ret->normalf + // Fix backward normals + if ((ret->normalf.z < 0 && j == 0) || (ret->normalf.z > 0 && j == 1)) + { + // cross = -cross + ret->normalf.x = -ret->normalf.x; + ret->normalf.y = -ret->normalf.x; + ret->normalf.z = -ret->normalf.x; + } + } + + secplane_t *srcplane = Z_Calloc(sizeof(*srcplane), PU_LEVEL, NULL); + + srcplane->a = FLOAT_TO_FIXED (ret->normalf.x); + srcplane->b = FLOAT_TO_FIXED (ret->normalf.y); + srcplane->c = FLOAT_TO_FIXED (ret->normalf.z); + //srcplane->ic = FixedDiv(FRACUNIT, srcplane->c); + srcplane->d = -TMulScale16 (srcplane->a, vertexes[vi3].x, + srcplane->b, vertexes[vi3].y, + srcplane->c, z3); + + if (j == 0) + { + sec->f_slope = ret; + sec->f_slope->secplane = *srcplane; + } + else if (j == 1) + { + sec->c_slope = ret; + sec->c_slope->secplane = *srcplane; + } + } + } + } + + + + + + + + + } + } + Z_Free(datastart); + + + + +} +#endif + +// Reset the dynamic slopes pointer, and read all of the fancy schmancy slopes +void P_ResetDynamicSlopes(void) { + size_t i; +#if 1 // Rewrite old specials to new ones, and give a console warning + boolean warned = false; +#endif + + slopelist = NULL; + slopecount = 0; + + // We'll handle copy slopes later, after all the tag lists have been made. + // Yes, this means copied slopes won't affect things' spawning heights. Too bad for you. + for (i = 0; i < numlines; i++) + { + switch (lines[i].special) + { +#if 1 // Rewrite old specials to new ones, and give a console warning +#define WARNME if (!warned) {warned = true; CONS_Alert(CONS_WARNING, "This level uses old slope specials.\nA conversion will be needed before 2.2's release.\n");} + case 386: + case 387: + case 388: + lines[i].special += 700-386; + WARNME + P_SpawnSlope_Line(i); + break; + + case 389: + case 390: + case 391: + case 392: + lines[i].special += 710-389; + WARNME + P_SpawnSlope_Line(i); + break; + + case 393: + lines[i].special = 703; + WARNME + P_SpawnSlope_Line(i); + break; + + case 394: + case 395: + case 396: + lines[i].special += 720-394; + WARNME + break; + +#endif + + case 700: + case 701: + case 702: + case 703: + case 710: + case 711: + case 712: + case 713: + P_SpawnSlope_Line(i); + break; + + case 704: + case 705: + case 714: + case 715: + { + pslope_t **slopetoset; + size_t which = lines[i].special; + + UINT8 flags = SL_VERTEXSLOPE; + if (lines[i].flags & ML_NOSONIC) + flags |= SL_NOPHYSICS; + if (!(lines[i].flags & ML_NOTAILS)) + flags |= SL_NODYNAMIC; + + if (which == 704) + { + slopetoset = &lines[i].frontsector->f_slope; + which = 0; + } + else if (which == 705) + { + slopetoset = &lines[i].frontsector->c_slope; + which = 0; + } + else if (which == 714) + { + slopetoset = &lines[i].backsector->f_slope; + which = 1; + } + else // 715 + { + slopetoset = &lines[i].backsector->c_slope; + which = 1; + } + + if (lines[i].flags & ML_NOKNUX) + *slopetoset = P_NewVertexSlope(lines[i].tag, sides[lines[i].sidenum[which]].textureoffset >> FRACBITS, + sides[lines[i].sidenum[which]].rowoffset >> FRACBITS, flags); + else + *slopetoset = P_NewVertexSlope(lines[i].tag, lines[i].tag, lines[i].tag, flags); + + sides[lines[i].sidenum[which]].sector->hasslope = true; + } + break; + + default: + break; + } + } +} + + + + +// ============================================================================ +// +// Various utilities related to slopes +// + +// +// P_GetZAt +// +// Returns the height of the sloped plane at (x, y) as a fixed_t +// +fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y) +{ + fixed_t dist = FixedMul(x - slope->o.x, slope->d.x) + + FixedMul(y - slope->o.y, slope->d.y); + + return slope->o.z + FixedMul(dist, slope->zdelta); +} + + +// +// P_QuantizeMomentumToSlope +// +// When given a vector, rotates it and aligns it to a slope +void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope) +{ + vector3_t axis; + axis.x = -slope->d.y; + axis.y = slope->d.x; + axis.z = 0; + + FV3_Rotate(momentum, &axis, slope->zangle >> ANGLETOFINESHIFT); +} + +// +// P_SlopeLaunch +// +// Handles slope ejection for objects +void P_SlopeLaunch(mobj_t *mo) +{ + // Double the pre-rotation Z, then halve the post-rotation Z. This reduces the + // vertical launch given from slopes while increasing the horizontal launch + // given. Good for SRB2's gravity and horizontal speeds. + vector3_t slopemom; + slopemom.x = mo->momx; + slopemom.y = mo->momy; + slopemom.z = mo->momz*2; + P_QuantizeMomentumToSlope(&slopemom, mo->standingslope); + + mo->momx = slopemom.x; + mo->momy = slopemom.y; + mo->momz = slopemom.z/2; + + //CONS_Printf("Launched off of slope.\n"); + mo->standingslope = NULL; +} + +// Function to help handle landing on slopes +void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) +{ + vector3_t mom; + mom.x = thing->momx; + mom.y = thing->momy; + mom.z = thing->momz*2; + + //CONS_Printf("langing on slope\n"); + + // Reverse quantizing might could use its own function later + slope->zangle = ANGLE_MAX-slope->zangle; + P_QuantizeMomentumToSlope(&mom, slope); + slope->zangle = ANGLE_MAX-slope->zangle; + + if (P_MobjFlip(thing)*mom.z < 0) { // falling, land on slope + thing->momx = mom.x; + thing->momy = mom.y; + thing->momz = -P_MobjFlip(thing); + + thing->standingslope = slope; + } +} + +// https://yourlogicalfallacyis.com/slippery-slope +// Handles sliding down slopes, like if they were made of butter :) +void P_ButteredSlope(mobj_t *mo) +{ + fixed_t thrust; + + if (!mo->standingslope) + return; + + if (mo->player) { + if (abs(mo->standingslope->zdelta) < FRACUNIT/4 && !(mo->player->pflags & PF_SPINNING)) + return; // Don't slide on non-steep slopes unless spinning + + if (abs(mo->standingslope->zdelta) < FRACUNIT/2 && !(mo->player->rmomx || mo->player->rmomy)) + return; // Allow the player to stand still on slopes below a certain steepness + } + + thrust = FINESINE(mo->standingslope->zangle>>ANGLETOFINESHIFT) * 3 / 2 * (mo->eflags & MFE_VERTICALFLIP ? 1 : -1); + + if (mo->player && (mo->player->pflags & PF_SPINNING)) { + fixed_t mult = 0; + if (mo->momx || mo->momy) { + angle_t angle = R_PointToAngle2(0, 0, mo->momx, mo->momy) - mo->standingslope->xydirection; + + if (P_MobjFlip(mo) * mo->standingslope->zdelta < 0) + angle ^= ANGLE_180; + + mult = FINECOSINE(angle >> ANGLETOFINESHIFT); + } + + //CONS_Printf("%d\n", mult); + + thrust = FixedMul(thrust, FRACUNIT*2/3 + mult/8); + } + + if (mo->momx || mo->momy) // Slightly increase thrust based on the object's speed + thrust = FixedMul(thrust, FRACUNIT+P_AproxDistance(mo->momx, mo->momy)/16); + // This makes it harder to zigzag up steep slopes, as well as allows greater top speed when rolling down + + // Multiply by gravity + thrust = FixedMul(thrust, FRACUNIT/2); // TODO actually get this + + P_Thrust(mo, mo->standingslope->xydirection, thrust); +} + +// EOF +#endif // #ifdef ESLOPE diff --git a/src/p_slopes.h b/src/p_slopes.h new file mode 100644 index 000000000..8d82632ff --- /dev/null +++ b/src/p_slopes.h @@ -0,0 +1,80 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// Copyright(C) 2004 Stephen McGranahan +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//-------------------------------------------------------------------------- +// +// DESCRIPTION: +// Slopes +// SoM created 05/10/09 +// +//----------------------------------------------------------------------------- + +#ifndef P_SLOPES_H__ +#define P_SLOPES_H__ + +#ifdef ESLOPE +void P_ResetDynamicSlopes(void); +void P_RunDynamicSlopes(void); +// P_SpawnSlope_Line +// Creates one or more slopes based on the given line type and front/back +// sectors. +void P_SpawnSlope_Line(int linenum); + +#ifdef SPRINGCLEAN +// Loads just map objects that make slopes, +// terrain affecting objects have to be spawned first +void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum); + +typedef enum +{ + THING_SlopeFloorPointLine = 9500, + THING_SlopeCeilingPointLine = 9501, + THING_SetFloorSlope = 9502, + THING_SetCeilingSlope = 9503, + THING_CopyFloorPlane = 9510, + THING_CopyCeilingPlane = 9511, + THING_VavoomFloor=1500, + THING_VavoomCeiling=1501, + THING_VertexFloorZ=1504, + THING_VertexCeilingZ=1505, +} slopething_e; +#endif + +// +// P_CopySectorSlope +// +// Searches through tagged sectors and copies +// +void P_CopySectorSlope(line_t *line); + +pslope_t *P_SlopeById(UINT16 id); + +// Returns the height of the sloped plane at (x, y) as a fixed_t +fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y); + +// Lots of physics-based bullshit +void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope); +void P_SlopeLaunch(mobj_t *mo); +void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope); +void P_ButteredSlope(mobj_t *mo); + +#endif + +// EOF +#endif // #ifdef ESLOPE diff --git a/src/p_spec.c b/src/p_spec.c index 6712f40ec..aa61138a0 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -29,6 +29,7 @@ #include "r_main.h" //Two extra includes. #include "r_sky.h" #include "p_polyobj.h" +#include "p_slopes.h" #include "hu_stuff.h" #include "m_misc.h" #include "m_cond.h" //unlock triggers @@ -2389,20 +2390,19 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) // console player only unless NOCLIMB is set if ((line->flags & ML_NOCLIMB) || (mo && mo->player && P_IsLocalPlayer(mo->player))) { - UINT16 musicnum = (UINT16)sides[line->sidenum[0]].toptexture; //P_AproxDistance(line->dx, line->dy)>>FRACBITS; UINT16 tracknum = (UINT16)sides[line->sidenum[0]].bottomtexture; - mapmusic = musicnum | (tracknum << MUSIC_TRACKSHIFT); - if (!(line->flags & ML_BLOCKMONSTERS)) - mapmusic |= MUSIC_RELOADRESET; + strncpy(mapmusname, sides[line->sidenum[0]].text, 7); + mapmusname[6] = 0; - if (musicnum >= NUMMUSIC || musicnum == mus_None) - S_StopMusic(); - else - S_ChangeMusic(mapmusic, !(line->flags & ML_EFFECT4)); + mapmusflags = tracknum & MUSIC_TRACKMASK; + if (!(line->flags & ML_BLOCKMONSTERS)) + mapmusflags |= MUSIC_RELOADRESET; + + S_ChangeMusic(mapmusname, mapmusflags, !(line->flags & ML_EFFECT4)); // Except, you can use the ML_BLOCKMONSTERS flag to change this behavior. - // if (mapmusic & MUSIC_RELOADRESET) then it will reset the music in G_PlayerReborn. + // if (mapmusflags & MUSIC_RELOADRESET) then it will reset the music in G_PlayerReborn. } break; @@ -3038,6 +3038,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); sector_t *sec; // Sector that the FOF is visible (or not visible) in ffloor_t *rover; // FOF to vanish/un-vanish + ffloortype_e oldflags; // store FOF's old flags for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) { @@ -3061,11 +3062,17 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) return; } + oldflags = rover->flags; + // Abracadabra! if (line->flags & ML_NOCLIMB) rover->flags |= FF_EXISTS; else rover->flags &= ~FF_EXISTS; + + // if flags changed, reset sector's light list + if (rover->flags != oldflags) + sec->moved = true; } } break; @@ -3365,6 +3372,7 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *targetsec) { ffloor_t *rover; + fixed_t top, bottom; if (!mo->player) // should NEVER happen return false; @@ -3381,6 +3389,9 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar //if (!(rover->flags & FF_EXISTS)) // return false; + top = P_GetSpecialTopZ(mo, sector, targetsec); + bottom = P_GetSpecialBottomZ(mo, sector, targetsec); + // Check the 3D floor's type... if (rover->flags & FF_BLOCKPLAYER) { @@ -3388,27 +3399,27 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)) { - if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != *rover->topheight) + if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != top) return false; } else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)) { if (!(mo->eflags & MFE_VERTICALFLIP) - || mo->z + mo->height != *rover->bottomheight) + || mo->z + mo->height != bottom) return false; } else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH) { - if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == *rover->bottomheight) - || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == *rover->topheight))) + if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == bottom) + || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == top))) return false; } } else { // Water and intangible FOFs - if (mo->z > *rover->topheight || (mo->z + mo->height) < *rover->bottomheight) + if (mo->z > top || (mo->z + mo->height) < bottom) return false; } @@ -3426,9 +3437,9 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar static inline boolean P_MobjReadyToTrigger(mobj_t *mo, sector_t *sec) { if (mo->eflags & MFE_VERTICALFLIP) - return (mo->z+mo->height == sec->ceilingheight && sec->flags & SF_FLIPSPECIAL_CEILING); + return (mo->z+mo->height == P_GetSpecialTopZ(mo, sec, sec) && sec->flags & SF_FLIPSPECIAL_CEILING); else - return (mo->z == sec->floorheight && sec->flags & SF_FLIPSPECIAL_FLOOR); + return (mo->z == P_GetSpecialBottomZ(mo, sec, sec) && sec->flags & SF_FLIPSPECIAL_FLOOR); } /** Applies a sector special to a player. @@ -4387,27 +4398,27 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector) if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)) { - if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != *rover->topheight) + if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector)) continue; } else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)) { if (!(player->mo->eflags & MFE_VERTICALFLIP) - || player->mo->z + player->mo->height != *rover->bottomheight) + || player->mo->z + player->mo->height != P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector)) continue; } else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH) { - if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == *rover->bottomheight) - || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == *rover->topheight))) + if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector)) + || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector)))) continue; } } else { // Water and DEATH FOG!!! heh - if (player->mo->z > *rover->topheight || (player->mo->z + player->mo->height) < *rover->bottomheight) + if (player->mo->z > P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector) || (player->mo->z + player->mo->height) < P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector)) continue; } @@ -4517,6 +4528,7 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector) static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector) { boolean nofloorneeded = false; + fixed_t f_affectpoint, c_affectpoint; if (!sector->special) // nothing special, exit return; @@ -4579,16 +4591,19 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector) return; } + f_affectpoint = P_GetSpecialBottomZ(player->mo, sector, sector); + c_affectpoint = P_GetSpecialTopZ(player->mo, sector, sector); + // Only go further if on the ground - if ((sector->flags & SF_FLIPSPECIAL_FLOOR) && !(sector->flags & SF_FLIPSPECIAL_CEILING) && player->mo->z != sector->floorheight) + if ((sector->flags & SF_FLIPSPECIAL_FLOOR) && !(sector->flags & SF_FLIPSPECIAL_CEILING) && player->mo->z != f_affectpoint) return; - if ((sector->flags & SF_FLIPSPECIAL_CEILING) && !(sector->flags & SF_FLIPSPECIAL_FLOOR) && player->mo->z + player->mo->height != sector->ceilingheight) + if ((sector->flags & SF_FLIPSPECIAL_CEILING) && !(sector->flags & SF_FLIPSPECIAL_FLOOR) && player->mo->z + player->mo->height != c_affectpoint) return; if ((sector->flags & SF_FLIPSPECIAL_BOTH) - && player->mo->z != sector->floorheight - && player->mo->z + player->mo->height != sector->ceilingheight) + && player->mo->z != f_affectpoint + && player->mo->z + player->mo->height != c_affectpoint) return; P_ProcessSpecialSector(player, sector, NULL); @@ -4637,126 +4652,34 @@ void P_PlayerInSpecialSector(player_t *player) /** Animate planes, scroll walls, etc. and keeps track of level timelimit and exits if time is up. * - * \sa cv_timelimit, P_CheckPointLimit + * \sa P_CheckTimeLimit, P_CheckPointLimit */ void P_UpdateSpecials(void) { anim_t *anim; - INT32 i, k; + INT32 i; INT32 pic; size_t j; levelflat_t *foundflats; // for flat animation // LEVEL TIMER - // Exit if the timer is equal to or greater the timelimit, unless you are - // in overtime. In which case leveltime may stretch out beyond timelimitintics - // and overtime's status will be checked here each tick. - if (cv_timelimit.value && timelimitintics <= leveltime && (multiplayer || netgame) - && G_RingSlingerGametype() && (gameaction != ga_completed)) - { - boolean pexit = false; - - //Tagmode round end but only on the tic before the - //XD_EXITLEVEL packet is recieved by all players. - if (G_TagGametype()) - { - if (leveltime == (timelimitintics + 1)) - { - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator - || (players[i].pflags & PF_TAGGED) || (players[i].pflags & PF_TAGIT)) - continue; - - CONS_Printf(M_GetText("%s recieved double points for surviving the round.\n"), player_names[i]); - P_AddPlayerScore(&players[i], players[i].score); - } - } - - pexit = true; - } - - //Optional tie-breaker for Match/CTF - else if (G_RingSlingerGametype() && cv_overtime.value) - { - INT32 playerarray[MAXPLAYERS]; - INT32 tempplayer = 0; - INT32 spectators = 0; - INT32 playercount = 0; - - //Figure out if we have enough participating players to care. - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] && players[i].spectator) - spectators++; - } - - if ((D_NumPlayers() - spectators) > 1) - { - // Play the starpost sfx after the first second of overtime. - if (gamestate == GS_LEVEL && (leveltime == (timelimitintics + TICRATE))) - S_StartSound(NULL, sfx_strpst); - - // Normal Match - if (!G_GametypeHasTeams()) - { - //Store the nodes of participating players in an array. - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] && !players[i].spectator) - { - playerarray[playercount] = i; - playercount++; - } - } - - //Sort 'em. - for (i = 1; i < playercount; i++) - { - for (k = i; k < playercount; k++) - { - if (players[playerarray[i-1]].score < players[playerarray[k]].score) - { - tempplayer = playerarray[i-1]; - playerarray[i-1] = playerarray[k]; - playerarray[k] = tempplayer; - } - } - } - - //End the round if the top players aren't tied. - if (!(players[playerarray[0]].score == players[playerarray[1]].score)) - pexit = true; - } - else - { - //In team match and CTF, determining a tie is much simpler. =P - if (!(redscore == bluescore)) - pexit = true; - } - } - else - pexit = true; - } - else - pexit = true; - - if (server && pexit) - SendNetXCmd(XD_EXITLEVEL, NULL, 0); - } + P_CheckTimeLimit(); // POINT LIMIT P_CheckPointLimit(); + // Dynamic slopeness + P_RunDynamicSlopes(); + // ANIMATE TEXTURES for (anim = anims; anim < lastanim; anim++) { - for (i = anim->basepic; i < anim->basepic + anim->numpics; i++) + for (i = 0; i < anim->numpics; i++) { pic = anim->basepic + ((leveltime/anim->speed + i) % anim->numpics); if (anim->istexture) - texturetranslation[i] = pic; + texturetranslation[anim->basepic+i] = pic; } } @@ -4892,6 +4815,12 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f ffloor->topyoffs = &sec2->ceiling_yoffs; ffloor->topangle = &sec2->ceilingpic_angle; +#ifdef ESLOPE + // Add slopes + ffloor->t_slope = &sec2->c_slope; + ffloor->b_slope = &sec2->f_slope; +#endif + if ((flags & FF_SOLID) && (master->flags & ML_EFFECT1)) // Block player only flags &= ~FF_BLOCKOTHERS; @@ -5325,6 +5254,7 @@ void T_LaserFlash(laserthink_t *flash) sector_t *sourcesec; ffloor_t *ffloor = flash->ffloor; sector_t *sector = flash->sector; + fixed_t top, bottom; if (!ffloor || !(ffloor->flags & FF_EXISTS)) return; @@ -5348,8 +5278,11 @@ void T_LaserFlash(laserthink_t *flash) && thing->flags & MF_BOSS) continue; // Don't hurt bosses - if (thing->z >= sourcesec->ceilingheight - || thing->z + thing->height <= sourcesec->floorheight) + top = P_GetSpecialTopZ(thing, sourcesec, sector); + bottom = P_GetSpecialBottomZ(thing, sourcesec, sector); + + if (thing->z >= top + || thing->z + thing->height <= bottom) continue; if (thing->flags & MF_SHOOTABLE) @@ -6094,31 +6027,6 @@ void P_SpawnSpecials(INT32 fromnetsave) P_AddRaiseThinker(lines[i].frontsector, &lines[i]); break; -#ifdef SLOPENESS - case 999: - sec = sides[*lines[i].sidenum].sector-sectors; - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) - { - size_t counting; - - sectors[s].floorangle = ANGLE_45; - for (counting = 0; counting < sectors[s].linecount/2; counting++) - { - sectors[s].lines[counting]->v1->z = sectors[sec].floorheight; - CONS_Debug(DBG_GAMELOGIC, "Set it to %d\n", sectors[s].lines[counting]->v1->z>>FRACBITS); - } - - for (counting = sectors[s].linecount/2; counting < sectors[s].linecount; counting++) - { - sectors[s].lines[counting]->v1->z = sectors[sec].ceilingheight; - CONS_Debug(DBG_GAMELOGIC, "Set it to %d\n", sectors[s].lines[counting]->v1->z>>FRACBITS); - } - sectors[s].special = 65535; - CONS_Debug(DBG_GAMELOGIC, "Found & Set slope!\n"); - } - break; -#endif - case 200: // Double light effect P_AddFakeFloorsByLine(i, FF_EXISTS|FF_CUTSPRITES|FF_DOUBLESHADOW, secthinkers); break; @@ -6428,6 +6336,14 @@ void P_SpawnSpecials(INT32 fromnetsave) sectors[s].midmap = lines[i].frontsector->midmap; break; +#ifdef ESLOPE // Slope copy specials. Handled here for sanity. + case 720: + case 721: + case 722: + P_CopySectorSlope(&lines[i]); + break; +#endif + default: break; } @@ -6632,6 +6548,8 @@ void T_Scroll(scroll_t *s) if (thing->eflags & MFE_PUSHED) // Already pushed this tic by an exclusive pusher. continue; + height = P_GetSpecialBottomZ(thing, sec, psec); + if (!(thing->flags & MF_NOCLIP)) // Thing must be clipped if (!(thing->flags & MF_NOGRAVITY || thing->z+thing->height != height)) // Thing must a) be non-floating and have z+height == height { @@ -6652,6 +6570,8 @@ void T_Scroll(scroll_t *s) if (thing->eflags & MFE_PUSHED) continue; + height = P_GetSpecialBottomZ(thing, sec, sec); + if (!(thing->flags & MF_NOCLIP) && (!(thing->flags & MF_NOGRAVITY || thing->z > height))) { @@ -6691,6 +6611,8 @@ void T_Scroll(scroll_t *s) if (thing->eflags & MFE_PUSHED) continue; + height = P_GetSpecialTopZ(thing, sec, psec); + if (!(thing->flags & MF_NOCLIP)) // Thing must be clipped if (!(thing->flags & MF_NOGRAVITY || thing->z != height))// Thing must a) be non-floating and have z == height { @@ -6711,6 +6633,8 @@ void T_Scroll(scroll_t *s) if (thing->eflags & MFE_PUSHED) continue; + height = P_GetSpecialTopZ(thing, sec, sec); + if (!(thing->flags & MF_NOCLIP) && (!(thing->flags & MF_NOGRAVITY || thing->z+thing->height < height))) { @@ -7004,7 +6928,7 @@ static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 */ void T_Friction(friction_t *f) { - sector_t *sec; + sector_t *sec, *referrer = NULL; mobj_t *thing; msecnode_t *node; @@ -7013,7 +6937,7 @@ void T_Friction(friction_t *f) // Make sure the sector type hasn't changed if (f->roverfriction) { - sector_t *referrer = sectors + f->referrer; + referrer = sectors + f->referrer; if (!(GETSECSPECIAL(referrer->special, 3) == 1 || GETSECSPECIAL(referrer->special, 3) == 3)) @@ -7045,9 +6969,7 @@ void T_Friction(friction_t *f) { if (f->roverfriction) { - sector_t *referrer = §ors[f->referrer]; - - if (thing->floorz != referrer->ceilingheight) + if (thing->floorz != P_GetSpecialTopZ(thing, referrer, sec)) { node = node->m_snext; continue; @@ -7060,7 +6982,7 @@ void T_Friction(friction_t *f) thing->movefactor = f->movefactor; } } - else if (sec->floorheight == thing->floorz && (thing->friction == ORIG_FRICTION // normal friction? + else if (P_GetSpecialBottomZ(thing, sec, sec) == thing->floorz && (thing->friction == ORIG_FRICTION // normal friction? || f->friction < thing->friction)) { thing->friction = f->friction; @@ -7334,7 +7256,7 @@ static inline boolean PIT_PushThing(mobj_t *thing) */ void T_Pusher(pusher_t *p) { - sector_t *sec; + sector_t *sec, *referrer = NULL; mobj_t *thing; msecnode_t *node; INT32 xspeed = 0,yspeed = 0; @@ -7343,7 +7265,6 @@ void T_Pusher(pusher_t *p) //INT32 ht = 0; boolean inFOF; boolean touching; - boolean foundfloor = false; boolean moved; xspeed = yspeed = 0; @@ -7355,19 +7276,16 @@ void T_Pusher(pusher_t *p) if (p->roverpusher) { - sector_t *referrer = §ors[p->referrer]; + referrer = §ors[p->referrer]; - if (GETSECSPECIAL(referrer->special, 3) == 2 - || GETSECSPECIAL(referrer->special, 3) == 3) - foundfloor = true; + if (!(GETSECSPECIAL(referrer->special, 3) == 2 + || GETSECSPECIAL(referrer->special, 3) == 3)) + return; } else if (!(GETSECSPECIAL(sec->special, 3) == 2 || GETSECSPECIAL(sec->special, 3) == 3)) return; - if (p->roverpusher && foundfloor == false) // Not even a 3d floor has the PUSH_MASK. - return; - // For constant pushers (wind/current) there are 3 situations: // // 1) Affected Thing is above the floor. @@ -7442,41 +7360,38 @@ void T_Pusher(pusher_t *p) // Find the area that the 'thing' is in if (p->roverpusher) { - sector_t *referrer = §ors[p->referrer]; - INT32 special; + fixed_t top, bottom; - special = GETSECSPECIAL(referrer->special, 3); - - if (!(special == 2 || special == 3)) - return; + top = P_GetSpecialTopZ(thing, referrer, sec); + bottom = P_GetSpecialBottomZ(thing, referrer, sec); if (thing->eflags & MFE_VERTICALFLIP) { - if (referrer->floorheight > thing->z + thing->height - || referrer->ceilingheight < (thing->z + (thing->height >> 1))) + if (bottom > thing->z + thing->height + || top < (thing->z + (thing->height >> 1))) continue; - if (thing->z < referrer->floorheight) + if (thing->z < bottom) touching = true; - if (thing->z + (thing->height >> 1) > referrer->floorheight) + if (thing->z + (thing->height >> 1) > bottom) inFOF = true; } else { - if (referrer->ceilingheight < thing->z || referrer->floorheight > (thing->z + (thing->height >> 1))) + if (top < thing->z || referrer->floorheight > (thing->z + (thing->height >> 1))) continue; - if (thing->z + thing->height > referrer->ceilingheight) + if (thing->z + thing->height > top) touching = true; - if (thing->z + (thing->height >> 1) < referrer->ceilingheight) + if (thing->z + (thing->height >> 1) < top) inFOF = true; } } else // Treat the entire sector as one big FOF { - if (thing->z == thing->subsector->sector->floorheight) + if (thing->z == P_GetSpecialBottomZ(thing, sec, sec)) touching = true; else if (p->type != p_current) inFOF = true; diff --git a/src/p_tick.c b/src/p_tick.c index 3c7820c2d..fd653ed7b 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -631,6 +631,7 @@ void P_Ticker(boolean run) // Run shield positioning P_RunShields(); + P_RunOverlays(); P_UpdateSpecials(); P_RespawnSpecials(); @@ -742,6 +743,7 @@ void P_PreTicker(INT32 frames) // Run shield positioning P_RunShields(); + P_RunOverlays(); P_UpdateSpecials(); P_RespawnSpecials(); diff --git a/src/p_user.c b/src/p_user.c index 2b4f6a4bd..dee5d4452 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -29,6 +29,7 @@ #include "m_random.h" #include "m_misc.h" #include "i_video.h" +#include "p_slopes.h" #include "p_spec.h" #include "r_splats.h" #include "z_zone.h" @@ -51,9 +52,6 @@ #include "hardware/hw_main.h" #endif -// Index of the special effects (INVUL inverse) map. -#define INVERSECOLORMAP 32 - #if 0 static void P_NukeAllPlayers(player_t *player); #endif @@ -957,7 +955,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings) if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC) && P_IsLocalPlayer(player)) { S_StopMusic(); - S_ChangeMusic(mus_supers, true); + S_ChangeMusicInternal("supers", true); } S_StartSound(NULL, sfx_supert); //let all players hear it -mattw_cfi @@ -1127,7 +1125,7 @@ void P_PlayLivesJingle(player_t *player) if (player) player->powers[pw_extralife] = extralifetics + 1; S_StopMusic(); // otherwise it won't restart if this is done twice in a row - S_ChangeMusic(mus_xtlife, false); + S_ChangeMusicInternal("xtlife", false); } } @@ -1145,21 +1143,21 @@ void P_RestoreMusic(player_t *player) return; S_SpeedMusic(1.0f); if (player->powers[pw_super] && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC)) - S_ChangeMusic(mus_supers, true); + S_ChangeMusicInternal("supers", true); else if (player->powers[pw_invulnerability] > 1) - S_ChangeMusic((mariomode) ? mus_minvnc : mus_invinc, false); + S_ChangeMusicInternal((mariomode) ? "minvnc" : "invinc", false); else if (player->powers[pw_sneakers] > 1 && !player->powers[pw_super]) { if (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC) { S_SpeedMusic(1.4f); - S_ChangeMusic(mapmusic, true); + S_ChangeMusic(mapmusname, mapmusflags, true); } else - S_ChangeMusic(mus_shoes, true); + S_ChangeMusicInternal("shoes", true); } else - S_ChangeMusic(mapmusic, true); + S_ChangeMusic(mapmusname, mapmusflags, true); } // @@ -1239,7 +1237,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec) if (mo->eflags & MFE_VERTICALFLIP) { // Detect if the player is on the ceiling. - if (mo->z+mo->height >= sec->ceilingheight) + if (mo->z+mo->height >= P_GetSpecialTopZ(mo, sec, sec)) return true; // Otherwise, detect if the player is on the bottom of a FOF. else @@ -1263,7 +1261,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec) continue; // Actually check if the player is on the suitable FOF. - if (mo->z+mo->height == *rover->bottomheight) + if (mo->z+mo->height == P_GetSpecialBottomZ(mo, sectors + rover->secnum, sec)) return true; } } @@ -1272,7 +1270,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec) else { // Detect if the player is on the floor. - if (mo->z <= sec->floorheight) + if (mo->z <= P_GetSpecialBottomZ(mo, sec, sec)) return true; // Otherwise, detect if the player is on the top of a FOF. else @@ -1296,7 +1294,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec) continue; // Actually check if the player is on the suitable FOF. - if (mo->z == *rover->topheight) + if (mo->z == P_GetSpecialTopZ(mo, sectors + rover->secnum, sec)) return true; } } @@ -1624,7 +1622,7 @@ void P_DoPlayerExit(player_t *player) { player->climbing = 0; player->pflags |= PF_JUMPED; - P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); } player->powers[pw_underwater] = 0; player->powers[pw_spacetime] = 0; @@ -1817,6 +1815,9 @@ static void P_CheckBouncySectors(player_t *player) fixed_t oldx; fixed_t oldy; fixed_t oldz; +#ifdef ESLOPE + vector3_t momentum; +#endif oldx = player->mo->x; oldy = player->mo->y; @@ -1837,16 +1838,21 @@ static void P_CheckBouncySectors(player_t *player) { ffloor_t *rover; boolean top = true; + fixed_t topheight, bottomheight; for (rover = node->m_sector->ffloors; rover; rover = rover->next) { - if (player->mo->z > *rover->topheight) + topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); + bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL); + + if (player->mo->z > topheight) continue; - if (player->mo->z + player->mo->height < *rover->bottomheight) + if (player->mo->z + player->mo->height < bottomheight) continue; - if (oldz < *rover->topheight && oldz > *rover->bottomheight) + if (oldz < P_GetFOFTopZ(player->mo, node->m_sector, rover, oldx, oldy, NULL) + && oldz + player->mo->height > P_GetFOFBottomZ(player->mo, node->m_sector, rover, oldx, oldy, NULL)) top = false; if (GETSECSPECIAL(rover->master->frontsector->special, 1) == 15) @@ -1861,7 +1867,29 @@ static void P_CheckBouncySectors(player_t *player) { fixed_t newmom; +#ifdef ESLOPE + pslope_t *slope; + if (abs(oldz - topheight) < abs(oldz + player->mo->height - bottomheight)) { // Hit top + slope = *rover->t_slope; + } else { // Hit bottom + slope = *rover->b_slope; + } + + momentum.x = player->mo->momx; + momentum.y = player->mo->momy; + momentum.z = player->mo->momz*2; + + if (slope) { + // Reverse quantizing might could use its own function later + slope->zangle = ANGLE_MAX-slope->zangle; + P_QuantizeMomentumToSlope(&momentum, slope); + slope->zangle = ANGLE_MAX-slope->zangle; + } + + newmom = momentum.z = -FixedMul(momentum.z,linedist)/2; +#else newmom = -FixedMul(player->mo->momz,linedist); +#endif if (abs(newmom) < (linedist*2)) { @@ -1884,7 +1912,18 @@ static void P_CheckBouncySectors(player_t *player) else if (newmom < -P_GetPlayerHeight(player)/2) newmom = -P_GetPlayerHeight(player)/2; +#ifdef ESLOPE + momentum.z = newmom*2; + + if (slope) + P_QuantizeMomentumToSlope(&momentum, slope); + + player->mo->momx = momentum.x; + player->mo->momy = momentum.y; + player->mo->momz = momentum.z/2; +#else player->mo->momz = newmom; +#endif if (player->pflags & PF_SPINNING) { @@ -2026,13 +2065,13 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player) else if (player->powers[pw_underwater] == 1) { if ((netgame || multiplayer) && P_IsLocalPlayer(player)) - S_ChangeMusic(mapmusic, true); + S_ChangeMusic(mapmusname, mapmusflags, true); P_DamageMobj(player->mo, NULL, NULL, 1, DMG_DROWNED); } else if (player->powers[pw_spacetime] == 1) { if ((netgame || multiplayer) && P_IsLocalPlayer(player)) - S_ChangeMusic(mapmusic, true); + S_ChangeMusic(mapmusname, mapmusflags, true); P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPACEDROWN); } @@ -2066,7 +2105,7 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player) && player == &players[consoleplayer]) { S_StopMusic(); - S_ChangeMusic(mus_drown, false); + S_ChangeMusicInternal("drown", false); } if (player->powers[pw_underwater] == 25*TICRATE + 1) @@ -2100,30 +2139,7 @@ static void P_CheckInvincibilityTimer(player_t *player) player->mo->color = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1))); else if (leveltime % (TICRATE/7) == 0) { - fixed_t destx, desty; - mobj_t *sparkle; - - if (!splitscreen && rendermode != render_soft) - { - angle_t viewingangle; - - if (players[displayplayer].awayviewtics) - viewingangle = R_PointToAngle2(player->mo->x, player->mo->y, players[displayplayer].awayviewmobj->x, players[displayplayer].awayviewmobj->y); - else if (!camera.chase && players[displayplayer].mo) - viewingangle = R_PointToAngle2(player->mo->x, player->mo->y, players[displayplayer].mo->x, players[displayplayer].mo->y); - else - viewingangle = R_PointToAngle2(player->mo->x, player->mo->y, camera.x, camera.y); - - destx = player->mo->x + P_ReturnThrustX(player->mo, viewingangle, FixedMul(FRACUNIT, player->mo->scale)); - desty = player->mo->y + P_ReturnThrustY(player->mo, viewingangle, FixedMul(FRACUNIT, player->mo->scale)); - } - else - { - destx = player->mo->x; - desty = player->mo->y; - } - - sparkle = P_SpawnMobj(destx, desty, player->mo->z, MT_IVSP); + mobj_t *sparkle = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_IVSP); sparkle->destscale = player->mo->scale; P_SetScale(sparkle, player->mo->scale); } @@ -2298,14 +2314,27 @@ static void P_DoClimbing(player_t *player) boolean thrust; boolean boostup; boolean skyclimber; + fixed_t floorheight, ceilingheight; // ESLOPE thrust = false; floorclimb = false; boostup = false; skyclimber = false; +#ifdef ESLOPE + floorheight = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) + : glidesector->sector->floorheight; + ceilingheight = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) + : glidesector->sector->ceilingheight; +#else + floorheight = glidesector->sector->floorheight; + ceilingheight = glidesector->sector->ceilingheight; +#endif + if (glidesector->sector->ffloors) { ffloor_t *rover; + fixed_t topheight, bottomheight; // ESLOPE + for (rover = glidesector->sector->ffloors; rover; rover = rover->next) { if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) @@ -2313,13 +2342,21 @@ static void P_DoClimbing(player_t *player) floorclimb = true; +#ifdef ESLOPE + bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; + topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight; +#else + bottomheight = *rover->bottomheight; + topheight = *rover->topheight; +#endif + // Only supports rovers that are moving like an 'elevator', not just the top or bottom. if (rover->master->frontsector->floorspeed && rover->master->frontsector->ceilspeed == 42) { - if ((!(player->mo->eflags & MFE_VERTICALFLIP) && (*rover->bottomheight < player->mo->z+player->mo->height) - && (*rover->topheight >= player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale))) - || ((player->mo->eflags & MFE_VERTICALFLIP) && (*rover->topheight > player->mo->z) - && (*rover->bottomheight <= player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)))) + if ((!(player->mo->eflags & MFE_VERTICALFLIP) && (bottomheight < player->mo->z+player->mo->height) + && (topheight >= player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale))) + || ((player->mo->eflags & MFE_VERTICALFLIP) && (topheight > player->mo->z) + && (bottomheight <= player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)))) { if (cmd->forwardmove != 0) player->mo->momz += rover->master->frontsector->floorspeed; @@ -2335,8 +2372,9 @@ static void P_DoClimbing(player_t *player) if (player->mo->eflags & MFE_VERTICALFLIP) { // Trying to climb down past the bottom of the FOF - if ((*rover->topheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= *rover->topheight)) + if ((topheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= topheight)) { + fixed_t bottomheight2; ffloor_t *roverbelow; boolean foundfof = false; floorclimb = true; @@ -2351,7 +2389,13 @@ static void P_DoClimbing(player_t *player) if (roverbelow == rover) continue; - if (*roverbelow->bottomheight < *rover->topheight + FixedMul(16*FRACUNIT, player->mo->scale)) +#ifdef ESLOPE + bottomheight2 = *roverbelow->b_slope ? P_GetZAt(*roverbelow->b_slope, player->mo->x, player->mo->y) : *roverbelow->bottomheight; +#else + bottomheight2 = *roverbelow->bottomheight; +#endif + + if (bottomheight2 < topheight + FixedMul(16*FRACUNIT, player->mo->scale)) foundfof = true; } @@ -2360,7 +2404,7 @@ static void P_DoClimbing(player_t *player) } // Below the FOF - if (*rover->topheight <= player->mo->z) + if (topheight <= player->mo->z) { floorclimb = false; boostup = false; @@ -2368,7 +2412,7 @@ static void P_DoClimbing(player_t *player) } // Above the FOF - if (*rover->bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)) + if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)) { floorclimb = false; thrust = true; @@ -2378,8 +2422,9 @@ static void P_DoClimbing(player_t *player) else { // Trying to climb down past the bottom of a FOF - if ((*rover->bottomheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= *rover->bottomheight)) + if ((bottomheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= bottomheight)) { + fixed_t topheight2; ffloor_t *roverbelow; boolean foundfof = false; floorclimb = true; @@ -2394,7 +2439,13 @@ static void P_DoClimbing(player_t *player) if (roverbelow == rover) continue; - if (*roverbelow->topheight > *rover->bottomheight - FixedMul(16*FRACUNIT, player->mo->scale)) +#ifdef ESLOPE + topheight2 = *roverbelow->t_slope ? P_GetZAt(*roverbelow->t_slope, player->mo->x, player->mo->y) : *roverbelow->topheight; +#else + topheight2 = *roverbelow->topheight; +#endif + + if (topheight2 > bottomheight - FixedMul(16*FRACUNIT, player->mo->scale)) foundfof = true; } @@ -2403,7 +2454,7 @@ static void P_DoClimbing(player_t *player) } // Below the FOF - if (*rover->bottomheight >= player->mo->z + player->mo->height) + if (bottomheight >= player->mo->z + player->mo->height) { floorclimb = false; boostup = false; @@ -2411,7 +2462,7 @@ static void P_DoClimbing(player_t *player) } // Above the FOF - if (*rover->topheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)) + if (topheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)) { floorclimb = false; thrust = true; @@ -2432,7 +2483,7 @@ static void P_DoClimbing(player_t *player) if (player->mo->eflags & MFE_VERTICALFLIP) { // Trying to climb down past the upper texture area - if ((glidesector->sector->floorheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= glidesector->sector->floorheight)) + if ((floorheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= floorheight)) { boolean foundfof = false; floorclimb = true; @@ -2440,13 +2491,20 @@ static void P_DoClimbing(player_t *player) // Is there a FOF directly below that we can move onto? if (glidesector->sector->ffloors) { + fixed_t bottomheight; ffloor_t *rover; for (rover = glidesector->sector->ffloors; rover; rover = rover->next) { if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) continue; - if (*rover->bottomheight < glidesector->sector->floorheight + FixedMul(16*FRACUNIT, player->mo->scale)) +#ifdef ESLOPE + bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight; +#else + bottomheight = *rover->bottomheight; +#endif + + if (bottomheight < floorheight + FixedMul(16*FRACUNIT, player->mo->scale)) { foundfof = true; break; @@ -2459,8 +2517,8 @@ static void P_DoClimbing(player_t *player) } // Reached the top of the lower texture area - if (!floorclimb && glidesector->sector->ceilingheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) - && (glidesector->sector->ceilingpic == skyflatnum || glidesector->sector->floorheight < (player->mo->z - FixedMul(8*FRACUNIT, player->mo->scale)))) + if (!floorclimb && ceilingheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) + && (glidesector->sector->ceilingpic == skyflatnum || floorheight < (player->mo->z - FixedMul(8*FRACUNIT, player->mo->scale)))) { thrust = true; boostup = true; @@ -2470,7 +2528,7 @@ static void P_DoClimbing(player_t *player) else { // Trying to climb down past the upper texture area - if ((glidesector->sector->ceilingheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= glidesector->sector->ceilingheight)) + if ((ceilingheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= ceilingheight)) { boolean foundfof = false; floorclimb = true; @@ -2484,7 +2542,7 @@ static void P_DoClimbing(player_t *player) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) continue; - if (*rover->topheight > glidesector->sector->ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale)) + if (*rover->topheight > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale)) { foundfof = true; break; @@ -2497,7 +2555,7 @@ static void P_DoClimbing(player_t *player) } // Allow climbing from a FOF or lower texture onto the upper texture and vice versa. - if (player->mo->z > glidesector->sector->ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale)) + if (player->mo->z > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale)) { floorclimb = true; thrust = false; @@ -2505,8 +2563,8 @@ static void P_DoClimbing(player_t *player) } // Reached the top of the lower texture area - if (!floorclimb && glidesector->sector->floorheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) - && (glidesector->sector->ceilingpic == skyflatnum || glidesector->sector->ceilingheight > (player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, player->mo->scale)))) + if (!floorclimb && floorheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) + && (glidesector->sector->ceilingpic == skyflatnum || ceilingheight > (player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, player->mo->scale)))) { thrust = true; boostup = true; @@ -2515,14 +2573,14 @@ static void P_DoClimbing(player_t *player) } // Trying to climb on the sky - if ((glidesector->sector->ceilingheight < player->mo->z) && glidesector->sector->ceilingpic == skyflatnum) + if ((ceilingheight < player->mo->z) && glidesector->sector->ceilingpic == skyflatnum) { skyclimber = true; } // Climbing on the lower texture area? - if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) < glidesector->sector->floorheight) - || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height <= glidesector->sector->floorheight)) + if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) < floorheight) + || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height <= floorheight)) { floorclimb = true; @@ -2538,8 +2596,8 @@ static void P_DoClimbing(player_t *player) } } // Climbing on the upper texture area? - else if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z >= glidesector->sector->ceilingheight) - || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) > glidesector->sector->ceilingheight)) + else if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z >= ceilingheight) + || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) > ceilingheight)) { floorclimb = true; @@ -2632,21 +2690,21 @@ static void P_DoClimbing(player_t *player) player->climbing = 0; player->pflags |= PF_JUMPED; - P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); } if (skyclimber) { player->climbing = 0; player->pflags |= PF_JUMPED; - P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); } } else { player->climbing = 0; player->pflags |= PF_JUMPED; - P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); } if (cmd->sidemove != 0 || cmd->forwardmove != 0) @@ -2664,7 +2722,7 @@ static void P_DoClimbing(player_t *player) { player->climbing = 0; player->pflags |= PF_JUMPED; - P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); P_SetObjectMomZ(player->mo, 4*FRACUNIT, false); P_InstaThrust(player->mo, player->mo->angle, FixedMul(-4*FRACUNIT, player->mo->scale)); } @@ -2675,7 +2733,7 @@ static void P_DoClimbing(player_t *player) localangle2 = player->mo->angle; if (player->climbing == 0) - P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); if (player->climbing && P_IsObjectOnGround(player->mo)) { @@ -3384,27 +3442,14 @@ static void P_DoSuperStuff(player_t *player) if ((leveltime % TICRATE == 0) && !(player->exiting)) player->rings--; + // future todo: a skin option for this, and possibly more colors switch (player->skin) { - case 1: // Golden orange supertails. - if (leveltime % 9 < 5) - player->mo->color = SKINCOLOR_TSUPER1 + leveltime % 9; - else - player->mo->color = SKINCOLOR_TSUPER1 + 9 - leveltime % 9; - break; - case 2: // Pink superknux. - if (leveltime % 9 < 5) - player->mo->color = SKINCOLOR_KSUPER1 + leveltime % 9; - else - player->mo->color = SKINCOLOR_KSUPER1 + 9 - leveltime % 9; - break; - default: // Yousa yellow now! - if (leveltime % 9 < 5) - player->mo->color = SKINCOLOR_SUPER1 + leveltime % 9; - else - player->mo->color = SKINCOLOR_SUPER1 + 9 - leveltime % 9; - break; + case 1: /* Tails */ player->mo->color = SKINCOLOR_TSUPER1; break; + case 2: /* Knux */ player->mo->color = SKINCOLOR_KSUPER1; break; + default: /* everyone */ player->mo->color = SKINCOLOR_SUPER1; break; } + player->mo->color += abs( ( ( leveltime >> 1 ) % 9) - 4); if ((cmd->forwardmove != 0 || cmd->sidemove != 0 || player->pflags & (PF_CARRIED|PF_ROPEHANG|PF_ITEMHANG|PF_MACESPIN)) && !(leveltime % TICRATE) && (player->mo->momx || player->mo->momy)) @@ -3441,8 +3486,9 @@ static void P_DoSuperStuff(player_t *player) if (player->mo->health > 0) { - if ((player->pflags & PF_JUMPED || player->pflags & PF_SPINNING) - && player->mo->state-states != S_PLAY_DASH) + if (player->pflags & PF_JUMPED) + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + else if (player->pflags & PF_SPINNING && player->mo->state-states != S_PLAY_DASH) P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); else switch (player->mo->state-states) { @@ -3460,8 +3506,8 @@ static void P_DoSuperStuff(player_t *player) case S_PLAY_SUPER_PAIN: P_SetPlayerMobjState(player->mo, S_PLAY_PAIN); break; - case S_PLAY_SUPER_JUMP: - P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + case S_PLAY_SUPER_SPRING: + P_SetPlayerMobjState(player->mo, S_PLAY_SPRING); break; case S_PLAY_SUPER_FALL: P_SetPlayerMobjState(player->mo, S_PLAY_FALL); @@ -3675,9 +3721,9 @@ void P_DoJump(player_t *player, boolean soundandstate) S_StartSound(player->mo, sfx_jump); // Play jump sound! if (!(player->charability2 == CA2_SPINDASH)) - P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); + P_SetPlayerMobjState(player->mo, S_PLAY_SPRING); else - P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); } } @@ -3703,7 +3749,11 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_SLIDING) && !player->exiting && !P_PlayerInPain(player)) // subsequent revs { - if ((cmd->buttons & BT_USE) && player->speed < FixedMul(5<mo->scale) && !player->mo->momz && onground && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING)) + if ((cmd->buttons & BT_USE) && player->speed < FixedMul(5<mo->scale) && !player->mo->momz && onground && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING) +#ifdef ESLOPE + && (!player->mo->standingslope || abs(player->mo->standingslope->zdelta) < FRACUNIT/2) +#endif + ) { player->mo->momx = player->cmomx; player->mo->momy = player->cmomy; @@ -3735,7 +3785,11 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) // down the spin button and not spinning. // AKA Just go into a spin on the ground, you idiot. ;) else if ((cmd->buttons & BT_USE || ((twodlevel || (player->mo->flags2 & MF2_TWOD)) && cmd->forwardmove < -20)) - && !player->climbing && !player->mo->momz && onground && player->speed > FixedMul(5<mo->scale) && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING)) + && !player->climbing && !player->mo->momz && onground && (player->speed > FixedMul(5<mo->scale) +#ifdef ESLOPE + || (player->mo->standingslope && abs(player->mo->standingslope->zdelta) >= FRACUNIT/2) +#endif + ) && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING)) { player->pflags |= PF_SPINNING; P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); @@ -3747,7 +3801,11 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd) // Rolling normally if (onground && player->pflags & PF_SPINNING && !(player->pflags & PF_STARTDASH) - && player->speed < FixedMul(5*FRACUNIT,player->mo->scale)) + && player->speed < FixedMul(5*FRACUNIT,player->mo->scale) +#ifdef ESLOPE + && (!player->mo->standingslope || abs(player->mo->standingslope->zdelta) < FRACUNIT/2) +#endif + ) { if (GETSECSPECIAL(player->mo->subsector->sector->special, 4) == 7 || (player->mo->ceilingz - player->mo->floorz < P_GetPlayerHeight(player))) P_InstaThrust(player->mo, player->mo->angle, FixedMul(10*FRACUNIT, player->mo->scale)); @@ -4443,12 +4501,16 @@ static void P_3dMovement(player_t *player) angle_t dangle; // replaces old quadrants bits fixed_t normalspd = FixedMul(player->normalspeed, player->mo->scale); boolean analogmove = false; -#ifndef OLD_MOVEMENT_CODE fixed_t oldMagnitude, newMagnitude; +#ifdef ESLOPE + vector3_t totalthrust; + + totalthrust.x = totalthrust.y = 0; // I forget if this is needed + totalthrust.z = FRACUNIT*P_MobjFlip(player->mo)/3; // A bit of extra push-back on slopes +#endif // ESLOPE // Get the old momentum; this will be needed at the end of the function! -SH oldMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0); -#endif analogmove = P_AnalogMove(player); @@ -4621,17 +4683,10 @@ static void P_3dMovement(player_t *player) } movepushforward = FixedMul(movepushforward, player->mo->scale); -#ifdef OLD_MOVEMENT_CODE - if (player->speed < topspeed && mforward && cmd->forwardmove > 0) // Sonic's Speed - P_Thrust(player->mo, movepushangle, movepushforward); - else if (mforward && cmd->forwardmove < 0) - P_Thrust(player->mo, movepushangle, movepushforward); - else if (player->speed < topspeed && mbackward && cmd->forwardmove < 0) - P_Thrust(player->mo, movepushangle, movepushforward); - else if (mbackward && cmd->forwardmove > 0) - P_Thrust(player->mo, movepushangle, movepushforward); - else if (!mforward && !mbackward) - P_Thrust(player->mo, movepushangle, movepushforward); + +#ifdef ESLOPE + totalthrust.x += P_ReturnThrustX(player->mo, movepushangle, movepushforward); + totalthrust.y += P_ReturnThrustY(player->mo, movepushangle, movepushforward); #else P_Thrust(player->mo, movepushangle, movepushforward); #endif @@ -4645,33 +4700,12 @@ static void P_3dMovement(player_t *player) if (!(player->pflags & PF_GLIDING || player->exiting || P_PlayerInPain(player))) { angle_t controldirection; -#ifdef OLD_MOVEMENT_CODE - angle_t controlplayerdirection; - boolean cforward; // controls pointing forward from the player - boolean cbackward; // controls pointing backward from the player - angle_t dangle; - cforward = cbackward = false; -#endif // Calculate the angle at which the controls are pointing // to figure out the proper mforward and mbackward. // (Why was it so complicated before? ~Red) controldirection = R_PointToAngle2(0, 0, cmd->forwardmove*FRACUNIT, -cmd->sidemove*FRACUNIT)+movepushangle; -#ifdef OLD_MOVEMENT_CODE - controlplayerdirection = player->mo->angle; - - dangle = controldirection - controlplayerdirection; - - if (dangle > ANGLE_180) //flip to keep to one side - dangle = InvAngle(dangle); - - if (dangle > ANGLE_90) - cbackward = true; // Controls pointing backwards from player - else - cforward = true; // Controls pointing in player's general direction -#endif - movepushforward = max(abs(cmd->sidemove), abs(cmd->forwardmove)) * (thrustfactor * acceleration); // allow very small movement while in air for gameplay @@ -4694,13 +4728,10 @@ static void P_3dMovement(player_t *player) movepushsideangle = controldirection; movepushforward = FixedMul(movepushforward, player->mo->scale); -#ifdef OLD_MOVEMENT_CODE - if (player->speed < topspeed) - P_Thrust(player->mo, controldirection, movepushforward); - else if ((mforward) && (cbackward)) - P_Thrust(player->mo, controldirection, movepushforward); - else if ((mbackward) && (cforward)) - P_Thrust(player->mo, controldirection, movepushforward); + +#ifdef ESLOPE + totalthrust.x += P_ReturnThrustX(player->mo, controldirection, movepushforward); + totalthrust.y += P_ReturnThrustY(player->mo, controldirection, movepushforward); #else P_Thrust(player->mo, controldirection, movepushforward); #endif @@ -4708,29 +4739,6 @@ static void P_3dMovement(player_t *player) } else if (cmd->sidemove && !(player->pflags & PF_GLIDING) && !player->exiting && !P_PlayerInPain(player)) { -#ifdef OLD_MOVEMENT_CODE - boolean mright = 0; - boolean mleft = 0; - angle_t sideangle; - - sideangle = player->mo->angle - ANGLE_90; - - // Monster Iestyn - 04-11-13 - // Quadrants are stupid, excessive and broken, let's do this a much simpler way! - // Get delta angle from rmom angle and player angle first - dangle = R_PointToAngle2(0,0, player->rmomx, player->rmomy) - sideangle; - if (dangle > ANGLE_180) - dangle = InvAngle(dangle); - - // now use it to determine direction! - if (dangle <= ANGLE_45) // angles 0-45 or 315-360 - mright = 1; // going right - else if (dangle >= ANGLE_135) // angles 135-225 - mleft = 1; // going left - - // anything else will leave both at 0, so no need to do anything else -#endif - movepushside = cmd->sidemove * (thrustfactor * acceleration); if (!onground) @@ -4753,19 +4761,37 @@ static void P_3dMovement(player_t *player) // Finally move the player now that his speed/direction has been decided. movepushside = FixedMul(movepushside, player->mo->scale); -#ifdef OLD_MOVEMENT_CODE - if (player->speed < topspeed) - P_Thrust(player->mo, movepushsideangle, movepushside); - else if (mright && cmd->sidemove < 0) - P_Thrust(player->mo, movepushsideangle, movepushside); - else if (mleft && cmd->sidemove > 0) - P_Thrust(player->mo, movepushsideangle, movepushside); + +#ifdef ESLOPE + totalthrust.x += P_ReturnThrustX(player->mo, movepushsideangle, movepushside); + totalthrust.y += P_ReturnThrustY(player->mo, movepushsideangle, movepushside); #else P_Thrust(player->mo, movepushsideangle, movepushside); #endif } -#ifndef OLD_MOVEMENT_CODE +#ifdef ESLOPE + if ((totalthrust.x || totalthrust.y) + && player->mo->standingslope && abs(player->mo->standingslope->zdelta) > FRACUNIT/2) { + // Factor thrust to slope, but only for the part pushing up it! + // The rest is unaffected. + angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y)-player->mo->standingslope->xydirection; + + if (player->mo->standingslope->zdelta < 0) { // Direction goes down, so thrustangle needs to face toward + if (thrustangle < ANGLE_90 || thrustangle > ANGLE_270) { + P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope); + } + } else { // Direction goes up, so thrustangle needs to face away + if (thrustangle > ANGLE_90 && thrustangle < ANGLE_270) { + P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope); + } + } + } + + player->mo->momx += totalthrust.x; + player->mo->momy += totalthrust.y; +#endif + // Time to ask three questions: // 1) Are we over topspeed? // 2) If "yes" to 1, were we moving over topspeed to begin with? @@ -4799,7 +4825,6 @@ static void P_3dMovement(player_t *player) player->mo->momy = tempmomy + player->cmomy; } } -#endif } // @@ -5553,7 +5578,7 @@ static void P_NiGHTSMovement(player_t *player) } else if (P_IsLocalPlayer(player) && player->nightstime == 10*TICRATE) // S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH - S_ChangeMusic(mus_drown,false); + S_ChangeMusicInternal("drown",false); if (player->mo->z < player->mo->floorz) @@ -6301,8 +6326,7 @@ static void P_MovePlayer(player_t *player) if (!(player->powers[pw_nocontrol] & (1<<15))) player->pflags |= PF_JUMPSTASIS; } - else - player->pflags &= ~PF_FULLSTASIS; + // note: don't unset stasis here if (!player->spectator && G_TagGametype()) { @@ -6452,10 +6476,10 @@ static void P_MovePlayer(player_t *player) } // If Springing, but travelling DOWNWARD, change back! - if (player->panim == PA_JUMP && P_MobjFlip(player->mo)*player->mo->momz < 0) + if (player->panim == PA_SPRING && P_MobjFlip(player->mo)*player->mo->momz < 0) P_SetPlayerMobjState(player->mo, S_PLAY_FALL); // If Springing but on the ground, change back! - else if (onground && (player->panim == PA_JUMP || player->panim == PA_FALL || player->panim == PA_RIDE) && !player->mo->momz) + else if (onground && (player->panim == PA_SPRING || player->panim == PA_FALL || player->panim == PA_RIDE) && !player->mo->momz) P_SetPlayerMobjState(player->mo, S_PLAY_STND); // If you are stopped and are still walking, stand still! @@ -6494,7 +6518,7 @@ static void P_MovePlayer(player_t *player) else { player->pflags |= PF_JUMPED; - P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); } } player->pflags &= ~PF_GLIDING; @@ -6552,7 +6576,7 @@ static void P_MovePlayer(player_t *player) && player->charability == CA_GLIDEANDCLIMB) { player->pflags |= PF_JUMPED; - P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); } else { @@ -6622,7 +6646,7 @@ static void P_MovePlayer(player_t *player) else { player->pflags |= PF_JUMPED; - P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); } } player->powers[pw_tailsfly] = 0; @@ -7197,7 +7221,7 @@ static void P_DoRopeHang(player_t *player) if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED) && !(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH) - P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); return; } @@ -7314,7 +7338,7 @@ static void P_DoRopeHang(player_t *player) if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED) && !(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH) - P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); } P_SetTarget(&player->mo->tracer, NULL); @@ -7691,7 +7715,7 @@ static void P_DeathThink(player_t *player) // Return to level music if (netgame && player->deadtimer == gameovertics && P_IsLocalPlayer(player)) - S_ChangeMusic(mapmusic, true); + S_ChangeMusic(mapmusname, mapmusflags, true); } if (!player->mo) @@ -7926,9 +7950,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (player == &players[consoleplayer]) { if (focusangle >= localangle) - localangle += abs(focusangle - localangle)>>5; + localangle += abs((focusangle - localangle))>>5; else - localangle -= abs(focusangle - localangle)>>5; + localangle -= abs((focusangle - localangle))>>5; } } else if (P_AnalogMove(player)) // Analog @@ -8630,7 +8654,7 @@ void P_PlayerThink(player_t *player) P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE); } else if ((player->pflags & PF_JUMPED) && !player->powers[pw_super] && player->panim != PA_ROLL && player->charability2 == CA2_SPINDASH) - P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); if (player->flashcount) player->flashcount--; @@ -8677,7 +8701,7 @@ void P_PlayerThink(player_t *player) if (countdown == 11*TICRATE - 1) { if (P_IsLocalPlayer(player)) - S_ChangeMusic(mus_drown, false); + S_ChangeMusicInternal("drown", false); } // If you've hit the countdown and you haven't made @@ -8831,10 +8855,7 @@ void P_PlayerThink(player_t *player) mo2 = (mobj_t *)th; if (!(mo2->type == MT_NIGHTSWING || mo2->type == MT_RING || mo2->type == MT_COIN -#ifdef BLUE_SPHERES - || mo2->type == MT_BLUEBALL -#endif - )) + || mo2->type == MT_BLUEBALL)) continue; if (P_AproxDistance(P_AproxDistance(mo2->x - x, mo2->y - y), mo2->z - z) > FixedMul(128*FRACUNIT, player->mo->scale)) @@ -8888,6 +8909,11 @@ void P_PlayerThink(player_t *player) if (!player->mo) return; // P_MovePlayer removed player->mo. + // Unset statis flags after moving. + // In other words, if you manually set stasis via code, + // it lasts for one tic. + player->pflags &= ~PF_FULLSTASIS; + #ifdef POLYOBJECTS if (player->onconveyor == 1) player->cmomy = player->cmomx = 0; @@ -9254,7 +9280,7 @@ void P_PlayerAfterThink(player_t *player) && ((!player->powers[pw_super] && player->panim != PA_ROLL) || player->mo->state == &states[player->mo->info->painstate]) && player->charability2 == CA2_SPINDASH) - P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); + P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); if (player->pflags & PF_CARRIED && player->mo->tracer) { diff --git a/src/r_bsp.c b/src/r_bsp.c index fb25b8e4d..c87d8baa7 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -18,6 +18,7 @@ #include "r_splats.h" #include "p_local.h" // camera +#include "p_slopes.h" #include "z_zone.h" // Check R_Prep3DFloors seg_t *curline; @@ -31,7 +32,6 @@ sector_t *backsector; // 896 drawsegs! So too bad here's a limit removal a-la-Boom drawseg_t *drawsegs = NULL; drawseg_t *ds_p = NULL; -drawseg_t *firstnewseg = NULL; // indicates doors closed wrt automap bugfix: INT32 doorclosed; @@ -459,6 +459,11 @@ static void R_AddLine(seg_t *line) doorclosed = 0; // Closed door. +#ifdef ESLOPE + // Just don't bother checking this if one side is sloped. This is probably inefficient, but it's better than + // random renderer stopping around slopes... + if (!(frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope)) +#endif if (backsector->ceilingheight <= frontsector->floorheight || backsector->floorheight >= frontsector->ceilingheight) { @@ -487,6 +492,10 @@ static void R_AddLine(seg_t *line) #endif backsector->ceilingpic == frontsector->ceilingpic && backsector->floorpic == frontsector->floorpic +#ifdef ESLOPE + && backsector->f_slope == frontsector->f_slope + && backsector->c_slope == frontsector->c_slope +#endif && backsector->lightlevel == frontsector->lightlevel && !curline->sidedef->midtexture // Check offsets too! @@ -842,11 +851,19 @@ static void R_Subsector(size_t num) sub->sector->moved = frontsector->moved = false; } - light = R_GetPlaneLight(frontsector, frontsector->floorheight, false); + light = R_GetPlaneLight(frontsector, +#ifdef ESLOPE + frontsector->f_slope ? P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) : +#endif + frontsector->floorheight, false); if (frontsector->floorlightsec == -1) floorlightlevel = *frontsector->lightlist[light].lightlevel; floorcolormap = frontsector->lightlist[light].extra_colormap; - light = R_GetPlaneLight(frontsector, frontsector->ceilingheight, false); + light = R_GetPlaneLight(frontsector, +#ifdef ESLOPE + frontsector->c_slope ? P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) : +#endif + frontsector->ceilingheight, false); if (frontsector->ceilinglightsec == -1) ceilinglightlevel = *frontsector->lightlist[light].lightlevel; ceilingcolormap = frontsector->lightlist[light].extra_colormap; @@ -854,32 +871,52 @@ static void R_Subsector(size_t num) sub->sector->extra_colormap = frontsector->extra_colormap; - if ((frontsector->floorheight < viewz || (frontsector->heightsec != -1 + if ((( +#ifdef ESLOPE + frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : +#endif + frontsector->floorheight) < viewz || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum))) { floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel, - frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL); + frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL +#ifdef ESLOPE + , frontsector->f_slope +#endif + ); } else floorplane = NULL; - if ((frontsector->ceilingheight > viewz || frontsector->ceilingpic == skyflatnum + if ((( +#ifdef ESLOPE + frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) : +#endif + frontsector->ceilingheight) > viewz || frontsector->ceilingpic == skyflatnum || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].floorpic == skyflatnum))) { ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic, ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle, - ceilingcolormap, NULL); + ceilingcolormap, NULL +#ifdef ESLOPE + , frontsector->c_slope +#endif + ); } else ceilingplane = NULL; numffloors = 0; +#ifdef ESLOPE + ffloor[numffloors].slope = NULL; +#endif ffloor[numffloors].plane = NULL; ffloor[numffloors].polyobj = NULL; if (frontsector->ffloors) { ffloor_t *rover; + fixed_t heightcheck, planecenterz, floorcenterz, ceilingcenterz; for (rover = frontsector->ffloors; rover && numffloors < MAXFFLOORS; rover = rover->next) { @@ -897,18 +934,60 @@ static void R_Subsector(size_t num) ffloor[numffloors].plane = NULL; ffloor[numffloors].polyobj = NULL; - if (*rover->bottomheight <= frontsector->ceilingheight - && *rover->bottomheight >= frontsector->floorheight - && ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) - || (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) + + floorcenterz = +#ifdef ESLOPE + frontsector->f_slope ? P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) : +#endif + frontsector->floorheight; + + ceilingcenterz = +#ifdef ESLOPE + frontsector->c_slope ? P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) : +#endif + frontsector->ceilingheight; + + heightcheck = +#ifdef ESLOPE + *rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : +#endif + *rover->bottomheight; + + planecenterz = +#ifdef ESLOPE + *rover->b_slope ? P_GetZAt(*rover->b_slope, frontsector->soundorg.x, frontsector->soundorg.y) : +#endif + *rover->bottomheight; + if (planecenterz <= ceilingcenterz + && planecenterz >= floorcenterz + && ((viewz < heightcheck && !(rover->flags & FF_INVERTPLANES)) + || (viewz > heightcheck && (rover->flags & FF_BOTHPLANES)))) { - light = R_GetPlaneLight(frontsector, *rover->bottomheight, + light = R_GetPlaneLight(frontsector, planecenterz, viewz < *rover->bottomheight); + ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic, *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, - *rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover); + *rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover +#ifdef ESLOPE + , *rover->b_slope +#endif + ); + +#ifdef ESLOPE + ffloor[numffloors].slope = *rover->b_slope; + + // Tell the renderer this sector has slopes in it. + if (ffloor[numffloors].slope) + frontsector->hasslope = true; +#endif + + ffloor[numffloors].height = +#ifdef ESLOPE + *rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : +#endif + *rover->bottomheight; - ffloor[numffloors].height = *rover->bottomheight; ffloor[numffloors].ffloor = rover; numffloors++; } @@ -916,16 +995,47 @@ static void R_Subsector(size_t num) break; ffloor[numffloors].plane = NULL; ffloor[numffloors].polyobj = NULL; - if (*rover->topheight >= frontsector->floorheight - && *rover->topheight <= frontsector->ceilingheight - && ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) - || (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) + + heightcheck = +#ifdef ESLOPE + *rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : +#endif + *rover->topheight; + + planecenterz = +#ifdef ESLOPE + *rover->t_slope ? P_GetZAt(*rover->t_slope, frontsector->soundorg.x, frontsector->soundorg.y) : +#endif + *rover->topheight; + if (planecenterz >= floorcenterz + && planecenterz <= ceilingcenterz + && ((viewz > heightcheck && !(rover->flags & FF_INVERTPLANES)) + || (viewz < heightcheck && (rover->flags & FF_BOTHPLANES)))) { - light = R_GetPlaneLight(frontsector, *rover->topheight, viewz < *rover->topheight); + light = R_GetPlaneLight(frontsector, planecenterz, viewz < *rover->topheight); + ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic, *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle, - frontsector->lightlist[light].extra_colormap, rover); - ffloor[numffloors].height = *rover->topheight; + frontsector->lightlist[light].extra_colormap, rover +#ifdef ESLOPE + , *rover->t_slope +#endif + ); + +#ifdef ESLOPE + ffloor[numffloors].slope = *rover->t_slope; + + // Tell the renderer this sector has slopes in it. + if (ffloor[numffloors].slope) + frontsector->hasslope = true; +#endif + + ffloor[numffloors].height = +#ifdef ESLOPE + *rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : +#endif + *rover->topheight; + ffloor[numffloors].ffloor = rover; numffloors++; } @@ -977,11 +1087,18 @@ static void R_Subsector(size_t num) polysec->lightlevel, xoff, yoff, polysec->floorpic_angle-po->angle, NULL, - NULL); + NULL +#ifdef ESLOPE + , NULL // will ffloors be slopable eventually? +#endif + ); //ffloor[numffloors].plane->polyobj = po; ffloor[numffloors].height = polysec->floorheight; ffloor[numffloors].polyobj = po; +#ifdef ESLOPE + ffloor[numffloors].slope = NULL; +#endif // ffloor[numffloors].ffloor = rover; po->visplane = ffloor[numffloors].plane; numffloors++; @@ -1014,11 +1131,18 @@ static void R_Subsector(size_t num) light = 0; ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic, polysec->lightlevel, xoff, yoff, polysec->ceilingpic_angle-po->angle, - NULL, NULL); + NULL, NULL +#ifdef ESLOPE + , NULL // will ffloors be slopable eventually? +#endif + ); //ffloor[numffloors].plane->polyobj = po; ffloor[numffloors].polyobj = po; ffloor[numffloors].height = polysec->ceilingheight; +#ifdef ESLOPE + ffloor[numffloors].slope = NULL; +#endif // ffloor[numffloors].ffloor = rover; po->visplane = ffloor[numffloors].plane; numffloors++; @@ -1077,6 +1201,11 @@ void R_Prep3DFloors(sector_t *sector) fixed_t bestheight, maxheight; INT32 count, i, mapnum; sector_t *sec; +#ifdef ESLOPE + pslope_t *bestslope; + fixed_t heighttest; // I think it's better to check the Z height at the sector's center + // than assume unsloped heights are accurate indicators of order in sloped sectors. -Red +#endif count = 1; for (rover = sector->ffloors; rover; rover = rover->next) @@ -1099,7 +1228,14 @@ void R_Prep3DFloors(sector_t *sector) else memset(sector->lightlist, 0, sizeof (lightlist_t) * count); +#ifdef ESLOPE + heighttest = sector->c_slope ? P_GetZAt(sector->c_slope, sector->soundorg.x, sector->soundorg.y) : sector->ceilingheight; + + sector->lightlist[0].height = heighttest + 1; + sector->lightlist[0].slope = sector->c_slope; +#else sector->lightlist[0].height = sector->ceilingheight + 1; +#endif sector->lightlist[0].lightlevel = §or->lightlevel; sector->lightlist[0].caster = NULL; sector->lightlist[0].extra_colormap = sector->extra_colormap; @@ -1117,6 +1253,29 @@ void R_Prep3DFloors(sector_t *sector) && !(rover->flags & FF_CUTLEVEL) && !(rover->flags & FF_CUTSPRITES))) continue; +#ifdef ESLOPE + heighttest = *rover->t_slope ? P_GetZAt(*rover->t_slope, sector->soundorg.x, sector->soundorg.y) : *rover->topheight; + + if (heighttest > bestheight && heighttest < maxheight) + { + best = rover; + bestheight = heighttest; + bestslope = *rover->t_slope; + continue; + } + if (rover->flags & FF_DOUBLESHADOW) { + heighttest = *rover->b_slope ? P_GetZAt(*rover->b_slope, sector->soundorg.x, sector->soundorg.y) : *rover->bottomheight; + + if (heighttest > bestheight + && heighttest < maxheight) + { + best = rover; + bestheight = heighttest; + bestslope = *rover->b_slope; + continue; + } + } +#else if (*rover->topheight > bestheight && *rover->topheight < maxheight) { best = rover; @@ -1130,6 +1289,7 @@ void R_Prep3DFloors(sector_t *sector) bestheight = *rover->bottomheight; continue; } +#endif } if (!best) { @@ -1140,6 +1300,9 @@ void R_Prep3DFloors(sector_t *sector) sector->lightlist[i].height = maxheight = bestheight; sector->lightlist[i].caster = best; sector->lightlist[i].flags = best->flags; +#ifdef ESLOPE + sector->lightlist[i].slope = bestslope; +#endif sec = §ors[best->secnum]; mapnum = sec->midmap; if (mapnum >= 0 && (size_t)mapnum < num_extra_colormaps) @@ -1165,7 +1328,12 @@ void R_Prep3DFloors(sector_t *sector) if (best->flags & FF_DOUBLESHADOW) { +#ifdef ESLOPE + heighttest = *best->b_slope ? P_GetZAt(*best->b_slope, sector->soundorg.x, sector->soundorg.y) : *best->bottomheight; + if (bestheight == heighttest) ///TODO: do this in a more efficient way -Red +#else if (bestheight == *best->bottomheight) +#endif { sector->lightlist[i].lightlevel = sector->lightlist[best->lastlight].lightlevel; sector->lightlist[i].extra_colormap = diff --git a/src/r_bsp.h b/src/r_bsp.h index 20a80d89a..14b11ea77 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -30,7 +30,6 @@ extern INT32 checkcoord[12][4]; extern drawseg_t *drawsegs; extern drawseg_t *ds_p; -extern drawseg_t *firstnewseg; extern INT32 doorclosed; typedef void (*drawfunc_t)(INT32 start, INT32 stop); diff --git a/src/r_defs.h b/src/r_defs.h index 7f8bd7e1d..2915b9259 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -155,6 +155,12 @@ typedef struct ffloor_s fixed_t *bottomyoffs; angle_t *bottomangle; +#ifdef ESLOPE + // Pointers to pointers. Yup. + struct pslope_s **t_slope; + struct pslope_s **b_slope; +#endif + size_t secnum; ffloortype_e flags; struct line_s *master; @@ -184,6 +190,9 @@ typedef struct lightlist_s extracolormap_t *extra_colormap; INT32 flags; ffloor_t *caster; +#ifdef ESLOPE + struct pslope_s *slope; // FF_DOUBLESHADOW makes me have to store this pointer here. Bluh bluh. +#endif } lightlist_t; @@ -224,6 +233,52 @@ typedef struct secplane_t fixed_t a, b, c, d, ic; } secplane_t; +// Slopes +#ifdef ESLOPE +typedef enum { + SL_NOPHYSICS = 1, // Don't do momentum adjustment with this slope + SL_NODYNAMIC = 1<<1, // Slope will never need to move during the level, so don't fuss with recalculating it + SL_ANCHORVERTEX = 1<<2, // Slope is using a Slope Vertex Thing to anchor its position + SL_VERTEXSLOPE = 1<<3, // Slope is built from three Slope Vertex Things +} slopeflags_t; + +typedef struct pslope_s +{ + UINT16 id; // The number of the slope, mostly used for netgame syncing purposes + + // --- Information used in clipping/projection --- + // Origin vector for the plane + vector3_t o; + + // 2-Dimentional vector (x, y) normalized. Used to determine distance from + // the origin in 2d mapspace. (Basically a thrust of FRACUNIT in xydirection angle) + vector2_t d; + + // The rate at which z changes based on distance from the origin plane. + fixed_t zdelta; + + // The normal of the slope; will always point upward, and thus be inverted on ceilings. I think it's only needed for physics? -Red + vector3_t normal; + + // For comparing when a slope should be rendered + fixed_t lowz; + fixed_t highz; + + // This values only check and must be updated if the slope itself is modified + angle_t zangle; // Angle of the plane going up from the ground (not mesured in degrees) + angle_t xydirection; // The direction the slope is facing (north, west, south, etc.) + + struct line_s *sourceline; // The line that generated the slope + fixed_t extent; // Distance value used for recalculating zdelta + UINT8 refpos; // 1=front floor 2=front ceiling 3=back floor 4=back ceiling (used for dynamic sloping) + + UINT8 flags; // Slope options + mapthing_t **vertices; // List should be three long for slopes made by vertex things, or one long for slopes using one vertex thing to anchor + + struct pslope_s *next; // Make a linked list of dynamic slopes, for easy reference later +} pslope_t; +#endif + typedef enum { SF_FLIPSPECIAL_FLOOR = 1, @@ -314,14 +369,6 @@ typedef struct sector_s double lineoutLength; #endif // ----- end special tricks ----- - // ZDoom C++ to Legacy C conversion (for slopes) - // store floor and ceiling planes instead of heights - //secplane_t floorplane, ceilingplane; -#ifdef SLOPENESS - //fixed_t floortexz, ceilingtexz; // [RH] used for wall texture mapping - angle_t floorangle; -#endif - // This points to the master's floorheight, so it can be changed in realtime! fixed_t *gravity; // per-sector gravity boolean verticalflip; // If gravity < 0, then allow flipped physics @@ -337,6 +384,13 @@ typedef struct sector_s precipmobj_t *preciplist; struct mprecipsecnode_s *touching_preciplist; +#ifdef ESLOPE + // Eternity engine slope + pslope_t *f_slope; // floor slope + pslope_t *c_slope; // ceiling slope + boolean hasslope; // The sector, or one of its visible FOFs, contains a slope +#endif + // these are saved for netgames, so do not let Lua touch these! // offsets sector spawned with (via linedef type 7) @@ -612,6 +666,12 @@ typedef struct drawseg_s INT16 *thicksidecol; INT32 numthicksides; fixed_t frontscale[MAXVIDWIDTH]; + +#ifdef ESLOPE + fixed_t maskedtextureheight[MAXVIDWIDTH]; // For handling sloped midtextures + + vertex_t leftpos, rightpos; // Used for rendering FOF walls with slopes +#endif } drawseg_t; typedef enum diff --git a/src/r_draw.c b/src/r_draw.c index cd219c15f..d1673c9a6 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -103,6 +103,12 @@ fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep; UINT8 *ds_source; // start of a 64*64 tile image UINT8 *ds_transmap; // one of the translucency tables +#ifdef ESLOPE +pslope_t *ds_slope; // Current slope being used +floatv3_t ds_su, ds_sv, ds_sz; // Vectors for... stuff? +float focallengthf, zeroheight; +#endif + /** \brief Variable flat sizes */ @@ -121,7 +127,7 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask; #define METALSONIC_TT_CACHE_INDEX (MAXSKINS + 2) #define ALLWHITE_TT_CACHE_INDEX (MAXSKINS + 3) #define SKIN_RAMP_LENGTH 16 -#define DEFAULT_STARTTRANSCOLOR 160 +#define DEFAULT_STARTTRANSCOLOR 96 #define NUM_PALETTE_ENTRIES 256 static UINT8** translationtablecache[MAXSKINS + 4] = {NULL}; @@ -131,62 +137,70 @@ static UINT8** translationtablecache[MAXSKINS + 4] = {NULL}; // TODO Callum: Can this be translated? const char *Color_Names[MAXSKINCOLORS] = { - "None", // SKINCOLOR_NONE - "White", // SKINCOLOR_WHITE - "Silver", // SKINCOLOR_SILVER - "Grey", // SKINCOLOR_GREY - "Black", // SKINCOLOR_BLACK - "Cyan", // SKINCOLOR_CYAN - "Teal", // SKINCOLOR_TEAL - "Steel_Blue",// SKINCOLOR_STEELBLUE - "Blue", // SKINCOLOR_BLUE - "Peach", // SKINCOLOR_PEACH - "Tan", // SKINCOLOR_TAN - "Pink", // SKINCOLOR_PINK - "Lavender", // SKINCOLOR_LAVENDER - "Purple", // SKINCOLOR_PURPLE - "Orange", // SKINCOLOR_ORANGE - "Rosewood", // SKINCOLOR_ROSEWOOD - "Beige", // SKINCOLOR_BEIGE - "Brown", // SKINCOLOR_BROWN - "Red", // SKINCOLOR_RED - "Dark_Red", // SKINCOLOR_DARKRED - "Neon_Green",// SKINCOLOR_NEONGREEN - "Green", // SKINCOLOR_GREEN - "Zim", // SKINCOLOR_ZIM - "Olive", // SKINCOLOR_OLIVE - "Yellow", // SKINCOLOR_YELLOW - "Gold" // SKINCOLOR_GOLD + "None", // SKINCOLOR_NONE + "White", // SKINCOLOR_WHITE + "Silver", // SKINCOLOR_SILVER + "Grey", // SKINCOLOR_GREY + "Black", // SKINCOLOR_BLACK + "Beige", // SKINCOLOR_BEIGE + "Peach", // SKINCOLOR_PEACH + "Brown", // SKINCOLOR_BROWN + "Red", // SKINCOLOR_RED + "Crimson", // SKINCOLOR_CRIMSON + "Orange", // SKINCOLOR_ORANGE + "Rust", // SKINCOLOR_RUST + "Gold", // SKINCOLOR_GOLD + "Yellow", // SKINCOLOR_YELLOW + "Tan", // SKINCOLOR_TAN + "Moss", // SKINCOLOR_MOSS + "Peridot", // SKINCOLOR_PERIDOT + "Green", // SKINCOLOR_GREEN + "Emerald", // SKINCOLOR_EMERALD + "Aqua", // SKINCOLOR_AQUA + "Teal", // SKINCOLOR_TEAL + "Cyan", // SKINCOLOR_CYAN + "Blue", // SKINCOLOR_BLUE + "Azure", // SKINCOLOR_AZURE + "Pastel", // SKINCOLOR_PASTEL + "Purple", // SKINCOLOR_PURPLE + "Lavender", // SKINCOLOR_LAVENDER + "Magenta", // SKINCOLOR_MAGENTA + "Pink", // SKINCOLOR_PINK + "Rosy" // SKINCOLOR_ROSY }; const UINT8 Color_Opposite[MAXSKINCOLORS*2] = { - SKINCOLOR_NONE,8, // SKINCOLOR_NONE - SKINCOLOR_BLACK,10, // SKINCOLOR_WHITE - SKINCOLOR_GREY,4, // SKINCOLOR_SILVER - SKINCOLOR_SILVER,12,// SKINCOLOR_GREY - SKINCOLOR_WHITE,8, // SKINCOLOR_BLACK - SKINCOLOR_NONE,8, // SKINCOLOR_CYAN - SKINCOLOR_NONE,8, // SKINCOLOR_TEAL - SKINCOLOR_NONE,8, // SKINCOLOR_STEELBLUE - SKINCOLOR_ORANGE,9, // SKINCOLOR_BLUE - SKINCOLOR_NONE,8, // SKINCOLOR_PEACH - SKINCOLOR_NONE,8, // SKINCOLOR_TAN - SKINCOLOR_NONE,8, // SKINCOLOR_PINK - SKINCOLOR_NONE,8, // SKINCOLOR_LAVENDER - SKINCOLOR_NONE,8, // SKINCOLOR_PURPLE - SKINCOLOR_BLUE,12, // SKINCOLOR_ORANGE - SKINCOLOR_NONE,8, // SKINCOLOR_ROSEWOOD - SKINCOLOR_NONE,8, // SKINCOLOR_BEIGE - SKINCOLOR_NONE,8, // SKINCOLOR_BROWN - SKINCOLOR_GREEN,5, // SKINCOLOR_RED - SKINCOLOR_NONE,8, // SKINCOLOR_DARKRED - SKINCOLOR_NONE,8, // SKINCOLOR_NEONGREEN - SKINCOLOR_RED,11, // SKINCOLOR_GREEN - SKINCOLOR_PURPLE,3, // SKINCOLOR_ZIM - SKINCOLOR_NONE,8, // SKINCOLOR_OLIVE - SKINCOLOR_NONE,8, // SKINCOLOR_YELLOW - SKINCOLOR_NONE,8 // SKINCOLOR_GOLD + SKINCOLOR_NONE,8, // SKINCOLOR_NONE + SKINCOLOR_BLACK,10, // SKINCOLOR_WHITE + SKINCOLOR_GREY,4, // SKINCOLOR_SILVER + SKINCOLOR_SILVER,12, // SKINCOLOR_GREY + SKINCOLOR_WHITE,8, // SKINCOLOR_BLACK + SKINCOLOR_BEIGE,8, // SKINCOLOR_BEIGE - needs new offset + SKINCOLOR_BROWN,8, // SKINCOLOR_PEACH - ditto + SKINCOLOR_PEACH,8, // SKINCOLOR_BROWN - ditto + SKINCOLOR_GREEN,5, // SKINCOLOR_RED + SKINCOLOR_CYAN,8, // SKINCOLOR_CRIMSON - ditto + SKINCOLOR_BLUE,12, // SKINCOLOR_ORANGE + SKINCOLOR_TAN,8, // SKINCOLOR_RUST - ditto + SKINCOLOR_LAVENDER,8, // SKINCOLOR_GOLD - ditto + SKINCOLOR_TEAL,8, // SKINCOLOR_YELLOW - ditto + SKINCOLOR_RUST,8, // SKINCOLOR_TAN - ditto + SKINCOLOR_MAGENTA,3, // SKINCOLOR_MOSS + SKINCOLOR_PURPLE,8, // SKINCOLOR_PERIDOT - ditto + SKINCOLOR_RED,11, // SKINCOLOR_GREEN + SKINCOLOR_PASTEL,8, // SKINCOLOR_EMERALD - ditto + SKINCOLOR_ROSY,8, // SKINCOLOR_AQUA - ditto + SKINCOLOR_YELLOW,8, // SKINCOLOR_TEAL - ditto + SKINCOLOR_CRIMSON,8, // SKINCOLOR_CYAN - ditto + SKINCOLOR_ORANGE,9, // SKINCOLOR_BLUE + SKINCOLOR_PINK,8, // SKINCOLOR_AZURE - ditto + SKINCOLOR_EMERALD,8, // SKINCOLOR_PASTEL - ditto + SKINCOLOR_PERIDOT,8, // SKINCOLOR_PURPLE - ditto + SKINCOLOR_GOLD,8, // SKINCOLOR_LAVENDER - ditto + SKINCOLOR_MOSS,8, // SKINCOLOR_MAGENTA - ditto + SKINCOLOR_AZURE,8, // SKINCOLOR_PINK - ditto + SKINCOLOR_AQUA,8 // SKINCOLOR_ROSY - ditto }; CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1]; @@ -236,27 +250,31 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U 0x03, // SKINCOLOR_SILVER 0x08, // SKINCOLOR_GREY 0x18, // SKINCOLOR_BLACK - 0xd0, // SKINCOLOR_CYAN - 0xdc, // SKINCOLOR_TEAL - 0xc8, // SKINCOLOR_STEELBLUE - 0xe2, // SKINCOLOR_BLUE - 0x40, // SKINCOLOR_PEACH - 0x48, // SKINCOLOR_TAN - 0x90, // SKINCOLOR_PINK - 0xf8, // SKINCOLOR_LAVENDER - 0xc0, // SKINCOLOR_PURPLE - 0x52, // SKINCOLOR_ORANGE - 0x5c, // SKINCOLOR_ROSEWOOD - 0x20, // SKINCOLOR_BEIGE - 0x30, // SKINCOLOR_BROWN - 0x7d, // SKINCOLOR_RED - 0x85, // SKINCOLOR_DARKRED - 0xb8, // SKINCOLOR_NEONGREEN - 0xa0, // SKINCOLOR_GREEN - 0xb0, // SKINCOLOR_ZIM - 0x69, // SKINCOLOR_OLIVE - 0x67, // SKINCOLOR_YELLOW - 0x70, // SKINCOLOR_GOLD + 0xf0, // SKINCOLOR_BEIGE + 0xd8, // SKINCOLOR_PEACH + 0xe0, // SKINCOLOR_BROWN + 0x21, // SKINCOLOR_RED + 0x28, // SKINCOLOR_CRIMSON + 0x31, // SKINCOLOR_ORANGE + 0x3a, // SKINCOLOR_RUST + 0x40, // SKINCOLOR_GOLD + 0x48, // SKINCOLOR_YELLOW + 0x54, // SKINCOLOR_TAN + 0x58, // SKINCOLOR_MOSS + 0xbc, // SKINCOLOR_PERIDOT + 0x60, // SKINCOLOR_GREEN + 0x70, // SKINCOLOR_EMERALD + 0x78, // SKINCOLOR_AQUA + 0x8c, // SKINCOLOR_TEAL + 0x80, // SKINCOLOR_CYAN + 0x92, // SKINCOLOR_BLUE + 0xaa, // SKINCOLOR_AZURE + 0xa0, // SKINCOLOR_PASTEL + 0xa0, // SKINCOLOR_PURPLE + 0xc0, // SKINCOLOR_LAVENDER + 0xb3, // SKINCOLOR_MAGENTA + 0xd0, // SKINCOLOR_PINK + 0xc8, // SKINCOLOR_ROSY }; INT32 i; INT32 starttranscolor; @@ -274,7 +292,7 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U if (skinnum == TC_BOSS) dest_colormap[31] = 0; else if (skinnum == TC_METALSONIC) - dest_colormap[239] = 0; + dest_colormap[159] = 0; return; } @@ -293,196 +311,339 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U { case SKINCOLOR_SILVER: case SKINCOLOR_GREY: - case SKINCOLOR_PEACH: - case SKINCOLOR_BEIGE: case SKINCOLOR_BROWN: - case SKINCOLOR_RED: case SKINCOLOR_GREEN: - case SKINCOLOR_BLUE: // 16 color ramp for (i = 0; i < SKIN_RAMP_LENGTH; i++) dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i); break; - case SKINCOLOR_ORANGE: - // 14 colors of orange + brown - for (i = 0; i < SKIN_RAMP_LENGTH-2; i++) - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i); - for (i = 0; i < 2; i++) - dest_colormap[starttranscolor + (i+SKIN_RAMP_LENGTH-2)] = (UINT8)(152 + i); - break; - + case SKINCOLOR_WHITE: case SKINCOLOR_CYAN: // 12 color ramp for (i = 0; i < SKIN_RAMP_LENGTH; i++) dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (12*i/SKIN_RAMP_LENGTH)); break; - case SKINCOLOR_WHITE: case SKINCOLOR_BLACK: - case SKINCOLOR_STEELBLUE: - case SKINCOLOR_PINK: + case SKINCOLOR_MOSS: + case SKINCOLOR_EMERALD: case SKINCOLOR_LAVENDER: - case SKINCOLOR_PURPLE: - case SKINCOLOR_DARKRED: - case SKINCOLOR_ZIM: - case SKINCOLOR_YELLOW: - case SKINCOLOR_GOLD: + case SKINCOLOR_PINK: // 8 color ramp for (i = 0; i < SKIN_RAMP_LENGTH; i++) dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1)); break; - case SKINCOLOR_TEAL: - // 5 color ramp + case SKINCOLOR_BEIGE: + // 13 colors for (i = 0; i < SKIN_RAMP_LENGTH; i++) { - if (5*i/16 == 0) - dest_colormap[starttranscolor + i] = 0xf7; + if (i == 15) + dest_colormap[starttranscolor + i] = 0xed; // Darkest + else if (i <= 6) + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + ((i + 1) >> 1)); // Brightest else - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (5*i/SKIN_RAMP_LENGTH) - 1); + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i - 3); } break; - case SKINCOLOR_OLIVE: - // 7 color ramp + case SKINCOLOR_PEACH: + // 11 colors for (i = 0; i < SKIN_RAMP_LENGTH; i++) - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (7*i/SKIN_RAMP_LENGTH)); + { + if (i == 0) + dest_colormap[starttranscolor + i] = 0xD0; // Lightest 1 + else if (i == 1) + dest_colormap[starttranscolor + i] = 0x30; // Lightest 2 + else if (i <= 11) + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) - 1); + else + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i - 7); // Darkest + } + break; + + case SKINCOLOR_RED: + // 16 colors + for (i = 0; i < SKIN_RAMP_LENGTH; i++) + { + if (i == 13) + dest_colormap[starttranscolor + i] = 0x47; // Semidark + else if (i > 13) + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i - 1); // Darkest + else + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i); + } + break; + + case SKINCOLOR_CRIMSON: + // 9 colors + for (i = 0; i < SKIN_RAMP_LENGTH; i++) + { + if (i/2 == 6) + dest_colormap[starttranscolor + i] = 0x47; // Semidark + else if (i/2 == 7) + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i - 8); // Darkest + else + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1)); + } + break; + + case SKINCOLOR_ORANGE: + for (i = 0; i < SKIN_RAMP_LENGTH; i++) + { + if (i == 15) + dest_colormap[starttranscolor + i] = 0x2c; // Darkest + else + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i); + } + break; + + case SKINCOLOR_RUST: + // 10 colors + for (i = 0; i < SKIN_RAMP_LENGTH; i++) + { + if (i <= 11) + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1)); + else if (i == 12) + dest_colormap[starttranscolor + i] = 0x2c; // Darkest 4 + else if (i == 13) + dest_colormap[starttranscolor + i] = 0xfe; // Darkest 3 + else + dest_colormap[starttranscolor + i] = 0x2d + i - 14; // Darkest 2 and 1 + } + break; + + case SKINCOLOR_GOLD: + // 10 colors + for (i = 0; i < SKIN_RAMP_LENGTH; i++) + { + if (i == 0) + dest_colormap[starttranscolor + i] = 0x50; // Lightest 1 + else if (i == 1) + dest_colormap[starttranscolor + i] = 0x53; // Lightest 2 + else if (i/2 == 7) + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i - 8); //Darkest + else + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) - 1); + } + break; + + case SKINCOLOR_YELLOW: + // 10 colors + for (i = 0; i < SKIN_RAMP_LENGTH; i++) + { + if (i == 0) + dest_colormap[starttranscolor + i] = 0x53; // Lightest + else if (i == 15) + dest_colormap[starttranscolor + i] = 0xed; // Darkest + else + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1)); + } break; case SKINCOLOR_TAN: - // 16 color ramp, from two color ranges - for (i = 0; i < SKIN_RAMP_LENGTH/2; i++) // Peach half - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i); - for (i = 0; i < SKIN_RAMP_LENGTH/2; i++) // Brown half - dest_colormap[starttranscolor + (i+8)] = (UINT8)(48 + i); + // 8 colors + for (i = 0; i < SKIN_RAMP_LENGTH; i++) + { + if (i/2 == 0) + dest_colormap[starttranscolor + i] = 0x51; // Lightest + else if (i/2 == 5) + dest_colormap[starttranscolor + i] = 0xf5; // Darkest 1 + else if (i/2 == 6) + dest_colormap[starttranscolor + i] = 0xf9; // Darkest 2 + else if (i/2 == 7) + dest_colormap[starttranscolor + i] = 0xed; // Darkest 3 + else + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) - 1); + } break; - case SKINCOLOR_ROSEWOOD: - // 12 color ramp, from two color ranges! - for (i = 0; i < 6; i++) // Orange ...third? - dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (12*i/SKIN_RAMP_LENGTH)); - for (i = 0; i < 10; i++) // Rosewood two-thirds-ish - dest_colormap[starttranscolor + (i+6)] = (UINT8)(152 + (12*i/SKIN_RAMP_LENGTH)); + case SKINCOLOR_PERIDOT: + // 8 colors + for (i = 0; i < SKIN_RAMP_LENGTH; i++) + { + if (i/2 == 0) + dest_colormap[starttranscolor + i] = 0x58; // Lightest + else if (i/2 == 7) + dest_colormap[starttranscolor + i] = 0x77; // Darkest + else if (i/2 >= 5) + dest_colormap[starttranscolor + i] = (UINT8)(0x5e + (i >> 1) - 5); // Semidark + else + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) - 1); + } break; - case SKINCOLOR_NEONGREEN: - // Multi-color ramp - dest_colormap[starttranscolor] = 0xA0; // Brighter green - for (i = 0; i < SKIN_RAMP_LENGTH-1; i++) // Neon Green - dest_colormap[starttranscolor + (i+1)] = (UINT8)(skinbasecolors[color - 1] + (6*i/(SKIN_RAMP_LENGTH-1))); + case SKINCOLOR_AQUA: + // 10 colors + for (i = 0; i < SKIN_RAMP_LENGTH; i++) + { + if (i == 0) + dest_colormap[starttranscolor + i] = 0x78; // Lightest + else if (i >= 14) + dest_colormap[starttranscolor + i] = (UINT8)(0x76 + i - 14); // Darkest + else + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) + 1); + } + break; + + case SKINCOLOR_TEAL: + // 6 colors + for (i = 0; i < SKIN_RAMP_LENGTH; i++) + { + if (i <= 1) + dest_colormap[starttranscolor + i] = 0x78; // Lightest + else if (i >= 13) + dest_colormap[starttranscolor + i] = 0x8a; // Darkest + else + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + ((i - 1)/3)); + } + break; + + case SKINCOLOR_AZURE: + // 8 colors + for (i = 0; i < SKIN_RAMP_LENGTH; i++) + { + if (i <= 3) + dest_colormap[starttranscolor + i] = (UINT8)(0x90 + i/2); // Lightest + else + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) - 2); + } + break; + + case SKINCOLOR_BLUE: + // 16 colors + for (i = 0; i < SKIN_RAMP_LENGTH; i++) + { + if (i == 15) + dest_colormap[starttranscolor + i] = 0x1F; //Darkest 1 + else if (i == 14) + dest_colormap[starttranscolor + i] = 0xfd; //Darkest 2 + else + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i); + } + break; + + case SKINCOLOR_PASTEL: + // 10 colors + for (i = 0; i < SKIN_RAMP_LENGTH; i++) + { + if (i >= 12) + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i - 7); // Darkest + else if (i <= 1) + dest_colormap[starttranscolor + i] = 0x90; // Lightest + else + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) - 1); + } + break; + + case SKINCOLOR_PURPLE: + // 10 colors + for (i = 0; i < SKIN_RAMP_LENGTH; i++) + { + if (i <= 3) + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i); // Lightest + else + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) + 2); + } + break; + + case SKINCOLOR_MAGENTA: + // 9 colors + for (i = 0; i < SKIN_RAMP_LENGTH; i++) + if (i == 0) + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1]); // Lightest + else + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) + 1); + break; + + case SKINCOLOR_ROSY: + // 9 colors + for (i = 0; i < SKIN_RAMP_LENGTH; i++) + { + if (i == 0) + dest_colormap[starttranscolor + i] = 0xfc; // Lightest + else + dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + ((i - 1) >> 1)); + } break; // Super colors, from lightest to darkest! case SKINCOLOR_SUPER1: // Super White for (i = 0; i < 10; i++) - dest_colormap[starttranscolor + i] = 120; // True white - for (; i < SKIN_RAMP_LENGTH; i++) // White-yellow fade - dest_colormap[starttranscolor + i] = (UINT8)(96 + (i-10)); + dest_colormap[starttranscolor + i] = (UINT8)0; // True white + for (; i < 12; i++) // White-yellow fade + dest_colormap[starttranscolor + i] = (UINT8)(80); + for (; i < 15; i++) // White-yellow fade + dest_colormap[starttranscolor + i] = (UINT8)(81 + (i-12)); + dest_colormap[starttranscolor + 15] = (UINT8)(72); break; case SKINCOLOR_SUPER2: // Super Bright - for (i = 0; i < 5; i++) // White-yellow fade - dest_colormap[starttranscolor + i] = (UINT8)(96 + i); - dest_colormap[starttranscolor + 5] = 112; // Golden shine - for (i = 0; i < 8; i++) // Yellow - dest_colormap[starttranscolor + (i+6)] = (UINT8)(101 + (i>>1)); - for (i = 0; i < 2; i++) // With a fine golden finish! :3 - dest_colormap[starttranscolor + (i+14)] = (UINT8)(113 + i); + dest_colormap[starttranscolor] = (UINT8)(0); + for (i = 1; i < 4; i++) // White-yellow fade + dest_colormap[starttranscolor + i] = (UINT8)(80 + (i-1)); + for (; i < 6; i++) // Yellow + dest_colormap[starttranscolor + i] = (UINT8)(83); + for (; i < 8; i++) // Yellow + dest_colormap[starttranscolor + i] = (UINT8)(72); + for (; i < 14; i++) // Yellow + dest_colormap[starttranscolor + i] = (UINT8)(73); + for (; i < 16; i++) // With a fine golden finish! :3 + dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-14)); break; case SKINCOLOR_SUPER3: // Super Yellow - for (i = 0; i < 3; i++) // White-yellow fade - dest_colormap[starttranscolor + i] = (UINT8)(98 + i); - dest_colormap[starttranscolor + 3] = 112; // Golden shine - for (i = 0; i < 8; i++) // Yellow - dest_colormap[starttranscolor + (i+4)] = (UINT8)(101 + (i>>1)); - for (i = 0; i < 4; i++) // With a fine golden finish! :3 - dest_colormap[starttranscolor + (i+12)] = (UINT8)(113 + i); + for (i = 0; i < 2; i++) // White-yellow fade + dest_colormap[starttranscolor + i] = (UINT8)(81 + i); + for (; i < 4; i++) + dest_colormap[starttranscolor + i] = (UINT8)(83); + for (; i < 6; i++) // Yellow + dest_colormap[starttranscolor + i] = (UINT8)(72); + for (; i < 12; i++) // Yellow + dest_colormap[starttranscolor + i] = (UINT8)(73); + for (; i < 16; i++) // With a fine golden finish! :3 + dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-12)); break; case SKINCOLOR_SUPER4: // "The SSNTails" - dest_colormap[starttranscolor] = 112; // Golden shine - for (i = 0; i < 8; i++) // Yellow - dest_colormap[starttranscolor + (i+1)] = (UINT8)(101 + (i>>1)); - for (i = 0; i < 7; i++) // With a fine golden finish! :3 - dest_colormap[starttranscolor + (i+9)] = (UINT8)(113 + i); + dest_colormap[starttranscolor] = 83; // Golden shine + for (i = 1; i < 3; i++) // Yellow + dest_colormap[starttranscolor + i] = (UINT8)(72); + for (; i < 9; i++) // Yellow + dest_colormap[starttranscolor + i] = (UINT8)(73); + for (; i < 16; i++) // With a fine golden finish! :3 + dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-9)); break; case SKINCOLOR_SUPER5: // Golden Delicious - for (i = 0; i < 8; i++) // Yellow - dest_colormap[starttranscolor + i] = (UINT8)(101 + (i>>1)); - for (i = 0; i < 7; i++) // With a fine golden finish! :3 - dest_colormap[starttranscolor + (i+8)] = (UINT8)(113 + i); - dest_colormap[starttranscolor + 15] = 155; + for (i = 0; i < 2; i++) // Yellow + dest_colormap[starttranscolor + i] = (UINT8)(72); + for (; i < 8; i++) // Yellow + dest_colormap[starttranscolor + i] = (UINT8)(73); + for (; i < 15; i++) // With a fine golden finish! :3 + dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-8)); + dest_colormap[starttranscolor + 15] = (UINT8)63; break; - // Super Tails + // Super Tails and Knuckles, who really should be dummied out by now case SKINCOLOR_TSUPER1: - for (i = 0; i < 10; i++) // white - dest_colormap[starttranscolor + i] = 120; - for (; i < SKIN_RAMP_LENGTH; i++) // orange - dest_colormap[starttranscolor + i] = (UINT8)(80 + (i-10)); - break; - case SKINCOLOR_TSUPER2: - for (i = 0; i < 4; i++) // white - dest_colormap[starttranscolor + i] = 120; - for (; i < SKIN_RAMP_LENGTH; i++) // orange - dest_colormap[starttranscolor + i] = (UINT8)(80 + ((i-4)>>1)); - break; - case SKINCOLOR_TSUPER3: - dest_colormap[starttranscolor] = 120; // pure white - dest_colormap[starttranscolor+1] = 120; - for (i = 2; i < SKIN_RAMP_LENGTH; i++) // orange - dest_colormap[starttranscolor + i] = (UINT8)(80 + ((i-2)>>1)); - break; - case SKINCOLOR_TSUPER4: - dest_colormap[starttranscolor] = 120; // pure white - for (i = 1; i < 9; i++) // orange - dest_colormap[starttranscolor + i] = (UINT8)(80 + (i-1)); - for (; i < SKIN_RAMP_LENGTH; i++) // gold - dest_colormap[starttranscolor + i] = (UINT8)(115 + (5*(i-9)/7)); - break; - case SKINCOLOR_TSUPER5: - for (i = 0; i < 8; i++) // orange - dest_colormap[starttranscolor + i] = (UINT8)(80 + i); - for (; i < SKIN_RAMP_LENGTH; i++) // gold - dest_colormap[starttranscolor + i] = (UINT8)(115 + (5*(i-8)/8)); - break; - - // Super Knuckles case SKINCOLOR_KSUPER1: - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - dest_colormap[starttranscolor + i] = (UINT8)(120 + (i >> 2)); - break; - case SKINCOLOR_KSUPER2: - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - dest_colormap[starttranscolor + i] = (UINT8)(120 + (6*i/SKIN_RAMP_LENGTH)); - break; - case SKINCOLOR_KSUPER3: - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - dest_colormap[starttranscolor + i] = (UINT8)(120 + (i >> 1)); - break; - case SKINCOLOR_KSUPER4: - for (i = 0; i < SKIN_RAMP_LENGTH; i++) - dest_colormap[starttranscolor + i] = (UINT8)(121 + (i >> 1)); - break; - case SKINCOLOR_KSUPER5: for (i = 0; i < SKIN_RAMP_LENGTH; i++) - dest_colormap[starttranscolor + i] = (UINT8)(122 + (i >> 1)); + dest_colormap[starttranscolor + i] = 0xFF; break; default: diff --git a/src/r_draw.h b/src/r_draw.h index 061a271b1..0ece26487 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -60,6 +60,16 @@ extern fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep; extern UINT8 *ds_source; // start of a 64*64 tile image extern UINT8 *ds_transmap; +#ifdef ESLOPE +typedef struct { + float x, y, z; +} floatv3_t; + +extern pslope_t *ds_slope; // Current slope being used +extern floatv3_t ds_su, ds_sv, ds_sz; // Vectors for... stuff? +extern float focallengthf, zeroheight; +#endif + // Variable flat sizes extern UINT32 nflatxshift; extern UINT32 nflatyshift; @@ -141,6 +151,12 @@ void ASMCALL R_DrawSpan_8_MMX(void); void R_DrawTranslatedColumn_8(void); void R_DrawTranslatedTranslucentColumn_8(void); void R_DrawSpan_8(void); +#ifdef ESLOPE +void R_CalcTiltedLighting(fixed_t start, fixed_t end); +void R_DrawTiltedSpan_8(void); +void R_DrawTiltedTranslucentSpan_8(void); +void R_DrawTiltedSplat_8(void); +#endif void R_DrawSplat_8(void); void R_DrawTranslucentSplat_8(void); void R_DrawTranslucentSpan_8(void); diff --git a/src/r_draw8.c b/src/r_draw8.c index e0264ba92..c42f5d869 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -105,7 +105,7 @@ void R_DrawColumn_8(void) } } -#define TRANSPARENTPIXEL 247 +#define TRANSPARENTPIXEL 255 void R_Draw2sMultiPatchColumn_8(void) { @@ -526,6 +526,447 @@ void R_DrawSpan_8 (void) } } +#ifdef ESLOPE +// R_CalcTiltedLighting +// Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly. +static INT32 tiltlighting[MAXVIDWIDTH]; +void R_CalcTiltedLighting(fixed_t start, fixed_t end) +{ + // ZDoom uses a different lighting setup to us, and I couldn't figure out how to adapt their version + // of this function. Here's my own. + INT32 left = ds_x1, right = ds_x2; + fixed_t step = (end-start)/(ds_x2-ds_x1+1); + INT32 i; + + // I wanna do some optimizing by checking for out-of-range segments on either side to fill in all at once, + // but I'm too bad at coding to not crash the game trying to do that. I guess this is fast enough for now... + + for (i = left; i <= right; i++) { + tiltlighting[i] = (start += step) >> FRACBITS; + if (tiltlighting[i] < 0) + tiltlighting[i] = 0; + else if (tiltlighting[i] >= MAXLIGHTSCALE) + tiltlighting[i] = MAXLIGHTSCALE-1; + } +} + + +/** \brief The R_DrawTiltedSpan_8 function + Draw slopes! Holy sheit! +*/ +void R_DrawTiltedSpan_8(void) +{ + // x1, x2 = ds_x1, ds_x2 + int width = ds_x2 - ds_x1; + double iz, uz, vz; + UINT32 u, v; + int i; + + UINT8 *source; + UINT8 *colormap; + UINT8 *dest; + + double startz, startu, startv; + double izstep, uzstep, vzstep; + double endz, endu, endv; + UINT32 stepu, stepv; + + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + + // Lighting is simple. It's just linear interpolation from start to end + { + float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f; + float lightstart, lightend; + + lightend = (iz + ds_sz.x*width) * planelightfloat; + lightstart = iz * planelightfloat; + + R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); + //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); + } + + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); + + dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds_source; + //colormap = ds_colormap; + +#if 0 // The "perfect" reference version of this routine. Pretty slow. + // Use it only to see how things are supposed to look. + i = 0; + do + { + 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)]]; + dest++; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; + } while (--width >= 0); +#else +#define SPANSIZE 16 +#define INVSPAN 0.0625f + + startz = 1.f/iz; + startu = uz*startz; + startv = vz*startz; + + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; + //x1 = 0; + width++; + + while (width >= SPANSIZE) + { + iz += izstep; + uz += uzstep; + vz += vzstep; + + endz = 1.f/iz; + endu = uz*endz; + endv = vz*endz; + stepu = (INT64)((endu - startu) * INVSPAN); + stepv = (INT64)((endv - startv) * INVSPAN); + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; + + for (i = SPANSIZE-1; i >= 0; i--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + dest++; + u += stepu; + v += stepv; + } + startu = endu; + startv = endv; + width -= SPANSIZE; + } + if (width > 0) + { + if (width == 1) + { + u = (INT64)(startu); + v = (INT64)(startv); + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + } + else + { + double left = width; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; + + endz = 1.f/iz; + endu = uz*endz; + endv = vz*endz; + left = 1.f/left; + stepu = (INT64)((endu - startu) * left); + stepv = (INT64)((endv - startv) * left); + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; + + for (; width != 0; width--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + dest++; + u += stepu; + v += stepv; + } + } + } +#endif +} + +/** \brief The R_DrawTiltedTranslucentSpan_8 function + Like DrawTiltedSpan, but translucent +*/ +void R_DrawTiltedTranslucentSpan_8(void) +{ + // x1, x2 = ds_x1, ds_x2 + int width = ds_x2 - ds_x1; + double iz, uz, vz; + UINT32 u, v; + int i; + + UINT8 *source; + UINT8 *colormap; + UINT8 *dest; + + double startz, startu, startv; + double izstep, uzstep, vzstep; + double endz, endu, endv; + UINT32 stepu, stepv; + + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + + // Lighting is simple. It's just linear interpolation from start to end + { + float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f; + float lightstart, lightend; + + lightend = (iz + ds_sz.x*width) * planelightfloat; + lightstart = iz * planelightfloat; + + R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); + //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); + } + + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); + + dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds_source; + //colormap = ds_colormap; + +#if 0 // The "perfect" reference version of this routine. Pretty slow. + // Use it only to see how things are supposed to look. + i = 0; + do + { + 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[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])]; + dest++; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; + } while (--width >= 0); +#else +#define SPANSIZE 16 +#define INVSPAN 0.0625f + + startz = 1.f/iz; + startu = uz*startz; + startv = vz*startz; + + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; + //x1 = 0; + width++; + + while (width >= SPANSIZE) + { + iz += izstep; + uz += uzstep; + vz += vzstep; + + endz = 1.f/iz; + endu = uz*endz; + endv = vz*endz; + stepu = (INT64)((endu - startu) * INVSPAN); + stepv = (INT64)((endv - startv) * INVSPAN); + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; + + for (i = SPANSIZE-1; i >= 0; i--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])]; + dest++; + u += stepu; + v += stepv; + } + startu = endu; + startv = endv; + width -= SPANSIZE; + } + if (width > 0) + { + if (width == 1) + { + u = (INT64)(startu); + v = (INT64)(startv); + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])]; + } + else + { + double left = width; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; + + endz = 1.f/iz; + endu = uz*endz; + endv = vz*endz; + left = 1.f/left; + stepu = (INT64)((endu - startu) * left); + stepv = (INT64)((endv - startv) * left); + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; + + for (; width != 0; width--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + *dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])]; + dest++; + u += stepu; + v += stepv; + } + } + } +#endif +} + +void R_DrawTiltedSplat_8(void) +{ + // x1, x2 = ds_x1, ds_x2 + int width = ds_x2 - ds_x1; + double iz, uz, vz; + UINT32 u, v; + int i; + + UINT8 *source; + UINT8 *colormap; + UINT8 *dest; + + UINT8 val; + + double startz, startu, startv; + double izstep, uzstep, vzstep; + double endz, endu, endv; + UINT32 stepu, stepv; + + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + + // Lighting is simple. It's just linear interpolation from start to end + { + float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f; + float lightstart, lightend; + + lightend = (iz + ds_sz.x*width) * planelightfloat; + lightstart = iz * planelightfloat; + + R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); + //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); + } + + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); + + dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds_source; + //colormap = ds_colormap; + +#if 0 // The "perfect" reference version of this routine. Pretty slow. + // Use it only to see how things are supposed to look. + i = 0; + do + { + double z = 1.f/iz; + u = (INT64)(uz*z) + viewx; + v = (INT64)(vz*z) + viewy; + + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + + val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + if (val != TRANSPARENTPIXEL) + *dest = val; + dest++; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; + } while (--width >= 0); +#else +#define SPANSIZE 16 +#define INVSPAN 0.0625f + + startz = 1.f/iz; + startu = uz*startz; + startv = vz*startz; + + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; + //x1 = 0; + width++; + + while (width >= SPANSIZE) + { + iz += izstep; + uz += uzstep; + vz += vzstep; + + endz = 1.f/iz; + endu = uz*endz; + endv = vz*endz; + stepu = (INT64)((endu - startu) * INVSPAN); + stepv = (INT64)((endv - startv) * INVSPAN); + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; + + for (i = SPANSIZE-1; i >= 0; i--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + if (val != TRANSPARENTPIXEL) + *dest = val; + dest++; + u += stepu; + v += stepv; + } + startu = endu; + startv = endv; + width -= SPANSIZE; + } + if (width > 0) + { + if (width == 1) + { + u = (INT64)(startu); + v = (INT64)(startv); + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + if (val != TRANSPARENTPIXEL) + *dest = val; + } + else + { + double left = width; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; + + endz = 1.f/iz; + endu = uz*endz; + endv = vz*endz; + left = 1.f/left; + stepu = (INT64)((endu - startu) * left); + stepv = (INT64)((endv - startv) * left); + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; + + for (; width != 0; width--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + if (val != TRANSPARENTPIXEL) + *dest = val; + dest++; + u += stepu; + v += stepv; + } + } + } +#endif +} +#endif // ESLOPE + /** \brief The R_DrawSplat_8 function Just like R_DrawSpan_8, but skips transparent pixels. */ diff --git a/src/r_main.c b/src/r_main.c index 1edcb815b..71b225e83 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -114,15 +114,6 @@ INT32 viewangletox[FINEANGLES/2]; // from clipangle to -clipangle. angle_t xtoviewangle[MAXVIDWIDTH+1]; -// UNUSED. -// The finetangentgent[angle+FINEANGLES/4] table -// holds the fixed_t tangent values for view angles, -// ranging from INT32_MIN to 0 to INT32_MAX. - -#if !(defined _NDS) || !(defined NONET) -fixed_t *finecosine = &finesine[FINEANGLES/4]; -#endif - lighttable_t *scalelight[LIGHTLEVELS][MAXLIGHTSCALE]; lighttable_t *scalelightfixed[MAXLIGHTSCALE]; lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ]; @@ -316,13 +307,13 @@ angle_t R_PointToAngle(fixed_t x, fixed_t y) x >= 0 ? y >= 0 ? (x > y) ? tantoangle[SlopeDiv(y,x)] : // octant 0 - ANGLE_90-1-tantoangle[SlopeDiv(x,y)] : // octant 1 + ANGLE_90-tantoangle[SlopeDiv(x,y)] : // octant 1 x > (y = -y) ? 0-tantoangle[SlopeDiv(y,x)] : // octant 8 ANGLE_270+tantoangle[SlopeDiv(x,y)] : // octant 7 - y >= 0 ? (x = -x) > y ? ANGLE_180-1-tantoangle[SlopeDiv(y,x)] :// octant 3 + y >= 0 ? (x = -x) > y ? ANGLE_180-tantoangle[SlopeDiv(y,x)] : // octant 3 ANGLE_90 + tantoangle[SlopeDiv(x,y)] : // octant 2 - (x = -x) > (y = -y) ? ANGLE_180+tantoangle[ SlopeDiv(y,x)] : // octant 4 - ANGLE_270-1-tantoangle[SlopeDiv(x,y)] : // octant 5 + (x = -x) > (y = -y) ? ANGLE_180+tantoangle[SlopeDiv(y,x)] : // octant 4 + ANGLE_270-tantoangle[SlopeDiv(x,y)] : // octant 5 0; } @@ -332,13 +323,13 @@ angle_t R_PointToAngle2(fixed_t pviewx, fixed_t pviewy, fixed_t x, fixed_t y) x >= 0 ? y >= 0 ? (x > y) ? tantoangle[SlopeDiv(y,x)] : // octant 0 - ANGLE_90-1-tantoangle[SlopeDiv(x,y)] : // octant 1 + ANGLE_90-tantoangle[SlopeDiv(x,y)] : // octant 1 x > (y = -y) ? 0-tantoangle[SlopeDiv(y,x)] : // octant 8 ANGLE_270+tantoangle[SlopeDiv(x,y)] : // octant 7 - y >= 0 ? (x = -x) > y ? ANGLE_180-1-tantoangle[SlopeDiv(y,x)] :// octant 3 + y >= 0 ? (x = -x) > y ? ANGLE_180-tantoangle[SlopeDiv(y,x)] : // octant 3 ANGLE_90 + tantoangle[SlopeDiv(x,y)] : // octant 2 - (x = -x) > (y = -y) ? ANGLE_180+tantoangle[ SlopeDiv(y,x)] : // octant 4 - ANGLE_270-1-tantoangle[SlopeDiv(x,y)] : // octant 5 + (x = -x) > (y = -y) ? ANGLE_180+tantoangle[SlopeDiv(y,x)] : // octant 4 + ANGLE_270-tantoangle[SlopeDiv(x,y)] : // octant 5 0; } @@ -527,6 +518,8 @@ static void R_InitTextureMapping(void) focallength = FixedDiv(centerxfrac, FINETANGENT(FINEANGLES/4+/*cv_fov.value*/ FIELDOFVIEW/2)); + focallengthf = FIXED_TO_FLOAT(focallength); + for (i = 0; i < FINEANGLES/2; i++) { if (FINETANGENT(i) > FRACUNIT*2) @@ -1276,7 +1269,7 @@ void R_RenderPlayerView(player_t *player) if (cv_homremoval.value == 1) V_DrawFill(0, 0, vid.width, vid.height, 31); // No HOM effect! else //'development' HOM removal -- makes it blindingly obvious if HOM is spotted. - V_DrawFill(0, 0, vid.width, vid.height, 128+(timeinmap&15)); + V_DrawFill(0, 0, vid.width, vid.height, 32+(timeinmap&15)); } portalrender = 0; diff --git a/src/r_plane.c b/src/r_plane.c index dcff25c13..417f0360a 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -28,6 +28,8 @@ #include "p_setup.h" // levelflats +#include "p_slopes.h" + // // opening // @@ -74,7 +76,7 @@ static INT32 spanstart[MAXVIDHEIGHT]; // // texture mapping // -static lighttable_t **planezlight; +lighttable_t **planezlight; static fixed_t planeheight; //added : 10-02-98: yslopetab is what yslope used to be, @@ -327,6 +329,11 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2) if (pindex >= MAXLIGHTZ) pindex = MAXLIGHTZ - 1; +#ifdef ESLOPE + if (currentplane->slope) + ds_colormap = colormaps; + else +#endif ds_colormap = planezlight[pindex]; if (currentplane->extra_colormap) @@ -423,11 +430,18 @@ static visplane_t *new_visplane(unsigned hash) // visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap, - ffloor_t *pfloor) + ffloor_t *pfloor +#ifdef ESLOPE + , pslope_t *slope +#endif + ) { visplane_t *check; unsigned hash; +#ifdef ESLOPE + if (slope); else // Don't mess with this right now if a slope is involved +#endif if (plangle != 0) { // Add the view offset, rotated by the plane angle. @@ -462,7 +476,11 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, && xoff == check->xoffs && yoff == check->yoffs && planecolormap == check->extra_colormap && !pfloor && !check->ffloor && check->viewz == viewz - && check->viewangle == viewangle) + && check->viewangle == viewangle +#ifdef ESLOPE + && check->slope == slope +#endif + ) { return check; } @@ -485,6 +503,9 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, #ifdef POLYOBJECTS_PLANES check->polyobj = NULL; #endif +#ifdef ESLOPE + check->slope = slope; +#endif memset(check->top, 0xff, sizeof (check->top)); memset(check->bottom, 0x00, sizeof (check->bottom)); @@ -551,6 +572,9 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop) new_pl->plangle = pl->plangle; #ifdef POLYOBJECTS_PLANES new_pl->polyobj = pl->polyobj; +#endif +#ifdef ESLOPE + new_pl->slope = pl->slope; #endif pl = new_pl; pl->minx = start; @@ -726,31 +750,15 @@ void R_DrawSinglePlane(visplane_t *pl) // Hacked up support for alpha value in software mode Tails 09-24-2002 (sidenote: ported to polys 10-15-2014, there was no time travel involved -Red) if (pl->polyobj->translucency >= 10) return; // Don't even draw it - else if (pl->polyobj->translucency == 9) - ds_transmap = ((tr_trans90)<polyobj->translucency == 8) - ds_transmap = ((tr_trans80)<polyobj->translucency == 7) - ds_transmap = ((tr_trans70)<polyobj->translucency == 6) - ds_transmap = ((tr_trans60)<polyobj->translucency == 5) - ds_transmap = ((tr_trans50)<polyobj->translucency == 4) - ds_transmap = ((tr_trans40)<polyobj->translucency == 3) - ds_transmap = ((tr_trans30)<polyobj->translucency == 2) - ds_transmap = ((tr_trans20)<polyobj->translucency == 1) - ds_transmap = ((tr_trans10)<polyobj->translucency > 0) + ds_transmap = transtables + ((pl->polyobj->translucency-1)<extra_colormap && pl->extra_colormap->fog) light = (pl->lightlevel >> LIGHTSEGSHIFT); else - light = LIGHTLEVELS-1; + light = LIGHTLEVELS-1; } else #endif @@ -781,23 +789,23 @@ void R_DrawSinglePlane(visplane_t *pl) if (pl->ffloor->alpha < 12) return; // Don't even draw it else if (pl->ffloor->alpha < 38) - ds_transmap = ((tr_trans90)<ffloor->alpha < 64) - ds_transmap = ((tr_trans80)<ffloor->alpha < 89) - ds_transmap = ((tr_trans70)<ffloor->alpha < 115) - ds_transmap = ((tr_trans60)<ffloor->alpha < 140) - ds_transmap = ((tr_trans50)<ffloor->alpha < 166) - ds_transmap = ((tr_trans40)<ffloor->alpha < 192) - ds_transmap = ((tr_trans30)<ffloor->alpha < 217) - ds_transmap = ((tr_trans20)<ffloor->alpha < 243) - ds_transmap = ((tr_trans10)<lightlevel >> LIGHTSEGSHIFT); #ifndef NOWATER - if (pl->ffloor->flags & FF_RIPPLE) + if (pl->ffloor->flags & FF_RIPPLE +#ifdef ESLOPE + && !pl->slope +#endif + ) { INT32 top, bottom; @@ -842,6 +854,9 @@ void R_DrawSinglePlane(visplane_t *pl) } else light = (pl->lightlevel >> LIGHTSEGSHIFT); +#ifdef ESLOPE + if (!pl->slope) // Don't mess with angle on slopes! We'll handle this ourselves later +#endif if (viewangle != pl->viewangle) { memset(cachedheight, 0, sizeof (cachedheight)); @@ -915,6 +930,106 @@ void R_DrawSinglePlane(visplane_t *pl) if (light < 0) light = 0; +#ifdef ESLOPE + if (pl->slope) { + // Potentially override other stuff for now cus we're mean. :< But draw a slope plane! + // I copied ZDoom's code and adapted it to SRB2... -Red + floatv3_t p, m, n; + float ang; + float vx, vy, vz; + float fudge; + // compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly + // use this as a temp var to store P_GetZAt's return value each time + fixed_t temp; + + xoffs &= ((1 << (32-nflatshiftup))-1); + yoffs &= ((1 << (32-nflatshiftup))-1); + + xoffs -= (pl->slope->o.x + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1); + yoffs += (pl->slope->o.y + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1); + + // Okay, look, don't ask me why this works, but without this setup there's a disgusting-looking misalignment with the textures. -Red + fudge = ((1<slope, viewx, viewy); + zeroheight = FIXED_TO_FLOAT(temp); + +#define ANG2RAD(angle) ((float)((angle)*M_PI)/ANGLE_180) + + // p is the texture origin in view space + // Don't add in the offsets at this stage, because doing so can result in + // errors if the flat is rotated. + ang = ANG2RAD(ANGLE_270 - viewangle); + p.x = vx * cos(ang) - vy * sin(ang); + p.z = vx * sin(ang) + vy * cos(ang); + temp = P_GetZAt(pl->slope, -xoffs, yoffs); + p.y = FIXED_TO_FLOAT(temp) - vz; + + // m is the v direction vector in view space + ang = ANG2RAD(ANGLE_180 - viewangle - pl->plangle); + m.x = cos(ang); + m.z = sin(ang); + + // n is the u direction vector in view space + n.x = sin(ang); + n.z = -cos(ang); + + ang = ANG2RAD(pl->plangle); + temp = P_GetZAt(pl->slope, viewx + FLOAT_TO_FIXED(sin(ang)), viewy + FLOAT_TO_FIXED(cos(ang))); + m.y = FIXED_TO_FLOAT(temp) - zeroheight; + temp = P_GetZAt(pl->slope, viewx + FLOAT_TO_FIXED(cos(ang)), viewy - FLOAT_TO_FIXED(sin(ang))); + n.y = FIXED_TO_FLOAT(temp) - zeroheight; + + m.x /= fudge; + m.y /= fudge; + m.z /= fudge; + + n.x *= fudge; + n.y *= fudge; + n.z *= fudge; + + // Eh. I tried making this stuff fixed-point and it exploded on me. Here's a macro for the only floating-point vector function I recall using. +#define CROSS(d, v1, v2) \ + d.x = (v1.y * v2.z) - (v1.z * v2.y);\ + d.y = (v1.z * v2.x) - (v1.x * v2.z);\ + d.z = (v1.x * v2.y) - (v1.y * v2.x) + CROSS(ds_su, p, m); + CROSS(ds_sv, p, n); + CROSS(ds_sz, m, n); +#undef CROSS + + ds_su.z *= focallengthf; + ds_sv.z *= focallengthf; + ds_sz.z *= focallengthf; + + // Premultiply the texture vectors with the scale factors +#define SFMULT 65536.f*(1<special) { case 900: - dc_transmap = ((tr_trans10)<special-900)<polyseg->translucency >= NUMTRANSMAPS) return; - dc_transmap = ((curline->polyseg->translucency)<polyseg->translucency-1)<scale1 + (x1 - ds->x1)*rw_scalestep; } + +#ifndef ESLOPE if (curline->linedef->flags & ML_DONTPEGBOTTOM) { dc_texturemid = front->floorheight > back->floorheight @@ -492,12 +479,21 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) dc_texturemid += (textureheight[texnum])*times; else dc_texturemid -= (textureheight[texnum])*times; +#endif dc_texheight = textureheight[texnum]>>FRACBITS; // draw the columns for (dc_x = x1; dc_x <= x2; dc_x++) { +#ifdef ESLOPE + dc_texturemid = ds->maskedtextureheight[dc_x]; + + if (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3)) + dc_texturemid += (textureheight[texnum])*times + textureheight[texnum]; + else + dc_texturemid -= (textureheight[texnum])*times; +#endif // calculate lighting if (maskedtexturecol[dc_x] != INT16_MAX) { @@ -679,6 +675,10 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) r_lightlist_t *rlight; fixed_t lheight; line_t *newline = NULL; +#ifdef ESLOPE + // Render FOF sides kinda like normal sides, with the frac and step and everything + fixed_t top_frac, top_step, bottom_frac, bottom_step; +#endif void (*colfunc_2s) (column_t *); @@ -709,23 +709,23 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (pfloor->alpha < 12) return; // Don't even draw it else if (pfloor->alpha < 38) - dc_transmap = ((tr_trans90)<alpha < 64) - dc_transmap = ((tr_trans80)<alpha < 89) - dc_transmap = ((tr_trans70)<alpha < 115) - dc_transmap = ((tr_trans60)<alpha < 140) - dc_transmap = ((tr_trans50)<alpha < 166) - dc_transmap = ((tr_trans40)<alpha < 192) - dc_transmap = ((tr_trans30)<alpha < 217) - dc_transmap = ((tr_trans20)<alpha < 243) - dc_transmap = ((tr_trans10)<height; } +#ifdef ESLOPE + // Set heights according to plane, or slope, whichever + { + fixed_t left_top, right_top, left_bottom, right_bottom; + + left_top = *pfloor->t_slope ? P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) : *pfloor->topheight; + right_top = *pfloor->t_slope ? P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) : *pfloor->topheight; + left_bottom = *pfloor->b_slope ? P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) : *pfloor->bottomheight; + right_bottom = *pfloor->b_slope ? P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) : *pfloor->bottomheight; + + left_top -= viewz; + right_top -= viewz; + left_bottom -= viewz; + right_bottom -= viewz; + + top_frac = centeryfrac - FixedMul(left_top, ds->scale1); + bottom_frac = centeryfrac - FixedMul(left_bottom, ds->scale1); + top_step = centeryfrac - FixedMul(right_top, ds->scale2); + bottom_step = centeryfrac - FixedMul(right_bottom, ds->scale2); + + top_step = (top_step-top_frac)/(ds->x2-ds->x1+1); + bottom_step = (bottom_step-bottom_frac)/(ds->x2-ds->x1+1); + + top_frac += top_step * (x1 - ds->x1); + bottom_frac += bottom_step * (x1 - ds->x1); + } +#endif + // draw the columns for (dc_x = x1; dc_x <= x2; dc_x++) { @@ -868,8 +896,16 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) INT32 solid = 0; INT32 lighteffect = 0; +#ifdef ESLOPE + sprtopscreen = windowtop = top_frac; + sprbotscreen = windowbottom = bottom_frac; + + top_frac += top_step; + bottom_frac += bottom_step; +#else sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale)); sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen; +#endif // SoM: If column is out of range, why bother with it?? if (windowbottom < topbounds || windowtop > bottombounds) @@ -1011,11 +1047,24 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) || ((signed)dc_texturemid < 0 && (spryscale) && (signed)(dc_texturemid)>>FRACBITS < (INT32_MIN / spryscale))) { spryscale += rw_scalestep; +#ifdef ESLOPE + top_frac += top_step; + bottom_frac += bottom_step; +#endif continue; } +#ifdef ESLOPE + sprtopscreen = windowtop = top_frac; + sprbotscreen = windowbottom = bottom_frac; + + top_frac += top_step; + bottom_frac += bottom_step; +#else sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale)); sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen; +#endif + dc_iscale = 0xffffffffu / (unsigned)spryscale; // draw the texture @@ -1061,6 +1110,7 @@ static void R_RenderSegLoop (void) INT32 mid; fixed_t texturecolumn = 0; + fixed_t oldtexturecolumn = -1; INT32 top; INT32 bottom; INT32 i; @@ -1197,6 +1247,17 @@ static void R_RenderSegLoop (void) // calculate texture offset angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT; texturecolumn = rw_offset-FixedMul(FINETANGENT(angle),rw_distance); + +#ifdef ESLOPE + if (oldtexturecolumn != -1) { + rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn-texturecolumn); + rw_midtexturemid += FixedMul(rw_midtextureslide, oldtexturecolumn-texturecolumn); + rw_toptexturemid += FixedMul(rw_toptextureslide, oldtexturecolumn-texturecolumn); + rw_midtextureback += FixedMul(rw_midtexturebackslide, oldtexturecolumn-texturecolumn); + } + oldtexturecolumn = texturecolumn; +#endif + texturecolumn >>= FRACBITS; // texturecolumn and lighting are independent of wall tiers @@ -1345,6 +1406,14 @@ static void R_RenderSegLoop (void) // save texturecol // for backdrawing of masked mid texture maskedtexturecol[rw_x] = (INT16)texturecolumn; + +#ifdef ESLOPE + if (maskedtextureheight != NULL) { + maskedtextureheight[rw_x] = (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3) ? + max(rw_midtexturemid, rw_midtextureback) : + min(rw_midtexturemid, rw_midtextureback)); + } +#endif } if (dc_numlights) @@ -1397,23 +1466,31 @@ void R_StoreWallRange(INT32 start, INT32 stop) fixed_t hyp; fixed_t sineval; angle_t distangle, offsetangle; - fixed_t vtop; + //fixed_t vtop; INT32 lightnum; INT32 i, p; lightlist_t *light; r_lightlist_t *rlight; +#ifdef ESLOPE + vertex_t segleft, segright; + fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide; +#endif static size_t maxdrawsegs = 0; + maskedtextureheight = NULL; + + //initialize segleft and segright + memset(&segleft, 0x00, sizeof(segleft)); + memset(&segright, 0x00, sizeof(segright)); + if (ds_p == drawsegs+maxdrawsegs) { size_t pos = ds_p - drawsegs; - size_t pos2 = firstnewseg - drawsegs; size_t newmax = maxdrawsegs ? maxdrawsegs*2 : 128; if (firstseg) firstseg = (drawseg_t *)(firstseg - drawsegs); drawsegs = Z_Realloc(drawsegs, newmax*sizeof (*drawsegs), PU_STATIC, NULL); ds_p = drawsegs + pos; - firstnewseg = drawsegs + pos2; maxdrawsegs = newmax; if (firstseg) firstseg = drawsegs + (size_t)firstseg; @@ -1502,8 +1579,80 @@ void R_StoreWallRange(INT32 start, INT32 stop) // calculate texture boundaries // and decide if floor / ceiling marks are needed - worldtop = frontsector->ceilingheight - viewz; - worldbottom = frontsector->floorheight - viewz; +#ifdef ESLOPE + // Figure out map coordinates of where start and end are mapping to on seg, so we can clip right for slope bullshit + if (frontsector->hasslope || (backsector && backsector->hasslope)) // Commenting this out for FOFslop. -Red + { + angle_t temp; + + // left + temp = xtoviewangle[start]+viewangle; + + { + // Both lines can be written in slope-intercept form, so figure out line intersection + float a1, b1, c1, a2, b2, c2, det; // 1 is the seg, 2 is the view angle vector... + ///TODO: convert to FPU + + a1 = FIXED_TO_FLOAT(curline->v2->y-curline->v1->y); + b1 = FIXED_TO_FLOAT(curline->v1->x-curline->v2->x); + c1 = a1*FIXED_TO_FLOAT(curline->v1->x) + b1*FIXED_TO_FLOAT(curline->v1->y); + + a2 = -FIXED_TO_FLOAT(FINESINE(temp>>ANGLETOFINESHIFT)); + b2 = FIXED_TO_FLOAT(FINECOSINE(temp>>ANGLETOFINESHIFT)); + c2 = a2*FIXED_TO_FLOAT(viewx) + b2*FIXED_TO_FLOAT(viewy); + + det = a1*b2 - a2*b1; + + ds_p->leftpos.x = segleft.x = FLOAT_TO_FIXED((b2*c1 - b1*c2)/det); + ds_p->leftpos.y = segleft.y = FLOAT_TO_FIXED((a1*c2 - a2*c1)/det); + } + + // right + temp = xtoviewangle[stop]+viewangle; + + { + // Both lines can be written in slope-intercept form, so figure out line intersection + float a1, b1, c1, a2, b2, c2, det; // 1 is the seg, 2 is the view angle vector... + ///TODO: convert to FPU + + a1 = FIXED_TO_FLOAT(curline->v2->y-curline->v1->y); + b1 = FIXED_TO_FLOAT(curline->v1->x-curline->v2->x); + c1 = a1*FIXED_TO_FLOAT(curline->v1->x) + b1*FIXED_TO_FLOAT(curline->v1->y); + + a2 = -FIXED_TO_FLOAT(FINESINE(temp>>ANGLETOFINESHIFT)); + b2 = FIXED_TO_FLOAT(FINECOSINE(temp>>ANGLETOFINESHIFT)); + c2 = a2*FIXED_TO_FLOAT(viewx) + b2*FIXED_TO_FLOAT(viewy); + + det = a1*b2 - a2*b1; + + ds_p->rightpos.x = segright.x = FLOAT_TO_FIXED((b2*c1 - b1*c2)/det); + ds_p->rightpos.y = segright.y = FLOAT_TO_FIXED((a1*c2 - a2*c1)/det); + } + } + + if (frontsector->c_slope) { + worldtop = P_GetZAt(frontsector->c_slope, segleft.x, segleft.y) - viewz; + worldtopslope = P_GetZAt(frontsector->c_slope, segright.x, segright.y) - viewz; + } else { + worldtopslope = +#else + { +#endif + worldtop = frontsector->ceilingheight - viewz; + } + + +#ifdef ESLOPE + if (frontsector->f_slope) { + worldbottom = P_GetZAt(frontsector->f_slope, segleft.x, segleft.y) - viewz; + worldbottomslope = P_GetZAt(frontsector->f_slope, segright.x, segright.y) - viewz; + } else { + worldbottomslope = +#else + { +#endif + worldbottom = frontsector->floorheight - viewz; + } midtexture = toptexture = bottomtexture = maskedtexture = 0; ds_p->maskedtexturecol = NULL; @@ -1524,27 +1673,72 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (ffloor[i].polyobj && (!ds_p->curline->polyseg || ffloor[i].polyobj != ds_p->curline->polyseg)) continue; #endif + +#ifdef ESLOPE + if (ffloor[i].slope) { + ffloor[i].f_pos = P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) - viewz; + ffloor[i].f_pos_slope = P_GetZAt(ffloor[i].slope, segright.x, segright.y) - viewz; + } else + ffloor[i].f_pos_slope = +#endif ffloor[i].f_pos = ffloor[i].height - viewz; } } +#ifdef ESLOPE + // Set up texture Y offset slides for sloped walls + rw_toptextureslide = rw_midtextureslide = rw_bottomtextureslide = 0; + ceilingfrontslide = floorfrontslide = ceilingbackslide = floorbackslide = 0; + + { + angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); + + if (frontsector->f_slope) + floorfrontslide = FixedMul(frontsector->f_slope->zdelta, FINECOSINE((lineangle-frontsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); + + if (frontsector->c_slope) + ceilingfrontslide = FixedMul(frontsector->c_slope->zdelta, FINECOSINE((lineangle-frontsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); + + if (backsector && backsector->f_slope) + floorbackslide = FixedMul(backsector->f_slope->zdelta, FINECOSINE((lineangle-backsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); + + if (backsector && backsector->c_slope) + ceilingbackslide = FixedMul(backsector->c_slope->zdelta, FINECOSINE((lineangle-backsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); + } +#endif + if (!backsector) { // single sided line midtexture = texturetranslation[sidedef->midtexture]; // a single sided line is terminal, so it must mark ends markfloor = markceiling = true; - +#ifdef ESLOPE + if (!(linedef->flags & ML_EFFECT1)) { + if (linedef->flags & ML_DONTPEGBOTTOM) + rw_midtexturemid = frontsector->floorheight + textureheight[sidedef->midtexture] - viewz; + else + rw_midtexturemid = frontsector->ceilingheight; + } +#endif if (linedef->flags & ML_DONTPEGBOTTOM) { +#ifdef ESLOPE + rw_midtexturemid = worldbottom + textureheight[sidedef->midtexture]; + rw_midtextureslide = floorfrontslide; +#else vtop = frontsector->floorheight + textureheight[sidedef->midtexture]; // bottom of texture at bottom rw_midtexturemid = vtop - viewz; +#endif } else { // top of texture at top rw_midtexturemid = worldtop; +#ifdef ESLOPE + rw_midtextureslide = ceilingfrontslide; +#endif } rw_midtexturemid += sidedef->rowoffset; @@ -1557,47 +1751,120 @@ void R_StoreWallRange(INT32 start, INT32 stop) else { // two sided line + +#ifdef ESLOPE + if (backsector->c_slope) { + worldhigh = P_GetZAt(backsector->c_slope, segleft.x, segleft.y) - viewz; + worldhighslope = P_GetZAt(backsector->c_slope, segright.x, segright.y) - viewz; + } else { + worldhighslope = +#else + { +#endif + worldhigh = backsector->ceilingheight - viewz; + } + + +#ifdef ESLOPE + if (backsector->f_slope) { + worldlow = P_GetZAt(backsector->f_slope, segleft.x, segleft.y) - viewz; + worldlowslope = P_GetZAt(backsector->f_slope, segright.x, segright.y) - viewz; + } else { + worldlowslope = +#else + { +#endif + worldlow = backsector->floorheight - viewz; + } + + + // hack to allow height changes in outdoor areas + if (frontsector->ceilingpic == skyflatnum + && backsector->ceilingpic == skyflatnum) + { +#ifdef ESLOPE + worldtopslope = worldhighslope = +#endif + worldtop = worldhigh; + } + ds_p->sprtopclip = ds_p->sprbottomclip = NULL; ds_p->silhouette = 0; - if (frontsector->floorheight > backsector->floorheight) + if ( +#ifdef ESLOPE + worldbottomslope > worldlowslope || +#endif + worldbottom > worldlow) { ds_p->silhouette = SIL_BOTTOM; +#ifdef ESLOPE + ds_p->bsilheight = (frontsector->f_slope ? INT32_MAX : frontsector->floorheight); +#else ds_p->bsilheight = frontsector->floorheight; +#endif } +#ifdef ESLOPE + else if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz) +#else else if (backsector->floorheight > viewz) +#endif { ds_p->silhouette = SIL_BOTTOM; ds_p->bsilheight = INT32_MAX; // ds_p->sprbottomclip = negonearray; } - if (frontsector->ceilingheight < backsector->ceilingheight) + if ( +#ifdef ESLOPE + worldtopslope < worldhighslope || +#endif + worldtop < worldhigh) { ds_p->silhouette |= SIL_TOP; +#ifdef ESLOPE + ds_p->tsilheight = (frontsector->c_slope ? INT32_MIN : frontsector->ceilingheight); +#else ds_p->tsilheight = frontsector->ceilingheight; +#endif } +#ifdef ESLOPE + else if ((backsector->c_slope ? P_GetZAt(backsector->c_slope, viewx, viewy) : backsector->ceilingheight) < viewz) +#else else if (backsector->ceilingheight < viewz) +#endif { ds_p->silhouette |= SIL_TOP; ds_p->tsilheight = INT32_MIN; // ds_p->sprtopclip = screenheightarray; } - if (backsector->ceilingheight <= frontsector->floorheight) +#ifdef ESLOPE + if (worldhigh <= worldbottom && worldhighslope <= worldbottomslope) +#else + if (worldhigh <= worldbottom) +#endif { ds_p->sprbottomclip = negonearray; ds_p->bsilheight = INT32_MAX; ds_p->silhouette |= SIL_BOTTOM; } - if (backsector->floorheight >= frontsector->ceilingheight) +#ifdef ESLOPE + if (worldlow >= worldtop && worldlowslope >= worldtopslope) +#else + if (worldlow >= worldtop) +#endif { ds_p->sprtopclip = screenheightarray; ds_p->tsilheight = INT32_MIN; ds_p->silhouette |= SIL_TOP; } +#ifdef ESLOPE + // This causes issues with slopes. + if (!(frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope)) +#endif //SoM: 3/25/2000: This code fixes an automap bug that didn't check // frontsector->ceiling and backsector->floor to see if a door was closed. // Without the following code, sprites get displayed behind closed doors. @@ -1616,17 +1883,11 @@ void R_StoreWallRange(INT32 start, INT32 stop) } } - worldhigh = backsector->ceilingheight - viewz; - worldlow = backsector->floorheight - viewz; - - // hack to allow height changes in outdoor areas - if (frontsector->ceilingpic == skyflatnum - && backsector->ceilingpic == skyflatnum) - { - worldtop = worldhigh; - } - if (worldlow != worldbottom +#ifdef ESLOPE + || worldlowslope != worldbottomslope + || backsector->f_slope != frontsector->f_slope +#endif || backsector->floorpic != frontsector->floorpic || backsector->lightlevel != frontsector->lightlevel //SoM: 3/22/2000: Check floor x and y offsets. @@ -1649,6 +1910,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) } if (worldhigh != worldtop +#ifdef ESLOPE + || worldhighslope != worldtopslope + || backsector->c_slope != frontsector->c_slope +#endif || backsector->ceilingpic != frontsector->ceilingpic || backsector->lightlevel != frontsector->lightlevel //SoM: 3/22/2000: Check floor x and y offsets. @@ -1678,7 +1943,11 @@ void R_StoreWallRange(INT32 start, INT32 stop) } // check TOP TEXTURE - if (worldhigh < worldtop) + if (worldhigh < worldtop +#ifdef ESLOPE + || worldhighslope < worldtopslope +#endif + ) { // top texture if ((linedef->flags & (ML_DONTPEGTOP) && (linedef->flags & ML_DONTPEGBOTTOM)) @@ -1691,49 +1960,100 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (!toptexture) //Second side has no texture, use the first side's instead. toptexture = texturetranslation[sidedef->toptexture]; +#ifdef ESLOPE + if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked + if (linedef->flags & ML_DONTPEGTOP) + rw_toptexturemid = frontsector->ceilingheight - viewz; + else + rw_toptexturemid = backsector->ceilingheight - viewz; + } else +#endif if (linedef->flags & ML_DONTPEGTOP) { // top of texture at top rw_toptexturemid = worldtop; +#ifdef ESLOPE + rw_toptextureslide = ceilingfrontslide; +#endif } else { +#ifdef ESLOPE + rw_toptexturemid = worldhigh + textureheight[def->toptexture]; + rw_toptextureslide = ceilingbackslide; +#else vtop = backsector->ceilingheight + textureheight[def->toptexture]; // bottom of texture rw_toptexturemid = vtop - viewz; +#endif } } else { toptexture = texturetranslation[sidedef->toptexture]; +#ifdef ESLOPE + if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked + if (linedef->flags & ML_DONTPEGTOP) + rw_toptexturemid = frontsector->ceilingheight - viewz; + else + rw_toptexturemid = backsector->ceilingheight - viewz; + } else +#endif if (linedef->flags & ML_DONTPEGTOP) { // top of texture at top rw_toptexturemid = worldtop; +#ifdef ESLOPE + rw_toptextureslide = ceilingfrontslide; +#endif } else { +#ifdef ESLOPE + rw_toptexturemid = worldhigh + textureheight[sidedef->toptexture]; + rw_toptextureslide = ceilingbackslide; +#else vtop = backsector->ceilingheight + textureheight[sidedef->toptexture]; // bottom of texture rw_toptexturemid = vtop - viewz; +#endif } } } // check BOTTOM TEXTURE - if (worldlow > worldbottom) //seulement si VISIBLE!!! + if (worldlow > worldbottom +#ifdef ESLOPE + || worldlowslope > worldbottomslope +#endif + ) //seulement si VISIBLE!!! { // bottom texture bottomtexture = texturetranslation[sidedef->bottomtexture]; +#ifdef ESLOPE + if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked + if (linedef->flags & ML_DONTPEGBOTTOM) + rw_bottomtexturemid = frontsector->floorheight - viewz; + else + rw_bottomtexturemid = backsector->floorheight - viewz; + } else +#endif if (linedef->flags & ML_DONTPEGBOTTOM) { // bottom of texture at bottom // top of texture at top - rw_bottomtexturemid = worldtop; + rw_bottomtexturemid = worldbottom; +#ifdef ESLOPE + rw_bottomtextureslide = floorfrontslide; +#endif } - else // top of texture at top + else { // top of texture at top rw_bottomtexturemid = worldlow; +#ifdef ESLOPE + rw_bottomtextureslide = floorbackslide; +#endif + } } rw_toptexturemid += sidedef->rowoffset; @@ -1745,6 +2065,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) ffloor_t *rover; ffloor_t *r2; fixed_t lowcut, highcut; +#ifdef ESLOPE + fixed_t lowcutslope, highcutslope; + + // Used for height comparisons and etc across FOFs and slopes + fixed_t high1, highslope1, low1, lowslope1, high2, highslope2, low2, lowslope2; +#endif //markceiling = markfloor = true; maskedtexture = true; @@ -1752,8 +2078,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) ds_p->thicksidecol = maskedtexturecol = lastopening - rw_x; lastopening += rw_stopx - rw_x; - lowcut = frontsector->floorheight > backsector->floorheight ? frontsector->floorheight : backsector->floorheight; - highcut = frontsector->ceilingheight < backsector->ceilingheight ? frontsector->ceilingheight : backsector->ceilingheight; + lowcut = max(worldbottom, worldlow) + viewz; + highcut = min(worldtop, worldhigh) + viewz; +#ifdef ESLOPE + lowcutslope = max(worldbottomslope, worldlowslope) + viewz; + highcutslope = min(worldtopslope, worldhighslope) + viewz; +#endif if (frontsector->ffloors && backsector->ffloors) { @@ -1764,16 +2094,33 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; if (rover->flags & FF_INVERTSIDES) continue; - if (*rover->topheight < lowcut || *rover->bottomheight > highcut) - continue; if (rover->norender == leveltime) continue; +#ifdef ESLOPE + if (*rover->t_slope) { + high1 = P_GetZAt(*rover->t_slope, segleft.x, segleft.y); + highslope1 = P_GetZAt(*rover->t_slope, segright.x, segright.y); + } else + high1 = highslope1 = *rover->topheight; + if (*rover->b_slope) { + low1 = P_GetZAt(*rover->b_slope, segleft.x, segleft.y); + lowslope1 = P_GetZAt(*rover->b_slope, segright.x, segright.y); + } else + low1 = lowslope1 = *rover->bottomheight; + + if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) + continue; +#else + if (*rover->topheight < lowcut || *rover->bottomheight > highcut) + continue; +#endif + for (r2 = frontsector->ffloors; r2; r2 = r2->next) { if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES) - || *r2->topheight < lowcut || *r2->bottomheight > highcut) + || *r2->topheight < lowcut || *r2->bottomheight > highcut) ///TODO: make these account for slopes -Red continue; if (r2->norender == leveltime) @@ -1793,8 +2140,24 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; } +#ifdef ESLOPE + if (*r2->t_slope) { + high2 = P_GetZAt(*r2->t_slope, segleft.x, segleft.y); + highslope2 = P_GetZAt(*r2->t_slope, segright.x, segright.y); + } else + high2 = highslope2 = *r2->topheight; + if (*r2->b_slope) { + low2 = P_GetZAt(*r2->b_slope, segleft.x, segleft.y); + lowslope2 = P_GetZAt(*r2->b_slope, segright.x, segright.y); + } else + low2 = lowslope2 = *r2->bottomheight; + + if ((high1 > high2 && highslope1 > highslope2) || (low1 < low2 && lowslope1 < lowslope2)) + continue; +#else if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) continue; +#endif break; } @@ -1811,16 +2174,33 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; if (!(rover->flags & FF_ALLSIDES)) continue; - if (*rover->topheight < lowcut || *rover->bottomheight > highcut) - continue; if (rover->norender == leveltime) continue; +#ifdef ESLOPE + if (*rover->t_slope) { + high1 = P_GetZAt(*rover->t_slope, segleft.x, segleft.y); + highslope1 = P_GetZAt(*rover->t_slope, segright.x, segright.y); + } else + high1 = highslope1 = *rover->topheight; + if (*rover->b_slope) { + low1 = P_GetZAt(*rover->b_slope, segleft.x, segleft.y); + lowslope1 = P_GetZAt(*rover->b_slope, segright.x, segright.y); + } else + low1 = lowslope1 = *rover->bottomheight; + + if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) + continue; +#else + if (*rover->topheight < lowcut || *rover->bottomheight > highcut) + continue; +#endif + for (r2 = backsector->ffloors; r2; r2 = r2->next) { if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES) - || *r2->topheight < lowcut || *r2->bottomheight > highcut) + || *r2->topheight < lowcut || *r2->bottomheight > highcut) ///TODO: make these account for slopes -Red continue; if (r2->norender == leveltime) @@ -1840,8 +2220,24 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; } +#ifdef ESLOPE + if (*r2->t_slope) { + high2 = P_GetZAt(*r2->t_slope, segleft.x, segleft.y); + highslope2 = P_GetZAt(*r2->t_slope, segright.x, segright.y); + } else + high2 = highslope2 = *r2->topheight; + if (*r2->b_slope) { + low2 = P_GetZAt(*r2->b_slope, segleft.x, segleft.y); + lowslope2 = P_GetZAt(*r2->b_slope, segright.x, segright.y); + } else + low2 = lowslope2 = *r2->bottomheight; + + if ((high1 > high2 && highslope1 > highslope2) || (low1 < low2 && lowslope1 < lowslope2)) + continue; +#else if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) continue; +#endif break; } @@ -1858,11 +2254,21 @@ void R_StoreWallRange(INT32 start, INT32 stop) { if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || rover->flags & FF_INVERTSIDES) continue; - if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) - continue; if (rover->norender == leveltime) continue; +#ifdef ESLOPE + // Oy vey. + if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz + && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) + ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz + && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) + continue; +#else + if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) + continue; +#endif + ds_p->thicksides[i] = rover; i++; } @@ -1873,12 +2279,27 @@ void R_StoreWallRange(INT32 start, INT32 stop) { if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_ALLSIDES)) continue; + if (rover->norender == leveltime) + continue; +#ifdef ESLOPE + // Oy vey. + if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz + && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) + ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz + && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) + continue; + + if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldlow+viewz + && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldlowslope+viewz) + ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldhigh+viewz + && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldhighslope+viewz)) + continue; +#else if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) continue; if (*rover->topheight <= backsector->floorheight || *rover->bottomheight >= backsector->ceilingheight) continue; - if (rover->norender == leveltime) - continue; +#endif ds_p->thicksides[i] = rover; i++; @@ -1898,6 +2319,32 @@ void R_StoreWallRange(INT32 start, INT32 stop) else ds_p->maskedtexturecol = ds_p->thicksidecol; +#ifdef ESLOPE + maskedtextureheight = &(ds_p->maskedtextureheight[0]); // ???? + + // Set midtexture starting height + if (linedef->flags & ML_EFFECT2) { // Ignore slopes when texturing + rw_midtextureslide = rw_midtexturebackslide = 0; + if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) + rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz; + else + rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz; + + } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { + rw_midtexturemid = worldbottom; + rw_midtextureslide = floorfrontslide; + rw_midtextureback = worldlow; + rw_midtexturebackslide = floorbackslide; + } else { + rw_midtexturemid = worldtop; + rw_midtextureslide = ceilingfrontslide; + rw_midtextureback = worldhigh; + rw_midtexturebackslide = ceilingbackslide; + } + rw_midtexturemid += sidedef->rowoffset; + rw_midtextureback += sidedef->rowoffset; +#endif + maskedtexture = true; } } @@ -1950,13 +2397,21 @@ void R_StoreWallRange(INT32 start, INT32 stop) // and doesn't need to be marked. if (frontsector->heightsec == -1) { - if (frontsector->floorheight >= viewz) + if (( +#ifdef ESLOPE + frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : +#endif + frontsector->floorheight) >= viewz) { // above view plane markfloor = false; } - if (frontsector->ceilingheight <= viewz && + if (( +#ifdef ESLOPE + frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) : +#endif + frontsector->ceilingheight) <= viewz && frontsector->ceilingpic != skyflatnum) { // below view plane @@ -1967,6 +2422,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) // calculate incremental stepping values for texture edges worldtop >>= 4; worldbottom >>= 4; +#ifdef ESLOPE + worldtopslope >>= 4; + worldbottomslope >>= 4; +#endif topstep = -FixedMul (rw_scalestep, worldtop); topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale); @@ -1974,6 +2433,17 @@ void R_StoreWallRange(INT32 start, INT32 stop) bottomstep = -FixedMul (rw_scalestep,worldbottom); bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale); +#ifdef ESLOPE + if (frontsector->c_slope) { + fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldtopslope, ds_p->scale2); + topstep = (topfracend-topfrac)/(stop-start+1); + } + if (frontsector->f_slope) { + fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldbottomslope, ds_p->scale2); + bottomstep = (bottomfracend-bottomfrac)/(stop-start+1); + } +#endif + dc_numlights = 0; if (frontsector->numlights) @@ -1987,26 +2457,83 @@ void R_StoreWallRange(INT32 start, INT32 stop) for (i = p = 0; i < dc_numlights; i++) { +#ifdef ESLOPE + fixed_t leftheight, rightheight; +#endif + light = &frontsector->lightlist[i]; rlight = &dc_lightlist[p]; +#ifdef ESLOPE + if (light->slope) { + leftheight = P_GetZAt(light->slope, segleft.x, segleft.y); + rightheight = P_GetZAt(light->slope, segright.x, segright.y); + + // Flag sector as having slopes + frontsector->hasslope = true; + } else + leftheight = rightheight = light->height; + + leftheight -= viewz; + rightheight -= viewz; + + leftheight >>= 4; + rightheight >>= 4; +#endif + if (i != 0) { +#ifdef ESLOPE + if (leftheight < worldbottom && rightheight < worldbottomslope) + continue; + + if (leftheight > worldtop && rightheight > worldtopslope && i+1 < dc_numlights && frontsector->lightlist[i+1].height > frontsector->ceilingheight) + continue; +#else if (light->height < frontsector->floorheight) continue; if (light->height > frontsector->ceilingheight && i+1 < dc_numlights && frontsector->lightlist[i+1].height > frontsector->ceilingheight) continue; +#endif } +#ifdef ESLOPE + rlight->height = (centeryfrac>>4) - FixedMul(leftheight, rw_scale); + rlight->heightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2); + rlight->heightstep = (rlight->heightstep-rlight->height)/(stop-start+1); +#else rlight->height = (centeryfrac>>4) - FixedMul((light->height - viewz) >> 4, rw_scale); rlight->heightstep = -FixedMul (rw_scalestep, (light->height - viewz) >> 4); +#endif rlight->flags = light->flags; if (light->caster && light->caster->flags & FF_SOLID) { +#ifdef ESLOPE + if (*light->caster->b_slope) { + leftheight = P_GetZAt(*light->caster->b_slope, segleft.x, segleft.y); + rightheight = P_GetZAt(*light->caster->b_slope, segright.x, segright.y); + + // Flag sector as having slopes + frontsector->hasslope = true; + } else + leftheight = rightheight = *light->caster->bottomheight; + + leftheight -= viewz; + rightheight -= viewz; + + leftheight >>= 4; + rightheight >>= 4; + + rlight->botheight = (centeryfrac>>4) - FixedMul(leftheight, rw_scale); + rlight->botheightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2); + rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(stop-start+1); + +#else rlight->botheight = (centeryfrac >> 4) - FixedMul((*light->caster->bottomheight - viewz) >> 4, rw_scale); rlight->botheightstep = -FixedMul (rw_scalestep, (*light->caster->bottomheight - viewz) >> 4); +#endif } rlight->lightlevel = *light->lightlevel; @@ -2027,8 +2554,14 @@ void R_StoreWallRange(INT32 start, INT32 stop) #endif ffloor[i].f_pos >>= 4; +#ifdef ESLOPE + ffloor[i].f_pos_slope >>= 4; + ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); + ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(stop-start+1); +#else ffloor[i].f_step = FixedMul(-rw_scalestep, ffloor[i].f_pos); ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); +#endif } } @@ -2036,21 +2569,50 @@ void R_StoreWallRange(INT32 start, INT32 stop) { worldhigh >>= 4; worldlow >>= 4; +#ifdef ESLOPE + worldhighslope >>= 4; + worldlowslope >>= 4; +#endif - if (worldhigh < worldtop) + if (worldhigh < worldtop +#ifdef ESLOPE + || worldhighslope <= worldtopslope +#endif + ) { pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); pixhighstep = -FixedMul (rw_scalestep,worldhigh); + +#ifdef ESLOPE + if (backsector->c_slope) { + fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2); + pixhighstep = (topfracend-pixhigh)/(stop-start+1); + } +#endif } - if (worldlow > worldbottom) + if (worldlow > worldbottom +#ifdef ESLOPE + || worldlowslope >= worldbottomslope +#endif + ) { pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale); pixlowstep = -FixedMul (rw_scalestep,worldlow); +#ifdef ESLOPE + if (backsector->f_slope) { + fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); + pixlowstep = (bottomfracend-pixlow)/(stop-start+1); + } +#endif } { ffloor_t * rover; +#ifdef ESLOPE + fixed_t rovertest; + fixed_t planevistest; +#endif i = 0; if (backsector->ffloors) @@ -2062,6 +2624,52 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (rover->norender == leveltime) continue; +#ifdef ESLOPE + // Let the renderer know this sector is sloped. + if (*rover->b_slope || *rover->t_slope) + backsector->hasslope = true; + + rovertest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, backsector->soundorg.x, backsector->soundorg.y) : *rover->bottomheight) - viewz; + planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); + + if (rovertest>>4 <= worldhigh && + rovertest>>4 >= worldlow && + ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->b_slope; + ffloor[i].b_pos = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; + ffloor[i].b_pos_slope = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1); + i++; + } + + if (i >= MAXFFLOORS) + break; + + rovertest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, backsector->soundorg.x, backsector->soundorg.y) : *rover->topheight) - viewz; + planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); + + if (rovertest>>4 <= worldhigh && + rovertest>>4 >= worldlow && + ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->t_slope; + ffloor[i].b_pos = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; + ffloor[i].b_pos_slope = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1); + i++; + } +#else if (*rover->bottomheight <= backsector->ceilingheight && *rover->bottomheight >= backsector->floorheight && ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || @@ -2073,8 +2681,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); i++; } + if (i >= MAXFFLOORS) break; + if (*rover->topheight >= backsector->floorheight && *rover->topheight <= backsector->ceilingheight && ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) || @@ -2086,6 +2696,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); i++; } +#endif } } else if (frontsector && frontsector->ffloors) @@ -2097,6 +2708,53 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (rover->norender == leveltime) continue; + +#ifdef ESLOPE + // Let the renderer know this sector is sloped. + if (*rover->b_slope || *rover->t_slope) + frontsector->hasslope = true; + + rovertest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, frontsector->soundorg.x, frontsector->soundorg.y) : *rover->bottomheight) - viewz; + planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); + + if (rovertest>>4 <= worldtop && + rovertest>>4 >= worldbottom && + ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->b_slope; + ffloor[i].b_pos = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; + ffloor[i].b_pos_slope = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1); + i++; + } + + if (i >= MAXFFLOORS) + break; + + rovertest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, frontsector->soundorg.x, frontsector->soundorg.y) : *rover->topheight) - viewz; + planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); + + if (rovertest>>4 <= worldtop && + rovertest>>4 >= worldbottom && + ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->t_slope; + ffloor[i].b_pos = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; + ffloor[i].b_pos_slope = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(stop-start+1); + i++; + } +#else if (*rover->bottomheight <= frontsector->ceilingheight && *rover->bottomheight >= frontsector->floorheight && ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || @@ -2121,6 +2779,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); i++; } +#endif } } #ifdef POLYOBJECTS_PLANES @@ -2137,6 +2796,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (ffloor[i].plane->maxx < ds_p->x2) ffloor[i].plane->maxx = ds_p->x2; +#ifdef ESLOPE + ffloor[i].slope = NULL; +#endif ffloor[i].b_pos = backsector->floorheight; ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); @@ -2153,6 +2815,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (ffloor[i].plane->maxx < ds_p->x2) ffloor[i].plane->maxx = ds_p->x2; +#ifdef ESLOPE + ffloor[i].slope = NULL; +#endif ffloor[i].b_pos = backsector->ceilingheight; ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); diff --git a/src/r_splats.c b/src/r_splats.c index 72eca08fb..b37ce1923 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -503,7 +503,7 @@ static void R_RenderFloorSplat(floorsplat_t *pSplat, vertex_t *verts, UINT8 *pTe { ds_x1 = x1; ds_x2 = x2; - ds_transmap = ((tr_trans50)<numlights; i++) { - if (sector->lightlist[i].height >= sprite->gzt || !(sector->lightlist[i].caster->flags & FF_CUTSPRITES)) + fixed_t testheight = sector->lightlist[i].height; + + if (!(sector->lightlist[i].caster->flags & FF_CUTSPRITES)) continue; - if (sector->lightlist[i].height <= sprite->gz) + +#ifdef ESLOPE + if (sector->lightlist[i].slope) + testheight = P_GetZAt(sector->lightlist[i].slope, sprite->gx, sprite->gy); +#endif + + if (testheight >= sprite->gzt) + continue; + if (testheight <= sprite->gz) return; - cutfrac = (INT16)((centeryfrac - FixedMul(sector->lightlist[i].height - viewz, sprite->scale))>>FRACBITS); + cutfrac = (INT16)((centeryfrac - FixedMul(testheight - viewz, sprite->scale))>>FRACBITS); if (cutfrac < 0) continue; if (cutfrac > vid.height) @@ -970,15 +981,15 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing) newsprite = M_Memcpy(R_NewVisSprite(), sprite, sizeof (vissprite_t)); sprite->cut |= SC_BOTTOM; - sprite->gz = sector->lightlist[i].height; + sprite->gz = testheight; newsprite->gzt = sprite->gz; sprite->sz = cutfrac; newsprite->szt = (INT16)(sprite->sz - 1); - if (sector->lightlist[i].height < sprite->pzt && sector->lightlist[i].height > sprite->pz) - sprite->pz = newsprite->pzt = sector->lightlist[i].height; + if (testheight < sprite->pzt && testheight > sprite->pz) + sprite->pz = newsprite->pzt = testheight; else { newsprite->pz = newsprite->gz; @@ -1094,7 +1105,7 @@ static void R_ProjectSprite(mobj_t *thing) { sprdef = &((skin_t *)thing->skin)->sprites[thing->sprite2]; if (rot >= sprdef->numframes) { - CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid skins[\"%s\"].sprites[SPR2_%s] frame %d\n"), ((skin_t *)thing->skin)->name, spr2names[thing->sprite2], rot); + CONS_Alert(CONS_ERROR, M_GetText("R_ProjectSprite: invalid skins[\"%s\"].sprites[SPR2_%s] frame %s\n"), ((skin_t *)thing->skin)->name, spr2names[thing->sprite2], sizeu5(rot)); thing->sprite = states[S_UNKNOWN].sprite; thing->frame = states[S_UNKNOWN].frame; sprdef = &sprites[thing->sprite]; @@ -1200,7 +1211,20 @@ static void R_ProjectSprite(mobj_t *thing) if (thing->subsector->sector->numlights) { INT32 lightnum; +#ifdef ESLOPE // R_GetPlaneLight won't work on sloped lights! + light = thing->subsector->sector->numlights - 1; + + for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) { + fixed_t h = thing->subsector->sector->lightlist[lightnum].slope ? P_GetZAt(thing->subsector->sector->lightlist[lightnum].slope, thing->x, thing->y) + : thing->subsector->sector->lightlist[lightnum].height; + if (h <= gzt) { + light = lightnum - 1; + break; + } + } +#else light = R_GetPlaneLight(thing->subsector->sector, gzt, false); +#endif lightnum = (*thing->subsector->sector->lightlist[light].lightlevel >> LIGHTSEGSHIFT); if (lightnum < 0) @@ -1242,7 +1266,8 @@ static void R_ProjectSprite(mobj_t *thing) vis = R_NewVisSprite(); vis->heightsec = heightsec; //SoM: 3/17/2000 vis->mobjflags = thing->flags; - vis->scale = yscale + thing->info->dispoffset; //<scale = yscale; //<dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15 vis->gx = thing->x; vis->gy = thing->y; vis->gz = gz; @@ -1305,9 +1330,9 @@ static void R_ProjectSprite(mobj_t *thing) if (!cv_translucency.value) ; // no translucency else if (thing->flags2 & MF2_SHADOW) // actually only the player should use this (temporary invisibility) - vis->transmap = ((tr_trans80-1)<transmap = transtables + ((tr_trans80-1)<frame & FF_TRANSMASK) - vis->transmap = (thing->frame & FF_TRANSMASK) - 0x10000 + transtables; + vis->transmap = transtables + (thing->frame & FF_TRANSMASK) - 0x10000; if (((thing->frame & FF_FULLBRIGHT) || (thing->flags2 & MF2_SHADOW)) && (!vis->extra_colormap || !vis->extra_colormap->fog)) @@ -1458,6 +1483,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) // store information in a vissprite vis = R_NewVisSprite(); vis->scale = yscale; //<dispoffset = 0; // Monster Iestyn: 23/11/15 vis->gx = thing->x; vis->gy = thing->y; vis->gz = gz; @@ -1609,6 +1635,7 @@ void R_SortVisSprites(void) vissprite_t *best = NULL; vissprite_t unsorted; fixed_t bestscale; + INT32 bestdispoffset; if (!visspritecount) return; @@ -1639,12 +1666,19 @@ void R_SortVisSprites(void) vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead; for (i = 0; i < visspritecount; i++) { - bestscale = INT32_MAX; + bestscale = bestdispoffset = INT32_MAX; for (ds = unsorted.next; ds != &unsorted; ds = ds->next) { if (ds->scale < bestscale) { bestscale = ds->scale; + bestdispoffset = ds->dispoffset; + best = ds; + } + // order visprites of same scale by dispoffset, smallest first + else if (ds->scale == bestscale && ds->dispoffset < bestdispoffset) + { + bestdispoffset = ds->dispoffset; best = ds; } } @@ -1761,24 +1795,34 @@ static void R_CreateDrawNodes(void) { if (r2->plane) { + fixed_t planeobjectz, planecameraz; if (r2->plane->minx > rover->x2 || r2->plane->maxx < rover->x1) continue; if (rover->szt > r2->plane->low || rover->sz < r2->plane->high) continue; +#ifdef ESLOPE + // Effective height may be different for each comparison in the case of slopes + if (r2->plane->slope) { + planeobjectz = P_GetZAt(r2->plane->slope, rover->gx, rover->gy); + planecameraz = P_GetZAt(r2->plane->slope, viewx, viewy); + } else +#endif + planeobjectz = planecameraz = r2->plane->height; + if (rover->mobjflags & MF_NOCLIPHEIGHT) { //Objects with NOCLIPHEIGHT can appear halfway in. - if (r2->plane->height < viewz && rover->pz+(rover->thingheight/2) >= r2->plane->height) + if (planecameraz < viewz && rover->pz+(rover->thingheight/2) >= planeobjectz) continue; - if (r2->plane->height > viewz && rover->pzt-(rover->thingheight/2) <= r2->plane->height) + if (planecameraz > viewz && rover->pzt-(rover->thingheight/2) <= planeobjectz) continue; } else { - if (r2->plane->height < viewz && rover->pz >= r2->plane->height) + if (planecameraz < viewz && rover->pz >= planeobjectz) continue; - if (r2->plane->height > viewz && rover->pzt <= r2->plane->height) + if (planecameraz > viewz && rover->pzt <= planeobjectz) continue; } @@ -1808,6 +1852,7 @@ static void R_CreateDrawNodes(void) } else if (r2->thickseg) { + fixed_t topplaneobjectz, topplanecameraz, botplaneobjectz, botplanecameraz; if (rover->x1 > r2->thickseg->x2 || rover->x2 < r2->thickseg->x1) continue; @@ -1818,9 +1863,25 @@ static void R_CreateDrawNodes(void) if (scale <= rover->scale) continue; - if ((*r2->ffloor->topheight > viewz && *r2->ffloor->bottomheight < viewz) || - (*r2->ffloor->topheight < viewz && rover->gzt < *r2->ffloor->topheight) || - (*r2->ffloor->bottomheight > viewz && rover->gz > *r2->ffloor->bottomheight)) +#ifdef ESLOPE + if (*r2->ffloor->t_slope) { + topplaneobjectz = P_GetZAt(*r2->ffloor->t_slope, rover->gx, rover->gy); + topplanecameraz = P_GetZAt(*r2->ffloor->t_slope, viewx, viewy); + } else +#endif + topplaneobjectz = topplanecameraz = *r2->ffloor->topheight; + +#ifdef ESLOPE + if (*r2->ffloor->b_slope) { + botplaneobjectz = P_GetZAt(*r2->ffloor->b_slope, rover->gx, rover->gy); + botplanecameraz = P_GetZAt(*r2->ffloor->b_slope, viewx, viewy); + } else +#endif + botplaneobjectz = botplanecameraz = *r2->ffloor->bottomheight; + + if ((topplanecameraz > viewz && botplanecameraz < viewz) || + (topplanecameraz < viewz && rover->gzt < topplaneobjectz) || + (botplanecameraz > viewz && rover->gz > botplaneobjectz)) { entry = R_CreateDrawNode(NULL); (entry->prev = r2->prev)->next = entry; @@ -1869,7 +1930,8 @@ static void R_CreateDrawNodes(void) if (r2->sprite->szt > rover->sz || r2->sprite->sz < rover->szt) continue; - if (r2->sprite->scale > rover->scale) + if (r2->sprite->scale > rover->scale + || (r2->sprite->scale == rover->scale && r2->sprite->dispoffset > rover->dispoffset)) { entry = R_CreateDrawNode(NULL); (entry->prev = r2->prev)->next = entry; @@ -2039,21 +2101,21 @@ void R_ClipSprites(void) if (spr->gzt <= ds->tsilheight) silhouette &= ~SIL_TOP; - if (silhouette == 1) + if (silhouette == SIL_BOTTOM) { // bottom sil for (x = r1; x <= r2; x++) if (spr->clipbot[x] == -2) spr->clipbot[x] = ds->sprbottomclip[x]; } - else if (silhouette == 2) + else if (silhouette == SIL_TOP) { // top sil for (x = r1; x <= r2; x++) if (spr->cliptop[x] == -2) spr->cliptop[x] = ds->sprtopclip[x]; } - else if (silhouette == 3) + else if (silhouette == (SIL_TOP|SIL_BOTTOM)) { // both for (x = r1; x <= r2; x++) @@ -2234,7 +2296,7 @@ static void Sk_SetDefaultValue(skin_t *skin) strncpy(skin->face, "MISSING", 8); strncpy(skin->superface, "MISSING", 8); - skin->starttranscolor = 160; + skin->starttranscolor = 96; skin->prefcolor = SKINCOLOR_GREEN; skin->normalspeed = 36<flags &= ~SF_SUPER; - // Add sprites { UINT16 z; diff --git a/src/r_things.h b/src/r_things.h index 054a6497d..3e2d13fd7 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -162,6 +162,7 @@ typedef struct vissprite_s boolean precip; boolean vflip; // Flip vertically boolean isScaled; + INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing } vissprite_t; // A drawnode is something that points to a 3D floor, 3D side, or masked diff --git a/src/s_sound.c b/src/s_sound.c index 14a8cc425..49373d94c 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -141,14 +141,6 @@ typedef struct static channel_t *channels = NULL; static INT32 numofchannels = 0; -// whether songs are mus_paused -static boolean mus_paused = 0; - -// music currently being played -musicinfo_t *mus_playing = 0; - -static INT32 nextcleanup; - // // Internals. // @@ -307,47 +299,6 @@ static void SetChannelsNum(void) channels[i].sfxinfo = 0; } -// -// Initializes sound stuff, including volume -// Sets channels, SFX and music volume, -// allocates channel buffer, sets S_sfx lookup. -// -void S_Init(INT32 sfxVolume, INT32 digMusicVolume, INT32 midiMusicVolume) -{ - INT32 i; - - if (dedicated) - return; - - S_SetSfxVolume(sfxVolume); - S_SetDigMusicVolume(digMusicVolume); - S_SetMIDIMusicVolume(midiMusicVolume); - - SetChannelsNum(); - - // no sounds are playing, and they are not mus_paused - mus_paused = 0; - - // Note that sounds have not been cached (yet). - for (i = 1; i < NUMSFX; i++) - { - S_sfx[i].usefulness = -1; // for I_GetSfx() - S_sfx[i].lumpnum = LUMPERROR; - } - - // precache sounds if requested by cmdline, or precachesound var true - if (!nosound && (M_CheckParm("-precachesound") || precachesound.value)) - { - // Initialize external data (all sounds) at start, keep static. - CONS_Printf(M_GetText("Loading sounds... ")); - - for (i = 1; i < NUMSFX; i++) - if (S_sfx[i].name) - S_sfx[i].data = I_GetSfx(&S_sfx[i]); - - CONS_Printf(M_GetText(" pre-cached all sound data\n")); - } -} // Retrieve the lump number of sfx // @@ -371,12 +322,6 @@ lumpnum_t S_GetSfxLumpNum(sfxinfo_t *sfx) return W_GetNumForName("dsthok"); } -// -// Per level startup code. -// Kills playing sounds at start of level, -// determines music if any, changes music. -// - // Stop all sounds, load level info, THEN start sounds. void S_StopSounds(void) { @@ -442,22 +387,6 @@ void S_StopSoundByNum(sfxenum_t sfxnum) } } -void S_Start(void) -{ - if (mapmusic & MUSIC_RELOADRESET) - { - mapmusic = mapheaderinfo[gamemap-1]->musicslot - | (mapheaderinfo[gamemap-1]->musicslottrack << MUSIC_TRACKSHIFT); - } - - mus_paused = 0; - - if (cv_resetmusic.value) - S_StopMusic(); - S_ChangeMusic(mapmusic, true); - nextcleanup = 15; -} - void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume) { INT32 sep, pitch, priority, cnum; @@ -745,43 +674,6 @@ void S_StopSound(void *origin) } } -// -// Stop and resume music, during game PAUSE. -// -void S_PauseSound(void) -{ - if (!nodigimusic) - I_PauseSong(0); - - if (mus_playing && !mus_paused) - { - I_PauseSong(mus_playing->handle); - mus_paused = true; - } - - // pause cd music -#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) - I_PauseCD(); -#else - I_StopCD(); -#endif -} - -void S_ResumeSound(void) -{ - if (!nodigimusic) - I_ResumeSong(0); - else - if (mus_playing && mus_paused) - { - I_ResumeSong(mus_playing->handle); - mus_paused = false; - } - - // resume cd music - I_ResumeCD(); -} - // // Updates music & sounds // @@ -883,38 +775,6 @@ void S_UpdateSounds(void) } } - // Clean up unused data. -#if 0 - { - static tic_t nextcleanup = 0; - size_t i; - sfxinfo_t *sfx; - - if (!gametic) nextcleanup = 0; - if (gametic > nextcleanup) - { - for (i = 1; i < NUMSFX; i++) - { - if (S_sfx[i].usefulness == 0) - { - S_sfx[i].usefulness--; - - // don't forget to unlock it !!! - // __dmpi_unlock_.... - //Z_ChangeTag(S_sfx[i].data, PU_CACHE); - I_FreeSfx(S_sfx+i); - //S_sfx[i].data = 0; - - CONS_Debug(DBG_GAMELOGIC, "flushed sfx %.6s\n", S_sfx[i].name); - } - } - nextcleanup = gametic + 15; - } - } -#endif - - // FIXTHIS: nextcleanup is probably unused - for (cnum = 0; cnum < numofchannels; cnum++) { c = &channels[cnum]; @@ -984,37 +844,6 @@ void S_UpdateSounds(void) I_UpdateSound(); } -void S_SetDigMusicVolume(INT32 volume) -{ - if (volume < 0 || volume > 31) - CONS_Alert(CONS_WARNING, "musicvolume should be between 0-31\n"); - - CV_SetValue(&cv_digmusicvolume, volume&31); - actualdigmusicvolume = cv_digmusicvolume.value; //check for change of var - -#ifdef DJGPPDOS - I_SetDigMusicVolume(31); // Trick for buggy dos drivers. Win32 doesn't need this. -#endif - - if (!nodigimusic) - I_SetDigMusicVolume(volume&31); -} - -void S_SetMIDIMusicVolume(INT32 volume) -{ - if (volume < 0 || volume > 31) - CONS_Alert(CONS_WARNING, "musicvolume should be between 0-31\n"); - - CV_SetValue(&cv_midimusicvolume, volume&0x1f); - actualmidimusicvolume = cv_midimusicvolume.value; //check for change of var - -#ifdef DJGPPDOS - I_SetMIDIMusicVolume(31); // Trick for buggy dos drivers. Win32 doesn't need this. -#endif - - I_SetMIDIMusicVolume(volume&0x1f); -} - void S_SetSfxVolume(INT32 volume) { if (volume < 0 || volume > 31) @@ -1031,137 +860,6 @@ void S_SetSfxVolume(INT32 volume) #endif } -static boolean S_MIDIMusic(musicinfo_t *music, boolean looping) -{ - if (nomidimusic) - return true; // no error - - if (music_disabled) - return true; // no error - - // get lumpnum if neccessary - if (!music->lumpnum) - { - if (W_CheckNumForName(va("d_%s", music->name)) == LUMPERROR) - return false; - music->lumpnum = W_GetNumForName(va("d_%s", music->name)); - } - - // load & register it - music->data = W_CacheLumpNum(music->lumpnum, PU_MUSIC); -#if defined (macintosh) && !defined (HAVE_SDL) - music->handle = I_RegisterSong(music_num); -#else - music->handle = I_RegisterSong(music->data, W_LumpLength(music->lumpnum)); -#endif - -#ifdef MUSSERV - if (msg_id != -1) - { - struct musmsg msg_buffer; - - msg_buffer.msg_type = 6; - memset(msg_buffer.msg_text, 0, sizeof (msg_buffer.msg_text)); - sprintf(msg_buffer.msg_text, "d_%s", music->name); - msgsnd(msg_id, (struct msgbuf*)&msg_buffer, sizeof (msg_buffer.msg_text), IPC_NOWAIT); - } -#endif - - // play it - if (!I_PlaySong(music->handle, looping)) - return false; - - mus_playing = music; - return true; -} - -static boolean S_DigMusic(musicinfo_t *music, boolean looping) -{ - if (nodigimusic) - return false; // try midi - - if (digital_disabled) - return false; // try midi - - if (!I_StartDigSong(music->name, looping)) - return false; - - mus_playing = music; - return true; -} - -void S_ChangeMusic(UINT32 mslotnum, boolean looping) -{ - musicinfo_t *music; - musicenum_t music_num = (signed)(mslotnum & MUSIC_SONGMASK); - INT32 track_num = (mslotnum & MUSIC_TRACKMASK) >> MUSIC_TRACKSHIFT; - -#if defined (DC) || defined (_WIN32_WCE) || defined (PSP) || defined(GP2X) - S_ClearSfx(); -#endif - - if (nomidimusic && nodigimusic) - return; - - if (music_disabled && digital_disabled) - return; - - // No Music - if (music_num == mus_None) - { - S_StopMusic(); - return; - } - - if (music_num >= NUMMUSIC) - { - CONS_Alert(CONS_ERROR, "Bad music number %d\n", music_num); - return; - } - else - music = &S_music[music_num]; - - if (mus_playing != music) - { - S_StopMusic(); // shutdown old music - if (!S_DigMusic(music, looping) && !S_MIDIMusic(music, looping)) - { - CONS_Alert(CONS_ERROR, M_GetText("Music lump %.6s not found!\n"), music->name); - return; - } - } - I_SetSongTrack(track_num); -} - -boolean S_SpeedMusic(float speed) -{ - return I_SetSongSpeed(speed); -} - -void S_StopMusic(void) -{ - if (!mus_playing) - return; - - if (mus_paused) - I_ResumeSong(mus_playing->handle); - - if (!nodigimusic) - I_StopDigSong(); - - S_SpeedMusic(1.0f); - I_StopSong(mus_playing->handle); - I_UnRegisterSong(mus_playing->handle); - -#ifndef HAVE_SDL //SDL uses RWOPS - Z_ChangeTag(mus_playing->data, PU_CACHE); -#endif - - mus_playing->data = NULL; - mus_playing = NULL; - -} - void S_ClearSfx(void) { #ifndef DJGPPDOS @@ -1452,3 +1150,285 @@ void S_StartSoundName(void *mo, const char *soundname) S_StartSound(mo, soundnum); } + +/// ------------------------ +/// Music +/// ------------------------ + +#ifdef MUSICSLOT_COMPATIBILITY +const char *compat_special_music_slots[16] = +{ + "titles", // 1036 title screen + "read_m", // 1037 intro + "lclear", // 1038 level clear + "invinc", // 1039 invincibility + "shoes", // 1040 super sneakers + "minvnc", // 1041 Mario invincibility + "drown", // 1042 drowning + "gmover", // 1043 game over + "xtlife", // 1044 extra life + "contsc", // 1045 continue screen + "supers", // 1046 Super Sonic + "chrsel", // 1047 character select + "credit", // 1048 credits + "racent", // 1049 Race Results + "stjr", // 1050 Sonic Team Jr. Presents + "" +}; +#endif + +#define music_playing (music_name[0]) // String is empty if no music is playing + +static char music_name[7]; // up to 6-character name +static lumpnum_t music_lumpnum; // lump number of music (used??) +static void *music_data; // music raw data +static INT32 music_handle; // once registered, the handle for the music + +static boolean mus_paused = 0; // whether songs are mus_paused + +static boolean S_MIDIMusic(const char *mname, boolean looping) +{ + lumpnum_t mlumpnum; + void *mdata; + INT32 mhandle; + + if (nomidimusic || music_disabled) + return false; // didn't search. + + if (W_CheckNumForName(va("d_%s", mname)) == LUMPERROR) + return false; + mlumpnum = W_GetNumForName(va("d_%s", mname)); + + // load & register it + mdata = W_CacheLumpNum(mlumpnum, PU_MUSIC); + mhandle = I_RegisterSong(mdata, W_LumpLength(mlumpnum)); + +#ifdef MUSSERV + if (msg_id != -1) + { + struct musmsg msg_buffer; + + msg_buffer.msg_type = 6; + memset(msg_buffer.msg_text, 0, sizeof (msg_buffer.msg_text)); + sprintf(msg_buffer.msg_text, "d_%s", mname); + msgsnd(msg_id, (struct msgbuf*)&msg_buffer, sizeof (msg_buffer.msg_text), IPC_NOWAIT); + } +#endif + + // play it + if (!I_PlaySong(mhandle, looping)) + return false; + + strncpy(music_name, mname, 7); + music_name[6] = 0; + music_lumpnum = mlumpnum; + music_data = mdata; + music_handle = mhandle; + return true; +} + +static boolean S_DigMusic(const char *mname, boolean looping) +{ + if (nodigimusic || digital_disabled) + return false; // try midi + + if (!I_StartDigSong(mname, looping)) + return false; + + strncpy(music_name, mname, 7); + music_name[6] = 0; + music_lumpnum = LUMPERROR; + music_data = NULL; + music_handle = 0; + return true; +} + +void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping) +{ +#if defined (DC) || defined (_WIN32_WCE) || defined (PSP) || defined(GP2X) + S_ClearSfx(); +#endif + + if ((nomidimusic || music_disabled) && (nodigimusic || digital_disabled)) + return; + + // No Music (empty string) + if (mmusic[0] == 0) + { + S_StopMusic(); + return; + } + + if (strncmp(music_name, mmusic, 6)) + { + S_StopMusic(); // shutdown old music + if (!S_DigMusic(mmusic, looping) && !S_MIDIMusic(mmusic, looping)) + { + CONS_Alert(CONS_ERROR, M_GetText("Music lump %.6s not found!\n"), mmusic); + return; + } + } + I_SetSongTrack(mflags & MUSIC_TRACKMASK); +} + +boolean S_SpeedMusic(float speed) +{ + return I_SetSongSpeed(speed); +} + +void S_StopMusic(void) +{ + if (!music_playing) + return; + + if (mus_paused) + I_ResumeSong(music_handle); + + if (!nodigimusic) + I_StopDigSong(); + + S_SpeedMusic(1.0f); + I_StopSong(music_handle); + I_UnRegisterSong(music_handle); + +#ifndef HAVE_SDL //SDL uses RWOPS + Z_ChangeTag(music_data, PU_CACHE); +#endif + + music_data = NULL; + music_name[0] = 0; +} + +void S_SetDigMusicVolume(INT32 volume) +{ + if (volume < 0 || volume > 31) + CONS_Alert(CONS_WARNING, "musicvolume should be between 0-31\n"); + + CV_SetValue(&cv_digmusicvolume, volume&31); + actualdigmusicvolume = cv_digmusicvolume.value; //check for change of var + +#ifdef DJGPPDOS + I_SetDigMusicVolume(31); // Trick for buggy dos drivers. Win32 doesn't need this. +#endif + if (!nodigimusic) + I_SetDigMusicVolume(volume&31); +} + +void S_SetMIDIMusicVolume(INT32 volume) +{ + if (volume < 0 || volume > 31) + CONS_Alert(CONS_WARNING, "musicvolume should be between 0-31\n"); + + CV_SetValue(&cv_midimusicvolume, volume&0x1f); + actualmidimusicvolume = cv_midimusicvolume.value; //check for change of var + +#ifdef DJGPPDOS + I_SetMIDIMusicVolume(31); // Trick for buggy dos drivers. Win32 doesn't need this. +#endif + I_SetMIDIMusicVolume(volume&0x1f); +} + +/// ------------------------ +/// Init & Others +/// ------------------------ + +// +// Initializes sound stuff, including volume +// Sets channels, SFX and music volume, +// allocates channel buffer, sets S_sfx lookup. +// +void S_Init(INT32 sfxVolume, INT32 digMusicVolume, INT32 midiMusicVolume) +{ + INT32 i; + + if (dedicated) + return; + + S_SetSfxVolume(sfxVolume); + S_SetDigMusicVolume(digMusicVolume); + S_SetMIDIMusicVolume(midiMusicVolume); + + SetChannelsNum(); + + // no sounds are playing, and they are not mus_paused + mus_paused = 0; + + // Note that sounds have not been cached (yet). + for (i = 1; i < NUMSFX; i++) + { + S_sfx[i].usefulness = -1; // for I_GetSfx() + S_sfx[i].lumpnum = LUMPERROR; + } + + // precache sounds if requested by cmdline, or precachesound var true + if (!nosound && (M_CheckParm("-precachesound") || precachesound.value)) + { + // Initialize external data (all sounds) at start, keep static. + CONS_Printf(M_GetText("Loading sounds... ")); + + for (i = 1; i < NUMSFX; i++) + if (S_sfx[i].name) + S_sfx[i].data = I_GetSfx(&S_sfx[i]); + + CONS_Printf(M_GetText(" pre-cached all sound data\n")); + } +} + + +// +// Per level startup code. +// Kills playing sounds at start of level, +// determines music if any, changes music. +// +void S_Start(void) +{ + if (mapmusflags & MUSIC_RELOADRESET) + { + strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7); + mapmusname[6] = 0; + mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK); + } + + mus_paused = 0; + + if (cv_resetmusic.value) + S_StopMusic(); + S_ChangeMusic(mapmusname, mapmusflags, true); +} + +// +// Stop and resume music, during game PAUSE. +// +void S_PauseAudio(void) +{ + if (!nodigimusic) + I_PauseSong(0); + + if (music_playing && !mus_paused) + { + I_PauseSong(music_handle); + mus_paused = true; + } + + // pause cd music +#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) + I_PauseCD(); +#else + I_StopCD(); +#endif +} + +void S_ResumeAudio(void) +{ + if (!nodigimusic) + I_ResumeSong(0); + else + if (music_playing && mus_paused) + { + I_ResumeSong(music_handle); + mus_paused = false; + } + + // resume cd music + I_ResumeCD(); +} diff --git a/src/s_sound.h b/src/s_sound.h index 6589ca598..d5cf3570d 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -48,9 +48,6 @@ typedef enum extern consvar_t play_mode; #endif -//in case you're wondering why: I need to define this as extern so P_RestoreMusic can get to it so we don't do stupid song/speed changes -extern musicinfo_t *mus_playing; - typedef enum { SF_TOTALLYSINGLE = 1, // Only play one of these sounds at a time...GLOBALLY @@ -100,11 +97,12 @@ void S_StartSoundAtVolume(const void *origin, sfxenum_t sound_id, INT32 volume); // Stop sound for thing at void S_StopSound(void *origin); -// Start music using from sounds.h, and set whether looping -// note: music slot is first 16 bits for songnum, -// next 15 bits for tracknum (gme, other formats with more than one track) +// Start music track, arbitrary, given its name, and set whether looping +// note: music flags 12 bits for tracknum (gme, other formats with more than one track) +// 13-15 aren't used yet // and the last bit we ignore (internal game flag for resetting music on reload) -void S_ChangeMusic(UINT32 mslotnum, boolean looping); +#define S_ChangeMusicInternal(a,b) S_ChangeMusic(a,0,b) +void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping); // Set Speed of Music boolean S_SpeedMusic(float speed); @@ -113,8 +111,8 @@ boolean S_SpeedMusic(float speed); void S_StopMusic(void); // Stop and resume music, during game PAUSE. -void S_PauseSound(void); -void S_ResumeSound(void); +void S_PauseAudio(void); +void S_ResumeAudio(void); // // Updates music & sounds @@ -141,4 +139,10 @@ void S_StopSoundByNum(sfxenum_t sfxnum); #define S_StartScreamSound S_StartSound #endif +#ifdef MUSICSLOT_COMPATIBILITY +// For compatibility with code/scripts relying on older versions +// This is a list of all the "special" slot names and their associated numbers +const char *compat_special_music_slots[16]; +#endif + #endif diff --git a/src/sdl/CMakeLists.txt b/src/sdl/CMakeLists.txt index b3fa5390c..b3d734521 100644 --- a/src/sdl/CMakeLists.txt +++ b/src/sdl/CMakeLists.txt @@ -57,7 +57,7 @@ if(${SDL2_FOUND}) ${SRB2_SDL2_SOURCES} ${SRB2_SDL2_HEADERS} ) - + 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}) @@ -117,7 +117,7 @@ if(${SDL2_FOUND}) add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32 ${SRB2_SDL2_TOTAL_SOURCES}) set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME ${SRB2_SDL2_EXE_NAME}) - if(CLANG) + if((CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")) add_framework(CoreFoundation SRB2SDL2) add_framework(SDL2 SRB2SDL2) add_framework(SDL2_mixer SRB2SDL2) @@ -224,7 +224,7 @@ if(${SDL2_FOUND}) endif() #### Installation #### - if (CLANG) + if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") install(TARGETS SRB2SDL2 BUNDLE DESTINATION . ) @@ -265,7 +265,7 @@ if(${SDL2_FOUND}) # Mac bundle fixup - if(CLANG) + if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") install(CODE " include(BundleUtilities) fixup_bundle(\"${CMAKE_INSTALL_PREFIX}/Sonic Robo Blast 2.app\" @@ -279,4 +279,4 @@ if(${SDL2_FOUND}) else() message(WARNING "SDL2 was not found, so the SDL2 target will not be available.") set(SRB2_SDL2_AVAILABLE NO PARENT_SCOPE) -endif() \ No newline at end of file +endif() diff --git a/src/sdl/Makefile.cfg b/src/sdl/Makefile.cfg index 3b92a9fb8..b54f7057c 100644 --- a/src/sdl/Makefile.cfg +++ b/src/sdl/Makefile.cfg @@ -119,6 +119,12 @@ ifdef SDL_NET SDL_LDFLAGS+=-lSDL2_net endif +ifdef MINGW +ifndef NOSDLMAIN + SDLMAIN=1 +endif +endif + ifdef SDLMAIN OPTS+=-DSDLMAIN else diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 976f7eb35..74b61339b 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -55,6 +55,10 @@ PSP_MAIN_THREAD_STACK_SIZE_KB(256); #include "i_ttf.h" #endif +#if defined (_WIN32) && !defined (main) +//#define SDLMAIN +#endif + #ifdef SDLMAIN #include "SDL_main.h" #elif defined(FORCESDLMAIN) @@ -132,7 +136,6 @@ static inline VOID MakeCodeWritable(VOID) \return int */ -FUNCNORETURN #if defined (_XBOX) && defined (__GNUC__) void XBoxStartup() { @@ -141,8 +144,10 @@ void XBoxStartup() myargv = NULL; #else #ifdef FORCESDLMAIN +FUNCNORETURN int SDL_main(int argc, char **argv) #else +FUNCNORETURN int main(int argc, char **argv) #endif { diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 66e1ece18..2e9ebbede 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -23,7 +23,7 @@ #ifdef CMAKECONFIG #include "config.h" #else -#include "config.h.in" +#include "../config.h.in" #endif #ifndef _WIN32_WCE @@ -45,9 +45,6 @@ typedef DWORD (WINAPI *p_timeGetTime) (void); typedef UINT (WINAPI *p_timeEndPeriod) (UINT); typedef HANDLE (WINAPI *p_OpenFileMappingA) (DWORD, BOOL, LPCSTR); typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); -typedef HANDLE (WINAPI *p_GetCurrentProcess) (VOID); -typedef BOOL (WINAPI *p_GetProcessAffinityMask) (HANDLE, PDWORD_PTR, PDWORD_PTR); -typedef BOOL (WINAPI *p_SetProcessAffinityMask) (HANDLE, DWORD_PTR); #endif #endif #include @@ -2779,7 +2776,6 @@ static const char *locateWad(void) { return returnWadPath; } - #endif // examine default dirs @@ -3070,52 +3066,6 @@ const CPUInfoFlags *I_CPUInfo(void) #endif } -#if (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) -static void CPUAffinity_OnChange(void); -static consvar_t cv_cpuaffinity = {"cpuaffinity", "-1", CV_SAVE | CV_CALL, NULL, CPUAffinity_OnChange, 0, NULL, NULL, 0, 0, NULL}; - -static p_GetCurrentProcess pfnGetCurrentProcess = NULL; -static p_GetProcessAffinityMask pfnGetProcessAffinityMask = NULL; -static p_SetProcessAffinityMask pfnSetProcessAffinityMask = NULL; - -static inline VOID GetAffinityFuncs(VOID) -{ - HMODULE h = GetModuleHandleA("kernel32.dll"); - pfnGetCurrentProcess = (p_GetCurrentProcess)GetProcAddress(h, "GetCurrentProcess"); - pfnGetProcessAffinityMask = (p_GetProcessAffinityMask)GetProcAddress(h, "GetProcessAffinityMask"); - pfnSetProcessAffinityMask = (p_SetProcessAffinityMask)GetProcAddress(h, "SetProcessAffinityMask"); -} - -static void CPUAffinity_OnChange(void) -{ - DWORD_PTR dwProcMask, dwSysMask; - HANDLE selfpid; - - if (!pfnGetCurrentProcess || !pfnGetProcessAffinityMask || !pfnSetProcessAffinityMask) - return; - else - selfpid = pfnGetCurrentProcess(); - - pfnGetProcessAffinityMask(selfpid, &dwProcMask, &dwSysMask); - - /* If resulting mask is zero, don't change anything and fall back to - * actual mask. - */ - if(dwSysMask & cv_cpuaffinity.value) - { - pfnSetProcessAffinityMask(selfpid, dwSysMask & cv_cpuaffinity.value); - CV_StealthSetValue(&cv_cpuaffinity, (INT32)(dwSysMask & cv_cpuaffinity.value)); - } - else - CV_StealthSetValue(&cv_cpuaffinity, (INT32)dwProcMask); -} -#endif - -void I_RegisterSysCommands(void) -{ -#if (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) - GetAffinityFuncs(); - CV_RegisterVar(&cv_cpuaffinity); -#endif -} +// note CPUAFFINITY code used to reside here +void I_RegisterSysCommands(void) {} #endif diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index faee1bc69..963310a26 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -217,10 +217,12 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen) } } +#ifdef HWRENDER if (rendermode == render_opengl) { OglSdlSurface(vid.width, vid.height); } +#endif if (rendermode == render_soft) { @@ -401,9 +403,11 @@ static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code) default: break; } +#ifdef HWRENDER DBG_Printf("Unknown incoming scancode: %d, represented %c\n", code, SDL_GetKeyName(SDL_GetKeyFromScancode(code))); +#endif return 0; } @@ -1697,21 +1701,11 @@ void I_StartupGraphics(void) keyboard_started = true; #if !defined(HAVE_TTF) -#ifdef _WIN32 // Initialize Audio as well, otherwise Win32's DirectX can not use audio - if (SDL_InitSubSystem(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0) -#else //SDL_OpenAudio will do SDL_InitSubSystem(SDL_INIT_AUDIO) + // Previously audio was init here for questionable reasons? if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) -#endif { -#ifdef _WIN32 - if (SDL_WasInit(SDL_INIT_AUDIO)==0) - CONS_Printf(M_GetText("Couldn't initialize SDL's Audio System with Video System: %s\n"), SDL_GetError()); - if (SDL_WasInit(SDL_INIT_VIDEO)==0) -#endif - { - CONS_Printf(M_GetText("Couldn't initialize SDL's Video System: %s\n"), SDL_GetError()); - return; - } + CONS_Printf(M_GetText("Couldn't initialize SDL's Video System: %s\n"), SDL_GetError()); + return; } #endif { diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 71969209c..0f96f4733 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -77,7 +77,16 @@ static INT32 current_track; void I_StartupSound(void) { I_Assert(!sound_started); - sound_started = true; + + // EE inits audio first so we're following along. + if (SDL_WasInit(SDL_INIT_AUDIO) == SDL_INIT_AUDIO) + CONS_Printf("SDL Audio already started\n"); + else if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) + { + CONS_Alert(CONS_ERROR, "Error initializing SDL Audio: %s\n", SDL_GetError()); + // call to start audio failed -- we do not have it + return; + } midimode = false; music = NULL; @@ -86,19 +95,31 @@ void I_StartupSound(void) #if SDL_MIXER_VERSION_ATLEAST(1,2,11) Mix_Init(MIX_INIT_FLAC|MIX_INIT_MOD|MIX_INIT_MP3|MIX_INIT_OGG); #endif - Mix_OpenAudio(44100, AUDIO_S16LSB, 2, 2048); + + if (Mix_OpenAudio(44100, AUDIO_S16SYS, 2, 2048) < 0) + { + CONS_Alert(CONS_ERROR, "Error starting SDL_Mixer: %s\n", Mix_GetError()); + // call to start audio failed -- we do not have it + return; + } + + sound_started = true; Mix_AllocateChannels(256); } void I_ShutdownSound(void) { - I_Assert(sound_started); + if (!sound_started) + return; // not an error condition sound_started = false; Mix_CloseAudio(); #if SDL_MIXER_VERSION_ATLEAST(1,2,11) Mix_Quit(); #endif + + SDL_QuitSubSystem(SDL_INIT_AUDIO); + #ifdef HAVE_LIBGME if (gme) gme_delete(gme); @@ -374,6 +395,7 @@ void I_FreeSfx(sfxinfo_t *sfx) if (sfx->data) Mix_FreeChunk(sfx->data); sfx->data = NULL; + sfx->lumpnum = LUMPERROR; } INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority) diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c index 5d6c007b5..0face92e2 100644 --- a/src/sdl/sdl_sound.c +++ b/src/sdl/sdl_sound.c @@ -1213,6 +1213,16 @@ void I_StartupSound(void) // Configure sound device CONS_Printf("I_StartupSound:\n"); + // EE inits audio first so we're following along. + if (SDL_WasInit(SDL_INIT_AUDIO) == SDL_INIT_AUDIO) + CONS_Printf("SDL Audio already started\n"); + else if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) + { + CONS_Alert(CONS_ERROR, "Error initializing SDL Audio: %s\n", SDL_GetError()); + // call to start audio failed -- we do not have it + return; + } + // Open the audio device if (M_CheckParm ("-freq") && M_IsNextParm()) { diff --git a/src/sounds.c b/src/sounds.c index 1ec86e7bc..97bdf23ec 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -20,1067 +20,6 @@ #include "w_wad.h" #include "lua_script.h" -// -// Information about all the music -// - -musicinfo_t S_music[NUMMUSIC] = -{ - {NULL, 0, NULL, -1}, - {"map01m", 0, NULL, -1}, - {"map02m", 0, NULL, -1}, - {"map03m", 0, NULL, -1}, - {"map04m", 0, NULL, -1}, - {"map05m", 0, NULL, -1}, - {"map06m", 0, NULL, -1}, - {"map07m", 0, NULL, -1}, - {"map08m", 0, NULL, -1}, - {"map09m", 0, NULL, -1}, - {"map10m", 0, NULL, -1}, - {"map11m", 0, NULL, -1}, - {"map12m", 0, NULL, -1}, - {"map13m", 0, NULL, -1}, - {"map14m", 0, NULL, -1}, - {"map15m", 0, NULL, -1}, - {"map16m", 0, NULL, -1}, - {"map17m", 0, NULL, -1}, - {"map18m", 0, NULL, -1}, - {"map19m", 0, NULL, -1}, - {"map20m", 0, NULL, -1}, - {"map21m", 0, NULL, -1}, - {"map22m", 0, NULL, -1}, - {"map23m", 0, NULL, -1}, - {"map24m", 0, NULL, -1}, - {"map25m", 0, NULL, -1}, - {"map26m", 0, NULL, -1}, - {"map27m", 0, NULL, -1}, - {"map28m", 0, NULL, -1}, - {"map29m", 0, NULL, -1}, - {"map30m", 0, NULL, -1}, - {"map31m", 0, NULL, -1}, - {"map32m", 0, NULL, -1}, - {"map33m", 0, NULL, -1}, - {"map34m", 0, NULL, -1}, - {"map35m", 0, NULL, -1}, - {"map36m", 0, NULL, -1}, - {"map37m", 0, NULL, -1}, - {"map38m", 0, NULL, -1}, - {"map39m", 0, NULL, -1}, - {"map40m", 0, NULL, -1}, - {"map41m", 0, NULL, -1}, - {"map42m", 0, NULL, -1}, - {"map43m", 0, NULL, -1}, - {"map44m", 0, NULL, -1}, - {"map45m", 0, NULL, -1}, - {"map46m", 0, NULL, -1}, - {"map47m", 0, NULL, -1}, - {"map48m", 0, NULL, -1}, - {"map49m", 0, NULL, -1}, - {"map50m", 0, NULL, -1}, - {"map51m", 0, NULL, -1}, - {"map52m", 0, NULL, -1}, - {"map53m", 0, NULL, -1}, - {"map54m", 0, NULL, -1}, - {"map55m", 0, NULL, -1}, - {"map56m", 0, NULL, -1}, - {"map57m", 0, NULL, -1}, - {"map58m", 0, NULL, -1}, - {"map59m", 0, NULL, -1}, - {"map60m", 0, NULL, -1}, - {"map61m", 0, NULL, -1}, - {"map62m", 0, NULL, -1}, - {"map63m", 0, NULL, -1}, - {"map64m", 0, NULL, -1}, - {"map65m", 0, NULL, -1}, - {"map66m", 0, NULL, -1}, - {"map67m", 0, NULL, -1}, - {"map68m", 0, NULL, -1}, - {"map69m", 0, NULL, -1}, - {"map70m", 0, NULL, -1}, - {"map71m", 0, NULL, -1}, - {"map72m", 0, NULL, -1}, - {"map73m", 0, NULL, -1}, - {"map74m", 0, NULL, -1}, - {"map75m", 0, NULL, -1}, - {"map76m", 0, NULL, -1}, - {"map77m", 0, NULL, -1}, - {"map78m", 0, NULL, -1}, - {"map79m", 0, NULL, -1}, - {"map80m", 0, NULL, -1}, - {"map81m", 0, NULL, -1}, - {"map82m", 0, NULL, -1}, - {"map83m", 0, NULL, -1}, - {"map84m", 0, NULL, -1}, - {"map85m", 0, NULL, -1}, - {"map86m", 0, NULL, -1}, - {"map87m", 0, NULL, -1}, - {"map88m", 0, NULL, -1}, - {"map89m", 0, NULL, -1}, - {"map90m", 0, NULL, -1}, - {"map91m", 0, NULL, -1}, - {"map92m", 0, NULL, -1}, - {"map93m", 0, NULL, -1}, - {"map94m", 0, NULL, -1}, - {"map95m", 0, NULL, -1}, - {"map96m", 0, NULL, -1}, - {"map97m", 0, NULL, -1}, - {"map98m", 0, NULL, -1}, - {"map99m", 0, NULL, -1}, - {"mapa0m", 0, NULL, -1}, - {"mapa1m", 0, NULL, -1}, - {"mapa2m", 0, NULL, -1}, - {"mapa3m", 0, NULL, -1}, - {"mapa4m", 0, NULL, -1}, - {"mapa5m", 0, NULL, -1}, - {"mapa6m", 0, NULL, -1}, - {"mapa7m", 0, NULL, -1}, - {"mapa8m", 0, NULL, -1}, - {"mapa9m", 0, NULL, -1}, - {"mapaam", 0, NULL, -1}, - {"mapabm", 0, NULL, -1}, - {"mapacm", 0, NULL, -1}, - {"mapadm", 0, NULL, -1}, - {"mapaem", 0, NULL, -1}, - {"mapafm", 0, NULL, -1}, - {"mapagm", 0, NULL, -1}, - {"mapahm", 0, NULL, -1}, - {"mapaim", 0, NULL, -1}, - {"mapajm", 0, NULL, -1}, - {"mapakm", 0, NULL, -1}, - {"mapalm", 0, NULL, -1}, - {"mapamm", 0, NULL, -1}, - {"mapanm", 0, NULL, -1}, - {"mapaom", 0, NULL, -1}, - {"mapapm", 0, NULL, -1}, - {"mapaqm", 0, NULL, -1}, - {"maparm", 0, NULL, -1}, - {"mapasm", 0, NULL, -1}, - {"mapatm", 0, NULL, -1}, - {"mapaum", 0, NULL, -1}, - {"mapavm", 0, NULL, -1}, - {"mapawm", 0, NULL, -1}, - {"mapaxm", 0, NULL, -1}, - {"mapaym", 0, NULL, -1}, - {"mapazm", 0, NULL, -1}, - {"mapb0m", 0, NULL, -1}, - {"mapb1m", 0, NULL, -1}, - {"mapb2m", 0, NULL, -1}, - {"mapb3m", 0, NULL, -1}, - {"mapb4m", 0, NULL, -1}, - {"mapb5m", 0, NULL, -1}, - {"mapb6m", 0, NULL, -1}, - {"mapb7m", 0, NULL, -1}, - {"mapb8m", 0, NULL, -1}, - {"mapb9m", 0, NULL, -1}, - {"mapbam", 0, NULL, -1}, - {"mapbbm", 0, NULL, -1}, - {"mapbcm", 0, NULL, -1}, - {"mapbdm", 0, NULL, -1}, - {"mapbem", 0, NULL, -1}, - {"mapbfm", 0, NULL, -1}, - {"mapbgm", 0, NULL, -1}, - {"mapbhm", 0, NULL, -1}, - {"mapbim", 0, NULL, -1}, - {"mapbjm", 0, NULL, -1}, - {"mapbkm", 0, NULL, -1}, - {"mapblm", 0, NULL, -1}, - {"mapbmm", 0, NULL, -1}, - {"mapbnm", 0, NULL, -1}, - {"mapbom", 0, NULL, -1}, - {"mapbpm", 0, NULL, -1}, - {"mapbqm", 0, NULL, -1}, - {"mapbrm", 0, NULL, -1}, - {"mapbsm", 0, NULL, -1}, - {"mapbtm", 0, NULL, -1}, - {"mapbum", 0, NULL, -1}, - {"mapbvm", 0, NULL, -1}, - {"mapbwm", 0, NULL, -1}, - {"mapbxm", 0, NULL, -1}, - {"mapbym", 0, NULL, -1}, - {"mapbzm", 0, NULL, -1}, - {"mapc0m", 0, NULL, -1}, - {"mapc1m", 0, NULL, -1}, - {"mapc2m", 0, NULL, -1}, - {"mapc3m", 0, NULL, -1}, - {"mapc4m", 0, NULL, -1}, - {"mapc5m", 0, NULL, -1}, - {"mapc6m", 0, NULL, -1}, - {"mapc7m", 0, NULL, -1}, - {"mapc8m", 0, NULL, -1}, - {"mapc9m", 0, NULL, -1}, - {"mapcam", 0, NULL, -1}, - {"mapcbm", 0, NULL, -1}, - {"mapccm", 0, NULL, -1}, - {"mapcdm", 0, NULL, -1}, - {"mapcem", 0, NULL, -1}, - {"mapcfm", 0, NULL, -1}, - {"mapcgm", 0, NULL, -1}, - {"mapchm", 0, NULL, -1}, - {"mapcim", 0, NULL, -1}, - {"mapcjm", 0, NULL, -1}, - {"mapckm", 0, NULL, -1}, - {"mapclm", 0, NULL, -1}, - {"mapcmm", 0, NULL, -1}, - {"mapcnm", 0, NULL, -1}, - {"mapcom", 0, NULL, -1}, - {"mapcpm", 0, NULL, -1}, - {"mapcqm", 0, NULL, -1}, - {"mapcrm", 0, NULL, -1}, - {"mapcsm", 0, NULL, -1}, - {"mapctm", 0, NULL, -1}, - {"mapcum", 0, NULL, -1}, - {"mapcvm", 0, NULL, -1}, - {"mapcwm", 0, NULL, -1}, - {"mapcxm", 0, NULL, -1}, - {"mapcym", 0, NULL, -1}, - {"mapczm", 0, NULL, -1}, - {"mapd0m", 0, NULL, -1}, - {"mapd1m", 0, NULL, -1}, - {"mapd2m", 0, NULL, -1}, - {"mapd3m", 0, NULL, -1}, - {"mapd4m", 0, NULL, -1}, - {"mapd5m", 0, NULL, -1}, - {"mapd6m", 0, NULL, -1}, - {"mapd7m", 0, NULL, -1}, - {"mapd8m", 0, NULL, -1}, - {"mapd9m", 0, NULL, -1}, - {"mapdam", 0, NULL, -1}, - {"mapdbm", 0, NULL, -1}, - {"mapdcm", 0, NULL, -1}, - {"mapddm", 0, NULL, -1}, - {"mapdem", 0, NULL, -1}, - {"mapdfm", 0, NULL, -1}, - {"mapdgm", 0, NULL, -1}, - {"mapdhm", 0, NULL, -1}, - {"mapdim", 0, NULL, -1}, - {"mapdjm", 0, NULL, -1}, - {"mapdkm", 0, NULL, -1}, - {"mapdlm", 0, NULL, -1}, - {"mapdmm", 0, NULL, -1}, - {"mapdnm", 0, NULL, -1}, - {"mapdom", 0, NULL, -1}, - {"mapdpm", 0, NULL, -1}, - {"mapdqm", 0, NULL, -1}, - {"mapdrm", 0, NULL, -1}, - {"mapdsm", 0, NULL, -1}, - {"mapdtm", 0, NULL, -1}, - {"mapdum", 0, NULL, -1}, - {"mapdvm", 0, NULL, -1}, - {"mapdwm", 0, NULL, -1}, - {"mapdxm", 0, NULL, -1}, - {"mapdym", 0, NULL, -1}, - {"mapdzm", 0, NULL, -1}, - {"mape0m", 0, NULL, -1}, - {"mape1m", 0, NULL, -1}, - {"mape2m", 0, NULL, -1}, - {"mape3m", 0, NULL, -1}, - {"mape4m", 0, NULL, -1}, - {"mape5m", 0, NULL, -1}, - {"mape6m", 0, NULL, -1}, - {"mape7m", 0, NULL, -1}, - {"mape8m", 0, NULL, -1}, - {"mape9m", 0, NULL, -1}, - {"mapeam", 0, NULL, -1}, - {"mapebm", 0, NULL, -1}, - {"mapecm", 0, NULL, -1}, - {"mapedm", 0, NULL, -1}, - {"mapeem", 0, NULL, -1}, - {"mapefm", 0, NULL, -1}, - {"mapegm", 0, NULL, -1}, - {"mapehm", 0, NULL, -1}, - {"mapeim", 0, NULL, -1}, - {"mapejm", 0, NULL, -1}, - {"mapekm", 0, NULL, -1}, - {"mapelm", 0, NULL, -1}, - {"mapemm", 0, NULL, -1}, - {"mapenm", 0, NULL, -1}, - {"mapeom", 0, NULL, -1}, - {"mapepm", 0, NULL, -1}, - {"mapeqm", 0, NULL, -1}, - {"maperm", 0, NULL, -1}, - {"mapesm", 0, NULL, -1}, - {"mapetm", 0, NULL, -1}, - {"mapeum", 0, NULL, -1}, - {"mapevm", 0, NULL, -1}, - {"mapewm", 0, NULL, -1}, - {"mapexm", 0, NULL, -1}, - {"mapeym", 0, NULL, -1}, - {"mapezm", 0, NULL, -1}, - {"mapf0m", 0, NULL, -1}, - {"mapf1m", 0, NULL, -1}, - {"mapf2m", 0, NULL, -1}, - {"mapf3m", 0, NULL, -1}, - {"mapf4m", 0, NULL, -1}, - {"mapf5m", 0, NULL, -1}, - {"mapf6m", 0, NULL, -1}, - {"mapf7m", 0, NULL, -1}, - {"mapf8m", 0, NULL, -1}, - {"mapf9m", 0, NULL, -1}, - {"mapfam", 0, NULL, -1}, - {"mapfbm", 0, NULL, -1}, - {"mapfcm", 0, NULL, -1}, - {"mapfdm", 0, NULL, -1}, - {"mapfem", 0, NULL, -1}, - {"mapffm", 0, NULL, -1}, - {"mapfgm", 0, NULL, -1}, - {"mapfhm", 0, NULL, -1}, - {"mapfim", 0, NULL, -1}, - {"mapfjm", 0, NULL, -1}, - {"mapfkm", 0, NULL, -1}, - {"mapflm", 0, NULL, -1}, - {"mapfmm", 0, NULL, -1}, - {"mapfnm", 0, NULL, -1}, - {"mapfom", 0, NULL, -1}, - {"mapfpm", 0, NULL, -1}, - {"mapfqm", 0, NULL, -1}, - {"mapfrm", 0, NULL, -1}, - {"mapfsm", 0, NULL, -1}, - {"mapftm", 0, NULL, -1}, - {"mapfum", 0, NULL, -1}, - {"mapfvm", 0, NULL, -1}, - {"mapfwm", 0, NULL, -1}, - {"mapfxm", 0, NULL, -1}, - {"mapfym", 0, NULL, -1}, - {"mapfzm", 0, NULL, -1}, - {"mapg0m", 0, NULL, -1}, - {"mapg1m", 0, NULL, -1}, - {"mapg2m", 0, NULL, -1}, - {"mapg3m", 0, NULL, -1}, - {"mapg4m", 0, NULL, -1}, - {"mapg5m", 0, NULL, -1}, - {"mapg6m", 0, NULL, -1}, - {"mapg7m", 0, NULL, -1}, - {"mapg8m", 0, NULL, -1}, - {"mapg9m", 0, NULL, -1}, - {"mapgam", 0, NULL, -1}, - {"mapgbm", 0, NULL, -1}, - {"mapgcm", 0, NULL, -1}, - {"mapgdm", 0, NULL, -1}, - {"mapgem", 0, NULL, -1}, - {"mapgfm", 0, NULL, -1}, - {"mapggm", 0, NULL, -1}, - {"mapghm", 0, NULL, -1}, - {"mapgim", 0, NULL, -1}, - {"mapgjm", 0, NULL, -1}, - {"mapgkm", 0, NULL, -1}, - {"mapglm", 0, NULL, -1}, - {"mapgmm", 0, NULL, -1}, - {"mapgnm", 0, NULL, -1}, - {"mapgom", 0, NULL, -1}, - {"mapgpm", 0, NULL, -1}, - {"mapgqm", 0, NULL, -1}, - {"mapgrm", 0, NULL, -1}, - {"mapgsm", 0, NULL, -1}, - {"mapgtm", 0, NULL, -1}, - {"mapgum", 0, NULL, -1}, - {"mapgvm", 0, NULL, -1}, - {"mapgwm", 0, NULL, -1}, - {"mapgxm", 0, NULL, -1}, - {"mapgym", 0, NULL, -1}, - {"mapgzm", 0, NULL, -1}, - {"maph0m", 0, NULL, -1}, - {"maph1m", 0, NULL, -1}, - {"maph2m", 0, NULL, -1}, - {"maph3m", 0, NULL, -1}, - {"maph4m", 0, NULL, -1}, - {"maph5m", 0, NULL, -1}, - {"maph6m", 0, NULL, -1}, - {"maph7m", 0, NULL, -1}, - {"maph8m", 0, NULL, -1}, - {"maph9m", 0, NULL, -1}, - {"mapham", 0, NULL, -1}, - {"maphbm", 0, NULL, -1}, - {"maphcm", 0, NULL, -1}, - {"maphdm", 0, NULL, -1}, - {"maphem", 0, NULL, -1}, - {"maphfm", 0, NULL, -1}, - {"maphgm", 0, NULL, -1}, - {"maphhm", 0, NULL, -1}, - {"maphim", 0, NULL, -1}, - {"maphjm", 0, NULL, -1}, - {"maphkm", 0, NULL, -1}, - {"maphlm", 0, NULL, -1}, - {"maphmm", 0, NULL, -1}, - {"maphnm", 0, NULL, -1}, - {"maphom", 0, NULL, -1}, - {"maphpm", 0, NULL, -1}, - {"maphqm", 0, NULL, -1}, - {"maphrm", 0, NULL, -1}, - {"maphsm", 0, NULL, -1}, - {"maphtm", 0, NULL, -1}, - {"maphum", 0, NULL, -1}, - {"maphvm", 0, NULL, -1}, - {"maphwm", 0, NULL, -1}, - {"maphxm", 0, NULL, -1}, - {"maphym", 0, NULL, -1}, - {"maphzm", 0, NULL, -1}, - {"mapi0m", 0, NULL, -1}, - {"mapi1m", 0, NULL, -1}, - {"mapi2m", 0, NULL, -1}, - {"mapi3m", 0, NULL, -1}, - {"mapi4m", 0, NULL, -1}, - {"mapi5m", 0, NULL, -1}, - {"mapi6m", 0, NULL, -1}, - {"mapi7m", 0, NULL, -1}, - {"mapi8m", 0, NULL, -1}, - {"mapi9m", 0, NULL, -1}, - {"mapiam", 0, NULL, -1}, - {"mapibm", 0, NULL, -1}, - {"mapicm", 0, NULL, -1}, - {"mapidm", 0, NULL, -1}, - {"mapiem", 0, NULL, -1}, - {"mapifm", 0, NULL, -1}, - {"mapigm", 0, NULL, -1}, - {"mapihm", 0, NULL, -1}, - {"mapiim", 0, NULL, -1}, - {"mapijm", 0, NULL, -1}, - {"mapikm", 0, NULL, -1}, - {"mapilm", 0, NULL, -1}, - {"mapimm", 0, NULL, -1}, - {"mapinm", 0, NULL, -1}, - {"mapiom", 0, NULL, -1}, - {"mapipm", 0, NULL, -1}, - {"mapiqm", 0, NULL, -1}, - {"mapirm", 0, NULL, -1}, - {"mapism", 0, NULL, -1}, - {"mapitm", 0, NULL, -1}, - {"mapium", 0, NULL, -1}, - {"mapivm", 0, NULL, -1}, - {"mapiwm", 0, NULL, -1}, - {"mapixm", 0, NULL, -1}, - {"mapiym", 0, NULL, -1}, - {"mapizm", 0, NULL, -1}, - {"mapj0m", 0, NULL, -1}, - {"mapj1m", 0, NULL, -1}, - {"mapj2m", 0, NULL, -1}, - {"mapj3m", 0, NULL, -1}, - {"mapj4m", 0, NULL, -1}, - {"mapj5m", 0, NULL, -1}, - {"mapj6m", 0, NULL, -1}, - {"mapj7m", 0, NULL, -1}, - {"mapj8m", 0, NULL, -1}, - {"mapj9m", 0, NULL, -1}, - {"mapjam", 0, NULL, -1}, - {"mapjbm", 0, NULL, -1}, - {"mapjcm", 0, NULL, -1}, - {"mapjdm", 0, NULL, -1}, - {"mapjem", 0, NULL, -1}, - {"mapjfm", 0, NULL, -1}, - {"mapjgm", 0, NULL, -1}, - {"mapjhm", 0, NULL, -1}, - {"mapjim", 0, NULL, -1}, - {"mapjjm", 0, NULL, -1}, - {"mapjkm", 0, NULL, -1}, - {"mapjlm", 0, NULL, -1}, - {"mapjmm", 0, NULL, -1}, - {"mapjnm", 0, NULL, -1}, - {"mapjom", 0, NULL, -1}, - {"mapjpm", 0, NULL, -1}, - {"mapjqm", 0, NULL, -1}, - {"mapjrm", 0, NULL, -1}, - {"mapjsm", 0, NULL, -1}, - {"mapjtm", 0, NULL, -1}, - {"mapjum", 0, NULL, -1}, - {"mapjvm", 0, NULL, -1}, - {"mapjwm", 0, NULL, -1}, - {"mapjxm", 0, NULL, -1}, - {"mapjym", 0, NULL, -1}, - {"mapjzm", 0, NULL, -1}, - {"mapk0m", 0, NULL, -1}, - {"mapk1m", 0, NULL, -1}, - {"mapk2m", 0, NULL, -1}, - {"mapk3m", 0, NULL, -1}, - {"mapk4m", 0, NULL, -1}, - {"mapk5m", 0, NULL, -1}, - {"mapk6m", 0, NULL, -1}, - {"mapk7m", 0, NULL, -1}, - {"mapk8m", 0, NULL, -1}, - {"mapk9m", 0, NULL, -1}, - {"mapkam", 0, NULL, -1}, - {"mapkbm", 0, NULL, -1}, - {"mapkcm", 0, NULL, -1}, - {"mapkdm", 0, NULL, -1}, - {"mapkem", 0, NULL, -1}, - {"mapkfm", 0, NULL, -1}, - {"mapkgm", 0, NULL, -1}, - {"mapkhm", 0, NULL, -1}, - {"mapkim", 0, NULL, -1}, - {"mapkjm", 0, NULL, -1}, - {"mapkkm", 0, NULL, -1}, - {"mapklm", 0, NULL, -1}, - {"mapkmm", 0, NULL, -1}, - {"mapknm", 0, NULL, -1}, - {"mapkom", 0, NULL, -1}, - {"mapkpm", 0, NULL, -1}, - {"mapkqm", 0, NULL, -1}, - {"mapkrm", 0, NULL, -1}, - {"mapksm", 0, NULL, -1}, - {"mapktm", 0, NULL, -1}, - {"mapkum", 0, NULL, -1}, - {"mapkvm", 0, NULL, -1}, - {"mapkwm", 0, NULL, -1}, - {"mapkxm", 0, NULL, -1}, - {"mapkym", 0, NULL, -1}, - {"mapkzm", 0, NULL, -1}, - {"mapl0m", 0, NULL, -1}, - {"mapl1m", 0, NULL, -1}, - {"mapl2m", 0, NULL, -1}, - {"mapl3m", 0, NULL, -1}, - {"mapl4m", 0, NULL, -1}, - {"mapl5m", 0, NULL, -1}, - {"mapl6m", 0, NULL, -1}, - {"mapl7m", 0, NULL, -1}, - {"mapl8m", 0, NULL, -1}, - {"mapl9m", 0, NULL, -1}, - {"maplam", 0, NULL, -1}, - {"maplbm", 0, NULL, -1}, - {"maplcm", 0, NULL, -1}, - {"mapldm", 0, NULL, -1}, - {"maplem", 0, NULL, -1}, - {"maplfm", 0, NULL, -1}, - {"maplgm", 0, NULL, -1}, - {"maplhm", 0, NULL, -1}, - {"maplim", 0, NULL, -1}, - {"mapljm", 0, NULL, -1}, - {"maplkm", 0, NULL, -1}, - {"mapllm", 0, NULL, -1}, - {"maplmm", 0, NULL, -1}, - {"maplnm", 0, NULL, -1}, - {"maplom", 0, NULL, -1}, - {"maplpm", 0, NULL, -1}, - {"maplqm", 0, NULL, -1}, - {"maplrm", 0, NULL, -1}, - {"maplsm", 0, NULL, -1}, - {"mapltm", 0, NULL, -1}, - {"maplum", 0, NULL, -1}, - {"maplvm", 0, NULL, -1}, - {"maplwm", 0, NULL, -1}, - {"maplxm", 0, NULL, -1}, - {"maplym", 0, NULL, -1}, - {"maplzm", 0, NULL, -1}, - {"mapm0m", 0, NULL, -1}, - {"mapm1m", 0, NULL, -1}, - {"mapm2m", 0, NULL, -1}, - {"mapm3m", 0, NULL, -1}, - {"mapm4m", 0, NULL, -1}, - {"mapm5m", 0, NULL, -1}, - {"mapm6m", 0, NULL, -1}, - {"mapm7m", 0, NULL, -1}, - {"mapm8m", 0, NULL, -1}, - {"mapm9m", 0, NULL, -1}, - {"mapmam", 0, NULL, -1}, - {"mapmbm", 0, NULL, -1}, - {"mapmcm", 0, NULL, -1}, - {"mapmdm", 0, NULL, -1}, - {"mapmem", 0, NULL, -1}, - {"mapmfm", 0, NULL, -1}, - {"mapmgm", 0, NULL, -1}, - {"mapmhm", 0, NULL, -1}, - {"mapmim", 0, NULL, -1}, - {"mapmjm", 0, NULL, -1}, - {"mapmkm", 0, NULL, -1}, - {"mapmlm", 0, NULL, -1}, - {"mapmmm", 0, NULL, -1}, - {"mapmnm", 0, NULL, -1}, - {"mapmom", 0, NULL, -1}, - {"mapmpm", 0, NULL, -1}, - {"mapmqm", 0, NULL, -1}, - {"mapmrm", 0, NULL, -1}, - {"mapmsm", 0, NULL, -1}, - {"mapmtm", 0, NULL, -1}, - {"mapmum", 0, NULL, -1}, - {"mapmvm", 0, NULL, -1}, - {"mapmwm", 0, NULL, -1}, - {"mapmxm", 0, NULL, -1}, - {"mapmym", 0, NULL, -1}, - {"mapmzm", 0, NULL, -1}, - {"mapn0m", 0, NULL, -1}, - {"mapn1m", 0, NULL, -1}, - {"mapn2m", 0, NULL, -1}, - {"mapn3m", 0, NULL, -1}, - {"mapn4m", 0, NULL, -1}, - {"mapn5m", 0, NULL, -1}, - {"mapn6m", 0, NULL, -1}, - {"mapn7m", 0, NULL, -1}, - {"mapn8m", 0, NULL, -1}, - {"mapn9m", 0, NULL, -1}, - {"mapnam", 0, NULL, -1}, - {"mapnbm", 0, NULL, -1}, - {"mapncm", 0, NULL, -1}, - {"mapndm", 0, NULL, -1}, - {"mapnem", 0, NULL, -1}, - {"mapnfm", 0, NULL, -1}, - {"mapngm", 0, NULL, -1}, - {"mapnhm", 0, NULL, -1}, - {"mapnim", 0, NULL, -1}, - {"mapnjm", 0, NULL, -1}, - {"mapnkm", 0, NULL, -1}, - {"mapnlm", 0, NULL, -1}, - {"mapnmm", 0, NULL, -1}, - {"mapnnm", 0, NULL, -1}, - {"mapnom", 0, NULL, -1}, - {"mapnpm", 0, NULL, -1}, - {"mapnqm", 0, NULL, -1}, - {"mapnrm", 0, NULL, -1}, - {"mapnsm", 0, NULL, -1}, - {"mapntm", 0, NULL, -1}, - {"mapnum", 0, NULL, -1}, - {"mapnvm", 0, NULL, -1}, - {"mapnwm", 0, NULL, -1}, - {"mapnxm", 0, NULL, -1}, - {"mapnym", 0, NULL, -1}, - {"mapnzm", 0, NULL, -1}, - {"mapo0m", 0, NULL, -1}, - {"mapo1m", 0, NULL, -1}, - {"mapo2m", 0, NULL, -1}, - {"mapo3m", 0, NULL, -1}, - {"mapo4m", 0, NULL, -1}, - {"mapo5m", 0, NULL, -1}, - {"mapo6m", 0, NULL, -1}, - {"mapo7m", 0, NULL, -1}, - {"mapo8m", 0, NULL, -1}, - {"mapo9m", 0, NULL, -1}, - {"mapoam", 0, NULL, -1}, - {"mapobm", 0, NULL, -1}, - {"mapocm", 0, NULL, -1}, - {"mapodm", 0, NULL, -1}, - {"mapoem", 0, NULL, -1}, - {"mapofm", 0, NULL, -1}, - {"mapogm", 0, NULL, -1}, - {"mapohm", 0, NULL, -1}, - {"mapoim", 0, NULL, -1}, - {"mapojm", 0, NULL, -1}, - {"mapokm", 0, NULL, -1}, - {"mapolm", 0, NULL, -1}, - {"mapomm", 0, NULL, -1}, - {"maponm", 0, NULL, -1}, - {"mapoom", 0, NULL, -1}, - {"mapopm", 0, NULL, -1}, - {"mapoqm", 0, NULL, -1}, - {"maporm", 0, NULL, -1}, - {"maposm", 0, NULL, -1}, - {"mapotm", 0, NULL, -1}, - {"mapoum", 0, NULL, -1}, - {"mapovm", 0, NULL, -1}, - {"mapowm", 0, NULL, -1}, - {"mapoxm", 0, NULL, -1}, - {"mapoym", 0, NULL, -1}, - {"mapozm", 0, NULL, -1}, - {"mapp0m", 0, NULL, -1}, - {"mapp1m", 0, NULL, -1}, - {"mapp2m", 0, NULL, -1}, - {"mapp3m", 0, NULL, -1}, - {"mapp4m", 0, NULL, -1}, - {"mapp5m", 0, NULL, -1}, - {"mapp6m", 0, NULL, -1}, - {"mapp7m", 0, NULL, -1}, - {"mapp8m", 0, NULL, -1}, - {"mapp9m", 0, NULL, -1}, - {"mappam", 0, NULL, -1}, - {"mappbm", 0, NULL, -1}, - {"mappcm", 0, NULL, -1}, - {"mappdm", 0, NULL, -1}, - {"mappem", 0, NULL, -1}, - {"mappfm", 0, NULL, -1}, - {"mappgm", 0, NULL, -1}, - {"mapphm", 0, NULL, -1}, - {"mappim", 0, NULL, -1}, - {"mappjm", 0, NULL, -1}, - {"mappkm", 0, NULL, -1}, - {"mapplm", 0, NULL, -1}, - {"mappmm", 0, NULL, -1}, - {"mappnm", 0, NULL, -1}, - {"mappom", 0, NULL, -1}, - {"mapppm", 0, NULL, -1}, - {"mappqm", 0, NULL, -1}, - {"mapprm", 0, NULL, -1}, - {"mappsm", 0, NULL, -1}, - {"mapptm", 0, NULL, -1}, - {"mappum", 0, NULL, -1}, - {"mappvm", 0, NULL, -1}, - {"mappwm", 0, NULL, -1}, - {"mappxm", 0, NULL, -1}, - {"mappym", 0, NULL, -1}, - {"mappzm", 0, NULL, -1}, - {"mapq0m", 0, NULL, -1}, - {"mapq1m", 0, NULL, -1}, - {"mapq2m", 0, NULL, -1}, - {"mapq3m", 0, NULL, -1}, - {"mapq4m", 0, NULL, -1}, - {"mapq5m", 0, NULL, -1}, - {"mapq6m", 0, NULL, -1}, - {"mapq7m", 0, NULL, -1}, - {"mapq8m", 0, NULL, -1}, - {"mapq9m", 0, NULL, -1}, - {"mapqam", 0, NULL, -1}, - {"mapqbm", 0, NULL, -1}, - {"mapqcm", 0, NULL, -1}, - {"mapqdm", 0, NULL, -1}, - {"mapqem", 0, NULL, -1}, - {"mapqfm", 0, NULL, -1}, - {"mapqgm", 0, NULL, -1}, - {"mapqhm", 0, NULL, -1}, - {"mapqim", 0, NULL, -1}, - {"mapqjm", 0, NULL, -1}, - {"mapqkm", 0, NULL, -1}, - {"mapqlm", 0, NULL, -1}, - {"mapqmm", 0, NULL, -1}, - {"mapqnm", 0, NULL, -1}, - {"mapqom", 0, NULL, -1}, - {"mapqpm", 0, NULL, -1}, - {"mapqqm", 0, NULL, -1}, - {"mapqrm", 0, NULL, -1}, - {"mapqsm", 0, NULL, -1}, - {"mapqtm", 0, NULL, -1}, - {"mapqum", 0, NULL, -1}, - {"mapqvm", 0, NULL, -1}, - {"mapqwm", 0, NULL, -1}, - {"mapqxm", 0, NULL, -1}, - {"mapqym", 0, NULL, -1}, - {"mapqzm", 0, NULL, -1}, - {"mapr0m", 0, NULL, -1}, - {"mapr1m", 0, NULL, -1}, - {"mapr2m", 0, NULL, -1}, - {"mapr3m", 0, NULL, -1}, - {"mapr4m", 0, NULL, -1}, - {"mapr5m", 0, NULL, -1}, - {"mapr6m", 0, NULL, -1}, - {"mapr7m", 0, NULL, -1}, - {"mapr8m", 0, NULL, -1}, - {"mapr9m", 0, NULL, -1}, - {"mapram", 0, NULL, -1}, - {"maprbm", 0, NULL, -1}, - {"maprcm", 0, NULL, -1}, - {"maprdm", 0, NULL, -1}, - {"maprem", 0, NULL, -1}, - {"maprfm", 0, NULL, -1}, - {"maprgm", 0, NULL, -1}, - {"maprhm", 0, NULL, -1}, - {"maprim", 0, NULL, -1}, - {"maprjm", 0, NULL, -1}, - {"maprkm", 0, NULL, -1}, - {"maprlm", 0, NULL, -1}, - {"maprmm", 0, NULL, -1}, - {"maprnm", 0, NULL, -1}, - {"maprom", 0, NULL, -1}, - {"maprpm", 0, NULL, -1}, - {"maprqm", 0, NULL, -1}, - {"maprrm", 0, NULL, -1}, - {"maprsm", 0, NULL, -1}, - {"maprtm", 0, NULL, -1}, - {"maprum", 0, NULL, -1}, - {"maprvm", 0, NULL, -1}, - {"maprwm", 0, NULL, -1}, - {"maprxm", 0, NULL, -1}, - {"maprym", 0, NULL, -1}, - {"maprzm", 0, NULL, -1}, - {"maps0m", 0, NULL, -1}, - {"maps1m", 0, NULL, -1}, - {"maps2m", 0, NULL, -1}, - {"maps3m", 0, NULL, -1}, - {"maps4m", 0, NULL, -1}, - {"maps5m", 0, NULL, -1}, - {"maps6m", 0, NULL, -1}, - {"maps7m", 0, NULL, -1}, - {"maps8m", 0, NULL, -1}, - {"maps9m", 0, NULL, -1}, - {"mapsam", 0, NULL, -1}, - {"mapsbm", 0, NULL, -1}, - {"mapscm", 0, NULL, -1}, - {"mapsdm", 0, NULL, -1}, - {"mapsem", 0, NULL, -1}, - {"mapsfm", 0, NULL, -1}, - {"mapsgm", 0, NULL, -1}, - {"mapshm", 0, NULL, -1}, - {"mapsim", 0, NULL, -1}, - {"mapsjm", 0, NULL, -1}, - {"mapskm", 0, NULL, -1}, - {"mapslm", 0, NULL, -1}, - {"mapsmm", 0, NULL, -1}, - {"mapsnm", 0, NULL, -1}, - {"mapsom", 0, NULL, -1}, - {"mapspm", 0, NULL, -1}, - {"mapsqm", 0, NULL, -1}, - {"mapsrm", 0, NULL, -1}, - {"mapssm", 0, NULL, -1}, - {"mapstm", 0, NULL, -1}, - {"mapsum", 0, NULL, -1}, - {"mapsvm", 0, NULL, -1}, - {"mapswm", 0, NULL, -1}, - {"mapsxm", 0, NULL, -1}, - {"mapsym", 0, NULL, -1}, - {"mapszm", 0, NULL, -1}, - {"mapt0m", 0, NULL, -1}, - {"mapt1m", 0, NULL, -1}, - {"mapt2m", 0, NULL, -1}, - {"mapt3m", 0, NULL, -1}, - {"mapt4m", 0, NULL, -1}, - {"mapt5m", 0, NULL, -1}, - {"mapt6m", 0, NULL, -1}, - {"mapt7m", 0, NULL, -1}, - {"mapt8m", 0, NULL, -1}, - {"mapt9m", 0, NULL, -1}, - {"maptam", 0, NULL, -1}, - {"maptbm", 0, NULL, -1}, - {"maptcm", 0, NULL, -1}, - {"maptdm", 0, NULL, -1}, - {"maptem", 0, NULL, -1}, - {"maptfm", 0, NULL, -1}, - {"maptgm", 0, NULL, -1}, - {"mapthm", 0, NULL, -1}, - {"maptim", 0, NULL, -1}, - {"maptjm", 0, NULL, -1}, - {"maptkm", 0, NULL, -1}, - {"maptlm", 0, NULL, -1}, - {"maptmm", 0, NULL, -1}, - {"maptnm", 0, NULL, -1}, - {"maptom", 0, NULL, -1}, - {"maptpm", 0, NULL, -1}, - {"maptqm", 0, NULL, -1}, - {"maptrm", 0, NULL, -1}, - {"maptsm", 0, NULL, -1}, - {"mapttm", 0, NULL, -1}, - {"maptum", 0, NULL, -1}, - {"maptvm", 0, NULL, -1}, - {"maptwm", 0, NULL, -1}, - {"maptxm", 0, NULL, -1}, - {"maptym", 0, NULL, -1}, - {"maptzm", 0, NULL, -1}, - {"mapu0m", 0, NULL, -1}, - {"mapu1m", 0, NULL, -1}, - {"mapu2m", 0, NULL, -1}, - {"mapu3m", 0, NULL, -1}, - {"mapu4m", 0, NULL, -1}, - {"mapu5m", 0, NULL, -1}, - {"mapu6m", 0, NULL, -1}, - {"mapu7m", 0, NULL, -1}, - {"mapu8m", 0, NULL, -1}, - {"mapu9m", 0, NULL, -1}, - {"mapuam", 0, NULL, -1}, - {"mapubm", 0, NULL, -1}, - {"mapucm", 0, NULL, -1}, - {"mapudm", 0, NULL, -1}, - {"mapuem", 0, NULL, -1}, - {"mapufm", 0, NULL, -1}, - {"mapugm", 0, NULL, -1}, - {"mapuhm", 0, NULL, -1}, - {"mapuim", 0, NULL, -1}, - {"mapujm", 0, NULL, -1}, - {"mapukm", 0, NULL, -1}, - {"mapulm", 0, NULL, -1}, - {"mapumm", 0, NULL, -1}, - {"mapunm", 0, NULL, -1}, - {"mapuom", 0, NULL, -1}, - {"mapupm", 0, NULL, -1}, - {"mapuqm", 0, NULL, -1}, - {"mapurm", 0, NULL, -1}, - {"mapusm", 0, NULL, -1}, - {"maputm", 0, NULL, -1}, - {"mapuum", 0, NULL, -1}, - {"mapuvm", 0, NULL, -1}, - {"mapuwm", 0, NULL, -1}, - {"mapuxm", 0, NULL, -1}, - {"mapuym", 0, NULL, -1}, - {"mapuzm", 0, NULL, -1}, - {"mapv0m", 0, NULL, -1}, - {"mapv1m", 0, NULL, -1}, - {"mapv2m", 0, NULL, -1}, - {"mapv3m", 0, NULL, -1}, - {"mapv4m", 0, NULL, -1}, - {"mapv5m", 0, NULL, -1}, - {"mapv6m", 0, NULL, -1}, - {"mapv7m", 0, NULL, -1}, - {"mapv8m", 0, NULL, -1}, - {"mapv9m", 0, NULL, -1}, - {"mapvam", 0, NULL, -1}, - {"mapvbm", 0, NULL, -1}, - {"mapvcm", 0, NULL, -1}, - {"mapvdm", 0, NULL, -1}, - {"mapvem", 0, NULL, -1}, - {"mapvfm", 0, NULL, -1}, - {"mapvgm", 0, NULL, -1}, - {"mapvhm", 0, NULL, -1}, - {"mapvim", 0, NULL, -1}, - {"mapvjm", 0, NULL, -1}, - {"mapvkm", 0, NULL, -1}, - {"mapvlm", 0, NULL, -1}, - {"mapvmm", 0, NULL, -1}, - {"mapvnm", 0, NULL, -1}, - {"mapvom", 0, NULL, -1}, - {"mapvpm", 0, NULL, -1}, - {"mapvqm", 0, NULL, -1}, - {"mapvrm", 0, NULL, -1}, - {"mapvsm", 0, NULL, -1}, - {"mapvtm", 0, NULL, -1}, - {"mapvum", 0, NULL, -1}, - {"mapvvm", 0, NULL, -1}, - {"mapvwm", 0, NULL, -1}, - {"mapvxm", 0, NULL, -1}, - {"mapvym", 0, NULL, -1}, - {"mapvzm", 0, NULL, -1}, - {"mapw0m", 0, NULL, -1}, - {"mapw1m", 0, NULL, -1}, - {"mapw2m", 0, NULL, -1}, - {"mapw3m", 0, NULL, -1}, - {"mapw4m", 0, NULL, -1}, - {"mapw5m", 0, NULL, -1}, - {"mapw6m", 0, NULL, -1}, - {"mapw7m", 0, NULL, -1}, - {"mapw8m", 0, NULL, -1}, - {"mapw9m", 0, NULL, -1}, - {"mapwam", 0, NULL, -1}, - {"mapwbm", 0, NULL, -1}, - {"mapwcm", 0, NULL, -1}, - {"mapwdm", 0, NULL, -1}, - {"mapwem", 0, NULL, -1}, - {"mapwfm", 0, NULL, -1}, - {"mapwgm", 0, NULL, -1}, - {"mapwhm", 0, NULL, -1}, - {"mapwim", 0, NULL, -1}, - {"mapwjm", 0, NULL, -1}, - {"mapwkm", 0, NULL, -1}, - {"mapwlm", 0, NULL, -1}, - {"mapwmm", 0, NULL, -1}, - {"mapwnm", 0, NULL, -1}, - {"mapwom", 0, NULL, -1}, - {"mapwpm", 0, NULL, -1}, - {"mapwqm", 0, NULL, -1}, - {"mapwrm", 0, NULL, -1}, - {"mapwsm", 0, NULL, -1}, - {"mapwtm", 0, NULL, -1}, - {"mapwum", 0, NULL, -1}, - {"mapwvm", 0, NULL, -1}, - {"mapwwm", 0, NULL, -1}, - {"mapwxm", 0, NULL, -1}, - {"mapwym", 0, NULL, -1}, - {"mapwzm", 0, NULL, -1}, - {"mapx0m", 0, NULL, -1}, - {"mapx1m", 0, NULL, -1}, - {"mapx2m", 0, NULL, -1}, - {"mapx3m", 0, NULL, -1}, - {"mapx4m", 0, NULL, -1}, - {"mapx5m", 0, NULL, -1}, - {"mapx6m", 0, NULL, -1}, - {"mapx7m", 0, NULL, -1}, - {"mapx8m", 0, NULL, -1}, - {"mapx9m", 0, NULL, -1}, - {"mapxam", 0, NULL, -1}, - {"mapxbm", 0, NULL, -1}, - {"mapxcm", 0, NULL, -1}, - {"mapxdm", 0, NULL, -1}, - {"mapxem", 0, NULL, -1}, - {"mapxfm", 0, NULL, -1}, - {"mapxgm", 0, NULL, -1}, - {"mapxhm", 0, NULL, -1}, - {"mapxim", 0, NULL, -1}, - {"mapxjm", 0, NULL, -1}, - {"mapxkm", 0, NULL, -1}, - {"mapxlm", 0, NULL, -1}, - {"mapxmm", 0, NULL, -1}, - {"mapxnm", 0, NULL, -1}, - {"mapxom", 0, NULL, -1}, - {"mapxpm", 0, NULL, -1}, - {"mapxqm", 0, NULL, -1}, - {"mapxrm", 0, NULL, -1}, - {"mapxsm", 0, NULL, -1}, - {"mapxtm", 0, NULL, -1}, - {"mapxum", 0, NULL, -1}, - {"mapxvm", 0, NULL, -1}, - {"mapxwm", 0, NULL, -1}, - {"mapxxm", 0, NULL, -1}, - {"mapxym", 0, NULL, -1}, - {"mapxzm", 0, NULL, -1}, - {"mapy0m", 0, NULL, -1}, - {"mapy1m", 0, NULL, -1}, - {"mapy2m", 0, NULL, -1}, - {"mapy3m", 0, NULL, -1}, - {"mapy4m", 0, NULL, -1}, - {"mapy5m", 0, NULL, -1}, - {"mapy6m", 0, NULL, -1}, - {"mapy7m", 0, NULL, -1}, - {"mapy8m", 0, NULL, -1}, - {"mapy9m", 0, NULL, -1}, - {"mapyam", 0, NULL, -1}, - {"mapybm", 0, NULL, -1}, - {"mapycm", 0, NULL, -1}, - {"mapydm", 0, NULL, -1}, - {"mapyem", 0, NULL, -1}, - {"mapyfm", 0, NULL, -1}, - {"mapygm", 0, NULL, -1}, - {"mapyhm", 0, NULL, -1}, - {"mapyim", 0, NULL, -1}, - {"mapyjm", 0, NULL, -1}, - {"mapykm", 0, NULL, -1}, - {"mapylm", 0, NULL, -1}, - {"mapymm", 0, NULL, -1}, - {"mapynm", 0, NULL, -1}, - {"mapyom", 0, NULL, -1}, - {"mapypm", 0, NULL, -1}, - {"mapyqm", 0, NULL, -1}, - {"mapyrm", 0, NULL, -1}, - {"mapysm", 0, NULL, -1}, - {"mapytm", 0, NULL, -1}, - {"mapyum", 0, NULL, -1}, - {"mapyvm", 0, NULL, -1}, - {"mapywm", 0, NULL, -1}, - {"mapyxm", 0, NULL, -1}, - {"mapyym", 0, NULL, -1}, - {"mapyzm", 0, NULL, -1}, - {"mapz0m", 0, NULL, -1}, - {"mapz1m", 0, NULL, -1}, - {"mapz2m", 0, NULL, -1}, - {"mapz3m", 0, NULL, -1}, - {"mapz4m", 0, NULL, -1}, - {"mapz5m", 0, NULL, -1}, - {"mapz6m", 0, NULL, -1}, - {"mapz7m", 0, NULL, -1}, - {"mapz8m", 0, NULL, -1}, - {"mapz9m", 0, NULL, -1}, - {"mapzam", 0, NULL, -1}, - {"mapzbm", 0, NULL, -1}, - {"mapzcm", 0, NULL, -1}, - {"mapzdm", 0, NULL, -1}, - {"mapzem", 0, NULL, -1}, - {"mapzfm", 0, NULL, -1}, - {"mapzgm", 0, NULL, -1}, - {"mapzhm", 0, NULL, -1}, - {"mapzim", 0, NULL, -1}, - {"mapzjm", 0, NULL, -1}, - {"mapzkm", 0, NULL, -1}, - {"mapzlm", 0, NULL, -1}, - {"mapzmm", 0, NULL, -1}, - {"mapznm", 0, NULL, -1}, - {"mapzom", 0, NULL, -1}, - {"mapzpm", 0, NULL, -1}, - {"mapzqm", 0, NULL, -1}, - {"mapzrm", 0, NULL, -1}, - {"mapzsm", 0, NULL, -1}, - {"mapztm", 0, NULL, -1}, - {"mapzum", 0, NULL, -1}, - {"mapzvm", 0, NULL, -1}, - {"mapzwm", 0, NULL, -1}, - {"mapzxm", 0, NULL, -1}, - {"mapzym", 0, NULL, -1}, - {"mapzzm", 0, NULL, -1}, - - {"titles", 0, NULL, -1}, // Title screen - {"read_m", 0, NULL, -1}, // Intro - {"lclear", 0, NULL, -1}, // Level clear - {"invinc", 0, NULL, -1}, // Invincibility - {"shoes", 0, NULL, -1}, // Super sneakers - {"minvnc", 0, NULL, -1}, // Mario invincibility - {"drown", 0, NULL, -1}, // Drowning - {"gmover", 0, NULL, -1}, // Game over - {"xtlife", 0, NULL, -1}, // Extra life - {"contsc", 0, NULL, -1}, // Continue screen - {"supers", 0, NULL, -1}, // Super Sonic - {"chrsel", 0, NULL, -1}, // Character select - {"credit", 0, NULL, -1}, // Credits - {"racent", 0, NULL, -1}, // Race Results - {"stjr", 0, NULL, -1}, // Sonic Team Jr. Presents -}; - - // // Information about all the sfx // diff --git a/src/sounds.h b/src/sounds.h index c5851a346..4388d02cf 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -86,1095 +86,9 @@ struct sfxinfo_struct lumpnum_t lumpnum; }; -// -// MusicInfo struct. -// -typedef struct -{ - // up to 6-character name - const char *name; - - // lump number of music - lumpnum_t lumpnum; - - // music data - void *data; - - // music handle once registered - INT32 handle; -} musicinfo_t; - // the complete set of sound effects extern sfxinfo_t S_sfx[]; -// the complete set of music -extern musicinfo_t S_music[]; - -// -// Identifiers for all music in game. -// - -// Music list (don't edit this comment!) -typedef enum -{ - mus_None, - mus_map01m, - mus_map02m, - mus_map03m, - mus_map04m, - mus_map05m, - mus_map06m, - mus_map07m, - mus_map08m, - mus_map09m, - mus_map10m, - mus_map11m, - mus_map12m, - mus_map13m, - mus_map14m, - mus_map15m, - mus_map16m, - mus_map17m, - mus_map18m, - mus_map19m, - mus_map20m, - mus_map21m, - mus_map22m, - mus_map23m, - mus_map24m, - mus_map25m, - mus_map26m, - mus_map27m, - mus_map28m, - mus_map29m, - mus_map30m, - mus_map31m, - mus_map32m, - mus_map33m, - mus_map34m, - mus_map35m, - mus_map36m, - mus_map37m, - mus_map38m, - mus_map39m, - mus_map40m, - mus_map41m, - mus_map42m, - mus_map43m, - mus_map44m, - mus_map45m, - mus_map46m, - mus_map47m, - mus_map48m, - mus_map49m, - mus_map50m, - mus_map51m, - mus_map52m, - mus_map53m, - mus_map54m, - mus_map55m, - mus_map56m, - mus_map57m, - mus_map58m, - mus_map59m, - mus_map60m, - mus_map61m, - mus_map62m, - mus_map63m, - mus_map64m, - mus_map65m, - mus_map66m, - mus_map67m, - mus_map68m, - mus_map69m, - mus_map70m, - mus_map71m, - mus_map72m, - mus_map73m, - mus_map74m, - mus_map75m, - mus_map76m, - mus_map77m, - mus_map78m, - mus_map79m, - mus_map80m, - mus_map81m, - mus_map82m, - mus_map83m, - mus_map84m, - mus_map85m, - mus_map86m, - mus_map87m, - mus_map88m, - mus_map89m, - mus_map90m, - mus_map91m, - mus_map92m, - mus_map93m, - mus_map94m, - mus_map95m, - mus_map96m, - mus_map97m, - mus_map98m, - mus_map99m, - mus_mapa0m, - mus_mapa1m, - mus_mapa2m, - mus_mapa3m, - mus_mapa4m, - mus_mapa5m, - mus_mapa6m, - mus_mapa7m, - mus_mapa8m, - mus_mapa9m, - mus_mapaam, - mus_mapabm, - mus_mapacm, - mus_mapadm, - mus_mapaem, - mus_mapafm, - mus_mapagm, - mus_mapahm, - mus_mapaim, - mus_mapajm, - mus_mapakm, - mus_mapalm, - mus_mapamm, - mus_mapanm, - mus_mapaom, - mus_mapapm, - mus_mapaqm, - mus_maparm, - mus_mapasm, - mus_mapatm, - mus_mapaum, - mus_mapavm, - mus_mapawm, - mus_mapaxm, - mus_mapaym, - mus_mapazm, - mus_mapb0m, - mus_mapb1m, - mus_mapb2m, - mus_mapb3m, - mus_mapb4m, - mus_mapb5m, - mus_mapb6m, - mus_mapb7m, - mus_mapb8m, - mus_mapb9m, - mus_mapbam, - mus_mapbbm, - mus_mapbcm, - mus_mapbdm, - mus_mapbem, - mus_mapbfm, - mus_mapbgm, - mus_mapbhm, - mus_mapbim, - mus_mapbjm, - mus_mapbkm, - mus_mapblm, - mus_mapbmm, - mus_mapbnm, - mus_mapbom, - mus_mapbpm, - mus_mapbqm, - mus_mapbrm, - mus_mapbsm, - mus_mapbtm, - mus_mapbum, - mus_mapbvm, - mus_mapbwm, - mus_mapbxm, - mus_mapbym, - mus_mapbzm, - mus_mapc0m, - mus_mapc1m, - mus_mapc2m, - mus_mapc3m, - mus_mapc4m, - mus_mapc5m, - mus_mapc6m, - mus_mapc7m, - mus_mapc8m, - mus_mapc9m, - mus_mapcam, - mus_mapcbm, - mus_mapccm, - mus_mapcdm, - mus_mapcem, - mus_mapcfm, - mus_mapcgm, - mus_mapchm, - mus_mapcim, - mus_mapcjm, - mus_mapckm, - mus_mapclm, - mus_mapcmm, - mus_mapcnm, - mus_mapcom, - mus_mapcpm, - mus_mapcqm, - mus_mapcrm, - mus_mapcsm, - mus_mapctm, - mus_mapcum, - mus_mapcvm, - mus_mapcwm, - mus_mapcxm, - mus_mapcym, - mus_mapczm, - mus_mapd0m, - mus_mapd1m, - mus_mapd2m, - mus_mapd3m, - mus_mapd4m, - mus_mapd5m, - mus_mapd6m, - mus_mapd7m, - mus_mapd8m, - mus_mapd9m, - mus_mapdam, - mus_mapdbm, - mus_mapdcm, - mus_mapddm, - mus_mapdem, - mus_mapdfm, - mus_mapdgm, - mus_mapdhm, - mus_mapdim, - mus_mapdjm, - mus_mapdkm, - mus_mapdlm, - mus_mapdmm, - mus_mapdnm, - mus_mapdom, - mus_mapdpm, - mus_mapdqm, - mus_mapdrm, - mus_mapdsm, - mus_mapdtm, - mus_mapdum, - mus_mapdvm, - mus_mapdwm, - mus_mapdxm, - mus_mapdym, - mus_mapdzm, - mus_mape0m, - mus_mape1m, - mus_mape2m, - mus_mape3m, - mus_mape4m, - mus_mape5m, - mus_mape6m, - mus_mape7m, - mus_mape8m, - mus_mape9m, - mus_mapeam, - mus_mapebm, - mus_mapecm, - mus_mapedm, - mus_mapeem, - mus_mapefm, - mus_mapegm, - mus_mapehm, - mus_mapeim, - mus_mapejm, - mus_mapekm, - mus_mapelm, - mus_mapemm, - mus_mapenm, - mus_mapeom, - mus_mapepm, - mus_mapeqm, - mus_maperm, - mus_mapesm, - mus_mapetm, - mus_mapeum, - mus_mapevm, - mus_mapewm, - mus_mapexm, - mus_mapeym, - mus_mapezm, - mus_mapf0m, - mus_mapf1m, - mus_mapf2m, - mus_mapf3m, - mus_mapf4m, - mus_mapf5m, - mus_mapf6m, - mus_mapf7m, - mus_mapf8m, - mus_mapf9m, - mus_mapfam, - mus_mapfbm, - mus_mapfcm, - mus_mapfdm, - mus_mapfem, - mus_mapffm, - mus_mapfgm, - mus_mapfhm, - mus_mapfim, - mus_mapfjm, - mus_mapfkm, - mus_mapflm, - mus_mapfmm, - mus_mapfnm, - mus_mapfom, - mus_mapfpm, - mus_mapfqm, - mus_mapfrm, - mus_mapfsm, - mus_mapftm, - mus_mapfum, - mus_mapfvm, - mus_mapfwm, - mus_mapfxm, - mus_mapfym, - mus_mapfzm, - mus_mapg0m, - mus_mapg1m, - mus_mapg2m, - mus_mapg3m, - mus_mapg4m, - mus_mapg5m, - mus_mapg6m, - mus_mapg7m, - mus_mapg8m, - mus_mapg9m, - mus_mapgam, - mus_mapgbm, - mus_mapgcm, - mus_mapgdm, - mus_mapgem, - mus_mapgfm, - mus_mapggm, - mus_mapghm, - mus_mapgim, - mus_mapgjm, - mus_mapgkm, - mus_mapglm, - mus_mapgmm, - mus_mapgnm, - mus_mapgom, - mus_mapgpm, - mus_mapgqm, - mus_mapgrm, - mus_mapgsm, - mus_mapgtm, - mus_mapgum, - mus_mapgvm, - mus_mapgwm, - mus_mapgxm, - mus_mapgym, - mus_mapgzm, - mus_maph0m, - mus_maph1m, - mus_maph2m, - mus_maph3m, - mus_maph4m, - mus_maph5m, - mus_maph6m, - mus_maph7m, - mus_maph8m, - mus_maph9m, - mus_mapham, - mus_maphbm, - mus_maphcm, - mus_maphdm, - mus_maphem, - mus_maphfm, - mus_maphgm, - mus_maphhm, - mus_maphim, - mus_maphjm, - mus_maphkm, - mus_maphlm, - mus_maphmm, - mus_maphnm, - mus_maphom, - mus_maphpm, - mus_maphqm, - mus_maphrm, - mus_maphsm, - mus_maphtm, - mus_maphum, - mus_maphvm, - mus_maphwm, - mus_maphxm, - mus_maphym, - mus_maphzm, - mus_mapi0m, - mus_mapi1m, - mus_mapi2m, - mus_mapi3m, - mus_mapi4m, - mus_mapi5m, - mus_mapi6m, - mus_mapi7m, - mus_mapi8m, - mus_mapi9m, - mus_mapiam, - mus_mapibm, - mus_mapicm, - mus_mapidm, - mus_mapiem, - mus_mapifm, - mus_mapigm, - mus_mapihm, - mus_mapiim, - mus_mapijm, - mus_mapikm, - mus_mapilm, - mus_mapimm, - mus_mapinm, - mus_mapiom, - mus_mapipm, - mus_mapiqm, - mus_mapirm, - mus_mapism, - mus_mapitm, - mus_mapium, - mus_mapivm, - mus_mapiwm, - mus_mapixm, - mus_mapiym, - mus_mapizm, - mus_mapj0m, - mus_mapj1m, - mus_mapj2m, - mus_mapj3m, - mus_mapj4m, - mus_mapj5m, - mus_mapj6m, - mus_mapj7m, - mus_mapj8m, - mus_mapj9m, - mus_mapjam, - mus_mapjbm, - mus_mapjcm, - mus_mapjdm, - mus_mapjem, - mus_mapjfm, - mus_mapjgm, - mus_mapjhm, - mus_mapjim, - mus_mapjjm, - mus_mapjkm, - mus_mapjlm, - mus_mapjmm, - mus_mapjnm, - mus_mapjom, - mus_mapjpm, - mus_mapjqm, - mus_mapjrm, - mus_mapjsm, - mus_mapjtm, - mus_mapjum, - mus_mapjvm, - mus_mapjwm, - mus_mapjxm, - mus_mapjym, - mus_mapjzm, - mus_mapk0m, - mus_mapk1m, - mus_mapk2m, - mus_mapk3m, - mus_mapk4m, - mus_mapk5m, - mus_mapk6m, - mus_mapk7m, - mus_mapk8m, - mus_mapk9m, - mus_mapkam, - mus_mapkbm, - mus_mapkcm, - mus_mapkdm, - mus_mapkem, - mus_mapkfm, - mus_mapkgm, - mus_mapkhm, - mus_mapkim, - mus_mapkjm, - mus_mapkkm, - mus_mapklm, - mus_mapkmm, - mus_mapknm, - mus_mapkom, - mus_mapkpm, - mus_mapkqm, - mus_mapkrm, - mus_mapksm, - mus_mapktm, - mus_mapkum, - mus_mapkvm, - mus_mapkwm, - mus_mapkxm, - mus_mapkym, - mus_mapkzm, - mus_mapl0m, - mus_mapl1m, - mus_mapl2m, - mus_mapl3m, - mus_mapl4m, - mus_mapl5m, - mus_mapl6m, - mus_mapl7m, - mus_mapl8m, - mus_mapl9m, - mus_maplam, - mus_maplbm, - mus_maplcm, - mus_mapldm, - mus_maplem, - mus_maplfm, - mus_maplgm, - mus_maplhm, - mus_maplim, - mus_mapljm, - mus_maplkm, - mus_mapllm, - mus_maplmm, - mus_maplnm, - mus_maplom, - mus_maplpm, - mus_maplqm, - mus_maplrm, - mus_maplsm, - mus_mapltm, - mus_maplum, - mus_maplvm, - mus_maplwm, - mus_maplxm, - mus_maplym, - mus_maplzm, - mus_mapm0m, - mus_mapm1m, - mus_mapm2m, - mus_mapm3m, - mus_mapm4m, - mus_mapm5m, - mus_mapm6m, - mus_mapm7m, - mus_mapm8m, - mus_mapm9m, - mus_mapmam, - mus_mapmbm, - mus_mapmcm, - mus_mapmdm, - mus_mapmem, - mus_mapmfm, - mus_mapmgm, - mus_mapmhm, - mus_mapmim, - mus_mapmjm, - mus_mapmkm, - mus_mapmlm, - mus_mapmmm, - mus_mapmnm, - mus_mapmom, - mus_mapmpm, - mus_mapmqm, - mus_mapmrm, - mus_mapmsm, - mus_mapmtm, - mus_mapmum, - mus_mapmvm, - mus_mapmwm, - mus_mapmxm, - mus_mapmym, - mus_mapmzm, - mus_mapn0m, - mus_mapn1m, - mus_mapn2m, - mus_mapn3m, - mus_mapn4m, - mus_mapn5m, - mus_mapn6m, - mus_mapn7m, - mus_mapn8m, - mus_mapn9m, - mus_mapnam, - mus_mapnbm, - mus_mapncm, - mus_mapndm, - mus_mapnem, - mus_mapnfm, - mus_mapngm, - mus_mapnhm, - mus_mapnim, - mus_mapnjm, - mus_mapnkm, - mus_mapnlm, - mus_mapnmm, - mus_mapnnm, - mus_mapnom, - mus_mapnpm, - mus_mapnqm, - mus_mapnrm, - mus_mapnsm, - mus_mapntm, - mus_mapnum, - mus_mapnvm, - mus_mapnwm, - mus_mapnxm, - mus_mapnym, - mus_mapnzm, - mus_mapo0m, - mus_mapo1m, - mus_mapo2m, - mus_mapo3m, - mus_mapo4m, - mus_mapo5m, - mus_mapo6m, - mus_mapo7m, - mus_mapo8m, - mus_mapo9m, - mus_mapoam, - mus_mapobm, - mus_mapocm, - mus_mapodm, - mus_mapoem, - mus_mapofm, - mus_mapogm, - mus_mapohm, - mus_mapoim, - mus_mapojm, - mus_mapokm, - mus_mapolm, - mus_mapomm, - mus_maponm, - mus_mapoom, - mus_mapopm, - mus_mapoqm, - mus_maporm, - mus_maposm, - mus_mapotm, - mus_mapoum, - mus_mapovm, - mus_mapowm, - mus_mapoxm, - mus_mapoym, - mus_mapozm, - mus_mapp0m, - mus_mapp1m, - mus_mapp2m, - mus_mapp3m, - mus_mapp4m, - mus_mapp5m, - mus_mapp6m, - mus_mapp7m, - mus_mapp8m, - mus_mapp9m, - mus_mappam, - mus_mappbm, - mus_mappcm, - mus_mappdm, - mus_mappem, - mus_mappfm, - mus_mappgm, - mus_mapphm, - mus_mappim, - mus_mappjm, - mus_mappkm, - mus_mapplm, - mus_mappmm, - mus_mappnm, - mus_mappom, - mus_mapppm, - mus_mappqm, - mus_mapprm, - mus_mappsm, - mus_mapptm, - mus_mappum, - mus_mappvm, - mus_mappwm, - mus_mappxm, - mus_mappym, - mus_mappzm, - mus_mapq0m, - mus_mapq1m, - mus_mapq2m, - mus_mapq3m, - mus_mapq4m, - mus_mapq5m, - mus_mapq6m, - mus_mapq7m, - mus_mapq8m, - mus_mapq9m, - mus_mapqam, - mus_mapqbm, - mus_mapqcm, - mus_mapqdm, - mus_mapqem, - mus_mapqfm, - mus_mapqgm, - mus_mapqhm, - mus_mapqim, - mus_mapqjm, - mus_mapqkm, - mus_mapqlm, - mus_mapqmm, - mus_mapqnm, - mus_mapqom, - mus_mapqpm, - mus_mapqqm, - mus_mapqrm, - mus_mapqsm, - mus_mapqtm, - mus_mapqum, - mus_mapqvm, - mus_mapqwm, - mus_mapqxm, - mus_mapqym, - mus_mapqzm, - mus_mapr0m, - mus_mapr1m, - mus_mapr2m, - mus_mapr3m, - mus_mapr4m, - mus_mapr5m, - mus_mapr6m, - mus_mapr7m, - mus_mapr8m, - mus_mapr9m, - mus_mapram, - mus_maprbm, - mus_maprcm, - mus_maprdm, - mus_maprem, - mus_maprfm, - mus_maprgm, - mus_maprhm, - mus_maprim, - mus_maprjm, - mus_maprkm, - mus_maprlm, - mus_maprmm, - mus_maprnm, - mus_maprom, - mus_maprpm, - mus_maprqm, - mus_maprrm, - mus_maprsm, - mus_maprtm, - mus_maprum, - mus_maprvm, - mus_maprwm, - mus_maprxm, - mus_maprym, - mus_maprzm, - mus_maps0m, - mus_maps1m, - mus_maps2m, - mus_maps3m, - mus_maps4m, - mus_maps5m, - mus_maps6m, - mus_maps7m, - mus_maps8m, - mus_maps9m, - mus_mapsam, - mus_mapsbm, - mus_mapscm, - mus_mapsdm, - mus_mapsem, - mus_mapsfm, - mus_mapsgm, - mus_mapshm, - mus_mapsim, - mus_mapsjm, - mus_mapskm, - mus_mapslm, - mus_mapsmm, - mus_mapsnm, - mus_mapsom, - mus_mapspm, - mus_mapsqm, - mus_mapsrm, - mus_mapssm, - mus_mapstm, - mus_mapsum, - mus_mapsvm, - mus_mapswm, - mus_mapsxm, - mus_mapsym, - mus_mapszm, - mus_mapt0m, - mus_mapt1m, - mus_mapt2m, - mus_mapt3m, - mus_mapt4m, - mus_mapt5m, - mus_mapt6m, - mus_mapt7m, - mus_mapt8m, - mus_mapt9m, - mus_maptam, - mus_maptbm, - mus_maptcm, - mus_maptdm, - mus_maptem, - mus_maptfm, - mus_maptgm, - mus_mapthm, - mus_maptim, - mus_maptjm, - mus_maptkm, - mus_maptlm, - mus_maptmm, - mus_maptnm, - mus_maptom, - mus_maptpm, - mus_maptqm, - mus_maptrm, - mus_maptsm, - mus_mapttm, - mus_maptum, - mus_maptvm, - mus_maptwm, - mus_maptxm, - mus_maptym, - mus_maptzm, - mus_mapu0m, - mus_mapu1m, - mus_mapu2m, - mus_mapu3m, - mus_mapu4m, - mus_mapu5m, - mus_mapu6m, - mus_mapu7m, - mus_mapu8m, - mus_mapu9m, - mus_mapuam, - mus_mapubm, - mus_mapucm, - mus_mapudm, - mus_mapuem, - mus_mapufm, - mus_mapugm, - mus_mapuhm, - mus_mapuim, - mus_mapujm, - mus_mapukm, - mus_mapulm, - mus_mapumm, - mus_mapunm, - mus_mapuom, - mus_mapupm, - mus_mapuqm, - mus_mapurm, - mus_mapusm, - mus_maputm, - mus_mapuum, - mus_mapuvm, - mus_mapuwm, - mus_mapuxm, - mus_mapuym, - mus_mapuzm, - mus_mapv0m, - mus_mapv1m, - mus_mapv2m, - mus_mapv3m, - mus_mapv4m, - mus_mapv5m, - mus_mapv6m, - mus_mapv7m, - mus_mapv8m, - mus_mapv9m, - mus_mapvam, - mus_mapvbm, - mus_mapvcm, - mus_mapvdm, - mus_mapvem, - mus_mapvfm, - mus_mapvgm, - mus_mapvhm, - mus_mapvim, - mus_mapvjm, - mus_mapvkm, - mus_mapvlm, - mus_mapvmm, - mus_mapvnm, - mus_mapvom, - mus_mapvpm, - mus_mapvqm, - mus_mapvrm, - mus_mapvsm, - mus_mapvtm, - mus_mapvum, - mus_mapvvm, - mus_mapvwm, - mus_mapvxm, - mus_mapvym, - mus_mapvzm, - mus_mapw0m, - mus_mapw1m, - mus_mapw2m, - mus_mapw3m, - mus_mapw4m, - mus_mapw5m, - mus_mapw6m, - mus_mapw7m, - mus_mapw8m, - mus_mapw9m, - mus_mapwam, - mus_mapwbm, - mus_mapwcm, - mus_mapwdm, - mus_mapwem, - mus_mapwfm, - mus_mapwgm, - mus_mapwhm, - mus_mapwim, - mus_mapwjm, - mus_mapwkm, - mus_mapwlm, - mus_mapwmm, - mus_mapwnm, - mus_mapwom, - mus_mapwpm, - mus_mapwqm, - mus_mapwrm, - mus_mapwsm, - mus_mapwtm, - mus_mapwum, - mus_mapwvm, - mus_mapwwm, - mus_mapwxm, - mus_mapwym, - mus_mapwzm, - mus_mapx0m, - mus_mapx1m, - mus_mapx2m, - mus_mapx3m, - mus_mapx4m, - mus_mapx5m, - mus_mapx6m, - mus_mapx7m, - mus_mapx8m, - mus_mapx9m, - mus_mapxam, - mus_mapxbm, - mus_mapxcm, - mus_mapxdm, - mus_mapxem, - mus_mapxfm, - mus_mapxgm, - mus_mapxhm, - mus_mapxim, - mus_mapxjm, - mus_mapxkm, - mus_mapxlm, - mus_mapxmm, - mus_mapxnm, - mus_mapxom, - mus_mapxpm, - mus_mapxqm, - mus_mapxrm, - mus_mapxsm, - mus_mapxtm, - mus_mapxum, - mus_mapxvm, - mus_mapxwm, - mus_mapxxm, - mus_mapxym, - mus_mapxzm, - mus_mapy0m, - mus_mapy1m, - mus_mapy2m, - mus_mapy3m, - mus_mapy4m, - mus_mapy5m, - mus_mapy6m, - mus_mapy7m, - mus_mapy8m, - mus_mapy9m, - mus_mapyam, - mus_mapybm, - mus_mapycm, - mus_mapydm, - mus_mapyem, - mus_mapyfm, - mus_mapygm, - mus_mapyhm, - mus_mapyim, - mus_mapyjm, - mus_mapykm, - mus_mapylm, - mus_mapymm, - mus_mapynm, - mus_mapyom, - mus_mapypm, - mus_mapyqm, - mus_mapyrm, - mus_mapysm, - mus_mapytm, - mus_mapyum, - mus_mapyvm, - mus_mapywm, - mus_mapyxm, - mus_mapyym, - mus_mapyzm, - mus_mapz0m, - mus_mapz1m, - mus_mapz2m, - mus_mapz3m, - mus_mapz4m, - mus_mapz5m, - mus_mapz6m, - mus_mapz7m, - mus_mapz8m, - mus_mapz9m, - mus_mapzam, - mus_mapzbm, - mus_mapzcm, - mus_mapzdm, - mus_mapzem, - mus_mapzfm, - mus_mapzgm, - mus_mapzhm, - mus_mapzim, - mus_mapzjm, - mus_mapzkm, - mus_mapzlm, - mus_mapzmm, - mus_mapznm, - mus_mapzom, - mus_mapzpm, - mus_mapzqm, - mus_mapzrm, - mus_mapzsm, - mus_mapztm, - mus_mapzum, - mus_mapzvm, - mus_mapzwm, - mus_mapzxm, - mus_mapzym, - mus_mapzzm, - - mus_titles, // title screen - mus_read_m, // intro - mus_lclear, // level clear - mus_invinc, // invincibility - mus_shoes, // super sneakers - mus_minvnc, // Mario invincibility - mus_drown, // drowning - mus_gmover, // game over - mus_xtlife, // extra life - mus_contsc, // continue screen - mus_supers, // Super Sonic - mus_chrsel, // character select - mus_credit, // credits - mus_racent, // Race Results - mus_stjr, // Sonic Team Jr. Presents - - NUMMUSIC -} musicenum_t; -// Note: song number should be a UINT16, as mapmusic only uses 16 bits for music slot number. -// (the rest is track number and an internal reload flag) - // // Identifiers for all sfx in game. // diff --git a/src/st_stuff.c b/src/st_stuff.c index b0875685f..bf6bab149 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -888,8 +888,8 @@ static void ST_drawFirstPersonHUD(void) // [21:42] <+Rob> Beige - Lavender - Steel Blue - Peach - Orange - Purple - Silver - Yellow - Pink - Red - Blue - Green - Cyan - Gold static skincolors_t linkColor[14] = -{SKINCOLOR_BEIGE, SKINCOLOR_LAVENDER, SKINCOLOR_STEELBLUE, SKINCOLOR_PEACH, SKINCOLOR_ORANGE, - SKINCOLOR_PURPLE, SKINCOLOR_SILVER, SKINCOLOR_SUPER4, SKINCOLOR_PINK, SKINCOLOR_RED, +{SKINCOLOR_BEIGE, SKINCOLOR_LAVENDER, SKINCOLOR_AZURE, SKINCOLOR_PEACH, SKINCOLOR_ORANGE, + SKINCOLOR_MAGENTA, SKINCOLOR_SILVER, SKINCOLOR_SUPER4, SKINCOLOR_PINK, SKINCOLOR_RED, SKINCOLOR_BLUE, SKINCOLOR_GREEN, SKINCOLOR_CYAN, SKINCOLOR_GOLD}; static void ST_drawNightsRecords(void) @@ -938,7 +938,7 @@ static void ST_drawNightsRecords(void) V_DrawString(BASEVIDWIDTH/2 - 48, STRINGY(148), aflag, "BONUS:"); V_DrawRightAlignedString(BASEVIDWIDTH/2 + 48, STRINGY(140), V_ORANGEMAP|aflag, va("%d", stplyr->finishedrings)); V_DrawRightAlignedString(BASEVIDWIDTH/2 + 48, STRINGY(148), V_ORANGEMAP|aflag, va("%d", stplyr->finishedrings * 50)); - ST_DrawNightsOverlayNum(BASEVIDWIDTH/2 + 48, STRINGY(160), aflag, stplyr->lastmarescore, nightsnum, SKINCOLOR_STEELBLUE); + ST_DrawNightsOverlayNum(BASEVIDWIDTH/2 + 48, STRINGY(160), aflag, stplyr->lastmarescore, nightsnum, SKINCOLOR_AZURE); // If new record, say so! if (!(netgame || multiplayer) && G_GetBestNightsScore(gamemap, stplyr->lastmare + 1) <= stplyr->lastmarescore) @@ -1220,7 +1220,7 @@ static void ST_drawNiGHTSHUD(void) #endif ) { - ST_DrawNightsOverlayNum(304, STRINGY(16), SPLITFLAGS(V_SNAPTOTOP)|V_SNAPTORIGHT, stplyr->marescore, nightsnum, SKINCOLOR_STEELBLUE); + ST_DrawNightsOverlayNum(304, STRINGY(16), SPLITFLAGS(V_SNAPTOTOP)|V_SNAPTORIGHT, stplyr->marescore, nightsnum, SKINCOLOR_AZURE); } if (!stplyr->exiting @@ -1842,37 +1842,6 @@ static void ST_overlayDrawer(void) LUAh_GameHUD(stplyr); #endif -#if 0 // Pope XVI - if (!(netgame || multiplayer) && !modifiedgame && gamemap == 11 && ALL7EMERALDS(emeralds) - && stplyr->mo && stplyr->mo->subsector && stplyr->mo->subsector->sector-sectors == 1361) - { - if (grade & 2048) // NAGZ - { - V_DrawCenteredString(BASEVIDWIDTH/2, 70, 0, M_GetText("I, Pope Rededict XVI proclaim")); - V_DrawCenteredString(BASEVIDWIDTH/2, 80, 0, M_GetText("AJ & Amy")); - V_DrawCenteredString(BASEVIDWIDTH/2, 90, 0, M_GetText("Husband & Wife")); - V_DrawCenteredString(BASEVIDWIDTH/2, 100, 0, M_GetText("on this day")); - V_DrawCenteredString(BASEVIDWIDTH/2, 110, 0, M_GetText("May 16, 2009")); - - P_GivePlayerRings(stplyr, 9999); - } - else - { - V_DrawCenteredString(BASEVIDWIDTH/2, 60, 0, M_GetText("Oh... it's you again...")); - V_DrawCenteredString(BASEVIDWIDTH/2, 80, 0, M_GetText("Look, I wanted to apologize for the way")); - V_DrawCenteredString(BASEVIDWIDTH/2, 90, 0, M_GetText("I've acted in the past.")); - V_DrawCenteredString(BASEVIDWIDTH/2, 110, 0, M_GetText("I've seen the error of my ways")); - V_DrawCenteredString(BASEVIDWIDTH/2, 120, 0, M_GetText("and turned over a new leaf.")); - V_DrawCenteredString(BASEVIDWIDTH/2, 140, 0, M_GetText("Instead of sending people to hell,")); - V_DrawCenteredString(BASEVIDWIDTH/2, 150, 0, M_GetText("I now send them to heaven!")); - - P_LinedefExecute(4200, stplyr->mo, stplyr->mo->subsector->sector); - P_LinedefExecute(4201, stplyr->mo, stplyr->mo->subsector->sector); - stplyr->mo->momx = stplyr->mo->momy = 0; - } - } -#endif - // draw level title Tails if (*mapheaderinfo[gamemap-1]->lvlttl != '\0' && !(hu_showscores && (netgame || multiplayer)) #ifdef HAVE_BLUA diff --git a/src/tables.c b/src/tables.c index 190522a35..3f881be7d 100644 --- a/src/tables.c +++ b/src/tables.c @@ -162,518 +162,518 @@ angle_t FixedAngle(fixed_t fa) #if !(defined _NDS) || !(defined NONET) fixed_t finetangent[4096] = { - -170910304, -56965752, -34178904, -24413316, -18988036, -15535599, -13145455, -11392683, - -10052327, -8994149, -8137527, -7429880, -6835455, -6329090, -5892567, -5512368, - -5178251, -4882318, -4618375, -4381502, -4167737, -3973855, -3797206, -3635590, - -3487165, -3350381, -3223918, -3106651, -2997613, -2895966, -2800983, -2712030, - -2628549, -2550052, -2476104, -2406322, -2340362, -2277919, -2218719, -2162516, - -2109087, -2058233, -2009771, -1963536, -1919378, -1877161, -1836758, -1798063, - -1760956, -1725348, -1691149, -1658278, -1626658, -1596220, -1566898, -1538632, - -1511367, -1485049, -1459630, -1435065, -1411312, -1388330, -1366084, -1344537, - -1323658, -1303416, -1283783, -1264730, -1246234, -1228269, -1210813, -1193846, - -1177345, -1161294, -1145673, -1130465, -1115654, -1101225, -1087164, -1073455, - -1060087, -1047046, -1034322, -1021901, -1009774, -997931, -986361, -975054, - -964003, -953199, -942633, -932298, -922186, -912289, -902602, -893117, - -883829, -874730, -865817, -857081, -848520, -840127, -831898, -823827, - -815910, -808143, -800521, -793041, -785699, -778490, -771411, -764460, - -757631, -750922, -744331, -737853, -731486, -725227, -719074, -713023, - -707072, -701219, -695462, -689797, -684223, -678737, -673338, -668024, - -662792, -657640, -652568, -647572, -642651, -637803, -633028, -628323, - -623686, -619117, -614613, -610174, -605798, -601483, -597229, -593033, - -588896, -584815, -580789, -576818, -572901, -569035, -565221, -561456, - -557741, -554074, -550455, -546881, -543354, -539870, -536431, -533034, - -529680, -526366, -523094, -519861, -516667, -513512, -510394, -507313, - -504269, -501261, -498287, -495348, -492443, -489571, -486732, -483925, - -481150, -478406, -475692, -473009, -470355, -467730, -465133, -462565, - -460024, -457511, -455024, -452564, -450129, -447720, -445337, -442978, - -440643, -438332, -436045, -433781, -431540, -429321, -427125, -424951, - -422798, -420666, -418555, -416465, -414395, -412344, -410314, -408303, - -406311, -404338, -402384, -400448, -398530, -396630, -394747, -392882, - -391034, -389202, -387387, -385589, -383807, -382040, -380290, -378555, - -376835, -375130, -373440, -371765, -370105, -368459, -366826, -365208, - -363604, -362013, -360436, -358872, -357321, -355783, -354257, -352744, - -351244, -349756, -348280, -346816, -345364, -343924, -342495, -341078, - -339671, -338276, -336892, -335519, -334157, -332805, -331464, -330133, - -328812, -327502, -326201, -324910, -323629, -322358, -321097, -319844, - -318601, -317368, -316143, -314928, -313721, -312524, -311335, -310154, - -308983, -307819, -306664, -305517, -304379, -303248, -302126, -301011, - -299904, -298805, -297714, -296630, -295554, -294485, -293423, -292369, - -291322, -290282, -289249, -288223, -287204, -286192, -285186, -284188, - -283195, -282210, -281231, -280258, -279292, -278332, -277378, -276430, - -275489, -274553, -273624, -272700, -271782, -270871, -269965, -269064, - -268169, -267280, -266397, -265519, -264646, -263779, -262917, -262060, - -261209, -260363, -259522, -258686, -257855, -257029, -256208, -255392, - -254581, -253774, -252973, -252176, -251384, -250596, -249813, -249035, - -248261, -247492, -246727, -245966, -245210, -244458, -243711, -242967, - -242228, -241493, -240763, -240036, -239314, -238595, -237881, -237170, - -236463, -235761, -235062, -234367, -233676, -232988, -232304, -231624, - -230948, -230275, -229606, -228941, -228279, -227621, -226966, -226314, - -225666, -225022, -224381, -223743, -223108, -222477, -221849, -221225, - -220603, -219985, -219370, -218758, -218149, -217544, -216941, -216341, - -215745, -215151, -214561, -213973, -213389, -212807, -212228, -211652, - -211079, -210509, -209941, -209376, -208815, -208255, -207699, -207145, - -206594, -206045, -205500, -204956, -204416, -203878, -203342, -202809, - -202279, -201751, -201226, -200703, -200182, -199664, -199149, -198636, - -198125, -197616, -197110, -196606, -196105, -195606, -195109, -194614, - -194122, -193631, -193143, -192658, -192174, -191693, -191213, -190736, - -190261, -189789, -189318, -188849, -188382, -187918, -187455, -186995, - -186536, -186080, -185625, -185173, -184722, -184274, -183827, -183382, - -182939, -182498, -182059, -181622, -181186, -180753, -180321, -179891, - -179463, -179037, -178612, -178190, -177769, -177349, -176932, -176516, - -176102, -175690, -175279, -174870, -174463, -174057, -173653, -173251, - -172850, -172451, -172053, -171657, -171263, -170870, -170479, -170089, - -169701, -169315, -168930, -168546, -168164, -167784, -167405, -167027, - -166651, -166277, -165904, -165532, -165162, -164793, -164426, -164060, - -163695, -163332, -162970, -162610, -162251, -161893, -161537, -161182, - -160828, -160476, -160125, -159775, -159427, -159079, -158734, -158389, - -158046, -157704, -157363, -157024, -156686, -156349, -156013, -155678, - -155345, -155013, -154682, -154352, -154024, -153697, -153370, -153045, - -152722, -152399, -152077, -151757, -151438, -151120, -150803, -150487, - -150172, -149859, -149546, -149235, -148924, -148615, -148307, -148000, - -147693, -147388, -147084, -146782, -146480, -146179, -145879, -145580, - -145282, -144986, -144690, -144395, -144101, -143808, -143517, -143226, - -142936, -142647, -142359, -142072, -141786, -141501, -141217, -140934, - -140651, -140370, -140090, -139810, -139532, -139254, -138977, -138701, - -138426, -138152, -137879, -137607, -137335, -137065, -136795, -136526, - -136258, -135991, -135725, -135459, -135195, -134931, -134668, -134406, - -134145, -133884, -133625, -133366, -133108, -132851, -132594, -132339, - -132084, -131830, -131576, -131324, -131072, -130821, -130571, -130322, - -130073, -129825, -129578, -129332, -129086, -128841, -128597, -128353, - -128111, -127869, -127627, -127387, -127147, -126908, -126669, -126432, - -126195, -125959, -125723, -125488, -125254, -125020, -124787, -124555, - -124324, -124093, -123863, -123633, -123404, -123176, -122949, -122722, - -122496, -122270, -122045, -121821, -121597, -121374, -121152, -120930, - -120709, -120489, -120269, -120050, -119831, -119613, -119396, -119179, - -118963, -118747, -118532, -118318, -118104, -117891, -117678, -117466, - -117254, -117044, -116833, -116623, -116414, -116206, -115998, -115790, - -115583, -115377, -115171, -114966, -114761, -114557, -114354, -114151, - -113948, -113746, -113545, -113344, -113143, -112944, -112744, -112546, - -112347, -112150, -111952, -111756, -111560, -111364, -111169, -110974, - -110780, -110586, -110393, -110200, -110008, -109817, -109626, -109435, - -109245, -109055, -108866, -108677, -108489, -108301, -108114, -107927, - -107741, -107555, -107369, -107184, -107000, -106816, -106632, -106449, - -106266, -106084, -105902, -105721, -105540, -105360, -105180, -105000, - -104821, -104643, -104465, -104287, -104109, -103933, -103756, -103580, - -103404, -103229, -103054, -102880, -102706, -102533, -102360, -102187, - -102015, -101843, -101671, -101500, -101330, -101159, -100990, -100820, - -100651, -100482, -100314, -100146, -99979, -99812, -99645, -99479, - -99313, -99148, -98982, -98818, -98653, -98489, -98326, -98163, - -98000, -97837, -97675, -97513, -97352, -97191, -97030, -96870, - -96710, -96551, -96391, -96233, -96074, -95916, -95758, -95601, - -95444, -95287, -95131, -94975, -94819, -94664, -94509, -94354, - -94200, -94046, -93892, -93739, -93586, -93434, -93281, -93129, - -92978, -92826, -92675, -92525, -92375, -92225, -92075, -91926, - -91777, -91628, -91480, -91332, -91184, -91036, -90889, -90742, - -90596, -90450, -90304, -90158, -90013, -89868, -89724, -89579, - -89435, -89292, -89148, -89005, -88862, -88720, -88577, -88435, - -88294, -88152, -88011, -87871, -87730, -87590, -87450, -87310, - -87171, -87032, -86893, -86755, -86616, -86479, -86341, -86204, - -86066, -85930, -85793, -85657, -85521, -85385, -85250, -85114, - -84980, -84845, -84710, -84576, -84443, -84309, -84176, -84043, - -83910, -83777, -83645, -83513, -83381, -83250, -83118, -82987, - -82857, -82726, -82596, -82466, -82336, -82207, -82078, -81949, - -81820, -81691, -81563, -81435, -81307, -81180, -81053, -80925, - -80799, -80672, -80546, -80420, -80294, -80168, -80043, -79918, - -79793, -79668, -79544, -79420, -79296, -79172, -79048, -78925, - -78802, -78679, -78557, -78434, -78312, -78190, -78068, -77947, - -77826, -77705, -77584, -77463, -77343, -77223, -77103, -76983, - -76864, -76744, -76625, -76506, -76388, -76269, -76151, -76033, - -75915, -75797, -75680, -75563, -75446, -75329, -75213, -75096, - -74980, -74864, -74748, -74633, -74517, -74402, -74287, -74172, - -74058, -73944, -73829, -73715, -73602, -73488, -73375, -73262, - -73149, -73036, -72923, -72811, -72699, -72587, -72475, -72363, - -72252, -72140, -72029, -71918, -71808, -71697, -71587, -71477, - -71367, -71257, -71147, -71038, -70929, -70820, -70711, -70602, - -70494, -70385, -70277, -70169, -70061, -69954, -69846, -69739, - -69632, -69525, -69418, -69312, -69205, -69099, -68993, -68887, - -68781, -68676, -68570, -68465, -68360, -68255, -68151, -68046, - -67942, -67837, -67733, -67629, -67526, -67422, -67319, -67216, - -67113, -67010, -66907, -66804, -66702, -66600, -66498, -66396, - -66294, -66192, -66091, -65989, -65888, -65787, -65686, -65586, - -65485, -65385, -65285, -65185, -65085, -64985, -64885, -64786, - -64687, -64587, -64488, -64389, -64291, -64192, -64094, -63996, - -63897, -63799, -63702, -63604, -63506, -63409, -63312, -63215, - -63118, -63021, -62924, -62828, -62731, -62635, -62539, -62443, - -62347, -62251, -62156, -62060, -61965, -61870, -61775, -61680, - -61585, -61491, -61396, -61302, -61208, -61114, -61020, -60926, - -60833, -60739, -60646, -60552, -60459, -60366, -60273, -60181, - -60088, -59996, -59903, -59811, -59719, -59627, -59535, -59444, - -59352, -59261, -59169, -59078, -58987, -58896, -58805, -58715, - -58624, -58534, -58443, -58353, -58263, -58173, -58083, -57994, - -57904, -57815, -57725, -57636, -57547, -57458, -57369, -57281, - -57192, -57104, -57015, -56927, -56839, -56751, -56663, -56575, - -56487, -56400, -56312, -56225, -56138, -56051, -55964, -55877, - -55790, -55704, -55617, -55531, -55444, -55358, -55272, -55186, - -55100, -55015, -54929, -54843, -54758, -54673, -54587, -54502, - -54417, -54333, -54248, -54163, -54079, -53994, -53910, -53826, - -53741, -53657, -53574, -53490, -53406, -53322, -53239, -53156, - -53072, -52989, -52906, -52823, -52740, -52657, -52575, -52492, - -52410, -52327, -52245, -52163, -52081, -51999, -51917, -51835, - -51754, -51672, -51591, -51509, -51428, -51347, -51266, -51185, - -51104, -51023, -50942, -50862, -50781, -50701, -50621, -50540, - -50460, -50380, -50300, -50221, -50141, -50061, -49982, -49902, - -49823, -49744, -49664, -49585, -49506, -49427, -49349, -49270, - -49191, -49113, -49034, -48956, -48878, -48799, -48721, -48643, - -48565, -48488, -48410, -48332, -48255, -48177, -48100, -48022, - -47945, -47868, -47791, -47714, -47637, -47560, -47484, -47407, - -47331, -47254, -47178, -47102, -47025, -46949, -46873, -46797, - -46721, -46646, -46570, -46494, -46419, -46343, -46268, -46193, - -46118, -46042, -45967, -45892, -45818, -45743, -45668, -45593, - -45519, -45444, -45370, -45296, -45221, -45147, -45073, -44999, - -44925, -44851, -44778, -44704, -44630, -44557, -44483, -44410, - -44337, -44263, -44190, -44117, -44044, -43971, -43898, -43826, - -43753, -43680, -43608, -43535, -43463, -43390, -43318, -43246, - -43174, -43102, -43030, -42958, -42886, -42814, -42743, -42671, - -42600, -42528, -42457, -42385, -42314, -42243, -42172, -42101, - -42030, -41959, -41888, -41817, -41747, -41676, -41605, -41535, - -41465, -41394, -41324, -41254, -41184, -41113, -41043, -40973, - -40904, -40834, -40764, -40694, -40625, -40555, -40486, -40416, - -40347, -40278, -40208, -40139, -40070, -40001, -39932, -39863, - -39794, -39726, -39657, -39588, -39520, -39451, -39383, -39314, - -39246, -39178, -39110, -39042, -38973, -38905, -38837, -38770, - -38702, -38634, -38566, -38499, -38431, -38364, -38296, -38229, - -38161, -38094, -38027, -37960, -37893, -37826, -37759, -37692, - -37625, -37558, -37491, -37425, -37358, -37291, -37225, -37158, - -37092, -37026, -36959, -36893, -36827, -36761, -36695, -36629, - -36563, -36497, -36431, -36365, -36300, -36234, -36168, -36103, - -36037, -35972, -35907, -35841, -35776, -35711, -35646, -35580, - -35515, -35450, -35385, -35321, -35256, -35191, -35126, -35062, - -34997, -34932, -34868, -34803, -34739, -34675, -34610, -34546, - -34482, -34418, -34354, -34289, -34225, -34162, -34098, -34034, - -33970, -33906, -33843, -33779, -33715, -33652, -33588, -33525, - -33461, -33398, -33335, -33272, -33208, -33145, -33082, -33019, - -32956, -32893, -32830, -32767, -32705, -32642, -32579, -32516, - -32454, -32391, -32329, -32266, -32204, -32141, -32079, -32017, - -31955, -31892, -31830, -31768, -31706, -31644, -31582, -31520, - -31458, -31396, -31335, -31273, -31211, -31150, -31088, -31026, - -30965, -30904, -30842, -30781, -30719, -30658, -30597, -30536, - -30474, -30413, -30352, -30291, -30230, -30169, -30108, -30048, - -29987, -29926, -29865, -29805, -29744, -29683, -29623, -29562, - -29502, -29441, -29381, -29321, -29260, -29200, -29140, -29080, - -29020, -28959, -28899, -28839, -28779, -28719, -28660, -28600, - -28540, -28480, -28420, -28361, -28301, -28241, -28182, -28122, - -28063, -28003, -27944, -27884, -27825, -27766, -27707, -27647, - -27588, -27529, -27470, -27411, -27352, -27293, -27234, -27175, - -27116, -27057, -26998, -26940, -26881, -26822, -26763, -26705, - -26646, -26588, -26529, -26471, -26412, -26354, -26295, -26237, - -26179, -26120, -26062, -26004, -25946, -25888, -25830, -25772, - -25714, -25656, -25598, -25540, -25482, -25424, -25366, -25308, - -25251, -25193, -25135, -25078, -25020, -24962, -24905, -24847, - -24790, -24732, -24675, -24618, -24560, -24503, -24446, -24389, - -24331, -24274, -24217, -24160, -24103, -24046, -23989, -23932, - -23875, -23818, -23761, -23704, -23647, -23591, -23534, -23477, - -23420, -23364, -23307, -23250, -23194, -23137, -23081, -23024, - -22968, -22911, -22855, -22799, -22742, -22686, -22630, -22573, - -22517, -22461, -22405, -22349, -22293, -22237, -22181, -22125, - -22069, -22013, -21957, -21901, -21845, -21789, -21733, -21678, - -21622, -21566, -21510, -21455, -21399, -21343, -21288, -21232, - -21177, -21121, -21066, -21010, -20955, -20900, -20844, -20789, - -20734, -20678, -20623, -20568, -20513, -20457, -20402, -20347, - -20292, -20237, -20182, -20127, -20072, -20017, -19962, -19907, - -19852, -19797, -19742, -19688, -19633, -19578, -19523, -19469, - -19414, -19359, -19305, -19250, -19195, -19141, -19086, -19032, - -18977, -18923, -18868, -18814, -18760, -18705, -18651, -18597, - -18542, -18488, -18434, -18380, -18325, -18271, -18217, -18163, - -18109, -18055, -18001, -17946, -17892, -17838, -17784, -17731, - -17677, -17623, -17569, -17515, -17461, -17407, -17353, -17300, - -17246, -17192, -17138, -17085, -17031, -16977, -16924, -16870, - -16817, -16763, -16710, -16656, -16603, -16549, -16496, -16442, - -16389, -16335, -16282, -16229, -16175, -16122, -16069, -16015, - -15962, -15909, -15856, -15802, -15749, -15696, -15643, -15590, - -15537, -15484, -15431, -15378, -15325, -15272, -15219, -15166, - -15113, -15060, -15007, -14954, -14901, -14848, -14795, -14743, - -14690, -14637, -14584, -14531, -14479, -14426, -14373, -14321, - -14268, -14215, -14163, -14110, -14057, -14005, -13952, -13900, - -13847, -13795, -13742, -13690, -13637, -13585, -13533, -13480, - -13428, -13375, -13323, -13271, -13218, -13166, -13114, -13062, - -13009, -12957, -12905, -12853, -12800, -12748, -12696, -12644, - -12592, -12540, -12488, -12436, -12383, -12331, -12279, -12227, - -12175, -12123, -12071, -12019, -11967, -11916, -11864, -11812, - -11760, -11708, -11656, -11604, -11552, -11501, -11449, -11397, - -11345, -11293, -11242, -11190, -11138, -11086, -11035, -10983, - -10931, -10880, -10828, -10777, -10725, -10673, -10622, -10570, - -10519, -10467, -10415, -10364, -10312, -10261, -10209, -10158, - -10106, -10055, -10004, -9952, -9901, -9849, -9798, -9747, - -9695, -9644, -9592, -9541, -9490, -9438, -9387, -9336, - -9285, -9233, -9182, -9131, -9080, -9028, -8977, -8926, - -8875, -8824, -8772, -8721, -8670, -8619, -8568, -8517, - -8466, -8414, -8363, -8312, -8261, -8210, -8159, -8108, - -8057, -8006, -7955, -7904, -7853, -7802, -7751, -7700, - -7649, -7598, -7547, -7496, -7445, -7395, -7344, -7293, - -7242, -7191, -7140, -7089, -7038, -6988, -6937, -6886, - -6835, -6784, -6733, -6683, -6632, -6581, -6530, -6480, - -6429, -6378, -6327, -6277, -6226, -6175, -6124, -6074, - -6023, -5972, -5922, -5871, -5820, -5770, -5719, -5668, - -5618, -5567, -5517, -5466, -5415, -5365, -5314, -5264, - -5213, -5162, -5112, -5061, -5011, -4960, -4910, -4859, - -4808, -4758, -4707, -4657, -4606, -4556, -4505, -4455, - -4404, -4354, -4303, -4253, -4202, -4152, -4101, -4051, - -4001, -3950, -3900, -3849, -3799, -3748, -3698, -3648, - -3597, -3547, -3496, -3446, -3395, -3345, -3295, -3244, - -3194, -3144, -3093, -3043, -2992, -2942, -2892, -2841, - -2791, -2741, -2690, -2640, -2590, -2539, -2489, -2439, - -2388, -2338, -2288, -2237, -2187, -2137, -2086, -2036, - -1986, -1935, -1885, -1835, -1784, -1734, -1684, -1633, - -1583, -1533, -1483, -1432, -1382, -1332, -1281, -1231, - -1181, -1131, -1080, -1030, -980, -929, -879, -829, - -779, -728, -678, -628, -578, -527, -477, -427, - -376, -326, -276, -226, -175, -125, -75, -25, - 25, 75, 125, 175, 226, 276, 326, 376, - 427, 477, 527, 578, 628, 678, 728, 779, - 829, 879, 929, 980, 1030, 1080, 1131, 1181, - 1231, 1281, 1332, 1382, 1432, 1483, 1533, 1583, - 1633, 1684, 1734, 1784, 1835, 1885, 1935, 1986, - 2036, 2086, 2137, 2187, 2237, 2288, 2338, 2388, - 2439, 2489, 2539, 2590, 2640, 2690, 2741, 2791, - 2841, 2892, 2942, 2992, 3043, 3093, 3144, 3194, - 3244, 3295, 3345, 3395, 3446, 3496, 3547, 3597, - 3648, 3698, 3748, 3799, 3849, 3900, 3950, 4001, - 4051, 4101, 4152, 4202, 4253, 4303, 4354, 4404, - 4455, 4505, 4556, 4606, 4657, 4707, 4758, 4808, - 4859, 4910, 4960, 5011, 5061, 5112, 5162, 5213, - 5264, 5314, 5365, 5415, 5466, 5517, 5567, 5618, - 5668, 5719, 5770, 5820, 5871, 5922, 5972, 6023, - 6074, 6124, 6175, 6226, 6277, 6327, 6378, 6429, - 6480, 6530, 6581, 6632, 6683, 6733, 6784, 6835, - 6886, 6937, 6988, 7038, 7089, 7140, 7191, 7242, - 7293, 7344, 7395, 7445, 7496, 7547, 7598, 7649, - 7700, 7751, 7802, 7853, 7904, 7955, 8006, 8057, - 8108, 8159, 8210, 8261, 8312, 8363, 8414, 8466, - 8517, 8568, 8619, 8670, 8721, 8772, 8824, 8875, - 8926, 8977, 9028, 9080, 9131, 9182, 9233, 9285, - 9336, 9387, 9438, 9490, 9541, 9592, 9644, 9695, - 9747, 9798, 9849, 9901, 9952, 10004, 10055, 10106, - 10158, 10209, 10261, 10312, 10364, 10415, 10467, 10519, - 10570, 10622, 10673, 10725, 10777, 10828, 10880, 10931, - 10983, 11035, 11086, 11138, 11190, 11242, 11293, 11345, - 11397, 11449, 11501, 11552, 11604, 11656, 11708, 11760, - 11812, 11864, 11916, 11967, 12019, 12071, 12123, 12175, - 12227, 12279, 12331, 12383, 12436, 12488, 12540, 12592, - 12644, 12696, 12748, 12800, 12853, 12905, 12957, 13009, - 13062, 13114, 13166, 13218, 13271, 13323, 13375, 13428, - 13480, 13533, 13585, 13637, 13690, 13742, 13795, 13847, - 13900, 13952, 14005, 14057, 14110, 14163, 14215, 14268, - 14321, 14373, 14426, 14479, 14531, 14584, 14637, 14690, - 14743, 14795, 14848, 14901, 14954, 15007, 15060, 15113, - 15166, 15219, 15272, 15325, 15378, 15431, 15484, 15537, - 15590, 15643, 15696, 15749, 15802, 15856, 15909, 15962, - 16015, 16069, 16122, 16175, 16229, 16282, 16335, 16389, - 16442, 16496, 16549, 16603, 16656, 16710, 16763, 16817, - 16870, 16924, 16977, 17031, 17085, 17138, 17192, 17246, - 17300, 17353, 17407, 17461, 17515, 17569, 17623, 17677, - 17731, 17784, 17838, 17892, 17946, 18001, 18055, 18109, - 18163, 18217, 18271, 18325, 18380, 18434, 18488, 18542, - 18597, 18651, 18705, 18760, 18814, 18868, 18923, 18977, - 19032, 19086, 19141, 19195, 19250, 19305, 19359, 19414, - 19469, 19523, 19578, 19633, 19688, 19742, 19797, 19852, - 19907, 19962, 20017, 20072, 20127, 20182, 20237, 20292, - 20347, 20402, 20457, 20513, 20568, 20623, 20678, 20734, - 20789, 20844, 20900, 20955, 21010, 21066, 21121, 21177, - 21232, 21288, 21343, 21399, 21455, 21510, 21566, 21622, - 21678, 21733, 21789, 21845, 21901, 21957, 22013, 22069, - 22125, 22181, 22237, 22293, 22349, 22405, 22461, 22517, - 22573, 22630, 22686, 22742, 22799, 22855, 22911, 22968, - 23024, 23081, 23137, 23194, 23250, 23307, 23364, 23420, - 23477, 23534, 23591, 23647, 23704, 23761, 23818, 23875, - 23932, 23989, 24046, 24103, 24160, 24217, 24274, 24331, - 24389, 24446, 24503, 24560, 24618, 24675, 24732, 24790, - 24847, 24905, 24962, 25020, 25078, 25135, 25193, 25251, - 25308, 25366, 25424, 25482, 25540, 25598, 25656, 25714, - 25772, 25830, 25888, 25946, 26004, 26062, 26120, 26179, - 26237, 26295, 26354, 26412, 26471, 26529, 26588, 26646, - 26705, 26763, 26822, 26881, 26940, 26998, 27057, 27116, - 27175, 27234, 27293, 27352, 27411, 27470, 27529, 27588, - 27647, 27707, 27766, 27825, 27884, 27944, 28003, 28063, - 28122, 28182, 28241, 28301, 28361, 28420, 28480, 28540, - 28600, 28660, 28719, 28779, 28839, 28899, 28959, 29020, - 29080, 29140, 29200, 29260, 29321, 29381, 29441, 29502, - 29562, 29623, 29683, 29744, 29805, 29865, 29926, 29987, - 30048, 30108, 30169, 30230, 30291, 30352, 30413, 30474, - 30536, 30597, 30658, 30719, 30781, 30842, 30904, 30965, - 31026, 31088, 31150, 31211, 31273, 31335, 31396, 31458, - 31520, 31582, 31644, 31706, 31768, 31830, 31892, 31955, - 32017, 32079, 32141, 32204, 32266, 32329, 32391, 32454, - 32516, 32579, 32642, 32705, 32767, 32830, 32893, 32956, - 33019, 33082, 33145, 33208, 33272, 33335, 33398, 33461, - 33525, 33588, 33652, 33715, 33779, 33843, 33906, 33970, - 34034, 34098, 34162, 34225, 34289, 34354, 34418, 34482, - 34546, 34610, 34675, 34739, 34803, 34868, 34932, 34997, - 35062, 35126, 35191, 35256, 35321, 35385, 35450, 35515, - 35580, 35646, 35711, 35776, 35841, 35907, 35972, 36037, - 36103, 36168, 36234, 36300, 36365, 36431, 36497, 36563, - 36629, 36695, 36761, 36827, 36893, 36959, 37026, 37092, - 37158, 37225, 37291, 37358, 37425, 37491, 37558, 37625, - 37692, 37759, 37826, 37893, 37960, 38027, 38094, 38161, - 38229, 38296, 38364, 38431, 38499, 38566, 38634, 38702, - 38770, 38837, 38905, 38973, 39042, 39110, 39178, 39246, - 39314, 39383, 39451, 39520, 39588, 39657, 39726, 39794, - 39863, 39932, 40001, 40070, 40139, 40208, 40278, 40347, - 40416, 40486, 40555, 40625, 40694, 40764, 40834, 40904, - 40973, 41043, 41113, 41184, 41254, 41324, 41394, 41465, - 41535, 41605, 41676, 41747, 41817, 41888, 41959, 42030, - 42101, 42172, 42243, 42314, 42385, 42457, 42528, 42600, - 42671, 42743, 42814, 42886, 42958, 43030, 43102, 43174, - 43246, 43318, 43390, 43463, 43535, 43608, 43680, 43753, - 43826, 43898, 43971, 44044, 44117, 44190, 44263, 44337, - 44410, 44483, 44557, 44630, 44704, 44778, 44851, 44925, - 44999, 45073, 45147, 45221, 45296, 45370, 45444, 45519, - 45593, 45668, 45743, 45818, 45892, 45967, 46042, 46118, - 46193, 46268, 46343, 46419, 46494, 46570, 46646, 46721, - 46797, 46873, 46949, 47025, 47102, 47178, 47254, 47331, - 47407, 47484, 47560, 47637, 47714, 47791, 47868, 47945, - 48022, 48100, 48177, 48255, 48332, 48410, 48488, 48565, - 48643, 48721, 48799, 48878, 48956, 49034, 49113, 49191, - 49270, 49349, 49427, 49506, 49585, 49664, 49744, 49823, - 49902, 49982, 50061, 50141, 50221, 50300, 50380, 50460, - 50540, 50621, 50701, 50781, 50862, 50942, 51023, 51104, - 51185, 51266, 51347, 51428, 51509, 51591, 51672, 51754, - 51835, 51917, 51999, 52081, 52163, 52245, 52327, 52410, - 52492, 52575, 52657, 52740, 52823, 52906, 52989, 53072, - 53156, 53239, 53322, 53406, 53490, 53574, 53657, 53741, - 53826, 53910, 53994, 54079, 54163, 54248, 54333, 54417, - 54502, 54587, 54673, 54758, 54843, 54929, 55015, 55100, - 55186, 55272, 55358, 55444, 55531, 55617, 55704, 55790, - 55877, 55964, 56051, 56138, 56225, 56312, 56400, 56487, - 56575, 56663, 56751, 56839, 56927, 57015, 57104, 57192, - 57281, 57369, 57458, 57547, 57636, 57725, 57815, 57904, - 57994, 58083, 58173, 58263, 58353, 58443, 58534, 58624, - 58715, 58805, 58896, 58987, 59078, 59169, 59261, 59352, - 59444, 59535, 59627, 59719, 59811, 59903, 59996, 60088, - 60181, 60273, 60366, 60459, 60552, 60646, 60739, 60833, - 60926, 61020, 61114, 61208, 61302, 61396, 61491, 61585, - 61680, 61775, 61870, 61965, 62060, 62156, 62251, 62347, - 62443, 62539, 62635, 62731, 62828, 62924, 63021, 63118, - 63215, 63312, 63409, 63506, 63604, 63702, 63799, 63897, - 63996, 64094, 64192, 64291, 64389, 64488, 64587, 64687, - 64786, 64885, 64985, 65085, 65185, 65285, 65385, 65485, - 65586, 65686, 65787, 65888, 65989, 66091, 66192, 66294, - 66396, 66498, 66600, 66702, 66804, 66907, 67010, 67113, - 67216, 67319, 67422, 67526, 67629, 67733, 67837, 67942, - 68046, 68151, 68255, 68360, 68465, 68570, 68676, 68781, - 68887, 68993, 69099, 69205, 69312, 69418, 69525, 69632, - 69739, 69846, 69954, 70061, 70169, 70277, 70385, 70494, - 70602, 70711, 70820, 70929, 71038, 71147, 71257, 71367, - 71477, 71587, 71697, 71808, 71918, 72029, 72140, 72252, - 72363, 72475, 72587, 72699, 72811, 72923, 73036, 73149, - 73262, 73375, 73488, 73602, 73715, 73829, 73944, 74058, - 74172, 74287, 74402, 74517, 74633, 74748, 74864, 74980, - 75096, 75213, 75329, 75446, 75563, 75680, 75797, 75915, - 76033, 76151, 76269, 76388, 76506, 76625, 76744, 76864, - 76983, 77103, 77223, 77343, 77463, 77584, 77705, 77826, - 77947, 78068, 78190, 78312, 78434, 78557, 78679, 78802, - 78925, 79048, 79172, 79296, 79420, 79544, 79668, 79793, - 79918, 80043, 80168, 80294, 80420, 80546, 80672, 80799, - 80925, 81053, 81180, 81307, 81435, 81563, 81691, 81820, - 81949, 82078, 82207, 82336, 82466, 82596, 82726, 82857, - 82987, 83118, 83250, 83381, 83513, 83645, 83777, 83910, - 84043, 84176, 84309, 84443, 84576, 84710, 84845, 84980, - 85114, 85250, 85385, 85521, 85657, 85793, 85930, 86066, - 86204, 86341, 86479, 86616, 86755, 86893, 87032, 87171, - 87310, 87450, 87590, 87730, 87871, 88011, 88152, 88294, - 88435, 88577, 88720, 88862, 89005, 89148, 89292, 89435, - 89579, 89724, 89868, 90013, 90158, 90304, 90450, 90596, - 90742, 90889, 91036, 91184, 91332, 91480, 91628, 91777, - 91926, 92075, 92225, 92375, 92525, 92675, 92826, 92978, - 93129, 93281, 93434, 93586, 93739, 93892, 94046, 94200, - 94354, 94509, 94664, 94819, 94975, 95131, 95287, 95444, - 95601, 95758, 95916, 96074, 96233, 96391, 96551, 96710, - 96870, 97030, 97191, 97352, 97513, 97675, 97837, 98000, - 98163, 98326, 98489, 98653, 98818, 98982, 99148, 99313, - 99479, 99645, 99812, 99979, 100146, 100314, 100482, 100651, - 100820, 100990, 101159, 101330, 101500, 101671, 101843, 102015, - 102187, 102360, 102533, 102706, 102880, 103054, 103229, 103404, - 103580, 103756, 103933, 104109, 104287, 104465, 104643, 104821, - 105000, 105180, 105360, 105540, 105721, 105902, 106084, 106266, - 106449, 106632, 106816, 107000, 107184, 107369, 107555, 107741, - 107927, 108114, 108301, 108489, 108677, 108866, 109055, 109245, - 109435, 109626, 109817, 110008, 110200, 110393, 110586, 110780, - 110974, 111169, 111364, 111560, 111756, 111952, 112150, 112347, - 112546, 112744, 112944, 113143, 113344, 113545, 113746, 113948, - 114151, 114354, 114557, 114761, 114966, 115171, 115377, 115583, - 115790, 115998, 116206, 116414, 116623, 116833, 117044, 117254, - 117466, 117678, 117891, 118104, 118318, 118532, 118747, 118963, - 119179, 119396, 119613, 119831, 120050, 120269, 120489, 120709, - 120930, 121152, 121374, 121597, 121821, 122045, 122270, 122496, - 122722, 122949, 123176, 123404, 123633, 123863, 124093, 124324, - 124555, 124787, 125020, 125254, 125488, 125723, 125959, 126195, - 126432, 126669, 126908, 127147, 127387, 127627, 127869, 128111, - 128353, 128597, 128841, 129086, 129332, 129578, 129825, 130073, - 130322, 130571, 130821, 131072, 131324, 131576, 131830, 132084, - 132339, 132594, 132851, 133108, 133366, 133625, 133884, 134145, - 134406, 134668, 134931, 135195, 135459, 135725, 135991, 136258, - 136526, 136795, 137065, 137335, 137607, 137879, 138152, 138426, - 138701, 138977, 139254, 139532, 139810, 140090, 140370, 140651, - 140934, 141217, 141501, 141786, 142072, 142359, 142647, 142936, - 143226, 143517, 143808, 144101, 144395, 144690, 144986, 145282, - 145580, 145879, 146179, 146480, 146782, 147084, 147388, 147693, - 148000, 148307, 148615, 148924, 149235, 149546, 149859, 150172, - 150487, 150803, 151120, 151438, 151757, 152077, 152399, 152722, - 153045, 153370, 153697, 154024, 154352, 154682, 155013, 155345, - 155678, 156013, 156349, 156686, 157024, 157363, 157704, 158046, - 158389, 158734, 159079, 159427, 159775, 160125, 160476, 160828, - 161182, 161537, 161893, 162251, 162610, 162970, 163332, 163695, - 164060, 164426, 164793, 165162, 165532, 165904, 166277, 166651, - 167027, 167405, 167784, 168164, 168546, 168930, 169315, 169701, - 170089, 170479, 170870, 171263, 171657, 172053, 172451, 172850, - 173251, 173653, 174057, 174463, 174870, 175279, 175690, 176102, - 176516, 176932, 177349, 177769, 178190, 178612, 179037, 179463, - 179891, 180321, 180753, 181186, 181622, 182059, 182498, 182939, - 183382, 183827, 184274, 184722, 185173, 185625, 186080, 186536, - 186995, 187455, 187918, 188382, 188849, 189318, 189789, 190261, - 190736, 191213, 191693, 192174, 192658, 193143, 193631, 194122, - 194614, 195109, 195606, 196105, 196606, 197110, 197616, 198125, - 198636, 199149, 199664, 200182, 200703, 201226, 201751, 202279, - 202809, 203342, 203878, 204416, 204956, 205500, 206045, 206594, - 207145, 207699, 208255, 208815, 209376, 209941, 210509, 211079, - 211652, 212228, 212807, 213389, 213973, 214561, 215151, 215745, - 216341, 216941, 217544, 218149, 218758, 219370, 219985, 220603, - 221225, 221849, 222477, 223108, 223743, 224381, 225022, 225666, - 226314, 226966, 227621, 228279, 228941, 229606, 230275, 230948, - 231624, 232304, 232988, 233676, 234367, 235062, 235761, 236463, - 237170, 237881, 238595, 239314, 240036, 240763, 241493, 242228, - 242967, 243711, 244458, 245210, 245966, 246727, 247492, 248261, - 249035, 249813, 250596, 251384, 252176, 252973, 253774, 254581, - 255392, 256208, 257029, 257855, 258686, 259522, 260363, 261209, - 262060, 262917, 263779, 264646, 265519, 266397, 267280, 268169, - 269064, 269965, 270871, 271782, 272700, 273624, 274553, 275489, - 276430, 277378, 278332, 279292, 280258, 281231, 282210, 283195, - 284188, 285186, 286192, 287204, 288223, 289249, 290282, 291322, - 292369, 293423, 294485, 295554, 296630, 297714, 298805, 299904, - 301011, 302126, 303248, 304379, 305517, 306664, 307819, 308983, - 310154, 311335, 312524, 313721, 314928, 316143, 317368, 318601, - 319844, 321097, 322358, 323629, 324910, 326201, 327502, 328812, - 330133, 331464, 332805, 334157, 335519, 336892, 338276, 339671, - 341078, 342495, 343924, 345364, 346816, 348280, 349756, 351244, - 352744, 354257, 355783, 357321, 358872, 360436, 362013, 363604, - 365208, 366826, 368459, 370105, 371765, 373440, 375130, 376835, - 378555, 380290, 382040, 383807, 385589, 387387, 389202, 391034, - 392882, 394747, 396630, 398530, 400448, 402384, 404338, 406311, - 408303, 410314, 412344, 414395, 416465, 418555, 420666, 422798, - 424951, 427125, 429321, 431540, 433781, 436045, 438332, 440643, - 442978, 445337, 447720, 450129, 452564, 455024, 457511, 460024, - 462565, 465133, 467730, 470355, 473009, 475692, 478406, 481150, - 483925, 486732, 489571, 492443, 495348, 498287, 501261, 504269, - 507313, 510394, 513512, 516667, 519861, 523094, 526366, 529680, - 533034, 536431, 539870, 543354, 546881, 550455, 554074, 557741, - 561456, 565221, 569035, 572901, 576818, 580789, 584815, 588896, - 593033, 597229, 601483, 605798, 610174, 614613, 619117, 623686, - 628323, 633028, 637803, 642651, 647572, 652568, 657640, 662792, - 668024, 673338, 678737, 684223, 689797, 695462, 701219, 707072, - 713023, 719074, 725227, 731486, 737853, 744331, 750922, 757631, - 764460, 771411, 778490, 785699, 793041, 800521, 808143, 815910, - 823827, 831898, 840127, 848520, 857081, 865817, 874730, 883829, - 893117, 902602, 912289, 922186, 932298, 942633, 953199, 964003, - 975054, 986361, 997931, 1009774, 1021901, 1034322, 1047046, 1060087, - 1073455, 1087164, 1101225, 1115654, 1130465, 1145673, 1161294, 1177345, - 1193846, 1210813, 1228269, 1246234, 1264730, 1283783, 1303416, 1323658, - 1344537, 1366084, 1388330, 1411312, 1435065, 1459630, 1485049, 1511367, - 1538632, 1566898, 1596220, 1626658, 1658278, 1691149, 1725348, 1760956, - 1798063, 1836758, 1877161, 1919378, 1963536, 2009771, 2058233, 2109087, - 2162516, 2218719, 2277919, 2340362, 2406322, 2476104, 2550052, 2628549, - 2712030, 2800983, 2895966, 2997613, 3106651, 3223918, 3350381, 3487165, - 3635590, 3797206, 3973855, 4167737, 4381502, 4618375, 4882318, 5178251, - 5512368, 5892567, 6329090, 6835455, 7429880, 8137527, 8994149, 10052327, - 11392683, 13145455, 15535599, 18988036, 24413316, 34178904, 56965752, 170910304 + INT32_MIN, -85445642, -42722796, -28481836, -21361347, -17089048, -14240842, -12206405, + -10680573, -9493811, -8544398, -7767602, -7120270, -6572525, -6103026, -5696125, + -5340085, -5025930, -4746679, -4496821, -4271947, -4068489, -3883524, -3714643, + -3559833, -3417407, -3285935, -3164201, -3051161, -2945916, -2847685, -2755792, + -2669640, -2588709, -2512537, -2440718, -2372887, -2308722, -2247933, -2190260, + -2135471, -2083353, -2033716, -1986387, -1941209, -1898038, -1856743, -1817205, + -1779313, -1742967, -1708075, -1674550, -1642314, -1611294, -1581422, -1552635, + -1524876, -1498091, -1472229, -1447242, -1423088, -1399726, -1377116, -1355224, + -1334015, -1313459, -1293525, -1274185, -1255414, -1237186, -1219479, -1202270, + -1185538, -1169265, -1153430, -1138018, -1123011, -1108393, -1094149, -1080266, + -1066729, -1053527, -1040645, -1028074, -1015802, -1003818, -992112, -980675, + -969498, -958571, -947887, -937438, -927215, -917211, -907420, -897835, + -888449, -879257, -870251, -861428, -852780, -844303, -835992, -827843, + -819849, -812008, -804314, -796763, -789353, -782077, -774934, -767919, + -761030, -754261, -747612, -741077, -734655, -728343, -722137, -716035, + -710035, -704133, -698328, -692618, -686999, -681469, -676027, -670671, + -665398, -660206, -655094, -650060, -645102, -640218, -635407, -630667, + -625996, -621393, -616857, -612386, -607978, -603633, -599348, -595124, + -590957, -586848, -582795, -578797, -574853, -570962, -567122, -563332, + -559593, -555902, -552259, -548662, -545112, -541606, -538145, -534727, + -531351, -528018, -524725, -521472, -518259, -515084, -511948, -508849, + -505787, -502760, -499769, -496813, -493891, -491003, -488148, -485325, + -482534, -479774, -477045, -474347, -471678, -469038, -466428, -463845, + -461291, -458764, -456264, -453791, -451343, -448922, -446526, -444154, + -441807, -439485, -437186, -434910, -432658, -430428, -428221, -426035, + -423871, -421729, -419608, -417507, -415427, -413367, -411327, -409306, + -407305, -405323, -403359, -401414, -399487, -397578, -395686, -393812, + -391956, -390116, -388293, -386486, -384696, -382921, -381163, -379420, + -377693, -375981, -374283, -372601, -370933, -369280, -367641, -366016, + -364404, -362807, -361223, -359652, -358094, -356550, -355018, -353499, + -351993, -350499, -349017, -347547, -346089, -344643, -343208, -341785, + -340373, -338973, -337583, -336204, -334837, -333480, -332133, -330797, + -329471, -328156, -326850, -325554, -324269, -322993, -321726, -320469, + -319222, -317984, -316754, -315535, -314324, -313121, -311928, -310743, + -309567, -308400, -307240, -306090, -304947, -303812, -302686, -301567, + -300457, -299354, -298259, -297171, -296091, -295018, -293953, -292895, + -291845, -290801, -289765, -288735, -287713, -286697, -285688, -284686, + -283691, -282702, -281719, -280743, -279774, -278811, -277854, -276903, + -275959, -275020, -274088, -273161, -272241, -271326, -270417, -269514, + -268616, -267724, -266838, -265957, -265082, -264212, -263347, -262488, + -261634, -260785, -259941, -259103, -258270, -257441, -256618, -255799, + -254986, -254177, -253373, -252574, -251779, -250989, -250204, -249423, + -248647, -247876, -247109, -246346, -245588, -244834, -244084, -243338, + -242597, -241860, -241128, -240399, -239674, -238954, -238237, -237525, + -236816, -236112, -235411, -234714, -234021, -233331, -232646, -231964, + -231286, -230611, -229940, -229273, -228610, -227949, -227293, -226640, + -225990, -225344, -224701, -224061, -223425, -222792, -222163, -221536, + -220913, -220294, -219677, -219064, -218453, -217846, -217242, -216641, + -216043, -215448, -214856, -214267, -213681, -213097, -212517, -211940, + -211365, -210793, -210225, -209658, -209095, -208535, -207977, -207422, + -206869, -206319, -205772, -205228, -204686, -204147, -203610, -203076, + -202544, -202015, -201488, -200964, -200442, -199923, -199406, -198892, + -198380, -197870, -197363, -196858, -196355, -195855, -195357, -194861, + -194367, -193876, -193387, -192900, -192416, -191933, -191453, -190975, + -190499, -190025, -189553, -189083, -188615, -188150, -187686, -187225, + -186765, -186308, -185852, -185399, -184947, -184498, -184050, -183604, + -183160, -182718, -182278, -181840, -181404, -180969, -180537, -180106, + -179677, -179250, -178824, -178401, -177979, -177559, -177140, -176724, + -176309, -175896, -175484, -175074, -174666, -174260, -173855, -173452, + -173050, -172650, -172252, -171855, -171460, -171066, -170674, -170284, + -169895, -169508, -169122, -168738, -168355, -167974, -167594, -167216, + -166839, -166464, -166090, -165718, -165347, -164977, -164609, -164242, + -163877, -163513, -163151, -162790, -162430, -162072, -161715, -161359, + -161005, -160652, -160300, -159950, -159601, -159253, -158906, -158561, + -158217, -157875, -157533, -157193, -156855, -156517, -156181, -155845, + -155512, -155179, -154847, -154517, -154188, -153860, -153533, -153208, + -152883, -152560, -152238, -151917, -151597, -151279, -150961, -150645, + -150329, -150015, -149702, -149390, -149079, -148769, -148461, -148153, + -147846, -147541, -147236, -146933, -146630, -146329, -146029, -145729, + -145431, -145134, -144837, -144542, -144248, -143955, -143662, -143371, + -143081, -142791, -142503, -142215, -141929, -141643, -141359, -141075, + -140792, -140511, -140230, -139950, -139671, -139393, -139115, -138839, + -138564, -138289, -138016, -137743, -137471, -137200, -136930, -136661, + -136392, -136125, -135858, -135592, -135327, -135063, -134799, -134537, + -134275, -134014, -133754, -133495, -133237, -132979, -132722, -132466, + -132211, -131957, -131703, -131450, -131198, -130947, -130696, -130446, + -130197, -129949, -129701, -129455, -129209, -128963, -128719, -128475, + -128232, -127990, -127748, -127507, -127267, -127027, -126789, -126551, + -126313, -126077, -125841, -125605, -125371, -125137, -124904, -124671, + -124439, -124208, -123978, -123748, -123519, -123290, -123062, -122835, + -122609, -122383, -122158, -121933, -121709, -121486, -121263, -121041, + -120820, -120599, -120379, -120159, -119940, -119722, -119504, -119287, + -119071, -118855, -118639, -118425, -118211, -117997, -117784, -117572, + -117360, -117149, -116938, -116728, -116519, -116310, -116102, -115894, + -115687, -115480, -115274, -115069, -114864, -114659, -114455, -114252, + -114049, -113847, -113645, -113444, -113244, -113043, -112844, -112645, + -112446, -112248, -112051, -111854, -111658, -111462, -111266, -111071, + -110877, -110683, -110490, -110297, -110104, -109912, -109721, -109530, + -109340, -109150, -108960, -108771, -108583, -108395, -108207, -108020, + -107834, -107648, -107462, -107277, -107092, -106908, -106724, -106541, + -106358, -106175, -105993, -105812, -105631, -105450, -105270, -105090, + -104911, -104732, -104554, -104376, -104198, -104021, -103844, -103668, + -103492, -103317, -103142, -102967, -102793, -102619, -102446, -102273, + -102101, -101929, -101757, -101586, -101415, -101244, -101074, -100905, + -100736, -100567, -100398, -100230, -100063, -99895, -99729, -99562, + -99396, -99230, -99065, -98900, -98735, -98571, -98408, -98244, + -98081, -97918, -97756, -97594, -97433, -97271, -97111, -96950, + -96790, -96630, -96471, -96312, -96153, -95995, -95837, -95680, + -95522, -95365, -95209, -95053, -94897, -94741, -94586, -94431, + -94277, -94123, -93969, -93816, -93663, -93510, -93357, -93205, + -93053, -92902, -92751, -92600, -92450, -92300, -92150, -92000, + -91851, -91702, -91554, -91406, -91258, -91110, -90963, -90816, + -90669, -90523, -90377, -90231, -90086, -89941, -89796, -89651, + -89507, -89363, -89220, -89077, -88934, -88791, -88648, -88506, + -88365, -88223, -88082, -87941, -87800, -87660, -87520, -87380, + -87241, -87101, -86963, -86824, -86686, -86547, -86410, -86272, + -86135, -85998, -85861, -85725, -85589, -85453, -85317, -85182, + -85047, -84912, -84778, -84643, -84509, -84376, -84242, -84109, + -83976, -83843, -83711, -83579, -83447, -83315, -83184, -83053, + -82922, -82791, -82661, -82531, -82401, -82271, -82142, -82013, + -81884, -81756, -81627, -81499, -81371, -81244, -81116, -80989, + -80862, -80735, -80609, -80483, -80357, -80231, -80106, -79980, + -79855, -79731, -79606, -79482, -79358, -79234, -79110, -78987, + -78864, -78741, -78618, -78495, -78373, -78251, -78129, -78008, + -77886, -77765, -77644, -77524, -77403, -77283, -77163, -77043, + -76923, -76804, -76685, -76566, -76447, -76328, -76210, -76092, + -75974, -75856, -75739, -75621, -75504, -75387, -75271, -75154, + -75038, -74922, -74806, -74690, -74575, -74460, -74345, -74230, + -74115, -74001, -73886, -73772, -73659, -73545, -73431, -73318, + -73205, -73092, -72979, -72867, -72755, -72643, -72531, -72419, + -72307, -72196, -72085, -71974, -71863, -71752, -71642, -71532, + -71422, -71312, -71202, -71093, -70983, -70874, -70765, -70656, + -70548, -70439, -70331, -70223, -70115, -70007, -69900, -69793, + -69685, -69578, -69472, -69365, -69258, -69152, -69046, -68940, + -68834, -68728, -68623, -68518, -68413, -68308, -68203, -68098, + -67994, -67889, -67785, -67681, -67578, -67474, -67371, -67267, + -67164, -67061, -66958, -66856, -66753, -66651, -66549, -66447, + -66345, -66243, -66141, -66040, -65939, -65838, -65737, -65636, + -65536, -65435, -65335, -65235, -65135, -65035, -64935, -64836, + -64736, -64637, -64538, -64439, -64340, -64241, -64143, -64045, + -63946, -63848, -63750, -63653, -63555, -63458, -63360, -63263, + -63166, -63069, -62972, -62876, -62779, -62683, -62587, -62491, + -62395, -62299, -62204, -62108, -62013, -61918, -61822, -61728, + -61633, -61538, -61444, -61349, -61255, -61161, -61067, -60973, + -60879, -60786, -60692, -60599, -60506, -60413, -60320, -60227, + -60134, -60042, -59950, -59857, -59765, -59673, -59581, -59489, + -59398, -59306, -59215, -59124, -59033, -58942, -58851, -58760, + -58669, -58579, -58489, -58398, -58308, -58218, -58128, -58039, + -57949, -57859, -57770, -57681, -57592, -57503, -57414, -57325, + -57236, -57148, -57059, -56971, -56883, -56795, -56707, -56619, + -56531, -56444, -56356, -56269, -56181, -56094, -56007, -55920, + -55834, -55747, -55660, -55574, -55487, -55401, -55315, -55229, + -55143, -55057, -54972, -54886, -54801, -54715, -54630, -54545, + -54460, -54375, -54290, -54205, -54121, -54036, -53952, -53868, + -53784, -53699, -53615, -53532, -53448, -53364, -53281, -53197, + -53114, -53031, -52948, -52865, -52782, -52699, -52616, -52533, + -52451, -52369, -52286, -52204, -52122, -52040, -51958, -51876, + -51794, -51713, -51631, -51550, -51469, -51387, -51306, -51225, + -51144, -51063, -50983, -50902, -50822, -50741, -50661, -50581, + -50500, -50420, -50340, -50260, -50181, -50101, -50021, -49942, + -49862, -49783, -49704, -49625, -49546, -49467, -49388, -49309, + -49230, -49152, -49073, -48995, -48917, -48838, -48760, -48682, + -48604, -48526, -48449, -48371, -48293, -48216, -48138, -48061, + -47984, -47907, -47830, -47753, -47676, -47599, -47522, -47445, + -47369, -47292, -47216, -47140, -47063, -46987, -46911, -46835, + -46759, -46684, -46608, -46532, -46457, -46381, -46306, -46230, + -46155, -46080, -46005, -45930, -45855, -45780, -45705, -45631, + -45556, -45482, -45407, -45333, -45259, -45184, -45110, -45036, + -44962, -44888, -44815, -44741, -44667, -44594, -44520, -44447, + -44373, -44300, -44227, -44154, -44081, -44008, -43935, -43862, + -43789, -43717, -43644, -43571, -43499, -43427, -43354, -43282, + -43210, -43138, -43066, -42994, -42922, -42850, -42779, -42707, + -42635, -42564, -42492, -42421, -42350, -42279, -42207, -42136, + -42065, -41994, -41923, -41853, -41782, -41711, -41641, -41570, + -41500, -41429, -41359, -41289, -41219, -41148, -41078, -41008, + -40939, -40869, -40799, -40729, -40660, -40590, -40520, -40451, + -40382, -40312, -40243, -40174, -40105, -40036, -39967, -39898, + -39829, -39760, -39691, -39623, -39554, -39486, -39417, -39349, + -39280, -39212, -39144, -39076, -39007, -38939, -38871, -38804, + -38736, -38668, -38600, -38532, -38465, -38397, -38330, -38262, + -38195, -38128, -38060, -37993, -37926, -37859, -37792, -37725, + -37658, -37591, -37525, -37458, -37391, -37325, -37258, -37192, + -37125, -37059, -36993, -36926, -36860, -36794, -36728, -36662, + -36596, -36530, -36464, -36398, -36333, -36267, -36201, -36136, + -36070, -36005, -35939, -35874, -35809, -35743, -35678, -35613, + -35548, -35483, -35418, -35353, -35288, -35223, -35159, -35094, + -35029, -34965, -34900, -34836, -34771, -34707, -34642, -34578, + -34514, -34450, -34386, -34322, -34257, -34194, -34130, -34066, + -34002, -33938, -33874, -33811, -33747, -33684, -33620, -33557, + -33493, -33430, -33366, -33303, -33240, -33177, -33114, -33051, + -32988, -32925, -32862, -32799, -32736, -32673, -32610, -32548, + -32485, -32422, -32360, -32297, -32235, -32173, -32110, -32048, + -31986, -31923, -31861, -31799, -31737, -31675, -31613, -31551, + -31489, -31427, -31366, -31304, -31242, -31180, -31119, -31057, + -30996, -30934, -30873, -30811, -30750, -30689, -30627, -30566, + -30505, -30444, -30383, -30322, -30261, -30200, -30139, -30078, + -30017, -29956, -29896, -29835, -29774, -29714, -29653, -29593, + -29532, -29472, -29411, -29351, -29291, -29230, -29170, -29110, + -29050, -28989, -28929, -28869, -28809, -28749, -28689, -28630, + -28570, -28510, -28450, -28390, -28331, -28271, -28212, -28152, + -28092, -28033, -27974, -27914, -27855, -27795, -27736, -27677, + -27618, -27559, -27499, -27440, -27381, -27322, -27263, -27204, + -27145, -27087, -27028, -26969, -26910, -26851, -26793, -26734, + -26675, -26617, -26558, -26500, -26441, -26383, -26325, -26266, + -26208, -26150, -26091, -26033, -25975, -25917, -25859, -25801, + -25743, -25685, -25627, -25569, -25511, -25453, -25395, -25337, + -25280, -25222, -25164, -25106, -25049, -24991, -24934, -24876, + -24819, -24761, -24704, -24646, -24589, -24532, -24474, -24417, + -24360, -24303, -24246, -24188, -24131, -24074, -24017, -23960, + -23903, -23846, -23789, -23733, -23676, -23619, -23562, -23505, + -23449, -23392, -23335, -23279, -23222, -23166, -23109, -23053, + -22996, -22940, -22883, -22827, -22770, -22714, -22658, -22602, + -22545, -22489, -22433, -22377, -22321, -22265, -22209, -22153, + -22097, -22041, -21985, -21929, -21873, -21817, -21761, -21705, + -21650, -21594, -21538, -21483, -21427, -21371, -21316, -21260, + -21205, -21149, -21094, -21038, -20983, -20927, -20872, -20817, + -20761, -20706, -20651, -20595, -20540, -20485, -20430, -20375, + -20320, -20264, -20209, -20154, -20099, -20044, -19989, -19935, + -19880, -19825, -19770, -19715, -19660, -19605, -19551, -19496, + -19441, -19387, -19332, -19277, -19223, -19168, -19114, -19059, + -19005, -18950, -18896, -18841, -18787, -18732, -18678, -18624, + -18569, -18515, -18461, -18407, -18352, -18298, -18244, -18190, + -18136, -18082, -18028, -17974, -17919, -17865, -17811, -17758, + -17704, -17650, -17596, -17542, -17488, -17434, -17380, -17327, + -17273, -17219, -17165, -17112, -17058, -17004, -16951, -16897, + -16843, -16790, -16736, -16683, -16629, -16576, -16522, -16469, + -16415, -16362, -16309, -16255, -16202, -16149, -16095, -16042, + -15989, -15935, -15882, -15829, -15776, -15723, -15670, -15616, + -15563, -15510, -15457, -15404, -15351, -15298, -15245, -15192, + -15139, -15086, -15033, -14980, -14927, -14875, -14822, -14769, + -14716, -14663, -14611, -14558, -14505, -14452, -14400, -14347, + -14294, -14242, -14189, -14136, -14084, -14031, -13979, -13926, + -13874, -13821, -13769, -13716, -13664, -13611, -13559, -13506, + -13454, -13402, -13349, -13297, -13245, -13192, -13140, -13088, + -13035, -12983, -12931, -12879, -12827, -12774, -12722, -12670, + -12618, -12566, -12514, -12462, -12409, -12357, -12305, -12253, + -12201, -12149, -12097, -12045, -11993, -11941, -11890, -11838, + -11786, -11734, -11682, -11630, -11578, -11526, -11475, -11423, + -11371, -11319, -11268, -11216, -11164, -11112, -11061, -11009, + -10957, -10906, -10854, -10802, -10751, -10699, -10647, -10596, + -10544, -10493, -10441, -10390, -10338, -10287, -10235, -10184, + -10132, -10081, -10029, -9978, -9926, -9875, -9824, -9772, + -9721, -9669, -9618, -9567, -9515, -9464, -9413, -9362, + -9310, -9259, -9208, -9156, -9105, -9054, -9003, -8952, + -8900, -8849, -8798, -8747, -8696, -8645, -8593, -8542, + -8491, -8440, -8389, -8338, -8287, -8236, -8185, -8134, + -8083, -8032, -7981, -7930, -7879, -7828, -7777, -7726, + -7675, -7624, -7573, -7522, -7471, -7420, -7369, -7318, + -7267, -7216, -7166, -7115, -7064, -7013, -6962, -6911, + -6861, -6810, -6759, -6708, -6657, -6607, -6556, -6505, + -6454, -6403, -6353, -6302, -6251, -6201, -6150, -6099, + -6048, -5998, -5947, -5896, -5846, -5795, -5744, -5694, + -5643, -5592, -5542, -5491, -5441, -5390, -5339, -5289, + -5238, -5188, -5137, -5086, -5036, -4985, -4935, -4884, + -4834, -4783, -4733, -4682, -4632, -4581, -4531, -4480, + -4430, -4379, -4329, -4278, -4228, -4177, -4127, -4076, + -4026, -3975, -3925, -3874, -3824, -3774, -3723, -3673, + -3622, -3572, -3521, -3471, -3421, -3370, -3320, -3269, + -3219, -3169, -3118, -3068, -3018, -2967, -2917, -2866, + -2816, -2766, -2715, -2665, -2615, -2564, -2514, -2464, + -2413, -2363, -2313, -2262, -2212, -2162, -2111, -2061, + -2011, -1960, -1910, -1860, -1810, -1759, -1709, -1659, + -1608, -1558, -1508, -1457, -1407, -1357, -1307, -1256, + -1206, -1156, -1105, -1055, -1005, -955, -904, -854, + -804, -754, -703, -653, -603, -552, -502, -452, + -402, -351, -301, -251, -201, -150, -100, -50, + 0, 50, 100, 150, 201, 251, 301, 351, + 402, 452, 502, 552, 603, 653, 703, 754, + 804, 854, 904, 955, 1005, 1055, 1105, 1156, + 1206, 1256, 1307, 1357, 1407, 1457, 1508, 1558, + 1608, 1659, 1709, 1759, 1810, 1860, 1910, 1960, + 2011, 2061, 2111, 2162, 2212, 2262, 2313, 2363, + 2413, 2464, 2514, 2564, 2615, 2665, 2715, 2766, + 2816, 2866, 2917, 2967, 3018, 3068, 3118, 3169, + 3219, 3269, 3320, 3370, 3421, 3471, 3521, 3572, + 3622, 3673, 3723, 3774, 3824, 3874, 3925, 3975, + 4026, 4076, 4127, 4177, 4228, 4278, 4329, 4379, + 4430, 4480, 4531, 4581, 4632, 4682, 4733, 4783, + 4834, 4884, 4935, 4985, 5036, 5086, 5137, 5188, + 5238, 5289, 5339, 5390, 5441, 5491, 5542, 5592, + 5643, 5694, 5744, 5795, 5846, 5896, 5947, 5998, + 6048, 6099, 6150, 6201, 6251, 6302, 6353, 6403, + 6454, 6505, 6556, 6607, 6657, 6708, 6759, 6810, + 6861, 6911, 6962, 7013, 7064, 7115, 7166, 7216, + 7267, 7318, 7369, 7420, 7471, 7522, 7573, 7624, + 7675, 7726, 7777, 7828, 7879, 7930, 7981, 8032, + 8083, 8134, 8185, 8236, 8287, 8338, 8389, 8440, + 8491, 8542, 8593, 8645, 8696, 8747, 8798, 8849, + 8900, 8952, 9003, 9054, 9105, 9156, 9208, 9259, + 9310, 9362, 9413, 9464, 9515, 9567, 9618, 9669, + 9721, 9772, 9824, 9875, 9926, 9978, 10029, 10081, + 10132, 10184, 10235, 10287, 10338, 10390, 10441, 10493, + 10544, 10596, 10647, 10699, 10751, 10802, 10854, 10906, + 10957, 11009, 11061, 11112, 11164, 11216, 11268, 11319, + 11371, 11423, 11475, 11526, 11578, 11630, 11682, 11734, + 11786, 11838, 11890, 11941, 11993, 12045, 12097, 12149, + 12201, 12253, 12305, 12357, 12409, 12462, 12514, 12566, + 12618, 12670, 12722, 12774, 12827, 12879, 12931, 12983, + 13035, 13088, 13140, 13192, 13245, 13297, 13349, 13402, + 13454, 13506, 13559, 13611, 13664, 13716, 13769, 13821, + 13874, 13926, 13979, 14031, 14084, 14136, 14189, 14242, + 14294, 14347, 14400, 14452, 14505, 14558, 14611, 14663, + 14716, 14769, 14822, 14875, 14927, 14980, 15033, 15086, + 15139, 15192, 15245, 15298, 15351, 15404, 15457, 15510, + 15563, 15616, 15670, 15723, 15776, 15829, 15882, 15935, + 15989, 16042, 16095, 16149, 16202, 16255, 16309, 16362, + 16415, 16469, 16522, 16576, 16629, 16683, 16736, 16790, + 16843, 16897, 16951, 17004, 17058, 17112, 17165, 17219, + 17273, 17327, 17380, 17434, 17488, 17542, 17596, 17650, + 17704, 17758, 17811, 17865, 17919, 17974, 18028, 18082, + 18136, 18190, 18244, 18298, 18352, 18407, 18461, 18515, + 18569, 18624, 18678, 18732, 18787, 18841, 18896, 18950, + 19005, 19059, 19114, 19168, 19223, 19277, 19332, 19387, + 19441, 19496, 19551, 19605, 19660, 19715, 19770, 19825, + 19880, 19935, 19989, 20044, 20099, 20154, 20209, 20264, + 20320, 20375, 20430, 20485, 20540, 20595, 20651, 20706, + 20761, 20817, 20872, 20927, 20983, 21038, 21094, 21149, + 21205, 21260, 21316, 21371, 21427, 21483, 21538, 21594, + 21650, 21705, 21761, 21817, 21873, 21929, 21985, 22041, + 22097, 22153, 22209, 22265, 22321, 22377, 22433, 22489, + 22545, 22602, 22658, 22714, 22770, 22827, 22883, 22940, + 22996, 23053, 23109, 23166, 23222, 23279, 23335, 23392, + 23449, 23505, 23562, 23619, 23676, 23733, 23789, 23846, + 23903, 23960, 24017, 24074, 24131, 24188, 24246, 24303, + 24360, 24417, 24474, 24532, 24589, 24646, 24704, 24761, + 24819, 24876, 24934, 24991, 25049, 25106, 25164, 25222, + 25280, 25337, 25395, 25453, 25511, 25569, 25627, 25685, + 25743, 25801, 25859, 25917, 25975, 26033, 26091, 26150, + 26208, 26266, 26325, 26383, 26441, 26500, 26558, 26617, + 26675, 26734, 26793, 26851, 26910, 26969, 27028, 27087, + 27145, 27204, 27263, 27322, 27381, 27440, 27499, 27559, + 27618, 27677, 27736, 27795, 27855, 27914, 27974, 28033, + 28092, 28152, 28212, 28271, 28331, 28390, 28450, 28510, + 28570, 28630, 28689, 28749, 28809, 28869, 28929, 28989, + 29050, 29110, 29170, 29230, 29291, 29351, 29411, 29472, + 29532, 29593, 29653, 29714, 29774, 29835, 29896, 29956, + 30017, 30078, 30139, 30200, 30261, 30322, 30383, 30444, + 30505, 30566, 30627, 30689, 30750, 30811, 30873, 30934, + 30996, 31057, 31119, 31180, 31242, 31304, 31366, 31427, + 31489, 31551, 31613, 31675, 31737, 31799, 31861, 31923, + 31986, 32048, 32110, 32173, 32235, 32297, 32360, 32422, + 32485, 32548, 32610, 32673, 32736, 32799, 32862, 32925, + 32988, 33051, 33114, 33177, 33240, 33303, 33366, 33430, + 33493, 33557, 33620, 33684, 33747, 33811, 33874, 33938, + 34002, 34066, 34130, 34194, 34257, 34322, 34386, 34450, + 34514, 34578, 34642, 34707, 34771, 34836, 34900, 34965, + 35029, 35094, 35159, 35223, 35288, 35353, 35418, 35483, + 35548, 35613, 35678, 35743, 35809, 35874, 35939, 36005, + 36070, 36136, 36201, 36267, 36333, 36398, 36464, 36530, + 36596, 36662, 36728, 36794, 36860, 36926, 36993, 37059, + 37125, 37192, 37258, 37325, 37391, 37458, 37525, 37591, + 37658, 37725, 37792, 37859, 37926, 37993, 38060, 38128, + 38195, 38262, 38330, 38397, 38465, 38532, 38600, 38668, + 38736, 38804, 38871, 38939, 39007, 39076, 39144, 39212, + 39280, 39349, 39417, 39486, 39554, 39623, 39691, 39760, + 39829, 39898, 39967, 40036, 40105, 40174, 40243, 40312, + 40382, 40451, 40520, 40590, 40660, 40729, 40799, 40869, + 40939, 41008, 41078, 41148, 41219, 41289, 41359, 41429, + 41500, 41570, 41641, 41711, 41782, 41853, 41923, 41994, + 42065, 42136, 42207, 42279, 42350, 42421, 42492, 42564, + 42635, 42707, 42779, 42850, 42922, 42994, 43066, 43138, + 43210, 43282, 43354, 43427, 43499, 43571, 43644, 43717, + 43789, 43862, 43935, 44008, 44081, 44154, 44227, 44300, + 44373, 44447, 44520, 44594, 44667, 44741, 44815, 44888, + 44962, 45036, 45110, 45184, 45259, 45333, 45407, 45482, + 45556, 45631, 45705, 45780, 45855, 45930, 46005, 46080, + 46155, 46230, 46306, 46381, 46457, 46532, 46608, 46684, + 46759, 46835, 46911, 46987, 47063, 47140, 47216, 47292, + 47369, 47445, 47522, 47599, 47676, 47753, 47830, 47907, + 47984, 48061, 48138, 48216, 48293, 48371, 48449, 48526, + 48604, 48682, 48760, 48838, 48917, 48995, 49073, 49152, + 49230, 49309, 49388, 49467, 49546, 49625, 49704, 49783, + 49862, 49942, 50021, 50101, 50181, 50260, 50340, 50420, + 50500, 50581, 50661, 50741, 50822, 50902, 50983, 51063, + 51144, 51225, 51306, 51387, 51469, 51550, 51631, 51713, + 51794, 51876, 51958, 52040, 52122, 52204, 52286, 52369, + 52451, 52533, 52616, 52699, 52782, 52865, 52948, 53031, + 53114, 53197, 53281, 53364, 53448, 53532, 53615, 53699, + 53784, 53868, 53952, 54036, 54121, 54205, 54290, 54375, + 54460, 54545, 54630, 54715, 54801, 54886, 54972, 55057, + 55143, 55229, 55315, 55401, 55487, 55574, 55660, 55747, + 55834, 55920, 56007, 56094, 56181, 56269, 56356, 56444, + 56531, 56619, 56707, 56795, 56883, 56971, 57059, 57148, + 57236, 57325, 57414, 57503, 57592, 57681, 57770, 57859, + 57949, 58039, 58128, 58218, 58308, 58398, 58489, 58579, + 58669, 58760, 58851, 58942, 59033, 59124, 59215, 59306, + 59398, 59489, 59581, 59673, 59765, 59857, 59950, 60042, + 60134, 60227, 60320, 60413, 60506, 60599, 60692, 60786, + 60879, 60973, 61067, 61161, 61255, 61349, 61444, 61538, + 61633, 61728, 61822, 61918, 62013, 62108, 62204, 62299, + 62395, 62491, 62587, 62683, 62779, 62876, 62972, 63069, + 63166, 63263, 63360, 63458, 63555, 63653, 63750, 63848, + 63946, 64045, 64143, 64241, 64340, 64439, 64538, 64637, + 64736, 64836, 64935, 65035, 65135, 65235, 65335, 65435, + 65536, 65636, 65737, 65838, 65939, 66040, 66141, 66243, + 66345, 66447, 66549, 66651, 66753, 66856, 66958, 67061, + 67164, 67267, 67371, 67474, 67578, 67681, 67785, 67889, + 67994, 68098, 68203, 68308, 68413, 68518, 68623, 68728, + 68834, 68940, 69046, 69152, 69258, 69365, 69472, 69578, + 69685, 69793, 69900, 70007, 70115, 70223, 70331, 70439, + 70548, 70656, 70765, 70874, 70983, 71093, 71202, 71312, + 71422, 71532, 71642, 71752, 71863, 71974, 72085, 72196, + 72307, 72419, 72531, 72643, 72755, 72867, 72979, 73092, + 73205, 73318, 73431, 73545, 73659, 73772, 73886, 74001, + 74115, 74230, 74345, 74460, 74575, 74690, 74806, 74922, + 75038, 75154, 75271, 75387, 75504, 75621, 75739, 75856, + 75974, 76092, 76210, 76328, 76447, 76566, 76685, 76804, + 76923, 77043, 77163, 77283, 77403, 77524, 77644, 77765, + 77886, 78008, 78129, 78251, 78373, 78495, 78618, 78741, + 78864, 78987, 79110, 79234, 79358, 79482, 79606, 79731, + 79855, 79980, 80106, 80231, 80357, 80483, 80609, 80735, + 80862, 80989, 81116, 81244, 81371, 81499, 81627, 81756, + 81884, 82013, 82142, 82271, 82401, 82531, 82661, 82791, + 82922, 83053, 83184, 83315, 83447, 83579, 83711, 83843, + 83976, 84109, 84242, 84376, 84509, 84643, 84778, 84912, + 85047, 85182, 85317, 85453, 85589, 85725, 85861, 85998, + 86135, 86272, 86410, 86547, 86686, 86824, 86963, 87101, + 87241, 87380, 87520, 87660, 87800, 87941, 88082, 88223, + 88365, 88506, 88648, 88791, 88934, 89077, 89220, 89363, + 89507, 89651, 89796, 89941, 90086, 90231, 90377, 90523, + 90669, 90816, 90963, 91110, 91258, 91406, 91554, 91702, + 91851, 92000, 92150, 92300, 92450, 92600, 92751, 92902, + 93053, 93205, 93357, 93510, 93663, 93816, 93969, 94123, + 94277, 94431, 94586, 94741, 94897, 95053, 95209, 95365, + 95522, 95680, 95837, 95995, 96153, 96312, 96471, 96630, + 96790, 96950, 97111, 97271, 97433, 97594, 97756, 97918, + 98081, 98244, 98408, 98571, 98735, 98900, 99065, 99230, + 99396, 99562, 99729, 99895, 100063, 100230, 100398, 100567, + 100736, 100905, 101074, 101244, 101415, 101586, 101757, 101929, + 102101, 102273, 102446, 102619, 102793, 102967, 103142, 103317, + 103492, 103668, 103844, 104021, 104198, 104376, 104554, 104732, + 104911, 105090, 105270, 105450, 105631, 105812, 105993, 106175, + 106358, 106541, 106724, 106908, 107092, 107277, 107462, 107648, + 107834, 108020, 108207, 108395, 108583, 108771, 108960, 109150, + 109340, 109530, 109721, 109912, 110104, 110297, 110490, 110683, + 110877, 111071, 111266, 111462, 111658, 111854, 112051, 112248, + 112446, 112645, 112844, 113043, 113244, 113444, 113645, 113847, + 114049, 114252, 114455, 114659, 114864, 115069, 115274, 115480, + 115687, 115894, 116102, 116310, 116519, 116728, 116938, 117149, + 117360, 117572, 117784, 117997, 118211, 118425, 118639, 118855, + 119071, 119287, 119504, 119722, 119940, 120159, 120379, 120599, + 120820, 121041, 121263, 121486, 121709, 121933, 122158, 122383, + 122609, 122835, 123062, 123290, 123519, 123748, 123978, 124208, + 124439, 124671, 124904, 125137, 125371, 125605, 125841, 126077, + 126313, 126551, 126789, 127027, 127267, 127507, 127748, 127990, + 128232, 128475, 128719, 128963, 129209, 129455, 129701, 129949, + 130197, 130446, 130696, 130947, 131198, 131450, 131703, 131957, + 132211, 132466, 132722, 132979, 133237, 133495, 133754, 134014, + 134275, 134537, 134799, 135063, 135327, 135592, 135858, 136125, + 136392, 136661, 136930, 137200, 137471, 137743, 138016, 138289, + 138564, 138839, 139115, 139393, 139671, 139950, 140230, 140511, + 140792, 141075, 141359, 141643, 141929, 142215, 142503, 142791, + 143081, 143371, 143662, 143955, 144248, 144542, 144837, 145134, + 145431, 145729, 146029, 146329, 146630, 146933, 147236, 147541, + 147846, 148153, 148461, 148769, 149079, 149390, 149702, 150015, + 150329, 150645, 150961, 151279, 151597, 151917, 152238, 152560, + 152883, 153208, 153533, 153860, 154188, 154517, 154847, 155179, + 155512, 155845, 156181, 156517, 156855, 157193, 157533, 157875, + 158217, 158561, 158906, 159253, 159601, 159950, 160300, 160652, + 161005, 161359, 161715, 162072, 162430, 162790, 163151, 163513, + 163877, 164242, 164609, 164977, 165347, 165718, 166090, 166464, + 166839, 167216, 167594, 167974, 168355, 168738, 169122, 169508, + 169895, 170284, 170674, 171066, 171460, 171855, 172252, 172650, + 173050, 173452, 173855, 174260, 174666, 175074, 175484, 175896, + 176309, 176724, 177140, 177559, 177979, 178401, 178824, 179250, + 179677, 180106, 180537, 180969, 181404, 181840, 182278, 182718, + 183160, 183604, 184050, 184498, 184947, 185399, 185852, 186308, + 186765, 187225, 187686, 188150, 188615, 189083, 189553, 190025, + 190499, 190975, 191453, 191933, 192416, 192900, 193387, 193876, + 194367, 194861, 195357, 195855, 196355, 196858, 197363, 197870, + 198380, 198892, 199406, 199923, 200442, 200964, 201488, 202015, + 202544, 203076, 203610, 204147, 204686, 205228, 205772, 206319, + 206869, 207422, 207977, 208535, 209095, 209658, 210225, 210793, + 211365, 211940, 212517, 213097, 213681, 214267, 214856, 215448, + 216043, 216641, 217242, 217846, 218453, 219064, 219677, 220294, + 220913, 221536, 222163, 222792, 223425, 224061, 224701, 225344, + 225990, 226640, 227293, 227949, 228610, 229273, 229940, 230611, + 231286, 231964, 232646, 233331, 234021, 234714, 235411, 236112, + 236816, 237525, 238237, 238954, 239674, 240399, 241128, 241860, + 242597, 243338, 244084, 244834, 245588, 246346, 247109, 247876, + 248647, 249423, 250204, 250989, 251779, 252574, 253373, 254177, + 254986, 255799, 256618, 257441, 258270, 259103, 259941, 260785, + 261634, 262488, 263347, 264212, 265082, 265957, 266838, 267724, + 268616, 269514, 270417, 271326, 272241, 273161, 274088, 275020, + 275959, 276903, 277854, 278811, 279774, 280743, 281719, 282702, + 283691, 284686, 285688, 286697, 287713, 288735, 289765, 290801, + 291845, 292895, 293953, 295018, 296091, 297171, 298259, 299354, + 300457, 301567, 302686, 303812, 304947, 306090, 307240, 308400, + 309567, 310743, 311928, 313121, 314324, 315535, 316754, 317984, + 319222, 320469, 321726, 322993, 324269, 325554, 326850, 328156, + 329471, 330797, 332133, 333480, 334837, 336204, 337583, 338973, + 340373, 341785, 343208, 344643, 346089, 347547, 349017, 350499, + 351993, 353499, 355018, 356550, 358094, 359652, 361223, 362807, + 364404, 366016, 367641, 369280, 370933, 372601, 374283, 375981, + 377693, 379420, 381163, 382921, 384696, 386486, 388293, 390116, + 391956, 393812, 395686, 397578, 399487, 401414, 403359, 405323, + 407305, 409306, 411327, 413367, 415427, 417507, 419608, 421729, + 423871, 426035, 428221, 430428, 432658, 434910, 437186, 439485, + 441807, 444154, 446526, 448922, 451343, 453791, 456264, 458764, + 461291, 463845, 466428, 469038, 471678, 474347, 477045, 479774, + 482534, 485325, 488148, 491003, 493891, 496813, 499769, 502760, + 505787, 508849, 511948, 515084, 518259, 521472, 524725, 528018, + 531351, 534727, 538145, 541606, 545112, 548662, 552259, 555902, + 559593, 563332, 567122, 570962, 574853, 578797, 582795, 586848, + 590957, 595124, 599348, 603633, 607978, 612386, 616857, 621393, + 625996, 630667, 635407, 640218, 645102, 650060, 655094, 660206, + 665398, 670671, 676027, 681469, 686999, 692618, 698328, 704133, + 710035, 716035, 722137, 728343, 734655, 741077, 747612, 754261, + 761030, 767919, 774934, 782077, 789353, 796763, 804314, 812008, + 819849, 827843, 835992, 844303, 852780, 861428, 870251, 879257, + 888449, 897835, 907420, 917211, 927215, 937438, 947887, 958571, + 969498, 980675, 992112, 1003818, 1015802, 1028074, 1040645, 1053527, + 1066729, 1080266, 1094149, 1108393, 1123011, 1138018, 1153430, 1169265, + 1185538, 1202270, 1219479, 1237186, 1255414, 1274185, 1293525, 1313459, + 1334015, 1355224, 1377116, 1399726, 1423088, 1447242, 1472229, 1498091, + 1524876, 1552635, 1581422, 1611294, 1642314, 1674550, 1708075, 1742967, + 1779313, 1817205, 1856743, 1898038, 1941209, 1986387, 2033716, 2083353, + 2135471, 2190260, 2247933, 2308722, 2372887, 2440718, 2512537, 2588709, + 2669640, 2755792, 2847685, 2945916, 3051161, 3164201, 3285935, 3417407, + 3559833, 3714643, 3883524, 4068489, 4271947, 4496821, 4746679, 5025930, + 5340085, 5696125, 6103026, 6572525, 7120270, 7767602, 8544398, 9493811, + 10680573, 12206405, 14240842, 17089048, 21361347, 28481836, 42722796, 85445642 }; @@ -1960,10 +1960,10 @@ fixed_t finesine[10240] = 65531, 65531, 65532, 65532, 65533, 65533, 65534, 65534, 65534, 65535, 65535, 65535, 65535, 65535, 65535, 65535 }; + +fixed_t *finecosine = &finesine[FINEANGLES/4]; #endif - - angle_t tantoangle[2049] = { 0, 333772, 667544, 1001315, 1335086, 1668857, 2002626, 2336395, @@ -2225,9 +2225,6 @@ angle_t tantoangle[2049] = 536870912 }; - -#ifdef NEED_FIXED_VECTOR - static angle_t fineacon[65536*2] = { ANGLE_MAX, 2143707442, 2142143280, 2140943052, 2139931208, 2139039753, 2138233813, 2137492672, 2136802831, 2136154917, 2135542102, 2134959233, 2134402306, 2133868139, 2133354148, 2132858208, 2132378539, 2131913638, 2131462220, 2131023174, 2130595537, 2130178462, 2129771202, 2129373097, 2128983555, 2128602046, 2128228092, 2127861261, 2127501162, 2127147436, 2126799757, 2126457825, @@ -10706,5 +10703,3 @@ void FM_Rotate(matrix_t *dest, angle_t angle, fixed_t x, fixed_t y, fixed_t z) M(3, 3) = FRACUNIT; #undef M } - -#endif diff --git a/src/tables.h b/src/tables.h index 219d668b9..d7ec589da 100644 --- a/src/tables.h +++ b/src/tables.h @@ -96,9 +96,6 @@ FUNCMATH angle_t FixedAngle(fixed_t fa); // and with a factor, with +factor for (fa/factor) and -factor for (fa*factor) FUNCMATH angle_t FixedAngleC(fixed_t fa, fixed_t factor); - -#ifdef NEED_FIXED_VECTOR - /// The FixedAcos function FUNCMATH angle_t FixedAcos(fixed_t x); @@ -112,8 +109,6 @@ void FV3_Rotate(vector3_t *rotVec, const vector3_t *axisVec, const angle_t angle /// Fixed Point Matrix functions void FM_Rotate(matrix_t *dest, angle_t angle, fixed_t x, fixed_t y, fixed_t z); -#endif // defined NEED_FIXED_VECTOR - // The table values in tables.c are calculated with this many fractional bits. #define FINE_FRACBITS 16 diff --git a/src/tmap.nas b/src/tmap.nas index 6d1629c20..dbe64806d 100644 --- a/src/tmap.nas +++ b/src/tmap.nas @@ -17,7 +17,7 @@ [BITS 32] %define FRACBITS 16 -%define TRANSPARENTPIXEL 247 +%define TRANSPARENTPIXEL 255 %ifdef LINUX %macro cextern 1 diff --git a/src/tmap_mmx.nas b/src/tmap_mmx.nas index 928916668..758cd4395 100644 --- a/src/tmap_mmx.nas +++ b/src/tmap_mmx.nas @@ -18,7 +18,7 @@ [BITS 32] %define FRACBITS 16 -%define TRANSPARENTPIXEL 247 +%define TRANSPARENTPIXEL 255 %ifdef LINUX %macro cextern 1 diff --git a/src/v_video.c b/src/v_video.c index 524c15cc7..c5afd783f 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -366,7 +366,7 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t } if (alphalevel) { - v_translevel = ((alphalevel)<filename); - DEH_LoadDehackedLumpPwad(wadnum, lump); - } - - // Check for OBJCTCFG - for (lump = 0;lump < INT16_MAX;lump++) - { - lump = W_CheckNumForNamePwad("OBJCTCFG", wadnum, lump); - if (lump == INT16_MAX) - break; - CONS_Printf(M_GetText("Loading object config from %s\n"), wadfiles[wadnum]->filename); - DEH_LoadDehackedLumpPwad(wadnum, lump); + lumpinfo_t *lump_p = wadfiles[wadnum]->lumpinfo; + for (lump = 0; lump < wadfiles[wadnum]->numlumps; lump++, lump_p++) + if (memcmp(lump_p->name,"SOC_",4)==0) // Check for generic SOC lump + { // shameless copy+paste of code from LUA_LoadLump + char *name = malloc(strlen(wadfiles[wadnum]->filename)+10); + strcpy(name, wadfiles[wadnum]->filename); + if (!fasticmp(&name[strlen(name) - 4], ".soc")) { + // If it's not a .soc file, copy the lump name in too. + name[strlen(wadfiles[wadnum]->filename)] = '|'; + M_Memcpy(name+strlen(wadfiles[wadnum]->filename)+1, lump_p->name, 8); + name[strlen(wadfiles[wadnum]->filename)+9] = '\0'; + } + CONS_Printf(M_GetText("Loading SOC from %s\n"), name); + DEH_LoadDehackedLumpPwad(wadnum, lump); + } + else if (memcmp(lump_p->name,"MAINCFG",8)==0) // Check for MAINCFG + { + CONS_Printf(M_GetText("Loading main config from %s\n"), wadfiles[wadnum]->filename); + DEH_LoadDehackedLumpPwad(wadnum, lump); + } + else if (memcmp(lump_p->name,"OBJCTCFG",8)==0) // Check for OBJCTCFG + { + CONS_Printf(M_GetText("Loading object config from %s\n"), wadfiles[wadnum]->filename); + DEH_LoadDehackedLumpPwad(wadnum, lump); + } } #ifdef SCANTHINGS diff --git a/src/w_wad.h b/src/w_wad.h index 614b7e4ae..d283c54a0 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -16,8 +16,6 @@ #ifdef HWRENDER #include "hardware/hw_data.h" -#else -typedef void GLPatch_t; #endif #ifdef __GNUG__ diff --git a/src/win32/win_sys.c b/src/win32/win_sys.c index efb0be463..2babb57b9 100644 --- a/src/win32/win_sys.c +++ b/src/win32/win_sys.c @@ -3656,7 +3656,7 @@ const CPUInfoFlags *I_CPUInfo(void) } static void CPUAffinity_OnChange(void); -static consvar_t cv_cpuaffinity = {"cpuaffinity", "1", CV_SAVE | CV_CALL, NULL, CPUAffinity_OnChange, 0, NULL, NULL, 0, 0, NULL}; +static consvar_t cv_cpuaffinity = {"cpuaffinity", "-1", CV_CALL, NULL, CPUAffinity_OnChange, 0, NULL, NULL, 0, 0, NULL}; typedef HANDLE (WINAPI *p_GetCurrentProcess) (VOID); static p_GetCurrentProcess pfnGetCurrentProcess = NULL; diff --git a/src/y_inter.c b/src/y_inter.c index 37a8bc4cc..718434d83 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -632,7 +632,7 @@ void Y_Ticker(void) boolean anybonuses = false; if (!intertic) // first time only - S_ChangeMusic(mus_lclear, false); // don't loop it + S_ChangeMusicInternal("lclear", false); // don't loop it if (intertic < TICRATE) // one second pause before tally begins return; @@ -693,7 +693,7 @@ void Y_Ticker(void) if (!intertic) // first time only { - S_ChangeMusic(mus_lclear, false); // don't loop it + S_ChangeMusicInternal("lclear", false); // don't loop it tallydonetic = 0; } @@ -754,7 +754,7 @@ void Y_Ticker(void) else if (intertype == int_match || intertype == int_ctf || intertype == int_teammatch) // match { if (!intertic) // first time only - S_ChangeMusic(mus_racent, true); // loop it + S_ChangeMusicInternal("racent", true); // loop it // If a player has left or joined, recalculate scores. if (data.match.numplayers != D_NumPlayers()) @@ -763,7 +763,7 @@ void Y_Ticker(void) else if (intertype == int_race || intertype == int_classicrace) // race { if (!intertic) // first time only - S_ChangeMusic(mus_racent, true); // loop it + S_ChangeMusicInternal("racent", true); // loop it // Don't bother recalcing for race. It doesn't make as much sense. } diff --git a/tools/anglechk.c b/tools/anglechk.c index bb9c4d9ea..4a67069bf 100644 --- a/tools/anglechk.c +++ b/tools/anglechk.c @@ -351,6 +351,13 @@ int main(int argc, char** argv) return 0; } +static void *cpu_cpy(void *dest, const void *src, size_t n) +{ + return memcpy(dest, src, n); +} + +void *(*M_Memcpy)(void* dest, const void* src, size_t n) = cpu_cpy; + void I_Error(const char *error, ...) { (void)error;