diff --git a/UnleashedRecomp/CMakeLists.txt b/UnleashedRecomp/CMakeLists.txt index 02b8aa9f..1f71ba32 100644 --- a/UnleashedRecomp/CMakeLists.txt +++ b/UnleashedRecomp/CMakeLists.txt @@ -314,6 +314,7 @@ set(RESOURCES_SOURCE_PATH "${PROJECT_SOURCE_DIR}/../UnleashedRecompResources") set(RESOURCES_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/res") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/achievements_menu/trophy.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/achievements_menu/trophy.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_trophy") +BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/general_window.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/general_window.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_general_window") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/select_fade.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select_fade.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_select_fade") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/common/select_fill.dds" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/common/select_fill.dds" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_select_fill") BIN2C(TARGET_OBJ UnleashedRecomp SOURCE_FILE "${RESOURCES_SOURCE_PATH}/images/game_icon.bmp" DEST_FILE "${RESOURCES_OUTPUT_PATH}/images/game_icon.bmp" ARRAY_TYPE "unsigned char" ARRAY_NAME "g_game_icon") diff --git a/UnleashedRecomp/ui/achievement_menu.cpp b/UnleashedRecomp/ui/achievement_menu.cpp index 52f70af1..152cfbde 100644 --- a/UnleashedRecomp/ui/achievement_menu.cpp +++ b/UnleashedRecomp/ui/achievement_menu.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include constexpr double HEADER_CONTAINER_INTRO_MOTION_START = 0; @@ -40,6 +41,7 @@ static ImFont* g_fntNewRodinUB; static std::unique_ptr g_upTrophyIcon; static std::unique_ptr g_upSelectionCursor; +static std::unique_ptr g_upWindow; static int g_firstVisibleRowIndex; static int g_selectedRowIndex; @@ -64,42 +66,8 @@ static void ResetSelection() static void DrawContainer(ImVec2 min, ImVec2 max, ImU32 gradientTop, ImU32 gradientBottom, float alpha = 1, float cornerRadius = 25) { auto drawList = ImGui::GetForegroundDrawList(); - auto vertices = GetPauseContainerVertices(min, max, cornerRadius); - // TODO: add a drop shadow. - - SetGradient(min, max, gradientTop, gradientBottom); - drawList->AddConvexPolyFilled(vertices.data(), vertices.size(), IM_COL32(255, 255, 255, 255 * alpha)); - ResetGradient(); - - drawList->AddPolyline(vertices.data(), vertices.size(), IM_COL32(247, 247, 247, 255 * alpha), true, Scale(2.5f)); - - for (int i = 0; i < vertices.size(); i++) - { - vertices[i].x -= Scale(0.4f); - vertices[i].y -= Scale(0.2f); - } - - auto colLineTop = IM_COL32(165, 170, 165, 230 * alpha); - auto colLineBottom = IM_COL32(190, 190, 190, 230 * alpha); - auto lineThickness = Scale(1); - - // Top left corner bottom to top left corner top. - drawList->AddLine(vertices[0], vertices[1], colLineTop, lineThickness * Scale(0.5f)); - - // Top left corner bottom to bottom left. - drawList->AddRectFilledMultiColor - ( - { /* X */ vertices[0].x - Scale(0.2f), /* Y */ vertices[0].y }, - { /* X */ vertices[6].x + lineThickness - Scale(0.2f), /* Y */ vertices[6].y }, - colLineTop, - colLineTop, - colLineBottom, - colLineBottom - ); - - // Top left corner top to top right. - drawList->AddLine(vertices[1], vertices[2], colLineTop, lineThickness); + DrawPauseContainer(g_upWindow, min, max, alpha); drawList->PushClipRect({ min.x, min.y + Scale(20) }, { max.x, max.y - Scale(5) }); } @@ -139,7 +107,7 @@ static void DrawSelectionContainer(ImVec2 min, ImVec2 max) static void DrawHeaderContainer(const char* text) { auto drawList = ImGui::GetForegroundDrawList(); - auto fontSize = Scale(26); + auto fontSize = Scale(24); auto textSize = g_fntNewRodinUB->CalcTextSizeA(fontSize, FLT_MAX, 0, text); auto cornerRadius = 23; auto textMarginX = Scale(16) + (Scale(cornerRadius) / 2); @@ -154,26 +122,25 @@ static void DrawHeaderContainer(const char* text) // Slide animation. auto containerMarginX = g_isClosing - ? Hermite(256, 156, containerMotion) - : Hermite(156, 256, containerMotion); + ? Hermite(251, 151, containerMotion) + : Hermite(151, 251, containerMotion); // Transparency fade animation. auto alpha = g_isClosing ? Lerp(1, 0, colourMotion) : Lerp(0, 1, colourMotion); - ImVec2 min = { Scale(containerMarginX), Scale(138) }; - ImVec2 max = { min.x + textMarginX * 2 + textSize.x, Scale(185) }; + ImVec2 min = { Scale(containerMarginX), Scale(136) }; + ImVec2 max = { min.x + textMarginX * 2 + textSize.x + Scale(5), Scale(196) }; - DrawContainer(min, max, IM_COL32(140, 142, 140, 201), IM_COL32(66, 65, 66, 234), alpha, cornerRadius); - drawList->PopClipRect(); + DrawPauseHeaderContainer(g_upWindow, min, max, alpha); // TODO: skew this text and apply bevel. DrawTextWithOutline ( g_fntNewRodinUB, fontSize, - { /* X */ min.x + textMarginX, /* Y */ min.y + ((max.y - min.y) - textSize.y) / 2 }, + { /* X */ min.x + textMarginX, /* Y */ min.y + ((max.y - min.y) - textSize.y) / 2 - Scale(5) }, IM_COL32(255, 255, 255, 255 * alpha), text, 3, @@ -188,9 +155,9 @@ static void DrawAchievement(int rowIndex, float yOffset, Achievement& achievemen auto clipRectMin = drawList->GetClipRectMin(); auto clipRectMax = drawList->GetClipRectMax(); - auto itemWidth = Scale(708); + auto itemWidth = Scale(700); auto itemHeight = Scale(94); - auto itemMarginX = Scale(13); + auto itemMarginX = Scale(18); auto imageMarginX = Scale(25); auto imageMarginY = Scale(18); auto imageSize = Scale(60); @@ -430,20 +397,20 @@ static void DrawContentContainer() : ComputeMotion(g_appearTime, CONTENT_CONTAINER_COMMON_MOTION_START, CONTENT_CONTAINER_COMMON_MOTION_END); auto minX = g_isClosing - ? Hermite(256, 306, motion) - : Hermite(306, 256, motion); + ? Hermite(251, 301, motion) + : Hermite(301, 251, motion); auto minY = g_isClosing - ? Hermite(192, 209, motion) - : Hermite(209, 192, motion); + ? Hermite(189, 206, motion) + : Hermite(206, 189, motion); auto maxX = g_isClosing - ? Hermite(1026, 973, motion) - : Hermite(973, 1026, motion); + ? Hermite(1031, 978, motion) + : Hermite(978, 1031, motion); auto maxY = g_isClosing - ? Hermite(601, 569, motion) - : Hermite(569, 601, motion); + ? Hermite(604, 573, motion) + : Hermite(573, 604, motion); ImVec2 min = { Scale(minX), Scale(minY) }; ImVec2 max = { Scale(maxX), Scale(maxY) }; @@ -475,8 +442,8 @@ static void DrawContentContainer() // Draw separators. for (int i = 1; i <= 3; i++) { - auto lineMarginLeft = Scale(31); - auto lineMarginRight = Scale(46); + auto lineMarginLeft = Scale(35); + auto lineMarginRight = Scale(55); auto lineMarginY = Scale(2); ImVec2 lineMin = { clipRectMin.x + lineMarginLeft, clipRectMin.y + itemHeight * i + lineMarginY }; @@ -594,34 +561,35 @@ static void DrawContentContainer() // Draw scroll bar if (rowCount > visibleRowCount) { - float cornerRadius = Scale(25.0f); - float totalHeight = (clipRectMax.y - clipRectMin.y - cornerRadius) - Scale(3.0f); + float cornerRadius = Scale(25); + float totalHeight = (clipRectMax.y - clipRectMin.y - cornerRadius) - Scale(3); float heightRatio = float(visibleRowCount) / float(rowCount); float offsetRatio = float(g_firstVisibleRowIndex) / float(rowCount); - float offsetX = clipRectMax.x - Scale(31.0f); - float offsetY = offsetRatio * totalHeight + clipRectMin.y + Scale(4.0f); - float lineThickness = Scale(1.0f); - float innerMarginX = Scale(2.0f); - float outerMarginX = Scale(16.0f); + float offsetX = clipRectMax.x - Scale(39); + float offsetY = offsetRatio * totalHeight + clipRectMin.y + Scale(4); + float maxY = max.y - cornerRadius - Scale(3); + float lineThickness = Scale(1); + float innerMarginX = Scale(2); + float outerMarginX = Scale(24); // Outline drawList->AddRect ( { /* X */ offsetX - lineThickness, /* Y */ clipRectMin.y - lineThickness }, - { /* X */ clipRectMax.x - outerMarginX + lineThickness, /* Y */ max.y - cornerRadius + lineThickness }, + { /* X */ clipRectMax.x - outerMarginX + lineThickness, /* Y */ maxY + lineThickness }, IM_COL32(255, 255, 255, 155), - Scale(0.5f) + Scale(1) ); // Background drawList->AddRectFilledMultiColor ( { /* X */ offsetX, /* Y */ clipRectMin.y }, - { /* X */ clipRectMax.x - outerMarginX, /* Y */ max.y - cornerRadius }, - IM_COL32(82, 85, 82, 186), - IM_COL32(82, 85, 82, 186), - IM_COL32(74, 73, 74, 185), - IM_COL32(74, 73, 74, 185) + { /* X */ clipRectMax.x - outerMarginX, /* Y */ maxY }, + IM_COL32(123, 125, 123, 255), + IM_COL32(123, 125, 123, 255), + IM_COL32(97, 99, 97, 255), + IM_COL32(97, 99, 97, 255) ); // Scroll Bar Outline @@ -657,6 +625,7 @@ void AchievementMenu::Init() g_upTrophyIcon = LoadTexture(g_trophy, sizeof(g_trophy)); g_upSelectionCursor = LoadTexture(g_select_fill, sizeof(g_select_fill)); + g_upWindow = LoadTexture(g_general_window, sizeof(g_general_window)); } void AchievementMenu::Draw() diff --git a/UnleashedRecomp/ui/achievement_overlay.cpp b/UnleashedRecomp/ui/achievement_overlay.cpp index e6e4eee4..703fce46 100644 --- a/UnleashedRecomp/ui/achievement_overlay.cpp +++ b/UnleashedRecomp/ui/achievement_overlay.cpp @@ -8,6 +8,7 @@ #include #include #include +#include constexpr double OVERLAY_CONTAINER_COMMON_MOTION_START = 0; constexpr double OVERLAY_CONTAINER_COMMON_MOTION_END = 11; @@ -26,6 +27,8 @@ static Achievement g_achievement; static ImFont* g_fntSeurat; +static std::unique_ptr g_upWindow; + static bool DrawContainer(ImVec2 min, ImVec2 max, float cornerRadius = 25) { auto drawList = ImGui::GetForegroundDrawList(); @@ -51,8 +54,6 @@ static bool DrawContainer(ImVec2 min, ImVec2 max, float cornerRadius = 25) max.y = Hermite(centreY, max.y, containerMotion); } - auto vertices = GetPauseContainerVertices(min, max, cornerRadius); - // Transparency fade animation. auto colourMotion = g_isClosing ? ComputeMotion(g_appearTime, OVERLAY_CONTAINER_OUTRO_FADE_START, OVERLAY_CONTAINER_OUTRO_FADE_END) @@ -62,46 +63,7 @@ static bool DrawContainer(ImVec2 min, ImVec2 max, float cornerRadius = 25) ? 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); - auto colGradientBottom = IM_COL32(115, 113, 115, 236 * alpha); - - // TODO: add a drop shadow. - - // Draw vertices with gradient. - SetGradient(min, max, colGradientTop, colGradientBottom); - drawList->AddConvexPolyFilled(vertices.data(), vertices.size(), IM_COL32(255, 255, 255, 255 * alpha)); - ResetGradient(); - - // Draw outline. - drawList->AddPolyline - ( - vertices.data(), - vertices.size(), - IM_COL32(247, 247, 247, 255 * alpha), - true, - Scale(2.5f) - ); - - // Offset vertices to draw 3D effect lines. - for (int i = 0; i < vertices.size(); i++) - { - vertices[i].x -= Scale(0.4f); - vertices[i].y -= Scale(0.2f); - } - - auto colLineTop = IM_COL32(165, 170, 165, 230 * alpha); - auto colLineBottom = IM_COL32(190, 190, 190, 230 * alpha); - auto lineThickness = Scale(1.0f); - - // Top left corner bottom to top left corner top. - drawList->AddLine(vertices[0], vertices[1], colLineTop, lineThickness * 0.5f); - - // Top left corner bottom to bottom left. - drawList->AddRectFilledMultiColor({ vertices[0].x - 0.2f, vertices[0].y }, { vertices[6].x + lineThickness - 0.2f, vertices[6].y }, colLineTop, colLineTop, colLineBottom, colLineBottom); - - // Top left corner top to top right. - drawList->AddLine(vertices[1], vertices[2], colLineTop, lineThickness); + DrawPauseContainer(g_upWindow, min, max, alpha); drawList->PushClipRect(min, max); @@ -115,6 +77,8 @@ void AchievementOverlay::Init() constexpr float FONT_SCALE = 2.0f; g_fntSeurat = io.Fonts->AddFontFromFileTTF("FOT-SeuratPro-M.otf", 24.0f * FONT_SCALE); + + g_upWindow = LoadTexture(g_general_window, sizeof(g_general_window)); } void AchievementOverlay::Draw() @@ -138,18 +102,18 @@ void AchievementOverlay::Draw() auto maxSize = std::max(headerSize.x, bodySize.x); // Calculate image margins. - auto imageMarginX = Scale(20); - auto imageMarginY = Scale(20); + auto imageMarginX = Scale(25); + auto imageMarginY = Scale(22.5f); auto imageSize = Scale(60); // Calculate text margins. - auto textMarginX = imageMarginX * 2 + imageSize; + auto textMarginX = imageMarginX * 2 + imageSize - Scale(5); auto textMarginY = imageMarginY + Scale(2); auto containerWidth = imageMarginX + textMarginX + maxSize; - ImVec2 min = { (res.x / 2) - (containerWidth / 2), Scale(50) }; - ImVec2 max = { min.x + containerWidth, min.y + Scale(100) }; + ImVec2 min = { (res.x / 2) - (containerWidth / 2), Scale(55) }; + ImVec2 max = { min.x + containerWidth, min.y + Scale(105) }; if (DrawContainer(min, max)) { diff --git a/UnleashedRecomp/ui/imgui_utils.h b/UnleashedRecomp/ui/imgui_utils.h index 728e5c57..50bbfafe 100644 --- a/UnleashedRecomp/ui/imgui_utils.h +++ b/UnleashedRecomp/ui/imgui_utils.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #define PIXELS_TO_UV_COORDS(textureWidth, textureHeight, x, y, width, height) \ @@ -84,17 +85,65 @@ static std::vector GetPauseContainerVertices(ImVec2 min, ImVec2 max, flo return { - { min.x, min.y + cornerRadius }, - { min.x + cornerRadius, min.y }, - { max.x, min.y }, - { max.x, min.y + cornerRadius }, - { max.x, max.y - cornerRadius }, - { max.x - cornerRadius, max.y }, - { min.x, max.y }, - { min.x, max.y - cornerRadius } + { min.x, min.y + cornerRadius }, // 0 - TL Corner Bottom + { min.x + cornerRadius, min.y }, // 1 - TL Corner Top + { max.x, min.y }, // 2 - TR Corner Top + { max.x, min.y + cornerRadius }, // 3 - TR Corner Bottom + { max.x, max.y - cornerRadius }, // 4 - BR Corner Top + { max.x - cornerRadius, max.y }, // 5 - BR Corner Bottom + { min.x, max.y }, // 6 - BL Corner Bottom + { min.x, max.y - cornerRadius } // 7 - BL Corner Top }; } +static void DrawPauseContainer(std::unique_ptr& texture, ImVec2 min, ImVec2 max, float alpha = 1) +{ + auto drawList = ImGui::GetForegroundDrawList(); + + auto commonWidth = Scale(35); + auto commonHeight = Scale(35); + auto bottomHeight = Scale(5); + + auto tl = PIXELS_TO_UV_COORDS(512, 512, 0, 0, 35, 35); + auto tc = PIXELS_TO_UV_COORDS(512, 512, 51, 0, 5, 35); + auto tr = PIXELS_TO_UV_COORDS(512, 512, 70, 0, 35, 35); + auto cl = PIXELS_TO_UV_COORDS(512, 512, 0, 35, 35, 235); + auto cc = PIXELS_TO_UV_COORDS(512, 512, 51, 35, 5, 235); + auto cr = PIXELS_TO_UV_COORDS(512, 512, 70, 35, 35, 235); + auto bl = PIXELS_TO_UV_COORDS(512, 512, 0, 270, 35, 40); + auto bc = PIXELS_TO_UV_COORDS(512, 512, 51, 270, 5, 40); + auto br = PIXELS_TO_UV_COORDS(512, 512, 70, 270, 35, 40); + + auto colour = IM_COL32(255, 255, 255, 255 * alpha); + + drawList->AddImage(texture.get(), min, { min.x + commonWidth, min.y + commonHeight }, GET_UV_COORDS(tl), colour); + drawList->AddImage(texture.get(), { min.x + commonWidth, min.y }, { max.x - commonWidth, min.y + commonHeight }, GET_UV_COORDS(tc), colour); + drawList->AddImage(texture.get(), { max.x - commonWidth, min.y }, { max.x, min.y + commonHeight }, GET_UV_COORDS(tr), colour); + drawList->AddImage(texture.get(), { min.x, min.y + commonHeight }, { min.x + commonWidth, max.y - commonHeight }, GET_UV_COORDS(cl), colour); + drawList->AddImage(texture.get(), { min.x + commonWidth, min.y + commonHeight }, { max.x - commonWidth, max.y - commonHeight }, GET_UV_COORDS(cc), colour); + drawList->AddImage(texture.get(), { max.x - commonWidth, min.y + commonHeight }, { max.x, max.y - commonHeight }, GET_UV_COORDS(cr), colour); + drawList->AddImage(texture.get(), { min.x, max.y - commonHeight }, { min.x + commonWidth, max.y + bottomHeight }, GET_UV_COORDS(bl), colour); + drawList->AddImage(texture.get(), { min.x + commonWidth, max.y - commonHeight }, { max.x - commonWidth, max.y + bottomHeight }, GET_UV_COORDS(bc), colour); + drawList->AddImage(texture.get(), { max.x - commonWidth, max.y - commonHeight }, { max.x, max.y + bottomHeight }, GET_UV_COORDS(br), colour); +} + +static void DrawPauseHeaderContainer(std::unique_ptr& texture, ImVec2 min, ImVec2 max, float alpha = 1) +{ + auto drawList = ImGui::GetForegroundDrawList(); + + auto commonWidth = Scale(35); + + auto left = PIXELS_TO_UV_COORDS(512, 512, 0, 314, 35, 60); + auto centre = PIXELS_TO_UV_COORDS(512, 512, 51, 314, 5, 60); + auto right = PIXELS_TO_UV_COORDS(512, 512, 70, 314, 35, 60); + + auto colour = IM_COL32(255, 255, 255, 255 * alpha); + + drawList->AddImage(texture.get(), min, { min.x + commonWidth, max.y }, GET_UV_COORDS(left), colour); + drawList->AddImage(texture.get(), { min.x + commonWidth, min.y }, { max.x - commonWidth, max.y }, GET_UV_COORDS(centre), colour); + drawList->AddImage(texture.get(), { max.x - commonWidth, min.y }, max, GET_UV_COORDS(right), colour); +} + static void DrawTextWithMarquee(const ImFont* font, float fontSize, const ImVec2& pos, const ImVec2& min, const ImVec2& max, ImU32 color, const char* text, double time, double delay, double speed) { auto drawList = ImGui::GetForegroundDrawList(); diff --git a/UnleashedRecompResources b/UnleashedRecompResources index e8dc5618..5b5ad279 160000 --- a/UnleashedRecompResources +++ b/UnleashedRecompResources @@ -1 +1 @@ -Subproject commit e8dc561807e68b65ce55e32292912c356f3e56c8 +Subproject commit 5b5ad2794a2c78d50dc6a85e71954fb6b9e80ae2