WIP safety commit

This commit is contained in:
Christoph Oelckers 2019-11-30 19:23:54 +01:00
parent 9cb6c65223
commit 2a9e4fca46
37 changed files with 772 additions and 903 deletions

View file

@ -762,38 +762,6 @@ void StartNetworkLevel(void)
int gDoQuickSave = 0;
static void DoQuickLoad(void)
{
if (!gGameMenuMgr.m_bActive)
{
if (gQuickLoadSlot != -1)
{
QuickLoadGame();
return;
}
if (gQuickLoadSlot == -1 && gQuickSaveSlot != -1)
{
gQuickLoadSlot = gQuickSaveSlot;
QuickLoadGame();
return;
}
gGameMenuMgr.Push(&menuLoadGame,-1);
}
}
static void DoQuickSave(void)
{
if (gGameStarted && !gGameMenuMgr.m_bActive && gPlayer[myconnectindex].pXSprite->health != 0)
{
if (gQuickSaveSlot != -1)
{
QuickSaveGame();
return;
}
gGameMenuMgr.Push(&menuSaveGame,-1);
}
}
void LocalKeys(void)
{
bool alt = inputState.AltPressed();
@ -831,21 +799,6 @@ void LocalKeys(void)
gView = &gPlayer[gViewIndex];
}
}
if (gDoQuickSave)
{
inputState.keyFlushScans();
switch (gDoQuickSave)
{
case 1:
DoQuickSave();
break;
case 2:
DoQuickLoad();
break;
}
gDoQuickSave = 0;
return;
}
char key;
if ((key = inputState.keyGetScan()) != 0)
{
@ -914,19 +867,11 @@ void LocalKeys(void)
if (!gGameMenuMgr.m_bActive)
gGameMenuMgr.Push(&menuOptions,-1);
return;
case sc_F6:
inputState.keyFlushScans();
DoQuickSave();
break;
case sc_F8:
inputState.keyFlushScans();
if (!gGameMenuMgr.m_bActive)
gGameMenuMgr.Push(&menuOptionsDisplayMode, -1);
return;
case sc_F9:
inputState.keyFlushScans();
DoQuickLoad();
break;
case sc_F10:
inputState.keyFlushScans();
if (!gGameMenuMgr.m_bActive)

View file

@ -2055,9 +2055,6 @@ void TenProcess(CGameMenuItem7EA1C *pItem)
UNREFERENCED_PARAMETER(pItem);
}
short gQuickLoadSlot = -1;
short gQuickSaveSlot = -1;
void SaveGame(CGameMenuItemZEditBitmap *pItem, CGameMenuEvent *event)
{
int nSlot = pItem->at28;
@ -2077,31 +2074,6 @@ void SaveGame(CGameMenuItemZEditBitmap *pItem, CGameMenuEvent *event)
videoNextPage();
gSaveGameNum = nSlot;
LoadSave::SaveGame(strSaveGameName.GetChars());
gQuickSaveSlot = nSlot;
gGameMenuMgr.Deactivate();
}
void QuickSaveGame(void)
{
if (gGameOptions.nGameType > 0 || !gGameStarted)
return;
/*if (strSaveGameName[0])
{
gGameMenuMgr.Deactivate();
return;
}*/
FStringf basename("save%04d", gQuickSaveSlot);
auto strSaveGameName = G_BuildSaveName(basename);
strcpy(gGameOptions.szUserGameName, strRestoreGameStrings[gQuickSaveSlot]);
sprintf(gGameOptions.szSaveGameName, "%s", strSaveGameName.GetChars());
gGameOptions.nSaveGameSlot = gQuickSaveSlot;
viewLoadingScreen(2518, "Saving", "Saving Your Game", strRestoreGameStrings[gQuickSaveSlot]);
videoNextPage();
LoadSave::SaveGame(strSaveGameName);
gGameOptions.picEntry = gSavedOffset;
gSaveGameOptions[gQuickSaveSlot] = gGameOptions;
UpdateSavedInfo(gQuickSaveSlot);
gGameMenuMgr.Deactivate();
}
@ -2119,22 +2091,6 @@ void LoadGame(CGameMenuItemZEditBitmap *pItem, CGameMenuEvent *event)
videoNextPage();
LoadSave::LoadGame(strLoadGameName);
gGameMenuMgr.Deactivate();
gQuickLoadSlot = nSlot;
}
void QuickLoadGame(void)
{
if (gGameOptions.nGameType > 0)
return;
FStringf basename("save%04d", gQuickSaveSlot);
auto strLoadGameName = G_BuildSaveName(basename);
if (!FileExists(strLoadGameName))
return;
viewLoadingScreen(2518, "Loading", "Loading Saved Game", strRestoreGameStrings[gQuickLoadSlot]);
videoNextPage();
LoadSave::LoadGame(strLoadGameName);
gGameMenuMgr.Deactivate();
}
void SetupLevelMenuItem(int nEpisode)

View file

@ -51,13 +51,9 @@ extern CGameMenu menuSorry2;
extern CGameMenu menuOptions;
extern CGameMenu menuOptionsSound;
extern CGameMenu menuOptionsDisplayMode;
extern short gQuickLoadSlot;
extern short gQuickSaveSlot;
extern char strRestoreGameStrings[][16];
void drawLoadingScreen(void);
void SetupMenus(void);
void UpdateNetworkMenus(void);
void QuickSaveGame(void);
void QuickLoadGame(void);
END_BLD_NS

View file

@ -371,23 +371,6 @@ void onvideomodechange(int32_t newmode)
UpdateDacs(gLastPal, false);
}
static int osdcmd_quicksave(osdcmdptr_t UNUSED(parm))
{
UNREFERENCED_CONST_PARAMETER(parm);
if (!gGameStarted || gDemo.at1 || gGameMenuMgr.m_bActive)
OSD_Printf("quicksave: not in a game.\n");
else gDoQuickSave = 1;
return OSDCMD_OK;
}
static int osdcmd_quickload(osdcmdptr_t UNUSED(parm))
{
UNREFERENCED_CONST_PARAMETER(parm);
if (!gGameStarted || gDemo.at1 || gGameMenuMgr.m_bActive)
OSD_Printf("quickload: not in a game.\n");
else gDoQuickSave = 2;
return OSDCMD_OK;
}
#if 0
@ -435,8 +418,6 @@ int32_t registerosdcommands(void)
OSD_RegisterFunction("give","give <all|health|weapons|ammo|armor|keys|inventory>: gives requested item", osdcmd_give);
OSD_RegisterFunction("god","god: toggles god mode", osdcmd_god);
OSD_RegisterFunction("noclip","noclip: toggles clipping mode", osdcmd_noclip);
OSD_RegisterFunction("quicksave","quicksave: performs a quick save", osdcmd_quicksave);
OSD_RegisterFunction("quickload","quickload: performs a quick load", osdcmd_quickload);
OSD_RegisterFunction("restartsound","restartsound: reinitializes the sound system",osdcmd_restartsound);
OSD_RegisterFunction("vidmode","vidmode <xdim> <ydim> <bpp> <fullscreen>: change the video mode",osdcmd_vidmode);

View file

@ -185,6 +185,22 @@ struct FSavegameInfo
int currentsavever;
};
struct FSaveGameNode
{
FString SaveTitle;
FString Filename;
bool bOldVersion = false;
bool bMissingWads = false;
bool bNoDelete = false;
bool bIsExt = false;
bool isValid() const
{
return Filename.IsNotEmpty() && !bOldVersion && !bMissingWads;
}
};
enum EMenuSounds : int;
struct GameInterface
@ -210,8 +226,8 @@ struct GameInterface
virtual bool DrawSpecialScreen(const DVector2 &origin, int tilenum) { return false; }
virtual void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position) {}
virtual void DrawMenuCaption(const DVector2& origin, const char* text) {}
virtual bool SaveGame(FSaveGameNode*) { return false; }
virtual bool LoadGame(FSaveGameNode*) { return false; }
};
extern GameInterface* gi;

View file

@ -10045,7 +10045,7 @@ void videoNextPage(void)
if (!recursion)
{
// This protection is needed because the menu can call scripts and the scripts can call the busy-looping Screen_Play script event
// This protection is needed because the menu can call scripts from inside its drawers and the scripts can call the busy-looping Screen_Play script event
// which calls videoNextPage for page flipping again. In this loop the UI drawers may not get called again.
// Ideally this stuff should be moved out of videoNextPage so that all those busy loops won't call UI overlays at all.
recursion = true;

View file

@ -106,8 +106,6 @@ static const ButtonDesc gamefuncs[] = {
{ gamefunc_Dpad_Aiming, "Dpad_Aiming"},
{ gamefunc_AutoRun, "AutoRun"},
{ gamefunc_Last_Weapon, "Last_Used_Weapon"},
{ gamefunc_Quick_Save, "Quick_Save"},
{ gamefunc_Quick_Load, "Quick_Load"},
{ gamefunc_Alt_Weapon, "Alt_Weapon"},
{ gamefunc_Third_Person_View, "Third_Person_View"},
{ gamefunc_Toggle_Crouch, "Toggle_Crouch"},

View file

@ -72,8 +72,6 @@ enum GameFunction_t
gamefunc_Dpad_Aiming,
gamefunc_AutoRun,
gamefunc_Last_Weapon,
gamefunc_Quick_Save,
gamefunc_Quick_Load,
gamefunc_Alt_Weapon,
gamefunc_Third_Person_View,
gamefunc_See_Chase_View = gamefunc_Third_Person_View, // this was added by Blood

View file

@ -360,6 +360,9 @@ void M_StartControlPanel (bool makeSound)
created = true;
M_CreateMenus();
}
FX_StopAllSounds();
gi->MenuOpened();
if (makeSound) gi->MenuSound(ActivateSound);
buttonMap.ResetButtonStates ();
inputState.ClearAllKeyStatus();
@ -964,10 +967,8 @@ CCMD(reset2saved)
CCMD(openmainmenu)
{
FX_StopAllSounds();
//gi->ClearSoundLocks();
//gi->MenuSound();
M_StartControlPanel(false);
M_StartControlPanel(true);
M_SetMenu(NAME_IngameMenu);
}
@ -975,8 +976,7 @@ CCMD(openhelpmenu)
{
if (!help_disabled)
{
gi->MenuOpened();
M_StartControlPanel(false);
M_StartControlPanel(true);
M_SetMenu(NAME_HelpMenu);
}
}
@ -985,15 +985,13 @@ CCMD(opensavemenu)
{
if (gi->CanSave())
{
gi->MenuOpened();
M_StartControlPanel(false);
M_StartControlPanel(true);
M_SetMenu(NAME_SaveGameMenu);
}
}
CCMD(openloadmenu)
{
gi->MenuOpened();
M_StartControlPanel(false);
M_StartControlPanel(true);
M_SetMenu(NAME_LoadGameMenu);
}

View file

@ -94,6 +94,7 @@ enum EMenuState : int
enum EMenuSounds : int
{
ActivateSound,
CursorSound,
AdvanceSound,
BackSound,
@ -742,6 +743,7 @@ void M_NotifyNewSave (const char *file, const char *title, bool okForQuicksave);
void M_StartMessage(const char *message, int messagemode, int scriptId, FName action = NAME_None);
void M_UnhideCustomMenu(int menu, int itemmask);
void M_MenuSound(EMenuSounds snd);
void M_Autosave();
void I_SetMouseCapture();
@ -750,6 +752,10 @@ void I_ReleaseMouseCapture();
struct MenuClassDescriptor;
extern TArray<MenuClassDescriptor*> menuClasses;
using hFunc = std::function<void(bool)>;
DMenu* CreateMessageBoxMenu(DMenu* parent, const char* message, int messagemode, int scriptID, bool playsound, FName action = NAME_None, hFunc handler = nullptr);
struct MenuClassDescriptor
{
FName mName;
@ -772,15 +778,6 @@ template<class Menu> struct TMenuClassDescriptor : public MenuClassDescriptor
};
struct FSaveGameNode
{
FString SaveTitle;
FString Filename;
bool bOldVersion = false;
bool bMissingWads = false;
bool bNoDelete = false;
};
struct FSavegameManager
{
private:
@ -819,6 +816,9 @@ public:
void InsertNewSaveNode();
bool RemoveNewSaveNode();
void LoadGame(FSaveGameNode* node, bool ok4q, bool forceq);
void SaveGame(FSaveGameNode* node);
};
extern FSavegameManager savegameManager;

View file

@ -32,7 +32,7 @@
**
*/
#include "menu/menu.h"
#include "menu.h"
#include "d_event.h"
#include "d_gui.h"
#include "v_text.h"
@ -41,7 +41,6 @@
#include "c_dispatch.h"
#include "v_2ddrawer.h"
extern FSaveGameNode *quickSaveSlot;
class DMessageBoxMenu : public DMenu
@ -52,10 +51,11 @@ class DMessageBoxMenu : public DMenu
int messageSelection;
int mMouseLeft, mMouseRight, mMouseY;
FName mAction;
std::function<void(bool)> mActionFunc;
public:
DMessageBoxMenu(DMenu *parent = NULL, const char *message = NULL, int messagemode = 0, bool playsound = false, FName action = NAME_None);
DMessageBoxMenu(DMenu *parent = NULL, const char *message = NULL, int messagemode = 0, bool playsound = false, FName action = NAME_None, hFunc handler = nullptr);
void Destroy();
void Init(DMenu *parent, const char *message, int messagemode, bool playsound = false);
void Drawer();
@ -73,10 +73,11 @@ public:
//
//=============================================================================
DMessageBoxMenu::DMessageBoxMenu(DMenu *parent, const char *message, int messagemode, bool playsound, FName action)
DMessageBoxMenu::DMessageBoxMenu(DMenu *parent, const char *message, int messagemode, bool playsound, FName action, hFunc handler)
: DMenu(parent)
{
mAction = action;
mActionFunc = handler;
messageSelection = 0;
mMouseLeft = 140;
mMouseY = INT_MIN;
@ -128,7 +129,7 @@ void DMessageBoxMenu::Destroy()
void DMessageBoxMenu::CloseSound()
{
//S_Sound (CHAN_VOICE | CHAN_UI, DMenu::CurrentMenu != NULL? "menu/backup" : "menu/dismiss", snd_menuvolume, ATTN_NONE);
M_MenuSound(DMenu::CurrentMenu ? BackSound : ::CloseSound);
}
//=============================================================================
@ -143,7 +144,12 @@ void DMessageBoxMenu::HandleResult(bool res)
{
if (mMessageMode == 0)
{
if (mAction == NAME_None)
if (mActionFunc)
{
mActionFunc(res);
Close();
}
else if (mAction == NAME_None)
{
mParentMenu->MenuEvent(res? MKEY_MBYes : MKEY_MBNo, false);
Close();
@ -358,3 +364,17 @@ void M_StartMessage(const char *message, int messagemode, int scriptId, FName ac
M_ActivateMenu(newmenu);
}
//=============================================================================
//
//
//
//=============================================================================
DMenu* CreateMessageBoxMenu(DMenu* parent, const char* message, int messagemode, int scriptId, bool playsound, FName action = NAME_None, hFunc handler)
{
auto newmenu = new DMessageBoxMenu(DMenu::CurrentMenu, message, messagemode, false, action, handler);
newmenu->scriptID = scriptId;
return newmenu;
}

View file

@ -49,11 +49,27 @@
#include "files.h"
#include "savegamehelp.h"
#include "i_specialpaths.h"
#include "c_dispatch.h"
#include "../../platform/win32/i_findfile.h" // This is a temporary direct path. Needs to be fixed when stuff gets cleaned up.
FSavegameManager savegameManager;
void FSavegameManager::LoadGame(FSaveGameNode* node, bool ok4q, bool forceq)
{
if (gi->LoadGame(node))
{
FString fn = node->Filename;
FString desc = node->SaveTitle;
NotifyNewSave(fn, desc, ok4q, forceq);
}
}
void FSavegameManager::SaveGame(FSaveGameNode* node)
{
gi->SaveGame(node);
}
//=============================================================================
//
// Save data maintenance
@ -261,7 +277,7 @@ void FSavegameManager::NotifyNewSave(const FString &file, const FString &title,
void FSavegameManager::LoadSavegame(int Selected)
{
//G_LoadGame(SaveGames[Selected]->Filename.GetChars(), true);
savegameManager.LoadGame(SaveGames[Selected]);
if (quickSaveSlot == (FSaveGameNode*)1)
{
quickSaveSlot = SaveGames[Selected];
@ -281,8 +297,9 @@ void FSavegameManager::DoSave(int Selected, const char *savegamestring)
{
if (Selected != 0)
{
auto node = SaveGames[Selected];
//G_SaveGame(node->Filename.GetChars(), savegamestring);
auto node = *SaveGames[Selected];
node.SaveTitle = savegamestring;
savegameManager.SaveGame(&node);
}
else
{
@ -298,7 +315,8 @@ void FSavegameManager::DoSave(int Selected, const char *savegamestring)
break;
}
}
//G_SaveGame(filename, savegamestring);
FSaveGameNode sg{ savegamestring, filename };
savegameManager.SaveGame(&sg);
}
M_ClearMenus();
}
@ -505,3 +523,575 @@ bool FSavegameManager::RemoveNewSaveNode()
return false;
}
//=============================================================================
//
//
//
//=============================================================================
CVAR(Bool, saveloadconfirmation, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CVAR(Int, autosavenum, 0, CVAR_NOSET | CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
static int nextautosave = -1;
CVAR(Int, disableautosave, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CUSTOM_CVAR(Int, autosavecount, 4, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
{
if (self < 1)
self = 1;
}
CVAR(Int, quicksavenum, 0, CVAR_NOSET | CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
static int nextquicksave = -1;
CUSTOM_CVAR(Int, quicksavecount, 4, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
{
if (self < 1)
self = 1;
}
void M_Autosave()
{
if (!gi->CanSave()) return;
FString description;
FString file;
// Keep a rotating sets of autosaves
UCVarValue num;
const char* readableTime;
int count = autosavecount != 0 ? autosavecount : 1;
if (nextautosave == -1)
{
nextautosave = (autosavenum + 1) % count;
}
num.Int = nextautosave;
autosavenum.ForceSet(num, CVAR_Int);
FSaveGameNode sg;
sg.Filename = G_BuildSaveName(FStringf("auto%04d", nextautosave));
readableTime = myasctime();
sg.SaveTitle.Format("Autosave %s", readableTime);
nextautosave = (nextautosave + 1) % count;
savegameManager.SaveGame(&sg);
}
CCMD(autosave)
{
if (disableautosave) return;
M_Autosave();
}
CCMD(rotatingquicksave)
{
if (!gi->CanSave()) return;
FString description;
FString file;
// Keep a rotating sets of quicksaves
UCVarValue num;
const char* readableTime;
int count = quicksavecount != 0 ? quicksavecount : 1;
if (nextquicksave == -1)
{
nextquicksave = (quicksavenum + 1) % count;
}
num.Int = nextquicksave;
quicksavenum.ForceSet(num, CVAR_Int);
FSaveGameNode sg;
sg.Filename = G_BuildSaveName(FStringf("quick%04d", nextquicksave));
readableTime = myasctime();
sg.SaveTitle.Format("Quicksave %s", readableTime);
nextquicksave = (nextquicksave + 1) % count;
savegameManager.SaveGame(&sg);
}
//=============================================================================
//
//
//
//=============================================================================
CCMD(quicksave)
{ // F6
if (!gi->CanSave()) return;
if (savegameManager.quickSaveSlot == NULL || savegameManager.quickSaveSlot == (FSaveGameNode*)1)
{
M_StartControlPanel(true);
M_SetMenu(NAME_SaveGameMenu);
return;
}
auto slot = savegameManager.quickSaveSlot;
// [mxd]. Just save the game, no questions asked.
if (!saveloadconfirmation)
{
savegameManager.SaveGame(savegameManager.quickSaveSlot);
return;
}
gi->MenuSound(ActivateSound);
FString tempstring = GStrings("QSPROMPT");
tempstring.Substitute("%s", slot->SaveTitle.GetChars());
DMenu* newmenu = CreateMessageBoxMenu(DMenu::CurrentMenu, tempstring, 0, INT_MAX, false, NAME_None, [](bool res)
{
if (res)
{
savegameManager.SaveGame(savegameManager.quickSaveSlot);
}
});
M_ActivateMenu(newmenu);
}
//=============================================================================
//
//
//
//=============================================================================
CCMD(quickload)
{ // F9
#if 0
if (netgame)
{
M_StartControlPanel(true);
M_StartMessage(GStrings("QLOADNET"), 1);
return;
}
#endif
if (savegameManager.quickSaveSlot == nullptr || savegameManager.quickSaveSlot == (FSaveGameNode*)1)
{
M_StartControlPanel(true);
// signal that whatever gets loaded should be the new quicksave
savegameManager.quickSaveSlot = (FSaveGameNode*)1;
M_SetMenu(NAME_LoadGameMenu);
return;
}
// [mxd]. Just load the game, no questions asked.
if (!saveloadconfirmation)
{
savegameManager.LoadGame(savegameManager.quickSaveSlot);
return;
}
FString tempstring = GStrings("QLPROMPT");
tempstring.Substitute("%s", savegameManager.quickSaveSlot->SaveTitle.GetChars());
M_StartControlPanel(true);
DMenu* newmenu = CreateMessageBoxMenu(DMenu::CurrentMenu, tempstring, 0, INT_MAX, false, NAME_None, [](bool res)
{
if (res)
{
savegameManager.LoadGame(savegameManager.quickSaveSlot);
}
});
M_ActivateMenu(newmenu);
}
#if 0
// Duke
if ((buttonMap.ButtonDown(gamefunc_Quick_Load) || g_doQuickSave == 2) && (myplayer.gm & MODE_GAME))
{
buttonMap.ClearButton(gamefunc_Quick_Load);
g_doQuickSave = 0;
if (g_quickload == nullptr || !g_quickload->isValid())
{
C_DoCommand("openloadmenu");
}
else if (g_quickload->isValid())
{
inputState.keyFlushChars();
inputState.ClearKeysDown();
if (G_LoadPlayerMaybeMulti(*g_quickload) != 0)
g_quickload->reset();
}
}
if ((buttonMap.ButtonDown(gamefunc_Quick_Save) || g_doQuickSave == 1) && (myplayer.gm & MODE_GAME))
{
buttonMap.ClearButton(gamefunc_Quick_Save);
g_doQuickSave = 0;
if (!g_lastusersave.isValid())
{
C_DoCommand("opensavemenu");
return;
}
inputState.keyFlushChars();
if (sprite[myplayer.i].extra <= 0)
{
P_DoQuote(QUOTE_SAVE_DEAD, &myplayer);
return;
}
g_screenCapture = 1;
G_DrawRooms(myconnectindex, 65536);
g_screenCapture = 0;
if (g_lastusersave.isValid())
{
savebrief_t& sv = g_lastusersave;
// dirty hack... char 127 in last position indicates an auto-filled name
if (sv.name[MAXSAVEGAMENAME] == 127)
{
strncpy(sv.name, g_mapInfo[ud.volume_number * MAXLEVELS + ud.level_number].name, MAXSAVEGAMENAME);
sv.name[MAXSAVEGAMENAME] = 127;
}
g_quickload = &sv;
G_SavePlayerMaybeMulti(sv);
}
}
// handle CON_SAVE and CON_SAVENN
if (g_saveRequested)
{
inputState.keyFlushChars();
videoNextPage();
g_screenCapture = 1;
G_DrawRooms(myconnectindex, 65536);
g_screenCapture = 0;
G_SavePlayerMaybeMulti(g_lastautosave, true);
g_quickload = &g_lastautosave;
OSD_Printf("Saved: %s\n", g_lastautosave.path);
g_saveRequested = false;
}
// RR
if ((buttonMap.ButtonDown(gamefunc_Quick_Load) || g_doQuickSave == 2) && (!RRRA || ud.player_skill != 4) && (!RR || RRRA || ud.player_skill != 5) && (g_player[myconnectindex].ps->gm & MODE_GAME))
{
buttonMap.ClearButton(gamefunc_Quick_Load);
g_doQuickSave = 0;
if (g_quickload == nullptr || !g_quickload->isValid())
{
C_DoCommand("openloadmenu");
}
else if (g_quickload->isValid())
{
inputState.keyFlushChars();
inputState.ClearKeysDown();
S_PauseSounds(true);
if (G_LoadPlayerMaybeMulti(*g_quickload) != 0)
g_quickload->reset();
}
}
if ((buttonMap.ButtonDown(gamefunc_Quick_Save) || g_doQuickSave == 1) && (!RRRA || ud.player_skill != 4) && (!RR || RRRA || ud.player_skill != 5) && (g_player[myconnectindex].ps->gm & MODE_GAME))
{
buttonMap.ClearButton(gamefunc_Quick_Save);
g_doQuickSave = 0;
if (!g_lastusersave.isValid())
{
C_DoCommand("opensavemenu");
return;
}
inputState.keyFlushChars();
if (sprite[g_player[myconnectindex].ps->i].extra <= 0)
{
P_DoQuote(QUOTE_SAVE_DEAD, g_player[myconnectindex].ps);
return;
}
g_screenCapture = 1;
G_DrawRooms(myconnectindex, 65536);
g_screenCapture = 0;
if (g_lastusersave.isValid())
{
savebrief_t& sv = g_lastusersave;
// dirty hack... char 127 in last position indicates an auto-filled name
if (sv.name[MAXSAVEGAMENAME] == 127)
{
strncpy(sv.name, g_mapInfo[ud.volume_number * MAXLEVELS + ud.level_number].name, MAXSAVEGAMENAME);
sv.name[MAXSAVEGAMENAME] = 127;
}
g_quickload = &sv;
G_SavePlayerMaybeMulti(sv);
}
}
// sw
SWBOOL DoQuickSave(short save_num)
{
PauseAction();
if (SaveGame(save_num) != -1)
{
QuickLoadNum = save_num;
LastSaveNum = -1;
return FALSE;
}
return TRUE;
}
SWBOOL DoQuickLoad()
{
inputState.ClearKeysDown();
PauseAction();
ReloadPrompt = FALSE;
if (LoadGame(QuickLoadNum) == -1)
{
return FALSE;
}
ready2send = 1;
LastSaveNum = -1;
return TRUE;
}
// F6 quick save
if (inputState.GetKeyStatus(KEYSC_F6))
{
inputState.ClearKeyStatus(KEYSC_F6);
if (!TEST(pp->Flags, PF_DEAD))
{
if (QuickLoadNum < 0)
{
inputState.SetKeyStatus(sc_Escape);
ControlPanelType = ct_savemenu;
}
else
{
inputState.ClearAllInput();
DoQuickSave(QuickLoadNum);
ResumeAction();
}
}
}
// F9 quick load
if (inputState.GetKeyStatus(KEYSC_F9))
{
inputState.ClearKeyStatus(KEYSC_F9);
if (!TEST(pp->Flags, PF_DEAD))
{
if (QuickLoadNum < 0)
{
inputState.SetKeyStatus(sc_Escape);
ControlPanelType = ct_loadmenu;
}
else
{
DoQuickLoad();
ResumeAction();
}
}
}
////////////////////////////////////////////////
// Load Game menu
// This function gets called whenever you
// press enter on one of the load game
// spots.
// I'm figuring it need to do the following:
// . Load the game if there is one by calling: MNU_LoadGameCustom.
////////////////////////////////////////////////
SWBOOL MNU_GetLoadCustom(void)
{
short load_num;
load_num = currentmenu->cursor;
// no saved game exists - don't do anything
if (SaveGameDescr[load_num][0] == '\0')
return FALSE;
if (InMenuLevel || DemoMode || DemoPlaying)
{
LoadSaveMsg("Loading...");
if (LoadGame(load_num) == -1)
return FALSE;
QuickLoadNum = load_num;
// the (Quick)Save menu should default to the last loaded game
SaveGameGroup.cursor = load_num;
ExitMenus();
ExitLevel = TRUE;
LoadGameOutsideMoveLoop = TRUE;
if (DemoMode || DemoPlaying)
LoadGameFromDemo = TRUE;
return TRUE;
}
LoadSaveMsg("Loading...");
PauseAction();
if (LoadGame(load_num) == -1)
{
ResumeAction();
return FALSE;
}
QuickLoadNum = load_num;
// the (Quick)Save menu should default to the last loaded game
SaveGameGroup.cursor = load_num;
ready2send = 1;
LastSaveNum = -1;
ExitMenus();
if (DemoMode)
{
ExitLevel = TRUE;
DemoPlaying = FALSE;
}
return TRUE;
}
////////////////////////////////////////////////
// Save Game menu
// This function gets called whenever you
// press enter on one of the save game
// spots.
// I'm figuring it need to do the following:
// . Call MNU_GetInput to allow string input of description.
// . Save the game if there is one by calling: MNU_SaveGameCustom.
////////////////////////////////////////////////
SWBOOL MNU_GetSaveCustom(void)
{
short save_num;
extern SWBOOL InMenuLevel, LoadGameOutsideMoveLoop;
save_num = currentmenu->cursor;
if (InMenuLevel)
return FALSE;
if (MenuInputMode)
{
LoadSaveMsg("Saving...");
if (DoQuickSave(save_num) == FALSE)
{
LoadGameGroup.cursor = save_num;
}
ResumeAction();
ExitMenus();
// toggle edit mode
MenuInputMode = FALSE;
}
else
{
strcpy(BackupSaveGameDescr, SaveGameDescr[save_num]);
// clear keyboard buffer
while (inputState.keyBufferWaiting())
{
if (inputState.keyGetChar() == 0)
inputState.keyGetChar();
}
// toggle edit mode
MenuInputMode = TRUE;
}
return TRUE;
}
// Blood
static void DoQuickLoad(void)
{
if (!gGameMenuMgr.m_bActive)
{
if (gQuickLoadSlot != -1)
{
QuickLoadGame();
return;
}
if (gQuickLoadSlot == -1 && gQuickSaveSlot != -1)
{
gQuickLoadSlot = gQuickSaveSlot;
QuickLoadGame();
return;
}
gGameMenuMgr.Push(&menuLoadGame, -1);
}
}
static void DoQuickSave(void)
{
if (gGameStarted && !gGameMenuMgr.m_bActive && gPlayer[myconnectindex].pXSprite->health != 0)
{
if (gQuickSaveSlot != -1)
{
QuickSaveGame();
return;
}
gGameMenuMgr.Push(&menuSaveGame, -1);
}
}
if (gDoQuickSave)
{
inputState.keyFlushScans();
switch (gDoQuickSave)
{
case 1:
DoQuickSave();
break;
case 2:
DoQuickLoad();
break;
}
gDoQuickSave = 0;
return;
}
case sc_F6:
inputState.keyFlushScans();
DoQuickSave();
break;
case sc_F9:
inputState.keyFlushScans();
DoQuickLoad();
break;
#endif

View file

@ -20,3 +20,4 @@ int G_ValidateSavegame(FileReader &fr, FString *savetitle);
void G_WriteSaveHeader(const char *name, const char*mapname, const char *title);
#define SAVEGAME_EXT ".dsave"

View file

@ -391,6 +391,33 @@ void CreatePath(const char *fn)
}
#endif
//==========================================================================
//
// myasctime
//
// [RH] Returns the current local time as ASCII, even if it's too early
//
//==========================================================================
const char* myasctime()
{
static char readabletime[50];
time_t clock;
struct tm* lt;
time(&clock);
lt = localtime(&clock);
if (lt != NULL)
{
strftime(readabletime, 50, "%F %T", lt);
return readabletime;
}
else
{
return "Unknown Time";
}
}
//==========================================================================
//
// strbin -- In-place version

View file

@ -36,6 +36,7 @@ bool IsNum (const char *str); // [RH] added
bool CheckWildcards (const char *pattern, const char *text);
const char* myasctime();
int strbin (char *str);
FString strbin1 (const char *start);

View file

@ -167,6 +167,8 @@ struct GameInterface : ::GameInterface
bool DrawSpecialScreen(const DVector2 &origin, int tilenum) override;
void DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position) override;
void DrawMenuCaption(const DVector2& origin, const char* text) override;
bool SaveGame(FSaveGameNode*) override;
bool LoadGame(FSaveGameNode*) override;
};

View file

@ -4688,45 +4688,6 @@ void G_HandleLocalKeys(void)
typebuf[0] = 0;
}
if ((buttonMap.ButtonDown(gamefunc_Quick_Save) || g_doQuickSave == 1) && (myplayer.gm & MODE_GAME))
{
buttonMap.ClearButton(gamefunc_Quick_Save);
g_doQuickSave = 0;
if (!g_lastusersave.isValid())
{
C_DoCommand("opensavemenu");
return;
}
inputState.keyFlushChars();
if (sprite[myplayer.i].extra <= 0)
{
P_DoQuote(QUOTE_SAVE_DEAD, &myplayer);
return;
}
g_screenCapture = 1;
G_DrawRooms(myconnectindex,65536);
g_screenCapture = 0;
if (g_lastusersave.isValid())
{
savebrief_t & sv = g_lastusersave;
// dirty hack... char 127 in last position indicates an auto-filled name
if (sv.name[MAXSAVEGAMENAME] == 127)
{
strncpy(sv.name, g_mapInfo[ud.volume_number * MAXLEVELS + ud.level_number].name, MAXSAVEGAMENAME);
sv.name[MAXSAVEGAMENAME] = 127;
}
g_quickload = &sv;
G_SavePlayerMaybeMulti(sv);
}
}
if (buttonMap.ButtonDown(gamefunc_Third_Person_View))
{
buttonMap.ClearButton(gamefunc_Third_Person_View);
@ -4749,25 +4710,6 @@ void G_HandleLocalKeys(void)
hud_messages = fta;
}
if ((buttonMap.ButtonDown(gamefunc_Quick_Load) || g_doQuickSave == 2) && (myplayer.gm & MODE_GAME))
{
buttonMap.ClearButton(gamefunc_Quick_Load);
g_doQuickSave = 0;
if (g_quickload == nullptr || !g_quickload->isValid())
{
C_DoCommand("openloadmenu");
}
else if (g_quickload->isValid())
{
inputState.keyFlushChars();
inputState.ClearKeysDown();
S_PauseSounds(true);
if (G_LoadPlayerMaybeMulti(*g_quickload) != 0)
g_quickload->reset();
}
}
if (ud.overhead_on != 0)
{
@ -6362,12 +6304,7 @@ MAIN_LOOP_RESTART:
inputState.keyFlushChars();
videoNextPage();
g_screenCapture = 1;
G_DrawRooms(myconnectindex, 65536);
g_screenCapture = 0;
G_SavePlayerMaybeMulti(g_lastautosave, true);
g_quickload = &g_lastautosave;
M_Autosave();
g_saveRequested = false;
}

View file

@ -38,6 +38,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "base64.h"
#include "version.h"
#include "menu/menu.h"
#include "c_dispatch.h"
#include "debugbreak.h"
extern bool rotatesprite_2doverride;
@ -1061,17 +1062,17 @@ static void VM_Fall(int const spriteNum, spritetype * const pSprite)
static int32_t VM_ResetPlayer(int const playerNum, int32_t vmFlags, int32_t const resetFlags)
{
// Who thought that allowing a script to do this shit is a good idea???
if (!g_netServer && ud.multimode < 2 && !(resetFlags & 2))
{
if (g_quickload && g_quickload->isValid() && ud.recstat != 2 && !(resetFlags & 8))
#if 0 // Who thought that allowing a script to do this shit is a good idea??? This needs to be sorted out later and implemented properly.
if (!(resetFlags & 8))
{
if (resetFlags & 4)
{
inputState.keyFlushChars();
inputState.ClearKeysDown();
FX_StopAllSounds();
S_ClearSoundLocks();
if (G_LoadPlayerMaybeMulti(*g_quickload) != 0)
{
g_quickload->reset();
@ -1082,16 +1083,22 @@ static int32_t VM_ResetPlayer(int const playerNum, int32_t vmFlags, int32_t cons
{
M_StartControlPanel(false);
M_SetMenu(NAME_ConfirmPlayerReset);
/*
case MENU_RESETPLAYER:
videoFadeToBlack(1);
Bsprintf(tempbuf, "Load last game:\n\"%s\"", g_quickload->name);
Menu_DrawVerifyPrompt(origin.x, origin.y, tempbuf, 2);
break;
*/
}
}
else
#endif
{
QuickLoadFailure:
g_player[playerNum].ps->gm = MODE_RESTART;
}
#if !defined LUNATIC
vmFlags |= VM_NOEXECUTE;
#endif
}
else
{
@ -4886,32 +4893,9 @@ badindex:
vInstruction(CON_SAVENN):
vInstruction(CON_SAVE):
insptr++;
{
int32_t const requestedSlot = *insptr++;
if ((unsigned)requestedSlot >= 10)
dispatch();
// check if we need to make a new file
if (strcmp(g_lastautosave.path, g_lastusersave.path) == 0 || requestedSlot != g_lastAutoSaveArbitraryID)
{
g_lastautosave.reset();
}
g_lastAutoSaveArbitraryID = requestedSlot;
if (VM_DECODE_INST(tw) == CON_SAVE || g_lastautosave.name[0] == 0)
{
time_t timeStruct = time(NULL);
struct tm *pTime = localtime(&timeStruct);
strftime(g_lastautosave.name, sizeof(g_lastautosave.name), "%d %b %Y %I:%M%p", pTime);
}
g_saveRequested = true;
dispatch();
}
insptr++; // skip the slot. I will not allow the script to do targeted saving without user control.
g_saveRequested = true; // cannot save right here.
dispatch();
vInstruction(CON_QUAKE):
insptr++;

View file

@ -1311,7 +1311,7 @@ static void Gv_AddSystemVars(void)
Gv_NewVar("gravitationalconstant", (intptr_t)&g_spriteGravity, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
Gv_NewVar("gs", (intptr_t)&hudweap.shade, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
Gv_NewVar("gun_pos", (intptr_t)&hudweap.gunposy, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
Gv_NewVar("lastsavepos", (intptr_t)&g_lastAutoSaveArbitraryID, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
Gv_NewVar("lastsavepos", (intptr_t)&g_fakeSaveID, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
Gv_NewVar("lastvisinc", (intptr_t)&lastvisinc, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
Gv_NewVar("looking_angSR1", (intptr_t)&hudweap.lookhalfang, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
Gv_NewVar("looking_arc", (intptr_t)&hudweap.lookhoriz, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
@ -1465,7 +1465,7 @@ void Gv_RefreshPointers(void)
(intptr_t)&g_spriteGravity;
aGameVars[Gv_GetVarIndex("gs")].global = (intptr_t)&hudweap.shade;
aGameVars[Gv_GetVarIndex("gun_pos")].global = (intptr_t)&hudweap.gunposy;
aGameVars[Gv_GetVarIndex("lastsavepos")].global = (intptr_t)&g_lastAutoSaveArbitraryID;
aGameVars[Gv_GetVarIndex("lastsavepos")].global = (intptr_t)&g_fakeSaveID; // This won't be of much use anymore. >D
aGameVars[Gv_GetVarIndex("lastvisinc")].global = (intptr_t)&lastvisinc;
aGameVars[Gv_GetVarIndex("looking_angSR1")].global = (intptr_t)&hudweap.lookhalfang;
aGameVars[Gv_GetVarIndex("looking_arc")].global = (intptr_t)&hudweap.lookhoriz;

View file

@ -1432,12 +1432,6 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin)
}
break;
case MENU_RESETPLAYER:
videoFadeToBlack(1);
Bsprintf(tempbuf, "Load last game:\n\"%s\"", g_quickload->name);
Menu_DrawVerifyPrompt(origin.x, origin.y, tempbuf, 2);
break;
case MENU_SAVECLEANVERIFY:
videoFadeToBlack(1);

View file

@ -687,24 +687,6 @@ void onvideomodechange(int32_t newmode)
g_crosshairSum = -1;
}
static int osdcmd_quicksave(osdcmdptr_t UNUSED(parm))
{
UNREFERENCED_CONST_PARAMETER(parm);
if (!(g_player[myconnectindex].ps->gm & MODE_GAME))
OSD_Printf("quicksave: not in a game.\n");
else g_doQuickSave = 1;
return OSDCMD_OK;
}
static int osdcmd_quickload(osdcmdptr_t UNUSED(parm))
{
UNREFERENCED_CONST_PARAMETER(parm);
if (!(g_player[myconnectindex].ps->gm & MODE_GAME))
OSD_Printf("quickload: not in a game.\n");
else g_doQuickSave = 2;
return OSDCMD_OK;
}
static int osdcmd_dumpmapstate(osdfuncparm_t const * const)
{
@ -982,9 +964,6 @@ int32_t registerosdcommands(void)
OSD_RegisterFunction("printtimes", "printtimes: prints VM timing statistics", osdcmd_printtimes);
OSD_RegisterFunction("quicksave","quicksave: performs a quick save", osdcmd_quicksave);
OSD_RegisterFunction("quickload","quickload: performs a quick load", osdcmd_quickload);
OSD_RegisterFunction("restartmap", "restartmap: restarts the current map", osdcmd_restartmap);
OSD_RegisterFunction("restartsound","restartsound: reinitializes the sound system",osdcmd_restartsound);
OSD_RegisterFunction("addlogvar","addlogvar <gamevar>: prints the value of a gamevar", osdcmd_addlogvar);

View file

@ -1341,11 +1341,6 @@ void G_NewGame(int volumeNum, int levelNum, int skillNum)
ud.volume_number = volumeNum;
STAT_StartNewGame(gVolumeNames[volumeNum], skillNum);
g_lastAutoSaveArbitraryID = -1;
g_lastautosave.reset();
g_lastusersave.reset();
g_quickload = nullptr;
// we don't want the intro to play after the multiplayer setup screen
if ((!g_netServer && ud.multimode < 2) && !Menu_HaveUserMap()
&& !VM_OnEventWithReturn(EVENT_NEWGAMESCREEN, g_player[myconnectindex].ps->i, myconnectindex, 0)

View file

@ -141,10 +141,8 @@ void G_ResetInterpolations(void)
G_SetInterpolation(g_animatePtr[i]);
}
savebrief_t g_lastautosave, g_lastusersave, g_freshload;
int32_t g_lastAutoSaveArbitraryID = -1;
int32_t g_fakeSaveID = -1;
bool g_saveRequested;
savebrief_t * g_quickload;
static FileReader *OpenSavegame(const char *fn)
@ -220,15 +218,15 @@ static int different_user_map;
// XXX: keyboard input 'blocked' after load fail? (at least ESC?)
int32_t G_LoadPlayer(savebrief_t & sv)
int32_t G_LoadPlayer(FSaveGameNode *sv)
{
if (sv.isExt)
if (sv->bIsExt)
{
int volume = -1;
int level = -1;
int skill = -1;
auto fil = OpenSavegame(sv.path);
auto fil = OpenSavegame(sv->Filename);
if (!fil) return -1;
{
@ -354,8 +352,6 @@ int32_t G_LoadPlayer(savebrief_t & sv)
ud.skill_voice = -1;
ud.volume_number = volume;
g_lastAutoSaveArbitraryID = -1;
#ifdef EDUKE32_TOUCH_DEVICES
p0.zoom = 360;
#else
@ -465,7 +461,7 @@ int32_t G_LoadPlayer(savebrief_t & sv)
return 0;
}
auto fil = OpenSavegame(sv.path);
auto fil = OpenSavegame(sv->Filename);
if (!fil)
return -1;
@ -545,7 +541,7 @@ int32_t G_LoadPlayer(savebrief_t & sv)
{
// 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.", sv.path, status);
Bsprintf(tempbuf, "Loading save game file \"%s\" failed (code %d), cannot recover.", sv->Filename.GetChars(), status);
G_GameExit(tempbuf);
}
@ -582,7 +578,7 @@ static void G_RestoreTimers(void)
//////////
int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave)
bool G_SavePlayer(FSaveGameNode *sv)
{
#ifdef __ANDROID__
G_SavePalette();
@ -598,62 +594,26 @@ int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave)
errno = 0;
FileWriter *fil;
if (sv.isValid())
{
fn = G_BuildSaveName(sv.path);
OpenSaveGameForWrite(fn);
fil = WriteSavegameChunk("snapshot.dat");
}
else
{
fn = G_BuildSaveName("save0000");
auto fnp = fn.LockBuffer();
char* zeros = strstr(fnp, "0000");
fil = savecounter.opennextfile(fnp, zeros); // fixme: Rewrite this so that it won't create the file.
fn.UnlockBuffer();
if (fil)
{
delete fil;
remove(fn);
OpenSaveGameForWrite(fn);
fil = WriteSavegameChunk("snapshot.dat");
}
savecounter.count++;
// don't copy the mod dir into sv.path (G_BuildSaveName guarantees the presence of a slash.)
Bstrcpy(sv.path, strrchr(fn, '/') + 1);
}
if (!fil)
{
OSD_Printf("G_SavePlayer: failed opening \"%s\" for writing: %s\n",
fn.GetChars(), strerror(errno));
ready2send = 1;
Net_WaitForServer();
G_RestoreTimers();
ototalclock = totalclock;
return -1;
}
else
fn = G_BuildSaveName(sv->Filename);
OpenSaveGameForWrite(fn);
fil = WriteSavegameChunk("snapshot.dat");
// The above call cannot fail.
{
auto& fw = *fil;
sv.isExt = 0;
// temporary hack
ud.user_map = G_HaveUserMap();
VM_OnEvent(EVENT_SAVEGAME, g_player[myconnectindex].ps->i, myconnectindex);
portableBackupSave(sv.path, sv.name, ud.last_stateless_volume, ud.last_stateless_level);
portableBackupSave(sv->Filename, sv->SaveTitle, ud.last_stateless_volume, ud.last_stateless_level);
// SAVE!
sv_saveandmakesnapshot(fw, sv.name, 0, 0, 0, 0, isAutoSave);
sv_saveandmakesnapshot(fw, sv->SaveTitle, 0, 0, 0, 0);
fw.Close();
FinishSavegameWrite();
bool res = FinishSavegameWrite();
if (!g_netServer && ud.multimode < 2)
{
@ -670,11 +630,12 @@ int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave)
VM_OnEvent(EVENT_POSTSAVEGAME, g_player[myconnectindex].ps->i, myconnectindex);
return 0;
return res;
}
}
int32_t G_LoadPlayerMaybeMulti(savebrief_t & sv)
bool GameInterface::LoadGame(FSaveGameNode *sv)
{
if (g_netServer || ud.multimode > 1)
{
@ -682,27 +643,33 @@ int32_t G_LoadPlayerMaybeMulti(savebrief_t & sv)
P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps);
// g_player[myconnectindex].ps->gm = MODE_GAME;
return 127;
return false;
}
else
{
int32_t c = G_LoadPlayer(sv);
if (c == 0)
g_player[myconnectindex].ps->gm = MODE_GAME;
return c;
return c == 0;
}
}
void G_SavePlayerMaybeMulti(savebrief_t & sv, bool isAutoSave)
bool GameInterface::SaveGame(FSaveGameNode* sv)
{
if (g_netServer || ud.multimode > 1)
{
Bstrcpy(apStrings[QUOTE_RESERVED4], "Multiplayer Saving Not Yet Supported");
P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps);
return false;
}
else
{
G_SavePlayer(sv, isAutoSave);
videoNextPage(); // no idea if this is needed here.
g_screenCapture = 1;
G_DrawRooms(myconnectindex, 65536);
g_screenCapture = 0;
return G_SavePlayer(sv);
}
}
@ -1470,7 +1437,7 @@ static void SV_AllocSnap(int32_t allocinit)
}
// make snapshot only if spot < 0 (demo)
int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress, bool isAutoSave)
int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress)
{
savehead_t h;
@ -1493,10 +1460,6 @@ int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, i
h.majorver = SV_MAJOR_VER;
h.minorver = SV_MINOR_VER;
h.ptrsize = sizeof(intptr_t);
if (isAutoSave)
h.ptrsize |= 1u << 7u;
h.bytever = BYTEVERSION;
h.userbytever = ud.userbytever;
h.scriptcrc = g_scriptcrc;

View file

@ -57,62 +57,13 @@ typedef struct
uint8_t numplayers, volnum, levnum, skill;
char boardfn[BMAX_PATH];
// 286 bytes
#ifdef __ANDROID__
char skillname[32], volname[32];
#endif
uint8_t getPtrSize() const { return ptrsize & 0x7Fu; }
bool isAutoSave() const { return !!(ptrsize & (1u<<7u)); }
uint8_t getPtrSize() const { return ptrsize; }
} savehead_t;
#pragma pack(pop)
struct savebrief_t
{
savebrief_t()
{
reset();
}
savebrief_t(char const *n)
{
strncpy(name, n, MAXSAVEGAMENAME);
path[0] = '\0';
}
char name[MAXSAVEGAMENAMESTRUCT];
char path[BMAX_PATH];
uint8_t isExt = 0;
void reset()
{
name[0] = '\0';
path[0] = '\0';
isExt = 0;
}
bool isValid() const
{
return path[0] != '\0';
}
};
struct menusave_t
{
savebrief_t brief;
uint8_t isOldVer = 0;
uint8_t isUnreadable = 0;
uint8_t isAutoSave = 0;
void clear()
{
brief.reset();
isOldVer = 0;
isUnreadable = 0;
isAutoSave = 0;
}
};
extern savebrief_t g_lastautosave, g_lastusersave, g_freshload;
extern int32_t g_lastAutoSaveArbitraryID;
extern int32_t g_fakeSaveID;
extern bool g_saveRequested;
extern savebrief_t * g_quickload;
int32_t sv_updatestate(int32_t frominit);
@ -120,14 +71,10 @@ int32_t sv_readdiff(FileReader& fil);
uint32_t sv_writediff(FileWriter *fil);
int32_t sv_loadheader(FileReader &fil, int32_t spot, savehead_t *h);
int32_t sv_loadsnapshot(FileReader &fil, int32_t spot, savehead_t *h);
int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress, bool isAutoSave = false);
int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress);
void sv_freemem();
int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave);
int32_t G_LoadPlayer(savebrief_t & sv);
int32_t G_LoadSaveHeaderNew(char const *fn, savehead_t *saveh);
void ReadSaveGameHeaders(void);
void G_SavePlayerMaybeMulti(savebrief_t & sv, bool isAutoSave = false);
int32_t G_LoadPlayerMaybeMulti(savebrief_t & sv);
#ifdef YAX_ENABLE
extern void sv_postyaxload(void);

View file

@ -167,6 +167,8 @@ struct GameInterface : ::GameInterface
FSavegameInfo GetSaveSig() override;
void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position) override;
void DrawMenuCaption(const DVector2& origin, const char* text) override;
bool SaveGame(FSaveGameNode*) override;
bool LoadGame(FSaveGameNode*) override;
};
END_RR_NS

View file

@ -6232,46 +6232,6 @@ void G_HandleLocalKeys(void)
}
if ((buttonMap.ButtonDown(gamefunc_Quick_Save) || g_doQuickSave == 1) && (!RRRA || ud.player_skill != 4) && (!RR || RRRA || ud.player_skill != 5) && (g_player[myconnectindex].ps->gm&MODE_GAME))
{
buttonMap.ClearButton(gamefunc_Quick_Save);
g_doQuickSave = 0;
if (!g_lastusersave.isValid())
{
C_DoCommand("opensavemenu");
return;
}
inputState.keyFlushChars();
if (sprite[g_player[myconnectindex].ps->i].extra <= 0)
{
P_DoQuote(QUOTE_SAVE_DEAD,g_player[myconnectindex].ps);
return;
}
g_screenCapture = 1;
G_DrawRooms(myconnectindex,65536);
g_screenCapture = 0;
if (g_lastusersave.isValid())
{
savebrief_t & sv = g_lastusersave;
// dirty hack... char 127 in last position indicates an auto-filled name
if (sv.name[MAXSAVEGAMENAME] == 127)
{
strncpy(sv.name, g_mapInfo[ud.volume_number * MAXLEVELS + ud.level_number].name, MAXSAVEGAMENAME);
sv.name[MAXSAVEGAMENAME] = 127;
}
g_quickload = &sv;
G_SavePlayerMaybeMulti(sv);
}
}
if (buttonMap.ButtonDown(gamefunc_Third_Person_View))
{
buttonMap.ClearButton(gamefunc_Third_Person_View);
@ -6297,26 +6257,6 @@ void G_HandleLocalKeys(void)
hud_messages = fta;
}
if ((buttonMap.ButtonDown(gamefunc_Quick_Load) || g_doQuickSave == 2) && (!RRRA || ud.player_skill != 4) && (!RR || RRRA || ud.player_skill != 5) && (g_player[myconnectindex].ps->gm&MODE_GAME))
{
buttonMap.ClearButton(gamefunc_Quick_Load);
g_doQuickSave = 0;
if (g_quickload == nullptr || !g_quickload->isValid())
{
C_DoCommand("openloadmenu");
}
else if (g_quickload->isValid())
{
inputState.keyFlushChars();
inputState.ClearKeysDown();
S_PauseSounds(true);
if (G_LoadPlayerMaybeMulti(*g_quickload) != 0)
g_quickload->reset();
}
}
if (ud.overhead_on != 0)
{
int const timerOffset = ((int) totalclock - nonsharedtimer);
@ -7783,7 +7723,7 @@ MAIN_LOOP_RESTART:
{
idle();
}
else */if (G_FPSLimit() || g_saveRequested)
else */if (G_FPSLimit())
{
int const smoothRatio = calc_smoothratio(totalclock, ototalclock);
@ -7799,24 +7739,6 @@ MAIN_LOOP_RESTART:
}
}
// handle CON_SAVE and CON_SAVENN
if (g_saveRequested)
{
inputState.keyFlushChars();
videoNextPage();
g_screenCapture = 1;
G_DrawRooms(myconnectindex, 65536);
g_screenCapture = 0;
G_SavePlayerMaybeMulti(g_lastautosave, true);
g_quickload = &g_lastautosave;
OSD_Printf("Saved: %s\n", g_lastautosave.path);
g_saveRequested = false;
}
if (g_player[myconnectindex].ps->gm&MODE_DEMO)
goto MAIN_LOOP_RESTART;
}

View file

@ -1061,12 +1061,14 @@ static int32_t VM_ResetPlayer(int const playerNum, int32_t vmFlags)
//AddLog("resetplayer");
if (!g_netServer && ud.multimode < 2)
{
#if 0
if (g_quickload && g_quickload->isValid() && ud.recstat != 2)
{
M_StartControlPanel(false);
M_SetMenu(NAME_ConfirmPlayerReset);
}
else
#endif
g_player[playerNum].ps->gm = MODE_RESTART;
vmFlags |= VM_NOEXECUTE;
}

View file

@ -1472,17 +1472,6 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin)
case MENU_MOUSEADVANCED:
break;
case MENU_RESETPLAYER:
videoFadeToBlack(1);
Bsprintf(tempbuf, "Load last game:\n\"%s\""
#ifndef EDUKE32_ANDROID_MENU
"\n(Y/N)"
#endif
, g_quickload->name);
mgametextcenter(origin.x, origin.y + (90<<16), tempbuf);
break;
case MENU_NEWVERIFY:
videoFadeToBlack(1);
mgametextcenter(origin.x, origin.y + (90<<16), "Abort this game?"

View file

@ -590,24 +590,6 @@ void onvideomodechange(int32_t newmode)
}
static int osdcmd_quicksave(osdcmdptr_t UNUSED(parm))
{
UNREFERENCED_CONST_PARAMETER(parm);
if (!(g_player[myconnectindex].ps->gm & MODE_GAME))
OSD_Printf("quicksave: not in a game.\n");
else g_doQuickSave = 1;
return OSDCMD_OK;
}
static int osdcmd_quickload(osdcmdptr_t UNUSED(parm))
{
UNREFERENCED_CONST_PARAMETER(parm);
if (!(g_player[myconnectindex].ps->gm & MODE_GAME))
OSD_Printf("quickload: not in a game.\n");
else g_doQuickSave = 2;
return OSDCMD_OK;
}
#if !defined NETCODE_DISABLE
static int osdcmd_disconnect(osdcmdptr_t UNUSED(parm))
{
@ -837,9 +819,6 @@ int32_t registerosdcommands(void)
OSD_RegisterFunction("printtimes", "printtimes: prints VM timing statistics", osdcmd_printtimes);
OSD_RegisterFunction("quicksave","quicksave: performs a quick save", osdcmd_quicksave);
OSD_RegisterFunction("quickload","quickload: performs a quick load", osdcmd_quickload);
OSD_RegisterFunction("restartmap", "restartmap: restarts the current map", osdcmd_restartmap);
OSD_RegisterFunction("restartsound","restartsound: reinitializes the sound system",osdcmd_restartsound);

View file

@ -1905,11 +1905,7 @@ void G_NewGame(int volumeNum, int levelNum, int skillNum)
STAT_StartNewGame(gVolumeNames[volumeNum], skillNum);
ud.last_level = -1;
g_lastAutoSaveArbitraryID = -1;
g_lastautosave.reset();
g_lastusersave.reset();
g_quickload = nullptr;
int const UserMap = Menu_HaveUserMap();
// we don't want the intro to play after the multiplayer setup screen

View file

@ -138,16 +138,6 @@ void G_ResetInterpolations(void)
G_SetInterpolation(g_animatePtr[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;
uint16_t g_nummenusaves;
static menusave_t * g_internalsaves;
static uint16_t g_numinternalsaves;
static FileReader *OpenSavegame(const char *fn)
{
@ -226,9 +216,9 @@ static void sv_postudload();
static int different_user_map;
// XXX: keyboard input 'blocked' after load fail? (at least ESC?)
int32_t G_LoadPlayer(savebrief_t & sv)
int32_t G_LoadPlayer(const char *path)
{
auto fil = OpenSavegame(sv.path);
auto fil = OpenSavegame(path);
if (!fil)
return -1;
@ -255,6 +245,7 @@ int32_t G_LoadPlayer(savebrief_t & sv)
// some setup first
ud.multimode = h.numplayers;
S_PauseSounds(true);
if (numplayers > 1)
{
@ -303,7 +294,7 @@ int32_t G_LoadPlayer(savebrief_t & sv)
{
// 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.", sv.path, status);
Bsprintf(tempbuf, "Loading save game file \"%s\" failed (code %d), cannot recover.", path, status);
G_GameExit(tempbuf);
}
@ -339,12 +330,8 @@ static void G_RestoreTimers(void)
lockclock = g_timers.lockclock;
}
int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave)
bool G_SavePlayer(FSaveGameNode *sv)
{
#ifdef __ANDROID__
G_SavePalette();
#endif
G_SaveTimers();
Net_WaitForEverybody();
@ -355,59 +342,23 @@ int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave)
errno = 0;
FileWriter *fil;
if (sv.isValid())
fn = G_BuildSaveName(sv->Filename);
OpenSaveGameForWrite(fn);
fil = WriteSavegameChunk("snapshot.dat");
// The above call cannot fail.
{
fn = G_BuildSaveName(sv.path);
OpenSaveGameForWrite(fn);
fil = WriteSavegameChunk("snapshot.dat");
}
else
{
fn = G_BuildSaveName("save0000");
auto fnp = fn.LockBuffer();
char* zeros = strstr(fnp, "0000");
fil = savecounter.opennextfile(fnp, zeros); // fixme: Rewrite this so that it won't create the file.
fn.UnlockBuffer();
if (fil)
{
delete fil;
remove(fn);
OpenSaveGameForWrite(fn);
fil = WriteSavegameChunk("snapshot.dat");
}
savecounter.count++;
// don't copy the mod dir into sv.path (G_BuildSaveName guarantees the presence of a slash.)
Bstrcpy(sv.path, strrchr(fn, '/') + 1);
}
if (!fil)
{
OSD_Printf("G_SavePlayer: failed opening \"%s\" for writing: %s\n",
fn.GetChars(), strerror(errno));
ready2send = 1;
Net_WaitForEverybody();
G_RestoreTimers();
ototalclock = totalclock;
return -1;
}
else
{
WriteSavegameChunk("DEMOLITION_RN");
auto& fw = *fil;
//CompressedFileWriter fw(fil, true);
// temporary hack
ud.user_map = G_HaveUserMap();
// SAVE!
sv_saveandmakesnapshot(fw, sv.name, 0, 0, 0, 0, isAutoSave);
sv_saveandmakesnapshot(fw, sv->SaveTitle, 0, 0, 0, 0);
fw.Close();
FinishSavegameWrite();
bool res = FinishSavegameWrite();
if (!g_netServer && ud.multimode < 2)
{
@ -422,11 +373,11 @@ int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave)
G_RestoreTimers();
ototalclock = totalclock;
return 0;
return res;
}
}
int32_t G_LoadPlayerMaybeMulti(savebrief_t & sv)
bool GameInterface::LoadGame(FSaveGameNode* sv)
{
if (g_netServer || ud.multimode > 1)
{
@ -434,18 +385,18 @@ int32_t G_LoadPlayerMaybeMulti(savebrief_t & sv)
P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps);
// g_player[myconnectindex].ps->gm = MODE_GAME;
return 127;
return false;
}
else
{
int32_t c = G_LoadPlayer(sv);
int32_t c = G_LoadPlayer(sv->Filename);
if (c == 0)
g_player[myconnectindex].ps->gm = MODE_GAME;
return c;
return !c;
}
}
void G_SavePlayerMaybeMulti(savebrief_t & sv, bool isAutoSave)
bool GameInterface::SaveGame(FSaveGameNode* sv)
{
if (g_netServer || ud.multimode > 1)
{
@ -454,7 +405,13 @@ void G_SavePlayerMaybeMulti(savebrief_t & sv, bool isAutoSave)
}
else
{
G_SavePlayer(sv, isAutoSave);
videoNextPage(); // no idea if this is needed here.
g_screenCapture = 1;
G_DrawRooms(myconnectindex, 65536);
g_screenCapture = 0;
G_SavePlayer(sv);
}
}

View file

@ -52,64 +52,11 @@ typedef struct
uint8_t numplayers, volnum, levnum, skill;
char boardfn[BMAX_PATH];
// 286 bytes
#ifdef __ANDROID__
char skillname[32], volname[32];
#endif
uint8_t getPtrSize() const { return ptrsize & 0x7Fu; }
bool isAutoSave() const { return !!(ptrsize & (1u<<7u)); }
uint8_t getPtrSize() const { return ptrsize; }
} savehead_t;
#pragma pack(pop)
struct savebrief_t
{
savebrief_t()
{
reset();
}
savebrief_t(char const *n)
{
strncpy(name, n, MAXSAVEGAMENAME);
path[0] = '\0';
}
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;
uint8_t isUnreadable = 0;
uint8_t isAutoSave = 0;
void clear()
{
brief.reset();
isOldVer = 0;
isUnreadable = 0;
isAutoSave = 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 uint16_t g_nummenusaves;
int32_t sv_updatestate(int32_t frominit);
int32_t sv_readdiff(FileReader& fil);
uint32_t sv_writediff(FileWriter *fil);
@ -117,12 +64,8 @@ int32_t sv_loadheader(FileReader &fil, int32_t spot, savehead_t *h);
int32_t sv_loadsnapshot(FileReader &fil, int32_t spot, savehead_t *h);
int32_t sv_saveandmakesnapshot(FileWriter &fil, char const *name, int8_t spot, int8_t recdiffsp, int8_t diffcompress, int8_t synccompress, bool isAutoSave = false);
void sv_freemem();
int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave);
int32_t G_LoadPlayer(savebrief_t & sv);
int32_t G_LoadSaveHeaderNew(char const *fn, savehead_t *saveh);
void ReadSaveGameHeaders(void);
void G_SavePlayerMaybeMulti(savebrief_t & sv, bool isAutoSave = false);
int32_t G_LoadPlayerMaybeMulti(savebrief_t & sv);
#ifdef YAX_ENABLE
extern void sv_postyaxload(void);

View file

@ -3338,40 +3338,6 @@ void ConKey(void)
char WangBangMacro[10][64];
SWBOOL DoQuickSave(short save_num)
{
PauseAction();
if (SaveGame(save_num) != -1)
{
QuickLoadNum = save_num;
LastSaveNum = -1;
return FALSE;
}
return TRUE;
}
SWBOOL DoQuickLoad()
{
inputState.ClearKeysDown();
PauseAction();
ReloadPrompt = FALSE;
if (LoadGame(QuickLoadNum) == -1)
{
return FALSE;
}
ready2send = 1;
LastSaveNum = -1;
return TRUE;
}
void
FunctionKeys(PLAYERp pp)
{
@ -3469,45 +3435,6 @@ FunctionKeys(PLAYERp pp)
}
}
// F6 quick save
if (inputState.GetKeyStatus(KEYSC_F6))
{
inputState.ClearKeyStatus(KEYSC_F6);
if (!TEST(pp->Flags, PF_DEAD))
{
if (QuickLoadNum < 0)
{
inputState.SetKeyStatus(sc_Escape);
ControlPanelType = ct_savemenu;
}
else
{
inputState.ClearAllInput();
DoQuickSave(QuickLoadNum);
ResumeAction();
}
}
}
// F9 quick load
if (inputState.GetKeyStatus(KEYSC_F9))
{
inputState.ClearKeyStatus(KEYSC_F9);
if (!TEST(pp->Flags, PF_DEAD))
{
if (QuickLoadNum < 0)
{
inputState.SetKeyStatus(sc_Escape);
ControlPanelType = ct_loadmenu;
}
else
{
DoQuickLoad();
ResumeAction();
}
}
}
}
@ -3609,15 +3536,15 @@ void PauseKey(PLAYERp pp)
{
if (ReloadPrompt)
{
if (QuickLoadNum < 0)
{
ReloadPrompt = FALSE;
ReloadPrompt = FALSE;
/*
}
else
{
inputState.SetKeyStatus(sc_Escape);
ControlPanelType = ct_quickloadmenu;
}
*/
}
}
}

View file

@ -2373,10 +2373,7 @@ int COVERinsertsprite(short sectnum, short statnum); //returns (short)spritenu
void AudioUpdate(void); // stupid
extern short LastSaveNum;
extern short QuickLoadNum;
void LoadSaveMsg(const char *msg);
SWBOOL DoQuickSave(short save_num);
SWBOOL DoQuickLoad(void);
struct GameInterface : ::GameInterface
{

View file

@ -67,8 +67,6 @@ signed char MNU_InputString(char*, short);
short TimeLimitTable[9] = {0,3,5,10,15,20,30,45,60};
short QuickLoadNum = -1;
char QuickLoadDescrDialog[128];
SWBOOL SavePrompt = FALSE;
extern SWBOOL InMenuLevel, LoadGameOutsideMoveLoop, LoadGameFromDemo;
extern uint8_t RedBookSong[40];
@ -511,7 +509,7 @@ MenuItem save_i[] =
// No actual submenus for this, just quit text.
MenuGroup quitgroup = {0, 0, NULL, NULL, 0, 0, m_defshade, MNU_QuitCustom, NULL, 0};
MenuGroup quickloadgroup = {0, 0, NULL, NULL, 0, 0, m_defshade, MNU_QuickLoadCustom, NULL, 0};
MenuGroup quickloadgroup = {0, 0, NULL, NULL, 0, 0, m_defshade, MNU_QuitCustom/* MNU_QuickLoadCustom*/, NULL, 0}; // temp.placeholder.
MenuGroup ordergroup = {0, 0, NULL, NULL, 0, 0, m_defshade, MNU_OrderCustom, NULL, 0};
// save and load function calls
@ -1734,87 +1732,6 @@ MNU_QuitCustom(UserCall call, MenuItem_p item)
return TRUE;
}
SWBOOL
MNU_QuickLoadCustom(UserCall call, MenuItem_p item)
{
int select;
extern SWBOOL ReloadPrompt;
int bak;
PLAYERp pp = Player + myconnectindex;
extern short GlobInfoStringTime;
extern SWBOOL DrawScreen;
int ret;
if (cust_callback == NULL)
{
if (call != uc_setup)
return FALSE;
memset(dialog, 0, sizeof(dialog));
dialog[0] = "Load saved game";
sprintf(QuickLoadDescrDialog,"\"%s\" (Y/N)?",SaveGameDescr[QuickLoadNum]);
dialog[1] = QuickLoadDescrDialog;
}
// Ignore the special touchup calls
if (call == uc_touchup)
return TRUE;
ret = MNU_Dialog();
if (DrawScreen)
{
return TRUE;
}
if (ret == FALSE)
{
if (inputState.GetKeyStatus(sc_N) || inputState.GetKeyStatus(sc_Space) || inputState.GetKeyStatus(sc_Enter))
{
cust_callback = NULL;
if (ReloadPrompt)
{
ReloadPrompt = FALSE;
bak = GlobInfoStringTime;
GlobInfoStringTime = 999;
PutStringInfo(pp, "Press SPACE to restart");
GlobInfoStringTime = bak;
}
inputState.ClearKeysDown();
ExitMenus();
}
else
{
cust_callback = MNU_QuickLoadCustom;
cust_callback_call = call;
cust_callback_item = item;
}
}
else
{
// Y pressed
cust_callback = NULL;
LoadSaveMsg("Loading...");
if (DoQuickLoad() == FALSE)
{
ResumeAction();
return FALSE;
}
ExitMenus();
return TRUE;
}
inputState.ClearKeysDown();
return TRUE;
}
// MENU FUNCTIONS /////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////
// Set some global menu related defaults
@ -2349,58 +2266,6 @@ void LoadSaveMsg(const char *msg)
////////////////////////////////////////////////
SWBOOL MNU_GetLoadCustom(void)
{
short load_num;
load_num = currentmenu->cursor;
// no saved game exists - don't do anything
if (SaveGameDescr[load_num][0] == '\0')
return FALSE;
if (InMenuLevel || DemoMode || DemoPlaying)
{
LoadSaveMsg("Loading...");
if (LoadGame(load_num) == -1)
return FALSE;
QuickLoadNum = load_num;
// the (Quick)Save menu should default to the last loaded game
SaveGameGroup.cursor = load_num;
ExitMenus();
ExitLevel = TRUE;
LoadGameOutsideMoveLoop = TRUE;
if (DemoMode || DemoPlaying)
LoadGameFromDemo = TRUE;
return TRUE;
}
LoadSaveMsg("Loading...");
PauseAction();
if (LoadGame(load_num) == -1)
{
ResumeAction();
return FALSE;
}
QuickLoadNum = load_num;
// the (Quick)Save menu should default to the last loaded game
SaveGameGroup.cursor = load_num;
ready2send = 1;
LastSaveNum = -1;
ExitMenus();
if (DemoMode)
{
ExitLevel = TRUE;
DemoPlaying = FALSE;
}
return TRUE;
}
@ -2415,44 +2280,6 @@ SWBOOL MNU_GetLoadCustom(void)
////////////////////////////////////////////////
SWBOOL MNU_GetSaveCustom(void)
{
short save_num;
extern SWBOOL InMenuLevel, LoadGameOutsideMoveLoop;
save_num = currentmenu->cursor;
if (InMenuLevel)
return FALSE;
if (MenuInputMode)
{
LoadSaveMsg("Saving...");
if (DoQuickSave(save_num) == FALSE)
{
LoadGameGroup.cursor = save_num;
}
ResumeAction();
ExitMenus();
// toggle edit mode
MenuInputMode = FALSE;
}
else
{
strcpy(BackupSaveGameDescr, SaveGameDescr[save_num]);
// clear keyboard buffer
while (inputState.keyBufferWaiting())
{
if (inputState.keyGetChar() == 0)
inputState.keyGetChar();
}
// toggle edit mode
MenuInputMode = TRUE;
}
return TRUE;
}

View file

@ -284,7 +284,6 @@ typedef struct MenuGroup
// Custom Routine Prototypes ////////////////////////////////////////////////////////////////////
SWBOOL MNU_QuitCustom(UserCall call, MenuItem *item);
SWBOOL MNU_QuickLoadCustom(UserCall call, MenuItem *item);
SWBOOL MNU_LoadSaveTouchupCustom(UserCall call, MenuItem *item);
SWBOOL MNU_OrderCustom(UserCall call, MenuItem *item);
SWBOOL MNU_DoEpisodeSelect(UserCall call, MenuItem *item);

View file

@ -6475,7 +6475,6 @@ DoPlayerBeginDie(PLAYERp pp)
short bak;
int choosesnd = 0;
extern short GlobInfoStringTime;
extern short QuickLoadNum;
USERp u = User[pp->PlayerSprite];
@ -6518,11 +6517,13 @@ DoPlayerBeginDie(PLAYERp pp)
PlayerSound(PlayerLowHealthPainVocs[choosesnd],&pp->posx,
&pp->posy,&pp->posy,v3df_dontpan|v3df_doppler|v3df_follow,pp);
#if 0
if (!CommEnabled && numplayers <= 1 && QuickLoadNum >= 0)
{
ReloadPrompt = TRUE;
}
else
#endif
{
bak = GlobInfoStringTime;
GlobInfoStringTime = 999;