Merge branch 'master' into 'chat-changes'

# Conflicts:
#   src/hu_stuff.c
This commit is contained in:
toaster 2018-10-21 08:27:28 -04:00
commit 791dc079ec
65 changed files with 1902 additions and 1477 deletions

View File

@ -66,6 +66,7 @@
# Compile without 3D sound support, add 'NOHS=1' # Compile without 3D sound support, add 'NOHS=1'
# Compile with GDBstubs, add 'RDB=1' # Compile with GDBstubs, add 'RDB=1'
# Compile without PNG, add 'NOPNG=1' # Compile without PNG, add 'NOPNG=1'
# Compile without zlib, add 'NOZLIB=1'
# #
# Addon for SDL: # Addon for SDL:
# To Cross-Compile, add 'SDL_CONFIG=/usr/*/bin/sdl-config' # To Cross-Compile, add 'SDL_CONFIG=/usr/*/bin/sdl-config'
@ -119,6 +120,7 @@ include Makefile.cfg
ifdef DUMMY ifdef DUMMY
NOPNG=1 NOPNG=1
NOZLIB=1
NONET=1 NONET=1
NOHW=1 NOHW=1
NOHS=1 NOHS=1
@ -199,6 +201,7 @@ endif
ifdef NDS ifdef NDS
NOPNG=1 NOPNG=1
NOZLIB=1
NONET=1 NONET=1
#NOHW=1 #NOHW=1
NOHS=1 NOHS=1
@ -325,13 +328,6 @@ LIBS+=$(PNG_LDFLAGS)
CFLAGS+=$(PNG_CFLAGS) CFLAGS+=$(PNG_CFLAGS)
endif endif
ZLIB_PKGCONFIG?=zlib
ZLIB_CFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --cflags)
ZLIB_LDFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --libs)
LIBS+=$(ZLIB_LDFLAGS)
CFLAGS+=$(ZLIB_CFLAGS)
ifdef HAVE_LIBGME ifdef HAVE_LIBGME
OPTS+=-DHAVE_LIBGME OPTS+=-DHAVE_LIBGME
@ -343,6 +339,18 @@ LIBS+=$(LIBGME_LDFLAGS)
CFLAGS+=$(LIBGME_CFLAGS) CFLAGS+=$(LIBGME_CFLAGS)
endif endif
ifndef NOZLIB
OPTS+=-DHAVE_ZLIB
ZLIB_PKGCONFIG?=zlib
ZLIB_CFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --cflags)
ZLIB_LDFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --libs)
LIBS+=$(ZLIB_LDFLAGS)
CFLAGS+=$(ZLIB_CFLAGS)
else
NOPNG=1
endif
ifdef STATIC ifdef STATIC
LIBS:=-static $(LIBS) LIBS:=-static $(LIBS)
endif endif

View File

@ -21,13 +21,14 @@ void I_ShutdownSound(void){}
// SFX I/O // SFX I/O
// //
INT32 I_StartSound(sfxenum_t id, INT32 vol, INT32 sep, INT32 pitch, INT32 priority) INT32 I_StartSound(sfxenum_t id, INT32 vol, INT32 sep, INT32 pitch, INT32 priority, INT32 channel)
{ {
(void)id; (void)id;
(void)vol; (void)vol;
(void)sep; (void)sep;
(void)pitch; (void)pitch;
(void)priority; (void)priority;
(void)channel;
return -1; return -1;
} }

View File

@ -1600,6 +1600,31 @@ void CV_AddValue(consvar_t *var, INT32 increment)
return; return;
} }
} }
else if (var == &cv_kartspeed)
{
INT32 maxspeed = (M_SecretUnlocked(SECRET_HARDSPEED) ? 2 : 1);
// Special case for the kartspeed variable, used only directly from the menu to prevent selecting hard mode
if (increment > 0) // Going up!
{
newvalue = var->value + 1;
if (newvalue > maxspeed)
newvalue = 0;
var->value = newvalue;
var->string = var->PossibleValue[var->value].strvalue;
var->func();
return;
}
else if (increment < 0) // Going down!
{
newvalue = var->value - 1;
if (newvalue < 0)
newvalue = maxspeed;
var->value = newvalue;
var->string = var->PossibleValue[var->value].strvalue;
var->func();
return;
}
}
#ifdef PARANOIA #ifdef PARANOIA
if (currentindice == -1) if (currentindice == -1)
I_Error("CV_AddValue: current value %d not found in possible value\n", I_Error("CV_AddValue: current value %d not found in possible value\n",

View File

@ -759,6 +759,19 @@ boolean CON_Responder(event_t *ev)
if (modeattacking || metalrecording) if (modeattacking || metalrecording)
return false; return false;
if (ev->data1 >= KEY_MOUSE1) // See also: HUD_Responder
{
INT32 i;
for (i = 0; i < num_gamecontrols; i++)
{
if (gamecontrol[i][0] == ev->data1 || gamecontrol[i][1] == ev->data1)
break;
}
if (i == num_gamecontrols)
return false;
}
if (key == gamecontrol[gc_console][0] || key == gamecontrol[gc_console][1]) if (key == gamecontrol[gc_console][0] || key == gamecontrol[gc_console][1])
{ {
if (consdown) // ignore repeat if (consdown) // ignore repeat

View File

@ -1631,22 +1631,20 @@ static void CL_LoadReceivedSavegame(void)
automapactive = false; automapactive = false;
// load a base level // load a base level
playerdeadview = false;
if (P_LoadNetGame()) if (P_LoadNetGame())
{ {
CONS_Printf(M_GetText("Map is now \"%s"), G_BuildMapName(gamemap)); CON_LogMessage(va(M_GetText("Map is now \"%s"), G_BuildMapName(gamemap)));
if (strlen(mapheaderinfo[gamemap-1]->lvlttl) > 0) if (strlen(mapheaderinfo[gamemap-1]->lvlttl) > 0)
{ {
CONS_Printf(": %s", mapheaderinfo[gamemap-1]->lvlttl); CON_LogMessage(va(": %s", mapheaderinfo[gamemap-1]->lvlttl));
if (strlen(mapheaderinfo[gamemap-1]->zonttl) > 0) if (strlen(mapheaderinfo[gamemap-1]->zonttl) > 0)
CONS_Printf(" %s", mapheaderinfo[gamemap-1]->zonttl); CON_LogMessage(va(" %s", mapheaderinfo[gamemap-1]->zonttl));
else if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)) else if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
CONS_Printf(M_GetText(" ZONE")); CON_LogMessage(M_GetText(" ZONE"));
if (strlen(mapheaderinfo[gamemap-1]->actnum) > 0) if (strlen(mapheaderinfo[gamemap-1]->actnum) > 0)
CONS_Printf(" %s", mapheaderinfo[gamemap-1]->actnum); CON_LogMessage(va(" %s", mapheaderinfo[gamemap-1]->actnum));
} }
CONS_Printf("\"\n"); CON_LogMessage("\"\n");
} }
else else
{ {
@ -2377,8 +2375,11 @@ static void Command_connect(void)
CONS_Alert(CONS_ERROR, M_GetText("There is no network driver\n")); CONS_Alert(CONS_ERROR, M_GetText("There is no network driver\n"));
} }
splitscreen = 0; if (splitscreen != cv_splitplayers.value-1)
SplitScreen_OnChange(); {
splitscreen = cv_splitplayers.value-1;
SplitScreen_OnChange();
}
botingame = false; botingame = false;
botskin = 0; botskin = 0;
CL_ConnectToServer(viams); CL_ConnectToServer(viams);
@ -2419,14 +2420,15 @@ static void CL_RemovePlayer(INT32 playernum)
if (server && !demoplayback) if (server && !demoplayback)
{ {
INT32 node = playernode[playernum]; INT32 node = playernode[playernum];
//playerpernode[node] = 0; // It'd be better to remove them all at once, but ghosting happened, so continue to let CL_RemovePlayer do it one-by-one
playerpernode[node]--; playerpernode[node]--;
if (playerpernode[node] <= 0) if (playerpernode[node] <= 0)
{ {
// If a resynch was in progress, well, it no longer needs to be. // If a resynch was in progress, well, it no longer needs to be.
SV_InitResynchVars(playernode[playernum]); SV_InitResynchVars(node);
nodeingame[playernode[playernum]] = false; nodeingame[node] = false;
Net_CloseConnection(playernode[playernum]); Net_CloseConnection(node);
ResetNode(node); ResetNode(node);
} }
} }
@ -2761,11 +2763,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
} }
// Is playernum authorized to make this kick? // Is playernum authorized to make this kick?
if (playernum != serverplayer && !IsPlayerAdmin(playernum) if (playernum != serverplayer && !IsPlayerAdmin(playernum))
&& !(playerpernode[playernode[playernum]] >= 2
&& (nodetoplayer2[playernode[playernum]] == pnum
|| nodetoplayer3[playernode[playernum]] == pnum
|| nodetoplayer4[playernode[playernum]] == pnum)))
{ {
// We received a kick command from someone who isn't the // We received a kick command from someone who isn't the
// server or admin, and who isn't in splitscreen removing // server or admin, and who isn't in splitscreen removing
@ -2777,12 +2775,6 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
// "consistency failure" and kicking the offending user // "consistency failure" and kicking the offending user
// instead. // instead.
// Note: Splitscreen in netgames is broken because of
// this. Only the server has any idea of which players
// are using splitscreen on the same computer, so
// clients cannot always determine if a kick is
// legitimate.
CONS_Alert(CONS_WARNING, M_GetText("Illegal kick command received from %s for player %d\n"), player_names[playernum], pnum); CONS_Alert(CONS_WARNING, M_GetText("Illegal kick command received from %s for player %d\n"), player_names[playernum], pnum);
// In debug, print a longer message with more details. // In debug, print a longer message with more details.
@ -2892,7 +2884,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
break; break;
} }
if (pnum == consoleplayer) if (playernode[pnum] == playernode[consoleplayer])
{ {
#ifdef DUMPCONSISTENCY #ifdef DUMPCONSISTENCY
if (msg == KICK_MSG_CON_FAIL) SV_SavedGame(); if (msg == KICK_MSG_CON_FAIL) SV_SavedGame();
@ -2901,7 +2893,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
CL_Reset(); CL_Reset();
D_StartTitle(); D_StartTitle();
if (msg == KICK_MSG_CON_FAIL) if (msg == KICK_MSG_CON_FAIL)
M_StartMessage(M_GetText("Server closed connection\n(synch failure)\nPress ESC\n"), NULL, MM_NOTHING); M_StartMessage(M_GetText("Server closed connection\n(Synch failure)\nPress ESC\n"), NULL, MM_NOTHING);
#ifdef NEWPING #ifdef NEWPING
else if (msg == KICK_MSG_PING_HIGH) else if (msg == KICK_MSG_PING_HIGH)
M_StartMessage(M_GetText("Server closed connection\n(Broke ping limit)\nPress ESC\n"), NULL, MM_NOTHING); M_StartMessage(M_GetText("Server closed connection\n(Broke ping limit)\nPress ESC\n"), NULL, MM_NOTHING);
@ -2915,8 +2907,32 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
else else
M_StartMessage(M_GetText("You have been kicked by the server\n\nPress ESC\n"), NULL, MM_NOTHING); M_StartMessage(M_GetText("You have been kicked by the server\n\nPress ESC\n"), NULL, MM_NOTHING);
} }
else else if (server)
CL_RemovePlayer(pnum); {
XBOXSTATIC UINT8 buf[0];
// Sal: Because kicks (and a lot of other commands) are player-based, we can't tell which player pnum is on the node from a glance.
// When we want to remove everyone from a node, we have to get the kicked player's node, then remove everyone on that node manually so we don't miss any.
// This avoids the bugs with older SRB2 version's online splitscreen kicks, specifically ghosting.
// On top of this, it can't just be a CL_RemovePlayer call; it has to be a server-sided.
// Clients don't bother setting any nodes for anything but THE server player (even ignoring the server's extra players!), so it'll often remove everyone because they all have node -1/255, insta-desync!
// And yes. This is a netxcmd wrap for just CL_RemovePlayer! :V
#define removethisplayer(otherp) \
if (otherp >= 0) \
{ \
if (otherp != pnum) \
CONS_Printf("\x82%s\x80 left the game (Joined with \x82%s\x80)\n", player_names[otherp], player_names[pnum]); \
buf[0] = (UINT8)otherp; \
SendNetXCmd(XD_REMOVEPLAYER, &buf, 1); \
otherp = -1; \
}
removethisplayer(nodetoplayer[playernode[pnum]])
removethisplayer(nodetoplayer2[playernode[pnum]])
removethisplayer(nodetoplayer3[playernode[pnum]])
removethisplayer(nodetoplayer4[playernode[pnum]])
#undef removethisplayer
}
} }
consvar_t cv_allownewplayer = {"allowjoin", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL }; consvar_t cv_allownewplayer = {"allowjoin", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL };
@ -2939,6 +2955,7 @@ static CV_PossibleValue_t downloadspeed_cons_t[] = {{0, "MIN"}, {32, "MAX"}, {0,
consvar_t cv_downloadspeed = {"downloadspeed", "16", CV_SAVE, downloadspeed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_downloadspeed = {"downloadspeed", "16", CV_SAVE, downloadspeed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static void Got_AddPlayer(UINT8 **p, INT32 playernum); static void Got_AddPlayer(UINT8 **p, INT32 playernum);
static void Got_RemovePlayer(UINT8 **p, INT32 playernum);
// called one time at init // called one time at init
void D_ClientServerInit(void) void D_ClientServerInit(void)
@ -2966,6 +2983,7 @@ void D_ClientServerInit(void)
RegisterNetXCmd(XD_KICK, Got_KickCmd); RegisterNetXCmd(XD_KICK, Got_KickCmd);
RegisterNetXCmd(XD_ADDPLAYER, Got_AddPlayer); RegisterNetXCmd(XD_ADDPLAYER, Got_AddPlayer);
RegisterNetXCmd(XD_REMOVEPLAYER, Got_RemovePlayer);
#ifndef NONET #ifndef NONET
CV_RegisterVar(&cv_allownewplayer); CV_RegisterVar(&cv_allownewplayer);
#ifdef VANILLAJOINNEXTROUND #ifdef VANILLAJOINNEXTROUND
@ -3159,9 +3177,8 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
newplayernum %= MAXPLAYERS; newplayernum %= MAXPLAYERS;
// Clear player before joining, lest some things get set incorrectly // Clear player before joining, lest some things get set incorrectly
// HACK: don't do this for splitscreen, it relies on preset values CL_ClearPlayer(newplayernum);
if (!splitscreen && !botingame)
CL_ClearPlayer(newplayernum);
playeringame[newplayernum] = true; playeringame[newplayernum] = true;
G_AddPlayer(newplayernum); G_AddPlayer(newplayernum);
if (newplayernum+1 > doomcom->numslots) if (newplayernum+1 > doomcom->numslots)
@ -3246,6 +3263,27 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
#endif #endif
} }
// Xcmd XD_REMOVEPLAYER
static void Got_RemovePlayer(UINT8 **p, INT32 playernum)
{
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
{
// protect against hacked/buggy client
CONS_Alert(CONS_WARNING, M_GetText("Illegal remove player command received from %s\n"), player_names[playernum]);
if (server)
{
XBOXSTATIC UINT8 buf[2];
buf[0] = (UINT8)playernum;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
return;
}
CL_RemovePlayer(READUINT8(*p));
}
static boolean SV_AddWaitingPlayers(void) static boolean SV_AddWaitingPlayers(void)
{ {
INT32 node, n, newplayer = false; INT32 node, n, newplayer = false;
@ -3263,69 +3301,17 @@ static boolean SV_AddWaitingPlayers(void)
{ {
newplayer = true; newplayer = true;
if (netgame) // search for a free playernum
// !!!!!!!!! EXTREMELY SUPER MEGA GIGA ULTRA ULTIMATELY TERRIBLY IMPORTANT !!!!!!!!! // we can't use playeringame since it is not updated here
// for (; newplayernum < MAXPLAYERS; newplayernum++)
// The line just after that comment is an awful, horrible, terrible, TERRIBLE hack. {
// for (n = 0; n < MAXNETNODES; n++)
// Basically, the fix I did in order to fix the download freezes happens if (nodetoplayer[n] == newplayernum || nodetoplayer2[n] == newplayernum
// to cause situations in which a player number does not match || nodetoplayer3[n] == newplayernum || nodetoplayer4[n] == newplayernum)
// the node number associated to that player.
// That is totally normal, there is absolutely *nothing* wrong with that.
// Really. Player 7 being tied to node 29, for instance, is totally fine.
//
// HOWEVER. A few (broken) parts of the netcode do the TERRIBLE mistake
// of mixing up the concepts of node and player, resulting in
// incorrect handling of cases where a player is tied to a node that has
// a different number (which is a totally normal case, or at least should be).
// This incorrect handling can go as far as literally
// anyone from joining your server at all, forever.
//
// Given those two facts, there are two options available
// in order to let this download freeze fix be:
// 1) Fix the broken parts that assume a node is a player or similar bullshit.
// 2) Change the part this comment is located at, so that any player who joins
// is given the same number as their associated node.
//
// No need to say, 1) is by far the obvious best, whereas 2) is a terrible hack.
// Unfortunately, after trying 1), I most likely didn't manage to find all
// of those broken parts, and thus 2) has become the only safe option that remains.
//
// So I did this hack.
//
// If it isn't clear enough, in order to get rid of this ugly hack,
// you will have to fix all parts of the netcode that
// make a confusion between nodes and players.
//
// And if it STILL isn't clear enough, a node and a player
// is NOT the same thing. Never. NEVER. *NEVER*.
//
// And if someday you make the terrible mistake of
// daring to have the unforgivable idea to try thinking
// that a node might possibly be the same as a player,
// or that a player should have the same number as its node,
// be sure that I will somehow know about it and
// hunt you down tirelessly and make you regret it,
// even if you live on the other side of the world.
//
// TODO: vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// \todo >>>>>>>>>> Remove this horrible hack as soon as possible <<<<<<<<<<
// TODO: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//
// !!!!!!!!! EXTREMELY SUPER MEGA GIGA ULTRA ULTIMATELY TERRIBLY IMPORTANT !!!!!!!!!
newplayernum = node; // OMFG SAY WELCOME TO TEH NEW HACK FOR FIX FIL DOWNLOAD!!1!
else // Don't use the hack if we don't have to
// search for a free playernum
// we can't use playeringame since it is not updated here
for (; newplayernum < MAXPLAYERS; newplayernum++)
{
for (n = 0; n < MAXNETNODES; n++)
if (nodetoplayer[n] == newplayernum || nodetoplayer2[n] == newplayernum
|| nodetoplayer3[n] == newplayernum || nodetoplayer4[n] == newplayernum)
break;
if (n == MAXNETNODES)
break; break;
} if (n == MAXNETNODES)
break;
}
// should never happen since we check the playernum // should never happen since we check the playernum
// before accepting the join // before accepting the join
@ -3500,7 +3486,7 @@ static void HandleConnect(SINT8 node)
SV_SendRefuse(node, M_GetText("The server is not accepting\njoins for the moment")); SV_SendRefuse(node, M_GetText("The server is not accepting\njoins for the moment"));
else if (D_NumPlayers() >= cv_maxplayers.value) else if (D_NumPlayers() >= cv_maxplayers.value)
SV_SendRefuse(node, va(M_GetText("Maximum players reached: %d"), cv_maxplayers.value)); SV_SendRefuse(node, va(M_GetText("Maximum players reached: %d"), cv_maxplayers.value));
else if (netgame && netbuffer->u.clientcfg.localplayers > 1) // Hacked client? else if (netgame && netbuffer->u.clientcfg.localplayers > 4) // Hacked client?
SV_SendRefuse(node, M_GetText("Too many players from\nthis node.")); SV_SendRefuse(node, M_GetText("Too many players from\nthis node."));
else if (netgame && !netbuffer->u.clientcfg.localplayers) // Stealth join? else if (netgame && !netbuffer->u.clientcfg.localplayers) // Stealth join?
SV_SendRefuse(node, M_GetText("No players from\nthis node.")); SV_SendRefuse(node, M_GetText("No players from\nthis node."));
@ -3534,8 +3520,8 @@ static void HandleConnect(SINT8 node)
{ {
G_SetGamestate(backupstate); G_SetGamestate(backupstate);
/// \note Shouldn't SV_SendRefuse be called before ResetNode? /// \note Shouldn't SV_SendRefuse be called before ResetNode?
ResetNode(node);
SV_SendRefuse(node, M_GetText("Server couldn't send info, please try again")); SV_SendRefuse(node, M_GetText("Server couldn't send info, please try again"));
ResetNode(node); // Yeah, lets try it!
/// \todo fix this !!! /// \todo fix this !!!
return; // restart the while return; // restart the while
} }
@ -3988,10 +3974,10 @@ FILESTAMP
--resynch_score[node]; --resynch_score[node];
break; break;
case PT_TEXTCMD: case PT_TEXTCMD:
case PT_TEXTCMD2: // splitscreen special case PT_TEXTCMD2:
case PT_TEXTCMD3: case PT_TEXTCMD3:
case PT_TEXTCMD4: case PT_TEXTCMD4:
if (netbuffer->packettype == PT_TEXTCMD2) if (netbuffer->packettype == PT_TEXTCMD2) // splitscreen special
netconsole = nodetoplayer2[node]; netconsole = nodetoplayer2[node];
else if (netbuffer->packettype == PT_TEXTCMD3) else if (netbuffer->packettype == PT_TEXTCMD3)
netconsole = nodetoplayer3[node]; netconsole = nodetoplayer3[node];
@ -4078,9 +4064,9 @@ FILESTAMP
else else
buf[1] = KICK_MSG_PLAYER_QUIT; buf[1] = KICK_MSG_PLAYER_QUIT;
SendNetXCmd(XD_KICK, &buf, 2); SendNetXCmd(XD_KICK, &buf, 2);
nodetoplayer[node] = -1; //nodetoplayer[node] = -1;
if (nodetoplayer2[node] != -1 && nodetoplayer2[node] >= 0 /*if (nodetoplayer2[node] != -1 && nodetoplayer2[node] >= 0
&& playeringame[(UINT8)nodetoplayer2[node]]) && playeringame[(UINT8)nodetoplayer2[node]])
{ {
buf[0] = nodetoplayer2[node]; buf[0] = nodetoplayer2[node];
@ -4102,7 +4088,7 @@ FILESTAMP
buf[0] = nodetoplayer4[node]; buf[0] = nodetoplayer4[node];
SendNetXCmd(XD_KICK, &buf, 2); SendNetXCmd(XD_KICK, &buf, 2);
nodetoplayer4[node] = -1; nodetoplayer4[node] = -1;
} }*/
} }
Net_CloseConnection(node); Net_CloseConnection(node);
nodeingame[node] = false; nodeingame[node] = false;

View File

@ -810,7 +810,6 @@ void D_StartTitle(void)
maptol = 0; maptol = 0;
gameaction = ga_nothing; gameaction = ga_nothing;
playerdeadview = false;
displayplayer = consoleplayer = 0; displayplayer = consoleplayer = 0;
//demosequence = -1; //demosequence = -1;
gametype = GT_RACE; // SRB2kart gametype = GT_RACE; // SRB2kart
@ -1363,11 +1362,26 @@ void D_SRB2Main(void)
#endif #endif
} }
// Set up splitscreen players before joining!
if (!dedicated && (M_CheckParm("-splitscreen") && M_IsNextParm()))
{
UINT8 num = atoi(M_GetNextParm());
if (num >= 1 && num <= 4)
{
CV_StealthSetValue(&cv_splitplayers, num);
splitscreen = num-1;
SplitScreen_OnChange();
}
}
// init all NETWORK // init all NETWORK
CONS_Printf("D_CheckNetGame(): Checking network game status.\n"); CONS_Printf("D_CheckNetGame(): Checking network game status.\n");
if (D_CheckNetGame()) if (D_CheckNetGame())
autostart = true; autostart = true;
if (splitscreen) // Make sure multiplayer & autostart is set if you have splitscreen, even after D_CheckNetGame
multiplayer = autostart = true;
// check for a driver that wants intermission stats // check for a driver that wants intermission stats
// start the apropriate game based on parms // start the apropriate game based on parms
if (M_CheckParm("-metal")) if (M_CheckParm("-metal"))

View File

@ -34,7 +34,7 @@ void D_SRB2Loop(void) FUNCNORETURN;
// D_SRB2Main() // D_SRB2Main()
// Not a globally visible function, just included for source reference, // Not a globally visible function, just included for source reference,
// calls all startup code, parses command line options. // calls all startup code, parses command line options.
// If not overrided by user input, calls N_AdvanceDemo. // If not overrided by user input, calls D_AdvanceDemo.
// //
void D_SRB2Main(void); void D_SRB2Main(void);
@ -51,9 +51,6 @@ const char *D_Home(void);
// //
// BASE LEVEL // BASE LEVEL
// //
void D_PageTicker(void);
// pagename is lumpname of a 320x200 patch to fill the screen
void D_PageDrawer(const char *pagename);
void D_AdvanceDemo(void); void D_AdvanceDemo(void);
void D_StartTitle(void); void D_StartTitle(void);

View File

@ -49,7 +49,9 @@ doomcom_t *doomcom = NULL;
/// \brief network packet data, points inside doomcom /// \brief network packet data, points inside doomcom
doomdata_t *netbuffer = NULL; doomdata_t *netbuffer = NULL;
#ifdef DEBUGFILE
FILE *debugfile = NULL; // put some net info in a file during the game FILE *debugfile = NULL; // put some net info in a file during the game
#endif
#define MAXREBOUND 8 #define MAXREBOUND 8
static doomdata_t reboundstore[MAXREBOUND]; static doomdata_t reboundstore[MAXREBOUND];

View File

@ -375,6 +375,7 @@ consvar_t cv_kartdebugdistribution = {"kartdebugdistribution", "Off", CV_NETVAR|
consvar_t cv_kartdebughuddrop = {"kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartdebughuddrop = {"kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartdebugcheckpoint = {"kartdebugcheckpoint", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartdebugcheckpoint = {"kartdebugcheckpoint", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_kartdebugnodes = {"kartdebugnodes", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t votetime_cons_t[] = {{10, "MIN"}, {3600, "MAX"}, {0, NULL}}; static CV_PossibleValue_t votetime_cons_t[] = {{10, "MIN"}, {3600, "MAX"}, {0, NULL}};
consvar_t cv_votetime = {"votetime", "20", CV_NETVAR, votetime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_votetime = {"votetime", "20", CV_NETVAR, votetime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -419,9 +420,6 @@ consvar_t cv_numlaps = {"numlaps", "3", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_con
static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, "Map default"}, {0, NULL}}; static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, "Map default"}, {0, NULL}};
consvar_t cv_basenumlaps = {"basenumlaps", "Map default", CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_basenumlaps = {"basenumlaps", "Map default", CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL};
// log elemental hazards -- not a netvar, is local to current player
consvar_t cv_hazardlog = {"hazardlog", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_forceskin = {"forceskin", "-1", CV_NETVAR|CV_CALL|CV_CHEAT, NULL, ForceSkin_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_forceskin = {"forceskin", "-1", CV_NETVAR|CV_CALL|CV_CHEAT, NULL, ForceSkin_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_downloading = {"downloading", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_downloading = {"downloading", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_allowexitlevel = {"allowexitlevel", "No", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_allowexitlevel = {"allowexitlevel", "No", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -594,8 +592,6 @@ void D_RegisterServerCommands(void)
CV_RegisterVar(&cv_numlaps); CV_RegisterVar(&cv_numlaps);
CV_RegisterVar(&cv_basenumlaps); CV_RegisterVar(&cv_basenumlaps);
CV_RegisterVar(&cv_hazardlog);
CV_RegisterVar(&cv_autobalance); CV_RegisterVar(&cv_autobalance);
CV_RegisterVar(&cv_teamscramble); CV_RegisterVar(&cv_teamscramble);
CV_RegisterVar(&cv_scrambleonchange); CV_RegisterVar(&cv_scrambleonchange);
@ -758,6 +754,8 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_playername4); CV_RegisterVar(&cv_playername4);
CV_RegisterVar(&cv_playercolor4); CV_RegisterVar(&cv_playercolor4);
CV_RegisterVar(&cv_skin4); CV_RegisterVar(&cv_skin4);
// preferred number of players
CV_RegisterVar(&cv_splitplayers);
#ifdef SEENAMES #ifdef SEENAMES
CV_RegisterVar(&cv_seenames); CV_RegisterVar(&cv_seenames);
@ -1350,16 +1348,23 @@ static void SendNameAndColor(void)
// splitscreen // splitscreen
static void SendNameAndColor2(void) static void SendNameAndColor2(void)
{ {
INT32 secondplaya; INT32 secondplaya = -1;
XBOXSTATIC char buf[MAXPLAYERNAME+2];
char *p;
if (splitscreen < 1 && !botingame) if (splitscreen < 1 && !botingame)
return; // can happen if skin2/color2/name2 changed return; // can happen if skin2/color2/name2 changed
if (secondarydisplayplayer != consoleplayer) if (secondarydisplayplayer != consoleplayer)
secondplaya = secondarydisplayplayer; secondplaya = secondarydisplayplayer;
else // HACK else if (!netgame) // HACK
secondplaya = 1; secondplaya = 1;
if (secondplaya == -1)
return;
p = buf;
// normal player colors // normal player colors
if (G_GametypeHasTeams()) if (G_GametypeHasTeams())
{ {
@ -1436,21 +1441,53 @@ static void SendNameAndColor2(void)
return; return;
} }
// Don't actually send anything because splitscreen isn't actually allowed in netgames anyway! snac2pending++;
// Don't change name if muted
if (cv_mute.value && !(server || IsPlayerAdmin(secondarydisplayplayer)))
CV_StealthSet(&cv_playername2, player_names[secondarydisplayplayer]);
else // Cleanup name if changing it
CleanupPlayerName(secondarydisplayplayer, cv_playername2.zstring);
// Don't change skin if the server doesn't want you to.
if (!CanChangeSkin(secondarydisplayplayer))
CV_StealthSet(&cv_skin2, skins[players[secondarydisplayplayer].skin].name);
// check if player has the skin loaded (cv_skin2 may have
// the name of a skin that was available in the previous game)
cv_skin2.value = R_SkinAvailable(cv_skin2.string);
if (cv_skin2.value < 0)
{
CV_StealthSet(&cv_skin2, DEFAULTSKIN);
cv_skin2.value = 0;
}
// Finally write out the complete packet and send it off.
WRITESTRINGN(p, cv_playername2.zstring, MAXPLAYERNAME);
WRITEUINT8(p, (UINT8)cv_playercolor2.value);
WRITEUINT8(p, (UINT8)cv_skin2.value);
SendNetXCmd2(XD_NAMEANDCOLOR, buf, p - buf);
} }
static void SendNameAndColor3(void) static void SendNameAndColor3(void)
{ {
INT32 thirdplaya; INT32 thirdplaya = -1;
XBOXSTATIC char buf[MAXPLAYERNAME+2];
char *p;
if (splitscreen < 2) if (splitscreen < 2)
return; // can happen if skin3/color3/name3 changed return; // can happen if skin3/color3/name3 changed
if (thirddisplayplayer != consoleplayer) if (thirddisplayplayer != consoleplayer)
thirdplaya = thirddisplayplayer; thirdplaya = thirddisplayplayer;
else // HACK else if (!netgame) // HACK
thirdplaya = 2; thirdplaya = 2;
if (thirdplaya == -1)
return;
p = buf;
// normal player colors // normal player colors
if (G_GametypeHasTeams()) if (G_GametypeHasTeams())
{ {
@ -1519,21 +1556,53 @@ static void SendNameAndColor3(void)
return; return;
} }
// Don't actually send anything because splitscreen isn't actually allowed in netgames anyway! snac3pending++;
// Don't change name if muted
if (cv_mute.value && !(server || IsPlayerAdmin(thirddisplayplayer)))
CV_StealthSet(&cv_playername3, player_names[thirddisplayplayer]);
else // Cleanup name if changing it
CleanupPlayerName(thirddisplayplayer, cv_playername3.zstring);
// Don't change skin if the server doesn't want you to.
if (!CanChangeSkin(thirddisplayplayer))
CV_StealthSet(&cv_skin3, skins[players[thirddisplayplayer].skin].name);
// check if player has the skin loaded (cv_skin3 may have
// the name of a skin that was available in the previous game)
cv_skin3.value = R_SkinAvailable(cv_skin3.string);
if (cv_skin3.value < 0)
{
CV_StealthSet(&cv_skin3, DEFAULTSKIN);
cv_skin3.value = 0;
}
// Finally write out the complete packet and send it off.
WRITESTRINGN(p, cv_playername3.zstring, MAXPLAYERNAME);
WRITEUINT8(p, (UINT8)cv_playercolor3.value);
WRITEUINT8(p, (UINT8)cv_skin3.value);
SendNetXCmd3(XD_NAMEANDCOLOR, buf, p - buf);
} }
static void SendNameAndColor4(void) static void SendNameAndColor4(void)
{ {
INT32 fourthplaya; INT32 fourthplaya = -1;
XBOXSTATIC char buf[MAXPLAYERNAME+2];
char *p;
if (splitscreen < 3) if (splitscreen < 3)
return; // can happen if skin4/color4/name4 changed return; // can happen if skin4/color4/name4 changed
if (fourthdisplayplayer != consoleplayer) if (fourthdisplayplayer != consoleplayer)
fourthplaya = fourthdisplayplayer; fourthplaya = fourthdisplayplayer;
else // HACK else if (!netgame) // HACK
fourthplaya = 3; fourthplaya = 3;
if (fourthplaya == -1)
return;
p = buf;
// normal player colors // normal player colors
if (G_GametypeHasTeams()) if (G_GametypeHasTeams())
{ {
@ -1610,7 +1679,32 @@ static void SendNameAndColor4(void)
return; return;
} }
// Don't actually send anything because splitscreen isn't actually allowed in netgames anyway! snac4pending++;
// Don't change name if muted
if (cv_mute.value && !(server || IsPlayerAdmin(fourthdisplayplayer)))
CV_StealthSet(&cv_playername4, player_names[fourthdisplayplayer]);
else // Cleanup name if changing it
CleanupPlayerName(fourthdisplayplayer, cv_playername4.zstring);
// Don't change skin if the server doesn't want you to.
if (!CanChangeSkin(fourthdisplayplayer))
CV_StealthSet(&cv_skin4, skins[players[fourthdisplayplayer].skin].name);
// check if player has the skin loaded (cv_skin4 may have
// the name of a skin that was available in the previous game)
cv_skin4.value = R_SkinAvailable(cv_skin4.string);
if (cv_skin4.value < 0)
{
CV_StealthSet(&cv_skin4, DEFAULTSKIN);
cv_skin4.value = 0;
}
// Finally write out the complete packet and send it off.
WRITESTRINGN(p, cv_playername4.zstring, MAXPLAYERNAME);
WRITEUINT8(p, (UINT8)cv_playercolor4.value);
WRITEUINT8(p, (UINT8)cv_skin4.value);
SendNetXCmd4(XD_NAMEANDCOLOR, buf, p - buf);
} }
static void Got_NameAndColor(UINT8 **cp, INT32 playernum) static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
@ -2010,16 +2104,20 @@ void D_SetupVote(void)
void D_ModifyClientVote(SINT8 voted, UINT8 splitplayer) void D_ModifyClientVote(SINT8 voted, UINT8 splitplayer)
{ {
char buf[1]; char buf[2];
char *p = buf; char *p = buf;
UINT8 player = consoleplayer;
if (splitplayer > 0) // Don't actually send anything for splitscreen if (splitplayer == 1)
votes[splitplayer] = voted; player = secondarydisplayplayer;
else else if (splitplayer == 2)
{ player = thirddisplayplayer;
WRITESINT8(p, voted); else if (splitplayer == 3)
SendNetXCmd(XD_MODIFYVOTE, &buf, 1); player = fourthdisplayplayer;
}
WRITESINT8(p, voted);
WRITEUINT8(p, player);
SendNetXCmd(XD_MODIFYVOTE, &buf, 2);
} }
void D_PickVote(void) void D_PickVote(void)
@ -2388,11 +2486,12 @@ static void Command_Suicide(void)
}*/ }*/
// Retry is quicker. Probably should force people to use it. // Retry is quicker. Probably should force people to use it.
if (!(netgame || multiplayer)) // nope, this is srb2kart - a complete retry is overkill
/*if (!(netgame || multiplayer))
{ {
CONS_Printf(M_GetText("You can't use this in Single Player! Use \"retry\" instead.\n")); CONS_Printf(M_GetText("You can't use this in Single Player! Use \"retry\" instead.\n"));
return; return;
} }*/
SendNetXCmd(XD_SUICIDE, &buf, 4); SendNetXCmd(XD_SUICIDE, &buf, 4);
} }
@ -3217,11 +3316,11 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
CONS_Printf(M_GetText("%s switched to the %c%s%c.\n"), player_names[playernum], '\x84', M_GetText("Blue Team"), '\x80'); CONS_Printf(M_GetText("%s switched to the %c%s%c.\n"), player_names[playernum], '\x84', M_GetText("Blue Team"), '\x80');
} }
else if (NetPacket.packet.newteam == 3) else if (NetPacket.packet.newteam == 3)
/*CONS_Printf(M_GetText("%s entered the game.\n"), player_names[playernum])*/; CON_LogMessage(va(M_GetText("%s entered the game.\n"), player_names[playernum]));
else if (players[playernum].pflags & PF_WANTSTOJOIN) else if (players[playernum].pflags & PF_WANTSTOJOIN)
players[playernum].pflags &= ~PF_WANTSTOJOIN; players[playernum].pflags &= ~PF_WANTSTOJOIN;
else else
CONS_Printf(M_GetText("%s became a spectator.\n"), player_names[playernum]); CON_LogMessage(va(M_GetText("%s became a spectator.\n"), player_names[playernum]));
//reset view if you are changed, or viewing someone who was changed. //reset view if you are changed, or viewing someone who was changed.
if (playernum == consoleplayer || displayplayer == playernum) if (playernum == consoleplayer || displayplayer == playernum)
@ -3341,6 +3440,12 @@ static void Command_Login_f(void)
XBOXSTATIC UINT8 finalmd5[16]; XBOXSTATIC UINT8 finalmd5[16];
const char *pw; const char *pw;
if (!netgame)
{
CONS_Printf(M_GetText("This only works in a netgame.\n"));
return;
}
// If the server uses login, it will effectively just remove admin privileges // If the server uses login, it will effectively just remove admin privileges
// from whoever has them. This is good. // from whoever has them. This is good.
if (COM_Argc() != 2) if (COM_Argc() != 2)
@ -3455,6 +3560,12 @@ static void Command_Verify_f(void)
return; return;
} }
if (!netgame)
{
CONS_Printf(M_GetText("This only works in a netgame.\n"));
return;
}
if (COM_Argc() != 2) if (COM_Argc() != 2)
{ {
CONS_Printf(M_GetText("giveadmin <node>: give admin privileges to a node\n")); CONS_Printf(M_GetText("giveadmin <node>: give admin privileges to a node\n"));
@ -3809,7 +3920,7 @@ static void Command_Addfile(void)
WRITEMEM(buf_p, md5sum, 16); WRITEMEM(buf_p, md5sum, 16);
} }
if (IsPlayerAdmin(consoleplayer)) // Request to add file if (IsPlayerAdmin(consoleplayer) && (!server)) // Request to add file
SendNetXCmd(XD_REQADDFILE, buf, buf_p - buf); SendNetXCmd(XD_REQADDFILE, buf, buf_p - buf);
else else
SendNetXCmd(XD_ADDFILE, buf, buf_p - buf); SendNetXCmd(XD_ADDFILE, buf, buf_p - buf);
@ -4623,7 +4734,10 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum)
static void Got_ModifyVotecmd(UINT8 **cp, INT32 playernum) static void Got_ModifyVotecmd(UINT8 **cp, INT32 playernum)
{ {
SINT8 voted = READSINT8(*cp); SINT8 voted = READSINT8(*cp);
votes[playernum] = voted; UINT8 p = READUINT8(*cp);
(void)playernum;
votes[p] = voted;
} }
static void Got_PickVotecmd(UINT8 **cp, INT32 playernum) static void Got_PickVotecmd(UINT8 **cp, INT32 playernum)
@ -4780,10 +4894,10 @@ void Command_Retry_f(void)
CONS_Printf(M_GetText("You must be in a level to use this.\n")); CONS_Printf(M_GetText("You must be in a level to use this.\n"));
else if (netgame || multiplayer) else if (netgame || multiplayer)
CONS_Printf(M_GetText("This only works in single player.\n")); CONS_Printf(M_GetText("This only works in single player.\n"));
else if (!&players[consoleplayer] || players[consoleplayer].lives <= 1) /*else if (!&players[consoleplayer] || players[consoleplayer].lives <= 1)
CONS_Printf(M_GetText("You can't retry without any lives remaining!\n")); CONS_Printf(M_GetText("You can't retry without any lives remaining!\n"));
else if (G_IsSpecialStage(gamemap)) else if (G_IsSpecialStage(gamemap))
CONS_Printf(M_GetText("You can't retry special stages!\n")); CONS_Printf(M_GetText("You can't retry special stages!\n"));*/
else else
{ {
M_ClearMenus(true); M_ClearMenus(true);
@ -5237,6 +5351,13 @@ static void KartFrantic_OnChange(void)
static void KartSpeed_OnChange(void) static void KartSpeed_OnChange(void)
{ {
if (!M_SecretUnlocked(SECRET_HARDSPEED) && cv_kartspeed.value == 2)
{
CONS_Printf(M_GetText("You haven't earned this yet.\n"));
CV_StealthSetValue(&cv_kartspeed, 1);
return;
}
if (G_RaceGametype()) if (G_RaceGametype())
{ {
if ((UINT8)cv_kartspeed.value != gamespeed && gamestate == GS_LEVEL && leveltime > starttime) if ((UINT8)cv_kartspeed.value != gamespeed && gamestate == GS_LEVEL && leveltime > starttime)

View File

@ -81,8 +81,6 @@ extern consvar_t cv_basenumlaps;
extern UINT32 timelimitintics; extern UINT32 timelimitintics;
extern consvar_t cv_allowexitlevel; extern consvar_t cv_allowexitlevel;
extern consvar_t cv_hazardlog;
extern consvar_t cv_autobalance; extern consvar_t cv_autobalance;
extern consvar_t cv_teamscramble; extern consvar_t cv_teamscramble;
extern consvar_t cv_scrambleonchange; extern consvar_t cv_scrambleonchange;
@ -134,7 +132,7 @@ extern consvar_t cv_karteliminatelast;
extern consvar_t cv_votetime; extern consvar_t cv_votetime;
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugshrink, cv_kartdebugdistribution, cv_kartdebughuddrop; extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugshrink, cv_kartdebugdistribution, cv_kartdebughuddrop;
extern consvar_t cv_kartdebugcheckpoint; extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes;
extern consvar_t cv_itemfinder; extern consvar_t cv_itemfinder;
@ -197,9 +195,10 @@ typedef enum
XD_SETUPVOTE, // 22 XD_SETUPVOTE, // 22
XD_MODIFYVOTE, // 23 XD_MODIFYVOTE, // 23
XD_PICKVOTE, // 24 XD_PICKVOTE, // 24
XD_REMOVEPLAYER,// 25
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
XD_LUACMD, // 25 XD_LUACMD, // 26
XD_LUAVAR, // 26 XD_LUAVAR, // 27
#endif #endif
MAXNETXCMD MAXNETXCMD
} netxcmd_t; } netxcmd_t;

View File

@ -2430,6 +2430,8 @@ static void readunlockable(MYFILE *f, INT32 num)
unlockables[num].type = SECRET_ENCORE; unlockables[num].type = SECRET_ENCORE;
else if (fastcmp(word2, "HELLATTACK")) else if (fastcmp(word2, "HELLATTACK"))
unlockables[num].type = SECRET_HELLATTACK; unlockables[num].type = SECRET_HELLATTACK;
else if (fastcmp(word2, "HARDSPEED"))
unlockables[num].type = SECRET_HARDSPEED;
else else
unlockables[num].type = (INT16)i; unlockables[num].type = (INT16)i;
} }
@ -6311,6 +6313,12 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_WIPEOUTTRAIL4", "S_WIPEOUTTRAIL4",
"S_WIPEOUTTRAIL5", "S_WIPEOUTTRAIL5",
// Rocket sneaker
"S_ROCKETSNEAKER_L",
"S_ROCKETSNEAKER_R",
"S_ROCKETSNEAKER_LVIBRATE",
"S_ROCKETSNEAKER_RVIBRATE",
//{ Eggman Monitor //{ Eggman Monitor
"S_FAKEITEM1", "S_FAKEITEM1",
"S_FAKEITEM2", "S_FAKEITEM2",
@ -7294,6 +7302,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_DRIFTSPARK", "MT_DRIFTSPARK",
"MT_DRIFTDUST", "MT_DRIFTDUST",
"MT_ROCKETSNEAKER", // Rocket sneakers
"MT_FAKESHIELD", "MT_FAKESHIELD",
"MT_FAKEITEM", "MT_FAKEITEM",
@ -7305,7 +7315,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_JAWZ", // Jawz stuff "MT_JAWZ", // Jawz stuff
"MT_JAWZ_DUD", "MT_JAWZ_DUD",
"MT_JAWZ_SHIELD", "MT_JAWZ_SHIELD",
"MT_PLAYERRETICULE", // Jawz reticule "MT_PLAYERRETICULE", // Jawz reticule

View File

@ -165,9 +165,11 @@ INT32 I_StartSound ( sfxenum_t id,
INT32 vol, INT32 vol,
INT32 sep, INT32 sep,
INT32 pitch, INT32 pitch,
INT32 priority ) INT32 priority,
INT32 channel)
{ {
int voice; int voice;
(void)channel;
if (nosound) if (nosound)
return 0; return 0;

View File

@ -461,6 +461,7 @@ extern tic_t indirectitemcooldown;
extern tic_t spbincoming; extern tic_t spbincoming;
extern UINT8 spbplayer; extern UINT8 spbplayer;
extern tic_t mapreset; extern tic_t mapreset;
extern UINT8 nospectategrief;
extern boolean legitimateexit; extern boolean legitimateexit;
extern boolean comebackshowninfo; extern boolean comebackshowninfo;
@ -497,19 +498,17 @@ extern mapthing_t *redctfstarts[MAXPLAYERS]; // CTF
#if defined (macintosh) #if defined (macintosh)
#define DEBFILE(msg) I_OutputMsg(msg) #define DEBFILE(msg) I_OutputMsg(msg)
extern FILE *debugfile;
#else #else
#define DEBUGFILE #define DEBUGFILE
#ifdef DEBUGFILE #ifdef DEBUGFILE
#define DEBFILE(msg) { if (debugfile) { fputs(msg, debugfile); fflush(debugfile); } } #define DEBFILE(msg) { if (debugfile) { fputs(msg, debugfile); fflush(debugfile); } }
extern FILE *debugfile;
#else #else
#define DEBFILE(msg) {} #define DEBFILE(msg) {}
extern FILE *debugfile;
#endif #endif
#endif #endif
#ifdef DEBUGFILE #ifdef DEBUGFILE
extern FILE *debugfile;
extern INT32 debugload; extern INT32 debugload;
#endif #endif

View File

@ -23,13 +23,14 @@ void I_UpdateSound(void){};
// SFX I/O // SFX I/O
// //
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority) INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
{ {
(void)id; (void)id;
(void)vol; (void)vol;
(void)sep; (void)sep;
(void)pitch; (void)pitch;
(void)priority; (void)priority;
(void)channel;
return -1; return -1;
} }

View File

@ -276,7 +276,6 @@ void F_StartIntro(void)
G_SetGamestate(GS_INTRO); G_SetGamestate(GS_INTRO);
gameaction = ga_nothing; gameaction = ga_nothing;
playerdeadview = false;
paused = false; paused = false;
CON_ToggleOff(); CON_ToggleOff();
CON_ClearHUD(); CON_ClearHUD();
@ -579,7 +578,6 @@ void F_StartCredits(void)
} }
gameaction = ga_nothing; gameaction = ga_nothing;
playerdeadview = false;
paused = false; paused = false;
CON_ToggleOff(); CON_ToggleOff();
CON_ClearHUD(); CON_ClearHUD();
@ -741,7 +739,6 @@ void F_StartGameEvaluation(void)
G_SaveGame((UINT32)cursaveslot); G_SaveGame((UINT32)cursaveslot);
gameaction = ga_nothing; gameaction = ga_nothing;
playerdeadview = false;
paused = false; paused = false;
CON_ToggleOff(); CON_ToggleOff();
CON_ClearHUD(); CON_ClearHUD();
@ -852,7 +849,6 @@ void F_StartGameEnd(void)
G_SetGamestate(GS_GAMEEND); G_SetGamestate(GS_GAMEEND);
gameaction = ga_nothing; gameaction = ga_nothing;
playerdeadview = false;
paused = false; paused = false;
CON_ToggleOff(); CON_ToggleOff();
CON_ClearHUD(); CON_ClearHUD();
@ -1109,7 +1105,6 @@ void F_StartContinue(void)
gameaction = ga_nothing; gameaction = ga_nothing;
keypressed = false; keypressed = false;
playerdeadview = false;
paused = false; paused = false;
CON_ToggleOff(); CON_ToggleOff();
CON_ClearHUD(); CON_ClearHUD();
@ -1278,7 +1273,6 @@ void F_StartCustomCutscene(INT32 cutscenenum, boolean precutscene, boolean reset
G_SetGamestate(GS_CUTSCENE); G_SetGamestate(GS_CUTSCENE);
gameaction = ga_nothing; gameaction = ga_nothing;
playerdeadview = false;
paused = false; paused = false;
CON_ToggleOff(); CON_ToggleOff();

View File

@ -267,6 +267,7 @@ tic_t indirectitemcooldown; // Cooldown before any more Shrink, SPB, or any othe
tic_t spbincoming; // Timer before SPB hits, can switch targets at this point tic_t spbincoming; // Timer before SPB hits, can switch targets at this point
UINT8 spbplayer; // Player num that used the last SPB UINT8 spbplayer; // Player num that used the last SPB
tic_t mapreset; // Map reset delay when enough players have joined an empty game tic_t mapreset; // Map reset delay when enough players have joined an empty game
UINT8 nospectategrief; // How many players need to be in-game to eliminate last; for preventing spectate griefing
// Client-sided, unsynched variables (NEVER use in anything that needs to be synced with other players) // Client-sided, unsynched variables (NEVER use in anything that needs to be synced with other players)
boolean legitimateexit; // Did this client actually finish the match? boolean legitimateexit; // Did this client actually finish the match?
@ -2100,10 +2101,12 @@ void G_Ticker(boolean run)
G_ClearRetryFlag(); G_ClearRetryFlag();
// Costs a life to retry ... unless the player in question is dead already. // Costs a life to retry ... unless the player in question is dead already.
if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE) /*if (G_GametypeUsesLives() && players[consoleplayer].playerstate == PST_LIVE)
players[consoleplayer].lives -= 1; players[consoleplayer].lives -= 1;
G_DoReborn(consoleplayer); G_DoReborn(consoleplayer);*/
D_MapChange(gamemap, gametype, cv_kartencore.value, true, 1, false, false);
} }
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
@ -2935,7 +2938,7 @@ void G_DoReborn(INT32 playernum)
if (oldmo) if (oldmo)
G_ChangePlayerReferences(oldmo, players[playernum].mo); G_ChangePlayerReferences(oldmo, players[playernum].mo);
} }
else if (countdowntimeup || (!multiplayer && gametype == GT_COOP)) /*else if (countdowntimeup || (!multiplayer && !modeattacking))
{ {
// reload the level from scratch // reload the level from scratch
if (countdowntimeup) if (countdowntimeup)
@ -3004,7 +3007,7 @@ void G_DoReborn(INT32 playernum)
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
} }
#endif #endif
} }*/
else else
{ {
// respawn at the start // respawn at the start
@ -3051,7 +3054,7 @@ void G_ExitLevel(void)
} }
if (netgame || multiplayer) if (netgame || multiplayer)
CONS_Printf(M_GetText("The round has ended.\n")); CON_LogMessage(M_GetText("The round has ended.\n"));
// Remove CEcho text on round end. // Remove CEcho text on round end.
HU_DoCEcho(""); HU_DoCEcho("");
@ -3119,7 +3122,7 @@ boolean G_GametypeHasSpectators(void)
#if 0 #if 0
return (gametype != GT_COOP && gametype != GT_COMPETITION && gametype != GT_RACE); return (gametype != GT_COOP && gametype != GT_COMPETITION && gametype != GT_RACE);
#else #else
return (!splitscreen);//true; return (netgame); //true
#endif #endif
} }
@ -3413,6 +3416,8 @@ static void G_DoCompleted(void)
// nextmap is 0-based, unlike gamemap // nextmap is 0-based, unlike gamemap
if (nextmapoverride != 0) if (nextmapoverride != 0)
nextmap = (INT16)(nextmapoverride-1); nextmap = (INT16)(nextmapoverride-1);
else if (mapheaderinfo[gamemap-1]->nextlevel == 1101) // SRB2Kart: !!! WHENEVER WE GET GRAND PRIX, GO TO AWARDS MAP INSTEAD !!!
nextmap = (INT16)(mapheaderinfo[gamemap] ? gamemap : (spstage_start-1)); // (gamemap-1)+1 == gamemap :V
else else
nextmap = (INT16)(mapheaderinfo[gamemap-1]->nextlevel-1); nextmap = (INT16)(mapheaderinfo[gamemap-1]->nextlevel-1);
@ -3441,9 +3446,6 @@ static void G_DoCompleted(void)
else else
cm = (INT16)(mapheaderinfo[cm]->nextlevel-1); cm = (INT16)(mapheaderinfo[cm]->nextlevel-1);
if (cm == 1100-1) // !!! WHENEVER WE GET GRAND PRIX, GO TO AWARDS MAP INSTEAD !!!
cm = cm+1;
if (cm >= NUMMAPS || cm < 0) // out of range (either 1100-1102 or error) if (cm >= NUMMAPS || cm < 0) // out of range (either 1100-1102 or error)
{ {
cm = nextmap; //Start the loop again so that the error checking below is executed. cm = nextmap; //Start the loop again so that the error checking below is executed.
@ -4328,7 +4330,6 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool
// Don't carry over custom music change to another map. // Don't carry over custom music change to another map.
mapmusflags |= MUSIC_RELOADRESET; mapmusflags |= MUSIC_RELOADRESET;
playerdeadview = false;
automapactive = false; automapactive = false;
imcontinuing = false; imcontinuing = false;
@ -4341,13 +4342,13 @@ void G_InitNew(UINT8 pencoremode, const char *mapname, boolean resetplayer, bool
{ {
char *title = G_BuildMapTitle(gamemap); char *title = G_BuildMapTitle(gamemap);
CONS_Printf(M_GetText("Map is now \"%s"), G_BuildMapName(gamemap)); CON_LogMessage(va(M_GetText("Map is now \"%s"), G_BuildMapName(gamemap)));
if (title) if (title)
{ {
CONS_Printf(": %s", title); CON_LogMessage(va(": %s", title));
Z_Free(title); Z_Free(title);
} }
CONS_Printf("\"\n"); CON_LogMessage("\"\n");
} }
} }
@ -4498,6 +4499,13 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
G_CopyTiccmd(cmd, &oldcmd, 1); G_CopyTiccmd(cmd, &oldcmd, 1);
// SRB2kart: Copy-pasted from ticcmd building, removes that crappy demo cam
if (((players[displayplayer].mo && players[displayplayer].speed > 0) // Moving
|| (leveltime > starttime && (cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE)) // Rubber-burn turn
|| (players[displayplayer].spectator || objectplacing)) // Not a physical player
&& !(players[displayplayer].kartstuff[k_spinouttimer] && players[displayplayer].kartstuff[k_sneakertimer])) // Spinning and boosting cancels out spinout
localangle += (cmd->angleturn<<16);
if (!(demoflags & DF_GHOST) && *demo_p == DEMOMARKER) if (!(demoflags & DF_GHOST) && *demo_p == DEMOMARKER)
{ {
// end of demo data stream // end of demo data stream

View File

@ -62,6 +62,7 @@ extern consvar_t cv_turnaxis2,cv_moveaxis2,cv_brakeaxis2,cv_aimaxis2,cv_lookaxis
extern consvar_t cv_turnaxis3,cv_moveaxis3,cv_brakeaxis3,cv_aimaxis3,cv_lookaxis3,cv_fireaxis3,cv_driftaxis3; extern consvar_t cv_turnaxis3,cv_moveaxis3,cv_brakeaxis3,cv_aimaxis3,cv_lookaxis3,cv_fireaxis3,cv_driftaxis3;
extern consvar_t cv_turnaxis4,cv_moveaxis4,cv_brakeaxis4,cv_aimaxis4,cv_lookaxis4,cv_fireaxis4,cv_driftaxis4; extern consvar_t cv_turnaxis4,cv_moveaxis4,cv_brakeaxis4,cv_aimaxis4,cv_lookaxis4,cv_fireaxis4,cv_driftaxis4;
extern consvar_t cv_ghost_besttime, cv_ghost_bestlap, cv_ghost_last, cv_ghost_guest, cv_ghost_staff; extern consvar_t cv_ghost_besttime, cv_ghost_bestlap, cv_ghost_last, cv_ghost_guest, cv_ghost_staff;
extern consvar_t cv_splitplayers;
typedef enum typedef enum
{ {
@ -188,7 +189,6 @@ void G_StopMetalDemo(void);
ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(void); ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(void);
void G_StopDemo(void); void G_StopDemo(void);
boolean G_CheckDemoStatus(void); boolean G_CheckDemoStatus(void);
char *G_DemoPlayerName(char *defdemoname);
boolean G_IsSpecialStage(INT32 mapnum); boolean G_IsSpecialStage(INT32 mapnum);
boolean G_GametypeUsesLives(void); boolean G_GametypeUsesLives(void);

View File

@ -1321,21 +1321,21 @@ void G_Controldefault(void)
gamecontrolbis[gc_accelerate ][0] = KEY_2JOY1+0; // A gamecontrolbis[gc_accelerate ][0] = KEY_2JOY1+0; // A
gamecontrolbis[gc_lookback ][0] = KEY_2JOY1+1; // X gamecontrolbis[gc_lookback ][0] = KEY_2JOY1+1; // X
gamecontrolbis[gc_brake ][0] = KEY_2JOY1+2; // B gamecontrolbis[gc_brake ][0] = KEY_2JOY1+2; // B
gamecontrolbis[gc_fire ][0] = KEY_2JOY1+4; // LB gamecontrolbis[gc_fire ][0] = KEY_2JOY1+4; // LB
gamecontrolbis[gc_drift ][0] = KEY_2JOY1+5; // RB gamecontrolbis[gc_drift ][0] = KEY_2JOY1+5; // RB
// Player 3 controls // Player 3 controls
gamecontrol3[gc_accelerate ][0] = KEY_3JOY1+0; // A gamecontrol3[gc_accelerate ][0] = KEY_3JOY1+0; // A
gamecontrol3[gc_lookback ][0] = KEY_3JOY1+1; // X gamecontrol3[gc_lookback ][0] = KEY_3JOY1+1; // X
gamecontrol3[gc_brake ][0] = KEY_3JOY1+2; // B gamecontrol3[gc_brake ][0] = KEY_3JOY1+2; // B
gamecontrol3[gc_fire ][0] = KEY_3JOY1+4; // LB gamecontrol3[gc_fire ][0] = KEY_3JOY1+4; // LB
gamecontrol3[gc_drift ][0] = KEY_3JOY1+5; // RB gamecontrol3[gc_drift ][0] = KEY_3JOY1+5; // RB
// Player 4 controls // Player 4 controls
gamecontrol4[gc_accelerate ][0] = KEY_4JOY1+0; // A gamecontrol4[gc_accelerate ][0] = KEY_4JOY1+0; // A
gamecontrol4[gc_lookback ][0] = KEY_4JOY1+1; // X gamecontrol4[gc_lookback ][0] = KEY_4JOY1+1; // X
gamecontrol4[gc_brake ][0] = KEY_4JOY1+2; // B gamecontrol4[gc_brake ][0] = KEY_4JOY1+2; // B
gamecontrol4[gc_fire ][0] = KEY_4JOY1+4; // LB gamecontrol4[gc_fire ][0] = KEY_4JOY1+4; // LB
gamecontrol4[gc_drift ][0] = KEY_4JOY1+5; // RB gamecontrol4[gc_drift ][0] = KEY_4JOY1+5; // RB
} }
//#endif //#endif

View File

@ -565,8 +565,6 @@ static inline void HWR_SubsecPoly(INT32 num, poly_t *poly)
subsector_t *sub; subsector_t *sub;
seg_t *lseg; seg_t *lseg;
sscount++;
sub = &subsectors[num]; sub = &subsectors[num];
count = sub->numlines; count = sub->numlines;
lseg = &segs[sub->firstline]; lseg = &segs[sub->firstline];

View File

@ -3276,7 +3276,6 @@ static void HWR_Subsector(size_t num, UINT8 ssplayer)
if (num < numsubsectors) if (num < numsubsectors)
{ {
sscount++;
// subsector // subsector
sub = &subsectors[num]; sub = &subsectors[num];
// sector // sector
@ -5148,7 +5147,7 @@ static void HWR_AddSprites(sector_t *sec, UINT8 ssplayer)
// Handle all things in sector. // Handle all things in sector.
// If a limit exists, handle things a tiny bit different. // If a limit exists, handle things a tiny bit different.
if ((limit_dist = (fixed_t)((maptol & TOL_NIGHTS) ? cv_drawdist_nights.value : cv_drawdist.value) << FRACBITS)) if ((limit_dist = (fixed_t)(/*(maptol & TOL_NIGHTS) ? cv_drawdist_nights.value : */cv_drawdist.value) << FRACBITS))
{ {
for (thing = sec->thinglist; thing; thing = thing->snext) for (thing = sec->thinglist; thing; thing = thing->snext)
{ {
@ -5176,8 +5175,10 @@ static void HWR_AddSprites(sector_t *sec, UINT8 ssplayer)
approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y); approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
if (approx_dist <= limit_dist) if (approx_dist > limit_dist)
HWR_ProjectSprite(thing); continue;
HWR_ProjectSprite(thing);
} }
} }
else else
@ -5222,8 +5223,10 @@ static void HWR_AddSprites(sector_t *sec, UINT8 ssplayer)
approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y); approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y);
if (approx_dist <= limit_dist) if (approx_dist > limit_dist)
HWR_ProjectPrecipitationSprite(precipthing); continue;
HWR_ProjectPrecipitationSprite(precipthing);
} }
} }
else else
@ -5554,6 +5557,16 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
x1 = tr_x + x1 * rightcos; x1 = tr_x + x1 * rightcos;
x2 = tr_x - x2 * rightcos; x2 = tr_x - x2 * rightcos;
// okay, we can't return now... this is a hack, but weather isn't networked, so it should be ok
if (!(thing->precipflags & PCF_THUNK))
{
if (thing->precipflags & PCF_RAIN)
P_RainThinker(thing);
else
P_SnowThinker(thing);
thing->precipflags |= PCF_THUNK;
}
// //
// store information in a vissprite // store information in a vissprite
// //

View File

@ -1057,6 +1057,26 @@ boolean HU_Responder(event_t *ev)
// only KeyDown events now... // only KeyDown events now...
// Shoot, to prevent P1 chatting from ruining the game for everyone else, it's either:
// A. completely disallow opening chat entirely in online splitscreen
// or B. iterate through all controls to make sure it's bound to player 1 before eating
// You can see which one I chose.
// (Unless if you're sharing a keyboard, since you probably establish when you start chatting that you have dibs on it...)
// (Ahhh, the good ol days when I was a kid who couldn't afford an extra USB controller...)
if (ev->data1 >= KEY_MOUSE1)
{
INT32 i;
for (i = 0; i < num_gamecontrols; i++)
{
if (gamecontrol[i][0] == ev->data1 || gamecontrol[i][1] == ev->data1)
break;
}
if (i == num_gamecontrols)
return false;
}
if (!chat_on) if (!chat_on)
{ {
// enter chat mode // enter chat mode
@ -1260,6 +1280,7 @@ static void HU_drawMiniChat(void)
{ {
INT32 x = chatx+2; INT32 x = chatx+2;
INT32 charwidth = 4, charheight = 6; INT32 charwidth = 4, charheight = 6;
INT32 boxw = cv_chatwidth.value;
INT32 dx = 0, dy = 0; INT32 dx = 0, dy = 0;
size_t i = chat_nummsg_min; size_t i = chat_nummsg_min;
boolean prev_linereturn = false; // a hack to prevent double \n while I have no idea why they happen in the first place. boolean prev_linereturn = false; // a hack to prevent double \n while I have no idea why they happen in the first place.
@ -1271,9 +1292,12 @@ static void HU_drawMiniChat(void)
if (!chat_nummsg_min) if (!chat_nummsg_min)
return; // needless to say it's useless to do anything if we don't have anything to draw. return; // needless to say it's useless to do anything if we don't have anything to draw.
if (splitscreen > 1)
boxw = max(64, boxw/2);
for (; i>0; i--) for (; i>0; i--)
{ {
const char *msg = CHAT_WordWrap(x+2, cv_chatwidth.value-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]); const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]);
size_t j = 0; size_t j = 0;
INT32 linescount = 0; INT32 linescount = 0;
@ -1306,7 +1330,7 @@ static void HU_drawMiniChat(void)
} }
prev_linereturn = false; prev_linereturn = false;
dx += charwidth; dx += charwidth;
if (dx >= cv_chatwidth.value) if (dx >= boxw)
{ {
dx = 0; dx = 0;
linescount += 1; linescount += 1;
@ -1317,7 +1341,17 @@ static void HU_drawMiniChat(void)
msglines += linescount+1; msglines += linescount+1;
} }
y = chaty - charheight*(msglines+1) - (cv_kartspeedometer.value ? 16 : 0); y = chaty - charheight*(msglines+1);
if (splitscreen)
{
y -= BASEVIDHEIGHT/2;
if (splitscreen > 1)
y += 16;
}
else
y -= (cv_kartspeedometer.value ? 16 : 0);
dx = 0; dx = 0;
dy = 0; dy = 0;
i = 0; i = 0;
@ -1329,7 +1363,7 @@ static void HU_drawMiniChat(void)
INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below... INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below...
INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one. INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one.
size_t j = 0; size_t j = 0;
const char *msg = CHAT_WordWrap(x+2, cv_chatwidth.value-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it. const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
UINT8 *colormap = NULL; UINT8 *colormap = NULL;
while(msg[j]) // iterate through msg while(msg[j]) // iterate through msg
@ -1367,7 +1401,7 @@ static void HU_drawMiniChat(void)
dx += charwidth; dx += charwidth;
prev_linereturn = false; prev_linereturn = false;
if (dx >= cv_chatwidth.value) if (dx >= boxw)
{ {
dx = 0; dx = 0;
dy += charheight; dy += charheight;
@ -1388,6 +1422,7 @@ static void HU_drawMiniChat(void)
static void HU_drawChatLog(INT32 offset) static void HU_drawChatLog(INT32 offset)
{ {
INT32 charwidth = 4, charheight = 6; INT32 charwidth = 4, charheight = 6;
INT32 boxw = cv_chatwidth.value, boxh = cv_chatheight.value;
INT32 x = chatx+2, y, dx = 0, dy = 0; INT32 x = chatx+2, y, dx = 0, dy = 0;
UINT32 i = 0; UINT32 i = 0;
INT32 chat_topy, chat_bottomy; INT32 chat_topy, chat_bottomy;
@ -1397,17 +1432,34 @@ static void HU_drawChatLog(INT32 offset)
if (chat_scroll > chat_maxscroll) if (chat_scroll > chat_maxscroll)
chat_scroll = chat_maxscroll; chat_scroll = chat_maxscroll;
y = chaty - offset*charheight - (chat_scroll*charheight) - cv_chatheight.value*charheight - 12 - (cv_kartspeedometer.value ? 16 : 0); if (splitscreen)
chat_topy = y + chat_scroll*charheight; {
chat_bottomy = chat_topy + cv_chatheight.value*charheight; boxh = max(6, boxh/2);
if (splitscreen > 1)
boxw = max(64, boxw/2);
}
V_DrawFillConsoleMap(chatx, chat_topy, cv_chatwidth.value, cv_chatheight.value*charheight +2, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT); // log box y = chaty - offset*charheight - (chat_scroll*charheight) - boxh*charheight - 12;
if (splitscreen)
{
y -= BASEVIDHEIGHT/2;
if (splitscreen > 1)
y += 16;
}
else
y -= (cv_kartspeedometer.value ? 16 : 0);
chat_topy = y + chat_scroll*charheight;
chat_bottomy = chat_topy + boxh*charheight;
V_DrawFillConsoleMap(chatx, chat_topy, boxw, boxh*charheight +2, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT); // log box
for (i=0; i<chat_nummsg_log; i++) // iterate through our chatlog for (i=0; i<chat_nummsg_log; i++) // iterate through our chatlog
{ {
INT32 clrflag = 0; INT32 clrflag = 0;
INT32 j = 0; INT32 j = 0;
const char *msg = CHAT_WordWrap(x+2, cv_chatwidth.value-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it. const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
UINT8 *colormap = NULL; UINT8 *colormap = NULL;
while(msg[j]) // iterate through msg while(msg[j]) // iterate through msg
{ {
@ -1439,7 +1491,7 @@ static void HU_drawChatLog(INT32 offset)
} }
dx += charwidth; dx += charwidth;
if (dx >= cv_chatwidth.value-charwidth-2 && i<chat_nummsg_log && msg[j] >= HU_FONTSTART) // end of message shouldn't count, nor should invisible characters!!!! if (dx >= boxw-charwidth-2 && i<chat_nummsg_log && msg[j] >= HU_FONTSTART) // end of message shouldn't count, nor should invisible characters!!!!
{ {
dx = 0; dx = 0;
dy += charheight; dy += charheight;
@ -1457,10 +1509,10 @@ static void HU_drawChatLog(INT32 offset)
// getmaxscroll through a lazy hack. We do all these loops, so let's not do more loops that are gonna lag the game more. :P // getmaxscroll through a lazy hack. We do all these loops, so let's not do more loops that are gonna lag the game more. :P
chat_maxscroll = (dy/charheight); // welcome to C, we don't know what min() and max() are. chat_maxscroll = (dy/charheight); // welcome to C, we don't know what min() and max() are.
if (chat_maxscroll <= (UINT32)cv_chatheight.value) if (chat_maxscroll <= (UINT32)boxh)
chat_maxscroll = 0; chat_maxscroll = 0;
else else
chat_maxscroll -= cv_chatheight.value; chat_maxscroll -= boxh;
// if we're not bound by the time, autoscroll for next frame: // if we're not bound by the time, autoscroll for next frame:
if (atbottom) if (atbottom)
@ -1493,13 +1545,26 @@ static INT16 typelines = 1; // number of drawfill lines we need. it's some weird
static void HU_DrawChat(void) static void HU_DrawChat(void)
{ {
INT32 charwidth = 4, charheight = 6; INT32 charwidth = 4, charheight = 6;
INT32 t = 0, c = 0, y = chaty - (typelines*charheight) - (cv_kartspeedometer.value ? 16 : 0); INT32 boxw = cv_chatwidth.value;
INT32 t = 0, c = 0, y = chaty - (typelines*charheight);
UINT32 i = 0, saylen = strlen(w_chat); // You learn new things everyday! UINT32 i = 0, saylen = strlen(w_chat); // You learn new things everyday!
INT32 cflag = 0; INT32 cflag = 0;
const char *ntalk = "Say: ", *ttalk = "Team: "; const char *ntalk = "Say: ", *ttalk = "Team: ";
const char *talk = ntalk; const char *talk = ntalk;
const char *mute = "Chat has been muted."; const char *mute = "Chat has been muted.";
if (splitscreen)
{
y -= BASEVIDHEIGHT/2;
if (splitscreen > 1)
{
y += 16;
boxw = max(64, boxw/2);
}
}
else
y -= (cv_kartspeedometer.value ? 16 : 0);
if (teamtalk) if (teamtalk)
{ {
talk = ttalk; talk = ttalk;
@ -1518,7 +1583,7 @@ static void HU_DrawChat(void)
cflag = V_GRAYMAP; // set text in gray if chat is muted. cflag = V_GRAYMAP; // set text in gray if chat is muted.
} }
V_DrawFillConsoleMap(chatx, y-1, cv_chatwidth.value, (typelines*charheight), 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); V_DrawFillConsoleMap(chatx, y-1, boxw, (typelines*charheight), 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT);
while (talk[i]) while (talk[i])
{ {
@ -1551,7 +1616,7 @@ static void HU_DrawChat(void)
boolean skippedline = false; boolean skippedline = false;
if (c_input == (i+1)) if (c_input == (i+1))
{ {
int cursorx = (c+charwidth < cv_chatwidth.value-charwidth) ? (chatx + 2 + c+charwidth) : (chatx+1); // we may have to go down. int cursorx = (c+charwidth < boxw-charwidth) ? (chatx + 2 + c+charwidth) : (chatx+1); // we may have to go down.
int cursory = (cursorx != chatx+1) ? (y) : (y+charheight); int cursory = (cursorx != chatx+1) ? (y) : (y+charheight);
if (hu_tick < 4) if (hu_tick < 4)
V_DrawChatCharacter(cursorx, cursory+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL); V_DrawChatCharacter(cursorx, cursory+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
@ -1571,7 +1636,7 @@ static void HU_DrawChat(void)
V_DrawChatCharacter(chatx + c + 2, y, w_chat[i++] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, !cv_allcaps.value, NULL); V_DrawChatCharacter(chatx + c + 2, y, w_chat[i++] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, !cv_allcaps.value, NULL);
c += charwidth; c += charwidth;
if (c > cv_chatwidth.value-(charwidth*2) && !skippedline) if (c > boxw-(charwidth*2) && !skippedline)
{ {
c = 0; c = 0;
y += charheight; y += charheight;
@ -1584,6 +1649,14 @@ static void HU_DrawChat(void)
{ {
INT32 count = 0; INT32 count = 0;
INT32 p_dispy = chaty - charheight -1; INT32 p_dispy = chaty - charheight -1;
if (splitscreen)
{
p_dispy -= BASEVIDHEIGHT/2;
if (splitscreen > 1)
p_dispy += 16;
}
else
p_dispy -= (cv_kartspeedometer.value ? 16 : 0);
i = 0; i = 0;
for(i=0; (i<MAXPLAYERS); i++) for(i=0; (i<MAXPLAYERS); i++)
{ {
@ -1634,8 +1707,8 @@ static void HU_DrawChat(void)
{ {
char name[MAXPLAYERNAME+1]; char name[MAXPLAYERNAME+1];
strlcpy(name, player_names[i], 7); // shorten name to 7 characters. strlcpy(name, player_names[i], 7); // shorten name to 7 characters.
V_DrawFillConsoleMap(chatx+ cv_chatwidth.value + 2, p_dispy- (6*count) - (cv_kartspeedometer.value ? 16 : 0), 48, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); // fill it like the chat so the text doesn't become hard to read because of the hud. V_DrawFillConsoleMap(chatx+ boxw + 2, p_dispy- (6*count), 48, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); // fill it like the chat so the text doesn't become hard to read because of the hud.
V_DrawSmallString(chatx+ cv_chatwidth.value + 4, p_dispy- (6*count) - (cv_kartspeedometer.value ? 16 : 0), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, va("\x82%d\x80 - %s", i, name)); V_DrawSmallString(chatx+ boxw + 4, p_dispy- (6*count), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, va("\x82%d\x80 - %s", i, name));
count++; count++;
} }
} }

View File

@ -93,9 +93,6 @@ extern boolean chat_on;
// set true whenever the tab rankings are being shown for any reason // set true whenever the tab rankings are being shown for any reason
extern boolean hu_showscores; extern boolean hu_showscores;
// P_DeathThink sets this true to show scores while dead, in multiplayer
extern boolean playerdeadview;
// init heads up data at game startup. // init heads up data at game startup.
void HU_Init(void); void HU_Init(void);

View File

@ -64,7 +64,7 @@ void I_ShutdownSound(void);
\return sfx handle \return sfx handle
*/ */
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority); INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel);
/** \brief Stops a sound channel. /** \brief Stops a sound channel.

View File

@ -686,14 +686,29 @@ static boolean SOCK_CanGet(void)
#endif #endif
#ifndef NONET #ifndef NONET
static void SOCK_Send(void) static inline ssize_t SOCK_SendToAddr(SOCKET_TYPE socket, mysockaddr_t *sockaddr)
{ {
ssize_t c = ERRSOCKET;
socklen_t d4 = (socklen_t)sizeof(struct sockaddr_in); socklen_t d4 = (socklen_t)sizeof(struct sockaddr_in);
#ifdef HAVE_IPV6 #ifdef HAVE_IPV6
socklen_t d6 = (socklen_t)sizeof(struct sockaddr_in6); socklen_t d6 = (socklen_t)sizeof(struct sockaddr_in6);
#endif #endif
socklen_t d, da = (socklen_t)sizeof(mysockaddr_t); socklen_t d, da = (socklen_t)sizeof(mysockaddr_t);
switch (sockaddr->any.sa_family)
{
case AF_INET: d = d4; break;
#ifdef HAVE_IPV6
case AF_INET6: d = d6; break;
#endif
default: d = da; break;
}
return sendto(socket, (char *)&doomcom->data, doomcom->datalength, 0, &sockaddr->any, d);
}
static void SOCK_Send(void)
{
ssize_t c = ERRSOCKET;
size_t i, j; size_t i, j;
if (!nodeconnected[doomcom->remotenode]) if (!nodeconnected[doomcom->remotenode])
@ -706,19 +721,7 @@ static void SOCK_Send(void)
for (j = 0; j < broadcastaddresses; j++) for (j = 0; j < broadcastaddresses; j++)
{ {
if (myfamily[i] == broadcastaddress[j].any.sa_family) if (myfamily[i] == broadcastaddress[j].any.sa_family)
{ SOCK_SendToAddr(mysockets[i], &broadcastaddress[j]);
if (broadcastaddress[i].any.sa_family == AF_INET)
d = d4;
#ifdef HAVE_IPV6
else if (broadcastaddress[i].any.sa_family == AF_INET6)
d = d6;
#endif
else
d = da;
c = sendto(mysockets[i], (char *)&doomcom->data, doomcom->datalength, 0,
&broadcastaddress[j].any, d);
}
} }
} }
return; return;
@ -728,35 +731,13 @@ static void SOCK_Send(void)
for (i = 0; i < mysocketses; i++) for (i = 0; i < mysocketses; i++)
{ {
if (myfamily[i] == clientaddress[doomcom->remotenode].any.sa_family) if (myfamily[i] == clientaddress[doomcom->remotenode].any.sa_family)
{ SOCK_SendToAddr(mysockets[i], &clientaddress[doomcom->remotenode]);
if (clientaddress[doomcom->remotenode].any.sa_family == AF_INET)
d = d4;
#ifdef HAVE_IPV6
else if (clientaddress[doomcom->remotenode].any.sa_family == AF_INET6)
d = d6;
#endif
else
d = da;
sendto(mysockets[i], (char *)&doomcom->data, doomcom->datalength, 0,
&clientaddress[doomcom->remotenode].any, d);
}
} }
return; return;
} }
else else
{ {
if (clientaddress[doomcom->remotenode].any.sa_family == AF_INET) c = SOCK_SendToAddr(nodesocket[doomcom->remotenode], &clientaddress[doomcom->remotenode]);
d = d4;
#ifdef HAVE_IPV6
else if (clientaddress[doomcom->remotenode].any.sa_family == AF_INET6)
d = d6;
#endif
else
d = da;
c = sendto(nodesocket[doomcom->remotenode], (char *)&doomcom->data, doomcom->datalength, 0,
&clientaddress[doomcom->remotenode].any, d);
} }
if (c == ERRSOCKET && errno != ECONNREFUSED && errno != EWOULDBLOCK) if (c == ERRSOCKET && errno != ECONNREFUSED && errno != EWOULDBLOCK)
@ -1044,7 +1025,7 @@ static boolean UDP_Socket(void)
if (gaie == 0) if (gaie == 0)
{ {
runp = ai; runp = ai;
while (runp != NULL) while (runp != NULL && s < MAXNETNODES+1)
{ {
memcpy(&clientaddress[s], runp->ai_addr, runp->ai_addrlen); memcpy(&clientaddress[s], runp->ai_addr, runp->ai_addrlen);
s++; s++;
@ -1059,12 +1040,15 @@ static boolean UDP_Socket(void)
clientaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_LOOPBACK); //GetLocalAddress(); // my own ip clientaddress[s].ip4.sin_addr.s_addr = htonl(INADDR_LOOPBACK); //GetLocalAddress(); // my own ip
s++; s++;
} }
s = 0;
// setup broadcast adress to BROADCASTADDR entry // setup broadcast adress to BROADCASTADDR entry
gaie = I_getaddrinfo("255.255.255.255", "0", &hints, &ai); gaie = I_getaddrinfo("255.255.255.255", "0", &hints, &ai);
if (gaie == 0) if (gaie == 0)
{ {
runp = ai; runp = ai;
while (runp != NULL) while (runp != NULL && s < MAXNETNODES+1)
{ {
memcpy(&broadcastaddress[s], runp->ai_addr, runp->ai_addrlen); memcpy(&broadcastaddress[s], runp->ai_addr, runp->ai_addrlen);
s++; s++;
@ -1087,7 +1071,7 @@ static boolean UDP_Socket(void)
if (gaie == 0) if (gaie == 0)
{ {
runp = ai; runp = ai;
while (runp != NULL) while (runp != NULL && s < MAXNETNODES+1)
{ {
memcpy(&broadcastaddress[s], runp->ai_addr, runp->ai_addrlen); memcpy(&broadcastaddress[s], runp->ai_addr, runp->ai_addrlen);
s++; s++;

View File

@ -56,12 +56,12 @@ char sprnames[NUMSPRITES + 1][5] =
"SRBJ","SRBK","SRBL","SRBM","SRBN","SRBO", "SRBJ","SRBK","SRBL","SRBM","SRBN","SRBO",
//SRB2kart Sprites //SRB2kart Sprites
"SPRG","BSPR","RNDM","RPOP","SGNS","FAST","DSHR","BOST","BOSM","KFRE", "SPRG","BSPR","RNDM","RPOP","SGNS","FAST","DSHR","BOST","BOSM","KFRE",
"KINV","KINF","WIPD","DRIF","DUST","FITM","BANA","ORBN","JAWZ","SSMN", "KINV","KINF","WIPD","DRIF","DUST","RSHE","FITM","BANA","ORBN","JAWZ",
"KRBM","BHOG","BHBM","BLIG","LIGH","THNS","SINK","SITR","KBLN","DEZL", "SSMN","KRBM","BHOG","BHBM","BLIG","LIGH","THNS","SINK","SITR","KBLN",
"POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS","BUZB","CHOM","SACO", "DEZL","POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS","BUZB","CHOM",
"CRAB","SHAD","BRNG","BUMP","FLEN","CLAS","PSHW","ISTA","ISTB","ARRO", "SACO","CRAB","SHAD","BRNG","BUMP","FLEN","CLAS","PSHW","ISTA","ISTB",
"ITEM","ITMO","ITMI","ITMN","WANT","PBOM","RETI","AIDU","KSPK","LZI1", "ARRO","ITEM","ITMO","ITMI","ITMN","WANT","PBOM","RETI","AIDU","KSPK",
"LZI2","KLIT","VIEW" "LZI1","LZI2","KLIT","VIEW"
}; };
// Doesn't work with g++, needs actionf_p1 (don't modify this comment) // Doesn't work with g++, needs actionf_p1 (don't modify this comment)
@ -2623,6 +2623,11 @@ state_t states[NUMSTATES] =
{SPR_WIPD, 3, 3, {NULL}, 0, 0, S_WIPEOUTTRAIL5}, // S_WIPEOUTTRAIL4 {SPR_WIPD, 3, 3, {NULL}, 0, 0, S_WIPEOUTTRAIL5}, // S_WIPEOUTTRAIL4
{SPR_WIPD, 4, 3, {NULL}, 0, 0, S_NULL}, // S_WIPEOUTTRAIL5 {SPR_WIPD, 4, 3, {NULL}, 0, 0, S_NULL}, // S_WIPEOUTTRAIL5
{SPR_RSHE, 0, -1, {NULL}, 0, 0, S_NULL}, // S_ROCKETSNEAKER_L
{SPR_RSHE, 1, -1, {NULL}, 0, 0, S_NULL}, // S_ROCKETSNEAKER_R
{SPR_RSHE, 2, -1, {NULL}, 0, 0, S_NULL}, // S_ROCKETSNEAKER_LVIBRATE
{SPR_RSHE, 3, -1, {NULL}, 0, 0, S_NULL}, // S_ROCKETSNEAKER_RVIBRATE
{SPR_FITM, FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM2}, // S_FAKEITEM1 {SPR_FITM, FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM2}, // S_FAKEITEM1
{SPR_FITM, 1|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM3}, // S_FAKEITEM2 {SPR_FITM, 1|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM3}, // S_FAKEITEM2
{SPR_FITM, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM4}, // S_FAKEITEM3 {SPR_FITM, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_FAKEITEM4}, // S_FAKEITEM3
@ -10755,7 +10760,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL, // deathstate S_NULL, // deathstate
S_NULL, // xdeathstate S_NULL, // xdeathstate
sfx_None, // deathsound sfx_None, // deathsound
-24*FRACUNIT, // speed -72*FRACUNIT, // speed -- -24*FRACUNIT originally, srb2kart x3 (nya)
1*FRACUNIT, // radius 1*FRACUNIT, // radius
8*FRACUNIT, // height 8*FRACUNIT, // height
0, // display offset 0, // display offset
@ -14803,6 +14808,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate S_NULL // raisestate
}, },
{ // MT_ROCKETSNEAKER
-1, // doomednum
S_ROCKETSNEAKER_L, // spawnstate
1, // spawnhealth
S_NULL, // seestate
sfx_tossed, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_s3k5d, // deathsound
0, // speed
16*FRACUNIT, // radius
16*FRACUNIT, // height
0, // display offset
0, // mass
0, // damage
sfx_s3kc0s, // activesound
MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags
S_NULL // raisestate
},
{ // MT_FAKESHIELD { // MT_FAKESHIELD
-1, // doomednum -1, // doomednum
S_FAKEITEM1, // spawnstate S_FAKEITEM1, // spawnstate

View File

@ -596,6 +596,7 @@ typedef enum sprite
SPR_DUST, // Drift Dust SPR_DUST, // Drift Dust
// Kart Items // Kart Items
SPR_RSHE, // Rocket sneaker
SPR_FITM, // Eggman Monitor SPR_FITM, // Eggman Monitor
SPR_BANA, // Banana Peel SPR_BANA, // Banana Peel
SPR_ORBN, // Orbinaut SPR_ORBN, // Orbinaut
@ -3155,6 +3156,12 @@ typedef enum state
S_WIPEOUTTRAIL4, S_WIPEOUTTRAIL4,
S_WIPEOUTTRAIL5, S_WIPEOUTTRAIL5,
// Rocket sneaker
S_ROCKETSNEAKER_L,
S_ROCKETSNEAKER_R,
S_ROCKETSNEAKER_LVIBRATE,
S_ROCKETSNEAKER_RVIBRATE,
//{ Eggman Monitor //{ Eggman Monitor
S_FAKEITEM1, S_FAKEITEM1,
S_FAKEITEM2, S_FAKEITEM2,
@ -4155,6 +4162,8 @@ typedef enum mobj_type
MT_DRIFTSPARK, MT_DRIFTSPARK,
MT_DRIFTDUST, MT_DRIFTDUST,
MT_ROCKETSNEAKER,
MT_FAKESHIELD, MT_FAKESHIELD,
MT_FAKEITEM, MT_FAKEITEM,

View File

@ -31,6 +31,7 @@
// spbincoming is the timer before k_deathsentence is cast on the player in 1st // spbincoming is the timer before k_deathsentence is cast on the player in 1st
// spbplayer is the last player who fired a SPB // spbplayer is the last player who fired a SPB
// mapreset is set when enough players fill an empty server // mapreset is set when enough players fill an empty server
// nospectategrief is the players in-game needed to eliminate the person in last
//{ SRB2kart Color Code //{ SRB2kart Color Code
@ -433,6 +434,7 @@ void K_RegisterKartStuff(void)
CV_RegisterVar(&cv_kartdebughuddrop); CV_RegisterVar(&cv_kartdebughuddrop);
CV_RegisterVar(&cv_kartdebugcheckpoint); CV_RegisterVar(&cv_kartdebugcheckpoint);
CV_RegisterVar(&cv_kartdebugnodes);
} }
//} //}
@ -894,7 +896,35 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
// This makes the roulette produce the random noises. // This makes the roulette produce the random noises.
if ((player->kartstuff[k_itemroulette] % 3) == 1 && P_IsLocalPlayer(player)) if ((player->kartstuff[k_itemroulette] % 3) == 1 && P_IsLocalPlayer(player))
S_StartSound(NULL, sfx_mkitm1 + ((player->kartstuff[k_itemroulette] / 3) % 8)); {
#define PLAYROULETTESND S_StartSound(NULL, sfx_mkitm1 + ((player->kartstuff[k_itemroulette] / 3) % 8));
if (splitscreen)
{
if (players[displayplayer].kartstuff[k_itemroulette])
{
if (player == &players[displayplayer])
PLAYROULETTESND;
}
else if (players[secondarydisplayplayer].kartstuff[k_itemroulette])
{
if (player == &players[secondarydisplayplayer])
PLAYROULETTESND;
}
else if (players[thirddisplayplayer].kartstuff[k_itemroulette] && splitscreen > 1)
{
if (player == &players[thirddisplayplayer])
PLAYROULETTESND;
}
else if (players[fourthdisplayplayer].kartstuff[k_itemroulette] && splitscreen > 2)
{
if (player == &players[fourthdisplayplayer])
PLAYROULETTESND;
}
}
else
PLAYROULETTESND;
#undef PLAYROULETTESND
}
roulettestop = TICRATE + (3*(pingame - player->kartstuff[k_position])); roulettestop = TICRATE + (3*(pingame - player->kartstuff[k_position]));
@ -1241,7 +1271,7 @@ static void K_UpdateOffroad(player_t *player)
} }
// These have to go earlier than its sisters because of K_RespawnChecker... // These have to go earlier than its sisters because of K_RespawnChecker...
static void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master) void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master)
{ {
// flipping // flipping
mo->eflags = (mo->eflags & ~MFE_VERTICALFLIP)|(master->eflags & MFE_VERTICALFLIP); mo->eflags = (mo->eflags & ~MFE_VERTICALFLIP)|(master->eflags & MFE_VERTICALFLIP);
@ -2042,13 +2072,8 @@ void K_StealBumper(player_t *player, player_t *victim, boolean force)
} }
} }
if (netgame) if (netgame && player->kartstuff[k_bumper] <= 0)
{ CONS_Printf(M_GetText("%s is back in the game!\n"), player_names[player-players]);
if (player->kartstuff[k_bumper] <= 0)
CONS_Printf(M_GetText("%s is back in the game!\n"), player_names[player-players]);
else if (cv_hazardlog.value)
CONS_Printf(M_GetText("%s stole a bumper from %s!\n"), player_names[player-players], player_names[victim-players]);
}
newbumper = player->kartstuff[k_bumper]; newbumper = player->kartstuff[k_bumper];
if (newbumper <= 1) if (newbumper <= 1)
@ -2967,35 +2992,66 @@ static void K_DoHyudoroSteal(player_t *player)
} }
} }
void K_DoSneaker(player_t *player, boolean doPFlag) void K_DoSneaker(player_t *player, INT32 type)
{ {
const fixed_t prevboost = player->kartstuff[k_speedboost]; fixed_t intendedboost;
switch (gamespeed)
{
case 0:
intendedboost = 53740+768;
break;
case 2:
intendedboost = 17294+768;
break;
default:
intendedboost = 32768;
break;
}
if (!player->kartstuff[k_floorboost] || player->kartstuff[k_floorboost] == 3) if (!player->kartstuff[k_floorboost] || player->kartstuff[k_floorboost] == 3)
{ {
S_StartSound(player->mo, sfx_cdfm01); S_StartSound(player->mo, sfx_cdfm01);
K_SpawnDashDustRelease(player); K_SpawnDashDustRelease(player);
if (intendedboost > player->kartstuff[k_speedboost])
player->kartstuff[k_destboostcam] = FixedMul(FRACUNIT, FixedDiv((intendedboost - player->kartstuff[k_speedboost]), intendedboost));
} }
if (!player->kartstuff[k_sneakertimer]) if (!player->kartstuff[k_sneakertimer])
{ {
mobj_t *overlay = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BOOSTFLAME); if (type == 2)
P_SetTarget(&overlay->target, player->mo); {
overlay->destscale = player->mo->scale; if (player->mo->hnext)
P_SetScale(overlay, player->mo->scale); {
mobj_t *cur = player->mo->hnext;
while (cur && !P_MobjWasRemoved(cur))
{
if (!cur->tracer)
{
mobj_t *overlay = P_SpawnMobj(cur->x, cur->y, cur->z, MT_BOOSTFLAME);
P_SetTarget(&overlay->target, cur);
P_SetTarget(&cur->tracer, overlay);
P_SetScale(overlay, (overlay->destscale = 3*cur->scale/4));
}
cur = cur->hnext;
}
}
}
else
{
mobj_t *overlay = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BOOSTFLAME);
P_SetTarget(&overlay->target, player->mo);
P_SetScale(overlay, (overlay->destscale = player->mo->scale));
}
} }
player->kartstuff[k_sneakertimer] = sneakertime; player->kartstuff[k_sneakertimer] = sneakertime;
if (doPFlag) if (type != 0)
{ {
player->pflags |= PF_ATTACKDOWN; player->pflags |= PF_ATTACKDOWN;
K_PlayBoostTaunt(player->mo); K_PlayBoostTaunt(player->mo);
} }
K_GetKartBoostPower(player);
if (player->kartstuff[k_speedboost] > prevboost)
player->kartstuff[k_destboostcam] = FRACUNIT;
} }
static void K_DoShrink(player_t *player) static void K_DoShrink(player_t *player)
@ -3206,6 +3262,7 @@ void K_DropHnextList(player_t *player)
break; break;
// intentionally do nothing // intentionally do nothing
case MT_SINK_SHIELD: case MT_SINK_SHIELD:
case MT_ROCKETSNEAKER:
return; return;
default: default:
continue; continue;
@ -3553,6 +3610,93 @@ static void K_MoveHeldObjects(player_t *player)
} }
} }
break; break;
case MT_ROCKETSNEAKER: // Special rocket sneaker stuff
{
mobj_t *cur = player->mo->hnext;
INT32 num = 0;
while (cur && !P_MobjWasRemoved(cur))
{
const fixed_t radius = FixedHypot(player->mo->radius, player->mo->radius) + FixedHypot(cur->radius, cur->radius);
boolean vibrate = ((leveltime & 1) && !cur->tracer);
angle_t angoffset;
fixed_t targx, targy, targz;
cur->flags &= ~MF_NOCLIPTHING;
if (player->kartstuff[k_rocketsneakertimer] <= TICRATE && (leveltime & 1))
cur->flags2 |= MF2_DONTDRAW;
else
cur->flags2 &= ~MF2_DONTDRAW;
if (num & 1)
P_SetMobjStateNF(cur, (vibrate ? S_ROCKETSNEAKER_LVIBRATE : S_ROCKETSNEAKER_L));
else
P_SetMobjStateNF(cur, (vibrate ? S_ROCKETSNEAKER_RVIBRATE : S_ROCKETSNEAKER_R));
if (!player->kartstuff[k_rocketsneakertimer] || cur->extravalue2 || !cur->health)
{
num = (num+1) % 2;
cur = cur->hnext;
continue;
}
if (cur->extravalue1 < radius)
cur->extravalue1 += FixedMul(P_AproxDistance(cur->extravalue1, radius), FRACUNIT/12);
if (cur->extravalue1 > radius)
cur->extravalue1 = radius;
// Shrink your items if the player shrunk too.
P_SetScale(cur, (cur->destscale = FixedMul(FixedDiv(cur->extravalue1, radius), player->mo->scale)));
#if 1
{
angle_t input = player->mo->angle - cur->angle;
boolean invert = (input > ANGLE_180);
if (invert)
input = InvAngle(input);
input = FixedAngle(AngleFixed(input)/4);
if (invert)
input = InvAngle(input);
cur->angle = cur->angle + input;
}
#else
cur->angle = player->mo->angle;
#endif
angoffset = ANGLE_90 + (ANGLE_180 * num);
targx = player->mo->x + P_ReturnThrustX(cur, cur->angle + angoffset, cur->extravalue1);
targy = player->mo->y + P_ReturnThrustY(cur, cur->angle + angoffset, cur->extravalue1);
{ // bobbing, copy pasted from my kimokawaiii entry
const fixed_t pi = (22<<FRACBITS) / 7; // loose approximation, this doesn't need to be incredibly precise
fixed_t sine = 8 * FINESINE((((2*pi*(4*TICRATE)) * leveltime)>>ANGLETOFINESHIFT) & FINEMASK);
targz = (player->mo->z + (player->mo->height/2)) + sine;
}
if (cur->tracer)
{
fixed_t diffx, diffy, diffz;
diffx = targx - cur->x;
diffy = targy - cur->y;
diffz = targz - cur->z;
P_TeleportMove(cur->tracer, cur->tracer->x + diffx + P_ReturnThrustX(cur, cur->angle + angoffset, 6*cur->scale),
cur->tracer->y + diffy + P_ReturnThrustY(cur, cur->angle + angoffset, 6*cur->scale), cur->tracer->z + diffz);
P_SetScale(cur->tracer, (cur->tracer->destscale = 3*cur->scale/4));
}
P_TeleportMove(cur, targx, targy, targz);
num = (num+1) % 2;
cur = cur->hnext;
}
}
break;
default: default:
break; break;
} }
@ -3651,8 +3795,8 @@ static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd)
{ {
const INT32 numsnds = 13; const INT32 numsnds = 13;
INT32 class = ((player->kartspeed-1)/3) + (3*((player->kartweight-1)/3)); // engine class number INT32 class = ((player->kartspeed-1)/3) + (3*((player->kartweight-1)/3)); // engine class number
INT32 numcloseplayers = 0;
UINT8 volume = 255; UINT8 volume = 255;
fixed_t volumedampen = 0;
INT32 targetsnd = 0; INT32 targetsnd = 0;
INT32 i; INT32 i;
@ -3690,31 +3834,45 @@ static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd)
if (player->kartstuff[k_enginesnd] > 12) if (player->kartstuff[k_enginesnd] > 12)
player->kartstuff[k_enginesnd] = 12; player->kartstuff[k_enginesnd] = 12;
// Display player's engines are quieter for (i = 0; i < MAXPLAYERS; i++)
if ((player == &players[displayplayer])
|| (player == &players[secondarydisplayplayer] && splitscreen)
|| (player == &players[thirddisplayplayer] && splitscreen > 1)
|| (player == &players[fourthdisplayplayer] && splitscreen > 2))
volume = FixedDiv(volume<<FRACBITS, FixedSqrt(((splitscreen+1)*3)<<FRACBITS))>>FRACBITS;
else
{ {
for (i = 0; i < MAXPLAYERS; i++) UINT8 thisvol = 0;
fixed_t dist;
if (!playeringame[i] || !players[i].mo || players[i].spectator || players[i].exiting)
continue;
if ((i == displayplayer)
|| (i == secondarydisplayplayer && splitscreen)
|| (i == thirddisplayplayer && splitscreen > 1)
|| (i == fourthdisplayplayer && splitscreen > 2))
{ {
if (!playeringame[i] || !players[i].mo || players[i].spectator || players[i].exiting) volumedampen += FRACUNIT; // We already know what this is gonna be, let's not waste our time.
continue; continue;
if ((i == displayplayer)
|| (i == secondarydisplayplayer && splitscreen)
|| (i == thirddisplayplayer && splitscreen > 1)
|| (i == fourthdisplayplayer && splitscreen > 2))
continue;
if (P_AproxDistance(P_AproxDistance(player->mo->x-players[i].mo->x,
player->mo->y-players[i].mo->y), player->mo->z-players[i].mo->z) <= 3072<<FRACBITS) // engine sounds' approx. range
numcloseplayers++;
} }
if (numcloseplayers > 1)
volume = FixedDiv(volume<<FRACBITS, FixedSqrt(numcloseplayers<<FRACBITS))>>FRACBITS; dist = P_AproxDistance(P_AproxDistance(player->mo->x-players[i].mo->x,
player->mo->y-players[i].mo->y), player->mo->z-players[i].mo->z) / 2;
if (dist > 1536<<FRACBITS)
continue;
else if (dist < 160<<FRACBITS) // engine sounds' approx. range
thisvol = 255;
else
thisvol = (15 * (((160<<FRACBITS) - dist)>>FRACBITS)) / (((1536<<FRACBITS)-(160<<FRACBITS))>>(FRACBITS+4));
if (thisvol == 0)
continue;
volumedampen += (thisvol * 257); // 255 * 257 = FRACUNIT
} }
if (volumedampen > FRACUNIT)
volume = FixedDiv(volume<<FRACBITS, volumedampen)>>FRACBITS;
if (volume <= 0) // Might as well
return;
S_StartSoundAtVolume(player->mo, (sfx_krta00 + player->kartstuff[k_enginesnd]) + (class*numsnds), volume); S_StartSoundAtVolume(player->mo, (sfx_krta00 + player->kartstuff[k_enginesnd]) + (class*numsnds), volume);
} }
@ -4564,9 +4722,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
else if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO else if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO
&& player->kartstuff[k_rocketsneakertimer] > 1) && player->kartstuff[k_rocketsneakertimer] > 1)
{ {
K_DoSneaker(player, true); K_DoSneaker(player, 2);
K_PlayBoostTaunt(player->mo); K_PlayBoostTaunt(player->mo);
player->kartstuff[k_rocketsneakertimer] -= 5; player->kartstuff[k_rocketsneakertimer] -= 2*TICRATE;
if (player->kartstuff[k_rocketsneakertimer] < 1) if (player->kartstuff[k_rocketsneakertimer] < 1)
player->kartstuff[k_rocketsneakertimer] = 1; player->kartstuff[k_rocketsneakertimer] = 1;
} }
@ -4581,7 +4739,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
case KITEM_SNEAKER: case KITEM_SNEAKER:
if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO) if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO)
{ {
K_DoSneaker(player, true); K_DoSneaker(player, 1);
K_PlayBoostTaunt(player->mo); K_PlayBoostTaunt(player->mo);
player->kartstuff[k_itemamount]--; player->kartstuff[k_itemamount]--;
} }
@ -4590,10 +4748,33 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO
&& player->kartstuff[k_rocketsneakertimer] == 0) && player->kartstuff[k_rocketsneakertimer] == 0)
{ {
K_DoSneaker(player, true); INT32 moloop;
mobj_t *mo = NULL;
mobj_t *prev = player->mo;
K_PlayBoostTaunt(player->mo); K_PlayBoostTaunt(player->mo);
player->kartstuff[k_rocketsneakertimer] = itemtime; //player->kartstuff[k_itemheld] = 1;
S_StartSound(player->mo, sfx_s3k3a);
//K_DoSneaker(player, 2);
player->kartstuff[k_rocketsneakertimer] = (itemtime*3);
player->kartstuff[k_itemamount]--; player->kartstuff[k_itemamount]--;
K_UpdateHnextList(player, true);
for (moloop = 0; moloop < 2; moloop++)
{
mo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_ROCKETSNEAKER);
mo->flags |= MF_NOCLIPTHING;
mo->angle = player->mo->angle;
mo->threshold = 10;
mo->movecount = moloop%2;
mo->movedir = mo->lastlook = moloop+1;
P_SetTarget(&mo->target, player->mo);
P_SetTarget(&mo->hprev, prev);
P_SetTarget(&prev->hnext, mo);
prev = mo;
}
} }
break; break;
case KITEM_INVINCIBILITY: case KITEM_INVINCIBILITY:
@ -4853,11 +5034,12 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
} }
break; break;
case KITEM_THUNDERSHIELD: case KITEM_THUNDERSHIELD:
if (player->kartstuff[k_curshield] <= 0) if (player->kartstuff[k_curshield] != 1)
{ {
mobj_t *shield = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_THUNDERSHIELD); mobj_t *shield = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_THUNDERSHIELD);
P_SetScale(shield, (shield->destscale = (5*shield->destscale)>>2)); P_SetScale(shield, (shield->destscale = (5*shield->destscale)>>2));
P_SetTarget(&shield->target, player->mo); P_SetTarget(&shield->target, player->mo);
S_StartSound(shield, sfx_s3k41);
player->kartstuff[k_curshield] = 1; player->kartstuff[k_curshield] = 1;
} }
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO)
@ -4956,8 +5138,10 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->mo->eflags |= MFE_DRAWONLYFORP3; player->mo->eflags |= MFE_DRAWONLYFORP3;
else if (player == &players[fourthdisplayplayer] && splitscreen > 2) else if (player == &players[fourthdisplayplayer] && splitscreen > 2)
player->mo->eflags |= MFE_DRAWONLYFORP4; player->mo->eflags |= MFE_DRAWONLYFORP4;
else else if (player == &players[consoleplayer])
player->mo->eflags |= MFE_DRAWONLYFORP1; player->mo->eflags |= MFE_DRAWONLYFORP1;
else
player->mo->flags2 |= MF2_DONTDRAW;
} }
else else
player->mo->eflags &= ~(MFE_DRAWONLYFORP1|MFE_DRAWONLYFORP2|MFE_DRAWONLYFORP3|MFE_DRAWONLYFORP4); player->mo->eflags &= ~(MFE_DRAWONLYFORP1|MFE_DRAWONLYFORP2|MFE_DRAWONLYFORP3|MFE_DRAWONLYFORP4);
@ -5099,7 +5283,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (player->kartstuff[k_boostcharge] <= 36) if (player->kartstuff[k_boostcharge] <= 36)
{ {
player->kartstuff[k_startboost] = 0; player->kartstuff[k_startboost] = 0;
K_DoSneaker(player, false); K_DoSneaker(player, 0);
player->kartstuff[k_sneakertimer] = 70; // PERFECT BOOST!! player->kartstuff[k_sneakertimer] = 70; // PERFECT BOOST!!
if (!player->kartstuff[k_floorboost] || player->kartstuff[k_floorboost] == 3) // Let everyone hear this one if (!player->kartstuff[k_floorboost] || player->kartstuff[k_floorboost] == 3) // Let everyone hear this one
@ -5325,7 +5509,7 @@ void K_CheckSpectateStatus(void)
return; return;
if (numingame < 2 || leveltime < starttime || mapreset) // Allow if the match hasn't started yet if (numingame < 2 || leveltime < starttime || mapreset) // Allow if the match hasn't started yet
continue; continue;
if (leveltime > 20*TICRATE) // DON'T allow if the match is 20 seconds in if (leveltime > (starttime + 20*TICRATE)) // DON'T allow if the match is 20 seconds in
return; return;
if (G_RaceGametype() && players[i].laps) // DON'T allow if the race is at 2 laps if (G_RaceGametype() && players[i].laps) // DON'T allow if the race is at 2 laps
return; return;
@ -6009,9 +6193,10 @@ static void K_drawKartItem(void)
// Extensible meter, currently only used for rocket sneaker... // Extensible meter, currently only used for rocket sneaker...
if (itembar && hudtrans) if (itembar && hudtrans)
{ {
const INT32 barlength = (splitscreen > 1 ? 12 : 24); const INT32 barlength = (splitscreen > 1 ? 12 : 26);
const INT32 max = itemtime; // timer's normal highest value const INT32 maxl = (itemtime*3) - barlength; // timer's normal highest value
const INT32 length = min(barlength, (itembar * barlength) / max); const INT32 fill = ((itembar*barlength)/maxl);
const INT32 length = min(barlength, fill);
const INT32 height = (offset ? 1 : 2); const INT32 height = (offset ? 1 : 2);
const INT32 x = (offset ? 17 : 11), y = (offset ? 27 : 35); const INT32 x = (offset ? 17 : 11), y = (offset ? 27 : 35);
@ -6896,10 +7081,15 @@ static void K_drawBattleFullscreen(void)
} }
else else
{ {
if (stplyr == &players[secondarydisplayplayer]) if (stplyr->exiting)
x = BASEVIDWIDTH-96; {
if (stplyr == &players[secondarydisplayplayer])
x = BASEVIDWIDTH-96;
else
x = 96;
}
else else
x = 96; scale /= 2;
} }
} }
@ -7420,7 +7610,7 @@ void K_drawKartHUD(void)
K_drawKartMinimap(); K_drawKartMinimap();
// Draw full screen stuff that turns off the rest of the HUD // Draw full screen stuff that turns off the rest of the HUD
if (mapreset) if (mapreset && stplyr == &players[displayplayer])
{ {
K_drawChallengerScreen(); K_drawChallengerScreen();
return; return;
@ -7536,6 +7726,13 @@ void K_drawKartHUD(void)
if (cv_kartdebugcheckpoint.value) if (cv_kartdebugcheckpoint.value)
K_drawCheckpointDebugger(); K_drawCheckpointDebugger();
if (cv_kartdebugnodes.value)
{
UINT8 p;
for (p = 0; p < MAXPLAYERS; p++)
V_DrawString(8, 64+(8*p), V_YELLOWMAP, va("%d - %d", p, playernode[p]));
}
} }
//} //}

View File

@ -21,6 +21,7 @@ void K_RegisterKartStuff(void);
boolean K_IsPlayerLosing(player_t *player); boolean K_IsPlayerLosing(player_t *player);
boolean K_IsPlayerWanted(player_t *player); boolean K_IsPlayerWanted(player_t *player);
void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid); void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid);
void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master);
void K_RespawnChecker(player_t *player); void K_RespawnChecker(player_t *player);
void K_KartMoveAnimation(player_t *player); void K_KartMoveAnimation(player_t *player);
void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); void K_KartPlayerThink(player_t *player, ticcmd_t *cmd);
@ -36,7 +37,7 @@ void K_SpawnBoostTrail(player_t *player);
void K_SpawnSparkleTrail(mobj_t *mo); void K_SpawnSparkleTrail(mobj_t *mo);
void K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent); void K_SpawnWipeoutTrail(mobj_t *mo, boolean translucent);
void K_DriftDustHandling(mobj_t *spawner); void K_DriftDustHandling(mobj_t *spawner);
void K_DoSneaker(player_t *player, boolean doPFlag); void K_DoSneaker(player_t *player, INT32 type);
void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound); void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, UINT8 sound);
void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source); void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source);
void K_UpdateHnextList(player_t *player, boolean clean); void K_UpdateHnextList(player_t *player, boolean clean);

View File

@ -2086,6 +2086,19 @@ static int lib_kKartBouncing(lua_State *L)
return 0; return 0;
} }
static int lib_kMatchGenericExtraFlags(lua_State *L)
{
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
mobj_t *master = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
NOHUD
if (!mo)
return LUA_ErrInvalid(L, "mobj_t");
if (!master)
return LUA_ErrInvalid(L, "mobj_t");
K_MatchGenericExtraFlags(mo, master);
return 0;
}
static int lib_kDoInstashield(lua_State *L) static int lib_kDoInstashield(lua_State *L)
{ {
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@ -2214,11 +2227,11 @@ static int lib_kDriftDustHandling(lua_State *L)
static int lib_kDoSneaker(lua_State *L) static int lib_kDoSneaker(lua_State *L)
{ {
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
boolean doPFlag = luaL_checkboolean(L, 2); INT32 type = luaL_checkinteger(L, 2);
NOHUD NOHUD
if (!player) if (!player)
return LUA_ErrInvalid(L, "player_t"); return LUA_ErrInvalid(L, "player_t");
K_DoSneaker(player, doPFlag); K_DoSneaker(player, type);
return 0; return 0;
} }
@ -2482,6 +2495,7 @@ static luaL_Reg lib[] = {
{"K_IsPlayerLosing",lib_kIsPlayerLosing}, {"K_IsPlayerLosing",lib_kIsPlayerLosing},
{"K_IsPlayerWanted",lib_kIsPlayerWanted}, {"K_IsPlayerWanted",lib_kIsPlayerWanted},
{"K_KartBouncing",lib_kKartBouncing}, {"K_KartBouncing",lib_kKartBouncing},
{"K_MatchGenericExtraFlags",lib_kMatchGenericExtraFlags},
{"K_DoInstashield",lib_kDoInstashield}, {"K_DoInstashield",lib_kDoInstashield},
{"K_SpinPlayer",lib_kSpinPlayer}, {"K_SpinPlayer",lib_kSpinPlayer},
{"K_SquishPlayer",lib_kSquishPlayer}, {"K_SquishPlayer",lib_kSquishPlayer},

View File

@ -327,6 +327,7 @@ static int sector_get(lua_State *L)
{ {
sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR)); sector_t *sector = *((sector_t **)luaL_checkudata(L, 1, META_SECTOR));
enum sector_e field = luaL_checkoption(L, 2, sector_opt[0], sector_opt); enum sector_e field = luaL_checkoption(L, 2, sector_opt[0], sector_opt);
INT16 i;
if (!sector) if (!sector)
{ {
@ -349,11 +350,23 @@ static int sector_get(lua_State *L)
lua_pushfixed(L, sector->ceilingheight); lua_pushfixed(L, sector->ceilingheight);
return 1; return 1;
case sector_floorpic: // floorpic case sector_floorpic: // floorpic
lua_pushlstring(L, levelflats[sector->floorpic].name, 8); {
levelflat_t *levelflat = &levelflats[sector->floorpic];
for (i = 0; i < 8; i++)
if (!levelflat->name[i])
break;
lua_pushlstring(L, levelflat->name, i);
return 1; return 1;
}
case sector_ceilingpic: // ceilingpic case sector_ceilingpic: // ceilingpic
lua_pushlstring(L, levelflats[sector->ceilingpic].name, 8); {
levelflat_t *levelflat = &levelflats[sector->ceilingpic];
for (i = 0; i < 8; i++)
if (!levelflat->name[i])
break;
lua_pushlstring(L, levelflat->name, i);
return 1; return 1;
}
case sector_lightlevel: case sector_lightlevel:
lua_pushinteger(L, sector->lightlevel); lua_pushinteger(L, sector->lightlevel);
return 1; return 1;

View File

@ -182,19 +182,21 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump)
{ {
MYFILE f; MYFILE f;
char *name; char *name;
size_t len;
f.wad = wad; f.wad = wad;
f.size = W_LumpLengthPwad(wad, lump); f.size = W_LumpLengthPwad(wad, lump);
f.data = Z_Malloc(f.size, PU_LUA, NULL); f.data = Z_Malloc(f.size, PU_LUA, NULL);
W_ReadLumpPwad(wad, lump, f.data); W_ReadLumpPwad(wad, lump, f.data);
f.curpos = f.data; f.curpos = f.data;
name = malloc(strlen(wadfiles[wad]->filename)+10); len = strlen(wadfiles[wad]->filename);
name = malloc(len+10);
strcpy(name, wadfiles[wad]->filename); strcpy(name, wadfiles[wad]->filename);
if (!fasticmp(&name[strlen(name) - 4], ".lua")) { if (!fasticmp(&name[len - 4], ".lua")) {
// If it's not a .lua file, copy the lump name in too. // If it's not a .lua file, copy the lump name in too.
name[strlen(wadfiles[wad]->filename)] = '|'; name[len] = '|';
M_Memcpy(name+strlen(wadfiles[wad]->filename)+1, wadfiles[wad]->lumpinfo[lump].name, 8); M_Memcpy(name+len+1, wadfiles[wad]->lumpinfo[lump].name, 8);
name[strlen(wadfiles[wad]->filename)+9] = '\0'; name[len+9] = '\0';
} }
LUA_LoadFile(&f, name); LUA_LoadFile(&f, name);

View File

@ -492,7 +492,9 @@ static void GIF_framewrite(void)
// screen regions are handled in GIF_lzw // screen regions are handled in GIF_lzw
{ {
UINT16 delay = 3; // todo int d1 = (int)((100.0/NEWTICRATE)*(gif_frames+1));
int d2 = (int)((100.0/NEWTICRATE)*(gif_frames));
UINT16 delay = d1-d2;
INT32 startline; INT32 startline;
WRITEMEM(p, gifframe_gchead, 4); WRITEMEM(p, gifframe_gchead, 4);

View File

@ -101,10 +101,11 @@ unlockable_t unlockables[MAXUNLOCKABLES] =
/* 02 */ {"SMK Cup", "", -1, 2, SECRET_NONE, 0, false, false, 0}, /* 02 */ {"SMK Cup", "", -1, 2, SECRET_NONE, 0, false, false, 0},
/* 03 */ {"Chao Cup", "", -1, 3, SECRET_NONE, 0, false, false, 0}, /* 03 */ {"Chao Cup", "", -1, 3, SECRET_NONE, 0, false, false, 0},
/* 04 */ {"Encore Mode", "", 3, 4, SECRET_ENCORE, 0, false, false, 0}, /* 04 */ {"Hard Game Speed", "", -1, 4, SECRET_HARDSPEED, 0, false, false, 0},
/* 05 */ {"Hell Attack", "", 5, 5, SECRET_HELLATTACK, 0, false, false, 0}, /* 05 */ {"Encore Mode", "", 4, 5, SECRET_ENCORE, 0, false, false, 0},
/* 06 */ {"Hell Attack", "", 6, 6, SECRET_HELLATTACK, 0, false, false, 0},
/* 06 */ {"Record Attack", "", -1, -1, SECRET_RECORDATTACK, 0, true, true, 0}, /* 07 */ {"Record Attack", "", -1, -1, SECRET_RECORDATTACK, 0, true, true, 0},
}; };
// Default number of emblems and extra emblems // Default number of emblems and extra emblems
@ -120,23 +121,27 @@ void M_SetupDefaultConditionSets(void)
M_AddRawCondition(1, 1, UC_TOTALEMBLEMS, 5, 0, 0); M_AddRawCondition(1, 1, UC_TOTALEMBLEMS, 5, 0, 0);
M_AddRawCondition(1, 2, UC_MATCHESPLAYED, 10, 0, 0); M_AddRawCondition(1, 2, UC_MATCHESPLAYED, 10, 0, 0);
// -- 2: Collect 15 emblems OR play 25 matches // -- 2: Collect 10 emblems OR play 25 matches
M_AddRawCondition(2, 1, UC_TOTALEMBLEMS, 15, 0, 0); M_AddRawCondition(2, 1, UC_TOTALEMBLEMS, 10, 0, 0);
M_AddRawCondition(2, 2, UC_MATCHESPLAYED, 25, 0, 0); M_AddRawCondition(2, 2, UC_MATCHESPLAYED, 25, 0, 0);
// -- 3: Collect 30 emblems OR play 50 matches // -- 3: Collect 20 emblems OR play 50 matches
M_AddRawCondition(3, 1, UC_TOTALEMBLEMS, 30, 0, 0); M_AddRawCondition(3, 1, UC_TOTALEMBLEMS, 20, 0, 0);
M_AddRawCondition(3, 2, UC_MATCHESPLAYED, 50, 0, 0); M_AddRawCondition(3, 2, UC_MATCHESPLAYED, 50, 0, 0);
// -- 4: Collect 40 emblems OR play 150 matches // -- 4: Collect 30 emblems OR play 100 matches
M_AddRawCondition(4, 1, UC_TOTALEMBLEMS, 40, 0, 0); M_AddRawCondition(4, 1, UC_TOTALEMBLEMS, 30, 0, 0);
M_AddRawCondition(4, 2, UC_MATCHESPLAYED, 150, 0, 0); M_AddRawCondition(4, 2, UC_MATCHESPLAYED, 100, 0, 0);
// -- 5: Collect 50 emblems ONLY // -- 5: Collect 40 emblems OR play 150 matches
M_AddRawCondition(5, 1, UC_TOTALEMBLEMS, 50, 0, 0); M_AddRawCondition(5, 1, UC_TOTALEMBLEMS, 40, 0, 0);
M_AddRawCondition(5, 2, UC_MATCHESPLAYED, 150, 0, 0);
// -- 10: Play 100 matches // -- 6: Collect 50 emblems ONLY
M_AddRawCondition(10, 1, UC_MATCHESPLAYED, 100, 0, 0); M_AddRawCondition(6, 1, UC_TOTALEMBLEMS, 50, 0, 0);
// -- 10: Play 300 matches
M_AddRawCondition(10, 1, UC_MATCHESPLAYED, 300, 0, 0);
} }
void M_AddRawCondition(UINT8 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2) void M_AddRawCondition(UINT8 set, UINT8 id, conditiontype_t c, INT32 r, INT16 x1, INT16 x2)

View File

@ -113,7 +113,7 @@ typedef struct
} unlockable_t; } unlockable_t;
// I have NO idea why these are going negative, but whatever. // I have NO idea why these are going negative, but whatever.
#define SECRET_NONE -6 // Does nil. Use with levels locked by UnlockRequired #define SECRET_NONE -6 // Does nil. Use with levels locked by UnlockRequired
#define SECRET_ITEMFINDER -5 // Enables Item Finder/Emblem Radar #define SECRET_ITEMFINDER -5 // Enables Item Finder/Emblem Radar
#define SECRET_EMBLEMHINTS -4 // Enables Emblem Hints #define SECRET_EMBLEMHINTS -4 // Enables Emblem Hints
#define SECRET_PANDORA -3 // Enables Pandora's Box #define SECRET_PANDORA -3 // Enables Pandora's Box
@ -124,8 +124,9 @@ typedef struct
#define SECRET_WARP 2 // Selectable warp #define SECRET_WARP 2 // Selectable warp
#define SECRET_SOUNDTEST 3 // Sound Test #define SECRET_SOUNDTEST 3 // Sound Test
#define SECRET_CREDITS 4 // Enables Credits #define SECRET_CREDITS 4 // Enables Credits
#define SECRET_ENCORE 5 // Enables Encore mode cvar #define SECRET_ENCORE 5 // Enables Encore mode cvar
#define SECRET_HELLATTACK 6 // Map Hell in record attack #define SECRET_HELLATTACK 6 // Map Hell in record attack
#define SECRET_HARDSPEED 7 // Enables Hard gamespeed
// If you have more secrets than these variables allow in your game, // If you have more secrets than these variables allow in your game,
// you seriously need to get a life. // you seriously need to get a life.

File diff suppressed because it is too large Load Diff

View File

@ -21,13 +21,14 @@ void I_ShutdownSound(void){}
// SFX I/O // SFX I/O
// //
INT32 I_StartSound(sfxenum_t id, INT32 vol, INT32 sep, INT32 pitch, INT32 priority) INT32 I_StartSound(sfxenum_t id, INT32 vol, INT32 sep, INT32 pitch, INT32 priority, INT32 channel)
{ {
(void)id; (void)id;
(void)vol; (void)vol;
(void)sep; (void)sep;
(void)pitch; (void)pitch;
(void)priority; (void)priority;
(void)channel;
return -1; return -1;
} }

View File

@ -1819,6 +1819,7 @@ void T_ThwompSector(levelspecthink_t *thwomp)
#define ceilingwasheight vars[5] #define ceilingwasheight vars[5]
fixed_t thwompx, thwompy; fixed_t thwompx, thwompy;
sector_t *actionsector; sector_t *actionsector;
ffloor_t *rover = NULL;
INT32 secnum; INT32 secnum;
// SRB2kart 170217 - Thwomps are automatic. // SRB2kart 170217 - Thwomps are automatic.
@ -1843,7 +1844,16 @@ void T_ThwompSector(levelspecthink_t *thwomp)
secnum = P_FindSectorFromTag((INT16)thwomp->vars[0], -1); secnum = P_FindSectorFromTag((INT16)thwomp->vars[0], -1);
if (secnum > 0) if (secnum > 0)
{
actionsector = &sectors[secnum]; actionsector = &sectors[secnum];
// Look for thwomp FFloor
for (rover = actionsector->ffloors; rover; rover = rover->next)
{
if (rover->master == thwomp->sourceline)
break;
}
}
else else
return; // Bad bad bad! return; // Bad bad bad!
@ -1932,10 +1942,13 @@ void T_ThwompSector(levelspecthink_t *thwomp)
{ {
mobj_t *mp = (void *)&actionsector->soundorg; mobj_t *mp = (void *)&actionsector->soundorg;
if (thwomp->sourceline->flags & ML_EFFECT4) if (!rover || (rover->flags & FF_EXISTS))
S_StartSound(mp, sides[thwomp->sourceline->sidenum[0]].textureoffset>>FRACBITS); {
else if (thwomp->sourceline->flags & ML_EFFECT4)
S_StartSound(mp, sfx_thwomp); S_StartSound(mp, sides[thwomp->sourceline->sidenum[0]].textureoffset>>FRACBITS);
else
S_StartSound(mp, sfx_thwomp);
}
thwomp->direction = 1; // start heading back up thwomp->direction = 1; // start heading back up
thwomp->distance = TICRATE; // but only after a small delay thwomp->distance = TICRATE; // but only after a small delay
@ -1953,17 +1966,22 @@ void T_ThwompSector(levelspecthink_t *thwomp)
/* // SRB2kart 170217 - Thwomps are automatic. /* // SRB2kart 170217 - Thwomps are automatic.
// scan the thinkers to find players! // scan the thinkers to find players!
for (th = thinkercap.next; th != &thinkercap; th = th->next) if (!rover || (rover->flags & FF_EXISTS))
{ {
if (th->function.acp1 != (actionf_p1)P_MobjThinker) // scan the thinkers to find players!
continue; for (th = thinkercap.next; th != &thinkercap; th = th->next)
mo = (mobj_t *)th;
if (mo->type == MT_PLAYER && mo->health && mo->z <= thwomp->sector->ceilingheight
&& P_AproxDistance(thwompx - mo->x, thwompy - mo->y) <= 96*FRACUNIT)
{ {
thwomp->direction = -1; if (th->function.acp1 != (actionf_p1)P_MobjThinker)
break; continue;
mo = (mobj_t *)th;
if (mo->type == MT_PLAYER && mo->health && mo->player && !mo->player->spectator
&& mo->z <= thwomp->sector->ceilingheight
&& P_AproxDistance(thwompx - mo->x, thwompy - mo->y) <= 96*FRACUNIT)
{
thwomp->direction = -1;
break;
}
} }
}*/ }*/

View File

@ -510,8 +510,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
} }
special->target->player->kartstuff[k_comebackpoints] += 2 * (K_IsPlayerWanted(player) ? 2 : 1); special->target->player->kartstuff[k_comebackpoints] += 2 * (K_IsPlayerWanted(player) ? 2 : 1);
if (netgame && cv_hazardlog.value)
CONS_Printf(M_GetText("%s bombed %s!\n"), player_names[special->target->player-players], player_names[player-players]);
if (special->target->player->kartstuff[k_comebackpoints] >= 3) if (special->target->player->kartstuff[k_comebackpoints] >= 3)
K_StealBumper(special->target->player, player, true); K_StealBumper(special->target->player, player, true);
special->target->player->kartstuff[k_comebacktimer] = comebacktime; special->target->player->kartstuff[k_comebacktimer] = comebacktime;
@ -527,8 +525,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
special->target->player->kartstuff[k_comebackmode] = 0; special->target->player->kartstuff[k_comebackmode] = 0;
special->target->player->kartstuff[k_comebackpoints]++; special->target->player->kartstuff[k_comebackpoints]++;
if (netgame && cv_hazardlog.value)
CONS_Printf(M_GetText("%s gave an item to %s.\n"), player_names[special->target->player-players], player_names[player-players]);
if (special->target->player->kartstuff[k_comebackpoints] >= 3) if (special->target->player->kartstuff[k_comebackpoints] >= 3)
K_StealBumper(special->target->player, player, true); K_StealBumper(special->target->player, player, true);
special->target->player->kartstuff[k_comebacktimer] = comebacktime; special->target->player->kartstuff[k_comebacktimer] = comebacktime;
@ -560,8 +556,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
special->target->player->kartstuff[k_comebackmode] = 0; special->target->player->kartstuff[k_comebackmode] = 0;
special->target->player->kartstuff[k_comebackpoints]++; special->target->player->kartstuff[k_comebackpoints]++;
if (netgame && cv_hazardlog.value)
CONS_Printf(M_GetText("%s gave an \"item\" to %s.\n"), player_names[special->target->player-players], player_names[player-players]);
if (special->target->player->kartstuff[k_comebackpoints] >= 3) if (special->target->player->kartstuff[k_comebackpoints] >= 3)
K_StealBumper(special->target->player, player, true); K_StealBumper(special->target->player, player, true);
special->target->player->kartstuff[k_comebacktimer] = comebacktime; special->target->player->kartstuff[k_comebacktimer] = comebacktime;
@ -1667,199 +1661,6 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
} }
} }
//
/** Prints death messages relating to a dying or hit player.
*
* \param player Affected player.
* \param inflictor The attack weapon used, can be NULL.
* \param source The attacker, can be NULL.
*/
static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *source)
{
const char *str = NULL;
boolean deathonly = false;
boolean deadsource = false;
boolean deadtarget = false;
// player names complete with control codes
char targetname[MAXPLAYERNAME+4];
char sourcename[MAXPLAYERNAME+4];
if (G_RaceGametype())
return; // Not in coop, etc.
if (!player)
return; // Impossible!
if (player->spectator)
return; // No messages for dying (crushed) spectators.
if (!netgame)
return; // Presumably it's obvious what's happening in splitscreen.
#ifdef HAVE_BLUA
if (LUAh_HurtMsg(player, inflictor, source))
return;
#endif
deadtarget = (player->health <= 0);
// Target's name
snprintf(targetname, sizeof(targetname), "%s%s%s",
CTFTEAMCODE(player),
player_names[player - players],
CTFTEAMENDCODE(player));
if (source)
{
// inflictor shouldn't be NULL if source isn't
I_Assert(inflictor != NULL);
if (source->player)
{
// Source's name (now that we know there is one)
snprintf(sourcename, sizeof(sourcename), "%s%s%s",
CTFTEAMCODE(source->player),
player_names[source->player - players],
CTFTEAMENDCODE(source->player));
// We don't care if it's us.
// "Player 1's [redacted] killed Player 1."
if (source->player->playerstate == PST_DEAD && source->player != player &&
(inflictor->flags2 & MF2_BEYONDTHEGRAVE))
deadsource = true;
if (inflictor->flags & MF_PUSHABLE)
{
str = M_GetText("%s%s's playtime with heavy objects %s %s.\n");
}
else switch (inflictor->type)
{
case MT_PLAYER:
if ((inflictor->player->powers[pw_shield] & SH_NOSTACK) == SH_BOMB)
str = M_GetText("%s%s's armageddon blast %s %s.\n");
else if (inflictor->player->powers[pw_invulnerability])
str = M_GetText("%s%s's invincibility aura %s %s.\n");
else if (inflictor->player->powers[pw_super])
str = M_GetText("%s%s's super aura %s %s.\n");
else
str = M_GetText("%s%s's tagging hand %s %s.\n");
break;
case MT_SPINFIRE:
str = M_GetText("%s%s's elemental fire trail %s %s.\n");
break;
case MT_THROWNBOUNCE:
str = M_GetText("%s%s's bounce ring %s %s.\n");
break;
case MT_THROWNINFINITY:
str = M_GetText("%s%s's infinity ring %s %s.\n");
break;
case MT_THROWNAUTOMATIC:
str = M_GetText("%s%s's automatic ring %s %s.\n");
break;
case MT_THROWNSCATTER:
str = M_GetText("%s%s's scatter ring %s %s.\n");
break;
// TODO: For next two, figure out how to determine if it was a direct hit or splash damage. -SH
case MT_THROWNEXPLOSION:
str = M_GetText("%s%s's explosion ring %s %s.\n");
break;
case MT_THROWNGRENADE:
str = M_GetText("%s%s's grenade ring %s %s.\n");
break;
case MT_REDRING:
if (inflictor->flags2 & MF2_RAILRING)
str = M_GetText("%s%s's rail ring %s %s.\n");
else
str = M_GetText("%s%s's thrown ring %s %s.\n");
break;
default:
str = M_GetText("%s%s %s %s.\n");
break;
}
CONS_Printf(str,
deadsource ? M_GetText("The late ") : "",
sourcename,
deadtarget ? M_GetText("killed") : M_GetText("hit"),
targetname);
return;
}
else switch (source->type)
{
case MT_NULL:
switch(source->threshold)
{
case 42:
deathonly = true;
str = M_GetText("%s drowned.\n");
break;
case 43:
str = M_GetText("%s was %s by spikes.\n");
break;
case 44:
deathonly = true;
str = M_GetText("%s was crushed.\n");
break;
}
break;
case MT_EGGMANICO:
case MT_EGGMANBOX:
str = M_GetText("%s was %s by Eggman's nefarious TV magic.\n");
break;
case MT_SPIKE:
str = M_GetText("%s was %s by spikes.\n");
break;
default:
str = M_GetText("%s was %s by an environmental hazard.\n");
break;
}
}
else
{
// null source, environment kills
// TERRIBLE HACK for hit damage because P_DoPlayerPain moves the player...
// I'll put it back, I promise!
player->mo->z -= player->mo->momz+1;
if (P_PlayerTouchingSectorSpecial(player, 1, 2))
str = M_GetText("%s was %s by chemical water.\n");
else if (P_PlayerTouchingSectorSpecial(player, 1, 3))
str = M_GetText("%s was %s by molten lava.\n");
else if (P_PlayerTouchingSectorSpecial(player, 1, 4))
str = M_GetText("%s was %s by electricity.\n");
else if (deadtarget)
{
deathonly = true;
if (P_PlayerTouchingSectorSpecial(player, 1, 6)
|| P_PlayerTouchingSectorSpecial(player, 1, 7))
str = M_GetText("%s fell into a bottomless pit.\n");
else if (P_PlayerTouchingSectorSpecial(player, 1, 12))
str = M_GetText("%s asphyxiated in space.\n");
else
str = M_GetText("%s died.\n");
}
if (!str)
str = M_GetText("%s was %s by an environmental hazard.\n");
player->mo->z += player->mo->momz+1;
}
if (!str) // Should not happen! Unless we missed catching something above.
return;
// Don't log every hazard hit if they don't want us to.
if (!deadtarget && !cv_hazardlog.value)
return;
if (deathonly)
{
if (!deadtarget)
return;
CONS_Printf(str, targetname);
}
else
CONS_Printf(str, targetname, deadtarget ? M_GetText("killed") : M_GetText("hit"));
}
/** Checks if the level timer is over the timelimit and the round should end, /** Checks if the level timer is over the timelimit and the round should end,
* unless you are in overtime. In which case leveltime may stretch out beyond * unless you are in overtime. In which case leveltime may stretch out beyond
* timelimitintics and overtime's status will be checked here each tick. * timelimitintics and overtime's status will be checked here each tick.
@ -2150,7 +1951,7 @@ boolean P_CheckRacers(void)
numplayersingame++; numplayersingame++;
} }
if (numplayersingame > 1) // if there's more than one player in-game, this is safe to do if (numplayersingame >= nospectategrief) // prevent spectate griefing
{ {
// check if we just got unlucky and there was only one guy who was a problem // check if we just got unlucky and there was only one guy who was a problem
for (j = i+1; j < MAXPLAYERS; j++) for (j = i+1; j < MAXPLAYERS; j++)
@ -2819,7 +2620,6 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou
/*if (source->player->pflags & PF_TAGIT && !(player->pflags & PF_TAGIT)) /*if (source->player->pflags & PF_TAGIT && !(player->pflags & PF_TAGIT))
{ {
P_AddPlayerScore(source->player, 1); //award points to tagger. P_AddPlayerScore(source->player, 1); //award points to tagger.
P_HitDeathMessages(player, inflictor, source);
if (gametype == GT_TAG) //survivor if (gametype == GT_TAG) //survivor
{ {
@ -3509,8 +3309,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
if (player->health < 0) if (player->health < 0)
player->health = 0; player->health = 0;
P_HitDeathMessages(player, inflictor, source);
P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2); P_ForceFeed(player, 40, 10, TICRATE, 40 + min(damage, 100)*2);
} }

View File

@ -68,7 +68,6 @@
// both the head and tail of the thinker list // both the head and tail of the thinker list
extern thinker_t thinkercap; extern thinker_t thinkercap;
extern INT32 runcount;
void P_InitThinkers(void); void P_InitThinkers(void);
void P_AddThinker(thinker_t *thinker); void P_AddThinker(thinker_t *thinker);

View File

@ -4007,7 +4007,8 @@ void P_RecalcPrecipInSector(sector_t *sector)
// //
void P_NullPrecipThinker(precipmobj_t *mobj) void P_NullPrecipThinker(precipmobj_t *mobj)
{ {
(void)mobj; //(void)mobj;
mobj->precipflags &= ~PCF_THUNK;
} }
void P_SnowThinker(precipmobj_t *mobj) void P_SnowThinker(precipmobj_t *mobj)
@ -4027,25 +4028,26 @@ void P_RainThinker(precipmobj_t *mobj)
{ {
// cycle through states, // cycle through states,
// calling action functions at transitions // calling action functions at transitions
if (mobj->tics > 0 && --mobj->tics == 0) if (mobj->tics <= 0)
{ return;
// you can cycle through multiple states in a tic
if (!P_SetPrecipMobjState(mobj, mobj->state->nextstate)) if (--mobj->tics)
return; // freed itself return;
}
if (!P_SetPrecipMobjState(mobj, mobj->state->nextstate))
return;
if (mobj->state != &states[S_RAINRETURN])
return;
mobj->z = mobj->ceilingz;
P_SetPrecipMobjState(mobj, S_RAIN1);
if (mobj->state == &states[S_RAINRETURN])
{
mobj->z = mobj->ceilingz;
P_SetPrecipMobjState(mobj, S_RAIN1);
}
return; return;
} }
// adjust height // adjust height
mobj->z += mobj->momz; if ((mobj->z += mobj->momz) <= mobj->floorz)
if (mobj->z <= mobj->floorz)
{ {
// no splashes on sky or bottomless pits // no splashes on sky or bottomless pits
if (mobj->precipflags & PCF_PIT) if (mobj->precipflags & PCF_PIT)
@ -6637,20 +6639,7 @@ void P_MobjThinker(mobj_t *mobj)
case MT_SSMINE_SHIELD: case MT_SSMINE_SHIELD:
case MT_FAKESHIELD: case MT_FAKESHIELD:
case MT_SINK_SHIELD: case MT_SINK_SHIELD:
/*if (mobj->health > 0 && mobj->target && mobj->target->player if ((mobj->health > 0
&& mobj->target->player->health > 0 && !mobj->target->player->spectator)
{
// Was this so hard? -- Handled this with K_UpdateHnextList instead of thinking it away...
if ((mobj->type == MT_ORBINAUT_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_ORBINAUT)
|| (mobj->type == MT_JAWZ_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_JAWZ)
|| (mobj->movedir > 0 && ((UINT16)mobj->target->player->kartstuff[k_itemamount] < mobj->movedir))
|| (!mobj->target->player->kartstuff[k_itemheld]))
{
P_RemoveMobj(mobj);
return;
}
}
else*/ if ((mobj->health > 0
&& (!mobj->target || !mobj->target->player || mobj->target->player->health <= 0 || mobj->target->player->spectator)) && (!mobj->target || !mobj->target->player || mobj->target->player->health <= 0 || mobj->target->player->spectator))
|| (mobj->health <= 0 && mobj->z <= mobj->floorz) || (mobj->health <= 0 && mobj->z <= mobj->floorz)
|| P_CheckDeathPitCollide(mobj)) // When in death state || P_CheckDeathPitCollide(mobj)) // When in death state
@ -6803,22 +6792,18 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->target && mobj->target->health if (mobj->target && mobj->target->health
&& mobj->target->player && !mobj->target->player->spectator && mobj->target->player && !mobj->target->player->spectator
&& mobj->target->player->health && mobj->target->player->playerstate != PST_DEAD && mobj->target->player->health && mobj->target->player->playerstate != PST_DEAD
&& players[displayplayer].mo && !players[displayplayer].spectator) /*&& players[displayplayer].mo && !players[displayplayer].spectator*/)
{ {
fixed_t scale = mobj->target->scale; fixed_t scale = mobj->target->scale;
mobj->color = mobj->target->color; mobj->color = mobj->target->color;
K_MatchGenericExtraFlags(mobj, mobj->target);
if (G_RaceGametype() if ((G_RaceGametype() || mobj->target->player->kartstuff[k_bumper] <= 0)
|| mobj->target->player == &players[displayplayer]
|| mobj->target->player->kartstuff[k_bumper] <= 0
|| (mobj->target->player->mo->flags2 & MF2_DONTDRAW)
#if 1 // Set to 0 to test without needing to host #if 1 // Set to 0 to test without needing to host
|| !netgame || ((mobj->target->player == &players[displayplayer]) || P_IsLocalPlayer(mobj->target->player))
#endif #endif
) )
mobj->flags2 |= MF2_DONTDRAW; mobj->flags2 |= MF2_DONTDRAW;
else
mobj->flags2 &= ~MF2_DONTDRAW;
P_UnsetThingPosition(mobj); P_UnsetThingPosition(mobj);
mobj->x = mobj->target->x; mobj->x = mobj->target->x;
@ -6838,10 +6823,13 @@ void P_MobjThinker(mobj_t *mobj)
} }
P_SetThingPosition(mobj); P_SetThingPosition(mobj);
scale += FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayer].mo->x-mobj->target->x, if (!splitscreen)
players[displayplayer].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale); {
if (scale > 16*FRACUNIT) scale += FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayer].mo->x-mobj->target->x,
scale = 16*FRACUNIT; players[displayplayer].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale);
if (scale > 16*FRACUNIT)
scale = 16*FRACUNIT;
}
mobj->destscale = scale; mobj->destscale = scale;
if (!mobj->tracer) if (!mobj->tracer)
@ -8249,16 +8237,24 @@ void P_MobjThinker(mobj_t *mobj)
return; return;
} }
P_TeleportMove(mobj, mobj->target->x + P_ReturnThrustX(mobj, mobj->target->angle+ANGLE_180, mobj->target->radius),
mobj->target->y + P_ReturnThrustY(mobj, mobj->target->angle+ANGLE_180, mobj->target->radius), mobj->target->z);
mobj->angle = mobj->target->angle; mobj->angle = mobj->target->angle;
P_TeleportMove(mobj, mobj->target->x + P_ReturnThrustX(mobj, mobj->angle+ANGLE_180, mobj->target->radius),
mobj->target->y + P_ReturnThrustY(mobj, mobj->angle+ANGLE_180, mobj->target->radius), mobj->target->z);
P_SetScale(mobj, mobj->target->scale); P_SetScale(mobj, mobj->target->scale);
if (mobj->target->player)
{ {
if (mobj->target->player->kartstuff[k_sneakertimer] > mobj->movecount) player_t *p = NULL;
P_SetMobjState(mobj, S_BOOSTFLAME); if (mobj->target->target && mobj->target->target->player)
mobj->movecount = mobj->target->player->kartstuff[k_sneakertimer]; p = mobj->target->target->player;
else if (mobj->target->player)
p = mobj->target->player;
if (p)
{
if (p->kartstuff[k_sneakertimer] > mobj->movecount)
P_SetMobjState(mobj, S_BOOSTFLAME);
mobj->movecount = p->kartstuff[k_sneakertimer];
}
} }
if (mobj->state == &states[S_BOOSTSMOKESPAWNER]) if (mobj->state == &states[S_BOOSTSMOKESPAWNER])
@ -8273,7 +8269,7 @@ void P_MobjThinker(mobj_t *mobj)
smoke->momy = mobj->target->momy/2; smoke->momy = mobj->target->momy/2;
smoke->momz = mobj->target->momz/2; smoke->momz = mobj->target->momz/2;
P_Thrust(smoke, mobj->target->angle+FixedAngle(P_RandomRange(135, 225)<<FRACBITS), P_RandomRange(0, 8) * mobj->target->scale); P_Thrust(smoke, mobj->angle+FixedAngle(P_RandomRange(135, 225)<<FRACBITS), P_RandomRange(0, 8) * mobj->target->scale);
} }
break; break;
case MT_SPARKLETRAIL: case MT_SPARKLETRAIL:
@ -8351,6 +8347,39 @@ void P_MobjThinker(mobj_t *mobj)
P_TeleportMove(mobj, destx, desty, mobj->target->z); P_TeleportMove(mobj, destx, desty, mobj->target->z);
break; break;
} }
case MT_ROCKETSNEAKER:
if (!mobj->target || !mobj->target->health)
{
P_RemoveMobj(mobj);
return;
}
if (mobj->target->player && !mobj->target->player->kartstuff[k_rocketsneakertimer])
{
mobj->flags &= ~MF_NOGRAVITY;
mobj->angle += ANGLE_45;
if (!mobj->extravalue2)
{
if (mobj->eflags & MFE_VERTICALFLIP)
mobj->z -= mobj->height;
else
mobj->z += mobj->height;
S_StartSound(mobj, mobj->info->deathsound);
P_SetObjectMomZ(mobj, 8*FRACUNIT, false);
P_InstaThrust(mobj, R_PointToAngle2(mobj->target->x, mobj->target->y, mobj->x, mobj->y)+ANGLE_90, 16*FRACUNIT);
mobj->momx += mobj->target->momx;
mobj->momy += mobj->target->momy;
mobj->momz += mobj->target->momz;
mobj->extravalue2 = 1;
}
else if (P_IsObjectOnGround(mobj))
{
P_RemoveMobj(mobj);
return;
}
}
break;
case MT_KARMAHITBOX: case MT_KARMAHITBOX:
if (!mobj->target || !mobj->target->health || !mobj->target->player || mobj->target->player->spectator if (!mobj->target || !mobj->target->health || !mobj->target->player || mobj->target->player->spectator
|| (G_RaceGametype() || mobj->target->player->kartstuff[k_bumper])) || (G_RaceGametype() || mobj->target->player->kartstuff[k_bumper]))
@ -9339,7 +9368,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
case MT_JAWZ: case MT_JAWZ_DUD: case MT_JAWZ_SHIELD: case MT_JAWZ: case MT_JAWZ_DUD: case MT_JAWZ_SHIELD:
case MT_SSMINE: case MT_SSMINE_SHIELD: case MT_SSMINE: case MT_SSMINE_SHIELD:
case MT_BALLHOG: case MT_SINK: case MT_BALLHOG: case MT_SINK:
case MT_THUNDERSHIELD: case MT_THUNDERSHIELD: case MT_ROCKETSNEAKER:
P_SpawnShadowMobj(mobj); P_SpawnShadowMobj(mobj);
default: default:
break; break;
@ -9545,14 +9574,15 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype
static inline precipmobj_t *P_SpawnRainMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) static inline precipmobj_t *P_SpawnRainMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
{ {
precipmobj_t *mo = P_SpawnPrecipMobj(x,y,z,type); precipmobj_t *mo = P_SpawnPrecipMobj(x,y,z,type);
mo->thinker.function.acp1 = (actionf_p1)P_RainThinker; mo->precipflags |= PCF_RAIN;
//mo->thinker.function.acp1 = (actionf_p1)P_RainThinker;
return mo; return mo;
} }
static inline precipmobj_t *P_SpawnSnowMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) static inline precipmobj_t *P_SpawnSnowMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
{ {
precipmobj_t *mo = P_SpawnPrecipMobj(x,y,z,type); precipmobj_t *mo = P_SpawnPrecipMobj(x,y,z,type);
mo->thinker.function.acp1 = (actionf_p1)P_SnowThinker; //mo->thinker.function.acp1 = (actionf_p1)P_SnowThinker;
return mo; return mo;
} }
@ -9741,13 +9771,12 @@ consvar_t cv_suddendeath = {"suddendeath", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff,
void P_SpawnPrecipitation(void) void P_SpawnPrecipitation(void)
{ {
INT32 i, j, mrand; INT32 i, mrand;
fixed_t basex, basey, x, y, height; fixed_t basex, basey, x, y, height;
subsector_t *precipsector = NULL; subsector_t *precipsector = NULL;
precipmobj_t *rainmo = NULL; precipmobj_t *rainmo = NULL;
if (dedicated || !cv_precipdensity.value || curWeather == PRECIP_NONE if (dedicated || /*!cv_precipdensity*/!cv_drawdist_precip.value || curWeather == PRECIP_NONE) // SRB2Kart
|| netgame) // SRB2Kart
return; return;
// Use the blockmap to narrow down our placing patterns // Use the blockmap to narrow down our placing patterns
@ -9756,7 +9785,7 @@ void P_SpawnPrecipitation(void)
basex = bmaporgx + (i % bmapwidth) * MAPBLOCKSIZE; basex = bmaporgx + (i % bmapwidth) * MAPBLOCKSIZE;
basey = bmaporgy + (i / bmapwidth) * MAPBLOCKSIZE; basey = bmaporgy + (i / bmapwidth) * MAPBLOCKSIZE;
for (j = 0; j < cv_precipdensity.value; ++j) //for (j = 0; j < cv_precipdensity.value; ++j) -- density is 1 for kart always
{ {
x = basex + ((M_RandomKey(MAPBLOCKUNITS<<3)<<FRACBITS)>>3); x = basex + ((M_RandomKey(MAPBLOCKUNITS<<3)<<FRACBITS)>>3);
y = basey + ((M_RandomKey(MAPBLOCKUNITS<<3)<<FRACBITS)>>3); y = basey + ((M_RandomKey(MAPBLOCKUNITS<<3)<<FRACBITS)>>3);
@ -9766,7 +9795,11 @@ void P_SpawnPrecipitation(void)
// No sector? Stop wasting time, // No sector? Stop wasting time,
// move on to the next entry in the blockmap // move on to the next entry in the blockmap
if (!precipsector) if (!precipsector)
break; continue;
// Not in a sector with visible sky?
if (precipsector->sector->ceilingpic != skyflatnum)
continue;
// Exists, but is too small for reasonable precipitation. // Exists, but is too small for reasonable precipitation.
if (!(precipsector->sector->floorheight <= precipsector->sector->ceilingheight - (32<<FRACBITS))) if (!(precipsector->sector->floorheight <= precipsector->sector->ceilingheight - (32<<FRACBITS)))
@ -9777,10 +9810,6 @@ void P_SpawnPrecipitation(void)
if (curWeather == PRECIP_SNOW) if (curWeather == PRECIP_SNOW)
{ {
// Not in a sector with visible sky -- exception for NiGHTS.
if (!(maptol & TOL_NIGHTS) && precipsector->sector->ceilingpic != skyflatnum)
continue;
rainmo = P_SpawnSnowMobj(x, y, height, MT_SNOWFLAKE); rainmo = P_SpawnSnowMobj(x, y, height, MT_SNOWFLAKE);
mrand = M_RandomByte(); mrand = M_RandomByte();
if (mrand < 64) if (mrand < 64)
@ -9789,13 +9818,7 @@ void P_SpawnPrecipitation(void)
P_SetPrecipMobjState(rainmo, S_SNOW2); P_SetPrecipMobjState(rainmo, S_SNOW2);
} }
else // everything else. else // everything else.
{
// Not in a sector with visible sky.
if (precipsector->sector->ceilingpic != skyflatnum)
continue;
rainmo = P_SpawnRainMobj(x, y, height, MT_RAIN); rainmo = P_SpawnRainMobj(x, y, height, MT_RAIN);
}
// Randomly assign a height, now that floorz is set. // Randomly assign a height, now that floorz is set.
rainmo->z = M_RandomRange(rainmo->floorz>>FRACBITS, rainmo->ceilingz>>FRACBITS)<<FRACBITS; rainmo->z = M_RandomRange(rainmo->floorz>>FRACBITS, rainmo->ceilingz>>FRACBITS)<<FRACBITS;
@ -10098,6 +10121,8 @@ void P_SpawnPlayer(INT32 playernum)
continue; continue;
if (!playeringame[i] || players[i].spectator) if (!playeringame[i] || players[i].spectator)
continue; continue;
if (players[i].jointime <= 1) // Prevent splitscreen hosters/joiners from only adding 1 player at a time in empty servers
continue;
pcount++; pcount++;
} }
@ -11239,7 +11264,7 @@ ML_NOCLIMB : Direction not controllable
void P_SpawnHoopsAndRings(mapthing_t *mthing) void P_SpawnHoopsAndRings(mapthing_t *mthing)
{ {
mobj_t *mobj = NULL; mobj_t *mobj = NULL;
INT32 r, i; INT32 /*r,*/ i;
fixed_t x, y, z, finalx, finaly, finalz; fixed_t x, y, z, finalx, finaly, finalz;
sector_t *sec; sector_t *sec;
TVector v, *res; TVector v, *res;
@ -11313,8 +11338,8 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
mobj = P_SpawnMobj(finalx, finaly, finalz, MT_HOOP); mobj = P_SpawnMobj(finalx, finaly, finalz, MT_HOOP);
if (maptol & TOL_XMAS) //if (maptol & TOL_XMAS)
P_SetMobjState(mobj, mobj->info->seestate + (i & 1)); //P_SetMobjState(mobj, mobj->info->seestate + (i & 1));
mobj->z -= mobj->height/2; mobj->z -= mobj->height/2;
P_SetTarget(&mobj->target, hoopcenter); // Link the sprite to the center. P_SetTarget(&mobj->target, hoopcenter); // Link the sprite to the center.
@ -11323,8 +11348,10 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
// Link all the sprites in the hoop together // Link all the sprites in the hoop together
if (nextmobj) if (nextmobj)
{ {
mobj->hprev = nextmobj; P_SetTarget(&mobj->hprev, nextmobj);
mobj->hprev->hnext = mobj; P_SetTarget(&mobj->hprev->hnext, mobj);
//mobj->hprev = nextmobj;
//mobj->hprev->hnext = mobj;
} }
else else
mobj->hprev = mobj->hnext = NULL; mobj->hprev = mobj->hnext = NULL;
@ -11354,8 +11381,10 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
// Link all the collision sprites together. // Link all the collision sprites together.
mobj->hnext = NULL; mobj->hnext = NULL;
mobj->hprev = nextmobj; P_SetTarget(&mobj->hprev, nextmobj);
mobj->hprev->hnext = mobj; P_SetTarget(&mobj->hprev->hnext, mobj);
//mobj->hprev = nextmobj;
//mobj->hprev->hnext = mobj;
nextmobj = mobj; nextmobj = mobj;
} }
@ -11381,8 +11410,10 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
// Link all the collision sprites together. // Link all the collision sprites together.
mobj->hnext = NULL; mobj->hnext = NULL;
mobj->hprev = nextmobj; P_SetTarget(&mobj->hprev, nextmobj);
mobj->hprev->hnext = mobj; P_SetTarget(&mobj->hprev->hnext, mobj);
//mobj->hprev = nextmobj;
//mobj->hprev->hnext = mobj;
nextmobj = mobj; nextmobj = mobj;
} }
@ -11455,8 +11486,8 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
mobj = P_SpawnMobj(finalx, finaly, finalz, MT_HOOP); mobj = P_SpawnMobj(finalx, finaly, finalz, MT_HOOP);
if (maptol & TOL_XMAS) //if (maptol & TOL_XMAS)
P_SetMobjState(mobj, mobj->info->seestate + (i & 1)); //P_SetMobjState(mobj, mobj->info->seestate + (i & 1));
mobj->z -= mobj->height/2; mobj->z -= mobj->height/2;
P_SetTarget(&mobj->target, hoopcenter); // Link the sprite to the center. P_SetTarget(&mobj->target, hoopcenter); // Link the sprite to the center.
@ -11465,8 +11496,10 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
// Link all the sprites in the hoop together // Link all the sprites in the hoop together
if (nextmobj) if (nextmobj)
{ {
mobj->hprev = nextmobj; P_SetTarget(&mobj->hprev, nextmobj);
mobj->hprev->hnext = mobj; P_SetTarget(&mobj->hprev->hnext, mobj);
//mobj->hprev = nextmobj;
//mobj->hprev->hnext = mobj;
} }
else else
mobj->hprev = mobj->hnext = NULL; mobj->hprev = mobj->hnext = NULL;
@ -11507,8 +11540,10 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
// Link all the collision sprites together. // Link all the collision sprites together.
mobj->hnext = NULL; mobj->hnext = NULL;
mobj->hprev = nextmobj; P_SetTarget(&mobj->hprev, nextmobj);
mobj->hprev->hnext = mobj; P_SetTarget(&mobj->hprev->hnext, mobj);
//mobj->hprev = nextmobj;
//mobj->hprev->hnext = mobj;
nextmobj = mobj; nextmobj = mobj;
} }
@ -11516,6 +11551,8 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
return; return;
} }
else return; // srb2kart - no rings or ring-like objects in R1
/*
// Wing logo item. // Wing logo item.
else if (mthing->type == mobjinfo[MT_NIGHTSWING].doomednum) else if (mthing->type == mobjinfo[MT_NIGHTSWING].doomednum)
{ {
@ -11809,7 +11846,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing)
} }
} }
return; return;
} }*/
} }
// //

View File

@ -261,6 +261,10 @@ typedef enum {
PCF_FOF = 4, PCF_FOF = 4,
// Above MOVING FOF (this means we need to keep floorz up to date...) // Above MOVING FOF (this means we need to keep floorz up to date...)
PCF_MOVINGFOF = 8, PCF_MOVINGFOF = 8,
// Is rain.
PCF_RAIN = 16,
// Ran the thinker this tic.
PCF_THUNK = 32,
} precipflag_t; } precipflag_t;
// Map Object definition. // Map Object definition.
typedef struct mobj_s typedef struct mobj_s

View File

@ -968,6 +968,7 @@ typedef enum
tc_bouncecheese, tc_bouncecheese,
tc_startcrumble, tc_startcrumble,
tc_marioblock, tc_marioblock,
tc_marioblockchecker,
tc_spikesector, tc_spikesector,
tc_floatsector, tc_floatsector,
tc_bridgethinker, tc_bridgethinker,
@ -1283,7 +1284,10 @@ static void SaveSpecialLevelThinker(const thinker_t *th, const UINT8 type)
size_t i; size_t i;
WRITEUINT8(save_p, type); WRITEUINT8(save_p, type);
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
{
WRITEFIXED(save_p, ht->vars[i]); //var[16] WRITEFIXED(save_p, ht->vars[i]); //var[16]
WRITEFIXED(save_p, ht->var2s[i]); //var[16]
}
WRITEUINT32(save_p, SaveLine(ht->sourceline)); WRITEUINT32(save_p, SaveLine(ht->sourceline));
WRITEUINT32(save_p, SaveSector(ht->sector)); WRITEUINT32(save_p, SaveSector(ht->sector));
} }
@ -1685,8 +1689,7 @@ static void P_NetArchiveThinkers(void)
for (th = thinkercap.next; th != &thinkercap; th = th->next) for (th = thinkercap.next; th != &thinkercap; th = th->next)
{ {
if (!(th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed if (!(th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed
|| th->function.acp1 == (actionf_p1)P_RainThinker || th->function.acp1 == (actionf_p1)P_NullPrecipThinker))
|| th->function.acp1 == (actionf_p1)P_SnowThinker))
numsaved++; numsaved++;
if (th->function.acp1 == (actionf_p1)P_MobjThinker) if (th->function.acp1 == (actionf_p1)P_MobjThinker)
@ -1695,8 +1698,7 @@ static void P_NetArchiveThinkers(void)
continue; continue;
} }
#ifdef PARANOIA #ifdef PARANOIA
else if (th->function.acp1 == (actionf_p1)P_RainThinker else if (th->function.acp1 == (actionf_p1)P_NullPrecipThinker);
|| th->function.acp1 == (actionf_p1)P_SnowThinker);
#endif #endif
else if (th->function.acp1 == (actionf_p1)T_MoveCeiling) else if (th->function.acp1 == (actionf_p1)T_MoveCeiling)
{ {
@ -1798,6 +1800,11 @@ static void P_NetArchiveThinkers(void)
SaveSpecialLevelThinker(th, tc_marioblock); SaveSpecialLevelThinker(th, tc_marioblock);
continue; continue;
} }
else if (th->function.acp1 == (actionf_p1)T_MarioBlockChecker)
{
SaveSpecialLevelThinker(th, tc_marioblockchecker);
continue;
}
else if (th->function.acp1 == (actionf_p1)T_SpikeSector) else if (th->function.acp1 == (actionf_p1)T_SpikeSector)
{ {
SaveSpecialLevelThinker(th, tc_spikesector); SaveSpecialLevelThinker(th, tc_spikesector);
@ -2189,7 +2196,10 @@ static void LoadSpecialLevelThinker(actionf_p1 thinker, UINT8 floorOrCeiling)
size_t i; size_t i;
ht->thinker.function.acp1 = thinker; ht->thinker.function.acp1 = thinker;
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
{
ht->vars[i] = READFIXED(save_p); //var[16] ht->vars[i] = READFIXED(save_p); //var[16]
ht->var2s[i] = READFIXED(save_p); //var[16]
}
ht->sourceline = LoadLine(READUINT32(save_p)); ht->sourceline = LoadLine(READUINT32(save_p));
ht->sector = LoadSector(READUINT32(save_p)); ht->sector = LoadSector(READUINT32(save_p));
@ -2762,6 +2772,10 @@ static void P_NetUnArchiveThinkers(void)
LoadSpecialLevelThinker((actionf_p1)T_MarioBlock, 3); LoadSpecialLevelThinker((actionf_p1)T_MarioBlock, 3);
break; break;
case tc_marioblockchecker:
LoadSpecialLevelThinker((actionf_p1)T_MarioBlockChecker, 0);
break;
case tc_spikesector: case tc_spikesector:
LoadSpecialLevelThinker((actionf_p1)T_SpikeSector, 0); LoadSpecialLevelThinker((actionf_p1)T_SpikeSector, 0);
break; break;
@ -3273,6 +3287,7 @@ static void P_NetArchiveMisc(void)
WRITEUINT32(save_p, spbincoming); WRITEUINT32(save_p, spbincoming);
WRITEUINT8(save_p, spbplayer); WRITEUINT8(save_p, spbplayer);
WRITEUINT32(save_p, mapreset); WRITEUINT32(save_p, mapreset);
WRITEUINT8(save_p, nospectategrief);
// Is it paused? // Is it paused?
if (paused) if (paused)
@ -3379,6 +3394,7 @@ static inline boolean P_NetUnArchiveMisc(void)
spbincoming = READUINT32(save_p); spbincoming = READUINT32(save_p);
spbplayer = READUINT8(save_p); spbplayer = READUINT8(save_p);
mapreset = READUINT32(save_p); mapreset = READUINT32(save_p);
nospectategrief = READUINT8(save_p);
// Is it paused? // Is it paused?
if (READUINT8(save_p) == 0x2f) if (READUINT8(save_p) == 0x2f)

View File

@ -2209,7 +2209,7 @@ static void P_LevelInitStuff(void)
players[i].lives = cv_startinglives.value; players[i].lives = cv_startinglives.value;
} }
#else #else
players[i].lives = 1; players[i].lives = 1; // SRB2Kart
#endif #endif
players[i].realtime = countdown = countdown2 = 0; players[i].realtime = countdown = countdown2 = 0;
@ -2782,7 +2782,6 @@ boolean P_SetupLevel(boolean skipprecip)
P_CreateBlockMap(); // Graue 02-29-2004 P_CreateBlockMap(); // Graue 02-29-2004
P_LoadSideDefs2(lastloadedmaplumpnum + ML_SIDEDEFS); P_LoadSideDefs2(lastloadedmaplumpnum + ML_SIDEDEFS);
R_MakeColormaps();
P_LoadLineDefs2(); P_LoadLineDefs2();
P_LoadSubsectors(lastloadedmaplumpnum + ML_SSECTORS); P_LoadSubsectors(lastloadedmaplumpnum + ML_SSECTORS);
P_LoadNodes(lastloadedmaplumpnum + ML_NODES); P_LoadNodes(lastloadedmaplumpnum + ML_NODES);
@ -3027,6 +3026,7 @@ boolean P_SetupLevel(boolean skipprecip)
spbincoming = 0; spbincoming = 0;
spbplayer = 0; spbplayer = 0;
mapreset = 0; mapreset = 0;
nospectategrief = 0;
// clear special respawning que // clear special respawning que
iquehead = iquetail = 0; iquehead = iquetail = 0;

View File

@ -36,6 +36,7 @@
#include "lua_hook.h" // LUAh_LinedefExecute #include "lua_hook.h" // LUAh_LinedefExecute
#include "k_kart.h" // SRB2kart #include "k_kart.h" // SRB2kart
#include "console.h" // CON_LogMessage
#ifdef HW3SOUND #ifdef HW3SOUND
#include "hardware/hw3sound.h" #include "hardware/hw3sound.h"
@ -2056,8 +2057,7 @@ void P_SwitchWeather(INT32 weathernum)
for (think = thinkercap.next; think != &thinkercap; think = think->next) for (think = thinkercap.next; think != &thinkercap; think = think->next)
{ {
if ((think->function.acp1 != (actionf_p1)P_SnowThinker) if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker)
&& (think->function.acp1 != (actionf_p1)P_RainThinker))
continue; // not a precipmobj thinker continue; // not a precipmobj thinker
precipmobj = (precipmobj_t *)think; precipmobj = (precipmobj_t *)think;
@ -2073,14 +2073,12 @@ void P_SwitchWeather(INT32 weathernum)
for (think = thinkercap.next; think != &thinkercap; think = think->next) for (think = thinkercap.next; think != &thinkercap; think = think->next)
{ {
if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker)
continue; // not a precipmobj thinker
precipmobj = (precipmobj_t *)think;
if (swap == PRECIP_RAIN) // Snow To Rain if (swap == PRECIP_RAIN) // Snow To Rain
{ {
if (!(think->function.acp1 == (actionf_p1)P_SnowThinker
|| think->function.acp1 == (actionf_p1)P_NullPrecipThinker))
continue; // not a precipmobj thinker
precipmobj = (precipmobj_t *)think;
precipmobj->flags = mobjinfo[MT_RAIN].flags; precipmobj->flags = mobjinfo[MT_RAIN].flags;
st = &states[mobjinfo[MT_RAIN].spawnstate]; st = &states[mobjinfo[MT_RAIN].spawnstate];
precipmobj->state = st; precipmobj->state = st;
@ -2091,18 +2089,13 @@ void P_SwitchWeather(INT32 weathernum)
precipmobj->precipflags &= ~PCF_INVISIBLE; precipmobj->precipflags &= ~PCF_INVISIBLE;
think->function.acp1 = (actionf_p1)P_RainThinker; precipmobj->precipflags |= PCF_RAIN;
//think->function.acp1 = (actionf_p1)P_RainThinker;
} }
else if (swap == PRECIP_SNOW) // Rain To Snow else if (swap == PRECIP_SNOW) // Rain To Snow
{ {
INT32 z; INT32 z;
if (!(think->function.acp1 == (actionf_p1)P_RainThinker
|| think->function.acp1 == (actionf_p1)P_NullPrecipThinker))
continue; // not a precipmobj thinker
precipmobj = (precipmobj_t *)think;
precipmobj->flags = mobjinfo[MT_SNOWFLAKE].flags; precipmobj->flags = mobjinfo[MT_SNOWFLAKE].flags;
z = M_RandomByte(); z = M_RandomByte();
@ -2120,19 +2113,13 @@ void P_SwitchWeather(INT32 weathernum)
precipmobj->frame = st->frame; precipmobj->frame = st->frame;
precipmobj->momz = mobjinfo[MT_SNOWFLAKE].speed; precipmobj->momz = mobjinfo[MT_SNOWFLAKE].speed;
precipmobj->precipflags &= ~PCF_INVISIBLE; precipmobj->precipflags &= ~(PCF_INVISIBLE|PCF_RAIN);
think->function.acp1 = (actionf_p1)P_SnowThinker; //think->function.acp1 = (actionf_p1)P_SnowThinker;
} }
else if (swap == PRECIP_BLANK || swap == PRECIP_STORM_NORAIN) // Remove precip, but keep it around for reuse. else if (swap == PRECIP_BLANK || swap == PRECIP_STORM_NORAIN) // Remove precip, but keep it around for reuse.
{ {
if (!(think->function.acp1 == (actionf_p1)P_RainThinker //think->function.acp1 = (actionf_p1)P_NullPrecipThinker;
|| think->function.acp1 == (actionf_p1)P_SnowThinker))
continue;
precipmobj = (precipmobj_t *)think;
think->function.acp1 = (actionf_p1)P_NullPrecipThinker;
precipmobj->precipflags |= PCF_INVISIBLE; precipmobj->precipflags |= PCF_INVISIBLE;
} }
@ -4036,7 +4023,7 @@ DoneSection2:
player->kartstuff[k_floorboost] = 3; player->kartstuff[k_floorboost] = 3;
else else
player->kartstuff[k_floorboost] = 2; player->kartstuff[k_floorboost] = 2;
K_DoSneaker(player, false); K_DoSneaker(player, 0);
} }
break; break;
@ -4215,15 +4202,8 @@ DoneSection2:
if (player->pflags & PF_NIGHTSMODE) if (player->pflags & PF_NIGHTSMODE)
player->drillmeter += 48*20; player->drillmeter += 48*20;
if (netgame) if (netgame && player->laps >= (UINT8)cv_numlaps.value)
{ CON_LogMessage(va(M_GetText("%s has finished the race.\n"), player_names[player-players]));
if (player->laps >= (UINT8)cv_numlaps.value)
CONS_Printf(M_GetText("%s has finished the race.\n"), player_names[player-players]);
else if (player->laps == (UINT8)(cv_numlaps.value - 1))
CONS_Printf("%s started the final lap\n", player_names[player-players]);
else
CONS_Printf(M_GetText("%s started lap %u\n"), player_names[player-players], (UINT32)player->laps+1);
}
// SRB2Kart: save best lap for record attack // SRB2Kart: save best lap for record attack
if (player == &players[consoleplayer]) if (player == &players[consoleplayer])
@ -4249,12 +4229,23 @@ DoneSection2:
S_StartSound(NULL, sfx_s221); S_StartSound(NULL, sfx_s221);
} }
//
//player->starpostangle = player->starposttime = player->starpostnum = 0; //player->starpostangle = player->starposttime = player->starpostnum = 0;
//player->starpostx = player->starposty = player->starpostz = 0; //player->starpostx = player->starposty = player->starpostz = 0;
// Play the starpost sound for 'consistency' // Play the starpost sound for 'consistency'
// S_StartSound(player->mo, sfx_strpst); // S_StartSound(player->mo, sfx_strpst);
// Figure out how many are playing on the last lap, to prevent spectate griefing
if (!nospectategrief && player->laps >= (UINT8)(cv_numlaps.value - 1))
{
UINT8 i;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
continue;
nospectategrief++;
}
}
} }
else if (player->starpostnum) else if (player->starpostnum)
{ {

View File

@ -57,12 +57,12 @@ void Command_Numthinkers_f(void)
CONS_Printf(M_GetText("numthinkers <#>: Count number of thinkers\n")); CONS_Printf(M_GetText("numthinkers <#>: Count number of thinkers\n"));
CONS_Printf( CONS_Printf(
"\t1: P_MobjThinker\n" "\t1: P_MobjThinker\n"
"\t2: P_RainThinker\n" /*"\t2: P_RainThinker\n"
"\t3: P_SnowThinker\n" "\t3: P_SnowThinker\n"*/
"\t4: P_NullPrecipThinker\n" "\t2: P_NullPrecipThinker\n"
"\t5: T_Friction\n" "\t3: T_Friction\n"
"\t6: T_Pusher\n" "\t4: T_Pusher\n"
"\t7: P_RemoveThinkerDelayed\n"); "\t5: P_RemoveThinkerDelayed\n");
return; return;
} }
@ -74,27 +74,27 @@ void Command_Numthinkers_f(void)
action = (actionf_p1)P_MobjThinker; action = (actionf_p1)P_MobjThinker;
CONS_Printf(M_GetText("Number of %s: "), "P_MobjThinker"); CONS_Printf(M_GetText("Number of %s: "), "P_MobjThinker");
break; break;
case 2: /*case 2:
action = (actionf_p1)P_RainThinker; action = (actionf_p1)P_RainThinker;
CONS_Printf(M_GetText("Number of %s: "), "P_RainThinker"); CONS_Printf(M_GetText("Number of %s: "), "P_RainThinker");
break; break;
case 3: case 3:
action = (actionf_p1)P_SnowThinker; action = (actionf_p1)P_SnowThinker;
CONS_Printf(M_GetText("Number of %s: "), "P_SnowThinker"); CONS_Printf(M_GetText("Number of %s: "), "P_SnowThinker");
break; break;*/
case 4: case 2:
action = (actionf_p1)P_NullPrecipThinker; action = (actionf_p1)P_NullPrecipThinker;
CONS_Printf(M_GetText("Number of %s: "), "P_NullPrecipThinker"); CONS_Printf(M_GetText("Number of %s: "), "P_NullPrecipThinker");
break; break;
case 5: case 3:
action = (actionf_p1)T_Friction; action = (actionf_p1)T_Friction;
CONS_Printf(M_GetText("Number of %s: "), "T_Friction"); CONS_Printf(M_GetText("Number of %s: "), "T_Friction");
break; break;
case 6: case 4:
action = (actionf_p1)T_Pusher; action = (actionf_p1)T_Pusher;
CONS_Printf(M_GetText("Number of %s: "), "T_Pusher"); CONS_Printf(M_GetText("Number of %s: "), "T_Pusher");
break; break;
case 7: case 5:
action = (actionf_p1)P_RemoveThinkerDelayed; action = (actionf_p1)P_RemoveThinkerDelayed;
CONS_Printf(M_GetText("Number of %s: "), "P_RemoveThinkerDelayed"); CONS_Printf(M_GetText("Number of %s: "), "P_RemoveThinkerDelayed");
break; break;

View File

@ -45,6 +45,7 @@
// SRB2kart // SRB2kart
#include "m_cond.h" // M_UpdateUnlockablesAndExtraEmblems #include "m_cond.h" // M_UpdateUnlockablesAndExtraEmblems
#include "k_kart.h" #include "k_kart.h"
#include "console.h" // CON_LogMessage
#ifdef HW3SOUND #ifdef HW3SOUND
#include "hardware/hw3sound.h" #include "hardware/hw3sound.h"
@ -1139,34 +1140,57 @@ boolean P_EndingMusic(player_t *player)
{ {
char buffer[9]; char buffer[9];
boolean looping = true; boolean looping = true;
INT32 bestlocalpos;
player_t *bestlocalplayer;
if (!P_IsLocalPlayer(player)) // Only applies to a local player if (!P_IsLocalPlayer(player)) // Only applies to a local player
return false; return false;
// Event - Level Finish // Event - Level Finish
if (splitscreen // Check for if this is valid or not
&& (players[displayplayer].exiting if (splitscreen)
|| players[secondarydisplayplayer].exiting
|| ((splitscreen < 2) && players[thirddisplayplayer].exiting)
|| ((splitscreen < 3) && players[fourthdisplayplayer].exiting)))
{ {
sprintf(buffer, "k*ok"); if (!((players[displayplayer].exiting || (players[displayplayer].pflags & PF_TIMEOVER))
|| (players[secondarydisplayplayer].exiting || (players[secondarydisplayplayer].pflags & PF_TIMEOVER))
|| ((splitscreen < 2) && (players[thirddisplayplayer].exiting || (players[thirddisplayplayer].pflags & PF_TIMEOVER)))
|| ((splitscreen < 3) && (players[fourthdisplayplayer].exiting || (players[fourthdisplayplayer].pflags & PF_TIMEOVER)))))
return false;
bestlocalplayer = &players[displayplayer];
bestlocalpos = ((players[displayplayer].pflags & PF_TIMEOVER) ? MAXPLAYERS+1 : players[displayplayer].kartstuff[k_position]);
#define setbests(p) \
if (((players[p].pflags & PF_TIMEOVER) ? MAXPLAYERS+1 : players[p].kartstuff[k_position]) < bestlocalpos) \
{ \
bestlocalplayer = &players[p]; \
bestlocalpos = ((players[p].pflags & PF_TIMEOVER) ? MAXPLAYERS+1 : players[p].kartstuff[k_position]); \
} }
else if (player->pflags & PF_TIMEOVER) // || !player->lives) -- outta lives, outta time setbests(secondarydisplayplayer);
{ if (splitscreen > 1)
sprintf(buffer, "k*lose"); setbests(thirddisplayplayer);
if (splitscreen > 2)
setbests(fourthdisplayplayer);
#undef setbests
} }
else if (player->exiting) else
{ {
if (player->kartstuff[k_position] == 1) if (!(player->exiting || (player->pflags & PF_TIMEOVER)))
return false;
bestlocalplayer = player;
bestlocalpos = ((player->pflags & PF_TIMEOVER) ? MAXPLAYERS+1 : player->kartstuff[k_position]);
}
if (G_RaceGametype() && bestlocalpos == MAXPLAYERS+1)
sprintf(buffer, "k*lose"); // krfail, for eventual F-Zero death results theme
else
{
if (bestlocalpos == 1)
sprintf(buffer, "k*win"); sprintf(buffer, "k*win");
else if (K_IsPlayerLosing(player)) else if (K_IsPlayerLosing(bestlocalplayer))
sprintf(buffer, "k*lose"); sprintf(buffer, "k*lose");
else else
sprintf(buffer, "k*ok"); sprintf(buffer, "k*ok");
} }
else
return false;
S_SpeedMusic(1.0f); S_SpeedMusic(1.0f);
@ -8143,11 +8167,17 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
subsector_t *newsubsec; subsector_t *newsubsec;
fixed_t f1, f2; fixed_t f1, f2;
// We probably shouldn't move the camera if there is no player or player mobj somehow
if (!player || !player->mo)
return true;
mo = player->mo;
#ifdef NOCLIPCAM #ifdef NOCLIPCAM
cameranoclip = true; // We like camera noclip! cameranoclip = true; // We like camera noclip!
#else #else
cameranoclip = ((player->pflags & (PF_NOCLIP|PF_NIGHTSMODE)) cameranoclip = ((player->pflags & (PF_NOCLIP|PF_NIGHTSMODE))
|| (player->mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)) // Noclipping player camera noclips too!! || (mo->flags & (MF_NOCLIP|MF_NOCLIPHEIGHT)) // Noclipping player camera noclips too!!
|| (leveltime < introtime)); // Kart intro cam || (leveltime < introtime)); // Kart intro cam
#endif #endif
@ -8180,7 +8210,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
else if (player == &players[fourthdisplayplayer]) else if (player == &players[fourthdisplayplayer])
focusangle = localangle4; focusangle = localangle4;
else else
focusangle = player->mo->angle; focusangle = mo->angle;
if (thiscam == &camera) if (thiscam == &camera)
camrotate = cv_cam_rotate.value; camrotate = cv_cam_rotate.value;
else if (thiscam == &camera2) else if (thiscam == &camera2)
@ -8201,25 +8231,17 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
return true; return true;
} }
if (!player || !player->mo)
return true;
mo = player->mo;
thiscam->radius = FixedMul(20*FRACUNIT, mapheaderinfo[gamemap-1]->mobj_scale); thiscam->radius = FixedMul(20*FRACUNIT, mapheaderinfo[gamemap-1]->mobj_scale);
thiscam->height = FixedMul(16*FRACUNIT, mapheaderinfo[gamemap-1]->mobj_scale); thiscam->height = FixedMul(16*FRACUNIT, mapheaderinfo[gamemap-1]->mobj_scale);
if (!mo)
return true;
// Don't run while respawning from a starpost // Don't run while respawning from a starpost
// Inu 4/8/13 Why not?! // Inu 4/8/13 Why not?!
// if (leveltime > 0 && timeinmap <= 0) // if (leveltime > 0 && timeinmap <= 0)
// return true; // return true;
if (player->pflags & PF_NIGHTSMODE) if (demoplayback)
{ {
focusangle = player->mo->angle; focusangle = mo->angle;
focusaiming = 0; focusaiming = 0;
} }
else if (player == &players[consoleplayer]) else if (player == &players[consoleplayer])
@ -8244,7 +8266,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
} }
else else
{ {
focusangle = player->mo->angle; focusangle = mo->angle;
focusaiming = player->aiming; focusaiming = player->aiming;
} }
@ -8324,9 +8346,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
input = InvAngle(input); input = InvAngle(input);
angle = thiscam->angle + input; angle = thiscam->angle + input;
if (demoplayback && player == &players[consoleplayer])
localangle = angle;
} }
if (!resetcalled && (leveltime > starttime) if (!resetcalled && (leveltime > starttime)
@ -8732,7 +8751,7 @@ boolean P_SpectatorJoinGame(player_t *player)
if (P_IsLocalPlayer(player) && displayplayer != consoleplayer) if (P_IsLocalPlayer(player) && displayplayer != consoleplayer)
displayplayer = consoleplayer; displayplayer = consoleplayer;
CONS_Printf(M_GetText("%s entered the game.\n"), player_names[player-players]); CON_LogMessage(va(M_GetText("%s entered the game.\n"), player_names[player-players]));
return true; // no more player->mo, cannot continue. return true; // no more player->mo, cannot continue.
} }
return false; return false;
@ -8909,8 +8928,6 @@ void P_DoTimeOver(player_t *player)
// P_PlayerThink // P_PlayerThink
// //
boolean playerdeadview; // show match/chaos/tag/capture the flag rankings while in death view
void P_PlayerThink(player_t *player) void P_PlayerThink(player_t *player)
{ {
ticcmd_t *cmd; ticcmd_t *cmd;
@ -8937,7 +8954,7 @@ void P_PlayerThink(player_t *player)
} }
#ifdef SEENAMES #ifdef SEENAMES
if (netgame && player == &players[displayplayer] && !(leveltime % (TICRATE/5))) if (netgame && player == &players[displayplayer] && !(leveltime % (TICRATE/5)) && !splitscreen)
{ {
seenplayer = NULL; seenplayer = NULL;
@ -9093,10 +9110,6 @@ void P_PlayerThink(player_t *player)
if (player->playerstate == PST_DEAD) if (player->playerstate == PST_DEAD)
{ {
player->mo->flags2 &= ~MF2_SHADOW; player->mo->flags2 &= ~MF2_SHADOW;
// show the multiplayer rankings while dead
if (player == &players[displayplayer])
playerdeadview = true;
P_DeathThink(player); P_DeathThink(player);
return; return;
@ -9121,9 +9134,6 @@ void P_PlayerThink(player_t *player)
player->lives = 1; // SRB2Kart player->lives = 1; // SRB2Kart
#endif #endif
if (player == &players[displayplayer])
playerdeadview = false;
// SRB2kart 010217 // SRB2kart 010217
if (leveltime < starttime) if (leveltime < starttime)
player->powers[pw_nocontrol] = 2; player->powers[pw_nocontrol] = 2;
@ -9158,10 +9168,10 @@ void P_PlayerThink(player_t *player)
} }
} }
if ((netgame || splitscreen) && player->spectator && cmd->buttons & BT_ATTACK && !player->powers[pw_flashing]) if ((netgame || multiplayer) && player->spectator && cmd->buttons & BT_ATTACK && !player->powers[pw_flashing])
{ {
player->pflags ^= PF_WANTSTOJOIN; player->pflags ^= PF_WANTSTOJOIN;
//player->powers[pw_flashing] = TICRATE + 1; player->powers[pw_flashing] = TICRATE/2 + 1;
/*if (P_SpectatorJoinGame(player)) /*if (P_SpectatorJoinGame(player))
return; // player->mo was removed.*/ return; // player->mo was removed.*/
} }

View File

@ -476,40 +476,22 @@ void R_LoadTextures(void)
} }
else else
{ {
UINT16 patchcount = 1;
//CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),patchlump->width, patchlump->height); //CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),patchlump->width, patchlump->height);
if (SHORT(patchlump->width) == 64 texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL);
&& SHORT(patchlump->height) == 64)
{ // 64x64 patch
const column_t *column;
for (k = 0; k < SHORT(patchlump->width); k++)
{ // Find use of transparency.
column = (const column_t *)((const UINT8 *)patchlump + LONG(patchlump->columnofs[k]));
if (column->length != SHORT(patchlump->height))
break;
}
if (k == SHORT(patchlump->width))
patchcount = 2; // No transparency? 64x128 texture.
}
texture = textures[i] = Z_Calloc(sizeof(texture_t) + (sizeof(texpatch_t) * patchcount), PU_STATIC, NULL);
// Set texture properties. // Set texture properties.
M_Memcpy(texture->name, W_CheckNameForNumPwad((UINT16)w, texstart + j), sizeof(texture->name)); M_Memcpy(texture->name, W_CheckNameForNumPwad((UINT16)w, texstart + j), sizeof(texture->name));
texture->width = SHORT(patchlump->width); texture->width = SHORT(patchlump->width);
texture->height = SHORT(patchlump->height)*patchcount; texture->height = SHORT(patchlump->height);
texture->patchcount = patchcount; texture->patchcount = 1;
texture->holes = false; texture->holes = false;
// Allocate information for the texture's patches. // Allocate information for the texture's patches.
for (k = 0; k < patchcount; k++) patch = &texture->patches[0];
{
patch = &texture->patches[k];
patch->originx = 0; patch->originx = patch->originy = 0;
patch->originy = (INT16)(k*patchlump->height); patch->wad = (UINT16)w;
patch->wad = (UINT16)w; patch->lump = texstart + j;
patch->lump = texstart + j;
}
Z_Unlock(patchlump); Z_Unlock(patchlump);
@ -1071,9 +1053,6 @@ void R_ReInitColormaps(UINT16 num, lumpnum_t newencoremap)
static lumpnum_t foundcolormaps[MAXCOLORMAPS]; static lumpnum_t foundcolormaps[MAXCOLORMAPS];
static char colormapFixingArray[MAXCOLORMAPS][3][9];
static size_t carrayindex;
// //
// R_ClearColormaps // R_ClearColormaps
// //
@ -1085,8 +1064,6 @@ void R_ClearColormaps(void)
num_extra_colormaps = 0; num_extra_colormaps = 0;
carrayindex = 0;
for (i = 0; i < MAXCOLORMAPS; i++) for (i = 0; i < MAXCOLORMAPS; i++)
foundcolormaps[i] = LUMPERROR; foundcolormaps[i] = LUMPERROR;
@ -1140,10 +1117,20 @@ static double deltas[256][3], map[256][3];
static UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b); static UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b);
static int RoundUp(double number); static int RoundUp(double number);
#ifdef HASINVERT
void R_MakeInvertmap(void)
{
size_t i;
for (i = 0; i < 256; i++)
invertmap[i] = NearestColor(256 - pLocalPalette[i].s.red, 256 - pLocalPalette[i].s.green, 256 - pLocalPalette[i].s.blue);
}
#endif
INT32 R_CreateColormap(char *p1, char *p2, char *p3) INT32 R_CreateColormap(char *p1, char *p2, char *p3)
{ {
double cmaskr, cmaskg, cmaskb, cdestr, cdestg, cdestb; double cmaskr, cmaskg, cmaskb, cdestr, cdestg, cdestb;
double r, g, b, cbrightness, maskamt = 0, othermask = 0; double maskamt = 0, othermask = 0;
int mask, fog = 0; int mask, fog = 0;
size_t mapnum = num_extra_colormaps; size_t mapnum = num_extra_colormaps;
size_t i; size_t i;
@ -1206,7 +1193,7 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3)
fadedist = fadeend - fadestart; fadedist = fadeend - fadestart;
fog = NUMFROMCHAR(p2[1]); fog = NUMFROMCHAR(p2[1]);
} }
#undef getnum #undef NUMFROMCHAR
if (p3[0] == '#') if (p3[0] == '#')
{ {
@ -1249,14 +1236,30 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3)
if (num_extra_colormaps == MAXCOLORMAPS) if (num_extra_colormaps == MAXCOLORMAPS)
I_Error("R_CreateColormap: Too many colormaps! the limit is %d\n", MAXCOLORMAPS); I_Error("R_CreateColormap: Too many colormaps! the limit is %d\n", MAXCOLORMAPS);
strncpy(colormapFixingArray[num_extra_colormaps][0], p1, 8);
strncpy(colormapFixingArray[num_extra_colormaps][1], p2, 8);
strncpy(colormapFixingArray[num_extra_colormaps][2], p3, 8);
num_extra_colormaps++; num_extra_colormaps++;
foundcolormaps[mapnum] = LUMPERROR;
// aligned on 8 bit for asm code
extra_colormaps[mapnum].colormap = NULL;
extra_colormaps[mapnum].maskcolor = (UINT16)maskcolor;
extra_colormaps[mapnum].fadecolor = (UINT16)fadecolor;
extra_colormaps[mapnum].maskamt = maskamt;
extra_colormaps[mapnum].fadestart = (UINT16)fadestart;
extra_colormaps[mapnum].fadeend = (UINT16)fadeend;
extra_colormaps[mapnum].fog = fog;
if (rendermode == render_soft) if (rendermode == render_soft)
{ {
double r, g, b, cbrightness;
int p;
lighttable_t *colormap_p;
// Initialise the map and delta arrays
// map[i] stores an RGB color (as double) for index i,
// which is then converted to SRB2's palette later
// deltas[i] stores a corresponding fade delta between the RGB color and the final fade color;
// map[i]'s values are decremented by after each use
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
{ {
r = pLocalPalette[i].s.red; r = pLocalPalette[i].s.red;
@ -1279,199 +1282,13 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3)
map[i][2] = 255.0l; map[i][2] = 255.0l;
deltas[i][2] = (map[i][2] - cdestb) / (double)fadedist; deltas[i][2] = (map[i][2] - cdestb) / (double)fadedist;
} }
}
foundcolormaps[mapnum] = LUMPERROR; // Now allocate memory for the actual colormap array itself!
// aligned on 8 bit for asm code
extra_colormaps[mapnum].colormap = NULL;
extra_colormaps[mapnum].maskcolor = (UINT16)maskcolor;
extra_colormaps[mapnum].fadecolor = (UINT16)fadecolor;
extra_colormaps[mapnum].maskamt = maskamt;
extra_colormaps[mapnum].fadestart = (UINT16)fadestart;
extra_colormaps[mapnum].fadeend = (UINT16)fadeend;
extra_colormaps[mapnum].fog = fog;
return (INT32)mapnum;
}
void R_MakeColormaps(void)
{
size_t i;
carrayindex = num_extra_colormaps;
num_extra_colormaps = 0;
for (i = 0; i < carrayindex; i++)
R_CreateColormap2(colormapFixingArray[i][0], colormapFixingArray[i][1],
colormapFixingArray[i][2]);
}
#ifdef HASINVERT
void R_MakeInvertmap(void)
{
size_t i;
for (i = 0; i < 256; i++)
invertmap[i] = NearestColor(256 - pLocalPalette[i].s.red, 256 - pLocalPalette[i].s.green, 256 - pLocalPalette[i].s.blue);
}
#endif
void R_CreateColormap2(char *p1, char *p2, char *p3)
{
double cmaskr, cmaskg, cmaskb, cdestr, cdestg, cdestb;
double r, g, b, cbrightness;
double maskamt = 0, othermask = 0;
INT32 mask, p, fog = 0;
size_t mapnum = num_extra_colormaps;
size_t i;
lighttable_t *colormap_p, *colormap_p2;
UINT32 cr, cg, cb, maskcolor, fadecolor;
UINT32 fadestart = 0, fadeend = 31, fadedist = 31;
#define HEX2INT(x) (UINT32)(x >= '0' && x <= '9' ? x - '0' : x >= 'a' && x <= 'f' ? x - 'a' + 10 : x >= 'A' && x <= 'F' ? x - 'A' + 10 : 0)
if (p1[0] == '#')
{
cr = ((HEX2INT(p1[1]) * 16) + HEX2INT(p1[2]));
cg = ((HEX2INT(p1[3]) * 16) + HEX2INT(p1[4]));
cb = ((HEX2INT(p1[5]) * 16) + HEX2INT(p1[6]));
if (encoremap)
{
i = encoremap[NearestColor((UINT8)cr, (UINT8)cg, (UINT8)cb)];
cr = pLocalPalette[i].s.red;
cg = pLocalPalette[i].s.green;
cb = pLocalPalette[i].s.blue;
}
cmaskr = cr;
cmaskg = cg;
cmaskb = cb;
// Create a rough approximation of the color (a 16 bit color)
maskcolor = ((cb) >> 3) + (((cg) >> 2) << 5) + (((cr) >> 3) << 11);
if (p1[7] >= 'a' && p1[7] <= 'z')
mask = (p1[7] - 'a');
else if (p1[7] >= 'A' && p1[7] <= 'Z')
mask = (p1[7] - 'A');
else
mask = 24;
maskamt = (double)(mask/24.0l);
othermask = 1 - maskamt;
maskamt /= 0xff;
cmaskr *= maskamt;
cmaskg *= maskamt;
cmaskb *= maskamt;
}
else
{
cmaskr = cmaskg = cmaskb = 0xff;
maskamt = 0;
maskcolor = ((0xff) >> 3) + (((0xff) >> 2) << 5) + (((0xff) >> 3) << 11);
}
#define NUMFROMCHAR(c) (c >= '0' && c <= '9' ? c - '0' : 0)
if (p2[0] == '#')
{
// Get parameters like fadestart, fadeend, and the fogflag
fadestart = NUMFROMCHAR(p2[3]) + (NUMFROMCHAR(p2[2]) * 10);
fadeend = NUMFROMCHAR(p2[5]) + (NUMFROMCHAR(p2[4]) * 10);
if (fadestart > 30)
fadestart = 0;
if (fadeend > 31 || fadeend < 1)
fadeend = 31;
fadedist = fadeend - fadestart;
fog = NUMFROMCHAR(p2[1]);
}
#undef getnum
if (p3[0] == '#')
{
cr = ((HEX2INT(p3[1]) * 16) + HEX2INT(p3[2]));
cg = ((HEX2INT(p3[3]) * 16) + HEX2INT(p3[4]));
cb = ((HEX2INT(p3[5]) * 16) + HEX2INT(p3[6]));
if (encoremap)
{
i = encoremap[NearestColor((UINT8)cr, (UINT8)cg, (UINT8)cb)];
cr = pLocalPalette[i].s.red;
cg = pLocalPalette[i].s.green;
cb = pLocalPalette[i].s.blue;
}
cdestr = cr;
cdestg = cg;
cdestb = cb;
fadecolor = (((cb) >> 3) + (((cg) >> 2) << 5) + (((cr) >> 3) << 11));
}
else
cdestr = cdestg = cdestb = fadecolor = 0;
#undef HEX2INT
for (i = 0; i < num_extra_colormaps; i++)
{
if (foundcolormaps[i] != LUMPERROR)
continue;
if (maskcolor == extra_colormaps[i].maskcolor
&& fadecolor == extra_colormaps[i].fadecolor
&& (float)maskamt == (float)extra_colormaps[i].maskamt
&& fadestart == extra_colormaps[i].fadestart
&& fadeend == extra_colormaps[i].fadeend
&& fog == extra_colormaps[i].fog)
{
return;
}
}
if (num_extra_colormaps == MAXCOLORMAPS)
I_Error("R_CreateColormap: Too many colormaps! the limit is %d\n", MAXCOLORMAPS);
num_extra_colormaps++;
if (rendermode == render_soft)
{
for (i = 0; i < 256; i++)
{
r = pLocalPalette[i].s.red;
g = pLocalPalette[i].s.green;
b = pLocalPalette[i].s.blue;
cbrightness = sqrt((r*r) + (g*g) + (b*b));
map[i][0] = (cbrightness * cmaskr) + (r * othermask);
if (map[i][0] > 255.0l)
map[i][0] = 255.0l;
deltas[i][0] = (map[i][0] - cdestr) / (double)fadedist;
map[i][1] = (cbrightness * cmaskg) + (g * othermask);
if (map[i][1] > 255.0l)
map[i][1] = 255.0l;
deltas[i][1] = (map[i][1] - cdestg) / (double)fadedist;
map[i][2] = (cbrightness * cmaskb) + (b * othermask);
if (map[i][2] > 255.0l)
map[i][2] = 255.0l;
deltas[i][2] = (map[i][2] - cdestb) / (double)fadedist;
}
}
foundcolormaps[mapnum] = LUMPERROR;
// aligned on 8 bit for asm code
extra_colormaps[mapnum].colormap = NULL;
extra_colormaps[mapnum].maskcolor = (UINT16)maskcolor;
extra_colormaps[mapnum].fadecolor = (UINT16)fadecolor;
extra_colormaps[mapnum].maskamt = maskamt;
extra_colormaps[mapnum].fadestart = (UINT16)fadestart;
extra_colormaps[mapnum].fadeend = (UINT16)fadeend;
extra_colormaps[mapnum].fog = fog;
#define ABS2(x) ((x) < 0 ? -(x) : (x))
if (rendermode == render_soft)
{
colormap_p = Z_MallocAlign((256 * (encoremap ? 64 : 32)) + 10, PU_LEVEL, NULL, 8); colormap_p = Z_MallocAlign((256 * (encoremap ? 64 : 32)) + 10, PU_LEVEL, NULL, 8);
extra_colormaps[mapnum].colormap = (UINT8 *)colormap_p; extra_colormaps[mapnum].colormap = (UINT8 *)colormap_p;
// Calculate the palette index for each palette index, for each light level
// (as well as the two unused colormap lines we inherited from Doom)
for (p = 0; p < 32; p++) for (p = 0; p < 32; p++)
{ {
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
@ -1483,7 +1300,7 @@ void R_CreateColormap2(char *p1, char *p2, char *p3)
if ((UINT32)p < fadestart) if ((UINT32)p < fadestart)
continue; continue;
#define ABS2(x) ((x) < 0 ? -(x) : (x))
if (ABS2(map[i][0] - cdestr) > ABS2(deltas[i][0])) if (ABS2(map[i][0] - cdestr) > ABS2(deltas[i][0]))
map[i][0] -= deltas[i][0]; map[i][0] -= deltas[i][0];
else else
@ -1498,27 +1315,27 @@ void R_CreateColormap2(char *p1, char *p2, char *p3)
map[i][2] -= deltas[i][2]; map[i][2] -= deltas[i][2];
else else
map[i][2] = cdestb; map[i][2] = cdestb;
#undef ABS2
} }
} }
if (!encoremap) if (encoremap)
return;
colormap_p2 = extra_colormaps[mapnum].colormap;
for (p = 0; p < 32; p++)
{ {
for (i = 0; i < 256; i++) lighttable_t *colormap_p2 = extra_colormaps[mapnum].colormap;
for (p = 0; p < 32; p++)
{ {
*colormap_p = colormap_p2[encoremap[i]]; for (i = 0; i < 256; i++)
colormap_p++; {
*colormap_p = colormap_p2[encoremap[i]];
colormap_p++;
}
colormap_p2 += 256;
} }
colormap_p2 += 256;
} }
} }
#undef ABS2
return; return (INT32)mapnum;
} }
// Thanks to quake2 source! // Thanks to quake2 source!

View File

@ -93,8 +93,6 @@ void R_ReInitColormaps(UINT16 num, lumpnum_t newencoremap);
void R_ClearColormaps(void); void R_ClearColormaps(void);
INT32 R_ColormapNumForName(char *name); INT32 R_ColormapNumForName(char *name);
INT32 R_CreateColormap(char *p1, char *p2, char *p3); INT32 R_CreateColormap(char *p1, char *p2, char *p3);
void R_CreateColormap2(char *p1, char *p2, char *p3);
void R_MakeColormaps(void);
#ifdef HASINVERT #ifdef HASINVERT
void R_MakeInvertmap(void); void R_MakeInvertmap(void);
#endif #endif

View File

@ -60,7 +60,6 @@ fixed_t projectiony; // aspect ratio
// just for profiling purposes // just for profiling purposes
size_t framecount; size_t framecount;
size_t sscount;
size_t loopcount; size_t loopcount;
fixed_t viewx, viewy, viewz; fixed_t viewx, viewy, viewz;
@ -123,11 +122,19 @@ size_t num_extra_colormaps;
extracolormap_t extra_colormaps[MAXCOLORMAPS]; extracolormap_t extra_colormaps[MAXCOLORMAPS];
static CV_PossibleValue_t drawdist_cons_t[] = { static CV_PossibleValue_t drawdist_cons_t[] = {
{256, "256"}, {512, "512"}, {768, "768"}, /*{256, "256"},*/ {512, "512"}, {768, "768"},
{1024, "1024"}, {1536, "1536"}, {2048, "2048"}, {1024, "1024"}, {1536, "1536"}, {2048, "2048"},
{3072, "3072"}, {4096, "4096"}, {6144, "6144"}, {3072, "3072"}, {4096, "4096"}, {6144, "6144"},
{8192, "8192"}, {0, "Infinite"}, {0, NULL}}; {8192, "8192"}, {0, "Infinite"}, {0, NULL}};
static CV_PossibleValue_t precipdensity_cons_t[] = {{0, "None"}, {1, "Light"}, {2, "Moderate"}, {4, "Heavy"}, {6, "Thick"}, {8, "V.Thick"}, {0, NULL}};
//static CV_PossibleValue_t precipdensity_cons_t[] = {{0, "None"}, {1, "Light"}, {2, "Moderate"}, {4, "Heavy"}, {6, "Thick"}, {8, "V.Thick"}, {0, NULL}};
static CV_PossibleValue_t drawdist_precip_cons_t[] = {
{256, "256"}, {512, "512"}, {768, "768"},
{1024, "1024"}, {1536, "1536"}, {2048, "2048"},
{0, "None"}, {0, NULL}};
//static CV_PossibleValue_t precipdensity_cons_t[] = {{0, "None"}, {1, "Light"}, {2, "Moderate"}, {4, "Heavy"}, {6, "Thick"}, {8, "V.Thick"}, {0, NULL}};
static CV_PossibleValue_t translucenthud_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}}; static CV_PossibleValue_t translucenthud_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}};
static CV_PossibleValue_t maxportals_cons_t[] = {{0, "MIN"}, {12, "MAX"}, {0, NULL}}; // lmao rendering 32 portals, you're a card static CV_PossibleValue_t maxportals_cons_t[] = {{0, "MIN"}, {12, "MAX"}, {0, NULL}}; // lmao rendering 32 portals, you're a card
static CV_PossibleValue_t homremoval_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Flash"}, {0, NULL}}; static CV_PossibleValue_t homremoval_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Flash"}, {0, NULL}};
@ -165,9 +172,9 @@ consvar_t cv_translucenthud = {"translucenthud", "10", CV_SAVE, translucenthud_c
consvar_t cv_translucency = {"translucency", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_translucency = {"translucency", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_drawdist = {"drawdist", "Infinite", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_drawdist = {"drawdist", "Infinite", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_drawdist_nights = {"drawdist_nights", "2048", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; //consvar_t cv_drawdist_nights = {"drawdist_nights", "2048", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_drawdist_precip = {"drawdist_precip", "1024", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_drawdist_precip = {"drawdist_precip", "1024", CV_SAVE, drawdist_precip_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_precipdensity = {"precipdensity", "Moderate", CV_SAVE, precipdensity_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; //consvar_t cv_precipdensity = {"precipdensity", "Moderate", CV_SAVE, precipdensity_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
// Okay, whoever said homremoval causes a performance hit should be shot. // Okay, whoever said homremoval causes a performance hit should be shot.
consvar_t cv_homremoval = {"homremoval", "Yes", CV_SAVE, homremoval_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_homremoval = {"homremoval", "Yes", CV_SAVE, homremoval_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -178,16 +185,6 @@ void SplitScreen_OnChange(void)
{ {
UINT8 i; UINT8 i;
if (!cv_debug && netgame)
{
if (splitscreen)
{
CONS_Alert(CONS_NOTICE, M_GetText("Splitscreen not supported in netplay, sorry!\n"));
splitscreen = 0;
}
return;
}
// recompute screen size // recompute screen size
R_ExecuteSetViewSize(); R_ExecuteSetViewSize();
@ -557,9 +554,6 @@ static void R_InitTextureMapping(void)
// Take out the fencepost cases from viewangletox. // Take out the fencepost cases from viewangletox.
for (i = 0; i < FINEANGLES/2; i++) for (i = 0; i < FINEANGLES/2; i++)
{ {
t = FixedMul(FINETANGENT(i), focallength);
t = centerx - t;
if (viewangletox[i] == -1) if (viewangletox[i] == -1)
viewangletox[i] = 0; viewangletox[i] = 0;
else if (viewangletox[i] == viewwidth+1) else if (viewangletox[i] == viewwidth+1)
@ -857,7 +851,7 @@ void R_SkyboxFrame(player_t *player)
{ {
aimingangle = player->aiming; aimingangle = player->aiming;
viewangle = player->mo->angle; viewangle = player->mo->angle;
if (!demoplayback && player->playerstate != PST_DEAD) if (/*!demoplayback && */player->playerstate != PST_DEAD)
{ {
if (player == &players[consoleplayer]) if (player == &players[consoleplayer])
{ {
@ -1048,8 +1042,6 @@ void R_SkyboxFrame(player_t *player)
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
sscount = 0;
// recalc necessary stuff for mouseaiming // recalc necessary stuff for mouseaiming
// slopes are already calculated for the full possible view (which is 4*viewheight). // slopes are already calculated for the full possible view (which is 4*viewheight).
@ -1136,7 +1128,7 @@ void R_SetupFrame(player_t *player, boolean skybox)
aimingangle = player->aiming; aimingangle = player->aiming;
viewangle = viewmobj->angle; viewangle = viewmobj->angle;
if (!demoplayback && player->playerstate != PST_DEAD) if (/*!demoplayback && */player->playerstate != PST_DEAD)
{ {
if (player == &players[consoleplayer]) if (player == &players[consoleplayer])
{ {
@ -1192,8 +1184,6 @@ void R_SetupFrame(player_t *player, boolean skybox)
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
sscount = 0;
// recalc necessary stuff for mouseaiming // recalc necessary stuff for mouseaiming
// slopes are already calculated for the full possible view (which is 4*viewheight). // slopes are already calculated for the full possible view (which is 4*viewheight).
@ -1349,9 +1339,9 @@ void R_RenderPlayerView(player_t *player)
if (cv_homremoval.value && player == &players[displayplayer]) if (cv_homremoval.value && player == &players[displayplayer])
{ {
if (cv_homremoval.value == 1) if (cv_homremoval.value == 1)
V_DrawFill(0, 0, vid.width, vid.height, 31); // No HOM effect! V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // No HOM effect!
else //'development' HOM removal -- makes it blindingly obvious if HOM is spotted. else //'development' HOM removal -- makes it blindingly obvious if HOM is spotted.
V_DrawFill(0, 0, vid.width, vid.height, 128+(timeinmap&15)); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 128+(timeinmap&15));
} }
// Draw over the fourth screen so you don't have to stare at a HOM :V // Draw over the fourth screen so you don't have to stare at a HOM :V
else if (splitscreen == 2 && player == &players[thirddisplayplayer]) else if (splitscreen == 2 && player == &players[thirddisplayplayer])
@ -1513,10 +1503,10 @@ void R_RegisterEngineStuff(void)
if (dedicated) if (dedicated)
return; return;
CV_RegisterVar(&cv_precipdensity); //CV_RegisterVar(&cv_precipdensity);
CV_RegisterVar(&cv_translucency); CV_RegisterVar(&cv_translucency);
CV_RegisterVar(&cv_drawdist); CV_RegisterVar(&cv_drawdist);
CV_RegisterVar(&cv_drawdist_nights); //CV_RegisterVar(&cv_drawdist_nights);
CV_RegisterVar(&cv_drawdist_precip); CV_RegisterVar(&cv_drawdist_precip);
CV_RegisterVar(&cv_chasecam); CV_RegisterVar(&cv_chasecam);

View File

@ -77,7 +77,7 @@ extern consvar_t cv_chasecam, cv_chasecam2, cv_chasecam3, cv_chasecam4;
extern consvar_t cv_flipcam, cv_flipcam2, cv_flipcam3, cv_flipcam4; extern consvar_t cv_flipcam, cv_flipcam2, cv_flipcam3, cv_flipcam4;
extern consvar_t cv_shadow, cv_shadowoffs; extern consvar_t cv_shadow, cv_shadowoffs;
extern consvar_t cv_translucency; extern consvar_t cv_translucency;
extern consvar_t cv_precipdensity, cv_drawdist, cv_drawdist_nights, cv_drawdist_precip; extern consvar_t /*cv_precipdensity,*/ cv_drawdist, /*cv_drawdist_nights,*/ cv_drawdist_precip;
extern consvar_t cv_skybox; extern consvar_t cv_skybox;
extern consvar_t cv_tailspickup; extern consvar_t cv_tailspickup;

View File

@ -112,7 +112,4 @@ extern angle_t rw_normalangle;
// angle to line origin // angle to line origin
extern angle_t rw_angle1; extern angle_t rw_angle1;
// Segs count?
extern size_t sscount;
#endif #endif

View File

@ -1602,6 +1602,17 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
return; return;
} }
// okay, we can't return now except for vertical clipping... this is a hack, but weather isn't networked, so it should be ok
if (!(thing->precipflags & PCF_THUNK))
{
if (thing->precipflags & PCF_RAIN)
P_RainThinker(thing);
else
P_SnowThinker(thing);
thing->precipflags |= PCF_THUNK;
}
//SoM: 3/17/2000: Disregard sprites that are out of view.. //SoM: 3/17/2000: Disregard sprites that are out of view..
gzt = thing->z + spritecachedinfo[lump].topoffset; gzt = thing->z + spritecachedinfo[lump].topoffset;
gz = gzt - spritecachedinfo[lump].height; gz = gzt - spritecachedinfo[lump].height;
@ -1712,7 +1723,7 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel, UINT8 viewnumber)
// Handle all things in sector. // Handle all things in sector.
// If a limit exists, handle things a tiny bit different. // If a limit exists, handle things a tiny bit different.
if ((limit_dist = (fixed_t)((maptol & TOL_NIGHTS) ? cv_drawdist_nights.value : cv_drawdist.value) << FRACBITS)) if ((limit_dist = (fixed_t)(/*(maptol & TOL_NIGHTS) ? cv_drawdist_nights.value : */cv_drawdist.value) << FRACBITS))
{ {
for (thing = sec->thinglist; thing; thing = thing->snext) for (thing = sec->thinglist; thing; thing = thing->snext)
{ {
@ -1740,8 +1751,10 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel, UINT8 viewnumber)
approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y); approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y);
if (approx_dist <= limit_dist) if (approx_dist > limit_dist)
R_ProjectSprite(thing); continue;
R_ProjectSprite(thing);
} }
} }
else else
@ -1785,8 +1798,10 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel, UINT8 viewnumber)
approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y); approx_dist = P_AproxDistance(viewx-precipthing->x, viewy-precipthing->y);
if (approx_dist <= limit_dist) if (approx_dist > limit_dist)
R_ProjectPrecipitationSprite(precipthing); continue;
R_ProjectPrecipitationSprite(precipthing);
} }
} }
else else
@ -2684,7 +2699,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
player->jumpfactor = skin->jumpfactor; player->jumpfactor = skin->jumpfactor;
if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback || modeattacking)) /*if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback || modeattacking))
{ {
if (playernum == consoleplayer) if (playernum == consoleplayer)
CV_StealthSetValue(&cv_playercolor, skin->prefcolor); CV_StealthSetValue(&cv_playercolor, skin->prefcolor);
@ -2697,7 +2712,7 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
player->skincolor = skin->prefcolor; player->skincolor = skin->prefcolor;
if (player->mo) if (player->mo)
player->mo->color = player->skincolor; player->mo->color = player->skincolor;
} }*/
if (player->mo) if (player->mo)
P_SetScale(player->mo, player->mo->scale); P_SetScale(player->mo, player->mo->scale);

View File

@ -85,7 +85,7 @@ consvar_t cv_digmusicvolume = {"digmusicvolume", "18", CV_SAVE, soundvolume_cons
#if defined (_WIN32_WCE) || defined (DC) || defined (PSP) || defined(GP2X) #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}; consvar_t cv_numChannels = {"snd_channels", "8", CV_SAVE|CV_CALL, CV_Unsigned, SetChannelsNum, 0, NULL, NULL, 0, 0, NULL};
#else #else
consvar_t cv_numChannels = {"snd_channels", "32", CV_SAVE|CV_CALL, CV_Unsigned, SetChannelsNum, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_numChannels = {"snd_channels", "64", CV_SAVE|CV_CALL, CV_Unsigned, SetChannelsNum, 0, NULL, NULL, 0, 0, NULL};
#endif #endif
consvar_t surround = {"surround", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t surround = {"surround", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -186,7 +186,7 @@ static INT32 S_getChannel(const void *origin, sfxinfo_t *sfxinfo)
} }
else if (origin && channels[cnum].origin == origin else if (origin && channels[cnum].origin == origin
&& channels[cnum].sfxinfo->name != sfxinfo->name && channels[cnum].sfxinfo->name != sfxinfo->name
&& channels[cnum].sfxinfo->pitch == SF_TOTALLYSINGLE && sfxinfo->pitch == SF_TOTALLYSINGLE) && (channels[cnum].sfxinfo->pitch & SF_TOTALLYSINGLE) && (sfxinfo->pitch & SF_TOTALLYSINGLE))
{ {
S_StopChannel(cnum); S_StopChannel(cnum);
break; break;
@ -582,7 +582,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
// Assigns the handle to one of the channels in the // Assigns the handle to one of the channels in the
// mix/output buffer. // mix/output buffer.
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority); channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
} }
dontplay: dontplay:
@ -638,7 +638,7 @@ dontplay:
// Assigns the handle to one of the channels in the // Assigns the handle to one of the channels in the
// mix/output buffer. // mix/output buffer.
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority); channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
} }
dontplay3: dontplay3:
@ -694,7 +694,7 @@ dontplay3:
// Assigns the handle to one of the channels in the // Assigns the handle to one of the channels in the
// mix/output buffer. // mix/output buffer.
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority); channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
} }
dontplay4: dontplay4:
@ -743,7 +743,7 @@ dontplay4:
// Assigns the handle to one of the channels in the // Assigns the handle to one of the channels in the
// mix/output buffer. // mix/output buffer.
channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority); channels[cnum].handle = I_StartSound(sfx_id, volume, sep, pitch, priority, cnum);
} }
void S_StartSound(const void *origin, sfxenum_t sfx_id) void S_StartSound(const void *origin, sfxenum_t sfx_id)

View File

@ -124,6 +124,10 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#include "macosx/mac_resources.h" #include "macosx/mac_resources.h"
#endif #endif
#ifndef errno
#include <errno.h>
#endif
// Locations for searching the srb2.srb // Locations for searching the srb2.srb
#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
#define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2" #define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2"
@ -1179,6 +1183,7 @@ static void I_ShutdownJoystick2(void)
D_PostEvent(&event); D_PostEvent(&event);
} }
joystick2_started = 0;
JoyReset(&JoyInfo2); JoyReset(&JoyInfo2);
if (!joystick_started && !joystick2_started && !joystick3_started && !joystick4_started if (!joystick_started && !joystick2_started && !joystick3_started && !joystick4_started
&& SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK) && SDL_WasInit(SDL_INIT_JOYSTICK) == SDL_INIT_JOYSTICK)
@ -2309,7 +2314,7 @@ static void I_ShutdownMouse2(void)
EscapeCommFunction(mouse2filehandle, CLRRTS); EscapeCommFunction(mouse2filehandle, CLRRTS);
PurgeComm(mouse2filehandle, PURGE_TXABORT | PURGE_RXABORT | PurgeComm(mouse2filehandle, PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR); PURGE_TXCLEAR | PURGE_RXCLEAR);
CloseHandle(mouse2filehandle); CloseHandle(mouse2filehandle);
@ -2502,11 +2507,11 @@ void I_StartupMouse2(void)
{ {
// COM file handle // COM file handle
mouse2filehandle = CreateFileA(cv_mouse2port.string, GENERIC_READ | GENERIC_WRITE, mouse2filehandle = CreateFileA(cv_mouse2port.string, GENERIC_READ | GENERIC_WRITE,
0, // exclusive access 0, // exclusive access
NULL, // no security attrs NULL, // no security attrs
OPEN_EXISTING, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL,
NULL); NULL);
if (mouse2filehandle == INVALID_HANDLE_VALUE) if (mouse2filehandle == INVALID_HANDLE_VALUE)
{ {
INT32 e = GetLastError(); INT32 e = GetLastError();
@ -2526,7 +2531,7 @@ void I_StartupMouse2(void)
// purge buffers // purge buffers
PurgeComm(mouse2filehandle, PURGE_TXABORT | PURGE_RXABORT PurgeComm(mouse2filehandle, PURGE_TXABORT | PURGE_RXABORT
| PURGE_TXCLEAR | PURGE_RXCLEAR); | PURGE_TXCLEAR | PURGE_RXCLEAR);
// setup port to 1200 7N1 // setup port to 1200 7N1
dcb.DCBlength = sizeof (DCB); dcb.DCBlength = sizeof (DCB);
@ -2687,7 +2692,7 @@ static void I_ShutdownTimer(void)
tic_t I_GetTime (void) tic_t I_GetTime (void)
{ {
static Uint32 basetime = 0; static Uint32 basetime = 0;
Uint32 ticks = SDL_GetTicks(); Uint32 ticks = SDL_GetTicks();
if (!basetime) if (!basetime)
basetime = ticks; basetime = ticks;
@ -2753,7 +2758,6 @@ INT32 I_StartupSystem(void)
return 0; return 0;
} }
// //
// I_Quit // I_Quit
// //
@ -3032,7 +3036,7 @@ void I_GetDiskFreeSpace(INT64 *freespace)
{ {
DWORD SectorsPerCluster, BytesPerSector, NumberOfFreeClusters, TotalNumberOfClusters; DWORD SectorsPerCluster, BytesPerSector, NumberOfFreeClusters, TotalNumberOfClusters;
GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector, GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector,
&NumberOfFreeClusters, &TotalNumberOfClusters); &NumberOfFreeClusters, &TotalNumberOfClusters);
*freespace = BytesPerSector*SectorsPerCluster*NumberOfFreeClusters; *freespace = BytesPerSector*SectorsPerCluster*NumberOfFreeClusters;
} }
#else // Dummy for platform independent; 1GB should be enough #else // Dummy for platform independent; 1GB should be enough
@ -3254,22 +3258,22 @@ static const char *locateWad(void)
#ifdef CMAKECONFIG #ifdef CMAKECONFIG
#ifndef NDEBUG #ifndef NDEBUG
I_OutputMsg(","CMAKE_ASSETS_DIR); I_OutputMsg(","CMAKE_ASSETS_DIR);
strcpy(returnWadPath, CMAKE_ASSETS_DIR); strcpy(returnWadPath, CMAKE_ASSETS_DIR);
if (isWadPathOk(returnWadPath)) if (isWadPathOk(returnWadPath))
{ {
return returnWadPath; return returnWadPath;
} }
#endif #endif
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__
OSX_GetResourcesPath(returnWadPath); OSX_GetResourcesPath(returnWadPath);
I_OutputMsg(",%s", returnWadPath); I_OutputMsg(",%s", returnWadPath);
if (isWadPathOk(returnWadPath)) if (isWadPathOk(returnWadPath))
{ {
return returnWadPath; return returnWadPath;
} }
#endif #endif
// examine default dirs // examine default dirs
@ -3374,7 +3378,30 @@ const char *I_LocateWad(void)
#ifdef __linux__ #ifdef __linux__
#define MEMINFO_FILE "/proc/meminfo" #define MEMINFO_FILE "/proc/meminfo"
#define MEMTOTAL "MemTotal:" #define MEMTOTAL "MemTotal:"
#define MEMAVAILABLE "MemAvailable:"
#define MEMFREE "MemFree:" #define MEMFREE "MemFree:"
#define CACHED "Cached:"
#define BUFFERS "Buffers:"
#define SHMEM "Shmem:"
/* Parse the contents of /proc/meminfo (in buf), return value of "name"
* (example: MemTotal) */
static long get_entry(const char* name, const char* buf)
{
long val;
char* hit = strstr(buf, name);
if (hit == NULL) {
return -1;
}
errno = 0;
val = strtol(hit + strlen(name), NULL, 10);
if (errno != 0) {
CONS_Alert(CONS_ERROR, M_GetText("get_entry: strtol() failed: %s\n"), strerror(errno));
return -1;
}
return val;
}
#endif #endif
// quick fix for compil // quick fix for compil
@ -3446,6 +3473,11 @@ UINT32 I_GetFreeMem(UINT32 *total)
UINT32 totalKBytes; UINT32 totalKBytes;
INT32 n; INT32 n;
INT32 meminfo_fd = -1; INT32 meminfo_fd = -1;
long Cached;
long MemFree;
long Buffers;
long Shmem;
long MemAvailable = -1;
meminfo_fd = open(MEMINFO_FILE, O_RDONLY); meminfo_fd = open(MEMINFO_FILE, O_RDONLY);
n = read(meminfo_fd, buf, 1023); n = read(meminfo_fd, buf, 1023);
@ -3471,16 +3503,28 @@ UINT32 I_GetFreeMem(UINT32 *total)
memTag += sizeof (MEMTOTAL); memTag += sizeof (MEMTOTAL);
totalKBytes = atoi(memTag); totalKBytes = atoi(memTag);
if ((memTag = strstr(buf, MEMFREE)) == NULL) if ((memTag = strstr(buf, MEMAVAILABLE)) == NULL)
{ {
// Error Cached = get_entry(CACHED, buf);
if (total) MemFree = get_entry(MEMFREE, buf);
*total = 0L; Buffers = get_entry(BUFFERS, buf);
return 0; Shmem = get_entry(SHMEM, buf);
} MemAvailable = Cached + MemFree + Buffers - Shmem;
memTag += sizeof (MEMFREE); if (MemAvailable == -1)
freeKBytes = atoi(memTag); {
// Error
if (total)
*total = 0L;
return 0;
}
freeKBytes = MemAvailable;
}
else
{
memTag += sizeof (MEMAVAILABLE);
freeKBytes = atoi(memTag);
}
if (total) if (total)
*total = totalKBytes << 10; *total = totalKBytes << 10;

View File

@ -38,10 +38,8 @@
#include "gme/gme.h" #include "gme/gme.h"
#define GME_TREBLE 5.0 #define GME_TREBLE 5.0
#define GME_BASS 1.0 #define GME_BASS 1.0
#ifdef HAVE_PNG /// TODO: compile with zlib support without libpng
#define HAVE_ZLIB
#ifdef HAVE_ZLIB
#ifndef _MSC_VER #ifndef _MSC_VER
#ifndef _LARGEFILE64_SOURCE #ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE #define _LARGEFILE64_SOURCE
@ -57,8 +55,8 @@
#endif #endif
#include "zlib.h" #include "zlib.h"
#endif #endif // HAVE_ZLIB
#endif #endif // HAVE_LIBGME
UINT8 sound_started = false; UINT8 sound_started = false;
@ -178,7 +176,7 @@ static Mix_Chunk *ds2chunk(void *stream)
return NULL; // would and/or did wrap, can't store. return NULL; // would and/or did wrap, can't store.
break; break;
} }
sound = malloc(newsamples<<2); // samples * frequency shift * bytes per sample * channels sound = Z_Malloc(newsamples<<2, PU_SOUND, NULL); // samples * frequency shift * bytes per sample * channels
s = (SINT8 *)stream; s = (SINT8 *)stream;
d = (INT16 *)sound; d = (INT16 *)sound;
@ -246,6 +244,7 @@ void *I_GetSfx(sfxinfo_t *sfx)
{ {
void *lump; void *lump;
Mix_Chunk *chunk; Mix_Chunk *chunk;
SDL_RWops *rw;
#ifdef HAVE_LIBGME #ifdef HAVE_LIBGME
Music_Emu *emu; Music_Emu *emu;
gme_info_t *info; gme_info_t *info;
@ -361,7 +360,7 @@ void *I_GetSfx(sfxinfo_t *sfx)
} }
Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up
#else #else
//CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n"); return NULL; // No zlib support
#endif #endif
} }
// Try to read it as a GME sound // Try to read it as a GME sound
@ -387,21 +386,43 @@ void *I_GetSfx(sfxinfo_t *sfx)
#endif #endif
// Try to load it as a WAVE or OGG using Mixer. // Try to load it as a WAVE or OGG using Mixer.
return Mix_LoadWAV_RW(SDL_RWFromMem(lump, sfx->length), 1); rw = SDL_RWFromMem(lump, sfx->length);
if (rw != NULL)
{
chunk = Mix_LoadWAV_RW(rw, 1);
return chunk;
}
return NULL; // haven't been able to get anything
} }
void I_FreeSfx(sfxinfo_t *sfx) void I_FreeSfx(sfxinfo_t *sfx)
{ {
if (sfx->data) if (sfx->data)
{
Mix_Chunk *chunk = (Mix_Chunk*)sfx->data;
UINT8 *abufdata = NULL;
if (chunk->allocated == 0)
{
// We allocated the data in this chunk, so get the abuf from mixer, then let it free the chunk, THEN we free the data
// I believe this should ensure the sound is not playing when we free it
abufdata = chunk->abuf;
}
Mix_FreeChunk(sfx->data); Mix_FreeChunk(sfx->data);
if (abufdata)
{
// I'm going to assume we used Z_Malloc to allocate this data.
Z_Free(abufdata);
}
}
sfx->data = NULL; sfx->data = NULL;
sfx->lumpnum = LUMPERROR; sfx->lumpnum = LUMPERROR;
} }
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority) INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
{ {
UINT8 volume = (((UINT16)vol + 1) * (UINT16)sfx_volume) / 62; // (256 * 31) / 62 == 127 UINT8 volume = (((UINT16)vol + 1) * (UINT16)sfx_volume) / 62; // (256 * 31) / 62 == 127
INT32 handle = Mix_PlayChannel(-1, S_sfx[id].data, 0); INT32 handle = Mix_PlayChannel(channel, S_sfx[id].data, 0);
Mix_Volume(handle, volume); Mix_Volume(handle, volume);
Mix_SetPanning(handle, min((UINT16)(0xff-sep)<<1, 0xff), min((UINT16)(sep)<<1, 0xff)); Mix_SetPanning(handle, min((UINT16)(0xff-sep)<<1, 0xff), min((UINT16)(sep)<<1, 0xff));
(void)pitch; // Mixer can't handle pitch (void)pitch; // Mixer can't handle pitch
@ -524,6 +545,7 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
char *data; char *data;
size_t len; size_t len;
lumpnum_t lumpnum = W_CheckNumForName(va("O_%s",musicname)); lumpnum_t lumpnum = W_CheckNumForName(va("O_%s",musicname));
SDL_RWops *rw;
I_Assert(!music); I_Assert(!music);
#ifdef HAVE_LIBGME #ifdef HAVE_LIBGME
@ -621,7 +643,8 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
} }
Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up Z_Free(inflatedData); // GME didn't open jack, but don't let that stop us from freeing this up
#else #else
//CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n"); CONS_Alert(CONS_ERROR,"Cannot decompress VGZ; no zlib support\n");
return true;
#endif #endif
} }
else if (!gme_open_data(data, len, &gme, 44100)) else if (!gme_open_data(data, len, &gme, 44100))
@ -635,7 +658,11 @@ boolean I_StartDigSong(const char *musicname, boolean looping)
} }
#endif #endif
music = Mix_LoadMUS_RW(SDL_RWFromMem(data, len), SDL_FALSE); rw = SDL_RWFromMem(data, len);
if (rw != NULL)
{
music = Mix_LoadMUS_RW(rw, 1);
}
if (!music) if (!music)
{ {
CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError()); CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError());
@ -798,7 +825,11 @@ void I_SetMIDIMusicVolume(UINT8 volume)
INT32 I_RegisterSong(void *data, size_t len) INT32 I_RegisterSong(void *data, size_t len)
{ {
music = Mix_LoadMUS_RW(SDL_RWFromMem(data, len), SDL_FALSE); SDL_RWops *rw = SDL_RWFromMem(data, len);
if (rw != NULL)
{
music = Mix_LoadMUS_RW(rw, 1);
}
if (!music) if (!music)
{ {
CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError()); CONS_Alert(CONS_ERROR, "Mix_LoadMUS_RW: %s\n", Mix_GetError());
@ -842,4 +873,4 @@ void I_UnRegisterSong(INT32 handle)
music = NULL; music = NULL;
} }
#endif #endif

View File

@ -604,10 +604,11 @@ void I_FreeSfx(sfxinfo_t * sfx)
// Pitching (that is, increased speed of playback) // Pitching (that is, increased speed of playback)
// is set, but currently not used by mixing. // is set, but currently not used by mixing.
// //
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority) INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
{ {
(void)priority; (void)priority;
(void)pitch; (void)pitch;
(void)channel;
if (nosound) if (nosound)
return 0; return 0;

View File

@ -376,10 +376,10 @@ void I_FreeSfx(sfxinfo_t *sfx)
sfx->data = NULL; sfx->data = NULL;
} }
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority) INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
{ {
UINT8 volume = (((UINT16)vol + 1) * (UINT16)sfx_volume) / 62; // (256 * 31) / 62 == 127 UINT8 volume = (((UINT16)vol + 1) * (UINT16)sfx_volume) / 62; // (256 * 31) / 62 == 127
INT32 handle = Mix_PlayChannel(-1, S_sfx[id].data, 0); INT32 handle = Mix_PlayChannel(channel, S_sfx[id].data, 0);
Mix_Volume(handle, volume); Mix_Volume(handle, volume);
Mix_SetPanning(handle, min((UINT16)(0xff-sep)<<1, 0xff), min((UINT16)(sep)<<1, 0xff)); Mix_SetPanning(handle, min((UINT16)(0xff-sep)<<1, 0xff), min((UINT16)(sep)<<1, 0xff));
(void)pitch; // Mixer can't handle pitch (void)pitch; // Mixer can't handle pitch

View File

@ -621,10 +621,11 @@ void I_FreeSfx(sfxinfo_t * sfx)
// Pitching (that is, increased speed of playback) // Pitching (that is, increased speed of playback)
// is set, but currently not used by mixing. // is set, but currently not used by mixing.
// //
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority) INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
{ {
(void)priority; (void)priority;
(void)pitch; (void)pitch;
(void)channel;
if (nosound) if (nosound)
return 0; return 0;

View File

@ -820,131 +820,131 @@ sfxinfo_t S_sfx[NUMSFX] =
// SRB2Kart - Engine sounds // SRB2Kart - Engine sounds
// Engine class A // Engine class A
{"krta00", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krta00", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krta01", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krta01", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krta02", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krta02", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krta03", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krta03", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krta04", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krta04", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krta05", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krta05", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krta06", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krta06", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krta07", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krta07", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krta08", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krta08", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krta09", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krta09", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krta10", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krta10", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krta11", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krta11", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krta12", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krta12", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
// Engine class B // Engine class B
{"krtb00", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtb00", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtb01", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtb01", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtb02", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtb02", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtb03", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtb03", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtb04", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtb04", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtb05", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtb05", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtb06", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtb06", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtb07", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtb07", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtb08", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtb08", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtb09", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtb09", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtb10", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtb10", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtb11", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtb11", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtb12", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtb12", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
// Engine class C // Engine class C
{"krtc00", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtc00", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtc01", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtc01", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtc02", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtc02", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtc03", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtc03", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtc04", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtc04", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtc05", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtc05", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtc06", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtc06", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtc07", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtc07", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtc08", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtc08", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtc09", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtc09", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtc10", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtc10", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtc11", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtc11", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtc12", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtc12", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
// Engine class D // Engine class D
{"krtd00", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtd00", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtd01", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtd01", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtd02", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtd02", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtd03", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtd03", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtd04", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtd04", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtd05", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtd05", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtd06", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtd06", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtd07", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtd07", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtd08", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtd08", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtd09", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtd09", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtd10", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtd10", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtd11", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtd11", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtd12", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtd12", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
// Engine class E // Engine class E
{"krte00", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krte00", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krte01", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krte01", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krte02", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krte02", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krte03", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krte03", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krte04", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krte04", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krte05", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krte05", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krte06", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krte06", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krte07", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krte07", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krte08", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krte08", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krte09", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krte09", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krte10", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krte10", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krte11", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krte11", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krte12", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krte12", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
// Engine class F // Engine class F
{"krtf00", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtf00", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtf01", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtf01", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtf02", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtf02", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtf03", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtf03", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtf04", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtf04", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtf05", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtf05", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtf06", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtf06", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtf07", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtf07", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtf08", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtf08", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtf09", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtf09", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtf10", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtf10", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtf11", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtf11", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtf12", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtf12", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
// Engine class G // Engine class G
{"krtg00", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtg00", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtg01", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtg01", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtg02", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtg02", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtg03", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtg03", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtg04", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtg04", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtg05", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtg05", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtg06", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtg06", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtg07", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtg07", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtg08", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtg08", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtg09", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtg09", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtg10", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtg10", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtg11", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtg11", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krtg12", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krtg12", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
// Engine class H // Engine class H
{"krth00", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krth00", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krth01", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krth01", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krth02", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krth02", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krth03", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krth03", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krth04", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krth04", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krth05", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krth05", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krth06", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krth06", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krth07", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krth07", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krth08", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krth08", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krth09", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krth09", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krth10", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krth10", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krth11", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krth11", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krth12", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krth12", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
// Engine class I // Engine class I
{"krti00", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krti00", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krti01", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krti01", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krti02", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krti02", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krti03", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krti03", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krti04", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krti04", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krti05", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krti05", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krti06", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krti06", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krti07", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krti07", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krti08", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krti08", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krti09", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krti09", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krti10", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krti10", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krti11", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krti11", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
{"krti12", false, 48, 64, -1, NULL, 0, -1, -1, LUMPERROR}, {"krti12", false, 48, 65, -1, NULL, 0, -1, -1, LUMPERROR},
// SRB2kart - Skin sounds // SRB2kart - Skin sounds
{"kwin", false, 64, 96, -1, NULL, 0, SKSKWIN, -1, LUMPERROR}, {"kwin", false, 64, 96, -1, NULL, 0, SKSKWIN, -1, LUMPERROR},
@ -955,8 +955,8 @@ sfxinfo_t S_sfx[NUMSFX] =
{"kattk2", false, 64, 96, -1, NULL, 0, SKSKATK2, -1, LUMPERROR}, {"kattk2", false, 64, 96, -1, NULL, 0, SKSKATK2, -1, LUMPERROR},
{"kbost1", false, 64, 96, -1, NULL, 0, SKSKBST1, -1, LUMPERROR}, {"kbost1", false, 64, 96, -1, NULL, 0, SKSKBST1, -1, LUMPERROR},
{"kbost2", false, 64, 96, -1, NULL, 0, SKSKBST2, -1, LUMPERROR}, {"kbost2", false, 64, 96, -1, NULL, 0, SKSKBST2, -1, LUMPERROR},
{"kslow", false, 128, 32, -1, NULL, 0, SKSKSLOW, -1, LUMPERROR}, {"kslow", false, 64, 32, -1, NULL, 0, SKSKSLOW, -1, LUMPERROR},
{"khitem", false, 64, 32, -1, NULL, 0, SKSKHITM, -1, LUMPERROR}, {"khitem", false, 128, 32, -1, NULL, 0, SKSKHITM, -1, LUMPERROR},
{"kgloat", false, 64, 48, -1, NULL, 0, SKSKPOWR, -1, LUMPERROR}, {"kgloat", false, 64, 48, -1, NULL, 0, SKSKPOWR, -1, LUMPERROR},
// skin sounds free slots to add sounds at run time (Boris HACK!!!) // skin sounds free slots to add sounds at run time (Boris HACK!!!)

View File

@ -1927,7 +1927,7 @@ static void ST_overlayDrawer(void)
) )
ST_drawLevelTitle(); ST_drawLevelTitle();
if (!hu_showscores && !splitscreen && netgame && displayplayer == consoleplayer && !mapreset) if (!hu_showscores && netgame && !mapreset)
{ {
/*if (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1) /*if (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1)
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press F12 to watch another player.")); V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press F12 to watch another player."));
@ -1952,15 +1952,33 @@ static void ST_overlayDrawer(void)
) )
{ {
// SRB2kart: changed positions & text // SRB2kart: changed positions & text
V_DrawString(2, BASEVIDHEIGHT-40, V_HUDTRANSHALF|V_YELLOWMAP, M_GetText("- SPECTATING -")); if (splitscreen)
if (stplyr->pflags & PF_WANTSTOJOIN) {
V_DrawString(2, BASEVIDHEIGHT-30, V_HUDTRANSHALF, M_GetText("Item - Cancel Join")); INT32 splitflags = K_calcSplitFlags(0);
/*else if (G_GametypeHasTeams()) V_DrawThinString(2, (BASEVIDHEIGHT/2)-20, V_YELLOWMAP|V_HUDTRANSHALF|splitflags, M_GetText("- SPECTATING -"));
V_DrawString(2, BASEVIDHEIGHT-30, V_HUDTRANSHALF, M_GetText("Item - Join Team"));*/ if (stplyr->powers[pw_flashing])
V_DrawString(2, (BASEVIDHEIGHT/2)-10, V_HUDTRANSHALF|splitflags, M_GetText("Item - . . ."));
else if (stplyr->pflags & PF_WANTSTOJOIN)
V_DrawThinString(2, (BASEVIDHEIGHT/2)-10, V_HUDTRANSHALF|splitflags, M_GetText("Item - Cancel Join"));
/*else if (G_GametypeHasTeams())
V_DrawThinString(2, (BASEVIDHEIGHT/2)-10, V_HUDTRANSHALF|splitflags, M_GetText("Item - Join Team"));*/
else
V_DrawThinString(2, (BASEVIDHEIGHT/2)-10, V_HUDTRANSHALF|splitflags, M_GetText("Item - Join Game"));
}
else else
V_DrawString(2, BASEVIDHEIGHT-30, V_HUDTRANSHALF, M_GetText("Item - Join Game")); {
V_DrawString(2, BASEVIDHEIGHT-20, V_HUDTRANSHALF, M_GetText("Accelerate - Float")); V_DrawString(2, BASEVIDHEIGHT-40, V_HUDTRANSHALF|V_YELLOWMAP, M_GetText("- SPECTATING -"));
V_DrawString(2, BASEVIDHEIGHT-10, V_HUDTRANSHALF, M_GetText("Brake - Sink")); if (stplyr->powers[pw_flashing])
V_DrawString(2, BASEVIDHEIGHT-30, V_HUDTRANSHALF, M_GetText("Item - . . ."));
else if (stplyr->pflags & PF_WANTSTOJOIN)
V_DrawString(2, BASEVIDHEIGHT-30, V_HUDTRANSHALF, M_GetText("Item - Cancel Join"));
/*else if (G_GametypeHasTeams())
V_DrawString(2, BASEVIDHEIGHT-30, V_HUDTRANSHALF, M_GetText("Item - Join Team"));*/
else
V_DrawString(2, BASEVIDHEIGHT-30, V_HUDTRANSHALF, M_GetText("Item - Join Game"));
V_DrawString(2, BASEVIDHEIGHT-20, V_HUDTRANSHALF, M_GetText("Accelerate - Float"));
V_DrawString(2, BASEVIDHEIGHT-10, V_HUDTRANSHALF, M_GetText("Brake - Sink"));
}
} }
} }

View File

@ -668,14 +668,10 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
// //
void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skincolor) void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skincolor)
{ {
if (skins[skinnum].flags & SF_HIRES if (skinnum < 0 || skinnum >= numskins || (skins[skinnum].flags & SF_HIRES))
#ifdef HWRENDER V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE)); // Draw a star
// || (rendermode != render_soft && rendermode != render_none)
#endif
)
V_DrawScaledPatch(x - 10, y - 14, flags, W_CachePatchName("CONTINS", PU_CACHE));
else else
{ { // Find front angle of the first waiting frame of the character's actual sprites
spriteframe_t *sprframe = &skins[skinnum].spritedef.spriteframes[2 & FF_FRAMEMASK]; spriteframe_t *sprframe = &skins[skinnum].spritedef.spriteframes[2 & FF_FRAMEMASK];
patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
const UINT8 *colormap = R_GetTranslationColormap(skinnum, skincolor, GTC_CACHE); const UINT8 *colormap = R_GetTranslationColormap(skinnum, skincolor, GTC_CACHE);

View File

@ -196,16 +196,21 @@ static inline void W_LoadDehackedLumps(UINT16 wadnum)
for (lump = 0; lump < wadfiles[wadnum]->numlumps; lump++, lump_p++) for (lump = 0; lump < wadfiles[wadnum]->numlumps; lump++, lump_p++)
if (memcmp(lump_p->name,"SOC_",4)==0) // Check for generic SOC lump if (memcmp(lump_p->name,"SOC_",4)==0) // Check for generic SOC lump
{ // shameless copy+paste of code from LUA_LoadLump { // shameless copy+paste of code from LUA_LoadLump
char *name = malloc(strlen(wadfiles[wadnum]->filename)+10); size_t len = strlen(wadfiles[wadnum]->filename);
char *name = malloc(len+10);
strcpy(name, wadfiles[wadnum]->filename); strcpy(name, wadfiles[wadnum]->filename);
if (!fasticmp(&name[strlen(name) - 4], ".soc")) { if (!fasticmp(&name[len - 4], ".soc")) {
// If it's not a .soc file, copy the lump name in too. // If it's not a .soc file, copy the lump name in too.
name[strlen(wadfiles[wadnum]->filename)] = '|'; name[len] = '|';
M_Memcpy(name+strlen(wadfiles[wadnum]->filename)+1, lump_p->name, 8); M_Memcpy(name+len+1, lump_p->name, 8);
name[strlen(wadfiles[wadnum]->filename)+9] = '\0'; name[len+9] = '\0';
} }
CONS_Printf(M_GetText("Loading SOC from %s\n"), name); CONS_Printf(M_GetText("Loading SOC from %s\n"), name);
DEH_LoadDehackedLumpPwad(wadnum, lump); DEH_LoadDehackedLumpPwad(wadnum, lump);
free(name);
} }
else if (memcmp(lump_p->name,"MAINCFG",8)==0) // Check for MAINCFG else if (memcmp(lump_p->name,"MAINCFG",8)==0) // Check for MAINCFG
{ {

View File

@ -17,17 +17,13 @@
#include "gme/gme.h" #include "gme/gme.h"
#define GME_TREBLE 5.0 #define GME_TREBLE 5.0
#define GME_BASS 1.0 #define GME_BASS 1.0
#ifdef HAVE_PNG /// TODO: compile with zlib support without libpng
#define HAVE_ZLIB
#ifdef HAVE_ZLIB
#ifndef _MSC_VER #ifndef _MSC_VER
#ifndef _WII
#ifndef _LARGEFILE64_SOURCE #ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE #define _LARGEFILE64_SOURCE
#endif #endif
#endif #endif
#endif
#ifndef _LFS64_LARGEFILE #ifndef _LFS64_LARGEFILE
#define _LFS64_LARGEFILE #define _LFS64_LARGEFILE
@ -38,8 +34,8 @@
#endif #endif
#include "zlib.h" #include "zlib.h"
#endif #endif // HAVE_ZLIB
#endif #endif // HAVE_LIBGME
static FMOD_SYSTEM *fsys; static FMOD_SYSTEM *fsys;
static FMOD_SOUND *music_stream; static FMOD_SOUND *music_stream;
@ -357,12 +353,13 @@ void I_FreeSfx(sfxinfo_t *sfx)
sfx->data = NULL; sfx->data = NULL;
} }
INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority) INT32 I_StartSound(sfxenum_t id, UINT8 vol, UINT8 sep, UINT8 pitch, UINT8 priority, INT32 channel)
{ {
FMOD_SOUND *sound; FMOD_SOUND *sound;
FMOD_CHANNEL *chan; FMOD_CHANNEL *chan;
INT32 i; INT32 i;
float frequency; float frequency;
(void)channel;
sound = (FMOD_SOUND *)S_sfx[id].data; sound = (FMOD_SOUND *)S_sfx[id].data;
I_Assert(sound != NULL); I_Assert(sound != NULL);

View File

@ -538,7 +538,8 @@ INT32 I_StartSound (sfxenum_t id,
INT32 vol, INT32 vol,
INT32 sep, INT32 sep,
INT32 pitch, INT32 pitch,
INT32 priority) INT32 priority,
INT32 channel)
{ {
HRESULT hr; HRESULT hr;
LPDIRECTSOUNDBUFFER dsbuffer; LPDIRECTSOUNDBUFFER dsbuffer;
@ -549,6 +550,7 @@ INT32 I_StartSound (sfxenum_t id,
#ifdef SURROUND #ifdef SURROUND
LPDIRECTSOUNDBUFFER dssurround; LPDIRECTSOUNDBUFFER dssurround;
#endif #endif
(void)channel;
if (nosound) if (nosound)
return -1; return -1;

View File

@ -296,9 +296,9 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32))
else else
data.match.pos[data.match.numplayers] = data.match.numplayers+1; data.match.pos[data.match.numplayers] = data.match.numplayers+1;
if (!rankingsmode && !(players[i].pflags & PF_TIMEOVER) && (data.match.pos[data.match.numplayers] != numplayersingame)) if (!rankingsmode && !(players[i].pflags & PF_TIMEOVER) && (data.match.pos[data.match.numplayers] < nospectategrief))
{ {
data.match.increase[i] = numplayersingame - data.match.pos[data.match.numplayers]; data.match.increase[i] = nospectategrief - data.match.pos[data.match.numplayers];
players[i].score += data.match.increase[i]; players[i].score += data.match.increase[i];
} }