mirror of
https://github.com/ZDoom/Raze.git
synced 2025-05-30 17:01:03 +00:00
WIP safety commit
This commit is contained in:
parent
9cb6c65223
commit
2a9e4fca46
37 changed files with 772 additions and 903 deletions
|
@ -762,38 +762,6 @@ void StartNetworkLevel(void)
|
||||||
|
|
||||||
int gDoQuickSave = 0;
|
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)
|
void LocalKeys(void)
|
||||||
{
|
{
|
||||||
bool alt = inputState.AltPressed();
|
bool alt = inputState.AltPressed();
|
||||||
|
@ -831,21 +799,6 @@ void LocalKeys(void)
|
||||||
gView = &gPlayer[gViewIndex];
|
gView = &gPlayer[gViewIndex];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (gDoQuickSave)
|
|
||||||
{
|
|
||||||
inputState.keyFlushScans();
|
|
||||||
switch (gDoQuickSave)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
DoQuickSave();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
DoQuickLoad();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
gDoQuickSave = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
char key;
|
char key;
|
||||||
if ((key = inputState.keyGetScan()) != 0)
|
if ((key = inputState.keyGetScan()) != 0)
|
||||||
{
|
{
|
||||||
|
@ -914,19 +867,11 @@ void LocalKeys(void)
|
||||||
if (!gGameMenuMgr.m_bActive)
|
if (!gGameMenuMgr.m_bActive)
|
||||||
gGameMenuMgr.Push(&menuOptions,-1);
|
gGameMenuMgr.Push(&menuOptions,-1);
|
||||||
return;
|
return;
|
||||||
case sc_F6:
|
|
||||||
inputState.keyFlushScans();
|
|
||||||
DoQuickSave();
|
|
||||||
break;
|
|
||||||
case sc_F8:
|
case sc_F8:
|
||||||
inputState.keyFlushScans();
|
inputState.keyFlushScans();
|
||||||
if (!gGameMenuMgr.m_bActive)
|
if (!gGameMenuMgr.m_bActive)
|
||||||
gGameMenuMgr.Push(&menuOptionsDisplayMode, -1);
|
gGameMenuMgr.Push(&menuOptionsDisplayMode, -1);
|
||||||
return;
|
return;
|
||||||
case sc_F9:
|
|
||||||
inputState.keyFlushScans();
|
|
||||||
DoQuickLoad();
|
|
||||||
break;
|
|
||||||
case sc_F10:
|
case sc_F10:
|
||||||
inputState.keyFlushScans();
|
inputState.keyFlushScans();
|
||||||
if (!gGameMenuMgr.m_bActive)
|
if (!gGameMenuMgr.m_bActive)
|
||||||
|
|
|
@ -2055,9 +2055,6 @@ void TenProcess(CGameMenuItem7EA1C *pItem)
|
||||||
UNREFERENCED_PARAMETER(pItem);
|
UNREFERENCED_PARAMETER(pItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
short gQuickLoadSlot = -1;
|
|
||||||
short gQuickSaveSlot = -1;
|
|
||||||
|
|
||||||
void SaveGame(CGameMenuItemZEditBitmap *pItem, CGameMenuEvent *event)
|
void SaveGame(CGameMenuItemZEditBitmap *pItem, CGameMenuEvent *event)
|
||||||
{
|
{
|
||||||
int nSlot = pItem->at28;
|
int nSlot = pItem->at28;
|
||||||
|
@ -2077,31 +2074,6 @@ void SaveGame(CGameMenuItemZEditBitmap *pItem, CGameMenuEvent *event)
|
||||||
videoNextPage();
|
videoNextPage();
|
||||||
gSaveGameNum = nSlot;
|
gSaveGameNum = nSlot;
|
||||||
LoadSave::SaveGame(strSaveGameName.GetChars());
|
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();
|
gGameMenuMgr.Deactivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2119,22 +2091,6 @@ void LoadGame(CGameMenuItemZEditBitmap *pItem, CGameMenuEvent *event)
|
||||||
videoNextPage();
|
videoNextPage();
|
||||||
LoadSave::LoadGame(strLoadGameName);
|
LoadSave::LoadGame(strLoadGameName);
|
||||||
gGameMenuMgr.Deactivate();
|
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)
|
void SetupLevelMenuItem(int nEpisode)
|
||||||
|
|
|
@ -51,13 +51,9 @@ extern CGameMenu menuSorry2;
|
||||||
extern CGameMenu menuOptions;
|
extern CGameMenu menuOptions;
|
||||||
extern CGameMenu menuOptionsSound;
|
extern CGameMenu menuOptionsSound;
|
||||||
extern CGameMenu menuOptionsDisplayMode;
|
extern CGameMenu menuOptionsDisplayMode;
|
||||||
extern short gQuickLoadSlot;
|
|
||||||
extern short gQuickSaveSlot;
|
|
||||||
extern char strRestoreGameStrings[][16];
|
extern char strRestoreGameStrings[][16];
|
||||||
void drawLoadingScreen(void);
|
void drawLoadingScreen(void);
|
||||||
void SetupMenus(void);
|
void SetupMenus(void);
|
||||||
void UpdateNetworkMenus(void);
|
void UpdateNetworkMenus(void);
|
||||||
void QuickSaveGame(void);
|
|
||||||
void QuickLoadGame(void);
|
|
||||||
|
|
||||||
END_BLD_NS
|
END_BLD_NS
|
||||||
|
|
|
@ -371,23 +371,6 @@ void onvideomodechange(int32_t newmode)
|
||||||
UpdateDacs(gLastPal, false);
|
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
|
#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("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("god","god: toggles god mode", osdcmd_god);
|
||||||
OSD_RegisterFunction("noclip","noclip: toggles clipping mode", osdcmd_noclip);
|
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("restartsound","restartsound: reinitializes the sound system",osdcmd_restartsound);
|
||||||
|
|
||||||
OSD_RegisterFunction("vidmode","vidmode <xdim> <ydim> <bpp> <fullscreen>: change the video mode",osdcmd_vidmode);
|
OSD_RegisterFunction("vidmode","vidmode <xdim> <ydim> <bpp> <fullscreen>: change the video mode",osdcmd_vidmode);
|
||||||
|
|
|
@ -185,6 +185,22 @@ struct FSavegameInfo
|
||||||
int currentsavever;
|
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;
|
enum EMenuSounds : int;
|
||||||
|
|
||||||
struct GameInterface
|
struct GameInterface
|
||||||
|
@ -210,8 +226,8 @@ struct GameInterface
|
||||||
virtual bool DrawSpecialScreen(const DVector2 &origin, int tilenum) { return false; }
|
virtual bool DrawSpecialScreen(const DVector2 &origin, int tilenum) { return false; }
|
||||||
virtual void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position) {}
|
virtual void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position) {}
|
||||||
virtual void DrawMenuCaption(const DVector2& origin, const char* text) {}
|
virtual void DrawMenuCaption(const DVector2& origin, const char* text) {}
|
||||||
|
virtual bool SaveGame(FSaveGameNode*) { return false; }
|
||||||
|
virtual bool LoadGame(FSaveGameNode*) { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
extern GameInterface* gi;
|
extern GameInterface* gi;
|
||||||
|
|
|
@ -10045,7 +10045,7 @@ void videoNextPage(void)
|
||||||
|
|
||||||
if (!recursion)
|
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.
|
// 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.
|
// Ideally this stuff should be moved out of videoNextPage so that all those busy loops won't call UI overlays at all.
|
||||||
recursion = true;
|
recursion = true;
|
||||||
|
|
|
@ -106,8 +106,6 @@ static const ButtonDesc gamefuncs[] = {
|
||||||
{ gamefunc_Dpad_Aiming, "Dpad_Aiming"},
|
{ gamefunc_Dpad_Aiming, "Dpad_Aiming"},
|
||||||
{ gamefunc_AutoRun, "AutoRun"},
|
{ gamefunc_AutoRun, "AutoRun"},
|
||||||
{ gamefunc_Last_Weapon, "Last_Used_Weapon"},
|
{ gamefunc_Last_Weapon, "Last_Used_Weapon"},
|
||||||
{ gamefunc_Quick_Save, "Quick_Save"},
|
|
||||||
{ gamefunc_Quick_Load, "Quick_Load"},
|
|
||||||
{ gamefunc_Alt_Weapon, "Alt_Weapon"},
|
{ gamefunc_Alt_Weapon, "Alt_Weapon"},
|
||||||
{ gamefunc_Third_Person_View, "Third_Person_View"},
|
{ gamefunc_Third_Person_View, "Third_Person_View"},
|
||||||
{ gamefunc_Toggle_Crouch, "Toggle_Crouch"},
|
{ gamefunc_Toggle_Crouch, "Toggle_Crouch"},
|
||||||
|
|
|
@ -72,8 +72,6 @@ enum GameFunction_t
|
||||||
gamefunc_Dpad_Aiming,
|
gamefunc_Dpad_Aiming,
|
||||||
gamefunc_AutoRun,
|
gamefunc_AutoRun,
|
||||||
gamefunc_Last_Weapon,
|
gamefunc_Last_Weapon,
|
||||||
gamefunc_Quick_Save,
|
|
||||||
gamefunc_Quick_Load,
|
|
||||||
gamefunc_Alt_Weapon,
|
gamefunc_Alt_Weapon,
|
||||||
gamefunc_Third_Person_View,
|
gamefunc_Third_Person_View,
|
||||||
gamefunc_See_Chase_View = gamefunc_Third_Person_View, // this was added by Blood
|
gamefunc_See_Chase_View = gamefunc_Third_Person_View, // this was added by Blood
|
||||||
|
|
|
@ -360,6 +360,9 @@ void M_StartControlPanel (bool makeSound)
|
||||||
created = true;
|
created = true;
|
||||||
M_CreateMenus();
|
M_CreateMenus();
|
||||||
}
|
}
|
||||||
|
FX_StopAllSounds();
|
||||||
|
gi->MenuOpened();
|
||||||
|
if (makeSound) gi->MenuSound(ActivateSound);
|
||||||
|
|
||||||
buttonMap.ResetButtonStates ();
|
buttonMap.ResetButtonStates ();
|
||||||
inputState.ClearAllKeyStatus();
|
inputState.ClearAllKeyStatus();
|
||||||
|
@ -964,10 +967,8 @@ CCMD(reset2saved)
|
||||||
|
|
||||||
CCMD(openmainmenu)
|
CCMD(openmainmenu)
|
||||||
{
|
{
|
||||||
FX_StopAllSounds();
|
|
||||||
//gi->ClearSoundLocks();
|
//gi->ClearSoundLocks();
|
||||||
//gi->MenuSound();
|
M_StartControlPanel(true);
|
||||||
M_StartControlPanel(false);
|
|
||||||
M_SetMenu(NAME_IngameMenu);
|
M_SetMenu(NAME_IngameMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -975,8 +976,7 @@ CCMD(openhelpmenu)
|
||||||
{
|
{
|
||||||
if (!help_disabled)
|
if (!help_disabled)
|
||||||
{
|
{
|
||||||
gi->MenuOpened();
|
M_StartControlPanel(true);
|
||||||
M_StartControlPanel(false);
|
|
||||||
M_SetMenu(NAME_HelpMenu);
|
M_SetMenu(NAME_HelpMenu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -985,15 +985,13 @@ CCMD(opensavemenu)
|
||||||
{
|
{
|
||||||
if (gi->CanSave())
|
if (gi->CanSave())
|
||||||
{
|
{
|
||||||
gi->MenuOpened();
|
M_StartControlPanel(true);
|
||||||
M_StartControlPanel(false);
|
|
||||||
M_SetMenu(NAME_SaveGameMenu);
|
M_SetMenu(NAME_SaveGameMenu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CCMD(openloadmenu)
|
CCMD(openloadmenu)
|
||||||
{
|
{
|
||||||
gi->MenuOpened();
|
M_StartControlPanel(true);
|
||||||
M_StartControlPanel(false);
|
|
||||||
M_SetMenu(NAME_LoadGameMenu);
|
M_SetMenu(NAME_LoadGameMenu);
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,6 +94,7 @@ enum EMenuState : int
|
||||||
|
|
||||||
enum EMenuSounds : int
|
enum EMenuSounds : int
|
||||||
{
|
{
|
||||||
|
ActivateSound,
|
||||||
CursorSound,
|
CursorSound,
|
||||||
AdvanceSound,
|
AdvanceSound,
|
||||||
BackSound,
|
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_StartMessage(const char *message, int messagemode, int scriptId, FName action = NAME_None);
|
||||||
void M_UnhideCustomMenu(int menu, int itemmask);
|
void M_UnhideCustomMenu(int menu, int itemmask);
|
||||||
void M_MenuSound(EMenuSounds snd);
|
void M_MenuSound(EMenuSounds snd);
|
||||||
|
void M_Autosave();
|
||||||
|
|
||||||
|
|
||||||
void I_SetMouseCapture();
|
void I_SetMouseCapture();
|
||||||
|
@ -750,6 +752,10 @@ void I_ReleaseMouseCapture();
|
||||||
struct MenuClassDescriptor;
|
struct MenuClassDescriptor;
|
||||||
extern TArray<MenuClassDescriptor*> menuClasses;
|
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
|
struct MenuClassDescriptor
|
||||||
{
|
{
|
||||||
FName mName;
|
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
|
struct FSavegameManager
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -819,6 +816,9 @@ public:
|
||||||
void InsertNewSaveNode();
|
void InsertNewSaveNode();
|
||||||
bool RemoveNewSaveNode();
|
bool RemoveNewSaveNode();
|
||||||
|
|
||||||
|
void LoadGame(FSaveGameNode* node, bool ok4q, bool forceq);
|
||||||
|
void SaveGame(FSaveGameNode* node);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern FSavegameManager savegameManager;
|
extern FSavegameManager savegameManager;
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "menu/menu.h"
|
#include "menu.h"
|
||||||
#include "d_event.h"
|
#include "d_event.h"
|
||||||
#include "d_gui.h"
|
#include "d_gui.h"
|
||||||
#include "v_text.h"
|
#include "v_text.h"
|
||||||
|
@ -41,7 +41,6 @@
|
||||||
#include "c_dispatch.h"
|
#include "c_dispatch.h"
|
||||||
#include "v_2ddrawer.h"
|
#include "v_2ddrawer.h"
|
||||||
|
|
||||||
|
|
||||||
extern FSaveGameNode *quickSaveSlot;
|
extern FSaveGameNode *quickSaveSlot;
|
||||||
|
|
||||||
class DMessageBoxMenu : public DMenu
|
class DMessageBoxMenu : public DMenu
|
||||||
|
@ -52,10 +51,11 @@ class DMessageBoxMenu : public DMenu
|
||||||
int messageSelection;
|
int messageSelection;
|
||||||
int mMouseLeft, mMouseRight, mMouseY;
|
int mMouseLeft, mMouseRight, mMouseY;
|
||||||
FName mAction;
|
FName mAction;
|
||||||
|
std::function<void(bool)> mActionFunc;
|
||||||
|
|
||||||
public:
|
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 Destroy();
|
||||||
void Init(DMenu *parent, const char *message, int messagemode, bool playsound = false);
|
void Init(DMenu *parent, const char *message, int messagemode, bool playsound = false);
|
||||||
void Drawer();
|
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)
|
: DMenu(parent)
|
||||||
{
|
{
|
||||||
mAction = action;
|
mAction = action;
|
||||||
|
mActionFunc = handler;
|
||||||
messageSelection = 0;
|
messageSelection = 0;
|
||||||
mMouseLeft = 140;
|
mMouseLeft = 140;
|
||||||
mMouseY = INT_MIN;
|
mMouseY = INT_MIN;
|
||||||
|
@ -128,7 +129,7 @@ void DMessageBoxMenu::Destroy()
|
||||||
|
|
||||||
void DMessageBoxMenu::CloseSound()
|
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 (mMessageMode == 0)
|
||||||
{
|
{
|
||||||
if (mAction == NAME_None)
|
if (mActionFunc)
|
||||||
|
{
|
||||||
|
mActionFunc(res);
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
else if (mAction == NAME_None)
|
||||||
{
|
{
|
||||||
mParentMenu->MenuEvent(res? MKEY_MBYes : MKEY_MBNo, false);
|
mParentMenu->MenuEvent(res? MKEY_MBYes : MKEY_MBNo, false);
|
||||||
Close();
|
Close();
|
||||||
|
@ -358,3 +364,17 @@ void M_StartMessage(const char *message, int messagemode, int scriptId, FName ac
|
||||||
M_ActivateMenu(newmenu);
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -49,11 +49,27 @@
|
||||||
#include "files.h"
|
#include "files.h"
|
||||||
#include "savegamehelp.h"
|
#include "savegamehelp.h"
|
||||||
#include "i_specialpaths.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.
|
#include "../../platform/win32/i_findfile.h" // This is a temporary direct path. Needs to be fixed when stuff gets cleaned up.
|
||||||
|
|
||||||
|
|
||||||
FSavegameManager savegameManager;
|
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
|
// Save data maintenance
|
||||||
|
@ -261,7 +277,7 @@ void FSavegameManager::NotifyNewSave(const FString &file, const FString &title,
|
||||||
|
|
||||||
void FSavegameManager::LoadSavegame(int Selected)
|
void FSavegameManager::LoadSavegame(int Selected)
|
||||||
{
|
{
|
||||||
//G_LoadGame(SaveGames[Selected]->Filename.GetChars(), true);
|
savegameManager.LoadGame(SaveGames[Selected]);
|
||||||
if (quickSaveSlot == (FSaveGameNode*)1)
|
if (quickSaveSlot == (FSaveGameNode*)1)
|
||||||
{
|
{
|
||||||
quickSaveSlot = SaveGames[Selected];
|
quickSaveSlot = SaveGames[Selected];
|
||||||
|
@ -281,8 +297,9 @@ void FSavegameManager::DoSave(int Selected, const char *savegamestring)
|
||||||
{
|
{
|
||||||
if (Selected != 0)
|
if (Selected != 0)
|
||||||
{
|
{
|
||||||
auto node = SaveGames[Selected];
|
auto node = *SaveGames[Selected];
|
||||||
//G_SaveGame(node->Filename.GetChars(), savegamestring);
|
node.SaveTitle = savegamestring;
|
||||||
|
savegameManager.SaveGame(&node);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -298,7 +315,8 @@ void FSavegameManager::DoSave(int Selected, const char *savegamestring)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//G_SaveGame(filename, savegamestring);
|
FSaveGameNode sg{ savegamestring, filename };
|
||||||
|
savegameManager.SaveGame(&sg);
|
||||||
}
|
}
|
||||||
M_ClearMenus();
|
M_ClearMenus();
|
||||||
}
|
}
|
||||||
|
@ -505,3 +523,575 @@ bool FSavegameManager::RemoveNewSaveNode()
|
||||||
return false;
|
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
|
|
@ -20,3 +20,4 @@ int G_ValidateSavegame(FileReader &fr, FString *savetitle);
|
||||||
void G_WriteSaveHeader(const char *name, const char*mapname, const char *title);
|
void G_WriteSaveHeader(const char *name, const char*mapname, const char *title);
|
||||||
|
|
||||||
#define SAVEGAME_EXT ".dsave"
|
#define SAVEGAME_EXT ".dsave"
|
||||||
|
|
||||||
|
|
|
@ -391,6 +391,33 @@ void CreatePath(const char *fn)
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
// strbin -- In-place version
|
||||||
|
|
|
@ -36,6 +36,7 @@ bool IsNum (const char *str); // [RH] added
|
||||||
|
|
||||||
bool CheckWildcards (const char *pattern, const char *text);
|
bool CheckWildcards (const char *pattern, const char *text);
|
||||||
|
|
||||||
|
const char* myasctime();
|
||||||
int strbin (char *str);
|
int strbin (char *str);
|
||||||
FString strbin1 (const char *start);
|
FString strbin1 (const char *start);
|
||||||
|
|
||||||
|
|
|
@ -167,6 +167,8 @@ struct GameInterface : ::GameInterface
|
||||||
bool DrawSpecialScreen(const DVector2 &origin, int tilenum) override;
|
bool DrawSpecialScreen(const DVector2 &origin, int tilenum) override;
|
||||||
void DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position) override;
|
void DrawCenteredTextScreen(const DVector2 &origin, const char *text, int position) override;
|
||||||
void DrawMenuCaption(const DVector2& origin, const char* text) override;
|
void DrawMenuCaption(const DVector2& origin, const char* text) override;
|
||||||
|
bool SaveGame(FSaveGameNode*) override;
|
||||||
|
bool LoadGame(FSaveGameNode*) override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4688,45 +4688,6 @@ void G_HandleLocalKeys(void)
|
||||||
typebuf[0] = 0;
|
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))
|
if (buttonMap.ButtonDown(gamefunc_Third_Person_View))
|
||||||
{
|
{
|
||||||
buttonMap.ClearButton(gamefunc_Third_Person_View);
|
buttonMap.ClearButton(gamefunc_Third_Person_View);
|
||||||
|
@ -4749,25 +4710,6 @@ void G_HandleLocalKeys(void)
|
||||||
hud_messages = fta;
|
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)
|
if (ud.overhead_on != 0)
|
||||||
{
|
{
|
||||||
|
@ -6362,12 +6304,7 @@ MAIN_LOOP_RESTART:
|
||||||
inputState.keyFlushChars();
|
inputState.keyFlushChars();
|
||||||
videoNextPage();
|
videoNextPage();
|
||||||
|
|
||||||
g_screenCapture = 1;
|
M_Autosave();
|
||||||
G_DrawRooms(myconnectindex, 65536);
|
|
||||||
g_screenCapture = 0;
|
|
||||||
|
|
||||||
G_SavePlayerMaybeMulti(g_lastautosave, true);
|
|
||||||
g_quickload = &g_lastautosave;
|
|
||||||
|
|
||||||
g_saveRequested = false;
|
g_saveRequested = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "menu/menu.h"
|
#include "menu/menu.h"
|
||||||
|
#include "c_dispatch.h"
|
||||||
|
|
||||||
#include "debugbreak.h"
|
#include "debugbreak.h"
|
||||||
extern bool rotatesprite_2doverride;
|
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)
|
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_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)
|
if (resetFlags & 4)
|
||||||
{
|
{
|
||||||
inputState.keyFlushChars();
|
inputState.keyFlushChars();
|
||||||
inputState.ClearKeysDown();
|
inputState.ClearKeysDown();
|
||||||
FX_StopAllSounds();
|
FX_StopAllSounds();
|
||||||
S_ClearSoundLocks();
|
|
||||||
if (G_LoadPlayerMaybeMulti(*g_quickload) != 0)
|
if (G_LoadPlayerMaybeMulti(*g_quickload) != 0)
|
||||||
{
|
{
|
||||||
g_quickload->reset();
|
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_StartControlPanel(false);
|
||||||
M_SetMenu(NAME_ConfirmPlayerReset);
|
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
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
QuickLoadFailure:
|
QuickLoadFailure:
|
||||||
g_player[playerNum].ps->gm = MODE_RESTART;
|
g_player[playerNum].ps->gm = MODE_RESTART;
|
||||||
}
|
}
|
||||||
#if !defined LUNATIC
|
|
||||||
vmFlags |= VM_NOEXECUTE;
|
vmFlags |= VM_NOEXECUTE;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -4886,32 +4893,9 @@ badindex:
|
||||||
vInstruction(CON_SAVENN):
|
vInstruction(CON_SAVENN):
|
||||||
vInstruction(CON_SAVE):
|
vInstruction(CON_SAVE):
|
||||||
insptr++;
|
insptr++;
|
||||||
{
|
insptr++; // skip the slot. I will not allow the script to do targeted saving without user control.
|
||||||
int32_t const requestedSlot = *insptr++;
|
g_saveRequested = true; // cannot save right here.
|
||||||
|
dispatch();
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
vInstruction(CON_QUAKE):
|
vInstruction(CON_QUAKE):
|
||||||
insptr++;
|
insptr++;
|
||||||
|
|
|
@ -1311,7 +1311,7 @@ static void Gv_AddSystemVars(void)
|
||||||
Gv_NewVar("gravitationalconstant", (intptr_t)&g_spriteGravity, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
|
Gv_NewVar("gravitationalconstant", (intptr_t)&g_spriteGravity, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
|
||||||
Gv_NewVar("gs", (intptr_t)&hudweap.shade, 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("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("lastvisinc", (intptr_t)&lastvisinc, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
|
||||||
Gv_NewVar("looking_angSR1", (intptr_t)&hudweap.lookhalfang, 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);
|
Gv_NewVar("looking_arc", (intptr_t)&hudweap.lookhoriz, GAMEVAR_SYSTEM | GAMEVAR_INT32PTR);
|
||||||
|
@ -1465,7 +1465,7 @@ void Gv_RefreshPointers(void)
|
||||||
(intptr_t)&g_spriteGravity;
|
(intptr_t)&g_spriteGravity;
|
||||||
aGameVars[Gv_GetVarIndex("gs")].global = (intptr_t)&hudweap.shade;
|
aGameVars[Gv_GetVarIndex("gs")].global = (intptr_t)&hudweap.shade;
|
||||||
aGameVars[Gv_GetVarIndex("gun_pos")].global = (intptr_t)&hudweap.gunposy;
|
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("lastvisinc")].global = (intptr_t)&lastvisinc;
|
||||||
aGameVars[Gv_GetVarIndex("looking_angSR1")].global = (intptr_t)&hudweap.lookhalfang;
|
aGameVars[Gv_GetVarIndex("looking_angSR1")].global = (intptr_t)&hudweap.lookhalfang;
|
||||||
aGameVars[Gv_GetVarIndex("looking_arc")].global = (intptr_t)&hudweap.lookhoriz;
|
aGameVars[Gv_GetVarIndex("looking_arc")].global = (intptr_t)&hudweap.lookhoriz;
|
||||||
|
|
|
@ -1432,12 +1432,6 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin)
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case MENU_SAVECLEANVERIFY:
|
||||||
videoFadeToBlack(1);
|
videoFadeToBlack(1);
|
||||||
|
|
|
@ -687,24 +687,6 @@ void onvideomodechange(int32_t newmode)
|
||||||
g_crosshairSum = -1;
|
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)
|
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("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("restartmap", "restartmap: restarts the current map", osdcmd_restartmap);
|
||||||
OSD_RegisterFunction("restartsound","restartsound: reinitializes the sound system",osdcmd_restartsound);
|
OSD_RegisterFunction("restartsound","restartsound: reinitializes the sound system",osdcmd_restartsound);
|
||||||
OSD_RegisterFunction("addlogvar","addlogvar <gamevar>: prints the value of a gamevar", osdcmd_addlogvar);
|
OSD_RegisterFunction("addlogvar","addlogvar <gamevar>: prints the value of a gamevar", osdcmd_addlogvar);
|
||||||
|
|
|
@ -1341,11 +1341,6 @@ void G_NewGame(int volumeNum, int levelNum, int skillNum)
|
||||||
ud.volume_number = volumeNum;
|
ud.volume_number = volumeNum;
|
||||||
STAT_StartNewGame(gVolumeNames[volumeNum], skillNum);
|
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
|
// we don't want the intro to play after the multiplayer setup screen
|
||||||
if ((!g_netServer && ud.multimode < 2) && !Menu_HaveUserMap()
|
if ((!g_netServer && ud.multimode < 2) && !Menu_HaveUserMap()
|
||||||
&& !VM_OnEventWithReturn(EVENT_NEWGAMESCREEN, g_player[myconnectindex].ps->i, myconnectindex, 0)
|
&& !VM_OnEventWithReturn(EVENT_NEWGAMESCREEN, g_player[myconnectindex].ps->i, myconnectindex, 0)
|
||||||
|
|
|
@ -141,10 +141,8 @@ void G_ResetInterpolations(void)
|
||||||
G_SetInterpolation(g_animatePtr[i]);
|
G_SetInterpolation(g_animatePtr[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
savebrief_t g_lastautosave, g_lastusersave, g_freshload;
|
int32_t g_fakeSaveID = -1;
|
||||||
int32_t g_lastAutoSaveArbitraryID = -1;
|
|
||||||
bool g_saveRequested;
|
bool g_saveRequested;
|
||||||
savebrief_t * g_quickload;
|
|
||||||
|
|
||||||
|
|
||||||
static FileReader *OpenSavegame(const char *fn)
|
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?)
|
// 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 volume = -1;
|
||||||
int level = -1;
|
int level = -1;
|
||||||
int skill = -1;
|
int skill = -1;
|
||||||
|
|
||||||
auto fil = OpenSavegame(sv.path);
|
auto fil = OpenSavegame(sv->Filename);
|
||||||
if (!fil) return -1;
|
if (!fil) return -1;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -354,8 +352,6 @@ int32_t G_LoadPlayer(savebrief_t & sv)
|
||||||
ud.skill_voice = -1;
|
ud.skill_voice = -1;
|
||||||
ud.volume_number = volume;
|
ud.volume_number = volume;
|
||||||
|
|
||||||
g_lastAutoSaveArbitraryID = -1;
|
|
||||||
|
|
||||||
#ifdef EDUKE32_TOUCH_DEVICES
|
#ifdef EDUKE32_TOUCH_DEVICES
|
||||||
p0.zoom = 360;
|
p0.zoom = 360;
|
||||||
#else
|
#else
|
||||||
|
@ -465,7 +461,7 @@ int32_t G_LoadPlayer(savebrief_t & sv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto fil = OpenSavegame(sv.path);
|
auto fil = OpenSavegame(sv->Filename);
|
||||||
|
|
||||||
if (!fil)
|
if (!fil)
|
||||||
return -1;
|
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
|
// in theory, we could load into an initial dump first and trivially
|
||||||
// recover if things go wrong...
|
// 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);
|
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__
|
#ifdef __ANDROID__
|
||||||
G_SavePalette();
|
G_SavePalette();
|
||||||
|
@ -598,62 +594,26 @@ int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave)
|
||||||
errno = 0;
|
errno = 0;
|
||||||
FileWriter *fil;
|
FileWriter *fil;
|
||||||
|
|
||||||
if (sv.isValid())
|
fn = G_BuildSaveName(sv->Filename);
|
||||||
{
|
OpenSaveGameForWrite(fn);
|
||||||
fn = G_BuildSaveName(sv.path);
|
fil = WriteSavegameChunk("snapshot.dat");
|
||||||
OpenSaveGameForWrite(fn);
|
// The above call cannot fail.
|
||||||
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
|
|
||||||
{
|
{
|
||||||
auto& fw = *fil;
|
auto& fw = *fil;
|
||||||
|
|
||||||
sv.isExt = 0;
|
|
||||||
|
|
||||||
// temporary hack
|
// temporary hack
|
||||||
ud.user_map = G_HaveUserMap();
|
ud.user_map = G_HaveUserMap();
|
||||||
|
|
||||||
VM_OnEvent(EVENT_SAVEGAME, g_player[myconnectindex].ps->i, myconnectindex);
|
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!
|
// SAVE!
|
||||||
sv_saveandmakesnapshot(fw, sv.name, 0, 0, 0, 0, isAutoSave);
|
sv_saveandmakesnapshot(fw, sv->SaveTitle, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
|
||||||
fw.Close();
|
fw.Close();
|
||||||
FinishSavegameWrite();
|
bool res = FinishSavegameWrite();
|
||||||
|
|
||||||
if (!g_netServer && ud.multimode < 2)
|
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);
|
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)
|
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);
|
P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps);
|
||||||
|
|
||||||
// g_player[myconnectindex].ps->gm = MODE_GAME;
|
// g_player[myconnectindex].ps->gm = MODE_GAME;
|
||||||
return 127;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int32_t c = G_LoadPlayer(sv);
|
int32_t c = G_LoadPlayer(sv);
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
g_player[myconnectindex].ps->gm = MODE_GAME;
|
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)
|
if (g_netServer || ud.multimode > 1)
|
||||||
{
|
{
|
||||||
Bstrcpy(apStrings[QUOTE_RESERVED4], "Multiplayer Saving Not Yet Supported");
|
Bstrcpy(apStrings[QUOTE_RESERVED4], "Multiplayer Saving Not Yet Supported");
|
||||||
P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps);
|
P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else
|
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)
|
// 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;
|
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.majorver = SV_MAJOR_VER;
|
||||||
h.minorver = SV_MINOR_VER;
|
h.minorver = SV_MINOR_VER;
|
||||||
h.ptrsize = sizeof(intptr_t);
|
h.ptrsize = sizeof(intptr_t);
|
||||||
|
|
||||||
if (isAutoSave)
|
|
||||||
h.ptrsize |= 1u << 7u;
|
|
||||||
|
|
||||||
h.bytever = BYTEVERSION;
|
h.bytever = BYTEVERSION;
|
||||||
h.userbytever = ud.userbytever;
|
h.userbytever = ud.userbytever;
|
||||||
h.scriptcrc = g_scriptcrc;
|
h.scriptcrc = g_scriptcrc;
|
||||||
|
|
|
@ -57,62 +57,13 @@ typedef struct
|
||||||
uint8_t numplayers, volnum, levnum, skill;
|
uint8_t numplayers, volnum, levnum, skill;
|
||||||
char boardfn[BMAX_PATH];
|
char boardfn[BMAX_PATH];
|
||||||
// 286 bytes
|
// 286 bytes
|
||||||
#ifdef __ANDROID__
|
|
||||||
char skillname[32], volname[32];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint8_t getPtrSize() const { return ptrsize & 0x7Fu; }
|
uint8_t getPtrSize() const { return ptrsize; }
|
||||||
bool isAutoSave() const { return !!(ptrsize & (1u<<7u)); }
|
|
||||||
} savehead_t;
|
} savehead_t;
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
struct savebrief_t
|
extern int32_t g_fakeSaveID;
|
||||||
{
|
|
||||||
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 bool g_saveRequested;
|
extern bool g_saveRequested;
|
||||||
extern savebrief_t * g_quickload;
|
|
||||||
|
|
||||||
|
|
||||||
int32_t sv_updatestate(int32_t frominit);
|
int32_t sv_updatestate(int32_t frominit);
|
||||||
|
@ -120,14 +71,10 @@ int32_t sv_readdiff(FileReader& fil);
|
||||||
uint32_t sv_writediff(FileWriter *fil);
|
uint32_t sv_writediff(FileWriter *fil);
|
||||||
int32_t sv_loadheader(FileReader &fil, int32_t spot, savehead_t *h);
|
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_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();
|
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);
|
int32_t G_LoadSaveHeaderNew(char const *fn, savehead_t *saveh);
|
||||||
void ReadSaveGameHeaders(void);
|
void ReadSaveGameHeaders(void);
|
||||||
void G_SavePlayerMaybeMulti(savebrief_t & sv, bool isAutoSave = false);
|
|
||||||
int32_t G_LoadPlayerMaybeMulti(savebrief_t & sv);
|
|
||||||
|
|
||||||
#ifdef YAX_ENABLE
|
#ifdef YAX_ENABLE
|
||||||
extern void sv_postyaxload(void);
|
extern void sv_postyaxload(void);
|
||||||
|
|
|
@ -167,6 +167,8 @@ struct GameInterface : ::GameInterface
|
||||||
FSavegameInfo GetSaveSig() override;
|
FSavegameInfo GetSaveSig() override;
|
||||||
void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position) override;
|
void DrawCenteredTextScreen(const DVector2& origin, const char* text, int position) override;
|
||||||
void DrawMenuCaption(const DVector2& origin, const char* text) override;
|
void DrawMenuCaption(const DVector2& origin, const char* text) override;
|
||||||
|
bool SaveGame(FSaveGameNode*) override;
|
||||||
|
bool LoadGame(FSaveGameNode*) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
END_RR_NS
|
END_RR_NS
|
||||||
|
|
|
@ -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))
|
if (buttonMap.ButtonDown(gamefunc_Third_Person_View))
|
||||||
{
|
{
|
||||||
buttonMap.ClearButton(gamefunc_Third_Person_View);
|
buttonMap.ClearButton(gamefunc_Third_Person_View);
|
||||||
|
@ -6297,26 +6257,6 @@ void G_HandleLocalKeys(void)
|
||||||
hud_messages = fta;
|
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)
|
if (ud.overhead_on != 0)
|
||||||
{
|
{
|
||||||
int const timerOffset = ((int) totalclock - nonsharedtimer);
|
int const timerOffset = ((int) totalclock - nonsharedtimer);
|
||||||
|
@ -7783,7 +7723,7 @@ MAIN_LOOP_RESTART:
|
||||||
{
|
{
|
||||||
idle();
|
idle();
|
||||||
}
|
}
|
||||||
else */if (G_FPSLimit() || g_saveRequested)
|
else */if (G_FPSLimit())
|
||||||
{
|
{
|
||||||
int const smoothRatio = calc_smoothratio(totalclock, ototalclock);
|
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)
|
if (g_player[myconnectindex].ps->gm&MODE_DEMO)
|
||||||
goto MAIN_LOOP_RESTART;
|
goto MAIN_LOOP_RESTART;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1061,12 +1061,14 @@ static int32_t VM_ResetPlayer(int const playerNum, int32_t vmFlags)
|
||||||
//AddLog("resetplayer");
|
//AddLog("resetplayer");
|
||||||
if (!g_netServer && ud.multimode < 2)
|
if (!g_netServer && ud.multimode < 2)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
if (g_quickload && g_quickload->isValid() && ud.recstat != 2)
|
if (g_quickload && g_quickload->isValid() && ud.recstat != 2)
|
||||||
{
|
{
|
||||||
M_StartControlPanel(false);
|
M_StartControlPanel(false);
|
||||||
M_SetMenu(NAME_ConfirmPlayerReset);
|
M_SetMenu(NAME_ConfirmPlayerReset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
g_player[playerNum].ps->gm = MODE_RESTART;
|
g_player[playerNum].ps->gm = MODE_RESTART;
|
||||||
vmFlags |= VM_NOEXECUTE;
|
vmFlags |= VM_NOEXECUTE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1472,17 +1472,6 @@ static void Menu_PreDraw(MenuID_t cm, MenuEntry_t *entry, const vec2_t origin)
|
||||||
case MENU_MOUSEADVANCED:
|
case MENU_MOUSEADVANCED:
|
||||||
break;
|
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:
|
case MENU_NEWVERIFY:
|
||||||
videoFadeToBlack(1);
|
videoFadeToBlack(1);
|
||||||
mgametextcenter(origin.x, origin.y + (90<<16), "Abort this game?"
|
mgametextcenter(origin.x, origin.y + (90<<16), "Abort this game?"
|
||||||
|
|
|
@ -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
|
#if !defined NETCODE_DISABLE
|
||||||
static int osdcmd_disconnect(osdcmdptr_t UNUSED(parm))
|
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("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("restartmap", "restartmap: restarts the current map", osdcmd_restartmap);
|
||||||
OSD_RegisterFunction("restartsound","restartsound: reinitializes the sound system",osdcmd_restartsound);
|
OSD_RegisterFunction("restartsound","restartsound: reinitializes the sound system",osdcmd_restartsound);
|
||||||
|
|
||||||
|
|
|
@ -1905,11 +1905,7 @@ void G_NewGame(int volumeNum, int levelNum, int skillNum)
|
||||||
STAT_StartNewGame(gVolumeNames[volumeNum], skillNum);
|
STAT_StartNewGame(gVolumeNames[volumeNum], skillNum);
|
||||||
|
|
||||||
ud.last_level = -1;
|
ud.last_level = -1;
|
||||||
g_lastAutoSaveArbitraryID = -1;
|
|
||||||
g_lastautosave.reset();
|
|
||||||
g_lastusersave.reset();
|
|
||||||
g_quickload = nullptr;
|
|
||||||
|
|
||||||
int const UserMap = Menu_HaveUserMap();
|
int const UserMap = Menu_HaveUserMap();
|
||||||
|
|
||||||
// we don't want the intro to play after the multiplayer setup screen
|
// we don't want the intro to play after the multiplayer setup screen
|
||||||
|
|
|
@ -138,16 +138,6 @@ void G_ResetInterpolations(void)
|
||||||
G_SetInterpolation(g_animatePtr[i]);
|
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)
|
static FileReader *OpenSavegame(const char *fn)
|
||||||
{
|
{
|
||||||
|
@ -226,9 +216,9 @@ static void sv_postudload();
|
||||||
static int different_user_map;
|
static int different_user_map;
|
||||||
|
|
||||||
// XXX: keyboard input 'blocked' after load fail? (at least ESC?)
|
// 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)
|
if (!fil)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -255,6 +245,7 @@ int32_t G_LoadPlayer(savebrief_t & sv)
|
||||||
|
|
||||||
// some setup first
|
// some setup first
|
||||||
ud.multimode = h.numplayers;
|
ud.multimode = h.numplayers;
|
||||||
|
S_PauseSounds(true);
|
||||||
|
|
||||||
if (numplayers > 1)
|
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
|
// in theory, we could load into an initial dump first and trivially
|
||||||
// recover if things go wrong...
|
// 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);
|
G_GameExit(tempbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,12 +330,8 @@ static void G_RestoreTimers(void)
|
||||||
lockclock = g_timers.lockclock;
|
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();
|
G_SaveTimers();
|
||||||
|
|
||||||
Net_WaitForEverybody();
|
Net_WaitForEverybody();
|
||||||
|
@ -355,59 +342,23 @@ int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave)
|
||||||
errno = 0;
|
errno = 0;
|
||||||
FileWriter *fil;
|
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;
|
auto& fw = *fil;
|
||||||
//CompressedFileWriter fw(fil, true);
|
|
||||||
|
|
||||||
// temporary hack
|
// temporary hack
|
||||||
ud.user_map = G_HaveUserMap();
|
ud.user_map = G_HaveUserMap();
|
||||||
|
|
||||||
|
|
||||||
// SAVE!
|
// SAVE!
|
||||||
sv_saveandmakesnapshot(fw, sv.name, 0, 0, 0, 0, isAutoSave);
|
sv_saveandmakesnapshot(fw, sv->SaveTitle, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
|
||||||
fw.Close();
|
fw.Close();
|
||||||
FinishSavegameWrite();
|
bool res = FinishSavegameWrite();
|
||||||
|
|
||||||
if (!g_netServer && ud.multimode < 2)
|
if (!g_netServer && ud.multimode < 2)
|
||||||
{
|
{
|
||||||
|
@ -422,11 +373,11 @@ int32_t G_SavePlayer(savebrief_t & sv, bool isAutoSave)
|
||||||
G_RestoreTimers();
|
G_RestoreTimers();
|
||||||
ototalclock = totalclock;
|
ototalclock = totalclock;
|
||||||
|
|
||||||
return 0;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t G_LoadPlayerMaybeMulti(savebrief_t & sv)
|
bool GameInterface::LoadGame(FSaveGameNode* sv)
|
||||||
{
|
{
|
||||||
if (g_netServer || ud.multimode > 1)
|
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);
|
P_DoQuote(QUOTE_RESERVED4, g_player[myconnectindex].ps);
|
||||||
|
|
||||||
// g_player[myconnectindex].ps->gm = MODE_GAME;
|
// g_player[myconnectindex].ps->gm = MODE_GAME;
|
||||||
return 127;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int32_t c = G_LoadPlayer(sv);
|
int32_t c = G_LoadPlayer(sv->Filename);
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
g_player[myconnectindex].ps->gm = MODE_GAME;
|
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)
|
if (g_netServer || ud.multimode > 1)
|
||||||
{
|
{
|
||||||
|
@ -454,7 +405,13 @@ void G_SavePlayerMaybeMulti(savebrief_t & sv, bool isAutoSave)
|
||||||
}
|
}
|
||||||
else
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,64 +52,11 @@ typedef struct
|
||||||
uint8_t numplayers, volnum, levnum, skill;
|
uint8_t numplayers, volnum, levnum, skill;
|
||||||
char boardfn[BMAX_PATH];
|
char boardfn[BMAX_PATH];
|
||||||
// 286 bytes
|
// 286 bytes
|
||||||
#ifdef __ANDROID__
|
|
||||||
char skillname[32], volname[32];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint8_t getPtrSize() const { return ptrsize & 0x7Fu; }
|
uint8_t getPtrSize() const { return ptrsize; }
|
||||||
bool isAutoSave() const { return !!(ptrsize & (1u<<7u)); }
|
|
||||||
} savehead_t;
|
} savehead_t;
|
||||||
#pragma pack(pop)
|
#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_updatestate(int32_t frominit);
|
||||||
int32_t sv_readdiff(FileReader& fil);
|
int32_t sv_readdiff(FileReader& fil);
|
||||||
uint32_t sv_writediff(FileWriter *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_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, bool isAutoSave = false);
|
||||||
void sv_freemem();
|
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);
|
int32_t G_LoadSaveHeaderNew(char const *fn, savehead_t *saveh);
|
||||||
void ReadSaveGameHeaders(void);
|
void ReadSaveGameHeaders(void);
|
||||||
void G_SavePlayerMaybeMulti(savebrief_t & sv, bool isAutoSave = false);
|
|
||||||
int32_t G_LoadPlayerMaybeMulti(savebrief_t & sv);
|
|
||||||
|
|
||||||
#ifdef YAX_ENABLE
|
#ifdef YAX_ENABLE
|
||||||
extern void sv_postyaxload(void);
|
extern void sv_postyaxload(void);
|
||||||
|
|
|
@ -3338,40 +3338,6 @@ void ConKey(void)
|
||||||
|
|
||||||
char WangBangMacro[10][64];
|
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
|
void
|
||||||
FunctionKeys(PLAYERp pp)
|
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 (ReloadPrompt)
|
||||||
{
|
{
|
||||||
if (QuickLoadNum < 0)
|
ReloadPrompt = FALSE;
|
||||||
{
|
/*
|
||||||
ReloadPrompt = FALSE;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
inputState.SetKeyStatus(sc_Escape);
|
inputState.SetKeyStatus(sc_Escape);
|
||||||
ControlPanelType = ct_quickloadmenu;
|
ControlPanelType = ct_quickloadmenu;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2373,10 +2373,7 @@ int COVERinsertsprite(short sectnum, short statnum); //returns (short)spritenu
|
||||||
void AudioUpdate(void); // stupid
|
void AudioUpdate(void); // stupid
|
||||||
|
|
||||||
extern short LastSaveNum;
|
extern short LastSaveNum;
|
||||||
extern short QuickLoadNum;
|
|
||||||
void LoadSaveMsg(const char *msg);
|
void LoadSaveMsg(const char *msg);
|
||||||
SWBOOL DoQuickSave(short save_num);
|
|
||||||
SWBOOL DoQuickLoad(void);
|
|
||||||
|
|
||||||
struct GameInterface : ::GameInterface
|
struct GameInterface : ::GameInterface
|
||||||
{
|
{
|
||||||
|
|
|
@ -67,8 +67,6 @@ signed char MNU_InputString(char*, short);
|
||||||
|
|
||||||
short TimeLimitTable[9] = {0,3,5,10,15,20,30,45,60};
|
short TimeLimitTable[9] = {0,3,5,10,15,20,30,45,60};
|
||||||
|
|
||||||
short QuickLoadNum = -1;
|
|
||||||
char QuickLoadDescrDialog[128];
|
|
||||||
SWBOOL SavePrompt = FALSE;
|
SWBOOL SavePrompt = FALSE;
|
||||||
extern SWBOOL InMenuLevel, LoadGameOutsideMoveLoop, LoadGameFromDemo;
|
extern SWBOOL InMenuLevel, LoadGameOutsideMoveLoop, LoadGameFromDemo;
|
||||||
extern uint8_t RedBookSong[40];
|
extern uint8_t RedBookSong[40];
|
||||||
|
@ -511,7 +509,7 @@ MenuItem save_i[] =
|
||||||
|
|
||||||
// No actual submenus for this, just quit text.
|
// No actual submenus for this, just quit text.
|
||||||
MenuGroup quitgroup = {0, 0, NULL, NULL, 0, 0, m_defshade, MNU_QuitCustom, NULL, 0};
|
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};
|
MenuGroup ordergroup = {0, 0, NULL, NULL, 0, 0, m_defshade, MNU_OrderCustom, NULL, 0};
|
||||||
|
|
||||||
// save and load function calls
|
// save and load function calls
|
||||||
|
@ -1734,87 +1732,6 @@ MNU_QuitCustom(UserCall call, MenuItem_p item)
|
||||||
return TRUE;
|
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 /////////////////////////////////////////////////////////////////////////////////
|
// MENU FUNCTIONS /////////////////////////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////
|
////////////////////////////////////////////////
|
||||||
// Set some global menu related defaults
|
// Set some global menu related defaults
|
||||||
|
@ -2349,58 +2266,6 @@ void LoadSaveMsg(const char *msg)
|
||||||
////////////////////////////////////////////////
|
////////////////////////////////////////////////
|
||||||
SWBOOL MNU_GetLoadCustom(void)
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2415,44 +2280,6 @@ SWBOOL MNU_GetLoadCustom(void)
|
||||||
////////////////////////////////////////////////
|
////////////////////////////////////////////////
|
||||||
SWBOOL MNU_GetSaveCustom(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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -284,7 +284,6 @@ typedef struct MenuGroup
|
||||||
// Custom Routine Prototypes ////////////////////////////////////////////////////////////////////
|
// Custom Routine Prototypes ////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
SWBOOL MNU_QuitCustom(UserCall call, MenuItem *item);
|
SWBOOL MNU_QuitCustom(UserCall call, MenuItem *item);
|
||||||
SWBOOL MNU_QuickLoadCustom(UserCall call, MenuItem *item);
|
|
||||||
SWBOOL MNU_LoadSaveTouchupCustom(UserCall call, MenuItem *item);
|
SWBOOL MNU_LoadSaveTouchupCustom(UserCall call, MenuItem *item);
|
||||||
SWBOOL MNU_OrderCustom(UserCall call, MenuItem *item);
|
SWBOOL MNU_OrderCustom(UserCall call, MenuItem *item);
|
||||||
SWBOOL MNU_DoEpisodeSelect(UserCall call, MenuItem *item);
|
SWBOOL MNU_DoEpisodeSelect(UserCall call, MenuItem *item);
|
||||||
|
|
|
@ -6475,7 +6475,6 @@ DoPlayerBeginDie(PLAYERp pp)
|
||||||
short bak;
|
short bak;
|
||||||
int choosesnd = 0;
|
int choosesnd = 0;
|
||||||
extern short GlobInfoStringTime;
|
extern short GlobInfoStringTime;
|
||||||
extern short QuickLoadNum;
|
|
||||||
|
|
||||||
USERp u = User[pp->PlayerSprite];
|
USERp u = User[pp->PlayerSprite];
|
||||||
|
|
||||||
|
@ -6518,11 +6517,13 @@ DoPlayerBeginDie(PLAYERp pp)
|
||||||
PlayerSound(PlayerLowHealthPainVocs[choosesnd],&pp->posx,
|
PlayerSound(PlayerLowHealthPainVocs[choosesnd],&pp->posx,
|
||||||
&pp->posy,&pp->posy,v3df_dontpan|v3df_doppler|v3df_follow,pp);
|
&pp->posy,&pp->posy,v3df_dontpan|v3df_doppler|v3df_follow,pp);
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (!CommEnabled && numplayers <= 1 && QuickLoadNum >= 0)
|
if (!CommEnabled && numplayers <= 1 && QuickLoadNum >= 0)
|
||||||
{
|
{
|
||||||
ReloadPrompt = TRUE;
|
ReloadPrompt = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
bak = GlobInfoStringTime;
|
bak = GlobInfoStringTime;
|
||||||
GlobInfoStringTime = 999;
|
GlobInfoStringTime = 999;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue