mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2026-03-08 04:06:25 +00:00
extras: replay hut
This commit is contained in:
parent
75df86da2f
commit
9de737682d
4 changed files with 677 additions and 2 deletions
29
src/k_menu.h
29
src/k_menu.h
|
|
@ -18,6 +18,7 @@
|
|||
#include "d_event.h"
|
||||
#include "command.h"
|
||||
#include "doomstat.h" // MAXSPLITSCREENPLAYERS
|
||||
#include "g_demo.h" //menudemo_t
|
||||
|
||||
// flags for items in the menu
|
||||
// menu handle (what we do when key is pressed
|
||||
|
|
@ -272,6 +273,12 @@ extern menu_t OPTIONS_DataEraseDef;
|
|||
extern menuitem_t EXTRAS_Main[];
|
||||
extern menu_t EXTRAS_MainDef;
|
||||
|
||||
extern menuitem_t EXTRAS_ReplayHut[];
|
||||
extern menu_t EXTRAS_ReplayHutDef;
|
||||
|
||||
extern menuitem_t EXTRAS_ReplayStart[];
|
||||
extern menu_t EXTRAS_ReplayStartDef;
|
||||
|
||||
// PAUSE
|
||||
extern menuitem_t PAUSE_Main[];
|
||||
extern menu_t PAUSE_MainDef;
|
||||
|
|
@ -571,6 +578,8 @@ void M_HandleVideoModes(INT32 ch);
|
|||
|
||||
|
||||
// Extras menu:
|
||||
#define DF_ENCORE 0x40
|
||||
|
||||
extern struct extrasmenu_s {
|
||||
|
||||
tic_t ticker; // How long the menu's been open for
|
||||
|
|
@ -583,6 +592,16 @@ extern struct extrasmenu_s {
|
|||
INT16 textx;
|
||||
INT16 texty;
|
||||
|
||||
|
||||
// The replay vars...... oh no......
|
||||
menudemo_t *demolist;
|
||||
|
||||
INT16 replayScrollTitle;
|
||||
SINT8 replayScrollDelay;
|
||||
SINT8 replayScrollDir;
|
||||
|
||||
|
||||
|
||||
} extrasmenu;
|
||||
|
||||
void M_InitExtras(INT32 choice); // init for the struct
|
||||
|
|
@ -590,6 +609,13 @@ void M_ExtrasTick(void);
|
|||
boolean M_ExtrasInputs(INT32 ch);
|
||||
boolean M_ExtrasQuit(void); // resets buttons when you quit
|
||||
|
||||
// Extras: Replay Hut
|
||||
void M_HandleReplayHutList(INT32 choice);
|
||||
boolean M_QuitReplayHut(void);
|
||||
void M_HutStartReplay(INT32 choice);
|
||||
void M_PrepReplayList(void);
|
||||
|
||||
|
||||
// Pause menu:
|
||||
|
||||
// Keep track of some pause menu data for visual goodness.
|
||||
|
|
@ -688,6 +714,9 @@ void M_DrawItemToggles(void);
|
|||
// Extras menu:
|
||||
void M_DrawExtrasMovingButton(void);
|
||||
void M_DrawExtras(void);
|
||||
void M_DrawReplayHut(void);
|
||||
void M_DrawReplayStartMenu(void);
|
||||
void M_DrawReplayHutReplayInfo(void);
|
||||
|
||||
// Misc menus:
|
||||
#define LOCATIONSTRING1 "Visit \x83SRB2.ORG/MODS\x80 to get & make addons!"
|
||||
|
|
|
|||
|
|
@ -1113,7 +1113,7 @@ menuitem_t EXTRAS_Main[] =
|
|||
NULL, M_Addons, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "Replay Hut", "Play the replays you've saved throughout your many races & battles!",
|
||||
NULL, NULL, 0, 0},
|
||||
NULL, M_ReplayHut, 0, 0},
|
||||
|
||||
{IT_STRING | IT_CALL, "Statistics", "Look back on some of your greatest achievements such as your playtime and wins!",
|
||||
NULL, NULL, 0, 0},
|
||||
|
|
@ -1137,6 +1137,62 @@ menu_t EXTRAS_MainDef = {
|
|||
M_ExtrasInputs
|
||||
};
|
||||
|
||||
// extras menu: replay hut
|
||||
menuitem_t EXTRAS_ReplayHut[] =
|
||||
{
|
||||
{IT_KEYHANDLER|IT_NOTHING, "", "", // Dummy menuitem for the replay list
|
||||
NULL, M_HandleReplayHutList, 0, 0},
|
||||
|
||||
{IT_NOTHING, "", "", // Dummy for handling wrapping to the top of the menu..
|
||||
NULL, NULL, 0, 0},
|
||||
};
|
||||
|
||||
menu_t EXTRAS_ReplayHutDef =
|
||||
{
|
||||
sizeof (EXTRAS_ReplayHut)/sizeof (menuitem_t),
|
||||
&EXTRAS_MainDef,
|
||||
0,
|
||||
EXTRAS_ReplayHut,
|
||||
30, 80,
|
||||
0, 0,
|
||||
0, 0,
|
||||
M_DrawReplayHut,
|
||||
NULL,
|
||||
M_QuitReplayHut,
|
||||
NULL
|
||||
};
|
||||
|
||||
menuitem_t EXTRAS_ReplayStart[] =
|
||||
{
|
||||
{IT_CALL |IT_STRING, "Load Addons and Watch", NULL,
|
||||
NULL, M_HutStartReplay, 0, 0},
|
||||
|
||||
{IT_CALL |IT_STRING, "Load Without Addons", NULL,
|
||||
NULL, M_HutStartReplay, 10, 0},
|
||||
|
||||
{IT_CALL |IT_STRING, "Watch Replay", NULL,
|
||||
NULL, M_HutStartReplay, 10, 0},
|
||||
|
||||
{IT_SUBMENU |IT_STRING, "Go Back", NULL,
|
||||
NULL, &EXTRAS_ReplayHutDef, 30, 0},
|
||||
};
|
||||
|
||||
|
||||
menu_t EXTRAS_ReplayStartDef =
|
||||
{
|
||||
sizeof (EXTRAS_ReplayStart)/sizeof (menuitem_t),
|
||||
&EXTRAS_ReplayHutDef,
|
||||
0,
|
||||
EXTRAS_ReplayStart,
|
||||
27, 80,
|
||||
0, 0,
|
||||
0, 0,
|
||||
M_DrawReplayStartMenu,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
// -------------------
|
||||
// In-game/pause menus
|
||||
// -------------------
|
||||
|
|
|
|||
381
src/k_menudraw.c
381
src/k_menudraw.c
|
|
@ -342,7 +342,7 @@ static const char *M_CreateSecretMenuOption(const char *str)
|
|||
//
|
||||
void M_DrawGenericMenu(void)
|
||||
{
|
||||
INT32 x = 0, y = 0, w, i, cursory = 0;
|
||||
INT32 x = currentMenu->x, y = currentMenu->y, w, i, cursory = 0;
|
||||
|
||||
M_DrawMenuTooltips();
|
||||
|
||||
|
|
@ -2456,6 +2456,385 @@ void M_DrawPlaybackMenu(void)
|
|||
}
|
||||
|
||||
|
||||
// replay hut...
|
||||
// ...dear lord this is messy, but Ima be real I ain't fixing this.
|
||||
|
||||
#define SCALEDVIEWWIDTH (vid.width/vid.dupx)
|
||||
#define SCALEDVIEWHEIGHT (vid.height/vid.dupy)
|
||||
void M_DrawReplayHutReplayInfo(void)
|
||||
{
|
||||
lumpnum_t lumpnum;
|
||||
patch_t *patch;
|
||||
UINT8 *colormap;
|
||||
INT32 x, y, w, h;
|
||||
|
||||
switch (extrasmenu.demolist[dir_on[menudepthleft]].type)
|
||||
{
|
||||
case MD_NOTLOADED:
|
||||
V_DrawCenteredString(160, 40, V_SNAPTOTOP, "Loading replay information...");
|
||||
break;
|
||||
|
||||
case MD_INVALID:
|
||||
V_DrawCenteredString(160, 40, V_SNAPTOTOP|warningflags, "This replay cannot be played.");
|
||||
break;
|
||||
|
||||
case MD_SUBDIR:
|
||||
break; // Can't think of anything to draw here right now
|
||||
|
||||
case MD_OUTDATED:
|
||||
V_DrawThinString(17, 64, V_SNAPTOTOP|V_ALLOWLOWERCASE|V_TRANSLUCENT|highlightflags, "Recorded on an outdated version.");
|
||||
/* FALLTHRU */
|
||||
default:
|
||||
// Draw level stuff
|
||||
x = 15; y = 15;
|
||||
|
||||
// A 160x100 image of the level as entry MAPxxP
|
||||
//CONS_Printf("%d %s\n", extrasmenu.demolist[dir_on[menudepthleft]].map, G_BuildMapName(extrasmenu.demolist[dir_on[menudepthleft]].map));
|
||||
lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(extrasmenu.demolist[dir_on[menudepthleft]].map)));
|
||||
if (lumpnum != LUMPERROR)
|
||||
patch = W_CachePatchNum(lumpnum, PU_CACHE);
|
||||
else
|
||||
patch = W_CachePatchName("M_NOLVL", PU_CACHE);
|
||||
|
||||
if (!(extrasmenu.demolist[dir_on[menudepthleft]].kartspeed & DF_ENCORE))
|
||||
V_DrawSmallScaledPatch(x, y, V_SNAPTOTOP, patch);
|
||||
else
|
||||
{
|
||||
w = SHORT(patch->width);
|
||||
h = SHORT(patch->height);
|
||||
V_DrawSmallScaledPatch(x+(w>>1), y, V_SNAPTOTOP|V_FLIP, patch);
|
||||
|
||||
{
|
||||
static angle_t rubyfloattime = 0;
|
||||
const fixed_t rubyheight = FINESINE(rubyfloattime>>ANGLETOFINESHIFT);
|
||||
V_DrawFixedPatch((x+(w>>2))<<FRACBITS, ((y+(h>>2))<<FRACBITS) - (rubyheight<<1), FRACUNIT, V_SNAPTOTOP, W_CachePatchName("RUBYICON", PU_CACHE), NULL);
|
||||
rubyfloattime += (ANGLE_MAX/NEWTICRATE);
|
||||
}
|
||||
}
|
||||
|
||||
x += 85;
|
||||
|
||||
if (mapheaderinfo[extrasmenu.demolist[dir_on[menudepthleft]].map-1])
|
||||
V_DrawString(x, y, V_SNAPTOTOP, G_BuildMapTitle(extrasmenu.demolist[dir_on[menudepthleft]].map));
|
||||
else
|
||||
V_DrawString(x, y, V_SNAPTOTOP|V_ALLOWLOWERCASE|V_TRANSLUCENT, "Level is not loaded.");
|
||||
|
||||
if (extrasmenu.demolist[dir_on[menudepthleft]].numlaps)
|
||||
V_DrawThinString(x, y+9, V_SNAPTOTOP|V_ALLOWLOWERCASE, va("(%d laps)", extrasmenu.demolist[dir_on[menudepthleft]].numlaps));
|
||||
|
||||
V_DrawString(x, y+20, V_SNAPTOTOP|V_ALLOWLOWERCASE, extrasmenu.demolist[dir_on[menudepthleft]].gametype == GT_RACE ?
|
||||
va("Race (%s speed)", kartspeed_cons_t[(extrasmenu.demolist[dir_on[menudepthleft]].kartspeed & ~DF_ENCORE) + 1].strvalue) :
|
||||
"Battle Mode");
|
||||
|
||||
if (!extrasmenu.demolist[dir_on[menudepthleft]].standings[0].ranking)
|
||||
{
|
||||
// No standings were loaded!
|
||||
V_DrawString(x, y+39, V_SNAPTOTOP|V_ALLOWLOWERCASE|V_TRANSLUCENT, "No standings available.");
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
V_DrawThinString(x, y+29, V_SNAPTOTOP|highlightflags, "WINNER");
|
||||
V_DrawString(x+38, y+30, V_SNAPTOTOP|V_ALLOWLOWERCASE, extrasmenu.demolist[dir_on[menudepthleft]].standings[0].name);
|
||||
|
||||
if (extrasmenu.demolist[dir_on[menudepthleft]].gametype == GT_RACE)
|
||||
{
|
||||
V_DrawThinString(x, y+39, V_SNAPTOTOP|highlightflags, "TIME");
|
||||
V_DrawRightAlignedString(x+84, y+40, V_SNAPTOTOP, va("%d'%02d\"%02d",
|
||||
G_TicsToMinutes(extrasmenu.demolist[dir_on[menudepthleft]].standings[0].timeorscore, true),
|
||||
G_TicsToSeconds(extrasmenu.demolist[dir_on[menudepthleft]].standings[0].timeorscore),
|
||||
G_TicsToCentiseconds(extrasmenu.demolist[dir_on[menudepthleft]].standings[0].timeorscore)
|
||||
));
|
||||
}
|
||||
else
|
||||
{
|
||||
V_DrawThinString(x, y+39, V_SNAPTOTOP|highlightflags, "SCORE");
|
||||
V_DrawString(x+32, y+40, V_SNAPTOTOP, va("%d", extrasmenu.demolist[dir_on[menudepthleft]].standings[0].timeorscore));
|
||||
}
|
||||
|
||||
// Character face!
|
||||
|
||||
// Lat: 08/06/2020: For some reason missing skins have their value set to 255 (don't even ask me why I didn't write this)
|
||||
// and for an even STRANGER reason this passes the first check below, so we're going to make sure that the skin here ISN'T 255 before we do anything stupid.
|
||||
|
||||
if (extrasmenu.demolist[dir_on[menudepthleft]].standings[0].skin != 0xFF)
|
||||
{
|
||||
patch = faceprefix[extrasmenu.demolist[dir_on[menudepthleft]].standings[0].skin][FACE_WANTED];
|
||||
colormap = R_GetTranslationColormap(
|
||||
extrasmenu.demolist[dir_on[menudepthleft]].standings[0].skin,
|
||||
extrasmenu.demolist[dir_on[menudepthleft]].standings[0].color,
|
||||
GTC_MENUCACHE);
|
||||
}
|
||||
else
|
||||
{
|
||||
patch = W_CachePatchName("M_NOWANT", PU_CACHE);
|
||||
colormap = R_GetTranslationColormap(
|
||||
TC_RAINBOW,
|
||||
extrasmenu.demolist[dir_on[menudepthleft]].standings[0].color,
|
||||
GTC_MENUCACHE);
|
||||
}
|
||||
|
||||
V_DrawMappedPatch(BASEVIDWIDTH-15 - SHORT(patch->width), y+20, V_SNAPTOTOP, patch, colormap);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void M_DrawReplayHut(void)
|
||||
{
|
||||
INT32 x, y, cursory = 0;
|
||||
INT16 i;
|
||||
INT16 replaylistitem = currentMenu->numitems-2;
|
||||
boolean processed_one_this_frame = false;
|
||||
|
||||
static UINT16 replayhutmenuy = 0;
|
||||
|
||||
M_DrawEggaChannel();
|
||||
|
||||
// Draw menu choices
|
||||
x = currentMenu->x;
|
||||
y = currentMenu->y;
|
||||
|
||||
if (itemOn > replaylistitem)
|
||||
{
|
||||
itemOn = replaylistitem;
|
||||
dir_on[menudepthleft] = sizedirmenu-1;
|
||||
extrasmenu.replayScrollTitle = 0; extrasmenu.replayScrollDelay = TICRATE; extrasmenu.replayScrollDir = 1;
|
||||
}
|
||||
else if (itemOn < replaylistitem)
|
||||
{
|
||||
dir_on[menudepthleft] = 0;
|
||||
extrasmenu.replayScrollTitle = 0; extrasmenu.replayScrollDelay = TICRATE; extrasmenu.replayScrollDir = 1;
|
||||
}
|
||||
|
||||
if (itemOn == replaylistitem)
|
||||
{
|
||||
INT32 maxy;
|
||||
// Scroll menu items if needed
|
||||
cursory = y + currentMenu->menuitems[replaylistitem].mvar1 + dir_on[menudepthleft]*10;
|
||||
maxy = y + currentMenu->menuitems[replaylistitem].mvar1 + sizedirmenu*10;
|
||||
|
||||
if (cursory > maxy - 20)
|
||||
cursory = maxy - 20;
|
||||
|
||||
if (cursory - replayhutmenuy > SCALEDVIEWHEIGHT-50)
|
||||
replayhutmenuy += (cursory-SCALEDVIEWHEIGHT-replayhutmenuy + 51)/2;
|
||||
else if (cursory - replayhutmenuy < 110)
|
||||
replayhutmenuy += (max(0, cursory-110)-replayhutmenuy - 1)/2;
|
||||
}
|
||||
else
|
||||
replayhutmenuy /= 2;
|
||||
|
||||
y -= replayhutmenuy;
|
||||
|
||||
// Draw static menu items
|
||||
for (i = 0; i < replaylistitem; i++)
|
||||
{
|
||||
INT32 localy = y + currentMenu->menuitems[i].mvar1;
|
||||
|
||||
if (localy < 65)
|
||||
continue;
|
||||
|
||||
if (i == itemOn)
|
||||
cursory = localy;
|
||||
|
||||
if ((currentMenu->menuitems[i].status & IT_DISPLAY)==IT_STRING)
|
||||
V_DrawString(x, localy, V_SNAPTOTOP|V_SNAPTOLEFT, currentMenu->menuitems[i].text);
|
||||
else
|
||||
V_DrawString(x, localy, V_SNAPTOTOP|V_SNAPTOLEFT|highlightflags, currentMenu->menuitems[i].text);
|
||||
}
|
||||
|
||||
y += currentMenu->menuitems[replaylistitem].mvar1;
|
||||
|
||||
for (i = 0; i < (INT16)sizedirmenu; i++)
|
||||
{
|
||||
INT32 localy = y+i*10;
|
||||
INT32 localx = x;
|
||||
|
||||
if (localy < 65)
|
||||
continue;
|
||||
if (localy >= SCALEDVIEWHEIGHT)
|
||||
break;
|
||||
|
||||
if (extrasmenu.demolist[i].type == MD_NOTLOADED && !processed_one_this_frame)
|
||||
{
|
||||
processed_one_this_frame = true;
|
||||
G_LoadDemoInfo(&extrasmenu.demolist[i]);
|
||||
}
|
||||
|
||||
if (extrasmenu.demolist[i].type == MD_SUBDIR)
|
||||
{
|
||||
localx += 8;
|
||||
V_DrawScaledPatch(x - 4, localy, V_SNAPTOTOP|V_SNAPTOLEFT, W_CachePatchName(dirmenu[i][DIR_TYPE] == EXT_UP ? "M_RBACK" : "M_RFLDR", PU_CACHE));
|
||||
}
|
||||
|
||||
if (itemOn == replaylistitem && i == (INT16)dir_on[menudepthleft])
|
||||
{
|
||||
cursory = localy;
|
||||
|
||||
if (extrasmenu.replayScrollDelay)
|
||||
extrasmenu.replayScrollDelay--;
|
||||
else if (extrasmenu.replayScrollDir > 0)
|
||||
{
|
||||
if (extrasmenu.replayScrollTitle < (V_StringWidth(extrasmenu.demolist[i].title, 0) - (SCALEDVIEWWIDTH - (x<<1)))<<1)
|
||||
extrasmenu.replayScrollTitle++;
|
||||
else
|
||||
{
|
||||
extrasmenu.replayScrollDelay = TICRATE;
|
||||
extrasmenu.replayScrollDir = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (extrasmenu.replayScrollTitle > 0)
|
||||
extrasmenu.replayScrollTitle--;
|
||||
else
|
||||
{
|
||||
extrasmenu.replayScrollDelay = TICRATE;
|
||||
extrasmenu.replayScrollDir = 1;
|
||||
}
|
||||
}
|
||||
|
||||
V_DrawString(localx - (extrasmenu.replayScrollTitle>>1), localy, V_SNAPTOTOP|V_SNAPTOLEFT|highlightflags|V_ALLOWLOWERCASE, extrasmenu.demolist[i].title);
|
||||
}
|
||||
else
|
||||
V_DrawString(localx, localy, V_SNAPTOTOP|V_SNAPTOLEFT|V_ALLOWLOWERCASE, extrasmenu.demolist[i].title);
|
||||
}
|
||||
|
||||
// Draw scrollbar
|
||||
y = sizedirmenu*10 + currentMenu->menuitems[replaylistitem].mvar1 + 30;
|
||||
if (y > SCALEDVIEWHEIGHT-80)
|
||||
{
|
||||
V_DrawFill(BASEVIDWIDTH-4, 75, 4, SCALEDVIEWHEIGHT-80, V_SNAPTOTOP|V_SNAPTORIGHT|159);
|
||||
V_DrawFill(BASEVIDWIDTH-3, 76 + (SCALEDVIEWHEIGHT-80) * replayhutmenuy / y, 2, (((SCALEDVIEWHEIGHT-80) * (SCALEDVIEWHEIGHT-80))-1) / y - 1, V_SNAPTOTOP|V_SNAPTORIGHT|149);
|
||||
}
|
||||
|
||||
// Draw the cursor
|
||||
V_DrawScaledPatch(currentMenu->x - 24, cursory, V_SNAPTOTOP|V_SNAPTOLEFT,
|
||||
W_CachePatchName("M_CURSOR", PU_CACHE));
|
||||
V_DrawString(currentMenu->x, cursory, V_SNAPTOTOP|V_SNAPTOLEFT|highlightflags, currentMenu->menuitems[itemOn].text);
|
||||
|
||||
// Now draw some replay info!
|
||||
V_DrawFill(10, 10, 300, 60, V_SNAPTOTOP|159);
|
||||
|
||||
if (itemOn == replaylistitem)
|
||||
{
|
||||
M_DrawReplayHutReplayInfo();
|
||||
}
|
||||
}
|
||||
|
||||
void M_DrawReplayStartMenu(void)
|
||||
{
|
||||
const char *warning;
|
||||
UINT8 i;
|
||||
|
||||
M_DrawEggaChannel();
|
||||
M_DrawGenericMenu();
|
||||
|
||||
#define STARTY 62-(extrasmenu.replayScrollTitle>>1)
|
||||
// Draw rankings beyond first
|
||||
for (i = 1; i < MAXPLAYERS && extrasmenu.demolist[dir_on[menudepthleft]].standings[i].ranking; i++)
|
||||
{
|
||||
patch_t *patch;
|
||||
UINT8 *colormap;
|
||||
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH-100, STARTY + i*20, V_SNAPTOTOP|highlightflags, va("%2d", extrasmenu.demolist[dir_on[menudepthleft]].standings[i].ranking));
|
||||
V_DrawThinString(BASEVIDWIDTH-96, STARTY + i*20, V_SNAPTOTOP|V_ALLOWLOWERCASE, extrasmenu.demolist[dir_on[menudepthleft]].standings[i].name);
|
||||
|
||||
if (extrasmenu.demolist[dir_on[menudepthleft]].standings[i].timeorscore == UINT32_MAX-1)
|
||||
V_DrawThinString(BASEVIDWIDTH-92, STARTY + i*20 + 9, V_SNAPTOTOP, "NO CONTEST");
|
||||
else if (extrasmenu.demolist[dir_on[menudepthleft]].gametype == GT_RACE)
|
||||
V_DrawRightAlignedString(BASEVIDWIDTH-40, STARTY + i*20 + 9, V_SNAPTOTOP, va("%d'%02d\"%02d",
|
||||
G_TicsToMinutes(extrasmenu.demolist[dir_on[menudepthleft]].standings[i].timeorscore, true),
|
||||
G_TicsToSeconds(extrasmenu.demolist[dir_on[menudepthleft]].standings[i].timeorscore),
|
||||
G_TicsToCentiseconds(extrasmenu.demolist[dir_on[menudepthleft]].standings[i].timeorscore)
|
||||
));
|
||||
else
|
||||
V_DrawString(BASEVIDWIDTH-92, STARTY + i*20 + 9, V_SNAPTOTOP, va("%d", extrasmenu.demolist[dir_on[menudepthleft]].standings[i].timeorscore));
|
||||
|
||||
// Character face!
|
||||
|
||||
// Lat: 08/06/2020: For some reason missing skins have their value set to 255 (don't even ask me why I didn't write this)
|
||||
// and for an even STRANGER reason this passes the first check below, so we're going to make sure that the skin here ISN'T 255 before we do anything stupid.
|
||||
|
||||
if (extrasmenu.demolist[dir_on[menudepthleft]].standings[i].skin != 0xFF)
|
||||
{
|
||||
patch = faceprefix[extrasmenu.demolist[dir_on[menudepthleft]].standings[i].skin][FACE_RANK];
|
||||
colormap = R_GetTranslationColormap(
|
||||
extrasmenu.demolist[dir_on[menudepthleft]].standings[i].skin,
|
||||
extrasmenu.demolist[dir_on[menudepthleft]].standings[i].color,
|
||||
GTC_MENUCACHE);
|
||||
}
|
||||
else
|
||||
{
|
||||
patch = W_CachePatchName("M_NORANK", PU_CACHE);
|
||||
colormap = R_GetTranslationColormap(
|
||||
TC_RAINBOW,
|
||||
extrasmenu.demolist[dir_on[menudepthleft]].standings[i].color,
|
||||
GTC_MENUCACHE);
|
||||
}
|
||||
|
||||
V_DrawMappedPatch(BASEVIDWIDTH-5 - SHORT(patch->width), STARTY + i*20, V_SNAPTOTOP, patch, colormap);
|
||||
}
|
||||
#undef STARTY
|
||||
|
||||
// Handle scrolling rankings
|
||||
if (extrasmenu.replayScrollDelay)
|
||||
extrasmenu.replayScrollDelay--;
|
||||
else if (extrasmenu.replayScrollDir > 0)
|
||||
{
|
||||
if (extrasmenu.replayScrollTitle < (i*20 - SCALEDVIEWHEIGHT + 100)<<1)
|
||||
extrasmenu.replayScrollTitle++;
|
||||
else
|
||||
{
|
||||
extrasmenu.replayScrollDelay = TICRATE;
|
||||
extrasmenu.replayScrollDir = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (extrasmenu.replayScrollTitle > 0)
|
||||
extrasmenu.replayScrollTitle--;
|
||||
else
|
||||
{
|
||||
extrasmenu.replayScrollDelay = TICRATE;
|
||||
extrasmenu.replayScrollDir = 1;
|
||||
}
|
||||
}
|
||||
|
||||
V_DrawFill(10, 10, 300, 60, V_SNAPTOTOP|159);
|
||||
M_DrawReplayHutReplayInfo();
|
||||
|
||||
V_DrawString(10, 72, V_SNAPTOTOP|highlightflags|V_ALLOWLOWERCASE, extrasmenu.demolist[dir_on[menudepthleft]].title);
|
||||
|
||||
// Draw a warning prompt if needed
|
||||
switch (extrasmenu.demolist[dir_on[menudepthleft]].addonstatus)
|
||||
{
|
||||
case DFILE_ERROR_CANNOTLOAD:
|
||||
warning = "Some addons in this replay cannot be loaded.\nYou can watch anyway, but desyncs may occur.";
|
||||
break;
|
||||
|
||||
case DFILE_ERROR_NOTLOADED:
|
||||
case DFILE_ERROR_INCOMPLETEOUTOFORDER:
|
||||
warning = "Loading addons will mark your game as modified, and Record Attack may be unavailable.\nYou can watch without loading addons, but desyncs may occur.";
|
||||
break;
|
||||
|
||||
case DFILE_ERROR_EXTRAFILES:
|
||||
warning = "You have addons loaded that were not present in this replay.\nYou can watch anyway, but desyncs may occur.";
|
||||
break;
|
||||
|
||||
case DFILE_ERROR_OUTOFORDER:
|
||||
warning = "You have this replay's addons loaded, but they are out of order.\nYou can watch anyway, but desyncs may occur.";
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
V_DrawSmallString(4, BASEVIDHEIGHT-14, V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, warning);
|
||||
}
|
||||
|
||||
// Draw misc menus:
|
||||
|
||||
// Addons (this is merely copypasted, original code by toaster)
|
||||
|
|
|
|||
211
src/k_menufunc.c
211
src/k_menufunc.c
|
|
@ -3783,12 +3783,223 @@ void M_PlaybackQuit(INT32 choice)
|
|||
D_StartTitle();
|
||||
}
|
||||
|
||||
void M_PrepReplayList(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (extrasmenu.demolist)
|
||||
Z_Free(extrasmenu.demolist);
|
||||
|
||||
extrasmenu.demolist = Z_Calloc(sizeof(menudemo_t) * sizedirmenu, PU_STATIC, NULL);
|
||||
|
||||
for (i = 0; i < sizedirmenu; i++)
|
||||
{
|
||||
if (dirmenu[i][DIR_TYPE] == EXT_UP)
|
||||
{
|
||||
extrasmenu.demolist[i].type = MD_SUBDIR;
|
||||
sprintf(extrasmenu.demolist[i].title, "UP");
|
||||
}
|
||||
else if (dirmenu[i][DIR_TYPE] == EXT_FOLDER)
|
||||
{
|
||||
extrasmenu.demolist[i].type = MD_SUBDIR;
|
||||
strncpy(extrasmenu.demolist[i].title, dirmenu[i] + DIR_STRING, 64);
|
||||
}
|
||||
else
|
||||
{
|
||||
extrasmenu.demolist[i].type = MD_NOTLOADED;
|
||||
snprintf(extrasmenu.demolist[i].filepath, 255, "%s%s", menupath, dirmenu[i] + DIR_STRING);
|
||||
sprintf(extrasmenu.demolist[i].title, ".....");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void M_ReplayHut(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
|
||||
extrasmenu.replayScrollTitle = 0;
|
||||
extrasmenu.replayScrollDelay = TICRATE;
|
||||
extrasmenu.replayScrollDir = 1;
|
||||
|
||||
if (!demo.inreplayhut)
|
||||
{
|
||||
snprintf(menupath, 1024, "%s"PATHSEP"media"PATHSEP"replay"PATHSEP"online"PATHSEP, srb2home);
|
||||
menupathindex[(menudepthleft = menudepth-1)] = strlen(menupath);
|
||||
}
|
||||
if (!preparefilemenu(false, true))
|
||||
{
|
||||
M_StartMessage("No replays found.\n\n(Press a key)\n", NULL, MM_NOTHING);
|
||||
return;
|
||||
}
|
||||
else if (!demo.inreplayhut)
|
||||
dir_on[menudepthleft] = 0;
|
||||
demo.inreplayhut = true;
|
||||
|
||||
extrasmenu.replayScrollTitle = 0; extrasmenu.replayScrollDelay = TICRATE; extrasmenu.replayScrollDir = 1;
|
||||
|
||||
M_PrepReplayList();
|
||||
|
||||
menuactive = true;
|
||||
M_SetupNextMenu(&EXTRAS_ReplayHutDef, false);
|
||||
//G_SetGamestate(GS_TIMEATTACK);
|
||||
//titlemapinaction = TITLEMAP_OFF; // Nope don't give us HOMs please
|
||||
|
||||
demo.rewinding = false;
|
||||
CL_ClearRewinds();
|
||||
|
||||
//S_ChangeMusicInternal("replst", true);
|
||||
}
|
||||
|
||||
// key handler
|
||||
void M_HandleReplayHutList(INT32 choice)
|
||||
{
|
||||
switch (choice)
|
||||
{
|
||||
case KEY_UPARROW:
|
||||
if (dir_on[menudepthleft])
|
||||
dir_on[menudepthleft]--;
|
||||
else
|
||||
return;
|
||||
//M_PrevOpt();
|
||||
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
extrasmenu.replayScrollTitle = 0; extrasmenu.replayScrollDelay = TICRATE; extrasmenu.replayScrollDir = 1;
|
||||
break;
|
||||
|
||||
case KEY_DOWNARROW:
|
||||
if (dir_on[menudepthleft] < sizedirmenu-1)
|
||||
dir_on[menudepthleft]++;
|
||||
else
|
||||
return;
|
||||
//itemOn = 0; // Not M_NextOpt because that would take us to the extra dummy item
|
||||
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
extrasmenu.replayScrollTitle = 0; extrasmenu.replayScrollDelay = TICRATE; extrasmenu.replayScrollDir = 1;
|
||||
break;
|
||||
|
||||
case KEY_ESCAPE:
|
||||
M_QuitReplayHut();
|
||||
break;
|
||||
|
||||
case KEY_ENTER:
|
||||
switch (dirmenu[dir_on[menudepthleft]][DIR_TYPE])
|
||||
{
|
||||
case EXT_FOLDER:
|
||||
strcpy(&menupath[menupathindex[menudepthleft]],dirmenu[dir_on[menudepthleft]]+DIR_STRING);
|
||||
if (menudepthleft)
|
||||
{
|
||||
menupathindex[--menudepthleft] = strlen(menupath);
|
||||
menupath[menupathindex[menudepthleft]] = 0;
|
||||
|
||||
if (!preparefilemenu(false, true))
|
||||
{
|
||||
S_StartSound(NULL, sfx_s224);
|
||||
M_StartMessage(va("%c%s\x80\nThis folder is empty.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), M_AddonsHeaderPath()),NULL,MM_NOTHING);
|
||||
menupath[menupathindex[++menudepthleft]] = 0;
|
||||
|
||||
if (!preparefilemenu(true, true))
|
||||
{
|
||||
M_QuitReplayHut();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
dir_on[menudepthleft] = 1;
|
||||
M_PrepReplayList();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
S_StartSound(NULL, sfx_s26d);
|
||||
M_StartMessage(va("%c%s\x80\nThis folder is too deep to navigate to!\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), M_AddonsHeaderPath()),NULL,MM_NOTHING);
|
||||
menupath[menupathindex[menudepthleft]] = 0;
|
||||
}
|
||||
break;
|
||||
case EXT_UP:
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
menupath[menupathindex[++menudepthleft]] = 0;
|
||||
if (!preparefilemenu(false, true))
|
||||
{
|
||||
M_QuitReplayHut();
|
||||
return;
|
||||
}
|
||||
M_PrepReplayList();
|
||||
break;
|
||||
default:
|
||||
// We can't just use M_SetupNextMenu because that'll run ReplayDef's quitroutine and boot us back to the title screen!
|
||||
currentMenu->lastOn = itemOn;
|
||||
currentMenu = &EXTRAS_ReplayStartDef;
|
||||
|
||||
extrasmenu.replayScrollTitle = 0; extrasmenu.replayScrollDelay = TICRATE; extrasmenu.replayScrollDir = 1;
|
||||
|
||||
switch (extrasmenu.demolist[dir_on[menudepthleft]].addonstatus)
|
||||
{
|
||||
case DFILE_ERROR_CANNOTLOAD:
|
||||
// Only show "Watch Replay Without Addons"
|
||||
EXTRAS_ReplayStart[0].status = IT_DISABLED;
|
||||
EXTRAS_ReplayStart[1].status = IT_CALL|IT_STRING;
|
||||
//EXTRAS_ReplayStart[1].alphaKey = 0;
|
||||
EXTRAS_ReplayStart[2].status = IT_DISABLED;
|
||||
itemOn = 1;
|
||||
break;
|
||||
|
||||
case DFILE_ERROR_NOTLOADED:
|
||||
case DFILE_ERROR_INCOMPLETEOUTOFORDER:
|
||||
// Show "Load Addons and Watch Replay" and "Watch Replay Without Addons"
|
||||
EXTRAS_ReplayStart[0].status = IT_CALL|IT_STRING;
|
||||
EXTRAS_ReplayStart[1].status = IT_CALL|IT_STRING;
|
||||
//EXTRAS_ReplayStart[1].alphaKey = 10;
|
||||
EXTRAS_ReplayStart[2].status = IT_DISABLED;
|
||||
itemOn = 0;
|
||||
break;
|
||||
|
||||
case DFILE_ERROR_EXTRAFILES:
|
||||
case DFILE_ERROR_OUTOFORDER:
|
||||
default:
|
||||
// Show "Watch Replay"
|
||||
EXTRAS_ReplayStart[0].status = IT_DISABLED;
|
||||
EXTRAS_ReplayStart[1].status = IT_DISABLED;
|
||||
EXTRAS_ReplayStart[2].status = IT_CALL|IT_STRING;
|
||||
//EXTRAS_ReplayStart[2].alphaKey = 0;
|
||||
itemOn = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
boolean M_QuitReplayHut(void)
|
||||
{
|
||||
// D_StartTitle does its own wipe, since GS_TIMEATTACK is now a complete gamestate.
|
||||
menuactive = false;
|
||||
D_StartTitle();
|
||||
|
||||
if (extrasmenu.demolist)
|
||||
Z_Free(extrasmenu.demolist);
|
||||
extrasmenu.demolist = NULL;
|
||||
|
||||
demo.inreplayhut = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void M_HutStartReplay(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
|
||||
M_ClearMenus(false);
|
||||
demo.loadfiles = (itemOn == 0);
|
||||
demo.ignorefiles = (itemOn != 0);
|
||||
|
||||
G_DoPlayDemo(extrasmenu.demolist[dir_on[menudepthleft]].filepath);
|
||||
}
|
||||
|
||||
|
||||
static void Splitplayers_OnChange(void)
|
||||
{
|
||||
#if 0
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue