mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2026-04-27 21:01:37 +00:00
achievement_menu: added total unlocked achievements
This commit is contained in:
parent
dcd31ffab6
commit
d258cfbd2d
4 changed files with 92 additions and 2 deletions
|
|
@ -74,3 +74,23 @@ constexpr size_t FirstBitLow(TValue value)
|
||||||
|
|
||||||
return 0;
|
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;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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_START = 11;
|
||||||
constexpr double CONTENT_CONTAINER_COMMON_MOTION_END = 12;
|
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;
|
constexpr double SELECTION_CONTAINER_BREATHE = 30;
|
||||||
|
|
||||||
static bool g_isClosing = false;
|
static bool g_isClosing = false;
|
||||||
|
|
@ -33,6 +38,8 @@ static ImFont* g_fntSeurat;
|
||||||
static ImFont* g_fntNewRodinDB;
|
static ImFont* g_fntNewRodinDB;
|
||||||
static ImFont* g_fntNewRodinUB;
|
static ImFont* g_fntNewRodinUB;
|
||||||
|
|
||||||
|
static std::unique_ptr<GuestTexture> g_upTrophyIcon;
|
||||||
|
|
||||||
static int g_firstVisibleRowIndex;
|
static int g_firstVisibleRowIndex;
|
||||||
static int g_selectedRowIndex;
|
static int g_selectedRowIndex;
|
||||||
static double g_rowSelectionTime;
|
static double g_rowSelectionTime;
|
||||||
|
|
@ -350,6 +357,43 @@ static void DrawAchievement(int rowIndex, float yOffset, Achievement& achievemen
|
||||||
drawList->PopClipRect();
|
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()
|
static void DrawContentContainer()
|
||||||
{
|
{
|
||||||
auto drawList = ImGui::GetForegroundDrawList();
|
auto drawList = ImGui::GetForegroundDrawList();
|
||||||
|
|
@ -519,6 +563,8 @@ static void DrawContentContainer()
|
||||||
// Pop clip rect from DrawContentContainer
|
// Pop clip rect from DrawContentContainer
|
||||||
drawList->PopClipRect();
|
drawList->PopClipRect();
|
||||||
|
|
||||||
|
DrawAchievementTotal(min, max);
|
||||||
|
|
||||||
// Draw scroll bar
|
// Draw scroll bar
|
||||||
if (rowCount > visibleRowCount)
|
if (rowCount > visibleRowCount)
|
||||||
{
|
{
|
||||||
|
|
@ -582,6 +628,14 @@ void AchievementMenu::Init()
|
||||||
g_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);
|
||||||
g_fntNewRodinDB = io.Fonts->AddFontFromFileTTF("FOT-NewRodinPro-DB.otf", 20.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);
|
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()
|
void AchievementMenu::Draw()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
#include "achievement_data.h"
|
#include "achievement_data.h"
|
||||||
#include <fstream>
|
|
||||||
#include <ui/achievement_overlay.h>
|
#include <ui/achievement_overlay.h>
|
||||||
#include <user/config.h>
|
#include <user/config.h>
|
||||||
|
|
||||||
|
|
@ -19,6 +18,21 @@ time_t AchievementData::GetTimestamp(uint16_t id)
|
||||||
return 0;
|
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)
|
bool AchievementData::IsUnlocked(uint16_t id)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < NUM_RECORDS; i++)
|
for (int i = 0; i < NUM_RECORDS; i++)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#define ACH_SIGNATURE { 'A', 'C', 'H', ' ' }
|
#define ACH_SIGNATURE { 'A', 'C', 'H', ' ' }
|
||||||
#define ACH_VERSION { 1, 0, 0 }
|
#define ACH_VERSION { 1, 0, 0 }
|
||||||
|
#define ACH_RECORDS 50
|
||||||
|
|
||||||
class AchievementData
|
class AchievementData
|
||||||
{
|
{
|
||||||
|
|
@ -39,7 +40,7 @@ public:
|
||||||
Version Version{};
|
Version Version{};
|
||||||
uint32_t Checksum;
|
uint32_t Checksum;
|
||||||
uint32_t Reserved;
|
uint32_t Reserved;
|
||||||
Record Records[50];
|
Record Records[ACH_RECORDS];
|
||||||
};
|
};
|
||||||
|
|
||||||
inline static Data Data{ ACH_SIGNATURE, ACH_VERSION };
|
inline static Data Data{ ACH_SIGNATURE, ACH_VERSION };
|
||||||
|
|
@ -50,6 +51,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
static time_t GetTimestamp(uint16_t id);
|
static time_t GetTimestamp(uint16_t id);
|
||||||
|
static int GetTotalRecords();
|
||||||
static bool IsUnlocked(uint16_t id);
|
static bool IsUnlocked(uint16_t id);
|
||||||
static void Unlock(uint16_t id);
|
static void Unlock(uint16_t id);
|
||||||
static uint32_t CalculateChecksum();
|
static uint32_t CalculateChecksum();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue