Merge branch 'next' into gl-slopes

# Conflicts:
#	src/hardware/hw_main.c
This commit is contained in:
Monster Iestyn 2016-04-09 22:12:29 +01:00
commit 11c24f5ab6
76 changed files with 1764 additions and 5333 deletions

View file

@ -3,13 +3,19 @@ sudo: required
dist: trusty dist: trusty
env: env:
- CFLAGS=-Wno-absolute-value -Werror - CFLAGS=-Wall -W -Werror
os:
- linux
- osx
compiler: compiler:
- gcc - gcc
- clang - clang
cache: cache:
apt: true
ccache: true
directories: directories:
- $HOME/srb2_cache - $HOME/srb2_cache
@ -30,4 +36,10 @@ before_script:
- cd build - cd build
- cmake .. - cmake ..
before_install:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install sdl2_mixer game-music-emu p7zip ; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then curl -O -L https://www.libsdl.org/release/SDL2-2.0.4.dmg; hdiutil attach SDL2-2.0.4.dmg; sudo cp -a /Volumes/SDL2/SDL2.framework /Library/Frameworks/; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then curl -O -L https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-2.0.1.dmg; hdiutil attach SDL2_mixer-2.0.1.dmg; sudo cp -a /Volumes/SDL2_mixer/SDL2_mixer.framework /Library/Frameworks/; fi
script: make script: make

View file

@ -3293,23 +3293,6 @@ 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/p_fab.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/p_floor.c"> <Unit filename="src/p_floor.c">
<Option compilerVar="CC" /> <Option compilerVar="CC" />
<Option target="Debug Native/SDL" /> <Option target="Debug Native/SDL" />

View file

@ -11,6 +11,7 @@ environment:
SDL2_MIXER_URL: https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-devel-2.0.1-mingw.tar.gz SDL2_MIXER_URL: https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-devel-2.0.1-mingw.tar.gz
SDL2_MIXER_ARCHIVE: SDL2_mixer-devel-2.0.1-mingw.tar SDL2_MIXER_ARCHIVE: SDL2_mixer-devel-2.0.1-mingw.tar
SDL2_MIXER_MOVE: SDL2_mixer-2.0.1\i686-w64-mingw32 SDL2_MIXER_MOVE: SDL2_mixer-2.0.1\i686-w64-mingw32
CFLAGS: -Wall -W -Werror
cache: cache:
- SDL2-devel-2.0.4-mingw.tar.gz - SDL2-devel-2.0.4-mingw.tar.gz

View file

@ -6,16 +6,16 @@ find_path(GME_INCLUDE_DIR
NAMES gme.h NAMES gme.h
PATHS PATHS
${GME_PKGCONF_INCLUDE_DIRS} ${GME_PKGCONF_INCLUDE_DIRS}
/usr/include/gme "/usr/include/gme"
/usr/local/include/gme "/usr/local/include/gme"
) )
find_library(GME_LIBRARY find_library(GME_LIBRARY
NAMES gme NAMES gme
PATHS PATHS
${GME_PKGCONF_LIBRARY_DIRS} ${GME_PKGCONF_LIBRARY_DIRS}
/usr/lib "/usr/lib"
/usr/local/lib "/usr/local/lib"
) )
set(GME_PROCESS_INCLUDES GME_INCLUDE_DIR) set(GME_PROCESS_INCLUDES GME_INCLUDE_DIR)

View file

@ -1,4 +1,4 @@
@ECHO OFF @echo off
set BRA=Unknown set BRA=Unknown
set REV=illegal set REV=illegal
@ -13,20 +13,20 @@ goto filwri
:gitrev :gitrev
set GIT=%2 set GIT=%2
if "%GIT%"=="" set GIT=git if "%GIT%"=="" set GIT=git
FOR /F "usebackq" %%s IN (`%GIT% rev-parse --abbrev-ref HEAD`) DO @SET BRA=%%s for /f "usebackq" %%s in (`%GIT% rev-parse --abbrev-ref HEAD`) do @set BRA=%%s
FOR /F "usebackq" %%s IN (`%GIT% rev-parse HEAD`) DO @SET REV=%%s for /f "usebackq" %%s in (`%GIT% rev-parse HEAD`) do @set REV=%%s
set REV=%REV:~0,8% set REV=%REV:~0,8%
goto filwri goto filwri
:svnrev :svnrev
set BRA=Subversion set BRA=Subversion
FOR /F "usebackq" %%s IN (`svnversion .`) DO @SET REV=%%s for /f "usebackq" %%s in (`svnversion .`) do @set REV=%%s
set REV=r%REV% set REV=r%REV%
goto filwri goto filwri
:filwri :filwri
ECHO // Do not edit! This file was autogenerated > %1\comptime.h echo // Do not edit! This file was autogenerated > %1\comptime.h
ECHO // by the %0 batch file >> %1\comptime.h echo // by the %0 batch file >> %1\comptime.h
ECHO // >> %1\comptime.h echo // >> %1\comptime.h
ECHO const char* compbranch = "%BRA%"; >> %1\comptime.h echo const char* compbranch = "%BRA%"; >> %1\comptime.h
ECHO const char* comprevision = "%REV%"; >> %1\comptime.h echo const char* comprevision = "%REV%"; >> %1\comptime.h

View file

@ -139,7 +139,6 @@ set(SRB2_CORE_RENDER_SOURCES
set(SRB2_CORE_GAME_SOURCES set(SRB2_CORE_GAME_SOURCES
p_ceilng.c p_ceilng.c
p_enemy.c p_enemy.c
p_fab.c
p_floor.c p_floor.c
p_inter.c p_inter.c
p_lights.c p_lights.c
@ -316,6 +315,7 @@ if(${SRB2_CONFIG_HAVE_GME})
find_package(GME) find_package(GME)
if(${GME_FOUND}) if(${GME_FOUND})
set(SRB2_HAVE_GME ON) set(SRB2_HAVE_GME ON)
add_definitions(-DHAVE_LIBGME)
else() else()
message(WARNING "You have specified that GME is available but it was not found.") message(WARNING "You have specified that GME is available but it was not found.")
endif() endif()

View file

@ -262,9 +262,7 @@ else
OBJS+=$(OBJDIR)/hw3sound.o OBJS+=$(OBJDIR)/hw3sound.o
endif endif
ifndef NOVERSION
OPTS += -DCOMPVERSION OPTS += -DCOMPVERSION
endif
ifndef NONX86 ifndef NONX86
ifndef GCC29 ifndef GCC29
@ -439,7 +437,6 @@ OBJS:=$(i_main_o) \
$(OBJDIR)/info.o \ $(OBJDIR)/info.o \
$(OBJDIR)/p_ceilng.o \ $(OBJDIR)/p_ceilng.o \
$(OBJDIR)/p_enemy.o \ $(OBJDIR)/p_enemy.o \
$(OBJDIR)/p_fab.o \
$(OBJDIR)/p_floor.o \ $(OBJDIR)/p_floor.o \
$(OBJDIR)/p_inter.o \ $(OBJDIR)/p_inter.o \
$(OBJDIR)/p_lights.o \ $(OBJDIR)/p_lights.o \
@ -551,15 +548,11 @@ cleandep:
$(REMOVE) comptime.h $(REMOVE) comptime.h
pre-build: pre-build:
ifdef NOVERSION
-@touch comptime.c
else
ifdef WINDOWSHELL ifdef WINDOWSHELL
-..\comptime.bat . -..\comptime.bat .
else else
-@../comptime.sh . -@../comptime.sh .
endif endif
endif
clean: clean:
$(REMOVE) *~ *.flc $(REMOVE) *~ *.flc

View file

@ -30,9 +30,7 @@ static const UINT8 REDRANGE = 16;
static const UINT8 GRAYS = (1*16); static const UINT8 GRAYS = (1*16);
static const UINT8 GRAYSRANGE = 16; static const UINT8 GRAYSRANGE = 16;
static const UINT8 BROWNS = (3*16); static const UINT8 BROWNS = (3*16);
static const UINT8 BROWNRANGE = 16;
static const UINT8 YELLOWS = (7*16); static const UINT8 YELLOWS = (7*16);
static const UINT8 YELLOWRANGE = 8;
static const UINT8 GREENS = (10*16); static const UINT8 GREENS = (10*16);
static const UINT8 GREENRANGE = 16; static const UINT8 GREENRANGE = 16;
static const UINT8 DBLACK = 31; static const UINT8 DBLACK = 31;
@ -41,11 +39,8 @@ static const UINT8 DWHITE = 0;
static const UINT8 NOCLIMBREDS = 248; static const UINT8 NOCLIMBREDS = 248;
static const UINT8 NOCLIMBREDRANGE = 8; static const UINT8 NOCLIMBREDRANGE = 8;
static const UINT8 NOCLIMBGRAYS = 204; static const UINT8 NOCLIMBGRAYS = 204;
static const UINT8 NOCLIMBGRAYSRANGE = 4;
static const UINT8 NOCLIMBBROWNS = (2*16); static const UINT8 NOCLIMBBROWNS = (2*16);
static const UINT8 NOCLIMBBROWNRANGE = 16;
static const UINT8 NOCLIMBYELLOWS = (11*16); static const UINT8 NOCLIMBYELLOWS = (11*16);
static const UINT8 NOCLIMBYELLOWRANGE = 8;
#ifdef _NDS #ifdef _NDS
@ -67,15 +62,10 @@ static const UINT8 NOCLIMBYELLOWRANGE = 8;
#define TSWALLCOLORS GRAYS #define TSWALLCOLORS GRAYS
#define TSWALLRANGE GRAYSRANGE #define TSWALLRANGE GRAYSRANGE
#define NOCLIMBTSWALLCOLORS NOCLIMBGRAYS #define NOCLIMBTSWALLCOLORS NOCLIMBGRAYS
#define NOCLIMBTSWALLRANGE NOCLIMBGRAYSRANGE
#define FDWALLCOLORS BROWNS #define FDWALLCOLORS BROWNS
#define FDWALLRANGE BROWNRANGE
#define NOCLIMBFDWALLCOLORS NOCLIMBBROWNS #define NOCLIMBFDWALLCOLORS NOCLIMBBROWNS
#define NOCLIMBFDWALLRANGE NOCLIMBBROWNRANGE
#define CDWALLCOLORS YELLOWS #define CDWALLCOLORS YELLOWS
#define CDWALLRANGE YELLOWRANGE
#define NOCLIMBCDWALLCOLORS NOCLIMBYELLOWS #define NOCLIMBCDWALLCOLORS NOCLIMBYELLOWS
#define NOCLIMBCDWALLRANGE NOCLIMBYELLOWRANGE
#define THINGCOLORS GREENS #define THINGCOLORS GREENS
#define THINGRANGE GREENRANGE #define THINGRANGE GREENRANGE
#define SECRETWALLCOLORS WALLCOLORS #define SECRETWALLCOLORS WALLCOLORS
@ -255,29 +245,6 @@ static AMDRAWFLINEFUNC AM_drawFline;
static void AM_drawFline_soft(const fline_t *fl, INT32 color); static void AM_drawFline_soft(const fline_t *fl, INT32 color);
/** Calculates the slope and slope according to the x-axis of a line
* segment in map coordinates (with the upright y-axis and all) so
* that it can be used with the braindead drawing stuff.
*
* \param ml The line segment.
* \param is Holds the result.
*/
static inline void AM_getIslope(const mline_t *ml, islope_t *is)
{
INT32 dx, dy;
dy = ml->a.y - ml->b.y;
dx = ml->b.x - ml->a.x;
if (!dy)
is->islp = (dx < 0 ? -INT32_MAX : INT32_MAX);
else
is->islp = FixedDiv(dx, dy);
if (!dx)
is->slp = (dy < 0 ? -INT32_MAX : INT32_MAX);
else
is->slp = FixedDiv(dy, dx);
}
static void AM_activateNewScale(void) static void AM_activateNewScale(void)
{ {
m_x += m_w/2; m_x += m_w/2;

View file

@ -49,7 +49,7 @@ static inline void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cm
if (sonic->player->pflags & (PF_MACESPIN|PF_ITEMHANG)) if (sonic->player->pflags & (PF_MACESPIN|PF_ITEMHANG))
{ {
cmd->forwardmove = sonic->player->cmd.forwardmove; cmd->forwardmove = sonic->player->cmd.forwardmove;
cmd->angleturn = abs((tails->angle - sonic->angle))>>16; cmd->angleturn = abs((signed)(tails->angle - sonic->angle))>>16;
if (sonic->angle < tails->angle) if (sonic->angle < tails->angle)
cmd->angleturn = -cmd->angleturn; cmd->angleturn = -cmd->angleturn;
} else if (dist > FixedMul(512*FRACUNIT, tails->scale)) } else if (dist > FixedMul(512*FRACUNIT, tails->scale))

View file

@ -15,7 +15,9 @@
#define ASSET_HASH_PLAYER_DTA "${SRB2_ASSET_player.dta_HASH}" #define ASSET_HASH_PLAYER_DTA "${SRB2_ASSET_player.dta_HASH}"
#define ASSET_HASH_RINGS_DTA "${SRB2_ASSET_rings.dta_HASH}" #define ASSET_HASH_RINGS_DTA "${SRB2_ASSET_rings.dta_HASH}"
#define ASSET_HASH_ZONES_DTA "${SRB2_ASSET_zones.dta_HASH}" #define ASSET_HASH_ZONES_DTA "${SRB2_ASSET_zones.dta_HASH}"
#ifdef USE_PATCH_DTA
#define ASSET_HASH_PATCH_DTA "${SRB2_ASSET_patch.dta_HASH}" #define ASSET_HASH_PATCH_DTA "${SRB2_ASSET_patch.dta_HASH}"
#endif
#define SRB2_COMP_REVISION "${SRB2_COMP_REVISION}" #define SRB2_COMP_REVISION "${SRB2_COMP_REVISION}"
#define SRB2_COMP_BRANCH "${SRB2_COMP_BRANCH}" #define SRB2_COMP_BRANCH "${SRB2_COMP_BRANCH}"
@ -26,10 +28,16 @@
#else #else
/* Manually defined asset hashes for non-CMake builds
* Last updated 2000 / 00 / 00
*/
#define ASSET_HASH_SRB2_SRB "c1b9577687f8a795104aef4600720ea7" #define ASSET_HASH_SRB2_SRB "c1b9577687f8a795104aef4600720ea7"
#define ASSET_HASH_ZONES_DTA "303838c6c534d9540288360fa49cca60" #define ASSET_HASH_ZONES_DTA "303838c6c534d9540288360fa49cca60"
#define ASSET_HASH_PLAYER_DTA "cfca0f1c73023cbbd8f844f45480f799" #define ASSET_HASH_PLAYER_DTA "cfca0f1c73023cbbd8f844f45480f799"
#define ASSET_HASH_RINGS_DTA "85901ad4bf94637e5753d2ac2c03ea26" #define ASSET_HASH_RINGS_DTA "85901ad4bf94637e5753d2ac2c03ea26"
#ifdef USE_PATCH_DTA
#define ASSET_HASH_PATCH_DTA "0c66790502e648bfce90fdc5bb15722e"
#endif
#endif #endif
#endif #endif

View file

@ -2935,9 +2935,9 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
if (botingame) if (botingame)
players[newplayernum].bot = 1; players[newplayernum].bot = 1;
// Same goes for player 2 when relevant // Same goes for player 2 when relevant
players[newplayernum].pflags &= ~(/*PF_FLIPCAM|*/PF_ANALOGMODE); players[newplayernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE);
//if (cv_flipcam2.value) if (cv_flipcam2.value)
//players[newplayernum].pflags |= PF_FLIPCAM; players[newplayernum].pflags |= PF_FLIPCAM;
if (cv_analog2.value) if (cv_analog2.value)
players[newplayernum].pflags |= PF_ANALOGMODE; players[newplayernum].pflags |= PF_ANALOGMODE;
} }

View file

@ -221,10 +221,7 @@ gamestate_t wipegamestate = GS_LEVEL;
static void D_Display(void) static void D_Display(void)
{ {
static boolean menuactivestate = false; boolean forcerefresh = false;
static gamestate_t oldgamestate = -1;
boolean redrawsbar = false;
static boolean wipe = false; static boolean wipe = false;
INT32 wipedefindex = 0; INT32 wipedefindex = 0;
@ -245,23 +242,15 @@ static void D_Display(void)
if (setsizeneeded) if (setsizeneeded)
{ {
R_ExecuteSetViewSize(); R_ExecuteSetViewSize();
oldgamestate = -1; // force background redraw forcerefresh = true; // force background redraw
redrawsbar = true;
} }
// save the current screen if about to wipe
if (gamestate != wipegamestate)
{
wipe = true;
F_WipeStartScreen();
}
else
wipe = false;
// draw buffered stuff to screen // draw buffered stuff to screen
// Used only by linux GGI version // Used only by linux GGI version
I_UpdateNoBlit(); I_UpdateNoBlit();
// save the current screen if about to wipe
wipe = (gamestate != wipegamestate);
if (wipe) if (wipe)
{ {
// set for all later // set for all later
@ -280,6 +269,7 @@ static void D_Display(void)
if (gamestate != GS_LEVEL // fades to black on its own timing, always if (gamestate != GS_LEVEL // fades to black on its own timing, always
&& wipedefs[wipedefindex] != UINT8_MAX) && wipedefs[wipedefindex] != UINT8_MAX)
{ {
F_WipeStartScreen();
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
F_WipeEndScreen(); F_WipeEndScreen();
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK); F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK);
@ -298,8 +288,6 @@ static void D_Display(void)
HU_Erase(); HU_Erase();
if (automapactive) if (automapactive)
AM_Drawer(); AM_Drawer();
if (wipe || menuactivestate || (rendermode != render_soft && rendermode != render_none) || vid.recalc)
redrawsbar = true;
break; break;
case GS_INTERMISSION: case GS_INTERMISSION:
@ -357,11 +345,6 @@ static void D_Display(void)
// see if the border needs to be initially drawn // see if the border needs to be initially drawn
if (gamestate == GS_LEVEL) if (gamestate == GS_LEVEL)
{ {
#if 0
if (oldgamestate != GS_LEVEL)
R_FillBackScreen(); // draw the pattern into the back screen
#endif
// draw the view directly // draw the view directly
if (!automapactive && !dedicated && cv_renderview.value) if (!automapactive && !dedicated && cv_renderview.value)
{ {
@ -417,17 +400,17 @@ static void D_Display(void)
lastdraw = false; lastdraw = false;
} }
ST_Drawer(redrawsbar); ST_Drawer();
HU_Drawer(); HU_Drawer();
} }
// change gamma if needed // change gamma if needed
if (gamestate != oldgamestate && gamestate != GS_LEVEL) // (GS_LEVEL handles this already due to level-specific palettes)
if (forcerefresh && gamestate != GS_LEVEL)
V_SetPalette(0); V_SetPalette(0);
menuactivestate = menuactive; wipegamestate = gamestate;
oldgamestate = wipegamestate = gamestate;
// draw pause pic // draw pause pic
if (paused && cv_showhud.value && (!menuactive || netgame)) if (paused && cv_showhud.value && (!menuactive || netgame))
@ -450,15 +433,22 @@ static void D_Display(void)
CON_Drawer(); CON_Drawer();
M_Drawer(); // menu is drawn even on top of everything M_Drawer(); // menu is drawn even on top of everything
// focus lost moved to M_Drawer
// focus lost notification goes on top of everything, even the former everything //
if (window_notinfocus) // wipe update
//
if (wipe)
{ {
M_DrawTextBox((BASEVIDWIDTH/2) - (60), (BASEVIDHEIGHT/2) - (16), 13, 2); // note: moved up here because NetUpdate does input changes
if (gamestate == GS_LEVEL && (P_AutoPause() || paused)) // and input during wipe tends to mess things up
V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4), V_YELLOWMAP, "Game Paused"); wipedefindex += WIPEFINALSHIFT;
else
V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4), V_YELLOWMAP, "Focus Lost"); if (rendermode != render_none)
{
F_WipeEndScreen();
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK);
}
} }
NetUpdate(); // send out any new accumulation NetUpdate(); // send out any new accumulation
@ -493,18 +483,6 @@ static void D_Display(void)
} }
I_FinishUpdate(); // page flip or blit buffer I_FinishUpdate(); // page flip or blit buffer
return;
}
//
// wipe update
//
wipedefindex += WIPEFINALSHIFT;
if (rendermode != render_none)
{
F_WipeEndScreen();
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK);
} }
} }
@ -513,7 +491,6 @@ static void D_Display(void)
// ========================================================================= // =========================================================================
tic_t rendergametic; tic_t rendergametic;
boolean supdate;
void D_SRB2Loop(void) void D_SRB2Loop(void)
{ {
@ -604,7 +581,6 @@ void D_SRB2Loop(void)
// Update display, next frame, with current state. // Update display, next frame, with current state.
D_Display(); D_Display();
supdate = false;
if (moviemode) if (moviemode)
M_SaveFrame(); M_SaveFrame();
@ -841,8 +817,10 @@ static void IdentifyVersion(void)
// Add the weapons // Add the weapons
D_AddFile(va(pandf,srb2waddir,"rings.dta")); D_AddFile(va(pandf,srb2waddir,"rings.dta"));
#ifdef USE_PATCH_DTA
// Add our crappy patches to fix our bugs // Add our crappy patches to fix our bugs
// D_AddFile(va(pandf,srb2waddir,"patch.dta")); D_AddFile(va(pandf,srb2waddir,"patch.dta"));
#endif
#if !defined (HAVE_SDL) || defined (HAVE_MIXER) #if !defined (HAVE_SDL) || defined (HAVE_MIXER)
{ {
@ -1133,12 +1111,18 @@ void D_SRB2Main(void)
W_VerifyFileMD5(1, ASSET_HASH_ZONES_DTA); // zones.dta W_VerifyFileMD5(1, ASSET_HASH_ZONES_DTA); // zones.dta
W_VerifyFileMD5(2, ASSET_HASH_PLAYER_DTA); // player.dta W_VerifyFileMD5(2, ASSET_HASH_PLAYER_DTA); // player.dta
W_VerifyFileMD5(3, ASSET_HASH_RINGS_DTA); // rings.dta W_VerifyFileMD5(3, ASSET_HASH_RINGS_DTA); // rings.dta
//W_VerifyFileMD5(4, "0c66790502e648bfce90fdc5bb15722e"); // patch.dta #ifdef USE_PATCH_DTA
// don't check music.dta because people like to modify it, and it doesn't matter if they do W_VerifyFileMD5(4, ASSET_HASH_PATCH_DTA); // patch.dta
// ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for.
#endif #endif
mainwads = 4; // there are 5 wads not to unload // don't check music.dta because people like to modify it, and it doesn't matter if they do
// ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for.
#endif //ifndef DEVELOP
mainwads = 4; // there are 4 wads not to unload
#ifdef USE_PATCH_DTA
++mainwads; // patch.dta adds one more
#endif
cht_Init(); cht_Init();

View file

@ -17,7 +17,6 @@
#include "d_event.h" #include "d_event.h"
#include "w_wad.h" // for MAX_WADFILES #include "w_wad.h" // for MAX_WADFILES
extern boolean supdate;
extern boolean advancedemo; extern boolean advancedemo;
// make sure not to write back the config until it's been correctly loaded // make sure not to write back the config until it's been correctly loaded

View file

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

File diff suppressed because it is too large Load diff

View file

@ -101,6 +101,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#define _USE_MATH_DEFINES // fixes M_PI errors in r_plane.c for Visual Studio
#include <math.h> #include <math.h>
#ifdef GETTEXT #ifdef GETTEXT
@ -148,13 +149,17 @@ extern FILE *logstream;
// we use comprevision and compbranch instead. // we use comprevision and compbranch instead.
#else #else
#define VERSION 201 // Game version #define VERSION 201 // Game version
#define SUBVERSION 14 // more precise version number #define SUBVERSION 15 // more precise version number
#define VERSIONSTRING "v2.1.14" #define VERSIONSTRING "v2.1.15"
#define VERSIONSTRINGW L"v2.1.14" #define VERSIONSTRINGW L"v2.1.15"
// Hey! If you change this, add 1 to the MODVERSION below! // Hey! If you change this, add 1 to the MODVERSION below!
// Otherwise we can't force updates! // Otherwise we can't force updates!
#endif #endif
// Does this version require an added patch file?
// Comment or uncomment this as necessary.
#define USE_PATCH_DTA
// Modification options // Modification options
// If you want to take advantage of the Master Server's ability to force clients to update // If you want to take advantage of the Master Server's ability to force clients to update
// to the latest version, fill these out. Otherwise, just comment out UPDATE_ALERT and leave // to the latest version, fill these out. Otherwise, just comment out UPDATE_ALERT and leave
@ -208,7 +213,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 19 #define MODVERSION 20
// ========================================================================= // =========================================================================
@ -423,13 +428,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
// None of these that are disabled in the normal build are guaranteed to work perfectly // None of these that are disabled in the normal build are guaranteed to work perfectly
// Compile them at your own risk! // Compile them at your own risk!
/// Max recursive portal renders
/// \note obsoleted by cv_maxportals
//#define PORTAL_LIMIT 8
/// Fun experimental slope stuff!
//#define SLOPENESS
/// Kalaron/Eternity Engine slope code (SRB2CB ported) /// Kalaron/Eternity Engine slope code (SRB2CB ported)
#define ESLOPE #define ESLOPE
@ -449,10 +447,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Polyobject fake flat code /// Polyobject fake flat code
#define POLYOBJECTS_PLANES #define POLYOBJECTS_PLANES
/// Blue spheres for future use.
/// \todo Remove this define.
#define BLUE_SPHERES // Blue spheres for future use.
/// Improved way of dealing with ping values and a ping limit. /// Improved way of dealing with ping values and a ping limit.
#define NEWPING #define NEWPING
@ -490,4 +484,8 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Experimental tweaks to analog mode. (Needs a lot of work before it's ready for primetime.) /// Experimental tweaks to analog mode. (Needs a lot of work before it's ready for primetime.)
//#define REDSANALOG //#define REDSANALOG
/// Backwards compatibility with musicslots.
/// \note You should leave this enabled unless you're working with a future SRB2 version.
#define MUSICSLOT_COMPATIBILITY
#endif // __DOOMDEF__ #endif // __DOOMDEF__

View file

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

View file

@ -94,7 +94,6 @@ typedef long ssize_t;
#ifdef __APPLE_CC__ #ifdef __APPLE_CC__
#define DIRECTFULLSCREEN #define DIRECTFULLSCREEN
#define DEBUG_LOG #define DEBUG_LOG
#define HWRENDER
#define NOIPX #define NOIPX
#endif #endif

View file

@ -559,7 +559,7 @@ static void F_IntroDrawScene(void)
if (finalecount < 4) if (finalecount < 4)
S_StopMusic(); S_StopMusic();
if (finalecount == 4) if (finalecount == 4)
S_ChangeMusic(mus_stjr, false); S_ChangeMusicInternal("stjr", false);
x = (BASEVIDWIDTH<<FRACBITS)/2 - FixedMul(334<<FRACBITS, aspect)/2; x = (BASEVIDWIDTH<<FRACBITS)/2 - FixedMul(334<<FRACBITS, aspect)/2;
y = (BASEVIDHEIGHT<<FRACBITS)/2 - FixedMul(358<<FRACBITS, aspect)/2; y = (BASEVIDHEIGHT<<FRACBITS)/2 - FixedMul(358<<FRACBITS, aspect)/2;
V_DrawSciencePatch(x, y, 0, (patch = W_CachePatchName("WAHH1", PU_CACHE)), aspect); V_DrawSciencePatch(x, y, 0, (patch = W_CachePatchName("WAHH1", PU_CACHE)), aspect);
@ -771,7 +771,7 @@ void F_IntroDrawer(void)
F_RunWipe(99,true); F_RunWipe(99,true);
} }
S_ChangeMusic(mus_read_m, false); S_ChangeMusicInternal("read_m", false);
} }
else if (intro_scenenum == 3) else if (intro_scenenum == 3)
roidtics = BASEVIDWIDTH - 64; roidtics = BASEVIDWIDTH - 64;
@ -977,6 +977,7 @@ static const char *credits[] = {
"\"Monster\" Iestyn Jealous", "\"Monster\" Iestyn Jealous",
"Ronald \"Furyhunter\" Kinard", // The SDL2 port "Ronald \"Furyhunter\" Kinard", // The SDL2 port
"John \"JTE\" Muniz", "John \"JTE\" Muniz",
"Ehab \"Wolfy\" Saeed",
"\"SSNTails\"", "\"SSNTails\"",
"Matthew \"Inuyasha\" Walsh", "Matthew \"Inuyasha\" Walsh",
"", "",
@ -1020,7 +1021,7 @@ static const char *credits[] = {
"\"Monster\" Iestyn Jealous", "\"Monster\" Iestyn Jealous",
"Jarel \"Arrow\" Jones", "Jarel \"Arrow\" Jones",
"Stefan \"Stuf\" Rimalia", "Stefan \"Stuf\" Rimalia",
"Shane Strife", "Shane Mychal Sexton",
"\"Spazzo\"", "\"Spazzo\"",
"David \"Big Wave Dave\" Spencer Sr.", "David \"Big Wave Dave\" Spencer Sr.",
"David \"Instant Sonic\" Spencer Jr.", "David \"Instant Sonic\" Spencer Jr.",
@ -1125,7 +1126,7 @@ void F_StartCredits(void)
CON_ClearHUD(); CON_ClearHUD();
S_StopMusic(); S_StopMusic();
S_ChangeMusic(mus_credit, false); S_ChangeMusicInternal("credit", false);
finalecount = 0; finalecount = 0;
animtimer = 0; animtimer = 0;
@ -1422,7 +1423,7 @@ void F_StartTitleScreen(void)
// IWAD dependent stuff. // IWAD dependent stuff.
S_ChangeMusic(mus_titles, looptitle); S_ChangeMusicInternal("titles", looptitle);
animtimer = 0; animtimer = 0;
@ -1588,7 +1589,7 @@ void F_StartContinue(void)
// In case menus are still up?!! // In case menus are still up?!!
M_ClearMenus(true); M_ClearMenus(true);
S_ChangeMusic(mus_contsc, false); S_ChangeMusicInternal("contsc", false);
S_StopSounds(); S_StopSounds();
timetonext = TICRATE*11; timetonext = TICRATE*11;
@ -1702,8 +1703,10 @@ static void F_AdvanceToNextScene(void)
picxpos = cutscenes[cutnum]->scene[scenenum].xcoord[picnum]; picxpos = cutscenes[cutnum]->scene[scenenum].xcoord[picnum];
picypos = cutscenes[cutnum]->scene[scenenum].ycoord[picnum]; picypos = cutscenes[cutnum]->scene[scenenum].ycoord[picnum];
if (cutscenes[cutnum]->scene[scenenum].musicslot != 0) if (cutscenes[cutnum]->scene[scenenum].musswitch[0])
S_ChangeMusic(cutscenes[cutnum]->scene[scenenum].musicslot, cutscenes[cutnum]->scene[scenenum].musicloop); S_ChangeMusic(cutscenes[cutnum]->scene[scenenum].musswitch,
cutscenes[cutnum]->scene[scenenum].musswitchflags,
cutscenes[cutnum]->scene[scenenum].musicloop);
// Fade to the next // Fade to the next
dofadenow = true; dofadenow = true;
@ -1774,8 +1777,10 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
animtimer = cutscenes[cutnum]->scene[0].picduration[0]; // Picture duration animtimer = cutscenes[cutnum]->scene[0].picduration[0]; // Picture duration
stoptimer = 0; stoptimer = 0;
if (cutscenes[cutnum]->scene[scenenum].musicslot != 0) if (cutscenes[cutnum]->scene[0].musswitch[0])
S_ChangeMusic(cutscenes[cutnum]->scene[scenenum].musicslot, cutscenes[cutnum]->scene[scenenum].musicloop); S_ChangeMusic(cutscenes[cutnum]->scene[0].musswitch,
cutscenes[cutnum]->scene[0].musswitchflags,
cutscenes[cutnum]->scene[0].musicloop);
else else
S_StopMusic(); S_StopMusic();
} }

View file

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

View file

@ -58,6 +58,7 @@ UINT8 wipedefs[NUMWIPEDEFS] = {
0, // wipe_specinter_toblack 0, // wipe_specinter_toblack
0, // wipe_multinter_toblack 0, // wipe_multinter_toblack
0, // wipe_speclevel_towhite
0, // wipe_level_final 0, // wipe_level_final
0, // wipe_intermission_final 0, // wipe_intermission_final

View file

@ -69,8 +69,10 @@ static void G_DoStartContinue(void);
static void G_DoContinued(void); static void G_DoContinued(void);
static void G_DoWorldDone(void); static void G_DoWorldDone(void);
char mapmusname[7]; // Music name
UINT16 mapmusflags; // Track and reset bit
INT16 gamemap = 1; INT16 gamemap = 1;
UINT32 mapmusic; // music, track, and reset bit
INT16 maptol; INT16 maptol;
UINT8 globalweather = 0; UINT8 globalweather = 0;
INT32 curWeather = PRECIP_NONE; INT32 curWeather = PRECIP_NONE;
@ -2182,12 +2184,13 @@ void G_PlayerReborn(INT32 player)
if (p-players == consoleplayer) if (p-players == consoleplayer)
{ {
if (mapmusic & MUSIC_RELOADRESET) // TODO: Might not need this here if (mapmusflags & MUSIC_RELOADRESET)
{ {
mapmusic = mapheaderinfo[gamemap-1]->musicslot strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7);
| (mapheaderinfo[gamemap-1]->musicslottrack << MUSIC_TRACKSHIFT); mapmusname[6] = 0;
mapmusflags = mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK;
} }
S_ChangeMusic(mapmusic, true); S_ChangeMusic(mapmusname, mapmusflags, true);
} }
if (gametype == GT_COOP) if (gametype == GT_COOP)
@ -2328,6 +2331,11 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost)
} }
} }
P_MovePlayerToSpawn(playernum, spawnpoint); P_MovePlayerToSpawn(playernum, spawnpoint);
#ifdef HAVE_BLUA
LUAh_PlayerSpawn(&players[playernum]); // Lua hook for player spawning :)
#endif
} }
mapthing_t *G_FindCTFStart(INT32 playernum) mapthing_t *G_FindCTFStart(INT32 playernum)
@ -2871,7 +2879,8 @@ static void G_DoCompleted(void)
// We are committed to this map now. // We are committed to this map now.
// We may as well allocate its header if it doesn't exist // We may as well allocate its header if it doesn't exist
if(!mapheaderinfo[nextmap]) // (That is, if it's a real map)
if (nextmap < NUMMAPS && !mapheaderinfo[nextmap])
P_AllocMapHeader(nextmap); P_AllocMapHeader(nextmap);
if (skipstats) if (skipstats)
@ -3521,7 +3530,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
if (paused) if (paused)
{ {
paused = false; paused = false;
S_ResumeSound(); S_ResumeAudio();
} }
if (netgame || multiplayer) // Nice try, haxor. if (netgame || multiplayer) // Nice try, haxor.
@ -3595,7 +3604,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
globalweather = mapheaderinfo[gamemap-1]->weather; globalweather = mapheaderinfo[gamemap-1]->weather;
// Don't carry over custom music change to another map. // Don't carry over custom music change to another map.
mapmusic |= MUSIC_RELOADRESET; mapmusflags |= MUSIC_RELOADRESET;
ultimatemode = pultmode; ultimatemode = pultmode;
playerdeadview = false; playerdeadview = false;
@ -4326,10 +4335,8 @@ void G_GhostTicker(void)
switch(g->color) switch(g->color)
{ {
case GHC_SUPER: // Super Sonic (P_DoSuperStuff) case GHC_SUPER: // Super Sonic (P_DoSuperStuff)
if (leveltime % 9 < 5) g->mo->color = SKINCOLOR_SUPER1;
g->mo->color = SKINCOLOR_SUPER1 + leveltime % 9; g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4);
else
g->mo->color = SKINCOLOR_SUPER1 + 9 - leveltime % 9;
break; break;
case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer) case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer)
g->mo->color = (UINT8)(leveltime % MAXSKINCOLORS); g->mo->color = (UINT8)(leveltime % MAXSKINCOLORS);

View file

@ -657,6 +657,9 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
FOutVector v[4]; FOutVector v[4];
FSurfaceInfo Surf; FSurfaceInfo Surf;
if (w < 0 || h < 0)
return; // consistency w/ software
// 3--2 // 3--2
// | /| // | /|
// |/ | // |/ |

View file

@ -36,9 +36,7 @@ typedef struct
{ {
float x; float x;
float y; float y;
//#ifdef SLOPENESS
float z; float z;
//#endif
} polyvertex_t; } polyvertex_t;
#ifdef _MSC_VER #ifdef _MSC_VER

View file

@ -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 *shittyUnusedVariable, extrasubsector_t *xsub, fixed_t fixedheight, static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, 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;
@ -544,7 +544,7 @@ static void HWR_RenderPlane(sector_t *shittyUnusedVariable, extrasubsector_t *xs
static FOutVector *planeVerts = NULL; static FOutVector *planeVerts = NULL;
static UINT16 numAllocedPlaneVerts = 0; static UINT16 numAllocedPlaneVerts = 0;
(void)shittyUnusedVariable; ///@TODO remove shitty unused variable (void)sector; ///@TODO remove shitty unused variable
// no convex poly were generated for this subsector // no convex poly were generated for this subsector
if (!xsub->planepoly) if (!xsub->planepoly)
@ -3899,12 +3899,6 @@ static void HWR_ClearSprites(void)
gr_visspritecount = 0; gr_visspritecount = 0;
} }
static inline void HWR_ResetVisSpriteChunks(void)
{
memset(gr_visspritechunks, 0, sizeof(gr_visspritechunks));
}
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// HWR_NewVisSprite // HWR_NewVisSprite
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------

View file

@ -406,191 +406,6 @@ static md2_model_t *md2_readModel(const char *filename)
return model; return model;
} }
/*
* center model
*/
static inline void md2_getBoundingBox (md2_model_t *model, float *minmax)
{
size_t i;
float minx, maxx;
float miny, maxy;
float minz, maxz;
minx = miny = minz = 999999.0f;
maxx = maxy = maxz = -999999.0f;
/* get bounding box */
for (i = 0; i < model->header.numVertices; i++)
{
md2_triangleVertex_t *v = &model->frames[0].vertices[i];
if (v->vertex[0] < minx)
minx = v->vertex[0];
else if (v->vertex[0] > maxx)
maxx = v->vertex[0];
if (v->vertex[1] < miny)
miny = v->vertex[1];
else if (v->vertex[1] > maxy)
maxy = v->vertex[1];
if (v->vertex[2] < minz)
minz = v->vertex[2];
else if (v->vertex[2] > maxz)
maxz = v->vertex[2];
}
minmax[0] = minx;
minmax[1] = maxx;
minmax[2] = miny;
minmax[3] = maxy;
minmax[4] = minz;
minmax[5] = maxz;
}
static inline INT32 md2_getAnimationCount(md2_model_t *model)
{
size_t i, pos;
INT32 j = 0, count;
char name[16], last[16];
strcpy(last, model->frames[0].name);
pos = strlen(last) - 1;
while (last[pos] >= '0' && last[pos] <= '9' && j < 2)
{
pos--;
j++;
}
last[pos + 1] = '\0';
count = 0;
for (i = 0; i <= model->header.numFrames; i++)
{
if (i == model->header.numFrames)
strcpy(name, ""); // some kind of a sentinel
else
strcpy(name, model->frames[i].name);
pos = strlen(name) - 1;
j = 0;
while (name[pos] >= '0' && name[pos] <= '9' && j < 2)
{
pos--;
j++;
}
name[pos + 1] = '\0';
if (strcmp(last, name))
{
strcpy(last, name);
count++;
}
}
return count;
}
static inline const char * md2_getAnimationName (md2_model_t *model, INT32 animation)
{
size_t i, pos;
INT32 j = 0, count;
static char last[32];
char name[32];
strcpy(last, model->frames[0].name);
pos = strlen(last) - 1;
while (last[pos] >= '0' && last[pos] <= '9' && j < 2)
{
pos--;
j++;
}
last[pos + 1] = '\0';
count = 0;
for (i = 0; i <= model->header.numFrames; i++)
{
if (i == model->header.numFrames)
strcpy(name, ""); // some kind of a sentinel
else
strcpy(name, model->frames[i].name);
pos = strlen(name) - 1;
j = 0;
while (name[pos] >= '0' && name[pos] <= '9' && j < 2)
{
pos--;
j++;
}
name[pos + 1] = '\0';
if (strcmp(last, name))
{
if (count == animation)
return last;
strcpy(last, name);
count++;
}
}
return 0;
}
static inline void md2_getAnimationFrames(md2_model_t *model,
INT32 animation, INT32 *startFrame, INT32 *endFrame)
{
size_t i, pos;
INT32 j = 0, count, numFrames, frameCount;
char name[16], last[16];
strcpy(last, model->frames[0].name);
pos = strlen(last) - 1;
while (last[pos] >= '0' && last[pos] <= '9' && j < 2)
{
pos--;
j++;
}
last[pos + 1] = '\0';
count = 0;
numFrames = 0;
frameCount = 0;
for (i = 0; i <= model->header.numFrames; i++)
{
if (i == model->header.numFrames)
strcpy(name, ""); // some kind of a sentinel
else
strcpy(name, model->frames[i].name);
pos = strlen(name) - 1;
j = 0;
while (name[pos] >= '0' && name[pos] <= '9' && j < 2)
{
pos--;
j++;
}
name[pos + 1] = '\0';
if (strcmp(last, name))
{
strcpy(last, name);
if (count == animation)
{
*startFrame = frameCount - numFrames;
*endFrame = frameCount - 1;
return;
}
count++;
numFrames = 0;
}
frameCount++;
numFrames++;
}
*startFrame = *endFrame = 0;
}
static inline void md2_printModelInfo (md2_model_t *model) static inline void md2_printModelInfo (md2_model_t *model)
{ {
#if 0 #if 0
@ -1503,16 +1318,37 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
HWR_GetMappedPatch(gpatch, spr->colormap); HWR_GetMappedPatch(gpatch, spr->colormap);
} }
if (spr->mobj->frame & FF_ANIMATE)
{
// set duration and tics to be the correct values for FF_ANIMATE states
durs = spr->mobj->state->var2;
tics = spr->mobj->anim_duration;
}
//FIXME: this is not yet correct //FIXME: this is not yet correct
frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->header.numFrames; frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->header.numFrames;
buff = md2->model->glCommandBuffer; buff = md2->model->glCommandBuffer;
curr = &md2->model->frames[frame]; curr = &md2->model->frames[frame];
if (cv_grmd2.value == 1 if (cv_grmd2.value == 1)
&& spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL
&& !(spr->mobj->player && (spr->mobj->state->nextstate == S_PLAY_TAP1 || spr->mobj->state->nextstate == S_PLAY_TAP2) && spr->mobj->state == &states[S_PLAY_STND]))
{ {
const INT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames; // frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation
next = &md2->model->frames[nextframe]; if (spr->mobj->frame & FF_ANIMATE)
{
UINT32 nextframe = (spr->mobj->frame & FF_FRAMEMASK) + 1;
if (nextframe >= (UINT32)spr->mobj->state->var1)
nextframe = (spr->mobj->state->frame & FF_FRAMEMASK);
nextframe %= md2->model->header.numFrames;
next = &md2->model->frames[nextframe];
}
else
{
if (spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL
&& !(spr->mobj->player && (spr->mobj->state->nextstate == S_PLAY_TAP1 || spr->mobj->state->nextstate == S_PLAY_TAP2) && spr->mobj->state == &states[S_PLAY_STND]))
{
const UINT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames;
next = &md2->model->frames[nextframe];
}
}
} }
//Hurdler: it seems there is still a small problem with mobj angle //Hurdler: it seems there is still a small problem with mobj angle

File diff suppressed because it is too large Load diff

View file

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

View file

@ -85,6 +85,14 @@ static int lib_print(lua_State *L)
return 0; return 0;
} }
static int lib_evalMath(lua_State *L)
{
const char *word = luaL_checkstring(L, 1);
LUA_Deprecated(L, "EvalMath(string)", "_G[string]");
lua_pushinteger(L, LUA_EvalMath(word));
return 1;
}
// M_RANDOM // M_RANDOM
////////////// //////////////
@ -140,14 +148,38 @@ static int lib_pAproxDistance(lua_State *L)
static int lib_pClosestPointOnLine(lua_State *L) static int lib_pClosestPointOnLine(lua_State *L)
{ {
int n = lua_gettop(L);
fixed_t x = luaL_checkfixed(L, 1); fixed_t x = luaL_checkfixed(L, 1);
fixed_t y = luaL_checkfixed(L, 2); fixed_t y = luaL_checkfixed(L, 2);
line_t *line = *((line_t **)luaL_checkudata(L, 3, META_LINE));
vertex_t result; vertex_t result;
//HUDSAFE //HUDSAFE
if (!line) if (lua_isuserdata(L, 3)) // use a real linedef to get our points
return LUA_ErrInvalid(L, "line_t"); {
P_ClosestPointOnLine(x, y, line, &result); line_t *line = *((line_t **)luaL_checkudata(L, 3, META_LINE));
if (!line)
return LUA_ErrInvalid(L, "line_t");
P_ClosestPointOnLine(x, y, line, &result);
}
else // use custom coordinates of our own!
{
vertex_t v1, v2; // fake vertexes
line_t junk; // fake linedef
if (n < 6)
return luaL_error(L, "arguments 3 to 6 not all given (expected 4 fixed-point integers)");
v1.x = luaL_checkfixed(L, 3);
v1.y = luaL_checkfixed(L, 4);
v2.x = luaL_checkfixed(L, 5);
v2.y = luaL_checkfixed(L, 6);
junk.v1 = &v1;
junk.v2 = &v2;
junk.dx = v2.x - v1.x;
junk.dy = v2.y - v1.y;
P_ClosestPointOnLine(x, y, &junk, &result);
}
lua_pushfixed(L, result.x); lua_pushfixed(L, result.x);
lua_pushfixed(L, result.y); lua_pushfixed(L, result.y);
return 2; return 2;
@ -1636,18 +1668,63 @@ static int lib_sStopSound(lua_State *L)
static int lib_sChangeMusic(lua_State *L) static int lib_sChangeMusic(lua_State *L)
{ {
UINT32 music_num = (UINT32)luaL_checkinteger(L, 1); #ifdef MUSICSLOT_COMPATIBILITY
const char *music_name;
UINT32 music_num;
char music_compat_name[7];
boolean looping;
player_t *player = NULL;
UINT16 music_flags = 0;
NOHUD
if (lua_isnumber(L, 1))
{
music_num = (UINT32)luaL_checkinteger(L, 1);
music_flags = (UINT16)(music_num & 0x0000FFFF);
if (music_flags && music_flags <= 1035)
snprintf(music_compat_name, 7, "%sM", G_BuildMapName((INT32)music_flags));
else if (music_flags && music_flags <= 1050)
strncpy(music_compat_name, compat_special_music_slots[music_flags - 1036], 7);
else
music_compat_name[0] = 0; // becomes empty string
music_compat_name[6] = 0;
music_name = (const char *)&music_compat_name;
music_flags = 0;
}
else
{
music_num = 0;
music_name = luaL_checkstring(L, 1);
}
looping = (boolean)lua_opttrueboolean(L, 2);
#else
const char *music_name = luaL_checkstring(L, 1);
boolean looping = (boolean)lua_opttrueboolean(L, 2); boolean looping = (boolean)lua_opttrueboolean(L, 2);
player_t *player = NULL; player_t *player = NULL;
UINT16 music_flags = 0;
NOHUD NOHUD
#endif
if (!lua_isnone(L, 3) && lua_isuserdata(L, 3)) if (!lua_isnone(L, 3) && lua_isuserdata(L, 3))
{ {
player = *((player_t **)luaL_checkudata(L, 3, META_PLAYER)); player = *((player_t **)luaL_checkudata(L, 3, META_PLAYER));
if (!player) if (!player)
return LUA_ErrInvalid(L, "player_t"); return LUA_ErrInvalid(L, "player_t");
} }
#ifdef MUSICSLOT_COMPATIBILITY
if (music_num)
music_flags = (UINT16)((music_num & 0x7FFF0000) >> 16);
else
#endif
music_flags = (UINT16)luaL_optinteger(L, 4, 0);
if (!player || P_IsLocalPlayer(player)) if (!player || P_IsLocalPlayer(player))
S_ChangeMusic(music_num, looping); S_ChangeMusic(music_name, music_flags, looping);
return 0; return 0;
} }
@ -1854,6 +1931,7 @@ static int lib_gTicsToMilliseconds(lua_State *L)
static luaL_Reg lib[] = { static luaL_Reg lib[] = {
{"print", lib_print}, {"print", lib_print},
{"EvalMath", lib_evalMath},
// m_random // m_random
{"P_Random",lib_pRandom}, {"P_Random",lib_pRandom},

View file

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

View file

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

View file

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

View file

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

View file

@ -37,6 +37,7 @@ enum sector_e {
sector_thinglist, sector_thinglist,
sector_heightsec, sector_heightsec,
sector_camsec, sector_camsec,
sector_lines,
sector_ffloors sector_ffloors
}; };
@ -52,6 +53,7 @@ static const char *const sector_opt[] = {
"thinglist", "thinglist",
"heightsec", "heightsec",
"camsec", "camsec",
"lines",
"ffloors", "ffloors",
NULL}; NULL};
@ -260,6 +262,67 @@ static int sector_iterate(lua_State *L)
return 3; return 3;
} }
// sector.lines, i -> sector.lines[i]
// sector.lines.valid, for validity checking
static int sectorlines_get(lua_State *L)
{
line_t **seclines = *((line_t ***)luaL_checkudata(L, 1, META_SECTORLINES));
size_t i;
size_t numoflines = 0;
lua_settop(L, 2);
if (!lua_isnumber(L, 2))
{
int field = luaL_checkoption(L, 2, NULL, valid_opt);
if (!seclines)
{
if (field == 0) {
lua_pushboolean(L, 0);
return 1;
}
return luaL_error(L, "accessed sector_t doesn't exist anymore.");
} else if (field == 0) {
lua_pushboolean(L, 1);
return 1;
}
}
// check first linedef to figure which of its sectors owns this sector->lines pointer
// then check that sector's linecount to get a maximum index
//if (!seclines[0])
//return luaL_error(L, "no lines found!"); // no first linedef?????
if (seclines[0]->frontsector->lines == seclines)
numoflines = seclines[0]->frontsector->linecount;
else if (seclines[0]->backsector && seclines[0]->backsector->lines == seclines) // check backsector exists first
numoflines = seclines[0]->backsector->linecount;
//if neither sector has it then ???
if (!numoflines)
return luaL_error(L, "no lines found!");
i = (size_t)lua_tointeger(L, 2);
if (i >= numoflines)
return 0;
LUA_PushUserdata(L, seclines[i], META_LINE);
return 1;
}
static int sectorlines_num(lua_State *L)
{
line_t **seclines = *((line_t ***)luaL_checkudata(L, 1, META_SECTORLINES));
size_t numoflines = 0;
// check first linedef to figure which of its sectors owns this sector->lines pointer
// then check that sector's linecount to get a maximum index
//if (!seclines[0])
//return luaL_error(L, "no lines found!"); // no first linedef?????
if (seclines[0]->frontsector->lines == seclines)
numoflines = seclines[0]->frontsector->linecount;
else if (seclines[0]->backsector && seclines[0]->backsector->lines == seclines) // check backsector exists first
numoflines = seclines[0]->backsector->linecount;
//if neither sector has it then ???
lua_pushinteger(L, numoflines);
return 1;
}
static int sector_get(lua_State *L) static int sector_get(lua_State *L)
{ {
sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR));
@ -325,6 +388,9 @@ static int sector_get(lua_State *L)
return 0; return 0;
LUA_PushUserdata(L, &sectors[sector->camsec], META_SECTOR); LUA_PushUserdata(L, &sectors[sector->camsec], META_SECTOR);
return 1; return 1;
case sector_lines: // lines
LUA_PushUserdata(L, sector->lines, META_SECTORLINES);
return 1;
case sector_ffloors: // ffloors case sector_ffloors: // ffloors
lua_pushcfunction(L, lib_iterateSectorFFloors); lua_pushcfunction(L, lib_iterateSectorFFloors);
LUA_PushUserdata(L, sector->ffloors, META_FFLOOR); LUA_PushUserdata(L, sector->ffloors, META_FFLOOR);
@ -1111,9 +1177,13 @@ static int ffloor_set(lua_State *L)
case ffloor_bottompic: case ffloor_bottompic:
*ffloor->bottompic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3)); *ffloor->bottompic = P_AddLevelFlatRuntime(luaL_checkstring(L, 3));
break; break;
case ffloor_flags: case ffloor_flags: {
ffloortype_e oldflags = ffloor->flags; // store FOF's old flags
ffloor->flags = luaL_checkinteger(L, 3); ffloor->flags = luaL_checkinteger(L, 3);
if (ffloor->flags != oldflags)
ffloor->target->moved = true; // reset target sector's lightlist
break; break;
}
case ffloor_alpha: case ffloor_alpha:
ffloor->alpha = (INT32)luaL_checkinteger(L, 3); ffloor->alpha = (INT32)luaL_checkinteger(L, 3);
break; break;
@ -1168,10 +1238,10 @@ static int mapheaderinfo_get(lua_State *L)
lua_pushinteger(L, header->typeoflevel); lua_pushinteger(L, header->typeoflevel);
else if (fastcmp(field,"nextlevel")) else if (fastcmp(field,"nextlevel"))
lua_pushinteger(L, header->nextlevel); lua_pushinteger(L, header->nextlevel);
else if (fastcmp(field,"musicslot")) else if (fastcmp(field,"musname"))
lua_pushinteger(L, header->musicslot); lua_pushstring(L, header->musname);
else if (fastcmp(field,"musicslottrack")) else if (fastcmp(field,"mustrack"))
lua_pushinteger(L, header->musicslottrack); lua_pushinteger(L, header->mustrack);
else if (fastcmp(field,"forcecharacter")) else if (fastcmp(field,"forcecharacter"))
lua_pushstring(L, header->forcecharacter); lua_pushstring(L, header->forcecharacter);
else if (fastcmp(field,"weather")) else if (fastcmp(field,"weather"))
@ -1230,6 +1300,14 @@ static int mapheaderinfo_get(lua_State *L)
int LUA_MapLib(lua_State *L) int LUA_MapLib(lua_State *L)
{ {
luaL_newmetatable(L, META_SECTORLINES);
lua_pushcfunction(L, sectorlines_get);
lua_setfield(L, -2, "__index");
lua_pushcfunction(L, sectorlines_num);
lua_setfield(L, -2, "__len");
lua_pop(L, 1);
luaL_newmetatable(L, META_SECTOR); luaL_newmetatable(L, META_SECTOR);
lua_pushcfunction(L, sector_get); lua_pushcfunction(L, sector_get);
lua_setfield(L, -2, "__index"); lua_setfield(L, -2, "__index");

View file

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

View file

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

View file

@ -30,9 +30,9 @@
#define lua_pushfixed(L, f) lua_pushinteger(L, f) #define lua_pushfixed(L, f) lua_pushinteger(L, f)
// angle_t casting // angle_t casting
// we reduce the angle to a fixed point between 0.0 and 1.0 // TODO deal with signedness
#define luaL_checkangle(L, i) (((angle_t)(luaL_checkfixed(L, i)&0xFFFF))<<16) #define luaL_checkangle(L, i) ((angle_t)luaL_checkinteger(L, i))
#define lua_pushangle(L, a) lua_pushfixed(L, a>>16) #define lua_pushangle(L, a) lua_pushinteger(L, a)
#ifdef _DEBUG #ifdef _DEBUG
void LUA_ClearExtVars(void); void LUA_ClearExtVars(void);
@ -55,6 +55,7 @@ void Got_Luacmd(UINT8 **cp, INT32 playernum); // lua_consolelib.c
void LUA_CVarChanged(const char *name); // lua_consolelib.c void LUA_CVarChanged(const char *name); // lua_consolelib.c
int Lua_optoption(lua_State *L, int narg, int Lua_optoption(lua_State *L, int narg,
const char *def, const char *const lst[]); const char *def, const char *const lst[]);
void LUAh_NetArchiveHook(lua_CFunction archFunc);
// Console wrapper // Console wrapper
void COM_Lua_f(void); void COM_Lua_f(void);
@ -69,4 +70,15 @@ void COM_Lua_f(void);
#define LUA_ErrInvalid(L, type) luaL_error(L, "accessed " type " doesn't exist anymore, please check 'valid' before using " type "."); #define LUA_ErrInvalid(L, type) luaL_error(L, "accessed " type " doesn't exist anymore, please check 'valid' before using " type ".");
// Deprecation warnings
// Shows once upon use. Then doesn't show again.
#define LUA_Deprecated(L,this_func,use_instead)\
{\
static UINT8 seen = 0;\
if (!seen) {\
seen = 1;\
CONS_Alert(CONS_WARNING,"\"%s\" is deprecated and will be removed.\nUse \"%s\" instead.\n", this_func, use_instead);\
}\
}
#endif #endif

View file

@ -196,26 +196,6 @@ static UINT8 cht_CheckCheat(cheatseq_t *cht, char key)
return rc; return rc;
} }
static inline void cht_GetParam(cheatseq_t *cht, char *buffer)
{
UINT8 *p;
UINT8 c;
p = cht->sequence;
while (*(p++) != 1)
;
do
{
c = *p;
*(buffer++) = c;
*(p++) = 0;
} while (c && *p != 0xff);
if (*p == 0xff)
*buffer = 0;
}
boolean cht_Responder(event_t *ev) boolean cht_Responder(event_t *ev)
{ {
UINT8 ret = 0, ch = 0; UINT8 ret = 0, ch = 0;

View file

@ -2059,6 +2059,10 @@ static void M_PrevOpt(void)
} while (oldItemOn != itemOn && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_SPACE); } while (oldItemOn != itemOn && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_SPACE);
} }
// lock out further input in a tic when important buttons are pressed
// (in other words -- stop bullshit happening by mashing buttons in fades)
static boolean noFurtherInput = false;
// //
// M_Responder // M_Responder
// //
@ -2081,6 +2085,12 @@ boolean M_Responder(event_t *ev)
shiftdown = false; shiftdown = false;
return false; return false;
} }
if (noFurtherInput)
{
// Ignore input after enter/escape/other buttons
// (but still allow shift keyup so caps doesn't get stuck)
return false;
}
else if (ev->type == ev_keydown) else if (ev->type == ev_keydown)
{ {
ch = ev->data1; ch = ev->data1;
@ -2182,6 +2192,7 @@ boolean M_Responder(event_t *ev)
// F-Keys // F-Keys
if (!menuactive) if (!menuactive)
{ {
noFurtherInput = true;
switch (ch) switch (ch)
{ {
case KEY_F1: // Help key case KEY_F1: // Help key
@ -2252,6 +2263,7 @@ boolean M_Responder(event_t *ev)
M_StartControlPanel(); M_StartControlPanel();
return true; return true;
} }
noFurtherInput = false; // turns out we didn't care
return false; return false;
} }
@ -2275,6 +2287,7 @@ boolean M_Responder(event_t *ev)
if (routine) if (routine)
routine(ch); routine(ch);
M_StopMessage(0); M_StopMessage(0);
noFurtherInput = true;
return true; return true;
} }
return true; return true;
@ -2354,6 +2367,7 @@ boolean M_Responder(event_t *ev)
return true; return true;
case KEY_ENTER: case KEY_ENTER:
noFurtherInput = true;
currentMenu->lastOn = itemOn; currentMenu->lastOn = itemOn;
if (routine) if (routine)
{ {
@ -2387,6 +2401,7 @@ boolean M_Responder(event_t *ev)
return true; return true;
case KEY_ESCAPE: case KEY_ESCAPE:
noFurtherInput = true;
currentMenu->lastOn = itemOn; currentMenu->lastOn = itemOn;
if (currentMenu->prevMenu) if (currentMenu->prevMenu)
{ {
@ -2443,35 +2458,45 @@ void M_Drawer(void)
if (currentMenu == &MessageDef) if (currentMenu == &MessageDef)
menuactive = true; menuactive = true;
if (!menuactive) if (menuactive)
return;
// now that's more readable with a faded background (yeah like Quake...)
if (!WipeInAction)
V_DrawFadeScreen();
if (currentMenu->drawroutine)
currentMenu->drawroutine(); // call current menu Draw routine
// Draw version down in corner
// ... but only in the MAIN MENU. I'm a picky bastard.
if (currentMenu == &MainDef)
{ {
if (customversionstring[0] != '\0') // now that's more readable with a faded background (yeah like Quake...)
{ if (!WipeInAction)
V_DrawThinString(vid.dupx, vid.height - 17*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT, "Mod version:"); V_DrawFadeScreen();
V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, customversionstring);
} if (currentMenu->drawroutine)
else currentMenu->drawroutine(); // call current menu Draw routine
// Draw version down in corner
// ... but only in the MAIN MENU. I'm a picky bastard.
if (currentMenu == &MainDef)
{ {
if (customversionstring[0] != '\0')
{
V_DrawThinString(vid.dupx, vid.height - 17*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT, "Mod version:");
V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, customversionstring);
}
else
{
#ifdef DEVELOP // Development -- show revision / branch info #ifdef DEVELOP // Development -- show revision / branch info
V_DrawThinString(vid.dupx, vid.height - 17*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, compbranch); V_DrawThinString(vid.dupx, vid.height - 17*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, compbranch);
V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, comprevision); V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, comprevision);
#else // Regular build #else // Regular build
V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, va("%s", VERSIONSTRING)); V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, va("%s", VERSIONSTRING));
#endif #endif
}
} }
} }
// focus lost notification goes on top of everything, even the former everything
if (window_notinfocus)
{
M_DrawTextBox((BASEVIDWIDTH/2) - (60), (BASEVIDHEIGHT/2) - (16), 13, 2);
if (gamestate == GS_LEVEL && (P_AutoPause() || paused))
V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4), V_YELLOWMAP, "Game Paused");
else
V_DrawCenteredString(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) - (4), V_YELLOWMAP, "Focus Lost");
}
} }
// //
@ -2656,6 +2681,9 @@ void M_SetupNextMenu(menu_t *menudef)
// //
void M_Ticker(void) void M_Ticker(void)
{ {
// reset input trigger
noFurtherInput = false;
if (dedicated) if (dedicated)
return; return;
@ -4751,7 +4779,7 @@ static void M_SetupChoosePlayer(INT32 choice)
if (Playing() == false) if (Playing() == false)
{ {
S_StopMusic(); S_StopMusic();
S_ChangeMusic(mus_chrsel, true); S_ChangeMusicInternal("chrsel", true);
} }
SP_PlayerDef.prevMenu = currentMenu; SP_PlayerDef.prevMenu = currentMenu;
@ -5202,7 +5230,7 @@ void M_DrawTimeAttackMenu(void)
lumpnum_t lumpnum; lumpnum_t lumpnum;
char beststr[40]; char beststr[40];
S_ChangeMusic(mus_racent, true); // Eww, but needed for when user hits escape during demo playback S_ChangeMusicInternal("racent", true); // Eww, but needed for when user hits escape during demo playback
V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE));
@ -5365,7 +5393,7 @@ static void M_TimeAttack(INT32 choice)
itemOn = tastart; // "Start" is selected. itemOn = tastart; // "Start" is selected.
G_SetGamestate(GS_TIMEATTACK); G_SetGamestate(GS_TIMEATTACK);
S_ChangeMusic(mus_racent, true); S_ChangeMusicInternal("racent", true);
} }
// Drawing function for Nights Attack // Drawing function for Nights Attack
@ -5375,7 +5403,7 @@ void M_DrawNightsAttackMenu(void)
lumpnum_t lumpnum; lumpnum_t lumpnum;
char beststr[40]; char beststr[40];
S_ChangeMusic(mus_racent, true); // Eww, but needed for when user hits escape during demo playback S_ChangeMusicInternal("racent", true); // Eww, but needed for when user hits escape during demo playback
V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE));
@ -5498,7 +5526,7 @@ static void M_NightsAttack(INT32 choice)
itemOn = nastart; // "Start" is selected. itemOn = nastart; // "Start" is selected.
G_SetGamestate(GS_TIMEATTACK); G_SetGamestate(GS_TIMEATTACK);
S_ChangeMusic(mus_racent, true); S_ChangeMusicInternal("racent", true);
} }
// Player has selected the "START" from the nights attack screen // Player has selected the "START" from the nights attack screen
@ -5732,7 +5760,7 @@ static void M_ModeAttackEndGame(INT32 choice)
itemOn = currentMenu->lastOn; itemOn = currentMenu->lastOn;
G_SetGamestate(GS_TIMEATTACK); G_SetGamestate(GS_TIMEATTACK);
modeattacking = ATTACKING_NONE; modeattacking = ATTACKING_NONE;
S_ChangeMusic(mus_racent, true); S_ChangeMusicInternal("racent", true);
// Update replay availability. // Update replay availability.
CV_AddValue(&cv_nextmap, 1); CV_AddValue(&cv_nextmap, 1);
CV_AddValue(&cv_nextmap, -1); CV_AddValue(&cv_nextmap, -1);
@ -6944,7 +6972,7 @@ static void M_ToggleDigital(void)
if (nodigimusic) return; if (nodigimusic) return;
S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
S_StopMusic(); S_StopMusic();
S_ChangeMusic(mus_lclear, false); S_ChangeMusicInternal("lclear", false);
M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING); M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING);
} }
else else
@ -6971,7 +6999,7 @@ static void M_ToggleMIDI(void)
I_InitMIDIMusic(); I_InitMIDIMusic();
if (nomidimusic) return; if (nomidimusic) return;
S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value); S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
S_ChangeMusic(mus_lclear, false); S_ChangeMusicInternal("lclear", false);
M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING); M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING);
} }
else else

View file

@ -36,7 +36,7 @@
#include <stdlib.h> #include <stdlib.h>
#else #else
#ifndef HAVE_MEMCPY #ifndef HAVE_MEMCPY
#if !((defined (_WIN32) || defined (_WIN32_WCE)) && !defined (__CYGWIN__)) #if !((defined (_WIN32) || defined (_WIN32_WCE)) && !defined (__CYGWIN__)) && !defined (__APPLE__)
#define memcpy(d, s, n) bcopy ((s), (d), (n)) #define memcpy(d, s, n) bcopy ((s), (d), (n))
#endif #endif
#endif #endif

View file

@ -351,33 +351,6 @@ static INT32 GetServersList(void)
} }
#endif #endif
/** Get the MOTD from the master server.
*/
static inline INT32 GetMSMOTD(void)
{
msg_t msg;
INT32 count = 0;
msg.type = GET_MOTD_MSG;
msg.length = 0;
if (MS_Write(&msg) < 0)
return MS_WRITE_ERROR;
while (MS_Read(&msg) >= 0)
{
if (!msg.length)
{
if (!count)
CONS_Alert(CONS_NOTICE, M_GetText("No servers currently running.\n"));
return MS_NO_ERROR;
}
count++;
CONS_Printf("%s",msg.buffer);
}
return MS_READ_ERROR;
}
// //
// MS_Connect() // MS_Connect()
// //

View file

@ -3063,12 +3063,8 @@ void A_Invincibility(mobj_t *actor)
{ {
S_StopMusic(); S_StopMusic();
if (mariomode) if (mariomode)
{
S_ChangeMusic(mus_minvnc, false);
G_GhostAddColor(GHC_INVINCIBLE); G_GhostAddColor(GHC_INVINCIBLE);
} S_ChangeMusicInternal((mariomode) ? "minvnc" : "invinc", false);
else
S_ChangeMusic(mus_invinc, false);
} }
} }
@ -3104,7 +3100,7 @@ void A_SuperSneakers(mobj_t *actor)
else else
{ {
S_StopMusic(); S_StopMusic();
S_ChangeMusic(mus_shoes, false); S_ChangeMusicInternal("shoes", false);
} }
} }
} }
@ -7227,7 +7223,7 @@ void A_ChangeAngleAbsolute(mobj_t *actor)
//const angle_t amin = FixedAngle(locvar1*FRACUNIT); //const angle_t amin = FixedAngle(locvar1*FRACUNIT);
//const angle_t amax = FixedAngle(locvar2*FRACUNIT); //const angle_t amax = FixedAngle(locvar2*FRACUNIT);
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
if (LUA_CallAction("A_ChangeAngelAbsolute", actor)) if (LUA_CallAction("A_ChangeAngleAbsolute", actor))
return; return;
#endif #endif

View file

@ -1,15 +0,0 @@
// SONIC ROBO BLAST 2
//-----------------------------------------------------------------------------
// Copyright (C) 1998-2000 by DooM Legacy Team.
// Copyright (C) 1999-2014 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 p_fab.c
/// \brief some new action routines, separated from the original doom
/// sources, so that you can include it or remove it easy.
/// \todo
/// This file is now unused, please remove at some point

View file

@ -1973,71 +1973,51 @@ void T_NoEnemiesSector(levelspecthink_t *nobaddies)
{ {
size_t i; size_t i;
fixed_t upperbound, lowerbound; fixed_t upperbound, lowerbound;
sector_t *sec = NULL; INT32 s;
sector_t *targetsec = NULL; sector_t *checksector;
INT32 secnum = -1;
msecnode_t *node; msecnode_t *node;
mobj_t *thing; mobj_t *thing;
boolean FOFsector = false; boolean exists = false;
while ((secnum = P_FindSectorFromLineTag(nobaddies->sourceline, secnum)) >= 0) for (i = 0; i < nobaddies->sector->linecount; i++)
{ {
sec = &sectors[secnum]; if (nobaddies->sector->lines[i]->special == 223)
FOFsector = false;
// Check the lines of this sector, to see if it is a FOF control sector.
for (i = 0; i < sec->linecount; i++)
{ {
INT32 targetsecnum = -1;
if (sec->lines[i]->special < 100 || sec->lines[i]->special >= 300) upperbound = nobaddies->sector->ceilingheight;
continue; lowerbound = nobaddies->sector->floorheight;
FOFsector = true; for (s = -1; (s = P_FindSectorFromLineTag(nobaddies->sector->lines[i], s)) >= 0 ;)
while ((targetsecnum = P_FindSectorFromLineTag(sec->lines[i], targetsecnum)) >= 0)
{ {
targetsec = &sectors[targetsecnum]; checksector = &sectors[s];
upperbound = targetsec->ceilingheight; node = checksector->touching_thinglist; // things touching this sector
lowerbound = targetsec->floorheight;
node = targetsec->touching_thinglist; // things touching this sector
while (node) while (node)
{ {
thing = node->m_thing; thing = node->m_thing;
if ((thing->flags & (MF_ENEMY|MF_BOSS)) && thing->health > 0 if ((thing->flags & (MF_ENEMY|MF_BOSS)) && thing->health > 0
&& thing->z < upperbound && thing->z+thing->height > lowerbound) && thing->z < upperbound && thing->z+thing->height > lowerbound)
return; {
exists = true;
goto foundenemy;
}
node = node->m_snext; node = node->m_snext;
} }
} }
} }
if (!FOFsector)
{
upperbound = sec->ceilingheight;
lowerbound = sec->floorheight;
node = sec->touching_thinglist; // things touching this sector
while (node)
{
thing = node->m_thing;
if ((thing->flags & (MF_ENEMY|MF_BOSS)) && thing->health > 0
&& thing->z < upperbound && thing->z+thing->height > lowerbound)
return;
node = node->m_snext;
}
}
} }
foundenemy:
if (exists)
return;
CONS_Debug(DBG_GAMELOGIC, "Running no-more-enemies exec with tag of %d\n", nobaddies->sourceline->tag); s = P_AproxDistance(nobaddies->sourceline->dx, nobaddies->sourceline->dy)>>FRACBITS;
// No enemies found, run the linedef exec and terminate this thinker CONS_Debug(DBG_GAMELOGIC, "Running no-more-enemies exec with tag of %d\n", s);
P_RunTriggerLinedef(nobaddies->sourceline, NULL, NULL);
// Otherwise, run the linedef exec and terminate this thinker
P_LinedefExecute((INT16)s, NULL, NULL);
P_RemoveThinker(&nobaddies->thinker); P_RemoveThinker(&nobaddies->thinker);
} }

View file

@ -27,6 +27,10 @@
#include "m_misc.h" #include "m_misc.h"
#include "v_video.h" // video flags for CEchos #include "v_video.h" // video flags for CEchos
// CTF player names
#define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : ""
#define CTFTEAMENDCODE(pl) pl->ctfteam ? "\x80" : ""
void P_ForceFeed(const player_t *player, INT32 attack, INT32 fade, tic_t duration, INT32 period) void P_ForceFeed(const player_t *player, INT32 attack, INT32 fade, tic_t duration, INT32 period)
{ {
BasicFF_t Basicfeed; BasicFF_t Basicfeed;
@ -405,7 +409,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if ((maptol & TOL_NIGHTS) && special->type != MT_FLINGCOIN) if ((maptol & TOL_NIGHTS) && special->type != MT_FLINGCOIN)
P_DoNightsScore(player); P_DoNightsScore(player);
break; break;
#ifdef BLUE_SPHERES
case MT_BLUEBALL: case MT_BLUEBALL:
if (!(P_CanPickupItem(player, false))) if (!(P_CanPickupItem(player, false)))
return; return;
@ -422,7 +425,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (maptol & TOL_NIGHTS) if (maptol & TOL_NIGHTS)
P_DoNightsScore(player); P_DoNightsScore(player);
break; break;
#endif
case MT_AUTOPICKUP: case MT_AUTOPICKUP:
case MT_BOUNCEPICKUP: case MT_BOUNCEPICKUP:
case MT_SCATTERPICKUP: case MT_SCATTERPICKUP:
@ -576,11 +578,23 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
{ {
UINT8 flagteam = (special->type == MT_REDFLAG) ? 1 : 2; UINT8 flagteam = (special->type == MT_REDFLAG) ? 1 : 2;
const char *flagtext; const char *flagtext;
char flagcolor;
char plname[MAXPLAYERNAME+4];
if (special->type == MT_REDFLAG) if (special->type == MT_REDFLAG)
flagtext = M_GetText("red"); {
flagtext = M_GetText("Red flag");
flagcolor = '\x85';
}
else else
flagtext = M_GetText("blue"); {
flagtext = M_GetText("Blue flag");
flagcolor = '\x84';
}
snprintf(plname, sizeof(plname), "%s%s%s",
CTFTEAMCODE(player),
player_names[player - players],
CTFTEAMENDCODE(player));
if (player->ctfteam == flagteam) // Player is on the same team as the flag if (player->ctfteam == flagteam) // Player is on the same team as the flag
{ {
@ -594,10 +608,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (!P_PlayerTouchingSectorSpecial(player, 4, 2 + flagteam)) if (!P_PlayerTouchingSectorSpecial(player, 4, 2 + flagteam))
{ {
CONS_Printf(M_GetText("%s returned the %s flag to base.\n"), player_names[player-players], flagtext); CONS_Printf(M_GetText("%s returned the %c%s%c to base.\n"), plname, flagcolor, flagtext, 0x80);
if (players[consoleplayer].ctfteam == player->ctfteam) // The fuse code plays this sound effect
S_StartSound(NULL, sfx_hoop1); //if (players[consoleplayer].ctfteam == player->ctfteam)
// S_StartSound(NULL, sfx_hoop1);
} }
} }
} }
@ -610,7 +625,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
return; return;
player->gotflag |= flagflag; player->gotflag |= flagflag;
CONS_Printf(M_GetText("%s picked up the %s flag!\n"), player_names[player-players], flagtext); CONS_Printf(M_GetText("%s picked up the %c%s%c!\n"), plname, flagcolor, flagtext, 0x80);
(*flagmobj) = NULL; (*flagmobj) = NULL;
// code for dealing with abilities is handled elsewhere now // code for dealing with abilities is handled elsewhere now
break; break;
@ -766,10 +781,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
} }
if (!(mo2->type == MT_NIGHTSWING || mo2->type == MT_RING || mo2->type == MT_COIN if (!(mo2->type == MT_NIGHTSWING || mo2->type == MT_RING || mo2->type == MT_COIN
#ifdef BLUE_SPHERES || mo2->type == MT_BLUEBALL))
|| mo2->type == MT_BLUEBALL
#endif
))
continue; continue;
// Yay! The thing's in reach! Pull it in! // Yay! The thing's in reach! Pull it in!
@ -1452,9 +1464,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
P_KillMobj(special, NULL, toucher); P_KillMobj(special, NULL, toucher);
} }
#define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : ""
#define CTFTEAMENDCODE(pl) pl->ctfteam ? "\x80" : ""
/** Prints death messages relating to a dying or hit player. /** Prints death messages relating to a dying or hit player.
* *
* \param player Affected player. * \param player Affected player.
@ -1477,6 +1486,9 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
if (!player) if (!player)
return; // Impossible! return; // Impossible!
if (player->spectator)
return; // No messages for dying (crushed) spectators.
if (!netgame) if (!netgame)
return; // Presumably it's obvious what's happening in splitscreen. return; // Presumably it's obvious what's happening in splitscreen.
@ -2073,10 +2085,10 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
if (target->player->lives <= 0) // Tails 03-14-2000 if (target->player->lives <= 0) // Tails 03-14-2000
{ {
if (P_IsLocalPlayer(target->player) && target->player == &players[consoleplayer]) if (P_IsLocalPlayer(target->player)/* && target->player == &players[consoleplayer] */)
{ {
S_StopMusic(); // Stop the Music! Tails 03-14-2000 S_StopMusic(); // Stop the Music! Tails 03-14-2000
S_ChangeMusic(mus_gmover, false); // Yousa dead now, Okieday? Tails 03-14-2000 S_ChangeMusicInternal("gmover", false); // Yousa dead now, Okieday? Tails 03-14-2000
} }
} }
} }
@ -2464,7 +2476,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
&& player->nightstime < 10*TICRATE) && player->nightstime < 10*TICRATE)
{ {
//S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH //S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH
S_ChangeMusic(mus_drown,false); S_ChangeMusicInternal("drown",false);
} }
} }
} }
@ -3623,10 +3635,33 @@ void P_PlayerFlagBurst(player_t *player, boolean toss)
flag->fuse = cv_flagtime.value * TICRATE; flag->fuse = cv_flagtime.value * TICRATE;
P_SetTarget(&flag->target, player->mo); P_SetTarget(&flag->target, player->mo);
if (toss) // Flag text
CONS_Printf(M_GetText("%s tossed the %s flag.\n"), player_names[player-players], (type == MT_REDFLAG ? "red" : "blue")); {
else char plname[MAXPLAYERNAME+4];
CONS_Printf(M_GetText("%s dropped the %s flag.\n"), player_names[player-players], (type == MT_REDFLAG ? "red" : "blue")); char *flagtext;
char flagcolor;
snprintf(plname, sizeof(plname), "%s%s%s",
CTFTEAMCODE(player),
player_names[player - players],
CTFTEAMENDCODE(player));
if (type == MT_REDFLAG)
{
flagtext = M_GetText("Red flag");
flagcolor = '\x85';
}
else
{
flagtext = M_GetText("Blue flag");
flagcolor = '\x84';
}
if (toss)
CONS_Printf(M_GetText("%s tossed the %c%s%c.\n"), plname, flagcolor, flagtext, 0x80);
else
CONS_Printf(M_GetText("%s dropped the %c%s%c.\n"), plname, flagcolor, flagtext, 0x80);
}
player->gotflag = 0; player->gotflag = 0;

View file

@ -212,6 +212,7 @@ void P_RemoveSavegameMobj(mobj_t *th);
boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state); boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state);
boolean P_SetMobjState(mobj_t *mobj, statenum_t state); boolean P_SetMobjState(mobj_t *mobj, statenum_t state);
void P_RunShields(void); void P_RunShields(void);
void P_RunOverlays(void);
void P_MobjThinker(mobj_t *mobj); void P_MobjThinker(mobj_t *mobj);
boolean P_RailThinker(mobj_t *mobj); boolean P_RailThinker(mobj_t *mobj);
void P_PushableThinker(mobj_t *mobj); void P_PushableThinker(mobj_t *mobj);

View file

@ -1616,7 +1616,7 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
po->validcount = validcount; po->validcount = validcount;
if (!P_PointInsidePolyobj(po, x, y)) if (!P_PointInsidePolyobj(po, x, y) || !(po->flags & POF_SOLID))
{ {
plink = (polymaplink_t *)(plink->link.next); plink = (polymaplink_t *)(plink->link.next);
continue; continue;
@ -2636,8 +2636,8 @@ isblocking:
climbangle += (ANGLE_90 * (whichside ? -1 : 1)); climbangle += (ANGLE_90 * (whichside ? -1 : 1));
if (((!slidemo->player->climbing && abs((slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45) if (((!slidemo->player->climbing && abs((signed)(slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45)
|| (slidemo->player->climbing == 1 && abs((slidemo->angle - climbline)) < ANGLE_135)) || (slidemo->player->climbing == 1 && abs((signed)(slidemo->angle - climbline)) < ANGLE_135))
&& P_IsClimbingValid(slidemo->player, climbangle)) && P_IsClimbingValid(slidemo->player, climbangle))
{ {
slidemo->angle = climbangle; slidemo->angle = climbangle;
@ -3712,6 +3712,9 @@ static inline boolean PIT_GetSectors(line_t *ld)
if (P_BoxOnLineSide(tmbbox, ld) != -1) if (P_BoxOnLineSide(tmbbox, ld) != -1)
return true; return true;
if (ld->polyobj) // line belongs to a polyobject, don't add it
return true;
// This line crosses through the object. // This line crosses through the object.
// Collect the sector(s) from the line and add to the // Collect the sector(s) from the line and add to the
@ -3744,6 +3747,9 @@ static inline boolean PIT_GetPrecipSectors(line_t *ld)
if (P_BoxOnLineSide(preciptmbbox, ld) != -1) if (P_BoxOnLineSide(preciptmbbox, ld) != -1)
return true; return true;
if (ld->polyobj) // line belongs to a polyobject, don't add it
return true;
// This line crosses through the object. // This line crosses through the object.
// Collect the sector(s) from the line and add to the // Collect the sector(s) from the line and add to the

View file

@ -36,21 +36,6 @@ fixed_t P_AproxDistance(fixed_t dx, fixed_t dy)
return dx + dy - (dy>>1); return dx + dy - (dy>>1);
} }
//
// P_PartialDistance
// Useful only for iterations finding the 'closest point'
//
FUNCMATH static inline fixed_t P_PartialDistance(fixed_t dx, fixed_t dy)
{
dx >>= FRACBITS;
dy >>= FRACBITS;
dx *= dx;
dy *= dy;
return dx + dy;
}
// //
// P_ClosestPointOnLine // P_ClosestPointOnLine
// Finds the closest point on a given line to the supplied point // Finds the closest point on a given line to the supplied point

View file

@ -79,11 +79,31 @@ void P_AddCachedAction(mobj_t *mobj, INT32 statenum)
actioncachehead.prev = newaction; actioncachehead.prev = newaction;
} }
//
// P_CycleStateAnimation
//
FUNCINLINE static ATTRINLINE void P_CycleStateAnimation(mobj_t *mobj)
{
// var2 determines delay between animation frames
if (!(mobj->frame & FF_ANIMATE) || --mobj->anim_duration != 0)
return;
mobj->anim_duration = (UINT16)mobj->state->var2;
// compare the current sprite frame to the one we started from
// if more than var1 away from it, swap back to the original
// else just advance by one
if (((++mobj->frame) & FF_FRAMEMASK) - (mobj->state->frame & FF_FRAMEMASK) > (UINT32)mobj->state->var1)
mobj->frame = (mobj->state->frame & FF_FRAMEMASK) | (mobj->frame & ~FF_FRAMEMASK);
}
// //
// P_CycleMobjState // P_CycleMobjState
// //
static void P_CycleMobjState(mobj_t *mobj) static void P_CycleMobjState(mobj_t *mobj)
{ {
// state animations
P_CycleStateAnimation(mobj);
// cycle through states, // cycle through states,
// calling action functions at transitions // calling action functions at transitions
if (mobj->tics != -1) if (mobj->tics != -1)
@ -102,6 +122,9 @@ static void P_CycleMobjState(mobj_t *mobj)
// //
static void P_CyclePlayerMobjState(mobj_t *mobj) static void P_CyclePlayerMobjState(mobj_t *mobj)
{ {
// state animations
P_CycleStateAnimation(mobj);
// cycle through states, // cycle through states,
// calling action functions at transitions // calling action functions at transitions
if (mobj->tics != -1) if (mobj->tics != -1)
@ -279,6 +302,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
mobj->sprite = st->sprite; mobj->sprite = st->sprite;
mobj->frame = st->frame; mobj->frame = st->frame;
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set
// Modified handling. // Modified handling.
// Call action functions when the state is set // Call action functions when the state is set
@ -346,6 +370,7 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state)
mobj->tics = st->tics; mobj->tics = st->tics;
mobj->sprite = st->sprite; mobj->sprite = st->sprite;
mobj->frame = st->frame; mobj->frame = st->frame;
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set
// Modified handling. // Modified handling.
// Call action functions when the state is set // Call action functions when the state is set
@ -399,6 +424,8 @@ boolean P_SetMobjStateNF(mobj_t *mobj, statenum_t state)
mobj->tics = st->tics; mobj->tics = st->tics;
mobj->sprite = st->sprite; mobj->sprite = st->sprite;
mobj->frame = st->frame; mobj->frame = st->frame;
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set
return true; return true;
} }
@ -416,6 +443,8 @@ static boolean P_SetPrecipMobjState(precipmobj_t *mobj, statenum_t state)
mobj->tics = st->tics; mobj->tics = st->tics;
mobj->sprite = st->sprite; mobj->sprite = st->sprite;
mobj->frame = st->frame; mobj->frame = st->frame;
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set
return true; return true;
} }
@ -2159,9 +2188,7 @@ static boolean P_ZMovement(mobj_t *mo)
case MT_RING: // Ignore still rings case MT_RING: // Ignore still rings
case MT_COIN: case MT_COIN:
#ifdef BLUE_SPHERES
case MT_BLUEBALL: case MT_BLUEBALL:
#endif
case MT_REDTEAMRING: case MT_REDTEAMRING:
case MT_BLUETEAMRING: case MT_BLUETEAMRING:
case MT_FLINGRING: case MT_FLINGRING:
@ -3716,6 +3743,8 @@ void P_NullPrecipThinker(precipmobj_t *mobj)
void P_SnowThinker(precipmobj_t *mobj) void P_SnowThinker(precipmobj_t *mobj)
{ {
P_CycleStateAnimation((mobj_t *)mobj);
// adjust height // adjust height
if ((mobj->z += mobj->momz) <= mobj->floorz) if ((mobj->z += mobj->momz) <= mobj->floorz)
mobj->z = mobj->ceilingz; mobj->z = mobj->ceilingz;
@ -3723,6 +3752,8 @@ void P_SnowThinker(precipmobj_t *mobj)
void P_RainThinker(precipmobj_t *mobj) void P_RainThinker(precipmobj_t *mobj)
{ {
P_CycleStateAnimation((mobj_t *)mobj);
if (mobj->state != &states[S_RAIN1]) if (mobj->state != &states[S_RAIN1])
{ {
// cycle through states, // cycle through states,
@ -5833,8 +5864,6 @@ INT32 numshields = 0;
void P_RunShields(void) void P_RunShields(void)
{ {
INT32 i; INT32 i;
mobj_t *mo, *next;
fixed_t destx,desty,zoffs;
// run shields // run shields
for (i = 0; i < numshields; i++) for (i = 0; i < numshields; i++)
@ -5843,60 +5872,6 @@ void P_RunShields(void)
P_SetTarget(&shields[i], NULL); P_SetTarget(&shields[i], NULL);
} }
numshields = 0; numshields = 0;
// run overlays
next = NULL;
for (mo = overlaycap; mo; mo = next)
{
I_Assert(!P_MobjWasRemoved(mo));
// grab next in chain, then unset the chain target
next = mo->hnext;
P_SetTarget(&mo->hnext, NULL);
if (!mo->target)
continue;
if (!splitscreen /*&& rendermode != render_soft*/)
{
angle_t viewingangle;
if (players[displayplayer].awayviewtics)
viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].awayviewmobj->x, players[displayplayer].awayviewmobj->y);
else if (!camera.chase && players[displayplayer].mo)
viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].mo->x, players[displayplayer].mo->y);
else
viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, camera.x, camera.y);
if (mo->state->var1)
viewingangle += ANGLE_180;
destx = mo->target->x + P_ReturnThrustX(mo->target, viewingangle, FixedMul(FRACUNIT/4, mo->scale));
desty = mo->target->y + P_ReturnThrustY(mo->target, viewingangle, FixedMul(FRACUNIT/4, mo->scale));
}
else
{
destx = mo->target->x;
desty = mo->target->y;
}
mo->eflags = (mo->eflags & ~MFE_VERTICALFLIP) | (mo->target->eflags & MFE_VERTICALFLIP);
mo->scale = mo->destscale = mo->target->scale;
zoffs = FixedMul(((signed)mo->state->var2)*FRACUNIT, mo->scale);
mo->angle = mo->target->angle;
P_UnsetThingPosition(mo);
mo->x = destx;
mo->y = desty;
if (mo->eflags & MFE_VERTICALFLIP)
mo->z = (mo->target->z + mo->target->height - mo->height) - zoffs;
else
mo->z = mo->target->z + zoffs;
if (mo->state->var1)
P_SetUnderlayPosition(mo);
else
P_SetThingPosition(mo);
P_CheckPosition(mo, mo->x, mo->y);
}
P_SetTarget(&overlaycap, NULL);
} }
static boolean P_AddShield(mobj_t *thing) static boolean P_AddShield(mobj_t *thing)
@ -5933,6 +5908,71 @@ static boolean P_AddShield(mobj_t *thing)
return true; return true;
} }
void P_RunOverlays(void)
{
// run overlays
mobj_t *mo, *next = NULL;
fixed_t destx,desty,zoffs;
for (mo = overlaycap; mo; mo = next)
{
I_Assert(!P_MobjWasRemoved(mo));
// grab next in chain, then unset the chain target
next = mo->hnext;
P_SetTarget(&mo->hnext, NULL);
if (!mo->target)
continue;
if (!splitscreen /*&& rendermode != render_soft*/)
{
angle_t viewingangle;
if (players[displayplayer].awayviewtics)
viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].awayviewmobj->x, players[displayplayer].awayviewmobj->y);
else if (!camera.chase && players[displayplayer].mo)
viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].mo->x, players[displayplayer].mo->y);
else
viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, camera.x, camera.y);
if (!(mo->state->frame & FF_ANIMATE) && mo->state->var1)
viewingangle += ANGLE_180;
destx = mo->target->x + P_ReturnThrustX(mo->target, viewingangle, FixedMul(FRACUNIT/4, mo->scale));
desty = mo->target->y + P_ReturnThrustY(mo->target, viewingangle, FixedMul(FRACUNIT/4, mo->scale));
}
else
{
destx = mo->target->x;
desty = mo->target->y;
}
mo->eflags = (mo->eflags & ~MFE_VERTICALFLIP) | (mo->target->eflags & MFE_VERTICALFLIP);
mo->scale = mo->destscale = mo->target->scale;
mo->angle = mo->target->angle;
if (!(mo->state->frame & FF_ANIMATE))
zoffs = FixedMul(((signed)mo->state->var2)*FRACUNIT, mo->scale);
// if you're using FF_ANIMATE on an overlay,
// then you're on your own.
else
zoffs = 0;
P_UnsetThingPosition(mo);
mo->x = destx;
mo->y = desty;
if (mo->eflags & MFE_VERTICALFLIP)
mo->z = (mo->target->z + mo->target->height - mo->height) - zoffs;
else
mo->z = mo->target->z + zoffs;
if (mo->state->var1)
P_SetUnderlayPosition(mo);
else
P_SetThingPosition(mo);
P_CheckPosition(mo, mo->x, mo->y);
}
P_SetTarget(&overlaycap, NULL);
}
// Called only when MT_OVERLAY thinks. // Called only when MT_OVERLAY thinks.
static void P_AddOverlay(mobj_t *thing) static void P_AddOverlay(mobj_t *thing)
{ {
@ -6041,7 +6081,8 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->tracer && P_MobjWasRemoved(mobj->tracer)) if (mobj->tracer && P_MobjWasRemoved(mobj->tracer))
P_SetTarget(&mobj->tracer, NULL); P_SetTarget(&mobj->tracer, NULL);
mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG); mobj->flags2 &= ~MF2_PUSHED;
mobj->eflags &= ~MFE_SPRUNG;
tmfloorthing = tmhitthing = NULL; tmfloorthing = tmhitthing = NULL;
@ -6436,14 +6477,12 @@ void P_MobjThinker(mobj_t *mobj)
else if (mobj->health <= 0) // Dead things think differently than the living. else if (mobj->health <= 0) // Dead things think differently than the living.
switch (mobj->type) switch (mobj->type)
{ {
#ifdef BLUE_SPHERES
case MT_BLUEBALL: case MT_BLUEBALL:
if ((mobj->tics>>2)+1 > 0 && (mobj->tics>>2)+1 <= tr_trans60) // tr_trans50 through tr_trans90, shifting once every second frame if ((mobj->tics>>2)+1 > 0 && (mobj->tics>>2)+1 <= tr_trans60) // tr_trans50 through tr_trans90, shifting once every second frame
mobj->frame = (NUMTRANSMAPS-((mobj->tics>>2)+1))<<FF_TRANSSHIFT; mobj->frame = (NUMTRANSMAPS-((mobj->tics>>2)+1))<<FF_TRANSSHIFT;
else // tr_trans60 otherwise else // tr_trans60 otherwise
mobj->frame = tr_trans60<<FF_TRANSSHIFT; mobj->frame = tr_trans60<<FF_TRANSSHIFT;
break; break;
#endif
case MT_EGGCAPSULE: case MT_EGGCAPSULE:
if (mobj->z <= mobj->floorz) if (mobj->z <= mobj->floorz)
{ {
@ -6901,9 +6940,7 @@ void P_MobjThinker(mobj_t *mobj)
break; break;
case MT_RING: case MT_RING:
case MT_COIN: case MT_COIN:
#ifdef BLUE_SPHERES
case MT_BLUEBALL: case MT_BLUEBALL:
#endif
case MT_REDTEAMRING: case MT_REDTEAMRING:
case MT_BLUETEAMRING: case MT_BLUETEAMRING:
// No need to check water. Who cares? // No need to check water. Who cares?
@ -7112,9 +7149,10 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->type == MT_REDFLAG) if (mobj->type == MT_REDFLAG)
{ {
if (!(mobj->flags2 & MF2_JUSTATTACKED)) if (!(mobj->flags2 & MF2_JUSTATTACKED))
CONS_Printf(M_GetText("The red flag has returned to base.\n")); CONS_Printf(M_GetText("The %c%s%c has returned to base.\n"), 0x85, M_GetText("Red flag"), 0x80);
if (players[consoleplayer].ctfteam == 1) // Assumedly in splitscreen players will be on opposing teams
if (players[consoleplayer].ctfteam == 1 || splitscreen)
S_StartSound(NULL, sfx_hoop1); S_StartSound(NULL, sfx_hoop1);
redflag = flagmo; redflag = flagmo;
@ -7122,9 +7160,10 @@ void P_MobjThinker(mobj_t *mobj)
else // MT_BLUEFLAG else // MT_BLUEFLAG
{ {
if (!(mobj->flags2 & MF2_JUSTATTACKED)) if (!(mobj->flags2 & MF2_JUSTATTACKED))
CONS_Printf(M_GetText("The blue flag has returned to base.\n")); CONS_Printf(M_GetText("The %c%s%c has returned to base.\n"), 0x84, M_GetText("Blue flag"), 0x80);
if (players[consoleplayer].ctfteam == 2) // Assumedly in splitscreen players will be on opposing teams
if (players[consoleplayer].ctfteam == 2 || splitscreen)
S_StartSound(NULL, sfx_hoop1); S_StartSound(NULL, sfx_hoop1);
blueflag = flagmo; blueflag = flagmo;
@ -7502,6 +7541,8 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
mobj->tics = st->tics; mobj->tics = st->tics;
mobj->sprite = st->sprite; mobj->sprite = st->sprite;
mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits.. mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits..
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set
mobj->friction = ORIG_FRICTION; mobj->friction = ORIG_FRICTION;
mobj->movefactor = ORIG_FRICTION_FACTOR; mobj->movefactor = ORIG_FRICTION_FACTOR;
@ -7667,9 +7708,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
break; break;
case MT_RING: case MT_RING:
case MT_COIN: case MT_COIN:
#ifdef BLUE_SPHERES
case MT_BLUEBALL: case MT_BLUEBALL:
#endif
nummaprings++; nummaprings++;
default: default:
break; break;
@ -7727,6 +7766,7 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
mobj->tics = st->tics; mobj->tics = st->tics;
mobj->sprite = st->sprite; mobj->sprite = st->sprite;
mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits.. mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits..
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set
// set subsector and/or block links // set subsector and/or block links
P_SetPrecipitationThingPosition(mobj); P_SetPrecipitationThingPosition(mobj);
@ -7794,9 +7834,7 @@ void P_RemoveMobj(mobj_t *mobj)
if (mobj->spawnpoint && if (mobj->spawnpoint &&
(mobj->type == MT_RING (mobj->type == MT_RING
|| mobj->type == MT_COIN || mobj->type == MT_COIN
#ifdef BLUE_SPHERES
|| mobj->type == MT_BLUEBALL || mobj->type == MT_BLUEBALL
#endif
|| mobj->type == MT_REDTEAMRING || mobj->type == MT_REDTEAMRING
|| mobj->type == MT_BLUETEAMRING || mobj->type == MT_BLUETEAMRING
|| P_WeaponOrPanel(mobj->type)) || P_WeaponOrPanel(mobj->type))
@ -8521,6 +8559,9 @@ void P_SpawnMapThing(mapthing_t *mthing)
return; return;
} }
else if (mthing->type == 750) // Slope vertex point (formerly chaos spawn)
return;
else if (mthing->type == 300 // Ring else if (mthing->type == 300 // Ring
|| mthing->type == 308 || mthing->type == 309 // Team Rings || mthing->type == 308 || mthing->type == 309 // Team Rings
|| mthing->type == 1706 // Nights Wing || mthing->type == 1706 // Nights Wing
@ -8554,8 +8595,7 @@ void P_SpawnMapThing(mapthing_t *mthing)
if (i == NUMMOBJTYPES) if (i == NUMMOBJTYPES)
{ {
if (mthing->type == 3328 // 3D Mode start Thing if (mthing->type == 3328) // 3D Mode start Thing
|| mthing->type == 750) // Chaos mode spawn
return; return;
CONS_Alert(CONS_WARNING, M_GetText("Unknown thing type %d placed at (%d, %d)\n"), mthing->type, mthing->x, mthing->y); CONS_Alert(CONS_WARNING, M_GetText("Unknown thing type %d placed at (%d, %d)\n"), mthing->type, mthing->x, mthing->y);
i = MT_UNKNOWN; i = MT_UNKNOWN;
@ -8863,6 +8903,7 @@ void P_SpawnMapThing(mapthing_t *mthing)
const size_t mthingi = (size_t)(mthing - mapthings); const size_t mthingi = (size_t)(mthing - mapthings);
// Why does P_FindSpecialLineFromTag not work here?!? // Why does P_FindSpecialLineFromTag not work here?!?
// Monster Iestyn: tag lists haven't been initialised yet for the map, that's why
for (line = 0; line < numlines; line++) for (line = 0; line < numlines; line++)
{ {
if (lines[line].special == 9 && lines[line].tag == mthing->angle) if (lines[line].special == 9 && lines[line].tag == mthing->angle)
@ -9012,10 +9053,6 @@ ML_NOCLIMB : Direction not controllable
{ {
if (mthing->options & MTF_OBJECTSPECIAL) // No egg trap for this boss if (mthing->options & MTF_OBJECTSPECIAL) // No egg trap for this boss
mobj->flags2 |= MF2_BOSSNOTRAP; mobj->flags2 |= MF2_BOSSNOTRAP;
z = ss->sector->floorheight + ((mthing->options >> (ZSHIFT)) << FRACBITS);
mthing->z = (INT16)(z>>FRACBITS);
} }
if (i == MT_AXIS || i == MT_AXISTRANSFER || i == MT_AXISTRANSFERLINE) // Axis Points if (i == MT_AXIS || i == MT_AXISTRANSFER || i == MT_AXISTRANSFERLINE) // Axis Points
@ -9582,11 +9619,9 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
ringthing = (gametype == GT_CTF) ? MT_BLUETEAMRING : MT_RING; ringthing = (gametype == GT_CTF) ? MT_BLUETEAMRING : MT_RING;
break; break;
default: default:
#ifdef BLUE_SPHERES
// Spawn rings as blue spheres in special stages, ala S3+K. // Spawn rings as blue spheres in special stages, ala S3+K.
if (G_IsSpecialStage(gamemap) && useNightsSS) if (G_IsSpecialStage(gamemap) && useNightsSS)
ringthing = MT_BLUEBALL; ringthing = MT_BLUEBALL;
#endif
break; break;
} }
@ -9651,11 +9686,9 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
if (ultimatemode && !(G_IsSpecialStage(gamemap) || maptol & TOL_NIGHTS)) if (ultimatemode && !(G_IsSpecialStage(gamemap) || maptol & TOL_NIGHTS))
return; return;
#ifdef BLUE_SPHERES
// Spawn rings as blue spheres in special stages, ala S3+K. // Spawn rings as blue spheres in special stages, ala S3+K.
if (G_IsSpecialStage(gamemap) && useNightsSS) if (G_IsSpecialStage(gamemap) && useNightsSS)
ringthing = MT_BLUEBALL; ringthing = MT_BLUEBALL;
#endif
for (r = 1; r <= 5; r++) for (r = 1; r <= 5; r++)
{ {
@ -9706,11 +9739,9 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
if (ultimatemode && !(G_IsSpecialStage(gamemap) || maptol & TOL_NIGHTS)) if (ultimatemode && !(G_IsSpecialStage(gamemap) || maptol & TOL_NIGHTS))
return; return;
#ifdef BLUE_SPHERES
// Spawn rings as blue spheres in special stages, ala S3+K. // Spawn rings as blue spheres in special stages, ala S3+K.
if (G_IsSpecialStage(gamemap) && useNightsSS) if (G_IsSpecialStage(gamemap) && useNightsSS)
ringthing = MT_BLUEBALL; ringthing = MT_BLUEBALL;
#endif
angle >>= ANGLETOFINESHIFT; angle >>= ANGLETOFINESHIFT;
@ -9803,11 +9834,9 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
if (ultimatemode && !(G_IsSpecialStage(gamemap) || (maptol & TOL_NIGHTS))) if (ultimatemode && !(G_IsSpecialStage(gamemap) || (maptol & TOL_NIGHTS)))
continue; continue;
#ifdef BLUE_SPHERES
// Spawn rings as blue spheres in special stages, ala S3+K. // Spawn rings as blue spheres in special stages, ala S3+K.
if (G_IsSpecialStage(gamemap) && useNightsSS) if (G_IsSpecialStage(gamemap) && useNightsSS)
itemToSpawn = MT_BLUEBALL; itemToSpawn = MT_BLUEBALL;
#endif
} }
fa = i*FINEANGLES/numitems; fa = i*FINEANGLES/numitems;

View file

@ -175,23 +175,24 @@ typedef enum
MF2_EXPLOSION = 1<<7, // Thrown ring has explosive properties MF2_EXPLOSION = 1<<7, // Thrown ring has explosive properties
MF2_SCATTER = 1<<8, // Thrown ring has scatter properties MF2_SCATTER = 1<<8, // Thrown ring has scatter properties
MF2_BEYONDTHEGRAVE = 1<<9, // Source of this missile has died and has since respawned. MF2_BEYONDTHEGRAVE = 1<<9, // Source of this missile has died and has since respawned.
MF2_SLIDEPUSH = 1<<10, // MF_PUSHABLE that pushes continuously. MF2_PUSHED = 1<<10, // Mobj was already pushed this tic
MF2_CLASSICPUSH = 1<<11, // Drops straight down when object has negative Z. MF2_SLIDEPUSH = 1<<11, // MF_PUSHABLE that pushes continuously.
MF2_STANDONME = 1<<12, // While not pushable, stand on me anyway. MF2_CLASSICPUSH = 1<<12, // Drops straight down when object has negative Z.
MF2_INFLOAT = 1<<13, // Floating to a height for a move, don't auto float to target's height. MF2_STANDONME = 1<<13, // While not pushable, stand on me anyway.
MF2_DEBRIS = 1<<14, // Splash ring from explosion ring MF2_INFLOAT = 1<<14, // Floating to a height for a move, don't auto float to target's height.
MF2_NIGHTSPULL = 1<<15, // Attracted from a paraloop MF2_DEBRIS = 1<<15, // Splash ring from explosion ring
MF2_JUSTATTACKED = 1<<16, // can be pushed by other moving mobjs MF2_NIGHTSPULL = 1<<16, // Attracted from a paraloop
MF2_FIRING = 1<<17, // turret fire MF2_JUSTATTACKED = 1<<17, // can be pushed by other moving mobjs
MF2_SUPERFIRE = 1<<18, // Firing something with Super Sonic-stopping properties. Or, if mobj has MF_MISSILE, this is the actual fire from it. MF2_FIRING = 1<<18, // turret fire
MF2_SHADOW = 1<<19, // Fuzzy draw, makes targeting harder. MF2_SUPERFIRE = 1<<19, // Firing something with Super Sonic-stopping properties. Or, if mobj has MF_MISSILE, this is the actual fire from it.
MF2_STRONGBOX = 1<<20, // Flag used for "strong" random monitors. MF2_SHADOW = 1<<20, // Fuzzy draw, makes targeting harder.
MF2_OBJECTFLIP = 1<<21, // Flag for objects that always have flipped gravity. MF2_STRONGBOX = 1<<21, // Flag used for "strong" random monitors.
MF2_SKULLFLY = 1<<22, // Special handling: skull in flight. MF2_OBJECTFLIP = 1<<22, // Flag for objects that always have flipped gravity.
MF2_FRET = 1<<23, // Flashing from a previous hit MF2_SKULLFLY = 1<<23, // Special handling: skull in flight.
MF2_BOSSNOTRAP = 1<<24, // No Egg Trap after boss MF2_FRET = 1<<24, // Flashing from a previous hit
MF2_BOSSFLEE = 1<<25, // Boss is fleeing! MF2_BOSSNOTRAP = 1<<25, // No Egg Trap after boss
MF2_BOSSDEAD = 1<<26, // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.) MF2_BOSSFLEE = 1<<26, // Boss is fleeing!
MF2_BOSSDEAD = 1<<27, // Boss is dead! (Not necessarily fleeing, if a fleeing point doesn't exist.)
// free: to and including 1<<31 // free: to and including 1<<31
} mobjflag2_t; } mobjflag2_t;
@ -231,8 +232,7 @@ typedef enum
MFE_VERTICALFLIP = 1<<5, MFE_VERTICALFLIP = 1<<5,
// Goo water // Goo water
MFE_GOOWATER = 1<<6, MFE_GOOWATER = 1<<6,
// Mobj was already pushed this tic // free: to and including 1<<7
MFE_PUSHED = 1<<7,
// Mobj was already sprung this tic // Mobj was already sprung this tic
MFE_SPRUNG = 1<<8, MFE_SPRUNG = 1<<8,
// Platform movement // Platform movement
@ -270,6 +270,7 @@ typedef struct mobj_s
angle_t angle; // orientation angle_t angle; // orientation
spritenum_t sprite; // used to find patch_t and flip value spritenum_t sprite; // used to find patch_t and flip value
UINT32 frame; // frame number, plus bits see p_pspr.h UINT32 frame; // frame number, plus bits see p_pspr.h
UINT16 anim_duration; // for FF_ANIMATE states
struct msecnode_s *touching_sectorlist; // a linked list of sectors where this object appears struct msecnode_s *touching_sectorlist; // a linked list of sectors where this object appears
@ -383,7 +384,8 @@ typedef struct precipmobj_s
// More drawing info: to determine current sprite. // More drawing info: to determine current sprite.
angle_t angle; // orientation angle_t angle; // orientation
spritenum_t sprite; // used to find patch_t and flip value spritenum_t sprite; // used to find patch_t and flip value
INT32 frame; // frame number, plus bits see p_pspr.h UINT32 frame; // frame number, plus bits see p_pspr.h
UINT16 anim_duration; // for FF_ANIMATE states
struct mprecipsecnode_s *touching_sectorlist; // a linked list of sectors where this object appears struct mprecipsecnode_s *touching_sectorlist; // a linked list of sectors where this object appears

View file

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

View file

@ -1058,6 +1058,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff |= MD_SPRITE; diff |= MD_SPRITE;
if (mobj->frame != mobj->state->frame) if (mobj->frame != mobj->state->frame)
diff |= MD_FRAME; diff |= MD_FRAME;
if (mobj->anim_duration != (UINT16)mobj->state->var2)
diff |= MD_FRAME;
if (mobj->eflags) if (mobj->eflags)
diff |= MD_EFLAGS; diff |= MD_EFLAGS;
if (mobj->player) if (mobj->player)
@ -1178,7 +1180,10 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
if (diff & MD_SPRITE) if (diff & MD_SPRITE)
WRITEUINT16(save_p, mobj->sprite); WRITEUINT16(save_p, mobj->sprite);
if (diff & MD_FRAME) if (diff & MD_FRAME)
{
WRITEUINT32(save_p, mobj->frame); WRITEUINT32(save_p, mobj->frame);
WRITEUINT16(save_p, mobj->anim_duration);
}
if (diff & MD_EFLAGS) if (diff & MD_EFLAGS)
WRITEUINT16(save_p, mobj->eflags); WRITEUINT16(save_p, mobj->eflags);
if (diff & MD_PLAYER) if (diff & MD_PLAYER)
@ -2004,9 +2009,15 @@ static void LoadMobjThinker(actionf_p1 thinker)
else else
mobj->sprite = mobj->state->sprite; mobj->sprite = mobj->state->sprite;
if (diff & MD_FRAME) if (diff & MD_FRAME)
{
mobj->frame = READUINT32(save_p); mobj->frame = READUINT32(save_p);
mobj->anim_duration = READUINT16(save_p);
}
else else
{
mobj->frame = mobj->state->frame; mobj->frame = mobj->state->frame;
mobj->anim_duration = (UINT16)mobj->state->var2;
}
if (diff & MD_EFLAGS) if (diff & MD_EFLAGS)
mobj->eflags = READUINT16(save_p); mobj->eflags = READUINT16(save_p);
if (diff & MD_PLAYER) if (diff & MD_PLAYER)
@ -3192,7 +3203,7 @@ static inline boolean P_NetUnArchiveMisc(void)
// tell the sound code to reset the music since we're skipping what // tell the sound code to reset the music since we're skipping what
// normally sets this flag // normally sets this flag
mapmusic |= MUSIC_RELOADRESET; mapmusflags |= MUSIC_RELOADRESET;
G_SetGamestate(READINT16(save_p)); G_SetGamestate(READINT16(save_p));

View file

@ -180,10 +180,11 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
mapheaderinfo[num]->typeoflevel = 0; mapheaderinfo[num]->typeoflevel = 0;
DEH_WriteUndoline("NEXTLEVEL", va("%d", mapheaderinfo[num]->nextlevel), UNDO_NONE); DEH_WriteUndoline("NEXTLEVEL", va("%d", mapheaderinfo[num]->nextlevel), UNDO_NONE);
mapheaderinfo[num]->nextlevel = (INT16)(i + 1); mapheaderinfo[num]->nextlevel = (INT16)(i + 1);
DEH_WriteUndoline("MUSICSLOT", va("%d", mapheaderinfo[num]->musicslot), UNDO_NONE); DEH_WriteUndoline("MUSIC", mapheaderinfo[num]->musname, UNDO_NONE);
mapheaderinfo[num]->musicslot = mus_map01m + num; snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i));
DEH_WriteUndoline("MUSICSLOTTRACK", va("%d", mapheaderinfo[num]->musicslottrack), UNDO_NONE); mapheaderinfo[num]->musname[6] = 0;
mapheaderinfo[num]->musicslottrack = 0; DEH_WriteUndoline("MUSICTRACK", va("%d", mapheaderinfo[num]->mustrack), UNDO_NONE);
mapheaderinfo[num]->mustrack = 0;
DEH_WriteUndoline("FORCECHARACTER", va("%d", mapheaderinfo[num]->forcecharacter), UNDO_NONE); DEH_WriteUndoline("FORCECHARACTER", va("%d", mapheaderinfo[num]->forcecharacter), UNDO_NONE);
mapheaderinfo[num]->forcecharacter[0] = '\0'; mapheaderinfo[num]->forcecharacter[0] = '\0';
DEH_WriteUndoline("WEATHER", va("%d", mapheaderinfo[num]->weather), UNDO_NONE); DEH_WriteUndoline("WEATHER", va("%d", mapheaderinfo[num]->weather), UNDO_NONE);
@ -1439,6 +1440,29 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
#endif #endif
case 413: // Change music case 413: // Change music
{
char process[8+1];
sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
if (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0')
{
M_Memcpy(process,msd->bottomtexture,8);
process[8] = '\0';
sd->bottomtexture = get_number(process)-1;
}
M_Memcpy(process,msd->toptexture,8);
process[8] = '\0';
sd->text = Z_Malloc(7, PU_LEVEL, NULL);
// If they type in O_ or D_ and their music name, just shrug,
// then copy the rest instead.
if ((process[0] == 'O' || process[0] == 'D') && process[7])
M_Memcpy(sd->text, process+2, 6);
else // Assume it's a proper music name.
M_Memcpy(sd->text, process, 6);
sd->text[6] = 0;
break;
}
case 414: // Play SFX case 414: // Play SFX
{ {
sd->toptexture = sd->midtexture = sd->bottomtexture = 0; sd->toptexture = sd->midtexture = sd->bottomtexture = 0;
@ -1449,13 +1473,6 @@ static void P_LoadSideDefs2(lumpnum_t lumpnum)
process[8] = '\0'; process[8] = '\0';
sd->toptexture = get_number(process); sd->toptexture = get_number(process);
} }
if (sd->special == 413 && (msd->bottomtexture[0] != '-' || msd->bottomtexture[1] != '\0'))
{
char process[8+1];
M_Memcpy(process,msd->bottomtexture,8);
process[8] = '\0';
sd->bottomtexture = get_number(process)-1;
}
break; break;
} }
@ -1871,7 +1888,7 @@ static boolean P_LoadBlockMap(lumpnum_t lumpnum)
// //
static void P_GroupLines(void) static void P_GroupLines(void)
{ {
size_t i, j, total = 0; size_t i, j;
line_t *li; line_t *li;
sector_t *sector; sector_t *sector;
subsector_t *ss = subsectors; subsector_t *ss = subsectors;
@ -1905,14 +1922,10 @@ static void P_GroupLines(void)
// count number of lines in each sector // count number of lines in each sector
for (i = 0, li = lines; i < numlines; i++, li++) for (i = 0, li = lines; i < numlines; i++, li++)
{ {
total++;
li->frontsector->linecount++; li->frontsector->linecount++;
if (li->backsector && li->backsector != li->frontsector) if (li->backsector && li->backsector != li->frontsector)
{
li->backsector->linecount++; li->backsector->linecount++;
total++;
}
} }
// allocate linebuffers for each sector // allocate linebuffers for each sector
@ -2369,7 +2382,7 @@ boolean P_SetupLevel(boolean skipprecip)
// use gamemap to get map number. // use gamemap to get map number.
// 99% of the things already did, so. // 99% of the things already did, so.
// Map header should always be in place at this point // Map header should always be in place at this point
INT32 i, loadprecip = 1; INT32 i, loadprecip = 1, ranspecialwipe = 0;
INT32 loademblems = 1; INT32 loademblems = 1;
INT32 fromnetsave = 0; INT32 fromnetsave = 0;
boolean loadedbm = false; boolean loadedbm = false;
@ -2442,6 +2455,28 @@ boolean P_SetupLevel(boolean skipprecip)
// will be set by player think. // will be set by player think.
players[consoleplayer].viewz = 1; players[consoleplayer].viewz = 1;
// Special stage fade to white
// This is handled BEFORE sounds are stopped.
if (rendermode != render_none && G_IsSpecialStage(gamemap))
{
tic_t starttime = I_GetTime();
tic_t endtime = starttime + (3*TICRATE)/2;
S_StartSound(NULL, sfx_s3kaf);
F_WipeStartScreen();
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0);
F_WipeEndScreen();
F_RunWipe(wipedefs[wipe_speclevel_towhite], false);
// Hold on white for extra effect.
while (I_GetTime() < endtime)
I_Sleep();
ranspecialwipe = 1;
}
// Make sure all sounds are stopped before Z_FreeTags. // Make sure all sounds are stopped before Z_FreeTags.
S_StopSounds(); S_StopSounds();
S_ClearSfx(); S_ClearSfx();
@ -2451,25 +2486,28 @@ boolean P_SetupLevel(boolean skipprecip)
S_Start(); S_Start();
// Let's fade to black here // Let's fade to black here
if (rendermode != render_none) // But only if we didn't do the special stage wipe
if (rendermode != render_none && !ranspecialwipe)
{ {
F_WipeStartScreen(); F_WipeStartScreen();
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
F_WipeEndScreen(); F_WipeEndScreen();
F_RunWipe(wipedefs[wipe_level_toblack], false); F_RunWipe(wipedefs[wipe_level_toblack], false);
}
// Print "SPEEDING OFF TO [ZONE] [ACT 1]..."
if (rendermode != render_none)
{
// Don't include these in the fade! // Don't include these in the fade!
{ char tx[64];
char tx[64]; V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to..."));
V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to...")); snprintf(tx, 63, "%s%s%s",
snprintf(tx, 63, "%s%s%s", mapheaderinfo[gamemap-1]->lvlttl,
mapheaderinfo[gamemap-1]->lvlttl, (mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE",
(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE", (mapheaderinfo[gamemap-1]->actnum > 0) ? va(", Act %d",mapheaderinfo[gamemap-1]->actnum) : "");
(mapheaderinfo[gamemap-1]->actnum > 0) ? va(", Act %d",mapheaderinfo[gamemap-1]->actnum) : ""); V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx);
V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx); I_UpdateNoVsync();
I_UpdateNoVsync();
}
} }
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
@ -2767,7 +2805,7 @@ boolean P_SetupLevel(boolean skipprecip)
// Remove the loading shit from the screen // Remove the loading shit from the screen
if (rendermode != render_none) if (rendermode != render_none)
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (ranspecialwipe) ? 0 : 31);
if (precache || dedicated) if (precache || dedicated)
R_PrecacheLevel(); R_PrecacheLevel();

View file

@ -103,7 +103,7 @@ static void Add_Pusher(pushertype_e type, fixed_t x_mag, fixed_t y_mag, mobj_t *
static void Add_MasterDisappearer(tic_t appeartime, tic_t disappeartime, tic_t offset, INT32 line, INT32 sourceline); static void Add_MasterDisappearer(tic_t appeartime, tic_t disappeartime, tic_t offset, INT32 line, INT32 sourceline);
static void P_AddBlockThinker(sector_t *sec, line_t *sourceline); static void P_AddBlockThinker(sector_t *sec, line_t *sourceline);
static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline); static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline);
static void P_AddBridgeThinker(line_t *sourceline, sector_t *sec); //static void P_AddBridgeThinker(line_t *sourceline, sector_t *sec);
static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinkerlist_t *secthinkers); static void P_AddFakeFloorsByLine(size_t line, ffloortype_e ffloorflags, thinkerlist_t *secthinkers);
static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec); static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec);
static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 referrer); static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 referrer);
@ -594,6 +594,7 @@ void P_SetupLevelFlatAnims(void)
// UTILITIES // UTILITIES
// //
#if 0
/** Gets a side from a sector line. /** Gets a side from a sector line.
* *
* \param currentSector Sector the line is in. * \param currentSector Sector the line is in.
@ -633,6 +634,7 @@ static inline boolean twoSided(INT32 sector, INT32 line)
{ {
return (sectors[sector].lines[line])->sidenum[1] != 0xffff; return (sectors[sector].lines[line])->sidenum[1] != 0xffff;
} }
#endif
/** Finds sector next to current. /** Finds sector next to current.
* *
@ -1891,7 +1893,6 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
|| specialtype == 304 // Ring count - Once || specialtype == 304 // Ring count - Once
|| specialtype == 307 // Character ability - Once || specialtype == 307 // Character ability - Once
|| specialtype == 308 // Race only - Once || specialtype == 308 // Race only - Once
|| specialtype == 313 // No More Enemies - Once
|| specialtype == 315 // No of pushables - Once || specialtype == 315 // No of pushables - Once
|| specialtype == 318 // Unlockable trigger - Once || specialtype == 318 // Unlockable trigger - Once
|| specialtype == 320 // Unlockable - Once || specialtype == 320 // Unlockable - Once
@ -2390,20 +2391,19 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
// console player only unless NOCLIMB is set // console player only unless NOCLIMB is set
if ((line->flags & ML_NOCLIMB) || (mo && mo->player && P_IsLocalPlayer(mo->player))) if ((line->flags & ML_NOCLIMB) || (mo && mo->player && P_IsLocalPlayer(mo->player)))
{ {
UINT16 musicnum = (UINT16)sides[line->sidenum[0]].toptexture; //P_AproxDistance(line->dx, line->dy)>>FRACBITS;
UINT16 tracknum = (UINT16)sides[line->sidenum[0]].bottomtexture; UINT16 tracknum = (UINT16)sides[line->sidenum[0]].bottomtexture;
mapmusic = musicnum | (tracknum << MUSIC_TRACKSHIFT); strncpy(mapmusname, sides[line->sidenum[0]].text, 7);
if (!(line->flags & ML_BLOCKMONSTERS)) mapmusname[6] = 0;
mapmusic |= MUSIC_RELOADRESET;
if (musicnum >= NUMMUSIC || musicnum == mus_None) mapmusflags = tracknum & MUSIC_TRACKMASK;
S_StopMusic(); if (!(line->flags & ML_BLOCKMONSTERS))
else mapmusflags |= MUSIC_RELOADRESET;
S_ChangeMusic(mapmusic, !(line->flags & ML_EFFECT4));
S_ChangeMusic(mapmusname, mapmusflags, !(line->flags & ML_EFFECT4));
// Except, you can use the ML_BLOCKMONSTERS flag to change this behavior. // Except, you can use the ML_BLOCKMONSTERS flag to change this behavior.
// if (mapmusic & MUSIC_RELOADRESET) then it will reset the music in G_PlayerReborn. // if (mapmusflags & MUSIC_RELOADRESET) then it will reset the music in G_PlayerReborn.
} }
break; break;
@ -3039,6 +3039,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS); INT16 foftag = (INT16)(sides[line->sidenum[0]].rowoffset>>FRACBITS);
sector_t *sec; // Sector that the FOF is visible (or not visible) in sector_t *sec; // Sector that the FOF is visible (or not visible) in
ffloor_t *rover; // FOF to vanish/un-vanish ffloor_t *rover; // FOF to vanish/un-vanish
ffloortype_e oldflags; // store FOF's old flags
for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;) for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;)
{ {
@ -3062,11 +3063,17 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
return; return;
} }
oldflags = rover->flags;
// Abracadabra! // Abracadabra!
if (line->flags & ML_NOCLIMB) if (line->flags & ML_NOCLIMB)
rover->flags |= FF_EXISTS; rover->flags |= FF_EXISTS;
else else
rover->flags &= ~FF_EXISTS; rover->flags &= ~FF_EXISTS;
// if flags changed, reset sector's light list
if (rover->flags != oldflags)
sec->moved = true;
} }
} }
break; break;
@ -3774,7 +3781,7 @@ DoneSection2:
HU_SetCEchoDuration(5); HU_SetCEchoDuration(5);
HU_DoCEcho(va(M_GetText("%s\\captured the blue flag.\\\\\\\\"), player_names[player-players])); HU_DoCEcho(va(M_GetText("%s\\captured the blue flag.\\\\\\\\"), player_names[player-players]));
if (players[consoleplayer].ctfteam == 1) if (splitscreen || players[consoleplayer].ctfteam == 1)
S_StartSound(NULL, sfx_flgcap); S_StartSound(NULL, sfx_flgcap);
else if (players[consoleplayer].ctfteam == 2) else if (players[consoleplayer].ctfteam == 2)
S_StartSound(NULL, sfx_lose); S_StartSound(NULL, sfx_lose);
@ -3807,7 +3814,7 @@ DoneSection2:
HU_SetCEchoDuration(5); HU_SetCEchoDuration(5);
HU_DoCEcho(va(M_GetText("%s\\captured the red flag.\\\\\\\\"), player_names[player-players])); HU_DoCEcho(va(M_GetText("%s\\captured the red flag.\\\\\\\\"), player_names[player-players]));
if (players[consoleplayer].ctfteam == 2) if (splitscreen || players[consoleplayer].ctfteam == 2)
S_StartSound(NULL, sfx_flgcap); S_StartSound(NULL, sfx_flgcap);
else if (players[consoleplayer].ctfteam == 1) else if (players[consoleplayer].ctfteam == 1)
S_StartSound(NULL, sfx_lose); S_StartSound(NULL, sfx_lose);
@ -4974,6 +4981,7 @@ static void P_AddFloatThinker(sector_t *sec, INT32 tag, line_t *sourceline)
* \sa P_SpawnSpecials, T_BridgeThinker * \sa P_SpawnSpecials, T_BridgeThinker
* \author SSNTails <http://www.ssntails.org> * \author SSNTails <http://www.ssntails.org>
*/ */
/*
static inline void P_AddBridgeThinker(line_t *sourceline, sector_t *sec) static inline void P_AddBridgeThinker(line_t *sourceline, sector_t *sec)
{ {
levelspecthink_t *bridge; levelspecthink_t *bridge;
@ -4996,6 +5004,7 @@ static inline void P_AddBridgeThinker(line_t *sourceline, sector_t *sec)
bridge->vars[4] = sourceline->tag; // Start tag bridge->vars[4] = sourceline->tag; // Start tag
bridge->vars[5] = (sides[sourceline->sidenum[0]].textureoffset>>FRACBITS); // End tag bridge->vars[5] = (sides[sourceline->sidenum[0]].textureoffset>>FRACBITS); // End tag
} }
*/
/** Adds a Mario block thinker, which changes the block's texture between blank /** Adds a Mario block thinker, which changes the block's texture between blank
* and ? depending on whether it has contents. * and ? depending on whether it has contents.
@ -6023,31 +6032,6 @@ void P_SpawnSpecials(INT32 fromnetsave)
P_AddRaiseThinker(lines[i].frontsector, &lines[i]); P_AddRaiseThinker(lines[i].frontsector, &lines[i]);
break; break;
#ifdef SLOPENESS
case 999:
sec = sides[*lines[i].sidenum].sector-sectors;
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
{
size_t counting;
sectors[s].floorangle = ANGLE_45;
for (counting = 0; counting < sectors[s].linecount/2; counting++)
{
sectors[s].lines[counting]->v1->z = sectors[sec].floorheight;
CONS_Debug(DBG_GAMELOGIC, "Set it to %d\n", sectors[s].lines[counting]->v1->z>>FRACBITS);
}
for (counting = sectors[s].linecount/2; counting < sectors[s].linecount; counting++)
{
sectors[s].lines[counting]->v1->z = sectors[sec].ceilingheight;
CONS_Debug(DBG_GAMELOGIC, "Set it to %d\n", sectors[s].lines[counting]->v1->z>>FRACBITS);
}
sectors[s].special = 65535;
CONS_Debug(DBG_GAMELOGIC, "Found & Set slope!\n");
}
break;
#endif
case 200: // Double light effect case 200: // Double light effect
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_CUTSPRITES|FF_DOUBLESHADOW, secthinkers); P_AddFakeFloorsByLine(i, FF_EXISTS|FF_CUTSPRITES|FF_DOUBLESHADOW, secthinkers);
break; break;
@ -6462,7 +6446,7 @@ static void P_DoScrollMove(mobj_t *thing, fixed_t dx, fixed_t dy, INT32 exclusiv
thing->momy += dy; thing->momy += dy;
if (exclusive) if (exclusive)
thing->eflags |= MFE_PUSHED; thing->flags2 |= MF2_PUSHED;
} }
/** Processes an active scroller. /** Processes an active scroller.
@ -6566,7 +6550,7 @@ void T_Scroll(scroll_t *s)
{ {
thing = node->m_thing; thing = node->m_thing;
if (thing->eflags & MFE_PUSHED) // Already pushed this tic by an exclusive pusher. if (thing->flags2 & MF2_PUSHED) // Already pushed this tic by an exclusive pusher.
continue; continue;
height = P_GetSpecialBottomZ(thing, sec, psec); height = P_GetSpecialBottomZ(thing, sec, psec);
@ -6588,7 +6572,7 @@ void T_Scroll(scroll_t *s)
{ {
thing = node->m_thing; thing = node->m_thing;
if (thing->eflags & MFE_PUSHED) if (thing->flags2 & MF2_PUSHED)
continue; continue;
height = P_GetSpecialBottomZ(thing, sec, sec); height = P_GetSpecialBottomZ(thing, sec, sec);
@ -6629,7 +6613,7 @@ void T_Scroll(scroll_t *s)
{ {
thing = node->m_thing; thing = node->m_thing;
if (thing->eflags & MFE_PUSHED) if (thing->flags2 & MF2_PUSHED)
continue; continue;
height = P_GetSpecialTopZ(thing, sec, psec); height = P_GetSpecialTopZ(thing, sec, psec);
@ -6651,7 +6635,7 @@ void T_Scroll(scroll_t *s)
{ {
thing = node->m_thing; thing = node->m_thing;
if (thing->eflags & MFE_PUSHED) if (thing->flags2 & MF2_PUSHED)
continue; continue;
height = P_GetSpecialTopZ(thing, sec, sec); height = P_GetSpecialTopZ(thing, sec, sec);
@ -7134,7 +7118,7 @@ static pusher_t *tmpusher; // pusher structure for blockmap searches
*/ */
static inline boolean PIT_PushThing(mobj_t *thing) static inline boolean PIT_PushThing(mobj_t *thing)
{ {
if (thing->eflags & MFE_PUSHED) if (thing->flags2 & MF2_PUSHED)
return false; return false;
if (thing->player && thing->player->pflags & PF_ROPEHANG) if (thing->player && thing->player->pflags & PF_ROPEHANG)
@ -7264,7 +7248,7 @@ static inline boolean PIT_PushThing(mobj_t *thing)
} }
if (tmpusher->exclusive) if (tmpusher->exclusive)
thing->eflags |= MFE_PUSHED; thing->flags2 |= MF2_PUSHED;
return true; return true;
} }
@ -7367,7 +7351,7 @@ void T_Pusher(pusher_t *p)
|| thing->type == MT_BIGTUMBLEWEED)) || thing->type == MT_BIGTUMBLEWEED))
continue; continue;
if (thing->eflags & MFE_PUSHED) if (thing->flags2 & MF2_PUSHED)
continue; continue;
if (thing->player && thing->player->pflags & PF_ROPEHANG) if (thing->player && thing->player->pflags & PF_ROPEHANG)
@ -7534,7 +7518,7 @@ void T_Pusher(pusher_t *p)
} }
if (p->exclusive) if (p->exclusive)
thing->eflags |= MFE_PUSHED; thing->flags2 |= MF2_PUSHED;
} }
} }
} }

View file

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

View file

@ -962,7 +962,7 @@ void P_DoSuperTransformation(player_t *player, boolean giverings)
if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC) && P_IsLocalPlayer(player)) if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC) && P_IsLocalPlayer(player))
{ {
S_StopMusic(); S_StopMusic();
S_ChangeMusic(mus_supers, true); S_ChangeMusicInternal("supers", true);
} }
S_StartSound(NULL, sfx_supert); //let all players hear it -mattw_cfi S_StartSound(NULL, sfx_supert); //let all players hear it -mattw_cfi
@ -1098,7 +1098,7 @@ void P_PlayLivesJingle(player_t *player)
if (player) if (player)
player->powers[pw_extralife] = extralifetics + 1; player->powers[pw_extralife] = extralifetics + 1;
S_StopMusic(); // otherwise it won't restart if this is done twice in a row S_StopMusic(); // otherwise it won't restart if this is done twice in a row
S_ChangeMusic(mus_xtlife, false); S_ChangeMusicInternal("xtlife", false);
} }
} }
@ -1116,21 +1116,21 @@ void P_RestoreMusic(player_t *player)
return; return;
S_SpeedMusic(1.0f); S_SpeedMusic(1.0f);
if (player->powers[pw_super] && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC)) if (player->powers[pw_super] && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC))
S_ChangeMusic(mus_supers, true); S_ChangeMusicInternal("supers", true);
else if (player->powers[pw_invulnerability] > 1) else if (player->powers[pw_invulnerability] > 1)
S_ChangeMusic((mariomode) ? mus_minvnc : mus_invinc, false); S_ChangeMusicInternal((mariomode) ? "minvnc" : "invinc", false);
else if (player->powers[pw_sneakers] > 1 && !player->powers[pw_super]) else if (player->powers[pw_sneakers] > 1 && !player->powers[pw_super])
{ {
if (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC) if (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC)
{ {
S_SpeedMusic(1.4f); S_SpeedMusic(1.4f);
S_ChangeMusic(mapmusic, true); S_ChangeMusic(mapmusname, mapmusflags, true);
} }
else else
S_ChangeMusic(mus_shoes, true); S_ChangeMusicInternal("shoes", true);
} }
else else
S_ChangeMusic(mapmusic, true); S_ChangeMusic(mapmusname, mapmusflags, true);
} }
// //
@ -2039,7 +2039,7 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player)
mobj_t *killer; mobj_t *killer;
if ((netgame || multiplayer) && P_IsLocalPlayer(player)) if ((netgame || multiplayer) && P_IsLocalPlayer(player))
S_ChangeMusic(mapmusic, true); S_ChangeMusic(mapmusname, mapmusflags, true);
killer = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_NULL); killer = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_NULL);
killer->threshold = 42; // Special flag that it was drowning which killed you. killer->threshold = 42; // Special flag that it was drowning which killed you.
@ -2048,7 +2048,7 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player)
else if (player->powers[pw_spacetime] == 1) else if (player->powers[pw_spacetime] == 1)
{ {
if ((netgame || multiplayer) && P_IsLocalPlayer(player)) if ((netgame || multiplayer) && P_IsLocalPlayer(player))
S_ChangeMusic(mapmusic, true); S_ChangeMusic(mapmusname, mapmusflags, true);
P_DamageMobj(player->mo, NULL, NULL, 10000); P_DamageMobj(player->mo, NULL, NULL, 10000);
} }
@ -2083,7 +2083,7 @@ static void P_CheckUnderwaterAndSpaceTimer(player_t *player)
&& player == &players[consoleplayer]) && player == &players[consoleplayer])
{ {
S_StopMusic(); S_StopMusic();
S_ChangeMusic(mus_drown, false); S_ChangeMusicInternal("drown", false);
} }
if (player->powers[pw_underwater] == 25*TICRATE + 1) if (player->powers[pw_underwater] == 25*TICRATE + 1)
@ -3087,7 +3087,7 @@ static void P_DoTeeter(player_t *player)
} }
if (polybottom > player->mo->z + player->mo->height + tiptop if (polybottom > player->mo->z + player->mo->height + tiptop
|| (polybottom < player->mo->z || (polytop < player->mo->z
&& player->mo->z + player->mo->height < player->mo->ceilingz - tiptop)) && player->mo->z + player->mo->height < player->mo->ceilingz - tiptop))
teeter = true; teeter = true;
else else
@ -3105,7 +3105,7 @@ static void P_DoTeeter(player_t *player)
} }
if (polytop < player->mo->z - tiptop if (polytop < player->mo->z - tiptop
|| (polytop > player->mo->z + player->mo->height || (polybottom > player->mo->z + player->mo->height
&& player->mo->z > player->mo->floorz + tiptop)) && player->mo->z > player->mo->floorz + tiptop))
teeter = true; teeter = true;
else else
@ -3442,27 +3442,14 @@ static void P_DoSuperStuff(player_t *player)
player->mo->health--; player->mo->health--;
} }
// future todo: a skin option for this, and possibly more colors
switch (player->skin) switch (player->skin)
{ {
case 1: // Golden orange supertails. case 1: /* Tails */ player->mo->color = SKINCOLOR_TSUPER1; break;
if (leveltime % 9 < 5) case 2: /* Knux */ player->mo->color = SKINCOLOR_KSUPER1; break;
player->mo->color = SKINCOLOR_TSUPER1 + leveltime % 9; default: /* everyone */ player->mo->color = SKINCOLOR_SUPER1; break;
else
player->mo->color = SKINCOLOR_TSUPER1 + 9 - leveltime % 9;
break;
case 2: // Pink superknux.
if (leveltime % 9 < 5)
player->mo->color = SKINCOLOR_KSUPER1 + leveltime % 9;
else
player->mo->color = SKINCOLOR_KSUPER1 + 9 - leveltime % 9;
break;
default: // Yousa yellow now!
if (leveltime % 9 < 5)
player->mo->color = SKINCOLOR_SUPER1 + leveltime % 9;
else
player->mo->color = SKINCOLOR_SUPER1 + 9 - leveltime % 9;
break;
} }
player->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4);
if ((cmd->forwardmove != 0 || cmd->sidemove != 0 || player->pflags & (PF_CARRIED|PF_ROPEHANG|PF_ITEMHANG|PF_MACESPIN)) if ((cmd->forwardmove != 0 || cmd->sidemove != 0 || player->pflags & (PF_CARRIED|PF_ROPEHANG|PF_ITEMHANG|PF_MACESPIN))
&& !(leveltime % TICRATE) && (player->mo->momx || player->mo->momy)) && !(leveltime % TICRATE) && (player->mo->momx || player->mo->momy))
@ -5592,7 +5579,7 @@ static void P_NiGHTSMovement(player_t *player)
} }
else if (P_IsLocalPlayer(player) && player->nightstime == 10*TICRATE) else if (P_IsLocalPlayer(player) && player->nightstime == 10*TICRATE)
// S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH // S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH
S_ChangeMusic(mus_drown,false); S_ChangeMusicInternal("drown",false);
if (player->mo->z < player->mo->floorz) if (player->mo->z < player->mo->floorz)
@ -7729,8 +7716,25 @@ static void P_DeathThink(player_t *player)
} }
// Return to level music // Return to level music
if (netgame && player->deadtimer == gameovertics && P_IsLocalPlayer(player)) if (player->lives <= 0)
S_ChangeMusic(mapmusic, true); {
if (netgame)
{
if (player->deadtimer == gameovertics && P_IsLocalPlayer(player))
S_ChangeMusic(mapmusname, mapmusflags, true);
}
else if (multiplayer) // local multiplayer only
{
if (player->deadtimer != gameovertics)
;
// Restore the other player's music once we're dead for long enough
// -- that is, as long as they aren't dead too
else if (player == &players[displayplayer] && players[secondarydisplayplayer].lives > 0)
P_RestoreMusic(&players[secondarydisplayplayer]);
else if (player == &players[secondarydisplayplayer] && players[displayplayer].lives > 0)
P_RestoreMusic(&players[displayplayer]);
}
}
} }
if (!player->mo) if (!player->mo)
@ -7965,9 +7969,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
if (player == &players[consoleplayer]) if (player == &players[consoleplayer])
{ {
if (focusangle >= localangle) if (focusangle >= localangle)
localangle += abs((focusangle - localangle))>>5; localangle += abs((signed)(focusangle - localangle))>>5;
else else
localangle -= abs((focusangle - localangle))>>5; localangle -= abs((signed)(focusangle - localangle))>>5;
} }
} }
else if (P_AnalogMove(player)) // Analog else if (P_AnalogMove(player)) // Analog
@ -8176,7 +8180,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
po->validcount = validcount; po->validcount = validcount;
if (!P_PointInsidePolyobj(po, x, y)) if (!P_PointInsidePolyobj(po, x, y) || !(po->flags & POF_SOLID))
{ {
plink = (polymaplink_t *)(plink->link.next); plink = (polymaplink_t *)(plink->link.next);
continue; continue;
@ -8452,9 +8456,9 @@ static boolean P_SpectatorJoinGame(player_t *player)
displayplayer = consoleplayer; displayplayer = consoleplayer;
if (changeto == 1) if (changeto == 1)
CONS_Printf(M_GetText("%s switched to the %c%s%c.\n"), player_names[player-players], '\x85', M_GetText("Red Team"), '\x80'); CONS_Printf(M_GetText("%s switched to the %c%s%c.\n"), player_names[player-players], '\x85', M_GetText("Red team"), '\x80');
else if (changeto == 2) else if (changeto == 2)
CONS_Printf(M_GetText("%s switched to the %c%s%c.\n"), player_names[player-players], '\x84', M_GetText("Blue Team"), '\x80'); CONS_Printf(M_GetText("%s switched to the %c%s%c.\n"), player_names[player-players], '\x84', M_GetText("Blue team"), '\x80');
return true; // no more player->mo, cannot continue. return true; // no more player->mo, cannot continue.
} }
@ -8716,7 +8720,7 @@ void P_PlayerThink(player_t *player)
if (countdown == 11*TICRATE - 1) if (countdown == 11*TICRATE - 1)
{ {
if (P_IsLocalPlayer(player)) if (P_IsLocalPlayer(player))
S_ChangeMusic(mus_drown, false); S_ChangeMusicInternal("drown", false);
} }
// If you've hit the countdown and you haven't made // If you've hit the countdown and you haven't made
@ -8870,10 +8874,7 @@ void P_PlayerThink(player_t *player)
mo2 = (mobj_t *)th; mo2 = (mobj_t *)th;
if (!(mo2->type == MT_NIGHTSWING || mo2->type == MT_RING || mo2->type == MT_COIN if (!(mo2->type == MT_NIGHTSWING || mo2->type == MT_RING || mo2->type == MT_COIN
#ifdef BLUE_SPHERES || mo2->type == MT_BLUEBALL))
|| mo2->type == MT_BLUEBALL
#endif
))
continue; continue;
if (P_AproxDistance(P_AproxDistance(mo2->x - x, mo2->y - y), mo2->z - z) > FixedMul(128*FRACUNIT, player->mo->scale)) if (P_AproxDistance(P_AproxDistance(mo2->x - x, mo2->y - y), mo2->z - z) > FixedMul(128*FRACUNIT, player->mo->scale))

View file

@ -26,6 +26,7 @@ side_t *sidedef;
line_t *linedef; line_t *linedef;
sector_t *frontsector; sector_t *frontsector;
sector_t *backsector; sector_t *backsector;
boolean portalline; // is curline a portal seg?
// very ugly realloc() of drawsegs at run-time, I upped it to 512 // very ugly realloc() of drawsegs at run-time, I upped it to 512
// instead of 256.. and someone managed to send me a level with // instead of 256.. and someone managed to send me a level with
@ -378,6 +379,7 @@ static void R_AddLine(seg_t *line)
return; return;
curline = line; curline = line;
portalline = false;
// OPTIMIZE: quickly reject orthogonal back sides. // OPTIMIZE: quickly reject orthogonal back sides.
angle1 = R_PointToAngle(line->v1->x, line->v1->y); angle1 = R_PointToAngle(line->v1->x, line->v1->y);
@ -431,7 +433,7 @@ static void R_AddLine(seg_t *line)
backsector = line->backsector; backsector = line->backsector;
// Portal line // Portal line
if (line->linedef->special == 40 && P_PointOnLineSide(viewx, viewy, line->linedef) == 0) if (line->linedef->special == 40 && line->side == 0)
{ {
if (portalrender < cv_maxportals.value) if (portalrender < cv_maxportals.value)
{ {

View file

@ -23,6 +23,7 @@ extern side_t *sidedef;
extern line_t *linedef; extern line_t *linedef;
extern sector_t *frontsector; extern sector_t *frontsector;
extern sector_t *backsector; extern sector_t *backsector;
extern boolean portalline; // is curline a portal seg?
// drawsegs are allocated on the fly... see r_segs.c // drawsegs are allocated on the fly... see r_segs.c

View file

@ -369,14 +369,6 @@ typedef struct sector_s
double lineoutLength; double lineoutLength;
#endif // ----- end special tricks ----- #endif // ----- end special tricks -----
// ZDoom C++ to Legacy C conversion (for slopes)
// store floor and ceiling planes instead of heights
//secplane_t floorplane, ceilingplane;
#ifdef SLOPENESS
//fixed_t floortexz, ceilingtexz; // [RH] used for wall texture mapping
angle_t floorangle;
#endif
// This points to the master's floorheight, so it can be changed in realtime! // This points to the master's floorheight, so it can be changed in realtime!
fixed_t *gravity; // per-sector gravity fixed_t *gravity; // per-sector gravity
boolean verticalflip; // If gravity < 0, then allow flipped physics boolean verticalflip; // If gravity < 0, then allow flipped physics
@ -675,6 +667,8 @@ typedef struct drawseg_s
INT32 numthicksides; INT32 numthicksides;
fixed_t frontscale[MAXVIDWIDTH]; fixed_t frontscale[MAXVIDWIDTH];
UINT8 portalpass; // if > 0 and <= portalrender, do not affect sprite clipping
#ifdef ESLOPE #ifdef ESLOPE
fixed_t maskedtextureheight[MAXVIDWIDTH]; // For handling sloped midtextures fixed_t maskedtextureheight[MAXVIDWIDTH]; // For handling sloped midtextures

View file

@ -91,7 +91,6 @@ typedef struct portal_pair
INT16 *ceilingclip; INT16 *ceilingclip;
INT16 *floorclip; INT16 *floorclip;
fixed_t *frontscale; fixed_t *frontscale;
size_t seg;
} portal_pair; } portal_pair;
portal_pair *portal_base, *portal_cap; portal_pair *portal_base, *portal_cap;
line_t *portalclipline; line_t *portalclipline;
@ -1230,7 +1229,7 @@ void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2)
portal->start = x1; portal->start = x1;
portal->end = x2; portal->end = x2;
portal->seg = ds_p-drawsegs; portalline = true; // this tells R_StoreWallRange that curline is a portal seg
portal->viewx = viewx; portal->viewx = viewx;
portal->viewy = viewy; portal->viewy = viewy;
@ -1344,14 +1343,6 @@ void R_RenderPlayerView(player_t *player)
validcount++; validcount++;
if (portal->seg)
{
// Push the portal's old drawseg out of the way so it isn't interfering with sprite clipping. -Red
drawseg_t *seg = drawsegs+portal->seg;
seg->scale1 = 0;
seg->scale2 = 0;
}
R_RenderBSPNode((INT32)numnodes - 1); R_RenderBSPNode((INT32)numnodes - 1);
R_ClipSprites(); R_ClipSprites();
//R_DrawPlanes(); //R_DrawPlanes();
@ -1360,6 +1351,9 @@ void R_RenderPlayerView(player_t *player)
// okay done. free it. // okay done. free it.
portalcullsector = NULL; // Just in case... portalcullsector = NULL; // Just in case...
portal_base = portal->next; portal_base = portal->next;
Z_Free(portal->ceilingclip);
Z_Free(portal->floorclip);
Z_Free(portal->frontscale);
Z_Free(portal); Z_Free(portal);
} }
// END PORTAL RENDERING // END PORTAL RENDERING
@ -1388,6 +1382,7 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_allowmlook); CV_RegisterVar(&cv_allowmlook);
CV_RegisterVar(&cv_homremoval); CV_RegisterVar(&cv_homremoval);
CV_RegisterVar(&cv_flipcam); CV_RegisterVar(&cv_flipcam);
CV_RegisterVar(&cv_flipcam2);
// Enough for dedicated server // Enough for dedicated server
if (dedicated) if (dedicated)

View file

@ -198,7 +198,7 @@ static void R_DrawWallSplats(void)
// draw the columns // draw the columns
for (dc_x = x1; dc_x <= x2; dc_x++, spryscale += rw_scalestep) for (dc_x = x1; dc_x <= x2; dc_x++, spryscale += rw_scalestep)
{ {
pindex = spryscale>>LIGHTSCALESHIFT; pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT;
if (pindex >= MAXLIGHTSCALE) if (pindex >= MAXLIGHTSCALE)
pindex = MAXLIGHTSCALE - 1; pindex = MAXLIGHTSCALE - 1;
dc_colormap = walllights[pindex]; dc_colormap = walllights[pindex];
@ -942,7 +942,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
else else
xwalllights = scalelight[lightnum]; xwalllights = scalelight[lightnum];
pindex = spryscale>>LIGHTSCALESHIFT; pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT;
if (pindex >= MAXLIGHTSCALE) if (pindex >= MAXLIGHTSCALE)
pindex = MAXLIGHTSCALE-1; pindex = MAXLIGHTSCALE-1;
@ -1030,7 +1030,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
} }
// calculate lighting // calculate lighting
pindex = spryscale>>LIGHTSCALESHIFT; pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT;
if (pindex >= MAXLIGHTSCALE) if (pindex >= MAXLIGHTSCALE)
pindex = MAXLIGHTSCALE - 1; pindex = MAXLIGHTSCALE - 1;
@ -1922,7 +1922,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|| backsector->ceilingpic_angle != frontsector->ceilingpic_angle || backsector->ceilingpic_angle != frontsector->ceilingpic_angle
//SoM: 3/22/2000: Prevents bleeding. //SoM: 3/22/2000: Prevents bleeding.
|| (frontsector->heightsec != -1 && frontsector->ceilingpic != skyflatnum) || (frontsector->heightsec != -1 && frontsector->ceilingpic != skyflatnum)
|| backsector->floorlightsec != frontsector->floorlightsec || backsector->ceilinglightsec != frontsector->ceilinglightsec
//SoM: 4/3/2000: Check for colormaps //SoM: 4/3/2000: Check for colormaps
|| frontsector->extra_colormap != backsector->extra_colormap || frontsector->extra_colormap != backsector->extra_colormap
|| (frontsector->ffloors != backsector->ffloors && frontsector->tag != backsector->tag)) || (frontsector->ffloors != backsector->ffloors && frontsector->tag != backsector->tag))
@ -2887,6 +2887,11 @@ void R_StoreWallRange(INT32 start, INT32 stop)
R_RenderSegLoop(); R_RenderSegLoop();
colfunc = wallcolfunc; colfunc = wallcolfunc;
if (portalline) // if curline is a portal, set portalrender for drawseg
ds_p->portalpass = portalrender+1;
else
ds_p->portalpass = 0;
// save sprite clipping info // save sprite clipping info
if (((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip) if (((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip)
{ {

View file

@ -551,11 +551,6 @@ void R_ClearSprites(void)
visspritecount = clippedvissprites = 0; visspritecount = clippedvissprites = 0;
} }
static inline void R_ResetVisSpriteChunks(void)
{
memset(visspritechunks, 0, sizeof(visspritechunks));
}
// //
// R_NewVisSprite // R_NewVisSprite
// //
@ -839,10 +834,10 @@ static void R_DrawVisSprite(vissprite_t *vis)
dc_texturemid = FixedDiv(dc_texturemid,this_scale); dc_texturemid = FixedDiv(dc_texturemid,this_scale);
//Oh lordy, mercy me. Don't freak out if sprites go offscreen! //Oh lordy, mercy me. Don't freak out if sprites go offscreen!
if (vis->xiscale > 0) /*if (vis->xiscale > 0)
frac = FixedDiv(frac, this_scale); frac = FixedDiv(frac, this_scale);
else if (vis->x1 <= 0) else if (vis->x1 <= 0)
frac = (vis->x1 - vis->x2) * vis->xiscale; frac = (vis->x1 - vis->x2) * vis->xiscale;*/
sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
//dc_hires = 1; //dc_hires = 1;
@ -1018,7 +1013,7 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing)
if (!((thing->frame & (FF_FULLBRIGHT|FF_TRANSMASK) || thing->flags2 & MF2_SHADOW) if (!((thing->frame & (FF_FULLBRIGHT|FF_TRANSMASK) || thing->flags2 & MF2_SHADOW)
&& (!newsprite->extra_colormap || !newsprite->extra_colormap->fog))) && (!newsprite->extra_colormap || !newsprite->extra_colormap->fog)))
{ {
lindex = sprite->xscale>>(LIGHTSCALESHIFT); lindex = FixedMul(sprite->xscale, FixedDiv(640, vid.width))>>(LIGHTSCALESHIFT);
if (lindex >= MAXLIGHTSCALE) if (lindex >= MAXLIGHTSCALE)
lindex = MAXLIGHTSCALE-1; lindex = MAXLIGHTSCALE-1;
@ -1306,7 +1301,7 @@ static void R_ProjectSprite(mobj_t *thing)
} }
if (vis->x1 > x1) if (vis->x1 > x1)
vis->startfrac += vis->xiscale*(vis->x1-x1); vis->startfrac += FixedDiv(vis->xiscale, this_scale)*(vis->x1-x1);
//Fab: lumppat is the lump number of the patch to use, this is different //Fab: lumppat is the lump number of the patch to use, this is different
// than lumpid for sprites-in-pwad : the graphics are patched // than lumpid for sprites-in-pwad : the graphics are patched
@ -1334,7 +1329,7 @@ static void R_ProjectSprite(mobj_t *thing)
else else
{ {
// diminished light // diminished light
lindex = xscale>>(LIGHTSCALESHIFT); lindex = FixedMul(xscale, FixedDiv(640, vid.width))>>(LIGHTSCALESHIFT);
if (lindex >= MAXLIGHTSCALE) if (lindex >= MAXLIGHTSCALE)
lindex = MAXLIGHTSCALE-1; lindex = MAXLIGHTSCALE-1;
@ -2058,6 +2053,9 @@ void R_ClipSprites(void)
continue; continue;
} }
if (ds->portalpass > 0 && ds->portalpass <= portalrender)
continue; // is a portal
r1 = ds->x1 < spr->x1 ? spr->x1 : ds->x1; r1 = ds->x1 < spr->x1 ? spr->x1 : ds->x1;
r2 = ds->x2 > spr->x2 ? spr->x2 : ds->x2; r2 = ds->x2 > spr->x2 ? spr->x2 : ds->x2;
@ -2698,9 +2696,6 @@ next_token:
} }
free(buf2); free(buf2);
// Not in vanilla, you don't.
skin->flags &= ~SF_SUPER;
lump++; // if no sprite defined use spirte just after this one lump++; // if no sprite defined use spirte just after this one
if (skin->sprite[0] == '\0') if (skin->sprite[0] == '\0')
{ {

View file

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

View file

@ -48,9 +48,6 @@ typedef enum
extern consvar_t play_mode; extern consvar_t play_mode;
#endif #endif
//in case you're wondering why: I need to define this as extern so P_RestoreMusic can get to it so we don't do stupid song/speed changes
extern musicinfo_t *mus_playing;
typedef enum typedef enum
{ {
SF_TOTALLYSINGLE = 1, // Only play one of these sounds at a time...GLOBALLY SF_TOTALLYSINGLE = 1, // Only play one of these sounds at a time...GLOBALLY
@ -100,11 +97,12 @@ void S_StartSoundAtVolume(const void *origin, sfxenum_t sound_id, INT32 volume);
// Stop sound for thing at <origin> // Stop sound for thing at <origin>
void S_StopSound(void *origin); void S_StopSound(void *origin);
// Start music using <music_id> from sounds.h, and set whether looping // Start music track, arbitrary, given its name, and set whether looping
// note: music slot is first 16 bits for songnum, // note: music flags 12 bits for tracknum (gme, other formats with more than one track)
// next 15 bits for tracknum (gme, other formats with more than one track) // 13-15 aren't used yet
// and the last bit we ignore (internal game flag for resetting music on reload) // and the last bit we ignore (internal game flag for resetting music on reload)
void S_ChangeMusic(UINT32 mslotnum, boolean looping); #define S_ChangeMusicInternal(a,b) S_ChangeMusic(a,0,b)
void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping);
// Set Speed of Music // Set Speed of Music
boolean S_SpeedMusic(float speed); boolean S_SpeedMusic(float speed);
@ -113,8 +111,8 @@ boolean S_SpeedMusic(float speed);
void S_StopMusic(void); void S_StopMusic(void);
// Stop and resume music, during game PAUSE. // Stop and resume music, during game PAUSE.
void S_PauseSound(void); void S_PauseAudio(void);
void S_ResumeSound(void); void S_ResumeAudio(void);
// //
// Updates music & sounds // Updates music & sounds
@ -141,4 +139,10 @@ void S_StopSoundByNum(sfxenum_t sfxnum);
#define S_StartScreamSound S_StartSound #define S_StartScreamSound S_StartSound
#endif #endif
#ifdef MUSICSLOT_COMPATIBILITY
// For compatibility with code/scripts relying on older versions
// This is a list of all the "special" slot names and their associated numbers
const char *compat_special_music_slots[16];
#endif
#endif #endif

View file

@ -117,11 +117,13 @@ if(${SDL2_FOUND})
add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32 ${SRB2_SDL2_TOTAL_SOURCES}) add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32 ${SRB2_SDL2_TOTAL_SOURCES})
set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME ${SRB2_SDL2_EXE_NAME}) set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME ${SRB2_SDL2_EXE_NAME})
if((CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")) if(${CMAKE_SYSTEM} MATCHES Darwin)
add_framework(CoreFoundation SRB2SDL2) find_library(CORE_LIB CoreFoundation)
add_framework(SDL2 SRB2SDL2)
add_framework(SDL2_mixer SRB2SDL2)
target_link_libraries(SRB2SDL2 PRIVATE target_link_libraries(SRB2SDL2 PRIVATE
${CORE_LIB}
SDL2
SDL2_mixer
${GME_LIBRARIES}
${PNG_LIBRARIES} ${PNG_LIBRARIES}
${ZLIB_LIBRARIES} ${ZLIB_LIBRARIES}
${OPENGL_LIBRARIES} ${OPENGL_LIBRARIES}
@ -131,6 +133,7 @@ if(${SDL2_FOUND})
target_link_libraries(SRB2SDL2 PRIVATE target_link_libraries(SRB2SDL2 PRIVATE
${SDL2_LIBRARIES} ${SDL2_LIBRARIES}
${SDL2_MIXER_LIBRARIES} ${SDL2_MIXER_LIBRARIES}
${GME_LIBRARIES}
${PNG_LIBRARIES} ${PNG_LIBRARIES}
${ZLIB_LIBRARIES} ${ZLIB_LIBRARIES}
${OPENGL_LIBRARIES} ${OPENGL_LIBRARIES}
@ -198,6 +201,7 @@ if(${SDL2_FOUND})
target_include_directories(SRB2SDL2 PRIVATE target_include_directories(SRB2SDL2 PRIVATE
${SDL2_INCLUDE_DIRS} ${SDL2_INCLUDE_DIRS}
${SDL2_MIXER_INCLUDE_DIRS} ${SDL2_MIXER_INCLUDE_DIRS}
${GME_INCLUDE_DIRS}
${PNG_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS}
${OPENGL_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIRS}
@ -224,7 +228,7 @@ if(${SDL2_FOUND})
endif() endif()
#### Installation #### #### Installation ####
if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") if(${CMAKE_SYSTEM} MATCHES Darwin)
install(TARGETS SRB2SDL2 install(TARGETS SRB2SDL2
BUNDLE DESTINATION . BUNDLE DESTINATION .
) )
@ -265,7 +269,7 @@ if(${SDL2_FOUND})
# Mac bundle fixup # Mac bundle fixup
if (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") if(${CMAKE_SYSTEM} MATCHES Darwin)
install(CODE " install(CODE "
include(BundleUtilities) include(BundleUtilities)
fixup_bundle(\"${CMAKE_INSTALL_PREFIX}/Sonic Robo Blast 2.app\" fixup_bundle(\"${CMAKE_INSTALL_PREFIX}/Sonic Robo Blast 2.app\"

View file

@ -126,8 +126,6 @@ static Uint8 BitsPerPixel = 16;
#endif #endif
Uint16 realwidth = BASEVIDWIDTH; Uint16 realwidth = BASEVIDWIDTH;
Uint16 realheight = BASEVIDHEIGHT; Uint16 realheight = BASEVIDHEIGHT;
static const Uint32 surfaceFlagsW = 0/*|SDL_RESIZABLE*/;
static const Uint32 surfaceFlagsF = 0;
static SDL_bool mousegrabok = SDL_TRUE; static SDL_bool mousegrabok = SDL_TRUE;
#define HalfWarpMouse(x,y) SDL_WarpMouseInWindow(window, (Uint16)(x/2),(Uint16)(y/2)) #define HalfWarpMouse(x,y) SDL_WarpMouseInWindow(window, (Uint16)(x/2),(Uint16)(y/2))
static SDL_bool videoblitok = SDL_FALSE; static SDL_bool videoblitok = SDL_FALSE;
@ -1252,17 +1250,6 @@ static inline boolean I_SkipFrame(void)
} }
} }
static inline SDL_bool SDLmatchVideoformat(void)
{
const SDL_PixelFormat *vidformat = vidSurface->format;
const INT32 vfBPP = vidformat?vidformat->BitsPerPixel:0;
return (((vfBPP == 8 && vid.bpp == 1 &&
!vidformat->Rmask && !vidformat->Gmask && !vidformat->Bmask) ||
(vfBPP == 15 && vid.bpp == 2 && vidformat->Rmask == 0x7C00 &&
vidformat->Gmask == 0x03E0 && vidformat->Bmask == 0x001F )) &&
!vidformat->Amask && (vidSurface->flags & SDL_RLEACCEL) == 0);
}
// //
// I_FinishUpdate // I_FinishUpdate
// //

View file

@ -1270,6 +1270,7 @@
HAVE_BLUA, HAVE_BLUA,
LUA_USE_POSIX, LUA_USE_POSIX,
COMPVERSION, COMPVERSION,
HWRENDER,
); );
GCC_THREADSAFE_STATICS = NO; GCC_THREADSAFE_STATICS = NO;
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
@ -1392,6 +1393,7 @@
HAVE_BLUA, HAVE_BLUA,
LUA_USE_POSIX, LUA_USE_POSIX,
COMPVERSION, COMPVERSION,
HWRENDER,
); );
GCC_THREADSAFE_STATICS = NO; GCC_THREADSAFE_STATICS = NO;
GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES; GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;

View file

@ -395,6 +395,7 @@ void I_FreeSfx(sfxinfo_t *sfx)
if (sfx->data) if (sfx->data)
Mix_FreeChunk(sfx->data); Mix_FreeChunk(sfx->data);
sfx->data = NULL; sfx->data = NULL;
sfx->lumpnum = LUMPERROR;
} }
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority) INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority)
@ -528,14 +529,8 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
#endif #endif
if (lumpnum == LUMPERROR) if (lumpnum == LUMPERROR)
{ return false;
lumpnum = W_CheckNumForName(va("D_%s",musicname)); midimode = false;
if (lumpnum == LUMPERROR)
return false;
midimode = true;
}
else
midimode = false;
data = (char *)W_CacheLumpNum(lumpnum, PU_MUSIC); data = (char *)W_CacheLumpNum(lumpnum, PU_MUSIC);
len = W_LumpLength(lumpnum); len = W_LumpLength(lumpnum);
@ -685,10 +680,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError()); CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError());
return true; return true;
} }
if (midimode) Mix_VolumeMusic((UINT32)music_volume*128/31);
Mix_VolumeMusic((UINT32)midi_volume*128/31);
else
Mix_VolumeMusic((UINT32)music_volume*128/31);
if (loop_point != 0.0f) if (loop_point != 0.0f)
Mix_HookMusicFinished(music_loop); Mix_HookMusicFinished(music_loop);
@ -791,10 +783,15 @@ void I_ShutdownMIDIMusic(void)
void I_SetMIDIMusicVolume(UINT8 volume) void I_SetMIDIMusicVolume(UINT8 volume)
{ {
midi_volume = volume; // HACK: Until we stop using native MIDI,
// disable volume changes
(void)volume;
midi_volume = 31;
//midi_volume = volume;
if (!midimode || !music) if (!midimode || !music)
return; return;
Mix_VolumeMusic((UINT32)volume*128/31); Mix_VolumeMusic((UINT32)midi_volume*128/31);
} }
INT32 I_RegisterSong(void *data, size_t len) INT32 I_RegisterSong(void *data, size_t len)
@ -819,7 +816,8 @@ boolean I_PlaySong(INT32 handle, boolean looping)
CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError()); CONS_Alert(CONS_ERROR, "Mix_PlayMusic: %s\n", Mix_GetError());
return false; return false;
} }
Mix_VolumeMusic((UINT32)music_volume*128/31);
Mix_VolumeMusic((UINT32)midi_volume*128/31);
return true; return true;
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1889,7 +1889,7 @@ static void ST_overlayDrawer(void)
ST_drawDebugInfo(); ST_drawDebugInfo();
} }
void ST_Drawer(boolean refresh) void ST_Drawer(void)
{ {
#ifdef SEENAMES #ifdef SEENAMES
if (cv_seenames.value && cv_allowseenames.value && displayplayer == consoleplayer && seenplayer && seenplayer->mo) if (cv_seenames.value && cv_allowseenames.value && displayplayer == consoleplayer && seenplayer && seenplayer->mo)
@ -1906,8 +1906,11 @@ void ST_Drawer(boolean refresh)
} }
#endif #endif
// Doom's status bar only updated if necessary.
// However, ours updates every frame regardless, so the "refresh" param was removed
//(void)refresh;
// force a set of the palette by using doPaletteStuff() // force a set of the palette by using doPaletteStuff()
(void)refresh; //?
if (vid.recalc) if (vid.recalc)
st_palette = -1; st_palette = -1;

View file

@ -27,7 +27,7 @@
void ST_Ticker(void); void ST_Ticker(void);
// Called by main loop. // Called by main loop.
void ST_Drawer(boolean refresh); void ST_Drawer(void);
// Called when the console player is spawned on each level. // Called when the console player is spawned on each level.
void ST_Start(void); void ST_Start(void);

View file

@ -15,6 +15,8 @@
#include <string.h> #include <string.h>
#include "doomdef.h" #include "doomdef.h"
#if !defined (__APPLE__)
// Like the OpenBSD version, but it doesn't check for src not being a valid // Like the OpenBSD version, but it doesn't check for src not being a valid
// C string. // C string.
size_t strlcat(char *dst, const char *src, size_t siz) size_t strlcat(char *dst, const char *src, size_t siz)
@ -46,3 +48,5 @@ size_t strlcpy(char *dst, const char *src, size_t siz)
dst[0] = '\0'; dst[0] = '\0';
return strlcat(dst, src, siz); return strlcat(dst, src, siz);
} }
#endif

View file

@ -336,6 +336,8 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
const column_t *column; const column_t *column;
UINT8 *desttop, *dest, *deststart, *destend; UINT8 *desttop, *dest, *deststart, *destend;
const UINT8 *source, *deststop; const UINT8 *source, *deststop;
fixed_t pwidth; // patch width
fixed_t offx = 0; // x offset
if (rendermode == render_none) if (rendermode == render_none)
return; return;
@ -476,16 +478,36 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
} }
} }
deststart = desttop; if (pscale != FRACUNIT) // scale width properly
destend = desttop + SHORT(patch->width) * dupx; {
pwidth = SHORT(patch->width)<<FRACBITS;
pwidth = FixedMul(pwidth, pscale);
pwidth = FixedMul(pwidth, dupx<<FRACBITS);
pwidth >>= FRACBITS;
}
else
pwidth = SHORT(patch->width) * dupx;
for (col = 0; (col>>FRACBITS) < SHORT(patch->width); col += colfrac, ++x, desttop++) deststart = desttop;
destend = desttop + pwidth;
for (col = 0; (col>>FRACBITS) < SHORT(patch->width); col += colfrac, ++offx, desttop++)
{ {
INT32 topdelta, prevdelta = -1; INT32 topdelta, prevdelta = -1;
if (x < 0) // don't draw off the left of the screen (WRAP PREVENTION) if (flip) // offx is measured from right edge instead of left
continue; {
if (x >= vid.width) // don't draw off the right of the screen (WRAP PREVENTION) if (x+pwidth-offx < 0) // don't draw off the left of the screen (WRAP PREVENTION)
break; break;
if (x+pwidth-offx >= vid.width) // don't draw off the right of the screen (WRAP PREVENTION)
continue;
}
else
{
if (x+offx < 0) // don't draw off the left of the screen (WRAP PREVENTION)
continue;
if (x+offx >= vid.width) // don't draw off the right of the screen (WRAP PREVENTION)
break;
}
column = (const column_t *)((const UINT8 *)(patch) + LONG(patch->columnofs[col>>FRACBITS])); column = (const column_t *)((const UINT8 *)(patch) + LONG(patch->columnofs[col>>FRACBITS]));
while (column->topdelta != 0xff) while (column->topdelta != 0xff)

View file

@ -32,6 +32,7 @@
#include "w_wad.h" #include "w_wad.h"
#include "z_zone.h" #include "z_zone.h"
#include "fastcmp.h"
#include "i_video.h" // rendermode #include "i_video.h" // rendermode
#include "d_netfil.h" #include "d_netfil.h"
@ -147,24 +148,32 @@ static inline void W_LoadDehackedLumps(UINT16 wadnum)
} }
#endif #endif
// Check for MAINCFG
for (lump = 0;lump != INT16_MAX;lump++)
{ {
lump = W_CheckNumForNamePwad("MAINCFG", wadnum, lump); lumpinfo_t *lump_p = wadfiles[wadnum]->lumpinfo;
if (lump == INT16_MAX) for (lump = 0; lump < wadfiles[wadnum]->numlumps; lump++, lump_p++)
break; if (memcmp(lump_p->name,"SOC_",4)==0) // Check for generic SOC lump
CONS_Printf(M_GetText("Loading main config from %s\n"), wadfiles[wadnum]->filename); { // shameless copy+paste of code from LUA_LoadLump
DEH_LoadDehackedLumpPwad(wadnum, lump); char *name = malloc(strlen(wadfiles[wadnum]->filename)+10);
} strcpy(name, wadfiles[wadnum]->filename);
if (!fasticmp(&name[strlen(name) - 4], ".soc")) {
// Check for OBJCTCFG // If it's not a .soc file, copy the lump name in too.
for (lump = 0;lump < INT16_MAX;lump++) name[strlen(wadfiles[wadnum]->filename)] = '|';
{ M_Memcpy(name+strlen(wadfiles[wadnum]->filename)+1, lump_p->name, 8);
lump = W_CheckNumForNamePwad("OBJCTCFG", wadnum, lump); name[strlen(wadfiles[wadnum]->filename)+9] = '\0';
if (lump == INT16_MAX) }
break; CONS_Printf(M_GetText("Loading SOC from %s\n"), name);
CONS_Printf(M_GetText("Loading object config from %s\n"), wadfiles[wadnum]->filename); DEH_LoadDehackedLumpPwad(wadnum, lump);
DEH_LoadDehackedLumpPwad(wadnum, lump); }
else if (memcmp(lump_p->name,"MAINCFG",8)==0) // Check for MAINCFG
{
CONS_Printf(M_GetText("Loading main config from %s\n"), wadfiles[wadnum]->filename);
DEH_LoadDehackedLumpPwad(wadnum, lump);
}
else if (memcmp(lump_p->name,"OBJCTCFG",8)==0) // Check for OBJCTCFG
{
CONS_Printf(M_GetText("Loading object config from %s\n"), wadfiles[wadnum]->filename);
DEH_LoadDehackedLumpPwad(wadnum, lump);
}
} }
#ifdef SCANTHINGS #ifdef SCANTHINGS

View file

@ -77,10 +77,14 @@ typedef union
struct struct
{ {
char passed1[13]; // KNUCKLES GOT char passed1[SKINNAMESIZE+1]; // KNUCKLES GOT / CRAWLA HONCHO
char passed2[16]; // A CHAOS EMERALD char passed2[17]; // A CHAOS EMERALD / GOT THEM ALL!
char passed3[15]; // CAN NOW BECOME
char passed4[SKINNAMESIZE+7]; // SUPER CRAWLA HONCHO
INT32 passedx1; INT32 passedx1;
INT32 passedx2; INT32 passedx2;
INT32 passedx3;
INT32 passedx4;
y_bonus_t bonus; y_bonus_t bonus;
patch_t *bonuspatch; patch_t *bonuspatch;
@ -250,19 +254,62 @@ void Y_IntermissionDrawer(void)
} }
else if (intertype == int_spec) else if (intertype == int_spec)
{ {
// draw the header static tic_t animatetic = 0;
/* if (endtic != -1 && ALL7EMERALDS(emeralds) && data.spec.nowsuper != NULL) INT32 ttheight = 16;
V_DrawScaledPatch(48, 32, 0, data.spec.nowsuper); INT32 xoffset1 = 0; // Line 1 x offset
else INT32 xoffset2 = 0; // Line 2 x offset
V_DrawScaledPatch(data.spec.headx, 26, 0, data.spec.cemerald); */ INT32 xoffset3 = 0; // Line 3 x offset
UINT8 drawsection = 0;
if (data.spec.passed1[0] != '\0') // draw the header
if (intertic <= TICRATE)
animatetic = 0;
else if (!animatetic && data.spec.bonus.points == 0 && data.spec.passed3[0] != '\0')
animatetic = intertic;
if (animatetic)
{ {
V_DrawLevelTitle(data.spec.passedx1, 24, 0, data.spec.passed1); INT32 animatetimer = (intertic - animatetic);
V_DrawLevelTitle(data.spec.passedx2, 24+V_LevelNameHeight(data.spec.passed2)+2, 0, data.spec.passed2); if (animatetimer <= 8)
{
xoffset1 = -(animatetimer * 40);
xoffset2 = -((animatetimer-2) * 40);
if (xoffset2 > 0) xoffset2 = 0;
}
else if (animatetimer <= 19)
{
drawsection = 1;
xoffset1 = (16-animatetimer) * 40;
xoffset2 = (18-animatetimer) * 40;
xoffset3 = (20-animatetimer) * 40;
if (xoffset1 < 0) xoffset1 = 0;
if (xoffset2 < 0) xoffset2 = 0;
}
else
drawsection = 1;
}
if (drawsection == 1)
{
ttheight = 16;
V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1);
ttheight += V_LevelNameHeight(data.spec.passed3) + 2;
V_DrawLevelTitle(data.spec.passedx3 + xoffset2, ttheight, 0, data.spec.passed3);
ttheight += V_LevelNameHeight(data.spec.passed4) + 2;
V_DrawLevelTitle(data.spec.passedx4 + xoffset3, ttheight, 0, data.spec.passed4);
}
else if (data.spec.passed1[0] != '\0')
{
ttheight = 24;
V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1);
ttheight += V_LevelNameHeight(data.spec.passed2) + 2;
V_DrawLevelTitle(data.spec.passedx2 + xoffset2, ttheight, 0, data.spec.passed2);
} }
else else
V_DrawLevelTitle(data.spec.passedx2, 24+(V_LevelNameHeight(data.spec.passed2)/2)+2, 0, data.spec.passed2); {
ttheight = 24 + (V_LevelNameHeight(data.spec.passed2)/2) + 2;
V_DrawLevelTitle(data.spec.passedx2 + xoffset1, ttheight, 0, data.spec.passed2);
}
// draw the emeralds // draw the emeralds
if (intertic & 1) if (intertic & 1)
@ -632,7 +679,7 @@ void Y_Ticker(void)
boolean anybonuses = false; boolean anybonuses = false;
if (!intertic) // first time only if (!intertic) // first time only
S_ChangeMusic(mus_lclear, false); // don't loop it S_ChangeMusicInternal("lclear", false); // don't loop it
if (intertic < TICRATE) // one second pause before tally begins if (intertic < TICRATE) // one second pause before tally begins
return; return;
@ -693,7 +740,7 @@ void Y_Ticker(void)
if (!intertic) // first time only if (!intertic) // first time only
{ {
S_ChangeMusic(mus_lclear, false); // don't loop it S_ChangeMusicInternal("lclear", false); // don't loop it
tallydonetic = 0; tallydonetic = 0;
} }
@ -708,7 +755,7 @@ void Y_Ticker(void)
{ {
if (intertic > tallydonetic) if (intertic > tallydonetic)
{ {
endtic = intertic + 4*TICRATE; // 4 second pause after end of tally for sound endtic = intertic + 4*TICRATE; // 4 second pause after end of tally
S_StartSound(NULL, sfx_flgcap); // cha-ching! S_StartSound(NULL, sfx_flgcap); // cha-ching!
} }
return; return;
@ -728,7 +775,7 @@ void Y_Ticker(void)
if (data.spec.continues & 0x80) // don't set endtic yet! if (data.spec.continues & 0x80) // don't set endtic yet!
tallydonetic = intertic + (3*TICRATE)/2; tallydonetic = intertic + (3*TICRATE)/2;
else // okay we're good. else // okay we're good.
endtic = intertic + 3*TICRATE; // 3 second pause after end of tally endtic = intertic + 4*TICRATE; // 4 second pause after end of tally
S_StartSound(NULL, sfx_chchng); // cha-ching! S_StartSound(NULL, sfx_chchng); // cha-ching!
@ -754,7 +801,7 @@ void Y_Ticker(void)
else if (intertype == int_match || intertype == int_ctf || intertype == int_teammatch) // match else if (intertype == int_match || intertype == int_ctf || intertype == int_teammatch) // match
{ {
if (!intertic) // first time only if (!intertic) // first time only
S_ChangeMusic(mus_racent, true); // loop it S_ChangeMusicInternal("racent", true); // loop it
// If a player has left or joined, recalculate scores. // If a player has left or joined, recalculate scores.
if (data.match.numplayers != D_NumPlayers()) if (data.match.numplayers != D_NumPlayers())
@ -763,7 +810,7 @@ void Y_Ticker(void)
else if (intertype == int_race || intertype == int_classicrace) // race else if (intertype == int_race || intertype == int_classicrace) // race
{ {
if (!intertic) // first time only if (!intertic) // first time only
S_ChangeMusic(mus_racent, true); // loop it S_ChangeMusicInternal("racent", true); // loop it
// Don't bother recalcing for race. It doesn't make as much sense. // Don't bother recalcing for race. It doesn't make as much sense.
} }
@ -1098,6 +1145,10 @@ void Y_StartIntermission(void)
data.spec.nowsuper = NULL; data.spec.nowsuper = NULL;
} */ } */
// Super form stuff (normally blank)
data.spec.passed3[0] = '\0';
data.spec.passed4[0] = '\0';
// set up the "got through act" message according to skin name // set up the "got through act" message according to skin name
if (stagefailed) if (stagefailed)
{ {
@ -1111,10 +1162,19 @@ void Y_StartIntermission(void)
skins[players[consoleplayer].skin].realname); skins[players[consoleplayer].skin].realname);
data.spec.passed1[sizeof data.spec.passed1 - 1] = '\0'; data.spec.passed1[sizeof data.spec.passed1 - 1] = '\0';
strcpy(data.spec.passed2, "GOT THEM ALL!"); strcpy(data.spec.passed2, "GOT THEM ALL!");
if (skins[players[consoleplayer].skin].flags & SF_SUPER)
{
strcpy(data.spec.passed3, "CAN NOW BECOME");
snprintf(data.spec.passed4,
sizeof data.spec.passed4, "SUPER %s",
skins[players[consoleplayer].skin].realname);
data.spec.passed4[sizeof data.spec.passed4 - 1] = '\0';
}
} }
else else
{ {
if (strlen(skins[players[consoleplayer].skin].realname) <= 8) if (strlen(skins[players[consoleplayer].skin].realname) <= SKINNAMESIZE-5)
{ {
snprintf(data.spec.passed1, snprintf(data.spec.passed1,
sizeof data.spec.passed1, "%s GOT", sizeof data.spec.passed1, "%s GOT",
@ -1127,6 +1187,8 @@ void Y_StartIntermission(void)
} }
data.spec.passedx1 = (BASEVIDWIDTH - V_LevelNameWidth(data.spec.passed1))/2; data.spec.passedx1 = (BASEVIDWIDTH - V_LevelNameWidth(data.spec.passed1))/2;
data.spec.passedx2 = (BASEVIDWIDTH - V_LevelNameWidth(data.spec.passed2))/2; data.spec.passedx2 = (BASEVIDWIDTH - V_LevelNameWidth(data.spec.passed2))/2;
data.spec.passedx3 = (BASEVIDWIDTH - V_LevelNameWidth(data.spec.passed3))/2;
data.spec.passedx4 = (BASEVIDWIDTH - V_LevelNameWidth(data.spec.passed4))/2;
break; break;
} }