- added back the menu transition, although it cannot be used yet, and all game specific menu CCMDs.

This commit is contained in:
Christoph Oelckers 2020-10-07 01:12:57 +02:00
parent 0968a9d97e
commit 5726b693bd
8 changed files with 184 additions and 15 deletions

View file

@ -195,6 +195,58 @@ void M_MarkMenus()
GC::Mark(menuDelegate);
}
//============================================================================
//
// Transition animation
//
//============================================================================
static MenuTransition transition;
bool MenuTransition::StartTransition(DMenu* from, DMenu* to, MenuTransitionType animtype)
{
if (!from->canAnimate() || !to->canAnimate() || animtype == MA_None)
{
return false;
}
else
{
start = I_GetTimeNS() * (120. / 1'000'000'000.);
length = 30;
dir = animtype == MA_Advance ? 1 : -1;
previous = from;
current = to;
if (from) GC::AddSoftRoot(from);
if (to) GC::AddSoftRoot(to);
return true;
}
}
bool MenuTransition::Draw()
{
double now = I_GetTimeNS() * (120. / 1'000'000'000);
if (now < start + length)
{
double factor = 120 * screen->GetWidth() / screen->GetHeight();
double phase = (now - start) / double(length) * M_PI + M_PI / 2;
DVector2 origin;
origin.Y = 0;
origin.X = factor * dir * (sin(phase) - 1.);
twod->SetOffset(origin);
previous->CallDrawer();
origin.X = factor * dir * (sin(phase) + 1.);
twod->SetOffset(origin);
current->CallDrawer();
return true;
}
if (previous) GC::DelSoftRoot(previous);
if (current) GC::DelSoftRoot(current);
return false;
}
//============================================================================
//
// DMenu base class
@ -299,20 +351,28 @@ void DMenu::Close ()
if (CurrentMenu == nullptr) return; // double closing can happen in the save menu.
assert(CurrentMenu == this);
CurrentMenu = mParentMenu;
Destroy();
if (CurrentMenu != nullptr)
{
GC::WriteBarrier(CurrentMenu);
IFVIRTUALPTR(CurrentMenu, DMenu, OnReturn)
{
VMValue params[] = { CurrentMenu };
VMCall(func, params, 1, nullptr, 0);
}
if (mParentMenu && transition.StartTransition(this, mParentMenu, MA_Return))
{
return;
}
else
{
M_ClearMenus ();
Destroy();
if (CurrentMenu != nullptr)
{
GC::WriteBarrier(CurrentMenu);
IFVIRTUALPTR(CurrentMenu, DMenu, OnReturn)
{
VMValue params[] = { CurrentMenu };
VMCall(func, params, 1, nullptr, 0);
}
}
else
{
M_ClearMenus();
}
}
}
@ -407,10 +467,14 @@ void M_DoStartControlPanel (bool scaleoverride)
void M_ActivateMenu(DMenu *menu)
{
if (menuactive == MENU_Off) menuactive = MENU_On;
if (CurrentMenu != nullptr && CurrentMenu->mMouseCapture)
if (CurrentMenu != nullptr)
{
CurrentMenu->mMouseCapture = false;
I_ReleaseMouseCapture();
if (CurrentMenu->mMouseCapture)
{
CurrentMenu->mMouseCapture = false;
I_ReleaseMouseCapture();
}
transition.StartTransition(CurrentMenu, menu, MA_Advance);
}
CurrentMenu = menu;
GC::WriteBarrier(CurrentMenu);

View file

@ -165,6 +165,31 @@ struct FMenuRect
};
enum MenuTransitionType
{ // Note: This enum is for logical categories, not visual types.
MA_None,
MA_Return,
MA_Advance,
};
class DMenu;
struct MenuTransition
{
DMenu* previous;
DMenu* current;
double start;
int32_t length;
int32_t dir;
bool StartTransition(DMenu* from, DMenu* to, MenuTransitionType animtype);
bool Draw();
};
class DMenu : public DObject
{
DECLARE_CLASS (DMenu, DObject)
@ -195,6 +220,7 @@ public:
bool CallMenuEvent(int mkey, bool fromcontroller);
void CallTicker();
void CallDrawer();
bool canAnimate() { return false; }
};
//=============================================================================

View file

@ -871,6 +871,7 @@ int RunGame()
if (exec) exec->ExecCommands();
SetupGameButtons();
gameinfo.mBackButton = "engine/graphics/m_back.png";
gi->app_init();
SetDefaultMenuColors();
M_Init();

View file

@ -74,6 +74,7 @@ void D_ToggleHud();
void I_WaitVBL(int count);
extern bool hud_toggled;
bool help_disabled;
//FNewGameStartup NewGameStartupInfo;
@ -1166,6 +1167,59 @@ void SetDefaultMenuColors()
}
//=============================================================================
//
// [RH] Most menus can now be accessed directly
// through console commands.
//
//=============================================================================
EXTERN_CVAR(Int, screenblocks)
CCMD(reset2defaults)
{
C_SetDefaultBindings();
C_SetCVarsToDefaults();
}
CCMD(reset2saved)
{
GameConfig->DoGlobalSetup();
GameConfig->DoGameSetup(currentGame);
}
CCMD(menu_main)
{
M_StartControlPanel(true);
M_SetMenu(gi->CanSave() ? NAME_IngameMenu : NAME_Mainmenu, -1);
}
CCMD(openhelpmenu)
{
if (!help_disabled)
{
M_StartControlPanel(true);
M_SetMenu(NAME_HelpMenu);
}
}
CCMD(opensavemenu)
{
if (gi->CanSave())
{
M_StartControlPanel(true);
M_SetMenu(NAME_Savegamemenu);
}
}
CCMD(openloadmenu)
{
M_StartControlPanel(true);
M_SetMenu(NAME_Loadgamemenu);
}
// The sound system is not yet capable of resolving this properly.
DEFINE_ACTION_FUNCTION(_RazeMenuDelegate, PlaySound)
{
@ -1205,4 +1259,11 @@ DEFINE_ACTION_FUNCTION(_RazeMenuDelegate, PlaySound)
}
gi->MenuSound(soundindex);
return 0;
}
}
// C_ToggleConsole cannot be exported for security reasons as it can be used to make the engine unresponsive.
DEFINE_ACTION_FUNCTION(_RazeMenuDelegate, MenuDismissed)
{
if (CurrentMenu == nullptr && gamestate == GS_MENUSCREEN) C_ToggleConsole();
return 0;
}

View file

@ -3,6 +3,8 @@
#include "gamestruct.h"
#include "c_cvars.h"
extern bool help_disabled;
void M_StartControlPanel (bool makeSound, bool scaleoverride = false);

View file

@ -44,4 +44,7 @@ class RazeMenuDelegate : MenuDelegateBase
{
// Todo: Fix this so that it can be done outside the games' sound modules.
native override void PlaySound(name sname);
// This is native for security reasons. Having a script call to open the console could be subject to abuse.
native override void MenuDismissed();
}

View file

@ -129,10 +129,14 @@ class Menu : Object native ui version("2.4")
switch (mkey)
{
case MKEY_Back:
{
Close();
MenuSound (GetCurrentMenu() != null? "menu/backup" : "menu/clear");
let m = GetCurrentMenu();
MenuSound(m != null ? "menu/backup" : "menu/clear");
if (!m) menuDelegate.MenuDismissed();
return true;
}
}
return false;
}

View file

@ -8,10 +8,18 @@ class MenuDelegateBase
return (y + fnt.GetHeight()) * CleanYfac_1; // return is spacing in screen pixels.
}
virtual void PlaySound(Name sound)
{
}
virtual bool DrawSelector(ListMenuDescriptor desc)
{
return false;
}
virtual void MenuDismissed()
{
// overriding this allows to execute special actions when the menu closes
}
}