mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'replay-stupid-parties' into 'master'
Emulate parties when watching replays Closes #1090 See merge request KartKrew/Kart!1977
This commit is contained in:
commit
b00255e333
7 changed files with 148 additions and 48 deletions
111
src/d_netcmd.c
111
src/d_netcmd.c
|
|
@ -1838,8 +1838,15 @@ static void Command_SetViews_f(void)
|
|||
// 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 (demo.playback)
|
||||
{
|
||||
G_SyncDemoParty(consoleplayer, newsplits-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
r_splitscreen = newsplits-1;
|
||||
R_ExecuteSetViewSize();
|
||||
}
|
||||
|
||||
// If promoting (outside of replays), make sure the
|
||||
// camera is in the correct position.
|
||||
|
|
@ -6226,35 +6233,85 @@ static void Got_Cheat(const UINT8 **cp, INT32 playernum)
|
|||
}
|
||||
}
|
||||
|
||||
static const char *displayplayer_compose_col(int playernum)
|
||||
{
|
||||
return va("\x84(%d) \x83%s\x80", playernum, player_names[playernum]);
|
||||
}
|
||||
|
||||
static int displayplayer_col_len(const char *text)
|
||||
{
|
||||
int n = strlen(text);
|
||||
int k = n;
|
||||
int i;
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
if (!isprint(text[i]))
|
||||
k--;
|
||||
}
|
||||
return k;
|
||||
}
|
||||
|
||||
static void displayplayer_calc_col(int *col, const char *text)
|
||||
{
|
||||
if (text && text[0] != ' ')
|
||||
{
|
||||
int n = displayplayer_col_len(text);
|
||||
if (*col < n)
|
||||
*col = n;
|
||||
}
|
||||
}
|
||||
|
||||
static void displayplayer_print_col(int *col, const char *text)
|
||||
{
|
||||
if (text)
|
||||
{
|
||||
if (*col)
|
||||
{
|
||||
int n = *col - displayplayer_col_len(text);
|
||||
CONS_Printf("%s%*s ", text, n, "");
|
||||
}
|
||||
}
|
||||
else
|
||||
CONS_Printf("\n");
|
||||
}
|
||||
|
||||
static void displayplayer_iter_table(int table[5], void(*col_cb)(int*,const char*))
|
||||
{
|
||||
int i;
|
||||
|
||||
col_cb(&table[0], "");
|
||||
for (i = 0; i < 4; ++i)
|
||||
col_cb(&table[1 + i], va(" %d", i));
|
||||
col_cb(NULL, NULL);
|
||||
|
||||
col_cb(&table[0], "g_local");
|
||||
for (i = 0; i <= splitscreen; ++i)
|
||||
col_cb(&table[1 + i], displayplayer_compose_col(g_localplayers[i]));
|
||||
col_cb(NULL, NULL);
|
||||
|
||||
col_cb(&table[0], "display");
|
||||
for (i = 0; i <= r_splitscreen; ++i)
|
||||
col_cb(&table[1 + i], displayplayer_compose_col(displayplayers[i]));
|
||||
col_cb(NULL, NULL);
|
||||
|
||||
col_cb(&table[0], "local party");
|
||||
for (i = 0; i < G_LocalSplitscreenPartySize(consoleplayer); ++i)
|
||||
col_cb(&table[1 + i], displayplayer_compose_col(G_LocalSplitscreenPartyMember(consoleplayer, i)));
|
||||
col_cb(NULL, NULL);
|
||||
|
||||
col_cb(&table[0], "final party");
|
||||
for (i = 0; i < G_PartySize(consoleplayer); ++i)
|
||||
col_cb(&table[1 + i], displayplayer_compose_col(G_PartyMember(consoleplayer, i)));
|
||||
col_cb(NULL, NULL);
|
||||
}
|
||||
|
||||
/** Prints the number of displayplayers[0].
|
||||
*
|
||||
* \todo Possibly remove this; it was useful for debugging at one point.
|
||||
*/
|
||||
static void Command_Displayplayer_f(void)
|
||||
{
|
||||
int playernum;
|
||||
int i;
|
||||
for (i = 0; i <= splitscreen; ++i)
|
||||
{
|
||||
playernum = g_localplayers[i];
|
||||
CONS_Printf(
|
||||
"local player %d: \x84(%d) \x83%s\x80\n",
|
||||
i,
|
||||
playernum,
|
||||
player_names[playernum]
|
||||
);
|
||||
}
|
||||
CONS_Printf("\x83----------------------------------------\x80\n");
|
||||
for (i = 0; i <= r_splitscreen; ++i)
|
||||
{
|
||||
playernum = displayplayers[i];
|
||||
CONS_Printf(
|
||||
"display player %d: \x84(%d) \x83%s\x80\n",
|
||||
i,
|
||||
playernum,
|
||||
player_names[playernum]
|
||||
);
|
||||
}
|
||||
int table[5] = {0};
|
||||
displayplayer_iter_table(table, displayplayer_calc_col);
|
||||
displayplayer_iter_table(table, displayplayer_print_col);
|
||||
}
|
||||
|
||||
/** Quits a game and returns to the title screen.
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include "lua_hook.h"
|
||||
#include "md5.h" // demo checksums
|
||||
#include "p_saveg.h" // savebuffer_t
|
||||
#include "g_party.h"
|
||||
|
||||
// SRB2Kart
|
||||
#include "d_netfil.h" // nameonly
|
||||
|
|
@ -3227,15 +3228,13 @@ void G_DoPlayDemo(const char *defdemoname)
|
|||
// didn't start recording right away.
|
||||
demo.deferstart = false;
|
||||
|
||||
displayplayers[0] = consoleplayer = 0;
|
||||
consoleplayer = 0;
|
||||
memset(playeringame,0,sizeof(playeringame));
|
||||
memset(displayplayers,0,sizeof(displayplayers));
|
||||
|
||||
// Load players that were in-game when the map started
|
||||
p = READUINT8(demobuf.p);
|
||||
|
||||
for (i = 1; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
displayplayers[i] = INT32_MAX;
|
||||
|
||||
while (p != 0xFF)
|
||||
{
|
||||
UINT8 flags = READUINT8(demobuf.p);
|
||||
|
|
@ -4126,3 +4125,33 @@ boolean G_CheckDemoTitleEntry(void)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
void G_SyncDemoParty(INT32 rem, INT32 newsplitscreen)
|
||||
{
|
||||
int r_splitscreen_copy = r_splitscreen;
|
||||
INT32 displayplayers_copy[MAXSPLITSCREENPLAYERS];
|
||||
memcpy(displayplayers_copy, displayplayers, sizeof displayplayers);
|
||||
|
||||
// If we switch away from someone's view, that player
|
||||
// should be removed from the party.
|
||||
// However, it is valid to have the player on multiple
|
||||
// viewports.
|
||||
|
||||
// Remove this player
|
||||
G_LeaveParty(rem);
|
||||
|
||||
// And reset the rest of the party
|
||||
for (int i = 0; i <= r_splitscreen_copy; ++i)
|
||||
G_LeaveParty(displayplayers_copy[i]);
|
||||
|
||||
// Restore the party, without the removed player, and
|
||||
// with the order matching displayplayers
|
||||
for (int i = 0; i <= newsplitscreen; ++i)
|
||||
G_JoinParty(consoleplayer, displayplayers_copy[i]);
|
||||
|
||||
// memcpy displayplayers back to preserve duplicates
|
||||
// (G_JoinParty will not create duplicates itself)
|
||||
r_splitscreen = newsplitscreen;
|
||||
memcpy(displayplayers, displayplayers_copy, sizeof displayplayers);
|
||||
R_ExecuteSetViewSize();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -243,6 +243,8 @@ typedef enum
|
|||
DEMO_ATTRACT_CREDITS
|
||||
} demoAttractMode_t;
|
||||
|
||||
void G_SyncDemoParty(INT32 rem, INT32 newsplitscreen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
30
src/g_game.c
30
src/g_game.c
|
|
@ -1648,13 +1648,6 @@ void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive)
|
|||
viewnum = playersviewable;
|
||||
r_splitscreen = viewnum-1;
|
||||
|
||||
/* Prepare extra views for G_FindView to pass. */
|
||||
for (viewd = splits+1; viewd < viewnum; ++viewd)
|
||||
{
|
||||
displayplayerp = (&displayplayers[viewd-1]);
|
||||
(*displayplayerp) = INT32_MAX;
|
||||
}
|
||||
|
||||
R_ExecuteSetViewSize();
|
||||
}
|
||||
|
||||
|
|
@ -1679,21 +1672,30 @@ void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive)
|
|||
|
||||
/* Focus our target view first so that we don't take its player. */
|
||||
(*displayplayerp) = playernum;
|
||||
if ((*displayplayerp) != olddisplayplayer)
|
||||
{
|
||||
G_FixCamera(viewnum);
|
||||
}
|
||||
|
||||
/* If a viewpoint changes, reset the camera to clear uninitialized memory. */
|
||||
if (viewnum > splits)
|
||||
{
|
||||
for (viewd = splits+1; viewd < viewnum; ++viewd)
|
||||
for (viewd = splits+1; viewd <= viewnum; ++viewd)
|
||||
{
|
||||
G_FixCamera(viewd);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((*displayplayerp) != olddisplayplayer)
|
||||
{
|
||||
G_FixCamera(viewnum);
|
||||
}
|
||||
}
|
||||
|
||||
if (viewnum == 1 && demo.playback)
|
||||
consoleplayer = displayplayers[0];
|
||||
if (demo.playback)
|
||||
{
|
||||
if (viewnum == 1)
|
||||
consoleplayer = displayplayers[0];
|
||||
|
||||
G_SyncDemoParty(olddisplayplayer, r_splitscreen);
|
||||
}
|
||||
|
||||
// change statusbar also if playing back demo
|
||||
if (demo.quitafterplaying)
|
||||
|
|
|
|||
|
|
@ -323,3 +323,10 @@ UINT8 G_LocalSplitscreenPartyPosition(UINT8 player)
|
|||
|
||||
return party.find(player) - party.begin();
|
||||
}
|
||||
|
||||
UINT8 G_LocalSplitscreenPartyMember(UINT8 player, UINT8 index)
|
||||
{
|
||||
SRB2_ASSERT(index < local_party[player].size());
|
||||
|
||||
return local_party[player][index];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,9 @@ UINT8 G_PartyPosition(UINT8 player);
|
|||
//
|
||||
UINT8 G_LocalSplitscreenPartyPosition(UINT8 player);
|
||||
|
||||
//
|
||||
UINT8 G_LocalSplitscreenPartyMember(UINT8 player, UINT8 index);
|
||||
|
||||
//
|
||||
// Globals
|
||||
//
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include "../../p_local.h" // P_InitCameraCmd
|
||||
#include "../../d_main.h" // D_StartTitle
|
||||
#include "../../k_credits.h"
|
||||
#include "../../g_demo.h"
|
||||
|
||||
static void M_PlaybackTick(void);
|
||||
|
||||
|
|
@ -220,13 +221,12 @@ void M_PlaybackSetViews(INT32 choice)
|
|||
{
|
||||
if (choice == 0)
|
||||
{
|
||||
r_splitscreen--;
|
||||
G_SyncDemoParty(displayplayers[r_splitscreen], r_splitscreen - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
r_splitscreen = 0;
|
||||
G_SyncDemoParty(consoleplayer, 0);
|
||||
}
|
||||
R_ExecuteSetViewSize();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue