diff --git a/src/common/2d/v_2ddrawer.cpp b/src/common/2d/v_2ddrawer.cpp index b79da9e735..22d8565a49 100644 --- a/src/common/2d/v_2ddrawer.cpp +++ b/src/common/2d/v_2ddrawer.cpp @@ -439,6 +439,9 @@ void F2DDrawer::AddTexture(FGameTexture* img, DrawParms& parms) std::swap(v1, v2); } + auto osave = offset; + if (parms.nooffset) offset = { 0,0 }; + if (parms.rotateangle == 0) { double x = parms.x - parms.left * xscale; @@ -521,6 +524,7 @@ void F2DDrawer::AddTexture(FGameTexture* img, DrawParms& parms) dg.mIndexCount += 6; AddIndices(dg.mVertIndex, 6, 0, 1, 2, 1, 3, 2); AddCommand(&dg); + offset = osave; } //========================================================================== @@ -561,6 +565,9 @@ void F2DDrawer::AddShape(FGameTexture* img, DShape2D* shape, DrawParms& parms) shape->dirty = false; } + auto osave = offset; + if (parms.nooffset) offset = { 0,0 }; + double minx = 16383, miny = 16383, maxx = -16384, maxy = -16384; for ( int i=0; imIndices[i], shape->mIndices[i+1], shape->mIndices[i+2]); } AddCommand(&dg); + offset = osave; } //========================================================================== diff --git a/src/common/2d/v_draw.cpp b/src/common/2d/v_draw.cpp index c6ca5188bd..32b55f1ca6 100644 --- a/src/common/2d/v_draw.cpp +++ b/src/common/2d/v_draw.cpp @@ -703,6 +703,7 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture *img, double x, double parms->rotateangle = 0; parms->flipoffsets = false; parms->indexed = false; + parms->nooffset = false; // Parse the tag list for attributes. (For floating point attributes, // consider that the C ABI dictates that all floats be promoted to @@ -914,6 +915,10 @@ bool ParseDrawTextureTags(F2DDrawer *drawer, FGameTexture *img, double x, double parms->flipoffsets = ListGetInt(tags); break; + case DTA_NoOffset: + parms->nooffset = ListGetInt(tags); + break; + case DTA_SrcX: parms->srcx = ListGetDouble(tags) / img->GetDisplayWidth(); break; diff --git a/src/common/2d/v_draw.h b/src/common/2d/v_draw.h index dc9b8d28c6..b7eafbbec2 100644 --- a/src/common/2d/v_draw.h +++ b/src/common/2d/v_draw.h @@ -131,6 +131,7 @@ enum DTA_FlipOffsets, // Flips offsets when using DTA_FlipX and DTA_FlipY, this cannot be automatic due to unexpected behavior with unoffsetted graphics. DTA_Indexed, // Use an indexed texture combined with the given translation. DTA_CleanTop, // Like DTA_Clean but aligns to the top of the screen instead of the center. + DTA_NoOffset, // Ignore 2D drawer's offset. }; @@ -198,6 +199,7 @@ struct DrawParms bool burn; bool flipoffsets; bool indexed; + bool nooffset; int8_t fsscalemode; double srcx, srcy; double srcwidth, srcheight; diff --git a/src/common/engine/namedef.h b/src/common/engine/namedef.h index e8e63c0e70..64d8c54901 100644 --- a/src/common/engine/namedef.h +++ b/src/common/engine/namedef.h @@ -1097,3 +1097,6 @@ xy(menu_clear, "menu/clear") xy(menu_dismiss, "menu/dismiss") xy(menu_change, "menu/change") xy(menu_advance, "menu/advance") + +xx(zoomsize) + diff --git a/src/common/menu/menu.cpp b/src/common/menu/menu.cpp index 0eb8861715..18bfdb106a 100644 --- a/src/common/menu/menu.cpp +++ b/src/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; } } @@ -228,7 +230,7 @@ bool MenuTransition::Draw() double now = I_GetTimeNS() * (120. / 1'000'000'000); if (now < start + length) { - double factor = 120 * screen->GetWidth() / screen->GetHeight(); + double factor = screen->GetWidth()/2; double phase = (now - start) / double(length) * M_PI + M_PI / 2; DVector2 origin; @@ -239,10 +241,13 @@ bool MenuTransition::Draw() origin.X = factor * dir * (sin(phase) + 1.); twod->SetOffset(origin); current->CallDrawer(); + origin = { 0,0 }; + twod->SetOffset(origin); 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 +357,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 +476,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 +828,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 +855,11 @@ void M_Drawer (void) void M_ClearMenus() { + if (menuactive == MENU_Off) return; + + transition.previous = transition.current = nullptr; + transition.dir = 0; + while (CurrentMenu != nullptr) { DMenu* parent = CurrentMenu->mParentMenu; @@ -959,6 +981,7 @@ DEFINE_FIELD(DMenu, mMouseCapture); DEFINE_FIELD(DMenu, mBackbuttonSelected); DEFINE_FIELD(DMenu, DontDim); DEFINE_FIELD(DMenu, DontBlur); +DEFINE_FIELD(DMenu, AnimatedTransition); DEFINE_FIELD(DMenuDescriptor, mMenuName) DEFINE_FIELD(DMenuDescriptor, mNetgameMessage) @@ -984,6 +1007,7 @@ DEFINE_FIELD(DListMenuDescriptor, mAutoselect) DEFINE_FIELD(DListMenuDescriptor, mFont) DEFINE_FIELD(DListMenuDescriptor, mFontColor) DEFINE_FIELD(DListMenuDescriptor, mFontColor2) +DEFINE_FIELD(DListMenuDescriptor, mAnimatedTransition) DEFINE_FIELD(DListMenuDescriptor, mCenter) DEFINE_FIELD(DListMenuDescriptor, mVirtWidth) DEFINE_FIELD(DListMenuDescriptor, mVirtHeight) diff --git a/src/common/menu/menu.h b/src/common/menu/menu.h index a4323244e3..c5d70f6592 100644 --- a/src/common/menu/menu.h +++ b/src/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(); @@ -210,6 +213,7 @@ public: bool mBackbuttonSelected; bool DontDim; bool DontBlur; + bool AnimatedTransition; static int InMenu; DMenu(DMenu *parent = NULL); @@ -220,7 +224,7 @@ public: bool CallMenuEvent(int mkey, bool fromcontroller); void CallTicker(); void CallDrawer(); - bool canAnimate() { return false; } + bool canAnimate() { return AnimatedTransition; } }; //============================================================================= diff --git a/src/common/menu/menudef.cpp b/src/common/menu/menudef.cpp index bf9f52b9e4..a879793ad3 100644 --- a/src/common/menu/menudef.cpp +++ b/src/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();