mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'replay-kms' into 'master'
demo improvements (why) See merge request kart-krew-dev/ring-racers-internal!2598
This commit is contained in:
commit
03d9430bb9
29 changed files with 883 additions and 767 deletions
|
|
@ -7560,66 +7560,6 @@ tic_t GetLag(INT32 node)
|
|||
return gametic - nettics[node];
|
||||
}
|
||||
|
||||
#define REWIND_POINT_INTERVAL 4*TICRATE + 16
|
||||
rewind_t *rewindhead;
|
||||
|
||||
void CL_ClearRewinds(void)
|
||||
{
|
||||
rewind_t *head;
|
||||
while ((head = rewindhead))
|
||||
{
|
||||
rewindhead = rewindhead->next;
|
||||
free(head);
|
||||
}
|
||||
}
|
||||
|
||||
rewind_t *CL_SaveRewindPoint(size_t demopos)
|
||||
{
|
||||
savebuffer_t save = {0};
|
||||
rewind_t *rewind;
|
||||
|
||||
if (rewindhead && rewindhead->leveltime + REWIND_POINT_INTERVAL > leveltime)
|
||||
return NULL;
|
||||
|
||||
rewind = (rewind_t *)malloc(sizeof (rewind_t));
|
||||
if (!rewind)
|
||||
return NULL;
|
||||
|
||||
P_SaveBufferFromExisting(&save, rewind->savebuffer, NETSAVEGAMESIZE);
|
||||
P_SaveNetGame(&save, false);
|
||||
|
||||
rewind->leveltime = leveltime;
|
||||
rewind->next = rewindhead;
|
||||
rewind->demopos = demopos;
|
||||
rewindhead = rewind;
|
||||
|
||||
return rewind;
|
||||
}
|
||||
|
||||
rewind_t *CL_RewindToTime(tic_t time)
|
||||
{
|
||||
savebuffer_t save = {0};
|
||||
rewind_t *rewind;
|
||||
|
||||
while (rewindhead && rewindhead->leveltime > time)
|
||||
{
|
||||
rewind = rewindhead->next;
|
||||
free(rewindhead);
|
||||
rewindhead = rewind;
|
||||
}
|
||||
|
||||
if (!rewindhead)
|
||||
return NULL;
|
||||
|
||||
P_SaveBufferFromExisting(&save, rewindhead->savebuffer, NETSAVEGAMESIZE);
|
||||
P_LoadNetGame(&save, false);
|
||||
|
||||
wipegamestate = gamestate; // No fading back in!
|
||||
timeinmap = leveltime;
|
||||
|
||||
return rewindhead;
|
||||
}
|
||||
|
||||
void D_MD5PasswordPass(const UINT8 *buffer, size_t len, const char *salt, void *dest)
|
||||
{
|
||||
#ifdef NOMD5
|
||||
|
|
|
|||
|
|
@ -712,21 +712,6 @@ extern boolean hu_stopped;
|
|||
// SRB2Kart
|
||||
//
|
||||
|
||||
struct rewind_t {
|
||||
UINT8 savebuffer[NETSAVEGAMESIZE];
|
||||
tic_t leveltime;
|
||||
size_t demopos;
|
||||
|
||||
ticcmd_t oldcmd[MAXPLAYERS];
|
||||
mobj_t oldghost[MAXPLAYERS];
|
||||
|
||||
rewind_t *next;
|
||||
};
|
||||
|
||||
void CL_ClearRewinds(void);
|
||||
rewind_t *CL_SaveRewindPoint(size_t demopos);
|
||||
rewind_t *CL_RewindToTime(tic_t time);
|
||||
|
||||
void HandleSigfail(const char *string);
|
||||
|
||||
void DoSayPacket(SINT8 target, UINT8 flags, UINT8 source, char *message);
|
||||
|
|
|
|||
|
|
@ -742,9 +742,6 @@ static bool D_Display(bool world)
|
|||
if (forcerefresh && G_GamestateUsesLevel() == false)
|
||||
V_SetPalette(0);
|
||||
|
||||
if (demo.rewinding)
|
||||
V_DrawFadeScreen(TC_RAINBOW, (leveltime & 0x20) ? SKINCOLOR_PASTEL : SKINCOLOR_MOONSET);
|
||||
|
||||
// vid size change is now finished if it was on...
|
||||
vid.recalc = 0;
|
||||
|
||||
|
|
@ -936,7 +933,7 @@ void D_SRB2Loop(void)
|
|||
realtics = entertic - oldentertics;
|
||||
oldentertics = entertic;
|
||||
|
||||
if (demo.playback && gamestate == GS_LEVEL)
|
||||
if (demo.playback && gamestate == GS_LEVEL && demo.simplerewind == DEMO_REWIND_OFF)
|
||||
{
|
||||
// Nicer place to put this.
|
||||
realtics = realtics * cv_playbackspeed.value;
|
||||
|
|
@ -1216,6 +1213,7 @@ void D_ClearState(void)
|
|||
// Reset GP and roundqueue
|
||||
memset(&grandprixinfo, 0, sizeof(struct grandprixinfo));
|
||||
memset(&roundqueue, 0, sizeof(struct roundqueue));
|
||||
memset(&menuqueue, 0, sizeof(struct menuqueue));
|
||||
|
||||
// empty some other semi-important state
|
||||
maptol = 0;
|
||||
|
|
@ -1248,7 +1246,8 @@ void D_ClearState(void)
|
|||
if (gamedata && gamedata->deferredsave)
|
||||
G_SaveGameData();
|
||||
|
||||
K_UnsetDialogue();
|
||||
P_FreeLevelState();
|
||||
P_InvalidateThinkersWithoutInit();
|
||||
|
||||
G_SetGamestate(GS_NULL);
|
||||
wipegamestate = GS_NULL;
|
||||
|
|
|
|||
|
|
@ -2984,7 +2984,7 @@ static void Command_RestartLevel(void)
|
|||
D_MapChange(gamemap, g_lastgametype, newencore, false, 0, false, false);
|
||||
}
|
||||
|
||||
static void Handle_MapQueueSend(UINT16 newmapnum, UINT16 newgametype, boolean newencoremode)
|
||||
void Handle_MapQueueSend(UINT16 newmapnum, UINT16 newgametype, boolean newencoremode)
|
||||
{
|
||||
UINT8 flags = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -206,6 +206,7 @@ size_t WeaponPref_Parse(const UINT8 *p, INT32 playernum);
|
|||
void D_SendPlayerConfig(UINT8 n);
|
||||
void Command_ExitGame_f(void);
|
||||
void Command_Retry_f(void);
|
||||
void Handle_MapQueueSend(UINT16 newmapnum, UINT16 newgametype, boolean newencoremode);
|
||||
boolean G_GamestateUsesExitLevel(void);
|
||||
void D_GameTypeChanged(INT32 lastgametype); // not a real _OnChange function anymore
|
||||
void D_MapChange(UINT16 pmapnum, INT32 pgametype, boolean pencoremode, boolean presetplayers, INT32 pdelay, boolean pskipprecutscene, boolean pforcespecialstage);
|
||||
|
|
|
|||
|
|
@ -404,7 +404,10 @@ class TiccmdBuilder
|
|||
map(gc_item, BT_ATTACK); // fire
|
||||
|
||||
map(gc_lookback, BT_LOOKBACK); // rear view
|
||||
map(gc_respawn, BT_RESPAWN | (freecam() ? 0 : BT_EBRAKEMASK)); // respawn
|
||||
if (!modeattacking)
|
||||
{
|
||||
map(gc_respawn, BT_RESPAWN | (freecam() ? 0 : BT_EBRAKEMASK)); // respawn
|
||||
}
|
||||
map(gc_vote, BT_VOTE); // mp general function button
|
||||
|
||||
// lua buttons a thru c
|
||||
|
|
|
|||
407
src/g_demo.cpp
407
src/g_demo.cpp
|
|
@ -270,22 +270,31 @@ static ticcmd_t oldcmd[MAXPLAYERS];
|
|||
|
||||
static mobj_t oldghost[MAXPLAYERS];
|
||||
|
||||
boolean G_ConsiderEndingDemoWrite(void)
|
||||
{
|
||||
// chill, we reserved extra memory so it's
|
||||
// "safe" to have written a bit past the end
|
||||
if (demobuf.p < demobuf.end)
|
||||
return false;
|
||||
|
||||
G_CheckDemoStatus();
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean G_ConsiderEndingDemoRead(void)
|
||||
{
|
||||
if (*demobuf.p != DEMOMARKER)
|
||||
return false;
|
||||
|
||||
G_CheckDemoStatus();
|
||||
return true;
|
||||
}
|
||||
|
||||
void G_ReadDemoExtraData(void)
|
||||
{
|
||||
INT32 p, extradata, i;
|
||||
char name[64];
|
||||
static_assert(sizeof name >= std::max({MAXPLAYERNAME+1u, SKINNAMESIZE+1u, MAXCOLORNAME+1u}));
|
||||
|
||||
if (leveltime > starttime)
|
||||
{
|
||||
rewind_t *rewind = CL_SaveRewindPoint(demobuf.p - demobuf.buffer);
|
||||
if (rewind)
|
||||
{
|
||||
memcpy(rewind->oldcmd, oldcmd, sizeof (oldcmd));
|
||||
memcpy(rewind->oldghost, oldghost, sizeof (oldghost));
|
||||
}
|
||||
}
|
||||
|
||||
memset(name, '\0', sizeof name);
|
||||
|
||||
p = READUINT8(demobuf.p);
|
||||
|
|
@ -460,13 +469,6 @@ void G_ReadDemoExtraData(void)
|
|||
|
||||
p = READUINT8(demobuf.p);
|
||||
}
|
||||
|
||||
if (!(demoflags & DF_GHOST) && *demobuf.p == DEMOMARKER)
|
||||
{
|
||||
// end of demo data stream
|
||||
G_CheckDemoStatus();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void G_WriteDemoExtraData(void)
|
||||
|
|
@ -623,13 +625,6 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
|
|||
}
|
||||
|
||||
G_CopyTiccmd(cmd, &oldcmd[playernum], 1);
|
||||
|
||||
if (!(demoflags & DF_GHOST) && *demobuf.p == DEMOMARKER)
|
||||
{
|
||||
// end of demo data stream
|
||||
G_CheckDemoStatus();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
|
||||
|
|
@ -739,14 +734,6 @@ void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
|
|||
|
||||
WRITEUINT16(botziptic_p, botziptic);
|
||||
}
|
||||
|
||||
// attention here for the ticcmd size!
|
||||
// latest demos with mouse aiming byte in ticcmd
|
||||
if (!(demoflags & DF_GHOST) && ziptic_p > demobuf.end - 9)
|
||||
{
|
||||
G_CheckDemoStatus(); // no more space
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void G_GhostAddFlip(INT32 playernum)
|
||||
|
|
@ -794,8 +781,11 @@ void G_GhostAddHit(INT32 playernum, mobj_t *victim)
|
|||
|
||||
void G_WriteAllGhostTics(void)
|
||||
{
|
||||
boolean toobig = false;
|
||||
INT32 i, counter = leveltime;
|
||||
|
||||
if (!demobuf.p || !(demoflags & DF_GHOST))
|
||||
return; // No ghost data to write.
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
|
|
@ -811,22 +801,9 @@ void G_WriteAllGhostTics(void)
|
|||
|
||||
WRITEUINT8(demobuf.p, i);
|
||||
G_WriteGhostTic(players[i].mo, i);
|
||||
|
||||
// attention here for the ticcmd size!
|
||||
// latest demos with mouse aiming byte in ticcmd
|
||||
if (demobuf.p >= demobuf.end - (13 + 9 + 9))
|
||||
{
|
||||
toobig = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WRITEUINT8(demobuf.p, 0xFF);
|
||||
|
||||
if (toobig)
|
||||
{
|
||||
G_CheckDemoStatus(); // no more space
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
|
||||
|
|
@ -835,11 +812,6 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum)
|
|||
UINT8 *ziptic_p;
|
||||
UINT32 i;
|
||||
|
||||
if (!demobuf.p)
|
||||
return;
|
||||
if (!(demoflags & DF_GHOST))
|
||||
return; // No ghost data to write.
|
||||
|
||||
ziptic_p = demobuf.p++; // the ziptic, written at the end of this function
|
||||
|
||||
#define MAXMOM (0xFFFF<<8)
|
||||
|
|
@ -1061,7 +1033,7 @@ void G_ConsAllGhostTics(void)
|
|||
{
|
||||
UINT8 p;
|
||||
|
||||
if (!demobuf.p || !demo.deferstart)
|
||||
if (!demobuf.p || !(demoflags & DF_GHOST) || !demo.deferstart)
|
||||
return;
|
||||
|
||||
p = READUINT8(demobuf.p);
|
||||
|
|
@ -1071,13 +1043,6 @@ void G_ConsAllGhostTics(void)
|
|||
G_ConsGhostTic(p);
|
||||
p = READUINT8(demobuf.p);
|
||||
}
|
||||
|
||||
if (*demobuf.p == DEMOMARKER)
|
||||
{
|
||||
// end of demo data stream
|
||||
G_CheckDemoStatus();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Uses ghost data to do consistency checks on your position.
|
||||
|
|
@ -1089,9 +1054,6 @@ void G_ConsGhostTic(INT32 playernum)
|
|||
mobj_t *testmo;
|
||||
UINT32 syncleeway;
|
||||
|
||||
if (!(demoflags & DF_GHOST))
|
||||
return; // No ghost data to use.
|
||||
|
||||
testmo = players[playernum].mo;
|
||||
|
||||
// Grab ghost data.
|
||||
|
|
@ -1282,13 +1244,6 @@ void G_ConsGhostTic(INT32 playernum)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*demobuf.p == DEMOMARKER)
|
||||
{
|
||||
// end of demo data stream
|
||||
G_CheckDemoStatus();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void G_GhostTicker(void)
|
||||
|
|
@ -1309,11 +1264,31 @@ void G_GhostTicker(void)
|
|||
continue;
|
||||
|
||||
readghosttic:
|
||||
#define follow g->mo->tracer
|
||||
|
||||
// Skip normal demo data.
|
||||
ziptic = READUINT8(g->p);
|
||||
xziptic = 0;
|
||||
|
||||
// Demo ends after ghost data.
|
||||
if (ziptic == DEMOMARKER)
|
||||
{
|
||||
fadeghost:
|
||||
g->mo->momx = g->mo->momy = g->mo->momz = 0;
|
||||
g->mo->fuse = TICRATE;
|
||||
if (follow)
|
||||
{
|
||||
follow->fuse = TICRATE;
|
||||
}
|
||||
|
||||
g->done = true;
|
||||
if (p)
|
||||
{
|
||||
p->next = g->next;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
while (ziptic != DW_END) // Get rid of extradata stuff
|
||||
{
|
||||
if (ziptic < MAXPLAYERS)
|
||||
|
|
@ -1414,9 +1389,11 @@ readghosttic:
|
|||
// Grab ghost data.
|
||||
ziptic = READUINT8(g->p);
|
||||
|
||||
if (ziptic == DEMOMARKER) // Had to end early for some reason
|
||||
goto fadeghost;
|
||||
if (ziptic == 0xFF)
|
||||
goto skippedghosttic; // Didn't write ghost info this frame
|
||||
else if (ziptic != 0)
|
||||
if (ziptic != 0)
|
||||
I_Error("Ghost is not a record attack ghost ZIPTIC"); //@TODO lmao don't blow up like this
|
||||
ziptic = READUINT8(g->p);
|
||||
|
||||
|
|
@ -1530,7 +1507,6 @@ readghosttic:
|
|||
g->mo->renderflags &= ~RF_DONTDRAW;
|
||||
}
|
||||
|
||||
#define follow g->mo->tracer
|
||||
if (ziptic & GZT_FOLLOW)
|
||||
{ // Even more...
|
||||
UINT8 followtic = READUINT8(g->p);
|
||||
|
|
@ -1620,28 +1596,6 @@ skippedghosttic:
|
|||
if (READUINT8(g->p) != 0xFF) // Make sure there isn't other ghost data here.
|
||||
I_Error("Ghost is not a record attack ghost GHOSTEND"); //@TODO lmao don't blow up like this
|
||||
|
||||
// Demo ends after ghost data.
|
||||
if (*g->p == DEMOMARKER)
|
||||
{
|
||||
g->mo->momx = g->mo->momy = g->mo->momz = 0;
|
||||
#if 0 // freeze frame (maybe more useful for time attackers) (2024-03-11: you leave it behind anyway!)
|
||||
g->mo->colorized = true;
|
||||
g->mo->fuse = 10*TICRATE;
|
||||
if (follow)
|
||||
follow->colorized = true;
|
||||
#else // dissapearing act
|
||||
g->mo->fuse = TICRATE;
|
||||
if (follow)
|
||||
follow->fuse = TICRATE;
|
||||
#endif
|
||||
g->done = true;
|
||||
if (p)
|
||||
{
|
||||
p->next = g->next;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the timer started, skip ahead until the ghost starts too.
|
||||
if (starttime <= leveltime && !g->linecrossed && G_TimeAttackStart())
|
||||
goto readghosttic;
|
||||
|
|
@ -1651,203 +1605,6 @@ skippedghosttic:
|
|||
}
|
||||
}
|
||||
|
||||
// Demo rewinding functions
|
||||
typedef struct rewindinfo_s {
|
||||
tic_t leveltime;
|
||||
|
||||
struct {
|
||||
boolean ingame;
|
||||
player_t player;
|
||||
mobj_t mobj;
|
||||
} playerinfo[MAXPLAYERS];
|
||||
|
||||
struct rewindinfo_s *prev;
|
||||
} rewindinfo_t;
|
||||
|
||||
static tic_t currentrewindnum;
|
||||
static rewindinfo_t *rewindhead = NULL; // Reverse chronological order
|
||||
|
||||
void G_InitDemoRewind(void)
|
||||
{
|
||||
CL_ClearRewinds();
|
||||
|
||||
while (rewindhead)
|
||||
{
|
||||
rewindinfo_t *p = rewindhead->prev;
|
||||
Z_Free(rewindhead);
|
||||
rewindhead = p;
|
||||
}
|
||||
|
||||
currentrewindnum = 0;
|
||||
}
|
||||
|
||||
void G_StoreRewindInfo(void)
|
||||
{
|
||||
static UINT8 timetolog = 8;
|
||||
rewindinfo_t *info;
|
||||
size_t i;
|
||||
|
||||
if (timetolog-- > 0)
|
||||
return;
|
||||
timetolog = 8;
|
||||
|
||||
info = static_cast<rewindinfo_t*>(Z_Calloc(sizeof(rewindinfo_t), PU_STATIC, NULL));
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
{
|
||||
info->playerinfo[i].ingame = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
info->playerinfo[i].ingame = true;
|
||||
memcpy(&info->playerinfo[i].player, &players[i], sizeof(player_t));
|
||||
if (players[i].mo)
|
||||
memcpy(&info->playerinfo[i].mobj, players[i].mo, sizeof(mobj_t));
|
||||
}
|
||||
|
||||
info->leveltime = leveltime;
|
||||
info->prev = rewindhead;
|
||||
rewindhead = info;
|
||||
}
|
||||
|
||||
void G_PreviewRewind(tic_t previewtime)
|
||||
{
|
||||
SINT8 i;
|
||||
//size_t j;
|
||||
fixed_t tweenvalue = 0;
|
||||
rewindinfo_t *info = rewindhead, *next_info = rewindhead;
|
||||
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
while (info->leveltime > previewtime && info->prev)
|
||||
{
|
||||
next_info = info;
|
||||
info = info->prev;
|
||||
}
|
||||
if (info != next_info)
|
||||
tweenvalue = FixedDiv(previewtime - info->leveltime, next_info->leveltime - info->leveltime);
|
||||
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
{
|
||||
if (info->playerinfo[i].player.mo)
|
||||
{
|
||||
//@TODO spawn temp object to act as a player display
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!info->playerinfo[i].ingame || !info->playerinfo[i].player.mo)
|
||||
{
|
||||
if (players[i].mo)
|
||||
players[i].mo->renderflags |= RF_DONTDRAW;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!players[i].mo)
|
||||
continue; //@TODO spawn temp object to act as a player display
|
||||
|
||||
players[i].mo->renderflags &= ~RF_DONTDRAW;
|
||||
|
||||
P_UnsetThingPosition(players[i].mo);
|
||||
#define TWEEN(pr) info->playerinfo[i].mobj.pr + FixedMul((INT32) (next_info->playerinfo[i].mobj.pr - info->playerinfo[i].mobj.pr), tweenvalue)
|
||||
players[i].mo->x = TWEEN(x);
|
||||
players[i].mo->y = TWEEN(y);
|
||||
players[i].mo->z = TWEEN(z);
|
||||
players[i].mo->angle = TWEEN(angle);
|
||||
#undef TWEEN
|
||||
P_SetThingPosition(players[i].mo);
|
||||
|
||||
players[i].drawangle = info->playerinfo[i].player.drawangle + FixedMul((INT32) (next_info->playerinfo[i].player.drawangle - info->playerinfo[i].player.drawangle), tweenvalue);
|
||||
|
||||
players[i].mo->sprite = info->playerinfo[i].mobj.sprite;
|
||||
players[i].mo->sprite2 = info->playerinfo[i].mobj.sprite2;
|
||||
players[i].mo->frame = info->playerinfo[i].mobj.frame;
|
||||
|
||||
players[i].mo->hitlag = info->playerinfo[i].mobj.hitlag;
|
||||
|
||||
players[i].realtime = info->playerinfo[i].player.realtime;
|
||||
// Genuinely CANNOT be fucked. I can redo lua and I can redo netsaves but I draw the line at this abysmal hack.
|
||||
/*for (j = 0; j < NUMKARTSTUFF; j++)
|
||||
players[i].kartstuff[j] = info->playerinfo[i].player.kartstuff[j];*/
|
||||
}
|
||||
|
||||
for (i = splitscreen; i >= 0; i--)
|
||||
P_ResetCamera(&players[displayplayers[i]], &camera[i]);
|
||||
}
|
||||
|
||||
void G_ConfirmRewind(tic_t rewindtime)
|
||||
{
|
||||
SINT8 i;
|
||||
tic_t j;
|
||||
boolean oldmenuactive = menuactive, oldsounddisabled = sound_disabled;
|
||||
|
||||
INT32 olddp1 = displayplayers[0], olddp2 = displayplayers[1], olddp3 = displayplayers[2], olddp4 = displayplayers[3];
|
||||
UINT8 oldss = splitscreen;
|
||||
|
||||
menuactive = false; // Prevent loops
|
||||
|
||||
CV_StealthSetValue(&cv_renderview, 0);
|
||||
|
||||
if (rewindtime <= starttime)
|
||||
{
|
||||
demo.rewinding = true; // this doesn't APPEAR to cause any misery, and it allows us to prevent running all the wipes again
|
||||
G_DoPlayDemo(NULL); // Restart the current demo
|
||||
}
|
||||
else
|
||||
{
|
||||
rewind_t *rewind;
|
||||
sound_disabled = true; // Prevent sound spam
|
||||
demo.rewinding = true;
|
||||
|
||||
rewind = CL_RewindToTime(rewindtime);
|
||||
|
||||
if (rewind)
|
||||
{
|
||||
demobuf.p = demobuf.buffer + rewind->demopos;
|
||||
memcpy(oldcmd, rewind->oldcmd, sizeof (oldcmd));
|
||||
memcpy(oldghost, rewind->oldghost, sizeof (oldghost));
|
||||
paused = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
demo.rewinding = true;
|
||||
G_DoPlayDemo(NULL); // Restart the current demo
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < rewindtime && leveltime < rewindtime; j++)
|
||||
{
|
||||
G_Ticker((j % NEWTICRATERATIO) == 0);
|
||||
}
|
||||
|
||||
demo.rewinding = false;
|
||||
menuactive = oldmenuactive; // Bring the menu back up
|
||||
sound_disabled = oldsounddisabled; // Re-enable SFX
|
||||
|
||||
wipegamestate = gamestate; // No fading back in!
|
||||
|
||||
COM_BufInsertText("renderview on\n");
|
||||
|
||||
splitscreen = oldss;
|
||||
displayplayers[0] = olddp1;
|
||||
displayplayers[1] = olddp2;
|
||||
displayplayers[2] = olddp3;
|
||||
displayplayers[3] = olddp4;
|
||||
R_ExecuteSetViewSize();
|
||||
G_ResetViews();
|
||||
|
||||
for (i = splitscreen; i >= 0; i--)
|
||||
P_ResetCamera(&players[displayplayers[i]], &camera[i]);
|
||||
}
|
||||
|
||||
//
|
||||
// G_RecordDemo
|
||||
//
|
||||
|
|
@ -1885,7 +1642,7 @@ void G_RecordDemo(const char *name)
|
|||
functions will check if they overran the buffer, but it
|
||||
should be safe enough because they'll think there's less
|
||||
memory than there actually is and stop early. */
|
||||
const size_t deadspace = 1024;
|
||||
const size_t deadspace = 2048;
|
||||
I_Assert(demobuf.size > deadspace);
|
||||
demobuf.size -= deadspace;
|
||||
demobuf.end -= deadspace;
|
||||
|
|
@ -2999,8 +2756,6 @@ void G_DoPlayDemoEx(const char *defdemoname, lumpnum_t deflumpnum)
|
|||
boolean skiperrors = true;
|
||||
#endif
|
||||
|
||||
G_InitDemoRewind();
|
||||
|
||||
gtname[MAXGAMETYPELENGTH-1] = '\0';
|
||||
|
||||
if (deflumpnum != LUMPERROR)
|
||||
|
|
@ -3363,22 +3118,6 @@ void G_DoPlayDemoEx(const char *defdemoname, lumpnum_t deflumpnum)
|
|||
// Load "mapmusrng" used for altmusic selection
|
||||
mapmusrng = READUINT8(demobuf.p);
|
||||
|
||||
// Sigh ... it's an empty demo.
|
||||
if (*demobuf.p == DEMOMARKER)
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("%s contains no data to be played.\n"), pdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage("Demo Playback", msg, NULL, MM_NOTHING, NULL, "Return to Menu");
|
||||
Z_Free(demo.skinlist);
|
||||
demo.skinlist = NULL;
|
||||
Z_Free(pdemoname);
|
||||
Z_Free(demobuf.buffer);
|
||||
demo.playback = false;
|
||||
return;
|
||||
}
|
||||
|
||||
Z_Free(pdemoname);
|
||||
|
||||
memset(&oldcmd,0,sizeof(oldcmd));
|
||||
memset(&oldghost,0,sizeof(oldghost));
|
||||
memset(&ghostext,0,sizeof(ghostext));
|
||||
|
|
@ -3607,9 +3346,26 @@ void G_DoPlayDemoEx(const char *defdemoname, lumpnum_t deflumpnum)
|
|||
players[p].lastfakeskin = lastfakeskin[p];
|
||||
}
|
||||
|
||||
// Sigh ... it's an empty demo.
|
||||
if (*demobuf.p == DEMOMARKER)
|
||||
{
|
||||
snprintf(msg, 1024, M_GetText("%s contains no data to be played.\n"), pdemoname);
|
||||
CONS_Alert(CONS_ERROR, "%s", msg);
|
||||
M_StartMessage("Demo Playback", msg, NULL, MM_NOTHING, NULL, "Return to Menu");
|
||||
Z_Free(demo.skinlist);
|
||||
demo.skinlist = NULL;
|
||||
Z_Free(pdemoname);
|
||||
Z_Free(demobuf.buffer);
|
||||
demo.playback = false;
|
||||
return;
|
||||
}
|
||||
|
||||
Z_Free(pdemoname);
|
||||
|
||||
demo.deferstart = true;
|
||||
|
||||
CV_StealthSetValue(&cv_playbackspeed, 1);
|
||||
if (demo.simplerewind == DEMO_REWIND_OFF)
|
||||
CV_StealthSetValue(&cv_playbackspeed, 1);
|
||||
}
|
||||
|
||||
void G_AddGhost(savebuffer_t *buffer, const char *defdemoname)
|
||||
|
|
@ -3756,14 +3512,6 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname)
|
|||
|
||||
p++; // mapmusrng
|
||||
|
||||
if (*p == DEMOMARKER)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Replay is empty.\n"), defdemoname);
|
||||
Z_Free(skinlist);
|
||||
P_SaveBufferFree(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
p++; // player number - doesn't really need to be checked, TODO maybe support adding multiple players' ghosts at once
|
||||
|
||||
// any invalidating flags?
|
||||
|
|
@ -3811,6 +3559,14 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname)
|
|||
return;
|
||||
}
|
||||
|
||||
if (*p == DEMOMARKER)
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Replay is empty.\n"), defdemoname);
|
||||
Z_Free(skinlist);
|
||||
P_SaveBufferFree(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
gh = static_cast<demoghost*>(Z_Calloc(sizeof(demoghost), PU_LEVEL, NULL));
|
||||
gh->sizes = ghostsizes;
|
||||
|
|
@ -4173,7 +3929,7 @@ boolean G_CheckDemoStatus(void)
|
|||
// Keep the demo open and don't boot to intermission
|
||||
// YET, pause demo playback.
|
||||
if (!demo.waitingfortally && modeattacking && exitcountdown)
|
||||
demo.waitingfortally = true;
|
||||
;
|
||||
else if (!demo.attract)
|
||||
G_FinishExitLevel();
|
||||
else
|
||||
|
|
@ -4191,6 +3947,8 @@ boolean G_CheckDemoStatus(void)
|
|||
D_SetDeferredStartTitle(true);
|
||||
}
|
||||
|
||||
demo.waitingfortally = true; // if we've returned early for some reason...
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -4235,6 +3993,13 @@ void G_SaveDemo(void)
|
|||
if (currentMenu == &TitleEntryDef)
|
||||
M_ClearMenus(true);
|
||||
|
||||
if (!leveltime)
|
||||
{
|
||||
// Why would you save if nothing has been recorded
|
||||
G_ResetDemoRecording();
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure extrainfo pointer is always available, even if no info is present.
|
||||
if (demoinfo_p && *(UINT32 *)demoinfo_p == 0)
|
||||
{
|
||||
|
|
|
|||
16
src/g_demo.h
16
src/g_demo.h
|
|
@ -84,7 +84,7 @@ struct demovars_s {
|
|||
boolean recording, playback, timing;
|
||||
UINT16 version; // Current file format of the demo being played
|
||||
UINT8 attract; // Attract demo can be cancelled by any key
|
||||
boolean rewinding; // Rewind in progress
|
||||
UINT8 simplerewind;
|
||||
|
||||
boolean loadfiles, ignorefiles; // Demo file loading options
|
||||
boolean quitafterplaying; // quit after playing a demo from cmdline
|
||||
|
|
@ -172,6 +172,8 @@ extern UINT8 demo_writerng;
|
|||
boolean G_CompatLevel(UINT16 level);
|
||||
|
||||
// Record/playback tics
|
||||
boolean G_ConsiderEndingDemoRead(void);
|
||||
boolean G_ConsiderEndingDemoWrite(void);
|
||||
void G_ReadDemoExtraData(void);
|
||||
void G_WriteDemoExtraData(void);
|
||||
void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
|
||||
|
|
@ -186,11 +188,6 @@ void G_ConsAllGhostTics(void);
|
|||
void G_ConsGhostTic(INT32 playernum);
|
||||
void G_GhostTicker(void);
|
||||
|
||||
void G_InitDemoRewind(void);
|
||||
void G_StoreRewindInfo(void);
|
||||
void G_PreviewRewind(tic_t previewtime);
|
||||
void G_ConfirmRewind(tic_t rewindtime);
|
||||
|
||||
struct DemoBufferSizes
|
||||
{
|
||||
size_t player_name;
|
||||
|
|
@ -250,6 +247,13 @@ typedef enum
|
|||
DEMO_ATTRACT_CREDITS
|
||||
} demoAttractMode_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DEMO_REWIND_OFF = 0,
|
||||
DEMO_REWIND_RESUME,
|
||||
DEMO_REWIND_PAUSE
|
||||
} demoRewindMode_t;
|
||||
|
||||
void G_SyncDemoParty(INT32 rem, INT32 newsplitscreen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
|||
57
src/g_game.c
57
src/g_game.c
|
|
@ -1245,26 +1245,36 @@ void G_StartTitleCard(void)
|
|||
// prepare status bar
|
||||
ST_startTitleCard(); // <-- always must be called to init some variables
|
||||
|
||||
// The title card has been disabled for this map.
|
||||
// Oh well.
|
||||
if (demo.rewinding || !G_IsTitleCardAvailable())
|
||||
{
|
||||
WipeStageTitle = false;
|
||||
if (demo.simplerewind)
|
||||
return;
|
||||
|
||||
sfxenum_t kstart = 0;
|
||||
|
||||
if (K_CheckBossIntro() == true)
|
||||
{
|
||||
kstart = sfx_ssa021;
|
||||
}
|
||||
else if (encoremode)
|
||||
{
|
||||
kstart = sfx_ruby2;
|
||||
}
|
||||
|
||||
if (kstart)
|
||||
{
|
||||
// Play the guaranteed alt sounds
|
||||
S_StartSound(NULL, kstart);
|
||||
}
|
||||
|
||||
if (!G_IsTitleCardAvailable())
|
||||
return;
|
||||
|
||||
// start the title card
|
||||
WipeStageTitle = (gamestate == GS_LEVEL);
|
||||
|
||||
// play the sound
|
||||
if (WipeStageTitle)
|
||||
if (WipeStageTitle && !kstart)
|
||||
{
|
||||
sfxenum_t kstart = sfx_kstart;
|
||||
if (K_CheckBossIntro() == true)
|
||||
kstart = sfx_ssa021;
|
||||
else if (encoremode == true)
|
||||
kstart = sfx_ruby2;
|
||||
S_StartSound(NULL, kstart);
|
||||
// Play the standard titlecard sound
|
||||
S_StartSound(NULL, sfx_kstart);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1439,13 +1449,7 @@ boolean G_Responder(event_t *ev)
|
|||
{
|
||||
paused = !paused;
|
||||
|
||||
if (demo.rewinding)
|
||||
{
|
||||
G_ConfirmRewind(leveltime);
|
||||
paused = true;
|
||||
S_PauseAudio();
|
||||
}
|
||||
else if (paused)
|
||||
if (paused)
|
||||
S_PauseAudio();
|
||||
else
|
||||
S_ResumeAudio();
|
||||
|
|
@ -2150,6 +2154,14 @@ void G_Ticker(boolean run)
|
|||
|
||||
if (g_fast_forward == 0)
|
||||
{
|
||||
// Not "rewinding" anymore.
|
||||
if (demo.simplerewind == DEMO_REWIND_PAUSE)
|
||||
{
|
||||
paused = true;
|
||||
S_PauseAudio();
|
||||
}
|
||||
demo.simplerewind = DEMO_REWIND_OFF;
|
||||
|
||||
// Next fast-forward is unlimited.
|
||||
g_fast_forward_clock_stop = INFTICS;
|
||||
}
|
||||
|
|
@ -4094,6 +4106,7 @@ doremove:
|
|||
|
||||
// Next map apparatus
|
||||
struct roundqueue roundqueue;
|
||||
struct menuqueue menuqueue;
|
||||
|
||||
void G_MapSlipIntoRoundQueue(UINT8 position, UINT16 map, UINT8 setgametype, boolean setencore, boolean rankrestricted)
|
||||
{
|
||||
|
|
@ -5377,7 +5390,7 @@ void G_InitNew(UINT8 pencoremode, INT32 map, boolean resetplayer, boolean skippr
|
|||
S_ResumeAudio();
|
||||
}
|
||||
|
||||
prevencoremode = ((!Playing()) ? false : encoremode);
|
||||
prevencoremode = encoremode;
|
||||
encoremode = pencoremode;
|
||||
|
||||
legitimateexit = false; // SRB2Kart
|
||||
|
|
@ -5829,7 +5842,7 @@ boolean G_GetExitGameFlag(void)
|
|||
// Same deal with retrying.
|
||||
void G_SetRetryFlag(void)
|
||||
{
|
||||
if (retrying == false)
|
||||
if (retrying == false && grandprixinfo.gp)
|
||||
{
|
||||
grandprixinfo.rank.continuesUsed++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,6 +75,15 @@ extern struct roundqueue
|
|||
roundentry_t entries[ROUNDQUEUE_MAX]; // Entries in the round queue
|
||||
} roundqueue;
|
||||
|
||||
extern struct menuqueue
|
||||
{
|
||||
// Degenerate version of roundqueue exclusively for menu use.
|
||||
UINT8 size;
|
||||
UINT8 sending;
|
||||
UINT8 anchor;
|
||||
roundentry_t entries[ROUNDQUEUE_MAX];
|
||||
} menuqueue;
|
||||
|
||||
void G_MapSlipIntoRoundQueue(UINT8 position, UINT16 map, UINT8 setgametype, boolean setencore, boolean rankrestricted);
|
||||
void G_MapIntoRoundQueue(UINT16 map, UINT8 setgametype, boolean setencore, boolean rankrestricted);
|
||||
void G_GPCupIntoRoundQueue(cupheader_t *cup, UINT8 setgametype, boolean setencore);
|
||||
|
|
|
|||
|
|
@ -1536,6 +1536,46 @@ void K_DrawLikeMapThumbnail(fixed_t x, fixed_t y, fixed_t width, UINT32 flags, p
|
|||
);
|
||||
}
|
||||
|
||||
void K_DrawMapAsFace(INT32 x, INT32 y, UINT32 flags, UINT16 map, const UINT8 *colormap)
|
||||
{
|
||||
const fixed_t iconHeight = (14 << FRACBITS);
|
||||
const fixed_t iconWidth = (iconHeight * 320) / 200;
|
||||
INT32 unit = 1;
|
||||
fixed_t mul = FRACUNIT;
|
||||
if (flags & V_NOSCALESTART)
|
||||
{
|
||||
unit = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
|
||||
mul = 1;
|
||||
}
|
||||
|
||||
V_DrawFill(
|
||||
x,
|
||||
y,
|
||||
16 * unit,
|
||||
16 * unit,
|
||||
(flags & ~V_FLIP)
|
||||
);
|
||||
|
||||
V_SetClipRect(
|
||||
(x + unit) * mul,
|
||||
(y + unit) * mul,
|
||||
(14 * unit) * mul,
|
||||
(14 * unit) * mul,
|
||||
(flags & ~V_FLIP)
|
||||
);
|
||||
|
||||
K_DrawMapThumbnail(
|
||||
((x + unit) * FRACUNIT) - (iconWidth - iconHeight)/2,
|
||||
((y + unit) * FRACUNIT),
|
||||
iconWidth,
|
||||
flags,
|
||||
map,
|
||||
colormap
|
||||
);
|
||||
|
||||
V_ClearClipRect();
|
||||
}
|
||||
|
||||
// see also K_DrawNameTagItemSpy
|
||||
static void K_drawKartItem(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ void K_drawKart4PTimestamp(void);
|
|||
void K_drawEmeraldWin(boolean overlay);
|
||||
void K_DrawMapThumbnail(fixed_t x, fixed_t y, fixed_t width, UINT32 flags, UINT16 map, const UINT8 *colormap);
|
||||
void K_DrawLikeMapThumbnail(fixed_t x, fixed_t y, fixed_t width, UINT32 flags, patch_t *patch, const UINT8 *colormap);
|
||||
void K_DrawMapAsFace(INT32 x, INT32 y, UINT32 flags, UINT16 map, const UINT8 *colormap);
|
||||
void K_drawTargetHUD(const vector3_t *origin, player_t *player);
|
||||
void K_drawButton(fixed_t x, fixed_t y, INT32 flags, patch_t *button[2], boolean pressed);
|
||||
void K_drawButtonAnim(INT32 x, INT32 y, INT32 flags, patch_t *button[2], tic_t animtic);
|
||||
|
|
|
|||
|
|
@ -593,10 +593,10 @@ extern menu_t PAUSE_PlaybackMenuDef;
|
|||
typedef enum
|
||||
{
|
||||
playback_hide,
|
||||
playback_restart,
|
||||
playback_rewind,
|
||||
playback_pause,
|
||||
playback_fastforward,
|
||||
playback_backframe,
|
||||
playback_resume,
|
||||
playback_advanceframe,
|
||||
playback_viewcount,
|
||||
|
|
@ -923,6 +923,7 @@ typedef struct levellist_s {
|
|||
UINT8 guessgt;
|
||||
levelsearch_t levelsearch;
|
||||
boolean netgame; // Start the game in an actual server
|
||||
boolean canqueue;
|
||||
menu_t *backMenu;
|
||||
} levellist_t;
|
||||
|
||||
|
|
@ -944,6 +945,8 @@ void M_CupSelectTick(void);
|
|||
void M_LevelSelectHandler(INT32 choice);
|
||||
void M_LevelSelectTick(void);
|
||||
|
||||
INT16 M_LevelFromScrolledList(INT16 add);
|
||||
void M_MenuToLevelPreamble(UINT8 ssplayers, boolean nowipe);
|
||||
void M_LevelSelected(INT16 add, boolean menuupdate);
|
||||
boolean M_LevelSelectCupSwitch(boolean next, boolean skipones);
|
||||
|
||||
|
|
|
|||
|
|
@ -755,33 +755,40 @@ static void M_DrawMenuTyping(void)
|
|||
|
||||
}
|
||||
|
||||
// Largely replaced by boxed drawing mode in K_DrawGameControl and rich text
|
||||
/*
|
||||
static void M_DrawMediocreKeyboardKey(const char *text, INT32 *workx, INT32 worky, boolean push, boolean rightaligned)
|
||||
static void M_DrawPauseRoundQueue(INT16 offset, boolean canqueue)
|
||||
{
|
||||
INT32 buttonwidth = V_StringWidth(text, 0) + 2;
|
||||
y_data_t standings;
|
||||
memset(&standings, 0, sizeof (standings));
|
||||
|
||||
if (rightaligned)
|
||||
if (gamestate == GS_MENU)
|
||||
{
|
||||
(*workx) -= buttonwidth;
|
||||
}
|
||||
|
||||
if (push)
|
||||
{
|
||||
worky += 2;
|
||||
standings.mainplayer = MAXPLAYERS;
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawFill((*workx)-1, worky+10, buttonwidth, 2, 24);
|
||||
standings.mainplayer = (demo.playback ? displayplayers[0] : consoleplayer);
|
||||
}
|
||||
|
||||
V_DrawFill((*workx)-1, worky, buttonwidth, 10, 16);
|
||||
V_DrawString(
|
||||
(*workx), worky + 1,
|
||||
0, text
|
||||
);
|
||||
// See also G_GetNextMap, Y_CalculateMatchData
|
||||
if (
|
||||
canqueue == false
|
||||
&& grandprixinfo.gp == true
|
||||
&& netgame == false // TODO netgame Special Mode support
|
||||
&& grandprixinfo.gamespeed >= KARTSPEED_NORMAL
|
||||
&& roundqueue.size > 1
|
||||
&& roundqueue.entries[roundqueue.size - 1].rankrestricted == true
|
||||
&& (
|
||||
gamedata->everseenspecial == true
|
||||
|| roundqueue.position == roundqueue.size
|
||||
)
|
||||
)
|
||||
{
|
||||
// Additional cases in which it should always be shown.
|
||||
standings.showrank = true;
|
||||
}
|
||||
|
||||
Y_RoundQueueDrawer(&standings, offset, false, false, canqueue);
|
||||
}
|
||||
*/
|
||||
|
||||
// Draw the message popup submenu
|
||||
void M_DrawMenuMessage(void)
|
||||
|
|
@ -991,6 +998,16 @@ void M_Drawer(void)
|
|||
|
||||
// Draw message overlay when needed
|
||||
M_DrawMenuMessage();
|
||||
|
||||
if (
|
||||
(
|
||||
currentMenu == &PLAY_LevelSelectDef
|
||||
|| currentMenu == &PLAY_CupSelectDef
|
||||
) && levellist.canqueue
|
||||
)
|
||||
{
|
||||
M_DrawPauseRoundQueue(0, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (menuwipe)
|
||||
|
|
@ -6288,30 +6305,11 @@ void M_DrawPause(void)
|
|||
V_DrawCenteredLSTitleLowString(220 + offset*2, 103, mainflags, word2);
|
||||
}
|
||||
|
||||
const boolean rulescheck = (K_CanChangeRules(false) && (server || IsPlayerAdmin(consoleplayer)));
|
||||
boolean drawqueue = (rulescheck && (menuqueue.size > 0));
|
||||
|
||||
if (gamestate != GS_INTERMISSION && roundqueue.size > 0)
|
||||
{
|
||||
y_data_t standings;
|
||||
memset(&standings, 0, sizeof (standings));
|
||||
|
||||
standings.mainplayer = (demo.playback ? displayplayers[0] : consoleplayer);
|
||||
|
||||
// See also G_GetNextMap, Y_CalculateMatchData
|
||||
if (
|
||||
grandprixinfo.gp == true
|
||||
&& netgame == false // TODO netgame Special Mode support
|
||||
&& grandprixinfo.gamespeed >= KARTSPEED_NORMAL
|
||||
&& roundqueue.size > 1
|
||||
&& roundqueue.entries[roundqueue.size - 1].rankrestricted == true
|
||||
&& (
|
||||
gamedata->everseenspecial == true
|
||||
|| roundqueue.position == roundqueue.size
|
||||
)
|
||||
)
|
||||
{
|
||||
// Additional cases in which it should always be shown.
|
||||
standings.showrank = true;
|
||||
}
|
||||
|
||||
if (roundqueue.position > 0 && roundqueue.position <= roundqueue.size)
|
||||
{
|
||||
patch_t *smallroundpatch = ST_getRoundPicture(true);
|
||||
|
|
@ -6328,7 +6326,7 @@ void M_DrawPause(void)
|
|||
|
||||
V_DrawCenteredMenuString(24, 167 + offset/2, V_YELLOWMAP, M_GetGameplayMode());
|
||||
|
||||
Y_RoundQueueDrawer(&standings, offset/2, false, false);
|
||||
drawqueue = true;
|
||||
}
|
||||
else if (gametype == GT_TUTORIAL)
|
||||
{
|
||||
|
|
@ -6347,6 +6345,11 @@ void M_DrawPause(void)
|
|||
{
|
||||
V_DrawMenuString(4, 188 + offset/2, V_YELLOWMAP, M_GetGameplayMode());
|
||||
}
|
||||
|
||||
if (drawqueue)
|
||||
{
|
||||
M_DrawPauseRoundQueue(offset/2, rulescheck);
|
||||
}
|
||||
}
|
||||
|
||||
void M_DrawKickHandler(void)
|
||||
|
|
@ -6485,7 +6488,7 @@ void M_DrawPlaybackMenu(void)
|
|||
else if (currentMenu->menuitems[i].patch && W_CheckNumForName(currentMenu->menuitems[i].patch) != LUMPERROR)
|
||||
icon = W_CachePatchName(currentMenu->menuitems[i].patch, PU_CACHE);
|
||||
|
||||
if ((i == playback_fastforward && cv_playbackspeed.value > 1) || (i == playback_rewind && demo.rewinding))
|
||||
if ((i == playback_fastforward && cv_playbackspeed.value > 1))
|
||||
V_DrawMappedPatch(currentMenu->x + currentMenu->menuitems[i].mvar1, currentMenu->y, V_SNAPTOTOP, icon, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_JAWZ, GTC_MENUCACHE));
|
||||
else
|
||||
V_DrawMappedPatch(currentMenu->x + currentMenu->menuitems[i].mvar1, currentMenu->y, V_SNAPTOTOP, icon, (i == itemOn) ? activemap : inactivemap);
|
||||
|
|
|
|||
|
|
@ -466,7 +466,7 @@ boolean M_Responder(event_t *ev)
|
|||
if (Playing() && !demo.playback)
|
||||
{
|
||||
// Quick Retry (Y in modeattacking)
|
||||
if (modeattacking && G_PlayerInputDown(0, gc_y, splitscreen + 1) == true)
|
||||
if (modeattacking && G_PlayerInputDown(0, gc_respawn, splitscreen + 1) == true)
|
||||
{
|
||||
M_TryAgain(0);
|
||||
return true;
|
||||
|
|
|
|||
24
src/k_vote.c
24
src/k_vote.c
|
|
@ -700,35 +700,13 @@ static void Y_DrawVoteThumbnail(fixed_t center_x, fixed_t center_y, fixed_t widt
|
|||
}
|
||||
else if (vote.stage_striking == false) // Angry map
|
||||
{
|
||||
const fixed_t iconHeight = (14 << FRACBITS);
|
||||
const fixed_t iconWidth = (iconHeight * 320) / 200;
|
||||
|
||||
V_DrawFill(
|
||||
K_DrawMapAsFace(
|
||||
fx + fw - whiteSq + dupx,
|
||||
fy + fh - whiteSq + dupy,
|
||||
whiteSq,
|
||||
whiteSq,
|
||||
0|flags|V_NOSCALESTART
|
||||
);
|
||||
|
||||
V_SetClipRect(
|
||||
fx + fw - whiteSq + (2 * dupx),
|
||||
fy + fh - whiteSq + (2 * dupy),
|
||||
whiteSq - (2 * dupx),
|
||||
whiteSq - (2 * dupy),
|
||||
flags|V_NOSCALESTART
|
||||
);
|
||||
|
||||
K_DrawMapThumbnail(
|
||||
((fx + fw - whiteSq + (2 * dupx)) * FRACUNIT) - (iconWidth - iconHeight),
|
||||
(fy + fh - whiteSq + (2 * dupy)) * FRACUNIT,
|
||||
iconWidth,
|
||||
flags | V_NOSCALESTART | ((encore == true) ? V_FLIP : 0),
|
||||
g_voteLevels[v][0],
|
||||
NULL
|
||||
);
|
||||
|
||||
V_ClearClipRect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1272,6 +1272,7 @@ void M_GonerTutorial(INT32 choice)
|
|||
|
||||
// Please also see M_LevelSelectInit as called in extras-1.c
|
||||
levellist.netgame = false;
|
||||
levellist.canqueue = false;
|
||||
levellist.levelsearch.checklocked = true;
|
||||
levellist.levelsearch.grandprix = false;
|
||||
levellist.levelsearch.timeattack = false;
|
||||
|
|
|
|||
|
|
@ -614,34 +614,19 @@ void M_StartTimeAttack(INT32 choice)
|
|||
{
|
||||
modeattacking |= ATTACKING_SPB;
|
||||
}
|
||||
|
||||
if (gamestate == GS_MENU)
|
||||
{
|
||||
encoremode = true; // guarantees short wipe
|
||||
}
|
||||
|
||||
modeprefix = "spb-";
|
||||
}
|
||||
|
||||
// DON'T SOFTLOCK
|
||||
CON_ToggleOff();
|
||||
|
||||
// Still need to reset devmode
|
||||
cht_debug = 0;
|
||||
|
||||
if (demo.playback)
|
||||
G_StopDemo();
|
||||
|
||||
splitscreen = 0;
|
||||
SplitScreen_OnChange();
|
||||
|
||||
S_StartSound(NULL, sfx_s3k63);
|
||||
|
||||
paused = false;
|
||||
|
||||
S_StopMusicCredit();
|
||||
|
||||
// Early fadeout to let the sound finish playing
|
||||
F_WipeStartScreen();
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(wipe_level_toblack, wipedefs[wipe_level_toblack], false, "FADEMAP0", false, false);
|
||||
|
||||
SV_StartSinglePlayerServer(levellist.newgametype, false);
|
||||
M_MenuToLevelPreamble(0, (gamestate != GS_MENU || cv_dummyspbattack.value == 1));
|
||||
|
||||
gpath = va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s",
|
||||
srb2home, timeattackfolder);
|
||||
|
|
@ -659,8 +644,17 @@ void M_StartTimeAttack(INT32 choice)
|
|||
|
||||
restoreMenu = &PLAY_TimeAttackDef;
|
||||
|
||||
D_MapChange(
|
||||
levellist.choosemap+1,
|
||||
levellist.newgametype,
|
||||
(cv_dummyspbattack.value == 1),
|
||||
true,
|
||||
1,
|
||||
false,
|
||||
false
|
||||
);
|
||||
|
||||
M_ClearMenus(true);
|
||||
D_MapChange(levellist.choosemap+1, levellist.newgametype, (cv_dummyspbattack.value == 1), 1, 1, false, false);
|
||||
|
||||
G_UpdateTimeStickerMedals(levellist.choosemap, true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -172,6 +172,7 @@ void M_MPSetupNetgameMapSelect(INT32 choice)
|
|||
|
||||
// Yep, we'll be starting a netgame.
|
||||
levellist.netgame = true;
|
||||
levellist.canqueue = true;
|
||||
// Make sure we reset those
|
||||
levellist.levelsearch.timeattack = false;
|
||||
levellist.levelsearch.checklocked = true;
|
||||
|
|
|
|||
|
|
@ -57,26 +57,7 @@ static void M_StartCup(UINT8 entry)
|
|||
entry = UINT8_MAX;
|
||||
}
|
||||
|
||||
S_StartSound(NULL, sfx_s3k63);
|
||||
|
||||
paused = false;
|
||||
|
||||
S_StopMusicCredit();
|
||||
|
||||
// Early fadeout to let the sound finish playing
|
||||
F_WipeStartScreen();
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(wipe_level_toblack, wipedefs[wipe_level_toblack], false, "FADEMAP0", false, false);
|
||||
|
||||
if (cv_maxconnections.value < ssplayers+1)
|
||||
CV_SetValue(&cv_maxconnections, ssplayers+1);
|
||||
|
||||
if (splitscreen != ssplayers)
|
||||
{
|
||||
splitscreen = ssplayers;
|
||||
SplitScreen_OnChange();
|
||||
}
|
||||
M_MenuToLevelPreamble(ssplayers, false);
|
||||
|
||||
if (entry == UINT8_MAX)
|
||||
{
|
||||
|
|
@ -135,10 +116,6 @@ static void M_StartCup(UINT8 entry)
|
|||
}
|
||||
}
|
||||
|
||||
paused = false;
|
||||
|
||||
SV_StartSinglePlayerServer(levellist.newgametype, levellist.netgame);
|
||||
|
||||
M_ClearMenus(true);
|
||||
|
||||
restoreMenu = &PLAY_CupSelectDef;
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "../../v_video.h"
|
||||
#include "../../g_game.h" // G_GetBackupCupData
|
||||
#include "../../p_saveg.h" // cupsavedata
|
||||
#include "../../d_netcmd.h" // Handle_MapQueueSend
|
||||
|
||||
cupheader_t dummy_lostandfound;
|
||||
|
||||
|
|
@ -657,14 +658,22 @@ void M_LevelSelectInit(INT32 choice)
|
|||
case 0:
|
||||
levellist.levelsearch.grandprix = false;
|
||||
levellist.levelsearch.timeattack = false;
|
||||
levellist.canqueue = true;
|
||||
|
||||
CV_StealthSet(&cv_kartbot, cv_dummymatchbots.string);
|
||||
CV_StealthSet(&cv_kartencore, (cv_dummygpencore.value == 1) ? "On" : "Auto");
|
||||
CV_StealthSet(&cv_kartspeed, (cv_dummykartspeed.value == KARTSPEED_NORMAL) ? "Auto Gear" : cv_dummykartspeed.string);
|
||||
|
||||
break;
|
||||
case 1:
|
||||
levellist.levelsearch.grandprix = false;
|
||||
levellist.levelsearch.timeattack = true;
|
||||
levellist.canqueue = false;
|
||||
break;
|
||||
case 2:
|
||||
levellist.levelsearch.grandprix = true;
|
||||
levellist.levelsearch.timeattack = false;
|
||||
levellist.canqueue = false;
|
||||
break;
|
||||
default:
|
||||
CONS_Alert(CONS_WARNING, "Bad level select init\n");
|
||||
|
|
@ -676,10 +685,14 @@ void M_LevelSelectInit(INT32 choice)
|
|||
gt = menugametype;
|
||||
}
|
||||
|
||||
if (levellist.levelsearch.timeattack && gt == GT_RACE && skins[R_SkinAvailableEx(cv_skin[0].string, false)].flags & SF_HIVOLT)
|
||||
if (levellist.levelsearch.timeattack && gt == GT_RACE)
|
||||
{
|
||||
M_StartMessage("A long-forgotten power...", "You are using a \x82prototype engine\x80.\nRecords will not be saved.", NULL, MM_NOTHING, NULL, NULL);
|
||||
S_StartSound(NULL, sfx_s3k81);
|
||||
const INT32 skinid = R_SkinAvailableEx(cv_skin[0].string, false);
|
||||
if (skinid >= 0 && (skins[skinid].flags & SF_HIVOLT))
|
||||
{
|
||||
M_StartMessage("A long-forgotten power...", "You are using a \x82prototype engine\x80.\nRecords will not be saved.", NULL, MM_NOTHING, NULL, NULL);
|
||||
S_StartSound(NULL, sfx_s3k81);
|
||||
}
|
||||
}
|
||||
|
||||
if (!M_LevelListFromGametype(gt))
|
||||
|
|
@ -689,7 +702,41 @@ void M_LevelSelectInit(INT32 choice)
|
|||
}
|
||||
}
|
||||
|
||||
void M_LevelSelected(INT16 add, boolean menuupdate)
|
||||
void M_MenuToLevelPreamble(UINT8 ssplayers, boolean nowipe)
|
||||
{
|
||||
cht_debug = 0;
|
||||
|
||||
if (demo.playback)
|
||||
G_StopDemo();
|
||||
|
||||
if (cv_maxconnections.value < ssplayers+1)
|
||||
CV_SetValue(&cv_maxconnections, ssplayers+1);
|
||||
|
||||
if (splitscreen != ssplayers)
|
||||
{
|
||||
splitscreen = ssplayers;
|
||||
SplitScreen_OnChange();
|
||||
}
|
||||
|
||||
paused = false;
|
||||
|
||||
S_StopMusicCredit();
|
||||
|
||||
if (!nowipe)
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3k63);
|
||||
|
||||
// Early fadeout to let the sound finish playing
|
||||
F_WipeStartScreen();
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(wipe_level_toblack, wipedefs[wipe_level_toblack], false, "FADEMAP0", false, false);
|
||||
}
|
||||
|
||||
SV_StartSinglePlayerServer(levellist.newgametype, levellist.netgame);
|
||||
}
|
||||
|
||||
INT16 M_LevelFromScrolledList(INT16 add)
|
||||
{
|
||||
UINT8 i = 0;
|
||||
INT16 map = M_GetFirstLevelInList(&i, &levellist.levelsearch);
|
||||
|
|
@ -706,6 +753,13 @@ void M_LevelSelected(INT16 add, boolean menuupdate)
|
|||
add--;
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
void M_LevelSelected(INT16 add, boolean menuupdate)
|
||||
{
|
||||
INT16 map = M_LevelFromScrolledList(add);
|
||||
|
||||
if (map >= nummapheaders)
|
||||
{
|
||||
// This shouldn't happen
|
||||
|
|
@ -733,75 +787,116 @@ void M_LevelSelected(INT16 add, boolean menuupdate)
|
|||
{
|
||||
if (gamestate == GS_MENU)
|
||||
{
|
||||
UINT8 ssplayers = levellist.levelsearch.tutorial ? 0 : cv_splitplayers.value-1;
|
||||
|
||||
netgame = false;
|
||||
multiplayer = true;
|
||||
|
||||
strlcpy(connectedservername, cv_servername.string, MAXSERVERNAME);
|
||||
M_MenuToLevelPreamble(
|
||||
(levellist.levelsearch.tutorial
|
||||
? 0
|
||||
: cv_splitplayers.value-1
|
||||
),
|
||||
(
|
||||
(cv_kartencore.value == 1)
|
||||
&& (gametypes[levellist.newgametype]->rules & GTR_ENCORE)
|
||||
)
|
||||
);
|
||||
|
||||
// Still need to reset devmode
|
||||
cht_debug = 0;
|
||||
|
||||
if (demo.playback)
|
||||
G_StopDemo();
|
||||
|
||||
/*if (levellist.choosemap == 0)
|
||||
levellist.choosemap = G_RandMap(G_TOLFlag(levellist.newgametype), -1, 0, 0, false, NULL);*/
|
||||
|
||||
if (cv_maxconnections.value < ssplayers+1)
|
||||
CV_SetValue(&cv_maxconnections, ssplayers+1);
|
||||
|
||||
if (splitscreen != ssplayers)
|
||||
{
|
||||
splitscreen = ssplayers;
|
||||
SplitScreen_OnChange();
|
||||
}
|
||||
|
||||
S_StartSound(NULL, sfx_s3k63);
|
||||
|
||||
paused = false;
|
||||
|
||||
S_StopMusicCredit();
|
||||
|
||||
// Early fadeout to let the sound finish playing
|
||||
F_WipeStartScreen();
|
||||
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31);
|
||||
F_WipeEndScreen();
|
||||
F_RunWipe(wipe_level_toblack, wipedefs[wipe_level_toblack], false, "FADEMAP0", false, false);
|
||||
|
||||
SV_StartSinglePlayerServer(levellist.newgametype, levellist.netgame);
|
||||
|
||||
if (!levellist.netgame)
|
||||
CV_StealthSet(&cv_kartbot, cv_dummymatchbots.string);
|
||||
|
||||
CV_StealthSet(&cv_kartencore, (cv_dummygpencore.value == 1) ? "On" : "Auto");
|
||||
CV_StealthSet(&cv_kartspeed, (cv_dummykartspeed.value == KARTSPEED_NORMAL) ? "Auto Gear" : cv_dummykartspeed.string);
|
||||
|
||||
D_MapChange(levellist.choosemap+1, levellist.newgametype, (cv_kartencore.value == 1), 1, 1, false, false);
|
||||
|
||||
if (levellist.netgame == true)
|
||||
{
|
||||
restoreMenu = &PLAY_MP_OptSelectDef;
|
||||
}
|
||||
else /*if (!M_GameTrulyStarted() ||
|
||||
levellist.levelsearch.tutorial)*/
|
||||
{
|
||||
restoreMenu = currentMenu;
|
||||
}
|
||||
restoreMenu = (levellist.netgame)
|
||||
? &PLAY_MP_OptSelectDef
|
||||
: currentMenu;
|
||||
|
||||
restorelevellist = levellist;
|
||||
}
|
||||
else
|
||||
{
|
||||
// directly do the map change
|
||||
D_MapChange(levellist.choosemap+1, levellist.newgametype, (cv_kartencore.value == 1), 1, 1, false, false);
|
||||
}
|
||||
|
||||
D_MapChange(
|
||||
levellist.choosemap+1,
|
||||
levellist.newgametype,
|
||||
(cv_kartencore.value == 1),
|
||||
true,
|
||||
1,
|
||||
false,
|
||||
false
|
||||
);
|
||||
|
||||
M_ClearMenus(true);
|
||||
}
|
||||
}
|
||||
|
||||
static void M_MenuQueueStopSend(INT32 ch)
|
||||
{
|
||||
(void)ch;
|
||||
|
||||
memset(&menuqueue, 0, sizeof(struct menuqueue));
|
||||
}
|
||||
|
||||
static void M_MenuQueueSelectedLocal(void)
|
||||
{
|
||||
UINT8 i = 0;
|
||||
|
||||
for (; i < menuqueue.size; i++)
|
||||
{
|
||||
G_MapIntoRoundQueue(
|
||||
menuqueue.entries[i].mapnum,
|
||||
menuqueue.entries[i].gametype,
|
||||
menuqueue.entries[i].encore,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
roundqueue.netcommunicate = true;
|
||||
|
||||
if (gamestate == GS_MENU)
|
||||
{
|
||||
levellist.choosemap = roundqueue.entries[0].mapnum;
|
||||
|
||||
multiplayer = true;
|
||||
|
||||
M_MenuToLevelPreamble(
|
||||
cv_splitplayers.value-1,
|
||||
(
|
||||
roundqueue.entries[0].encore
|
||||
&& (gametypes[roundqueue.entries[0].gametype]->rules & GTR_ENCORE)
|
||||
)
|
||||
);
|
||||
|
||||
restoreMenu = (levellist.netgame)
|
||||
? &PLAY_MP_OptSelectDef
|
||||
: currentMenu;
|
||||
|
||||
restorelevellist = levellist;
|
||||
|
||||
roundqueue.position = roundqueue.roundnum = 1;
|
||||
|
||||
D_MapChange(
|
||||
roundqueue.entries[0].mapnum + 1,
|
||||
roundqueue.entries[0].gametype,
|
||||
roundqueue.entries[0].encore,
|
||||
true,
|
||||
1,
|
||||
false,
|
||||
roundqueue.entries[0].rankrestricted
|
||||
);
|
||||
|
||||
M_MenuQueueStopSend(MA_NONE);
|
||||
|
||||
M_ClearMenus(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gamestate == GS_LEVEL && roundqueue.position == 0)
|
||||
{
|
||||
menuqueue.sending = UINT8_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
S_StartSound(NULL, sfx_chchng);
|
||||
|
||||
M_MenuQueueStopSend(MA_NONE);
|
||||
|
||||
M_ClearMenus(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean M_LevelSelectCupSwitch(boolean next, boolean skipones)
|
||||
{
|
||||
levelsearch_t templevelsearch = levellist.levelsearch;
|
||||
|
|
@ -883,6 +978,44 @@ boolean M_LevelSelectCupSwitch(boolean next, boolean skipones)
|
|||
}
|
||||
}
|
||||
|
||||
static void M_MenuQueueResponse(INT32 ch)
|
||||
{
|
||||
M_ClearMenus(false);
|
||||
|
||||
if (ch != MA_YES)
|
||||
return;
|
||||
|
||||
if (!(server || (IsPlayerAdmin(consoleplayer))))
|
||||
return;
|
||||
|
||||
if (!(gamestate == GS_LEVEL && roundqueue.position == 0))
|
||||
return;
|
||||
|
||||
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
static void M_ClearQueueResponse(INT32 ch)
|
||||
{
|
||||
if (ch != MA_YES)
|
||||
return;
|
||||
|
||||
if (!(server || (IsPlayerAdmin(consoleplayer))))
|
||||
return;
|
||||
|
||||
S_StartSound(NULL, sfx_slip);
|
||||
|
||||
if (netgame)
|
||||
{
|
||||
if (roundqueue.size)
|
||||
{
|
||||
Handle_MapQueueSend(0, ROUNDQUEUE_CMD_CLEAR, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&roundqueue, 0, sizeof(struct roundqueue));
|
||||
}
|
||||
void M_LevelSelectHandler(INT32 choice)
|
||||
{
|
||||
const UINT8 pid = 0;
|
||||
|
|
@ -894,6 +1027,11 @@ void M_LevelSelectHandler(INT32 choice)
|
|||
return;
|
||||
}
|
||||
|
||||
if (menuqueue.sending)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (menucmd[pid].dpad_ud > 0)
|
||||
{
|
||||
levellist.cursor++;
|
||||
|
|
@ -926,10 +1064,96 @@ void M_LevelSelectHandler(INT32 choice)
|
|||
|
||||
M_LevelSelectScrollDest();
|
||||
|
||||
if (M_MenuConfirmPressed(pid) /*|| M_MenuButtonPressed(pid, MBT_START)*/)
|
||||
if (M_MenuConfirmPressed(pid))
|
||||
{
|
||||
// Starting immediately OR importing queue
|
||||
|
||||
M_SetMenuDelay(pid);
|
||||
M_LevelSelected(levellist.cursor, true);
|
||||
|
||||
while ((menuqueue.size + roundqueue.size) > ROUNDQUEUE_MAX)
|
||||
menuqueue.size--;
|
||||
|
||||
if (!levellist.canqueue || !menuqueue.size)
|
||||
{
|
||||
M_LevelSelected(levellist.cursor, true);
|
||||
}
|
||||
else if (netgame)
|
||||
{
|
||||
menuqueue.anchor = roundqueue.size;
|
||||
menuqueue.sending = 1;
|
||||
|
||||
M_StartMessage("Queueing Rounds",
|
||||
va(M_GetText(
|
||||
"Attempting to send %d Round%s...\n"
|
||||
"\n"
|
||||
"If this is taking longer than you\n"
|
||||
"expect, exit out of this message.\n"
|
||||
), menuqueue.size, (menuqueue.size == 1 ? "" : "s")
|
||||
), &M_MenuQueueStopSend, MM_NOTHING,
|
||||
NULL,
|
||||
"This is taking too long..."
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
M_MenuQueueSelectedLocal();
|
||||
}
|
||||
}
|
||||
else if (levellist.canqueue && M_MenuButtonPressed(pid, MBT_Z))
|
||||
{
|
||||
// Adding to queue
|
||||
|
||||
INT16 map = NEXTMAP_INVALID;
|
||||
|
||||
M_SetMenuDelay(pid);
|
||||
|
||||
if ((roundqueue.size + menuqueue.size) < ROUNDQUEUE_MAX)
|
||||
{
|
||||
map = M_LevelFromScrolledList(levellist.cursor);
|
||||
}
|
||||
|
||||
if (map < nummapheaders)
|
||||
{
|
||||
memset(menuqueue.entries+menuqueue.size, 0, sizeof(roundentry_t));
|
||||
menuqueue.entries[menuqueue.size].mapnum = map;
|
||||
menuqueue.entries[menuqueue.size].gametype = levellist.newgametype;
|
||||
menuqueue.entries[menuqueue.size].encore = (cv_kartencore.value == 1);
|
||||
|
||||
menuqueue.size++;
|
||||
|
||||
S_StartSound(NULL, sfx_s3k4a);
|
||||
}
|
||||
else
|
||||
{
|
||||
S_StartSound(NULL, sfx_s3kb2);
|
||||
}
|
||||
}
|
||||
else if (levellist.canqueue && M_MenuExtraPressed(pid))
|
||||
{
|
||||
while ((menuqueue.size + roundqueue.size) > ROUNDQUEUE_MAX)
|
||||
menuqueue.size--;
|
||||
|
||||
if (menuqueue.size)
|
||||
{
|
||||
S_StartSound(NULL, sfx_shldls);
|
||||
menuqueue.size--;
|
||||
}
|
||||
else if (roundqueue.size)
|
||||
{
|
||||
M_StartMessage("Queue Clearing",
|
||||
va(M_GetText(
|
||||
"There %s %d Round%s of play queued.\n"
|
||||
"\n"
|
||||
"Do you want to empty the queue?\n"
|
||||
),
|
||||
(roundqueue.size == 1 ? "is" : "are"),
|
||||
roundqueue.size,
|
||||
(roundqueue.size == 1 ? "" : "s")
|
||||
), &M_ClearQueueResponse, MM_YESNO,
|
||||
"Time to start fresh",
|
||||
"Not right now"
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (M_MenuBackPressed(pid))
|
||||
{
|
||||
|
|
@ -944,4 +1168,55 @@ void M_LevelSelectHandler(INT32 choice)
|
|||
|
||||
void M_LevelSelectTick(void)
|
||||
{
|
||||
if (!menuqueue.sending)
|
||||
return;
|
||||
|
||||
if ((menuqueue.sending <= menuqueue.size) // Sending
|
||||
&& (roundqueue.size >= menuqueue.anchor)) // Didn't get it wiped
|
||||
{
|
||||
if (!netgame)
|
||||
return;
|
||||
|
||||
const UINT8 idcount = (roundqueue.size - menuqueue.anchor);
|
||||
|
||||
if (idcount == menuqueue.sending-1)
|
||||
{
|
||||
Handle_MapQueueSend(
|
||||
menuqueue.entries[idcount].mapnum,
|
||||
menuqueue.entries[idcount].gametype,
|
||||
menuqueue.entries[idcount].encore
|
||||
);
|
||||
}
|
||||
if (idcount >= menuqueue.sending-1)
|
||||
{
|
||||
menuqueue.sending++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (menuqueue.size)
|
||||
{
|
||||
S_StartSound(NULL, sfx_chchng);
|
||||
|
||||
if (roundqueue.position || gamestate != GS_LEVEL)
|
||||
{
|
||||
M_StopMessage(MA_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
M_StartMessage("Round Queue",
|
||||
va(M_GetText(
|
||||
"You just queued %d Round%s of play.\n"
|
||||
"\n"
|
||||
"Do you want to skip the current\n"
|
||||
"course and start them immediately?\n"
|
||||
), menuqueue.size, (menuqueue.size == 1 ? "" : "s")
|
||||
), &M_MenuQueueResponse, MM_YESNO,
|
||||
"Let's get going!",
|
||||
"Not right now"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
M_MenuQueueStopSend(MA_NONE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,21 +39,21 @@ menuitem_t PAUSE_PlaybackMenu[] =
|
|||
{IT_CALL | IT_STRING, "Hide Menu", NULL, "M_PHIDE", {.routine = M_SelectableClearMenus}, 0, 0},
|
||||
|
||||
{IT_CALL | IT_STRING, "Restart", NULL, "M_PRSTRT", {.routine = M_PlaybackRewind}, 20, 0},
|
||||
{IT_CALL | IT_STRING, "Pause", NULL, "M_PPAUSE", {.routine = M_PlaybackPause}, 36, 0},
|
||||
{IT_CALL | IT_STRING, "Fast-Forward", NULL, "M_PFFWD", {.routine = M_PlaybackFastForward}, 52, 0},
|
||||
{IT_CALL | IT_STRING, "Restart", NULL, "M_PRSTRT", {.routine = M_PlaybackRewind}, 20, 0},
|
||||
{IT_CALL | IT_STRING, "Resume", NULL, "M_PRESUM", {.routine = M_PlaybackPause}, 36, 0},
|
||||
{IT_CALL | IT_STRING, "Advance Frame", NULL, "M_PFADV", {.routine = M_PlaybackAdvance}, 52, 0},
|
||||
{IT_CALL | IT_STRING, "Rewind 5 seconds", NULL, "M_PREW", {.routine = M_PlaybackRewind}, 36, 0},
|
||||
{IT_CALL | IT_STRING, "Pause", NULL, "M_PPAUSE", {.routine = M_PlaybackPause}, 52, 0},
|
||||
{IT_CALL | IT_STRING, "Fast-Forward", NULL, "M_PFFWD", {.routine = M_PlaybackFastForward}, 68, 0},
|
||||
{IT_CALL | IT_STRING, "Resume", NULL, "M_PRESUM", {.routine = M_PlaybackPause}, 52, 0},
|
||||
{IT_CALL | IT_STRING, "Advance Frame", NULL, "M_PFADV", {.routine = M_PlaybackAdvance}, 68, 0},
|
||||
|
||||
{IT_ARROWS | IT_STRING, "View Count", NULL, "M_PVIEWS", {.routine = M_PlaybackSetViews}, 72, 0},
|
||||
{IT_ARROWS | IT_STRING, "Viewpoint", NULL, "M_PNVIEW", {.routine = M_PlaybackAdjustView}, 88, 0},
|
||||
{IT_ARROWS | IT_STRING, "Viewpoint 2", NULL, "M_PNVIEW", {.routine = M_PlaybackAdjustView}, 104, 0},
|
||||
{IT_ARROWS | IT_STRING, "Viewpoint 3", NULL, "M_PNVIEW", {.routine = M_PlaybackAdjustView}, 120, 0},
|
||||
{IT_ARROWS | IT_STRING, "Viewpoint 4", NULL, "M_PNVIEW", {.routine = M_PlaybackAdjustView}, 136, 0},
|
||||
{IT_ARROWS | IT_STRING, "View Count", NULL, "M_PVIEWS", {.routine = M_PlaybackSetViews}, 88, 0},
|
||||
{IT_ARROWS | IT_STRING, "Viewpoint", NULL, "M_PNVIEW", {.routine = M_PlaybackAdjustView}, 104, 0},
|
||||
{IT_ARROWS | IT_STRING, "Viewpoint 2", NULL, "M_PNVIEW", {.routine = M_PlaybackAdjustView}, 120, 0},
|
||||
{IT_ARROWS | IT_STRING, "Viewpoint 3", NULL, "M_PNVIEW", {.routine = M_PlaybackAdjustView}, 136, 0},
|
||||
{IT_ARROWS | IT_STRING, "Viewpoint 4", NULL, "M_PNVIEW", {.routine = M_PlaybackAdjustView}, 152, 0},
|
||||
|
||||
{IT_CALL | IT_STRING, "Toggle Director", NULL, "UN_IC11A", {.routine = M_PlaybackToggleDirector}, 156, 0},
|
||||
{IT_CALL | IT_STRING, "Toggle Free Camera", NULL, "M_PVIEWS", {.routine = M_PlaybackToggleFreecam}, 172, 0},
|
||||
{IT_CALL | IT_STRING, "Stop Playback", NULL, "M_PEXIT", {.routine = M_PlaybackQuit}, 188, 0},
|
||||
{IT_CALL | IT_STRING, "Toggle Director", NULL, "UN_IC11A", {.routine = M_PlaybackToggleDirector}, 172, 0},
|
||||
{IT_CALL | IT_STRING, "Toggle Free Camera", NULL, "M_PVIEWS", {.routine = M_PlaybackToggleFreecam}, 188, 0},
|
||||
{IT_CALL | IT_STRING, "Stop Playback", NULL, "M_PEXIT", {.routine = M_PlaybackQuit}, 204, 0},
|
||||
};
|
||||
|
||||
menu_t PAUSE_PlaybackMenuDef = {
|
||||
|
|
@ -151,21 +151,21 @@ static void M_PlaybackTick(void)
|
|||
playback_last_menu_interaction_leveltime = leveltime - 6*TICRATE;
|
||||
|
||||
// Toggle items
|
||||
if (paused && !demo.rewinding)
|
||||
if (paused)
|
||||
{
|
||||
PAUSE_PlaybackMenu[playback_pause].status = PAUSE_PlaybackMenu[playback_fastforward].status = PAUSE_PlaybackMenu[playback_rewind].status = IT_DISABLED;
|
||||
PAUSE_PlaybackMenu[playback_resume].status = PAUSE_PlaybackMenu[playback_advanceframe].status = PAUSE_PlaybackMenu[playback_backframe].status = IT_CALL|IT_STRING;
|
||||
PAUSE_PlaybackMenu[playback_pause].status = PAUSE_PlaybackMenu[playback_fastforward].status = IT_DISABLED;
|
||||
PAUSE_PlaybackMenu[playback_resume].status = PAUSE_PlaybackMenu[playback_advanceframe].status = IT_CALL|IT_STRING;
|
||||
|
||||
if (itemOn >= playback_rewind && itemOn <= playback_fastforward)
|
||||
itemOn += playback_backframe - playback_rewind;
|
||||
if (itemOn >= playback_pause && itemOn <= playback_fastforward)
|
||||
itemOn += playback_resume - playback_pause;
|
||||
}
|
||||
else
|
||||
{
|
||||
PAUSE_PlaybackMenu[playback_pause].status = PAUSE_PlaybackMenu[playback_fastforward].status = PAUSE_PlaybackMenu[playback_rewind].status = IT_CALL|IT_STRING;
|
||||
PAUSE_PlaybackMenu[playback_resume].status = PAUSE_PlaybackMenu[playback_advanceframe].status = PAUSE_PlaybackMenu[playback_backframe].status = IT_DISABLED;
|
||||
PAUSE_PlaybackMenu[playback_pause].status = PAUSE_PlaybackMenu[playback_fastforward].status = IT_CALL|IT_STRING;
|
||||
PAUSE_PlaybackMenu[playback_resume].status = PAUSE_PlaybackMenu[playback_advanceframe].status = IT_DISABLED;
|
||||
|
||||
if (itemOn >= playback_backframe && itemOn <= playback_advanceframe)
|
||||
itemOn -= playback_backframe - playback_rewind;
|
||||
if (itemOn >= playback_resume && itemOn <= playback_advanceframe)
|
||||
itemOn -= playback_resume - playback_pause;
|
||||
}
|
||||
|
||||
if (modeattacking)
|
||||
|
|
@ -173,10 +173,10 @@ static void M_PlaybackTick(void)
|
|||
for (i = playback_viewcount; i <= playback_director; i++)
|
||||
PAUSE_PlaybackMenu[i].status = IT_DISABLED;
|
||||
|
||||
PAUSE_PlaybackMenu[playback_freecam].mvar1 = 72;
|
||||
PAUSE_PlaybackMenu[playback_quit].mvar1 = 88;
|
||||
PAUSE_PlaybackMenu[playback_freecam].mvar1 = 88;
|
||||
PAUSE_PlaybackMenu[playback_quit].mvar1 = 104;
|
||||
|
||||
currentMenu->x = BASEVIDWIDTH/2 - 52;
|
||||
currentMenu->x = BASEVIDWIDTH/2 - 60;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -189,11 +189,11 @@ static void M_PlaybackTick(void)
|
|||
for (i = r_splitscreen+1; i < 4; i++)
|
||||
PAUSE_PlaybackMenu[playback_view1+i].status = IT_DISABLED;
|
||||
|
||||
PAUSE_PlaybackMenu[playback_freecam].mvar1 = 172;
|
||||
PAUSE_PlaybackMenu[playback_quit].mvar1 = 188;
|
||||
PAUSE_PlaybackMenu[playback_freecam].mvar1 = 188;
|
||||
PAUSE_PlaybackMenu[playback_quit].mvar1 = 204;
|
||||
|
||||
//currentMenu->x = BASEVIDWIDTH/2 - 94;
|
||||
currentMenu->x = BASEVIDWIDTH/2 - 96;
|
||||
//currentMenu->x = BASEVIDWIDTH/2 - 102;
|
||||
currentMenu->x = BASEVIDWIDTH/2 - 104;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -204,34 +204,38 @@ void M_SetPlaybackMenuPointer(void)
|
|||
|
||||
void M_PlaybackRewind(INT32 choice)
|
||||
{
|
||||
#if 0
|
||||
static tic_t lastconfirmtime;
|
||||
const tic_t curleveltime = leveltime;
|
||||
|
||||
(void)choice;
|
||||
|
||||
if (!demo.rewinding)
|
||||
if (choice == playback_rewind)
|
||||
{
|
||||
if (paused)
|
||||
demo.simplerewind = (paused ? DEMO_REWIND_PAUSE : DEMO_REWIND_RESUME);
|
||||
menuactive = false;
|
||||
}
|
||||
|
||||
G_DoPlayDemo(NULL); // Restart the current demo
|
||||
|
||||
if (demo.simplerewind)
|
||||
{
|
||||
if (curleveltime > 5*TICRATE)
|
||||
{
|
||||
G_ConfirmRewind(leveltime-1);
|
||||
paused = true;
|
||||
S_PauseAudio();
|
||||
g_fast_forward = curleveltime - (5 * TICRATE);
|
||||
g_fast_forward_clock_stop = INFTICS; //I_GetTime() + 2 * TICRATE; -- maybe?
|
||||
}
|
||||
else
|
||||
demo.rewinding = paused = true;
|
||||
{
|
||||
if (demo.simplerewind == DEMO_REWIND_PAUSE)
|
||||
{
|
||||
paused = true;
|
||||
S_PauseAudio();
|
||||
}
|
||||
demo.simplerewind = DEMO_REWIND_OFF;
|
||||
}
|
||||
menuactive = true;
|
||||
}
|
||||
else if (lastconfirmtime + TICRATE/2 < I_GetTime())
|
||||
else
|
||||
{
|
||||
lastconfirmtime = I_GetTime();
|
||||
G_ConfirmRewind(leveltime);
|
||||
M_ClearMenus(true);
|
||||
}
|
||||
|
||||
CV_SetValue(&cv_playbackspeed, 1);
|
||||
#else
|
||||
(void)choice;
|
||||
G_DoPlayDemo(NULL); // Restart the current demo
|
||||
M_ClearMenus(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void M_PlaybackPause(INT32 choice)
|
||||
|
|
@ -240,13 +244,7 @@ void M_PlaybackPause(INT32 choice)
|
|||
|
||||
paused = !paused;
|
||||
|
||||
if (demo.rewinding)
|
||||
{
|
||||
G_ConfirmRewind(leveltime);
|
||||
paused = true;
|
||||
S_PauseAudio();
|
||||
}
|
||||
else if (paused)
|
||||
if (paused)
|
||||
S_PauseAudio();
|
||||
else
|
||||
S_ResumeAudio();
|
||||
|
|
@ -258,12 +256,6 @@ void M_PlaybackFastForward(INT32 choice)
|
|||
{
|
||||
(void)choice;
|
||||
|
||||
if (demo.rewinding)
|
||||
{
|
||||
G_ConfirmRewind(leveltime);
|
||||
paused = false;
|
||||
S_ResumeAudio();
|
||||
}
|
||||
CV_SetValue(&cv_playbackspeed, cv_playbackspeed.value == 1 ? 4 : 1);
|
||||
}
|
||||
|
||||
|
|
|
|||
130
src/p_setup.cpp
130
src/p_setup.cpp
|
|
@ -8388,6 +8388,46 @@ void P_LoadLevelMusic(void)
|
|||
Music_ResetLevelVolume();
|
||||
}
|
||||
|
||||
void P_FreeLevelState(void)
|
||||
{
|
||||
if (numsectors)
|
||||
{
|
||||
F_EndTextPrompt(false, true);
|
||||
K_UnsetDialogue();
|
||||
|
||||
ACS_InvalidateMapScope();
|
||||
LUA_InvalidateLevel();
|
||||
|
||||
Obj_ClearCheckpoints();
|
||||
|
||||
sector_t *ss;
|
||||
for (ss = sectors; sectors+numsectors != ss; ss++)
|
||||
{
|
||||
Z_Free(ss->attached);
|
||||
Z_Free(ss->attachedsolid);
|
||||
}
|
||||
|
||||
// This is the simplest guard against double frees.
|
||||
// No valid map has zero sectors. Or, come to think
|
||||
// of it, less than two in general! ~toast 310525
|
||||
numsectors = 0;
|
||||
}
|
||||
|
||||
// Clear pointers that would be left dangling by the purge
|
||||
R_FlushTranslationColormapCache();
|
||||
|
||||
#ifdef HWRENDER
|
||||
// Free GPU textures before freeing patches.
|
||||
if (rendermode == render_opengl && (vid.glstate == VID_GL_LIBRARY_LOADED))
|
||||
HWR_ClearAllTextures();
|
||||
#endif
|
||||
|
||||
G_FreeGhosts(); // ghosts are allocated with PU_LEVEL
|
||||
Patch_FreeTag(PU_PATCH_LOWPRIORITY);
|
||||
Patch_FreeTag(PU_PATCH_ROTATED);
|
||||
Z_FreeTags(PU_LEVEL, PU_PURGELEVEL - 1);
|
||||
}
|
||||
|
||||
/** Loads a level from a lump or external wad.
|
||||
*
|
||||
* \param fromnetsave If true, skip some stuff because we're loading a netgame snapshot.
|
||||
|
|
@ -8401,7 +8441,6 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
// 99% of the things already did, so.
|
||||
// Map header should always be in place at this point
|
||||
INT32 i, ranspecialwipe = 0;
|
||||
sector_t *ss;
|
||||
virtlump_t *encoreLump = NULL;
|
||||
|
||||
levelloading = true;
|
||||
|
|
@ -8474,7 +8513,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
wipegamestate = gamestate; // Don't fade if reloading the gamestate
|
||||
// Encore mode fade to pink to white
|
||||
// This is handled BEFORE sounds are stopped.
|
||||
else if (encoremode && !prevencoremode && modeattacking == ATTACKING_NONE && !demo.rewinding)
|
||||
else if (encoremode && !prevencoremode && !demo.simplerewind)
|
||||
{
|
||||
if (rendermode != render_none)
|
||||
{
|
||||
|
|
@ -8545,7 +8584,14 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
|
||||
// Let's fade to white here
|
||||
// But only if we didn't do the encore startup wipe
|
||||
if (!demo.rewinding && !reloadinggamestate)
|
||||
if (demo.attract || demo.simplerewind)
|
||||
{
|
||||
// Leave the music alone! We're already playing what we want!
|
||||
// Pull from RNG even though music will never change
|
||||
// To silence playback has desynced warning
|
||||
P_Random(PR_MUSICSELECT);
|
||||
}
|
||||
else if (!reloadinggamestate)
|
||||
{
|
||||
int wipetype = wipe_level_toblack;
|
||||
|
||||
|
|
@ -8558,15 +8604,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
FixedDiv((F_GetWipeLength(wipedefs[wipe_level_toblack])-2)*NEWTICRATERATIO, NEWTICRATE), MUSICRATE));
|
||||
#endif
|
||||
|
||||
if (demo.attract)
|
||||
{
|
||||
; // Leave the music alone! We're already playing what we want!
|
||||
|
||||
// Pull from RNG even though music will never change
|
||||
// To silence playback has desynced warning
|
||||
P_Random(PR_MUSICSELECT);
|
||||
}
|
||||
else if (K_PodiumSequence())
|
||||
if (K_PodiumSequence())
|
||||
{
|
||||
// mapmusrng is set by local player position in K_ResetCeremony
|
||||
P_LoadLevelMusic();
|
||||
|
|
@ -8643,44 +8681,42 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
|
|||
}
|
||||
|
||||
F_RunWipe(wipetype, wipedefs[wipetype], false, ((levelfadecol == 0) ? "FADEMAP1" : "FADEMAP0"), false, false);
|
||||
|
||||
// Hold respawn to keep waiting until you're ready
|
||||
if (G_IsModeAttackRetrying() && !demo.playback)
|
||||
{
|
||||
nowtime = lastwipetic;
|
||||
while (G_PlayerInputDown(0, gc_respawn, splitscreen + 1) == true)
|
||||
{
|
||||
while (!((nowtime = I_GetTime()) - lastwipetic))
|
||||
{
|
||||
I_Sleep(cv_sleep.value);
|
||||
I_UpdateTime();
|
||||
} \
|
||||
|
||||
I_OsPolling();
|
||||
G_ResetAllDeviceResponding();
|
||||
|
||||
for (; eventtail != eventhead; eventtail = (eventtail+1) & (MAXEVENTS-1))
|
||||
{
|
||||
HandleGamepadDeviceEvents(&events[eventtail]);
|
||||
G_MapEventsToControls(&events[eventtail]);
|
||||
}
|
||||
|
||||
lastwipetic = nowtime;
|
||||
if (moviemode && rendermode == render_opengl)
|
||||
M_LegacySaveFrame();
|
||||
else if (moviemode && rendermode == render_soft)
|
||||
I_CaptureVideoFrame();
|
||||
NetKeepAlive();
|
||||
}
|
||||
|
||||
//wipestyleflags |= (WSF_FADEOUT|WSF_TOWHITE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if (!titlemapinaction)
|
||||
wipegamestate = GS_LEVEL;
|
||||
*/
|
||||
|
||||
// Close text prompt before freeing the old level
|
||||
F_EndTextPrompt(false, true);
|
||||
|
||||
K_UnsetDialogue();
|
||||
|
||||
ACS_InvalidateMapScope();
|
||||
|
||||
LUA_InvalidateLevel();
|
||||
|
||||
Obj_ClearCheckpoints();
|
||||
|
||||
for (ss = sectors; sectors+numsectors != ss; ss++)
|
||||
{
|
||||
Z_Free(ss->attached);
|
||||
Z_Free(ss->attachedsolid);
|
||||
}
|
||||
|
||||
// Clear pointers that would be left dangling by the purge
|
||||
R_FlushTranslationColormapCache();
|
||||
|
||||
#ifdef HWRENDER
|
||||
// Free GPU textures before freeing patches.
|
||||
if (rendermode == render_opengl && (vid.glstate == VID_GL_LIBRARY_LOADED))
|
||||
HWR_ClearAllTextures();
|
||||
#endif
|
||||
|
||||
G_FreeGhosts(); // ghosts are allocated with PU_LEVEL
|
||||
Patch_FreeTag(PU_PATCH_LOWPRIORITY);
|
||||
Patch_FreeTag(PU_PATCH_ROTATED);
|
||||
Z_FreeTags(PU_LEVEL, PU_PURGELEVEL - 1);
|
||||
P_FreeLevelState();
|
||||
|
||||
R_InitializeLevelInterpolators();
|
||||
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ extern mapthing_t *mapthings;
|
|||
|
||||
void P_SetupLevelSky(const char *skytexname, boolean global);
|
||||
void P_RespawnThings(void);
|
||||
void P_FreeLevelState(void);
|
||||
void P_ResetLevelMusic(void);
|
||||
boolean P_UseContinuousLevelMusic(void);
|
||||
void P_LoadLevelMusic(void);
|
||||
|
|
|
|||
52
src/p_tick.c
52
src/p_tick.c
|
|
@ -739,15 +739,7 @@ void P_Ticker(boolean run)
|
|||
// Check for pause or menu up in single player
|
||||
if (paused || P_AutoPause())
|
||||
{
|
||||
if (demo.rewinding && leveltime > 0)
|
||||
{
|
||||
leveltime = (leveltime-1) & ~3;
|
||||
if (timeinmap > 0)
|
||||
timeinmap = (timeinmap-1) & ~3;
|
||||
G_PreviewRewind(leveltime);
|
||||
}
|
||||
else
|
||||
P_RunChaseCameras(); // special case: allow freecam to MOVE during pause!
|
||||
P_RunChaseCameras(); // special case: allow freecam to MOVE during pause!
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -762,17 +754,23 @@ void P_Ticker(boolean run)
|
|||
|
||||
if (demo.recording)
|
||||
{
|
||||
G_WriteDemoExtraData();
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
G_WriteDemoTiccmd(&players[i].cmd, i);
|
||||
if (!G_ConsiderEndingDemoWrite())
|
||||
{
|
||||
G_WriteDemoExtraData();
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
G_WriteDemoTiccmd(&players[i].cmd, i);
|
||||
}
|
||||
}
|
||||
if (demo.playback && !demo.waitingfortally)
|
||||
{
|
||||
G_ReadDemoExtraData();
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
G_ReadDemoTiccmd(&players[i].cmd, i);
|
||||
if (!G_ConsiderEndingDemoRead())
|
||||
{
|
||||
G_ReadDemoExtraData();
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
if (playeringame[i])
|
||||
G_ReadDemoTiccmd(&players[i].cmd, i);
|
||||
}
|
||||
}
|
||||
|
||||
LUA_ResetTicTimers();
|
||||
|
|
@ -1078,7 +1076,7 @@ void P_Ticker(boolean run)
|
|||
}
|
||||
}
|
||||
|
||||
if (g_fast_forward == 0)
|
||||
if (g_fast_forward == 0 || demo.simplerewind)
|
||||
{
|
||||
timeinmap++;
|
||||
}
|
||||
|
|
@ -1168,14 +1166,21 @@ void P_Ticker(boolean run)
|
|||
|
||||
if (demo.recording)
|
||||
{
|
||||
G_WriteAllGhostTics();
|
||||
|
||||
if (cv_recordmultiplayerdemos.value && demo.savebutton && demo.savebutton + 3*TICRATE < leveltime)
|
||||
G_CheckDemoTitleEntry();
|
||||
|
||||
if (!G_ConsiderEndingDemoWrite())
|
||||
{
|
||||
G_WriteAllGhostTics();
|
||||
}
|
||||
}
|
||||
else if (demo.playback && !demo.waitingfortally) // Use Ghost data for consistency checks.
|
||||
else if (demo.playback && !demo.waitingfortally)
|
||||
{
|
||||
G_ConsAllGhostTics();
|
||||
if (!G_ConsiderEndingDemoRead())
|
||||
{
|
||||
// Use Ghost data for consistency checks.
|
||||
G_ConsAllGhostTics();
|
||||
}
|
||||
}
|
||||
|
||||
if (modeattacking)
|
||||
|
|
@ -1238,9 +1243,6 @@ void P_Ticker(boolean run)
|
|||
|
||||
P_MapEnd();
|
||||
|
||||
if (demo.playback)
|
||||
G_StoreRewindInfo();
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
G_CopyTiccmd(&players[i].oldcmd, &players[i].cmd, 1);
|
||||
|
|
|
|||
|
|
@ -737,6 +737,8 @@ void ST_startTitleCard(void)
|
|||
lt_ticker = lt_exitticker = lt_lasttic = 0;
|
||||
lt_endtime = 4*TICRATE; // + (10*NEWTICRATERATIO);
|
||||
lt_fade = 0;
|
||||
|
||||
WipeStageTitle = false;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -788,7 +790,7 @@ patch_t *ST_getRoundPicture(boolean small)
|
|||
//
|
||||
void ST_runTitleCard(void)
|
||||
{
|
||||
boolean run = !(paused || P_AutoPause() || g_fast_forward > 0);
|
||||
boolean run = !(paused || P_AutoPause() || (g_fast_forward > 0 && demo.simplerewind == DEMO_REWIND_OFF));
|
||||
INT32 auxticker;
|
||||
boolean doroundicon = (ST_getRoundPicture(false) != NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -76,7 +76,6 @@ TYPEDEF (plrconfig);
|
|||
TYPEDEF (filesneededconfig_pak);
|
||||
TYPEDEF (doomdata_t);
|
||||
TYPEDEF (serverelem_t);
|
||||
TYPEDEF (rewind_t);
|
||||
TYPEDEF (clientkey_pak);
|
||||
TYPEDEF (serverchallenge_pak);
|
||||
TYPEDEF (challengeall_pak);
|
||||
|
|
|
|||
134
src/y_inter.cpp
134
src/y_inter.cpp
|
|
@ -971,11 +971,15 @@ void Y_PlayerStandingsDrawer(y_data_t *standings, INT32 xoffset)
|
|||
// Handles drawing the bottom-of-screen progression.
|
||||
// Currently requires intermission y_data for animation only.
|
||||
//
|
||||
void Y_RoundQueueDrawer(y_data_t *standings, INT32 offset, boolean doanimations, boolean widescreen)
|
||||
void Y_RoundQueueDrawer(y_data_t *standings, INT32 offset, boolean doanimations, boolean widescreen, boolean adminmode)
|
||||
{
|
||||
if (roundqueue.size == 0)
|
||||
{
|
||||
return;
|
||||
if (!adminmode
|
||||
|| menuqueue.size == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// The following is functionally a hack.
|
||||
|
|
@ -1041,6 +1045,10 @@ void Y_RoundQueueDrawer(y_data_t *standings, INT32 offset, boolean doanimations,
|
|||
prize_dot[BPP_AHEAD] = static_cast<patch_t*>(W_CachePatchName("R_RRMRK4", PU_PATCH));
|
||||
prize_dot[BPP_DONE] = static_cast<patch_t*>(W_CachePatchName("R_RRMRK6", PU_PATCH));
|
||||
|
||||
patch_t *rpmark[2];
|
||||
rpmark[0] = static_cast<patch_t*>(W_CachePatchName("R_RPMARK", PU_PATCH));
|
||||
rpmark[1] = static_cast<patch_t*>(W_CachePatchName("R_R2MARK", PU_PATCH));
|
||||
|
||||
UINT8 *colormap = NULL, *oppositemap = NULL;
|
||||
fixed_t playerx = 0, playery = 0;
|
||||
UINT8 pskin = MAXSKINS;
|
||||
|
|
@ -1079,10 +1087,37 @@ void Y_RoundQueueDrawer(y_data_t *standings, INT32 offset, boolean doanimations,
|
|||
upwa = true;
|
||||
}
|
||||
|
||||
workingqueuesize--;
|
||||
if (!adminmode)
|
||||
{
|
||||
workingqueuesize--;
|
||||
}
|
||||
}
|
||||
|
||||
INT32 widthofroundqueue = 24*(workingqueuesize - 1);
|
||||
INT32 widthofroundqueue, totalsteps;
|
||||
|
||||
INT32 menusendoffset = 0;
|
||||
if (menuqueue.sending)
|
||||
{
|
||||
if (menuqueue.sending > menuqueue.size)
|
||||
{
|
||||
menusendoffset = menuqueue.size;
|
||||
}
|
||||
else
|
||||
{
|
||||
menusendoffset = menuqueue.sending-1;
|
||||
}
|
||||
}
|
||||
|
||||
if (adminmode)
|
||||
{
|
||||
totalsteps = std::min(workingqueuesize + (menuqueue.size - menusendoffset), ROUNDQUEUE_MAX);
|
||||
}
|
||||
else
|
||||
{
|
||||
totalsteps = workingqueuesize;
|
||||
}
|
||||
|
||||
widthofroundqueue = (totalsteps - 1) * 24;
|
||||
|
||||
INT32 x = (BASEVIDWIDTH - widthofroundqueue) / 2;
|
||||
INT32 y, basey = 167 + offset;
|
||||
|
|
@ -1091,7 +1126,7 @@ void Y_RoundQueueDrawer(y_data_t *standings, INT32 offset, boolean doanimations,
|
|||
|
||||
// The following block handles horizontal easing of the
|
||||
// progression bar on the last non-rankrestricted round.
|
||||
if (standings->showrank == true)
|
||||
if (!adminmode && standings->showrank == true)
|
||||
{
|
||||
fixed_t percentslide = 0;
|
||||
SINT8 deferxoffs = 0;
|
||||
|
|
@ -1151,12 +1186,22 @@ void Y_RoundQueueDrawer(y_data_t *standings, INT32 offset, boolean doanimations,
|
|||
V_DrawMappedPatch(xiter, basey, baseflags, queuebg_upwa, greymap);
|
||||
}
|
||||
|
||||
// Draw to left side of screen
|
||||
while (xiter > -bufferspace)
|
||||
{
|
||||
xiter -= 24;
|
||||
V_DrawMappedPatch(xiter, basey, baseflags, queuebg_flat, greymap);
|
||||
}
|
||||
|
||||
// Draw to right side of screen
|
||||
xiter = x + widthofroundqueue;
|
||||
while (xiter < BASEVIDWIDTH + bufferspace)
|
||||
{
|
||||
xiter += 24;
|
||||
V_DrawMappedPatch(xiter, basey, baseflags, queuebg_flat, greymap);
|
||||
}
|
||||
|
||||
// Actually queued maps
|
||||
for (i = 0; i < workingqueuesize; i++)
|
||||
{
|
||||
// Draw the background, and grab the appropriate line, to the right of the dot
|
||||
|
|
@ -1186,7 +1231,13 @@ void Y_RoundQueueDrawer(y_data_t *standings, INT32 offset, boolean doanimations,
|
|||
}
|
||||
else
|
||||
{
|
||||
V_DrawMappedPatch(x, basey, baseflags, queuebg_flat, greymap);
|
||||
V_DrawMappedPatch(
|
||||
x,
|
||||
basey,
|
||||
baseflags,
|
||||
((workingqueuesize == totalsteps) ? queuebg_flat : queuebg_upwa),
|
||||
greymap
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1321,17 +1372,9 @@ void Y_RoundQueueDrawer(y_data_t *standings, INT32 offset, boolean doanimations,
|
|||
}
|
||||
else
|
||||
{
|
||||
// No more line! Fill in background to right edge of screen
|
||||
xiter = x;
|
||||
while (xiter < BASEVIDWIDTH + bufferspace)
|
||||
{
|
||||
xiter += 24;
|
||||
V_DrawMappedPatch(xiter, basey, baseflags, queuebg_flat, greymap);
|
||||
}
|
||||
|
||||
// Handle special entry on the end
|
||||
// (has to be drawn before the semifinal dot due to overlap)
|
||||
if (standings->showrank == true)
|
||||
if (!adminmode && standings->showrank == true)
|
||||
{
|
||||
const fixed_t x2 = x + spacetospecial;
|
||||
|
||||
|
|
@ -1342,7 +1385,7 @@ void Y_RoundQueueDrawer(y_data_t *standings, INT32 offset, boolean doanimations,
|
|||
}
|
||||
else if (
|
||||
doanimations == true
|
||||
&& roundqueue.position == roundqueue.size-1
|
||||
&& roundqueue.position == workingqueuesize
|
||||
&& timer - interpoffs <= 2*TICRATE
|
||||
)
|
||||
{
|
||||
|
|
@ -1522,13 +1565,62 @@ void Y_RoundQueueDrawer(y_data_t *standings, INT32 offset, boolean doanimations,
|
|||
x += 24;
|
||||
}
|
||||
|
||||
totalsteps -= i;
|
||||
|
||||
// Maps in the progress of being queued on the menu
|
||||
if (adminmode && totalsteps)
|
||||
{
|
||||
for (i = menusendoffset; i < (totalsteps + menusendoffset); i++)
|
||||
{
|
||||
upwa ^= true;
|
||||
if (upwa == false)
|
||||
{
|
||||
y = basey + 4;
|
||||
|
||||
V_DrawMappedPatch(x, basey, baseflags, queuebg_down, greymap);
|
||||
}
|
||||
else
|
||||
{
|
||||
y = basey + 12;
|
||||
|
||||
if (i+1 != menuqueue.size) // no more line?
|
||||
{
|
||||
V_DrawMappedPatch(x, basey, baseflags, queuebg_upwa, greymap);
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawMappedPatch(x, basey, baseflags, queuebg_flat, greymap);
|
||||
}
|
||||
}
|
||||
|
||||
V_DrawMappedPatch(
|
||||
x - 8, y,
|
||||
baseflags,
|
||||
level_dot[BPP_AHEAD],
|
||||
NULL
|
||||
);
|
||||
|
||||
V_DrawMappedPatch(
|
||||
x - 10, y - 14,
|
||||
baseflags,
|
||||
rpmark[0],
|
||||
NULL
|
||||
);
|
||||
|
||||
K_DrawMapAsFace(
|
||||
x - 9, y - 13,
|
||||
(baseflags|((menuqueue.entries[i].encore) ? V_FLIP : 0)),
|
||||
menuqueue.entries[i].mapnum,
|
||||
NULL
|
||||
);
|
||||
|
||||
x += 24;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the player position through the round queue!
|
||||
if (playery != 0)
|
||||
{
|
||||
patch_t *rpmark[2];
|
||||
rpmark[0] = static_cast<patch_t*>(W_CachePatchName("R_RPMARK", PU_PATCH));
|
||||
rpmark[1] = static_cast<patch_t*>(W_CachePatchName("R_R2MARK", PU_PATCH));
|
||||
|
||||
// Change alignment
|
||||
playerx -= (10 * FRACUNIT);
|
||||
playery -= (14 * FRACUNIT);
|
||||
|
|
@ -1934,7 +2026,7 @@ skiptallydrawer:
|
|||
goto finalcounter;
|
||||
|
||||
// Returns early if there's no roundqueue entries to draw
|
||||
Y_RoundQueueDrawer(&data, 0, true, false);
|
||||
Y_RoundQueueDrawer(&data, 0, true, false, false);
|
||||
|
||||
if (netgame)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ void Y_Ticker(void);
|
|||
|
||||
// Specific sub-drawers
|
||||
void Y_PlayerStandingsDrawer(y_data_t *standings, INT32 xoffset);
|
||||
void Y_RoundQueueDrawer(y_data_t *standings, INT32 offset, boolean doanimations, boolean widescreen);
|
||||
void Y_RoundQueueDrawer(y_data_t *standings, INT32 offset, boolean doanimations, boolean widescreen, boolean adminmode);
|
||||
void Y_DrawIntermissionButton(INT32 startslide, INT32 through, boolean widescreen);
|
||||
void Y_DrawRankMode(INT32 x, INT32 y, boolean center);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue