From 0ffd475d8ca39fefaf1aa1c631edae3aff74f937 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 18 Feb 2017 10:34:27 +0200 Subject: [PATCH 01/22] Fixed compilation with GCC/Clang src/r_data/sprites.cpp:805:79: error: cannot pass non-trivial object of type 'FString' to variadic function; expected type from format string was 'char *' [-Wnon-pod-varargs] --- src/r_data/sprites.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_data/sprites.cpp b/src/r_data/sprites.cpp index 45167580f..d6d6aa4e1 100644 --- a/src/r_data/sprites.cpp +++ b/src/r_data/sprites.cpp @@ -802,7 +802,7 @@ void R_InitSkins (void) if (spr == 0 && maxframe <= 0) { - Printf (PRINT_BOLD, "Skin %s (#%u) has no frames. Removing.\n", Skins[i].Name, i); + Printf (PRINT_BOLD, "Skin %s (#%u) has no frames. Removing.\n", Skins[i].Name.GetChars(), i); remove = true; break; } From 128dfdeee62593c23fd008219ef0c78c6bd21c0c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 18 Feb 2017 12:36:31 +0100 Subject: [PATCH 02/22] - made some of the load/save menu's data a bit more scripting friendly, this mostly means removal of static string buffers. --- src/menu/loadsavemenu.cpp | 31 ++--- src/menu/menu.h | 2 +- src/menu/messagebox.cpp | 8 +- wadsrc/static/zscript.txt | 1 + wadsrc/static/zscript/menu/loadsavemenu.txt | 128 ++++++++++++++++++++ 5 files changed, 145 insertions(+), 25 deletions(-) create mode 100644 wadsrc/static/zscript/menu/loadsavemenu.txt diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index ec92a591f..d90c03b66 100644 --- a/src/menu/loadsavemenu.cpp +++ b/src/menu/loadsavemenu.cpp @@ -120,8 +120,7 @@ int SavegameManager::InsertSaveNode(FSaveGameNode *node) unsigned int i; for (i = 0; i < SaveGames.Size(); i++) { - if (SaveGames[i]->bOldVersion || - stricmp(node->Title, SaveGames[i]->Title) <= 0) + if (SaveGames[i]->bOldVersion || node->SaveTitle.CompareNoCase(SaveGames[i]->SaveTitle) <= 0) { break; } @@ -212,7 +211,7 @@ void SavegameManager::ReadSaveStrings() node->Filename = filepath; node->bOldVersion = oldVer; node->bMissingWads = missing; - strncpy(node->Title, title.GetChars(), SAVESTRINGSIZE); + node->SaveTitle = title; InsertSaveNode(node); delete savegame; } @@ -287,7 +286,7 @@ void SavegameManager::ReadSaveStrings() node->Filename = filepath; node->bOldVersion = true; node->bMissingWads = false; - memcpy(node->Title, title, SAVESTRINGSIZE); + node->SaveTitle = title; InsertSaveNode(node); } fclose(file); @@ -324,7 +323,7 @@ void SavegameManager::NotifyNewSave(const char *file, const char *title, bool ok if (node->Filename.CompareNoCase(file) == 0) #endif { - strcpy(node->Title, title); + node->SaveTitle = title; node->bOldVersion = false; node->bMissingWads = false; if (okForQuicksave) @@ -337,7 +336,7 @@ void SavegameManager::NotifyNewSave(const char *file, const char *title, bool ok } node = new FSaveGameNode; - strcpy(node->Title, title); + node->SaveTitle = title; node->Filename = file; node->bOldVersion = false; node->bMissingWads = false; @@ -597,7 +596,6 @@ protected: // this needs to be kept in memory so that the texture can access it when it needs to. bool mEntering; - char savegamestring[SAVESTRINGSIZE]; DTextEnterMenu *mInput = nullptr; DLoadSaveMenu(DMenu *parent = nullptr, DListMenuDescriptor *desc = nullptr); @@ -756,7 +754,7 @@ void DLoadSaveMenu::Drawer () if (!mEntering) { screen->DrawText (SmallFont, color, - listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, node->Title, + listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, node->SaveTitle.GetChars(), DTA_CleanNoMove, true, TAG_DONE); } else @@ -770,7 +768,7 @@ void DLoadSaveMenu::Drawer () else { screen->DrawText (SmallFont, color, - listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, node->Title, + listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, node->SaveTitle.GetChars(), DTA_CleanNoMove, true, TAG_DONE); } } @@ -936,7 +934,7 @@ bool DLoadSaveMenu::Responder (event_t *ev) { FString EndString; EndString.Format("%s" TEXTCOLOR_WHITE "%s" TEXTCOLOR_NORMAL "?\n\n%s", - GStrings("MNU_DELETESG"), manager->SaveGames[Selected]->Title, GStrings("PRESSYN")); + GStrings("MNU_DELETESG"), manager->SaveGames[Selected]->SaveTitle.GetChars(), GStrings("PRESSYN")); M_StartMessage (EndString, 0); } return true; @@ -991,7 +989,7 @@ IMPLEMENT_CLASS(DSaveMenu, false, false) DSaveMenu::DSaveMenu(DMenu *parent, DListMenuDescriptor *desc) : DLoadSaveMenu(parent, desc) { - strcpy (NewSaveNode.Title, GStrings["NEWSAVE"]); + NewSaveNode.SaveTitle = GStrings["NEWSAVE"]; NewSaveNode.bNoDelete = true; manager->SaveGames.Insert(0, &NewSaveNode); TopItem = 0; @@ -1042,15 +1040,8 @@ bool DSaveMenu::MenuEvent (int mkey, bool fromcontroller) if (mkey == MKEY_Enter) { - if (Selected != 0) - { - strcpy (savegamestring, manager->SaveGames[Selected]->Title); - } - else - { - savegamestring[0] = 0; - } - mInput = new DTextEnterMenu(this, savegamestring, SAVESTRINGSIZE, 1, fromcontroller); + const char *SavegameString = (Selected != 0)? manager->SaveGames[Selected]->SaveTitle.GetChars() : ""; + mInput = new DTextEnterMenu(this, SavegameString, SAVESTRINGSIZE, 1, fromcontroller); M_ActivateMenu(mInput); mEntering = true; } diff --git a/src/menu/menu.h b/src/menu/menu.h index d272fe242..e48e17814 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -58,7 +58,7 @@ extern FGameStartup GameStartupInfo; struct FSaveGameNode { - char Title[SAVESTRINGSIZE]; + FString SaveTitle; FString Filename; bool bOldVersion; bool bMissingWads; diff --git a/src/menu/messagebox.cpp b/src/menu/messagebox.cpp index e15940acb..b1d602555 100644 --- a/src/menu/messagebox.cpp +++ b/src/menu/messagebox.cpp @@ -548,7 +548,7 @@ DQuickSaveMenu::DQuickSaveMenu(bool playsound) { FString tempstring; - tempstring.Format(GStrings("QSPROMPT"), savegameManager.quickSaveSlot->Title); + tempstring.Format(GStrings("QSPROMPT"), savegameManager.quickSaveSlot->SaveTitle.GetChars()); Init(NULL, tempstring, 0, playsound); } @@ -562,7 +562,7 @@ void DQuickSaveMenu::HandleResult(bool res) { if (res) { - G_SaveGame (savegameManager.quickSaveSlot->Filename.GetChars(), savegameManager.quickSaveSlot->Title); + G_SaveGame (savegameManager.quickSaveSlot->Filename.GetChars(), savegameManager.quickSaveSlot->SaveTitle.GetChars()); S_Sound (CHAN_VOICE | CHAN_UI, "menu/dismiss", snd_menuvolume, ATTN_NONE); M_ClearMenus(); } @@ -601,7 +601,7 @@ CCMD (quicksave) // [mxd]. Just save the game, no questions asked. if (!saveloadconfirmation) { - G_SaveGame(savegameManager.quickSaveSlot->Filename.GetChars(), savegameManager.quickSaveSlot->Title); + G_SaveGame(savegameManager.quickSaveSlot->Filename.GetChars(), savegameManager.quickSaveSlot->SaveTitle.GetChars()); return; } @@ -644,7 +644,7 @@ DQuickLoadMenu::DQuickLoadMenu(bool playsound) { FString tempstring; - tempstring.Format(GStrings("QLPROMPT"), savegameManager.quickSaveSlot->Title); + tempstring.Format(GStrings("QLPROMPT"), savegameManager.quickSaveSlot->SaveTitle.GetChars()); Init(NULL, tempstring, 0, playsound); } diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index ae582e058..419adfe76 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -15,6 +15,7 @@ #include "zscript/menu/optionmenuitems.txt" #include "zscript/menu/colorpickermenu.txt" #include "zscript/menu/joystickmenu.txt" +#include "zscript/menu/loadsavemenu.txt" #include "zscript/menu/playermenu.txt" #include "zscript/menu/playerdisplay.txt" #include "zscript/menu/playercontrols.txt" diff --git a/wadsrc/static/zscript/menu/loadsavemenu.txt b/wadsrc/static/zscript/menu/loadsavemenu.txt new file mode 100644 index 000000000..b07c7a489 --- /dev/null +++ b/wadsrc/static/zscript/menu/loadsavemenu.txt @@ -0,0 +1,128 @@ +/* +** loadsavemenu.cpp +** The load game and save game menus +** +**--------------------------------------------------------------------------- +** Copyright 2001-2010 Randy Heit +** Copyright 2010-2017 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +/* +struct SavegameManager native +{ + native int LastSaved; + native int LastAccessed; + native int WindowSize; + //SaveGameNode quickSaveSlot = nullptr; + //FBrokenLines *SaveComment = nullptr; + + 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); + +} +*/ + + +class LoadSaveMenu : ListMenu native +{ + //native SavegameManager manager; + //native int TopItem; + //native int Selected; +} + +class SaveMenu : LoadSaveMenu native +{ +} + +//============================================================================= +// +// +// +//============================================================================= + +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); + + } + */ + + //============================================================================= + // + // + // + //============================================================================= + + /* + override bool MenuEvent (int mkey, bool fromcontroller) + { + if (Super.MenuEvent(mkey, fromcontroller)) + { + return true; + } + if (Selected == -1 || manager.SaveGames.Size() == 0) + { + return false; + } + + if (mkey == MKEY_Enter) + { + manager.LoadSavegame(Selected); + return true; + } + return false; + } + */ +} \ No newline at end of file From 9d51266145ae7af888207ffc016e2a95b6e8b08a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 18 Feb 2017 13:05:33 +0100 Subject: [PATCH 03/22] - some more encapsulation of savegame data in the savegame manager, because some of its info is not in a state that can be accessed directly through script code and needs a few helper functions. --- src/g_game.cpp | 2 +- src/menu/loadsavemenu.cpp | 124 +++++++++++++++++++++++++------------- src/menu/menu.h | 13 +++- 3 files changed, 94 insertions(+), 45 deletions(-) diff --git a/src/g_game.cpp b/src/g_game.cpp index dcd36b041..1c6c4cca9 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -2310,7 +2310,7 @@ void G_DoSaveGame (bool okForQuicksave, FString filename, const char *descriptio WriteZip(filename, savegame_filenames, savegame_content); - savegameManager.NotifyNewSave (filename.GetChars(), description, okForQuicksave); + savegameManager.NotifyNewSave (filename, description, okForQuicksave); // delete the JSON buffers we created just above. Everything else will // either still be needed or taken care of automatically. diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index d90c03b66..bfe796970 100644 --- a/src/menu/loadsavemenu.cpp +++ b/src/menu/loadsavemenu.cpp @@ -304,11 +304,11 @@ void SavegameManager::ReadSaveStrings() // //============================================================================= -void SavegameManager::NotifyNewSave(const char *file, const char *title, bool okForQuicksave) +void SavegameManager::NotifyNewSave(const FString &file, const FString &title, bool okForQuicksave) { FSaveGameNode *node; - if (file == nullptr) + if (file.IsEmpty()) return; ReadSaveStrings(); @@ -555,6 +555,60 @@ void SavegameManager::SetFileInfo(int Selected) } } +//============================================================================= +// +// +// +//============================================================================= + +unsigned SavegameManager::SavegameCount() +{ + return SaveGames.Size(); +} + +//============================================================================= +// +// +// +//============================================================================= + +FSaveGameNode *SavegameManager::GetSavegame(unsigned i) +{ + return SaveGames[i]; +} + +//============================================================================= +// +// +// +//============================================================================= + +void SavegameManager::InsertNewSaveNode() +{ + NewSaveNode.SaveTitle = GStrings["NEWSAVE"]; + NewSaveNode.bNoDelete = true; + SaveGames.Insert(0, &NewSaveNode); +} + +//============================================================================= +// +// +// +//============================================================================= + +bool SavegameManager::RemoveNewSaveNode() +{ + if (SaveGames[0] == &NewSaveNode) + { + SaveGames.Delete(0); + return true; + } + return false; +} + + + + SavegameManager savegameManager; @@ -576,7 +630,6 @@ protected: int savepicTop; int savepicWidth; int savepicHeight; - int rowHeight; int listboxLeft; int listboxTop; @@ -680,10 +733,10 @@ void DLoadSaveMenu::Drawer () screen->Clear (savepicLeft, savepicTop, savepicLeft+savepicWidth, savepicTop+savepicHeight, 0, 0); - if (manager->SaveGames.Size() > 0) + if (manager->SavegameCount() > 0) { const char *text = - (Selected == -1 || !manager->SaveGames[Selected]->bOldVersion) + (Selected == -1 || !manager->GetSavegame(Selected)->bOldVersion) ? GStrings("MNU_NOPICTURE") : GStrings("MNU_DIFFVERSION"); const int textlen = SmallFont->StringWidth (text)*CleanXfac; @@ -713,7 +766,7 @@ void DLoadSaveMenu::Drawer () V_DrawFrame (listboxLeft, listboxTop, listboxWidth, listboxHeight); screen->Clear (listboxLeft, listboxTop, listboxRight, listboxBottom, 0, 0); - if (manager->SaveGames.Size() == 0) + if (manager->SavegameCount() == 0) { const char * text = GStrings("MNU_NOFILES"); const int textlen = SmallFont->StringWidth (text)*CleanXfac; @@ -724,10 +777,10 @@ void DLoadSaveMenu::Drawer () return; } - for (i = 0, j = TopItem; i < listboxRows && j < manager->SaveGames.Size(); i++,j++) + for (i = 0, j = TopItem; i < listboxRows && j < manager->SavegameCount(); i++,j++) { int color; - node = manager->SaveGames[j]; + node = manager->GetSavegame(j); if (node->bOldVersion) { color = CR_BLUE; @@ -785,12 +838,12 @@ bool DLoadSaveMenu::MenuEvent (int mkey, bool fromcontroller) switch (mkey) { case MKEY_Up: - if (manager->SaveGames.Size() > 1) + if (manager->SavegameCount() > 1) { if (Selected == -1) Selected = TopItem; else { - if (--Selected < 0) Selected = manager->SaveGames.Size()-1; + if (--Selected < 0) Selected = manager->SavegameCount()-1; if (Selected < TopItem) TopItem = Selected; else if (Selected >= TopItem + listboxRows) TopItem = MAX(0, Selected - listboxRows + 1); } @@ -800,12 +853,12 @@ bool DLoadSaveMenu::MenuEvent (int mkey, bool fromcontroller) return true; case MKEY_Down: - if (manager->SaveGames.Size() > 1) + if (manager->SavegameCount() > 1) { if (Selected == -1) Selected = TopItem; else { - if (unsigned(++Selected) >= manager->SaveGames.Size()) Selected = 0; + if (unsigned(++Selected) >= manager->SavegameCount()) Selected = 0; if (Selected < TopItem) TopItem = Selected; else if (Selected >= TopItem + listboxRows) TopItem = MAX(0, Selected - listboxRows + 1); } @@ -815,16 +868,16 @@ bool DLoadSaveMenu::MenuEvent (int mkey, bool fromcontroller) return true; case MKEY_PageDown: - if (manager->SaveGames.Size() > 1) + if (manager->SavegameCount() > 1) { - if (TopItem >= (int)manager->SaveGames.Size() - listboxRows) + if (TopItem >= (int)manager->SavegameCount() - listboxRows) { TopItem = 0; if (Selected != -1) Selected = 0; } else { - TopItem = MIN(TopItem + listboxRows, manager->SaveGames.Size() - listboxRows); + TopItem = MIN(TopItem + listboxRows, manager->SavegameCount() - listboxRows); if (TopItem > Selected && Selected != -1) Selected = TopItem; } manager->UnloadSaveData (); @@ -833,11 +886,11 @@ bool DLoadSaveMenu::MenuEvent (int mkey, bool fromcontroller) return true; case MKEY_PageUp: - if (manager->SaveGames.Size() > 1) + if (manager->SavegameCount() > 1) { if (TopItem == 0) { - TopItem = manager->SaveGames.Size() - listboxRows; + TopItem = manager->SavegameCount() - listboxRows; if (Selected != -1) Selected = TopItem; } else @@ -855,9 +908,9 @@ bool DLoadSaveMenu::MenuEvent (int mkey, bool fromcontroller) case MKEY_MBYes: { - if ((unsigned)Selected < manager->SaveGames.Size()) + if ((unsigned)Selected < manager->SavegameCount()) { - int listindex = manager->SaveGames[0]->bNoDelete? Selected-1 : Selected; + int listindex = manager->GetSavegame(0)->bNoDelete? Selected-1 : Selected; manager->DeleteEntry(Selected); manager->UnloadSaveData (); Selected = manager->RemoveSaveSlot (Selected); @@ -889,7 +942,7 @@ bool DLoadSaveMenu::MouseEvent(int type, int x, int y) { int lineno = (y - listboxTop) / rowHeight; - if (TopItem + lineno < (int)manager->SaveGames.Size()) + if (TopItem + lineno < (int)manager->SavegameCount()) { Selected = TopItem + lineno; manager->UnloadSaveData (); @@ -921,7 +974,7 @@ bool DLoadSaveMenu::Responder (event_t *ev) { if (ev->subtype == EV_GUI_KeyDown) { - if ((unsigned)Selected < manager->SaveGames.Size()) + if ((unsigned)Selected < manager->SavegameCount()) { switch (ev->data1) { @@ -934,7 +987,7 @@ bool DLoadSaveMenu::Responder (event_t *ev) { FString EndString; EndString.Format("%s" TEXTCOLOR_WHITE "%s" TEXTCOLOR_NORMAL "?\n\n%s", - GStrings("MNU_DELETESG"), manager->SaveGames[Selected]->SaveTitle.GetChars(), GStrings("PRESSYN")); + GStrings("MNU_DELETESG"), manager->GetSavegame(Selected)->SaveTitle.GetChars(), GStrings("PRESSYN")); M_StartMessage (EndString, 0); } return true; @@ -948,7 +1001,7 @@ bool DLoadSaveMenu::Responder (event_t *ev) } else if (ev->subtype == EV_GUI_WheelDown) { - if (TopItem < (int)manager->SaveGames.Size() - listboxRows) TopItem++; + if (TopItem < (int)manager->SavegameCount() - listboxRows) TopItem++; return true; } } @@ -966,8 +1019,6 @@ class DSaveMenu : public DLoadSaveMenu { DECLARE_CLASS(DSaveMenu, DLoadSaveMenu) - FSaveGameNode NewSaveNode; - public: DSaveMenu(DMenu *parent = nullptr, DListMenuDescriptor *desc = nullptr); @@ -989,18 +1040,9 @@ IMPLEMENT_CLASS(DSaveMenu, false, false) DSaveMenu::DSaveMenu(DMenu *parent, DListMenuDescriptor *desc) : DLoadSaveMenu(parent, desc) { - NewSaveNode.SaveTitle = GStrings["NEWSAVE"]; - NewSaveNode.bNoDelete = true; - manager->SaveGames.Insert(0, &NewSaveNode); + manager->InsertNewSaveNode(); TopItem = 0; - if (manager->LastSaved == -1) - { - Selected = 0; - } - else - { - Selected = manager->LastSaved + 1; - } + Selected = manager->LastSaved + 1; manager->ExtractSaveData (Selected); } @@ -1012,11 +1054,9 @@ DSaveMenu::DSaveMenu(DMenu *parent, DListMenuDescriptor *desc) void DSaveMenu::OnDestroy() { - if (manager->SaveGames[0] == &NewSaveNode) + if (manager->RemoveNewSaveNode()) { - manager->SaveGames.Delete(0); - if (Selected == 0) Selected = -1; - else Selected--; + Selected--; } Super::OnDestroy(); } @@ -1040,7 +1080,7 @@ bool DSaveMenu::MenuEvent (int mkey, bool fromcontroller) if (mkey == MKEY_Enter) { - const char *SavegameString = (Selected != 0)? manager->SaveGames[Selected]->SaveTitle.GetChars() : ""; + const char *SavegameString = (Selected != 0)? manager->GetSavegame(Selected)->SaveTitle.GetChars() : ""; mInput = new DTextEnterMenu(this, SavegameString, SAVESTRINGSIZE, 1, fromcontroller); M_ActivateMenu(mInput); mEntering = true; @@ -1139,7 +1179,7 @@ bool DLoadMenu::MenuEvent (int mkey, bool fromcontroller) { return true; } - if (Selected == -1 || manager->SaveGames.Size() == 0) + if (Selected == -1 || manager->SavegameCount() == 0) { return false; } diff --git a/src/menu/menu.h b/src/menu/menu.h index e48e17814..642d36e99 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -69,7 +69,10 @@ struct FSaveGameNode struct SavegameManager { +private: TArray SaveGames; + FSaveGameNode NewSaveNode; +public: int LastSaved = -1; int LastAccessed = -1; int WindowSize = 0; @@ -81,11 +84,13 @@ struct SavegameManager FTexture *SavePic = nullptr; FBrokenLines *SaveComment = nullptr; - void ClearSaveGames(); +private: int InsertSaveNode(FSaveGameNode *node); +public: + void ClearSaveGames(); int RemoveSaveSlot(int index); void ReadSaveStrings(); - void NotifyNewSave(const char *file, const char *title, bool okForQuicksave); + void NotifyNewSave(const FString &file, const FString &title, bool okForQuicksave); void LoadSavegame(int Selected); void DoSave(int Selected, const char *savegamestring); void DeleteEntry(int Selected); @@ -94,6 +99,10 @@ struct SavegameManager void ClearSaveStuff(); bool DrawSavePic(int x, int y, int w, int h); void SetFileInfo(int Selected); + unsigned SavegameCount(); + FSaveGameNode *GetSavegame(unsigned i); + void InsertNewSaveNode(); + bool RemoveNewSaveNode(); }; From 872969eb140e5c46348e7defadcee3aabb227921 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 18 Feb 2017 14:08:16 +0100 Subject: [PATCH 04/22] - scriptified the LoadMenu class and exported the entire interface to handle the LoadSaveMenu. --- src/menu/loadsavemenu.cpp | 190 +++++++++++++------- src/menu/menu.cpp | 2 +- src/menu/menu.h | 38 ++-- wadsrc/static/zscript/base.txt | 5 - wadsrc/static/zscript/menu/loadsavemenu.txt | 90 ++++++---- 5 files changed, 208 insertions(+), 117 deletions(-) diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index bfe796970..56cd60b39 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 f32c20373..ee7d5cbdb 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 642d36e99..c73b8a7b6 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 57bdc7b01..6c5d671de 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 b07c7a489..870049412 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 From e58a03de9bb8a3a643ffcf7e2768dcde6b239a7c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 18 Feb 2017 14:18:27 +0100 Subject: [PATCH 05/22] - the savegame manager needs a destructor --- src/menu/loadsavemenu.cpp | 4 ++++ src/menu/menu.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index 56cd60b39..b8989d2fa 100644 --- a/src/menu/loadsavemenu.cpp +++ b/src/menu/loadsavemenu.cpp @@ -66,6 +66,10 @@ void FSavegameManager::ClearSaveGames() SaveGames.Clear(); } +FSavegameManager::~FSavegameManager() +{ + ClearSaveGames(); +} //============================================================================= // // Save data maintenance diff --git a/src/menu/menu.h b/src/menu/menu.h index c73b8a7b6..2241513cb 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -80,7 +80,7 @@ private: public: int WindowSize = 0; FSaveGameNode *quickSaveSlot = nullptr; - + ~FSavegameManager(); private: int InsertSaveNode(FSaveGameNode *node); From ee6a90deece2c700f63d5ba5a421666b5ceb26bb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 18 Feb 2017 16:40:32 +0100 Subject: [PATCH 06/22] - scriptified DLoadSaveMenu::Responder. - scriptified DSaveMenu. --- src/d_net.cpp | 5 +- src/g_game.cpp | 14 +- src/menu/loadsavemenu.cpp | 293 ++++---------------- src/version.h | 3 - wadsrc/static/zscript/menu/loadsavemenu.txt | 164 ++++++++++- 5 files changed, 217 insertions(+), 262 deletions(-) diff --git a/src/d_net.cpp b/src/d_net.cpp index 0985cf41c..a480ae0ae 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 1c6c4cca9..e5a48c245 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 b8989d2fa..4bfc8c50e 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 e50bdfd8d..ca7de97fe 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 870049412..a52c8191b 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 { //============================================================================= // From 4a6d0f1fa5695bb9ef0129a1eb19c6f32dc93c95 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 18 Feb 2017 17:35:01 +0100 Subject: [PATCH 07/22] - scriptified DLoadSaveMenu::MenuEvent. --- src/menu/loadsavemenu.cpp | 137 ++------------------ src/menu/menu.h | 2 +- wadsrc/static/zscript/menu/loadsavemenu.txt | 129 +++++++++++++++++- 3 files changed, 138 insertions(+), 130 deletions(-) diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index 4bfc8c50e..f085fa252 100644 --- a/src/menu/loadsavemenu.cpp +++ b/src/menu/loadsavemenu.cpp @@ -105,6 +105,14 @@ int FSavegameManager::RemoveSaveSlot(int index) return index; } +DEFINE_ACTION_FUNCTION(FSavegameManager, RemoveSaveSlot) +{ + PARAM_SELF_STRUCT_PROLOGUE(FSavegameManager); + PARAM_INT(sel); + ACTION_RETURN_INT(self->RemoveSaveSlot(sel)); +} + + //============================================================================= // // @@ -664,7 +672,7 @@ DEFINE_ACTION_FUNCTION(FSavegameManager, SavegameCount) // //============================================================================= -FSaveGameNode *FSavegameManager::GetSavegame(unsigned i) +FSaveGameNode *FSavegameManager::GetSavegame(int i) { return SaveGames[i]; } @@ -764,8 +772,6 @@ public: void OnDestroy() override; void Drawer (); - bool MenuEvent (int mkey, bool fromcontroller); - bool MouseEvent(int type, int x, int y); }; IMPLEMENT_CLASS(DLoadSaveMenu, false, false) @@ -925,131 +931,6 @@ void DLoadSaveMenu::Drawer () } } -//============================================================================= -// -// -// -//============================================================================= - -bool DLoadSaveMenu::MenuEvent (int mkey, bool fromcontroller) -{ - switch (mkey) - { - case MKEY_Up: - if (manager->SavegameCount() > 1) - { - if (Selected == -1) Selected = TopItem; - else - { - if (--Selected < 0) Selected = manager->SavegameCount()-1; - if (Selected < TopItem) TopItem = Selected; - else if (Selected >= TopItem + listboxRows) TopItem = MAX(0, Selected - listboxRows + 1); - } - manager->UnloadSaveData (); - manager->ExtractSaveData (Selected); - } - return true; - - case MKEY_Down: - if (manager->SavegameCount() > 1) - { - if (Selected == -1) Selected = TopItem; - else - { - if (unsigned(++Selected) >= manager->SavegameCount()) Selected = 0; - if (Selected < TopItem) TopItem = Selected; - else if (Selected >= TopItem + listboxRows) TopItem = MAX(0, Selected - listboxRows + 1); - } - manager->UnloadSaveData (); - manager->ExtractSaveData (Selected); - } - return true; - - case MKEY_PageDown: - if (manager->SavegameCount() > 1) - { - if (TopItem >= (int)manager->SavegameCount() - listboxRows) - { - TopItem = 0; - if (Selected != -1) Selected = 0; - } - else - { - TopItem = MIN(TopItem + listboxRows, manager->SavegameCount() - listboxRows); - if (TopItem > Selected && Selected != -1) Selected = TopItem; - } - manager->UnloadSaveData (); - manager->ExtractSaveData (Selected); - } - return true; - - case MKEY_PageUp: - if (manager->SavegameCount() > 1) - { - if (TopItem == 0) - { - TopItem = manager->SavegameCount() - listboxRows; - if (Selected != -1) Selected = TopItem; - } - else - { - TopItem = MAX(TopItem - listboxRows, 0); - if (Selected >= TopItem + listboxRows) Selected = TopItem; - } - manager->UnloadSaveData (); - manager->ExtractSaveData (Selected); - } - return true; - - case MKEY_Enter: - return false; // This event will be handled by the subclasses - - case MKEY_MBYes: - { - if ((unsigned)Selected < manager->SavegameCount()) - { - Selected = manager->RemoveSaveSlot (Selected); - } - return true; - } - - default: - return Super::MenuEvent(mkey, fromcontroller); - } -} - -//============================================================================= -// -// -// -//============================================================================= - -bool DLoadSaveMenu::MouseEvent(int type, int x, int y) -{ - if (x >= listboxLeft && x < listboxLeft + listboxWidth && - y >= listboxTop && y < listboxTop + listboxHeight) - { - int lineno = (y - listboxTop) / rowHeight; - - if (TopItem + lineno < (int)manager->SavegameCount()) - { - Selected = TopItem + lineno; - manager->UnloadSaveData (); - manager->ExtractSaveData (Selected); - if (type == MOUSE_Release) - { - if (MenuEvent(MKEY_Enter, true)) - { - return true; - } - } - } - else Selected = -1; - } - else Selected = -1; - - return Super::MouseEvent(type, x, y); -} DEFINE_FIELD(FSaveGameNode, SaveTitle); DEFINE_FIELD(FSaveGameNode, Filename); diff --git a/src/menu/menu.h b/src/menu/menu.h index 2241513cb..dd06dc605 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -100,7 +100,7 @@ public: void DrawSaveComment(FFont *font, int cr, int x, int y, int scalefactor); void SetFileInfo(int Selected); unsigned SavegameCount(); - FSaveGameNode *GetSavegame(unsigned i); + FSaveGameNode *GetSavegame(int i); void InsertNewSaveNode(); bool RemoveNewSaveNode(); diff --git a/wadsrc/static/zscript/menu/loadsavemenu.txt b/wadsrc/static/zscript/menu/loadsavemenu.txt index a52c8191b..b97042cf7 100644 --- a/wadsrc/static/zscript/menu/loadsavemenu.txt +++ b/wadsrc/static/zscript/menu/loadsavemenu.txt @@ -51,7 +51,7 @@ struct SavegameManager native //void ReadSaveStrings(); native void UnloadSaveData(); - //int RemoveSaveSlot(int index); + native int RemoveSaveSlot(int index); native void LoadSavegame(int Selected); native void DoSave(int Selected, String savegamestring); native int ExtractSaveData(int index); @@ -99,6 +99,133 @@ class LoadSaveMenu : ListMenu native native TextEnterMenu mInput; + + //============================================================================= + // + // + // + //============================================================================= + + override bool MenuEvent (int mkey, bool fromcontroller) + { + switch (mkey) + { + case MKEY_Up: + if (manager.SavegameCount() > 1) + { + if (Selected == -1) Selected = TopItem; + else + { + if (--Selected < 0) Selected = manager.SavegameCount()-1; + if (Selected < TopItem) TopItem = Selected; + else if (Selected >= TopItem + listboxRows) TopItem = MAX(0, Selected - listboxRows + 1); + } + manager.UnloadSaveData (); + manager.ExtractSaveData (Selected); + } + return true; + + case MKEY_Down: + if (manager.SavegameCount() > 1) + { + if (Selected == -1) Selected = TopItem; + else + { + if (++Selected >= manager.SavegameCount()) Selected = 0; + if (Selected < TopItem) TopItem = Selected; + else if (Selected >= TopItem + listboxRows) TopItem = MAX(0, Selected - listboxRows + 1); + } + manager.UnloadSaveData (); + manager.ExtractSaveData (Selected); + } + return true; + + case MKEY_PageDown: + if (manager.SavegameCount() > 1) + { + if (TopItem >= manager.SavegameCount() - listboxRows) + { + TopItem = 0; + if (Selected != -1) Selected = 0; + } + else + { + TopItem = MIN(TopItem + listboxRows, manager.SavegameCount() - listboxRows); + if (TopItem > Selected && Selected != -1) Selected = TopItem; + } + manager.UnloadSaveData (); + manager.ExtractSaveData (Selected); + } + return true; + + case MKEY_PageUp: + if (manager.SavegameCount() > 1) + { + if (TopItem == 0) + { + TopItem = MAX(0, manager.SavegameCount() - listboxRows); + if (Selected != -1) Selected = TopItem; + } + else + { + TopItem = MAX(TopItem - listboxRows, 0); + if (Selected >= TopItem + listboxRows) Selected = TopItem; + } + manager.UnloadSaveData (); + manager.ExtractSaveData (Selected); + } + return true; + + case MKEY_Enter: + return false; // This event will be handled by the subclasses + + case MKEY_MBYes: + { + if (Selected < manager.SavegameCount()) + { + Selected = manager.RemoveSaveSlot (Selected); + } + return true; + } + + default: + return Super.MenuEvent(mkey, fromcontroller); + } + } + + //============================================================================= + // + // + // + //============================================================================= + + override bool MouseEvent(int type, int x, int y) + { + if (x >= listboxLeft && x < listboxLeft + listboxWidth && + y >= listboxTop && y < listboxTop + listboxHeight) + { + int lineno = (y - listboxTop) / rowHeight; + + if (TopItem + lineno < manager.SavegameCount()) + { + Selected = TopItem + lineno; + manager.UnloadSaveData (); + manager.ExtractSaveData (Selected); + if (type == MOUSE_Release) + { + if (MenuEvent(MKEY_Enter, true)) + { + return true; + } + } + } + else Selected = -1; + } + else Selected = -1; + + return Super.MouseEvent(type, x, y); + } + //============================================================================= // From e46d378fb293991bb6cd30d4982904dfd7ac537a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 18 Feb 2017 17:51:40 +0100 Subject: [PATCH 08/22] - sciptified DLoadSaveMenu::Drawer. --- src/menu/loadsavemenu.cpp | 135 ++++---------------- wadsrc/static/zscript/menu/loadsavemenu.txt | 104 ++++++++++++++- 2 files changed, 124 insertions(+), 115 deletions(-) diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index f085fa252..0f4fa56a9 100644 --- a/src/menu/loadsavemenu.cpp +++ b/src/menu/loadsavemenu.cpp @@ -593,6 +593,16 @@ bool FSavegameManager::DrawSavePic(int x, int y, int w, int h) return true; } +DEFINE_ACTION_FUNCTION(FSavegameManager, DrawSavePic) +{ + PARAM_SELF_STRUCT_PROLOGUE(FSavegameManager); + PARAM_INT(x); + PARAM_INT(y); + PARAM_INT(w); + PARAM_INT(h); + ACTION_RETURN_BOOL(self->DrawSavePic(x, y, w, h)); +} + //============================================================================= // // @@ -618,6 +628,18 @@ void FSavegameManager::DrawSaveComment(FFont *font, int cr, int x, int y, int sc CleanYfac = sy; } +DEFINE_ACTION_FUNCTION(FSavegameManager, DrawSaveComment) +{ + PARAM_SELF_STRUCT_PROLOGUE(FSavegameManager); + PARAM_POINTER(fnt, FFont); + PARAM_INT(cr); + PARAM_INT(x); + PARAM_INT(y); + PARAM_INT(fac); + self->DrawSaveComment(fnt, cr, x, y, fac); + return 0; +} + //============================================================================= // @@ -770,8 +792,6 @@ public: DLoadSaveMenu(DMenu *parent = nullptr, DListMenuDescriptor *desc = nullptr); void OnDestroy() override; - - void Drawer (); }; IMPLEMENT_CLASS(DLoadSaveMenu, false, false) @@ -820,117 +840,6 @@ void DLoadSaveMenu::OnDestroy() Super::OnDestroy(); } -//============================================================================= -// -// -// -//============================================================================= - -void DLoadSaveMenu::Drawer () -{ - Super::Drawer(); - - FSaveGameNode *node; - int i; - unsigned j; - bool didSeeSelected = false; - - // Draw picture area - if (gameaction == ga_loadgame || gameaction == ga_loadgamehidecon || gameaction == ga_savegame) - { - return; - } - - V_DrawFrame (savepicLeft, savepicTop, savepicWidth, savepicHeight); - if (!manager->DrawSavePic(savepicLeft, savepicTop, savepicWidth, savepicHeight)) - { - screen->Clear (savepicLeft, savepicTop, - savepicLeft+savepicWidth, savepicTop+savepicHeight, 0, 0); - - if (manager->SavegameCount() > 0) - { - const char *text = - (Selected == -1 || !manager->GetSavegame(Selected)->bOldVersion) - ? GStrings("MNU_NOPICTURE") : GStrings("MNU_DIFFVERSION"); - const int textlen = SmallFont->StringWidth (text)*CleanXfac; - - screen->DrawText (SmallFont, CR_GOLD, savepicLeft+(savepicWidth-textlen)/2, - savepicTop+(savepicHeight-rowHeight)/2, text, - DTA_CleanNoMove, true, TAG_DONE); - } - } - - // Draw comment area - V_DrawFrame (commentLeft, commentTop, commentWidth, commentHeight); - screen->Clear (commentLeft, commentTop, commentRight, commentBottom, 0, 0); - - manager->DrawSaveComment(SmallFont, CR_GOLD, commentLeft, commentTop, CleanYfac); - - // Draw file area - V_DrawFrame (listboxLeft, listboxTop, listboxWidth, listboxHeight); - screen->Clear (listboxLeft, listboxTop, listboxRight, listboxBottom, 0, 0); - - if (manager->SavegameCount() == 0) - { - const char * text = GStrings("MNU_NOFILES"); - const int textlen = SmallFont->StringWidth (text)*CleanXfac; - - screen->DrawText (SmallFont, CR_GOLD, listboxLeft+(listboxWidth-textlen)/2, - listboxTop+(listboxHeight-rowHeight)/2, text, - DTA_CleanNoMove, true, TAG_DONE); - return; - } - - for (i = 0, j = TopItem; i < listboxRows && j < manager->SavegameCount(); i++,j++) - { - int color; - node = manager->GetSavegame(j); - if (node->bOldVersion) - { - color = CR_BLUE; - } - else if (node->bMissingWads) - { - color = CR_ORANGE; - } - else if ((int)j == Selected) - { - color = CR_WHITE; - } - else - { - color = CR_TAN; - } - - if ((int)j == Selected) - { - screen->Clear (listboxLeft, listboxTop+rowHeight*i, - listboxRight, listboxTop+rowHeight*(i+1), -1, - mEntering ? MAKEARGB(255,255,0,0) : MAKEARGB(255,0,0,255)); - didSeeSelected = true; - if (!mEntering) - { - screen->DrawText (SmallFont, color, - listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, node->SaveTitle.GetChars(), - DTA_CleanNoMove, true, TAG_DONE); - } - else - { - FString s = mInput->GetText() + SmallFont->GetCursor(); - screen->DrawText (SmallFont, CR_WHITE, - listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, s, - DTA_CleanNoMove, true, TAG_DONE); - } - } - else - { - screen->DrawText (SmallFont, color, - listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, node->SaveTitle.GetChars(), - DTA_CleanNoMove, true, TAG_DONE); - } - } -} - DEFINE_FIELD(FSaveGameNode, SaveTitle); DEFINE_FIELD(FSaveGameNode, Filename); diff --git a/wadsrc/static/zscript/menu/loadsavemenu.txt b/wadsrc/static/zscript/menu/loadsavemenu.txt index b97042cf7..960d238eb 100644 --- a/wadsrc/static/zscript/menu/loadsavemenu.txt +++ b/wadsrc/static/zscript/menu/loadsavemenu.txt @@ -56,8 +56,8 @@ struct SavegameManager native 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); + native bool DrawSavePic(int x, int y, int w, int h); + native void DrawSaveComment(Font font, int cr, int x, int y, int scalefactor); native void SetFileInfo(int Selected); native int SavegameCount(); native SaveGameNode GetSavegame(int i); @@ -99,6 +99,106 @@ class LoadSaveMenu : ListMenu native native TextEnterMenu mInput; + //============================================================================= + // + // + // + //============================================================================= + + override void Drawer () + { + Super.Drawer(); + + SaveGameNode node; + int i; + int j; + bool didSeeSelected = false; + + // Draw picture area + if (gameaction == ga_loadgame || gameaction == ga_loadgamehidecon || gameaction == ga_savegame) + { + return; + } + + Screen.DrawFrame (savepicLeft, savepicTop, savepicWidth, savepicHeight); + if (!manager.DrawSavePic(savepicLeft, savepicTop, savepicWidth, savepicHeight)) + { + screen.Clear (savepicLeft, savepicTop, savepicLeft+savepicWidth, savepicTop+savepicHeight, 0, 0); + + if (manager.SavegameCount() > 0) + { + String text = (Selected == -1 || !manager.GetSavegame(Selected).bOldVersion)? Stringtable.Localize("$MNU_NOPICTURE") : Stringtable.Localize("$MNU_DIFFVERSION"); + int textlen = SmallFont.StringWidth(text) * CleanXfac; + + screen.DrawText (SmallFont, Font.CR_GOLD, savepicLeft+(savepicWidth-textlen)/2, + savepicTop+(savepicHeight-rowHeight)/2, text, DTA_CleanNoMove, true); + } + } + + // Draw comment area + Screen.DrawFrame (commentLeft, commentTop, commentWidth, commentHeight); + screen.Clear (commentLeft, commentTop, commentRight, commentBottom, 0, 0); + + manager.DrawSaveComment(SmallFont, Font.CR_GOLD, commentLeft, commentTop, CleanYfac); + + // Draw file area + Screen.DrawFrame (listboxLeft, listboxTop, listboxWidth, listboxHeight); + screen.Clear (listboxLeft, listboxTop, listboxRight, listboxBottom, 0, 0); + + if (manager.SavegameCount() == 0) + { + String text = Stringtable.Localize("$MNU_NOFILES"); + int textlen = SmallFont.StringWidth(text) * CleanXfac; + + screen.DrawText (SmallFont, Font.CR_GOLD, listboxLeft+(listboxWidth-textlen)/2, listboxTop+(listboxHeight-rowHeight)/2, text, DTA_CleanNoMove, true); + return; + } + + j = TopItem; + for (i = 0; i < listboxRows && j < manager.SavegameCount(); i++) + { + int colr; + node = manager.GetSavegame(j); + if (node.bOldVersion) + { + colr = Font.CR_BLUE; + } + else if (node.bMissingWads) + { + colr = Font.CR_ORANGE; + } + else if (j == Selected) + { + colr = Font.CR_WHITE; + } + else + { + colr = Font.CR_TAN; + } + + if (j == Selected) + { + screen.Clear (listboxLeft, listboxTop+rowHeight*i, listboxRight, listboxTop+rowHeight*(i+1), mEntering ? Color(255,255,0,0) : Color(255,0,0,255)); + didSeeSelected = true; + if (!mEntering) + { + screen.DrawText (SmallFont, colr, listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, node.SaveTitle, DTA_CleanNoMove, true); + } + else + { + String s = mInput.GetText() .. SmallFont.GetCursor(); + screen.DrawText (SmallFont, Font.CR_WHITE, listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, s, DTA_CleanNoMove, true); + } + } + else + { + screen.DrawText (SmallFont, colr, listboxLeft+1, listboxTop+rowHeight*i+CleanYfac, node.SaveTitle, DTA_CleanNoMove, true); + } + j++; + } + } + + //============================================================================= // From 6a65f022572e740192c5e050d5103b1e3aeb4d01 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 18 Feb 2017 18:01:24 +0100 Subject: [PATCH 09/22] - completed scriptification of LoadSaveMenu. --- src/menu/loadsavemenu.cpp | 126 +++----------------- wadsrc/static/zscript/menu/loadsavemenu.txt | 102 ++++++++++++---- 2 files changed, 94 insertions(+), 134 deletions(-) diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index 0f4fa56a9..fdca9abc8 100644 --- a/src/menu/loadsavemenu.cpp +++ b/src/menu/loadsavemenu.cpp @@ -72,6 +72,7 @@ FSavegameManager::~FSavegameManager() { ClearSaveGames(); } + //============================================================================= // // Save data maintenance @@ -313,6 +314,14 @@ void FSavegameManager::ReadSaveStrings() } } +DEFINE_ACTION_FUNCTION(FSavegameManager, ReadSaveStrings) +{ + PARAM_SELF_STRUCT_PROLOGUE(FSavegameManager); + self->ReadSaveStrings(); + return 0; +} + + //============================================================================= // // @@ -579,6 +588,12 @@ void FSavegameManager::ClearSaveStuff() } } +DEFINE_ACTION_FUNCTION(FSavegameManager, ClearSaveStuff) +{ + PARAM_SELF_STRUCT_PROLOGUE(FSavegameManager); + self->ClearSaveStuff(); + return 0; +} //============================================================================= // @@ -751,94 +766,12 @@ DEFINE_ACTION_FUNCTION(FSavegameManager, RemoveNewSaveNode) FSavegameManager savegameManager; - - - -class DLoadSaveMenu : public DListMenu +DEFINE_ACTION_FUNCTION(FSavegameManager, GetManager) { - DECLARE_CLASS(DLoadSaveMenu, DListMenu) - -public: - - FSavegameManager *manager; - - int Selected; - int TopItem; - - - int savepicLeft; - int savepicTop; - int savepicWidth; - int savepicHeight; - int rowHeight; - int listboxLeft; - int listboxTop; - int listboxWidth; - - int listboxRows; - int listboxHeight; - int listboxRight; - int listboxBottom; - - int commentLeft; - int commentTop; - int commentWidth; - int commentHeight; - int commentRight; - int commentBottom; - - bool mEntering; - DTextEnterMenu *mInput = nullptr; - - DLoadSaveMenu(DMenu *parent = nullptr, DListMenuDescriptor *desc = nullptr); - void OnDestroy() override; -}; - -IMPLEMENT_CLASS(DLoadSaveMenu, false, false) - - - -//============================================================================= -// -// End of static savegame maintenance code -// -//============================================================================= - -DLoadSaveMenu::DLoadSaveMenu(DMenu *parent, DListMenuDescriptor *desc) -: DListMenu(parent, desc) -{ - manager = &savegameManager; - manager->ReadSaveStrings(); - - savepicLeft = 10; - savepicTop = 54*CleanYfac; - savepicWidth = 216*screen->GetWidth()/640; - savepicHeight = 135*screen->GetHeight()/400; - manager->WindowSize = savepicWidth / CleanXfac; - - rowHeight = (SmallFont->GetHeight() + 1) * CleanYfac; - listboxLeft = savepicLeft + savepicWidth + 14; - listboxTop = savepicTop; - listboxWidth = screen->GetWidth() - listboxLeft - 10; - int listboxHeight1 = screen->GetHeight() - listboxTop - 10; - listboxRows = (listboxHeight1 - 1) / rowHeight; - listboxHeight = listboxRows * rowHeight + 1; - listboxRight = listboxLeft + listboxWidth; - listboxBottom = listboxTop + listboxHeight; - - commentLeft = savepicLeft; - commentTop = savepicTop + savepicHeight + 16; - commentWidth = savepicWidth; - commentHeight = (51+(screen->GetHeight()>200?10:0))*CleanYfac; - commentRight = commentLeft + commentWidth; - commentBottom = commentTop + commentHeight; + PARAM_PROLOGUE; + ACTION_RETURN_POINTER(&savegameManager); } -void DLoadSaveMenu::OnDestroy() -{ - manager->ClearSaveStuff (); - Super::OnDestroy(); -} DEFINE_FIELD(FSaveGameNode, SaveTitle); @@ -850,26 +783,3 @@ 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/wadsrc/static/zscript/menu/loadsavemenu.txt b/wadsrc/static/zscript/menu/loadsavemenu.txt index 960d238eb..34d56f374 100644 --- a/wadsrc/static/zscript/menu/loadsavemenu.txt +++ b/wadsrc/static/zscript/menu/loadsavemenu.txt @@ -48,14 +48,15 @@ struct SavegameManager native native int WindowSize; native SaveGameNode quickSaveSlot; - //void ReadSaveStrings(); + native static SavegameManager GetManager(); + native void ReadSaveStrings(); native void UnloadSaveData(); native int RemoveSaveSlot(int index); native void LoadSavegame(int Selected); native void DoSave(int Selected, String savegamestring); native int ExtractSaveData(int index); - //void ClearSaveStuff(); + native void ClearSaveStuff(); native bool DrawSavePic(int x, int y, int w, int h); native void DrawSaveComment(Font font, int cr, int x, int y, int scalefactor); native void SetFileInfo(int Selected); @@ -68,37 +69,86 @@ struct SavegameManager native -class LoadSaveMenu : ListMenu native +class LoadSaveMenu : ListMenu { - native SavegameManager manager; - native int TopItem; - native int Selected; + SavegameManager manager; + int TopItem; + 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; + int savepicLeft; + int savepicTop; + int savepicWidth; + int savepicHeight; + int rowHeight; + int listboxLeft; + int listboxTop; + int listboxWidth; - native int listboxRows; - native int listboxHeight; - native int listboxRight; - native int listboxBottom; + int listboxRows; + int listboxHeight; + int listboxRight; + int listboxBottom; - native int commentLeft; - native int commentTop; - native int commentWidth; - native int commentHeight; - native int commentRight; - native int commentBottom; + int commentLeft; + int commentTop; + int commentWidth; + int commentHeight; + int commentRight; + int commentBottom; - native bool mEntering; - native TextEnterMenu mInput; + bool mEntering; + TextEnterMenu mInput; + + //============================================================================= + // + // + // + //============================================================================= + + override void Init(Menu parent, ListMenuDescriptor desc) + { + Super.Init(parent, desc); + manager = SavegameManager.GetManager(); + manager.ReadSaveStrings(); + + savepicLeft = 10; + savepicTop = 54*CleanYfac; + savepicWidth = 216*screen.GetWidth()/640; + savepicHeight = 135*screen.GetHeight()/400; + manager.WindowSize = savepicWidth / CleanXfac; + + rowHeight = (SmallFont.GetHeight() + 1) * CleanYfac; + listboxLeft = savepicLeft + savepicWidth + 14; + listboxTop = savepicTop; + listboxWidth = screen.GetWidth() - listboxLeft - 10; + int listboxHeight1 = screen.GetHeight() - listboxTop - 10; + listboxRows = (listboxHeight1 - 1) / rowHeight; + listboxHeight = listboxRows * rowHeight + 1; + listboxRight = listboxLeft + listboxWidth; + listboxBottom = listboxTop + listboxHeight; + + commentLeft = savepicLeft; + commentTop = savepicTop + savepicHeight + 16; + commentWidth = savepicWidth; + commentHeight = (51+(screen.GetHeight()>200?10:0))*CleanYfac; + commentRight = commentLeft + commentWidth; + commentBottom = commentTop + commentHeight; + } + + //============================================================================= + // + // + // + //============================================================================= + + override void OnDestroy() + { + manager.ClearSaveStuff (); + Super.OnDestroy(); + } + //============================================================================= // // From b7a5437af6eaf6f0c5d94cffe7c3fba7a5db8509 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 18 Feb 2017 18:35:44 +0100 Subject: [PATCH 10/22] - scriptified parts of ListMenu. --- src/menu/listmenu.cpp | 162 +---------------- src/menu/menu.cpp | 36 +--- src/menu/menu.h | 9 - src/menu/menudef.cpp | 2 +- src/menu/playermenu.cpp | 20 +-- wadsrc/static/zscript/menu/listmenu.txt | 178 ++++++++++++++++++- wadsrc/static/zscript/menu/listmenuitems.txt | 2 +- 7 files changed, 190 insertions(+), 219 deletions(-) diff --git a/src/menu/listmenu.cpp b/src/menu/listmenu.cpp index 18c627359..beaa687f1 100644 --- a/src/menu/listmenu.cpp +++ b/src/menu/listmenu.cpp @@ -115,167 +115,13 @@ DMenuItemBase *DListMenu::GetItem(FName name) return NULL; } -//============================================================================= -// -// -// -//============================================================================= - -bool DListMenu::Responder (event_t *ev) -{ - if (ev->type == EV_GUI_Event) - { - if (ev->subtype == EV_GUI_KeyDown) - { - int ch = tolower (ev->data1); - - for(unsigned i = mDesc->mSelectedItem + 1; i < mDesc->mItems.Size(); i++) - { - if (mDesc->mItems[i]->CheckHotkey(ch)) - { - mDesc->mSelectedItem = i; - S_Sound(CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); - return true; - } - } - for(int i = 0; i < mDesc->mSelectedItem; i++) - { - if (mDesc->mItems[i]->CheckHotkey(ch)) - { - mDesc->mSelectedItem = i; - S_Sound(CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); - return true; - } - } - } - } - return Super::Responder(ev); -} - -//============================================================================= -// -// -// -//============================================================================= - -bool DListMenu::MenuEvent (int mkey, bool fromcontroller) -{ - int oldSelect = mDesc->mSelectedItem; - int startedAt = mDesc->mSelectedItem; - if (startedAt < 0) startedAt = 0; - - switch (mkey) - { - case MKEY_Up: - do - { - if (--mDesc->mSelectedItem < 0) mDesc->mSelectedItem = mDesc->mItems.Size()-1; - } - while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable() && mDesc->mSelectedItem != startedAt); - if (mDesc->mSelectedItem == startedAt) mDesc->mSelectedItem = oldSelect; - S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); - return true; - - case MKEY_Down: - do - { - if (++mDesc->mSelectedItem >= (int)mDesc->mItems.Size()) mDesc->mSelectedItem = 0; - } - while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable() && mDesc->mSelectedItem != startedAt); - if (mDesc->mSelectedItem == startedAt) mDesc->mSelectedItem = oldSelect; - S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); - return true; - - case MKEY_Enter: - if (mDesc->mSelectedItem >= 0 && mDesc->mItems[mDesc->mSelectedItem]->Activate()) - { - S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); - } - return true; - - default: - return Super::MenuEvent(mkey, fromcontroller); - } -} - -//============================================================================= -// -// -// -//============================================================================= - -bool DListMenu::MouseEvent(int type, int x, int y) -{ - int sel = -1; - - // convert x/y from screen to virtual coordinates, according to CleanX/Yfac use in DrawTexture - x = ((x - (screen->GetWidth() / 2)) / CleanXfac) + 160; - y = ((y - (screen->GetHeight() / 2)) / CleanYfac) + 100; - - if (mFocusControl != NULL) - { - mFocusControl->MouseEvent(type, x, y); - return true; - } - else - { - if ((mDesc->mWLeft <= 0 || x > mDesc->mWLeft) && - (mDesc->mWRight <= 0 || x < mDesc->mWRight)) - { - for(unsigned i=0;imItems.Size(); i++) - { - if (mDesc->mItems[i]->CheckCoordinate(x, y)) - { - if ((int)i != mDesc->mSelectedItem) - { - //S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); - } - mDesc->mSelectedItem = i; - mDesc->mItems[i]->MouseEvent(type, x, y); - return true; - } - } - } - } - mDesc->mSelectedItem = -1; - return Super::MouseEvent(type, x, y); -} - -//============================================================================= -// -// -// -//============================================================================= - -void DListMenu::Ticker () -{ - Super::Ticker(); - for(unsigned i=0;imItems.Size(); i++) - { - mDesc->mItems[i]->Ticker(); - } -} - -//============================================================================= -// -// -// -//============================================================================= - -void DListMenu::Drawer () -{ - for(unsigned i=0;imItems.Size(); i++) - { - if (mDesc->mItems[i]->mEnabled) mDesc->mItems[i]->Drawer(mDesc->mSelectedItem == (int)i); - } - if (mDesc->mSelectedItem >= 0 && mDesc->mSelectedItem < (int)mDesc->mItems.Size()) - mDesc->mItems[mDesc->mSelectedItem]->DrawSelector(mDesc->mSelectOfsX, mDesc->mSelectOfsY, mDesc->mSelector); - Super::Drawer(); -} - //============================================================================= // // base class for menu items // //============================================================================= IMPLEMENT_CLASS(DMenuItemBase, false, false) + +DEFINE_FIELD(DListMenu, mDesc) +DEFINE_FIELD(DListMenu, mFocusControl) + diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index ee7d5cbdb..dc7e02126 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -629,7 +629,7 @@ void M_SetMenu(FName menu, int param) if (cls == nullptr) cls = DefaultListMenuClass; if (cls == nullptr) cls = PClass::FindClass("ListMenu"); - DListMenu *newmenu = (DListMenu *)cls->CreateNew(); + DMenu *newmenu = (DMenu *)cls->CreateNew(); IFVIRTUALPTRNAME(newmenu, "ListMenu", Init) { VMValue params[3] = { newmenu, DMenu::CurrentMenu, ld }; @@ -1220,9 +1220,6 @@ DEFINE_FIELD(DMenuItemBase, mYpos) DEFINE_FIELD(DMenuItemBase, mAction) DEFINE_FIELD(DMenuItemBase, mEnabled) -DEFINE_FIELD(DListMenu, mDesc) -DEFINE_FIELD(DListMenu, mFocusControl) - DEFINE_FIELD(DListMenuDescriptor, mItems) DEFINE_FIELD(DListMenuDescriptor, mSelectedItem) DEFINE_FIELD(DListMenuDescriptor, mSelectOfsX) @@ -1344,15 +1341,6 @@ void DMenuItemBase::Ticker() } } -void DMenuItemBase::Drawer(bool selected) -{ - IFVIRTUAL(DMenuItemBase, Drawer) - { - VMValue params[] = { (DObject*)this, selected }; - GlobalVMStack.Call(func, params, countof(params), nullptr, 0, nullptr); - } -} - bool DMenuItemBase::Selectable() { IFVIRTUAL(DMenuItemBase, Selectable) @@ -1534,25 +1522,3 @@ int DMenuItemBase::Draw(DOptionMenuDescriptor *desc, int y, int indent, bool sel } return false; } - -void DMenuItemBase::DrawSelector(int xofs, int yofs, FTextureID tex) -{ - if (tex.isNull()) - { - if ((DMenu::MenuTime % 8) < 6) - { - screen->DrawText(ConFont, OptionSettings.mFontColorSelection, - (mXpos + xofs - 160) * CleanXfac + screen->GetWidth() / 2, - (mYpos + yofs - 100) * CleanYfac + screen->GetHeight() / 2, - "\xd", - DTA_CellX, 8 * CleanXfac, - DTA_CellY, 8 * CleanYfac, - TAG_DONE); - } - } - else - { - screen->DrawTexture(TexMan(tex), mXpos + xofs, mYpos + yofs, DTA_Clean, true, TAG_DONE); - } -} - diff --git a/src/menu/menu.h b/src/menu/menu.h index dd06dc605..e197a62ef 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -319,7 +319,6 @@ public: bool CheckCoordinate(int x, int y); void Ticker(); - void Drawer(bool selected); bool Selectable(); bool Activate(); FName GetAction(int *pparam); @@ -338,9 +337,6 @@ public: int GetY() { return mYpos; } int GetX() { return mXpos; } void SetX(int x) { mXpos = x; } - - void DrawSelector(int xofs, int yofs, FTextureID tex); - }; //============================================================================= @@ -361,11 +357,6 @@ public: DListMenu(DMenu *parent = NULL, DListMenuDescriptor *desc = NULL); virtual void Init(DMenu *parent = NULL, DListMenuDescriptor *desc = NULL); DMenuItemBase *GetItem(FName name); - bool Responder (event_t *ev); - bool MenuEvent (int mkey, bool fromcontroller); - bool MouseEvent(int type, int x, int y); - void Ticker (); - void Drawer (); void SetFocus(DMenuItemBase *fc) { mFocusControl = fc; diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index 8afed617e..252533091 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -294,7 +294,7 @@ static void ParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc) { sc.MustGetString(); PClass *cls = PClass::FindClass(sc.String); - if (cls == nullptr || !cls->IsDescendantOf(RUNTIME_CLASS(DListMenu))) + if (cls == nullptr || !cls->IsDescendantOf("ListMenu")) { sc.ScriptError("Unknown menu class '%s'", sc.String); } diff --git a/src/menu/playermenu.cpp b/src/menu/playermenu.cpp index 519af0a9d..c900cc4a7 100644 --- a/src/menu/playermenu.cpp +++ b/src/menu/playermenu.cpp @@ -61,7 +61,7 @@ EXTERN_CVAR(Bool, cl_run) DEFINE_ACTION_FUNCTION(DPlayerMenu, ColorChanged) { - PARAM_SELF_PROLOGUE(DListMenu); + PARAM_SELF_PROLOGUE(DMenu); PARAM_INT(r); PARAM_INT(g); PARAM_INT(b); @@ -86,7 +86,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, ColorChanged) DEFINE_ACTION_FUNCTION(DPlayerMenu, PlayerNameChanged) { - PARAM_SELF_PROLOGUE(DListMenu); + PARAM_SELF_PROLOGUE(DMenu); PARAM_STRING(s); const char *pp = s; FString command("name \""); @@ -116,7 +116,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, PlayerNameChanged) DEFINE_ACTION_FUNCTION(DPlayerMenu, ColorSetChanged) { - PARAM_SELF_PROLOGUE(DListMenu); + PARAM_SELF_PROLOGUE(DMenu); PARAM_INT(sel); if (self == DMenu::CurrentMenu) { @@ -136,7 +136,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, ColorSetChanged) DEFINE_ACTION_FUNCTION(DPlayerMenu, ClassChanged) { - PARAM_SELF_PROLOGUE(DListMenu); + PARAM_SELF_PROLOGUE(DMenu); PARAM_INT(sel); PARAM_POINTER(cls, FPlayerClass); if (self == DMenu::CurrentMenu) @@ -156,7 +156,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, ClassChanged) DEFINE_ACTION_FUNCTION(DPlayerMenu, SkinChanged) { - PARAM_SELF_PROLOGUE(DListMenu); + PARAM_SELF_PROLOGUE(DMenu); PARAM_INT(sel); if (self == DMenu::CurrentMenu) { @@ -174,7 +174,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, SkinChanged) DEFINE_ACTION_FUNCTION(DPlayerMenu, AutoaimChanged) { - PARAM_SELF_PROLOGUE(DListMenu); + PARAM_SELF_PROLOGUE(DMenu); PARAM_FLOAT(val); // only allow if the menu is active to prevent abuse. if (self == DMenu::CurrentMenu) @@ -192,7 +192,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, AutoaimChanged) DEFINE_ACTION_FUNCTION(DPlayerMenu, TeamChanged) { - PARAM_SELF_PROLOGUE(DListMenu); + PARAM_SELF_PROLOGUE(DMenu); PARAM_INT(val); // only allow if the menu is active to prevent abuse. if (self == DMenu::CurrentMenu) @@ -210,7 +210,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, TeamChanged) DEFINE_ACTION_FUNCTION(DPlayerMenu, GenderChanged) { - PARAM_SELF_PROLOGUE(DListMenu); + PARAM_SELF_PROLOGUE(DMenu); PARAM_INT(v); // only allow if the menu is active to prevent abuse. if (self == DMenu::CurrentMenu) @@ -228,7 +228,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, GenderChanged) DEFINE_ACTION_FUNCTION(DPlayerMenu, SwitchOnPickupChanged) { - PARAM_SELF_PROLOGUE(DListMenu); + PARAM_SELF_PROLOGUE(DMenu); PARAM_INT(v); // only allow if the menu is active to prevent abuse. if (self == DMenu::CurrentMenu) @@ -246,7 +246,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, SwitchOnPickupChanged) DEFINE_ACTION_FUNCTION(DPlayerMenu, AlwaysRunChanged) { - PARAM_SELF_PROLOGUE(DListMenu); + PARAM_SELF_PROLOGUE(DMenu); PARAM_INT(v); // only allow if the menu is active to prevent abuse. if (self == DMenu::CurrentMenu) diff --git a/wadsrc/static/zscript/menu/listmenu.txt b/wadsrc/static/zscript/menu/listmenu.txt index d920dc26c..2aacbb94c 100644 --- a/wadsrc/static/zscript/menu/listmenu.txt +++ b/wadsrc/static/zscript/menu/listmenu.txt @@ -76,6 +76,12 @@ class ListMenu : Menu native } } + //============================================================================= + // + // + // + //============================================================================= + MenuItemBase GetItem(Name name) { for(int i = 0; i < mDesc.mItems.Size(); i++) @@ -86,12 +92,173 @@ class ListMenu : Menu native return NULL; } - //bool Responder (InputEventData ev); - //bool MenuEvent (int mkey, bool fromcontroller); - //bool MouseEvent(int type, int x, int y); - //void Ticker (); - //void Drawer (); + + //============================================================================= + // + // + // + //============================================================================= + + override bool Responder (InputEventData ev) + { + if (ev.type == InputEventData.GUI_Event) + { + if (ev.subtype == InputEventData.GUI_KeyDown) + { + // tolower + int ch = ev.data1; + ch = ch >= 65 && ch <91? ch + 32 : ch; + + for(int i = mDesc.mSelectedItem + 1; i < mDesc.mItems.Size(); i++) + { + if (mDesc.mItems[i].CheckHotkey(ch)) + { + mDesc.mSelectedItem = i; + MenuSound("menu/cursor"); + return true; + } + } + for(int i = 0; i < mDesc.mSelectedItem; i++) + { + if (mDesc.mItems[i].CheckHotkey(ch)) + { + mDesc.mSelectedItem = i; + MenuSound("menu/cursor"); + return true; + } + } + } + } + return Super.Responder(ev); + } + + //============================================================================= + // + // + // + //============================================================================= + + override bool MenuEvent (int mkey, bool fromcontroller) + { + int oldSelect = mDesc.mSelectedItem; + int startedAt = mDesc.mSelectedItem; + if (startedAt < 0) startedAt = 0; + + switch (mkey) + { + case MKEY_Up: + do + { + if (--mDesc.mSelectedItem < 0) mDesc.mSelectedItem = mDesc.mItems.Size()-1; + } + while (!mDesc.mItems[mDesc.mSelectedItem].Selectable() && mDesc.mSelectedItem != startedAt); + if (mDesc.mSelectedItem == startedAt) mDesc.mSelectedItem = oldSelect; + MenuSound("menu/cursor"); + return true; + + case MKEY_Down: + do + { + if (++mDesc.mSelectedItem >= mDesc.mItems.Size()) mDesc.mSelectedItem = 0; + } + while (!mDesc.mItems[mDesc.mSelectedItem].Selectable() && mDesc.mSelectedItem != startedAt); + if (mDesc.mSelectedItem == startedAt) mDesc.mSelectedItem = oldSelect; + MenuSound("menu/cursor"); + return true; + + case MKEY_Enter: + if (mDesc.mSelectedItem >= 0 && mDesc.mItems[mDesc.mSelectedItem].Activate()) + { + MenuSound("menu/choose"); + } + return true; + + default: + return Super.MenuEvent(mkey, fromcontroller); + } + } + + //============================================================================= + // + // + // + //============================================================================= + + override bool MouseEvent(int type, int x, int y) + { + int sel = -1; + + // convert x/y from screen to virtual coordinates, according to CleanX/Yfac use in DrawTexture + x = ((x - (screen.GetWidth() / 2)) / CleanXfac) + 160; + y = ((y - (screen.GetHeight() / 2)) / CleanYfac) + 100; + + if (mFocusControl != NULL) + { + mFocusControl.MouseEvent(type, x, y); + return true; + } + else + { + if ((mDesc.mWLeft <= 0 || x > mDesc.mWLeft) && + (mDesc.mWRight <= 0 || x < mDesc.mWRight)) + { + for(int i=0;i= 0 && mDesc.mSelectedItem < mDesc.mItems.Size()) + mDesc.mItems[mDesc.mSelectedItem].DrawSelector(mDesc.mSelectOfsX, mDesc.mSelectOfsY, mDesc.mSelector); + Super.Drawer(); + } + //============================================================================= + // + // + // + //============================================================================= + override void SetFocus(MenuItemBase fc) { mFocusControl = fc; @@ -106,3 +273,4 @@ class ListMenu : Menu native } } + diff --git a/wadsrc/static/zscript/menu/listmenuitems.txt b/wadsrc/static/zscript/menu/listmenuitems.txt index 8920e617b..e3eec6dd1 100644 --- a/wadsrc/static/zscript/menu/listmenuitems.txt +++ b/wadsrc/static/zscript/menu/listmenuitems.txt @@ -52,7 +52,7 @@ class ListMenuItem : MenuItemBase } else { - screen.DrawTexture (tex, mXpos + xofs, mYpos + yofs, DTA_Clean, true); + screen.DrawTexture (tex, true, mXpos + xofs, mYpos + yofs, DTA_Clean, true); } } } From 1b4c9e13b839dfd5ce070c41821f694d7e486d9c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 18 Feb 2017 19:11:53 +0100 Subject: [PATCH 11/22] - cleaned out some cruft from the menu code, now that ListMenu is fully scripted. --- src/CMakeLists.txt | 1 - src/menu/joystickmenu.cpp | 2 +- src/menu/listmenu.cpp | 127 --------------- src/menu/menu.cpp | 150 +----------------- src/menu/menu.h | 48 ------ src/menu/menudef.cpp | 3 +- src/menu/optionmenu.cpp | 28 +--- wadsrc/static/zscript/menu/listmenu.txt | 8 +- wadsrc/static/zscript/menu/menu.txt | 1 - wadsrc/static/zscript/menu/optionmenu.txt | 40 ++++- .../static/zscript/menu/optionmenuitems.txt | 4 +- 11 files changed, 47 insertions(+), 365 deletions(-) delete mode 100644 src/menu/listmenu.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b673b2c20..04f2d0cd9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -845,7 +845,6 @@ set( FASTMATH_PCH_SOURCES intermission/intermission.cpp intermission/intermission_parse.cpp menu/joystickmenu.cpp - menu/listmenu.cpp menu/loadsavemenu.cpp menu/menu.cpp menu/menudef.cpp diff --git a/src/menu/joystickmenu.cpp b/src/menu/joystickmenu.cpp index 9b16b90f4..8813dcaa7 100644 --- a/src/menu/joystickmenu.cpp +++ b/src/menu/joystickmenu.cpp @@ -186,7 +186,7 @@ void UpdateJoystickMenu(IJoystickConfig *selected) { opt->mSelectedItem = opt->mItems.Size() - 1; } - opt->CalcIndent(); + //opt->CalcIndent(); // If the joystick config menu is open, close it if the device it's open for is gone. if (DMenu::CurrentMenu != nullptr && (DMenu::CurrentMenu->IsKindOf("JoystickConfigMenu"))) diff --git a/src/menu/listmenu.cpp b/src/menu/listmenu.cpp deleted file mode 100644 index beaa687f1..000000000 --- a/src/menu/listmenu.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/* -** listmenu.cpp -** A simple menu consisting of a list of items -** -**--------------------------------------------------------------------------- -** Copyright 2010 Christoph Oelckers -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#include "v_video.h" -#include "v_font.h" -#include "cmdlib.h" -#include "gstrings.h" -#include "g_level.h" -#include "gi.h" -#include "d_gui.h" -#include "d_event.h" -#include "menu/menu.h" - -IMPLEMENT_CLASS(DListMenu, false, false) - -IMPLEMENT_POINTERS_START(DListMenu) -IMPLEMENT_POINTER(mFocusControl) -IMPLEMENT_POINTERS_END - -//============================================================================= -// -// -// -//============================================================================= - -DListMenu::DListMenu(DMenu *parent, DListMenuDescriptor *desc) -: DMenu(parent) -{ - mDesc = NULL; - if (desc != NULL) Init(parent, desc); -} - -//============================================================================= -// -// -// -//============================================================================= - -void DListMenu::Init(DMenu *parent, DListMenuDescriptor *desc) -{ - mParentMenu = parent; - GC::WriteBarrier(this, parent); - mDesc = desc; - if (desc->mCenter) - { - int center = 160; - for(unsigned i=0;imItems.Size(); i++) - { - int xpos = mDesc->mItems[i]->GetX(); - int width = mDesc->mItems[i]->GetWidth(); - int curx = mDesc->mSelectOfsX; - - if (width > 0 && mDesc->mItems[i]->Selectable()) - { - int left = 160 - (width - curx) / 2 - curx; - if (left < center) center = left; - } - } - for(unsigned i=0;imItems.Size(); i++) - { - int width = mDesc->mItems[i]->GetWidth(); - - if (width > 0) - { - mDesc->mItems[i]->SetX(center); - } - } - } -} - -//============================================================================= -// -// -// -//============================================================================= - -DMenuItemBase *DListMenu::GetItem(FName name) -{ - for(unsigned i=0;imItems.Size(); i++) - { - FName nm = mDesc->mItems[i]->GetAction(NULL); - if (nm == name) return mDesc->mItems[i]; - } - return NULL; -} - -//============================================================================= -// -// base class for menu items -// -//============================================================================= -IMPLEMENT_CLASS(DMenuItemBase, false, false) - -DEFINE_FIELD(DListMenu, mDesc) -DEFINE_FIELD(DListMenu, mFocusControl) - diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index dc7e02126..e61ac896c 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -444,21 +444,6 @@ DEFINE_ACTION_FUNCTION(DMenu, Close) return 0; } -DEFINE_ACTION_FUNCTION(DMenu, GetItem) -{ - PARAM_SELF_PROLOGUE(DMenu); - PARAM_NAME(name); - ACTION_RETURN_OBJECT(self->GetItem(name)); -} - -DEFINE_ACTION_FUNCTION(DOptionMenuDescriptor, GetItem) -{ - PARAM_SELF_PROLOGUE(DOptionMenuDescriptor); - PARAM_NAME(name); - ACTION_RETURN_OBJECT(self->GetItem(name)); -} - - bool DMenu::DimAllowed() { return true; @@ -1319,41 +1304,6 @@ DMenuItemBase * CreateListMenuItemText(int x, int y, int height, int hotkey, con return (DMenuItemBase*)p; } -bool DMenuItemBase::CheckCoordinate(int x, int y) -{ - IFVIRTUAL(DMenuItemBase, CheckCoordinate) - { - VMValue params[] = { (DObject*)this, x, y }; - int retval; - VMReturn ret(&retval); - GlobalVMStack.Call(func, params, countof(params), &ret, 1, nullptr); - return !!retval; - } - return false; -} - -void DMenuItemBase::Ticker() -{ - IFVIRTUAL(DMenuItemBase, Ticker) - { - VMValue params[] = { (DObject*)this }; - GlobalVMStack.Call(func, params, countof(params), nullptr, 0, nullptr); - } -} - -bool DMenuItemBase::Selectable() -{ - IFVIRTUAL(DMenuItemBase, Selectable) - { - VMValue params[] = { (DObject*)this }; - int retval; - VMReturn ret(&retval); - GlobalVMStack.Call(func, params, countof(params), &ret, 1, nullptr); - return !!retval; - } - return false; -} - bool DMenuItemBase::Activate() { IFVIRTUAL(DMenuItemBase, Activate) @@ -1366,18 +1316,6 @@ bool DMenuItemBase::Activate() } return false; } -FName DMenuItemBase::GetAction(int *pparam) -{ - IFVIRTUAL(DMenuItemBase, GetAction) - { - VMValue params[] = { (DObject*)this }; - int retval[2]; - VMReturn ret[2]; ret[0].IntAt(&retval[0]); ret[1].IntAt(&retval[1]); - GlobalVMStack.Call(func, params, countof(params), ret, 2, nullptr); - return ENamedName(retval[0]); - } - return NAME_None; -} bool DMenuItemBase::SetString(int i, const char *s) { @@ -1435,90 +1373,4 @@ bool DMenuItemBase::GetValue(int i, int *pvalue) return false; } - -void DMenuItemBase::Enable(bool on) -{ - IFVIRTUAL(DMenuItemBase, Enable) - { - VMValue params[] = { (DObject*)this, on }; - GlobalVMStack.Call(func, params, countof(params), nullptr, 0, nullptr); - } -} - -bool DMenuItemBase::MenuEvent(int mkey, bool fromcontroller) -{ - IFVIRTUAL(DMenuItemBase, MenuEvent) - { - VMValue params[] = { (DObject*)this, mkey, fromcontroller }; - int retval; - VMReturn ret(&retval); - GlobalVMStack.Call(func, params, countof(params), &ret, 1, nullptr); - return !!retval; - } - return false; -} - -bool DMenuItemBase::MouseEvent(int type, int x, int y) -{ - IFVIRTUAL(DMenuItemBase, MouseEvent) - { - VMValue params[] = { (DObject*)this, type, x, y }; - int retval; - VMReturn ret(&retval); - GlobalVMStack.Call(func, params, countof(params), &ret, 1, nullptr); - return !!retval; - } - return false; -} - -bool DMenuItemBase::CheckHotkey(int c) -{ - IFVIRTUAL(DMenuItemBase, CheckHotkey) - { - VMValue params[] = { (DObject*)this, c }; - int retval; - VMReturn ret(&retval); - GlobalVMStack.Call(func, params, countof(params), &ret, 1, nullptr); - return !!retval; - } - return false; -} - -int DMenuItemBase::GetWidth() -{ - IFVIRTUAL(DMenuItemBase, GetWidth) - { - VMValue params[] = { (DObject*)this }; - int retval; - VMReturn ret(&retval); - GlobalVMStack.Call(func, params, countof(params), &ret, 1, nullptr); - return retval; - } - return false; -} - -int DMenuItemBase::GetIndent() -{ - IFVIRTUAL(DMenuItemBase, GetIndent) - { - VMValue params[] = { (DObject*)this }; - int retval; - VMReturn ret(&retval); - GlobalVMStack.Call(func, params, countof(params), &ret, 1, nullptr); - return retval; - } - return false; -} - -int DMenuItemBase::Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected) -{ - IFVIRTUAL(DMenuItemBase, Draw) - { - VMValue params[] = { (DObject*)this, desc, y, indent, selected }; - int retval; - VMReturn ret(&retval); - GlobalVMStack.Call(func, params, countof(params), &ret, 1, nullptr); - return retval; - } - return false; -} +IMPLEMENT_CLASS(DMenuItemBase, false, false) diff --git a/src/menu/menu.h b/src/menu/menu.h index e197a62ef..9ca7a6f31 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -286,8 +286,6 @@ public: virtual bool CheckFocus(DMenuItemBase *fc) { return false; } virtual void ReleaseFocus() {} - virtual DMenuItemBase *GetItem(FName name) { return nullptr; } - bool CallResponder(event_t *ev); bool CallMenuEvent(int mkey, bool fromcontroller); bool CallMouseEvent(int type, int x, int y); @@ -317,61 +315,15 @@ public: FNameNoInit mAction; bool mEnabled; - bool CheckCoordinate(int x, int y); - void Ticker(); - bool Selectable(); bool Activate(); - FName GetAction(int *pparam); bool SetString(int i, const char *s); bool GetString(int i, char *s, int len); bool SetValue(int i, int value); bool GetValue(int i, int *pvalue); - void Enable(bool on); - bool MenuEvent (int mkey, bool fromcontroller); - bool MouseEvent(int type, int x, int y); - bool CheckHotkey(int c); - int GetWidth(); - int GetIndent(); - int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected); void OffsetPositionY(int ydelta) { mYpos += ydelta; } int GetY() { return mYpos; } - int GetX() { return mXpos; } - void SetX(int x) { mXpos = x; } }; -//============================================================================= -// -// list menu class runs a menu described by a DListMenuDescriptor -// -//============================================================================= - -class DListMenu : public DMenu -{ - DECLARE_CLASS(DListMenu, DMenu) - HAS_OBJECT_POINTERS; -public: - - DListMenuDescriptor *mDesc; - DMenuItemBase *mFocusControl; - - DListMenu(DMenu *parent = NULL, DListMenuDescriptor *desc = NULL); - virtual void Init(DMenu *parent = NULL, DListMenuDescriptor *desc = NULL); - DMenuItemBase *GetItem(FName name); - void SetFocus(DMenuItemBase *fc) - { - mFocusControl = fc; - } - bool CheckFocus(DMenuItemBase *fc) - { - return mFocusControl == fc; - } - void ReleaseFocus() - { - mFocusControl = NULL; - } -}; - - //============================================================================= // // diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index 252533091..2f5c2603d 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -868,7 +868,6 @@ static void ParseOptionMenu(FScanner &sc) ParseOptionMenuBody(sc, desc); ReplaceMenu(sc, desc); - if (desc->mIndent == 0) desc->CalcIndent(); } @@ -1340,7 +1339,7 @@ void M_StartupSkillMenu(FGameStartup *gs) // Delete previous contents for(unsigned i=0; imItems.Size(); i++) { - FName n = ld->mItems[i]->GetAction(nullptr); + FName n = ld->mItems[i]->mAction; if (n == NAME_Startgame || n == NAME_StartgameConfirm) { ld->mItems.Resize(i); diff --git a/src/menu/optionmenu.cpp b/src/menu/optionmenu.cpp index acbb3c58e..87f0adcf1 100644 --- a/src/menu/optionmenu.cpp +++ b/src/menu/optionmenu.cpp @@ -49,32 +49,6 @@ #include "menu/menu.h" -//============================================================================= -// -// -// -//============================================================================= - -void DOptionMenuDescriptor::CalcIndent() -{ - // calculate the menu indent - int widest = 0, thiswidth; - - for (unsigned i = 0; i < mItems.Size(); i++) - { - thiswidth = mItems[i]->GetIndent(); - if (thiswidth > widest) widest = thiswidth; - } - mIndent = widest + 4; -} - -DEFINE_ACTION_FUNCTION(DOptionMenuDescriptor, CalcIndent) -{ - PARAM_SELF_PROLOGUE(DOptionMenuDescriptor); - self->CalcIndent(); - return 0; -} - //============================================================================= // // @@ -85,7 +59,7 @@ DMenuItemBase *DOptionMenuDescriptor::GetItem(FName name) { for(unsigned i=0;iGetAction(NULL); + FName nm = mItems[i]->mAction; if (nm == name) return mItems[i]; } return NULL; diff --git a/wadsrc/static/zscript/menu/listmenu.txt b/wadsrc/static/zscript/menu/listmenu.txt index 2aacbb94c..db1a4a19c 100644 --- a/wadsrc/static/zscript/menu/listmenu.txt +++ b/wadsrc/static/zscript/menu/listmenu.txt @@ -40,10 +40,10 @@ class ListMenuDescriptor : MenuDescriptor native // //============================================================================= -class ListMenu : Menu native +class ListMenu : Menu { - native ListMenuDescriptor mDesc; - native MenuItemBase mFocusControl; + ListMenuDescriptor mDesc; + MenuItemBase mFocusControl; virtual void Init(Menu parent = NULL, ListMenuDescriptor desc = NULL) { @@ -82,7 +82,7 @@ class ListMenu : Menu native // //============================================================================= - MenuItemBase GetItem(Name name) + ListMenuItem GetItem(Name name) { for(int i = 0; i < mDesc.mItems.Size(); i++) { diff --git a/wadsrc/static/zscript/menu/menu.txt b/wadsrc/static/zscript/menu/menu.txt index 1640e9d35..103d75104 100644 --- a/wadsrc/static/zscript/menu/menu.txt +++ b/wadsrc/static/zscript/menu/menu.txt @@ -111,7 +111,6 @@ class Menu : Object native native virtual void Ticker(); native virtual void Drawer(); native void Close(); - native MenuItemBase GetItem(Name n); native void ActivateMenu(); static void MenuSound(Sound snd) diff --git a/wadsrc/static/zscript/menu/optionmenu.txt b/wadsrc/static/zscript/menu/optionmenu.txt index 5b06f3020..c6f0247a7 100644 --- a/wadsrc/static/zscript/menu/optionmenu.txt +++ b/wadsrc/static/zscript/menu/optionmenu.txt @@ -56,8 +56,6 @@ class OptionMenuDescriptor : MenuDescriptor native native int mPosition; native bool mDontDim; - native void CalcIndent(); - native OptionMenuItem GetItem(Name iname); void Reset() { // Reset the default settings (ignore all other values in the struct) @@ -66,6 +64,25 @@ class OptionMenuDescriptor : MenuDescriptor native mIndent = 0; mDontDim = 0; } + + //============================================================================= + // + // + // + //============================================================================= + + void CalcIndent() + { + // calculate the menu indent + int widest = 0, thiswidth; + + for (int i = 0; i < mItems.Size(); i++) + { + thiswidth = mItems[i].GetIndent(); + if (thiswidth > widest) widest = thiswidth; + } + mIndent = widest + 4; + } } @@ -88,10 +105,27 @@ class OptionMenu : Menu mParentMenu = parent; mDesc = desc; if (mDesc != NULL && mDesc.mSelectedItem == -1) mDesc.mSelectedItem = FirstSelectable(); - + mDesc.CalcIndent(); } + //============================================================================= + // + // + // + //============================================================================= + + OptionMenuItem GetItem(Name name) + { + for(int i = 0; i < mDesc.mItems.Size(); i++) + { + Name nm = mDesc.mItems[i].GetAction(); + if (nm == name) return mDesc.mItems[i]; + } + return NULL; + } + + //============================================================================= // // diff --git a/wadsrc/static/zscript/menu/optionmenuitems.txt b/wadsrc/static/zscript/menu/optionmenuitems.txt index 4d61edcd0..9ac308372 100644 --- a/wadsrc/static/zscript/menu/optionmenuitems.txt +++ b/wadsrc/static/zscript/menu/optionmenuitems.txt @@ -136,7 +136,7 @@ class OptionMenuItemCommand : OptionMenuItemSubmenu // don't execute if no menu is active if (m == null) return false; // don't execute if this item cannot be found in the current menu. - if (m.mDesc.GetItem(mAction) != self) return false; + if (m.GetItem(mAction) != self) return false; Menu.MenuSound("menu/choose"); DoCommand(mAction); return true; @@ -388,7 +388,7 @@ class EnterKey : Menu let parent = OptionMenu(mParentMenu); if (parent != null) { - let it = parent.mDesc.GetItem('Controlmessage'); + let it = parent.GetItem('Controlmessage'); if (it != null) { it.SetValue(0, which); From 06141338f11c9c6c0212e0de01a026646f3a41a3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 18 Feb 2017 19:19:14 +0100 Subject: [PATCH 12/22] - made DMenu's static variables regular global variables because that class is going to go completely scripted soon. --- src/c_cvars.cpp | 6 ++-- src/c_dispatch.cpp | 2 +- src/menu/joystickmenu.cpp | 6 ++-- src/menu/menu.cpp | 76 +++++++++++++++++++-------------------- src/menu/menu.h | 6 ++-- src/menu/menudef.cpp | 2 +- src/menu/messagebox.cpp | 18 +++++----- src/menu/playermenu.cpp | 20 +++++------ src/p_conversation.cpp | 12 +++---- 9 files changed, 74 insertions(+), 74 deletions(-) diff --git a/src/c_cvars.cpp b/src/c_cvars.cpp index cd48e304e..6430d95ad 100644 --- a/src/c_cvars.cpp +++ b/src/c_cvars.cpp @@ -207,7 +207,7 @@ DEFINE_ACTION_FUNCTION(_CVar, SetInt) { // Only menus are allowed to change CVARs. PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar); - if (!(self->GetFlags() & CVAR_MOD) && DMenu::CurrentMenu == nullptr) return 0; + if (!(self->GetFlags() & CVAR_MOD) && CurrentMenu == nullptr) return 0; PARAM_INT(val); UCVarValue v; v.Int = val; @@ -219,7 +219,7 @@ DEFINE_ACTION_FUNCTION(_CVar, SetFloat) { // Only menus are allowed to change CVARs. PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar); - if (!(self->GetFlags() & CVAR_MOD) && DMenu::CurrentMenu == nullptr) return 0; + if (!(self->GetFlags() & CVAR_MOD) && CurrentMenu == nullptr) return 0; PARAM_FLOAT(val); UCVarValue v; v.Float = (float)val; @@ -231,7 +231,7 @@ DEFINE_ACTION_FUNCTION(_CVar, SetString) { // Only menus are allowed to change CVARs. PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar); - if (!(self->GetFlags() & CVAR_MOD) && DMenu::CurrentMenu == nullptr) return 0; + if (!(self->GetFlags() & CVAR_MOD) && CurrentMenu == nullptr) return 0; PARAM_STRING(val); UCVarValue v; v.String = val.GetChars(); diff --git a/src/c_dispatch.cpp b/src/c_dispatch.cpp index 343903495..184f33adb 100644 --- a/src/c_dispatch.cpp +++ b/src/c_dispatch.cpp @@ -666,7 +666,7 @@ void C_DoCommand (const char *cmd, int keynum) // This is only accessible to the special menu item to run CCMDs. DEFINE_ACTION_FUNCTION(DOptionMenuItemCommand, DoCommand) { - if (DMenu::CurrentMenu == nullptr) return 0; + if (CurrentMenu == nullptr) return 0; PARAM_PROLOGUE; PARAM_STRING(cmd); C_DoCommand(cmd); diff --git a/src/menu/joystickmenu.cpp b/src/menu/joystickmenu.cpp index 8813dcaa7..59b3ad990 100644 --- a/src/menu/joystickmenu.cpp +++ b/src/menu/joystickmenu.cpp @@ -189,9 +189,9 @@ void UpdateJoystickMenu(IJoystickConfig *selected) //opt->CalcIndent(); // If the joystick config menu is open, close it if the device it's open for is gone. - if (DMenu::CurrentMenu != nullptr && (DMenu::CurrentMenu->IsKindOf("JoystickConfigMenu"))) + if (CurrentMenu != nullptr && (CurrentMenu->IsKindOf("JoystickConfigMenu"))) { - auto p = DMenu::CurrentMenu->PointerVar("mJoy"); + auto p = CurrentMenu->PointerVar("mJoy"); if (p != nullptr) { unsigned i; @@ -204,7 +204,7 @@ void UpdateJoystickMenu(IJoystickConfig *selected) } if (i == Joysticks.Size()) { - DMenu::CurrentMenu->Close(); + CurrentMenu->Close(); } } } diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index e61ac896c..57a609b06 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -69,18 +69,16 @@ CVAR (Float, snd_menuvolume, 0.6f, CVAR_ARCHIVE) CVAR(Int, m_use_mouse, 2, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR(Int, m_show_backbutton, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -DMenu *DMenu::CurrentMenu; DEFINE_ACTION_FUNCTION(DMenu, GetCurrentMenu) { - ACTION_RETURN_OBJECT(DMenu::CurrentMenu); + ACTION_RETURN_OBJECT(CurrentMenu); } -int DMenu::MenuTime; DEFINE_ACTION_FUNCTION(DMenu, MenuTime) { - ACTION_RETURN_INT(DMenu::MenuTime); + ACTION_RETURN_INT(MenuTime); } FGameStartup GameStartupInfo; @@ -92,6 +90,8 @@ bool MenuButtonOrigin[NUM_MKEYS]; int BackbuttonTime; float BackbuttonAlpha; static bool MenuEnabled = true; +DMenu *CurrentMenu; +int MenuTime; void M_InitVideoModes(); extern PClass *DefaultListMenuClass; @@ -140,7 +140,7 @@ void M_MarkMenus() { GC::Mark(pair->Value); } - GC::Mark(DMenu::CurrentMenu); + GC::Mark(CurrentMenu); } //============================================================================ // @@ -237,7 +237,7 @@ bool DMenu::MenuEvent (int mkey, bool fromcontroller) { Close(); S_Sound (CHAN_VOICE | CHAN_UI, - DMenu::CurrentMenu != nullptr? "menu/backup" : "menu/clear", snd_menuvolume, ATTN_NONE); + CurrentMenu != nullptr? "menu/backup" : "menu/clear", snd_menuvolume, ATTN_NONE); return true; } } @@ -272,13 +272,13 @@ bool DMenu::CallMenuEvent(int mkey, bool fromcontroller) void DMenu::Close () { - if (DMenu::CurrentMenu == nullptr) return; // double closing can happen in the save menu. - assert(DMenu::CurrentMenu == this); - DMenu::CurrentMenu = mParentMenu; + if (CurrentMenu == nullptr) return; // double closing can happen in the save menu. + assert(CurrentMenu == this); + CurrentMenu = mParentMenu; Destroy(); - if (DMenu::CurrentMenu != nullptr) + if (CurrentMenu != nullptr) { - GC::WriteBarrier(DMenu::CurrentMenu); + GC::WriteBarrier(CurrentMenu); } else { @@ -401,7 +401,7 @@ void DMenu::CallTicker() void DMenu::Drawer () { - if (this == DMenu::CurrentMenu && BackbuttonAlpha > 0 && m_show_backbutton >= 0 && m_use_mouse) + if (this == CurrentMenu && BackbuttonAlpha > 0 && m_show_backbutton >= 0 && m_use_mouse) { FTexture *tex = TexMan(gameinfo.mBackButton); int w = tex->GetScaledWidth() * CleanXfac; @@ -471,7 +471,7 @@ bool DMenu::TranslateKeyboardEvents() void M_StartControlPanel (bool makeSound) { // intro might call this repeatedly - if (DMenu::CurrentMenu != nullptr) + if (CurrentMenu != nullptr) return; ResetButtonStates (); @@ -503,9 +503,9 @@ void M_StartControlPanel (bool makeSound) void M_ActivateMenu(DMenu *menu) { if (menuactive == MENU_Off) menuactive = MENU_On; - if (DMenu::CurrentMenu != nullptr) DMenu::CurrentMenu->ReleaseCapture(); - DMenu::CurrentMenu = menu; - GC::WriteBarrier(DMenu::CurrentMenu); + if (CurrentMenu != nullptr) CurrentMenu->ReleaseCapture(); + CurrentMenu = menu; + GC::WriteBarrier(CurrentMenu); } DEFINE_ACTION_FUNCTION(DMenu, ActivateMenu) @@ -617,7 +617,7 @@ void M_SetMenu(FName menu, int param) DMenu *newmenu = (DMenu *)cls->CreateNew(); IFVIRTUALPTRNAME(newmenu, "ListMenu", Init) { - VMValue params[3] = { newmenu, DMenu::CurrentMenu, ld }; + VMValue params[3] = { newmenu, CurrentMenu, ld }; GlobalVMStack.Call(func, params, 3, nullptr, 0); } M_ActivateMenu(newmenu); @@ -633,7 +633,7 @@ void M_SetMenu(FName menu, int param) DMenu *newmenu = (DMenu*)cls->CreateNew(); IFVIRTUALPTRNAME(newmenu, "OptionMenu", Init) { - VMValue params[3] = { newmenu, DMenu::CurrentMenu, ld }; + VMValue params[3] = { newmenu, CurrentMenu, ld }; GlobalVMStack.Call(func, params, 3, nullptr, 0); } M_ActivateMenu(newmenu); @@ -648,7 +648,7 @@ void M_SetMenu(FName menu, int param) if (menuclass->IsDescendantOf(RUNTIME_CLASS(DMenu))) { DMenu *newmenu = (DMenu*)menuclass->CreateNew(); - newmenu->mParentMenu = DMenu::CurrentMenu; + newmenu->mParentMenu = CurrentMenu; M_ActivateMenu(newmenu); return; } @@ -684,7 +684,7 @@ bool M_Responder (event_t *ev) return false; } - if (DMenu::CurrentMenu != nullptr && menuactive != MENU_Off) + if (CurrentMenu != nullptr && menuactive != MENU_Off) { // There are a few input sources we are interested in: // @@ -719,9 +719,9 @@ bool M_Responder (event_t *ev) } // pass everything else on to the current menu - return DMenu::CurrentMenu->CallResponder(ev); + return CurrentMenu->CallResponder(ev); } - else if (DMenu::CurrentMenu->TranslateKeyboardEvents()) + else if (CurrentMenu->TranslateKeyboardEvents()) { ch = ev->data1; keyup = ev->subtype == EV_GUI_KeyUp; @@ -740,7 +740,7 @@ bool M_Responder (event_t *ev) default: if (!keyup) { - return DMenu::CurrentMenu->CallResponder(ev); + return CurrentMenu->CallResponder(ev); } break; } @@ -823,11 +823,11 @@ bool M_Responder (event_t *ev) { MenuButtonTickers[mkey] = KEY_REPEAT_DELAY; } - DMenu::CurrentMenu->CallMenuEvent(mkey, fromcontroller); + CurrentMenu->CallMenuEvent(mkey, fromcontroller); return true; } } - return DMenu::CurrentMenu->CallResponder(ev) || !keyup; + return CurrentMenu->CallResponder(ev) || !keyup; } else if (MenuEnabled) { @@ -868,10 +868,10 @@ bool M_Responder (event_t *ev) void M_Ticker (void) { - DMenu::MenuTime++; - if (DMenu::CurrentMenu != nullptr && menuactive != MENU_Off) + MenuTime++; + if (CurrentMenu != nullptr && menuactive != MENU_Off) { - DMenu::CurrentMenu->CallTicker(); + CurrentMenu->CallTicker(); for (int i = 0; i < NUM_MKEYS; ++i) { @@ -880,7 +880,7 @@ void M_Ticker (void) if (MenuButtonTickers[i] > 0 && --MenuButtonTickers[i] <= 0) { MenuButtonTickers[i] = KEY_REPEAT_RATE; - DMenu::CurrentMenu->CallMenuEvent(i, MenuButtonOrigin[i]); + CurrentMenu->CallMenuEvent(i, MenuButtonOrigin[i]); } } } @@ -920,14 +920,14 @@ void M_Drawer (void) } - if (DMenu::CurrentMenu != nullptr && menuactive != MENU_Off) + if (CurrentMenu != nullptr && menuactive != MENU_Off) { - if (DMenu::CurrentMenu->DimAllowed()) + if (CurrentMenu->DimAllowed()) { screen->Dim(fade); V_SetBorderNeedRefresh(); } - DMenu::CurrentMenu->CallDrawer(); + CurrentMenu->CallDrawer(); } } @@ -940,10 +940,10 @@ void M_Drawer (void) void M_ClearMenus () { M_DemoNoPlay = false; - if (DMenu::CurrentMenu != nullptr) + if (CurrentMenu != nullptr) { - DMenu::CurrentMenu->Destroy(); - DMenu::CurrentMenu = nullptr; + CurrentMenu->Destroy(); + CurrentMenu = nullptr; } V_SetBorderNeedRefresh(); menuactive = MENU_Off; @@ -1181,11 +1181,11 @@ CCMD(reset2saved) // This really should be in the script but we can't do scripted CCMDs yet. CCMD(undocolorpic) { - if (DMenu::CurrentMenu != NULL) + if (CurrentMenu != NULL) { - IFVIRTUALPTR(DMenu::CurrentMenu, DMenu, ResetColor) + IFVIRTUALPTR(CurrentMenu, DMenu, ResetColor) { - VMValue params[] = { (DObject*)DMenu::CurrentMenu }; + VMValue params[] = { (DObject*)CurrentMenu }; GlobalVMStack.Call(func, params, countof(params), nullptr, 0, nullptr); } } diff --git a/src/menu/menu.h b/src/menu/menu.h index 9ca7a6f31..fba754113 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -107,6 +107,9 @@ public: }; extern FSavegameManager savegameManager; +class DMenu; +extern DMenu *CurrentMenu; +extern int MenuTime; //============================================================================= // @@ -267,9 +270,6 @@ public: BACKBUTTON_TIME = 4*TICRATE }; - static DMenu *CurrentMenu; - static int MenuTime; - TObjPtr mParentMenu; DMenu(DMenu *parent = NULL); diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index 2f5c2603d..f9ecbd808 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -147,7 +147,7 @@ static void DeinitMenus() } MenuDescriptors.Clear(); OptionValues.Clear(); - DMenu::CurrentMenu = nullptr; + CurrentMenu = nullptr; savegameManager.ClearSaveGames(); } diff --git a/src/menu/messagebox.cpp b/src/menu/messagebox.cpp index b1d602555..af2cb9b3d 100644 --- a/src/menu/messagebox.cpp +++ b/src/menu/messagebox.cpp @@ -139,7 +139,7 @@ void DMessageBoxMenu::OnDestroy() void DMessageBoxMenu::CloseSound() { S_Sound (CHAN_VOICE | CHAN_UI, - DMenu::CurrentMenu != NULL? "menu/backup" : "menu/dismiss", snd_menuvolume, ATTN_NONE); + CurrentMenu != NULL? "menu/backup" : "menu/dismiss", snd_menuvolume, ATTN_NONE); } //============================================================================= @@ -212,7 +212,7 @@ void DMessageBoxMenu::Drawer () if (messageSelection >= 0) { - if ((DMenu::MenuTime%8) < 6) + if ((MenuTime%8) < 6) { screen->DrawText(ConFont, OptionSettings.mFontColorSelection, (150 - 160) * CleanXfac + screen->GetWidth() / 2, @@ -431,7 +431,7 @@ CCMD (menu_quit) { // F10 M_StartControlPanel (true); DMenu *newmenu = new DQuitMenu(false); - newmenu->mParentMenu = DMenu::CurrentMenu; + newmenu->mParentMenu = CurrentMenu; M_ActivateMenu(newmenu); } @@ -511,7 +511,7 @@ CCMD (menu_endgame) //M_StartControlPanel (true); S_Sound (CHAN_VOICE | CHAN_UI, "menu/activate", snd_menuvolume, ATTN_NONE); DMenu *newmenu = new DEndGameMenu(false); - newmenu->mParentMenu = DMenu::CurrentMenu; + newmenu->mParentMenu = CurrentMenu; M_ActivateMenu(newmenu); } @@ -607,7 +607,7 @@ CCMD (quicksave) S_Sound(CHAN_VOICE | CHAN_UI, "menu/activate", snd_menuvolume, ATTN_NONE); DMenu *newmenu = new DQuickSaveMenu(false); - newmenu->mParentMenu = DMenu::CurrentMenu; + newmenu->mParentMenu = CurrentMenu; M_ActivateMenu(newmenu); } @@ -702,7 +702,7 @@ CCMD (quickload) M_StartControlPanel(true); DMenu *newmenu = new DQuickLoadMenu(false); - newmenu->mParentMenu = DMenu::CurrentMenu; + newmenu->mParentMenu = CurrentMenu; M_ActivateMenu(newmenu); } @@ -714,13 +714,13 @@ CCMD (quickload) void M_StartMessage(const char *message, int messagemode, FName action) { - if (DMenu::CurrentMenu == NULL) + if (CurrentMenu == NULL) { // only play a sound if no menu was active before M_StartControlPanel(menuactive == MENU_Off); } - DMenu *newmenu = new DMessageBoxMenu(DMenu::CurrentMenu, message, messagemode, false, action); - newmenu->mParentMenu = DMenu::CurrentMenu; + DMenu *newmenu = new DMessageBoxMenu(CurrentMenu, message, messagemode, false, action); + newmenu->mParentMenu = CurrentMenu; M_ActivateMenu(newmenu); } diff --git a/src/menu/playermenu.cpp b/src/menu/playermenu.cpp index c900cc4a7..c730f2d81 100644 --- a/src/menu/playermenu.cpp +++ b/src/menu/playermenu.cpp @@ -66,7 +66,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, ColorChanged) PARAM_INT(g); PARAM_INT(b); // only allow if the menu is active to prevent abuse. - if (self == DMenu::CurrentMenu) + if (self == CurrentMenu) { char command[24]; players[consoleplayer].userinfo.ColorChanged(MAKERGB(r, g, b)); @@ -91,7 +91,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, PlayerNameChanged) const char *pp = s; FString command("name \""); - if (self == DMenu::CurrentMenu) + if (self == CurrentMenu) { // Escape any backslashes or quotation marks before sending the name to the console. for (auto p = pp; *p != '\0'; ++p) @@ -118,7 +118,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, ColorSetChanged) { PARAM_SELF_PROLOGUE(DMenu); PARAM_INT(sel); - if (self == DMenu::CurrentMenu) + if (self == CurrentMenu) { players[consoleplayer].userinfo.ColorSetChanged(sel); char command[24]; @@ -139,7 +139,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, ClassChanged) PARAM_SELF_PROLOGUE(DMenu); PARAM_INT(sel); PARAM_POINTER(cls, FPlayerClass); - if (self == DMenu::CurrentMenu) + if (self == CurrentMenu) { players[consoleplayer].userinfo.PlayerClassNumChanged(gameinfo.norandomplayerclass ? sel : sel - 1); cvar_set("playerclass", sel == 0 && !gameinfo.norandomplayerclass ? "Random" : GetPrintableDisplayName(cls->Type).GetChars()); @@ -158,7 +158,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, SkinChanged) { PARAM_SELF_PROLOGUE(DMenu); PARAM_INT(sel); - if (self == DMenu::CurrentMenu) + if (self == CurrentMenu) { players[consoleplayer].userinfo.SkinNumChanged(sel); cvar_set("skin", Skins[sel].Name); @@ -177,7 +177,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, AutoaimChanged) PARAM_SELF_PROLOGUE(DMenu); PARAM_FLOAT(val); // only allow if the menu is active to prevent abuse. - if (self == DMenu::CurrentMenu) + if (self == CurrentMenu) { autoaim = float(val); } @@ -195,7 +195,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, TeamChanged) PARAM_SELF_PROLOGUE(DMenu); PARAM_INT(val); // only allow if the menu is active to prevent abuse. - if (self == DMenu::CurrentMenu) + if (self == CurrentMenu) { team = val == 0 ? TEAM_NONE : val - 1; } @@ -213,7 +213,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, GenderChanged) PARAM_SELF_PROLOGUE(DMenu); PARAM_INT(v); // only allow if the menu is active to prevent abuse. - if (self == DMenu::CurrentMenu) + if (self == CurrentMenu) { cvar_set("gender", v == 0 ? "male" : v == 1 ? "female" : "other"); } @@ -231,7 +231,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, SwitchOnPickupChanged) PARAM_SELF_PROLOGUE(DMenu); PARAM_INT(v); // only allow if the menu is active to prevent abuse. - if (self == DMenu::CurrentMenu) + if (self == CurrentMenu) { neverswitchonpickup = !!v; } @@ -249,7 +249,7 @@ DEFINE_ACTION_FUNCTION(DPlayerMenu, AlwaysRunChanged) PARAM_SELF_PROLOGUE(DMenu); PARAM_INT(v); // only allow if the menu is active to prevent abuse. - if (self == DMenu::CurrentMenu) + if (self == CurrentMenu) { cl_run = !!v; } diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index 54be79e3c..0133ca961 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -1097,7 +1097,7 @@ public: if (response == mSelection+1) { - int color = ((DMenu::MenuTime%8) < 4) || DMenu::CurrentMenu != this ? CR_RED:CR_GREY; + int color = ((MenuTime%8) < 4) || CurrentMenu != this ? CR_RED:CR_GREY; x = (50 + 3 - 160) * CleanXfac + screen->GetWidth() / 2; int yy = (y + fontheight/2 - 5 - 100) * CleanYfac + screen->GetHeight() / 2; @@ -1135,9 +1135,9 @@ void P_FreeStrifeConversations () ClassRoots.Clear(); PrevNode = NULL; - if (DMenu::CurrentMenu != NULL && DMenu::CurrentMenu->IsKindOf(RUNTIME_CLASS(DConversationMenu))) + if (CurrentMenu != NULL && CurrentMenu->IsKindOf(RUNTIME_CLASS(DConversationMenu))) { - DMenu::CurrentMenu->Close(); + CurrentMenu->Close(); } } @@ -1482,10 +1482,10 @@ void P_ConversationCommand (int netcode, int pnum, BYTE **stream) // The conversation menus are normally closed by the menu code, but that // doesn't happen during demo playback, so we need to do it here. - if (demoplayback && DMenu::CurrentMenu != NULL && - DMenu::CurrentMenu->IsKindOf(RUNTIME_CLASS(DConversationMenu))) + if (demoplayback && CurrentMenu != NULL && + CurrentMenu->IsKindOf(RUNTIME_CLASS(DConversationMenu))) { - DMenu::CurrentMenu->Close(); + CurrentMenu->Close(); } if (netcode == DEM_CONVREPLY) { From 0c41a9dee7e9c2f3068540f49b2cd261a904ef0d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 18 Feb 2017 20:12:06 +0100 Subject: [PATCH 13/22] - scriptified DTextEnterMenu::Drawer. --- src/menu/menu.h | 2 - src/menu/menuinput.cpp | 115 ++----------------- src/v_video.cpp | 14 +++ wadsrc/static/zscript/base.txt | 1 + wadsrc/static/zscript/menu/textentermenu.txt | 91 ++++++++++++++- 5 files changed, 113 insertions(+), 110 deletions(-) diff --git a/src/menu/menu.h b/src/menu/menu.h index fba754113..3924ab869 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -373,11 +373,9 @@ public: // [TP] Added allowcolors DTextEnterMenu(DMenu *parent, const char *textbuffer, int maxlen, int sizemode, bool showgrid, bool allowcolors = false); - void Drawer (); bool MenuEvent (int mkey, bool fromcontroller); bool Responder(event_t *ev); bool MouseEvent(int type, int x, int y); - FString GetText(); }; diff --git a/src/menu/menuinput.cpp b/src/menu/menuinput.cpp index 9a0b717b5..f880fabfd 100644 --- a/src/menu/menuinput.cpp +++ b/src/menu/menuinput.cpp @@ -61,8 +61,6 @@ static const char InputGridChars[INPUTGRID_WIDTH * INPUTGRID_HEIGHT] = CVAR(Bool, m_showinputgrid, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -DEFINE_FIELD(DTextEnterMenu, mInputGridOkay) - //============================================================================= // // @@ -91,24 +89,6 @@ DTextEnterMenu::DTextEnterMenu(DMenu *parent, const char *textbuffer, int maxlen AllowColors = allowcolors; // [TP] } -//============================================================================= -// -// -// -//============================================================================= - -FString DTextEnterMenu::GetText() -{ - return mEnterString; -} - -//============================================================================= -// -// -// -//============================================================================= - - //============================================================================= // // @@ -294,88 +274,6 @@ bool DTextEnterMenu::MenuEvent (int key, bool fromcontroller) return false; } -//============================================================================= -// -// -// -//============================================================================= - -void DTextEnterMenu::Drawer () -{ - mParentMenu->CallDrawer(); - if (mInputGridOkay) - { - const int cell_width = 18 * CleanXfac; - const int cell_height = 12 * CleanYfac; - const int top_padding = cell_height / 2 - SmallFont->GetHeight() * CleanYfac / 2; - - // Darken the background behind the character grid. - // Unless we frame it with a border, I think it looks better to extend the - // background across the full width of the screen. - screen->Dim(0, 0.8f, - 0 /*screen->GetWidth()/2 - 13 * cell_width / 2*/, - screen->GetHeight() - INPUTGRID_HEIGHT * cell_height, - screen->GetWidth() /*13 * cell_width*/, - INPUTGRID_HEIGHT * cell_height); - - if (InputGridX >= 0 && InputGridY >= 0) - { - // Highlight the background behind the selected character. - screen->Dim(MAKERGB(255,248,220), 0.6f, - InputGridX * cell_width - INPUTGRID_WIDTH * cell_width / 2 + screen->GetWidth() / 2, - InputGridY * cell_height - INPUTGRID_HEIGHT * cell_height + screen->GetHeight(), - cell_width, cell_height); - } - - for (int y = 0; y < INPUTGRID_HEIGHT; ++y) - { - const int yy = y * cell_height - INPUTGRID_HEIGHT * cell_height + screen->GetHeight(); - for (int x = 0; x < INPUTGRID_WIDTH; ++x) - { - int width; - const int xx = x * cell_width - INPUTGRID_WIDTH * cell_width / 2 + screen->GetWidth() / 2; - const int ch = InputGridChars[y * INPUTGRID_WIDTH + x]; - FTexture *pic = SmallFont->GetChar(ch, &width); - EColorRange color; - - // The highlighted character is yellow; the rest are dark gray. - color = (x == InputGridX && y == InputGridY) ? CR_YELLOW : CR_DARKGRAY; - - if (pic != NULL) - { - // Draw a normal character. - screen->DrawChar(SmallFont, color, xx + cell_width/2 - width*CleanXfac/2, yy + top_padding, ch, DTA_CleanNoMove, true, TAG_DONE); - } - else if (ch == ' ') - { - FRemapTable *remap = SmallFont->GetColorTranslation(color); - // Draw the space as a box outline. We also draw it 50% wider than it really is. - const int x1 = xx + cell_width/2 - width * CleanXfac * 3 / 4; - const int x2 = x1 + width * 3 * CleanXfac / 2; - const int y1 = yy + top_padding; - const int y2 = y1 + SmallFont->GetHeight() * CleanYfac; - const int palentry = remap->Remap[remap->NumEntries * 2 / 3]; - const uint32 palcolor = remap->Palette[remap->NumEntries * 2 / 3]; - screen->Clear(x1, y1, x2, y1+CleanYfac, palentry, palcolor); // top - screen->Clear(x1, y2, x2, y2+CleanYfac, palentry, palcolor); // bottom - screen->Clear(x1, y1+CleanYfac, x1+CleanXfac, y2, palentry, palcolor); // left - screen->Clear(x2-CleanXfac, y1+CleanYfac, x2, y2, palentry, palcolor); // right - } - else if (ch == '\b' || ch == 0) - { - // Draw the backspace and end "characters". - const char *const str = ch == '\b' ? "BS" : "ED"; - screen->DrawText(SmallFont, color, - xx + cell_width/2 - SmallFont->StringWidth(str)*CleanXfac/2, - yy + top_padding, str, DTA_CleanNoMove, true, TAG_DONE); - } - } - } - } - Super::Drawer(); -} - - DEFINE_ACTION_FUNCTION(DTextEnterMenu, Open) { PARAM_PROLOGUE; @@ -389,8 +287,11 @@ DEFINE_ACTION_FUNCTION(DTextEnterMenu, Open) ACTION_RETURN_OBJECT(m); } -DEFINE_ACTION_FUNCTION(DTextEnterMenu, GetText) -{ - PARAM_SELF_PROLOGUE(DTextEnterMenu); - ACTION_RETURN_STRING(self->GetText()); -} +DEFINE_FIELD(DTextEnterMenu, mEnterString); +DEFINE_FIELD(DTextEnterMenu, mEnterSize); +DEFINE_FIELD(DTextEnterMenu, mEnterPos); +DEFINE_FIELD(DTextEnterMenu, mSizeMode); // 1: size is length in chars. 2: also check string width +DEFINE_FIELD(DTextEnterMenu, mInputGridOkay); +DEFINE_FIELD(DTextEnterMenu, InputGridX); +DEFINE_FIELD(DTextEnterMenu, InputGridY); +DEFINE_FIELD(DTextEnterMenu, AllowColors); diff --git a/src/v_video.cpp b/src/v_video.cpp index 6d5913ce1..aca00cfb3 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -398,6 +398,20 @@ void DCanvas::Dim (PalEntry color, float damount, int x1, int y1, int w, int h) } } +DEFINE_ACTION_FUNCTION(_Screen, Dim) +{ + PARAM_PROLOGUE; + PARAM_INT(color); + PARAM_FLOAT(amount); + PARAM_INT(x1); + PARAM_INT(y1); + PARAM_INT(w); + PARAM_INT(h); + screen->Dim(color, float(amount), x1, y1, w, h); + return 0; +} + + //========================================================================== // // DCanvas :: GetScreenshotBuffer diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 6c5d671de..43d1df05a 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -162,6 +162,7 @@ struct Screen native native static int GetWidth(); native static int GetHeight(); native static void Clear(int left, int top, int right, int bottom, Color color, int palcolor = -1); + native static void Dim(Color col, double amount, int x, int y, int w, int h); native static void DrawHUDTexture(TextureID tex, double x, double y); native static vararg void DrawTexture(TextureID tex, bool animate, double x, double y, ...); diff --git a/wadsrc/static/zscript/menu/textentermenu.txt b/wadsrc/static/zscript/menu/textentermenu.txt index 7974a62bd..c99285145 100644 --- a/wadsrc/static/zscript/menu/textentermenu.txt +++ b/wadsrc/static/zscript/menu/textentermenu.txt @@ -2,14 +2,103 @@ // This is only the parts that are needed to make the menu fully work right now. More to come later. class TextEnterMenu : Menu native { + const INPUTGRID_WIDTH = 13; + const INPUTGRID_HEIGHT = 5; + + const Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-=.,!?@'\":;[]()<>^#$%&*/_ \b"; + + native String mEnterString; + native int mEnterSize; + native int mEnterPos; + native int mSizeMode; // 1: size is length in chars. 2: also check string width native bool mInputGridOkay; + native int InputGridX; + native int InputGridY; + native bool AllowColors; native static TextEnterMenu Open(Menu parent, String text, int maxlen, int sizemode, bool fromcontroller); - native String GetText(); + String GetText() + { + return mEnterString; + } + override bool TranslateKeyboardEvents() { return mInputGridOkay; } + + //============================================================================= + // + // + // + //============================================================================= + + override void Drawer () + { + mParentMenu.Drawer(); + if (mInputGridOkay) + { + String InputGridChars = Chars; + int cell_width = 18 * CleanXfac; + int cell_height = 12 * CleanYfac; + int top_padding = cell_height / 2 - SmallFont.GetHeight() * CleanYfac / 2; + + // Darken the background behind the character grid. + screen.Dim(0, 0.8, 0, screen.GetHeight() - INPUTGRID_HEIGHT * cell_height, screen.GetWidth(), INPUTGRID_HEIGHT * cell_height); + + if (InputGridX >= 0 && InputGridY >= 0) + { + // Highlight the background behind the selected character. + screen.Dim(Color(255,248,220), 0.6, + InputGridX * cell_width - INPUTGRID_WIDTH * cell_width / 2 + screen.GetWidth() / 2, + InputGridY * cell_height - INPUTGRID_HEIGHT * cell_height + screen.GetHeight(), + cell_width, cell_height); + } + + for (int y = 0; y < INPUTGRID_HEIGHT; ++y) + { + int yy = y * cell_height - INPUTGRID_HEIGHT * cell_height + screen.GetHeight(); + for (int x = 0; x < INPUTGRID_WIDTH; ++x) + { + int xx = x * cell_width - INPUTGRID_WIDTH * cell_width / 2 + screen.GetWidth() / 2; + int ch = InputGridChars.CharCodeAt(y * INPUTGRID_WIDTH + x); + int width = SmallFont.GetCharWidth(ch); + + // The highlighted character is yellow; the rest are dark gray. + int colr = (x == InputGridX && y == InputGridY) ? Font.CR_YELLOW : Font.CR_DARKGRAY; + Color palcolor = (x == InputGridX && y == InputGridY) ? Color(160, 120, 0) : Color(120, 120, 120); + + if (ch > 32) + { + // Draw a normal character. + screen.DrawChar(SmallFont, colr, xx + cell_width/2 - width*CleanXfac/2, yy + top_padding, ch, DTA_CleanNoMove, true); + } + else if (ch == 32) + { + // Draw the space as a box outline. We also draw it 50% wider than it really is. + int x1 = xx + cell_width/2 - width * CleanXfac * 3 / 4; + int x2 = x1 + width * 3 * CleanXfac / 2; + int y1 = yy + top_padding; + int y2 = y1 + SmallFont.GetHeight() * CleanYfac; + screen.Clear(x1, y1, x2, y1+CleanYfac, palcolor); // top + screen.Clear(x1, y2, x2, y2+CleanYfac, palcolor); // bottom + screen.Clear(x1, y1+CleanYfac, x1+CleanXfac, y2, palcolor); // left + screen.Clear(x2-CleanXfac, y1+CleanYfac, x2, y2, palcolor); // right + } + else if (ch == 8 || ch == 0) + { + // Draw the backspace and end "characters". + String str = ch == 8 ? "BS" : "ED"; + screen.DrawText(SmallFont, colr, + xx + cell_width/2 - SmallFont.StringWidth(str)*CleanXfac/2, + yy + top_padding, str, DTA_CleanNoMove, true); + } + } + } + } + Super.Drawer(); + } + } \ No newline at end of file From f5a0f6b3bf21302ead0e30fec7b8bc51fca790ba Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 18 Feb 2017 21:18:23 +0100 Subject: [PATCH 14/22] - almost done with TextEnterMenu. --- src/menu/menu.cpp | 2 + src/menu/menu.h | 15 +- src/menu/menuinput.cpp | 241 +------------------ src/scripting/thingdef_data.cpp | 13 +- src/scripting/vm/vm.h | 2 + wadsrc/static/zscript/base.txt | 3 +- wadsrc/static/zscript/menu/menu.txt | 2 + wadsrc/static/zscript/menu/textentermenu.txt | 233 +++++++++++++++++- 8 files changed, 255 insertions(+), 256 deletions(-) diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index 57a609b06..50e07f5b2 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -1195,6 +1195,8 @@ CCMD(undocolorpic) DEFINE_FIELD(DMenu, mParentMenu) +DEFINE_FIELD(DMenu, mMouseCapture); +DEFINE_FIELD(DMenu, mBackbuttonSelected); DEFINE_FIELD(DMenuDescriptor, mMenuName) DEFINE_FIELD(DMenuDescriptor, mNetgameMessage) diff --git a/src/menu/menu.h b/src/menu/menu.h index 3924ab869..c9307a0ef 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -253,9 +253,7 @@ class DMenu : public DObject DECLARE_CLASS (DMenu, DObject) HAS_OBJECT_POINTERS -protected: - bool mMouseCapture; - bool mBackbuttonSelected; + public: enum @@ -271,6 +269,8 @@ public: }; TObjPtr mParentMenu; + bool mMouseCapture; + bool mBackbuttonSelected; DMenu(DMenu *parent = NULL); virtual bool Responder (event_t *ev); @@ -354,7 +354,7 @@ extern FOptionMap OptionValues; class DTextEnterMenu : public DMenu { - DECLARE_ABSTRACT_CLASS(DTextEnterMenu, DMenu) + DECLARE_CLASS(DTextEnterMenu, DMenu) public: FString mEnterString; @@ -370,12 +370,7 @@ public: bool AllowColors; - // [TP] Added allowcolors - DTextEnterMenu(DMenu *parent, const char *textbuffer, int maxlen, int sizemode, bool showgrid, bool allowcolors = false); - - bool MenuEvent (int mkey, bool fromcontroller); - bool Responder(event_t *ev); - bool MouseEvent(int type, int x, int y); + DTextEnterMenu() {} }; diff --git a/src/menu/menuinput.cpp b/src/menu/menuinput.cpp index f880fabfd..404b955a0 100644 --- a/src/menu/menuinput.cpp +++ b/src/menu/menuinput.cpp @@ -44,249 +44,10 @@ // [TP] New #includes #include "v_text.h" -IMPLEMENT_CLASS(DTextEnterMenu, true, false) - -#define INPUTGRID_WIDTH 13 -#define INPUTGRID_HEIGHT 5 - -// Heretic and Hexen do not, by default, come with glyphs for all of these -// characters. Oh well. Doom and Strife do. -static const char InputGridChars[INPUTGRID_WIDTH * INPUTGRID_HEIGHT] = - "ABCDEFGHIJKLM" - "NOPQRSTUVWXYZ" - "0123456789+-=" - ".,!?@'\":;[]()" - "<>^#$%&*/_ \b"; - +IMPLEMENT_CLASS(DTextEnterMenu, false, false) CVAR(Bool, m_showinputgrid, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) -//============================================================================= -// -// -// -//============================================================================= - -// [TP] Added allowcolors -DTextEnterMenu::DTextEnterMenu(DMenu *parent, const char *textbuffer, int maxlen, int sizemode, bool showgrid, bool allowcolors) -: DMenu(parent) -{ - mEnterString = textbuffer; - mEnterSize = maxlen < 0 ? UINT_MAX : unsigned(maxlen); - mSizeMode = sizemode; - mInputGridOkay = showgrid || m_showinputgrid; - if (mEnterString.IsNotEmpty()) - { - InputGridX = INPUTGRID_WIDTH - 1; - InputGridY = INPUTGRID_HEIGHT - 1; - } - else - { - // If we are naming a new save, don't start the cursor on "end". - InputGridX = 0; - InputGridY = 0; - } - AllowColors = allowcolors; // [TP] -} - -//============================================================================= -// -// -// -//============================================================================= - -bool DTextEnterMenu::Responder(event_t *ev) -{ - if (ev->type == EV_GUI_Event) - { - // Save game and player name string input - if (ev->subtype == EV_GUI_Char) - { - mInputGridOkay = false; - if (mEnterString.Len() < mEnterSize && - (mSizeMode == 2/*entering player name*/ || (size_t)SmallFont->StringWidth(mEnterString) < (mEnterSize-1)*8)) - { - mEnterString.AppendFormat("%c", (char)ev->data1); - } - return true; - } - char ch = (char)ev->data1; - if ((ev->subtype == EV_GUI_KeyDown || ev->subtype == EV_GUI_KeyRepeat) && ch == '\b') - { - if (mEnterString.IsNotEmpty()) - { - mEnterString.Truncate(mEnterString.Len() - 1); - } - } - else if (ev->subtype == EV_GUI_KeyDown) - { - if (ch == GK_ESCAPE) - { - DMenu *parent = mParentMenu; - Close(); - parent->CallMenuEvent(MKEY_Abort, false); - return true; - } - else if (ch == '\r') - { - if (mEnterString.IsNotEmpty()) - { - // [TP] If we allow color codes, colorize the string now. - if (AllowColors) - mEnterString = strbin1(mEnterString); - - DMenu *parent = mParentMenu; - parent->CallMenuEvent(MKEY_Input, false); - Close(); - return true; - } - } - } - if (ev->subtype == EV_GUI_KeyDown || ev->subtype == EV_GUI_KeyRepeat) - { - return true; - } - } - return Super::Responder(ev); -} - -//============================================================================= -// -// -// -//============================================================================= - -bool DTextEnterMenu::MouseEvent(int type, int x, int y) -{ - const int cell_width = 18 * CleanXfac; - const int cell_height = 12 * CleanYfac; - const int screen_y = screen->GetHeight() - INPUTGRID_HEIGHT * cell_height; - const int screen_x = (screen->GetWidth() - INPUTGRID_WIDTH * cell_width) / 2; - - if (x >= screen_x && x < screen_x + INPUTGRID_WIDTH * cell_width && y >= screen_y) - { - InputGridX = (x - screen_x) / cell_width; - InputGridY = (y - screen_y) / cell_height; - if (type == DMenu::MOUSE_Release) - { - if (CallMenuEvent(MKEY_Enter, true)) - { - S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); - if (m_use_mouse == 2) InputGridX = InputGridY = -1; - return true; - } - } - } - else - { - InputGridX = InputGridY = -1; - } - return Super::MouseEvent(type, x, y); -} - - - -//============================================================================= -// -// -// -//============================================================================= - -bool DTextEnterMenu::MenuEvent (int key, bool fromcontroller) -{ - if (key == MKEY_Back) - { - mParentMenu->CallMenuEvent(MKEY_Abort, false); - return Super::MenuEvent(key, fromcontroller); - } - if (fromcontroller) - { - mInputGridOkay = true; - } - - if (mInputGridOkay) - { - int ch; - - if (InputGridX == -1 || InputGridY == -1) - { - InputGridX = InputGridY = 0; - } - switch (key) - { - case MKEY_Down: - InputGridY = (InputGridY + 1) % INPUTGRID_HEIGHT; - return true; - - case MKEY_Up: - InputGridY = (InputGridY + INPUTGRID_HEIGHT - 1) % INPUTGRID_HEIGHT; - return true; - - case MKEY_Right: - InputGridX = (InputGridX + 1) % INPUTGRID_WIDTH; - return true; - - case MKEY_Left: - InputGridX = (InputGridX + INPUTGRID_WIDTH - 1) % INPUTGRID_WIDTH; - return true; - - case MKEY_Clear: - if (mEnterString.IsNotEmpty()) - { - mEnterString.Truncate(mEnterString.Len() - 1); - } - return true; - - case MKEY_Enter: - assert(unsigned(InputGridX) < INPUTGRID_WIDTH && unsigned(InputGridY) < INPUTGRID_HEIGHT); - if (mInputGridOkay) - { - ch = InputGridChars[InputGridX + InputGridY * INPUTGRID_WIDTH]; - if (ch == 0) // end - { - if (mEnterString.IsNotEmpty()) - { - DMenu *parent = mParentMenu; - Close(); - parent->CallMenuEvent(MKEY_Input, false); - return true; - } - } - else if (ch == '\b') // bs - { - if (mEnterString.IsNotEmpty()) - { - mEnterString.Truncate(mEnterString.Len() - 1); - } - } - else if (mEnterString.Len() < mEnterSize && - (mSizeMode == 2/*entering player name*/ || (size_t)SmallFont->StringWidth(mEnterString) < (mEnterSize-1)*8)) - { - mEnterString += char(ch); - } - } - return true; - - default: - break; // Keep GCC quiet - } - } - return false; -} - -DEFINE_ACTION_FUNCTION(DTextEnterMenu, Open) -{ - PARAM_PROLOGUE; - PARAM_OBJECT(parent, DMenu); - PARAM_STRING(text); - PARAM_INT(maxlen); - PARAM_INT(sizemode); - PARAM_BOOL(fromcontroller); - auto m = new DTextEnterMenu(parent, text.GetChars(), maxlen, sizemode, fromcontroller, false); - M_ActivateMenu(m); - ACTION_RETURN_OBJECT(m); -} - DEFINE_FIELD(DTextEnterMenu, mEnterString); DEFINE_FIELD(DTextEnterMenu, mEnterSize); DEFINE_FIELD(DTextEnterMenu, mEnterPos); diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index 4fb167f56..986f0f1f2 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -1213,10 +1213,12 @@ DEFINE_ACTION_FUNCTION(FStringStruct, Mid) ACTION_RETURN_STRING(s); } -DEFINE_ACTION_FUNCTION(FStringStruct, Len) +DEFINE_ACTION_FUNCTION(FStringStruct, Truncate) { PARAM_SELF_STRUCT_PROLOGUE(FString); - ACTION_RETURN_INT((int)self->Len()); + PARAM_UINT(len); + self->Truncate(len); + return 0; } // CharAt and CharCodeAt is how JS does it, and JS is similar here in that it doesn't have char type as int. @@ -1239,3 +1241,10 @@ DEFINE_ACTION_FUNCTION(FStringStruct, CharCodeAt) ACTION_RETURN_INT(0); ACTION_RETURN_INT((*self)[pos]); } + +DEFINE_ACTION_FUNCTION(FStringStruct, Filter) +{ + PARAM_SELF_STRUCT_PROLOGUE(FString); + ACTION_RETURN_STRING(strbin1(*self)); +} + diff --git a/src/scripting/vm/vm.h b/src/scripting/vm/vm.h index aa191c34e..de5132716 100644 --- a/src/scripting/vm/vm.h +++ b/src/scripting/vm/vm.h @@ -8,6 +8,8 @@ #include "doomerrors.h" #include "memarena.h" +class DObject; + extern FMemArena ClassDataAllocator; #define MAX_RETURNS 8 // Maximum number of results a function called by script code can return diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 43d1df05a..9ae86abb5 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -578,9 +578,10 @@ struct StringStruct native native void Replace(String pattern, String replacement); native String Mid(int pos = 0, int len = 2147483647); - native int Len(); + native void Truncate(int newlen); native String CharAt(int pos); native int CharCodeAt(int pos); + native String Filter(); } class Floor : Thinker native diff --git a/wadsrc/static/zscript/menu/menu.txt b/wadsrc/static/zscript/menu/menu.txt index 103d75104..2f5d9454a 100644 --- a/wadsrc/static/zscript/menu/menu.txt +++ b/wadsrc/static/zscript/menu/menu.txt @@ -87,6 +87,8 @@ class Menu : Object native }; native Menu mParentMenu; + native bool mMouseCapture; + native bool mBackbuttonSelected; void Init(Menu parent) { diff --git a/wadsrc/static/zscript/menu/textentermenu.txt b/wadsrc/static/zscript/menu/textentermenu.txt index c99285145..c48f6854f 100644 --- a/wadsrc/static/zscript/menu/textentermenu.txt +++ b/wadsrc/static/zscript/menu/textentermenu.txt @@ -16,9 +16,47 @@ class TextEnterMenu : Menu native native int InputGridY; native bool AllowColors; - native static TextEnterMenu Open(Menu parent, String text, int maxlen, int sizemode, bool fromcontroller); - - + //============================================================================= + // + // + // + //============================================================================= + + // [TP] Added allowcolors + private void Init(Menu parent, String textbuffer, int maxlen, int sizemode, bool showgrid, bool allowcolors) + { + Super.init(parent); + mEnterString = textbuffer; + mEnterSize = maxlen < 0 ? 0x7fffffff : maxlen; + mSizeMode = sizemode; + mInputGridOkay = showgrid || m_showinputgrid; + if (mEnterString.Length() > 0) + { + InputGridX = INPUTGRID_WIDTH - 1; + InputGridY = INPUTGRID_HEIGHT - 1; + } + else + { + // If we are naming a new save, don't start the cursor on "end". + InputGridX = 0; + InputGridY = 0; + } + AllowColors = allowcolors; // [TP] + } + + static TextEnterMenu Open(Menu parent, String textbuffer, int maxlen, int sizemode, bool showgrid = false, bool allowcolors = false) + { + let me = new("TextEnterMenu"); + me.Init(parent, textbuffer, maxlen, sizemode, showgrid, allowcolors); + return me; + } + + //============================================================================= + // + // + // + //============================================================================= + String GetText() { return mEnterString; @@ -29,6 +67,195 @@ class TextEnterMenu : Menu native return mInputGridOkay; } + + //============================================================================= + // + // + // + //============================================================================= + + override bool Responder(InputEventData ev) + { + if (ev.type == InputEventData.GUI_Event) + { + // Save game and player name string input + if (ev.subtype == InputEventData.GUI_Char) + { + mInputGridOkay = false; + if (mEnterString.Length() < mEnterSize && + (mSizeMode == 2/*entering player name*/ || SmallFont.StringWidth(mEnterString) < (mEnterSize-1)*8)) + { + mEnterString.AppendFormat("%c", ev.data1); + } + return true; + } + int ch = ev.data1; + if ((ev.subtype == InputEventData.GUI_KeyDown || ev.subtype == InputEventData.GUI_KeyRepeat) && ch == 8) + { + if (mEnterString.Length() > 0) + { + mEnterString.Truncate(mEnterString.Length() - 1); + } + } + else if (ev.subtype == InputEventData.GUI_KeyDown) + { + if (ch == UIEvent.Key_ESCAPE) + { + Menu parent = mParentMenu; + Close(); + parent.MenuEvent(MKEY_Abort, false); + return true; + } + else if (ch == 13) + { + if (mEnterString.Length() > 0) + { + // [TP] If we allow color codes, colorize the string now. + if (AllowColors) + mEnterString = mEnterString.Filter(); + + Menu parent = mParentMenu; + parent.MenuEvent(MKEY_Input, false); + Close(); + return true; + } + } + } + if (ev.subtype == InputEventData.GUI_KeyDown || ev.subtype == InputEventData.GUI_KeyRepeat) + { + return true; + } + } + return Super.Responder(ev); + } + + //============================================================================= + // + // + // + //============================================================================= + + override bool MouseEvent(int type, int x, int y) + { + if (mMouseCapture || m_use_mouse == 1) + { + int cell_width = 18 * CleanXfac; + int cell_height = 12 * CleanYfac; + int screen_y = screen.GetHeight() - INPUTGRID_HEIGHT * cell_height; + int screen_x = (screen.GetWidth() - INPUTGRID_WIDTH * cell_width) / 2; + + if (x >= screen_x && x < screen_x + INPUTGRID_WIDTH * cell_width && y >= screen_y) + { + InputGridX = (x - screen_x) / cell_width; + InputGridY = (y - screen_y) / cell_height; + if (type == MOUSE_Release) + { + if (MenuEvent(MKEY_Enter, true)) + { + MenuSound("menu/choose"); + if (m_use_mouse == 2) InputGridX = InputGridY = -1; + return true; + } + } + } + else + { + InputGridX = InputGridY = -1; + } + } + return Super.MouseEvent(type, x, y); + } + + //============================================================================= + // + // + // + //============================================================================= + + override bool MenuEvent (int key, bool fromcontroller) + { + String InputGridChars = Chars; + if (key == MKEY_Back) + { + mParentMenu.MenuEvent(MKEY_Abort, false); + return Super.MenuEvent(key, fromcontroller); + } + if (fromcontroller) + { + mInputGridOkay = true; + } + + if (mInputGridOkay) + { + int ch; + + if (InputGridX == -1 || InputGridY == -1) + { + InputGridX = InputGridY = 0; + } + switch (key) + { + case MKEY_Down: + InputGridY = (InputGridY + 1) % INPUTGRID_HEIGHT; + return true; + + case MKEY_Up: + InputGridY = (InputGridY + INPUTGRID_HEIGHT - 1) % INPUTGRID_HEIGHT; + return true; + + case MKEY_Right: + InputGridX = (InputGridX + 1) % INPUTGRID_WIDTH; + return true; + + case MKEY_Left: + InputGridX = (InputGridX + INPUTGRID_WIDTH - 1) % INPUTGRID_WIDTH; + return true; + + case MKEY_Clear: + if (mEnterString.Length() > 0) + { + mEnterString.Truncate(mEnterString.Length() - 1); + } + return true; + + case MKEY_Enter: + if (mInputGridOkay) + { + String c = InputGridChars.CharAt(InputGridX + InputGridY * INPUTGRID_WIDTH); + int ch = c.CharCodeAt(0); + if (ch == 0) // end + { + if (mEnterString.Length() > 0) + { + Menu parent = mParentMenu; + Close(); + parent.MenuEvent(MKEY_Input, false); + return true; + } + } + else if (ch == 8) // bs + { + if (mEnterString.Length() > 0) + { + mEnterString.Truncate(mEnterString.Length() - 1); + } + } + else if (mEnterString.Length() < mEnterSize && + (mSizeMode == 2/*entering player name*/ || SmallFont.StringWidth(mEnterString) < (mEnterSize-1)*8)) + { + mEnterString = mEnterString .. c; + } + } + return true; + + default: + break; // Keep GCC quiet + } + } + return false; + } + + //============================================================================= // // From de1e7661ebd16517d1329f3c67f6ae5b80fb36e9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 18 Feb 2017 21:25:19 +0100 Subject: [PATCH 15/22] - removed all native remnants of TextEnterMenu. --- src/CMakeLists.txt | 1 - src/menu/menu.cpp | 1 + src/menu/menu.h | 26 +-------- src/menu/menuinput.cpp | 58 -------------------- wadsrc/static/zscript/menu/textentermenu.txt | 54 ++++++++++++++---- 5 files changed, 46 insertions(+), 94 deletions(-) delete mode 100644 src/menu/menuinput.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 04f2d0cd9..7619c6334 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -848,7 +848,6 @@ set( FASTMATH_PCH_SOURCES menu/loadsavemenu.cpp menu/menu.cpp menu/menudef.cpp - menu/menuinput.cpp menu/messagebox.cpp menu/optionmenu.cpp menu/playermenu.cpp diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index 50e07f5b2..54615f4e7 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -63,6 +63,7 @@ CVAR (Float, mouse_sensitivity, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Bool, show_messages, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Bool, show_obituaries, true, CVAR_ARCHIVE) +CVAR(Bool, m_showinputgrid, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR (Float, snd_menuvolume, 0.6f, CVAR_ARCHIVE) diff --git a/src/menu/menu.h b/src/menu/menu.h index c9307a0ef..415e3dff6 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -348,34 +348,10 @@ extern FOptionMap OptionValues; //============================================================================= // -// Input some text +// // //============================================================================= -class DTextEnterMenu : public DMenu -{ - DECLARE_CLASS(DTextEnterMenu, DMenu) - -public: - FString mEnterString; - unsigned int mEnterSize; - unsigned int mEnterPos; - int mSizeMode; // 1: size is length in chars. 2: also check string width - bool mInputGridOkay; - - int InputGridX; - int InputGridY; - - // [TP] - bool AllowColors; - - - DTextEnterMenu() {} -}; - - - - struct event_t; void M_EnableMenu (bool on) ; bool M_Responder (event_t *ev); diff --git a/src/menu/menuinput.cpp b/src/menu/menuinput.cpp deleted file mode 100644 index 404b955a0..000000000 --- a/src/menu/menuinput.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* -** menuinput.cpp -** The string input code -** -**--------------------------------------------------------------------------- -** Copyright 2001-2010 Randy Heit -** Copyright 2010 Christoph Oelckers -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#include "menu/menu.h" -#include "v_video.h" -#include "c_cvars.h" -#include "d_event.h" -#include "d_gui.h" -#include "v_font.h" -#include "v_palette.h" -#include "cmdlib.h" -// [TP] New #includes -#include "v_text.h" - -IMPLEMENT_CLASS(DTextEnterMenu, false, false) - -CVAR(Bool, m_showinputgrid, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) - -DEFINE_FIELD(DTextEnterMenu, mEnterString); -DEFINE_FIELD(DTextEnterMenu, mEnterSize); -DEFINE_FIELD(DTextEnterMenu, mEnterPos); -DEFINE_FIELD(DTextEnterMenu, mSizeMode); // 1: size is length in chars. 2: also check string width -DEFINE_FIELD(DTextEnterMenu, mInputGridOkay); -DEFINE_FIELD(DTextEnterMenu, InputGridX); -DEFINE_FIELD(DTextEnterMenu, InputGridY); -DEFINE_FIELD(DTextEnterMenu, AllowColors); diff --git a/wadsrc/static/zscript/menu/textentermenu.txt b/wadsrc/static/zscript/menu/textentermenu.txt index c48f6854f..356eba1e6 100644 --- a/wadsrc/static/zscript/menu/textentermenu.txt +++ b/wadsrc/static/zscript/menu/textentermenu.txt @@ -1,20 +1,54 @@ +/* +** menuinput.cpp +** The string input code +** +**--------------------------------------------------------------------------- +** Copyright 2001-2010 Randy Heit +** Copyright 2010-2017 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ -// This is only the parts that are needed to make the menu fully work right now. More to come later. -class TextEnterMenu : Menu native + +class TextEnterMenu : Menu { const INPUTGRID_WIDTH = 13; const INPUTGRID_HEIGHT = 5; const Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-=.,!?@'\":;[]()<>^#$%&*/_ \b"; - native String mEnterString; - native int mEnterSize; - native int mEnterPos; - native int mSizeMode; // 1: size is length in chars. 2: also check string width - native bool mInputGridOkay; - native int InputGridX; - native int InputGridY; - native bool AllowColors; + String mEnterString; + int mEnterSize; + int mEnterPos; + int mSizeMode; // 1: size is length in chars. 2: also check string width + bool mInputGridOkay; + int InputGridX; + int InputGridY; + bool AllowColors; //============================================================================= // From 6e0e2b24579747ec64fe52562fffa16ca30c02f9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 18 Feb 2017 22:07:28 +0100 Subject: [PATCH 16/22] - replaced all subclasses of DMessageBoxMenu with a callback option and lambdas to reduce the amount of menu code to port over. Now this is only one class. --- src/menu/menu.cpp | 5 + src/menu/messagebox.cpp | 289 ++++++++-------------------------------- 2 files changed, 57 insertions(+), 237 deletions(-) diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index 54615f4e7..6569c00c7 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -588,6 +588,11 @@ void M_SetMenu(FName menu, int param) M_InitVideoModes(); break; + case NAME_Quitmenu: + // The separate menu class no longer exists but the name still needs support for existing mods. + C_DoCommand("menu_quit"); + return; + } // End of special checks diff --git a/src/menu/messagebox.cpp b/src/menu/messagebox.cpp index af2cb9b3d..7d6312df8 100644 --- a/src/menu/messagebox.cpp +++ b/src/menu/messagebox.cpp @@ -58,12 +58,13 @@ class DMessageBoxMenu : public DMenu int messageSelection; int mMouseLeft, mMouseRight, mMouseY; FName mAction; + void (*Handler)(); 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, void (*hnd)() = nullptr); void OnDestroy() override; - 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(*hnd)() = nullptr); void Drawer(); bool Responder(event_t *ev); bool MenuEvent(int mkey, bool fromcontroller); @@ -80,7 +81,7 @@ IMPLEMENT_CLASS(DMessageBoxMenu, false, false) // //============================================================================= -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, void (*hnd)()) : DMenu(parent) { mAction = action; @@ -91,7 +92,7 @@ DMessageBoxMenu::DMessageBoxMenu(DMenu *parent, const char *message, int message int mr2 = 170 + SmallFont->StringWidth(GStrings["TXT_NO"]); mMouseRight = MAX(mr1, mr2); - Init(parent, message, messagemode, playsound); + Init(parent, message, messagemode, playsound, hnd); } //============================================================================= @@ -100,7 +101,7 @@ DMessageBoxMenu::DMessageBoxMenu(DMenu *parent, const char *message, int message // //============================================================================= -void DMessageBoxMenu::Init(DMenu *parent, const char *message, int messagemode, bool playsound) +void DMessageBoxMenu::Init(DMenu *parent, const char *message, int messagemode, bool playsound, void (*hnd)()) { mParentMenu = parent; if (message != NULL) @@ -115,6 +116,7 @@ void DMessageBoxMenu::Init(DMenu *parent, const char *message, int messagemode, S_StopSound (CHAN_VOICE); S_Sound (CHAN_VOICE | CHAN_UI, "menu/prompt", snd_menuvolume, ATTN_NONE); } + Handler = hnd; } //============================================================================= @@ -150,7 +152,16 @@ void DMessageBoxMenu::CloseSound() void DMessageBoxMenu::HandleResult(bool res) { - if (mParentMenu != NULL) + if (Handler != nullptr) + { + if (res) Handler(); + else + { + Close(); + CloseSound(); + } + } + else if (mParentMenu != NULL) { if (mMessageMode == 0) { @@ -344,156 +355,51 @@ bool DMessageBoxMenu::MouseEvent(int type, int x, int y) } } -//============================================================================= -// -// -// -//============================================================================= //============================================================================= // // // //============================================================================= -class DQuitMenu : public DMessageBoxMenu -{ - DECLARE_CLASS(DQuitMenu, DMessageBoxMenu) +CCMD (menu_quit) +{ // F10 + M_StartControlPanel (true); -public: - - DQuitMenu(bool playsound = false); - virtual void HandleResult(bool res); -}; - -IMPLEMENT_CLASS(DQuitMenu, false, false) - -//============================================================================= -// -// -// -//============================================================================= - -DQuitMenu::DQuitMenu(bool playsound) -{ int messageindex = gametic % gameinfo.quitmessages.Size(); FString EndString; const char *msg = gameinfo.quitmessages[messageindex]; - if (msg[0] == '$') + if (msg[0] == '$') { if (msg[1] == '*') { - EndString = GStrings(msg+2); + EndString = GStrings(msg + 2); } else { - EndString.Format("%s\n\n%s", GStrings(msg+1), GStrings("DOSY")); + EndString.Format("%s\n\n%s", GStrings(msg + 1), GStrings("DOSY")); } } else EndString = gameinfo.quitmessages[messageindex]; - Init(NULL, EndString, 0, playsound); -} - -//============================================================================= -// -// -// -//============================================================================= - -void DQuitMenu::HandleResult(bool res) -{ - if (res) + DMenu *newmenu = new DMessageBoxMenu(CurrentMenu, EndString, 0, false, NAME_None, []() { if (!netgame) { if (gameinfo.quitSound.IsNotEmpty()) { - S_Sound (CHAN_VOICE | CHAN_UI, gameinfo.quitSound, snd_menuvolume, ATTN_NONE); - I_WaitVBL (105); + S_Sound(CHAN_VOICE | CHAN_UI, gameinfo.quitSound, snd_menuvolume, ATTN_NONE); + I_WaitVBL(105); } } ST_Endoom(); - } - else - { - Close(); - CloseSound(); - } -} + }); -//============================================================================= -// -// -// -//============================================================================= -CCMD (menu_quit) -{ // F10 - M_StartControlPanel (true); - DMenu *newmenu = new DQuitMenu(false); - newmenu->mParentMenu = CurrentMenu; M_ActivateMenu(newmenu); } -//============================================================================= -// -// -// -//============================================================================= -//============================================================================= -// -// -// -//============================================================================= - -class DEndGameMenu : public DMessageBoxMenu -{ - DECLARE_CLASS(DEndGameMenu, DMessageBoxMenu) - -public: - - DEndGameMenu(bool playsound = false); - virtual void HandleResult(bool res); -}; - -IMPLEMENT_CLASS(DEndGameMenu, false, false) - -//============================================================================= -// -// -// -//============================================================================= - -DEndGameMenu::DEndGameMenu(bool playsound) -{ - Init(NULL, GStrings(netgame ? "NETEND" : "ENDGAME"), 0, playsound); -} - -//============================================================================= -// -// -// -//============================================================================= - -void DEndGameMenu::HandleResult(bool res) -{ - if (res) - { - M_ClearMenus (); - if (!netgame) - { - D_StartTitle (); - } - } - else - { - Close(); - CloseSound(); - } -} - //============================================================================= // // @@ -510,67 +416,18 @@ CCMD (menu_endgame) //M_StartControlPanel (true); S_Sound (CHAN_VOICE | CHAN_UI, "menu/activate", snd_menuvolume, ATTN_NONE); - DMenu *newmenu = new DEndGameMenu(false); - newmenu->mParentMenu = CurrentMenu; - M_ActivateMenu(newmenu); -} -//============================================================================= -// -// -// -//============================================================================= -//============================================================================= -// -// -// -//============================================================================= - -class DQuickSaveMenu : public DMessageBoxMenu -{ - DECLARE_CLASS(DQuickSaveMenu, DMessageBoxMenu) - -public: - - DQuickSaveMenu(bool playsound = false); - virtual void HandleResult(bool res); -}; - -IMPLEMENT_CLASS(DQuickSaveMenu, false, false) - -//============================================================================= -// -// -// -//============================================================================= - -DQuickSaveMenu::DQuickSaveMenu(bool playsound) -{ - FString tempstring; - - tempstring.Format(GStrings("QSPROMPT"), savegameManager.quickSaveSlot->SaveTitle.GetChars()); - Init(NULL, tempstring, 0, playsound); -} - -//============================================================================= -// -// -// -//============================================================================= - -void DQuickSaveMenu::HandleResult(bool res) -{ - if (res) + FString tempstring = GStrings(netgame ? "NETEND" : "ENDGAME"); + DMenu *newmenu = new DMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []() { - G_SaveGame (savegameManager.quickSaveSlot->Filename.GetChars(), savegameManager.quickSaveSlot->SaveTitle.GetChars()); - S_Sound (CHAN_VOICE | CHAN_UI, "menu/dismiss", snd_menuvolume, ATTN_NONE); M_ClearMenus(); - } - else - { - Close(); - CloseSound(); - } + if (!netgame) + { + D_StartTitle(); + } + }); + + M_ActivateMenu(newmenu); } //============================================================================= @@ -606,67 +463,18 @@ CCMD (quicksave) } S_Sound(CHAN_VOICE | CHAN_UI, "menu/activate", snd_menuvolume, ATTN_NONE); - DMenu *newmenu = new DQuickSaveMenu(false); - newmenu->mParentMenu = CurrentMenu; - M_ActivateMenu(newmenu); -} -//============================================================================= -// -// -// -//============================================================================= -//============================================================================= -// -// -// -//============================================================================= - -class DQuickLoadMenu : public DMessageBoxMenu -{ - DECLARE_CLASS(DQuickLoadMenu, DMessageBoxMenu) - -public: - - DQuickLoadMenu(bool playsound = false); - virtual void HandleResult(bool res); -}; - -IMPLEMENT_CLASS(DQuickLoadMenu, false, false) - -//============================================================================= -// -// -// -//============================================================================= - -DQuickLoadMenu::DQuickLoadMenu(bool playsound) -{ FString tempstring; + tempstring.Format(GStrings("QSPROMPT"), savegameManager.quickSaveSlot->SaveTitle.GetChars()); - tempstring.Format(GStrings("QLPROMPT"), savegameManager.quickSaveSlot->SaveTitle.GetChars()); - Init(NULL, tempstring, 0, playsound); -} - -//============================================================================= -// -// -// -//============================================================================= - -void DQuickLoadMenu::HandleResult(bool res) -{ - if (res) + DMenu *newmenu = new DMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []() { - G_LoadGame (savegameManager.quickSaveSlot->Filename.GetChars()); - S_Sound (CHAN_VOICE | CHAN_UI, "menu/dismiss", snd_menuvolume, ATTN_NONE); + G_SaveGame(savegameManager.quickSaveSlot->Filename.GetChars(), savegameManager.quickSaveSlot->SaveTitle.GetChars()); + S_Sound(CHAN_VOICE | CHAN_UI, "menu/dismiss", snd_menuvolume, ATTN_NONE); M_ClearMenus(); - } - else - { - Close(); - CloseSound(); - } + }); + + M_ActivateMenu(newmenu); } //============================================================================= @@ -699,10 +507,17 @@ CCMD (quickload) G_LoadGame(savegameManager.quickSaveSlot->Filename.GetChars()); return; } + FString tempstring; + tempstring.Format(GStrings("QLPROMPT"), savegameManager.quickSaveSlot->SaveTitle.GetChars()); M_StartControlPanel(true); - DMenu *newmenu = new DQuickLoadMenu(false); - newmenu->mParentMenu = CurrentMenu; + + DMenu *newmenu = new DMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []() + { + G_LoadGame(savegameManager.quickSaveSlot->Filename.GetChars()); + S_Sound(CHAN_VOICE | CHAN_UI, "menu/dismiss", snd_menuvolume, ATTN_NONE); + M_ClearMenus(); + }); M_ActivateMenu(newmenu); } From aabcc1f92e3fb2e811887738fca9d41724009cd4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 18 Feb 2017 23:05:01 +0100 Subject: [PATCH 17/22] - scriptified the input functions of DMessageBoxMenu. --- src/menu/messagebox.cpp | 187 ++---------------- src/scripting/vm/vm.h | 2 + wadsrc/static/zscript.txt | 1 + wadsrc/static/zscript/menu/messagebox.txt | 221 ++++++++++++++++++++++ 4 files changed, 241 insertions(+), 170 deletions(-) create mode 100644 wadsrc/static/zscript/menu/messagebox.txt diff --git a/src/menu/messagebox.cpp b/src/menu/messagebox.cpp index 7d6312df8..e4f9c1cf6 100644 --- a/src/menu/messagebox.cpp +++ b/src/menu/messagebox.cpp @@ -52,7 +52,7 @@ EXTERN_CVAR (Bool, saveloadconfirmation) // [mxd] class DMessageBoxMenu : public DMenu { DECLARE_CLASS(DMessageBoxMenu, DMenu) - +public: FBrokenLines *mMessage; int mMessageMode; int messageSelection; @@ -66,11 +66,6 @@ public: void OnDestroy() override; void Init(DMenu *parent, const char *message, int messagemode, bool playsound = false, void(*hnd)() = nullptr); void Drawer(); - bool Responder(event_t *ev); - bool MenuEvent(int mkey, bool fromcontroller); - bool MouseEvent(int type, int x, int y); - void CloseSound(); - virtual void HandleResult(bool res); }; IMPLEMENT_CLASS(DMessageBoxMenu, false, false) @@ -138,54 +133,6 @@ void DMessageBoxMenu::OnDestroy() // //============================================================================= -void DMessageBoxMenu::CloseSound() -{ - S_Sound (CHAN_VOICE | CHAN_UI, - CurrentMenu != NULL? "menu/backup" : "menu/dismiss", snd_menuvolume, ATTN_NONE); -} - -//============================================================================= -// -// -// -//============================================================================= - -void DMessageBoxMenu::HandleResult(bool res) -{ - if (Handler != nullptr) - { - if (res) Handler(); - else - { - Close(); - CloseSound(); - } - } - else if (mParentMenu != NULL) - { - if (mMessageMode == 0) - { - if (mAction == NAME_None) - { - mParentMenu->CallMenuEvent(res? MKEY_MBYes : MKEY_MBNo, false); - Close(); - } - else - { - Close(); - if (res) M_SetMenu(mAction, -1); - } - CloseSound(); - } - } -} - -//============================================================================= -// -// -// -//============================================================================= - void DMessageBoxMenu::Drawer () { int i, y; @@ -237,122 +184,13 @@ void DMessageBoxMenu::Drawer () } } -//============================================================================= -// -// -// -//============================================================================= - -bool DMessageBoxMenu::Responder(event_t *ev) +typedef void(*hfunc)(); +DEFINE_ACTION_FUNCTION(DMessageBoxMenu, CallHandler) { - if (ev->type == EV_GUI_Event && ev->subtype == EV_GUI_KeyDown) - { - if (mMessageMode == 0) - { - int ch = tolower(ev->data1); - if (ch == 'n' || ch == ' ') - { - HandleResult(false); - return true; - } - else if (ch == 'y') - { - HandleResult(true); - return true; - } - } - else - { - Close(); - return true; - } - return false; - } - else if (ev->type == EV_KeyDown) - { - Close(); - return true; - } - return Super::Responder(ev); -} - -//============================================================================= -// -// -// -//============================================================================= - -bool DMessageBoxMenu::MenuEvent(int mkey, bool fromcontroller) -{ - if (mMessageMode == 0) - { - if (mkey == MKEY_Up || mkey == MKEY_Down) - { - S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); - messageSelection = !messageSelection; - return true; - } - else if (mkey == MKEY_Enter) - { - // 0 is yes, 1 is no - HandleResult(!messageSelection); - return true; - } - else if (mkey == MKEY_Back) - { - HandleResult(false); - return true; - } - return false; - } - else - { - Close(); - CloseSound(); - return true; - } -} - -//============================================================================= -// -// -// -//============================================================================= - -bool DMessageBoxMenu::MouseEvent(int type, int x, int y) -{ - if (mMessageMode == 1) - { - if (type == MOUSE_Click) - { - return MenuEvent(MKEY_Enter, true); - } - return false; - } - else - { - int sel = -1; - int fh = SmallFont->GetHeight() + 1; - - // convert x/y from screen to virtual coordinates, according to CleanX/Yfac use in DrawTexture - x = ((x - (screen->GetWidth() / 2)) / CleanXfac) + 160; - y = ((y - (screen->GetHeight() / 2)) / CleanYfac) + 100; - - if (x >= mMouseLeft && x <= mMouseRight && y >= mMouseY && y < mMouseY + 2 * fh) - { - sel = y >= mMouseY + fh; - } - if (sel != -1 && sel != messageSelection) - { - //S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); - } - messageSelection = sel; - if (type == MOUSE_Release) - { - return MenuEvent(MKEY_Enter, true); - } - return true; - } + PARAM_PROLOGUE; + PARAM_POINTERTYPE(Handler, hfunc); + Handler(); + return 0; } //============================================================================= @@ -547,4 +385,13 @@ DEFINE_ACTION_FUNCTION(DMenu, StartMessage) PARAM_NAME_DEF(action); M_StartMessage(msg, mode, action); return 0; -} \ No newline at end of file +} + + +DEFINE_FIELD(DMessageBoxMenu, mMessageMode); +DEFINE_FIELD(DMessageBoxMenu, messageSelection); +DEFINE_FIELD(DMessageBoxMenu, mMouseLeft); +DEFINE_FIELD(DMessageBoxMenu, mMouseRight); +DEFINE_FIELD(DMessageBoxMenu, mMouseY); +DEFINE_FIELD(DMessageBoxMenu, mAction); +DEFINE_FIELD(DMessageBoxMenu, Handler); diff --git a/src/scripting/vm/vm.h b/src/scripting/vm/vm.h index de5132716..cda7a1c58 100644 --- a/src/scripting/vm/vm.h +++ b/src/scripting/vm/vm.h @@ -1030,6 +1030,7 @@ void NullParam(const char *varname); #define PARAM_STATE_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_INT); FState *x = (FState *)StateLabels.GetState(param[p].i, self->GetClass()); #define PARAM_STATE_ACTION_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_INT); FState *x = (FState *)StateLabels.GetState(param[p].i, stateowner->GetClass()); #define PARAM_POINTER_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER); type *x = (type *)param[p].a; +#define PARAM_POINTERTYPE_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER); type x = (type )param[p].a; #define PARAM_OBJECT_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); type *x = (type *)param[p].a; assert(x == NULL || x->IsKindOf(RUNTIME_CLASS(type))); #define PARAM_CLASS_AT(p,x,base) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); base::MetaClass *x = (base::MetaClass *)param[p].a; assert(x == NULL || x->IsDescendantOf(RUNTIME_CLASS(base))); #define PARAM_POINTER_NOT_NULL_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER); type *x = (type *)PARAM_NULLCHECK(param[p].a, #x); @@ -1074,6 +1075,7 @@ void NullParam(const char *varname); #define PARAM_STATE(x) ++paramnum; PARAM_STATE_AT(paramnum,x) #define PARAM_STATE_ACTION(x) ++paramnum; PARAM_STATE_ACTION_AT(paramnum,x) #define PARAM_POINTER(x,type) ++paramnum; PARAM_POINTER_AT(paramnum,x,type) +#define PARAM_POINTERTYPE(x,type) ++paramnum; PARAM_POINTERTYPE_AT(paramnum,x,type) #define PARAM_OBJECT(x,type) ++paramnum; PARAM_OBJECT_AT(paramnum,x,type) #define PARAM_CLASS(x,base) ++paramnum; PARAM_CLASS_AT(paramnum,x,base) #define PARAM_POINTER_NOT_NULL(x,type) ++paramnum; PARAM_POINTER_NOT_NULL_AT(paramnum,x,type) diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 419adfe76..2bd535d77 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -9,6 +9,7 @@ #include "zscript/menu/menuitembase.txt" #include "zscript/menu/menu.txt" +#include "zscript/menu/messagebox.txt" #include "zscript/menu/listmenu.txt" #include "zscript/menu/listmenuitems.txt" #include "zscript/menu/optionmenu.txt" diff --git a/wadsrc/static/zscript/menu/messagebox.txt b/wadsrc/static/zscript/menu/messagebox.txt new file mode 100644 index 000000000..f0b08eb72 --- /dev/null +++ b/wadsrc/static/zscript/menu/messagebox.txt @@ -0,0 +1,221 @@ +/* +** messagebox.cpp +** Confirmation, notification screns +** +**--------------------------------------------------------------------------- +** Copyright 2010-2017 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +class MessageBoxMenu : Menu native +{ + native voidptr Handler; + native int mMessageMode; + native int messageSelection; + native int mMouseLeft, mMouseRight, mMouseY; + native Name mAction; + + native static void CallHandler(voidptr hnd); + + + //============================================================================= + // + // + // + //============================================================================= + + protected void CloseSound() + { + MenuSound (GetCurrentMenu() != NULL? "menu/backup" : "menu/dismiss"); + } + + //============================================================================= + // + // + // + //============================================================================= + + virtual void HandleResult(bool res) + { + if (Handler != null) + { + if (res) + { + CallHandler(Handler); + } + else + { + Close(); + CloseSound(); + } + } + else if (mParentMenu != NULL) + { + if (mMessageMode == 0) + { + if (mAction == 'None') + { + mParentMenu.MenuEvent(res? MKEY_MBYes : MKEY_MBNo, false); + Close(); + } + else + { + Close(); + if (res) SetMenu(mAction, -1); + } + CloseSound(); + } + } + } + + //============================================================================= + // + // + // + //============================================================================= + + override bool Responder(InputEventData ev) + { + if (ev.type == InputEventData.GUI_Event && ev.subtype == InputEventData.GUI_KeyDown) + { + if (mMessageMode == 0) + { + // tolower + int ch = ev.data1; + ch = ch >= 65 && ch <91? ch + 32 : ch; + + if (ch == 78 /*'n'*/ || ch == 32) + { + HandleResult(false); + return true; + } + else if (ch == 89 /*'y'*/) + { + HandleResult(true); + return true; + } + } + else + { + Close(); + return true; + } + return false; + } + else if (ev.type == InputEventData.KeyDown) + { + Close(); + return true; + } + return Super.Responder(ev); + } + + //============================================================================= + // + // + // + //============================================================================= + + override bool MenuEvent(int mkey, bool fromcontroller) + { + if (mMessageMode == 0) + { + if (mkey == MKEY_Up || mkey == MKEY_Down) + { + MenuSound("menu/cursor"); + messageSelection = !messageSelection; + return true; + } + else if (mkey == MKEY_Enter) + { + // 0 is yes, 1 is no + HandleResult(!messageSelection); + return true; + } + else if (mkey == MKEY_Back) + { + HandleResult(false); + return true; + } + return false; + } + else + { + Close(); + CloseSound(); + return true; + } + } + + //============================================================================= + // + // + // + //============================================================================= + + override bool MouseEvent(int type, int x, int y) + { + if (mMessageMode == 1) + { + if (type == MOUSE_Click) + { + return MenuEvent(MKEY_Enter, true); + } + return false; + } + else + { + int sel = -1; + int fh = SmallFont.GetHeight() + 1; + + // convert x/y from screen to virtual coordinates, according to CleanX/Yfac use in DrawTexture + x = ((x - (screen.GetWidth() / 2)) / CleanXfac) + 160; + y = ((y - (screen.GetHeight() / 2)) / CleanYfac) + 100; + + if (x >= mMouseLeft && x <= mMouseRight && y >= mMouseY && y < mMouseY + 2 * fh) + { + sel = y >= mMouseY + fh; + } + if (sel != -1 && sel != messageSelection) + { + //S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); + } + messageSelection = sel; + if (type == MOUSE_Release) + { + return MenuEvent(MKEY_Enter, true); + } + return true; + } + } + + +} + + + From 62b594a4990f91e58141d5255898c3732d3a87dc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 18 Feb 2017 23:18:55 +0100 Subject: [PATCH 18/22] - DMessageBoxMenu::Drawer scriptified. --- src/menu/messagebox.cpp | 102 ++++++---------------- wadsrc/static/zscript/menu/messagebox.txt | 61 +++++++++++++ 2 files changed, 89 insertions(+), 74 deletions(-) diff --git a/src/menu/messagebox.cpp b/src/menu/messagebox.cpp index e4f9c1cf6..078d7f31e 100644 --- a/src/menu/messagebox.cpp +++ b/src/menu/messagebox.cpp @@ -47,13 +47,34 @@ #include "g_game.h" +class DBrokenLines : public DObject +{ + DECLARE_ABSTRACT_CLASS(DBrokenLines, DObject) + +public: + FBrokenLines *mBroken; + unsigned int mCount; + + DBrokenLines(FBrokenLines *broken, unsigned int count) + { + mBroken = broken; + mCount = count; + } + + void OnDestroy() override + { + V_FreeBrokenLines(mBroken); + } +}; + + EXTERN_CVAR (Bool, saveloadconfirmation) // [mxd] class DMessageBoxMenu : public DMenu { DECLARE_CLASS(DMessageBoxMenu, DMenu) public: - FBrokenLines *mMessage; + DBrokenLines *mMessage; int mMessageMode; int messageSelection; int mMouseLeft, mMouseRight, mMouseY; @@ -63,9 +84,7 @@ public: public: DMessageBoxMenu(DMenu *parent = NULL, const char *message = NULL, int messagemode = 0, bool playsound = false, FName action = NAME_None, void (*hnd)() = nullptr); - void OnDestroy() override; void Init(DMenu *parent, const char *message, int messagemode, bool playsound = false, void(*hnd)() = nullptr); - void Drawer(); }; IMPLEMENT_CLASS(DMessageBoxMenu, false, false) @@ -102,7 +121,11 @@ void DMessageBoxMenu::Init(DMenu *parent, const char *message, int messagemode, if (message != NULL) { if (*message == '$') message = GStrings(message+1); - mMessage = V_BreakLines(SmallFont, 300, message); + unsigned count; + auto Message = V_BreakLines(SmallFont, 300, message, true, &count); + mMessage = new DBrokenLines(Message, count); + GC::WriteBarrier(mMessage); + mMessage->ObjectFlags |= OF_Fixed; } else mMessage = NULL; mMessageMode = messagemode; @@ -114,76 +137,6 @@ void DMessageBoxMenu::Init(DMenu *parent, const char *message, int messagemode, Handler = hnd; } -//============================================================================= -// -// -// -//============================================================================= - -void DMessageBoxMenu::OnDestroy() -{ - if (mMessage != NULL) V_FreeBrokenLines(mMessage); - mMessage = NULL; - Super::OnDestroy(); -} - -//============================================================================= -// -// -// -//============================================================================= - -void DMessageBoxMenu::Drawer () -{ - int i, y; - PalEntry fade = 0; - - int fontheight = SmallFont->GetHeight(); - //V_SetBorderNeedRefresh(); - //ST_SetNeedRefresh(); - - y = 100; - - if (mMessage != NULL) - { - for (i = 0; mMessage[i].Width >= 0; i++) - y -= SmallFont->GetHeight () / 2; - - for (i = 0; mMessage[i].Width >= 0; i++) - { - screen->DrawText (SmallFont, CR_UNTRANSLATED, 160 - mMessage[i].Width/2, y, mMessage[i].Text, - DTA_Clean, true, TAG_DONE); - y += fontheight; - } - } - - if (mMessageMode == 0) - { - y += fontheight; - mMouseY = y; - screen->DrawText(SmallFont, - messageSelection == 0? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, - 160, y, GStrings["TXT_YES"], DTA_Clean, true, TAG_DONE); - screen->DrawText(SmallFont, - messageSelection == 1? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, - 160, y + fontheight + 1, GStrings["TXT_NO"], DTA_Clean, true, TAG_DONE); - - if (messageSelection >= 0) - { - if ((MenuTime%8) < 6) - { - screen->DrawText(ConFont, OptionSettings.mFontColorSelection, - (150 - 160) * CleanXfac + screen->GetWidth() / 2, - (y + (fontheight + 1) * messageSelection - 100 + fontheight/2 - 5) * CleanYfac + screen->GetHeight() / 2, - "\xd", - DTA_CellX, 8 * CleanXfac, - DTA_CellY, 8 * CleanYfac, - TAG_DONE); - } - } - } -} - typedef void(*hfunc)(); DEFINE_ACTION_FUNCTION(DMessageBoxMenu, CallHandler) { @@ -395,3 +348,4 @@ DEFINE_FIELD(DMessageBoxMenu, mMouseRight); DEFINE_FIELD(DMessageBoxMenu, mMouseY); DEFINE_FIELD(DMessageBoxMenu, mAction); DEFINE_FIELD(DMessageBoxMenu, Handler); +DEFINE_FIELD(DMessageBoxMenu, mMessage); diff --git a/wadsrc/static/zscript/menu/messagebox.txt b/wadsrc/static/zscript/menu/messagebox.txt index f0b08eb72..f6ad0c639 100644 --- a/wadsrc/static/zscript/menu/messagebox.txt +++ b/wadsrc/static/zscript/menu/messagebox.txt @@ -34,6 +34,7 @@ class MessageBoxMenu : Menu native { + native BrokenLines mMessage; native voidptr Handler; native int mMessageMode; native int messageSelection; @@ -43,6 +44,66 @@ class MessageBoxMenu : Menu native native static void CallHandler(voidptr hnd); + //============================================================================= + // + // + // + //============================================================================= + + override void OnDestroy() + { + mMessage.Destroy(); // explicitly free the strings now. + Super.OnDestroy(); + } + + //============================================================================= + // + // + // + //============================================================================= + + override void Drawer () + { + int i, y; + + int fontheight = SmallFont.GetHeight(); + + y = 100; + + if (mMessage != NULL) + { + int c = mMessage.Count(); + for (i = 0; i < c; i++) + y -= SmallFont.GetHeight () / 2; + + for (i = 0; i < c; i++) + { + screen.DrawText (SmallFont, Font.CR_UNTRANSLATED, 160 - mMessage.StringWidth(i)/2, y, mMessage.StringAt(i), DTA_Clean, true); + y += fontheight; + } + } + + if (mMessageMode == 0) + { + y += fontheight; + mMouseY = y; + screen.DrawText(SmallFont, messageSelection == 0? OptionMenuSettings.mFontColorSelection : OptionMenuSettings.mFontColor, 160, y, Stringtable.Localize("$TXT_YES"), DTA_Clean, true); + screen.DrawText(SmallFont, messageSelection == 1? OptionMenuSettings.mFontColorSelection : OptionMenuSettings.mFontColor, 160, y + fontheight + 1, Stringtable.Localize("$TXT_NO"), DTA_Clean, true); + + if (messageSelection >= 0) + { + if ((MenuTime() % 8) < 6) + { + screen.DrawText(ConFont, OptionMenuSettings.mFontColorSelection, + (150 - 160) * CleanXfac + screen.GetWidth() / 2, + (y + (fontheight + 1) * messageSelection - 100 + fontheight/2 - 5) * CleanYfac + screen.GetHeight() / 2, + "\xd", DTA_CellX, 8 * CleanXfac, DTA_CellY, 8 * CleanYfac); + } + } + } + } + + //============================================================================= // // From e46571c192e568a773be8887b2e3ad515853c217 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 18 Feb 2017 23:39:02 +0100 Subject: [PATCH 19/22] - DMessageBoxMenu is fully scriptified. --- src/menu/messagebox.cpp | 126 ++++------------------ wadsrc/static/zscript/base.txt | 16 +-- wadsrc/static/zscript/menu/messagebox.txt | 53 +++++---- 3 files changed, 62 insertions(+), 133 deletions(-) diff --git a/src/menu/messagebox.cpp b/src/menu/messagebox.cpp index 078d7f31e..8cbaa3e24 100644 --- a/src/menu/messagebox.cpp +++ b/src/menu/messagebox.cpp @@ -46,97 +46,8 @@ #include "c_dispatch.h" #include "g_game.h" - -class DBrokenLines : public DObject -{ - DECLARE_ABSTRACT_CLASS(DBrokenLines, DObject) - -public: - FBrokenLines *mBroken; - unsigned int mCount; - - DBrokenLines(FBrokenLines *broken, unsigned int count) - { - mBroken = broken; - mCount = count; - } - - void OnDestroy() override - { - V_FreeBrokenLines(mBroken); - } -}; - - EXTERN_CVAR (Bool, saveloadconfirmation) // [mxd] -class DMessageBoxMenu : public DMenu -{ - DECLARE_CLASS(DMessageBoxMenu, DMenu) -public: - DBrokenLines *mMessage; - int mMessageMode; - int messageSelection; - int mMouseLeft, mMouseRight, mMouseY; - FName mAction; - void (*Handler)(); - -public: - - DMessageBoxMenu(DMenu *parent = NULL, const char *message = NULL, int messagemode = 0, bool playsound = false, FName action = NAME_None, void (*hnd)() = nullptr); - void Init(DMenu *parent, const char *message, int messagemode, bool playsound = false, void(*hnd)() = nullptr); -}; - -IMPLEMENT_CLASS(DMessageBoxMenu, false, false) - -//============================================================================= -// -// -// -//============================================================================= - -DMessageBoxMenu::DMessageBoxMenu(DMenu *parent, const char *message, int messagemode, bool playsound, FName action, void (*hnd)()) -: DMenu(parent) -{ - mAction = action; - messageSelection = 0; - mMouseLeft = 140; - mMouseY = INT_MIN; - int mr1 = 170 + SmallFont->StringWidth(GStrings["TXT_YES"]); - int mr2 = 170 + SmallFont->StringWidth(GStrings["TXT_NO"]); - mMouseRight = MAX(mr1, mr2); - - Init(parent, message, messagemode, playsound, hnd); -} - -//============================================================================= -// -// -// -//============================================================================= - -void DMessageBoxMenu::Init(DMenu *parent, const char *message, int messagemode, bool playsound, void (*hnd)()) -{ - mParentMenu = parent; - if (message != NULL) - { - if (*message == '$') message = GStrings(message+1); - unsigned count; - auto Message = V_BreakLines(SmallFont, 300, message, true, &count); - mMessage = new DBrokenLines(Message, count); - GC::WriteBarrier(mMessage); - mMessage->ObjectFlags |= OF_Fixed; - } - else mMessage = NULL; - mMessageMode = messagemode; - if (playsound) - { - S_StopSound (CHAN_VOICE); - S_Sound (CHAN_VOICE | CHAN_UI, "menu/prompt", snd_menuvolume, ATTN_NONE); - } - Handler = hnd; -} - typedef void(*hfunc)(); DEFINE_ACTION_FUNCTION(DMessageBoxMenu, CallHandler) { @@ -152,6 +63,23 @@ DEFINE_ACTION_FUNCTION(DMessageBoxMenu, CallHandler) // //============================================================================= +DMenu *CreateMessageBoxMenu(DMenu *parent, const char *message, int messagemode, bool playsound, FName action = NAME_None, hfunc handler = nullptr) +{ + auto c = PClass::FindClass("MessageBoxMenu"); + auto p = c->CreateNew(); + VMValue params[] = { p, parent, FString(message), messagemode, playsound, action.GetIndex(), handler }; + + auto f = dyn_cast(c->Symbols.FindSymbol("Init", false)); + GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0); + return (DMenu*)p; +} + +//============================================================================= +// +// +// +//============================================================================= + CCMD (menu_quit) { // F10 M_StartControlPanel (true); @@ -172,7 +100,7 @@ CCMD (menu_quit) } else EndString = gameinfo.quitmessages[messageindex]; - DMenu *newmenu = new DMessageBoxMenu(CurrentMenu, EndString, 0, false, NAME_None, []() + DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, EndString, 0, false, NAME_None, []() { if (!netgame) { @@ -209,7 +137,7 @@ CCMD (menu_endgame) S_Sound (CHAN_VOICE | CHAN_UI, "menu/activate", snd_menuvolume, ATTN_NONE); FString tempstring = GStrings(netgame ? "NETEND" : "ENDGAME"); - DMenu *newmenu = new DMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []() + DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []() { M_ClearMenus(); if (!netgame) @@ -258,7 +186,7 @@ CCMD (quicksave) FString tempstring; tempstring.Format(GStrings("QSPROMPT"), savegameManager.quickSaveSlot->SaveTitle.GetChars()); - DMenu *newmenu = new DMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []() + DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []() { G_SaveGame(savegameManager.quickSaveSlot->Filename.GetChars(), savegameManager.quickSaveSlot->SaveTitle.GetChars()); S_Sound(CHAN_VOICE | CHAN_UI, "menu/dismiss", snd_menuvolume, ATTN_NONE); @@ -303,7 +231,7 @@ CCMD (quickload) M_StartControlPanel(true); - DMenu *newmenu = new DMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []() + DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []() { G_LoadGame(savegameManager.quickSaveSlot->Filename.GetChars()); S_Sound(CHAN_VOICE | CHAN_UI, "menu/dismiss", snd_menuvolume, ATTN_NONE); @@ -325,7 +253,7 @@ void M_StartMessage(const char *message, int messagemode, FName action) // only play a sound if no menu was active before M_StartControlPanel(menuactive == MENU_Off); } - DMenu *newmenu = new DMessageBoxMenu(CurrentMenu, message, messagemode, false, action); + DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, message, messagemode, false, action); newmenu->mParentMenu = CurrentMenu; M_ActivateMenu(newmenu); } @@ -339,13 +267,3 @@ DEFINE_ACTION_FUNCTION(DMenu, StartMessage) M_StartMessage(msg, mode, action); return 0; } - - -DEFINE_FIELD(DMessageBoxMenu, mMessageMode); -DEFINE_FIELD(DMessageBoxMenu, messageSelection); -DEFINE_FIELD(DMessageBoxMenu, mMouseLeft); -DEFINE_FIELD(DMessageBoxMenu, mMouseRight); -DEFINE_FIELD(DMessageBoxMenu, mMouseY); -DEFINE_FIELD(DMessageBoxMenu, mAction); -DEFINE_FIELD(DMessageBoxMenu, Handler); -DEFINE_FIELD(DMessageBoxMenu, mMessage); diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 9ae86abb5..47dad06be 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -171,13 +171,6 @@ struct Screen native native static void DrawFrame(int x, int y, int w, int h); } -class BrokenLines : Object native -{ - native int Count(); - native int StringWidth(int line); - native String StringAt(int line); -} - struct Font native { enum EColorRange @@ -248,7 +241,7 @@ struct Font native native static int FindFontColor(Name color); native static Font FindFont(Name fontname); native static Font GetFont(Name fontname); - native static BrokenLines BreakLines(String text, int maxlen); + native BrokenLines BreakLines(String text, int maxlen); } struct Translation @@ -332,6 +325,13 @@ class Object native virtual void OnDestroy() {} } +class BrokenLines : Object native +{ + native int Count(); + native int StringWidth(int line); + native String StringAt(int line); +} + class Thinker : Object native { enum EStatnums diff --git a/wadsrc/static/zscript/menu/messagebox.txt b/wadsrc/static/zscript/menu/messagebox.txt index f6ad0c639..deb73046e 100644 --- a/wadsrc/static/zscript/menu/messagebox.txt +++ b/wadsrc/static/zscript/menu/messagebox.txt @@ -32,14 +32,14 @@ ** */ -class MessageBoxMenu : Menu native +class MessageBoxMenu : Menu { - native BrokenLines mMessage; - native voidptr Handler; - native int mMessageMode; - native int messageSelection; - native int mMouseLeft, mMouseRight, mMouseY; - native Name mAction; + BrokenLines mMessage; + voidptr Handler; + int mMessageMode; + int messageSelection; + int mMouseLeft, mMouseRight, mMouseY; + Name mAction; native static void CallHandler(voidptr hnd); @@ -50,12 +50,26 @@ class MessageBoxMenu : Menu native // //============================================================================= - override void OnDestroy() + void Init(Menu parent, String message, int messagemode, bool playsound = false, Name cmd = 'None', voidptr native_handler = null) { - mMessage.Destroy(); // explicitly free the strings now. - Super.OnDestroy(); + Super.Init(parent); + mAction = cmd; + messageSelection = 0; + mMouseLeft = 140; + mMouseY = 0x80000000; + int mr1 = 170 + SmallFont.StringWidth(Stringtable.Localize("$TXT_YES")); + int mr2 = 170 + SmallFont.StringWidth(Stringtable.Localize("TXT_NO")); + mMouseRight = MAX(mr1, mr2); + mParentMenu = parent; + mMessage = SmallFont.BreakLines(message, 300); + mMessageMode = messagemode; + if (playsound) + { + MenuSound ("menu/prompt"); + } + Handler = native_handler; } - + //============================================================================= // // @@ -70,17 +84,14 @@ class MessageBoxMenu : Menu native y = 100; - if (mMessage != NULL) - { - int c = mMessage.Count(); - for (i = 0; i < c; i++) - y -= SmallFont.GetHeight () / 2; + int c = mMessage.Count(); + for (i = 0; i < c; i++) + y -= SmallFont.GetHeight () / 2; - for (i = 0; i < c; i++) - { - screen.DrawText (SmallFont, Font.CR_UNTRANSLATED, 160 - mMessage.StringWidth(i)/2, y, mMessage.StringAt(i), DTA_Clean, true); - y += fontheight; - } + for (i = 0; i < c; i++) + { + screen.DrawText (SmallFont, Font.CR_UNTRANSLATED, 160 - mMessage.StringWidth(i)/2, y, mMessage.StringAt(i), DTA_Clean, true); + y += fontheight; } if (mMessageMode == 0) From 2440951811050685ca1e88280692edc6848012f7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 19 Feb 2017 00:08:30 +0100 Subject: [PATCH 20/22] -scriptified the ReadThis screen. --- src/CMakeLists.txt | 1 - src/g_level.cpp | 2 + src/g_levellocals.h | 1 + src/g_mapinfo.cpp | 1 + src/gi.cpp | 1 + src/menu/readthis.cpp | 149 ------------------------ src/scripting/thingdef_data.cpp | 5 +- wadsrc/static/zscript.txt | 1 + wadsrc/static/zscript/base.txt | 2 + wadsrc/static/zscript/menu/readthis.txt | 124 ++++++++++++++++++++ 10 files changed, 136 insertions(+), 151 deletions(-) delete mode 100644 src/menu/readthis.cpp create mode 100644 wadsrc/static/zscript/menu/readthis.txt diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7619c6334..c5149121c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -851,7 +851,6 @@ set( FASTMATH_PCH_SOURCES menu/messagebox.cpp menu/optionmenu.cpp menu/playermenu.cpp - menu/readthis.cpp menu/videomenu.cpp oplsynth/fmopl.cpp oplsynth/mlopl.cpp diff --git a/src/g_level.cpp b/src/g_level.cpp index 0842f3ec8..eafdd7209 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1461,6 +1461,7 @@ void G_InitLevelLocals () level.LevelName = level.info->LookupLevelName(); level.NextMap = info->NextMap; level.NextSecretMap = info->NextSecretMap; + level.F1Pic = info->F1Pic; compatflags.Callback(); compatflags2.Callback(); @@ -1909,6 +1910,7 @@ DEFINE_FIELD(FLevelLocals, LevelName) DEFINE_FIELD(FLevelLocals, MapName) DEFINE_FIELD(FLevelLocals, NextMap) DEFINE_FIELD(FLevelLocals, NextSecretMap) +DEFINE_FIELD(FLevelLocals, F1Pic) DEFINE_FIELD(FLevelLocals, maptype) DEFINE_FIELD(FLevelLocals, Music) DEFINE_FIELD(FLevelLocals, musicorder) diff --git a/src/g_levellocals.h b/src/g_levellocals.h index 357e2e154..1b3d1dba2 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -25,6 +25,7 @@ struct FLevelLocals FString MapName; // the lump name (E1M1, MAP01, etc) FString NextMap; // go here when using the regular exit FString NextSecretMap; // map to go to when used secret exit + FString F1Pic; EMapType maptype; TStaticArray vertexes; diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 6f2636337..f83e18ece 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -1970,6 +1970,7 @@ static void ClearMapinfo() DefaultSkill = -1; DeinitIntermissions(); level.info = NULL; + level.F1Pic = ""; } //========================================================================== diff --git a/src/gi.cpp b/src/gi.cpp index b05000d01..247036ea7 100644 --- a/src/gi.cpp +++ b/src/gi.cpp @@ -51,6 +51,7 @@ DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, ArmorIcon1) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, ArmorIcon2) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, gametype) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, norandomplayerclass) +DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, infoPages) const char *GameNames[17] = diff --git a/src/menu/readthis.cpp b/src/menu/readthis.cpp deleted file mode 100644 index 06d4620da..000000000 --- a/src/menu/readthis.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* -** readthis.cpp -** Help screens -** -**--------------------------------------------------------------------------- -** Copyright 2001-2010 Randy Heit -** Copyright 2010 Christoph Oelckers -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -*/ - -#include "menu/menu.h" -#include "v_video.h" -#include "g_level.h" -#include "gi.h" -#include "g_levellocals.h" -#include "textures/textures.h" - -class DReadThisMenu : public DMenu -{ - DECLARE_CLASS(DReadThisMenu, DMenu) - int mScreen; - int mInfoTic; - -public: - - DReadThisMenu(DMenu *parent = NULL); - void Drawer(); - bool MenuEvent(int mkey, bool fromcontroller); - bool DimAllowed () { return false; } - bool MouseEvent(int type, int x, int y); -}; - -IMPLEMENT_CLASS(DReadThisMenu, false, false) - -//============================================================================= -// -// Read This Menus -// -//============================================================================= - -DReadThisMenu::DReadThisMenu(DMenu *parent) -: DMenu(parent) -{ - mScreen = 1; - mInfoTic = gametic; -} - - -//============================================================================= -// -// -// -//============================================================================= - -void DReadThisMenu::Drawer() -{ - FTexture *tex = NULL, *prevpic = NULL; - double alpha; - - // Did the mapper choose a custom help page via MAPINFO? - if ((level.info != NULL) && level.info->F1Pic.Len() != 0) - { - tex = TexMan.FindTexture(level.info->F1Pic); - mScreen = 1; - } - - if (tex == NULL) - { - tex = TexMan[gameinfo.infoPages[mScreen-1].GetChars()]; - } - - if (mScreen > 1) - { - prevpic = TexMan[gameinfo.infoPages[mScreen-2].GetChars()]; - } - - screen->Dim(0, 1.0, 0,0, SCREENWIDTH, SCREENHEIGHT); - alpha = MIN((gametic - mInfoTic) * (3. / TICRATE), 1.); - if (alpha < 1. && prevpic != NULL) - { - screen->DrawTexture (prevpic, 0, 0, DTA_Fullscreen, true, TAG_DONE); - } - screen->DrawTexture (tex, 0, 0, DTA_Fullscreen, true, DTA_Alpha, alpha, TAG_DONE); - -} - - -//============================================================================= -// -// -// -//============================================================================= - -bool DReadThisMenu::MenuEvent(int mkey, bool fromcontroller) -{ - if (mkey == MKEY_Enter) - { - S_Sound (CHAN_VOICE | CHAN_UI, "menu/choose", snd_menuvolume, ATTN_NONE); - mScreen++; - mInfoTic = gametic; - if ((level.info != NULL && level.info->F1Pic.Len() != 0) || mScreen > int(gameinfo.infoPages.Size())) - { - Close(); - } - return true; - } - else return Super::MenuEvent(mkey, fromcontroller); -} - -//============================================================================= -// -// -// -//============================================================================= - -bool DReadThisMenu::MouseEvent(int type, int x, int y) -{ - if (type == MOUSE_Click) - { - return MenuEvent(MKEY_Enter, true); - } - return false; -} - diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index 986f0f1f2..3808194e1 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -906,7 +906,10 @@ void InitThingdef() fieldptr = new PField("OptionMenuSettings", NewStruct("FOptionMenuSettings", nullptr), VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&OptionSettings); Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); - + fieldptr = new PField("gametic", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&gametic); + Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); + + // Argh. It sucks when bad hacks need to be supported. WP_NOCHANGE is just a bogus pointer but it used everywhere as a special flag. // It cannot be defined as constant because constants can either be numbers or strings but nothing else, so the only 'solution' // is to create a static variable from it and reference that in the script. Yuck!!! diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 2bd535d77..cbe913fa3 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -22,6 +22,7 @@ #include "zscript/menu/playercontrols.txt" #include "zscript/menu/textentermenu.txt" #include "zscript/menu/videomenu.txt" +#include "zscript/menu/readthis.txt" #include "zscript/inventory/inventory.txt" #include "zscript/inventory/inv_misc.txt" diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 47dad06be..fcad86814 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -299,6 +299,7 @@ struct GameInfoStruct native native String ArmorIcon2; native int gametype; native bool norandomplayerclass; + native Array infoPages; } class Object native @@ -436,6 +437,7 @@ struct LevelLocals native native readonly String MapName; native String NextMap; native String NextSecretMap; + native String F1Pic; native readonly int maptype; native readonly String Music; native readonly int musicorder; diff --git a/wadsrc/static/zscript/menu/readthis.txt b/wadsrc/static/zscript/menu/readthis.txt new file mode 100644 index 000000000..a3db8a8a7 --- /dev/null +++ b/wadsrc/static/zscript/menu/readthis.txt @@ -0,0 +1,124 @@ +/* +** readthis.cpp +** Help screens +** +**--------------------------------------------------------------------------- +** Copyright 2001-2010 Randy Heit +** Copyright 2010 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +*/ + +class ReadThisMenu : Menu +{ + int mScreen; + int mInfoTic; + + //============================================================================= + // + // + // + //============================================================================= + + override void Drawer() + { + double alpha; + TextureID tex, prevpic; + + if (mScreen == 0) + { + mScreen = 1; + mInfoTic = gametic; + } + + // Did the mapper choose a custom help page via MAPINFO? + if (level.F1Pic.Length() != 0) + { + tex = TexMan.CheckForTexture(level.F1Pic, TexMan.Type_MiscPatch); + mScreen = 1; + } + + if (!tex.IsValid()) + { + tex = TexMan.CheckForTexture(gameinfo.infoPages[mScreen-1], TexMan.Type_MiscPatch); + } + + if (mScreen > 1) + { + prevpic = TexMan.CheckForTexture(gameinfo.infoPages[mScreen-2], TexMan.Type_MiscPatch); + } + + screen.Dim(0, 1.0, 0,0, screen.GetWidth(), screen.GetHeight()); + alpha = MIN((gametic - mInfoTic) * (3. / Thinker.TICRATE), 1.); + if (alpha < 1. && prevpic.IsValid()) + { + screen.DrawTexture (prevpic, false, 0, 0, DTA_Fullscreen, true); + } + else alpha = 1; + screen.DrawTexture (tex, false, 0, 0, DTA_Fullscreen, true, DTA_Alpha, alpha); + + } + + + //============================================================================= + // + // + // + //============================================================================= + + override bool MenuEvent(int mkey, bool fromcontroller) + { + if (mkey == MKEY_Enter) + { + MenuSound("menu/choose"); + mScreen++; + mInfoTic = gametic; + if (level.F1Pic.Length() != 0 || mScreen > gameinfo.infoPages.Size()) + { + Close(); + } + return true; + } + else return Super.MenuEvent(mkey, fromcontroller); + } + + //============================================================================= + // + // + // + //============================================================================= + + override bool MouseEvent(int type, int x, int y) + { + if (type == MOUSE_Click) + { + return MenuEvent(MKEY_Enter, true); + } + return false; + } + +} \ No newline at end of file From b1a79414140b6281e5a9eb8282b469c0a8a3e3a8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 19 Feb 2017 01:11:52 +0100 Subject: [PATCH 21/22] - some preparations of the Strife dialogue data to make it usable for ZScript, most importantly this means to replace all const char * with FString. --- src/p_conversation.cpp | 39 +++++++++++++++++---------------------- src/p_conversation.h | 15 ++++++++------- src/p_usdf.cpp | 19 ++++++++++--------- 3 files changed, 35 insertions(+), 38 deletions(-) diff --git a/src/p_conversation.cpp b/src/p_conversation.cpp index 0133ca961..3977d6a01 100644 --- a/src/p_conversation.cpp +++ b/src/p_conversation.cpp @@ -347,7 +347,7 @@ static FStrifeDialogueNode *ReadRetailNode (FileReader *lump, DWORD &prevSpeaker } // Convert the rest of the data to our own internal format. - node->Dialogue = ncopystring (speech.Dialogue); + node->Dialogue = speech.Dialogue; // The speaker's portrait, if any. speech.Dialogue[0] = 0; //speech.Backdrop[8] = 0; @@ -360,7 +360,7 @@ static FStrifeDialogueNode *ReadRetailNode (FileReader *lump, DWORD &prevSpeaker // The speaker's name, if any. speech.Sound[0] = 0; //speech.Name[16] = 0; - node->SpeakerName = ncopystring(speech.Name); + node->SpeakerName = speech.Name; // The item the speaker should drop when killed. node->DropType = dyn_cast(GetStrifeType(speech.DropType)); @@ -422,7 +422,7 @@ static FStrifeDialogueNode *ReadTeaserNode (FileReader *lump, DWORD &prevSpeaker } // Convert the rest of the data to our own internal format. - node->Dialogue = ncopystring (speech.Dialogue); + node->Dialogue = speech.Dialogue; // The Teaser version doesn't have portraits. node->Backdrop.SetInvalid(); @@ -440,7 +440,7 @@ static FStrifeDialogueNode *ReadTeaserNode (FileReader *lump, DWORD &prevSpeaker // The speaker's name, if any. speech.Dialogue[0] = 0; //speech.Name[16] = 0; - node->SpeakerName = ncopystring (speech.Name); + node->SpeakerName = speech.Name; // The item the speaker should drop when killed. node->DropType = dyn_cast(GetStrifeType (speech.DropType)); @@ -505,7 +505,7 @@ static void ParseReplies (FStrifeDialogueReply **replyptr, Response *responses) // The message to record in the log for this reply. reply->LogNumber = rsp->Log; - reply->LogString = NULL; + reply->LogString = ""; // The item to receive when this reply is used. reply->GiveType = dyn_cast(GetStrifeType (rsp->GiveType)); @@ -520,31 +520,32 @@ static void ParseReplies (FStrifeDialogueReply **replyptr, Response *responses) reply->ItemCheck[k].Item = inv; reply->ItemCheck[k].Amount = rsp->Count[k]; } + reply->PrintAmount = reply->ItemCheck[0].Amount; reply->ItemCheckRequire.Clear(); reply->ItemCheckExclude.Clear(); // If the first item check has a positive amount required, then // add that to the reply string. Otherwise, use the reply as-is. - reply->Reply = copystring (rsp->Reply); + reply->Reply = rsp->Reply; reply->NeedsGold = (rsp->Count[0] > 0); // QuickYes messages are shown when you meet the item checks. // QuickNo messages are shown when you don't. if (rsp->Yes[0] == '_' && rsp->Yes[1] == 0) { - reply->QuickYes = NULL; + reply->QuickYes = ""; } else { - reply->QuickYes = ncopystring (rsp->Yes); + reply->QuickYes = rsp->Yes; } if (reply->ItemCheck[0].Item != 0) { - reply->QuickNo = ncopystring (rsp->No); + reply->QuickNo = rsp->No; } else { - reply->QuickNo = NULL; + reply->QuickNo = ""; } reply->Next = *replyptr; *replyptr = reply; @@ -560,9 +561,6 @@ static void ParseReplies (FStrifeDialogueReply **replyptr, Response *responses) FStrifeDialogueNode::~FStrifeDialogueNode () { - if (SpeakerName != NULL) delete[] SpeakerName; - if (Dialogue != NULL) delete[] Dialogue; - if (Goodbye != nullptr) delete[] Goodbye; FStrifeDialogueReply *tokill = Children; while (tokill != NULL) { @@ -580,9 +578,6 @@ FStrifeDialogueNode::~FStrifeDialogueNode () FStrifeDialogueReply::~FStrifeDialogueReply () { - if (Reply != NULL) delete[] Reply; - if (QuickYes != NULL) delete[] QuickYes; - if (QuickNo != NULL) delete[] QuickNo; } //============================================================================ @@ -672,7 +667,7 @@ CUSTOM_CVAR(Float, dlg_musicvolume, 1.0f, CVAR_ARCHIVE) static bool ShouldSkipReply(FStrifeDialogueReply *reply, player_t *player) { - if (reply->Reply == nullptr) + if (reply->Reply.IsEmpty()) return true; int i; @@ -772,7 +767,7 @@ public: ReplyText = GStrings(ReplyText + 1); } FString ReplyString = ReplyText; - if (reply->NeedsGold) ReplyString.AppendFormat(" for %u", reply->ItemCheck[0].Amount); + if (reply->NeedsGold) ReplyString.AppendFormat(" for %u", reply->PrintAmount); FBrokenLines *ReplyLines = V_BreakLines (SmallFont, 320-50-10, ReplyString); @@ -785,7 +780,7 @@ public: V_FreeBrokenLines (ReplyLines); } const char *goodbyestr = CurNode->Goodbye; - if (goodbyestr == nullptr) + if (*goodbyestr == 0) { char goodbye[25]; mysnprintf(goodbye, countof(goodbye), "TXT_RANDOMGOODBYE_%d", 1 + (pr_randomspeech() % NUM_RANDOM_GOODBYES)); @@ -1012,7 +1007,7 @@ public: linesize = 10 * CleanYfac; // Who is talking to you? - if (CurNode->SpeakerName != NULL) + if (CurNode->SpeakerName.IsNotEmpty()) { speakerName = CurNode->SpeakerName; if (speakerName[0] == '$') speakerName = GStrings(speakerName+1); @@ -1315,7 +1310,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply if (!CheckStrifeItem(player, reply->ItemCheck[i].Item, reply->ItemCheck[i].Amount)) { // No, you don't. Say so and let the NPC animate negatively. - if (reply->QuickNo && isconsole) + if (reply->QuickNo.IsNotEmpty() && isconsole) { TerminalResponse(reply->QuickNo); } @@ -1396,7 +1391,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply } // Update the quest log, if needed. - if (reply->LogString != NULL) + if (reply->LogString.IsNotEmpty()) { const char *log = reply->LogString; if (log[0] == '$') diff --git a/src/p_conversation.h b/src/p_conversation.h index 8771d95ae..c10c4c697 100644 --- a/src/p_conversation.h +++ b/src/p_conversation.h @@ -26,11 +26,11 @@ struct FStrifeDialogueNode int ItemCheckNode; // index into StrifeDialogues PClassActor *SpeakerType; - char *SpeakerName; + FString SpeakerName; FSoundID SpeakerVoice; FTextureID Backdrop; - char *Dialogue; - char *Goodbye = nullptr; // must init to null for binary scripts to work as intended + FString Dialogue; + FString Goodbye; // must init to null for binary scripts to work as intended FStrifeDialogueReply *Children; }; @@ -44,15 +44,16 @@ struct FStrifeDialogueReply PClassActor *GiveType; int ActionSpecial; int Args[5]; + int PrintAmount; TArray ItemCheck; TArray ItemCheckRequire; TArray ItemCheckExclude; - char *Reply; - char *QuickYes; + FString Reply; + FString QuickYes; + FString QuickNo; + FString LogString; int NextNode; // index into StrifeDialogues int LogNumber; - char *LogString; - char *QuickNo; bool NeedsGold; }; diff --git a/src/p_usdf.cpp b/src/p_usdf.cpp index f4ebe5ebd..b8e290deb 100644 --- a/src/p_usdf.cpp +++ b/src/p_usdf.cpp @@ -232,20 +232,21 @@ class USDFParser : public UDMFParserBase // Todo: Finalize if (reply->ItemCheck.Size() > 0) { - if (reply->ItemCheck[0].Amount <= 0) reply->NeedsGold = false; + reply->PrintAmount = reply->ItemCheck[0].Amount; + if (reply->PrintAmount <= 0) reply->NeedsGold = false; } - reply->Reply = ncopystring(ReplyString); - reply->QuickYes = ncopystring(QuickYes); + reply->Reply = ReplyString; + reply->QuickYes = QuickYes; if (reply->ItemCheck.Size() > 0 && reply->ItemCheck[0].Item != NULL) { - reply->QuickNo = ncopystring(QuickNo); + reply->QuickNo = QuickNo; } else { - reply->QuickNo = NULL; + reply->QuickNo = ""; } - reply->LogString = ncopystring(LogString); + reply->LogString = LogString; if(!closeDialog) reply->NextNode *= -1; return true; } @@ -373,9 +374,9 @@ class USDFParser : public UDMFParserBase } } } - node->SpeakerName = ncopystring(SpeakerName); - node->Dialogue = ncopystring(Dialogue); - node->Goodbye = ncopystring(Goodbye); + node->SpeakerName = SpeakerName; + node->Dialogue = Dialogue; + node->Goodbye = Goodbye; return true; } From c0dd37e16eb0a7ce24d2ffbebed4f5c65bf91c0f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 19 Feb 2017 01:14:31 +0100 Subject: [PATCH 22/22] - ncopystring is not needed anymore. --- src/cmdlib.cpp | 17 ----------------- src/cmdlib.h | 1 - 2 files changed, 18 deletions(-) diff --git a/src/cmdlib.cpp b/src/cmdlib.cpp index f7fb94510..471c02cc8 100644 --- a/src/cmdlib.cpp +++ b/src/cmdlib.cpp @@ -95,23 +95,6 @@ char *copystring (const char *s) return b; } -//============================================================================ -// -// ncopystring -// -// If the string has no content, returns NULL. Otherwise, returns a copy. -// -//============================================================================ - -char *ncopystring (const char *string) -{ - if (string == NULL || string[0] == 0) - { - return NULL; - } - return copystring (string); -} - //========================================================================== // // ReplaceString diff --git a/src/cmdlib.h b/src/cmdlib.h index 6e9fcd622..7af4e630b 100644 --- a/src/cmdlib.h +++ b/src/cmdlib.h @@ -38,7 +38,6 @@ int ParseHex(const char *str, FScriptPosition *sc = nullptr); bool IsNum (const char *str); // [RH] added char *copystring(const char *s); -char *ncopystring(const char *s); void ReplaceString (char **ptr, const char *str); bool CheckWildcards (const char *pattern, const char *text);