mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2026-04-27 21:01:37 +00:00
achievements_overlay: implemented queue and hermite interpolation
This commit is contained in:
parent
82f3c4ee1a
commit
e1fff00bab
3 changed files with 63 additions and 38 deletions
|
|
@ -14,53 +14,53 @@ constexpr double OVERLAY_CONTAINER_COMMON_MOTION_END = 11;
|
|||
constexpr double OVERLAY_CONTAINER_INTRO_FADE_START = 5;
|
||||
constexpr double OVERLAY_CONTAINER_INTRO_FADE_END = 9;
|
||||
constexpr double OVERLAY_CONTAINER_OUTRO_FADE_START = 0;
|
||||
constexpr double OVERLAY_CONTAINER_OUTRO_FADE_END = 5;
|
||||
constexpr double OVERLAY_CONTAINER_OUTRO_FADE_END = 4;
|
||||
|
||||
constexpr double OVERLAY_DURATION = 5;
|
||||
constexpr double OVERLAY_DURATION = 3;
|
||||
|
||||
static bool m_isClosing = false;
|
||||
static bool g_isClosing = false;
|
||||
|
||||
static double m_appearTime = 0;
|
||||
static double g_appearTime = 0;
|
||||
|
||||
static Achievement m_achievement;
|
||||
static Achievement g_achievement;
|
||||
|
||||
static ImFont* m_fntSeurat;
|
||||
static ImFont* g_fntSeurat;
|
||||
|
||||
static bool DrawContainer(ImVec2 min, ImVec2 max, float cornerRadius = 25)
|
||||
{
|
||||
auto drawList = ImGui::GetForegroundDrawList();
|
||||
|
||||
// Expand/retract animation.
|
||||
auto containerMotion = ComputeMotion(m_appearTime, OVERLAY_CONTAINER_COMMON_MOTION_START, OVERLAY_CONTAINER_COMMON_MOTION_END);
|
||||
auto containerMotion = ComputeMotion(g_appearTime, OVERLAY_CONTAINER_COMMON_MOTION_START, OVERLAY_CONTAINER_COMMON_MOTION_END);
|
||||
|
||||
auto centreX = (min.x + max.x) / 2;
|
||||
auto centreY = (min.y + max.y) / 2;
|
||||
|
||||
if (m_isClosing)
|
||||
if (g_isClosing)
|
||||
{
|
||||
min.x = CubicEase(min.x, centreX, containerMotion);
|
||||
max.x = CubicEase(max.x, centreX, containerMotion);
|
||||
min.y = CubicEase(min.y, centreY, containerMotion);
|
||||
max.y = CubicEase(max.y, centreY, containerMotion);
|
||||
min.x = Hermite(min.x, centreX, containerMotion);
|
||||
max.x = Hermite(max.x, centreX, containerMotion);
|
||||
min.y = Hermite(min.y, centreY, containerMotion);
|
||||
max.y = Hermite(max.y, centreY, containerMotion);
|
||||
}
|
||||
else
|
||||
{
|
||||
min.x = CubicEase(centreX, min.x, containerMotion);
|
||||
max.x = CubicEase(centreX, max.x, containerMotion);
|
||||
min.y = CubicEase(centreY, min.y, containerMotion);
|
||||
max.y = CubicEase(centreY, max.y, containerMotion);
|
||||
min.x = Hermite(centreX, min.x, containerMotion);
|
||||
max.x = Hermite(centreX, max.x, containerMotion);
|
||||
min.y = Hermite(centreY, min.y, containerMotion);
|
||||
max.y = Hermite(centreY, max.y, containerMotion);
|
||||
}
|
||||
|
||||
auto vertices = GetPauseContainerVertices(min, max, cornerRadius);
|
||||
|
||||
// Transparency fade animation.
|
||||
auto colourMotion = m_isClosing
|
||||
? ComputeMotion(m_appearTime, OVERLAY_CONTAINER_OUTRO_FADE_START, OVERLAY_CONTAINER_OUTRO_FADE_END)
|
||||
: ComputeMotion(m_appearTime, OVERLAY_CONTAINER_INTRO_FADE_START, OVERLAY_CONTAINER_INTRO_FADE_END);
|
||||
auto colourMotion = g_isClosing
|
||||
? ComputeMotion(g_appearTime, OVERLAY_CONTAINER_OUTRO_FADE_START, OVERLAY_CONTAINER_OUTRO_FADE_END)
|
||||
: ComputeMotion(g_appearTime, OVERLAY_CONTAINER_INTRO_FADE_START, OVERLAY_CONTAINER_INTRO_FADE_END);
|
||||
|
||||
auto alpha = m_isClosing
|
||||
? CubicEase(1, 0, colourMotion)
|
||||
: CubicEase(0, 1, colourMotion);
|
||||
auto alpha = g_isClosing
|
||||
? Hermite(1, 0, colourMotion)
|
||||
: Hermite(0, 1, colourMotion);
|
||||
|
||||
auto colShadow = IM_COL32(0, 0, 0, 156 * alpha);
|
||||
auto colGradientTop = IM_COL32(197, 194, 197, 200 * alpha);
|
||||
|
|
@ -114,7 +114,7 @@ void AchievementOverlay::Init()
|
|||
|
||||
constexpr float FONT_SCALE = 2.0f;
|
||||
|
||||
m_fntSeurat = io.Fonts->AddFontFromFileTTF("FOT-SeuratPro-M.otf", 24.0f * FONT_SCALE);
|
||||
g_fntSeurat = io.Fonts->AddFontFromFileTTF("FOT-SeuratPro-M.otf", 24.0f * FONT_SCALE);
|
||||
}
|
||||
|
||||
void AchievementOverlay::Draw()
|
||||
|
|
@ -122,19 +122,19 @@ void AchievementOverlay::Draw()
|
|||
if (!s_isVisible)
|
||||
return;
|
||||
|
||||
if (ImGui::GetTime() - m_appearTime >= OVERLAY_DURATION)
|
||||
if (ImGui::GetTime() - g_appearTime >= OVERLAY_DURATION)
|
||||
AchievementOverlay::Close();
|
||||
|
||||
auto drawList = ImGui::GetForegroundDrawList();
|
||||
auto& res = ImGui::GetIO().DisplaySize;
|
||||
|
||||
auto strAchievementUnlocked = Localise("Achievements_Unlock").c_str();
|
||||
auto strAchievementName = m_achievement.Name.c_str();
|
||||
auto strAchievementName = g_achievement.Name.c_str();
|
||||
|
||||
// Calculate text sizes.
|
||||
auto fontSize = Scale(24);
|
||||
auto headerSize = m_fntSeurat->CalcTextSizeA(fontSize, FLT_MAX, 0, strAchievementUnlocked);
|
||||
auto bodySize = m_fntSeurat->CalcTextSizeA(fontSize, FLT_MAX, 0, strAchievementName);
|
||||
auto headerSize = g_fntSeurat->CalcTextSizeA(fontSize, FLT_MAX, 0, strAchievementUnlocked);
|
||||
auto bodySize = g_fntSeurat->CalcTextSizeA(fontSize, FLT_MAX, 0, strAchievementName);
|
||||
auto maxSize = std::max(headerSize.x, bodySize.x);
|
||||
|
||||
// Calculate image margins.
|
||||
|
|
@ -153,10 +153,16 @@ void AchievementOverlay::Draw()
|
|||
|
||||
if (DrawContainer(min, max))
|
||||
{
|
||||
if (g_isClosing)
|
||||
{
|
||||
s_isVisible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Draw achievement icon.
|
||||
drawList->AddImage
|
||||
(
|
||||
g_xdbfTextureCache[m_achievement.ID], // user_texture_id
|
||||
g_xdbfTextureCache[g_achievement.ID], // user_texture_id
|
||||
{ /* X */ min.x + imageMarginX, /* Y */ min.y + imageMarginY }, // p_min
|
||||
{ /* X */ min.x + imageMarginX + imageSize, /* Y */ min.y + imageMarginY + imageSize }, // p_max
|
||||
{ 0, 0 }, // uv_min
|
||||
|
|
@ -167,7 +173,7 @@ void AchievementOverlay::Draw()
|
|||
// Draw header text.
|
||||
DrawTextWithShadow
|
||||
(
|
||||
m_fntSeurat, // font
|
||||
g_fntSeurat, // font
|
||||
fontSize, // fontSize
|
||||
{ /* X */ min.x + textMarginX + (maxSize - headerSize.x) / 2, /* Y */ min.y + textMarginY }, // pos
|
||||
IM_COL32(252, 243, 5, 255), // colour
|
||||
|
|
@ -180,7 +186,7 @@ void AchievementOverlay::Draw()
|
|||
// Draw achievement name.
|
||||
DrawTextWithShadow
|
||||
(
|
||||
m_fntSeurat, // font
|
||||
g_fntSeurat, // font
|
||||
fontSize, // fontSize
|
||||
{ /* X */ min.x + textMarginX + (maxSize - bodySize.x) / 2, /* Y */ min.y + textMarginY + bodySize.y + Scale(6) }, // pos
|
||||
IM_COL32(255, 255, 255, 255), // colour
|
||||
|
|
@ -197,22 +203,32 @@ void AchievementOverlay::Draw()
|
|||
|
||||
void AchievementOverlay::Open(int id)
|
||||
{
|
||||
if (s_isVisible)
|
||||
{
|
||||
s_queue.emplace(id);
|
||||
return;
|
||||
}
|
||||
|
||||
s_isVisible = true;
|
||||
m_isClosing = false;
|
||||
m_appearTime = ImGui::GetTime();
|
||||
m_achievement = g_xdbfWrapper.GetAchievement((EXDBFLanguage)Config::Language.Value, id);
|
||||
g_isClosing = false;
|
||||
g_appearTime = ImGui::GetTime();
|
||||
g_achievement = g_xdbfWrapper.GetAchievement((EXDBFLanguage)Config::Language.Value, id);
|
||||
|
||||
Game_PlaySound("obj_navi_appear");
|
||||
}
|
||||
|
||||
void AchievementOverlay::Close()
|
||||
{
|
||||
if (!m_isClosing)
|
||||
if (!g_isClosing)
|
||||
{
|
||||
m_appearTime = ImGui::GetTime();
|
||||
m_isClosing = true;
|
||||
g_appearTime = ImGui::GetTime();
|
||||
g_isClosing = true;
|
||||
}
|
||||
|
||||
if (ImGui::GetTime() - m_appearTime >= OVERLAY_CONTAINER_COMMON_MOTION_END)
|
||||
if (s_queue.size())
|
||||
{
|
||||
s_isVisible = false;
|
||||
AchievementOverlay::Open(s_queue.front());
|
||||
s_queue.pop();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include <queue>
|
||||
|
||||
class AchievementOverlay
|
||||
{
|
||||
public:
|
||||
inline static bool s_isVisible = false;
|
||||
|
||||
inline static std::queue<uint16_t> s_queue{};
|
||||
|
||||
static void Init();
|
||||
static void Draw();
|
||||
static void Open(int id);
|
||||
|
|
|
|||
|
|
@ -176,11 +176,16 @@ static float Lerp(float a, float b, float t)
|
|||
return a + (b - a) * t;
|
||||
}
|
||||
|
||||
static float CubicEase(float a, float b, float t)
|
||||
static float Cubic(float a, float b, float t)
|
||||
{
|
||||
return a + (b - a) * (t * t * t);
|
||||
}
|
||||
|
||||
static float Hermite(float a, float b, float t)
|
||||
{
|
||||
return a + (b - a) * (t * t * (3 - 2 * t));
|
||||
}
|
||||
|
||||
static ImVec2 Lerp(const ImVec2& a, const ImVec2& b, float t)
|
||||
{
|
||||
return { a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t };
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue