diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index bfe7969704..56cd60b39f 100644 --- a/src/menu/loadsavemenu.cpp +++ b/src/menu/loadsavemenu.cpp @@ -50,25 +50,13 @@ #include "resourcefiles/resourcefile.h" -//============================================================================= -// -// This should remain native because exposing 'remove' would allow -// the creation of actual malware mods! -// -//============================================================================= - -void SavegameManager::DeleteEntry(int Selected) -{ - remove(SaveGames[Selected]->Filename.GetChars()); -} - //============================================================================= // // Save data maintenance // //============================================================================= -void SavegameManager::ClearSaveGames() +void FSavegameManager::ClearSaveGames() { for (unsigned i = 0; ibNoDelete ? index - 1 : index; + if (listindex < 0) return index; + + remove(SaveGames[index]->Filename.GetChars()); + UnloadSaveData(); + FSaveGameNode *file = SaveGames[index]; if (quickSaveSlot == SaveGames[index]) @@ -93,8 +87,15 @@ int SavegameManager::RemoveSaveSlot(int index) quickSaveSlot = nullptr; } if (!file->bNoDelete) delete file; + + if (LastSaved == listindex) LastSaved = -1; + else if (LastSaved > listindex) LastSaved--; + if (LastAccessed == listindex) LastAccessed = -1; + else if (LastAccessed > listindex) LastAccessed--; + SaveGames.Delete(index); if ((unsigned)index >= SaveGames.Size()) index--; + ExtractSaveData(index); return index; } @@ -104,7 +105,7 @@ int SavegameManager::RemoveSaveSlot(int index) // //============================================================================= -int SavegameManager::InsertSaveNode(FSaveGameNode *node) +int FSavegameManager::InsertSaveNode(FSaveGameNode *node) { if (SaveGames.Size() == 0) { @@ -138,7 +139,7 @@ int SavegameManager::InsertSaveNode(FSaveGameNode *node) // //============================================================================= -void SavegameManager::ReadSaveStrings() +void FSavegameManager::ReadSaveStrings() { if (SaveGames.Size() == 0) { @@ -304,7 +305,7 @@ void SavegameManager::ReadSaveStrings() // //============================================================================= -void SavegameManager::NotifyNewSave(const FString &file, const FString &title, bool okForQuicksave) +void FSavegameManager::NotifyNewSave(const FString &file, const FString &title, bool okForQuicksave) { FSaveGameNode *node; @@ -355,7 +356,7 @@ void SavegameManager::NotifyNewSave(const FString &file, const FString &title, b // //============================================================================= -void SavegameManager::LoadSavegame(int Selected) +void FSavegameManager::LoadSavegame(int Selected) { G_LoadGame(SaveGames[Selected]->Filename.GetChars(), true); if (quickSaveSlot == (FSaveGameNode*)1) @@ -367,13 +368,21 @@ void SavegameManager::LoadSavegame(int Selected) LastAccessed = Selected; } +DEFINE_ACTION_FUNCTION(FSavegameManager, LoadSavegame) +{ + PARAM_SELF_STRUCT_PROLOGUE(FSavegameManager); + PARAM_INT(sel); + self->LoadSavegame(sel); + return 0; +} + //============================================================================= // // // //============================================================================= -void SavegameManager::DoSave(int Selected, const char *savegamestring) +void FSavegameManager::DoSave(int Selected, const char *savegamestring) { if (Selected != 0) { @@ -409,11 +418,23 @@ void SavegameManager::DoSave(int Selected, const char *savegamestring) // //============================================================================= -void SavegameManager::ExtractSaveData(int index) +unsigned FSavegameManager::ExtractSaveData(int index) { FResourceFile *resf; FSaveGameNode *node; + if (index == -1) + { + if (SaveGames.Size() > 0 && SaveGames[0]->bNoDelete) + { + index = LastSaved + 1; + } + else + { + index = LastAccessed + 1; + } + } + UnloadSaveData(); if ((unsigned)index < SaveGames.Size() && @@ -426,7 +447,7 @@ void SavegameManager::ExtractSaveData(int index) if (info == nullptr) { // this should not happen because the file has already been verified. - return; + return index; } void *data = info->CacheLump(); FSerializer arc; @@ -476,6 +497,14 @@ void SavegameManager::ExtractSaveData(int index) } delete resf; } + return index; +} + +DEFINE_ACTION_FUNCTION(FSavegameManager, ExtractSaveData) +{ + PARAM_SELF_STRUCT_PROLOGUE(FSavegameManager); + PARAM_INT(sel); + ACTION_RETURN_INT(self->ExtractSaveData(sel)); } //============================================================================= @@ -484,7 +513,7 @@ void SavegameManager::ExtractSaveData(int index) // //============================================================================= -void SavegameManager::UnloadSaveData() +void FSavegameManager::UnloadSaveData() { if (SavePic != nullptr) { @@ -511,7 +540,7 @@ void SavegameManager::UnloadSaveData() // //============================================================================= -void SavegameManager::ClearSaveStuff() +void FSavegameManager::ClearSaveStuff() { UnloadSaveData(); if (quickSaveSlot == (FSaveGameNode*)1) @@ -527,7 +556,7 @@ void SavegameManager::ClearSaveStuff() // //============================================================================= -bool SavegameManager::DrawSavePic(int x, int y, int w, int h) +bool FSavegameManager::DrawSavePic(int x, int y, int w, int h) { if (SavePic == nullptr) return false; screen->DrawTexture(SavePic, x, y, DTA_DestWidth, w, DTA_DestHeight, h, DTA_Masked, false, TAG_DONE); @@ -540,7 +569,33 @@ bool SavegameManager::DrawSavePic(int x, int y, int w, int h) // //============================================================================= -void SavegameManager::SetFileInfo(int Selected) +void FSavegameManager::DrawSaveComment(FFont *font, int cr, int x, int y, int scalefactor) +{ + int sx = CleanXfac; + int sy = CleanYfac; + + CleanXfac = CleanYfac = scalefactor; + + // I'm not sure why SaveComment would go nullptr in this loop, but I got + // a crash report where it was nullptr when i reached 1, so now I check + // for that. + for (int i = 0; SaveComment != nullptr && SaveComment[i].Width >= 0 && i < 6; ++i) + { + screen->DrawText(font, cr, x, y + font->GetHeight() * i * scalefactor, SaveComment[i].Text, DTA_CleanNoMove, true, TAG_DONE); + } + + CleanXfac = sx; + CleanYfac = sy; +} + + +//============================================================================= +// +// +// +//============================================================================= + +void FSavegameManager::SetFileInfo(int Selected) { if (!SaveGames[Selected]->Filename.IsEmpty()) { @@ -561,18 +616,24 @@ void SavegameManager::SetFileInfo(int Selected) // //============================================================================= -unsigned SavegameManager::SavegameCount() +unsigned FSavegameManager::SavegameCount() { return SaveGames.Size(); } +DEFINE_ACTION_FUNCTION(FSavegameManager, SavegameCount) +{ + PARAM_SELF_STRUCT_PROLOGUE(FSavegameManager); + ACTION_RETURN_INT(self->SavegameCount()); +} + //============================================================================= // // // //============================================================================= -FSaveGameNode *SavegameManager::GetSavegame(unsigned i) +FSaveGameNode *FSavegameManager::GetSavegame(unsigned i) { return SaveGames[i]; } @@ -583,7 +644,7 @@ FSaveGameNode *SavegameManager::GetSavegame(unsigned i) // //============================================================================= -void SavegameManager::InsertNewSaveNode() +void FSavegameManager::InsertNewSaveNode() { NewSaveNode.SaveTitle = GStrings["NEWSAVE"]; NewSaveNode.bNoDelete = true; @@ -596,7 +657,7 @@ void SavegameManager::InsertNewSaveNode() // //============================================================================= -bool SavegameManager::RemoveNewSaveNode() +bool FSavegameManager::RemoveNewSaveNode() { if (SaveGames[0] == &NewSaveNode) { @@ -609,7 +670,7 @@ bool SavegameManager::RemoveNewSaveNode() -SavegameManager savegameManager; +FSavegameManager savegameManager; @@ -618,9 +679,9 @@ class DLoadSaveMenu : public DListMenu { DECLARE_CLASS(DLoadSaveMenu, DListMenu) -protected: +public: - SavegameManager *manager; + FSavegameManager *manager; int Selected; int TopItem; @@ -749,18 +810,8 @@ void DLoadSaveMenu::Drawer () // Draw comment area V_DrawFrame (commentLeft, commentTop, commentWidth, commentHeight); screen->Clear (commentLeft, commentTop, commentRight, commentBottom, 0, 0); - if (manager->SaveComment != nullptr) - { - // I'm not sure why SaveComment would go nullptr in this loop, but I got - // a crash report where it was nullptr when i reached 1, so now I check - // for that. - for (i = 0; manager->SaveComment != nullptr && manager->SaveComment[i].Width >= 0 && i < 6; ++i) - { - screen->DrawText (SmallFont, CR_GOLD, commentLeft, commentTop - + SmallFont->GetHeight()*i*CleanYfac, manager->SaveComment[i].Text, - DTA_CleanNoMove, true, TAG_DONE); - } - } + + // manager->DrawSaveComment(SmallFont, CR_GOLD, commentLeft, commentTop, CleanYfac); // Draw file area V_DrawFrame (listboxLeft, listboxTop, listboxWidth, listboxHeight); @@ -910,16 +961,7 @@ bool DLoadSaveMenu::MenuEvent (int mkey, bool fromcontroller) { if ((unsigned)Selected < manager->SavegameCount()) { - int listindex = manager->GetSavegame(0)->bNoDelete? Selected-1 : Selected; - manager->DeleteEntry(Selected); - manager->UnloadSaveData (); Selected = manager->RemoveSaveSlot (Selected); - manager->ExtractSaveData (Selected); - - if (manager->LastSaved == listindex) manager->LastSaved = -1; - else if (manager->LastSaved > listindex) manager->LastSaved--; - if (manager->LastAccessed == listindex) manager->LastAccessed = -1; - else if (manager->LastAccessed > listindex) manager->LastAccessed--; } return true; } @@ -1042,8 +1084,7 @@ DSaveMenu::DSaveMenu(DMenu *parent, DListMenuDescriptor *desc) { manager->InsertNewSaveNode(); TopItem = 0; - Selected = manager->LastSaved + 1; - manager->ExtractSaveData (Selected); + Selected = manager->ExtractSaveData (-1); } //============================================================================= @@ -1159,11 +1200,7 @@ DLoadMenu::DLoadMenu(DMenu *parent, DListMenuDescriptor *desc) : DLoadSaveMenu(parent, desc) { TopItem = 0; - if (manager->LastAccessed != -1) - { - Selected = manager->LastAccessed; - } - manager->ExtractSaveData (Selected); + Selected = manager->ExtractSaveData (-1); } @@ -1192,3 +1229,36 @@ bool DLoadMenu::MenuEvent (int mkey, bool fromcontroller) return false; } + +DEFINE_FIELD(FSaveGameNode, SaveTitle); +DEFINE_FIELD(FSaveGameNode, Filename); +DEFINE_FIELD(FSaveGameNode, bOldVersion); +DEFINE_FIELD(FSaveGameNode, bMissingWads); +DEFINE_FIELD(FSaveGameNode, bNoDelete); + +DEFINE_FIELD(FSavegameManager, WindowSize); +DEFINE_FIELD(FSavegameManager, quickSaveSlot); + +DEFINE_FIELD(DLoadSaveMenu, manager); +DEFINE_FIELD(DLoadSaveMenu, Selected); +DEFINE_FIELD(DLoadSaveMenu, TopItem); +DEFINE_FIELD(DLoadSaveMenu, savepicLeft); +DEFINE_FIELD(DLoadSaveMenu, savepicTop); +DEFINE_FIELD(DLoadSaveMenu, savepicWidth); +DEFINE_FIELD(DLoadSaveMenu, savepicHeight); +DEFINE_FIELD(DLoadSaveMenu, rowHeight); +DEFINE_FIELD(DLoadSaveMenu, listboxLeft); +DEFINE_FIELD(DLoadSaveMenu, listboxTop); +DEFINE_FIELD(DLoadSaveMenu, listboxWidth); +DEFINE_FIELD(DLoadSaveMenu, listboxRows); +DEFINE_FIELD(DLoadSaveMenu, listboxHeight); +DEFINE_FIELD(DLoadSaveMenu, listboxRight); +DEFINE_FIELD(DLoadSaveMenu, listboxBottom); +DEFINE_FIELD(DLoadSaveMenu, commentLeft); +DEFINE_FIELD(DLoadSaveMenu, commentTop); +DEFINE_FIELD(DLoadSaveMenu, commentWidth); +DEFINE_FIELD(DLoadSaveMenu, commentHeight); +DEFINE_FIELD(DLoadSaveMenu, commentRight); +DEFINE_FIELD(DLoadSaveMenu, commentBottom); +DEFINE_FIELD(DLoadSaveMenu, mEntering); +DEFINE_FIELD(DLoadSaveMenu, mInput); diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index f32c203737..ee7d5cbdb1 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -630,7 +630,7 @@ void M_SetMenu(FName menu, int param) if (cls == nullptr) cls = PClass::FindClass("ListMenu"); DListMenu *newmenu = (DListMenu *)cls->CreateNew(); - IFVIRTUALPTRNAME(newmenu, "OptionMenu", Init) + IFVIRTUALPTRNAME(newmenu, "ListMenu", Init) { VMValue params[3] = { newmenu, DMenu::CurrentMenu, ld }; GlobalVMStack.Call(func, params, 3, nullptr, 0); diff --git a/src/menu/menu.h b/src/menu/menu.h index 642d36e99f..c73b8a7b6a 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -60,44 +60,44 @@ struct FSaveGameNode { FString SaveTitle; FString Filename; - bool bOldVersion; - bool bMissingWads; - bool bNoDelete; - - FSaveGameNode() { bNoDelete = false; } + bool bOldVersion = false; + bool bMissingWads = false; + bool bNoDelete = false; }; -struct SavegameManager +struct FSavegameManager { private: TArray SaveGames; FSaveGameNode NewSaveNode; -public: int LastSaved = -1; int LastAccessed = -1; + FileReader *currentSavePic = nullptr; + TArray SavePicData; + FTexture *SavePic = nullptr; + FBrokenLines *SaveComment = nullptr; + +public: int WindowSize = 0; FSaveGameNode *quickSaveSlot = nullptr; - FileReader *currentSavePic = nullptr; - TArray SavePicData; - - FTexture *SavePic = nullptr; - FBrokenLines *SaveComment = nullptr; private: int InsertSaveNode(FSaveGameNode *node); public: - void ClearSaveGames(); - int RemoveSaveSlot(int index); - void ReadSaveStrings(); void NotifyNewSave(const FString &file, const FString &title, bool okForQuicksave); + void ClearSaveGames(); + + void ReadSaveStrings(); + void UnloadSaveData(); + + int RemoveSaveSlot(int index); void LoadSavegame(int Selected); void DoSave(int Selected, const char *savegamestring); - void DeleteEntry(int Selected); - void ExtractSaveData(int index); - void UnloadSaveData(); + unsigned ExtractSaveData(int index); void ClearSaveStuff(); bool DrawSavePic(int x, int y, int w, int h); + void DrawSaveComment(FFont *font, int cr, int x, int y, int scalefactor); void SetFileInfo(int Selected); unsigned SavegameCount(); FSaveGameNode *GetSavegame(unsigned i); @@ -106,7 +106,7 @@ public: }; -extern SavegameManager savegameManager; +extern FSavegameManager savegameManager; //============================================================================= // diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 57bdc7b019..6c5d671dee 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -158,11 +158,6 @@ enum DrawTextureTags struct Screen native { - int CleanWidth, CleanHeight; - int CleanXFac, CleanYFac; - int CleanWidth_1, CleanHeight_1; - int CleanXFac_1, CleanYFac_1; - native static Color PaletteColor(int index); native static int GetWidth(); native static int GetHeight(); diff --git a/wadsrc/static/zscript/menu/loadsavemenu.txt b/wadsrc/static/zscript/menu/loadsavemenu.txt index b07c7a4893..8700494120 100644 --- a/wadsrc/static/zscript/menu/loadsavemenu.txt +++ b/wadsrc/static/zscript/menu/loadsavemenu.txt @@ -33,38 +33,72 @@ ** */ -/* + +struct SaveGameNode native +{ + native String SaveTitle; + native String Filename; + native bool bOldVersion; + native bool bMissingWads; + native bool bNoDelete; +} + struct SavegameManager native { - native int LastSaved; - native int LastAccessed; native int WindowSize; - //SaveGameNode quickSaveSlot = nullptr; - //FBrokenLines *SaveComment = nullptr; + native SaveGameNode quickSaveSlot; - void ClearSaveGames(); - int InsertSaveNode(FSaveGameNode *node); - int RemoveSaveSlot(int index); - void ReadSaveStrings(); - void NotifyNewSave(const char *file, const char *title, bool okForQuicksave); - void LoadSavegame(int Selected); - void DoSave(int Selected, const char *savegamestring); - void DeleteEntry(int Selected); - void ExtractSaveData(int index); - void UnloadSaveData(); - void ClearSaveStuff(); - bool DrawSavePic(int x, int y, int w, int h); - void SetFileInfo(int Selected); + //void ReadSaveStrings(); + //void UnloadSaveData(); + + //int RemoveSaveSlot(int index); + native void LoadSavegame(int Selected); + //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 int SavegameCount(); + //SaveGameNode GetSavegame(int i); + //void InsertNewSaveNode(); + //bool RemoveNewSaveNode(); } -*/ + class LoadSaveMenu : ListMenu native { - //native SavegameManager manager; - //native int TopItem; - //native int Selected; + native SavegameManager manager; + native int TopItem; + native int Selected; + + native int savepicLeft; + native int savepicTop; + native int savepicWidth; + native int savepicHeight; + native int rowHeight; + native int listboxLeft; + native int listboxTop; + native int listboxWidth; + + native int listboxRows; + native int listboxHeight; + native int listboxRight; + native int listboxBottom; + + native int commentLeft; + native int commentTop; + native int commentWidth; + native int commentHeight; + native int commentRight; + native int commentBottom; + + native bool mEntering; + native TextEnterMenu mInput; + + } class SaveMenu : LoadSaveMenu native @@ -85,19 +119,13 @@ class LoadMenu : LoadSaveMenu native // //============================================================================= - /* override void Init(Menu parent, ListMenuDescriptor desc) { Super.Init(parent, desc); TopItem = 0; - if (manager.LastAccessed != -1) - { - Selected = manager.LastAccessed; - } - manager.ExtractSaveData (Selected); + Selected = manager.ExtractSaveData (-1); } - */ //============================================================================= // @@ -105,14 +133,13 @@ class LoadMenu : LoadSaveMenu native // //============================================================================= - /* override bool MenuEvent (int mkey, bool fromcontroller) { if (Super.MenuEvent(mkey, fromcontroller)) { return true; } - if (Selected == -1 || manager.SaveGames.Size() == 0) + if (Selected == -1 || manager.SavegameCount() == 0) { return false; } @@ -124,5 +151,4 @@ class LoadMenu : LoadSaveMenu native } return false; } - */ } \ No newline at end of file