- made the menu descriptors garbage collectable and started exporting some fields as preparation for script work on the menu.

This commit is contained in:
Christoph Oelckers 2017-02-09 20:18:53 +01:00
parent f37db344df
commit 7efa9cd70d
15 changed files with 333 additions and 240 deletions

View file

@ -254,14 +254,6 @@ static DObject **SweepList(DObject **p, size_t count, size_t *finalize_count)
curr->Destroy(); curr->Destroy();
} }
/*
if (curr->IsKindOf(RUNTIME_CLASS(PSymbol)))
Printf("Collecting %s, name = %s\n", curr->GetClass()->TypeName.GetChars(), static_cast<PSymbol*>(curr)->SymbolName.GetChars());
else if (curr->IsKindOf(RUNTIME_CLASS(PType)))
Printf("Collecting %s, name = %s\n", curr->GetClass()->TypeName.GetChars(), static_cast<PType*>(curr)->DescriptiveName());
else
Printf("Collecting %s\n", curr->GetClass()->TypeName.GetChars());
*/
curr->ObjectFlags |= OF_Cleanup; curr->ObjectFlags |= OF_Cleanup;
delete curr; delete curr;
finalized++; finalized++;

View file

@ -68,7 +68,7 @@ class DColorPickerMenu : public DOptionMenu
public: 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(); mStartItem = desc->mItems.Size();
mRed = (float)RPART(DWORD(*cvar)); mRed = (float)RPART(DWORD(*cvar));
@ -344,10 +344,10 @@ CCMD(undocolorpic)
DMenu *StartPickerMenu(DMenu *parent, const char *name, FColorCVar *cvar) DMenu *StartPickerMenu(DMenu *parent, const char *name, FColorCVar *cvar)
{ {
FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Colorpickermenu); DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Colorpickermenu);
if (desc != NULL && (*desc)->mType == MDESC_OptionsMenu) 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 else
{ {

View file

@ -58,7 +58,7 @@
static TArray<IJoystickConfig *> Joysticks; static TArray<IJoystickConfig *> Joysticks;
IJoystickConfig *SELECTED_JOYSTICK; 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); DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_JoystickConfigMenu);
if (desc != NULL && (*desc)->mType == MDESC_OptionsMenu) if (desc != NULL && (*desc)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor)))
{ {
FOptionMenuDescriptor *opt = (FOptionMenuDescriptor *)*desc; DOptionMenuDescriptor *opt = (DOptionMenuDescriptor *)*desc;
DOptionMenuItem *it; DOptionMenuItem *it;
opt->mItems.Clear(); opt->mItems.Clear();
if (joy == NULL) if (joy == NULL)
@ -340,10 +340,10 @@ FOptionMenuDescriptor *UpdateJoystickConfigMenu(IJoystickConfig *joy)
void UpdateJoystickMenu(IJoystickConfig *selected) void UpdateJoystickMenu(IJoystickConfig *selected)
{ {
FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_JoystickOptions); DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_JoystickOptions);
if (desc != NULL && (*desc)->mType == MDESC_OptionsMenu) if (desc != NULL && (*desc)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor)))
{ {
FOptionMenuDescriptor *opt = (FOptionMenuDescriptor *)*desc; DOptionMenuDescriptor *opt = (DOptionMenuDescriptor *)*desc;
DOptionMenuItem *it; DOptionMenuItem *it;
opt->mItems.Clear(); opt->mItems.Clear();

View file

@ -54,7 +54,7 @@ IMPLEMENT_POINTERS_END
// //
//============================================================================= //=============================================================================
DListMenu::DListMenu(DMenu *parent, FListMenuDescriptor *desc) DListMenu::DListMenu(DMenu *parent, DListMenuDescriptor *desc)
: DMenu(parent) : DMenu(parent)
{ {
mDesc = NULL; 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; mParentMenu = parent;
GC::WriteBarrier(this, parent); GC::WriteBarrier(this, parent);
@ -359,6 +359,15 @@ bool DMenuItemBase::MenuEvent(int mkey, bool fromcontroller)
return false; 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) bool DMenuItemBase::MouseEvent(int type, int x, int y)
{ {
return false; return false;

View file

@ -102,7 +102,7 @@ protected:
bool mEntering; bool mEntering;
char savegamestring[SAVESTRINGSIZE]; char savegamestring[SAVESTRINGSIZE];
DLoadSaveMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); DLoadSaveMenu(DMenu *parent = NULL, DListMenuDescriptor *desc = NULL);
void OnDestroy() override; void OnDestroy() override;
int RemoveSaveSlot (int index); 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) : DListMenu(parent, desc)
{ {
ReadSaveStrings(); ReadSaveStrings();
@ -927,7 +927,7 @@ class DSaveMenu : public DLoadSaveMenu
public: public:
DSaveMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); DSaveMenu(DMenu *parent = NULL, DListMenuDescriptor *desc = NULL);
void OnDestroy() override; void OnDestroy() override;
void DoSave (FSaveGameNode *node); void DoSave (FSaveGameNode *node);
bool Responder (event_t *ev); 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) : DLoadSaveMenu(parent, desc)
{ {
strcpy (NewSaveNode.Title, GStrings["NEWSAVE"]); strcpy (NewSaveNode.Title, GStrings["NEWSAVE"]);
@ -1099,7 +1099,7 @@ class DLoadMenu : public DLoadSaveMenu
public: public:
DLoadMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); DLoadMenu(DMenu *parent = NULL, DListMenuDescriptor *desc = NULL);
bool MenuEvent (int mkey, bool fromcontroller); 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) : DLoadSaveMenu(parent, desc)
{ {
TopItem = 0; TopItem = 0;

View file

@ -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); for (auto item : mItems) GC::Mark(item);
return 0; return 0;
} }
size_t FOptionMenuDescriptor::PropagateMark() size_t DOptionMenuDescriptor::PropagateMark()
{ {
for (auto item : mItems) GC::Mark(item); for (auto item : mItems) GC::Mark(item);
return 0; return 0;
@ -109,8 +114,7 @@ void M_MarkMenus()
MenuDescriptorList::Pair *pair; MenuDescriptorList::Pair *pair;
while (it.NextPair(pair)) while (it.NextPair(pair))
{ {
//GC::Mark(pair->Value); // once the descriptors have been made objects. GC::Mark(pair->Value);
pair->Value->PropagateMark();
} }
GC::Mark(DMenu::CurrentMenu); GC::Mark(DMenu::CurrentMenu);
} }
@ -189,13 +193,21 @@ bool DMenu::MenuEvent (int mkey, bool fromcontroller)
{ {
Close(); Close();
S_Sound (CHAN_VOICE | CHAN_UI, 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 true;
} }
} }
return false; 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); assert(DMenu::CurrentMenu == this);
DMenu::CurrentMenu = mParentMenu; DMenu::CurrentMenu = mParentMenu;
Destroy(); Destroy();
if (DMenu::CurrentMenu != NULL) if (DMenu::CurrentMenu != nullptr)
{ {
GC::WriteBarrier(DMenu::CurrentMenu); GC::WriteBarrier(DMenu::CurrentMenu);
} }
@ -239,7 +251,7 @@ bool DMenu::MouseEventBack(int type, int x, int y)
if (m_show_backbutton >= 0) if (m_show_backbutton >= 0)
{ {
FTexture *tex = TexMan(gameinfo.mBackButton); 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&1) x -= screen->GetWidth() - tex->GetScaledWidth() * CleanXfac;
if (m_show_backbutton&2) y -= screen->GetHeight() - tex->GetScaledHeight() * CleanYfac; if (m_show_backbutton&2) y -= screen->GetHeight() - tex->GetScaledHeight() * CleanYfac;
@ -329,7 +341,7 @@ bool DMenu::TranslateKeyboardEvents()
void M_StartControlPanel (bool makeSound) void M_StartControlPanel (bool makeSound)
{ {
// intro might call this repeatedly // intro might call this repeatedly
if (DMenu::CurrentMenu != NULL) if (DMenu::CurrentMenu != nullptr)
return; return;
ResetButtonStates (); ResetButtonStates ();
@ -361,7 +373,7 @@ void M_StartControlPanel (bool makeSound)
void M_ActivateMenu(DMenu *menu) void M_ActivateMenu(DMenu *menu)
{ {
if (menuactive == MENU_Off) menuactive = MENU_On; if (menuactive == MENU_Off) menuactive = MENU_On;
if (DMenu::CurrentMenu != NULL) DMenu::CurrentMenu->ReleaseCapture(); if (DMenu::CurrentMenu != nullptr) DMenu::CurrentMenu->ReleaseCapture();
DMenu::CurrentMenu = menu; DMenu::CurrentMenu = menu;
GC::WriteBarrier(DMenu::CurrentMenu); GC::WriteBarrier(DMenu::CurrentMenu);
} }
@ -382,7 +394,7 @@ void M_SetMenu(FName menu, int param)
GameStartupInfo.Skill = -1; GameStartupInfo.Skill = -1;
GameStartupInfo.Episode = -1; GameStartupInfo.Episode = -1;
GameStartupInfo.PlayerClass = GameStartupInfo.PlayerClass =
param == -1000? NULL : param == -1000? nullptr :
param == -1? "Random" : GetPrintableDisplayName(PlayerClasses[param].Type).GetChars(); param == -1? "Random" : GetPrintableDisplayName(PlayerClasses[param].Type).GetChars();
break; break;
@ -437,8 +449,8 @@ void M_SetMenu(FName menu, int param)
// End of special checks // End of special checks
FMenuDescriptor **desc = MenuDescriptors.CheckKey(menu); DMenuDescriptor **desc = MenuDescriptors.CheckKey(menu);
if (desc != NULL) if (desc != nullptr)
{ {
if ((*desc)->mNetgameMessage.IsNotEmpty() && netgame && !demoplayback) if ((*desc)->mNetgameMessage.IsNotEmpty() && netgame && !demoplayback)
{ {
@ -446,9 +458,9 @@ void M_SetMenu(FName menu, int param)
return; return;
} }
if ((*desc)->mType == MDESC_ListMenu) if ((*desc)->IsKindOf(RUNTIME_CLASS(DListMenuDescriptor)))
{ {
FListMenuDescriptor *ld = static_cast<FListMenuDescriptor*>(*desc); DListMenuDescriptor *ld = static_cast<DListMenuDescriptor*>(*desc);
if (ld->mAutoselect >= 0 && ld->mAutoselect < (int)ld->mItems.Size()) if (ld->mAutoselect >= 0 && ld->mAutoselect < (int)ld->mItems.Size())
{ {
// recursively activate the autoselected item without ever creating this menu. // recursively activate the autoselected item without ever creating this menu.
@ -456,17 +468,17 @@ void M_SetMenu(FName menu, int param)
} }
else 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(); DListMenu *newmenu = (DListMenu *)cls->CreateNew();
newmenu->Init(DMenu::CurrentMenu, ld); newmenu->Init(DMenu::CurrentMenu, ld);
M_ActivateMenu(newmenu); M_ActivateMenu(newmenu);
} }
} }
else if ((*desc)->mType == MDESC_OptionsMenu) else if ((*desc)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor)))
{ {
FOptionMenuDescriptor *ld = static_cast<FOptionMenuDescriptor*>(*desc); DOptionMenuDescriptor *ld = static_cast<DOptionMenuDescriptor*>(*desc);
const PClass *cls = ld->mClass == NULL? RUNTIME_CLASS(DOptionMenu) : ld->mClass; const PClass *cls = ld->mClass == nullptr? RUNTIME_CLASS(DOptionMenu) : ld->mClass;
DOptionMenu *newmenu = (DOptionMenu *)cls->CreateNew(); DOptionMenu *newmenu = (DOptionMenu *)cls->CreateNew();
newmenu->Init(DMenu::CurrentMenu, ld); newmenu->Init(DMenu::CurrentMenu, ld);
@ -477,7 +489,7 @@ void M_SetMenu(FName menu, int param)
else else
{ {
const PClass *menuclass = PClass::FindClass(menu); const PClass *menuclass = PClass::FindClass(menu);
if (menuclass != NULL) if (menuclass != nullptr)
{ {
if (menuclass->IsDescendantOf(RUNTIME_CLASS(DMenu))) if (menuclass->IsDescendantOf(RUNTIME_CLASS(DMenu)))
{ {
@ -510,7 +522,7 @@ bool M_Responder (event_t *ev)
return false; 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: // 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) // what it's bound to. (for those who don't bother to read the docs)
if (devparm && ev->data1 == KEY_F1) if (devparm && ev->data1 == KEY_F1)
{ {
G_ScreenShot(NULL); G_ScreenShot(nullptr);
return true; return true;
} }
return false; return false;
@ -695,7 +707,7 @@ bool M_Responder (event_t *ev)
void M_Ticker (void) void M_Ticker (void)
{ {
DMenu::MenuTime++; DMenu::MenuTime++;
if (DMenu::CurrentMenu != NULL && menuactive != MENU_Off) if (DMenu::CurrentMenu != nullptr && menuactive != MENU_Off)
{ {
DMenu::CurrentMenu->Ticker(); DMenu::CurrentMenu->Ticker();
@ -736,9 +748,9 @@ void M_Drawer (void)
AActor *camera = player->camera; AActor *camera = player->camera;
PalEntry fade = 0; 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; 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()) if (DMenu::CurrentMenu->DimAllowed())
{ {
@ -766,10 +778,10 @@ void M_Drawer (void)
void M_ClearMenus () void M_ClearMenus ()
{ {
M_DemoNoPlay = false; M_DemoNoPlay = false;
if (DMenu::CurrentMenu != NULL) if (DMenu::CurrentMenu != nullptr)
{ {
DMenu::CurrentMenu->Destroy(); DMenu::CurrentMenu->Destroy();
DMenu::CurrentMenu = NULL; DMenu::CurrentMenu = nullptr;
} }
V_SetBorderNeedRefresh(); V_SetBorderNeedRefresh();
menuactive = MENU_Off; menuactive = MENU_Off;
@ -1002,3 +1014,38 @@ CCMD(reset2saved)
GameConfig->DoModSetup (gameinfo.ConfigName); GameConfig->DoModSetup (gameinfo.ConfigName);
R_SetViewSize (screenblocks); 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)

View file

@ -75,28 +75,25 @@ struct FSaveGameNode
// //
//============================================================================= //=============================================================================
enum EMenuDescriptorType class DMenuDescriptor : public DObject
{
MDESC_ListMenu,
MDESC_OptionsMenu,
};
struct FMenuDescriptor
{ {
DECLARE_CLASS(DMenuDescriptor, DObject)
public:
FName mMenuName; FName mMenuName;
FString mNetgameMessage; FString mNetgameMessage;
int mType;
const PClass *mClass; const PClass *mClass;
virtual ~FMenuDescriptor() {}
virtual size_t PropagateMark() { return 0; } virtual size_t PropagateMark() { return 0; }
}; };
class DMenuItemBase; class DMenuItemBase;
class DOptionMenuItem; class DOptionMenuItem;
struct FListMenuDescriptor : public FMenuDescriptor class DListMenuDescriptor : public DMenuDescriptor
{ {
DECLARE_CLASS(DListMenuDescriptor, DMenuDescriptor)
public:
TArray<DMenuItemBase *> mItems; TArray<DMenuItemBase *> mItems;
int mSelectedItem; int mSelectedItem;
int mSelectOfsX; int mSelectOfsX;
@ -110,7 +107,6 @@ struct FListMenuDescriptor : public FMenuDescriptor
FFont *mFont; FFont *mFont;
EColorRange mFontColor; EColorRange mFontColor;
EColorRange mFontColor2; EColorRange mFontColor2;
FMenuDescriptor *mRedirect; // used to redirect overlong skill and episode menus to option menu based alternatives
bool mCenter; bool mCenter;
void Reset() void Reset()
@ -144,8 +140,11 @@ struct FOptionMenuSettings
int mLinespacing; int mLinespacing;
}; };
struct FOptionMenuDescriptor : public FMenuDescriptor class DOptionMenuDescriptor : public DMenuDescriptor
{ {
DECLARE_CLASS(DOptionMenuDescriptor, DMenuDescriptor)
public:
TArray<DOptionMenuItem *> mItems; TArray<DOptionMenuItem *> mItems;
FString mTitle; FString mTitle;
int mSelectedItem; int mSelectedItem;
@ -167,10 +166,13 @@ struct FOptionMenuDescriptor : public FMenuDescriptor
mDontDim = 0; mDontDim = 0;
} }
size_t PropagateMark() override; size_t PropagateMark() override;
~DOptionMenuDescriptor()
{
}
}; };
typedef TMap<FName, FMenuDescriptor *> MenuDescriptorList; typedef TMap<FName, DMenuDescriptor *> MenuDescriptorList;
extern FOptionMenuSettings OptionSettings; extern FOptionMenuSettings OptionSettings;
extern MenuDescriptorList MenuDescriptors; extern MenuDescriptorList MenuDescriptors;
@ -258,11 +260,10 @@ public:
class DMenuItemBase : public DObject class DMenuItemBase : public DObject
{ {
DECLARE_CLASS(DMenuItemBase, DObject) DECLARE_CLASS(DMenuItemBase, DObject)
protected: public:
int mXpos, mYpos; int mXpos, mYpos;
FName mAction; FName mAction;
public:
bool mEnabled; bool mEnabled;
DMenuItemBase(int xpos = 0, int ypos = 0, FName action = NAME_None) DMenuItemBase(int xpos = 0, int ypos = 0, FName action = NAME_None)
@ -333,7 +334,7 @@ class DListMenuItemPlayerDisplay : public DMenuItemBase
{ {
DECLARE_CLASS(DListMenuItemPlayerDisplay, DMenuItemBase) DECLARE_CLASS(DListMenuItemPlayerDisplay, DMenuItemBase)
FListMenuDescriptor *mOwner; DListMenuDescriptor *mOwner;
FTexture *mBackdrop; FTexture *mBackdrop;
FRemapTable mRemap; FRemapTable mRemap;
FPlayerClass *mPlayerClass; FPlayerClass *mPlayerClass;
@ -365,7 +366,7 @@ public:
PDF_TRANSLATE = 0x10005, 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; void OnDestroy() override;
virtual void Ticker(); virtual void Ticker();
virtual void Drawer(bool selected); 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; HAS_OBJECT_POINTERS;
protected: protected:
FListMenuDescriptor *mDesc; DListMenuDescriptor *mDesc;
DMenuItemBase *mFocusControl; DMenuItemBase *mFocusControl;
public: public:
DListMenu(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); DListMenu(DMenu *parent = NULL, DListMenuDescriptor *desc = NULL);
virtual void Init(DMenu *parent = NULL, FListMenuDescriptor *desc = NULL); virtual void Init(DMenu *parent = NULL, DListMenuDescriptor *desc = NULL);
DMenuItemBase *GetItem(FName name); DMenuItemBase *GetItem(FName name);
bool Responder (event_t *ev); bool Responder (event_t *ev);
bool MenuEvent (int mkey, bool fromcontroller); bool MenuEvent (int mkey, bool fromcontroller);
@ -559,12 +560,11 @@ public:
class DOptionMenuItem : public DMenuItemBase class DOptionMenuItem : public DMenuItemBase
{ {
DECLARE_ABSTRACT_CLASS(DOptionMenuItem, DMenuItemBase) DECLARE_ABSTRACT_CLASS(DOptionMenuItem, DMenuItemBase)
protected: public:
FString mLabel; FString mLabel;
bool mCentered; bool mCentered;
void drawLabel(int indent, int y, EColorRange color, bool grayed = false); void drawLabel(int indent, int y, EColorRange color, bool grayed = false);
public:
DOptionMenuItem(const char *text = nullptr, FName action = NAME_None, bool center = false) DOptionMenuItem(const char *text = nullptr, FName action = NAME_None, bool center = false)
: DMenuItemBase(0, 0, action) : DMenuItemBase(0, 0, action)
@ -573,7 +573,7 @@ public:
mCentered = center; 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 bool Selectable();
virtual int GetIndent(); virtual int GetIndent();
virtual bool MouseEvent(int type, int x, int y); 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) DECLARE_CLASS(DOptionMenu, DMenu)
HAS_OBJECT_POINTERS; HAS_OBJECT_POINTERS;
public: // needs to be public for script access
bool CanScrollUp; bool CanScrollUp;
bool CanScrollDown; bool CanScrollDown;
int VisBottom; int VisBottom;
DOptionMenuItem *mFocusControl; DOptionMenuItem *mFocusControl;
DOptionMenuDescriptor *mDesc;
protected: //public:
FOptionMenuDescriptor *mDesc;
public:
DOptionMenuItem *GetItem(FName name); DOptionMenuItem *GetItem(FName name);
DOptionMenu(DMenu *parent = NULL, FOptionMenuDescriptor *desc = NULL); DOptionMenu(DMenu *parent = NULL, DOptionMenuDescriptor *desc = NULL);
virtual void Init(DMenu *parent = NULL, FOptionMenuDescriptor *desc = NULL); virtual void Init(DMenu *parent = NULL, DOptionMenuDescriptor *desc = NULL);
int FirstSelectable(); int FirstSelectable();
bool Responder (event_t *ev); bool Responder (event_t *ev);
bool MenuEvent (int mkey, bool fromcontroller); bool MenuEvent (int mkey, bool fromcontroller);
bool MouseEvent(int type, int x, int y); bool MouseEvent(int type, int x, int y);
void Ticker (); void Ticker ();
void Drawer (); void Drawer ();
const FOptionMenuDescriptor *GetDescriptor() const { return mDesc; } const DOptionMenuDescriptor *GetDescriptor() const { return mDesc; }
void SetFocus(DOptionMenuItem *fc) void SetFocus(DOptionMenuItem *fc)
{ {
mFocusControl = fc; mFocusControl = fc;

View file

@ -57,8 +57,8 @@
void ClearSaveGames(); void ClearSaveGames();
MenuDescriptorList MenuDescriptors; MenuDescriptorList MenuDescriptors;
static FListMenuDescriptor DefaultListMenuSettings; // contains common settings for all list menus static DListMenuDescriptor *DefaultListMenuSettings; // contains common settings for all list menus
static FOptionMenuDescriptor DefaultOptionMenuSettings; // contains common settings for all Option menus static DOptionMenuDescriptor *DefaultOptionMenuSettings; // contains common settings for all Option menus
FOptionMenuSettings OptionSettings; FOptionMenuSettings OptionSettings;
FOptionMap OptionValues; FOptionMap OptionValues;
bool mustPrintErrors; bool mustPrintErrors;
@ -67,18 +67,6 @@ void I_BuildALDeviceList(FOptionValues *opt);
static void DeinitMenus() static void DeinitMenus()
{ {
{
MenuDescriptorList::Iterator it(MenuDescriptors);
MenuDescriptorList::Pair *pair;
while (it.NextPair(pair))
{
delete pair->Value;
pair->Value = NULL;
}
}
{ {
FOptionMap::Iterator it(OptionValues); FOptionMap::Iterator it(OptionValues);
@ -87,13 +75,12 @@ static void DeinitMenus()
while (it.NextPair(pair)) while (it.NextPair(pair))
{ {
delete pair->Value; delete pair->Value;
pair->Value = NULL; pair->Value = nullptr;
} }
} }
MenuDescriptors.Clear(); MenuDescriptors.Clear();
OptionValues.Clear(); OptionValues.Clear();
DMenu::CurrentMenu = NULL; DMenu::CurrentMenu = nullptr;
DefaultListMenuSettings.mItems.Clear();
ClearSaveGames(); 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("{"); sc.MustGetStringName("{");
while (!sc.CheckString("}")) while (!sc.CheckString("}"))
@ -240,7 +227,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc)
{ {
sc.MustGetString(); sc.MustGetString();
const PClass *cls = PClass::FindClass(sc.String); 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); sc.ScriptError("Unknown menu class '%s'", sc.String);
} }
@ -367,7 +354,7 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc)
{ {
sc.MustGetString(); sc.MustGetString();
FFont *newfont = V_GetFont(sc.String); FFont *newfont = V_GetFont(sc.String);
if (newfont != NULL) desc->mFont = newfont; if (newfont != nullptr) desc->mFont = newfont;
if (sc.CheckString(",")) if (sc.CheckString(","))
{ {
sc.MustGetString(); sc.MustGetString();
@ -400,10 +387,10 @@ static void ParseListMenuBody(FScanner &sc, FListMenuDescriptor *desc)
int y = sc.Number; int y = sc.Number;
sc.MustGetStringName(","); sc.MustGetStringName(",");
sc.MustGetString(); sc.MustGetString();
PalEntry c1 = V_GetColor(NULL, sc); PalEntry c1 = V_GetColor(nullptr, sc);
sc.MustGetStringName(","); sc.MustGetStringName(",");
sc.MustGetString(); sc.MustGetString();
PalEntry c2 = V_GetColor(NULL, sc); PalEntry c2 = V_GetColor(nullptr, sc);
if (sc.CheckString(",")) if (sc.CheckString(","))
{ {
sc.MustGetNumber(); 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; 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); DMenuDescriptor **pOld = MenuDescriptors.CheckKey(desc->mMenuName);
if (pOld != NULL && *pOld != NULL) if (pOld != nullptr && *pOld != nullptr)
{ {
if (CheckCompatible(desc, *pOld)) if (!CheckCompatible(desc, *pOld))
{
delete *pOld;
}
else
{ {
sc.ScriptMessage("Tried to replace menu '%s' with a menu of different type", desc->mMenuName.GetChars()); sc.ScriptMessage("Tried to replace menu '%s' with a menu of different type", desc->mMenuName.GetChars());
return true; return true;
} }
} }
MenuDescriptors[desc->mMenuName] = desc; MenuDescriptors[desc->mMenuName] = desc;
GC::WriteBarrier(desc);
return false; return false;
} }
@ -522,31 +506,28 @@ static void ParseListMenu(FScanner &sc)
{ {
sc.MustGetString(); sc.MustGetString();
FListMenuDescriptor *desc = new FListMenuDescriptor; DListMenuDescriptor *desc = new DListMenuDescriptor;
desc->mType = MDESC_ListMenu;
desc->mMenuName = sc.String; desc->mMenuName = sc.String;
desc->mSelectedItem = -1; desc->mSelectedItem = -1;
desc->mAutoselect = -1; desc->mAutoselect = -1;
desc->mSelectOfsX = DefaultListMenuSettings.mSelectOfsX; desc->mSelectOfsX = DefaultListMenuSettings->mSelectOfsX;
desc->mSelectOfsY = DefaultListMenuSettings.mSelectOfsY; desc->mSelectOfsY = DefaultListMenuSettings->mSelectOfsY;
desc->mSelector = DefaultListMenuSettings.mSelector; desc->mSelector = DefaultListMenuSettings->mSelector;
desc->mDisplayTop = DefaultListMenuSettings.mDisplayTop; desc->mDisplayTop = DefaultListMenuSettings->mDisplayTop;
desc->mXpos = DefaultListMenuSettings.mXpos; desc->mXpos = DefaultListMenuSettings->mXpos;
desc->mYpos = DefaultListMenuSettings.mYpos; desc->mYpos = DefaultListMenuSettings->mYpos;
desc->mLinespacing = DefaultListMenuSettings.mLinespacing; desc->mLinespacing = DefaultListMenuSettings->mLinespacing;
desc->mNetgameMessage = DefaultListMenuSettings.mNetgameMessage; desc->mNetgameMessage = DefaultListMenuSettings->mNetgameMessage;
desc->mFont = DefaultListMenuSettings.mFont; desc->mFont = DefaultListMenuSettings->mFont;
desc->mFontColor = DefaultListMenuSettings.mFontColor; desc->mFontColor = DefaultListMenuSettings->mFontColor;
desc->mFontColor2 = DefaultListMenuSettings.mFontColor2; desc->mFontColor2 = DefaultListMenuSettings->mFontColor2;
desc->mClass = NULL; desc->mClass = nullptr;
desc->mRedirect = NULL;
desc->mWLeft = 0; desc->mWLeft = 0;
desc->mWRight = 0; desc->mWRight = 0;
desc->mCenter = false; desc->mCenter = false;
ParseListMenuBody(sc, desc); ParseListMenuBody(sc, desc);
bool scratch = ReplaceMenu(sc, desc); ReplaceMenu(sc, desc);
if (scratch) delete desc;
} }
//============================================================================= //=============================================================================
@ -573,7 +554,7 @@ static void ParseOptionValue(FScanner &sc)
pair.Text = strbin1(sc.String); pair.Text = strbin1(sc.String);
} }
FOptionValues **pOld = OptionValues.CheckKey(optname); FOptionValues **pOld = OptionValues.CheckKey(optname);
if (pOld != NULL && *pOld != NULL) if (pOld != nullptr && *pOld != nullptr)
{ {
delete *pOld; delete *pOld;
} }
@ -606,7 +587,7 @@ static void ParseOptionString(FScanner &sc)
pair.Text = strbin1(sc.String); pair.Text = strbin1(sc.String);
} }
FOptionValues **pOld = OptionValues.CheckKey(optname); FOptionValues **pOld = OptionValues.CheckKey(optname);
if (pOld != NULL && *pOld != NULL) if (pOld != nullptr && *pOld != nullptr)
{ {
delete *pOld; 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; EColorRange cr = OptionSettings.mFontColor;
if (sc.CheckString(",")) if (sc.CheckString(","))
@ -670,13 +651,13 @@ static EColorRange ParseOptionColor(FScanner &sc, FOptionMenuDescriptor *desc)
cr = V_FindFontColor(sc.String); cr = V_FindFontColor(sc.String);
if (cr == CR_UNTRANSLATED && !sc.Compare("untranslated") && isdigit(sc.String[0])) 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; return cr;
} }
static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc) static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc)
{ {
sc.MustGetStringName("{"); sc.MustGetStringName("{");
while (!sc.CheckString("}")) while (!sc.CheckString("}"))
@ -706,7 +687,7 @@ static void ParseOptionMenuBody(FScanner &sc, FOptionMenuDescriptor *desc)
{ {
sc.MustGetString(); sc.MustGetString();
const PClass *cls = PClass::FindClass(sc.String); 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); sc.ScriptError("Unknown menu class '%s'", sc.String);
} }
@ -947,21 +928,19 @@ static void ParseOptionMenu(FScanner &sc)
{ {
sc.MustGetString(); sc.MustGetString();
FOptionMenuDescriptor *desc = new FOptionMenuDescriptor; DOptionMenuDescriptor *desc = new DOptionMenuDescriptor;
desc->mType = MDESC_OptionsMenu;
desc->mMenuName = sc.String; desc->mMenuName = sc.String;
desc->mSelectedItem = -1; desc->mSelectedItem = -1;
desc->mScrollPos = 0; desc->mScrollPos = 0;
desc->mClass = NULL; desc->mClass = nullptr;
desc->mPosition = DefaultOptionMenuSettings.mPosition; desc->mPosition = DefaultOptionMenuSettings->mPosition;
desc->mScrollTop = DefaultOptionMenuSettings.mScrollTop; desc->mScrollTop = DefaultOptionMenuSettings->mScrollTop;
desc->mIndent = DefaultOptionMenuSettings.mIndent; desc->mIndent = DefaultOptionMenuSettings->mIndent;
desc->mDontDim = DefaultOptionMenuSettings.mDontDim; desc->mDontDim = DefaultOptionMenuSettings->mDontDim;
ParseOptionMenuBody(sc, desc); ParseOptionMenuBody(sc, desc);
bool scratch = ReplaceMenu(sc, desc); ReplaceMenu(sc, desc);
if (desc->mIndent == 0) desc->CalcIndent(); if (desc->mIndent == 0) desc->CalcIndent();
if (scratch) delete desc;
} }
@ -982,8 +961,11 @@ void M_ParseMenuDefs()
OptionSettings.mFontColorHeader = V_FindFontColor(gameinfo.mFontColorHeader); OptionSettings.mFontColorHeader = V_FindFontColor(gameinfo.mFontColorHeader);
OptionSettings.mFontColorHighlight = V_FindFontColor(gameinfo.mFontColorHighlight); OptionSettings.mFontColorHighlight = V_FindFontColor(gameinfo.mFontColorHighlight);
OptionSettings.mFontColorSelection = V_FindFontColor(gameinfo.mFontColorSelection); OptionSettings.mFontColorSelection = V_FindFontColor(gameinfo.mFontColorSelection);
DefaultListMenuSettings.Reset(); // these are supposed to get GC'd after parsing is complete.
DefaultOptionMenuSettings.Reset(); DefaultListMenuSettings = new DListMenuDescriptor;
DefaultOptionMenuSettings = new DOptionMenuDescriptor;
DefaultListMenuSettings->Reset();
DefaultOptionMenuSettings->Reset();
atterm( DeinitMenus); atterm( DeinitMenus);
DeinitMenus(); DeinitMenus();
@ -1004,8 +986,8 @@ void M_ParseMenuDefs()
} }
else if (sc.Compare("DEFAULTLISTMENU")) else if (sc.Compare("DEFAULTLISTMENU"))
{ {
ParseListMenuBody(sc, &DefaultListMenuSettings); ParseListMenuBody(sc, DefaultListMenuSettings);
if (DefaultListMenuSettings.mItems.Size() > 0) if (DefaultListMenuSettings->mItems.Size() > 0)
{ {
I_FatalError("You cannot add menu items to the menu default settings."); I_FatalError("You cannot add menu items to the menu default settings.");
} }
@ -1028,8 +1010,8 @@ void M_ParseMenuDefs()
} }
else if (sc.Compare("DEFAULTOPTIONMENU")) else if (sc.Compare("DEFAULTOPTIONMENU"))
{ {
ParseOptionMenuBody(sc, &DefaultOptionMenuSettings); ParseOptionMenuBody(sc, DefaultOptionMenuSettings);
if (DefaultOptionMenuSettings.mItems.Size() > 0) if (DefaultOptionMenuSettings->mItems.Size() > 0)
{ {
I_FatalError("You cannot add menu items to the menu default settings."); 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 // Build episode menu
bool success = false; bool success = false;
FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Episodemenu); DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Episodemenu);
if (desc != NULL) if (desc != nullptr)
{ {
if ((*desc)->mType == MDESC_ListMenu) if ((*desc)->IsKindOf(RUNTIME_CLASS(DListMenuDescriptor)))
{ {
FListMenuDescriptor *ld = static_cast<FListMenuDescriptor*>(*desc); DListMenuDescriptor *ld = static_cast<DListMenuDescriptor*>(*desc);
int posy = ld->mYpos; int posy = ld->mYpos;
int topy = posy; int topy = posy;
@ -1111,7 +1095,7 @@ static void BuildEpisodeMenu()
success = true; success = true;
for (auto &p : ld->mItems) 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 // 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. // Create an option menu for episode selection instead.
FOptionMenuDescriptor *od = new FOptionMenuDescriptor; DOptionMenuDescriptor *od = new DOptionMenuDescriptor;
if (desc != NULL) delete *desc;
MenuDescriptors[NAME_Episodemenu] = od; MenuDescriptors[NAME_Episodemenu] = od;
od->mType = MDESC_OptionsMenu;
od->mMenuName = NAME_Episodemenu; od->mMenuName = NAME_Episodemenu;
od->mTitle = "$MNU_EPISODE"; od->mTitle = "$MNU_EPISODE";
od->mSelectedItem = 0; od->mSelectedItem = 0;
od->mScrollPos = 0; od->mScrollPos = 0;
od->mClass = NULL; od->mClass = nullptr;
od->mPosition = -15; od->mPosition = -15;
od->mScrollTop = 0; od->mScrollTop = 0;
od->mIndent = 160; od->mIndent = 160;
od->mDontDim = false; od->mDontDim = false;
GC::WriteBarrier(od);
for(unsigned i = 0; i < AllEpisodes.Size(); i++) for(unsigned i = 0; i < AllEpisodes.Size(); i++)
{ {
DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu(AllEpisodes[i].mEpisodeName, "Skillmenu", i); DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu(AllEpisodes[i].mEpisodeName, "Skillmenu", i);
od->mItems.Push(it); od->mItems.Push(it);
GC::WriteBarrier(it); GC::WriteBarrier(od, it);
} }
} }
} }
@ -1153,12 +1136,12 @@ static void BuildPlayerclassMenu()
bool success = false; bool success = false;
// Build player class menu // Build player class menu
FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Playerclassmenu); DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Playerclassmenu);
if (desc != NULL) if (desc != nullptr)
{ {
if ((*desc)->mType == MDESC_ListMenu) if ((*desc)->IsKindOf(RUNTIME_CLASS(DListMenuDescriptor)))
{ {
FListMenuDescriptor *ld = static_cast<FListMenuDescriptor*>(*desc); DListMenuDescriptor *ld = static_cast<DListMenuDescriptor*>(*desc);
// add player display // add player display
ld->mSelectedItem = ld->mItems.Size(); ld->mSelectedItem = ld->mItems.Size();
@ -1179,7 +1162,7 @@ static void BuildPlayerclassMenu()
if (!(PlayerClasses[i].Flags & PCF_NOMENU)) if (!(PlayerClasses[i].Flags & PCF_NOMENU))
{ {
const char *pname = GetPrintableDisplayName(PlayerClasses[i].Type); const char *pname = GetPrintableDisplayName(PlayerClasses[i].Type);
if (pname != NULL) if (pname != nullptr)
{ {
numclassitems++; numclassitems++;
} }
@ -1216,7 +1199,7 @@ static void BuildPlayerclassMenu()
if (!(PlayerClasses[i].Flags & PCF_NOMENU)) if (!(PlayerClasses[i].Flags & PCF_NOMENU))
{ {
const char *pname = GetPrintableDisplayName(PlayerClasses[i].Type); const char *pname = GetPrintableDisplayName(PlayerClasses[i].Type);
if (pname != NULL) if (pname != nullptr)
{ {
DListMenuItemText *it = new DListMenuItemText(ld->mXpos, ld->mYpos, ld->mLinespacing, *pname, DListMenuItemText *it = new DListMenuItemText(ld->mXpos, ld->mYpos, ld->mLinespacing, *pname,
pname, ld->mFont,ld->mFontColor,ld->mFontColor2, NAME_Episodemenu, i); pname, ld->mFont,ld->mFontColor,ld->mFontColor2, NAME_Episodemenu, i);
@ -1235,7 +1218,7 @@ static void BuildPlayerclassMenu()
if (n == 0) if (n == 0)
{ {
const char *pname = GetPrintableDisplayName(PlayerClasses[0].Type); const char *pname = GetPrintableDisplayName(PlayerClasses[0].Type);
if (pname != NULL) if (pname != nullptr)
{ {
DListMenuItemText *it = new DListMenuItemText(ld->mXpos, ld->mYpos, ld->mLinespacing, *pname, DListMenuItemText *it = new DListMenuItemText(ld->mXpos, ld->mYpos, ld->mLinespacing, *pname,
pname, ld->mFont,ld->mFontColor,ld->mFontColor2, NAME_Episodemenu, 0); pname, ld->mFont,ld->mFontColor,ld->mFontColor2, NAME_Episodemenu, 0);
@ -1245,7 +1228,7 @@ static void BuildPlayerclassMenu()
success = true; success = true;
for (auto &p : ld->mItems) 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 // 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. // Create an option menu for class selection instead.
FOptionMenuDescriptor *od = new FOptionMenuDescriptor; DOptionMenuDescriptor *od = new DOptionMenuDescriptor;
if (desc != NULL) delete *desc;
MenuDescriptors[NAME_Playerclassmenu] = od; MenuDescriptors[NAME_Playerclassmenu] = od;
od->mType = MDESC_OptionsMenu;
od->mMenuName = NAME_Playerclassmenu; od->mMenuName = NAME_Playerclassmenu;
od->mTitle = "$MNU_CHOOSECLASS"; od->mTitle = "$MNU_CHOOSECLASS";
od->mSelectedItem = 0; od->mSelectedItem = 0;
od->mScrollPos = 0; od->mScrollPos = 0;
od->mClass = NULL; od->mClass = nullptr;
od->mPosition = -15; od->mPosition = -15;
od->mScrollTop = 0; od->mScrollTop = 0;
od->mIndent = 160; od->mIndent = 160;
od->mDontDim = false; od->mDontDim = false;
od->mNetgameMessage = "$NEWGAME"; od->mNetgameMessage = "$NEWGAME";
GC::WriteBarrier(od);
for (unsigned i = 0; i < PlayerClasses.Size (); i++) for (unsigned i = 0; i < PlayerClasses.Size (); i++)
{ {
if (!(PlayerClasses[i].Flags & PCF_NOMENU)) if (!(PlayerClasses[i].Flags & PCF_NOMENU))
{ {
const char *pname = GetPrintableDisplayName(PlayerClasses[i].Type); const char *pname = GetPrintableDisplayName(PlayerClasses[i].Type);
if (pname != NULL) if (pname != nullptr)
{ {
DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu(pname, "Episodemenu", i); DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu(pname, "Episodemenu", i);
od->mItems.Push(it); od->mItems.Push(it);
GC::WriteBarrier(it); GC::WriteBarrier(od, it);
} }
} }
} }
DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu("Random", "Episodemenu", -1); DOptionMenuItemSubmenu *it = new DOptionMenuItemSubmenu("Random", "Episodemenu", -1);
od->mItems.Push(it); od->mItems.Push(it);
GC::WriteBarrier(it); GC::WriteBarrier(od, it);
} }
} }
@ -1302,7 +1283,7 @@ static void InitCrosshairsList()
lastlump = 0; lastlump = 0;
FOptionValues **opt = OptionValues.CheckKey(NAME_Crosshairs); FOptionValues **opt = OptionValues.CheckKey(NAME_Crosshairs);
if (opt == NULL) if (opt == nullptr)
{ {
return; // no crosshair value list present. No need to go on. return; // no crosshair value list present. No need to go on.
} }
@ -1353,12 +1334,12 @@ static void InitCrosshairsList()
static void InitKeySections() static void InitKeySections()
{ {
FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_CustomizeControls); DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_CustomizeControls);
if (desc != NULL) if (desc != nullptr)
{ {
if ((*desc)->mType == MDESC_OptionsMenu) if ((*desc)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor)))
{ {
FOptionMenuDescriptor *menu = static_cast<FOptionMenuDescriptor*>(*desc); DOptionMenuDescriptor *menu = static_cast<DOptionMenuDescriptor*>(*desc);
for (unsigned i = 0; i < KeySections.Size(); i++) for (unsigned i = 0; i < KeySections.Size(); i++)
{ {
@ -1376,7 +1357,7 @@ static void InitKeySections()
} }
for (auto &p : menu->mItems) for (auto &p : menu->mItems)
{ {
GC::WriteBarrier(p); GC::WriteBarrier(*desc, p);
} }
} }
} }
@ -1396,12 +1377,12 @@ void M_CreateMenus()
InitKeySections(); InitKeySections();
FOptionValues **opt = OptionValues.CheckKey(NAME_Mididevices); FOptionValues **opt = OptionValues.CheckKey(NAME_Mididevices);
if (opt != NULL) if (opt != nullptr)
{ {
I_BuildMIDIMenuList(*opt); I_BuildMIDIMenuList(*opt);
} }
opt = OptionValues.CheckKey(NAME_Aldevices); opt = OptionValues.CheckKey(NAME_Aldevices);
if (opt != NULL) if (opt != nullptr)
{ {
I_BuildALDeviceList(*opt); I_BuildALDeviceList(*opt);
} }
@ -1418,19 +1399,19 @@ void M_StartupSkillMenu(FGameStartup *gs)
{ {
static int done = -1; static int done = -1;
bool success = false; bool success = false;
FMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Skillmenu); DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_Skillmenu);
if (desc != NULL) if (desc != nullptr)
{ {
if ((*desc)->mType == MDESC_ListMenu) if ((*desc)->IsKindOf(RUNTIME_CLASS(DListMenuDescriptor)))
{ {
FListMenuDescriptor *ld = static_cast<FListMenuDescriptor*>(*desc); DListMenuDescriptor *ld = static_cast<DListMenuDescriptor*>(*desc);
int x = ld->mXpos; int x = ld->mXpos;
int y = ld->mYpos; int y = ld->mYpos;
// Delete previous contents // Delete previous contents
for(unsigned i=0; i<ld->mItems.Size(); i++) for(unsigned i=0; i<ld->mItems.Size(); i++)
{ {
FName n = ld->mItems[i]->GetAction(NULL); FName n = ld->mItems[i]->GetAction(nullptr);
if (n == NAME_Startgame || n == NAME_StartgameConfirm) if (n == NAME_Startgame || n == NAME_StartgameConfirm)
{ {
ld->mItems.Resize(i); ld->mItems.Resize(i);
@ -1477,8 +1458,7 @@ void M_StartupSkillMenu(FGameStartup *gs)
else else
{ {
// too large // too large
delete ld; desc = nullptr;
desc = NULL;
done = false; done = false;
goto fail; 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. // Using a different name for skills that must be confirmed makes handling this easier.
FName action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ? FName action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ?
NAME_StartgameConfirm : NAME_Startgame; NAME_StartgameConfirm : NAME_Startgame;
FString *pItemText = NULL; FString *pItemText = nullptr;
if (gs->PlayerClass != NULL) if (gs->PlayerClass != nullptr)
{ {
pItemText = skill.MenuNamesForPlayerClass.CheckKey(gs->PlayerClass); 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); FTextureID tex = GetMenuTexture(skill.PicName);
li = new DListMenuItemPatch(ld->mXpos, y, ld->mLinespacing, skill.Shortcut, tex, action, i); 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); pItemText? *pItemText : skill.MenuName, ld->mFont, color,ld->mFontColor2, action, i);
} }
ld->mItems.Push(li); ld->mItems.Push(li);
GC::WriteBarrier(li); GC::WriteBarrier(*desc, li);
y += ld->mLinespacing; y += ld->mLinespacing;
} }
if (AllEpisodes[gs->Episode].mNoSkill || AllSkills.Size() == 1) if (AllEpisodes[gs->Episode].mNoSkill || AllSkills.Size() == 1)
@ -1528,26 +1508,25 @@ void M_StartupSkillMenu(FGameStartup *gs)
if (success) return; if (success) return;
fail: fail:
// Option menu fallback for overlong skill lists // Option menu fallback for overlong skill lists
FOptionMenuDescriptor *od; DOptionMenuDescriptor *od;
if (desc == NULL) if (desc == nullptr)
{ {
od = new FOptionMenuDescriptor; od = new DOptionMenuDescriptor;
if (desc != NULL) delete *desc;
MenuDescriptors[NAME_Skillmenu] = od; MenuDescriptors[NAME_Skillmenu] = od;
od->mType = MDESC_OptionsMenu;
od->mMenuName = NAME_Skillmenu; od->mMenuName = NAME_Skillmenu;
od->mTitle = "$MNU_CHOOSESKILL"; od->mTitle = "$MNU_CHOOSESKILL";
od->mSelectedItem = 0; od->mSelectedItem = 0;
od->mScrollPos = 0; od->mScrollPos = 0;
od->mClass = NULL; od->mClass = nullptr;
od->mPosition = -15; od->mPosition = -15;
od->mScrollTop = 0; od->mScrollTop = 0;
od->mIndent = 160; od->mIndent = 160;
od->mDontDim = false; od->mDontDim = false;
GC::WriteBarrier(od);
} }
else else
{ {
od = static_cast<FOptionMenuDescriptor*>(*desc); od = static_cast<DOptionMenuDescriptor*>(*desc);
od->mItems.Clear(); od->mItems.Clear();
} }
for(unsigned int i = 0; i < AllSkills.Size(); i++) for(unsigned int i = 0; i < AllSkills.Size(); i++)
@ -1558,14 +1537,14 @@ fail:
const char *action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ? const char *action = (skill.MustConfirm && !AllEpisodes[gs->Episode].mNoSkill) ?
"StartgameConfirm" : "Startgame"; "StartgameConfirm" : "Startgame";
FString *pItemText = NULL; FString *pItemText = nullptr;
if (gs->PlayerClass != NULL) if (gs->PlayerClass != nullptr)
{ {
pItemText = skill.MenuNamesForPlayerClass.CheckKey(gs->PlayerClass); pItemText = skill.MenuNamesForPlayerClass.CheckKey(gs->PlayerClass);
} }
li = new DOptionMenuItemSubmenu(pItemText? *pItemText : skill.MenuName, action, i); li = new DOptionMenuItemSubmenu(pItemText? *pItemText : skill.MenuName, action, i);
od->mItems.Push(li); od->mItems.Push(li);
GC::WriteBarrier(li); GC::WriteBarrier(od, li);
if (!done) if (!done)
{ {
done = true; done = true;

View file

@ -76,7 +76,7 @@ IMPLEMENT_POINTERS_END
// //
//============================================================================= //=============================================================================
DOptionMenu::DOptionMenu(DMenu *parent, FOptionMenuDescriptor *desc) DOptionMenu::DOptionMenu(DMenu *parent, DOptionMenuDescriptor *desc)
: DMenu(parent) : DMenu(parent)
{ {
CanScrollUp = false; 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; mParentMenu = parent;
GC::WriteBarrier(this, 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; 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 // calculate the menu indent
int widest = 0, thiswidth; 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;i<mItems.Size(); i++) for(unsigned i=0;i<mItems.Size(); i++)
{ {

View file

@ -60,7 +60,7 @@ public:
mParam = param; mParam = param;
} }
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.mFontColorMore); drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColorMore);
return indent; return indent;
@ -221,7 +221,7 @@ public:
virtual void SetSelection(int Selection) = 0; virtual void SetSelection(int Selection) = 0;
//============================================================================= //=============================================================================
int Draw(FOptionMenuDescriptor *desc, int y, int indent, bool selected) int Draw(DOptionMenuDescriptor *desc, int y, int indent, bool selected)
{ {
bool grayed = mGrayCheck != NULL && !(mGrayCheck->GetGenericRep(CVAR_Bool).Bool); bool grayed = mGrayCheck != NULL && !(mGrayCheck->GetGenericRep(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: drawLabel(indent, y, mWaiting? OptionSettings.mFontColorHighlight:
(selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor)); (selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor));
@ -541,7 +541,7 @@ public:
mColor = cr; 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); drawLabel(indent, y, mColor);
return -1; return -1;
@ -581,7 +581,7 @@ public:
mCurrent = 0; 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(); const char *txt = mCurrent? mAltText.GetChars() : mLabel.GetChars();
if (*txt == '$') txt = GStrings(txt + 1); 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); drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor);
mDrawX = indent + CURSORSPACE; 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); drawLabel(indent, y, selected? OptionSettings.mFontColorSelection : OptionSettings.mFontColor);
@ -1038,7 +1038,7 @@ public:
return true; 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; int colwidth = screen->GetWidth() / 3;
EColorRange color; EColorRange color;
@ -1108,7 +1108,7 @@ public:
return GetCVarString(); 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 ); bool grayed = mGrayCheck != NULL && !( mGrayCheck->GetGenericRep( CVAR_Bool ).Bool );
drawLabel( indent, y, selected ? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, grayed ); drawLabel( indent, y, selected ? OptionSettings.mFontColorSelection : OptionSettings.mFontColor, grayed );
@ -1186,7 +1186,7 @@ public:
return text; return text;
} }
int Draw(FOptionMenuDescriptor*desc, int y, int indent, bool selected) int Draw(DOptionMenuDescriptor*desc, int y, int indent, bool selected)
{ {
if (mEntering) if (mEntering)
{ {

View file

@ -355,7 +355,7 @@ void FBackdropTexture::Render()
// //
//============================================================================= //=============================================================================
IMPLEMENT_CLASS(DListMenuItemPlayerDisplay, false, false) 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) : DMenuItemBase(x, y, action)
{ {
mOwner = menu; mOwner = menu;

View file

@ -509,7 +509,7 @@ class DPlayerMenu : public DListMenu
public: public:
DPlayerMenu() {} DPlayerMenu() {}
void Init(DMenu *parent, FListMenuDescriptor *desc); void Init(DMenu *parent, DListMenuDescriptor *desc);
bool Responder (event_t *ev); bool Responder (event_t *ev);
bool MenuEvent (int mkey, bool fromcontroller); bool MenuEvent (int mkey, bool fromcontroller);
bool MouseEvent(int type, int x, int y); 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; DMenuItemBase *li;

View file

@ -66,7 +66,7 @@
static void BuildModesList (int hiwidth, int hiheight, int hi_id); static void BuildModesList (int hiwidth, int hiheight, int hi_id);
static bool GetSelectedSize (int *width, int *height); static bool GetSelectedSize (int *width, int *height);
static void SetModesMenu (int w, int h, int bits); static void SetModesMenu (int w, int h, int bits);
FOptionMenuDescriptor *GetVideoModeMenu(); DOptionMenuDescriptor *GetVideoModeMenu();
extern bool setmodeneeded; extern bool setmodeneeded;
extern int NewWidth, NewHeight, NewBits; 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) CUSTOM_CVAR (Bool, vid_tft, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{ {
FOptionMenuDescriptor *opt = GetVideoModeMenu(); DOptionMenuDescriptor *opt = GetVideoModeMenu();
if (opt != NULL) if (opt != NULL)
{ {
DOptionMenuItem *it = opt->GetItem("menu_screenratios"); 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); DMenuDescriptor **desc = MenuDescriptors.CheckKey(NAME_VideoModeMenu);
if (desc != NULL && (*desc)->mType == MDESC_OptionsMenu) if (desc != NULL && (*desc)->IsKindOf(RUNTIME_CLASS(DOptionMenuDescriptor)))
{ {
return (FOptionMenuDescriptor *)*desc; return (DOptionMenuDescriptor *)*desc;
} }
return NULL; return NULL;
} }
@ -231,7 +231,7 @@ static void BuildModesList (int hiwidth, int hiheight, int hi_bits)
Video->StartModeIterator (showbits, screen->IsFullscreen()); Video->StartModeIterator (showbits, screen->IsFullscreen());
} }
FOptionMenuDescriptor *opt = GetVideoModeMenu(); DOptionMenuDescriptor *opt = GetVideoModeMenu();
if (opt != NULL) if (opt != NULL)
{ {
for (i = NAME_res_0; i<= NAME_res_9; i++) for (i = NAME_res_0; i<= NAME_res_9; i++)
@ -354,7 +354,7 @@ void M_InitVideoModesMenu ()
static bool GetSelectedSize (int *width, int *height) static bool GetSelectedSize (int *width, int *height)
{ {
FOptionMenuDescriptor *opt = GetVideoModeMenu(); DOptionMenuDescriptor *opt = GetVideoModeMenu();
if (opt != NULL && (unsigned)opt->mSelectedItem < opt->mItems.Size()) if (opt != NULL && (unsigned)opt->mSelectedItem < opt->mItems.Size())
{ {
int line = opt->mSelectedItem; int line = opt->mSelectedItem;
@ -420,7 +420,7 @@ static void SetModesMenu (int w, int h, int bits)
{ {
DummyDepthCvar = FindBits (bits); DummyDepthCvar = FindBits (bits);
FOptionMenuDescriptor *opt = GetVideoModeMenu(); DOptionMenuDescriptor *opt = GetVideoModeMenu();
if (opt != NULL) if (opt != NULL)
{ {
DOptionMenuItem *it; DOptionMenuItem *it;

View file

@ -7,7 +7,7 @@
#include "zscript/actor_checks.txt" #include "zscript/actor_checks.txt"
#include "zscript/menu/menu.txt" #include "zscript/menu/menu.txt"
#include "zscript/menu/menuitembase.txt" //#include "zscript/menu/menuitembase.txt"
#include "zscript/inventory/inventory.txt" #include "zscript/inventory/inventory.txt"
#include "zscript/inventory/inv_misc.txt" #include "zscript/inventory/inv_misc.txt"

View file

@ -2,6 +2,31 @@
class Menu : Object native class Menu : Object native
{ {
//native static int MenuTime(); //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<Menu> 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 struct FOptionMenuSettings
@ -15,3 +40,45 @@ struct FOptionMenuSettings
int mFontColorSelection; int mFontColorSelection;
int mLinespacing; int mLinespacing;
} }
class OptionMenuDescriptor : MenuDescriptor native
{
native Array<OptionMenuItem> 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;
}