diff --git a/source/common/menu/menu.cpp b/source/common/menu/menu.cpp index 0eb886171..1c08e4d6d 100644 --- a/source/common/menu/menu.cpp +++ b/source/common/menu/menu.cpp @@ -101,6 +101,7 @@ static bool MenuEnabled = true; DMenu *CurrentMenu; int MenuTime; DObject* menuDelegate; +static MenuTransition transition; extern PClass *DefaultListMenuClass; @@ -193,6 +194,8 @@ void M_MarkMenus() } GC::Mark(CurrentMenu); GC::Mark(menuDelegate); + GC::Mark(transition.previous); + GC::Mark(transition.current); } @@ -202,8 +205,6 @@ void M_MarkMenus() // //============================================================================ -static MenuTransition transition; - bool MenuTransition::StartTransition(DMenu* from, DMenu* to, MenuTransitionType animtype) { if (!from->canAnimate() || !to->canAnimate() || animtype == MA_None) @@ -215,10 +216,11 @@ bool MenuTransition::StartTransition(DMenu* from, DMenu* to, MenuTransitionType start = I_GetTimeNS() * (120. / 1'000'000'000.); length = 30; dir = animtype == MA_Advance ? 1 : -1; + destroyprev = animtype == MA_Return; previous = from; current = to; - if (from) GC::AddSoftRoot(from); - if (to) GC::AddSoftRoot(to); + if (from) GC::WriteBarrier(from); + if (to) GC::WriteBarrier(to); return true; } } @@ -241,8 +243,9 @@ bool MenuTransition::Draw() current->CallDrawer(); return true; } - if (previous) GC::DelSoftRoot(previous); - if (current) GC::DelSoftRoot(current); + if (destroyprev && previous) previous->Destroy(); + previous = nullptr; + current = nullptr; return false; } @@ -352,27 +355,24 @@ void DMenu::Close () assert(CurrentMenu == this); CurrentMenu = mParentMenu; - if (false)// todo: && mParentMenu && transition.StartTransition(this, mParentMenu, MA_Return)) + if (CurrentMenu != nullptr) { - return; + GC::WriteBarrier(CurrentMenu); + IFVIRTUALPTR(CurrentMenu, DMenu, OnReturn) + { + VMValue params[] = { CurrentMenu }; + VMCall(func, params, 1, nullptr, 0); + } + if (transition.StartTransition(this, CurrentMenu, MA_Return)) + { + return; + } } - else - { - Destroy(); - if (CurrentMenu != nullptr) - { - GC::WriteBarrier(CurrentMenu); - IFVIRTUALPTR(CurrentMenu, DMenu, OnReturn) - { - VMValue params[] = { CurrentMenu }; - VMCall(func, params, 1, nullptr, 0); - } - } - else - { - M_ClearMenus(); - } + Destroy(); + if (CurrentMenu == nullptr) + { + M_ClearMenus(); } } @@ -474,7 +474,7 @@ void M_ActivateMenu(DMenu *menu) CurrentMenu->mMouseCapture = false; I_ReleaseMouseCapture(); } - //transition.StartTransition(CurrentMenu, menu, MA_Advance); + transition.StartTransition(CurrentMenu, menu, MA_Advance); } CurrentMenu = menu; GC::WriteBarrier(CurrentMenu); @@ -826,10 +826,25 @@ void M_Drawer (void) { if (sysCallbacks.MenuDim) sysCallbacks.MenuDim(); } - CurrentMenu->CallDrawer(); + bool going = false; + if (transition.previous) + { + going = transition.Draw(); + if (!going) + { + if (transition.dir == -1) delete transition.previous; + transition.previous = nullptr; + transition.current = nullptr; + } + } + if (!going) + { + CurrentMenu->CallDrawer(); + } } } + //============================================================================= // // @@ -838,6 +853,9 @@ void M_Drawer (void) void M_ClearMenus() { + transition.previous = transition.current = nullptr; + transition.dir = 0; + while (CurrentMenu != nullptr) { DMenu* parent = CurrentMenu->mParentMenu; diff --git a/source/common/menu/menu.h b/source/common/menu/menu.h index 3bbb7b25e..7b236ee48 100644 --- a/source/common/menu/menu.h +++ b/source/common/menu/menu.h @@ -89,6 +89,8 @@ public: EColorRange mFontColor2; bool mCenter; bool mFromEngine; + bool mAnimated; + bool mAnimatedTransition; int mVirtWidth; int mVirtHeight; @@ -181,7 +183,8 @@ struct MenuTransition double start; int32_t length; - int32_t dir; + int8_t dir; + bool destroyprev; bool StartTransition(DMenu* from, DMenu* to, MenuTransitionType animtype); bool Draw(); diff --git a/source/common/menu/menudef.cpp b/source/common/menu/menudef.cpp index bf9f52b9e..a879793ad 100644 --- a/source/common/menu/menudef.cpp +++ b/source/common/menu/menudef.cpp @@ -341,6 +341,10 @@ static void ParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc) { desc->mCenter = true; } + else if (sc.Compare("animatedtransition")) + { + desc->mAnimatedTransition = true; + } else if (sc.Compare("MouseWindow")) { sc.MustGetNumber(); diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 74b481141..ed9c4a4fa 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -11,7 +11,7 @@ LISTMENU "MainMenu" { position 160, 55 Linespacing 20 - //animatedtransition + animatedtransition DukeLogo DukeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" //DukeTextItem "$MNU_NEWGAME", "m", "MultiMenu" // In EDuke this replaces "New Game" when in networking mode. Kept here as a reminder. @@ -80,7 +80,7 @@ LISTMENU "IngameMenu" { position 160, 55 linespacing 18 - //animatedtransition + animatedtransition DukeLogo DukeTextItem "$MNU_NEWGAME", "n", "EpisodeMenu" DukeTextItem "$MNU_SAVEGAME", "s", "SaveGameMenu" @@ -152,7 +152,7 @@ LISTMENU "EpisodeMenu" position 160, 48 Linespacing 20 captionItem "$MNU_SELECTEPISODE" - //animatedtransition + animatedtransition } ifgame(blood) { @@ -176,7 +176,7 @@ LISTMENU "SkillMenu" position 160, 48 Linespacing 20 captionItem "$MNU_SELECTSKILL" - //animatedtransition + animatedtransition } ifgame(blood) {