diff --git a/src/menu/messagebox.cpp b/src/menu/messagebox.cpp index 078d7f31e..8cbaa3e24 100644 --- a/src/menu/messagebox.cpp +++ b/src/menu/messagebox.cpp @@ -46,97 +46,8 @@ #include "c_dispatch.h" #include "g_game.h" - -class DBrokenLines : public DObject -{ - DECLARE_ABSTRACT_CLASS(DBrokenLines, DObject) - -public: - FBrokenLines *mBroken; - unsigned int mCount; - - DBrokenLines(FBrokenLines *broken, unsigned int count) - { - mBroken = broken; - mCount = count; - } - - void OnDestroy() override - { - V_FreeBrokenLines(mBroken); - } -}; - - EXTERN_CVAR (Bool, saveloadconfirmation) // [mxd] -class DMessageBoxMenu : public DMenu -{ - DECLARE_CLASS(DMessageBoxMenu, DMenu) -public: - DBrokenLines *mMessage; - int mMessageMode; - int messageSelection; - int mMouseLeft, mMouseRight, mMouseY; - FName mAction; - void (*Handler)(); - -public: - - DMessageBoxMenu(DMenu *parent = NULL, const char *message = NULL, int messagemode = 0, bool playsound = false, FName action = NAME_None, void (*hnd)() = nullptr); - void Init(DMenu *parent, const char *message, int messagemode, bool playsound = false, void(*hnd)() = nullptr); -}; - -IMPLEMENT_CLASS(DMessageBoxMenu, false, false) - -//============================================================================= -// -// -// -//============================================================================= - -DMessageBoxMenu::DMessageBoxMenu(DMenu *parent, const char *message, int messagemode, bool playsound, FName action, void (*hnd)()) -: DMenu(parent) -{ - mAction = action; - messageSelection = 0; - mMouseLeft = 140; - mMouseY = INT_MIN; - int mr1 = 170 + SmallFont->StringWidth(GStrings["TXT_YES"]); - int mr2 = 170 + SmallFont->StringWidth(GStrings["TXT_NO"]); - mMouseRight = MAX(mr1, mr2); - - Init(parent, message, messagemode, playsound, hnd); -} - -//============================================================================= -// -// -// -//============================================================================= - -void DMessageBoxMenu::Init(DMenu *parent, const char *message, int messagemode, bool playsound, void (*hnd)()) -{ - mParentMenu = parent; - if (message != NULL) - { - if (*message == '$') message = GStrings(message+1); - unsigned count; - auto Message = V_BreakLines(SmallFont, 300, message, true, &count); - mMessage = new DBrokenLines(Message, count); - GC::WriteBarrier(mMessage); - mMessage->ObjectFlags |= OF_Fixed; - } - else mMessage = NULL; - mMessageMode = messagemode; - if (playsound) - { - S_StopSound (CHAN_VOICE); - S_Sound (CHAN_VOICE | CHAN_UI, "menu/prompt", snd_menuvolume, ATTN_NONE); - } - Handler = hnd; -} - typedef void(*hfunc)(); DEFINE_ACTION_FUNCTION(DMessageBoxMenu, CallHandler) { @@ -152,6 +63,23 @@ DEFINE_ACTION_FUNCTION(DMessageBoxMenu, CallHandler) // //============================================================================= +DMenu *CreateMessageBoxMenu(DMenu *parent, const char *message, int messagemode, bool playsound, FName action = NAME_None, hfunc handler = nullptr) +{ + auto c = PClass::FindClass("MessageBoxMenu"); + auto p = c->CreateNew(); + VMValue params[] = { p, parent, FString(message), messagemode, playsound, action.GetIndex(), handler }; + + auto f = dyn_cast(c->Symbols.FindSymbol("Init", false)); + GlobalVMStack.Call(f->Variants[0].Implementation, params, countof(params), nullptr, 0); + return (DMenu*)p; +} + +//============================================================================= +// +// +// +//============================================================================= + CCMD (menu_quit) { // F10 M_StartControlPanel (true); @@ -172,7 +100,7 @@ CCMD (menu_quit) } else EndString = gameinfo.quitmessages[messageindex]; - DMenu *newmenu = new DMessageBoxMenu(CurrentMenu, EndString, 0, false, NAME_None, []() + DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, EndString, 0, false, NAME_None, []() { if (!netgame) { @@ -209,7 +137,7 @@ CCMD (menu_endgame) S_Sound (CHAN_VOICE | CHAN_UI, "menu/activate", snd_menuvolume, ATTN_NONE); FString tempstring = GStrings(netgame ? "NETEND" : "ENDGAME"); - DMenu *newmenu = new DMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []() + DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []() { M_ClearMenus(); if (!netgame) @@ -258,7 +186,7 @@ CCMD (quicksave) FString tempstring; tempstring.Format(GStrings("QSPROMPT"), savegameManager.quickSaveSlot->SaveTitle.GetChars()); - DMenu *newmenu = new DMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []() + DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []() { G_SaveGame(savegameManager.quickSaveSlot->Filename.GetChars(), savegameManager.quickSaveSlot->SaveTitle.GetChars()); S_Sound(CHAN_VOICE | CHAN_UI, "menu/dismiss", snd_menuvolume, ATTN_NONE); @@ -303,7 +231,7 @@ CCMD (quickload) M_StartControlPanel(true); - DMenu *newmenu = new DMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []() + DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, tempstring, 0, false, NAME_None, []() { G_LoadGame(savegameManager.quickSaveSlot->Filename.GetChars()); S_Sound(CHAN_VOICE | CHAN_UI, "menu/dismiss", snd_menuvolume, ATTN_NONE); @@ -325,7 +253,7 @@ void M_StartMessage(const char *message, int messagemode, FName action) // only play a sound if no menu was active before M_StartControlPanel(menuactive == MENU_Off); } - DMenu *newmenu = new DMessageBoxMenu(CurrentMenu, message, messagemode, false, action); + DMenu *newmenu = CreateMessageBoxMenu(CurrentMenu, message, messagemode, false, action); newmenu->mParentMenu = CurrentMenu; M_ActivateMenu(newmenu); } @@ -339,13 +267,3 @@ DEFINE_ACTION_FUNCTION(DMenu, StartMessage) M_StartMessage(msg, mode, action); return 0; } - - -DEFINE_FIELD(DMessageBoxMenu, mMessageMode); -DEFINE_FIELD(DMessageBoxMenu, messageSelection); -DEFINE_FIELD(DMessageBoxMenu, mMouseLeft); -DEFINE_FIELD(DMessageBoxMenu, mMouseRight); -DEFINE_FIELD(DMessageBoxMenu, mMouseY); -DEFINE_FIELD(DMessageBoxMenu, mAction); -DEFINE_FIELD(DMessageBoxMenu, Handler); -DEFINE_FIELD(DMessageBoxMenu, mMessage); diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 9ae86abb5..47dad06be 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -171,13 +171,6 @@ struct Screen native native static void DrawFrame(int x, int y, int w, int h); } -class BrokenLines : Object native -{ - native int Count(); - native int StringWidth(int line); - native String StringAt(int line); -} - struct Font native { enum EColorRange @@ -248,7 +241,7 @@ struct Font native native static int FindFontColor(Name color); native static Font FindFont(Name fontname); native static Font GetFont(Name fontname); - native static BrokenLines BreakLines(String text, int maxlen); + native BrokenLines BreakLines(String text, int maxlen); } struct Translation @@ -332,6 +325,13 @@ class Object native virtual void OnDestroy() {} } +class BrokenLines : Object native +{ + native int Count(); + native int StringWidth(int line); + native String StringAt(int line); +} + class Thinker : Object native { enum EStatnums diff --git a/wadsrc/static/zscript/menu/messagebox.txt b/wadsrc/static/zscript/menu/messagebox.txt index f6ad0c639..deb73046e 100644 --- a/wadsrc/static/zscript/menu/messagebox.txt +++ b/wadsrc/static/zscript/menu/messagebox.txt @@ -32,14 +32,14 @@ ** */ -class MessageBoxMenu : Menu native +class MessageBoxMenu : Menu { - native BrokenLines mMessage; - native voidptr Handler; - native int mMessageMode; - native int messageSelection; - native int mMouseLeft, mMouseRight, mMouseY; - native Name mAction; + BrokenLines mMessage; + voidptr Handler; + int mMessageMode; + int messageSelection; + int mMouseLeft, mMouseRight, mMouseY; + Name mAction; native static void CallHandler(voidptr hnd); @@ -50,12 +50,26 @@ class MessageBoxMenu : Menu native // //============================================================================= - override void OnDestroy() + void Init(Menu parent, String message, int messagemode, bool playsound = false, Name cmd = 'None', voidptr native_handler = null) { - mMessage.Destroy(); // explicitly free the strings now. - Super.OnDestroy(); + Super.Init(parent); + mAction = cmd; + messageSelection = 0; + mMouseLeft = 140; + mMouseY = 0x80000000; + int mr1 = 170 + SmallFont.StringWidth(Stringtable.Localize("$TXT_YES")); + int mr2 = 170 + SmallFont.StringWidth(Stringtable.Localize("TXT_NO")); + mMouseRight = MAX(mr1, mr2); + mParentMenu = parent; + mMessage = SmallFont.BreakLines(message, 300); + mMessageMode = messagemode; + if (playsound) + { + MenuSound ("menu/prompt"); + } + Handler = native_handler; } - + //============================================================================= // // @@ -70,17 +84,14 @@ class MessageBoxMenu : Menu native y = 100; - if (mMessage != NULL) - { - int c = mMessage.Count(); - for (i = 0; i < c; i++) - y -= SmallFont.GetHeight () / 2; + int c = mMessage.Count(); + for (i = 0; i < c; i++) + y -= SmallFont.GetHeight () / 2; - for (i = 0; i < c; i++) - { - screen.DrawText (SmallFont, Font.CR_UNTRANSLATED, 160 - mMessage.StringWidth(i)/2, y, mMessage.StringAt(i), DTA_Clean, true); - y += fontheight; - } + for (i = 0; i < c; i++) + { + screen.DrawText (SmallFont, Font.CR_UNTRANSLATED, 160 - mMessage.StringWidth(i)/2, y, mMessage.StringAt(i), DTA_Clean, true); + y += fontheight; } if (mMessageMode == 0)