mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-12-23 16:32:36 +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();
|
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
|
// G_SaveGame
|
||||||
// Saves your game.
|
// Saves your game.
|
||||||
|
|
|
||||||
|
|
@ -190,6 +190,7 @@ boolean G_IsTitleCardAvailable(void);
|
||||||
void G_HandleSaveLevel(boolean removecondition);
|
void G_HandleSaveLevel(boolean removecondition);
|
||||||
void G_SaveGame(void);
|
void G_SaveGame(void);
|
||||||
void G_LoadGame(void);
|
void G_LoadGame(void);
|
||||||
|
void G_GetBackupCupData(boolean actuallygetdata);
|
||||||
|
|
||||||
void G_SaveGameData(void);
|
void G_SaveGameData(void);
|
||||||
void G_DirtyGameData(void);
|
void G_DirtyGameData(void);
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "doomstat.h" // MAXSPLITSCREENPLAYERS
|
#include "doomstat.h" // MAXSPLITSCREENPLAYERS
|
||||||
#include "g_demo.h" //menudemo_t
|
#include "g_demo.h" //menudemo_t
|
||||||
|
#include "p_saveg.h" // savedata_cup_t
|
||||||
#include "k_profiles.h" // profile data & functions
|
#include "k_profiles.h" // profile data & functions
|
||||||
#include "g_input.h" // gc_
|
#include "g_input.h" // gc_
|
||||||
#include "i_threads.h"
|
#include "i_threads.h"
|
||||||
|
|
|
||||||
|
|
@ -2368,6 +2368,7 @@ static void M_DrawCupTitle(INT16 y, levelsearch_t *levelsearch)
|
||||||
void M_DrawCupSelect(void)
|
void M_DrawCupSelect(void)
|
||||||
{
|
{
|
||||||
UINT8 i, j, temp = 0;
|
UINT8 i, j, temp = 0;
|
||||||
|
INT16 x, y;
|
||||||
UINT8 *colormap = NULL;
|
UINT8 *colormap = NULL;
|
||||||
cupwindata_t *windata = NULL;
|
cupwindata_t *windata = NULL;
|
||||||
levelsearch_t templevelsearch = levellist.levelsearch; // full copy
|
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));
|
size_t id = (i + (j * CUPMENU_COLUMNS)) + (cupgrid.pageno * (CUPMENU_COLUMNS * CUPMENU_ROWS));
|
||||||
patch_t *patch = NULL;
|
patch_t *patch = NULL;
|
||||||
INT16 x, y;
|
|
||||||
INT16 icony = 7;
|
INT16 icony = 7;
|
||||||
char status = 'A';
|
char status = 'A';
|
||||||
char monitor;
|
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(templevelsearch.cup->icon, PU_CACHE));
|
||||||
V_DrawScaledPatch(x + 8, y + icony, 0, W_CachePatchName("CUPBOX", 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)
|
if (!windata)
|
||||||
;
|
;
|
||||||
else if (windata->best_placement != 0)
|
else if (windata->best_placement != 0)
|
||||||
|
|
@ -2562,13 +2569,20 @@ void M_DrawCupSelect(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
V_DrawScaledPatch(14 + (cupgrid.x*42) - 4,
|
x = 14 + (cupgrid.x*42);
|
||||||
20 + (cupgrid.y*44) - 1 - (24*menutransition.tics),
|
y = 20 + (cupgrid.y*44) - (30*menutransition.tics);
|
||||||
0, W_CachePatchName("CUPCURS", PU_CACHE)
|
|
||||||
);
|
V_DrawScaledPatch(x - 4, y - 1, 0, W_CachePatchName("CUPCURS", PU_CACHE));
|
||||||
|
|
||||||
templevelsearch.cup = cupgrid.builtgrid[CUPMENU_CURSORID];
|
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);
|
V_DrawFill(0, 146 + (24*menutransition.tics), BASEVIDWIDTH, 54, 31);
|
||||||
M_DrawCupPreview(146 + (24*menutransition.tics), &templevelsearch);
|
M_DrawCupPreview(146 + (24*menutransition.tics), &templevelsearch);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,7 @@
|
||||||
#include "../r_skins.h"
|
#include "../r_skins.h"
|
||||||
#include "../s_sound.h"
|
#include "../s_sound.h"
|
||||||
#include "../k_grandprix.h" // K_CanChangeRules
|
#include "../k_grandprix.h" // K_CanChangeRules
|
||||||
#include "../k_podium.h" // K_StartCeremony
|
|
||||||
#include "../m_cond.h" // Condition Sets
|
#include "../m_cond.h" // Condition Sets
|
||||||
#include "../r_local.h" // SplitScreen_OnChange
|
|
||||||
#include "../m_misc.h" // FIL_FileExists
|
|
||||||
|
|
||||||
//#define CHARSELECT_DEVICEDEBUG
|
//#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)
|
void M_CharacterSelect(INT32 choice)
|
||||||
{
|
{
|
||||||
if (currentMenu == &MainDef
|
(void)choice;
|
||||||
&& 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
PLAY_CharSelectDef.music = currentMenu->music;
|
PLAY_CharSelectDef.music = currentMenu->music;
|
||||||
PLAY_CharSelectDef.prevMenu = currentMenu;
|
PLAY_CharSelectDef.prevMenu = currentMenu;
|
||||||
M_SetupNextMenu(&PLAY_CharSelectDef, false);
|
M_SetupNextMenu(&PLAY_CharSelectDef, false);
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,9 @@
|
||||||
#include "../../v_video.h"
|
#include "../../v_video.h"
|
||||||
#include "../../k_grandprix.h"
|
#include "../../k_grandprix.h"
|
||||||
#include "../../r_local.h" // SplitScreen_OnChange
|
#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[] =
|
menuitem_t PLAY_CupSelect[] =
|
||||||
{
|
{
|
||||||
|
|
@ -32,6 +35,150 @@ menu_t PLAY_CupSelectDef = {
|
||||||
|
|
||||||
struct cupgrid_s cupgrid;
|
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)
|
void M_CupSelectHandler(INT32 choice)
|
||||||
{
|
{
|
||||||
const UINT8 pid = 0;
|
const UINT8 pid = 0;
|
||||||
|
|
@ -104,67 +251,24 @@ void M_CupSelectHandler(INT32 choice)
|
||||||
|
|
||||||
if (cupgrid.grandprix == true)
|
if (cupgrid.grandprix == true)
|
||||||
{
|
{
|
||||||
UINT8 ssplayers = cv_splitplayers.value-1;
|
if (newcup == cupsavedata.cup
|
||||||
|
&& FIL_FileExists(gpbackup))
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
splitscreen = ssplayers;
|
M_StartMessage(
|
||||||
SplitScreen_OnChange();
|
"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"
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read our dummy cvars
|
M_StartCup(0);
|
||||||
|
|
||||||
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_ClearMenus(true);
|
|
||||||
|
|
||||||
restoreMenu = &PLAY_CupSelectDef;
|
|
||||||
}
|
}
|
||||||
else if (count == 1 && levellist.levelsearch.timeattack == true)
|
else if (count == 1 && levellist.levelsearch.timeattack == true)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@
|
||||||
#include "../../r_local.h" // SplitScreen_OnChange
|
#include "../../r_local.h" // SplitScreen_OnChange
|
||||||
#include "../../f_finale.h" // F_WipeStartScreen
|
#include "../../f_finale.h" // F_WipeStartScreen
|
||||||
#include "../../v_video.h"
|
#include "../../v_video.h"
|
||||||
|
#include "../../g_game.h" // G_GetBackupCupData
|
||||||
|
#include "../../p_saveg.h" // cupsavedata
|
||||||
|
|
||||||
cupheader_t dummy_lostandfound;
|
cupheader_t dummy_lostandfound;
|
||||||
|
|
||||||
|
|
@ -262,6 +264,11 @@ boolean M_LevelListFromGametype(INT16 gt)
|
||||||
const size_t pagelen = sizeof(cupheader_t*) * (CUPMENU_COLUMNS * CUPMENU_ROWS);
|
const size_t pagelen = sizeof(cupheader_t*) * (CUPMENU_COLUMNS * CUPMENU_ROWS);
|
||||||
boolean foundany = false, currentvalid = false;
|
boolean foundany = false, currentvalid = false;
|
||||||
|
|
||||||
|
G_GetBackupCupData(
|
||||||
|
cupgrid.grandprix == true
|
||||||
|
|| cv_splitplayers.value <= 1
|
||||||
|
);
|
||||||
|
|
||||||
templevelsearch.cup = kartcupheaders;
|
templevelsearch.cup = kartcupheaders;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
@ -331,7 +338,8 @@ boolean M_LevelListFromGametype(INT16 gt)
|
||||||
|
|
||||||
if (Playing()
|
if (Playing()
|
||||||
? (mapheaderinfo[gamemap-1] && mapheaderinfo[gamemap-1]->cup == templevelsearch.cup)
|
? (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;
|
GRID_FOCUSCUP;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@
|
||||||
#include "k_zvote.h"
|
#include "k_zvote.h"
|
||||||
|
|
||||||
savedata_t savedata;
|
savedata_t savedata;
|
||||||
|
savedata_cup_t cupsavedata;
|
||||||
|
|
||||||
// Block UINT32s to attempt to ensure that the correct data is
|
// Block UINT32s to attempt to ensure that the correct data is
|
||||||
// being sent and received
|
// being sent and received
|
||||||
|
|
@ -5407,6 +5408,46 @@ static inline void P_ArchiveMisc(savebuffer_t *save)
|
||||||
WRITEUINT32(save->p, writetime);
|
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)
|
static boolean P_UnArchiveSPGame(savebuffer_t *save)
|
||||||
{
|
{
|
||||||
char testname[sizeof(timeattackfolder)];
|
char testname[sizeof(timeattackfolder)];
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ extern "C" {
|
||||||
// Local Play
|
// Local Play
|
||||||
void P_SaveGame(savebuffer_t *save);
|
void P_SaveGame(savebuffer_t *save);
|
||||||
boolean P_LoadGame(savebuffer_t *save);
|
boolean P_LoadGame(savebuffer_t *save);
|
||||||
|
void P_GetBackupCupData(savebuffer_t *save);
|
||||||
|
|
||||||
// Online
|
// Online
|
||||||
void P_SaveNetGame(savebuffer_t *save, boolean resending);
|
void P_SaveNetGame(savebuffer_t *save, boolean resending);
|
||||||
|
|
@ -66,6 +67,15 @@ struct savedata_t
|
||||||
|
|
||||||
extern savedata_t savedata;
|
extern savedata_t savedata;
|
||||||
|
|
||||||
|
struct savedata_cup_t
|
||||||
|
{
|
||||||
|
cupheader_t *cup;
|
||||||
|
UINT8 difficulty;
|
||||||
|
boolean encore;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern savedata_cup_t cupsavedata;
|
||||||
|
|
||||||
struct savebuffer_t
|
struct savebuffer_t
|
||||||
{
|
{
|
||||||
UINT8 *buffer;
|
UINT8 *buffer;
|
||||||
|
|
|
||||||
|
|
@ -297,6 +297,7 @@ TYPEDEF (polyfadedata_t);
|
||||||
|
|
||||||
// p_saveg.h
|
// p_saveg.h
|
||||||
TYPEDEF (savedata_t);
|
TYPEDEF (savedata_t);
|
||||||
|
TYPEDEF (savedata_cup_t);
|
||||||
TYPEDEF (savebuffer_t);
|
TYPEDEF (savebuffer_t);
|
||||||
|
|
||||||
// p_setup.h
|
// p_setup.h
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue