diff --git a/src/d_net.cpp b/src/d_net.cpp index 0985cf41c9..a480ae0ae7 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -73,7 +73,7 @@ EXTERN_CVAR (Int, autosavecount) #define SIMULATEERRORS 0 extern BYTE *demo_p; // [RH] Special "ticcmds" get recorded in demos -extern char savedescription[SAVESTRINGSIZE]; +extern FString savedescription; extern FString savegamefile; extern short consistancy[MAXPLAYERS][BACKUPTICS]; @@ -2418,8 +2418,7 @@ void Net_DoCommand (int type, BYTE **stream, int player) savegamefile = s; delete[] s; s = ReadString (stream); - memset (savedescription, 0, sizeof(savedescription)); - strncpy (savedescription, s, sizeof(savedescription)); + savedescription = s; if (player != consoleplayer) { // Paths sent over the network will be valid for the system that sent diff --git a/src/g_game.cpp b/src/g_game.cpp index 1c6c4cca9b..e5a48c245e 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -226,7 +226,7 @@ int mousex; int mousey; FString savegamefile; -char savedescription[SAVESTRINGSIZE]; +FString savedescription; // [RH] Name of screenshot file to generate (usually NULL) FString shotfile; @@ -1081,7 +1081,7 @@ void G_Ticker () G_DoSaveGame (true, savegamefile, savedescription); gameaction = ga_nothing; savegamefile = ""; - savedescription[0] = '\0'; + savedescription = ""; break; case ga_autosave: G_DoAutoSave (); @@ -2068,8 +2068,7 @@ void G_SaveGame (const char *filename, const char *description) else { savegamefile = filename; - strncpy (savedescription, description, sizeof(savedescription)-1); - savedescription[sizeof(savedescription)-1] = '\0'; + savedescription = description; sendsave = true; } } @@ -2119,7 +2118,7 @@ extern void P_CalcHeight (player_t *); void G_DoAutoSave () { - char description[SAVESTRINGSIZE]; + FString description; FString file; // Keep up to four autosaves at a time UCVarValue num; @@ -2147,10 +2146,7 @@ void G_DoAutoSave () } readableTime = myasctime (); - strcpy (description, "Autosave "); - strncpy (description+9, readableTime+4, 12); - description[9+12] = 0; - + description.Format("Autosave %.12s", readableTime + 4); G_DoSaveGame (false, file, description); } diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index b8989d2fa6..4bfc8c50e3 100644 --- a/src/menu/loadsavemenu.cpp +++ b/src/menu/loadsavemenu.cpp @@ -49,6 +49,8 @@ #include "serializer.h" #include "resourcefiles/resourcefile.h" +// Save name length limit for old binary formats. +#define OLDSAVESTRINGSIZE 24 //============================================================================= // @@ -229,7 +231,7 @@ void FSavegameManager::ReadSaveStrings() { PNGHandle *png; char sig[16]; - char title[SAVESTRINGSIZE + 1]; + char title[OLDSAVESTRINGSIZE + 1]; bool oldVer = true; bool addIt = false; bool missing = false; @@ -241,7 +243,7 @@ void FSavegameManager::ReadSaveStrings() // Old savegame versions are always added to the menu so // the user can easily delete them if desired. - title[SAVESTRINGSIZE] = 0; + title[OLDSAVESTRINGSIZE] = 0; if (nullptr != (png = M_VerifyPNG(file))) @@ -250,9 +252,9 @@ void FSavegameManager::ReadSaveStrings() if (ver != nullptr) { // An old version - if (!M_GetPNGText(png, "Title", title, SAVESTRINGSIZE)) + if (!M_GetPNGText(png, "Title", title, OLDSAVESTRINGSIZE)) { - strncpy(title, I_FindName(&c_file), SAVESTRINGSIZE); + strncpy(title, I_FindName(&c_file), OLDSAVESTRINGSIZE); } addIt = true; delete[] ver; @@ -267,7 +269,7 @@ void FSavegameManager::ReadSaveStrings() if (strncmp(sig, "ZDOOMSAVE", 9) == 0) { - if (fread(title, 1, SAVESTRINGSIZE, file) == SAVESTRINGSIZE) + if (fread(title, 1, OLDSAVESTRINGSIZE, file) == OLDSAVESTRINGSIZE) { addIt = true; } @@ -275,7 +277,7 @@ void FSavegameManager::ReadSaveStrings() else { memcpy(title, sig, 16); - if (fread(title + 16, 1, SAVESTRINGSIZE - 16, file) == SAVESTRINGSIZE - 16 && + if (fread(title + 16, 1, OLDSAVESTRINGSIZE - 16, file) == OLDSAVESTRINGSIZE - 16 && fread(sig, 1, 16, file) == 16 && strncmp(sig, "ZDOOMSAVE", 9) == 0) { @@ -416,6 +418,15 @@ void FSavegameManager::DoSave(int Selected, const char *savegamestring) V_SetBorderNeedRefresh(); } +DEFINE_ACTION_FUNCTION(FSavegameManager, DoSave) +{ + PARAM_SELF_STRUCT_PROLOGUE(FSavegameManager); + PARAM_INT(sel); + PARAM_STRING(name); + self->DoSave(sel, name); + return 0; +} + //============================================================================= // // @@ -435,7 +446,7 @@ unsigned FSavegameManager::ExtractSaveData(int index) } else { - index = LastAccessed + 1; + index = LastAccessed < 0? 0 : LastAccessed; } } @@ -538,6 +549,13 @@ void FSavegameManager::UnloadSaveData() SavePicData.Clear(); } +DEFINE_ACTION_FUNCTION(FSavegameManager, UnloadSaveData) +{ + PARAM_SELF_STRUCT_PROLOGUE(FSavegameManager); + self->UnloadSaveData(); + return 0; +} + //============================================================================= // // @@ -614,6 +632,15 @@ void FSavegameManager::SetFileInfo(int Selected) } } +DEFINE_ACTION_FUNCTION(FSavegameManager, SetFileInfo) +{ + PARAM_SELF_STRUCT_PROLOGUE(FSavegameManager); + PARAM_INT(i); + self->SetFileInfo(i); + return 0; +} + + //============================================================================= // // @@ -642,6 +669,13 @@ FSaveGameNode *FSavegameManager::GetSavegame(unsigned i) return SaveGames[i]; } +DEFINE_ACTION_FUNCTION(FSavegameManager, GetSavegame) +{ + PARAM_SELF_STRUCT_PROLOGUE(FSavegameManager); + PARAM_INT(i); + ACTION_RETURN_POINTER(self->GetSavegame(i)); +} + //============================================================================= // // @@ -655,6 +689,13 @@ void FSavegameManager::InsertNewSaveNode() SaveGames.Insert(0, &NewSaveNode); } +DEFINE_ACTION_FUNCTION(FSavegameManager, InsertNewSaveNode) +{ + PARAM_SELF_STRUCT_PROLOGUE(FSavegameManager); + self->InsertNewSaveNode(); + return 0; +} + //============================================================================= // // @@ -671,7 +712,11 @@ bool FSavegameManager::RemoveNewSaveNode() return false; } - +DEFINE_ACTION_FUNCTION(FSavegameManager, RemoveNewSaveNode) +{ + PARAM_SELF_STRUCT_PROLOGUE(FSavegameManager); + ACTION_RETURN_INT(self->RemoveNewSaveNode()); +} FSavegameManager savegameManager; @@ -712,7 +757,6 @@ public: int commentRight; int commentBottom; - // this needs to be kept in memory so that the texture can access it when it needs to. bool mEntering; DTextEnterMenu *mInput = nullptr; @@ -722,7 +766,6 @@ public: void Drawer (); bool MenuEvent (int mkey, bool fromcontroller); bool MouseEvent(int type, int x, int y); - bool Responder(event_t *ev); }; IMPLEMENT_CLASS(DLoadSaveMenu, false, false) @@ -745,7 +788,7 @@ DLoadSaveMenu::DLoadSaveMenu(DMenu *parent, DListMenuDescriptor *desc) savepicTop = 54*CleanYfac; savepicWidth = 216*screen->GetWidth()/640; savepicHeight = 135*screen->GetHeight()/400; - manager->WindowSize = savepicWidth; + manager->WindowSize = savepicWidth / CleanXfac; rowHeight = (SmallFont->GetHeight() + 1) * CleanYfac; listboxLeft = savepicLeft + savepicWidth + 14; @@ -815,7 +858,7 @@ void DLoadSaveMenu::Drawer () V_DrawFrame (commentLeft, commentTop, commentWidth, commentHeight); screen->Clear (commentLeft, commentTop, commentRight, commentBottom, 0, 0); - // manager->DrawSaveComment(SmallFont, CR_GOLD, commentLeft, commentTop, CleanYfac); + manager->DrawSaveComment(SmallFont, CR_GOLD, commentLeft, commentTop, CleanYfac); // Draw file area V_DrawFrame (listboxLeft, listboxTop, listboxWidth, listboxHeight); @@ -1008,232 +1051,6 @@ bool DLoadSaveMenu::MouseEvent(int type, int x, int y) return Super::MouseEvent(type, x, y); } -//============================================================================= -// -// -// -//============================================================================= - -bool DLoadSaveMenu::Responder (event_t *ev) -{ - if (ev->type == EV_GUI_Event) - { - if (ev->subtype == EV_GUI_KeyDown) - { - if ((unsigned)Selected < manager->SavegameCount()) - { - switch (ev->data1) - { - case GK_F1: - manager->SetFileInfo(Selected); - return true; - - case GK_DEL: - case '\b': - { - FString EndString; - EndString.Format("%s" TEXTCOLOR_WHITE "%s" TEXTCOLOR_NORMAL "?\n\n%s", - GStrings("MNU_DELETESG"), manager->GetSavegame(Selected)->SaveTitle.GetChars(), GStrings("PRESSYN")); - M_StartMessage (EndString, 0); - } - return true; - } - } - } - else if (ev->subtype == EV_GUI_WheelUp) - { - if (TopItem > 0) TopItem--; - return true; - } - else if (ev->subtype == EV_GUI_WheelDown) - { - if (TopItem < (int)manager->SavegameCount() - listboxRows) TopItem++; - return true; - } - } - return Super::Responder(ev); -} - - -//============================================================================= -// -// -// -//============================================================================= - -class DSaveMenu : public DLoadSaveMenu -{ - DECLARE_CLASS(DSaveMenu, DLoadSaveMenu) - -public: - - DSaveMenu(DMenu *parent = nullptr, DListMenuDescriptor *desc = nullptr); - void OnDestroy() override; - bool Responder (event_t *ev); - bool MenuEvent (int mkey, bool fromcontroller); - -}; - -IMPLEMENT_CLASS(DSaveMenu, false, false) - - -//============================================================================= -// -// -// -//============================================================================= - -DSaveMenu::DSaveMenu(DMenu *parent, DListMenuDescriptor *desc) -: DLoadSaveMenu(parent, desc) -{ - manager->InsertNewSaveNode(); - TopItem = 0; - Selected = manager->ExtractSaveData (-1); -} - -//============================================================================= -// -// -// -//============================================================================= - -void DSaveMenu::OnDestroy() -{ - if (manager->RemoveNewSaveNode()) - { - Selected--; - } - Super::OnDestroy(); -} - -//============================================================================= -// -// -// -//============================================================================= - -bool DSaveMenu::MenuEvent (int mkey, bool fromcontroller) -{ - if (Super::MenuEvent(mkey, fromcontroller)) - { - return true; - } - if (Selected == -1) - { - return false; - } - - if (mkey == MKEY_Enter) - { - const char *SavegameString = (Selected != 0)? manager->GetSavegame(Selected)->SaveTitle.GetChars() : ""; - mInput = new DTextEnterMenu(this, SavegameString, SAVESTRINGSIZE, 1, fromcontroller); - M_ActivateMenu(mInput); - mEntering = true; - } - else if (mkey == MKEY_Input) - { - mEntering = false; - manager->DoSave(Selected, mInput->GetText()); - mInput = nullptr; - } - else if (mkey == MKEY_Abort) - { - mEntering = false; - mInput = nullptr; - } - return false; -} - -//============================================================================= -// -// -// -//============================================================================= - -bool DSaveMenu::Responder (event_t *ev) -{ - if (ev->subtype == EV_GUI_KeyDown) - { - if (Selected != -1) - { - switch (ev->data1) - { - case GK_DEL: - case '\b': - // cannot delete 'new save game' item - if (Selected == 0) return true; - break; - - case 'N': - Selected = TopItem = 0; - manager->UnloadSaveData (); - return true; - } - } - } - return Super::Responder(ev); -} - -//============================================================================= -// -// -// -//============================================================================= - -class DLoadMenu : public DLoadSaveMenu -{ - DECLARE_CLASS(DLoadMenu, DLoadSaveMenu) - -public: - - DLoadMenu(DMenu *parent = nullptr, DListMenuDescriptor *desc = nullptr); - - bool MenuEvent (int mkey, bool fromcontroller); -}; - -IMPLEMENT_CLASS(DLoadMenu, false, false) - - -//============================================================================= -// -// -// -//============================================================================= - -DLoadMenu::DLoadMenu(DMenu *parent, DListMenuDescriptor *desc) -: DLoadSaveMenu(parent, desc) -{ - TopItem = 0; - Selected = manager->ExtractSaveData (-1); - -} - -//============================================================================= -// -// -// -//============================================================================= - -bool DLoadMenu::MenuEvent (int mkey, bool fromcontroller) -{ - if (Super::MenuEvent(mkey, fromcontroller)) - { - return true; - } - if (Selected == -1 || manager->SavegameCount() == 0) - { - return false; - } - - if (mkey == MKEY_Enter) - { - manager->LoadSavegame(Selected); - return true; - } - return false; -} - - DEFINE_FIELD(FSaveGameNode, SaveTitle); DEFINE_FIELD(FSaveGameNode, Filename); DEFINE_FIELD(FSaveGameNode, bOldVersion); diff --git a/src/version.h b/src/version.h index e50bdfd8d8..ca7de97fef 100644 --- a/src/version.h +++ b/src/version.h @@ -100,7 +100,4 @@ const char *GetVersionString(); #endif -// The maximum length of one save game description for the menus. -#define SAVESTRINGSIZE 24 - #endif //__VERSION_H__ diff --git a/wadsrc/static/zscript/menu/loadsavemenu.txt b/wadsrc/static/zscript/menu/loadsavemenu.txt index 8700494120..a52c8191bd 100644 --- a/wadsrc/static/zscript/menu/loadsavemenu.txt +++ b/wadsrc/static/zscript/menu/loadsavemenu.txt @@ -1,5 +1,5 @@ /* -** loadsavemenu.cpp +** loacpp ** The load game and save game menus ** **--------------------------------------------------------------------------- @@ -49,20 +49,20 @@ struct SavegameManager native native SaveGameNode quickSaveSlot; //void ReadSaveStrings(); - //void UnloadSaveData(); + native void UnloadSaveData(); //int RemoveSaveSlot(int index); native void LoadSavegame(int Selected); - //void DoSave(int Selected, String savegamestring); + native void DoSave(int Selected, String savegamestring); native int ExtractSaveData(int index); //void ClearSaveStuff(); //bool DrawSavePic(int x, int y, int w, int h); //void DrawSaveComment(Font font, int cr, int x, int y, int scalefactor); - //void SetFileInfo(int Selected); + native void SetFileInfo(int Selected); native int SavegameCount(); - //SaveGameNode GetSavegame(int i); - //void InsertNewSaveNode(); - //bool RemoveNewSaveNode(); + native SaveGameNode GetSavegame(int i); + native void InsertNewSaveNode(); + native bool RemoveNewSaveNode(); } @@ -99,10 +99,156 @@ class LoadSaveMenu : ListMenu native native TextEnterMenu mInput; + + //============================================================================= + // + // + // + //============================================================================= + + override bool Responder (InputEventData ev) + { + if (ev.type == InputEventData.GUI_Event) + { + if (ev.subtype == InputEventData.GUI_KeyDown) + { + if (Selected < manager.SavegameCount()) + { + switch (ev.data1) + { + case UIEvent.Key_F1: + manager.SetFileInfo(Selected); + return true; + + case UIEvent.Key_DEL: + { + String EndString; + EndString = String.Format("%s%s%s%s?\n\n%s", Stringtable.Localize("$MNU_DELETESG"), TEXTCOLOR_WHITE, manager.GetSavegame(Selected).SaveTitle, TEXTCOLOR_NORMAL, Stringtable.Localize("$PRESSYN")); + StartMessage (EndString, 0); + } + return true; + } + } + } + else if (ev.subtype == InputEventData.GUI_WheelUp) + { + if (TopItem > 0) TopItem--; + return true; + } + else if (ev.subtype == InputEventData.GUI_WheelDown) + { + if (TopItem < manager.SavegameCount() - listboxRows) TopItem++; + return true; + } + } + return Super.Responder(ev); + } + + } -class SaveMenu : LoadSaveMenu native +class SaveMenu : LoadSaveMenu { + //============================================================================= + // + // + // + //============================================================================= + + override void Init(Menu parent, ListMenuDescriptor desc) + { + Super.Init(parent, desc); + manager.InsertNewSaveNode(); + TopItem = 0; + Selected = manager.ExtractSaveData (-1); + } + + //============================================================================= + // + // + // + //============================================================================= + + override void OnDestroy() + { + if (manager.RemoveNewSaveNode()) + { + Selected--; + } + Super.OnDestroy(); + } + + //============================================================================= + // + // + // + //============================================================================= + const SAVESTRINGSIZE = 32; + + override bool MenuEvent (int mkey, bool fromcontroller) + { + + if (Super.MenuEvent(mkey, fromcontroller)) + { + return true; + } + if (Selected == -1) + { + return false; + } + + if (mkey == MKEY_Enter) + { + String SavegameString = (Selected != 0)? manager.GetSavegame(Selected).SaveTitle : ""; + mInput = TextEnterMenu.Open(self, SavegameString, SAVESTRINGSIZE, 1, fromcontroller); + mInput.ActivateMenu(); + mEntering = true; + } + else if (mkey == MKEY_Input) + { + mEntering = false; + manager.DoSave(Selected, mInput.GetText()); + mInput = null; + } + else if (mkey == MKEY_Abort) + { + mEntering = false; + mInput = null; + } + return false; + } + + //============================================================================= + // + // + // + //============================================================================= + + override bool Responder (InputEventData ev) + { + if (ev.subtype == InputEventData.GUI_KeyDown) + { + if (Selected != -1) + { + switch (ev.data1) + { + case UIEvent.Key_DEL: + // cannot delete 'new save game' item + if (Selected == 0) return true; + break; + + case 78://'N': + Selected = TopItem = 0; + manager.UnloadSaveData (); + return true; + } + } + } + return Super.Responder(ev); + } + + + } //============================================================================= @@ -111,7 +257,7 @@ class SaveMenu : LoadSaveMenu native // //============================================================================= -class LoadMenu : LoadSaveMenu native +class LoadMenu : LoadSaveMenu { //============================================================================= //