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/watcom/watcom_f.mak -crlf -whitespace
/libs/zlib/watcom/watcom_l.mak -crlf -whitespace
#Appveyor
/appveyor.yml -crlf -whitespace
# 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

@ -23,13 +23,13 @@ endfunction()
# Macro to add OSX framework
macro(add_framework fwname appname)
find_library(FRAMEWORK_${fwname}
NAMES ${fwname}
PATHS ${CMAKE_OSX_SYSROOT}/System/Library
${CMAKE_OSX_SYSROOT}/Library
/System/Library
/Library
PATH_SUFFIXES Frameworks
NO_DEFAULT_PATH)
NAMES ${fwname}
PATHS ${CMAKE_OSX_SYSROOT}/System/Library
${CMAKE_OSX_SYSROOT}/Library
/System/Library
/Library
ATH_SUFFIXES Frameworks
NO_DEFAULT_PATH)
if( ${FRAMEWORK_${fwname}} STREQUAL FRAMEWORK_${fwname}-NOTFOUND)
MESSAGE(ERROR ": Framework ${fwname} not found")
else()
@ -80,9 +80,6 @@ endif()
if(${CMAKE_SYSTEM} MATCHES "Darwin")
add_definitions(-DMACOSX)
if(${CMAKE_C_COMPILER_ID} MATCHES "Clang")
set(CLANG ON)
endif()
endif()
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
@ -103,7 +100,8 @@ set(GIT_EXECUTABLE "git" CACHE FILEPATH "Path to git binary")
include(GitUtilities)
git_describe(SRB2_GIT_DESCRIBE "${CMAKE_SOURCE_DIR}")
git_current_branch(SRB2_GIT_BRANCH "${CMAKE_SOURCE_DIR}")
set(SRB2_COMP_REVISION "${SRB2_GIT_DESCRIBE}-<${SRB2_GIT_BRANCH}>")
set(SRB2_COMP_BRANCH "${SRB2_GIT_BRANCH}")
set(SRB2_COMP_REVISION "${SRB2_GIT_DESCRIBE}")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/src/config.h)
##### PACKAGE CONFIGURATION #####

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)
PACKAGE := $(shell cat $(DIR)/debian/control | grep 'Package:' | sed -e 's/Package: //g')
DATAFILES := drill.dta music.dta soar.dta zones.dta player.dta rings.wpn srb2.wad
DATAFILES := srb2.srb zones.dta player.dta rings.dta music.dta
DATADIR := usr/games/SRB2
RESOURCEDIR := .
@ -48,7 +48,7 @@ build:
# This will need to be updated every time SRB2 official version is
# Copy data files to their install locations, and add data files to include-binaries
for file in $(DATAFILES); do \
$(WGET) http://alam.srb2.org/SRB2/2.0.6-Final/Resources/$$file; \
$(WGET) http://alam.srb2.org/SRB2/2.1.14-Final/Resources/$$file; \
if test "$$file" = "srb2.wad"; then \
$(INSTALL) $(RESOURCEDIR)/$$file $(DIR)/debian/tmp/$(DATADIR)/srb2.srb; \
else \

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,6 +1,6 @@
# Find SDL2
# Once done, this will define
#
#
# SDL2_FOUND - system has SDL2
# SDL2_INCLUDE_DIRS - SDL2 include directories
# SDL2_LIBRARIES - link libraries

View File

@ -1,6 +1,6 @@
# Find SDL2
# Once done, this will define
#
#
# SDL2_MAIN_FOUND - system has SDL2
# SDL2_MAIN_INCLUDE_DIRS - SDL2 include directories
# SDL2_MAIN_LIBRARIES - link libraries

View File

@ -1,6 +1,6 @@
# Find SDL2
# Once done, this will define
#
#
# SDL2_MIXER_FOUND - system has SDL2
# SDL2_MIXER_INCLUDE_DIRS - SDL2 include directories
# SDL2_MIXER_LIBRARIES - link libraries

View File

@ -123,7 +123,7 @@ function (libfind_process PREFIX)
set(includeopts ${${PREFIX}_PROCESS_INCLUDES})
set(libraryopts ${${PREFIX}_PROCESS_LIBS})
# Process deps to add to
# Process deps to add to
foreach (i ${PREFIX} ${${PREFIX}_DEPENDENCIES})
if (DEFINED ${i}_INCLUDE_OPTS OR DEFINED ${i}_LIBRARY_OPTS)
# The package seems to export option lists that we can use, woohoo!
@ -146,11 +146,11 @@ function (libfind_process PREFIX)
endif()
endif()
endforeach()
if (includeopts)
list(REMOVE_DUPLICATES includeopts)
endif()
if (libraryopts)
list(REMOVE_DUPLICATES libraryopts)
endif()
@ -215,7 +215,7 @@ function (libfind_process PREFIX)
set (${PREFIX}_LIBRARIES ${libs} PARENT_SCOPE)
set (${PREFIX}_FOUND TRUE PARENT_SCOPE)
endif()
return()
return()
endif()
# Format messages for debug info and the type of error

View File

@ -1,10 +1,32 @@
@ECHO OFF
set REV=Unknown
set BRA=Unknown
set REV=illegal
copy nul: /b +%1\comptime.c tmp.$$$ > nul
move tmp.$$$ %1\comptime.c > nul
SET REV=illegal
FOR /F "usebackq" %%s IN (`svnversion %1`) DO @SET REV=%%s
if exist .git goto gitrev
if exist ..\.git goto gitrev
if exist .svn goto svnrev
goto filwri
:gitrev
set GIT=%2
if "%GIT%"=="" set GIT=git
FOR /F "usebackq" %%s IN (`%GIT% rev-parse --abbrev-ref HEAD`) DO @SET BRA=%%s
FOR /F "usebackq" %%s IN (`%GIT% rev-parse HEAD`) DO @SET REV=%%s
set REV=%REV:~0,8%
goto filwri
:svnrev
set BRA=Subversion
FOR /F "usebackq" %%s IN (`svnversion .`) DO @SET REV=%%s
set REV=r%REV%
goto filwri
:filwri
ECHO // Do not edit! This file was autogenerated > %1\comptime.h
ECHO // by the %0 batch file >> %1\comptime.h
ECHO // >> %1\comptime.h
ECHO const char* comprevision = "r%REV%"; >> %1\comptime.h
ECHO const char* compbranch = "%BRA%"; >> %1\comptime.h
ECHO const char* comprevision = "%REV%"; >> %1\comptime.h

View File

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

14
debian/control vendored
View File

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

17
debian/rules vendored
View File

@ -59,16 +59,18 @@ DBGNAME = debug/$(EXENAME)
PKGDIR = usr/games
DBGDIR = usr/lib/debug/$(PKGDIR)
PIXMAPS_DIR = usr/share/pixmaps
DESKTOP_DIR = usr/share/applications
PREFIX = $(shell test "$(CROSS_COMPILE_BUILD)" != "$(CROSS_COMPILE_HOST)" && echo "PREFIX=$(CROSS_COMPILE_HOST)")
OS = LINUX=1
NONX86 = $(shell test "`echo $(CROSS_COMPILE_HOST) | grep 'i[3-6]86'`" || echo "NONX86=1")
MAKEARGS = $(OS) $(NONX86) $(PREFIX) EXENAME=$(EXENAME) DBGNAME=$(DBGNAME) SDL_PKGCONFIG=sdl PNG_PKGCONFIG=libpng NOOBJDUMP=1
MAKEARGS = $(OS) $(NONX86) $(PREFIX) EXENAME=$(EXENAME) DBGNAME=$(DBGNAME) SDL_PKGCONFIG=sdl2 PNG_PKGCONFIG=libpng NOOBJDUMP=1
MENUFILE1 = ?package($(PACKAGE)):needs="X11" section="$(SECTION)"
MENUFILE2 = title="$(TITLE)" command="/$(PKGDIR)/$(PACKAGE)"
# FIXME pkg-config dir hacks
export PKG_CONFIG_LIBDIR = /usr/$(CROSS_COMPILE_HOST)/lib/pkgconfig
export PKG_CONFIG_LIBDIR = /usr/lib/$(CROSS_COMPILE_HOST)/pkgconfig
BINDIR := $(DIR)/bin/Linux/Release
LDFLAGS += "-Wl,-rpath=/usr/$(CROSS_COMPILE_HOST)/lib/"
LDFLAGS += "-Wl,-rpath=/usr/lib/$(CROSS_COMPILE_HOST)"
build:
$(MKDIR) $(BINDIR)/debug
@ -80,14 +82,23 @@ binary-indep:
echo "no need to do any arch-independent stuff"
binary-arch:
# create ddirs
$(MKDIR) $(DIR)/debian/tmp/$(PKGDIR) $(DIR)/debian/tmp/$(DBGDIR)
$(MKDIR) $(DIR)/debian/tmp/$(PKGDIR) $(DIR)/debian/tmp/$(DESKTOP_DIR)
$(MKDIR) $(DIR)/debian/tmp/$(PKGDIR) $(DIR)/debian/tmp/$(PIXMAPS_DIR)
# install main binaries
$(INSTALL) $(BINDIR)/$(EXENAME) $(DIR)/debian/tmp/$(PKGDIR)/$(PACKAGE)
$(INSTALL) $(BINDIR)/$(DBGNAME) $(DIR)/debian/tmp/$(DBGDIR)/$(PACKAGE)
# Install desktop file and banner image
$(INSTALL) $(DIR)/srb2.png $(DIR)/debian/tmp/usr/share/pixmaps
$(INSTALL) $(DIR)/debian/srb2.desktop $(DIR)/debian/tmp/usr/share/applications
# add compiled binaries to include-binaries
echo $(BINDIR)/$(EXENAME) >> $(DIR)/debian/source/include-binaries
echo $(BINDIR)/$(EXENAME) >> $(DIR)/debian/source/include-binaries
# Generate install folder files
echo $(PKGDIR) > $(DIR)/debian/$(PACKAGE).install
echo $(DESKTOP_DIR) >> $(DIR)/debian/$(PACKAGE).install
echo $(PIXMAPS_DIR) >> $(DIR)/debian/$(PACKAGE).install
echo $(DBGDIR) > $(DIR)/debian/$(DBGPKG).install
binary: binary-arch

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_setup.c
p_sight.c
p_slopes.c
p_spec.c
p_telept.c
p_tick.c
@ -162,11 +163,12 @@ set(SRB2_CORE_GAME_SOURCES
p_pspr.h
p_saveg.h
p_setup.h
p_slopes.h
p_spec.h
p_tick.h
)
if(NOT CLANG)
if(NOT (CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
set(SRB2_CORE_SOURCES ${SRB2_CORE_SOURCES} string.c)
endif()
@ -404,10 +406,14 @@ endif()
# Compatibility flag with later versions of GCC
# We should really fix our code to not need this
if(NOT CLANG AND NOT MSVC)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -mno-ms-bitfields)
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -Wno-absolute-value)
endif()
add_definitions(-DCMAKECONFIG)
#add_library(SRB2Core STATIC
@ -429,4 +435,4 @@ endif()
if(NOT ${SRB2_SDL2_AVAILABLE} AND NOT ${SRB2_WIN32_AVAILABLE})
message(FATAL_ERROR "There are no targets available to build an SRB2 executable. :(")
endif()
endif()

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1129,10 +1129,10 @@ void D_SRB2Main(void)
#ifndef DEVELOP // md5s last updated 12/14/14
// Check MD5s of autoloaded files
W_VerifyFileMD5(0, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad
W_VerifyFileMD5(1, ASSET_HASH_ZONES_DTA); // zones.dta
W_VerifyFileMD5(2, ASSET_HASH_PLAYER_DTA); // player.dta
W_VerifyFileMD5(3, ASSET_HASH_RINGS_DTA); // rings.dta
//W_VerifyFileMD5(0, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad
//W_VerifyFileMD5(1, ASSET_HASH_ZONES_DTA); // zones.dta
//W_VerifyFileMD5(2, ASSET_HASH_PLAYER_DTA); // player.dta
//W_VerifyFileMD5(3, ASSET_HASH_RINGS_DTA); // rings.dta
//W_VerifyFileMD5(4, "0c66790502e648bfce90fdc5bb15722e"); // patch.dta
// don't check music.dta because people like to modify it, and it doesn't matter if they do
// ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for.

View File

@ -1854,10 +1854,10 @@ static void Got_Pause(UINT8 **cp, INT32 playernum)
if (paused)
{
if (!menuactive || netgame)
S_PauseSound();
S_PauseAudio();
}
else
S_ResumeSound();
S_ResumeAudio();
}
}
@ -3179,7 +3179,11 @@ static void Command_ListWADS_f(void)
*/
static void Command_Version_f(void)
{
#ifdef DEVELOP
CONS_Printf("Sonic Robo Blast 2 %s-%s (%s %s)\n", compbranch, comprevision, compdate, comptime);
#else
CONS_Printf("Sonic Robo Blast 2 %s (%s %s %s)\n", VERSIONSTRING, compdate, comptime, comprevision);
#endif
}
#ifdef UPDATE_ALERT
@ -3757,50 +3761,66 @@ static void Command_Displayplayer_f(void)
static void Command_Tunes_f(void)
{
const char *tunearg;
UINT16 tune, track = 0;
UINT16 tunenum, track = 0;
const size_t argc = COM_Argc();
if (argc < 2) //tunes slot ...
{
CONS_Printf("tunes <slot #/map name/\"default\"> <speed> <track>:\n");
CONS_Printf(M_GetText("Play a music slot at a set speed (\"1\" being normal speed).\n"));
CONS_Printf(M_GetText("If the format supports multiple songs, you can specify which one to play.\n"));
CONS_Printf(M_GetText("The current tune is: %d\nThe current track is: %d\n"),
(mapmusic & MUSIC_SONGMASK), ((mapmusic & MUSIC_TRACKMASK) >> MUSIC_TRACKSHIFT));
CONS_Printf("tunes <name/num> [track] [speed] / <-show> / <-default> / <-none>:\n");
CONS_Printf(M_GetText("Play an arbitrary music lump. If a map number is used, 'MAP##M' is played.\n"));
CONS_Printf(M_GetText("If the format supports multiple songs, you can specify which one to play.\n\n"));
CONS_Printf(M_GetText("* With \"-show\", shows the currently playing tune and track.\n"));
CONS_Printf(M_GetText("* With \"-default\", returns to the default music for the map.\n"));
CONS_Printf(M_GetText("* With \"-none\", any music playing will be stopped.\n"));
return;
}
tunearg = COM_Argv(1);
tune = (UINT16)atoi(tunearg);
tunenum = (UINT16)atoi(tunearg);
track = 0;
if (!strcasecmp(tunearg, "default"))
if (!strcasecmp(tunearg, "-show"))
{
tune = mapheaderinfo[gamemap-1]->musicslot;
track = mapheaderinfo[gamemap-1]->musicslottrack;
}
else if (toupper(tunearg[0]) >= 'A' && toupper(tunearg[0]) <= 'Z')
tune = (UINT16)M_MapNumber(tunearg[0], tunearg[1]);
if (tune >= NUMMUSIC)
{
CONS_Alert(CONS_NOTICE, M_GetText("Valid slots are 1 to %d, or 0 to stop music\n"), NUMMUSIC - 1);
CONS_Printf(M_GetText("The current tune is: %s [track %d]\n"),
mapmusname, (mapmusflags & MUSIC_TRACKMASK));
return;
}
if (argc > 3)
track = (UINT16)atoi(COM_Argv(3))-1;
mapmusic = tune | (track << MUSIC_TRACKSHIFT);
if (tune == mus_None)
if (!strcasecmp(tunearg, "-none"))
{
S_StopMusic();
else
S_ChangeMusic(mapmusic, true);
return;
}
else if (!strcasecmp(tunearg, "-default"))
{
tunearg = mapheaderinfo[gamemap-1]->musname;
track = mapheaderinfo[gamemap-1]->mustrack;
}
else if (!tunearg[2] && toupper(tunearg[0]) >= 'A' && toupper(tunearg[0]) <= 'Z')
tunenum = (UINT16)M_MapNumber(tunearg[0], tunearg[1]);
if (tunenum && tunenum >= 1036)
{
CONS_Alert(CONS_NOTICE, M_GetText("Valid music slots are 1 to 1035.\n"));
return;
}
if (!tunenum && strlen(tunearg) > 6) // This is automatic -- just show the error just in case
CONS_Alert(CONS_NOTICE, M_GetText("Music name too long - truncated to six characters.\n"));
if (argc > 2)
track = (UINT16)atoi(COM_Argv(2))-1;
if (tunenum)
snprintf(mapmusname, 7, "%sM", G_BuildMapName(tunenum));
else
strncpy(mapmusname, tunearg, 7);
mapmusname[6] = 0;
mapmusflags = (track & MUSIC_TRACKMASK);
S_ChangeMusic(mapmusname, mapmusflags, true);
if (argc > 3)
{
float speed = (float)atof(COM_Argv(2));
float speed = (float)atof(COM_Argv(3));
if (speed > 0.0f)
S_SpeedMusic(speed);
}

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -142,8 +142,10 @@ extern FILE *logstream;
#ifdef DEVELOP
#define VERSION 0 // Game version
#define SUBVERSION 0 // more precise version number
#define VERSIONSTRING "Trunk"
#define VERSIONSTRINGW L"Trunk"
#define VERSIONSTRING "Development EXE"
#define VERSIONSTRINGW L"Development EXE"
// most interface strings are ignored in development mode.
// we use comprevision and compbranch instead.
#else
#define VERSION 202 // Game version
#define SUBVERSION 0 // more precise version number
@ -208,13 +210,6 @@ extern FILE *logstream;
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
#define MODVERSION 20
// some tests, enable or disable it if it run or not
#define SPLITSCREEN
// =========================================================================
// The maximum number of players, multiplayer/networking.
@ -232,27 +227,31 @@ typedef enum
SKINCOLOR_SILVER,
SKINCOLOR_GREY,
SKINCOLOR_BLACK,
SKINCOLOR_CYAN,
SKINCOLOR_TEAL,
SKINCOLOR_STEELBLUE,
SKINCOLOR_BLUE,
SKINCOLOR_PEACH,
SKINCOLOR_TAN,
SKINCOLOR_PINK,
SKINCOLOR_LAVENDER,
SKINCOLOR_PURPLE,
SKINCOLOR_ORANGE,
SKINCOLOR_ROSEWOOD,
SKINCOLOR_BEIGE,
SKINCOLOR_PEACH,
SKINCOLOR_BROWN,
SKINCOLOR_RED,
SKINCOLOR_DARKRED,
SKINCOLOR_NEONGREEN,
SKINCOLOR_GREEN,
SKINCOLOR_ZIM,
SKINCOLOR_OLIVE,
SKINCOLOR_YELLOW,
SKINCOLOR_CRIMSON,
SKINCOLOR_ORANGE,
SKINCOLOR_RUST,
SKINCOLOR_GOLD,
SKINCOLOR_YELLOW,
SKINCOLOR_TAN,
SKINCOLOR_MOSS,
SKINCOLOR_PERIDOT,
SKINCOLOR_GREEN,
SKINCOLOR_EMERALD,
SKINCOLOR_AQUA,
SKINCOLOR_TEAL,
SKINCOLOR_CYAN,
SKINCOLOR_BLUE,
SKINCOLOR_AZURE,
SKINCOLOR_PASTEL,
SKINCOLOR_PURPLE,
SKINCOLOR_LAVENDER,
SKINCOLOR_MAGENTA,
SKINCOLOR_PINK,
SKINCOLOR_ROSY,
// Careful! MAXSKINCOLORS cannot be greater than 0x20!
MAXSKINCOLORS,
@ -350,11 +349,7 @@ void CONS_Debug(INT32 debugflags, const char *fmt, ...) FUNCDEBUG;
#include "m_swap.h"
// Things that used to be in dstrings.h
#define DEVMAPS "devmaps"
#define DEVDATA "devdata"
#define SAVEGAMENAME "srb2sav"
char savegamename[256];
// m_misc.h
@ -426,7 +421,7 @@ INT32 I_GetKey(void);
#endif
// Compile date and time and revision.
extern const char *compdate, *comptime, *comprevision;
extern const char *compdate, *comptime, *comprevision, *compbranch;
// Disabled code and code under testing
// None of these that are disabled in the normal build are guaranteed to work perfectly
@ -436,8 +431,8 @@ extern const char *compdate, *comptime, *comprevision;
/// \note obsoleted by cv_maxportals
//#define PORTAL_LIMIT 8
/// Fun experimental slope stuff!
//#define SLOPENESS
/// Kalaron/Eternity Engine slope code (SRB2CB ported)
#define ESLOPE
/// Delete file while the game is running.
/// \note EXTREMELY buggy, tends to crash game.
@ -455,10 +450,6 @@ extern const char *compdate, *comptime, *comprevision;
/// Polyobject fake flat code
#define POLYOBJECTS_PLANES
/// Blue spheres for future use.
/// \todo Remove this define.
#define BLUE_SPHERES // Blue spheres for future use.
/// Improved way of dealing with ping values and a ping limit.
#define NEWPING
@ -496,4 +487,8 @@ extern const char *compdate, *comptime, *comprevision;
/// Experimental tweaks to analog mode. (Needs a lot of work before it's ready for primetime.)
//#define REDSANALOG
/// Backwards compatibility with musicslots.
/// \note You should leave this enabled unless you're working with a future SRB2 version.
#define MUSICSLOT_COMPATIBILITY
#endif // __DOOMDEF__

View File

@ -31,15 +31,11 @@
// Selected by user.
extern INT16 gamemap;
// ----------------xxxxxxxxxxxxxxxx = music slot
// -xxxxxxxxxxxxxxx---------------- = track slot
// x------------------------------- = reset music bit
extern UINT32 mapmusic;
#define MUSIC_TRACKSHIFT 16
#define MUSIC_SONGMASK 0x0000FFFF
#define MUSIC_TRACKMASK 0x7FFF0000
#define MUSIC_RELOADRESET 0x80000000
extern char mapmusname[7];
extern UINT16 mapmusflags;
#define MUSIC_TRACKMASK 0x0FFF // ----************
#define MUSIC_RELOADRESET 0x8000 // *---------------
// Use other bits if necessary.
extern INT16 maptol;
extern UINT8 globalweather;
@ -146,11 +142,13 @@ typedef struct
UINT16 xcoord[8];
UINT16 ycoord[8];
UINT16 picduration[8];
UINT16 musicslot;
UINT8 musicloop;
UINT16 textxpos;
UINT16 textypos;
char musswitch[7];
UINT16 musswitchflags;
UINT8 fadecolor; // Color number for fade, 0 means don't do the first fade
UINT8 fadeinid; // ID of the first fade, to a color -- ignored if fadecolor is 0
UINT8 fadeoutid; // ID of the second fade, to the new screen
@ -218,8 +216,8 @@ typedef struct
UINT8 actnum; ///< Act number or 0 for none.
UINT16 typeoflevel; ///< Combination of typeoflevel flags.
INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end.
UINT16 musicslot; ///< Music slot number to play. 0 for no music.
UINT16 musicslottrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
char musname[7]; ///< Music track to play. "" for no music.
UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore.
char forcecharacter[17]; ///< (SKINNAMESIZE+1) Skin to switch to or "" to disable.
UINT8 weather; ///< 0 = sunny day, 1 = storm, 2 = snow, 3 = rain, 4 = blank, 5 = thunder w/o rain, 6 = rain w/o lightning, 7 = heat wave.
INT16 skynum; ///< Sky number to use.

View File

@ -100,11 +100,13 @@ typedef long ssize_t;
#if defined (_MSC_VER) || defined (__OS2__)
// Microsoft VisualC++
#ifdef _MSC_VER
#if (_MSC_VER <= 1800) // MSVC 2013 and back
#define snprintf _snprintf
#if (_MSC_VER <= 1200) // MSVC 2012 and back
#define vsnprintf _vsnprintf
#endif
#endif
#endif
#define strncasecmp strnicmp
#define strcasecmp stricmp
@ -177,6 +179,8 @@ size_t strlcpy(char *dst, const char *src, size_t siz);
// not the number of bytes in the buffer.
#define STRBUFCPY(dst,src) strlcpy(dst, src, sizeof dst)
// \note __BYTEBOOL__ used to be set above if "macintosh" was defined,
// if macintosh's version of boolean type isn't needed anymore, then isn't this macro pointless now?
#ifndef __BYTEBOOL__
#define __BYTEBOOL__
@ -193,7 +197,6 @@ size_t strlcpy(char *dst, const char *src, size_t siz);
#else
typedef enum {false, true} boolean;
#endif
//#endif // __cplusplus
#endif // __BYTEBOOL__
/* 7.18.2.1 Limits of exact-width integer types */

View File

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

View File

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

View File

@ -58,6 +58,7 @@ UINT8 wipedefs[NUMWIPEDEFS] = {
0, // wipe_specinter_toblack
0, // wipe_multinter_toblack
0, // wipe_speclevel_towhite
0, // wipe_level_final
0, // wipe_intermission_final
@ -231,34 +232,52 @@ static void F_DoWipe(fademask_t *fademask)
maskx = masky = 0;
do
{
// pointer to transtable that this mask would use
transtbl = transtables + ((9 - *mask)<<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_rowend = scrxpos[maskx + 1];
draw_linestart = scrypos[masky];
draw_lineend = scrypos[masky + 1];
// DRAWING LOOP
relativepos = (draw_linestart * vid.width) + draw_rowstart;
draw_linestogo = draw_lineend - draw_linestart;
while (draw_linestogo--)
if (*mask == 0)
{
w = w_base + relativepos;
s = s_base + relativepos;
e = e_base + relativepos;
draw_rowstogo = draw_rowend - draw_rowstart;
while (draw_rowstogo--)
// shortcut - memcpy source to work
while (draw_linestogo--)
{
if (*s != *e)
*w = ((*mask == 0) ? *s : (*mask == 10) ? *e : transtbl[(*e<<8) + *s]);
++w, ++s, ++e;
M_Memcpy(w_base+relativepos, s_base+relativepos, draw_rowend-draw_rowstart);
relativepos += vid.width;
}
relativepos += vid.width;
}
// END DRAWING LOOP
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--)
{
w = w_base + relativepos;
s = s_base + relativepos;
e = e_base + relativepos;
draw_rowstogo = draw_rowend - draw_rowstart;
while (draw_rowstogo--)
*w++ = transtbl[ ( *e++ << 8 ) + *s++ ];
relativepos += vid.width;
}
// END DRAWING LOOP
}
if (++maskx >= fademask->width)
++masky, maskx = 0;

View File

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

View File

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

View File

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

View File

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

View File

@ -539,6 +539,8 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fi
static FOutVector *planeVerts = NULL;
static UINT16 numAllocedPlaneVerts = 0;
(void)sector;
// no convex poly were generated for this subsector
if (!xsub->planepoly)
return;
@ -678,25 +680,6 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fi
v3d->x = pv->x;
v3d->y = height;
v3d->z = pv->y;
#ifdef SLOPENESS
if (sector && sector->special == 65535)
{
size_t q;
for (q = 0; q < sector->linecount; q++)
{
if (v3d->x == sector->lines[q]->v1->x>>FRACBITS)
{
if (v3d->z == sector->lines[q]->v1->y>>FRACBITS)
{
v3d->y += sector->lines[q]->v1->z>>FRACBITS;
break;
}
}
}
}
#else
(void)sector;
#endif
}
// only useful for flat coloured triangles
@ -2856,7 +2839,6 @@ static void HWR_AddPolyObjectPlanes(void)
// : Draw one or more line segments.
// Notes : Sets gr_cursectorlight to the light of the parent sector, to modulate wall textures
// -----------------+
static lumpnum_t doomwaterflat; //set by R_InitFlats hack
static void HWR_Subsector(size_t num)
{
INT16 count;
@ -2867,7 +2849,6 @@ static void HWR_Subsector(size_t num)
INT32 ceilinglightlevel;
INT32 locFloorHeight, locCeilingHeight;
INT32 light = 0;
fixed_t wh;
extracolormap_t *floorcolormap;
extracolormap_t *ceilingcolormap;
@ -3193,26 +3174,6 @@ static void HWR_Subsector(size_t num)
}
}
//20/08/99: Changed by Hurdler (taken from faB's code)
#ifdef DOPLANES
// -------------------- WATER IN DEV. TEST ------------------------
//dck hack : use abs(tag) for waterheight
//ilag : Since we changed to UINT16 for sector tags, simulate INT16
if (gr_frontsector->tag > 32767)
{
wh = ((65535-gr_frontsector->tag) <<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;
}
@ -3998,6 +3959,7 @@ static void HWR_SortVisSprites(void)
gr_vissprite_t *best = NULL;
gr_vissprite_t unsorted;
float bestdist;
INT32 bestdispoffset;
if (!gr_visspritecount)
return;
@ -4025,11 +3987,19 @@ static void HWR_SortVisSprites(void)
for (i = 0; i < gr_visspritecount; i++)
{
bestdist = ZCLIP_PLANE-1;
bestdispoffset = INT32_MAX;
for (ds = unsorted.next; ds != &unsorted; ds = ds->next)
{
if (ds->tz > bestdist)
{
bestdist = ds->tz;
bestdispoffset = ds->dispoffset;
best = ds;
}
// order visprites of same scale by dispoffset, smallest first
else if (ds->tz == bestdist && ds->dispoffset < bestdispoffset)
{
bestdispoffset = ds->dispoffset;
best = ds;
}
}
@ -4653,6 +4623,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
#endif
vis->x2 = tx;
vis->tz = tz;
vis->dispoffset = thing->info->dispoffset; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST
vis->patchlumpnum = sprframe->lumppat[rot];
vis->flip = flip;
vis->mobj = thing;
@ -4769,6 +4740,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
vis->x1 = x1;
vis->x2 = tx;
vis->tz = tz;
vis->dispoffset = 0; // Monster Iestyn: 23/11/15: HARDWARE SUPPORT AT LAST
vis->patchlumpnum = sprframe->lumppat[rot];
vis->flip = flip;
vis->mobj = (mobj_t *)thing;
@ -5488,11 +5460,6 @@ void HWR_Startup(void)
HWR_AddEngineCommands();
HWR_InitTextureCache();
// for test water translucent surface
doomwaterflat = W_CheckNumForName("FWATER1");
if (doomwaterflat == LUMPERROR) // if FWATER1 not found (in doom shareware)
doomwaterflat = W_GetNumForName("WATER0");
HWR_InitMD2();
#ifdef ALAM_LIGHTING

View File

@ -41,6 +41,7 @@
#include "../r_things.h"
#include "hw_main.h"
#include "../v_video.h"
#ifdef HAVE_PNG
#ifndef _MSC_VER
@ -881,6 +882,59 @@ static void md2_loadTexture(md2_t *model)
HWR_UnlockCachedPatch(grpatch);
}
// -----------------+
// md2_loadBlendTexture : Download a pcx or png texture for blending MD2 models
// -----------------+
static void md2_loadBlendTexture(md2_t *model)
{
GLPatch_t *grpatch;
char *filename = Z_Malloc(strlen(model->filename)+7, PU_STATIC, NULL);
strcpy(filename, model->filename);
FIL_ForceExtension(filename, "_blend.png");
if (model->blendgrpatch)
{
grpatch = model->blendgrpatch;
Z_Free(grpatch->mipmap.grInfo.data);
}
else
grpatch = Z_Calloc(sizeof *grpatch, PU_HWRPATCHINFO,
&(model->blendgrpatch));
if (!grpatch->mipmap.downloaded && !grpatch->mipmap.grInfo.data)
{
int w = 0, h = 0;
#ifdef HAVE_PNG
grpatch->mipmap.grInfo.format = PNG_Load(filename, &w, &h, grpatch);
if (grpatch->mipmap.grInfo.format == 0)
#endif
grpatch->mipmap.grInfo.format = PCX_Load(filename, &w, &h, grpatch);
if (grpatch->mipmap.grInfo.format == 0)
{
Z_Free(filename);
return;
}
grpatch->mipmap.downloaded = 0;
grpatch->mipmap.flags = 0;
grpatch->width = (INT16)w;
grpatch->height = (INT16)h;
grpatch->mipmap.width = (UINT16)w;
grpatch->mipmap.height = (UINT16)h;
// not correct!
grpatch->mipmap.grInfo.smallLodLog2 = GR_LOD_LOG2_256;
grpatch->mipmap.grInfo.largeLodLog2 = GR_LOD_LOG2_256;
grpatch->mipmap.grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
}
HWD.pfnSetTexture(&grpatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary
HWR_UnlockCachedPatch(grpatch);
Z_Free(filename);
}
// Don't spam the console, or the OS with fopen requests!
static boolean nomd2s = false;
@ -1050,6 +1104,238 @@ spritemd2found:
fclose(f);
}
static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, skincolors_t color)
{
UINT16 w = gpatch->width, h = gpatch->height;
UINT32 size = w*h;
RGBA_t *image, *blendimage, *cur, blendcolor;
if (grmip->width == 0)
{
grmip->width = gpatch->width;
grmip->height = gpatch->height;
// no wrap around, no chroma key
grmip->flags = 0;
// setup the texture info
grmip->grInfo.format = GR_RGBA;
}
Z_Free(grmip->grInfo.data);
grmip->grInfo.data = NULL;
cur = Z_Malloc(size*4, PU_HWRCACHE, &grmip->grInfo.data);
memset(cur, 0x00, size*4);
image = gpatch->mipmap.grInfo.data;
blendimage = blendgpatch->mipmap.grInfo.data;
switch (color)
{
case SKINCOLOR_WHITE:
blendcolor = V_GetColor(3);
break;
case SKINCOLOR_SILVER:
blendcolor = V_GetColor(10);
break;
case SKINCOLOR_GREY:
blendcolor = V_GetColor(15);
break;
case SKINCOLOR_BLACK:
blendcolor = V_GetColor(27);
break;
case SKINCOLOR_BEIGE:
blendcolor = V_GetColor(247);
break;
case SKINCOLOR_PEACH:
blendcolor = V_GetColor(218);
break;
case SKINCOLOR_BROWN:
blendcolor = V_GetColor(234);
break;
case SKINCOLOR_RED:
blendcolor = V_GetColor(38);
break;
case SKINCOLOR_CRIMSON:
blendcolor = V_GetColor(45);
break;
case SKINCOLOR_ORANGE:
blendcolor = V_GetColor(54);
break;
case SKINCOLOR_RUST:
blendcolor = V_GetColor(60);
break;
case SKINCOLOR_GOLD:
blendcolor = V_GetColor(67);
break;
case SKINCOLOR_YELLOW:
blendcolor = V_GetColor(73);
break;
case SKINCOLOR_TAN:
blendcolor = V_GetColor(85);
break;
case SKINCOLOR_MOSS:
blendcolor = V_GetColor(92);
break;
case SKINCOLOR_PERIDOT:
blendcolor = V_GetColor(188);
break;
case SKINCOLOR_GREEN:
blendcolor = V_GetColor(101);
break;
case SKINCOLOR_EMERALD:
blendcolor = V_GetColor(112);
break;
case SKINCOLOR_AQUA:
blendcolor = V_GetColor(122);
break;
case SKINCOLOR_TEAL:
blendcolor = V_GetColor(141);
break;
case SKINCOLOR_CYAN:
blendcolor = V_GetColor(131);
break;
case SKINCOLOR_BLUE:
blendcolor = V_GetColor(152);
break;
case SKINCOLOR_AZURE:
blendcolor = V_GetColor(171);
break;
case SKINCOLOR_PASTEL:
blendcolor = V_GetColor(161);
break;
case SKINCOLOR_PURPLE:
blendcolor = V_GetColor(165);
break;
case SKINCOLOR_LAVENDER:
blendcolor = V_GetColor(195);
break;
case SKINCOLOR_MAGENTA:
blendcolor = V_GetColor(183);
break;
case SKINCOLOR_PINK:
blendcolor = V_GetColor(211);
break;
case SKINCOLOR_ROSY:
blendcolor = V_GetColor(202);
break;
case SKINCOLOR_SUPER1:
blendcolor = V_GetColor(80);
break;
case SKINCOLOR_SUPER2:
blendcolor = V_GetColor(83);
break;
case SKINCOLOR_SUPER3:
blendcolor = V_GetColor(73);
break;
case SKINCOLOR_SUPER4:
blendcolor = V_GetColor(64);
break;
case SKINCOLOR_SUPER5:
blendcolor = V_GetColor(67);
break;
case SKINCOLOR_TSUPER1:
case SKINCOLOR_TSUPER2:
case SKINCOLOR_TSUPER3:
case SKINCOLOR_TSUPER4:
case SKINCOLOR_TSUPER5:
case SKINCOLOR_KSUPER1:
case SKINCOLOR_KSUPER2:
case SKINCOLOR_KSUPER3:
case SKINCOLOR_KSUPER4:
case SKINCOLOR_KSUPER5:
default:
blendcolor = V_GetColor(255);
break;
}
while (size--)
{
if (blendimage->s.alpha == 0)
{
// Don't bother with blending the pixel if the alpha of the blend pixel is 0
cur->rgba = image->rgba;
}
else
{
INT32 tempcolor;
INT16 tempmult, tempalpha;
tempalpha = -(abs(blendimage->s.red-127)-127)*2;
if (tempalpha > 255)
tempalpha = 255;
else if (tempalpha < 0)
tempalpha = 0;
tempmult = (blendimage->s.red-127)*2;
if (tempmult > 255)
tempmult = 255;
else if (tempmult < 0)
tempmult = 0;
tempcolor = (image->s.red*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.red)/255)) * blendimage->s.alpha)/255;
cur->s.red = (UINT8)tempcolor;
tempcolor = (image->s.green*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.green)/255)) * blendimage->s.alpha)/255;
cur->s.green = (UINT8)tempcolor;
tempcolor = (image->s.blue*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.blue)/255)) * blendimage->s.alpha)/255;
cur->s.blue = (UINT8)tempcolor;
cur->s.alpha = image->s.alpha;
}
cur++; image++; blendimage++;
}
return;
}
static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, const UINT8 *colormap, skincolors_t color)
{
// mostly copied from HWR_GetMappedPatch, hence the similarities and comment
GLMipmap_t *grmip, *newmip;
if (colormap == colormaps || colormap == NULL)
{
// Don't do any blending
HWD.pfnSetTexture(&gpatch->mipmap);
return;
}
// search for the mimmap
// skip the first (no colormap translated)
for (grmip = &gpatch->mipmap; grmip->nextcolormap; )
{
grmip = grmip->nextcolormap;
if (grmip->colormap == colormap)
{
if (grmip->downloaded && grmip->grInfo.data)
{
HWD.pfnSetTexture(grmip); // found the colormap, set it to the correct texture
Z_ChangeTag(grmip->grInfo.data, PU_HWRCACHE_UNLOCKED);
return;
}
}
}
// If here, the blended texture has not been created
// So we create it
//BP: WARNING: don't free it manually without clearing the cache of harware renderer
// (it have a liste of mipmap)
// this malloc is cleared in HWR_FreeTextureCache
// (...) unfortunately z_malloc fragment alot the memory :(so malloc is better
newmip = calloc(1, sizeof (*newmip));
if (newmip == NULL)
I_Error("%s: Out of memory", "HWR_GetMappedPatch");
grmip->nextcolormap = newmip;
newmip->colormap = colormap;
HWR_CreateBlendedTexture(gpatch, blendgpatch, newmip, color);
HWD.pfnSetTexture(newmip);
Z_ChangeTag(newmip->grInfo.data, PU_HWRCACHE_UNLOCKED);
}
// -----------------+
// HWR_DrawMD2 : Draw MD2
@ -1085,7 +1371,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
if (!cv_grmd2.value)
return;
if (!spr->precip)
if (spr->precip)
return;
// MD2 colormap fix
@ -1180,13 +1466,25 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
gpatch = md2->grpatch;
if (!gpatch || !gpatch->mipmap.grInfo.format || !gpatch->mipmap.downloaded)
md2_loadTexture(md2);
gpatch = md2->grpatch; // Load it again, because it isn't being loaded into gpatch after md2_loadtexture...
if ((gpatch && gpatch->mipmap.grInfo.format) // don't load the blend texture if the base texture isn't available
&& (!md2->blendgrpatch || !((GLPatch_t *)md2->blendgrpatch)->mipmap.grInfo.format || !((GLPatch_t *)md2->blendgrpatch)->mipmap.downloaded))
md2_loadBlendTexture(md2);
if (gpatch && gpatch->mipmap.grInfo.format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture
{
// This is safe, since we know the texture has been downloaded
HWD.pfnSetTexture(&gpatch->mipmap);
if ((skincolors_t)spr->mobj->color != SKINCOLOR_NONE &&
md2->blendgrpatch && ((GLPatch_t *)md2->blendgrpatch)->mipmap.grInfo.format
&& gpatch->width == ((GLPatch_t *)md2->blendgrpatch)->width && gpatch->height == ((GLPatch_t *)md2->blendgrpatch)->height)
{
HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, spr->colormap, (skincolors_t)spr->mobj->color);
}
else
{
// This is safe, since we know the texture has been downloaded
HWD.pfnSetTexture(&gpatch->mipmap);
}
}
else
{
@ -1195,16 +1493,37 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
HWR_GetMappedPatch(gpatch, spr->colormap);
}
if (spr->mobj->frame & FF_ANIMATE)
{
// set duration and tics to be the correct values for FF_ANIMATE states
durs = spr->mobj->state->var2;
tics = spr->mobj->anim_duration;
}
//FIXME: this is not yet correct
frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->header.numFrames;
buff = md2->model->glCommandBuffer;
curr = &md2->model->frames[frame];
if (cv_grmd2.value == 1
&& spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL
&& !(spr->mobj->player && spr->mobj->state->nextstate == S_PLAY_WAIT && spr->mobj->state == &states[S_PLAY_STND]))
if (cv_grmd2.value == 1)
{
const INT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames;
next = &md2->model->frames[nextframe];
// frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation
if (spr->mobj->frame & FF_ANIMATE)
{
UINT32 nextframe = (spr->mobj->frame & FF_FRAMEMASK) + 1;
if (nextframe >= (UINT32)spr->mobj->state->var1)
nextframe = (spr->mobj->state->frame & FF_FRAMEMASK);
nextframe %= md2->model->header.numFrames;
next = &md2->model->frames[nextframe];
}
else
{
if (spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL
&& !(spr->mobj->player && spr->mobj->state->nextstate == S_PLAY_WAIT && spr->mobj->state == &states[S_PLAY_STND]))
{
const UINT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames;
next = &md2->model->frames[nextframe];
}
}
}
//Hurdler: it seems there is still a small problem with mobj angle

View File

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

View File

@ -2371,7 +2371,7 @@ EXPORT void HWRAPI(MakeScreenTexture) (void)
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
#ifndef KOS_GL_COMPATIBILITY
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, texsize, texsize, 0);
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
#endif
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now
@ -2399,7 +2399,7 @@ EXPORT void HWRAPI(MakeScreenFinalTexture) (void)
Clamp2D(GL_TEXTURE_WRAP_S);
Clamp2D(GL_TEXTURE_WRAP_T);
#ifndef KOS_GL_COMPATIBILITY
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, texsize, texsize, 0);
pglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, texsize, texsize, 0);
#endif
tex_downloaded = 0; // 0 so it knows it doesn't have any of the cached patches downloaded right now

File diff suppressed because it is too large Load Diff

View File

@ -588,6 +588,7 @@ enum playersprite
SPR2_DASH,
SPR2_GASP,
SPR2_JUMP,
SPR2_SPNG, // spring
SPR2_FALL,
SPR2_EDGE,
SPR2_RIDE,
@ -613,6 +614,7 @@ enum playersprite
SPR2_SSPN,
SPR2_SGSP,
SPR2_SJMP,
SPR2_SSPG,
SPR2_SFAL,
SPR2_SEDG,
SPR2_SRID,
@ -649,7 +651,8 @@ typedef enum state
S_PLAY_SPIN,
S_PLAY_DASH,
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_EDGE,
S_PLAY_RIDE,
@ -673,7 +676,8 @@ typedef enum state
S_PLAY_SUPER_DRWN,
S_PLAY_SUPER_SPIN,
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_EDGE,
S_PLAY_SUPER_RIDE,
@ -1475,30 +1479,7 @@ typedef enum state
S_MSSHIELD_F12,
// Ring
S_RING1,
S_RING2,
S_RING3,
S_RING4,
S_RING5,
S_RING6,
S_RING7,
S_RING8,
S_RING9,
S_RING10,
S_RING11,
S_RING12,
S_RING13,
S_RING14,
S_RING15,
S_RING16,
S_RING17,
S_RING18,
S_RING19,
S_RING20,
S_RING21,
S_RING22,
S_RING23,
S_RING24,
S_RING,
// Blue Sphere for special stages
S_BLUEBALL,
@ -1514,39 +1495,10 @@ typedef enum state
S_GRAVWELLRED3,
// Individual Team Rings
S_TEAMRING1,
S_TEAMRING2,
S_TEAMRING3,
S_TEAMRING4,
S_TEAMRING5,
S_TEAMRING6,
S_TEAMRING7,
S_TEAMRING8,
S_TEAMRING9,
S_TEAMRING10,
S_TEAMRING11,
S_TEAMRING12,
S_TEAMRING13,
S_TEAMRING14,
S_TEAMRING15,
S_TEAMRING16,
S_TEAMRING17,
S_TEAMRING18,
S_TEAMRING19,
S_TEAMRING20,
S_TEAMRING21,
S_TEAMRING22,
S_TEAMRING23,
S_TEAMRING24,
S_TEAMRING,
// Special Stage Token
S_EMMY1,
S_EMMY2,
S_EMMY3,
S_EMMY4,
S_EMMY5,
S_EMMY6,
S_EMMY7,
S_EMMY,
// Special Stage Token
S_TOKEN,
@ -1700,40 +1652,9 @@ typedef enum state
S_SPIKED2,
// Starpost
S_STARPOST1,
S_STARPOST2,
S_STARPOST3,
S_STARPOST4,
S_STARPOST5,
S_STARPOST6,
S_STARPOST7,
S_STARPOST8,
S_STARPOST9,
S_STARPOST10,
S_STARPOST11,
S_STARPOST12,
S_STARPOST13,
S_STARPOST14,
S_STARPOST15,
S_STARPOST16,
S_STARPOST17,
S_STARPOST18,
S_STARPOST19,
S_STARPOST20,
S_STARPOST21,
S_STARPOST22,
S_STARPOST23,
S_STARPOST24,
S_STARPOST25,
S_STARPOST26,
S_STARPOST27,
S_STARPOST28,
S_STARPOST29,
S_STARPOST30,
S_STARPOST31,
S_STARPOST32,
S_STARPOST33,
S_STARPOST34,
S_STARPOST_IDLE,
S_STARPOST_FLASH,
S_STARPOST_SPIN,
// Big floating mine
S_BIGMINE1,
@ -2341,38 +2262,7 @@ typedef enum state
S_PITY10,
// Invincibility Sparkles
S_IVSP1,
S_IVSP2,
S_IVSP3,
S_IVSP4,
S_IVSP5,
S_IVSP6,
S_IVSP7,
S_IVSP8,
S_IVSP9,
S_IVSP10,
S_IVSP11,
S_IVSP12,
S_IVSP13,
S_IVSP14,
S_IVSP15,
S_IVSP16,
S_IVSP17,
S_IVSP18,
S_IVSP19,
S_IVSP20,
S_IVSP21,
S_IVSP22,
S_IVSP23,
S_IVSP24,
S_IVSP25,
S_IVSP26,
S_IVSP27,
S_IVSP28,
S_IVSP29,
S_IVSP30,
S_IVSP31,
S_IVSP32,
S_IVSP,
// Super Sonic Spark
S_SSPK1,
@ -2559,283 +2449,17 @@ typedef enum state
S_RRNG6,
S_RRNG7,
// Bounce Ring
S_BOUNCERING1,
S_BOUNCERING2,
S_BOUNCERING3,
S_BOUNCERING4,
S_BOUNCERING5,
S_BOUNCERING6,
S_BOUNCERING7,
S_BOUNCERING8,
S_BOUNCERING9,
S_BOUNCERING10,
S_BOUNCERING11,
S_BOUNCERING12,
S_BOUNCERING13,
S_BOUNCERING14,
S_BOUNCERING15,
S_BOUNCERING16,
S_BOUNCERING17,
S_BOUNCERING18,
S_BOUNCERING19,
S_BOUNCERING20,
S_BOUNCERING21,
S_BOUNCERING22,
S_BOUNCERING23,
S_BOUNCERING24,
S_BOUNCERING25,
S_BOUNCERING26,
S_BOUNCERING27,
S_BOUNCERING28,
S_BOUNCERING29,
S_BOUNCERING30,
S_BOUNCERING31,
S_BOUNCERING32,
S_BOUNCERING33,
S_BOUNCERING34,
S_BOUNCERING35,
// Rail Ring
S_RAILRING1,
S_RAILRING2,
S_RAILRING3,
S_RAILRING4,
S_RAILRING5,
S_RAILRING6,
S_RAILRING7,
S_RAILRING8,
S_RAILRING9,
S_RAILRING10,
S_RAILRING11,
S_RAILRING12,
S_RAILRING13,
S_RAILRING14,
S_RAILRING15,
S_RAILRING16,
S_RAILRING17,
S_RAILRING18,
S_RAILRING19,
S_RAILRING20,
S_RAILRING21,
S_RAILRING22,
S_RAILRING23,
S_RAILRING24,
S_RAILRING25,
S_RAILRING26,
S_RAILRING27,
S_RAILRING28,
S_RAILRING29,
S_RAILRING30,
S_RAILRING31,
S_RAILRING32,
S_RAILRING33,
S_RAILRING34,
S_RAILRING35,
// Infinity Ring
S_INFINITYRING1,
S_INFINITYRING2,
S_INFINITYRING3,
S_INFINITYRING4,
S_INFINITYRING5,
S_INFINITYRING6,
S_INFINITYRING7,
S_INFINITYRING8,
S_INFINITYRING9,
S_INFINITYRING10,
S_INFINITYRING11,
S_INFINITYRING12,
S_INFINITYRING13,
S_INFINITYRING14,
S_INFINITYRING15,
S_INFINITYRING16,
S_INFINITYRING17,
S_INFINITYRING18,
S_INFINITYRING19,
S_INFINITYRING20,
S_INFINITYRING21,
S_INFINITYRING22,
S_INFINITYRING23,
S_INFINITYRING24,
S_INFINITYRING25,
S_INFINITYRING26,
S_INFINITYRING27,
S_INFINITYRING28,
S_INFINITYRING29,
S_INFINITYRING30,
S_INFINITYRING31,
S_INFINITYRING32,
S_INFINITYRING33,
S_INFINITYRING34,
S_INFINITYRING35,
// Automatic Ring
S_AUTOMATICRING1,
S_AUTOMATICRING2,
S_AUTOMATICRING3,
S_AUTOMATICRING4,
S_AUTOMATICRING5,
S_AUTOMATICRING6,
S_AUTOMATICRING7,
S_AUTOMATICRING8,
S_AUTOMATICRING9,
S_AUTOMATICRING10,
S_AUTOMATICRING11,
S_AUTOMATICRING12,
S_AUTOMATICRING13,
S_AUTOMATICRING14,
S_AUTOMATICRING15,
S_AUTOMATICRING16,
S_AUTOMATICRING17,
S_AUTOMATICRING18,
S_AUTOMATICRING19,
S_AUTOMATICRING20,
S_AUTOMATICRING21,
S_AUTOMATICRING22,
S_AUTOMATICRING23,
S_AUTOMATICRING24,
S_AUTOMATICRING25,
S_AUTOMATICRING26,
S_AUTOMATICRING27,
S_AUTOMATICRING28,
S_AUTOMATICRING29,
S_AUTOMATICRING30,
S_AUTOMATICRING31,
S_AUTOMATICRING32,
S_AUTOMATICRING33,
S_AUTOMATICRING34,
S_AUTOMATICRING35,
// Explosion Ring
S_EXPLOSIONRING1,
S_EXPLOSIONRING2,
S_EXPLOSIONRING3,
S_EXPLOSIONRING4,
S_EXPLOSIONRING5,
S_EXPLOSIONRING6,
S_EXPLOSIONRING7,
S_EXPLOSIONRING8,
S_EXPLOSIONRING9,
S_EXPLOSIONRING10,
S_EXPLOSIONRING11,
S_EXPLOSIONRING12,
S_EXPLOSIONRING13,
S_EXPLOSIONRING14,
S_EXPLOSIONRING15,
S_EXPLOSIONRING16,
S_EXPLOSIONRING17,
S_EXPLOSIONRING18,
S_EXPLOSIONRING19,
S_EXPLOSIONRING20,
S_EXPLOSIONRING21,
S_EXPLOSIONRING22,
S_EXPLOSIONRING23,
S_EXPLOSIONRING24,
S_EXPLOSIONRING25,
S_EXPLOSIONRING26,
S_EXPLOSIONRING27,
S_EXPLOSIONRING28,
S_EXPLOSIONRING29,
S_EXPLOSIONRING30,
S_EXPLOSIONRING31,
S_EXPLOSIONRING32,
S_EXPLOSIONRING33,
S_EXPLOSIONRING34,
S_EXPLOSIONRING35,
// Scatter Ring
S_SCATTERRING1,
S_SCATTERRING2,
S_SCATTERRING3,
S_SCATTERRING4,
S_SCATTERRING5,
S_SCATTERRING6,
S_SCATTERRING7,
S_SCATTERRING8,
S_SCATTERRING9,
S_SCATTERRING10,
S_SCATTERRING11,
S_SCATTERRING12,
S_SCATTERRING13,
S_SCATTERRING14,
S_SCATTERRING15,
S_SCATTERRING16,
S_SCATTERRING17,
S_SCATTERRING18,
S_SCATTERRING19,
S_SCATTERRING20,
S_SCATTERRING21,
S_SCATTERRING22,
S_SCATTERRING23,
S_SCATTERRING24,
S_SCATTERRING25,
S_SCATTERRING26,
S_SCATTERRING27,
S_SCATTERRING28,
S_SCATTERRING29,
S_SCATTERRING30,
S_SCATTERRING31,
S_SCATTERRING32,
S_SCATTERRING33,
S_SCATTERRING34,
S_SCATTERRING35,
// Grenade Ring
S_GRENADERING1,
S_GRENADERING2,
S_GRENADERING3,
S_GRENADERING4,
S_GRENADERING5,
S_GRENADERING6,
S_GRENADERING7,
S_GRENADERING8,
S_GRENADERING9,
S_GRENADERING10,
S_GRENADERING11,
S_GRENADERING12,
S_GRENADERING13,
S_GRENADERING14,
S_GRENADERING15,
S_GRENADERING16,
S_GRENADERING17,
S_GRENADERING18,
S_GRENADERING19,
S_GRENADERING20,
S_GRENADERING21,
S_GRENADERING22,
S_GRENADERING23,
S_GRENADERING24,
S_GRENADERING25,
S_GRENADERING26,
S_GRENADERING27,
S_GRENADERING28,
S_GRENADERING29,
S_GRENADERING30,
S_GRENADERING31,
S_GRENADERING32,
S_GRENADERING33,
S_GRENADERING34,
S_GRENADERING35,
// Weapon Ring Ammo
S_BOUNCERINGAMMO,
S_RAILRINGAMMO,
S_INFINITYRINGAMMO,
S_AUTOMATICRINGAMMO,
S_EXPLOSIONRINGAMMO,
S_SCATTERRINGAMMO,
S_GRENADERINGAMMO,
// Weapon pickup
S_BOUNCEPICKUP1,
S_BOUNCEPICKUP2,
S_BOUNCEPICKUP3,
S_BOUNCEPICKUP4,
S_BOUNCEPICKUP5,
S_BOUNCEPICKUP6,
S_BOUNCEPICKUP7,
S_BOUNCEPICKUP8,
S_BOUNCEPICKUP9,
S_BOUNCEPICKUP10,
S_BOUNCEPICKUP11,
S_BOUNCEPICKUP12,
S_BOUNCEPICKUP13,
S_BOUNCEPICKUP14,
S_BOUNCEPICKUP15,
S_BOUNCEPICKUP16,
S_BOUNCEPICKUP,
S_BOUNCEPICKUPFADE1,
S_BOUNCEPICKUPFADE2,
S_BOUNCEPICKUPFADE3,
@ -2845,23 +2469,7 @@ typedef enum state
S_BOUNCEPICKUPFADE7,
S_BOUNCEPICKUPFADE8,
S_RAILPICKUP1,
S_RAILPICKUP2,
S_RAILPICKUP3,
S_RAILPICKUP4,
S_RAILPICKUP5,
S_RAILPICKUP6,
S_RAILPICKUP7,
S_RAILPICKUP8,
S_RAILPICKUP9,
S_RAILPICKUP10,
S_RAILPICKUP11,
S_RAILPICKUP12,
S_RAILPICKUP13,
S_RAILPICKUP14,
S_RAILPICKUP15,
S_RAILPICKUP16,
S_RAILPICKUP,
S_RAILPICKUPFADE1,
S_RAILPICKUPFADE2,
S_RAILPICKUPFADE3,
@ -2871,23 +2479,7 @@ typedef enum state
S_RAILPICKUPFADE7,
S_RAILPICKUPFADE8,
S_AUTOPICKUP1,
S_AUTOPICKUP2,
S_AUTOPICKUP3,
S_AUTOPICKUP4,
S_AUTOPICKUP5,
S_AUTOPICKUP6,
S_AUTOPICKUP7,
S_AUTOPICKUP8,
S_AUTOPICKUP9,
S_AUTOPICKUP10,
S_AUTOPICKUP11,
S_AUTOPICKUP12,
S_AUTOPICKUP13,
S_AUTOPICKUP14,
S_AUTOPICKUP15,
S_AUTOPICKUP16,
S_AUTOPICKUP,
S_AUTOPICKUPFADE1,
S_AUTOPICKUPFADE2,
S_AUTOPICKUPFADE3,
@ -2897,23 +2489,7 @@ typedef enum state
S_AUTOPICKUPFADE7,
S_AUTOPICKUPFADE8,
S_EXPLODEPICKUP1,
S_EXPLODEPICKUP2,
S_EXPLODEPICKUP3,
S_EXPLODEPICKUP4,
S_EXPLODEPICKUP5,
S_EXPLODEPICKUP6,
S_EXPLODEPICKUP7,
S_EXPLODEPICKUP8,
S_EXPLODEPICKUP9,
S_EXPLODEPICKUP10,
S_EXPLODEPICKUP11,
S_EXPLODEPICKUP12,
S_EXPLODEPICKUP13,
S_EXPLODEPICKUP14,
S_EXPLODEPICKUP15,
S_EXPLODEPICKUP16,
S_EXPLODEPICKUP,
S_EXPLODEPICKUPFADE1,
S_EXPLODEPICKUPFADE2,
S_EXPLODEPICKUPFADE3,
@ -2923,23 +2499,7 @@ typedef enum state
S_EXPLODEPICKUPFADE7,
S_EXPLODEPICKUPFADE8,
S_SCATTERPICKUP1,
S_SCATTERPICKUP2,
S_SCATTERPICKUP3,
S_SCATTERPICKUP4,
S_SCATTERPICKUP5,
S_SCATTERPICKUP6,
S_SCATTERPICKUP7,
S_SCATTERPICKUP8,
S_SCATTERPICKUP9,
S_SCATTERPICKUP10,
S_SCATTERPICKUP11,
S_SCATTERPICKUP12,
S_SCATTERPICKUP13,
S_SCATTERPICKUP14,
S_SCATTERPICKUP15,
S_SCATTERPICKUP16,
S_SCATTERPICKUP,
S_SCATTERPICKUPFADE1,
S_SCATTERPICKUPFADE2,
S_SCATTERPICKUPFADE3,
@ -2949,23 +2509,7 @@ typedef enum state
S_SCATTERPICKUPFADE7,
S_SCATTERPICKUPFADE8,
S_GRENADEPICKUP1,
S_GRENADEPICKUP2,
S_GRENADEPICKUP3,
S_GRENADEPICKUP4,
S_GRENADEPICKUP5,
S_GRENADEPICKUP6,
S_GRENADEPICKUP7,
S_GRENADEPICKUP8,
S_GRENADEPICKUP9,
S_GRENADEPICKUP10,
S_GRENADEPICKUP11,
S_GRENADEPICKUP12,
S_GRENADEPICKUP13,
S_GRENADEPICKUP14,
S_GRENADEPICKUP15,
S_GRENADEPICKUP16,
S_GRENADEPICKUP,
S_GRENADEPICKUPFADE1,
S_GRENADEPICKUPFADE2,
S_GRENADEPICKUPFADE3,
@ -3346,101 +2890,22 @@ typedef enum state
S_ROCKSPAWN,
S_ROCKCRUMBLEA1,
S_ROCKCRUMBLEA2,
S_ROCKCRUMBLEA3,
S_ROCKCRUMBLEA4,
S_ROCKCRUMBLEA5,
S_ROCKCRUMBLEB1,
S_ROCKCRUMBLEB2,
S_ROCKCRUMBLEB3,
S_ROCKCRUMBLEB4,
S_ROCKCRUMBLEB5,
S_ROCKCRUMBLEC1,
S_ROCKCRUMBLEC2,
S_ROCKCRUMBLEC3,
S_ROCKCRUMBLEC4,
S_ROCKCRUMBLEC5,
S_ROCKCRUMBLED1,
S_ROCKCRUMBLED2,
S_ROCKCRUMBLED3,
S_ROCKCRUMBLED4,
S_ROCKCRUMBLED5,
S_ROCKCRUMBLEE1,
S_ROCKCRUMBLEE2,
S_ROCKCRUMBLEE3,
S_ROCKCRUMBLEE4,
S_ROCKCRUMBLEE5,
S_ROCKCRUMBLEF1,
S_ROCKCRUMBLEF2,
S_ROCKCRUMBLEF3,
S_ROCKCRUMBLEF4,
S_ROCKCRUMBLEF5,
S_ROCKCRUMBLEG1,
S_ROCKCRUMBLEG2,
S_ROCKCRUMBLEG3,
S_ROCKCRUMBLEG4,
S_ROCKCRUMBLEG5,
S_ROCKCRUMBLEH1,
S_ROCKCRUMBLEH2,
S_ROCKCRUMBLEH3,
S_ROCKCRUMBLEH4,
S_ROCKCRUMBLEH5,
S_ROCKCRUMBLEI1,
S_ROCKCRUMBLEI2,
S_ROCKCRUMBLEI3,
S_ROCKCRUMBLEI4,
S_ROCKCRUMBLEI5,
S_ROCKCRUMBLEJ1,
S_ROCKCRUMBLEJ2,
S_ROCKCRUMBLEJ3,
S_ROCKCRUMBLEJ4,
S_ROCKCRUMBLEJ5,
S_ROCKCRUMBLEK1,
S_ROCKCRUMBLEK2,
S_ROCKCRUMBLEK3,
S_ROCKCRUMBLEK4,
S_ROCKCRUMBLEK5,
S_ROCKCRUMBLEL1,
S_ROCKCRUMBLEL2,
S_ROCKCRUMBLEL3,
S_ROCKCRUMBLEL4,
S_ROCKCRUMBLEL5,
S_ROCKCRUMBLEM1,
S_ROCKCRUMBLEM2,
S_ROCKCRUMBLEM3,
S_ROCKCRUMBLEM4,
S_ROCKCRUMBLEM5,
S_ROCKCRUMBLEN1,
S_ROCKCRUMBLEN2,
S_ROCKCRUMBLEN3,
S_ROCKCRUMBLEN4,
S_ROCKCRUMBLEN5,
S_ROCKCRUMBLEO1,
S_ROCKCRUMBLEO2,
S_ROCKCRUMBLEO3,
S_ROCKCRUMBLEO4,
S_ROCKCRUMBLEO5,
S_ROCKCRUMBLEP1,
S_ROCKCRUMBLEP2,
S_ROCKCRUMBLEP3,
S_ROCKCRUMBLEP4,
S_ROCKCRUMBLEP5,
S_ROCKCRUMBLEA,
S_ROCKCRUMBLEB,
S_ROCKCRUMBLEC,
S_ROCKCRUMBLED,
S_ROCKCRUMBLEE,
S_ROCKCRUMBLEF,
S_ROCKCRUMBLEG,
S_ROCKCRUMBLEH,
S_ROCKCRUMBLEI,
S_ROCKCRUMBLEJ,
S_ROCKCRUMBLEK,
S_ROCKCRUMBLEL,
S_ROCKCRUMBLEM,
S_ROCKCRUMBLEN,
S_ROCKCRUMBLEO,
S_ROCKCRUMBLEP,
S_SRB1_CRAWLA1,
S_SRB1_CRAWLA2,
@ -3631,9 +3096,7 @@ typedef enum mobj_type
// Collectible Items
MT_RING,
MT_FLINGRING, // Lost ring
#ifdef BLUE_SPHERES
MT_BLUEBALL, // Blue sphere replacement for special stages
#endif
MT_REDTEAMRING, //Rings collectable by red team.
MT_BLUETEAMRING, //Rings collectable by blue team.
MT_EMMY, // emerald token for special stage

View File

@ -1020,8 +1020,8 @@ static int lib_pDoSpring(lua_State *L)
NOHUD
if (!spring || !object)
return LUA_ErrInvalid(L, "mobj_t");
P_DoSpring(spring, object);
return 0;
lua_pushboolean(L, P_DoSpring(spring, object));
return 1;
}
// P_INTER
@ -1671,18 +1671,63 @@ static int lib_sStopSound(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);
player_t *player = NULL;
UINT16 music_flags = 0;
NOHUD
#endif
if (!lua_isnone(L, 3) && lua_isuserdata(L, 3))
{
player = *((player_t **)luaL_checkudata(L, 3, META_PLAYER));
if (!player)
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))
S_ChangeMusic(music_num, looping);
S_ChangeMusic(music_name, music_flags, looping);
return 0;
}

View File

@ -42,6 +42,7 @@ enum hook {
hook_LinedefExecute,
hook_PlayerMsg,
hook_HurtMsg,
hook_PlayerSpawn,
hook_MAX // last hook
};
@ -75,5 +76,6 @@ boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_B
boolean LUAh_LinedefExecute(line_t *line, mobj_t *mo, sector_t *sector); // Hook for linedef executors
boolean LUAh_PlayerMsg(int source, int target, int flags, char *msg); // Hook for chat messages
boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source); // Hook for hurt messages
#define LUAh_PlayerSpawn(player) LUAh_PlayerHook(player, hook_PlayerSpawn) // Hook for G_SpawnPlayer
#endif

View File

@ -53,6 +53,7 @@ const char *const hookNames[hook_MAX+1] = {
"LinedefExecute",
"PlayerMsg",
"HurtMsg",
"PlayerSpawn",
NULL
};
@ -768,4 +769,33 @@ boolean LUAh_HurtMsg(player_t *player, mobj_t *inflictor, mobj_t *source)
return hooked;
}
void LUAh_NetArchiveHook(lua_CFunction archFunc)
{
hook_p hookp;
if (!gL || !(hooksAvailable[hook_NetVars/8] & (1<<(hook_NetVars%8))))
return;
// stack: tables
I_Assert(lua_gettop(gL) > 0);
I_Assert(lua_istable(gL, -1));
// tables becomes an upvalue of archFunc
lua_pushvalue(gL, -1);
lua_pushcclosure(gL, archFunc, 1);
// stack: tables, archFunc
for (hookp = roothook; hookp; hookp = hookp->next)
if (hookp->type == hook_NetVars)
{
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
lua_gettable(gL, LUA_REGISTRYINDEX);
lua_pushvalue(gL, -2); // archFunc
LUA_Call(gL, 1);
}
lua_pop(gL, 1); // pop archFunc
// stack: tables
}
#endif

View File

@ -16,7 +16,9 @@
#include "r_local.h"
#include "st_stuff.h" // hudinfo[]
#include "g_game.h"
#include "i_video.h" // rendermode
#include "p_local.h" // camera_t
#include "screen.h" // screen width/height
#include "v_video.h"
#include "w_wad.h"
#include "z_zone.h"
@ -486,7 +488,7 @@ static int libd_getColormap(lua_State *L)
INT32 skinnum = TC_DEFAULT;
skincolors_t color = luaL_optinteger(L, 2, 0);
UINT8* colormap = NULL;
//HUDSAFE
HUDONLY
if (lua_isnoneornil(L, 1))
; // defaults to TC_DEFAULT
else if (lua_type(L, 1) == LUA_TNUMBER) // skin number
@ -510,6 +512,31 @@ static int libd_getColormap(lua_State *L)
return 1;
}
static int libd_width(lua_State *L)
{
HUDONLY
lua_pushinteger(L, vid.width); // push screen width
return 1;
}
static int libd_height(lua_State *L)
{
HUDONLY
lua_pushinteger(L, vid.height); // push screen height
return 1;
}
static int libd_renderer(lua_State *L)
{
HUDONLY
switch (rendermode) {
case render_opengl: lua_pushliteral(L, "opengl"); break; // OpenGL renderer
case render_soft: lua_pushliteral(L, "software"); break; // Software renderer
default: lua_pushliteral(L, "none"); break; // render_none (for dedicated), in case there's any reason this should be run
}
return 1;
}
static luaL_Reg lib_draw[] = {
{"patchExists", libd_patchExists},
{"cachePatch", libd_cachePatch},
@ -521,6 +548,9 @@ static luaL_Reg lib_draw[] = {
{"drawString", libd_drawString},
{"stringWidth", libd_stringWidth},
{"getColormap", libd_getColormap},
{"width", libd_width},
{"height", libd_height},
{"renderer", libd_renderer},
{NULL, NULL}
};

View File

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

View File

@ -37,6 +37,7 @@ enum sector_e {
sector_thinglist,
sector_heightsec,
sector_camsec,
sector_lines,
sector_ffloors
};
@ -52,6 +53,7 @@ static const char *const sector_opt[] = {
"thinglist",
"heightsec",
"camsec",
"lines",
"ffloors",
NULL};
@ -260,6 +262,67 @@ static int sector_iterate(lua_State *L)
return 3;
}
// sector.lines, i -> sector.lines[i]
// sector.lines.valid, for validity checking
static int sectorlines_get(lua_State *L)
{
line_t **seclines = *((line_t ***)luaL_checkudata(L, 1, META_SECTORLINES));
size_t i;
size_t numoflines = 0;
lua_settop(L, 2);
if (!lua_isnumber(L, 2))
{
int field = luaL_checkoption(L, 2, NULL, valid_opt);
if (!seclines)
{
if (field == 0) {
lua_pushboolean(L, 0);
return 1;
}
return luaL_error(L, "accessed sector_t doesn't exist anymore.");
} else if (field == 0) {
lua_pushboolean(L, 1);
return 1;
}
}
// check first linedef to figure which of its sectors owns this sector->lines pointer
// then check that sector's linecount to get a maximum index
//if (!seclines[0])
//return luaL_error(L, "no lines found!"); // no first linedef?????
if (seclines[0]->frontsector->lines == seclines)
numoflines = seclines[0]->frontsector->linecount;
else if (seclines[0]->backsector && seclines[0]->backsector->lines == seclines) // check backsector exists first
numoflines = seclines[0]->backsector->linecount;
//if neither sector has it then ???
if (!numoflines)
return luaL_error(L, "no lines found!");
i = (size_t)lua_tointeger(L, 2);
if (i >= numoflines)
return 0;
LUA_PushUserdata(L, seclines[i], META_LINE);
return 1;
}
static int sectorlines_num(lua_State *L)
{
line_t **seclines = *((line_t ***)luaL_checkudata(L, 1, META_SECTORLINES));
size_t numoflines = 0;
// check first linedef to figure which of its sectors owns this sector->lines pointer
// then check that sector's linecount to get a maximum index
//if (!seclines[0])
//return luaL_error(L, "no lines found!"); // no first linedef?????
if (seclines[0]->frontsector->lines == seclines)
numoflines = seclines[0]->frontsector->linecount;
else if (seclines[0]->backsector && seclines[0]->backsector->lines == seclines) // check backsector exists first
numoflines = seclines[0]->backsector->linecount;
//if neither sector has it then ???
lua_pushinteger(L, numoflines);
return 1;
}
static int sector_get(lua_State *L)
{
sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR));
@ -325,6 +388,9 @@ static int sector_get(lua_State *L)
return 0;
LUA_PushUserdata(L, &sectors[sector->camsec], META_SECTOR);
return 1;
case sector_lines: // lines
LUA_PushUserdata(L, sector->lines, META_SECTORLINES);
return 1;
case sector_ffloors: // ffloors
lua_pushcfunction(L, lib_iterateSectorFFloors);
LUA_PushUserdata(L, sector->ffloors, META_FFLOOR);
@ -1111,9 +1177,13 @@ static int ffloor_set(lua_State *L)
case ffloor_bottompic:
*ffloor->bottompic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3));
break;
case ffloor_flags:
case ffloor_flags: {
ffloortype_e oldflags = ffloor->flags; // store FOF's old flags
ffloor->flags = luaL_checkinteger(L, 3);
if (ffloor->flags != oldflags)
ffloor->target->moved = true; // reset target sector's lightlist
break;
}
case ffloor_alpha:
ffloor->alpha = (INT32)luaL_checkinteger(L, 3);
break;
@ -1157,26 +1227,23 @@ static int mapheaderinfo_get(lua_State *L)
{
mapheader_t *header = *((mapheader_t **)luaL_checkudata(L, 1, META_MAPHEADER));
const char *field = luaL_checkstring(L, 2);
//INT16 i;
if (fastcmp(field,"lvlttl")) {
//for (i = 0; i < 21; i++)
// if (!header->lvlttl[i])
// break;
lua_pushlstring(L, header->lvlttl, 21);
} else if (fastcmp(field,"subttl"))
lua_pushlstring(L, header->subttl, 32);
INT16 i;
if (fastcmp(field,"lvlttl"))
lua_pushstring(L, header->lvlttl);
else if (fastcmp(field,"subttl"))
lua_pushstring(L, header->subttl);
else if (fastcmp(field,"actnum"))
lua_pushinteger(L, header->actnum);
else if (fastcmp(field,"typeoflevel"))
lua_pushinteger(L, header->typeoflevel);
else if (fastcmp(field,"nextlevel"))
lua_pushinteger(L, header->nextlevel);
else if (fastcmp(field,"musicslot"))
lua_pushinteger(L, header->musicslot);
else if (fastcmp(field,"musicslottrack"))
lua_pushinteger(L, header->musicslottrack);
else if (fastcmp(field,"musname"))
lua_pushstring(L, header->musname);
else if (fastcmp(field,"mustrack"))
lua_pushinteger(L, header->mustrack);
else if (fastcmp(field,"forcecharacter"))
lua_pushlstring(L, header->forcecharacter, 16);
lua_pushstring(L, header->forcecharacter);
else if (fastcmp(field,"weather"))
lua_pushinteger(L, header->weather);
else if (fastcmp(field,"skynum"))
@ -1187,12 +1254,15 @@ static int mapheaderinfo_get(lua_State *L)
lua_pushinteger(L, header->skybox_scaley);
else if (fastcmp(field,"skybox_scalez"))
lua_pushinteger(L, header->skybox_scalez);
else if (fastcmp(field,"interscreen"))
lua_pushlstring(L, header->interscreen, 8);
else if (fastcmp(field,"runsoc"))
lua_pushlstring(L, header->runsoc, 32);
else if (fastcmp(field,"interscreen")) {
for (i = 0; i < 8; i++)
if (!header->interscreen[i])
break;
lua_pushlstring(L, header->interscreen, i);
} else if (fastcmp(field,"runsoc"))
lua_pushstring(L, header->runsoc);
else if (fastcmp(field,"scriptname"))
lua_pushlstring(L, header->scriptname, 32);
lua_pushstring(L, header->scriptname);
else if (fastcmp(field,"precutscenenum"))
lua_pushinteger(L, header->precutscenenum);
else if (fastcmp(field,"cutscenenum"))
@ -1217,11 +1287,11 @@ static int mapheaderinfo_get(lua_State *L)
else {
// Read custom vars now
// (note: don't include the "LUA." in your lua scripts!)
UINT8 i = 0;
for (;i < header->numCustomOptions && !fastcmp(field, header->customopts[i].option); ++i);
UINT8 j = 0;
for (;j < header->numCustomOptions && !fastcmp(field, header->customopts[j].option); ++j);
if(i < header->numCustomOptions)
lua_pushlstring(L, header->customopts[i].value, 255);
if(j < header->numCustomOptions)
lua_pushstring(L, header->customopts[j].value);
else
lua_pushnil(L);
}
@ -1230,6 +1300,14 @@ static int mapheaderinfo_get(lua_State *L)
int LUA_MapLib(lua_State *L)
{
luaL_newmetatable(L, META_SECTORLINES);
lua_pushcfunction(L, sectorlines_get);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, sectorlines_num);
lua_setfield(L, -2, "__len");
lua_pop(L, 1);
luaL_newmetatable(L, META_SECTOR);
lua_pushcfunction(L, sector_get);
lua_setfield(L, -2, "__index");

View File

@ -77,7 +77,9 @@ static int lib_finecosine(lua_State *L)
static int lib_finetangent(lua_State *L)
{
lua_pushfixed(L, FINETANGENT((luaL_checkangle(L, 1)>>ANGLETOFINESHIFT) & FINEMASK));
// HACK: add ANGLE_90 to make tan() in Lua start at 0 like it should
// use & 4095 instead of & FINEMASK (8191), so it doesn't go out of the array's bounds
lua_pushfixed(L, FINETANGENT(((luaL_checkangle(L, 1)+ANGLE_90)>>ANGLETOFINESHIFT) & 4095));
return 1;
}
@ -164,7 +166,7 @@ static int lib_all7emeralds(lua_State *L)
// Returns both color and frame numbers!
static int lib_coloropposite(lua_State *L)
{
int colornum = ((int)luaL_checkinteger(L, 1)) & MAXSKINCOLORS;
int colornum = ((int)luaL_checkinteger(L, 1)) % MAXSKINCOLORS;
lua_pushinteger(L, Color_Opposite[colornum*2]); // push color
lua_pushinteger(L, Color_Opposite[colornum*2+1]); // push frame
return 2;

View File

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

View File

@ -737,7 +737,7 @@ static int NetArchive(lua_State *L)
{
int TABLESINDEX = lua_upvalueindex(1);
int i, n = lua_gettop(L);
for (i = 0; i < n; i++)
for (i = 1; i <= n; i++)
ArchiveValue(TABLESINDEX, i);
return n;
}
@ -884,7 +884,7 @@ static int NetUnArchive(lua_State *L)
{
int TABLESINDEX = lua_upvalueindex(1);
int i, n = lua_gettop(L);
for (i = 0; i < n; i++)
for (i = 1; i <= n; i++)
UnArchiveValue(TABLESINDEX);
return n;
}
@ -915,30 +915,6 @@ static void UnArchiveTables(void)
}
}
static void NetArchiveHook(lua_CFunction archFunc)
{
int TABLESINDEX;
if (!gL)
return;
TABLESINDEX = lua_gettop(gL);
lua_getfield(gL, LUA_REGISTRYINDEX, "hook");
I_Assert(lua_istable(gL, -1));
lua_rawgeti(gL, -1, hook_NetVars);
lua_remove(gL, -2);
I_Assert(lua_istable(gL, -1));
lua_pushvalue(gL, TABLESINDEX);
lua_pushcclosure(gL, archFunc, 1);
lua_pushnil(gL);
while (lua_next(gL, -3) != 0) {
lua_pushvalue(gL, -3); // function
LUA_Call(gL, 1);
}
lua_pop(gL, 2);
}
void LUA_Step(void)
{
if (!gL)
@ -972,7 +948,7 @@ void LUA_Archive(void)
}
WRITEUINT32(save_p, UINT32_MAX); // end of mobjs marker, replaces mobjnum.
NetArchiveHook(NetArchive); // call the NetArchive hook in archive mode
LUAh_NetArchiveHook(NetArchive); // call the NetArchive hook in archive mode
ArchiveTables();
if (gL)
@ -1003,7 +979,7 @@ void LUA_UnArchive(void)
UnArchiveExtVars(th); // apply variables
} while(mobjnum != UINT32_MAX); // repeat until end of mobjs marker.
NetArchiveHook(NetUnArchive); // call the NetArchive hook in unarchive mode
LUAh_NetArchiveHook(NetUnArchive); // call the NetArchive hook in unarchive mode
UnArchiveTables();
if (gL)

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
int Lua_optoption(lua_State *L, int narg,
const char *def, const char *const lst[]);
void LUAh_NetArchiveHook(lua_CFunction archFunc);
// Console wrapper
void COM_Lua_f(void);
@ -69,4 +70,15 @@ void COM_Lua_f(void);
#define LUA_ErrInvalid(L, type) luaL_error(L, "accessed " type " doesn't exist anymore, please check 'valid' before using " type ".");
// Deprecation warnings
// Shows once upon use. Then doesn't show again.
#define LUA_Deprecated(L,this_func,use_instead)\
{\
static UINT8 seen = 0;\
if (!seen) {\
seen = 1;\
CONS_Alert(CONS_WARNING,"\"%s\" is deprecated and will be removed.\nUse \"%s\" instead.\n", this_func, use_instead);\
}\
}
#endif

View File

@ -108,7 +108,7 @@ static UINT8 cheatf_devmode(void)
G_SetGameModified(false);
for (i = 0; i < MAXUNLOCKABLES; i++)
unlockables[i].unlocked = true;
devparm = TRUE;
devparm = true;
cv_debug |= 0x8000;
// Refresh secrets menu existing.
@ -880,12 +880,33 @@ static boolean OP_HeightOkay(player_t *player, UINT8 ceiling)
static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean ceiling)
{
mapthing_t *mt;
mapthing_t *mt = mapthings;
#ifdef HAVE_BLUA
LUA_InvalidateMapthings();
#endif
mapthings = Z_Realloc(mapthings, ++nummapthings * sizeof (*mapthings), PU_LEVEL, NULL);
// as Z_Realloc can relocate mapthings, quickly go through thinker list and correct
// the spawnpoints of any objects that have them to the new location
if (mt != mapthings)
{
thinker_t *th;
mobj_t *mo;
for (th = thinkercap.next; th != &thinkercap; th = th->next)
{
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
continue;
mo = (mobj_t *)th;
// get offset from mt, which points to old mapthings, then add new location
if (mo->spawnpoint)
mo->spawnpoint = (mo->spawnpoint - mt) + mapthings;
}
}
mt = (mapthings+nummapthings-1);
mt->type = type;

View File

@ -49,7 +49,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"Streams come to an end\n"
"where they can no longer fall.\n"
"But if you went up...", 0},
{0, -336, 2064, 195, 1, 'E', SKINCOLOR_NEONGREEN, 0,
{0, -336, 2064, 195, 1, 'E', SKINCOLOR_EMERALD, 0,
"This one's in plain sight.\n"
"Why haven't you claimed it?\n"
"Surely you saw it.", 0},
@ -77,7 +77,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"Near the level's end,\n"
"another bridge spans a lake.\n"
"What could be under...?", 0},
{0, -170, 491, 3821, 2, 'E', SKINCOLOR_NEONGREEN, 0,
{0, -170, 491, 3821, 2, 'E', SKINCOLOR_EMERALD, 0,
"An ivied tunnel\n"
"has a corner that's sunlit.\n"
"Go reach for the sky!", 0},
@ -110,7 +110,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"Spinning through small gaps\n"
"can slip you into a cave.\n"
"In that cave's first stretch...", 0},
{0, 2848, -9088, 488, 4, 'E', SKINCOLOR_NEONGREEN, 0,
{0, 2848, -9088, 488, 4, 'E', SKINCOLOR_EMERALD, 0,
"The slime lake is deep,\n"
"but reaching the floor takes height.\n"
"Scream \"Geronimo!\"...", 0},
@ -138,7 +138,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"There is a hallway\n"
"that a button floods with slime.\n"
"Go through it again!", 0},
{0, -2468,-12128, 1312, 5, 'E', SKINCOLOR_NEONGREEN, 0,
{0, -2468,-12128, 1312, 5, 'E', SKINCOLOR_EMERALD, 0,
"Jumping on turtles\n"
"will send you springing skyward.\n"
"Now, do that six times...", 0},
@ -171,7 +171,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"A caved-in hallway?\n"
"The floor falls; the path goes down.\n"
"But those rocks looked weak...", 0},
{0, 12576, 16096, -992, 7, 'E', SKINCOLOR_NEONGREEN, 0,
{0, 12576, 16096, -992, 7, 'E', SKINCOLOR_EMERALD, 0,
"The end is quite dry.\n"
"Some rocks dam the water in.\n"
"Knuckles can fix that...", 0},
@ -199,7 +199,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"In the current maze\n"
"hides a dark room of columns.\n"
"Find it, then look up.", 0},
{0, 3104, 16192, 2408, 8, 'E', SKINCOLOR_NEONGREEN, 0,
{0, 3104, 16192, 2408, 8, 'E', SKINCOLOR_EMERALD, 0,
"That same dragon's eye\n"
"hides another secret room.\n"
"There, solve its riddle.", 0},
@ -232,7 +232,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"The final approach!\n"
"A tower holds the emblem\n"
"near a ring arrow.", 0},
{0, 9472, -5890, 710, 10, 'E', SKINCOLOR_NEONGREEN, 0,
{0, 9472, -5890, 710, 10, 'E', SKINCOLOR_EMERALD, 0,
"The right starting path\n"
"hides this near a canopy,\n"
"high, where two trees meet.", 0},
@ -260,7 +260,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"Some of these bookshelves\n"
"are not flush against the walls.\n"
"Wonder why that is?", 0},
{0, 12708,-13536, 4768, 11, 'E', SKINCOLOR_NEONGREEN, 0,
{0, 12708,-13536, 4768, 11, 'E', SKINCOLOR_EMERALD, 0,
"The ending's towers\n"
"are hiding a small alcove.\n"
"Check around outside.", 0},
@ -293,7 +293,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"Not far from the start,\n"
"if you climb toward the sky,\n"
"the cliffs hide something.", 0},
{0, 12504, 6848, 3424, 13, 'E', SKINCOLOR_NEONGREEN, 0,
{0, 12504, 6848, 3424, 13, 'E', SKINCOLOR_EMERALD, 0,
"Right by the exit,\n"
"an emblem lies on a cliff.\n"
"Ride ropes to reach it.", 0},
@ -321,7 +321,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"Where once a bridge stood,\n"
"now magma falls from above.\n"
"The bridge dropped something...", 0},
{0, 8287,-11043, 1328, 16, 'E', SKINCOLOR_NEONGREEN, 0,
{0, 8287,-11043, 1328, 16, 'E', SKINCOLOR_EMERALD, 0,
"A lake of magma\n"
"ebbs and flows unendingly.\n"
"Wait for its nadir.", 0},
@ -349,7 +349,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"Don't jump too high here!\n"
"No conveyor will catch you;\n"
"you'd fall to your death.", 0},
{0, -6432, -6192, 584, 22, 'E', SKINCOLOR_NEONGREEN, 0,
{0, -6432, -6192, 584, 22, 'E', SKINCOLOR_EMERALD, 0,
"Conveyors! Magma!\n"
"What an intense room this is!\n"
"But, what brought you here?", 0},
@ -377,7 +377,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"Gears with missing teeth\n"
"can hide a clever secret!\n"
"Think Green Hill Zone boss.", 0},
{0, 1920, 20608, 1064, 23, 'E', SKINCOLOR_NEONGREEN, 0,
{0, 1920, 20608, 1064, 23, 'E', SKINCOLOR_EMERALD, 0,
"Just before you reach\n"
"the defective cargo bay,\n"
"fly under a bridge.", 0},
@ -398,7 +398,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"[PH] In the ceiling of the conveyor belt + laser hallway.", 0},
{0,-13728,-13728, 1552, 24, 'D', SKINCOLOR_ORANGE, 0,
"[PH] On top of the platform with rows of spikes in reverse gravity.", 0},
{0,-14944, 768, 1232, 24, 'E', SKINCOLOR_NEONGREEN, 0,
{0,-14944, 768, 1232, 24, 'E', SKINCOLOR_EMERALD, 0,
"Follow the leader.", 0},
*/
@ -430,7 +430,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"The underground room\n"
"with platforms that fall and rise\n"
"only LOOKS empty...", 0},
{0 , 4960, -6112, 1312, 30, 'E', SKINCOLOR_NEONGREEN, 0,
{0 , 4960, -6112, 1312, 30, 'E', SKINCOLOR_EMERALD, 0,
"This one's straightforward.\n"
"What comes to mind when I say:\n"
"\"WELCOME TO WARP ZONE!\"?", 0},
@ -458,7 +458,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"Much like the last one,\n"
"you need to find some switches.\n"
"Only two, this time.", 0},
{0, 13184, 18880, 6672, 40, 'E', SKINCOLOR_NEONGREEN, 0,
{0, 13184, 18880, 6672, 40, 'E', SKINCOLOR_EMERALD, 0,
"The inner sanctum!\n"
"Teleport to its switches;\n"
"then, check near the goal.", 0},
@ -486,7 +486,7 @@ emblem_t emblemlocations[MAXEMBLEMS] =
"A room of currents;\n"
"most of them are marked by spikes.\n"
"This one? A corner.", 0},
{0, -4128, 21344, 1120, 41, 'E', SKINCOLOR_NEONGREEN, 0,
{0, -4128, 21344, 1120, 41, 'E', SKINCOLOR_EMERALD, 0,
"The only way to hit\n"
"all those gems at once is with\n"
"a radial blast.", 0},
@ -498,63 +498,63 @@ emblem_t emblemlocations[MAXEMBLEMS] =
// FLORAL FIELD
// ---
{0, 5394, -996, 160, 50, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0},
{0, 5394, -996, 160, 50, 'N', SKINCOLOR_RUST, 0, "", 0},
{ET_NGRADE, 0,0,0, 50, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0},
{ET_NTIME, 0,0,0, 50, 'T', SKINCOLOR_GREY, 40*TICRATE, "", 0},
// TOXIC PLATEAU
// ---
{0, 780, -1664, 32, 51, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0},
{0, 780, -1664, 32, 51, 'N', SKINCOLOR_RUST, 0, "", 0},
{ET_NGRADE, 0,0,0, 51, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0},
{ET_NTIME, 0,0,0, 51, 'T', SKINCOLOR_GREY, 50*TICRATE, "", 0},
// FLOODED COVE
// ---
{0, 1824, -1888, 2448, 52, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0},
{0, 1824, -1888, 2448, 52, 'N', SKINCOLOR_RUST, 0, "", 0},
{ET_NGRADE, 0,0,0, 52, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0},
{ET_NTIME, 0,0,0, 52, 'T', SKINCOLOR_GREY, 90*TICRATE, "", 0},
// CAVERN FORTRESS
// ---
{0, -3089, -431, 1328, 53, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0},
{0, -3089, -431, 1328, 53, 'N', SKINCOLOR_RUST, 0, "", 0},
{ET_NGRADE, 0,0,0, 53, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0},
{ET_NTIME, 0,0,0, 53, 'T', SKINCOLOR_GREY, 75*TICRATE, "", 0},
// DUSTY WASTELAND
// ---
{0, 957, 924, 2956, 54, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0},
{0, 957, 924, 2956, 54, 'N', SKINCOLOR_RUST, 0, "", 0},
{ET_NGRADE, 0,0,0, 54, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0},
{ET_NTIME, 0,0,0, 54, 'T', SKINCOLOR_GREY, 65*TICRATE, "", 0},
// MAGMA CAVES
// ---
{0, -2752, 3104, 1800, 55, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0},
{0, -2752, 3104, 1800, 55, 'N', SKINCOLOR_RUST, 0, "", 0},
{ET_NGRADE, 0,0,0, 55, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0},
{ET_NTIME, 0,0,0, 55, 'T', SKINCOLOR_GREY, 80*TICRATE, "", 0},
// EGG SATELLITE
// ---
{0, 5334, -609, 3426, 56, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0},
{0, 5334, -609, 3426, 56, 'N', SKINCOLOR_RUST, 0, "", 0},
{ET_NGRADE, 0,0,0, 56, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0},
{ET_NTIME, 0,0,0, 56, 'T', SKINCOLOR_GREY, 120*TICRATE, "", 0},
// BLACK HOLE
// ---
{0, 2108, 3776, 32, 57, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0},
{0, 2108, 3776, 32, 57, 'N', SKINCOLOR_RUST, 0, "", 0},
{ET_NGRADE, 0,0,0, 57, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0},
{ET_NTIME, 0,0,0, 57, 'T', SKINCOLOR_GREY, 150*TICRATE, "", 0},
// SPRING HILL
// ---
{0, -1840, -1024, 1644, 58, 'N', SKINCOLOR_ROSEWOOD, 0, "", 0},
{0, -1840, -1024, 1644, 58, 'N', SKINCOLOR_RUST, 0, "", 0},
{ET_NGRADE, 0,0,0, 58, 'Q', SKINCOLOR_TEAL, GRADE_A, "", 0},
{ET_NTIME, 0,0,0, 58, 'T', SKINCOLOR_GREY, 60*TICRATE, "", 0},
};
@ -565,7 +565,7 @@ extraemblem_t extraemblems[MAXEXTRAEMBLEMS] =
{"Game Complete", "Complete 1P Mode", 10, 'X', SKINCOLOR_BLUE, 0},
{"All Emeralds", "Complete 1P Mode with all Emeralds", 11, 'V', SKINCOLOR_GREY, 0},
{"Perfect Bonus", "Perfect Bonus on a non-secret stage", 30, 'P', SKINCOLOR_GOLD, 0},
{"SRB1 Remake", "Complete SRB1 Remake", 21, 'O', SKINCOLOR_ROSEWOOD, 0},
{"SRB1 Remake", "Complete SRB1 Remake", 21, 'O', SKINCOLOR_RUST, 0},
{"NiGHTS Mastery", "Show your mastery of NiGHTS!", 22, 'W', SKINCOLOR_TEAL, 0},
};

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

View File

@ -357,8 +357,6 @@ FUNCMATH FUNCINLINE static ATTRINLINE fixed_t FixedRound(fixed_t x)
return INT32_MAX;
}
#ifdef NEED_FIXED_VECTOR
typedef struct
{
fixed_t x;
@ -437,6 +435,4 @@ void FM_MultMatrix(matrix_t *dest, const matrix_t *multme);
void FM_Translate(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z);
void FM_Scale(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z);
#endif // defined NEED_FIXED_VECTOR
#endif //m_fixed.h

View File

@ -2203,6 +2203,7 @@ boolean M_Responder(event_t *ev)
if (modeattacking)
return true;
M_StartControlPanel();
M_Options(0);
currentMenu = &OP_SoundOptionsDef;
itemOn = 0;
return true;
@ -2212,6 +2213,7 @@ boolean M_Responder(event_t *ev)
if (modeattacking)
return true;
M_StartControlPanel();
M_Options(0);
M_VideoModeMenu(0);
return true;
#endif
@ -2223,6 +2225,7 @@ boolean M_Responder(event_t *ev)
if (modeattacking)
return true;
M_StartControlPanel();
M_Options(0);
M_SetupNextMenu(&OP_MainDef);
return true;
@ -2460,11 +2463,14 @@ void M_Drawer(void)
V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, customversionstring);
}
else
#if VERSION > 0 || SUBVERSION > 0
{
#ifdef DEVELOP // Development -- show revision / branch info
V_DrawThinString(vid.dupx, vid.height - 17*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, compbranch);
V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, comprevision);
#else // Regular build
V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, va("%s", VERSIONSTRING));
#else // Trunk build, show revision info
V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, va("%s (%s)", VERSIONSTRING, comprevision));
#endif
}
}
}
@ -2820,7 +2826,7 @@ static void M_DrawSlider(INT32 x, INT32 y, const consvar_t *cv)
void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines)
{
// Solid color textbox.
V_DrawFill(x+5, y+5, width*8+6, boxlines*8+6, 239);
V_DrawFill(x+5, y+5, width*8+6, boxlines*8+6, 159);
//V_DrawFill(x+8, y+8, width*8, boxlines*8, 31);
/*
patch_t *p;
@ -4745,7 +4751,7 @@ static void M_SetupChoosePlayer(INT32 choice)
if (Playing() == false)
{
S_StopMusic();
S_ChangeMusic(mus_chrsel, true);
S_ChangeMusicInternal("chrsel", true);
}
SP_PlayerDef.prevMenu = currentMenu;
@ -5196,7 +5202,7 @@ void M_DrawTimeAttackMenu(void)
lumpnum_t lumpnum;
char beststr[40];
S_ChangeMusic(mus_racent, true); // Eww, but needed for when user hits escape during demo playback
S_ChangeMusicInternal("racent", true); // Eww, but needed for when user hits escape during demo playback
V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE));
@ -5359,7 +5365,7 @@ static void M_TimeAttack(INT32 choice)
itemOn = tastart; // "Start" is selected.
G_SetGamestate(GS_TIMEATTACK);
S_ChangeMusic(mus_racent, true);
S_ChangeMusicInternal("racent", true);
}
// Drawing function for Nights Attack
@ -5369,7 +5375,7 @@ void M_DrawNightsAttackMenu(void)
lumpnum_t lumpnum;
char beststr[40];
S_ChangeMusic(mus_racent, true); // Eww, but needed for when user hits escape during demo playback
S_ChangeMusicInternal("racent", true); // Eww, but needed for when user hits escape during demo playback
V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE));
@ -5492,7 +5498,7 @@ static void M_NightsAttack(INT32 choice)
itemOn = nastart; // "Start" is selected.
G_SetGamestate(GS_TIMEATTACK);
S_ChangeMusic(mus_racent, true);
S_ChangeMusicInternal("racent", true);
}
// Player has selected the "START" from the nights attack screen
@ -5726,7 +5732,7 @@ static void M_ModeAttackEndGame(INT32 choice)
itemOn = currentMenu->lastOn;
G_SetGamestate(GS_TIMEATTACK);
modeattacking = ATTACKING_NONE;
S_ChangeMusic(mus_racent, true);
S_ChangeMusicInternal("racent", true);
// Update replay availability.
CV_AddValue(&cv_nextmap, 1);
CV_AddValue(&cv_nextmap, -1);
@ -6068,7 +6074,7 @@ static void M_RoomMenu(INT32 choice)
for (i = 0; room_list[i].header.buffer[0]; i++)
{
if(room_list[i].name != '\0')
if(*room_list[i].name != '\0')
{
MP_RoomMenu[i+1].text = room_list[i].name;
roomIds[i] = room_list[i].id;
@ -6932,7 +6938,7 @@ static void M_ToggleDigital(void)
if (nodigimusic) return;
S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
S_StopMusic();
S_ChangeMusic(mus_lclear, false);
S_ChangeMusicInternal("lclear", false);
M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING);
}
else
@ -6959,7 +6965,7 @@ static void M_ToggleMIDI(void)
I_InitMIDIMusic();
if (nomidimusic) return;
S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
S_ChangeMusic(mus_lclear, false);
S_ChangeMusicInternal("lclear", false);
M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING);
}
else

View File

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

View File

@ -3063,12 +3063,8 @@ void A_Invincibility(mobj_t *actor)
{
S_StopMusic();
if (mariomode)
{
S_ChangeMusic(mus_minvnc, false);
G_GhostAddColor(GHC_INVINCIBLE);
}
else
S_ChangeMusic(mus_invinc, false);
S_ChangeMusicInternal((mariomode) ? "minvnc" : "invinc", false);
}
}
@ -3104,7 +3100,7 @@ void A_SuperSneakers(mobj_t *actor)
else
{
S_StopMusic();
S_ChangeMusic(mus_shoes, false);
S_ChangeMusicInternal("shoes", false);
}
}
}
@ -5606,8 +5602,13 @@ void A_MixUp(mobj_t *actor)
P_SetThingPosition(players[i].mo);
#ifdef ESLOPE
players[i].mo->floorz = P_GetFloorZ(players[i].mo, players[i].mo->subsector->sector, players[i].mo->x, players[i].mo->y, NULL);
players[i].mo->ceilingz = P_GetCeilingZ(players[i].mo, players[i].mo->subsector->sector, players[i].mo->x, players[i].mo->y, NULL);
#else
players[i].mo->floorz = players[i].mo->subsector->sector->floorheight;
players[i].mo->ceilingz = players[i].mo->subsector->sector->ceilingheight;
#endif
P_CheckPosition(players[i].mo, players[i].mo->x, players[i].mo->y);
}
@ -6357,7 +6358,7 @@ void A_Boss2PogoTarget(mobj_t *actor)
if (actor->info->missilestate) // spawn the pogo stick collision box
{
mobj_t *pogo = P_SpawnMobj(actor->x, actor->y, actor->z - mobjinfo[actor->info->missilestate].height, actor->info->missilestate);
mobj_t *pogo = P_SpawnMobj(actor->x, actor->y, actor->z - mobjinfo[actor->info->missilestate].height, (mobjtype_t)actor->info->missilestate);
pogo->target = actor;
}
@ -7592,48 +7593,35 @@ void A_SetTargetsTarget(mobj_t *actor)
{
INT32 locvar1 = var1;
INT32 locvar2 = var2;
mobj_t *targetedmobj = NULL;
thinker_t *th;
mobj_t *mo2;
mobj_t *oldtarg = NULL, *newtarg = NULL;
#ifdef HAVE_BLUA
if (LUA_CallAction("A_SetTargetsTarget", actor))
return;
#endif
if ((!locvar1 && (!actor->target)) || (locvar1 && (!actor->tracer)))
// actor's target
if (locvar1) // or tracer
oldtarg = actor->tracer;
else
oldtarg = actor->target;
if (P_MobjWasRemoved(oldtarg))
return;
if ((!locvar1 && !locvar2 && (!actor->target->target))
|| (!locvar1 && locvar2 && (!actor->target->tracer))
|| (locvar1 && !locvar2 && (!actor->tracer->target))
|| (locvar1 && locvar2 && (!actor->tracer->tracer)))
return; // Don't search for nothing.
// scan the thinkers
for (th = thinkercap.next; th != &thinkercap; th = th->next)
{
if (th->function.acp1 != (actionf_p1)P_MobjThinker)
continue;
mo2 = (mobj_t *)th;
if ((!locvar1 && !locvar2 && (mo2 == actor->target->target))
|| (!locvar1 && locvar2 && (mo2 == actor->target->tracer))
|| (locvar1 && !locvar2 && (mo2 == actor->tracer->target))
|| (locvar1 && locvar2 && (mo2 == actor->tracer->tracer)))
{
targetedmobj = mo2;
break;
}
}
if (!targetedmobj)
return; // Oops, nothing found..
if (!locvar1)
P_SetTarget(&actor->target, targetedmobj);
// actor's target's target!
if (locvar2) // or tracer
newtarg = oldtarg->tracer;
else
P_SetTarget(&actor->tracer, targetedmobj);
newtarg = oldtarg->target;
if (P_MobjWasRemoved(newtarg))
return;
// set actor's new target
if (locvar1) // or tracer
P_SetTarget(&actor->tracer, newtarg);
else
P_SetTarget(&actor->target, newtarg);
}
// Function: A_SetObjectFlags

View File

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

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)
P_DoNightsScore(player);
break;
#ifdef BLUE_SPHERES
case MT_BLUEBALL:
if (!(P_CanPickupItem(player, false)))
return;
@ -489,7 +488,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (maptol & TOL_NIGHTS)
P_DoNightsScore(player);
break;
#endif
case MT_AUTOPICKUP:
case MT_BOUNCEPICKUP:
case MT_SCATTERPICKUP:
@ -837,10 +835,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
}
if (!(mo2->type == MT_NIGHTSWING || mo2->type == MT_RING || mo2->type == MT_COIN
#ifdef BLUE_SPHERES
|| mo2->type == MT_BLUEBALL
#endif
))
|| mo2->type == MT_BLUEBALL))
continue;
// Yay! The thing's in reach! Pull it in!
@ -1408,6 +1403,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
}
else
player->pflags |= PF_ITEMHANG;
// Can't jump first frame
player->pflags |= PF_JUMPSTASIS;
return;
case MT_BIGMINE:
case MT_BIGAIRMINE:
@ -1719,11 +1717,126 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
CONS_Printf(str, targetname, deadtarget ? M_GetText("killed") : M_GetText("hit"));
}
/** Checks if the level timer is over the timelimit and the round should end,
* unless you are in overtime. In which case leveltime may stretch out beyond
* timelimitintics and overtime's status will be checked here each tick.
* Verify that the value of ::cv_timelimit is greater than zero before
* calling this function.
*
* \sa cv_timelimit, P_CheckPointLimit, P_UpdateSpecials
*/
void P_CheckTimeLimit(void)
{
INT32 i, k;
if (!cv_timelimit.value)
return;
if (!(multiplayer || netgame))
return;
if (G_PlatformGametype())
return;
if (leveltime < timelimitintics)
return;
if (gameaction == ga_completed)
return;
//Tagmode round end but only on the tic before the
//XD_EXITLEVEL packet is recieved by all players.
if (G_TagGametype())
{
if (leveltime == (timelimitintics + 1))
{
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator
|| (players[i].pflags & PF_TAGGED) || (players[i].pflags & PF_TAGIT))
continue;
CONS_Printf(M_GetText("%s recieved double points for surviving the round.\n"), player_names[i]);
P_AddPlayerScore(&players[i], players[i].score);
}
}
if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
}
//Optional tie-breaker for Match/CTF
else if (cv_overtime.value)
{
INT32 playerarray[MAXPLAYERS];
INT32 tempplayer = 0;
INT32 spectators = 0;
INT32 playercount = 0;
//Figure out if we have enough participating players to care.
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && players[i].spectator)
spectators++;
}
if ((D_NumPlayers() - spectators) > 1)
{
// Play the starpost sfx after the first second of overtime.
if (gamestate == GS_LEVEL && (leveltime == (timelimitintics + TICRATE)))
S_StartSound(NULL, sfx_strpst);
// Normal Match
if (!G_GametypeHasTeams())
{
//Store the nodes of participating players in an array.
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && !players[i].spectator)
{
playerarray[playercount] = i;
playercount++;
}
}
//Sort 'em.
for (i = 1; i < playercount; i++)
{
for (k = i; k < playercount; k++)
{
if (players[playerarray[i-1]].score < players[playerarray[k]].score)
{
tempplayer = playerarray[i-1];
playerarray[i-1] = playerarray[k];
playerarray[k] = tempplayer;
}
}
}
//End the round if the top players aren't tied.
if (players[playerarray[0]].score == players[playerarray[1]].score)
return;
}
else
{
//In team match and CTF, determining a tie is much simpler. =P
if (redscore == bluescore)
return;
}
}
if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
}
if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
}
/** Checks if a player's score is over the pointlimit and the round should end.
* Verify that the value of ::cv_pointlimit is greater than zero before
* calling this function.
*
* \sa cv_pointlimit, P_UpdateSpecials
* \sa cv_pointlimit, P_CheckTimeLimit, P_UpdateSpecials
*/
void P_CheckPointLimit(void)
{
@ -2037,7 +2150,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
if (P_IsLocalPlayer(target->player) && target->player == &players[consoleplayer])
{
S_StopMusic(); // Stop the Music! Tails 03-14-2000
S_ChangeMusic(mus_gmover, false); // Yousa dead now, Okieday? Tails 03-14-2000
S_ChangeMusicInternal("gmover", false); // Yousa dead now, Okieday? Tails 03-14-2000
}
}
}
@ -2067,7 +2180,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
// allow them to try again, rather than sitting the whole thing out.
if (leveltime >= hidetime * TICRATE)
{
if (gametype == GT_HIDEANDSEEK)//suiciding in survivor makes you IT.
if (gametype == GT_TAG)//suiciding in survivor makes you IT.
{
target->player->pflags |= PF_TAGIT;
CONS_Printf(M_GetText("%s is now IT!\n"), player_names[target->player-players]); // Tell everyone who is it!
@ -2433,7 +2546,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
&& player->nightstime < 10*TICRATE)
{
//S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH
S_ChangeMusic(mus_drown,false);
S_ChangeMusicInternal("drown",false);
}
}
}

View File

@ -213,11 +213,29 @@ void P_RemoveSavegameMobj(mobj_t *th);
boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state);
boolean P_SetMobjState(mobj_t *mobj, statenum_t state);
void P_RunShields(void);
void P_RunOverlays(void);
void P_MobjThinker(mobj_t *mobj);
boolean P_RailThinker(mobj_t *mobj);
void P_PushableThinker(mobj_t *mobj);
void P_SceneryThinker(mobj_t *mobj);
fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
#define P_GetFloorZ(mobj, sector, x, y, line) P_MobjFloorZ(mobj, sector, NULL, x, y, line, false, false)
#define P_GetCeilingZ(mobj, sector, x, y, line) P_MobjCeilingZ(mobj, sector, NULL, x, y, line, true, false)
#define P_GetFOFTopZ(mobj, sector, fof, x, y, line) P_MobjCeilingZ(mobj, sectors + fof->secnum, sector, x, y, line, false, false)
#define P_GetFOFBottomZ(mobj, sector, fof, x, y, line) P_MobjFloorZ(mobj, sectors + fof->secnum, sector, x, y, line, true, false)
#define P_GetSpecialBottomZ(mobj, src, bound) P_MobjFloorZ(mobj, src, bound, mobj->x, mobj->y, NULL, src != bound, true)
#define P_GetSpecialTopZ(mobj, src, bound) P_MobjCeilingZ(mobj, src, bound, mobj->x, mobj->y, NULL, src == bound, true)
fixed_t P_CameraFloorZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
fixed_t P_CameraCeilingZ(camera_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
#define P_CameraGetFloorZ(mobj, sector, x, y, line) P_CameraFloorZ(mobj, sector, NULL, x, y, line, false, false)
#define P_CameraGetCeilingZ(mobj, sector, x, y, line) P_CameraCeilingZ(mobj, sector, NULL, x, y, line, true, false)
#define P_CameraGetFOFTopZ(mobj, sector, fof, x, y, line) P_CameraCeilingZ(mobj, sectors + fof->secnum, sector, x, y, line, false, false)
#define P_CameraGetFOFBottomZ(mobj, sector, fof, x, y, line) P_CameraFloorZ(mobj, sectors + fof->secnum, sector, x, y, line, true, false)
boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover);
boolean P_CheckDeathPitCollide(mobj_t *mo);
boolean P_CheckSolidLava(mobj_t *mo, ffloor_t *rover);
@ -279,6 +297,11 @@ extern fixed_t tmfloorz;
extern fixed_t tmceilingz;
extern mobj_t *tmfloorthing, *tmhitthing, *tmthing;
extern camera_t *mapcampointer;
extern fixed_t tmx;
extern fixed_t tmy;
#ifdef ESLOPE
extern pslope_t *tmfloorslope, *tmceilingslope;
#endif
/* cphipps 2004/08/30 */
extern void P_MapStart(void);
@ -317,7 +340,7 @@ void P_RadiusAttack(mobj_t *spot, mobj_t *source, fixed_t damagedist);
fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height);
boolean PIT_PushableMoved(mobj_t *thing);
void P_DoSpring(mobj_t *spring, mobj_t *object);
boolean P_DoSpring(mobj_t *spring, mobj_t *object);
//
// P_SETUP
@ -377,6 +400,7 @@ void P_PlayerEmeraldBurst(player_t *player, boolean toss);
void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck);
void P_PlayerFlagBurst(player_t *player, boolean toss);
void P_CheckTimeLimit(void);
void P_CheckPointLimit(void);
void P_CheckSurvivors(void);
boolean P_CheckRacers(void);

View File

@ -27,6 +27,10 @@
#include "r_splats.h"
#ifdef ESLOPE
#include "p_slopes.h"
#endif
#include "z_zone.h"
#include "lua_hook.h"
@ -34,8 +38,8 @@
fixed_t tmbbox[4];
mobj_t *tmthing;
static INT32 tmflags;
static fixed_t tmx;
static fixed_t tmy;
fixed_t tmx;
fixed_t tmy;
static precipmobj_t *tmprecipthing;
static fixed_t preciptmbbox[4];
@ -48,6 +52,9 @@ fixed_t tmfloorz, tmceilingz;
static fixed_t tmdropoffz, tmdrpoffceilz; // drop-off floor/ceiling heights
mobj_t *tmfloorthing; // the thing corresponding to tmfloorz or NULL if tmfloorz is from a sector
mobj_t *tmhitthing; // the solid thing you bumped into (for collisions)
#ifdef ESLOPE
pslope_t *tmfloorslope, *tmceilingslope;
#endif
// keep track of the line that lowers the ceiling,
// so missiles don't explode against sky hack walls
@ -102,7 +109,7 @@ boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z)
// MOVEMENT ITERATOR FUNCTIONS
// =========================================================================
void P_DoSpring(mobj_t *spring, mobj_t *object)
boolean P_DoSpring(mobj_t *spring, mobj_t *object)
{
INT32 pflags;
fixed_t offx, offy;
@ -110,16 +117,16 @@ void P_DoSpring(mobj_t *spring, mobj_t *object)
fixed_t horizspeed = spring->info->damage;
if (object->eflags & MFE_SPRUNG) // Object was already sprung this tic
return;
return false;
// Spectators don't trigger springs.
if (object->player && object->player->spectator)
return;
return false;
if (object->player && (object->player->pflags & PF_NIGHTSMODE))
{
/*Someone want to make these work like bumpers?*/
return;
return false;
}
object->eflags |= MFE_SPRUNG; // apply this flag asap!
@ -192,7 +199,7 @@ void P_DoSpring(mobj_t *spring, mobj_t *object)
P_ResetPlayer(object->player);
if (P_MobjFlip(object)*vertispeed > 0)
P_SetPlayerMobjState(object, S_PLAY_JUMP);
P_SetPlayerMobjState(object, S_PLAY_SPRING);
else if (P_MobjFlip(object)*vertispeed < 0)
P_SetPlayerMobjState(object, S_PLAY_FALL);
else // horizontal spring
@ -206,9 +213,10 @@ void P_DoSpring(mobj_t *spring, mobj_t *object)
if (spring->info->painchance)
{
object->player->pflags |= PF_JUMPED;
P_SetPlayerMobjState(object, S_PLAY_SPIN);
P_SetPlayerMobjState(object, S_PLAY_JUMP);
}
}
return true;
}
static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
@ -365,6 +373,7 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
static boolean PIT_CheckThing(mobj_t *thing)
{
fixed_t blockdist;
boolean iwassprung = false;
// don't clip against self
if (thing == tmthing)
@ -494,7 +503,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true; // overhead
if (thing->z + thing->height < tmthing->z)
return true; // underneath
if (tmthing->player && tmthing->flags & MF_SHOOTABLE)
if (tmthing->player && tmthing->flags & MF_SHOOTABLE && thing->health > 0)
{
UINT8 damagetype = 0;
if (thing->flags & MF_FIRE) // BURN!
@ -510,7 +519,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true; // overhead
if (tmthing->z + tmthing->height < thing->z)
return true; // underneath
if (thing->player && thing->flags & MF_SHOOTABLE)
if (thing->player && thing->flags & MF_SHOOTABLE && tmthing->health > 0)
{
UINT8 damagetype = 0;
if (tmthing->flags & MF_FIRE) // BURN!
@ -829,7 +838,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
{
if ( thing->z <= tmthing->z + tmthing->height
&& tmthing->z <= thing->z + thing->height)
P_DoSpring(thing, tmthing);
iwassprung = P_DoSpring(thing, tmthing);
}
}
@ -916,7 +925,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
{
if ( thing->z <= tmthing->z + tmthing->height
&& tmthing->z <= thing->z + thing->height)
P_DoSpring(thing, tmthing);
iwassprung = P_DoSpring(thing, tmthing);
}
// Are you touching the side of the object you're interacting with?
else if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height
@ -938,12 +947,14 @@ static boolean PIT_CheckThing(mobj_t *thing)
}
}
if (thing->flags & MF_SPRING && (tmthing->player || tmthing->flags & MF_PUSHABLE));
else
if (thing->flags & MF_SPRING && (tmthing->player || tmthing->flags & MF_PUSHABLE))
{
if (iwassprung) // this spring caused you to gain MFE_SPRUNG just now...
return false; // "cancel" P_TryMove via blocking so you keep your current position
}
// Monitors are not treated as solid to players who are jumping, spinning or gliding,
// unless it's a CTF team monitor and you're on the wrong team
if (thing->flags & MF_MONITOR && tmthing->player && tmthing->player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)
else if (thing->flags & MF_MONITOR && tmthing->player && tmthing->player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)
&& !((thing->type == MT_REDRINGBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_BLUERINGBOX && tmthing->player->ctfteam != 2)))
;
// z checking at last
@ -963,6 +974,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->z + thing->height > tmfloorz)
{
tmfloorz = thing->z + thing->height;
#ifdef ESLOPE
tmfloorslope = NULL;
#endif
}
return true;
}
@ -981,6 +995,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
else if (topz < tmceilingz && tmthing->z+tmthing->height <= thing->z+thing->height)
{
tmceilingz = topz;
#ifdef ESLOPE
tmceilingslope = NULL;
#endif
tmfloorthing = thing; // thing we may stand on
}
}
@ -994,6 +1011,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->z < tmceilingz)
{
tmceilingz = thing->z;
#ifdef ESLOPE
tmceilingslope = NULL;
#endif
}
return true;
}
@ -1011,6 +1031,9 @@ static boolean PIT_CheckThing(mobj_t *thing)
else if (topz > tmfloorz && tmthing->z >= thing->z)
{
tmfloorz = topz;
#ifdef ESLOPE
tmfloorslope = NULL;
#endif
tmfloorthing = thing; // thing we may stand on
}
}
@ -1133,11 +1156,13 @@ static boolean PIT_CheckLine(line_t *ld)
{
tmceilingz = opentop;
ceilingline = ld;
tmceilingslope = opentopslope;
}
if (openbottom > tmfloorz)
{
tmfloorz = openbottom;
tmfloorslope = openbottomslope;
}
if (highceiling > tmdrpoffceilz)
@ -1214,8 +1239,12 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
// that contains the point.
// Any contacted lines the step closer together
// will adjust them.
tmfloorz = tmdropoffz = newsubsec->sector->floorheight;
tmceilingz = tmdrpoffceilz = newsubsec->sector->ceilingheight;
tmfloorz = tmdropoffz = P_GetFloorZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->floorheight;
tmceilingz = P_GetCeilingZ(thing, newsubsec->sector, x, y, NULL); //newsubsec->sector->ceilingheight;
#ifdef ESLOPE
tmfloorslope = newsubsec->sector->f_slope;
tmceilingslope = newsubsec->sector->c_slope;
#endif
// Check list of fake floors and see if tmfloorz/tmceilingz need to be altered.
if (newsubsec->sector->ffloors)
@ -1226,35 +1255,48 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS))
continue;
topheight = P_GetFOFTopZ(thing, newsubsec->sector, rover, x, y, NULL);
bottomheight = P_GetFOFBottomZ(thing, newsubsec->sector, rover, x, y, NULL);
if (rover->flags & FF_GOOWATER && !(thing->flags & MF_NOGRAVITY))
{
// If you're inside goowater and slowing down
fixed_t sinklevel = FixedMul(thing->info->height/6, thing->scale);
fixed_t minspeed = FixedMul(thing->info->height/9, thing->scale);
if (thing->z < *rover->topheight && *rover->bottomheight < thingtop
if (thing->z < topheight && bottomheight < thingtop
&& abs(thing->momz) < minspeed)
{
// Oh no! The object is stick in between the surface of the goo and sinklevel! help them out!
if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z > *rover->topheight - sinklevel
if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z > topheight - sinklevel
&& thing->momz >= 0 && thing->momz < (minspeed>>2))
thing->momz += minspeed>>2;
else if (thing->eflags & MFE_VERTICALFLIP && thingtop < *rover->bottomheight + sinklevel
else if (thing->eflags & MFE_VERTICALFLIP && thingtop < bottomheight + sinklevel
&& thing->momz <= 0 && thing->momz > -(minspeed>>2))
thing->momz -= minspeed>>2;
// Land on the top or the bottom, depending on gravity flip.
if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z >= *rover->topheight - sinklevel && thing->momz <= 0)
if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z >= topheight - sinklevel && thing->momz <= 0)
{
if (tmfloorz < *rover->topheight - sinklevel)
tmfloorz = *rover->topheight - sinklevel;
if (tmfloorz < topheight - sinklevel) {
tmfloorz = topheight - sinklevel;
#ifdef ESLOPE
tmfloorslope = *rover->t_slope;
#endif
}
}
else if (thing->eflags & MFE_VERTICALFLIP && thingtop <= *rover->bottomheight + sinklevel && thing->momz >= 0)
else if (thing->eflags & MFE_VERTICALFLIP && thingtop <= bottomheight + sinklevel && thing->momz >= 0)
{
if (tmceilingz > *rover->bottomheight + sinklevel)
tmceilingz = *rover->bottomheight + sinklevel;
if (tmceilingz > bottomheight + sinklevel) {
tmceilingz = bottomheight + sinklevel;
#ifdef ESLOPE
tmceilingslope = *rover->b_slope;
#endif
}
}
}
continue;
@ -1271,30 +1313,40 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
if (rover->flags & FF_QUICKSAND)
{
if (thing->z < *rover->topheight && *rover->bottomheight < thingtop)
if (thing->z < topheight && bottomheight < thingtop)
{
if (tmfloorz < thing->z)
if (tmfloorz < thing->z) {
tmfloorz = thing->z;
#ifdef ESLOPE
tmfloorslope = NULL;
#endif
}
}
// Quicksand blocks never change heights otherwise.
continue;
}
delta1 = thing->z - (*rover->bottomheight
+ ((*rover->topheight - *rover->bottomheight)/2));
delta2 = thingtop - (*rover->bottomheight
+ ((*rover->topheight - *rover->bottomheight)/2));
delta1 = thing->z - (bottomheight
+ ((topheight - bottomheight)/2));
delta2 = thingtop - (bottomheight
+ ((topheight - bottomheight)/2));
if (*rover->topheight > tmfloorz && abs(delta1) < abs(delta2)
if (topheight > tmfloorz && abs(delta1) < abs(delta2)
&& !(rover->flags & FF_REVERSEPLATFORM))
{
tmfloorz = tmdropoffz = *rover->topheight;
tmfloorz = tmdropoffz = topheight;
#ifdef ESLOPE
tmfloorslope = *rover->t_slope;
#endif
}
if (*rover->bottomheight < tmceilingz && abs(delta1) >= abs(delta2)
if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2)
&& !(rover->flags & FF_PLATFORM)
&& !(thing->type == MT_SKIM && (rover->flags & FF_SWIMMABLE)))
{
tmceilingz = tmdrpoffceilz = *rover->bottomheight;
tmceilingz = tmdrpoffceilz = bottomheight;
#ifdef ESLOPE
tmceilingslope = *rover->b_slope;
#endif
}
}
}
@ -1367,11 +1419,19 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
delta1 = thing->z - (polybottom + ((polytop - polybottom)/2));
delta2 = thingtop - (polybottom + ((polytop - polybottom)/2));
if (polytop > tmfloorz && abs(delta1) < abs(delta2))
if (polytop > tmfloorz && abs(delta1) < abs(delta2)) {
tmfloorz = tmdropoffz = polytop;
#ifdef ESLOPE
tmfloorslope = NULL;
#endif
}
if (polybottom < tmceilingz && abs(delta1) >= abs(delta2))
if (polybottom < tmceilingz && abs(delta1) >= abs(delta2)) {
tmceilingz = tmdrpoffceilz = polybottom;
#ifdef ESLOPE
tmceilingslope = NULL;
#endif
}
}
plink = (polymaplink_t *)(plink->link.next);
}
@ -1473,8 +1533,9 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
// that contains the point.
// Any contacted lines the step closer together
// will adjust them.
tmfloorz = tmdropoffz = newsubsec->sector->floorheight;
tmceilingz = tmdrpoffceilz = newsubsec->sector->ceilingheight;
tmfloorz = tmdropoffz = P_CameraGetFloorZ(thiscam, newsubsec->sector, x, y, NULL);
tmceilingz = P_CameraGetCeilingZ(thiscam, newsubsec->sector, x, y, NULL);
// Cameras use the heightsec's heights rather then the actual sector heights.
// If you can see through it, why not move the camera through it too?
@ -1500,20 +1561,24 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
continue;
delta1 = thiscam->z - (*rover->bottomheight
+ ((*rover->topheight - *rover->bottomheight)/2));
delta2 = thingtop - (*rover->bottomheight
+ ((*rover->topheight - *rover->bottomheight)/2));
if (*rover->topheight > tmfloorz && abs(delta1) < abs(delta2))
topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, x, y, NULL);
bottomheight = P_CameraGetFOFBottomZ(thiscam, newsubsec->sector, rover, x, y, NULL);
delta1 = thiscam->z - (bottomheight
+ ((topheight - bottomheight)/2));
delta2 = thingtop - (bottomheight
+ ((topheight - bottomheight)/2));
if (topheight > tmfloorz && abs(delta1) < abs(delta2))
{
tmfloorz = tmdropoffz = *rover->topheight;
tmfloorz = tmdropoffz = topheight;
}
if (*rover->bottomheight < tmceilingz && abs(delta1) >= abs(delta2))
if (bottomheight < tmceilingz && abs(delta1) >= abs(delta2))
{
tmceilingz = tmdrpoffceilz = *rover->bottomheight;
tmceilingz = tmdrpoffceilz = bottomheight;
}
}
}
@ -1708,8 +1773,8 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
}
else
{
tmfloorz = thiscam->subsector->sector->floorheight;
tmceilingz = thiscam->subsector->sector->ceilingheight;
tmfloorz = P_CameraGetFloorZ(thiscam, thiscam->subsector->sector, x, y, NULL);
tmceilingz = P_CameraGetCeilingZ(thiscam, thiscam->subsector->sector, x, y, NULL);
}
// the move is ok,
@ -1775,6 +1840,10 @@ boolean PIT_PushableMoved(mobj_t *thing)
mobj_t *oldthing = tmthing;
line_t *oldceilline = ceilingline;
line_t *oldblockline = blockingline;
#ifdef ESLOPE
pslope_t *oldfslope = tmfloorslope;
pslope_t *oldcslope = tmceilingslope;
#endif
// Move the player
P_TryMove(thing, thing->x+stand->momx, thing->y+stand->momy, true);
@ -1787,6 +1856,10 @@ boolean PIT_PushableMoved(mobj_t *thing)
P_SetTarget(&tmthing, oldthing);
ceilingline = oldceilline;
blockingline = oldblockline;
#ifdef ESLOPE
tmfloorslope = oldfslope;
tmceilingslope = oldcslope;
#endif
thing->momz = stand->momz;
}
else
@ -1808,6 +1881,9 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
fixed_t tryy = thing->y;
fixed_t radius = thing->radius;
fixed_t thingtop = thing->z + thing->height;
#ifdef ESLOPE
fixed_t startingonground = P_IsObjectOnGround(thing);
#endif
floatok = false;
if (radius < MAXRADIUS/2)
@ -1853,7 +1929,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
// Don't 'step up' while springing,
// Only step up "if needed".
if (thing->player->panim == PA_JUMP
if (thing->player->panim == PA_SPRING
&& P_MobjFlip(thing)*thing->momz > FixedMul(FRACUNIT, thing->scale))
maxstep = 0;
}
@ -1896,13 +1972,23 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
{
if (thingtop == thing->ceilingz && tmceilingz > thingtop && tmceilingz - thingtop <= maxstep)
{
thing->z = tmceilingz - thing->height;
thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
else if (tmceilingz < thingtop && thingtop - tmceilingz <= maxstep)
{
thing->z = (thing->ceilingz = thingtop = tmceilingz) - thing->height;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
}
else if (thing->z == thing->floorz && tmfloorz < thing->z && thing->z - tmfloorz <= maxstep)
{
thing->z = tmfloorz;
thing->z = thing->floorz = tmfloorz;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
else if (tmfloorz > thing->z && tmfloorz - thing->z <= maxstep)
{
thing->z = thing->floorz = tmfloorz;
thing->eflags |= MFE_JUSTSTEPPEDDOWN;
}
}
@ -1973,6 +2059,25 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
thing->floorz = tmfloorz;
thing->ceilingz = tmceilingz;
#ifdef ESLOPE
// Assign thing's standingslope if needed
if (thing->z <= tmfloorz && !(thing->eflags & MFE_VERTICALFLIP)) {
if (!startingonground && tmfloorslope)
P_HandleSlopeLanding(thing, tmfloorslope);
if (thing->momz <= 0)
thing->standingslope = tmfloorslope;
}
else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) {
if (!startingonground && tmceilingslope)
P_HandleSlopeLanding(thing, tmceilingslope);
if (thing->momz >= 0)
thing->standingslope = tmceilingslope;
}
#endif
thing->x = x;
thing->y = y;
@ -1988,6 +2093,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y)
{
fixed_t tryx, tryy;
tryx = thing->x;
tryy = thing->y;
do {
@ -2310,15 +2416,25 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle)
{
fixed_t platx, platy;
subsector_t *glidesector;
fixed_t floorz, ceilingz;
platx = P_ReturnThrustX(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
platy = P_ReturnThrustY(player->mo, angle, player->mo->radius + FixedMul(8*FRACUNIT, player->mo->scale));
glidesector = R_PointInSubsector(player->mo->x + platx, player->mo->y + platy);
#ifdef ESLOPE
floorz = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y) : glidesector->sector->floorheight;
ceilingz = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y) : glidesector->sector->ceilingheight;
#else
floorz = glidesector->sector->floorheight;
ceilingz = glidesector->sector->ceilingheight;
#endif
if (glidesector->sector != player->mo->subsector->sector)
{
boolean floorclimb = false;
fixed_t topheight, bottomheight;
if (glidesector->sector->ffloors)
{
@ -2328,34 +2444,44 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle)
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER))
continue;
topheight = *rover->topheight;
bottomheight = *rover->bottomheight;
#ifdef ESLOPE
if (*rover->t_slope)
topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y);
if (*rover->b_slope)
bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y);
#endif
floorclimb = true;
if (player->mo->eflags & MFE_VERTICALFLIP)
{
if ((*rover->topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < *rover->topheight))
if ((topheight < player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) < topheight))
{
floorclimb = true;
}
if (*rover->topheight < player->mo->z) // Waaaay below the ledge.
if (topheight < player->mo->z) // Waaaay below the ledge.
{
floorclimb = false;
}
if (*rover->bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale))
if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale))
{
floorclimb = false;
}
}
else
{
if ((*rover->bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > *rover->bottomheight))
if ((bottomheight > player->mo->z) && ((player->mo->z - player->mo->momz) > bottomheight))
{
floorclimb = true;
}
if (*rover->bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge.
if (bottomheight > player->mo->z + player->mo->height) // Waaaay below the ledge.
{
floorclimb = false;
}
if (*rover->topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale))
if (topheight < player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale))
{
floorclimb = false;
}
@ -2368,30 +2494,30 @@ static boolean P_IsClimbingValid(player_t *player, angle_t angle)
if (player->mo->eflags & MFE_VERTICALFLIP)
{
if ((glidesector->sector->floorheight <= player->mo->z + player->mo->height)
&& ((player->mo->z + player->mo->height - player->mo->momz) <= glidesector->sector->floorheight))
if ((floorz <= player->mo->z + player->mo->height)
&& ((player->mo->z + player->mo->height - player->mo->momz) <= floorz))
floorclimb = true;
if ((glidesector->sector->floorheight > player->mo->z)
if ((floorz > player->mo->z)
&& glidesector->sector->floorpic == skyflatnum)
return false;
if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > glidesector->sector->ceilingheight)
|| (player->mo->z + player->mo->height <= glidesector->sector->floorheight))
if ((player->mo->z + player->mo->height - FixedMul(16*FRACUNIT,player->mo->scale) > ceilingz)
|| (player->mo->z + player->mo->height <= floorz))
floorclimb = true;
}
else
{
if ((glidesector->sector->ceilingheight >= player->mo->z)
&& ((player->mo->z - player->mo->momz) >= glidesector->sector->ceilingheight))
if ((ceilingz >= player->mo->z)
&& ((player->mo->z - player->mo->momz) >= ceilingz))
floorclimb = true;
if ((glidesector->sector->ceilingheight < player->mo->z+player->mo->height)
if ((ceilingz < player->mo->z+player->mo->height)
&& glidesector->sector->ceilingpic == skyflatnum)
return false;
if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < glidesector->sector->floorheight)
|| (player->mo->z >= glidesector->sector->ceilingheight))
if ((player->mo->z + FixedMul(16*FRACUNIT,player->mo->scale) < ceilingz)
|| (player->mo->z >= ceilingz))
floorclimb = true;
}
@ -2463,6 +2589,7 @@ isblocking:
line_t *checkline = li;
sector_t *checksector;
ffloor_t *rover;
fixed_t topheight, bottomheight;
boolean fofline = false;
INT32 side = P_PointOnLineSide(slidemo->x, slidemo->y, li);
@ -2478,13 +2605,23 @@ isblocking:
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
continue;
if (*rover->topheight < slidemo->z)
topheight = *rover->topheight;
bottomheight = *rover->bottomheight;
#ifdef ESLOPE
if (*rover->t_slope)
topheight = P_GetZAt(*rover->t_slope, slidemo->x, slidemo->y);
if (*rover->b_slope)
bottomheight = P_GetZAt(*rover->b_slope, slidemo->x, slidemo->y);
#endif
if (topheight < slidemo->z)
continue;
if (*rover->bottomheight > slidemo->z + slidemo->height)
if (bottomheight > slidemo->z + slidemo->height)
continue;
// Got this far, so I guess it's climbable.
// Got this far, so I guess it's climbable. // TODO: Climbing check, also, better method to do this?
if (rover->master->flags & ML_TFERLINE)
{
size_t linenum = li-checksector->lines[0];
@ -2509,8 +2646,8 @@ isblocking:
climbangle += (ANGLE_90 * (whichside ? -1 : 1));
if (((!slidemo->player->climbing && abs(slidemo->angle - ANGLE_90 - climbline) < ANGLE_45)
|| (slidemo->player->climbing == 1 && abs(slidemo->angle - climbline) < ANGLE_135))
if (((!slidemo->player->climbing && abs((slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45)
|| (slidemo->player->climbing == 1 && abs((slidemo->angle - climbline)) < ANGLE_135))
&& P_IsClimbingValid(slidemo->player, climbangle))
{
slidemo->angle = climbangle;
@ -3104,6 +3241,7 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
if (thing->subsector->sector->ffloors && (realcrush || thing->flags & MF_PUSHABLE))
{
ffloor_t *rover;
fixed_t topheight, bottomheight;
fixed_t delta1, delta2;
INT32 thingtop = thing->z + thing->height;
@ -3113,9 +3251,19 @@ static boolean PIT_ChangeSector(mobj_t *thing, boolean realcrush)
|| ((rover->flags & FF_BLOCKOTHERS) && !thing->player)) || !(rover->flags & FF_EXISTS))
continue;
delta1 = thing->z - (*rover->bottomheight + *rover->topheight)/2;
delta2 = thingtop - (*rover->bottomheight + *rover->topheight)/2;
if (*rover->bottomheight <= thing->ceilingz && abs(delta1) >= abs(delta2))
topheight = *rover->topheight;
bottomheight = *rover->bottomheight;
/*#ifdef ESLOPE
if (rover->t_slope)
topheight = P_GetZAt(rover->t_slope, thing->x, thing->y);
if (rover->b_slope)
bottomheight = P_GetZAt(rover->b_slope, thing->x, thing->y);
#endif*/
delta1 = thing->z - (bottomheight + topheight)/2;
delta2 = thingtop - (bottomheight + topheight)/2;
if (bottomheight <= thing->ceilingz && abs(delta1) >= abs(delta2))
{
if (thing->flags & MF_PUSHABLE)
{
@ -3786,7 +3934,7 @@ void P_MapEnd(void)
}
// P_FloorzAtPos
// Returns the floorz of the XYZ position
// Returns the floorz of the XYZ position // TODO: Need ceilingpos function too
// Tails 05-26-2003
fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
{
@ -3801,15 +3949,26 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
for (rover = sec->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!(rover->flags & FF_EXISTS))
continue;
if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE)))
continue;
topheight = *rover->topheight;
bottomheight = *rover->bottomheight;
#ifdef ESLOPE
if (*rover->t_slope)
topheight = P_GetZAt(*rover->t_slope, x, y);
if (*rover->b_slope)
bottomheight = P_GetZAt(*rover->b_slope, x, y);
#endif
if (rover->flags & FF_QUICKSAND)
{
if (z < *rover->topheight && *rover->bottomheight < thingtop)
if (z < topheight && bottomheight < thingtop)
{
if (floorz < z)
floorz = z;
@ -3817,10 +3976,10 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
continue;
}
delta1 = z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2));
delta2 = thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2));
if (*rover->topheight > floorz && abs(delta1) < abs(delta2))
floorz = *rover->topheight;
delta1 = z - (bottomheight + ((topheight - bottomheight)/2));
delta2 = thingtop - (bottomheight + ((topheight - bottomheight)/2));
if (topheight > floorz && abs(delta1) < abs(delta2))
floorz = topheight;
}
}

View File

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

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);
extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling;
#ifdef ESLOPE
extern pslope_t *opentopslope, *openbottomslope;
#endif
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
UINT32 frame; // frame number, plus bits see p_pspr.h
UINT8 sprite2; // player sprites
UINT16 anim_duration; // for FF_ANIMATE states
struct msecnode_s *touching_sectorlist; // a linked list of sectors where this object appears
@ -355,6 +356,10 @@ typedef struct mobj_s
INT32 cusval;
INT32 cvmem;
#ifdef ESLOPE
struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?)
#endif
// WARNING: New fields must be added separately to savegame and Lua.
} mobj_t;
@ -380,7 +385,8 @@ typedef struct precipmobj_s
// More drawing info: to determine current sprite.
angle_t angle; // orientation
spritenum_t sprite; // used to find patch_t and flip value
INT32 frame; // frame number, plus bits see p_pspr.h
UINT32 frame; // frame number, plus bits see p_pspr.h
UINT16 anim_duration; // for FF_ANIMATE states
struct mprecipsecnode_s *touching_sectorlist; // a linked list of sectors where this object appears

View File

@ -442,6 +442,8 @@ newseg:
// seg's ending vertex.
for (i = 0; i < numsegs; ++i)
{
if (segs[i].side != 0) // needs to be frontfacing
continue;
if (segs[i].v1->x == seg->v2->x && segs[i].v1->y == seg->v2->y)
{
// Make sure you didn't already add this seg...
@ -610,14 +612,17 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id)
INT32 poflags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES;
INT32 parentID = 0, potrans = 0;
if (seg->side != 0) // needs to be frontfacing
continue;
if (seg->linedef->special != POLYOBJ_START_LINE)
continue;
if (seg->linedef->tag != po->id)
continue;
Polyobj_GetInfo(po->id, &poflags, &parentID, &potrans); // apply extra settings if they exist!
// save original flags and translucency to reference later for netgames!
po->spawnflags = po->flags = poflags;
po->spawntrans = po->translucency = potrans;

View File

@ -36,9 +36,11 @@
#endif
/// \brief Frame flags: only the frame number
#define FF_FRAMEMASK 0x7fff
#define FF_FRAMEMASK 0x3fff
/// \brief Frame flags: Simple stateless animation
#define FF_ANIMATE 0x4000
/// \brief Frame flags: frame always appears full bright
#define FF_FULLBRIGHT 0x8000 //
#define FF_FULLBRIGHT 0x8000
/// \brief Frame flags: 0 = no trans(opaque), 1-15 = transl. table
#define FF_TRANSMASK 0xf0000
/// \brief shift for FF_TRANSMASK

View File

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

View File

@ -72,6 +72,10 @@
#include "hardware/hw_light.h"
#endif
#ifdef ESLOPE
#include "p_slopes.h"
#endif
//
// Map MD5, calculated on level load.
// Sent to clients in PT_SERVERINFO.
@ -176,10 +180,11 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
mapheaderinfo[num]->typeoflevel = 0;
DEH_WriteUndoline("NEXTLEVEL", va("%d", mapheaderinfo[num]->nextlevel), UNDO_NONE);
mapheaderinfo[num]->nextlevel = (INT16)(i + 1);
DEH_WriteUndoline("MUSICSLOT", va("%d", mapheaderinfo[num]->musicslot), UNDO_NONE);
mapheaderinfo[num]->musicslot = mus_map01m + num;
DEH_WriteUndoline("MUSICSLOTTRACK", va("%d", mapheaderinfo[num]->musicslottrack), UNDO_NONE);
mapheaderinfo[num]->musicslottrack = 0;
DEH_WriteUndoline("MUSIC", mapheaderinfo[num]->musname, UNDO_NONE);
snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i));
mapheaderinfo[num]->musname[6] = 0;
DEH_WriteUndoline("MUSICTRACK", va("%d", mapheaderinfo[num]->mustrack), UNDO_NONE);
mapheaderinfo[num]->mustrack = 0;
DEH_WriteUndoline("FORCECHARACTER", va("%d", mapheaderinfo[num]->forcecharacter), UNDO_NONE);
mapheaderinfo[num]->forcecharacter[0] = '\0';
DEH_WriteUndoline("WEATHER", va("%d", mapheaderinfo[num]->weather), UNDO_NONE);
@ -846,7 +851,7 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum)
//
// P_LoadThings
//
static void P_LoadThings(lumpnum_t lumpnum)
static void P_PrepareThings(lumpnum_t lumpnum)
{
size_t i;
mapthing_t *mt;
@ -884,13 +889,27 @@ static void P_LoadThings(lumpnum_t lumpnum)
}
Z_Free(datastart);
}
static void P_LoadThings(void)
{
size_t i;
mapthing_t *mt;
// Loading the things lump itself into memory is now handled in P_PrepareThings, above
mt = mapthings;
numhuntemeralds = 0;
for (i = 0; i < nummapthings; i++, mt++)
{
sector_t *mtsector = R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)->sector;
// Z for objects
mt->z = (INT16)(R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)
->sector->floorheight>>FRACBITS);
mt->z = (INT16)(
#ifdef ESLOPE
mtsector->f_slope ? P_GetZAt(mtsector->f_slope, mt->x << FRACBITS, mt->y << FRACBITS) :
#endif
mtsector->floorheight)>>FRACBITS;
if (mt->type == 1700 // MT_AXIS
|| mt->type == 1701 // MT_AXISTRANSFER
@ -1421,6 +1440,29 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
#endif
case 413: // Change music
{
char process[8+1];
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
if (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0')
{
M_Memcpy(process,msd->bottomtexture,8);
process[8] = '\0';
sd->bottomtexture = get_number(process)-1;
}
M_Memcpy(process,msd->toptexture,8);
process[8] = '\0';
sd->text = Z_Malloc(7, PU_LEVEL, NULL);
// If they type in O_ or D_ and their music name, just shrug,
// then copy the rest instead.
if ((process[0] == 'O' || process[0] == 'D') && process[7])
M_Memcpy(sd->text, process+2, 6);
else // Assume it's a proper music name.
M_Memcpy(sd->text, process, 6);
sd->text[6] = 0;
break;
}
case 414: // Play SFX
{
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
@ -1431,13 +1473,6 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
process[8] = '\0';
sd->toptexture = get_number(process);
}
if (sd->special == 413 && (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0'))
{
char process[8+1];
M_Memcpy(process,msd->bottomtexture,8);
process[8] = '\0';
sd->bottomtexture = get_number(process)-1;
}
break;
}
@ -2115,7 +2150,8 @@ void P_LoadThingsOnly(void)
P_LevelInitStuff();
P_LoadThings(lastloadedmaplumpnum + ML_THINGS);
P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
P_LoadThings();
P_SpawnSecretItems(true);
}
@ -2351,7 +2387,7 @@ boolean P_SetupLevel(boolean skipprecip)
// use gamemap to get map number.
// 99% of the things already did, so.
// Map header should always be in place at this point
INT32 i, loadprecip = 1;
INT32 i, loadprecip = 1, ranspecialwipe = 0;
INT32 loademblems = 1;
INT32 fromnetsave = 0;
boolean loadedbm = false;
@ -2424,6 +2460,28 @@ boolean P_SetupLevel(boolean skipprecip)
// will be set by player think.
players[consoleplayer].viewz = 1;
// Special stage fade to white
// This is handled BEFORE sounds are stopped.
if (rendermode != render_none && G_IsSpecialStage(gamemap))
{
tic_t starttime = I_GetTime();
tic_t endtime = starttime + (3*TICRATE)/2;
S_StartSound(NULL, sfx_s3kaf);
F_WipeStartScreen();
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0);
F_WipeEndScreen();
F_RunWipe(wipedefs[wipe_speclevel_towhite], false);
// Hold on white for extra effect.
while (I_GetTime() < endtime)
I_Sleep();
ranspecialwipe = 1;
}
// Make sure all sounds are stopped before Z_FreeTags.
S_StopSounds();
S_ClearSfx();
@ -2433,25 +2491,28 @@ boolean P_SetupLevel(boolean skipprecip)
S_Start();
// Let's fade to black here
if (rendermode != render_none)
// But only if we didn't do the special stage wipe
if (rendermode != render_none && !ranspecialwipe)
{
F_WipeStartScreen();
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
F_WipeEndScreen();
F_RunWipe(wipedefs[wipe_level_toblack], false);
}
// Print "SPEEDING OFF TO [ZONE] [ACT 1]..."
if (rendermode != render_none)
{
// Don't include these in the fade!
{
char tx[64];
V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to..."));
snprintf(tx, 63, "%s%s%s",
mapheaderinfo[gamemap-1]->lvlttl,
(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE",
(mapheaderinfo[gamemap-1]->actnum > 0) ? va(", Act %d",mapheaderinfo[gamemap-1]->actnum) : "");
V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx);
I_UpdateNoVsync();
}
char tx[64];
V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to..."));
snprintf(tx, 63, "%s%s%s",
mapheaderinfo[gamemap-1]->lvlttl,
(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE",
(mapheaderinfo[gamemap-1]->actnum > 0) ? va(", Act %d",mapheaderinfo[gamemap-1]->actnum) : "");
V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx);
I_UpdateNoVsync();
}
#ifdef HAVE_BLUA
@ -2532,7 +2593,13 @@ boolean P_SetupLevel(boolean skipprecip)
P_MapStart();
P_LoadThings(lastloadedmaplumpnum + ML_THINGS);
P_PrepareThings(lastloadedmaplumpnum + ML_THINGS);
#ifdef ESLOPE
P_ResetDynamicSlopes();
#endif
P_LoadThings();
P_SpawnSecretItems(loademblems);
@ -2743,7 +2810,7 @@ boolean P_SetupLevel(boolean skipprecip)
// Remove the loading shit from the screen
if (rendermode != render_none)
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (ranspecialwipe) ? 0 : 31);
if (precache || dedicated)
R_PrecacheLevel();

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_sky.h"
#include "p_polyobj.h"
#include "p_slopes.h"
#include "hu_stuff.h"
#include "m_misc.h"
#include "m_cond.h" //unlock triggers
@ -2389,20 +2390,19 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
// console player only unless NOCLIMB is set
if ((line->flags & ML_NOCLIMB) || (mo && mo->player && P_IsLocalPlayer(mo->player)))
{
UINT16 musicnum = (UINT16)sides[line->sidenum[0]].toptexture; //P_AproxDistance(line->dx, line->dy)>>FRACBITS;
UINT16 tracknum = (UINT16)sides[line->sidenum[0]].bottomtexture;
mapmusic = musicnum | (tracknum << MUSIC_TRACKSHIFT);
if (!(line->flags & ML_BLOCKMONSTERS))
mapmusic |= MUSIC_RELOADRESET;
strncpy(mapmusname, sides[line->sidenum[0]].text, 7);
mapmusname[6] = 0;
if (musicnum >= NUMMUSIC || musicnum == mus_None)
S_StopMusic();
else
S_ChangeMusic(mapmusic, !(line->flags & ML_EFFECT4));
mapmusflags = tracknum & MUSIC_TRACKMASK;
if (!(line->flags & ML_BLOCKMONSTERS))
mapmusflags |= MUSIC_RELOADRESET;
S_ChangeMusic(mapmusname, mapmusflags, !(line->flags & ML_EFFECT4));
// Except, you can use the ML_BLOCKMONSTERS flag to change this behavior.
// if (mapmusic & MUSIC_RELOADRESET) then it will reset the music in G_PlayerReborn.
// if (mapmusflags & MUSIC_RELOADRESET) then it will reset the music in G_PlayerReborn.
}
break;
@ -3038,6 +3038,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS);
sector_t *sec; // Sector that the FOF is visible (or not visible) in
ffloor_t *rover; // FOF to vanish/un-vanish
ffloortype_e oldflags; // store FOF's old flags
for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;)
{
@ -3061,11 +3062,17 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
return;
}
oldflags = rover->flags;
// Abracadabra!
if (line->flags & ML_NOCLIMB)
rover->flags |= FF_EXISTS;
else
rover->flags &= ~FF_EXISTS;
// if flags changed, reset sector's light list
if (rover->flags != oldflags)
sec->moved = true;
}
}
break;
@ -3365,6 +3372,7 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n
static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *targetsec)
{
ffloor_t *rover;
fixed_t top, bottom;
if (!mo->player) // should NEVER happen
return false;
@ -3381,6 +3389,9 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar
//if (!(rover->flags & FF_EXISTS))
// return false;
top = P_GetSpecialTopZ(mo, sector, targetsec);
bottom = P_GetSpecialBottomZ(mo, sector, targetsec);
// Check the 3D floor's type...
if (rover->flags & FF_BLOCKPLAYER)
{
@ -3388,27 +3399,27 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar
if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING))
{
if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != *rover->topheight)
if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != top)
return false;
}
else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR))
{
if (!(mo->eflags & MFE_VERTICALFLIP)
|| mo->z + mo->height != *rover->bottomheight)
|| mo->z + mo->height != bottom)
return false;
}
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
{
if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == *rover->bottomheight)
|| (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == *rover->topheight)))
if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == bottom)
|| (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == top)))
return false;
}
}
else
{
// Water and intangible FOFs
if (mo->z > *rover->topheight || (mo->z + mo->height) < *rover->bottomheight)
if (mo->z > top || (mo->z + mo->height) < bottom)
return false;
}
@ -3426,9 +3437,9 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar
static inline boolean P_MobjReadyToTrigger(mobj_t *mo, sector_t *sec)
{
if (mo->eflags & MFE_VERTICALFLIP)
return (mo->z+mo->height == sec->ceilingheight && sec->flags & SF_FLIPSPECIAL_CEILING);
return (mo->z+mo->height == P_GetSpecialTopZ(mo, sec, sec) && sec->flags & SF_FLIPSPECIAL_CEILING);
else
return (mo->z == sec->floorheight && sec->flags & SF_FLIPSPECIAL_FLOOR);
return (mo->z == P_GetSpecialBottomZ(mo, sec, sec) && sec->flags & SF_FLIPSPECIAL_FLOOR);
}
/** Applies a sector special to a player.
@ -4387,27 +4398,27 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING))
{
if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != *rover->topheight)
if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector))
continue;
}
else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)
&& !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR))
{
if (!(player->mo->eflags & MFE_VERTICALFLIP)
|| player->mo->z + player->mo->height != *rover->bottomheight)
|| player->mo->z + player->mo->height != P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector))
continue;
}
else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH)
{
if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == *rover->bottomheight)
|| (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == *rover->topheight)))
if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector))
|| (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector))))
continue;
}
}
else
{
// Water and DEATH FOG!!! heh
if (player->mo->z > *rover->topheight || (player->mo->z + player->mo->height) < *rover->bottomheight)
if (player->mo->z > P_GetSpecialTopZ(player->mo, sectors + rover->secnum, sector) || (player->mo->z + player->mo->height) < P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, sector))
continue;
}
@ -4517,6 +4528,7 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector)
{
boolean nofloorneeded = false;
fixed_t f_affectpoint, c_affectpoint;
if (!sector->special) // nothing special, exit
return;
@ -4579,16 +4591,19 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector)
return;
}
f_affectpoint = P_GetSpecialBottomZ(player->mo, sector, sector);
c_affectpoint = P_GetSpecialTopZ(player->mo, sector, sector);
// Only go further if on the ground
if ((sector->flags & SF_FLIPSPECIAL_FLOOR) && !(sector->flags & SF_FLIPSPECIAL_CEILING) && player->mo->z != sector->floorheight)
if ((sector->flags & SF_FLIPSPECIAL_FLOOR) && !(sector->flags & SF_FLIPSPECIAL_CEILING) && player->mo->z != f_affectpoint)
return;
if ((sector->flags & SF_FLIPSPECIAL_CEILING) && !(sector->flags & SF_FLIPSPECIAL_FLOOR) && player->mo->z + player->mo->height != sector->ceilingheight)
if ((sector->flags & SF_FLIPSPECIAL_CEILING) && !(sector->flags & SF_FLIPSPECIAL_FLOOR) && player->mo->z + player->mo->height != c_affectpoint)
return;
if ((sector->flags & SF_FLIPSPECIAL_BOTH)
&& player->mo->z != sector->floorheight
&& player->mo->z + player->mo->height != sector->ceilingheight)
&& player->mo->z != f_affectpoint
&& player->mo->z + player->mo->height != c_affectpoint)
return;
P_ProcessSpecialSector(player, sector, NULL);
@ -4637,126 +4652,34 @@ void P_PlayerInSpecialSector(player_t *player)
/** Animate planes, scroll walls, etc. and keeps track of level timelimit and exits if time is up.
*
* \sa cv_timelimit, P_CheckPointLimit
* \sa P_CheckTimeLimit, P_CheckPointLimit
*/
void P_UpdateSpecials(void)
{
anim_t *anim;
INT32 i, k;
INT32 i;
INT32 pic;
size_t j;
levelflat_t *foundflats; // for flat animation
// LEVEL TIMER
// Exit if the timer is equal to or greater the timelimit, unless you are
// in overtime. In which case leveltime may stretch out beyond timelimitintics
// and overtime's status will be checked here each tick.
if (cv_timelimit.value && timelimitintics <= leveltime && (multiplayer || netgame)
&& G_RingSlingerGametype() && (gameaction != ga_completed))
{
boolean pexit = false;
//Tagmode round end but only on the tic before the
//XD_EXITLEVEL packet is recieved by all players.
if (G_TagGametype())
{
if (leveltime == (timelimitintics + 1))
{
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator
|| (players[i].pflags & PF_TAGGED) || (players[i].pflags & PF_TAGIT))
continue;
CONS_Printf(M_GetText("%s recieved double points for surviving the round.\n"), player_names[i]);
P_AddPlayerScore(&players[i], players[i].score);
}
}
pexit = true;
}
//Optional tie-breaker for Match/CTF
else if (G_RingSlingerGametype() && cv_overtime.value)
{
INT32 playerarray[MAXPLAYERS];
INT32 tempplayer = 0;
INT32 spectators = 0;
INT32 playercount = 0;
//Figure out if we have enough participating players to care.
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && players[i].spectator)
spectators++;
}
if ((D_NumPlayers() - spectators) > 1)
{
// Play the starpost sfx after the first second of overtime.
if (gamestate == GS_LEVEL && (leveltime == (timelimitintics + TICRATE)))
S_StartSound(NULL, sfx_strpst);
// Normal Match
if (!G_GametypeHasTeams())
{
//Store the nodes of participating players in an array.
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && !players[i].spectator)
{
playerarray[playercount] = i;
playercount++;
}
}
//Sort 'em.
for (i = 1; i < playercount; i++)
{
for (k = i; k < playercount; k++)
{
if (players[playerarray[i-1]].score < players[playerarray[k]].score)
{
tempplayer = playerarray[i-1];
playerarray[i-1] = playerarray[k];
playerarray[k] = tempplayer;
}
}
}
//End the round if the top players aren't tied.
if (!(players[playerarray[0]].score == players[playerarray[1]].score))
pexit = true;
}
else
{
//In team match and CTF, determining a tie is much simpler. =P
if (!(redscore == bluescore))
pexit = true;
}
}
else
pexit = true;
}
else
pexit = true;
if (server && pexit)
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
}
P_CheckTimeLimit();
// POINT LIMIT
P_CheckPointLimit();
// Dynamic slopeness
P_RunDynamicSlopes();
// ANIMATE TEXTURES
for (anim = anims; anim < lastanim; anim++)
{
for (i = anim->basepic; i < anim->basepic + anim->numpics; i++)
for (i = 0; i < anim->numpics; i++)
{
pic = anim->basepic + ((leveltime/anim->speed + i) % anim->numpics);
if (anim->istexture)
texturetranslation[i] = pic;
texturetranslation[anim->basepic+i] = pic;
}
}
@ -4892,6 +4815,12 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
ffloor->topyoffs = &sec2->ceiling_yoffs;
ffloor->topangle = &sec2->ceilingpic_angle;
#ifdef ESLOPE
// Add slopes
ffloor->t_slope = &sec2->c_slope;
ffloor->b_slope = &sec2->f_slope;
#endif
if ((flags & FF_SOLID) && (master->flags & ML_EFFECT1)) // Block player only
flags &= ~FF_BLOCKOTHERS;
@ -5325,6 +5254,7 @@ void T_LaserFlash(laserthink_t *flash)
sector_t *sourcesec;
ffloor_t *ffloor = flash->ffloor;
sector_t *sector = flash->sector;
fixed_t top, bottom;
if (!ffloor || !(ffloor->flags & FF_EXISTS))
return;
@ -5348,8 +5278,11 @@ void T_LaserFlash(laserthink_t *flash)
&& thing->flags & MF_BOSS)
continue; // Don't hurt bosses
if (thing->z >= sourcesec->ceilingheight
|| thing->z + thing->height <= sourcesec->floorheight)
top = P_GetSpecialTopZ(thing, sourcesec, sector);
bottom = P_GetSpecialBottomZ(thing, sourcesec, sector);
if (thing->z >= top
|| thing->z + thing->height <= bottom)
continue;
if (thing->flags & MF_SHOOTABLE)
@ -6094,31 +6027,6 @@ void P_SpawnSpecials(INT32 fromnetsave)
P_AddRaiseThinker(lines[i].frontsector, &lines[i]);
break;
#ifdef SLOPENESS
case 999:
sec = sides[*lines[i].sidenum].sector-sectors;
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
{
size_t counting;
sectors[s].floorangle = ANGLE_45;
for (counting = 0; counting < sectors[s].linecount/2; counting++)
{
sectors[s].lines[counting]->v1->z = sectors[sec].floorheight;
CONS_Debug(DBG_GAMELOGIC, "Set it to %d\n", sectors[s].lines[counting]->v1->z>>FRACBITS);
}
for (counting = sectors[s].linecount/2; counting < sectors[s].linecount; counting++)
{
sectors[s].lines[counting]->v1->z = sectors[sec].ceilingheight;
CONS_Debug(DBG_GAMELOGIC, "Set it to %d\n", sectors[s].lines[counting]->v1->z>>FRACBITS);
}
sectors[s].special = 65535;
CONS_Debug(DBG_GAMELOGIC, "Found & Set slope!\n");
}
break;
#endif
case 200: // Double light effect
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_CUTSPRITES|FF_DOUBLESHADOW, secthinkers);
break;
@ -6428,6 +6336,14 @@ void P_SpawnSpecials(INT32 fromnetsave)
sectors[s].midmap = lines[i].frontsector->midmap;
break;
#ifdef ESLOPE // Slope copy specials. Handled here for sanity.
case 720:
case 721:
case 722:
P_CopySectorSlope(&lines[i]);
break;
#endif
default:
break;
}
@ -6632,6 +6548,8 @@ void T_Scroll(scroll_t *s)
if (thing->eflags & MFE_PUSHED) // Already pushed this tic by an exclusive pusher.
continue;
height = P_GetSpecialBottomZ(thing, sec, psec);
if (!(thing->flags & MF_NOCLIP)) // Thing must be clipped
if (!(thing->flags & MF_NOGRAVITY || thing->z+thing->height != height)) // Thing must a) be non-floating and have z+height == height
{
@ -6652,6 +6570,8 @@ void T_Scroll(scroll_t *s)
if (thing->eflags & MFE_PUSHED)
continue;
height = P_GetSpecialBottomZ(thing, sec, sec);
if (!(thing->flags & MF_NOCLIP) &&
(!(thing->flags & MF_NOGRAVITY || thing->z > height)))
{
@ -6691,6 +6611,8 @@ void T_Scroll(scroll_t *s)
if (thing->eflags & MFE_PUSHED)
continue;
height = P_GetSpecialTopZ(thing, sec, psec);
if (!(thing->flags & MF_NOCLIP)) // Thing must be clipped
if (!(thing->flags & MF_NOGRAVITY || thing->z != height))// Thing must a) be non-floating and have z == height
{
@ -6711,6 +6633,8 @@ void T_Scroll(scroll_t *s)
if (thing->eflags & MFE_PUSHED)
continue;
height = P_GetSpecialTopZ(thing, sec, sec);
if (!(thing->flags & MF_NOCLIP) &&
(!(thing->flags & MF_NOGRAVITY || thing->z+thing->height < height)))
{
@ -7004,7 +6928,7 @@ static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32
*/
void T_Friction(friction_t *f)
{
sector_t *sec;
sector_t *sec, *referrer = NULL;
mobj_t *thing;
msecnode_t *node;
@ -7013,7 +6937,7 @@ void T_Friction(friction_t *f)
// Make sure the sector type hasn't changed
if (f->roverfriction)
{
sector_t *referrer = sectors + f->referrer;
referrer = sectors + f->referrer;
if (!(GETSECSPECIAL(referrer->special, 3) == 1
|| GETSECSPECIAL(referrer->special, 3) == 3))
@ -7045,9 +6969,7 @@ void T_Friction(friction_t *f)
{
if (f->roverfriction)
{
sector_t *referrer = &sectors[f->referrer];
if (thing->floorz != referrer->ceilingheight)
if (thing->floorz != P_GetSpecialTopZ(thing, referrer, sec))
{
node = node->m_snext;
continue;
@ -7060,7 +6982,7 @@ void T_Friction(friction_t *f)
thing->movefactor = f->movefactor;
}
}
else if (sec->floorheight == thing->floorz && (thing->friction == ORIG_FRICTION // normal friction?
else if (P_GetSpecialBottomZ(thing, sec, sec) == thing->floorz && (thing->friction == ORIG_FRICTION // normal friction?
|| f->friction < thing->friction))
{
thing->friction = f->friction;
@ -7334,7 +7256,7 @@ static inline boolean PIT_PushThing(mobj_t *thing)
*/
void T_Pusher(pusher_t *p)
{
sector_t *sec;
sector_t *sec, *referrer = NULL;
mobj_t *thing;
msecnode_t *node;
INT32 xspeed = 0,yspeed = 0;
@ -7343,7 +7265,6 @@ void T_Pusher(pusher_t *p)
//INT32 ht = 0;
boolean inFOF;
boolean touching;
boolean foundfloor = false;
boolean moved;
xspeed = yspeed = 0;
@ -7355,19 +7276,16 @@ void T_Pusher(pusher_t *p)
if (p->roverpusher)
{
sector_t *referrer = &sectors[p->referrer];
referrer = &sectors[p->referrer];
if (GETSECSPECIAL(referrer->special, 3) == 2
|| GETSECSPECIAL(referrer->special, 3) == 3)
foundfloor = true;
if (!(GETSECSPECIAL(referrer->special, 3) == 2
|| GETSECSPECIAL(referrer->special, 3) == 3))
return;
}
else if (!(GETSECSPECIAL(sec->special, 3) == 2
|| GETSECSPECIAL(sec->special, 3) == 3))
return;
if (p->roverpusher && foundfloor == false) // Not even a 3d floor has the PUSH_MASK.
return;
// For constant pushers (wind/current) there are 3 situations:
//
// 1) Affected Thing is above the floor.
@ -7442,41 +7360,38 @@ void T_Pusher(pusher_t *p)
// Find the area that the 'thing' is in
if (p->roverpusher)
{
sector_t *referrer = &sectors[p->referrer];
INT32 special;
fixed_t top, bottom;
special = GETSECSPECIAL(referrer->special, 3);
if (!(special == 2 || special == 3))
return;
top = P_GetSpecialTopZ(thing, referrer, sec);
bottom = P_GetSpecialBottomZ(thing, referrer, sec);
if (thing->eflags & MFE_VERTICALFLIP)
{
if (referrer->floorheight > thing->z + thing->height
|| referrer->ceilingheight < (thing->z + (thing->height >> 1)))
if (bottom > thing->z + thing->height
|| top < (thing->z + (thing->height >> 1)))
continue;
if (thing->z < referrer->floorheight)
if (thing->z < bottom)
touching = true;
if (thing->z + (thing->height >> 1) > referrer->floorheight)
if (thing->z + (thing->height >> 1) > bottom)
inFOF = true;
}
else
{
if (referrer->ceilingheight < thing->z || referrer->floorheight > (thing->z + (thing->height >> 1)))
if (top < thing->z || referrer->floorheight > (thing->z + (thing->height >> 1)))
continue;
if (thing->z + thing->height > referrer->ceilingheight)
if (thing->z + thing->height > top)
touching = true;
if (thing->z + (thing->height >> 1) < referrer->ceilingheight)
if (thing->z + (thing->height >> 1) < top)
inFOF = true;
}
}
else // Treat the entire sector as one big FOF
{
if (thing->z == thing->subsector->sector->floorheight)
if (thing->z == P_GetSpecialBottomZ(thing, sec, sec))
touching = true;
else if (p->type != p_current)
inFOF = true;

View File

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

View File

@ -29,6 +29,7 @@
#include "m_random.h"
#include "m_misc.h"
#include "i_video.h"
#include "p_slopes.h"
#include "p_spec.h"
#include "r_splats.h"
#include "z_zone.h"
@ -51,9 +52,6 @@
#include "hardware/hw_main.h"
#endif
// Index of the special effects (INVUL inverse) map.
#define INVERSECOLORMAP 32
#if 0
static void P_NukeAllPlayers(player_t *player);
#endif
@ -957,7 +955,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC) && P_IsLocalPlayer(player))
{
S_StopMusic();
S_ChangeMusic(mus_supers, true);
S_ChangeMusicInternal("supers", true);
}
S_StartSound(NULL, sfx_supert); //let all players hear it -mattw_cfi
@ -1127,7 +1125,7 @@ void P_PlayLivesJingle(player_t *player)
if (player)
player->powers[pw_extralife] = extralifetics + 1;
S_StopMusic(); // otherwise it won't restart if this is done twice in a row
S_ChangeMusic(mus_xtlife, false);
S_ChangeMusicInternal("xtlife", false);
}
}
@ -1145,21 +1143,21 @@ void P_RestoreMusic(player_t *player)
return;
S_SpeedMusic(1.0f);
if (player->powers[pw_super] && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC))
S_ChangeMusic(mus_supers, true);
S_ChangeMusicInternal("supers", true);
else if (player->powers[pw_invulnerability] > 1)
S_ChangeMusic((mariomode) ? mus_minvnc : mus_invinc, false);
S_ChangeMusicInternal((mariomode) ? "minvnc" : "invinc", false);
else if (player->powers[pw_sneakers] > 1 && !player->powers[pw_super])
{
if (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC)
{
S_SpeedMusic(1.4f);
S_ChangeMusic(mapmusic, true);
S_ChangeMusic(mapmusname, mapmusflags, true);
}
else
S_ChangeMusic(mus_shoes, true);
S_ChangeMusicInternal("shoes", true);
}
else
S_ChangeMusic(mapmusic, true);
S_ChangeMusic(mapmusname, mapmusflags, true);
}
//
@ -1239,7 +1237,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec)
if (mo->eflags & MFE_VERTICALFLIP)
{
// Detect if the player is on the ceiling.
if (mo->z+mo->height >= sec->ceilingheight)
if (mo->z+mo->height >= P_GetSpecialTopZ(mo, sec, sec))
return true;
// Otherwise, detect if the player is on the bottom of a FOF.
else
@ -1263,7 +1261,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec)
continue;
// Actually check if the player is on the suitable FOF.
if (mo->z+mo->height == *rover->bottomheight)
if (mo->z+mo->height == P_GetSpecialBottomZ(mo, sectors + rover->secnum, sec))
return true;
}
}
@ -1272,7 +1270,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec)
else
{
// Detect if the player is on the floor.
if (mo->z <= sec->floorheight)
if (mo->z <= P_GetSpecialBottomZ(mo, sec, sec))
return true;
// Otherwise, detect if the player is on the top of a FOF.
else
@ -1296,7 +1294,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec)
continue;
// Actually check if the player is on the suitable FOF.
if (mo->z == *rover->topheight)
if (mo->z == P_GetSpecialTopZ(mo, sectors + rover->secnum, sec))
return true;
}
}
@ -1624,7 +1622,7 @@ void P_DoPlayerExit(player_t *player)
{
player->climbing = 0;
player->pflags |= PF_JUMPED;
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
}
player->powers[pw_underwater] = 0;
player->powers[pw_spacetime] = 0;
@ -1817,6 +1815,9 @@ static void P_CheckBouncySectors(player_t *player)
fixed_t oldx;
fixed_t oldy;
fixed_t oldz;
#ifdef ESLOPE
vector3_t momentum;
#endif
oldx = player->mo->x;
oldy = player->mo->y;
@ -1837,16 +1838,21 @@ static void P_CheckBouncySectors(player_t *player)
{
ffloor_t *rover;
boolean top = true;
fixed_t topheight, bottomheight;
for (rover = node->m_sector->ffloors; rover; rover = rover->next)
{
if (player->mo->z > *rover->topheight)
topheight = P_GetFOFTopZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
bottomheight = P_GetFOFBottomZ(player->mo, node->m_sector, rover, player->mo->x, player->mo->y, NULL);
if (player->mo->z > topheight)
continue;
if (player->mo->z + player->mo->height < *rover->bottomheight)
if (player->mo->z + player->mo->height < bottomheight)
continue;
if (oldz < *rover->topheight && oldz > *rover->bottomheight)
if (oldz < P_GetFOFTopZ(player->mo, node->m_sector, rover, oldx, oldy, NULL)
&& oldz + player->mo->height > P_GetFOFBottomZ(player->mo, node->m_sector, rover, oldx, oldy, NULL))
top = false;
if (GETSECSPECIAL(rover->master->frontsector->special, 1) == 15)
@ -1861,7 +1867,29 @@ static void P_CheckBouncySectors(player_t *player)
{
fixed_t newmom;
#ifdef ESLOPE
pslope_t *slope;
if (abs(oldz - topheight) < abs(oldz + player->mo->height - bottomheight)) { // Hit top
slope = *rover->t_slope;
} else { // Hit bottom
slope = *rover->b_slope;
}
momentum.x = player->mo->momx;
momentum.y = player->mo->momy;
momentum.z = player->mo->momz*2;
if (slope) {
// Reverse quantizing might could use its own function later
slope->zangle = ANGLE_MAX-slope->zangle;
P_QuantizeMomentumToSlope(&momentum, slope);
slope->zangle = ANGLE_MAX-slope->zangle;
}
newmom = momentum.z = -FixedMul(momentum.z,linedist)/2;
#else
newmom = -FixedMul(player->mo->momz,linedist);
#endif
if (abs(newmom) < (linedist*2))
{
@ -1884,7 +1912,18 @@ static void P_CheckBouncySectors(player_t *player)
else if (newmom < -P_GetPlayerHeight(player)/2)
newmom = -P_GetPlayerHeight(player)/2;
#ifdef ESLOPE
momentum.z = newmom*2;
if (slope)
P_QuantizeMomentumToSlope(&momentum, slope);
player->mo->momx = momentum.x;
player->mo->momy = momentum.y;
player->mo->momz = momentum.z/2;
#else
player->mo->momz = newmom;
#endif
if (player->pflags & PF_SPINNING)
{
@ -2026,13 +2065,13 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player)
else if (player->powers[pw_underwater] == 1)
{
if ((netgame || multiplayer) && P_IsLocalPlayer(player))
S_ChangeMusic(mapmusic, true);
S_ChangeMusic(mapmusname, mapmusflags, true);
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_DROWNED);
}
else if (player->powers[pw_spacetime] == 1)
{
if ((netgame || multiplayer) && P_IsLocalPlayer(player))
S_ChangeMusic(mapmusic, true);
S_ChangeMusic(mapmusname, mapmusflags, true);
P_DamageMobj(player->mo, NULL, NULL, 1, DMG_SPACEDROWN);
}
@ -2066,7 +2105,7 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player)
&& player == &players[consoleplayer])
{
S_StopMusic();
S_ChangeMusic(mus_drown, false);
S_ChangeMusicInternal("drown", false);
}
if (player->powers[pw_underwater] == 25*TICRATE + 1)
@ -2100,30 +2139,7 @@ static void P_CheckInvincibilityTimer(player_t *player)
player->mo->color = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1)));
else if (leveltime % (TICRATE/7) == 0)
{
fixed_t destx, desty;
mobj_t *sparkle;
if (!splitscreen && rendermode != render_soft)
{
angle_t viewingangle;
if (players[displayplayer].awayviewtics)
viewingangle = R_PointToAngle2(player->mo->x, player->mo->y, players[displayplayer].awayviewmobj->x, players[displayplayer].awayviewmobj->y);
else if (!camera.chase && players[displayplayer].mo)
viewingangle = R_PointToAngle2(player->mo->x, player->mo->y, players[displayplayer].mo->x, players[displayplayer].mo->y);
else
viewingangle = R_PointToAngle2(player->mo->x, player->mo->y, camera.x, camera.y);
destx = player->mo->x + P_ReturnThrustX(player->mo, viewingangle, FixedMul(FRACUNIT, player->mo->scale));
desty = player->mo->y + P_ReturnThrustY(player->mo, viewingangle, FixedMul(FRACUNIT, player->mo->scale));
}
else
{
destx = player->mo->x;
desty = player->mo->y;
}
sparkle = P_SpawnMobj(destx, desty, player->mo->z, MT_IVSP);
mobj_t *sparkle = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_IVSP);
sparkle->destscale = player->mo->scale;
P_SetScale(sparkle, player->mo->scale);
}
@ -2298,14 +2314,27 @@ static void P_DoClimbing(player_t *player)
boolean thrust;
boolean boostup;
boolean skyclimber;
fixed_t floorheight, ceilingheight; // ESLOPE
thrust = false;
floorclimb = false;
boostup = false;
skyclimber = false;
#ifdef ESLOPE
floorheight = glidesector->sector->f_slope ? P_GetZAt(glidesector->sector->f_slope, player->mo->x, player->mo->y)
: glidesector->sector->floorheight;
ceilingheight = glidesector->sector->c_slope ? P_GetZAt(glidesector->sector->c_slope, player->mo->x, player->mo->y)
: glidesector->sector->ceilingheight;
#else
floorheight = glidesector->sector->floorheight;
ceilingheight = glidesector->sector->ceilingheight;
#endif
if (glidesector->sector->ffloors)
{
ffloor_t *rover;
fixed_t topheight, bottomheight; // ESLOPE
for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
@ -2313,13 +2342,21 @@ static void P_DoClimbing(player_t *player)
floorclimb = true;
#ifdef ESLOPE
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
#else
bottomheight = *rover->bottomheight;
topheight = *rover->topheight;
#endif
// Only supports rovers that are moving like an 'elevator', not just the top or bottom.
if (rover->master->frontsector->floorspeed && rover->master->frontsector->ceilspeed == 42)
{
if ((!(player->mo->eflags & MFE_VERTICALFLIP) && (*rover->bottomheight < player->mo->z+player->mo->height)
&& (*rover->topheight >= player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)))
|| ((player->mo->eflags & MFE_VERTICALFLIP) && (*rover->topheight > player->mo->z)
&& (*rover->bottomheight <= player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale))))
if ((!(player->mo->eflags & MFE_VERTICALFLIP) && (bottomheight < player->mo->z+player->mo->height)
&& (topheight >= player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)))
|| ((player->mo->eflags & MFE_VERTICALFLIP) && (topheight > player->mo->z)
&& (bottomheight <= player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale))))
{
if (cmd->forwardmove != 0)
player->mo->momz += rover->master->frontsector->floorspeed;
@ -2335,8 +2372,9 @@ static void P_DoClimbing(player_t *player)
if (player->mo->eflags & MFE_VERTICALFLIP)
{
// Trying to climb down past the bottom of the FOF
if ((*rover->topheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= *rover->topheight))
if ((topheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= topheight))
{
fixed_t bottomheight2;
ffloor_t *roverbelow;
boolean foundfof = false;
floorclimb = true;
@ -2351,7 +2389,13 @@ static void P_DoClimbing(player_t *player)
if (roverbelow == rover)
continue;
if (*roverbelow->bottomheight < *rover->topheight + FixedMul(16*FRACUNIT, player->mo->scale))
#ifdef ESLOPE
bottomheight2 = *roverbelow->b_slope ? P_GetZAt(*roverbelow->b_slope, player->mo->x, player->mo->y) : *roverbelow->bottomheight;
#else
bottomheight2 = *roverbelow->bottomheight;
#endif
if (bottomheight2 < topheight + FixedMul(16*FRACUNIT, player->mo->scale))
foundfof = true;
}
@ -2360,7 +2404,7 @@ static void P_DoClimbing(player_t *player)
}
// Below the FOF
if (*rover->topheight <= player->mo->z)
if (topheight <= player->mo->z)
{
floorclimb = false;
boostup = false;
@ -2368,7 +2412,7 @@ static void P_DoClimbing(player_t *player)
}
// Above the FOF
if (*rover->bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale))
if (bottomheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale))
{
floorclimb = false;
thrust = true;
@ -2378,8 +2422,9 @@ static void P_DoClimbing(player_t *player)
else
{
// Trying to climb down past the bottom of a FOF
if ((*rover->bottomheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= *rover->bottomheight))
if ((bottomheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= bottomheight))
{
fixed_t topheight2;
ffloor_t *roverbelow;
boolean foundfof = false;
floorclimb = true;
@ -2394,7 +2439,13 @@ static void P_DoClimbing(player_t *player)
if (roverbelow == rover)
continue;
if (*roverbelow->topheight > *rover->bottomheight - FixedMul(16*FRACUNIT, player->mo->scale))
#ifdef ESLOPE
topheight2 = *roverbelow->t_slope ? P_GetZAt(*roverbelow->t_slope, player->mo->x, player->mo->y) : *roverbelow->topheight;
#else
topheight2 = *roverbelow->topheight;
#endif
if (topheight2 > bottomheight - FixedMul(16*FRACUNIT, player->mo->scale))
foundfof = true;
}
@ -2403,7 +2454,7 @@ static void P_DoClimbing(player_t *player)
}
// Below the FOF
if (*rover->bottomheight >= player->mo->z + player->mo->height)
if (bottomheight >= player->mo->z + player->mo->height)
{
floorclimb = false;
boostup = false;
@ -2411,7 +2462,7 @@ static void P_DoClimbing(player_t *player)
}
// Above the FOF
if (*rover->topheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale))
if (topheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale))
{
floorclimb = false;
thrust = true;
@ -2432,7 +2483,7 @@ static void P_DoClimbing(player_t *player)
if (player->mo->eflags & MFE_VERTICALFLIP)
{
// Trying to climb down past the upper texture area
if ((glidesector->sector->floorheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= glidesector->sector->floorheight))
if ((floorheight >= player->mo->z + player->mo->height) && ((player->mo->z + player->mo->height + player->mo->momz) >= floorheight))
{
boolean foundfof = false;
floorclimb = true;
@ -2440,13 +2491,20 @@ static void P_DoClimbing(player_t *player)
// Is there a FOF directly below that we can move onto?
if (glidesector->sector->ffloors)
{
fixed_t bottomheight;
ffloor_t *rover;
for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
continue;
if (*rover->bottomheight < glidesector->sector->floorheight + FixedMul(16*FRACUNIT, player->mo->scale))
#ifdef ESLOPE
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
#else
bottomheight = *rover->bottomheight;
#endif
if (bottomheight < floorheight + FixedMul(16*FRACUNIT, player->mo->scale))
{
foundfof = true;
break;
@ -2459,8 +2517,8 @@ static void P_DoClimbing(player_t *player)
}
// Reached the top of the lower texture area
if (!floorclimb && glidesector->sector->ceilingheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)
&& (glidesector->sector->ceilingpic == skyflatnum || glidesector->sector->floorheight < (player->mo->z - FixedMul(8*FRACUNIT, player->mo->scale))))
if (!floorclimb && ceilingheight > player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale)
&& (glidesector->sector->ceilingpic == skyflatnum || floorheight < (player->mo->z - FixedMul(8*FRACUNIT, player->mo->scale))))
{
thrust = true;
boostup = true;
@ -2470,7 +2528,7 @@ static void P_DoClimbing(player_t *player)
else
{
// Trying to climb down past the upper texture area
if ((glidesector->sector->ceilingheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= glidesector->sector->ceilingheight))
if ((ceilingheight <= player->mo->z) && ((player->mo->z + player->mo->momz) <= ceilingheight))
{
boolean foundfof = false;
floorclimb = true;
@ -2484,7 +2542,7 @@ static void P_DoClimbing(player_t *player)
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
continue;
if (*rover->topheight > glidesector->sector->ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
if (*rover->topheight > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
{
foundfof = true;
break;
@ -2497,7 +2555,7 @@ static void P_DoClimbing(player_t *player)
}
// Allow climbing from a FOF or lower texture onto the upper texture and vice versa.
if (player->mo->z > glidesector->sector->ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
if (player->mo->z > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
{
floorclimb = true;
thrust = false;
@ -2505,8 +2563,8 @@ static void P_DoClimbing(player_t *player)
}
// Reached the top of the lower texture area
if (!floorclimb && glidesector->sector->floorheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)
&& (glidesector->sector->ceilingpic == skyflatnum || glidesector->sector->ceilingheight > (player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, player->mo->scale))))
if (!floorclimb && floorheight < player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale)
&& (glidesector->sector->ceilingpic == skyflatnum || ceilingheight > (player->mo->z + player->mo->height + FixedMul(8*FRACUNIT, player->mo->scale))))
{
thrust = true;
boostup = true;
@ -2515,14 +2573,14 @@ static void P_DoClimbing(player_t *player)
}
// Trying to climb on the sky
if ((glidesector->sector->ceilingheight < player->mo->z) && glidesector->sector->ceilingpic == skyflatnum)
if ((ceilingheight < player->mo->z) && glidesector->sector->ceilingpic == skyflatnum)
{
skyclimber = true;
}
// Climbing on the lower texture area?
if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) < glidesector->sector->floorheight)
|| ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height <= glidesector->sector->floorheight))
if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + FixedMul(16*FRACUNIT, player->mo->scale) < floorheight)
|| ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height <= floorheight))
{
floorclimb = true;
@ -2538,8 +2596,8 @@ static void P_DoClimbing(player_t *player)
}
}
// Climbing on the upper texture area?
else if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z >= glidesector->sector->ceilingheight)
|| ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) > glidesector->sector->ceilingheight))
else if ((!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z >= ceilingheight)
|| ((player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z + player->mo->height - FixedMul(16*FRACUNIT, player->mo->scale) > ceilingheight))
{
floorclimb = true;
@ -2632,21 +2690,21 @@ static void P_DoClimbing(player_t *player)
player->climbing = 0;
player->pflags |= PF_JUMPED;
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
}
if (skyclimber)
{
player->climbing = 0;
player->pflags |= PF_JUMPED;
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
}
}
else
{
player->climbing = 0;
player->pflags |= PF_JUMPED;
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
}
if (cmd->sidemove != 0 || cmd->forwardmove != 0)
@ -2664,7 +2722,7 @@ static void P_DoClimbing(player_t *player)
{
player->climbing = 0;
player->pflags |= PF_JUMPED;
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
P_SetObjectMomZ(player->mo, 4*FRACUNIT, false);
P_InstaThrust(player->mo, player->mo->angle, FixedMul(-4*FRACUNIT, player->mo->scale));
}
@ -2675,7 +2733,7 @@ static void P_DoClimbing(player_t *player)
localangle2 = player->mo->angle;
if (player->climbing == 0)
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
if (player->climbing && P_IsObjectOnGround(player->mo))
{
@ -3384,27 +3442,14 @@ static void P_DoSuperStuff(player_t *player)
if ((leveltime % TICRATE == 0) && !(player->exiting))
player->rings--;
// future todo: a skin option for this, and possibly more colors
switch (player->skin)
{
case 1: // Golden orange supertails.
if (leveltime % 9 < 5)
player->mo->color = SKINCOLOR_TSUPER1 + leveltime % 9;
else
player->mo->color = SKINCOLOR_TSUPER1 + 9 - leveltime % 9;
break;
case 2: // Pink superknux.
if (leveltime % 9 < 5)
player->mo->color = SKINCOLOR_KSUPER1 + leveltime % 9;
else
player->mo->color = SKINCOLOR_KSUPER1 + 9 - leveltime % 9;
break;
default: // Yousa yellow now!
if (leveltime % 9 < 5)
player->mo->color = SKINCOLOR_SUPER1 + leveltime % 9;
else
player->mo->color = SKINCOLOR_SUPER1 + 9 - leveltime % 9;
break;
case 1: /* Tails */ player->mo->color = SKINCOLOR_TSUPER1; break;
case 2: /* Knux */ player->mo->color = SKINCOLOR_KSUPER1; break;
default: /* everyone */ player->mo->color = SKINCOLOR_SUPER1; break;
}
player->mo->color += abs( ( ( leveltime >> 1 ) % 9) - 4);
if ((cmd->forwardmove != 0 || cmd->sidemove != 0 || player->pflags & (PF_CARRIED|PF_ROPEHANG|PF_ITEMHANG|PF_MACESPIN))
&& !(leveltime % TICRATE) && (player->mo->momx || player->mo->momy))
@ -3441,8 +3486,9 @@ static void P_DoSuperStuff(player_t *player)
if (player->mo->health > 0)
{
if ((player->pflags & PF_JUMPED || player->pflags & PF_SPINNING)
&& player->mo->state-states != S_PLAY_DASH)
if (player->pflags & PF_JUMPED)
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
else if (player->pflags & PF_SPINNING && player->mo->state-states != S_PLAY_DASH)
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
else switch (player->mo->state-states)
{
@ -3460,8 +3506,8 @@ static void P_DoSuperStuff(player_t *player)
case S_PLAY_SUPER_PAIN:
P_SetPlayerMobjState(player->mo, S_PLAY_PAIN);
break;
case S_PLAY_SUPER_JUMP:
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
case S_PLAY_SUPER_SPRING:
P_SetPlayerMobjState(player->mo, S_PLAY_SPRING);
break;
case S_PLAY_SUPER_FALL:
P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
@ -3675,9 +3721,9 @@ void P_DoJump(player_t *player, boolean soundandstate)
S_StartSound(player->mo, sfx_jump); // Play jump sound!
if (!(player->charability2 == CA2_SPINDASH))
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
P_SetPlayerMobjState(player->mo, S_PLAY_SPRING);
else
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
}
}
@ -3703,7 +3749,11 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
if ((player->charability2 == CA2_SPINDASH) && !(player->pflags & PF_SLIDING) && !player->exiting
&& !P_PlayerInPain(player)) // subsequent revs
{
if ((cmd->buttons & BT_USE) && player->speed < FixedMul(5<<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->momy = player->cmomy;
@ -3735,7 +3785,11 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
// down the spin button and not spinning.
// AKA Just go into a spin on the ground, you idiot. ;)
else if ((cmd->buttons & BT_USE || ((twodlevel || (player->mo->flags2 & MF2_TWOD)) && cmd->forwardmove < -20))
&& !player->climbing && !player->mo->momz && onground && player->speed > FixedMul(5<<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;
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
@ -3747,7 +3801,11 @@ static void P_DoSpinDash(player_t *player, ticcmd_t *cmd)
// Rolling normally
if (onground && player->pflags & PF_SPINNING && !(player->pflags & PF_STARTDASH)
&& player->speed < FixedMul(5*FRACUNIT,player->mo->scale))
&& player->speed < FixedMul(5*FRACUNIT,player->mo->scale)
#ifdef ESLOPE
&& (!player->mo->standingslope || abs(player->mo->standingslope->zdelta) < FRACUNIT/2)
#endif
)
{
if (GETSECSPECIAL(player->mo->subsector->sector->special, 4) == 7 || (player->mo->ceilingz - player->mo->floorz < P_GetPlayerHeight(player)))
P_InstaThrust(player->mo, player->mo->angle, FixedMul(10*FRACUNIT, player->mo->scale));
@ -4443,12 +4501,16 @@ static void P_3dMovement(player_t *player)
angle_t dangle; // replaces old quadrants bits
fixed_t normalspd = FixedMul(player->normalspeed, player->mo->scale);
boolean analogmove = false;
#ifndef OLD_MOVEMENT_CODE
fixed_t oldMagnitude, newMagnitude;
#ifdef ESLOPE
vector3_t totalthrust;
totalthrust.x = totalthrust.y = 0; // I forget if this is needed
totalthrust.z = FRACUNIT*P_MobjFlip(player->mo)/3; // A bit of extra push-back on slopes
#endif // ESLOPE
// Get the old momentum; this will be needed at the end of the function! -SH
oldMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0);
#endif
analogmove = P_AnalogMove(player);
@ -4621,17 +4683,10 @@ static void P_3dMovement(player_t *player)
}
movepushforward = FixedMul(movepushforward, player->mo->scale);
#ifdef OLD_MOVEMENT_CODE
if (player->speed < topspeed && mforward && cmd->forwardmove > 0) // Sonic's Speed
P_Thrust(player->mo, movepushangle, movepushforward);
else if (mforward && cmd->forwardmove < 0)
P_Thrust(player->mo, movepushangle, movepushforward);
else if (player->speed < topspeed && mbackward && cmd->forwardmove < 0)
P_Thrust(player->mo, movepushangle, movepushforward);
else if (mbackward && cmd->forwardmove > 0)
P_Thrust(player->mo, movepushangle, movepushforward);
else if (!mforward && !mbackward)
P_Thrust(player->mo, movepushangle, movepushforward);
#ifdef ESLOPE
totalthrust.x += P_ReturnThrustX(player->mo, movepushangle, movepushforward);
totalthrust.y += P_ReturnThrustY(player->mo, movepushangle, movepushforward);
#else
P_Thrust(player->mo, movepushangle, movepushforward);
#endif
@ -4645,33 +4700,12 @@ static void P_3dMovement(player_t *player)
if (!(player->pflags & PF_GLIDING || player->exiting || P_PlayerInPain(player)))
{
angle_t controldirection;
#ifdef OLD_MOVEMENT_CODE
angle_t controlplayerdirection;
boolean cforward; // controls pointing forward from the player
boolean cbackward; // controls pointing backward from the player
angle_t dangle;
cforward = cbackward = false;
#endif
// Calculate the angle at which the controls are pointing
// to figure out the proper mforward and mbackward.
// (Why was it so complicated before? ~Red)
controldirection = R_PointToAngle2(0, 0, cmd->forwardmove*FRACUNIT, -cmd->sidemove*FRACUNIT)+movepushangle;
#ifdef OLD_MOVEMENT_CODE
controlplayerdirection = player->mo->angle;
dangle = controldirection - controlplayerdirection;
if (dangle > ANGLE_180) //flip to keep to one side
dangle = InvAngle(dangle);
if (dangle > ANGLE_90)
cbackward = true; // Controls pointing backwards from player
else
cforward = true; // Controls pointing in player's general direction
#endif
movepushforward = max(abs(cmd->sidemove), abs(cmd->forwardmove)) * (thrustfactor * acceleration);
// allow very small movement while in air for gameplay
@ -4694,13 +4728,10 @@ static void P_3dMovement(player_t *player)
movepushsideangle = controldirection;
movepushforward = FixedMul(movepushforward, player->mo->scale);
#ifdef OLD_MOVEMENT_CODE
if (player->speed < topspeed)
P_Thrust(player->mo, controldirection, movepushforward);
else if ((mforward) && (cbackward))
P_Thrust(player->mo, controldirection, movepushforward);
else if ((mbackward) && (cforward))
P_Thrust(player->mo, controldirection, movepushforward);
#ifdef ESLOPE
totalthrust.x += P_ReturnThrustX(player->mo, controldirection, movepushforward);
totalthrust.y += P_ReturnThrustY(player->mo, controldirection, movepushforward);
#else
P_Thrust(player->mo, controldirection, movepushforward);
#endif
@ -4708,29 +4739,6 @@ static void P_3dMovement(player_t *player)
}
else if (cmd->sidemove && !(player->pflags & PF_GLIDING) && !player->exiting && !P_PlayerInPain(player))
{
#ifdef OLD_MOVEMENT_CODE
boolean mright = 0;
boolean mleft = 0;
angle_t sideangle;
sideangle = player->mo->angle - ANGLE_90;
// Monster Iestyn - 04-11-13
// Quadrants are stupid, excessive and broken, let's do this a much simpler way!
// Get delta angle from rmom angle and player angle first
dangle = R_PointToAngle2(0,0, player->rmomx, player->rmomy) - sideangle;
if (dangle > ANGLE_180)
dangle = InvAngle(dangle);
// now use it to determine direction!
if (dangle <= ANGLE_45) // angles 0-45 or 315-360
mright = 1; // going right
else if (dangle >= ANGLE_135) // angles 135-225
mleft = 1; // going left
// anything else will leave both at 0, so no need to do anything else
#endif
movepushside = cmd->sidemove * (thrustfactor * acceleration);
if (!onground)
@ -4753,19 +4761,37 @@ static void P_3dMovement(player_t *player)
// Finally move the player now that his speed/direction has been decided.
movepushside = FixedMul(movepushside, player->mo->scale);
#ifdef OLD_MOVEMENT_CODE
if (player->speed < topspeed)
P_Thrust(player->mo, movepushsideangle, movepushside);
else if (mright && cmd->sidemove < 0)
P_Thrust(player->mo, movepushsideangle, movepushside);
else if (mleft && cmd->sidemove > 0)
P_Thrust(player->mo, movepushsideangle, movepushside);
#ifdef ESLOPE
totalthrust.x += P_ReturnThrustX(player->mo, movepushsideangle, movepushside);
totalthrust.y += P_ReturnThrustY(player->mo, movepushsideangle, movepushside);
#else
P_Thrust(player->mo, movepushsideangle, movepushside);
#endif
}
#ifndef OLD_MOVEMENT_CODE
#ifdef ESLOPE
if ((totalthrust.x || totalthrust.y)
&& player->mo->standingslope && abs(player->mo->standingslope->zdelta) > FRACUNIT/2) {
// Factor thrust to slope, but only for the part pushing up it!
// The rest is unaffected.
angle_t thrustangle = R_PointToAngle2(0, 0, totalthrust.x, totalthrust.y)-player->mo->standingslope->xydirection;
if (player->mo->standingslope->zdelta < 0) { // Direction goes down, so thrustangle needs to face toward
if (thrustangle < ANGLE_90 || thrustangle > ANGLE_270) {
P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope);
}
} else { // Direction goes up, so thrustangle needs to face away
if (thrustangle > ANGLE_90 && thrustangle < ANGLE_270) {
P_QuantizeMomentumToSlope(&totalthrust, player->mo->standingslope);
}
}
}
player->mo->momx += totalthrust.x;
player->mo->momy += totalthrust.y;
#endif
// Time to ask three questions:
// 1) Are we over topspeed?
// 2) If "yes" to 1, were we moving over topspeed to begin with?
@ -4799,7 +4825,6 @@ static void P_3dMovement(player_t *player)
player->mo->momy = tempmomy + player->cmomy;
}
}
#endif
}
//
@ -5553,7 +5578,7 @@ static void P_NiGHTSMovement(player_t *player)
}
else if (P_IsLocalPlayer(player) && player->nightstime == 10*TICRATE)
// S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH
S_ChangeMusic(mus_drown,false);
S_ChangeMusicInternal("drown",false);
if (player->mo->z < player->mo->floorz)
@ -6301,8 +6326,7 @@ static void P_MovePlayer(player_t *player)
if (!(player->powers[pw_nocontrol] & (1<<15)))
player->pflags |= PF_JUMPSTASIS;
}
else
player->pflags &= ~PF_FULLSTASIS;
// note: don't unset stasis here
if (!player->spectator && G_TagGametype())
{
@ -6452,10 +6476,10 @@ static void P_MovePlayer(player_t *player)
}
// If Springing, but travelling DOWNWARD, change back!
if (player->panim == PA_JUMP && P_MobjFlip(player->mo)*player->mo->momz < 0)
if (player->panim == PA_SPRING && P_MobjFlip(player->mo)*player->mo->momz < 0)
P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
// If Springing but on the ground, change back!
else if (onground && (player->panim == PA_JUMP || player->panim == PA_FALL || player->panim == PA_RIDE) && !player->mo->momz)
else if (onground && (player->panim == PA_SPRING || player->panim == PA_FALL || player->panim == PA_RIDE) && !player->mo->momz)
P_SetPlayerMobjState(player->mo, S_PLAY_STND);
// If you are stopped and are still walking, stand still!
@ -6494,7 +6518,7 @@ static void P_MovePlayer(player_t *player)
else
{
player->pflags |= PF_JUMPED;
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
}
}
player->pflags &= ~PF_GLIDING;
@ -6552,7 +6576,7 @@ static void P_MovePlayer(player_t *player)
&& player->charability == CA_GLIDEANDCLIMB)
{
player->pflags |= PF_JUMPED;
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
}
else
{
@ -6622,7 +6646,7 @@ static void P_MovePlayer(player_t *player)
else
{
player->pflags |= PF_JUMPED;
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
}
}
player->powers[pw_tailsfly] = 0;
@ -7197,7 +7221,7 @@ static void P_DoRopeHang(player_t *player)
if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED)
&& !(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH)
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
return;
}
@ -7314,7 +7338,7 @@ static void P_DoRopeHang(player_t *player)
if (!(player->pflags & PF_SLIDING) && (player->pflags & PF_JUMPED)
&& !(player->panim == PA_ROLL) && player->charability2 == CA2_SPINDASH)
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
}
P_SetTarget(&player->mo->tracer, NULL);
@ -7691,7 +7715,7 @@ static void P_DeathThink(player_t *player)
// Return to level music
if (netgame && player->deadtimer == gameovertics && P_IsLocalPlayer(player))
S_ChangeMusic(mapmusic, true);
S_ChangeMusic(mapmusname, mapmusflags, true);
}
if (!player->mo)
@ -7926,9 +7950,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
if (player == &players[consoleplayer])
{
if (focusangle >= localangle)
localangle += abs(focusangle - localangle)>>5;
localangle += abs((focusangle - localangle))>>5;
else
localangle -= abs(focusangle - localangle)>>5;
localangle -= abs((focusangle - localangle))>>5;
}
}
else if (P_AnalogMove(player)) // Analog
@ -8630,7 +8654,7 @@ void P_PlayerThink(player_t *player)
P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE);
}
else if ((player->pflags & PF_JUMPED) && !player->powers[pw_super] && player->panim != PA_ROLL && player->charability2 == CA2_SPINDASH)
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
if (player->flashcount)
player->flashcount--;
@ -8677,7 +8701,7 @@ void P_PlayerThink(player_t *player)
if (countdown == 11*TICRATE - 1)
{
if (P_IsLocalPlayer(player))
S_ChangeMusic(mus_drown, false);
S_ChangeMusicInternal("drown", false);
}
// If you've hit the countdown and you haven't made
@ -8831,10 +8855,7 @@ void P_PlayerThink(player_t *player)
mo2 = (mobj_t *)th;
if (!(mo2->type == MT_NIGHTSWING || mo2->type == MT_RING || mo2->type == MT_COIN
#ifdef BLUE_SPHERES
|| mo2->type == MT_BLUEBALL
#endif
))
|| mo2->type == MT_BLUEBALL))
continue;
if (P_AproxDistance(P_AproxDistance(mo2->x - x, mo2->y - y), mo2->z - z) > FixedMul(128*FRACUNIT, player->mo->scale))
@ -8888,6 +8909,11 @@ void P_PlayerThink(player_t *player)
if (!player->mo)
return; // P_MovePlayer removed player->mo.
// Unset statis flags after moving.
// In other words, if you manually set stasis via code,
// it lasts for one tic.
player->pflags &= ~PF_FULLSTASIS;
#ifdef POLYOBJECTS
if (player->onconveyor == 1)
player->cmomy = player->cmomx = 0;
@ -9254,7 +9280,7 @@ void P_PlayerAfterThink(player_t *player)
&& ((!player->powers[pw_super] && player->panim != PA_ROLL)
|| player->mo->state == &states[player->mo->info->painstate])
&& player->charability2 == CA2_SPINDASH)
P_SetPlayerMobjState(player->mo, S_PLAY_SPIN);
P_SetPlayerMobjState(player->mo, S_PLAY_JUMP);
if (player->pflags & PF_CARRIED && player->mo->tracer)
{

View File

@ -18,6 +18,7 @@
#include "r_splats.h"
#include "p_local.h" // camera
#include "p_slopes.h"
#include "z_zone.h" // Check R_Prep3DFloors
seg_t *curline;
@ -31,7 +32,6 @@ sector_t *backsector;
// 896 drawsegs! So too bad here's a limit removal a-la-Boom
drawseg_t *drawsegs = NULL;
drawseg_t *ds_p = NULL;
drawseg_t *firstnewseg = NULL;
// indicates doors closed wrt automap bugfix:
INT32 doorclosed;
@ -459,6 +459,11 @@ static void R_AddLine(seg_t *line)
doorclosed = 0;
// Closed door.
#ifdef ESLOPE
// Just don't bother checking this if one side is sloped. This is probably inefficient, but it's better than
// random renderer stopping around slopes...
if (!(frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope))
#endif
if (backsector->ceilingheight <= frontsector->floorheight
|| backsector->floorheight >= frontsector->ceilingheight)
{
@ -487,6 +492,10 @@ static void R_AddLine(seg_t *line)
#endif
backsector->ceilingpic == frontsector->ceilingpic
&& backsector->floorpic == frontsector->floorpic
#ifdef ESLOPE
&& backsector->f_slope == frontsector->f_slope
&& backsector->c_slope == frontsector->c_slope
#endif
&& backsector->lightlevel == frontsector->lightlevel
&& !curline->sidedef->midtexture
// Check offsets too!
@ -842,11 +851,19 @@ static void R_Subsector(size_t num)
sub->sector->moved = frontsector->moved = false;
}
light = R_GetPlaneLight(frontsector, frontsector->floorheight, false);
light = R_GetPlaneLight(frontsector,
#ifdef ESLOPE
frontsector->f_slope ? P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
#endif
frontsector->floorheight, false);
if (frontsector->floorlightsec == -1)
floorlightlevel = *frontsector->lightlist[light].lightlevel;
floorcolormap = frontsector->lightlist[light].extra_colormap;
light = R_GetPlaneLight(frontsector, frontsector->ceilingheight, false);
light = R_GetPlaneLight(frontsector,
#ifdef ESLOPE
frontsector->c_slope ? P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
#endif
frontsector->ceilingheight, false);
if (frontsector->ceilinglightsec == -1)
ceilinglightlevel = *frontsector->lightlist[light].lightlevel;
ceilingcolormap = frontsector->lightlist[light].extra_colormap;
@ -854,32 +871,52 @@ static void R_Subsector(size_t num)
sub->sector->extra_colormap = frontsector->extra_colormap;
if ((frontsector->floorheight < viewz || (frontsector->heightsec != -1
if (((
#ifdef ESLOPE
frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) :
#endif
frontsector->floorheight) < viewz || (frontsector->heightsec != -1
&& sectors[frontsector->heightsec].ceilingpic == skyflatnum)))
{
floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel,
frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL);
frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL
#ifdef ESLOPE
, frontsector->f_slope
#endif
);
}
else
floorplane = NULL;
if ((frontsector->ceilingheight > viewz || frontsector->ceilingpic == skyflatnum
if (((
#ifdef ESLOPE
frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) :
#endif
frontsector->ceilingheight) > viewz || frontsector->ceilingpic == skyflatnum
|| (frontsector->heightsec != -1
&& sectors[frontsector->heightsec].floorpic == skyflatnum)))
{
ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic,
ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle,
ceilingcolormap, NULL);
ceilingcolormap, NULL
#ifdef ESLOPE
, frontsector->c_slope
#endif
);
}
else
ceilingplane = NULL;
numffloors = 0;
#ifdef ESLOPE
ffloor[numffloors].slope = NULL;
#endif
ffloor[numffloors].plane = NULL;
ffloor[numffloors].polyobj = NULL;
if (frontsector->ffloors)
{
ffloor_t *rover;
fixed_t heightcheck, planecenterz, floorcenterz, ceilingcenterz;
for (rover = frontsector->ffloors; rover && numffloors < MAXFFLOORS; rover = rover->next)
{
@ -897,18 +934,60 @@ static void R_Subsector(size_t num)
ffloor[numffloors].plane = NULL;
ffloor[numffloors].polyobj = NULL;
if (*rover->bottomheight <= frontsector->ceilingheight
&& *rover->bottomheight >= frontsector->floorheight
&& ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES))
|| (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES))))
floorcenterz =
#ifdef ESLOPE
frontsector->f_slope ? P_GetZAt(frontsector->f_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
#endif
frontsector->floorheight;
ceilingcenterz =
#ifdef ESLOPE
frontsector->c_slope ? P_GetZAt(frontsector->c_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
#endif
frontsector->ceilingheight;
heightcheck =
#ifdef ESLOPE
*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) :
#endif
*rover->bottomheight;
planecenterz =
#ifdef ESLOPE
*rover->b_slope ? P_GetZAt(*rover->b_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
#endif
*rover->bottomheight;
if (planecenterz <= ceilingcenterz
&& planecenterz >= floorcenterz
&& ((viewz < heightcheck && !(rover->flags & FF_INVERTPLANES))
|| (viewz > heightcheck && (rover->flags & FF_BOTHPLANES))))
{
light = R_GetPlaneLight(frontsector, *rover->bottomheight,
light = R_GetPlaneLight(frontsector, planecenterz,
viewz < *rover->bottomheight);
ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic,
*frontsector->lightlist[light].lightlevel, *rover->bottomxoffs,
*rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover);
*rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover
#ifdef ESLOPE
, *rover->b_slope
#endif
);
#ifdef ESLOPE
ffloor[numffloors].slope = *rover->b_slope;
// Tell the renderer this sector has slopes in it.
if (ffloor[numffloors].slope)
frontsector->hasslope = true;
#endif
ffloor[numffloors].height =
#ifdef ESLOPE
*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) :
#endif
*rover->bottomheight;
ffloor[numffloors].height = *rover->bottomheight;
ffloor[numffloors].ffloor = rover;
numffloors++;
}
@ -916,16 +995,47 @@ static void R_Subsector(size_t num)
break;
ffloor[numffloors].plane = NULL;
ffloor[numffloors].polyobj = NULL;
if (*rover->topheight >= frontsector->floorheight
&& *rover->topheight <= frontsector->ceilingheight
&& ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES))
|| (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES))))
heightcheck =
#ifdef ESLOPE
*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) :
#endif
*rover->topheight;
planecenterz =
#ifdef ESLOPE
*rover->t_slope ? P_GetZAt(*rover->t_slope, frontsector->soundorg.x, frontsector->soundorg.y) :
#endif
*rover->topheight;
if (planecenterz >= floorcenterz
&& planecenterz <= ceilingcenterz
&& ((viewz > heightcheck && !(rover->flags & FF_INVERTPLANES))
|| (viewz < heightcheck && (rover->flags & FF_BOTHPLANES))))
{
light = R_GetPlaneLight(frontsector, *rover->topheight, viewz < *rover->topheight);
light = R_GetPlaneLight(frontsector, planecenterz, viewz < *rover->topheight);
ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic,
*frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle,
frontsector->lightlist[light].extra_colormap, rover);
ffloor[numffloors].height = *rover->topheight;
frontsector->lightlist[light].extra_colormap, rover
#ifdef ESLOPE
, *rover->t_slope
#endif
);
#ifdef ESLOPE
ffloor[numffloors].slope = *rover->t_slope;
// Tell the renderer this sector has slopes in it.
if (ffloor[numffloors].slope)
frontsector->hasslope = true;
#endif
ffloor[numffloors].height =
#ifdef ESLOPE
*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) :
#endif
*rover->topheight;
ffloor[numffloors].ffloor = rover;
numffloors++;
}
@ -977,11 +1087,18 @@ static void R_Subsector(size_t num)
polysec->lightlevel, xoff, yoff,
polysec->floorpic_angle-po->angle,
NULL,
NULL);
NULL
#ifdef ESLOPE
, NULL // will ffloors be slopable eventually?
#endif
);
//ffloor[numffloors].plane->polyobj = po;
ffloor[numffloors].height = polysec->floorheight;
ffloor[numffloors].polyobj = po;
#ifdef ESLOPE
ffloor[numffloors].slope = NULL;
#endif
// ffloor[numffloors].ffloor = rover;
po->visplane = ffloor[numffloors].plane;
numffloors++;
@ -1014,11 +1131,18 @@ static void R_Subsector(size_t num)
light = 0;
ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic,
polysec->lightlevel, xoff, yoff, polysec->ceilingpic_angle-po->angle,
NULL, NULL);
NULL, NULL
#ifdef ESLOPE
, NULL // will ffloors be slopable eventually?
#endif
);
//ffloor[numffloors].plane->polyobj = po;
ffloor[numffloors].polyobj = po;
ffloor[numffloors].height = polysec->ceilingheight;
#ifdef ESLOPE
ffloor[numffloors].slope = NULL;
#endif
// ffloor[numffloors].ffloor = rover;
po->visplane = ffloor[numffloors].plane;
numffloors++;
@ -1077,6 +1201,11 @@ void R_Prep3DFloors(sector_t *sector)
fixed_t bestheight, maxheight;
INT32 count, i, mapnum;
sector_t *sec;
#ifdef ESLOPE
pslope_t *bestslope;
fixed_t heighttest; // I think it's better to check the Z height at the sector's center
// than assume unsloped heights are accurate indicators of order in sloped sectors. -Red
#endif
count = 1;
for (rover = sector->ffloors; rover; rover = rover->next)
@ -1099,7 +1228,14 @@ void R_Prep3DFloors(sector_t *sector)
else
memset(sector->lightlist, 0, sizeof (lightlist_t) * count);
#ifdef ESLOPE
heighttest = sector->c_slope ? P_GetZAt(sector->c_slope, sector->soundorg.x, sector->soundorg.y) : sector->ceilingheight;
sector->lightlist[0].height = heighttest + 1;
sector->lightlist[0].slope = sector->c_slope;
#else
sector->lightlist[0].height = sector->ceilingheight + 1;
#endif
sector->lightlist[0].lightlevel = &sector->lightlevel;
sector->lightlist[0].caster = NULL;
sector->lightlist[0].extra_colormap = sector->extra_colormap;
@ -1117,6 +1253,29 @@ void R_Prep3DFloors(sector_t *sector)
&& !(rover->flags & FF_CUTLEVEL) && !(rover->flags & FF_CUTSPRITES)))
continue;
#ifdef ESLOPE
heighttest = *rover->t_slope ? P_GetZAt(*rover->t_slope, sector->soundorg.x, sector->soundorg.y) : *rover->topheight;
if (heighttest > bestheight && heighttest < maxheight)
{
best = rover;
bestheight = heighttest;
bestslope = *rover->t_slope;
continue;
}
if (rover->flags & FF_DOUBLESHADOW) {
heighttest = *rover->b_slope ? P_GetZAt(*rover->b_slope, sector->soundorg.x, sector->soundorg.y) : *rover->bottomheight;
if (heighttest > bestheight
&& heighttest < maxheight)
{
best = rover;
bestheight = heighttest;
bestslope = *rover->b_slope;
continue;
}
}
#else
if (*rover->topheight > bestheight && *rover->topheight < maxheight)
{
best = rover;
@ -1130,6 +1289,7 @@ void R_Prep3DFloors(sector_t *sector)
bestheight = *rover->bottomheight;
continue;
}
#endif
}
if (!best)
{
@ -1140,6 +1300,9 @@ void R_Prep3DFloors(sector_t *sector)
sector->lightlist[i].height = maxheight = bestheight;
sector->lightlist[i].caster = best;
sector->lightlist[i].flags = best->flags;
#ifdef ESLOPE
sector->lightlist[i].slope = bestslope;
#endif
sec = &sectors[best->secnum];
mapnum = sec->midmap;
if (mapnum >= 0 && (size_t)mapnum < num_extra_colormaps)
@ -1165,7 +1328,12 @@ void R_Prep3DFloors(sector_t *sector)
if (best->flags & FF_DOUBLESHADOW)
{
#ifdef ESLOPE
heighttest = *best->b_slope ? P_GetZAt(*best->b_slope, sector->soundorg.x, sector->soundorg.y) : *best->bottomheight;
if (bestheight == heighttest) ///TODO: do this in a more efficient way -Red
#else
if (bestheight == *best->bottomheight)
#endif
{
sector->lightlist[i].lightlevel = sector->lightlist[best->lastlight].lightlevel;
sector->lightlist[i].extra_colormap =

View File

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

View File

@ -155,6 +155,12 @@ typedef struct ffloor_s
fixed_t *bottomyoffs;
angle_t *bottomangle;
#ifdef ESLOPE
// Pointers to pointers. Yup.
struct pslope_s **t_slope;
struct pslope_s **b_slope;
#endif
size_t secnum;
ffloortype_e flags;
struct line_s *master;
@ -184,6 +190,9 @@ typedef struct lightlist_s
extracolormap_t *extra_colormap;
INT32 flags;
ffloor_t *caster;
#ifdef ESLOPE
struct pslope_s *slope; // FF_DOUBLESHADOW makes me have to store this pointer here. Bluh bluh.
#endif
} lightlist_t;
@ -224,6 +233,52 @@ typedef struct secplane_t
fixed_t a, b, c, d, ic;
} secplane_t;
// Slopes
#ifdef ESLOPE
typedef enum {
SL_NOPHYSICS = 1, // Don't do momentum adjustment with this slope
SL_NODYNAMIC = 1<<1, // Slope will never need to move during the level, so don't fuss with recalculating it
SL_ANCHORVERTEX = 1<<2, // Slope is using a Slope Vertex Thing to anchor its position
SL_VERTEXSLOPE = 1<<3, // Slope is built from three Slope Vertex Things
} slopeflags_t;
typedef struct pslope_s
{
UINT16 id; // The number of the slope, mostly used for netgame syncing purposes
// --- Information used in clipping/projection ---
// Origin vector for the plane
vector3_t o;
// 2-Dimentional vector (x, y) normalized. Used to determine distance from
// the origin in 2d mapspace. (Basically a thrust of FRACUNIT in xydirection angle)
vector2_t d;
// The rate at which z changes based on distance from the origin plane.
fixed_t zdelta;
// The normal of the slope; will always point upward, and thus be inverted on ceilings. I think it's only needed for physics? -Red
vector3_t normal;
// For comparing when a slope should be rendered
fixed_t lowz;
fixed_t highz;
// This values only check and must be updated if the slope itself is modified
angle_t zangle; // Angle of the plane going up from the ground (not mesured in degrees)
angle_t xydirection; // The direction the slope is facing (north, west, south, etc.)
struct line_s *sourceline; // The line that generated the slope
fixed_t extent; // Distance value used for recalculating zdelta
UINT8 refpos; // 1=front floor 2=front ceiling 3=back floor 4=back ceiling (used for dynamic sloping)
UINT8 flags; // Slope options
mapthing_t **vertices; // List should be three long for slopes made by vertex things, or one long for slopes using one vertex thing to anchor
struct pslope_s *next; // Make a linked list of dynamic slopes, for easy reference later
} pslope_t;
#endif
typedef enum
{
SF_FLIPSPECIAL_FLOOR = 1,
@ -314,14 +369,6 @@ typedef struct sector_s
double lineoutLength;
#endif // ----- end special tricks -----
// ZDoom C++ to Legacy C conversion (for slopes)
// store floor and ceiling planes instead of heights
//secplane_t floorplane, ceilingplane;
#ifdef SLOPENESS
//fixed_t floortexz, ceilingtexz; // [RH] used for wall texture mapping
angle_t floorangle;
#endif
// This points to the master's floorheight, so it can be changed in realtime!
fixed_t *gravity; // per-sector gravity
boolean verticalflip; // If gravity < 0, then allow flipped physics
@ -337,6 +384,13 @@ typedef struct sector_s
precipmobj_t *preciplist;
struct mprecipsecnode_s *touching_preciplist;
#ifdef ESLOPE
// Eternity engine slope
pslope_t *f_slope; // floor slope
pslope_t *c_slope; // ceiling slope
boolean hasslope; // The sector, or one of its visible FOFs, contains a slope
#endif
// these are saved for netgames, so do not let Lua touch these!
// offsets sector spawned with (via linedef type 7)
@ -612,6 +666,12 @@ typedef struct drawseg_s
INT16 *thicksidecol;
INT32 numthicksides;
fixed_t frontscale[MAXVIDWIDTH];
#ifdef ESLOPE
fixed_t maskedtextureheight[MAXVIDWIDTH]; // For handling sloped midtextures
vertex_t leftpos, rightpos; // Used for rendering FOF walls with slopes
#endif
} drawseg_t;
typedef enum

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_transmap; // one of the translucency tables
#ifdef ESLOPE
pslope_t *ds_slope; // Current slope being used
floatv3_t ds_su, ds_sv, ds_sz; // Vectors for... stuff?
float focallengthf, zeroheight;
#endif
/** \brief Variable flat sizes
*/
@ -121,7 +127,7 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask;
#define METALSONIC_TT_CACHE_INDEX (MAXSKINS + 2)
#define ALLWHITE_TT_CACHE_INDEX (MAXSKINS + 3)
#define SKIN_RAMP_LENGTH 16
#define DEFAULT_STARTTRANSCOLOR 160
#define DEFAULT_STARTTRANSCOLOR 96
#define NUM_PALETTE_ENTRIES 256
static UINT8** translationtablecache[MAXSKINS + 4] = {NULL};
@ -131,62 +137,70 @@ static UINT8** translationtablecache[MAXSKINS + 4] = {NULL};
// TODO Callum: Can this be translated?
const char *Color_Names[MAXSKINCOLORS] =
{
"None", // SKINCOLOR_NONE
"White", // SKINCOLOR_WHITE
"Silver", // SKINCOLOR_SILVER
"Grey", // SKINCOLOR_GREY
"Black", // SKINCOLOR_BLACK
"Cyan", // SKINCOLOR_CYAN
"Teal", // SKINCOLOR_TEAL
"Steel_Blue",// SKINCOLOR_STEELBLUE
"Blue", // SKINCOLOR_BLUE
"Peach", // SKINCOLOR_PEACH
"Tan", // SKINCOLOR_TAN
"Pink", // SKINCOLOR_PINK
"Lavender", // SKINCOLOR_LAVENDER
"Purple", // SKINCOLOR_PURPLE
"Orange", // SKINCOLOR_ORANGE
"Rosewood", // SKINCOLOR_ROSEWOOD
"Beige", // SKINCOLOR_BEIGE
"Brown", // SKINCOLOR_BROWN
"Red", // SKINCOLOR_RED
"Dark_Red", // SKINCOLOR_DARKRED
"Neon_Green",// SKINCOLOR_NEONGREEN
"Green", // SKINCOLOR_GREEN
"Zim", // SKINCOLOR_ZIM
"Olive", // SKINCOLOR_OLIVE
"Yellow", // SKINCOLOR_YELLOW
"Gold" // SKINCOLOR_GOLD
"None", // SKINCOLOR_NONE
"White", // SKINCOLOR_WHITE
"Silver", // SKINCOLOR_SILVER
"Grey", // SKINCOLOR_GREY
"Black", // SKINCOLOR_BLACK
"Beige", // SKINCOLOR_BEIGE
"Peach", // SKINCOLOR_PEACH
"Brown", // SKINCOLOR_BROWN
"Red", // SKINCOLOR_RED
"Crimson", // SKINCOLOR_CRIMSON
"Orange", // SKINCOLOR_ORANGE
"Rust", // SKINCOLOR_RUST
"Gold", // SKINCOLOR_GOLD
"Yellow", // SKINCOLOR_YELLOW
"Tan", // SKINCOLOR_TAN
"Moss", // SKINCOLOR_MOSS
"Peridot", // SKINCOLOR_PERIDOT
"Green", // SKINCOLOR_GREEN
"Emerald", // SKINCOLOR_EMERALD
"Aqua", // SKINCOLOR_AQUA
"Teal", // SKINCOLOR_TEAL
"Cyan", // SKINCOLOR_CYAN
"Blue", // SKINCOLOR_BLUE
"Azure", // SKINCOLOR_AZURE
"Pastel", // SKINCOLOR_PASTEL
"Purple", // SKINCOLOR_PURPLE
"Lavender", // SKINCOLOR_LAVENDER
"Magenta", // SKINCOLOR_MAGENTA
"Pink", // SKINCOLOR_PINK
"Rosy" // SKINCOLOR_ROSY
};
const UINT8 Color_Opposite[MAXSKINCOLORS*2] =
{
SKINCOLOR_NONE,8, // SKINCOLOR_NONE
SKINCOLOR_BLACK,10, // SKINCOLOR_WHITE
SKINCOLOR_GREY,4, // SKINCOLOR_SILVER
SKINCOLOR_SILVER,12,// SKINCOLOR_GREY
SKINCOLOR_WHITE,8, // SKINCOLOR_BLACK
SKINCOLOR_NONE,8, // SKINCOLOR_CYAN
SKINCOLOR_NONE,8, // SKINCOLOR_TEAL
SKINCOLOR_NONE,8, // SKINCOLOR_STEELBLUE
SKINCOLOR_ORANGE,9, // SKINCOLOR_BLUE
SKINCOLOR_NONE,8, // SKINCOLOR_PEACH
SKINCOLOR_NONE,8, // SKINCOLOR_TAN
SKINCOLOR_NONE,8, // SKINCOLOR_PINK
SKINCOLOR_NONE,8, // SKINCOLOR_LAVENDER
SKINCOLOR_NONE,8, // SKINCOLOR_PURPLE
SKINCOLOR_BLUE,12, // SKINCOLOR_ORANGE
SKINCOLOR_NONE,8, // SKINCOLOR_ROSEWOOD
SKINCOLOR_NONE,8, // SKINCOLOR_BEIGE
SKINCOLOR_NONE,8, // SKINCOLOR_BROWN
SKINCOLOR_GREEN,5, // SKINCOLOR_RED
SKINCOLOR_NONE,8, // SKINCOLOR_DARKRED
SKINCOLOR_NONE,8, // SKINCOLOR_NEONGREEN
SKINCOLOR_RED,11, // SKINCOLOR_GREEN
SKINCOLOR_PURPLE,3, // SKINCOLOR_ZIM
SKINCOLOR_NONE,8, // SKINCOLOR_OLIVE
SKINCOLOR_NONE,8, // SKINCOLOR_YELLOW
SKINCOLOR_NONE,8 // SKINCOLOR_GOLD
SKINCOLOR_NONE,8, // SKINCOLOR_NONE
SKINCOLOR_BLACK,10, // SKINCOLOR_WHITE
SKINCOLOR_GREY,4, // SKINCOLOR_SILVER
SKINCOLOR_SILVER,12, // SKINCOLOR_GREY
SKINCOLOR_WHITE,8, // SKINCOLOR_BLACK
SKINCOLOR_BEIGE,8, // SKINCOLOR_BEIGE - needs new offset
SKINCOLOR_BROWN,8, // SKINCOLOR_PEACH - ditto
SKINCOLOR_PEACH,8, // SKINCOLOR_BROWN - ditto
SKINCOLOR_GREEN,5, // SKINCOLOR_RED
SKINCOLOR_CYAN,8, // SKINCOLOR_CRIMSON - ditto
SKINCOLOR_BLUE,12, // SKINCOLOR_ORANGE
SKINCOLOR_TAN,8, // SKINCOLOR_RUST - ditto
SKINCOLOR_LAVENDER,8, // SKINCOLOR_GOLD - ditto
SKINCOLOR_TEAL,8, // SKINCOLOR_YELLOW - ditto
SKINCOLOR_RUST,8, // SKINCOLOR_TAN - ditto
SKINCOLOR_MAGENTA,3, // SKINCOLOR_MOSS
SKINCOLOR_PURPLE,8, // SKINCOLOR_PERIDOT - ditto
SKINCOLOR_RED,11, // SKINCOLOR_GREEN
SKINCOLOR_PASTEL,8, // SKINCOLOR_EMERALD - ditto
SKINCOLOR_ROSY,8, // SKINCOLOR_AQUA - ditto
SKINCOLOR_YELLOW,8, // SKINCOLOR_TEAL - ditto
SKINCOLOR_CRIMSON,8, // SKINCOLOR_CYAN - ditto
SKINCOLOR_ORANGE,9, // SKINCOLOR_BLUE
SKINCOLOR_PINK,8, // SKINCOLOR_AZURE - ditto
SKINCOLOR_EMERALD,8, // SKINCOLOR_PASTEL - ditto
SKINCOLOR_PERIDOT,8, // SKINCOLOR_PURPLE - ditto
SKINCOLOR_GOLD,8, // SKINCOLOR_LAVENDER - ditto
SKINCOLOR_MOSS,8, // SKINCOLOR_MAGENTA - ditto
SKINCOLOR_AZURE,8, // SKINCOLOR_PINK - ditto
SKINCOLOR_AQUA,8 // SKINCOLOR_ROSY - ditto
};
CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1];
@ -236,27 +250,31 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
0x03, // SKINCOLOR_SILVER
0x08, // SKINCOLOR_GREY
0x18, // SKINCOLOR_BLACK
0xd0, // SKINCOLOR_CYAN
0xdc, // SKINCOLOR_TEAL
0xc8, // SKINCOLOR_STEELBLUE
0xe2, // SKINCOLOR_BLUE
0x40, // SKINCOLOR_PEACH
0x48, // SKINCOLOR_TAN
0x90, // SKINCOLOR_PINK
0xf8, // SKINCOLOR_LAVENDER
0xc0, // SKINCOLOR_PURPLE
0x52, // SKINCOLOR_ORANGE
0x5c, // SKINCOLOR_ROSEWOOD
0x20, // SKINCOLOR_BEIGE
0x30, // SKINCOLOR_BROWN
0x7d, // SKINCOLOR_RED
0x85, // SKINCOLOR_DARKRED
0xb8, // SKINCOLOR_NEONGREEN
0xa0, // SKINCOLOR_GREEN
0xb0, // SKINCOLOR_ZIM
0x69, // SKINCOLOR_OLIVE
0x67, // SKINCOLOR_YELLOW
0x70, // SKINCOLOR_GOLD
0xf0, // SKINCOLOR_BEIGE
0xd8, // SKINCOLOR_PEACH
0xe0, // SKINCOLOR_BROWN
0x21, // SKINCOLOR_RED
0x28, // SKINCOLOR_CRIMSON
0x31, // SKINCOLOR_ORANGE
0x3a, // SKINCOLOR_RUST
0x40, // SKINCOLOR_GOLD
0x48, // SKINCOLOR_YELLOW
0x54, // SKINCOLOR_TAN
0x58, // SKINCOLOR_MOSS
0xbc, // SKINCOLOR_PERIDOT
0x60, // SKINCOLOR_GREEN
0x70, // SKINCOLOR_EMERALD
0x78, // SKINCOLOR_AQUA
0x8c, // SKINCOLOR_TEAL
0x80, // SKINCOLOR_CYAN
0x92, // SKINCOLOR_BLUE
0xaa, // SKINCOLOR_AZURE
0xa0, // SKINCOLOR_PASTEL
0xa0, // SKINCOLOR_PURPLE
0xc0, // SKINCOLOR_LAVENDER
0xb3, // SKINCOLOR_MAGENTA
0xd0, // SKINCOLOR_PINK
0xc8, // SKINCOLOR_ROSY
};
INT32 i;
INT32 starttranscolor;
@ -274,7 +292,7 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
if (skinnum == TC_BOSS)
dest_colormap[31] = 0;
else if (skinnum == TC_METALSONIC)
dest_colormap[239] = 0;
dest_colormap[159] = 0;
return;
}
@ -293,196 +311,339 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
{
case SKINCOLOR_SILVER:
case SKINCOLOR_GREY:
case SKINCOLOR_PEACH:
case SKINCOLOR_BEIGE:
case SKINCOLOR_BROWN:
case SKINCOLOR_RED:
case SKINCOLOR_GREEN:
case SKINCOLOR_BLUE:
// 16 color ramp
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i);
break;
case SKINCOLOR_ORANGE:
// 14 colors of orange + brown
for (i = 0; i < SKIN_RAMP_LENGTH-2; i++)
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i);
for (i = 0; i < 2; i++)
dest_colormap[starttranscolor + (i+SKIN_RAMP_LENGTH-2)] = (UINT8)(152 + i);
break;
case SKINCOLOR_WHITE:
case SKINCOLOR_CYAN:
// 12 color ramp
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (12*i/SKIN_RAMP_LENGTH));
break;
case SKINCOLOR_WHITE:
case SKINCOLOR_BLACK:
case SKINCOLOR_STEELBLUE:
case SKINCOLOR_PINK:
case SKINCOLOR_MOSS:
case SKINCOLOR_EMERALD:
case SKINCOLOR_LAVENDER:
case SKINCOLOR_PURPLE:
case SKINCOLOR_DARKRED:
case SKINCOLOR_ZIM:
case SKINCOLOR_YELLOW:
case SKINCOLOR_GOLD:
case SKINCOLOR_PINK:
// 8 color ramp
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1));
break;
case SKINCOLOR_TEAL:
// 5 color ramp
case SKINCOLOR_BEIGE:
// 13 colors
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
{
if (5*i/16 == 0)
dest_colormap[starttranscolor + i] = 0xf7;
if (i == 15)
dest_colormap[starttranscolor + i] = 0xed; // Darkest
else if (i <= 6)
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + ((i + 1) >> 1)); // Brightest
else
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (5*i/SKIN_RAMP_LENGTH) - 1);
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i - 3);
}
break;
case SKINCOLOR_OLIVE:
// 7 color ramp
case SKINCOLOR_PEACH:
// 11 colors
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (7*i/SKIN_RAMP_LENGTH));
{
if (i == 0)
dest_colormap[starttranscolor + i] = 0xD0; // Lightest 1
else if (i == 1)
dest_colormap[starttranscolor + i] = 0x30; // Lightest 2
else if (i <= 11)
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) - 1);
else
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i - 7); // Darkest
}
break;
case SKINCOLOR_RED:
// 16 colors
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
{
if (i == 13)
dest_colormap[starttranscolor + i] = 0x47; // Semidark
else if (i > 13)
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i - 1); // Darkest
else
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i);
}
break;
case SKINCOLOR_CRIMSON:
// 9 colors
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
{
if (i/2 == 6)
dest_colormap[starttranscolor + i] = 0x47; // Semidark
else if (i/2 == 7)
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i - 8); // Darkest
else
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1));
}
break;
case SKINCOLOR_ORANGE:
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
{
if (i == 15)
dest_colormap[starttranscolor + i] = 0x2c; // Darkest
else
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i);
}
break;
case SKINCOLOR_RUST:
// 10 colors
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
{
if (i <= 11)
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1));
else if (i == 12)
dest_colormap[starttranscolor + i] = 0x2c; // Darkest 4
else if (i == 13)
dest_colormap[starttranscolor + i] = 0xfe; // Darkest 3
else
dest_colormap[starttranscolor + i] = 0x2d + i - 14; // Darkest 2 and 1
}
break;
case SKINCOLOR_GOLD:
// 10 colors
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
{
if (i == 0)
dest_colormap[starttranscolor + i] = 0x50; // Lightest 1
else if (i == 1)
dest_colormap[starttranscolor + i] = 0x53; // Lightest 2
else if (i/2 == 7)
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i - 8); //Darkest
else
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) - 1);
}
break;
case SKINCOLOR_YELLOW:
// 10 colors
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
{
if (i == 0)
dest_colormap[starttranscolor + i] = 0x53; // Lightest
else if (i == 15)
dest_colormap[starttranscolor + i] = 0xed; // Darkest
else
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1));
}
break;
case SKINCOLOR_TAN:
// 16 color ramp, from two color ranges
for (i = 0; i < SKIN_RAMP_LENGTH/2; i++) // Peach half
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i);
for (i = 0; i < SKIN_RAMP_LENGTH/2; i++) // Brown half
dest_colormap[starttranscolor + (i+8)] = (UINT8)(48 + i);
// 8 colors
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
{
if (i/2 == 0)
dest_colormap[starttranscolor + i] = 0x51; // Lightest
else if (i/2 == 5)
dest_colormap[starttranscolor + i] = 0xf5; // Darkest 1
else if (i/2 == 6)
dest_colormap[starttranscolor + i] = 0xf9; // Darkest 2
else if (i/2 == 7)
dest_colormap[starttranscolor + i] = 0xed; // Darkest 3
else
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) - 1);
}
break;
case SKINCOLOR_ROSEWOOD:
// 12 color ramp, from two color ranges!
for (i = 0; i < 6; i++) // Orange ...third?
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (12*i/SKIN_RAMP_LENGTH));
for (i = 0; i < 10; i++) // Rosewood two-thirds-ish
dest_colormap[starttranscolor + (i+6)] = (UINT8)(152 + (12*i/SKIN_RAMP_LENGTH));
case SKINCOLOR_PERIDOT:
// 8 colors
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
{
if (i/2 == 0)
dest_colormap[starttranscolor + i] = 0x58; // Lightest
else if (i/2 == 7)
dest_colormap[starttranscolor + i] = 0x77; // Darkest
else if (i/2 >= 5)
dest_colormap[starttranscolor + i] = (UINT8)(0x5e + (i >> 1) - 5); // Semidark
else
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) - 1);
}
break;
case SKINCOLOR_NEONGREEN:
// Multi-color ramp
dest_colormap[starttranscolor] = 0xA0; // Brighter green
for (i = 0; i < SKIN_RAMP_LENGTH-1; i++) // Neon Green
dest_colormap[starttranscolor + (i+1)] = (UINT8)(skinbasecolors[color - 1] + (6*i/(SKIN_RAMP_LENGTH-1)));
case SKINCOLOR_AQUA:
// 10 colors
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
{
if (i == 0)
dest_colormap[starttranscolor + i] = 0x78; // Lightest
else if (i >= 14)
dest_colormap[starttranscolor + i] = (UINT8)(0x76 + i - 14); // Darkest
else
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) + 1);
}
break;
case SKINCOLOR_TEAL:
// 6 colors
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
{
if (i <= 1)
dest_colormap[starttranscolor + i] = 0x78; // Lightest
else if (i >= 13)
dest_colormap[starttranscolor + i] = 0x8a; // Darkest
else
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + ((i - 1)/3));
}
break;
case SKINCOLOR_AZURE:
// 8 colors
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
{
if (i <= 3)
dest_colormap[starttranscolor + i] = (UINT8)(0x90 + i/2); // Lightest
else
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) - 2);
}
break;
case SKINCOLOR_BLUE:
// 16 colors
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
{
if (i == 15)
dest_colormap[starttranscolor + i] = 0x1F; //Darkest 1
else if (i == 14)
dest_colormap[starttranscolor + i] = 0xfd; //Darkest 2
else
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i);
}
break;
case SKINCOLOR_PASTEL:
// 10 colors
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
{
if (i >= 12)
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i - 7); // Darkest
else if (i <= 1)
dest_colormap[starttranscolor + i] = 0x90; // Lightest
else
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) - 1);
}
break;
case SKINCOLOR_PURPLE:
// 10 colors
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
{
if (i <= 3)
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + i); // Lightest
else
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) + 2);
}
break;
case SKINCOLOR_MAGENTA:
// 9 colors
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
if (i == 0)
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1]); // Lightest
else
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + (i >> 1) + 1);
break;
case SKINCOLOR_ROSY:
// 9 colors
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
{
if (i == 0)
dest_colormap[starttranscolor + i] = 0xfc; // Lightest
else
dest_colormap[starttranscolor + i] = (UINT8)(skinbasecolors[color - 1] + ((i - 1) >> 1));
}
break;
// Super colors, from lightest to darkest!
case SKINCOLOR_SUPER1:
// Super White
for (i = 0; i < 10; i++)
dest_colormap[starttranscolor + i] = 120; // True white
for (; i < SKIN_RAMP_LENGTH; i++) // White-yellow fade
dest_colormap[starttranscolor + i] = (UINT8)(96 + (i-10));
dest_colormap[starttranscolor + i] = (UINT8)0; // True white
for (; i < 12; i++) // White-yellow fade
dest_colormap[starttranscolor + i] = (UINT8)(80);
for (; i < 15; i++) // White-yellow fade
dest_colormap[starttranscolor + i] = (UINT8)(81 + (i-12));
dest_colormap[starttranscolor + 15] = (UINT8)(72);
break;
case SKINCOLOR_SUPER2:
// Super Bright
for (i = 0; i < 5; i++) // White-yellow fade
dest_colormap[starttranscolor + i] = (UINT8)(96 + i);
dest_colormap[starttranscolor + 5] = 112; // Golden shine
for (i = 0; i < 8; i++) // Yellow
dest_colormap[starttranscolor + (i+6)] = (UINT8)(101 + (i>>1));
for (i = 0; i < 2; i++) // With a fine golden finish! :3
dest_colormap[starttranscolor + (i+14)] = (UINT8)(113 + i);
dest_colormap[starttranscolor] = (UINT8)(0);
for (i = 1; i < 4; i++) // White-yellow fade
dest_colormap[starttranscolor + i] = (UINT8)(80 + (i-1));
for (; i < 6; i++) // Yellow
dest_colormap[starttranscolor + i] = (UINT8)(83);
for (; i < 8; i++) // Yellow
dest_colormap[starttranscolor + i] = (UINT8)(72);
for (; i < 14; i++) // Yellow
dest_colormap[starttranscolor + i] = (UINT8)(73);
for (; i < 16; i++) // With a fine golden finish! :3
dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-14));
break;
case SKINCOLOR_SUPER3:
// Super Yellow
for (i = 0; i < 3; i++) // White-yellow fade
dest_colormap[starttranscolor + i] = (UINT8)(98 + i);
dest_colormap[starttranscolor + 3] = 112; // Golden shine
for (i = 0; i < 8; i++) // Yellow
dest_colormap[starttranscolor + (i+4)] = (UINT8)(101 + (i>>1));
for (i = 0; i < 4; i++) // With a fine golden finish! :3
dest_colormap[starttranscolor + (i+12)] = (UINT8)(113 + i);
for (i = 0; i < 2; i++) // White-yellow fade
dest_colormap[starttranscolor + i] = (UINT8)(81 + i);
for (; i < 4; i++)
dest_colormap[starttranscolor + i] = (UINT8)(83);
for (; i < 6; i++) // Yellow
dest_colormap[starttranscolor + i] = (UINT8)(72);
for (; i < 12; i++) // Yellow
dest_colormap[starttranscolor + i] = (UINT8)(73);
for (; i < 16; i++) // With a fine golden finish! :3
dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-12));
break;
case SKINCOLOR_SUPER4:
// "The SSNTails"
dest_colormap[starttranscolor] = 112; // Golden shine
for (i = 0; i < 8; i++) // Yellow
dest_colormap[starttranscolor + (i+1)] = (UINT8)(101 + (i>>1));
for (i = 0; i < 7; i++) // With a fine golden finish! :3
dest_colormap[starttranscolor + (i+9)] = (UINT8)(113 + i);
dest_colormap[starttranscolor] = 83; // Golden shine
for (i = 1; i < 3; i++) // Yellow
dest_colormap[starttranscolor + i] = (UINT8)(72);
for (; i < 9; i++) // Yellow
dest_colormap[starttranscolor + i] = (UINT8)(73);
for (; i < 16; i++) // With a fine golden finish! :3
dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-9));
break;
case SKINCOLOR_SUPER5:
// Golden Delicious
for (i = 0; i < 8; i++) // Yellow
dest_colormap[starttranscolor + i] = (UINT8)(101 + (i>>1));
for (i = 0; i < 7; i++) // With a fine golden finish! :3
dest_colormap[starttranscolor + (i+8)] = (UINT8)(113 + i);
dest_colormap[starttranscolor + 15] = 155;
for (i = 0; i < 2; i++) // Yellow
dest_colormap[starttranscolor + i] = (UINT8)(72);
for (; i < 8; i++) // Yellow
dest_colormap[starttranscolor + i] = (UINT8)(73);
for (; i < 15; i++) // With a fine golden finish! :3
dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-8));
dest_colormap[starttranscolor + 15] = (UINT8)63;
break;
// Super Tails
// Super Tails and Knuckles, who really should be dummied out by now
case SKINCOLOR_TSUPER1:
for (i = 0; i < 10; i++) // white
dest_colormap[starttranscolor + i] = 120;
for (; i < SKIN_RAMP_LENGTH; i++) // orange
dest_colormap[starttranscolor + i] = (UINT8)(80 + (i-10));
break;
case SKINCOLOR_TSUPER2:
for (i = 0; i < 4; i++) // white
dest_colormap[starttranscolor + i] = 120;
for (; i < SKIN_RAMP_LENGTH; i++) // orange
dest_colormap[starttranscolor + i] = (UINT8)(80 + ((i-4)>>1));
break;
case SKINCOLOR_TSUPER3:
dest_colormap[starttranscolor] = 120; // pure white
dest_colormap[starttranscolor+1] = 120;
for (i = 2; i < SKIN_RAMP_LENGTH; i++) // orange
dest_colormap[starttranscolor + i] = (UINT8)(80 + ((i-2)>>1));
break;
case SKINCOLOR_TSUPER4:
dest_colormap[starttranscolor] = 120; // pure white
for (i = 1; i < 9; i++) // orange
dest_colormap[starttranscolor + i] = (UINT8)(80 + (i-1));
for (; i < SKIN_RAMP_LENGTH; i++) // gold
dest_colormap[starttranscolor + i] = (UINT8)(115 + (5*(i-9)/7));
break;
case SKINCOLOR_TSUPER5:
for (i = 0; i < 8; i++) // orange
dest_colormap[starttranscolor + i] = (UINT8)(80 + i);
for (; i < SKIN_RAMP_LENGTH; i++) // gold
dest_colormap[starttranscolor + i] = (UINT8)(115 + (5*(i-8)/8));
break;
// Super Knuckles
case SKINCOLOR_KSUPER1:
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
dest_colormap[starttranscolor + i] = (UINT8)(120 + (i >> 2));
break;
case SKINCOLOR_KSUPER2:
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
dest_colormap[starttranscolor + i] = (UINT8)(120 + (6*i/SKIN_RAMP_LENGTH));
break;
case SKINCOLOR_KSUPER3:
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
dest_colormap[starttranscolor + i] = (UINT8)(120 + (i >> 1));
break;
case SKINCOLOR_KSUPER4:
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
dest_colormap[starttranscolor + i] = (UINT8)(121 + (i >> 1));
break;
case SKINCOLOR_KSUPER5:
for (i = 0; i < SKIN_RAMP_LENGTH; i++)
dest_colormap[starttranscolor + i] = (UINT8)(122 + (i >> 1));
dest_colormap[starttranscolor + i] = 0xFF;
break;
default:

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_transmap;
#ifdef ESLOPE
typedef struct {
float x, y, z;
} floatv3_t;
extern pslope_t *ds_slope; // Current slope being used
extern floatv3_t ds_su, ds_sv, ds_sz; // Vectors for... stuff?
extern float focallengthf, zeroheight;
#endif
// Variable flat sizes
extern UINT32 nflatxshift;
extern UINT32 nflatyshift;
@ -141,6 +151,12 @@ void ASMCALL R_DrawSpan_8_MMX(void);
void R_DrawTranslatedColumn_8(void);
void R_DrawTranslatedTranslucentColumn_8(void);
void R_DrawSpan_8(void);
#ifdef ESLOPE
void R_CalcTiltedLighting(fixed_t start, fixed_t end);
void R_DrawTiltedSpan_8(void);
void R_DrawTiltedTranslucentSpan_8(void);
void R_DrawTiltedSplat_8(void);
#endif
void R_DrawSplat_8(void);
void R_DrawTranslucentSplat_8(void);
void R_DrawTranslucentSpan_8(void);

View File

@ -105,7 +105,7 @@ void R_DrawColumn_8(void)
}
}
#define TRANSPARENTPIXEL 247
#define TRANSPARENTPIXEL 255
void R_Draw2sMultiPatchColumn_8(void)
{
@ -526,6 +526,447 @@ void R_DrawSpan_8 (void)
}
}
#ifdef ESLOPE
// R_CalcTiltedLighting
// Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly.
static INT32 tiltlighting[MAXVIDWIDTH];
void R_CalcTiltedLighting(fixed_t start, fixed_t end)
{
// ZDoom uses a different lighting setup to us, and I couldn't figure out how to adapt their version
// of this function. Here's my own.
INT32 left = ds_x1, right = ds_x2;
fixed_t step = (end-start)/(ds_x2-ds_x1+1);
INT32 i;
// I wanna do some optimizing by checking for out-of-range segments on either side to fill in all at once,
// but I'm too bad at coding to not crash the game trying to do that. I guess this is fast enough for now...
for (i = left; i <= right; i++) {
tiltlighting[i] = (start += step) >> FRACBITS;
if (tiltlighting[i] < 0)
tiltlighting[i] = 0;
else if (tiltlighting[i] >= MAXLIGHTSCALE)
tiltlighting[i] = MAXLIGHTSCALE-1;
}
}
/** \brief The R_DrawTiltedSpan_8 function
Draw slopes! Holy sheit!
*/
void R_DrawTiltedSpan_8(void)
{
// x1, x2 = ds_x1, ds_x2
int width = ds_x2 - ds_x1;
double iz, uz, vz;
UINT32 u, v;
int i;
UINT8 *source;
UINT8 *colormap;
UINT8 *dest;
double startz, startu, startv;
double izstep, uzstep, vzstep;
double endz, endu, endv;
UINT32 stepu, stepv;
iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
float lightstart, lightend;
lightend = (iz + ds_sz.x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1];
source = ds_source;
//colormap = ds_colormap;
#if 0 // The "perfect" reference version of this routine. Pretty slow.
// Use it only to see how things are supposed to look.
i = 0;
do
{
double z = 1.f/iz;
u = (INT64)(uz*z) + viewx;
v = (INT64)(vz*z) + viewy;
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
dest++;
iz += ds_sz.x;
uz += ds_su.x;
vz += ds_sv.x;
} while (--width >= 0);
#else
#define SPANSIZE 16
#define INVSPAN 0.0625f
startz = 1.f/iz;
startu = uz*startz;
startv = vz*startz;
izstep = ds_sz.x * SPANSIZE;
uzstep = ds_su.x * SPANSIZE;
vzstep = ds_sv.x * SPANSIZE;
//x1 = 0;
width++;
while (width >= SPANSIZE)
{
iz += izstep;
uz += uzstep;
vz += vzstep;
endz = 1.f/iz;
endu = uz*endz;
endv = vz*endz;
stepu = (INT64)((endu - startu) * INVSPAN);
stepv = (INT64)((endv - startv) * INVSPAN);
u = (INT64)(startu) + viewx;
v = (INT64)(startv) + viewy;
for (i = SPANSIZE-1; i >= 0; i--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
dest++;
u += stepu;
v += stepv;
}
startu = endu;
startv = endv;
width -= SPANSIZE;
}
if (width > 0)
{
if (width == 1)
{
u = (INT64)(startu);
v = (INT64)(startv);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
}
else
{
double left = width;
iz += ds_sz.x * left;
uz += ds_su.x * left;
vz += ds_sv.x * left;
endz = 1.f/iz;
endu = uz*endz;
endv = vz*endz;
left = 1.f/left;
stepu = (INT64)((endu - startu) * left);
stepv = (INT64)((endv - startv) * left);
u = (INT64)(startu) + viewx;
v = (INT64)(startv) + viewy;
for (; width != 0; width--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
dest++;
u += stepu;
v += stepv;
}
}
}
#endif
}
/** \brief The R_DrawTiltedTranslucentSpan_8 function
Like DrawTiltedSpan, but translucent
*/
void R_DrawTiltedTranslucentSpan_8(void)
{
// x1, x2 = ds_x1, ds_x2
int width = ds_x2 - ds_x1;
double iz, uz, vz;
UINT32 u, v;
int i;
UINT8 *source;
UINT8 *colormap;
UINT8 *dest;
double startz, startu, startv;
double izstep, uzstep, vzstep;
double endz, endu, endv;
UINT32 stepu, stepv;
iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
float lightstart, lightend;
lightend = (iz + ds_sz.x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1];
source = ds_source;
//colormap = ds_colormap;
#if 0 // The "perfect" reference version of this routine. Pretty slow.
// Use it only to see how things are supposed to look.
i = 0;
do
{
double z = 1.f/iz;
u = (INT64)(uz*z) + viewx;
v = (INT64)(vz*z) + viewy;
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])];
dest++;
iz += ds_sz.x;
uz += ds_su.x;
vz += ds_sv.x;
} while (--width >= 0);
#else
#define SPANSIZE 16
#define INVSPAN 0.0625f
startz = 1.f/iz;
startu = uz*startz;
startv = vz*startz;
izstep = ds_sz.x * SPANSIZE;
uzstep = ds_su.x * SPANSIZE;
vzstep = ds_sv.x * SPANSIZE;
//x1 = 0;
width++;
while (width >= SPANSIZE)
{
iz += izstep;
uz += uzstep;
vz += vzstep;
endz = 1.f/iz;
endu = uz*endz;
endv = vz*endz;
stepu = (INT64)((endu - startu) * INVSPAN);
stepv = (INT64)((endv - startv) * INVSPAN);
u = (INT64)(startu) + viewx;
v = (INT64)(startv) + viewy;
for (i = SPANSIZE-1; i >= 0; i--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])];
dest++;
u += stepu;
v += stepv;
}
startu = endu;
startv = endv;
width -= SPANSIZE;
}
if (width > 0)
{
if (width == 1)
{
u = (INT64)(startu);
v = (INT64)(startv);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])];
}
else
{
double left = width;
iz += ds_sz.x * left;
uz += ds_su.x * left;
vz += ds_sv.x * left;
endz = 1.f/iz;
endu = uz*endz;
endv = vz*endz;
left = 1.f/left;
stepu = (INT64)((endu - startu) * left);
stepv = (INT64)((endv - startv) * left);
u = (INT64)(startu) + viewx;
v = (INT64)(startv) + viewy;
for (; width != 0; width--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
*dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])];
dest++;
u += stepu;
v += stepv;
}
}
}
#endif
}
void R_DrawTiltedSplat_8(void)
{
// x1, x2 = ds_x1, ds_x2
int width = ds_x2 - ds_x1;
double iz, uz, vz;
UINT32 u, v;
int i;
UINT8 *source;
UINT8 *colormap;
UINT8 *dest;
UINT8 val;
double startz, startu, startv;
double izstep, uzstep, vzstep;
double endz, endu, endv;
UINT32 stepu, stepv;
iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx);
// Lighting is simple. It's just linear interpolation from start to end
{
float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f;
float lightstart, lightend;
lightend = (iz + ds_sz.x*width) * planelightfloat;
lightstart = iz * planelightfloat;
R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend));
//CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf);
}
uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx);
vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1];
source = ds_source;
//colormap = ds_colormap;
#if 0 // The "perfect" reference version of this routine. Pretty slow.
// Use it only to see how things are supposed to look.
i = 0;
do
{
double z = 1.f/iz;
u = (INT64)(uz*z) + viewx;
v = (INT64)(vz*z) + viewy;
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
if (val != TRANSPARENTPIXEL)
*dest = val;
dest++;
iz += ds_sz.x;
uz += ds_su.x;
vz += ds_sv.x;
} while (--width >= 0);
#else
#define SPANSIZE 16
#define INVSPAN 0.0625f
startz = 1.f/iz;
startu = uz*startz;
startv = vz*startz;
izstep = ds_sz.x * SPANSIZE;
uzstep = ds_su.x * SPANSIZE;
vzstep = ds_sv.x * SPANSIZE;
//x1 = 0;
width++;
while (width >= SPANSIZE)
{
iz += izstep;
uz += uzstep;
vz += vzstep;
endz = 1.f/iz;
endu = uz*endz;
endv = vz*endz;
stepu = (INT64)((endu - startu) * INVSPAN);
stepv = (INT64)((endv - startv) * INVSPAN);
u = (INT64)(startu) + viewx;
v = (INT64)(startv) + viewy;
for (i = SPANSIZE-1; i >= 0; i--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
if (val != TRANSPARENTPIXEL)
*dest = val;
dest++;
u += stepu;
v += stepv;
}
startu = endu;
startv = endv;
width -= SPANSIZE;
}
if (width > 0)
{
if (width == 1)
{
u = (INT64)(startu);
v = (INT64)(startv);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
if (val != TRANSPARENTPIXEL)
*dest = val;
}
else
{
double left = width;
iz += ds_sz.x * left;
uz += ds_su.x * left;
vz += ds_sv.x * left;
endz = 1.f/iz;
endu = uz*endz;
endv = vz*endz;
left = 1.f/left;
stepu = (INT64)((endu - startu) * left);
stepv = (INT64)((endv - startv) * left);
u = (INT64)(startu) + viewx;
v = (INT64)(startv) + viewy;
for (; width != 0; width--)
{
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]];
if (val != TRANSPARENTPIXEL)
*dest = val;
dest++;
u += stepu;
v += stepv;
}
}
}
#endif
}
#endif // ESLOPE
/** \brief The R_DrawSplat_8 function
Just like R_DrawSpan_8, but skips transparent pixels.
*/

View File

@ -114,15 +114,6 @@ INT32 viewangletox[FINEANGLES/2];
// from clipangle to -clipangle.
angle_t xtoviewangle[MAXVIDWIDTH+1];
// UNUSED.
// The finetangentgent[angle+FINEANGLES/4] table
// holds the fixed_t tangent values for view angles,
// ranging from INT32_MIN to 0 to INT32_MAX.
#if !(defined _NDS) || !(defined NONET)
fixed_t *finecosine = &finesine[FINEANGLES/4];
#endif
lighttable_t *scalelight[LIGHTLEVELS][MAXLIGHTSCALE];
lighttable_t *scalelightfixed[MAXLIGHTSCALE];
lighttable_t *zlight[LIGHTLEVELS][MAXLIGHTZ];
@ -316,13 +307,13 @@ angle_t R_PointToAngle(fixed_t x, fixed_t y)
x >= 0 ?
y >= 0 ?
(x > y) ? tantoangle[SlopeDiv(y,x)] : // octant 0
ANGLE_90-1-tantoangle[SlopeDiv(x,y)] : // octant 1
ANGLE_90-tantoangle[SlopeDiv(x,y)] : // octant 1
x > (y = -y) ? 0-tantoangle[SlopeDiv(y,x)] : // octant 8
ANGLE_270+tantoangle[SlopeDiv(x,y)] : // octant 7
y >= 0 ? (x = -x) > y ? ANGLE_180-1-tantoangle[SlopeDiv(y,x)] :// octant 3
y >= 0 ? (x = -x) > y ? ANGLE_180-tantoangle[SlopeDiv(y,x)] : // octant 3
ANGLE_90 + tantoangle[SlopeDiv(x,y)] : // octant 2
(x = -x) > (y = -y) ? ANGLE_180+tantoangle[ SlopeDiv(y,x)] : // octant 4
ANGLE_270-1-tantoangle[SlopeDiv(x,y)] : // octant 5
(x = -x) > (y = -y) ? ANGLE_180+tantoangle[SlopeDiv(y,x)] : // octant 4
ANGLE_270-tantoangle[SlopeDiv(x,y)] : // octant 5
0;
}
@ -332,13 +323,13 @@ angle_t R_PointToAngle2(fixed_t pviewx, fixed_t pviewy, fixed_t x, fixed_t y)
x >= 0 ?
y >= 0 ?
(x > y) ? tantoangle[SlopeDiv(y,x)] : // octant 0
ANGLE_90-1-tantoangle[SlopeDiv(x,y)] : // octant 1
ANGLE_90-tantoangle[SlopeDiv(x,y)] : // octant 1
x > (y = -y) ? 0-tantoangle[SlopeDiv(y,x)] : // octant 8
ANGLE_270+tantoangle[SlopeDiv(x,y)] : // octant 7
y >= 0 ? (x = -x) > y ? ANGLE_180-1-tantoangle[SlopeDiv(y,x)] :// octant 3
y >= 0 ? (x = -x) > y ? ANGLE_180-tantoangle[SlopeDiv(y,x)] : // octant 3
ANGLE_90 + tantoangle[SlopeDiv(x,y)] : // octant 2
(x = -x) > (y = -y) ? ANGLE_180+tantoangle[ SlopeDiv(y,x)] : // octant 4
ANGLE_270-1-tantoangle[SlopeDiv(x,y)] : // octant 5
(x = -x) > (y = -y) ? ANGLE_180+tantoangle[SlopeDiv(y,x)] : // octant 4
ANGLE_270-tantoangle[SlopeDiv(x,y)] : // octant 5
0;
}
@ -527,6 +518,8 @@ static void R_InitTextureMapping(void)
focallength = FixedDiv(centerxfrac,
FINETANGENT(FINEANGLES/4+/*cv_fov.value*/ FIELDOFVIEW/2));
focallengthf = FIXED_TO_FLOAT(focallength);
for (i = 0; i < FINEANGLES/2; i++)
{
if (FINETANGENT(i) > FRACUNIT*2)
@ -1276,7 +1269,7 @@ void R_RenderPlayerView(player_t *player)
if (cv_homremoval.value == 1)
V_DrawFill(0, 0, vid.width, vid.height, 31); // No HOM effect!
else //'development' HOM removal -- makes it blindingly obvious if HOM is spotted.
V_DrawFill(0, 0, vid.width, vid.height, 128+(timeinmap&15));
V_DrawFill(0, 0, vid.width, vid.height, 32+(timeinmap&15));
}
portalrender = 0;

View File

@ -28,6 +28,8 @@
#include "p_setup.h" // levelflats
#include "p_slopes.h"
//
// opening
//
@ -74,7 +76,7 @@ static INT32 spanstart[MAXVIDHEIGHT];
//
// texture mapping
//
static lighttable_t **planezlight;
lighttable_t **planezlight;
static fixed_t planeheight;
//added : 10-02-98: yslopetab is what yslope used to be,
@ -327,6 +329,11 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2)
if (pindex >= MAXLIGHTZ)
pindex = MAXLIGHTZ - 1;
#ifdef ESLOPE
if (currentplane->slope)
ds_colormap = colormaps;
else
#endif
ds_colormap = planezlight[pindex];
if (currentplane->extra_colormap)
@ -423,11 +430,18 @@ static visplane_t *new_visplane(unsigned hash)
//
visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap,
ffloor_t *pfloor)
ffloor_t *pfloor
#ifdef ESLOPE
, pslope_t *slope
#endif
)
{
visplane_t *check;
unsigned hash;
#ifdef ESLOPE
if (slope); else // Don't mess with this right now if a slope is involved
#endif
if (plangle != 0)
{
// Add the view offset, rotated by the plane angle.
@ -462,7 +476,11 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
&& xoff == check->xoffs && yoff == check->yoffs
&& planecolormap == check->extra_colormap
&& !pfloor && !check->ffloor && check->viewz == viewz
&& check->viewangle == viewangle)
&& check->viewangle == viewangle
#ifdef ESLOPE
&& check->slope == slope
#endif
)
{
return check;
}
@ -485,6 +503,9 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
#ifdef POLYOBJECTS_PLANES
check->polyobj = NULL;
#endif
#ifdef ESLOPE
check->slope = slope;
#endif
memset(check->top, 0xff, sizeof (check->top));
memset(check->bottom, 0x00, sizeof (check->bottom));
@ -551,6 +572,9 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop)
new_pl->plangle = pl->plangle;
#ifdef POLYOBJECTS_PLANES
new_pl->polyobj = pl->polyobj;
#endif
#ifdef ESLOPE
new_pl->slope = pl->slope;
#endif
pl = new_pl;
pl->minx = start;
@ -726,31 +750,15 @@ void R_DrawSinglePlane(visplane_t *pl)
// Hacked up support for alpha value in software mode Tails 09-24-2002 (sidenote: ported to polys 10-15-2014, there was no time travel involved -Red)
if (pl->polyobj->translucency >= 10)
return; // Don't even draw it
else if (pl->polyobj->translucency == 9)
ds_transmap = ((tr_trans90)<<FF_TRANSSHIFT) - 0x10000 + transtables;
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 if (pl->polyobj->translucency > 0)
ds_transmap = transtables + ((pl->polyobj->translucency-1)<<FF_TRANSSHIFT);
else // Opaque, but allow transparent flat pixels
spanfunc = splatfunc;
if (pl->extra_colormap && pl->extra_colormap->fog)
light = (pl->lightlevel >> LIGHTSEGSHIFT);
else
light = LIGHTLEVELS-1;
light = LIGHTLEVELS-1;
} else
#endif
@ -781,23 +789,23 @@ void R_DrawSinglePlane(visplane_t *pl)
if (pl->ffloor->alpha < 12)
return; // Don't even draw it
else if (pl->ffloor->alpha < 38)
ds_transmap = ((tr_trans90)<<FF_TRANSSHIFT) - 0x10000 + transtables;
ds_transmap = transtables + ((tr_trans90-1)<<FF_TRANSSHIFT);
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)
ds_transmap = ((tr_trans70)<<FF_TRANSSHIFT) - 0x10000 + transtables;
ds_transmap = transtables + ((tr_trans70-1)<<FF_TRANSSHIFT);
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)
ds_transmap = ((tr_trans50)<<FF_TRANSSHIFT) - 0x10000 + transtables;
ds_transmap = transtables + ((tr_trans50-1)<<FF_TRANSSHIFT);
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)
ds_transmap = ((tr_trans30)<<FF_TRANSSHIFT) - 0x10000 + transtables;
ds_transmap = transtables + ((tr_trans30-1)<<FF_TRANSSHIFT);
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)
ds_transmap = ((tr_trans10)<<FF_TRANSSHIFT) - 0x10000 + transtables;
ds_transmap = transtables + ((tr_trans10-1)<<FF_TRANSSHIFT);
else // Opaque, but allow transparent flat pixels
spanfunc = splatfunc;
@ -814,7 +822,11 @@ void R_DrawSinglePlane(visplane_t *pl)
else light = (pl->lightlevel >> LIGHTSEGSHIFT);
#ifndef NOWATER
if (pl->ffloor->flags & FF_RIPPLE)
if (pl->ffloor->flags & FF_RIPPLE
#ifdef ESLOPE
&& !pl->slope
#endif
)
{
INT32 top, bottom;
@ -842,6 +854,9 @@ void R_DrawSinglePlane(visplane_t *pl)
}
else light = (pl->lightlevel >> LIGHTSEGSHIFT);
#ifdef ESLOPE
if (!pl->slope) // Don't mess with angle on slopes! We'll handle this ourselves later
#endif
if (viewangle != pl->viewangle)
{
memset(cachedheight, 0, sizeof (cachedheight));
@ -915,6 +930,106 @@ void R_DrawSinglePlane(visplane_t *pl)
if (light < 0)
light = 0;
#ifdef ESLOPE
if (pl->slope) {
// Potentially override other stuff for now cus we're mean. :< But draw a slope plane!
// I copied ZDoom's code and adapted it to SRB2... -Red
floatv3_t p, m, n;
float ang;
float vx, vy, vz;
float fudge;
// compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly
// use this as a temp var to store P_GetZAt's return value each time
fixed_t temp;
xoffs &= ((1 << (32-nflatshiftup))-1);
yoffs &= ((1 << (32-nflatshiftup))-1);
xoffs -= (pl->slope->o.x + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1);
yoffs += (pl->slope->o.y + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1);
// Okay, look, don't ask me why this works, but without this setup there's a disgusting-looking misalignment with the textures. -Red
fudge = ((1<<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];
// set the maximum value for unsigned
@ -951,7 +1066,7 @@ using the palette colors.
if (spanfunc == R_DrawSpan_8)
{
INT32 i;
ds_transmap = ((tr_trans50)<<FF_TRANSSHIFT) - 0x10000 + transtables;
ds_transmap = transtables + ((tr_trans50-1)<<FF_TRANSSHIFT);
spanfunc = R_DrawTranslucentSpan_8;
for (i=0; i<4; i++)
{

View File

@ -61,6 +61,9 @@ typedef struct visplane_s
#ifdef POLYOBJECTS_PLANES
polyobj_t *polyobj;
#endif
#ifdef ESLOPE
pslope_t *slope;
#endif
} visplane_t;
extern visplane_t *floorplane;
@ -79,6 +82,8 @@ extern fixed_t cachedxstep[MAXVIDHEIGHT];
extern fixed_t cachedystep[MAXVIDHEIGHT];
extern fixed_t basexscale, baseyscale;
extern lighttable_t **planezlight;
extern fixed_t *yslope;
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_DrawPlanes(void);
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);
void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop);
void R_PlaneBounds(visplane_t *plane);
@ -110,6 +119,14 @@ typedef struct planemgr_s
INT16 f_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;
#ifdef POLYOBJECTS_PLANES
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_x2 = x2;
ds_transmap = ((tr_trans50)<<FF_TRANSSHIFT) - 0x10000 + transtables;
ds_transmap = transtables + ((tr_trans50-1)<<FF_TRANSSHIFT);
splatfunc();
}

View File

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

View File

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

View File

@ -141,14 +141,6 @@ typedef struct
static channel_t *channels = NULL;
static INT32 numofchannels = 0;
// whether songs are mus_paused
static boolean mus_paused = 0;
// music currently being played
musicinfo_t *mus_playing = 0;
static INT32 nextcleanup;
//
// Internals.
//
@ -307,47 +299,6 @@ static void SetChannelsNum(void)
channels[i].sfxinfo = 0;
}
//
// Initializes sound stuff, including volume
// Sets channels, SFX and music volume,
// allocates channel buffer, sets S_sfx lookup.
//
void S_Init(INT32 sfxVolume, INT32 digMusicVolume, INT32 midiMusicVolume)
{
INT32 i;
if (dedicated)
return;
S_SetSfxVolume(sfxVolume);
S_SetDigMusicVolume(digMusicVolume);
S_SetMIDIMusicVolume(midiMusicVolume);
SetChannelsNum();
// no sounds are playing, and they are not mus_paused
mus_paused = 0;
// Note that sounds have not been cached (yet).
for (i = 1; i < NUMSFX; i++)
{
S_sfx[i].usefulness = -1; // for I_GetSfx()
S_sfx[i].lumpnum = LUMPERROR;
}
// precache sounds if requested by cmdline, or precachesound var true
if (!nosound && (M_CheckParm("-precachesound") || precachesound.value))
{
// Initialize external data (all sounds) at start, keep static.
CONS_Printf(M_GetText("Loading sounds... "));
for (i = 1; i < NUMSFX; i++)
if (S_sfx[i].name)
S_sfx[i].data = I_GetSfx(&S_sfx[i]);
CONS_Printf(M_GetText(" pre-cached all sound data\n"));
}
}
// Retrieve the lump number of sfx
//
@ -371,12 +322,6 @@ lumpnum_t S_GetSfxLumpNum(sfxinfo_t *sfx)
return W_GetNumForName("dsthok");
}
//
// Per level startup code.
// Kills playing sounds at start of level,
// determines music if any, changes music.
//
// Stop all sounds, load level info, THEN start sounds.
void S_StopSounds(void)
{
@ -442,22 +387,6 @@ void S_StopSoundByNum(sfxenum_t sfxnum)
}
}
void S_Start(void)
{
if (mapmusic & MUSIC_RELOADRESET)
{
mapmusic = mapheaderinfo[gamemap-1]->musicslot
| (mapheaderinfo[gamemap-1]->musicslottrack << MUSIC_TRACKSHIFT);
}
mus_paused = 0;
if (cv_resetmusic.value)
S_StopMusic();
S_ChangeMusic(mapmusic, true);
nextcleanup = 15;
}
void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
{
INT32 sep, pitch, priority, cnum;
@ -745,43 +674,6 @@ void S_StopSound(void *origin)
}
}
//
// Stop and resume music, during game PAUSE.
//
void S_PauseSound(void)
{
if (!nodigimusic)
I_PauseSong(0);
if (mus_playing && !mus_paused)
{
I_PauseSong(mus_playing->handle);
mus_paused = true;
}
// pause cd music
#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
I_PauseCD();
#else
I_StopCD();
#endif
}
void S_ResumeSound(void)
{
if (!nodigimusic)
I_ResumeSong(0);
else
if (mus_playing && mus_paused)
{
I_ResumeSong(mus_playing->handle);
mus_paused = false;
}
// resume cd music
I_ResumeCD();
}
//
// Updates music & sounds
//
@ -883,38 +775,6 @@ void S_UpdateSounds(void)
}
}
// Clean up unused data.
#if 0
{
static tic_t nextcleanup = 0;
size_t i;
sfxinfo_t *sfx;
if (!gametic) nextcleanup = 0;
if (gametic > nextcleanup)
{
for (i = 1; i < NUMSFX; i++)
{
if (S_sfx[i].usefulness == 0)
{
S_sfx[i].usefulness--;
// don't forget to unlock it !!!
// __dmpi_unlock_....
//Z_ChangeTag(S_sfx[i].data, PU_CACHE);
I_FreeSfx(S_sfx+i);
//S_sfx[i].data = 0;
CONS_Debug(DBG_GAMELOGIC, "flushed sfx %.6s\n", S_sfx[i].name);
}
}
nextcleanup = gametic + 15;
}
}
#endif
// FIXTHIS: nextcleanup is probably unused
for (cnum = 0; cnum < numofchannels; cnum++)
{
c = &channels[cnum];
@ -984,37 +844,6 @@ void S_UpdateSounds(void)
I_UpdateSound();
}
void S_SetDigMusicVolume(INT32 volume)
{
if (volume < 0 || volume > 31)
CONS_Alert(CONS_WARNING, "musicvolume should be between 0-31\n");
CV_SetValue(&cv_digmusicvolume, volume&31);
actualdigmusicvolume = cv_digmusicvolume.value; //check for change of var
#ifdef DJGPPDOS
I_SetDigMusicVolume(31); // Trick for buggy dos drivers. Win32 doesn't need this.
#endif
if (!nodigimusic)
I_SetDigMusicVolume(volume&31);
}
void S_SetMIDIMusicVolume(INT32 volume)
{
if (volume < 0 || volume > 31)
CONS_Alert(CONS_WARNING, "musicvolume should be between 0-31\n");
CV_SetValue(&cv_midimusicvolume, volume&0x1f);
actualmidimusicvolume = cv_midimusicvolume.value; //check for change of var
#ifdef DJGPPDOS
I_SetMIDIMusicVolume(31); // Trick for buggy dos drivers. Win32 doesn't need this.
#endif
I_SetMIDIMusicVolume(volume&0x1f);
}
void S_SetSfxVolume(INT32 volume)
{
if (volume < 0 || volume > 31)
@ -1031,137 +860,6 @@ void S_SetSfxVolume(INT32 volume)
#endif
}
static boolean S_MIDIMusic(musicinfo_t *music, boolean looping)
{
if (nomidimusic)
return true; // no error
if (music_disabled)
return true; // no error
// get lumpnum if neccessary
if (!music->lumpnum)
{
if (W_CheckNumForName(va("d_%s", music->name)) == LUMPERROR)
return false;
music->lumpnum = W_GetNumForName(va("d_%s", music->name));
}
// load & register it
music->data = W_CacheLumpNum(music->lumpnum, PU_MUSIC);
#if defined (macintosh) && !defined (HAVE_SDL)
music->handle = I_RegisterSong(music_num);
#else
music->handle = I_RegisterSong(music->data, W_LumpLength(music->lumpnum));
#endif
#ifdef MUSSERV
if (msg_id != -1)
{
struct musmsg msg_buffer;
msg_buffer.msg_type = 6;
memset(msg_buffer.msg_text, 0, sizeof (msg_buffer.msg_text));
sprintf(msg_buffer.msg_text, "d_%s", music->name);
msgsnd(msg_id, (struct msgbuf*)&msg_buffer, sizeof (msg_buffer.msg_text), IPC_NOWAIT);
}
#endif
// play it
if (!I_PlaySong(music->handle, looping))
return false;
mus_playing = music;
return true;
}
static boolean S_DigMusic(musicinfo_t *music, boolean looping)
{
if (nodigimusic)
return false; // try midi
if (digital_disabled)
return false; // try midi
if (!I_StartDigSong(music->name, looping))
return false;
mus_playing = music;
return true;
}
void S_ChangeMusic(UINT32 mslotnum, boolean looping)
{
musicinfo_t *music;
musicenum_t music_num = (signed)(mslotnum & MUSIC_SONGMASK);
INT32 track_num = (mslotnum & MUSIC_TRACKMASK) >> MUSIC_TRACKSHIFT;
#if defined (DC) || defined (_WIN32_WCE) || defined (PSP) || defined(GP2X)
S_ClearSfx();
#endif
if (nomidimusic && nodigimusic)
return;
if (music_disabled && digital_disabled)
return;
// No Music
if (music_num == mus_None)
{
S_StopMusic();
return;
}
if (music_num >= NUMMUSIC)
{
CONS_Alert(CONS_ERROR, "Bad music number %d\n", music_num);
return;
}
else
music = &S_music[music_num];
if (mus_playing != music)
{
S_StopMusic(); // shutdown old music
if (!S_DigMusic(music, looping) && !S_MIDIMusic(music, looping))
{
CONS_Alert(CONS_ERROR, M_GetText("Music lump %.6s not found!\n"), music->name);
return;
}
}
I_SetSongTrack(track_num);
}
boolean S_SpeedMusic(float speed)
{
return I_SetSongSpeed(speed);
}
void S_StopMusic(void)
{
if (!mus_playing)
return;
if (mus_paused)
I_ResumeSong(mus_playing->handle);
if (!nodigimusic)
I_StopDigSong();
S_SpeedMusic(1.0f);
I_StopSong(mus_playing->handle);
I_UnRegisterSong(mus_playing->handle);
#ifndef HAVE_SDL //SDL uses RWOPS
Z_ChangeTag(mus_playing->data, PU_CACHE);
#endif
mus_playing->data = NULL;
mus_playing = NULL;
}
void S_ClearSfx(void)
{
#ifndef DJGPPDOS
@ -1452,3 +1150,285 @@ void S_StartSoundName(void *mo, const char *soundname)
S_StartSound(mo, soundnum);
}
/// ------------------------
/// Music
/// ------------------------
#ifdef MUSICSLOT_COMPATIBILITY
const char *compat_special_music_slots[16] =
{
"titles", // 1036 title screen
"read_m", // 1037 intro
"lclear", // 1038 level clear
"invinc", // 1039 invincibility
"shoes", // 1040 super sneakers
"minvnc", // 1041 Mario invincibility
"drown", // 1042 drowning
"gmover", // 1043 game over
"xtlife", // 1044 extra life
"contsc", // 1045 continue screen
"supers", // 1046 Super Sonic
"chrsel", // 1047 character select
"credit", // 1048 credits
"racent", // 1049 Race Results
"stjr", // 1050 Sonic Team Jr. Presents
""
};
#endif
#define music_playing (music_name[0]) // String is empty if no music is playing
static char music_name[7]; // up to 6-character name
static lumpnum_t music_lumpnum; // lump number of music (used??)
static void *music_data; // music raw data
static INT32 music_handle; // once registered, the handle for the music
static boolean mus_paused = 0; // whether songs are mus_paused
static boolean S_MIDIMusic(const char *mname, boolean looping)
{
lumpnum_t mlumpnum;
void *mdata;
INT32 mhandle;
if (nomidimusic || music_disabled)
return false; // didn't search.
if (W_CheckNumForName(va("d_%s", mname)) == LUMPERROR)
return false;
mlumpnum = W_GetNumForName(va("d_%s", mname));
// load & register it
mdata = W_CacheLumpNum(mlumpnum, PU_MUSIC);
mhandle = I_RegisterSong(mdata, W_LumpLength(mlumpnum));
#ifdef MUSSERV
if (msg_id != -1)
{
struct musmsg msg_buffer;
msg_buffer.msg_type = 6;
memset(msg_buffer.msg_text, 0, sizeof (msg_buffer.msg_text));
sprintf(msg_buffer.msg_text, "d_%s", mname);
msgsnd(msg_id, (struct msgbuf*)&msg_buffer, sizeof (msg_buffer.msg_text), IPC_NOWAIT);
}
#endif
// play it
if (!I_PlaySong(mhandle, looping))
return false;
strncpy(music_name, mname, 7);
music_name[6] = 0;
music_lumpnum = mlumpnum;
music_data = mdata;
music_handle = mhandle;
return true;
}
static boolean S_DigMusic(const char *mname, boolean looping)
{
if (nodigimusic || digital_disabled)
return false; // try midi
if (!I_StartDigSong(mname, looping))
return false;
strncpy(music_name, mname, 7);
music_name[6] = 0;
music_lumpnum = LUMPERROR;
music_data = NULL;
music_handle = 0;
return true;
}
void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping)
{
#if defined (DC) || defined (_WIN32_WCE) || defined (PSP) || defined(GP2X)
S_ClearSfx();
#endif
if ((nomidimusic || music_disabled) && (nodigimusic || digital_disabled))
return;
// No Music (empty string)
if (mmusic[0] == 0)
{
S_StopMusic();
return;
}
if (strncmp(music_name, mmusic, 6))
{
S_StopMusic(); // shutdown old music
if (!S_DigMusic(mmusic, looping) && !S_MIDIMusic(mmusic, looping))
{
CONS_Alert(CONS_ERROR, M_GetText("Music lump %.6s not found!\n"), mmusic);
return;
}
}
I_SetSongTrack(mflags & MUSIC_TRACKMASK);
}
boolean S_SpeedMusic(float speed)
{
return I_SetSongSpeed(speed);
}
void S_StopMusic(void)
{
if (!music_playing)
return;
if (mus_paused)
I_ResumeSong(music_handle);
if (!nodigimusic)
I_StopDigSong();
S_SpeedMusic(1.0f);
I_StopSong(music_handle);
I_UnRegisterSong(music_handle);
#ifndef HAVE_SDL //SDL uses RWOPS
Z_ChangeTag(music_data, PU_CACHE);
#endif
music_data = NULL;
music_name[0] = 0;
}
void S_SetDigMusicVolume(INT32 volume)
{
if (volume < 0 || volume > 31)
CONS_Alert(CONS_WARNING, "musicvolume should be between 0-31\n");
CV_SetValue(&cv_digmusicvolume, volume&31);
actualdigmusicvolume = cv_digmusicvolume.value; //check for change of var
#ifdef DJGPPDOS
I_SetDigMusicVolume(31); // Trick for buggy dos drivers. Win32 doesn't need this.
#endif
if (!nodigimusic)
I_SetDigMusicVolume(volume&31);
}
void S_SetMIDIMusicVolume(INT32 volume)
{
if (volume < 0 || volume > 31)
CONS_Alert(CONS_WARNING, "musicvolume should be between 0-31\n");
CV_SetValue(&cv_midimusicvolume, volume&0x1f);
actualmidimusicvolume = cv_midimusicvolume.value; //check for change of var
#ifdef DJGPPDOS
I_SetMIDIMusicVolume(31); // Trick for buggy dos drivers. Win32 doesn't need this.
#endif
I_SetMIDIMusicVolume(volume&0x1f);
}
/// ------------------------
/// Init & Others
/// ------------------------
//
// Initializes sound stuff, including volume
// Sets channels, SFX and music volume,
// allocates channel buffer, sets S_sfx lookup.
//
void S_Init(INT32 sfxVolume, INT32 digMusicVolume, INT32 midiMusicVolume)
{
INT32 i;
if (dedicated)
return;
S_SetSfxVolume(sfxVolume);
S_SetDigMusicVolume(digMusicVolume);
S_SetMIDIMusicVolume(midiMusicVolume);
SetChannelsNum();
// no sounds are playing, and they are not mus_paused
mus_paused = 0;
// Note that sounds have not been cached (yet).
for (i = 1; i < NUMSFX; i++)
{
S_sfx[i].usefulness = -1; // for I_GetSfx()
S_sfx[i].lumpnum = LUMPERROR;
}
// precache sounds if requested by cmdline, or precachesound var true
if (!nosound && (M_CheckParm("-precachesound") || precachesound.value))
{
// Initialize external data (all sounds) at start, keep static.
CONS_Printf(M_GetText("Loading sounds... "));
for (i = 1; i < NUMSFX; i++)
if (S_sfx[i].name)
S_sfx[i].data = I_GetSfx(&S_sfx[i]);
CONS_Printf(M_GetText(" pre-cached all sound data\n"));
}
}
//
// Per level startup code.
// Kills playing sounds at start of level,
// determines music if any, changes music.
//
void S_Start(void)
{
if (mapmusflags & MUSIC_RELOADRESET)
{
strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7);
mapmusname[6] = 0;
mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK);
}
mus_paused = 0;
if (cv_resetmusic.value)
S_StopMusic();
S_ChangeMusic(mapmusname, mapmusflags, true);
}
//
// Stop and resume music, during game PAUSE.
//
void S_PauseAudio(void)
{
if (!nodigimusic)
I_PauseSong(0);
if (music_playing && !mus_paused)
{
I_PauseSong(music_handle);
mus_paused = true;
}
// pause cd music
#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
I_PauseCD();
#else
I_StopCD();
#endif
}
void S_ResumeAudio(void)
{
if (!nodigimusic)
I_ResumeSong(0);
else
if (music_playing && mus_paused)
{
I_ResumeSong(music_handle);
mus_paused = false;
}
// resume cd music
I_ResumeCD();
}

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