From 28a493dbc30fbdd326ffa608a3b39f27f9b033fb Mon Sep 17 00:00:00 2001 From: NepDisk Date: Sat, 12 Apr 2025 10:45:33 -0400 Subject: [PATCH] Tri map records pt.3: Finalize changes --- src/deh_tables.c | 3 ++ src/doomstat.h | 93 ++++++++++++++++++++++++------------------------ src/g_game.c | 43 +++++++++++----------- src/g_game.h | 3 +- src/info/menus.h | 1 + src/m_cond.c | 2 -- src/m_menu.c | 60 +++++++++++++++++++++++++++++-- src/m_menu.h | 3 ++ 8 files changed, 133 insertions(+), 75 deletions(-) diff --git a/src/deh_tables.c b/src/deh_tables.c index d8b904ab1..0e4057847 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -632,6 +632,9 @@ struct menu_routine_s const MENU_ROUTINES[] = { { "CHOOSETIMEATTACK", &M_ChooseTimeAttack }, { "SETGUESTREPLAY", &M_SetGuestReplay }, { "REPLAYTIMEATTACK", &M_ReplayTimeAttack }, + { "SRB2KARTPRESET", &M_SRB2KartPreset }, + { "TECHPRESET", &M_TechPreset }, + { "BLANKARTPRESET", &M_BlanKartPreset }, { "HANDLESTAFFREPLAY", &M_HandleStaffReplay }, { "SETUPMULTIHANDLER", &M_SetupMultiHandler }, { "HANDLESETUPMULTIPLAYER", &M_HandleSetupMultiPlayer }, diff --git a/src/doomstat.h b/src/doomstat.h index 102dcbf7a..05369c06e 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -116,6 +116,7 @@ struct recorddata_t //UINT32 score; ///< Score when the level was finished. //UINT16 rings; ///< Rings when the level was finished. }; +#define MAXMAPRECORDS 4 // mapvisited is now a set of flags that says what we've done in the map. #define MV_VISITED (1) @@ -368,80 +369,80 @@ extern UINT16 numkartcupheaders; struct mapheader_t { // Core game information, not user-modifiable directly - char *lumpname; ///< Lump name can be really long - UINT32 lumpnamehash; ///< quickncasehash(->lumpname, MAXMAPLUMPNAME) - lumpnum_t lumpnum; ///< Lump number for the map, used by vres_GetMap + char *lumpname; ///< Lump name can be really long + UINT32 lumpnamehash; ///< quickncasehash(->lumpname, MAXMAPLUMPNAME) + lumpnum_t lumpnum; ///< Lump number for the map, used by vres_GetMap - void *thumbnailPic; ///< Lump data for the level select thumbnail. - void *minimapPic; ///< Lump data for the minimap graphic. + void *thumbnailPic; ///< Lump data for the level select thumbnail. + void *minimapPic; ///< Lump data for the minimap graphic. - UINT8 mapvisited; ///< A set of flags that says what we've done in the map. - recorddata_t *mainrecord[3]; ///< Stores best time attack data + UINT8 mapvisited; ///< A set of flags that says what we've done in the map. + recorddata_t *mainrecord[MAXMAPRECORDS]; ///< Stores best time attack data - cupheader_t *cup; ///< Cached cup + cupheader_t *cup; ///< Cached cup // Titlecard information - char lvlttl[22]; ///< Level name without "Zone". (21 character limit instead of 32, 21 characters can display on screen max anyway) - char subttl[33]; ///< Subtitle for level - char zonttl[22]; ///< "ZONE" replacement name - char actnum[3]; ///< SRB2Kart: Now a 2 character long string. + char lvlttl[22]; ///< Level name without "Zone". (21 character limit instead of 32, 21 characters can display on screen max anyway) + char subttl[33]; ///< Subtitle for level + char zonttl[22]; ///< "ZONE" replacement name + char actnum[3]; ///< SRB2Kart: Now a 2 character long string. // Selection metadata - char keywords[33]; ///< Keywords separated by space to search for. 32 characters. + char keywords[33]; ///< Keywords separated by space to search for. 32 characters. - SINT8 unlockrequired; ///< Is an unlockable required to play this level? -1 if no. - UINT8 levelselect; ///< Is this map available in the level select? If so, which map list is it available in? - UINT8 menuflags; ///< LF2_flags: options that affect record attack menus + SINT8 unlockrequired; ///< Is an unlockable required to play this level? -1 if no. + UINT8 levelselect; ///< Is this map available in the level select? If so, which map list is it available in? + UINT8 menuflags; ///< LF2_flags: options that affect record attack menus // Operational metadata - UINT16 levelflags; ///< LF_flags: merged booleans into one UINT16 for space, see below - UINT32 typeoflevel; ///< Combination of typeoflevel flags. - UINT8 numlaps; ///< Number of laps in circuit mode, unless overridden. - UINT8 lapspersection; ///< Number of laps per section in hybrid section-circuit maps. - fixed_t gravity; ///< Map-wide gravity. + UINT16 levelflags; ///< LF_flags: merged booleans into one UINT16 for space, see below + UINT32 typeoflevel; ///< Combination of typeoflevel flags. + UINT8 numlaps; ///< Number of laps in circuit mode, unless overridden. + UINT8 lapspersection; ///< Number of laps per section in hybrid section-circuit maps. + fixed_t gravity; ///< Map-wide gravity. // Music information - char musname[MAXMUSNAMES][7]; ///< Music tracks to play. First dimension is the track number, second is the music string. "" for no music. - UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore. - UINT32 muspos; ///< Music position to jump to. - UINT8 musname_size; ///< Number of music tracks defined + char musname[MAXMUSNAMES][7]; ///< Music tracks to play. First dimension is the track number, second is the music string. "" for no music. + UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore. + UINT32 muspos; ///< Music position to jump to. + UINT8 musname_size; ///< Number of music tracks defined // Sky information - UINT8 weather; ///< See preciptype_t - char skytexture[9]; ///< Sky texture to use. - INT16 skybox_scalex; ///< Skybox X axis scale. (0 = no movement, 1 = 1:1 movement, 16 = 16:1 slow movement, -4 = 1:4 fast movement, etc.) - INT16 skybox_scaley; ///< Skybox Y axis scale. - INT16 skybox_scalez; ///< Skybox Z axis scale. + UINT8 weather; ///< See preciptype_t + char skytexture[9]; ///< Sky texture to use. + INT16 skybox_scalex; ///< Skybox X axis scale. (0 = no movement, 1 = 1:1 movement, 16 = 16:1 slow movement, -4 = 1:4 fast movement, etc.) + INT16 skybox_scaley; ///< Skybox Y axis scale. + INT16 skybox_scalez; ///< Skybox Z axis scale. // Distance information - fixed_t mobj_scale; ///< Defines the size all object calculations are relative to - fixed_t default_waypoint_radius; ///< 0 is a special value for DEFAULT_WAYPOINT_RADIUS, but scaled with mobjscale + fixed_t mobj_scale; ///< Defines the size all object calculations are relative to + fixed_t default_waypoint_radius; ///< 0 is a special value for DEFAULT_WAYPOINT_RADIUS, but scaled with mobjscale // Visual information - UINT16 palette; ///< PAL lump to use on this map - UINT16 encorepal; ///< PAL for encore mode - mapheader_lighting_t lighting; ///< Wall and sprite lighting - mapheader_lighting_t lighting_encore; ///< Alternative lighting for Encore mode - boolean use_encore_lighting; ///< Whether to use separate Encore lighting + UINT16 palette; ///< PAL lump to use on this map + UINT16 encorepal; ///< PAL for encore mode + mapheader_lighting_t lighting; ///< Wall and sprite lighting + mapheader_lighting_t lighting_encore; ///< Alternative lighting for Encore mode + boolean use_encore_lighting; ///< Whether to use separate Encore lighting // Freed animal information - UINT8 numFlickies; ///< Internal. For freed flicky support. - mobjtype_t *flickies; ///< List of freeable flickies in this level. Allocated dynamically for space reasons. Be careful. + UINT8 numFlickies; ///< Internal. For freed flicky support. + mobjtype_t *flickies; ///< List of freeable flickies in this level. Allocated dynamically for space reasons. Be careful. // Script information - char runsoc[33]; ///< SOC to execute at start of level (32 character limit instead of 63) - char scriptname[33]; ///< Script to use when the map is switched to. (32 character limit instead of 191) + char runsoc[33]; ///< SOC to execute at start of level (32 character limit instead of 63) + char scriptname[33]; ///< Script to use when the map is switched to. (32 character limit instead of 191) // Cutscene information - UINT8 precutscenenum; ///< Cutscene number to play BEFORE a level starts. - UINT8 cutscenenum; ///< Cutscene number to use, 0 for none. + UINT8 precutscenenum; ///< Cutscene number to play BEFORE a level starts. + UINT8 cutscenenum; ///< Cutscene number to use, 0 for none. // Lua information - UINT8 numCustomOptions; ///< Internal. For Lua custom value support. - customoption_t *customopts; ///< Custom options. Allocated dynamically for space reasons. Be careful. + UINT8 numCustomOptions; ///< Internal. For Lua custom value support. + customoption_t *customopts; ///< Custom options. Allocated dynamically for space reasons. Be careful. // BlanKart - boolean use_walltransfer; ///< Whether to use DRRR style wall transfering or not + boolean use_walltransfer; ///< Whether to use DRRR style wall transfering or not }; diff --git a/src/g_game.c b/src/g_game.c index 00e73cf77..cbb7d4058 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -471,16 +471,14 @@ SINT8 G_RecordPresetIndex(void) if (rings && stacking && chaining && slipdash && purpledrift) return 2; - return -1; + return 3; } // Allocation for time and nights data -void G_AllocMainRecordData(INT16 i) +void G_AllocMainRecordData(INT16 i, SINT8 preset) { - SINT8 preset = G_RecordPresetIndex(); - - if (preset == -1) - return; + if (preset < 0 || preset >= MAXMAPRECORDS) + I_Error("G_AllocMainRecordData: Tried allocating invalid record index (%d)", preset); if (i > nummapheaders || !mapheaderinfo[i]) I_Error("G_AllocMainRecordData: Internal map ID %d not found (nummapheaders = %d)\n", i, nummapheaders); @@ -493,17 +491,17 @@ void G_AllocMainRecordData(INT16 i) void G_ClearRecords(void) { INT16 i; - SINT8 preset = G_RecordPresetIndex(); - - if (preset == -1) - return; + SINT8 k; for (i = 0; i < nummapheaders; ++i) { - if (mapheaderinfo[i]->mainrecord[preset]) + for (k = 0; k < MAXMAPRECORDS; k++) { - Z_Free(mapheaderinfo[i]->mainrecord[preset]); - mapheaderinfo[i]->mainrecord[preset] = NULL; + if (mapheaderinfo[i]->mainrecord[k]) + { + Z_Free(mapheaderinfo[i]->mainrecord[k]); + mapheaderinfo[i]->mainrecord[k] = NULL; + } } } } @@ -513,7 +511,7 @@ tic_t G_GetBestTime(INT16 map) { SINT8 preset = G_RecordPresetIndex(); - if (!mapheaderinfo[map] || preset == -1 || !mapheaderinfo[map]->mainrecord[preset] || mapheaderinfo[map]->mainrecord[preset]->time <= 0) + if (!mapheaderinfo[map] || !mapheaderinfo[map]->mainrecord[preset] || mapheaderinfo[map]->mainrecord[preset]->time <= 0) return (tic_t)UINT32_MAX; return mapheaderinfo[map]->mainrecord[preset]->time; @@ -547,17 +545,15 @@ boolean K_EmblemsEnabled(void) static void G_UpdateRecordReplays(void) { char *gpath; + char *gamemode = M_AppendGametypeAndModName(); char lastdemo[256], bestdemo[256]; UINT8 earnedEmblems; int parts; SINT8 preset = G_RecordPresetIndex(); - if (preset == -1) - return; - // Record new best time if (!mapheaderinfo[gamemap-1]->mainrecord[preset]) - G_AllocMainRecordData(gamemap-1); + G_AllocMainRecordData(gamemap-1, preset); if (players[consoleplayer].pflags & PF_NOCONTEST) { @@ -591,14 +587,14 @@ static void G_UpdateRecordReplays(void) parts = M_PathParts(gpath); M_MkdirEachUntil(gpath, parts - 4, parts - 1, 0755); - snprintf(lastdemo, 255, "%s-%s-last.lmp", gpath, cv_chooseskin.string); + snprintf(lastdemo, 255, "%s-%s-%s-last.lmp", gpath, cv_chooseskin.string, gamemode); if (FIL_FileExists(lastdemo)) { UINT8 *buf; size_t len = FIL_ReadFile(lastdemo, &buf); - snprintf(bestdemo, 255, "%s-%s-time-best.lmp", gpath, cv_chooseskin.string); + snprintf(bestdemo, 255, "%s-%s-%s-time-best.lmp", gpath, cv_chooseskin.string, gamemode); if (!FIL_FileExists(bestdemo) || G_CmpDemoTime(bestdemo, lastdemo) & 1) { // Better time, save this demo. if (FIL_FileExists(bestdemo)) @@ -609,7 +605,7 @@ static void G_UpdateRecordReplays(void) if (modeattacking == ATTACKING_TIME) { - snprintf(bestdemo, 255, "%s-%s-lap-best.lmp", gpath, cv_chooseskin.string); + snprintf(bestdemo, 255, "%s-%s-%s-lap-best.lmp", gpath, cv_chooseskin.string, gamemode); if (!FIL_FileExists(bestdemo) || G_CmpDemoTime(bestdemo, lastdemo) & (1<<1)) { // Better lap time, save this demo. if (FIL_FileExists(bestdemo)) @@ -625,6 +621,7 @@ static void G_UpdateRecordReplays(void) } free(gpath); + free(gamemode); // Check emblems when level data is updated if ((earnedEmblems = M_CheckLevelEmblems())) @@ -3884,7 +3881,7 @@ void G_AddMapToBuffer(INT16 map) static void G_UpdateVisited(void) { UINT8 i; - UINT8 earnedEmblems; + //UINT8 earnedEmblems; // No demos. if (demo.playback) @@ -4564,7 +4561,7 @@ void G_LoadGameData(void) if (rectime || reclap) { - G_AllocMainRecordData((INT16)i); + G_AllocMainRecordData((INT16)i, k); mapheaderinfo[i]->mainrecord[k]->time = rectime; mapheaderinfo[i]->mainrecord[k]->lap = reclap; CONS_Printf("Map Record %d, ID %d, Time = %d, Lap = %d\n", k, i, rectime/35, reclap/35); diff --git a/src/g_game.h b/src/g_game.h index 1121aae6d..cb12230bf 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -249,9 +249,8 @@ void G_SetGamestate(gamestate_t newstate); boolean G_GamestateUsesLevel(void); // Gamedata record shit -#define MAXMAPRECORDS 3 SINT8 G_RecordPresetIndex(void); -void G_AllocMainRecordData(INT16 i); +void G_AllocMainRecordData(INT16 i, SINT8 preset); void G_ClearRecords(void); boolean K_EmblemsEnabled(void); diff --git a/src/info/menus.h b/src/info/menus.h index e223c1dca..83ac550b8 100644 --- a/src/info/menus.h +++ b/src/info/menus.h @@ -7,6 +7,7 @@ _(PLAYBACK) _(SP_MAIN) _(SP_GRANDPRIX) _(SP_TIMEATTACK) +_(SP_PRES) _(SP_MODS) _(SP_GUESTREPLAY) _(SP_REPLAY) diff --git a/src/m_cond.c b/src/m_cond.c index 1847f8df3..939f9fe6d 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -542,8 +542,6 @@ UINT8 M_GotLowEnoughTime(INT32 tictime) if (!mapheaderinfo[i] || (mapheaderinfo[i]->menuflags & LF2_NOTIMEATTACK)) continue; - if (preset == -1) - return false; if (!mapheaderinfo[i]->mainrecord[preset] || !mapheaderinfo[i]->mainrecord[preset]->time) return false; else if ((curtics += mapheaderinfo[i]->mainrecord[preset]->time) > tictime) diff --git a/src/m_menu.c b/src/m_menu.c index d765100d0..a1cb6a236 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5218,7 +5218,7 @@ static void M_DrawStatsMaps(void) if (!mapheaderinfo[j] || (mapheaderinfo[j]->menuflags & LF2_NOTIMEATTACK)) continue; - if (preset == -1 || !mapheaderinfo[j]->mainrecord[preset] || mapheaderinfo[j]->mainrecord[preset]->time <= 0) + if (!mapheaderinfo[j]->mainrecord[preset] || mapheaderinfo[j]->mainrecord[preset]->time <= 0) { mapsunfinished++; continue; @@ -5665,7 +5665,7 @@ void M_DrawTimeAttackMenu(void) { INT32 dupadjust = (vid.width/vid.dupx); tic_t lap = 0, time = 0; - if (preset != -1 && mapheaderinfo[cv_nextmap.value-1]->mainrecord[preset]) + if (mapheaderinfo[cv_nextmap.value-1]->mainrecord[preset]) { lap = mapheaderinfo[cv_nextmap.value-1]->mainrecord[preset]->lap; time = mapheaderinfo[cv_nextmap.value-1]->mainrecord[preset]->time; @@ -5683,6 +5683,29 @@ void M_DrawTimeAttackMenu(void) K_drawKartTimestamp(time, 162, 86, cv_nextmap.value-1, 1); } + // Draw current RA preset mode. + { + const char *mode = "Unkown mode"; + if (preset == 0) + { + mode = "SRB2Kart Mode"; + } + else if (preset == 1) + { + mode = "Tech Mode"; + } + else if (preset == 2) + { + mode = "BlanKart Mode"; + } + else if (preset == 3) + { + mode = "Custom Mode"; + } + + V_DrawString(50, 104, V_6WIDTHSPACE, mode); + } + // ALWAYS DRAW player name, level name, skin and color even when not on this menu! if (menustack[0] != MN_SP_TIMEATTACK) { @@ -5840,6 +5863,39 @@ void M_HandleStaffReplay(INT32 choice) M_ExitMenu(); } +void M_SRB2KartPreset(INT32 choice) +{ + (void)choice; + + CV_Set(&cv_dummyattackingrings, "Off"); + CV_Set(&cv_dummyattackingstacking, "Off"); + CV_Set(&cv_dummyattackingchaining, "Off"); + CV_Set(&cv_dummyattackingslipdash, "Off"); + CV_Set(&cv_dummyattackingpurpledrift, "Off"); +} + +void M_TechPreset(INT32 choice) +{ + (void)choice; + + CV_Set(&cv_dummyattackingrings, "Off"); + CV_Set(&cv_dummyattackingstacking, "On"); + CV_Set(&cv_dummyattackingchaining, "On"); + CV_Set(&cv_dummyattackingslipdash,"Off"); + CV_Set(&cv_dummyattackingpurpledrift, "Off"); +} + +void M_BlanKartPreset(INT32 choice) +{ + (void)choice; + + CV_Set(&cv_dummyattackingrings, "On"); + CV_Set(&cv_dummyattackingstacking, "On"); + CV_Set(&cv_dummyattackingchaining, "On"); + CV_Set(&cv_dummyattackingslipdash, "On"); + CV_Set(&cv_dummyattackingpurpledrift, "On"); +} + // Player has selected the "REPLAY" from the time attack screen void M_ReplayTimeAttack(INT32 choice) { diff --git a/src/m_menu.h b/src/m_menu.h index c545e4ea9..de4512507 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -279,6 +279,9 @@ void M_StartGrandPrix(INT32 choice); void M_QuitTimeAttackMenu(INT32 choice); void M_ChooseTimeAttack(INT32 choice); void M_SetGuestReplay(INT32 choice); +void M_SRB2KartPreset(INT32 choice); +void M_TechPreset(INT32 choice); +void M_BlanKartPreset(INT32 choice); void M_ReplayTimeAttack(INT32 choice); void M_HandleStaffReplay(INT32 choice); void M_SetupMultiHandler(INT32 choice);