mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-11-11 07:11:39 +00:00
ZDoom-style saves
git-svn-id: https://svn.eduke32.com/eduke32@6569 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
29a0fffd5b
commit
d9b0479343
15 changed files with 443 additions and 247 deletions
|
@ -775,18 +775,6 @@ void G_CheckCommandLine(int32_t argc, char const * const * argv)
|
|||
if (*c)
|
||||
G_AddCon(c);
|
||||
break;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
ud.warp_on = 2 + (*c) - '0';
|
||||
break;
|
||||
case 'z':
|
||||
c++;
|
||||
g_scriptDebug = Batoi(c);
|
||||
|
|
|
@ -204,7 +204,7 @@ void G_OpenDemoWrite(void)
|
|||
if (g_demo_filePtr == NULL)
|
||||
return;
|
||||
|
||||
i=sv_saveandmakesnapshot(g_demo_filePtr, -1, demorec_diffs_cvar, demorec_diffcompress_cvar,
|
||||
i=sv_saveandmakesnapshot(g_demo_filePtr, nullptr, -1, demorec_diffs_cvar, demorec_diffcompress_cvar,
|
||||
demorec_synccompress_cvar|(demorec_seeds_cvar<<1));
|
||||
if (i)
|
||||
{
|
||||
|
|
|
@ -4842,7 +4842,7 @@ FAKE_F3:
|
|||
|
||||
g_doQuickSave = 0;
|
||||
|
||||
if (g_lastSaveSlot == -1)
|
||||
if (!g_lastusersave.isValid())
|
||||
goto FAKE_F2;
|
||||
|
||||
KB_FlushKeyboardQueue();
|
||||
|
@ -4857,16 +4857,19 @@ FAKE_F3:
|
|||
G_DrawRooms(myconnectindex,65536);
|
||||
g_screenCapture = 0;
|
||||
|
||||
if (g_lastSaveSlot >= 0)
|
||||
if (g_lastusersave.isValid())
|
||||
{
|
||||
savebrief_t & sv = g_lastusersave;
|
||||
|
||||
// dirty hack... char 127 in last position indicates an auto-filled name
|
||||
if (ud.savegame[g_lastSaveSlot][MAXSAVEGAMENAME] == 127)
|
||||
if (sv.name[MAXSAVEGAMENAME] == 127)
|
||||
{
|
||||
Bstrncpy(&ud.savegame[g_lastSaveSlot][0], g_mapInfo[ud.volume_number * MAXLEVELS + ud.level_number].name, MAXSAVEGAMENAME);
|
||||
ud.savegame[g_lastSaveSlot][MAXSAVEGAMENAME] = 127;
|
||||
strncpy(sv.name, g_mapInfo[ud.volume_number * MAXLEVELS + ud.level_number].name, MAXSAVEGAMENAME);
|
||||
sv.name[MAXSAVEGAMENAME] = 127;
|
||||
}
|
||||
|
||||
G_SavePlayerMaybeMulti(g_lastSaveSlot);
|
||||
g_quickload = &sv;
|
||||
G_SavePlayerMaybeMulti(sv);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4898,14 +4901,14 @@ FAKE_F3:
|
|||
|
||||
g_doQuickSave = 0;
|
||||
|
||||
if (g_lastSaveSlot == -1)
|
||||
if (g_quickload == nullptr || !g_quickload->isValid())
|
||||
goto FAKE_F3;
|
||||
else if (g_lastSaveSlot >= 0)
|
||||
else if (g_quickload->isValid())
|
||||
{
|
||||
KB_FlushKeyboardQueue();
|
||||
KB_ClearKeysDown();
|
||||
S_PauseSounds(1);
|
||||
G_LoadPlayerMaybeMulti(g_lastSaveSlot);
|
||||
G_LoadPlayerMaybeMulti(*g_quickload);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5922,8 +5925,6 @@ static void G_Startup(void)
|
|||
// initprintf("Loading palette/lookups...\n");
|
||||
G_LoadLookups();
|
||||
|
||||
ReadSaveGameHeaders();
|
||||
|
||||
screenpeek = myconnectindex;
|
||||
|
||||
Bfflush(NULL);
|
||||
|
@ -6532,7 +6533,10 @@ int app_main(int argc, char const * const * argv)
|
|||
Menu_Init();
|
||||
}
|
||||
|
||||
if (ud.warp_on > 1 && (!g_netServer && ud.multimode < 2))
|
||||
#if 0
|
||||
// previously, passing -0 through -9 on the command line would load the save in that slot #
|
||||
// this code should be reusable for a new parameter that takes a filename, if desired
|
||||
if (/* havesavename */ && (!g_netServer && ud.multimode < 2))
|
||||
{
|
||||
clearview(0L);
|
||||
//g_player[myconnectindex].ps->palette = palette;
|
||||
|
@ -6542,9 +6546,10 @@ int app_main(int argc, char const * const * argv)
|
|||
menutext_center(105,"Loading saved game...");
|
||||
nextpage();
|
||||
|
||||
if (G_LoadPlayer(ud.warp_on-2))
|
||||
ud.warp_on = 0;
|
||||
if (G_LoadPlayer(/* savefile */))
|
||||
/* havesavename = false; */
|
||||
}
|
||||
#endif
|
||||
|
||||
FX_StopAllSounds();
|
||||
S_ClearSoundLocks();
|
||||
|
@ -6721,21 +6726,20 @@ MAIN_LOOP_RESTART:
|
|||
}
|
||||
|
||||
// handle CON_SAVE and CON_SAVENN
|
||||
if (g_requestedSaveSlot != -1)
|
||||
if (g_saveRequested)
|
||||
{
|
||||
g_lastSaveSlot = g_requestedSaveSlot;
|
||||
|
||||
OSD_Printf("Saving to slot %d\n", g_requestedSaveSlot);
|
||||
|
||||
KB_FlushKeyboardQueue();
|
||||
|
||||
g_screenCapture = 1;
|
||||
G_DrawRooms(myconnectindex, 65536);
|
||||
g_screenCapture = 0;
|
||||
|
||||
G_SavePlayerMaybeMulti(g_requestedSaveSlot);
|
||||
G_SavePlayerMaybeMulti(g_lastautosave);
|
||||
g_quickload = &g_lastautosave;
|
||||
|
||||
g_requestedSaveSlot = -1;
|
||||
OSD_Printf("Saved: %s\n", g_lastautosave.path);
|
||||
|
||||
g_saveRequested = false;
|
||||
}
|
||||
|
||||
G_DoCheats();
|
||||
|
|
|
@ -132,7 +132,6 @@ extern camera_t g_camera;
|
|||
|
||||
#define MAXRIDECULE 10
|
||||
#define MAXRIDECULELENGTH 40
|
||||
#define MAXSAVEGAMES 10
|
||||
#define MAXSAVEGAMENAMESTRUCT 32
|
||||
#define MAXSAVEGAMENAME (MAXSAVEGAMENAMESTRUCT-1)
|
||||
#define MAXPWLOCKOUT 128
|
||||
|
@ -239,7 +238,6 @@ typedef struct {
|
|||
char god,warp_on,cashman,eog,showallmap;
|
||||
char show_help,scrollmode,noclip;
|
||||
char ridecule[MAXRIDECULE][MAXRIDECULELENGTH];
|
||||
char savegame[MAXSAVEGAMES][MAXSAVEGAMENAMESTRUCT];
|
||||
char pwlockout[MAXPWLOCKOUT],rtsname[MAXRTSNAME];
|
||||
char display_bonus_screen;
|
||||
char show_level_text;
|
||||
|
@ -481,6 +479,10 @@ enum
|
|||
(((g_modDir[0] != '/') ? Bsnprintf(buf, size, "%s/" basename, g_modDir, ##__VA_ARGS__) \
|
||||
: Bsnprintf(buf, size, basename, ##__VA_ARGS__)) >= ((int32_t)size) - 1\
|
||||
)
|
||||
#define G_ModDirSnprintfLite(buf, size, basename) \
|
||||
\
|
||||
((g_modDir[0] != '/') ? Bsnprintf(buf, size, "%s/%s", g_modDir, basename) \
|
||||
: Bsnprintf(buf, size, basename))
|
||||
|
||||
static inline void G_NewGame_EnterLevel(void)
|
||||
{
|
||||
|
|
|
@ -1078,7 +1078,7 @@ static int32_t VM_ResetPlayer(int const playerNum, int32_t vmFlags, int32_t cons
|
|||
//AddLog("resetplayer");
|
||||
if (!g_netServer && ud.multimode < 2 && !(resetFlags & 2))
|
||||
{
|
||||
if (g_lastSaveSlot >= 0 && ud.recstat != 2 && !(resetFlags & 1))
|
||||
if (g_quickload && g_quickload->isValid() && ud.recstat != 2 && !(resetFlags & 1))
|
||||
{
|
||||
Menu_Open(playerNum);
|
||||
KB_ClearKeyDown(sc_Space);
|
||||
|
@ -3463,20 +3463,29 @@ nullquote:
|
|||
{
|
||||
int32_t const requestedSlot = *insptr++;
|
||||
|
||||
if ((unsigned)requestedSlot >= MAXSAVEGAMES)
|
||||
if ((unsigned)requestedSlot >= 10)
|
||||
continue;
|
||||
|
||||
g_requestedSaveSlot = requestedSlot;
|
||||
// check if we need to make a new file
|
||||
if (strcmp(g_lastautosave.path, g_lastusersave.path) == 0 ||
|
||||
requestedSlot != g_lastAutoSaveArbitraryID)
|
||||
{
|
||||
g_lastautosave.reset();
|
||||
}
|
||||
|
||||
if (tw == CON_SAVE || ud.savegame[requestedSlot][0] == 0)
|
||||
g_lastAutoSaveArbitraryID = requestedSlot;
|
||||
|
||||
if (tw == CON_SAVE || g_lastautosave.name[0] == 0)
|
||||
{
|
||||
time_t timeStruct = time(NULL);
|
||||
struct tm *pTime = localtime(&timeStruct);
|
||||
|
||||
strftime(ud.savegame[requestedSlot], sizeof(ud.savegame[requestedSlot]),
|
||||
strftime(g_lastautosave.name, sizeof(g_lastautosave.name),
|
||||
"%d %b %Y %I:%M%p", pTime);
|
||||
}
|
||||
|
||||
g_saveRequested = true;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,6 @@ int32_t __fastcall VM_GetUserdef(int32_t labelNum)
|
|||
case USERDEFS_CLIPPING: labelNum = ud.noclip; break;
|
||||
// case USERDEFS_USER_NAME: labelNum= ud.user_name[MAXPLAYERS][32]; break;
|
||||
// case USERDEFS_RIDECULE: labelNum= ud.ridecule; break;
|
||||
// case USERDEFS_SAVEGAME: labelNum= ud.savegame; break;
|
||||
// case USERDEFS_PWLOCKOUT: labelNum= ud.pwlockout; break;
|
||||
// case USERDEFS_RTSNAME: labelNum= ud.rtsname; break;
|
||||
case USERDEFS_OVERHEAD_ON: labelNum = ud.overhead_on; break;
|
||||
|
@ -198,7 +197,6 @@ void __fastcall VM_SetUserdef(int32_t const labelNum, int32_t const iSet)
|
|||
case USERDEFS_CLIPPING: ud.noclip = iSet; break;
|
||||
// case USERDEFS_USER_NAME: ud.user_name[MAXPLAYERS][32] = lValue; break;
|
||||
// case USERDEFS_RIDECULE: ud.ridecule = lValue; break;
|
||||
// case USERDEFS_SAVEGAME: ud.savegame = lValue; break;
|
||||
// case USERDEFS_PWLOCKOUT: ud.pwlockout = lValue; break;
|
||||
// case USERDEFS_RTSNAME: ud.rtsname = lValue; break;
|
||||
case USERDEFS_OVERHEAD_ON: ud.overhead_on = iSet; break;
|
||||
|
|
|
@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
|
||||
#include "duke3d.h"
|
||||
#include "menus.h"
|
||||
#include "savegame.h"
|
||||
|
||||
#define gamevars_c_
|
||||
|
||||
|
@ -1552,7 +1553,7 @@ static void Gv_AddSystemVars(void)
|
|||
Gv_NewVar("NUMSECTORS",(intptr_t)&numsectors, GAMEVAR_SYSTEM | GAMEVAR_INT16PTR | GAMEVAR_READONLY);
|
||||
Gv_NewVar("Numsprites",(intptr_t)&Numsprites, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR | GAMEVAR_READONLY);
|
||||
|
||||
Gv_NewVar("lastsavepos",(intptr_t)&g_lastSaveSlot, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
|
||||
Gv_NewVar("lastsavepos",(intptr_t)&g_lastAutoSaveArbitraryID, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
|
||||
|
||||
# ifdef USE_OPENGL
|
||||
Gv_NewVar("rendmode",(intptr_t)&rendmode, GAMEVAR_READONLY | GAMEVAR_INT32PTR | GAMEVAR_SYSTEM);
|
||||
|
@ -1709,7 +1710,7 @@ void Gv_RefreshPointers(void)
|
|||
aGameVars[Gv_GetVarIndex("NUMSECTORS")].global = (intptr_t)&numsectors;
|
||||
aGameVars[Gv_GetVarIndex("Numsprites")].global = (intptr_t)&Numsprites;
|
||||
|
||||
aGameVars[Gv_GetVarIndex("lastsavepos")].global = (intptr_t)&g_lastSaveSlot;
|
||||
aGameVars[Gv_GetVarIndex("lastsavepos")].global = (intptr_t)&g_lastAutoSaveArbitraryID;
|
||||
# ifdef USE_OPENGL
|
||||
aGameVars[Gv_GetVarIndex("rendmode")].global = (intptr_t)&rendmode;
|
||||
# endif
|
||||
|
|
|
@ -94,8 +94,6 @@ int32_t g_actorRespawnTime = 768;
|
|||
int32_t g_bouncemineRadius = 2500;
|
||||
int32_t g_deleteQueueSize = 64;
|
||||
int32_t g_itemRespawnTime = 768;
|
||||
int32_t g_lastSaveSlot = -1;
|
||||
int32_t g_requestedSaveSlot = -1;
|
||||
|
||||
int32_t g_morterRadius = 2500;
|
||||
int32_t g_numFreezeBounces = 3;
|
||||
|
|
|
@ -174,8 +174,6 @@ extern int32_t g_bouncemineRadius;
|
|||
extern int32_t g_deleteQueueSize;
|
||||
extern int32_t g_gametypeCnt;
|
||||
extern int32_t g_itemRespawnTime;
|
||||
extern int32_t g_lastSaveSlot;
|
||||
extern int32_t g_requestedSaveSlot;
|
||||
extern int32_t g_morterRadius;
|
||||
extern int32_t g_numFreezeBounces;
|
||||
extern int32_t g_pipebombRadius;
|
||||
|
|
|
@ -490,7 +490,6 @@ enum
|
|||
// game.h
|
||||
MAXRIDECULE = 10,
|
||||
MAXRIDECULELENGTH = 40,
|
||||
MAXSAVEGAMES = 10,
|
||||
MAXSAVEGAMENAME = 22,
|
||||
MAXPWLOCKOUT = 128,
|
||||
MAXRTSNAME = 128,
|
||||
|
@ -589,7 +588,6 @@ typedef struct {
|
|||
char god,warp_on,cashman,eog,showallmap;
|
||||
char show_help,scrollmode,noclip;
|
||||
char ridecule[MAXRIDECULE][MAXRIDECULELENGTH];
|
||||
char savegame[MAXSAVEGAMES][MAXSAVEGAMENAME];
|
||||
char pwlockout[MAXPWLOCKOUT],rtsname[MAXRTSNAME];
|
||||
char display_bonus_screen;
|
||||
char show_level_text;
|
||||
|
|
|
@ -219,7 +219,7 @@ static MenuMenuFormat_t MMF_MouseJoySetupBtns = { { 76<<16,
|
|||
static MenuMenuFormat_t MMF_FuncList = { { 100<<16, 51<<16, }, 152<<16 };
|
||||
static MenuMenuFormat_t MMF_ColorCorrect = { { MENU_MARGIN_REGULAR<<16, 86<<16, }, 190<<16 };
|
||||
static MenuMenuFormat_t MMF_BigSliders = { { MENU_MARGIN_WIDE<<16, 37<<16, }, 190<<16 };
|
||||
static MenuMenuFormat_t MMF_LoadSave = { { 223<<16, 48<<16, }, 320<<16 };
|
||||
static MenuMenuFormat_t MMF_LoadSave = { { 200<<16, 49<<16, }, 145<<16 };
|
||||
static MenuMenuFormat_t MMF_NetSetup = { { 36<<16, 38<<16, }, 190<<16 };
|
||||
static MenuMenuFormat_t MMF_FileSelectLeft = { { 40<<16, 45<<16, }, 162<<16 };
|
||||
static MenuMenuFormat_t MMF_FileSelectRight = { { 164<<16, 45<<16, }, 162<<16 };
|
||||
|
@ -242,7 +242,7 @@ static MenuEntryFormat_t MEF_VideoSetup_Apply = { 4<<16, 16<<16, 168<<16 };
|
|||
static MenuEntryFormat_t MEF_FuncList = { 3<<16, 0, 100<<16 };
|
||||
static MenuEntryFormat_t MEF_ColorCorrect = { 2<<16, 0, -(240<<16) };
|
||||
static MenuEntryFormat_t MEF_BigSliders = { 2<<16, 0, 170<<16 };
|
||||
static MenuEntryFormat_t MEF_LoadSave = { 7<<16, -1, 78<<16 };
|
||||
static MenuEntryFormat_t MEF_LoadSave = { 2<<16, -1, 78<<16 };
|
||||
static MenuEntryFormat_t MEF_NetSetup = { 4<<16, 0, 112<<16 };
|
||||
static MenuEntryFormat_t MEF_NetSetup_Confirm = { 4<<16, 16<<16, 112<<16 };
|
||||
|
||||
|
@ -1110,14 +1110,18 @@ static MenuEntry_t *MEL_SCREENSETUP[] = {
|
|||
// Save and load will be filled in before every viewing of the save/load screen.
|
||||
static MenuLink_t MEO_LOAD = { MENU_LOADVERIFY, MA_None, };
|
||||
static MenuEntry_t ME_LOAD_TEMPLATE = MAKE_MENUENTRY( NULL, &MF_MinifontSave, &MEF_LoadSave, &MEO_LOAD, Link );
|
||||
static MenuEntry_t ME_LOAD[MAXSAVEGAMES];
|
||||
static MenuEntry_t *MEL_LOAD[MAXSAVEGAMES];
|
||||
static MenuEntry_t ME_LOAD_EMPTY = MAKE_MENUENTRY( NULL, &MF_MinifontSave, &MEF_LoadSave, nullptr, Dummy );
|
||||
static MenuEntry_t *ME_LOAD;
|
||||
static MenuEntry_t **MEL_LOAD;
|
||||
|
||||
static char const s_NewSaveGame[] = "(New Save Game)";
|
||||
static MenuString_t MEO_SAVE_TEMPLATE = MAKE_MENUSTRING( NULL, &MF_MinifontSave, MAXSAVEGAMENAME, 0 );
|
||||
static MenuString_t MEO_SAVE[MAXSAVEGAMES];
|
||||
static MenuString_t MEO_SAVE_NEW = MAKE_MENUSTRING( NULL, &MF_MinifontSave, MAXSAVEGAMENAME, 0 );
|
||||
static MenuString_t *MEO_SAVE;
|
||||
static MenuEntry_t ME_SAVE_TEMPLATE = MAKE_MENUENTRY( NULL, &MF_MinifontSave, &MEF_LoadSave, &MEO_SAVE_TEMPLATE, String );
|
||||
static MenuEntry_t ME_SAVE[MAXSAVEGAMES];
|
||||
static MenuEntry_t *MEL_SAVE[MAXSAVEGAMES];
|
||||
static MenuEntry_t ME_SAVE_NEW = MAKE_MENUENTRY( s_NewSaveGame, &MF_MinifontSave, &MEF_LoadSave, &MEO_SAVE_NEW, String );
|
||||
static MenuEntry_t *ME_SAVE;
|
||||
static MenuEntry_t **MEL_SAVE;
|
||||
|
||||
static int32_t soundrate, soundvoices;
|
||||
static MenuOption_t MEO_SOUND = MAKE_MENUOPTION( &MF_Redfont, &MEOS_OffOn, &ud.config.SoundToggle );
|
||||
|
@ -1221,7 +1225,7 @@ static MenuEntry_t *MEL_PLAYER[] = {
|
|||
};
|
||||
|
||||
static MenuString_t MEO_MACROS_TEMPLATE = MAKE_MENUSTRING( NULL, &MF_Bluefont, MAXRIDECULELENGTH, 0 );
|
||||
static MenuString_t MEO_MACROS[MAXSAVEGAMES];
|
||||
static MenuString_t MEO_MACROS[10];
|
||||
static MenuEntry_t ME_MACROS_TEMPLATE = MAKE_MENUENTRY( NULL, &MF_Bluefont, &MEF_Macros, &MEO_MACROS_TEMPLATE, String );
|
||||
static MenuEntry_t ME_MACROS[MAXRIDECULE];
|
||||
static MenuEntry_t *MEL_MACROS[MAXRIDECULE];
|
||||
|
@ -1299,6 +1303,7 @@ static MenuEntry_t *MEL_NETJOIN[] = {
|
|||
#define NoTitle NULL
|
||||
|
||||
#define MAKE_MENUMENU(Title, Format, Entries) { Title, Format, Entries, ARRAY_SIZE(Entries), 0, 0, 0 }
|
||||
#define MAKE_MENUMENU_CUSTOMSIZE(Title, Format, Entries) { Title, Format, Entries, 0, 0, 0, 0 }
|
||||
|
||||
static MenuMenu_t M_MAIN = MAKE_MENUMENU( NoTitle, &MMF_Top_Main, MEL_MAIN );
|
||||
static MenuMenu_t M_MAIN_INGAME = MAKE_MENUMENU( NoTitle, &MMF_Top_Main, MEL_MAIN_INGAME );
|
||||
|
@ -1334,8 +1339,8 @@ static MenuMenu_t M_RENDERERSETUP_POLYMER = MAKE_MENUMENU("Polymer Setup", &MMF_
|
|||
static MenuMenu_t M_COLCORR = MAKE_MENUMENU( "Color Correction", &MMF_ColorCorrect, MEL_COLCORR );
|
||||
static MenuMenu_t M_SCREENSETUP = MAKE_MENUMENU( "HUD Setup", &MMF_BigOptions, MEL_SCREENSETUP );
|
||||
static MenuMenu_t M_DISPLAYSETUP = MAKE_MENUMENU( "Display Setup", &MMF_BigOptions, MEL_DISPLAYSETUP );
|
||||
static MenuMenu_t M_LOAD = MAKE_MENUMENU( s_LoadGame, &MMF_LoadSave, MEL_LOAD );
|
||||
static MenuMenu_t M_SAVE = MAKE_MENUMENU( s_SaveGame, &MMF_LoadSave, MEL_SAVE );
|
||||
static MenuMenu_t M_LOAD = MAKE_MENUMENU_CUSTOMSIZE( s_LoadGame, &MMF_LoadSave, MEL_LOAD );
|
||||
static MenuMenu_t M_SAVE = MAKE_MENUMENU_CUSTOMSIZE( s_SaveGame, &MMF_LoadSave, MEL_SAVE );
|
||||
static MenuMenu_t M_SOUND = MAKE_MENUMENU( "Sound Setup", &MMF_BigOptions, MEL_SOUND );
|
||||
static MenuMenu_t M_ADVSOUND = MAKE_MENUMENU( "Advanced Sound", &MMF_BigOptions, MEL_ADVSOUND );
|
||||
static MenuMenu_t M_NETWORK = MAKE_MENUMENU( "Network Game", &MMF_Top_Joystick_Network, MEL_NETWORK );
|
||||
|
@ -1490,6 +1495,29 @@ static void MenuEntry_LookDisabledOnCondition(MenuEntry_t * const entry, const i
|
|||
entry->flags &= ~MEF_LookDisabled;
|
||||
}
|
||||
|
||||
static int32_t M_RunMenu_Menu(Menu_t *cm, MenuMenu_t *menu, MenuEntry_t *currentry, int32_t state, const vec2_t origin, bool actually_draw = true);
|
||||
static void Menu_EntryFocus(/*MenuEntry_t *entry*/);
|
||||
|
||||
static MenuEntry_t *Menu_AdjustForCurrentEntryAssignment(MenuMenu_t *menu)
|
||||
{
|
||||
MenuEntry_t *currentry = menu->entrylist[menu->currentEntry];
|
||||
|
||||
Menu_EntryFocus(/*currentry*/);
|
||||
|
||||
if (currentry->ybottom - menu->scrollPos > klabs(menu->format->bottomcutoff))
|
||||
menu->scrollPos = currentry->ybottom - klabs(menu->format->bottomcutoff);
|
||||
else if (currentry->ytop - menu->scrollPos < menu->format->pos.y)
|
||||
menu->scrollPos = currentry->ytop - menu->format->pos.y;
|
||||
|
||||
return currentry;
|
||||
}
|
||||
|
||||
static MenuEntry_t *Menu_AdjustForCurrentEntryAssignmentBlind(MenuMenu_t *menu)
|
||||
{
|
||||
M_RunMenu_Menu(nullptr, menu, nullptr, 0, { 0, 0 }, false);
|
||||
return Menu_AdjustForCurrentEntryAssignment(menu);
|
||||
}
|
||||
|
||||
/*
|
||||
This function prepares data after ART and CON have been processed.
|
||||
It also initializes some data in loops rather than statically at compile time.
|
||||
|
@ -1606,6 +1634,7 @@ void Menu_Init(void)
|
|||
MEOSN_NetSkills[g_skillCnt] = MenuSkillNone;
|
||||
MMF_Top_Skill.pos.y = (58 + (4-g_skillCnt)*6)<<16;
|
||||
M_SKILL.currentEntry = 1;
|
||||
Menu_AdjustForCurrentEntryAssignmentBlind(&M_SKILL);
|
||||
|
||||
// prepare multiplayer gametypes
|
||||
k = -1;
|
||||
|
@ -1620,20 +1649,6 @@ void Menu_Init(void)
|
|||
if (NAM_WW2GI)
|
||||
ME_NETOPTIONS_MONSTERS.name = "Enemies";
|
||||
|
||||
// prepare savegames
|
||||
for (i = 0; i < MAXSAVEGAMES; ++i)
|
||||
{
|
||||
MEL_LOAD[i] = &ME_LOAD[i];
|
||||
MEL_SAVE[i] = &ME_SAVE[i];
|
||||
ME_LOAD[i] = ME_LOAD_TEMPLATE;
|
||||
ME_SAVE[i] = ME_SAVE_TEMPLATE;
|
||||
ME_SAVE[i].entry = &MEO_SAVE[i];
|
||||
MEO_SAVE[i] = MEO_SAVE_TEMPLATE;
|
||||
|
||||
ME_LOAD[i].name = ud.savegame[i];
|
||||
MEO_SAVE[i].variable = ud.savegame[i];
|
||||
}
|
||||
|
||||
// prepare text chat macros
|
||||
for (i = 0; i < MAXRIDECULE; ++i)
|
||||
{
|
||||
|
@ -1791,6 +1806,7 @@ void Menu_Init(void)
|
|||
static void Menu_Run(Menu_t *cm, vec2_t origin);
|
||||
|
||||
|
||||
static void Menu_BlackRectangle(int32_t x, int32_t y, int32_t width, int32_t height, int32_t orientation);
|
||||
|
||||
/*
|
||||
At present, no true difference is planned between Menu_Pre() and Menu_PreDraw().
|
||||
|
@ -2113,24 +2129,36 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin)
|
|||
#ifndef EDUKE32_ANDROID_MENU
|
||||
"\n(Y/N)"
|
||||
#endif
|
||||
, ud.savegame[g_lastSaveSlot]);
|
||||
, g_quickload->name);
|
||||
mgametextcenter(origin.x, origin.y + (90<<16), tempbuf);
|
||||
break;
|
||||
|
||||
case MENU_LOAD:
|
||||
{
|
||||
#if 0
|
||||
for (i = 0; i <= 108; i += 12)
|
||||
rotatesprite_fs(origin.x + ((160+64+91-64)<<16), origin.y + ((i+56)<<16), 65536L,0,TEXTBOX,24,0,10);
|
||||
#endif
|
||||
Menu_BlackRectangle(origin.x + (198<<16), origin.y + (47<<16), 102<<16, 100<<16, 1|32);
|
||||
|
||||
rotatesprite_fs(origin.x + (22<<16), origin.y + (97<<16), 65536L,0,WINDOWBORDER2,24,0,10);
|
||||
rotatesprite_fs(origin.x + (180<<16), origin.y + (97<<16), 65536L,1024,WINDOWBORDER2,24,0,10);
|
||||
rotatesprite_fs(origin.x + (99<<16), origin.y + (50<<16), 65536L,512,WINDOWBORDER1,24,0,10);
|
||||
rotatesprite_fs(origin.x + (103<<16), origin.y + (144<<16), 65536L,1024+512,WINDOWBORDER1,24,0,10);
|
||||
|
||||
if (ud.savegame[M_LOAD.currentEntry][0])
|
||||
if (M_LOAD.currentEntry >= (int32_t)g_nummenusaves)
|
||||
{
|
||||
mmenutext(origin.x + (72<<16), origin.y + (100<<16), "Empty");
|
||||
break;
|
||||
}
|
||||
|
||||
menusave_t & msv = g_menusaves[M_LOAD.currentEntry];
|
||||
|
||||
if (msv.brief.isValid())
|
||||
{
|
||||
rotatesprite_fs(origin.x + (101<<16), origin.y + (97<<16), 65536>>1,512,TILE_LOADSHOT,-32,0,4+10+64);
|
||||
|
||||
if (g_oldverSavegame[M_LOAD.currentEntry])
|
||||
if (msv.isOldVer)
|
||||
{
|
||||
mmenutext(origin.x + (53<<16), origin.y + (70<<16), "Previous");
|
||||
mmenutext(origin.x + (58<<16), origin.y + (90<<16), "Version");
|
||||
|
@ -2160,13 +2188,16 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin)
|
|||
if (savehead.volnum == 0 && savehead.levnum == 7)
|
||||
mgametextcenter(origin.x, origin.y + (180<<16), savehead.boardfn);
|
||||
}
|
||||
else
|
||||
mmenutext(origin.x + (69<<16), origin.y + (70<<16), "Empty");
|
||||
break;
|
||||
}
|
||||
|
||||
case MENU_SAVE:
|
||||
{
|
||||
#if 0
|
||||
for (i = 0; i <= 108; i += 12)
|
||||
rotatesprite_fs(origin.x + ((160+64+91-64)<<16), origin.y + ((i+56)<<16), 65536L,0,TEXTBOX,24,0,10);
|
||||
#endif
|
||||
Menu_BlackRectangle(origin.x + (198<<16), origin.y + (47<<16), 102<<16, 100<<16, 1|32);
|
||||
|
||||
rotatesprite_fs(origin.x + (22<<16), origin.y + (97<<16), 65536L,0,WINDOWBORDER2,24,0,10);
|
||||
rotatesprite_fs(origin.x + (180<<16), origin.y + (97<<16), 65536L,1024,WINDOWBORDER2,24,0,10);
|
||||
|
@ -2174,31 +2205,36 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin)
|
|||
rotatesprite_fs(origin.x + (103<<16), origin.y + (144<<16), 65536L,1024+512,WINDOWBORDER1,24,0,10);
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < 10; ++i)
|
||||
if (((MenuString_t*)M_SAVE.entrylist[i]->entry)->editfield)
|
||||
for (size_t k = 0; k < g_nummenusaves+1; ++k)
|
||||
if (((MenuString_t*)M_SAVE.entrylist[k]->entry)->editfield)
|
||||
j |= 1;
|
||||
|
||||
if (j)
|
||||
rotatesprite_fs(origin.x + (101<<16), origin.y + (97<<16), 65536L>>1,512,TILE_SAVESHOT,-32,0,4+10+64);
|
||||
else if (ud.savegame[M_SAVE.currentEntry][0])
|
||||
rotatesprite_fs(origin.x + (101<<16), origin.y + (97<<16), 65536L>>1,512,TILE_LOADSHOT,-32,0,4+10+64);
|
||||
else
|
||||
mmenutext(origin.x + (69<<16), origin.y + (70<<16), "Empty");
|
||||
|
||||
if (ud.savegame[M_SAVE.currentEntry][0] && g_oldverSavegame[M_SAVE.currentEntry])
|
||||
else if (0 < M_SAVE.currentEntry && M_SAVE.currentEntry <= (int32_t)g_nummenusaves)
|
||||
{
|
||||
mmenutext(origin.x + (53<<16), origin.y + (70<<16), "Previous");
|
||||
mmenutext(origin.x + (58<<16), origin.y + (90<<16), "Version");
|
||||
if (g_menusaves[M_SAVE.currentEntry-1].brief.isValid())
|
||||
{
|
||||
rotatesprite_fs(origin.x + (101<<16), origin.y + (97<<16), 65536L>>1,512,TILE_LOADSHOT,-32,0,4+10+64);
|
||||
|
||||
if (g_menusaves[M_SAVE.currentEntry-1].isOldVer)
|
||||
{
|
||||
mmenutext(origin.x + (53<<16), origin.y + (70<<16), "Previous");
|
||||
mmenutext(origin.x + (58<<16), origin.y + (90<<16), "Version");
|
||||
|
||||
#ifndef EDUKE32_SIMPLE_MENU
|
||||
Bsprintf(tempbuf,"Saved: %d.%d.%d %d-bit", savehead.majorver, savehead.minorver,
|
||||
savehead.bytever, 8*savehead.ptrsize);
|
||||
mgametext(origin.x + (31<<16), origin.y + (104<<16), tempbuf);
|
||||
Bsprintf(tempbuf,"Our: %d.%d.%d %d-bit", SV_MAJOR_VER, SV_MINOR_VER, BYTEVERSION,
|
||||
(int32_t)(8*sizeof(intptr_t)));
|
||||
mgametext(origin.x + ((31+16)<<16), origin.y + (114<<16), tempbuf);
|
||||
Bsprintf(tempbuf,"Saved: %d.%d.%d %d-bit", savehead.majorver, savehead.minorver,
|
||||
savehead.bytever, 8*savehead.ptrsize);
|
||||
mgametext(origin.x + (31<<16), origin.y + (104<<16), tempbuf);
|
||||
Bsprintf(tempbuf,"Our: %d.%d.%d %d-bit", SV_MAJOR_VER, SV_MINOR_VER, BYTEVERSION,
|
||||
(int32_t)(8*sizeof(intptr_t)));
|
||||
mgametext(origin.x + ((31+16)<<16), origin.y + (114<<16), tempbuf);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
mmenutext(origin.x + (82<<16), origin.y + (100<<16), "New");
|
||||
|
||||
if (ud.multimode > 1)
|
||||
{
|
||||
|
@ -2211,6 +2247,7 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin)
|
|||
if (ud.volume_number == 0 && ud.level_number == 7)
|
||||
mgametextcenter(origin.x, origin.y + (180<<16), currentboardfilename);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef EDUKE32_ANDROID_MENU
|
||||
case MENU_SKILL:
|
||||
|
@ -2223,8 +2260,10 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin)
|
|||
#endif
|
||||
|
||||
case MENU_LOADVERIFY:
|
||||
{
|
||||
fade_screen_black(1);
|
||||
if (g_oldverSavegame[M_LOAD.currentEntry])
|
||||
menusave_t & msv = g_menusaves[M_LOAD.currentEntry];
|
||||
if (msv.isOldVer)
|
||||
{
|
||||
Bsprintf(tempbuf, "Start new game:\n%s / %s"
|
||||
#ifndef EDUKE32_ANDROID_MENU
|
||||
|
@ -2239,10 +2278,11 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin)
|
|||
#ifndef EDUKE32_ANDROID_MENU
|
||||
"\n(Y/N)"
|
||||
#endif
|
||||
, ud.savegame[M_LOAD.currentEntry]);
|
||||
, msv.brief.name);
|
||||
mgametextcenter(origin.x, origin.y + (90<<16), tempbuf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MENU_SAVEVERIFY:
|
||||
fade_screen_black(1);
|
||||
|
@ -2619,10 +2659,21 @@ static void Menu_EntryFocus(/*MenuEntry_t *entry*/)
|
|||
switch (g_currentMenu)
|
||||
{
|
||||
case MENU_LOAD:
|
||||
G_LoadSaveHeaderNew(M_LOAD.currentEntry, &savehead);
|
||||
if (M_LOAD.currentEntry < (int32_t)g_nummenusaves)
|
||||
{
|
||||
savebrief_t & sv = g_menusaves[M_LOAD.currentEntry].brief;
|
||||
if (sv.isValid())
|
||||
G_LoadSaveHeaderNew(sv.path, &savehead);
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_SAVE:
|
||||
G_LoadSaveHeaderNew(M_SAVE.currentEntry, &savehead);
|
||||
if (0 < M_SAVE.currentEntry && M_SAVE.currentEntry <= (int32_t)g_nummenusaves)
|
||||
{
|
||||
savebrief_t & sv = g_menusaves[M_SAVE.currentEntry-1].brief;
|
||||
if (sv.isValid())
|
||||
G_LoadSaveHeaderNew(sv.path, &savehead);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -3131,10 +3182,19 @@ static void Menu_EntryStringActivate(/*MenuEntry_t *entry*/)
|
|||
switch (g_currentMenu)
|
||||
{
|
||||
case MENU_SAVE:
|
||||
if (!save_xxh)
|
||||
save_xxh = XXH32((uint8_t *)&ud.savegame[M_SAVE.currentEntry][0], MAXSAVEGAMENAME, 0xDEADBEEF);
|
||||
if (ud.savegame[M_SAVE.currentEntry][0])
|
||||
Menu_Change(MENU_SAVEVERIFY);
|
||||
if (M_SAVE.currentEntry > 0)
|
||||
{
|
||||
savebrief_t & sv = g_menusaves[M_SAVE.currentEntry-1].brief;
|
||||
if (!save_xxh)
|
||||
save_xxh = XXH32((uint8_t *)sv.name, MAXSAVEGAMENAME, 0xDEADBEEF);
|
||||
if (sv.isValid())
|
||||
Menu_Change(MENU_SAVEVERIFY);
|
||||
}
|
||||
else
|
||||
{
|
||||
ME_SAVE_NEW.name = nullptr;
|
||||
save_xxh = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -3142,41 +3202,44 @@ static void Menu_EntryStringActivate(/*MenuEntry_t *entry*/)
|
|||
}
|
||||
}
|
||||
|
||||
static int32_t Menu_EntryStringSubmit(MenuEntry_t *entry, char *input)
|
||||
static int32_t Menu_EntryStringSubmit(/*MenuEntry_t *entry, */char *input)
|
||||
{
|
||||
MenuString_t *object = (MenuString_t*)entry->entry;
|
||||
int32_t returnvar = 0;
|
||||
|
||||
switch (g_currentMenu)
|
||||
{
|
||||
case MENU_SAVE:
|
||||
{
|
||||
savebrief_t & sv = g_lastusersave = M_SAVE.currentEntry == 0 ? savebrief_t{input} : g_menusaves[M_SAVE.currentEntry-1].brief;
|
||||
|
||||
// dirty hack... char 127 in last position indicates an auto-filled name
|
||||
#ifdef __ANDROID__
|
||||
if (1)
|
||||
#else
|
||||
if (input[0] == 0 || (ud.savegame[M_SAVE.currentEntry][MAXSAVEGAMENAME] == 127 &&
|
||||
Bstrncmp(&ud.savegame[M_SAVE.currentEntry][0], input, MAXSAVEGAMENAME) == 0 &&
|
||||
save_xxh == XXH32((uint8_t *)&ud.savegame[M_SAVE.currentEntry][0], MAXSAVEGAMENAME, 0xDEADBEEF)))
|
||||
if (input[0] == 0 || (sv.name[MAXSAVEGAMENAME] == 127 &&
|
||||
strncmp(sv.name, input, MAXSAVEGAMENAME) == 0 &&
|
||||
save_xxh == XXH32((uint8_t *)sv.name, MAXSAVEGAMENAME, 0xDEADBEEF)))
|
||||
#endif
|
||||
{
|
||||
Bstrncpy(&ud.savegame[M_SAVE.currentEntry][0], g_mapInfo[ud.volume_number * MAXLEVELS + ud.level_number].name, MAXSAVEGAMENAME);
|
||||
ud.savegame[M_SAVE.currentEntry][MAXSAVEGAMENAME] = 127;
|
||||
strncpy(sv.name, g_mapInfo[ud.volume_number * MAXLEVELS + ud.level_number].name, MAXSAVEGAMENAME);
|
||||
sv.name[MAXSAVEGAMENAME] = 127;
|
||||
returnvar = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
ud.savegame[M_SAVE.currentEntry][MAXSAVEGAMENAME] = 0;
|
||||
Bstrncpy(object->variable, input, object->bufsize);
|
||||
strncpy(sv.name, input, MAXSAVEGAMENAME);
|
||||
sv.name[MAXSAVEGAMENAME] = 0;
|
||||
}
|
||||
|
||||
G_SavePlayerMaybeMulti(M_SAVE.currentEntry);
|
||||
G_SavePlayerMaybeMulti(sv);
|
||||
|
||||
g_lastSaveSlot = M_SAVE.currentEntry;
|
||||
g_quickload = &sv;
|
||||
g_player[myconnectindex].ps->gm = MODE_GAME;
|
||||
|
||||
Menu_Change(MENU_CLOSE);
|
||||
save_xxh = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
|
@ -3191,7 +3254,7 @@ static void Menu_EntryStringCancel(/*MenuEntry_t *entry*/)
|
|||
{
|
||||
case MENU_SAVE:
|
||||
save_xxh = 0;
|
||||
ReadSaveGameHeaders();
|
||||
ME_SAVE_NEW.name = s_NewSaveGame;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -3226,7 +3289,7 @@ static void Menu_Verify(int32_t input)
|
|||
FX_StopAllSounds();
|
||||
S_ClearSoundLocks();
|
||||
|
||||
G_LoadPlayerMaybeMulti(g_lastSaveSlot);
|
||||
G_LoadPlayerMaybeMulti(*g_quickload);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3243,14 +3306,26 @@ static void Menu_Verify(int32_t input)
|
|||
case MENU_LOADVERIFY:
|
||||
if (input)
|
||||
{
|
||||
g_lastSaveSlot = M_LOAD.currentEntry;
|
||||
savebrief_t & sv = g_menusaves[M_LOAD.currentEntry].brief;
|
||||
|
||||
if (strcmp(sv.path, g_lastusersave.path) != 0)
|
||||
{
|
||||
g_freshload = sv;
|
||||
g_lastusersave.reset();
|
||||
g_lastautosave.reset();
|
||||
g_quickload = &g_freshload;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_quickload = &g_lastusersave;
|
||||
}
|
||||
|
||||
KB_FlushKeyboardQueue();
|
||||
KB_ClearKeysDown();
|
||||
|
||||
Menu_Change(MENU_CLOSE);
|
||||
|
||||
G_LoadPlayerMaybeMulti(g_lastSaveSlot);
|
||||
G_LoadPlayerMaybeMulti(sv);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -3258,7 +3333,6 @@ static void Menu_Verify(int32_t input)
|
|||
if (!input)
|
||||
{
|
||||
save_xxh = 0;
|
||||
ReadSaveGameHeaders();
|
||||
|
||||
((MenuString_t*)M_SAVE.entrylist[M_SAVE.currentEntry]->entry)->editfield = NULL;
|
||||
}
|
||||
|
@ -3629,6 +3703,7 @@ static void Menu_MaybeSetSelectionToChild(Menu_t * m, MenuID_t id)
|
|||
if (link->linkID == id)
|
||||
{
|
||||
menu->currentEntry = i;
|
||||
Menu_AdjustForCurrentEntryAssignmentBlind(menu);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -3636,6 +3711,43 @@ static void Menu_MaybeSetSelectionToChild(Menu_t * m, MenuID_t id)
|
|||
}
|
||||
}
|
||||
|
||||
static void Menu_ReadSaveGameHeaders()
|
||||
{
|
||||
ReadSaveGameHeaders();
|
||||
|
||||
size_t const numloaditems = max(g_nummenusaves, 1), numsaveitems = g_nummenusaves+1;
|
||||
ME_LOAD = (MenuEntry_t *)realloc(ME_LOAD, g_nummenusaves * sizeof(MenuEntry_t));
|
||||
MEL_LOAD = (MenuEntry_t **)realloc(MEL_LOAD, numloaditems * sizeof(MenuEntry_t *));
|
||||
MEO_SAVE = (MenuString_t *)realloc(MEO_SAVE, g_nummenusaves * sizeof(MenuString_t));
|
||||
ME_SAVE = (MenuEntry_t *)realloc(ME_SAVE, g_nummenusaves * sizeof(MenuEntry_t));
|
||||
MEL_SAVE = (MenuEntry_t **)realloc(MEL_SAVE, numsaveitems * sizeof(MenuEntry_t *));
|
||||
|
||||
MEL_SAVE[0] = &ME_SAVE_NEW;
|
||||
ME_SAVE_NEW.name = s_NewSaveGame;
|
||||
for (size_t i = 0; i < g_nummenusaves; ++i)
|
||||
{
|
||||
MEL_LOAD[i] = &ME_LOAD[i];
|
||||
MEL_SAVE[i+1] = &ME_SAVE[i];
|
||||
ME_LOAD[i] = ME_LOAD_TEMPLATE;
|
||||
ME_SAVE[i] = ME_SAVE_TEMPLATE;
|
||||
ME_SAVE[i].entry = &MEO_SAVE[i];
|
||||
MEO_SAVE[i] = MEO_SAVE_TEMPLATE;
|
||||
|
||||
ME_LOAD[i].name = g_menusaves[i].brief.name;
|
||||
MEO_SAVE[i].variable = g_menusaves[i].brief.name;
|
||||
}
|
||||
|
||||
if (g_nummenusaves == 0)
|
||||
MEL_LOAD[0] = &ME_LOAD_EMPTY;
|
||||
|
||||
M_LOAD.entrylist = MEL_LOAD;
|
||||
M_LOAD.numEntries = numloaditems;
|
||||
M_SAVE.entrylist = MEL_SAVE;
|
||||
M_SAVE.numEntries = numsaveitems;
|
||||
|
||||
// lexicographical sorting?
|
||||
}
|
||||
|
||||
static void Menu_AboutToStartDisplaying(Menu_t * m)
|
||||
{
|
||||
switch (m->menuID)
|
||||
|
@ -3653,22 +3765,47 @@ static void Menu_AboutToStartDisplaying(Menu_t * m)
|
|||
case MENU_LOAD:
|
||||
if (KXDWN)
|
||||
M_LOAD.title = (g_player[myconnectindex].ps->gm & MODE_GAME) ? s_LoadGame : s_Continue;
|
||||
for (size_t i = 0; i < MAXSAVEGAMES; ++i)
|
||||
{
|
||||
MenuEntry_DisableOnCondition(&ME_LOAD[i], !ud.savegame[i][0] /*|| g_oldverSavegame[i]*/);
|
||||
MenuEntry_LookDisabledOnCondition(&ME_LOAD[i], g_oldverSavegame[i]);
|
||||
}
|
||||
|
||||
if (g_lastSaveSlot >= 0 && g_previousMenu != MENU_LOADVERIFY)
|
||||
M_LOAD.currentEntry = g_lastSaveSlot;
|
||||
Menu_ReadSaveGameHeaders();
|
||||
|
||||
for (size_t i = 0; i < g_nummenusaves; ++i)
|
||||
MenuEntry_LookDisabledOnCondition(&ME_LOAD[i], g_menusaves[i].isOldVer);
|
||||
|
||||
if (g_quickload && g_quickload->isValid())
|
||||
{
|
||||
for (size_t i = 0; i < g_nummenusaves; ++i)
|
||||
{
|
||||
if (strcmp(g_menusaves[i].brief.path, g_quickload->path) == 0)
|
||||
{
|
||||
M_LOAD.currentEntry = i;
|
||||
Menu_AdjustForCurrentEntryAssignmentBlind(&M_LOAD);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_SAVE:
|
||||
if (g_lastSaveSlot >= 0 && g_previousMenu != MENU_SAVEVERIFY)
|
||||
M_SAVE.currentEntry = g_lastSaveSlot;
|
||||
if (g_previousMenu == MENU_SAVEVERIFY)
|
||||
break;
|
||||
|
||||
for (size_t i = 0; i < MAXSAVEGAMES; ++i)
|
||||
MenuEntry_LookDisabledOnCondition(&ME_SAVE[i], g_oldverSavegame[i]);
|
||||
Menu_ReadSaveGameHeaders();
|
||||
|
||||
if (g_lastusersave.isValid())
|
||||
{
|
||||
for (size_t i = 0; i < g_nummenusaves; ++i)
|
||||
{
|
||||
if (strcmp(g_menusaves[i].brief.path, g_lastusersave.path) == 0)
|
||||
{
|
||||
M_SAVE.currentEntry = i+1;
|
||||
Menu_AdjustForCurrentEntryAssignmentBlind(&M_SAVE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < g_nummenusaves; ++i)
|
||||
MenuEntry_LookDisabledOnCondition(&ME_SAVE[i], g_menusaves[i].isOldVer);
|
||||
|
||||
if (g_player[myconnectindex].ps->gm&MODE_GAME)
|
||||
{
|
||||
|
@ -4162,13 +4299,13 @@ static void Menu_RunInput_EntryRangeDouble_MovementArbitrary(/*MenuEntry_t *entr
|
|||
static void Menu_RunInput_EntryRangeDouble_Movement(/*MenuEntry_t *entry, */MenuRangeDouble_t *object, MenuMovement_t direction);
|
||||
#endif
|
||||
static void Menu_RunInput_EntryString_Activate(MenuEntry_t *entry);
|
||||
static void Menu_RunInput_EntryString_Submit(MenuEntry_t *entry, MenuString_t *object);
|
||||
static void Menu_RunInput_EntryString_Submit(/*MenuEntry_t *entry, */MenuString_t *object);
|
||||
static void Menu_RunInput_EntryString_Cancel(/*MenuEntry_t *entry, */MenuString_t *object);
|
||||
static void Menu_RunInput_FileSelect_MovementVerify(MenuFileSelect_t *object);
|
||||
static void Menu_RunInput_FileSelect_Movement(MenuFileSelect_t *object, MenuMovement_t direction);
|
||||
static void Menu_RunInput_FileSelect_Select(MenuFileSelect_t *object);
|
||||
|
||||
static int32_t M_RunMenu_Menu(Menu_t *cm, MenuMenu_t *menu, MenuEntry_t *currentry, int32_t state, const vec2_t origin)
|
||||
static int32_t M_RunMenu_Menu(Menu_t *cm, MenuMenu_t *menu, MenuEntry_t *currentry, int32_t state, const vec2_t origin, bool actually_draw)
|
||||
{
|
||||
int32_t totalHeight = 0;
|
||||
|
||||
|
@ -4245,7 +4382,9 @@ static int32_t M_RunMenu_Menu(Menu_t *cm, MenuMenu_t *menu, MenuEntry_t *current
|
|||
if (entry->format->width == 0)
|
||||
status |= MT_XCenter;
|
||||
|
||||
const int32_t dodraw = entry->type != Spacer && 0 <= y - menu->scrollPos + entry->font->get_yline() && y - menu->scrollPos <= klabs(menu->format->bottomcutoff) - menu->format->pos.y;
|
||||
bool const dodraw = entry->type != Spacer && actually_draw &&
|
||||
0 <= y - menu->scrollPos + entry->font->get_yline() &&
|
||||
y - menu->scrollPos <= klabs(menu->format->bottomcutoff) - menu->format->pos.y;
|
||||
|
||||
int32_t const height = entry->getHeight(); // max(textsize.y, entry->font->get_yline()); // bluefont Q ruins this
|
||||
status |= MT_YCenter;
|
||||
|
@ -4763,7 +4902,7 @@ static int32_t M_RunMenu_Menu(Menu_t *cm, MenuMenu_t *menu, MenuEntry_t *current
|
|||
{
|
||||
if (entry == currentry && object->editfield != NULL)
|
||||
{
|
||||
Menu_RunInput_EntryString_Submit(entry, object);
|
||||
Menu_RunInput_EntryString_Submit(/*entry, */object);
|
||||
|
||||
S_PlaySound(PISTOL_BODYHIT);
|
||||
|
||||
|
@ -4797,7 +4936,8 @@ static int32_t M_RunMenu_Menu(Menu_t *cm, MenuMenu_t *menu, MenuEntry_t *current
|
|||
}
|
||||
|
||||
// draw indicators if applicable
|
||||
Menu_RunScrollbar(cm, menu->format, y_upper + totalHeight, &menu->scrollPos, 320<<16, origin);
|
||||
if (actually_draw)
|
||||
Menu_RunScrollbar(cm, menu->format, y_upper + totalHeight, &menu->scrollPos, 320<<16, origin);
|
||||
}
|
||||
|
||||
return totalHeight;
|
||||
|
@ -4847,7 +4987,8 @@ static void Menu_RunOptionList(Menu_t *cm, MenuEntry_t *entry, MenuOption_t *obj
|
|||
if (object->options->entryFormat->width == 0)
|
||||
status |= MT_XCenter;
|
||||
|
||||
const int32_t dodraw = 0 <= y - object->options->scrollPos + object->options->font->get_yline() && y - object->options->scrollPos <= object->options->menuFormat->bottomcutoff - object->options->menuFormat->pos.y;
|
||||
bool const dodraw = 0 <= y - object->options->scrollPos + object->options->font->get_yline() &&
|
||||
y - object->options->scrollPos <= object->options->menuFormat->bottomcutoff - object->options->menuFormat->pos.y;
|
||||
|
||||
int32_t const height = object->options->font->get_yline(); // max(textsize.y, object->options->font->get_yline());
|
||||
status |= MT_YCenter;
|
||||
|
@ -5263,20 +5404,14 @@ or else this function will recurse infinitely.
|
|||
*/
|
||||
static MenuEntry_t *Menu_RunInput_Menu_MovementVerify(MenuMenu_t *menu)
|
||||
{
|
||||
MenuEntry_t *currentry = menu->entrylist[menu->currentEntry];
|
||||
|
||||
Menu_EntryFocus(/*currentry*/);
|
||||
|
||||
if (currentry->ybottom - menu->scrollPos > klabs(menu->format->bottomcutoff))
|
||||
menu->scrollPos = currentry->ybottom - klabs(menu->format->bottomcutoff);
|
||||
else if (currentry->ytop - menu->scrollPos < menu->format->pos.y)
|
||||
menu->scrollPos = currentry->ytop - menu->format->pos.y;
|
||||
|
||||
return currentry;
|
||||
return Menu_AdjustForCurrentEntryAssignment(menu);
|
||||
}
|
||||
|
||||
static MenuEntry_t *Menu_RunInput_Menu_Movement(MenuMenu_t *menu, MenuMovement_t direction)
|
||||
{
|
||||
if (menu->numEntries == 1)
|
||||
return menu->entrylist[menu->currentEntry];
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
case MM_End:
|
||||
|
@ -5631,7 +5766,10 @@ static void Menu_RunInput_EntryString_Activate(MenuEntry_t *entry)
|
|||
{
|
||||
MenuString_t *object = (MenuString_t*)entry->entry;
|
||||
|
||||
Bstrncpy(typebuf, object->variable, TYPEBUFSIZE);
|
||||
if (object->variable)
|
||||
strncpy(typebuf, object->variable, TYPEBUFSIZE);
|
||||
else
|
||||
typebuf[0] = '\0';
|
||||
object->editfield = typebuf;
|
||||
|
||||
// this limitation is an arbitrary implementation detail
|
||||
|
@ -5642,10 +5780,13 @@ static void Menu_RunInput_EntryString_Activate(MenuEntry_t *entry)
|
|||
WithSDL2_StartTextInput();
|
||||
}
|
||||
|
||||
static void Menu_RunInput_EntryString_Submit(MenuEntry_t *entry, MenuString_t *object)
|
||||
static void Menu_RunInput_EntryString_Submit(/*MenuEntry_t *entry, */MenuString_t *object)
|
||||
{
|
||||
if (!Menu_EntryStringSubmit(entry, object->editfield))
|
||||
Bstrncpy(object->variable, object->editfield, object->bufsize);
|
||||
if (!Menu_EntryStringSubmit(/*entry, */object->editfield))
|
||||
{
|
||||
if (object->variable)
|
||||
strncpy(object->variable, object->editfield, object->bufsize);
|
||||
}
|
||||
|
||||
object->editfield = NULL;
|
||||
WithSDL2_StopTextInput();
|
||||
|
@ -6249,7 +6390,7 @@ static void Menu_RunInput(Menu_t *cm)
|
|||
}
|
||||
else if (hitstate == 1)
|
||||
{
|
||||
Menu_RunInput_EntryString_Submit(currentry, object);
|
||||
Menu_RunInput_EntryString_Submit(/*currentry, */object);
|
||||
|
||||
S_PlaySound(PISTOL_BODYHIT);
|
||||
}
|
||||
|
|
|
@ -447,7 +447,6 @@ extern MenuAnimation_t m_animation;
|
|||
extern MenuID_t g_currentMenu;
|
||||
extern Menu_t *m_currentMenu;
|
||||
|
||||
extern int32_t g_lastSaveSlot;
|
||||
extern int32_t g_quitDeadline;
|
||||
extern int32_t voting;
|
||||
int Menu_Change(int32_t cm);
|
||||
|
|
|
@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#include "anim.h"
|
||||
#include "menus.h"
|
||||
#include "demo.h"
|
||||
#include "savegame.h"
|
||||
|
||||
#ifdef LUNATIC
|
||||
# include "lunatic_game.h"
|
||||
|
@ -1413,7 +1414,10 @@ end_vol4a:
|
|||
ud.from_bonus = 0;
|
||||
|
||||
ud.last_level = -1;
|
||||
g_lastSaveSlot = -1;
|
||||
g_lastAutoSaveArbitraryID = -1;
|
||||
g_lastautosave.reset();
|
||||
g_lastusersave.reset();
|
||||
g_quickload = nullptr;
|
||||
|
||||
#ifdef EDUKE32_TOUCH_DEVICES
|
||||
pPlayer->zoom = 360;
|
||||
|
|
|
@ -30,9 +30,9 @@ static int32_t g_savedOK;
|
|||
const char *g_failedVarname;
|
||||
#endif
|
||||
|
||||
extern char *bitptr;
|
||||
static OutputFileCounter savecounter;
|
||||
|
||||
uint8_t g_oldverSavegame[MAXSAVEGAMES];
|
||||
extern char *bitptr;
|
||||
|
||||
#define BITPTR_POINTER 1
|
||||
|
||||
|
@ -138,64 +138,88 @@ void G_ResetInterpolations(void)
|
|||
G_SetInterpolation(g_animatePtr[i]);
|
||||
}
|
||||
|
||||
void ReadSaveGameHeaders(void)
|
||||
{
|
||||
char fn[16];
|
||||
int32_t fil, i;
|
||||
savebrief_t g_lastautosave, g_lastusersave, g_freshload;
|
||||
int32_t g_lastAutoSaveArbitraryID = -1;
|
||||
bool g_saveRequested;
|
||||
savebrief_t * g_quickload;
|
||||
|
||||
menusave_t * g_menusaves;
|
||||
size_t g_nummenusaves;
|
||||
|
||||
static void ReadSaveGameHeaders_CACHE1D(CACHE1D_FIND_REC *f)
|
||||
{
|
||||
savehead_t h;
|
||||
|
||||
EDUKE32_STATIC_ASSERT(sizeof(h.savename) == sizeof(ud.savegame[0]));
|
||||
|
||||
Bstrcpy(fn, "save0.esv");
|
||||
|
||||
for (i=0; i<MAXSAVEGAMES; i++)
|
||||
for (; f != nullptr; f = f->next)
|
||||
{
|
||||
int32_t k;
|
||||
|
||||
fn[4] = i + '0';
|
||||
fil = kopen4loadfrommod(fn, 0);
|
||||
char const * fn = f->name;
|
||||
int32_t fil = kopen4loadfrommod(fn, 0);
|
||||
if (fil == -1)
|
||||
{
|
||||
Bmemset(ud.savegame[i], 0, sizeof(ud.savegame[i]));
|
||||
continue;
|
||||
}
|
||||
|
||||
k = sv_loadheader(fil, i, &h);
|
||||
menusave_t & msv = g_menusaves[g_nummenusaves];
|
||||
|
||||
int32_t k = sv_loadheader(fil, 0, &h);
|
||||
if (k)
|
||||
{
|
||||
// old version, signal to menu code
|
||||
if (k > 0)
|
||||
g_oldverSavegame[i] = 1;
|
||||
msv.isOldVer = 1;
|
||||
else
|
||||
continue;
|
||||
// else h.savename is all zeros (fatal failure, like wrong header
|
||||
// magic or too short header)
|
||||
}
|
||||
else
|
||||
msv.isOldVer = 0;
|
||||
|
||||
if (k >= 0)
|
||||
Bmemcpy(ud.savegame[i], h.savename, sizeof(ud.savegame[i]));
|
||||
if (k >= 0 && h.savename[0] != '\0')
|
||||
{
|
||||
memcpy(msv.brief.name, h.savename, ARRAY_SIZE(msv.brief.name));
|
||||
strncpy(msv.brief.path, fn, ARRAY_SIZE(msv.brief.path));
|
||||
|
||||
++g_nummenusaves;
|
||||
}
|
||||
|
||||
kclose(fil);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t G_LoadSaveHeaderNew(int32_t spot, savehead_t *saveh)
|
||||
static size_t countcache1dfind(CACHE1D_FIND_REC *f)
|
||||
{
|
||||
char fn[16];
|
||||
int32_t fil, screenshotofs, i;
|
||||
size_t x = 0;
|
||||
for (; f != nullptr; f = f->next)
|
||||
++x;
|
||||
return x;
|
||||
}
|
||||
|
||||
Bassert(spot < MAXSAVEGAMES);
|
||||
void ReadSaveGameHeaders(void)
|
||||
{
|
||||
static char const DefaultPath[] = "/", SavePattern[] = "*.esv";
|
||||
|
||||
Bstrcpy(fn, "save0.esv");
|
||||
fn[4] = spot + '0';
|
||||
CACHE1D_FIND_REC *findfiles_default = klistpath(DefaultPath, SavePattern, CACHE1D_FIND_FILE);
|
||||
|
||||
fil = kopen4loadfrommod(fn, 0);
|
||||
// potentially overallocating but programmatically simple
|
||||
size_t const numfiles = countcache1dfind(findfiles_default);
|
||||
g_menusaves = (menusave_t *)Xrealloc(g_menusaves, sizeof(menusave_t) * numfiles);
|
||||
|
||||
g_nummenusaves = 0;
|
||||
ReadSaveGameHeaders_CACHE1D(findfiles_default);
|
||||
|
||||
klistfree(findfiles_default);
|
||||
}
|
||||
|
||||
int32_t G_LoadSaveHeaderNew(char const *fn, savehead_t *saveh)
|
||||
{
|
||||
int32_t fil = kopen4loadfrommod(fn, 0);
|
||||
if (fil == -1)
|
||||
return -1;
|
||||
|
||||
i = sv_loadheader(fil, spot, saveh);
|
||||
int32_t i = sv_loadheader(fil, 0, saveh);
|
||||
if (i < 0)
|
||||
goto corrupt;
|
||||
|
||||
int32_t screenshotofs;
|
||||
if (kread(fil, &screenshotofs, 4) != 4)
|
||||
goto corrupt;
|
||||
|
||||
|
@ -208,7 +232,7 @@ int32_t G_LoadSaveHeaderNew(int32_t spot, savehead_t *saveh)
|
|||
{
|
||||
if (kdfread((char *)waloff[TILE_LOADSHOT], 320, 200, fil) != 200)
|
||||
{
|
||||
OSD_Printf("G_LoadSaveHeaderNew(%d): failed reading screenshot\n", spot);
|
||||
OSD_Printf("G_LoadSaveHeaderNew(): failed reading screenshot \"%s\"\n", fn);
|
||||
goto corrupt;
|
||||
}
|
||||
}
|
||||
|
@ -230,25 +254,17 @@ corrupt:
|
|||
static void sv_postudload();
|
||||
|
||||
// XXX: keyboard input 'blocked' after load fail? (at least ESC?)
|
||||
int32_t G_LoadPlayer(int32_t spot)
|
||||
int32_t G_LoadPlayer(savebrief_t & sv)
|
||||
{
|
||||
char fn[16];
|
||||
int32_t fil, i;
|
||||
|
||||
savehead_t h;
|
||||
|
||||
Bassert(spot < MAXSAVEGAMES);
|
||||
|
||||
Bstrcpy(fn, "save0.esv");
|
||||
fn[4] = spot + '0';
|
||||
|
||||
fil = kopen4loadfrommod(fn, 0);
|
||||
int32_t fil = kopen4loadfrommod(sv.path, 0);
|
||||
if (fil == -1)
|
||||
return -1;
|
||||
|
||||
ready2send = 0;
|
||||
|
||||
i = sv_loadheader(fil, spot, &h);
|
||||
int32_t i = sv_loadheader(fil, 0, &h);
|
||||
if ((i < 0) || h.numplayers != ud.multimode)
|
||||
{
|
||||
if (i == -4 || i == -3 || i == 1)
|
||||
|
@ -283,12 +299,6 @@ int32_t G_LoadPlayer(int32_t spot)
|
|||
FX_StopAllSounds();
|
||||
S_ClearSoundLocks();
|
||||
|
||||
if (spot >= 0 && numplayers==1)
|
||||
{
|
||||
Bmemcpy(ud.savegame[spot], h.savename, sizeof(ud.savegame[0]));
|
||||
ud.savegame[spot][sizeof(ud.savegame[0])-1] = 0;
|
||||
}
|
||||
|
||||
// non-"m_" fields will be loaded from svgm_udnetw
|
||||
ud.m_volume_number = h.volnum;
|
||||
ud.m_level_number = h.levnum;
|
||||
|
@ -321,12 +331,12 @@ int32_t G_LoadPlayer(int32_t spot)
|
|||
else
|
||||
{
|
||||
// read the rest...
|
||||
i = sv_loadsnapshot(fil, spot, &h);
|
||||
i = sv_loadsnapshot(fil, 0, &h);
|
||||
if (i)
|
||||
{
|
||||
// in theory, we could load into an initial dump first and trivially
|
||||
// recover if things go wrong...
|
||||
Bsprintf(tempbuf, "Loading save game file \"%s\" failed (code %d), cannot recover.", fn, i);
|
||||
Bsprintf(tempbuf, "Loading save game file \"%s\" failed (code %d), cannot recover.", sv.path, i);
|
||||
G_GameExit(tempbuf);
|
||||
}
|
||||
}
|
||||
|
@ -395,44 +405,52 @@ static void G_SavePalette(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
int32_t G_SavePlayer(int32_t spot)
|
||||
int32_t G_SavePlayer(savebrief_t & sv)
|
||||
{
|
||||
char fn[16];
|
||||
FILE *fil;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
G_SavePalette();
|
||||
#endif
|
||||
|
||||
Bassert(spot < MAXSAVEGAMES);
|
||||
|
||||
G_SaveTimers();
|
||||
|
||||
Bstrcpy(fn, "save0.esv");
|
||||
fn[4] = spot + '0';
|
||||
|
||||
// Bstrcpy(mpfn, "edukA_00.esv");
|
||||
|
||||
Net_WaitForServer();
|
||||
ready2send = 0;
|
||||
|
||||
char temp[BMAX_PATH];
|
||||
|
||||
errno = 0;
|
||||
FILE *fil;
|
||||
|
||||
if (sv.isValid())
|
||||
{
|
||||
char temp[BMAX_PATH];
|
||||
|
||||
if (G_ModDirSnprintf(temp, sizeof(temp), "%s", fn))
|
||||
if (G_ModDirSnprintf(temp, sizeof(temp), "%s", sv.path))
|
||||
{
|
||||
OSD_Printf("G_SavePlayer: file name \"%s\" too long\n", fn);
|
||||
return -1;
|
||||
OSD_Printf("G_SavePlayer: file name \"%s\" too long\n", sv.path);
|
||||
goto saveproblem;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
fil = fopen(temp, "wb");
|
||||
if (!fil)
|
||||
}
|
||||
else
|
||||
{
|
||||
static char const SaveName[] = "save0000.esv";
|
||||
size_t len = G_ModDirSnprintfLite(temp, sizeof(temp), SaveName);
|
||||
if (len >= sizeof(temp)-1)
|
||||
{
|
||||
OSD_Printf("G_SavePlayer: failed opening \"%s\" for writing: %s\n",
|
||||
temp, strerror(errno));
|
||||
return -1;
|
||||
OSD_Printf("G_SavePlayer: could not form automatic save path\n");
|
||||
goto saveproblem;
|
||||
}
|
||||
char * zeros = temp + (len-8);
|
||||
fil = savecounter.opennextfile(temp, zeros);
|
||||
savecounter.count++;
|
||||
// don't copy the mod dir into sv.path
|
||||
strcpy(sv.path, temp + (len-(ARRAY_SIZE(SaveName)-1)));
|
||||
}
|
||||
|
||||
if (!fil)
|
||||
{
|
||||
OSD_Printf("G_SavePlayer: failed opening \"%s\" for writing: %s\n",
|
||||
temp, strerror(errno));
|
||||
goto saveproblem;
|
||||
}
|
||||
|
||||
#ifdef POLYMER
|
||||
|
@ -443,7 +461,7 @@ int32_t G_SavePlayer(int32_t spot)
|
|||
VM_OnEvent(EVENT_SAVEGAME, g_player[screenpeek].ps->i, screenpeek);
|
||||
|
||||
// SAVE!
|
||||
sv_saveandmakesnapshot(fil, spot, 0, 0, 0);
|
||||
sv_saveandmakesnapshot(fil, sv.name, 0, 0, 0, 0);
|
||||
|
||||
fclose(fil);
|
||||
|
||||
|
@ -467,41 +485,46 @@ int32_t G_SavePlayer(int32_t spot)
|
|||
VM_OnEvent(EVENT_POSTSAVEGAME, g_player[screenpeek].ps->i, screenpeek);
|
||||
|
||||
return 0;
|
||||
|
||||
saveproblem:
|
||||
ready2send = 1;
|
||||
Net_WaitForServer();
|
||||
|
||||
G_RestoreTimers();
|
||||
ototalclock = totalclock;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void G_LoadPlayerMaybeMulti(int32_t slot)
|
||||
void G_LoadPlayerMaybeMulti(savebrief_t & sv)
|
||||
{
|
||||
if (g_netServer || ud.multimode > 1)
|
||||
{
|
||||
Bstrcpy(apStrings[QUOTE_RESERVED4], "Multiplayer Loading Not Yet Supported");
|
||||
P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps);
|
||||
|
||||
// G_LoadPlayer(-1-g_lastSaveSlot);
|
||||
// g_player[myconnectindex].ps->gm = MODE_GAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
int32_t c = G_LoadPlayer(slot);
|
||||
int32_t c = G_LoadPlayer(sv);
|
||||
if (c == 0)
|
||||
g_player[myconnectindex].ps->gm = MODE_GAME;
|
||||
}
|
||||
}
|
||||
|
||||
void G_SavePlayerMaybeMulti(int32_t slot)
|
||||
void G_SavePlayerMaybeMulti(savebrief_t & sv)
|
||||
{
|
||||
Bassert(slot >= 0);
|
||||
|
||||
CONFIG_WriteSetup(2);
|
||||
|
||||
if (g_netServer || ud.multimode > 1)
|
||||
{
|
||||
Bstrcpy(apStrings[QUOTE_RESERVED4], "Multiplayer Saving Not Yet Supported");
|
||||
P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps);
|
||||
// G_SavePlayer(-1-slot);
|
||||
}
|
||||
else
|
||||
{
|
||||
G_SavePlayer(slot);
|
||||
G_SavePlayer(sv);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1283,7 +1306,7 @@ static void SV_AllocSnap(int32_t allocinit)
|
|||
}
|
||||
|
||||
// make snapshot only if spot < 0 (demo)
|
||||
int32_t sv_saveandmakesnapshot(FILE *fil, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress)
|
||||
int32_t sv_saveandmakesnapshot(FILE *fil, char const *name, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress)
|
||||
{
|
||||
savehead_t h;
|
||||
|
||||
|
@ -1338,10 +1361,10 @@ int32_t sv_saveandmakesnapshot(FILE *fil, int8_t spot, int8_t recdiffsp, int8_t
|
|||
}
|
||||
}
|
||||
|
||||
if ((unsigned)spot < MAXSAVEGAMES)
|
||||
if (spot >= 0)
|
||||
{
|
||||
// savegame
|
||||
Bstrncpyz(h.savename, ud.savegame[spot], sizeof(h.savename));
|
||||
Bstrncpyz(h.savename, name, sizeof(h.savename));
|
||||
#ifdef __ANDROID__
|
||||
Bstrncpyz(h.volname, g_volumeNames[ud.volume_number], sizeof(h.volname));
|
||||
Bstrncpyz(h.skillname, g_skillNames[ud.player_skill], sizeof(h.skillname));
|
||||
|
@ -1414,8 +1437,6 @@ int32_t sv_saveandmakesnapshot(FILE *fil, int8_t spot, int8_t recdiffsp, int8_t
|
|||
}
|
||||
}
|
||||
|
||||
g_oldverSavegame[spot] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -61,19 +61,55 @@ typedef struct
|
|||
} savehead_t;
|
||||
#pragma pack(pop)
|
||||
|
||||
struct savebrief_t
|
||||
{
|
||||
savebrief_t() = default;
|
||||
savebrief_t(char const *n)
|
||||
{
|
||||
strncpy(name, n, MAXSAVEGAMENAME);
|
||||
}
|
||||
|
||||
char name[MAXSAVEGAMENAMESTRUCT];
|
||||
char path[BMAX_PATH];
|
||||
|
||||
void reset()
|
||||
{
|
||||
name[0] = '\0';
|
||||
path[0] = '\0';
|
||||
}
|
||||
bool isValid() const
|
||||
{
|
||||
return path[0] != '\0';
|
||||
}
|
||||
};
|
||||
|
||||
struct menusave_t
|
||||
{
|
||||
savebrief_t brief;
|
||||
uint8_t isOldVer = 0;
|
||||
};
|
||||
|
||||
extern savebrief_t g_lastautosave, g_lastusersave, g_freshload;
|
||||
extern int32_t g_lastAutoSaveArbitraryID;
|
||||
extern bool g_saveRequested;
|
||||
extern savebrief_t * g_quickload;
|
||||
|
||||
extern menusave_t * g_menusaves;
|
||||
extern size_t g_nummenusaves;
|
||||
|
||||
int32_t sv_updatestate(int32_t frominit);
|
||||
int32_t sv_readdiff(int32_t fil);
|
||||
uint32_t sv_writediff(FILE *fil);
|
||||
int32_t sv_loadheader(int32_t fil, int32_t spot, savehead_t *h);
|
||||
int32_t sv_loadsnapshot(int32_t fil, int32_t spot, savehead_t *h);
|
||||
int32_t sv_saveandmakesnapshot(FILE *fil, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress);
|
||||
int32_t sv_saveandmakesnapshot(FILE *fil, char const *name, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress);
|
||||
void sv_freemem();
|
||||
int32_t G_SavePlayer(int32_t spot);
|
||||
int32_t G_LoadPlayer(int32_t spot);
|
||||
int32_t G_LoadSaveHeaderNew(int32_t spot, savehead_t *saveh);
|
||||
int32_t G_SavePlayer(savebrief_t & sv);
|
||||
int32_t G_LoadPlayer(savebrief_t & sv);
|
||||
int32_t G_LoadSaveHeaderNew(char const *fn, savehead_t *saveh);
|
||||
void ReadSaveGameHeaders(void);
|
||||
void G_SavePlayerMaybeMulti(int32_t slot);
|
||||
void G_LoadPlayerMaybeMulti(int32_t slot);
|
||||
void G_SavePlayerMaybeMulti(savebrief_t & sv);
|
||||
void G_LoadPlayerMaybeMulti(savebrief_t & sv);
|
||||
|
||||
#ifdef YAX_ENABLE
|
||||
extern void sv_postyaxload(void);
|
||||
|
@ -82,7 +118,6 @@ extern void sv_postyaxload(void);
|
|||
// XXX: The 'bitptr' decl really belongs into gamedef.h, but we don't want to
|
||||
// pull all of it in savegame.c?
|
||||
extern char *bitptr;
|
||||
extern uint8_t g_oldverSavegame[MAXSAVEGAMES];
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue