achievement_menu: added total unlocked achievements

This commit is contained in:
Hyper 2024-12-01 19:43:09 +00:00
parent dcd31ffab6
commit d258cfbd2d
4 changed files with 92 additions and 2 deletions

View file

@ -74,3 +74,23 @@ constexpr size_t FirstBitLow(TValue value)
return 0;
}
static std::unique_ptr<uint8_t[]> ReadAllBytes(const char* filePath, size_t& fileSize)
{
FILE* file = fopen(filePath, "rb");
if (!file)
return std::make_unique<uint8_t[]>(0);
fseek(file, 0, SEEK_END);
fileSize = ftell(file);
fseek(file, 0, SEEK_SET);
auto data = std::make_unique<uint8_t[]>(fileSize);
fread(data.get(), 1, fileSize, file);
fclose(file);
return data;
}

View file

@ -21,6 +21,11 @@ constexpr double HEADER_CONTAINER_OUTRO_FADE_END = 7;
constexpr double CONTENT_CONTAINER_COMMON_MOTION_START = 11;
constexpr double CONTENT_CONTAINER_COMMON_MOTION_END = 12;
constexpr double COUNTER_INTRO_FADE_START = 15;
constexpr double COUNTER_INTRO_FADE_END = 16;
constexpr double COUNTER_SPRITE_FRAME_START = 0;
constexpr double COUNTER_SPRITE_FRAME_END = 30;
constexpr double SELECTION_CONTAINER_BREATHE = 30;
static bool g_isClosing = false;
@ -33,6 +38,8 @@ static ImFont* g_fntSeurat;
static ImFont* g_fntNewRodinDB;
static ImFont* g_fntNewRodinUB;
static std::unique_ptr<GuestTexture> g_upTrophyIcon;
static int g_firstVisibleRowIndex;
static int g_selectedRowIndex;
static double g_rowSelectionTime;
@ -350,6 +357,43 @@ static void DrawAchievement(int rowIndex, float yOffset, Achievement& achievemen
drawList->PopClipRect();
}
static void DrawAchievementTotal(ImVec2 min, ImVec2 max)
{
auto drawList = ImGui::GetForegroundDrawList();
// Transparency fade animation.
auto alpha = Cubic(0, 1, ComputeMotion(g_appearTime, COUNTER_INTRO_FADE_START, COUNTER_INTRO_FADE_END));
auto imageMarginX = Scale(5);
auto imageMarginY = Scale(5);
auto imageSize = Scale(45);
ImVec2 imageMin = { max.x - imageSize - imageMarginX, min.y - imageSize - imageMarginY };
ImVec2 imageMax = { imageMin.x + imageSize, imageMin.y + imageSize };
auto frm = int32_t(floor(ImGui::GetTime() * 30.0f)) % 30;
auto w = 256.0f / 7680.0f;
auto uv0 = ImVec2(frm * w, 0);
auto uv1 = ImVec2((frm + 1) * w, 1);
drawList->AddImage(g_upTrophyIcon.get(), imageMin, imageMax, uv0, uv1, IM_COL32(255, 255, 255, 255 * alpha));
auto str = std::format("{} / {}", AchievementData::GetTotalRecords(), ACH_RECORDS);
auto fontSize = Scale(20);
auto textSize = g_fntNewRodinDB->CalcTextSizeA(fontSize, FLT_MAX, 0, str.c_str());
DrawTextWithOutline<int>
(
g_fntNewRodinDB,
fontSize,
{ /* X */ imageMin.x - textSize.x - Scale(6), /* Y */ imageMin.y + ((imageMax.y - imageMin.y) - textSize.y) / 2 },
IM_COL32(255, 255, 255, 255 * alpha),
str.c_str(),
2,
IM_COL32(0, 0, 0, 255 * alpha)
);
}
static void DrawContentContainer()
{
auto drawList = ImGui::GetForegroundDrawList();
@ -519,6 +563,8 @@ static void DrawContentContainer()
// Pop clip rect from DrawContentContainer
drawList->PopClipRect();
DrawAchievementTotal(min, max);
// Draw scroll bar
if (rowCount > visibleRowCount)
{
@ -582,6 +628,14 @@ void AchievementMenu::Init()
g_fntSeurat = io.Fonts->AddFontFromFileTTF("FOT-SeuratPro-M.otf", 24.0f * FONT_SCALE);
g_fntNewRodinDB = io.Fonts->AddFontFromFileTTF("FOT-NewRodinPro-DB.otf", 20.0f * FONT_SCALE);
g_fntNewRodinUB = io.Fonts->AddFontFromFileTTF("FOT-NewRodinPro-UB.otf", 20.0f * FONT_SCALE);
size_t bufferSize = 0;
auto buffer = ReadAllBytes("achievements_trophy.png", bufferSize);
if (!bufferSize)
return;
g_upTrophyIcon = LoadTexture(buffer.get(), bufferSize);
}
void AchievementMenu::Draw()

View file

@ -1,5 +1,4 @@
#include "achievement_data.h"
#include <fstream>
#include <ui/achievement_overlay.h>
#include <user/config.h>
@ -19,6 +18,21 @@ time_t AchievementData::GetTimestamp(uint16_t id)
return 0;
}
int AchievementData::GetTotalRecords()
{
auto result = 0;
for (int i = 0; i < NUM_RECORDS; i++)
{
if (!Data.Records[i].ID)
break;
result++;
}
return result;
}
bool AchievementData::IsUnlocked(uint16_t id)
{
for (int i = 0; i < NUM_RECORDS; i++)

View file

@ -4,6 +4,7 @@
#define ACH_SIGNATURE { 'A', 'C', 'H', ' ' }
#define ACH_VERSION { 1, 0, 0 }
#define ACH_RECORDS 50
class AchievementData
{
@ -39,7 +40,7 @@ public:
Version Version{};
uint32_t Checksum;
uint32_t Reserved;
Record Records[50];
Record Records[ACH_RECORDS];
};
inline static Data Data{ ACH_SIGNATURE, ACH_VERSION };
@ -50,6 +51,7 @@ public:
}
static time_t GetTimestamp(uint16_t id);
static int GetTotalRecords();
static bool IsUnlocked(uint16_t id);
static void Unlock(uint16_t id);
static uint32_t CalculateChecksum();