mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Rework how GP Backups are accessed
- Now actually from the relevant GP difficulty's Cupgrid, instead of the top-level Play choice
- Permits a much cleaner M_StartCup, combining two of the previously four copypasted, slightly modified level startup regions (which could be further combined for sanity's sake, but would take a LITTLE more work right now than I have in me)
- Shows a funny exclamation mark from Sonic Rush on the relevant cup on the grid
- Selected by default when loading the menu, if appropriate
This commit is contained in:
parent
e9df563826
commit
a016a54e52
10 changed files with 296 additions and 182 deletions
51
src/g_game.c
51
src/g_game.c
|
|
@ -5719,6 +5719,57 @@ void G_LoadGame(void)
|
|||
CON_ToggleOff();
|
||||
}
|
||||
|
||||
void G_GetBackupCupData(boolean actuallygetdata)
|
||||
{
|
||||
if (actuallygetdata == false)
|
||||
{
|
||||
cupsavedata.cup = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
char vcheck[VERSIONSIZE+1];
|
||||
char savename[255];
|
||||
UINT8 versionMinor;
|
||||
savebuffer_t save = {0};
|
||||
|
||||
//if (makelivebackup)
|
||||
strcpy(savename, gpbackup);
|
||||
//else
|
||||
//sprintf(savename, savegamename, cursaveslot);
|
||||
|
||||
if (P_SaveBufferFromFile(&save, savename) == false)
|
||||
{
|
||||
cupsavedata.cup = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
versionMinor = READUINT8(save.p);
|
||||
|
||||
memset(vcheck, 0, sizeof (vcheck));
|
||||
sprintf(vcheck, "version %d", VERSION);
|
||||
|
||||
if (versionMinor != SAV_VERSIONMINOR
|
||||
|| memcmp(save.p, vcheck, VERSIONSIZE))
|
||||
{
|
||||
cupsavedata.cup = NULL;
|
||||
P_SaveBufferFree(&save);
|
||||
return; // bad version
|
||||
}
|
||||
save.p += VERSIONSIZE;
|
||||
|
||||
P_GetBackupCupData(&save);
|
||||
|
||||
if (cv_dummygpdifficulty.value != cupsavedata.difficulty
|
||||
|| !!cv_dummygpencore.value != cupsavedata.encore)
|
||||
{
|
||||
// Still not compatible.
|
||||
cupsavedata.cup = NULL;
|
||||
}
|
||||
|
||||
// done
|
||||
P_SaveBufferFree(&save);
|
||||
}
|
||||
|
||||
//
|
||||
// G_SaveGame
|
||||
// Saves your game.
|
||||
|
|
|
|||
|
|
@ -190,6 +190,7 @@ boolean G_IsTitleCardAvailable(void);
|
|||
void G_HandleSaveLevel(boolean removecondition);
|
||||
void G_SaveGame(void);
|
||||
void G_LoadGame(void);
|
||||
void G_GetBackupCupData(boolean actuallygetdata);
|
||||
|
||||
void G_SaveGameData(void);
|
||||
void G_DirtyGameData(void);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include "command.h"
|
||||
#include "doomstat.h" // MAXSPLITSCREENPLAYERS
|
||||
#include "g_demo.h" //menudemo_t
|
||||
#include "p_saveg.h" // savedata_cup_t
|
||||
#include "k_profiles.h" // profile data & functions
|
||||
#include "g_input.h" // gc_
|
||||
#include "i_threads.h"
|
||||
|
|
|
|||
|
|
@ -2368,6 +2368,7 @@ static void M_DrawCupTitle(INT16 y, levelsearch_t *levelsearch)
|
|||
void M_DrawCupSelect(void)
|
||||
{
|
||||
UINT8 i, j, temp = 0;
|
||||
INT16 x, y;
|
||||
UINT8 *colormap = NULL;
|
||||
cupwindata_t *windata = NULL;
|
||||
levelsearch_t templevelsearch = levellist.levelsearch; // full copy
|
||||
|
|
@ -2378,7 +2379,6 @@ void M_DrawCupSelect(void)
|
|||
{
|
||||
size_t id = (i + (j * CUPMENU_COLUMNS)) + (cupgrid.pageno * (CUPMENU_COLUMNS * CUPMENU_ROWS));
|
||||
patch_t *patch = NULL;
|
||||
INT16 x, y;
|
||||
INT16 icony = 7;
|
||||
char status = 'A';
|
||||
char monitor;
|
||||
|
|
@ -2463,6 +2463,13 @@ void M_DrawCupSelect(void)
|
|||
V_DrawScaledPatch(x + 8, y + icony, 0, W_CachePatchName(templevelsearch.cup->icon, PU_CACHE));
|
||||
V_DrawScaledPatch(x + 8, y + icony, 0, W_CachePatchName("CUPBOX", PU_CACHE));
|
||||
|
||||
if (cupgrid.grandprix == true
|
||||
&& templevelsearch.cup == cupsavedata.cup
|
||||
&& id != CUPMENU_CURSORID)
|
||||
{
|
||||
V_DrawScaledPatch(x + 32, y + 32, 0, W_CachePatchName("CUPBKUP1", PU_CACHE));
|
||||
}
|
||||
|
||||
if (!windata)
|
||||
;
|
||||
else if (windata->best_placement != 0)
|
||||
|
|
@ -2562,13 +2569,20 @@ void M_DrawCupSelect(void)
|
|||
}
|
||||
}
|
||||
|
||||
V_DrawScaledPatch(14 + (cupgrid.x*42) - 4,
|
||||
20 + (cupgrid.y*44) - 1 - (24*menutransition.tics),
|
||||
0, W_CachePatchName("CUPCURS", PU_CACHE)
|
||||
);
|
||||
x = 14 + (cupgrid.x*42);
|
||||
y = 20 + (cupgrid.y*44) - (30*menutransition.tics);
|
||||
|
||||
V_DrawScaledPatch(x - 4, y - 1, 0, W_CachePatchName("CUPCURS", PU_CACHE));
|
||||
|
||||
templevelsearch.cup = cupgrid.builtgrid[CUPMENU_CURSORID];
|
||||
|
||||
if (cupgrid.grandprix == true
|
||||
&& templevelsearch.cup != NULL
|
||||
&& templevelsearch.cup == cupsavedata.cup)
|
||||
{
|
||||
V_DrawScaledPatch(x + 32, y + 32, 0, W_CachePatchName("CUPBKUP2", PU_CACHE));
|
||||
}
|
||||
|
||||
V_DrawFill(0, 146 + (24*menutransition.tics), BASEVIDWIDTH, 54, 31);
|
||||
M_DrawCupPreview(146 + (24*menutransition.tics), &templevelsearch);
|
||||
|
||||
|
|
|
|||
|
|
@ -5,10 +5,7 @@
|
|||
#include "../r_skins.h"
|
||||
#include "../s_sound.h"
|
||||
#include "../k_grandprix.h" // K_CanChangeRules
|
||||
#include "../k_podium.h" // K_StartCeremony
|
||||
#include "../m_cond.h" // Condition Sets
|
||||
#include "../r_local.h" // SplitScreen_OnChange
|
||||
#include "../m_misc.h" // FIL_FileExists
|
||||
|
||||
//#define CHARSELECT_DEVICEDEBUG
|
||||
|
||||
|
|
@ -488,123 +485,9 @@ void M_CharacterSelectInit(void)
|
|||
}
|
||||
|
||||
|
||||
static void M_GPBackup(INT32 choice)
|
||||
{
|
||||
if (choice == MA_YES)
|
||||
{
|
||||
G_LoadGame();
|
||||
|
||||
if (savedata.lives != 0)
|
||||
{
|
||||
// Only do this after confirming savegame is ok
|
||||
const UINT8 ssplayers = 0;
|
||||
|
||||
{
|
||||
CV_StealthSetValue(&cv_playercolor[0], savedata.skincolor);
|
||||
|
||||
// follower
|
||||
if (savedata.followerskin < 0 || savedata.followerskin >= numfollowers)
|
||||
CV_StealthSet(&cv_follower[0], "None");
|
||||
else
|
||||
CV_StealthSet(&cv_follower[0], followers[savedata.followerskin].name);
|
||||
|
||||
// finally, call the skin[x] console command.
|
||||
// This will call SendNameAndColor which will synch everything we sent here and apply the changes!
|
||||
|
||||
CV_StealthSet(&cv_skin[0], skins[savedata.skin].name);
|
||||
|
||||
// ...actually, let's do this last - Skin_OnChange has some return-early occasions
|
||||
// follower color
|
||||
CV_SetValue(&cv_followercolor[0], savedata.followercolor);
|
||||
}
|
||||
|
||||
paused = false;
|
||||
|
||||
S_StopMusicCredit();
|
||||
|
||||
if (cv_maxconnections.value < ssplayers+1)
|
||||
CV_SetValue(&cv_maxconnections, ssplayers+1);
|
||||
|
||||
if (splitscreen != ssplayers)
|
||||
{
|
||||
splitscreen = ssplayers;
|
||||
SplitScreen_OnChange();
|
||||
}
|
||||
|
||||
UINT8 entry = roundqueue.position-1;
|
||||
|
||||
SV_StartSinglePlayerServer(roundqueue.entries[entry].gametype, false);
|
||||
|
||||
// Skip Bonus rounds.
|
||||
if (roundqueue.entries[entry].gametype != roundqueue.entries[0].gametype
|
||||
&& roundqueue.entries[entry].rankrestricted == false)
|
||||
{
|
||||
G_GetNextMap(); // updates position in the roundqueue
|
||||
entry = roundqueue.position-1;
|
||||
}
|
||||
|
||||
if (entry < roundqueue.size)
|
||||
{
|
||||
D_MapChange(
|
||||
roundqueue.entries[entry].mapnum + 1,
|
||||
roundqueue.entries[entry].gametype,
|
||||
roundqueue.entries[entry].encore,
|
||||
true,
|
||||
1,
|
||||
false,
|
||||
roundqueue.entries[entry].rankrestricted
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (K_StartCeremony() == false)
|
||||
{
|
||||
// Accomodate our buffoonery with the artificial fade.
|
||||
wipegamestate = -1;
|
||||
|
||||
M_StartMessage(
|
||||
"Grand Prix Backup",
|
||||
"The session is concluded!\n"
|
||||
"You exited a final Bonus Round,\n"
|
||||
"and the Podium failed to load.\n",
|
||||
NULL, MM_NOTHING, NULL, NULL);
|
||||
|
||||
G_HandleSaveLevel(true);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
M_ClearMenus(true);
|
||||
|
||||
// We can't put it deeper in the menuflow due to lack of guaranteed setup
|
||||
restoreMenu = &MainDef;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
M_CharacterSelect(-1);
|
||||
}
|
||||
|
||||
void M_CharacterSelect(INT32 choice)
|
||||
{
|
||||
if (currentMenu == &MainDef
|
||||
&& choice != -1
|
||||
&& FIL_FileExists(gpbackup))
|
||||
{
|
||||
M_StartMessage(
|
||||
"Grand Prix Backup",
|
||||
"A progress backup was found.\n"
|
||||
"Do you want to resurrect your\n"
|
||||
"last Grand Prix session?\n",
|
||||
M_GPBackup,
|
||||
MM_YESNO,
|
||||
"Yes, let's try again",
|
||||
"No, play another way");
|
||||
return;
|
||||
}
|
||||
|
||||
(void)choice;
|
||||
PLAY_CharSelectDef.music = currentMenu->music;
|
||||
PLAY_CharSelectDef.prevMenu = currentMenu;
|
||||
M_SetupNextMenu(&PLAY_CharSelectDef, false);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@
|
|||
#include "../../v_video.h"
|
||||
#include "../../k_grandprix.h"
|
||||
#include "../../r_local.h" // SplitScreen_OnChange
|
||||
#include "../../k_podium.h" // K_StartCeremony
|
||||
#include "../../m_misc.h" // FIL_FileExists
|
||||
#include "../../d_main.h" // D_ClearState
|
||||
|
||||
menuitem_t PLAY_CupSelect[] =
|
||||
{
|
||||
|
|
@ -32,6 +35,150 @@ menu_t PLAY_CupSelectDef = {
|
|||
|
||||
struct cupgrid_s cupgrid;
|
||||
|
||||
static void M_StartCup(UINT8 entry)
|
||||
{
|
||||
UINT8 ssplayers = cv_splitplayers.value-1;
|
||||
|
||||
if (ssplayers > 0)
|
||||
{
|
||||
// Splitscreen is not accomodated with this recovery feature.
|
||||
entry = 0;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
if (entry == 0)
|
||||
{
|
||||
memset(&grandprixinfo, 0, sizeof(struct grandprixinfo));
|
||||
|
||||
// read our dummy cvars
|
||||
|
||||
grandprixinfo.gamespeed = min(KARTSPEED_HARD, cv_dummygpdifficulty.value);
|
||||
grandprixinfo.masterbots = (cv_dummygpdifficulty.value == 3);
|
||||
|
||||
grandprixinfo.gp = true;
|
||||
grandprixinfo.initalize = true;
|
||||
grandprixinfo.cup = levellist.levelsearch.cup;
|
||||
|
||||
// Populate the roundqueue
|
||||
memset(&roundqueue, 0, sizeof(struct roundqueue));
|
||||
G_GPCupIntoRoundQueue(levellist.levelsearch.cup, levellist.newgametype, (boolean)cv_dummygpencore.value);
|
||||
roundqueue.position = roundqueue.roundnum = 1;
|
||||
roundqueue.netcommunicate = true; // relevant for future Online GP
|
||||
}
|
||||
else
|
||||
{
|
||||
// Silently change player setup
|
||||
{
|
||||
CV_StealthSetValue(&cv_playercolor[0], savedata.skincolor);
|
||||
|
||||
// follower
|
||||
if (savedata.followerskin < 0 || savedata.followerskin >= numfollowers)
|
||||
CV_StealthSet(&cv_follower[0], "None");
|
||||
else
|
||||
CV_StealthSet(&cv_follower[0], followers[savedata.followerskin].name);
|
||||
|
||||
// finally, call the skin[x] console command.
|
||||
// This will call SendNameAndColor which will synch everything we sent here and apply the changes!
|
||||
|
||||
CV_StealthSet(&cv_skin[0], skins[savedata.skin].name);
|
||||
|
||||
// ...actually, let's do this last - Skin_OnChange has some return-early occasions
|
||||
// follower color
|
||||
CV_SetValue(&cv_followercolor[0], savedata.followercolor);
|
||||
}
|
||||
|
||||
// Skip Bonus rounds.
|
||||
if (roundqueue.entries[entry].gametype != roundqueue.entries[0].gametype
|
||||
&& roundqueue.entries[entry].rankrestricted == false)
|
||||
{
|
||||
G_GetNextMap(); // updates position in the roundqueue
|
||||
entry = roundqueue.position-1;
|
||||
}
|
||||
}
|
||||
|
||||
paused = false;
|
||||
|
||||
SV_StartSinglePlayerServer(levellist.newgametype, levellist.netgame);
|
||||
|
||||
M_ClearMenus(true);
|
||||
restoreMenu = &PLAY_CupSelectDef;
|
||||
|
||||
if (entry < roundqueue.size)
|
||||
{
|
||||
D_MapChange(
|
||||
roundqueue.entries[entry].mapnum + 1,
|
||||
roundqueue.entries[entry].gametype,
|
||||
roundqueue.entries[entry].encore,
|
||||
true,
|
||||
1,
|
||||
false,
|
||||
roundqueue.entries[entry].rankrestricted
|
||||
);
|
||||
}
|
||||
else if (entry == 0)
|
||||
{
|
||||
I_Error("M_StartCup: roundqueue is empty on startup!!");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (K_StartCeremony() == false)
|
||||
{
|
||||
// Accomodate our buffoonery
|
||||
D_ClearState();
|
||||
M_StartControlPanel();
|
||||
|
||||
M_StartMessage(
|
||||
"Grand Prix Backup",
|
||||
"The session is concluded!\n"
|
||||
"You exited a final Bonus Round,\n"
|
||||
"and the Podium failed to load.\n",
|
||||
NULL, MM_NOTHING, NULL, NULL
|
||||
);
|
||||
|
||||
G_HandleSaveLevel(true);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void M_GPBackup(INT32 choice)
|
||||
{
|
||||
if (choice == MA_YES)
|
||||
{
|
||||
G_LoadGame();
|
||||
|
||||
if (savedata.lives != 0)
|
||||
{
|
||||
M_StartCup(roundqueue.position-1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
M_StartCup(0);
|
||||
}
|
||||
|
||||
void M_CupSelectHandler(INT32 choice)
|
||||
{
|
||||
const UINT8 pid = 0;
|
||||
|
|
@ -104,67 +251,24 @@ void M_CupSelectHandler(INT32 choice)
|
|||
|
||||
if (cupgrid.grandprix == true)
|
||||
{
|
||||
UINT8 ssplayers = cv_splitplayers.value-1;
|
||||
|
||||
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);
|
||||
|
||||
memset(&grandprixinfo, 0, sizeof(struct grandprixinfo));
|
||||
|
||||
if (cv_maxconnections.value < ssplayers+1)
|
||||
CV_SetValue(&cv_maxconnections, ssplayers+1);
|
||||
|
||||
if (splitscreen != ssplayers)
|
||||
if (newcup == cupsavedata.cup
|
||||
&& FIL_FileExists(gpbackup))
|
||||
{
|
||||
splitscreen = ssplayers;
|
||||
SplitScreen_OnChange();
|
||||
}
|
||||
|
||||
// read our dummy cvars
|
||||
|
||||
grandprixinfo.gamespeed = min(KARTSPEED_HARD, cv_dummygpdifficulty.value);
|
||||
grandprixinfo.masterbots = (cv_dummygpdifficulty.value == 3);
|
||||
|
||||
grandprixinfo.gp = true;
|
||||
grandprixinfo.initalize = true;
|
||||
grandprixinfo.cup = newcup;
|
||||
|
||||
// Populate the roundqueue
|
||||
memset(&roundqueue, 0, sizeof(struct roundqueue));
|
||||
G_GPCupIntoRoundQueue(newcup, levellist.newgametype, (boolean)cv_dummygpencore.value);
|
||||
roundqueue.position = roundqueue.roundnum = 1;
|
||||
roundqueue.netcommunicate = true; // relevant for future Online GP
|
||||
|
||||
paused = false;
|
||||
|
||||
// Don't restart the server if we're already in a game lol
|
||||
if (gamestate == GS_MENU)
|
||||
{
|
||||
SV_StartSinglePlayerServer(levellist.newgametype, levellist.netgame);
|
||||
}
|
||||
|
||||
D_MapChange(
|
||||
roundqueue.entries[0].mapnum + 1,
|
||||
roundqueue.entries[0].gametype,
|
||||
roundqueue.entries[0].encore,
|
||||
true,
|
||||
1,
|
||||
false,
|
||||
roundqueue.entries[0].rankrestricted
|
||||
M_StartMessage(
|
||||
"Grand Prix Backup",
|
||||
"A progress backup was found.\n"
|
||||
"Do you want to resurrect your\n"
|
||||
"last Grand Prix session?\n",
|
||||
M_GPBackup,
|
||||
MM_YESNO,
|
||||
"Yes, let's try again",
|
||||
"No, start from Round 1"
|
||||
);
|
||||
|
||||
M_ClearMenus(true);
|
||||
return;
|
||||
}
|
||||
|
||||
restoreMenu = &PLAY_CupSelectDef;
|
||||
M_StartCup(0);
|
||||
}
|
||||
else if (count == 1 && levellist.levelsearch.timeattack == true)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
#include "../../r_local.h" // SplitScreen_OnChange
|
||||
#include "../../f_finale.h" // F_WipeStartScreen
|
||||
#include "../../v_video.h"
|
||||
#include "../../g_game.h" // G_GetBackupCupData
|
||||
#include "../../p_saveg.h" // cupsavedata
|
||||
|
||||
cupheader_t dummy_lostandfound;
|
||||
|
||||
|
|
@ -262,6 +264,11 @@ boolean M_LevelListFromGametype(INT16 gt)
|
|||
const size_t pagelen = sizeof(cupheader_t*) * (CUPMENU_COLUMNS * CUPMENU_ROWS);
|
||||
boolean foundany = false, currentvalid = false;
|
||||
|
||||
G_GetBackupCupData(
|
||||
cupgrid.grandprix == true
|
||||
|| cv_splitplayers.value <= 1
|
||||
);
|
||||
|
||||
templevelsearch.cup = kartcupheaders;
|
||||
|
||||
#if 0
|
||||
|
|
@ -331,7 +338,8 @@ boolean M_LevelListFromGametype(INT16 gt)
|
|||
|
||||
if (Playing()
|
||||
? (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->cup == templevelsearch.cup)
|
||||
: (gt == -1 && levellist.levelsearch.cup == templevelsearch.cup))
|
||||
: (cupsavedata.cup == templevelsearch.cup
|
||||
|| (gt == -1 && levellist.levelsearch.cup == templevelsearch.cup)))
|
||||
{
|
||||
GRID_FOCUSCUP;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@
|
|||
#include "k_zvote.h"
|
||||
|
||||
savedata_t savedata;
|
||||
savedata_cup_t cupsavedata;
|
||||
|
||||
// Block UINT32s to attempt to ensure that the correct data is
|
||||
// being sent and received
|
||||
|
|
@ -5407,6 +5408,46 @@ static inline void P_ArchiveMisc(savebuffer_t *save)
|
|||
WRITEUINT32(save->p, writetime);
|
||||
}
|
||||
|
||||
void P_GetBackupCupData(savebuffer_t *save)
|
||||
{
|
||||
char testname[sizeof(timeattackfolder)];
|
||||
|
||||
READSTRINGN(save->p, testname, sizeof(testname));
|
||||
|
||||
if (strcmp(testname, timeattackfolder))
|
||||
{
|
||||
cupsavedata.cup = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
// Grand Prix information
|
||||
|
||||
cupsavedata.difficulty = READUINT8(save->p);
|
||||
cupsavedata.encore = (boolean)READUINT8(save->p);
|
||||
boolean masterbots = (boolean)READUINT8(save->p);
|
||||
|
||||
if (masterbots == true)
|
||||
cupsavedata.difficulty = KARTGP_MASTER;
|
||||
|
||||
// Find the relevant cup.
|
||||
char cupname[MAXCUPNAME];
|
||||
READSTRINGL(save->p, cupname, sizeof(cupname));
|
||||
UINT32 hash = quickncasehash(cupname, MAXCUPNAME);
|
||||
|
||||
for (cupsavedata.cup = kartcupheaders; cupsavedata.cup; cupsavedata.cup = cupsavedata.cup->next)
|
||||
{
|
||||
if (cupsavedata.cup->namehash != hash)
|
||||
continue;
|
||||
|
||||
if (strcmp(cupsavedata.cup->name, cupname))
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Okay, no further! We've got everything we need.
|
||||
}
|
||||
|
||||
static boolean P_UnArchiveSPGame(savebuffer_t *save)
|
||||
{
|
||||
char testname[sizeof(timeattackfolder)];
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ extern "C" {
|
|||
// Local Play
|
||||
void P_SaveGame(savebuffer_t *save);
|
||||
boolean P_LoadGame(savebuffer_t *save);
|
||||
void P_GetBackupCupData(savebuffer_t *save);
|
||||
|
||||
// Online
|
||||
void P_SaveNetGame(savebuffer_t *save, boolean resending);
|
||||
|
|
@ -66,6 +67,15 @@ struct savedata_t
|
|||
|
||||
extern savedata_t savedata;
|
||||
|
||||
struct savedata_cup_t
|
||||
{
|
||||
cupheader_t *cup;
|
||||
UINT8 difficulty;
|
||||
boolean encore;
|
||||
};
|
||||
|
||||
extern savedata_cup_t cupsavedata;
|
||||
|
||||
struct savebuffer_t
|
||||
{
|
||||
UINT8 *buffer;
|
||||
|
|
|
|||
|
|
@ -297,6 +297,7 @@ TYPEDEF (polyfadedata_t);
|
|||
|
||||
// p_saveg.h
|
||||
TYPEDEF (savedata_t);
|
||||
TYPEDEF (savedata_cup_t);
|
||||
TYPEDEF (savebuffer_t);
|
||||
|
||||
// p_setup.h
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue