Merge branch 'master' of git@git.magicalgirl.moe:STJr/SRB2Internal.git into damage-control

This commit is contained in:
Monster Iestyn 2016-03-13 20:37:43 +00:00
commit f9c4b877ca
121 changed files with 7671 additions and 6592 deletions

2
.gitattributes vendored
View file

@ -29,4 +29,6 @@
/libs/zlib/nintendods/README -whitespace /libs/zlib/nintendods/README -whitespace
/libs/zlib/watcom/watcom_f.mak -crlf -whitespace /libs/zlib/watcom/watcom_f.mak -crlf -whitespace
/libs/zlib/watcom/watcom_l.mak -crlf -whitespace /libs/zlib/watcom/watcom_l.mak -crlf -whitespace
#Appveyor
/appveyor.yml -crlf -whitespace
# Other # Other

33
.travis.yml Normal file
View file

@ -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

View file

@ -28,7 +28,7 @@ macro(add_framework fwname appname)
${CMAKE_OSX_SYSROOT}/Library ${CMAKE_OSX_SYSROOT}/Library
/System/Library /System/Library
/Library /Library
PATH_SUFFIXES Frameworks ATH_SUFFIXES Frameworks
NO_DEFAULT_PATH) NO_DEFAULT_PATH)
if( ${FRAMEWORK_${fwname}} STREQUAL FRAMEWORK_${fwname}-NOTFOUND) if( ${FRAMEWORK_${fwname}} STREQUAL FRAMEWORK_${fwname}-NOTFOUND)
MESSAGE(ERROR ": Framework ${fwname} not found") MESSAGE(ERROR ": Framework ${fwname} not found")
@ -80,9 +80,6 @@ endif()
if(${CMAKE_SYSTEM} MATCHES "Darwin") if(${CMAKE_SYSTEM} MATCHES "Darwin")
add_definitions(-DMACOSX) add_definitions(-DMACOSX)
if(${CMAKE_C_COMPILER_ID} MATCHES "Clang")
set(CLANG ON)
endif()
endif() endif()
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") 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) include(GitUtilities)
git_describe(SRB2_GIT_DESCRIBE "${CMAKE_SOURCE_DIR}") git_describe(SRB2_GIT_DESCRIBE "${CMAKE_SOURCE_DIR}")
git_current_branch(SRB2_GIT_BRANCH "${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) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/src/config.h)
##### PACKAGE CONFIGURATION ##### ##### PACKAGE CONFIGURATION #####

71
appveyor.yml Normal file
View file

@ -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:<ip>:<port>
#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))

12
assets/debian/changelog Normal file
View file

@ -0,0 +1,12 @@
srb2-data (2.1.14~1) unstable; urgency=low
* Updated for SRB2 v2.1.14
-- Alam Arias <alam+debian@srb2.org> Sat, 6 Jan 2016 11:00:00 -0500
srb2-data (2.0.6-2) maverick; urgency=high
* Initial proper release..
-- Callum Dickinson <gcfreak_ag20@hotmail.com> Sat, 29 Jan 2011 01:18:42 +1300

View file

@ -37,7 +37,7 @@ RM := rm -rf
DIR := $(shell pwd) DIR := $(shell pwd)
PACKAGE := $(shell cat $(DIR)/debian/control | grep 'Package:' | sed -e 's/Package: //g') 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 DATADIR := usr/games/SRB2
RESOURCEDIR := . RESOURCEDIR := .
@ -48,7 +48,7 @@ build:
# This will need to be updated every time SRB2 official version is # 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 # Copy data files to their install locations, and add data files to include-binaries
for file in $(DATAFILES); do \ 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 \ if test "$$file" = "srb2.wad"; then \
$(INSTALL) $(RESOURCEDIR)/$$file $(DIR)/debian/tmp/$(DATADIR)/srb2.srb; \ $(INSTALL) $(RESOURCEDIR)/$$file $(DIR)/debian/tmp/$(DATADIR)/srb2.srb; \
else \ else \

View file

@ -0,0 +1 @@
3.0 (native)

View file

@ -1,5 +0,0 @@
srb2-data (2.0.6-2) maverick; urgency=high
* Initial proper release..
-- Callum Dickinson <gcfreak_ag20@hotmail.com> Sat, 29 Jan 2011 01:18:42 +1300

View file

@ -1 +0,0 @@
3.0 (quilt)

View file

@ -1,10 +1,32 @@
@ECHO OFF @ECHO OFF
set REV=Unknown set BRA=Unknown
set REV=illegal
copy nul: /b +%1\comptime.c tmp.$$$ > nul copy nul: /b +%1\comptime.c tmp.$$$ > nul
move tmp.$$$ %1\comptime.c > 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 // Do not edit! This file was autogenerated > %1\comptime.h
ECHO // by the %0 batch file >> %1\comptime.h ECHO // by the %0 batch file >> %1\comptime.h
ECHO // >> %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

View file

@ -5,13 +5,15 @@ if [ x"$1" != x ]; then
fi fi
versiongit() { versiongit() {
gitversion=`git describe` gitbranch=`git rev-parse --abbrev-ref HEAD`
gitversion=`git rev-parse HEAD`
cat <<EOF > $path/comptime.h cat <<EOF > $path/comptime.h
// Do not edit! This file was autogenerated // 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 EOF
exit 0 exit 0
} }
@ -23,6 +25,7 @@ versionsvn() {
// Do not edit! This file was autogenerated // Do not edit! This file was autogenerated
// by the $0 script with subversion // by the $0 script with subversion
// //
const char* compbranch = "Subversion";
const char* comprevision = "r$svnrevision"; const char* comprevision = "r$svnrevision";
EOF EOF
exit 0 exit 0
@ -34,6 +37,7 @@ versionfake() {
// Do not edit! This file was autogenerated // Do not edit! This file was autogenerated
// by the $0 script with an unknown or nonexist SCM // by the $0 script with an unknown or nonexist SCM
// //
const char* compbranch = "Unknown";
const char* comprevision = "illegal"; const char* comprevision = "illegal";
EOF EOF
} }

14
debian/control vendored
View file

@ -4,13 +4,19 @@ Source: srb2
Section: games Section: games
Priority: extra Priority: extra
Maintainer: Callum Dickinson <gcfreak_ag20@hotmail.com> Maintainer: Callum Dickinson <gcfreak_ag20@hotmail.com>
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 Standards-Version: 3.8.4
Homepage: http://www.srb2.org Homepage: http://www.srb2.org
Package: srb2 Package: srb2
Architecture: any 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 Description: A cross-platform 3D Sonic fangame
Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog
fangame built using a modified version of the Doom Legacy fangame built using a modified version of the Doom Legacy
@ -22,8 +28,8 @@ Description: A cross-platform 3D Sonic fangame
Package: srb2-dbg Package: srb2-dbg
Architecture: any Architecture: any
# FIXME: should be Depends: ${shlibs:Depends}, ${misc:Depends}, srb2-data (= 2.0.6), srb2 but dh_shlibdeps is being an asshat # 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.0.6), srb2 Depends: libc6, ${misc:Depends}, srb2-data (= 2.1.14), srb2
Description: A cross-platform 3D Sonic fangame Description: A cross-platform 3D Sonic fangame
Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog
fangame built using a modified version of the Doom Legacy fangame built using a modified version of the Doom Legacy

17
debian/rules vendored
View file

@ -59,16 +59,18 @@ DBGNAME = debug/$(EXENAME)
PKGDIR = usr/games PKGDIR = usr/games
DBGDIR = usr/lib/debug/$(PKGDIR) 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)") PREFIX = $(shell test "$(CROSS_COMPILE_BUILD)" != "$(CROSS_COMPILE_HOST)" && echo "PREFIX=$(CROSS_COMPILE_HOST)")
OS = LINUX=1 OS = LINUX=1
NONX86 = $(shell test "`echo $(CROSS_COMPILE_HOST) | grep 'i[3-6]86'`" || echo "NONX86=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)" MENUFILE1 = ?package($(PACKAGE)):needs="X11" section="$(SECTION)"
MENUFILE2 = title="$(TITLE)" command="/$(PKGDIR)/$(PACKAGE)" MENUFILE2 = title="$(TITLE)" command="/$(PKGDIR)/$(PACKAGE)"
# FIXME pkg-config dir hacks # 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 BINDIR := $(DIR)/bin/Linux/Release
LDFLAGS += "-Wl,-rpath=/usr/$(CROSS_COMPILE_HOST)/lib/" LDFLAGS += "-Wl,-rpath=/usr/lib/$(CROSS_COMPILE_HOST)"
build: build:
$(MKDIR) $(BINDIR)/debug $(MKDIR) $(BINDIR)/debug
@ -80,14 +82,23 @@ binary-indep:
echo "no need to do any arch-independent stuff" echo "no need to do any arch-independent stuff"
binary-arch: binary-arch:
# create ddirs
$(MKDIR) $(DIR)/debian/tmp/$(PKGDIR) $(DIR)/debian/tmp/$(DBGDIR) $(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)/$(EXENAME) $(DIR)/debian/tmp/$(PKGDIR)/$(PACKAGE)
$(INSTALL) $(BINDIR)/$(DBGNAME) $(DIR)/debian/tmp/$(DBGDIR)/$(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 # add compiled binaries to include-binaries
echo $(BINDIR)/$(EXENAME) >> $(DIR)/debian/source/include-binaries echo $(BINDIR)/$(EXENAME) >> $(DIR)/debian/source/include-binaries
echo $(BINDIR)/$(EXENAME) >> $(DIR)/debian/source/include-binaries echo $(BINDIR)/$(EXENAME) >> $(DIR)/debian/source/include-binaries
# Generate install folder files # Generate install folder files
echo $(PKGDIR) > $(DIR)/debian/$(PACKAGE).install 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 echo $(DBGDIR) > $(DIR)/debian/$(DBGPKG).install
binary: binary-arch binary: binary-arch

10
debian/srb2.desktop vendored Normal file
View file

@ -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;

BIN
srb2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

View file

@ -150,6 +150,7 @@ set(SRB2_CORE_GAME_SOURCES
p_saveg.c p_saveg.c
p_setup.c p_setup.c
p_sight.c p_sight.c
p_slopes.c
p_spec.c p_spec.c
p_telept.c p_telept.c
p_tick.c p_tick.c
@ -162,11 +163,12 @@ set(SRB2_CORE_GAME_SOURCES
p_pspr.h p_pspr.h
p_saveg.h p_saveg.h
p_setup.h p_setup.h
p_slopes.h
p_spec.h p_spec.h
p_tick.h p_tick.h
) )
if(NOT CLANG) if(NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
set(SRB2_CORE_SOURCES ${SRB2_CORE_SOURCES} string.c) set(SRB2_CORE_SOURCES ${SRB2_CORE_SOURCES} string.c)
endif() endif()
@ -404,10 +406,14 @@ endif()
# Compatibility flag with later versions of GCC # Compatibility flag with later versions of GCC
# We should really fix our code to not need this # 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) set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -mno-ms-bitfields)
endif() endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -Wno-absolute-value)
endif()
add_definitions(-DCMAKECONFIG) add_definitions(-DCMAKECONFIG)
#add_library(SRB2Core STATIC #add_library(SRB2Core STATIC

View file

@ -454,6 +454,7 @@ OBJS:=$(i_main_o) \
$(OBJDIR)/p_telept.o \ $(OBJDIR)/p_telept.o \
$(OBJDIR)/p_tick.o \ $(OBJDIR)/p_tick.o \
$(OBJDIR)/p_user.o \ $(OBJDIR)/p_user.o \
$(OBJDIR)/p_slopes.o \
$(OBJDIR)/tables.o \ $(OBJDIR)/tables.o \
$(OBJDIR)/r_bsp.o \ $(OBJDIR)/r_bsp.o \
$(OBJDIR)/r_data.o \ $(OBJDIR)/r_data.o \

View file

@ -7,6 +7,22 @@
# and other things # 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 ifdef GCC48
GCC47=1 GCC47=1
endif endif
@ -139,6 +155,10 @@ WFLAGS+=-Wformat-security
ifndef GCC29 ifndef GCC29
#WFLAGS+=-Winit-self #WFLAGS+=-Winit-self
endif endif
ifdef GCC46
WFLAGS+=-Wno-suggest-attribute=noreturn
endif
ifndef MINGW ifndef MINGW
ifdef GCC45 ifdef GCC45
WFLAGS+=-Wunsuffixed-float-constants WFLAGS+=-Wunsuffixed-float-constants
@ -155,6 +175,7 @@ ifdef GCC43
endif endif
WFLAGS+=$(OLDWFLAGS) WFLAGS+=$(OLDWFLAGS)
#indicate platform and what interface use with #indicate platform and what interface use with
ifndef WINCE ifndef WINCE
ifndef XBOX ifndef XBOX

View file

@ -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)) if (sonic->player->pflags & (PF_MACESPIN|PF_ITEMHANG))
{ {
cmd->forwardmove = sonic->player->cmd.forwardmove; 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) if (sonic->angle < tails->angle)
cmd->angleturn = -cmd->angleturn; cmd->angleturn = -cmd->angleturn;
} else if (dist > FixedMul(512*FRACUNIT, tails->scale)) } else if (dist > FixedMul(512*FRACUNIT, tails->scale))

View file

@ -9,12 +9,14 @@
#if (defined(CMAKECONFIG)) #if (defined(CMAKECONFIG))
#include "config.h" #include "config.h"
const char *compbranch = SRB2_COMP_BRANCH;
const char *comprevision = SRB2_COMP_REVISION; const char *comprevision = SRB2_COMP_REVISION;
#elif (defined(COMPVERSION)) #elif (defined(COMPVERSION))
#include "comptime.h" #include "comptime.h"
#else #else
const char *compbranch = "Unknown";
const char *comprevision = "illegal"; const char *comprevision = "illegal";
#endif #endif

View file

@ -18,6 +18,7 @@
#define ASSET_HASH_PATCH_DTA "${SRB2_ASSET_patch.dta_HASH}" #define ASSET_HASH_PATCH_DTA "${SRB2_ASSET_patch.dta_HASH}"
#define SRB2_COMP_REVISION "${SRB2_COMP_REVISION}" #define SRB2_COMP_REVISION "${SRB2_COMP_REVISION}"
#define SRB2_COMP_BRANCH "${SRB2_COMP_BRANCH}"
#define SRB2_GIT_DESCRIBE "${SRB2_GIT_DESCRIBE}" #define SRB2_GIT_DESCRIBE "${SRB2_GIT_DESCRIBE}"
#define SRB2_GIT_BRANCH "${SRB2_GIT_BRANCH}" #define SRB2_GIT_BRANCH "${SRB2_GIT_BRANCH}"

View file

@ -202,7 +202,7 @@ static void CONS_Bind_f(void)
} }
key = G_KeyStringtoNum(COM_Argv(1)); key = G_KeyStringtoNum(COM_Argv(1));
if (!key) if (key <= 0 || key >= NUMINPUTS)
{ {
CONS_Alert(CONS_NOTICE, M_GetText("Invalid key name\n")); CONS_Alert(CONS_NOTICE, M_GetText("Invalid key name\n"));
return; return;
@ -248,11 +248,11 @@ void CON_ReSetupBackColormap(UINT16 num)
{ {
j = pal[i] + pal[i+1] + pal[i+2]; j = pal[i] + pal[i+1] + pal[i+2];
cwhitemap[k] = (UINT8)(15 - (j>>6)); cwhitemap[k] = (UINT8)(15 - (j>>6));
corangemap[k] = (UINT8)(95 - (j>>6)); corangemap[k] = (UINT8)(63 - (j>>6));
cbluemap[k] = (UINT8)(239 - (j>>6)); cbluemap[k] = (UINT8)(159 - (j>>6));
cgreenmap[k] = (UINT8)(175 - (j>>6)); cgreenmap[k] = (UINT8)(111 - (j>>6));
cgraymap[k] = (UINT8)(31 - (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]; j = pal[i] + pal[i+1] + pal[i+2];
cwhitemap[k] = (UINT8)(15 - (j>>6)); cwhitemap[k] = (UINT8)(15 - (j>>6));
corangemap[k] = (UINT8)(95 - (j>>6)); corangemap[k] = (UINT8)(63 - (j>>6));
cbluemap[k] = (UINT8)(239 - (j>>6)); cbluemap[k] = (UINT8)(159 - (j>>6));
cgreenmap[k] = (UINT8)(175 - (j>>6)); cgreenmap[k] = (UINT8)(111 - (j>>6));
cgraymap[k] = (UINT8)(31 - (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 // setup the other colormaps, for console text
@ -306,20 +306,20 @@ static void CON_SetupBackColormap(void)
orangemap[i] = (UINT8)i; orangemap[i] = (UINT8)i;
} }
yellowmap[3] = (UINT8)103; yellowmap[3] = (UINT8)73;
yellowmap[9] = (UINT8)115; yellowmap[9] = (UINT8)66;
purplemap[3] = (UINT8)195; purplemap[3] = (UINT8)184;
purplemap[9] = (UINT8)198; purplemap[9] = (UINT8)186;
lgreenmap[3] = (UINT8)162; lgreenmap[3] = (UINT8)98;
lgreenmap[9] = (UINT8)170; lgreenmap[9] = (UINT8)106;
bluemap[3] = (UINT8)228; bluemap[3] = (UINT8)147;
bluemap[9] = (UINT8)238; bluemap[9] = (UINT8)158;
graymap[3] = (UINT8)10; graymap[3] = (UINT8)10;
graymap[9] = (UINT8)15; graymap[9] = (UINT8)15;
redmap[3] = (UINT8)124; redmap[3] = (UINT8)210;
redmap[9] = (UINT8)127; redmap[9] = (UINT8)32;
orangemap[3] = (UINT8)85; orangemap[3] = (UINT8)52;
orangemap[9] = (UINT8)90; orangemap[9] = (UINT8)57;
} }
// Setup the console text buffer // Setup the console text buffer

View file

@ -1100,7 +1100,7 @@ static inline void CL_DrawConnectionStatus(void)
if (cl_mode != cl_downloadfiles) if (cl_mode != cl_downloadfiles)
{ {
INT32 i, animtime = ((ccstime / 4) & 15) + 16; 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. // 15 pal entries total.
const char *cltext; const char *cltext;
@ -1138,8 +1138,8 @@ static inline void CL_DrawConnectionStatus(void)
dldlength = (INT32)((fileneeded[lastfilenum].currentsize/(double)fileneeded[lastfilenum].totalsize) * 256); dldlength = (INT32)((fileneeded[lastfilenum].currentsize/(double)fileneeded[lastfilenum].totalsize) * 256);
if (dldlength > 256) if (dldlength > 256)
dldlength = 256; dldlength = 256;
V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, 256, 8, 175); V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, 256, 8, 111);
V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, dldlength, 8, 160); V_DrawFill(BASEVIDWIDTH/2-128, BASEVIDHEIGHT-24, dldlength, 8, 96);
memset(tempname, 0, sizeof(tempname)); memset(tempname, 0, sizeof(tempname));
nameonly(strncpy(tempname, fileneeded[lastfilenum].filename, 31)); nameonly(strncpy(tempname, fileneeded[lastfilenum].filename, 31));

View file

@ -1129,10 +1129,10 @@ void D_SRB2Main(void)
#ifndef DEVELOP // md5s last updated 12/14/14 #ifndef DEVELOP // md5s last updated 12/14/14
// Check MD5s of autoloaded files // Check MD5s of autoloaded files
W_VerifyFileMD5(0, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad //W_VerifyFileMD5(0, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad
W_VerifyFileMD5(1, ASSET_HASH_ZONES_DTA); // zones.dta //W_VerifyFileMD5(1, ASSET_HASH_ZONES_DTA); // zones.dta
W_VerifyFileMD5(2, ASSET_HASH_PLAYER_DTA); // player.dta //W_VerifyFileMD5(2, ASSET_HASH_PLAYER_DTA); // player.dta
W_VerifyFileMD5(3, ASSET_HASH_RINGS_DTA); // rings.dta //W_VerifyFileMD5(3, ASSET_HASH_RINGS_DTA); // rings.dta
//W_VerifyFileMD5(4, "0c66790502e648bfce90fdc5bb15722e"); // patch.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 // 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. // ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for.

View file

@ -1854,10 +1854,10 @@ static void Got_Pause(UINT8 **cp, INT32 playernum)
if (paused) if (paused)
{ {
if (!menuactive || netgame) if (!menuactive || netgame)
S_PauseSound(); S_PauseAudio();
} }
else else
S_ResumeSound(); S_ResumeAudio();
} }
} }
@ -3179,7 +3179,11 @@ static void Command_ListWADS_f(void)
*/ */
static void Command_Version_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); CONS_Printf("Sonic Robo Blast 2 %s (%s %s %s)\n", VERSIONSTRING, compdate, comptime, comprevision);
#endif
} }
#ifdef UPDATE_ALERT #ifdef UPDATE_ALERT
@ -3757,50 +3761,66 @@ static void Command_Displayplayer_f(void)
static void Command_Tunes_f(void) static void Command_Tunes_f(void)
{ {
const char *tunearg; const char *tunearg;
UINT16 tune, track = 0; UINT16 tunenum, track = 0;
const size_t argc = COM_Argc(); const size_t argc = COM_Argc();
if (argc < 2) //tunes slot ... if (argc < 2) //tunes slot ...
{ {
CONS_Printf("tunes <slot #/map name/\"default\"> <speed> <track>:\n"); CONS_Printf("tunes <name/num> [track] [speed] / <-show> / <-default> / <-none>:\n");
CONS_Printf(M_GetText("Play a music slot at a set speed (\"1\" being normal speed).\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")); CONS_Printf(M_GetText("If the format supports multiple songs, you can specify which one to play.\n\n"));
CONS_Printf(M_GetText("The current tune is: %d\nThe current track is: %d\n"), CONS_Printf(M_GetText("* With \"-show\", shows the currently playing tune and track.\n"));
(mapmusic & MUSIC_SONGMASK), ((mapmusic & MUSIC_TRACKMASK) >> MUSIC_TRACKSHIFT)); 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; return;
} }
tunearg = COM_Argv(1); tunearg = COM_Argv(1);
tune = (UINT16)atoi(tunearg); tunenum = (UINT16)atoi(tunearg);
track = 0; track = 0;
if (!strcasecmp(tunearg, "default")) if (!strcasecmp(tunearg, "-show"))
{ {
tune = mapheaderinfo[gamemap-1]->musicslot; CONS_Printf(M_GetText("The current tune is: %s [track %d]\n"),
track = mapheaderinfo[gamemap-1]->musicslottrack; mapmusname, (mapmusflags & MUSIC_TRACKMASK));
}
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);
return; return;
} }
if (!strcasecmp(tunearg, "-none"))
if (argc > 3) {
track = (UINT16)atoi(COM_Argv(3))-1;
mapmusic = tune | (track << MUSIC_TRACKSHIFT);
if (tune == mus_None)
S_StopMusic(); S_StopMusic();
else return;
S_ChangeMusic(mapmusic, true); }
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) 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) if (speed > 0.0f)
S_SpeedMusic(speed); S_SpeedMusic(speed);
} }

View file

@ -166,7 +166,7 @@ typedef enum
PA_RUN, PA_RUN,
PA_PAIN, PA_PAIN,
PA_ROLL, PA_ROLL,
PA_JUMP, PA_SPRING,
PA_FALL, PA_FALL,
PA_ABILITY, PA_ABILITY,
PA_RIDE PA_RIDE

File diff suppressed because it is too large Load diff

View file

@ -142,8 +142,10 @@ extern FILE *logstream;
#ifdef DEVELOP #ifdef DEVELOP
#define VERSION 0 // Game version #define VERSION 0 // Game version
#define SUBVERSION 0 // more precise version number #define SUBVERSION 0 // more precise version number
#define VERSIONSTRING "Trunk" #define VERSIONSTRING "Development EXE"
#define VERSIONSTRINGW L"Trunk" #define VERSIONSTRINGW L"Development EXE"
// most interface strings are ignored in development mode.
// we use comprevision and compbranch instead.
#else #else
#define VERSION 202 // Game version #define VERSION 202 // Game version
#define SUBVERSION 0 // more precise version number #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". // 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 #define MODVERSION 20
// some tests, enable or disable it if it run or not
#define SPLITSCREEN
// ========================================================================= // =========================================================================
// The maximum number of players, multiplayer/networking. // The maximum number of players, multiplayer/networking.
@ -232,27 +227,31 @@ typedef enum
SKINCOLOR_SILVER, SKINCOLOR_SILVER,
SKINCOLOR_GREY, SKINCOLOR_GREY,
SKINCOLOR_BLACK, 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_BEIGE,
SKINCOLOR_PEACH,
SKINCOLOR_BROWN, SKINCOLOR_BROWN,
SKINCOLOR_RED, SKINCOLOR_RED,
SKINCOLOR_DARKRED, SKINCOLOR_CRIMSON,
SKINCOLOR_NEONGREEN, SKINCOLOR_ORANGE,
SKINCOLOR_GREEN, SKINCOLOR_RUST,
SKINCOLOR_ZIM,
SKINCOLOR_OLIVE,
SKINCOLOR_YELLOW,
SKINCOLOR_GOLD, 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! // Careful! MAXSKINCOLORS cannot be greater than 0x20!
MAXSKINCOLORS, MAXSKINCOLORS,
@ -350,11 +349,7 @@ void CONS_Debug(INT32 debugflags, const char *fmt, ...) FUNCDEBUG;
#include "m_swap.h" #include "m_swap.h"
// Things that used to be in dstrings.h // Things that used to be in dstrings.h
#define DEVMAPS "devmaps"
#define DEVDATA "devdata"
#define SAVEGAMENAME "srb2sav" #define SAVEGAMENAME "srb2sav"
char savegamename[256]; char savegamename[256];
// m_misc.h // m_misc.h
@ -426,7 +421,7 @@ INT32 I_GetKey(void);
#endif #endif
// Compile date and time and revision. // 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 // Disabled code and code under testing
// None of these that are disabled in the normal build are guaranteed to work perfectly // 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 /// \note obsoleted by cv_maxportals
//#define PORTAL_LIMIT 8 //#define PORTAL_LIMIT 8
/// Fun experimental slope stuff! /// Kalaron/Eternity Engine slope code (SRB2CB ported)
//#define SLOPENESS #define ESLOPE
/// Delete file while the game is running. /// Delete file while the game is running.
/// \note EXTREMELY buggy, tends to crash game. /// \note EXTREMELY buggy, tends to crash game.
@ -455,10 +450,6 @@ extern const char *compdate, *comptime, *comprevision;
/// Polyobject fake flat code /// Polyobject fake flat code
#define POLYOBJECTS_PLANES #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. /// Improved way of dealing with ping values and a ping limit.
#define NEWPING #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.) /// Experimental tweaks to analog mode. (Needs a lot of work before it's ready for primetime.)
//#define REDSANALOG //#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__ #endif // __DOOMDEF__

View file

@ -31,15 +31,11 @@
// Selected by user. // Selected by user.
extern INT16 gamemap; extern INT16 gamemap;
extern char mapmusname[7];
// ----------------xxxxxxxxxxxxxxxx = music slot extern UINT16 mapmusflags;
// -xxxxxxxxxxxxxxx---------------- = track slot #define MUSIC_TRACKMASK 0x0FFF // ----************
// x------------------------------- = reset music bit #define MUSIC_RELOADRESET 0x8000 // *---------------
extern UINT32 mapmusic; // Use other bits if necessary.
#define MUSIC_TRACKSHIFT 16
#define MUSIC_SONGMASK 0x0000FFFF
#define MUSIC_TRACKMASK 0x7FFF0000
#define MUSIC_RELOADRESET 0x80000000
extern INT16 maptol; extern INT16 maptol;
extern UINT8 globalweather; extern UINT8 globalweather;
@ -146,11 +142,13 @@ typedef struct
UINT16 xcoord[8]; UINT16 xcoord[8];
UINT16 ycoord[8]; UINT16 ycoord[8];
UINT16 picduration[8]; UINT16 picduration[8];
UINT16 musicslot;
UINT8 musicloop; UINT8 musicloop;
UINT16 textxpos; UINT16 textxpos;
UINT16 textypos; UINT16 textypos;
char musswitch[7];
UINT16 musswitchflags;
UINT8 fadecolor; // Color number for fade, 0 means don't do the first fade 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 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 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. UINT8 actnum; ///< Act number or 0 for none.
UINT16 typeoflevel; ///< Combination of typeoflevel flags. UINT16 typeoflevel; ///< Combination of typeoflevel flags.
INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end. INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end.
UINT16 musicslot; ///< Music slot number to play. 0 for no music. char musname[7]; ///< Music track to play. "" for no music.
UINT16 musicslottrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore. 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. 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. 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. INT16 skynum; ///< Sky number to use.

View file

@ -100,11 +100,13 @@ typedef long ssize_t;
#if defined (_MSC_VER) || defined (__OS2__) #if defined (_MSC_VER) || defined (__OS2__)
// Microsoft VisualC++ // Microsoft VisualC++
#ifdef _MSC_VER
#if (_MSC_VER <= 1800) // MSVC 2013 and back #if (_MSC_VER <= 1800) // MSVC 2013 and back
#define snprintf _snprintf #define snprintf _snprintf
#if (_MSC_VER <= 1200) // MSVC 2012 and back #if (_MSC_VER <= 1200) // MSVC 2012 and back
#define vsnprintf _vsnprintf #define vsnprintf _vsnprintf
#endif #endif
#endif
#endif #endif
#define strncasecmp strnicmp #define strncasecmp strnicmp
#define strcasecmp stricmp #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. // not the number of bytes in the buffer.
#define STRBUFCPY(dst,src) strlcpy(dst, src, sizeof dst) #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__ #ifndef __BYTEBOOL__
#define __BYTEBOOL__ #define __BYTEBOOL__
@ -193,7 +197,6 @@ size_t strlcpy(char *dst, const char *src, size_t siz);
#else #else
typedef enum {false, true} boolean; typedef enum {false, true} boolean;
#endif #endif
//#endif // __cplusplus
#endif // __BYTEBOOL__ #endif // __BYTEBOOL__
/* 7.18.2.1 Limits of exact-width integer types */ /* 7.18.2.1 Limits of exact-width integer types */

View file

@ -559,7 +559,7 @@ static void F_IntroDrawScene(void)
if (finalecount < 4) if (finalecount < 4)
S_StopMusic(); S_StopMusic();
if (finalecount == 4) if (finalecount == 4)
S_ChangeMusic(mus_stjr, false); S_ChangeMusicInternal("stjr", false);
x = (BASEVIDWIDTH<<FRACBITS)/2 - FixedMul(334<<FRACBITS, aspect)/2; x = (BASEVIDWIDTH<<FRACBITS)/2 - FixedMul(334<<FRACBITS, aspect)/2;
y = (BASEVIDHEIGHT<<FRACBITS)/2 - FixedMul(358<<FRACBITS, aspect)/2; y = (BASEVIDHEIGHT<<FRACBITS)/2 - FixedMul(358<<FRACBITS, aspect)/2;
V_DrawSciencePatch(x, y, 0, (patch = W_CachePatchName("WAHH1", PU_CACHE)), aspect); V_DrawSciencePatch(x, y, 0, (patch = W_CachePatchName("WAHH1", PU_CACHE)), aspect);
@ -603,7 +603,7 @@ static void F_IntroDrawScene(void)
if (finalecount-84 < 58) { // Pure Fat is driving up! if (finalecount-84 < 58) { // Pure Fat is driving up!
int ftime = (finalecount-84); int ftime = (finalecount-84);
x = (-189<<FRACBITS) + (FixedMul((6<<FRACBITS)+FRACUNIT/3, ftime<<FRACBITS) - FixedMul((6<<FRACBITS)+FRACUNIT/3, FixedDiv(FixedMul(ftime<<FRACBITS, ftime<<FRACBITS), 120<<FRACBITS))); x = (-189*FRACUNIT) + (FixedMul((6<<FRACBITS)+FRACUNIT/3, ftime<<FRACBITS) - FixedMul((6<<FRACBITS)+FRACUNIT/3, FixedDiv(FixedMul(ftime<<FRACBITS, ftime<<FRACBITS), 120<<FRACBITS)));
y = (BASEVIDHEIGHT<<FRACBITS) - FixedMul(417<<FRACBITS, aspect); y = (BASEVIDHEIGHT<<FRACBITS) - FixedMul(417<<FRACBITS, aspect);
// Draw the body // Draw the body
V_DrawSciencePatch(x, y, V_SNAPTOLEFT|V_SNAPTOBOTTOM, (patch = W_CachePatchName("PUREFAT1", PU_CACHE)), aspect); V_DrawSciencePatch(x, y, V_SNAPTOLEFT|V_SNAPTOBOTTOM, (patch = W_CachePatchName("PUREFAT1", PU_CACHE)), aspect);
@ -771,7 +771,7 @@ void F_IntroDrawer(void)
F_RunWipe(99,true); F_RunWipe(99,true);
} }
S_ChangeMusic(mus_read_m, false); S_ChangeMusicInternal("read_m", false);
} }
else if (intro_scenenum == 3) else if (intro_scenenum == 3)
roidtics = BASEVIDWIDTH - 64; roidtics = BASEVIDWIDTH - 64;
@ -977,13 +977,16 @@ static const char *credits[] = {
"\"Monster\" Iestyn Jealous", "\"Monster\" Iestyn Jealous",
"Ronald \"Furyhunter\" Kinard", // The SDL2 port "Ronald \"Furyhunter\" Kinard", // The SDL2 port
"John \"JTE\" Muniz", "John \"JTE\" Muniz",
"Ehab \"Wolfy\" Saeed",
"\"SSNTails\"", "\"SSNTails\"",
"Matthew \"Inuyasha\" Walsh", "Matthew \"Inuyasha\" Walsh",
"", "",
"\1Programming", "\1Programming",
"\1Assistance", "\1Assistance",
"\"chi.miru\"", // Red's secret weapon, the REAL reason slopes exist (also helped port drawing code from ZDoom)
"Andrew \"orospakr\" Clunis", "Andrew \"orospakr\" Clunis",
"Gregor \"Oogaland\" Dick", "Gregor \"Oogaland\" Dick",
"Vivian \"toaster\" Grannell",
"Julio \"Chaos Zero 64\" Guir", "Julio \"Chaos Zero 64\" Guir",
"\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog "\"Kalaron\"", // Coded some of Sryder13's collection of OpenGL fixes, especially fog
"Matthew \"Shuffle\" Marsalko", "Matthew \"Shuffle\" Marsalko",
@ -999,6 +1002,7 @@ static const char *credits[] = {
"Jim \"MotorRoach\" DeMello", "Jim \"MotorRoach\" DeMello",
"Desmond \"Blade\" DesJardins", "Desmond \"Blade\" DesJardins",
"Sherman \"CoatRack\" DesJardins", "Sherman \"CoatRack\" DesJardins",
"Vivian \"toaster\" Grannell",
"Andrew \"Senku Niola\" Moran", "Andrew \"Senku Niola\" Moran",
"David \"Instant Sonic\" Spencer Jr.", "David \"Instant Sonic\" Spencer Jr.",
"\"SSNTails\"", "\"SSNTails\"",
@ -1019,7 +1023,7 @@ static const char *credits[] = {
"\"Monster\" Iestyn Jealous", "\"Monster\" Iestyn Jealous",
"Jarel \"Arrow\" Jones", "Jarel \"Arrow\" Jones",
"Stefan \"Stuf\" Rimalia", "Stefan \"Stuf\" Rimalia",
"Shane Strife", "Shane Mychal Sexton",
"\"Spazzo\"", "\"Spazzo\"",
"David \"Big Wave Dave\" Spencer Sr.", "David \"Big Wave Dave\" Spencer Sr.",
"David \"Instant Sonic\" Spencer Jr.", "David \"Instant Sonic\" Spencer Jr.",
@ -1032,6 +1036,7 @@ static const char *credits[] = {
"Sherman \"CoatRack\" DesJardins", "Sherman \"CoatRack\" DesJardins",
"Ben \"Mystic\" Geyer", "Ben \"Mystic\" Geyer",
"Nathan \"Jazz\" Giroux", "Nathan \"Jazz\" Giroux",
"Vivian \"toaster\" Grannell",
"Dan \"Blitzzo\" Hagerstrand", "Dan \"Blitzzo\" Hagerstrand",
"Kepa \"Nev3r\" Iceta", "Kepa \"Nev3r\" Iceta",
"Thomas \"Shadow Hog\" Igoe", "Thomas \"Shadow Hog\" Igoe",
@ -1068,7 +1073,7 @@ static const char *credits[] = {
"iD Software", "iD Software",
"Alex \"MistaED\" Fuller", "Alex \"MistaED\" Fuller",
"FreeDoom Project", // Used some of the mancubus and rocket launcher sprites for Brak "FreeDoom Project", // Used some of the mancubus and rocket launcher sprites for Brak
"Randy Heit (<!>)", // For his MSPaint <!> sprite that we nicked "Randi Heit (<!>)", // For their MSPaint <!> sprite that we nicked
"", "",
"\1Produced By", "\1Produced By",
"Sonic Team Junior", "Sonic Team Junior",
@ -1124,7 +1129,7 @@ void F_StartCredits(void)
CON_ClearHUD(); CON_ClearHUD();
S_StopMusic(); S_StopMusic();
S_ChangeMusic(mus_credit, false); S_ChangeMusicInternal("credit", false);
finalecount = 0; finalecount = 0;
animtimer = 0; animtimer = 0;
@ -1421,7 +1426,7 @@ void F_StartTitleScreen(void)
// IWAD dependent stuff. // IWAD dependent stuff.
S_ChangeMusic(mus_titles, looptitle); S_ChangeMusicInternal("titles", looptitle);
animtimer = 0; animtimer = 0;
@ -1587,7 +1592,7 @@ void F_StartContinue(void)
// In case menus are still up?!! // In case menus are still up?!!
M_ClearMenus(true); M_ClearMenus(true);
S_ChangeMusic(mus_contsc, false); S_ChangeMusicInternal("contsc", false);
S_StopSounds(); S_StopSounds();
timetonext = TICRATE*11; timetonext = TICRATE*11;
@ -1701,8 +1706,10 @@ static void F_AdvanceToNextScene(void)
picxpos = cutscenes[cutnum]->scene[scenenum].xcoord[picnum]; picxpos = cutscenes[cutnum]->scene[scenenum].xcoord[picnum];
picypos = cutscenes[cutnum]->scene[scenenum].ycoord[picnum]; picypos = cutscenes[cutnum]->scene[scenenum].ycoord[picnum];
if (cutscenes[cutnum]->scene[scenenum].musicslot != 0) if (cutscenes[cutnum]->scene[scenenum].musswitch[0])
S_ChangeMusic(cutscenes[cutnum]->scene[scenenum].musicslot, cutscenes[cutnum]->scene[scenenum].musicloop); S_ChangeMusic(cutscenes[cutnum]->scene[scenenum].musswitch,
cutscenes[cutnum]->scene[scenenum].musswitchflags,
cutscenes[cutnum]->scene[scenenum].musicloop);
// Fade to the next // Fade to the next
dofadenow = true; dofadenow = true;
@ -1773,8 +1780,10 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
animtimer = cutscenes[cutnum]->scene[0].picduration[0]; // Picture duration animtimer = cutscenes[cutnum]->scene[0].picduration[0]; // Picture duration
stoptimer = 0; stoptimer = 0;
if (cutscenes[cutnum]->scene[scenenum].musicslot != 0) if (cutscenes[cutnum]->scene[0].musswitch[0])
S_ChangeMusic(cutscenes[cutnum]->scene[scenenum].musicslot, cutscenes[cutnum]->scene[scenenum].musicloop); S_ChangeMusic(cutscenes[cutnum]->scene[0].musswitch,
cutscenes[cutnum]->scene[0].musswitchflags,
cutscenes[cutnum]->scene[0].musicloop);
else else
S_StopMusic(); S_StopMusic();
} }

View file

@ -90,6 +90,7 @@ enum
// custom intermissions // custom intermissions
wipe_specinter_toblack, wipe_specinter_toblack,
wipe_multinter_toblack, wipe_multinter_toblack,
wipe_speclevel_towhite,
wipe_level_final, wipe_level_final,
wipe_intermission_final, wipe_intermission_final,
@ -108,7 +109,7 @@ enum
NUMWIPEDEFS NUMWIPEDEFS
}; };
#define WIPEFINALSHIFT 12 #define WIPEFINALSHIFT 13
extern UINT8 wipedefs[NUMWIPEDEFS]; extern UINT8 wipedefs[NUMWIPEDEFS];
#endif #endif

View file

@ -58,6 +58,7 @@ UINT8 wipedefs[NUMWIPEDEFS] = {
0, // wipe_specinter_toblack 0, // wipe_specinter_toblack
0, // wipe_multinter_toblack 0, // wipe_multinter_toblack
0, // wipe_speclevel_towhite
0, // wipe_level_final 0, // wipe_level_final
0, // wipe_intermission_final 0, // wipe_intermission_final
@ -231,34 +232,52 @@ static void F_DoWipe(fademask_t *fademask)
maskx = masky = 0; maskx = masky = 0;
do do
{ {
// pointer to transtable that this mask would use
transtbl = transtables + ((9 - *mask)<<FF_TRANSSHIFT);
// (ignore that it goes out of bounds if *mask is 0 or 10 --
// it wouldn't be used in those cases anyway)
draw_rowstart = scrxpos[maskx]; draw_rowstart = scrxpos[maskx];
draw_rowend = scrxpos[maskx + 1]; draw_rowend = scrxpos[maskx + 1];
draw_linestart = scrypos[masky]; draw_linestart = scrypos[masky];
draw_lineend = scrypos[masky + 1]; draw_lineend = scrypos[masky + 1];
// DRAWING LOOP
relativepos = (draw_linestart * vid.width) + draw_rowstart; relativepos = (draw_linestart * vid.width) + draw_rowstart;
draw_linestogo = draw_lineend - draw_linestart; draw_linestogo = draw_lineend - draw_linestart;
if (*mask == 0)
{
// shortcut - memcpy source to work
while (draw_linestogo--)
{
M_Memcpy(w_base+relativepos, s_base+relativepos, draw_rowend-draw_rowstart);
relativepos += vid.width;
}
}
else if (*mask == 10)
{
// shortcut - memcpy target to work
while (draw_linestogo--)
{
M_Memcpy(w_base+relativepos, e_base+relativepos, draw_rowend-draw_rowstart);
relativepos += vid.width;
}
}
else
{
// pointer to transtable that this mask would use
transtbl = transtables + ((9 - *mask)<<FF_TRANSSHIFT);
// DRAWING LOOP
while (draw_linestogo--) while (draw_linestogo--)
{ {
w = w_base + relativepos; w = w_base + relativepos;
s = s_base + relativepos; s = s_base + relativepos;
e = e_base + relativepos; e = e_base + relativepos;
draw_rowstogo = draw_rowend - draw_rowstart; draw_rowstogo = draw_rowend - draw_rowstart;
while (draw_rowstogo--) while (draw_rowstogo--)
{ *w++ = transtbl[ ( *e++ << 8 ) + *s++ ];
if (*s != *e)
*w = ((*mask == 0) ? *s : (*mask == 10) ? *e : transtbl[(*e<<8) + *s]);
++w, ++s, ++e;
}
relativepos += vid.width; relativepos += vid.width;
} }
// END DRAWING LOOP // END DRAWING LOOP
}
if (++maskx >= fademask->width) if (++maskx >= fademask->width)
++masky, maskx = 0; ++masky, maskx = 0;

View file

@ -69,8 +69,10 @@ static void G_DoStartContinue(void);
static void G_DoContinued(void); static void G_DoContinued(void);
static void G_DoWorldDone(void); static void G_DoWorldDone(void);
char mapmusname[7]; // Music name
UINT16 mapmusflags; // Track and reset bit
INT16 gamemap = 1; INT16 gamemap = 1;
UINT32 mapmusic; // music, track, and reset bit
INT16 maptol; INT16 maptol;
UINT8 globalweather = 0; UINT8 globalweather = 0;
INT32 curWeather = PRECIP_NONE; INT32 curWeather = PRECIP_NONE;
@ -124,7 +126,7 @@ boolean useNightsSS = false;
UINT8 skincolor_redteam = SKINCOLOR_RED; UINT8 skincolor_redteam = SKINCOLOR_RED;
UINT8 skincolor_blueteam = SKINCOLOR_BLUE; UINT8 skincolor_blueteam = SKINCOLOR_BLUE;
UINT8 skincolor_redring = SKINCOLOR_RED; UINT8 skincolor_redring = SKINCOLOR_RED;
UINT8 skincolor_bluering = SKINCOLOR_STEELBLUE; UINT8 skincolor_bluering = SKINCOLOR_AZURE;
tic_t countdowntimer = 0; tic_t countdowntimer = 0;
boolean countdowntimeup = false; boolean countdowntimeup = false;
@ -298,9 +300,6 @@ static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"},
#if JOYAXISSET > 3 #if JOYAXISSET > 3
{7, "Pitch"}, {8, "Roll"}, {-7, "Pitch-"}, {-8, "Roll-"}, {7, "Pitch"}, {8, "Roll"}, {-7, "Pitch-"}, {-8, "Roll-"},
#endif #endif
#if JOYAXISSET > 3
{7, "Pitch"}, {8, "Roll"}, {-7, "Pitch-"}, {-8, "Roll-"},
#endif
#if JOYAXISSET > 4 #if JOYAXISSET > 4
{7, "Yaw"}, {8, "Dummy"}, {-7, "Yaw-"}, {-8, "Dummy-"}, {7, "Yaw"}, {8, "Dummy"}, {-7, "Yaw-"}, {-8, "Dummy-"},
#endif #endif
@ -2186,12 +2185,13 @@ void G_PlayerReborn(INT32 player)
if (p-players == consoleplayer) if (p-players == consoleplayer)
{ {
if (mapmusic & MUSIC_RELOADRESET) // TODO: Might not need this here if (mapmusflags & MUSIC_RELOADRESET)
{ {
mapmusic = mapheaderinfo[gamemap-1]->musicslot strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7);
| (mapheaderinfo[gamemap-1]->musicslottrack << MUSIC_TRACKSHIFT); mapmusname[6] = 0;
mapmusflags = mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK;
} }
S_ChangeMusic(mapmusic, true); S_ChangeMusic(mapmusname, mapmusflags, true);
} }
if (gametype == GT_COOP) if (gametype == GT_COOP)
@ -2332,6 +2332,11 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost)
} }
} }
P_MovePlayerToSpawn(playernum, spawnpoint); P_MovePlayerToSpawn(playernum, spawnpoint);
#ifdef HAVE_BLUA
LUAh_PlayerSpawn(&players[playernum]); // Lua hook for player spawning :)
#endif
} }
mapthing_t *G_FindCTFStart(INT32 playernum) mapthing_t *G_FindCTFStart(INT32 playernum)
@ -2875,7 +2880,8 @@ static void G_DoCompleted(void)
// We are committed to this map now. // We are committed to this map now.
// We may as well allocate its header if it doesn't exist // 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); P_AllocMapHeader(nextmap);
if (skipstats) if (skipstats)
@ -3525,7 +3531,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
if (paused) if (paused)
{ {
paused = false; paused = false;
S_ResumeSound(); S_ResumeAudio();
} }
if (netgame || multiplayer) // Nice try, haxor. 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; globalweather = mapheaderinfo[gamemap-1]->weather;
// Don't carry over custom music change to another map. // Don't carry over custom music change to another map.
mapmusic |= MUSIC_RELOADRESET; mapmusflags |= MUSIC_RELOADRESET;
ultimatemode = pultmode; ultimatemode = pultmode;
playerdeadview = false; playerdeadview = false;
@ -4340,10 +4346,8 @@ void G_GhostTicker(void)
switch(g->color) switch(g->color)
{ {
case GHC_SUPER: // Super Sonic (P_DoSuperStuff) case GHC_SUPER: // Super Sonic (P_DoSuperStuff)
if (leveltime % 9 < 5) g->mo->color = SKINCOLOR_SUPER1;
g->mo->color = SKINCOLOR_SUPER1 + leveltime % 9; g->mo->color += abs( ( ( leveltime >> 1 ) % 9) - 4);
else
g->mo->color = SKINCOLOR_SUPER1 + 9 - leveltime % 9;
break; break;
case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer) case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer)
g->mo->color = (UINT8)(leveltime % MAXSKINCOLORS); g->mo->color = (UINT8)(leveltime % MAXSKINCOLORS);
@ -5587,7 +5591,7 @@ boolean G_CheckDemoStatus(void)
free(demobuffer); free(demobuffer);
demorecording = false; demorecording = false;
if (!modeattacking == ATTACKING_RECORD) if (modeattacking != ATTACKING_RECORD)
{ {
if (saved) if (saved)
CONS_Printf(M_GetText("Demo %s recorded\n"), demoname); CONS_Printf(M_GetText("Demo %s recorded\n"), demoname);

View file

@ -16,7 +16,6 @@
#include "g_input.h" #include "g_input.h"
#include "keys.h" #include "keys.h"
#include "hu_stuff.h" // need HUFONT start & end #include "hu_stuff.h" // need HUFONT start & end
#include "keys.h"
#include "d_net.h" #include "d_net.h"
#include "console.h" #include "console.h"
@ -1042,13 +1041,13 @@ INT32 G_KeyStringtoNum(const char *keystr)
if (!keystr[1] && keystr[0] > ' ' && keystr[0] <= 'z') if (!keystr[1] && keystr[0] > ' ' && keystr[0] <= 'z')
return keystr[0]; return keystr[0];
if (!strncmp(keystr, "KEY", 3) && keystr[3] >= '0' && keystr[3] <= '9')
return atoi(&keystr[3]);
for (j = 0; j < NUMKEYNAMES; j++) for (j = 0; j < NUMKEYNAMES; j++)
if (!stricmp(keynames[j].name, keystr)) if (!stricmp(keynames[j].name, keystr))
return keynames[j].keynum; return keynames[j].keynum;
if (strlen(keystr) > 3)
return atoi(&keystr[3]);
return 0; return 0;
} }

View file

@ -46,8 +46,8 @@ typedef unsigned char FBOOLEAN;
#define HWR_PATCHES_CHROMAKEY_COLORINDEX 0 #define HWR_PATCHES_CHROMAKEY_COLORINDEX 0
#define HWR_CHROMAKEY_EQUIVALENTCOLORINDEX 1 #define HWR_CHROMAKEY_EQUIVALENTCOLORINDEX 1
#else #else
#define HWR_PATCHES_CHROMAKEY_COLORINDEX 247 #define HWR_PATCHES_CHROMAKEY_COLORINDEX 255
#define HWR_CHROMAKEY_EQUIVALENTCOLORINDEX 220 #define HWR_CHROMAKEY_EQUIVALENTCOLORINDEX 130
#endif #endif
// the chroma key color shows on border sprites, set it to black // the chroma key color shows on border sprites, set it to black

View file

@ -36,9 +36,7 @@ typedef struct
{ {
float x; float x;
float y; float y;
//#ifdef SLOPENESS
float z; float z;
//#endif
} polyvertex_t; } polyvertex_t;
#ifdef _MSC_VER #ifdef _MSC_VER
@ -79,6 +77,7 @@ typedef struct gr_vissprite_s
boolean vflip; boolean vflip;
//Hurdler: 25/04/2000: now support colormap in hardware mode //Hurdler: 25/04/2000: now support colormap in hardware mode
UINT8 *colormap; UINT8 *colormap;
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
} gr_vissprite_t; } gr_vissprite_t;
// -------- // --------

View file

@ -539,6 +539,8 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fi
static FOutVector *planeVerts = NULL; static FOutVector *planeVerts = NULL;
static UINT16 numAllocedPlaneVerts = 0; static UINT16 numAllocedPlaneVerts = 0;
(void)sector;
// no convex poly were generated for this subsector // no convex poly were generated for this subsector
if (!xsub->planepoly) if (!xsub->planepoly)
return; return;
@ -678,25 +680,6 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fi
v3d->x = pv->x; v3d->x = pv->x;
v3d->y = height; v3d->y = height;
v3d->z = pv->y; 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 // only useful for flat coloured triangles
@ -2856,7 +2839,6 @@ static void HWR_AddPolyObjectPlanes(void)
// : Draw one or more line segments. // : Draw one or more line segments.
// Notes : Sets gr_cursectorlight to the light of the parent sector, to modulate wall textures // 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) static void HWR_Subsector(size_t num)
{ {
INT16 count; INT16 count;
@ -2867,7 +2849,6 @@ static void HWR_Subsector(size_t num)
INT32 ceilinglightlevel; INT32 ceilinglightlevel;
INT32 locFloorHeight, locCeilingHeight; INT32 locFloorHeight, locCeilingHeight;
INT32 light = 0; INT32 light = 0;
fixed_t wh;
extracolormap_t *floorcolormap; extracolormap_t *floorcolormap;
extracolormap_t *ceilingcolormap; 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) <<FRACBITS) + (FRACUNIT/2);
if (wh > 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; sub->validcount = validcount;
} }
@ -3998,6 +3959,7 @@ static void HWR_SortVisSprites(void)
gr_vissprite_t *best = NULL; gr_vissprite_t *best = NULL;
gr_vissprite_t unsorted; gr_vissprite_t unsorted;
float bestdist; float bestdist;
INT32 bestdispoffset;
if (!gr_visspritecount) if (!gr_visspritecount)
return; return;
@ -4025,11 +3987,19 @@ static void HWR_SortVisSprites(void)
for (i = 0; i < gr_visspritecount; i++) for (i = 0; i < gr_visspritecount; i++)
{ {
bestdist = ZCLIP_PLANE-1; bestdist = ZCLIP_PLANE-1;
bestdispoffset = INT32_MAX;
for (ds = unsorted.next; ds != &unsorted; ds = ds->next) for (ds = unsorted.next; ds != &unsorted; ds = ds->next)
{ {
if (ds->tz > bestdist) if (ds->tz > bestdist)
{ {
bestdist = ds->tz; 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; best = ds;
} }
} }
@ -4653,6 +4623,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
#endif #endif
vis->x2 = tx; vis->x2 = tx;
vis->tz = tz; vis->tz = tz;
vis->dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST
vis->patchlumpnum = sprframe->lumppat[rot]; vis->patchlumpnum = sprframe->lumppat[rot];
vis->flip = flip; vis->flip = flip;
vis->mobj = thing; vis->mobj = thing;
@ -4769,6 +4740,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
vis->x1 = x1; vis->x1 = x1;
vis->x2 = tx; vis->x2 = tx;
vis->tz = tz; vis->tz = tz;
vis->dispoffset = 0; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST
vis->patchlumpnum = sprframe->lumppat[rot]; vis->patchlumpnum = sprframe->lumppat[rot];
vis->flip = flip; vis->flip = flip;
vis->mobj = (mobj_t *)thing; vis->mobj = (mobj_t *)thing;
@ -5488,11 +5460,6 @@ void HWR_Startup(void)
HWR_AddEngineCommands(); HWR_AddEngineCommands();
HWR_InitTextureCache(); 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(); HWR_InitMD2();
#ifdef ALAM_LIGHTING #ifdef ALAM_LIGHTING

View file

@ -41,6 +41,7 @@
#include "../r_things.h" #include "../r_things.h"
#include "hw_main.h" #include "hw_main.h"
#include "../v_video.h"
#ifdef HAVE_PNG #ifdef HAVE_PNG
#ifndef _MSC_VER #ifndef _MSC_VER
@ -881,6 +882,59 @@ static void md2_loadTexture(md2_t *model)
HWR_UnlockCachedPatch(grpatch); 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! // Don't spam the console, or the OS with fopen requests!
static boolean nomd2s = false; static boolean nomd2s = false;
@ -1050,6 +1104,238 @@ spritemd2found:
fclose(f); 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 // HWR_DrawMD2 : Draw MD2
@ -1085,7 +1371,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
if (!cv_grmd2.value) if (!cv_grmd2.value)
return; return;
if (!spr->precip) if (spr->precip)
return; return;
// MD2 colormap fix // MD2 colormap fix
@ -1180,14 +1466,26 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
gpatch = md2->grpatch; gpatch = md2->grpatch;
if (!gpatch || !gpatch->mipmap.grInfo.format || !gpatch->mipmap.downloaded) if (!gpatch || !gpatch->mipmap.grInfo.format || !gpatch->mipmap.downloaded)
md2_loadTexture(md2); md2_loadTexture(md2);
gpatch = md2->grpatch; // Load it again, because it isn't being loaded into gpatch after md2_loadtexture... gpatch = md2->grpatch; // Load it again, because it isn't being loaded into gpatch after md2_loadtexture...
if ((gpatch && gpatch->mipmap.grInfo.format) // don't load the blend texture if the base texture isn't available
&& (!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 if (gpatch && gpatch->mipmap.grInfo.format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture
{
if ((skincolors_t)spr->mobj->color != SKINCOLOR_NONE &&
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 // This is safe, since we know the texture has been downloaded
HWD.pfnSetTexture(&gpatch->mipmap); HWD.pfnSetTexture(&gpatch->mipmap);
} }
}
else else
{ {
// Sprite // Sprite
@ -1195,17 +1493,38 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
HWR_GetMappedPatch(gpatch, spr->colormap); 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 //FIXME: this is not yet correct
frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->header.numFrames; frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->header.numFrames;
buff = md2->model->glCommandBuffer; buff = md2->model->glCommandBuffer;
curr = &md2->model->frames[frame]; curr = &md2->model->frames[frame];
if (cv_grmd2.value == 1 if (cv_grmd2.value == 1)
&& spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL {
// 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])) && !(spr->mobj->player && spr->mobj->state->nextstate == S_PLAY_WAIT && spr->mobj->state == &states[S_PLAY_STND]))
{ {
const INT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames; const UINT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames;
next = &md2->model->frames[nextframe]; next = &md2->model->frames[nextframe];
} }
}
}
//Hurdler: it seems there is still a small problem with mobj angle //Hurdler: it seems there is still a small problem with mobj angle
p.x = FIXED_TO_FLOAT(spr->mobj->x); p.x = FIXED_TO_FLOAT(spr->mobj->x);

View file

@ -120,6 +120,7 @@ typedef struct
float offset; float offset;
md2_model_t *model; md2_model_t *model;
void *grpatch; void *grpatch;
void *blendgrpatch;
boolean notfound; boolean notfound;
INT32 skin; INT32 skin;
} md2_t; } md2_t;

View file

@ -2371,7 +2371,7 @@ EXPORT void HWRAPI(MakeScreenTexture) (void)
Clamp2D(GL_TEXTURE_WRAP_S); Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T); Clamp2D(GL_TEXTURE_WRAP_T);
#ifndef KOS_GL_COMPATIBILITY #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 #endif
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now 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_S);
Clamp2D(GL_TEXTURE_WRAP_T); Clamp2D(GL_TEXTURE_WRAP_T);
#ifndef KOS_GL_COMPATIBILITY #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 #endif
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now

File diff suppressed because it is too large Load diff

View file

@ -588,6 +588,7 @@ enum playersprite
SPR2_DASH, SPR2_DASH,
SPR2_GASP, SPR2_GASP,
SPR2_JUMP, SPR2_JUMP,
SPR2_SPNG, // spring
SPR2_FALL, SPR2_FALL,
SPR2_EDGE, SPR2_EDGE,
SPR2_RIDE, SPR2_RIDE,
@ -613,6 +614,7 @@ enum playersprite
SPR2_SSPN, SPR2_SSPN,
SPR2_SGSP, SPR2_SGSP,
SPR2_SJMP, SPR2_SJMP,
SPR2_SSPG,
SPR2_SFAL, SPR2_SFAL,
SPR2_SEDG, SPR2_SEDG,
SPR2_SRID, SPR2_SRID,
@ -649,7 +651,8 @@ typedef enum state
S_PLAY_SPIN, S_PLAY_SPIN,
S_PLAY_DASH, S_PLAY_DASH,
S_PLAY_GASP, S_PLAY_GASP,
S_PLAY_JUMP, S_PLAY_JUMP, // spin jump (todo: make jump separate from spring up for non-spin chars too?)
S_PLAY_SPRING,
S_PLAY_FALL, S_PLAY_FALL,
S_PLAY_EDGE, S_PLAY_EDGE,
S_PLAY_RIDE, S_PLAY_RIDE,
@ -673,7 +676,8 @@ typedef enum state
S_PLAY_SUPER_DRWN, S_PLAY_SUPER_DRWN,
S_PLAY_SUPER_SPIN, S_PLAY_SUPER_SPIN,
S_PLAY_SUPER_GASP, S_PLAY_SUPER_GASP,
S_PLAY_SUPER_JUMP, S_PLAY_SUPER_JUMP, // see note above
S_PLAY_SUPER_SPRING,
S_PLAY_SUPER_FALL, S_PLAY_SUPER_FALL,
S_PLAY_SUPER_EDGE, S_PLAY_SUPER_EDGE,
S_PLAY_SUPER_RIDE, S_PLAY_SUPER_RIDE,
@ -1475,30 +1479,7 @@ typedef enum state
S_MSSHIELD_F12, S_MSSHIELD_F12,
// Ring // Ring
S_RING1, S_RING,
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,
// Blue Sphere for special stages // Blue Sphere for special stages
S_BLUEBALL, S_BLUEBALL,
@ -1514,39 +1495,10 @@ typedef enum state
S_GRAVWELLRED3, S_GRAVWELLRED3,
// Individual Team Rings // Individual Team Rings
S_TEAMRING1, S_TEAMRING,
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,
// Special Stage Token // Special Stage Token
S_EMMY1, S_EMMY,
S_EMMY2,
S_EMMY3,
S_EMMY4,
S_EMMY5,
S_EMMY6,
S_EMMY7,
// Special Stage Token // Special Stage Token
S_TOKEN, S_TOKEN,
@ -1700,40 +1652,9 @@ typedef enum state
S_SPIKED2, S_SPIKED2,
// Starpost // Starpost
S_STARPOST1, S_STARPOST_IDLE,
S_STARPOST2, S_STARPOST_FLASH,
S_STARPOST3, S_STARPOST_SPIN,
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,
// Big floating mine // Big floating mine
S_BIGMINE1, S_BIGMINE1,
@ -2341,38 +2262,7 @@ typedef enum state
S_PITY10, S_PITY10,
// Invincibility Sparkles // Invincibility Sparkles
S_IVSP1, S_IVSP,
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,
// Super Sonic Spark // Super Sonic Spark
S_SSPK1, S_SSPK1,
@ -2559,283 +2449,17 @@ typedef enum state
S_RRNG6, S_RRNG6,
S_RRNG7, S_RRNG7,
// Bounce Ring // Weapon Ring Ammo
S_BOUNCERING1, S_BOUNCERINGAMMO,
S_BOUNCERING2, S_RAILRINGAMMO,
S_BOUNCERING3, S_INFINITYRINGAMMO,
S_BOUNCERING4, S_AUTOMATICRINGAMMO,
S_BOUNCERING5, S_EXPLOSIONRINGAMMO,
S_BOUNCERING6, S_SCATTERRINGAMMO,
S_BOUNCERING7, S_GRENADERINGAMMO,
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 pickup // Weapon pickup
S_BOUNCEPICKUP1, S_BOUNCEPICKUP,
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_BOUNCEPICKUPFADE1, S_BOUNCEPICKUPFADE1,
S_BOUNCEPICKUPFADE2, S_BOUNCEPICKUPFADE2,
S_BOUNCEPICKUPFADE3, S_BOUNCEPICKUPFADE3,
@ -2845,23 +2469,7 @@ typedef enum state
S_BOUNCEPICKUPFADE7, S_BOUNCEPICKUPFADE7,
S_BOUNCEPICKUPFADE8, S_BOUNCEPICKUPFADE8,
S_RAILPICKUP1, S_RAILPICKUP,
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_RAILPICKUPFADE1, S_RAILPICKUPFADE1,
S_RAILPICKUPFADE2, S_RAILPICKUPFADE2,
S_RAILPICKUPFADE3, S_RAILPICKUPFADE3,
@ -2871,23 +2479,7 @@ typedef enum state
S_RAILPICKUPFADE7, S_RAILPICKUPFADE7,
S_RAILPICKUPFADE8, S_RAILPICKUPFADE8,
S_AUTOPICKUP1, S_AUTOPICKUP,
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_AUTOPICKUPFADE1, S_AUTOPICKUPFADE1,
S_AUTOPICKUPFADE2, S_AUTOPICKUPFADE2,
S_AUTOPICKUPFADE3, S_AUTOPICKUPFADE3,
@ -2897,23 +2489,7 @@ typedef enum state
S_AUTOPICKUPFADE7, S_AUTOPICKUPFADE7,
S_AUTOPICKUPFADE8, S_AUTOPICKUPFADE8,
S_EXPLODEPICKUP1, S_EXPLODEPICKUP,
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_EXPLODEPICKUPFADE1, S_EXPLODEPICKUPFADE1,
S_EXPLODEPICKUPFADE2, S_EXPLODEPICKUPFADE2,
S_EXPLODEPICKUPFADE3, S_EXPLODEPICKUPFADE3,
@ -2923,23 +2499,7 @@ typedef enum state
S_EXPLODEPICKUPFADE7, S_EXPLODEPICKUPFADE7,
S_EXPLODEPICKUPFADE8, S_EXPLODEPICKUPFADE8,
S_SCATTERPICKUP1, S_SCATTERPICKUP,
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_SCATTERPICKUPFADE1, S_SCATTERPICKUPFADE1,
S_SCATTERPICKUPFADE2, S_SCATTERPICKUPFADE2,
S_SCATTERPICKUPFADE3, S_SCATTERPICKUPFADE3,
@ -2949,23 +2509,7 @@ typedef enum state
S_SCATTERPICKUPFADE7, S_SCATTERPICKUPFADE7,
S_SCATTERPICKUPFADE8, S_SCATTERPICKUPFADE8,
S_GRENADEPICKUP1, S_GRENADEPICKUP,
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_GRENADEPICKUPFADE1, S_GRENADEPICKUPFADE1,
S_GRENADEPICKUPFADE2, S_GRENADEPICKUPFADE2,
S_GRENADEPICKUPFADE3, S_GRENADEPICKUPFADE3,
@ -3346,101 +2890,22 @@ typedef enum state
S_ROCKSPAWN, S_ROCKSPAWN,
S_ROCKCRUMBLEA1, S_ROCKCRUMBLEA,
S_ROCKCRUMBLEA2, S_ROCKCRUMBLEB,
S_ROCKCRUMBLEA3, S_ROCKCRUMBLEC,
S_ROCKCRUMBLEA4, S_ROCKCRUMBLED,
S_ROCKCRUMBLEA5, S_ROCKCRUMBLEE,
S_ROCKCRUMBLEF,
S_ROCKCRUMBLEB1, S_ROCKCRUMBLEG,
S_ROCKCRUMBLEB2, S_ROCKCRUMBLEH,
S_ROCKCRUMBLEB3, S_ROCKCRUMBLEI,
S_ROCKCRUMBLEB4, S_ROCKCRUMBLEJ,
S_ROCKCRUMBLEB5, S_ROCKCRUMBLEK,
S_ROCKCRUMBLEL,
S_ROCKCRUMBLEC1, S_ROCKCRUMBLEM,
S_ROCKCRUMBLEC2, S_ROCKCRUMBLEN,
S_ROCKCRUMBLEC3, S_ROCKCRUMBLEO,
S_ROCKCRUMBLEC4, S_ROCKCRUMBLEP,
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_SRB1_CRAWLA1, S_SRB1_CRAWLA1,
S_SRB1_CRAWLA2, S_SRB1_CRAWLA2,
@ -3631,9 +3096,7 @@ typedef enum mobj_type
// Collectible Items // Collectible Items
MT_RING, MT_RING,
MT_FLINGRING, // Lost ring MT_FLINGRING, // Lost ring
#ifdef BLUE_SPHERES
MT_BLUEBALL, // Blue sphere replacement for special stages MT_BLUEBALL, // Blue sphere replacement for special stages
#endif
MT_REDTEAMRING, //Rings collectable by red team. MT_REDTEAMRING, //Rings collectable by red team.
MT_BLUETEAMRING, //Rings collectable by blue team. MT_BLUETEAMRING, //Rings collectable by blue team.
MT_EMMY, // emerald token for special stage MT_EMMY, // emerald token for special stage

View file

@ -1020,8 +1020,8 @@ static int lib_pDoSpring(lua_State *L)
NOHUD NOHUD
if (!spring || !object) if (!spring || !object)
return LUA_ErrInvalid(L, "mobj_t"); return LUA_ErrInvalid(L, "mobj_t");
P_DoSpring(spring, object); lua_pushboolean(L, P_DoSpring(spring, object));
return 0; return 1;
} }
// P_INTER // P_INTER
@ -1671,18 +1671,63 @@ static int lib_sStopSound(lua_State *L)
static int lib_sChangeMusic(lua_State *L) static int lib_sChangeMusic(lua_State *L)
{ {
UINT32 music_num = (UINT32)luaL_checkinteger(L, 1); #ifdef MUSICSLOT_COMPATIBILITY
const char *music_name;
UINT32 music_num;
char music_compat_name[7];
boolean looping;
player_t *player = NULL;
UINT16 music_flags = 0;
NOHUD
if (lua_isnumber(L, 1))
{
music_num = (UINT32)luaL_checkinteger(L, 1);
music_flags = (UINT16)(music_num & 0x0000FFFF);
if (music_flags && music_flags <= 1035)
snprintf(music_compat_name, 7, "%sM", G_BuildMapName((INT32)music_flags));
else if (music_flags && music_flags <= 1050)
strncpy(music_compat_name, compat_special_music_slots[music_flags - 1036], 7);
else
music_compat_name[0] = 0; // becomes empty string
music_compat_name[6] = 0;
music_name = (const char *)&music_compat_name;
music_flags = 0;
}
else
{
music_num = 0;
music_name = luaL_checkstring(L, 1);
}
looping = (boolean)lua_opttrueboolean(L, 2);
#else
const char *music_name = luaL_checkstring(L, 1);
boolean looping = (boolean)lua_opttrueboolean(L, 2); boolean looping = (boolean)lua_opttrueboolean(L, 2);
player_t *player = NULL; player_t *player = NULL;
UINT16 music_flags = 0;
NOHUD NOHUD
#endif
if (!lua_isnone(L, 3) && lua_isuserdata(L, 3)) if (!lua_isnone(L, 3) && lua_isuserdata(L, 3))
{ {
player = *((player_t **)luaL_checkudata(L, 3, META_PLAYER)); player = *((player_t **)luaL_checkudata(L, 3, META_PLAYER));
if (!player) if (!player)
return LUA_ErrInvalid(L, "player_t"); return LUA_ErrInvalid(L, "player_t");
} }
#ifdef MUSICSLOT_COMPATIBILITY
if (music_num)
music_flags = (UINT16)((music_num & 0x7FFF0000) >> 16);
else
#endif
music_flags = (UINT16)luaL_optinteger(L, 4, 0);
if (!player || P_IsLocalPlayer(player)) if (!player || P_IsLocalPlayer(player))
S_ChangeMusic(music_num, looping); S_ChangeMusic(music_name, music_flags, looping);
return 0; return 0;
} }

View file

@ -42,6 +42,7 @@ enum hook {
hook_LinedefExecute, hook_LinedefExecute,
hook_PlayerMsg, hook_PlayerMsg,
hook_HurtMsg, hook_HurtMsg,
hook_PlayerSpawn,
hook_MAX // last hook 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_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_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 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 #endif

View file

@ -53,6 +53,7 @@ const char *const hookNames[hook_MAX+1] = {
"LinedefExecute", "LinedefExecute",
"PlayerMsg", "PlayerMsg",
"HurtMsg", "HurtMsg",
"PlayerSpawn",
NULL NULL
}; };
@ -768,4 +769,33 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source)
return hooked; 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 #endif

View file

@ -16,7 +16,9 @@
#include "r_local.h" #include "r_local.h"
#include "st_stuff.h" // hudinfo[] #include "st_stuff.h" // hudinfo[]
#include "g_game.h" #include "g_game.h"
#include "i_video.h" // rendermode
#include "p_local.h" // camera_t #include "p_local.h" // camera_t
#include "screen.h" // screen width/height
#include "v_video.h" #include "v_video.h"
#include "w_wad.h" #include "w_wad.h"
#include "z_zone.h" #include "z_zone.h"
@ -486,7 +488,7 @@ static int libd_getColormap(lua_State *L)
INT32 skinnum = TC_DEFAULT; INT32 skinnum = TC_DEFAULT;
skincolors_t color = luaL_optinteger(L, 2, 0); skincolors_t color = luaL_optinteger(L, 2, 0);
UINT8* colormap = NULL; UINT8* colormap = NULL;
//HUDSAFE HUDONLY
if (lua_isnoneornil(L, 1)) if (lua_isnoneornil(L, 1))
; // defaults to TC_DEFAULT ; // defaults to TC_DEFAULT
else if (lua_type(L, 1) == LUA_TNUMBER) // skin number else if (lua_type(L, 1) == LUA_TNUMBER) // skin number
@ -510,6 +512,31 @@ static int libd_getColormap(lua_State *L)
return 1; 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[] = { static luaL_Reg lib_draw[] = {
{"patchExists", libd_patchExists}, {"patchExists", libd_patchExists},
{"cachePatch", libd_cachePatch}, {"cachePatch", libd_cachePatch},
@ -521,6 +548,9 @@ static luaL_Reg lib_draw[] = {
{"drawString", libd_drawString}, {"drawString", libd_drawString},
{"stringWidth", libd_stringWidth}, {"stringWidth", libd_stringWidth},
{"getColormap", libd_getColormap}, {"getColormap", libd_getColormap},
{"width", libd_width},
{"height", libd_height},
{"renderer", libd_renderer},
{NULL, NULL} {NULL, NULL}
}; };

View file

@ -42,6 +42,7 @@ extern lua_State *gL;
#define META_CVAR "CONSVAR_T*" #define META_CVAR "CONSVAR_T*"
#define META_SECTORLINES "SECTOR_T*LINES"
#define META_SIDENUM "LINE_T*SIDENUM" #define META_SIDENUM "LINE_T*SIDENUM"
#define META_HUDINFO "HUDINFO_T*" #define META_HUDINFO "HUDINFO_T*"

View file

@ -37,6 +37,7 @@ enum sector_e {
sector_thinglist, sector_thinglist,
sector_heightsec, sector_heightsec,
sector_camsec, sector_camsec,
sector_lines,
sector_ffloors sector_ffloors
}; };
@ -52,6 +53,7 @@ static const char *const sector_opt[] = {
"thinglist", "thinglist",
"heightsec", "heightsec",
"camsec", "camsec",
"lines",
"ffloors", "ffloors",
NULL}; NULL};
@ -260,6 +262,67 @@ static int sector_iterate(lua_State *L)
return 3; 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) static int sector_get(lua_State *L)
{ {
sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR));
@ -325,6 +388,9 @@ static int sector_get(lua_State *L)
return 0; return 0;
LUA_PushUserdata(L, &sectors[sector->camsec], META_SECTOR); LUA_PushUserdata(L, &sectors[sector->camsec], META_SECTOR);
return 1; return 1;
case sector_lines: // lines
LUA_PushUserdata(L, sector->lines, META_SECTORLINES);
return 1;
case sector_ffloors: // ffloors case sector_ffloors: // ffloors
lua_pushcfunction(L, lib_iterateSectorFFloors); lua_pushcfunction(L, lib_iterateSectorFFloors);
LUA_PushUserdata(L, sector->ffloors, META_FFLOOR); LUA_PushUserdata(L, sector->ffloors, META_FFLOOR);
@ -1111,9 +1177,13 @@ static int ffloor_set(lua_State *L)
case ffloor_bottompic: case ffloor_bottompic:
*ffloor->bottompic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3)); *ffloor->bottompic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3));
break; break;
case ffloor_flags: case ffloor_flags: {
ffloortype_e oldflags = ffloor->flags; // store FOF's old flags
ffloor->flags = luaL_checkinteger(L, 3); ffloor->flags = luaL_checkinteger(L, 3);
if (ffloor->flags != oldflags)
ffloor->target->moved = true; // reset target sector's lightlist
break; break;
}
case ffloor_alpha: case ffloor_alpha:
ffloor->alpha = (INT32)luaL_checkinteger(L, 3); ffloor->alpha = (INT32)luaL_checkinteger(L, 3);
break; break;
@ -1157,26 +1227,23 @@ static int mapheaderinfo_get(lua_State *L)
{ {
mapheader_t *header = *((mapheader_t **)luaL_checkudata(L, 1, META_MAPHEADER)); mapheader_t *header = *((mapheader_t **)luaL_checkudata(L, 1, META_MAPHEADER));
const char *field = luaL_checkstring(L, 2); const char *field = luaL_checkstring(L, 2);
//INT16 i; INT16 i;
if (fastcmp(field,"lvlttl")) { if (fastcmp(field,"lvlttl"))
//for (i = 0; i < 21; i++) lua_pushstring(L, header->lvlttl);
// if (!header->lvlttl[i]) else if (fastcmp(field,"subttl"))
// break; lua_pushstring(L, header->subttl);
lua_pushlstring(L, header->lvlttl, 21);
} else if (fastcmp(field,"subttl"))
lua_pushlstring(L, header->subttl, 32);
else if (fastcmp(field,"actnum")) else if (fastcmp(field,"actnum"))
lua_pushinteger(L, header->actnum); lua_pushinteger(L, header->actnum);
else if (fastcmp(field,"typeoflevel")) else if (fastcmp(field,"typeoflevel"))
lua_pushinteger(L, header->typeoflevel); lua_pushinteger(L, header->typeoflevel);
else if (fastcmp(field,"nextlevel")) else if (fastcmp(field,"nextlevel"))
lua_pushinteger(L, header->nextlevel); lua_pushinteger(L, header->nextlevel);
else if (fastcmp(field,"musicslot")) else if (fastcmp(field,"musname"))
lua_pushinteger(L, header->musicslot); lua_pushstring(L, header->musname);
else if (fastcmp(field,"musicslottrack")) else if (fastcmp(field,"mustrack"))
lua_pushinteger(L, header->musicslottrack); lua_pushinteger(L, header->mustrack);
else if (fastcmp(field,"forcecharacter")) else if (fastcmp(field,"forcecharacter"))
lua_pushlstring(L, header->forcecharacter, 16); lua_pushstring(L, header->forcecharacter);
else if (fastcmp(field,"weather")) else if (fastcmp(field,"weather"))
lua_pushinteger(L, header->weather); lua_pushinteger(L, header->weather);
else if (fastcmp(field,"skynum")) else if (fastcmp(field,"skynum"))
@ -1187,12 +1254,15 @@ static int mapheaderinfo_get(lua_State *L)
lua_pushinteger(L, header->skybox_scaley); lua_pushinteger(L, header->skybox_scaley);
else if (fastcmp(field,"skybox_scalez")) else if (fastcmp(field,"skybox_scalez"))
lua_pushinteger(L, header->skybox_scalez); lua_pushinteger(L, header->skybox_scalez);
else if (fastcmp(field,"interscreen")) else if (fastcmp(field,"interscreen")) {
lua_pushlstring(L, header->interscreen, 8); for (i = 0; i < 8; i++)
else if (fastcmp(field,"runsoc")) if (!header->interscreen[i])
lua_pushlstring(L, header->runsoc, 32); break;
lua_pushlstring(L, header->interscreen, i);
} else if (fastcmp(field,"runsoc"))
lua_pushstring(L, header->runsoc);
else if (fastcmp(field,"scriptname")) else if (fastcmp(field,"scriptname"))
lua_pushlstring(L, header->scriptname, 32); lua_pushstring(L, header->scriptname);
else if (fastcmp(field,"precutscenenum")) else if (fastcmp(field,"precutscenenum"))
lua_pushinteger(L, header->precutscenenum); lua_pushinteger(L, header->precutscenenum);
else if (fastcmp(field,"cutscenenum")) else if (fastcmp(field,"cutscenenum"))
@ -1217,11 +1287,11 @@ static int mapheaderinfo_get(lua_State *L)
else { else {
// Read custom vars now // Read custom vars now
// (note: don't include the "LUA." in your lua scripts!) // (note: don't include the "LUA." in your lua scripts!)
UINT8 i = 0; UINT8 j = 0;
for (;i < header->numCustomOptions && !fastcmp(field, header->customopts[i].option); ++i); for (;j < header->numCustomOptions && !fastcmp(field, header->customopts[j].option); ++j);
if(i < header->numCustomOptions) if(j < header->numCustomOptions)
lua_pushlstring(L, header->customopts[i].value, 255); lua_pushstring(L, header->customopts[j].value);
else else
lua_pushnil(L); lua_pushnil(L);
} }
@ -1230,6 +1300,14 @@ static int mapheaderinfo_get(lua_State *L)
int LUA_MapLib(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); luaL_newmetatable(L, META_SECTOR);
lua_pushcfunction(L, sector_get); lua_pushcfunction(L, sector_get);
lua_setfield(L, -2, "__index"); lua_setfield(L, -2, "__index");

View file

@ -77,7 +77,9 @@ static int lib_finecosine(lua_State *L)
static int lib_finetangent(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; return 1;
} }
@ -164,7 +166,7 @@ static int lib_all7emeralds(lua_State *L)
// Returns both color and frame numbers! // Returns both color and frame numbers!
static int lib_coloropposite(lua_State *L) 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]); // push color
lua_pushinteger(L, Color_Opposite[colornum*2+1]); // push frame lua_pushinteger(L, Color_Opposite[colornum*2+1]); // push frame
return 2; return 2;

View file

@ -34,6 +34,7 @@ enum mobj_e {
mobj_angle, mobj_angle,
mobj_sprite, mobj_sprite,
mobj_frame, mobj_frame,
mobj_anim_duration,
mobj_touching_sectorlist, mobj_touching_sectorlist,
mobj_subsector, mobj_subsector,
mobj_floorz, mobj_floorz,
@ -92,6 +93,7 @@ static const char *const mobj_opt[] = {
"angle", "angle",
"sprite", "sprite",
"frame", "frame",
"anim_duration",
"touching_sectorlist", "touching_sectorlist",
"subsector", "subsector",
"floorz", "floorz",
@ -187,6 +189,9 @@ static int mobj_get(lua_State *L)
case mobj_frame: case mobj_frame:
lua_pushinteger(L, mo->frame); lua_pushinteger(L, mo->frame);
break; break;
case mobj_anim_duration:
lua_pushinteger(L, mo->anim_duration);
break;
case mobj_touching_sectorlist: case mobj_touching_sectorlist:
return UNIMPLEMENTED; return UNIMPLEMENTED;
case mobj_subsector: case mobj_subsector:
@ -406,6 +411,9 @@ static int mobj_set(lua_State *L)
case mobj_frame: case mobj_frame:
mo->frame = (UINT32)luaL_checkinteger(L, 3); mo->frame = (UINT32)luaL_checkinteger(L, 3);
break; break;
case mobj_anim_duration:
mo->anim_duration = (UINT16)luaL_checkinteger(L, 3);
break;
case mobj_touching_sectorlist: case mobj_touching_sectorlist:
return UNIMPLEMENTED; return UNIMPLEMENTED;
case mobj_subsector: case mobj_subsector:

View file

@ -737,7 +737,7 @@ static int NetArchive(lua_State *L)
{ {
int TABLESINDEX = lua_upvalueindex(1); int TABLESINDEX = lua_upvalueindex(1);
int i, n = lua_gettop(L); int i, n = lua_gettop(L);
for (i = 0; i < n; i++) for (i = 1; i <= n; i++)
ArchiveValue(TABLESINDEX, i); ArchiveValue(TABLESINDEX, i);
return n; return n;
} }
@ -884,7 +884,7 @@ static int NetUnArchive(lua_State *L)
{ {
int TABLESINDEX = lua_upvalueindex(1); int TABLESINDEX = lua_upvalueindex(1);
int i, n = lua_gettop(L); int i, n = lua_gettop(L);
for (i = 0; i < n; i++) for (i = 1; i <= n; i++)
UnArchiveValue(TABLESINDEX); UnArchiveValue(TABLESINDEX);
return n; 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) void LUA_Step(void)
{ {
if (!gL) if (!gL)
@ -972,7 +948,7 @@ void LUA_Archive(void)
} }
WRITEUINT32(save_p, UINT32_MAX); // end of mobjs marker, replaces mobjnum. 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(); ArchiveTables();
if (gL) if (gL)
@ -1003,7 +979,7 @@ void LUA_UnArchive(void)
UnArchiveExtVars(th); // apply variables UnArchiveExtVars(th); // apply variables
} while(mobjnum != UINT32_MAX); // repeat until end of mobjs marker. } 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(); UnArchiveTables();
if (gL) if (gL)

View file

@ -55,6 +55,7 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum); // lua_consolelib.c
void LUA_CVarChanged(const char *name); // lua_consolelib.c void LUA_CVarChanged(const char *name); // lua_consolelib.c
int Lua_optoption(lua_State *L, int narg, int Lua_optoption(lua_State *L, int narg,
const char *def, const char *const lst[]); const char *def, const char *const lst[]);
void LUAh_NetArchiveHook(lua_CFunction archFunc);
// Console wrapper // Console wrapper
void COM_Lua_f(void); 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 "."); #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 #endif

View file

@ -108,7 +108,7 @@ static UINT8 cheatf_devmode(void)
G_SetGameModified(false); G_SetGameModified(false);
for (i = 0; i < MAXUNLOCKABLES; i++) for (i = 0; i < MAXUNLOCKABLES; i++)
unlockables[i].unlocked = true; unlockables[i].unlocked = true;
devparm = TRUE; devparm = true;
cv_debug |= 0x8000; cv_debug |= 0x8000;
// Refresh secrets menu existing. // 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) static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean ceiling)
{ {
mapthing_t *mt; mapthing_t *mt = mapthings;
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
LUA_InvalidateMapthings(); LUA_InvalidateMapthings();
#endif #endif
mapthings = Z_Realloc(mapthings, ++nummapthings * sizeof (*mapthings), PU_LEVEL, NULL); 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 = (mapthings+nummapthings-1);
mt->type = type; mt->type = type;

View file

@ -49,7 +49,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"Streams come to an end\n" "Streams come to an end\n"
"where they can no longer fall.\n" "where they can no longer fall.\n"
"But if you went up...", 0}, "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" "This one's in plain sight.\n"
"Why haven't you claimed it?\n" "Why haven't you claimed it?\n"
"Surely you saw it.", 0}, "Surely you saw it.", 0},
@ -77,7 +77,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"Near the level's end,\n" "Near the level's end,\n"
"another bridge spans a lake.\n" "another bridge spans a lake.\n"
"What could be under...?", 0}, "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" "An ivied tunnel\n"
"has a corner that's sunlit.\n" "has a corner that's sunlit.\n"
"Go reach for the sky!", 0}, "Go reach for the sky!", 0},
@ -110,7 +110,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"Spinning through small gaps\n" "Spinning through small gaps\n"
"can slip you into a cave.\n" "can slip you into a cave.\n"
"In that cave's first stretch...", 0}, "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" "The slime lake is deep,\n"
"but reaching the floor takes height.\n" "but reaching the floor takes height.\n"
"Scream \"Geronimo!\"...", 0}, "Scream \"Geronimo!\"...", 0},
@ -138,7 +138,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"There is a hallway\n" "There is a hallway\n"
"that a button floods with slime.\n" "that a button floods with slime.\n"
"Go through it again!", 0}, "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" "Jumping on turtles\n"
"will send you springing skyward.\n" "will send you springing skyward.\n"
"Now, do that six times...", 0}, "Now, do that six times...", 0},
@ -171,7 +171,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"A caved-in hallway?\n" "A caved-in hallway?\n"
"The floor falls; the path goes down.\n" "The floor falls; the path goes down.\n"
"But those rocks looked weak...", 0}, "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" "The end is quite dry.\n"
"Some rocks dam the water in.\n" "Some rocks dam the water in.\n"
"Knuckles can fix that...", 0}, "Knuckles can fix that...", 0},
@ -199,7 +199,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"In the current maze\n" "In the current maze\n"
"hides a dark room of columns.\n" "hides a dark room of columns.\n"
"Find it, then look up.", 0}, "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" "That same dragon's eye\n"
"hides another secret room.\n" "hides another secret room.\n"
"There, solve its riddle.", 0}, "There, solve its riddle.", 0},
@ -232,7 +232,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"The final approach!\n" "The final approach!\n"
"A tower holds the emblem\n" "A tower holds the emblem\n"
"near a ring arrow.", 0}, "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" "The right starting path\n"
"hides this near a canopy,\n" "hides this near a canopy,\n"
"high, where two trees meet.", 0}, "high, where two trees meet.", 0},
@ -260,7 +260,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"Some of these bookshelves\n" "Some of these bookshelves\n"
"are not flush against the walls.\n" "are not flush against the walls.\n"
"Wonder why that is?", 0}, "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" "The ending's towers\n"
"are hiding a small alcove.\n" "are hiding a small alcove.\n"
"Check around outside.", 0}, "Check around outside.", 0},
@ -293,7 +293,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"Not far from the start,\n" "Not far from the start,\n"
"if you climb toward the sky,\n" "if you climb toward the sky,\n"
"the cliffs hide something.", 0}, "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" "Right by the exit,\n"
"an emblem lies on a cliff.\n" "an emblem lies on a cliff.\n"
"Ride ropes to reach it.", 0}, "Ride ropes to reach it.", 0},
@ -321,7 +321,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"Where once a bridge stood,\n" "Where once a bridge stood,\n"
"now magma falls from above.\n" "now magma falls from above.\n"
"The bridge dropped something...", 0}, "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" "A lake of magma\n"
"ebbs and flows unendingly.\n" "ebbs and flows unendingly.\n"
"Wait for its nadir.", 0}, "Wait for its nadir.", 0},
@ -349,7 +349,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"Don't jump too high here!\n" "Don't jump too high here!\n"
"No conveyor will catch you;\n" "No conveyor will catch you;\n"
"you'd fall to your death.", 0}, "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" "Conveyors! Magma!\n"
"What an intense room this is!\n" "What an intense room this is!\n"
"But, what brought you here?", 0}, "But, what brought you here?", 0},
@ -377,7 +377,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"Gears with missing teeth\n" "Gears with missing teeth\n"
"can hide a clever secret!\n" "can hide a clever secret!\n"
"Think Green Hill Zone boss.", 0}, "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" "Just before you reach\n"
"the defective cargo bay,\n" "the defective cargo bay,\n"
"fly under a bridge.", 0}, "fly under a bridge.", 0},
@ -398,7 +398,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"[PH] In the ceiling of the conveyor belt + laser hallway.", 0}, "[PH] In the ceiling of the conveyor belt + laser hallway.", 0},
{0,-13728,-13728, 1552, 24, 'D', SKINCOLOR_ORANGE, 0, {0,-13728,-13728, 1552, 24, 'D', SKINCOLOR_ORANGE, 0,
"[PH] On top of the platform with rows of spikes in reverse gravity.", 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}, "Follow the leader.", 0},
*/ */
@ -430,7 +430,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"The underground room\n" "The underground room\n"
"with platforms that fall and rise\n" "with platforms that fall and rise\n"
"only LOOKS empty...", 0}, "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" "This one's straightforward.\n"
"What comes to mind when I say:\n" "What comes to mind when I say:\n"
"\"WELCOME TO WARP ZONE!\"?", 0}, "\"WELCOME TO WARP ZONE!\"?", 0},
@ -458,7 +458,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"Much like the last one,\n" "Much like the last one,\n"
"you need to find some switches.\n" "you need to find some switches.\n"
"Only two, this time.", 0}, "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" "The inner sanctum!\n"
"Teleport to its switches;\n" "Teleport to its switches;\n"
"then, check near the goal.", 0}, "then, check near the goal.", 0},
@ -486,7 +486,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"A room of currents;\n" "A room of currents;\n"
"most of them are marked by spikes.\n" "most of them are marked by spikes.\n"
"This one? A corner.", 0}, "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" "The only way to hit\n"
"all those gems at once is with\n" "all those gems at once is with\n"
"a radial blast.", 0}, "a radial blast.", 0},
@ -498,63 +498,63 @@ emblem_t emblemlocations[MAXEMBLEMS] =
// FLORAL FIELD // 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_NGRADE, 0,0,0, 50, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0},
{ET_NTIME, 0,0,0, 50, 'T', SKINCOLOR_GREY, 40*TICRATE, "", 0}, {ET_NTIME, 0,0,0, 50, 'T', SKINCOLOR_GREY, 40*TICRATE, "", 0},
// TOXIC PLATEAU // 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_NGRADE, 0,0,0, 51, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0},
{ET_NTIME, 0,0,0, 51, 'T', SKINCOLOR_GREY, 50*TICRATE, "", 0}, {ET_NTIME, 0,0,0, 51, 'T', SKINCOLOR_GREY, 50*TICRATE, "", 0},
// FLOODED COVE // 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_NGRADE, 0,0,0, 52, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0},
{ET_NTIME, 0,0,0, 52, 'T', SKINCOLOR_GREY, 90*TICRATE, "", 0}, {ET_NTIME, 0,0,0, 52, 'T', SKINCOLOR_GREY, 90*TICRATE, "", 0},
// CAVERN FORTRESS // 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_NGRADE, 0,0,0, 53, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0},
{ET_NTIME, 0,0,0, 53, 'T', SKINCOLOR_GREY, 75*TICRATE, "", 0}, {ET_NTIME, 0,0,0, 53, 'T', SKINCOLOR_GREY, 75*TICRATE, "", 0},
// DUSTY WASTELAND // 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_NGRADE, 0,0,0, 54, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0},
{ET_NTIME, 0,0,0, 54, 'T', SKINCOLOR_GREY, 65*TICRATE, "", 0}, {ET_NTIME, 0,0,0, 54, 'T', SKINCOLOR_GREY, 65*TICRATE, "", 0},
// MAGMA CAVES // 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_NGRADE, 0,0,0, 55, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0},
{ET_NTIME, 0,0,0, 55, 'T', SKINCOLOR_GREY, 80*TICRATE, "", 0}, {ET_NTIME, 0,0,0, 55, 'T', SKINCOLOR_GREY, 80*TICRATE, "", 0},
// EGG SATELLITE // 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_NGRADE, 0,0,0, 56, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0},
{ET_NTIME, 0,0,0, 56, 'T', SKINCOLOR_GREY, 120*TICRATE, "", 0}, {ET_NTIME, 0,0,0, 56, 'T', SKINCOLOR_GREY, 120*TICRATE, "", 0},
// BLACK HOLE // 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_NGRADE, 0,0,0, 57, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0},
{ET_NTIME, 0,0,0, 57, 'T', SKINCOLOR_GREY, 150*TICRATE, "", 0}, {ET_NTIME, 0,0,0, 57, 'T', SKINCOLOR_GREY, 150*TICRATE, "", 0},
// SPRING HILL // 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_NGRADE, 0,0,0, 58, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0},
{ET_NTIME, 0,0,0, 58, 'T', SKINCOLOR_GREY, 60*TICRATE, "", 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}, {"Game Complete", "Complete 1P Mode", 10, 'X', SKINCOLOR_BLUE, 0},
{"All Emeralds", "Complete 1P Mode with all Emeralds", 11, 'V', SKINCOLOR_GREY, 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}, {"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}, {"NiGHTS Mastery", "Show your mastery of NiGHTS!", 22, 'W', SKINCOLOR_TEAL, 0},
}; };

View file

@ -119,8 +119,6 @@ fixed_t FixedHypot(fixed_t x, fixed_t y)
return FixedMul(ax, yx1); // |x|*((1 + (x/y)^2)^1/2) 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) vector2_t *FV2_Load(vector2_t *vec, fixed_t x, fixed_t y)
{ {
vec->x = x; vec->x = x;
@ -863,8 +861,6 @@ void FM_Scale(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z)
#undef M #undef M
} }
#endif
#ifdef M_TESTCASE #ifdef M_TESTCASE
//#define MULDIV_TEST //#define MULDIV_TEST
#define SQRT_TEST #define SQRT_TEST

View file

@ -357,8 +357,6 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedRound(fixed_t x)
return INT32_MAX; return INT32_MAX;
} }
#ifdef NEED_FIXED_VECTOR
typedef struct typedef struct
{ {
fixed_t x; 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_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); void FM_Scale(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z);
#endif // defined NEED_FIXED_VECTOR
#endif //m_fixed.h #endif //m_fixed.h

View file

@ -2203,6 +2203,7 @@ boolean M_Responder(event_t *ev)
if (modeattacking) if (modeattacking)
return true; return true;
M_StartControlPanel(); M_StartControlPanel();
M_Options(0);
currentMenu = &OP_SoundOptionsDef; currentMenu = &OP_SoundOptionsDef;
itemOn = 0; itemOn = 0;
return true; return true;
@ -2212,6 +2213,7 @@ boolean M_Responder(event_t *ev)
if (modeattacking) if (modeattacking)
return true; return true;
M_StartControlPanel(); M_StartControlPanel();
M_Options(0);
M_VideoModeMenu(0); M_VideoModeMenu(0);
return true; return true;
#endif #endif
@ -2223,6 +2225,7 @@ boolean M_Responder(event_t *ev)
if (modeattacking) if (modeattacking)
return true; return true;
M_StartControlPanel(); M_StartControlPanel();
M_Options(0);
M_SetupNextMenu(&OP_MainDef); M_SetupNextMenu(&OP_MainDef);
return true; return true;
@ -2460,13 +2463,16 @@ void M_Drawer(void)
V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, customversionstring); V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, customversionstring);
} }
else 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)); 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 #endif
} }
} }
}
// //
// M_StartControlPanel // M_StartControlPanel
@ -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) void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines)
{ {
// Solid color textbox. // 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); //V_DrawFill(x+8, y+8, width*8, boxlines*8, 31);
/* /*
patch_t *p; patch_t *p;
@ -4745,7 +4751,7 @@ static void M_SetupChoosePlayer(INT32 choice)
if (Playing() == false) if (Playing() == false)
{ {
S_StopMusic(); S_StopMusic();
S_ChangeMusic(mus_chrsel, true); S_ChangeMusicInternal("chrsel", true);
} }
SP_PlayerDef.prevMenu = currentMenu; SP_PlayerDef.prevMenu = currentMenu;
@ -5196,7 +5202,7 @@ void M_DrawTimeAttackMenu(void)
lumpnum_t lumpnum; lumpnum_t lumpnum;
char beststr[40]; 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)); V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE));
@ -5359,7 +5365,7 @@ static void M_TimeAttack(INT32 choice)
itemOn = tastart; // "Start" is selected. itemOn = tastart; // "Start" is selected.
G_SetGamestate(GS_TIMEATTACK); G_SetGamestate(GS_TIMEATTACK);
S_ChangeMusic(mus_racent, true); S_ChangeMusicInternal("racent", true);
} }
// Drawing function for Nights Attack // Drawing function for Nights Attack
@ -5369,7 +5375,7 @@ void M_DrawNightsAttackMenu(void)
lumpnum_t lumpnum; lumpnum_t lumpnum;
char beststr[40]; 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)); V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE));
@ -5492,7 +5498,7 @@ static void M_NightsAttack(INT32 choice)
itemOn = nastart; // "Start" is selected. itemOn = nastart; // "Start" is selected.
G_SetGamestate(GS_TIMEATTACK); G_SetGamestate(GS_TIMEATTACK);
S_ChangeMusic(mus_racent, true); S_ChangeMusicInternal("racent", true);
} }
// Player has selected the "START" from the nights attack screen // Player has selected the "START" from the nights attack screen
@ -5726,7 +5732,7 @@ static void M_ModeAttackEndGame(INT32 choice)
itemOn = currentMenu->lastOn; itemOn = currentMenu->lastOn;
G_SetGamestate(GS_TIMEATTACK); G_SetGamestate(GS_TIMEATTACK);
modeattacking = ATTACKING_NONE; modeattacking = ATTACKING_NONE;
S_ChangeMusic(mus_racent, true); S_ChangeMusicInternal("racent", true);
// Update replay availability. // Update replay availability.
CV_AddValue(&cv_nextmap, 1); CV_AddValue(&cv_nextmap, 1);
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++) 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; MP_RoomMenu[i+1].text = room_list[i].name;
roomIds[i] = room_list[i].id; roomIds[i] = room_list[i].id;
@ -6932,7 +6938,7 @@ static void M_ToggleDigital(void)
if (nodigimusic) return; if (nodigimusic) return;
S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
S_StopMusic(); S_StopMusic();
S_ChangeMusic(mus_lclear, false); S_ChangeMusicInternal("lclear", false);
M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING); M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING);
} }
else else
@ -6959,7 +6965,7 @@ static void M_ToggleMIDI(void)
I_InitMIDIMusic(); I_InitMIDIMusic();
if (nomidimusic) return; if (nomidimusic) return;
S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); 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); M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING);
} }
else else

View file

@ -677,7 +677,7 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png
else else
snprintf(maptext, 8, "Unknown"); 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", snprintf(lvlttltext, 48, "%s%s%s",
mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->lvlttl,
(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE", (mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE",
@ -1800,16 +1800,14 @@ UINT8 M_HighestBit(UINT32 num)
const char *GetRevisionString(void) const char *GetRevisionString(void)
{ {
INT32 vinfo; static char rev[9] = {0};
static char rev[8] = {0};
if (rev[0]) if (rev[0])
return rev; return rev;
vinfo = atoi(&comprevision[1]); if (comprevision[0] == 'r')
if (vinfo) strncpy(rev, comprevision, 7);
snprintf(rev, 7, "r%d", vinfo);
else else
strcpy(rev, "rNULL"); snprintf(rev, 7, "r%s", comprevision);
rev[7] = '\0'; rev[7] = '\0';
return rev; return rev;

View file

@ -3063,12 +3063,8 @@ void A_Invincibility(mobj_t *actor)
{ {
S_StopMusic(); S_StopMusic();
if (mariomode) if (mariomode)
{
S_ChangeMusic(mus_minvnc, false);
G_GhostAddColor(GHC_INVINCIBLE); G_GhostAddColor(GHC_INVINCIBLE);
} S_ChangeMusicInternal((mariomode) ? "minvnc" : "invinc", false);
else
S_ChangeMusic(mus_invinc, false);
} }
} }
@ -3104,7 +3100,7 @@ void A_SuperSneakers(mobj_t *actor)
else else
{ {
S_StopMusic(); 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); 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->floorz = players[i].mo->subsector->sector->floorheight;
players[i].mo->ceilingz = players[i].mo->subsector->sector->ceilingheight; players[i].mo->ceilingz = players[i].mo->subsector->sector->ceilingheight;
#endif
P_CheckPosition(players[i].mo, players[i].mo->x, players[i].mo->y); 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 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; pogo->target = actor;
} }
@ -7592,48 +7593,35 @@ void A_SetTargetsTarget(mobj_t *actor)
{ {
INT32 locvar1 = var1; INT32 locvar1 = var1;
INT32 locvar2 = var2; INT32 locvar2 = var2;
mobj_t *targetedmobj = NULL; mobj_t *oldtarg = NULL, *newtarg = NULL;
thinker_t *th;
mobj_t *mo2;
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
if (LUA_CallAction("A_SetTargetsTarget", actor)) if (LUA_CallAction("A_SetTargetsTarget", actor))
return; return;
#endif #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; return;
if ((!locvar1 && !locvar2 && (!actor->target->target)) // actor's target's target!
|| (!locvar1 && locvar2 && (!actor->target->tracer)) if (locvar2) // or tracer
|| (locvar1 && !locvar2 && (!actor->tracer->target)) newtarg = oldtarg->tracer;
|| (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);
else 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 // Function: A_SetObjectFlags

View file

@ -1174,12 +1174,15 @@ void T_SpikeSector(levelspecthink_t *spikes)
if (affectsec == spikes->sector) // Applied to an actual sector 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 (affectsec->flags & SF_FLIPSPECIAL_FLOOR)
{ {
if (!(thing->eflags & MFE_VERTICALFLIP) && thing->momz > 0) if (!(thing->eflags & MFE_VERTICALFLIP) && thing->momz > 0)
continue; continue;
if (thing->z == affectsec->floorheight) if (thing->z == affectfloor)
dothepain = true; dothepain = true;
} }
@ -1188,18 +1191,20 @@ void T_SpikeSector(levelspecthink_t *spikes)
if ((thing->eflags & MFE_VERTICALFLIP) && thing->momz < 0) if ((thing->eflags & MFE_VERTICALFLIP) && thing->momz < 0)
continue; continue;
if (thing->z + thing->height == affectsec->ceilingheight) if (thing->z + thing->height == affectceil)
dothepain = true; dothepain = true;
} }
} }
else 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 (affectsec->flags & SF_FLIPSPECIAL_FLOOR)
{ {
if (!(thing->eflags & MFE_VERTICALFLIP) && thing->momz > 0) if (!(thing->eflags & MFE_VERTICALFLIP) && thing->momz > 0)
continue; continue;
if (thing->z == affectsec->ceilingheight) if (thing->z == affectceil)
dothepain = true; dothepain = true;
} }
@ -1208,7 +1213,7 @@ void T_SpikeSector(levelspecthink_t *spikes)
if ((thing->eflags & MFE_VERTICALFLIP) && thing->momz < 0) if ((thing->eflags & MFE_VERTICALFLIP) && thing->momz < 0)
continue; continue;
if (thing->z + thing->height == affectsec->floorheight) if (thing->z + thing->height == affectfloor)
dothepain = true; dothepain = true;
} }
} }
@ -2085,6 +2090,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
boolean FOFsector = false; boolean FOFsector = false;
boolean inAndOut = false; boolean inAndOut = false;
boolean floortouch = false; boolean floortouch = false;
fixed_t bottomheight, topheight;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
{ {
@ -2149,10 +2155,13 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
if (players[j].mo->subsector->sector != targetsec) if (players[j].mo->subsector->sector != targetsec)
continue; 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; continue;
if (players[j].mo->z + players[j].mo->height < sec->floorheight) if (players[j].mo->z + players[j].mo->height < bottomheight)
continue; continue;
if (floortouch == true && P_IsObjectOnGroundIn(players[j].mo, targetsec)) 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)) if (raise->vars[1] && !(thing->player->pflags & PF_STARTDASH))
continue; continue;
if (!(thing->z == raise->sector->ceilingheight)) if (!(thing->z == P_GetSpecialTopZ(thing, raise->sector, sector)))
continue; continue;
playeronme = true; playeronme = true;

View file

@ -472,7 +472,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if ((maptol & TOL_NIGHTS) && special->type != MT_FLINGCOIN) if ((maptol & TOL_NIGHTS) && special->type != MT_FLINGCOIN)
P_DoNightsScore(player); P_DoNightsScore(player);
break; break;
#ifdef BLUE_SPHERES
case MT_BLUEBALL: case MT_BLUEBALL:
if (!(P_CanPickupItem(player, false))) if (!(P_CanPickupItem(player, false)))
return; return;
@ -489,7 +488,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (maptol & TOL_NIGHTS) if (maptol & TOL_NIGHTS)
P_DoNightsScore(player); P_DoNightsScore(player);
break; break;
#endif
case MT_AUTOPICKUP: case MT_AUTOPICKUP:
case MT_BOUNCEPICKUP: case MT_BOUNCEPICKUP:
case MT_SCATTERPICKUP: 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 if (!(mo2->type == MT_NIGHTSWING || mo2->type == MT_RING || mo2->type == MT_COIN
#ifdef BLUE_SPHERES || mo2->type == MT_BLUEBALL))
|| mo2->type == MT_BLUEBALL
#endif
))
continue; continue;
// Yay! The thing's in reach! Pull it in! // 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 else
player->pflags |= PF_ITEMHANG; player->pflags |= PF_ITEMHANG;
// Can't jump first frame
player->pflags |= PF_JUMPSTASIS;
return; return;
case MT_BIGMINE: case MT_BIGMINE:
case MT_BIGAIRMINE: 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")); 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. /** 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 * Verify that the value of ::cv_pointlimit is greater than zero before
* calling this function. * calling this function.
* *
* \sa cv_pointlimit, P_UpdateSpecials * \sa cv_pointlimit, P_CheckTimeLimit, P_UpdateSpecials
*/ */
void P_CheckPointLimit(void) 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]) if (P_IsLocalPlayer(target->player) && target->player == &players[consoleplayer])
{ {
S_StopMusic(); // Stop the Music! Tails 03-14-2000 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. // allow them to try again, rather than sitting the whole thing out.
if (leveltime >= hidetime * TICRATE) 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; target->player->pflags |= PF_TAGIT;
CONS_Printf(M_GetText("%s is now IT!\n"), player_names[target->player-players]); // Tell everyone who is it! 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) && 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_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);
} }
} }
} }

View file

@ -213,11 +213,29 @@ void P_RemoveSavegameMobj(mobj_t *th);
boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state); boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state);
boolean P_SetMobjState(mobj_t *mobj, statenum_t state); boolean P_SetMobjState(mobj_t *mobj, statenum_t state);
void P_RunShields(void); void P_RunShields(void);
void P_RunOverlays(void);
void P_MobjThinker(mobj_t *mobj); void P_MobjThinker(mobj_t *mobj);
boolean P_RailThinker(mobj_t *mobj); boolean P_RailThinker(mobj_t *mobj);
void P_PushableThinker(mobj_t *mobj); void P_PushableThinker(mobj_t *mobj);
void P_SceneryThinker(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_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover);
boolean P_CheckDeathPitCollide(mobj_t *mo); boolean P_CheckDeathPitCollide(mobj_t *mo);
boolean P_CheckSolidLava(mobj_t *mo, ffloor_t *rover); boolean P_CheckSolidLava(mobj_t *mo, ffloor_t *rover);
@ -279,6 +297,11 @@ extern fixed_t tmfloorz;
extern fixed_t tmceilingz; extern fixed_t tmceilingz;
extern mobj_t *tmfloorthing, *tmhitthing, *tmthing; extern mobj_t *tmfloorthing, *tmhitthing, *tmthing;
extern camera_t *mapcampointer; extern camera_t *mapcampointer;
extern fixed_t tmx;
extern fixed_t tmy;
#ifdef ESLOPE
extern pslope_t *tmfloorslope, *tmceilingslope;
#endif
/* cphipps 2004/08/30 */ /* cphipps 2004/08/30 */
extern void P_MapStart(void); 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); fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height);
boolean PIT_PushableMoved(mobj_t *thing); 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 // 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_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck);
void P_PlayerFlagBurst(player_t *player, boolean toss); void P_PlayerFlagBurst(player_t *player, boolean toss);
void P_CheckTimeLimit(void);
void P_CheckPointLimit(void); void P_CheckPointLimit(void);
void P_CheckSurvivors(void); void P_CheckSurvivors(void);
boolean P_CheckRacers(void); boolean P_CheckRacers(void);

View file

@ -27,6 +27,10 @@
#include "r_splats.h" #include "r_splats.h"
#ifdef ESLOPE
#include "p_slopes.h"
#endif
#include "z_zone.h" #include "z_zone.h"
#include "lua_hook.h" #include "lua_hook.h"
@ -34,8 +38,8 @@
fixed_t tmbbox[4]; fixed_t tmbbox[4];
mobj_t *tmthing; mobj_t *tmthing;
static INT32 tmflags; static INT32 tmflags;
static fixed_t tmx; fixed_t tmx;
static fixed_t tmy; fixed_t tmy;
static precipmobj_t *tmprecipthing; static precipmobj_t *tmprecipthing;
static fixed_t preciptmbbox[4]; static fixed_t preciptmbbox[4];
@ -48,6 +52,9 @@ fixed_t tmfloorz, tmceilingz;
static fixed_t tmdropoffz, tmdrpoffceilz; // drop-off floor/ceiling heights 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 *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) 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, // keep track of the line that lowers the ceiling,
// so missiles don't explode against sky hack walls // 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 // MOVEMENT ITERATOR FUNCTIONS
// ========================================================================= // =========================================================================
void P_DoSpring(mobj_t *spring, mobj_t *object) boolean P_DoSpring(mobj_t *spring, mobj_t *object)
{ {
INT32 pflags; INT32 pflags;
fixed_t offx, offy; fixed_t offx, offy;
@ -110,16 +117,16 @@ void P_DoSpring(mobj_t *spring, mobj_t *object)
fixed_t horizspeed = spring->info->damage; fixed_t horizspeed = spring->info->damage;
if (object->eflags & MFE_SPRUNG) // Object was already sprung this tic if (object->eflags & MFE_SPRUNG) // Object was already sprung this tic
return; return false;
// Spectators don't trigger springs. // Spectators don't trigger springs.
if (object->player && object->player->spectator) if (object->player && object->player->spectator)
return; return false;
if (object->player && (object->player->pflags & PF_NIGHTSMODE)) if (object->player && (object->player->pflags & PF_NIGHTSMODE))
{ {
/*Someone want to make these work like bumpers?*/ /*Someone want to make these work like bumpers?*/
return; return false;
} }
object->eflags |= MFE_SPRUNG; // apply this flag asap! 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); P_ResetPlayer(object->player);
if (P_MobjFlip(object)*vertispeed > 0) 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) else if (P_MobjFlip(object)*vertispeed < 0)
P_SetPlayerMobjState(object, S_PLAY_FALL); P_SetPlayerMobjState(object, S_PLAY_FALL);
else // horizontal spring else // horizontal spring
@ -206,9 +213,10 @@ void P_DoSpring(mobj_t *spring, mobj_t *object)
if (spring->info->painchance) if (spring->info->painchance)
{ {
object->player->pflags |= PF_JUMPED; 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) 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) static boolean PIT_CheckThing(mobj_t *thing)
{ {
fixed_t blockdist; fixed_t blockdist;
boolean iwassprung = false;
// don't clip against self // don't clip against self
if (thing == tmthing) if (thing == tmthing)
@ -494,7 +503,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true; // overhead return true; // overhead
if (thing->z + thing->height < tmthing->z) if (thing->z + thing->height < tmthing->z)
return true; // underneath return true; // underneath
if (tmthing->player && tmthing->flags & MF_SHOOTABLE) if (tmthing->player && tmthing->flags & MF_SHOOTABLE && thing->health > 0)
{ {
UINT8 damagetype = 0; UINT8 damagetype = 0;
if (thing->flags & MF_FIRE) // BURN! if (thing->flags & MF_FIRE) // BURN!
@ -510,7 +519,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true; // overhead return true; // overhead
if (tmthing->z + tmthing->height < thing->z) if (tmthing->z + tmthing->height < thing->z)
return true; // underneath return true; // underneath
if (thing->player && thing->flags & MF_SHOOTABLE) if (thing->player && thing->flags & MF_SHOOTABLE && tmthing->health > 0)
{ {
UINT8 damagetype = 0; UINT8 damagetype = 0;
if (tmthing->flags & MF_FIRE) // BURN! if (tmthing->flags & MF_FIRE) // BURN!
@ -829,7 +838,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
{ {
if ( thing->z <= tmthing->z + tmthing->height if ( thing->z <= tmthing->z + tmthing->height
&& tmthing->z <= thing->z + thing->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 if ( thing->z <= tmthing->z + tmthing->height
&& tmthing->z <= thing->z + thing->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? // Are you touching the side of the object you're interacting with?
else if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height 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))
if (thing->flags & MF_SPRING && (tmthing->player || tmthing->flags & MF_PUSHABLE)); {
else 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, // 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 // 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))) && !((thing->type == MT_REDRINGBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_BLUERINGBOX && tmthing->player->ctfteam != 2)))
; ;
// z checking at last // z checking at last
@ -963,6 +974,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->z + thing->height > tmfloorz) if (thing->z + thing->height > tmfloorz)
{ {
tmfloorz = thing->z + thing->height; tmfloorz = thing->z + thing->height;
#ifdef ESLOPE
tmfloorslope = NULL;
#endif
} }
return true; 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) else if (topz < tmceilingz && tmthing->z+tmthing->height <= thing->z+thing->height)
{ {
tmceilingz = topz; tmceilingz = topz;
#ifdef ESLOPE
tmceilingslope = NULL;
#endif
tmfloorthing = thing; // thing we may stand on tmfloorthing = thing; // thing we may stand on
} }
} }
@ -994,6 +1011,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->z < tmceilingz) if (thing->z < tmceilingz)
{ {
tmceilingz = thing->z; tmceilingz = thing->z;
#ifdef ESLOPE
tmceilingslope = NULL;
#endif
} }
return true; return true;
} }
@ -1011,6 +1031,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
else if (topz > tmfloorz && tmthing->z >= thing->z) else if (topz > tmfloorz && tmthing->z >= thing->z)
{ {
tmfloorz = topz; tmfloorz = topz;
#ifdef ESLOPE
tmfloorslope = NULL;
#endif
tmfloorthing = thing; // thing we may stand on tmfloorthing = thing; // thing we may stand on
} }
} }
@ -1133,11 +1156,13 @@ static boolean PIT_CheckLine(line_t *ld)
{ {
tmceilingz = opentop; tmceilingz = opentop;
ceilingline = ld; ceilingline = ld;
tmceilingslope = opentopslope;
} }
if (openbottom > tmfloorz) if (openbottom > tmfloorz)
{ {
tmfloorz = openbottom; tmfloorz = openbottom;
tmfloorslope = openbottomslope;
} }
if (highceiling > tmdrpoffceilz) if (highceiling > tmdrpoffceilz)
@ -1214,8 +1239,12 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
// that contains the point. // that contains the point.
// Any contacted lines the step closer together // Any contacted lines the step closer together
// will adjust them. // will adjust them.
tmfloorz = tmdropoffz = newsubsec->sector->floorheight; tmfloorz = tmdropoffz = P_GetFloorZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->floorheight;
tmceilingz = tmdrpoffceilz = newsubsec->sector->ceilingheight; 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. // Check list of fake floors and see if tmfloorz/tmceilingz need to be altered.
if (newsubsec->sector->ffloors) 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) for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
{ {
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS)) if (!(rover->flags & FF_EXISTS))
continue; 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 (rover->flags & FF_GOOWATER && !(thing->flags & MF_NOGRAVITY))
{ {
// If you're inside goowater and slowing down // If you're inside goowater and slowing down
fixed_t sinklevel = FixedMul(thing->info->height/6, thing->scale); fixed_t sinklevel = FixedMul(thing->info->height/6, thing->scale);
fixed_t minspeed = FixedMul(thing->info->height/9, 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) && abs(thing->momz) < minspeed)
{ {
// Oh no! The object is stick in between the surface of the goo and sinklevel! help them out! // 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 >= 0 && thing->momz < (minspeed>>2))
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 <= 0 && thing->momz > -(minspeed>>2))
thing->momz -= minspeed>>2; thing->momz -= minspeed>>2;
// Land on the top or the bottom, depending on gravity flip. // 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) if (tmfloorz < topheight - sinklevel) {
tmfloorz = *rover->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) if (tmceilingz > bottomheight + sinklevel) {
tmceilingz = *rover->bottomheight + sinklevel; tmceilingz = bottomheight + sinklevel;
#ifdef ESLOPE
tmceilingslope = *rover->b_slope;
#endif
}
} }
} }
continue; continue;
@ -1271,30 +1313,40 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
if (rover->flags & FF_QUICKSAND) 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; tmfloorz = thing->z;
#ifdef ESLOPE
tmfloorslope = NULL;
#endif
}
} }
// Quicksand blocks never change heights otherwise. // Quicksand blocks never change heights otherwise.
continue; continue;
} }
delta1 = thing->z - (*rover->bottomheight delta1 = thing->z - (bottomheight
+ ((*rover->topheight - *rover->bottomheight)/2)); + ((topheight - bottomheight)/2));
delta2 = thingtop - (*rover->bottomheight delta2 = thingtop - (bottomheight
+ ((*rover->topheight - *rover->bottomheight)/2)); + ((topheight - bottomheight)/2));
if (*rover->topheight > tmfloorz && abs(delta1) < abs(delta2) if (topheight > tmfloorz && abs(delta1) < abs(delta2)
&& !(rover->flags & FF_REVERSEPLATFORM)) && !(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) && !(rover->flags & FF_PLATFORM)
&& !(thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE))) && !(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)); delta1 = thing->z - (polybottom + ((polytop - polybottom)/2));
delta2 = thingtop - (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; 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; tmceilingz = tmdrpoffceilz = polybottom;
#ifdef ESLOPE
tmceilingslope = NULL;
#endif
}
} }
plink = (polymaplink_t *)(plink->link.next); 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. // that contains the point.
// Any contacted lines the step closer together // Any contacted lines the step closer together
// will adjust them. // will adjust them.
tmfloorz = tmdropoffz = newsubsec->sector->floorheight; tmfloorz = tmdropoffz = P_CameraGetFloorZ(thiscam, newsubsec->sector, x, y, NULL);
tmceilingz = tmdrpoffceilz = newsubsec->sector->ceilingheight;
tmceilingz = P_CameraGetCeilingZ(thiscam, newsubsec->sector, x, y, NULL);
// Cameras use the heightsec's heights rather then the actual sector heights. // 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? // 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) 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) if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
continue; continue;
delta1 = thiscam->z - (*rover->bottomheight topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, x, y, NULL);
+ ((*rover->topheight - *rover->bottomheight)/2)); bottomheight = P_CameraGetFOFBottomZ(thiscam, newsubsec->sector, rover, x, y, NULL);
delta2 = thingtop - (*rover->bottomheight
+ ((*rover->topheight - *rover->bottomheight)/2)); delta1 = thiscam->z - (bottomheight
if (*rover->topheight > tmfloorz && abs(delta1) < abs(delta2)) + ((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 else
{ {
tmfloorz = thiscam->subsector->sector->floorheight; tmfloorz = P_CameraGetFloorZ(thiscam, thiscam->subsector->sector, x, y, NULL);
tmceilingz = thiscam->subsector->sector->ceilingheight; tmceilingz = P_CameraGetCeilingZ(thiscam, thiscam->subsector->sector, x, y, NULL);
} }
// the move is ok, // the move is ok,
@ -1775,6 +1840,10 @@ boolean PIT_PushableMoved(mobj_t *thing)
mobj_t *oldthing = tmthing; mobj_t *oldthing = tmthing;
line_t *oldceilline = ceilingline; line_t *oldceilline = ceilingline;
line_t *oldblockline = blockingline; line_t *oldblockline = blockingline;
#ifdef ESLOPE
pslope_t *oldfslope = tmfloorslope;
pslope_t *oldcslope = tmceilingslope;
#endif
// Move the player // Move the player
P_TryMove(thing, thing->x+stand->momx, thing->y+stand->momy, true); 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); P_SetTarget(&tmthing, oldthing);
ceilingline = oldceilline; ceilingline = oldceilline;
blockingline = oldblockline; blockingline = oldblockline;
#ifdef ESLOPE
tmfloorslope = oldfslope;
tmceilingslope = oldcslope;
#endif
thing->momz = stand->momz; thing->momz = stand->momz;
} }
else 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 tryy = thing->y;
fixed_t radius = thing->radius; fixed_t radius = thing->radius;
fixed_t thingtop = thing->z + thing->height; fixed_t thingtop = thing->z + thing->height;
#ifdef ESLOPE
fixed_t startingonground = P_IsObjectOnGround(thing);
#endif
floatok = false; floatok = false;
if (radius < MAXRADIUS/2) 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, // Don't 'step up' while springing,
// Only step up "if needed". // 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)) && P_MobjFlip(thing)*thing->momz > FixedMul(FRACUNIT, thing->scale))
maxstep = 0; 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) 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; thing->eflags |= MFE_JUSTSTEPPEDDOWN;
} }
} }
else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep) 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; 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->floorz = tmfloorz;
thing->ceilingz = tmceilingz; 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->x = x;
thing->y = y; 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) boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y)
{ {
fixed_t tryx, tryy; fixed_t tryx, tryy;
tryx = thing->x; tryx = thing->x;
tryy = thing->y; tryy = thing->y;
do { do {
@ -2310,15 +2416,25 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle)
{ {
fixed_t platx, platy; fixed_t platx, platy;
subsector_t *glidesector; subsector_t *glidesector;
fixed_t floorz, ceilingz;
platx = P_ReturnThrustX(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale)); 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)); 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); 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) if (glidesector->sector != player->mo->subsector->sector)
{ {
boolean floorclimb = false; boolean floorclimb = false;
fixed_t topheight, bottomheight;
if (glidesector->sector->ffloors) 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)) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER))
continue; 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; floorclimb = true;
if (player->mo->eflags & MFE_VERTICALFLIP) 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; floorclimb = true;
} }
if (*rover->topheight < player->mo->z) // Waaaay below the ledge. if (topheight < player->mo->z) // Waaaay below the ledge.
{ {
floorclimb = false; 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; floorclimb = false;
} }
} }
else 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; 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; 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; floorclimb = false;
} }
@ -2368,30 +2494,30 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle)
if (player->mo->eflags & MFE_VERTICALFLIP) if (player->mo->eflags & MFE_VERTICALFLIP)
{ {
if ((glidesector->sector->floorheight <= player->mo->z + player->mo->height) if ((floorz <= player->mo->z + player->mo->height)
&& ((player->mo->z + player->mo->height - player->mo->momz) <= glidesector->sector->floorheight)) && ((player->mo->z + player->mo->height - player->mo->momz) <= floorz))
floorclimb = true; floorclimb = true;
if ((glidesector->sector->floorheight > player->mo->z) if ((floorz > player->mo->z)
&& glidesector->sector->floorpic == skyflatnum) && glidesector->sector->floorpic == skyflatnum)
return false; return false;
if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > glidesector->sector->ceilingheight) if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > ceilingz)
|| (player->mo->z + player->mo->height <= glidesector->sector->floorheight)) || (player->mo->z + player->mo->height <= floorz))
floorclimb = true; floorclimb = true;
} }
else else
{ {
if ((glidesector->sector->ceilingheight >= player->mo->z) if ((ceilingz >= player->mo->z)
&& ((player->mo->z - player->mo->momz) >= glidesector->sector->ceilingheight)) && ((player->mo->z - player->mo->momz) >= ceilingz))
floorclimb = true; floorclimb = true;
if ((glidesector->sector->ceilingheight < player->mo->z+player->mo->height) if ((ceilingz < player->mo->z+player->mo->height)
&& glidesector->sector->ceilingpic == skyflatnum) && glidesector->sector->ceilingpic == skyflatnum)
return false; return false;
if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < glidesector->sector->floorheight) if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < ceilingz)
|| (player->mo->z >= glidesector->sector->ceilingheight)) || (player->mo->z >= ceilingz))
floorclimb = true; floorclimb = true;
} }
@ -2463,6 +2589,7 @@ isblocking:
line_t *checkline = li; line_t *checkline = li;
sector_t *checksector; sector_t *checksector;
ffloor_t *rover; ffloor_t *rover;
fixed_t topheight, bottomheight;
boolean fofline = false; boolean fofline = false;
INT32 side = P_PointOnLineSide(slidemo->x, slidemo->y, li); 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)) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
continue; 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; continue;
if (*rover->bottomheight > slidemo->z + slidemo->height) if (bottomheight > slidemo->z + slidemo->height)
continue; 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) if (rover->master->flags & ML_TFERLINE)
{ {
size_t linenum = li-checksector->lines[0]; size_t linenum = li-checksector->lines[0];
@ -2509,8 +2646,8 @@ isblocking:
climbangle += (ANGLE_90 * (whichside ? -1 : 1)); climbangle += (ANGLE_90 * (whichside ? -1 : 1));
if (((!slidemo->player->climbing && abs(slidemo->angle - ANGLE_90 - climbline) < ANGLE_45) if (((!slidemo->player->climbing && abs((slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45)
|| (slidemo->player->climbing == 1 && abs(slidemo->angle - climbline) < ANGLE_135)) || (slidemo->player->climbing == 1 && abs((slidemo->angle - climbline)) < ANGLE_135))
&& P_IsClimbingValid(slidemo->player, climbangle)) && P_IsClimbingValid(slidemo->player, climbangle))
{ {
slidemo->angle = 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)) if (thing->subsector->sector->ffloors && (realcrush || thing->flags & MF_PUSHABLE))
{ {
ffloor_t *rover; ffloor_t *rover;
fixed_t topheight, bottomheight;
fixed_t delta1, delta2; fixed_t delta1, delta2;
INT32 thingtop = thing->z + thing->height; 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)) || ((rover->flags & FF_BLOCKOTHERS) && !thing->player)) || !(rover->flags & FF_EXISTS))
continue; continue;
delta1 = thing->z - (*rover->bottomheight + *rover->topheight)/2; topheight = *rover->topheight;
delta2 = thingtop - (*rover->bottomheight + *rover->topheight)/2; bottomheight = *rover->bottomheight;
if (*rover->bottomheight <= thing->ceilingz && abs(delta1) >= abs(delta2))
/*#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) if (thing->flags & MF_PUSHABLE)
{ {
@ -3786,7 +3934,7 @@ void P_MapEnd(void)
} }
// P_FloorzAtPos // 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 // Tails 05-26-2003
fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) 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) for (rover = sec->ffloors; rover; rover = rover->next)
{ {
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS)) if (!(rover->flags & FF_EXISTS))
continue; continue;
if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE))) if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE)))
continue; 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 (rover->flags & FF_QUICKSAND)
{ {
if (z < *rover->topheight && *rover->bottomheight < thingtop) if (z < topheight && bottomheight < thingtop)
{ {
if (floorz < z) if (floorz < z)
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; continue;
} }
delta1 = z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)); delta1 = z - (bottomheight + ((topheight - bottomheight)/2));
delta2 = thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)); delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2));
if (*rover->topheight > floorz && abs(delta1) < abs(delta2)) if (topheight > floorz && abs(delta1) < abs(delta2))
floorz = *rover->topheight; floorz = topheight;
} }
} }

View file

@ -20,6 +20,7 @@
#include "r_data.h" #include "r_data.h"
#include "p_maputl.h" #include "p_maputl.h"
#include "p_polyobj.h" #include "p_polyobj.h"
#include "p_slopes.h"
#include "z_zone.h" #include "z_zone.h"
// //
@ -322,6 +323,9 @@ fixed_t P_InterceptVector(divline_t *v2, divline_t *v1)
// OPTIMIZE: keep this precalculated // OPTIMIZE: keep this precalculated
// //
fixed_t opentop, openbottom, openrange, lowfloor, highceiling; fixed_t opentop, openbottom, openrange, lowfloor, highceiling;
#ifdef ESLOPE
pslope_t *opentopslope, *openbottomslope;
#endif
// P_CameraLineOpening // P_CameraLineOpening
// P_LineOpening, but for camera // P_LineOpening, but for camera
@ -348,31 +352,56 @@ void P_CameraLineOpening(line_t *linedef)
{ {
frontfloor = sectors[front->camsec].floorheight; frontfloor = sectors[front->camsec].floorheight;
frontceiling = sectors[front->camsec].ceilingheight; 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) else if (front->heightsec >= 0)
{ {
frontfloor = sectors[front->heightsec].floorheight; frontfloor = sectors[front->heightsec].floorheight;
frontceiling = sectors[front->heightsec].ceilingheight; 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 else
{ {
frontfloor = front->floorheight; frontfloor = P_CameraGetFloorZ(mapcampointer, front, tmx, tmy, linedef);
frontceiling = front->ceilingheight; frontceiling = P_CameraGetCeilingZ(mapcampointer, front, tmx, tmy, linedef);
} }
if (back->camsec >= 0) if (back->camsec >= 0)
{ {
backfloor = sectors[back->camsec].floorheight; backfloor = sectors[back->camsec].floorheight;
backceiling = sectors[back->camsec].ceilingheight; 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) else if (back->heightsec >= 0)
{ {
backfloor = sectors[back->heightsec].floorheight; backfloor = sectors[back->heightsec].floorheight;
backceiling = sectors[back->heightsec].ceilingheight; 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 else
{ {
backfloor = back->floorheight; backfloor = P_CameraGetFloorZ(mapcampointer, back, tmx, tmy, linedef);
backceiling = back->ceilingheight; backceiling = P_CameraGetCeilingZ(mapcampointer, back, tmx, tmy, linedef);
} }
{ {
@ -414,40 +443,48 @@ void P_CameraLineOpening(line_t *linedef)
if (front->ffloors) if (front->ffloors)
for (rover = front->ffloors; rover; rover = rover->next) 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) if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
continue; continue;
delta1 = abs(mapcampointer->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); topheight = P_CameraGetFOFTopZ(mapcampointer, front, rover, tmx, tmy, linedef);
delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); bottomheight = P_CameraGetFOFBottomZ(mapcampointer, front, rover, tmx, tmy, linedef);
if (*rover->bottomheight < lowestceiling && delta1 >= delta2)
lowestceiling = *rover->bottomheight;
else if (*rover->bottomheight < highestceiling && delta1 >= delta2)
highestceiling = *rover->bottomheight;
if (*rover->topheight > highestfloor && delta1 < delta2) delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
highestfloor = *rover->topheight; delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
else if (*rover->topheight > lowestfloor && delta1 < delta2) if (bottomheight < lowestceiling && delta1 >= delta2)
lowestfloor = *rover->topheight; 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 // Check for backsectors fake floors
if (back->ffloors) if (back->ffloors)
for (rover = back->ffloors; rover; rover = rover->next) 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) if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_RENDERALL) || !(rover->flags & FF_EXISTS) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
continue; continue;
delta1 = abs(mapcampointer->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); topheight = P_CameraGetFOFTopZ(mapcampointer, back, rover, tmx, tmy, linedef);
delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); bottomheight = P_CameraGetFOFBottomZ(mapcampointer, back, rover, tmx, tmy, linedef);
if (*rover->bottomheight < lowestceiling && delta1 >= delta2)
lowestceiling = *rover->bottomheight;
else if (*rover->bottomheight < highestceiling && delta1 >= delta2)
highestceiling = *rover->bottomheight;
if (*rover->topheight > highestfloor && delta1 < delta2) delta1 = abs(mapcampointer->z - (bottomheight + ((topheight - bottomheight)/2)));
highestfloor = *rover->topheight; delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
else if (*rover->topheight > lowestfloor && delta1 < delta2) if (bottomheight < lowestceiling && delta1 >= delta2)
lowestfloor = *rover->topheight; 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) if (highestceiling < highceiling)
@ -495,26 +532,40 @@ void P_LineOpening(line_t *linedef)
I_Assert(front != NULL); I_Assert(front != NULL);
I_Assert(back != NULL); I_Assert(back != NULL);
if (front->ceilingheight < back->ceilingheight) { // Set open and high/low values here
fixed_t frontheight, backheight;
frontheight = P_GetCeilingZ(tmthing, front, tmx, tmy, linedef);
backheight = P_GetCeilingZ(tmthing, back, tmx, tmy, linedef);
if (frontheight < backheight)
{ {
opentop = front->ceilingheight; opentop = frontheight;
highceiling = back->ceilingheight; highceiling = backheight;
opentopslope = front->c_slope;
} }
else else
{ {
opentop = back->ceilingheight; opentop = backheight;
highceiling = front->ceilingheight; highceiling = frontheight;
opentopslope = back->c_slope;
} }
if (front->floorheight > back->floorheight) frontheight = P_GetFloorZ(tmthing, front, tmx, tmy, linedef);
backheight = P_GetFloorZ(tmthing, back, tmx, tmy, linedef);
if (frontheight > backheight)
{ {
openbottom = front->floorheight; openbottom = frontheight;
lowfloor = back->floorheight; lowfloor = backheight;
openbottomslope = front->f_slope;
} }
else else
{ {
openbottom = back->floorheight; openbottom = backheight;
lowfloor = front->floorheight; lowfloor = frontheight;
openbottomslope = back->f_slope;
}
} }
if (tmthing) if (tmthing)
@ -580,10 +631,15 @@ void P_LineOpening(line_t *linedef)
fixed_t highestfloor = openbottom; fixed_t highestfloor = openbottom;
fixed_t lowestfloor = lowfloor; fixed_t lowestfloor = lowfloor;
fixed_t delta1, delta2; fixed_t delta1, delta2;
#ifdef ESLOPE
pslope_t *ceilingslope = opentopslope;
pslope_t *floorslope = openbottomslope;
#endif
// Check for frontsector's fake floors // Check for frontsector's fake floors
for (rover = front->ffloors; rover; rover = rover->next) for (rover = front->ffloors; rover; rover = rover->next)
{ {
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS)) if (!(rover->flags & FF_EXISTS))
continue; continue;
@ -593,29 +649,41 @@ void P_LineOpening(line_t *linedef)
|| (rover->flags & FF_BLOCKOTHERS && !tmthing->player))) || (rover->flags & FF_BLOCKOTHERS && !tmthing->player)))
continue; continue;
delta1 = abs(tmthing->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); topheight = P_GetFOFTopZ(tmthing, front, rover, tmx, tmy, linedef);
delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); 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 (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
{ {
if (*rover->bottomheight < lowestceiling) if (bottomheight < lowestceiling) {
lowestceiling = *rover->bottomheight; lowestceiling = bottomheight;
else if (*rover->bottomheight < highestceiling) #ifdef ESLOPE
highestceiling = *rover->bottomheight; ceilingslope = *rover->b_slope;
#endif
}
else if (bottomheight < highestceiling)
highestceiling = bottomheight;
} }
if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF
{ {
if (*rover->topheight > highestfloor) if (topheight > highestfloor) {
highestfloor = *rover->topheight; highestfloor = topheight;
else if (*rover->topheight > lowestfloor) #ifdef ESLOPE
lowestfloor = *rover->topheight; floorslope = *rover->t_slope;
#endif
}
else if (topheight > lowestfloor)
lowestfloor = topheight;
} }
} }
// Check for backsectors fake floors // Check for backsectors fake floors
for (rover = back->ffloors; rover; rover = rover->next) for (rover = back->ffloors; rover; rover = rover->next)
{ {
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS)) if (!(rover->flags & FF_EXISTS))
continue; continue;
@ -625,23 +693,34 @@ void P_LineOpening(line_t *linedef)
|| (rover->flags & FF_BLOCKOTHERS && !tmthing->player))) || (rover->flags & FF_BLOCKOTHERS && !tmthing->player)))
continue; continue;
delta1 = abs(tmthing->z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); topheight = P_GetFOFTopZ(tmthing, back, rover, tmx, tmy, linedef);
delta2 = abs(thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2))); 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 (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
{ {
if (*rover->bottomheight < lowestceiling) if (bottomheight < lowestceiling) {
lowestceiling = *rover->bottomheight; lowestceiling = bottomheight;
else if (*rover->bottomheight < highestceiling) #ifdef ESLOPE
highestceiling = *rover->bottomheight; ceilingslope = *rover->b_slope;
#endif
}
else if (bottomheight < highestceiling)
highestceiling = bottomheight;
} }
if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF if (delta1 < delta2 && !(rover->flags & FF_REVERSEPLATFORM)) // thing is above FOF
{ {
if (*rover->topheight > highestfloor) if (topheight > highestfloor) {
highestfloor = *rover->topheight; highestfloor = topheight;
else if (*rover->topheight > lowestfloor) #ifdef ESLOPE
lowestfloor = *rover->topheight; 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))); delta1 = abs(tmthing->z - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
delta2 = abs(thingtop - (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; lowestceiling = polysec->floorheight;
#ifdef ESLOPE
ceilingslope = NULL;
#endif
}
else if (polysec->floorheight < highestceiling && delta1 >= delta2) else if (polysec->floorheight < highestceiling && delta1 >= delta2)
highestceiling = polysec->floorheight; highestceiling = polysec->floorheight;
if (polysec->ceilingheight > highestfloor && delta1 < delta2) if (polysec->ceilingheight > highestfloor && delta1 < delta2) {
highestfloor = polysec->ceilingheight; highestfloor = polysec->ceilingheight;
#ifdef ESLOPE
floorslope = NULL;
#endif
}
else if (polysec->ceilingheight > lowestfloor && delta1 < delta2) else if (polysec->ceilingheight > lowestfloor && delta1 < delta2)
lowestfloor = polysec->ceilingheight; lowestfloor = polysec->ceilingheight;
} }
@ -667,11 +754,19 @@ void P_LineOpening(line_t *linedef)
if (highestceiling < highceiling) if (highestceiling < highceiling)
highceiling = highestceiling; highceiling = highestceiling;
if (highestfloor > openbottom) if (highestfloor > openbottom) {
openbottom = highestfloor; openbottom = highestfloor;
#ifdef ESLOPE
openbottomslope = floorslope;
#endif
}
if (lowestceiling < opentop) if (lowestceiling < opentop) {
opentop = lowestceiling; opentop = lowestceiling;
#ifdef ESLOPE
opentopslope = ceilingslope;
#endif
}
if (lowestfloor > lowfloor) if (lowestfloor > lowfloor)
lowfloor = lowestfloor; lowfloor = lowestfloor;
@ -769,6 +864,7 @@ void P_SetThingPosition(mobj_t *thing)
{ // link into subsector { // link into subsector
subsector_t *ss; subsector_t *ss;
sector_t *oldsec = NULL; sector_t *oldsec = NULL;
fixed_t tfloorz, tceilz;
I_Assert(thing != NULL); I_Assert(thing != NULL);
I_Assert(!P_MobjWasRemoved(thing)); I_Assert(!P_MobjWasRemoved(thing));
@ -838,12 +934,15 @@ void P_SetThingPosition(mobj_t *thing)
// sector's floor is the same height. // sector's floor is the same height.
if (thing->player && oldsec != NULL && thing->subsector && oldsec != thing->subsector->sector) 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->eflags & MFE_VERTICALFLIP)
{ {
if (thing->z + thing->height >= thing->subsector->sector->ceilingheight) if (thing->z + thing->height >= tceilz)
thing->eflags |= MFE_JUSTSTEPPEDDOWN; thing->eflags |= MFE_JUSTSTEPPEDDOWN;
} }
else if (thing->z <= thing->subsector->sector->floorheight) else if (thing->z <= tfloorz)
thing->eflags |= MFE_JUSTSTEPPEDDOWN; thing->eflags |= MFE_JUSTSTEPPEDDOWN;
} }
} }

View file

@ -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); boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y);
extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling; extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling;
#ifdef ESLOPE
extern pslope_t *opentopslope, *openbottomslope;
#endif
void P_LineOpening(line_t *plinedef); void P_LineOpening(line_t *plinedef);

File diff suppressed because it is too large Load diff

View file

@ -271,6 +271,7 @@ typedef struct mobj_s
spritenum_t sprite; // used to find patch_t and flip value spritenum_t sprite; // used to find patch_t and flip value
UINT32 frame; // frame number, plus bits see p_pspr.h UINT32 frame; // frame number, plus bits see p_pspr.h
UINT8 sprite2; // player sprites 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 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 cusval;
INT32 cvmem; 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. // WARNING: New fields must be added separately to savegame and Lua.
} mobj_t; } mobj_t;
@ -380,7 +385,8 @@ typedef struct precipmobj_s
// More drawing info: to determine current sprite. // More drawing info: to determine current sprite.
angle_t angle; // orientation angle_t angle; // orientation
spritenum_t sprite; // used to find patch_t and flip value 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 struct mprecipsecnode_s *touching_sectorlist; // a linked list of sectors where this object appears

View file

@ -442,6 +442,8 @@ newseg:
// seg's ending vertex. // seg's ending vertex.
for (i = 0; i < numsegs; ++i) 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) if (segs[i].v1->x == seg->v2->x && segs[i].v1->y == seg->v2->y)
{ {
// Make sure you didn't already add this seg... // Make sure you didn't already add this seg...
@ -610,6 +612,9 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id)
INT32 poflags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES; INT32 poflags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES;
INT32 parentID = 0, potrans = 0; INT32 parentID = 0, potrans = 0;
if (seg->side != 0) // needs to be frontfacing
continue;
if (seg->linedef->special != POLYOBJ_START_LINE) if (seg->linedef->special != POLYOBJ_START_LINE)
continue; continue;

View file

@ -36,9 +36,11 @@
#endif #endif
/// \brief Frame flags: only the frame number /// \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 /// \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 /// \brief Frame flags: 0 = no trans(opaque), 1-15 = transl. table
#define FF_TRANSMASK 0xf0000 #define FF_TRANSMASK 0xf0000
/// \brief shift for FF_TRANSMASK /// \brief shift for FF_TRANSMASK

View file

@ -30,6 +30,9 @@
#include "r_sky.h" #include "r_sky.h"
#include "p_polyobj.h" #include "p_polyobj.h"
#include "lua_script.h" #include "lua_script.h"
#ifdef ESLOPE
#include "p_slopes.h"
#endif
savedata_t savedata; savedata_t savedata;
UINT8 *save_p; UINT8 *save_p;
@ -633,7 +636,7 @@ static void P_NetArchiveWorld(void)
if (li->special != SHORT(mld->special)) if (li->special != SHORT(mld->special))
diff |= LD_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; diff |= LD_CLLCOUNT;
if (li->sidenum[0] != 0xffff) if (li->sidenum[0] != 0xffff)
@ -921,7 +924,8 @@ typedef enum
MD2_EXTVAL1 = 1<<5, MD2_EXTVAL1 = 1<<5,
MD2_EXTVAL2 = 1<<6, MD2_EXTVAL2 = 1<<6,
MD2_HNEXT = 1<<7, MD2_HNEXT = 1<<7,
MD2_HPREV = 1<<8 MD2_HPREV = 1<<8,
MD2_SLOPE = 1<<9
} mobj_diff2_t; } mobj_diff2_t;
typedef enum typedef enum
@ -1056,6 +1060,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff |= MD_SPRITE; diff |= MD_SPRITE;
if (mobj->frame != mobj->state->frame) if (mobj->frame != mobj->state->frame)
diff |= MD_FRAME; diff |= MD_FRAME;
if (mobj->anim_duration != (UINT16)mobj->state->var2)
diff |= MD_FRAME;
if (mobj->eflags) if (mobj->eflags)
diff |= MD_EFLAGS; diff |= MD_EFLAGS;
if (mobj->player) if (mobj->player)
@ -1111,6 +1117,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff2 |= MD2_HNEXT; diff2 |= MD2_HNEXT;
if (mobj->hprev) if (mobj->hprev)
diff2 |= MD2_HPREV; diff2 |= MD2_HPREV;
if (mobj->standingslope)
diff2 |= MD2_SLOPE;
if (diff2 != 0) if (diff2 != 0)
diff |= MD_MORE; diff |= MD_MORE;
@ -1177,7 +1185,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEUINT8(save_p, mobj->sprite2); WRITEUINT8(save_p, mobj->sprite2);
} }
if (diff & MD_FRAME) if (diff & MD_FRAME)
{
WRITEUINT32(save_p, mobj->frame); WRITEUINT32(save_p, mobj->frame);
WRITEUINT16(save_p, mobj->anim_duration);
}
if (diff & MD_EFLAGS) if (diff & MD_EFLAGS)
WRITEUINT16(save_p, mobj->eflags); WRITEUINT16(save_p, mobj->eflags);
if (diff & MD_PLAYER) if (diff & MD_PLAYER)
@ -1226,6 +1237,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEUINT32(save_p, mobj->hnext->mobjnum); WRITEUINT32(save_p, mobj->hnext->mobjnum);
if (diff2 & MD2_HPREV) if (diff2 & MD2_HPREV)
WRITEUINT32(save_p, mobj->hprev->mobjnum); WRITEUINT32(save_p, mobj->hprev->mobjnum);
if (diff2 & MD2_SLOPE)
WRITEUINT16(save_p, mobj->standingslope->id);
WRITEUINT32(save_p, mobj->mobjnum); WRITEUINT32(save_p, mobj->mobjnum);
} }
@ -2007,9 +2020,15 @@ static void LoadMobjThinker(actionf_p1 thinker)
mobj->sprite2 = mobj->state->frame&FF_FRAMEMASK; mobj->sprite2 = mobj->state->frame&FF_FRAMEMASK;
} }
if (diff & MD_FRAME) if (diff & MD_FRAME)
{
mobj->frame = READUINT32(save_p); mobj->frame = READUINT32(save_p);
mobj->anim_duration = READUINT16(save_p);
}
else else
{
mobj->frame = mobj->state->frame; mobj->frame = mobj->state->frame;
mobj->anim_duration = (UINT16)mobj->state->var2;
}
if (diff & MD_EFLAGS) if (diff & MD_EFLAGS)
mobj->eflags = READUINT16(save_p); mobj->eflags = READUINT16(save_p);
if (diff & MD_PLAYER) if (diff & MD_PLAYER)
@ -2079,6 +2098,9 @@ static void LoadMobjThinker(actionf_p1 thinker)
mobj->hnext = (mobj_t *)(size_t)READUINT32(save_p); mobj->hnext = (mobj_t *)(size_t)READUINT32(save_p);
if (diff2 & MD2_HPREV) if (diff2 & MD2_HPREV)
mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p); mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p);
if (diff2 & MD2_SLOPE)
mobj->standingslope = P_SlopeById(READUINT16(save_p));
if (diff & MD_REDFLAG) 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 // tell the sound code to reset the music since we're skipping what
// normally sets this flag // normally sets this flag
mapmusic |= MUSIC_RELOADRESET; mapmusflags |= MUSIC_RELOADRESET;
G_SetGamestate(READINT16(save_p)); G_SetGamestate(READINT16(save_p));

View file

@ -72,6 +72,10 @@
#include "hardware/hw_light.h" #include "hardware/hw_light.h"
#endif #endif
#ifdef ESLOPE
#include "p_slopes.h"
#endif
// //
// Map MD5, calculated on level load. // Map MD5, calculated on level load.
// Sent to clients in PT_SERVERINFO. // Sent to clients in PT_SERVERINFO.
@ -176,10 +180,11 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
mapheaderinfo[num]->typeoflevel = 0; mapheaderinfo[num]->typeoflevel = 0;
DEH_WriteUndoline("NEXTLEVEL", va("%d", mapheaderinfo[num]->nextlevel), UNDO_NONE); DEH_WriteUndoline("NEXTLEVEL", va("%d", mapheaderinfo[num]->nextlevel), UNDO_NONE);
mapheaderinfo[num]->nextlevel = (INT16)(i + 1); mapheaderinfo[num]->nextlevel = (INT16)(i + 1);
DEH_WriteUndoline("MUSICSLOT", va("%d", mapheaderinfo[num]->musicslot), UNDO_NONE); DEH_WriteUndoline("MUSIC", mapheaderinfo[num]->musname, UNDO_NONE);
mapheaderinfo[num]->musicslot = mus_map01m + num; snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i));
DEH_WriteUndoline("MUSICSLOTTRACK", va("%d", mapheaderinfo[num]->musicslottrack), UNDO_NONE); mapheaderinfo[num]->musname[6] = 0;
mapheaderinfo[num]->musicslottrack = 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); DEH_WriteUndoline("FORCECHARACTER", va("%d", mapheaderinfo[num]->forcecharacter), UNDO_NONE);
mapheaderinfo[num]->forcecharacter[0] = '\0'; mapheaderinfo[num]->forcecharacter[0] = '\0';
DEH_WriteUndoline("WEATHER", va("%d", mapheaderinfo[num]->weather), UNDO_NONE); 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 // P_LoadThings
// //
static void P_LoadThings(lumpnum_t lumpnum) static void P_PrepareThings(lumpnum_t lumpnum)
{ {
size_t i; size_t i;
mapthing_t *mt; mapthing_t *mt;
@ -884,13 +889,27 @@ static void P_LoadThings(lumpnum_t lumpnum)
} }
Z_Free(datastart); 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; mt = mapthings;
numhuntemeralds = 0; numhuntemeralds = 0;
for (i = 0; i < nummapthings; i++, mt++) for (i = 0; i < nummapthings; i++, mt++)
{ {
sector_t *mtsector = R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)->sector;
// Z for objects // Z for objects
mt->z = (INT16)(R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS) mt->z = (INT16)(
->sector->floorheight>>FRACBITS); #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 if (mt->type == 1700 // MT_AXIS
|| mt->type == 1701 // MT_AXISTRANSFER || mt->type == 1701 // MT_AXISTRANSFER
@ -1421,6 +1440,29 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
#endif #endif
case 413: // Change music 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 case 414: // Play SFX
{ {
sd->toptexture = sd->midtexture = sd->bottomtexture = 0; sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
@ -1431,13 +1473,6 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
process[8] = '\0'; process[8] = '\0';
sd->toptexture = get_number(process); 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; break;
} }
@ -2115,7 +2150,8 @@ void P_LoadThingsOnly(void)
P_LevelInitStuff(); P_LevelInitStuff();
P_LoadThings(lastloadedmaplumpnum + ML_THINGS); P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
P_LoadThings();
P_SpawnSecretItems(true); P_SpawnSecretItems(true);
} }
@ -2351,7 +2387,7 @@ boolean P_SetupLevel(boolean skipprecip)
// use gamemap to get map number. // use gamemap to get map number.
// 99% of the things already did, so. // 99% of the things already did, so.
// Map header should always be in place at this point // Map header should always be in place at this point
INT32 i, loadprecip = 1; INT32 i, loadprecip = 1, ranspecialwipe = 0;
INT32 loademblems = 1; INT32 loademblems = 1;
INT32 fromnetsave = 0; INT32 fromnetsave = 0;
boolean loadedbm = false; boolean loadedbm = false;
@ -2424,6 +2460,28 @@ boolean P_SetupLevel(boolean skipprecip)
// will be set by player think. // will be set by player think.
players[consoleplayer].viewz = 1; 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. // Make sure all sounds are stopped before Z_FreeTags.
S_StopSounds(); S_StopSounds();
S_ClearSfx(); S_ClearSfx();
@ -2433,16 +2491,20 @@ boolean P_SetupLevel(boolean skipprecip)
S_Start(); S_Start();
// Let's fade to black here // 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(); F_WipeStartScreen();
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
F_WipeEndScreen(); F_WipeEndScreen();
F_RunWipe(wipedefs[wipe_level_toblack], false); F_RunWipe(wipedefs[wipe_level_toblack], false);
}
// Don't include these in the fade! // Print "SPEEDING OFF TO [ZONE] [ACT 1]..."
if (rendermode != render_none)
{ {
// Don't include these in the fade!
char tx[64]; char tx[64];
V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to...")); V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to..."));
snprintf(tx, 63, "%s%s%s", snprintf(tx, 63, "%s%s%s",
@ -2452,7 +2514,6 @@ boolean P_SetupLevel(boolean skipprecip)
V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx); V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx);
I_UpdateNoVsync(); I_UpdateNoVsync();
} }
}
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
LUA_InvalidateLevel(); LUA_InvalidateLevel();
@ -2532,7 +2593,13 @@ boolean P_SetupLevel(boolean skipprecip)
P_MapStart(); P_MapStart();
P_LoadThings(lastloadedmaplumpnum + ML_THINGS); P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
#ifdef ESLOPE
P_ResetDynamicSlopes();
#endif
P_LoadThings();
P_SpawnSecretItems(loademblems); P_SpawnSecretItems(loademblems);
@ -2743,7 +2810,7 @@ boolean P_SetupLevel(boolean skipprecip)
// Remove the loading shit from the screen // Remove the loading shit from the screen
if (rendermode != render_none) if (rendermode != render_none)
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (ranspecialwipe) ? 0 : 31);
if (precache || dedicated) if (precache || dedicated)
R_PrecacheLevel(); R_PrecacheLevel();

1139
src/p_slopes.c Normal file

File diff suppressed because it is too large Load diff

80
src/p_slopes.h Normal file
View file

@ -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

View file

@ -29,6 +29,7 @@
#include "r_main.h" //Two extra includes. #include "r_main.h" //Two extra includes.
#include "r_sky.h" #include "r_sky.h"
#include "p_polyobj.h" #include "p_polyobj.h"
#include "p_slopes.h"
#include "hu_stuff.h" #include "hu_stuff.h"
#include "m_misc.h" #include "m_misc.h"
#include "m_cond.h" //unlock triggers #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 // console player only unless NOCLIMB is set
if ((line->flags & ML_NOCLIMB) || (mo && mo->player && P_IsLocalPlayer(mo->player))) 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; UINT16 tracknum = (UINT16)sides[line->sidenum[0]].bottomtexture;
mapmusic = musicnum | (tracknum << MUSIC_TRACKSHIFT); strncpy(mapmusname, sides[line->sidenum[0]].text, 7);
if (!(line->flags & ML_BLOCKMONSTERS)) mapmusname[6] = 0;
mapmusic |= MUSIC_RELOADRESET;
if (musicnum >= NUMMUSIC || musicnum == mus_None) mapmusflags = tracknum & MUSIC_TRACKMASK;
S_StopMusic(); if (!(line->flags & ML_BLOCKMONSTERS))
else mapmusflags |= MUSIC_RELOADRESET;
S_ChangeMusic(mapmusic, !(line->flags & ML_EFFECT4));
S_ChangeMusic(mapmusname, mapmusflags, !(line->flags & ML_EFFECT4));
// Except, you can use the ML_BLOCKMONSTERS flag to change this behavior. // 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; 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); INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS);
sector_t *sec; // Sector that the FOF is visible (or not visible) in sector_t *sec; // Sector that the FOF is visible (or not visible) in
ffloor_t *rover; // FOF to vanish/un-vanish 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 ;) 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; return;
} }
oldflags = rover->flags;
// Abracadabra! // Abracadabra!
if (line->flags & ML_NOCLIMB) if (line->flags & ML_NOCLIMB)
rover->flags |= FF_EXISTS; rover->flags |= FF_EXISTS;
else else
rover->flags &= ~FF_EXISTS; rover->flags &= ~FF_EXISTS;
// if flags changed, reset sector's light list
if (rover->flags != oldflags)
sec->moved = true;
} }
} }
break; 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) static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *targetsec)
{ {
ffloor_t *rover; ffloor_t *rover;
fixed_t top, bottom;
if (!mo->player) // should NEVER happen if (!mo->player) // should NEVER happen
return false; return false;
@ -3381,6 +3389,9 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar
//if (!(rover->flags & FF_EXISTS)) //if (!(rover->flags & FF_EXISTS))
// return false; // return false;
top = P_GetSpecialTopZ(mo, sector, targetsec);
bottom = P_GetSpecialBottomZ(mo, sector, targetsec);
// Check the 3D floor's type... // Check the 3D floor's type...
if (rover->flags & FF_BLOCKPLAYER) 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) if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)) && !(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; return false;
} }
else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR))
{ {
if (!(mo->eflags & MFE_VERTICALFLIP) if (!(mo->eflags & MFE_VERTICALFLIP)
|| mo->z + mo->height != *rover->bottomheight) || mo->z + mo->height != bottom)
return false; return false;
} }
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH) else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
{ {
if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == *rover->bottomheight) if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == bottom)
|| (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == *rover->topheight))) || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == top)))
return false; return false;
} }
} }
else else
{ {
// Water and intangible FOFs // 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; 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) static inline boolean P_MobjReadyToTrigger(mobj_t *mo, sector_t *sec)
{ {
if (mo->eflags & MFE_VERTICALFLIP) 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 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. /** 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) if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)) && !(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; continue;
} }
else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR))
{ {
if (!(player->mo->eflags & MFE_VERTICALFLIP) 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; continue;
} }
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH) else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
{ {
if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == *rover->bottomheight) 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 == *rover->topheight))) || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector))))
continue; continue;
} }
} }
else else
{ {
// Water and DEATH FOG!!! heh // 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; 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) static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector)
{ {
boolean nofloorneeded = false; boolean nofloorneeded = false;
fixed_t f_affectpoint, c_affectpoint;
if (!sector->special) // nothing special, exit if (!sector->special) // nothing special, exit
return; return;
@ -4579,16 +4591,19 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector)
return; return;
} }
f_affectpoint = P_GetSpecialBottomZ(player->mo, sector, sector);
c_affectpoint = P_GetSpecialTopZ(player->mo, sector, sector);
// Only go further if on the ground // 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; 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; return;
if ((sector->flags & SF_FLIPSPECIAL_BOTH) if ((sector->flags & SF_FLIPSPECIAL_BOTH)
&& player->mo->z != sector->floorheight && player->mo->z != f_affectpoint
&& player->mo->z + player->mo->height != sector->ceilingheight) && player->mo->z + player->mo->height != c_affectpoint)
return; return;
P_ProcessSpecialSector(player, sector, NULL); 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. /** 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) void P_UpdateSpecials(void)
{ {
anim_t *anim; anim_t *anim;
INT32 i, k; INT32 i;
INT32 pic; INT32 pic;
size_t j; size_t j;
levelflat_t *foundflats; // for flat animation levelflat_t *foundflats; // for flat animation
// LEVEL TIMER // LEVEL TIMER
// Exit if the timer is equal to or greater the timelimit, unless you are P_CheckTimeLimit();
// 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);
}
// POINT LIMIT // POINT LIMIT
P_CheckPointLimit(); P_CheckPointLimit();
// Dynamic slopeness
P_RunDynamicSlopes();
// ANIMATE TEXTURES // ANIMATE TEXTURES
for (anim = anims; anim < lastanim; anim++) 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); pic = anim->basepic + ((leveltime/anim->speed + i) % anim->numpics);
if (anim->istexture) 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->topyoffs = &sec2->ceiling_yoffs;
ffloor->topangle = &sec2->ceilingpic_angle; 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 if ((flags & FF_SOLID) && (master->flags & ML_EFFECT1)) // Block player only
flags &= ~FF_BLOCKOTHERS; flags &= ~FF_BLOCKOTHERS;
@ -5325,6 +5254,7 @@ void T_LaserFlash(laserthink_t *flash)
sector_t *sourcesec; sector_t *sourcesec;
ffloor_t *ffloor = flash->ffloor; ffloor_t *ffloor = flash->ffloor;
sector_t *sector = flash->sector; sector_t *sector = flash->sector;
fixed_t top, bottom;
if (!ffloor || !(ffloor->flags & FF_EXISTS)) if (!ffloor || !(ffloor->flags & FF_EXISTS))
return; return;
@ -5348,8 +5278,11 @@ void T_LaserFlash(laserthink_t *flash)
&& thing->flags & MF_BOSS) && thing->flags & MF_BOSS)
continue; // Don't hurt bosses continue; // Don't hurt bosses
if (thing->z >= sourcesec->ceilingheight top = P_GetSpecialTopZ(thing, sourcesec, sector);
|| thing->z + thing->height <= sourcesec->floorheight) bottom = P_GetSpecialBottomZ(thing, sourcesec, sector);
if (thing->z >= top
|| thing->z + thing->height <= bottom)
continue; continue;
if (thing->flags & MF_SHOOTABLE) if (thing->flags & MF_SHOOTABLE)
@ -6094,31 +6027,6 @@ void P_SpawnSpecials(INT32 fromnetsave)
P_AddRaiseThinker(lines[i].frontsector, &lines[i]); P_AddRaiseThinker(lines[i].frontsector, &lines[i]);
break; 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 case 200: // Double light effect
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_CUTSPRITES|FF_DOUBLESHADOW, secthinkers); P_AddFakeFloorsByLine(i, FF_EXISTS|FF_CUTSPRITES|FF_DOUBLESHADOW, secthinkers);
break; break;
@ -6428,6 +6336,14 @@ void P_SpawnSpecials(INT32 fromnetsave)
sectors[s].midmap = lines[i].frontsector->midmap; sectors[s].midmap = lines[i].frontsector->midmap;
break; break;
#ifdef ESLOPE // Slope copy specials. Handled here for sanity.
case 720:
case 721:
case 722:
P_CopySectorSlope(&lines[i]);
break;
#endif
default: default:
break; break;
} }
@ -6632,6 +6548,8 @@ void T_Scroll(scroll_t *s)
if (thing->eflags & MFE_PUSHED) // Already pushed this tic by an exclusive pusher. if (thing->eflags & MFE_PUSHED) // Already pushed this tic by an exclusive pusher.
continue; continue;
height = P_GetSpecialBottomZ(thing, sec, psec);
if (!(thing->flags & MF_NOCLIP)) // Thing must be clipped 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 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) if (thing->eflags & MFE_PUSHED)
continue; continue;
height = P_GetSpecialBottomZ(thing, sec, sec);
if (!(thing->flags & MF_NOCLIP) && if (!(thing->flags & MF_NOCLIP) &&
(!(thing->flags & MF_NOGRAVITY || thing->z > height))) (!(thing->flags & MF_NOGRAVITY || thing->z > height)))
{ {
@ -6691,6 +6611,8 @@ void T_Scroll(scroll_t *s)
if (thing->eflags & MFE_PUSHED) if (thing->eflags & MFE_PUSHED)
continue; continue;
height = P_GetSpecialTopZ(thing, sec, psec);
if (!(thing->flags & MF_NOCLIP)) // Thing must be clipped 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 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) if (thing->eflags & MFE_PUSHED)
continue; continue;
height = P_GetSpecialTopZ(thing, sec, sec);
if (!(thing->flags & MF_NOCLIP) && if (!(thing->flags & MF_NOCLIP) &&
(!(thing->flags & MF_NOGRAVITY || thing->z+thing->height < height))) (!(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) void T_Friction(friction_t *f)
{ {
sector_t *sec; sector_t *sec, *referrer = NULL;
mobj_t *thing; mobj_t *thing;
msecnode_t *node; msecnode_t *node;
@ -7013,7 +6937,7 @@ void T_Friction(friction_t *f)
// Make sure the sector type hasn't changed // Make sure the sector type hasn't changed
if (f->roverfriction) if (f->roverfriction)
{ {
sector_t *referrer = sectors + f->referrer; referrer = sectors + f->referrer;
if (!(GETSECSPECIAL(referrer->special, 3) == 1 if (!(GETSECSPECIAL(referrer->special, 3) == 1
|| GETSECSPECIAL(referrer->special, 3) == 3)) || GETSECSPECIAL(referrer->special, 3) == 3))
@ -7045,9 +6969,7 @@ void T_Friction(friction_t *f)
{ {
if (f->roverfriction) if (f->roverfriction)
{ {
sector_t *referrer = &sectors[f->referrer]; if (thing->floorz != P_GetSpecialTopZ(thing, referrer, sec))
if (thing->floorz != referrer->ceilingheight)
{ {
node = node->m_snext; node = node->m_snext;
continue; continue;
@ -7060,7 +6982,7 @@ void T_Friction(friction_t *f)
thing->movefactor = f->movefactor; 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)) || f->friction < thing->friction))
{ {
thing->friction = f->friction; thing->friction = f->friction;
@ -7334,7 +7256,7 @@ static inline boolean PIT_PushThing(mobj_t *thing)
*/ */
void T_Pusher(pusher_t *p) void T_Pusher(pusher_t *p)
{ {
sector_t *sec; sector_t *sec, *referrer = NULL;
mobj_t *thing; mobj_t *thing;
msecnode_t *node; msecnode_t *node;
INT32 xspeed = 0,yspeed = 0; INT32 xspeed = 0,yspeed = 0;
@ -7343,7 +7265,6 @@ void T_Pusher(pusher_t *p)
//INT32 ht = 0; //INT32 ht = 0;
boolean inFOF; boolean inFOF;
boolean touching; boolean touching;
boolean foundfloor = false;
boolean moved; boolean moved;
xspeed = yspeed = 0; xspeed = yspeed = 0;
@ -7355,19 +7276,16 @@ void T_Pusher(pusher_t *p)
if (p->roverpusher) if (p->roverpusher)
{ {
sector_t *referrer = &sectors[p->referrer]; referrer = &sectors[p->referrer];
if (GETSECSPECIAL(referrer->special, 3) == 2 if (!(GETSECSPECIAL(referrer->special, 3) == 2
|| GETSECSPECIAL(referrer->special, 3) == 3) || GETSECSPECIAL(referrer->special, 3) == 3))
foundfloor = true; return;
} }
else if (!(GETSECSPECIAL(sec->special, 3) == 2 else if (!(GETSECSPECIAL(sec->special, 3) == 2
|| GETSECSPECIAL(sec->special, 3) == 3)) || GETSECSPECIAL(sec->special, 3) == 3))
return; 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: // For constant pushers (wind/current) there are 3 situations:
// //
// 1) Affected Thing is above the floor. // 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 // Find the area that the 'thing' is in
if (p->roverpusher) if (p->roverpusher)
{ {
sector_t *referrer = &sectors[p->referrer]; fixed_t top, bottom;
INT32 special;
special = GETSECSPECIAL(referrer->special, 3); top = P_GetSpecialTopZ(thing, referrer, sec);
bottom = P_GetSpecialBottomZ(thing, referrer, sec);
if (!(special == 2 || special == 3))
return;
if (thing->eflags & MFE_VERTICALFLIP) if (thing->eflags & MFE_VERTICALFLIP)
{ {
if (referrer->floorheight > thing->z + thing->height if (bottom > thing->z + thing->height
|| referrer->ceilingheight < (thing->z + (thing->height >> 1))) || top < (thing->z + (thing->height >> 1)))
continue; continue;
if (thing->z < referrer->floorheight) if (thing->z < bottom)
touching = true; touching = true;
if (thing->z + (thing->height >> 1) > referrer->floorheight) if (thing->z + (thing->height >> 1) > bottom)
inFOF = true; inFOF = true;
} }
else 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; continue;
if (thing->z + thing->height > referrer->ceilingheight) if (thing->z + thing->height > top)
touching = true; touching = true;
if (thing->z + (thing->height >> 1) < referrer->ceilingheight) if (thing->z + (thing->height >> 1) < top)
inFOF = true; inFOF = true;
} }
} }
else // Treat the entire sector as one big FOF 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; touching = true;
else if (p->type != p_current) else if (p->type != p_current)
inFOF = true; inFOF = true;

View file

@ -631,6 +631,7 @@ void P_Ticker(boolean run)
// Run shield positioning // Run shield positioning
P_RunShields(); P_RunShields();
P_RunOverlays();
P_UpdateSpecials(); P_UpdateSpecials();
P_RespawnSpecials(); P_RespawnSpecials();
@ -742,6 +743,7 @@ void P_PreTicker(INT32 frames)
// Run shield positioning // Run shield positioning
P_RunShields(); P_RunShields();
P_RunOverlays();
P_UpdateSpecials(); P_UpdateSpecials();
P_RespawnSpecials(); P_RespawnSpecials();

View file

@ -29,6 +29,7 @@
#include "m_random.h" #include "m_random.h"
#include "m_misc.h" #include "m_misc.h"
#include "i_video.h" #include "i_video.h"
#include "p_slopes.h"
#include "p_spec.h" #include "p_spec.h"
#include "r_splats.h" #include "r_splats.h"
#include "z_zone.h" #include "z_zone.h"
@ -51,9 +52,6 @@
#include "hardware/hw_main.h" #include "hardware/hw_main.h"
#endif #endif
// Index of the special effects (INVUL inverse) map.
#define INVERSECOLORMAP 32
#if 0 #if 0
static void P_NukeAllPlayers(player_t *player); static void P_NukeAllPlayers(player_t *player);
#endif #endif
@ -957,7 +955,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC) && P_IsLocalPlayer(player)) if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC) && P_IsLocalPlayer(player))
{ {
S_StopMusic(); S_StopMusic();
S_ChangeMusic(mus_supers, true); S_ChangeMusicInternal("supers", true);
} }
S_StartSound(NULL, sfx_supert); //let all players hear it -mattw_cfi S_StartSound(NULL, sfx_supert); //let all players hear it -mattw_cfi
@ -1127,7 +1125,7 @@ void P_PlayLivesJingle(player_t *player)
if (player) if (player)
player->powers[pw_extralife] = extralifetics + 1; player->powers[pw_extralife] = extralifetics + 1;
S_StopMusic(); // otherwise it won't restart if this is done twice in a row 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; return;
S_SpeedMusic(1.0f); S_SpeedMusic(1.0f);
if (player->powers[pw_super] && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC)) 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) 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]) else if (player->powers[pw_sneakers] > 1 && !player->powers[pw_super])
{ {
if (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC) if (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC)
{ {
S_SpeedMusic(1.4f); S_SpeedMusic(1.4f);
S_ChangeMusic(mapmusic, true); S_ChangeMusic(mapmusname, mapmusflags, true);
} }
else else
S_ChangeMusic(mus_shoes, true); S_ChangeMusicInternal("shoes", true);
} }
else 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) if (mo->eflags & MFE_VERTICALFLIP)
{ {
// Detect if the player is on the ceiling. // 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; return true;
// Otherwise, detect if the player is on the bottom of a FOF. // Otherwise, detect if the player is on the bottom of a FOF.
else else
@ -1263,7 +1261,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec)
continue; continue;
// Actually check if the player is on the suitable FOF. // 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; return true;
} }
} }
@ -1272,7 +1270,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec)
else else
{ {
// Detect if the player is on the floor. // Detect if the player is on the floor.
if (mo->z <= sec->floorheight) if (mo->z <= P_GetSpecialBottomZ(mo, sec, sec))
return true; return true;
// Otherwise, detect if the player is on the top of a FOF. // Otherwise, detect if the player is on the top of a FOF.
else else
@ -1296,7 +1294,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec)
continue; continue;
// Actually check if the player is on the suitable FOF. // 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; return true;
} }
} }
@ -1624,7 +1622,7 @@ void P_DoPlayerExit(player_t *player)
{ {
player->climbing = 0; player->climbing = 0;
player->pflags |= PF_JUMPED; 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_underwater] = 0;
player->powers[pw_spacetime] = 0; player->powers[pw_spacetime] = 0;
@ -1817,6 +1815,9 @@ static void P_CheckBouncySectors(player_t *player)
fixed_t oldx; fixed_t oldx;
fixed_t oldy; fixed_t oldy;
fixed_t oldz; fixed_t oldz;
#ifdef ESLOPE
vector3_t momentum;
#endif
oldx = player->mo->x; oldx = player->mo->x;
oldy = player->mo->y; oldy = player->mo->y;
@ -1837,16 +1838,21 @@ static void P_CheckBouncySectors(player_t *player)
{ {
ffloor_t *rover; ffloor_t *rover;
boolean top = true; boolean top = true;
fixed_t topheight, bottomheight;
for (rover = node->m_sector->ffloors; rover; rover = rover->next) 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; continue;
if (player->mo->z + player->mo->height < *rover->bottomheight) if (player->mo->z + player->mo->height < bottomheight)
continue; 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; top = false;
if (GETSECSPECIAL(rover->master->frontsector->special, 1) == 15) if (GETSECSPECIAL(rover->master->frontsector->special, 1) == 15)
@ -1861,7 +1867,29 @@ static void P_CheckBouncySectors(player_t *player)
{ {
fixed_t newmom; 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); newmom = -FixedMul(player->mo->momz,linedist);
#endif
if (abs(newmom) < (linedist*2)) if (abs(newmom) < (linedist*2))
{ {
@ -1884,7 +1912,18 @@ static void P_CheckBouncySectors(player_t *player)
else if (newmom < -P_GetPlayerHeight(player)/2) else if (newmom < -P_GetPlayerHeight(player)/2)
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; player->mo->momz = newmom;
#endif
if (player->pflags & PF_SPINNING) if (player->pflags & PF_SPINNING)
{ {
@ -2026,13 +2065,13 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player)
else if (player->powers[pw_underwater] == 1) else if (player->powers[pw_underwater] == 1)
{ {
if ((netgame || multiplayer) && P_IsLocalPlayer(player)) if ((netgame || multiplayer) && P_IsLocalPlayer(player))
S_ChangeMusic(mapmusic, true); S_ChangeMusic(mapmusname, mapmusflags, true);
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_DROWNED); P_DamageMobj(player->mo, NULL, NULL, 1, DMG_DROWNED);
} }
else if (player->powers[pw_spacetime] == 1) else if (player->powers[pw_spacetime] == 1)
{ {
if ((netgame || multiplayer) && P_IsLocalPlayer(player)) if ((netgame || multiplayer) && P_IsLocalPlayer(player))
S_ChangeMusic(mapmusic, true); S_ChangeMusic(mapmusname, mapmusflags, true);
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPACEDROWN); P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPACEDROWN);
} }
@ -2066,7 +2105,7 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player)
&& player == &players[consoleplayer]) && player == &players[consoleplayer])
{ {
S_StopMusic(); S_StopMusic();
S_ChangeMusic(mus_drown, false); S_ChangeMusicInternal("drown", false);
} }
if (player->powers[pw_underwater] == 25*TICRATE + 1) 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))); player->mo->color = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1)));
else if (leveltime % (TICRATE/7) == 0) else if (leveltime % (TICRATE/7) == 0)
{ {
fixed_t destx, desty; mobj_t *sparkle = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_IVSP);
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);
sparkle->destscale = player->mo->scale; sparkle->destscale = player->mo->scale;
P_SetScale(sparkle, player->mo->scale); P_SetScale(sparkle, player->mo->scale);
} }
@ -2298,14 +2314,27 @@ static void P_DoClimbing(player_t *player)
boolean thrust; boolean thrust;
boolean boostup; boolean boostup;
boolean skyclimber; boolean skyclimber;
fixed_t floorheight, ceilingheight; // ESLOPE
thrust = false; thrust = false;
floorclimb = false; floorclimb = false;
boostup = false; boostup = false;
skyclimber = 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) if (glidesector->sector->ffloors)
{ {
ffloor_t *rover; ffloor_t *rover;
fixed_t topheight, bottomheight; // ESLOPE
for (rover = glidesector->sector->ffloors; rover; rover = rover->next) for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
{ {
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) 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; 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. // 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 (rover->master->frontsector->floorspeed && rover->master->frontsector->ceilspeed == 42)
{ {
if ((!(player->mo->eflags & MFE_VERTICALFLIP) && (*rover->bottomheight < player->mo->z+player->mo->height) if ((!(player->mo->eflags & MFE_VERTICALFLIP) && (bottomheight < player->mo->z+player->mo->height)
&& (*rover->topheight >= player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale))) && (topheight >= player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)))
|| ((player->mo->eflags & MFE_VERTICALFLIP) && (*rover->topheight > player->mo->z) || ((player->mo->eflags & MFE_VERTICALFLIP) && (topheight > player->mo->z)
&& (*rover->bottomheight <= player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)))) && (bottomheight <= player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale))))
{ {
if (cmd->forwardmove != 0) if (cmd->forwardmove != 0)
player->mo->momz += rover->master->frontsector->floorspeed; player->mo->momz += rover->master->frontsector->floorspeed;
@ -2335,8 +2372,9 @@ static void P_DoClimbing(player_t *player)
if (player->mo->eflags & MFE_VERTICALFLIP) if (player->mo->eflags & MFE_VERTICALFLIP)
{ {
// Trying to climb down past the bottom of the FOF // 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; ffloor_t *roverbelow;
boolean foundfof = false; boolean foundfof = false;
floorclimb = true; floorclimb = true;
@ -2351,7 +2389,13 @@ static void P_DoClimbing(player_t *player)
if (roverbelow == rover) if (roverbelow == rover)
continue; 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; foundfof = true;
} }
@ -2360,7 +2404,7 @@ static void P_DoClimbing(player_t *player)
} }
// Below the FOF // Below the FOF
if (*rover->topheight <= player->mo->z) if (topheight <= player->mo->z)
{ {
floorclimb = false; floorclimb = false;
boostup = false; boostup = false;
@ -2368,7 +2412,7 @@ static void P_DoClimbing(player_t *player)
} }
// Above the FOF // 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; floorclimb = false;
thrust = true; thrust = true;
@ -2378,8 +2422,9 @@ static void P_DoClimbing(player_t *player)
else else
{ {
// Trying to climb down past the bottom of a FOF // 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; ffloor_t *roverbelow;
boolean foundfof = false; boolean foundfof = false;
floorclimb = true; floorclimb = true;
@ -2394,7 +2439,13 @@ static void P_DoClimbing(player_t *player)
if (roverbelow == rover) if (roverbelow == rover)
continue; 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; foundfof = true;
} }
@ -2403,7 +2454,7 @@ static void P_DoClimbing(player_t *player)
} }
// Below the FOF // Below the FOF
if (*rover->bottomheight >= player->mo->z + player->mo->height) if (bottomheight >= player->mo->z + player->mo->height)
{ {
floorclimb = false; floorclimb = false;
boostup = false; boostup = false;
@ -2411,7 +2462,7 @@ static void P_DoClimbing(player_t *player)
} }
// Above the FOF // 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; floorclimb = false;
thrust = true; thrust = true;
@ -2432,7 +2483,7 @@ static void P_DoClimbing(player_t *player)
if (player->mo->eflags & MFE_VERTICALFLIP) if (player->mo->eflags & MFE_VERTICALFLIP)
{ {
// Trying to climb down past the upper texture area // 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; boolean foundfof = false;
floorclimb = true; floorclimb = true;
@ -2440,13 +2491,20 @@ static void P_DoClimbing(player_t *player)
// Is there a FOF directly below that we can move onto? // Is there a FOF directly below that we can move onto?
if (glidesector->sector->ffloors) if (glidesector->sector->ffloors)
{ {
fixed_t bottomheight;
ffloor_t *rover; ffloor_t *rover;
for (rover = glidesector->sector->ffloors; rover; rover = rover->next) for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
{ {
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP)) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
continue; 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; foundfof = true;
break; break;
@ -2459,8 +2517,8 @@ static void P_DoClimbing(player_t *player)
} }
// Reached the top of the lower texture area // 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) if (!floorclimb && 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)))) && (glidesector->sector->ceilingpic == skyflatnum || floorheight < (player->mo->z - FixedMul(8*FRACUNIT, player->mo->scale))))
{ {
thrust = true; thrust = true;
boostup = true; boostup = true;
@ -2470,7 +2528,7 @@ static void P_DoClimbing(player_t *player)
else else
{ {
// Trying to climb down past the upper texture area // 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; boolean foundfof = false;
floorclimb = true; 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)) if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
continue; 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; foundfof = true;
break; 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. // 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; floorclimb = true;
thrust = false; thrust = false;
@ -2505,8 +2563,8 @@ static void P_DoClimbing(player_t *player)
} }
// Reached the top of the lower texture area // Reached the top of the lower texture area
if (!floorclimb && glidesector->sector->floorheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) if (!floorclimb && 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)))) && (glidesector->sector->ceilingpic == skyflatnum || ceilingheight > (player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, player->mo->scale))))
{ {
thrust = true; thrust = true;
boostup = true; boostup = true;
@ -2515,14 +2573,14 @@ static void P_DoClimbing(player_t *player)
} }
// Trying to climb on the sky // 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; skyclimber = true;
} }
// Climbing on the lower texture area? // Climbing on the lower texture area?
if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) < 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 <= glidesector->sector->floorheight)) || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height <= floorheight))
{ {
floorclimb = true; floorclimb = true;
@ -2538,8 +2596,8 @@ static void P_DoClimbing(player_t *player)
} }
} }
// Climbing on the upper texture area? // Climbing on the upper texture area?
else if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z >= 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) > glidesector->sector->ceilingheight)) || ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) > ceilingheight))
{ {
floorclimb = true; floorclimb = true;
@ -2632,21 +2690,21 @@ static void P_DoClimbing(player_t *player)
player->climbing = 0; player->climbing = 0;
player->pflags |= PF_JUMPED; player->pflags |= PF_JUMPED;
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
} }
if (skyclimber) if (skyclimber)
{ {
player->climbing = 0; player->climbing = 0;
player->pflags |= PF_JUMPED; player->pflags |= PF_JUMPED;
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
} }
} }
else else
{ {
player->climbing = 0; player->climbing = 0;
player->pflags |= PF_JUMPED; 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) if (cmd->sidemove != 0 || cmd->forwardmove != 0)
@ -2664,7 +2722,7 @@ static void P_DoClimbing(player_t *player)
{ {
player->climbing = 0; player->climbing = 0;
player->pflags |= PF_JUMPED; 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_SetObjectMomZ(player->mo, 4*FRACUNIT, false);
P_InstaThrust(player->mo, player->mo->angle, FixedMul(-4*FRACUNIT, player->mo->scale)); 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; localangle2 = player->mo->angle;
if (player->climbing == 0) 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)) if (player->climbing && P_IsObjectOnGround(player->mo))
{ {
@ -3384,27 +3442,14 @@ static void P_DoSuperStuff(player_t *player)
if ((leveltime % TICRATE == 0) && !(player->exiting)) if ((leveltime % TICRATE == 0) && !(player->exiting))
player->rings--; player->rings--;
// future todo: a skin option for this, and possibly more colors
switch (player->skin) switch (player->skin)
{ {
case 1: // Golden orange supertails. case 1: /* Tails */ player->mo->color = SKINCOLOR_TSUPER1; break;
if (leveltime % 9 < 5) case 2: /* Knux */ player->mo->color = SKINCOLOR_KSUPER1; break;
player->mo->color = SKINCOLOR_TSUPER1 + leveltime % 9; default: /* everyone */ player->mo->color = SKINCOLOR_SUPER1; break;
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;
} }
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)) 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)) && !(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->mo->health > 0)
{ {
if ((player->pflags & PF_JUMPED || player->pflags & PF_SPINNING) if (player->pflags & PF_JUMPED)
&& player->mo->state-states != S_PLAY_DASH) 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); P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
else switch (player->mo->state-states) else switch (player->mo->state-states)
{ {
@ -3460,8 +3506,8 @@ static void P_DoSuperStuff(player_t *player)
case S_PLAY_SUPER_PAIN: case S_PLAY_SUPER_PAIN:
P_SetPlayerMobjState(player->mo, S_PLAY_PAIN); P_SetPlayerMobjState(player->mo, S_PLAY_PAIN);
break; break;
case S_PLAY_SUPER_JUMP: case S_PLAY_SUPER_SPRING:
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); P_SetPlayerMobjState(player->mo, S_PLAY_SPRING);
break; break;
case S_PLAY_SUPER_FALL: case S_PLAY_SUPER_FALL:
P_SetPlayerMobjState(player->mo, S_PLAY_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! S_StartSound(player->mo, sfx_jump); // Play jump sound!
if (!(player->charability2 == CA2_SPINDASH)) if (!(player->charability2 == CA2_SPINDASH))
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP); P_SetPlayerMobjState(player->mo, S_PLAY_SPRING);
else 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 if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_SLIDING) && !player->exiting
&& !P_PlayerInPain(player)) // subsequent revs && !P_PlayerInPain(player)) // subsequent revs
{ {
if ((cmd->buttons & BT_USE) && player->speed < FixedMul(5<<FRACBITS, player->mo->scale) && !player->mo->momz && onground && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING)) if ((cmd->buttons & BT_USE) && player->speed < FixedMul(5<<FRACBITS, player->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->momx = player->cmomx;
player->mo->momy = player->cmomy; 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. // down the spin button and not spinning.
// AKA Just go into a spin on the ground, you idiot. ;) // 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)) 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<<FRACBITS, player->mo->scale) && !(player->pflags & PF_USEDOWN) && !(player->pflags & PF_SPINNING)) && !player->climbing && !player->mo->momz && onground && (player->speed > FixedMul(5<<FRACBITS, player->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; player->pflags |= PF_SPINNING;
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
@ -3747,7 +3801,11 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
// Rolling normally // Rolling normally
if (onground && player->pflags & PF_SPINNING && !(player->pflags & PF_STARTDASH) 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))) 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)); 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 angle_t dangle; // replaces old quadrants bits
fixed_t normalspd = FixedMul(player->normalspeed, player->mo->scale); fixed_t normalspd = FixedMul(player->normalspeed, player->mo->scale);
boolean analogmove = false; boolean analogmove = false;
#ifndef OLD_MOVEMENT_CODE
fixed_t oldMagnitude, newMagnitude; 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 // 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); oldMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0);
#endif
analogmove = P_AnalogMove(player); analogmove = P_AnalogMove(player);
@ -4621,17 +4683,10 @@ static void P_3dMovement(player_t *player)
} }
movepushforward = FixedMul(movepushforward, player->mo->scale); movepushforward = FixedMul(movepushforward, player->mo->scale);
#ifdef OLD_MOVEMENT_CODE
if (player->speed < topspeed && mforward && cmd->forwardmove > 0) // Sonic's Speed #ifdef ESLOPE
P_Thrust(player->mo, movepushangle, movepushforward); totalthrust.x += P_ReturnThrustX(player->mo, movepushangle, movepushforward);
else if (mforward && cmd->forwardmove < 0) totalthrust.y += P_ReturnThrustY(player->mo, movepushangle, movepushforward);
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);
#else #else
P_Thrust(player->mo, movepushangle, movepushforward); P_Thrust(player->mo, movepushangle, movepushforward);
#endif #endif
@ -4645,33 +4700,12 @@ static void P_3dMovement(player_t *player)
if (!(player->pflags & PF_GLIDING || player->exiting || P_PlayerInPain(player))) if (!(player->pflags & PF_GLIDING || player->exiting || P_PlayerInPain(player)))
{ {
angle_t controldirection; 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 // Calculate the angle at which the controls are pointing
// to figure out the proper mforward and mbackward. // to figure out the proper mforward and mbackward.
// (Why was it so complicated before? ~Red) // (Why was it so complicated before? ~Red)
controldirection = R_PointToAngle2(0, 0, cmd->forwardmove*FRACUNIT, -cmd->sidemove*FRACUNIT)+movepushangle; 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); movepushforward = max(abs(cmd->sidemove), abs(cmd->forwardmove)) * (thrustfactor * acceleration);
// allow very small movement while in air for gameplay // allow very small movement while in air for gameplay
@ -4694,13 +4728,10 @@ static void P_3dMovement(player_t *player)
movepushsideangle = controldirection; movepushsideangle = controldirection;
movepushforward = FixedMul(movepushforward, player->mo->scale); movepushforward = FixedMul(movepushforward, player->mo->scale);
#ifdef OLD_MOVEMENT_CODE
if (player->speed < topspeed) #ifdef ESLOPE
P_Thrust(player->mo, controldirection, movepushforward); totalthrust.x += P_ReturnThrustX(player->mo, controldirection, movepushforward);
else if ((mforward) && (cbackward)) totalthrust.y += P_ReturnThrustY(player->mo, controldirection, movepushforward);
P_Thrust(player->mo, controldirection, movepushforward);
else if ((mbackward) && (cforward))
P_Thrust(player->mo, controldirection, movepushforward);
#else #else
P_Thrust(player->mo, controldirection, movepushforward); P_Thrust(player->mo, controldirection, movepushforward);
#endif #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)) 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); movepushside = cmd->sidemove * (thrustfactor * acceleration);
if (!onground) 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. // Finally move the player now that his speed/direction has been decided.
movepushside = FixedMul(movepushside, player->mo->scale); movepushside = FixedMul(movepushside, player->mo->scale);
#ifdef OLD_MOVEMENT_CODE
if (player->speed < topspeed) #ifdef ESLOPE
P_Thrust(player->mo, movepushsideangle, movepushside); totalthrust.x += P_ReturnThrustX(player->mo, movepushsideangle, movepushside);
else if (mright && cmd->sidemove < 0) totalthrust.y += P_ReturnThrustY(player->mo, movepushsideangle, movepushside);
P_Thrust(player->mo, movepushsideangle, movepushside);
else if (mleft && cmd->sidemove > 0)
P_Thrust(player->mo, movepushsideangle, movepushside);
#else #else
P_Thrust(player->mo, movepushsideangle, movepushside); P_Thrust(player->mo, movepushsideangle, movepushside);
#endif #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: // Time to ask three questions:
// 1) Are we over topspeed? // 1) Are we over topspeed?
// 2) If "yes" to 1, were we moving over topspeed to begin with? // 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; 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) 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_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) 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))) if (!(player->powers[pw_nocontrol] & (1<<15)))
player->pflags |= PF_JUMPSTASIS; player->pflags |= PF_JUMPSTASIS;
} }
else // note: don't unset stasis here
player->pflags &= ~PF_FULLSTASIS;
if (!player->spectator && G_TagGametype()) if (!player->spectator && G_TagGametype())
{ {
@ -6452,10 +6476,10 @@ static void P_MovePlayer(player_t *player)
} }
// If Springing, but travelling DOWNWARD, change back! // 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); P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
// If Springing but on the ground, change back! // 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); P_SetPlayerMobjState(player->mo, S_PLAY_STND);
// If you are stopped and are still walking, stand still! // If you are stopped and are still walking, stand still!
@ -6494,7 +6518,7 @@ static void P_MovePlayer(player_t *player)
else else
{ {
player->pflags |= PF_JUMPED; player->pflags |= PF_JUMPED;
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
} }
} }
player->pflags &= ~PF_GLIDING; player->pflags &= ~PF_GLIDING;
@ -6552,7 +6576,7 @@ static void P_MovePlayer(player_t *player)
&& player->charability == CA_GLIDEANDCLIMB) && player->charability == CA_GLIDEANDCLIMB)
{ {
player->pflags |= PF_JUMPED; player->pflags |= PF_JUMPED;
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
} }
else else
{ {
@ -6622,7 +6646,7 @@ static void P_MovePlayer(player_t *player)
else else
{ {
player->pflags |= PF_JUMPED; player->pflags |= PF_JUMPED;
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
} }
} }
player->powers[pw_tailsfly] = 0; 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) if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED)
&& !(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH) && !(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH)
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN); P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
return; return;
} }
@ -7314,7 +7338,7 @@ static void P_DoRopeHang(player_t *player)
if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED) if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED)
&& !(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH) && !(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); P_SetTarget(&player->mo->tracer, NULL);
@ -7691,7 +7715,7 @@ static void P_DeathThink(player_t *player)
// Return to level music // Return to level music
if (netgame && player->deadtimer == gameovertics && P_IsLocalPlayer(player)) if (netgame && player->deadtimer == gameovertics && P_IsLocalPlayer(player))
S_ChangeMusic(mapmusic, true); S_ChangeMusic(mapmusname, mapmusflags, true);
} }
if (!player->mo) if (!player->mo)
@ -7926,9 +7950,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
if (player == &players[consoleplayer]) if (player == &players[consoleplayer])
{ {
if (focusangle >= localangle) if (focusangle >= localangle)
localangle += abs(focusangle - localangle)>>5; localangle += abs((focusangle - localangle))>>5;
else else
localangle -= abs(focusangle - localangle)>>5; localangle -= abs((focusangle - localangle))>>5;
} }
} }
else if (P_AnalogMove(player)) // Analog else if (P_AnalogMove(player)) // Analog
@ -8630,7 +8654,7 @@ void P_PlayerThink(player_t *player)
P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE); 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) 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) if (player->flashcount)
player->flashcount--; player->flashcount--;
@ -8677,7 +8701,7 @@ void P_PlayerThink(player_t *player)
if (countdown == 11*TICRATE - 1) if (countdown == 11*TICRATE - 1)
{ {
if (P_IsLocalPlayer(player)) if (P_IsLocalPlayer(player))
S_ChangeMusic(mus_drown, false); S_ChangeMusicInternal("drown", false);
} }
// If you've hit the countdown and you haven't made // 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; mo2 = (mobj_t *)th;
if (!(mo2->type == MT_NIGHTSWING || mo2->type == MT_RING || mo2->type == MT_COIN if (!(mo2->type == MT_NIGHTSWING || mo2->type == MT_RING || mo2->type == MT_COIN
#ifdef BLUE_SPHERES || mo2->type == MT_BLUEBALL))
|| mo2->type == MT_BLUEBALL
#endif
))
continue; continue;
if (P_AproxDistance(P_AproxDistance(mo2->x - x, mo2->y - y), mo2->z - z) > FixedMul(128*FRACUNIT, player->mo->scale)) 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) if (!player->mo)
return; // P_MovePlayer removed 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 #ifdef POLYOBJECTS
if (player->onconveyor == 1) if (player->onconveyor == 1)
player->cmomy = player->cmomx = 0; player->cmomy = player->cmomx = 0;
@ -9254,7 +9280,7 @@ void P_PlayerAfterThink(player_t *player)
&& ((!player->powers[pw_super] && player->panim != PA_ROLL) && ((!player->powers[pw_super] && player->panim != PA_ROLL)
|| player->mo->state == &states[player->mo->info->painstate]) || player->mo->state == &states[player->mo->info->painstate])
&& player->charability2 == CA2_SPINDASH) && 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) if (player->pflags & PF_CARRIED && player->mo->tracer)
{ {

View file

@ -18,6 +18,7 @@
#include "r_splats.h" #include "r_splats.h"
#include "p_local.h" // camera #include "p_local.h" // camera
#include "p_slopes.h"
#include "z_zone.h" // Check R_Prep3DFloors #include "z_zone.h" // Check R_Prep3DFloors
seg_t *curline; seg_t *curline;
@ -31,7 +32,6 @@ sector_t *backsector;
// 896 drawsegs! So too bad here's a limit removal a-la-Boom // 896 drawsegs! So too bad here's a limit removal a-la-Boom
drawseg_t *drawsegs = NULL; drawseg_t *drawsegs = NULL;
drawseg_t *ds_p = NULL; drawseg_t *ds_p = NULL;
drawseg_t *firstnewseg = NULL;
// indicates doors closed wrt automap bugfix: // indicates doors closed wrt automap bugfix:
INT32 doorclosed; INT32 doorclosed;
@ -459,6 +459,11 @@ static void R_AddLine(seg_t *line)
doorclosed = 0; doorclosed = 0;
// Closed door. // 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 if (backsector->ceilingheight <= frontsector->floorheight
|| backsector->floorheight >= frontsector->ceilingheight) || backsector->floorheight >= frontsector->ceilingheight)
{ {
@ -487,6 +492,10 @@ static void R_AddLine(seg_t *line)
#endif #endif
backsector->ceilingpic == frontsector->ceilingpic backsector->ceilingpic == frontsector->ceilingpic
&& backsector->floorpic == frontsector->floorpic && backsector->floorpic == frontsector->floorpic
#ifdef ESLOPE
&& backsector->f_slope == frontsector->f_slope
&& backsector->c_slope == frontsector->c_slope
#endif
&& backsector->lightlevel == frontsector->lightlevel && backsector->lightlevel == frontsector->lightlevel
&& !curline->sidedef->midtexture && !curline->sidedef->midtexture
// Check offsets too! // Check offsets too!
@ -842,11 +851,19 @@ static void R_Subsector(size_t num)
sub->sector->moved = frontsector->moved = false; 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) if (frontsector->floorlightsec == -1)
floorlightlevel = *frontsector->lightlist[light].lightlevel; floorlightlevel = *frontsector->lightlist[light].lightlevel;
floorcolormap = frontsector->lightlist[light].extra_colormap; 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) if (frontsector->ceilinglightsec == -1)
ceilinglightlevel = *frontsector->lightlist[light].lightlevel; ceilinglightlevel = *frontsector->lightlist[light].lightlevel;
ceilingcolormap = frontsector->lightlist[light].extra_colormap; ceilingcolormap = frontsector->lightlist[light].extra_colormap;
@ -854,32 +871,52 @@ static void R_Subsector(size_t num)
sub->sector->extra_colormap = frontsector->extra_colormap; 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))) && sectors[frontsector->heightsec].ceilingpic == skyflatnum)))
{ {
floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel, 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 else
floorplane = NULL; 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 || (frontsector->heightsec != -1
&& sectors[frontsector->heightsec].floorpic == skyflatnum))) && sectors[frontsector->heightsec].floorpic == skyflatnum)))
{ {
ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic, ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic,
ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle, ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle,
ceilingcolormap, NULL); ceilingcolormap, NULL
#ifdef ESLOPE
, frontsector->c_slope
#endif
);
} }
else else
ceilingplane = NULL; ceilingplane = NULL;
numffloors = 0; numffloors = 0;
#ifdef ESLOPE
ffloor[numffloors].slope = NULL;
#endif
ffloor[numffloors].plane = NULL; ffloor[numffloors].plane = NULL;
ffloor[numffloors].polyobj = NULL; ffloor[numffloors].polyobj = NULL;
if (frontsector->ffloors) if (frontsector->ffloors)
{ {
ffloor_t *rover; ffloor_t *rover;
fixed_t heightcheck, planecenterz, floorcenterz, ceilingcenterz;
for (rover = frontsector->ffloors; rover && numffloors < MAXFFLOORS; rover = rover->next) 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].plane = NULL;
ffloor[numffloors].polyobj = NULL; ffloor[numffloors].polyobj = NULL;
if (*rover->bottomheight <= frontsector->ceilingheight
&& *rover->bottomheight >= frontsector->floorheight floorcenterz =
&& ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) #ifdef ESLOPE
|| (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) 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); viewz < *rover->bottomheight);
ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic, ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic,
*frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, *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; ffloor[numffloors].ffloor = rover;
numffloors++; numffloors++;
} }
@ -916,16 +995,47 @@ static void R_Subsector(size_t num)
break; break;
ffloor[numffloors].plane = NULL; ffloor[numffloors].plane = NULL;
ffloor[numffloors].polyobj = NULL; ffloor[numffloors].polyobj = NULL;
if (*rover->topheight >= frontsector->floorheight
&& *rover->topheight <= frontsector->ceilingheight heightcheck =
&& ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) #ifdef ESLOPE
|| (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) *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, ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic,
*frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle, *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle,
frontsector->lightlist[light].extra_colormap, rover); frontsector->lightlist[light].extra_colormap, rover
ffloor[numffloors].height = *rover->topheight; #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; ffloor[numffloors].ffloor = rover;
numffloors++; numffloors++;
} }
@ -977,11 +1087,18 @@ static void R_Subsector(size_t num)
polysec->lightlevel, xoff, yoff, polysec->lightlevel, xoff, yoff,
polysec->floorpic_angle-po->angle, polysec->floorpic_angle-po->angle,
NULL, NULL,
NULL); NULL
#ifdef ESLOPE
, NULL // will ffloors be slopable eventually?
#endif
);
//ffloor[numffloors].plane->polyobj = po; //ffloor[numffloors].plane->polyobj = po;
ffloor[numffloors].height = polysec->floorheight; ffloor[numffloors].height = polysec->floorheight;
ffloor[numffloors].polyobj = po; ffloor[numffloors].polyobj = po;
#ifdef ESLOPE
ffloor[numffloors].slope = NULL;
#endif
// ffloor[numffloors].ffloor = rover; // ffloor[numffloors].ffloor = rover;
po->visplane = ffloor[numffloors].plane; po->visplane = ffloor[numffloors].plane;
numffloors++; numffloors++;
@ -1014,11 +1131,18 @@ static void R_Subsector(size_t num)
light = 0; light = 0;
ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic, ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic,
polysec->lightlevel, xoff, yoff, polysec->ceilingpic_angle-po->angle, 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].plane->polyobj = po;
ffloor[numffloors].polyobj = po; ffloor[numffloors].polyobj = po;
ffloor[numffloors].height = polysec->ceilingheight; ffloor[numffloors].height = polysec->ceilingheight;
#ifdef ESLOPE
ffloor[numffloors].slope = NULL;
#endif
// ffloor[numffloors].ffloor = rover; // ffloor[numffloors].ffloor = rover;
po->visplane = ffloor[numffloors].plane; po->visplane = ffloor[numffloors].plane;
numffloors++; numffloors++;
@ -1077,6 +1201,11 @@ void R_Prep3DFloors(sector_t *sector)
fixed_t bestheight, maxheight; fixed_t bestheight, maxheight;
INT32 count, i, mapnum; INT32 count, i, mapnum;
sector_t *sec; 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; count = 1;
for (rover = sector->ffloors; rover; rover = rover->next) for (rover = sector->ffloors; rover; rover = rover->next)
@ -1099,7 +1228,14 @@ void R_Prep3DFloors(sector_t *sector)
else else
memset(sector->lightlist, 0, sizeof (lightlist_t) * count); 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; sector->lightlist[0].height = sector->ceilingheight + 1;
#endif
sector->lightlist[0].lightlevel = &sector->lightlevel; sector->lightlist[0].lightlevel = &sector->lightlevel;
sector->lightlist[0].caster = NULL; sector->lightlist[0].caster = NULL;
sector->lightlist[0].extra_colormap = sector->extra_colormap; 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))) && !(rover->flags & FF_CUTLEVEL) && !(rover->flags & FF_CUTSPRITES)))
continue; 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) if (*rover->topheight > bestheight && *rover->topheight < maxheight)
{ {
best = rover; best = rover;
@ -1130,6 +1289,7 @@ void R_Prep3DFloors(sector_t *sector)
bestheight = *rover->bottomheight; bestheight = *rover->bottomheight;
continue; continue;
} }
#endif
} }
if (!best) if (!best)
{ {
@ -1140,6 +1300,9 @@ void R_Prep3DFloors(sector_t *sector)
sector->lightlist[i].height = maxheight = bestheight; sector->lightlist[i].height = maxheight = bestheight;
sector->lightlist[i].caster = best; sector->lightlist[i].caster = best;
sector->lightlist[i].flags = best->flags; sector->lightlist[i].flags = best->flags;
#ifdef ESLOPE
sector->lightlist[i].slope = bestslope;
#endif
sec = &sectors[best->secnum]; sec = &sectors[best->secnum];
mapnum = sec->midmap; mapnum = sec->midmap;
if (mapnum >= 0 && (size_t)mapnum < num_extra_colormaps) if (mapnum >= 0 && (size_t)mapnum < num_extra_colormaps)
@ -1165,7 +1328,12 @@ void R_Prep3DFloors(sector_t *sector)
if (best->flags & FF_DOUBLESHADOW) 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) if (bestheight == *best->bottomheight)
#endif
{ {
sector->lightlist[i].lightlevel = sector->lightlist[best->lastlight].lightlevel; sector->lightlist[i].lightlevel = sector->lightlist[best->lastlight].lightlevel;
sector->lightlist[i].extra_colormap = sector->lightlist[i].extra_colormap =

View file

@ -30,7 +30,6 @@ extern INT32 checkcoord[12][4];
extern drawseg_t *drawsegs; extern drawseg_t *drawsegs;
extern drawseg_t *ds_p; extern drawseg_t *ds_p;
extern drawseg_t *firstnewseg;
extern INT32 doorclosed; extern INT32 doorclosed;
typedef void (*drawfunc_t)(INT32 start, INT32 stop); typedef void (*drawfunc_t)(INT32 start, INT32 stop);

View file

@ -155,6 +155,12 @@ typedef struct ffloor_s
fixed_t *bottomyoffs; fixed_t *bottomyoffs;
angle_t *bottomangle; angle_t *bottomangle;
#ifdef ESLOPE
// Pointers to pointers. Yup.
struct pslope_s **t_slope;
struct pslope_s **b_slope;
#endif
size_t secnum; size_t secnum;
ffloortype_e flags; ffloortype_e flags;
struct line_s *master; struct line_s *master;
@ -184,6 +190,9 @@ typedef struct lightlist_s
extracolormap_t *extra_colormap; extracolormap_t *extra_colormap;
INT32 flags; INT32 flags;
ffloor_t *caster; ffloor_t *caster;
#ifdef ESLOPE
struct pslope_s *slope; // FF_DOUBLESHADOW makes me have to store this pointer here. Bluh bluh.
#endif
} lightlist_t; } lightlist_t;
@ -224,6 +233,52 @@ typedef struct secplane_t
fixed_t a, b, c, d, ic; fixed_t a, b, c, d, ic;
} secplane_t; } 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 typedef enum
{ {
SF_FLIPSPECIAL_FLOOR = 1, SF_FLIPSPECIAL_FLOOR = 1,
@ -314,14 +369,6 @@ typedef struct sector_s
double lineoutLength; double lineoutLength;
#endif // ----- end special tricks ----- #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! // This points to the master's floorheight, so it can be changed in realtime!
fixed_t *gravity; // per-sector gravity fixed_t *gravity; // per-sector gravity
boolean verticalflip; // If gravity < 0, then allow flipped physics boolean verticalflip; // If gravity < 0, then allow flipped physics
@ -337,6 +384,13 @@ typedef struct sector_s
precipmobj_t *preciplist; precipmobj_t *preciplist;
struct mprecipsecnode_s *touching_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! // these are saved for netgames, so do not let Lua touch these!
// offsets sector spawned with (via linedef type 7) // offsets sector spawned with (via linedef type 7)
@ -612,6 +666,12 @@ typedef struct drawseg_s
INT16 *thicksidecol; INT16 *thicksidecol;
INT32 numthicksides; INT32 numthicksides;
fixed_t frontscale[MAXVIDWIDTH]; 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; } drawseg_t;
typedef enum typedef enum

View file

@ -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_source; // start of a 64*64 tile image
UINT8 *ds_transmap; // one of the translucency tables 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 /** \brief Variable flat sizes
*/ */
@ -121,7 +127,7 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask;
#define METALSONIC_TT_CACHE_INDEX (MAXSKINS + 2) #define METALSONIC_TT_CACHE_INDEX (MAXSKINS + 2)
#define ALLWHITE_TT_CACHE_INDEX (MAXSKINS + 3) #define ALLWHITE_TT_CACHE_INDEX (MAXSKINS + 3)
#define SKIN_RAMP_LENGTH 16 #define SKIN_RAMP_LENGTH 16
#define DEFAULT_STARTTRANSCOLOR 160 #define DEFAULT_STARTTRANSCOLOR 96
#define NUM_PALETTE_ENTRIES 256 #define NUM_PALETTE_ENTRIES 256
static UINT8** translationtablecache[MAXSKINS + 4] = {NULL}; static UINT8** translationtablecache[MAXSKINS + 4] = {NULL};
@ -136,27 +142,31 @@ const char *Color_Names[MAXSKINCOLORS] =
"Silver", // SKINCOLOR_SILVER "Silver", // SKINCOLOR_SILVER
"Grey", // SKINCOLOR_GREY "Grey", // SKINCOLOR_GREY
"Black", // SKINCOLOR_BLACK "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 "Beige", // SKINCOLOR_BEIGE
"Peach", // SKINCOLOR_PEACH
"Brown", // SKINCOLOR_BROWN "Brown", // SKINCOLOR_BROWN
"Red", // SKINCOLOR_RED "Red", // SKINCOLOR_RED
"Dark_Red", // SKINCOLOR_DARKRED "Crimson", // SKINCOLOR_CRIMSON
"Neon_Green",// SKINCOLOR_NEONGREEN "Orange", // SKINCOLOR_ORANGE
"Green", // SKINCOLOR_GREEN "Rust", // SKINCOLOR_RUST
"Zim", // SKINCOLOR_ZIM "Gold", // SKINCOLOR_GOLD
"Olive", // SKINCOLOR_OLIVE
"Yellow", // SKINCOLOR_YELLOW "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
}; };
const UINT8 Color_Opposite[MAXSKINCOLORS*2] = const UINT8 Color_Opposite[MAXSKINCOLORS*2] =
@ -166,27 +176,31 @@ const UINT8 Color_Opposite[MAXSKINCOLORS*2] =
SKINCOLOR_GREY,4, // SKINCOLOR_SILVER SKINCOLOR_GREY,4, // SKINCOLOR_SILVER
SKINCOLOR_SILVER,12, // SKINCOLOR_GREY SKINCOLOR_SILVER,12, // SKINCOLOR_GREY
SKINCOLOR_WHITE,8, // SKINCOLOR_BLACK SKINCOLOR_WHITE,8, // SKINCOLOR_BLACK
SKINCOLOR_NONE,8, // SKINCOLOR_CYAN SKINCOLOR_BEIGE,8, // SKINCOLOR_BEIGE - needs new offset
SKINCOLOR_NONE,8, // SKINCOLOR_TEAL SKINCOLOR_BROWN,8, // SKINCOLOR_PEACH - ditto
SKINCOLOR_NONE,8, // SKINCOLOR_STEELBLUE SKINCOLOR_PEACH,8, // SKINCOLOR_BROWN - ditto
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_GREEN,5, // SKINCOLOR_RED
SKINCOLOR_NONE,8, // SKINCOLOR_DARKRED SKINCOLOR_CYAN,8, // SKINCOLOR_CRIMSON - ditto
SKINCOLOR_NONE,8, // SKINCOLOR_NEONGREEN 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_RED,11, // SKINCOLOR_GREEN
SKINCOLOR_PURPLE,3, // SKINCOLOR_ZIM SKINCOLOR_PASTEL,8, // SKINCOLOR_EMERALD - ditto
SKINCOLOR_NONE,8, // SKINCOLOR_OLIVE SKINCOLOR_ROSY,8, // SKINCOLOR_AQUA - ditto
SKINCOLOR_NONE,8, // SKINCOLOR_YELLOW SKINCOLOR_YELLOW,8, // SKINCOLOR_TEAL - ditto
SKINCOLOR_NONE,8 // SKINCOLOR_GOLD 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]; 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 0x03, // SKINCOLOR_SILVER
0x08, // SKINCOLOR_GREY 0x08, // SKINCOLOR_GREY
0x18, // SKINCOLOR_BLACK 0x18, // SKINCOLOR_BLACK
0xd0, // SKINCOLOR_CYAN 0xf0, // SKINCOLOR_BEIGE
0xdc, // SKINCOLOR_TEAL 0xd8, // SKINCOLOR_PEACH
0xc8, // SKINCOLOR_STEELBLUE 0xe0, // SKINCOLOR_BROWN
0xe2, // SKINCOLOR_BLUE 0x21, // SKINCOLOR_RED
0x40, // SKINCOLOR_PEACH 0x28, // SKINCOLOR_CRIMSON
0x48, // SKINCOLOR_TAN 0x31, // SKINCOLOR_ORANGE
0x90, // SKINCOLOR_PINK 0x3a, // SKINCOLOR_RUST
0xf8, // SKINCOLOR_LAVENDER 0x40, // SKINCOLOR_GOLD
0xc0, // SKINCOLOR_PURPLE 0x48, // SKINCOLOR_YELLOW
0x52, // SKINCOLOR_ORANGE 0x54, // SKINCOLOR_TAN
0x5c, // SKINCOLOR_ROSEWOOD 0x58, // SKINCOLOR_MOSS
0x20, // SKINCOLOR_BEIGE 0xbc, // SKINCOLOR_PERIDOT
0x30, // SKINCOLOR_BROWN 0x60, // SKINCOLOR_GREEN
0x7d, // SKINCOLOR_RED 0x70, // SKINCOLOR_EMERALD
0x85, // SKINCOLOR_DARKRED 0x78, // SKINCOLOR_AQUA
0xb8, // SKINCOLOR_NEONGREEN 0x8c, // SKINCOLOR_TEAL
0xa0, // SKINCOLOR_GREEN 0x80, // SKINCOLOR_CYAN
0xb0, // SKINCOLOR_ZIM 0x92, // SKINCOLOR_BLUE
0x69, // SKINCOLOR_OLIVE 0xaa, // SKINCOLOR_AZURE
0x67, // SKINCOLOR_YELLOW 0xa0, // SKINCOLOR_PASTEL
0x70, // SKINCOLOR_GOLD 0xa0, // SKINCOLOR_PURPLE
0xc0, // SKINCOLOR_LAVENDER
0xb3, // SKINCOLOR_MAGENTA
0xd0, // SKINCOLOR_PINK
0xc8, // SKINCOLOR_ROSY
}; };
INT32 i; INT32 i;
INT32 starttranscolor; INT32 starttranscolor;
@ -274,7 +292,7 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
if (skinnum == TC_BOSS) if (skinnum == TC_BOSS)
dest_colormap[31] = 0; dest_colormap[31] = 0;
else if (skinnum == TC_METALSONIC) else if (skinnum == TC_METALSONIC)
dest_colormap[239] = 0; dest_colormap[159] = 0;
return; return;
} }
@ -293,196 +311,339 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
{ {
case SKINCOLOR_SILVER: case SKINCOLOR_SILVER:
case SKINCOLOR_GREY: case SKINCOLOR_GREY:
case SKINCOLOR_PEACH:
case SKINCOLOR_BEIGE:
case SKINCOLOR_BROWN: case SKINCOLOR_BROWN:
case SKINCOLOR_RED:
case SKINCOLOR_GREEN: case SKINCOLOR_GREEN:
case SKINCOLOR_BLUE:
// 16 color ramp // 16 color ramp
for (i = 0; i < SKIN_RAMP_LENGTH; i++) for (i = 0; i < SKIN_RAMP_LENGTH; i++)
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i); dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i);
break; break;
case SKINCOLOR_ORANGE: case SKINCOLOR_WHITE:
// 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_CYAN: case SKINCOLOR_CYAN:
// 12 color ramp // 12 color ramp
for (i = 0; i < SKIN_RAMP_LENGTH; i++) for (i = 0; i < SKIN_RAMP_LENGTH; i++)
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (12*i/SKIN_RAMP_LENGTH)); dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (12*i/SKIN_RAMP_LENGTH));
break; break;
case SKINCOLOR_WHITE:
case SKINCOLOR_BLACK: case SKINCOLOR_BLACK:
case SKINCOLOR_STEELBLUE: case SKINCOLOR_MOSS:
case SKINCOLOR_PINK: case SKINCOLOR_EMERALD:
case SKINCOLOR_LAVENDER: case SKINCOLOR_LAVENDER:
case SKINCOLOR_PURPLE: case SKINCOLOR_PINK:
case SKINCOLOR_DARKRED:
case SKINCOLOR_ZIM:
case SKINCOLOR_YELLOW:
case SKINCOLOR_GOLD:
// 8 color ramp // 8 color ramp
for (i = 0; i < SKIN_RAMP_LENGTH; i++) for (i = 0; i < SKIN_RAMP_LENGTH; i++)
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1)); dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1));
break; break;
case SKINCOLOR_TEAL: case SKINCOLOR_BEIGE:
// 5 color ramp // 13 colors
for (i = 0; i < SKIN_RAMP_LENGTH; i++) for (i = 0; i < SKIN_RAMP_LENGTH; i++)
{ {
if (5*i/16 == 0) if (i == 15)
dest_colormap[starttranscolor + i] = 0xf7; dest_colormap[starttranscolor + i] = 0xed; // Darkest
else if (i <= 6)
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + ((i + 1) >> 1)); // Brightest
else 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; break;
case SKINCOLOR_OLIVE: case SKINCOLOR_PEACH:
// 7 color ramp // 11 colors
for (i = 0; i < SKIN_RAMP_LENGTH; i++) 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; break;
case SKINCOLOR_TAN: case SKINCOLOR_TAN:
// 16 color ramp, from two color ranges // 8 colors
for (i = 0; i < SKIN_RAMP_LENGTH/2; i++) // Peach half 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_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_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); 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);
break; break;
case SKINCOLOR_ROSEWOOD: case SKINCOLOR_PASTEL:
// 12 color ramp, from two color ranges! // 10 colors
for (i = 0; i < 6; i++) // Orange ...third? for (i = 0; i < SKIN_RAMP_LENGTH; i++)
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (12*i/SKIN_RAMP_LENGTH)); {
for (i = 0; i < 10; i++) // Rosewood two-thirds-ish if (i >= 12)
dest_colormap[starttranscolor + (i+6)] = (UINT8)(152 + (12*i/SKIN_RAMP_LENGTH)); 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; break;
case SKINCOLOR_NEONGREEN: case SKINCOLOR_PURPLE:
// Multi-color ramp // 10 colors
dest_colormap[starttranscolor] = 0xA0; // Brighter green for (i = 0; i < SKIN_RAMP_LENGTH; i++)
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))); 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; break;
// Super colors, from lightest to darkest! // Super colors, from lightest to darkest!
case SKINCOLOR_SUPER1: case SKINCOLOR_SUPER1:
// Super White // Super White
for (i = 0; i < 10; i++) for (i = 0; i < 10; i++)
dest_colormap[starttranscolor + i] = 120; // True white dest_colormap[starttranscolor + i] = (UINT8)0; // True white
for (; i < SKIN_RAMP_LENGTH; i++) // White-yellow fade for (; i < 12; i++) // White-yellow fade
dest_colormap[starttranscolor + i] = (UINT8)(96 + (i-10)); 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; break;
case SKINCOLOR_SUPER2: case SKINCOLOR_SUPER2:
// Super Bright // Super Bright
for (i = 0; i < 5; i++) // White-yellow fade dest_colormap[starttranscolor] = (UINT8)(0);
dest_colormap[starttranscolor + i] = (UINT8)(96 + i); for (i = 1; i < 4; i++) // White-yellow fade
dest_colormap[starttranscolor + 5] = 112; // Golden shine dest_colormap[starttranscolor + i] = (UINT8)(80 + (i-1));
for (i = 0; i < 8; i++) // Yellow for (; i < 6; i++) // Yellow
dest_colormap[starttranscolor + (i+6)] = (UINT8)(101 + (i>>1)); dest_colormap[starttranscolor + i] = (UINT8)(83);
for (i = 0; i < 2; i++) // With a fine golden finish! :3 for (; i < 8; i++) // Yellow
dest_colormap[starttranscolor + (i+14)] = (UINT8)(113 + i); 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; break;
case SKINCOLOR_SUPER3: case SKINCOLOR_SUPER3:
// Super Yellow // Super Yellow
for (i = 0; i < 3; i++) // White-yellow fade for (i = 0; i < 2; i++) // White-yellow fade
dest_colormap[starttranscolor + i] = (UINT8)(98 + i); dest_colormap[starttranscolor + i] = (UINT8)(81 + i);
dest_colormap[starttranscolor + 3] = 112; // Golden shine for (; i < 4; i++)
for (i = 0; i < 8; i++) // Yellow dest_colormap[starttranscolor + i] = (UINT8)(83);
dest_colormap[starttranscolor + (i+4)] = (UINT8)(101 + (i>>1)); for (; i < 6; i++) // Yellow
for (i = 0; i < 4; i++) // With a fine golden finish! :3 dest_colormap[starttranscolor + i] = (UINT8)(72);
dest_colormap[starttranscolor + (i+12)] = (UINT8)(113 + i); 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; break;
case SKINCOLOR_SUPER4: case SKINCOLOR_SUPER4:
// "The SSNTails" // "The SSNTails"
dest_colormap[starttranscolor] = 112; // Golden shine dest_colormap[starttranscolor] = 83; // Golden shine
for (i = 0; i < 8; i++) // Yellow for (i = 1; i < 3; i++) // Yellow
dest_colormap[starttranscolor + (i+1)] = (UINT8)(101 + (i>>1)); dest_colormap[starttranscolor + i] = (UINT8)(72);
for (i = 0; i < 7; i++) // With a fine golden finish! :3 for (; i < 9; i++) // Yellow
dest_colormap[starttranscolor + (i+9)] = (UINT8)(113 + i); 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; break;
case SKINCOLOR_SUPER5: case SKINCOLOR_SUPER5:
// Golden Delicious // Golden Delicious
for (i = 0; i < 8; i++) // Yellow for (i = 0; i < 2; i++) // Yellow
dest_colormap[starttranscolor + i] = (UINT8)(101 + (i>>1)); dest_colormap[starttranscolor + i] = (UINT8)(72);
for (i = 0; i < 7; i++) // With a fine golden finish! :3 for (; i < 8; i++) // Yellow
dest_colormap[starttranscolor + (i+8)] = (UINT8)(113 + i); dest_colormap[starttranscolor + i] = (UINT8)(73);
dest_colormap[starttranscolor + 15] = 155; 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; break;
// Super Tails // Super Tails and Knuckles, who really should be dummied out by now
case SKINCOLOR_TSUPER1: 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: 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: 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: 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: 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: case SKINCOLOR_KSUPER1:
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
dest_colormap[starttranscolor + i] = (UINT8)(120 + (i >> 2));
break;
case SKINCOLOR_KSUPER2: 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: case SKINCOLOR_KSUPER3:
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
dest_colormap[starttranscolor + i] = (UINT8)(120 + (i >> 1));
break;
case SKINCOLOR_KSUPER4: case SKINCOLOR_KSUPER4:
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
dest_colormap[starttranscolor + i] = (UINT8)(121 + (i >> 1));
break;
case SKINCOLOR_KSUPER5: case SKINCOLOR_KSUPER5:
for (i = 0; i < SKIN_RAMP_LENGTH; i++) for (i = 0; i < SKIN_RAMP_LENGTH; i++)
dest_colormap[starttranscolor + i] = (UINT8)(122 + (i >> 1)); dest_colormap[starttranscolor + i] = 0xFF;
break; break;
default: default:

View file

@ -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_source; // start of a 64*64 tile image
extern UINT8 *ds_transmap; 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 // Variable flat sizes
extern UINT32 nflatxshift; extern UINT32 nflatxshift;
extern UINT32 nflatyshift; extern UINT32 nflatyshift;
@ -141,6 +151,12 @@ void ASMCALL R_DrawSpan_8_MMX(void);
void R_DrawTranslatedColumn_8(void); void R_DrawTranslatedColumn_8(void);
void R_DrawTranslatedTranslucentColumn_8(void); void R_DrawTranslatedTranslucentColumn_8(void);
void R_DrawSpan_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_DrawSplat_8(void);
void R_DrawTranslucentSplat_8(void); void R_DrawTranslucentSplat_8(void);
void R_DrawTranslucentSpan_8(void); void R_DrawTranslucentSpan_8(void);

View file

@ -105,7 +105,7 @@ void R_DrawColumn_8(void)
} }
} }
#define TRANSPARENTPIXEL 247 #define TRANSPARENTPIXEL 255
void R_Draw2sMultiPatchColumn_8(void) 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 /** \brief The R_DrawSplat_8 function
Just like R_DrawSpan_8, but skips transparent pixels. Just like R_DrawSpan_8, but skips transparent pixels.
*/ */

View file

@ -114,15 +114,6 @@ INT32 viewangletox[FINEANGLES/2];
// from clipangle to -clipangle. // from clipangle to -clipangle.
angle_t xtoviewangle[MAXVIDWIDTH+1]; 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 *scalelight[LIGHTLEVELS][MAXLIGHTSCALE];
lighttable_t *scalelightfixed[MAXLIGHTSCALE]; lighttable_t *scalelightfixed[MAXLIGHTSCALE];
lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ]; lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ];
@ -316,13 +307,13 @@ angle_t R_PointToAngle(fixed_t x, fixed_t y)
x >= 0 ? x >= 0 ?
y >= 0 ? y >= 0 ?
(x > y) ? tantoangle[SlopeDiv(y,x)] : // octant 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 x > (y = -y) ? 0-tantoangle[SlopeDiv(y,x)] : // octant 8
ANGLE_270+tantoangle[SlopeDiv(x,y)] : // octant 7 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 ANGLE_90 + tantoangle[SlopeDiv(x,y)] : // octant 2
(x = -x) > (y = -y) ? ANGLE_180+tantoangle[SlopeDiv(y,x)] : // octant 4 (x = -x) > (y = -y) ? ANGLE_180+tantoangle[SlopeDiv(y,x)] : // octant 4
ANGLE_270-1-tantoangle[SlopeDiv(x,y)] : // octant 5 ANGLE_270-tantoangle[SlopeDiv(x,y)] : // octant 5
0; 0;
} }
@ -332,13 +323,13 @@ angle_t R_PointToAngle2(fixed_t pviewx, fixed_t pviewy, fixed_t x, fixed_t y)
x >= 0 ? x >= 0 ?
y >= 0 ? y >= 0 ?
(x > y) ? tantoangle[SlopeDiv(y,x)] : // octant 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 x > (y = -y) ? 0-tantoangle[SlopeDiv(y,x)] : // octant 8
ANGLE_270+tantoangle[SlopeDiv(x,y)] : // octant 7 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 ANGLE_90 + tantoangle[SlopeDiv(x,y)] : // octant 2
(x = -x) > (y = -y) ? ANGLE_180+tantoangle[SlopeDiv(y,x)] : // octant 4 (x = -x) > (y = -y) ? ANGLE_180+tantoangle[SlopeDiv(y,x)] : // octant 4
ANGLE_270-1-tantoangle[SlopeDiv(x,y)] : // octant 5 ANGLE_270-tantoangle[SlopeDiv(x,y)] : // octant 5
0; 0;
} }
@ -527,6 +518,8 @@ static void R_InitTextureMapping(void)
focallength = FixedDiv(centerxfrac, focallength = FixedDiv(centerxfrac,
FINETANGENT(FINEANGLES/4+/*cv_fov.value*/ FIELDOFVIEW/2)); FINETANGENT(FINEANGLES/4+/*cv_fov.value*/ FIELDOFVIEW/2));
focallengthf = FIXED_TO_FLOAT(focallength);
for (i = 0; i < FINEANGLES/2; i++) for (i = 0; i < FINEANGLES/2; i++)
{ {
if (FINETANGENT(i) > FRACUNIT*2) if (FINETANGENT(i) > FRACUNIT*2)
@ -1276,7 +1269,7 @@ void R_RenderPlayerView(player_t *player)
if (cv_homremoval.value == 1) if (cv_homremoval.value == 1)
V_DrawFill(0, 0, vid.width, vid.height, 31); // No HOM effect! V_DrawFill(0, 0, vid.width, vid.height, 31); // No HOM effect!
else //'development' HOM removal -- makes it blindingly obvious if HOM is spotted. 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; portalrender = 0;

View file

@ -28,6 +28,8 @@
#include "p_setup.h" // levelflats #include "p_setup.h" // levelflats
#include "p_slopes.h"
// //
// opening // opening
// //
@ -74,7 +76,7 @@ static INT32 spanstart[MAXVIDHEIGHT];
// //
// texture mapping // texture mapping
// //
static lighttable_t **planezlight; lighttable_t **planezlight;
static fixed_t planeheight; static fixed_t planeheight;
//added : 10-02-98: yslopetab is what yslope used to be, //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) if (pindex >= MAXLIGHTZ)
pindex = MAXLIGHTZ - 1; pindex = MAXLIGHTZ - 1;
#ifdef ESLOPE
if (currentplane->slope)
ds_colormap = colormaps;
else
#endif
ds_colormap = planezlight[pindex]; ds_colormap = planezlight[pindex];
if (currentplane->extra_colormap) 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, visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap, 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; visplane_t *check;
unsigned hash; unsigned hash;
#ifdef ESLOPE
if (slope); else // Don't mess with this right now if a slope is involved
#endif
if (plangle != 0) if (plangle != 0)
{ {
// Add the view offset, rotated by the plane angle. // 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 && xoff == check->xoffs && yoff == check->yoffs
&& planecolormap == check->extra_colormap && planecolormap == check->extra_colormap
&& !pfloor && !check->ffloor && check->viewz == viewz && !pfloor && !check->ffloor && check->viewz == viewz
&& check->viewangle == viewangle) && check->viewangle == viewangle
#ifdef ESLOPE
&& check->slope == slope
#endif
)
{ {
return check; return check;
} }
@ -485,6 +503,9 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
#ifdef POLYOBJECTS_PLANES #ifdef POLYOBJECTS_PLANES
check->polyobj = NULL; check->polyobj = NULL;
#endif #endif
#ifdef ESLOPE
check->slope = slope;
#endif
memset(check->top, 0xff, sizeof (check->top)); memset(check->top, 0xff, sizeof (check->top));
memset(check->bottom, 0x00, sizeof (check->bottom)); 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; new_pl->plangle = pl->plangle;
#ifdef POLYOBJECTS_PLANES #ifdef POLYOBJECTS_PLANES
new_pl->polyobj = pl->polyobj; new_pl->polyobj = pl->polyobj;
#endif
#ifdef ESLOPE
new_pl->slope = pl->slope;
#endif #endif
pl = new_pl; pl = new_pl;
pl->minx = start; pl->minx = start;
@ -726,24 +750,8 @@ 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) // 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) if (pl->polyobj->translucency >= 10)
return; // Don't even draw it return; // Don't even draw it
else if (pl->polyobj->translucency == 9) else if (pl->polyobj->translucency > 0)
ds_transmap = ((tr_trans90)<<FF_TRANSSHIFT) - 0x10000 + transtables; ds_transmap = transtables + ((pl->polyobj->translucency-1)<<FF_TRANSSHIFT);
else if (pl->polyobj->translucency == 8)
ds_transmap = ((tr_trans80)<<FF_TRANSSHIFT) - 0x10000 + transtables;
else if (pl->polyobj->translucency == 7)
ds_transmap = ((tr_trans70)<<FF_TRANSSHIFT) - 0x10000 + transtables;
else if (pl->polyobj->translucency == 6)
ds_transmap = ((tr_trans60)<<FF_TRANSSHIFT) - 0x10000 + transtables;
else if (pl->polyobj->translucency == 5)
ds_transmap = ((tr_trans50)<<FF_TRANSSHIFT) - 0x10000 + transtables;
else if (pl->polyobj->translucency == 4)
ds_transmap = ((tr_trans40)<<FF_TRANSSHIFT) - 0x10000 + transtables;
else if (pl->polyobj->translucency == 3)
ds_transmap = ((tr_trans30)<<FF_TRANSSHIFT) - 0x10000 + transtables;
else if (pl->polyobj->translucency == 2)
ds_transmap = ((tr_trans20)<<FF_TRANSSHIFT) - 0x10000 + transtables;
else if (pl->polyobj->translucency == 1)
ds_transmap = ((tr_trans10)<<FF_TRANSSHIFT) - 0x10000 + transtables;
else // Opaque, but allow transparent flat pixels else // Opaque, but allow transparent flat pixels
spanfunc = splatfunc; spanfunc = splatfunc;
@ -781,23 +789,23 @@ void R_DrawSinglePlane(visplane_t *pl)
if (pl->ffloor->alpha < 12) if (pl->ffloor->alpha < 12)
return; // Don't even draw it return; // Don't even draw it
else if (pl->ffloor->alpha < 38) else if (pl->ffloor->alpha < 38)
ds_transmap = ((tr_trans90)<<FF_TRANSSHIFT) - 0x10000 + transtables; ds_transmap = transtables + ((tr_trans90-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 64) else if (pl->ffloor->alpha < 64)
ds_transmap = ((tr_trans80)<<FF_TRANSSHIFT) - 0x10000 + transtables; ds_transmap = transtables + ((tr_trans80-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 89) else if (pl->ffloor->alpha < 89)
ds_transmap = ((tr_trans70)<<FF_TRANSSHIFT) - 0x10000 + transtables; ds_transmap = transtables + ((tr_trans70-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 115) else if (pl->ffloor->alpha < 115)
ds_transmap = ((tr_trans60)<<FF_TRANSSHIFT) - 0x10000 + transtables; ds_transmap = transtables + ((tr_trans60-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 140) else if (pl->ffloor->alpha < 140)
ds_transmap = ((tr_trans50)<<FF_TRANSSHIFT) - 0x10000 + transtables; ds_transmap = transtables + ((tr_trans50-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 166) else if (pl->ffloor->alpha < 166)
ds_transmap = ((tr_trans40)<<FF_TRANSSHIFT) - 0x10000 + transtables; ds_transmap = transtables + ((tr_trans40-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 192) else if (pl->ffloor->alpha < 192)
ds_transmap = ((tr_trans30)<<FF_TRANSSHIFT) - 0x10000 + transtables; ds_transmap = transtables + ((tr_trans30-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 217) else if (pl->ffloor->alpha < 217)
ds_transmap = ((tr_trans20)<<FF_TRANSSHIFT) - 0x10000 + transtables; ds_transmap = transtables + ((tr_trans20-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 243) else if (pl->ffloor->alpha < 243)
ds_transmap = ((tr_trans10)<<FF_TRANSSHIFT) - 0x10000 + transtables; ds_transmap = transtables + ((tr_trans10-1)<<FF_TRANSSHIFT);
else // Opaque, but allow transparent flat pixels else // Opaque, but allow transparent flat pixels
spanfunc = splatfunc; spanfunc = splatfunc;
@ -814,7 +822,11 @@ void R_DrawSinglePlane(visplane_t *pl)
else light = (pl->lightlevel >> LIGHTSEGSHIFT); else light = (pl->lightlevel >> LIGHTSEGSHIFT);
#ifndef NOWATER #ifndef NOWATER
if (pl->ffloor->flags & FF_RIPPLE) if (pl->ffloor->flags & FF_RIPPLE
#ifdef ESLOPE
&& !pl->slope
#endif
)
{ {
INT32 top, bottom; INT32 top, bottom;
@ -842,6 +854,9 @@ void R_DrawSinglePlane(visplane_t *pl)
} }
else light = (pl->lightlevel >> LIGHTSEGSHIFT); 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) if (viewangle != pl->viewangle)
{ {
memset(cachedheight, 0, sizeof (cachedheight)); memset(cachedheight, 0, sizeof (cachedheight));
@ -915,6 +930,106 @@ void R_DrawSinglePlane(visplane_t *pl)
if (light < 0) if (light < 0)
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<<nflatshiftup)+1.0f)/(1<<nflatshiftup);
xoffs *= fudge;
yoffs /= fudge;
vx = FIXED_TO_FLOAT(viewx+xoffs);
vy = FIXED_TO_FLOAT(viewy-yoffs);
vz = FIXED_TO_FLOAT(viewz);
temp = P_GetZAt(pl->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<<nflatshiftup)
ds_su.x *= SFMULT;
ds_su.y *= SFMULT;
ds_su.z *= SFMULT;
ds_sv.x *= SFMULT;
ds_sv.y *= SFMULT;
ds_sv.z *= SFMULT;
#undef SFMULT
if (spanfunc == R_DrawTranslucentSpan_8)
spanfunc = R_DrawTiltedTranslucentSpan_8;
else if (spanfunc == splatfunc)
spanfunc = R_DrawTiltedSplat_8;
else
spanfunc = R_DrawTiltedSpan_8;
planezlight = scalelight[light];
} else
#endif // ESLOPE
planezlight = zlight[light]; planezlight = zlight[light];
// set the maximum value for unsigned // set the maximum value for unsigned
@ -951,7 +1066,7 @@ using the palette colors.
if (spanfunc == R_DrawSpan_8) if (spanfunc == R_DrawSpan_8)
{ {
INT32 i; INT32 i;
ds_transmap = ((tr_trans50)<<FF_TRANSSHIFT) - 0x10000 + transtables; ds_transmap = transtables + ((tr_trans50-1)<<FF_TRANSSHIFT);
spanfunc = R_DrawTranslucentSpan_8; spanfunc = R_DrawTranslucentSpan_8;
for (i=0; i<4; i++) for (i=0; i<4; i++)
{ {

View file

@ -61,6 +61,9 @@ typedef struct visplane_s
#ifdef POLYOBJECTS_PLANES #ifdef POLYOBJECTS_PLANES
polyobj_t *polyobj; polyobj_t *polyobj;
#endif #endif
#ifdef ESLOPE
pslope_t *slope;
#endif
} visplane_t; } visplane_t;
extern visplane_t *floorplane; extern visplane_t *floorplane;
@ -79,6 +82,8 @@ extern fixed_t cachedxstep[MAXVIDHEIGHT];
extern fixed_t cachedystep[MAXVIDHEIGHT]; extern fixed_t cachedystep[MAXVIDHEIGHT];
extern fixed_t basexscale, baseyscale; extern fixed_t basexscale, baseyscale;
extern lighttable_t **planezlight;
extern fixed_t *yslope; extern fixed_t *yslope;
extern fixed_t distscale[MAXVIDWIDTH]; extern fixed_t distscale[MAXVIDWIDTH];
@ -91,7 +96,11 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2);
void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2); void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2);
void R_DrawPlanes(void); void R_DrawPlanes(void);
visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, 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 *ffloor); extracolormap_t *planecolormap, ffloor_t *ffloor
#ifdef ESLOPE
, pslope_t *slope
#endif
);
visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop); visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop);
void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop); void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop);
void R_PlaneBounds(visplane_t *plane); void R_PlaneBounds(visplane_t *plane);
@ -110,6 +119,14 @@ typedef struct planemgr_s
INT16 f_clip[MAXVIDWIDTH]; INT16 f_clip[MAXVIDWIDTH];
INT16 c_clip[MAXVIDWIDTH]; INT16 c_clip[MAXVIDWIDTH];
#ifdef ESLOPE
// For slope rendering; the height at the other end
fixed_t f_pos_slope;
fixed_t b_pos_slope;
struct pslope_s *slope;
#endif
struct ffloor_s *ffloor; struct ffloor_s *ffloor;
#ifdef POLYOBJECTS_PLANES #ifdef POLYOBJECTS_PLANES
polyobj_t *polyobj; polyobj_t *polyobj;

File diff suppressed because it is too large Load diff

View file

@ -503,7 +503,7 @@ static void R_RenderFloorSplat(floorsplat_t *pSplat, vertex_t *verts, UINT8 *pTe
{ {
ds_x1 = x1; ds_x1 = x1;
ds_x2 = x2; ds_x2 = x2;
ds_transmap = ((tr_trans50)<<FF_TRANSSHIFT) - 0x10000 + transtables; ds_transmap = transtables + ((tr_trans50-1)<<FF_TRANSSHIFT);
splatfunc(); splatfunc();
} }

View file

@ -24,6 +24,7 @@
#include "r_plane.h" #include "r_plane.h"
#include "p_tick.h" #include "p_tick.h"
#include "p_local.h" #include "p_local.h"
#include "p_slopes.h"
#include "dehacked.h" // get_number (for thok) #include "dehacked.h" // get_number (for thok)
#include "d_netfil.h" // blargh. for nameonly(). #include "d_netfil.h" // blargh. for nameonly().
#include "m_cheat.h" // objectplace #include "m_cheat.h" // objectplace
@ -954,12 +955,22 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing)
for (i = 1; i < sector->numlights; i++) for (i = 1; i < sector->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; 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; 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) if (cutfrac < 0)
continue; continue;
if (cutfrac > vid.height) 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)); newsprite = M_Memcpy(R_NewVisSprite(), sprite, sizeof (vissprite_t));
sprite->cut |= SC_BOTTOM; sprite->cut |= SC_BOTTOM;
sprite->gz = sector->lightlist[i].height; sprite->gz = testheight;
newsprite->gzt = sprite->gz; newsprite->gzt = sprite->gz;
sprite->sz = cutfrac; sprite->sz = cutfrac;
newsprite->szt = (INT16)(sprite->sz - 1); newsprite->szt = (INT16)(sprite->sz - 1);
if (sector->lightlist[i].height < sprite->pzt && sector->lightlist[i].height > sprite->pz) if (testheight < sprite->pzt && testheight > sprite->pz)
sprite->pz = newsprite->pzt = sector->lightlist[i].height; sprite->pz = newsprite->pzt = testheight;
else else
{ {
newsprite->pz = newsprite->gz; newsprite->pz = newsprite->gz;
@ -1094,7 +1105,7 @@ static void R_ProjectSprite(mobj_t *thing)
{ {
sprdef = &((skin_t *)thing->skin)->sprites[thing->sprite2]; sprdef = &((skin_t *)thing->skin)->sprites[thing->sprite2];
if (rot >= sprdef->numframes) { 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->sprite = states[S_UNKNOWN].sprite;
thing->frame = states[S_UNKNOWN].frame; thing->frame = states[S_UNKNOWN].frame;
sprdef = &sprites[thing->sprite]; sprdef = &sprites[thing->sprite];
@ -1200,7 +1211,20 @@ static void R_ProjectSprite(mobj_t *thing)
if (thing->subsector->sector->numlights) if (thing->subsector->sector->numlights)
{ {
INT32 lightnum; 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); light = R_GetPlaneLight(thing->subsector->sector, gzt, false);
#endif
lightnum = (*thing->subsector->sector->lightlist[light].lightlevel >> LIGHTSEGSHIFT); lightnum = (*thing->subsector->sector->lightlist[light].lightlevel >> LIGHTSEGSHIFT);
if (lightnum < 0) if (lightnum < 0)
@ -1242,7 +1266,8 @@ static void R_ProjectSprite(mobj_t *thing)
vis = R_NewVisSprite(); vis = R_NewVisSprite();
vis->heightsec = heightsec; //SoM: 3/17/2000 vis->heightsec = heightsec; //SoM: 3/17/2000
vis->mobjflags = thing->flags; vis->mobjflags = thing->flags;
vis->scale = yscale + thing->info->dispoffset; //<<detailshift; vis->scale = yscale; //<<detailshift;
vis->dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15
vis->gx = thing->x; vis->gx = thing->x;
vis->gy = thing->y; vis->gy = thing->y;
vis->gz = gz; vis->gz = gz;
@ -1305,9 +1330,9 @@ static void R_ProjectSprite(mobj_t *thing)
if (!cv_translucency.value) if (!cv_translucency.value)
; // no translucency ; // no translucency
else if (thing->flags2 & MF2_SHADOW) // actually only the player should use this (temporary invisibility) else if (thing->flags2 & MF2_SHADOW) // actually only the player should use this (temporary invisibility)
vis->transmap = ((tr_trans80-1)<<FF_TRANSSHIFT) + transtables; // because now the translucency is set through FF_TRANSMASK vis->transmap = transtables + ((tr_trans80-1)<<FF_TRANSSHIFT); // because now the translucency is set through FF_TRANSMASK
else if (thing->frame & FF_TRANSMASK) else if (thing->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)) if (((thing->frame & FF_FULLBRIGHT) || (thing->flags2 & MF2_SHADOW))
&& (!vis->extra_colormap || !vis->extra_colormap->fog)) && (!vis->extra_colormap || !vis->extra_colormap->fog))
@ -1458,6 +1483,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
// store information in a vissprite // store information in a vissprite
vis = R_NewVisSprite(); vis = R_NewVisSprite();
vis->scale = yscale; //<<detailshift; vis->scale = yscale; //<<detailshift;
vis->dispoffset = 0; // Monster Iestyn: 23/11/15
vis->gx = thing->x; vis->gx = thing->x;
vis->gy = thing->y; vis->gy = thing->y;
vis->gz = gz; vis->gz = gz;
@ -1609,6 +1635,7 @@ void R_SortVisSprites(void)
vissprite_t *best = NULL; vissprite_t *best = NULL;
vissprite_t unsorted; vissprite_t unsorted;
fixed_t bestscale; fixed_t bestscale;
INT32 bestdispoffset;
if (!visspritecount) if (!visspritecount)
return; return;
@ -1639,12 +1666,19 @@ void R_SortVisSprites(void)
vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead; vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead;
for (i = 0; i < visspritecount; i++) for (i = 0; i < visspritecount; i++)
{ {
bestscale = INT32_MAX; bestscale = bestdispoffset = INT32_MAX;
for (ds = unsorted.next; ds != &unsorted; ds = ds->next) for (ds = unsorted.next; ds != &unsorted; ds = ds->next)
{ {
if (ds->scale < bestscale) if (ds->scale < bestscale)
{ {
bestscale = ds->scale; 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; best = ds;
} }
} }
@ -1761,24 +1795,34 @@ static void R_CreateDrawNodes(void)
{ {
if (r2->plane) if (r2->plane)
{ {
fixed_t planeobjectz, planecameraz;
if (r2->plane->minx > rover->x2 || r2->plane->maxx < rover->x1) if (r2->plane->minx > rover->x2 || r2->plane->maxx < rover->x1)
continue; continue;
if (rover->szt > r2->plane->low || rover->sz < r2->plane->high) if (rover->szt > r2->plane->low || rover->sz < r2->plane->high)
continue; 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) if (rover->mobjflags & MF_NOCLIPHEIGHT)
{ {
//Objects with NOCLIPHEIGHT can appear halfway in. //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; continue;
if (r2->plane->height > viewz && rover->pzt-(rover->thingheight/2) <= r2->plane->height) if (planecameraz > viewz && rover->pzt-(rover->thingheight/2) <= planeobjectz)
continue; continue;
} }
else else
{ {
if (r2->plane->height < viewz && rover->pz >= r2->plane->height) if (planecameraz < viewz && rover->pz >= planeobjectz)
continue; continue;
if (r2->plane->height > viewz && rover->pzt <= r2->plane->height) if (planecameraz > viewz && rover->pzt <= planeobjectz)
continue; continue;
} }
@ -1808,6 +1852,7 @@ static void R_CreateDrawNodes(void)
} }
else if (r2->thickseg) else if (r2->thickseg)
{ {
fixed_t topplaneobjectz, topplanecameraz, botplaneobjectz, botplanecameraz;
if (rover->x1 > r2->thickseg->x2 || rover->x2 < r2->thickseg->x1) if (rover->x1 > r2->thickseg->x2 || rover->x2 < r2->thickseg->x1)
continue; continue;
@ -1818,9 +1863,25 @@ static void R_CreateDrawNodes(void)
if (scale <= rover->scale) if (scale <= rover->scale)
continue; continue;
if ((*r2->ffloor->topheight > viewz && *r2->ffloor->bottomheight < viewz) || #ifdef ESLOPE
(*r2->ffloor->topheight < viewz && rover->gzt < *r2->ffloor->topheight) || if (*r2->ffloor->t_slope) {
(*r2->ffloor->bottomheight > viewz && rover->gz > *r2->ffloor->bottomheight)) 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 = R_CreateDrawNode(NULL);
(entry->prev = r2->prev)->next = entry; (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) if (r2->sprite->szt > rover->sz || r2->sprite->sz < rover->szt)
continue; 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 = R_CreateDrawNode(NULL);
(entry->prev = r2->prev)->next = entry; (entry->prev = r2->prev)->next = entry;
@ -2039,21 +2101,21 @@ void R_ClipSprites(void)
if (spr->gzt <= ds->tsilheight) if (spr->gzt <= ds->tsilheight)
silhouette &= ~SIL_TOP; silhouette &= ~SIL_TOP;
if (silhouette == 1) if (silhouette == SIL_BOTTOM)
{ {
// bottom sil // bottom sil
for (x = r1; x <= r2; x++) for (x = r1; x <= r2; x++)
if (spr->clipbot[x] == -2) if (spr->clipbot[x] == -2)
spr->clipbot[x] = ds->sprbottomclip[x]; spr->clipbot[x] = ds->sprbottomclip[x];
} }
else if (silhouette == 2) else if (silhouette == SIL_TOP)
{ {
// top sil // top sil
for (x = r1; x <= r2; x++) for (x = r1; x <= r2; x++)
if (spr->cliptop[x] == -2) if (spr->cliptop[x] == -2)
spr->cliptop[x] = ds->sprtopclip[x]; spr->cliptop[x] = ds->sprtopclip[x];
} }
else if (silhouette == 3) else if (silhouette == (SIL_TOP|SIL_BOTTOM))
{ {
// both // both
for (x = r1; x <= r2; x++) for (x = r1; x <= r2; x++)
@ -2234,7 +2296,7 @@ static void Sk_SetDefaultValue(skin_t *skin)
strncpy(skin->face, "MISSING", 8); strncpy(skin->face, "MISSING", 8);
strncpy(skin->superface, "MISSING", 8); strncpy(skin->superface, "MISSING", 8);
skin->starttranscolor = 160; skin->starttranscolor = 96;
skin->prefcolor = SKINCOLOR_GREEN; skin->prefcolor = SKINCOLOR_GREEN;
skin->normalspeed = 36<<FRACBITS; skin->normalspeed = 36<<FRACBITS;
@ -2603,9 +2665,6 @@ next_token:
} }
free(buf2); free(buf2);
if (skin != &skins[0])
skin->flags &= ~SF_SUPER;
// Add sprites // Add sprites
{ {
UINT16 z; UINT16 z;

View file

@ -162,6 +162,7 @@ typedef struct vissprite_s
boolean precip; boolean precip;
boolean vflip; // Flip vertically boolean vflip; // Flip vertically
boolean isScaled; boolean isScaled;
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
} vissprite_t; } vissprite_t;
// A drawnode is something that points to a 3D floor, 3D side, or masked // A drawnode is something that points to a 3D floor, 3D side, or masked

View file

@ -141,14 +141,6 @@ typedef struct
static channel_t *channels = NULL; static channel_t *channels = NULL;
static INT32 numofchannels = 0; 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. // Internals.
// //
@ -307,47 +299,6 @@ static void SetChannelsNum(void)
channels[i].sfxinfo = 0; 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 // Retrieve the lump number of sfx
// //
@ -371,12 +322,6 @@ lumpnum_t S_GetSfxLumpNum(sfxinfo_t *sfx)
return W_GetNumForName("dsthok"); 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. // Stop all sounds, load level info, THEN start sounds.
void S_StopSounds(void) 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) void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
{ {
INT32 sep, pitch, priority, cnum; 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 // 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++) for (cnum = 0; cnum < numofchannels; cnum++)
{ {
c = &channels[cnum]; c = &channels[cnum];
@ -984,37 +844,6 @@ void S_UpdateSounds(void)
I_UpdateSound(); 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) void S_SetSfxVolume(INT32 volume)
{ {
if (volume < 0 || volume > 31) if (volume < 0 || volume > 31)
@ -1031,137 +860,6 @@ void S_SetSfxVolume(INT32 volume)
#endif #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) void S_ClearSfx(void)
{ {
#ifndef DJGPPDOS #ifndef DJGPPDOS
@ -1452,3 +1150,285 @@ void S_StartSoundName(void *mo, const char *soundname)
S_StartSound(mo, soundnum); 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();
}

View file

@ -48,9 +48,6 @@ typedef enum
extern consvar_t play_mode; extern consvar_t play_mode;
#endif #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 typedef enum
{ {
SF_TOTALLYSINGLE = 1, // Only play one of these sounds at a time...GLOBALLY 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 <origin> // Stop sound for thing at <origin>
void S_StopSound(void *origin); void S_StopSound(void *origin);
// Start music using <music_id> from sounds.h, and set whether looping // Start music track, arbitrary, given its name, and set whether looping
// note: music slot is first 16 bits for songnum, // note: music flags 12 bits for tracknum (gme, other formats with more than one track)
// next 15 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) // 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 // Set Speed of Music
boolean S_SpeedMusic(float speed); boolean S_SpeedMusic(float speed);
@ -113,8 +111,8 @@ boolean S_SpeedMusic(float speed);
void S_StopMusic(void); void S_StopMusic(void);
// Stop and resume music, during game PAUSE. // Stop and resume music, during game PAUSE.
void S_PauseSound(void); void S_PauseAudio(void);
void S_ResumeSound(void); void S_ResumeAudio(void);
// //
// Updates music & sounds // Updates music & sounds
@ -141,4 +139,10 @@ void S_StopSoundByNum(sfxenum_t sfxnum);
#define S_StartScreamSound S_StartSound #define S_StartScreamSound S_StartSound
#endif #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 #endif

View file

@ -117,7 +117,7 @@ if(${SDL2_FOUND})
add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32 ${SRB2_SDL2_TOTAL_SOURCES}) add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32 ${SRB2_SDL2_TOTAL_SOURCES})
set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME ${SRB2_SDL2_EXE_NAME}) 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(CoreFoundation SRB2SDL2)
add_framework(SDL2 SRB2SDL2) add_framework(SDL2 SRB2SDL2)
add_framework(SDL2_mixer SRB2SDL2) add_framework(SDL2_mixer SRB2SDL2)
@ -224,7 +224,7 @@ if(${SDL2_FOUND})
endif() endif()
#### Installation #### #### Installation ####
if (CLANG) if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
install(TARGETS SRB2SDL2 install(TARGETS SRB2SDL2
BUNDLE DESTINATION . BUNDLE DESTINATION .
) )
@ -265,7 +265,7 @@ if(${SDL2_FOUND})
# Mac bundle fixup # Mac bundle fixup
if(CLANG) if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
install(CODE " install(CODE "
include(BundleUtilities) include(BundleUtilities)
fixup_bundle(\"${CMAKE_INSTALL_PREFIX}/Sonic Robo Blast 2.app\" fixup_bundle(\"${CMAKE_INSTALL_PREFIX}/Sonic Robo Blast 2.app\"

View file

@ -119,6 +119,12 @@ ifdef SDL_NET
SDL_LDFLAGS+=-lSDL2_net SDL_LDFLAGS+=-lSDL2_net
endif endif
ifdef MINGW
ifndef NOSDLMAIN
SDLMAIN=1
endif
endif
ifdef SDLMAIN ifdef SDLMAIN
OPTS+=-DSDLMAIN OPTS+=-DSDLMAIN
else else

View file

@ -55,6 +55,10 @@ PSP_MAIN_THREAD_STACK_SIZE_KB(256);
#include "i_ttf.h" #include "i_ttf.h"
#endif #endif
#if defined (_WIN32) && !defined (main)
//#define SDLMAIN
#endif
#ifdef SDLMAIN #ifdef SDLMAIN
#include "SDL_main.h" #include "SDL_main.h"
#elif defined(FORCESDLMAIN) #elif defined(FORCESDLMAIN)
@ -132,7 +136,6 @@ static inline VOID MakeCodeWritable(VOID)
\return int \return int
*/ */
FUNCNORETURN
#if defined (_XBOX) && defined (__GNUC__) #if defined (_XBOX) && defined (__GNUC__)
void XBoxStartup() void XBoxStartup()
{ {
@ -141,8 +144,10 @@ void XBoxStartup()
myargv = NULL; myargv = NULL;
#else #else
#ifdef FORCESDLMAIN #ifdef FORCESDLMAIN
FUNCNORETURN
int SDL_main(int argc, char **argv) int SDL_main(int argc, char **argv)
#else #else
FUNCNORETURN
int main(int argc, char **argv) int main(int argc, char **argv)
#endif #endif
{ {

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