diff --git a/src/g_game.c b/src/g_game.c index 09a3db52d..94f8bd8d1 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -6346,12 +6346,8 @@ static void G_SkipDemoExtraFiles(UINT8 **pp) } // G_CheckDemoExtraFiles: checks if our loaded WAD list matches the demo's. -#define DFILE_ERROR_NOTLOADED 0x01 // Files are not loaded, but can be without a restart. -#define DFILE_ERROR_OUTOFORDER 0x02 // Files are loaded, but out of order. -#define DFILE_ERROR_INCOMPLETEOUTOFORDER 0x03 // Some files are loaded out of order, but others are not. -#define DFILE_ERROR_CANNOTLOAD 0x04 // Files are missing and cannot be loaded. -#define DFILE_ERROR_EXTRAFILES 0x05 // Extra files outside of the replay's file list are loaded. -static UINT8 G_CheckDemoExtraFiles(UINT8 **pp) +// Enabling quick prevents filesystem checks to see if needed files are available to load. +static UINT8 G_CheckDemoExtraFiles(UINT8 **pp, boolean quick) { UINT8 totalfiles, filesloaded, nmusfilecount; char filename[MAX_WADPATH]; @@ -6405,7 +6401,7 @@ static UINT8 G_CheckDemoExtraFiles(UINT8 **pp) if (numwadfiles >= MAX_WADFILES) error = DFILE_ERROR_CANNOTLOAD; - else if (findfile(filename, md5sum, false) != FS_FOUND) + else if (!quick && findfile(filename, md5sum, false) != FS_FOUND) error = DFILE_ERROR_CANNOTLOAD; else if (error < DFILE_ERROR_INCOMPLETEOUTOFORDER) error |= DFILE_ERROR_NOTLOADED; @@ -6633,9 +6629,9 @@ void G_LoadDemoInfo(menudemo_t *pdemo) Z_Free(infobuffer); return; } - demo_p += 4; // "PLAY" + info_p += 4; // "PLAY" pdemo->map = READINT16(info_p); - demo_p += 16; // mapmd5 + info_p += 16; // mapmd5 pdemoflags = READUINT8(info_p); @@ -6649,8 +6645,8 @@ void G_LoadDemoInfo(menudemo_t *pdemo) pdemo->gametype = READUINT8(info_p); - G_SkipDemoExtraFiles(&info_p); //@TODO see if this information is useful for display? - demo_p += 4; // RNG seed + pdemo->addonstatus = G_CheckDemoExtraFiles(&info_p, true); + info_p += 4; // RNG seed // Pared down version of CV_LoadNetVars to find the kart speed cvarcount = READUINT16(info_p); @@ -6666,9 +6662,9 @@ void G_LoadDemoInfo(menudemo_t *pdemo) if (netid == cv_kartspeed.netid) { - for (cvarcount = 0; kartspeed_cons_t[cvarcount].value; cvarcount++) + for (cvarcount = 0; kartspeed_cons_t[cvarcount].strvalue; cvarcount++) { - if (!strcasecmp(kartspeed_cons_t[cvarcount].strvalue, svalue)) + if (!stricmp(kartspeed_cons_t[cvarcount].strvalue, svalue)) { pdemo->kartspeed = kartspeed_cons_t[cvarcount].value; break; @@ -6682,6 +6678,12 @@ void G_LoadDemoInfo(menudemo_t *pdemo) if (pdemoflags & DF_ENCORE) pdemo->kartspeed |= DF_ENCORE; + // Temporary info until this is actually present in replays. + sprintf(pdemo->winnername, "transrights420"); + pdemo->winnerskin = 1; + pdemo->winnercolor = SKINCOLOR_MOONSLAM; + pdemo->winnertime = 6666; + // I think that's everything we need? free(infobuffer); } @@ -6845,7 +6847,7 @@ void G_DoPlayDemo(char *defdemoname) G_SkipDemoExtraFiles(&demo_p); else { - UINT8 error = G_CheckDemoExtraFiles(&demo_p); + UINT8 error = G_CheckDemoExtraFiles(&demo_p, false); if (error) { diff --git a/src/g_game.h b/src/g_game.h index 5b07d053c..af85bd029 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -75,8 +75,13 @@ typedef struct menudemo_s { char title[65]; // Null-terminated for string prints UINT16 map; + UINT8 addonstatus; // What do we need to do addon-wise to play this demo? UINT8 gametype; UINT8 kartspeed; // Add OR DF_ENCORE for encore mode, idk + + char winnername[17]; + UINT8 winnerskin, winnercolor; + UINT32 winnertime; } menudemo_t; @@ -239,6 +244,13 @@ typedef struct demoghost { } demoghost; extern demoghost *ghosts; +// G_CheckDemoExtraFiles: checks if our loaded WAD list matches the demo's. +#define DFILE_ERROR_NOTLOADED 0x01 // Files are not loaded, but can be without a restart. +#define DFILE_ERROR_OUTOFORDER 0x02 // Files are loaded, but out of order. +#define DFILE_ERROR_INCOMPLETEOUTOFORDER 0x03 // Some files are loaded out of order, but others are not. +#define DFILE_ERROR_CANNOTLOAD 0x04 // Files are missing and cannot be loaded. +#define DFILE_ERROR_EXTRAFILES 0x05 // Extra files outside of the replay's file list are loaded. + void G_DoPlayDemo(char *defdemoname); void G_TimeDemo(const char *name); void G_AddGhost(char *defdemoname); diff --git a/src/m_menu.c b/src/m_menu.c index a5f51f2a9..db31a4a54 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5012,7 +5012,10 @@ static void M_HandleAddons(INT32 choice) // ---- REPLAY HUT ----- menudemo_t *demolist; +#define DF_ENCORE 0x40 static INT16 replayOn = 0; +static INT16 replayScrollTitle = 0; +static INT8 replayScrollDelay = TICRATE, replayScrollDir = 1; static void PrepReplayList(void) { @@ -5073,6 +5076,7 @@ static void M_HandleReplayHutList(INT32 choice) M_PrevOpt(); S_StartSound(NULL, sfx_menu1); + replayScrollTitle = 0; replayScrollDelay = TICRATE; replayScrollDir = 1; break; case KEY_DOWNARROW: @@ -5082,6 +5086,7 @@ static void M_HandleReplayHutList(INT32 choice) itemOn = 0; // Not M_NextOpt because that would take us to the extra dummy item S_StartSound(NULL, sfx_menu1); + replayScrollTitle = 0; replayScrollDelay = TICRATE; replayScrollDir = 1; break; } } @@ -5096,7 +5101,6 @@ static void M_DrawReplayHut(void) static UINT16 replayhutmenuy = 0; V_DrawPatchFill(W_CachePatchName("SRB2BACK", PU_CACHE)); - M_DrawMenuTitle(); // Draw menu choices x = currentMenu->x; @@ -5106,10 +5110,12 @@ static void M_DrawReplayHut(void) { itemOn = replaylistitem; replayOn = sizedirmenu-1; + replayScrollTitle = 0; replayScrollDelay = TICRATE; replayScrollDir = 1; } else if (itemOn < replaylistitem) { replayOn = 0; + replayScrollTitle = 0; replayScrollDelay = TICRATE; replayScrollDir = 1; } if (itemOn == replaylistitem) @@ -5123,9 +5129,9 @@ static void M_DrawReplayHut(void) cursory = maxy - 20; if (cursory - replayhutmenuy > 150) - replayhutmenuy += (cursory-150-replayhutmenuy)/2; + replayhutmenuy += (cursory-150-replayhutmenuy + 1)/2; else if (cursory - replayhutmenuy < 110) - replayhutmenuy += (max(0, cursory-110)-replayhutmenuy)/2; + replayhutmenuy += (max(0, cursory-110)-replayhutmenuy - 1)/2; } else replayhutmenuy /= 2; @@ -5149,7 +5155,13 @@ static void M_DrawReplayHut(void) for (i = 0; i < (INT16)sizedirmenu; i++) { INT32 localy = y+i*10; - if (localy >= 0 && localy < 200 && demolist[i].type == MD_NOTLOADED && !processed_one_this_frame) + + if (localy < 65) + continue; + if (localy >= 200) + break; + + if (demolist[i].type == MD_NOTLOADED && !processed_one_this_frame) { processed_one_this_frame = true; G_LoadDemoInfo(&demolist[i]); @@ -5158,7 +5170,31 @@ static void M_DrawReplayHut(void) if (itemOn == replaylistitem && i == replayOn) { cursory = localy; - V_DrawString(x, localy, highlightflags|V_ALLOWLOWERCASE, demolist[i].title); + + if (replayScrollDelay) + replayScrollDelay--; + else if (replayScrollDir > 0) + { + if (replayScrollTitle < (V_StringWidth(demolist[i].title, 0) - (BASEVIDWIDTH - (x<<1)))<<1) + replayScrollTitle++; + else + { + replayScrollDelay = TICRATE; + replayScrollDir = -1; + } + } + else + { + if (replayScrollTitle > 0) + replayScrollTitle--; + else + { + replayScrollDelay = TICRATE; + replayScrollDir = 1; + } + } + + V_DrawString(x - (replayScrollTitle>>1), localy, highlightflags|V_ALLOWLOWERCASE, demolist[i].title); } else V_DrawString(x, localy, V_ALLOWLOWERCASE, demolist[i].title); @@ -5168,6 +5204,92 @@ static void M_DrawReplayHut(void) V_DrawScaledPatch(currentMenu->x - 24, cursory, 0, W_CachePatchName("M_CURSOR", PU_CACHE)); V_DrawString(currentMenu->x, cursory, highlightflags, currentMenu->menuitems[itemOn].text); + + // Now draw some replay info! + V_DrawFill(10, 10, 300, 60, 239); + + if (itemOn == replaylistitem) + { + switch (demolist[replayOn].type) + { + case MD_NOTLOADED: + V_DrawCenteredString(160, 40, 0, "Loading replay information..."); + break; + + case MD_INVALID: + V_DrawCenteredString(160, 40, 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, 60, V_ALLOWLOWERCASE|V_TRANSLUCENT|highlightflags, "Recorded on an outdated version."); + /*fallthru*/ + default: + { // Draw level stuff + lumpnum_t lumpnum; + patch_t *PictureOfLevel; + INT32 w, h; + x = 15; y = 15; + //INT32 x, y, w, i, oldval, trans, dupadjust = ((vid.width/vid.dupx) - BASEVIDWIDTH)>>1; + + // A 160x100 image of the level as entry MAPxxP + CONS_Printf("%d %s\n", demolist[replayOn].map, G_BuildMapName(demolist[replayOn].map)); + lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(demolist[replayOn].map))); + if (lumpnum != LUMPERROR) + PictureOfLevel = W_CachePatchNum(lumpnum, PU_CACHE); + else + PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE); + + if (!(demolist[replayOn].kartspeed & DF_ENCORE)) + V_DrawSmallScaledPatch(x, y, 0, PictureOfLevel); + else + { + w = SHORT(PictureOfLevel->width); + h = SHORT(PictureOfLevel->height); + V_DrawFixedPatch((x+w)<>ANGLETOFINESHIFT); + V_DrawFixedPatch((x+w/2)<width), y+20, 0, facewantprefix[demolist[replayOn].winnerskin], colormap); + } + } + + break; + } + } } static void M_PandorasBox(INT32 choice)