mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2026-04-27 12:51:42 +00:00
Implemented message window
This commit is contained in:
parent
03381065c7
commit
55d40032b0
7 changed files with 433 additions and 2 deletions
|
|
@ -86,6 +86,7 @@ set(SWA_UI_CXX_SOURCES
|
||||||
"ui/achievement_menu.cpp"
|
"ui/achievement_menu.cpp"
|
||||||
"ui/achievement_overlay.cpp"
|
"ui/achievement_overlay.cpp"
|
||||||
"ui/installer_wizard.cpp"
|
"ui/installer_wizard.cpp"
|
||||||
|
"ui/message_window.cpp"
|
||||||
"ui/options_menu.cpp"
|
"ui/options_menu.cpp"
|
||||||
"ui/sdl_listener.cpp"
|
"ui/sdl_listener.cpp"
|
||||||
"ui/window.cpp"
|
"ui/window.cpp"
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include <shader/shader_cache.h>
|
#include <shader/shader_cache.h>
|
||||||
#include <ui/achievement_menu.h>
|
#include <ui/achievement_menu.h>
|
||||||
#include <ui/achievement_overlay.h>
|
#include <ui/achievement_overlay.h>
|
||||||
|
#include <ui/message_window.h>
|
||||||
#include <ui/options_menu.h>
|
#include <ui/options_menu.h>
|
||||||
#include <ui/installer_wizard.h>
|
#include <ui/installer_wizard.h>
|
||||||
|
|
||||||
|
|
@ -1066,6 +1067,7 @@ static void CreateImGuiBackend()
|
||||||
|
|
||||||
AchievementMenu::Init();
|
AchievementMenu::Init();
|
||||||
AchievementOverlay::Init();
|
AchievementOverlay::Init();
|
||||||
|
MessageWindow::Init();
|
||||||
OptionsMenu::Init();
|
OptionsMenu::Init();
|
||||||
InstallerWizard::Init();
|
InstallerWizard::Init();
|
||||||
|
|
||||||
|
|
@ -1741,6 +1743,7 @@ static void DrawImGui()
|
||||||
OptionsMenu::Draw();
|
OptionsMenu::Draw();
|
||||||
AchievementOverlay::Draw();
|
AchievementOverlay::Draw();
|
||||||
InstallerWizard::Draw();
|
InstallerWizard::Draw();
|
||||||
|
MessageWindow::Draw();
|
||||||
|
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <span>
|
||||||
#include <xbox.h>
|
#include <xbox.h>
|
||||||
#include <xxhash.h>
|
#include <xxhash.h>
|
||||||
#include <ankerl/unordered_dense.h>
|
#include <ankerl/unordered_dense.h>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,12 @@
|
||||||
#include <gpu/imgui_common.h>
|
#include <gpu/imgui_common.h>
|
||||||
#include <app.h>
|
#include <app.h>
|
||||||
|
|
||||||
|
#define PIXELS_TO_UV_COORDS(textureWidth, textureHeight, x, y, width, height) \
|
||||||
|
std::make_tuple(ImVec2((float)x / (float)textureWidth, (float)y / (float)textureHeight), \
|
||||||
|
ImVec2(((float)x + (float)width) / (float)textureWidth, ((float)y + (float)height) / (float)textureHeight))
|
||||||
|
|
||||||
|
#define GET_UV_COORDS(tuple) std::get<0>(tuple), std::get<1>(tuple)
|
||||||
|
|
||||||
static std::vector<std::unique_ptr<ImGuiCallbackData>> g_callbackData;
|
static std::vector<std::unique_ptr<ImGuiCallbackData>> g_callbackData;
|
||||||
static uint32_t g_callbackDataIndex = 0;
|
static uint32_t g_callbackDataIndex = 0;
|
||||||
|
|
||||||
|
|
@ -150,7 +156,80 @@ static void DrawTextWithShadow(const ImFont* font, float fontSize, const ImVec2&
|
||||||
|
|
||||||
DrawTextWithOutline<float>(font, fontSize, { pos.x + offset, pos.y + offset }, shadowColour, text, radius, shadowColour);
|
DrawTextWithOutline<float>(font, fontSize, { pos.x + offset, pos.y + offset }, shadowColour, text, radius, shadowColour);
|
||||||
|
|
||||||
drawList->AddText(font, fontSize, pos, colour, text);
|
drawList->AddText(font, fontSize, pos, colour, text, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static float CalcWidestTextSize(const ImFont* font, float fontSize, std::span<std::string> strs)
|
||||||
|
{
|
||||||
|
auto result = 0.0f;
|
||||||
|
|
||||||
|
for (auto& str : strs)
|
||||||
|
result = std::max(result, font->CalcTextSizeA(fontSize, FLT_MAX, 0, str.c_str()).x);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> Split(const char* str, char delimiter)
|
||||||
|
{
|
||||||
|
std::vector<std::string> result;
|
||||||
|
|
||||||
|
if (!str)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
const char* start = str;
|
||||||
|
const char* current = str;
|
||||||
|
|
||||||
|
while (*current)
|
||||||
|
{
|
||||||
|
if (*current == delimiter)
|
||||||
|
{
|
||||||
|
result.emplace_back(start, current - start);
|
||||||
|
start = current + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
current++;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.emplace_back(start);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ImVec2 MeasureCentredParagraph(const ImFont* font, float fontSize, float lineMargin, std::vector<std::string> lines)
|
||||||
|
{
|
||||||
|
auto x = 0.0f;
|
||||||
|
auto y = 0.0f;
|
||||||
|
|
||||||
|
for (auto& str : lines)
|
||||||
|
{
|
||||||
|
auto textSize = font->CalcTextSizeA(fontSize, FLT_MAX, 0, str.c_str());
|
||||||
|
|
||||||
|
x = std::max(x, textSize.x);
|
||||||
|
y += textSize.y + Scale(lineMargin);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { x, y };
|
||||||
|
}
|
||||||
|
|
||||||
|
static ImVec2 MeasureCentredParagraph(const ImFont* font, float fontSize, float lineMargin, const char* text)
|
||||||
|
{
|
||||||
|
return MeasureCentredParagraph(font, fontSize, lineMargin, Split(text, '\n'));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void DrawCentredParagraph(const ImFont* font, float fontSize, const ImVec2& centre, float lineMargin, const char* text, std::function<void(const char*, ImVec2)> drawMethod)
|
||||||
|
{
|
||||||
|
auto lines = Split(text, '\n');
|
||||||
|
auto paragraphSize = MeasureCentredParagraph(font, fontSize, lineMargin, lines);
|
||||||
|
auto offsetY = 0.0f;
|
||||||
|
|
||||||
|
for (auto& str : lines)
|
||||||
|
{
|
||||||
|
auto textSize = font->CalcTextSizeA(fontSize, FLT_MAX, 0, str.c_str());
|
||||||
|
|
||||||
|
drawMethod(str.c_str(), ImVec2(/* X */ centre.x - textSize.x / 2, /* Y */ centre.y - paragraphSize.y / 2 + offsetY));
|
||||||
|
|
||||||
|
offsetY += textSize.y + Scale(lineMargin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DrawTextWithMarqueeShadow(const ImFont* font, float fontSize, const ImVec2& pos, const ImVec2& min, const ImVec2& max, ImU32 colour, const char* text, double time, double delay, double speed, float offset = 2.0f, float radius = 0.4f, ImU32 shadowColour = IM_COL32(0, 0, 0, 255))
|
static void DrawTextWithMarqueeShadow(const ImFont* font, float fontSize, const ImVec2& pos, const ImVec2& min, const ImVec2& max, ImU32 colour, const char* text, double time, double delay, double speed, float offset = 2.0f, float radius = 0.4f, ImU32 shadowColour = IM_COL32(0, 0, 0, 255))
|
||||||
|
|
|
||||||
335
UnleashedRecomp/ui/message_window.cpp
Normal file
335
UnleashedRecomp/ui/message_window.cpp
Normal file
|
|
@ -0,0 +1,335 @@
|
||||||
|
#include "message_window.h"
|
||||||
|
#include "imgui_utils.h"
|
||||||
|
#include <api/SWA.h>
|
||||||
|
#include <gpu/video.h>
|
||||||
|
#include <exports.h>
|
||||||
|
#include "../UnleashedRecompResources/images/pause.h"
|
||||||
|
|
||||||
|
constexpr double OVERLAY_CONTAINER_COMMON_MOTION_START = 0;
|
||||||
|
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 = 4;
|
||||||
|
|
||||||
|
static bool g_isAwaitingResult = false;
|
||||||
|
static bool g_isClosing = false;
|
||||||
|
static bool g_isControlsVisible = false;
|
||||||
|
|
||||||
|
static int g_selectedRowIndex;
|
||||||
|
static int g_foregroundCount;
|
||||||
|
|
||||||
|
static bool g_upWasHeld;
|
||||||
|
static bool g_downWasHeld;
|
||||||
|
|
||||||
|
static double g_appearTime;
|
||||||
|
static double g_controlsAppearTime;
|
||||||
|
|
||||||
|
static ImFont* g_fntSeurat;
|
||||||
|
|
||||||
|
static std::unique_ptr<GuestTexture> g_upSelectionCursor;
|
||||||
|
|
||||||
|
std::string g_text;
|
||||||
|
int g_result;
|
||||||
|
std::vector<std::string> g_buttons;
|
||||||
|
int g_defaultButtonIndex;
|
||||||
|
|
||||||
|
bool DrawContainer(float appearTime, ImVec2 centre, ImVec2 max, bool isForeground = true)
|
||||||
|
{
|
||||||
|
auto drawList = ImGui::GetForegroundDrawList();
|
||||||
|
|
||||||
|
ImVec2 _min = { centre.x - max.x, centre.y - max.y };
|
||||||
|
ImVec2 _max = { centre.x + max.x, centre.y + max.y };
|
||||||
|
|
||||||
|
// Expand/retract animation.
|
||||||
|
auto containerMotion = ComputeMotion(appearTime, OVERLAY_CONTAINER_COMMON_MOTION_START, OVERLAY_CONTAINER_COMMON_MOTION_END);
|
||||||
|
|
||||||
|
if (g_isClosing)
|
||||||
|
{
|
||||||
|
_min.x = Hermite(_min.x, centre.x, containerMotion);
|
||||||
|
_max.x = Hermite(_max.x, centre.x, containerMotion);
|
||||||
|
_min.y = Hermite(_min.y, centre.y, containerMotion);
|
||||||
|
_max.y = Hermite(_max.y, centre.y, containerMotion);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_min.x = Hermite(centre.x, _min.x, containerMotion);
|
||||||
|
_max.x = Hermite(centre.x, _max.x, containerMotion);
|
||||||
|
_min.y = Hermite(centre.y, _min.y, containerMotion);
|
||||||
|
_max.y = Hermite(centre.y, _max.y, containerMotion);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto vertices = GetPauseContainerVertices(_min, _max);
|
||||||
|
|
||||||
|
// Transparency fade animation.
|
||||||
|
auto colourMotion = g_isClosing
|
||||||
|
? ComputeMotion(appearTime, OVERLAY_CONTAINER_OUTRO_FADE_START, OVERLAY_CONTAINER_OUTRO_FADE_END)
|
||||||
|
: ComputeMotion(appearTime, OVERLAY_CONTAINER_INTRO_FADE_START, OVERLAY_CONTAINER_INTRO_FADE_END);
|
||||||
|
|
||||||
|
auto alpha = g_isClosing
|
||||||
|
? Lerp(1, 0, colourMotion)
|
||||||
|
: Lerp(0, 1, colourMotion);
|
||||||
|
|
||||||
|
if (!isForeground)
|
||||||
|
g_foregroundCount++;
|
||||||
|
|
||||||
|
if (isForeground)
|
||||||
|
drawList->AddRectFilled({ 0.0f, 0.0f }, ImGui::GetIO().DisplaySize, IM_COL32(0, 0, 0, 223 * (g_foregroundCount ? 1 : alpha)));
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
drawList->PushClipRect(_min, _max);
|
||||||
|
|
||||||
|
return containerMotion >= 1.0f && !g_isClosing;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawButton(int rowIndex, float yOffset, float width, float height, std::string& text)
|
||||||
|
{
|
||||||
|
auto drawList = ImGui::GetForegroundDrawList();
|
||||||
|
|
||||||
|
auto clipRectMin = drawList->GetClipRectMin();
|
||||||
|
auto clipRectMax = drawList->GetClipRectMax();
|
||||||
|
|
||||||
|
ImVec2 min = { clipRectMin.x + ((clipRectMax.x - clipRectMin.x) - width) / 2, clipRectMin.y + height * rowIndex + yOffset };
|
||||||
|
ImVec2 max = { min.x + width, min.y + height };
|
||||||
|
|
||||||
|
bool isSelected = rowIndex == g_selectedRowIndex;
|
||||||
|
|
||||||
|
if (isSelected)
|
||||||
|
{
|
||||||
|
static auto breatheStart = ImGui::GetTime();
|
||||||
|
auto alpha = Lerp(1.0f, 0.75f, (sin((ImGui::GetTime() - breatheStart) * (2.0f * M_PI / (55.0f / 60.0f))) + 1.0f) / 2.0f);
|
||||||
|
auto colour = IM_COL32(255, 255, 255, 255 * alpha);
|
||||||
|
|
||||||
|
auto width = Scale(11);
|
||||||
|
auto left = PIXELS_TO_UV_COORDS(128, 128, 0, 0, 11, 50);
|
||||||
|
auto centre = PIXELS_TO_UV_COORDS(128, 128, 11, 0, 8, 50);
|
||||||
|
auto right = PIXELS_TO_UV_COORDS(128, 128, 19, 0, 11, 50);
|
||||||
|
|
||||||
|
drawList->AddImage(g_upSelectionCursor.get(), min, { min.x + width, max.y }, GET_UV_COORDS(left), colour);
|
||||||
|
drawList->AddImage(g_upSelectionCursor.get(), { min.x + width, min.y }, { max.x - width, max.y }, GET_UV_COORDS(centre), colour);
|
||||||
|
drawList->AddImage(g_upSelectionCursor.get(), { max.x - width, min.y }, max, GET_UV_COORDS(right), colour);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto fontSize = Scale(28);
|
||||||
|
auto textSize = g_fntSeurat->CalcTextSizeA(fontSize, FLT_MAX, 0, text.c_str());
|
||||||
|
|
||||||
|
DrawTextWithShadow
|
||||||
|
(
|
||||||
|
g_fntSeurat,
|
||||||
|
fontSize,
|
||||||
|
{ /* X */ min.x + ((max.x - min.x) - textSize.x) / 2, /* Y */ min.y + ((max.y - min.y) - textSize.y) / 2 },
|
||||||
|
isSelected ? IM_COL32(255, 128, 0, 255) : IM_COL32(255, 255, 255, 255),
|
||||||
|
text.c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ResetSelection()
|
||||||
|
{
|
||||||
|
g_selectedRowIndex = g_defaultButtonIndex;
|
||||||
|
g_upWasHeld = false;
|
||||||
|
g_downWasHeld = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageWindow::Init()
|
||||||
|
{
|
||||||
|
auto& io = ImGui::GetIO();
|
||||||
|
|
||||||
|
constexpr float FONT_SCALE = 2.0f;
|
||||||
|
|
||||||
|
g_fntSeurat = io.Fonts->AddFontFromFileTTF("FOT-SeuratPro-M.otf", 28.0f * FONT_SCALE);
|
||||||
|
|
||||||
|
g_upSelectionCursor = LoadTexture((uint8_t*)g_res_pause, g_res_pause_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageWindow::Draw()
|
||||||
|
{
|
||||||
|
if (!s_isVisible)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto pInputState = SWA::CInputState::GetInstance();
|
||||||
|
auto drawList = ImGui::GetForegroundDrawList();
|
||||||
|
auto& res = ImGui::GetIO().DisplaySize;
|
||||||
|
|
||||||
|
ImVec2 centre = { res.x / 2, res.y / 2 };
|
||||||
|
|
||||||
|
auto fontSize = Scale(28);
|
||||||
|
auto textSize = MeasureCentredParagraph(g_fntSeurat, fontSize, 5, g_text.c_str());
|
||||||
|
auto textMarginX = Scale(32);
|
||||||
|
auto textMarginY = Scale(40);
|
||||||
|
|
||||||
|
if (DrawContainer(g_appearTime, centre, { textSize.x / 2 + textMarginX, textSize.y / 2 + textMarginY }, !g_isControlsVisible))
|
||||||
|
{
|
||||||
|
DrawCentredParagraph
|
||||||
|
(
|
||||||
|
g_fntSeurat,
|
||||||
|
fontSize,
|
||||||
|
{ centre.x, centre.y + Scale(3) },
|
||||||
|
5,
|
||||||
|
g_text.c_str(),
|
||||||
|
|
||||||
|
[=](const char* str, ImVec2 pos)
|
||||||
|
{
|
||||||
|
DrawTextWithShadow(g_fntSeurat, fontSize, pos, IM_COL32(255, 255, 255, 255), str);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
drawList->PopClipRect();
|
||||||
|
|
||||||
|
if (g_buttons.size())
|
||||||
|
{
|
||||||
|
auto itemWidth = std::max(Scale(162), Scale(CalcWidestTextSize(g_fntSeurat, fontSize, g_buttons)));
|
||||||
|
auto itemHeight = Scale(57);
|
||||||
|
auto windowMarginX = Scale(18);
|
||||||
|
auto windowMarginY = Scale(25);
|
||||||
|
|
||||||
|
ImVec2 controlsMax = { /* X */ itemWidth / 2 + windowMarginX, /* Y */ itemHeight / 2 * g_buttons.size() + windowMarginY };
|
||||||
|
|
||||||
|
if (g_isControlsVisible && DrawContainer(g_controlsAppearTime, centre, controlsMax))
|
||||||
|
{
|
||||||
|
auto rowCount = 0;
|
||||||
|
|
||||||
|
for (auto& button : g_buttons)
|
||||||
|
DrawButton(rowCount++, windowMarginY, itemWidth, itemHeight, button);
|
||||||
|
|
||||||
|
drawList->PopClipRect();
|
||||||
|
|
||||||
|
bool upIsHeld = pInputState->GetPadState().IsDown(SWA::eKeyState_DpadUp) ||
|
||||||
|
pInputState->GetPadState().LeftStickVertical > 0.5f;
|
||||||
|
|
||||||
|
bool downIsHeld = pInputState->GetPadState().IsDown(SWA::eKeyState_DpadDown) ||
|
||||||
|
pInputState->GetPadState().LeftStickVertical < -0.5f;
|
||||||
|
|
||||||
|
bool scrollUp = !g_upWasHeld && upIsHeld;
|
||||||
|
bool scrollDown = !g_downWasHeld && downIsHeld;
|
||||||
|
|
||||||
|
if (scrollUp)
|
||||||
|
{
|
||||||
|
--g_selectedRowIndex;
|
||||||
|
if (g_selectedRowIndex < 0)
|
||||||
|
g_selectedRowIndex = rowCount - 1;
|
||||||
|
}
|
||||||
|
else if (scrollDown)
|
||||||
|
{
|
||||||
|
++g_selectedRowIndex;
|
||||||
|
if (g_selectedRowIndex >= rowCount)
|
||||||
|
g_selectedRowIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scrollUp || scrollDown)
|
||||||
|
Game_PlaySound("sys_actstg_pausecursor");
|
||||||
|
|
||||||
|
g_upWasHeld = upIsHeld;
|
||||||
|
g_downWasHeld = downIsHeld;
|
||||||
|
|
||||||
|
if (pInputState->GetPadState().IsTapped(SWA::eKeyState_A))
|
||||||
|
{
|
||||||
|
g_result = g_selectedRowIndex;
|
||||||
|
|
||||||
|
Game_PlaySound("sys_actstg_pausedecide");
|
||||||
|
MessageWindow::Close();
|
||||||
|
}
|
||||||
|
else if (pInputState->GetPadState().IsTapped(SWA::eKeyState_B))
|
||||||
|
{
|
||||||
|
g_result = -1;
|
||||||
|
|
||||||
|
Game_PlaySound("sys_actstg_pausecansel");
|
||||||
|
MessageWindow::Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!g_isControlsVisible && pInputState->GetPadState().IsTapped(SWA::eKeyState_A))
|
||||||
|
{
|
||||||
|
g_controlsAppearTime = ImGui::GetTime();
|
||||||
|
g_isControlsVisible = true;
|
||||||
|
|
||||||
|
Game_PlaySound("sys_actstg_pausewinopen");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (pInputState->GetPadState().IsTapped(SWA::eKeyState_A))
|
||||||
|
MessageWindow::Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MessageWindow::Open(std::string text, int* result, std::span<std::string> buttons, int defaultButtonIndex)
|
||||||
|
{
|
||||||
|
if (!g_isAwaitingResult && *result == -1)
|
||||||
|
{
|
||||||
|
s_isVisible = true;
|
||||||
|
g_isClosing = false;
|
||||||
|
g_isControlsVisible = false;
|
||||||
|
g_foregroundCount = 0;
|
||||||
|
g_appearTime = ImGui::GetTime();
|
||||||
|
g_controlsAppearTime = ImGui::GetTime();
|
||||||
|
|
||||||
|
g_text = text;
|
||||||
|
g_buttons = std::vector(buttons.begin(), buttons.end());
|
||||||
|
g_defaultButtonIndex = defaultButtonIndex;
|
||||||
|
|
||||||
|
ResetSelection();
|
||||||
|
|
||||||
|
Game_PlaySound("sys_actstg_pausewinopen");
|
||||||
|
|
||||||
|
g_isAwaitingResult = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
*result = g_result;
|
||||||
|
|
||||||
|
return !g_isAwaitingResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageWindow::Close()
|
||||||
|
{
|
||||||
|
if (!g_isClosing)
|
||||||
|
{
|
||||||
|
g_appearTime = ImGui::GetTime();
|
||||||
|
g_controlsAppearTime = ImGui::GetTime();
|
||||||
|
g_isClosing = true;
|
||||||
|
g_isControlsVisible = false;
|
||||||
|
g_isAwaitingResult = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Game_PlaySound("sys_actstg_pausewinclose");
|
||||||
|
}
|
||||||
12
UnleashedRecomp/ui/message_window.h
Normal file
12
UnleashedRecomp/ui/message_window.h
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
class MessageWindow
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline static bool s_isVisible = false;
|
||||||
|
|
||||||
|
static void Init();
|
||||||
|
static void Draw();
|
||||||
|
static bool Open(std::string text, int* result, std::span<std::string> buttons = {}, int defaultButtonIndex = 0);
|
||||||
|
static void Close();
|
||||||
|
};
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#include <api/SWA.h>
|
#include <api/SWA.h>
|
||||||
|
|
||||||
struct OptionsMenu
|
class OptionsMenu
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline static bool s_isVisible = false;
|
inline static bool s_isVisible = false;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue