From 7efa9cd70d47ffea20b69d705db7017eba20cfb5 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 9 Feb 2017 20:18:53 +0100 Subject: [PATCH] - made the menu descriptors garbage collectable and started exporting some fields as preparation for script work on the menu. --- src/dobjgc.cpp | 8 - src/menu/colorpickermenu.cpp | 8 +- src/menu/joystickmenu.cpp | 16 +- src/menu/listmenu.cpp | 13 +- src/menu/loadsavemenu.cpp | 12 +- src/menu/menu.cpp | 101 ++++++++---- src/menu/menu.h | 63 ++++---- src/menu/menudef.cpp | 229 +++++++++++++--------------- src/menu/optionmenu.cpp | 10 +- src/menu/optionmenuitems.h | 20 +-- src/menu/playerdisplay.cpp | 2 +- src/menu/playermenu.cpp | 4 +- src/menu/videomenu.cpp | 18 +-- wadsrc/static/zscript.txt | 2 +- wadsrc/static/zscript/menu/menu.txt | 67 ++++++++ 15 files changed, 333 insertions(+), 240 deletions(-) diff --git a/src/dobjgc.cpp b/src/dobjgc.cpp index 8e93339344..8ac991aa82 100644 --- a/src/dobjgc.cpp +++ b/src/dobjgc.cpp @@ -254,14 +254,6 @@ static DObject **SweepList(DObject **p, size_t count, size_t *finalize_count) curr->Destroy(); } - /* - if (curr->IsKindOf(RUNTIME_CLASS(PSymbol))) - Printf("Collecting %s, name = %s\n", curr->GetClass()->TypeName.GetChars(), static_cast(curr)->SymbolName.GetChars()); - else if (curr->IsKindOf(RUNTIME_CLASS(PType))) - Printf("Collecting %s, name = %s\n", curr->GetClass()->TypeName.GetChars(), static_cast(curr)->DescriptiveName()); - else - Printf("Collecting %s\n", curr->GetClass()->TypeName.GetChars()); - */ curr->ObjectFlags |= OF_Cleanup; delete curr; finalized++; diff --git a/src/menu/colorpickermenu.cpp b/src/menu/colorpickermenu.cpp index df96b37a02..def67d44ba 100644 --- a/src/menu/colorpickermenu.cpp +++ b/src/menu/colorpickermenu.cpp @@ -68,7 +68,7 @@ class DColorPickerMenu : public DOptionMenu public: - DColorPickerMenu(DMenu *parent, const char *name, FOptionMenuDescriptor *desc, FColorCVar *cvar) + DColorPickerMenu(DMenu *parent, const char *name, DOptionMenuDescriptor *desc, FColorCVar *cvar) { mStartItem = desc->mItems.Size(); mRed = (float)RPART(DWORD(*cvar)); @@ -344,10 +344,10 @@ CCMD(undocolorpic) DMenu *StartPickerMenu(DMenu *parent, const char *name, FColorCVar *cvar) { - FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Colorpickermenu); - if (desc != NULL && (*desc)->mType == MDESC_OptionsMenu) + DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Colorpickermenu); + if (desc != NULL && (*desc)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor))) { - return new DColorPickerMenu(parent, name, (FOptionMenuDescriptor*)(*desc), cvar); + return new DColorPickerMenu(parent, name, (DOptionMenuDescriptor*)(*desc), cvar); } else { diff --git a/src/menu/joystickmenu.cpp b/src/menu/joystickmenu.cpp index 21bb370b4a..61f81bb604 100644 --- a/src/menu/joystickmenu.cpp +++ b/src/menu/joystickmenu.cpp @@ -58,7 +58,7 @@ static TArray Joysticks; IJoystickConfig *SELECTED_JOYSTICK; -FOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy); +DOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy); //============================================================================= // @@ -271,12 +271,12 @@ IMPLEMENT_CLASS(DOptionMenuItemJoyConfigMenu, false, false) * *=======================================*/ -FOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy) +DOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy) { - FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_JoystickConfigMenu); - if (desc != NULL && (*desc)->mType == MDESC_OptionsMenu) + DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_JoystickConfigMenu); + if (desc != NULL && (*desc)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor))) { - FOptionMenuDescriptor *opt = (FOptionMenuDescriptor *)*desc; + DOptionMenuDescriptor *opt = (DOptionMenuDescriptor *)*desc; DOptionMenuItem *it; opt->mItems.Clear(); if (joy == NULL) @@ -340,10 +340,10 @@ FOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy) void UpdateJoystickMenu(IJoystickConfig *selected) { - FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_JoystickOptions); - if (desc != NULL && (*desc)->mType == MDESC_OptionsMenu) + DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_JoystickOptions); + if (desc != NULL && (*desc)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor))) { - FOptionMenuDescriptor *opt = (FOptionMenuDescriptor *)*desc; + DOptionMenuDescriptor *opt = (DOptionMenuDescriptor *)*desc; DOptionMenuItem *it; opt->mItems.Clear(); diff --git a/src/menu/listmenu.cpp b/src/menu/listmenu.cpp index 020a540c54..2ade7d2201 100644 --- a/src/menu/listmenu.cpp +++ b/src/menu/listmenu.cpp @@ -54,7 +54,7 @@ IMPLEMENT_POINTERS_END // //============================================================================= -DListMenu::DListMenu(DMenu *parent, FListMenuDescriptor *desc) +DListMenu::DListMenu(DMenu *parent, DListMenuDescriptor *desc) : DMenu(parent) { mDesc = NULL; @@ -67,7 +67,7 @@ DListMenu::DListMenu(DMenu *parent, FListMenuDescriptor *desc) // //============================================================================= -void DListMenu::Init(DMenu *parent, FListMenuDescriptor *desc) +void DListMenu::Init(DMenu *parent, DListMenuDescriptor *desc) { mParentMenu = parent; GC::WriteBarrier(this, parent); @@ -359,6 +359,15 @@ bool DMenuItemBase::MenuEvent(int mkey, bool fromcontroller) return false; } +DEFINE_ACTION_FUNCTION(DMenuItemBase, MenuEvent) +{ + PARAM_SELF_PROLOGUE(DMenuItemBase); + PARAM_INT(key); + PARAM_BOOL(fromcontroller); + ACTION_RETURN_BOOL(self->MenuEvent(key, fromcontroller)); +} + + bool DMenuItemBase::MouseEvent(int type, int x, int y) { return false; diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index 457b020b45..8d9dc15e94 100644 --- a/src/menu/loadsavemenu.cpp +++ b/src/menu/loadsavemenu.cpp @@ -102,7 +102,7 @@ protected: bool mEntering; char savegamestring[SAVESTRINGSIZE]; - DLoadSaveMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); + DLoadSaveMenu(DMenu *parent = NULL, DListMenuDescriptor *desc = NULL); void OnDestroy() override; int RemoveSaveSlot (int index); @@ -432,7 +432,7 @@ void M_NotifyNewSave (const char *file, const char *title, bool okForQuicksave) // //============================================================================= -DLoadSaveMenu::DLoadSaveMenu(DMenu *parent, FListMenuDescriptor *desc) +DLoadSaveMenu::DLoadSaveMenu(DMenu *parent, DListMenuDescriptor *desc) : DListMenu(parent, desc) { ReadSaveStrings(); @@ -927,7 +927,7 @@ class DSaveMenu : public DLoadSaveMenu public: - DSaveMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); + DSaveMenu(DMenu *parent = NULL, DListMenuDescriptor *desc = NULL); void OnDestroy() override; void DoSave (FSaveGameNode *node); bool Responder (event_t *ev); @@ -944,7 +944,7 @@ IMPLEMENT_CLASS(DSaveMenu, false, false) // //============================================================================= -DSaveMenu::DSaveMenu(DMenu *parent, FListMenuDescriptor *desc) +DSaveMenu::DSaveMenu(DMenu *parent, DListMenuDescriptor *desc) : DLoadSaveMenu(parent, desc) { strcpy (NewSaveNode.Title, GStrings["NEWSAVE"]); @@ -1099,7 +1099,7 @@ class DLoadMenu : public DLoadSaveMenu public: - DLoadMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); + DLoadMenu(DMenu *parent = NULL, DListMenuDescriptor *desc = NULL); bool MenuEvent (int mkey, bool fromcontroller); }; @@ -1113,7 +1113,7 @@ IMPLEMENT_CLASS(DLoadMenu, false, false) // //============================================================================= -DLoadMenu::DLoadMenu(DMenu *parent, FListMenuDescriptor *desc) +DLoadMenu::DLoadMenu(DMenu *parent, DListMenuDescriptor *desc) : DLoadSaveMenu(parent, desc) { TopItem = 0; diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index c047a145da..c3bc81a108 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -91,13 +91,18 @@ static bool MenuEnabled = true; // //============================================================================ -size_t FListMenuDescriptor::PropagateMark() +IMPLEMENT_CLASS(DMenuDescriptor, false, false) +IMPLEMENT_CLASS(DListMenuDescriptor, false, false) +IMPLEMENT_CLASS(DOptionMenuDescriptor, false, false) + + +size_t DListMenuDescriptor::PropagateMark() { for (auto item : mItems) GC::Mark(item); return 0; } -size_t FOptionMenuDescriptor::PropagateMark() +size_t DOptionMenuDescriptor::PropagateMark() { for (auto item : mItems) GC::Mark(item); return 0; @@ -109,8 +114,7 @@ void M_MarkMenus() MenuDescriptorList::Pair *pair; while (it.NextPair(pair)) { - //GC::Mark(pair->Value); // once the descriptors have been made objects. - pair->Value->PropagateMark(); + GC::Mark(pair->Value); } GC::Mark(DMenu::CurrentMenu); } @@ -189,13 +193,21 @@ bool DMenu::MenuEvent (int mkey, bool fromcontroller) { Close(); S_Sound (CHAN_VOICE | CHAN_UI, - DMenu::CurrentMenu != NULL? "menu/backup" : "menu/clear", snd_menuvolume, ATTN_NONE); + DMenu::CurrentMenu != nullptr? "menu/backup" : "menu/clear", snd_menuvolume, ATTN_NONE); return true; } } return false; } +DEFINE_ACTION_FUNCTION(DMenu, MenuEvent) +{ + PARAM_SELF_PROLOGUE(DMenu); + PARAM_INT(key); + PARAM_BOOL(fromcontroller); + ACTION_RETURN_BOOL(self->MenuEvent(key, fromcontroller)); +} + //============================================================================= // // @@ -207,7 +219,7 @@ void DMenu::Close () assert(DMenu::CurrentMenu == this); DMenu::CurrentMenu = mParentMenu; Destroy(); - if (DMenu::CurrentMenu != NULL) + if (DMenu::CurrentMenu != nullptr) { GC::WriteBarrier(DMenu::CurrentMenu); } @@ -239,7 +251,7 @@ bool DMenu::MouseEventBack(int type, int x, int y) if (m_show_backbutton >= 0) { FTexture *tex = TexMan(gameinfo.mBackButton); - if (tex != NULL) + if (tex != nullptr) { if (m_show_backbutton&1) x -= screen->GetWidth() - tex->GetScaledWidth() * CleanXfac; if (m_show_backbutton&2) y -= screen->GetHeight() - tex->GetScaledHeight() * CleanYfac; @@ -329,7 +341,7 @@ bool DMenu::TranslateKeyboardEvents() void M_StartControlPanel (bool makeSound) { // intro might call this repeatedly - if (DMenu::CurrentMenu != NULL) + if (DMenu::CurrentMenu != nullptr) return; ResetButtonStates (); @@ -361,7 +373,7 @@ void M_StartControlPanel (bool makeSound) void M_ActivateMenu(DMenu *menu) { if (menuactive == MENU_Off) menuactive = MENU_On; - if (DMenu::CurrentMenu != NULL) DMenu::CurrentMenu->ReleaseCapture(); + if (DMenu::CurrentMenu != nullptr) DMenu::CurrentMenu->ReleaseCapture(); DMenu::CurrentMenu = menu; GC::WriteBarrier(DMenu::CurrentMenu); } @@ -382,7 +394,7 @@ void M_SetMenu(FName menu, int param) GameStartupInfo.Skill = -1; GameStartupInfo.Episode = -1; GameStartupInfo.PlayerClass = - param == -1000? NULL : + param == -1000? nullptr : param == -1? "Random" : GetPrintableDisplayName(PlayerClasses[param].Type).GetChars(); break; @@ -437,8 +449,8 @@ void M_SetMenu(FName menu, int param) // End of special checks - FMenuDescriptor **desc = MenuDescriptors.CheckKey(menu); - if (desc != NULL) + DMenuDescriptor **desc = MenuDescriptors.CheckKey(menu); + if (desc != nullptr) { if ((*desc)->mNetgameMessage.IsNotEmpty() && netgame && !demoplayback) { @@ -446,9 +458,9 @@ void M_SetMenu(FName menu, int param) return; } - if ((*desc)->mType == MDESC_ListMenu) + if ((*desc)->IsKindOf(RUNTIME_CLASS(DListMenuDescriptor))) { - FListMenuDescriptor *ld = static_cast(*desc); + DListMenuDescriptor *ld = static_cast(*desc); if (ld->mAutoselect >= 0 && ld->mAutoselect < (int)ld->mItems.Size()) { // recursively activate the autoselected item without ever creating this menu. @@ -456,17 +468,17 @@ void M_SetMenu(FName menu, int param) } else { - const PClass *cls = ld->mClass == NULL? RUNTIME_CLASS(DListMenu) : ld->mClass; + const PClass *cls = ld->mClass == nullptr? RUNTIME_CLASS(DListMenu) : ld->mClass; DListMenu *newmenu = (DListMenu *)cls->CreateNew(); newmenu->Init(DMenu::CurrentMenu, ld); M_ActivateMenu(newmenu); } } - else if ((*desc)->mType == MDESC_OptionsMenu) + else if ((*desc)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor))) { - FOptionMenuDescriptor *ld = static_cast(*desc); - const PClass *cls = ld->mClass == NULL? RUNTIME_CLASS(DOptionMenu) : ld->mClass; + DOptionMenuDescriptor *ld = static_cast(*desc); + const PClass *cls = ld->mClass == nullptr? RUNTIME_CLASS(DOptionMenu) : ld->mClass; DOptionMenu *newmenu = (DOptionMenu *)cls->CreateNew(); newmenu->Init(DMenu::CurrentMenu, ld); @@ -477,7 +489,7 @@ void M_SetMenu(FName menu, int param) else { const PClass *menuclass = PClass::FindClass(menu); - if (menuclass != NULL) + if (menuclass != nullptr) { if (menuclass->IsDescendantOf(RUNTIME_CLASS(DMenu))) { @@ -510,7 +522,7 @@ bool M_Responder (event_t *ev) return false; } - if (DMenu::CurrentMenu != NULL && menuactive != MENU_Off) + if (DMenu::CurrentMenu != nullptr && menuactive != MENU_Off) { // There are a few input sources we are interested in: // @@ -670,7 +682,7 @@ bool M_Responder (event_t *ev) // what it's bound to. (for those who don't bother to read the docs) if (devparm && ev->data1 == KEY_F1) { - G_ScreenShot(NULL); + G_ScreenShot(nullptr); return true; } return false; @@ -695,7 +707,7 @@ bool M_Responder (event_t *ev) void M_Ticker (void) { DMenu::MenuTime++; - if (DMenu::CurrentMenu != NULL && menuactive != MENU_Off) + if (DMenu::CurrentMenu != nullptr && menuactive != MENU_Off) { DMenu::CurrentMenu->Ticker(); @@ -736,9 +748,9 @@ void M_Drawer (void) AActor *camera = player->camera; PalEntry fade = 0; - if (!screen->Accel2D && camera != NULL && (gamestate == GS_LEVEL || gamestate == GS_TITLELEVEL)) + if (!screen->Accel2D && camera != nullptr && (gamestate == GS_LEVEL || gamestate == GS_TITLELEVEL)) { - if (camera->player != NULL) + if (camera->player != nullptr) { player = camera->player; } @@ -746,7 +758,7 @@ void M_Drawer (void) } - if (DMenu::CurrentMenu != NULL && menuactive != MENU_Off) + if (DMenu::CurrentMenu != nullptr && menuactive != MENU_Off) { if (DMenu::CurrentMenu->DimAllowed()) { @@ -766,10 +778,10 @@ void M_Drawer (void) void M_ClearMenus () { M_DemoNoPlay = false; - if (DMenu::CurrentMenu != NULL) + if (DMenu::CurrentMenu != nullptr) { DMenu::CurrentMenu->Destroy(); - DMenu::CurrentMenu = NULL; + DMenu::CurrentMenu = nullptr; } V_SetBorderNeedRefresh(); menuactive = MENU_Off; @@ -1002,3 +1014,38 @@ CCMD(reset2saved) GameConfig->DoModSetup (gameinfo.ConfigName); R_SetViewSize (screenblocks); } + + + +//native void OptionMenuDescriptor.CalcIndent(); +//native OptionMenuItem OptionMenuDescriptor.GetItem(Name iname); +//native void OptionMenuItem.drawLabel(int indent, int y, EColorRange color, bool grayed = false); + +DEFINE_FIELD(DMenuDescriptor, mMenuName) +DEFINE_FIELD(DMenuDescriptor, mNetgameMessage) +DEFINE_FIELD(DMenuDescriptor, mClass) + +DEFINE_FIELD(DMenuItemBase, mXpos) +DEFINE_FIELD(DMenuItemBase, mYpos) +DEFINE_FIELD(DMenuItemBase, mAction) +DEFINE_FIELD(DMenuItemBase, mEnabled) + +DEFINE_FIELD(DOptionMenuDescriptor, mItems) +DEFINE_FIELD(DOptionMenuDescriptor, mTitle) +DEFINE_FIELD(DOptionMenuDescriptor, mSelectedItem) +DEFINE_FIELD(DOptionMenuDescriptor, mDrawTop) +DEFINE_FIELD(DOptionMenuDescriptor, mScrollTop) +DEFINE_FIELD(DOptionMenuDescriptor, mScrollPos) +DEFINE_FIELD(DOptionMenuDescriptor, mIndent) +DEFINE_FIELD(DOptionMenuDescriptor, mPosition) +DEFINE_FIELD(DOptionMenuDescriptor, mDontDim) + +DEFINE_FIELD(DOptionMenuItem, mLabel) +DEFINE_FIELD(DOptionMenuItem, mCentered) + +DEFINE_FIELD(DOptionMenu, CanScrollUp) +DEFINE_FIELD(DOptionMenu, CanScrollDown) +DEFINE_FIELD(DOptionMenu, VisBottom) +DEFINE_FIELD(DOptionMenu, mFocusControl) +DEFINE_FIELD(DOptionMenu, mDesc) + diff --git a/src/menu/menu.h b/src/menu/menu.h index 23a4e87187..854eab43f5 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -75,28 +75,25 @@ struct FSaveGameNode // //============================================================================= -enum EMenuDescriptorType -{ - MDESC_ListMenu, - MDESC_OptionsMenu, -}; - -struct FMenuDescriptor +class DMenuDescriptor : public DObject { + DECLARE_CLASS(DMenuDescriptor, DObject) +public: FName mMenuName; FString mNetgameMessage; - int mType; const PClass *mClass; - virtual ~FMenuDescriptor() {} virtual size_t PropagateMark() { return 0; } }; class DMenuItemBase; class DOptionMenuItem; -struct FListMenuDescriptor : public FMenuDescriptor +class DListMenuDescriptor : public DMenuDescriptor { + DECLARE_CLASS(DListMenuDescriptor, DMenuDescriptor) + +public: TArray mItems; int mSelectedItem; int mSelectOfsX; @@ -110,7 +107,6 @@ struct FListMenuDescriptor : public FMenuDescriptor FFont *mFont; EColorRange mFontColor; EColorRange mFontColor2; - FMenuDescriptor *mRedirect; // used to redirect overlong skill and episode menus to option menu based alternatives bool mCenter; void Reset() @@ -144,8 +140,11 @@ struct FOptionMenuSettings int mLinespacing; }; -struct FOptionMenuDescriptor : public FMenuDescriptor +class DOptionMenuDescriptor : public DMenuDescriptor { + DECLARE_CLASS(DOptionMenuDescriptor, DMenuDescriptor) + +public: TArray mItems; FString mTitle; int mSelectedItem; @@ -167,10 +166,13 @@ struct FOptionMenuDescriptor : public FMenuDescriptor mDontDim = 0; } size_t PropagateMark() override; + ~DOptionMenuDescriptor() + { + } }; -typedef TMap MenuDescriptorList; +typedef TMap MenuDescriptorList; extern FOptionMenuSettings OptionSettings; extern MenuDescriptorList MenuDescriptors; @@ -258,11 +260,10 @@ public: class DMenuItemBase : public DObject { DECLARE_CLASS(DMenuItemBase, DObject) -protected: +public: int mXpos, mYpos; FName mAction; -public: bool mEnabled; DMenuItemBase(int xpos = 0, int ypos = 0, FName action = NAME_None) @@ -333,7 +334,7 @@ class DListMenuItemPlayerDisplay : public DMenuItemBase { DECLARE_CLASS(DListMenuItemPlayerDisplay, DMenuItemBase) - FListMenuDescriptor *mOwner; + DListMenuDescriptor *mOwner; FTexture *mBackdrop; FRemapTable mRemap; FPlayerClass *mPlayerClass; @@ -365,7 +366,7 @@ public: PDF_TRANSLATE = 0x10005, }; - DListMenuItemPlayerDisplay(FListMenuDescriptor *menu, int x, int y, PalEntry c1, PalEntry c2, bool np, FName action); + DListMenuItemPlayerDisplay(DListMenuDescriptor *menu, int x, int y, PalEntry c1, PalEntry c2, bool np, FName action); void OnDestroy() override; virtual void Ticker(); virtual void Drawer(bool selected); @@ -513,7 +514,7 @@ public: //============================================================================= // -// list menu class runs a menu described by a FListMenuDescriptor +// list menu class runs a menu described by a DListMenuDescriptor // //============================================================================= @@ -523,12 +524,12 @@ class DListMenu : public DMenu HAS_OBJECT_POINTERS; protected: - FListMenuDescriptor *mDesc; + DListMenuDescriptor *mDesc; DMenuItemBase *mFocusControl; public: - DListMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); - virtual void Init(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); + 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); @@ -559,12 +560,11 @@ public: class DOptionMenuItem : public DMenuItemBase { DECLARE_ABSTRACT_CLASS(DOptionMenuItem, DMenuItemBase) -protected: +public: FString mLabel; bool mCentered; void drawLabel(int indent, int y, EColorRange color, bool grayed = false); -public: DOptionMenuItem(const char *text = nullptr, FName action = NAME_None, bool center = false) : DMenuItemBase(0, 0, action) @@ -573,7 +573,7 @@ public: mCentered = center; } - virtual int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected); + virtual int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected); virtual bool Selectable(); virtual int GetIndent(); virtual bool MouseEvent(int type, int x, int y); @@ -603,7 +603,7 @@ extern FOptionMap OptionValues; //============================================================================= // -// Option menu class runs a menu described by a FOptionMenuDescriptor +// Option menu class runs a menu described by a DOptionMenuDescriptor // //============================================================================= @@ -612,25 +612,24 @@ class DOptionMenu : public DMenu DECLARE_CLASS(DOptionMenu, DMenu) HAS_OBJECT_POINTERS; +public: // needs to be public for script access bool CanScrollUp; bool CanScrollDown; int VisBottom; DOptionMenuItem *mFocusControl; + DOptionMenuDescriptor *mDesc; -protected: - FOptionMenuDescriptor *mDesc; - -public: +//public: DOptionMenuItem *GetItem(FName name); - DOptionMenu(DMenu *parent = NULL, FOptionMenuDescriptor *desc = NULL); - virtual void Init(DMenu *parent = NULL, FOptionMenuDescriptor *desc = NULL); + DOptionMenu(DMenu *parent = NULL, DOptionMenuDescriptor *desc = NULL); + virtual void Init(DMenu *parent = NULL, DOptionMenuDescriptor *desc = NULL); int FirstSelectable(); bool Responder (event_t *ev); bool MenuEvent (int mkey, bool fromcontroller); bool MouseEvent(int type, int x, int y); void Ticker (); void Drawer (); - const FOptionMenuDescriptor *GetDescriptor() const { return mDesc; } + const DOptionMenuDescriptor *GetDescriptor() const { return mDesc; } void SetFocus(DOptionMenuItem *fc) { mFocusControl = fc; diff --git a/src/menu/menudef.cpp b/src/menu/menudef.cpp index efb444d5c2..835189317e 100644 --- a/src/menu/menudef.cpp +++ b/src/menu/menudef.cpp @@ -57,8 +57,8 @@ void ClearSaveGames(); MenuDescriptorList MenuDescriptors; -static FListMenuDescriptor DefaultListMenuSettings; // contains common settings for all list menus -static FOptionMenuDescriptor DefaultOptionMenuSettings; // contains common settings for all Option menus +static DListMenuDescriptor *DefaultListMenuSettings; // contains common settings for all list menus +static DOptionMenuDescriptor *DefaultOptionMenuSettings; // contains common settings for all Option menus FOptionMenuSettings OptionSettings; FOptionMap OptionValues; bool mustPrintErrors; @@ -67,18 +67,6 @@ void I_BuildALDeviceList(FOptionValues *opt); static void DeinitMenus() { - { - MenuDescriptorList::Iterator it(MenuDescriptors); - - MenuDescriptorList::Pair *pair; - - while (it.NextPair(pair)) - { - delete pair->Value; - pair->Value = NULL; - } - } - { FOptionMap::Iterator it(OptionValues); @@ -87,13 +75,12 @@ static void DeinitMenus() while (it.NextPair(pair)) { delete pair->Value; - pair->Value = NULL; + pair->Value = nullptr; } } MenuDescriptors.Clear(); OptionValues.Clear(); - DMenu::CurrentMenu = NULL; - DefaultListMenuSettings.mItems.Clear(); + DMenu::CurrentMenu = nullptr; ClearSaveGames(); } @@ -210,7 +197,7 @@ static bool CheckSkipOptionBlock(FScanner &sc) // //============================================================================= -static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) +static void ParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc) { sc.MustGetStringName("{"); while (!sc.CheckString("}")) @@ -240,7 +227,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) { sc.MustGetString(); const PClass *cls = PClass::FindClass(sc.String); - if (cls == NULL || !cls->IsDescendantOf(RUNTIME_CLASS(DListMenu))) + if (cls == nullptr || !cls->IsDescendantOf(RUNTIME_CLASS(DListMenu))) { sc.ScriptError("Unknown menu class '%s'", sc.String); } @@ -367,7 +354,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) { sc.MustGetString(); FFont *newfont = V_GetFont(sc.String); - if (newfont != NULL) desc->mFont = newfont; + if (newfont != nullptr) desc->mFont = newfont; if (sc.CheckString(",")) { sc.MustGetString(); @@ -400,10 +387,10 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) int y = sc.Number; sc.MustGetStringName(","); sc.MustGetString(); - PalEntry c1 = V_GetColor(NULL, sc); + PalEntry c1 = V_GetColor(nullptr, sc); sc.MustGetStringName(","); sc.MustGetString(); - PalEntry c2 = V_GetColor(NULL, sc); + PalEntry c2 = V_GetColor(nullptr, sc); if (sc.CheckString(",")) { sc.MustGetNumber(); @@ -487,28 +474,25 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc) // //============================================================================= -static bool CheckCompatible(FMenuDescriptor *newd, FMenuDescriptor *oldd) +static bool CheckCompatible(DMenuDescriptor *newd, DMenuDescriptor *oldd) { - if (oldd->mClass == NULL) return true; + if (oldd->mClass == nullptr) return true; return oldd->mClass == newd->mClass; } -static bool ReplaceMenu(FScanner &sc, FMenuDescriptor *desc) +static bool ReplaceMenu(FScanner &sc, DMenuDescriptor *desc) { - FMenuDescriptor **pOld = MenuDescriptors.CheckKey(desc->mMenuName); - if (pOld != NULL && *pOld != NULL) + DMenuDescriptor **pOld = MenuDescriptors.CheckKey(desc->mMenuName); + if (pOld != nullptr && *pOld != nullptr) { - if (CheckCompatible(desc, *pOld)) - { - delete *pOld; - } - else + if (!CheckCompatible(desc, *pOld)) { sc.ScriptMessage("Tried to replace menu '%s' with a menu of different type", desc->mMenuName.GetChars()); return true; } } MenuDescriptors[desc->mMenuName] = desc; + GC::WriteBarrier(desc); return false; } @@ -522,31 +506,28 @@ static void ParseListMenu(FScanner &sc) { sc.MustGetString(); - FListMenuDescriptor *desc = new FListMenuDescriptor; - desc->mType = MDESC_ListMenu; + DListMenuDescriptor *desc = new DListMenuDescriptor; desc->mMenuName = sc.String; desc->mSelectedItem = -1; desc->mAutoselect = -1; - desc->mSelectOfsX = DefaultListMenuSettings.mSelectOfsX; - desc->mSelectOfsY = DefaultListMenuSettings.mSelectOfsY; - desc->mSelector = DefaultListMenuSettings.mSelector; - desc->mDisplayTop = DefaultListMenuSettings.mDisplayTop; - desc->mXpos = DefaultListMenuSettings.mXpos; - desc->mYpos = DefaultListMenuSettings.mYpos; - desc->mLinespacing = DefaultListMenuSettings.mLinespacing; - desc->mNetgameMessage = DefaultListMenuSettings.mNetgameMessage; - desc->mFont = DefaultListMenuSettings.mFont; - desc->mFontColor = DefaultListMenuSettings.mFontColor; - desc->mFontColor2 = DefaultListMenuSettings.mFontColor2; - desc->mClass = NULL; - desc->mRedirect = NULL; + desc->mSelectOfsX = DefaultListMenuSettings->mSelectOfsX; + desc->mSelectOfsY = DefaultListMenuSettings->mSelectOfsY; + desc->mSelector = DefaultListMenuSettings->mSelector; + desc->mDisplayTop = DefaultListMenuSettings->mDisplayTop; + desc->mXpos = DefaultListMenuSettings->mXpos; + desc->mYpos = DefaultListMenuSettings->mYpos; + desc->mLinespacing = DefaultListMenuSettings->mLinespacing; + desc->mNetgameMessage = DefaultListMenuSettings->mNetgameMessage; + desc->mFont = DefaultListMenuSettings->mFont; + desc->mFontColor = DefaultListMenuSettings->mFontColor; + desc->mFontColor2 = DefaultListMenuSettings->mFontColor2; + desc->mClass = nullptr; desc->mWLeft = 0; desc->mWRight = 0; desc->mCenter = false; ParseListMenuBody(sc, desc); - bool scratch = ReplaceMenu(sc, desc); - if (scratch) delete desc; + ReplaceMenu(sc, desc); } //============================================================================= @@ -573,7 +554,7 @@ static void ParseOptionValue(FScanner &sc) pair.Text = strbin1(sc.String); } FOptionValues **pOld = OptionValues.CheckKey(optname); - if (pOld != NULL && *pOld != NULL) + if (pOld != nullptr && *pOld != nullptr) { delete *pOld; } @@ -606,7 +587,7 @@ static void ParseOptionString(FScanner &sc) pair.Text = strbin1(sc.String); } FOptionValues **pOld = OptionValues.CheckKey(optname); - if (pOld != NULL && *pOld != NULL) + if (pOld != nullptr && *pOld != nullptr) { delete *pOld; } @@ -661,7 +642,7 @@ static void ParseOptionSettings(FScanner &sc) // //============================================================================= -static EColorRange ParseOptionColor(FScanner &sc, FOptionMenuDescriptor *desc) +static EColorRange ParseOptionColor(FScanner &sc, DOptionMenuDescriptor *desc) { EColorRange cr = OptionSettings.mFontColor; if (sc.CheckString(",")) @@ -670,13 +651,13 @@ static EColorRange ParseOptionColor(FScanner &sc, FOptionMenuDescriptor *desc) cr = V_FindFontColor(sc.String); if (cr == CR_UNTRANSLATED && !sc.Compare("untranslated") && isdigit(sc.String[0])) { - if (strtoll(sc.String, NULL, 0)) cr = OptionSettings.mFontColorHeader; + if (strtoll(sc.String, nullptr, 0)) cr = OptionSettings.mFontColorHeader; } } return cr; } -static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc) +static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc) { sc.MustGetStringName("{"); while (!sc.CheckString("}")) @@ -706,7 +687,7 @@ static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc) { sc.MustGetString(); const PClass *cls = PClass::FindClass(sc.String); - if (cls == NULL || !cls->IsDescendantOf(RUNTIME_CLASS(DOptionMenu))) + if (cls == nullptr || !cls->IsDescendantOf(RUNTIME_CLASS(DOptionMenu))) { sc.ScriptError("Unknown menu class '%s'", sc.String); } @@ -947,21 +928,19 @@ static void ParseOptionMenu(FScanner &sc) { sc.MustGetString(); - FOptionMenuDescriptor *desc = new FOptionMenuDescriptor; - desc->mType = MDESC_OptionsMenu; + DOptionMenuDescriptor *desc = new DOptionMenuDescriptor; desc->mMenuName = sc.String; desc->mSelectedItem = -1; desc->mScrollPos = 0; - desc->mClass = NULL; - desc->mPosition = DefaultOptionMenuSettings.mPosition; - desc->mScrollTop = DefaultOptionMenuSettings.mScrollTop; - desc->mIndent = DefaultOptionMenuSettings.mIndent; - desc->mDontDim = DefaultOptionMenuSettings.mDontDim; + desc->mClass = nullptr; + desc->mPosition = DefaultOptionMenuSettings->mPosition; + desc->mScrollTop = DefaultOptionMenuSettings->mScrollTop; + desc->mIndent = DefaultOptionMenuSettings->mIndent; + desc->mDontDim = DefaultOptionMenuSettings->mDontDim; ParseOptionMenuBody(sc, desc); - bool scratch = ReplaceMenu(sc, desc); + ReplaceMenu(sc, desc); if (desc->mIndent == 0) desc->CalcIndent(); - if (scratch) delete desc; } @@ -982,8 +961,11 @@ void M_ParseMenuDefs() OptionSettings.mFontColorHeader = V_FindFontColor(gameinfo.mFontColorHeader); OptionSettings.mFontColorHighlight = V_FindFontColor(gameinfo.mFontColorHighlight); OptionSettings.mFontColorSelection = V_FindFontColor(gameinfo.mFontColorSelection); - DefaultListMenuSettings.Reset(); - DefaultOptionMenuSettings.Reset(); + // these are supposed to get GC'd after parsing is complete. + DefaultListMenuSettings = new DListMenuDescriptor; + DefaultOptionMenuSettings = new DOptionMenuDescriptor; + DefaultListMenuSettings->Reset(); + DefaultOptionMenuSettings->Reset(); atterm( DeinitMenus); DeinitMenus(); @@ -1004,8 +986,8 @@ void M_ParseMenuDefs() } else if (sc.Compare("DEFAULTLISTMENU")) { - ParseListMenuBody(sc, &DefaultListMenuSettings); - if (DefaultListMenuSettings.mItems.Size() > 0) + ParseListMenuBody(sc, DefaultListMenuSettings); + if (DefaultListMenuSettings->mItems.Size() > 0) { I_FatalError("You cannot add menu items to the menu default settings."); } @@ -1028,8 +1010,8 @@ void M_ParseMenuDefs() } else if (sc.Compare("DEFAULTOPTIONMENU")) { - ParseOptionMenuBody(sc, &DefaultOptionMenuSettings); - if (DefaultOptionMenuSettings.mItems.Size() > 0) + ParseOptionMenuBody(sc, DefaultOptionMenuSettings); + if (DefaultOptionMenuSettings->mItems.Size() > 0) { I_FatalError("You cannot add menu items to the menu default settings."); } @@ -1040,6 +1022,8 @@ void M_ParseMenuDefs() } } } + DefaultListMenuSettings = nullptr; + DefaultOptionMenuSettings = nullptr; } @@ -1054,12 +1038,12 @@ static void BuildEpisodeMenu() { // Build episode menu bool success = false; - FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Episodemenu); - if (desc != NULL) + DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Episodemenu); + if (desc != nullptr) { - if ((*desc)->mType == MDESC_ListMenu) + if ((*desc)->IsKindOf(RUNTIME_CLASS(DListMenuDescriptor))) { - FListMenuDescriptor *ld = static_cast(*desc); + DListMenuDescriptor *ld = static_cast(*desc); int posy = ld->mYpos; int topy = posy; @@ -1111,7 +1095,7 @@ static void BuildEpisodeMenu() success = true; for (auto &p : ld->mItems) { - GC::WriteBarrier(p); + GC::WriteBarrier(*desc, p); } } } @@ -1120,24 +1104,23 @@ static void BuildEpisodeMenu() { // Couldn't create the episode menu, either because there's too many episodes or some error occured // Create an option menu for episode selection instead. - FOptionMenuDescriptor *od = new FOptionMenuDescriptor; - if (desc != NULL) delete *desc; + DOptionMenuDescriptor *od = new DOptionMenuDescriptor; MenuDescriptors[NAME_Episodemenu] = od; - od->mType = MDESC_OptionsMenu; od->mMenuName = NAME_Episodemenu; od->mTitle = "$MNU_EPISODE"; od->mSelectedItem = 0; od->mScrollPos = 0; - od->mClass = NULL; + od->mClass = nullptr; od->mPosition = -15; od->mScrollTop = 0; od->mIndent = 160; od->mDontDim = false; + GC::WriteBarrier(od); for(unsigned i = 0; i < AllEpisodes.Size(); i++) { DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu(AllEpisodes[i].mEpisodeName, "Skillmenu", i); od->mItems.Push(it); - GC::WriteBarrier(it); + GC::WriteBarrier(od, it); } } } @@ -1153,12 +1136,12 @@ static void BuildPlayerclassMenu() bool success = false; // Build player class menu - FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Playerclassmenu); - if (desc != NULL) + DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Playerclassmenu); + if (desc != nullptr) { - if ((*desc)->mType == MDESC_ListMenu) + if ((*desc)->IsKindOf(RUNTIME_CLASS(DListMenuDescriptor))) { - FListMenuDescriptor *ld = static_cast(*desc); + DListMenuDescriptor *ld = static_cast(*desc); // add player display ld->mSelectedItem = ld->mItems.Size(); @@ -1179,7 +1162,7 @@ static void BuildPlayerclassMenu() if (!(PlayerClasses[i].Flags & PCF_NOMENU)) { const char *pname = GetPrintableDisplayName(PlayerClasses[i].Type); - if (pname != NULL) + if (pname != nullptr) { numclassitems++; } @@ -1216,7 +1199,7 @@ static void BuildPlayerclassMenu() if (!(PlayerClasses[i].Flags & PCF_NOMENU)) { const char *pname = GetPrintableDisplayName(PlayerClasses[i].Type); - if (pname != NULL) + if (pname != nullptr) { DListMenuItemText *it = new DListMenuItemText(ld->mXpos, ld->mYpos, ld->mLinespacing, *pname, pname, ld->mFont,ld->mFontColor,ld->mFontColor2, NAME_Episodemenu, i); @@ -1235,7 +1218,7 @@ static void BuildPlayerclassMenu() if (n == 0) { const char *pname = GetPrintableDisplayName(PlayerClasses[0].Type); - if (pname != NULL) + if (pname != nullptr) { DListMenuItemText *it = new DListMenuItemText(ld->mXpos, ld->mYpos, ld->mLinespacing, *pname, pname, ld->mFont,ld->mFontColor,ld->mFontColor2, NAME_Episodemenu, 0); @@ -1245,7 +1228,7 @@ static void BuildPlayerclassMenu() success = true; for (auto &p : ld->mItems) { - GC::WriteBarrier(p); + GC::WriteBarrier(ld, p); } } } @@ -1254,37 +1237,35 @@ static void BuildPlayerclassMenu() { // Couldn't create the playerclass menu, either because there's too many episodes or some error occured // Create an option menu for class selection instead. - FOptionMenuDescriptor *od = new FOptionMenuDescriptor; - if (desc != NULL) delete *desc; + DOptionMenuDescriptor *od = new DOptionMenuDescriptor; MenuDescriptors[NAME_Playerclassmenu] = od; - od->mType = MDESC_OptionsMenu; od->mMenuName = NAME_Playerclassmenu; od->mTitle = "$MNU_CHOOSECLASS"; od->mSelectedItem = 0; od->mScrollPos = 0; - od->mClass = NULL; + od->mClass = nullptr; od->mPosition = -15; od->mScrollTop = 0; od->mIndent = 160; od->mDontDim = false; od->mNetgameMessage = "$NEWGAME"; - + GC::WriteBarrier(od); for (unsigned i = 0; i < PlayerClasses.Size (); i++) { if (!(PlayerClasses[i].Flags & PCF_NOMENU)) { const char *pname = GetPrintableDisplayName(PlayerClasses[i].Type); - if (pname != NULL) + if (pname != nullptr) { DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu(pname, "Episodemenu", i); od->mItems.Push(it); - GC::WriteBarrier(it); + GC::WriteBarrier(od, it); } } } DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu("Random", "Episodemenu", -1); od->mItems.Push(it); - GC::WriteBarrier(it); + GC::WriteBarrier(od, it); } } @@ -1302,7 +1283,7 @@ static void InitCrosshairsList() lastlump = 0; FOptionValues **opt = OptionValues.CheckKey(NAME_Crosshairs); - if (opt == NULL) + if (opt == nullptr) { return; // no crosshair value list present. No need to go on. } @@ -1353,12 +1334,12 @@ static void InitCrosshairsList() static void InitKeySections() { - FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_CustomizeControls); - if (desc != NULL) + DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_CustomizeControls); + if (desc != nullptr) { - if ((*desc)->mType == MDESC_OptionsMenu) + if ((*desc)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor))) { - FOptionMenuDescriptor *menu = static_cast(*desc); + DOptionMenuDescriptor *menu = static_cast(*desc); for (unsigned i = 0; i < KeySections.Size(); i++) { @@ -1376,7 +1357,7 @@ static void InitKeySections() } for (auto &p : menu->mItems) { - GC::WriteBarrier(p); + GC::WriteBarrier(*desc, p); } } } @@ -1396,12 +1377,12 @@ void M_CreateMenus() InitKeySections(); FOptionValues **opt = OptionValues.CheckKey(NAME_Mididevices); - if (opt != NULL) + if (opt != nullptr) { I_BuildMIDIMenuList(*opt); } opt = OptionValues.CheckKey(NAME_Aldevices); - if (opt != NULL) + if (opt != nullptr) { I_BuildALDeviceList(*opt); } @@ -1418,19 +1399,19 @@ void M_StartupSkillMenu(FGameStartup *gs) { static int done = -1; bool success = false; - FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Skillmenu); - if (desc != NULL) + DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Skillmenu); + if (desc != nullptr) { - if ((*desc)->mType == MDESC_ListMenu) + if ((*desc)->IsKindOf(RUNTIME_CLASS(DListMenuDescriptor))) { - FListMenuDescriptor *ld = static_cast(*desc); + DListMenuDescriptor *ld = static_cast(*desc); int x = ld->mXpos; int y = ld->mYpos; // Delete previous contents for(unsigned i=0; imItems.Size(); i++) { - FName n = ld->mItems[i]->GetAction(NULL); + FName n = ld->mItems[i]->GetAction(nullptr); if (n == NAME_Startgame || n == NAME_StartgameConfirm) { ld->mItems.Resize(i); @@ -1477,8 +1458,7 @@ void M_StartupSkillMenu(FGameStartup *gs) else { // too large - delete ld; - desc = NULL; + desc = nullptr; done = false; goto fail; } @@ -1492,13 +1472,13 @@ void M_StartupSkillMenu(FGameStartup *gs) // Using a different name for skills that must be confirmed makes handling this easier. FName action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ? NAME_StartgameConfirm : NAME_Startgame; - FString *pItemText = NULL; - if (gs->PlayerClass != NULL) + FString *pItemText = nullptr; + if (gs->PlayerClass != nullptr) { pItemText = skill.MenuNamesForPlayerClass.CheckKey(gs->PlayerClass); } - if (skill.PicName.Len() != 0 && pItemText == NULL) + if (skill.PicName.Len() != 0 && pItemText == nullptr) { FTextureID tex = GetMenuTexture(skill.PicName); li = new DListMenuItemPatch(ld->mXpos, y, ld->mLinespacing, skill.Shortcut, tex, action, i); @@ -1511,7 +1491,7 @@ void M_StartupSkillMenu(FGameStartup *gs) pItemText? *pItemText : skill.MenuName, ld->mFont, color,ld->mFontColor2, action, i); } ld->mItems.Push(li); - GC::WriteBarrier(li); + GC::WriteBarrier(*desc, li); y += ld->mLinespacing; } if (AllEpisodes[gs->Episode].mNoSkill || AllSkills.Size() == 1) @@ -1528,26 +1508,25 @@ void M_StartupSkillMenu(FGameStartup *gs) if (success) return; fail: // Option menu fallback for overlong skill lists - FOptionMenuDescriptor *od; - if (desc == NULL) + DOptionMenuDescriptor *od; + if (desc == nullptr) { - od = new FOptionMenuDescriptor; - if (desc != NULL) delete *desc; + od = new DOptionMenuDescriptor; MenuDescriptors[NAME_Skillmenu] = od; - od->mType = MDESC_OptionsMenu; od->mMenuName = NAME_Skillmenu; od->mTitle = "$MNU_CHOOSESKILL"; od->mSelectedItem = 0; od->mScrollPos = 0; - od->mClass = NULL; + od->mClass = nullptr; od->mPosition = -15; od->mScrollTop = 0; od->mIndent = 160; od->mDontDim = false; + GC::WriteBarrier(od); } else { - od = static_cast(*desc); + od = static_cast(*desc); od->mItems.Clear(); } for(unsigned int i = 0; i < AllSkills.Size(); i++) @@ -1558,14 +1537,14 @@ fail: const char *action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ? "StartgameConfirm" : "Startgame"; - FString *pItemText = NULL; - if (gs->PlayerClass != NULL) + FString *pItemText = nullptr; + if (gs->PlayerClass != nullptr) { pItemText = skill.MenuNamesForPlayerClass.CheckKey(gs->PlayerClass); } li = new DOptionMenuItemSubmenu(pItemText? *pItemText : skill.MenuName, action, i); od->mItems.Push(li); - GC::WriteBarrier(li); + GC::WriteBarrier(od, li); if (!done) { done = true; diff --git a/src/menu/optionmenu.cpp b/src/menu/optionmenu.cpp index e27ae20a2b..07168bffe1 100644 --- a/src/menu/optionmenu.cpp +++ b/src/menu/optionmenu.cpp @@ -76,7 +76,7 @@ IMPLEMENT_POINTERS_END // //============================================================================= -DOptionMenu::DOptionMenu(DMenu *parent, FOptionMenuDescriptor *desc) +DOptionMenu::DOptionMenu(DMenu *parent, DOptionMenuDescriptor *desc) : DMenu(parent) { CanScrollUp = false; @@ -92,7 +92,7 @@ DOptionMenu::DOptionMenu(DMenu *parent, FOptionMenuDescriptor *desc) // //============================================================================= -void DOptionMenu::Init(DMenu *parent, FOptionMenuDescriptor *desc) +void DOptionMenu::Init(DMenu *parent, DOptionMenuDescriptor *desc) { mParentMenu = parent; GC::WriteBarrier(this, parent); @@ -482,7 +482,7 @@ void DOptionMenu::Drawer () // //============================================================================= -int DOptionMenuItem::Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) +int DOptionMenuItem::Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected) { return indent; } @@ -528,7 +528,7 @@ void DOptionMenuItem::drawLabel(int indent, int y, EColorRange color, bool graye -void FOptionMenuDescriptor::CalcIndent() +void DOptionMenuDescriptor::CalcIndent() { // calculate the menu indent int widest = 0, thiswidth; @@ -547,7 +547,7 @@ void FOptionMenuDescriptor::CalcIndent() // //============================================================================= -DOptionMenuItem *FOptionMenuDescriptor::GetItem(FName name) +DOptionMenuItem *DOptionMenuDescriptor::GetItem(FName name) { for(unsigned i=0;iGetGenericRep(CVAR_Bool).Bool); @@ -459,7 +459,7 @@ public: //============================================================================= - int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) + int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected) { drawLabel(indent, y, mWaiting? OptionSettings.mFontColorHighlight: (selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor)); @@ -541,7 +541,7 @@ public: mColor = cr; } - int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) + int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected) { drawLabel(indent, y, mColor); return -1; @@ -581,7 +581,7 @@ public: mCurrent = 0; } - int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) + int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected) { const char *txt = mCurrent? mAltText.GetChars() : mLabel.GetChars(); if (*txt == '$') txt = GStrings(txt + 1); @@ -700,7 +700,7 @@ public: //============================================================================= - int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) + int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected) { drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor); mDrawX = indent + CURSORSPACE; @@ -883,7 +883,7 @@ public: } //============================================================================= - int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) + int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected) { drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor); @@ -1038,7 +1038,7 @@ public: return true; } - int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) + int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected) { int colwidth = screen->GetWidth() / 3; EColorRange color; @@ -1108,7 +1108,7 @@ public: return GetCVarString(); } - int Draw ( FOptionMenuDescriptor*, int y, int indent, bool selected ) + int Draw ( DOptionMenuDescriptor*, int y, int indent, bool selected ) { bool grayed = mGrayCheck != NULL && !( mGrayCheck->GetGenericRep( CVAR_Bool ).Bool ); drawLabel( indent, y, selected ? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, grayed ); @@ -1186,7 +1186,7 @@ public: return text; } - int Draw(FOptionMenuDescriptor*desc, int y, int indent, bool selected) + int Draw(DOptionMenuDescriptor*desc, int y, int indent, bool selected) { if (mEntering) { diff --git a/src/menu/playerdisplay.cpp b/src/menu/playerdisplay.cpp index ba99aba364..358192280b 100644 --- a/src/menu/playerdisplay.cpp +++ b/src/menu/playerdisplay.cpp @@ -355,7 +355,7 @@ void FBackdropTexture::Render() // //============================================================================= IMPLEMENT_CLASS(DListMenuItemPlayerDisplay, false, false) -DListMenuItemPlayerDisplay::DListMenuItemPlayerDisplay(FListMenuDescriptor *menu, int x, int y, PalEntry c1, PalEntry c2, bool np, FName action) +DListMenuItemPlayerDisplay::DListMenuItemPlayerDisplay(DListMenuDescriptor *menu, int x, int y, PalEntry c1, PalEntry c2, bool np, FName action) : DMenuItemBase(x, y, action) { mOwner = menu; diff --git a/src/menu/playermenu.cpp b/src/menu/playermenu.cpp index add8e5680b..ee8ea18533 100644 --- a/src/menu/playermenu.cpp +++ b/src/menu/playermenu.cpp @@ -509,7 +509,7 @@ class DPlayerMenu : public DListMenu public: DPlayerMenu() {} - void Init(DMenu *parent, FListMenuDescriptor *desc); + void Init(DMenu *parent, DListMenuDescriptor *desc); bool Responder (event_t *ev); bool MenuEvent (int mkey, bool fromcontroller); bool MouseEvent(int type, int x, int y); @@ -525,7 +525,7 @@ IMPLEMENT_CLASS(DPlayerMenu, false, false) // //============================================================================= -void DPlayerMenu::Init(DMenu *parent, FListMenuDescriptor *desc) +void DPlayerMenu::Init(DMenu *parent, DListMenuDescriptor *desc) { DMenuItemBase *li; diff --git a/src/menu/videomenu.cpp b/src/menu/videomenu.cpp index aad6e411a3..6737f832e6 100644 --- a/src/menu/videomenu.cpp +++ b/src/menu/videomenu.cpp @@ -66,7 +66,7 @@ static void BuildModesList (int hiwidth, int hiheight, int hi_id); static bool GetSelectedSize (int *width, int *height); static void SetModesMenu (int w, int h, int bits); -FOptionMenuDescriptor *GetVideoModeMenu(); +DOptionMenuDescriptor *GetVideoModeMenu(); extern bool setmodeneeded; extern int NewWidth, NewHeight, NewBits; @@ -101,7 +101,7 @@ CUSTOM_CVAR (Int, menu_screenratios, -1, CVAR_ARCHIVE) CUSTOM_CVAR (Bool, vid_tft, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) { - FOptionMenuDescriptor *opt = GetVideoModeMenu(); + DOptionMenuDescriptor *opt = GetVideoModeMenu(); if (opt != NULL) { DOptionMenuItem *it = opt->GetItem("menu_screenratios"); @@ -192,12 +192,12 @@ IMPLEMENT_CLASS(DVideoModeMenu, false, false) // //============================================================================= -FOptionMenuDescriptor *GetVideoModeMenu() +DOptionMenuDescriptor *GetVideoModeMenu() { - FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_VideoModeMenu); - if (desc != NULL && (*desc)->mType == MDESC_OptionsMenu) + DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_VideoModeMenu); + if (desc != NULL && (*desc)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor))) { - return (FOptionMenuDescriptor *)*desc; + return (DOptionMenuDescriptor *)*desc; } return NULL; } @@ -231,7 +231,7 @@ static void BuildModesList (int hiwidth, int hiheight, int hi_bits) Video->StartModeIterator (showbits, screen->IsFullscreen()); } - FOptionMenuDescriptor *opt = GetVideoModeMenu(); + DOptionMenuDescriptor *opt = GetVideoModeMenu(); if (opt != NULL) { for (i = NAME_res_0; i<= NAME_res_9; i++) @@ -354,7 +354,7 @@ void M_InitVideoModesMenu () static bool GetSelectedSize (int *width, int *height) { - FOptionMenuDescriptor *opt = GetVideoModeMenu(); + DOptionMenuDescriptor *opt = GetVideoModeMenu(); if (opt != NULL && (unsigned)opt->mSelectedItem < opt->mItems.Size()) { int line = opt->mSelectedItem; @@ -420,7 +420,7 @@ static void SetModesMenu (int w, int h, int bits) { DummyDepthCvar = FindBits (bits); - FOptionMenuDescriptor *opt = GetVideoModeMenu(); + DOptionMenuDescriptor *opt = GetVideoModeMenu(); if (opt != NULL) { DOptionMenuItem *it; diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 16b7b52541..48ffc102f5 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -7,7 +7,7 @@ #include "zscript/actor_checks.txt" #include "zscript/menu/menu.txt" -#include "zscript/menu/menuitembase.txt" +//#include "zscript/menu/menuitembase.txt" #include "zscript/inventory/inventory.txt" #include "zscript/inventory/inv_misc.txt" diff --git a/wadsrc/static/zscript/menu/menu.txt b/wadsrc/static/zscript/menu/menu.txt index ffada31983..c47c93d053 100644 --- a/wadsrc/static/zscript/menu/menu.txt +++ b/wadsrc/static/zscript/menu/menu.txt @@ -2,6 +2,31 @@ class Menu : Object native { //native static int MenuTime(); + + native virtual bool MenuEvent (int mkey, bool fromcontroller); + + void MenuSound(Sound snd) + { + S_Sound (snd, CHAN_VOICE | CHAN_UI, snd_menuvolume, ATTN_NONE); + } + +} + +class MenuDescriptor : Object native +{ + native Name mMenuName; + native String mNetgameMessage; + native Class mClass; +} + +class MenuItemBase : object native +{ + native int mXpos, mYpos; + native Name mAction; + native bool mEnabled; + + native virtual bool MenuEvent (int mkey, bool fromcontroller); + } struct FOptionMenuSettings @@ -15,3 +40,45 @@ struct FOptionMenuSettings int mFontColorSelection; int mLinespacing; } + +class OptionMenuDescriptor : MenuDescriptor native +{ + native Array mItems; + native String mTitle; + native int mSelectedItem; + native int mDrawTop; + native int mScrollTop; + native int mScrollPos; + native int mIndent; + 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) + mPosition = 0; + mScrollTop = 0; + mIndent = 0; + mDontDim = 0; + } +} + +class OptionMenuItem : MenuItemBase native +{ + native String mLabel; + native bool mCentered; + + //native void drawLabel(int indent, int y, EColorRange color, bool grayed = false); +} + +class OptionMenu : Menu native +{ + native bool CanScrollUp; + native bool CanScrollDown; + native int VisBottom; + native OptionMenuItem mFocusControl; + native OptionMenuDescriptor mDesc; +} +