- backport of menu transition code from Raze.

This commit is contained in:
Christoph Oelckers 2020-10-08 17:14:42 +02:00
parent 62138decfe
commit 881a77b3a1
7 changed files with 79 additions and 29 deletions

View file

@ -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; i<dg.mVertCount; i++ )
{
@ -599,6 +606,7 @@ void F2DDrawer::AddShape(FGameTexture* img, DShape2D* shape, DrawParms& parms)
AddIndices(dg.mVertIndex, 3, shape->mIndices[i], shape->mIndices[i+1], shape->mIndices[i+2]);
}
AddCommand(&dg);
offset = osave;
}
//==========================================================================

View file

@ -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;

View file

@ -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;

View file

@ -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)

View file

@ -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)

View file

@ -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; }
};
//=============================================================================

View file

@ -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();