- scriptified most of the remaining parts of DMenu. Only the engine interface remains native now.

This commit is contained in:
Christoph Oelckers 2017-02-19 15:23:33 +01:00
parent e05242e44d
commit 9089beb110
6 changed files with 211 additions and 243 deletions

View file

@ -52,6 +52,7 @@ DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, ArmorIcon2)
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, gametype) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, gametype)
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, norandomplayerclass) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, norandomplayerclass)
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, infoPages) DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, infoPages)
DEFINE_FIELD_X(GameInfoStruct, gameinfo_t, mBackButton)
const char *GameNames[17] = const char *GameNames[17] =

View file

@ -164,53 +164,11 @@ DMenu::DMenu(DMenu *parent)
GC::WriteBarrier(this, 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) bool DMenu::CallResponder(event_t *ev)
{ {
@ -222,7 +180,7 @@ bool DMenu::CallResponder(event_t *ev)
GlobalVMStack.Call(func, params, 2, &ret, 1, nullptr); GlobalVMStack.Call(func, params, 2, &ret, 1, nullptr);
return !!retval; 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) bool DMenu::CallMenuEvent(int mkey, bool fromcontroller)
{ {
IFVIRTUAL(DMenu, MenuEvent) IFVIRTUAL(DMenu, MenuEvent)
@ -264,7 +199,7 @@ bool DMenu::CallMenuEvent(int mkey, bool fromcontroller)
GlobalVMStack.Call(func, params, 3, &ret, 1, nullptr); GlobalVMStack.Call(func, params, 3, &ret, 1, nullptr);
return !!retval; 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 () void DMenu::Close ()
{ {
if (CurrentMenu == nullptr) return; // double closing can happen in the save menu. if (CurrentMenu == nullptr) return; // double closing can happen in the save menu.
@ -288,108 +232,19 @@ void DMenu::Close ()
} }
} }
//============================================================================= DEFINE_ACTION_FUNCTION(DMenu, Close)
//
//
//
//=============================================================================
bool DMenu::MouseEvent(int type, int x, int y)
{
return true;
}
DEFINE_ACTION_FUNCTION(DMenu, MouseEvent)
{ {
PARAM_SELF_PROLOGUE(DMenu); PARAM_SELF_PROLOGUE(DMenu);
PARAM_INT(type); self->Close();
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();
return 0; return 0;
} }
//=============================================================================
//
//
//
//=============================================================================
void DMenu::CallTicker() void DMenu::CallTicker()
{ {
IFVIRTUAL(DMenu, Ticker) IFVIRTUAL(DMenu, Ticker)
@ -397,38 +252,9 @@ void DMenu::CallTicker()
VMValue params[] = { (DObject*)this }; VMValue params[] = { (DObject*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr); 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() void DMenu::CallDrawer()
{ {
IFVIRTUAL(DMenu, Drawer) IFVIRTUAL(DMenu, Drawer)
@ -436,14 +262,6 @@ void DMenu::CallDrawer()
VMValue params[] = { (DObject*)this }; VMValue params[] = { (DObject*)this };
GlobalVMStack.Call(func, params, 1, nullptr, 0, nullptr); 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() bool DMenu::TranslateKeyboardEvents()
@ -500,7 +318,11 @@ 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 (CurrentMenu != nullptr) CurrentMenu->ReleaseCapture(); if (CurrentMenu != nullptr && CurrentMenu->mMouseCapture)
{
CurrentMenu->mMouseCapture = false;
I_ReleaseMouseCapture();
}
CurrentMenu = menu; CurrentMenu = menu;
GC::WriteBarrier(CurrentMenu); GC::WriteBarrier(CurrentMenu);
} }

View file

@ -263,42 +263,19 @@ public:
MOUSE_Release MOUSE_Release
}; };
enum
{
BACKBUTTON_TIME = 4*TICRATE
};
TObjPtr<DMenu> mParentMenu; TObjPtr<DMenu> mParentMenu;
bool mMouseCapture; bool mMouseCapture;
bool mBackbuttonSelected; bool mBackbuttonSelected;
bool DontDim; bool DontDim;
DMenu(DMenu *parent = NULL); 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(); bool TranslateKeyboardEvents();
virtual void Close(); 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 CallResponder(event_t *ev);
bool CallMenuEvent(int mkey, bool fromcontroller); bool CallMenuEvent(int mkey, bool fromcontroller);
bool CallMouseEvent(int type, int x, int y);
void CallTicker(); void CallTicker();
void CallDrawer(); void CallDrawer();
bool MouseEventBack(int type, int x, int y);
void SetCapture();
void ReleaseCapture();
bool HasCapture()
{
return mMouseCapture;
}
}; };
//============================================================================= //=============================================================================

View file

@ -63,6 +63,8 @@
static TArray<FPropertyInfo*> properties; static TArray<FPropertyInfo*> properties;
static TArray<AFuncDesc> AFTable; static TArray<AFuncDesc> AFTable;
static TArray<FieldDesc> FieldTable; static TArray<FieldDesc> 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); fieldptr = new PField("demoplayback", TypeSInt32, VARF_Native | VARF_Static | VARF_ReadOnly, (intptr_t)&demoplayback);
Namespaces.GlobalNamespace->Symbols.AddSymbol(fieldptr); 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. // 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' // It cannot be defined as constant because constants can either be numbers or strings but nothing else, so the only 'solution'

View file

@ -300,6 +300,7 @@ struct GameInfoStruct native
native int gametype; native int gametype;
native bool norandomplayerclass; native bool norandomplayerclass;
native Array<Name> infoPages; native Array<Name> infoPages;
native String mBackButton;
} }
class Object native class Object native

View file

@ -91,31 +91,190 @@ class Menu : Object native
native bool mBackbuttonSelected; native bool mBackbuttonSelected;
native bool DontDim; native bool DontDim;
void Init(Menu parent)
{
mParentMenu = parent;
}
native static int MenuTime(); native static int MenuTime();
native static void SetVideoMode(); native static void SetVideoMode();
native static Menu GetCurrentMenu(); native static Menu GetCurrentMenu();
native static void SetMenu(Name mnu, int param = 0); native static void SetMenu(Name mnu, int param = 0);
native static void StartMessage(String msg, int mode = 0, Name command = 'none'); 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 bool TranslateKeyboardEvents() { return true; }
virtual void SetFocus(MenuItemBase fc) {} virtual void SetFocus(MenuItemBase fc) {}
virtual bool CheckFocus(MenuItemBase fc) { return false; } virtual bool CheckFocus(MenuItemBase fc) { return false; }
virtual void ReleaseFocus() {} virtual void ReleaseFocus() {}
virtual void ResetColor() {} 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) static void MenuSound(Sound snd)
{ {
S_Sound (snd, CHAN_VOICE | CHAN_UI, snd_menuvolume, ATTN_NONE); S_Sound (snd, CHAN_VOICE | CHAN_UI, snd_menuvolume, ATTN_NONE);