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
env:
- CFLAGS=-Wno-absolute-value -Werror
- CFLAGS=-Wall -W -Werror
os:
- linux
- osx
compiler:
- gcc
- clang
cache:
apt: true
ccache: true
directories:
- $HOME/srb2_cache
@ -30,4 +36,10 @@ before_script:
- cd build
- 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

View file

@ -3293,23 +3293,6 @@ HW3SOUND for 3D hardware sound support
<Option target="Debug Mingw64/DirectX" />
<Option target="Release Mingw64/DirectX" />
</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">
<Option compilerVar="CC" />
<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_ARCHIVE: SDL2_mixer-devel-2.0.1-mingw.tar
SDL2_MIXER_MOVE: SDL2_mixer-2.0.1\i686-w64-mingw32
CFLAGS: -Wall -W -Werror
cache:
- SDL2-devel-2.0.4-mingw.tar.gz

View file

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

View file

@ -1,4 +1,4 @@
@ECHO OFF
@echo off
set BRA=Unknown
set REV=illegal
@ -13,20 +13,20 @@ goto filwri
:gitrev
set GIT=%2
if "%GIT%"=="" set GIT=git
FOR /F "usebackq" %%s IN (`%GIT% rev-parse --abbrev-ref HEAD`) DO @SET BRA=%%s
FOR /F "usebackq" %%s IN (`%GIT% rev-parse HEAD`) DO @SET REV=%%s
for /f "usebackq" %%s in (`%GIT% rev-parse --abbrev-ref HEAD`) do @set BRA=%%s
for /f "usebackq" %%s in (`%GIT% rev-parse HEAD`) do @set REV=%%s
set REV=%REV:~0,8%
goto filwri
:svnrev
set BRA=Subversion
FOR /F "usebackq" %%s IN (`svnversion .`) DO @SET REV=%%s
for /f "usebackq" %%s in (`svnversion .`) do @set REV=%%s
set REV=r%REV%
goto filwri
:filwri
ECHO // Do not edit! This file was autogenerated > %1\comptime.h
ECHO // by the %0 batch file >> %1\comptime.h
ECHO // >> %1\comptime.h
ECHO const char* compbranch = "%BRA%"; >> %1\comptime.h
ECHO const char* comprevision = "%REV%"; >> %1\comptime.h
echo // Do not edit! This file was autogenerated > %1\comptime.h
echo // by the %0 batch file >> %1\comptime.h
echo // >> %1\comptime.h
echo const char* compbranch = "%BRA%"; >> %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
p_ceilng.c
p_enemy.c
p_fab.c
p_floor.c
p_inter.c
p_lights.c
@ -316,6 +315,7 @@ if(${SRB2_CONFIG_HAVE_GME})
find_package(GME)
if(${GME_FOUND})
set(SRB2_HAVE_GME ON)
add_definitions(-DHAVE_LIBGME)
else()
message(WARNING "You have specified that GME is available but it was not found.")
endif()

View file

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

View file

@ -30,9 +30,7 @@ static const UINT8 REDRANGE = 16;
static const UINT8 GRAYS = (1*16);
static const UINT8 GRAYSRANGE = 16;
static const UINT8 BROWNS = (3*16);
static const UINT8 BROWNRANGE = 16;
static const UINT8 YELLOWS = (7*16);
static const UINT8 YELLOWRANGE = 8;
static const UINT8 GREENS = (10*16);
static const UINT8 GREENRANGE = 16;
static const UINT8 DBLACK = 31;
@ -41,11 +39,8 @@ static const UINT8 DWHITE = 0;
static const UINT8 NOCLIMBREDS = 248;
static const UINT8 NOCLIMBREDRANGE = 8;
static const UINT8 NOCLIMBGRAYS = 204;
static const UINT8 NOCLIMBGRAYSRANGE = 4;
static const UINT8 NOCLIMBBROWNS = (2*16);
static const UINT8 NOCLIMBBROWNRANGE = 16;
static const UINT8 NOCLIMBYELLOWS = (11*16);
static const UINT8 NOCLIMBYELLOWRANGE = 8;
#ifdef _NDS
@ -67,15 +62,10 @@ static const UINT8 NOCLIMBYELLOWRANGE = 8;
#define TSWALLCOLORS GRAYS
#define TSWALLRANGE GRAYSRANGE
#define NOCLIMBTSWALLCOLORS NOCLIMBGRAYS
#define NOCLIMBTSWALLRANGE NOCLIMBGRAYSRANGE
#define FDWALLCOLORS BROWNS
#define FDWALLRANGE BROWNRANGE
#define NOCLIMBFDWALLCOLORS NOCLIMBBROWNS
#define NOCLIMBFDWALLRANGE NOCLIMBBROWNRANGE
#define CDWALLCOLORS YELLOWS
#define CDWALLRANGE YELLOWRANGE
#define NOCLIMBCDWALLCOLORS NOCLIMBYELLOWS
#define NOCLIMBCDWALLRANGE NOCLIMBYELLOWRANGE
#define THINGCOLORS GREENS
#define THINGRANGE GREENRANGE
#define SECRETWALLCOLORS WALLCOLORS
@ -255,29 +245,6 @@ static AMDRAWFLINEFUNC AM_drawFline;
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)
{
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))
{
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)
cmd->angleturn = -cmd->angleturn;
} 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_RINGS_DTA "${SRB2_ASSET_rings.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}"
#endif
#define SRB2_COMP_REVISION "${SRB2_COMP_REVISION}"
#define SRB2_COMP_BRANCH "${SRB2_COMP_BRANCH}"
@ -26,10 +28,16 @@
#else
/* Manually defined asset hashes for non-CMake builds
* Last updated 2000 / 00 / 00
*/
#define ASSET_HASH_SRB2_SRB "c1b9577687f8a795104aef4600720ea7"
#define ASSET_HASH_ZONES_DTA "303838c6c534d9540288360fa49cca60"
#define ASSET_HASH_PLAYER_DTA "cfca0f1c73023cbbd8f844f45480f799"
#define ASSET_HASH_RINGS_DTA "85901ad4bf94637e5753d2ac2c03ea26"
#ifdef USE_PATCH_DTA
#define ASSET_HASH_PATCH_DTA "0c66790502e648bfce90fdc5bb15722e"
#endif
#endif
#endif

View file

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

View file

@ -221,10 +221,7 @@ gamestate_t wipegamestate = GS_LEVEL;
static void D_Display(void)
{
static boolean menuactivestate = false;
static gamestate_t oldgamestate = -1;
boolean redrawsbar = false;
boolean forcerefresh = false;
static boolean wipe = false;
INT32 wipedefindex = 0;
@ -245,23 +242,15 @@ static void D_Display(void)
if (setsizeneeded)
{
R_ExecuteSetViewSize();
oldgamestate = -1; // force background redraw
redrawsbar = true;
forcerefresh = true; // force background redraw
}
// save the current screen if about to wipe
if (gamestate != wipegamestate)
{
wipe = true;
F_WipeStartScreen();
}
else
wipe = false;
// draw buffered stuff to screen
// Used only by linux GGI version
I_UpdateNoBlit();
// save the current screen if about to wipe
wipe = (gamestate != wipegamestate);
if (wipe)
{
// 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
&& wipedefs[wipedefindex] != UINT8_MAX)
{
F_WipeStartScreen();
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
F_WipeEndScreen();
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK);
@ -298,8 +288,6 @@ static void D_Display(void)
HU_Erase();
if (automapactive)
AM_Drawer();
if (wipe || menuactivestate || (rendermode != render_soft && rendermode != render_none) || vid.recalc)
redrawsbar = true;
break;
case GS_INTERMISSION:
@ -357,11 +345,6 @@ static void D_Display(void)
// see if the border needs to be initially drawn
if (gamestate == GS_LEVEL)
{
#if 0
if (oldgamestate != GS_LEVEL)
R_FillBackScreen(); // draw the pattern into the back screen
#endif
// draw the view directly
if (!automapactive && !dedicated && cv_renderview.value)
{
@ -417,17 +400,17 @@ static void D_Display(void)
lastdraw = false;
}
ST_Drawer(redrawsbar);
ST_Drawer();
HU_Drawer();
}
// 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);
menuactivestate = menuactive;
oldgamestate = wipegamestate = gamestate;
wipegamestate = gamestate;
// draw pause pic
if (paused && cv_showhud.value && (!menuactive || netgame))
@ -450,15 +433,22 @@ static void D_Display(void)
CON_Drawer();
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);
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");
// note: moved up here because NetUpdate does input changes
// and input during wipe tends to mess things up
wipedefindex += WIPEFINALSHIFT;
if (rendermode != render_none)
{
F_WipeEndScreen();
F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK);
}
}
NetUpdate(); // send out any new accumulation
@ -493,18 +483,6 @@ static void D_Display(void)
}
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;
boolean supdate;
void D_SRB2Loop(void)
{
@ -604,7 +581,6 @@ void D_SRB2Loop(void)
// Update display, next frame, with current state.
D_Display();
supdate = false;
if (moviemode)
M_SaveFrame();
@ -841,8 +817,10 @@ static void IdentifyVersion(void)
// Add the weapons
D_AddFile(va(pandf,srb2waddir,"rings.dta"));
#ifdef USE_PATCH_DTA
// 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)
{
@ -1133,12 +1111,18 @@ void D_SRB2Main(void)
W_VerifyFileMD5(1, ASSET_HASH_ZONES_DTA); // zones.dta
W_VerifyFileMD5(2, ASSET_HASH_PLAYER_DTA); // player.dta
W_VerifyFileMD5(3, ASSET_HASH_RINGS_DTA); // rings.dta
//W_VerifyFileMD5(4, "0c66790502e648bfce90fdc5bb15722e"); // patch.dta
// don't check music.dta because people like to modify it, and it doesn't matter if they do
// ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for.
#ifdef USE_PATCH_DTA
W_VerifyFileMD5(4, ASSET_HASH_PATCH_DTA); // patch.dta
#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();

View file

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

File diff suppressed because it is too large Load diff

View file

@ -101,6 +101,7 @@
#include <stdlib.h>
#include <string.h>
#define _USE_MATH_DEFINES // fixes M_PI errors in r_plane.c for Visual Studio
#include <math.h>
#ifdef GETTEXT
@ -148,13 +149,17 @@ extern FILE *logstream;
// we use comprevision and compbranch instead.
#else
#define VERSION 201 // Game version
#define SUBVERSION 14 // more precise version number
#define VERSIONSTRING "v2.1.14"
#define VERSIONSTRINGW L"v2.1.14"
#define SUBVERSION 15 // more precise version number
#define VERSIONSTRING "v2.1.15"
#define VERSIONSTRINGW L"v2.1.15"
// Hey! If you change this, add 1 to the MODVERSION below!
// Otherwise we can't force updates!
#endif
// Does this version require an added patch file?
// Comment or uncomment this as necessary.
#define USE_PATCH_DTA
// Modification options
// 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
@ -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.
// 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".
#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
// 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)
#define ESLOPE
@ -449,10 +447,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Polyobject fake flat code
#define POLYOBJECTS_PLANES
/// Blue spheres for future use.
/// \todo Remove this define.
#define BLUE_SPHERES // Blue spheres for future use.
/// Improved way of dealing with ping values and a ping limit.
#define NEWPING
@ -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.)
//#define REDSANALOG
/// Backwards compatibility with musicslots.
/// \note You should leave this enabled unless you're working with a future SRB2 version.
#define MUSICSLOT_COMPATIBILITY
#endif // __DOOMDEF__

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -36,9 +36,7 @@ typedef struct
{
float x;
float y;
//#ifdef SLOPENESS
float z;
//#endif
} polyvertex_t;
#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
// -----------------+
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)
{
polyvertex_t * pv;
@ -544,7 +544,7 @@ static void HWR_RenderPlane(sector_t *shittyUnusedVariable, extrasubsector_t *xs
static FOutVector *planeVerts = NULL;
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
if (!xsub->planepoly)
@ -3899,12 +3899,6 @@ static void HWR_ClearSprites(void)
gr_visspritecount = 0;
}
static inline void HWR_ResetVisSpriteChunks(void)
{
memset(gr_visspritechunks, 0, sizeof(gr_visspritechunks));
}
// --------------------------------------------------------------------------
// HWR_NewVisSprite
// --------------------------------------------------------------------------

View file

@ -406,191 +406,6 @@ static md2_model_t *md2_readModel(const char *filename)
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)
{
#if 0
@ -1503,16 +1318,37 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
HWR_GetMappedPatch(gpatch, spr->colormap);
}
if (spr->mobj->frame & FF_ANIMATE)
{
// set duration and tics to be the correct values for FF_ANIMATE states
durs = spr->mobj->state->var2;
tics = spr->mobj->anim_duration;
}
//FIXME: this is not yet correct
frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->header.numFrames;
buff = md2->model->glCommandBuffer;
curr = &md2->model->frames[frame];
if (cv_grmd2.value == 1
&& spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL
&& !(spr->mobj->player && (spr->mobj->state->nextstate == S_PLAY_TAP1 || spr->mobj->state->nextstate == S_PLAY_TAP2) && spr->mobj->state == &states[S_PLAY_STND]))
if (cv_grmd2.value == 1)
{
const INT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames;
next = &md2->model->frames[nextframe];
// frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation
if (spr->mobj->frame & FF_ANIMATE)
{
UINT32 nextframe = (spr->mobj->frame & FF_FRAMEMASK) + 1;
if (nextframe >= (UINT32)spr->mobj->state->var1)
nextframe = (spr->mobj->state->frame & FF_FRAMEMASK);
nextframe %= md2->model->header.numFrames;
next = &md2->model->frames[nextframe];
}
else
{
if (spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL
&& !(spr->mobj->player && (spr->mobj->state->nextstate == S_PLAY_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

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -196,26 +196,6 @@ static UINT8 cht_CheckCheat(cheatseq_t *cht, char key)
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)
{
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);
}
// 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
//
@ -2081,6 +2085,12 @@ boolean M_Responder(event_t *ev)
shiftdown = 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)
{
ch = ev->data1;
@ -2182,6 +2192,7 @@ boolean M_Responder(event_t *ev)
// F-Keys
if (!menuactive)
{
noFurtherInput = true;
switch (ch)
{
case KEY_F1: // Help key
@ -2252,6 +2263,7 @@ boolean M_Responder(event_t *ev)
M_StartControlPanel();
return true;
}
noFurtherInput = false; // turns out we didn't care
return false;
}
@ -2275,6 +2287,7 @@ boolean M_Responder(event_t *ev)
if (routine)
routine(ch);
M_StopMessage(0);
noFurtherInput = true;
return true;
}
return true;
@ -2354,6 +2367,7 @@ boolean M_Responder(event_t *ev)
return true;
case KEY_ENTER:
noFurtherInput = true;
currentMenu->lastOn = itemOn;
if (routine)
{
@ -2387,6 +2401,7 @@ boolean M_Responder(event_t *ev)
return true;
case KEY_ESCAPE:
noFurtherInput = true;
currentMenu->lastOn = itemOn;
if (currentMenu->prevMenu)
{
@ -2443,35 +2458,45 @@ void M_Drawer(void)
if (currentMenu == &MessageDef)
menuactive = true;
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 (menuactive)
{
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
// 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')
{
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
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 - 17*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, compbranch);
V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, comprevision);
#else // Regular build
V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, va("%s", VERSIONSTRING));
V_DrawThinString(vid.dupx, vid.height - 9*vid.dupy, V_NOSCALESTART|V_TRANSLUCENT|V_ALLOWLOWERCASE, va("%s", VERSIONSTRING));
#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)
{
// reset input trigger
noFurtherInput = false;
if (dedicated)
return;
@ -4751,7 +4779,7 @@ static void M_SetupChoosePlayer(INT32 choice)
if (Playing() == false)
{
S_StopMusic();
S_ChangeMusic(mus_chrsel, true);
S_ChangeMusicInternal("chrsel", true);
}
SP_PlayerDef.prevMenu = currentMenu;
@ -5202,7 +5230,7 @@ void M_DrawTimeAttackMenu(void)
lumpnum_t lumpnum;
char beststr[40];
S_ChangeMusic(mus_racent, true); // Eww, but needed for when user hits escape during demo playback
S_ChangeMusicInternal("racent", true); // Eww, but needed for when user hits escape during demo playback
V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE));
@ -5365,7 +5393,7 @@ static void M_TimeAttack(INT32 choice)
itemOn = tastart; // "Start" is selected.
G_SetGamestate(GS_TIMEATTACK);
S_ChangeMusic(mus_racent, true);
S_ChangeMusicInternal("racent", true);
}
// Drawing function for Nights Attack
@ -5375,7 +5403,7 @@ void M_DrawNightsAttackMenu(void)
lumpnum_t lumpnum;
char beststr[40];
S_ChangeMusic(mus_racent, true); // Eww, but needed for when user hits escape during demo playback
S_ChangeMusicInternal("racent", true); // Eww, but needed for when user hits escape during demo playback
V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE));
@ -5498,7 +5526,7 @@ static void M_NightsAttack(INT32 choice)
itemOn = nastart; // "Start" is selected.
G_SetGamestate(GS_TIMEATTACK);
S_ChangeMusic(mus_racent, true);
S_ChangeMusicInternal("racent", true);
}
// Player has selected the "START" from the nights attack screen
@ -5732,7 +5760,7 @@ static void M_ModeAttackEndGame(INT32 choice)
itemOn = currentMenu->lastOn;
G_SetGamestate(GS_TIMEATTACK);
modeattacking = ATTACKING_NONE;
S_ChangeMusic(mus_racent, true);
S_ChangeMusicInternal("racent", true);
// Update replay availability.
CV_AddValue(&cv_nextmap, 1);
CV_AddValue(&cv_nextmap, -1);
@ -6944,7 +6972,7 @@ static void M_ToggleDigital(void)
if (nodigimusic) return;
S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
S_StopMusic();
S_ChangeMusic(mus_lclear, false);
S_ChangeMusicInternal("lclear", false);
M_StartMessage(M_GetText("Digital Music Enabled\n"), NULL, MM_NOTHING);
}
else
@ -6971,7 +6999,7 @@ static void M_ToggleMIDI(void)
I_InitMIDIMusic();
if (nomidimusic) return;
S_Init(cv_soundvolume.value, cv_digmusicvolume.value, cv_midimusicvolume.value);
S_ChangeMusic(mus_lclear, false);
S_ChangeMusicInternal("lclear", false);
M_StartMessage(M_GetText("MIDI Music Enabled\n"), NULL, MM_NOTHING);
}
else

View file

@ -36,7 +36,7 @@
#include <stdlib.h>
#else
#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))
#endif
#endif

View file

@ -351,33 +351,6 @@ static INT32 GetServersList(void)
}
#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()
//

View file

@ -3063,12 +3063,8 @@ void A_Invincibility(mobj_t *actor)
{
S_StopMusic();
if (mariomode)
{
S_ChangeMusic(mus_minvnc, false);
G_GhostAddColor(GHC_INVINCIBLE);
}
else
S_ChangeMusic(mus_invinc, false);
S_ChangeMusicInternal((mariomode) ? "minvnc" : "invinc", false);
}
}
@ -3104,7 +3100,7 @@ void A_SuperSneakers(mobj_t *actor)
else
{
S_StopMusic();
S_ChangeMusic(mus_shoes, false);
S_ChangeMusicInternal("shoes", false);
}
}
}
@ -7227,7 +7223,7 @@ void A_ChangeAngleAbsolute(mobj_t *actor)
//const angle_t amin = FixedAngle(locvar1*FRACUNIT);
//const angle_t amax = FixedAngle(locvar2*FRACUNIT);
#ifdef HAVE_BLUA
if (LUA_CallAction("A_ChangeAngelAbsolute", actor))
if (LUA_CallAction("A_ChangeAngleAbsolute", actor))
return;
#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;
fixed_t upperbound, lowerbound;
sector_t *sec = NULL;
sector_t *targetsec = NULL;
INT32 secnum = -1;
INT32 s;
sector_t *checksector;
msecnode_t *node;
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];
FOFsector = false;
// Check the lines of this sector, to see if it is a FOF control sector.
for (i = 0; i < sec->linecount; i++)
if (nobaddies->sector->lines[i]->special == 223)
{
INT32 targetsecnum = -1;
if (sec->lines[i]->special < 100 || sec->lines[i]->special >= 300)
continue;
upperbound = nobaddies->sector->ceilingheight;
lowerbound = nobaddies->sector->floorheight;
FOFsector = true;
while ((targetsecnum = P_FindSectorFromLineTag(sec->lines[i], targetsecnum)) >= 0)
for (s = -1; (s = P_FindSectorFromLineTag(nobaddies->sector->lines[i], s)) >= 0 ;)
{
targetsec = &sectors[targetsecnum];
checksector = &sectors[s];
upperbound = targetsec->ceilingheight;
lowerbound = targetsec->floorheight;
node = targetsec->touching_thinglist; // things touching this sector
node = checksector->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;
&& thing->z < upperbound && thing->z+thing->height > lowerbound)
{
exists = true;
goto foundenemy;
}
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
P_RunTriggerLinedef(nobaddies->sourceline, NULL, NULL);
CONS_Debug(DBG_GAMELOGIC, "Running no-more-enemies exec with tag of %d\n", s);
// Otherwise, run the linedef exec and terminate this thinker
P_LinedefExecute((INT16)s, NULL, NULL);
P_RemoveThinker(&nobaddies->thinker);
}

View file

@ -27,6 +27,10 @@
#include "m_misc.h"
#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)
{
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)
P_DoNightsScore(player);
break;
#ifdef BLUE_SPHERES
case MT_BLUEBALL:
if (!(P_CanPickupItem(player, false)))
return;
@ -422,7 +425,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
if (maptol & TOL_NIGHTS)
P_DoNightsScore(player);
break;
#endif
case MT_AUTOPICKUP:
case MT_BOUNCEPICKUP:
case MT_SCATTERPICKUP:
@ -576,11 +578,23 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
{
UINT8 flagteam = (special->type == MT_REDFLAG) ? 1 : 2;
const char *flagtext;
char flagcolor;
char plname[MAXPLAYERNAME+4];
if (special->type == MT_REDFLAG)
flagtext = M_GetText("red");
{
flagtext = M_GetText("Red flag");
flagcolor = '\x85';
}
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
{
@ -594,10 +608,11 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
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)
S_StartSound(NULL, sfx_hoop1);
// The fuse code plays this sound effect
//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;
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;
// code for dealing with abilities is handled elsewhere now
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
#ifdef BLUE_SPHERES
|| mo2->type == MT_BLUEBALL
#endif
))
|| mo2->type == MT_BLUEBALL))
continue;
// 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);
}
#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.
*
* \param player Affected player.
@ -1477,6 +1486,9 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour
if (!player)
return; // Impossible!
if (player->spectator)
return; // No messages for dying (crushed) spectators.
if (!netgame)
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 (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_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)
{
//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;
P_SetTarget(&flag->target, player->mo);
if (toss)
CONS_Printf(M_GetText("%s tossed the %s flag.\n"), player_names[player-players], (type == MT_REDFLAG ? "red" : "blue"));
else
CONS_Printf(M_GetText("%s dropped the %s flag.\n"), player_names[player-players], (type == MT_REDFLAG ? "red" : "blue"));
// Flag text
{
char plname[MAXPLAYERNAME+4];
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;

View file

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

View file

@ -1616,7 +1616,7 @@ boolean P_CheckCameraPosition(fixed_t x, fixed_t y, camera_t *thiscam)
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);
continue;
@ -2636,8 +2636,8 @@ isblocking:
climbangle += (ANGLE_90 * (whichside ? -1 : 1));
if (((!slidemo->player->climbing && abs((slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45)
|| (slidemo->player->climbing == 1 && abs((slidemo->angle - climbline)) < ANGLE_135))
if (((!slidemo->player->climbing && abs((signed)(slidemo->angle - ANGLE_90 - climbline)) < ANGLE_45)
|| (slidemo->player->climbing == 1 && abs((signed)(slidemo->angle - climbline)) < ANGLE_135))
&& P_IsClimbingValid(slidemo->player, climbangle))
{
slidemo->angle = climbangle;
@ -3712,6 +3712,9 @@ static inline boolean PIT_GetSectors(line_t *ld)
if (P_BoxOnLineSide(tmbbox, ld) != -1)
return true;
if (ld->polyobj) // line belongs to a polyobject, don't add it
return true;
// This line crosses through the object.
// 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)
return true;
if (ld->polyobj) // line belongs to a polyobject, don't add it
return true;
// This line crosses through the object.
// 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);
}
//
// 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
// 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;
}
//
// P_CycleStateAnimation
//
FUNCINLINE static ATTRINLINE void P_CycleStateAnimation(mobj_t *mobj)
{
// var2 determines delay between animation frames
if (!(mobj->frame & FF_ANIMATE) || --mobj->anim_duration != 0)
return;
mobj->anim_duration = (UINT16)mobj->state->var2;
// compare the current sprite frame to the one we started from
// if more than var1 away from it, swap back to the original
// else just advance by one
if (((++mobj->frame) & FF_FRAMEMASK) - (mobj->state->frame & FF_FRAMEMASK) > (UINT32)mobj->state->var1)
mobj->frame = (mobj->state->frame & FF_FRAMEMASK) | (mobj->frame & ~FF_FRAMEMASK);
}
//
// P_CycleMobjState
//
static void P_CycleMobjState(mobj_t *mobj)
{
// state animations
P_CycleStateAnimation(mobj);
// cycle through states,
// calling action functions at transitions
if (mobj->tics != -1)
@ -102,6 +122,9 @@ static void P_CycleMobjState(mobj_t *mobj)
//
static void P_CyclePlayerMobjState(mobj_t *mobj)
{
// state animations
P_CycleStateAnimation(mobj);
// cycle through states,
// calling action functions at transitions
if (mobj->tics != -1)
@ -279,6 +302,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
mobj->sprite = st->sprite;
mobj->frame = st->frame;
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set
// Modified handling.
// 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->sprite = st->sprite;
mobj->frame = st->frame;
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set
// Modified handling.
// 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->sprite = st->sprite;
mobj->frame = st->frame;
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set
return true;
}
@ -416,6 +443,8 @@ static boolean P_SetPrecipMobjState(precipmobj_t *mobj, statenum_t state)
mobj->tics = st->tics;
mobj->sprite = st->sprite;
mobj->frame = st->frame;
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set
return true;
}
@ -2159,9 +2188,7 @@ static boolean P_ZMovement(mobj_t *mo)
case MT_RING: // Ignore still rings
case MT_COIN:
#ifdef BLUE_SPHERES
case MT_BLUEBALL:
#endif
case MT_REDTEAMRING:
case MT_BLUETEAMRING:
case MT_FLINGRING:
@ -3716,6 +3743,8 @@ void P_NullPrecipThinker(precipmobj_t *mobj)
void P_SnowThinker(precipmobj_t *mobj)
{
P_CycleStateAnimation((mobj_t *)mobj);
// adjust height
if ((mobj->z += mobj->momz) <= mobj->floorz)
mobj->z = mobj->ceilingz;
@ -3723,6 +3752,8 @@ void P_SnowThinker(precipmobj_t *mobj)
void P_RainThinker(precipmobj_t *mobj)
{
P_CycleStateAnimation((mobj_t *)mobj);
if (mobj->state != &states[S_RAIN1])
{
// cycle through states,
@ -5833,8 +5864,6 @@ INT32 numshields = 0;
void P_RunShields(void)
{
INT32 i;
mobj_t *mo, *next;
fixed_t destx,desty,zoffs;
// run shields
for (i = 0; i < numshields; i++)
@ -5843,60 +5872,6 @@ void P_RunShields(void)
P_SetTarget(&shields[i], NULL);
}
numshields = 0;
// run overlays
next = NULL;
for (mo = overlaycap; mo; mo = next)
{
I_Assert(!P_MobjWasRemoved(mo));
// grab next in chain, then unset the chain target
next = mo->hnext;
P_SetTarget(&mo->hnext, NULL);
if (!mo->target)
continue;
if (!splitscreen /*&& rendermode != render_soft*/)
{
angle_t viewingangle;
if (players[displayplayer].awayviewtics)
viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].awayviewmobj->x, players[displayplayer].awayviewmobj->y);
else if (!camera.chase && players[displayplayer].mo)
viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].mo->x, players[displayplayer].mo->y);
else
viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, camera.x, camera.y);
if (mo->state->var1)
viewingangle += ANGLE_180;
destx = mo->target->x + P_ReturnThrustX(mo->target, viewingangle, FixedMul(FRACUNIT/4, mo->scale));
desty = mo->target->y + P_ReturnThrustY(mo->target, viewingangle, FixedMul(FRACUNIT/4, mo->scale));
}
else
{
destx = mo->target->x;
desty = mo->target->y;
}
mo->eflags = (mo->eflags & ~MFE_VERTICALFLIP) | (mo->target->eflags & MFE_VERTICALFLIP);
mo->scale = mo->destscale = mo->target->scale;
zoffs = FixedMul(((signed)mo->state->var2)*FRACUNIT, mo->scale);
mo->angle = mo->target->angle;
P_UnsetThingPosition(mo);
mo->x = destx;
mo->y = desty;
if (mo->eflags & MFE_VERTICALFLIP)
mo->z = (mo->target->z + mo->target->height - mo->height) - zoffs;
else
mo->z = mo->target->z + zoffs;
if (mo->state->var1)
P_SetUnderlayPosition(mo);
else
P_SetThingPosition(mo);
P_CheckPosition(mo, mo->x, mo->y);
}
P_SetTarget(&overlaycap, NULL);
}
static boolean P_AddShield(mobj_t *thing)
@ -5933,6 +5908,71 @@ static boolean P_AddShield(mobj_t *thing)
return true;
}
void P_RunOverlays(void)
{
// run overlays
mobj_t *mo, *next = NULL;
fixed_t destx,desty,zoffs;
for (mo = overlaycap; mo; mo = next)
{
I_Assert(!P_MobjWasRemoved(mo));
// grab next in chain, then unset the chain target
next = mo->hnext;
P_SetTarget(&mo->hnext, NULL);
if (!mo->target)
continue;
if (!splitscreen /*&& rendermode != render_soft*/)
{
angle_t viewingangle;
if (players[displayplayer].awayviewtics)
viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].awayviewmobj->x, players[displayplayer].awayviewmobj->y);
else if (!camera.chase && players[displayplayer].mo)
viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].mo->x, players[displayplayer].mo->y);
else
viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, camera.x, camera.y);
if (!(mo->state->frame & FF_ANIMATE) && mo->state->var1)
viewingangle += ANGLE_180;
destx = mo->target->x + P_ReturnThrustX(mo->target, viewingangle, FixedMul(FRACUNIT/4, mo->scale));
desty = mo->target->y + P_ReturnThrustY(mo->target, viewingangle, FixedMul(FRACUNIT/4, mo->scale));
}
else
{
destx = mo->target->x;
desty = mo->target->y;
}
mo->eflags = (mo->eflags & ~MFE_VERTICALFLIP) | (mo->target->eflags & MFE_VERTICALFLIP);
mo->scale = mo->destscale = mo->target->scale;
mo->angle = mo->target->angle;
if (!(mo->state->frame & FF_ANIMATE))
zoffs = FixedMul(((signed)mo->state->var2)*FRACUNIT, mo->scale);
// if you're using FF_ANIMATE on an overlay,
// then you're on your own.
else
zoffs = 0;
P_UnsetThingPosition(mo);
mo->x = destx;
mo->y = desty;
if (mo->eflags & MFE_VERTICALFLIP)
mo->z = (mo->target->z + mo->target->height - mo->height) - zoffs;
else
mo->z = mo->target->z + zoffs;
if (mo->state->var1)
P_SetUnderlayPosition(mo);
else
P_SetThingPosition(mo);
P_CheckPosition(mo, mo->x, mo->y);
}
P_SetTarget(&overlaycap, NULL);
}
// Called only when MT_OVERLAY thinks.
static void P_AddOverlay(mobj_t *thing)
{
@ -6041,7 +6081,8 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->tracer && P_MobjWasRemoved(mobj->tracer))
P_SetTarget(&mobj->tracer, NULL);
mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG);
mobj->flags2 &= ~MF2_PUSHED;
mobj->eflags &= ~MFE_SPRUNG;
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.
switch (mobj->type)
{
#ifdef BLUE_SPHERES
case MT_BLUEBALL:
if ((mobj->tics>>2)+1 > 0 && (mobj->tics>>2)+1 <= tr_trans60) // tr_trans50 through tr_trans90, shifting once every second frame
mobj->frame = (NUMTRANSMAPS-((mobj->tics>>2)+1))<<FF_TRANSSHIFT;
else // tr_trans60 otherwise
mobj->frame = tr_trans60<<FF_TRANSSHIFT;
break;
#endif
case MT_EGGCAPSULE:
if (mobj->z <= mobj->floorz)
{
@ -6901,9 +6940,7 @@ void P_MobjThinker(mobj_t *mobj)
break;
case MT_RING:
case MT_COIN:
#ifdef BLUE_SPHERES
case MT_BLUEBALL:
#endif
case MT_REDTEAMRING:
case MT_BLUETEAMRING:
// No need to check water. Who cares?
@ -7112,9 +7149,10 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->type == MT_REDFLAG)
{
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);
redflag = flagmo;
@ -7122,9 +7160,10 @@ void P_MobjThinker(mobj_t *mobj)
else // MT_BLUEFLAG
{
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);
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->sprite = st->sprite;
mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits..
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set
mobj->friction = ORIG_FRICTION;
mobj->movefactor = ORIG_FRICTION_FACTOR;
@ -7667,9 +7708,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
break;
case MT_RING:
case MT_COIN:
#ifdef BLUE_SPHERES
case MT_BLUEBALL:
#endif
nummaprings++;
default:
break;
@ -7727,6 +7766,7 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
mobj->tics = st->tics;
mobj->sprite = st->sprite;
mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits..
mobj->anim_duration = (UINT16)st->var2; // only used if FF_ANIMATE is set
// set subsector and/or block links
P_SetPrecipitationThingPosition(mobj);
@ -7794,9 +7834,7 @@ void P_RemoveMobj(mobj_t *mobj)
if (mobj->spawnpoint &&
(mobj->type == MT_RING
|| mobj->type == MT_COIN
#ifdef BLUE_SPHERES
|| mobj->type == MT_BLUEBALL
#endif
|| mobj->type == MT_REDTEAMRING
|| mobj->type == MT_BLUETEAMRING
|| P_WeaponOrPanel(mobj->type))
@ -8521,6 +8559,9 @@ void P_SpawnMapThing(mapthing_t *mthing)
return;
}
else if (mthing->type == 750) // Slope vertex point (formerly chaos spawn)
return;
else if (mthing->type == 300 // Ring
|| mthing->type == 308 || mthing->type == 309 // Team Rings
|| mthing->type == 1706 // Nights Wing
@ -8554,8 +8595,7 @@ void P_SpawnMapThing(mapthing_t *mthing)
if (i == NUMMOBJTYPES)
{
if (mthing->type == 3328 // 3D Mode start Thing
|| mthing->type == 750) // Chaos mode spawn
if (mthing->type == 3328) // 3D Mode start Thing
return;
CONS_Alert(CONS_WARNING, M_GetText("Unknown thing type %d placed at (%d, %d)\n"), mthing->type, mthing->x, mthing->y);
i = MT_UNKNOWN;
@ -8863,6 +8903,7 @@ void P_SpawnMapThing(mapthing_t *mthing)
const size_t mthingi = (size_t)(mthing - mapthings);
// 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++)
{
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
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
@ -9582,11 +9619,9 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
ringthing = (gametype == GT_CTF) ? MT_BLUETEAMRING : MT_RING;
break;
default:
#ifdef BLUE_SPHERES
// Spawn rings as blue spheres in special stages, ala S3+K.
if (G_IsSpecialStage(gamemap) && useNightsSS)
ringthing = MT_BLUEBALL;
#endif
break;
}
@ -9651,11 +9686,9 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
if (ultimatemode && !(G_IsSpecialStage(gamemap) || maptol & TOL_NIGHTS))
return;
#ifdef BLUE_SPHERES
// Spawn rings as blue spheres in special stages, ala S3+K.
if (G_IsSpecialStage(gamemap) && useNightsSS)
ringthing = MT_BLUEBALL;
#endif
for (r = 1; r <= 5; r++)
{
@ -9706,11 +9739,9 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
if (ultimatemode && !(G_IsSpecialStage(gamemap) || maptol & TOL_NIGHTS))
return;
#ifdef BLUE_SPHERES
// Spawn rings as blue spheres in special stages, ala S3+K.
if (G_IsSpecialStage(gamemap) && useNightsSS)
ringthing = MT_BLUEBALL;
#endif
angle >>= ANGLETOFINESHIFT;
@ -9803,11 +9834,9 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
if (ultimatemode && !(G_IsSpecialStage(gamemap) || (maptol & TOL_NIGHTS)))
continue;
#ifdef BLUE_SPHERES
// Spawn rings as blue spheres in special stages, ala S3+K.
if (G_IsSpecialStage(gamemap) && useNightsSS)
itemToSpawn = MT_BLUEBALL;
#endif
}
fa = i*FINEANGLES/numitems;

View file

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

View file

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

View file

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

View file

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

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 P_AddBlockThinker(sector_t *sec, 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_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec);
static void Add_Friction(INT32 friction, INT32 movefactor, INT32 affectee, INT32 referrer);
@ -594,6 +594,7 @@ void P_SetupLevelFlatAnims(void)
// UTILITIES
//
#if 0
/** Gets a side from a sector line.
*
* \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;
}
#endif
/** 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 == 307 // Character ability - Once
|| specialtype == 308 // Race only - Once
|| specialtype == 313 // No More Enemies - Once
|| specialtype == 315 // No of pushables - Once
|| specialtype == 318 // Unlockable trigger - 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
if ((line->flags & ML_NOCLIMB) || (mo && mo->player && P_IsLocalPlayer(mo->player)))
{
UINT16 musicnum = (UINT16)sides[line->sidenum[0]].toptexture; //P_AproxDistance(line->dx, line->dy)>>FRACBITS;
UINT16 tracknum = (UINT16)sides[line->sidenum[0]].bottomtexture;
mapmusic = musicnum | (tracknum << MUSIC_TRACKSHIFT);
if (!(line->flags & ML_BLOCKMONSTERS))
mapmusic |= MUSIC_RELOADRESET;
strncpy(mapmusname, sides[line->sidenum[0]].text, 7);
mapmusname[6] = 0;
if (musicnum >= NUMMUSIC || musicnum == mus_None)
S_StopMusic();
else
S_ChangeMusic(mapmusic, !(line->flags & ML_EFFECT4));
mapmusflags = tracknum & MUSIC_TRACKMASK;
if (!(line->flags & ML_BLOCKMONSTERS))
mapmusflags |= MUSIC_RELOADRESET;
S_ChangeMusic(mapmusname, mapmusflags, !(line->flags & ML_EFFECT4));
// Except, you can use the ML_BLOCKMONSTERS flag to change this behavior.
// if (mapmusic & MUSIC_RELOADRESET) then it will reset the music in G_PlayerReborn.
// if (mapmusflags & MUSIC_RELOADRESET) then it will reset the music in G_PlayerReborn.
}
break;
@ -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);
sector_t *sec; // Sector that the FOF is visible (or not visible) in
ffloor_t *rover; // FOF to vanish/un-vanish
ffloortype_e oldflags; // store FOF's old flags
for (secnum = -1; (secnum = P_FindSectorFromTag(sectag, secnum)) >= 0 ;)
{
@ -3062,11 +3063,17 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
return;
}
oldflags = rover->flags;
// Abracadabra!
if (line->flags & ML_NOCLIMB)
rover->flags |= FF_EXISTS;
else
rover->flags &= ~FF_EXISTS;
// if flags changed, reset sector's light list
if (rover->flags != oldflags)
sec->moved = true;
}
}
break;
@ -3774,7 +3781,7 @@ DoneSection2:
HU_SetCEchoDuration(5);
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);
else if (players[consoleplayer].ctfteam == 2)
S_StartSound(NULL, sfx_lose);
@ -3807,7 +3814,7 @@ DoneSection2:
HU_SetCEchoDuration(5);
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);
else if (players[consoleplayer].ctfteam == 1)
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
* \author SSNTails <http://www.ssntails.org>
*/
/*
static inline void P_AddBridgeThinker(line_t *sourceline, sector_t *sec)
{
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[5] = (sides[sourceline->sidenum[0]].textureoffset>>FRACBITS); // End tag
}
*/
/** Adds a Mario block thinker, which changes the block's texture between blank
* and ? depending on whether it has contents.
@ -6023,31 +6032,6 @@ void P_SpawnSpecials(INT32 fromnetsave)
P_AddRaiseThinker(lines[i].frontsector, &lines[i]);
break;
#ifdef SLOPENESS
case 999:
sec = sides[*lines[i].sidenum].sector-sectors;
for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
{
size_t counting;
sectors[s].floorangle = ANGLE_45;
for (counting = 0; counting < sectors[s].linecount/2; counting++)
{
sectors[s].lines[counting]->v1->z = sectors[sec].floorheight;
CONS_Debug(DBG_GAMELOGIC, "Set it to %d\n", sectors[s].lines[counting]->v1->z>>FRACBITS);
}
for (counting = sectors[s].linecount/2; counting < sectors[s].linecount; counting++)
{
sectors[s].lines[counting]->v1->z = sectors[sec].ceilingheight;
CONS_Debug(DBG_GAMELOGIC, "Set it to %d\n", sectors[s].lines[counting]->v1->z>>FRACBITS);
}
sectors[s].special = 65535;
CONS_Debug(DBG_GAMELOGIC, "Found & Set slope!\n");
}
break;
#endif
case 200: // Double light effect
P_AddFakeFloorsByLine(i, FF_EXISTS|FF_CUTSPRITES|FF_DOUBLESHADOW, secthinkers);
break;
@ -6462,7 +6446,7 @@ static void P_DoScrollMove(mobj_t *thing, fixed_t dx, fixed_t dy, INT32 exclusiv
thing->momy += dy;
if (exclusive)
thing->eflags |= MFE_PUSHED;
thing->flags2 |= MF2_PUSHED;
}
/** Processes an active scroller.
@ -6566,7 +6550,7 @@ void T_Scroll(scroll_t *s)
{
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;
height = P_GetSpecialBottomZ(thing, sec, psec);
@ -6588,7 +6572,7 @@ void T_Scroll(scroll_t *s)
{
thing = node->m_thing;
if (thing->eflags & MFE_PUSHED)
if (thing->flags2 & MF2_PUSHED)
continue;
height = P_GetSpecialBottomZ(thing, sec, sec);
@ -6629,7 +6613,7 @@ void T_Scroll(scroll_t *s)
{
thing = node->m_thing;
if (thing->eflags & MFE_PUSHED)
if (thing->flags2 & MF2_PUSHED)
continue;
height = P_GetSpecialTopZ(thing, sec, psec);
@ -6651,7 +6635,7 @@ void T_Scroll(scroll_t *s)
{
thing = node->m_thing;
if (thing->eflags & MFE_PUSHED)
if (thing->flags2 & MF2_PUSHED)
continue;
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)
{
if (thing->eflags & MFE_PUSHED)
if (thing->flags2 & MF2_PUSHED)
return false;
if (thing->player && thing->player->pflags & PF_ROPEHANG)
@ -7264,7 +7248,7 @@ static inline boolean PIT_PushThing(mobj_t *thing)
}
if (tmpusher->exclusive)
thing->eflags |= MFE_PUSHED;
thing->flags2 |= MF2_PUSHED;
return true;
}
@ -7367,7 +7351,7 @@ void T_Pusher(pusher_t *p)
|| thing->type == MT_BIGTUMBLEWEED))
continue;
if (thing->eflags & MFE_PUSHED)
if (thing->flags2 & MF2_PUSHED)
continue;
if (thing->player && thing->player->pflags & PF_ROPEHANG)
@ -7534,7 +7518,7 @@ void T_Pusher(pusher_t *p)
}
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
P_RunShields();
P_RunOverlays();
P_UpdateSpecials();
P_RespawnSpecials();
@ -742,6 +743,7 @@ void P_PreTicker(INT32 frames)
// Run shield positioning
P_RunShields();
P_RunOverlays();
P_UpdateSpecials();
P_RespawnSpecials();

View file

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

View file

@ -26,6 +26,7 @@ side_t *sidedef;
line_t *linedef;
sector_t *frontsector;
sector_t *backsector;
boolean portalline; // is curline a portal seg?
// 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
@ -378,6 +379,7 @@ static void R_AddLine(seg_t *line)
return;
curline = line;
portalline = false;
// OPTIMIZE: quickly reject orthogonal back sides.
angle1 = R_PointToAngle(line->v1->x, line->v1->y);
@ -431,7 +433,7 @@ static void R_AddLine(seg_t *line)
backsector = line->backsector;
// 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)
{

View file

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

View file

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

View file

@ -91,7 +91,6 @@ typedef struct portal_pair
INT16 *ceilingclip;
INT16 *floorclip;
fixed_t *frontscale;
size_t seg;
} portal_pair;
portal_pair *portal_base, *portal_cap;
line_t *portalclipline;
@ -1230,7 +1229,7 @@ void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2)
portal->start = x1;
portal->end = x2;
portal->seg = ds_p-drawsegs;
portalline = true; // this tells R_StoreWallRange that curline is a portal seg
portal->viewx = viewx;
portal->viewy = viewy;
@ -1344,14 +1343,6 @@ void R_RenderPlayerView(player_t *player)
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_ClipSprites();
//R_DrawPlanes();
@ -1360,6 +1351,9 @@ void R_RenderPlayerView(player_t *player)
// okay done. free it.
portalcullsector = NULL; // Just in case...
portal_base = portal->next;
Z_Free(portal->ceilingclip);
Z_Free(portal->floorclip);
Z_Free(portal->frontscale);
Z_Free(portal);
}
// END PORTAL RENDERING
@ -1388,6 +1382,7 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_allowmlook);
CV_RegisterVar(&cv_homremoval);
CV_RegisterVar(&cv_flipcam);
CV_RegisterVar(&cv_flipcam2);
// Enough for dedicated server
if (dedicated)

View file

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

View file

@ -551,11 +551,6 @@ void R_ClearSprites(void)
visspritecount = clippedvissprites = 0;
}
static inline void R_ResetVisSpriteChunks(void)
{
memset(visspritechunks, 0, sizeof(visspritechunks));
}
//
// R_NewVisSprite
//
@ -839,10 +834,10 @@ static void R_DrawVisSprite(vissprite_t *vis)
dc_texturemid = FixedDiv(dc_texturemid,this_scale);
//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);
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);
//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)
&& (!newsprite->extra_colormap || !newsprite->extra_colormap->fog)))
{
lindex = sprite->xscale>>(LIGHTSCALESHIFT);
lindex = FixedMul(sprite->xscale, FixedDiv(640, vid.width))>>(LIGHTSCALESHIFT);
if (lindex >= MAXLIGHTSCALE)
lindex = MAXLIGHTSCALE-1;
@ -1306,7 +1301,7 @@ static void R_ProjectSprite(mobj_t *thing)
}
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
// than lumpid for sprites-in-pwad : the graphics are patched
@ -1334,7 +1329,7 @@ static void R_ProjectSprite(mobj_t *thing)
else
{
// diminished light
lindex = xscale>>(LIGHTSCALESHIFT);
lindex = FixedMul(xscale, FixedDiv(640, vid.width))>>(LIGHTSCALESHIFT);
if (lindex >= MAXLIGHTSCALE)
lindex = MAXLIGHTSCALE-1;
@ -2058,6 +2053,9 @@ void R_ClipSprites(void)
continue;
}
if (ds->portalpass > 0 && ds->portalpass <= portalrender)
continue; // is a portal
r1 = ds->x1 < spr->x1 ? spr->x1 : ds->x1;
r2 = ds->x2 > spr->x2 ? spr->x2 : ds->x2;
@ -2698,9 +2696,6 @@ next_token:
}
free(buf2);
// Not in vanilla, you don't.
skin->flags &= ~SF_SUPER;
lump++; // if no sprite defined use spirte just after this one
if (skin->sprite[0] == '\0')
{

View file

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

View file

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

View file

@ -126,8 +126,6 @@ static Uint8 BitsPerPixel = 16;
#endif
Uint16 realwidth = BASEVIDWIDTH;
Uint16 realheight = BASEVIDHEIGHT;
static const Uint32 surfaceFlagsW = 0/*|SDL_RESIZABLE*/;
static const Uint32 surfaceFlagsF = 0;
static SDL_bool mousegrabok = SDL_TRUE;
#define HalfWarpMouse(x,y) SDL_WarpMouseInWindow(window, (Uint16)(x/2),(Uint16)(y/2))
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
//

View file

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

View file

@ -395,6 +395,7 @@ void I_FreeSfx(sfxinfo_t *sfx)
if (sfx->data)
Mix_FreeChunk(sfx->data);
sfx->data = NULL;
sfx->lumpnum = LUMPERROR;
}
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority)
@ -528,14 +529,8 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
#endif
if (lumpnum == LUMPERROR)
{
lumpnum = W_CheckNumForName(va("D_%s",musicname));
if (lumpnum == LUMPERROR)
return false;
midimode = true;
}
else
midimode = false;
return false;
midimode = false;
data = (char *)W_CacheLumpNum(lumpnum, PU_MUSIC);
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());
return true;
}
if (midimode)
Mix_VolumeMusic((UINT32)midi_volume*128/31);
else
Mix_VolumeMusic((UINT32)music_volume*128/31);
Mix_VolumeMusic((UINT32)music_volume*128/31);
if (loop_point != 0.0f)
Mix_HookMusicFinished(music_loop);
@ -791,10 +783,15 @@ void I_ShutdownMIDIMusic(void)
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)
return;
Mix_VolumeMusic((UINT32)volume*128/31);
Mix_VolumeMusic((UINT32)midi_volume*128/31);
}
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());
return false;
}
Mix_VolumeMusic((UINT32)music_volume*128/31);
Mix_VolumeMusic((UINT32)midi_volume*128/31);
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();
}
void ST_Drawer(boolean refresh)
void ST_Drawer(void)
{
#ifdef SEENAMES
if (cv_seenames.value && cv_allowseenames.value && displayplayer == consoleplayer && seenplayer && seenplayer->mo)
@ -1906,8 +1906,11 @@ void ST_Drawer(boolean refresh)
}
#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()
(void)refresh; //?
if (vid.recalc)
st_palette = -1;

View file

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

View file

@ -15,6 +15,8 @@
#include <string.h>
#include "doomdef.h"
#if !defined (__APPLE__)
// Like the OpenBSD version, but it doesn't check for src not being a valid
// C string.
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';
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;
UINT8 *desttop, *dest, *deststart, *destend;
const UINT8 *source, *deststop;
fixed_t pwidth; // patch width
fixed_t offx = 0; // x offset
if (rendermode == render_none)
return;
@ -476,16 +478,36 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
}
}
deststart = desttop;
destend = desttop + SHORT(patch->width) * dupx;
if (pscale != FRACUNIT) // scale width properly
{
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;
if (x < 0) // don't draw off the left of the screen (WRAP PREVENTION)
continue;
if (x >= vid.width) // don't draw off the right of the screen (WRAP PREVENTION)
break;
if (flip) // offx is measured from right edge instead of left
{
if (x+pwidth-offx < 0) // don't draw off the left of the screen (WRAP PREVENTION)
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]));
while (column->topdelta != 0xff)

View file

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

View file

@ -77,10 +77,14 @@ typedef union
struct
{
char passed1[13]; // KNUCKLES GOT
char passed2[16]; // A CHAOS EMERALD
char passed1[SKINNAMESIZE+1]; // KNUCKLES GOT / CRAWLA HONCHO
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 passedx2;
INT32 passedx3;
INT32 passedx4;
y_bonus_t bonus;
patch_t *bonuspatch;
@ -250,19 +254,62 @@ void Y_IntermissionDrawer(void)
}
else if (intertype == int_spec)
{
// draw the header
/* if (endtic != -1 && ALL7EMERALDS(emeralds) && data.spec.nowsuper != NULL)
V_DrawScaledPatch(48, 32, 0, data.spec.nowsuper);
else
V_DrawScaledPatch(data.spec.headx, 26, 0, data.spec.cemerald); */
static tic_t animatetic = 0;
INT32 ttheight = 16;
INT32 xoffset1 = 0; // Line 1 x offset
INT32 xoffset2 = 0; // Line 2 x offset
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);
V_DrawLevelTitle(data.spec.passedx2, 24+V_LevelNameHeight(data.spec.passed2)+2, 0, data.spec.passed2);
INT32 animatetimer = (intertic - animatetic);
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
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
if (intertic & 1)
@ -632,7 +679,7 @@ void Y_Ticker(void)
boolean anybonuses = false;
if (!intertic) // first time only
S_ChangeMusic(mus_lclear, false); // don't loop it
S_ChangeMusicInternal("lclear", false); // don't loop it
if (intertic < TICRATE) // one second pause before tally begins
return;
@ -693,7 +740,7 @@ void Y_Ticker(void)
if (!intertic) // first time only
{
S_ChangeMusic(mus_lclear, false); // don't loop it
S_ChangeMusicInternal("lclear", false); // don't loop it
tallydonetic = 0;
}
@ -708,7 +755,7 @@ void Y_Ticker(void)
{
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!
}
return;
@ -728,7 +775,7 @@ void Y_Ticker(void)
if (data.spec.continues & 0x80) // don't set endtic yet!
tallydonetic = intertic + (3*TICRATE)/2;
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!
@ -754,7 +801,7 @@ void Y_Ticker(void)
else if (intertype == int_match || intertype == int_ctf || intertype == int_teammatch) // match
{
if (!intertic) // first time only
S_ChangeMusic(mus_racent, true); // loop it
S_ChangeMusicInternal("racent", true); // loop it
// If a player has left or joined, recalculate scores.
if (data.match.numplayers != D_NumPlayers())
@ -763,7 +810,7 @@ void Y_Ticker(void)
else if (intertype == int_race || intertype == int_classicrace) // race
{
if (!intertic) // first time only
S_ChangeMusic(mus_racent, true); // loop it
S_ChangeMusicInternal("racent", true); // loop it
// Don't bother recalcing for race. It doesn't make as much sense.
}
@ -1098,6 +1145,10 @@ void Y_StartIntermission(void)
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
if (stagefailed)
{
@ -1111,10 +1162,19 @@ void Y_StartIntermission(void)
skins[players[consoleplayer].skin].realname);
data.spec.passed1[sizeof data.spec.passed1 - 1] = '\0';
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
{
if (strlen(skins[players[consoleplayer].skin].realname) <= 8)
if (strlen(skins[players[consoleplayer].skin].realname) <= SKINNAMESIZE-5)
{
snprintf(data.spec.passed1,
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.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;
}