Merge branch 'master' of http://git.magicalgirl.moe/STJr/SRB2Internal.git into shield-actions

# Conflicts:
#	src/d_player.h
#	src/p_inter.c
#	src/p_mobj.c
#	src/p_user.c
This commit is contained in:
toasterbabe 2016-09-27 18:24:53 +01:00
commit a8be1e6b7d
96 changed files with 4419 additions and 2940 deletions

View File

@ -98,7 +98,7 @@ matrix:
- p7zip-full - p7zip-full
- gcc-6 - gcc-6
compiler: gcc-6 compiler: gcc-6
env: WFLAGS="-Wno-error=tautological-compare" env: WFLAGS="-Wno-tautological-compare"
#gcc-6 (Ubuntu 6.1.1-3ubuntu11~14.04.1) 6.1.1 20160511 #gcc-6 (Ubuntu 6.1.1-3ubuntu11~14.04.1) 6.1.1 20160511
- os: linux - os: linux
compiler: clang compiler: clang
@ -162,28 +162,28 @@ matrix:
- clang-3.8 - clang-3.8
compiler: clang-3.8 compiler: clang-3.8
#clang version 3.8.1-svn271127-1~exp1 (branches/release_38) #clang version 3.8.1-svn271127-1~exp1 (branches/release_38)
- os: osx
osx_image: beta-xcode6.1
#Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn)
- os: osx
osx_image: beta-xcode6.2
compiler: gcc
#Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)
# - os: osx # - os: osx
# osx_image: beta-xcode6.3 # osx_image: beta-xcode6.1
# #I think xcode.6.3 VM is broken, it does not boot # #Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn)
- os: osx # - os: osx
osx_image: xcode6.4 # osx_image: beta-xcode6.2
#Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn) # compiler: gcc
- os: osx # #Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)
osx_image: xcode7 ## - os: osx
#Apple LLVM version 7.0.0 (clang-700.0.72) ## osx_image: beta-xcode6.3
- os: osx ## #I think xcode.6.3 VM is broken, it does not boot
osx_image: xcode7.1 # - os: osx
#Apple LLVM version 7.0.0 (clang-700.1.76) # osx_image: xcode6.4
- os: osx # #Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
osx_image: xcode7.2 # - os: osx
#Apple LLVM version 7.0.2 (clang-700.1.81) # osx_image: xcode7
# #Apple LLVM version 7.0.0 (clang-700.0.72)
# - os: osx
# osx_image: xcode7.1
# #Apple LLVM version 7.0.0 (clang-700.1.76)
# - os: osx
# osx_image: xcode7.2
# #Apple LLVM version 7.0.2 (clang-700.1.81)
- os: osx - os: osx
osx_image: xcode7.3 osx_image: xcode7.3
#Apple LLVM version 7.3.0 (clang-703.0.31) #Apple LLVM version 7.3.0 (clang-703.0.31)
@ -213,7 +213,7 @@ before_script:
- 7z x $HOME/srb2_cache/SRB2-v2115-assets-2.7z -oassets - 7z x $HOME/srb2_cache/SRB2-v2115-assets-2.7z -oassets
- mkdir build - mkdir build
- cd build - cd build
- export CFLAGS="-Wall -W $WFLAGS" - export CFLAGS="-Wall -W -Werror $WFLAGS"
- export CCACHE_COMPRESS=true - export CCACHE_COMPRESS=true
- cmake .. -DCMAKE_BUILD_TYPE=Release - cmake .. -DCMAKE_BUILD_TYPE=Release

22
README.md Normal file
View File

@ -0,0 +1,22 @@
# Sonic Robo Blast 2
[![Build status](https://ci.appveyor.com/api/projects/status/399d4hcw9yy7hg2y?svg=true)](https://ci.appveyor.com/project/STJr/srb2)
[![Build status](https://travis-ci.org/STJr/SRB2.svg?branch=master)](https://travis-ci.org/STJr/SRB2)
[Sonic Robo Blast 2](https://srb2.org/) is a 3D Sonic the Hedgehog fangame based on a modified version of [Doom Legacy](http://doomlegacy.sourceforge.net/).
## Dependencies
- NASM (x86 builds only)
- SDL2 (Linux/OS X only)
- SDL2-Mixer (Linux/OS X only)
- libupnp (Linux/OS X only)
- libgme (Linux/OS X only)
Warning: 64-bit builds are not netgame compatible with 32-bit builds. Use at your own risk.
## Compiling
See [SRB2 Wiki/Source code compiling](http://wiki.srb2.org/wiki/Source_code_compiling)
## Disclaimer
Sonic Team Junior is in no way affiliated with SEGA or Sonic Team. We do not claim ownership of any of SEGA's intellectual property used in SRB2.

View File

@ -2815,6 +2815,39 @@ HW3SOUND for 3D hardware sound support
<Option target="Debug Mingw64/DirectX" /> <Option target="Debug Mingw64/DirectX" />
<Option target="Release Mingw64/DirectX" /> <Option target="Release Mingw64/DirectX" />
</Unit> </Unit>
<Unit filename="src/m_aatree.c">
<Option compilerVar="CC" />
<Option target="Debug Native/SDL" />
<Option target="Release Native/SDL" />
<Option target="Debug Mingw/SDL" />
<Option target="Release Mingw/SDL" />
<Option target="Debug Mingw/DirectX" />
<Option target="Release Mingw/DirectX" />
<Option target="Debug Any/Dummy" />
<Option target="Release Any/Dummy" />
<Option target="Debug Linux/SDL" />
<Option target="Release Linux/SDL" />
<Option target="Debug Mingw64/SDL" />
<Option target="Release Mingw64/SDL" />
<Option target="Debug Mingw64/DirectX" />
<Option target="Release Mingw64/DirectX" />
</Unit>
<Unit filename="src/m_aatree.h">
<Option target="Debug Native/SDL" />
<Option target="Release Native/SDL" />
<Option target="Debug Mingw/SDL" />
<Option target="Release Mingw/SDL" />
<Option target="Debug Mingw/DirectX" />
<Option target="Release Mingw/DirectX" />
<Option target="Debug Any/Dummy" />
<Option target="Release Any/Dummy" />
<Option target="Debug Linux/SDL" />
<Option target="Release Linux/SDL" />
<Option target="Debug Mingw64/SDL" />
<Option target="Release Mingw64/SDL" />
<Option target="Debug Mingw64/DirectX" />
<Option target="Release Mingw64/DirectX" />
</Unit>
<Unit filename="src/m_anigif.c"> <Unit filename="src/m_anigif.c">
<Option compilerVar="CC" /> <Option compilerVar="CC" />
<Option target="Debug Native/SDL" /> <Option target="Debug Native/SDL" />

View File

@ -1,4 +1,4 @@
version: 2.1.14.{branch}-{build} version: 2.1.16.{branch}-{build}
os: MinGW os: MinGW
environment: environment:

View File

@ -1,155 +0,0 @@
Here it is! SRB2 v2.1.14 source code!
(why do we keep the version number up to date
when everything else in this file is hilariously old?
- Inuyasha)
Win32 with Visual C (6SP6+Processor Pack OR 7)
~~~
2 VC++ 6.0 project files are included:
Win32/DirectX/FMOD
src\win32\wLegacy.dsw
You'll need FMOD to compile this version (www.fmod.org)
or
Win32/SDL/SDL_mixer
src\sdl\Win32SDL.dsp
You'll need SDL and SDL_mixer for this version (www.libsdl.org)
Both needs NASM (http://sourceforge.net/projects/nasm)
For PNG screenshot, libPNG, and Zlib (from http://gnuwin32.sourceforge.net/)
No warranty, support, etc. of any kind is offered,
just plain old as is.
Some bits of code are still really scary.
Go nuts!
Win32 with Dev-C++ (http://bloodshed.net/ free!)
~~~
2 Dev-C++ project files are included:
Win32/DirectX/FMOD
src\win32\SRB2.dev
or
Win32/SDL/SDL_mixer
src\sdl\Win32SDL.dev
You'll need SDL and SDL_mixer for this version (www.libsdl.org)
libPNG and Zlib (from http://gnuwin32.sourceforge.net/)
Note there are precompiled libpng.a and libz.a for Mingw
you will need NASM for both SDL/SDL_mixer and DirectX/FMOD
and you need DirectX 6 (or up) Dev-Paks to compile DirectX version
GNU/Linux
~~~
Dependencies:
SDL 1.2.7 or better (from libsdl.org)
SDL_Mixer 1.2.2(.7 for file-less music playback) (from libsdl.org)
Nasm (use NOASM=1 if you don't have it or have an non-i386 system, I think)
libPNG 1.2.7
Zlib 1.2.3
The Xiph.org libogg and libvorbis libraries
The OpenGL headers (from Mesa, usually shipped with your X.org or XFree
installation, so you needn't worry, most likely)
GCC 3.x toolchain and binutils
GNU Make
Build instructions:
make -C src LINUX=1
Build instructions (64 bit):
make -C src LINUX64=1
Build instructions to build for Wii Linux/SRB2Wii on a PowerPC system,
follow cross-compiling instructions for cross-compiling on a x86 system:
make -C src LINUX=1 WIILINUX=1
Build instructions to build for Pandora (Linux) on a ARM system,
follow cross-compiling instructions for cross-compiling on a x86 system:
make -C src PANDORA=1
Solaris
~~~
Dependencies:
SDL 1.2.5 or better (from libsdl.org)
SDL_Mixer 1.2.2(.7 for file-less music playback) (from libsdl.org)
libPNG 1.2.7
Zlib 1.2.3
The Xiph.org libogg and libvorbis libraries
The OpenGL headers (from Mesa, usually shipped with your X.org or XFree
installation, so you needn't worry, most likely)
GCC 3.x toolchain and binutils
GNU Make
You can get all these programs/libraries from the Companion CD (except SDL_mixer and OpenGL)
Build instructions:
gmake -C src SOLARIS=1
FreeBSD
~~~
Dependencies:
SDL 1.2.7 or better (from libsdl.org)
SDL_Mixer 1.2.2(.7 for file-less music playback) (from libsdl.org)
Nasm (use NOASM=1 if you don't have it or have an non-i386 system, I think)
libPNG 1.2.7
Zlib 1.2.3
The Xiph.org libogg and libvorbis libraries
The OpenGL headers (from Mesa, usually shipped with your X.org or XFree
installation, so you needn't worry, most likely)
GCC 3.x toolchain and binutils
GNU Make
Build instructions:
gmake -C src FREEBSD=1
DJGPP/DOS
~~~
Dependencies:
Allegro 3.12 game programming library, (from
http://alleg.sourceforge.net/index.html)
Nasm (use NOASM=1 if you don't have it)
libsocket (from http://homepages.nildram.co.uk/~phekda/richdawe/lsck/) or
Watt-32 (from http://www.bgnett.no/~giva/)
GCC 3.x toolchain and binutils
GNU Make
Build instructions:
make -C src # to link with Watt-32, add WATTCP=1
# for remote debugging over the COM port, add RDB=1
Notes:
use tools\djgpp\all313.diff to update Allegro to a "more usable" version ;)
Example: E:\djgpp\allegro>patch -p# < D:\SRB2Code\1.1\srb2\tools\djgpp\all313.diff
Windows CE
~~~
Dependencies:
SDL 1.27
Build instructions:
use src\SDL\WinCE\SRB2CE.vcw
-------------------------------------------------------------------------------
binaries will turn in up in bin/
note: read the src/makefile for more options
- Sonic Team Junior
http://www.srb2.org

View File

@ -22,6 +22,7 @@ set(SRB2_CORE_SOURCES
i_tcp.c i_tcp.c
info.c info.c
lzf.c lzf.c
m_aatree.c
m_anigif.c m_anigif.c
m_argv.c m_argv.c
m_bbox.c m_bbox.c
@ -83,6 +84,7 @@ set(SRB2_CORE_HEADERS
info.h info.h
keys.h keys.h
lzf.h lzf.h
m_aatree.h
m_anigif.h m_anigif.h
m_argv.h m_argv.h
m_bbox.h m_bbox.h

View File

@ -189,6 +189,10 @@ ifdef FREEBSD
UNIXCOMMON=1 UNIXCOMMON=1
endif endif
ifdef MACOSX
UNIXCOMMON=1
endif
ifdef NDS ifdef NDS
NOPNG=1 NOPNG=1
NONET=1 NONET=1
@ -429,6 +433,7 @@ OBJS:=$(i_main_o) \
$(OBJDIR)/hu_stuff.o \ $(OBJDIR)/hu_stuff.o \
$(OBJDIR)/y_inter.o \ $(OBJDIR)/y_inter.o \
$(OBJDIR)/st_stuff.o \ $(OBJDIR)/st_stuff.o \
$(OBJDIR)/m_aatree.o \
$(OBJDIR)/m_anigif.o \ $(OBJDIR)/m_anigif.o \
$(OBJDIR)/m_argv.o \ $(OBJDIR)/m_argv.o \
$(OBJDIR)/m_bbox.o \ $(OBJDIR)/m_bbox.o \
@ -593,11 +598,15 @@ ifndef WINDOWSHELL
-$(GZIP) $(GZIP_OPT2) $(BIN)/$(DBGNAME).txt -$(GZIP) $(GZIP_OPT2) $(BIN)/$(DBGNAME).txt
endif endif
endif endif
# mac os x lsdlsrb2 does not like objcopy
ifndef MACOSX
ifndef PSP ifndef PSP
$(OBJCOPY) $(BIN)/$(EXENAME) $(BIN)/$(DBGNAME) $(OBJCOPY) $(BIN)/$(EXENAME) $(BIN)/$(DBGNAME)
$(OBJCOPY) --strip-debug $(BIN)/$(EXENAME) $(OBJCOPY) --strip-debug $(BIN)/$(EXENAME)
-$(OBJCOPY) --add-gnu-debuglink=$(BIN)/$(DBGNAME) $(BIN)/$(EXENAME) -$(OBJCOPY) --add-gnu-debuglink=$(BIN)/$(DBGNAME) $(BIN)/$(EXENAME)
endif endif
endif
ifndef NOUPX ifndef NOUPX
-$(UPX) $(UPX_OPTS) $(BIN)/$(EXENAME) -$(UPX) $(UPX_OPTS) $(BIN)/$(EXENAME)
endif endif
@ -745,6 +754,11 @@ $(OBJDIR)/%.o: %.c
$(OBJDIR)/%.o: $(INTERFACE)/%.c $(OBJDIR)/%.o: $(INTERFACE)/%.c
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
ifdef MACOSX
$(OBJDIR)/%.o: sdl/macosx/%.c
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
endif
$(OBJDIR)/%.o: hardware/%.c $(OBJDIR)/%.o: hardware/%.c
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@ $(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@

View File

@ -406,6 +406,15 @@ else
WINDRES=windres WINDRES=windres
endif endif
# because Apple screws with us on this
# need to get bintools from homebrew
ifdef MACOSX
CC=clang
CXX=clang
OBJCOPY=gobjcopy
OBJDUMP=gobjdump
endif
OBJDUMP_OPTS?=--wide --source --line-numbers OBJDUMP_OPTS?=--wide --source --line-numbers
LD=$(CC) LD=$(CC)

View File

@ -41,12 +41,13 @@ static inline void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cm
return; return;
#endif #endif
if (tails->player->pflags & (PF_MACESPIN|PF_ITEMHANG)) if (tails->player->powers[pw_carry] == CR_MACESPIN || tails->player->powers[pw_carry] == CR_GENERIC)
{ {
boolean isrelevant = (sonic->player->powers[pw_carry] == CR_MACESPIN || sonic->player->powers[pw_carry] == CR_GENERIC);
dist = P_AproxDistance(tails->x-sonic->x, tails->y-sonic->y); dist = P_AproxDistance(tails->x-sonic->x, tails->y-sonic->y);
if (sonic->player->cmd.buttons & BT_JUMP && sonic->player->pflags & (PF_JUMPED|PF_MACESPIN|PF_ITEMHANG)) if (sonic->player->cmd.buttons & BT_JUMP && (sonic->player->pflags & PF_JUMPED) && isrelevant)
cmd->buttons |= BT_JUMP; cmd->buttons |= BT_JUMP;
if (sonic->player->pflags & (PF_MACESPIN|PF_ITEMHANG)) if (isrelevant)
{ {
cmd->forwardmove = sonic->player->cmd.forwardmove; cmd->forwardmove = sonic->player->cmd.forwardmove;
cmd->angleturn = abs((signed)(tails->angle - sonic->angle))>>16; cmd->angleturn = abs((signed)(tails->angle - sonic->angle))>>16;
@ -211,8 +212,9 @@ boolean B_CheckRespawn(player_t *player)
// Check if Sonic is busy first. // Check if Sonic is busy first.
// If he's doing any of these things, he probably doesn't want to see us. // If he's doing any of these things, he probably doesn't want to see us.
if (sonic->player->pflags & (PF_ROPEHANG|PF_GLIDING|PF_CARRIED|PF_SLIDING|PF_ITEMHANG|PF_MACESPIN|PF_NIGHTSMODE) if (sonic->player->pflags & (PF_GLIDING|PF_SLIDING|PF_NIGHTSMODE)
|| (sonic->player->panim != PA_IDLE && sonic->player->panim != PA_WALK)) || (sonic->player->panim != PA_IDLE && sonic->player->panim != PA_WALK)
|| (sonic->player->powers[pw_carry]))
return false; return false;
// Low ceiling, do not want! // Low ceiling, do not want!

View File

@ -732,7 +732,8 @@ void luaV_execute (lua_State *L, int nexeccalls) {
luaG_runerror(L, LUA_QL("for") " limit must be a number"); luaG_runerror(L, LUA_QL("for") " limit must be a number");
else if (!tonumber(pstep, ra+2)) else if (!tonumber(pstep, ra+2))
luaG_runerror(L, LUA_QL("for") " step must be a number"); luaG_runerror(L, LUA_QL("for") " step must be a number");
setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep))); if (ra && pstep)
setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
dojump(L, pc, GETARG_sBx(i)); dojump(L, pc, GETARG_sBx(i));
continue; continue;
} }

View File

@ -966,9 +966,11 @@ void CV_RegisterVar(consvar_t *variable)
// check net variables // check net variables
if (variable->flags & CV_NETVAR) if (variable->flags & CV_NETVAR)
{ {
const consvar_t *netvar;
variable->netid = CV_ComputeNetid(variable->name); variable->netid = CV_ComputeNetid(variable->name);
if (CV_FindNetVar(variable->netid)) netvar = CV_FindNetVar(variable->netid);
I_Error("Variables %s and %s have same netid\n", variable->name, CV_FindNetVar(variable->netid)->name); if (netvar)
I_Error("Variables %s and %s have same netid\n", variable->name, netvar->name);
} }
// link the variable in // link the variable in
@ -1159,7 +1161,16 @@ found:
var->value = (INT32)(d * FRACUNIT); var->value = (INT32)(d * FRACUNIT);
} }
else else
var->value = atoi(var->string); {
if (var == &cv_forceskin)
{
var->value = R_SkinAvailable(var->string);
if (!R_SkinUnlock(var->value))
var->value = -1;
}
else
var->value = atoi(var->string);
}
finish: finish:
// See the note above. // See the note above.
@ -1383,6 +1394,30 @@ void CV_StealthSet(consvar_t *var, const char *value)
CV_SetCVar(var, value, true); CV_SetCVar(var, value, true);
} }
/** Sets a numeric value to a variable, sometimes calling its callback
* function.
*
* \param var The variable.
* \param value The numeric value, converted to a string before setting.
* \param stealth Do we call the callback function or not?
*/
static void CV_SetValueMaybeStealth(consvar_t *var, INT32 value, boolean stealth)
{
char val[32];
if (var == &cv_forceskin) // Special handling.
{
if ((value < 0) || (value >= numskins))
sprintf(val, "None");
else
sprintf(val, "%s", skins[value].name);
}
else
sprintf(val, "%d", value);
CV_SetCVar(var, val, stealth);
}
/** Sets a numeric value to a variable without calling its callback /** Sets a numeric value to a variable without calling its callback
* function. * function.
* *
@ -1392,10 +1427,7 @@ void CV_StealthSet(consvar_t *var, const char *value)
*/ */
void CV_StealthSetValue(consvar_t *var, INT32 value) void CV_StealthSetValue(consvar_t *var, INT32 value)
{ {
char val[32]; CV_SetValueMaybeStealth(var, value, true);
sprintf(val, "%d", value);
CV_SetCVar(var, val, true);
} }
// New wrapper for what used to be CV_Set() // New wrapper for what used to be CV_Set()
@ -1413,10 +1445,7 @@ void CV_Set(consvar_t *var, const char *value)
*/ */
void CV_SetValue(consvar_t *var, INT32 value) void CV_SetValue(consvar_t *var, INT32 value)
{ {
char val[32]; CV_SetValueMaybeStealth(var, value, false);
sprintf(val, "%d", value);
CV_SetCVar(var, val, false);
} }
/** Adds a value to a console variable. /** Adds a value to a console variable.
@ -1436,7 +1465,23 @@ void CV_AddValue(consvar_t *var, INT32 increment)
// count pointlimit better // count pointlimit better
if (var == &cv_pointlimit && (gametype == GT_MATCH)) if (var == &cv_pointlimit && (gametype == GT_MATCH))
increment *= 50; increment *= 50;
newvalue = var->value + increment;
if (var == &cv_forceskin) // Special handling.
{
INT32 oldvalue = var->value;
newvalue = oldvalue;
do
{
newvalue += increment;
if (newvalue < -1)
newvalue = (numskins - 1);
else if (newvalue >= numskins)
newvalue = -1;
} while ((oldvalue != newvalue)
&& !(R_SkinUnlock(newvalue)));
}
else
newvalue = var->value + increment;
if (var->PossibleValue) if (var->PossibleValue)
{ {

View File

@ -506,6 +506,8 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
rsp->skin = LONG(players[i].skin); rsp->skin = LONG(players[i].skin);
// Just in case Lua does something like // Just in case Lua does something like
// modify these at runtime // modify these at runtime
rsp->camerascale = (fixed_t)LONG(players[i].camerascale);
rsp->shieldscale = (fixed_t)LONG(players[i].shieldscale);
rsp->normalspeed = (fixed_t)LONG(players[i].normalspeed); rsp->normalspeed = (fixed_t)LONG(players[i].normalspeed);
rsp->runspeed = (fixed_t)LONG(players[i].runspeed); rsp->runspeed = (fixed_t)LONG(players[i].runspeed);
rsp->thrustfactor = players[i].thrustfactor; rsp->thrustfactor = players[i].thrustfactor;
@ -521,6 +523,8 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
rsp->mindash = (fixed_t)LONG(players[i].mindash); rsp->mindash = (fixed_t)LONG(players[i].mindash);
rsp->maxdash = (fixed_t)LONG(players[i].maxdash); rsp->maxdash = (fixed_t)LONG(players[i].maxdash);
rsp->jumpfactor = (fixed_t)LONG(players[i].jumpfactor); rsp->jumpfactor = (fixed_t)LONG(players[i].jumpfactor);
rsp->playerheight = (fixed_t)LONG(players[i].height);
rsp->playerspinheight = (fixed_t)LONG(players[i].spinheight);
rsp->speed = (fixed_t)LONG(players[i].speed); rsp->speed = (fixed_t)LONG(players[i].speed);
rsp->jumping = players[i].jumping; rsp->jumping = players[i].jumping;
@ -531,6 +535,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
rsp->deadtimer = players[i].deadtimer; rsp->deadtimer = players[i].deadtimer;
rsp->exiting = (tic_t)LONG(players[i].exiting); rsp->exiting = (tic_t)LONG(players[i].exiting);
rsp->homing = players[i].homing; rsp->homing = players[i].homing;
rsp->dashmode = (tic_t)LONG(players[i].dashmode);
rsp->skidtime = (tic_t)LONG(players[i].skidtime); rsp->skidtime = (tic_t)LONG(players[i].skidtime);
rsp->cmomx = (fixed_t)LONG(players[i].cmomx); rsp->cmomx = (fixed_t)LONG(players[i].cmomx);
rsp->cmomy = (fixed_t)LONG(players[i].cmomy); rsp->cmomy = (fixed_t)LONG(players[i].cmomy);
@ -549,7 +554,6 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
rsp->maxlink = LONG(players[i].maxlink); rsp->maxlink = LONG(players[i].maxlink);
rsp->dashspeed = (fixed_t)LONG(players[i].dashspeed); rsp->dashspeed = (fixed_t)LONG(players[i].dashspeed);
rsp->dashtime = LONG(players[i].dashtime);
rsp->angle_pos = (angle_t)LONG(players[i].angle_pos); rsp->angle_pos = (angle_t)LONG(players[i].angle_pos);
rsp->old_angle_pos = (angle_t)LONG(players[i].old_angle_pos); rsp->old_angle_pos = (angle_t)LONG(players[i].old_angle_pos);
rsp->bumpertime = (tic_t)LONG(players[i].bumpertime); rsp->bumpertime = (tic_t)LONG(players[i].bumpertime);
@ -632,6 +636,8 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].skin = LONG(rsp->skin); players[i].skin = LONG(rsp->skin);
// Just in case Lua does something like // Just in case Lua does something like
// modify these at runtime // modify these at runtime
players[i].camerascale = (fixed_t)LONG(rsp->camerascale);
players[i].shieldscale = (fixed_t)LONG(rsp->shieldscale);
players[i].normalspeed = (fixed_t)LONG(rsp->normalspeed); players[i].normalspeed = (fixed_t)LONG(rsp->normalspeed);
players[i].runspeed = (fixed_t)LONG(rsp->runspeed); players[i].runspeed = (fixed_t)LONG(rsp->runspeed);
players[i].thrustfactor = rsp->thrustfactor; players[i].thrustfactor = rsp->thrustfactor;
@ -647,6 +653,8 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].mindash = (fixed_t)LONG(rsp->mindash); players[i].mindash = (fixed_t)LONG(rsp->mindash);
players[i].maxdash = (fixed_t)LONG(rsp->maxdash); players[i].maxdash = (fixed_t)LONG(rsp->maxdash);
players[i].jumpfactor = (fixed_t)LONG(rsp->jumpfactor); players[i].jumpfactor = (fixed_t)LONG(rsp->jumpfactor);
players[i].height = (fixed_t)LONG(rsp->playerheight);
players[i].spinheight = (fixed_t)LONG(rsp->playerspinheight);
players[i].speed = (fixed_t)LONG(rsp->speed); players[i].speed = (fixed_t)LONG(rsp->speed);
players[i].jumping = rsp->jumping; players[i].jumping = rsp->jumping;
@ -657,6 +665,7 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].deadtimer = rsp->deadtimer; players[i].deadtimer = rsp->deadtimer;
players[i].exiting = (tic_t)LONG(rsp->exiting); players[i].exiting = (tic_t)LONG(rsp->exiting);
players[i].homing = rsp->homing; players[i].homing = rsp->homing;
players[i].dashmode = (tic_t)LONG(rsp->dashmode);
players[i].skidtime = (tic_t)LONG(rsp->skidtime); players[i].skidtime = (tic_t)LONG(rsp->skidtime);
players[i].cmomx = (fixed_t)LONG(rsp->cmomx); players[i].cmomx = (fixed_t)LONG(rsp->cmomx);
players[i].cmomy = (fixed_t)LONG(rsp->cmomy); players[i].cmomy = (fixed_t)LONG(rsp->cmomy);
@ -675,7 +684,6 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].maxlink = LONG(rsp->maxlink); players[i].maxlink = LONG(rsp->maxlink);
players[i].dashspeed = (fixed_t)LONG(rsp->dashspeed); players[i].dashspeed = (fixed_t)LONG(rsp->dashspeed);
players[i].dashtime = LONG(rsp->dashtime);
players[i].angle_pos = (angle_t)LONG(rsp->angle_pos); players[i].angle_pos = (angle_t)LONG(rsp->angle_pos);
players[i].old_angle_pos = (angle_t)LONG(rsp->old_angle_pos); players[i].old_angle_pos = (angle_t)LONG(rsp->old_angle_pos);
players[i].bumpertime = (tic_t)LONG(rsp->bumpertime); players[i].bumpertime = (tic_t)LONG(rsp->bumpertime);

View File

@ -166,6 +166,8 @@ typedef struct
INT32 skin; INT32 skin;
// Just in case Lua does something like // Just in case Lua does something like
// modify these at runtime // modify these at runtime
fixed_t camerascale;
fixed_t shieldscale;
fixed_t normalspeed; fixed_t normalspeed;
fixed_t runspeed; fixed_t runspeed;
UINT8 thrustfactor; UINT8 thrustfactor;
@ -181,6 +183,8 @@ typedef struct
fixed_t mindash; fixed_t mindash;
fixed_t maxdash; fixed_t maxdash;
fixed_t jumpfactor; fixed_t jumpfactor;
fixed_t playerheight;
fixed_t playerspinheight;
fixed_t speed; fixed_t speed;
UINT8 jumping; UINT8 jumping;
@ -191,6 +195,7 @@ typedef struct
INT32 deadtimer; INT32 deadtimer;
tic_t exiting; tic_t exiting;
UINT8 homing; UINT8 homing;
tic_t dashmode;
tic_t skidtime; tic_t skidtime;
fixed_t cmomx; fixed_t cmomx;
fixed_t cmomy; fixed_t cmomy;
@ -209,7 +214,6 @@ typedef struct
INT32 maxlink; INT32 maxlink;
fixed_t dashspeed; fixed_t dashspeed;
INT32 dashtime;
angle_t angle_pos; angle_t angle_pos;
angle_t old_angle_pos; angle_t old_angle_pos;
tic_t bumpertime; tic_t bumpertime;

View File

@ -1060,10 +1060,11 @@ void D_SRB2Main(void)
if (M_CheckParm("-warp") && M_IsNextParm()) if (M_CheckParm("-warp") && M_IsNextParm())
{ {
const char *word = M_GetNextParm(); const char *word = M_GetNextParm();
if (fastncmp(word, "MAP", 3)) char ch; // use this with sscanf to catch non-digits with
if (fastncmp(word, "MAP", 3)) // MAPxx name
pstartmap = M_MapNumber(word[3], word[4]); pstartmap = M_MapNumber(word[3], word[4]);
else else if (sscanf(word, "%d%c", &pstartmap, &ch) != 1) // a plain number
pstartmap = atoi(word); I_Error("Cannot warp to map %s (invalid map name)\n", word);
// Don't check if lump exists just yet because the wads haven't been loaded! // Don't check if lump exists just yet because the wads haven't been loaded!
// Just do a basic range check here. // Just do a basic range check here.
if (pstartmap < 1 || pstartmap > NUMMAPS) if (pstartmap < 1 || pstartmap > NUMMAPS)

View File

@ -41,7 +41,7 @@ void D_SRB2Main(void);
// Called by IO functions when input is detected. // Called by IO functions when input is detected.
void D_PostEvent(const event_t *ev); void D_PostEvent(const event_t *ev);
#ifndef DOXYGEN #ifndef DOXYGEN
void D_PostEvent_end(void); // delimiter for locking memory FUNCMATH void D_PostEvent_end(void); // delimiter for locking memory
#endif #endif
void D_ProcessEvents(void); void D_ProcessEvents(void);

View File

@ -332,7 +332,7 @@ consvar_t cv_usemapnumlaps = {"usemaplaps", "Yes", CV_NETVAR, CV_YesNo, NULL, 0,
// log elemental hazards -- not a netvar, is local to current player // log elemental hazards -- not a netvar, is local to current player
consvar_t cv_hazardlog = {"hazardlog", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_hazardlog = {"hazardlog", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_forceskin = {"forceskin", "-1", CV_NETVAR|CV_CALL|CV_CHEAT, NULL, ForceSkin_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_forceskin = {"forceskin", "None", CV_NETVAR|CV_CALL|CV_CHEAT, NULL, ForceSkin_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_downloading = {"downloading", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_downloading = {"downloading", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_allowexitlevel = {"allowexitlevel", "No", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_allowexitlevel = {"allowexitlevel", "No", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -1092,7 +1092,7 @@ static void SendNameAndColor(void)
SetPlayerSkinByNum(consoleplayer, 0); SetPlayerSkinByNum(consoleplayer, 0);
CV_StealthSet(&cv_skin, skins[0].name); CV_StealthSet(&cv_skin, skins[0].name);
} }
else if ((foundskin = R_SkinAvailable(cv_skin.string)) != -1) else if ((foundskin = R_SkinAvailable(cv_skin.string)) != -1 && R_SkinUnlock(foundskin))
{ {
boolean notsame; boolean notsame;
@ -1139,7 +1139,7 @@ static void SendNameAndColor(void)
// check if player has the skin loaded (cv_skin may have // check if player has the skin loaded (cv_skin may have
// the name of a skin that was available in the previous game) // the name of a skin that was available in the previous game)
cv_skin.value = R_SkinAvailable(cv_skin.string); cv_skin.value = R_SkinAvailable(cv_skin.string);
if (cv_skin.value < 0) if ((cv_skin.value < 0) || !R_SkinUnlock(cv_skin.value))
{ {
CV_StealthSet(&cv_skin, DEFAULTSKIN); CV_StealthSet(&cv_skin, DEFAULTSKIN);
cv_skin.value = 0; cv_skin.value = 0;
@ -1217,7 +1217,7 @@ static void SendNameAndColor2(void)
SetPlayerSkinByNum(secondplaya, forcedskin); SetPlayerSkinByNum(secondplaya, forcedskin);
CV_StealthSet(&cv_skin2, skins[forcedskin].name); CV_StealthSet(&cv_skin2, skins[forcedskin].name);
} }
else if ((foundskin = R_SkinAvailable(cv_skin2.string)) != -1) else if ((foundskin = R_SkinAvailable(cv_skin2.string)) != -1 && R_SkinUnlock(foundskin))
{ {
boolean notsame; boolean notsame;
@ -4002,17 +4002,10 @@ static void Command_Archivetest_f(void)
*/ */
static void ForceSkin_OnChange(void) static void ForceSkin_OnChange(void)
{ {
if ((server || adminplayer == consoleplayer) && (cv_forceskin.value < -1 || cv_forceskin.value >= numskins)) if ((server || adminplayer == consoleplayer) && ((cv_forceskin.value == -1 && stricmp(cv_forceskin.string, "None")) || !(R_SkinUnlock(cv_forceskin.value))))
{ {
if (cv_forceskin.value == -2) CONS_Printf("Please provide a valid skin name (\"None\" disables).\n");
CV_SetValue(&cv_forceskin, numskins-1); CV_SetValue(&cv_forceskin, -1);
else
{
// hack because I can't restrict this and still allow added skins to be used with forceskin.
if (!menuactive)
CONS_Printf(M_GetText("Valid skin numbers are 0 to %d (-1 disables)\n"), numskins - 1);
CV_SetValue(&cv_forceskin, -1);
}
return; return;
} }
@ -4024,7 +4017,7 @@ static void ForceSkin_OnChange(void)
CONS_Printf("The server has lifted the forced skin restrictions.\n"); CONS_Printf("The server has lifted the forced skin restrictions.\n");
else else
{ {
CONS_Printf("The server is restricting all players to skin \"%s\".\n",skins[cv_forceskin.value].name); CONS_Printf("The server is restricting all players to skin \"%s\".\n",skins[cv_forceskin.value].realname);
ForceAllSkins(cv_forceskin.value); ForceAllSkins(cv_forceskin.value);
} }
} }

View File

@ -39,6 +39,12 @@ typedef enum
SF_NOSKID = 1<<4, // No skid particles etc SF_NOSKID = 1<<4, // No skid particles etc
SF_NOSPEEDADJUST = 1<<5, // Skin-specific version of disablespeedadjust SF_NOSPEEDADJUST = 1<<5, // Skin-specific version of disablespeedadjust
SF_RUNONWATER = 1<<6, // Run on top of water FOFs? SF_RUNONWATER = 1<<6, // Run on top of water FOFs?
SF_NOJUMPSPIN = 1<<7, // SPR2_JUMP defaults to SPR2_SPRG instead of SPR2_SPIN, falling states used, and player height is full when jumping?
SF_NOJUMPDAMAGE = 1<<8, // Don't damage enemies, etc whilst jumping?
SF_STOMPDAMAGE = 1<<9, // Always damage enemies, etc by landing on them, no matter your vunerability?
SF_MARIODAMAGE = SF_NOJUMPDAMAGE|SF_STOMPDAMAGE, // The Mario method of being able to damage enemies, etc.
SF_MACHINE = 1<<10, // Beep boop. Are you a robot?
// free up to and including 1<<31
} skinflags_t; } skinflags_t;
//Primary and secondary skin abilities //Primary and secondary skin abilities
@ -57,7 +63,9 @@ typedef enum
CA_FALLSWITCH, CA_FALLSWITCH,
CA_JUMPBOOST, CA_JUMPBOOST,
CA_AIRDRILL, CA_AIRDRILL,
CA_JUMPTHOK CA_JUMPTHOK,
CA_DASHMODE,
CA_TWINSPIN
} charability_t; } charability_t;
//Secondary skin abilities //Secondary skin abilities
@ -65,7 +73,8 @@ typedef enum
{ {
CA2_NONE=0, CA2_NONE=0,
CA2_SPINDASH, CA2_SPINDASH,
CA2_MULTIABILITY CA2_MULTIABILITY,
CA2_MELEE
} charability2_t; } charability2_t;
// //
@ -120,39 +129,34 @@ typedef enum
// Are you gliding? // Are you gliding?
PF_GLIDING = 1<<16, PF_GLIDING = 1<<16,
// Tails pickup!
PF_CARRIED = 1<<17,
// Sliding (usually in water) like Labyrinth/Oil Ocean // Sliding (usually in water) like Labyrinth/Oil Ocean
PF_SLIDING = 1<<18, PF_SLIDING = 1<<17,
// Hanging on a rope
PF_ROPEHANG = 1<<19,
// Hanging on an item of some kind - zipline, chain, etc. (->tracer)
PF_ITEMHANG = 1<<20,
// On the mace chain spinning around (->tracer)
PF_MACESPIN = 1<<21,
/*** NIGHTS STUFF ***/ /*** NIGHTS STUFF ***/
// Is the player in NiGHTS mode? // Is the player in NiGHTS mode?
PF_NIGHTSMODE = 1<<22, PF_NIGHTSMODE = 1<<18,
PF_TRANSFERTOCLOSEST = 1<<23, PF_TRANSFERTOCLOSEST = 1<<19,
// Spill rings after falling // Spill rings after falling
PF_NIGHTSFALL = 1<<24, PF_NIGHTSFALL = 1<<20,
PF_DRILLING = 1<<25, PF_DRILLING = 1<<21,
PF_SKIDDOWN = 1<<26, PF_SKIDDOWN = 1<<22,
/*** TAG STUFF ***/ /*** TAG STUFF ***/
PF_TAGGED = 1<<27, // Player has been tagged and awaits the next round in hide and seek. PF_TAGGED = 1<<23, // Player has been tagged and awaits the next round in hide and seek.
PF_TAGIT = 1<<28, // The player is it! For Tag Mode PF_TAGIT = 1<<24, // The player is it! For Tag Mode
/*** misc ***/ /*** misc ***/
PF_FORCESTRAFE = 1<<29, // Turning inputs are translated into strafing inputs PF_FORCESTRAFE = 1<<25, // Turning inputs are translated into strafing inputs
PF_ANALOGMODE = 1<<30, // Analog mode? PF_ANALOGMODE = 1<<26, // Analog mode?
PF_SHIELDABILITY = 1<<31 // Thokked with shield ability
// Can carry another player?
PF_CANCARRY = 1<<27,
// Used shield ability
PF_SHIELDABILITY = 1<<28
// free up to and including 1<<31
} pflags_t; } pflags_t;
typedef enum typedef enum
@ -163,11 +167,14 @@ typedef enum
PA_EDGE, PA_EDGE,
PA_WALK, PA_WALK,
PA_RUN, PA_RUN,
PA_PEEL,
PA_PAIN, PA_PAIN,
PA_ROLL, PA_ROLL,
PA_JUMP,
PA_SPRING, PA_SPRING,
PA_FALL, PA_FALL,
PA_ABILITY, PA_ABILITY,
PA_ABILITY2,
PA_RIDE PA_RIDE
} panim_t; } panim_t;
@ -192,7 +199,20 @@ typedef enum
SH_STACK = SH_FIREFLOWER, SH_STACK = SH_FIREFLOWER,
SH_NOSTACK = ~SH_STACK SH_NOSTACK = ~SH_STACK
} shieldtype_t; } shieldtype_t; // pw_shield
typedef enum
{
CR_NONE = 0,
// The generic case is suitable for most objects.
CR_GENERIC,
// Tails carry.
CR_PLAYER,
// Specific level gimmicks.
CR_ZOOMTUBE,
CR_ROPEHANG,
CR_MACESPIN
} carrytype_t; // pw_carry
// Player powers. (don't edit this comment) // Player powers. (don't edit this comment)
typedef enum typedef enum
@ -201,6 +221,7 @@ typedef enum
pw_sneakers, pw_sneakers,
pw_flashing, pw_flashing,
pw_shield, pw_shield,
pw_carry,
pw_tailsfly, // tails flying pw_tailsfly, // tails flying
pw_underwater, // underwater timer pw_underwater, // underwater timer
pw_spacetime, // In space, no one can hear you spin! pw_spacetime, // In space, no one can hear you spin!
@ -264,6 +285,8 @@ typedef struct player_s
playerstate_t playerstate; playerstate_t playerstate;
// Determine POV, including viewpoint bobbing during movement. // Determine POV, including viewpoint bobbing during movement.
fixed_t camerascale;
fixed_t shieldscale;
// Focal origin above r.z // Focal origin above r.z
fixed_t viewz; fixed_t viewz;
// Base height above floor for viewz. // Base height above floor for viewz.
@ -307,7 +330,6 @@ typedef struct player_s
UINT32 score; // player score UINT32 score; // player score
fixed_t dashspeed; // dashing speed fixed_t dashspeed; // dashing speed
INT32 dashtime; // tics dashing, used for rev sound
fixed_t normalspeed; // Normal ground fixed_t normalspeed; // Normal ground
fixed_t runspeed; // Speed you break into the run animation fixed_t runspeed; // Speed you break into the run animation
@ -332,6 +354,9 @@ typedef struct player_s
fixed_t jumpfactor; // How high can the player jump? fixed_t jumpfactor; // How high can the player jump?
fixed_t height; // Bounding box changes.
fixed_t spinheight;
SINT8 lives; SINT8 lives;
SINT8 continues; // continues that player has acquired SINT8 continues; // continues that player has acquired
@ -350,6 +375,7 @@ typedef struct player_s
tic_t exiting; // Exitlevel timer tic_t exiting; // Exitlevel timer
UINT8 homing; // Are you homing? UINT8 homing; // Are you homing?
tic_t dashmode; // counter for dashmode ability
tic_t skidtime; // Skid timer tic_t skidtime; // Skid timer

View File

@ -430,16 +430,20 @@ static void readAnimTex(MYFILE *f, INT32 num)
} }
*/ */
static boolean findFreeSlot(INT32 *num) static boolean findFreeSlot(INT32 *num, UINT16 wadnum)
{ {
// Send the character select entry to a free slot. // Send the character select entry to a free slot.
while (*num < 32 && PlayerMenu[*num].status != IT_DISABLED) while (*num < 32 && (!(PlayerMenu[*num].status & IT_DISABLED) || description[*num].wadnum == wadnum)) // Will kill hidden characters from other files, but that's okay.
*num = *num+1; *num = *num+1;
// No more free slots. :( // No more free slots. :(
if (*num >= 32) if (*num >= 32)
return false; return false;
PlayerMenu[*num].status = IT_CALL;
description[*num].wadnum = wadnum;
description[*num].picname[0] = '\0'; // Redesign your logo. (See M_DrawSetupChoosePlayerMenu in m_menu.c...)
// Found one! ^_^ // Found one! ^_^
return true; return true;
} }
@ -473,9 +477,8 @@ static void readPlayer(MYFILE *f, INT32 num)
{ {
char *playertext = NULL; char *playertext = NULL;
if (!slotfound && (slotfound = findFreeSlot(&num)) == false) if (!slotfound && (slotfound = findFreeSlot(&num, f->wad)) == false)
goto done; goto done;
PlayerMenu[num].status = IT_CALL;
for (i = 0; i < MAXLINELEN-3; i++) for (i = 0; i < MAXLINELEN-3; i++)
{ {
@ -521,34 +524,12 @@ static void readPlayer(MYFILE *f, INT32 num)
word2[strlen(word2)-1] = '\0'; word2[strlen(word2)-1] = '\0';
i = atoi(word2); i = atoi(word2);
/*if (fastcmp(word, "PLAYERNAME")) if (fastcmp(word, "PICNAME"))
{ {
if (!slotfound && (slotfound = findFreeSlot(&num)) == false) if (!slotfound && (slotfound = findFreeSlot(&num, f->wad)) == false)
goto done;
DEH_WriteUndoline(word, description[num].text, UNDO_NONE);
strlcpy(description[num].text, word2, sizeof (description[num].text));
for (word2 = description[num].text; *word2; word2++)
if (*word2 == '_')
*word2 = ' ';
PlayerMenu[num].text = description[num].text;
}*/
/* else if (fastcmp(word, "MENUPOSITION"))
{ // Make sure you make MENUPOSITION the first thing under CHARACTER if you're using it!
// This is to manually choose a slot and overwrite existing characters! It is NOT necessary for most individual character wads!!
#ifdef DELFILE
if (disableundo)
#endif
{
slotfound = true;
num = i;
}
} */
/*else*/ if (fastcmp(word, "PICNAME"))
{
if (!slotfound && (slotfound = findFreeSlot(&num)) == false)
goto done; goto done;
DEH_WriteUndoline(word, &description[num].picname[0], UNDO_NONE); DEH_WriteUndoline(word, &description[num].picname[0], UNDO_NONE);
PlayerMenu[num].status = IT_CALL;
strncpy(description[num].picname, word2, 8); strncpy(description[num].picname, word2, 8);
} }
else if (fastcmp(word, "STATUS")) else if (fastcmp(word, "STATUS"))
@ -563,13 +544,10 @@ static void readPlayer(MYFILE *f, INT32 num)
You MAY disable previous entries if you so desire... You MAY disable previous entries if you so desire...
But try to enable something that's already enabled and you will be sent to a free slot. But try to enable something that's already enabled and you will be sent to a free slot.
Because of this, you are allowed to edit any previous entrys you like, but only if you Because of this, you are allowed to edit any previous entries you like, but only if you
signal that you are purposely doing so by disabling and then reenabling the slot. signal that you are purposely doing so by disabling and then reenabling the slot.
... Or use MENUPOSITION first, that works too. Hell, you could edit multiple character
slots in a single section that way, due to how SOC editing works.
*/ */
if (i != IT_DISABLED && !slotfound && (slotfound = findFreeSlot(&num)) == false) if (i != IT_DISABLED && !slotfound && (slotfound = findFreeSlot(&num, f->wad)) == false)
goto done; goto done;
DEH_WriteUndoline(word, va("%d", PlayerMenu[num].status), UNDO_NONE); DEH_WriteUndoline(word, va("%d", PlayerMenu[num].status), UNDO_NONE);
PlayerMenu[num].status = (INT16)i; PlayerMenu[num].status = (INT16)i;
@ -577,10 +555,9 @@ static void readPlayer(MYFILE *f, INT32 num)
else if (fastcmp(word, "SKINNAME")) else if (fastcmp(word, "SKINNAME"))
{ {
// Send to free slot. // Send to free slot.
if (!slotfound && (slotfound = findFreeSlot(&num)) == false) if (!slotfound && (slotfound = findFreeSlot(&num, f->wad)) == false)
goto done; goto done;
DEH_WriteUndoline(word, description[num].skinname, UNDO_NONE); DEH_WriteUndoline(word, description[num].skinname, UNDO_NONE);
PlayerMenu[num].status = IT_CALL;
strlcpy(description[num].skinname, word2, sizeof description[num].skinname); strlcpy(description[num].skinname, word2, sizeof description[num].skinname);
strlwr(description[num].skinname); strlwr(description[num].skinname);
@ -673,6 +650,22 @@ static void readfreeslots(MYFILE *f)
break; break;
} }
} }
else if (fastcmp(type, "SPR2"))
{
// Search if we already have an SPR2 by that name...
for (i = SPR2_FIRSTFREESLOT; i < (int)free_spr2; i++)
if (memcmp(spr2names[i],word,4) == 0)
break;
// We found it? (Two mods using the same SPR2 name?) Then don't allocate another one.
if (i < (int)free_spr2)
continue;
// Copy in the spr2 name and increment free_spr2.
if (free_spr2 < NUMPLAYERSPRITES) {
strncpy(spr2names[free_spr2],word,4);
spr2names[free_spr2++][4] = 0;
} else
CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n");
}
else else
deh_warning("Freeslots: unknown enum class '%s' for '%s_%s'", type, type, word); deh_warning("Freeslots: unknown enum class '%s' for '%s_%s'", type, type, word);
} }
@ -3794,6 +3787,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_PLAY_WAIT", "S_PLAY_WAIT",
"S_PLAY_WALK", "S_PLAY_WALK",
"S_PLAY_RUN", "S_PLAY_RUN",
"S_PLAY_PEEL",
"S_PLAY_PAIN", "S_PLAY_PAIN",
"S_PLAY_DEAD", "S_PLAY_DEAD",
"S_PLAY_DRWN", "S_PLAY_DRWN",
@ -3806,8 +3800,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_PLAY_EDGE", "S_PLAY_EDGE",
"S_PLAY_RIDE", "S_PLAY_RIDE",
// CA_FLY // CA_FLY/SWIM
"S_PLAY_FLY", "S_PLAY_FLY",
"S_PLAY_SWIM",
"S_PLAY_FLY_TIRED", "S_PLAY_FLY_TIRED",
// CA_GLIDEANDCLIMB // CA_GLIDEANDCLIMB
@ -3815,10 +3810,18 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_PLAY_CLING", "S_PLAY_CLING",
"S_PLAY_CLIMB", "S_PLAY_CLIMB",
// CA_TWINSPIN
"S_PLAY_TWINSPIN",
// CA2_MELEE
"S_PLAY_MELEE",
"S_PLAY_MELEE_FINISH",
// SF_SUPERANIMS // SF_SUPERANIMS
"S_PLAY_SUPER_STND", "S_PLAY_SUPER_STND",
"S_PLAY_SUPER_WALK", "S_PLAY_SUPER_WALK",
"S_PLAY_SUPER_RUN", "S_PLAY_SUPER_RUN",
"S_PLAY_SUPER_PEEL",
"S_PLAY_SUPER_PAIN", "S_PLAY_SUPER_PAIN",
"S_PLAY_SUPER_STUN", "S_PLAY_SUPER_STUN",
"S_PLAY_SUPER_DEAD", "S_PLAY_SUPER_DEAD",
@ -3856,6 +3859,50 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// Level end sign (uses player sprite) // Level end sign (uses player sprite)
"S_PLAY_SIGN", "S_PLAY_SIGN",
// NiGHTS character (uses player sprite)
"S_PLAY_NIGHTS_TRANS",
"S_PLAY_NIGHTS_TRANS2",
"S_PLAY_NIGHTS_TRANS3",
"S_PLAY_NIGHTS_TRANS4",
"S_PLAY_NIGHTS_TRANS5",
"S_PLAY_NIGHTS_TRANS6",
"S_PLAY_NIGHTS_TRANS7",
"S_PLAY_NIGHTS_TRANS8",
"S_PLAY_NIGHTS_TRANS9",
"S_PLAY_NIGHTS_STAND",
"S_PLAY_NIGHTS_FLOAT",
"S_PLAY_NIGHTS_PAIN",
"S_PLAY_NIGHTS_PULL",
"S_PLAY_NIGHTS_ATTACK",
"S_PLAY_NIGHTS_FLY0",
"S_PLAY_NIGHTS_DRILL0",
"S_PLAY_NIGHTS_FLY1",
"S_PLAY_NIGHTS_DRILL1",
"S_PLAY_NIGHTS_FLY2",
"S_PLAY_NIGHTS_DRILL2",
"S_PLAY_NIGHTS_FLY3",
"S_PLAY_NIGHTS_DRILL3",
"S_PLAY_NIGHTS_FLY4",
"S_PLAY_NIGHTS_DRILL4",
"S_PLAY_NIGHTS_FLY5",
"S_PLAY_NIGHTS_DRILL5",
"S_PLAY_NIGHTS_FLY6",
"S_PLAY_NIGHTS_DRILL6",
"S_PLAY_NIGHTS_FLY7",
"S_PLAY_NIGHTS_DRILL7",
"S_PLAY_NIGHTS_FLY8",
"S_PLAY_NIGHTS_DRILL8",
"S_PLAY_NIGHTS_FLY9",
"S_PLAY_NIGHTS_DRILL9",
"S_PLAY_NIGHTS_FLYA",
"S_PLAY_NIGHTS_DRILLA",
"S_PLAY_NIGHTS_FLYB",
"S_PLAY_NIGHTS_DRILLB",
"S_PLAY_NIGHTS_FLYC",
"S_PLAY_NIGHTS_DRILLC",
// Blue Crawla // Blue Crawla
"S_POSS_STND", "S_POSS_STND",
"S_POSS_RUN1", "S_POSS_RUN1",
@ -4706,6 +4753,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// Bubble Source // Bubble Source
"S_BUBBLES1", "S_BUBBLES1",
"S_BUBBLES2", "S_BUBBLES2",
"S_BUBBLES3",
"S_BUBBLES4",
// Level End Sign // Level End Sign
"S_SIGN1", "S_SIGN1",
@ -5500,6 +5549,36 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_RDIAG7", "S_RDIAG7",
"S_RDIAG8", "S_RDIAG8",
// Yellow Side Spring
"S_YHORIZ1",
"S_YHORIZ2",
"S_YHORIZ3",
"S_YHORIZ4",
"S_YHORIZ5",
"S_YHORIZ6",
"S_YHORIZ7",
"S_YHORIZ8",
// Red Side Spring
"S_RHORIZ1",
"S_RHORIZ2",
"S_RHORIZ3",
"S_RHORIZ4",
"S_RHORIZ5",
"S_RHORIZ6",
"S_RHORIZ7",
"S_RHORIZ8",
// Blue Side Spring
"S_BHORIZ1",
"S_BHORIZ2",
"S_BHORIZ3",
"S_BHORIZ4",
"S_BHORIZ5",
"S_BHORIZ6",
"S_BHORIZ7",
"S_BHORIZ8",
// Rain // Rain
"S_RAIN1", "S_RAIN1",
"S_RAINRETURN", "S_RAINRETURN",
@ -5534,14 +5613,15 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
// Bubbles // Bubbles
"S_SMALLBUBBLE", "S_SMALLBUBBLE",
"S_SMALLBUBBLE1",
"S_MEDIUMBUBBLE", "S_MEDIUMBUBBLE",
"S_MEDIUMBUBBLE1", "S_LARGEBUBBLE1",
"S_LARGEBUBBLE", "S_LARGEBUBBLE2",
"S_EXTRALARGEBUBBLE", // breathable "S_EXTRALARGEBUBBLE", // breathable
"S_POP1", // Extra Large bubble goes POP! "S_POP1", // Extra Large bubble goes POP!
"S_WATERZAP",
"S_FOG1", "S_FOG1",
"S_FOG2", "S_FOG2",
"S_FOG3", "S_FOG3",
@ -5583,6 +5663,13 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_FOUR1", "S_FOUR1",
"S_FIVE1", "S_FIVE1",
"S_ZERO2",
"S_ONE2",
"S_TWO2",
"S_THREE2",
"S_FOUR2",
"S_FIVE2",
// Tag Sign // Tag Sign
"S_TTAG1", "S_TTAG1",
@ -5815,93 +5902,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_NIGHTSGOAL3", "S_NIGHTSGOAL3",
"S_NIGHTSGOAL4", "S_NIGHTSGOAL4",
"S_NIGHTSFLY1A",
"S_NIGHTSFLY1B",
"S_NIGHTSDRILL1A",
"S_NIGHTSDRILL1B",
"S_NIGHTSDRILL1C",
"S_NIGHTSDRILL1D",
"S_NIGHTSFLY2A",
"S_NIGHTSFLY2B",
"S_NIGHTSDRILL2A",
"S_NIGHTSDRILL2B",
"S_NIGHTSDRILL2C",
"S_NIGHTSDRILL2D",
"S_NIGHTSFLY3A",
"S_NIGHTSFLY3B",
"S_NIGHTSDRILL3A",
"S_NIGHTSDRILL3B",
"S_NIGHTSDRILL3C",
"S_NIGHTSDRILL3D",
"S_NIGHTSFLY4A",
"S_NIGHTSFLY4B",
"S_NIGHTSDRILL4A",
"S_NIGHTSDRILL4B",
"S_NIGHTSDRILL4C",
"S_NIGHTSDRILL4D",
"S_NIGHTSFLY5A",
"S_NIGHTSFLY5B",
"S_NIGHTSDRILL5A",
"S_NIGHTSDRILL5B",
"S_NIGHTSDRILL5C",
"S_NIGHTSDRILL5D",
"S_NIGHTSFLY6A",
"S_NIGHTSFLY6B",
"S_NIGHTSDRILL6A",
"S_NIGHTSDRILL6B",
"S_NIGHTSDRILL6C",
"S_NIGHTSDRILL6D",
"S_NIGHTSFLY7A",
"S_NIGHTSFLY7B",
"S_NIGHTSDRILL7A",
"S_NIGHTSDRILL7B",
"S_NIGHTSDRILL7C",
"S_NIGHTSDRILL7D",
"S_NIGHTSFLY8A",
"S_NIGHTSFLY8B",
"S_NIGHTSDRILL8A",
"S_NIGHTSDRILL8B",
"S_NIGHTSDRILL8C",
"S_NIGHTSDRILL8D",
"S_NIGHTSFLY9A",
"S_NIGHTSFLY9B",
"S_NIGHTSDRILL9A",
"S_NIGHTSDRILL9B",
"S_NIGHTSDRILL9C",
"S_NIGHTSDRILL9D",
"S_NIGHTSHURT1",
"S_NIGHTSHURT2",
"S_NIGHTSHURT3",
"S_NIGHTSHURT4",
"S_NIGHTSHURT5",
"S_NIGHTSHURT6",
"S_NIGHTSHURT7",
"S_NIGHTSHURT8",
"S_NIGHTSHURT9",
"S_NIGHTSHURT10",
"S_NIGHTSHURT11",
"S_NIGHTSHURT12",
"S_NIGHTSHURT13",
"S_NIGHTSHURT14",
"S_NIGHTSHURT15",
"S_NIGHTSHURT16",
"S_NIGHTSHURT17",
"S_NIGHTSHURT18",
"S_NIGHTSHURT19",
"S_NIGHTSHURT20",
"S_NIGHTSHURT21",
"S_NIGHTSHURT22",
"S_NIGHTSHURT23",
"S_NIGHTSHURT24",
"S_NIGHTSHURT25",
"S_NIGHTSHURT26",
"S_NIGHTSHURT27",
"S_NIGHTSHURT28",
"S_NIGHTSHURT29",
"S_NIGHTSHURT30",
"S_NIGHTSHURT31",
"S_NIGHTSHURT32",
"S_NIGHTSPARKLE1", "S_NIGHTSPARKLE1",
"S_NIGHTSPARKLE2", "S_NIGHTSPARKLE2",
"S_NIGHTSPARKLE3", "S_NIGHTSPARKLE3",
@ -5998,16 +5998,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_CRUMBLE1", "S_CRUMBLE1",
"S_CRUMBLE2", "S_CRUMBLE2",
"S_SUPERTRANS1",
"S_SUPERTRANS2",
"S_SUPERTRANS3",
"S_SUPERTRANS4",
"S_SUPERTRANS5",
"S_SUPERTRANS6",
"S_SUPERTRANS7",
"S_SUPERTRANS8",
"S_SUPERTRANS9",
// Spark // Spark
"S_SPRK1", "S_SPRK1",
"S_SPRK2", "S_SPRK2",
@ -6257,6 +6247,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_REDSPRING", "MT_REDSPRING",
"MT_YELLOWDIAG", // Yellow Diagonal Spring "MT_YELLOWDIAG", // Yellow Diagonal Spring
"MT_REDDIAG", // Red Diagonal Spring "MT_REDDIAG", // Red Diagonal Spring
"MT_YELLOWHORIZ", // Yellow Side Spring
"MT_REDHORIZ", // Red Side Spring
"MT_BLUEHORIZ", // Blue Side Spring
// Interactive Objects // Interactive Objects
"MT_BUBBLES", // Bubble source "MT_BUBBLES", // Bubble source
@ -6488,6 +6481,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_SMALLBUBBLE", // small bubble "MT_SMALLBUBBLE", // small bubble
"MT_MEDIUMBUBBLE", // medium bubble "MT_MEDIUMBUBBLE", // medium bubble
"MT_EXTRALARGEBUBBLE", // extra large bubble "MT_EXTRALARGEBUBBLE", // extra large bubble
"MT_WATERZAP",
"MT_TFOG", "MT_TFOG",
"MT_SEED", "MT_SEED",
"MT_PARTICLE", "MT_PARTICLE",
@ -6560,7 +6554,6 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_AXISTRANSFERLINE", "MT_AXISTRANSFERLINE",
"MT_NIGHTSDRONE", "MT_NIGHTSDRONE",
"MT_NIGHTSGOAL", "MT_NIGHTSGOAL",
"MT_NIGHTSCHAR",
"MT_NIGHTSPARKLE", "MT_NIGHTSPARKLE",
"MT_NIGHTSLOOPHELPER", "MT_NIGHTSLOOPHELPER",
"MT_NIGHTSBUMPER", // NiGHTS Bumper "MT_NIGHTSBUMPER", // NiGHTS Bumper
@ -6717,12 +6710,14 @@ static const char *const MOBJEFLAG_LIST[] = {
NULL NULL
}; };
#ifdef HAVE_BLUA
static const char *const MAPTHINGFLAG_LIST[4] = { static const char *const MAPTHINGFLAG_LIST[4] = {
NULL, NULL,
"OBJECTFLIP", // Reverse gravity flag for objects. "OBJECTFLIP", // Reverse gravity flag for objects.
"OBJECTSPECIAL", // Special flag used with certain objects. "OBJECTSPECIAL", // Special flag used with certain objects.
"AMBUSH" // Deaf monsters/do not react to sound. "AMBUSH" // Deaf monsters/do not react to sound.
}; };
#endif
static const char *const PLAYERFLAG_LIST[] = { static const char *const PLAYERFLAG_LIST[] = {
// Flip camera angle with gravity flip prefrence. // Flip camera angle with gravity flip prefrence.
@ -6759,21 +6754,9 @@ static const char *const PLAYERFLAG_LIST[] = {
// Are you gliding? // Are you gliding?
"GLIDING", "GLIDING",
// Tails pickup!
"CARRIED",
// Sliding (usually in water) like Labyrinth/Oil Ocean // Sliding (usually in water) like Labyrinth/Oil Ocean
"SLIDING", "SLIDING",
// Hanging on a rope
"ROPEHANG",
// Hanging on an item of some kind - zipline, chain, etc. (->tracer)
"ITEMHANG",
// On the mace chain spinning around (->tracer)
"MACESPIN",
/*** NIGHTS STUFF ***/ /*** NIGHTS STUFF ***/
// Is the player in NiGHTS mode? // Is the player in NiGHTS mode?
"NIGHTSMODE", "NIGHTSMODE",
@ -6796,6 +6779,7 @@ static const char *const PLAYERFLAG_LIST[] = {
NULL // stop loop here. NULL // stop loop here.
}; };
#ifdef HAVE_BLUA
// Linedef flags // Linedef flags
static const char *const ML_LIST[16] = { static const char *const ML_LIST[16] = {
"IMPASSIBLE", "IMPASSIBLE",
@ -6815,6 +6799,7 @@ static const char *const ML_LIST[16] = {
"BOUNCY", "BOUNCY",
"TFERLINE" "TFERLINE"
}; };
#endif
// This DOES differ from r_draw's Color_Names, unfortunately. // This DOES differ from r_draw's Color_Names, unfortunately.
// Also includes Super colors // Also includes Super colors
@ -6849,24 +6834,61 @@ static const char *COLOR_ENUMS[] = {
"MAGENTA", // SKINCOLOR_MAGENTA "MAGENTA", // SKINCOLOR_MAGENTA
"PINK", // SKINCOLOR_PINK "PINK", // SKINCOLOR_PINK
"ROSY", // SKINCOLOR_ROSY "ROSY", // SKINCOLOR_ROSY
// Super special awesome Super flashing colors! // Super special awesome Super flashing colors!
"SUPER1", // SKINCOLOR_SUPER1 "SUPERSILVER1", // SKINCOLOR_SUPERSILVER1
"SUPER2", // SKINCOLOR_SUPER2, "SUPERSILVER2", // SKINCOLOR_SUPERSILVER2,
"SUPER3", // SKINCOLOR_SUPER3, "SUPERSILVER3", // SKINCOLOR_SUPERSILVER3,
"SUPER4", // SKINCOLOR_SUPER4, "SUPERSILVER4", // SKINCOLOR_SUPERSILVER4,
"SUPER5", // SKINCOLOR_SUPER5, "SUPERSILVER5", // SKINCOLOR_SUPERSILVER5,
// Super Tails
"TSUPER1", // SKINCOLOR_TSUPER1, "SUPERRED1", // SKINCOLOR_SUPERRED1
"TSUPER2", // SKINCOLOR_TSUPER2, "SUPERRED2", // SKINCOLOR_SUPERRED2,
"TSUPER3", // SKINCOLOR_TSUPER3, "SUPERRED3", // SKINCOLOR_SUPERRED3,
"TSUPER4", // SKINCOLOR_TSUPER4, "SUPERRED4", // SKINCOLOR_SUPERRED4,
"TSUPER5", // SKINCOLOR_TSUPER5, "SUPERRED5", // SKINCOLOR_SUPERRED5,
// Super Knuckles
"KSUPER1", // SKINCOLOR_KSUPER1, "SUPERORANGE1", // SKINCOLOR_SUPERORANGE1
"KSUPER2", // SKINCOLOR_KSUPER2, "SUPERORANGE2", // SKINCOLOR_SUPERORANGE2,
"KSUPER3", // SKINCOLOR_KSUPER3, "SUPERORANGE3", // SKINCOLOR_SUPERORANGE3,
"KSUPER4", // SKINCOLOR_KSUPER4, "SUPERORANGE4", // SKINCOLOR_SUPERORANGE4,
"KSUPER5" // SKINCOLOR_KSUPER5, "SUPERORANGE5", // SKINCOLOR_SUPERORANGE5,
"SUPERGOLD1", // SKINCOLOR_SUPERGOLD1
"SUPERGOLD2", // SKINCOLOR_SUPERGOLD2,
"SUPERGOLD3", // SKINCOLOR_SUPERGOLD3,
"SUPERGOLD4", // SKINCOLOR_SUPERGOLD4,
"SUPERGOLD5", // SKINCOLOR_SUPERGOLD5,
"SUPERPERIDOT1", // SKINCOLOR_SUPERPERIDOT1
"SUPERPERIDOT2", // SKINCOLOR_SUPERPERIDOT2,
"SUPERPERIDOT3", // SKINCOLOR_SUPERPERIDOT3,
"SUPERPERIDOT4", // SKINCOLOR_SUPERPERIDOT4,
"SUPERPERIDOT5", // SKINCOLOR_SUPERPERIDOT5,
"SUPERCYAN1", // SKINCOLOR_SUPERCYAN1
"SUPERCYAN2", // SKINCOLOR_SUPERCYAN2,
"SUPERCYAN3", // SKINCOLOR_SUPERCYAN3,
"SUPERCYAN4", // SKINCOLOR_SUPERCYAN4,
"SUPERCYAN5", // SKINCOLOR_SUPERCYAN5,
"SUPERPURPLE1", // SKINCOLOR_SUPERPURPLE1,
"SUPERPURPLE2", // SKINCOLOR_SUPERPURPLE2,
"SUPERPURPLE3", // SKINCOLOR_SUPERPURPLE3,
"SUPERPURPLE4", // SKINCOLOR_SUPERPURPLE4,
"SUPERPURPLE5", // SKINCOLOR_SUPERPURPLE5,
"SUPERRUST1", // SKINCOLOR_SUPERRUST1
"SUPERRUST2", // SKINCOLOR_SUPERRUST2,
"SUPERRUST3", // SKINCOLOR_SUPERRUST3,
"SUPERRUST4", // SKINCOLOR_SUPERRUST4,
"SUPERRUST5", // SKINCOLOR_SUPERRUST5,
"SUPERTAN1", // SKINCOLOR_SUPERTAN1
"SUPERTAN2", // SKINCOLOR_SUPERTAN2,
"SUPERTAN3", // SKINCOLOR_SUPERTAN3,
"SUPERTAN4", // SKINCOLOR_SUPERTAN4,
"SUPERTAN5" // SKINCOLOR_SUPERTAN5,
}; };
static const char *const POWERS_LIST[] = { static const char *const POWERS_LIST[] = {
@ -6874,6 +6896,7 @@ static const char *const POWERS_LIST[] = {
"SNEAKERS", "SNEAKERS",
"FLASHING", "FLASHING",
"SHIELD", "SHIELD",
"CARRY",
"TAILSFLY", // tails flying "TAILSFLY", // tails flying
"UNDERWATER", // underwater timer "UNDERWATER", // underwater timer
"SPACETIME", // In space, no one can hear you spin! "SPACETIME", // In space, no one can hear you spin!
@ -6993,6 +7016,8 @@ struct {
// Frame settings // Frame settings
{"FF_FRAMEMASK",FF_FRAMEMASK}, {"FF_FRAMEMASK",FF_FRAMEMASK},
{"FF_SPR2ENDSTATE",FF_SPR2ENDSTATE},
{"FF_MIDDLESTARTCHANCE",FF_MIDDLESTARTCHANCE},
{"FF_ANIMATE",FF_ANIMATE}, {"FF_ANIMATE",FF_ANIMATE},
{"FF_FULLBRIGHT",FF_FULLBRIGHT}, {"FF_FULLBRIGHT",FF_FULLBRIGHT},
{"FF_TRANSMASK",FF_TRANSMASK}, {"FF_TRANSMASK",FF_TRANSMASK},
@ -7107,6 +7132,14 @@ struct {
{"SH_STACK",SH_STACK}, {"SH_STACK",SH_STACK},
{"SH_NOSTACK",SH_NOSTACK}, {"SH_NOSTACK",SH_NOSTACK},
// Carrying
{"CR_NONE",CR_NONE},
{"CR_GENERIC",CR_GENERIC},
{"CR_PLAYER",CR_PLAYER},
{"CR_ZOOMTUBE",CR_ZOOMTUBE},
{"CR_ROPEHANG",CR_ROPEHANG},
{"CR_MACESPIN",CR_MACESPIN},
// Ring weapons (ringweapons_t) // Ring weapons (ringweapons_t)
// Useful for A_GiveWeapon // Useful for A_GiveWeapon
{"RW_AUTO",RW_AUTO}, {"RW_AUTO",RW_AUTO},
@ -7124,6 +7157,11 @@ struct {
{"SF_NOSKID",SF_NOSKID}, {"SF_NOSKID",SF_NOSKID},
{"SF_NOSPEEDADJUST",SF_NOSPEEDADJUST}, {"SF_NOSPEEDADJUST",SF_NOSPEEDADJUST},
{"SF_RUNONWATER",SF_RUNONWATER}, {"SF_RUNONWATER",SF_RUNONWATER},
{"SF_NOJUMPSPIN",SF_NOJUMPSPIN},
{"SF_NOJUMPDAMAGE",SF_NOJUMPDAMAGE},
{"SF_STOMPDAMAGE",SF_STOMPDAMAGE},
{"SF_MARIODAMAGE",SF_MARIODAMAGE},
{"SF_MACHINE",SF_MACHINE},
// Character abilities! // Character abilities!
// Primary // Primary
@ -7141,10 +7179,13 @@ struct {
{"CA_JUMPBOOST",CA_JUMPBOOST}, {"CA_JUMPBOOST",CA_JUMPBOOST},
{"CA_AIRDRILL",CA_AIRDRILL}, {"CA_AIRDRILL",CA_AIRDRILL},
{"CA_JUMPTHOK",CA_JUMPTHOK}, {"CA_JUMPTHOK",CA_JUMPTHOK},
{"CA_DASHMODE",CA_DASHMODE},
{"CA_TWINSPIN",CA_TWINSPIN},
// Secondary // Secondary
{"CA2_NONE",CA2_NONE}, // now slot 0! {"CA2_NONE",CA2_NONE}, // now slot 0!
{"CA2_SPINDASH",CA2_SPINDASH}, {"CA2_SPINDASH",CA2_SPINDASH},
{"CA2_MULTIABILITY",CA2_MULTIABILITY}, {"CA2_MULTIABILITY",CA2_MULTIABILITY},
{"CA2_MELEE",CA2_MELEE},
// Sound flags // Sound flags
{"SF_TOTALLYSINGLE",SF_TOTALLYSINGLE}, {"SF_TOTALLYSINGLE",SF_TOTALLYSINGLE},
@ -7191,11 +7232,14 @@ struct {
{"PA_EDGE",PA_EDGE}, {"PA_EDGE",PA_EDGE},
{"PA_WALK",PA_WALK}, {"PA_WALK",PA_WALK},
{"PA_RUN",PA_RUN}, {"PA_RUN",PA_RUN},
{"PA_PEEL",PA_PEEL},
{"PA_PAIN",PA_PAIN}, {"PA_PAIN",PA_PAIN},
{"PA_ROLL",PA_ROLL}, {"PA_ROLL",PA_ROLL},
{"PA_JUMP",PA_JUMP},
{"PA_SPRING",PA_SPRING}, {"PA_SPRING",PA_SPRING},
{"PA_FALL",PA_FALL}, {"PA_FALL",PA_FALL},
{"PA_ABILITY",PA_ABILITY}, {"PA_ABILITY",PA_ABILITY},
{"PA_ABILITY2",PA_ABILITY2},
{"PA_RIDE",PA_RIDE}, {"PA_RIDE",PA_RIDE},
// Current weapon // Current weapon
@ -7771,7 +7815,7 @@ fixed_t get_number(const char *word)
#endif #endif
} }
void DEH_Check(void) void FUNCMATH DEH_Check(void)
{ {
#if defined(_DEBUG) || defined(PARANOIA) #if defined(_DEBUG) || defined(PARANOIA)
const size_t dehstates = sizeof(STATE_LIST)/sizeof(const char*); const size_t dehstates = sizeof(STATE_LIST)/sizeof(const char*);
@ -7836,7 +7880,7 @@ static inline int lib_freeslot(lua_State *L)
lua_pushinteger(L, sfx); lua_pushinteger(L, sfx);
r++; r++;
} else } else
return r; CONS_Alert(CONS_WARNING, "Ran out of free SFX slots!\n");
} }
else if (fastcmp(type, "SPR")) else if (fastcmp(type, "SPR"))
{ {
@ -7863,7 +7907,7 @@ static inline int lib_freeslot(lua_State *L)
break; break;
} }
if (j > SPR_LASTFREESLOT) if (j > SPR_LASTFREESLOT)
return r; CONS_Alert(CONS_WARNING, "Ran out of free sprite slots!\n");
} }
else if (fastcmp(type, "S")) else if (fastcmp(type, "S"))
{ {
@ -7878,7 +7922,7 @@ static inline int lib_freeslot(lua_State *L)
break; break;
} }
if (i == NUMSTATEFREESLOTS) if (i == NUMSTATEFREESLOTS)
return r; CONS_Alert(CONS_WARNING, "Ran out of free State slots!\n");
} }
else if (fastcmp(type, "MT")) else if (fastcmp(type, "MT"))
{ {
@ -7893,7 +7937,26 @@ static inline int lib_freeslot(lua_State *L)
break; break;
} }
if (i == NUMMOBJFREESLOTS) if (i == NUMMOBJFREESLOTS)
return r; CONS_Alert(CONS_WARNING, "Ran out of free MobjType slots!\n");
}
else if (fastcmp(type, "SPR2"))
{
// Search if we already have an SPR2 by that name...
enum playersprite i;
for (i = SPR2_FIRSTFREESLOT; i < free_spr2; i++)
if (memcmp(spr2names[i],word,4) == 0)
break;
// We don't, so allocate a new one.
if (i >= free_spr2) {
if (free_spr2 < NUMPLAYERSPRITES)
{
CONS_Printf("Sprite SPR2_%s allocated.\n",word);
strncpy(spr2names[free_spr2],word,4);
spr2names[free_spr2++][4] = 0;
} else
CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n");
}
r++;
} }
Z_Free(s); Z_Free(s);
lua_remove(L, 1); lua_remove(L, 1);
@ -8060,7 +8123,7 @@ static inline int lib_getenum(lua_State *L)
} }
else if (fastncmp("SPR2_",word,4)) { else if (fastncmp("SPR2_",word,4)) {
p = word+5; p = word+5;
for (i = 0; i < NUMPLAYERSPRITES; i++) for (i = 0; i < (fixed_t)free_spr2; i++)
if (!spr2names[i][4]) if (!spr2names[i][4])
{ {
// special 3-char cases, e.g. SPR2_RUN // special 3-char cases, e.g. SPR2_RUN

View File

@ -207,7 +207,7 @@ typedef struct
#define ZSHIFT 4 #define ZSHIFT 4
extern const char *Color_Names[MAXSKINCOLORS]; extern const char *Color_Names[MAXSKINCOLORS + NUMSUPERCOLORS];
extern const UINT8 Color_Opposite[MAXSKINCOLORS*2]; extern const UINT8 Color_Opposite[MAXSKINCOLORS*2];
#define NUMMAPS 1035 #define NUMMAPS 1035

View File

@ -60,6 +60,7 @@
#endif #endif
#ifdef _WINDOWS #ifdef _WINDOWS
#define NONET
#if !defined (HWRENDER) && !defined (NOHW) #if !defined (HWRENDER) && !defined (NOHW)
#define HWRENDER #define HWRENDER
#endif #endif
@ -213,7 +214,7 @@ extern FILE *logstream;
// it's only for detection of the version the player is using so the MS can alert them of an update. // it's only for detection of the version the player is using so the MS can alert them of an update.
// Only set it higher, not lower, obviously. // Only set it higher, not lower, obviously.
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1". // Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
#define MODVERSION 20 #define MODVERSION 21
// ========================================================================= // =========================================================================
@ -257,32 +258,69 @@ typedef enum
SKINCOLOR_MAGENTA, SKINCOLOR_MAGENTA,
SKINCOLOR_PINK, SKINCOLOR_PINK,
SKINCOLOR_ROSY, SKINCOLOR_ROSY,
//SKINCOLOR_?
//SKINCOLOR_?
// Careful! MAXSKINCOLORS cannot be greater than 0x20! // Careful! MAXSKINCOLORS cannot be greater than 0x20! Two slots left...
MAXSKINCOLORS, MAXSKINCOLORS,
// Super special awesome Super flashing colors! // Super special awesome Super flashing colors!
SKINCOLOR_SUPER1 = MAXSKINCOLORS, SKINCOLOR_SUPERSILVER1 = MAXSKINCOLORS,
SKINCOLOR_SUPER2, SKINCOLOR_SUPERSILVER2,
SKINCOLOR_SUPER3, SKINCOLOR_SUPERSILVER3,
SKINCOLOR_SUPER4, SKINCOLOR_SUPERSILVER4,
SKINCOLOR_SUPER5, SKINCOLOR_SUPERSILVER5,
// Super Tails SKINCOLOR_SUPERRED1,
SKINCOLOR_TSUPER1, SKINCOLOR_SUPERRED2,
SKINCOLOR_TSUPER2, SKINCOLOR_SUPERRED3,
SKINCOLOR_TSUPER3, SKINCOLOR_SUPERRED4,
SKINCOLOR_TSUPER4, SKINCOLOR_SUPERRED5,
SKINCOLOR_TSUPER5,
// Super Knuckles SKINCOLOR_SUPERORANGE1,
SKINCOLOR_KSUPER1, SKINCOLOR_SUPERORANGE2,
SKINCOLOR_KSUPER2, SKINCOLOR_SUPERORANGE3,
SKINCOLOR_KSUPER3, SKINCOLOR_SUPERORANGE4,
SKINCOLOR_KSUPER4, SKINCOLOR_SUPERORANGE5,
SKINCOLOR_KSUPER5,
MAXTRANSLATIONS SKINCOLOR_SUPERGOLD1,
SKINCOLOR_SUPERGOLD2,
SKINCOLOR_SUPERGOLD3,
SKINCOLOR_SUPERGOLD4,
SKINCOLOR_SUPERGOLD5,
SKINCOLOR_SUPERPERIDOT1,
SKINCOLOR_SUPERPERIDOT2,
SKINCOLOR_SUPERPERIDOT3,
SKINCOLOR_SUPERPERIDOT4,
SKINCOLOR_SUPERPERIDOT5,
SKINCOLOR_SUPERCYAN1,
SKINCOLOR_SUPERCYAN2,
SKINCOLOR_SUPERCYAN3,
SKINCOLOR_SUPERCYAN4,
SKINCOLOR_SUPERCYAN5,
SKINCOLOR_SUPERPURPLE1,
SKINCOLOR_SUPERPURPLE2,
SKINCOLOR_SUPERPURPLE3,
SKINCOLOR_SUPERPURPLE4,
SKINCOLOR_SUPERPURPLE5,
SKINCOLOR_SUPERRUST1,
SKINCOLOR_SUPERRUST2,
SKINCOLOR_SUPERRUST3,
SKINCOLOR_SUPERRUST4,
SKINCOLOR_SUPERRUST5,
SKINCOLOR_SUPERTAN1,
SKINCOLOR_SUPERTAN2,
SKINCOLOR_SUPERTAN3,
SKINCOLOR_SUPERTAN4,
SKINCOLOR_SUPERTAN5,
MAXTRANSLATIONS,
NUMSUPERCOLORS = ((MAXTRANSLATIONS - MAXSKINCOLORS)/5)
} skincolors_t; } skincolors_t;
// State updates, number of tics / second. // State updates, number of tics / second.
@ -435,6 +473,12 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Kalaron/Eternity Engine slope code (SRB2CB ported) /// Kalaron/Eternity Engine slope code (SRB2CB ported)
#define ESLOPE #define ESLOPE
#ifdef ESLOPE
/// Backwards compatibility with SRB2CB's slope linedef types.
/// \note A simple shim that prints a warning.
#define ESLOPE_TYPESHIM
#endif
/// Delete file while the game is running. /// Delete file while the game is running.
/// \note EXTREMELY buggy, tends to crash game. /// \note EXTREMELY buggy, tends to crash game.
//#define DELFILE //#define DELFILE

View File

@ -92,7 +92,7 @@ typedef long ssize_t;
#endif #endif
#ifdef __APPLE_CC__ #ifdef __APPLE_CC__
#define DIRECTFULLSCREEN #define DIRECTFULLSCREEN 1
#define DEBUG_LOG #define DEBUG_LOG
#define NOIPX #define NOIPX
#endif #endif

View File

@ -1727,6 +1727,7 @@ static void F_AdvanceToNextScene(void)
void F_EndCutScene(void) void F_EndCutScene(void)
{ {
cutsceneover = true; // do this first, just in case Y_EndGame or something wants to turn it back false later
if (runningprecutscene) if (runningprecutscene)
{ {
if (server) if (server)
@ -1743,7 +1744,6 @@ void F_EndCutScene(void)
else else
Y_EndGame(); Y_EndGame();
} }
cutsceneover = true;
} }
void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean resetplayer) void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean resetplayer)

View File

@ -35,7 +35,7 @@ void F_CutsceneTicker(void);
void F_TitleDemoTicker(void); void F_TitleDemoTicker(void);
// Called by main loop. // Called by main loop.
void F_GameEndDrawer(void); FUNCMATH void F_GameEndDrawer(void);
void F_IntroDrawer(void); void F_IntroDrawer(void);
void F_TitleScreenDrawer(void); void F_TitleScreenDrawer(void);

View File

@ -711,6 +711,10 @@ void G_SetGameModified(boolean silent)
if (!silent) if (!silent)
CONS_Alert(CONS_NOTICE, M_GetText("Game must be restarted to record statistics.\n")); CONS_Alert(CONS_NOTICE, M_GetText("Game must be restarted to record statistics.\n"));
// If in record attack recording, cancel it.
if (modeattacking)
M_EndModeAttackRun();
} }
/** Builds an original game map name from a map number. /** Builds an original game map name from a map number.
@ -2043,6 +2047,8 @@ void G_PlayerReborn(INT32 player)
INT32 score; INT32 score;
INT32 lives; INT32 lives;
INT32 continues; INT32 continues;
fixed_t camerascale;
fixed_t shieldscale;
UINT8 charability; UINT8 charability;
UINT8 charability2; UINT8 charability2;
fixed_t normalspeed; fixed_t normalspeed;
@ -2066,6 +2072,8 @@ void G_PlayerReborn(INT32 player)
INT32 starpostnum; INT32 starpostnum;
INT32 starpostangle; INT32 starpostangle;
fixed_t jumpfactor; fixed_t jumpfactor;
fixed_t height;
fixed_t spinheight;
INT32 exiting; INT32 exiting;
INT16 numboxes; INT16 numboxes;
INT16 totalring; INT16 totalring;
@ -2097,6 +2105,8 @@ void G_PlayerReborn(INT32 player)
skincolor = players[player].skincolor; skincolor = players[player].skincolor;
skin = players[player].skin; skin = players[player].skin;
camerascale = players[player].camerascale;
shieldscale = players[player].shieldscale;
charability = players[player].charability; charability = players[player].charability;
charability2 = players[player].charability2; charability2 = players[player].charability2;
normalspeed = players[player].normalspeed; normalspeed = players[player].normalspeed;
@ -2113,6 +2123,8 @@ void G_PlayerReborn(INT32 player)
starpostnum = players[player].starpostnum; starpostnum = players[player].starpostnum;
starpostangle = players[player].starpostangle; starpostangle = players[player].starpostangle;
jumpfactor = players[player].jumpfactor; jumpfactor = players[player].jumpfactor;
height = players[player].height;
spinheight = players[player].spinheight;
thokitem = players[player].thokitem; thokitem = players[player].thokitem;
spinitem = players[player].spinitem; spinitem = players[player].spinitem;
revitem = players[player].revitem; revitem = players[player].revitem;
@ -2138,6 +2150,8 @@ void G_PlayerReborn(INT32 player)
// save player config truth reborn // save player config truth reborn
p->skincolor = skincolor; p->skincolor = skincolor;
p->skin = skin; p->skin = skin;
p->camerascale = camerascale;
p->shieldscale = shieldscale;
p->charability = charability; p->charability = charability;
p->charability2 = charability2; p->charability2 = charability2;
p->normalspeed = normalspeed; p->normalspeed = normalspeed;
@ -2160,6 +2174,8 @@ void G_PlayerReborn(INT32 player)
p->starpostnum = starpostnum; p->starpostnum = starpostnum;
p->starpostangle = starpostangle; p->starpostangle = starpostangle;
p->jumpfactor = jumpfactor; p->jumpfactor = jumpfactor;
p->height = height;
p->spinheight = spinheight;
p->exiting = exiting; p->exiting = exiting;
p->numboxes = numboxes; p->numboxes = numboxes;
@ -4345,12 +4361,18 @@ void G_GhostTicker(void)
// Tick ghost colors (Super and Mario Invincibility flashing) // Tick ghost colors (Super and Mario Invincibility flashing)
switch(g->color) switch(g->color)
{ {
case GHC_SUPER: // Super Sonic (P_DoSuperStuff) case GHC_SUPER: // Super (P_DoSuperStuff)
g->mo->color = SKINCOLOR_SUPER1; if (g->mo->skin)
{
skin_t *skin = (skin_t *)g->mo->skin;
g->mo->color = skin->supercolor;
}
else
g->mo->color = SKINCOLOR_SUPERGOLD1;
g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4); g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4);
break; break;
case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer) case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer)
g->mo->color = (UINT8)(leveltime % MAXSKINCOLORS); g->mo->color = (UINT8)(SKINCOLOR_RED + (leveltime % (MAXSKINCOLORS - SKINCOLOR_RED))); // Passes through all saturated colours
break; break;
default: default:
break; break;
@ -4686,6 +4708,8 @@ void G_BeginRecording(void)
demo_p += 16; demo_p += 16;
// Stats // Stats
WRITEUINT8(demo_p,player->camerascale>>FRACBITS);
WRITEUINT8(demo_p,player->shieldscale>>FRACBITS);
WRITEUINT8(demo_p,player->charability); WRITEUINT8(demo_p,player->charability);
WRITEUINT8(demo_p,player->charability2); WRITEUINT8(demo_p,player->charability2);
WRITEUINT8(demo_p,player->actionspd>>FRACBITS); WRITEUINT8(demo_p,player->actionspd>>FRACBITS);
@ -4696,6 +4720,8 @@ void G_BeginRecording(void)
WRITEUINT8(demo_p,player->thrustfactor); WRITEUINT8(demo_p,player->thrustfactor);
WRITEUINT8(demo_p,player->accelstart); WRITEUINT8(demo_p,player->accelstart);
WRITEUINT8(demo_p,player->acceleration); WRITEUINT8(demo_p,player->acceleration);
WRITEUINT8(demo_p,player->height>>FRACBITS);
WRITEUINT8(demo_p,player->spinheight>>FRACBITS);
// Trying to convert it back to % causes demo desync due to precision loss. // Trying to convert it back to % causes demo desync due to precision loss.
// Don't do it. // Don't do it.
@ -4926,7 +4952,7 @@ void G_DoPlayDemo(char *defdemoname)
char skin[17],color[17],*n,*pdemoname; char skin[17],color[17],*n,*pdemoname;
UINT8 version,subversion,charability,charability2,thrustfactor,accelstart,acceleration; UINT8 version,subversion,charability,charability2,thrustfactor,accelstart,acceleration;
UINT32 randseed; UINT32 randseed;
fixed_t actionspd,mindash,maxdash,normalspeed,runspeed,jumpfactor; fixed_t camerascale,shieldscale,actionspd,mindash,maxdash,normalspeed,runspeed,jumpfactor,height,spinheight;
char msg[1024]; char msg[1024];
skin[16] = '\0'; skin[16] = '\0';
@ -5062,6 +5088,8 @@ void G_DoPlayDemo(char *defdemoname)
M_Memcpy(color,demo_p,16); M_Memcpy(color,demo_p,16);
demo_p += 16; demo_p += 16;
camerascale = (fixed_t)READUINT8(demo_p)<<FRACBITS;
shieldscale = (fixed_t)READUINT8(demo_p)<<FRACBITS;
charability = READUINT8(demo_p); charability = READUINT8(demo_p);
charability2 = READUINT8(demo_p); charability2 = READUINT8(demo_p);
actionspd = (fixed_t)READUINT8(demo_p)<<FRACBITS; actionspd = (fixed_t)READUINT8(demo_p)<<FRACBITS;
@ -5072,6 +5100,8 @@ void G_DoPlayDemo(char *defdemoname)
thrustfactor = READUINT8(demo_p); thrustfactor = READUINT8(demo_p);
accelstart = READUINT8(demo_p); accelstart = READUINT8(demo_p);
acceleration = READUINT8(demo_p); acceleration = READUINT8(demo_p);
height = (fixed_t)READUINT8(demo_p)<<FRACBITS;
spinheight = (fixed_t)READUINT8(demo_p)<<FRACBITS;
jumpfactor = READFIXED(demo_p); jumpfactor = READFIXED(demo_p);
// net var data // net var data
@ -5135,6 +5165,8 @@ void G_DoPlayDemo(char *defdemoname)
// Set saved attribute values // Set saved attribute values
// No cheat checking here, because even if they ARE wrong... // No cheat checking here, because even if they ARE wrong...
// it would only break the replay if we clipped them. // it would only break the replay if we clipped them.
players[0].camerascale = camerascale;
players[0].shieldscale = shieldscale;
players[0].charability = charability; players[0].charability = charability;
players[0].charability2 = charability2; players[0].charability2 = charability2;
players[0].actionspd = actionspd; players[0].actionspd = actionspd;
@ -5146,6 +5178,8 @@ void G_DoPlayDemo(char *defdemoname)
players[0].accelstart = accelstart; players[0].accelstart = accelstart;
players[0].acceleration = acceleration; players[0].acceleration = acceleration;
players[0].jumpfactor = jumpfactor; players[0].jumpfactor = jumpfactor;
players[0].height = height;
players[0].spinheight = spinheight;
demo_start = true; demo_start = true;
} }

View File

@ -54,7 +54,7 @@
#endif #endif
#endif #endif
typedef void (*I_Error_t) (const char *error, ...); typedef void (*I_Error_t) (const char *error, ...) FUNCIERROR;
// ========================================================================== // ==========================================================================
// MATHS // MATHS

View File

@ -237,7 +237,7 @@ light_t *t_lspr[NUMSPRITES] =
// Interactive Objects // Interactive Objects
&lspr[NOLIGHT], // SPR_FANS &lspr[NOLIGHT], // SPR_FANS
&lspr[NOLIGHT], // SPR_BUBL &lspr[NOLIGHT], // SPR_BBLS
&lspr[NOLIGHT], // SPR_SIGN &lspr[NOLIGHT], // SPR_SIGN
&lspr[NOLIGHT], // SPR_STEM &lspr[NOLIGHT], // SPR_STEM
&lspr[NOLIGHT], // SPR_SPIK &lspr[NOLIGHT], // SPR_SPIK
@ -382,11 +382,8 @@ light_t *t_lspr[NUMSPRITES] =
&lspr[NOLIGHT], // SPR_SPLH &lspr[NOLIGHT], // SPR_SPLH
&lspr[NOLIGHT], // SPR_SPLA &lspr[NOLIGHT], // SPR_SPLA
&lspr[NOLIGHT], // SPR_SMOK &lspr[NOLIGHT], // SPR_SMOK
&lspr[NOLIGHT], // SPR_BUBP &lspr[NOLIGHT], // SPR_BUBL
&lspr[NOLIGHT], // SPR_BUBO &lspr[SUPERSPARK_L], // SPR_WZAP
&lspr[NOLIGHT], // SPR_BUBN
&lspr[NOLIGHT], // SPR_BUBM
&lspr[NOLIGHT], // SPR_POPP
&lspr[SUPERSPARK_L], // SPR_TFOG &lspr[SUPERSPARK_L], // SPR_TFOG
&lspr[NIGHTSLIGHT_L], // SPR_SEED // Sonic CD flower seed &lspr[NIGHTSLIGHT_L], // SPR_SEED // Sonic CD flower seed
&lspr[NOLIGHT], // SPR_PRTL &lspr[NOLIGHT], // SPR_PRTL
@ -437,16 +434,12 @@ light_t *t_lspr[NUMSPRITES] =
// NiGHTS Stuff // NiGHTS Stuff
&lspr[SUPERSONIC_L], // SPR_NDRN // NiGHTS drone &lspr[SUPERSONIC_L], // SPR_NDRN // NiGHTS drone
&lspr[SUPERSONIC_L], // SPR_SUPE // NiGHTS character flying
&lspr[SUPERSONIC_L], // SPR_SUPZ // NiGHTS hurt
&lspr[SUPERSONIC_L], // SPR_NDRL // NiGHTS character drilling
&lspr[NOLIGHT], // SPR_NSPK &lspr[NOLIGHT], // SPR_NSPK
&lspr[NOLIGHT], // SPR_NBMP &lspr[NOLIGHT], // SPR_NBMP
&lspr[NOLIGHT], // SPR_HOOP &lspr[NOLIGHT], // SPR_HOOP
&lspr[NOLIGHT], // SPR_HSCR &lspr[NOLIGHT], // SPR_HSCR
&lspr[NOLIGHT], // SPR_NPRU &lspr[NOLIGHT], // SPR_NPRU
&lspr[NOLIGHT], // SPR_CAPS &lspr[NOLIGHT], // SPR_CAPS
&lspr[SUPERSONIC_L], // SPR_SUPT
// Debris // Debris
&lspr[RINGSPARK_L], // SPR_SPRK &lspr[RINGSPARK_L], // SPR_SPRK

View File

@ -66,9 +66,9 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing);
#endif #endif
#ifdef SORTING #ifdef SORTING
void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, fixed_t fixedheight, void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight,
INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap); INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap);
void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, fixed_t fixedheight, void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight,
INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap); INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap);
#else #else
static void HWR_Add3DWater(lumpnum_t lumpnum, extrasubsector_t *xsub, fixed_t fixedheight, static void HWR_Add3DWater(lumpnum_t lumpnum, extrasubsector_t *xsub, fixed_t fixedheight,
@ -521,7 +521,7 @@ static UINT8 HWR_FogBlockAlpha(INT32 light, UINT32 color, UINT32 fadecolor) // L
// -----------------+ // -----------------+
// HWR_RenderPlane : Render a floor or ceiling convex polygon // HWR_RenderPlane : Render a floor or ceiling convex polygon
// -----------------+ // -----------------+
static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fixedheight, static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight,
FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, boolean fogplane, extracolormap_t *planecolormap) FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, boolean fogplane, extracolormap_t *planecolormap)
{ {
polyvertex_t * pv; polyvertex_t * pv;
@ -554,17 +554,16 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fi
// Get the slope pointer to simplify future code // Get the slope pointer to simplify future code
if (FOFsector) if (FOFsector)
{ {
if (FOFsector->f_slope && FOFsector->floorheight == fixedheight) if (FOFsector->f_slope && !isceiling)
slope = FOFsector->f_slope; slope = FOFsector->f_slope;
else if (FOFsector->c_slope && FOFsector->ceilingheight == fixedheight) else if (FOFsector->c_slope && isceiling)
slope = FOFsector->c_slope; slope = FOFsector->c_slope;
} }
else else
{ {
// Use fixedheight to determine whether to check floor or ceiling because I hate my life if (gr_frontsector->f_slope && !isceiling)
if (gr_frontsector->f_slope && gr_frontsector->floorheight == fixedheight)
slope = gr_frontsector->f_slope; slope = gr_frontsector->f_slope;
else if (gr_frontsector->c_slope && gr_frontsector->ceilingheight == fixedheight) else if (gr_frontsector->c_slope && isceiling)
slope = gr_frontsector->c_slope; slope = gr_frontsector->c_slope;
} }
@ -638,12 +637,7 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fi
if (FOFsector != NULL) if (FOFsector != NULL)
{ {
#ifdef ESLOPE if (!isceiling) // it's a floor
if ((slope && slope == FOFsector->f_slope)
|| fixedheight == FOFsector->floorheight) // it's a floor
#else
if (fixedheight == FOFsector->floorheight) // it's a floor
#endif
{ {
scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatsize; scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatsize;
scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatsize; scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatsize;
@ -658,12 +652,7 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, fixed_t fi
} }
else if (gr_frontsector) else if (gr_frontsector)
{ {
#ifdef ESLOPE if (!isceiling) // it's a floor
if ((slope && slope == gr_frontsector->f_slope)
|| fixedheight == gr_frontsector->floorheight) // it's a floor
#else
if (fixedheight < dup_viewz) // it's a floor
#endif
{ {
scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatsize; scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatsize;
scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatsize; scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatsize;
@ -3111,7 +3100,7 @@ static inline void HWR_AddPolyObjectSegs(void)
} }
#ifdef POLYOBJECTS_PLANES #ifdef POLYOBJECTS_PLANES
static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, fixed_t fixedheight, static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight,
FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector,
UINT8 alpha, extracolormap_t *planecolormap) UINT8 alpha, extracolormap_t *planecolormap)
{ {
@ -3195,7 +3184,7 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, fixed_t fixedheight
if (FOFsector != NULL) if (FOFsector != NULL)
{ {
if (fixedheight == FOFsector->floorheight) // it's a floor if (!isceiling) // it's a floor
{ {
scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatsize; scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatsize;
scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatsize; scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatsize;
@ -3210,7 +3199,7 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, fixed_t fixedheight
} }
else if (gr_frontsector) else if (gr_frontsector)
{ {
if (fixedheight < dup_viewz) // it's a floor if (!isceiling) // it's a floor
{ {
scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatsize; scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatsize;
scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatsize; scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatsize;
@ -3303,13 +3292,13 @@ static void HWR_AddPolyObjectPlanes(void)
{ {
FSurfaceInfo Surf; FSurfaceInfo Surf;
FBITFIELD blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf); FBITFIELD blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf);
HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->floorpic].lumpnum, po_ptrs[i], polyobjsector->floorheight, HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->floorpic].lumpnum, po_ptrs[i], false, polyobjsector->floorheight,
polyobjsector->lightlevel, Surf.FlatColor.s.alpha, polyobjsector, blendmode, NULL); polyobjsector->lightlevel, Surf.FlatColor.s.alpha, polyobjsector, blendmode, NULL);
} }
else else
{ {
HWR_GetFlat(levelflats[polyobjsector->floorpic].lumpnum); HWR_GetFlat(levelflats[polyobjsector->floorpic].lumpnum);
HWR_RenderPolyObjectPlane(po_ptrs[i], polyobjsector->floorheight, PF_Occlude, HWR_RenderPolyObjectPlane(po_ptrs[i], false, polyobjsector->floorheight, PF_Occlude,
polyobjsector->lightlevel, levelflats[polyobjsector->floorpic].lumpnum, polyobjsector->lightlevel, levelflats[polyobjsector->floorpic].lumpnum,
polyobjsector, 255, NULL); polyobjsector, 255, NULL);
} }
@ -3325,13 +3314,13 @@ static void HWR_AddPolyObjectPlanes(void)
FBITFIELD blendmode; FBITFIELD blendmode;
memset(&Surf, 0x00, sizeof(Surf)); memset(&Surf, 0x00, sizeof(Surf));
blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf); blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf);
HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->ceilingpic].lumpnum, po_ptrs[i], polyobjsector->ceilingheight, HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->ceilingpic].lumpnum, po_ptrs[i], true, polyobjsector->ceilingheight,
polyobjsector->lightlevel, Surf.FlatColor.s.alpha, polyobjsector, blendmode, NULL); polyobjsector->lightlevel, Surf.FlatColor.s.alpha, polyobjsector, blendmode, NULL);
} }
else else
{ {
HWR_GetFlat(levelflats[polyobjsector->ceilingpic].lumpnum); HWR_GetFlat(levelflats[polyobjsector->ceilingpic].lumpnum);
HWR_RenderPolyObjectPlane(po_ptrs[i], polyobjsector->ceilingheight, PF_Occlude, HWR_RenderPolyObjectPlane(po_ptrs[i], true, polyobjsector->ceilingheight, PF_Occlude,
polyobjsector->lightlevel, levelflats[polyobjsector->floorpic].lumpnum, polyobjsector->lightlevel, levelflats[polyobjsector->floorpic].lumpnum,
polyobjsector, 255, NULL); polyobjsector, 255, NULL);
} }
@ -3485,7 +3474,7 @@ static void HWR_Subsector(size_t num)
if (sub->validcount != validcount) if (sub->validcount != validcount)
{ {
HWR_GetFlat(levelflats[gr_frontsector->floorpic].lumpnum); HWR_GetFlat(levelflats[gr_frontsector->floorpic].lumpnum);
HWR_RenderPlane(gr_frontsector, &extrasubsectors[num], HWR_RenderPlane(gr_frontsector, &extrasubsectors[num], false,
// Hack to make things continue to work around slopes. // Hack to make things continue to work around slopes.
locFloorHeight == cullFloorHeight ? locFloorHeight : gr_frontsector->floorheight, locFloorHeight == cullFloorHeight ? locFloorHeight : gr_frontsector->floorheight,
// We now return you to your regularly scheduled rendering. // We now return you to your regularly scheduled rendering.
@ -3507,7 +3496,7 @@ static void HWR_Subsector(size_t num)
if (sub->validcount != validcount) if (sub->validcount != validcount)
{ {
HWR_GetFlat(levelflats[gr_frontsector->ceilingpic].lumpnum); HWR_GetFlat(levelflats[gr_frontsector->ceilingpic].lumpnum);
HWR_RenderPlane(NULL, &extrasubsectors[num], HWR_RenderPlane(NULL, &extrasubsectors[num], true,
// Hack to make things continue to work around slopes. // Hack to make things continue to work around slopes.
locCeilingHeight == cullCeilingHeight ? locCeilingHeight : gr_frontsector->ceilingheight, locCeilingHeight == cullCeilingHeight ? locCeilingHeight : gr_frontsector->ceilingheight,
// We now return you to your regularly scheduled rendering. // We now return you to your regularly scheduled rendering.
@ -3576,6 +3565,7 @@ static void HWR_Subsector(size_t num)
HWR_AddTransparentFloor(0, HWR_AddTransparentFloor(0,
&extrasubsectors[num], &extrasubsectors[num],
false,
*rover->bottomheight, *rover->bottomheight,
*gr_frontsector->lightlist[light].lightlevel, *gr_frontsector->lightlist[light].lightlevel,
alpha, rover->master->frontsector, PF_Translucent|PF_NoTexture, alpha, rover->master->frontsector, PF_Translucent|PF_NoTexture,
@ -3593,6 +3583,7 @@ static void HWR_Subsector(size_t num)
#else #else
HWR_AddTransparentFloor(levelflats[*rover->bottompic].lumpnum, HWR_AddTransparentFloor(levelflats[*rover->bottompic].lumpnum,
&extrasubsectors[num], &extrasubsectors[num],
false,
*rover->bottomheight, *rover->bottomheight,
*gr_frontsector->lightlist[light].lightlevel, *gr_frontsector->lightlist[light].lightlevel,
rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, PF_Translucent, rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, PF_Translucent,
@ -3603,7 +3594,7 @@ static void HWR_Subsector(size_t num)
{ {
HWR_GetFlat(levelflats[*rover->bottompic].lumpnum); HWR_GetFlat(levelflats[*rover->bottompic].lumpnum);
light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
HWR_RenderPlane(NULL, &extrasubsectors[num], *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum, HWR_RenderPlane(NULL, &extrasubsectors[num], false, *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum,
rover->master->frontsector, 255, false, gr_frontsector->lightlist[light].extra_colormap); rover->master->frontsector, 255, false, gr_frontsector->lightlist[light].extra_colormap);
} }
} }
@ -3637,6 +3628,7 @@ static void HWR_Subsector(size_t num)
HWR_AddTransparentFloor(0, HWR_AddTransparentFloor(0,
&extrasubsectors[num], &extrasubsectors[num],
true,
*rover->topheight, *rover->topheight,
*gr_frontsector->lightlist[light].lightlevel, *gr_frontsector->lightlist[light].lightlevel,
alpha, rover->master->frontsector, PF_Translucent|PF_NoTexture, alpha, rover->master->frontsector, PF_Translucent|PF_NoTexture,
@ -3654,6 +3646,7 @@ static void HWR_Subsector(size_t num)
#else #else
HWR_AddTransparentFloor(levelflats[*rover->toppic].lumpnum, HWR_AddTransparentFloor(levelflats[*rover->toppic].lumpnum,
&extrasubsectors[num], &extrasubsectors[num],
true,
*rover->topheight, *rover->topheight,
*gr_frontsector->lightlist[light].lightlevel, *gr_frontsector->lightlist[light].lightlevel,
rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, PF_Translucent, rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, PF_Translucent,
@ -3665,7 +3658,7 @@ static void HWR_Subsector(size_t num)
{ {
HWR_GetFlat(levelflats[*rover->toppic].lumpnum); HWR_GetFlat(levelflats[*rover->toppic].lumpnum);
light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
HWR_RenderPlane(NULL, &extrasubsectors[num], *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum, HWR_RenderPlane(NULL, &extrasubsectors[num], true, *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum,
rover->master->frontsector, 255, false, gr_frontsector->lightlist[light].extra_colormap); rover->master->frontsector, 255, false, gr_frontsector->lightlist[light].extra_colormap);
} }
} }
@ -4529,7 +4522,8 @@ static void HWR_SortVisSprites(void)
// Fix first and last. ds still points to the last one after the loop // Fix first and last. ds still points to the last one after the loop
dsfirst->prev = &unsorted; dsfirst->prev = &unsorted;
unsorted.next = dsfirst; unsorted.next = dsfirst;
ds->next = &unsorted; if (ds)
ds->next = &unsorted;
unsorted.prev = ds; unsorted.prev = ds;
// pull the vissprites out by scale // pull the vissprites out by scale
@ -4552,10 +4546,13 @@ static void HWR_SortVisSprites(void)
best = ds; best = ds;
} }
} }
best->next->prev = best->prev; if (best)
best->prev->next = best->next; {
best->next = &gr_vsprsortedhead; best->next->prev = best->prev;
best->prev = gr_vsprsortedhead.prev; best->prev->next = best->next;
best->next = &gr_vsprsortedhead;
best->prev = gr_vsprsortedhead.prev;
}
gr_vsprsortedhead.prev->next = best; gr_vsprsortedhead.prev->next = best;
gr_vsprsortedhead.prev = best; gr_vsprsortedhead.prev = best;
} }
@ -4588,6 +4585,7 @@ static void HWR_RenderWall(wallVert3D *wallVerts, FSurfaceInfo *pSurf, FBITFIE
typedef struct typedef struct
{ {
extrasubsector_t *xsub; extrasubsector_t *xsub;
boolean isceiling;
fixed_t fixedheight; fixed_t fixedheight;
INT32 lightlevel; INT32 lightlevel;
lumpnum_t lumpnum; lumpnum_t lumpnum;
@ -4605,6 +4603,7 @@ static planeinfo_t *planeinfo = NULL;
typedef struct typedef struct
{ {
polyobj_t *polysector; polyobj_t *polysector;
boolean isceiling;
fixed_t fixedheight; fixed_t fixedheight;
INT32 lightlevel; INT32 lightlevel;
lumpnum_t lumpnum; lumpnum_t lumpnum;
@ -4640,7 +4639,7 @@ static INT32 drawcount = 0;
#define MAX_TRANSPARENTFLOOR 512 #define MAX_TRANSPARENTFLOOR 512
// This will likely turn into a copy of HWR_Add3DWater and replace it. // This will likely turn into a copy of HWR_Add3DWater and replace it.
void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling,
fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap) fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap)
{ {
static size_t allocedplanes = 0; static size_t allocedplanes = 0;
@ -4655,6 +4654,7 @@ void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub,
Z_Realloc(planeinfo, allocedplanes * sizeof (*planeinfo), PU_LEVEL, &planeinfo); Z_Realloc(planeinfo, allocedplanes * sizeof (*planeinfo), PU_LEVEL, &planeinfo);
} }
planeinfo[numplanes].isceiling = isceiling;
planeinfo[numplanes].fixedheight = fixedheight; planeinfo[numplanes].fixedheight = fixedheight;
planeinfo[numplanes].lightlevel = lightlevel; planeinfo[numplanes].lightlevel = lightlevel;
planeinfo[numplanes].lumpnum = lumpnum; planeinfo[numplanes].lumpnum = lumpnum;
@ -4665,12 +4665,13 @@ void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub,
planeinfo[numplanes].fogplane = fogplane; planeinfo[numplanes].fogplane = fogplane;
planeinfo[numplanes].planecolormap = planecolormap; planeinfo[numplanes].planecolormap = planecolormap;
planeinfo[numplanes].drawcount = drawcount++; planeinfo[numplanes].drawcount = drawcount++;
numplanes++; numplanes++;
} }
// Adding this for now until I can create extrasubsector info for polyobjects // Adding this for now until I can create extrasubsector info for polyobjects
// When that happens it'll just be done through HWR_AddTransparentFloor and HWR_RenderPlane // When that happens it'll just be done through HWR_AddTransparentFloor and HWR_RenderPlane
void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling,
fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap) fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap)
{ {
static size_t allocedpolyplanes = 0; static size_t allocedpolyplanes = 0;
@ -4685,6 +4686,7 @@ void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector,
Z_Realloc(polyplaneinfo, allocedpolyplanes * sizeof (*polyplaneinfo), PU_LEVEL, &polyplaneinfo); Z_Realloc(polyplaneinfo, allocedpolyplanes * sizeof (*polyplaneinfo), PU_LEVEL, &polyplaneinfo);
} }
polyplaneinfo[numpolyplanes].isceiling = isceiling;
polyplaneinfo[numpolyplanes].fixedheight = fixedheight; polyplaneinfo[numpolyplanes].fixedheight = fixedheight;
polyplaneinfo[numpolyplanes].lightlevel = lightlevel; polyplaneinfo[numpolyplanes].lightlevel = lightlevel;
polyplaneinfo[numpolyplanes].lumpnum = lumpnum; polyplaneinfo[numpolyplanes].lumpnum = lumpnum;
@ -4850,7 +4852,7 @@ static void HWR_CreateDrawNodes(void)
if (!(sortnode[sortindex[i]].plane->blend & PF_NoTexture)) if (!(sortnode[sortindex[i]].plane->blend & PF_NoTexture))
HWR_GetFlat(sortnode[sortindex[i]].plane->lumpnum); HWR_GetFlat(sortnode[sortindex[i]].plane->lumpnum);
HWR_RenderPlane(NULL, sortnode[sortindex[i]].plane->xsub, sortnode[sortindex[i]].plane->fixedheight, sortnode[sortindex[i]].plane->blend, sortnode[sortindex[i]].plane->lightlevel, HWR_RenderPlane(NULL, sortnode[sortindex[i]].plane->xsub, sortnode[sortindex[i]].plane->isceiling, sortnode[sortindex[i]].plane->fixedheight, sortnode[sortindex[i]].plane->blend, sortnode[sortindex[i]].plane->lightlevel,
sortnode[sortindex[i]].plane->lumpnum, sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->fogplane, sortnode[sortindex[i]].plane->planecolormap); sortnode[sortindex[i]].plane->lumpnum, sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->fogplane, sortnode[sortindex[i]].plane->planecolormap);
} }
else if (sortnode[sortindex[i]].polyplane) else if (sortnode[sortindex[i]].polyplane)
@ -4860,7 +4862,7 @@ static void HWR_CreateDrawNodes(void)
if (!(sortnode[sortindex[i]].polyplane->blend & PF_NoTexture)) if (!(sortnode[sortindex[i]].polyplane->blend & PF_NoTexture))
HWR_GetFlat(sortnode[sortindex[i]].polyplane->lumpnum); HWR_GetFlat(sortnode[sortindex[i]].polyplane->lumpnum);
HWR_RenderPolyObjectPlane(sortnode[sortindex[i]].polyplane->polysector, sortnode[sortindex[i]].polyplane->fixedheight, sortnode[sortindex[i]].polyplane->blend, sortnode[sortindex[i]].polyplane->lightlevel, HWR_RenderPolyObjectPlane(sortnode[sortindex[i]].polyplane->polysector, sortnode[sortindex[i]].polyplane->isceiling, sortnode[sortindex[i]].polyplane->fixedheight, sortnode[sortindex[i]].polyplane->blend, sortnode[sortindex[i]].polyplane->lightlevel,
sortnode[sortindex[i]].polyplane->lumpnum, sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->alpha, sortnode[sortindex[i]].polyplane->planecolormap); sortnode[sortindex[i]].polyplane->lumpnum, sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->alpha, sortnode[sortindex[i]].polyplane->planecolormap);
} }
else if (sortnode[sortindex[i]].wall) else if (sortnode[sortindex[i]].wall)
@ -5092,22 +5094,29 @@ static void HWR_ProjectSprite(mobj_t *thing)
I_Error("sprframes NULL for sprite %d\n", thing->sprite); I_Error("sprframes NULL for sprite %d\n", thing->sprite);
#endif #endif
if (sprframe->rotate) if (sprframe->rotate == SRF_SINGLE)
{
// choose a different rotation based on player view
ang = R_PointToAngle(thing->x, thing->y); // uses viewx,viewy
rot = (ang-thing->angle+ANGLE_202h)>>29;
//Fab: lumpid is the index for spritewidth,spriteoffset... tables
lumpoff = sprframe->lumpid[rot];
flip = sprframe->flip & (1<<rot);
}
else
{ {
// use single rotation for all views // use single rotation for all views
rot = 0; //Fab: for vis->patch below rot = 0; //Fab: for vis->patch below
lumpoff = sprframe->lumpid[0]; //Fab: see note above lumpoff = sprframe->lumpid[0]; //Fab: see note above
flip = sprframe->flip; // Will only be 0x00 or 0xFF flip = sprframe->flip; // Will only be 0x00 or 0xFF
} }
else
{
// choose a different rotation based on player view
ang = R_PointToAngle (thing->x, thing->y) - thing->angle;
if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
rot = 6; // F7 slot
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
rot = 2; // F3 slot
else // Normal behaviour
rot = (ang+ANGLE_202h)>>29;
//Fab: lumpid is the index for spritewidth,spriteoffset... tables
lumpoff = sprframe->lumpid[rot];
flip = sprframe->flip & (1<<rot);
}
if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES) if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES)
this_scale = this_scale * FIXED_TO_FLOAT(((skin_t *)thing->skin)->highresscale); this_scale = this_scale * FIXED_TO_FLOAT(((skin_t *)thing->skin)->highresscale);
@ -6157,7 +6166,7 @@ static void HWR_Render3DWater(void)
for (i = 0; i < numfloors; i++) for (i = 0; i < numfloors; i++)
{ {
HWR_GetFlat(planeinfo[i].lumpnum); HWR_GetFlat(planeinfo[i].lumpnum);
HWR_RenderPlane(NULL, planeinfo[i].xsub, planeinfo[i].fixedheight, PF_Translucent, planeinfo[i].lightlevel, planeinfo[i].lumpnum, HWR_RenderPlane(NULL, planeinfo[i].xsub, planeinfo[i].isceiling, planeinfo[i].fixedheight, PF_Translucent, planeinfo[i].lightlevel, planeinfo[i].lumpnum,
planeinfo[i].FOFSector, planeinfo[i].alpha, planeinfo[i].fogplane, planeinfo[i].planecolormap); planeinfo[i].FOFSector, planeinfo[i].alpha, planeinfo[i].fogplane, planeinfo[i].planecolormap);
} }
numfloors = 0; numfloors = 0;

View File

@ -1035,32 +1035,151 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
case SKINCOLOR_ROSY: case SKINCOLOR_ROSY:
blendcolor = V_GetColor(202); blendcolor = V_GetColor(202);
break; break;
case SKINCOLOR_SUPER1:
case SKINCOLOR_SUPERSILVER1: // Super silver
blendcolor = V_GetColor(0);
break;
case SKINCOLOR_SUPERSILVER2:
blendcolor = V_GetColor(2);
break;
case SKINCOLOR_SUPERSILVER3:
blendcolor = V_GetColor(4);
break;
case SKINCOLOR_SUPERSILVER4:
blendcolor = V_GetColor(7);
break;
case SKINCOLOR_SUPERSILVER5:
blendcolor = V_GetColor(10);
break;
case SKINCOLOR_SUPERRED1: // Super red
blendcolor = V_GetColor(208);
break;
case SKINCOLOR_SUPERRED2:
blendcolor = V_GetColor(210);
break;
case SKINCOLOR_SUPERRED3:
blendcolor = V_GetColor(32);
break;
case SKINCOLOR_SUPERRED4:
blendcolor = V_GetColor(33);
break;
case SKINCOLOR_SUPERRED5:
blendcolor = V_GetColor(35);
break;
case SKINCOLOR_SUPERORANGE1: // Super orange
blendcolor = V_GetColor(208);
break;
case SKINCOLOR_SUPERORANGE2:
blendcolor = V_GetColor(48);
break;
case SKINCOLOR_SUPERORANGE3:
blendcolor = V_GetColor(50);
break;
case SKINCOLOR_SUPERORANGE4:
blendcolor = V_GetColor(54);
break;
case SKINCOLOR_SUPERORANGE5:
blendcolor = V_GetColor(58);
break;
case SKINCOLOR_SUPERGOLD1: // Super gold
blendcolor = V_GetColor(80); blendcolor = V_GetColor(80);
break; break;
case SKINCOLOR_SUPER2: case SKINCOLOR_SUPERGOLD2:
blendcolor = V_GetColor(83); blendcolor = V_GetColor(83);
break; break;
case SKINCOLOR_SUPER3: case SKINCOLOR_SUPERGOLD3:
blendcolor = V_GetColor(73); blendcolor = V_GetColor(73);
break; break;
case SKINCOLOR_SUPER4: case SKINCOLOR_SUPERGOLD4:
blendcolor = V_GetColor(64); blendcolor = V_GetColor(64);
break; break;
case SKINCOLOR_SUPER5: case SKINCOLOR_SUPERGOLD5:
blendcolor = V_GetColor(67); blendcolor = V_GetColor(67);
break; break;
case SKINCOLOR_TSUPER1: case SKINCOLOR_SUPERPERIDOT1: // Super peridot
case SKINCOLOR_TSUPER2: blendcolor = V_GetColor(88);
case SKINCOLOR_TSUPER3: break;
case SKINCOLOR_TSUPER4: case SKINCOLOR_SUPERPERIDOT2:
case SKINCOLOR_TSUPER5: blendcolor = V_GetColor(188);
case SKINCOLOR_KSUPER1: break;
case SKINCOLOR_KSUPER2: case SKINCOLOR_SUPERPERIDOT3:
case SKINCOLOR_KSUPER3: blendcolor = V_GetColor(189);
case SKINCOLOR_KSUPER4: break;
case SKINCOLOR_KSUPER5: case SKINCOLOR_SUPERPERIDOT4:
blendcolor = V_GetColor(190);
break;
case SKINCOLOR_SUPERPERIDOT5:
blendcolor = V_GetColor(191);
break;
case SKINCOLOR_SUPERCYAN1: // Super cyan
blendcolor = V_GetColor(128);
break;
case SKINCOLOR_SUPERCYAN2:
blendcolor = V_GetColor(131);
break;
case SKINCOLOR_SUPERCYAN3:
blendcolor = V_GetColor(133);
break;
case SKINCOLOR_SUPERCYAN4:
blendcolor = V_GetColor(134);
break;
case SKINCOLOR_SUPERCYAN5:
blendcolor = V_GetColor(136);
break;
case SKINCOLOR_SUPERPURPLE1: // Super purple
blendcolor = V_GetColor(144);
break;
case SKINCOLOR_SUPERPURPLE2:
blendcolor = V_GetColor(162);
break;
case SKINCOLOR_SUPERPURPLE3:
blendcolor = V_GetColor(164);
break;
case SKINCOLOR_SUPERPURPLE4:
blendcolor = V_GetColor(166);
break;
case SKINCOLOR_SUPERPURPLE5:
blendcolor = V_GetColor(168);
break;
case SKINCOLOR_SUPERRUST1: // Super rust
blendcolor = V_GetColor(51);
break;
case SKINCOLOR_SUPERRUST2:
blendcolor = V_GetColor(54);
break;
case SKINCOLOR_SUPERRUST3:
blendcolor = V_GetColor(68);
break;
case SKINCOLOR_SUPERRUST4:
blendcolor = V_GetColor(70);
break;
case SKINCOLOR_SUPERRUST5:
blendcolor = V_GetColor(234);
break;
case SKINCOLOR_SUPERTAN1: // Super tan
blendcolor = V_GetColor(80);
break;
case SKINCOLOR_SUPERTAN2:
blendcolor = V_GetColor(82);
break;
case SKINCOLOR_SUPERTAN3:
blendcolor = V_GetColor(84);
break;
case SKINCOLOR_SUPERTAN4:
blendcolor = V_GetColor(87);
break;
case SKINCOLOR_SUPERTAN5:
blendcolor = V_GetColor(247);
break;
default: default:
blendcolor = V_GetColor(255); blendcolor = V_GetColor(255);
break; break;

View File

@ -1836,10 +1836,7 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value)
} }
} }
// -----------------+ static inline void DrawMD2Ex(INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 duration, UINT32 tics, md2_frame_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color)
// HWRAPI DrawMD2 : Draw an MD2 model with glcommands
// -----------------+
EXPORT void HWRAPI(DrawMD2i) (INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 duration, UINT32 tics, md2_frame_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color)
{ {
INT32 val, count, pindex; INT32 val, count, pindex;
GLfloat s, t; GLfloat s, t;
@ -1931,7 +1928,7 @@ EXPORT void HWRAPI(DrawMD2i) (INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 d
//pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency //pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
// Remove depth mask when the model is transparent so it doesn't cut thorugh sprites // SRB2CBTODO: For all stuff too?! // Remove depth mask when the model is transparent so it doesn't cut thorugh sprites // SRB2CBTODO: For all stuff too?!
if (color[3] < 255) if (color && color[3] < 255)
{ {
pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
pglDepthMask(GL_FALSE); pglDepthMask(GL_FALSE);
@ -2007,11 +2004,20 @@ EXPORT void HWRAPI(DrawMD2i) (INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 d
pglDisable(GL_CULL_FACE); pglDisable(GL_CULL_FACE);
} }
// -----------------+
// HWRAPI DrawMD2 : Draw an MD2 model with glcommands
// -----------------+
EXPORT void HWRAPI(DrawMD2i) (INT32 *gl_cmd_buffer, md2_frame_t *frame, UINT32 duration, UINT32 tics, md2_frame_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color)
{
DrawMD2Ex(gl_cmd_buffer, frame, duration, tics, nextframe, pos, scale, flipped, color);
}
EXPORT void HWRAPI(DrawMD2) (INT32 *gl_cmd_buffer, md2_frame_t *frame, FTransform *pos, float scale) EXPORT void HWRAPI(DrawMD2) (INT32 *gl_cmd_buffer, md2_frame_t *frame, FTransform *pos, float scale)
{ {
DrawMD2i(gl_cmd_buffer, frame, 0, 0, NULL, pos, scale, false, NULL); DrawMD2Ex(gl_cmd_buffer, frame, 0, 0, NULL, pos, scale, false, NULL);
} }
// -----------------+ // -----------------+
// SetTransform : // SetTransform :
// -----------------+ // -----------------+

View File

@ -87,7 +87,7 @@ void HU_Init(void);
void HU_LoadGraphics(void); void HU_LoadGraphics(void);
// reset heads up when consoleplayer respawns. // reset heads up when consoleplayer respawns.
void HU_Start(void); FUNCMATH void HU_Start(void);
boolean HU_Responder(event_t *ev); boolean HU_Responder(event_t *ev);

View File

@ -56,7 +56,9 @@
//#define NONET //#define NONET
#endif #endif
#ifndef NONET #ifdef NONET
#undef HAVE_MINIUPNPC
#else
#ifdef USE_WINSOCK1 #ifdef USE_WINSOCK1
#include <winsock.h> #include <winsock.h>
#elif !defined (SCOUW2) && !defined (SCOUW7) && !defined (__OS2__) #elif !defined (SCOUW2) && !defined (SCOUW7) && !defined (__OS2__)

View File

@ -33,7 +33,7 @@ char sprnames[NUMSPRITES + 1][5] =
"BBUZ","JETF","EGGM","EGGN","TNKA","TNKB","SPNK","GOOP","EGGO","PRPL", "BBUZ","JETF","EGGM","EGGN","TNKA","TNKB","SPNK","GOOP","EGGO","PRPL",
"FAKE","EGGP","EFIR","EGGQ","EGGR","BRAK","BGOO","BMSL","EGGT","RCKT", "FAKE","EGGP","EFIR","EGGQ","EGGR","BRAK","BGOO","BMSL","EGGT","RCKT",
"ELEC","TARG","NPLM","MNPL","METL","MSCF","MSCB","RING","TRNG","EMMY", "ELEC","TARG","NPLM","MNPL","METL","MSCF","MSCB","RING","TRNG","EMMY",
"TOKE","RFLG","BFLG","NWNG","EMBM","CEMG","EMER","FANS","BUBL","SIGN", "TOKE","RFLG","BFLG","NWNG","EMBM","CEMG","EMER","FANS","BBLS","SIGN",
"STEM","SPIK","SFLM","USPK","STPT","BMNE","SRBX","RRBX","BRBX","SHTV", "STEM","SPIK","SFLM","USPK","STPT","BMNE","SRBX","RRBX","BRBX","SHTV",
"PINV","YLTV","BLTV","BKTV","WHTV","GRTV","ELTV","EGGB","MIXU","RECY", "PINV","YLTV","BLTV","BKTV","WHTV","GRTV","ELTV","EGGB","MIXU","RECY",
"QUES","GBTV","PRUP","PTTV","MTEX","MISL","TORP","ENRG","MINE","JBUL", "QUES","GBTV","PRUP","PTTV","MTEX","MISL","TORP","ENRG","MINE","JBUL",
@ -43,17 +43,17 @@ char sprnames[NUMSPRITES + 1][5] =
"DFLM","XMS1","XMS2","XMS3","BSZ1","BSZ2","BSZ3","BSZ4","BSZ5","BSZ6", "DFLM","XMS1","XMS2","XMS3","BSZ1","BSZ2","BSZ3","BSZ4","BSZ5","BSZ6",
"BSZ7","BSZ8","STLG","DBAL","RCRY","ARMA","ARMF","ARMB","WIND","MAGN", "BSZ7","BSZ8","STLG","DBAL","RCRY","ARMA","ARMF","ARMB","WIND","MAGN",
"ELEM","FORC","PITY","IVSP","SSPK","GOAL","BIRD","BUNY","MOUS","CHIC", "ELEM","FORC","PITY","IVSP","SSPK","GOAL","BIRD","BUNY","MOUS","CHIC",
"COWZ","RBRD","SPRY","SPRR","SPRB","YSPR","RSPR","RAIN","SNO1","SPLH", "COWZ","RBRD","SPRY","SPRR","SPRB","YSPR","RSPR","SSWY","SSWR","SSWB",
"SPLA","SMOK","BUBP","BUBO","BUBN","BUBM","POPP","TFOG","SEED","PRTL", "RAIN","SNO1","SPLH","SPLA","SMOK","BUBL","WZAP","TFOG","SEED","PRTL",
"SCOR","DRWN","TTAG","GFLG","RRNG","RNGB","RNGR","RNGI","RNGA","RNGE", "SCOR","DRWN","TTAG","GFLG","RRNG","RNGB","RNGR","RNGI","RNGA","RNGE",
"RNGS","RNGG","PIKB","PIKR","PIKA","PIKE","PIKS","PIKG","TAUT","TGRE", "RNGS","RNGG","PIKB","PIKR","PIKA","PIKE","PIKS","PIKG","TAUT","TGRE",
"TSCR","COIN","CPRK","GOOM","BGOM","FFWR","FBLL","SHLL","PUMA","HAMM", "TSCR","COIN","CPRK","GOOM","BGOM","FFWR","FBLL","SHLL","PUMA","HAMM",
"KOOP","BFLM","MAXE","MUS1","MUS2","TOAD","NDRN","SUPE","SUPZ","NDRL", "KOOP","BFLM","MAXE","MUS1","MUS2","TOAD","NDRN","NSPK","NBMP","HOOP",
"NSPK","NBMP","HOOP","NSCR","NPRU","CAPS","SUPT","SPRK","BOM1","BOM2", "NSCR","NPRU","CAPS","SPRK","BOM1","BOM2","BOM3","BOM4","ROIA","ROIB",
"BOM3","BOM4","ROIA","ROIB","ROIC","ROID","ROIE","ROIF","ROIG","ROIH", "ROIC","ROID","ROIE","ROIF","ROIG","ROIH","ROII","ROIJ","ROIK","ROIL",
"ROII","ROIJ","ROIK","ROIL","ROIM","ROIN","ROIO","ROIP","BBAL","GWLG", "ROIM","ROIN","ROIO","ROIP","BBAL","GWLG","GWLR","SRBA","SRBB","SRBC",
"GWLR","SRBA","SRBB","SRBC","SRBD","SRBE","SRBF","SRBG","SRBH","SRBI", "SRBD","SRBE","SRBF","SRBG","SRBH","SRBI","SRBJ","SRBK","SRBL","SRBM",
"SRBJ","SRBK","SRBL","SRBM","SRBN","SRBO", "SRBN","SRBO",
}; };
char spr2names[NUMPLAYERSPRITES][5] = char spr2names[NUMPLAYERSPRITES][5] =
@ -62,6 +62,7 @@ char spr2names[NUMPLAYERSPRITES][5] =
"WAIT", "WAIT",
"WALK", "WALK",
"RUN_", "RUN_",
"PEEL",
"PAIN", "PAIN",
"DEAD", "DEAD",
"DRWN", "DRWN",
@ -78,18 +79,24 @@ char spr2names[NUMPLAYERSPRITES][5] =
"LIFE", "LIFE",
"FLY_", "FLY_",
"SWIM",
"TIRE", "TIRE",
"GLID", "GLID",
"CLNG", "CLNG",
"CLMB", "CLMB",
"TWIN",
"MLEE",
"TRNS", "TRNS",
"SSTD", "SSTD",
"SWLK", "SWLK",
"SRUN", "SRUN",
"SPEE",
"SPAN", "SPAN",
"SMSL", "SSTN",
"SDTH", "SDTH",
"SDRN", "SDRN",
"SSPN", "SSPN",
@ -99,8 +106,44 @@ char spr2names[NUMPLAYERSPRITES][5] =
"SFAL", "SFAL",
"SEDG", "SEDG",
"SRID", "SRID",
"SFLT" "SFLT",
"NTRN",
"NSTD",
"NFLT",
"NPAN",
"NPUL",
"NATK",
"NGT0",
"NGT1",
"NGT2",
"NGT3",
"NGT4",
"NGT5",
"NGT6",
"NGT7",
"NGT8",
"NGT9",
"NGTA",
"NGTB",
"NGTC",
"DRL0",
"DRL1",
"DRL2",
"DRL3",
"DRL4",
"DRL5",
"DRL6",
"DRL7",
"DRL8",
"DRL9",
"DRLA",
"DRLB",
"DRLC"
}; };
enum playersprite free_spr2 = SPR2_FIRSTFREESLOT;
// Doesn't work with g++, needs actionf_p1 (don't modify this comment) // Doesn't work with g++, needs actionf_p1 (don't modify this comment)
state_t states[NUMSTATES] = state_t states[NUMSTATES] =
@ -132,6 +175,7 @@ state_t states[NUMSTATES] =
{SPR_PLAY, SPR2_WAIT, 16, {NULL}, 0, 0, S_PLAY_WAIT}, // S_PLAY_WAIT {SPR_PLAY, SPR2_WAIT, 16, {NULL}, 0, 0, S_PLAY_WAIT}, // S_PLAY_WAIT
{SPR_PLAY, SPR2_WALK, 4, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_WALK {SPR_PLAY, SPR2_WALK, 4, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_WALK
{SPR_PLAY, SPR2_RUN , 2, {NULL}, 0, 0, S_PLAY_RUN}, // S_PLAY_RUN {SPR_PLAY, SPR2_RUN , 2, {NULL}, 0, 0, S_PLAY_RUN}, // S_PLAY_RUN
{SPR_PLAY, SPR2_PEEL, 2, {NULL}, 0, 0, S_PLAY_PEEL}, // S_PLAY_PEEL
{SPR_PLAY, SPR2_PAIN, 350, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_PAIN {SPR_PLAY, SPR2_PAIN, 350, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_PAIN
{SPR_PLAY, SPR2_DEAD, 4, {NULL}, 0, 0, S_PLAY_DEAD}, // S_PLAY_DEAD {SPR_PLAY, SPR2_DEAD, 4, {NULL}, 0, 0, S_PLAY_DEAD}, // S_PLAY_DEAD
{SPR_PLAY, SPR2_DRWN, 4, {NULL}, 0, 0, S_PLAY_DRWN}, // S_PLAY_DRWN {SPR_PLAY, SPR2_DRWN, 4, {NULL}, 0, 0, S_PLAY_DRWN}, // S_PLAY_DRWN
@ -144,21 +188,30 @@ state_t states[NUMSTATES] =
{SPR_PLAY, SPR2_EDGE, 12, {NULL}, 0, 0, S_PLAY_EDGE}, // S_PLAY_EDGE {SPR_PLAY, SPR2_EDGE, 12, {NULL}, 0, 0, S_PLAY_EDGE}, // S_PLAY_EDGE
{SPR_PLAY, SPR2_RIDE, 4, {NULL}, 0, 0, S_PLAY_RIDE}, // S_PLAY_RIDE {SPR_PLAY, SPR2_RIDE, 4, {NULL}, 0, 0, S_PLAY_RIDE}, // S_PLAY_RIDE
// Tails abilities // CA_FLY/CA_SWIM
{SPR_PLAY, SPR2_FLY , 2, {NULL}, 0, 0, S_PLAY_FLY}, // S_PLAY_FLY {SPR_PLAY, SPR2_FLY , 2, {NULL}, 0, 0, S_PLAY_FLY}, // S_PLAY_FLY
{SPR_PLAY, SPR2_SWIM, 2, {NULL}, 0, 0, S_PLAY_SWIM}, // S_PLAY_SWIM
{SPR_PLAY, SPR2_TIRE, 12, {NULL}, 0, 0, S_PLAY_FLY_TIRED}, // S_PLAY_FLY_TIRED {SPR_PLAY, SPR2_TIRE, 12, {NULL}, 0, 0, S_PLAY_FLY_TIRED}, // S_PLAY_FLY_TIRED
// Knuckles abilities // CA_GLIDEANDCLIMB
{SPR_PLAY, SPR2_GLID, 2, {NULL}, 0, 0, S_PLAY_GLIDE}, // S_PLAY_GLIDE {SPR_PLAY, SPR2_GLID, 2, {NULL}, 0, 0, S_PLAY_GLIDE}, // S_PLAY_GLIDE
{SPR_PLAY, SPR2_CLNG, 6, {NULL}, 0, 0, S_PLAY_CLING}, // S_PLAY_CLING {SPR_PLAY, SPR2_CLNG, 6, {NULL}, 0, 0, S_PLAY_CLING}, // S_PLAY_CLING
{SPR_PLAY, SPR2_CLMB, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB {SPR_PLAY, SPR2_CLMB, 5, {NULL}, 0, 0, S_PLAY_CLIMB}, // S_PLAY_CLIMB
// Super Sonic // CA_TWINSPIN
{SPR_PLAY, SPR2_TWIN|FF_SPR2ENDSTATE, 1, {NULL}, S_PLAY_JUMP, 0, S_PLAY_TWINSPIN}, // S_PLAY_TWINSPIN
// CA2_MELEE
{SPR_PLAY, SPR2_MLEE|FF_SPR2ENDSTATE, 1, {NULL}, S_PLAY_MELEE_FINISH, 0, S_PLAY_MELEE}, // S_PLAY_MELEE
{SPR_PLAY, SPR2_MLEE, 20, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_MELEE_FINISH
// SF_SUPERANIMS
{SPR_PLAY, SPR2_SSTD, 7, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STND {SPR_PLAY, SPR2_SSTD, 7, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STND
{SPR_PLAY, SPR2_SWLK, 7, {NULL}, 0, 0, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_WALK {SPR_PLAY, SPR2_SWLK, 7, {NULL}, 0, 0, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_WALK
{SPR_PLAY, SPR2_SRUN, 7, {NULL}, 0, 0, S_PLAY_SUPER_RUN}, // S_PLAY_SUPER_RUN {SPR_PLAY, SPR2_SRUN, 7, {NULL}, 0, 0, S_PLAY_SUPER_RUN}, // S_PLAY_SUPER_RUN
{SPR_PLAY, SPR2_SPEE, 7, {NULL}, 0, 0, S_PLAY_SUPER_PEEL}, // S_PLAY_SUPER_PEEL
{SPR_PLAY, SPR2_SPAN, -1, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_PAIN {SPR_PLAY, SPR2_SPAN, -1, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_PAIN
{SPR_PLAY, SPR2_SMSL, -1, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STUN {SPR_PLAY, SPR2_SSTN, -1, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STUN
{SPR_PLAY, SPR2_SDTH, 4, {NULL}, 0, 0, S_PLAY_SUPER_DEAD}, // S_PLAY_SUPER_DEAD {SPR_PLAY, SPR2_SDTH, 4, {NULL}, 0, 0, S_PLAY_SUPER_DEAD}, // S_PLAY_SUPER_DEAD
{SPR_PLAY, SPR2_SDRN, 4, {NULL}, 0, 0, S_PLAY_SUPER_DRWN}, // S_PLAY_SUPER_DRWN {SPR_PLAY, SPR2_SDRN, 4, {NULL}, 0, 0, S_PLAY_SUPER_DRWN}, // S_PLAY_SUPER_DRWN
{SPR_PLAY, SPR2_SSPN, 1, {NULL}, 0, 0, S_PLAY_SUPER_SPIN}, // S_PLAY_SUPER_SPIN {SPR_PLAY, SPR2_SSPN, 1, {NULL}, 0, 0, S_PLAY_SUPER_SPIN}, // S_PLAY_SUPER_SPIN
@ -170,16 +223,16 @@ state_t states[NUMSTATES] =
{SPR_PLAY, SPR2_SRID, 4, {NULL}, 0, 0, S_PLAY_SUPER_RIDE}, // S_PLAY_SUPER_RIDE {SPR_PLAY, SPR2_SRID, 4, {NULL}, 0, 0, S_PLAY_SUPER_RIDE}, // S_PLAY_SUPER_RIDE
{SPR_PLAY, SPR2_SFLT, 7, {NULL}, 0, 0, S_PLAY_SUPER_FLOAT}, // S_PLAY_SUPER_FLOAT {SPR_PLAY, SPR2_SFLT, 7, {NULL}, 0, 0, S_PLAY_SUPER_FLOAT}, // S_PLAY_SUPER_FLOAT
// Transforming into Super // SF_SUPER
{SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS2}, // S_PLAY_SUPER_TRANS {SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS2}, // S_PLAY_SUPER_TRANS
{SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS3}, // S_PLAY_SUPER_TRANS2 {SPR_PLAY, SPR2_TRNS, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS3}, // S_PLAY_SUPER_TRANS2
{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS4}, // S_PLAY_SUPER_TRANS3 {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS4}, // S_PLAY_SUPER_TRANS3
{SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS5}, // S_PLAY_SUPER_TRANS4 {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS5}, // S_PLAY_SUPER_TRANS4
{SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS6}, // S_PLAY_SUPER_TRANS5 {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS6}, // S_PLAY_SUPER_TRANS5
{SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS7}, // S_PLAY_SUPER_TRANS6 {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS7}, // S_PLAY_SUPER_TRANS6
{SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS8}, // S_PLAY_SUPER_TRANS7 {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS8}, // S_PLAY_SUPER_TRANS7
{SPR_PLAY, SPR2_TRNS, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS9}, // S_PLAY_SUPER_TRANS8 {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS9}, // S_PLAY_SUPER_TRANS8
{SPR_PLAY, SPR2_TRNS, 16, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_SUPER_TRANS9 {SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 16, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_SUPER_TRANS9
{SPR_NULL, 0, -1, {NULL}, 0, 0, S_OBJPLACE_DUMMY}, //S_OBJPLACE_DUMMY {SPR_NULL, 0, -1, {NULL}, 0, 0, S_OBJPLACE_DUMMY}, //S_OBJPLACE_DUMMY
@ -193,6 +246,52 @@ state_t states[NUMSTATES] =
// Level end sign (uses player sprite) // Level end sign (uses player sprite)
{SPR_PLAY, SPR2_SIGN, 1, {NULL}, 0, 24, S_PLAY_SIGN}, // S_PLAY_SIGN {SPR_PLAY, SPR2_SIGN, 1, {NULL}, 0, 24, S_PLAY_SIGN}, // S_PLAY_SIGN
// NiGHTS Player, transforming
{SPR_PLAY, SPR2_NTRN, 4, {A_Scream}, 0, 0, S_PLAY_NIGHTS_TRANS2}, // S_PLAY_NIGHTS_TRANS
{SPR_PLAY, SPR2_NTRN, 4, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS3}, // S_PLAY_NIGHTS_TRANS2
{SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT, 4, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS4}, // S_PLAY_NIGHTS_TRANS3
{SPR_PLAY, SPR2_NTRN, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS5}, // S_PLAY_NIGHTS_TRANS4
{SPR_PLAY, SPR2_NTRN, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS6}, // S_PLAY_NIGHTS_TRANS5
{SPR_PLAY, SPR2_NTRN, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS7}, // S_PLAY_NIGHTS_TRANS6
{SPR_PLAY, SPR2_NTRN, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS8}, // S_PLAY_NIGHTS_TRANS7
{SPR_PLAY, SPR2_NTRN, 3, {NULL}, 0, 0, S_PLAY_NIGHTS_TRANS9}, // S_PLAY_NIGHTS_TRANS8
{SPR_PLAY, SPR2_NTRN, 16, {NULL}, 0, 0, S_PLAY_NIGHTS_FLOAT}, // S_PLAY_NIGHTS_TRANS9
// NiGHTS Player, Stand, Floating, Pain, Pull and Attack
{SPR_PLAY, SPR2_NSTD, 7, {NULL}, 0, 0, S_PLAY_NIGHTS_STAND}, // S_PLAY_NIGHTS_STAND
{SPR_PLAY, SPR2_NFLT, 7, {NULL}, 0, 0, S_PLAY_NIGHTS_FLOAT}, // S_PLAY_NIGHTS_FLOAT
{SPR_PLAY, SPR2_NPAN, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_PAIN}, // S_PLAY_NIGHTS_PAIN
{SPR_PLAY, SPR2_NPUL, 1, {NULL}, 0, 0, S_PLAY_NIGHTS_PULL}, // S_PLAY_NIGHTS_PULL
{SPR_PLAY, SPR2_NATK, 1, {NULL}, 0, 0, S_PLAY_NIGHTS_ATTACK}, // S_PLAY_NIGHTS_ATTACK
// NiGHTS Player, Flying and Drilling
{SPR_PLAY, SPR2_NGT0, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY0}, // S_PLAY_NIGHTS_FLY0
{SPR_PLAY, SPR2_DRL0, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL0}, // S_PLAY_NIGHTS_DRILL0
{SPR_PLAY, SPR2_NGT1, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY1}, // S_PLAY_NIGHTS_FLY1
{SPR_PLAY, SPR2_DRL1, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL1}, // S_PLAY_NIGHTS_DRILL1
{SPR_PLAY, SPR2_NGT2, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY2}, // S_PLAY_NIGHTS_FLY2
{SPR_PLAY, SPR2_DRL2, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL2}, // S_PLAY_NIGHTS_DRILL2
{SPR_PLAY, SPR2_NGT3, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY3}, // S_PLAY_NIGHTS_FLY3
{SPR_PLAY, SPR2_DRL3, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL3}, // S_PLAY_NIGHTS_DRILL3
{SPR_PLAY, SPR2_NGT4, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY4}, // S_PLAY_NIGHTS_FLY4
{SPR_PLAY, SPR2_DRL4, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL4}, // S_PLAY_NIGHTS_DRILL4
{SPR_PLAY, SPR2_NGT5, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY5}, // S_PLAY_NIGHTS_FLY5
{SPR_PLAY, SPR2_DRL5, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL5}, // S_PLAY_NIGHTS_DRILL5
{SPR_PLAY, SPR2_NGT6, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY6}, // S_PLAY_NIGHTS_FLY6
{SPR_PLAY, SPR2_DRL6, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL6}, // S_PLAY_NIGHTS_DRILL6
{SPR_PLAY, SPR2_NGT7, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY7}, // S_PLAY_NIGHTS_FLY7
{SPR_PLAY, SPR2_DRL7, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL7}, // S_PLAY_NIGHTS_DRILL7
{SPR_PLAY, SPR2_NGT8, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY8}, // S_PLAY_NIGHTS_FLY8
{SPR_PLAY, SPR2_DRL8, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL8}, // S_PLAY_NIGHTS_DRILL8
{SPR_PLAY, SPR2_NGT9, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY9}, // S_PLAY_NIGHTS_FLY9
{SPR_PLAY, SPR2_DRL9, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL9}, // S_PLAY_NIGHTS_DRILL9
{SPR_PLAY, SPR2_NGTA, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYA}, // S_PLAY_NIGHTS_FLYA
{SPR_PLAY, SPR2_DRLA, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLA}, // S_PLAY_NIGHTS_DRILLA
{SPR_PLAY, SPR2_NGTB, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYB}, // S_PLAY_NIGHTS_FLYB
{SPR_PLAY, SPR2_DRLB, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLB}, // S_PLAY_NIGHTS_DRILLB
{SPR_PLAY, SPR2_NGTC, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYC}, // S_PLAY_NIGHTS_FLYC
{SPR_PLAY, SPR2_DRLC, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLC}, // S_PLAY_NIGHTS_DRILLC
// Blue Crawla // Blue Crawla
{SPR_POSS, 0, 5, {A_Look}, 0, 0, S_POSS_STND}, // S_POSS_STND {SPR_POSS, 0, 5, {A_Look}, 0, 0, S_POSS_STND}, // S_POSS_STND
{SPR_POSS, 0, 3, {A_Chase}, 0, 0, S_POSS_RUN2}, // S_POSS_RUN1 {SPR_POSS, 0, 3, {A_Chase}, 0, 0, S_POSS_RUN2}, // S_POSS_RUN1
@ -1045,8 +1144,10 @@ state_t states[NUMSTATES] =
{SPR_FANS, 4, 1, {A_FanBubbleSpawn}, 512, 0, S_FAN}, // S_FAN5 {SPR_FANS, 4, 1, {A_FanBubbleSpawn}, 512, 0, S_FAN}, // S_FAN5
// Bubble Source // Bubble Source
{SPR_BUBL, 0, 8, {A_BubbleSpawn}, 2048, 0, S_BUBBLES2}, // S_BUBBLES1 {SPR_BBLS, 0, 8, {A_BubbleSpawn}, 2048, 0, S_BUBBLES2}, // S_BUBBLES1
{SPR_BUBL, 1, 8, {A_BubbleCheck}, 0, 0, S_BUBBLES1}, // S_BUBBLES2 {SPR_BBLS, 1, 8, {A_BubbleCheck}, 0, 0, S_BUBBLES3}, // S_BUBBLES2
{SPR_BBLS, 2, 8, {A_BubbleSpawn}, 2048, 0, S_BUBBLES4}, // S_BUBBLES3
{SPR_BBLS, 3, 8, {A_BubbleCheck}, 0, 0, S_BUBBLES1}, // S_BUBBLES4
// Level End Sign // Level End Sign
{SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN2}, // S_SIGN1 {SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN2}, // S_SIGN1
@ -1853,6 +1954,36 @@ state_t states[NUMSTATES] =
{SPR_RSPR, 2, 1, {NULL}, 0, 0, S_RDIAG8}, // S_RDIAG7 {SPR_RSPR, 2, 1, {NULL}, 0, 0, S_RDIAG8}, // S_RDIAG7
{SPR_RSPR, 1, 1, {NULL}, 0, 0, S_RDIAG1}, // S_RDIAG8 {SPR_RSPR, 1, 1, {NULL}, 0, 0, S_RDIAG1}, // S_RDIAG8
// Yellow Side Spring
{SPR_SSWY, 0, -1, {NULL}, 0, 0, S_NULL}, // S_YHORIZ1
{SPR_SSWY, 1, 1, {A_Pain}, 0, 0, S_YHORIZ3}, // S_YHORIZ2
{SPR_SSWY, 2, 1, {NULL}, 0, 0, S_YHORIZ4}, // S_YHORIZ3
{SPR_SSWY, 3, 1, {NULL}, 0, 0, S_YHORIZ5}, // S_YHORIZ4
{SPR_SSWY, 4, 1, {NULL}, 0, 0, S_YHORIZ6}, // S_YHORIZ5
{SPR_SSWY, 3, 1, {NULL}, 0, 0, S_YHORIZ7}, // S_YHORIZ6
{SPR_SSWY, 2, 1, {NULL}, 0, 0, S_YHORIZ8}, // S_YHORIZ7
{SPR_SSWY, 1, 1, {NULL}, 0, 0, S_YHORIZ1}, // S_YHORIZ8
// Red Side Spring
{SPR_SSWR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_RHORIZ1
{SPR_SSWR, 1, 1, {A_Pain}, 0, 0, S_RHORIZ3}, // S_RHORIZ2
{SPR_SSWR, 2, 1, {NULL}, 0, 0, S_RHORIZ4}, // S_RHORIZ3
{SPR_SSWR, 3, 1, {NULL}, 0, 0, S_RHORIZ5}, // S_RHORIZ4
{SPR_SSWR, 4, 1, {NULL}, 0, 0, S_RHORIZ6}, // S_RHORIZ5
{SPR_SSWR, 3, 1, {NULL}, 0, 0, S_RHORIZ7}, // S_RHORIZ6
{SPR_SSWR, 2, 1, {NULL}, 0, 0, S_RHORIZ8}, // S_RHORIZ7
{SPR_SSWR, 1, 1, {NULL}, 0, 0, S_RHORIZ1}, // S_RHORIZ8
// Blue Side Spring
{SPR_SSWB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BHORIZ1
{SPR_SSWB, 1, 1, {A_Pain}, 0, 0, S_BHORIZ3}, // S_BHORIZ2
{SPR_SSWB, 2, 1, {NULL}, 0, 0, S_BHORIZ4}, // S_BHORIZ3
{SPR_SSWB, 3, 1, {NULL}, 0, 0, S_BHORIZ5}, // S_BHORIZ4
{SPR_SSWB, 4, 1, {NULL}, 0, 0, S_BHORIZ6}, // S_BHORIZ5
{SPR_SSWB, 3, 1, {NULL}, 0, 0, S_BHORIZ7}, // S_BHORIZ6
{SPR_SSWB, 2, 1, {NULL}, 0, 0, S_BHORIZ8}, // S_BHORIZ7
{SPR_SSWB, 1, 1, {NULL}, 0, 0, S_BHORIZ1}, // S_BHORIZ8
// Rain // Rain
{SPR_RAIN, FF_TRANS50, -1, {NULL}, 0, 0, S_NULL}, // S_RAIN1 {SPR_RAIN, FF_TRANS50, -1, {NULL}, 0, 0, S_NULL}, // S_RAIN1
{SPR_RAIN, FF_TRANS50, 1, {NULL}, 0, 0, S_RAIN1}, // S_RAINRETURN {SPR_RAIN, FF_TRANS50, 1, {NULL}, 0, 0, S_RAIN1}, // S_RAINRETURN
@ -1886,17 +2017,18 @@ state_t states[NUMSTATES] =
{SPR_SMOK, FF_TRANS50|4, 8, {NULL}, 0, 0, S_NULL}, // S_SMOKE5 {SPR_SMOK, FF_TRANS50|4, 8, {NULL}, 0, 0, S_NULL}, // S_SMOKE5
// Bubbles // Bubbles
{SPR_BUBP, FF_TRANS50, 1, {A_BubbleRise}, 0, 1024, S_SMALLBUBBLE1}, // S_SMALLBUBBLE {SPR_BUBL, FF_TRANS50, 1, {A_BubbleRise}, 0, 1024, S_SMALLBUBBLE}, // S_SMALLBUBBLE
{SPR_BUBP, FF_TRANS50, 1, {A_BubbleRise}, 0, 1024, S_SMALLBUBBLE}, // S_SMALLBUBBLE1 {SPR_BUBL, FF_TRANS50|1, 1, {A_BubbleRise}, 0, 1024, S_MEDIUMBUBBLE}, // S_MEDIUMBUBBLE
{SPR_BUBO, FF_TRANS50, 1, {A_BubbleRise}, 0, 1024, S_MEDIUMBUBBLE1}, // S_MEDIUMBUBBLE
{SPR_BUBO, FF_TRANS50, 1, {A_BubbleRise}, 0, 1024, S_MEDIUMBUBBLE}, // S_MEDIUMBUBBLE1
// Extra Large Bubble (breathable) // Extra Large Bubble (breathable)
{SPR_BUBN, FF_TRANS50|FF_FULLBRIGHT, 16, {A_BubbleRise}, 0, 1024, S_EXTRALARGEBUBBLE}, // S_LARGEBUBBLE {SPR_BUBL, FF_TRANS50|FF_FULLBRIGHT|2, 8, {A_BubbleRise}, 0, 1024, S_LARGEBUBBLE2}, // S_LARGEBUBBLE1
{SPR_BUBM, FF_TRANS50|FF_FULLBRIGHT, 16, {A_BubbleRise}, 0, 1024, S_EXTRALARGEBUBBLE}, // S_EXTRALARGEBUBBLE {SPR_BUBL, FF_TRANS50|FF_FULLBRIGHT|3, 8, {A_BubbleRise}, 0, 1024, S_EXTRALARGEBUBBLE}, // S_LARGEBUBBLE2
{SPR_BUBL, FF_TRANS50|FF_FULLBRIGHT|4, 16, {A_BubbleRise}, 0, 1024, S_EXTRALARGEBUBBLE}, // S_EXTRALARGEBUBBLE
// Extra Large Bubble goes POP! // Extra Large Bubble goes POP!
{SPR_POPP, 0, 16, {NULL}, 0, 0, S_NULL}, // S_POP1 {SPR_BUBL, 5, 16, {NULL}, 0, 0, S_NULL}, // S_POP1
{SPR_WZAP, FF_TRANS10|FF_ANIMATE|FF_MIDDLESTARTCHANCE, 4, {NULL}, 3, 2, S_NULL}, // S_WATERZAP
{SPR_TFOG, FF_FULLBRIGHT|FF_TRANS50, 2, {NULL}, 0, 0, S_FOG2}, // S_FOG1 {SPR_TFOG, FF_FULLBRIGHT|FF_TRANS50, 2, {NULL}, 0, 0, S_FOG2}, // S_FOG1
{SPR_TFOG, FF_FULLBRIGHT|FF_TRANS50|1, 2, {NULL}, 0, 0, S_FOG3}, // S_FOG2 {SPR_TFOG, FF_FULLBRIGHT|FF_TRANS50|1, 2, {NULL}, 0, 0, S_FOG3}, // S_FOG2
@ -1940,6 +2072,13 @@ state_t states[NUMSTATES] =
{SPR_DRWN, 4, 40, {NULL}, 0, 0, S_NULL}, // S_FOUR1 {SPR_DRWN, 4, 40, {NULL}, 0, 0, S_NULL}, // S_FOUR1
{SPR_DRWN, 5, 40, {NULL}, 0, 0, S_NULL}, // S_FIVE1 {SPR_DRWN, 5, 40, {NULL}, 0, 0, S_NULL}, // S_FIVE1
{SPR_DRWN, 6, 40, {NULL}, 0, 0, S_NULL}, // S_ZERO2
{SPR_DRWN, 7, 40, {NULL}, 0, 0, S_NULL}, // S_ONE2
{SPR_DRWN, 8, 40, {NULL}, 0, 0, S_NULL}, // S_TWO2
{SPR_DRWN, 9, 40, {NULL}, 0, 0, S_NULL}, // S_THREE2
{SPR_DRWN, 10, 40, {NULL}, 0, 0, S_NULL}, // S_FOUR2
{SPR_DRWN, 11, 40, {NULL}, 0, 0, S_NULL}, // S_FIVE2
{SPR_TTAG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_TTAG1 {SPR_TTAG, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_NULL}, // S_TTAG1
// CTF Sign // CTF Sign
@ -2212,96 +2351,6 @@ state_t states[NUMSTATES] =
{SPR_GOAL, 2, 4, {NULL}, 0, 0, S_NIGHTSGOAL4}, // S_NIGHTSGOAL3 {SPR_GOAL, 2, 4, {NULL}, 0, 0, S_NIGHTSGOAL4}, // S_NIGHTSGOAL3
{SPR_GOAL, 3, 4, {NULL}, 0, 0, S_NIGHTSGOAL1}, // S_NIGHTSGOAL4 {SPR_GOAL, 3, 4, {NULL}, 0, 0, S_NIGHTSGOAL1}, // S_NIGHTSGOAL4
// Nights Player, Flying and Drilling
{SPR_SUPE, 0, 1, {NULL}, 0, 0, S_NIGHTSFLY1B}, // S_NIGHTSFLY1A
{SPR_SUPE, 1, 1, {NULL}, 0, 0, S_NIGHTSFLY1A}, // S_NIGHTSFLY1B
{SPR_NDRL, 0, 2, {NULL}, 0, 0, S_NIGHTSDRILL1B}, // S_NIGHTSDRILL1A
{SPR_NDRL, 1, 2, {NULL}, 0, 0, S_NIGHTSDRILL1C}, // S_NIGHTSDRILL1B
{SPR_NDRL, 2, 2, {NULL}, 0, 0, S_NIGHTSDRILL1D}, // S_NIGHTSDRILL1C
{SPR_NDRL, 3, 2, {NULL}, 0, 0, S_NIGHTSDRILL1A}, // S_NIGHTSDRILL1D
{SPR_SUPE, 2, 1, {NULL}, 0, 0, S_NIGHTSFLY2B}, // S_NIGHTSFLY2A
{SPR_SUPE, 3, 1, {NULL}, 0, 0, S_NIGHTSFLY2A}, // S_NIGHTSFLY2B
{SPR_NDRL, 4, 2, {NULL}, 0, 0, S_NIGHTSDRILL2B}, // S_NIGHTSDRILL2A
{SPR_NDRL, 5, 2, {NULL}, 0, 0, S_NIGHTSDRILL2C}, // S_NIGHTSDRILL2B
{SPR_NDRL, 6, 2, {NULL}, 0, 0, S_NIGHTSDRILL2D}, // S_NIGHTSDRILL2C
{SPR_NDRL, 7, 2, {NULL}, 0, 0, S_NIGHTSDRILL2A}, // S_NIGHTSDRILL2D
{SPR_SUPE, 4, 1, {NULL}, 0, 0, S_NIGHTSFLY3B}, // S_NIGHTSFLY3A
{SPR_SUPE, 5, 1, {NULL}, 0, 0, S_NIGHTSFLY3A}, // S_NIGHTSFLY3B
{SPR_NDRL, 8, 2, {NULL}, 0, 0, S_NIGHTSDRILL3B}, // S_NIGHTSDRILL3A
{SPR_NDRL, 9, 2, {NULL}, 0, 0, S_NIGHTSDRILL3C}, // S_NIGHTSDRILL3B
{SPR_NDRL, 10, 2, {NULL}, 0, 0, S_NIGHTSDRILL3D}, // S_NIGHTSDRILL3C
{SPR_NDRL, 11, 2, {NULL}, 0, 0, S_NIGHTSDRILL3A}, // S_NIGHTSDRILL3D
{SPR_SUPE, 6, 1, {NULL}, 0, 0, S_NIGHTSFLY4B}, // S_NIGHTSFLY4A
{SPR_SUPE, 7, 1, {NULL}, 0, 0, S_NIGHTSFLY4A}, // S_NIGHTSFLY4B
{SPR_NDRL, 12, 2, {NULL}, 0, 0, S_NIGHTSDRILL4B}, // S_NIGHTSDRILL4A
{SPR_NDRL, 13, 2, {NULL}, 0, 0, S_NIGHTSDRILL4C}, // S_NIGHTSDRILL4B
{SPR_NDRL, 14, 2, {NULL}, 0, 0, S_NIGHTSDRILL4D}, // S_NIGHTSDRILL4C
{SPR_NDRL, 15, 2, {NULL}, 0, 0, S_NIGHTSDRILL4A}, // S_NIGHTSDRILL4D
{SPR_SUPE, 8, 1, {NULL}, 0, 0, S_NIGHTSFLY5B}, // S_NIGHTSFLY5A
{SPR_SUPE, 9, 1, {NULL}, 0, 0, S_NIGHTSFLY5A}, // S_NIGHTSFLY5B
{SPR_NDRL, 16, 2, {NULL}, 0, 0, S_NIGHTSDRILL5B}, // S_NIGHTSDRILL5A
{SPR_NDRL, 17, 2, {NULL}, 0, 0, S_NIGHTSDRILL5C}, // S_NIGHTSDRILL5B
{SPR_NDRL, 18, 2, {NULL}, 0, 0, S_NIGHTSDRILL5D}, // S_NIGHTSDRILL5C
{SPR_NDRL, 19, 2, {NULL}, 0, 0, S_NIGHTSDRILL5A}, // S_NIGHTSDRILL5D
{SPR_SUPE, 10, 1, {NULL}, 0, 0, S_NIGHTSFLY6B}, // S_NIGHTSFLY6A
{SPR_SUPE, 11, 1, {NULL}, 0, 0, S_NIGHTSFLY6A}, // S_NIGHTSFLY6B
{SPR_NDRL, 20, 2, {NULL}, 0, 0, S_NIGHTSDRILL6B}, // S_NIGHTSDRILL6A
{SPR_NDRL, 21, 2, {NULL}, 0, 0, S_NIGHTSDRILL6C}, // S_NIGHTSDRILL6B
{SPR_NDRL, 22, 2, {NULL}, 0, 0, S_NIGHTSDRILL6D}, // S_NIGHTSDRILL6C
{SPR_NDRL, 23, 2, {NULL}, 0, 0, S_NIGHTSDRILL6A}, // S_NIGHTSDRILL6D
{SPR_SUPE, 12, 1, {NULL}, 0, 0, S_NIGHTSFLY7B}, // S_NIGHTSFLY7A
{SPR_SUPE, 13, 1, {NULL}, 0, 0, S_NIGHTSFLY7A}, // S_NIGHTSFLY7B
{SPR_NDRL, 24, 2, {NULL}, 0, 0, S_NIGHTSDRILL7B}, // S_NIGHTSDRILL7A
{SPR_NDRL, 25, 2, {NULL}, 0, 0, S_NIGHTSDRILL7C}, // S_NIGHTSDRILL7B
{SPR_NDRL, 26, 2, {NULL}, 0, 0, S_NIGHTSDRILL7D}, // S_NIGHTSDRILL7C
{SPR_NDRL, 27, 2, {NULL}, 0, 0, S_NIGHTSDRILL7A}, // S_NIGHTSDRILL7D
{SPR_SUPE, 14, 1, {NULL}, 0, 0, S_NIGHTSFLY8B}, // S_NIGHTSFLY8A
{SPR_SUPE, 15, 1, {NULL}, 0, 0, S_NIGHTSFLY8A}, // S_NIGHTSFLY8B
{SPR_NDRL, 28, 2, {NULL}, 0, 0, S_NIGHTSDRILL8B}, // S_NIGHTSDRILL8A
{SPR_NDRL, 29, 2, {NULL}, 0, 0, S_NIGHTSDRILL8C}, // S_NIGHTSDRILL8B
{SPR_NDRL, 30, 2, {NULL}, 0, 0, S_NIGHTSDRILL8D}, // S_NIGHTSDRILL8C
{SPR_NDRL, 31, 2, {NULL}, 0, 0, S_NIGHTSDRILL8A}, // S_NIGHTSDRILL8D
{SPR_SUPE, 16, 1, {NULL}, 0, 0, S_NIGHTSFLY9B}, // S_NIGHTSFLY9A
{SPR_SUPE, 17, 1, {NULL}, 0, 0, S_NIGHTSFLY9A}, // S_NIGHTSFLY9B
{SPR_NDRL, 32, 2, {NULL}, 0, 0, S_NIGHTSDRILL9B}, // S_NIGHTSDRILL9A
{SPR_NDRL, 33, 2, {NULL}, 0, 0, S_NIGHTSDRILL9C}, // S_NIGHTSDRILL9B
{SPR_NDRL, 34, 2, {NULL}, 0, 0, S_NIGHTSDRILL9D}, // S_NIGHTSDRILL9C
{SPR_NDRL, 35, 2, {NULL}, 0, 0, S_NIGHTSDRILL9A}, // S_NIGHTSDRILL9D
// Nights Player, Falling
{SPR_SUPZ, 0, 1, {NULL}, 0, 0, S_NIGHTSHURT2}, // S_NIGHTSHURT1
{SPR_SUPZ, 1, 1, {NULL}, 0, 0, S_NIGHTSHURT3}, // S_NIGHTSHURT2
{SPR_SUPZ, 2, 1, {NULL}, 0, 0, S_NIGHTSHURT4}, // S_NIGHTSHURT3
{SPR_SUPZ, 3, 1, {NULL}, 0, 0, S_NIGHTSHURT5}, // S_NIGHTSHURT4
{SPR_SUPZ, 4, 1, {NULL}, 0, 0, S_NIGHTSHURT6}, // S_NIGHTSHURT5
{SPR_SUPZ, 5, 1, {NULL}, 0, 0, S_NIGHTSHURT7}, // S_NIGHTSHURT6
{SPR_SUPZ, 6, 1, {NULL}, 0, 0, S_NIGHTSHURT8}, // S_NIGHTSHURT7
{SPR_SUPZ, 7, 1, {NULL}, 0, 0, S_NIGHTSHURT9}, // S_NIGHTSHURT8
{SPR_SUPZ, 8, 1, {NULL}, 0, 0, S_NIGHTSHURT10}, // S_NIGHTSHURT9
{SPR_SUPZ, 9, 1, {NULL}, 0, 0, S_NIGHTSHURT11}, // S_NIGHTSHURT10
{SPR_SUPZ, 10, 1, {NULL}, 0, 0, S_NIGHTSHURT12}, // S_NIGHTSHURT11
{SPR_SUPZ, 11, 1, {NULL}, 0, 0, S_NIGHTSHURT13}, // S_NIGHTSHURT12
{SPR_SUPZ, 12, 1, {NULL}, 0, 0, S_NIGHTSHURT14}, // S_NIGHTSHURT13
{SPR_SUPZ, 13, 1, {NULL}, 0, 0, S_NIGHTSHURT15}, // S_NIGHTSHURT14
{SPR_SUPZ, 14, 1, {NULL}, 0, 0, S_NIGHTSHURT16}, // S_NIGHTSHURT15
{SPR_SUPZ, 15, 1, {NULL}, 0, 0, S_NIGHTSHURT17}, // S_NIGHTSHURT16
{SPR_SUPZ, 0, 1, {NULL}, 0, 0, S_NIGHTSHURT18}, // S_NIGHTSHURT17
{SPR_SUPZ, 1, 1, {NULL}, 0, 0, S_NIGHTSHURT19}, // S_NIGHTSHURT18
{SPR_SUPZ, 2, 1, {NULL}, 0, 0, S_NIGHTSHURT20}, // S_NIGHTSHURT19
{SPR_SUPZ, 3, 1, {NULL}, 0, 0, S_NIGHTSHURT21}, // S_NIGHTSHURT20
{SPR_SUPZ, 4, 1, {NULL}, 0, 0, S_NIGHTSHURT22}, // S_NIGHTSHURT21
{SPR_SUPZ, 5, 1, {NULL}, 0, 0, S_NIGHTSHURT23}, // S_NIGHTSHURT22
{SPR_SUPZ, 6, 1, {NULL}, 0, 0, S_NIGHTSHURT24}, // S_NIGHTSHURT23
{SPR_SUPZ, 7, 1, {NULL}, 0, 0, S_NIGHTSHURT25}, // S_NIGHTSHURT24
{SPR_SUPZ, 8, 1, {NULL}, 0, 0, S_NIGHTSHURT26}, // S_NIGHTSHURT25
{SPR_SUPZ, 9, 1, {NULL}, 0, 0, S_NIGHTSHURT27}, // S_NIGHTSHURT26
{SPR_SUPZ, 10, 1, {NULL}, 0, 0, S_NIGHTSHURT28}, // S_NIGHTSHURT27
{SPR_SUPZ, 11, 1, {NULL}, 0, 0, S_NIGHTSHURT29}, // S_NIGHTSHURT28
{SPR_SUPZ, 12, 1, {NULL}, 0, 0, S_NIGHTSHURT30}, // S_NIGHTSHURT29
{SPR_SUPZ, 13, 1, {NULL}, 0, 0, S_NIGHTSHURT31}, // S_NIGHTSHURT30
{SPR_SUPZ, 14, 1, {NULL}, 0, 0, S_NIGHTSHURT32}, // S_NIGHTSHURT31
{SPR_SUPZ, 15, 1, {NULL}, 0, 0, S_NIGHTSFLY1A}, // S_NIGHTSHURT32
// Nights Sparkle // Nights Sparkle
{SPR_NSPK, FF_FULLBRIGHT, 140, {NULL}, 0, 0, S_NIGHTSPARKLE2}, // S_NIGHTSPARKLE1 {SPR_NSPK, FF_FULLBRIGHT, 140, {NULL}, 0, 0, S_NIGHTSPARKLE2}, // S_NIGHTSPARKLE1
{SPR_NSPK, FF_FULLBRIGHT|1, 7, {NULL}, 0, 0, S_NIGHTSPARKLE3}, // S_NIGHTSPARKLE2 {SPR_NSPK, FF_FULLBRIGHT|1, 7, {NULL}, 0, 0, S_NIGHTSPARKLE3}, // S_NIGHTSPARKLE2
@ -2404,16 +2453,6 @@ state_t states[NUMSTATES] =
{SPR_NULL, 0, 35, {NULL}, 0, 0, S_CRUMBLE2}, // S_CRUMBLE1 {SPR_NULL, 0, 35, {NULL}, 0, 0, S_CRUMBLE2}, // S_CRUMBLE1
{SPR_NULL, 0, 105, {A_Scream}, 0, 0, S_NULL}, // S_CRUMBLE2 {SPR_NULL, 0, 105, {A_Scream}, 0, 0, S_NULL}, // S_CRUMBLE2
{SPR_SUPT, 0, 4, {A_Scream}, 0, 0, S_SUPERTRANS2}, // S_SUPERTRANS1
{SPR_SUPT, 1, 4, {NULL}, 0, 0, S_SUPERTRANS3}, // S_SUPERTRANS2
{SPR_SUPT, FF_FULLBRIGHT|2, 4, {NULL}, 0, 0, S_SUPERTRANS4}, // S_SUPERTRANS3
{SPR_SUPT, 3, 3, {NULL}, 0, 0, S_SUPERTRANS5}, // S_SUPERTRANS4
{SPR_SUPT, 4, 3, {NULL}, 0, 0, S_SUPERTRANS6}, // S_SUPERTRANS5
{SPR_SUPT, 5, 3, {NULL}, 0, 0, S_SUPERTRANS7}, // S_SUPERTRANS6
{SPR_SUPT, 6, 3, {NULL}, 0, 0, S_SUPERTRANS8}, // S_SUPERTRANS7
{SPR_SUPT, 7, 3, {NULL}, 0, 0, S_SUPERTRANS9}, // S_SUPERTRANS8
{SPR_SUPT, 8, 16, {NULL}, 0, 0, S_NIGHTSDRONE1}, // S_SUPERTRANS9
// Spark // Spark
{SPR_SPRK, FF_TRANS40 , 1, {NULL}, 0, 0, S_SPRK2}, // S_SPRK1 {SPR_SPRK, FF_TRANS40 , 1, {NULL}, 0, 0, S_SPRK2}, // S_SPRK1
{SPR_SPRK, FF_TRANS50|1, 1, {NULL}, 0, 0, S_SPRK3}, // S_SPRK2 {SPR_SPRK, FF_TRANS50|1, 1, {NULL}, 0, 0, S_SPRK3}, // S_SPRK2
@ -2640,7 +2679,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
MT_THOK, // damage MT_THOK, // damage
sfx_None, // activesound sfx_None, // activesound
MF_SOLID|MF_SHOOTABLE, // flags MF_SOLID|MF_SHOOTABLE, // flags
(statenum_t)MT_THOK // raisestate (statenum_t)MT_NULL // raisestate
}, },
{ // MT_BLUECRAWLA { // MT_BLUECRAWLA
@ -5284,6 +5323,87 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_RDIAG2 // raisestate S_RDIAG2 // raisestate
}, },
{ // MT_YELLOWHORIZ
558, // doomednum
S_YHORIZ1, // spawnstate
1, // spawnhealth
S_YHORIZ2, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_spring, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
16*FRACUNIT, // radius
32*FRACUNIT, // height
0, // display offset
0, // mass
16*FRACUNIT, // damage
sfx_None, // activesound
MF_SOLID|MF_SPRING|MF_NOGRAVITY, // flags
S_YHORIZ2 // raisestate
},
{ // MT_REDHORIZ
559, // doomednum
S_RHORIZ1, // spawnstate
1, // spawnhealth
S_RHORIZ2, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_spring, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
16*FRACUNIT, // radius
32*FRACUNIT, // height
0, // display offset
0, // mass
64*FRACUNIT, // damage
sfx_None, // activesound
MF_SOLID|MF_SPRING|MF_NOGRAVITY, // flags
S_RHORIZ2 // raisestate
},
{ // MT_BLUEHORIZ
560, // doomednum
S_BHORIZ1, // spawnstate
1, // spawnhealth
S_BHORIZ2, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_spring, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
16*FRACUNIT, // radius
32*FRACUNIT, // height
0, // display offset
0, // mass
4*FRACUNIT, // damage
sfx_None, // activesound
MF_SOLID|MF_SPRING|MF_NOGRAVITY, // flags
S_BHORIZ2 // raisestate
},
{ // MT_BUBBLES { // MT_BUBBLES
500, // doomednum 500, // doomednum
S_BUBBLES1, // spawnstate S_BUBBLES1, // spawnstate
@ -10370,7 +10490,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
{ // MT_EXTRALARGEBUBBLE { // MT_EXTRALARGEBUBBLE
-1, // doomednum -1, // doomednum
S_LARGEBUBBLE, // spawnstate S_LARGEBUBBLE1, // spawnstate
1000, // spawnhealth 1000, // spawnhealth
S_NULL, // seestate S_NULL, // seestate
sfx_None, // seesound sfx_None, // seesound
@ -10385,8 +10505,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_gasp, // deathsound sfx_gasp, // deathsound
8, // speed 8, // speed
8*FRACUNIT, // radius 23*FRACUNIT, // radius
12*FRACUNIT, // height 43*FRACUNIT, // height
0, // display offset 0, // display offset
16, // mass 16, // mass
0, // damage 0, // damage
@ -10395,6 +10515,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate S_NULL // raisestate
}, },
{ // MT_WATERZAP
-1, // doomednum
S_WATERZAP, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
8, // speed
4*FRACUNIT, // radius
4*FRACUNIT, // height
0, // display offset
16, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOGRAVITY|MF_SCENERY, // flags
S_NULL // raisestate
},
{ // MT_TFOG { // MT_TFOG
-1, // doomednum -1, // doomednum
S_FOG1, // spawnstate S_FOG1, // spawnstate
@ -12023,33 +12170,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate S_NULL // raisestate
}, },
{ // MT_NIGHTSCHAR
-1, // doomednum
S_NIGHTSFLY1A, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NIGHTSFLY1A, // painstate
255, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NIGHTSFLY1A, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
0, // speed
16*FRACUNIT, // radius
48*FRACUNIT, // height
0, // display offset
1000, // mass
0, // damage
sfx_None, // activesound
MF_NOCLIP|MF_NOGRAVITY, // flags
S_NULL // raisestate
},
{ // MT_NIGHTSPARKLE { // MT_NIGHTSPARKLE
-1, // doomednum -1, // doomednum
S_NIGHTSPARKLE1,// spawnstate S_NIGHTSPARKLE1,// spawnstate

View File

@ -314,7 +314,7 @@ typedef enum sprite
// Interactive Objects // Interactive Objects
SPR_FANS, SPR_FANS,
SPR_BUBL, // water bubble source SPR_BBLS, // water bubble source
SPR_SIGN, // Level end sign SPR_SIGN, // Level end sign
SPR_STEM, // Steam riser SPR_STEM, // Steam riser
SPR_SPIK, // Spike Ball SPR_SPIK, // Spike Ball
@ -448,6 +448,9 @@ typedef enum sprite
SPR_SPRB, // Blue springs SPR_SPRB, // Blue springs
SPR_YSPR, // Yellow Diagonal Spring SPR_YSPR, // Yellow Diagonal Spring
SPR_RSPR, // Red Diagonal Spring SPR_RSPR, // Red Diagonal Spring
SPR_SSWY, // Yellow Side Spring
SPR_SSWR, // Red Side Spring
SPR_SSWB, // Blue Side Spring
// Environmental Effects // Environmental Effects
SPR_RAIN, // Rain SPR_RAIN, // Rain
@ -455,11 +458,8 @@ typedef enum sprite
SPR_SPLH, // Water Splish SPR_SPLH, // Water Splish
SPR_SPLA, // Water Splash SPR_SPLA, // Water Splash
SPR_SMOK, SPR_SMOK,
SPR_BUBP, // Small bubble SPR_BUBL, // Bubble
SPR_BUBO, // Medium bubble SPR_WZAP,
SPR_BUBN, // Large bubble
SPR_BUBM, // Extra Large (would you like fries with that?) bubble
SPR_POPP, // Extra Large bubble goes POP!
SPR_TFOG, // Teleport Fog SPR_TFOG, // Teleport Fog
SPR_SEED, // Sonic CD flower seed SPR_SEED, // Sonic CD flower seed
SPR_PRTL, // Particle (for fans, etc.) SPR_PRTL, // Particle (for fans, etc.)
@ -510,16 +510,12 @@ typedef enum sprite
// NiGHTS Stuff // NiGHTS Stuff
SPR_NDRN, // NiGHTS drone SPR_NDRN, // NiGHTS drone
SPR_SUPE, // NiGHTS character flying
SPR_SUPZ, // NiGHTS hurt
SPR_NDRL, // NiGHTS character drilling
SPR_NSPK, // NiGHTS sparkle SPR_NSPK, // NiGHTS sparkle
SPR_NBMP, // NiGHTS Bumper SPR_NBMP, // NiGHTS Bumper
SPR_HOOP, // NiGHTS hoop sprite SPR_HOOP, // NiGHTS hoop sprite
SPR_NSCR, // NiGHTS score sprite SPR_NSCR, // NiGHTS score sprite
SPR_NPRU, // Nights Powerups SPR_NPRU, // Nights Powerups
SPR_CAPS, // Capsule thingy for NiGHTS SPR_CAPS, // Capsule thingy for NiGHTS
SPR_SUPT, // Super Sonic Transformation (NiGHTS)
// Debris // Debris
SPR_SPRK, // spark SPR_SPRK, // spark
@ -575,17 +571,21 @@ typedef enum sprite
NUMSPRITES NUMSPRITES
} spritenum_t; } spritenum_t;
// Make sure to be conscious of FF_FRAMEMASK whenever you change this table.
// Currently, FF_FRAMEMASK is 0x1ff, or 511 - and NUMSPRITEFREESLOTS is 256.
// Since this is zero-based, there can be at most 256 different SPR2_'s without changing that.
enum playersprite enum playersprite
{ {
SPR2_STND = 0, SPR2_STND = 0,
SPR2_WAIT, SPR2_WAIT,
SPR2_WALK, SPR2_WALK,
SPR2_RUN , SPR2_RUN ,
SPR2_PEEL,
SPR2_PAIN, SPR2_PAIN,
SPR2_DEAD, SPR2_DEAD,
SPR2_DRWN, SPR2_DRWN, // drown
SPR2_SPIN, SPR2_SPIN,
SPR2_DASH, SPR2_DASH, // spindash charge
SPR2_GASP, SPR2_GASP,
SPR2_JUMP, SPR2_JUMP,
SPR2_SPNG, // spring SPR2_SPNG, // spring
@ -593,33 +593,78 @@ enum playersprite
SPR2_EDGE, SPR2_EDGE,
SPR2_RIDE, SPR2_RIDE,
SPR2_SIGN, SPR2_SIGN, // end sign head
SPR2_LIFE, SPR2_LIFE, // life monitor icon
SPR2_FLY , SPR2_FLY ,
SPR2_TIRE, SPR2_SWIM,
SPR2_TIRE, // tired
SPR2_GLID, SPR2_GLID, // glide
SPR2_CLNG, SPR2_CLNG, // cling
SPR2_CLMB, SPR2_CLMB, // climb
SPR2_TRNS, SPR2_TWIN, // twinspin
SPR2_SSTD,
SPR2_SWLK,
SPR2_SRUN,
SPR2_SPAN,
SPR2_SMSL,
SPR2_SDTH,
SPR2_SDRN,
SPR2_SSPN,
SPR2_SGSP,
SPR2_SJMP,
SPR2_SSPG,
SPR2_SFAL,
SPR2_SEDG,
SPR2_SRID,
SPR2_SFLT,
SPR2_MLEE, // melee
SPR2_TRNS, // super transformation
SPR2_SSTD, // super stand
SPR2_SWLK, // super walk
SPR2_SRUN, // super run
SPR2_SPEE, // super peelout
SPR2_SPAN, // super pain
SPR2_SSTN, // super stun
SPR2_SDTH, // super death
SPR2_SDRN, // super drown
SPR2_SSPN, // super spin
SPR2_SGSP, // super gasp
SPR2_SJMP, // super jump
SPR2_SSPG, // super spring
SPR2_SFAL, // super fall
SPR2_SEDG, // super edge
SPR2_SRID, // super ride
SPR2_SFLT, // super float
SPR2_NTRN, // NiGHTS transformation
SPR2_NSTD, // NiGHTS stand
SPR2_NFLT, // NiGHTS float
SPR2_NPAN, // NiGHTS pain
SPR2_NPUL, // NiGHTS pull
SPR2_NATK, // NiGHTS attack
// NiGHTS flight.
SPR2_NGT0,
SPR2_NGT1,
SPR2_NGT2,
SPR2_NGT3,
SPR2_NGT4,
SPR2_NGT5,
SPR2_NGT6,
SPR2_NGT7,
SPR2_NGT8,
SPR2_NGT9,
SPR2_NGTA,
SPR2_NGTB,
SPR2_NGTC,
// NiGHTS drill.
SPR2_DRL0,
SPR2_DRL1,
SPR2_DRL2,
SPR2_DRL3,
SPR2_DRL4,
SPR2_DRL5,
SPR2_DRL6,
SPR2_DRL7,
SPR2_DRL8,
SPR2_DRL9,
SPR2_DRLA,
SPR2_DRLB,
SPR2_DRLC,
SPR2_FIRSTFREESLOT,
SPR2_LASTFREESLOT = SPR2_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1,
NUMPLAYERSPRITES NUMPLAYERSPRITES
}; };
@ -645,20 +690,22 @@ typedef enum state
S_PLAY_WAIT, S_PLAY_WAIT,
S_PLAY_WALK, S_PLAY_WALK,
S_PLAY_RUN, S_PLAY_RUN,
S_PLAY_PEEL,
S_PLAY_PAIN, S_PLAY_PAIN,
S_PLAY_DEAD, S_PLAY_DEAD,
S_PLAY_DRWN, S_PLAY_DRWN,
S_PLAY_SPIN, S_PLAY_SPIN,
S_PLAY_DASH, S_PLAY_DASH,
S_PLAY_GASP, S_PLAY_GASP,
S_PLAY_JUMP, // spin jump (todo: make jump separate from spring up for non-spin chars too?) S_PLAY_JUMP, // spin jump
S_PLAY_SPRING, S_PLAY_SPRING,
S_PLAY_FALL, S_PLAY_FALL,
S_PLAY_EDGE, S_PLAY_EDGE,
S_PLAY_RIDE, S_PLAY_RIDE,
// CA_FLY // CA_FLY/SWIM
S_PLAY_FLY, S_PLAY_FLY,
S_PLAY_SWIM,
S_PLAY_FLY_TIRED, S_PLAY_FLY_TIRED,
// CA_GLIDEANDCLIMB // CA_GLIDEANDCLIMB
@ -666,10 +713,18 @@ typedef enum state
S_PLAY_CLING, S_PLAY_CLING,
S_PLAY_CLIMB, S_PLAY_CLIMB,
// CA_TWINSPIN
S_PLAY_TWINSPIN,
// CA2_MELEE
S_PLAY_MELEE,
S_PLAY_MELEE_FINISH,
// SF_SUPERANIMS // SF_SUPERANIMS
S_PLAY_SUPER_STND, S_PLAY_SUPER_STND,
S_PLAY_SUPER_WALK, S_PLAY_SUPER_WALK,
S_PLAY_SUPER_RUN, S_PLAY_SUPER_RUN,
S_PLAY_SUPER_PEEL,
S_PLAY_SUPER_PAIN, S_PLAY_SUPER_PAIN,
S_PLAY_SUPER_STUN, S_PLAY_SUPER_STUN,
S_PLAY_SUPER_DEAD, S_PLAY_SUPER_DEAD,
@ -707,6 +762,50 @@ typedef enum state
// Level end sign overlay (uses player sprite) // Level end sign overlay (uses player sprite)
S_PLAY_SIGN, S_PLAY_SIGN,
// NiGHTS character (uses player sprite)
S_PLAY_NIGHTS_TRANS,
S_PLAY_NIGHTS_TRANS2,
S_PLAY_NIGHTS_TRANS3,
S_PLAY_NIGHTS_TRANS4,
S_PLAY_NIGHTS_TRANS5,
S_PLAY_NIGHTS_TRANS6,
S_PLAY_NIGHTS_TRANS7,
S_PLAY_NIGHTS_TRANS8,
S_PLAY_NIGHTS_TRANS9,
S_PLAY_NIGHTS_STAND,
S_PLAY_NIGHTS_FLOAT,
S_PLAY_NIGHTS_PAIN,
S_PLAY_NIGHTS_PULL,
S_PLAY_NIGHTS_ATTACK,
S_PLAY_NIGHTS_FLY0,
S_PLAY_NIGHTS_DRILL0,
S_PLAY_NIGHTS_FLY1,
S_PLAY_NIGHTS_DRILL1,
S_PLAY_NIGHTS_FLY2,
S_PLAY_NIGHTS_DRILL2,
S_PLAY_NIGHTS_FLY3,
S_PLAY_NIGHTS_DRILL3,
S_PLAY_NIGHTS_FLY4,
S_PLAY_NIGHTS_DRILL4,
S_PLAY_NIGHTS_FLY5,
S_PLAY_NIGHTS_DRILL5,
S_PLAY_NIGHTS_FLY6,
S_PLAY_NIGHTS_DRILL6,
S_PLAY_NIGHTS_FLY7,
S_PLAY_NIGHTS_DRILL7,
S_PLAY_NIGHTS_FLY8,
S_PLAY_NIGHTS_DRILL8,
S_PLAY_NIGHTS_FLY9,
S_PLAY_NIGHTS_DRILL9,
S_PLAY_NIGHTS_FLYA,
S_PLAY_NIGHTS_DRILLA,
S_PLAY_NIGHTS_FLYB,
S_PLAY_NIGHTS_DRILLB,
S_PLAY_NIGHTS_FLYC,
S_PLAY_NIGHTS_DRILLC,
// Blue Crawla // Blue Crawla
S_POSS_STND, S_POSS_STND,
S_POSS_RUN1, S_POSS_RUN1,
@ -1557,6 +1656,8 @@ typedef enum state
// Bubble Source // Bubble Source
S_BUBBLES1, S_BUBBLES1,
S_BUBBLES2, S_BUBBLES2,
S_BUBBLES3,
S_BUBBLES4,
// Level End Sign // Level End Sign
S_SIGN1, S_SIGN1,
@ -2351,6 +2452,36 @@ typedef enum state
S_RDIAG7, S_RDIAG7,
S_RDIAG8, S_RDIAG8,
// Yellow Side Spring
S_YHORIZ1,
S_YHORIZ2,
S_YHORIZ3,
S_YHORIZ4,
S_YHORIZ5,
S_YHORIZ6,
S_YHORIZ7,
S_YHORIZ8,
// Red Side Spring
S_RHORIZ1,
S_RHORIZ2,
S_RHORIZ3,
S_RHORIZ4,
S_RHORIZ5,
S_RHORIZ6,
S_RHORIZ7,
S_RHORIZ8,
// Blue Side Spring
S_BHORIZ1,
S_BHORIZ2,
S_BHORIZ3,
S_BHORIZ4,
S_BHORIZ5,
S_BHORIZ6,
S_BHORIZ7,
S_BHORIZ8,
// Rain // Rain
S_RAIN1, S_RAIN1,
S_RAINRETURN, S_RAINRETURN,
@ -2385,14 +2516,15 @@ typedef enum state
// Bubbles // Bubbles
S_SMALLBUBBLE, S_SMALLBUBBLE,
S_SMALLBUBBLE1,
S_MEDIUMBUBBLE, S_MEDIUMBUBBLE,
S_MEDIUMBUBBLE1, S_LARGEBUBBLE1,
S_LARGEBUBBLE, S_LARGEBUBBLE2,
S_EXTRALARGEBUBBLE, // breathable S_EXTRALARGEBUBBLE, // breathable
S_POP1, // Extra Large bubble goes POP! S_POP1, // Extra Large bubble goes POP!
S_WATERZAP,
S_FOG1, S_FOG1,
S_FOG2, S_FOG2,
S_FOG3, S_FOG3,
@ -2434,6 +2566,13 @@ typedef enum state
S_FOUR1, S_FOUR1,
S_FIVE1, S_FIVE1,
S_ZERO2,
S_ONE2,
S_TWO2,
S_THREE2,
S_FOUR2,
S_FIVE2,
// Tag Sign // Tag Sign
S_TTAG1, S_TTAG1,
@ -2666,93 +2805,6 @@ typedef enum state
S_NIGHTSGOAL3, S_NIGHTSGOAL3,
S_NIGHTSGOAL4, S_NIGHTSGOAL4,
S_NIGHTSFLY1A,
S_NIGHTSFLY1B,
S_NIGHTSDRILL1A,
S_NIGHTSDRILL1B,
S_NIGHTSDRILL1C,
S_NIGHTSDRILL1D,
S_NIGHTSFLY2A,
S_NIGHTSFLY2B,
S_NIGHTSDRILL2A,
S_NIGHTSDRILL2B,
S_NIGHTSDRILL2C,
S_NIGHTSDRILL2D,
S_NIGHTSFLY3A,
S_NIGHTSFLY3B,
S_NIGHTSDRILL3A,
S_NIGHTSDRILL3B,
S_NIGHTSDRILL3C,
S_NIGHTSDRILL3D,
S_NIGHTSFLY4A,
S_NIGHTSFLY4B,
S_NIGHTSDRILL4A,
S_NIGHTSDRILL4B,
S_NIGHTSDRILL4C,
S_NIGHTSDRILL4D,
S_NIGHTSFLY5A,
S_NIGHTSFLY5B,
S_NIGHTSDRILL5A,
S_NIGHTSDRILL5B,
S_NIGHTSDRILL5C,
S_NIGHTSDRILL5D,
S_NIGHTSFLY6A,
S_NIGHTSFLY6B,
S_NIGHTSDRILL6A,
S_NIGHTSDRILL6B,
S_NIGHTSDRILL6C,
S_NIGHTSDRILL6D,
S_NIGHTSFLY7A,
S_NIGHTSFLY7B,
S_NIGHTSDRILL7A,
S_NIGHTSDRILL7B,
S_NIGHTSDRILL7C,
S_NIGHTSDRILL7D,
S_NIGHTSFLY8A,
S_NIGHTSFLY8B,
S_NIGHTSDRILL8A,
S_NIGHTSDRILL8B,
S_NIGHTSDRILL8C,
S_NIGHTSDRILL8D,
S_NIGHTSFLY9A,
S_NIGHTSFLY9B,
S_NIGHTSDRILL9A,
S_NIGHTSDRILL9B,
S_NIGHTSDRILL9C,
S_NIGHTSDRILL9D,
S_NIGHTSHURT1,
S_NIGHTSHURT2,
S_NIGHTSHURT3,
S_NIGHTSHURT4,
S_NIGHTSHURT5,
S_NIGHTSHURT6,
S_NIGHTSHURT7,
S_NIGHTSHURT8,
S_NIGHTSHURT9,
S_NIGHTSHURT10,
S_NIGHTSHURT11,
S_NIGHTSHURT12,
S_NIGHTSHURT13,
S_NIGHTSHURT14,
S_NIGHTSHURT15,
S_NIGHTSHURT16,
S_NIGHTSHURT17,
S_NIGHTSHURT18,
S_NIGHTSHURT19,
S_NIGHTSHURT20,
S_NIGHTSHURT21,
S_NIGHTSHURT22,
S_NIGHTSHURT23,
S_NIGHTSHURT24,
S_NIGHTSHURT25,
S_NIGHTSHURT26,
S_NIGHTSHURT27,
S_NIGHTSHURT28,
S_NIGHTSHURT29,
S_NIGHTSHURT30,
S_NIGHTSHURT31,
S_NIGHTSHURT32,
S_NIGHTSPARKLE1, S_NIGHTSPARKLE1,
S_NIGHTSPARKLE2, S_NIGHTSPARKLE2,
S_NIGHTSPARKLE3, S_NIGHTSPARKLE3,
@ -2849,16 +2901,6 @@ typedef enum state
S_CRUMBLE1, S_CRUMBLE1,
S_CRUMBLE2, S_CRUMBLE2,
S_SUPERTRANS1,
S_SUPERTRANS2,
S_SUPERTRANS3,
S_SUPERTRANS4,
S_SUPERTRANS5,
S_SUPERTRANS6,
S_SUPERTRANS7,
S_SUPERTRANS8,
S_SUPERTRANS9,
// Spark // Spark
S_SPRK1, S_SPRK1,
S_SPRK2, S_SPRK2,
@ -2996,8 +3038,9 @@ typedef struct
extern state_t states[NUMSTATES]; extern state_t states[NUMSTATES];
extern char sprnames[NUMSPRITES + 1][5]; extern char sprnames[NUMSPRITES + 1][5];
char spr2names[NUMPLAYERSPRITES][5]; extern char spr2names[NUMPLAYERSPRITES][5];
extern state_t *astate; extern state_t *astate;
extern enum playersprite free_spr2;
typedef enum mobj_type typedef enum mobj_type
{ {
@ -3126,6 +3169,9 @@ typedef enum mobj_type
MT_REDSPRING, MT_REDSPRING,
MT_YELLOWDIAG, // Yellow Diagonal Spring MT_YELLOWDIAG, // Yellow Diagonal Spring
MT_REDDIAG, // Red Diagonal Spring MT_REDDIAG, // Red Diagonal Spring
MT_YELLOWHORIZ, // Yellow Side Spring
MT_REDHORIZ, // Red Side Spring
MT_BLUEHORIZ, // Blue Side Spring
// Interactive Objects // Interactive Objects
MT_BUBBLES, // Bubble source MT_BUBBLES, // Bubble source
@ -3357,6 +3403,7 @@ typedef enum mobj_type
MT_SMALLBUBBLE, // small bubble MT_SMALLBUBBLE, // small bubble
MT_MEDIUMBUBBLE, // medium bubble MT_MEDIUMBUBBLE, // medium bubble
MT_EXTRALARGEBUBBLE, // extra large bubble MT_EXTRALARGEBUBBLE, // extra large bubble
MT_WATERZAP,
MT_TFOG, MT_TFOG,
MT_SEED, MT_SEED,
MT_PARTICLE, MT_PARTICLE,
@ -3429,7 +3476,6 @@ typedef enum mobj_type
MT_AXISTRANSFERLINE, MT_AXISTRANSFERLINE,
MT_NIGHTSDRONE, MT_NIGHTSDRONE,
MT_NIGHTSGOAL, MT_NIGHTSGOAL,
MT_NIGHTSCHAR,
MT_NIGHTSPARKLE, MT_NIGHTSPARKLE,
MT_NIGHTSLOOPHELPER, MT_NIGHTSLOOPHELPER,
MT_NIGHTSBUMPER, // NiGHTS Bumper MT_NIGHTSBUMPER, // NiGHTS Bumper

View File

@ -1377,11 +1377,6 @@ msgstr ""
msgid "modifiedgame is false, you can unlock secrets\n" msgid "modifiedgame is false, you can unlock secrets\n"
msgstr "" msgstr ""
#: d_netcmd.c:4599
#, c-format
msgid "Valid skin numbers are 0 to %d (-1 disables)\n"
msgstr ""
#: d_netcmd.c:4617 d_netcmd.c:4629 #: d_netcmd.c:4617 d_netcmd.c:4629
msgid "You may not change your name when chat is muted.\n" msgid "You may not change your name when chat is muted.\n"
msgstr "" msgstr ""

View File

@ -1362,11 +1362,6 @@ msgstr ""
msgid "No CHEAT-marked variables are changed -- Cheats are disabled.\n" msgid "No CHEAT-marked variables are changed -- Cheats are disabled.\n"
msgstr "" msgstr ""
#: d_netcmd.c:4439
#, c-format
msgid "Valid skin numbers are 0 to %d (-1 disables)\n"
msgstr ""
#: d_netcmd.c:4457 d_netcmd.c:4469 #: d_netcmd.c:4457 d_netcmd.c:4469
msgid "You may not change your name when chat is muted.\n" msgid "You may not change your name when chat is muted.\n"
msgstr "" msgstr ""

View File

@ -429,6 +429,16 @@ static int lib_pMobjFlip(lua_State *L)
return 1; return 1;
} }
static int lib_pGetMobjGravity(lua_State *L)
{
mobj_t *mobj = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
//HUDSAFE
if (!mobj)
return LUA_ErrInvalid(L, "mobj_t");
lua_pushfixed(L, P_GetMobjGravity(mobj));
return 1;
}
static int lib_pWeaponOrPanel(lua_State *L) static int lib_pWeaponOrPanel(lua_State *L)
{ {
mobjtype_t type = luaL_checkinteger(L, 1); mobjtype_t type = luaL_checkinteger(L, 1);
@ -2005,6 +2015,7 @@ static luaL_Reg lib[] = {
{"P_SPMAngle",lib_pSPMAngle}, {"P_SPMAngle",lib_pSPMAngle},
{"P_SpawnPlayerMissile",lib_pSpawnPlayerMissile}, {"P_SpawnPlayerMissile",lib_pSpawnPlayerMissile},
{"P_MobjFlip",lib_pMobjFlip}, {"P_MobjFlip",lib_pMobjFlip},
{"P_GetMobjGravity",lib_pGetMobjGravity},
{"P_WeaponOrPanel",lib_pWeaponOrPanel}, {"P_WeaponOrPanel",lib_pWeaponOrPanel},
{"P_FlashPal",lib_pFlashPal}, {"P_FlashPal",lib_pFlashPal},
{"P_GetClosestAxis",lib_pGetClosestAxis}, {"P_GetClosestAxis",lib_pGetClosestAxis},

View File

@ -69,7 +69,7 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source); // Ho
#define LUAh_MobjRemoved(mo) LUAh_MobjHook(mo, hook_MobjRemoved) // Hook for P_RemoveMobj by mobj type #define LUAh_MobjRemoved(mo) LUAh_MobjHook(mo, hook_MobjRemoved) // Hook for P_RemoveMobj by mobj type
#define LUAh_JumpSpecial(player) LUAh_PlayerHook(player, hook_JumpSpecial) // Hook for P_DoJumpStuff (Any-jumping) #define LUAh_JumpSpecial(player) LUAh_PlayerHook(player, hook_JumpSpecial) // Hook for P_DoJumpStuff (Any-jumping)
#define LUAh_AbilitySpecial(player) LUAh_PlayerHook(player, hook_AbilitySpecial) // Hook for P_DoJumpStuff (Double-jumping) #define LUAh_AbilitySpecial(player) LUAh_PlayerHook(player, hook_AbilitySpecial) // Hook for P_DoJumpStuff (Double-jumping)
#define LUAh_SpinSpecial(player) LUAh_PlayerHook(player, hook_SpinSpecial) // Hook for P_DoSpinDash (Spin button effect) #define LUAh_SpinSpecial(player) LUAh_PlayerHook(player, hook_SpinSpecial) // Hook for P_DoSpinAbility (Spin button effect)
#define LUAh_JumpSpinSpecial(player) LUAh_PlayerHook(player, hook_JumpSpinSpecial) // Hook for P_DoJumpStuff (Spin button effect (mid-air)) #define LUAh_JumpSpinSpecial(player) LUAh_PlayerHook(player, hook_JumpSpinSpecial) // Hook for P_DoJumpStuff (Spin button effect (mid-air))
boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd boolean LUAh_BotTiccmd(player_t *bot, ticcmd_t *cmd); // Hook for B_BuildTiccmd
boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name boolean LUAh_BotAI(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd); // Hook for B_BuildTailsTiccmd by skin name

View File

@ -18,6 +18,9 @@ enum hud {
hud_time, hud_time,
hud_rings, hud_rings,
hud_lives, hud_lives,
// Match / CTF / Tag / Ringslinger
hud_weaponrings,
hud_powerstones,
// NiGHTS mode // NiGHTS mode
hud_nightslink, hud_nightslink,
hud_nightsdrill, hud_nightsdrill,

View File

@ -44,6 +44,9 @@ static const char *const hud_disable_options[] = {
"rings", "rings",
"lives", "lives",
"weaponrings",
"powerstones",
"nightslink", "nightslink",
"nightsdrill", "nightsdrill",
"nightsrings", "nightsrings",

View File

@ -105,7 +105,7 @@ static int lib_getSpr2name(lua_State *L)
if (lua_isnumber(L, 1)) if (lua_isnumber(L, 1))
{ {
i = lua_tonumber(L, 1); i = lua_tonumber(L, 1);
if (i > NUMPLAYERSPRITES) if (i >= free_spr2)
return 0; return 0;
lua_pushlstring(L, spr2names[i], 4); lua_pushlstring(L, spr2names[i], 4);
return 1; return 1;
@ -113,7 +113,7 @@ static int lib_getSpr2name(lua_State *L)
else if (lua_isstring(L, 1)) else if (lua_isstring(L, 1))
{ {
const char *name = lua_tostring(L, 1); const char *name = lua_tostring(L, 1);
for (i = 0; i < NUMPLAYERSPRITES; i++) for (i = 0; i < free_spr2; i++)
if (fastcmp(name, spr2names[i])) if (fastcmp(name, spr2names[i]))
{ {
lua_pushinteger(L, i); lua_pushinteger(L, i);
@ -125,7 +125,7 @@ static int lib_getSpr2name(lua_State *L)
static int lib_spr2namelen(lua_State *L) static int lib_spr2namelen(lua_State *L)
{ {
lua_pushinteger(L, NUMPLAYERSPRITES); lua_pushinteger(L, free_spr2);
return 1; return 1;
} }

View File

@ -108,6 +108,10 @@ static int player_get(lua_State *L)
LUA_PushUserdata(L, &plr->cmd, META_TICCMD); LUA_PushUserdata(L, &plr->cmd, META_TICCMD);
else if (fastcmp(field,"playerstate")) else if (fastcmp(field,"playerstate"))
lua_pushinteger(L, plr->playerstate); lua_pushinteger(L, plr->playerstate);
else if (fastcmp(field,"camerascale"))
lua_pushfixed(L, plr->camerascale);
else if (fastcmp(field,"shieldscale"))
lua_pushfixed(L, plr->shieldscale);
else if (fastcmp(field,"viewz")) else if (fastcmp(field,"viewz"))
lua_pushfixed(L, plr->viewz); lua_pushfixed(L, plr->viewz);
else if (fastcmp(field,"viewheight")) else if (fastcmp(field,"viewheight"))
@ -142,8 +146,6 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->score); lua_pushinteger(L, plr->score);
else if (fastcmp(field,"dashspeed")) else if (fastcmp(field,"dashspeed"))
lua_pushfixed(L, plr->dashspeed); lua_pushfixed(L, plr->dashspeed);
else if (fastcmp(field,"dashtime"))
lua_pushinteger(L, plr->dashtime);
else if (fastcmp(field,"normalspeed")) else if (fastcmp(field,"normalspeed"))
lua_pushfixed(L, plr->normalspeed); lua_pushfixed(L, plr->normalspeed);
else if (fastcmp(field,"runspeed")) else if (fastcmp(field,"runspeed"))
@ -174,6 +176,10 @@ static int player_get(lua_State *L)
lua_pushfixed(L, plr->maxdash); lua_pushfixed(L, plr->maxdash);
else if (fastcmp(field,"jumpfactor")) else if (fastcmp(field,"jumpfactor"))
lua_pushfixed(L, plr->jumpfactor); lua_pushfixed(L, plr->jumpfactor);
else if (fastcmp(field,"height"))
lua_pushfixed(L, plr->height);
else if (fastcmp(field,"spinheight"))
lua_pushfixed(L, plr->spinheight);
else if (fastcmp(field,"lives")) else if (fastcmp(field,"lives"))
lua_pushinteger(L, plr->lives); lua_pushinteger(L, plr->lives);
else if (fastcmp(field,"continues")) else if (fastcmp(field,"continues"))
@ -202,6 +208,8 @@ static int player_get(lua_State *L)
lua_pushinteger(L, plr->exiting); lua_pushinteger(L, plr->exiting);
else if (fastcmp(field,"homing")) else if (fastcmp(field,"homing"))
lua_pushinteger(L, plr->homing); lua_pushinteger(L, plr->homing);
else if (fastcmp(field,"dashmode"))
lua_pushinteger(L, plr->dashmode);
else if (fastcmp(field,"skidtime")) else if (fastcmp(field,"skidtime"))
lua_pushinteger(L, plr->skidtime); lua_pushinteger(L, plr->skidtime);
else if (fastcmp(field,"cmomx")) else if (fastcmp(field,"cmomx"))
@ -355,6 +363,10 @@ static int player_set(lua_State *L)
return NOSET; return NOSET;
else if (fastcmp(field,"playerstate")) else if (fastcmp(field,"playerstate"))
plr->playerstate = luaL_checkinteger(L, 3); plr->playerstate = luaL_checkinteger(L, 3);
else if (fastcmp(field,"camerascale"))
plr->camerascale = luaL_checkfixed(L, 3);
else if (fastcmp(field,"shieldscale"))
plr->shieldscale = luaL_checkfixed(L, 3);
else if (fastcmp(field,"viewz")) else if (fastcmp(field,"viewz"))
plr->viewz = luaL_checkfixed(L, 3); plr->viewz = luaL_checkfixed(L, 3);
else if (fastcmp(field,"viewheight")) else if (fastcmp(field,"viewheight"))
@ -399,8 +411,6 @@ static int player_set(lua_State *L)
plr->score = (UINT32)luaL_checkinteger(L, 3); plr->score = (UINT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"dashspeed")) else if (fastcmp(field,"dashspeed"))
plr->dashspeed = luaL_checkfixed(L, 3); plr->dashspeed = luaL_checkfixed(L, 3);
else if (fastcmp(field,"dashtime"))
plr->dashtime = (INT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"normalspeed")) else if (fastcmp(field,"normalspeed"))
plr->normalspeed = luaL_checkfixed(L, 3); plr->normalspeed = luaL_checkfixed(L, 3);
else if (fastcmp(field,"runspeed")) else if (fastcmp(field,"runspeed"))
@ -431,6 +441,10 @@ static int player_set(lua_State *L)
plr->maxdash = (INT32)luaL_checkinteger(L, 3); plr->maxdash = (INT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"jumpfactor")) else if (fastcmp(field,"jumpfactor"))
plr->jumpfactor = (INT32)luaL_checkinteger(L, 3); plr->jumpfactor = (INT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"height"))
plr->height = luaL_checkfixed(L, 3);
else if (fastcmp(field,"spinheight"))
plr->spinheight = luaL_checkfixed(L, 3);
else if (fastcmp(field,"lives")) else if (fastcmp(field,"lives"))
plr->lives = (SINT8)luaL_checkinteger(L, 3); plr->lives = (SINT8)luaL_checkinteger(L, 3);
else if (fastcmp(field,"continues")) else if (fastcmp(field,"continues"))
@ -459,6 +473,8 @@ static int player_set(lua_State *L)
plr->exiting = (tic_t)luaL_checkinteger(L, 3); plr->exiting = (tic_t)luaL_checkinteger(L, 3);
else if (fastcmp(field,"homing")) else if (fastcmp(field,"homing"))
plr->homing = (UINT8)luaL_checkinteger(L, 3); plr->homing = (UINT8)luaL_checkinteger(L, 3);
else if (fastcmp(field,"dashmode"))
plr->dashmode = (tic_t)luaL_checkinteger(L, 3);
else if (fastcmp(field,"skidtime")) else if (fastcmp(field,"skidtime"))
plr->skidtime = (tic_t)luaL_checkinteger(L, 3); plr->skidtime = (tic_t)luaL_checkinteger(L, 3);
else if (fastcmp(field,"cmomx")) else if (fastcmp(field,"cmomx"))

View File

@ -44,10 +44,18 @@ enum skin {
skin_accelstart, skin_accelstart,
skin_acceleration, skin_acceleration,
skin_jumpfactor, skin_jumpfactor,
skin_radius,
skin_height,
skin_spinheight,
skin_shieldscale,
skin_camerascale,
skin_starttranscolor, skin_starttranscolor,
skin_prefcolor, skin_prefcolor,
skin_supercolor,
skin_prefoppositecolor,
skin_highresscale, skin_highresscale,
skin_soundsid skin_soundsid,
skin_availability
}; };
static const char *const skin_opt[] = { static const char *const skin_opt[] = {
"valid", "valid",
@ -74,10 +82,18 @@ static const char *const skin_opt[] = {
"accelstart", "accelstart",
"acceleration", "acceleration",
"jumpfactor", "jumpfactor",
"radius",
"height",
"spinheight",
"shieldscale",
"camerascale",
"starttranscolor", "starttranscolor",
"prefcolor", "prefcolor",
"supercolor",
"prefoppositecolor",
"highresscale", "highresscale",
"soundsid", "soundsid",
"availability",
NULL}; NULL};
#define UNIMPLEMENTED luaL_error(L, LUA_QL("skin_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", skin_opt[field]) #define UNIMPLEMENTED luaL_error(L, LUA_QL("skin_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", skin_opt[field])
@ -173,18 +189,42 @@ static int skin_get(lua_State *L)
case skin_jumpfactor: case skin_jumpfactor:
lua_pushfixed(L, skin->jumpfactor); lua_pushfixed(L, skin->jumpfactor);
break; break;
case skin_radius:
lua_pushfixed(L, skin->radius);
break;
case skin_height:
lua_pushfixed(L, skin->height);
break;
case skin_spinheight:
lua_pushfixed(L, skin->spinheight);
break;
case skin_shieldscale:
lua_pushfixed(L, skin->shieldscale);
break;
case skin_camerascale:
lua_pushfixed(L, skin->camerascale);
break;
case skin_starttranscolor: case skin_starttranscolor:
lua_pushinteger(L, skin->starttranscolor); lua_pushinteger(L, skin->starttranscolor);
break; break;
case skin_prefcolor: case skin_prefcolor:
lua_pushinteger(L, skin->prefcolor); lua_pushinteger(L, skin->prefcolor);
break; break;
case skin_supercolor:
lua_pushinteger(L, skin->supercolor);
break;
case skin_prefoppositecolor:
lua_pushinteger(L, skin->prefoppositecolor);
break;
case skin_highresscale: case skin_highresscale:
lua_pushinteger(L, skin->highresscale); lua_pushinteger(L, skin->highresscale);
break; break;
case skin_soundsid: case skin_soundsid:
LUA_PushUserdata(L, skin->soundsid, META_SOUNDSID); LUA_PushUserdata(L, skin->soundsid, META_SOUNDSID);
break; break;
case skin_availability:
lua_pushinteger(L, skin->availability);
break;
} }
return 1; return 1;
} }

View File

@ -59,7 +59,11 @@
* Unconditionally aligning does not cost very much, so do it if unsure * Unconditionally aligning does not cost very much, so do it if unsure
*/ */
#ifndef STRICT_ALIGN #ifndef STRICT_ALIGN
# define STRICT_ALIGN !(defined(__i386) || defined (__amd64)) || defined (__clang__) #if !(defined(__i386) || defined (__amd64)) || defined (__clang__)
#define STRICT_ALIGN 1
#else
#define STRICT_ALIGN 0
#endif
#endif #endif
/* /*

167
src/m_aatree.c Normal file
View File

@ -0,0 +1,167 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2016 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file m_aatree.h
/// \brief AA trees code
#include "m_aatree.h"
#include "z_zone.h"
// A partial implementation of AA trees,
// according to the algorithms given on Wikipedia.
// http://en.wikipedia.org/wiki/AA_tree
typedef struct aatree_node_s
{
INT32 level;
INT32 key;
void* value;
struct aatree_node_s *left, *right;
} aatree_node_t;
struct aatree_s
{
aatree_node_t *root;
UINT32 flags;
};
aatree_t *M_AATreeAlloc(UINT32 flags)
{
aatree_t *aatree = Z_Malloc(sizeof (aatree_t), PU_STATIC, NULL);
aatree->root = NULL;
aatree->flags = flags;
return aatree;
}
static void M_AATreeFree_Node(aatree_node_t *node)
{
if (node->left) M_AATreeFree_Node(node->left);
if (node->right) M_AATreeFree_Node(node->right);
Z_Free(node);
}
void M_AATreeFree(aatree_t *aatree)
{
if (aatree->root)
M_AATreeFree_Node(aatree->root);
Z_Free(aatree);
}
static aatree_node_t *M_AATreeSkew(aatree_node_t *node)
{
if (node && node->left && node->left->level == node->level)
{
// Not allowed: horizontal left-link. Reverse the
// horizontal link and hook the orphan back in.
aatree_node_t *oldleft = node->left;
node->left = oldleft->right;
oldleft->right = node;
return oldleft;
}
// No change needed.
return node;
}
static aatree_node_t *M_AATreeSplit(aatree_node_t *node)
{
if (node && node->right && node->right->right && node->level == node->right->right->level)
{
// Not allowed: two consecutive horizontal right-links.
// The middle one becomes the new root at this point,
// with suitable adjustments below.
aatree_node_t *oldright = node->right;
node->right = oldright->left;
oldright->left = node;
oldright->level++;
return oldright;
}
// No change needed.
return node;
}
static aatree_node_t *M_AATreeSet_Node(aatree_node_t *node, UINT32 flags, INT32 key, void* value)
{
if (!node)
{
// Nothing here, so just add where we are
node = Z_Malloc(sizeof (aatree_node_t), PU_STATIC, NULL);
node->level = 1;
node->key = key;
if (value && (flags & AATREE_ZUSER)) Z_SetUser(value, &node->value);
else node->value = value;
node->left = node->right = NULL;
}
else
{
if (key < node->key)
node->left = M_AATreeSet_Node(node->left, flags, key, value);
else if (key > node->key)
node->right = M_AATreeSet_Node(node->right, flags, key, value);
else
{
if (value && (flags & AATREE_ZUSER)) Z_SetUser(value, &node->value);
else node->value = value;
}
node = M_AATreeSkew(node);
node = M_AATreeSplit(node);
}
return node;
}
void M_AATreeSet(aatree_t *aatree, INT32 key, void* value)
{
aatree->root = M_AATreeSet_Node(aatree->root, aatree->flags, key, value);
}
// Caveat: we don't distinguish between nodes that don't exists
// and nodes with value == NULL.
static void *M_AATreeGet_Node(aatree_node_t *node, INT32 key)
{
if (node)
{
if (node->key == key)
return node->value;
else if(node->key < key)
return M_AATreeGet_Node(node->right, key);
else
return M_AATreeGet_Node(node->left, key);
}
return NULL;
}
void *M_AATreeGet(aatree_t *aatree, INT32 key)
{
return M_AATreeGet_Node(aatree->root, key);
}
static void M_AATreeIterate_Node(aatree_node_t *node, aatree_iter_t callback)
{
if (node->left) M_AATreeIterate_Node(node->left, callback);
callback(node->key, node->value);
if (node->right) M_AATreeIterate_Node(node->right, callback);
}
void M_AATreeIterate(aatree_t *aatree, aatree_iter_t callback)
{
if (aatree->root)
M_AATreeIterate_Node(aatree->root, callback);
}

31
src/m_aatree.h Normal file
View File

@ -0,0 +1,31 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1993-1996 by id Software, Inc.
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2016 by Sonic Team Junior.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \file m_aatree.h
/// \brief AA trees code
#ifndef __M_AATREE__
#define __M_AATREE__
#include "doomtype.h"
// Flags for AA trees.
#define AATREE_ZUSER 1 // Treat values as z_zone-allocated blocks and set their user fields
typedef struct aatree_s aatree_t;
typedef void (*aatree_iter_t)(INT32 key, void *value);
aatree_t *M_AATreeAlloc(UINT32 flags);
void M_AATreeFree(aatree_t *aatree);
void M_AATreeSet(aatree_t *aatree, INT32 key, void* value);
void *M_AATreeGet(aatree_t *aatree, INT32 key);
void M_AATreeIterate(aatree_t *aatree, aatree_iter_t callback);
#endif

View File

@ -110,38 +110,38 @@ const char *quitmsg[NUM_QUITMESSAGES];
// Stuff for customizing the player select screen Tails 09-22-2003 // Stuff for customizing the player select screen Tails 09-22-2003
description_t description[32] = description_t description[32] =
{ {
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""}, {"???", "", "", 0, 0, 0},
{"???", "", ""} {"???", "", "", 0, 0, 0}
}; };
static char *char_notes = NULL; static char *char_notes = NULL;
static fixed_t char_scroll = 0; static fixed_t char_scroll = 0;
@ -170,6 +170,7 @@ static saveinfo_t savegameinfo[MAXSAVEGAMES]; // Extra info about the save games
INT16 startmap; // Mario, NiGHTS, or just a plain old normal game? INT16 startmap; // Mario, NiGHTS, or just a plain old normal game?
static INT16 itemOn = 1; // menu item skull is on, Hack by Tails 09-18-2002 static INT16 itemOn = 1; // menu item skull is on, Hack by Tails 09-18-2002
static boolean lastdirection = true; // toaster - Only You Can Prevent Hacks - true is for forward, false is for backwards
static INT16 skullAnimCounter = 10; // skull animation counter static INT16 skullAnimCounter = 10; // skull animation counter
static boolean setupcontrols_secondaryplayer; static boolean setupcontrols_secondaryplayer;
@ -705,7 +706,7 @@ static menuitem_t SP_TimeAttackMenu[] =
{IT_DISABLED, NULL, "Guest Option...", &SP_GuestReplayDef, 100}, {IT_DISABLED, NULL, "Guest Option...", &SP_GuestReplayDef, 100},
{IT_DISABLED, NULL, "Replay...", &SP_ReplayDef, 110}, {IT_DISABLED, NULL, "Replay...", &SP_ReplayDef, 110},
{IT_DISABLED, NULL, "Ghosts...", &SP_GhostDef, 120}, {IT_DISABLED, NULL, "Ghosts...", &SP_GhostDef, 120},
{IT_WHITESTRING|IT_CALL, NULL, "Start", M_ChooseTimeAttack, 130}, {IT_WHITESTRING|IT_CALL|IT_CALL_NOTMODIFIED, NULL, "Start", M_ChooseTimeAttack, 130},
}; };
enum enum
@ -797,7 +798,7 @@ static menuitem_t SP_NightsAttackMenu[] =
{IT_DISABLED, NULL, "Guest Option...", &SP_NightsGuestReplayDef, 108}, {IT_DISABLED, NULL, "Guest Option...", &SP_NightsGuestReplayDef, 108},
{IT_DISABLED, NULL, "Replay...", &SP_NightsReplayDef, 118}, {IT_DISABLED, NULL, "Replay...", &SP_NightsReplayDef, 118},
{IT_DISABLED, NULL, "Ghosts...", &SP_NightsGhostDef, 128}, {IT_DISABLED, NULL, "Ghosts...", &SP_NightsGhostDef, 128},
{IT_WHITESTRING|IT_CALL, NULL, "Start", M_ChooseNightsAttack, 138}, {IT_WHITESTRING|IT_CALL|IT_CALL_NOTMODIFIED, NULL, "Start", M_ChooseNightsAttack, 138},
}; };
enum enum
@ -1342,7 +1343,7 @@ static menuitem_t OP_NetgameOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Sudden Death", &cv_suddendeath, 90}, {IT_STRING | IT_CVAR, NULL, "Sudden Death", &cv_suddendeath, 90},
{IT_STRING | IT_CVAR, NULL, "Player respawn delay", &cv_respawntime, 98}, {IT_STRING | IT_CVAR, NULL, "Player respawn delay", &cv_respawntime, 98},
{IT_STRING | IT_CVAR, NULL, "Force Skin #", &cv_forceskin, 114}, {IT_STRING | IT_CVAR, NULL, "Force Skin", &cv_forceskin, 114},
{IT_STRING | IT_CVAR, NULL, "Restrict skin changes", &cv_restrictskinchange, 122}, {IT_STRING | IT_CVAR, NULL, "Restrict skin changes", &cv_restrictskinchange, 122},
{IT_STRING | IT_CVAR, NULL, "Autobalance Teams", &cv_autobalance, 138}, {IT_STRING | IT_CVAR, NULL, "Autobalance Teams", &cv_autobalance, 138},
@ -2036,6 +2037,7 @@ static boolean M_ChangeStringCvar(INT32 choice)
static void M_NextOpt(void) static void M_NextOpt(void)
{ {
INT16 oldItemOn = itemOn; // prevent infinite loop INT16 oldItemOn = itemOn; // prevent infinite loop
lastdirection = true;
do do
{ {
@ -2049,6 +2051,7 @@ static void M_NextOpt(void)
static void M_PrevOpt(void) static void M_PrevOpt(void)
{ {
INT16 oldItemOn = itemOn; // prevent infinite loop INT16 oldItemOn = itemOn; // prevent infinite loop
lastdirection = false;
do do
{ {
@ -3426,9 +3429,9 @@ static void M_PatchSkinNameTable(void)
for (j = 0; j < MAXSKINS; j++) for (j = 0; j < MAXSKINS; j++)
{ {
if (skins[j].name[0] != '\0') if (skins[j].name[0] != '\0' && R_SkinUnlock(j))
{ {
skins_cons_t[j].strvalue = skins[j].name; skins_cons_t[j].strvalue = skins[j].realname;
skins_cons_t[j].value = j+1; skins_cons_t[j].value = j+1;
} }
else else
@ -3702,6 +3705,11 @@ static void M_DrawMessageMenu(void)
mlines = currentMenu->lastOn>>8; mlines = currentMenu->lastOn>>8;
max = (INT16)((UINT8)(currentMenu->lastOn & 0xFF)*8); max = (INT16)((UINT8)(currentMenu->lastOn & 0xFF)*8);
// hack: draw RA background in RA menus
if (gamestate == GS_TIMEATTACK)
V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE));
M_DrawTextBox(currentMenu->x, y - 8, (max+7)>>3, mlines); M_DrawTextBox(currentMenu->x, y - 8, (max+7)>>3, mlines);
while (*(msg+start)) while (*(msg+start))
@ -4310,9 +4318,9 @@ static void M_SinglePlayerMenu(INT32 choice)
{ {
(void)choice; (void)choice;
SP_MainMenu[sprecordattack].status = SP_MainMenu[sprecordattack].status =
(M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED : IT_SECRET; (M_SecretUnlocked(SECRET_RECORDATTACK)) ? IT_CALL|IT_STRING : IT_SECRET;
SP_MainMenu[spnightsmode].status = SP_MainMenu[spnightsmode].status =
(M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED : IT_SECRET; (M_SecretUnlocked(SECRET_NIGHTSMODE)) ? IT_CALL|IT_STRING : IT_SECRET;
M_SetupNextMenu(&SP_MainDef); M_SetupNextMenu(&SP_MainDef);
} }
@ -4768,14 +4776,63 @@ void M_ForceSaveSlotSelected(INT32 sslot)
static void M_SetupChoosePlayer(INT32 choice) static void M_SetupChoosePlayer(INT32 choice)
{ {
INT32 skinnum;
UINT8 i;
UINT8 firstvalid = 255;
UINT8 lastvalid = 0;
char *name;
(void)choice; (void)choice;
if (mapheaderinfo[startmap-1] && mapheaderinfo[startmap-1]->forcecharacter[0] != '\0') if (PlayerMenu[0].status & (IT_DYBIGSPACE)) // Correcting a hack that may be made below.
PlayerMenu[0].status = (IT_DISABLED|(PlayerMenu[0].status & IT_CENTER));
for (i = 0; i < 32; i++) // Handle charsels, availability, and unlocks.
{ {
M_ChoosePlayer(0); //oh for crying out loud just get STARTED, it doesn't matter! if (PlayerMenu[i].status != IT_DISABLED) // If the character's disabled through SOC, there's nothing we can do for it.
{
name = strtok(Z_StrDup(description[i].skinname), "&");
skinnum = R_SkinAvailable(name);
if ((skinnum != -1) && (R_SkinUnlock(skinnum)))
{
// Handling order.
if (firstvalid == 255)
firstvalid = i;
else
{
description[i].prev = lastvalid;
description[lastvalid].next = i;
}
lastvalid = i;
// Handling visibility.
if (PlayerMenu[i].status & (IT_DISABLED|IT_CENTER))
PlayerMenu[i].status = IT_CALL;
if (description[i].picname[0] == '\0')
strncpy(description[i].picname, skins[skinnum].charsel, 8);
}
else // Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them.
PlayerMenu[i].status = (IT_DISABLED|IT_CENTER);
Z_Free(name);
}
}
if ((firstvalid != 255)
&& !(mapheaderinfo[startmap-1]
&& (mapheaderinfo[startmap-1]->forcecharacter[0] != '\0')
)
)
{ // One last bit of order we can't do in the iteration above.
description[firstvalid].prev = lastvalid;
description[lastvalid].next = firstvalid;
}
else // We're being forced into a specific character, so might as well.
{
PlayerMenu[0].status = (IT_CALL|IT_DYBIGSPACE|(PlayerMenu[0].status & IT_CENTER)); // This is a hack to make a non-IT_CALL character in slot 0 not softlock the game. IT_DYBIGSPACE is a dummy flag, whilst IT_CENTER is preserved.
M_ChoosePlayer(0);
return; return;
} }
if (Playing() == false) if (Playing() == false)
{ {
S_StopMusic(); S_StopMusic();
@ -4794,8 +4851,9 @@ static void M_DrawSetupChoosePlayerMenu(void)
{ {
const INT32 my = 24; const INT32 my = 24;
patch_t *patch; patch_t *patch;
INT32 i, o, j; INT32 i, o;
char *picname; UINT8 prev, next;
boolean loophack = false;
// Black BG // Black BG
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
@ -4804,91 +4862,76 @@ static void M_DrawSetupChoosePlayerMenu(void)
// Character select profile images!1 // Character select profile images!1
M_DrawTextBox(0, my, 16, 20); M_DrawTextBox(0, my, 16, 20);
if (abs(itemOn*128*FRACUNIT - char_scroll) > 256*FRACUNIT) i = (itemOn*128 - (char_scroll / FRACUNIT));
char_scroll = itemOn*128*FRACUNIT;
else if (itemOn*128*FRACUNIT - char_scroll > 128*FRACUNIT) if (!char_notes)
char_scroll += 48*FRACUNIT; {
else if (itemOn*128*FRACUNIT - char_scroll < -128*FRACUNIT) if (i) // turns out this and the preceding check is better then (abs(i) > 128)
char_scroll -= 48*FRACUNIT; {
else if (itemOn*128*FRACUNIT > char_scroll+16*FRACUNIT) o = (lastdirection) ? -1 : 1;
char_scroll += 16*FRACUNIT; char_scroll = (itemOn + o)*128*FRACUNIT;
else if (itemOn*128*FRACUNIT < char_scroll-16*FRACUNIT) i = -o*128;
char_scroll -= 16*FRACUNIT; }
char_notes = V_WordWrap(0, 21*8, V_ALLOWLOWERCASE, description[itemOn].notes);
}
if (abs(i) > 1)
char_scroll += i*FRACUNIT>>2;
else // close enough. else // close enough.
char_scroll = itemOn*128*FRACUNIT; // just be exact now. char_scroll = itemOn*128*FRACUNIT; // just be exact now.
i = (char_scroll+16*FRACUNIT)/(128*FRACUNIT);
o = ((char_scroll/FRACUNIT)+16)%128;
// prev character o = ((char_scroll / FRACUNIT) + 16);
if (i-1 >= 0 && PlayerMenu[i-1].status != IT_DISABLED
&& o < 32) if (o < 0) // This hack is to prevent visual glitches when looping from the last character to the 1st character.
loophack = true;
if (loophack)
o += 128;
i = (o / 128);
o = (o % 128);
if (loophack)
i = description[i].prev;
// Get prev character...
prev = description[i].prev;
if (prev != i) // If there's more than one character available...
{ {
picname = description[i-1].picname; // Let's get the next character now.
if (picname[0] == '\0') next = description[i].next;
// Draw prev character if it's visible and its number isn't greater than the current one or there's more than two
if (o < 32) // (prev != i) was previously a part of this, but we don't need to check again after above.
{ {
picname = strtok(Z_StrDup(description[i-1].skinname), "&"); patch = W_CachePatchName(description[prev].picname, PU_CACHE);
for (j = 0; j < numskins; j++) if (SHORT(patch->width) >= 256)
if (stricmp(skins[j].name, picname) == 0) V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT/2, 0, patch, 0, SHORT(patch->height) - 64 + o*2, SHORT(patch->width), SHORT(patch->height));
{ else
Z_Free(picname); V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT, 0, patch, 0, SHORT(patch->height) - 32 + o, SHORT(patch->width), SHORT(patch->height));
picname = skins[j].charsel; W_UnlockCachedPatch(patch);
break;
}
if (j == numskins) // AAAAAAAAAA
picname = skins[0].charsel;
} }
patch = W_CachePatchName(picname, PU_CACHE);
if (SHORT(patch->width) >= 256) // Draw next character if it's visible and its number isn't less than the current one or there's more than two
V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT/2, 0, patch, 0, SHORT(patch->height) - 64 + o*2, SHORT(patch->width), SHORT(patch->height)); if (o < 128) // (next != i) was previously a part of this, but it's implicitly true if (prev != i) is true.
else {
V_DrawCroppedPatch(8<<FRACBITS, (my + 8)<<FRACBITS, FRACUNIT, 0, patch, 0, SHORT(patch->height) - 32 + o, SHORT(patch->width), SHORT(patch->height)); patch = W_CachePatchName(description[next].picname, PU_CACHE);
W_UnlockCachedPatch(patch); if (SHORT(patch->width) >= 256)
V_DrawCroppedPatch(8<<FRACBITS, (my + 168 - o)<<FRACBITS, FRACUNIT/2, 0, patch, 0, 0, SHORT(patch->width), o*2);
else
V_DrawCroppedPatch(8<<FRACBITS, (my + 168 - o)<<FRACBITS, FRACUNIT, 0, patch, 0, 0, SHORT(patch->width), o);
W_UnlockCachedPatch(patch);
}
// current character
if (PlayerMenu[i].status & IT_DISABLED) // Prevent flickering.
i = (lastdirection) ? prev : next; // This actually causes duplication at slow scroll speeds (<16FU per tic), but thankfully we always go quickly.
} }
// next character if (!(PlayerMenu[i].status & IT_DISABLED))
if (i+1 < currentMenu->numitems && PlayerMenu[i+1].status != IT_DISABLED
&& o < 128)
{ {
picname = description[i+1].picname; patch = W_CachePatchName(description[i].picname, PU_CACHE);
if (picname[0] == '\0')
{
picname = strtok(Z_StrDup(description[i+1].skinname), "&");
for (j = 0; j < numskins; j++)
if (stricmp(skins[j].name, picname) == 0)
{
Z_Free(picname);
picname = skins[j].charsel;
break;
}
if (j == numskins) // AAAAAAAAAA
picname = skins[0].charsel;
}
patch = W_CachePatchName(picname, PU_CACHE);
if (SHORT(patch->width) >= 256)
V_DrawCroppedPatch(8<<FRACBITS, (my + 168 - o)<<FRACBITS, FRACUNIT/2, 0, patch, 0, 0, SHORT(patch->width), o*2);
else
V_DrawCroppedPatch(8<<FRACBITS, (my + 168 - o)<<FRACBITS, FRACUNIT, 0, patch, 0, 0, SHORT(patch->width), o);
W_UnlockCachedPatch(patch);
}
// current character
if (i < currentMenu->numitems && PlayerMenu[i].status != IT_DISABLED)
{
picname = description[i].picname;
if (picname[0] == '\0')
{
picname = strtok(Z_StrDup(description[i].skinname), "&");
for (j = 0; j < numskins; j++)
if (stricmp(skins[j].name, picname) == 0)
{
Z_Free(picname);
picname = skins[j].charsel;
break;
}
if (j == numskins) // AAAAAAAAAA
picname = skins[0].charsel;
}
patch = W_CachePatchName(picname, PU_CACHE);
if (o >= 0 && o <= 32) if (o >= 0 && o <= 32)
{ {
if (SHORT(patch->width) >= 256) if (SHORT(patch->width) >= 256)
@ -4911,8 +4954,6 @@ static void M_DrawSetupChoosePlayerMenu(void)
// Character description // Character description
M_DrawTextBox(136, my, 21, 20); M_DrawTextBox(136, my, 21, 20);
if (!char_notes)
char_notes = V_WordWrap(0, 21*8, V_ALLOWLOWERCASE, description[itemOn].notes);
V_DrawString(146, my + 9, V_RETURN8|V_ALLOWLOWERCASE, char_notes); V_DrawString(146, my + 9, V_RETURN8|V_ALLOWLOWERCASE, char_notes);
} }
@ -4923,8 +4964,8 @@ static void M_ChoosePlayer(INT32 choice)
INT32 skinnum; INT32 skinnum;
boolean ultmode = (ultimate_selectable && SP_PlayerDef.prevMenu == &SP_LoadDef && saveSlotSelected == NOSAVESLOT); boolean ultmode = (ultimate_selectable && SP_PlayerDef.prevMenu == &SP_LoadDef && saveSlotSelected == NOSAVESLOT);
// skip this if forcecharacter // skip this if forcecharacter or no characters available
if (mapheaderinfo[startmap-1] && mapheaderinfo[startmap-1]->forcecharacter[0] == '\0') if (!(PlayerMenu[choice].status & IT_DYBIGSPACE))
{ {
// M_SetupChoosePlayer didn't call us directly, that means we've been properly set up. // M_SetupChoosePlayer didn't call us directly, that means we've been properly set up.
char_scroll = itemOn*128*FRACUNIT; // finish scrolling the menu char_scroll = itemOn*128*FRACUNIT; // finish scrolling the menu
@ -6470,6 +6511,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
static void M_HandleSetupMultiPlayer(INT32 choice) static void M_HandleSetupMultiPlayer(INT32 choice)
{ {
size_t l; size_t l;
INT32 prev_setupm_fakeskin;
boolean exitmenu = false; // exit to previous menu and send name change boolean exitmenu = false; // exit to previous menu and send name change
switch (choice) switch (choice)
@ -6488,7 +6530,14 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
if (itemOn == 2) //player skin if (itemOn == 2) //player skin
{ {
S_StartSound(NULL,sfx_menu1); // Tails S_StartSound(NULL,sfx_menu1); // Tails
setupm_fakeskin--; prev_setupm_fakeskin = setupm_fakeskin;
do
{
setupm_fakeskin--;
if (setupm_fakeskin < 0)
setupm_fakeskin = numskins-1;
}
while ((prev_setupm_fakeskin != setupm_fakeskin) && !(R_SkinUnlock(setupm_fakeskin)));
} }
else if (itemOn == 1) // player color else if (itemOn == 1) // player color
{ {
@ -6501,7 +6550,14 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
if (itemOn == 2) //player skin if (itemOn == 2) //player skin
{ {
S_StartSound(NULL,sfx_menu1); // Tails S_StartSound(NULL,sfx_menu1); // Tails
setupm_fakeskin++; prev_setupm_fakeskin = setupm_fakeskin;
do
{
setupm_fakeskin++;
if (setupm_fakeskin > numskins-1)
setupm_fakeskin = 0;
}
while ((prev_setupm_fakeskin != setupm_fakeskin) && !(R_SkinUnlock(setupm_fakeskin)));
} }
else if (itemOn == 1) // player color else if (itemOn == 1) // player color
{ {
@ -6535,12 +6591,6 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
break; break;
} }
// check skin
if (setupm_fakeskin < 0)
setupm_fakeskin = numskins-1;
if (setupm_fakeskin > numskins-1)
setupm_fakeskin = 0;
// check color // check color
if (setupm_fakecolor < 1) if (setupm_fakecolor < 1)
setupm_fakecolor = MAXSKINCOLORS-1; setupm_fakecolor = MAXSKINCOLORS-1;

View File

@ -79,7 +79,7 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt);
#define IT_SUBMENU 6 // go to sub menu #define IT_SUBMENU 6 // go to sub menu
#define IT_CVAR 8 // handle as a cvar #define IT_CVAR 8 // handle as a cvar
#define IT_SPACE 10 // no handling #define IT_SPACE 10 // no handling
#define IT_MSGHANDLER 12 // same as key but with event and sometime can handle y/n key (special for message #define IT_MSGHANDLER 12 // same as key but with event and sometime can handle y/n key (special for message)
#define IT_DISPLAY (48+64+128) // 16+32+64+128 #define IT_DISPLAY (48+64+128) // 16+32+64+128
#define IT_NOTHING 0 // space #define IT_NOTHING 0 // space
@ -177,6 +177,9 @@ typedef struct
char notes[441]; char notes[441];
char picname[8]; char picname[8];
char skinname[SKINNAMESIZE*2+2]; // skin&skin\0 char skinname[SKINNAMESIZE*2+2]; // skin&skin\0
UINT16 wadnum; // for duplicate characters
UINT8 prev;
UINT8 next;
} description_t; } description_t;
// mode descriptions for video mode menu // mode descriptions for video mode menu

View File

@ -2323,158 +2323,3 @@ void M_SetupMemcpy(void)
M_Memcpy = cpu_cpy; M_Memcpy = cpu_cpy;
#endif #endif
} }
// A partial implementation of AA trees,
// according to the algorithms given on Wikipedia.
// http://en.wikipedia.org/wiki/AA_tree
typedef struct aatree_node_s
{
INT32 level;
INT32 key;
void* value;
struct aatree_node_s *left, *right;
} aatree_node_t;
struct aatree_s
{
aatree_node_t *root;
UINT32 flags;
};
aatree_t *M_AATreeAlloc(UINT32 flags)
{
aatree_t *aatree = Z_Malloc(sizeof (aatree_t), PU_STATIC, NULL);
aatree->root = NULL;
aatree->flags = flags;
return aatree;
}
static void M_AATreeFree_Node(aatree_node_t *node)
{
if (node->left) M_AATreeFree_Node(node->left);
if (node->right) M_AATreeFree_Node(node->right);
Z_Free(node);
}
void M_AATreeFree(aatree_t *aatree)
{
if (aatree->root)
M_AATreeFree_Node(aatree->root);
Z_Free(aatree);
}
static aatree_node_t *M_AATreeSkew(aatree_node_t *node)
{
if (node && node->left && node->left->level == node->level)
{
// Not allowed: horizontal left-link. Reverse the
// horizontal link and hook the orphan back in.
aatree_node_t *oldleft = node->left;
node->left = oldleft->right;
oldleft->right = node;
return oldleft;
}
// No change needed.
return node;
}
static aatree_node_t *M_AATreeSplit(aatree_node_t *node)
{
if (node && node->right && node->right->right && node->level == node->right->right->level)
{
// Not allowed: two consecutive horizontal right-links.
// The middle one becomes the new root at this point,
// with suitable adjustments below.
aatree_node_t *oldright = node->right;
node->right = oldright->left;
oldright->left = node;
oldright->level++;
return oldright;
}
// No change needed.
return node;
}
static aatree_node_t *M_AATreeSet_Node(aatree_node_t *node, UINT32 flags, INT32 key, void* value)
{
if (!node)
{
// Nothing here, so just add where we are
node = Z_Malloc(sizeof (aatree_node_t), PU_STATIC, NULL);
node->level = 1;
node->key = key;
if (value && (flags & AATREE_ZUSER)) Z_SetUser(value, &node->value);
else node->value = value;
node->left = node->right = NULL;
}
else
{
if (key < node->key)
node->left = M_AATreeSet_Node(node->left, flags, key, value);
else if (key > node->key)
node->right = M_AATreeSet_Node(node->right, flags, key, value);
else
{
if (value && (flags & AATREE_ZUSER)) Z_SetUser(value, &node->value);
else node->value = value;
}
node = M_AATreeSkew(node);
node = M_AATreeSplit(node);
}
return node;
}
void M_AATreeSet(aatree_t *aatree, INT32 key, void* value)
{
aatree->root = M_AATreeSet_Node(aatree->root, aatree->flags, key, value);
}
// Caveat: we don't distinguish between nodes that don't exists
// and nodes with value == NULL.
static void *M_AATreeGet_Node(aatree_node_t *node, INT32 key)
{
if (node)
{
if (node->key == key)
return node->value;
else if(node->key < key)
return M_AATreeGet_Node(node->right, key);
else
return M_AATreeGet_Node(node->left, key);
}
return NULL;
}
void *M_AATreeGet(aatree_t *aatree, INT32 key)
{
return M_AATreeGet_Node(aatree->root, key);
}
static void M_AATreeIterate_Node(aatree_node_t *node, aatree_iter_t callback)
{
if (node->left) M_AATreeIterate_Node(node->left, callback);
callback(node->key, node->value);
if (node->right) M_AATreeIterate_Node(node->right, callback);
}
void M_AATreeIterate(aatree_t *aatree, aatree_iter_t callback)
{
if (aatree->root)
M_AATreeIterate_Node(aatree->root, callback);
}

View File

@ -96,19 +96,6 @@ void M_SetupMemcpy(void);
// counting bits, for weapon ammo code, usually // counting bits, for weapon ammo code, usually
FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size); FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size);
// Flags for AA trees.
#define AATREE_ZUSER 1 // Treat values as z_zone-allocated blocks and set their user fields
typedef struct aatree_s aatree_t;
typedef void (*aatree_iter_t)(INT32 key, void *value);
aatree_t *M_AATreeAlloc(UINT32 flags);
void M_AATreeFree(aatree_t *aatree);
void M_AATreeSet(aatree_t *aatree, INT32 key, void* value);
void *M_AATreeGet(aatree_t *aatree, INT32 key);
void M_AATreeIterate(aatree_t *aatree, aatree_iter_t callback);
// Nasty cyclic dependency workaround. This must come after aatree stuff.
#include "w_wad.h" #include "w_wad.h"
extern char configfile[MAX_WADPATH]; extern char configfile[MAX_WADPATH];

View File

@ -3950,6 +3950,7 @@ void A_UnsetSolidSteam(mobj_t *actor)
void A_SignPlayer(mobj_t *actor) void A_SignPlayer(mobj_t *actor)
{ {
mobj_t *ov; mobj_t *ov;
skin_t *skin;
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
if (LUA_CallAction("A_SignPlayer", actor)) if (LUA_CallAction("A_SignPlayer", actor))
return; return;
@ -3960,15 +3961,35 @@ void A_SignPlayer(mobj_t *actor)
if (!actor->target->player) if (!actor->target->player)
return; return;
// Set the sign to be an appropriate background color for this player's skincolor. skin = &skins[actor->target->player->skin];
actor->color = Color_Opposite[actor->target->player->skincolor*2];
actor->frame += Color_Opposite[actor->target->player->skincolor*2+1]; if ((actor->target->player->skincolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor?
{
actor->color = skin->prefoppositecolor;
/*
If you're here from the comment above Color_Opposite,
the following line is the one which is dependent on the
array being symmetrical. It gets the opposite of the
opposite of your desired colour just so it can get the
brightness frame for the End Sign. It's not a great
design choice, but it's constant time array access and
the idea that the colours should be OPPOSITES is kind
of in the name. If you have a better idea, feel free
to let me know. ~toast 2016/07/20
*/
actor->frame += Color_Opposite[Color_Opposite[skin->prefoppositecolor*2]*2+1];
}
else // Set the sign to be an appropriate background color for this player's skincolor.
{
actor->color = Color_Opposite[actor->target->player->skincolor*2];
actor->frame += Color_Opposite[actor->target->player->skincolor*2+1];
}
// spawn an overlay of the player's face. // spawn an overlay of the player's face.
ov = P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY); ov = P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY);
P_SetTarget(&ov->target, actor); P_SetTarget(&ov->target, actor);
ov->color = actor->target->player->skincolor; ov->color = actor->target->player->skincolor;
ov->skin = &skins[actor->target->player->skin]; ov->skin = skin;
P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN
} }
@ -5408,8 +5429,8 @@ void A_MixUp(mobj_t *actor)
// Zoom tube stuff // Zoom tube stuff
mobj_t *tempthing = NULL; //tracer mobj_t *tempthing = NULL; //tracer
pflags_t flags1,flags2; //player pflags UINT16 carry1,carry2; //carry
INT32 transspeed; //player speed INT32 transspeed; //player speed
// Starpost stuff // Starpost stuff
INT16 starpostx, starposty, starpostz; INT16 starpostx, starposty, starpostz;
@ -5446,8 +5467,8 @@ void A_MixUp(mobj_t *actor)
players[two].speed = transspeed; players[two].speed = transspeed;
//set flags variables now but DON'T set them. //set flags variables now but DON'T set them.
flags1 = (players[one].pflags & (PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG)); carry1 = (players[one].powers[pw_carry] == CR_PLAYER ? CR_NONE : players[one].powers[pw_carry]);
flags2 = (players[two].pflags & (PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG)); carry2 = (players[two].powers[pw_carry] == CR_PLAYER ? CR_NONE : players[two].powers[pw_carry]);
x = players[one].mo->x; x = players[one].mo->x;
y = players[one].mo->y; y = players[one].mo->y;
@ -5472,12 +5493,10 @@ void A_MixUp(mobj_t *actor)
starpostnum, starposttime, starpostangle, starpostnum, starposttime, starpostangle,
mflags2); mflags2);
//flags set after mixup. Stupid P_ResetPlayer() takes away some of the flags we look for... //carry set after mixup. Stupid P_ResetPlayer() takes away some of the stuff we look for...
//but not all of them! So we need to make sure they aren't set wrong or anything. //but not all of it! So we need to make sure they aren't set wrong or anything.
players[one].pflags &= ~(PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG); players[one].powers[pw_carry] = carry2;
players[one].pflags |= flags2; players[two].powers[pw_carry] = carry1;
players[two].pflags &= ~(PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG);
players[two].pflags |= flags1;
teleported[one] = true; teleported[one] = true;
teleported[two] = true; teleported[two] = true;
@ -5489,8 +5508,9 @@ void A_MixUp(mobj_t *actor)
INT32 pindex[MAXPLAYERS], counter = 0, teleportfrom = 0; INT32 pindex[MAXPLAYERS], counter = 0, teleportfrom = 0;
// Zoom tube stuff // Zoom tube stuff
mobj_t *transtracer[MAXPLAYERS]; //tracer mobj_t *transtracer[MAXPLAYERS]; //tracer
pflags_t transflag[MAXPLAYERS]; //player pflags //pflags_t transflag[MAXPLAYERS]; //cyan pink white pink cyan
UINT16 transcarry[MAXPLAYERS]; //player carry
INT32 transspeed[MAXPLAYERS]; //player speed INT32 transspeed[MAXPLAYERS]; //player speed
// Star post stuff // Star post stuff
@ -5524,7 +5544,7 @@ void A_MixUp(mobj_t *actor)
players[i].rmomx = players[i].rmomy = 1; players[i].rmomx = players[i].rmomy = 1;
players[i].cmomx = players[i].cmomy = 0; players[i].cmomx = players[i].cmomy = 0;
transflag[counter] = (players[i].pflags & (PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG)); transcarry[counter] = (players[i].powers[pw_carry] == CR_PLAYER ? CR_NONE : players[i].powers[pw_carry]);
transspeed[counter] = players[i].speed; transspeed[counter] = players[i].speed;
transtracer[counter] = players[i].mo->tracer; transtracer[counter] = players[i].mo->tracer;
@ -5576,9 +5596,8 @@ void A_MixUp(mobj_t *actor)
starpostnum[teleportfrom], starposttime[teleportfrom], starpostangle[teleportfrom], starpostnum[teleportfrom], starposttime[teleportfrom], starpostangle[teleportfrom],
flags2[teleportfrom]); flags2[teleportfrom]);
//...flags after. same reasoning. //...carry after. same reasoning.
players[i].pflags &= ~(PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG); players[i].powers[pw_carry] = transcarry[teleportfrom];
players[i].pflags |= transflag[teleportfrom];
teleported[i] = true; teleported[i] = true;
counter++; counter++;
@ -6145,7 +6164,7 @@ void A_Boss7Chase(mobj_t *actor)
if (actor->health <= actor->info->damage if (actor->health <= actor->info->damage
&& actor->target && actor->target
&& actor->target->player && actor->target->player
&& (actor->target->player->pflags & PF_ITEMHANG)) && (actor->target->player->powers[pw_carry] == CR_GENERIC))
{ {
A_FaceTarget(actor); A_FaceTarget(actor);
P_SetMobjState(actor, S_BLACKEGG_SHOOT1); P_SetMobjState(actor, S_BLACKEGG_SHOOT1);
@ -8019,7 +8038,7 @@ void A_OrbitNights(mobj_t* actor)
#endif #endif
if (!actor->target || !actor->target->player || if (!actor->target || !actor->target->player ||
!actor->target->tracer || !actor->target->player->nightstime !(actor->target->player->pflags & PF_NIGHTSMODE) || !actor->target->player->nightstime
// Also remove this object if they no longer have a NiGHTS helper // Also remove this object if they no longer have a NiGHTS helper
|| (ishelper && !actor->target->player->powers[pw_nights_helper])) || (ishelper && !actor->target->player->powers[pw_nights_helper]))
{ {
@ -8038,14 +8057,23 @@ void A_OrbitNights(mobj_t* actor)
const fixed_t fh = FixedMul(FINECOSINE(ofa),FixedMul(20*FRACUNIT, actor->scale)); const fixed_t fh = FixedMul(FINECOSINE(ofa),FixedMul(20*FRACUNIT, actor->scale));
const fixed_t fs = FixedMul(FINESINE(fa),FixedMul(32*FRACUNIT, actor->scale)); const fixed_t fs = FixedMul(FINESINE(fa),FixedMul(32*FRACUNIT, actor->scale));
actor->x = actor->target->tracer->x + fc; actor->x = actor->target->x + fc;
actor->y = actor->target->tracer->y + fs; actor->y = actor->target->y + fs;
actor->z = actor->target->tracer->z + fh + FixedMul(16*FRACUNIT, actor->scale); actor->z = actor->target->z + fh + FixedMul(16*FRACUNIT, actor->scale);
// Semi-lazy hack // Semi-lazy hack
actor->angle = (angle_t)actor->extravalue1 + ANGLE_90; actor->angle = (angle_t)actor->extravalue1 + ANGLE_90;
} }
P_SetThingPosition(actor); P_SetThingPosition(actor);
if (ishelper) // Flash a helper that's about to be removed.
{
if ((actor->target->player->powers[pw_nights_helper] < TICRATE)
&& (actor->target->player->powers[pw_nights_helper] & 1))
actor->flags2 |= MF2_DONTDRAW;
else
actor->flags2 &= ~MF2_DONTDRAW;
}
} }
} }

View File

@ -1163,7 +1163,7 @@ void T_SpikeSector(levelspecthink_t *spikes)
node = spikes->sector->touching_thinglist; // things touching this sector node = spikes->sector->touching_thinglist; // things touching this sector
for (; node; node = node->m_snext) for (; node; node = node->m_thinglist_next)
{ {
thing = node->m_thing; thing = node->m_thing;
if (!thing->player) if (!thing->player)
@ -1314,7 +1314,7 @@ void T_BridgeThinker(levelspecthink_t *bridge)
controlsec = &sectors[k]; controlsec = &sectors[k];
// Is a player standing on me? // Is a player standing on me?
for (node = sector->touching_thinglist; node; node = node->m_snext) for (node = sector->touching_thinglist; node; node = node->m_thinglist_next)
{ {
thing = node->m_thing; thing = node->m_thing;
@ -1737,7 +1737,7 @@ wegotit:
static mobj_t *SearchMarioNode(msecnode_t *node) static mobj_t *SearchMarioNode(msecnode_t *node)
{ {
mobj_t *thing = NULL; mobj_t *thing = NULL;
for (; node; node = node->m_snext) for (; node; node = node->m_thinglist_next)
{ {
// Things which should NEVER be ejected from a MarioBlock, by type. // Things which should NEVER be ejected from a MarioBlock, by type.
switch (node->m_thing->type) switch (node->m_thing->type)
@ -2009,7 +2009,7 @@ void T_NoEnemiesSector(levelspecthink_t *nobaddies)
&& thing->z < upperbound && thing->z+thing->height > lowerbound) && thing->z < upperbound && thing->z+thing->height > lowerbound)
return; return;
node = node->m_snext; node = node->m_thinglist_next;
} }
} }
} }
@ -2027,7 +2027,7 @@ void T_NoEnemiesSector(levelspecthink_t *nobaddies)
&& thing->z < upperbound && thing->z+thing->height > lowerbound) && thing->z < upperbound && thing->z+thing->height > lowerbound)
return; return;
node = node->m_snext; node = node->m_thinglist_next;
} }
} }
} }
@ -2306,7 +2306,7 @@ void T_RaiseSector(levelspecthink_t *raise)
sector = &sectors[i]; sector = &sectors[i];
// Is a player standing on me? // Is a player standing on me?
for (node = sector->touching_thinglist; node; node = node->m_snext) for (node = sector->touching_thinglist; node; node = node->m_thinglist_next)
{ {
thing = node->m_thing; thing = node->m_thing;

View File

@ -303,7 +303,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
} }
if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING))
|| (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)) || ((player->pflags & PF_JUMPED) && !(player->charflags & SF_NOJUMPDAMAGE && !(player->charability == CA_TWINSPIN && player->panim == PA_ABILITY)))
|| (player->pflags & (PF_SPINNING|PF_GLIDING))
|| (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)
|| ((player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0))
|| player->powers[pw_invulnerability] || player->powers[pw_super] || player->powers[pw_invulnerability] || player->powers[pw_super]
|| elementalpierce) // Do you possess the ability to subdue the object? || elementalpierce) // Do you possess the ability to subdue the object?
{ {
@ -347,7 +350,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
P_DamageMobj(toucher, special, special, 1, 0); P_DamageMobj(toucher, special, special, 1, 0);
} }
else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING))
|| (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)) || ((player->pflags & PF_JUMPED) && !(player->charflags & SF_NOJUMPDAMAGE && !(player->charability == CA_TWINSPIN && player->panim == PA_ABILITY)))
|| (player->pflags & (PF_SPINNING|PF_GLIDING))
|| (player->charability2 == CA2_MELEE && player->panim == PA_ABILITY2)
|| ((player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0))
|| player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object? || player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object?
{ {
if ((P_MobjFlip(toucher)*toucher->momz < 0) && !elementalpierce) if ((P_MobjFlip(toucher)*toucher->momz < 0) && !elementalpierce)
@ -650,16 +656,16 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (G_IsSpecialStage(gamemap)) //After-mare bonus time/emerald reward in special stages. if (G_IsSpecialStage(gamemap)) //After-mare bonus time/emerald reward in special stages.
{ {
// only allow the player with the emerald in-hand to leave. // only allow the player with the emerald in-hand to leave.
if (toucher->tracer && toucher->tracer->target if (toucher->tracer
&& toucher->tracer->target->type == MT_GOTEMERALD) && toucher->tracer->type == MT_GOTEMERALD)
{ {
} }
else // Make sure that SOMEONE has the emerald, at least! else // Make sure that SOMEONE has the emerald, at least!
{ {
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].playerstate == PST_LIVE if (playeringame[i] && players[i].playerstate == PST_LIVE
&& players[i].mo->tracer && players[i].mo->tracer->target && players[i].mo->tracer
&& players[i].mo->tracer->target->type == MT_GOTEMERALD) && players[i].mo->tracer->type == MT_GOTEMERALD)
return; return;
// Well no one has an emerald, so exit anyway! // Well no one has an emerald, so exit anyway!
} }
@ -1247,10 +1253,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
player->powers[pw_ingoop] = 2; player->powers[pw_ingoop] = 2;
if (player->pflags & PF_ITEMHANG) if (player->powers[pw_carry] == CR_GENERIC)
{ {
P_SetTarget(&toucher->tracer, NULL); P_SetTarget(&toucher->tracer, NULL);
player->pflags &= ~PF_ITEMHANG; player->powers[pw_carry] = CR_NONE;
} }
P_ResetPlayer(player); P_ResetPlayer(player);
@ -1302,7 +1308,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
S_StartSound(toucher, special->info->painsound); S_StartSound(toucher, special->info->painsound);
return; return;
} }
else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING)) || (player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)) else if (((player->pflags & PF_NIGHTSMODE) && (player->pflags & PF_DRILLING))
|| ((player->pflags & PF_JUMPED) && !(player->charflags & SF_NOJUMPDAMAGE))
|| ((player->charflags & SF_STOMPDAMAGE) && (P_MobjFlip(toucher)*(toucher->z - (special->z + special->height/2)) > 0) && (P_MobjFlip(toucher)*toucher->momz < 0))
|| (player->pflags & (PF_SPINNING|PF_GLIDING))
|| player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object? || player->powers[pw_invulnerability] || player->powers[pw_super]) // Do you possess the ability to subdue the object?
{ {
// Shatter the shield! // Shatter the shield!
@ -1332,7 +1341,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
case MT_BIGMACECHAIN: case MT_BIGMACECHAIN:
// Is this the last link in the chain? // Is this the last link in the chain?
if (toucher->momz > 0 || !(special->flags & MF_AMBUSH) if (toucher->momz > 0 || !(special->flags & MF_AMBUSH)
|| (player->pflags & PF_ITEMHANG) || (player->pflags & PF_MACESPIN)) || (player->powers[pw_carry]))
return; return;
if (toucher->z > special->z + special->height/2) if (toucher->z > special->z + special->height/2)
@ -1349,12 +1358,12 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (special->target && (special->target->type == MT_SPINMACEPOINT || special->target->type == MT_HIDDEN_SLING)) if (special->target && (special->target->type == MT_SPINMACEPOINT || special->target->type == MT_HIDDEN_SLING))
{ {
player->pflags |= PF_MACESPIN; player->powers[pw_carry] = CR_MACESPIN;
S_StartSound(toucher, sfx_spin); S_StartSound(toucher, sfx_spin);
P_SetPlayerMobjState(toucher, S_PLAY_SPIN); P_SetPlayerMobjState(toucher, S_PLAY_SPIN);
} }
else else
player->pflags |= PF_ITEMHANG; player->powers[pw_carry] = CR_GENERIC;
// Can't jump first frame // Can't jump first frame
player->pflags |= PF_JUMPSTASIS; player->pflags |= PF_JUMPSTASIS;
@ -2258,7 +2267,11 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
target->momx = target->momy = target->momz = 0; target->momx = target->momy = target->momz = 0;
if (damagetype == DMG_DROWNED) // drowned if (damagetype == DMG_DROWNED) // drowned
{ {
S_StartSound(target, sfx_drown); target->movedir = damagetype; // we're MOVING the Damage Into anotheR function... Okay, this is a bit of a hack.
if (target->player->charflags & SF_MACHINE)
S_StartSound(target, sfx_fizzle);
else
S_StartSound(target, sfx_drown);
// Don't jump up when drowning // Don't jump up when drowning
} }
else else
@ -2478,7 +2491,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
} }
player->powers[pw_flashing] = flashingtics; player->powers[pw_flashing] = flashingtics;
P_SetMobjState(target->tracer, S_NIGHTSHURT1); P_SetPlayerMobjState(target, S_PLAY_NIGHTS_PAIN);
S_StartSound(target, sfx_nghurt); S_StartSound(target, sfx_nghurt);
if (oldnightstime > 10*TICRATE if (oldnightstime > 10*TICRATE
@ -2614,7 +2627,9 @@ static inline boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj
static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
{ {
player->pflags &= ~(PF_CARRIED|PF_SLIDING|PF_ITEMHANG|PF_MACESPIN|PF_ROPEHANG|PF_NIGHTSMODE); player->pflags &= ~(PF_SLIDING|PF_NIGHTSMODE);
player->powers[pw_carry] = CR_NONE;
// Burst weapons and emeralds in Match/CTF only // Burst weapons and emeralds in Match/CTF only
if (source && (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF)) if (source && (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF))
@ -3661,7 +3676,7 @@ void P_PlayerFlagBurst(player_t *player, boolean toss)
// Flag text // Flag text
{ {
char plname[MAXPLAYERNAME+4]; char plname[MAXPLAYERNAME+4];
char *flagtext; const char *flagtext;
char flagcolor; char flagcolor;
snprintf(plname, sizeof(plname), "%s%s%s", snprintf(plname, sizeof(plname), "%s%s%s",

View File

@ -62,6 +62,9 @@
#define mariomode (maptol & TOL_MARIO) #define mariomode (maptol & TOL_MARIO)
#define twodlevel (maptol & TOL_2D) #define twodlevel (maptol & TOL_2D)
#define P_GetPlayerHeight(player) FixedMul(player->height, player->mo->scale)
#define P_GetPlayerSpinHeight(player) FixedMul(player->spinheight, player->mo->scale)
// //
// P_TICK // P_TICK
// //
@ -119,8 +122,6 @@ extern consvar_t cv_cam2_speed, cv_cam2_rotate, cv_cam2_rotspeed;
extern fixed_t t_cam_dist, t_cam_height, t_cam_rotate; extern fixed_t t_cam_dist, t_cam_height, t_cam_rotate;
extern fixed_t t_cam2_dist, t_cam2_height, t_cam2_rotate; extern fixed_t t_cam2_dist, t_cam2_height, t_cam2_rotate;
fixed_t P_GetPlayerHeight(player_t *player);
fixed_t P_GetPlayerSpinHeight(player_t *player);
INT32 P_GetPlayerControlDirection(player_t *player); INT32 P_GetPlayerControlDirection(player_t *player);
void P_AddPlayerScore(player_t *player, UINT32 amount); void P_AddPlayerScore(player_t *player, UINT32 amount);
void P_ResetCamera(player_t *player, camera_t *thiscam); void P_ResetCamera(player_t *player, camera_t *thiscam);
@ -251,7 +252,8 @@ mobj_t *P_SPMAngle(mobj_t *source, mobjtype_t type, angle_t angle, UINT8 aimtype
#endif #endif
void P_ColorTeamMissile(mobj_t *missile, player_t *source); void P_ColorTeamMissile(mobj_t *missile, player_t *source);
SINT8 P_MobjFlip(mobj_t *mobj); SINT8 P_MobjFlip(mobj_t *mobj);
boolean P_WeaponOrPanel(mobjtype_t type); fixed_t P_GetMobjGravity(mobj_t *mo);
FUNCMATH boolean P_WeaponOrPanel(mobjtype_t type);
boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled); boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled);

View File

@ -129,6 +129,10 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
return false; return false;
} }
#ifdef ESLOPE
object->standingslope = NULL; // Okay, now we can't return - no launching off at silly angles for you.
#endif
object->eflags |= MFE_SPRUNG; // apply this flag asap! object->eflags |= MFE_SPRUNG; // apply this flag asap!
spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify
@ -207,7 +211,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
P_SetPlayerMobjState(object, S_PLAY_FALL); P_SetPlayerMobjState(object, S_PLAY_FALL);
else // horizontal spring else // horizontal spring
{ {
if (pflags & (PF_JUMPED|PF_SPINNING) && object->player->panim == PA_ROLL) if (pflags & (PF_JUMPED|PF_SPINNING) && (object->player->panim == PA_ROLL || object->player->panim == PA_JUMP || object->player->panim == PA_FALL))
object->player->pflags = pflags; object->player->pflags = pflags;
else else
P_SetPlayerMobjState(object, S_PLAY_WALK); P_SetPlayerMobjState(object, S_PLAY_WALK);
@ -232,20 +236,24 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
if (p && object->state == &states[object->info->painstate]) // can't use fans and gas jets when player is in pain! if (p && object->state == &states[object->info->painstate]) // can't use fans and gas jets when player is in pain!
return; return;
// is object below thruster's position? if not, calculate distance between their bottoms // is object's top below thruster's position? if not, calculate distance between their bottoms
if (spring->eflags & MFE_VERTICALFLIP) if (spring->eflags & MFE_VERTICALFLIP)
{ {
if (object->z + object->height > spring->z + spring->height) if (object->z > spring->z + spring->height)
return; return;
zdist = (spring->z + spring->height) - (object->z + object->height); zdist = (spring->z + spring->height) - (object->z + object->height);
} }
else else
{ {
if (object->z < spring->z) if (object->z + object->height < spring->z)
return; return;
zdist = object->z - spring->z; zdist = object->z - spring->z;
} }
#ifdef ESLOPE
object->standingslope = NULL; // No launching off at silly angles for you.
#endif
switch (spring->type) switch (spring->type)
{ {
case MT_FAN: // fan case MT_FAN: // fan
@ -294,12 +302,17 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
INT32 p; INT32 p;
fixed_t zdist; // z distance between the two players' bottoms fixed_t zdist; // z distance between the two players' bottoms
if ((tails->pflags & PF_CARRIED) && tails->mo->tracer == sonic->mo) if (tails->powers[pw_carry])
return; return;
if ((sonic->pflags & PF_CARRIED) && sonic->mo->tracer == tails->mo) if (sonic->powers[pw_carry])
return; return;
if (!tails->powers[pw_tailsfly] && !(tails->charability == CA_FLY && tails->mo->state-states == S_PLAY_FLY_TIRED)) if (tails->spectator)
return;
if (sonic->spectator)
return;
if (!(tails->pflags & PF_CANCARRY))
return; return;
if (tails->bot == 1) if (tails->bot == 1)
@ -308,10 +321,6 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
if (sonic->pflags & PF_NIGHTSMODE) if (sonic->pflags & PF_NIGHTSMODE)
return; return;
if (sonic->mo->tracer && sonic->mo->tracer->type == MT_TUBEWAYPOINT
&& !(sonic->pflags & PF_ROPEHANG))
return; // don't steal players from zoomtubes!
if ((sonic->mo->eflags & MFE_VERTICALFLIP) != (tails->mo->eflags & MFE_VERTICALFLIP)) if ((sonic->mo->eflags & MFE_VERTICALFLIP) != (tails->mo->eflags & MFE_VERTICALFLIP))
return; // Both should be in same gravity return; // Both should be in same gravity
@ -326,47 +335,43 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
// Search in case another player is already being carried by this fox. // Search in case another player is already being carried by this fox.
for (p = 0; p < MAXPLAYERS; p++) for (p = 0; p < MAXPLAYERS; p++)
if (playeringame[p] && players[p].mo if (playeringame[p] && players[p].mo
&& players[p].pflags & PF_CARRIED && players[p].mo->tracer == tails->mo) && players[p].powers[pw_carry] == CR_PLAYER && players[p].mo->tracer == tails->mo)
return; return;
// Why block opposing teams from tailsflying each other?
// Sneaking into the hands of a flying tails player in Race might be a viable strategy, who knows.
/*
if (gametype == GT_RACE || gametype == GT_COMPETITION
|| (netgame && (tails->spectator || sonic->spectator))
|| (G_TagGametype() && (!(tails->pflags & PF_TAGIT) != !(sonic->pflags & PF_TAGIT)))
|| (gametype == GT_MATCH)
|| (G_GametypeHasTeams() && tails->ctfteam != sonic->ctfteam))
return; */
if (tails->mo->eflags & MFE_VERTICALFLIP) if (tails->mo->eflags & MFE_VERTICALFLIP)
zdist = (sonic->mo->z + sonic->mo->height) - (tails->mo->z + tails->mo->height); zdist = (sonic->mo->z + sonic->mo->height) - (tails->mo->z + tails->mo->height);
else else
zdist = tails->mo->z - sonic->mo->z; zdist = tails->mo->z - sonic->mo->z;
if (zdist <= sonic->mo->height + FixedMul(FRACUNIT, sonic->mo->scale) if (zdist <= sonic->mo->height + sonic->mo->scale // FixedMul(FRACUNIT, sonic->mo->scale), but scale == FRACUNIT by default
&& zdist > sonic->mo->height*2/3 && zdist > sonic->mo->height*2/3
&& P_MobjFlip(tails->mo)*sonic->mo->momz <= 0) && P_MobjFlip(tails->mo)*sonic->mo->momz <= 0)
{ {
// Why block opposing teams from tailsflying each other? if (sonic-players == consoleplayer && botingame)
// Sneaking into the hands of a flying tails player in Race might be a viable strategy, who knows. CV_SetValue(&cv_analog2, false);
/* P_ResetPlayer(sonic);
if (gametype == GT_RACE || gametype == GT_COMPETITION P_SetTarget(&sonic->mo->tracer, tails->mo);
|| (netgame && (tails->spectator || sonic->spectator)) sonic->powers[pw_carry] = CR_PLAYER;
|| (G_TagGametype() && (!(tails->pflags & PF_TAGIT) != !(sonic->pflags & PF_TAGIT))) S_StartSound(sonic->mo, sfx_s3k4a);
|| (gametype == GT_MATCH) P_UnsetThingPosition(sonic->mo);
|| (G_GametypeHasTeams() && tails->ctfteam != sonic->ctfteam)) sonic->mo->x = tails->mo->x;
sonic->pflags &= ~PF_CARRIED; */ sonic->mo->y = tails->mo->y;
if (tails->spectator || sonic->spectator) P_SetThingPosition(sonic->mo);
sonic->pflags &= ~PF_CARRIED;
else
{
if (sonic-players == consoleplayer && botingame)
CV_SetValue(&cv_analog2, false);
P_ResetPlayer(sonic);
P_SetTarget(&sonic->mo->tracer, tails->mo);
sonic->pflags |= PF_CARRIED;
S_StartSound(sonic->mo, sfx_s3k4a);
P_UnsetThingPosition(sonic->mo);
sonic->mo->x = tails->mo->x;
sonic->mo->y = tails->mo->y;
P_SetThingPosition(sonic->mo);
}
} }
else { else {
if (sonic-players == consoleplayer && botingame) if (sonic-players == consoleplayer && botingame)
CV_SetValue(&cv_analog2, true); CV_SetValue(&cv_analog2, true);
sonic->pflags &= ~PF_CARRIED; sonic->powers[pw_carry] = CR_NONE;
} }
} }
@ -435,7 +440,42 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true; // underneath return true; // underneath
if (thing->type == MT_SPIKE) if (thing->type == MT_SPIKE)
{ {
S_StartSound(tmthing, thing->info->deathsound); if (thing->flags & MF_SOLID)
S_StartSound(tmthing, thing->info->deathsound);
for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext)
if (thing->type == MT_SPIKE && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y) < FixedMul(56*FRACUNIT, thing->scale))
P_KillMobj(thing, tmthing, tmthing, 0);
}
else
{
thing->health = 0;
P_KillMobj(thing, tmthing, tmthing, 0);
}
return true;
}
// CA_DASHMODE users destroy spikes and monitors, CA_TWINSPIN users and CA2_MELEE users destroy spikes.
if ((tmthing->player)
&& (((tmthing->player->charability == CA_DASHMODE) && (tmthing->player->dashmode >= 3*TICRATE)
&& (thing->flags & (MF_MONITOR) || thing->type == MT_SPIKE))
|| ((((tmthing->player->charability == CA_TWINSPIN) && (tmthing->player->panim == PA_ABILITY))
|| (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2))
&& (thing->type == MT_SPIKE))))
{
if ((thing->flags & (MF_MONITOR)) && (thing->health <= 0 || !(thing->flags & MF_SHOOTABLE)))
return true;
blockdist = thing->radius + tmthing->radius;
if (abs(thing->x - tmx) >= blockdist || abs(thing->y - tmy) >= blockdist)
return true; // didn't hit it
// see if it went over / under
if (tmthing->z > thing->z + thing->height)
return true; // overhead
if (tmthing->z + tmthing->height < thing->z)
return true; // underneath
if (thing->type == MT_SPIKE)
{
if (thing->flags & MF_SOLID)
S_StartSound(tmthing, thing->info->deathsound);
for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext) for (thing = thing->subsector->sector->thinglist; thing; thing = thing->snext)
if (thing->type == MT_SPIKE && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y) < FixedMul(56*FRACUNIT, thing->scale)) if (thing->type == MT_SPIKE && thing->health > 0 && thing->flags & MF_SOLID && P_AproxDistance(thing->x - tmthing->x, thing->y - tmthing->y) < FixedMul(56*FRACUNIT, thing->scale))
P_KillMobj(thing, tmthing, tmthing, 0); P_KillMobj(thing, tmthing, tmthing, 0);
@ -623,7 +663,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (tmthing->flags & MF_MISSILE && thing->player && tmthing->target && tmthing->target->player if (tmthing->flags & MF_MISSILE && thing->player && tmthing->target && tmthing->target->player
&& thing->player->ctfteam == tmthing->target->player->ctfteam && thing->player->ctfteam == tmthing->target->player->ctfteam
&& thing->player->pflags & PF_CARRIED && thing->tracer == tmthing->target) && thing->player->powers[pw_carry] == CR_PLAYER && thing->tracer == tmthing->target)
return true; // Don't give rings to your carry player by accident. return true; // Don't give rings to your carry player by accident.
if (thing->type == MT_EGGSHIELD) if (thing->type == MT_EGGSHIELD)
@ -666,7 +706,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
&& tmthing->target != thing) && tmthing->target != thing)
{ {
// Hop on the missile for a ride! // Hop on the missile for a ride!
thing->player->pflags |= PF_ITEMHANG; thing->player->powers[pw_carry] = CR_GENERIC;
thing->player->pflags &= ~PF_JUMPED; thing->player->pflags &= ~PF_JUMPED;
P_SetTarget(&thing->tracer, tmthing); P_SetTarget(&thing->tracer, tmthing);
P_SetTarget(&tmthing->target, thing); // Set owner to the player P_SetTarget(&tmthing->target, thing); // Set owner to the player
@ -685,7 +725,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
return true; return true;
} }
else if (tmthing->type == MT_BLACKEGGMAN_MISSILE && thing->player && ((thing->player->pflags & PF_ITEMHANG) || (thing->player->pflags & PF_JUMPED))) else if (tmthing->type == MT_BLACKEGGMAN_MISSILE && thing->player && ((thing->player->powers[pw_carry] == CR_GENERIC) || (thing->player->pflags & PF_JUMPED)))
{ {
// Ignore // Ignore
} }
@ -886,7 +926,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
else if (thing->player) { else if (thing->player) {
if (thing->player-players == consoleplayer && botingame) if (thing->player-players == consoleplayer && botingame)
CV_SetValue(&cv_analog2, true); CV_SetValue(&cv_analog2, true);
thing->player->pflags &= ~PF_CARRIED; if (thing->player->powers[pw_carry] == CR_PLAYER)
thing->player->powers[pw_carry] = CR_NONE;
} }
if (thing->player) if (thing->player)
@ -938,7 +979,13 @@ static boolean PIT_CheckThing(mobj_t *thing)
&& thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) >= tmthing->z) && thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) >= tmthing->z)
{ {
if (thing->flags & MF_MONITOR if (thing->flags & MF_MONITOR
&& tmthing->player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)) && (tmthing->player->pflags & (PF_SPINNING|PF_GLIDING)
|| ((tmthing->player->pflags & PF_JUMPED)
&& !(tmthing->player->charflags & SF_NOJUMPDAMAGE
&& !(tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY)))
|| (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2)
|| ((tmthing->player->charflags & SF_STOMPDAMAGE)
&& (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0))))
{ {
SINT8 flipval = P_MobjFlip(thing); // Save this value in case monitor gets removed. SINT8 flipval = P_MobjFlip(thing); // Save this value in case monitor gets removed.
fixed_t *momz = &tmthing->momz; // tmthing gets changed by P_DamageMobj, so we need a new pointer?! X_x;; fixed_t *momz = &tmthing->momz; // tmthing gets changed by P_DamageMobj, so we need a new pointer?! X_x;;
@ -962,7 +1009,14 @@ static boolean PIT_CheckThing(mobj_t *thing)
} }
// Monitors are not treated as solid to players who are jumping, spinning or gliding, // Monitors are not treated as solid to players who are jumping, spinning or gliding,
// unless it's a CTF team monitor and you're on the wrong team // unless it's a CTF team monitor and you're on the wrong team
else 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_SPINNING|PF_GLIDING)
|| ((tmthing->player->pflags & PF_JUMPED)
&& !(tmthing->player->charflags & SF_NOJUMPDAMAGE
&& !(tmthing->player->charability == CA_TWINSPIN && tmthing->player->panim == PA_ABILITY)))
|| (tmthing->player->charability2 == CA2_MELEE && tmthing->player->panim == PA_ABILITY2)
|| ((tmthing->player->charflags & SF_STOMPDAMAGE)
&& (P_MobjFlip(tmthing)*(tmthing->z - (thing->z + thing->height/2)) > 0) && (P_MobjFlip(tmthing)*tmthing->momz < 0)))
&& !((thing->type == MT_REDRINGBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_BLUERINGBOX && tmthing->player->ctfteam != 2))) && !((thing->type == MT_REDRINGBOX && tmthing->player->ctfteam != 1) || (thing->type == MT_BLUERINGBOX && tmthing->player->ctfteam != 2)))
; ;
// z checking at last // z checking at last
@ -1157,7 +1211,7 @@ static boolean PIT_CheckLine(line_t *ld)
} }
// set openrange, opentop, openbottom // set openrange, opentop, openbottom
P_LineOpening(ld); P_LineOpening(ld, tmthing);
// adjust floor / ceiling heights // adjust floor / ceiling heights
if (opentop < tmceilingz) if (opentop < tmceilingz)
@ -1275,7 +1329,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
topheight = P_GetFOFTopZ(thing, newsubsec->sector, rover, x, y, NULL); topheight = P_GetFOFTopZ(thing, newsubsec->sector, rover, x, y, NULL);
bottomheight = P_GetFOFBottomZ(thing, newsubsec->sector, rover, x, y, NULL); bottomheight = P_GetFOFBottomZ(thing, newsubsec->sector, rover, x, y, NULL);
if (rover->flags & FF_GOOWATER && !(thing->flags & MF_NOGRAVITY)) if ((rover->flags & (FF_SWIMMABLE|FF_GOOWATER)) == (FF_SWIMMABLE|FF_GOOWATER) && !(thing->flags & MF_NOGRAVITY))
{ {
// If you're inside goowater and slowing down // If you're inside goowater and slowing down
fixed_t sinklevel = FixedMul(thing->info->height/6, thing->scale); fixed_t sinklevel = FixedMul(thing->info->height/6, thing->scale);
@ -1974,8 +2028,12 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff)
} }
// Ramp test // Ramp test
if (thing->player && maxstep > 0 if (maxstep > 0 && !(
&& !(P_PlayerTouchingSectorSpecial(thing->player, 1, 14) || GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 14)) thing->player && (
P_PlayerTouchingSectorSpecial(thing->player, 1, 14)
|| GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 14)
)
)
{ {
// If the floor difference is MAXSTEPMOVE or less, and the sector isn't Section1:14, ALWAYS // If the floor difference is MAXSTEPMOVE or less, and the sector isn't Section1:14, ALWAYS
// step down! Formerly required a Section1:13 sector for the full MAXSTEPMOVE, but no more. // step down! Formerly required a Section1:13 sector for the full MAXSTEPMOVE, but no more.
@ -2435,6 +2493,8 @@ isblocking:
// //
// P_IsClimbingValid // P_IsClimbingValid
// //
// Unlike P_DoClimbing, don't use when up against a one-sided linedef.
//
static boolean P_IsClimbingValid(player_t *player, angle_t angle) static boolean P_IsClimbingValid(player_t *player, angle_t angle)
{ {
fixed_t platx, platy; fixed_t platx, platy;
@ -2583,7 +2643,7 @@ static boolean PTR_SlideTraverse(intercept_t *in)
} }
// set openrange, opentop, openbottom // set openrange, opentop, openbottom
P_LineOpening(li); P_LineOpening(li, slidemo);
if (openrange < slidemo->height) if (openrange < slidemo->height)
goto isblocking; // doesn't fit goto isblocking; // doesn't fit
@ -2659,6 +2719,7 @@ isblocking:
// see about climbing on the wall // see about climbing on the wall
if (!(checkline->flags & ML_NOCLIMB)) if (!(checkline->flags & ML_NOCLIMB))
{ {
boolean canclimb;
angle_t climbangle, climbline; angle_t climbangle, climbline;
INT32 whichside = P_PointOnLineSide(slidemo->x, slidemo->y, li); INT32 whichside = P_PointOnLineSide(slidemo->x, slidemo->y, li);
@ -2669,9 +2730,11 @@ isblocking:
climbangle += (ANGLE_90 * (whichside ? -1 : 1)); climbangle += (ANGLE_90 * (whichside ? -1 : 1));
canclimb = (li->backsector ? P_IsClimbingValid(slidemo->player, climbangle) : true);
if (((!slidemo->player->climbing && abs((signed)(slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45) if (((!slidemo->player->climbing && abs((signed)(slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45)
|| (slidemo->player->climbing == 1 && abs((signed)(slidemo->angle - climbline)) < ANGLE_135)) || (slidemo->player->climbing == 1 && abs((signed)(slidemo->angle - climbline)) < ANGLE_135))
&& P_IsClimbingValid(slidemo->player, climbangle)) && canclimb)
{ {
slidemo->angle = climbangle; slidemo->angle = climbangle;
if (!demoplayback || P_AnalogMove(slidemo->player)) if (!demoplayback || P_AnalogMove(slidemo->player))
@ -3370,7 +3433,7 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
for (i = 0; i < sector->numattached; i++) for (i = 0; i < sector->numattached; i++)
{ {
sec = &sectors[sector->attached[i]]; sec = &sectors[sector->attached[i]];
for (n = sec->touching_thinglist; n; n = n->m_snext) for (n = sec->touching_thinglist; n; n = n->m_thinglist_next)
n->visited = false; n->visited = false;
sec->moved = true; sec->moved = true;
@ -3382,7 +3445,7 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
do do
{ {
for (n = sec->touching_thinglist; n; n = n->m_snext) for (n = sec->touching_thinglist; n; n = n->m_thinglist_next)
if (!n->visited) if (!n->visited)
{ {
n->visited = true; n->visited = true;
@ -3403,12 +3466,12 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
// Mark all things invalid // Mark all things invalid
sector->moved = true; sector->moved = true;
for (n = sector->touching_thinglist; n; n = n->m_snext) for (n = sector->touching_thinglist; n; n = n->m_thinglist_next)
n->visited = false; n->visited = false;
do do
{ {
for (n = sector->touching_thinglist; n; n = n->m_snext) // go through list for (n = sector->touching_thinglist; n; n = n->m_thinglist_next) // go through list
if (!n->visited) // unprocessed thing found if (!n->visited) // unprocessed thing found
{ {
n->visited = true; // mark thing as processed n->visited = true; // mark thing as processed
@ -3432,7 +3495,7 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
for (i = 0; i < sector->numattached; i++) for (i = 0; i < sector->numattached; i++)
{ {
sec = &sectors[sector->attached[i]]; sec = &sectors[sector->attached[i]];
for (n = sec->touching_thinglist; n; n = n->m_snext) for (n = sec->touching_thinglist; n; n = n->m_thinglist_next)
n->visited = false; n->visited = false;
sec->moved = true; sec->moved = true;
@ -3444,7 +3507,7 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
do do
{ {
for (n = sec->touching_thinglist; n; n = n->m_snext) for (n = sec->touching_thinglist; n; n = n->m_thinglist_next)
if (!n->visited) if (!n->visited)
{ {
n->visited = true; n->visited = true;
@ -3462,12 +3525,12 @@ boolean P_CheckSector(sector_t *sector, boolean crunch)
// Mark all things invalid // Mark all things invalid
sector->moved = true; sector->moved = true;
for (n = sector->touching_thinglist; n; n = n->m_snext) for (n = sector->touching_thinglist; n; n = n->m_thinglist_next)
n->visited = false; n->visited = false;
do do
{ {
for (n = sector->touching_thinglist; n; n = n->m_snext) // go through list for (n = sector->touching_thinglist; n; n = n->m_thinglist_next) // go through list
if (!n->visited) // unprocessed thing found if (!n->visited) // unprocessed thing found
{ {
n->visited = true; // mark thing as processed n->visited = true; // mark thing as processed
@ -3507,7 +3570,7 @@ static msecnode_t *P_GetSecnode(void)
if (headsecnode) if (headsecnode)
{ {
node = headsecnode; node = headsecnode;
headsecnode = headsecnode->m_snext; headsecnode = headsecnode->m_thinglist_next;
} }
else else
node = Z_Calloc(sizeof (*node), PU_LEVEL, NULL); node = Z_Calloc(sizeof (*node), PU_LEVEL, NULL);
@ -3521,7 +3584,7 @@ static mprecipsecnode_t *P_GetPrecipSecnode(void)
if (headprecipsecnode) if (headprecipsecnode)
{ {
node = headprecipsecnode; node = headprecipsecnode;
headprecipsecnode = headprecipsecnode->m_snext; headprecipsecnode = headprecipsecnode->m_thinglist_next;
} }
else else
node = Z_Calloc(sizeof (*node), PU_LEVEL, NULL); node = Z_Calloc(sizeof (*node), PU_LEVEL, NULL);
@ -3532,14 +3595,14 @@ static mprecipsecnode_t *P_GetPrecipSecnode(void)
static inline void P_PutSecnode(msecnode_t *node) static inline void P_PutSecnode(msecnode_t *node)
{ {
node->m_snext = headsecnode; node->m_thinglist_next = headsecnode;
headsecnode = node; headsecnode = node;
} }
// Tails 08-25-2002 // Tails 08-25-2002
static inline void P_PutPrecipSecnode(mprecipsecnode_t *node) static inline void P_PutPrecipSecnode(mprecipsecnode_t *node)
{ {
node->m_snext = headprecipsecnode; node->m_thinglist_next = headprecipsecnode;
headprecipsecnode = node; headprecipsecnode = node;
} }
@ -3560,7 +3623,7 @@ static msecnode_t *P_AddSecnode(sector_t *s, mobj_t *thing, msecnode_t *nextnode
node->m_thing = thing; // Yes. Setting m_thing says 'keep it'. node->m_thing = thing; // Yes. Setting m_thing says 'keep it'.
return nextnode; return nextnode;
} }
node = node->m_tnext; node = node->m_sectorlist_next;
} }
// Couldn't find an existing node for this sector. Add one at the head // Couldn't find an existing node for this sector. Add one at the head
@ -3573,17 +3636,17 @@ static msecnode_t *P_AddSecnode(sector_t *s, mobj_t *thing, msecnode_t *nextnode
node->m_sector = s; // sector node->m_sector = s; // sector
node->m_thing = thing; // mobj node->m_thing = thing; // mobj
node->m_tprev = NULL; // prev node on Thing thread node->m_sectorlist_prev = NULL; // prev node on Thing thread
node->m_tnext = nextnode; // next node on Thing thread node->m_sectorlist_next = nextnode; // next node on Thing thread
if (nextnode) if (nextnode)
nextnode->m_tprev = node; // set back link on Thing nextnode->m_sectorlist_prev = node; // set back link on Thing
// Add new node at head of sector thread starting at s->touching_thinglist // Add new node at head of sector thread starting at s->touching_thinglist
node->m_sprev = NULL; // prev node on sector thread node->m_thinglist_prev = NULL; // prev node on sector thread
node->m_snext = s->touching_thinglist; // next node on sector thread node->m_thinglist_next = s->touching_thinglist; // next node on sector thread
if (s->touching_thinglist) if (s->touching_thinglist)
node->m_snext->m_sprev = node; node->m_thinglist_next->m_thinglist_prev = node;
s->touching_thinglist = node; s->touching_thinglist = node;
return node; return node;
} }
@ -3601,7 +3664,7 @@ static mprecipsecnode_t *P_AddPrecipSecnode(sector_t *s, precipmobj_t *thing, mp
node->m_thing = thing; // Yes. Setting m_thing says 'keep it'. node->m_thing = thing; // Yes. Setting m_thing says 'keep it'.
return nextnode; return nextnode;
} }
node = node->m_tnext; node = node->m_sectorlist_next;
} }
// Couldn't find an existing node for this sector. Add one at the head // Couldn't find an existing node for this sector. Add one at the head
@ -3614,17 +3677,17 @@ static mprecipsecnode_t *P_AddPrecipSecnode(sector_t *s, precipmobj_t *thing, mp
node->m_sector = s; // sector node->m_sector = s; // sector
node->m_thing = thing; // mobj node->m_thing = thing; // mobj
node->m_tprev = NULL; // prev node on Thing thread node->m_sectorlist_prev = NULL; // prev node on Thing thread
node->m_tnext = nextnode; // next node on Thing thread node->m_sectorlist_next = nextnode; // next node on Thing thread
if (nextnode) if (nextnode)
nextnode->m_tprev = node; // set back link on Thing nextnode->m_sectorlist_prev = node; // set back link on Thing
// Add new node at head of sector thread starting at s->touching_thinglist // Add new node at head of sector thread starting at s->touching_thinglist
node->m_sprev = NULL; // prev node on sector thread node->m_thinglist_prev = NULL; // prev node on sector thread
node->m_snext = s->touching_preciplist; // next node on sector thread node->m_thinglist_next = s->touching_preciplist; // next node on sector thread
if (s->touching_preciplist) if (s->touching_preciplist)
node->m_snext->m_sprev = node; node->m_thinglist_next->m_thinglist_prev = node;
s->touching_preciplist = node; s->touching_preciplist = node;
return node; return node;
} }
@ -3646,24 +3709,24 @@ static msecnode_t *P_DelSecnode(msecnode_t *node)
// Unlink from the Thing thread. The Thing thread begins at // Unlink from the Thing thread. The Thing thread begins at
// sector_list and not from mobj_t->touching_sectorlist. // sector_list and not from mobj_t->touching_sectorlist.
tp = node->m_tprev; tp = node->m_sectorlist_prev;
tn = node->m_tnext; tn = node->m_sectorlist_next;
if (tp) if (tp)
tp->m_tnext = tn; tp->m_sectorlist_next = tn;
if (tn) if (tn)
tn->m_tprev = tp; tn->m_sectorlist_prev = tp;
// Unlink from the sector thread. This thread begins at // Unlink from the sector thread. This thread begins at
// sector_t->touching_thinglist. // sector_t->touching_thinglist.
sp = node->m_sprev; sp = node->m_thinglist_prev;
sn = node->m_snext; sn = node->m_thinglist_next;
if (sp) if (sp)
sp->m_snext = sn; sp->m_thinglist_next = sn;
else else
node->m_sector->touching_thinglist = sn; node->m_sector->touching_thinglist = sn;
if (sn) if (sn)
sn->m_sprev = sp; sn->m_thinglist_prev = sp;
// Return this node to the freelist // Return this node to the freelist
@ -3685,24 +3748,24 @@ static mprecipsecnode_t *P_DelPrecipSecnode(mprecipsecnode_t *node)
// Unlink from the Thing thread. The Thing thread begins at // Unlink from the Thing thread. The Thing thread begins at
// sector_list and not from mobj_t->touching_sectorlist. // sector_list and not from mobj_t->touching_sectorlist.
tp = node->m_tprev; tp = node->m_sectorlist_prev;
tn = node->m_tnext; tn = node->m_sectorlist_next;
if (tp) if (tp)
tp->m_tnext = tn; tp->m_sectorlist_next = tn;
if (tn) if (tn)
tn->m_tprev = tp; tn->m_sectorlist_prev = tp;
// Unlink from the sector thread. This thread begins at // Unlink from the sector thread. This thread begins at
// sector_t->touching_thinglist. // sector_t->touching_thinglist.
sp = node->m_sprev; sp = node->m_thinglist_prev;
sn = node->m_snext; sn = node->m_thinglist_next;
if (sp) if (sp)
sp->m_snext = sn; sp->m_thinglist_next = sn;
else else
node->m_sector->touching_preciplist = sn; node->m_sector->touching_preciplist = sn;
if (sn) if (sn)
sn->m_sprev = sp; sn->m_thinglist_prev = sp;
// Return this node to the freelist // Return this node to the freelist
@ -3817,7 +3880,7 @@ void P_CreateSecNodeList(mobj_t *thing, fixed_t x, fixed_t y)
while (node) while (node)
{ {
node->m_thing = NULL; node->m_thing = NULL;
node = node->m_tnext; node = node->m_sectorlist_next;
} }
P_SetTarget(&tmthing, thing); P_SetTarget(&tmthing, thing);
@ -3855,11 +3918,11 @@ void P_CreateSecNodeList(mobj_t *thing, fixed_t x, fixed_t y)
if (!node->m_thing) if (!node->m_thing)
{ {
if (node == sector_list) if (node == sector_list)
sector_list = node->m_tnext; sector_list = node->m_sectorlist_next;
node = P_DelSecnode(node); node = P_DelSecnode(node);
} }
else else
node = node->m_tnext; node = node->m_sectorlist_next;
} }
/* cph - /* cph -
@ -3900,7 +3963,7 @@ void P_CreatePrecipSecNodeList(precipmobj_t *thing,fixed_t x,fixed_t y)
while (node) while (node)
{ {
node->m_thing = NULL; node->m_thing = NULL;
node = node->m_tnext; node = node->m_sectorlist_next;
} }
tmprecipthing = thing; tmprecipthing = thing;
@ -3934,11 +3997,11 @@ void P_CreatePrecipSecNodeList(precipmobj_t *thing,fixed_t x,fixed_t y)
if (!node->m_thing) if (!node->m_thing)
{ {
if (node == precipsector_list) if (node == precipsector_list)
precipsector_list = node->m_tnext; precipsector_list = node->m_sectorlist_next;
node = P_DelPrecipSecnode(node); node = P_DelPrecipSecnode(node);
} }
else else
node = node->m_tnext; node = node->m_sectorlist_next;
} }
/* cph - /* cph -

View File

@ -489,7 +489,7 @@ void P_CameraLineOpening(line_t *linedef)
} }
} }
void P_LineOpening(line_t *linedef) void P_LineOpening(line_t *linedef, mobj_t *mobj)
{ {
sector_t *front, *back; sector_t *front, *back;
@ -520,8 +520,8 @@ void P_LineOpening(line_t *linedef)
{ // Set open and high/low values here { // Set open and high/low values here
fixed_t frontheight, backheight; fixed_t frontheight, backheight;
frontheight = P_GetCeilingZ(tmthing, front, tmx, tmy, linedef); frontheight = P_GetCeilingZ(mobj, front, tmx, tmy, linedef);
backheight = P_GetCeilingZ(tmthing, back, tmx, tmy, linedef); backheight = P_GetCeilingZ(mobj, back, tmx, tmy, linedef);
if (frontheight < backheight) if (frontheight < backheight)
{ {
@ -540,8 +540,8 @@ void P_LineOpening(line_t *linedef)
#endif #endif
} }
frontheight = P_GetFloorZ(tmthing, front, tmx, tmy, linedef); frontheight = P_GetFloorZ(mobj, front, tmx, tmy, linedef);
backheight = P_GetFloorZ(tmthing, back, tmx, tmy, linedef); backheight = P_GetFloorZ(mobj, back, tmx, tmy, linedef);
if (frontheight > backheight) if (frontheight > backheight)
{ {
@ -561,12 +561,14 @@ void P_LineOpening(line_t *linedef)
} }
} }
if (tmthing) if (mobj)
{ {
fixed_t thingtop = tmthing->z + tmthing->height; fixed_t thingtop = mobj->z + mobj->height;
// Check for collision with front side's midtexture if Effect 4 is set // Check for collision with front side's midtexture if Effect 4 is set
if (linedef->flags & ML_EFFECT4) { if (linedef->flags & ML_EFFECT4
&& !linedef->polyobj // don't do anything for polyobjects! ...for now
) {
side_t *side = &sides[linedef->sidenum[0]]; side_t *side = &sides[linedef->sidenum[0]];
fixed_t textop, texbottom, texheight; fixed_t textop, texbottom, texheight;
fixed_t texmid, delta1, delta2; fixed_t texmid, delta1, delta2;
@ -575,30 +577,38 @@ void P_LineOpening(line_t *linedef)
texheight = textures[texturetranslation[side->midtexture]]->height << FRACBITS; texheight = textures[texturetranslation[side->midtexture]]->height << FRACBITS;
// Set texbottom and textop to the Z coordinates of the texture's boundaries // Set texbottom and textop to the Z coordinates of the texture's boundaries
#ifdef POLYOBJECTS #if 0 // #ifdef POLYOBJECTS
// don't remove this code unless solid midtextures
// on non-solid polyobjects should NEVER happen in the future
if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) { if (linedef->polyobj && (linedef->polyobj->flags & POF_TESTHEIGHT)) {
if (linedef->flags & ML_DONTPEGBOTTOM) { if (linedef->flags & ML_EFFECT5 && !side->repeatcnt) { // "infinite" repeat
texbottom = back->floorheight + side->rowoffset;
textop = back->ceilingheight + side->rowoffset;
} else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) {
texbottom = back->floorheight + side->rowoffset; texbottom = back->floorheight + side->rowoffset;
textop = texbottom + texheight*(side->repeatcnt+1); textop = texbottom + texheight*(side->repeatcnt+1);
} else { } else {
textop = back->ceilingheight - side->rowoffset; textop = back->ceilingheight + side->rowoffset;
texbottom = textop - texheight*(side->repeatcnt+1); texbottom = textop - texheight*(side->repeatcnt+1);
} }
} else } else
#endif #endif
{ {
if (linedef->flags & ML_DONTPEGBOTTOM) { if (linedef->flags & ML_EFFECT5 && !side->repeatcnt) { // "infinite" repeat
texbottom = openbottom + side->rowoffset;
textop = opentop + side->rowoffset;
} else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) {
texbottom = openbottom + side->rowoffset; texbottom = openbottom + side->rowoffset;
textop = texbottom + texheight*(side->repeatcnt+1); textop = texbottom + texheight*(side->repeatcnt+1);
} else { } else {
textop = opentop - side->rowoffset; textop = opentop + side->rowoffset;
texbottom = textop - texheight*(side->repeatcnt+1); texbottom = textop - texheight*(side->repeatcnt+1);
} }
} }
texmid = texbottom+(textop-texbottom)/2; texmid = texbottom+(textop-texbottom)/2;
delta1 = abs(tmthing->z - texmid); delta1 = abs(mobj->z - texmid);
delta2 = abs(thingtop - texmid); delta2 = abs(thingtop - texmid);
if (delta1 > delta2) { // Below if (delta1 > delta2) { // Below
@ -636,16 +646,16 @@ void P_LineOpening(line_t *linedef)
if (!(rover->flags & FF_EXISTS)) if (!(rover->flags & FF_EXISTS))
continue; continue;
if (tmthing->player && (P_CheckSolidLava(tmthing, rover) || P_CanRunOnWater(tmthing->player, rover))) if (mobj->player && (P_CheckSolidLava(mobj, rover) || P_CanRunOnWater(mobj->player, rover)))
; ;
else if (!((rover->flags & FF_BLOCKPLAYER && tmthing->player) else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|| (rover->flags & FF_BLOCKOTHERS && !tmthing->player))) || (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
continue; continue;
topheight = P_GetFOFTopZ(tmthing, front, rover, tmx, tmy, linedef); topheight = P_GetFOFTopZ(mobj, front, rover, tmx, tmy, linedef);
bottomheight = P_GetFOFBottomZ(tmthing, front, rover, tmx, tmy, linedef); bottomheight = P_GetFOFBottomZ(mobj, front, rover, tmx, tmy, linedef);
delta1 = abs(tmthing->z - (bottomheight + ((topheight - bottomheight)/2))); delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
@ -680,16 +690,16 @@ void P_LineOpening(line_t *linedef)
if (!(rover->flags & FF_EXISTS)) if (!(rover->flags & FF_EXISTS))
continue; continue;
if (tmthing->player && (P_CheckSolidLava(tmthing, rover) || P_CanRunOnWater(tmthing->player, rover))) if (mobj->player && (P_CheckSolidLava(mobj, rover) || P_CanRunOnWater(mobj->player, rover)))
; ;
else if (!((rover->flags & FF_BLOCKPLAYER && tmthing->player) else if (!((rover->flags & FF_BLOCKPLAYER && mobj->player)
|| (rover->flags & FF_BLOCKOTHERS && !tmthing->player))) || (rover->flags & FF_BLOCKOTHERS && !mobj->player)))
continue; continue;
topheight = P_GetFOFTopZ(tmthing, back, rover, tmx, tmy, linedef); topheight = P_GetFOFTopZ(mobj, back, rover, tmx, tmy, linedef);
bottomheight = P_GetFOFBottomZ(tmthing, back, rover, tmx, tmy, linedef); bottomheight = P_GetFOFBottomZ(mobj, back, rover, tmx, tmy, linedef);
delta1 = abs(tmthing->z - (bottomheight + ((topheight - bottomheight)/2))); delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2)));
delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2)));
if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF if (delta1 >= delta2 && !(rover->flags & FF_PLATFORM)) // thing is below FOF
@ -723,7 +733,7 @@ void P_LineOpening(line_t *linedef)
{ {
const sector_t *polysec = linedef->backsector; const sector_t *polysec = linedef->backsector;
delta1 = abs(tmthing->z - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2))); delta1 = abs(mobj->z - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
delta2 = abs(thingtop - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2))); delta2 = abs(thingtop - (polysec->floorheight + ((polysec->ceilingheight - polysec->floorheight)/2)));
if (polysec->floorheight < lowestceiling && delta1 >= delta2) { if (polysec->floorheight < lowestceiling && delta1 >= delta2) {
lowestceiling = polysec->floorheight; lowestceiling = polysec->floorheight;

View File

@ -59,7 +59,7 @@ extern fixed_t opentop, openbottom, openrange, lowfloor, highceiling;
extern pslope_t *opentopslope, *openbottomslope; extern pslope_t *opentopslope, *openbottomslope;
#endif #endif
void P_LineOpening(line_t *plinedef); void P_LineOpening(line_t *plinedef, mobj_t *mobj);
boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean(*func)(line_t *)); boolean P_BlockLinesIterator(INT32 x, INT32 y, boolean(*func)(line_t *));
boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean(*func)(mobj_t *)); boolean P_BlockThingsIterator(INT32 x, INT32 y, boolean(*func)(mobj_t *));

File diff suppressed because it is too large Load Diff

View File

@ -442,7 +442,7 @@ boolean P_SupermanLook4Players(mobj_t *actor);
void P_DestroyRobots(void); void P_DestroyRobots(void);
void P_SnowThinker(precipmobj_t *mobj); void P_SnowThinker(precipmobj_t *mobj);
void P_RainThinker(precipmobj_t *mobj); void P_RainThinker(precipmobj_t *mobj);
void P_NullPrecipThinker(precipmobj_t *mobj); FUNCMATH void P_NullPrecipThinker(precipmobj_t *mobj);
void P_RemovePrecipMobj(precipmobj_t *mobj); void P_RemovePrecipMobj(precipmobj_t *mobj);
void P_SetScale(mobj_t *mobj, fixed_t newscale); void P_SetScale(mobj_t *mobj, fixed_t newscale);
void P_XYMovement(mobj_t *mo); void P_XYMovement(mobj_t *mo);

View File

@ -35,8 +35,12 @@
#pragma interface #pragma interface
#endif #endif
/// \brief Frame flags: only the frame number /// \brief Frame flags: only the frame number - 0 to 511 (Frames from 0 to 63, Sprite2 number uses full range)
#define FF_FRAMEMASK 0x3fff #define FF_FRAMEMASK 0x1ff
/// \brief Frame flags: A change of state at the end of Sprite2 animation
#define FF_SPR2ENDSTATE 0x1000
/// \brief Frame flags: 50% of starting in middle of animation (Sprite2 and FF_ANIMATE)
#define FF_MIDDLESTARTCHANCE 0x2000
/// \brief Frame flags: Simple stateless animation /// \brief Frame flags: Simple stateless animation
#define FF_ANIMATE 0x4000 #define FF_ANIMATE 0x4000
/// \brief Frame flags: frame always appears full bright /// \brief Frame flags: frame always appears full bright

View File

@ -147,7 +147,6 @@ static void P_NetArchivePlayers(void)
WRITEUINT32(save_p, players[i].score); WRITEUINT32(save_p, players[i].score);
WRITEFIXED(save_p, players[i].dashspeed); WRITEFIXED(save_p, players[i].dashspeed);
WRITEINT32(save_p, players[i].dashtime);
WRITESINT8(save_p, players[i].lives); WRITESINT8(save_p, players[i].lives);
WRITESINT8(save_p, players[i].continues); WRITESINT8(save_p, players[i].continues);
WRITESINT8(save_p, players[i].xtralife); WRITESINT8(save_p, players[i].xtralife);
@ -162,6 +161,7 @@ static void P_NetArchivePlayers(void)
WRITEINT32(save_p, players[i].deadtimer); WRITEINT32(save_p, players[i].deadtimer);
WRITEUINT32(save_p, players[i].exiting); WRITEUINT32(save_p, players[i].exiting);
WRITEUINT8(save_p, players[i].homing); WRITEUINT8(save_p, players[i].homing);
WRITEUINT32(save_p, players[i].dashmode);
WRITEUINT32(save_p, players[i].skidtime); WRITEUINT32(save_p, players[i].skidtime);
//////////////////////////// ////////////////////////////
@ -259,6 +259,9 @@ static void P_NetArchivePlayers(void)
if (flags & AWAYVIEW) if (flags & AWAYVIEW)
WRITEUINT32(save_p, players[i].awayviewmobj->mobjnum); WRITEUINT32(save_p, players[i].awayviewmobj->mobjnum);
WRITEFIXED(save_p, players[i].camerascale);
WRITEFIXED(save_p, players[i].shieldscale);
WRITEUINT8(save_p, players[i].charability); WRITEUINT8(save_p, players[i].charability);
WRITEUINT8(save_p, players[i].charability2); WRITEUINT8(save_p, players[i].charability2);
WRITEUINT32(save_p, players[i].charflags); WRITEUINT32(save_p, players[i].charflags);
@ -274,6 +277,8 @@ static void P_NetArchivePlayers(void)
WRITEUINT8(save_p, players[i].accelstart); WRITEUINT8(save_p, players[i].accelstart);
WRITEUINT8(save_p, players[i].acceleration); WRITEUINT8(save_p, players[i].acceleration);
WRITEFIXED(save_p, players[i].jumpfactor); WRITEFIXED(save_p, players[i].jumpfactor);
WRITEFIXED(save_p, players[i].height);
WRITEFIXED(save_p, players[i].spinheight);
} }
} }
@ -322,7 +327,6 @@ static void P_NetUnArchivePlayers(void)
players[i].score = READUINT32(save_p); players[i].score = READUINT32(save_p);
players[i].dashspeed = READFIXED(save_p); // dashing speed players[i].dashspeed = READFIXED(save_p); // dashing speed
players[i].dashtime = READINT32(save_p); // dashing speed
players[i].lives = READSINT8(save_p); players[i].lives = READSINT8(save_p);
players[i].continues = READSINT8(save_p); // continues that player has acquired players[i].continues = READSINT8(save_p); // continues that player has acquired
players[i].xtralife = READSINT8(save_p); // Ring Extra Life counter players[i].xtralife = READSINT8(save_p); // Ring Extra Life counter
@ -337,6 +341,7 @@ static void P_NetUnArchivePlayers(void)
players[i].deadtimer = READINT32(save_p); // End game if game over lasts too long players[i].deadtimer = READINT32(save_p); // End game if game over lasts too long
players[i].exiting = READUINT32(save_p); // Exitlevel timer players[i].exiting = READUINT32(save_p); // Exitlevel timer
players[i].homing = READUINT8(save_p); // Are you homing? players[i].homing = READUINT8(save_p); // Are you homing?
players[i].dashmode = READUINT32(save_p); // counter for dashmode ability
players[i].skidtime = READUINT32(save_p); // Skid timer players[i].skidtime = READUINT32(save_p); // Skid timer
//////////////////////////// ////////////////////////////
@ -424,6 +429,9 @@ static void P_NetUnArchivePlayers(void)
players[i].viewheight = cv_viewheight.value<<FRACBITS; players[i].viewheight = cv_viewheight.value<<FRACBITS;
players[i].camerascale = READFIXED(save_p);
players[i].shieldscale = READFIXED(save_p);
//SetPlayerSkinByNum(i, players[i].skin); //SetPlayerSkinByNum(i, players[i].skin);
players[i].charability = READUINT8(save_p); players[i].charability = READUINT8(save_p);
players[i].charability2 = READUINT8(save_p); players[i].charability2 = READUINT8(save_p);
@ -440,6 +448,8 @@ static void P_NetUnArchivePlayers(void)
players[i].accelstart = READUINT8(save_p); players[i].accelstart = READUINT8(save_p);
players[i].acceleration = READUINT8(save_p); players[i].acceleration = READUINT8(save_p);
players[i].jumpfactor = READFIXED(save_p); players[i].jumpfactor = READFIXED(save_p);
players[i].height = READFIXED(save_p);
players[i].spinheight = READFIXED(save_p);
} }
} }

View File

@ -1931,10 +1931,18 @@ static void P_GroupLines(void)
// allocate linebuffers for each sector // allocate linebuffers for each sector
for (i = 0, sector = sectors; i < numsectors; i++, sector++) for (i = 0, sector = sectors; i < numsectors; i++, sector++)
{ {
sector->lines = Z_Calloc(sector->linecount * sizeof(line_t*), PU_LEVEL, NULL); if (sector->linecount == 0) // no lines found?
{
sector->lines = NULL;
CONS_Debug(DBG_SETUP, "P_GroupLines: sector %s has no lines\n", sizeu1(i));
}
else
{
sector->lines = Z_Calloc(sector->linecount * sizeof(line_t*), PU_LEVEL, NULL);
// zero the count, since we'll later use this to track how many we've recorded // zero the count, since we'll later use this to track how many we've recorded
sector->linecount = 0; sector->linecount = 0;
}
} }
// iterate through lines, assigning them to sectors' linebuffers, // iterate through lines, assigning them to sectors' linebuffers,
@ -1952,11 +1960,14 @@ static void P_GroupLines(void)
{ {
M_ClearBox(bbox); M_ClearBox(bbox);
for (j = 0; j < sector->linecount; j++) if (sector->linecount != 0)
{ {
li = sector->lines[j]; for (j = 0; j < sector->linecount; j++)
M_AddToBox(bbox, li->v1->x, li->v1->y); {
M_AddToBox(bbox, li->v2->x, li->v2->y); li = sector->lines[j];
M_AddToBox(bbox, li->v1->x, li->v1->y);
M_AddToBox(bbox, li->v2->x, li->v2->y);
}
} }
// set the degenmobj_t to the middle of the bounding box // set the degenmobj_t to the middle of the bounding box
@ -1966,6 +1977,35 @@ static void P_GroupLines(void)
} }
} }
//
// P_LoadReject
//
// Detect if the REJECT lump is valid,
// if not, rejectmatrix will be NULL
static void P_LoadReject(lumpnum_t lumpnum)
{
size_t count;
const char *lumpname = W_CheckNameForNum(lumpnum);
// Check if the lump exists, and if it's named "REJECT"
if (!lumpname || memcmp(lumpname, "REJECT\0\0", 8) != 0)
{
rejectmatrix = NULL;
CONS_Debug(DBG_SETUP, "P_LoadReject: No valid REJECT lump found\n");
return;
}
count = W_LumpLength(lumpnum);
if (!count) // zero length, someone probably used ZDBSP
{
rejectmatrix = NULL;
CONS_Debug(DBG_SETUP, "P_LoadReject: REJECT lump has size 0, will not be loaded\n");
}
else
rejectmatrix = W_CacheLumpNum(lumpnum, PU_LEVEL);
}
#if 0 #if 0
static char *levellumps[] = static char *levellumps[] =
{ {
@ -2574,7 +2614,7 @@ boolean P_SetupLevel(boolean skipprecip)
P_LoadSubsectors(lastloadedmaplumpnum + ML_SSECTORS); P_LoadSubsectors(lastloadedmaplumpnum + ML_SSECTORS);
P_LoadNodes(lastloadedmaplumpnum + ML_NODES); P_LoadNodes(lastloadedmaplumpnum + ML_NODES);
P_LoadSegs(lastloadedmaplumpnum + ML_SEGS); P_LoadSegs(lastloadedmaplumpnum + ML_SEGS);
rejectmatrix = W_CacheLumpNum(lastloadedmaplumpnum + ML_REJECT, PU_LEVEL); P_LoadReject(lastloadedmaplumpnum + ML_REJECT);
P_GroupLines(); P_GroupLines();
numdmstarts = numredctfstarts = numbluectfstarts = 0; numdmstarts = numredctfstarts = numbluectfstarts = 0;

View File

@ -325,9 +325,12 @@ boolean P_CheckSight(mobj_t *t1, mobj_t *t2)
s2 = t2->subsector->sector; s2 = t2->subsector->sector;
pnum = (s1-sectors)*numsectors + (s2-sectors); pnum = (s1-sectors)*numsectors + (s2-sectors);
// Check in REJECT table. if (rejectmatrix != NULL)
if (rejectmatrix[pnum>>3] & (1 << (pnum&7))) // can't possibly be connected {
return false; // Check in REJECT table.
if (rejectmatrix[pnum>>3] & (1 << (pnum&7))) // can't possibly be connected
return false;
}
// killough 11/98: shortcut for melee situations // killough 11/98: shortcut for melee situations
// same subsector? obviously visible // same subsector? obviously visible

View File

@ -199,7 +199,6 @@ static fixed_t P_GetExtent(sector_t *sector, line_t *line)
// Find furthest vertex from the reference line. It, along with the two ends // Find furthest vertex from the reference line. It, along with the two ends
// of the line, will define the plane. // of the line, will define the plane.
// SRB2CBTODO: Use a formula to get the slope to slide objects depending on how steep
for(i = 0; i < sector->linecount; i++) for(i = 0; i < sector->linecount; i++)
{ {
line_t *li = sector->lines[i]; line_t *li = sector->lines[i];
@ -231,7 +230,6 @@ static fixed_t P_GetExtent(sector_t *sector, line_t *line)
// //
// Creates one or more slopes based on the given line type and front/back // Creates one or more slopes based on the given line type and front/back
// sectors. // sectors.
// Kalaron: Check if dynamic slopes need recalculation
// //
void P_SpawnSlope_Line(int linenum) void P_SpawnSlope_Line(int linenum)
{ {
@ -276,7 +274,6 @@ void P_SpawnSlope_Line(int linenum)
ny = -FixedDiv(line->dx, len); ny = -FixedDiv(line->dx, len);
} }
// SRB2CBTODO: Transform origin relative to the bounds of an individual FOF
origin.x = line->v1->x + (line->v2->x - line->v1->x)/2; origin.x = line->v1->x + (line->v2->x - line->v1->x)/2;
origin.y = line->v1->y + (line->v2->y - line->v1->y)/2; origin.y = line->v1->y + (line->v2->y - line->v1->y)/2;
@ -327,7 +324,7 @@ void P_SpawnSlope_Line(int linenum)
// fslope->normal is a 3D line perpendicular to the 3D vector // fslope->normal is a 3D line perpendicular to the 3D vector
// Sync the linedata of the line that started this slope // Sync the linedata of the line that started this slope
// SRB2CBTODO: Anything special for remote(control sector)-based slopes later? // TODO: Anything special for control sector based slopes later?
fslope->sourceline = line; fslope->sourceline = line;
// To find the real highz/lowz of a slope, you need to check all the vertexes // To find the real highz/lowz of a slope, you need to check all the vertexes
@ -379,7 +376,7 @@ void P_SpawnSlope_Line(int linenum)
cslope->refpos = 2; cslope->refpos = 2;
// Sync the linedata of the line that started this slope // Sync the linedata of the line that started this slope
// SRB2CBTODO: Anything special for remote(control sector)-based slopes later? // TODO: Anything special for control sector based slopes later?
cslope->sourceline = line; cslope->sourceline = line;
// Remember the way the slope is formed // Remember the way the slope is formed
@ -445,7 +442,7 @@ void P_SpawnSlope_Line(int linenum)
fslope->refpos = 3; fslope->refpos = 3;
// Sync the linedata of the line that started this slope // Sync the linedata of the line that started this slope
// SRB2CBTODO: Anything special for remote(control sector)-based slopes later? // TODO: Anything special for control sector based slopes later?
fslope->sourceline = line; fslope->sourceline = line;
// Remember the way the slope is formed // Remember the way the slope is formed
@ -488,7 +485,7 @@ void P_SpawnSlope_Line(int linenum)
cslope->refpos = 4; cslope->refpos = 4;
// Sync the linedata of the line that started this slope // Sync the linedata of the line that started this slope
// SRB2CBTODO: Anything special for remote(control sector)-based slopes later? // TODO: Anything special for control sector based slopes later?
cslope->sourceline = line; cslope->sourceline = line;
// Remember the way the slope is formed // Remember the way the slope is formed
@ -554,16 +551,11 @@ static pslope_t *P_NewVertexSlope(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flag
ret->vertices[2] = mt; ret->vertices[2] = mt;
} }
if (!ret->vertices[0])
CONS_Printf("PANIC 0\n");
if (!ret->vertices[1])
CONS_Printf("PANIC 1\n");
if (!ret->vertices[2])
CONS_Printf("PANIC 2\n");
// Now set heights for each vertex, because they haven't been set yet // Now set heights for each vertex, because they haven't been set yet
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
mt = ret->vertices[i]; mt = ret->vertices[i];
if (!mt) // If a vertex wasn't found, it's game over. There's nothing you can do to recover (except maybe try and kill the slope instead - TODO?)
I_Error("P_NewVertexSlope: Slope vertex %s (for linedef tag %d) not found!", sizeu1(i), tag1);
if (mt->extrainfo) if (mt->extrainfo)
mt->z = mt->options; mt->z = mt->options;
else else
@ -623,265 +615,10 @@ pslope_t *P_SlopeById(UINT16 id)
return ret; return ret;
} }
#ifdef SPRINGCLEAN
#include "byteptr.h"
#include "p_setup.h"
#include "p_local.h"
//==========================================================================
//
// P_SetSlopesFromVertexHeights
//
//==========================================================================
void P_SetSlopesFromVertexHeights(lumpnum_t lumpnum)
{
mapthing_t *mt;
boolean vt_found = false;
size_t i, j, k, l, q;
//size_t i;
//mapthing_t *mt;
char *data;
char *datastart;
// SRB2CBTODO: WHAT IS (5 * sizeof (short))?! It = 10
// anything else seems to make a map not load properly,
// but this hard-coded value MUST have some reason for being what it is
size_t snummapthings = W_LumpLength(lumpnum) / (5 * sizeof (short));
mapthing_t *smapthings = Z_Calloc(snummapthings * sizeof (*smapthings), PU_LEVEL, NULL);
fixed_t x, y;
sector_t *sector;
// Spawn axis points first so they are
// at the front of the list for fast searching.
data = datastart = W_CacheLumpNum(lumpnum, PU_LEVEL);
mt = smapthings;
for (i = 0; i < snummapthings; i++, mt++)
{
mt->x = READINT16(data);
mt->y = READINT16(data);
mt->angle = READINT16(data);
mt->type = READINT16(data);
mt->options = READINT16(data);
// mt->z hasn't been set yet!
//mt->extrainfo = (byte)(mt->type >> 12); // slope things are special, they have a bigger range of types
//mt->type &= 4095; // SRB2CBTODO: WHAT IS THIS???? Mobj type limits?!!!!
x = mt->x*FRACUNIT;
y = mt->y*FRACUNIT;
sector = R_PointInSubsector(x, y)->sector;
// Z for objects
#ifdef ESLOPE
if (sector->f_slope)
mt->z = (short)(P_GetZAt(sector->f_slope, x, y)>>FRACBITS);
else
#endif
mt->z = (short)(sector->floorheight>>FRACBITS);
mt->z = mt->z + (mt->options >> ZSHIFT);
if (mt->type == THING_VertexFloorZ || mt->type == THING_VertexCeilingZ) // THING_VertexFloorZ
{
for(l = 0; l < numvertexes; l++)
{
if (vertexes[l].x == mt->x*FRACUNIT && vertexes[l].y == mt->y*FRACUNIT)
{
if (mt->type == THING_VertexFloorZ)
{
vertexes[l].z = mt->z*FRACUNIT;
//I_Error("Z value: %i", vertexes[l].z/FRACUNIT);
}
else
{
vertexes[l].z = mt->z*FRACUNIT; // celing floor
}
vt_found = true;
}
}
//mt->type = 0; // VPHYSICS: Dynamic slopes
if (vt_found)
{
for (k = 0; k < numsectors; k++)
{
sector_t *sec = &sectors[k];
if (sec->linecount != 3) continue; // only works with triangular sectors
v3float_t vt1, vt2, vt3; // cross = ret->normalf
v3float_t vec1, vec2;
int vi1, vi2, vi3;
vi1 = (int)(sec->lines[0]->v1 - vertexes);
vi2 = (int)(sec->lines[0]->v2 - vertexes);
vi3 = (sec->lines[1]->v1 == sec->lines[0]->v1 || sec->lines[1]->v1 == sec->lines[0]->v2)?
(int)(sec->lines[1]->v2 - vertexes) : (int)(sec->lines[1]->v1 - vertexes);
//if (vertexes[vi1].z)
// I_Error("OSNAP %i", vertexes[vi1].z/FRACUNIT);
//if (vertexes[vi2].z)
// I_Error("OSNAP %i", vertexes[vi2].z/FRACUNIT);
//if (vertexes[vi3].z)
// I_Error("OSNAP %i", vertexes[vi3].z/FRACUNIT);
//I_Error("%i, %i", mt->z*FRACUNIT, vertexes[vi1].z);
//I_Error("%i, %i, %i", mt->x, mt->y, mt->z);
//P_SpawnMobj(mt->x*FRACUNIT, mt->y*FRACUNIT, mt->z*FRACUNIT, MT_RING);
// TODO: Make sure not to spawn in the same place 2x! (we need an object in every vertex of the
// triangle sector to setup the real vertex slopes
// Check for the vertexes of all sectors
for(q = 0; q < numvertexes; q++)
{
if (vertexes[q].x == mt->x*FRACUNIT && vertexes[q].y == mt->y*FRACUNIT)
{
//I_Error("yeah %i", vertexes[q].z);
P_SpawnMobj(vertexes[q].x, vertexes[q].y, vertexes[q].z, MT_RING);
#if 0
if ((mt->y*FRACUNIT == vertexes[vi1].y && mt->x*FRACUNIT == vertexes[vi1].x && mt->z*FRACUNIT == vertexes[vi1].z)
&& !(mt->y*FRACUNIT == vertexes[vi2].y && mt->x*FRACUNIT == vertexes[vi2].x && mt->z*FRACUNIT == vertexes[vi2].z)
&& !(mt->y*FRACUNIT == vertexes[vi3].y && mt->x*FRACUNIT == vertexes[vi3].x && mt->z*FRACUNIT == vertexes[vi3].z))
P_SpawnMobj(vertexes[vi1].x, vertexes[vi1].y, vertexes[vi1].z, MT_RING);
else if ((mt->y*FRACUNIT == vertexes[vi2].y && mt->x*FRACUNIT == vertexes[vi2].x && mt->z*FRACUNIT == vertexes[vi2].z)
&& !(mt->y*FRACUNIT == vertexes[vi1].y && mt->x*FRACUNIT == vertexes[vi1].x && mt->z*FRACUNIT == vertexes[vi1].z)
&& !(mt->y*FRACUNIT == vertexes[vi3].y && mt->x*FRACUNIT == vertexes[vi3].x && mt->z*FRACUNIT == vertexes[vi3].z))
P_SpawnMobj(vertexes[vi2].x, vertexes[vi2].y, vertexes[vi2].z, MT_BOUNCETV);
else if ((mt->y*FRACUNIT == vertexes[vi3].y && mt->x*FRACUNIT == vertexes[vi3].x && mt->z*FRACUNIT == vertexes[vi3].z)
&& !(mt->y*FRACUNIT == vertexes[vi2].y && mt->x*FRACUNIT == vertexes[vi2].x && mt->z*FRACUNIT == vertexes[vi2].z)
&& !(mt->y*FRACUNIT == vertexes[vi1].y && mt->x*FRACUNIT == vertexes[vi1].x && mt->z*FRACUNIT == vertexes[vi1].z))
P_SpawnMobj(vertexes[vi3].x, vertexes[vi3].y, vertexes[vi3].z, MT_GFZFLOWER1);
else
#endif
continue;
}
}
vt1.x = FIXED_TO_FLOAT(vertexes[vi1].x);
vt1.y = FIXED_TO_FLOAT(vertexes[vi1].y);
vt2.x = FIXED_TO_FLOAT(vertexes[vi2].x);
vt2.y = FIXED_TO_FLOAT(vertexes[vi2].y);
vt3.x = FIXED_TO_FLOAT(vertexes[vi3].x);
vt3.y = FIXED_TO_FLOAT(vertexes[vi3].y);
for(j = 0; j < 2; j++)
{
fixed_t z3;
//I_Error("Lo hicimos");
vt1.z = mt->z;//FIXED_TO_FLOAT(j==0 ? sec->floorheight : sec->ceilingheight);
vt2.z = mt->z;//FIXED_TO_FLOAT(j==0? sec->floorheight : sec->ceilingheight);
z3 = mt->z;//j==0? sec->floorheight : sec->ceilingheight; // Destination height
vt3.z = FIXED_TO_FLOAT(z3);
if (P_PointOnLineSide(vertexes[vi3].x, vertexes[vi3].y, sec->lines[0]) == 0)
{
vec1.x = vt2.x - vt3.x;
vec1.y = vt2.y - vt3.y;
vec1.z = vt2.z - vt3.z;
vec2.x = vt1.x - vt3.x;
vec2.y = vt1.y - vt3.y;
vec2.z = vt1.z - vt3.z;
}
else
{
vec1.x = vt1.x - vt3.x;
vec1.y = vt1.y - vt3.y;
vec1.z = vt1.z - vt3.z;
vec2.x = vt2.x - vt3.x;
vec2.y = vt2.y - vt3.y;
vec2.z = vt2.z - vt3.z;
}
pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL);
memset(ret, 0, sizeof(*ret));
{
M_CrossProduct3f(&ret->normalf, &vec1, &vec2);
// Cross product length
float len = (float)sqrt(ret->normalf.x * ret->normalf.x +
ret->normalf.y * ret->normalf.y +
ret->normalf.z * ret->normalf.z);
if (len == 0)
{
// Only happens when all vertices in this sector are on the same line.
// Let's just ignore this case.
//CONS_Printf("Slope thing at (%d,%d) lies directly on its target line.\n", (int)(x>>16), (int)(y>>16));
return;
}
// cross/len
ret->normalf.x /= len;
ret->normalf.y /= len;
ret->normalf.z /= len;
// ZDoom cross = ret->normalf
// Fix backward normals
if ((ret->normalf.z < 0 && j == 0) || (ret->normalf.z > 0 && j == 1))
{
// cross = -cross
ret->normalf.x = -ret->normalf.x;
ret->normalf.y = -ret->normalf.x;
ret->normalf.z = -ret->normalf.x;
}
}
secplane_t *srcplane = Z_Calloc(sizeof(*srcplane), PU_LEVEL, NULL);
srcplane->a = FLOAT_TO_FIXED (ret->normalf.x);
srcplane->b = FLOAT_TO_FIXED (ret->normalf.y);
srcplane->c = FLOAT_TO_FIXED (ret->normalf.z);
//srcplane->ic = FixedDiv(FRACUNIT, srcplane->c);
srcplane->d = -TMulScale16 (srcplane->a, vertexes[vi3].x,
srcplane->b, vertexes[vi3].y,
srcplane->c, z3);
if (j == 0)
{
sec->f_slope = ret;
sec->f_slope->secplane = *srcplane;
}
else if (j == 1)
{
sec->c_slope = ret;
sec->c_slope->secplane = *srcplane;
}
}
}
}
}
}
Z_Free(datastart);
}
#endif
// Reset the dynamic slopes pointer, and read all of the fancy schmancy slopes // Reset the dynamic slopes pointer, and read all of the fancy schmancy slopes
void P_ResetDynamicSlopes(void) { void P_ResetDynamicSlopes(void) {
size_t i; size_t i;
#if 1 // Rewrite old specials to new ones, and give a console warning #ifdef ESLOPE_TYPESHIM // Rewrite old specials to new ones, and give a console warning
boolean warned = false; boolean warned = false;
#endif #endif
@ -894,7 +631,7 @@ void P_ResetDynamicSlopes(void) {
{ {
switch (lines[i].special) switch (lines[i].special)
{ {
#if 1 // Rewrite old specials to new ones, and give a console warning #ifdef ESLOPE_TYPESHIM // Rewrite old specials to new ones, and give a console warning
#define WARNME if (!warned) {warned = true; CONS_Alert(CONS_WARNING, "This level uses old slope specials.\nA conversion will be needed before 2.2's release.\n");} #define WARNME if (!warned) {warned = true; CONS_Alert(CONS_WARNING, "This level uses old slope specials.\nA conversion will be needed before 2.2's release.\n");}
case 386: case 386:
case 387: case 387:
@ -1018,7 +755,11 @@ fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y)
// When given a vector, rotates it and aligns it to a slope // When given a vector, rotates it and aligns it to a slope
void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope) void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope)
{ {
vector3_t axis; vector3_t axis; // Fuck you, C90.
if (slope->flags & SL_NOPHYSICS)
return; // No physics, no quantizing.
axis.x = -slope->d.y; axis.x = -slope->d.y;
axis.y = slope->d.x; axis.y = slope->d.x;
axis.z = 0; axis.z = 0;
@ -1026,24 +767,38 @@ void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope)
FV3_Rotate(momentum, &axis, slope->zangle >> ANGLETOFINESHIFT); FV3_Rotate(momentum, &axis, slope->zangle >> ANGLETOFINESHIFT);
} }
//
// P_ReverseQuantizeMomentumToSlope
//
// When given a vector, rotates and aligns it to a flat surface (from being relative to a given slope)
void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope)
{
slope->zangle = InvAngle(slope->zangle);
P_QuantizeMomentumToSlope(momentum, slope);
slope->zangle = InvAngle(slope->zangle);
}
// //
// P_SlopeLaunch // P_SlopeLaunch
// //
// Handles slope ejection for objects // Handles slope ejection for objects
void P_SlopeLaunch(mobj_t *mo) void P_SlopeLaunch(mobj_t *mo)
{ {
// Double the pre-rotation Z, then halve the post-rotation Z. This reduces the if (!(mo->standingslope->flags & SL_NOPHYSICS)) // If there's physics, time for launching.
// vertical launch given from slopes while increasing the horizontal launch {
// given. Good for SRB2's gravity and horizontal speeds. // Double the pre-rotation Z, then halve the post-rotation Z. This reduces the
vector3_t slopemom; // vertical launch given from slopes while increasing the horizontal launch
slopemom.x = mo->momx; // given. Good for SRB2's gravity and horizontal speeds.
slopemom.y = mo->momy; vector3_t slopemom;
slopemom.z = mo->momz*2; slopemom.x = mo->momx;
P_QuantizeMomentumToSlope(&slopemom, mo->standingslope); slopemom.y = mo->momy;
slopemom.z = mo->momz*2;
P_QuantizeMomentumToSlope(&slopemom, mo->standingslope);
mo->momx = slopemom.x; mo->momx = slopemom.x;
mo->momy = slopemom.y; mo->momy = slopemom.y;
mo->momz = slopemom.z/2; mo->momz = slopemom.z/2;
}
//CONS_Printf("Launched off of slope.\n"); //CONS_Printf("Launched off of slope.\n");
mo->standingslope = NULL; mo->standingslope = NULL;
@ -1052,17 +807,21 @@ void P_SlopeLaunch(mobj_t *mo)
// Function to help handle landing on slopes // Function to help handle landing on slopes
void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope)
{ {
vector3_t mom; vector3_t mom; // Ditto.
if (slope->flags & SL_NOPHYSICS) { // No physics, no need to make anything complicated.
if (P_MobjFlip(thing)*(thing->momz) < 0) { // falling, land on slope
thing->momz = -P_MobjFlip(thing);
thing->standingslope = slope;
}
return;
}
mom.x = thing->momx; mom.x = thing->momx;
mom.y = thing->momy; mom.y = thing->momy;
mom.z = thing->momz*2; mom.z = thing->momz*2;
//CONS_Printf("langing on slope\n"); P_ReverseQuantizeMomentumToSlope(&mom, slope);
// Reverse quantizing might could use its own function later
slope->zangle = ANGLE_MAX-slope->zangle;
P_QuantizeMomentumToSlope(&mom, slope);
slope->zangle = ANGLE_MAX-slope->zangle;
if (P_MobjFlip(thing)*mom.z < 0) { // falling, land on slope if (P_MobjFlip(thing)*mom.z < 0) { // falling, land on slope
thing->momx = mom.x; thing->momx = mom.x;
@ -1082,6 +841,9 @@ void P_ButteredSlope(mobj_t *mo)
if (!mo->standingslope) if (!mo->standingslope)
return; return;
if (mo->standingslope->flags & SL_NOPHYSICS)
return; // No physics, no butter.
if (mo->flags & (MF_NOCLIPHEIGHT|MF_NOGRAVITY)) if (mo->flags & (MF_NOCLIPHEIGHT|MF_NOGRAVITY))
return; // don't slide down slopes if you can't touch them or you're not affected by gravity return; // don't slide down slopes if you can't touch them or you're not affected by gravity
@ -1106,8 +868,6 @@ void P_ButteredSlope(mobj_t *mo)
mult = FINECOSINE(angle >> ANGLETOFINESHIFT); mult = FINECOSINE(angle >> ANGLETOFINESHIFT);
} }
//CONS_Printf("%d\n", mult);
thrust = FixedMul(thrust, FRACUNIT*2/3 + mult/8); thrust = FixedMul(thrust, FRACUNIT*2/3 + mult/8);
} }
@ -1115,10 +875,11 @@ void P_ButteredSlope(mobj_t *mo)
thrust = FixedMul(thrust, FRACUNIT+P_AproxDistance(mo->momx, mo->momy)/16); thrust = FixedMul(thrust, FRACUNIT+P_AproxDistance(mo->momx, mo->momy)/16);
// This makes it harder to zigzag up steep slopes, as well as allows greater top speed when rolling down // This makes it harder to zigzag up steep slopes, as well as allows greater top speed when rolling down
// Multiply by gravity // Let's get the gravity strength for the object...
thrust = FixedMul(thrust, gravity); // TODO account for per-sector gravity etc thrust = FixedMul(thrust, abs(P_GetMobjGravity(mo)));
// Multiply by scale (gravity strength depends on mobj scale)
thrust = FixedMul(thrust, mo->scale); // ... and its friction against the ground for good measure (divided by original friction to keep behaviour for normal slopes the same).
thrust = FixedMul(thrust, FixedDiv(mo->friction, ORIG_FRICTION));
P_Thrust(mo, mo->standingslope->xydirection, thrust); P_Thrust(mo, mo->standingslope->xydirection, thrust);
} }

View File

@ -21,26 +21,6 @@ void P_RunDynamicSlopes(void);
// sectors. // sectors.
void P_SpawnSlope_Line(int linenum); 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 // P_CopySectorSlope
// //
@ -55,6 +35,7 @@ fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y);
// Lots of physics-based bullshit // Lots of physics-based bullshit
void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope); void P_QuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);
void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope);
void P_SlopeLaunch(mobj_t *mo); void P_SlopeLaunch(mobj_t *mo);
void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope); void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope);
void P_ButteredSlope(mobj_t *mo); void P_ButteredSlope(mobj_t *mo);

View File

@ -1188,7 +1188,12 @@ INT32 P_FindSpecialLineFromTag(INT16 special, INT16 tag, INT32 start)
{ {
start++; start++;
while (lines[start].special != special) // This redundant check stops the compiler from complaining about function expansion
// elsewhere for some reason and everything is awful
if (start >= (INT32)numlines)
return -1;
while (start < (INT32)numlines && lines[start].special != special)
start++; start++;
if (start >= (INT32)numlines) if (start >= (INT32)numlines)
@ -1642,7 +1647,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
mo = node->m_thing; mo = node->m_thing;
if (mo->flags & MF_PUSHABLE) if (mo->flags & MF_PUSHABLE)
numpush++; numpush++;
node = node->m_snext; node = node->m_thinglist_next;
} }
if (triggerline->flags & ML_NOCLIMB) // Need at least or more if (triggerline->flags & ML_NOCLIMB) // Need at least or more
@ -3145,7 +3150,7 @@ void P_SetupSignExit(player_t *player)
thinker_t *think; thinker_t *think;
INT32 numfound = 0; INT32 numfound = 0;
for (; node; node = node->m_snext) for (; node; node = node->m_thinglist_next)
{ {
thing = node->m_thing; thing = node->m_thing;
if (thing->type != MT_SIGN) if (thing->type != MT_SIGN)
@ -3309,7 +3314,7 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n
return rover->master->frontsector; return rover->master->frontsector;
} }
for (node = player->mo->touching_sectorlist; node; node = node->m_snext) for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next)
{ {
if (GETSECSPECIAL(node->m_sector->special, section) == number) if (GETSECSPECIAL(node->m_sector->special, section) == number)
{ {
@ -3884,7 +3889,7 @@ DoneSection2:
mobj_t *mo2; mobj_t *mo2;
angle_t an; angle_t an;
if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT) if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ZOOMTUBE)
break; break;
// Find line #3 tagged to this sector // Find line #3 tagged to this sector
@ -3933,10 +3938,10 @@ DoneSection2:
break; // behind back break; // behind back
P_SetTarget(&player->mo->tracer, waypoint); P_SetTarget(&player->mo->tracer, waypoint);
player->powers[pw_carry] = CR_ZOOMTUBE;
player->speed = speed; player->speed = speed;
player->pflags |= PF_SPINNING; player->pflags |= PF_SPINNING;
player->pflags &= ~PF_JUMPED; player->pflags &= ~(PF_JUMPED|PF_GLIDING|PF_SLIDING|PF_CANCARRY);
player->pflags &= ~PF_GLIDING;
player->climbing = 0; player->climbing = 0;
if (player->mo->state-states != S_PLAY_SPIN) if (player->mo->state-states != S_PLAY_SPIN)
@ -3957,7 +3962,7 @@ DoneSection2:
mobj_t *mo2; mobj_t *mo2;
angle_t an; angle_t an;
if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT) if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ZOOMTUBE)
break; break;
// Find line #3 tagged to this sector // Find line #3 tagged to this sector
@ -4007,9 +4012,10 @@ DoneSection2:
break; // behind back break; // behind back
P_SetTarget(&player->mo->tracer, waypoint); P_SetTarget(&player->mo->tracer, waypoint);
player->powers[pw_carry] = CR_ZOOMTUBE;
player->speed = speed; player->speed = speed;
player->pflags |= PF_SPINNING; player->pflags |= PF_SPINNING;
player->pflags &= ~PF_JUMPED; player->pflags &= ~(PF_JUMPED|PF_GLIDING|PF_SLIDING|PF_CANCARRY);
if (player->mo->state-states != S_PLAY_SPIN) if (player->mo->state-states != S_PLAY_SPIN)
{ {
@ -4079,7 +4085,7 @@ DoneSection2:
vertex_t v1, v2, resulthigh, resultlow; vertex_t v1, v2, resulthigh, resultlow;
mobj_t *highest = NULL; mobj_t *highest = NULL;
if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT) if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ROPEHANG)
break; break;
if (player->mo->momz > 0) if (player->mo->momz > 0)
@ -4300,6 +4306,7 @@ DoneSection2:
} }
P_SetTarget(&player->mo->tracer, closest); P_SetTarget(&player->mo->tracer, closest);
player->powers[pw_carry] = CR_ROPEHANG;
// Option for static ropes. // Option for static ropes.
if (lines[lineindex].flags & ML_NOCLIMB) if (lines[lineindex].flags & ML_NOCLIMB)
@ -4307,13 +4314,9 @@ DoneSection2:
else else
player->speed = speed; player->speed = speed;
player->pflags |= PF_ROPEHANG;
S_StartSound(player->mo, sfx_s3k4a); S_StartSound(player->mo, sfx_s3k4a);
player->pflags &= ~PF_JUMPED; player->pflags &= ~(PF_JUMPED|PF_GLIDING|PF_SLIDING|PF_CANCARRY);
player->pflags &= ~PF_GLIDING;
player->pflags &= ~PF_SLIDING;
player->climbing = 0; player->climbing = 0;
P_SetThingPosition(player->mo); P_SetThingPosition(player->mo);
P_SetPlayerMobjState(player->mo, S_PLAY_RIDE); P_SetPlayerMobjState(player->mo, S_PLAY_RIDE);
@ -4658,7 +4661,7 @@ void P_PlayerInSpecialSector(player_t *player)
P_RunSpecialSectorCheck(player, sector); P_RunSpecialSectorCheck(player, sector);
// Iterate through touching_sectorlist // Iterate through touching_sectorlist
for (node = player->mo->touching_sectorlist; node; node = node->m_snext) for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next)
{ {
sector = node->m_sector; sector = node->m_sector;
@ -5309,7 +5312,7 @@ void T_LaserFlash(laserthink_t *flash)
S_StartSound(&sector->soundorg, sfx_laser); S_StartSound(&sector->soundorg, sfx_laser);
// Seek out objects to DESTROY! MUAHAHHAHAHAA!!!*cough* // Seek out objects to DESTROY! MUAHAHHAHAHAA!!!*cough*
for (node = sector->touching_thinglist; node && node->m_thing; node = node->m_snext) for (node = sector->touching_thinglist; node && node->m_thing; node = node->m_thinglist_next)
{ {
thing = node->m_thing; thing = node->m_thing;
@ -6580,7 +6583,7 @@ void T_Scroll(scroll_t *s)
sector_t *psec; sector_t *psec;
psec = sectors + sect; psec = sectors + sect;
for (node = psec->touching_thinglist; node; node = node->m_snext) for (node = psec->touching_thinglist; node; node = node->m_thinglist_next)
{ {
thing = node->m_thing; thing = node->m_thing;
@ -6602,7 +6605,7 @@ void T_Scroll(scroll_t *s)
if (!is3dblock) if (!is3dblock)
{ {
for (node = sec->touching_thinglist; node; node = node->m_snext) for (node = sec->touching_thinglist; node; node = node->m_thinglist_next)
{ {
thing = node->m_thing; thing = node->m_thing;
@ -6643,7 +6646,7 @@ void T_Scroll(scroll_t *s)
sector_t *psec; sector_t *psec;
psec = sectors + sect; psec = sectors + sect;
for (node = psec->touching_thinglist; node; node = node->m_snext) for (node = psec->touching_thinglist; node; node = node->m_thinglist_next)
{ {
thing = node->m_thing; thing = node->m_thing;
@ -6665,7 +6668,7 @@ void T_Scroll(scroll_t *s)
if (!is3dblock) if (!is3dblock)
{ {
for (node = sec->touching_thinglist; node; node = node->m_snext) for (node = sec->touching_thinglist; node; node = node->m_thinglist_next)
{ {
thing = node->m_thing; thing = node->m_thing;
@ -7015,7 +7018,7 @@ void T_Friction(friction_t *f)
{ {
if (thing->floorz != P_GetSpecialTopZ(thing, referrer, sec)) if (thing->floorz != P_GetSpecialTopZ(thing, referrer, sec))
{ {
node = node->m_snext; node = node->m_thinglist_next;
continue; continue;
} }
@ -7033,7 +7036,7 @@ void T_Friction(friction_t *f)
thing->movefactor = f->movefactor; thing->movefactor = f->movefactor;
} }
} }
node = node->m_snext; node = node->m_thinglist_next;
} }
} }
@ -7160,7 +7163,7 @@ static inline boolean PIT_PushThing(mobj_t *thing)
if (thing->eflags & MFE_PUSHED) if (thing->eflags & MFE_PUSHED)
return false; return false;
if (thing->player && thing->player->pflags & PF_ROPEHANG) if (thing->player && thing->player->powers[pw_carry] == CR_ROPEHANG)
return false; return false;
// Allow this to affect pushable objects at some point? // Allow this to affect pushable objects at some point?
@ -7373,7 +7376,7 @@ void T_Pusher(pusher_t *p)
// constant pushers p_wind and p_current // constant pushers p_wind and p_current
node = sec->touching_thinglist; // things touching this sector node = sec->touching_thinglist; // things touching this sector
for (; node; node = node->m_snext) for (; node; node = node->m_thinglist_next)
{ {
thing = node->m_thing; thing = node->m_thing;
if (thing->flags & (MF_NOGRAVITY | MF_NOCLIP) if (thing->flags & (MF_NOGRAVITY | MF_NOCLIP)
@ -7393,7 +7396,7 @@ void T_Pusher(pusher_t *p)
if (thing->eflags & MFE_PUSHED) if (thing->eflags & MFE_PUSHED)
continue; continue;
if (thing->player && thing->player->pflags & PF_ROPEHANG) if (thing->player && thing->player->powers[pw_carry] == CR_ROPEHANG)
continue; continue;
if (thing->player && (thing->state == &states[thing->info->painstate]) && (thing->player->powers[pw_flashing] > (flashingtics/4)*3 && thing->player->powers[pw_flashing] <= flashingtics)) if (thing->player && (thing->state == &states[thing->info->painstate]) && (thing->player->powers[pw_flashing] > (flashingtics/4)*3 && thing->player->powers[pw_flashing] <= flashingtics))

View File

@ -160,9 +160,9 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle
INT32 p; INT32 p;
// Search for any players you might be carrying, so you can get them off before they end up being taken with you! // Search for any players you might be carrying, so you can get them off before they end up being taken with you!
for (p = 0; p < MAXPLAYERS; p++) for (p = 0; p < MAXPLAYERS; p++)
if (playeringame[p] && players[p].mo && players[p].pflags & PF_CARRIED && players[p].mo->tracer == thing) if (playeringame[p] && players[p].mo && players[p].powers[pw_carry] == CR_PLAYER && players[p].mo->tracer == thing)
{ {
players[p].pflags &= ~PF_CARRIED; players[p].powers[pw_carry] = CR_NONE;
break; break;
} }
thing->player->cmomx = thing->player->cmomy = 0; thing->player->cmomx = thing->player->cmomy = 0;

File diff suppressed because it is too large Load Diff

View File

@ -30,7 +30,7 @@ typedef struct
{ {
// Block origin (always UL), which has already accounted for the internal origin of the patch. // Block origin (always UL), which has already accounted for the internal origin of the patch.
INT16 originx, originy; INT16 originx, originy;
INT16 wad, lump; UINT16 wad, lump;
} texpatch_t; } texpatch_t;
// A maptexturedef_t describes a rectangular texture, // A maptexturedef_t describes a rectangular texture,

View File

@ -500,10 +500,10 @@ typedef struct subsector_s
// Sector list node showing all sectors an object appears in. // Sector list node showing all sectors an object appears in.
// //
// There are two threads that flow through these nodes. The first thread // There are two threads that flow through these nodes. The first thread
// starts at touching_thinglist in a sector_t and flows through the m_snext // starts at touching_thinglist in a sector_t and flows through the m_thinglist_next
// links to find all mobjs that are entirely or partially in the sector. // links to find all mobjs that are entirely or partially in the sector.
// The second thread starts at touching_sectorlist in an mobj_t and flows // The second thread starts at touching_sectorlist in an mobj_t and flows
// through the m_tnext links to find all sectors a thing touches. This is // through the m_sectorlist_next links to find all sectors a thing touches. This is
// useful when applying friction or push effects to sectors. These effects // useful when applying friction or push effects to sectors. These effects
// can be done as thinkers that act upon all objects touching their sectors. // can be done as thinkers that act upon all objects touching their sectors.
// As an mobj moves through the world, these nodes are created and // As an mobj moves through the world, these nodes are created and
@ -515,10 +515,10 @@ typedef struct msecnode_s
{ {
sector_t *m_sector; // a sector containing this object sector_t *m_sector; // a sector containing this object
struct mobj_s *m_thing; // this object struct mobj_s *m_thing; // this object
struct msecnode_s *m_tprev; // prev msecnode_t for this thing struct msecnode_s *m_sectorlist_prev; // prev msecnode_t for this thing
struct msecnode_s *m_tnext; // next msecnode_t for this thing struct msecnode_s *m_sectorlist_next; // next msecnode_t for this thing
struct msecnode_s *m_sprev; // prev msecnode_t for this sector struct msecnode_s *m_thinglist_prev; // prev msecnode_t for this sector
struct msecnode_s *m_snext; // next msecnode_t for this sector struct msecnode_s *m_thinglist_next; // next msecnode_t for this sector
boolean visited; // used in search algorithms boolean visited; // used in search algorithms
} msecnode_t; } msecnode_t;
@ -526,10 +526,10 @@ typedef struct mprecipsecnode_s
{ {
sector_t *m_sector; // a sector containing this object sector_t *m_sector; // a sector containing this object
struct precipmobj_s *m_thing; // this object struct precipmobj_s *m_thing; // this object
struct mprecipsecnode_s *m_tprev; // prev msecnode_t for this thing struct mprecipsecnode_s *m_sectorlist_prev; // prev msecnode_t for this thing
struct mprecipsecnode_s *m_tnext; // next msecnode_t for this thing struct mprecipsecnode_s *m_sectorlist_next; // next msecnode_t for this thing
struct mprecipsecnode_s *m_sprev; // prev msecnode_t for this sector struct mprecipsecnode_s *m_thinglist_prev; // prev msecnode_t for this sector
struct mprecipsecnode_s *m_snext; // next msecnode_t for this sector struct mprecipsecnode_s *m_thinglist_next; // next msecnode_t for this sector
boolean visited; // used in search algorithms boolean visited; // used in search algorithms
} mprecipsecnode_t; } mprecipsecnode_t;
@ -729,23 +729,36 @@ typedef struct
#pragma pack() #pragma pack()
#endif #endif
typedef enum
{
SRF_SINGLE = 0, // 0-angle for all rotations
SRF_3D = 1, // Angles 1-8
SRF_LEFT = 2, // Left side uses single patch
SRF_RIGHT = 4, // Right side uses single patch
SRF_2D = SRF_LEFT|SRF_RIGHT, // 6
SRF_NONE = 0xff // Initial value
} spriterotateflags_t; // SRF's up!
// //
// Sprites are patches with a special naming convention so they can be // Sprites are patches with a special naming convention so they can be
// recognized by R_InitSprites. // recognized by R_InitSprites.
// The base name is NNNNFx or NNNNFxFx, with x indicating the rotation, // The base name is NNNNFx or NNNNFxFx, with x indicating the rotation,
// x = 0, 1-7. // x = 0, 1-8, L/R
// The sprite and frame specified by a thing_t is range checked at run time. // The sprite and frame specified by a thing_t is range checked at run time.
// A sprite is a patch_t that is assumed to represent a three dimensional // A sprite is a patch_t that is assumed to represent a three dimensional
// object and may have multiple rotations predrawn. // object and may have multiple rotations predrawn.
// Horizontal flipping is used to save space, thus NNNNF2F5 defines a mirrored patch. // Horizontal flipping is used to save space, thus NNNNF2F5 defines a mirrored patch.
// Some sprites will only have one picture used for all views: NNNNF0 // Some sprites will only have one picture used for all views: NNNNF0
// Some sprites will take the entirety of the left side: NNNNFL
// Or the right side: NNNNFR
// Or both, mirrored: NNNNFLFR
// //
typedef struct typedef struct
{ {
// If false use 0 for any position. // If false use 0 for any position.
// Note: as eight entries are available, we might as well insert the same // Note: as eight entries are available, we might as well insert the same
// name eight times. // name eight times.
UINT8 rotate; UINT8 rotate; // see spriterotateflags_t above
// Lump to use for view angles 0-7. // Lump to use for view angles 0-7.
lumpnum_t lumppat[8]; // lump number 16 : 16 wad : lump lumpnum_t lumppat[8]; // lump number 16 : 16 wad : lump

View File

@ -135,7 +135,7 @@ static UINT8** translationtablecache[MAXSKINS + 4] = {NULL};
// See also the enum skincolors_t // See also the enum skincolors_t
// TODO Callum: Can this be translated? // TODO Callum: Can this be translated?
const char *Color_Names[MAXSKINCOLORS] = const char *Color_Names[MAXSKINCOLORS + NUMSUPERCOLORS] =
{ {
"None", // SKINCOLOR_NONE "None", // SKINCOLOR_NONE
"White", // SKINCOLOR_WHITE "White", // SKINCOLOR_WHITE
@ -166,9 +166,23 @@ const char *Color_Names[MAXSKINCOLORS] =
"Lavender", // SKINCOLOR_LAVENDER "Lavender", // SKINCOLOR_LAVENDER
"Magenta", // SKINCOLOR_MAGENTA "Magenta", // SKINCOLOR_MAGENTA
"Pink", // SKINCOLOR_PINK "Pink", // SKINCOLOR_PINK
"Rosy" // SKINCOLOR_ROSY "Rosy", // SKINCOLOR_ROSY
// Super behaves by different rules (one name per 5 colours), and will be accessed exclusively via R_GetSuperColorByName instead of R_GetColorByName.
"Silver", // SKINCOLOR_SUPERSILVER1
"Red", // SKINCOLOR_SUPERRED1
"Orange", // SKINCOLOR_SUPERORANGE1
"Gold", // SKINCOLOR_SUPERGOLD1
"Peridot", // SKINCOLOR_SUPERPERIDOT1
"Cyan", // SKINCOLOR_SUPERCYAN1
"Purple", // SKINCOLOR_SUPERPURPLE1
"Rust", // SKINCOLOR_SUPERRUST1
"Tan" // SKINCOLOR_SUPERTAN1
}; };
/*
A word of warning: If the following array is non-symmetrical,
A_SignPlayer's prefoppositecolor behaviour will break.
*/
const UINT8 Color_Opposite[MAXSKINCOLORS*2] = const UINT8 Color_Opposite[MAXSKINCOLORS*2] =
{ {
SKINCOLOR_NONE,8, // SKINCOLOR_NONE SKINCOLOR_NONE,8, // SKINCOLOR_NONE
@ -183,7 +197,7 @@ const UINT8 Color_Opposite[MAXSKINCOLORS*2] =
SKINCOLOR_CYAN,8, // SKINCOLOR_CRIMSON - ditto SKINCOLOR_CYAN,8, // SKINCOLOR_CRIMSON - ditto
SKINCOLOR_BLUE,12, // SKINCOLOR_ORANGE SKINCOLOR_BLUE,12, // SKINCOLOR_ORANGE
SKINCOLOR_TAN,8, // SKINCOLOR_RUST - ditto SKINCOLOR_TAN,8, // SKINCOLOR_RUST - ditto
SKINCOLOR_LAVENDER,8, // SKINCOLOR_GOLD - ditto SKINCOLOR_LAVENDER,8, // SKINCOLOR_GOLD - ditto
SKINCOLOR_TEAL,8, // SKINCOLOR_YELLOW - ditto SKINCOLOR_TEAL,8, // SKINCOLOR_YELLOW - ditto
SKINCOLOR_RUST,8, // SKINCOLOR_TAN - ditto SKINCOLOR_RUST,8, // SKINCOLOR_TAN - ditto
SKINCOLOR_MAGENTA,3, // SKINCOLOR_MOSS SKINCOLOR_MAGENTA,3, // SKINCOLOR_MOSS
@ -196,11 +210,11 @@ const UINT8 Color_Opposite[MAXSKINCOLORS*2] =
SKINCOLOR_ORANGE,9, // SKINCOLOR_BLUE SKINCOLOR_ORANGE,9, // SKINCOLOR_BLUE
SKINCOLOR_PINK,8, // SKINCOLOR_AZURE - ditto SKINCOLOR_PINK,8, // SKINCOLOR_AZURE - ditto
SKINCOLOR_EMERALD,8, // SKINCOLOR_PASTEL - ditto SKINCOLOR_EMERALD,8, // SKINCOLOR_PASTEL - ditto
SKINCOLOR_PERIDOT,8, // SKINCOLOR_PURPLE - ditto SKINCOLOR_PERIDOT,10, // SKINCOLOR_PURPLE - ditto
SKINCOLOR_GOLD,8, // SKINCOLOR_LAVENDER - ditto SKINCOLOR_GOLD,8, // SKINCOLOR_LAVENDER - ditto
SKINCOLOR_MOSS,8, // SKINCOLOR_MAGENTA - ditto SKINCOLOR_MOSS,8, // SKINCOLOR_MAGENTA - ditto
SKINCOLOR_AZURE,8, // SKINCOLOR_PINK - ditto SKINCOLOR_AZURE,8, // SKINCOLOR_PINK - ditto
SKINCOLOR_AQUA,8 // SKINCOLOR_ROSY - ditto SKINCOLOR_AQUA,14 // SKINCOLOR_ROSY - ditto
}; };
CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1]; CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1];
@ -569,49 +583,186 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
break; break;
// Super colors, from lightest to darkest! // Super colors, from lightest to darkest!
case SKINCOLOR_SUPER1:
// Super White // Super silvers.
case SKINCOLOR_SUPERSILVER1:
for (i = 0; i < 12; i++)
dest_colormap[starttranscolor + i] = (UINT8)0;
for (; i < 14; i++)
dest_colormap[starttranscolor + i] = (UINT8)1;
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(i-12);
break;
case SKINCOLOR_SUPERSILVER2:
for (i = 0; i < 3; i++)
dest_colormap[starttranscolor + i] = (UINT8)(i);
dest_colormap[starttranscolor + (i++)] = (UINT8)2;
for (; i < 8; i++)
dest_colormap[starttranscolor + i] = (UINT8)3;
for (; i < 14; i++)
dest_colormap[starttranscolor + i] = (UINT8)4;
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(i-9);
break;
case SKINCOLOR_SUPERSILVER3:
dest_colormap[starttranscolor] = (UINT8)1;
for (i = 1; i < 3; i++)
dest_colormap[starttranscolor + i] = (UINT8)2;
for (; i < 6; i++)
dest_colormap[starttranscolor + i] = (UINT8)3;
for (; i < 12; i++)
dest_colormap[starttranscolor + i] = (UINT8)4;
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(5 + ((i-12)*2));
break;
case SKINCOLOR_SUPERSILVER4:
dest_colormap[starttranscolor] = (UINT8)2;
for (i = 1; i < 3; i++)
dest_colormap[starttranscolor + i] = (UINT8)3;
for (; i < 9; i++)
dest_colormap[starttranscolor + i] = (UINT8)4;
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(5 + ((i-9)*2));
break;
case SKINCOLOR_SUPERSILVER5:
for (i = 0; i < 2; i++)
dest_colormap[starttranscolor + i] = (UINT8)3;
for (; i < 8; i++)
dest_colormap[starttranscolor + i] = (UINT8)4;
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(5 + ((i-8)*2));
break;
// Super reds.
case SKINCOLOR_SUPERRED1:
for (i = 0; i < 10; i++)
dest_colormap[starttranscolor + i] = (UINT8)0;
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(208 + ((i-10) >> 1));
break;
case SKINCOLOR_SUPERRED2:
for (i = 0; i < 3; i++)
dest_colormap[starttranscolor + i] = (UINT8)0;
for (; i < 12; i++)
dest_colormap[starttranscolor + i] = (UINT8)(208 + ((i-3) / 3));
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(32 + ((i-12) >> 1));
break;
case SKINCOLOR_SUPERRED3:
for (i = 0; i < 2; i++)
dest_colormap[starttranscolor + i] = (UINT8)0;
for (; i < 8; i++)
dest_colormap[starttranscolor + i] = (UINT8)(208 + ((i-2) >> 1));
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(32 + ((i-8) >> 1));
break;
case SKINCOLOR_SUPERRED4:
dest_colormap[starttranscolor] = (UINT8)0;
for (i = 1; i < 6; i++)
dest_colormap[starttranscolor + i] = (UINT8)(208 + (i >> 1));
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(32 + ((i-6) >> 1));
break;
case SKINCOLOR_SUPERRED5:
dest_colormap[starttranscolor] = (UINT8)208;
for (i = 1; i < 4; i++)
dest_colormap[starttranscolor + i] = (UINT8)(209 + (i >> 1));
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(32 + ((i-4) >> 1));
break;
// Super oranges.
case SKINCOLOR_SUPERORANGE1:
for (i = 0; i < 10; i++)
dest_colormap[starttranscolor + i] = (UINT8)0;
dest_colormap[starttranscolor + (i++)] = (UINT8)208;
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(48 + (i-11));
break;
case SKINCOLOR_SUPERORANGE2:
for (i = 0; i < 4; i++)
dest_colormap[starttranscolor + i] = (UINT8)0;
for (; i < 6; i++)
dest_colormap[starttranscolor + i] = (UINT8)208;
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(48 + ((i-6) >> 1));
break;
case SKINCOLOR_SUPERORANGE3:
for (i = 0; i < 2; i++)
dest_colormap[starttranscolor + i] = (UINT8)0;
for (; i < 4; i++)
dest_colormap[starttranscolor + i] = (UINT8)208;
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(48 + ((i-4) >> 1));
break;
case SKINCOLOR_SUPERORANGE4:
dest_colormap[starttranscolor] = (UINT8)0;
dest_colormap[starttranscolor + 1] = (UINT8)208;
for (i = 2; i < 13; i++)
dest_colormap[starttranscolor + i] = (UINT8)(48 + (i-2));
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(68 + (i-13));
break;
case SKINCOLOR_SUPERORANGE5:
dest_colormap[starttranscolor] = (UINT8)208;
for (i = 1; i < 12; i++)
dest_colormap[starttranscolor + i] = (UINT8)(48 + (i-1));
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(68 + (i-12));
break;
// Super golds.
case SKINCOLOR_SUPERGOLD1:
for (i = 0; i < 10; i++) for (i = 0; i < 10; i++)
dest_colormap[starttranscolor + i] = (UINT8)0; // True white dest_colormap[starttranscolor + i] = (UINT8)0; // True white
for (; i < 12; i++) // White-yellow fade for (; i < 12; i++) // White-yellow fade
dest_colormap[starttranscolor + i] = (UINT8)(80); dest_colormap[starttranscolor + i] = (UINT8)80;
for (; i < 15; i++) // White-yellow fade for (; i < 15; i++) // White-yellow fade
dest_colormap[starttranscolor + i] = (UINT8)(81 + (i-12)); dest_colormap[starttranscolor + i] = (UINT8)(81 + (i-12));
dest_colormap[starttranscolor + 15] = (UINT8)(72); dest_colormap[starttranscolor + 15] = (UINT8)72;
break; break;
case SKINCOLOR_SUPER2: case SKINCOLOR_SUPERGOLD2:
// Super Bright
dest_colormap[starttranscolor] = (UINT8)(0); dest_colormap[starttranscolor] = (UINT8)(0);
for (i = 1; i < 4; i++) // White-yellow fade for (i = 1; i < 4; i++) // White-yellow fade
dest_colormap[starttranscolor + i] = (UINT8)(80 + (i-1)); dest_colormap[starttranscolor + i] = (UINT8)(80 + (i-1));
for (; i < 6; i++) // Yellow for (; i < 6; i++) // Yellow
dest_colormap[starttranscolor + i] = (UINT8)(83); dest_colormap[starttranscolor + i] = (UINT8)83;
for (; i < 8; i++) // Yellow for (; i < 8; i++) // Yellow
dest_colormap[starttranscolor + i] = (UINT8)(72); dest_colormap[starttranscolor + i] = (UINT8)72;
for (; i < 14; i++) // Yellow for (; i < 14; i++) // Yellow
dest_colormap[starttranscolor + i] = (UINT8)(73); dest_colormap[starttranscolor + i] = (UINT8)73;
for (; i < 16; i++) // With a fine golden finish! :3 for (; i < 16; i++) // With a fine golden finish! :3
dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-14)); dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-14));
break; break;
case SKINCOLOR_SUPER3: case SKINCOLOR_SUPERGOLD3:
// Super Yellow
for (i = 0; i < 2; i++) // White-yellow fade for (i = 0; i < 2; i++) // White-yellow fade
dest_colormap[starttranscolor + i] = (UINT8)(81 + i); dest_colormap[starttranscolor + i] = (UINT8)(81 + i);
for (; i < 4; i++) for (; i < 4; i++)
dest_colormap[starttranscolor + i] = (UINT8)(83); dest_colormap[starttranscolor + i] = (UINT8)83;
for (; i < 6; i++) // Yellow for (; i < 6; i++) // Yellow
dest_colormap[starttranscolor + i] = (UINT8)(72); dest_colormap[starttranscolor + i] = (UINT8)72;
for (; i < 12; i++) // Yellow for (; i < 12; i++) // Yellow
dest_colormap[starttranscolor + i] = (UINT8)(73); dest_colormap[starttranscolor + i] = (UINT8)73;
for (; i < 16; i++) // With a fine golden finish! :3 for (; i < 16; i++) // With a fine golden finish! :3
dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-12)); dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-12));
break; break;
case SKINCOLOR_SUPER4: case SKINCOLOR_SUPERGOLD4: // "The SSNTails"
// "The SSNTails" dest_colormap[starttranscolor] = (UINT8)83; // Golden shine
dest_colormap[starttranscolor] = 83; // Golden shine
for (i = 1; i < 3; i++) // Yellow for (i = 1; i < 3; i++) // Yellow
dest_colormap[starttranscolor + i] = (UINT8)(72); dest_colormap[starttranscolor + i] = (UINT8)(72);
for (; i < 9; i++) // Yellow for (; i < 9; i++) // Yellow
@ -620,30 +771,310 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-9)); dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-9));
break; break;
case SKINCOLOR_SUPER5: case SKINCOLOR_SUPERGOLD5: // Golden Delicious
// Golden Delicious
for (i = 0; i < 2; i++) // Yellow for (i = 0; i < 2; i++) // Yellow
dest_colormap[starttranscolor + i] = (UINT8)(72); dest_colormap[starttranscolor + i] = (UINT8)(72);
for (; i < 8; i++) // Yellow for (; i < 8; i++) // Yellow
dest_colormap[starttranscolor + i] = (UINT8)(73); dest_colormap[starttranscolor + i] = (UINT8)(73);
for (; i < 15; i++) // With a fine golden finish! :3 for (; i < 16; i++) // With a fine golden finish! :3
dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-8)); dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-8));
dest_colormap[starttranscolor + 15] = (UINT8)63;
break; break;
// Super Tails and Knuckles, who really should be dummied out by now // Super peridots. (nyeheheheh)
case SKINCOLOR_TSUPER1: case SKINCOLOR_SUPERPERIDOT1:
case SKINCOLOR_TSUPER2: for (i = 0; i < 10; i++)
case SKINCOLOR_TSUPER3: dest_colormap[starttranscolor + i] = (UINT8)0;
case SKINCOLOR_TSUPER4: for (; i < 13; i++)
case SKINCOLOR_TSUPER5: dest_colormap[starttranscolor + i] = (UINT8)88;
case SKINCOLOR_KSUPER1: for (; i < 16; i++)
case SKINCOLOR_KSUPER2: dest_colormap[starttranscolor + i] = (UINT8)188;
case SKINCOLOR_KSUPER3: break;
case SKINCOLOR_KSUPER4:
case SKINCOLOR_KSUPER5: case SKINCOLOR_SUPERPERIDOT2:
for (i = 0; i < SKIN_RAMP_LENGTH; i++) dest_colormap[starttranscolor] = (UINT8)(0);
dest_colormap[starttranscolor + i] = 0xFF; for (i = 1; i < 4; i++)
dest_colormap[starttranscolor + i] = (UINT8)88;
for (; i < 8; i++)
dest_colormap[starttranscolor + i] = (UINT8)188;
for (; i < 14; i++)
dest_colormap[starttranscolor + i] = (UINT8)189;
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)190;
break;
case SKINCOLOR_SUPERPERIDOT3:
for (i = 0; i < 2; i++)
dest_colormap[starttranscolor + i] = (UINT8)88;
for (; i < 6; i++)
dest_colormap[starttranscolor + i] = (UINT8)188;
for (; i < 12; i++)
dest_colormap[starttranscolor + i] = (UINT8)189;
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(190 + ((i-12) >> 1));
break;
case SKINCOLOR_SUPERPERIDOT4:
dest_colormap[starttranscolor] = (UINT8)88;
for (i = 1; i < 3; i++)
dest_colormap[starttranscolor + i] = (UINT8)188;
for (; i < 9; i++)
dest_colormap[starttranscolor + i] = (UINT8)189;
for (; i < 13; i++)
dest_colormap[starttranscolor + i] = (UINT8)(190 + ((i-9) >> 1));
for (; i < 15; i++)
dest_colormap[starttranscolor + i] = (UINT8)94;
dest_colormap[starttranscolor + i] = (UINT8)95;
break;
case SKINCOLOR_SUPERPERIDOT5:
for (i = 0; i < 2; i++)
dest_colormap[starttranscolor + i] = (UINT8)188;
for (; i < 8; i++)
dest_colormap[starttranscolor + i] = (UINT8)189;
for (; i < 12; i++)
dest_colormap[starttranscolor + i] = (UINT8)(190 + ((i-8) >> 1));
for (; i < 14; i++)
dest_colormap[starttranscolor + i] = (UINT8)94;
dest_colormap[starttranscolor + (i++)] = (UINT8)95;
dest_colormap[starttranscolor + i] = (UINT8)119;
break;
// Super cyans.
case SKINCOLOR_SUPERCYAN1:
for (i = 0; i < 10; i++)
dest_colormap[starttranscolor + i] = (UINT8)0;
for (; i < 12; i++)
dest_colormap[starttranscolor + i] = (UINT8)128;
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(129 + (i-12));
break;
case SKINCOLOR_SUPERCYAN2:
dest_colormap[starttranscolor] = (UINT8)0;
for (i = 1; i < 4; i++)
dest_colormap[starttranscolor + i] = (UINT8)(128 + (i-1));
for (; i < 8; i++)
dest_colormap[starttranscolor + i] = (UINT8)(131 + ((i-4) >> 1));
for (; i < 14; i++)
dest_colormap[starttranscolor + i] = (UINT8)133;
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)134;
break;
case SKINCOLOR_SUPERCYAN3:
for (i = 0; i < 2; i++)
dest_colormap[starttranscolor + i] = (UINT8)(129 + i);
for (; i < 6; i++)
dest_colormap[starttranscolor + i] = (UINT8)(131 + ((i-2) >> 1));
for (; i < 12; i++)
dest_colormap[starttranscolor + i] = (UINT8)133;
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(134 + ((i-12) >> 1));
break;
case SKINCOLOR_SUPERCYAN4:
dest_colormap[starttranscolor] = (UINT8)131;
for (i = 1; i < 3; i++)
dest_colormap[starttranscolor + i] = (UINT8)132;
for (; i < 9; i++)
dest_colormap[starttranscolor + i] = (UINT8)133;
for (; i < 13; i++)
dest_colormap[starttranscolor + i] = (UINT8)(134 + ((i-9) >> 1));
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(136 + (i-13));
break;
case SKINCOLOR_SUPERCYAN5:
for (i = 0; i < 2; i++)
dest_colormap[starttranscolor + i] = (UINT8)132;
for (; i < 8; i++)
dest_colormap[starttranscolor + i] = (UINT8)133;
for (; i < 12; i++)
dest_colormap[starttranscolor + i] = (UINT8)(134 + ((i-8) >> 1));
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(136 + (i-12));
break;
// Super purples.
case SKINCOLOR_SUPERPURPLE1:
for (i = 0; i < 10; i++)
dest_colormap[starttranscolor + i] = (UINT8)0;
for (; i < 12; i++)
dest_colormap[starttranscolor + i] = (UINT8)144;
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(160 + (i-12));
break;
case SKINCOLOR_SUPERPURPLE2:
dest_colormap[starttranscolor] = (UINT8)0;
dest_colormap[starttranscolor + 1] = (UINT8)144;
for (i = 2; i < 4; i++)
dest_colormap[starttranscolor + i] = (UINT8)(160 + (i-2));
for (; i < 8; i++)
dest_colormap[starttranscolor + i] = (UINT8)(162 + ((i-4) >> 1));
for (; i < 14; i++)
dest_colormap[starttranscolor + i] = (UINT8)164;
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)165;
break;
case SKINCOLOR_SUPERPURPLE3:
for (i = 0; i < 2; i++)
dest_colormap[starttranscolor + i] = (UINT8)(160 + i);
for (; i < 6; i++)
dest_colormap[starttranscolor + i] = (UINT8)(162 + ((i-2) >> 1));
for (; i < 12; i++)
dest_colormap[starttranscolor + i] = (UINT8)164;
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(165 + ((i-12) >> 1));
break;
case SKINCOLOR_SUPERPURPLE4:
dest_colormap[starttranscolor] = (UINT8)162;
for (i = 1; i < 3; i++)
dest_colormap[starttranscolor + i] = (UINT8)163;
for (; i < 9; i++)
dest_colormap[starttranscolor + i] = (UINT8)164;
for (; i < 13; i++)
dest_colormap[starttranscolor + i] = (UINT8)(165 + ((i-9) >> 1));
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(167 + (i-13));
break;
case SKINCOLOR_SUPERPURPLE5:
for (i = 0; i < 2; i++)
dest_colormap[starttranscolor + i] = (UINT8)163;
for (; i < 8; i++)
dest_colormap[starttranscolor + i] = (UINT8)164;
for (; i < 12; i++)
dest_colormap[starttranscolor + i] = (UINT8)(165 + ((i-8) >> 1));
for (; i < 15; i++)
dest_colormap[starttranscolor + i] = (UINT8)(167 + (i-12));
dest_colormap[starttranscolor + i] = (UINT8)253;
break;
// Super rusts.
case SKINCOLOR_SUPERRUST1:
for (i = 0; i < 2; i++)
dest_colormap[starttranscolor + i] = (UINT8)0;
for (; i < 5; i++)
dest_colormap[starttranscolor + i] = (UINT8)208;
for (; i < 7; i++)
dest_colormap[starttranscolor + i] = (UINT8)48;
for (; i < 10; i++)
dest_colormap[starttranscolor + i] = (UINT8)(49 + (i-7));
for (; i < 12; i++)
dest_colormap[starttranscolor + i] = (UINT8)(55 + ((i-10)*3));
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(68 + (i-11));
break;
case SKINCOLOR_SUPERRUST2:
for (i = 0; i < 4; i++)
dest_colormap[starttranscolor + i] = (UINT8)48;
for (; i < 9; i++)
dest_colormap[starttranscolor + i] = (UINT8)(49 + (i-4));
for (; i < 11; i++)
dest_colormap[starttranscolor + i] = (UINT8)(56 + ((i-9)*2));
for (; i < 15; i++)
dest_colormap[starttranscolor + i] = (UINT8)(68 + (i-11));
dest_colormap[starttranscolor + i] = (UINT8)71;
break;
case SKINCOLOR_SUPERRUST3:
dest_colormap[starttranscolor] = (UINT8)49;
for (i = 1; i < 3; i++)
dest_colormap[starttranscolor + i] = (UINT8)50;
for (; i < 5; i++)
dest_colormap[starttranscolor + i] = (UINT8)(51 + (i-3));
for (; i < 8; i++)
dest_colormap[starttranscolor + i] = (UINT8)(54 + (i-5));
dest_colormap[starttranscolor + (i++)] = (UINT8)58;
for (; i < 15; i++)
dest_colormap[starttranscolor + i] = (UINT8)(68 + ((i-7) >> 1));
dest_colormap[starttranscolor + i] = (UINT8)46;
break;
case SKINCOLOR_SUPERRUST4:
dest_colormap[starttranscolor] = (UINT8)83;
dest_colormap[starttranscolor + 1] = (UINT8)72;
for (i = 2; i < 6; i++)
dest_colormap[starttranscolor + i] = (UINT8)(64 + (i-2));
for (; i < 14; i++)
dest_colormap[starttranscolor + i] = (UINT8)(68 + ((i-6) >> 1));
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)46;
break;
case SKINCOLOR_SUPERRUST5:
for (i = 0; i < 3; i++)
dest_colormap[starttranscolor + i] = (UINT8)(64 + i);
for (; i < 7; i++)
dest_colormap[starttranscolor + i] = (UINT8)(67 + ((i-3) >> 1));
for (; i < 12; i++)
dest_colormap[starttranscolor + i] = (UINT8)(233 + (i-7));
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(238 + ((i-12) >> 1));
break;
// Super tans.
case SKINCOLOR_SUPERTAN1:
for (i = 0; i < 10; i++)
dest_colormap[starttranscolor + i] = (UINT8)0;
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(80 + ((i-10) >> 1));
break;
case SKINCOLOR_SUPERTAN2:
dest_colormap[starttranscolor] = (UINT8)0;
for (i = 1; i < 7; i++)
dest_colormap[starttranscolor + i] = (UINT8)(80 + ((i-1) >> 1));
dest_colormap[starttranscolor + (i++)] = (UINT8)82;
for (; i < 12; i++)
dest_colormap[starttranscolor + i] = (UINT8)84;
for (; i < 15; i++)
dest_colormap[starttranscolor + i] = (UINT8)(85 + (i-12));
dest_colormap[starttranscolor + i] = (UINT8)245;
break;
case SKINCOLOR_SUPERTAN3:
dest_colormap[starttranscolor] = (UINT8)80;
for (i = 1; i < 5; i++)
dest_colormap[starttranscolor + i] = (UINT8)(81 + ((i-1) >> 1));
dest_colormap[starttranscolor + (i++)] = (UINT8)82;
for (; i < 10; i++)
dest_colormap[starttranscolor + i] = (UINT8)84;
for (; i < 13; i++)
dest_colormap[starttranscolor + i] = (UINT8)(85 + (i-10));
for (; i < 16; i++)
dest_colormap[starttranscolor + i] = (UINT8)(245 + ((i-13)*2));
break;
case SKINCOLOR_SUPERTAN4:
dest_colormap[starttranscolor] = (UINT8)81;
for (i = 1; i < 5; i++)
dest_colormap[starttranscolor + i] = (UINT8)82;
for (; i < 8; i++)
dest_colormap[starttranscolor + i] = (UINT8)84;
for (; i < 11; i++)
dest_colormap[starttranscolor + i] = (UINT8)(85 + (i-8));
for (; i < 15; i++)
dest_colormap[starttranscolor + i] = (UINT8)(245 + ((i-11)*2));
dest_colormap[starttranscolor + i] = (UINT8)237;
break;
case SKINCOLOR_SUPERTAN5:
for (i = 0; i < 2; i++)
dest_colormap[starttranscolor + i] = (UINT8)82;
for (; i < 5; i++)
dest_colormap[starttranscolor + i] = (UINT8)84;
for (; i < 8; i++)
dest_colormap[starttranscolor + i] = (UINT8)(85 + (i-5));
for (; i < 12; i++)
dest_colormap[starttranscolor + i] = (UINT8)(245 + (i-8));
for (; i < 15; i++)
dest_colormap[starttranscolor + i] = (UINT8)(237 + (i-12));
dest_colormap[starttranscolor + i] = (UINT8)239;
break; break;
default: default:
@ -727,6 +1158,17 @@ UINT8 R_GetColorByName(const char *name)
return 0; return 0;
} }
UINT8 R_GetSuperColorByName(const char *name)
{
UINT8 color; /* = (UINT8)atoi(name); -- This isn't relevant to S_SKIN, which is the only way it's accessible right now. Let's simplify things.
if (color > MAXSKINCOLORS && color < MAXTRANSLATIONS && !((color - MAXSKINCOLORS) % 5))
return color;*/
for (color = 0; color < NUMSUPERCOLORS; color++)
if (!stricmp(Color_Names[color + MAXSKINCOLORS], name))
return ((color*5) + MAXSKINCOLORS);
return 0;
}
// ========================================================================== // ==========================================================================
// COMMON DRAWER FOR 8 AND 16 BIT COLOR MODES // COMMON DRAWER FOR 8 AND 16 BIT COLOR MODES
// ========================================================================== // ==========================================================================

View File

@ -111,6 +111,7 @@ void R_InitTranslationTables(void);
UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags); UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags);
void R_FlushTranslationColormapCache(void); void R_FlushTranslationColormapCache(void);
UINT8 R_GetColorByName(const char *name); UINT8 R_GetColorByName(const char *name);
UINT8 R_GetSuperColorByName(const char *name);
// Custom player skin translation // Custom player skin translation
void R_InitViewBuffer(INT32 width, INT32 height); void R_InitViewBuffer(INT32 width, INT32 height);

View File

@ -874,9 +874,9 @@ void R_DrawTiltedSplat_8(void)
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val != TRANSPARENTPIXEL) if (val != TRANSPARENTPIXEL)
*dest = val; *dest = colormap[val];
dest++; dest++;
iz += ds_sz.x; iz += ds_sz.x;
uz += ds_su.x; uz += ds_su.x;
@ -913,9 +913,9 @@ void R_DrawTiltedSplat_8(void)
for (i = SPANSIZE-1; i >= 0; i--) for (i = SPANSIZE-1; i >= 0; i--)
{ {
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val != TRANSPARENTPIXEL) if (val != TRANSPARENTPIXEL)
*dest = val; *dest = colormap[val];
dest++; dest++;
u += stepu; u += stepu;
v += stepv; v += stepv;
@ -931,9 +931,9 @@ void R_DrawTiltedSplat_8(void)
u = (INT64)(startu); u = (INT64)(startu);
v = (INT64)(startv); v = (INT64)(startv);
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val != TRANSPARENTPIXEL) if (val != TRANSPARENTPIXEL)
*dest = val; *dest = colormap[val];
} }
else else
{ {
@ -954,9 +954,9 @@ void R_DrawTiltedSplat_8(void)
for (; width != 0; width--) for (; width != 0; width--)
{ {
colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps);
val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val != TRANSPARENTPIXEL) if (val != TRANSPARENTPIXEL)
*dest = val; *dest = colormap[val];
dest++; dest++;
u += stepu; u += stepu;
v += stepv; v += stepv;
@ -1124,49 +1124,49 @@ void R_DrawTranslucentSplat_8 (void)
// need! // need!
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL) if (val != TRANSPARENTPIXEL)
dest[0] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[0])]; dest[0] = colormap[*(ds_transmap + (val << 8) + dest[0])];
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL) if (val != TRANSPARENTPIXEL)
dest[1] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[1])]; dest[1] = colormap[*(ds_transmap + (val << 8) + dest[1])];
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL) if (val != TRANSPARENTPIXEL)
dest[2] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[2])]; dest[2] = colormap[*(ds_transmap + (val << 8) + dest[2])];
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL) if (val != TRANSPARENTPIXEL)
dest[3] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[3])]; dest[3] = colormap[*(ds_transmap + (val << 8) + dest[3])];
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL) if (val != TRANSPARENTPIXEL)
dest[4] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[4])]; dest[4] = colormap[*(ds_transmap + (val << 8) + dest[4])];
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL) if (val != TRANSPARENTPIXEL)
dest[5] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[5])]; dest[5] = colormap[*(ds_transmap + (val << 8) + dest[5])];
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL) if (val != TRANSPARENTPIXEL)
dest[6] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[6])]; dest[6] = colormap[*(ds_transmap + (val << 8) + dest[6])];
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL) if (val != TRANSPARENTPIXEL)
dest[7] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + dest[7])]; dest[7] = colormap[*(ds_transmap + (val << 8) + dest[7])];
xposition += xstep; xposition += xstep;
yposition += ystep; yposition += ystep;
@ -1175,9 +1175,9 @@ void R_DrawTranslucentSplat_8 (void)
} }
while (count--) while (count--)
{ {
val =colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]]; val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)];
if (val != TRANSPARENTPIXEL) if (val != TRANSPARENTPIXEL)
*dest = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dest)]; *dest = colormap[*(ds_transmap + (val << 8) + *dest)];
dest++; dest++;
xposition += xstep; xposition += xstep;
@ -1363,7 +1363,19 @@ void R_DrawColumnShadowed_8(void)
height = dc_lightlist[i].height >> LIGHTSCALESHIFT; height = dc_lightlist[i].height >> LIGHTSCALESHIFT;
if (solid) if (solid)
{
bheight = dc_lightlist[i].botheight >> LIGHTSCALESHIFT; bheight = dc_lightlist[i].botheight >> LIGHTSCALESHIFT;
if (bheight < height)
{
// confounded slopes sometimes allow partial invertedness,
// even including cases where the top and bottom heights
// should actually be the same!
// swap the height values as a workaround for this quirk
INT32 temp = height;
height = bheight;
bheight = temp;
}
}
if (height <= dc_yl) if (height <= dc_yl)
{ {
dc_colormap = dc_lightlist[i].rcolormap; dc_colormap = dc_lightlist[i].rcolormap;

View File

@ -771,7 +771,7 @@ subsector_t *R_PointInSubsector(fixed_t x, fixed_t y)
} }
// //
// R_IsPointInSubsector, same as above but returns 0 if not in subsector // R_IsPointInSubsector, same as above but returns 0 if not in subsector - this does not work in opengl because of polyvertex_t
// //
subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y) subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y)
{ {
@ -919,9 +919,9 @@ void R_SkyboxFrame(player_t *player)
} }
} }
if (mh->skybox_scalez > 0) if (mh->skybox_scalez > 0)
viewz += player->awayviewmobj->z / mh->skybox_scalez; viewz += (player->awayviewmobj->z + 20*FRACUNIT) / mh->skybox_scalez;
else if (mh->skybox_scalez < 0) else if (mh->skybox_scalez < 0)
viewz += player->awayviewmobj->z * -mh->skybox_scalez; viewz += (player->awayviewmobj->z + 20*FRACUNIT) * -mh->skybox_scalez;
} }
else if (thiscam->chase) else if (thiscam->chase)
{ {
@ -966,9 +966,9 @@ void R_SkyboxFrame(player_t *player)
} }
} }
if (mh->skybox_scalez > 0) if (mh->skybox_scalez > 0)
viewz += thiscam->z / mh->skybox_scalez; viewz += (thiscam->z + (thiscam->height>>1)) / mh->skybox_scalez;
else if (mh->skybox_scalez < 0) else if (mh->skybox_scalez < 0)
viewz += thiscam->z * -mh->skybox_scalez; viewz += (thiscam->z + (thiscam->height>>1)) * -mh->skybox_scalez;
} }
else else
{ {

View File

@ -87,7 +87,7 @@ extern lighttable_t **planezlight;
extern fixed_t *yslope; extern fixed_t *yslope;
extern fixed_t distscale[MAXVIDWIDTH]; extern fixed_t distscale[MAXVIDWIDTH];
void R_InitPlanes(void); FUNCMATH void R_InitPlanes(void);
void R_PortalStoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale); void R_PortalStoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale);
void R_PortalRestoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale); void R_PortalRestoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor, fixed_t *scale);
void R_ClearPlanes(void); void R_ClearPlanes(void);

View File

@ -1453,34 +1453,45 @@ static void R_RenderSegLoop (void)
frontscale[rw_x] = rw_scale; frontscale[rw_x] = rw_scale;
// draw the wall tiers // draw the wall tiers
if (midtexture && yl <= yh && yh < vid.height && yh > 0) if (midtexture)
{ {
// single sided line // single sided line
dc_yl = yl; if (yl <= yh && yh >= 0 && yl < viewheight)
dc_yh = yh; {
dc_texturemid = rw_midtexturemid; dc_yl = yl;
dc_source = R_GetColumn(midtexture,texturecolumn); dc_yh = yh;
dc_texheight = textureheight[midtexture]>>FRACBITS; dc_texturemid = rw_midtexturemid;
dc_source = R_GetColumn(midtexture,texturecolumn);
dc_texheight = textureheight[midtexture]>>FRACBITS;
//profile stuff --------------------------------------------------------- //profile stuff ---------------------------------------------------------
#ifdef TIMING #ifdef TIMING
ProfZeroTimer(); ProfZeroTimer();
#endif #endif
colfunc(); colfunc();
#ifdef TIMING #ifdef TIMING
RDMSR(0x10,&mycount); RDMSR(0x10,&mycount);
mytotal += mycount; //64bit add mytotal += mycount; //64bit add
if (nombre--==0) if (nombre--==0)
I_Error("R_DrawColumn CPU Spy reports: 0x%d %d\n", *((INT32 *)&mytotal+1), I_Error("R_DrawColumn CPU Spy reports: 0x%d %d\n", *((INT32 *)&mytotal+1),
(INT32)mytotal); (INT32)mytotal);
#endif #endif
//profile stuff --------------------------------------------------------- //profile stuff ---------------------------------------------------------
// dont draw anything more for this column, since // dont draw anything more for this column, since
// a midtexture blocks the view // a midtexture blocks the view
ceilingclip[rw_x] = (INT16)viewheight; ceilingclip[rw_x] = (INT16)viewheight;
floorclip[rw_x] = -1; floorclip[rw_x] = -1;
}
else
{
// note: don't use min/max macros, since casting from INT32 to INT16 is involved here
if (markceiling)
ceilingclip[rw_x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1;
if (markfloor)
floorclip[rw_x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight;
}
} }
else else
{ {
@ -1494,21 +1505,28 @@ static void R_RenderSegLoop (void)
if (mid >= floorclip[rw_x]) if (mid >= floorclip[rw_x])
mid = floorclip[rw_x]-1; mid = floorclip[rw_x]-1;
if (mid >= yl && yh < vid.height && yh > 0) if (mid >= yl) // back ceiling lower than front ceiling ?
{ {
dc_yl = yl; if (yl >= viewheight) // entirely off bottom of screen
dc_yh = mid; ceilingclip[rw_x] = (INT16)viewheight;
dc_texturemid = rw_toptexturemid; else if (mid >= 0) // safe to draw top texture
dc_source = R_GetColumn(toptexture,texturecolumn); {
dc_texheight = textureheight[toptexture]>>FRACBITS; dc_yl = yl;
colfunc(); dc_yh = mid;
ceilingclip[rw_x] = (INT16)mid; dc_texturemid = rw_toptexturemid;
dc_source = R_GetColumn(toptexture,texturecolumn);
dc_texheight = textureheight[toptexture]>>FRACBITS;
colfunc();
ceilingclip[rw_x] = (INT16)mid;
}
else // entirely off top of screen
ceilingclip[rw_x] = -1;
} }
else else
ceilingclip[rw_x] = (INT16)((INT16)yl - 1); ceilingclip[rw_x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1;
} }
else if (markceiling) // no top wall else if (markceiling) // no top wall
ceilingclip[rw_x] = (INT16)((INT16)yl - 1); ceilingclip[rw_x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1;
if (bottomtexture) if (bottomtexture)
{ {
@ -1520,22 +1538,29 @@ static void R_RenderSegLoop (void)
if (mid <= ceilingclip[rw_x]) if (mid <= ceilingclip[rw_x])
mid = ceilingclip[rw_x]+1; mid = ceilingclip[rw_x]+1;
if (mid <= yh && yh < vid.height && yh > 0) if (mid <= yh) // back floor higher than front floor ?
{ {
dc_yl = mid; if (yh < 0) // entirely off top of screen
dc_yh = yh; floorclip[rw_x] = -1;
dc_texturemid = rw_bottomtexturemid; else if (mid < viewheight) // safe to draw bottom texture
dc_source = R_GetColumn(bottomtexture, {
texturecolumn); dc_yl = mid;
dc_texheight = textureheight[bottomtexture]>>FRACBITS; dc_yh = yh;
colfunc(); dc_texturemid = rw_bottomtexturemid;
floorclip[rw_x] = (INT16)mid; dc_source = R_GetColumn(bottomtexture,
texturecolumn);
dc_texheight = textureheight[bottomtexture]>>FRACBITS;
colfunc();
floorclip[rw_x] = (INT16)mid;
}
else // entirely off bottom of screen
floorclip[rw_x] = (INT16)viewheight;
} }
else else
floorclip[rw_x] = (INT16)((INT16)yh + 1); floorclip[rw_x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight;
} }
else if (markfloor) // no bottom wall else if (markfloor) // no bottom wall
floorclip[rw_x] = (INT16)((INT16)yh + 1); floorclip[rw_x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight;
} }
if (maskedtexture || numthicksides) if (maskedtexture || numthicksides)
@ -1858,12 +1883,13 @@ void R_StoreWallRange(INT32 start, INT32 stop)
// a single sided line is terminal, so it must mark ends // a single sided line is terminal, so it must mark ends
markfloor = markceiling = true; markfloor = markceiling = true;
#ifdef ESLOPE #ifdef ESLOPE
if (!(linedef->flags & ML_EFFECT1)) { if (linedef->flags & ML_EFFECT2) {
if (linedef->flags & ML_DONTPEGBOTTOM) if (linedef->flags & ML_DONTPEGBOTTOM)
rw_midtexturemid = frontsector->floorheight + textureheight[sidedef->midtexture] - viewz; rw_midtexturemid = frontsector->floorheight + textureheight[sidedef->midtexture] - viewz;
else else
rw_midtexturemid = frontsector->ceilingheight; rw_midtexturemid = frontsector->ceilingheight - viewz;
} }
else
#endif #endif
if (linedef->flags & ML_DONTPEGBOTTOM) if (linedef->flags & ML_DONTPEGBOTTOM)
{ {
@ -2482,6 +2508,15 @@ void R_StoreWallRange(INT32 start, INT32 stop)
#ifdef ESLOPE #ifdef ESLOPE
maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0])
#ifdef POLYOBJECTS
if (curline->polyseg) { // use REAL front and back floors please, so midtexture rendering isn't mucked up
rw_midtextureslide = rw_midtexturebackslide = 0;
if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3))
rw_midtexturemid = rw_midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz;
else
rw_midtexturemid = rw_midtextureback = min(curline->frontsector->ceilingheight, curline->backsector->ceilingheight) - viewz;
} else
#endif
// Set midtexture starting height // Set midtexture starting height
if (linedef->flags & ML_EFFECT2) { // Ignore slopes when texturing if (linedef->flags & ML_EFFECT2) { // Ignore slopes when texturing
rw_midtextureslide = rw_midtexturebackslide = 0; rw_midtextureslide = rw_midtexturebackslide = 0;

View File

@ -63,7 +63,11 @@ typedef struct floorsplat_s
fixed_t P_SegLength(seg_t *seg); fixed_t P_SegLength(seg_t *seg);
// call at P_SetupLevel() // call at P_SetupLevel()
#if !(defined (WALLSPLATS) || defined (FLOORSPLATS))
FUNCMATH void R_ClearLevelSplats(void);
#else
void R_ClearLevelSplats(void); void R_ClearLevelSplats(void);
#endif
#ifdef WALLSPLATS #ifdef WALLSPLATS
void R_AddWallSplat(line_t *wallline, INT16 sectorside, const char *patchname, fixed_t top, void R_AddWallSplat(line_t *wallline, INT16 sectorside, const char *patchname, fixed_t top,

View File

@ -18,6 +18,7 @@
#include "st_stuff.h" #include "st_stuff.h"
#include "w_wad.h" #include "w_wad.h"
#include "z_zone.h" #include "z_zone.h"
#include "m_menu.h" // character select
#include "m_misc.h" #include "m_misc.h"
#include "i_video.h" // rendermode #include "i_video.h" // rendermode
#include "r_things.h" #include "r_things.h"
@ -28,6 +29,7 @@
#include "dehacked.h" // get_number (for thok) #include "dehacked.h" // get_number (for thok)
#include "d_netfil.h" // blargh. for nameonly(). #include "d_netfil.h" // blargh. for nameonly().
#include "m_cheat.h" // objectplace #include "m_cheat.h" // objectplace
#include "m_cond.h"
#ifdef HWRENDER #ifdef HWRENDER
#include "hardware/hw_md2.h" #include "hardware/hw_md2.h"
#endif #endif
@ -100,7 +102,7 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
lumppat <<= 16; lumppat <<= 16;
lumppat += lump; lumppat += lump;
if (frame >= 64 || rotation > 8) if (frame >= 64 || !(R_ValidSpriteAngle(rotation)))
I_Error("R_InstallSpriteLump: Bad frame characters in lump %s", W_CheckNameForNum(lumppat)); I_Error("R_InstallSpriteLump: Bad frame characters in lump %s", W_CheckNameForNum(lumppat));
if (maxframe ==(size_t)-1 || frame > maxframe) if (maxframe ==(size_t)-1 || frame > maxframe)
@ -109,31 +111,72 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch
if (rotation == 0) if (rotation == 0)
{ {
// the lump should be used for all rotations // the lump should be used for all rotations
if (sprtemp[frame].rotate == 0) if (sprtemp[frame].rotate == SRF_SINGLE)
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple rot = 0 lump\n", spritename, cn); CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple rot = 0 lump\n", spritename, cn);
else if (sprtemp[frame].rotate != SRF_NONE) // Let's bundle 1-8 and L/R rotations into one debug message.
if (sprtemp[frame].rotate == 1)
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has rotations and a rot = 0 lump\n", spritename, cn); CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has rotations and a rot = 0 lump\n", spritename, cn);
sprtemp[frame].rotate = 0; sprtemp[frame].rotate = SRF_SINGLE;
for (r = 0; r < 8; r++) for (r = 0; r < 8; r++)
{ {
sprtemp[frame].lumppat[r] = lumppat; sprtemp[frame].lumppat[r] = lumppat;
sprtemp[frame].lumpid[r] = lumpid; sprtemp[frame].lumpid[r] = lumpid;
} }
sprtemp[frame].flip = flipped ? UINT8_MAX : 0; sprtemp[frame].flip = flipped ? 0xFF : 0; // 11111111 in binary
return;
}
if (rotation == ROT_L || rotation == ROT_R)
{
UINT8 rightfactor = ((rotation == ROT_R) ? 4 : 0);
// the lump should be used for half of all rotations
if (sprtemp[frame].rotate == SRF_SINGLE)
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has L/R rotations and a rot = 0 lump\n", spritename, cn);
else if (sprtemp[frame].rotate == SRF_3D)
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has both L/R and 1-8 rotations\n", spritename, cn);
else if ((sprtemp[frame].rotate & SRF_LEFT) && (rotation == ROT_L))
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple L rotations\n", spritename, cn);
else if ((sprtemp[frame].rotate & SRF_RIGHT) && (rotation == ROT_R))
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple R rotations\n", spritename, cn);
if (sprtemp[frame].rotate == SRF_NONE)
sprtemp[frame].rotate = SRF_SINGLE;
sprtemp[frame].rotate |= ((rotation == ROT_R) ? SRF_RIGHT : SRF_LEFT);
if (sprtemp[frame].rotate == (SRF_3D|SRF_2D))
sprtemp[frame].rotate = SRF_2D; // SRF_3D|SRF_2D being enabled at the same time doesn't HURT in the current sprite angle implementation, but it DOES mean more to check in some of the helper functions. Let's not allow this scenario to happen.
for (r = 0; r < 4; r++) // Thanks to R_PrecacheLevel, we can't leave sprtemp[*].lumppat[*] == LUMPERROR... so we load into the front/back angle too.
{
sprtemp[frame].lumppat[r + rightfactor] = lumppat;
sprtemp[frame].lumpid[r + rightfactor] = lumpid;
}
if (flipped)
sprtemp[frame].flip |= (0x0F<<rightfactor); // 00001111 or 11110000 in binary, depending on rotation being ROT_L or ROT_R
else
sprtemp[frame].flip &= ~(0x0F<<rightfactor); // ditto
return; return;
} }
// the lump is only used for one rotation // the lump is only used for one rotation
if (sprtemp[frame].rotate == 0) if (sprtemp[frame].rotate == SRF_SINGLE)
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has rotations and a rot = 0 lump\n", spritename, cn); CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has 1-8 rotations and a rot = 0 lump\n", spritename, cn);
else if ((sprtemp[frame].rotate != SRF_3D) && (sprtemp[frame].rotate != SRF_NONE))
sprtemp[frame].rotate = 1; CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has both L/R and 1-8 rotations\n", spritename, cn);
// make 0 based // make 0 based
rotation--; rotation--;
if (rotation == 0 || rotation == 4) // Front or back...
sprtemp[frame].rotate = SRF_3D; // Prevent L and R changeover
else if (rotation > 3) // Right side
sprtemp[frame].rotate = (SRF_3D | (sprtemp[frame].rotate & SRF_LEFT)); // Continue allowing L frame changeover
else // if (rotation <= 3) // Left side
sprtemp[frame].rotate = (SRF_3D | (sprtemp[frame].rotate & SRF_RIGHT)); // Continue allowing R frame changeover
if (sprtemp[frame].lumppat[rotation] != LUMPERROR) if (sprtemp[frame].lumppat[rotation] != LUMPERROR)
CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s: %c%c has two lumps mapped to it\n", spritename, cn, '1'+rotation); CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s: %c%c has two lumps mapped to it\n", spritename, cn, '1'+rotation);
@ -195,7 +238,7 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef,
frame = R_Char2Frame(lumpinfo[l].name[4]); frame = R_Char2Frame(lumpinfo[l].name[4]);
rotation = (UINT8)(lumpinfo[l].name[5] - '0'); rotation = (UINT8)(lumpinfo[l].name[5] - '0');
if (frame >= 64 || rotation > 8) // Give an actual NAME error -_-... if (frame >= 64 || !(R_ValidSpriteAngle(rotation))) // Give an actual NAME error -_-...
{ {
CONS_Alert(CONS_WARNING, M_GetText("Bad sprite name: %s\n"), W_CheckNameForNumPwad(wadnum,l)); CONS_Alert(CONS_WARNING, M_GetText("Bad sprite name: %s\n"), W_CheckNameForNumPwad(wadnum,l));
continue; continue;
@ -278,22 +321,29 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef,
{ {
switch (sprtemp[frame].rotate) switch (sprtemp[frame].rotate)
{ {
case 0xff: case SRF_NONE:
// no rotations were found for that frame at all // no rotations were found for that frame at all
I_Error("R_AddSingleSpriteDef: No patches found for %s frame %c", sprname, R_Frame2Char(frame)); I_Error("R_AddSingleSpriteDef: No patches found for %.4s frame %c", sprname, R_Frame2Char(frame));
break; break;
case 0: case SRF_SINGLE:
// only the first rotation is needed // only the first rotation is needed
break; break;
case 1: case SRF_2D: // both Left and Right rotations
// we test to see whether the left and right slots are present
if ((sprtemp[frame].lumppat[2] == LUMPERROR) || (sprtemp[frame].lumppat[6] == LUMPERROR))
I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations",
sprname, R_Frame2Char(frame));
break;
default:
// must have all 8 frames // must have all 8 frames
for (rotation = 0; rotation < 8; rotation++) for (rotation = 0; rotation < 8; rotation++)
// we test the patch lump, or the id lump whatever // we test the patch lump, or the id lump whatever
// if it was not loaded the two are LUMPERROR // if it was not loaded the two are LUMPERROR
if (sprtemp[frame].lumppat[rotation] == LUMPERROR) if (sprtemp[frame].lumppat[rotation] == LUMPERROR)
I_Error("R_AddSingleSpriteDef: Sprite %s frame %c is missing rotations", I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations",
sprname, R_Frame2Char(frame)); sprname, R_Frame2Char(frame));
break; break;
} }
@ -1138,22 +1188,29 @@ static void R_ProjectSprite(mobj_t *thing)
I_Error("R_ProjectSprite: sprframes NULL for sprite %d\n", thing->sprite); I_Error("R_ProjectSprite: sprframes NULL for sprite %d\n", thing->sprite);
#endif #endif
if (sprframe->rotate) if (sprframe->rotate == SRF_SINGLE)
{
// choose a different rotation based on player view
ang = R_PointToAngle (thing->x, thing->y);
rot = (ang-thing->angle+ANGLE_202h)>>29;
//Fab: lumpid is the index for spritewidth,spriteoffset... tables
lump = sprframe->lumpid[rot];
flip = sprframe->flip & (1<<rot);
}
else
{ {
// use single rotation for all views // use single rotation for all views
rot = 0; //Fab: for vis->patch below rot = 0; //Fab: for vis->patch below
lump = sprframe->lumpid[0]; //Fab: see note above lump = sprframe->lumpid[0]; //Fab: see note above
flip = sprframe->flip; // Will only be 0x00 or 0xFF flip = sprframe->flip; // Will only be 0x00 or 0xFF
} }
else
{
// choose a different rotation based on player view
ang = R_PointToAngle (thing->x, thing->y) - thing->angle;
if ((sprframe->rotate & SRF_RIGHT) && (ang < ANGLE_180)) // See from right
rot = 6; // F7 slot
else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left
rot = 2; // F3 slot
else // Normal behaviour
rot = (ang+ANGLE_202h)>>29;
//Fab: lumpid is the index for spritewidth,spriteoffset... tables
lump = sprframe->lumpid[rot];
flip = sprframe->flip & (1<<rot);
}
I_Assert(lump < max_spritelumps); I_Assert(lump < max_spritelumps);
@ -1643,7 +1700,8 @@ void R_SortVisSprites(void)
// Fix first and last. ds still points to the last one after the loop // Fix first and last. ds still points to the last one after the loop
dsfirst->prev = &unsorted; dsfirst->prev = &unsorted;
unsorted.next = dsfirst; unsorted.next = dsfirst;
ds->next = &unsorted; if (ds)
ds->next = &unsorted;
unsorted.prev = ds; unsorted.prev = ds;
// pull the vissprites out by scale // pull the vissprites out by scale
@ -2285,6 +2343,8 @@ static void Sk_SetDefaultValue(skin_t *skin)
skin->starttranscolor = 96; skin->starttranscolor = 96;
skin->prefcolor = SKINCOLOR_GREEN; skin->prefcolor = SKINCOLOR_GREEN;
skin->supercolor = SKINCOLOR_SUPERGOLD1;
skin->prefoppositecolor = 0; // use tables
skin->normalspeed = 36<<FRACBITS; skin->normalspeed = 36<<FRACBITS;
skin->runspeed = 28<<FRACBITS; skin->runspeed = 28<<FRACBITS;
@ -2297,7 +2357,14 @@ static void Sk_SetDefaultValue(skin_t *skin)
skin->jumpfactor = FRACUNIT; skin->jumpfactor = FRACUNIT;
skin->actionspd = 30<<FRACBITS; skin->actionspd = 30<<FRACBITS;
skin->mindash = 15<<FRACBITS; skin->mindash = 15<<FRACBITS;
skin->maxdash = 90<<FRACBITS; skin->maxdash = 70<<FRACBITS;
skin->radius = mobjinfo[MT_PLAYER].radius;
skin->height = mobjinfo[MT_PLAYER].height;
skin->spinheight = FixedMul(skin->height, 2*FRACUNIT/3);
skin->shieldscale = FRACUNIT;
skin->camerascale = FRACUNIT;
skin->thokitem = -1; skin->thokitem = -1;
skin->spinitem = -1; skin->spinitem = -1;
@ -2305,6 +2372,8 @@ static void Sk_SetDefaultValue(skin_t *skin)
skin->highresscale = FRACUNIT>>1; skin->highresscale = FRACUNIT>>1;
skin->availability = 0;
for (i = 0; i < sfx_skinsoundslot0; i++) for (i = 0; i < sfx_skinsoundslot0; i++)
if (S_sfx[i].skinsound != -1) if (S_sfx[i].skinsound != -1)
skin->soundsid[S_sfx[i].skinsound] = i; skin->soundsid[S_sfx[i].skinsound] = i;
@ -2329,6 +2398,19 @@ void R_InitSkins(void)
numskins = 0; numskins = 0;
} }
// returns true if available in circumstances, otherwise nope
// warning don't use with an invalid skinnum other than -1 which always returns true
boolean R_SkinUnlock(INT32 skinnum)
{
return ((skinnum == -1) // Simplifies things elsewhere, since there's already plenty of checks for less-than-0...
|| (!skins[skinnum].availability)
|| (unlockables[skins[skinnum].availability - 1].unlocked)
|| (modeattacking) // If you have someone else's run you might as well take a look
|| (Playing() && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum)) // Force 1.
|| (netgame && !(server || adminplayer == consoleplayer) && (cv_forceskin.value == skinnum)) // Force 2.
);
}
// returns true if the skin name is found (loaded from pwad) // returns true if the skin name is found (loaded from pwad)
// warning return -1 if not found // warning return -1 if not found
INT32 R_SkinAvailable(const char *name) INT32 R_SkinAvailable(const char *name)
@ -2337,6 +2419,7 @@ INT32 R_SkinAvailable(const char *name)
for (i = 0; i < numskins; i++) for (i = 0; i < numskins; i++)
{ {
// search in the skin list
if (stricmp(skins[i].name,name)==0) if (stricmp(skins[i].name,name)==0)
return i; return i;
} }
@ -2346,17 +2429,13 @@ INT32 R_SkinAvailable(const char *name)
// network code calls this when a 'skin change' is received // network code calls this when a 'skin change' is received
void SetPlayerSkin(INT32 playernum, const char *skinname) void SetPlayerSkin(INT32 playernum, const char *skinname)
{ {
INT32 i; INT32 i = R_SkinAvailable(skinname);
player_t *player = &players[playernum]; player_t *player = &players[playernum];
for (i = 0; i < numskins; i++) if ((i != -1) && (!P_IsLocalPlayer(player) || R_SkinUnlock(i)))
{ {
// search in the skin list SetPlayerSkinByNum(playernum, i);
if (stricmp(skins[i].name, skinname) == 0) return;
{
SetPlayerSkinByNum(playernum, i);
return;
}
} }
if (P_IsLocalPlayer(player)) if (P_IsLocalPlayer(player))
@ -2373,12 +2452,15 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
{ {
player_t *player = &players[playernum]; player_t *player = &players[playernum];
skin_t *skin = &skins[skinnum]; skin_t *skin = &skins[skinnum];
UINT8 newcolor = 0;
if (skinnum >= 0 && skinnum < numskins) // Make sure it exists! if ((skinnum >= 0 && skinnum < numskins) // Make sure it exists!
&& (!P_IsLocalPlayer(player) || R_SkinUnlock(skinnum))) // ...but is it allowed? We must always allow external players to change skin. The server should vet that...
{ {
player->skin = skinnum; player->skin = skinnum;
if (player->mo)
player->mo->skin = skin; player->camerascale = skin->camerascale;
player->shieldscale = skin->shieldscale;
player->charability = (UINT8)skin->ability; player->charability = (UINT8)skin->ability;
player->charability2 = (UINT8)skin->ability2; player->charability2 = (UINT8)skin->ability2;
@ -2401,21 +2483,35 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
player->jumpfactor = skin->jumpfactor; player->jumpfactor = skin->jumpfactor;
player->height = skin->height;
player->spinheight = skin->spinheight;
if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback)) if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback))
{ {
if (playernum == consoleplayer) if (playernum == consoleplayer)
CV_StealthSetValue(&cv_playercolor, skin->prefcolor); CV_StealthSetValue(&cv_playercolor, skin->prefcolor);
else if (playernum == secondarydisplayplayer) else if (playernum == secondarydisplayplayer)
CV_StealthSetValue(&cv_playercolor2, skin->prefcolor); CV_StealthSetValue(&cv_playercolor2, skin->prefcolor);
player->skincolor = skin->prefcolor; player->skincolor = newcolor = skin->prefcolor;
if (player->mo)
player->mo->color = player->skincolor;
} }
if (player->mo) if (player->mo)
{
if ((player->pflags & PF_NIGHTSMODE) && (skin->sprites[SPR2_NGT0].numframes == 0)) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin.
{
skin = &skins[DEFAULTNIGHTSSKIN];
newcolor = ((skin->flags & SF_SUPER) ? skin->supercolor : skin->prefcolor);
}
player->mo->skin = skin;
if (newcolor)
player->mo->color = newcolor;
P_SetScale(player->mo, player->mo->scale); P_SetScale(player->mo, player->mo->scale);
player->mo->radius = FixedMul(skin->radius, player->mo->scale);
}
return; return;
} }
else if (skinnum >= 0 && skinnum < numskins)
skinnum = 255; // Cheeky emulation.
if (P_IsLocalPlayer(player)) if (P_IsLocalPlayer(player))
CONS_Alert(CONS_WARNING, M_GetText("Skin %d not found\n"), skinnum); CONS_Alert(CONS_WARNING, M_GetText("Skin %d not found\n"), skinnum);
@ -2510,15 +2606,12 @@ void R_AddSkins(UINT16 wadnum)
if (!stricmp(stoken, "name")) if (!stricmp(stoken, "name"))
{ {
// the skin name must uniquely identify a single skin INT32 skinnum = R_SkinAvailable(value);
// I'm lazy so if name is already used I leave the 'skin x' strlwr(value);
// default skin name set in Sk_SetDefaultValue if (skinnum == -1)
if (R_SkinAvailable(value) == -1)
{
STRBUFCPY(skin->name, value); STRBUFCPY(skin->name, value);
strlwr(skin->name); // the skin name must uniquely identify a single skin
} // if the name is already used I make the name 'namex'
// I'm not lazy, so if the name is already used I make the name 'namex'
// using the default skin name's number set above // using the default skin name's number set above
else else
{ {
@ -2529,11 +2622,9 @@ void R_AddSkins(UINT16 wadnum)
"%s%d", value, numskins); "%s%d", value, numskins);
value2[stringspace - 1] = '\0'; value2[stringspace - 1] = '\0';
if (R_SkinAvailable(value2) == -1) if (R_SkinAvailable(value2) == -1)
{ // I'm lazy so if NEW name is already used I leave the 'skin x'
STRBUFCPY(skin->name, // default skin name set in Sk_SetDefaultValue
value2); STRBUFCPY(skin->name, value2);
strlwr(skin->name);
}
Z_Free(value2); Z_Free(value2);
} }
@ -2601,13 +2692,18 @@ void R_AddSkins(UINT16 wadnum)
FULLPROCESS(revitem) FULLPROCESS(revitem)
#undef FULLPROCESS #undef FULLPROCESS
#define GETSPEED(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value)<<FRACBITS; #define GETFRACBITS(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value)<<FRACBITS;
GETSPEED(normalspeed) GETFRACBITS(normalspeed)
GETSPEED(runspeed) GETFRACBITS(runspeed)
GETSPEED(mindash)
GETSPEED(maxdash) GETFRACBITS(mindash)
GETSPEED(actionspd) GETFRACBITS(maxdash)
#undef GETSPEED GETFRACBITS(actionspd)
GETFRACBITS(radius)
GETFRACBITS(height)
GETFRACBITS(spinheight)
#undef GETFRACBITS
#define GETINT(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value); #define GETINT(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value);
GETINT(thrustfactor) GETINT(thrustfactor)
@ -2615,20 +2711,75 @@ void R_AddSkins(UINT16 wadnum)
GETINT(acceleration) GETINT(acceleration)
#undef GETINT #undef GETINT
else if (!stricmp(stoken, "availability"))
{
skin->availability = atoi(value);
if (skin->availability >= MAXUNLOCKABLES)
skin->availability = 0;
if (skin->availability)
STRBUFCPY(unlockables[skin->availability - 1].name, skin->realname);
}
// custom translation table // custom translation table
else if (!stricmp(stoken, "startcolor")) else if (!stricmp(stoken, "startcolor"))
skin->starttranscolor = atoi(value); skin->starttranscolor = atoi(value);
else if (!stricmp(stoken, "prefcolor")) #define GETSKINCOLOR(field) else if (!stricmp(stoken, #field)) skin->field = R_GetColorByName(value);
skin->prefcolor = R_GetColorByName(value); GETSKINCOLOR(prefcolor)
else if (!stricmp(stoken, "jumpfactor")) GETSKINCOLOR(prefoppositecolor)
skin->jumpfactor = FLOAT_TO_FIXED(atof(value)); #undef GETSKINCOLOR
else if (!stricmp(stoken, "highresscale")) else if (!stricmp(stoken, "supercolor"))
skin->highresscale = FLOAT_TO_FIXED(atof(value)); skin->supercolor = R_GetSuperColorByName(value);
else
#define GETFLOAT(field) else if (!stricmp(stoken, #field)) skin->field = FLOAT_TO_FIXED(atof(value));
GETFLOAT(jumpfactor)
GETFLOAT(highresscale)
GETFLOAT(shieldscale)
GETFLOAT(camerascale)
#undef GETFLOAT
#define GETFLAG(field) else if (!stricmp(stoken, #field)) { \
strupr(value); \
if (atoi(value) || value[0] == 'T' || value[0] == 'Y') \
skin->flags |= (SF_##field); \
else \
skin->flags &= ~(SF_##field); \
}
// parameters for individual character flags
// these are uppercase so they can be concatenated with SF_
// 1, true, yes are all valid values
GETFLAG(SUPER)
GETFLAG(SUPERANIMS)
GETFLAG(SUPERSPIN)
GETFLAG(HIRES)
GETFLAG(NOSKID)
GETFLAG(NOSPEEDADJUST)
GETFLAG(RUNONWATER)
GETFLAG(NOJUMPSPIN)
GETFLAG(NOJUMPDAMAGE)
GETFLAG(STOMPDAMAGE)
GETFLAG(MARIODAMAGE)
GETFLAG(MACHINE)
#undef GETFLAG
else // let's check if it's a sound, otherwise error out
{ {
INT32 found = false; boolean found = false;
sfxenum_t i; sfxenum_t i;
size_t stokenadjust;
// Remove the prefix. (We need to affect an adjusting variable so that we can print error messages if it's not actually a sound.)
if ((stoken[0] == 'D' || stoken[0] == 'd') && (stoken[1] == 'S' || stoken[1] == 's')) // DS*
stokenadjust = 2;
else // sfx_*
stokenadjust = 4;
// Remove the prefix. (We can affect this directly since we're not going to use it again.)
if ((value[0] == 'D' || value[0] == 'd') && (value[1] == 'S' || value[1] == 's')) // DS*
value += 2;
else // sfx_*
value += 4;
// copy name of sounds that are remapped // copy name of sounds that are remapped
// for this skin // for this skin
for (i = 0; i < sfx_skinsoundslot0; i++) for (i = 0; i < sfx_skinsoundslot0; i++)
@ -2637,15 +2788,15 @@ void R_AddSkins(UINT16 wadnum)
continue; continue;
if (S_sfx[i].skinsound != -1 if (S_sfx[i].skinsound != -1
&& !stricmp(S_sfx[i].name, && !stricmp(S_sfx[i].name,
stoken + 2)) stoken + stokenadjust))
{ {
skin->soundsid[S_sfx[i].skinsound] = skin->soundsid[S_sfx[i].skinsound] =
S_AddSoundFx(value+2, S_sfx[i].singularity, S_sfx[i].pitch, true); S_AddSoundFx(value, S_sfx[i].singularity, S_sfx[i].pitch, true);
found = true; found = true;
} }
} }
if (!found) if (!found)
CONS_Debug(DBG_SETUP, "R_AddSkins: Unknown keyword '%s' in S_SKIN lump# %d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename); CONS_Debug(DBG_SETUP, "R_AddSkins: Unknown keyword '%s' in S_SKIN lump #%d (WAD %s)\n", stoken, lump, wadfiles[wadnum]->filename);
} }
next_token: next_token:
stoken = strtok(NULL, "\r\n= "); stoken = strtok(NULL, "\r\n= ");
@ -2666,13 +2817,14 @@ next_token:
if (z < lastlump) lastlump = z; if (z < lastlump) lastlump = z;
// load all sprite sets we are aware of. // load all sprite sets we are aware of.
for (sprite2 = 0; sprite2 < NUMPLAYERSPRITES; sprite2++) for (sprite2 = 0; sprite2 < free_spr2; sprite2++)
R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[sprite2], wadnum, lump, lastlump); R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[sprite2], wadnum, lump, lastlump);
} }
R_FlushTranslationColormapCache(); R_FlushTranslationColormapCache();
CONS_Printf(M_GetText("Added skin '%s'\n"), skin->name); if (!skin->availability) // Safe to print...
CONS_Printf(M_GetText("Added skin '%s'\n"), skin->name);
#ifdef SKINVALUES #ifdef SKINVALUES
skin_cons_t[numskins].value = numskins; skin_cons_t[numskins].value = numskins;
skin_cons_t[numskins].strvalue = skin->name; skin_cons_t[numskins].strvalue = skin->name;

View File

@ -17,6 +17,10 @@
#include "sounds.h" #include "sounds.h"
#include "r_plane.h" #include "r_plane.h"
// "Left" and "Right" character symbols for additional rotation functionality
#define ROT_L ('L' - '0')
#define ROT_R ('R' - '0')
// number of sprite lumps for spritewidth,offset,topoffset lookup tables // number of sprite lumps for spritewidth,offset,topoffset lookup tables
// Fab: this is a hack : should allocate the lookup tables per sprite // Fab: this is a hack : should allocate the lookup tables per sprite
#define MAXVISSPRITES 2048 // added 2-2-98 was 128 #define MAXVISSPRITES 2048 // added 2-2-98 was 128
@ -25,6 +29,8 @@
#define VISSPRITESPERCHUNK (1 << VISSPRITECHUNKBITS) #define VISSPRITESPERCHUNK (1 << VISSPRITECHUNKBITS)
#define VISSPRITEINDEXMASK (VISSPRITESPERCHUNK - 1) #define VISSPRITEINDEXMASK (VISSPRITESPERCHUNK - 1)
#define DEFAULTNIGHTSSKIN 0
// Constant arrays used for psprite clipping // Constant arrays used for psprite clipping
// and initializing clipping. // and initializing clipping.
extern INT16 negonearray[MAXVIDWIDTH]; extern INT16 negonearray[MAXVIDWIDTH];
@ -93,15 +99,27 @@ typedef struct
fixed_t jumpfactor; // multiple of standard jump height fixed_t jumpfactor; // multiple of standard jump height
fixed_t radius; // Bounding box changes.
fixed_t height;
fixed_t spinheight;
fixed_t shieldscale; // no change to bounding box, but helps set the shield's sprite size
fixed_t camerascale;
// Definable color translation table // Definable color translation table
UINT8 starttranscolor; UINT8 starttranscolor;
UINT8 prefcolor; UINT8 prefcolor;
UINT8 supercolor;
UINT8 prefoppositecolor; // if 0 use tables instead
fixed_t highresscale; // scale of highres, default is 0.5 fixed_t highresscale; // scale of highres, default is 0.5
// specific sounds per skin // specific sounds per skin
sfxenum_t soundsid[NUMSKINSOUNDS]; // sound # in S_sfx table sfxenum_t soundsid[NUMSKINSOUNDS]; // sound # in S_sfx table
spritedef_t sprites[NUMPLAYERSPRITES]; spritedef_t sprites[NUMPLAYERSPRITES];
UINT8 availability; // lock?
} skin_t; } skin_t;
// ----------- // -----------
@ -184,6 +202,7 @@ extern skin_t skins[MAXSKINS + 1];
void SetPlayerSkin(INT32 playernum,const char *skinname); void SetPlayerSkin(INT32 playernum,const char *skinname);
void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002 void SetPlayerSkinByNum(INT32 playernum,INT32 skinnum); // Tails 03-16-2002
boolean R_SkinUnlock(INT32 skinnum);
INT32 R_SkinAvailable(const char *name); INT32 R_SkinAvailable(const char *name);
void R_AddSkins(UINT16 wadnum); void R_AddSkins(UINT16 wadnum);
@ -230,4 +249,9 @@ FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Frame(char cn)
#endif #endif
} }
FUNCMATH FUNCINLINE static ATTRINLINE boolean R_ValidSpriteAngle(UINT8 rotation)
{
return ((rotation <= 8) || (rotation == ROT_L) || (rotation == ROT_R));
}
#endif //__R_THINGS__ #endif //__R_THINGS__

View File

@ -119,7 +119,7 @@ void S_ResumeAudio(void);
// //
void S_UpdateSounds(void); void S_UpdateSounds(void);
fixed_t S_CalculateSoundDistance(fixed_t px1, fixed_t py1, fixed_t pz1, fixed_t px2, fixed_t py2, fixed_t pz2); FUNCMATH fixed_t S_CalculateSoundDistance(fixed_t px1, fixed_t py1, fixed_t pz1, fixed_t px2, fixed_t py2, fixed_t pz2);
void S_SetDigMusicVolume(INT32 volume); void S_SetDigMusicVolume(INT32 volume);
void S_SetMIDIMusicVolume(INT32 volume); void S_SetMIDIMusicVolume(INT32 volume);

View File

@ -69,6 +69,13 @@ consvar_t cv_scr_height = {"scr_height", "800", CV_SAVE, CV_Unsigned, NULL, 0, N
consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
#endif #endif
consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
#ifdef DIRECTFULLSCREEN
static FUNCMATH void SCR_ChangeFullscreen (void);
#else
static void SCR_ChangeFullscreen (void);
#endif
consvar_t cv_fullscreen = {"fullscreen", "Yes", CV_SAVE|CV_CALL, CV_YesNo, SCR_ChangeFullscreen, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_fullscreen = {"fullscreen", "Yes", CV_SAVE|CV_CALL, CV_YesNo, SCR_ChangeFullscreen, 0, NULL, NULL, 0, 0, NULL};
// ========================================================================= // =========================================================================

View File

@ -175,9 +175,7 @@ void SCR_SetDefaultMode (void);
void SCR_Startup (void); void SCR_Startup (void);
void SCR_ChangeFullscreen (void); FUNCMATH boolean SCR_IsAspectCorrect(INT32 width, INT32 height);
boolean SCR_IsAspectCorrect(INT32 width, INT32 height);
// move out to main code for consistency // move out to main code for consistency
void SCR_DisplayTicRate(void); void SCR_DisplayTicRate(void);

View File

@ -56,6 +56,15 @@ ifdef FREEBSD
LIBS+=-lipx -lkvm LIBS+=-lipx -lkvm
endif endif
#
#here is Mac OS X
#
ifdef MACOSX
OBJS+=$(OBJDIR)/mac_resources.o
OBJS+=$(OBJDIR)/mac_alert.o
LIBS+=-framework CoreFoundation
endif
# #
#here is GP2x (arm-gp2x-linux) #here is GP2x (arm-gp2x-linux)
# #

View File

@ -167,6 +167,7 @@
<ClInclude Include="..\lzf.h" /> <ClInclude Include="..\lzf.h" />
<ClInclude Include="..\md5.h" /> <ClInclude Include="..\md5.h" />
<ClInclude Include="..\mserv.h" /> <ClInclude Include="..\mserv.h" />
<ClInclude Include="..\m_aatree.h" />
<ClInclude Include="..\m_anigif.h" /> <ClInclude Include="..\m_anigif.h" />
<ClInclude Include="..\m_argv.h" /> <ClInclude Include="..\m_argv.h" />
<ClInclude Include="..\m_bbox.h" /> <ClInclude Include="..\m_bbox.h" />
@ -308,6 +309,7 @@
<ClCompile Include="..\lzf.c" /> <ClCompile Include="..\lzf.c" />
<ClCompile Include="..\md5.c" /> <ClCompile Include="..\md5.c" />
<ClCompile Include="..\mserv.c" /> <ClCompile Include="..\mserv.c" />
<ClCompile Include="..\m_aatree.c" />
<ClCompile Include="..\m_anigif.c" /> <ClCompile Include="..\m_anigif.c" />
<ClCompile Include="..\m_argv.c" /> <ClCompile Include="..\m_argv.c" />
<ClCompile Include="..\m_bbox.c" /> <ClCompile Include="..\m_bbox.c" />

View File

@ -294,6 +294,9 @@
<ClInclude Include="..\md5.h"> <ClInclude Include="..\md5.h">
<Filter>M_Misc</Filter> <Filter>M_Misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\m_aatree.h">
<Filter>M_Misc</Filter>
</ClInclude>
<ClInclude Include="..\m_anigif.h"> <ClInclude Include="..\m_anigif.h">
<Filter>M_Misc</Filter> <Filter>M_Misc</Filter>
</ClInclude> </ClInclude>
@ -666,6 +669,9 @@
<ClCompile Include="..\md5.c"> <ClCompile Include="..\md5.c">
<Filter>M_Misc</Filter> <Filter>M_Misc</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\m_aatree.c">
<Filter>M_Misc</Filter>
</ClCompile>
<ClCompile Include="..\m_anigif.c"> <ClCompile Include="..\m_anigif.c">
<Filter>M_Misc</Filter> <Filter>M_Misc</Filter>
</ClCompile> </ClCompile>

View File

@ -12,25 +12,25 @@ consvar_t cd_volume = {"cd_volume","31",CV_SAVE,soundvolume_cons_t, NULL, 0, NUL
consvar_t cdUpdate = {"cd_update","1",CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cdUpdate = {"cd_update","1",CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
void I_InitCD(void){} FUNCMATH void I_InitCD(void){}
void I_StopCD(void){} FUNCMATH void I_StopCD(void){}
void I_PauseCD(void){} FUNCMATH void I_PauseCD(void){}
void I_ResumeCD(void){} FUNCMATH void I_ResumeCD(void){}
void I_ShutdownCD(void){} FUNCMATH void I_ShutdownCD(void){}
void I_UpdateCD(void){} FUNCMATH void I_UpdateCD(void){}
void I_PlayCD(UINT8 track, UINT8 looping) FUNCMATH void I_PlayCD(UINT8 track, UINT8 looping)
{ {
(void)track; (void)track;
(void)looping; (void)looping;
} }
boolean I_SetVolumeCD(int volume) FUNCMATH boolean I_SetVolumeCD(int volume)
{ {
(void)volume; (void)volume;
return false; return false;

View File

@ -2049,14 +2049,14 @@ void I_StartupMouse2(void)
// //
// I_Tactile // I_Tactile
// //
void I_Tactile(FFType pFFType, const JoyFF_t *FFEffect) FUNCMATH void I_Tactile(FFType pFFType, const JoyFF_t *FFEffect)
{ {
// UNUSED. // UNUSED.
(void)pFFType; (void)pFFType;
(void)FFEffect; (void)FFEffect;
} }
void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect) FUNCMATH void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect)
{ {
// UNUSED. // UNUSED.
(void)pFFType; (void)pFFType;
@ -2067,7 +2067,7 @@ void I_Tactile2(FFType pFFType, const JoyFF_t *FFEffect)
*/ */
static ticcmd_t emptycmd; static ticcmd_t emptycmd;
ticcmd_t *I_BaseTiccmd(void) FUNCMATH ticcmd_t *I_BaseTiccmd(void)
{ {
return &emptycmd; return &emptycmd;
} }
@ -2076,7 +2076,7 @@ ticcmd_t *I_BaseTiccmd(void)
*/ */
static ticcmd_t emptycmd2; static ticcmd_t emptycmd2;
ticcmd_t *I_BaseTiccmd2(void) FUNCMATH ticcmd_t *I_BaseTiccmd2(void)
{ {
return &emptycmd2; return &emptycmd2;
} }
@ -2179,7 +2179,7 @@ tic_t I_GetTime (void)
// //
//I_StartupTimer //I_StartupTimer
// //
void I_StartupTimer(void) FUNCMATH void I_StartupTimer(void)
{ {
#if (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX) #if (defined (_WIN32) && !defined (_WIN32_WCE)) && !defined (_XBOX)
// for win2k time bug // for win2k time bug
@ -2313,11 +2313,11 @@ void I_WaitVBL(INT32 count)
SDL_Delay(count); SDL_Delay(count);
} }
void I_BeginRead(void) FUNCMATH void I_BeginRead(void)
{ {
} }
void I_EndRead(void) FUNCMATH void I_EndRead(void)
{ {
} }
@ -3067,5 +3067,5 @@ const CPUInfoFlags *I_CPUInfo(void)
} }
// note CPUAFFINITY code used to reside here // note CPUAFFINITY code used to reside here
void I_RegisterSysCommands(void) {} FUNCMATH void I_RegisterSysCommands(void) {}
#endif #endif

View File

@ -1346,7 +1346,7 @@ void I_SetPalette(RGBA_t *palette)
} }
// return number of fullscreen + X11 modes // return number of fullscreen + X11 modes
INT32 VID_NumModes(void) FUNCMATH INT32 VID_NumModes(void)
{ {
if (USE_FULLSCREEN && numVidModes != -1) if (USE_FULLSCREEN && numVidModes != -1)
return numVidModes - firstEntry; return numVidModes - firstEntry;
@ -1354,7 +1354,7 @@ INT32 VID_NumModes(void)
return MAXWINMODES; return MAXWINMODES;
} }
const char *VID_GetModeName(INT32 modeNum) FUNCMATH const char *VID_GetModeName(INT32 modeNum)
{ {
#if 0 #if 0
if (USE_FULLSCREEN && numVidModes != -1) // fullscreen modes if (USE_FULLSCREEN && numVidModes != -1) // fullscreen modes
@ -1384,7 +1384,7 @@ const char *VID_GetModeName(INT32 modeNum)
return &vidModeName[modeNum][0]; return &vidModeName[modeNum][0];
} }
INT32 VID_GetModeForSize(INT32 w, INT32 h) FUNCMATH INT32 VID_GetModeForSize(INT32 w, INT32 h)
{ {
int i; int i;
for (i = 0; i < MAXWINMODES; i++) for (i = 0; i < MAXWINMODES; i++)

View File

@ -25,19 +25,38 @@
#include "mac_alert.h" #include "mac_alert.h"
#include <CoreFoundation/CoreFoundation.h> #include <CoreFoundation/CoreFoundation.h>
#define CFSTRINGIFY(x) CFStringCreateWithCString(NULL, x, kCFStringEncodingASCII)
int MacShowAlert(const char *title, const char *message, const char *button1, const char *button2, const char *button3) int MacShowAlert(const char *title, const char *message, const char *button1, const char *button2, const char *button3)
{ {
CFOptionFlags results; CFOptionFlags results;
CFUserNotificationDisplayAlert(0, CFStringRef cf_title = CFSTRINGIFY(title);
kCFUserNotificationStopAlertLevel | kCFUserNotificationNoDefaultButtonFlag, CFStringRef cf_message = CFSTRINGIFY(message);
NULL, NULL, NULL, CFStringRef cf_button1 = NULL;
CFStringCreateWithCString(NULL, title, kCFStringEncodingASCII), CFStringRef cf_button2 = NULL;
CFStringCreateWithCString(NULL, message, kCFStringEncodingASCII), CFStringRef cf_button3 = NULL;
button1 != NULL ? CFStringCreateWithCString(NULL, button1, kCFStringEncodingASCII) : NULL,
button2 != NULL ? CFStringCreateWithCString(NULL, button2, kCFStringEncodingASCII) : NULL, if (button1 != NULL)
button3 != NULL ? CFStringCreateWithCString(NULL, button3, kCFStringEncodingASCII) : NULL, cf_button1 = CFSTRINGIFY(button1);
&results); if (button2 != NULL)
cf_button2 = CFSTRINGIFY(button2);
if (button3 != NULL)
cf_button3 = CFSTRINGIFY(button3);
CFOptionFlags alert_flags = kCFUserNotificationStopAlertLevel | kCFUserNotificationNoDefaultButtonFlag;
CFUserNotificationDisplayAlert(0, alert_flags, NULL, NULL, NULL, cf_title, cf_message,
cf_button1, cf_button2, cf_button3, &results);
if (cf_button1 != NULL)
CFRelease(cf_button1);
if (cf_button2 != NULL)
CFRelease(cf_button2);
if (cf_button3 != NULL)
CFRelease(cf_button3);
CFRelease(cf_message);
CFRelease(cf_title);
return (int)results; return (int)results;
} }

View File

@ -9,23 +9,29 @@ void OSX_GetResourcesPath(char * buffer)
mainBundle = CFBundleGetMainBundle(); mainBundle = CFBundleGetMainBundle();
if (mainBundle) if (mainBundle)
{ {
const int BUF_SIZE = 256; // because we somehow always know that
CFURLRef appUrlRef = CFBundleCopyBundleURL(mainBundle); CFURLRef appUrlRef = CFBundleCopyBundleURL(mainBundle);
CFStringRef macPath = CFURLCopyFileSystemPath(appUrlRef, kCFURLPOSIXPathStyle); CFStringRef macPath;
CFStringRef resources = CFStringCreateWithCString(kCFAllocatorMalloc, "/Contents/Resources", kCFStringEncodingASCII); if (appUrlRef != NULL)
const void* rawarray[2] = {macPath, resources}; macPath = CFURLCopyFileSystemPath(appUrlRef, kCFURLPOSIXPathStyle);
CFArrayRef array = CFArrayCreate(kCFAllocatorMalloc, rawarray, 2, NULL); else
CFStringRef separator = CFStringCreateWithCString(kCFAllocatorMalloc, "", kCFStringEncodingASCII); macPath = NULL;
CFStringRef fullPath = CFStringCreateByCombiningStrings(kCFAllocatorMalloc, array, separator);
const char * path = CFStringGetCStringPtr(fullPath, kCFStringEncodingASCII); const char* rawPath;
strcpy(buffer, path);
CFRelease(fullPath); if (macPath != NULL)
path = NULL; rawPath = CFStringGetCStringPtr(macPath, kCFStringEncodingASCII);
CFRelease(array); else
CFRelease(resources); rawPath = NULL;
if (rawPath != NULL && (CFStringGetLength(macPath) + strlen("/Contents/Resources") < BUF_SIZE))
{
strcpy(buffer, rawPath);
strcat(buffer, "/Contents/Resources");
}
CFRelease(macPath); CFRelease(macPath);
CFRelease(appUrlRef); CFRelease(appUrlRef);
//CFRelease(mainBundle);
CFRelease(separator);
} }
}
}

View File

@ -126,7 +126,7 @@ void I_ShutdownSound(void)
#endif #endif
} }
void I_UpdateSound(void) FUNCMATH void I_UpdateSound(void)
{ {
} }
@ -464,7 +464,7 @@ static void mix_gme(void *udata, Uint8 *stream, int len)
} }
#endif #endif
void I_InitMusic(void) FUNCMATH void I_InitMusic(void)
{ {
} }
@ -769,7 +769,7 @@ boolean I_SetSongTrack(int track)
// MIDI Music // MIDI Music
// //
void I_InitMIDIMusic(void) FUNCMATH void I_InitMIDIMusic(void)
{ {
} }

View File

@ -565,7 +565,7 @@ static void ST_drawDebugInfo(void)
{ {
V_DrawRightAlignedString(320, height - 104, V_MONOSPACE, va("SHIELD: %5x", stplyr->powers[pw_shield])); V_DrawRightAlignedString(320, height - 104, V_MONOSPACE, va("SHIELD: %5x", stplyr->powers[pw_shield]));
V_DrawRightAlignedString(320, height - 96, V_MONOSPACE, va("SCALE: %5d%%", (stplyr->mo->scale*100)/FRACUNIT)); V_DrawRightAlignedString(320, height - 96, V_MONOSPACE, va("SCALE: %5d%%", (stplyr->mo->scale*100)/FRACUNIT));
V_DrawRightAlignedString(320, height - 88, V_MONOSPACE, va("DASH: %3d/%3d", stplyr->dashspeed>>FRACBITS, FixedMul(stplyr->maxdash,stplyr->mo->scale)>>FRACBITS)); V_DrawRightAlignedString(320, height - 88, V_MONOSPACE, va("DASH: %3d/%3d", stplyr->dashspeed>>FRACBITS, stplyr->maxdash>>FRACBITS));
V_DrawRightAlignedString(320, height - 80, V_MONOSPACE, va("AIR: %4d, %3d", stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime])); V_DrawRightAlignedString(320, height - 80, V_MONOSPACE, va("AIR: %4d, %3d", stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime]));
// Flags // Flags
@ -890,11 +890,19 @@ static void ST_drawFirstPersonHUD(void)
V_NOSCALESTART|V_OFFSET|V_TRANSLUCENT, p); V_NOSCALESTART|V_OFFSET|V_TRANSLUCENT, p);
} }
// [21:42] <+Rob> Beige - Lavender - Steel Blue - Peach - Orange - Purple - Silver - Yellow - Pink - Red - Blue - Green - Cyan - Gold // 2.0-1: [21:42] <+Rob> Beige - Lavender - Steel Blue - Peach - Orange - Purple - Silver - Yellow - Pink - Red - Blue - Green - Cyan - Gold
static skincolors_t linkColor[14] = /*#define NUMLINKCOLORS 14
static skincolors_t linkColor[NUMLINKCOLORS] =
{SKINCOLOR_BEIGE, SKINCOLOR_LAVENDER, SKINCOLOR_AZURE, SKINCOLOR_PEACH, SKINCOLOR_ORANGE, {SKINCOLOR_BEIGE, SKINCOLOR_LAVENDER, SKINCOLOR_AZURE, SKINCOLOR_PEACH, SKINCOLOR_ORANGE,
SKINCOLOR_MAGENTA, SKINCOLOR_SILVER, SKINCOLOR_SUPER4, SKINCOLOR_PINK, SKINCOLOR_RED, SKINCOLOR_MAGENTA, SKINCOLOR_SILVER, SKINCOLOR_SUPERGOLD4, SKINCOLOR_PINK, SKINCOLOR_RED,
SKINCOLOR_BLUE, SKINCOLOR_GREEN, SKINCOLOR_CYAN, SKINCOLOR_GOLD}; SKINCOLOR_BLUE, SKINCOLOR_GREEN, SKINCOLOR_CYAN, SKINCOLOR_GOLD};*/
// 2.2+: (unix time 1470866042) <Rob> Emerald, Aqua, Cyan, Blue, Pastel, Purple, Magenta, Rosy, Red, Orange, Gold, Yellow, Peridot
#define NUMLINKCOLORS 13
static skincolors_t linkColor[NUMLINKCOLORS] =
{SKINCOLOR_EMERALD, SKINCOLOR_AQUA, SKINCOLOR_CYAN, SKINCOLOR_BLUE, SKINCOLOR_PASTEL,
SKINCOLOR_PURPLE, SKINCOLOR_MAGENTA, SKINCOLOR_ROSY, SKINCOLOR_RED, SKINCOLOR_ORANGE,
SKINCOLOR_GOLD, SKINCOLOR_YELLOW, SKINCOLOR_PERIDOT};
static void ST_drawNightsRecords(void) static void ST_drawNightsRecords(void)
{ {
@ -974,7 +982,7 @@ static void ST_drawNiGHTSHUD(void)
if (cv_debug & DBG_NIGHTSBASIC) if (cv_debug & DBG_NIGHTSBASIC)
minlink = 0; minlink = 0;
// Cheap hack: don't display when the score is showing // Cheap hack: don't display when the score is showing (it popping up for a split second when exiting a map is intentional)
if (stplyr->texttimer && stplyr->textvar == 4) if (stplyr->texttimer && stplyr->textvar == 4)
minlink = INT32_MAX; minlink = INT32_MAX;
@ -994,7 +1002,7 @@ static void ST_drawNiGHTSHUD(void)
#endif #endif
stplyr->linkcount > minlink) stplyr->linkcount > minlink)
{ {
skincolors_t colornum = linkColor[((stplyr->linkcount-1) / 5) % (sizeof(linkColor) / sizeof(skincolors_t))]; skincolors_t colornum = linkColor[((stplyr->linkcount-1) / 5) % NUMLINKCOLORS];
if (stplyr->powers[pw_nights_linkfreeze]) if (stplyr->powers[pw_nights_linkfreeze])
colornum = SKINCOLOR_WHITE; colornum = SKINCOLOR_WHITE;
@ -1299,7 +1307,7 @@ static void ST_drawNiGHTSHUD(void)
nightsnum, SKINCOLOR_RED); nightsnum, SKINCOLOR_RED);
else else
ST_DrawNightsOverlayNum(160 + numbersize, STRINGY(12), SPLITFLAGS(V_SNAPTOTOP), realnightstime, ST_DrawNightsOverlayNum(160 + numbersize, STRINGY(12), SPLITFLAGS(V_SNAPTOTOP), realnightstime,
nightsnum, SKINCOLOR_SUPER4); nightsnum, SKINCOLOR_SUPERGOLD4);
// Show exact time in debug // Show exact time in debug
if (cv_debug & DBG_NIGHTSBASIC) if (cv_debug & DBG_NIGHTSBASIC)
@ -1385,6 +1393,10 @@ static void ST_drawMatchHUD(void)
if (G_TagGametype() && !(stplyr->pflags & PF_TAGIT)) if (G_TagGametype() && !(stplyr->pflags & PF_TAGIT))
return; return;
#ifdef HAVE_BLUA
if (LUA_HudEnabled(hud_weaponrings)) {
#endif
if (stplyr->powers[pw_infinityring]) if (stplyr->powers[pw_infinityring])
ST_drawWeaponRing(pw_infinityring, 0, 0, offset, infinityring); ST_drawWeaponRing(pw_infinityring, 0, 0, offset, infinityring);
else if (stplyr->health > 1) else if (stplyr->health > 1)
@ -1408,6 +1420,12 @@ static void ST_drawMatchHUD(void)
offset += 20; offset += 20;
ST_drawWeaponRing(pw_railring, RW_RAIL, WEP_RAIL, offset, railring); ST_drawWeaponRing(pw_railring, RW_RAIL, WEP_RAIL, offset, railring);
#ifdef HAVE_BLUA
}
if (LUA_HudEnabled(hud_powerstones)) {
#endif
// Power Stones collected // Power Stones collected
offset = 136; // Used for Y now offset = 136; // Used for Y now
@ -1439,6 +1457,10 @@ static void ST_drawMatchHUD(void)
if (stplyr->powers[pw_emeralds] & EMERALD7) if (stplyr->powers[pw_emeralds] & EMERALD7)
V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[6]); V_DrawScaledPatch(28, STRINGY(offset), V_SNAPTOLEFT, tinyemeraldpics[6]);
#ifdef HAVE_BLUA
}
#endif
} }
static inline void ST_drawRaceHUD(void) static inline void ST_drawRaceHUD(void)

View File

@ -24,7 +24,7 @@
// //
// Called by main loop. // Called by main loop.
void ST_Ticker(void); FUNCMATH void ST_Ticker(void);
// Called by main loop. // Called by main loop.
void ST_Drawer(void); void ST_Drawer(void);

View File

@ -82,7 +82,7 @@ typedef UINT32 angle_t;
extern angle_t tantoangle[SLOPERANGE+1]; extern angle_t tantoangle[SLOPERANGE+1];
// Utility function, called by R_PointToAngle. // Utility function, called by R_PointToAngle.
unsigned SlopeDiv(unsigned num, unsigned den); FUNCMATH unsigned SlopeDiv(unsigned num, unsigned den);
// 360 - angle_t(ANGLE_45) = ANGLE_315 // 360 - angle_t(ANGLE_45) = ANGLE_315
FUNCMATH FUNCINLINE static ATTRINLINE angle_t InvAngle(angle_t a) FUNCMATH FUNCINLINE static ATTRINLINE angle_t InvAngle(angle_t a)

View File

@ -54,10 +54,8 @@ typedef struct
#define lumpcache_t void * #define lumpcache_t void *
// Annoying cyclic dependency workaround: this inlcusion must come after
// the definition of MAX_WADPATH.
#ifdef HWRENDER #ifdef HWRENDER
#include "m_misc.h" #include "m_aatree.h"
#endif #endif
typedef struct wadfile_s typedef struct wadfile_s

View File

@ -145,6 +145,7 @@
<ClCompile Include="..\lzf.c" /> <ClCompile Include="..\lzf.c" />
<ClCompile Include="..\md5.c" /> <ClCompile Include="..\md5.c" />
<ClCompile Include="..\mserv.c" /> <ClCompile Include="..\mserv.c" />
<ClCompile Include="..\m_aatree.c" />
<ClCompile Include="..\m_anigif.c" /> <ClCompile Include="..\m_anigif.c" />
<ClCompile Include="..\m_argv.c" /> <ClCompile Include="..\m_argv.c" />
<ClCompile Include="..\m_bbox.c" /> <ClCompile Include="..\m_bbox.c" />
@ -300,6 +301,7 @@
<ClInclude Include="..\lzf.h" /> <ClInclude Include="..\lzf.h" />
<ClInclude Include="..\md5.h" /> <ClInclude Include="..\md5.h" />
<ClInclude Include="..\mserv.h" /> <ClInclude Include="..\mserv.h" />
<ClInclude Include="..\m_aatree.h" />
<ClInclude Include="..\m_anigif.h" /> <ClInclude Include="..\m_anigif.h" />
<ClInclude Include="..\m_argv.h" /> <ClInclude Include="..\m_argv.h" />
<ClInclude Include="..\m_bbox.h" /> <ClInclude Include="..\m_bbox.h" />

View File

@ -255,6 +255,9 @@
<ClCompile Include="..\lua_skinlib.c"> <ClCompile Include="..\lua_skinlib.c">
<Filter>LUA</Filter> <Filter>LUA</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\m_aatree.c">
<Filter>M_Misc</Filter>
</ClCompile>
<ClCompile Include="..\m_anigif.c"> <ClCompile Include="..\m_anigif.c">
<Filter>M_Misc</Filter> <Filter>M_Misc</Filter>
</ClCompile> </ClCompile>
@ -662,6 +665,9 @@
<ClInclude Include="..\md5.h"> <ClInclude Include="..\md5.h">
<Filter>M_Misc</Filter> <Filter>M_Misc</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\m_aatree.h">
<Filter>M_Misc</Filter>
</ClInclude>
<ClInclude Include="..\m_anigif.h"> <ClInclude Include="..\m_anigif.h">
<Filter>M_Misc</Filter> <Filter>M_Misc</Filter>
</ClInclude> </ClInclude>