1414#include < app.h>
1515#include < exports.h>
1616
17+ static constexpr double CONTAINER_MOVE_OFFSET = 0 ;
18+ static constexpr double CONTAINER_MOVE_DURATION = 5 ;
19+ static constexpr double CONTAINER_FADE_OFFSET = CONTAINER_MOVE_OFFSET;
20+ static constexpr double CONTAINER_FADE_DURATION = 10 ;
21+ static constexpr double ROW_FADE_OFFSET = CONTAINER_FADE_DURATION;
22+ static constexpr double ROW_FADE_TIME = 5 ;
23+
1724static constexpr int MAX_VISIBLE_ROWS = 4 ;
1825
1926static double g_time{};
@@ -26,6 +33,7 @@ static bool g_up{};
2633static bool g_upWasHeld{};
2734static bool g_down{};
2835static bool g_downWasHeld{};
36+ static bool g_hasSwitched{};
2937
3038static int g_rowCount{};
3139static int g_selectedIndex{};
@@ -94,8 +102,8 @@ static bool DrawContainer(ImVec2 min, ImVec2 max)
94102 auto containerTopCentreUVs = PIXELS_TO_UV_COORDS (1024 , 1024 , 50 , 400 , 50 , 50 );
95103 auto containerSideUVs = PIXELS_TO_UV_COORDS (1024 , 1024 , 1 , 450 , 50 , 50 );
96104 auto containerCentreUVs = PIXELS_TO_UV_COORDS (1024 , 1024 , 50 , 450 , 50 , 50 );
97- auto containerColourMotion = AchievementMenu::IsClosing () ? 0 : ComputeLinearMotion (g_time, 0 , 10 );
98- auto containerColour = IM_COL32 (255 , 255 , 255 , 63 * containerColourMotion );
105+ auto containerAlphaMotionTime = AchievementMenu::IsClosing () ? 0 : ComputeLinearMotion (g_time, CONTAINER_FADE_OFFSET, CONTAINER_FADE_DURATION );
106+ auto containerColour = IM_COL32 (255 , 255 , 255 , AchievementMenu::s_state == AchievementMenuState::GoldMedals ? Lerp ( 63 , 0 , containerAlphaMotionTime) : 63 );
99107 auto containerEdgeSize = Scale (50 , true );
100108
101109 ImVec2 containerTopLeftCornerMin = min;
@@ -127,7 +135,7 @@ static bool DrawContainer(ImVec2 min, ImVec2 max)
127135
128136 drawList->PushClipRect (containerTopLeftCornerMin, containerRightMax);
129137
130- return containerColourMotion >= 1.0 ;
138+ return containerAlphaMotionTime >= 1.0 ;
131139}
132140
133141static void DrawAchievement (int rowIndex, Achievement& achievement, bool isUnlocked)
@@ -175,8 +183,10 @@ static void DrawAchievement(int rowIndex, Achievement& achievement, bool isUnloc
175183 auto rowUVs = PIXELS_TO_UV_COORDS (1024 , 1024 , 605 , 450 , 10 , 30 );
176184 auto rowMarginX = Scale (2 , true );
177185 auto rowMarginY = Scale (24 , true );
178- auto rowColourMotion = BREATHE_MOTION (1 .0f , 0 .0f , g_rowSelectionTime, 0 .9f );
179- auto rowColour = IM_COL32 (255 , 255 , 255 , isCurrent ? Lerp (165 , 94 , rowColourMotion) : 94 );
186+ auto rowColourBreatheMotionTime = BREATHE_MOTION (1 .0f , 0 .0f , g_rowSelectionTime, 0 .9f );
187+ auto rowColourTransitionMotionTime = ComputeLinearMotion (g_time, ROW_FADE_OFFSET, ROW_FADE_TIME);
188+ auto rowColourAlpha = isCurrent ? Lerp (165 , 94 , rowColourBreatheMotionTime) * rowColourTransitionMotionTime : 94 * rowColourTransitionMotionTime;
189+ auto rowColour = IM_COL32 (255 , 255 , 255 , rowColourAlpha);
180190 ImVec2 rowMin = { clipRectMin.x + rowMarginX, min.y + itemHeight - rowMarginY };
181191 ImVec2 rowMax = { clipRectMax.x - rowMarginX, rowMin.y + Scale (30 , true ) };
182192
@@ -336,6 +346,7 @@ void AchievementMenu::Draw()
336346 ButtonWindow::Open (" Button_GoldMedalsBack" );
337347 SetGoldMedalResultsVisible (false );
338348 Game_PlaySound (" window_open" );
349+ g_hasSwitched = true ;
339350 }
340351
341352 break ;
@@ -361,25 +372,36 @@ void AchievementMenu::Draw()
361372 }
362373 }
363374
375+ auto containerMotionTime = ComputeLinearMotion (g_time, CONTAINER_MOVE_OFFSET, CONTAINER_MOVE_DURATION, s_state == AchievementMenuState::GoldMedals);
376+ auto containerTop = Scale (Lerp (217 , 148 , containerMotionTime), true );
377+ auto containerBottom = Scale (554 , true );
378+ auto containerWidth = Scale (1158 , true );
379+
380+ ImVec2 min = { (res.x / 2 ) - containerWidth / 2 , g_vertCentre + containerTop };
381+ ImVec2 max = { min.x + containerWidth, g_vertCentre + containerBottom };
382+
364383 switch (s_state)
365384 {
366385 case AchievementMenuState::GoldMedals:
386+ {
367387 s_commonMenu.SetTitle (Localise (" Achievements_GoldMedals_Uppercase" ));
368388 s_commonMenu.ShowDescription = false ;
389+
390+ if (g_hasSwitched)
391+ {
392+ // For outro animation.
393+ DrawContainer (min, max);
394+ drawList->PopClipRect ();
395+ }
396+
369397 break ;
398+ }
370399
371400 case AchievementMenuState::Achievements:
372401 {
373402 s_commonMenu.SetTitle (Localise (" Achievements_Title_Uppercase" ));
374403 s_commonMenu.ShowDescription = true ;
375404
376- auto containerWidth = Scale (1158 , true );
377- auto containerTop = Scale (148 , true );
378- auto containerHeight = Scale (405 , true );
379-
380- ImVec2 min = { (res.x / 2 ) - containerWidth / 2 , g_vertCentre + containerTop };
381- ImVec2 max = { min.x + containerWidth, min.y + containerHeight };
382-
383405 if (DrawContainer (min, max))
384406 {
385407 auto rowIndex = 0 ;
@@ -481,6 +503,7 @@ void AchievementMenu::Open(Sonicteam::MainMenuTask* pMainMenuTask)
481503 s_isVisible = true ;
482504 s_state = AchievementMenuState::GoldMedals;
483505 g_time = ImGui::GetTime ();
506+ g_hasSwitched = false ;
484507 g_selectedIndex = 0 ;
485508
486509 ButtonWindow::Open (" Button_AchievementsBack" );
0 commit comments