From 9089beb110fd834e5b8d216d5ec93a3c84cc9631 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 19 Feb 2017 15:23:33 +0100 Subject: [PATCH] - scriptified most of the remaining parts of DMenu. Only the engine interface remains native now. --- src/gi.cpp | 1 + src/menu/menu.cpp | 236 ++++------------------------ src/menu/menu.h | 23 --- src/scripting/thingdef_data.cpp | 8 + wadsrc/static/zscript/base.txt | 1 + wadsrc/static/zscript/menu/menu.txt | 185 ++++++++++++++++++++-- 6 files changed, 211 insertions(+), 243 deletions(-) diff --git a/src/gi.cpp b/src/gi.cpp index c497bf176a..18fd39f69b 100644 --- a/src/gi.cpp +++ b/src/gi.cpp @@ -52,6 +52,7 @@ DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, ArmorIcon2) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, gametype) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, norandomplayerclass) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, infoPages) +DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, mBackButton) const char *GameNames[17] = diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index b0bf096f88..c64b057117 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -164,53 +164,11 @@ DMenu::DMenu(DMenu *parent) GC::WriteBarrier(this, parent); } -bool DMenu::Responder (event_t *ev) -{ - bool res = false; - if (ev->type == EV_GUI_Event) - { - if (ev->subtype == EV_GUI_LButtonDown) - { - res = MouseEventBack(MOUSE_Click, ev->data1, ev->data2); - // make the menu's mouse handler believe that the current coordinate is outside the valid range - if (res) ev->data2 = -1; - res |= CallMouseEvent(MOUSE_Click, ev->data1, ev->data2); - if (res) - { - SetCapture(); - } - - } - else if (ev->subtype == EV_GUI_MouseMove) - { - BackbuttonTime = BACKBUTTON_TIME; - if (mMouseCapture || m_use_mouse == 1) - { - res = MouseEventBack(MOUSE_Move, ev->data1, ev->data2); - if (res) ev->data2 = -1; - res |= CallMouseEvent(MOUSE_Move, ev->data1, ev->data2); - } - } - else if (ev->subtype == EV_GUI_LButtonUp) - { - if (mMouseCapture) - { - ReleaseCapture(); - res = MouseEventBack(MOUSE_Release, ev->data1, ev->data2); - if (res) ev->data2 = -1; - res |= CallMouseEvent(MOUSE_Release, ev->data1, ev->data2); - } - } - } - return false; -} - -DEFINE_ACTION_FUNCTION(DMenu, Responder) -{ - PARAM_SELF_PROLOGUE(DMenu); - PARAM_POINTER(ev, event_t); - ACTION_RETURN_BOOL(self->Responder(ev)); -} +//============================================================================= +// +// +// +//============================================================================= bool DMenu::CallResponder(event_t *ev) { @@ -222,7 +180,7 @@ bool DMenu::CallResponder(event_t *ev) GlobalVMStack.Call(func, params, 2, &ret, 1, nullptr); return !!retval; } - else return Responder(ev); + else return false; } //============================================================================= @@ -231,29 +189,6 @@ bool DMenu::CallResponder(event_t *ev) // //============================================================================= -bool DMenu::MenuEvent (int mkey, bool fromcontroller) -{ - switch (mkey) - { - case MKEY_Back: - { - Close(); - S_Sound (CHAN_VOICE | CHAN_UI, - 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)); -} - bool DMenu::CallMenuEvent(int mkey, bool fromcontroller) { IFVIRTUAL(DMenu, MenuEvent) @@ -264,7 +199,7 @@ bool DMenu::CallMenuEvent(int mkey, bool fromcontroller) GlobalVMStack.Call(func, params, 3, &ret, 1, nullptr); return !!retval; } - else return MenuEvent(mkey, fromcontroller); + else return false; } //============================================================================= // @@ -272,6 +207,15 @@ bool DMenu::CallMenuEvent(int mkey, bool fromcontroller) // //============================================================================= +DEFINE_ACTION_FUNCTION(DMenu, SetMouseCapture) +{ + PARAM_PROLOGUE; + PARAM_BOOL(on); + if (on) I_SetMouseCapture(); + else I_ReleaseMouseCapture(); + return 0; +} + void DMenu::Close () { if (CurrentMenu == nullptr) return; // double closing can happen in the save menu. @@ -288,108 +232,19 @@ void DMenu::Close () } } -//============================================================================= -// -// -// -//============================================================================= - -bool DMenu::MouseEvent(int type, int x, int y) -{ - return true; -} - -DEFINE_ACTION_FUNCTION(DMenu, MouseEvent) +DEFINE_ACTION_FUNCTION(DMenu, Close) { PARAM_SELF_PROLOGUE(DMenu); - PARAM_INT(type); - PARAM_INT(x); - PARAM_INT(y); - ACTION_RETURN_BOOL(self->MouseEvent(type, x, y)); -} - -bool DMenu::CallMouseEvent(int type, int x, int y) -{ - IFVIRTUAL(DMenu, MouseEvent) - { - VMValue params[] = { (DObject*)this, type, x, y }; - int retval; - VMReturn ret(&retval); - GlobalVMStack.Call(func, params, 4, &ret, 1, nullptr); - return !!retval; - } - else return MouseEvent (type, x, y); -} - -//============================================================================= -// -// -// -//============================================================================= - -bool DMenu::MouseEventBack(int type, int x, int y) -{ - if (m_show_backbutton >= 0) - { - FTexture *tex = TexMan(gameinfo.mBackButton); - 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; - mBackbuttonSelected = ( x >= 0 && x < tex->GetScaledWidth() * CleanXfac && - y >= 0 && y < tex->GetScaledHeight() * CleanYfac); - if (mBackbuttonSelected && type == MOUSE_Release) - { - if (m_use_mouse == 2) mBackbuttonSelected = false; - CallMenuEvent(MKEY_Back, true); - } - return mBackbuttonSelected; - } - } - return false; -} - -//============================================================================= -// -// -// -//============================================================================= - -void DMenu::SetCapture() -{ - if (!mMouseCapture) - { - mMouseCapture = true; - I_SetMouseCapture(); - } -} - -void DMenu::ReleaseCapture() -{ - if (mMouseCapture) - { - mMouseCapture = false; - I_ReleaseMouseCapture(); - } -} - -//============================================================================= -// -// -// -//============================================================================= - -void DMenu::Ticker () -{ -} - -DEFINE_ACTION_FUNCTION(DMenu, Ticker) -{ - PARAM_SELF_PROLOGUE(DMenu); - self->Ticker(); + self->Close(); return 0; } +//============================================================================= +// +// +// +//============================================================================= + void DMenu::CallTicker() { IFVIRTUAL(DMenu, Ticker) @@ -397,38 +252,9 @@ void DMenu::CallTicker() VMValue params[] = { (DObject*)this }; GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr); } - else Ticker(); } -void DMenu::Drawer () -{ - if (this == CurrentMenu && BackbuttonAlpha > 0 && m_show_backbutton >= 0 && m_use_mouse) - { - FTexture *tex = TexMan(gameinfo.mBackButton); - int w = tex->GetScaledWidth() * CleanXfac; - int h = tex->GetScaledHeight() * CleanYfac; - int x = (!(m_show_backbutton&1))? 0:screen->GetWidth() - w; - int y = (!(m_show_backbutton&2))? 0:screen->GetHeight() - h; - if (mBackbuttonSelected && (mMouseCapture || m_use_mouse == 1)) - { - screen->DrawTexture(tex, x, y, DTA_CleanNoMove, true, DTA_ColorOverlay, MAKEARGB(40, 255,255,255), TAG_DONE); - } - else - { - screen->DrawTexture(tex, x, y, DTA_CleanNoMove, true, DTA_Alpha, BackbuttonAlpha, TAG_DONE); - } - } -} - - -DEFINE_ACTION_FUNCTION(DMenu, Drawer) -{ - PARAM_SELF_PROLOGUE(DMenu); - self->Drawer(); - return 0; -} - void DMenu::CallDrawer() { IFVIRTUAL(DMenu, Drawer) @@ -436,14 +262,6 @@ void DMenu::CallDrawer() VMValue params[] = { (DObject*)this }; GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr); } - else Drawer(); -} - -DEFINE_ACTION_FUNCTION(DMenu, Close) -{ - PARAM_SELF_PROLOGUE(DMenu); - self->Close(); - return 0; } bool DMenu::TranslateKeyboardEvents() @@ -500,7 +318,11 @@ void M_StartControlPanel (bool makeSound) void M_ActivateMenu(DMenu *menu) { if (menuactive == MENU_Off) menuactive = MENU_On; - if (CurrentMenu != nullptr) CurrentMenu->ReleaseCapture(); + if (CurrentMenu != nullptr && CurrentMenu->mMouseCapture) + { + CurrentMenu->mMouseCapture = false; + I_ReleaseMouseCapture(); + } CurrentMenu = menu; GC::WriteBarrier(CurrentMenu); } diff --git a/src/menu/menu.h b/src/menu/menu.h index 7d1236ccf9..1b4b22255d 100644 --- a/src/menu/menu.h +++ b/src/menu/menu.h @@ -263,42 +263,19 @@ public: MOUSE_Release }; - enum - { - BACKBUTTON_TIME = 4*TICRATE - }; - TObjPtr mParentMenu; bool mMouseCapture; bool mBackbuttonSelected; bool DontDim; DMenu(DMenu *parent = NULL); - virtual bool Responder (event_t *ev); - virtual bool MenuEvent (int mkey, bool fromcontroller); - virtual void Ticker (); - virtual void Drawer (); bool TranslateKeyboardEvents(); virtual void Close(); - virtual bool MouseEvent(int type, int x, int y); - - virtual void SetFocus(DMenuItemBase *fc) {} - virtual bool CheckFocus(DMenuItemBase *fc) { return false; } - virtual void ReleaseFocus() {} bool CallResponder(event_t *ev); bool CallMenuEvent(int mkey, bool fromcontroller); - bool CallMouseEvent(int type, int x, int y); void CallTicker(); void CallDrawer(); - - bool MouseEventBack(int type, int x, int y); - void SetCapture(); - void ReleaseCapture(); - bool HasCapture() - { - return mMouseCapture; - } }; //============================================================================= diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index 1abd0bc4c8..0f5647005f 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -63,6 +63,8 @@ static TArray properties; static TArray AFTable; static TArray FieldTable; +extern int BackbuttonTime; +extern float BackbuttonAlpha; //========================================================================== // @@ -912,6 +914,12 @@ void InitThingdef() fieldptr = new PField("demoplayback", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&demoplayback); Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); + fieldptr = new PField("BackbuttonTime", TypeSInt32, VARF_Native | VARF_Static, (intptr_t)&BackbuttonTime); + Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); + + fieldptr = new PField("BackbuttonAlpha", TypeFloat32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&BackbuttonAlpha); + Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); + // Argh. It sucks when bad hacks need to be supported. WP_NOCHANGE is just a bogus pointer but it used everywhere as a special flag. // It cannot be defined as constant because constants can either be numbers or strings but nothing else, so the only 'solution' diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 500fe3abcc..e9a89b0abc 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -300,6 +300,7 @@ struct GameInfoStruct native native int gametype; native bool norandomplayerclass; native Array infoPages; + native String mBackButton; } class Object native diff --git a/wadsrc/static/zscript/menu/menu.txt b/wadsrc/static/zscript/menu/menu.txt index 7d0c030dfd..dda75a739f 100644 --- a/wadsrc/static/zscript/menu/menu.txt +++ b/wadsrc/static/zscript/menu/menu.txt @@ -91,31 +91,190 @@ class Menu : Object native native bool mBackbuttonSelected; native bool DontDim; - void Init(Menu parent) - { - mParentMenu = parent; - } - native static int MenuTime(); native static void SetVideoMode(); native static Menu GetCurrentMenu(); native static void SetMenu(Name mnu, int param = 0); native static void StartMessage(String msg, int mode = 0, Name command = 'none'); + native static void SetMouseCapture(bool on); + native void Close(); + native void ActivateMenu(); + //============================================================================= + // + // + // + //============================================================================= + + void Init(Menu parent) + { + mParentMenu = parent; + mMouseCapture = false; + mBackbuttonSelected = false; + DontDim = false; + } + + //============================================================================= + // + // + // + //============================================================================= + + virtual bool MenuEvent (int mkey, bool fromcontroller) + { + switch (mkey) + { + case MKEY_Back: + Close(); + MenuSound (GetCurrentMenu() != null? "menu/backup" : "menu/clear"); + return true; + } + return false; + } + + + //============================================================================= + // + // + // + //============================================================================= + + protected bool MouseEventBack(int type, int x, int y) + { + if (m_show_backbutton >= 0) + { + let tex = TexMan.CheckForTexture(gameinfo.mBackButton, TexMan.Type_MiscPatch); + if (tex.IsValid()) + { + Vector2 v = TexMan.GetScaledSize(tex); + int w = int(v.X + 0.5) * CleanXfac; + int h = int(v.Y + 0.5) * CleanYfac; + if (m_show_backbutton&1) x -= screen.GetWidth() - w; + if (m_show_backbutton&2) y -= screen.GetHeight() - h; + mBackbuttonSelected = ( x >= 0 && x < w && y >= 0 && y < h); + if (mBackbuttonSelected && type == MOUSE_Release) + { + if (m_use_mouse == 2) mBackbuttonSelected = false; + MenuEvent(MKEY_Back, true); + } + return mBackbuttonSelected; + } + } + return false; + } + + //============================================================================= + // + // + // + //============================================================================= + + virtual bool Responder(InputEventData ev) + { + bool res = false; + if (ev.type == InputEventData.GUI_Event) + { + if (ev.subtype == InputEventData.GUI_LButtonDown) + { + res = MouseEventBack(MOUSE_Click, ev.data1, ev.data2); + // make the menu's mouse handler believe that the current coordinate is outside the valid range + if (res) ev.data2 = -1; + res |= MouseEvent(MOUSE_Click, ev.data1, ev.data2); + if (res) + { + SetCapture(true); + } + + } + else if (ev.subtype == InputEventData.GUI_MouseMove) + { + BackbuttonTime = 4*Thinker.TICRATE; + if (mMouseCapture || m_use_mouse == 1) + { + res = MouseEventBack(MOUSE_Move, ev.data1, ev.data2); + if (res) ev.data2 = -1; + res |= MouseEvent(MOUSE_Move, ev.data1, ev.data2); + } + } + else if (ev.subtype == InputEventData.GUI_LButtonUp) + { + if (mMouseCapture) + { + SetCapture(false); + res = MouseEventBack(MOUSE_Release, ev.data1, ev.data2); + if (res) ev.data2 = -1; + res |= MouseEvent(MOUSE_Release, ev.data1, ev.data2); + } + } + } + return false; + } + + //============================================================================= + // + // + // + //============================================================================= + + virtual void Drawer () + { + if (self == GetCurrentMenu() && BackbuttonAlpha > 0 && m_show_backbutton >= 0 && m_use_mouse) + { + let tex = TexMan.CheckForTexture(gameinfo.mBackButton, TexMan.Type_MiscPatch); + if (tex.IsValid()) + { + Vector2 v = TexMan.GetScaledSize(tex); + int w = int(v.X + 0.5) * CleanXfac; + int h = int(v.Y + 0.5) * CleanYfac; + int x = (!(m_show_backbutton&1))? 0:screen.GetWidth() - w; + int y = (!(m_show_backbutton&2))? 0:screen.GetHeight() - h; + if (mBackbuttonSelected && (mMouseCapture || m_use_mouse == 1)) + { + screen.DrawTexture(tex, true, x, y, DTA_CleanNoMove, true, DTA_ColorOverlay, Color(40, 255,255,255)); + } + else + { + screen.DrawTexture(tex, true, x, y, DTA_CleanNoMove, true, DTA_Alpha, BackbuttonAlpha); + } + } + } + } + + //============================================================================= + // + // + // + //============================================================================= + + void SetCapture(bool on) + { + if (mMouseCapture != on) + { + mMouseCapture = on; + SetMouseCapture(on); + } + } + + //============================================================================= + // + // + // + //============================================================================= + virtual bool TranslateKeyboardEvents() { return true; } virtual void SetFocus(MenuItemBase fc) {} virtual bool CheckFocus(MenuItemBase fc) { return false; } virtual void ReleaseFocus() {} virtual void ResetColor() {} + virtual bool MouseEvent(int type, int mx, int my) { return false; } + virtual void Ticker() {} + + //============================================================================= + // + // + // + //============================================================================= - native virtual bool Responder(InputEventData ev); - native virtual bool MenuEvent (int mkey, bool fromcontroller); - native virtual bool MouseEvent(int type, int mx, int my); - native virtual void Ticker(); - native virtual void Drawer(); - native void Close(); - native void ActivateMenu(); - static void MenuSound(Sound snd) { S_Sound (snd, CHAN_VOICE | CHAN_UI, snd_menuvolume, ATTN_NONE);