Merge branch 'splitscreen-fixes' into 'master'

Some major cleanup to splitscreen HUD and spectator support; starting bumpers fix + ring sting indicator

Closes #692

See merge request KartKrew/Kart!1539
This commit is contained in:
Oni 2023-10-04 05:15:12 +00:00
commit 26973e6539
29 changed files with 407 additions and 456 deletions

View file

@ -419,6 +419,9 @@ void D_RegisterServerCommands(void)
COM_AddDebugCommand("downloads", Command_Downloads_f); COM_AddDebugCommand("downloads", Command_Downloads_f);
COM_AddDebugCommand("give", Command_KartGiveItem_f); COM_AddDebugCommand("give", Command_KartGiveItem_f);
COM_AddDebugCommand("give2", Command_KartGiveItem_f);
COM_AddDebugCommand("give3", Command_KartGiveItem_f);
COM_AddDebugCommand("give4", Command_KartGiveItem_f);
COM_AddCommand("schedule_add", Command_Schedule_Add); COM_AddCommand("schedule_add", Command_Schedule_Add);
COM_AddCommand("schedule_clear", Command_Schedule_Clear); COM_AddCommand("schedule_clear", Command_Schedule_Clear);
@ -1606,6 +1609,22 @@ static void GetViewablePlayerPlaceRange(INT32 *first, INT32 *last)
} }
} }
static int GetCommandViewNumber(void)
{
char c = COM_Argv(0)[strlen(COM_Argv(0))-1];/* may be digit */
switch (c)
{
default:
return 0;
case '2':
case '3':
case '4':
return c - '1';
}
}
#define PRINTVIEWPOINT( pre,suf ) \ #define PRINTVIEWPOINT( pre,suf ) \
CONS_Printf(pre"viewing \x84(%d) \x83%s\x80"suf".\n",\ CONS_Printf(pre"viewing \x84(%d) \x83%s\x80"suf".\n",\
(*displayplayerp), player_names[(*displayplayerp)]); (*displayplayerp), player_names[(*displayplayerp)]);
@ -1613,21 +1632,11 @@ static void Command_View_f(void)
{ {
INT32 *displayplayerp; INT32 *displayplayerp;
INT32 olddisplayplayer; INT32 olddisplayplayer;
int viewnum; int viewnum = 1 + GetCommandViewNumber();
const char *playerparam; const char *playerparam;
INT32 placenum; INT32 placenum;
INT32 playernum; INT32 playernum;
INT32 firstplace, lastplace; INT32 firstplace, lastplace;
char c;
/* easy peasy */
c = COM_Argv(0)[strlen(COM_Argv(0))-1];/* may be digit */
switch (c)
{
case '2': viewnum = 2; break;
case '3': viewnum = 3; break;
case '4': viewnum = 4; break;
default: viewnum = 1;
}
if (viewnum > 1 && !( multiplayer && demo.playback )) if (viewnum > 1 && !( multiplayer && demo.playback ))
{ {
@ -1710,13 +1719,6 @@ static void Command_SetViews_f(void)
UINT8 splits; UINT8 splits;
UINT8 newsplits; UINT8 newsplits;
if (!( demo.playback && multiplayer ))
{
CONS_Alert(CONS_NOTICE,
"You must be viewing a multiplayer replay to use this.\n");
return;
}
if (COM_Argc() != 2) if (COM_Argc() != 2)
{ {
CONS_Printf("setviews <views>: set the number of split screens\n"); CONS_Printf("setviews <views>: set the number of split screens\n");
@ -1727,12 +1729,26 @@ static void Command_SetViews_f(void)
newsplits = atoi(COM_Argv(1)); newsplits = atoi(COM_Argv(1));
newsplits = min(max(newsplits, 1), 4); newsplits = min(max(newsplits, 1), 4);
if (newsplits > splits)
if (newsplits > splits && demo.playback && multiplayer)
{
G_AdjustView(newsplits, 0, true); G_AdjustView(newsplits, 0, true);
}
else else
{ {
// Even if the splits go beyond the real number of
// splitscreen players, displayplayers was filled
// with duplicates of P1 (see Got_AddPlayer).
r_splitscreen = newsplits-1; r_splitscreen = newsplits-1;
R_ExecuteSetViewSize(); R_ExecuteSetViewSize();
// If promoting (outside of replays), make sure the
// camera is in the correct position.
UINT8 i;
for (i = splits + 1; i <= newsplits; ++i)
{
G_FixCamera(i);
}
} }
} }
@ -5917,6 +5933,8 @@ static void Command_Archivetest_f(void)
*/ */
static void Command_KartGiveItem_f(void) static void Command_KartGiveItem_f(void)
{ {
UINT8 localplayer = g_localplayers[GetCommandViewNumber()];
int ac; int ac;
const char *name; const char *name;
INT32 item; INT32 item;
@ -5972,7 +5990,7 @@ static void Command_KartGiveItem_f(void)
else else
amt = BATTLE_POWERUP_TIME; amt = BATTLE_POWERUP_TIME;
D_Cheat(consoleplayer, CHEAT_GIVEPOWERUP, item, amt); D_Cheat(localplayer, CHEAT_GIVEPOWERUP, item, amt);
} }
else if (item < NUMKARTITEMS) else if (item < NUMKARTITEMS)
{ {
@ -5983,7 +6001,7 @@ static void Command_KartGiveItem_f(void)
else else
amt = (item != KITEM_NONE);/* default to one quantity, or zero, if KITEM_NONE */ amt = (item != KITEM_NONE);/* default to one quantity, or zero, if KITEM_NONE */
D_Cheat(consoleplayer, CHEAT_GIVEITEM, item, amt); D_Cheat(localplayer, CHEAT_GIVEITEM, item, amt);
} }
else else
{ {

View file

@ -206,7 +206,15 @@ class TiccmdBuilder
else else
#endif #endif
{ {
localangle[viewnum] += angleChange; int p = g_localplayers[forplayer()];
for (int i = 0; i <= r_splitscreen; ++i)
{
if (displayplayers[i] == p)
{
localangle[i] += angleChange;
}
}
} }
} }
@ -237,7 +245,7 @@ class TiccmdBuilder
bool director_input() bool director_input()
{ {
if (demo.freecam || G_IsPartyLocal(displayplayers[forplayer()]) == true) if (demo.freecam || !K_DirectorIsAvailable(viewnum))
{ {
return false; return false;
} }

View file

@ -1507,13 +1507,15 @@ boolean G_CouldView(INT32 playernum)
// //
boolean G_CanView(INT32 playernum, UINT8 viewnum, boolean onlyactive) boolean G_CanView(INT32 playernum, UINT8 viewnum, boolean onlyactive)
{ {
if (!playeringame[playernum] || players[playernum].spectator)
{
return false;
}
UINT8 splits; UINT8 splits;
UINT8 viewd; UINT8 viewd;
INT32 *displayplayerp; INT32 *displayplayerp;
if (!(onlyactive ? G_CouldView(playernum) : (playeringame[playernum] && !players[playernum].spectator)))
return false;
splits = r_splitscreen+1; splits = r_splitscreen+1;
if (viewnum > splits) if (viewnum > splits)
viewnum = splits; viewnum = splits;
@ -1522,15 +1524,18 @@ boolean G_CanView(INT32 playernum, UINT8 viewnum, boolean onlyactive)
{ {
displayplayerp = (&displayplayers[viewd-1]); displayplayerp = (&displayplayers[viewd-1]);
if ((*displayplayerp) == playernum) if ((*displayplayerp) == playernum)
return false; return true;
} }
for (viewd = viewnum + 1; viewd <= splits; ++viewd) for (viewd = viewnum + 1; viewd <= splits; ++viewd)
{ {
displayplayerp = (&displayplayers[viewd-1]); displayplayerp = (&displayplayers[viewd-1]);
if ((*displayplayerp) == playernum) if ((*displayplayerp) == playernum)
return false; return true;
} }
if (onlyactive && !G_CouldView(playernum))
return false;
return true; return true;
} }
@ -1580,7 +1585,6 @@ void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive)
UINT8 viewd; UINT8 viewd;
INT32 *displayplayerp; INT32 *displayplayerp;
camera_t *camerap;
INT32 olddisplayplayer; INT32 olddisplayplayer;
INT32 playersviewable; INT32 playersviewable;
@ -1631,22 +1635,14 @@ void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive)
(*displayplayerp) = playernum; (*displayplayerp) = playernum;
if ((*displayplayerp) != olddisplayplayer) if ((*displayplayerp) != olddisplayplayer)
{ {
camerap = &camera[viewnum-1]; G_FixCamera(viewnum);
P_ResetCamera(&players[(*displayplayerp)], camerap);
R_ResetViewInterpolation(viewnum);
} }
if (viewnum > splits) if (viewnum > splits)
{ {
for (viewd = splits+1; viewd < viewnum; ++viewd) for (viewd = splits+1; viewd < viewnum; ++viewd)
{ {
displayplayerp = (&displayplayers[viewd-1]); G_FixCamera(viewd);
camerap = &camera[viewd];
(*displayplayerp) = G_FindView(0, viewd, onlyactive, false);
P_ResetCamera(&players[(*displayplayerp)], camerap);
} }
} }
@ -1708,6 +1704,26 @@ void G_ResetViews(void)
} }
} }
//
// G_FixCamera
// Reset camera position, angle and interpolation on a view
// after changing state.
//
void G_FixCamera(UINT8 view)
{
player_t *player = &players[displayplayers[view - 1]];
// The order of displayplayers can change, which would
// invalidate localangle.
localangle[view - 1] = player->angleturn;
P_ResetCamera(player, &camera[view - 1]);
// Make sure the viewport doesn't interpolate at all into
// its new position -- just snap instantly into place.
R_ResetViewInterpolation(view);
}
// //
// G_Ticker // G_Ticker
// Make ticcmd_ts for the players. // Make ticcmd_ts for the players.

View file

@ -240,6 +240,7 @@ INT32 G_CountPlayersPotentiallyViewable(boolean active);
void G_ResetViews(void); void G_ResetViews(void);
void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive); void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive);
void G_AdjustView(UINT8 viewnum, INT32 offset, boolean onlyactive); void G_AdjustView(UINT8 viewnum, INT32 offset, boolean onlyactive);
void G_FixCamera(UINT8 viewnum);
void G_AddPlayer(INT32 playernum); void G_AddPlayer(INT32 playernum);
void G_SpectatePlayerOnJoin(INT32 playernum); void G_SpectatePlayerOnJoin(INT32 playernum);

View file

@ -19,7 +19,7 @@
#include "d_clisrv.h" // playerconsole #include "d_clisrv.h" // playerconsole
#include "doomdef.h" // MAXPLAYERS #include "doomdef.h" // MAXPLAYERS
#include "doomstat.h" // consoleplayer #include "doomstat.h" // consoleplayer
#include "g_game.h" // localangle #include "g_game.h" // G_FixCamera
#include "g_party.h" #include "g_party.h"
#include "g_state.h" #include "g_state.h"
#include "p_local.h" #include "p_local.h"
@ -136,20 +136,8 @@ public:
for (std::size_t i = 0; i < size(); ++i) for (std::size_t i = 0; i < size(); ++i)
{ {
const playernum_t player = at(i); displayplayers[i] = at(i);
G_FixCamera(1 + i);
displayplayers[i] = player;
// The order of displayplayers can change, which
// would make localangle invalid now.
localangle[i] = players[player].angleturn;
P_ResetCamera(&players[player], &camera[i]);
// Make sure the viewport doesn't interpolate at
// all into its new position -- just snap
// instantly into place.
R_ResetViewInterpolation(1 + i);
} }
r_splitscreen = size() - 1; r_splitscreen = size() - 1;

View file

@ -5398,17 +5398,7 @@ static void HWR_DrawSkyBackground(player_t *player)
{ {
FTransform dometransform; FTransform dometransform;
const float fpov = FIXED_TO_FLOAT(cv_fov[viewssnum].value+player->fovadd); const float fpov = FIXED_TO_FLOAT(cv_fov[viewssnum].value+player->fovadd);
postimg_t *type = &postimgtype[0]; postimg_t *type = &postimgtype[R_GetViewNumber()];
SINT8 i;
for (i = r_splitscreen; i >= 0; i--)
{
if (player == &players[displayplayers[i]])
{
type = &postimgtype[i];
break;
}
}
memset(&dometransform, 0x00, sizeof(FTransform)); memset(&dometransform, 0x00, sizeof(FTransform));
@ -6104,20 +6094,10 @@ INT32 HWR_GetTextureUsed(void)
void HWR_DoPostProcessor(player_t *player) void HWR_DoPostProcessor(player_t *player)
{ {
postimg_t *type = &postimgtype[0]; postimg_t *type = &postimgtype[R_GetViewNumber()];
SINT8 i;
HWD.pfnUnSetShader(); HWD.pfnUnSetShader();
for (i = r_splitscreen; i >= 0; i--)
{
if (player == &players[displayplayers[i]])
{
type = &postimgtype[i];
break;
}
}
// Armageddon Blast Flash! // Armageddon Blast Flash!
// Could this even be considered postprocessor? // Could this even be considered postprocessor?
if (player->flashcount) if (player->flashcount)

View file

@ -90,10 +90,10 @@ void K_drawKartPowerUps(void)
switch (r_splitscreen) switch (r_splitscreen)
{ {
case 0: case 0:
return { make_drawer(307, 55, Draw::Font::kZVote), "PWRU", -17, 7, -35, -1 }; return { make_drawer(307, 58, Draw::Font::kZVote), "PWRU", -17, 7, -35, -1 };
case 1: case 1:
return { make_drawer(318, viewnum == 0 ? 55 : 155, Draw::Font::kPing), "PWRS", -9, 6, -19, -1 }; return { make_drawer(318, viewnum == 0 ? 58 : 147, Draw::Font::kPing), "PWRS", -9, 6, -19, -1 };
} }
// 3/4P // 3/4P

View file

@ -4,6 +4,7 @@
#include "../g_game.h" #include "../g_game.h"
#include "../k_hud.h" #include "../k_hud.h"
#include "../p_local.h" #include "../p_local.h"
#include "../r_fps.h"
#include "../v_draw.hpp" #include "../v_draw.hpp"
using srb2::Draw; using srb2::Draw;
@ -24,13 +25,13 @@ void K_drawKart2PTimestamp(void)
{ {
auto get_row = [] auto get_row = []
{ {
if (stplyr == &players[displayplayers[0]]) if (R_GetViewNumber() == 0)
{ {
return Draw(286, 31).flags(V_SNAPTOTOP); return Draw(287, 33).flags(V_SNAPTOTOP);
} }
else else
{ {
return Draw(286, 163).flags(V_SNAPTOBOTTOM); return Draw(287, 156).flags(V_SNAPTOBOTTOM);
} }
}; };

View file

@ -107,62 +107,6 @@ static void postframe_update(Rhi& rhi)
g_hw_state.palette_manager->destroy_per_frame_resources(rhi); g_hw_state.palette_manager->destroy_per_frame_resources(rhi);
} }
#ifdef HWRENDER
static void finish_legacy_ogl_update()
{
int player;
SCR_CalculateFPS();
if (st_overlay)
{
if (cv_songcredits.value)
HU_DrawSongCredits();
if (cv_ticrate.value)
SCR_DisplayTicRate();
if (cv_showping.value && netgame && (consoleplayer != serverplayer || !server_lagless))
{
if (server_lagless)
{
if (consoleplayer != serverplayer)
SCR_DisplayLocalPing();
}
else
{
for (player = 1; player < MAXPLAYERS; player++)
{
if (D_IsPlayerHumanAndGaming(player))
{
SCR_DisplayLocalPing();
break;
}
}
}
}
if (cv_mindelay.value && consoleplayer == serverplayer && Playing())
SCR_DisplayLocalPing();
}
if (marathonmode)
SCR_DisplayMarathonInfo();
// draw captions if enabled
if (cv_closedcaptioning.value)
SCR_ClosedCaptions();
#ifdef HAVE_DISCORDRPC
if (discordRequestList != NULL)
ST_AskToJoinEnvelope();
#endif
ST_drawDebugInfo();
OglSdlFinishUpdate(cv_vidwait.value);
}
#endif
static void temp_legacy_finishupdate_draws() static void temp_legacy_finishupdate_draws()
{ {
SCR_CalculateFPS(); SCR_CalculateFPS();
@ -215,6 +159,14 @@ static void temp_legacy_finishupdate_draws()
ST_drawDebugInfo(); ST_drawDebugInfo();
} }
#ifdef HWRENDER
static void finish_legacy_ogl_update()
{
temp_legacy_finishupdate_draws();
OglSdlFinishUpdate(cv_vidwait.value);
}
#endif
static void new_twodee_frame() static void new_twodee_frame()
{ {
g_2d = Twodee(); g_2d = Twodee();

View file

@ -801,24 +801,6 @@ void K_BattleInit(boolean singleplayercontext)
battleprisons = true; battleprisons = true;
} }
if (gametyperules & GTR_BUMPERS)
{
const INT32 startingHealth = K_BumpersToHealth(K_StartingBumperCount());
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
continue;
if (players[i].mo)
{
players[i].mo->health = startingHealth;
}
K_SpawnPlayerBattleBumpers(players+i);
}
}
g_battleufo.due = starttime; g_battleufo.due = starttime;
g_battleufo.previousId = Obj_GetFirstBattleUFOSpawnerID(); g_battleufo.previousId = Obj_GetFirstBattleUFOSpawnerID();
} }

View file

@ -11,6 +11,7 @@
#include "k_director.h" #include "k_director.h"
#include "d_netcmd.h" #include "d_netcmd.h"
#include "p_local.h" #include "p_local.h"
#include "g_party.h"
#define SWITCHTIME TICRATE * 5 // cooldown between unforced switches #define SWITCHTIME TICRATE * 5 // cooldown between unforced switches
#define BOREDOMTIME 3 * TICRATE / 2 // how long until players considered far apart? #define BOREDOMTIME 3 * TICRATE / 2 // how long until players considered far apart?
@ -322,3 +323,9 @@ void K_ToggleDirector(boolean active)
directorinfo.active = active; directorinfo.active = active;
} }
boolean K_DirectorIsAvailable(UINT8 viewnum)
{
return viewnum <= r_splitscreen && viewnum < G_PartySize(consoleplayer) &&
displayplayers[viewnum] != G_PartyMember(consoleplayer, viewnum);
}

View file

@ -28,6 +28,7 @@ void K_UpdateDirector(void);
void K_DrawDirectorDebugger(void); void K_DrawDirectorDebugger(void);
void K_DirectorFollowAttack(player_t *player, mobj_t *inflictor, mobj_t *source); void K_DirectorFollowAttack(player_t *player, mobj_t *inflictor, mobj_t *source);
void K_ToggleDirector(boolean active); void K_ToggleDirector(boolean active);
boolean K_DirectorIsAvailable(UINT8 viewnum);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"

View file

@ -100,6 +100,7 @@ static patch_t *kp_speedometersticker;
static patch_t *kp_speedometerlabel[4]; static patch_t *kp_speedometerlabel[4];
static patch_t *kp_rankbumper; static patch_t *kp_rankbumper;
static patch_t *kp_bigbumper;
static patch_t *kp_tinybumper[2]; static patch_t *kp_tinybumper[2];
static patch_t *kp_ranknobumpers; static patch_t *kp_ranknobumpers;
static patch_t *kp_rankcapsule; static patch_t *kp_rankcapsule;
@ -439,6 +440,7 @@ void K_LoadKartHUDGraphics(void)
// Extra ranking icons // Extra ranking icons
HU_UpdatePatch(&kp_rankbumper, "K_BLNICO"); HU_UpdatePatch(&kp_rankbumper, "K_BLNICO");
HU_UpdatePatch(&kp_bigbumper, "K_BLNBIG");
HU_UpdatePatch(&kp_tinybumper[0], "K_BLNA"); HU_UpdatePatch(&kp_tinybumper[0], "K_BLNA");
HU_UpdatePatch(&kp_tinybumper[1], "K_BLNB"); HU_UpdatePatch(&kp_tinybumper[1], "K_BLNB");
HU_UpdatePatch(&kp_ranknobumpers, "K_NOBLNS"); HU_UpdatePatch(&kp_ranknobumpers, "K_NOBLNS");
@ -1481,7 +1483,7 @@ static void K_drawKartItem(void)
// pain and suffering defined below // pain and suffering defined below
if (offset) if (offset)
{ {
if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) // If we are P1 or P3... if (!(R_GetViewNumber() & 1)) // If we are P1 or P3...
{ {
fx = ITEM_X; fx = ITEM_X;
fy = ITEM_Y; fy = ITEM_Y;
@ -1507,6 +1509,11 @@ static void K_drawKartItem(void)
fflags = V_SNAPTOTOP|V_SNAPTOLEFT|V_SPLITSCREEN; fflags = V_SNAPTOTOP|V_SNAPTOLEFT|V_SPLITSCREEN;
} }
if (r_splitscreen == 1)
{
fy -= 5;
}
V_DrawScaledPatch(fx, fy, V_HUDTRANS|V_SLIDEIN|fflags, localbg); V_DrawScaledPatch(fx, fy, V_HUDTRANS|V_SLIDEIN|fflags, localbg);
// Need to draw these in a particular order, for sorting. // Need to draw these in a particular order, for sorting.
@ -1622,7 +1629,7 @@ static void K_drawKartItem(void)
{ {
xo++; xo++;
if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) // Flip for P1 and P3 (yes, that's correct) if (!(R_GetViewNumber() & 1)) // Flip for P1 and P3 (yes, that's correct)
{ {
xo -= 62; xo -= 62;
flip = V_FLIP; flip = V_FLIP;
@ -1730,7 +1737,7 @@ static void K_drawKartSlotMachine(void)
if (offset) if (offset)
{ {
boxoffx -= 4; boxoffx -= 4;
if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) // If we are P1 or P3... if (!(R_GetViewNumber() & 1)) // If we are P1 or P3...
{ {
fx = ITEM_X + 10; fx = ITEM_X + 10;
fy = ITEM_Y + 10; fy = ITEM_Y + 10;
@ -1759,6 +1766,11 @@ static void K_drawKartSlotMachine(void)
fflags = V_SNAPTOTOP|V_SNAPTOLEFT|V_SPLITSCREEN; fflags = V_SNAPTOTOP|V_SNAPTOLEFT|V_SPLITSCREEN;
} }
if (r_splitscreen == 1)
{
fy -= 5;
}
V_DrawScaledPatch(fx, fy, V_HUDTRANS|V_SLIDEIN|fflags, localbg); V_DrawScaledPatch(fx, fy, V_HUDTRANS|V_SLIDEIN|fflags, localbg);
V_SetClipRect( V_SetClipRect(
@ -2052,7 +2064,7 @@ static void K_DrawKartPositionNum(UINT8 num)
{ {
fx = BASEVIDWIDTH << FRACBITS; fx = BASEVIDWIDTH << FRACBITS;
if (stplyr == &players[displayplayers[0]]) if (R_GetViewNumber() == 0)
{ {
// for player 1: display this at the top right, above the minimap. // for player 1: display this at the top right, above the minimap.
fy = 0; fy = 0;
@ -2071,8 +2083,7 @@ static void K_DrawKartPositionNum(UINT8 num)
{ {
fy = BASEVIDHEIGHT << FRACBITS; fy = BASEVIDHEIGHT << FRACBITS;
if (stplyr == &players[displayplayers[0]] if (!(R_GetViewNumber() & 1)) // If we are P1 or P3...
|| stplyr == &players[displayplayers[2]])
{ {
// If we are P1 or P3... // If we are P1 or P3...
fx = 0; fx = 0;
@ -2098,6 +2109,8 @@ static void K_DrawKartPositionNum(UINT8 num)
fflags |= (trans << V_ALPHASHIFT); fflags |= (trans << V_ALPHASHIFT);
} }
fflags |= V_SLIDEIN;
if (stplyr->exiting && num == 1) if (stplyr->exiting && num == 1)
{ {
// 1st place winner? You get rainbows!! // 1st place winner? You get rainbows!!
@ -2128,7 +2141,7 @@ static void K_DrawKartPositionNum(UINT8 num)
color = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_POSNUM, GTC_CACHE); color = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_POSNUM, GTC_CACHE);
} }
if ((fflags & V_SNAPTORIGHT) == 0 && num > 9) if ((fflags & V_SNAPTORIGHT) == 0)
{ {
const UINT8 splitIndex = (r_splitscreen > 0) ? 1 : 0; const UINT8 splitIndex = (r_splitscreen > 0) ? 1 : 0;
UINT8 adjustNum = num; UINT8 adjustNum = num;
@ -2512,7 +2525,7 @@ static void K_drawKartEmeralds(void)
if (r_splitscreen < 2) if (r_splitscreen < 2)
{ {
startx -= 8; startx -= 8;
if (r_splitscreen == 1 && stplyr == &players[displayplayers[0]]) if (r_splitscreen == 1 && R_GetViewNumber() == 0)
{ {
starty = 1; starty = 1;
} }
@ -2522,7 +2535,7 @@ static void K_drawKartEmeralds(void)
{ {
xindex = 2; xindex = 2;
starty -= 15; starty -= 15;
if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) // If we are P1 or P3... if (!(R_GetViewNumber() & 1)) // If we are P1 or P3...
{ {
startx = LAPS_X; startx = LAPS_X;
splitflags = V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_SPLITSCREEN; splitflags = V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_SPLITSCREEN;
@ -2586,7 +2599,7 @@ static void K_drawKartLaps(void)
} }
else else
{ {
if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) // If we are P1 or P3... if (!(R_GetViewNumber() & 1)) // If we are P1 or P3...
{ {
fx = LAPS_X; fx = LAPS_X;
fy = LAPS_Y; fy = LAPS_Y;
@ -2693,7 +2706,7 @@ static void K_drawRingCounter(boolean gametypeinfoshown)
} }
else else
{ {
if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) // If we are P1 or P3... if (!(R_GetViewNumber() & 1)) // If we are P1 or P3...
{ {
fx = LAPS_X; fx = LAPS_X;
fy = LAPS_Y; fy = LAPS_Y;
@ -2728,10 +2741,16 @@ static void K_drawRingCounter(boolean gametypeinfoshown)
V_DrawMappedPatch(fr+ringx, fy-3, V_HUDTRANS|V_SLIDEIN|splitflags|ringflip, kp_smallring[ringanim_realframe], (colorring ? ringmap : NULL)); V_DrawMappedPatch(fr+ringx, fy-3, V_HUDTRANS|V_SLIDEIN|splitflags|ringflip, kp_smallring[ringanim_realframe], (colorring ? ringmap : NULL));
if (stplyr->hudrings < 0) // Draw the minus for ring debt if (stplyr->hudrings < 0) // Draw the minus for ring debt
V_DrawMappedPatch(fr+7, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_ringdebtminussmall, ringmap); {
V_DrawMappedPatch(fr+11, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_ringdebtminussmall, ringmap);
V_DrawMappedPatch(fr+11, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[rn[0]], ringmap); V_DrawMappedPatch(fr+15, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[rn[0]], ringmap);
V_DrawMappedPatch(fr+15, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[rn[1]], ringmap); V_DrawMappedPatch(fr+19, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[rn[1]], ringmap);
}
else
{
V_DrawMappedPatch(fr+11, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[rn[0]], ringmap);
V_DrawMappedPatch(fr+15, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[rn[1]], ringmap);
}
// SPB ring lock // SPB ring lock
if (stplyr->pflags & PF_RINGLOCK) if (stplyr->pflags & PF_RINGLOCK)
@ -2833,7 +2852,7 @@ static void K_drawKartAccessibilityIcons(boolean gametypeinfoshown, INT32 fx)
{ {
fx = LAPS_X+44; fx = LAPS_X+44;
fy = LAPS_Y; fy = LAPS_Y;
if (!(stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]])) // If we are not P1 or P3... if (R_GetViewNumber() & 1) // If we are not P1 or P3...
{ {
splitflags ^= (V_SNAPTOLEFT|V_SNAPTORIGHT); splitflags ^= (V_SNAPTOLEFT|V_SNAPTORIGHT);
fx = (BASEVIDWIDTH/2) - fx; fx = (BASEVIDWIDTH/2) - fx;
@ -2904,6 +2923,11 @@ static void K_drawKartSpeedometer(boolean gametypeinfoshown)
INT32 splitflags = V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN; INT32 splitflags = V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN;
INT32 fy = LAPS_Y-14; INT32 fy = LAPS_Y-14;
if (battleprisons)
{
fy -= 2;
}
if (!stplyr->exiting) // Keep the same speed value as when you crossed the finish line! if (!stplyr->exiting) // Keep the same speed value as when you crossed the finish line!
{ {
switch (cv_kartspeedometer.value) switch (cv_kartspeedometer.value)
@ -2976,7 +3000,23 @@ static void K_drawBlueSphereMeter(boolean gametypeinfoshown)
if (r_splitscreen < 2) // don't change shit for THIS splitscreen. if (r_splitscreen < 2) // don't change shit for THIS splitscreen.
{ {
fx = LAPS_X; fx = LAPS_X;
fy = LAPS_Y-7; fy = LAPS_Y-4;
if (battleprisons)
{
if (r_splitscreen == 1)
{
fy -= 8;
}
else
{
fy -= 5;
}
}
else if (r_splitscreen == 1)
{
fy -= 5;
}
if (gametypeinfoshown) if (gametypeinfoshown)
{ {
@ -2992,7 +3032,7 @@ static void K_drawBlueSphereMeter(boolean gametypeinfoshown)
else else
{ {
xstep = 8; xstep = 8;
if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) // If we are P1 or P3... if (!(R_GetViewNumber() & 1)) // If we are P1 or P3...
{ {
fx = LAPS_X-2; fx = LAPS_X-2;
fy = LAPS_Y; fy = LAPS_Y;
@ -3006,6 +3046,11 @@ static void K_drawBlueSphereMeter(boolean gametypeinfoshown)
xstep = -xstep; xstep = -xstep;
} }
if (battleprisons)
{
fy -= 5;
}
if (gametypeinfoshown) if (gametypeinfoshown)
{ {
fy -= 16; fy -= 16;
@ -3077,7 +3122,7 @@ static void K_drawKartBumpersOrKarma(void)
} }
else else
{ {
if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) // If we are P1 or P3... if (!(R_GetViewNumber() & 1)) // If we are P1 or P3...
{ {
fx = LAPS_X; fx = LAPS_X;
fy = LAPS_Y; fy = LAPS_Y;
@ -3093,11 +3138,13 @@ static void K_drawKartBumpersOrKarma(void)
} }
V_DrawScaledPatch(fx-2 + (flipflag ? (SHORT(kp_ringstickersplit[1]->width) - 3) : 0), fy, V_HUDTRANS|V_SLIDEIN|splitflags|flipflag, kp_ringstickersplit[0]); V_DrawScaledPatch(fx-2 + (flipflag ? (SHORT(kp_ringstickersplit[1]->width) - 3) : 0), fy, V_HUDTRANS|V_SLIDEIN|splitflags|flipflag, kp_ringstickersplit[0]);
V_DrawScaledPatch(fx+22, fy, V_HUDTRANS|V_SLIDEIN|splitflags, frameslash);
fx += 2;
if (battleprisons) if (battleprisons)
{ {
V_DrawMappedPatch(fx+1, fy-2, V_HUDTRANS|V_SLIDEIN|splitflags, kp_rankcapsule, NULL); V_DrawScaledPatch(fx+22, fy, V_HUDTRANS|V_SLIDEIN|splitflags, frameslash);
V_DrawMappedPatch(fx-1, fy-2, V_HUDTRANS|V_SLIDEIN|splitflags, kp_rankcapsule, NULL);
if (numtargets > 9 || maptargets > 9) if (numtargets > 9 || maptargets > 9)
{ {
@ -3122,54 +3169,42 @@ static void K_drawKartBumpersOrKarma(void)
} }
else else
{ {
const INT32 maxbumper = K_StartingBumperCount();
const UINT8 bumpers = K_Bumpers(stplyr); const UINT8 bumpers = K_Bumpers(stplyr);
V_DrawMappedPatch(fx+1, fy-2, V_HUDTRANS|V_SLIDEIN|splitflags, kp_rankbumper, colormap); V_DrawMappedPatch(fx-1, fy-2, V_HUDTRANS|V_SLIDEIN|splitflags, kp_rankbumper, colormap);
if (bumpers > 9 || maxbumper > 9) UINT8 ln[2];
{ ln[0] = (bumpers / 10 % 10);
UINT8 ln[2]; ln[1] = (bumpers % 10);
ln[0] = (bumpers / 10 % 10);
ln[1] = (bumpers % 10);
V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]); V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[ln[0]]);
V_DrawScaledPatch(fx+17, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]); V_DrawScaledPatch(fx+19, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[ln[1]]);
ln[0] = ((abs(maxbumper) / 10) % 10);
ln[1] = (abs(maxbumper) % 10);
V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[0]]);
V_DrawScaledPatch(fx+31, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[ln[1]]);
}
else
{
V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(bumpers) % 10]);
V_DrawScaledPatch(fx+27, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(maxbumper) % 10]);
}
} }
} }
else else
{ {
INT32 fy = r_splitscreen == 1 ? LAPS_Y-3 : LAPS_Y;
if (battleprisons) if (battleprisons)
{ {
if (numtargets > 9 && maptargets > 9) if (numtargets > 9 && maptargets > 9)
V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_capsulestickerwide, NULL); V_DrawMappedPatch(LAPS_X, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_capsulestickerwide, NULL);
else else
V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_capsulesticker, NULL); V_DrawMappedPatch(LAPS_X, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_capsulesticker, NULL);
V_DrawTimerString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", numtargets, maptargets)); V_DrawTimerString(LAPS_X+47, fy+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", numtargets, maptargets));
} }
else else
{ {
const INT32 maxbumper = K_StartingBumperCount();
const UINT8 bumpers = K_Bumpers(stplyr); const UINT8 bumpers = K_Bumpers(stplyr);
if (bumpers > 9 && maxbumper > 9) if (r_splitscreen == 0)
V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumperstickerwide, colormap); {
else fy += 2;
V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumpersticker, colormap); }
V_DrawTimerString(LAPS_X+47, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", bumpers, maxbumper)); K_DrawSticker(LAPS_X+12, fy+5, bumpers > 9 ? 64 : 52, V_HUDTRANS|V_SLIDEIN|splitflags, false);
V_DrawMappedPatch(LAPS_X+15, fy-5, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bigbumper, colormap);
V_DrawTimerString(LAPS_X+47, fy+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d", bumpers));
} }
} }
} }
@ -3418,7 +3453,7 @@ static void K_DrawNameTagForPlayer(fixed_t x, fixed_t y, player_t *p)
// Since there's no "V_DrawFixedFill", and I don't feel like making it, // Since there's no "V_DrawFixedFill", and I don't feel like making it,
// fuck it, we're gonna just V_NOSCALESTART hack it // fuck it, we're gonna just V_NOSCALESTART hack it
if (cnum & 1) if (r_splitscreen > 1 && cnum & 1)
{ {
x += (BASEVIDWIDTH/2) * FRACUNIT; x += (BASEVIDWIDTH/2) * FRACUNIT;
} }
@ -3704,20 +3739,10 @@ static void K_drawKartNameTags(void)
if (result.onScreen == true) if (result.onScreen == true)
{ {
if (!(demo.playback == true && demo.freecam == true)) if (!(demo.playback == true && demo.freecam == true) && P_IsDisplayPlayer(ntplayer) &&
ntplayer != &players[displayplayers[cnum]])
{ {
for (j = 0; j <= (unsigned)r_splitscreen; j++) localindicator = G_PartyPosition(ntplayer - players);
{
if (ntplayer == &players[displayplayers[j]])
{
break;
}
}
if (j <= (unsigned)r_splitscreen && j != cnum)
{
localindicator = j;
}
} }
if (localindicator >= 0) if (localindicator >= 0)
@ -3896,7 +3921,7 @@ static void K_drawKartMinimap(void)
// Only draw for the first player // Only draw for the first player
// Maybe move this somewhere else where this won't be a concern? // Maybe move this somewhere else where this won't be a concern?
if (stplyr != &players[displayplayers[0]]) if (R_GetViewNumber() != 0)
return; return;
if (specialstageinfo.valid == true) if (specialstageinfo.valid == true)
@ -4431,7 +4456,7 @@ static void K_drawKartFinish(boolean finish)
interpx = R_InterpolateFixed(ox, x); interpx = R_InterpolateFixed(ox, x);
if (r_splitscreen && stplyr == &players[displayplayers[1]]) if (r_splitscreen && R_GetViewNumber() == 1)
interpx = -interpx; interpx = -interpx;
V_DrawFixedPatch(interpx + (STCD_X<<FRACBITS) - (pwidth / 2), V_DrawFixedPatch(interpx + (STCD_X<<FRACBITS) - (pwidth / 2),
@ -4669,14 +4694,12 @@ static void K_drawKartFirstPerson(void)
if (stplyr->spectator || !stplyr->mo || (stplyr->mo->renderflags & RF_DONTDRAW)) if (stplyr->spectator || !stplyr->mo || (stplyr->mo->renderflags & RF_DONTDRAW))
return; return;
if (stplyr == &players[displayplayers[1]] && r_splitscreen) {
{ pn = pnum[1]; tn = turn[1]; dr = drift[1]; } UINT8 view = R_GetViewNumber();
else if (stplyr == &players[displayplayers[2]] && r_splitscreen > 1) pn = pnum[view];
{ pn = pnum[2]; tn = turn[2]; dr = drift[2]; } tn = turn[view];
else if (stplyr == &players[displayplayers[3]] && r_splitscreen > 2) dr = drift[view];
{ pn = pnum[3]; tn = turn[3]; dr = drift[3]; } }
else
{ pn = pnum[0]; tn = turn[0]; dr = drift[0]; }
if (r_splitscreen) if (r_splitscreen)
{ {
@ -4805,14 +4828,12 @@ static void K_drawKartFirstPerson(void)
V_DrawFixedPatch(x, y, scale, splitflags, kp_fpview[target], colmap); V_DrawFixedPatch(x, y, scale, splitflags, kp_fpview[target], colmap);
if (stplyr == &players[displayplayers[1]] && r_splitscreen) {
{ pnum[1] = pn; turn[1] = tn; drift[1] = dr; } UINT8 view = R_GetViewNumber();
else if (stplyr == &players[displayplayers[2]] && r_splitscreen > 1) pnum[view] = pn;
{ pnum[2] = pn; turn[2] = tn; drift[2] = dr; } turn[view] = tn;
else if (stplyr == &players[displayplayers[3]] && r_splitscreen > 2) drift[view] = dr;
{ pnum[3] = pn; turn[3] = tn; drift[3] = dr; } }
else
{ pnum[0] = pn; turn[0] = tn; drift[0] = dr; }
} }
// doesn't need to ever support 4p // doesn't need to ever support 4p
@ -5060,23 +5081,26 @@ void K_drawKartFreePlay(void)
if (((leveltime-lt_endtime) % TICRATE) < TICRATE/2) if (((leveltime-lt_endtime) % TICRATE) < TICRATE/2)
return; return;
const fixed_t x = ((BASEVIDWIDTH - (LAPS_X+6)) * FRACUNIT) - \ INT32 h_snap = (r_splitscreen < 2 || R_GetViewNumber() & 1) ? V_SNAPTORIGHT : V_SNAPTOLEFT;
V_StringScaledWidth( fixed_t x = ((r_splitscreen > 1 ? BASEVIDWIDTH/4 : BASEVIDWIDTH - (LAPS_X+6)) * FRACUNIT);
fixed_t y = ((r_splitscreen ? BASEVIDHEIGHT/2 : BASEVIDHEIGHT) - 20) * FRACUNIT;
x -= V_StringScaledWidth(
FRACUNIT, FRACUNIT,
FRACUNIT, FRACUNIT,
FRACUNIT, FRACUNIT,
V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_SPLITSCREEN, V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|h_snap|V_SPLITSCREEN,
KART_FONT, KART_FONT,
"FREE PLAY" "FREE PLAY"
); ) / (r_splitscreen > 1 ? 2 : 1);
V_DrawStringScaled( V_DrawStringScaled(
x, x,
(LAPS_Y+3) * FRACUNIT, y,
FRACUNIT, FRACUNIT,
FRACUNIT, FRACUNIT,
FRACUNIT, FRACUNIT,
V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_SPLITSCREEN, V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|h_snap|V_SPLITSCREEN,
NULL, NULL,
KART_FONT, KART_FONT,
"FREE PLAY" "FREE PLAY"
@ -5086,33 +5110,26 @@ void K_drawKartFreePlay(void)
static void static void
Draw_party_ping (int ss, INT32 snap) Draw_party_ping (int ss, INT32 snap)
{ {
HU_drawMiniPing(0, 0, playerpingtable[displayplayers[ss]], V_HUDTRANS|V_SPLITSCREEN|V_SNAPTOTOP|snap); HU_drawMiniPing(0, 0, playerpingtable[displayplayers[ss]], V_SPLITSCREEN|V_SNAPTOTOP|snap);
} }
static void static void
K_drawMiniPing (void) K_drawMiniPing (void)
{ {
UINT32 f = V_SNAPTORIGHT; UINT32 f = V_SNAPTORIGHT;
UINT8 i; UINT8 i = R_GetViewNumber();
if (!cv_showping.value) if (!cv_showping.value)
{ {
return; return;
} }
for (i = 0; i <= r_splitscreen; i++) if (r_splitscreen > 1 && !(i & 1))
{ {
if (stplyr == &players[displayplayers[i]]) f = V_SNAPTOLEFT;
{
if (r_splitscreen > 1 && !(i & 1))
{
f = V_SNAPTOLEFT;
}
Draw_party_ping(i, f);
break;
}
} }
Draw_party_ping(i, f);
} }
void K_drawButton(fixed_t x, fixed_t y, INT32 flags, patch_t *button[2], boolean pressed) void K_drawButton(fixed_t x, fixed_t y, INT32 flags, patch_t *button[2], boolean pressed)
@ -5210,7 +5227,7 @@ static void K_drawDistributionDebugger(void)
fixed_t y = -pad; fixed_t y = -pad;
size_t i; size_t i;
if (stplyr != &players[displayplayers[0]]) // only for p1 if (R_GetViewNumber() != 0) // only for p1
{ {
return; return;
} }
@ -5268,7 +5285,7 @@ static void K_DrawWaypointDebugger(void)
if (cv_kartdebugwaypoints.value == 0) if (cv_kartdebugwaypoints.value == 0)
return; return;
if (stplyr != &players[displayplayers[0]]) // only for p1 if (R_GetViewNumber() != 0) // only for p1
return; return;
if (netgame) if (netgame)
@ -5298,7 +5315,7 @@ static void K_DrawBotDebugger(void)
return; return;
} }
if (stplyr != &players[displayplayers[0]]) // only for p1 if (R_GetViewNumber() != 0) // only for p1
{ {
return; return;
} }
@ -5368,7 +5385,7 @@ static void K_DrawGPRankDebugger(void)
return; return;
} }
if (stplyr != &players[displayplayers[0]]) // only for p1 if (R_GetViewNumber() != 0) // only for p1
{ {
return; return;
} }
@ -5425,7 +5442,7 @@ void K_drawKartHUD(void)
K_drawKartFirstPerson(); K_drawKartFirstPerson();
// 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 && stplyr == &players[displayplayers[0]]) if (mapreset && R_GetViewNumber() == 0)
{ {
K_drawChallengerScreen(); K_drawChallengerScreen();
return; return;
@ -5455,19 +5472,6 @@ void K_drawKartHUD(void)
K_drawKartMinimap(); K_drawKartMinimap();
} }
// Draw the item window
if (LUA_HudEnabled(hud_item) && !freecam)
{
if (stplyr->itemRoulette.ringbox && stplyr->itemamount == 0 && stplyr->itemtype == 0)
{
K_drawKartSlotMachine();
}
else
{
K_drawKartItem();
}
}
if (demo.title) if (demo.title)
; ;
else if (!r_splitscreen) else if (!r_splitscreen)
@ -5482,18 +5486,23 @@ void K_drawKartHUD(void)
islonesome = K_drawKartPositionFaces(); islonesome = K_drawKartPositionFaces();
} }
else if (r_splitscreen == 1) else
{ {
if (LUA_HudEnabled(hud_time)) islonesome = M_NotFreePlay() == false;
if (r_splitscreen == 1)
{ {
K_drawKart2PTimestamp(); if (LUA_HudEnabled(hud_time))
{
K_drawKart2PTimestamp();
}
} }
} else if (viewnum == r_splitscreen)
else if (viewnum == r_splitscreen)
{
if (LUA_HudEnabled(hud_time))
{ {
K_drawKart4PTimestamp(); if (LUA_HudEnabled(hud_time))
{
K_drawKart4PTimestamp();
}
} }
} }
@ -5581,6 +5590,19 @@ void K_drawKartHUD(void)
if (LUA_HudEnabled(hud_position)) if (LUA_HudEnabled(hud_position))
K_drawInput(); K_drawInput();
} }
// Draw the item window
if (LUA_HudEnabled(hud_item) && !freecam)
{
if (stplyr->itemRoulette.ringbox && stplyr->itemamount == 0 && stplyr->itemtype == 0)
{
K_drawKartSlotMachine();
}
else
{
K_drawKartItem();
}
}
} }
} }
@ -5640,7 +5662,7 @@ void K_drawKartHUD(void)
K_drawKartPowerUps(); K_drawKartPowerUps();
if (G_IsPartyLocal(displayplayers[viewnum]) == false) if (K_DirectorIsAvailable(viewnum) == true)
{ {
K_drawDirectorHUD(); K_drawDirectorHUD();
} }

View file

@ -264,13 +264,13 @@ UINT32 K_GetPlayerDontDrawFlag(player_t *player)
return flag; return flag;
if (player == &players[displayplayers[0]]) if (player == &players[displayplayers[0]])
flag = RF_DONTDRAWP1; flag |= RF_DONTDRAWP1;
else if (r_splitscreen >= 1 && player == &players[displayplayers[1]]) if (r_splitscreen >= 1 && player == &players[displayplayers[1]])
flag = RF_DONTDRAWP2; flag |= RF_DONTDRAWP2;
else if (r_splitscreen >= 2 && player == &players[displayplayers[2]]) if (r_splitscreen >= 2 && player == &players[displayplayers[2]])
flag = RF_DONTDRAWP3; flag |= RF_DONTDRAWP3;
else if (r_splitscreen >= 3 && player == &players[displayplayers[3]]) if (r_splitscreen >= 3 && player == &players[displayplayers[3]])
flag = RF_DONTDRAWP4; flag |= RF_DONTDRAWP4;
return flag; return flag;
} }
@ -7927,8 +7927,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
debtflag->color = player->skincolor; debtflag->color = player->skincolor;
debtflag->fuse = 2; debtflag->fuse = 2;
debtflag->renderflags = K_GetPlayerDontDrawFlag(player);
} }
if (player->springstars && (leveltime & 1)) if (player->springstars && (leveltime & 1))

View file

@ -33,6 +33,7 @@
#include "m_easing.h" #include "m_easing.h"
#include "s_sound.h" #include "s_sound.h"
#include "st_stuff.h" #include "st_stuff.h"
#include "r_fps.h"
boolean level_tally_t::UseBonuses(void) boolean level_tally_t::UseBonuses(void)
{ {
@ -883,14 +884,14 @@ void level_tally_t::Draw(void)
SINT8 h_transition_sign = 1; SINT8 h_transition_sign = 1;
if (r_splitscreen > 1) if (r_splitscreen > 1)
{ {
if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) if (!(R_GetViewNumber() & 1))
{ {
h_transition_sign = -h_transition_sign; h_transition_sign = -h_transition_sign;
} }
} }
else if (r_splitscreen > 0) else if (r_splitscreen > 0)
{ {
if (stplyr == &players[displayplayers[1]]) if (R_GetViewNumber() == 1)
{ {
h_transition_sign = -h_transition_sign; h_transition_sign = -h_transition_sign;
} }

View file

@ -662,7 +662,7 @@ static int libd_drawOnMinimap(lua_State *L)
if (gamestate != GS_LEVEL) if (gamestate != GS_LEVEL)
return 0; return 0;
if (stplyr != &players[displayplayers[0]]) if (R_GetViewNumber() != 0)
return 0; return 0;
AutomapPic = mapheaderinfo[gamemap-1]->minimapPic; AutomapPic = mapheaderinfo[gamemap-1]->minimapPic;

View file

@ -599,7 +599,6 @@ static int player_set(lua_State *L)
if (plr == &players[displayplayers[i]]) if (plr == &players[displayplayers[i]])
{ {
localaiming[i] = plr->aiming; localaiming[i] = plr->aiming;
break;
} }
} }
} }

View file

@ -1439,7 +1439,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
if (target->player == &players[displayplayers[i]]) if (target->player == &players[displayplayers[i]])
{ {
localaiming[i] = 0; localaiming[i] = 0;
break;
} }
} }

View file

@ -154,7 +154,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount);
void P_ResetCamera(player_t *player, camera_t *thiscam); void P_ResetCamera(player_t *player, camera_t *thiscam);
boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam); boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam);
void P_SlideCameraMove(camera_t *thiscam); void P_SlideCameraMove(camera_t *thiscam);
void P_DemoCameraMovement(camera_t *cam); void P_DemoCameraMovement(camera_t *cam, UINT8 num);
boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled); boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled);
void P_ToggleDemoCamera(void); void P_ToggleDemoCamera(void);
@ -167,7 +167,6 @@ boolean P_IsMachineLocalPlayer(player_t *player);
boolean P_IsDisplayPlayer(player_t *player); boolean P_IsDisplayPlayer(player_t *player);
void P_SetPlayerAngle(player_t *player, angle_t angle); void P_SetPlayerAngle(player_t *player, angle_t angle);
angle_t P_GetLocalAngle(player_t *player);
void P_ForceLocalAngle(player_t *player, angle_t angle); void P_ForceLocalAngle(player_t *player, angle_t angle);
boolean P_PlayerFullbright(player_t *player); boolean P_PlayerFullbright(player_t *player);

View file

@ -12090,13 +12090,8 @@ void P_SpawnPlayer(INT32 playernum)
if ((gametyperules & GTR_BUMPERS) && !p->spectator) if ((gametyperules & GTR_BUMPERS) && !p->spectator)
{ {
// At leveltime == 2, K_TimerInit will get called and reset mobj->health = K_BumpersToHealth(K_StartingBumperCount());
// the bumpers to the initial value for the level. K_SpawnPlayerBattleBumpers(p);
if (leveltime > 2) // Reset those bumpers!
{
mobj->health = K_BumpersToHealth(K_StartingBumperCount());
K_SpawnPlayerBattleBumpers(p);
}
} }
// Block visuals // Block visuals

View file

@ -2867,7 +2867,6 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha
camera[i].z += z; camera[i].z += z;
camera[i].subsector = R_PointInSubsector(camera[i].x, camera[i].y); camera[i].subsector = R_PointInSubsector(camera[i].x, camera[i].y);
R_RelativeTeleportViewInterpolation(i, x, y, z, 0); R_RelativeTeleportViewInterpolation(i, x, y, z, 0);
break;
} }
} }
} }

View file

@ -79,7 +79,6 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
if (camera[i].chase) if (camera[i].chase)
P_ResetCamera(thing->player, &camera[i]); P_ResetCamera(thing->player, &camera[i]);
R_ResetViewInterpolation(i + 1); R_ResetViewInterpolation(i + 1);
break;
} }
// don't run in place after a teleport // don't run in place after a teleport
@ -170,8 +169,6 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle
} }
R_ResetViewInterpolation(1 + i); R_ResetViewInterpolation(1 + i);
break;
} }
} }

View file

@ -2887,7 +2887,7 @@ fixed_t t_cam_rotate[MAXSPLITSCREENPLAYERS] = {-42,-42,-42,-42};
struct demofreecam_s democam; struct demofreecam_s democam;
void P_DemoCameraMovement(camera_t *cam) void P_DemoCameraMovement(camera_t *cam, UINT8 num)
{ {
ticcmd_t *cmd; ticcmd_t *cmd;
angle_t thrustangle; angle_t thrustangle;
@ -2897,7 +2897,7 @@ void P_DemoCameraMovement(camera_t *cam)
boolean moving = false; boolean moving = false;
// first off we need to get button input // first off we need to get button input
cmd = D_LocalTiccmd(0); cmd = D_LocalTiccmd(num);
if (cmd->aiming != 0) if (cmd->aiming != 0)
{ {
@ -3083,18 +3083,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
if (thiscam->subsector == NULL || thiscam->subsector->sector == NULL) if (thiscam->subsector == NULL || thiscam->subsector->sector == NULL)
return true; return true;
if (demo.freecam || player->spectator)
{
P_DemoCameraMovement(thiscam);
return true;
}
if (paused || P_AutoPause())
return true;
playerScale = FixedDiv(player->mo->scale, mapobjectscale);
scaleDiff = playerScale - FRACUNIT;
if (thiscam == &camera[1]) // Camera 2 if (thiscam == &camera[1]) // Camera 2
{ {
num = 1; num = 1;
@ -3112,6 +3100,18 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
num = 0; num = 0;
} }
if (demo.freecam || player->spectator)
{
P_DemoCameraMovement(thiscam, num);
return true;
}
if (paused || P_AutoPause())
return true;
playerScale = FixedDiv(player->mo->scale, mapobjectscale);
scaleDiff = playerScale - FRACUNIT;
mo = player->mo; mo = player->mo;
if (P_MobjIsFrozen(mo) || player->playerstate == PST_DEAD) if (P_MobjIsFrozen(mo) || player->playerstate == PST_DEAD)
@ -3544,19 +3544,10 @@ boolean P_SpectatorJoinGame(player_t *player)
player->enteredGame = true; player->enteredGame = true;
// Reset away view (some code referenced from Got_Teamchange) // Reset away view (some code referenced from Got_Teamchange)
if (G_IsPartyLocal(player - players))
{ {
UINT8 i = 0; LUA_HookViewpointSwitch(player, player, true);
const UINT8 *localplayertable = G_PartyArray(consoleplayer); displayplayers[G_PartyPosition(player - players)] = (player-players);
for (i = 0; i <= r_splitscreen; i++)
{
if (localplayertable[i] == (player-players))
{
LUA_HookViewpointSwitch(player, player, true);
displayplayers[i] = (player-players);
break;
}
}
} }
// a surprise tool that will help us later... // a surprise tool that will help us later...
@ -3572,11 +3563,11 @@ boolean P_SpectatorJoinGame(player_t *player)
} }
// the below is first person only, if you're curious. check out P_CalcChasePostImg in p_mobj.c for chasecam // the below is first person only, if you're curious. check out P_CalcChasePostImg in p_mobj.c for chasecam
static void P_CalcPostImg(player_t *player) static void P_CalcPostImg(player_t *player, size_t viewnum)
{ {
sector_t *sector = player->mo->subsector->sector; sector_t *sector = player->mo->subsector->sector;
postimg_t *type = NULL; postimg_t *type = &postimgtype[viewnum];
INT32 *param; INT32 *param = &postimgparam[viewnum];
fixed_t pviewheight; fixed_t pviewheight;
size_t i; size_t i;
@ -3591,16 +3582,6 @@ static void P_CalcPostImg(player_t *player)
pviewheight = player->awayview.mobj->z; pviewheight = player->awayview.mobj->z;
} }
for (i = 0; i <= (unsigned)r_splitscreen; i++)
{
if (player == &players[displayplayers[i]])
{
type = &postimgtype[i];
param = &postimgparam[i];
break;
}
}
// see if we are in heat (no, not THAT kind of heat...) // see if we are in heat (no, not THAT kind of heat...)
for (i = 0; i < sector->tags.count; i++) for (i = 0; i < sector->tags.count; i++)
{ {
@ -4400,7 +4381,6 @@ void P_PlayerThink(player_t *player)
// //
void P_PlayerAfterThink(player_t *player) void P_PlayerAfterThink(player_t *player)
{ {
camera_t *thiscam = NULL; // if not one of the displayed players, just don't bother
UINT8 i; UINT8 i;
#ifdef PARANOIA #ifdef PARANOIA
@ -4425,15 +4405,6 @@ void P_PlayerAfterThink(player_t *player)
P_PlayerInSpecialSector(player); P_PlayerInSpecialSector(player);
#endif #endif
for (i = 0; i <= r_splitscreen; i++)
{
if (player == &players[displayplayers[i]])
{
thiscam = &camera[i];
break;
}
}
if (player->playerstate == PST_DEAD) if (player->playerstate == PST_DEAD)
{ {
// Followers need handled while dead. // Followers need handled while dead.
@ -4448,12 +4419,20 @@ void P_PlayerAfterThink(player_t *player)
return; return;
} }
if (thiscam)
{ {
if (!thiscam->chase) // bob view only if looking through the player's eyes boolean chase = true;
for (i = 0; i <= r_splitscreen; i++)
{
if (player == &players[displayplayers[i]] && !camera[i].chase)
{
chase = false;
}
}
if (!chase) // bob view only if looking through the player's eyes
{ {
P_CalcHeight(player); P_CalcHeight(player);
P_CalcPostImg(player);
} }
else else
{ {
@ -4466,6 +4445,14 @@ void P_PlayerAfterThink(player_t *player)
else else
player->viewz = player->mo->z + player->viewheight; player->viewz = player->mo->z + player->viewheight;
} }
for (i = 0; i <= r_splitscreen; i++)
{
if (player == &players[displayplayers[i]] && !camera[i].chase)
{
P_CalcPostImg(player, i);
}
}
} }
// spectator invisibility and nogravity. // spectator invisibility and nogravity.
@ -4530,10 +4517,15 @@ void P_PlayerAfterThink(player_t *player)
K_UpdateBotGameplayVars(player); K_UpdateBotGameplayVars(player);
} }
if (thiscam) for (i = 0; i <= r_splitscreen; i++)
{ {
if (player != &players[displayplayers[i]])
{
continue;
}
// Store before it gets 0'd out // Store before it gets 0'd out
thiscam->pmomz = player->mo->pmomz; camera[i].pmomz = player->mo->pmomz;
} }
if (P_IsObjectOnGround(player->mo)) if (P_IsObjectOnGround(player->mo))
@ -4632,21 +4624,6 @@ void P_SetPlayerAngle(player_t *player, angle_t angle)
player->angleturn = angle; player->angleturn = angle;
} }
angle_t P_GetLocalAngle(player_t *player)
{
// this function is from vanilla srb2. can you tell?
// (hint: they have separate variables for all of this shit instead of arrays)
UINT8 i;
for (i = 0; i <= r_splitscreen; i++)
{
if (player == &players[displayplayers[i]])
return localangle[i];
}
return 0;
}
void P_ForceLocalAngle(player_t *player, angle_t angle) void P_ForceLocalAngle(player_t *player, angle_t angle)
{ {
UINT8 i; UINT8 i;
@ -4658,8 +4635,6 @@ void P_ForceLocalAngle(player_t *player, angle_t angle)
if (player == &players[displayplayers[i]]) if (player == &players[displayplayers[i]])
{ {
localangle[i] = angle; localangle[i] = angle;
break;
} }
} }

View file

@ -20,6 +20,7 @@
#include "r_local.h" #include "r_local.h"
#include "r_state.h" #include "r_state.h"
#include "r_portal.h" // Add seg portals #include "r_portal.h" // Add seg portals
#include "r_fps.h"
#include "r_splats.h" #include "r_splats.h"
#include "p_local.h" // camera #include "p_local.h" // camera
@ -276,18 +277,11 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
mobj_t *viewmobj = viewplayer->mo; mobj_t *viewmobj = viewplayer->mo;
INT32 heightsec; INT32 heightsec;
boolean underwater; boolean underwater;
UINT8 i; UINT8 i = R_GetViewNumber();
for (i = 0; i <= r_splitscreen; i++) if (camera[i].chase)
{ heightsec = R_PointInSubsector(camera[i].x, camera[i].y)->sector->heightsec;
if (viewplayer == &players[displayplayers[i]] && camera[i].chase) else if (i > r_splitscreen && viewmobj)
{
heightsec = R_PointInSubsector(camera[i].x, camera[i].y)->sector->heightsec;
break;
}
}
if (i > r_splitscreen && viewmobj)
heightsec = R_PointInSubsector(viewmobj->x, viewmobj->y)->sector->heightsec; heightsec = R_PointInSubsector(viewmobj->x, viewmobj->y)->sector->heightsec;
else else
return sec; return sec;

View file

@ -22,6 +22,7 @@
#include "r_state.h" #include "r_state.h"
#include "z_zone.h" #include "z_zone.h"
#include "console.h" // con_startup_loadprogress #include "console.h" // con_startup_loadprogress
#include "i_time.h"
UINT32 R_GetFramerateCap(void) UINT32 R_GetFramerateCap(void)
{ {
@ -58,6 +59,7 @@ static viewvars_t skyview_old[MAXSPLITSCREENPLAYERS];
static viewvars_t skyview_new[MAXSPLITSCREENPLAYERS]; static viewvars_t skyview_new[MAXSPLITSCREENPLAYERS];
static viewvars_t *oldview = &pview_old[0]; static viewvars_t *oldview = &pview_old[0];
static tic_t last_view_update;
static int oldview_invalid[MAXSPLITSCREENPLAYERS] = {0, 0, 0, 0}; static int oldview_invalid[MAXSPLITSCREENPLAYERS] = {0, 0, 0, 0};
viewvars_t *newview = &pview_new[0]; viewvars_t *newview = &pview_new[0];
@ -165,21 +167,27 @@ void R_UpdateViewInterpolation(void)
skyview_old[i] = skyview_new[i]; skyview_old[i] = skyview_new[i];
if (oldview_invalid[i] > 0) oldview_invalid[i]--; if (oldview_invalid[i] > 0) oldview_invalid[i]--;
} }
last_view_update = I_GetTime();
} }
void R_ResetViewInterpolation(UINT8 p) void R_ResetViewInterpolation(UINT8 p)
{ {
// Wait an extra tic if the interpolation state hasn't
// updated yet.
int t = last_view_update == I_GetTime() ? 1 : 2;
if (p == 0) if (p == 0)
{ {
UINT8 i; UINT8 i;
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++) for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{ {
oldview_invalid[i]++; oldview_invalid[i] = t;
} }
} }
else else
{ {
oldview_invalid[p - 1]++; oldview_invalid[p - 1] = t;
} }
} }

View file

@ -20,6 +20,7 @@
#include "g_game.h" #include "g_game.h"
#include "p_setup.h" // levelflats #include "p_setup.h" // levelflats
#include "p_slopes.h" #include "p_slopes.h"
#include "r_fps.h"
#include "r_data.h" #include "r_data.h"
#include "r_textures.h" #include "r_textures.h"
#include "r_local.h" #include "r_local.h"
@ -963,8 +964,6 @@ void R_DrawSinglePlane(visplane_t *pl)
planeripple.active = true; planeripple.active = true;
if (spanfunctype == SPANDRAWFUNC_TRANS) if (spanfunctype == SPANDRAWFUNC_TRANS)
{ {
UINT8 i;
spanfunctype = SPANDRAWFUNC_WATER; spanfunctype = SPANDRAWFUNC_WATER;
// Copy the current scene, ugh // Copy the current scene, ugh
@ -977,43 +976,38 @@ void R_DrawSinglePlane(visplane_t *pl)
bottom = viewheight; bottom = viewheight;
// Only copy the part of the screen we need // Only copy the part of the screen we need
for (i = 0; i <= r_splitscreen; i++) UINT8 i = R_GetViewNumber();
INT32 scrx = 0;
INT32 scry = top;
INT32 offset;
if (r_splitscreen == 1)
{ {
if (viewplayer == &players[displayplayers[i]]) if (i & 1)
{ {
INT32 scrx = 0; scry += viewheight;
INT32 scry = top;
INT32 offset;
if (r_splitscreen == 1)
{
if (i & 1)
{
scry += viewheight;
}
}
else
{
if (i & 1)
{
scrx += viewwidth;
}
if (i / 2)
{
scry += viewheight;
}
}
offset = (scry*vid.width) + scrx;
// No idea if this works
VID_BlitLinearScreen(screens[0] + offset,
screens[1] + (top*vid.width), // intentionally not +offset
viewwidth, bottom-top,
vid.width, vid.width);
} }
} }
else
{
if (i & 1)
{
scrx += viewwidth;
}
if (i / 2)
{
scry += viewheight;
}
}
offset = (scry*vid.width) + scrx;
// No idea if this works
VID_BlitLinearScreen(screens[0] + offset,
screens[1] + (top*vid.width), // intentionally not +offset
viewwidth, bottom-top,
vid.width, vid.width);
} }
} }
#endif #endif

View file

@ -532,12 +532,9 @@ void SCR_DisplayTicRate(void)
const UINT8 *ticcntcolor = NULL; const UINT8 *ticcntcolor = NULL;
UINT32 cap = R_GetFramerateCap(); UINT32 cap = R_GetFramerateCap();
UINT32 benchmark = (cap == 0) ? I_GetRefreshRate() : cap; UINT32 benchmark = (cap == 0) ? I_GetRefreshRate() : cap;
INT32 x = 318; INT32 x = 317;
double fps = round(averageFPS); double fps = round(averageFPS);
// draw "FPS"
V_DrawFixedPatch(306<<FRACBITS, 183<<FRACBITS, FRACUNIT, V_SNAPTOBOTTOM|V_SNAPTORIGHT, framecounter, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_YELLOW, GTC_CACHE));
if (fps > (benchmark * 0.9)) if (fps > (benchmark * 0.9))
ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_MINT, GTC_CACHE); ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_MINT, GTC_CACHE);
else if (fps < (benchmark * 0.5)) else if (fps < (benchmark * 0.5))
@ -571,15 +568,28 @@ void SCR_DisplayTicRate(void)
void SCR_DisplayLocalPing(void) void SCR_DisplayLocalPing(void)
{ {
boolean offline; // Splitscreen party has its own ping counter, but show the
// 1P version anyway in some cases:
UINT32 ping = playerpingtable[consoleplayer]; // consoleplayer's ping is everyone's ping in a splitnetgame :P // - On intermission, vote, etc. gamestates where the player
if (! r_splitscreen && ( cv_showping.value == 1 || (cv_showping.value == 2 && ping > servermaxping) )) // only show 2 (warning) if our ping is at a bad level // HUD is not drawn.
// - If the menu is opened, since it draws over the player
// HUD.
if (r_splitscreen && gamestate == GS_LEVEL && !menuactive)
{ {
INT32 dispy = cv_ticrate.value ? 160 : 181; return;
offline = (consoleplayer == serverplayer);
HU_drawPing(307 * FRACUNIT, dispy * FRACUNIT, ping, V_SNAPTORIGHT | V_SNAPTOBOTTOM | V_HUDTRANS, offline, 0);
} }
UINT32 ping = playerpingtable[consoleplayer];
if (cv_showping.value == 2 && ping <= servermaxping) // only show 2 (warning) if our ping is at a bad level
{
return;
}
INT32 dispy = cv_ticrate.value ? 170 : 181;
boolean offline = (consoleplayer == serverplayer);
HU_drawPing(307 * FRACUNIT, dispy * FRACUNIT, ping, V_SNAPTORIGHT | V_SNAPTOBOTTOM, offline, 0);
} }

View file

@ -1203,7 +1203,7 @@ static void ST_overlayDrawer(void)
{ {
char name[MAXPLAYERNAME+12]; char name[MAXPLAYERNAME+12];
INT32 y = (stplyr == &players[displayplayers[0]]) ? 4 : BASEVIDHEIGHT/2-12; INT32 y = (viewnum == 0) ? 4 : BASEVIDHEIGHT/2-12;
sprintf(name, "VIEWPOINT: %s", player_names[stplyr-players]); sprintf(name, "VIEWPOINT: %s", player_names[stplyr-players]);
V_DrawRightAlignedThinString(BASEVIDWIDTH-40, y, V_HUDTRANSHALF|V_SNAPTOTOP|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_SPLITSCREEN, name); V_DrawRightAlignedThinString(BASEVIDWIDTH-40, y, V_HUDTRANSHALF|V_SNAPTOTOP|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_SPLITSCREEN, name);
} }
@ -1451,8 +1451,15 @@ static fixed_t ST_CalculateFadeIn(player_t *player)
if (player->tally.hudSlide != 0) if (player->tally.hudSlide != 0)
{ {
tic_t timer = length - player->tally.hudSlide; tic_t timer = length - player->tally.hudSlide;
fixed_t f = timer * FRACUNIT;
return ((timer * FRACUNIT) + (FRACUNIT - rendertimefrac)) / length; // Not interpolated at very beginning or end
if (timer > 0 && timer < length)
{
f += FRACUNIT - rendertimefrac;
}
return f / length;
} }
tic_t timer = lt_exitticker; tic_t timer = lt_exitticker;
@ -1467,9 +1474,18 @@ static fixed_t ST_CalculateFadeIn(player_t *player)
if (timer < length) if (timer < length)
{ {
return ((timer * FRACUNIT) + rendertimefrac) / length; fixed_t f = timer * FRACUNIT;
// Not interpolated at very beginning
if (timer > 0)
{
f += rendertimefrac;
}
return f / length;
} }
// Not interpolated at very end
return FRACUNIT; return FRACUNIT;
} }

View file

@ -27,6 +27,7 @@
#include "f_finale.h" #include "f_finale.h"
#include "r_draw.h" #include "r_draw.h"
#include "console.h" #include "console.h"
#include "r_fps.h"
#include "i_video.h" // rendermode #include "i_video.h" // rendermode
#include "z_zone.h" #include "z_zone.h"
@ -513,8 +514,7 @@ void V_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dupx, INT32 du
INT32 screenheight = vid.height; INT32 screenheight = vid.height;
INT32 basewidth = BASEVIDWIDTH * dupx; INT32 basewidth = BASEVIDWIDTH * dupx;
INT32 baseheight = BASEVIDHEIGHT * dupy; INT32 baseheight = BASEVIDHEIGHT * dupy;
SINT8 player = -1; SINT8 player = R_GetViewNumber();
UINT8 i;
if (options & V_SPLITSCREEN) if (options & V_SPLITSCREEN)
{ {
@ -531,15 +531,6 @@ void V_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dupx, INT32 du
} }
} }
for (i = 0; i <= r_splitscreen; i++)
{
if (stplyr == &players[displayplayers[i]])
{
player = i;
break;
}
}
if (vid.width != (BASEVIDWIDTH * dupx)) if (vid.width != (BASEVIDWIDTH * dupx))
{ {
if (options & V_SNAPTORIGHT) if (options & V_SNAPTORIGHT)
@ -586,7 +577,7 @@ void V_AdjustXYWithSnap(INT32 *x, INT32 *y, UINT32 options, INT32 dupx, INT32 du
if (r_splitscreen > 1) if (r_splitscreen > 1)
{ {
if (stplyr == &players[displayplayers[1]] || stplyr == &players[displayplayers[3]]) if (player & 1)
slidefromright = true; slidefromright = true;
} }