Merge branch 'master' of http://git.magicalgirl.moe/STJr/SRB2Internal.git into FileManagement

# Conflicts:
#	src/p_setup.c
This commit is contained in:
Nevur 2017-06-25 14:51:37 +02:00
commit d5e38c087d
99 changed files with 3679 additions and 1797 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.0)
project(SRB2
VERSION 2.1.17
VERSION 2.1.19
LANGUAGES C)
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})

View File

@ -1,4 +1,4 @@
version: 2.1.17.{branch}-{build}
version: 2.1.19.{branch}-{build}
os: MinGW
environment:
@ -47,7 +47,7 @@ before_build:
- upx -V
- ccache -V
- ccache -s
- set SRB2_MFLAGS=-C src MINGW=1 WARNINGMODE=1 GCC63=1 CCACHE=1
- set SRB2_MFLAGS=-C src MINGW=1 WARNINGMODE=1 GCC63=1 CCACHE=1 NOOBJDUMP=1
build_script:
- cmd: mingw32-make.exe %SRB2_MFLAGS% %CONFIGURATION%=1 clean
@ -58,26 +58,29 @@ after_build:
- cmd: git rev-parse --short %APPVEYOR_REPO_COMMIT%>%TMP%/gitshort.txt
- cmd: set /P GITSHORT=<%TMP%/gitshort.txt
- set BUILD_ARCHIVE=%APPVEYOR_REPO_BRANCH%-%GITSHORT%-%CONFIGURATION%.7z
- set BUILDSARCHIVE=%APPVEYOR_REPO_BRANCH%-%CONFIGURATION%.7z
- cmd: 7z a %BUILD_ARCHIVE% bin\Mingw\Release -xr!.gitignore
- appveyor PushArtifact %BUILD_ARCHIVE%
- cmd: copy %BUILD_ARCHIVE% %BUILDSARCHIVE%
- appveyor PushArtifact %BUILDSARCHIVE%
test: off
deploy:
- provider: FTP
protocol: ftps
host:
secure: NsLJEPIBvmwCOj8Tg8RoRQ==
username:
secure: ejxi5mvk7oLYu7QtbYojajEPigMy0mokaKhuEVuDZcA=
password:
secure: Hbn6Uy3lT0YZ88yFJ3aW4w==
folder: appveyor
application:
active_mode: false
on:
branch: master
appveyor_repo_tag: true
#deploy:
# - provider: FTP
# protocol: ftps
# host:
# secure: NsLJEPIBvmwCOj8Tg8RoRQ==
# username:
# secure: ejxi5mvk7oLYu7QtbYojajEPigMy0mokaKhuEVuDZcA=
# password:
# secure: Hbn6Uy3lT0YZ88yFJ3aW4w==
# folder: appveyor
# application:
# active_mode: false
# on:
# branch: master
# appveyor_repo_tag: true
on_finish:

View File

@ -1,3 +1,3 @@
/srb2sdl.exe
/srb2win.exe
/r_opengl.dll
*.exe
*.mo
r_opengl.dll

View File

@ -1,3 +1,3 @@
/srb2sdl.exe
/srb2win.exe
/r_opengl.dll
*.exe
*.mo
r_opengl.dll

8
objs/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
#All folders
SRB2.res
depend.dep
depend.ped
*.o
#VC9 folder only
/VC9/Win32
/VC9/x64

View File

@ -1 +1,2 @@
/depend.dep
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1 +1,2 @@
/depend.dep
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1,2 +1,2 @@
/depend.dep
/*.o
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1,2 +1,2 @@
/depend.dep
/*.o
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1,2 +1,2 @@
/depend.dep
/*.o
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1,2 +1,2 @@
/depend.dep
/*.o
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1,3 +1,2 @@
/SRB2.res
/depend.dep
/*.o
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1,3 +1,2 @@
/SRB2.res
/depend.dep
/*.o
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1,3 +1,2 @@
/SRB2.res
/depend.dep
/*.o
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1,3 +1,2 @@
/SRB2.res
/depend.dep
/*.o
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1,3 +1,2 @@
/SRB2.res
/depend.dep
/*.o
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1,3 +1,2 @@
/SRB2.res
/depend.dep
/*.o
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1,3 +1,2 @@
/SRB2.res
/depend.dep
/*.o
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1,3 +1,2 @@
/SRB2.res
/depend.dep
/*.o
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1,2 +1,2 @@
/depend.dep
/*.o
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1,2 +1,2 @@
/depend.dep
/*.o
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1 +1,2 @@
/depend.dep
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1 +1,2 @@
/depend.ped
# DON'T REMOVE
# This keeps the folder from disappearing

2
objs/VC/.gitignore vendored
View File

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

4
objs/VC9/.gitignore vendored
View File

@ -1,2 +1,2 @@
/Win32
/x64
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1,2 +1,2 @@
/depend.dep
/*.o
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1,2 +1,2 @@
/depend.dep
/*.o
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1 +1,2 @@
/depend.dep
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1 +1,2 @@
/depend.dep
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1 +1,2 @@
/depend.dep
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1,2 +1,2 @@
/depend.dep
/*.o
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -1,2 +1,2 @@
/depend.dep
/*.o
# DON'T REMOVE
# This keeps the folder from disappearing

View File

@ -511,13 +511,11 @@ OBJS:=$(i_main_o) \
# For reference, this is the command I use to build a srb2.pot file from the source code.
# (The listed source files are the ones containing translated strings).
# FILES=""; for file in `find ./ | grep "\.c" | grep -v svn`; do [ "`grep "M_GetText(" $file`" ] && FILES="$FILES $file"; done; xgettext -d srb2 -o locale/srb2.pot -kM_GetText -F --no-wrap $FILES
ifndef NOGETTEXT
ifdef GETTEXT
POS:=$(BIN)/en.mo
OPTS+=-DGETTEXT
endif
endif
ifdef DJGPPDOS
all: pre-build $(BIN)/$(EXENAME)

View File

@ -283,9 +283,6 @@ else
ifdef LINUX
NASMFORMAT=elf -DLINUX
SDL=1
ifndef NOGETTEXT
GETTEXT=1
endif
ifdef LINUX64
OBJDIR:=$(OBJDIR)/Linux64
BIN:=$(BIN)/Linux64
@ -321,9 +318,6 @@ else
ifdef MINGW64
INTERFACE=win32
#NASMFORMAT=win64
ifndef NOGETTEXT
#GETTEXT=1
endif
OBJDIR:=$(OBJDIR)/Mingw64
BIN:=$(BIN)/Mingw64
else
@ -354,9 +348,6 @@ else
ifdef MINGW
INTERFACE=win32
NASMFORMAT=win32
ifndef NOGETTEXT
GETTEXT=1
endif
OBJDIR:=$(OBJDIR)/Mingw
BIN:=$(BIN)/Mingw
else

View File

@ -1394,32 +1394,32 @@ static void CON_DrawInput(void)
if (input_sel < c)
V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 77 | V_NOSCALESTART);
for (i = 0; i < 3; ++i, x += charwidth)
V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value);
V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, true);
}
else
V_DrawCharacter(x-charwidth, y, CON_PROMPTCHAR | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value);
V_DrawCharacter(x-charwidth, y, CON_PROMPTCHAR | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, true);
for (cend = c + clen; c < cend; ++c, x += charwidth)
{
if ((input_sel > c && input_cur <= c) || (input_sel <= c && input_cur > c))
{
V_DrawFill(x, y, charwidth, (10 * con_scalefactor), 77 | V_NOSCALESTART);
V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_YELLOWMAP | V_NOSCALESTART, !cv_allcaps.value);
V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_YELLOWMAP | V_NOSCALESTART, true);
}
else
V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, true);
if (c == input_cur && con_tick >= 4)
V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, true);
}
if (cend == input_cur && con_tick >= 4)
V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, true);
if (rellip)
{
if (input_sel > cend)
V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 77 | V_NOSCALESTART);
for (i = 0; i < 3; ++i, x += charwidth)
V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, !cv_allcaps.value);
V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, true);
}
}
@ -1465,11 +1465,11 @@ static void CON_DrawHudlines(void)
else
{
//charwidth = SHORT(hu_font['A'-HU_FONTSTART]->width) * con_scalefactor;
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, true);
}
}
//V_DrawCharacter(x, y, (p[c]&0xff) | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
//V_DrawCharacter(x, y, (p[c]&0xff) | cv_constextsize.value | V_NOSCALESTART, true);
y += charheight;
}
@ -1607,7 +1607,7 @@ static void CON_DrawConsole(void)
charflags = (*p & 0x7f) << V_CHARCOLORSHIFT;
p++;
}
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, true);
}
}

View File

@ -1740,9 +1740,7 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
{
#ifndef NONET
INT32 i;
#endif
#ifndef NONET
// serverlist is updated by GetPacket function
if (serverlistcount > 0)
{
@ -1776,7 +1774,20 @@ static boolean CL_ServerConnectionSearchTicker(boolean viams, tic_t *asksent)
serverlist[i].info.fileneeded);
CONS_Printf(M_GetText("Checking files...\n"));
i = CL_CheckFiles();
if (i == 2) // cannot join for some reason
if (i == 3) // too many files
{
D_QuitNetGame();
CL_Reset();
D_StartTitle();
M_StartMessage(M_GetText(
"You have too many WAD files loaded\n"
"to add ones the server is using.\n"
"Please restart SRB2 before connecting.\n\n"
"Press ESC\n"
), NULL, MM_NOTHING);
return false;
}
else if (i == 2) // cannot join for some reason
{
D_QuitNetGame();
CL_Reset();
@ -2533,7 +2544,7 @@ static void Command_Ban(void)
return;
else
WRITEUINT8(p, pn);
if (I_Ban && !I_Ban(node))
if (server && I_Ban && !I_Ban(node)) // only the server is allowed to do this right now
{
CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n"));
WRITEUINT8(p, KICK_MSG_GO_AWAY);
@ -2541,7 +2552,8 @@ static void Command_Ban(void)
}
else
{
Ban_Add(COM_Argv(2));
if (server) // only the server is allowed to do this right now
Ban_Add(COM_Argv(2));
if (COM_Argc() == 2)
{
@ -2698,12 +2710,14 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
// If a verified admin banned someone, the server needs to know about it.
// If the playernum isn't zero (the server) then the server needs to record the ban.
if (server && playernum && msg == KICK_MSG_BANNED)
if (server && playernum && (msg == KICK_MSG_BANNED || msg == KICK_MSG_CUSTOM_BAN))
{
if (I_Ban && !I_Ban(playernode[(INT32)pnum]))
{
CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n"));
}
#ifndef NONET
else
Ban_Add(reason);
#endif
}
switch (msg)
@ -3401,17 +3415,42 @@ static void HandlePacketFromAwayNode(SINT8 node)
if (node != servernode)
DEBFILE(va("Received packet from unknown host %d\n", node));
// macro for packets that should only be sent by the server
// if it is NOT from the server, bail out and close the connection!
#define SERVERONLY \
if (node != servernode) \
{ \
Net_CloseConnection(node); \
break; \
}
switch (netbuffer->packettype)
{
case PT_ASKINFOVIAMS:
#if 0
if (server && serverrunning)
{
INT32 clientnode = I_NetMakeNode(netbuffer->u.msaskinfo.clientaddr);
SV_SendServerInfo(clientnode, (tic_t)LONG(netbuffer->u.msaskinfo.time));
SV_SendPlayerInfo(clientnode); // Send extra info
Net_CloseConnection(clientnode);
// Don't close connection to MS.
INT32 clientnode;
if (ms_RoomId < 0) // ignore if we're not actually on the MS right now
{
Net_CloseConnection(node); // and yes, close connection
return;
}
clientnode = I_NetMakeNode(netbuffer->u.msaskinfo.clientaddr);
if (clientnode != -1)
{
SV_SendServerInfo(clientnode, (tic_t)LONG(netbuffer->u.msaskinfo.time));
SV_SendPlayerInfo(clientnode); // Send extra info
Net_CloseConnection(clientnode);
// Don't close connection to MS...
}
else
Net_CloseConnection(node); // ...unless the IP address is not valid
}
else
Net_CloseConnection(node); // you're not supposed to get it, so ignore it
#else
Net_CloseConnection(node);
#endif
break;
case PT_ASKINFO:
@ -3419,8 +3458,8 @@ static void HandlePacketFromAwayNode(SINT8 node)
{
SV_SendServerInfo(node, (tic_t)LONG(netbuffer->u.askinfo.time));
SV_SendPlayerInfo(node); // Send extra info
Net_CloseConnection(node);
}
Net_CloseConnection(node);
break;
case PT_SERVERREFUSE: // Negative response of client join request
@ -3429,6 +3468,7 @@ static void HandlePacketFromAwayNode(SINT8 node)
Net_CloseConnection(node);
break;
}
SERVERONLY
if (cl_mode == CL_WAITJOINRESPONSE)
{
// Save the reason so it can be displayed after quitting the netgame
@ -3460,6 +3500,7 @@ static void HandlePacketFromAwayNode(SINT8 node)
Net_CloseConnection(node);
break;
}
SERVERONLY
/// \note how would this happen? and is it doing the right thing if it does?
if (cl_mode != CL_WAITJOINRESPONSE)
break;
@ -3525,13 +3566,18 @@ static void HandlePacketFromAwayNode(SINT8 node)
Net_CloseConnection(node);
break;
}
else
Got_Filetxpak();
SERVERONLY
Got_Filetxpak();
break;
case PT_REQUESTFILE:
if (server)
Got_RequestFilePak(node);
{
if (!cv_downloading.value || !Got_RequestFilePak(node))
Net_CloseConnection(node); // close connection if one of the requested files could not be sent, or you disabled downloading anyway
}
else
Net_CloseConnection(node); // nope
break;
case PT_NODETIMEOUT:
@ -3554,6 +3600,7 @@ static void HandlePacketFromAwayNode(SINT8 node)
break; // Ignore it
}
#undef SERVERONLY
}
/** Handles a packet received from a node that is in game
@ -3586,6 +3633,8 @@ FILESTAMP
{
// -------------------------------------------- SERVER RECEIVE ----------
case PT_RESYNCHGET:
if (client)
break;
SV_AcknowledgeResynchAck(netconsole, netbuffer->u.resynchgot);
break;
case PT_CLIENTCMD:
@ -3652,7 +3701,8 @@ FILESTAMP
}
// Splitscreen cmd
if (netbuffer->packettype == PT_CLIENT2CMD && nodetoplayer2[node] >= 0)
if ((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS)
&& nodetoplayer2[node] >= 0)
G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer2[node]],
&netbuffer->u.client2pak.cmd2, 1);
@ -3711,6 +3761,27 @@ FILESTAMP
tic_t tic = maketic;
UINT8 *textcmd;
// ignore if the textcmd has a reported size of zero
// this shouldn't be sent at all
if (!netbuffer->u.textcmd[0])
{
DEBFILE(va("GetPacket: Textcmd with size 0 detected! (node %u, player %d)\n",
node, netconsole));
Net_UnAcknowledgePacket(node);
break;
}
// ignore if the textcmd size var is actually larger than it should be
// BASEPACKETSIZE + 1 (for size) + textcmd[0] should == datalength
if (netbuffer->u.textcmd[0] > (size_t)doomcom->datalength-BASEPACKETSIZE-1)
{
DEBFILE(va("GetPacket: Bad Textcmd packet size! (expected %d, actual %s, node %u, player %d)\n",
netbuffer->u.textcmd[0], sizeu1((size_t)doomcom->datalength-BASEPACKETSIZE-1),
node, netconsole));
Net_UnAcknowledgePacket(node);
break;
}
// check if tic that we are making isn't too large else we cannot send it :(
// doomcom->numslots+1 "+1" since doomcom->numslots can change within this time and sent time
j = software_MAXPACKETLENGTH
@ -3904,7 +3975,7 @@ FILESTAMP
if (client)
{
INT32 i;
for (i = 0; i < MAXNETNODES; i++)
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i])
playerpingtable[i] = (tic_t)netbuffer->u.pingtable[i];
}
@ -3914,6 +3985,21 @@ FILESTAMP
case PT_SERVERCFG:
break;
case PT_FILEFRAGMENT:
// Only accept PT_FILEFRAGMENT from the server.
if (node != servernode)
{
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_FILEFRAGMENT", node);
if (server)
{
XBOXSTATIC UINT8 buf[2];
buf[0] = (UINT8)node;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
break;
}
if (client)
Got_Filetxpak();
break;
@ -4447,8 +4533,8 @@ static inline void PingUpdate(void)
}
//send out our ping packets
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i])
for (i = 0; i < MAXNETNODES; i++)
if (nodeingame[i])
HSendPacket(i, true, 0, sizeof(INT32) * MAXPLAYERS);
pingmeasurecount = 1; //Reset count
@ -4478,20 +4564,15 @@ void NetUpdate(void)
gametime = nowtime;
if (!(gametime % 255) && netgame && server)
{
#ifdef NEWPING
PingUpdate();
#endif
}
#ifdef NEWPING
if (server)
{
if (netgame && !(gametime % 255))
PingUpdate();
// update node latency values so we can take an average later.
for (i = 0; i < MAXNETNODES; i++)
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i])
realpingtable[i] += G_TicsToMilliseconds(GetLag(i));
realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i]));
pingmeasurecount++;
}
#endif

View File

@ -713,11 +713,24 @@ void Net_CloseConnection(INT32 node)
#else
INT32 i;
boolean forceclose = (node & FORCECLOSE) != 0;
if (node == -1)
{
DEBFILE(M_GetText("Net_CloseConnection: node -1 detected!\n"));
return; // nope, just ignore it
}
node &= ~FORCECLOSE;
if (!node)
return;
if (node < 0 || node >= MAXNETNODES) // prevent invalid nodes from crashing the game
{
DEBFILE(va(M_GetText("Net_CloseConnection: invalid node %d detected!\n"), node));
return;
}
nodes[node].flags |= NF_CLOSE;
// try to Send ack back (two army problem)

View File

@ -189,14 +189,13 @@ static CV_PossibleValue_t teamscramble_cons_t[] = {{0, "Off"}, {1, "Random"}, {2
static CV_PossibleValue_t startingliveslimit_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, NULL}};
static CV_PossibleValue_t sleeping_cons_t[] = {{-1, "MIN"}, {1000/TICRATE, "MAX"}, {0, NULL}};
static CV_PossibleValue_t competitionboxes_cons_t[] = {{0, "Normal"}, {1, "Random"}, {2, "Teleports"},
static CV_PossibleValue_t competitionboxes_cons_t[] = {{0, "Normal"}, {1, "Random"}, //{2, "Teleports"},
{3, "None"}, {0, NULL}};
static CV_PossibleValue_t matchboxes_cons_t[] = {{0, "Normal"}, {1, "Random"}, {2, "Non-Random"},
{3, "None"}, {0, NULL}};
static CV_PossibleValue_t chances_cons_t[] = {{0, "MIN"}, {9, "MAX"}, {0, NULL}};
static CV_PossibleValue_t match_scoring_cons_t[] = {{0, "Normal"}, {1, "Classic"}, {0, NULL}};
static CV_PossibleValue_t pause_cons_t[] = {{0, "Server"}, {1, "All"}, {0, NULL}};
static CV_PossibleValue_t timetic_cons_t[] = {{0, "Normal"}, {1, "Tics"}, {2, "Centiseconds"}, {0, NULL}};
@ -311,7 +310,6 @@ consvar_t cv_friendlyfire = {"friendlyfire", "Off", CV_NETVAR, CV_OnOff, NULL, 0
consvar_t cv_itemfinder = {"itemfinder", "Off", CV_CALL, CV_OnOff, ItemFinder_OnChange, 0, NULL, NULL, 0, 0, NULL};
// Scoring type options
consvar_t cv_match_scoring = {"matchscoring", "Normal", CV_NETVAR|CV_CHEAT, match_scoring_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_overtime = {"overtime", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_rollingdemos = {"rollingdemos", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -485,7 +483,6 @@ void D_RegisterServerCommands(void)
CV_RegisterVar(&cv_itemrespawntime);
CV_RegisterVar(&cv_itemrespawn);
CV_RegisterVar(&cv_flagtime);
CV_RegisterVar(&cv_suddendeath);
// misc
CV_RegisterVar(&cv_friendlyfire);
@ -533,7 +530,6 @@ void D_RegisterServerCommands(void)
CV_RegisterVar(&cv_startinglives);
CV_RegisterVar(&cv_countdowntime);
CV_RegisterVar(&cv_runscripts);
CV_RegisterVar(&cv_match_scoring);
CV_RegisterVar(&cv_overtime);
CV_RegisterVar(&cv_pause);
CV_RegisterVar(&cv_mute);
@ -616,6 +612,7 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_screenshot_option);
CV_RegisterVar(&cv_screenshot_folder);
CV_RegisterVar(&cv_screenshot_colorprofile);
CV_RegisterVar(&cv_moviemode);
// PNG variables
CV_RegisterVar(&cv_zlib_level);
@ -673,7 +670,29 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_resetmusic);
// FIXME: not to be here.. but needs be done for config loading
CV_RegisterVar(&cv_usegamma);
CV_RegisterVar(&cv_globalgamma);
CV_RegisterVar(&cv_globalsaturation);
CV_RegisterVar(&cv_rhue);
CV_RegisterVar(&cv_yhue);
CV_RegisterVar(&cv_ghue);
CV_RegisterVar(&cv_chue);
CV_RegisterVar(&cv_bhue);
CV_RegisterVar(&cv_mhue);
CV_RegisterVar(&cv_rgamma);
CV_RegisterVar(&cv_ygamma);
CV_RegisterVar(&cv_ggamma);
CV_RegisterVar(&cv_cgamma);
CV_RegisterVar(&cv_bgamma);
CV_RegisterVar(&cv_mgamma);
CV_RegisterVar(&cv_rsaturation);
CV_RegisterVar(&cv_ysaturation);
CV_RegisterVar(&cv_gsaturation);
CV_RegisterVar(&cv_csaturation);
CV_RegisterVar(&cv_bsaturation);
CV_RegisterVar(&cv_msaturation);
// m_menu.c
CV_RegisterVar(&cv_crosshair);
@ -731,6 +750,7 @@ void D_RegisterClientCommands(void)
// s_sound.c
CV_RegisterVar(&cv_soundvolume);
CV_RegisterVar(&cv_closedcaptioning);
CV_RegisterVar(&cv_digmusicvolume);
CV_RegisterVar(&cv_midimusicvolume);
CV_RegisterVar(&cv_numChannels);
@ -1583,8 +1603,13 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
mapchangepending = 0;
// spawn the server if needed
// reset players if there is a new one
if (!(adminplayer == consoleplayer) && SV_SpawnServer())
buf[0] &= ~(1<<1);
if (!(adminplayer == consoleplayer))
{
if (SV_SpawnServer())
buf[0] &= ~(1<<1);
if (!Playing()) // you failed to start a server somehow, so cancel the map change
return;
}
// Kick bot from special stages
if (botskin)
@ -2128,7 +2153,7 @@ static void Command_Teamchange_f(void)
return;
}
if (!cv_allowteamchange.value && !NetPacket.packet.newteam) // allow swapping to spectator even in locked teams.
if (!cv_allowteamchange.value && NetPacket.packet.newteam) // allow swapping to spectator even in locked teams.
{
CONS_Alert(CONS_NOTICE, M_GetText("The server is not allowing team changes at the moment.\n"));
return;
@ -2225,7 +2250,7 @@ static void Command_Teamchange2_f(void)
return;
}
if (!cv_allowteamchange.value && !NetPacket.packet.newteam) // allow swapping to spectator even in locked teams.
if (!cv_allowteamchange.value && NetPacket.packet.newteam) // allow swapping to spectator even in locked teams.
{
CONS_Alert(CONS_NOTICE, M_GetText("The server is not allowing team changes at the moment.\n"));
return;
@ -3090,7 +3115,13 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
filestatus_t ncs = FS_NOTFOUND;
UINT8 md5sum[16];
boolean kick = false;
boolean toomany = false;
INT32 i;
size_t packetsize = 0;
serverinfo_pak *dummycheck = NULL;
// Shut the compiler up.
(void)dummycheck;
READSTRINGN(*cp, filename, 240);
READMEM(*cp, md5sum, 16);
@ -3116,13 +3147,25 @@ static void Got_RequestAddfilecmd(UINT8 **cp, INT32 playernum)
return;
}
ncs = findfile(filename,md5sum,true);
// See W_LoadWadFile in w_wad.c
for (i = 0; i < numwadfiles; i++)
packetsize += nameonlylength(wadfiles[i]->filename) + 22;
if (ncs != FS_FOUND)
packetsize += nameonlylength(filename) + 22;
if ((numwadfiles >= MAX_WADFILES)
|| (packetsize > sizeof(dummycheck->fileneeded)))
toomany = true;
else
ncs = findfile(filename,md5sum,true);
if (ncs != FS_FOUND || toomany)
{
char message[256];
if (ncs == FS_NOTFOUND)
if (toomany)
sprintf(message, M_GetText("Too many files loaded to add %s\n"), filename);
else if (ncs == FS_NOTFOUND)
sprintf(message, M_GetText("The server doesn't have %s\n"), filename);
else if (ncs == FS_MD5SUMBAD)
sprintf(message, M_GetText("Checksum mismatch on %s\n"), filename);
@ -3192,10 +3235,15 @@ static void Got_Addfilecmd(UINT8 **cp, INT32 playernum)
ncs = findfile(filename,md5sum,true);
if (ncs != FS_FOUND)
if (ncs != FS_FOUND || !P_AddWadFile(filename, NULL))
{
Command_ExitGame_f();
if (ncs == FS_NOTFOUND)
if (ncs == FS_FOUND)
{
CONS_Printf(M_GetText("The server tried to add %s,\nbut you have too many files added.\nRestart the game to clear loaded files\nand play on this server."), filename);
M_StartMessage(va("The server added a file \n(%s)\nbut you have too many files added.\nRestart the game to clear loaded files.\n\nPress ESC\n",filename), NULL, MM_NOTHING);
}
else if (ncs == FS_NOTFOUND)
{
CONS_Printf(M_GetText("The server tried to add %s,\nbut you don't have this file.\nYou need to find it in order\nto play on this server."), filename);
M_StartMessage(va("The server added a file \n(%s)\nthat you do not have.\n\nPress ESC\n",filename), NULL, MM_NOTHING);
@ -3213,7 +3261,6 @@ static void Got_Addfilecmd(UINT8 **cp, INT32 playernum)
return;
}
P_AddWadFile(filename, NULL);
G_SetGameModified(true);
}

View File

@ -51,7 +51,6 @@ extern consvar_t cv_itemrespawntime;
extern consvar_t cv_itemrespawn;
extern consvar_t cv_flagtime;
extern consvar_t cv_suddendeath;
extern consvar_t cv_touchtag;
extern consvar_t cv_hidetime;
@ -91,7 +90,6 @@ extern consvar_t cv_recycler;
extern consvar_t cv_itemfinder;
extern consvar_t cv_inttime, cv_advancemap, cv_playersforexit;
extern consvar_t cv_match_scoring;
extern consvar_t cv_overtime;
extern consvar_t cv_startinglives;

View File

@ -62,7 +62,8 @@
#include <errno.h>
static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid);
// Prototypes
static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid);
// Sender structure
typedef struct filetx_s
@ -303,7 +304,8 @@ boolean CL_SendRequestFile(void)
}
// get request filepak and put it on the send queue
void Got_RequestFilePak(INT32 node)
// returns false if a requested file was not found or cannot be sent
boolean Got_RequestFilePak(INT32 node)
{
char wad[MAX_WADPATH+1];
UINT8 *p = netbuffer->u.textcmd;
@ -314,8 +316,13 @@ void Got_RequestFilePak(INT32 node)
if (id == 0xFF)
break;
READSTRINGN(p, wad, MAX_WADPATH);
SV_SendFile(node, wad, id);
if (!SV_SendFile(node, wad, id))
{
SV_AbortSendFiles(node);
return false; // don't read the rest of the files
}
}
return true; // no problems with any files
}
/** Checks if the files needed aren't already loaded or on the disk
@ -330,6 +337,12 @@ INT32 CL_CheckFiles(void)
INT32 i, j;
char wadfilename[MAX_WADPATH];
INT32 ret = 1;
size_t packetsize = 0;
size_t filestoget = 0;
serverinfo_pak *dummycheck = NULL;
// Shut the compiler up.
(void)dummycheck;
// if (M_CheckParm("-nofiles"))
// return 1;
@ -378,6 +391,10 @@ INT32 CL_CheckFiles(void)
return 1;
}
// See W_LoadWadFile in w_wad.c
for (i = 0; i < numwadfiles; i++)
packetsize += nameonlylength(wadfiles[i]->filename) + 22;
for (i = 1; i < fileneedednum; i++)
{
CONS_Debug(DBG_NETPLAY, "searching for '%s' ", fileneeded[i].filename);
@ -397,6 +414,14 @@ INT32 CL_CheckFiles(void)
if (fileneeded[i].status != FS_NOTFOUND || !fileneeded[i].important)
continue;
packetsize += nameonlylength(fileneeded[i].filename) + 22;
if ((numwadfiles+filestoget >= MAX_WADFILES)
|| (packetsize > sizeof(dummycheck->fileneeded)))
return 3;
filestoget++;
fileneeded[i].status = findfile(fileneeded[i].filename, fileneeded[i].md5sum, true);
CONS_Debug(DBG_NETPLAY, "found %d\n", fileneeded[i].status);
if (fileneeded[i].status != FS_FOUND)
@ -480,7 +505,7 @@ static INT32 filestosend = 0;
* \sa SV_SendRam
*
*/
static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
{
filetx_t **q; // A pointer to the "next" field of the last file in the list
filetx_t *p; // The new file request
@ -488,7 +513,7 @@ static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
char wadfilename[MAX_WADPATH];
if (cv_noticedownload.value)
CONS_Printf("Sending file \"%s\" to node %d\n", filename, node);
CONS_Printf("Sending file \"%s\" to node %d (%s)\n", filename, node, I_GetNodeAddress(node));
// Find the last file in the list and set a pointer to its "next" field
q = &transfer[node].txlist;
@ -537,7 +562,7 @@ static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
free(p->id.filename);
free(p);
*q = NULL;
return;
return false; // cancel the rest of the requests
}
// Handle huge file requests (i.e. bigger than cv_maxsend.value KB)
@ -549,7 +574,7 @@ static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
free(p->id.filename);
free(p);
*q = NULL;
return;
return false; // cancel the rest of the requests
}
DEBFILE(va("Sending file %s (id=%d) to %d\n", filename, fileid, node));
@ -557,6 +582,7 @@ static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
p->fileid = fileid;
p->next = NULL; // End of list
filestosend++;
return true;
}
/** Adds a memory block to the file list for a node

View File

@ -69,7 +69,7 @@ boolean SV_SendingFile(INT32 node);
boolean CL_CheckDownloadable(void);
boolean CL_SendRequestFile(void);
void Got_RequestFilePak(INT32 node);
boolean Got_RequestFilePak(INT32 node);
void SV_AbortSendFiles(INT32 node);
void CloseNetFile(void);

View File

@ -2110,6 +2110,7 @@ static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
char *word;
char *word2;
char *tmp;
INT32 value;
@ -2123,8 +2124,8 @@ static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
tmp = strchr(s, '#');
if (tmp)
*tmp = '\0';
value = searchvalue(s);
if (s == tmp)
continue; // Skip comment lines, but don't break.
word = strtok(s, " ");
if (word)
@ -2132,6 +2133,15 @@ static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
else
break;
word2 = strtok(NULL, " ");
if (word2)
value = atoi(word2);
else
{
deh_warning("No value for token %s", word);
continue;
}
/* if (fastcmp(word, "OFFSET"))
{
value -= 150360;
@ -2161,6 +2171,11 @@ static void readsound(MYFILE *f, INT32 num, const char *savesfxnames[])
DEH_WriteUndoline(word, va("%d", S_sfx[num].pitch), UNDO_NONE);
S_sfx[num].pitch = value;
}
else if (fastcmp(word, "CAPTION") || fastcmp(word, "DESCRIPTION"))
{
deh_strlcpy(S_sfx[num].caption, word2,
sizeof(S_sfx[num].caption), va("Sound effect %d: caption", num));
}
else
deh_warning("Sound %d : unknown word '%s'",num,word);
}
@ -2454,6 +2469,7 @@ static void readunlockable(MYFILE *f, INT32 num)
DEH_WriteUndoline("VAR", va("%d", unlockables[num].variable), UNDO_NONE);
memset(&unlockables[num], 0, sizeof(unlockable_t));
unlockables[num].objective[0] = '/';
do
{
@ -3615,11 +3631,11 @@ static void DEH_LoadDehackedFile(MYFILE *f, UINT16 wad)
{
if (i == 0 && word2[0] != '0') // If word2 isn't a number
i = get_sfx(word2); // find a sound by name
if (i < NUMSFX && i >= 0)
if (i < NUMSFX && i > 0)
readsound(f, i, savesfxnames);
else
{
deh_warning("Sound %d out of range (0 - %d)", i, NUMSFX-1);
deh_warning("Sound %d out of range (1 - %d)", i, NUMSFX-1);
ignorelines(f);
}
DEH_WriteUndoline(word, word2, UNDO_HEADER);

View File

@ -90,6 +90,10 @@ static unsigned long nombre = NEWTICRATE*10;
static void I_BlitScreenVesa1(void); //see later
void I_FinishUpdate (void)
{
// draw captions if enabled
if (cv_closedcaptioning.value)
SCR_ClosedCaptions();
// draw FPS if enabled
if (cv_ticrate.value)
SCR_DisplayTicRate();

View File

@ -214,7 +214,7 @@ extern FILE *logstream;
// it's only for detection of the version the player is using so the MS can alert them of an update.
// 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 22
#define MODVERSION 24
// =========================================================================
@ -546,4 +546,8 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Hudname padding.
#define SKINNAMEPADDING
/// Handle touching sector specials in P_PlayerAfterThink instead of P_PlayerThink.
/// \note Required for proper collision with moving sloped surfaces that have sector specials on them.
//#define SECTORSPECIALSAFTERTHINK
#endif // __DOOMDEF__

View File

@ -379,6 +379,7 @@ nightsdata_t ntemprecords;
extern UINT32 token; ///< Number of tokens collected in a level
extern UINT32 tokenlist; ///< List of tokens collected
extern boolean gottoken; ///< Did you get a token? Used for end of act
extern INT32 tokenbits; ///< Used for setting token bits
extern INT32 sstimer; ///< Time allotted in the special stage
extern UINT32 bluescore; ///< Blue Team Scores

View File

@ -1723,7 +1723,7 @@ static void F_AdvanceToNextScene(void)
void F_EndCutScene(void)
{
cutsceneover = true; // do this first, just in case Y_EndGame or something wants to turn it back false later
cutsceneover = true; // do this first, just in case G_EndGame or something wants to turn it back false later
if (runningprecutscene)
{
if (server)
@ -1738,7 +1738,7 @@ void F_EndCutScene(void)
else if (nextmap < 1100-1)
G_NextLevel();
else
Y_EndGame();
G_EndGame();
}
}

View File

@ -86,7 +86,7 @@ INT32 lastwipetic = 0;
static UINT8 *wipe_scr_start; //screen 3
static UINT8 *wipe_scr_end; //screen 4
static UINT8 *wipe_scr; //screen 0 (main drawing)
static fixed_t paldiv;
static fixed_t paldiv = 0;
/** Create fademask_t from lump
*
@ -145,7 +145,7 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) {
while (lsize--)
{
// Determine pixel to use from fademask
pcolor = &pLocalPalette[*lump++];
pcolor = &pMasterPalette[*lump++];
*mask++ = FixedDiv((pcolor->s.red+1)<<FRACBITS, paldiv)>>FRACBITS;
}
@ -337,7 +337,8 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu)
UINT8 wipeframe = 0;
fademask_t *fmask;
paldiv = FixedDiv(257<<FRACBITS, 11<<FRACBITS);
if (!paldiv)
paldiv = FixedDiv(257<<FRACBITS, 11<<FRACBITS);
// Init the wipe
WipeInAction = true;

View File

@ -156,6 +156,7 @@ UINT8 stagefailed; // Used for GEMS BONUS? Also to see if you beat the stage.
UINT16 emeralds;
UINT32 token; // Number of tokens collected in a level
UINT32 tokenlist; // List of tokens collected
boolean gottoken; // Did you get a token? Used for end of act
INT32 tokenbits; // Used for setting token bits
// Old Special Stage
@ -1011,13 +1012,13 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
if (turnleft)
cmd->angleturn = (INT16)(cmd->angleturn + angleturn[tspeed]);
}
if (cv_analog.value || twodlevel
if (twodlevel
|| (player->mo && (player->mo->flags2 & MF2_TWOD))
|| (!demoplayback && (player->climbing
|| (player->powers[pw_carry] == CR_NIGHTSMODE)
|| (player->pflags & (PF_SLIDING|PF_FORCESTRAFE))))) // Analog
forcestrafe = true;
if (forcestrafe) // Analog
if (forcestrafe)
{
if (turnright)
side += sidemove[speed];
@ -1030,6 +1031,13 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
side += ((axis * sidemove[1]) >> 10);
}
}
else if (cv_analog.value) // Analog
{
if (turnright)
cmd->buttons |= BT_CAMRIGHT;
if (turnleft)
cmd->buttons |= BT_CAMLEFT;
}
else
{
if (turnright)
@ -1117,15 +1125,6 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
if (PLAYER1INPUTDOWN(gc_use))
cmd->buttons |= BT_USE;
// Camera Controls
if (cv_debug || cv_analog.value || demoplayback || objectplacing || player->powers[pw_carry] == CR_NIGHTSMODE)
{
if (PLAYER1INPUTDOWN(gc_camleft))
cmd->buttons |= BT_CAMLEFT;
if (PLAYER1INPUTDOWN(gc_camright))
cmd->buttons |= BT_CAMRIGHT;
}
if (PLAYER1INPUTDOWN(gc_camreset))
{
if (camera.chase && !resetdown)
@ -1187,10 +1186,19 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
if (!mouseaiming && cv_mousemove.value)
forward += mousey;
if (cv_analog.value ||
(!demoplayback && (player->climbing
if ((!demoplayback && (player->climbing
|| (player->pflags & PF_SLIDING)))) // Analog for mouse
side += mousex*2;
else if (cv_analog.value)
{
if (mousex)
{
if (mousex > 0)
cmd->buttons |= BT_CAMRIGHT;
else
cmd->buttons |= BT_CAMLEFT;
}
}
else
cmd->angleturn = (INT16)(cmd->angleturn - (mousex*8));
@ -1225,9 +1233,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
cmd->sidemove = (SINT8)(cmd->sidemove + side);
if (cv_analog.value) {
cmd->angleturn = (INT16)(thiscam->angle >> 16);
if (player->awayviewtics)
cmd->angleturn = (INT16)(player->awayviewmobj->angle >> 16);
else
cmd->angleturn = (INT16)(thiscam->angle >> 16);
}
else
{
@ -1301,7 +1310,7 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
if (turnleft)
cmd->angleturn = (INT16)(cmd->angleturn + angleturn[tspeed]);
}
if (cv_analog2.value || twodlevel
if (twodlevel
|| (player->mo && (player->mo->flags2 & MF2_TWOD))
|| player->climbing
|| (player->powers[pw_carry] == CR_NIGHTSMODE)
@ -1320,6 +1329,13 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
side += ((axis * sidemove[1]) >> 10);
}
}
else if (cv_analog2.value) // Analog
{
if (turnright)
cmd->buttons |= BT_CAMRIGHT;
if (turnleft)
cmd->buttons |= BT_CAMLEFT;
}
else
{
if (turnright)
@ -1404,15 +1420,6 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
if (PLAYER2INPUTDOWN(gc_use))
cmd->buttons |= BT_USE;
// Camera Controls
if (cv_debug || cv_analog2.value || player->powers[pw_carry] == CR_NIGHTSMODE)
{
if (PLAYER2INPUTDOWN(gc_camleft))
cmd->buttons |= BT_CAMLEFT;
if (PLAYER2INPUTDOWN(gc_camright))
cmd->buttons |= BT_CAMRIGHT;
}
if (PLAYER2INPUTDOWN(gc_camreset))
{
if (camera2.chase && !resetdown)
@ -1474,9 +1481,19 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
if (!mouseaiming && cv_mousemove2.value)
forward += mouse2y;
if (cv_analog2.value || player->climbing
if (player->climbing
|| (player->pflags & PF_SLIDING)) // Analog for mouse
side += mouse2x*2;
else if (cv_analog2.value)
{
if (mouse2x)
{
if (mouse2x > 0)
cmd->buttons |= BT_CAMRIGHT;
else
cmd->buttons |= BT_CAMLEFT;
}
}
else
cmd->angleturn = (INT16)(cmd->angleturn - (mouse2x*8));
@ -1524,9 +1541,10 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics)
}
if (cv_analog2.value) {
cmd->angleturn = (INT16)(thiscam->angle >> 16);
if (player->awayviewtics)
cmd->angleturn = (INT16)(player->awayviewmobj->angle >> 16);
else
cmd->angleturn = (INT16)(thiscam->angle >> 16);
}
else
{
@ -2291,6 +2309,9 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost)
if (starpost) //Don't even bother with looking for a place to spawn.
{
P_MovePlayerToStarpost(playernum);
#ifdef HAVE_BLUA
LUAh_PlayerSpawn(&players[playernum]); // Lua hook for player spawning :)
#endif
return;
}
@ -2615,7 +2636,7 @@ void G_ExitLevel(void)
CONS_Printf(M_GetText("The round has ended.\n"));
// Remove CEcho text on round end.
HU_DoCEcho("");
HU_ClearCEcho();
}
}
@ -2763,7 +2784,6 @@ static INT16 RandMap(INT16 tolflags, INT16 pprevmap)
static void G_DoCompleted(void)
{
INT32 i;
boolean gottoken = false;
tokenlist = 0; // Reset the list
@ -2849,10 +2869,9 @@ static void G_DoCompleted(void)
if (nextmap >= 1100-1 && nextmap <= 1102-1 && (gametype == GT_RACE || gametype == GT_COMPETITION))
nextmap = (INT16)(spstage_start-1);
if (gametype == GT_COOP && token)
if ((gottoken = (gametype == GT_COOP && token)))
{
token--;
gottoken = true;
if (!(emeralds & EMERALD1))
nextmap = (INT16)(sstage_start - 1); // Special Stage 1
@ -2911,7 +2930,7 @@ void G_AfterIntermission(void)
if (nextmap < 1100-1)
G_NextLevel();
else
Y_EndGame();
G_EndGame();
}
}
@ -2997,6 +3016,38 @@ static void G_DoContinued(void)
gameaction = ga_nothing;
}
//
// G_EndGame (formerly Y_EndGame)
// Frankly this function fits better in g_game.c than it does in y_inter.c
//
// ...Gee, (why) end the game?
// Because G_AfterIntermission and F_EndCutscene would
// both do this exact same thing *in different ways* otherwise,
// which made it so that you could only unlock Ultimate mode
// if you had a cutscene after the final level and crap like that.
// This function simplifies it so only one place has to be updated
// when something new is added.
void G_EndGame(void)
{
// Only do evaluation and credits in coop games.
if (gametype == GT_COOP)
{
if (nextmap == 1102-1) // end game with credits
{
F_StartCredits();
return;
}
if (nextmap == 1101-1) // end game with evaluation
{
F_StartGameEvaluation();
return;
}
}
// 1100 or competitive multiplayer, so go back to title screen.
D_StartTitle();
}
//
// G_LoadGameSettings
//
@ -3646,6 +3697,9 @@ char *G_BuildMapTitle(INT32 mapnum)
{
char *title = NULL;
if (!mapheaderinfo[mapnum-1])
P_AllocMapHeader(mapnum-1);
if (strcmp(mapheaderinfo[mapnum-1]->lvlttl, ""))
{
size_t len = 1;
@ -3879,7 +3933,7 @@ void G_GhostAddColor(ghostcolor_t color)
ghostext.color = (UINT8)color;
}
void G_GhostAddScale(UINT16 scale)
void G_GhostAddScale(fixed_t scale)
{
if (!demorecording || !(demoflags & DF_GHOST))
return;

View File

@ -142,7 +142,7 @@ void G_GhostAddSpin(void);
void G_GhostAddRev(void);
void G_GhostAddColor(ghostcolor_t color);
void G_GhostAddFlip(void);
void G_GhostAddScale(UINT16 scale);
void G_GhostAddScale(fixed_t scale);
void G_GhostAddHit(mobj_t *victim);
void G_WriteGhostTic(mobj_t *ghost);
void G_ConsGhostTic(void);
@ -174,6 +174,7 @@ void G_NextLevel(void);
void G_Continue(void);
void G_UseContinue(void);
void G_AfterIntermission(void);
void G_EndGame(void); // moved from y_inter.c/h and renamed
void G_Ticker(boolean run);
boolean G_Responder(event_t *ev);

View File

@ -977,8 +977,6 @@ static const char *gamecontrolname[num_gamecontrols] =
"tossflag",
"use",
"camtoggle",
"camleft",
"camright",
"camreset",
"lookup",
"lookdown",
@ -1074,8 +1072,6 @@ void G_Controldefault(void)
gamecontrol[gc_use ][0] = KEY_JOY1+1; //B
gamecontrol[gc_use ][1] = '.';
gamecontrol[gc_camtoggle ][1] = ',';
gamecontrol[gc_camleft ][0] = 'o';
gamecontrol[gc_camright ][0] = 'p';
gamecontrol[gc_camreset ][0] = 'c';
gamecontrol[gc_lookup ][0] = KEY_PGUP;
gamecontrol[gc_lookdown ][0] = KEY_PGDN;
@ -1178,8 +1174,6 @@ void G_Controldefault(void)
gamecontrol[gc_tossflag ][0] = '\'';
gamecontrol[gc_use ][0] = KEY_LSHIFT;
gamecontrol[gc_camtoggle ][0] = 'v';
gamecontrol[gc_camleft ][0] = '[';
gamecontrol[gc_camright ][0] = ']';
gamecontrol[gc_camreset ][0] = 'r';
gamecontrol[gc_lookup ][0] = KEY_UPARROW;
gamecontrol[gc_lookdown ][0] = KEY_DOWNARROW;

View File

@ -105,8 +105,6 @@ typedef enum
gc_tossflag,
gc_use,
gc_camtoggle,
gc_camleft,
gc_camright,
gc_camreset,
gc_lookup,
gc_lookdown,

View File

@ -789,7 +789,7 @@ boolean HWR_Screenshot(const char *lbmname)
HWD.pfnReadRect(0, 0, vid.width, vid.height, vid.width * 3, (void *)buf);
#ifdef USE_PNG
ret = M_SavePNG(lbmname, buf, vid.width, vid.height, NULL);
ret = M_SavePNG(lbmname, buf, vid.width, vid.height, false);
#else
ret = saveTGA(lbmname, buf, vid.width, vid.height);
#endif

View File

@ -1084,9 +1084,9 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum,
float endheight = 0.0f, endbheight = 0.0f;
fixed_t v1x = FLOAT_TO_FIXED(wallVerts[0].x);
fixed_t v1y = FLOAT_TO_FIXED(wallVerts[0].y);
fixed_t v1y = FLOAT_TO_FIXED(wallVerts[0].z); // not a typo
fixed_t v2x = FLOAT_TO_FIXED(wallVerts[1].x);
fixed_t v2y = FLOAT_TO_FIXED(wallVerts[1].y);
fixed_t v2y = FLOAT_TO_FIXED(wallVerts[1].z); // not a typo
// compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly
// use this as a temp var to store P_GetZAt's return value each time
fixed_t temp;
@ -3721,6 +3721,9 @@ static void HWR_Subsector(size_t num)
while (count--)
{
#ifdef POLYOBJECTS
if (!line->polyseg) // ignore segs that belong to polyobjects
#endif
HWR_AddLine(line);
line++;
}

View File

@ -244,6 +244,7 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...)
#define pglMaterialfv glMaterialfv
/* Raster functions */
#define pglPixelStorei glPixelStorei
#define pglReadPixels glReadPixels
/* Texture mapping */
@ -262,15 +263,8 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...)
/* texture mapping */ //GL_EXT_copy_texture
#ifndef KOS_GL_COMPATIBILITY
#define pglCopyTexImage2D glCopyTexImage2D
#endif
/* GLU functions */
#define pgluBuild2DMipmaps gluBuild2DMipmaps
#endif
#ifndef MINI_GL_COMPATIBILITY
/* 1.3 functions for multitexturing */
#define pglActiveTexture glActiveTexture
#define pglMultiTexCoord2f glMultiTexCoord2f
#endif
#else //!STATIC_OPENGL
/* 1.0 functions */
@ -365,6 +359,8 @@ typedef void (APIENTRY * PFNglMaterialfv) (GLint face, GLenum pname, GLfloat *pa
static PFNglMaterialfv pglMaterialfv;
/* Raster functions */
typedef void (APIENTRY * PFNglPixelStorei) (GLenum pname, GLint param);
static PFNglPixelStorei pglPixelStorei;
typedef void (APIENTRY * PFNglReadPixels) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
static PFNglReadPixels pglReadPixels;
@ -391,7 +387,7 @@ static PFNglBindTexture pglBindTexture;
/* texture mapping */ //GL_EXT_copy_texture
typedef void (APIENTRY * PFNglCopyTexImage2D) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
static PFNglCopyTexImage2D pglCopyTexImage2D;
#endif
/* GLU functions */
typedef GLint (APIENTRY * PFNgluBuild2DMipmaps) (GLenum target, GLint internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *data);
static PFNgluBuild2DMipmaps pgluBuild2DMipmaps;
@ -403,7 +399,6 @@ static PFNglActiveTexture pglActiveTexture;
typedef void (APIENTRY *PFNglMultiTexCoord2f) (GLenum, GLfloat, GLfloat);
static PFNglMultiTexCoord2f pglMultiTexCoord2f;
#endif
#endif
#ifndef MINI_GL_COMPATIBILITY
/* 1.2 Parms */
@ -494,6 +489,7 @@ boolean SetupGLfunc(void)
GETOPENGLFUNC(pglLightModelfv , glLightModelfv)
GETOPENGLFUNC(pglMaterialfv , glMaterialfv)
GETOPENGLFUNC(pglPixelStorei , glPixelStorei)
GETOPENGLFUNC(pglReadPixels , glReadPixels)
GETOPENGLFUNC(pglTexEnvi , glTexEnvi)
@ -519,35 +515,23 @@ boolean SetupGLfunc(void)
// This has to be done after the context is created so the version number can be obtained
boolean SetupGLFunc13(void)
{
#ifdef MINI_GL_COMPATIBILITY
return false;
#else
const GLubyte *version = pglGetString(GL_VERSION);
int glmajor, glminor;
gl13 = false;
#ifdef MINI_GL_COMPATIBILITY
return false;
#else
#ifdef STATIC_OPENGL
gl13 = true;
#else
// Parse the GL version
if (version != NULL)
{
if (sscanf((const char*)version, "%d.%d", &glmajor, &glminor) == 2)
{
// Look, we gotta prepare for the inevitable arrival of GL 2.0 code...
switch (glmajor)
{
case 1:
if (glminor == 3) gl13 = true;
break;
case 2:
case 3:
case 4:
gl13 = true;
default:
break;
}
if (glmajor == 1 && glminor >= 3)
gl13 = true;
else if (glmajor > 1)
gl13 = true;
}
}
@ -568,9 +552,6 @@ boolean SetupGLFunc13(void)
}
else
DBG_Printf("GL_ARB_multitexture support: disabled\n");
#undef GETOPENGLFUNC
#endif
return true;
#endif
}
@ -897,7 +878,9 @@ EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height,
GLubyte*top = (GLvoid*)dst_data, *bottom = top + dst_stride * (height - 1);
GLubyte *row = malloc(dst_stride);
if (!row) return;
pglPixelStorei(GL_PACK_ALIGNMENT, 1);
pglReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, dst_data);
pglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
for(i = 0; i < height/2; i++)
{
memcpy(row, top, dst_stride);
@ -913,7 +896,9 @@ EXPORT void HWRAPI(ReadRect) (INT32 x, INT32 y, INT32 width, INT32 height,
INT32 j;
GLubyte *image = malloc(width*height*3*sizeof (*image));
if (!image) return;
pglPixelStorei(GL_PACK_ALIGNMENT, 1);
pglReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, image);
pglPixelStorei(GL_UNPACK_ALIGNMENT, 1);
for (i = height-1; i >= 0; i--)
{
for (j = 0; j < width; j++)
@ -1815,13 +1800,11 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value)
min_filter = GL_NEAREST;
#endif
}
#ifndef STATIC_OPENGL
if (!pgluBuild2DMipmaps)
{
MipMap = GL_FALSE;
min_filter = GL_LINEAR;
}
#endif
Flush(); //??? if we want to change filter mode by texture, remove this
break;

View File

@ -91,7 +91,7 @@ patch_t *tallminus;
patch_t *emeraldpics[7];
patch_t *tinyemeraldpics[7];
static patch_t *emblemicon;
static patch_t *tokenicon;
patch_t *tokenicon;
//-------------------------------------------
// misc vars
@ -840,7 +840,7 @@ static void HU_DrawChat(void)
else
{
//charwidth = SHORT(hu_font[talk[i]-HU_FONTSTART]->width) * con_scalefactor;
V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | cv_constextsize.value | V_NOSCALESTART, true);
}
c += charwidth;
}
@ -857,7 +857,7 @@ static void HU_DrawChat(void)
else
{
//charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor;
V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | cv_constextsize.value | V_NOSCALESTART | t, !cv_allcaps.value);
V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | cv_constextsize.value | V_NOSCALESTART | t, true);
}
c += charwidth;
@ -869,7 +869,7 @@ static void HU_DrawChat(void)
}
if (hu_tick < 4)
V_DrawCharacter(HU_INPUTX + c, y, '_' | cv_constextsize.value |V_NOSCALESTART|t, !cv_allcaps.value);
V_DrawCharacter(HU_INPUTX + c, y, '_' | cv_constextsize.value |V_NOSCALESTART|t, true);
}

View File

@ -21,7 +21,7 @@
//------------------------------------
// heads up font
//------------------------------------
#define HU_FONTSTART '\x1F' // the first font character
#define HU_FONTSTART '\x19' // the first font character
#define HU_FONTEND '~'
#define HU_FONTSIZE (HU_FONTEND - HU_FONTSTART + 1)
@ -71,6 +71,7 @@ extern patch_t *rmatcico;
extern patch_t *bmatcico;
extern patch_t *tagico;
extern patch_t *tallminus;
extern patch_t *tokenicon;
// set true when entering a chat message
extern boolean chat_on;

View File

@ -926,13 +926,13 @@ state_t states[NUMSTATES] =
{SPR_EGGM, 20, 2, {NULL}, 0, 0, S_EGGMOBILE_STND}, // S_EGGMOBILE_RATK10
{SPR_EGGM, 3, 12, {NULL}, 0, 0, S_EGGMOBILE_PANIC2}, // S_EGGMOBILE_PANIC1
{SPR_EGGM, 4, 4, {A_Boss1Spikeballs}, 0, 4, S_EGGMOBILE_PANIC3}, // S_EGGMOBILE_PANIC2
{SPR_EGGM, 3, 5, {NULL}, 0, 0, S_EGGMOBILE_PANIC4}, // S_EGGMOBILE_PANIC3
{SPR_EGGM, 3, 8, {NULL}, 0, 0, S_EGGMOBILE_PANIC4}, // S_EGGMOBILE_PANIC3
{SPR_EGGM, 4, 4, {A_Boss1Spikeballs}, 1, 4, S_EGGMOBILE_PANIC5}, // S_EGGMOBILE_PANIC4
{SPR_EGGM, 3, 5, {NULL}, 0, 0, S_EGGMOBILE_PANIC6}, // S_EGGMOBILE_PANIC5
{SPR_EGGM, 3, 8, {NULL}, 0, 0, S_EGGMOBILE_PANIC6}, // S_EGGMOBILE_PANIC5
{SPR_EGGM, 4, 4, {A_Boss1Spikeballs}, 2, 4, S_EGGMOBILE_PANIC7}, // S_EGGMOBILE_PANIC6
{SPR_EGGM, 3, 5, {NULL}, 0, 0, S_EGGMOBILE_PANIC8}, // S_EGGMOBILE_PANIC7
{SPR_EGGM, 3, 8, {NULL}, 0, 0, S_EGGMOBILE_PANIC8}, // S_EGGMOBILE_PANIC7
{SPR_EGGM, 4, 4, {A_Boss1Spikeballs}, 3, 4, S_EGGMOBILE_PANIC9}, // S_EGGMOBILE_PANIC8
{SPR_EGGM, 3, 5, {NULL}, 0, 0, S_EGGMOBILE_PANIC10},// S_EGGMOBILE_PANIC9
{SPR_EGGM, 3, 8, {NULL}, 0, 0, S_EGGMOBILE_PANIC10},// S_EGGMOBILE_PANIC9
{SPR_EGGM, 0, 35, {A_SkullAttack}, 0, 0, S_EGGMOBILE_STND}, // S_EGGMOBILE_PANIC10
{SPR_EGGM, 21, 24, {A_Pain}, 0, 0, S_EGGMOBILE_PAIN2}, // S_EGGMOBILE_PAIN
{SPR_EGGM, 21, 16, {A_SkullAttack}, 1, 1, S_EGGMOBILE_STND}, // S_EGGMOBILE_PAIN2
@ -4097,7 +4097,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
2*FRACUNIT, // speed
4*FRACUNIT, // speed
13*FRACUNIT, // radius
26*FRACUNIT, // height
0, // display offset
@ -6453,7 +6453,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
},
{ // MT_MYSTERY_BOX
412, // doomednum
-1, //412, // doomednum
S_MYSTERY_BOX, // spawnstate
1, // spawnhealth
S_NULL, // seestate
@ -7105,7 +7105,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_PITY_ICON1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_s3k3a, // seesound
sfx_shield, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
@ -7456,7 +7456,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_SCORE1K_ICON1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_token, // seesound
sfx_chchng, // seesound
1000, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
@ -7483,7 +7483,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_SCORE10K_ICON1, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_token, // seesound
sfx_chchng, // seesound
10000, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
@ -12652,7 +12652,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_RRNG1, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_thok, // seesound
sfx_wepfir, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
@ -13059,7 +13059,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_THROWNINFINITY1, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_thok, // seesound
sfx_wepfir, // seesound
0, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
@ -13086,7 +13086,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_THROWNAUTOMATIC1, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_thok, // seesound
sfx_wepfir, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
@ -13167,7 +13167,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_THROWNGRENADE1, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_thok, // seesound
sfx_wepfir, // seesound
8, // reactiontime
sfx_gbeep, // attacksound
S_NULL, // painstate
@ -13954,7 +13954,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_itemup, // painsound
sfx_s3k33, // painsound
S_RING, // meleestate
S_NULL, // missilestate
S_SPRK1, // deathstate

View File

@ -462,7 +462,7 @@ static int lib_pSpawnLockOn(lua_State *L)
return LUA_ErrInvalid(L, "mobj_t");
if (!player)
return LUA_ErrInvalid(L, "player_t");
if (player == &players[consoleplayer] || player == &players[secondarydisplayplayer] || player == &players[displayplayer]) // Only display it on your own view.
if (P_IsLocalPlayer(player)) // Only display it on your own view.
{
mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker
visual->target = lockon;
@ -2181,6 +2181,31 @@ static int lib_sSoundPlaying(lua_State *L)
return 1;
}
// This doesn't really exist, but we're providing it as a handy netgame-safe wrapper for stuff that should be locally handled.
static int lib_sStartMusicCaption(lua_State *L)
{
player_t *player = NULL;
const char *caption = luaL_checkstring(L, 1);
UINT16 lifespan = (UINT16)luaL_checkinteger(L, 2);
//HUDSAFE
INLEVEL
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");
}
if (lifespan && (!player || P_IsLocalPlayer(player)))
{
strlcpy(S_sfx[sfx_None].caption, caption, sizeof(S_sfx[sfx_None].caption));
S_StartCaption(sfx_None, -1, lifespan);
}
return 0;
}
// G_GAME
////////////
@ -2493,6 +2518,7 @@ static luaL_Reg lib[] = {
{"S_OriginPlaying",lib_sOriginPlaying},
{"S_IdPlaying",lib_sIdPlaying},
{"S_SoundPlaying",lib_sSoundPlaying},
{"S_StartMusicCaption", lib_sStartMusicCaption},
// g_game
{"G_BuildMapName",lib_gBuildMapName},

View File

@ -266,4 +266,4 @@ int LUA_BlockmapLib(lua_State *L)
return 0;
}
#endif
#endif

View File

@ -31,6 +31,7 @@ enum sfxinfo_read {
sfxinfor_singular,
sfxinfor_priority,
sfxinfor_flags, // "pitch"
sfxinfor_caption,
sfxinfor_skinsound
};
const char *const sfxinfo_ropt[] = {
@ -38,18 +39,21 @@ const char *const sfxinfo_ropt[] = {
"singular",
"priority",
"flags",
"caption",
"skinsound",
NULL};
enum sfxinfo_write {
sfxinfow_singular = 0,
sfxinfow_priority,
sfxinfow_flags // "pitch"
sfxinfow_flags, // "pitch"
sfxinfow_caption
};
const char *const sfxinfo_wopt[] = {
"singular",
"priority",
"flags",
"caption",
NULL};
//
@ -769,8 +773,8 @@ static int lib_getSfxInfo(lua_State *L)
lua_remove(L, 1);
i = luaL_checkinteger(L, 1);
if (i >= NUMSFX)
return luaL_error(L, "sfxinfo[] index %d out of range (0 - %d)", i, NUMSFX-1);
if (i == 0 || i >= NUMSFX)
return luaL_error(L, "sfxinfo[] index %d out of range (1 - %d)", i, NUMSFX-1);
LUA_PushUserdata(L, &S_sfx[i], META_SFXINFO);
return 1;
}
@ -783,9 +787,9 @@ static int lib_setSfxInfo(lua_State *L)
lua_remove(L, 1);
{
UINT32 i = luaL_checkinteger(L, 1);
if (i >= NUMSFX)
return luaL_error(L, "sfxinfo[] index %d out of range (0 - %d)", i, NUMSFX-1);
info = &S_sfx[i]; // get the mobjinfo to assign to.
if (i == 0 || i >= NUMSFX)
return luaL_error(L, "sfxinfo[] index %d out of range (1 - %d)", i, NUMSFX-1);
info = &S_sfx[i]; // get the sfxinfo to assign to.
}
luaL_checktype(L, 2, LUA_TTABLE); // check that we've been passed a table.
lua_remove(L, 1); // pop mobjtype num, don't need it any more.
@ -814,6 +818,9 @@ static int lib_setSfxInfo(lua_State *L)
case sfxinfow_flags:
info->pitch = (INT32)luaL_checkinteger(L, 3);
break;
case sfxinfow_caption:
strlcpy(info->caption, luaL_checkstring(L, 3), sizeof(info->caption));
break;
default:
break;
}
@ -851,11 +858,14 @@ static int sfxinfo_get(lua_State *L)
case sfxinfor_flags:
lua_pushinteger(L, sfx->pitch);
return 1;
case sfxinfor_caption:
lua_pushstring(L, sfx->caption);
return 1;
case sfxinfor_skinsound:
lua_pushinteger(L, sfx->skinsound);
return 1;
default:
return luaL_error(L, "impossible error");
return luaL_error(L, "Field does not exist in sfxinfo_t");
}
return 0;
}
@ -886,8 +896,11 @@ static int sfxinfo_set(lua_State *L)
case sfxinfow_flags:
sfx->pitch = luaL_checkinteger(L, 1);
break;
case sfxinfow_caption:
strlcpy(sfx->caption, luaL_checkstring(L, 1), sizeof(sfx->caption));
break;
default:
return luaL_error(L, "impossible error");
return luaL_error(L, "Field does not exist in sfxinfo_t");
}
return 0;
}

View File

@ -16,89 +16,127 @@
#include "lua_script.h"
#include "lua_libs.h"
#define META_ITERATIONSTATE "iteration state"
static const char *const iter_opt[] = {
"all",
"mobj",
NULL};
static const actionf_p1 iter_funcs[] = {
NULL,
(actionf_p1)P_MobjThinker
};
struct iterationState {
actionf_p1 filter;
int next;
};
static int iterationState_gc(lua_State *L)
{
struct iterationState *it = luaL_checkudata(L, -1, META_ITERATIONSTATE);
if (it->next != LUA_REFNIL)
{
luaL_unref(L, LUA_REGISTRYINDEX, it->next);
it->next = LUA_REFNIL;
}
return 0;
}
#define push_thinker(th) {\
if ((th)->function.acp1 == (actionf_p1)P_MobjThinker) \
LUA_PushUserdata(L, (th), META_MOBJ); \
else \
lua_pushlightuserdata(L, (th)); \
}
static int lib_iterateThinkers(lua_State *L)
{
int state = luaL_checkoption(L, 1, "mobj", iter_opt);
thinker_t *th = NULL;
actionf_p1 searchFunc;
const char *searchMeta;
thinker_t *th = NULL, *next = NULL;
struct iterationState *it;
if (gamestate != GS_LEVEL)
return luaL_error(L, "This function can only be used in a level!");
lua_settop(L, 2);
lua_remove(L, 1); // remove state now.
it = luaL_checkudata(L, 1, META_ITERATIONSTATE);
switch(state)
lua_settop(L, 2);
if (lua_isnil(L, 2))
th = &thinkercap;
else if (lua_isuserdata(L, 2))
{
case 0:
searchFunc = NULL;
searchMeta = NULL;
break;
case 1:
default:
searchFunc = (actionf_p1)P_MobjThinker;
searchMeta = META_MOBJ;
break;
if (lua_islightuserdata(L, 2))
th = lua_touserdata(L, 2);
else
{
th = *(thinker_t **)lua_touserdata(L, -1);
if (!th)
{
if (it->next == LUA_REFNIL)
return 0;
lua_rawgeti(L, LUA_REGISTRYINDEX, it->next);
if (lua_islightuserdata(L, -1))
next = lua_touserdata(L, -1);
else
next = *(thinker_t **)lua_touserdata(L, -1);
}
}
}
if (!lua_isnil(L, 1)) {
if (lua_islightuserdata(L, 1))
th = (thinker_t *)lua_touserdata(L, 1);
else if (searchMeta)
th = *((thinker_t **)luaL_checkudata(L, 1, searchMeta));
else
th = *((thinker_t **)lua_touserdata(L, 1));
} else
th = &thinkercap;
luaL_unref(L, LUA_REGISTRYINDEX, it->next);
it->next = LUA_REFNIL;
if (!th) // something got our userdata invalidated!
return 0;
if (th && !next)
next = th->next;
if (!next)
return luaL_error(L, "next thinker invalidated during iteration");
if (searchFunc == NULL)
{
if ((th = th->next) != &thinkercap)
for (; next != &thinkercap; next = next->next)
if (!it->filter || next->function.acp1 == it->filter)
{
if (th->function.acp1 == (actionf_p1)P_MobjThinker)
LUA_PushUserdata(L, th, META_MOBJ);
else
lua_pushlightuserdata(L, th);
push_thinker(next);
if (next->next != &thinkercap)
{
push_thinker(next->next);
it->next = luaL_ref(L, LUA_REGISTRYINDEX);
}
return 1;
}
return 0;
}
for (th = th->next; th != &thinkercap; th = th->next)
{
if (th->function.acp1 != searchFunc)
continue;
LUA_PushUserdata(L, th, searchMeta);
return 1;
}
return 0;
}
static int lib_startIterate(lua_State *L)
{
struct iterationState *it;
if (gamestate != GS_LEVEL)
return luaL_error(L, "This function can only be used in a level!");
luaL_checkoption(L, 1, iter_opt[0], iter_opt);
lua_pushcfunction(L, lib_iterateThinkers);
lua_pushvalue(L, 1);
lua_pushvalue(L, lua_upvalueindex(1));
it = lua_newuserdata(L, sizeof(struct iterationState));
luaL_getmetatable(L, META_ITERATIONSTATE);
lua_setmetatable(L, -2);
it->filter = iter_funcs[luaL_checkoption(L, 1, "mobj", iter_opt)];
it->next = LUA_REFNIL;
return 2;
}
#undef push_thinker
int LUA_ThinkerLib(lua_State *L)
{
luaL_newmetatable(L, META_ITERATIONSTATE);
lua_pushcfunction(L, iterationState_gc);
lua_setfield(L, -2, "__gc");
lua_pop(L, 1);
lua_createtable(L, 0, 1);
lua_pushcfunction(L, lib_startIterate);
lua_pushcfunction(L, lib_iterateThinkers);
lua_pushcclosure(L, lib_startIterate, 1);
lua_setfield(L, -2, "iterate");
lua_setglobal(L, "thinkers");
return 0;

View File

@ -18,6 +18,7 @@
#include "z_zone.h"
#include "v_video.h"
#include "i_video.h"
#include "m_misc.h"
// GIFs are always little-endian
#include "byteptr.h"
@ -396,7 +397,6 @@ static void GIF_headwrite(void)
{
UINT8 *gifhead = Z_Malloc(800, PU_STATIC, NULL);
UINT8 *p = gifhead;
RGBA_t *c;
INT32 i;
UINT16 rwidth, rheight;
@ -427,12 +427,17 @@ static void GIF_headwrite(void)
WRITEUINT8(p, 0x00);
// write color table
for (i = 0; i < 256; ++i)
{
c = &pLocalPalette[i];
WRITEUINT8(p, c->s.red);
WRITEUINT8(p, c->s.green);
WRITEUINT8(p, c->s.blue);
RGBA_t *pal = ((cv_screenshot_colorprofile.value)
? pLocalPalette
: pMasterPalette);
for (i = 0; i < 256; i++)
{
WRITEUINT8(p, pal[i].s.red);
WRITEUINT8(p, pal[i].s.green);
WRITEUINT8(p, pal[i].s.blue);
}
}
// write extension block

View File

@ -968,7 +968,7 @@ void OP_NightsObjectplace(player_t *player)
if (player->pflags & PF_ATTACKDOWN)
{
// Are ANY objectplace buttons pressed? If no, remove flag.
if (!(cmd->buttons & (BT_ATTACK|BT_TOSSFLAG|BT_USE|BT_CAMRIGHT|BT_CAMLEFT)))
if (!(cmd->buttons & (BT_ATTACK|BT_TOSSFLAG|BT_USE|BT_WEAPONNEXT|BT_WEAPONPREV)))
player->pflags &= ~PF_ATTACKDOWN;
// Do nothing.
@ -1019,7 +1019,7 @@ void OP_NightsObjectplace(player_t *player)
}
// This places a ring!
if (cmd->buttons & BT_CAMRIGHT)
if (cmd->buttons & BT_WEAPONNEXT)
{
player->pflags |= PF_ATTACKDOWN;
if (!OP_HeightOkay(player, false))
@ -1030,7 +1030,7 @@ void OP_NightsObjectplace(player_t *player)
}
// This places a wing item!
if (cmd->buttons & BT_CAMLEFT)
if (cmd->buttons & BT_WEAPONPREV)
{
player->pflags |= PF_ATTACKDOWN;
if (!OP_HeightOkay(player, false))

View File

@ -573,31 +573,31 @@ extraemblem_t extraemblems[MAXEXTRAEMBLEMS] =
unlockable_t unlockables[MAXUNLOCKABLES] =
{
// Name, Objective, Menu Height, ConditionSet, Unlock Type, Variable, NoCecho, NoChecklist
/* 01 */ {"Record Attack", "Complete Greenflower Zone, Act 1", 0, 1, SECRET_RECORDATTACK, 0, true, true, 0},
/* 02 */ {"NiGHTS Mode", "Complete Floral Field", 0, 2, SECRET_NIGHTSMODE, 0, true, true, 0},
/* 01 */ {"Record Attack", "/", 0, 1, SECRET_RECORDATTACK, 0, true, true, 0},
/* 02 */ {"NiGHTS Mode", "/", 0, 2, SECRET_NIGHTSMODE, 0, true, true, 0},
/* 03 */ {"Play Credits", "Complete 1P Mode", 30, 10, SECRET_CREDITS, 0, true, true, 0},
/* 04 */ {"Sound Test", "Complete 1P Mode", 40, 10, SECRET_SOUNDTEST, 0, false, false, 0},
/* 03 */ {"Play Credits", "/", 30, 10, SECRET_CREDITS, 0, true, true, 0},
/* 04 */ {"Sound Test", "/", 40, 10, SECRET_SOUNDTEST, 0, false, false, 0},
/* 05 */ {"EXTRA LEVELS", "", 60, 0, SECRET_HEADER, 0, true, true, 0},
/* 05 */ {"EXTRA LEVELS", "/", 58, 0, SECRET_HEADER, 0, true, true, 0},
/* 06 */ {"Aerial Garden Zone", "Complete 1P Mode w/ all emeralds", 70, 11, SECRET_WARP, 40, false, false, 0},
/* 07 */ {"Azure Temple Zone", "Complete Aerial Garden Zone", 80, 20, SECRET_WARP, 41, false, false, 0},
/* 06 */ {"Aerial Garden Zone", "/", 70, 11, SECRET_WARP, 40, false, false, 0},
/* 07 */ {"Azure Temple Zone", "/", 80, 20, SECRET_WARP, 41, false, false, 0},
/* 08 */ {"BONUS LEVELS", "", 100, 0, SECRET_HEADER, 0, true, true, 0},
/* 08 */ {"BONUS LEVELS", "/", 98, 0, SECRET_HEADER, 0, true, true, 0},
/* 09 */ {"PLACEHOLDER", "PLACEHOLDER", 0, 0, SECRET_NONE, 0, true, true, 0},
/* 10 */ {"Mario Koopa Blast", "Collect 60 Emblems", 110, 42, SECRET_WARP, 30, false, false, 0},
/* 11 */ {"PLACEHOLDER", "PLACEHOLDER", 0, 0, SECRET_NONE, 0, true, true, 0},
/* 09 */ {"PLACEHOLDER", "/", 0, 0, SECRET_NONE, 0, true, true, 0},
/* 10 */ {"Mario Koopa Blast", "/", 110, 42, SECRET_WARP, 30, false, false, 0},
/* 11 */ {"PLACEHOLDER", "/", 0, 0, SECRET_NONE, 0, true, true, 0},
/* 12 */ {"Spring Hill Zone", "Collect 100 Emblems", 0, 44, SECRET_NONE, 0, false, false, 0},
/* 13 */ {"Black Hole", "A Rank in all Special Stages", 0, 50, SECRET_NONE, 0, false, true, 0},
/* 12 */ {"Spring Hill Zone", "/", 0, 44, SECRET_NONE, 0, false, false, 0},
/* 13 */ {"Black Hole", "Get grade A in all Special Stages", 0, 50, SECRET_NONE, 0, false, true, 0},
/* 14 */ {"Emblem Hints", "Collect 40 Emblems", 0, 41, SECRET_EMBLEMHINTS, 0, false, true, 0},
/* 15 */ {"Emblem Radar", "Collect 80 Emblems", 0, 43, SECRET_ITEMFINDER, 0, false, true, 0},
/* 14 */ {"Emblem Hints", "/", 0, 41, SECRET_EMBLEMHINTS, 0, false, true, 0},
/* 15 */ {"Emblem Radar", "/", 0, 43, SECRET_ITEMFINDER, 0, false, true, 0},
/* 16 */ {"Pandora's Box", "Collect All Emblems", 0, 45, SECRET_PANDORA, 0, false, false, 0},
/* 17 */ {"Level Select", "Collect All Emblems", 20, 45, SECRET_LEVELSELECT, 1, false, true, 0},
/* 16 */ {"Pandora's Box", "/", 0, 45, SECRET_PANDORA, 0, false, false, 0},
/* 17 */ {"Level Select", "/", 20, 45, SECRET_LEVELSELECT, 1, false, true, 0},
};
// Default number of emblems and extra emblems

File diff suppressed because it is too large Load Diff

View File

@ -100,6 +100,8 @@ static CV_PossibleValue_t screenshot_cons_t[] = {{0, "Default"}, {1, "HOME"}, {2
consvar_t cv_screenshot_option = {"screenshot_option", "Default", CV_SAVE|CV_CALL, screenshot_cons_t, Screenshot_option_Onchange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_screenshot_folder = {"screenshot_folder", "", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_screenshot_colorprofile = {"screenshot_colorprofile", "Yes", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t moviemode_cons_t[] = {{MM_GIF, "GIF"}, {MM_APNG, "aPNG"}, {MM_SCREENSHOT, "Screenshots"}, {0, NULL}};
consvar_t cv_moviemode = {"moviemode_mode", "GIF", CV_SAVE|CV_CALL, moviemode_cons_t, Moviemode_mode_Onchange, 0, NULL, NULL, 0, 0, NULL};
@ -610,20 +612,25 @@ static void PNG_warn(png_structp PNG, png_const_charp pngtext)
CONS_Debug(DBG_RENDER, "libpng warning at %p: %s", PNG, pngtext);
}
static void M_PNGhdr(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_uint_32 width, PNG_CONST png_uint_32 height, PNG_CONST png_byte *palette)
static void M_PNGhdr(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_uint_32 width, PNG_CONST png_uint_32 height, const boolean palette)
{
const png_byte png_interlace = PNG_INTERLACE_NONE; //PNG_INTERLACE_ADAM7
if (palette)
{
png_colorp png_PLTE = png_malloc(png_ptr, sizeof(png_color)*256); //palette
const png_byte *pal = palette;
png_uint_16 i;
RGBA_t *pal = ((cv_screenshot_colorprofile.value)
? pLocalPalette
: pMasterPalette);
for (i = 0; i < 256; i++)
{
png_PLTE[i].red = *pal; pal++;
png_PLTE[i].green = *pal; pal++;
png_PLTE[i].blue = *pal; pal++;
png_PLTE[i].red = pal[i].s.red;
png_PLTE[i].green = pal[i].s.green;
png_PLTE[i].blue = pal[i].s.blue;
}
png_set_IHDR(png_ptr, png_info_ptr, width, height, 8, PNG_COLOR_TYPE_PALETTE,
png_interlace, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
png_write_info_before_PLTE(png_ptr, png_info_ptr);
@ -924,7 +931,7 @@ static void M_PNGfix_acTL(png_structp png_ptr, png_infop png_info_ptr)
fseek(apng_FILE, oldpos, SEEK_SET);
}
static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal)
static boolean M_SetupaPNG(png_const_charp filename, boolean palette)
{
apng_FILE = fopen(filename,"wb+"); // + mode for reading
if (!apng_FILE)
@ -966,7 +973,7 @@ static boolean M_SetupaPNG(png_const_charp filename, png_bytep pal)
png_set_compression_strategy(apng_ptr, cv_zlib_strategya.value);
png_set_compression_window_bits(apng_ptr, cv_zlib_window_bitsa.value);
M_PNGhdr(apng_ptr, apng_info_ptr, vid.width, vid.height, pal);
M_PNGhdr(apng_ptr, apng_info_ptr, vid.width, vid.height, palette);
M_PNGText(apng_ptr, apng_info_ptr, true);
@ -1007,9 +1014,9 @@ static inline moviemode_t M_StartMovieAPNG(const char *pathname)
}
if (rendermode == render_soft)
ret = M_SetupaPNG(va(pandf,pathname,freename), W_CacheLumpName(GetPalette(), PU_CACHE));
ret = M_SetupaPNG(va(pandf,pathname,freename), true);
else
ret = M_SetupaPNG(va(pandf,pathname,freename), NULL);
ret = M_SetupaPNG(va(pandf,pathname,freename), false);
if (!ret)
{
@ -1215,11 +1222,10 @@ void M_StopMovie(void)
* \param palette Palette of image data
* \note if palette is NULL, BGR888 format
*/
boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette)
boolean M_SavePNG(const char *filename, void *data, int width, int height, const boolean palette)
{
png_structp png_ptr;
png_infop png_info_ptr;
PNG_CONST png_byte *PLTE = (const png_byte *)palette;
#ifdef PNG_SETJMP_SUPPORTED
#ifdef USE_FAR_KEYWORD
jmp_buf jmpbuf;
@ -1282,7 +1288,7 @@ boolean M_SavePNG(const char *filename, void *data, int width, int height, const
png_set_compression_strategy(png_ptr, cv_zlib_strategy.value);
png_set_compression_window_bits(png_ptr, cv_zlib_window_bits.value);
M_PNGhdr(png_ptr, png_info_ptr, width, height, PLTE);
M_PNGhdr(png_ptr, png_info_ptr, width, height, palette);
M_PNGText(png_ptr, png_info_ptr, false);
@ -1329,7 +1335,7 @@ typedef struct
* \param palette Palette of image data
*/
#if NUMSCREENS > 2
static boolean WritePCXfile(const char *filename, const UINT8 *data, int width, int height, const UINT8 *palette)
static boolean WritePCXfile(const char *filename, const UINT8 *data, int width, int height)
{
int i;
size_t length;
@ -1370,8 +1376,20 @@ static boolean WritePCXfile(const char *filename, const UINT8 *data, int width,
// write the palette
*pack++ = 0x0c; // palette ID byte
for (i = 0; i < 768; i++)
*pack++ = *palette++;
// write color table
{
RGBA_t *pal = ((cv_screenshot_colorprofile.value)
? pLocalPalette
: pMasterPalette);
for (i = 0; i < 256; i++)
{
*pack++ = pal[i].s.red;
*pack++ = pal[i].s.green;
*pack++ = pal[i].s.blue;
}
}
// write output file
length = pack - (UINT8 *)pcx;
@ -1445,11 +1463,9 @@ void M_DoScreenShot(void)
if (rendermode != render_none)
{
#ifdef USE_PNG
ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height,
W_CacheLumpName(GetPalette(), PU_CACHE));
ret = M_SavePNG(va(pandf,pathname,freename), linear, vid.width, vid.height, true);
#else
ret = WritePCXfile(va(pandf,pathname,freename), linear, vid.width, vid.height,
W_CacheLumpName(GetPalette(), PU_CACHE));
ret = WritePCXfile(va(pandf,pathname,freename), linear, vid.width, vid.height);
#endif
}

View File

@ -29,7 +29,7 @@ typedef enum {
} moviemode_t;
extern moviemode_t moviemode;
extern consvar_t cv_screenshot_option, cv_screenshot_folder;
extern consvar_t cv_screenshot_option, cv_screenshot_folder, cv_screenshot_colorprofile;
extern consvar_t cv_moviemode;
extern consvar_t cv_zlib_memory, cv_zlib_level, cv_zlib_strategy, cv_zlib_window_bits;
extern consvar_t cv_zlib_memorya, cv_zlib_levela, cv_zlib_strategya, cv_zlib_window_bitsa;
@ -64,7 +64,7 @@ void FIL_ForceExtension(char *path, const char *extension);
boolean FIL_CheckExtension(const char *in);
#ifdef HAVE_PNG
boolean M_SavePNG(const char *filename, void *data, int width, int height, const UINT8 *palette);
boolean M_SavePNG(const char *filename, void *data, int width, int height, const boolean palette);
#endif
extern boolean takescreenshot;

View File

@ -1145,7 +1145,7 @@ void A_JetJawChomp(mobj_t *actor)
if (!actor->target || !(actor->target->flags & MF_SHOOTABLE)
|| actor->target->health <= 0 || !P_CheckSight(actor, actor->target))
{
P_SetMobjState(actor, actor->info->spawnstate);
P_SetMobjStateNF(actor, actor->info->spawnstate);
return;
}
@ -3170,6 +3170,8 @@ void A_Invincibility(mobj_t *actor)
S_StopMusic();
if (mariomode)
G_GhostAddColor(GHC_INVINCIBLE);
strlcpy(S_sfx[sfx_None].caption, "Invincibility", 14);
S_StartCaption(sfx_None, -1, player->powers[pw_invulnerability]);
S_ChangeMusicInternal((mariomode) ? "_minv" : "_inv", false);
}
}
@ -3208,6 +3210,8 @@ void A_SuperSneakers(mobj_t *actor)
S_StopMusic();
S_ChangeMusicInternal("_shoes", false);
}
strlcpy(S_sfx[sfx_None].caption, "Speed shoes", 12);
S_StartCaption(sfx_None, -1, player->powers[pw_sneakers]);
}
}
@ -5602,7 +5606,10 @@ void A_MixUp(mobj_t *actor)
// No mix-up monitors in hide and seek or time only race.
// The random factor is okay for other game modes, but in these, it is cripplingly unfair.
if (gametype == GT_HIDEANDSEEK || gametype == GT_RACE)
{
S_StartSound(actor, sfx_lose);
return;
}
numplayers = 0;
memset(teleported, 0, sizeof (teleported));

View File

@ -2113,6 +2113,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
boolean inAndOut = false;
boolean floortouch = false;
fixed_t bottomheight, topheight;
msecnode_t *node;
for (i = 0; i < MAXPLAYERS; i++)
{
@ -2174,7 +2175,23 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
if ((netgame || multiplayer) && players[j].spectator)
continue;
if (players[j].mo->subsector->sector != targetsec)
if (players[j].mo->subsector->sector == targetsec)
;
else if (sec->flags & SF_TRIGGERSPECIAL_TOUCH)
{
boolean insector = false;
for (node = players[j].mo->touching_sectorlist; node; node = node->m_sectorlist_next)
{
if (node->m_sector == targetsec)
{
insector = true;
break;
}
}
if (!insector)
continue;
}
else
continue;
topheight = P_GetSpecialTopZ(players[j].mo, sec, targetsec);
@ -2224,7 +2241,27 @@ void T_EachTimeThinker(levelspecthink_t *eachtime)
if ((netgame || multiplayer) && players[i].spectator)
continue;
if (players[i].mo->subsector->sector != sec)
if (players[i].mo->subsector->sector == sec)
;
else if (sec->flags & SF_TRIGGERSPECIAL_TOUCH)
{
boolean insector = false;
for (node = players[i].mo->touching_sectorlist; node; node = node->m_sectorlist_next)
{
if (node->m_sector == sec)
{
insector = true;
break;
}
}
if (!insector)
continue;
}
else
continue;
if (!(players[i].mo->subsector->sector == sec
|| P_PlayerTouchingSectorSpecial(&players[i], 2, (GETSECSPECIAL(sec->special, 2))) == sec))
continue;
if (floortouch == true && P_IsObjectOnGroundIn(players[i].mo, sec))
@ -2929,7 +2966,7 @@ void EV_CrumbleChain(sector_t *sec, ffloor_t *rover)
fixed_t leftx, rightx;
fixed_t topy, bottomy;
fixed_t topz, bottomz;
fixed_t widthfactor, heightfactor;
fixed_t widthfactor = FRACUNIT, heightfactor = FRACUNIT;
fixed_t a, b, c;
mobjtype_t type = MT_ROCKCRUMBLE1;
fixed_t spacing = (32<<FRACBITS);

View File

@ -257,6 +257,8 @@ void P_DoMatchSuper(player_t *player)
S_StopMusic();
if (mariomode)
G_GhostAddColor(GHC_INVINCIBLE);
strlcpy(S_sfx[sfx_None].caption, "Invincibility", 14);
S_StartCaption(sfx_None, -1, player->powers[pw_invulnerability]);
S_ChangeMusicInternal((mariomode) ? "_minv" : "_inv", false);
}
@ -278,6 +280,8 @@ void P_DoMatchSuper(player_t *player)
S_StopMusic();
if (mariomode)
G_GhostAddColor(GHC_INVINCIBLE);
strlcpy(S_sfx[sfx_None].caption, "Invincibility", 14);
S_StartCaption(sfx_None, -1, player->powers[pw_invulnerability]);
S_ChangeMusicInternal((mariomode) ? "_minv" : "_inv", false);
}
}
@ -571,10 +575,17 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
return;
tokenlist += special->health;
P_AddPlayerScore(player, 1000);
if (ALL7EMERALDS(emeralds)) // Got all 7
{
P_GivePlayerRings(player, 50);
nummaprings += 50; // no cheating towards Perfect!
if (!(netgame || multiplayer))
{
player->continues += 1;
players->gotcontinue = true;
if (P_IsLocalPlayer(player))
S_StartSound(NULL, sfx_s3kac);
}
}
else
token++;
@ -2097,7 +2108,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
{
if (metalrecording) // Ack! Metal Sonic shouldn't die! Cut the tape, end recording!
G_StopMetalRecording();
if (gametype == GT_MATCH && cv_match_scoring.value == 0 // note, no team match suicide penalty
if (gametype == GT_MATCH // note, no team match suicide penalty
&& ((target == source) || (source == NULL && inflictor == NULL) || (source && !source->player)))
{ // Suicide penalty
if (target->player->score >= 50)
@ -2887,7 +2898,7 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source,
{
// Award no points when players shoot each other when cv_friendlyfire is on.
if (!G_GametypeHasTeams() || !(source->player->ctfteam == player->ctfteam && source != player->mo))
P_AddPlayerScore(source->player, cv_match_scoring.value == 1 ? 25 : 50);
P_AddPlayerScore(source->player, 50);
}
}
@ -3120,14 +3131,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
return false; // Don't get hurt by fire generated from friends.
}
// Sudden-Death mode
if (source && source->type == MT_PLAYER)
{
if ((gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF) && cv_suddendeath.value
&& !player->powers[pw_flashing] && !player->powers[pw_invulnerability])
damagetype = DMG_INSTAKILL;
}
// Player hits another player
if (!force && source && source->player)
{

View File

@ -2560,10 +2560,18 @@ boolean P_CheckSolidLava(mobj_t *mo, ffloor_t *rover)
I_Assert(mo != NULL);
I_Assert(!P_MobjWasRemoved(mo));
if (rover->flags & FF_SWIMMABLE && GETSECSPECIAL(rover->master->frontsector->special, 1) == 3
&& !(rover->master->flags & ML_BLOCKMONSTERS)
&& ((rover->master->flags & ML_EFFECT3) || mo->z-mo->momz > *rover->topheight - FixedMul(16*FRACUNIT, mo->scale)))
return true;
{
fixed_t topheight =
#ifdef ESLOPE
*rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) :
#endif
*rover->topheight;
if (rover->flags & FF_SWIMMABLE && GETSECSPECIAL(rover->master->frontsector->special, 1) == 3
&& !(rover->master->flags & ML_BLOCKMONSTERS)
&& ((rover->master->flags & ML_EFFECT3) || mo->z-mo->momz > topheight - FixedMul(16*FRACUNIT, mo->scale)))
return true;
}
return false;
}
@ -2802,7 +2810,7 @@ static boolean P_ZMovement(mobj_t *mo)
mo->z = mo->floorz;
#ifdef ESLOPE
if (mo->standingslope) // You're still on the ground; why are we here?
if (!(mo->flags & MF_MISSILE) && mo->standingslope) // You're still on the ground; why are we here?
{
mo->momz = 0;
return true;
@ -3578,11 +3586,17 @@ static boolean P_SceneryZMovement(mobj_t *mo)
//
boolean P_CanRunOnWater(player_t *player, ffloor_t *rover)
{
fixed_t topheight =
#ifdef ESLOPE
*rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) :
#endif
*rover->topheight;
if (!player->powers[pw_carry] && !player->homing
&& ((player->powers[pw_super] || player->charflags & SF_RUNONWATER || player->dashmode >= 3*TICRATE) && player->mo->ceilingz-*rover->topheight >= player->mo->height)
&& ((player->powers[pw_super] || player->charflags & SF_RUNONWATER || player->dashmode >= 3*TICRATE) && player->mo->ceilingz-topheight >= player->mo->height)
&& (rover->flags & FF_SWIMMABLE) && !(player->pflags & PF_SPINNING) && player->speed > FixedMul(player->runspeed, player->mo->scale)
&& !(player->pflags & PF_SLIDING)
&& abs(player->mo->z - *rover->topheight) < FixedMul(30*FRACUNIT, player->mo->scale))
&& abs(player->mo->z - topheight) < FixedMul(30*FRACUNIT, player->mo->scale))
return true;
return false;
@ -8515,6 +8529,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
break;
case MT_EGGCAPSULE:
mobj->extravalue1 = -1; // timer for how long a player has been at the capsule
break;
case MT_REDTEAMRING:
mobj->color = skincolor_redteam;
break;
@ -8779,7 +8794,6 @@ consvar_t cv_itemrespawntime = {"respawnitemtime", "30", CV_NETVAR|CV_CHEAT, res
consvar_t cv_itemrespawn = {"respawnitem", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t flagtime_cons_t[] = {{0, "MIN"}, {300, "MAX"}, {0, NULL}};
consvar_t cv_flagtime = {"flagtime", "30", CV_NETVAR|CV_CHEAT, flagtime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_suddendeath = {"suddendeath", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
void P_SpawnPrecipitation(void)
{
@ -9522,7 +9536,7 @@ void P_SpawnMapThing(mapthing_t *mthing)
// Yeah, this is a dirty hack.
if ((mobjinfo[i].flags & (MF_MONITOR|MF_GRENADEBOUNCE)) == MF_MONITOR)
{
if (gametype == GT_COMPETITION)
if (gametype == GT_COMPETITION || gametype == GT_RACE)
{
// Set powerup boxes to user settings for competition.
if (cv_competitionboxes.value == 1) // Random
@ -9595,7 +9609,8 @@ void P_SpawnMapThing(mapthing_t *mthing)
if (ultimatemode)
{
if (i == MT_PITY_BOX || i == MT_ELEMENTAL_BOX || i == MT_ATTRACT_BOX
|| i == MT_FORCE_BOX || i == MT_ARMAGEDDON_BOX || i == MT_WHIRLWIND_BOX)
|| i == MT_FORCE_BOX || i == MT_ARMAGEDDON_BOX || i == MT_WHIRLWIND_BOX
|| i == MT_FLAMEAURA_BOX || i == MT_BUBBLEWRAP_BOX || i == MT_THUNDERCOIN_BOX)
return; // No shields in Ultimate mode
if (i == MT_RING_BOX && !G_IsSpecialStage(gamemap))
@ -9717,11 +9732,10 @@ void P_SpawnMapThing(mapthing_t *mthing)
switch(mobj->type)
{
case MT_SKYBOX:
mobj->angle = 0;
if (mthing->options & MTF_OBJECTSPECIAL)
skyboxmo[1] = mobj;
skyboxcenterpnts[mthing->extrainfo] = mobj;
else
skyboxmo[0] = mobj;
skyboxviewpnts[mthing->extrainfo] = mobj;
break;
case MT_FAN:
if (mthing->options & MTF_OBJECTSPECIAL)
@ -9766,20 +9780,16 @@ void P_SpawnMapThing(mapthing_t *mthing)
mobjtype_t macetype = MT_SMALLMACE;
boolean firsttime;
mobj_t *spawnee;
size_t line;
INT32 line;
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)
break;
}
// Find the corresponding linedef special, using angle as tag
// P_FindSpecialLineFromTag works here now =D
line = P_FindSpecialLineFromTag(9, mthing->angle, -1);
if (line == numlines)
if (line == -1)
{
CONS_Debug(DBG_GAMELOGIC, "Mace chain (mapthing #%s) needs tagged to a #9 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle);
CONS_Debug(DBG_GAMELOGIC, "Mace chain (mapthing #%s) needs to be tagged to a #9 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle);
return;
}
/*
@ -9877,18 +9887,15 @@ ML_NOCLIMB : Direction not controllable
fixed_t radius, speed, bottomheight, topheight;
INT32 type, numdivisions, time, anglespeed;
angle_t angledivision;
size_t line;
INT32 line;
const size_t mthingi = (size_t)(mthing - mapthings);
for (line = 0; line < numlines; line++)
{
if (lines[line].special == 15 && lines[line].tag == mthing->angle)
break;
}
// Find the corresponding linedef special, using angle as tag
line = P_FindSpecialLineFromTag(15, mthing->angle, -1);
if (line == numlines)
if (line == -1)
{
CONS_Debug(DBG_GAMELOGIC, "Particle generator (mapthing #%s) needs tagged to a #15 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle);
CONS_Debug(DBG_GAMELOGIC, "Particle generator (mapthing #%s) needs to be tagged to a #15 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle);
return;
}

View File

@ -46,7 +46,9 @@
#include <errno.h>
#endif
mobj_t *skyboxmo[2];
mobj_t *skyboxmo[2]; // current skybox mobjs: 0 = viewpoint, 1 = centerpoint
mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs
mobj_t *skyboxcenterpnts[16]; // array of MT_SKYBOX centerpoint mobjs
// Amount (dx, dy) vector linedef is shifted right to get scroll amount
#define SCROLL_SHIFT 5
@ -2445,73 +2447,81 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
case 414: // Play SFX
{
fixed_t sfxnum;
INT32 sfxnum;
sfxnum = sides[line->sidenum[0]].toptexture;
if (line->tag != 0 && line->flags & ML_EFFECT5)
if (sfxnum == sfx_None)
return; // Do nothing!
if (sfxnum < sfx_None || sfxnum >= NUMSFX)
{
sector_t *sec;
while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0)
CONS_Debug(DBG_GAMELOGIC, "Line type 414 Executor: sfx number %d is invalid!\n", sfxnum);
return;
}
if (line->tag != 0) // Do special stuff only if a non-zero linedef tag is set
{
if (line->flags & ML_EFFECT5) // Repeat Midtexture
{
sec = &sectors[secnum];
S_StartSound(&sec->soundorg, sfxnum);
// Additionally play the sound from tagged sectors' soundorgs
sector_t *sec;
while ((secnum = P_FindSectorFromLineTag(line, secnum)) >= 0)
{
sec = &sectors[secnum];
S_StartSound(&sec->soundorg, sfxnum);
}
}
else if (mo) // A mobj must have triggered the executor
{
// Only trigger if mobj is touching the tag
ffloor_t *rover;
boolean foundit = false;
for(rover = mo->subsector->sector->ffloors; rover; rover = rover->next)
{
if (rover->master->frontsector->tag != line->tag)
continue;
if (mo->z > P_GetSpecialTopZ(mo, sectors + rover->secnum, mo->subsector->sector))
continue;
if (mo->z + mo->height < P_GetSpecialBottomZ(mo, sectors + rover->secnum, mo->subsector->sector))
continue;
foundit = true;
}
if (mo->subsector->sector->tag == line->tag)
foundit = true;
if (!foundit)
return;
}
}
else if (line->tag != 0 && mo)
if (line->flags & ML_NOCLIMB)
{
// Only trigger if mobj is touching the tag
ffloor_t *rover;
boolean foundit = false;
for(rover = mo->subsector->sector->ffloors; rover; rover = rover->next)
{
if (rover->master->frontsector->tag != line->tag)
continue;
if (mo->z > P_GetSpecialTopZ(mo, sectors + rover->secnum, mo->subsector->sector))
continue;
if (mo->z + mo->height < P_GetSpecialBottomZ(mo, sectors + rover->secnum, mo->subsector->sector))
continue;
foundit = true;
}
if (mo->subsector->sector->tag == line->tag)
foundit = true;
if (!foundit)
return;
}
if (sfxnum < NUMSFX && sfxnum > sfx_None)
{
if (line->flags & ML_NOCLIMB)
{
// play the sound from nowhere, but only if display player triggered it
if (mo && mo->player && (mo->player == &players[displayplayer] || mo->player == &players[secondarydisplayplayer]))
S_StartSound(NULL, sfxnum);
}
else if (line->flags & ML_EFFECT4)
{
// play the sound from nowhere
// play the sound from nowhere, but only if display player triggered it
if (mo && mo->player && (mo->player == &players[displayplayer] || mo->player == &players[secondarydisplayplayer]))
S_StartSound(NULL, sfxnum);
}
else if (line->flags & ML_BLOCKMONSTERS)
{
// play the sound from calling sector's soundorg
if (callsec)
S_StartSound(&callsec->soundorg, sfxnum);
else if (mo)
S_StartSound(&mo->subsector->sector->soundorg, sfxnum);
}
}
else if (line->flags & ML_EFFECT4)
{
// play the sound from nowhere
S_StartSound(NULL, sfxnum);
}
else if (line->flags & ML_BLOCKMONSTERS)
{
// play the sound from calling sector's soundorg
if (callsec)
S_StartSound(&callsec->soundorg, sfxnum);
else if (mo)
{
// play the sound from mobj that triggered it
S_StartSound(mo, sfxnum);
}
S_StartSound(&mo->subsector->sector->soundorg, sfxnum);
}
else if (mo)
{
// play the sound from mobj that triggered it
S_StartSound(mo, sfxnum);
}
}
break;
@ -3162,6 +3172,47 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
}
break;
case 448: // Change skybox viewpoint/centerpoint
if ((mo && mo->player && P_IsLocalPlayer(mo->player)) || (line->flags & ML_NOCLIMB))
{
INT32 viewid = sides[line->sidenum[0]].textureoffset>>FRACBITS;
INT32 centerid = sides[line->sidenum[0]].rowoffset>>FRACBITS;
if ((line->flags & (ML_EFFECT4|ML_BLOCKMONSTERS)) == ML_EFFECT4) // Solid Midtexture is on but Block Enemies is off?
{
CONS_Alert(CONS_WARNING,
M_GetText("Skybox switch linedef (tag %d) doesn't have anything to do.\nConsider changing the linedef's flag configuration or removing it entirely.\n"),
line->tag);
}
else
{
// set viewpoint mobj
if (!(line->flags & ML_EFFECT4)) // Solid Midtexture turns off viewpoint setting
{
if (viewid >= 0 && viewid < 16)
skyboxmo[0] = skyboxviewpnts[viewid];
else
skyboxmo[0] = NULL;
}
// set centerpoint mobj
if (line->flags & ML_BLOCKMONSTERS) // Block Enemies turns ON centerpoint setting
{
if (centerid >= 0 && centerid < 16)
skyboxmo[1] = skyboxcenterpnts[centerid];
else
skyboxmo[1] = NULL;
}
}
CONS_Debug(DBG_GAMELOGIC, "Line type 448 Executor: viewid = %d, centerid = %d, viewpoint? = %s, centerpoint? = %s\n",
viewid,
centerid,
((line->flags & ML_EFFECT4) ? "no" : "yes"),
((line->flags & ML_BLOCKMONSTERS) ? "yes" : "no"));
}
break;
case 450: // Execute Linedef Executor - for recursion
P_LinedefExecute(line->tag, mo, NULL);
break;
@ -3529,7 +3580,7 @@ static boolean P_ThingIsOnThe3DFloor(mobj_t *mo, sector_t *sector, sector_t *tar
//
// Is player standing on the sector's "ground"?
//
static inline boolean P_MobjReadyToTrigger(mobj_t *mo, sector_t *sec)
static boolean P_MobjReadyToTrigger(mobj_t *mo, sector_t *sec)
{
if (mo->eflags & MFE_VERTICALFLIP)
return (mo->z+mo->height == P_GetSpecialTopZ(mo, sec, sec) && sec->flags & SF_FLIPSPECIAL_CEILING);
@ -3662,14 +3713,49 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers
{
if (roversector)
{
if (players[i].mo->subsector->sector != roversector)
if (players[i].mo->subsector->sector == roversector)
;
else if (sector->flags & SF_TRIGGERSPECIAL_TOUCH)
{
boolean insector = false;
msecnode_t *node;
for (node = players[i].mo->touching_sectorlist; node; node = node->m_sectorlist_next)
{
if (node->m_sector == roversector)
{
insector = true;
break;
}
}
if (!insector)
goto DoneSection2;
}
else
goto DoneSection2;
if (!P_ThingIsOnThe3DFloor(players[i].mo, sector, roversector))
goto DoneSection2;
}
else
{
if (players[i].mo->subsector->sector != sector)
if (players[i].mo->subsector->sector == sector)
;
else if (sector->flags & SF_TRIGGERSPECIAL_TOUCH)
{
boolean insector = false;
msecnode_t *node;
for (node = players[i].mo->touching_sectorlist; node; node = node->m_sectorlist_next)
{
if (node->m_sector == sector)
{
insector = true;
break;
}
}
if (!insector)
goto DoneSection2;
}
else
goto DoneSection2;
if (special == 3 && !P_MobjReadyToTrigger(players[i].mo, sector))
@ -4450,6 +4536,7 @@ sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo)
{
sector_t *sector;
ffloor_t *rover;
fixed_t topheight, bottomheight;
sector = mo->subsector->sector;
if (!sector->ffloors)
@ -4457,8 +4544,6 @@ sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo)
for (rover = sector->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!rover->master->frontsector->special)
continue;
@ -4506,6 +4591,8 @@ sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo)
return NULL;
}
#define TELEPORTED (player->mo->subsector->sector != originalsector)
/** Checks if a player is standing on or is inside a 3D floor (e.g. water) and
* applies any specials.
*
@ -4514,12 +4601,12 @@ sector_t *P_ThingOnSpecial3DFloor(mobj_t *mo)
*/
static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
{
sector_t *originalsector = player->mo->subsector->sector;
ffloor_t *rover;
fixed_t topheight, bottomheight;
for (rover = sector->ffloors; rover; rover = rover->next)
{
fixed_t topheight, bottomheight;
if (!rover->master->frontsector->special)
continue;
@ -4563,7 +4650,10 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
// This FOF has the special we're looking for, but are we allowed to touch it?
if (sector == player->mo->subsector->sector
|| (rover->master->frontsector->flags & SF_TRIGGERSPECIAL_TOUCH))
{
P_ProcessSpecialSector(player, rover->master->frontsector, sector);
if TELEPORTED return;
}
}
// Allow sector specials to be applied to polyobjects!
@ -4574,7 +4664,7 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
boolean touching = false;
boolean inside = false;
while(po)
while (po)
{
if (po->flags & POF_NOSPECIALS)
{
@ -4650,6 +4740,7 @@ static void P_PlayerOnSpecial3DFloor(player_t *player, sector_t *sector)
}
P_ProcessSpecialSector(player, polysec, sector);
if TELEPORTED return;
po = (polyobj_t *)(po->link.next);
}
@ -4754,40 +4845,43 @@ static void P_RunSpecialSectorCheck(player_t *player, sector_t *sector)
*/
void P_PlayerInSpecialSector(player_t *player)
{
sector_t *sector;
sector_t *originalsector;
sector_t *loopsector;
msecnode_t *node;
if (!player->mo)
return;
// Do your ->subsector->sector first
sector = player->mo->subsector->sector;
P_PlayerOnSpecial3DFloor(player, sector);
// After P_PlayerOnSpecial3DFloor, recheck if the player is in that sector,
// because the player can be teleported in between these times.
if (sector == player->mo->subsector->sector)
P_RunSpecialSectorCheck(player, sector);
originalsector = player->mo->subsector->sector;
// Iterate through touching_sectorlist
P_PlayerOnSpecial3DFloor(player, originalsector); // Handle FOFs first.
if TELEPORTED return;
P_RunSpecialSectorCheck(player, originalsector);
if TELEPORTED return;
// Iterate through touching_sectorlist for SF_TRIGGERSPECIAL_TOUCH
for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next)
{
sector = node->m_sector;
loopsector = node->m_sector;
if (sector == player->mo->subsector->sector) // Don't duplicate
if (loopsector == originalsector) // Don't duplicate
continue;
// Check 3D floors...
P_PlayerOnSpecial3DFloor(player, sector);
P_PlayerOnSpecial3DFloor(player, loopsector);
if TELEPORTED return;
if (!(sector->flags & SF_TRIGGERSPECIAL_TOUCH))
return;
// After P_PlayerOnSpecial3DFloor, recheck if the player is in that sector,
// because the player can be teleported in between these times.
if (sector == player->mo->subsector->sector)
P_RunSpecialSectorCheck(player, sector);
if (!(loopsector->flags & SF_TRIGGERSPECIAL_TOUCH))
continue;
P_RunSpecialSectorCheck(player, loopsector);
if TELEPORTED return;
}
}
#undef TELEPORTED
/** Animate planes, scroll walls, etc. and keeps track of level timelimit and exits if time is up.
*
* \sa P_CheckTimeLimit, P_CheckPointLimit
@ -5549,6 +5643,45 @@ static void P_RunLevelLoadExecutors(void)
}
}
/** Before things are loaded, initialises certain stuff in case they're needed
* by P_ResetDynamicSlopes or P_LoadThings. This was split off from
* P_SpawnSpecials, in case you couldn't tell.
*
* \sa P_SpawnSpecials, P_InitTagLists
* \author Monster Iestyn
*/
void P_InitSpecials(void)
{
// Set the default gravity. Custom gravity overrides this setting.
gravity = FRACUNIT/2;
// Defaults in case levels don't have them set.
sstimer = 90*TICRATE + 6;
totalrings = 1;
CheckForBustableBlocks = CheckForBouncySector = CheckForQuicksand = CheckForMarioBlocks = CheckForFloatBob = CheckForReverseGravity = false;
// Set curWeather
switch (mapheaderinfo[gamemap-1]->weather)
{
case PRECIP_SNOW: // snow
case PRECIP_RAIN: // rain
case PRECIP_STORM: // storm
case PRECIP_STORM_NORAIN: // storm w/o rain
case PRECIP_STORM_NOSTRIKES: // storm w/o lightning
curWeather = mapheaderinfo[gamemap-1]->weather;
break;
default: // blank/none
curWeather = PRECIP_NONE;
break;
}
// Set globalweather
globalweather = mapheaderinfo[gamemap-1]->weather;
P_InitTagLists(); // Create xref tables for tags
}
/** After the map has loaded, scans for specials that spawn 3Dfloors and
* thinkers.
*
@ -5570,15 +5703,6 @@ void P_SpawnSpecials(INT32 fromnetsave)
// but currently isn't.
(void)fromnetsave;
// Set the default gravity. Custom gravity overrides this setting.
gravity = FRACUNIT/2;
// Defaults in case levels don't have them set.
sstimer = 90*TICRATE + 6;
totalrings = 1;
CheckForBustableBlocks = CheckForBouncySector = CheckForQuicksand = CheckForMarioBlocks = CheckForFloatBob = CheckForReverseGravity = false;
// Init special SECTORs.
sector = sectors;
for (i = 0; i < numsectors; i++, sector++)
@ -5627,20 +5751,6 @@ void P_SpawnSpecials(INT32 fromnetsave)
}
}
if (mapheaderinfo[gamemap-1]->weather == 2) // snow
curWeather = PRECIP_SNOW;
else if (mapheaderinfo[gamemap-1]->weather == 3) // rain
curWeather = PRECIP_RAIN;
else if (mapheaderinfo[gamemap-1]->weather == 1) // storm
curWeather = PRECIP_STORM;
else if (mapheaderinfo[gamemap-1]->weather == 5) // storm w/o rain
curWeather = PRECIP_STORM_NORAIN;
else if (mapheaderinfo[gamemap-1]->weather == 6) // storm w/o lightning
curWeather = PRECIP_STORM_NOSTRIKES;
else
curWeather = PRECIP_NONE;
P_InitTagLists(); // Create xref tables for tags
P_SearchForDisableLinedefs(); // Disable linedefs are now allowed to disable *any* line
P_SpawnScrollers(); // Add generalized scrollers

View File

@ -17,7 +17,9 @@
#ifndef __P_SPEC__
#define __P_SPEC__
extern mobj_t *skyboxmo[2];
extern mobj_t *skyboxmo[2]; // current skybox mobjs: 0 = viewpoint, 1 = centerpoint
extern mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs
extern mobj_t *skyboxcenterpnts[16]; // array of MT_SKYBOX centerpoint mobjs
// GETSECSPECIAL (specialval, section)
//
@ -32,6 +34,7 @@ void P_InitPicAnims(void);
void P_SetupLevelFlatAnims(void);
// at map load
void P_InitSpecials(void);
void P_SpawnSpecials(INT32 fromnetsave);
// every tic

View File

@ -1030,7 +1030,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount)
players[i].continues += 1;
players[i].gotcontinue = true;
if (P_IsLocalPlayer(player))
S_StartSound(NULL, sfx_flgcap);
S_StartSound(NULL, sfx_s3kac);
} */
}
}
@ -1050,7 +1050,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount)
player->continues += 1;
player->gotcontinue = true;
if (P_IsLocalPlayer(player))
S_StartSound(NULL, sfx_flgcap);
S_StartSound(NULL, sfx_s3kac);
}
}
@ -1134,8 +1134,10 @@ void P_PlayLivesJingle(player_t *player)
else
{
if (player)
player->powers[pw_extralife] = extralifetics + 1;
player->powers[pw_extralife] = extralifetics+1;
S_StopMusic(); // otherwise it won't restart if this is done twice in a row
strlcpy(S_sfx[sfx_None].caption, "One-up", 7);
S_StartCaption(sfx_None, -1, extralifetics+1);
S_ChangeMusicInternal("_1up", false);
}
}
@ -1156,9 +1158,15 @@ void P_RestoreMusic(player_t *player)
if (player->powers[pw_super] && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOSSMUSIC))
S_ChangeMusicInternal("_super", true);
else if (player->powers[pw_invulnerability] > 1)
{
strlcpy(S_sfx[sfx_None].caption, "Invincibility", 14);
S_StartCaption(sfx_None, -1, player->powers[pw_invulnerability]);
S_ChangeMusicInternal((mariomode) ? "_minv" : "_inv", false);
}
else if (player->powers[pw_sneakers] > 1 && !player->powers[pw_super])
{
strlcpy(S_sfx[sfx_None].caption, "Speed shoes", 12);
S_StartCaption(sfx_None, -1, player->powers[pw_sneakers]);
if (mapheaderinfo[gamemap-1]->levelflags & LF_SPEEDMUSIC)
{
S_SpeedMusic(1.4f);
@ -1698,9 +1706,8 @@ void P_DoPlayerExit(player_t *player)
#define SPACESPECIAL 12
boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space
{
sector_t *sector;
sector = mo->subsector->sector;
sector_t *sector = mo->subsector->sector;
fixed_t topheight, bottomheight;
if (GETSECSPECIAL(sector->special, 1) == SPACESPECIAL)
return true;
@ -1713,11 +1720,18 @@ boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space
{
if (GETSECSPECIAL(rover->master->frontsector->special, 1) != SPACESPECIAL)
continue;
#ifdef ESLOPE
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) : *rover->topheight;
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, mo->x, mo->y) : *rover->bottomheight;
#else
topheight = *rover->topheight;
bottomheight = *rover->bottomheight;
#endif
if (mo->z > *rover->topheight)
if (mo->z + (mo->height/2) > topheight)
continue;
if (mo->z + (mo->height/2) < *rover->bottomheight)
if (mo->z + (mo->height/2) < bottomheight)
continue;
return true;
@ -1729,9 +1743,10 @@ boolean P_InSpaceSector(mobj_t *mo) // Returns true if you are in space
boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand
{
sector_t *sector;
sector_t *sector = mo->subsector->sector;
fixed_t topheight, bottomheight;
sector = mo->subsector->sector;
fixed_t flipoffset = ((mo->eflags & MFE_VERTICALFLIP) ? (mo->height/2) : 0);
if (sector->ffloors)
{
@ -1745,10 +1760,18 @@ boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand
if (!(rover->flags & FF_QUICKSAND))
continue;
if (mo->z > *rover->topheight)
#ifdef ESLOPE
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, mo->x, mo->y) : *rover->topheight;
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, mo->x, mo->y) : *rover->bottomheight;
#else
topheight = *rover->topheight;
bottomheight = *rover->bottomheight;
#endif
if (mo->z + flipoffset > topheight)
continue;
if (mo->z + (mo->height/2) < *rover->bottomheight)
if (mo->z + (mo->height/2) + flipoffset < bottomheight)
continue;
return true;
@ -2059,6 +2082,7 @@ static void P_CheckQuicksand(player_t *player)
{
ffloor_t *rover;
fixed_t sinkspeed, friction;
fixed_t topheight, bottomheight;
if (!(player->mo->subsector->sector->ffloors && player->mo->momz <= 0))
return;
@ -2070,16 +2094,38 @@ static void P_CheckQuicksand(player_t *player)
if (!(rover->flags & FF_QUICKSAND))
continue;
if (*rover->topheight >= player->mo->z && *rover->bottomheight < player->mo->z + player->mo->height)
#ifdef ESLOPE
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
#else
topheight = *rover->topheight;
bottomheight = *rover->bottomheight;
#endif
if (topheight >= player->mo->z && bottomheight < player->mo->z + player->mo->height)
{
sinkspeed = abs(rover->master->v1->x - rover->master->v2->x)>>1;
sinkspeed = FixedDiv(sinkspeed,TICRATE*FRACUNIT);
player->mo->z -= sinkspeed;
if (player->mo->eflags & MFE_VERTICALFLIP)
{
fixed_t ceilingheight = P_GetCeilingZ(player->mo, player->mo->subsector->sector, player->mo->x, player->mo->y, NULL);
if (player->mo->z <= player->mo->subsector->sector->floorheight)
player->mo->z = player->mo->subsector->sector->floorheight;
player->mo->z += sinkspeed;
if (player->mo->z + player->mo->height >= ceilingheight)
player->mo->z = ceilingheight - player->mo->height;
}
else
{
fixed_t floorheight = P_GetFloorZ(player->mo, player->mo->subsector->sector, player->mo->x, player->mo->y, NULL);
player->mo->z -= sinkspeed;
if (player->mo->z <= floorheight)
player->mo->z = floorheight;
}
friction = abs(rover->master->v1->y - rover->master->v2->y)>>6;
@ -2341,7 +2387,7 @@ static void P_DoPlayerHeadSigns(player_t *player)
// If you're "IT", show a big "IT" over your head for others to see.
if (player->pflags & PF_TAGIT)
{
if (!(player == &players[consoleplayer] || player == &players[secondarydisplayplayer] || player == &players[displayplayer])) // Don't display it on your own view.
if (!P_IsLocalPlayer(player)) // Don't display it on your own view.
{
if (!(player->mo->eflags & MFE_VERTICALFLIP))
P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->height, MT_TAG);
@ -2429,11 +2475,11 @@ static void P_DoClimbing(player_t *player)
floorclimb = true;
#ifdef ESLOPE
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
#else
bottomheight = *rover->bottomheight;
topheight = *rover->topheight;
bottomheight = *rover->bottomheight;
#endif
// Only supports rovers that are moving like an 'elevator', not just the top or bottom.
@ -2622,13 +2668,20 @@ static void P_DoClimbing(player_t *player)
// Is there a FOF directly below that we can move onto?
if (glidesector->sector->ffloors)
{
fixed_t topheight;
ffloor_t *rover;
for (rover = glidesector->sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER) || (rover->flags & FF_BUSTUP))
continue;
if (*rover->topheight > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
#ifdef ESLOPE
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
#else
topheight = *rover->topheight;
#endif
if (topheight > ceilingheight - FixedMul(16*FRACUNIT, player->mo->scale))
{
foundfof = true;
break;
@ -3006,14 +3059,12 @@ static void P_DoTeeter(player_t *player)
{
if (!(rover->flags & FF_EXISTS)) continue;
#ifdef ESLOPE
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
#else
topheight = *rover->topheight;
bottomheight = *rover->bottomheight;
#ifdef ESLOPE
if (*rover->t_slope)
topheight = P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y);
if (*rover->b_slope)
bottomheight = P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y);
#endif
if (P_CheckSolidLava(player->mo, rover))
@ -3858,7 +3909,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
mobj_t *lockon = P_LookForEnemies(player, false, true);
if (lockon)
{
if (player == &players[consoleplayer] || player == &players[secondarydisplayplayer] || player == &players[displayplayer]) // Only display it on your own view.
if (P_IsLocalPlayer(player)) // Only display it on your own view.
{
mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker
visual->target = lockon;
@ -4126,7 +4177,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
if ((player->charability == CA_HOMINGTHOK) && !player->homing && (player->pflags & PF_JUMPED) && (!(player->pflags & PF_THOKKED) || (player->charflags & SF_MULTIABILITY)) && (lockon = P_LookForEnemies(player, true, false)))
{
if (player == &players[consoleplayer] || player == &players[secondarydisplayplayer] || player == &players[displayplayer]) // Only display it on your own view.
if (P_IsLocalPlayer(player)) // Only display it on your own view.
{
mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker
visual->target = lockon;
@ -7194,7 +7245,7 @@ static void P_MovePlayer(player_t *player)
{
if ((lockon = P_LookForEnemies(player, false, false)))
{
if (player == &players[consoleplayer] || player == &players[secondarydisplayplayer] || player == &players[displayplayer]) // Only display it on your own view.
if (P_IsLocalPlayer(player)) // Only display it on your own view.
{
mobj_t *visual = P_SpawnMobj(lockon->x, lockon->y, lockon->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker
visual->target = lockon;
@ -8451,46 +8502,24 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
thiscam->angle = angle;
}
if (!objectplacing && !(twodlevel || (mo->flags2 & MF2_TWOD)) && (player->powers[pw_carry] != CR_NIGHTSMODE) && displayplayer == consoleplayer)
if ((((thiscam == &camera) && cv_analog.value) || ((thiscam != &camera) && cv_analog2.value) || demoplayback) && !objectplacing && !(twodlevel || (mo->flags2 & MF2_TWOD)) && (player->powers[pw_carry] != CR_NIGHTSMODE) && displayplayer == consoleplayer)
{
#ifdef REDSANALOG
if ((player->cmd.buttons & (BT_CAMLEFT|BT_CAMRIGHT)) == (BT_CAMLEFT|BT_CAMRIGHT)); else
#endif
if (player->cmd.buttons & BT_CAMLEFT)
if (player->cmd.buttons & BT_CAMRIGHT)
{
if (thiscam == &camera)
{
if (cv_analog.value || demoplayback)
angle -= FixedAngle(cv_cam_rotspeed.value*FRACUNIT);
else
CV_SetValue(&cv_cam_rotate, camrotate == 0 ? 358
: camrotate - 2);
}
angle -= FixedAngle(cv_cam_rotspeed.value*FRACUNIT);
else
{
if (cv_analog2.value)
angle -= FixedAngle(cv_cam2_rotspeed.value*FRACUNIT);
else
CV_SetValue(&cv_cam2_rotate, camrotate == 0 ? 358
: camrotate - 2);
}
angle -= FixedAngle(cv_cam2_rotspeed.value*FRACUNIT);
}
else if (player->cmd.buttons & BT_CAMRIGHT)
else if (player->cmd.buttons & BT_CAMLEFT)
{
if (thiscam == &camera)
{
if (cv_analog.value || demoplayback)
angle += FixedAngle(cv_cam_rotspeed.value*FRACUNIT);
else
CV_SetValue(&cv_cam_rotate, camrotate + 2);
}
angle += FixedAngle(cv_cam_rotspeed.value*FRACUNIT);
else
{
if (cv_analog2.value)
angle += FixedAngle(cv_cam2_rotspeed.value*FRACUNIT);
else
CV_SetValue(&cv_cam2_rotate, camrotate + 2);
}
angle += FixedAngle(cv_cam2_rotspeed.value*FRACUNIT);
}
}
@ -9021,13 +9050,23 @@ static void P_CalcPostImg(player_t *player)
else if (sector->ffloors)
{
ffloor_t *rover;
fixed_t topheight;
fixed_t bottomheight;
for (rover = sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS))
continue;
if (pviewheight >= *rover->topheight || pviewheight <= *rover->bottomheight)
#ifdef ESLOPE
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
#else
topheight = *rover->topheight;
bottomheight = *rover->bottomheight;
#endif
if (pviewheight >= topheight || pviewheight <= bottomheight)
continue;
if (P_FindSpecialLineFromTag(13, rover->master->frontsector->tag, -1) != -1)
@ -9039,13 +9078,23 @@ static void P_CalcPostImg(player_t *player)
if (sector->ffloors)
{
ffloor_t *rover;
fixed_t topheight;
fixed_t bottomheight;
for (rover = sector->ffloors; rover; rover = rover->next)
{
if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_SWIMMABLE) || rover->flags & FF_BLOCKPLAYER)
continue;
if (pviewheight >= *rover->topheight || pviewheight <= *rover->bottomheight)
#ifdef ESLOPE
topheight = *rover->t_slope ? P_GetZAt(*rover->t_slope, player->mo->x, player->mo->y) : *rover->topheight;
bottomheight = *rover->b_slope ? P_GetZAt(*rover->b_slope, player->mo->x, player->mo->y) : *rover->bottomheight;
#else
topheight = *rover->topheight;
bottomheight = *rover->bottomheight;
#endif
if (pviewheight >= topheight || pviewheight <= bottomheight)
continue;
*type = postimg_water;
@ -9151,8 +9200,9 @@ void P_PlayerThink(player_t *player)
if (player->panim != PA_ABILITY)
P_SetPlayerMobjState(player->mo, S_PLAY_GLIDE);
}
else if ((player->pflags & PF_JUMPED && !(player->pflags & PF_NOJUMPDAMAGE))
&& ((player->charflags & SF_NOJUMPSPIN && player->panim != PA_ROLL)
else if ((player->pflags & PF_JUMPED && !(player->pflags & PF_NOJUMPDAMAGE)
&& (player->mo->state-states != S_PLAY_FLOAT && player->mo->state-states != S_PLAY_FLOAT_RUN))
&& ((((player->charflags & (SF_NOJUMPSPIN|SF_NOJUMPDAMAGE)) == (SF_NOJUMPSPIN|SF_NOJUMPDAMAGE)) && player->panim != PA_ROLL)
|| (!(player->charflags & SF_NOJUMPSPIN) && player->panim != PA_JUMP)))
{
if (!(player->charflags & SF_NOJUMPSPIN))
@ -9276,6 +9326,7 @@ void P_PlayerThink(player_t *player)
// check water content, set stuff in mobj
P_MobjCheckWater(player->mo);
#ifndef SECTORSPECIALSAFTERTHINK
#ifdef POLYOBJECTS
if (player->onconveyor != 1 || !P_IsObjectOnGround(player->mo))
#endif
@ -9284,6 +9335,7 @@ void P_PlayerThink(player_t *player)
if (!player->spectator)
P_PlayerInSpecialSector(player);
#endif
if (player->playerstate == PST_DEAD)
{
@ -9675,6 +9727,17 @@ void P_PlayerAfterThink(player_t *player)
cmd = &player->cmd;
#ifdef SECTORSPECIALSAFTERTHINK
#ifdef POLYOBJECTS
if (player->onconveyor != 1 || !P_IsObjectOnGround(player->mo))
#endif
player->onconveyor = 0;
// check special sectors : damage & secrets
if (!player->spectator)
P_PlayerInSpecialSector(player);
#endif
if (splitscreen && player == &players[secondarydisplayplayer])
thiscam = &camera2;
else if (player == &players[displayplayer])

View File

@ -1222,6 +1222,9 @@ static void R_Subsector(size_t num)
while (count--)
{
// CONS_Debug(DBG_GAMELOGIC, "Adding normal line %d...(%d)\n", line->linedef-lines, leveltime);
#ifdef POLYOBJECTS
if (!line->polyseg) // ignore segs that belong to polyobjects
#endif
R_AddLine(line);
line++;
curline = NULL; /* cph 2001/11/18 - must clear curline now we're done with it, so stuff doesn't try using it for other things */

View File

@ -22,7 +22,7 @@
#include "w_wad.h"
#include "z_zone.h"
#include "p_setup.h" // levelflats
#include "v_video.h" // pLocalPalette
#include "v_video.h" // pMasterPalette
#include "dehacked.h"
#if defined (_WIN32) || defined (_WIN32_WCE)
@ -1174,23 +1174,24 @@ static void R_InitExtraColormaps(void)
for (cfile = clump = 0; cfile < numwadfiles; cfile++, clump = 0)
{
startnum = W_CheckNumForNamePwad("C_START", cfile, clump);
if (startnum == LUMPERROR)
if (startnum == INT16_MAX)
continue;
endnum = W_CheckNumForNamePwad("C_END", cfile, clump);
if (endnum == LUMPERROR)
if (endnum == INT16_MAX)
I_Error("R_InitExtraColormaps: C_START without C_END\n");
if (WADFILENUM(startnum) != WADFILENUM(endnum))
I_Error("R_InitExtraColormaps: C_START and C_END in different wad files!\n");
// This shouldn't be possible when you use the Pwad function, silly
//if (WADFILENUM(startnum) != WADFILENUM(endnum))
//I_Error("R_InitExtraColormaps: C_START and C_END in different wad files!\n");
if (numcolormaplumps >= maxcolormaplumps)
maxcolormaplumps *= 2;
colormaplumps = Z_Realloc(colormaplumps,
sizeof (*colormaplumps) * maxcolormaplumps, PU_STATIC, NULL);
colormaplumps[numcolormaplumps].wadfile = WADFILENUM(startnum);
colormaplumps[numcolormaplumps].firstlump = LUMPNUM(startnum+1);
colormaplumps[numcolormaplumps].wadfile = cfile;
colormaplumps[numcolormaplumps].firstlump = startnum+1;
colormaplumps[numcolormaplumps].numlumps = endnum - (startnum + 1);
numcolormaplumps++;
}
@ -1480,9 +1481,9 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3)
{
for (i = 0; i < 256; i++)
{
r = pLocalPalette[i].s.red;
g = pLocalPalette[i].s.green;
b = pLocalPalette[i].s.blue;
r = pMasterPalette[i].s.red;
g = pMasterPalette[i].s.green;
b = pMasterPalette[i].s.blue;
cbrightness = sqrt((r*r) + (g*g) + (b*b));
map[i][0] = (cbrightness * cmaskr) + (r * othermask);
@ -1623,9 +1624,9 @@ void R_CreateColormap2(char *p1, char *p2, char *p3)
{
for (i = 0; i < 256; i++)
{
r = pLocalPalette[i].s.red;
g = pLocalPalette[i].s.green;
b = pLocalPalette[i].s.blue;
r = pMasterPalette[i].s.red;
g = pMasterPalette[i].s.green;
b = pMasterPalette[i].s.blue;
cbrightness = sqrt((r*r) + (g*g) + (b*b));
map[i][0] = (cbrightness * cmaskr) + (r * othermask);
@ -1705,9 +1706,9 @@ static UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b)
for (i = 0; i < 256; i++)
{
dr = r - pLocalPalette[i].s.red;
dg = g - pLocalPalette[i].s.green;
db = b - pLocalPalette[i].s.blue;
dr = r - pMasterPalette[i].s.red;
dg = g - pMasterPalette[i].s.green;
db = b - pMasterPalette[i].s.blue;
distortion = dr*dr + dg*dg + db*db;
if (distortion < bestdistortion)
{

View File

@ -798,9 +798,7 @@ void R_SkyboxFrame(player_t *player)
viewx = viewmobj->x;
viewy = viewmobj->y;
viewz = 0;
if (viewmobj->spawnpoint)
viewz = ((fixed_t)viewmobj->spawnpoint->angle)<<FRACBITS;
viewz = viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle!
if (mapheaderinfo[gamemap-1])
{

View File

@ -2852,14 +2852,20 @@ void R_AddSkins(UINT16 wadnum)
{
STRBUFCPY(skin->realname, skin->name);
for (value = skin->realname; *value; value++)
{
if (*value == '_') *value = ' '; // turn _ into spaces.
else if (*value == '.') *value = '\x1E'; // turn . into katana dot.
}
}
if (!hudname)
{
HUDNAMEWRITE(skin->name);
strupr(skin->hudname);
for (value = skin->hudname; *value; value++)
{
if (*value == '_') *value = ' '; // turn _ into spaces.
else if (*value == '.') *value = '\x1E'; // turn . into katana dot.
}
}
}
else if (!stricmp(stoken, "realname"))
@ -2867,7 +2873,10 @@ void R_AddSkins(UINT16 wadnum)
realname = true;
STRBUFCPY(skin->realname, value);
for (value = skin->realname; *value; value++)
{
if (*value == '_') *value = ' '; // turn _ into spaces.
else if (*value == '.') *value = '\x1E'; // turn . into katana dot.
}
if (!hudname)
HUDNAMEWRITE(skin->realname);
}
@ -2876,7 +2885,10 @@ void R_AddSkins(UINT16 wadnum)
hudname = true;
HUDNAMEWRITE(value);
for (value = skin->hudname; *value; value++)
{
if (*value == '_') *value = ' '; // turn _ into spaces.
else if (*value == '.') *value = '\x1E'; // turn . into katana dot.
}
if (!realname)
STRBUFCPY(skin->realname, skin->hudname);
}

View File

@ -36,6 +36,7 @@ extern INT32 msg_id;
#include "d_main.h"
#include "r_sky.h" // skyflatnum
#include "p_local.h" // camera info
#include "fastcmp.h"
#ifdef HW3SOUND
// 3D Sound Interface
@ -81,6 +82,16 @@ static consvar_t precachesound = {"precachesound", "Off", CV_SAVE, CV_OnOff, NUL
consvar_t cv_soundvolume = {"soundvolume", "31", CV_SAVE, soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_digmusicvolume = {"digmusicvolume", "18", CV_SAVE, soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_midimusicvolume = {"midimusicvolume", "18", CV_SAVE, soundvolume_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static void Captioning_OnChange(void)
{
S_ResetCaptions();
if (cv_closedcaptioning.value)
S_StartSound(NULL, sfx_menu1);
}
consvar_t cv_closedcaptioning = {"closedcaptioning", "Off", CV_SAVE|CV_CALL, CV_OnOff, Captioning_OnChange, 0, NULL, NULL, 0, 0, NULL};
// number of channels available
#if defined (_WIN32_WCE) || defined (DC) || defined (PSP) || defined(GP2X)
consvar_t cv_numChannels = {"snd_channels", "8", CV_SAVE|CV_CALL, CV_Unsigned, SetChannelsNum, 0, NULL, NULL, 0, 0, NULL};
@ -124,23 +135,24 @@ static consvar_t surround = {"surround", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL
// percent attenuation from front to back
#define S_IFRACVOL 30
typedef struct
{
// sound information (if null, channel avail.)
sfxinfo_t *sfxinfo;
// origin of sound
const void *origin;
// handle of the sound being played
INT32 handle;
} channel_t;
// the set of channels available
static channel_t *channels = NULL;
static INT32 numofchannels = 0;
caption_t closedcaptions[NUMCAPTIONS];
void S_ResetCaptions(void)
{
UINT8 i;
for (i = 0; i < NUMCAPTIONS; i++)
{
closedcaptions[i].c = NULL;
closedcaptions[i].s = NULL;
closedcaptions[i].t = 0;
closedcaptions[i].b = 0;
}
}
//
// Internals.
//
@ -297,6 +309,8 @@ static void SetChannelsNum(void)
// Free all channels for use
for (i = 0; i < numofchannels; i++)
channels[i].sfxinfo = 0;
S_ResetCaptions();
}
@ -339,6 +353,8 @@ void S_StopSounds(void)
for (cnum = 0; cnum < numofchannels; cnum++)
if (channels[cnum].sfxinfo)
S_StopChannel(cnum);
S_ResetCaptions();
}
void S_StopSoundByID(void *origin, sfxenum_t sfx_id)
@ -387,6 +403,92 @@ void S_StopSoundByNum(sfxenum_t sfxnum)
}
}
void S_StartCaption(sfxenum_t sfx_id, INT32 cnum, UINT16 lifespan)
{
UINT8 i, set, moveup, start;
boolean same = false;
sfxinfo_t *sfx;
if (!cv_closedcaptioning.value) // no captions at all
return;
// check for bogus sound #
// I_Assert(sfx_id >= 0); -- allowing sfx_None; this shouldn't be allowed directly if S_StartCaption is ever exposed to Lua by itself
I_Assert(sfx_id < NUMSFX);
sfx = &S_sfx[sfx_id];
if (sfx->caption[0] == '/') // no caption for this one
return;
start = ((closedcaptions[0].s && (closedcaptions[0].s-S_sfx == sfx_None)) ? 1 : 0);
if (sfx_id)
{
for (i = start; i < (set = NUMCAPTIONS-1); i++)
{
same = ((sfx == closedcaptions[i].s) || (closedcaptions[i].s && fastcmp(sfx->caption, closedcaptions[i].s->caption)));
if (same)
{
set = i;
break;
}
}
}
else
{
set = 0;
same = (closedcaptions[0].s == sfx);
}
moveup = 255;
if (!same)
{
for (i = start; i < set; i++)
{
if (!(closedcaptions[i].c || closedcaptions[i].s) || (sfx->priority >= closedcaptions[i].s->priority))
{
set = i;
if (closedcaptions[i].s && (sfx->priority >= closedcaptions[i].s->priority))
moveup = i;
break;
}
}
for (i = NUMCAPTIONS-1; i > set; i--)
{
if (sfx == closedcaptions[i].s)
{
closedcaptions[i].c = NULL;
closedcaptions[i].s = NULL;
closedcaptions[i].t = 0;
closedcaptions[i].b = 0;
}
}
}
if (moveup != 255)
{
for (i = moveup; i < NUMCAPTIONS-1; i++)
{
if (!(closedcaptions[i].c || closedcaptions[i].s))
break;
}
for (; i > set; i--)
{
closedcaptions[i].c = closedcaptions[i-1].c;
closedcaptions[i].s = closedcaptions[i-1].s;
closedcaptions[i].t = closedcaptions[i-1].t;
closedcaptions[i].b = closedcaptions[i-1].b;
}
}
closedcaptions[set].c = ((cnum == -1) ? NULL : &channels[cnum]);
closedcaptions[set].s = sfx;
closedcaptions[set].t = lifespan;
closedcaptions[set].b = 2; // bob
}
void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
{
INT32 sep, pitch, priority, cnum;
@ -527,6 +629,9 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
sep = (~sep) & 255;
#endif
// Handle closed caption input.
S_StartCaption(sfx_id, cnum, MAXCAPTIONTICS);
// Assigns the handle to one of the channels in the
// mix/output buffer.
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority);
@ -577,6 +682,9 @@ dontplay:
sep = (~sep) & 255;
#endif
// Handle closed caption input.
S_StartCaption(sfx_id, cnum, MAXCAPTIONTICS);
// Assigns the handle to one of the channels in the
// mix/output buffer.
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority);
@ -598,6 +706,7 @@ void S_StartSound(const void *origin, sfxenum_t sfx_id)
// sfx_id = sfx_mario8;
// break;
case sfx_thok:
case sfx_wepfir:
sfx_id = sfx_mario7;
break;
case sfx_pop:
@ -692,6 +801,7 @@ static INT32 actualmidimusicvolume;
void S_UpdateSounds(void)
{
INT32 audible, cnum, volume, sep, pitch;
UINT8 i;
channel_t *c;
listener_t listener;
@ -719,9 +829,7 @@ void S_UpdateSounds(void)
I_UpdateMumble(NULL, listener);
#endif
// Stop cutting FMOD out. WE'RE sick of it.
I_UpdateSound();
return;
goto notinlevel;
}
if (dedicated || nosound)
@ -760,8 +868,7 @@ void S_UpdateSounds(void)
if (hws_mode != HWS_DEFAULT_MODE)
{
HW3S_UpdateSources();
I_UpdateSound();
return;
goto notinlevel;
}
#endif
@ -849,7 +956,26 @@ void S_UpdateSounds(void)
}
}
notinlevel:
I_UpdateSound();
for (i = 0; i < NUMCAPTIONS; i++) // update captions
{
if (!closedcaptions[i].s)
continue;
if (!(--closedcaptions[i].t))
{
closedcaptions[i].c = NULL;
closedcaptions[i].s = NULL;
}
else if (closedcaptions[i].c && !I_SoundIsPlaying(closedcaptions[i].c->handle))
{
closedcaptions[i].c = NULL;
if (closedcaptions[i].t > CAPTIONFADETICS)
closedcaptions[i].t = CAPTIONFADETICS;
}
}
}
void S_SetSfxVolume(INT32 volume)
@ -1305,6 +1431,12 @@ void S_StopMusic(void)
music_data = NULL;
music_name[0] = 0;
if (cv_closedcaptioning.value)
{
if (closedcaptions[0].s-S_sfx == sfx_None)
closedcaptions[0].t = CAPTIONFADETICS;
}
}
void S_SetDigMusicVolume(INT32 volume)

View File

@ -23,7 +23,7 @@
#define PICKUP_SOUND 0x8000
extern consvar_t stereoreverse;
extern consvar_t cv_soundvolume, cv_digmusicvolume, cv_midimusicvolume;
extern consvar_t cv_soundvolume, cv_closedcaptioning, cv_digmusicvolume, cv_midimusicvolume;
extern consvar_t cv_numChannels;
#ifdef SNDSERV
@ -64,6 +64,34 @@ typedef struct {
angle_t angle;
} listener_t;
typedef struct
{
// sound information (if null, channel avail.)
sfxinfo_t *sfxinfo;
// origin of sound
const void *origin;
// handle of the sound being played
INT32 handle;
} channel_t;
typedef struct {
channel_t *c;
sfxinfo_t *s;
UINT16 t;
UINT8 b;
} caption_t;
#define NUMCAPTIONS 8
#define MAXCAPTIONTICS (2*TICRATE)
#define CAPTIONFADETICS 20
extern caption_t closedcaptions[NUMCAPTIONS];
void S_StartCaption(sfxenum_t sfx_id, INT32 cnum, UINT16 lifespan);
void S_ResetCaptions(void);
// register sound vars and commands at game startup
void S_RegisterSoundStuff(void);

View File

@ -28,6 +28,9 @@
#include "d_main.h"
#include "d_clisrv.h"
#include "f_finale.h"
#include "i_sound.h" // closed captions
#include "s_sound.h" // ditto
#include "g_game.h" // ditto
#if defined (USEASM) && !defined (NORUSEASM)//&& (!defined (_MSC_VER) || (_MSC_VER <= 1200))
@ -434,3 +437,39 @@ void SCR_DisplayTicRate(void)
lasttic = ontic;
}
void SCR_ClosedCaptions(void)
{
UINT8 i;
for (i = 0; i < NUMCAPTIONS; i++)
{
INT32 flags, y;
char dot;
boolean music;
if (!closedcaptions[i].s)
continue;
if ((music = (closedcaptions[i].s-S_sfx == sfx_None)) && (closedcaptions[i].t < flashingtics) && (closedcaptions[i].t & 1))
continue;
flags = V_NOSCALESTART|V_ALLOWLOWERCASE;
y = vid.height-((i + 2)*10*vid.dupy);
dot = ' ';
if (closedcaptions[i].b)
y -= (closedcaptions[i].b--)*vid.dupy;
if (closedcaptions[i].t < CAPTIONFADETICS)
flags |= (((CAPTIONFADETICS-closedcaptions[i].t)/2)*V_10TRANS);
if (music)
dot = '\x19';
else if (closedcaptions[i].c && closedcaptions[i].c->origin)
dot = '\x1E';
V_DrawRightAlignedString(vid.width-(20*vid.dupx), y,
flags, va("%c [%s]", dot, (closedcaptions[i].s->caption[0] ? closedcaptions[i].s->caption : closedcaptions[i].s->name)));
}
}

View File

@ -180,5 +180,6 @@ FUNCMATH boolean SCR_IsAspectCorrect(INT32 width, INT32 height);
// move out to main code for consistency
void SCR_DisplayTicRate(void);
void SCR_ClosedCaptions(void);
#undef DNWH
#endif //__SCREEN_H__

View File

@ -590,70 +590,78 @@ static BOOL I_ReadyConsole(HANDLE ci)
static boolean entering_con_command = false;
static void Impl_HandleKeyboardConsoleEvent(KEY_EVENT_RECORD evt, HANDLE co)
{
event_t event;
CONSOLE_SCREEN_BUFFER_INFO CSBI;
DWORD t;
memset(&event,0x00,sizeof (event));
if (evt.bKeyDown)
{
event.type = ev_console;
entering_con_command = true;
switch (evt.wVirtualKeyCode)
{
case VK_ESCAPE:
case VK_TAB:
event.data1 = KEY_NULL;
break;
case VK_SHIFT:
event.data1 = KEY_LSHIFT;
break;
case VK_RETURN:
entering_con_command = false;
// Fall through.
default:
event.data1 = MapVirtualKey(evt.wVirtualKeyCode,2); // convert in to char
}
if (co != INVALID_HANDLE_VALUE && GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &t))
{
if (event.data1 && event.data1 != KEY_LSHIFT && event.data1 != KEY_RSHIFT)
{
#ifdef _UNICODE
WriteConsole(co, &evt.uChar.UnicodeChar, 1, &t, NULL);
#else
WriteConsole(co, &evt.uChar.AsciiChar, 1 , &t, NULL);
#endif
}
if (evt.wVirtualKeyCode == VK_BACK
&& GetConsoleScreenBufferInfo(co,&CSBI))
{
WriteConsoleOutputCharacterA(co, " ",1, CSBI.dwCursorPosition, &t);
}
}
}
else
{
event.type = ev_keyup;
switch (evt.wVirtualKeyCode)
{
case VK_SHIFT:
event.data1 = KEY_LSHIFT;
break;
default:
break;
}
}
if (event.data1) D_PostEvent(&event);
}
void I_GetConsoleEvents(void)
{
event_t ev = {0,0,0,0};
HANDLE ci = GetStdHandle(STD_INPUT_HANDLE);
HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO CSBI;
INPUT_RECORD input;
DWORD t;
while (I_ReadyConsole(ci) && ReadConsoleInput(ci, &input, 1, &t) && t)
{
memset(&ev,0x00,sizeof (ev));
switch (input.EventType)
{
case KEY_EVENT:
if (input.Event.KeyEvent.bKeyDown)
{
ev.type = ev_console;
entering_con_command = true;
switch (input.Event.KeyEvent.wVirtualKeyCode)
{
case VK_ESCAPE:
case VK_TAB:
ev.data1 = KEY_NULL;
break;
case VK_SHIFT:
ev.data1 = KEY_LSHIFT;
break;
case VK_RETURN:
entering_con_command = false;
// Fall through.
default:
ev.data1 = MapVirtualKey(input.Event.KeyEvent.wVirtualKeyCode,2); // convert in to char
}
if (co != INVALID_HANDLE_VALUE && GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &t))
{
if (ev.data1 && ev.data1 != KEY_LSHIFT && ev.data1 != KEY_RSHIFT)
{
#ifdef _UNICODE
WriteConsole(co, &input.Event.KeyEvent.uChar.UnicodeChar, 1, &t, NULL);
#else
WriteConsole(co, &input.Event.KeyEvent.uChar.AsciiChar, 1 , &t, NULL);
#endif
}
if (input.Event.KeyEvent.wVirtualKeyCode == VK_BACK
&& GetConsoleScreenBufferInfo(co,&CSBI))
{
WriteConsoleOutputCharacterA(co, " ",1, CSBI.dwCursorPosition, &t);
}
}
}
else
{
ev.type = ev_keyup;
switch (input.Event.KeyEvent.wVirtualKeyCode)
{
case VK_SHIFT:
ev.data1 = KEY_LSHIFT;
break;
default:
break;
}
}
if (ev.data1) D_PostEvent(&ev);
Impl_HandleKeyboardConsoleEvent(input.Event.KeyEvent, co);
break;
case MOUSE_EVENT:
case WINDOW_BUFFER_SIZE_EVENT:

View File

@ -181,15 +181,13 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
wasfullscreen = SDL_TRUE;
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
}
else if (wasfullscreen)
{
wasfullscreen = SDL_FALSE;
SDL_SetWindowFullscreen(window, 0);
SDL_SetWindowSize(window, width, height);
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED_DISPLAY(1), SDL_WINDOWPOS_CENTERED_DISPLAY(1));
}
else
else // windowed mode
{
if (wasfullscreen)
{
wasfullscreen = SDL_FALSE;
SDL_SetWindowFullscreen(window, 0);
}
// Reposition window only in windowed mode
SDL_SetWindowSize(window, width, height);
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED_DISPLAY(1), SDL_WINDOWPOS_CENTERED_DISPLAY(1));
@ -899,7 +897,7 @@ static inline boolean I_SkipFrame(void)
{
static boolean skip = false;
if (render_soft != rendermode)
if (rendermode != render_soft)
return false;
skip = !skip;
@ -928,10 +926,14 @@ void I_FinishUpdate(void)
if (I_SkipFrame())
return;
// draw captions if enabled
if (cv_closedcaptioning.value)
SCR_ClosedCaptions();
if (cv_ticrate.value)
SCR_DisplayTicRate();
if (render_soft == rendermode && screens[0])
if (rendermode == render_soft && screens[0])
{
SDL_Rect rect;
@ -958,7 +960,7 @@ void I_FinishUpdate(void)
}
#ifdef HWRENDER
else
else if (rendermode == render_opengl)
{
OglSdlFinishUpdate(cv_vidwait.value);
}
@ -1188,9 +1190,9 @@ INT32 VID_SetMode(INT32 modeNum)
}
Impl_SetWindowName("SRB2 "VERSIONSTRING);
SDLSetMode(windowedModes[modeNum][0], windowedModes[modeNum][1], USE_FULLSCREEN);
SDLSetMode(vid.width, vid.height, USE_FULLSCREEN);
if (render_soft == rendermode)
if (rendermode == render_soft)
{
if (bufSurface)
{
@ -1209,30 +1211,20 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
int flags = 0;
if (rendermode == render_none) // dedicated
{
return SDL_TRUE; // Monster Iestyn -- not sure if it really matters what we return here tbh
}
if (window != NULL)
{
return SDL_FALSE;
}
if (fullscreen)
{
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
}
if (borderlesswindow)
{
flags |= SDL_WINDOW_BORDERLESS;
}
#ifdef HWRENDER
if (rendermode == render_opengl)
{
flags |= SDL_WINDOW_OPENGL;
}
#endif
// Create a window
@ -1261,7 +1253,13 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
#endif
if (rendermode == render_soft)
{
renderer = SDL_CreateRenderer(window, -1, (usesdl2soft ? SDL_RENDERER_SOFTWARE : 0) | (cv_vidwait.value && !usesdl2soft ? SDL_RENDERER_PRESENTVSYNC : 0));
flags = 0; // Use this to set SDL_RENDERER_* flags now
if (usesdl2soft)
flags |= SDL_RENDERER_SOFTWARE;
else if (cv_vidwait.value)
flags |= SDL_RENDERER_PRESENTVSYNC;
renderer = SDL_CreateRenderer(window, -1, flags);
if (renderer == NULL)
{
CONS_Printf(M_GetText("Couldn't create rendering context: %s\n"), SDL_GetError());
@ -1483,7 +1481,7 @@ void I_ShutdownGraphics(void)
rendermode = render_none;
if (icoSurface) SDL_FreeSurface(icoSurface);
icoSurface = NULL;
if (render_soft == oldrendermode)
if (oldrendermode == render_soft)
{
if (vidSurface) SDL_FreeSurface(vidSurface);
vidSurface = NULL;

View File

@ -1214,7 +1214,7 @@
C01FCF4B08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.17;
CURRENT_PROJECT_VERSION = 2.1.19;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
NORMALSRB2,
@ -1226,7 +1226,7 @@
C01FCF4C08A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.17;
CURRENT_PROJECT_VERSION = 2.1.19;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_PREPROCESSOR_DEFINITIONS = (

View File

@ -71,7 +71,6 @@ INT32 oglflags = 0;
void *GLUhandle = NULL;
SDL_GLContext sdlglcontext = 0;
#ifndef STATIC_OPENGL
void *GetGLFunc(const char *proc)
{
if (strncmp(proc, "glu", 3) == 0)
@ -83,7 +82,6 @@ void *GetGLFunc(const char *proc)
}
return SDL_GL_GetProcAddress(proc);
}
#endif
boolean LoadGL(void)
{

View File

@ -1341,6 +1341,10 @@ void I_FinishUpdate(void)
if (I_SkipFrame())
return;
// draw captions if enabled
if (cv_closedcaptioning.value)
SCR_ClosedCaptions();
if (cv_ticrate.value)
SCR_DisplayTicRate();

View File

@ -1214,7 +1214,7 @@
C01FCF4B08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.17;
CURRENT_PROJECT_VERSION = 2.1.19;
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
NORMALSRB2,
@ -1226,7 +1226,7 @@
C01FCF4C08A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.17;
CURRENT_PROJECT_VERSION = 2.1.19;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_PREPROCESSOR_DEFINITIONS = (

View File

@ -32,448 +32,448 @@ sfxinfo_t S_sfx[NUMSFX] =
various flags. See soundflags_t.
*****/
// S_sfx[0] needs to be a dummy for odd reasons. (don't modify this comment)
// name, singularity, priority, pitch, volume, data, length, skinsound, usefulness, lumpnum
{"none" , false, 0, 0, -1, NULL, 0, -1, -1, LUMPERROR},
// name, singularity, priority, pitch, volume, data, length, skinsound, usefulness, lumpnum, caption
{"none" , false, 0, 0, -1, NULL, 0, -1, -1, LUMPERROR, "///////////////////////////////"}, // maximum length
// Skin Sounds
{"altdi1", false, 192, 16, -1, NULL, 0, SKSPLDET1, -1, LUMPERROR},
{"altdi2", false, 192, 16, -1, NULL, 0, SKSPLDET2, -1, LUMPERROR},
{"altdi3", false, 192, 16, -1, NULL, 0, SKSPLDET3, -1, LUMPERROR},
{"altdi4", false, 192, 16, -1, NULL, 0, SKSPLDET4, -1, LUMPERROR},
{"altow1", false, 192, 16, -1, NULL, 0, SKSPLPAN1, -1, LUMPERROR},
{"altow2", false, 192, 16, -1, NULL, 0, SKSPLPAN2, -1, LUMPERROR},
{"altow3", false, 192, 16, -1, NULL, 0, SKSPLPAN3, -1, LUMPERROR},
{"altow4", false, 192, 16, -1, NULL, 0, SKSPLPAN4, -1, LUMPERROR},
{"victr1", false, 64, 16, -1, NULL, 0, SKSPLVCT1, -1, LUMPERROR},
{"victr2", false, 64, 16, -1, NULL, 0, SKSPLVCT2, -1, LUMPERROR},
{"victr3", false, 64, 16, -1, NULL, 0, SKSPLVCT3, -1, LUMPERROR},
{"victr4", false, 64, 16, -1, NULL, 0, SKSPLVCT4, -1, LUMPERROR},
{"gasp" , false, 64, 0, -1, NULL, 0, SKSGASP, -1, LUMPERROR},
{"jump" , false, 140, 0, -1, NULL, 0, SKSJUMP, -1, LUMPERROR},
{"pudpud", false, 64, 0, -1, NULL, 0, SKSPUDPUD, -1, LUMPERROR},
{"putput", false, 64, 0, -1, NULL, 0, SKSPUTPUT, -1, LUMPERROR}, // not as high a priority
{"spin" , false, 100, 0, -1, NULL, 0, SKSSPIN, -1, LUMPERROR},
{"spndsh", false, 64, 1, -1, NULL, 0, SKSSPNDSH, -1, LUMPERROR},
{"thok" , false, 96, 0, -1, NULL, 0, SKSTHOK, -1, LUMPERROR},
{"zoom" , false, 120, 1, -1, NULL, 0, SKSZOOM, -1, LUMPERROR},
{"skid", false, 64, 32, -1, NULL, 0, SKSSKID, -1, LUMPERROR},
{"altdi1", false, 192, 16, -1, NULL, 0, SKSPLDET1, -1, LUMPERROR, "Dying"},
{"altdi2", false, 192, 16, -1, NULL, 0, SKSPLDET2, -1, LUMPERROR, "Dying"},
{"altdi3", false, 192, 16, -1, NULL, 0, SKSPLDET3, -1, LUMPERROR, "Dying"},
{"altdi4", false, 192, 16, -1, NULL, 0, SKSPLDET4, -1, LUMPERROR, "Dying"},
{"altow1", false, 192, 16, -1, NULL, 0, SKSPLPAN1, -1, LUMPERROR, "Ring loss"},
{"altow2", false, 192, 16, -1, NULL, 0, SKSPLPAN2, -1, LUMPERROR, "Ring loss"},
{"altow3", false, 192, 16, -1, NULL, 0, SKSPLPAN3, -1, LUMPERROR, "Ring loss"},
{"altow4", false, 192, 16, -1, NULL, 0, SKSPLPAN4, -1, LUMPERROR, "Ring loss"},
{"victr1", false, 64, 16, -1, NULL, 0, SKSPLVCT1, -1, LUMPERROR, "/"},
{"victr2", false, 64, 16, -1, NULL, 0, SKSPLVCT2, -1, LUMPERROR, "/"},
{"victr3", false, 64, 16, -1, NULL, 0, SKSPLVCT3, -1, LUMPERROR, "/"},
{"victr4", false, 64, 16, -1, NULL, 0, SKSPLVCT4, -1, LUMPERROR, "/"},
{"gasp" , false, 64, 0, -1, NULL, 0, SKSGASP, -1, LUMPERROR, "Bubble gasp"},
{"jump" , false, 140, 0, -1, NULL, 0, SKSJUMP, -1, LUMPERROR, "Jump"},
{"pudpud", false, 64, 0, -1, NULL, 0, SKSPUDPUD, -1, LUMPERROR, "Tired flight"},
{"putput", false, 64, 0, -1, NULL, 0, SKSPUTPUT, -1, LUMPERROR, "Flight"}, // not as high a priority
{"spin" , false, 100, 0, -1, NULL, 0, SKSSPIN, -1, LUMPERROR, "Spin"},
{"spndsh", false, 64, 1, -1, NULL, 0, SKSSPNDSH, -1, LUMPERROR, "Spindash"},
{"thok" , false, 96, 0, -1, NULL, 0, SKSTHOK, -1, LUMPERROR, "Thok"},
{"zoom" , false, 120, 1, -1, NULL, 0, SKSZOOM, -1, LUMPERROR, "Spin launch"},
{"skid", false, 64, 32, -1, NULL, 0, SKSSKID, -1, LUMPERROR, "Skid"},
// Ambience/background objects/etc
{"ambint", true, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"ambint", true, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Obnoxious disco music"},
{"alarm", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"buzz1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"buzz2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"buzz3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"buzz4", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"crumbl", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Platform Crumble Tails 03-16-2001
{"fire", false, 8, 32, -1, NULL, 0, -1, -1, LUMPERROR},
{"grind", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"laser", true, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR},
{"mswing", false, 16, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"pstart", false, 100, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"pstop", false, 100, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"steam1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Tails 06-19-2001
{"steam2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Tails 06-19-2001
{"wbreak", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"alarm", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Alarm"},
{"buzz1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Electric zap"},
{"buzz2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Electric zap"},
{"buzz3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Wacky worksurface"},
{"buzz4", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Buzz"},
{"crumbl", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Crumbling"}, // Platform Crumble Tails 03-16-2001
{"fire", false, 8, 32, -1, NULL, 0, -1, -1, LUMPERROR, "Flamethrower"},
{"grind", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Metallic grinding"},
{"laser", true, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Laser hum"},
{"mswing", false, 16, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Swinging mace"},
{"pstart", false, 100, 0, -1, NULL, 0, -1, -1, LUMPERROR, "/"},
{"pstop", false, 100, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Crusher stomp"},
{"steam1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Steam jet"}, // Tails 06-19-2001
{"steam2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Steam jet"}, // Tails 06-19-2001
{"wbreak", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Wood breaking"},
{"rainin", true, 24, 4, -1, NULL, 0, -1, -1, LUMPERROR},
{"litng1", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR},
{"litng2", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR},
{"litng3", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR},
{"litng4", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR},
{"athun1", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR},
{"athun2", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR},
{"rainin", true, 24, 4, -1, NULL, 0, -1, -1, LUMPERROR, "Rain"},
{"litng1", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Lightning"},
{"litng2", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Lightning"},
{"litng3", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Lightning"},
{"litng4", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Lightning"},
{"athun1", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Thunder"},
{"athun2", false, 16, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Thunder"},
{"amwtr1", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"amwtr2", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"amwtr3", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"amwtr4", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"amwtr5", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"amwtr6", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"amwtr7", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"amwtr8", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"bubbl1", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"bubbl2", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"bubbl3", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"bubbl4", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"bubbl5", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"floush", false, 16, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"splash", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"splish", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Splish Tails 12-08-2000
{"wdrip1", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"wdrip2", false, 8 , 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"wdrip3", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"wdrip4", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"wdrip5", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"wdrip6", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"wdrip7", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"wdrip8", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"wslap", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Water Slap Tails 12-13-2000
{"amwtr1", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"},
{"amwtr2", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"},
{"amwtr3", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"},
{"amwtr4", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"},
{"amwtr5", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"},
{"amwtr6", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"},
{"amwtr7", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"},
{"amwtr8", false, 12, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running water"},
{"bubbl1", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Glub"},
{"bubbl2", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Glub"},
{"bubbl3", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Glub"},
{"bubbl4", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Glub"},
{"bubbl5", false, 11, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Glub"},
{"floush", false, 16, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Glub"},
{"splash", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Glub"}, // labeling sfx_splash as "glub" and sfx_splish as "splash" seems wrong but isn't
{"splish", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Splash"}, // Splish Tails 12-08-2000
{"wdrip1", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drip"},
{"wdrip2", false, 8 , 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drip"},
{"wdrip3", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drip"},
{"wdrip4", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drip"},
{"wdrip5", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drip"},
{"wdrip6", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drip"},
{"wdrip7", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drip"},
{"wdrip8", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drip"},
{"wslap", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Splash"}, // Water Slap Tails 12-13-2000
{"doora1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"doorb1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"doorc1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"doorc2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"doord1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"doord2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"eleva1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"eleva2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"eleva3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"elevb1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"elevb2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"elevb3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"doora1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sliding open"},
{"doorb1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sliding open"},
{"doorc1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Wooden door opening"},
{"doorc2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Slamming shut"},
{"doord1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Creaking open"},
{"doord2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Slamming shut"},
{"eleva1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Starting elevator"},
{"eleva2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Moving elevator"},
{"eleva3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stopping elevator"},
{"elevb1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Starting elevator"},
{"elevb2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Moving elevator"},
{"elevb3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Stopping elevator"},
{"ambin2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"lavbub", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR},
{"rocks1", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"rocks2", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"rocks3", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"rocks4", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"rumbam", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"rumble", false, 64, 24, -1, NULL, 0, -1, -1, LUMPERROR},
{"ambin2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Natural vibrations"},
{"lavbub", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Bubbling lava"},
{"rocks1", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Falling rocks"},
{"rocks2", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Falling rocks"},
{"rocks3", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Falling rocks"},
{"rocks4", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Falling rocks"},
{"rumbam", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"},
{"rumble", false, 64, 24, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"},
// Game objects, etc
{"appear", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"bkpoof", false, 70, 8, -1, NULL, 0, -1, -1, LUMPERROR},
{"bnce1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Boing!
{"bnce2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Boing!
{"cannon", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR},
{"cgot" , true, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Got Emerald! Tails 09-02-2001
{"cybdth", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"deton", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"ding", false, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR},
{"dmpain", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"drown", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"fizzle", false, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR},
{"gbeep", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Grenade beep
{"gclose", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"ghit" , false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"gloop", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"gspray", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"gravch", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"itemup", true, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"jet", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"jshard", true, 167, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"lose" , false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"lvpass", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"mindig", false, 8, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"mixup", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"monton", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"pogo" , false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"pop" , false, 78, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"rail1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"rail2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"rlaunc", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"shield", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // generic GET!
{"wirlsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Whirlwind GET!
{"forcsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Force GET!
{"elemsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Elemental GET!
{"armasg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Armaggeddon GET!
{"attrsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Attract GET!
{"shldls", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // You LOSE!
{"spdpad", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"spkdth", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"spring", false, 112, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"statu1", true, 64, 2, -1, NULL, 0, -1, -1, LUMPERROR},
{"statu2", true, 64, 2, -1, NULL, 0, -1, -1, LUMPERROR},
{"strpst", true, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Starpost Sound Tails 07-04-2002
{"supert", true, 127, 2, -1, NULL, 0, -1, -1, LUMPERROR},
{"telept", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"tink" , false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"token" , true, 224, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // SS token
{"trfire", true, 60, 8, -1, NULL, 0, -1, -1, LUMPERROR},
{"trpowr", true, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR},
{"turhit", false, 40, 8, -1, NULL, 0, -1, -1, LUMPERROR},
{"wdjump", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"mswarp", false, 60, 16, -1, NULL, 0, -1, -1, LUMPERROR},
{"mspogo", false, 60, 8, -1, NULL, 0, -1, -1, LUMPERROR},
{"boingf", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"corkp", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"corkh", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"appear", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Appearing platform"},
{"bkpoof", false, 70, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Armageddon explosion"},
{"bnce1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bounce"}, // Boing!
{"bnce2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Scatter"}, // Boing!
{"cannon", false, 64, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Powerful shot"},
{"cgot" , true, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got Chaos Emerald"}, // Got Emerald! Tails 09-02-2001
{"cybdth", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Explosion"},
{"deton", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous beeping"},
{"ding", false, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Ding"},
{"dmpain", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Machine damage"},
{"drown", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drowning"},
{"fizzle", false, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Electric fizzle"},
{"gbeep", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous beeping"}, // Grenade beep
{"wepfir", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing weapon"}, // defaults to thok
{"ghit" , false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Goop splash"},
{"gloop", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Splash"},
{"gspray", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Goop sling"},
{"gravch", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Recycler"},
{"itemup", true, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sparkle"},
{"jet", false, 8, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Jet engine"},
{"jshard", true, 167, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got shard"},
{"lose" , false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Failure"},
{"lvpass", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spinning signpost"},
{"mindig", false, 8, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Tunnelling"},
{"mixup", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Teleport"},
{"monton", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Golden Monitor activated"},
{"pogo" , false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Mechanical pogo"},
{"pop" , false, 78, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pop"},
{"rail1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing rail"},
{"rail2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Crashing rail"},
{"rlaunc", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing"},
{"shield", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pity Shield"}, // generic GET!
{"wirlsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Whirlwind Shield"}, // Whirlwind GET!
{"forcsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Force Shield"}, // Force GET!
{"elemsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Elemental Shield"}, // Elemental GET!
{"armasg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Armageddon Shield"}, // Armaggeddon GET!
{"attrsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Attraction Shield"}, // Attract GET!
{"shldls", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hurt"}, // You LOSE!
{"spdpad", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Speedpad"},
{"spkdth", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spiked"},
{"spring", false, 112, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spring"},
{"statu1", true, 64, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Pushing a statue"},
{"statu2", true, 64, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Pushing a statue"},
{"strpst", true, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Starpost"}, // Starpost Sound Tails 07-04-2002
{"supert", true, 127, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Transformation"},
{"telept", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Dash"},
{"tink" , false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Tink"},
{"token" , true, 224, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got Token"}, // SS token
{"trfire", true, 60, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Laser fired"},
{"trpowr", true, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Powering up"},
{"turhit", false, 40, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Laser hit"},
{"wdjump", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Whirlwind jump"},
{"mswarp", false, 60, 16, -1, NULL, 0, -1, -1, LUMPERROR, "Spinning out"},
{"mspogo", false, 60, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Breaking through"},
{"boingf", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bouncing"},
{"corkp", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Cork fired"},
{"corkh", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Cork hit"},
// Menu, interface
{"chchng", false, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"dwnind", false, 212, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"emfind", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"flgcap", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"menu1", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"oneup", true, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"ptally", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Point tally is identical to menu for now
{"radio", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"wepchg", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Weapon switch is identical to menu for now
{"wtrdng", true, 212, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // make sure you can hear the DING DING! Tails 03-08-2000
{"zelda", false, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"chchng", false, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Score"},
{"dwnind", false, 212, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Thinking about air"},
{"emfind", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Radar beep"},
{"flgcap", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flag captured"},
{"menu1", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Menu beep"},
{"oneup", true, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR, "One-up"},
{"ptally", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Tally"}, // Point tally is identical to menu for now
{"radio", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Notification"},
{"wepchg", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Weapon change"}, // Weapon switch is identical to menu for now
{"wtrdng", true, 212, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Aquaphobia"}, // make sure you can hear the DING DING! Tails 03-08-2000
{"zelda", false, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Discovery"},
// NiGHTS
{"ideya", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"xideya", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Xmas
{"nbmper", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"nxbump", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Xmas
{"ncitem", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"nxitem", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Xmas
{"ngdone", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"nxdone", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Xmas
{"drill1", false, 48, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"drill2", false, 48, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"ncspec", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Tails 12-15-2003
{"nghurt", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"ngskid", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"hoop1", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"hoop2", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"hoop3", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"hidden", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"prloop", false, 104, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"timeup", true, 256, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"ideya", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Success"},
{"xideya", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Success"}, // Xmas
{"nbmper", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bumper"},
{"nxbump", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bumper"}, // Xmas
{"ncitem", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got special"},
{"nxitem", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got special"}, // Xmas
{"ngdone", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bonus time start"},
{"nxdone", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bonus time start"}, // Xmas
{"drill1", false, 48, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drill start"},
{"drill2", false, 48, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drill"},
{"ncspec", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Power-up"}, // Tails 12-15-2003
{"nghurt", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hurt"},
{"ngskid", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Force stop"},
{"hoop1", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hoop"},
{"hoop2", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hoop+"},
{"hoop3", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hoop++"},
{"hidden", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Discovery"},
{"prloop", false, 104, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Gust of wind"},
{"timeup", true, 256, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous Countdown"},
// Mario
{"koopfr" , true, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR},
{"mario1", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"mario2", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"mario3", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"mario4", true, 78, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"mario5", false, 78, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"mario6", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"mario7", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"mario8", false, 48, 8, -1, NULL, 0, -1, -1, LUMPERROR},
{"mario9", true, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"marioa", true, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"thwomp", true, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR},
{"koopfr" , true, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Fire"},
{"mario1", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hitting a ceiling"},
{"mario2", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Koopa shell"},
{"mario3", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Power-up"},
{"mario4", true, 78, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got coin"},
{"mario5", false, 78, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Boot"},
{"mario6", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Jump"},
{"mario7", false, 32, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Fire"},
{"mario8", false, 48, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Hurt"},
{"mario9", true, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Emerging"},
{"marioa", true, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR, "One-up"},
{"thwomp", true, 127, 8, -1, NULL, 0, -1, -1, LUMPERROR, "Thwomp"},
// Black Eggman
{"bebomb", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"bechrg", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"becrsh", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"bedeen", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"bedie1", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"bedie2", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"beeyow", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"befall", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"befire", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"beflap", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"begoop", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"begrnd", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"behurt", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"bejet1", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"belnch", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"beoutb", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"beragh", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"beshot", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"bestep", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"bestp2", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"bewar1", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"bewar2", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"bewar3", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"bewar4", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"bexpld", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"bgxpld", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"bebomb", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Big explosion"},
{"bechrg", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Powering up"},
{"becrsh", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Crash"},
{"bedeen", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Metallic crash"},
{"bedie1", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Eggman crying"},
{"bedie2", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Eggman crying"},
{"beeyow", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Failing machinery"},
{"befall", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Metallic slam"},
{"befire", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Firing goop"},
{"beflap", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Mechanical jump"},
{"begoop", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Powerful shot"},
{"begrnd", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Metallic grinding"},
{"behurt", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Eggman shocked"},
{"bejet1", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Jetpack charge"},
{"belnch", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Mechanical jump"},
{"beoutb", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Failed shot"},
{"beragh", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Eggman screaming"},
{"beshot", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Firing missile"},
{"bestep", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Mechanical stomp"},
{"bestp2", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Mechanical stomp"},
{"bewar1", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Eggman laughing"},
{"bewar2", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Eggman laughing"},
{"bewar3", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Eggman laughing"},
{"bewar4", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Eggman laughing"},
{"bexpld", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Explosion"},
{"bgxpld", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Explosion"},
// Cybrakdemon
{"beelec", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"brakrl", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"brakrx", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR},
{"beelec", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Electricity"},
{"brakrl", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Rocket launch"},
{"brakrx", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Rocket explosion"},
// S3&K sounds
{"s3k33", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k34", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k35", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k36", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k37", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k38", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k39", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k3a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k3b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k3c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k3d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k3e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k3f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k40", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k41", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k42", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k43", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k44", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k45", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k46", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k47", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k48", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k49", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k4a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k4b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k4c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k4d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k4e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k4f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k50", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k51", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k52", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k53", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k54", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, // MetalSonic shot fire
{"s3k55", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k56", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k57", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k58", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k59", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k5a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k5b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k5c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k5d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k5e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k5f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k60", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k61", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k62", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k63", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k64", false, 64, 2, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k65", false, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Blue Spheres
{"s3k66", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k67", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k68", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k69", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k6a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k6b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k6c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k6d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k6e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k6f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k70", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k71", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k72", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k73", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k74", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k75", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k76", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k77", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k78", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k79", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k7a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k7b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k7c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k7d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k7e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k7f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k80", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k81", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k82", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k83", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k84", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k85", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k86", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k87", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k88", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k89", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k8a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k8b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k8c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k8d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k8e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k8f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k90", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k91", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k92", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k93", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k94", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k95", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k96", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k97", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k98", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k99", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k9a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k9b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k9c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k9d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k9e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k9f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3ka0", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3ka1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3ka2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3ka3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3ka4", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3ka5", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3ka6", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3ka7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3ka8", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3ka9", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kaa", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kab", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kac", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kad", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kae", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kaf", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kb0", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kb1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kb2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kb3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kb4", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kb5", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kb6", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kb7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kb8", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kb9", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kba", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kbb", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kbcs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kbcl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kbds", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kbdl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kbes", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kbel", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kbfs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kbfl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kc0s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kc0l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kc1s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kc1l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kc2s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kc2l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kc3s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kc3l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kc4s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kc4l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kc5s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kc5l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kc6s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kc6l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kc7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kc8s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kc8l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kc9s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kc9l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kcas", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kcal", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kcbs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kcbl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kccs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kccl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kcds", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kcdl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kces", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kcel", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kcfs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kcfl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kd0s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kd0l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kd1s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kd1l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kd2s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kd2l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kd3s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kd3l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kd4s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kd4l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kd5s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kd5l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kd6s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kd6l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kd7s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kd7l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kd8s", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR}, // Sharp Spin (maybe use the long/L version?)
{"s3kd8l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kd9s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kd9l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kdas", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kdal", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kdbs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3kdbl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR},
{"s3k33", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sparkle"}, // stereo in original game, identical to latter
{"s3k34", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sparkle"}, // mono in original game, identical to previous
{"s3k35", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hurt"},
{"s3k36", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Skid"},
{"s3k37", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spiked"},
{"s3k38", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bubble gasp"},
{"s3k39", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Splash"},
{"s3k3a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Shield"},
{"s3k3b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drowning"},
{"s3k3c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spin"},
{"s3k3d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pop"},
{"s3k3e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flame Shield"},
{"s3k3f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bubble Shield"},
{"s3k40", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Attraction shot"},
{"s3k41", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Lightning Shield"},
{"s3k42", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Twinspin"},
{"s3k43", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flame burst"},
{"s3k44", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bubble bounce"},
{"s3k45", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Lightning zap"},
{"s3k46", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Transformation"},
{"s3k47", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Rising dust"},
{"s3k48", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Metallic clink"},
{"s3k49", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling rock"},
{"s3k4a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Grab"},
{"s3k4b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Water splash"},
{"s3k4c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Heavy landing"},
{"s3k4d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing bullet"},
{"s3k4e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bomb explosion"},
{"s3k4f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flamethrower"},
{"s3k50", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Siren"},
{"s3k51", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling bomb"},
{"s3k52", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spike"},
{"s3k53", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Powering up"},
{"s3k54", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Firing"}, // MetalSonic shot fire
{"s3k55", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Mechanical movement"},
{"s3k56", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Heavy landing"},
{"s3k57", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Splash"},
{"s3k58", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Mechanical movement"},
{"s3k59", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Crumbling"},
{"s3k5a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Aiming"},
{"s3k5b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Menu beep"},
{"s3k5c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Electric spark"},
{"s3k5d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bouncing missile"},
{"s3k5e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing laser"},
{"s3k5f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Crusher stomp"},
{"s3k60", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flying away"},
{"s3k61", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Drilling"},
{"s3k62", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Jump"},
{"s3k63", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Starpost"},
{"s3k64", false, 64, 2, -1, NULL, 0, -1, -1, LUMPERROR, "Clatter"},
{"s3k65", false, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got blue sphere"}, // Blue Spheres
{"s3k66", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Special stage clear"},
{"s3k67", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing missile"},
{"s3k68", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Unknown possibilities"},
{"s3k69", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Switch click"},
{"s3k6a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Special stage clear"},
{"s3k6b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s3k6c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Burst"},
{"s3k6d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s3k6e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Mechanical damage"},
{"s3k6f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"},
{"s3k70", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Burst"},
{"s3k71", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Basic Shield"},
{"s3k72", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Movement"},
{"s3k73", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Warp"},
{"s3k74", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Gong"},
{"s3k75", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Rising"},
{"s3k76", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Click"},
{"s3k77", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Balloon pop"},
{"s3k78", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Magnet"},
{"s3k79", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Electric charge"},
{"s3k7a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Rising from lava"},
{"s3k7b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Organic bounce"},
{"s3k7c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Magnet"},
{"s3k7d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s3k7e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Eating dirt"},
{"s3k7f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Freeze"},
{"s3k80", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ice spike burst"},
{"s3k81", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Burst"},
{"s3k82", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Burst"},
{"s3k83", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Collapsing"},
{"s3k84", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Powering up"},
{"s3k85", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Powering down"},
{"s3k86", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Alarm"},
{"s3k87", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bounce"},
{"s3k88", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Metallic squeak"},
{"s3k89", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Advanced technology"},
{"s3k8a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Boing"},
{"s3k8b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Powerful hit"},
{"s3k8c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s3k8d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s3k8e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s3k8f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Opening"},
{"s3k90", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Closing"},
{"s3k91", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Closed"},
{"s3k92", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ghost"},
{"s3k93", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Rebuilding"},
{"s3k94", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spike"},
{"s3k95", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Rising from lava"},
{"s3k96", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling object"},
{"s3k97", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Wind"},
{"s3k98", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling spike"},
{"s3k99", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bounce"},
{"s3k9a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Click"},
{"s3k9b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Crusher stomp"},
{"s3k9c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got Super Emerald"},
{"s3k9d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Targeting"},
{"s3k9e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Wham"},
{"s3k9f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Transformation"},
{"s3ka0", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Launch"},
{"s3ka1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s3ka2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Launch"},
{"s3ka3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Lift"},
{"s3ka4", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Powering up"},
{"s3ka5", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s3ka6", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Attraction fizzle"},
{"s3ka7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Countdown beep"},
{"s3ka8", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Energy"},
{"s3ka9", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Aquaphobia"},
{"s3kaa", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bumper"},
{"s3kab", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"},
{"s3kac", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got Continue"},
{"s3kad", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "GO!"},
{"s3kae", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pinball flipper"},
{"s3kaf", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "To Special Stage"},
{"s3kb0", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Score"},
{"s3kb1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spring"},
{"s3kb2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Failure"},
{"s3kb3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Warp"},
{"s3kb4", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Explosion"},
{"s3kb5", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Clink"},
{"s3kb6", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spin launch"},
{"s3kb7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Tumbler"},
{"s3kb8", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling signpost"},
{"s3kb9", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ring loss"},
{"s3kba", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flight"},
{"s3kbb", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Tired flight"},
{"s3kbcs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s3kbcl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // long version of previous
{"s3kbds", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flying fortress"},
{"s3kbdl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flying fortress"}, // ditto
{"s3kbes", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flying away"},
{"s3kbel", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flying away"}, // ditto
{"s3kbfs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Turbine"},
{"s3kbfl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Turbine"}, // ditto
{"s3kc0s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Turbine"},
{"s3kc0l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Turbine"}, // ditto
{"s3kc1s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Fan"},
{"s3kc1l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Fan"}, // ditto
{"s3kc2s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flamethrower"},
{"s3kc2l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Flamethrower"}, // ditto
{"s3kc3s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Levitation"},
{"s3kc3l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Levitation"}, // ditto
{"s3kc4s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing laser"},
{"s3kc4l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Firing laser"}, // ditto
{"s3kc5s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s3kc5l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // ditto
{"s3kc6s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Orbiting"},
{"s3kc6l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Orbiting"}, // ditto
{"s3kc7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Aiming"},
{"s3kc8s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sliding"},
{"s3kc8l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sliding"}, // ditto
{"s3kc9s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Swinging"},
{"s3kc9l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Swinging"}, // ditto
{"s3kcas", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Energy"},
{"s3kcal", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Energy"}, // ditto
{"s3kcbs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"},
{"s3kcbl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominuous rumbling"}, // ditto
{"s3kccs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Collapsing"},
{"s3kccl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Collapsing"}, // ditto
{"s3kcds", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"},
{"s3kcdl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous rumbling"}, // ditto
{"s3kces", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Wind tunnel"},
{"s3kcel", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Wind tunnel"}, // ditto
{"s3kcfs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s3kcfl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // ditto
{"s3kd0s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Rising"},
{"s3kd0l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Rising"}, // ditto
{"s3kd1s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s3kd1l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // ditto
{"s3kd2s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Turning"},
{"s3kd2l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Turning"}, // ditto
{"s3kd3s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s3kd3l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // ditto
{"s3kd4s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Engine"},
{"s3kd4l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Engine"}, // ditto
{"s3kd5s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling lava"},
{"s3kd5l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Falling lava"}, // ditto
{"s3kd6s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""},
{"s3kd6l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // ditto
{"s3kd7s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Movement"},
{"s3kd7l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Movement"}, // ditto
{"s3kd8s", false, 64, 64, -1, NULL, 0, -1, -1, LUMPERROR, "Acceleration"}, // Sharp Spin (maybe use the long/L version?)
{"s3kd8l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Acceleration"}, // ditto
{"s3kd9s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Magnetism"},
{"s3kd9l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Magnetism"}, // ditto
{"s3kdas", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Click"},
{"s3kdal", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Click"}, // ditto
{"s3kdbs", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running on water"},
{"s3kdbl", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Running on water"}, // ditto
// skin sounds free slots to add sounds at run time (Boris HACK!!!)
// initialized to NULL
@ -513,6 +513,8 @@ void S_InitRuntimeSounds (void)
S_sfx[i].skinsound = -1;
S_sfx[i].usefulness = -1;
S_sfx[i].lumpnum = LUMPERROR;
//strlcpy(S_sfx[i].caption, "", 1);
S_sfx[i].caption[0] = '\0';
}
}

View File

@ -84,6 +84,9 @@ struct sfxinfo_struct
// lump number of sfx
lumpnum_t lumpnum;
// closed caption info/wiki table bait
char caption[32];
};
// the complete set of sound effects
@ -210,7 +213,7 @@ typedef enum
sfx_drown,
sfx_fizzle,
sfx_gbeep,
sfx_gclose,
sfx_wepfir,
sfx_ghit,
sfx_gloop,
sfx_gspray,

View File

@ -131,25 +131,25 @@ hudinfo_t hudinfo[NUMHUDITEMS] =
{ 16, 42}, // HUD_RINGS
{ 220, 10}, // HUD_RINGSSPLIT
{ 112, 42}, // HUD_RINGSNUM
{ 288, 10}, // HUD_RINGSNUMSPLIT
{ 120, 42}, // HUD_RINGSNUM
{ 296, 10}, // HUD_RINGSNUMSPLIT
{ 16, 10}, // HUD_SCORE
{ 128, 10}, // HUD_SCORENUM
{ 120, 10}, // HUD_SCORENUM
{ 16, 26}, // HUD_TIME
{ 136, 10}, // HUD_TIMESPLIT
{ 88, 26}, // HUD_MINUTES
{ 128, 10}, // HUD_TIMESPLIT
{ 96, 26}, // HUD_MINUTES
{ 188, 10}, // HUD_MINUTESSPLIT
{ 88, 26}, // HUD_TIMECOLON
{ 96, 26}, // HUD_TIMECOLON
{ 188, 10}, // HUD_TIMECOLONSPLIT
{ 112, 26}, // HUD_SECONDS
{ 120, 26}, // HUD_SECONDS
{ 212, 10}, // HUD_SECONDSSPLIT
{ 112, 26}, // HUD_TIMETICCOLON
{ 136, 26}, // HUD_TICS
{ 120, 26}, // HUD_TIMETICCOLON
{ 144, 26}, // HUD_TICS
{ 112, 56}, // HUD_SS_TOTALRINGS
{ 288, 40}, // HUD_SS_TOTALRINGS_SPLIT
{ 120, 56}, // HUD_SS_TOTALRINGS
{ 296, 40}, // HUD_SS_TOTALRINGS_SPLIT
{ 110, 93}, // HUD_GETRINGS
{ 160, 93}, // HUD_GETRINGSNUM
@ -806,8 +806,15 @@ static void ST_drawFirstPersonHUD(void)
// Graue 06-18-2004: no V_NOSCALESTART, no SCX, no SCY, snap to right
if ((player->powers[pw_shield] & SH_NOSTACK & ~SH_FORCEHP) == SH_FORCE)
{
if ((player->powers[pw_shield] & SH_FORCEHP) > 0 || leveltime & 1)
p = forceshield;
UINT8 i, max = (player->powers[pw_shield] & SH_FORCEHP);
for (i = 0; i <= max; i++)
{
INT32 flags = (V_SNAPTORIGHT|V_SNAPTOTOP)|((i == max) ? V_HUDTRANS : V_HUDTRANSHALF);
if (splitscreen)
V_DrawSmallScaledPatch(312-(3*i), STRINGY(24)+(3*i), flags, forceshield);
else
V_DrawScaledPatch(304-(3*i), 24+(3*i), flags, forceshield);
}
}
else switch (player->powers[pw_shield] & SH_NOSTACK)
{
@ -1474,7 +1481,7 @@ static inline void ST_drawRaceHUD(void)
{
if (leveltime >= TICRATE && leveltime < 5*TICRATE)
{
INT32 height = (BASEVIDHEIGHT/2);
INT32 height = ((3*BASEVIDHEIGHT)>>2) - 8;
INT32 bounce = (leveltime % TICRATE);
patch_t *racenum;
switch (leveltime/TICRATE)
@ -1493,7 +1500,11 @@ static inline void ST_drawRaceHUD(void)
break;
}
if (bounce < 3)
{
height -= (2 - bounce);
if (!bounce)
S_StartSound(0, ((racenum == racego) ? sfx_s3kad : sfx_s3ka7));
}
V_DrawScaledPatch(SCX((BASEVIDWIDTH - SHORT(racenum->width))/2), (INT32)(SCY(height)), V_NOSCALESTART, racenum);
}

View File

@ -38,13 +38,39 @@ UINT8 *screens[5];
// screens[3] = fade screen start
// screens[4] = fade screen end, postimage tempoarary buffer
static CV_PossibleValue_t gamma_cons_t[] = {{0, "MIN"}, {4, "MAX"}, {0, NULL}};
static void CV_usegamma_OnChange(void);
consvar_t cv_ticrate = {"showfps", "No", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_usegamma = {"gamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_usegamma_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_allcaps = {"allcaps", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static void CV_palette_OnChange(void);
static CV_PossibleValue_t gamma_cons_t[] = {{-15, "MIN"}, {5, "MAX"}, {0, NULL}};
consvar_t cv_globalgamma = {"gamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t saturation_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}};
consvar_t cv_globalsaturation = {"saturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL};
#define huecoloursteps 4
static CV_PossibleValue_t hue_cons_t[] = {{0, "MIN"}, {(huecoloursteps*6)-1, "MAX"}, {0, NULL}};
consvar_t cv_rhue = {"rhue", "0", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_yhue = {"yhue", "4", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_ghue = {"ghue", "8", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_chue = {"chue", "12", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_bhue = {"bhue", "16", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_mhue = {"mhue", "20", CV_SAVE|CV_CALL, hue_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_rgamma = {"rgamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_ygamma = {"ygamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_ggamma = {"ggamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_cgamma = {"cgamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_bgamma = {"bgamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_mgamma = {"mgamma", "0", CV_SAVE|CV_CALL, gamma_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_rsaturation = {"rsaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_ysaturation = {"ysaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_gsaturation = {"gsaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_csaturation = {"csaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_bsaturation = {"bsaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_msaturation = {"msaturation", "10", CV_SAVE|CV_CALL, saturation_cons_t, CV_palette_OnChange, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t constextsize_cons_t[] = {
{V_NOSCALEPATCH, "Small"}, {V_SMALLSCALEPATCH, "Medium"}, {V_MEDSCALEPATCH, "Large"}, {0, "Huge"},
@ -83,8 +109,209 @@ static CV_PossibleValue_t CV_MD2[] = {{0, "Off"}, {1, "On"}, {2, "Old"}, {0, NUL
consvar_t cv_grmd2 = {"gr_md2", "Off", CV_SAVE, CV_MD2, NULL, 0, NULL, NULL, 0, 0, NULL};
#endif
const UINT8 gammatable[5][256] =
// local copy of the palette for V_GetColor()
RGBA_t *pLocalPalette = NULL;
RGBA_t *pMasterPalette = NULL;
/*
The following was an extremely helpful resource when developing my Colour Cube LUT.
http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter24.html
Please check it out if you're trying to maintain this.
toast 18/04/17
*/
float Cubepal[2][2][2][3];
// returns whether to apply cube, selectively avoiding expensive operations
static boolean InitCube(void)
{
boolean apply = false;
UINT8 q;
float working[2][2][2][3] = // the initial positions of the corners of the colour cube!
{
{
{
{0.0, 0.0, 0.0}, // black corner
{0.0, 0.0, 1.0} // blue corner
},
{
{0.0, 1.0, 0.0}, // green corner
{0.0, 1.0, 1.0} // cyan corner
}
},
{
{
{1.0, 0.0, 0.0}, // red corner
{1.0, 0.0, 1.0} // magenta corner
},
{
{1.0, 1.0, 0.0}, // yellow corner
{1.0, 1.0, 1.0} // white corner
}
}
};
float desatur[3]; // grey
float globalgammamul, globalgammaoffs;
boolean doinggamma;
#define diffcons(cv) (cv.value != atoi(cv.defaultvalue))
doinggamma = diffcons(cv_globalgamma);
#define gammascale 8
globalgammamul = (cv_globalgamma.value ? ((255 - (gammascale*abs(cv_globalgamma.value)))/255.0) : 1.0);
globalgammaoffs = ((cv_globalgamma.value > 0) ? ((gammascale*cv_globalgamma.value)/255.0) : 0.0);
desatur[0] = desatur[1] = desatur[2] = globalgammaoffs + (0.33*globalgammamul);
if (doinggamma
|| diffcons(cv_rhue)
|| diffcons(cv_yhue)
|| diffcons(cv_ghue)
|| diffcons(cv_chue)
|| diffcons(cv_bhue)
|| diffcons(cv_mhue)
|| diffcons(cv_rgamma)
|| diffcons(cv_ygamma)
|| diffcons(cv_ggamma)
|| diffcons(cv_cgamma)
|| diffcons(cv_bgamma)
|| diffcons(cv_mgamma)) // set the gamma'd/hued positions (saturation is done later)
{
float mod, tempgammamul, tempgammaoffs;
apply = true;
working[0][0][0][0] = working[0][0][0][1] = working[0][0][0][2] = globalgammaoffs;
working[1][1][1][0] = working[1][1][1][1] = working[1][1][1][2] = globalgammaoffs+globalgammamul;
#define dohue(hue, gamma, loc) \
tempgammamul = (gamma ? ((255 - (gammascale*abs(gamma)))/255.0)*globalgammamul : globalgammamul);\
tempgammaoffs = ((gamma > 0) ? ((gammascale*gamma)/255.0) + globalgammaoffs : globalgammaoffs);\
mod = ((hue % huecoloursteps)*(tempgammamul)/huecoloursteps);\
switch (hue/huecoloursteps)\
{\
case 0:\
default:\
loc[0] = tempgammaoffs+tempgammamul;\
loc[1] = tempgammaoffs+mod;\
loc[2] = tempgammaoffs;\
break;\
case 1:\
loc[0] = tempgammaoffs+tempgammamul-mod;\
loc[1] = tempgammaoffs+tempgammamul;\
loc[2] = tempgammaoffs;\
break;\
case 2:\
loc[0] = tempgammaoffs;\
loc[1] = tempgammaoffs+tempgammamul;\
loc[2] = tempgammaoffs+mod;\
break;\
case 3:\
loc[0] = tempgammaoffs;\
loc[1] = tempgammaoffs+tempgammamul-mod;\
loc[2] = tempgammaoffs+tempgammamul;\
break;\
case 4:\
loc[0] = tempgammaoffs+mod;\
loc[1] = tempgammaoffs;\
loc[2] = tempgammaoffs+tempgammamul;\
break;\
case 5:\
loc[0] = tempgammaoffs+tempgammamul;\
loc[1] = tempgammaoffs;\
loc[2] = tempgammaoffs+tempgammamul-mod;\
break;\
}
dohue(cv_rhue.value, cv_rgamma.value, working[1][0][0]);
dohue(cv_yhue.value, cv_ygamma.value, working[1][1][0]);
dohue(cv_ghue.value, cv_ggamma.value, working[0][1][0]);
dohue(cv_chue.value, cv_cgamma.value, working[0][1][1]);
dohue(cv_bhue.value, cv_bgamma.value, working[0][0][1]);
dohue(cv_mhue.value, cv_mgamma.value, working[1][0][1]);
#undef dohue
}
#define dosaturation(a, e) a = ((1 - work)*e + work*a)
#define docvsat(cv_sat, hue, gamma, r, g, b) \
if diffcons(cv_sat)\
{\
float work, mod, tempgammamul, tempgammaoffs;\
apply = true;\
work = (cv_sat.value/10.0);\
mod = ((hue % huecoloursteps)*(1.0)/huecoloursteps);\
if (hue & huecoloursteps)\
mod = 2-mod;\
else\
mod += 1;\
tempgammamul = (gamma ? ((255 - (gammascale*abs(gamma)))/255.0)*globalgammamul : globalgammamul);\
tempgammaoffs = ((gamma > 0) ? ((gammascale*gamma)/255.0) + globalgammaoffs : globalgammaoffs);\
for (q = 0; q < 3; q++)\
dosaturation(working[r][g][b][q], (tempgammaoffs+(desatur[q]*mod*tempgammamul)));\
}
docvsat(cv_rsaturation, cv_rhue.value, cv_rgamma.value, 1, 0, 0);
docvsat(cv_ysaturation, cv_yhue.value, cv_ygamma.value, 1, 1, 0);
docvsat(cv_gsaturation, cv_ghue.value, cv_ggamma.value, 0, 1, 0);
docvsat(cv_csaturation, cv_chue.value, cv_cgamma.value, 0, 1, 1);
docvsat(cv_bsaturation, cv_bhue.value, cv_bgamma.value, 0, 0, 1);
docvsat(cv_msaturation, cv_mhue.value, cv_mgamma.value, 1, 0, 1);
#undef gammascale
if diffcons(cv_globalsaturation)
{
float work = (cv_globalsaturation.value/10.0);
apply = true;
for (q = 0; q < 3; q++)
{
dosaturation(working[1][0][0][q], desatur[q]);
dosaturation(working[0][1][0][q], desatur[q]);
dosaturation(working[0][0][1][q], desatur[q]);
dosaturation(working[1][1][0][q], 2*desatur[q]);
dosaturation(working[0][1][1][q], 2*desatur[q]);
dosaturation(working[1][0][1][q], 2*desatur[q]);
}
}
#undef dosaturation
#undef diffcons
if (!apply)
return false;
#define dowork(i, j, k, l) \
if (working[i][j][k][l] > 1.0)\
working[i][j][k][l] = 1.0;\
else if (working[i][j][k][l] < 0.0)\
working[i][j][k][l] = 0.0;\
Cubepal[i][j][k][l] = working[i][j][k][l]
for (q = 0; q < 3; q++)
{
dowork(0, 0, 0, q);
dowork(1, 0, 0, q);
dowork(0, 1, 0, q);
dowork(1, 1, 0, q);
dowork(0, 0, 1, q);
dowork(1, 0, 1, q);
dowork(0, 1, 1, q);
dowork(1, 1, 1, q);
}
#undef dowork
return true;
}
/*
So it turns out that the way gamma was implemented previously, the default
colour profile of the game was messed up. Since this bad decision has been
around for a long time, and the intent is to keep the base game looking the
same, I'm not gonna be the one to remove this base modification.
toast 20/04/17
*/
const UINT8 correctiontable[256] =
{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,
33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,
@ -100,95 +327,67 @@ const UINT8 gammatable[5][256] =
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255},
{2,4,5,7,8,10,11,12,14,15,16,18,19,20,21,23,24,25,26,27,29,30,31,
32,33,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,54,55,
56,57,58,59,60,61,62,63,64,65,66,67,69,70,71,72,73,74,75,76,77,
78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,
99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,
115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,129,
130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,
146,147,148,148,149,150,151,152,153,154,155,156,157,158,159,160,
161,162,163,163,164,165,166,167,168,169,170,171,172,173,174,175,
175,176,177,178,179,180,181,182,183,184,185,186,186,187,188,189,
190,191,192,193,194,195,196,196,197,198,199,200,201,202,203,204,
205,205,206,207,208,209,210,211,212,213,214,214,215,216,217,218,
219,220,221,222,222,223,224,225,226,227,228,229,230,230,231,232,
233,234,235,236,237,237,238,239,240,241,242,243,244,245,245,246,
247,248,249,250,251,252,252,253,254,255},
{4,7,9,11,13,15,17,19,21,22,24,26,27,29,30,32,33,35,36,38,39,40,42,
43,45,46,47,48,50,51,52,54,55,56,57,59,60,61,62,63,65,66,67,68,69,
70,72,73,74,75,76,77,78,79,80,82,83,84,85,86,87,88,89,90,91,92,93,
94,95,96,97,98,100,101,102,103,104,105,106,107,108,109,110,111,112,
113,114,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,
129,130,131,132,133,133,134,135,136,137,138,139,140,141,142,143,144,
144,145,146,147,148,149,150,151,152,153,153,154,155,156,157,158,159,
160,160,161,162,163,164,165,166,166,167,168,169,170,171,172,172,173,
174,175,176,177,178,178,179,180,181,182,183,183,184,185,186,187,188,
188,189,190,191,192,193,193,194,195,196,197,197,198,199,200,201,201,
202,203,204,205,206,206,207,208,209,210,210,211,212,213,213,214,215,
216,217,217,218,219,220,221,221,222,223,224,224,225,226,227,228,228,
229,230,231,231,232,233,234,235,235,236,237,238,238,239,240,241,241,
242,243,244,244,245,246,247,247,248,249,250,251,251,252,253,254,254,
255},
{8,12,16,19,22,24,27,29,31,34,36,38,40,41,43,45,47,49,50,52,53,55,
57,58,60,61,63,64,65,67,68,70,71,72,74,75,76,77,79,80,81,82,84,85,
86,87,88,90,91,92,93,94,95,96,98,99,100,101,102,103,104,105,106,107,
108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,
125,126,127,128,129,130,131,132,133,134,135,135,136,137,138,139,140,
141,142,143,143,144,145,146,147,148,149,150,150,151,152,153,154,155,
155,156,157,158,159,160,160,161,162,163,164,165,165,166,167,168,169,
169,170,171,172,173,173,174,175,176,176,177,178,179,180,180,181,182,
183,183,184,185,186,186,187,188,189,189,190,191,192,192,193,194,195,
195,196,197,197,198,199,200,200,201,202,202,203,204,205,205,206,207,
207,208,209,210,210,211,212,212,213,214,214,215,216,216,217,218,219,
219,220,221,221,222,223,223,224,225,225,226,227,227,228,229,229,230,
231,231,232,233,233,234,235,235,236,237,237,238,238,239,240,240,241,
242,242,243,244,244,245,246,246,247,247,248,249,249,250,251,251,252,
253,253,254,254,255},
{16,23,28,32,36,39,42,45,48,50,53,55,57,60,62,64,66,68,69,71,73,75,76,
78,80,81,83,84,86,87,89,90,92,93,94,96,97,98,100,101,102,103,105,106,
107,108,109,110,112,113,114,115,116,117,118,119,120,121,122,123,124,
125,126,128,128,129,130,131,132,133,134,135,136,137,138,139,140,141,
142,143,143,144,145,146,147,148,149,150,150,151,152,153,154,155,155,
156,157,158,159,159,160,161,162,163,163,164,165,166,166,167,168,169,
169,170,171,172,172,173,174,175,175,176,177,177,178,179,180,180,181,
182,182,183,184,184,185,186,187,187,188,189,189,190,191,191,192,193,
193,194,195,195,196,196,197,198,198,199,200,200,201,202,202,203,203,
204,205,205,206,207,207,208,208,209,210,210,211,211,212,213,213,214,
214,215,216,216,217,217,218,219,219,220,220,221,221,222,223,223,224,
224,225,225,226,227,227,228,228,229,229,230,230,231,232,232,233,233,
234,234,235,235,236,236,237,237,238,239,239,240,240,241,241,242,242,
243,243,244,244,245,245,246,246,247,247,248,248,249,249,250,250,251,
251,252,252,253,254,254,255,255}
};
// local copy of the palette for V_GetColor()
RGBA_t *pLocalPalette = NULL;
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255};
// keep a copy of the palette so that we can get the RGB value for a color index at any time.
static void LoadPalette(const char *lumpname)
{
const UINT8 *usegamma = gammatable[cv_usegamma.value];
boolean cube = InitCube();
lumpnum_t lumpnum = W_GetNumForName(lumpname);
size_t i, palsize = W_LumpLength(lumpnum)/3;
UINT8 *pal;
Z_Free(pLocalPalette);
Z_Free(pMasterPalette);
pLocalPalette = Z_Malloc(sizeof (*pLocalPalette)*palsize, PU_STATIC, NULL);
pMasterPalette = Z_Malloc(sizeof (*pMasterPalette)*palsize, PU_STATIC, NULL);
pal = W_CacheLumpNum(lumpnum, PU_CACHE);
for (i = 0; i < palsize; i++)
{
pLocalPalette[i].s.red = usegamma[*pal++];
pLocalPalette[i].s.green = usegamma[*pal++];
pLocalPalette[i].s.blue = usegamma[*pal++];
pLocalPalette[i].s.alpha = 0xFF;
pMasterPalette[i].s.red = pLocalPalette[i].s.red = correctiontable[*pal++];
pMasterPalette[i].s.green = pLocalPalette[i].s.green = correctiontable[*pal++];
pMasterPalette[i].s.blue = pLocalPalette[i].s.blue = correctiontable[*pal++];
pMasterPalette[i].s.alpha = pLocalPalette[i].s.alpha = 0xFF;
// lerp of colour cubing!
if (cube)
{
float working[4][3];
float linear;
UINT8 q;
linear = (pLocalPalette[i].s.red/255.0);
#define dolerp(e1, e2) ((1 - linear)*e1 + linear*e2)
for (q = 0; q < 3; q++)
{
working[0][q] = dolerp(Cubepal[0][0][0][q], Cubepal[1][0][0][q]);
working[1][q] = dolerp(Cubepal[0][1][0][q], Cubepal[1][1][0][q]);
working[2][q] = dolerp(Cubepal[0][0][1][q], Cubepal[1][0][1][q]);
working[3][q] = dolerp(Cubepal[0][1][1][q], Cubepal[1][1][1][q]);
}
linear = (pLocalPalette[i].s.green/255.0);
for (q = 0; q < 3; q++)
{
working[0][q] = dolerp(working[0][q], working[1][q]);
working[1][q] = dolerp(working[2][q], working[3][q]);
}
linear = (pLocalPalette[i].s.blue/255.0);
for (q = 0; q < 3; q++)
{
working[0][q] = 255*dolerp(working[0][q], working[1][q]);
if (working[0][q] > 255.0)
working[0][q] = 255.0;
else if (working[0][q] < 0.0)
working[0][q] = 0.0;
}
#undef dolerp
pLocalPalette[i].s.red = (UINT8)(working[0][0]);
pLocalPalette[i].s.green = (UINT8)(working[0][1]);
pLocalPalette[i].s.blue = (UINT8)(working[0][2]);
}
}
}
@ -250,7 +449,7 @@ void V_SetPaletteLump(const char *pal)
I_SetPalette(pLocalPalette);
}
static void CV_usegamma_OnChange(void)
static void CV_palette_OnChange(void)
{
// reload palette
LoadMapPalette();
@ -649,7 +848,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
dest = desttop;
dest += FixedInt(FixedMul(topdelta<<FRACBITS,fdup))*vid.width;
for (ofs = sy<<FRACBITS; dest < deststop && (ofs>>FRACBITS) < column->length && (ofs>>FRACBITS) < h; ofs += rowfrac)
for (ofs = sy<<FRACBITS; dest < deststop && (ofs>>FRACBITS) < column->length && ((ofs>>FRACBITS) + topdelta) < h; ofs += rowfrac)
{
if (dest >= screens[scrn&V_PARAMMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = source[ofs>>FRACBITS];
@ -1784,6 +1983,9 @@ INT32 V_StringWidth(const char *string, INT32 option)
w += (charwidth ? charwidth : SHORT(hu_font[c]->width));
}
if (option & V_NOSCALESTART)
w *= vid.dupx;
return w;
}

View File

@ -27,8 +27,11 @@
extern UINT8 *screens[5];
extern const UINT8 gammatable[5][256];
extern consvar_t cv_ticrate, cv_usegamma, cv_allcaps, cv_constextsize;
extern consvar_t cv_ticrate, cv_constextsize,\
cv_globalgamma, cv_globalsaturation, \
cv_rhue, cv_yhue, cv_ghue, cv_chue, cv_bhue, cv_mhue,\
cv_rgamma, cv_ygamma, cv_ggamma, cv_cgamma, cv_bgamma, cv_mgamma, \
cv_rsaturation, cv_ysaturation, cv_gsaturation, cv_csaturation, cv_bsaturation, cv_msaturation;
// Allocates buffer screens, call before R_Init.
void V_Init(void);
@ -42,6 +45,7 @@ const char *R_GetPalname(UINT16 num);
const char *GetPalette(void);
extern RGBA_t *pLocalPalette;
extern RGBA_t *pMasterPalette;
// Retrieve the ARGB value from a palette color index
#define V_GetColor(color) (pLocalPalette[color&0xFF])

View File

@ -180,9 +180,9 @@ static LPSTR hms(UINT seconds)
hours = minutes / 60;
minutes %= 60;
if (hours > 0)
sprintf (s, "%lu:%02lu:%02lu", hours, minutes, seconds);
sprintf (s, "%lu:%02lu:%02lu", (long unsigned int)hours, (long unsigned int)minutes, (long unsigned int)seconds);
else
sprintf (s, "%2lu:%02lu", minutes, seconds);
sprintf (s, "%2lu:%02lu", (long unsigned int)minutes, (long unsigned int)seconds);
return s;
}

View File

@ -470,7 +470,7 @@ static inline BOOL tlErrorMessage(const TCHAR *err)
//
// warn user if there is one
//
printf("Error %Ts..\n", err);
printf("Error %s..\n", err);
fflush(stdout);
MessageBox(hWndMain, err, TEXT("ERROR"), MB_OK);

View File

@ -362,6 +362,10 @@ void I_FinishUpdate(void)
if (I_SkipFrame())
return;
// draw captions if enabled
if (cv_closedcaptioning.value)
SCR_ClosedCaptions();
// display a graph of ticrate
if (cv_ticrate.value)
SCR_DisplayTicRate();

View File

@ -194,6 +194,10 @@ void I_FinishUpdate(void)
if (rendermode == render_none)
return;
// draw captions if enabled
if (cv_closedcaptioning.value)
SCR_ClosedCaptions();
// display a graph of ticrate
if (cv_ticrate.value)
SCR_DisplayTicRate();

View File

@ -147,6 +147,7 @@ static boolean useinterpic;
static INT32 timer;
static INT32 intertic;
static INT32 tallydonetic = -1;
static INT32 endtic = -1;
intertype_t intertype = int_none;
@ -159,6 +160,40 @@ static void Y_CalculateMatchWinners(void);
static void Y_FollowIntermission(void);
static void Y_UnloadData(void);
static void Y_IntermissionTokenDrawer(void)
{
INT32 y;
INT32 offs = 0;
UINT32 tokencount;
INT32 lowy = BASEVIDHEIGHT - 32;
INT16 temp = SHORT(tokenicon->height)/2;
INT32 calc;
if (tallydonetic != -1)
{
offs = (intertic - tallydonetic)*2;
if (offs > 10)
offs = 8;
}
V_DrawFill(32, lowy-1, 16, 1, 31); // slot
y = (lowy + offs + 1) - (temp + (token + 1)*8);
for (tokencount = token; tokencount; tokencount--)
{
if (y >= -temp)
V_DrawSmallScaledPatch(32, y, 0, tokenicon);
y += 8;
}
y += (offs*(temp - 1)/8);
calc = (lowy - y)*2;
if (calc > 0)
V_DrawCroppedPatch(32<<FRACBITS, y<<FRACBITS, FRACUNIT/2, 0, tokenicon, 32*FRACUNIT, y<<FRACBITS, SHORT(tokenicon->width), calc);
}
//
// Y_IntermissionDrawer
//
@ -203,6 +238,9 @@ void Y_IntermissionDrawer(void)
{
INT32 bonusy;
if (gottoken) // first to be behind everything else
Y_IntermissionTokenDrawer();
// draw score
V_DrawScaledPatch(hudinfo[HUD_SCORE].x, hudinfo[HUD_SCORE].y, V_SNAPTOLEFT, sboscore);
V_DrawTallNum(hudinfo[HUD_SCORENUM].x, hudinfo[HUD_SCORENUM].y, V_SNAPTOLEFT, data.coop.score);
@ -261,6 +299,9 @@ void Y_IntermissionDrawer(void)
INT32 xoffset3 = 0; // Line 3 x offset
UINT8 drawsection = 0;
if (gottoken) // first to be behind everything else
Y_IntermissionTokenDrawer();
// draw the header
if (intertic <= TICRATE)
animatetic = 0;
@ -679,7 +720,10 @@ void Y_Ticker(void)
boolean anybonuses = false;
if (!intertic) // first time only
{
S_ChangeMusicInternal("_clear", false); // don't loop it
tallydonetic = -1;
}
if (intertic < TICRATE) // one second pause before tally begins
return;
@ -709,6 +753,7 @@ void Y_Ticker(void)
if (!anybonuses)
{
tallydonetic = intertic;
endtic = intertic + 3*TICRATE; // 3 second pause after end of tally
S_StartSound(NULL, sfx_chchng); // cha-ching!
@ -736,12 +781,11 @@ void Y_Ticker(void)
INT32 i;
UINT32 oldscore = data.spec.score;
boolean skip = false;
static INT32 tallydonetic = 0;
if (!intertic) // first time only
{
S_ChangeMusicInternal("_clear", false); // don't loop it
tallydonetic = 0;
tallydonetic = -1;
}
if (intertic < TICRATE) // one second pause before tally begins
@ -751,12 +795,12 @@ void Y_Ticker(void)
if (playeringame[i] && (players[i].cmd.buttons & BT_USE))
skip = true;
if (tallydonetic != 0)
if ((data.spec.continues & 0x80) && tallydonetic != -1)
{
if (intertic > tallydonetic)
if ((intertic - tallydonetic) > (3*TICRATE)/2)
{
endtic = intertic + 4*TICRATE; // 4 second pause after end of tally
S_StartSound(NULL, sfx_flgcap); // cha-ching!
S_StartSound(NULL, sfx_s3kac); // cha-ching!
}
return;
}
@ -772,9 +816,8 @@ void Y_Ticker(void)
if (!data.spec.bonus.points)
{
if (data.spec.continues & 0x80) // don't set endtic yet!
tallydonetic = intertic + (3*TICRATE)/2;
else // okay we're good.
tallydonetic = intertic;
if (!(data.spec.continues & 0x80)) // don't set endtic yet!
endtic = intertic + 4*TICRATE; // 4 second pause after end of tally
S_StartSound(NULL, sfx_chchng); // cha-ching!
@ -965,7 +1008,8 @@ void Y_StartIntermission(void)
}
// We couldn't display the intermission even if we wanted to.
if (dedicated) return;
// But we still need to give the players their score bonuses, dummy.
//if (dedicated) return;
// This should always exist, but just in case...
if(!mapheaderinfo[prevmap])
@ -1556,8 +1600,7 @@ static void Y_SetTimeBonus(player_t *player, y_bonus_t *bstruct)
// calculate time bonus
secs = player->realtime / TICRATE;
if (secs < 30) /* :30 */ bonus = 100000;
else if (secs < 45) /* :45 */ bonus = 50000;
if (secs < 30) /* :30 */ bonus = 50000;
else if (secs < 60) /* 1:00 */ bonus = 10000;
else if (secs < 90) /* 1:30 */ bonus = 5000;
else if (secs < 120) /* 2:00 */ bonus = 4000;
@ -1781,37 +1824,6 @@ void Y_EndIntermission(void)
usebuffer = false;
}
//
// Y_EndGame
//
// Why end the game?
// Because Y_FollowIntermission and F_EndCutscene would
// both do this exact same thing *in different ways* otherwise,
// which made it so that you could only unlock Ultimate mode
// if you had a cutscene after the final level and crap like that.
// This function simplifies it so only one place has to be updated
// when something new is added.
void Y_EndGame(void)
{
// Only do evaluation and credits in coop games.
if (gametype == GT_COOP)
{
if (nextmap == 1102-1) // end game with credits
{
F_StartCredits();
return;
}
if (nextmap == 1101-1) // end game with evaluation
{
F_StartGameEvaluation();
return;
}
}
// 1100 or competitive multiplayer, so go back to title screen.
D_StartTitle();
}
//
// Y_FollowIntermission
//
@ -1823,21 +1835,10 @@ static void Y_FollowIntermission(void)
return;
}
if (nextmap < 1100-1)
{
// normal level
G_AfterIntermission();
return;
}
// Start a custom cutscene if there is one.
if (mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking)
{
F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false);
return;
}
Y_EndGame();
// This handles whether to play a post-level cutscene, end the game,
// or simply go to the next level.
// No need to duplicate the code here!
G_AfterIntermission();
}
#define UNLOAD(x) Z_ChangeTag(x, PU_CACHE); x = NULL

View File

@ -15,7 +15,6 @@ void Y_IntermissionDrawer(void);
void Y_Ticker(void);
void Y_StartIntermission(void);
void Y_EndIntermission(void);
void Y_EndGame(void);
typedef enum
{