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("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_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 ) \
CONS_Printf(pre"viewing \x84(%d) \x83%s\x80"suf".\n",\
(*displayplayerp), player_names[(*displayplayerp)]);
@ -1613,21 +1632,11 @@ static void Command_View_f(void)
{
INT32 *displayplayerp;
INT32 olddisplayplayer;
int viewnum;
int viewnum = 1 + GetCommandViewNumber();
const char *playerparam;
INT32 placenum;
INT32 playernum;
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 ))
{
@ -1710,13 +1719,6 @@ static void Command_SetViews_f(void)
UINT8 splits;
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)
{
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 = min(max(newsplits, 1), 4);
if (newsplits > splits)
if (newsplits > splits && demo.playback && multiplayer)
{
G_AdjustView(newsplits, 0, true);
}
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_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)
{
UINT8 localplayer = g_localplayers[GetCommandViewNumber()];
int ac;
const char *name;
INT32 item;
@ -5972,7 +5990,7 @@ static void Command_KartGiveItem_f(void)
else
amt = BATTLE_POWERUP_TIME;
D_Cheat(consoleplayer, CHEAT_GIVEPOWERUP, item, amt);
D_Cheat(localplayer, CHEAT_GIVEPOWERUP, item, amt);
}
else if (item < NUMKARTITEMS)
{
@ -5983,7 +6001,7 @@ static void Command_KartGiveItem_f(void)
else
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
{

View file

@ -206,7 +206,15 @@ class TiccmdBuilder
else
#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()
{
if (demo.freecam || G_IsPartyLocal(displayplayers[forplayer()]) == true)
if (demo.freecam || !K_DirectorIsAvailable(viewnum))
{
return false;
}

View file

@ -1507,13 +1507,15 @@ boolean G_CouldView(INT32 playernum)
//
boolean G_CanView(INT32 playernum, UINT8 viewnum, boolean onlyactive)
{
if (!playeringame[playernum] || players[playernum].spectator)
{
return false;
}
UINT8 splits;
UINT8 viewd;
INT32 *displayplayerp;
if (!(onlyactive ? G_CouldView(playernum) : (playeringame[playernum] && !players[playernum].spectator)))
return false;
splits = r_splitscreen+1;
if (viewnum > splits)
viewnum = splits;
@ -1522,15 +1524,18 @@ boolean G_CanView(INT32 playernum, UINT8 viewnum, boolean onlyactive)
{
displayplayerp = (&displayplayers[viewd-1]);
if ((*displayplayerp) == playernum)
return false;
return true;
}
for (viewd = viewnum + 1; viewd <= splits; ++viewd)
{
displayplayerp = (&displayplayers[viewd-1]);
if ((*displayplayerp) == playernum)
return false;
return true;
}
if (onlyactive && !G_CouldView(playernum))
return false;
return true;
}
@ -1580,7 +1585,6 @@ void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive)
UINT8 viewd;
INT32 *displayplayerp;
camera_t *camerap;
INT32 olddisplayplayer;
INT32 playersviewable;
@ -1631,22 +1635,14 @@ void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive)
(*displayplayerp) = playernum;
if ((*displayplayerp) != olddisplayplayer)
{
camerap = &camera[viewnum-1];
P_ResetCamera(&players[(*displayplayerp)], camerap);
R_ResetViewInterpolation(viewnum);
G_FixCamera(viewnum);
}
if (viewnum > splits)
{
for (viewd = splits+1; viewd < viewnum; ++viewd)
{
displayplayerp = (&displayplayers[viewd-1]);
camerap = &camera[viewd];
(*displayplayerp) = G_FindView(0, viewd, onlyactive, false);
P_ResetCamera(&players[(*displayplayerp)], camerap);
G_FixCamera(viewd);
}
}
@ -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
// Make ticcmd_ts for the players.

View file

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

View file

@ -19,7 +19,7 @@
#include "d_clisrv.h" // playerconsole
#include "doomdef.h" // MAXPLAYERS
#include "doomstat.h" // consoleplayer
#include "g_game.h" // localangle
#include "g_game.h" // G_FixCamera
#include "g_party.h"
#include "g_state.h"
#include "p_local.h"
@ -136,20 +136,8 @@ public:
for (std::size_t i = 0; i < size(); ++i)
{
const playernum_t player = at(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);
displayplayers[i] = at(i);
G_FixCamera(1 + i);
}
r_splitscreen = size() - 1;

View file

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

View file

@ -90,10 +90,10 @@ void K_drawKartPowerUps(void)
switch (r_splitscreen)
{
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:
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

View file

@ -4,6 +4,7 @@
#include "../g_game.h"
#include "../k_hud.h"
#include "../p_local.h"
#include "../r_fps.h"
#include "../v_draw.hpp"
using srb2::Draw;
@ -24,13 +25,13 @@ void K_drawKart2PTimestamp(void)
{
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
{
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);
}
#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()
{
SCR_CalculateFPS();
@ -215,6 +159,14 @@ static void temp_legacy_finishupdate_draws()
ST_drawDebugInfo();
}
#ifdef HWRENDER
static void finish_legacy_ogl_update()
{
temp_legacy_finishupdate_draws();
OglSdlFinishUpdate(cv_vidwait.value);
}
#endif
static void new_twodee_frame()
{
g_2d = Twodee();

View file

@ -801,24 +801,6 @@ void K_BattleInit(boolean singleplayercontext)
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.previousId = Obj_GetFirstBattleUFOSpawnerID();
}

View file

@ -11,6 +11,7 @@
#include "k_director.h"
#include "d_netcmd.h"
#include "p_local.h"
#include "g_party.h"
#define SWITCHTIME TICRATE * 5 // cooldown between unforced switches
#define BOREDOMTIME 3 * TICRATE / 2 // how long until players considered far apart?
@ -322,3 +323,9 @@ void K_ToggleDirector(boolean 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_DirectorFollowAttack(player_t *player, mobj_t *inflictor, mobj_t *source);
void K_ToggleDirector(boolean active);
boolean K_DirectorIsAvailable(UINT8 viewnum);
#ifdef __cplusplus
} // extern "C"

View file

@ -100,6 +100,7 @@ static patch_t *kp_speedometersticker;
static patch_t *kp_speedometerlabel[4];
static patch_t *kp_rankbumper;
static patch_t *kp_bigbumper;
static patch_t *kp_tinybumper[2];
static patch_t *kp_ranknobumpers;
static patch_t *kp_rankcapsule;
@ -439,6 +440,7 @@ void K_LoadKartHUDGraphics(void)
// Extra ranking icons
HU_UpdatePatch(&kp_rankbumper, "K_BLNICO");
HU_UpdatePatch(&kp_bigbumper, "K_BLNBIG");
HU_UpdatePatch(&kp_tinybumper[0], "K_BLNA");
HU_UpdatePatch(&kp_tinybumper[1], "K_BLNB");
HU_UpdatePatch(&kp_ranknobumpers, "K_NOBLNS");
@ -1481,7 +1483,7 @@ static void K_drawKartItem(void)
// pain and suffering defined below
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;
fy = ITEM_Y;
@ -1507,6 +1509,11 @@ static void K_drawKartItem(void)
fflags = V_SNAPTOTOP|V_SNAPTOLEFT|V_SPLITSCREEN;
}
if (r_splitscreen == 1)
{
fy -= 5;
}
V_DrawScaledPatch(fx, fy, V_HUDTRANS|V_SLIDEIN|fflags, localbg);
// Need to draw these in a particular order, for sorting.
@ -1622,7 +1629,7 @@ static void K_drawKartItem(void)
{
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;
flip = V_FLIP;
@ -1730,7 +1737,7 @@ static void K_drawKartSlotMachine(void)
if (offset)
{
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;
fy = ITEM_Y + 10;
@ -1759,6 +1766,11 @@ static void K_drawKartSlotMachine(void)
fflags = V_SNAPTOTOP|V_SNAPTOLEFT|V_SPLITSCREEN;
}
if (r_splitscreen == 1)
{
fy -= 5;
}
V_DrawScaledPatch(fx, fy, V_HUDTRANS|V_SLIDEIN|fflags, localbg);
V_SetClipRect(
@ -2052,7 +2064,7 @@ static void K_DrawKartPositionNum(UINT8 num)
{
fx = BASEVIDWIDTH << FRACBITS;
if (stplyr == &players[displayplayers[0]])
if (R_GetViewNumber() == 0)
{
// for player 1: display this at the top right, above the minimap.
fy = 0;
@ -2071,8 +2083,7 @@ static void K_DrawKartPositionNum(UINT8 num)
{
fy = BASEVIDHEIGHT << FRACBITS;
if (stplyr == &players[displayplayers[0]]
|| stplyr == &players[displayplayers[2]])
if (!(R_GetViewNumber() & 1)) // If we are P1 or P3...
{
// If we are P1 or P3...
fx = 0;
@ -2098,6 +2109,8 @@ static void K_DrawKartPositionNum(UINT8 num)
fflags |= (trans << V_ALPHASHIFT);
}
fflags |= V_SLIDEIN;
if (stplyr->exiting && num == 1)
{
// 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);
}
if ((fflags & V_SNAPTORIGHT) == 0 && num > 9)
if ((fflags & V_SNAPTORIGHT) == 0)
{
const UINT8 splitIndex = (r_splitscreen > 0) ? 1 : 0;
UINT8 adjustNum = num;
@ -2512,7 +2525,7 @@ static void K_drawKartEmeralds(void)
if (r_splitscreen < 2)
{
startx -= 8;
if (r_splitscreen == 1 && stplyr == &players[displayplayers[0]])
if (r_splitscreen == 1 && R_GetViewNumber() == 0)
{
starty = 1;
}
@ -2522,7 +2535,7 @@ static void K_drawKartEmeralds(void)
{
xindex = 2;
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;
splitflags = V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_SPLITSCREEN;
@ -2586,7 +2599,7 @@ static void K_drawKartLaps(void)
}
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;
fy = LAPS_Y;
@ -2693,7 +2706,7 @@ static void K_drawRingCounter(boolean gametypeinfoshown)
}
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;
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));
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, 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+11, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_ringdebtminussmall, ringmap);
V_DrawMappedPatch(fr+15, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[rn[0]], 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
if (stplyr->pflags & PF_RINGLOCK)
@ -2833,7 +2852,7 @@ static void K_drawKartAccessibilityIcons(boolean gametypeinfoshown, INT32 fx)
{
fx = LAPS_X+44;
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);
fx = (BASEVIDWIDTH/2) - fx;
@ -2904,6 +2923,11 @@ static void K_drawKartSpeedometer(boolean gametypeinfoshown)
INT32 splitflags = V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN;
INT32 fy = LAPS_Y-14;
if (battleprisons)
{
fy -= 2;
}
if (!stplyr->exiting) // Keep the same speed value as when you crossed the finish line!
{
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.
{
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)
{
@ -2992,7 +3032,7 @@ static void K_drawBlueSphereMeter(boolean gametypeinfoshown)
else
{
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;
fy = LAPS_Y;
@ -3006,6 +3046,11 @@ static void K_drawBlueSphereMeter(boolean gametypeinfoshown)
xstep = -xstep;
}
if (battleprisons)
{
fy -= 5;
}
if (gametypeinfoshown)
{
fy -= 16;
@ -3077,7 +3122,7 @@ static void K_drawKartBumpersOrKarma(void)
}
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;
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+22, fy, V_HUDTRANS|V_SLIDEIN|splitflags, frameslash);
fx += 2;
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)
{
@ -3122,54 +3169,42 @@ static void K_drawKartBumpersOrKarma(void)
}
else
{
const INT32 maxbumper = K_StartingBumperCount();
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);
ln[1] = (bumpers % 10);
UINT8 ln[2];
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+17, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[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]);
}
V_DrawScaledPatch(fx+13, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[ln[0]]);
V_DrawScaledPatch(fx+19, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[ln[1]]);
}
}
else
{
INT32 fy = r_splitscreen == 1 ? LAPS_Y-3 : LAPS_Y;
if (battleprisons)
{
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
V_DrawMappedPatch(LAPS_X, LAPS_Y, 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_DrawMappedPatch(LAPS_X, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_capsulesticker, NULL);
V_DrawTimerString(LAPS_X+47, fy+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", numtargets, maptargets));
}
else
{
const INT32 maxbumper = K_StartingBumperCount();
const UINT8 bumpers = K_Bumpers(stplyr);
if (bumpers > 9 && maxbumper > 9)
V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumperstickerwide, colormap);
else
V_DrawMappedPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_bumpersticker, colormap);
if (r_splitscreen == 0)
{
fy += 2;
}
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,
// fuck it, we're gonna just V_NOSCALESTART hack it
if (cnum & 1)
if (r_splitscreen > 1 && cnum & 1)
{
x += (BASEVIDWIDTH/2) * FRACUNIT;
}
@ -3704,20 +3739,10 @@ static void K_drawKartNameTags(void)
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++)
{
if (ntplayer == &players[displayplayers[j]])
{
break;
}
}
if (j <= (unsigned)r_splitscreen && j != cnum)
{
localindicator = j;
}
localindicator = G_PartyPosition(ntplayer - players);
}
if (localindicator >= 0)
@ -3896,7 +3921,7 @@ static void K_drawKartMinimap(void)
// Only draw for the first player
// Maybe move this somewhere else where this won't be a concern?
if (stplyr != &players[displayplayers[0]])
if (R_GetViewNumber() != 0)
return;
if (specialstageinfo.valid == true)
@ -4431,7 +4456,7 @@ static void K_drawKartFinish(boolean finish)
interpx = R_InterpolateFixed(ox, x);
if (r_splitscreen && stplyr == &players[displayplayers[1]])
if (r_splitscreen && R_GetViewNumber() == 1)
interpx = -interpx;
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))
return;
if (stplyr == &players[displayplayers[1]] && r_splitscreen)
{ pn = pnum[1]; tn = turn[1]; dr = drift[1]; }
else if (stplyr == &players[displayplayers[2]] && r_splitscreen > 1)
{ pn = pnum[2]; tn = turn[2]; dr = drift[2]; }
else if (stplyr == &players[displayplayers[3]] && r_splitscreen > 2)
{ pn = pnum[3]; tn = turn[3]; dr = drift[3]; }
else
{ pn = pnum[0]; tn = turn[0]; dr = drift[0]; }
{
UINT8 view = R_GetViewNumber();
pn = pnum[view];
tn = turn[view];
dr = drift[view];
}
if (r_splitscreen)
{
@ -4805,14 +4828,12 @@ static void K_drawKartFirstPerson(void)
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; }
else if (stplyr == &players[displayplayers[2]] && r_splitscreen > 1)
{ pnum[2] = pn; turn[2] = tn; drift[2] = dr; }
else if (stplyr == &players[displayplayers[3]] && r_splitscreen > 2)
{ pnum[3] = pn; turn[3] = tn; drift[3] = dr; }
else
{ pnum[0] = pn; turn[0] = tn; drift[0] = dr; }
{
UINT8 view = R_GetViewNumber();
pnum[view] = pn;
turn[view] = tn;
drift[view] = dr;
}
}
// doesn't need to ever support 4p
@ -5060,23 +5081,26 @@ void K_drawKartFreePlay(void)
if (((leveltime-lt_endtime) % TICRATE) < TICRATE/2)
return;
const fixed_t x = ((BASEVIDWIDTH - (LAPS_X+6)) * FRACUNIT) - \
V_StringScaledWidth(
INT32 h_snap = (r_splitscreen < 2 || R_GetViewNumber() & 1) ? V_SNAPTORIGHT : V_SNAPTOLEFT;
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,
V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_SPLITSCREEN,
V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|h_snap|V_SPLITSCREEN,
KART_FONT,
"FREE PLAY"
);
) / (r_splitscreen > 1 ? 2 : 1);
V_DrawStringScaled(
x,
(LAPS_Y+3) * FRACUNIT,
y,
FRACUNIT,
FRACUNIT,
FRACUNIT,
V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_SPLITSCREEN,
V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|h_snap|V_SPLITSCREEN,
NULL,
KART_FONT,
"FREE PLAY"
@ -5086,33 +5110,26 @@ void K_drawKartFreePlay(void)
static void
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
K_drawMiniPing (void)
{
UINT32 f = V_SNAPTORIGHT;
UINT8 i;
UINT8 i = R_GetViewNumber();
if (!cv_showping.value)
{
return;
}
for (i = 0; i <= r_splitscreen; i++)
if (r_splitscreen > 1 && !(i & 1))
{
if (stplyr == &players[displayplayers[i]])
{
if (r_splitscreen > 1 && !(i & 1))
{
f = V_SNAPTOLEFT;
}
Draw_party_ping(i, f);
break;
}
f = V_SNAPTOLEFT;
}
Draw_party_ping(i, f);
}
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;
size_t i;
if (stplyr != &players[displayplayers[0]]) // only for p1
if (R_GetViewNumber() != 0) // only for p1
{
return;
}
@ -5268,7 +5285,7 @@ static void K_DrawWaypointDebugger(void)
if (cv_kartdebugwaypoints.value == 0)
return;
if (stplyr != &players[displayplayers[0]]) // only for p1
if (R_GetViewNumber() != 0) // only for p1
return;
if (netgame)
@ -5298,7 +5315,7 @@ static void K_DrawBotDebugger(void)
return;
}
if (stplyr != &players[displayplayers[0]]) // only for p1
if (R_GetViewNumber() != 0) // only for p1
{
return;
}
@ -5368,7 +5385,7 @@ static void K_DrawGPRankDebugger(void)
return;
}
if (stplyr != &players[displayplayers[0]]) // only for p1
if (R_GetViewNumber() != 0) // only for p1
{
return;
}
@ -5425,7 +5442,7 @@ void K_drawKartHUD(void)
K_drawKartFirstPerson();
// 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();
return;
@ -5455,19 +5472,6 @@ void K_drawKartHUD(void)
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)
;
else if (!r_splitscreen)
@ -5482,18 +5486,23 @@ void K_drawKartHUD(void)
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)
{
if (LUA_HudEnabled(hud_time))
else if (viewnum == r_splitscreen)
{
K_drawKart4PTimestamp();
if (LUA_HudEnabled(hud_time))
{
K_drawKart4PTimestamp();
}
}
}
@ -5581,6 +5590,19 @@ void K_drawKartHUD(void)
if (LUA_HudEnabled(hud_position))
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();
if (G_IsPartyLocal(displayplayers[viewnum]) == false)
if (K_DirectorIsAvailable(viewnum) == true)
{
K_drawDirectorHUD();
}

View file

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

View file

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

View file

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

View file

@ -599,7 +599,6 @@ static int player_set(lua_State *L)
if (plr == &players[displayplayers[i]])
{
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]])
{
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);
boolean P_TryCameraMove(fixed_t x, fixed_t y, 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);
void P_ToggleDemoCamera(void);
@ -167,7 +167,6 @@ boolean P_IsMachineLocalPlayer(player_t *player);
boolean P_IsDisplayPlayer(player_t *player);
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);
boolean P_PlayerFullbright(player_t *player);

View file

@ -12090,13 +12090,8 @@ void P_SpawnPlayer(INT32 playernum)
if ((gametyperules & GTR_BUMPERS) && !p->spectator)
{
// At leveltime == 2, K_TimerInit will get called and reset
// the bumpers to the initial value for the level.
if (leveltime > 2) // Reset those bumpers!
{
mobj->health = K_BumpersToHealth(K_StartingBumperCount());
K_SpawnPlayerBattleBumpers(p);
}
mobj->health = K_BumpersToHealth(K_StartingBumperCount());
K_SpawnPlayerBattleBumpers(p);
}
// 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].subsector = R_PointInSubsector(camera[i].x, camera[i].y);
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)
P_ResetCamera(thing->player, &camera[i]);
R_ResetViewInterpolation(i + 1);
break;
}
// 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);
break;
}
}

View file

@ -2887,7 +2887,7 @@ fixed_t t_cam_rotate[MAXSPLITSCREENPLAYERS] = {-42,-42,-42,-42};
struct demofreecam_s democam;
void P_DemoCameraMovement(camera_t *cam)
void P_DemoCameraMovement(camera_t *cam, UINT8 num)
{
ticcmd_t *cmd;
angle_t thrustangle;
@ -2897,7 +2897,7 @@ void P_DemoCameraMovement(camera_t *cam)
boolean moving = false;
// first off we need to get button input
cmd = D_LocalTiccmd(0);
cmd = D_LocalTiccmd(num);
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)
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
{
num = 1;
@ -3112,6 +3100,18 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
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;
if (P_MobjIsFrozen(mo) || player->playerstate == PST_DEAD)
@ -3544,19 +3544,10 @@ boolean P_SpectatorJoinGame(player_t *player)
player->enteredGame = true;
// Reset away view (some code referenced from Got_Teamchange)
if (G_IsPartyLocal(player - players))
{
UINT8 i = 0;
const UINT8 *localplayertable = G_PartyArray(consoleplayer);
for (i = 0; i <= r_splitscreen; i++)
{
if (localplayertable[i] == (player-players))
{
LUA_HookViewpointSwitch(player, player, true);
displayplayers[i] = (player-players);
break;
}
}
LUA_HookViewpointSwitch(player, player, true);
displayplayers[G_PartyPosition(player - players)] = (player-players);
}
// 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
static void P_CalcPostImg(player_t *player)
static void P_CalcPostImg(player_t *player, size_t viewnum)
{
sector_t *sector = player->mo->subsector->sector;
postimg_t *type = NULL;
INT32 *param;
postimg_t *type = &postimgtype[viewnum];
INT32 *param = &postimgparam[viewnum];
fixed_t pviewheight;
size_t i;
@ -3591,16 +3582,6 @@ static void P_CalcPostImg(player_t *player)
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...)
for (i = 0; i < sector->tags.count; i++)
{
@ -4400,7 +4381,6 @@ void P_PlayerThink(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;
#ifdef PARANOIA
@ -4425,15 +4405,6 @@ void P_PlayerAfterThink(player_t *player)
P_PlayerInSpecialSector(player);
#endif
for (i = 0; i <= r_splitscreen; i++)
{
if (player == &players[displayplayers[i]])
{
thiscam = &camera[i];
break;
}
}
if (player->playerstate == PST_DEAD)
{
// Followers need handled while dead.
@ -4448,12 +4419,20 @@ void P_PlayerAfterThink(player_t *player)
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_CalcPostImg(player);
}
else
{
@ -4466,6 +4445,14 @@ void P_PlayerAfterThink(player_t *player)
else
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.
@ -4530,10 +4517,15 @@ void P_PlayerAfterThink(player_t *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
thiscam->pmomz = player->mo->pmomz;
camera[i].pmomz = player->mo->pmomz;
}
if (P_IsObjectOnGround(player->mo))
@ -4632,21 +4624,6 @@ void P_SetPlayerAngle(player_t *player, angle_t 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)
{
UINT8 i;
@ -4658,8 +4635,6 @@ void P_ForceLocalAngle(player_t *player, angle_t angle)
if (player == &players[displayplayers[i]])
{
localangle[i] = angle;
break;
}
}

View file

@ -20,6 +20,7 @@
#include "r_local.h"
#include "r_state.h"
#include "r_portal.h" // Add seg portals
#include "r_fps.h"
#include "r_splats.h"
#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;
INT32 heightsec;
boolean underwater;
UINT8 i;
UINT8 i = R_GetViewNumber();
for (i = 0; i <= r_splitscreen; i++)
{
if (viewplayer == &players[displayplayers[i]] && camera[i].chase)
{
heightsec = R_PointInSubsector(camera[i].x, camera[i].y)->sector->heightsec;
break;
}
}
if (i > r_splitscreen && viewmobj)
if (camera[i].chase)
heightsec = R_PointInSubsector(camera[i].x, camera[i].y)->sector->heightsec;
else if (i > r_splitscreen && viewmobj)
heightsec = R_PointInSubsector(viewmobj->x, viewmobj->y)->sector->heightsec;
else
return sec;

View file

@ -22,6 +22,7 @@
#include "r_state.h"
#include "z_zone.h"
#include "console.h" // con_startup_loadprogress
#include "i_time.h"
UINT32 R_GetFramerateCap(void)
{
@ -58,6 +59,7 @@ static viewvars_t skyview_old[MAXSPLITSCREENPLAYERS];
static viewvars_t skyview_new[MAXSPLITSCREENPLAYERS];
static viewvars_t *oldview = &pview_old[0];
static tic_t last_view_update;
static int oldview_invalid[MAXSPLITSCREENPLAYERS] = {0, 0, 0, 0};
viewvars_t *newview = &pview_new[0];
@ -165,21 +167,27 @@ void R_UpdateViewInterpolation(void)
skyview_old[i] = skyview_new[i];
if (oldview_invalid[i] > 0) oldview_invalid[i]--;
}
last_view_update = I_GetTime();
}
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)
{
UINT8 i;
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
{
oldview_invalid[i]++;
oldview_invalid[i] = t;
}
}
else
{
oldview_invalid[p - 1]++;
oldview_invalid[p - 1] = t;
}
}

View file

@ -20,6 +20,7 @@
#include "g_game.h"
#include "p_setup.h" // levelflats
#include "p_slopes.h"
#include "r_fps.h"
#include "r_data.h"
#include "r_textures.h"
#include "r_local.h"
@ -963,8 +964,6 @@ void R_DrawSinglePlane(visplane_t *pl)
planeripple.active = true;
if (spanfunctype == SPANDRAWFUNC_TRANS)
{
UINT8 i;
spanfunctype = SPANDRAWFUNC_WATER;
// Copy the current scene, ugh
@ -977,43 +976,38 @@ void R_DrawSinglePlane(visplane_t *pl)
bottom = viewheight;
// 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;
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);
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);
}
}
#endif

View file

@ -532,12 +532,9 @@ void SCR_DisplayTicRate(void)
const UINT8 *ticcntcolor = NULL;
UINT32 cap = R_GetFramerateCap();
UINT32 benchmark = (cap == 0) ? I_GetRefreshRate() : cap;
INT32 x = 318;
INT32 x = 317;
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))
ticcntcolor = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_MINT, GTC_CACHE);
else if (fps < (benchmark * 0.5))
@ -571,15 +568,28 @@ void SCR_DisplayTicRate(void)
void SCR_DisplayLocalPing(void)
{
boolean offline;
UINT32 ping = playerpingtable[consoleplayer]; // consoleplayer's ping is everyone's ping in a splitnetgame :P
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
// Splitscreen party has its own ping counter, but show the
// 1P version anyway in some cases:
// - On intermission, vote, etc. gamestates where the player
// 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;
offline = (consoleplayer == serverplayer);
HU_drawPing(307 * FRACUNIT, dispy * FRACUNIT, ping, V_SNAPTORIGHT | V_SNAPTOBOTTOM | V_HUDTRANS, offline, 0);
return;
}
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];
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]);
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)
{
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;
@ -1467,9 +1474,18 @@ static fixed_t ST_CalculateFadeIn(player_t *player)
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;
}

View file

@ -27,6 +27,7 @@
#include "f_finale.h"
#include "r_draw.h"
#include "console.h"
#include "r_fps.h"
#include "i_video.h" // rendermode
#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 basewidth = BASEVIDWIDTH * dupx;
INT32 baseheight = BASEVIDHEIGHT * dupy;
SINT8 player = -1;
UINT8 i;
SINT8 player = R_GetViewNumber();
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 (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 (stplyr == &players[displayplayers[1]] || stplyr == &players[displayplayers[3]])
if (player & 1)
slidefromright = true;
}