diff --git a/src/core/achievements.cpp b/src/core/achievements.cpp index 71eab67a6..9875cc4b4 100644 --- a/src/core/achievements.cpp +++ b/src/core/achievements.cpp @@ -305,7 +305,8 @@ std::string Achievements::GetGameHash(CDImage* image) void Achievements::DownloadImage(std::string url, std::string cache_filename) { - auto callback = [cache_filename](s32 status_code, const std::string& content_type, HTTPDownloader::Request::Data data) { + auto callback = [cache_filename](s32 status_code, const std::string& content_type, + HTTPDownloader::Request::Data data) { if (status_code != HTTPDownloader::HTTP_STATUS_OK) return; @@ -615,18 +616,18 @@ uint32_t Achievements::ClientReadMemory(uint32_t address, uint8_t* buffer, uint3 void Achievements::ClientServerCall(const rc_api_request_t* request, rc_client_server_callback_t callback, void* callback_data, rc_client_t* client) { - HTTPDownloader::Request::Callback hd_callback = [callback, callback_data](s32 status_code, const std::string& content_type, - HTTPDownloader::Request::Data data) { - rc_api_server_response_t rr; - rr.http_status_code = (status_code <= 0) ? (status_code == HTTPDownloader::HTTP_STATUS_CANCELLED ? - RC_API_SERVER_RESPONSE_CLIENT_ERROR : - RC_API_SERVER_RESPONSE_RETRYABLE_CLIENT_ERROR) : - status_code; - rr.body_length = data.size(); - rr.body = reinterpret_cast(data.data()); + HTTPDownloader::Request::Callback hd_callback = + [callback, callback_data](s32 status_code, const std::string& content_type, HTTPDownloader::Request::Data data) { + rc_api_server_response_t rr; + rr.http_status_code = (status_code <= 0) ? (status_code == HTTPDownloader::HTTP_STATUS_CANCELLED ? + RC_API_SERVER_RESPONSE_CLIENT_ERROR : + RC_API_SERVER_RESPONSE_RETRYABLE_CLIENT_ERROR) : + status_code; + rr.body_length = data.size(); + rr.body = reinterpret_cast(data.data()); - callback(&rr, callback_data); - }; + callback(&rr, callback_data); + }; HTTPDownloader* http = static_cast(rc_client_get_userdata(client)); @@ -1793,6 +1794,43 @@ bool Achievements::ConfirmHardcoreModeDisable(const char* trigger) return true; } +void Achievements::ConfirmHardcoreModeDisableAsync(const char* trigger, std::function callback) +{ +#ifdef ENABLE_RAINTEGRATION + if (IsUsingRAIntegration()) + { + const bool result = (RA_WarnDisableHardcore(trigger) != 0); + callback(result); + return; + } +#endif + + if (!FullscreenUI::Initialize()) + { + Host::AddOSDMessage(fmt::format(TRANSLATE_FS("Cannot {} while hardcode mode is active.", trigger)), + Host::OSD_WARNING_DURATION); + callback(false); + return; + } + + auto real_callback = [callback = std::move(callback)](bool res) mutable { + // don't run the callback in the middle of rendering the UI + Host::RunOnCPUThread([callback = std::move(callback), res]() { + if (res) + DisableHardcoreMode(); + callback(res); + }); + }; + + ImGuiFullscreen::OpenConfirmMessageDialog( + TRANSLATE_STR("Achievements", "Confirm Hardcore Mode"), + fmt::format(TRANSLATE_FS("Achievements", "{0} cannot be performed while hardcore mode is active. Do you " + "want to disable hardcore mode? {0} will be cancelled if you select No."), + trigger), + std::move(real_callback), fmt::format(ICON_FA_CHECK " {}", TRANSLATE_SV("Achievements", "Yes")), + fmt::format(ICON_FA_TIMES " {}", TRANSLATE_SV("Achievements", "No"))); +} + void Achievements::ClearUIState() { #ifndef __ANDROID__ diff --git a/src/core/achievements.h b/src/core/achievements.h index 32245d523..d4eb68dd4 100644 --- a/src/core/achievements.h +++ b/src/core/achievements.h @@ -6,6 +6,7 @@ #include "common/small_string.h" #include "common/types.h" +#include #include #include #include @@ -81,6 +82,7 @@ void DisableHardcoreMode(); /// Prompts the user to disable hardcore mode, if they agree, returns true. bool ConfirmHardcoreModeDisable(const char* trigger); +void ConfirmHardcoreModeDisableAsync(const char* trigger, std::function callback); /// Returns true if hardcore mode is active, and functionality should be restricted. bool IsHardcoreModeActive(); diff --git a/src/core/fullscreen_ui.cpp b/src/core/fullscreen_ui.cpp index dbce45cdd..e091cd076 100644 --- a/src/core/fullscreen_ui.cpp +++ b/src/core/fullscreen_ui.cpp @@ -6472,98 +6472,6 @@ void FullscreenUI::DrawAboutWindow() ImGui::PopFont(); } -bool FullscreenUI::DrawErrorWindow(const char* message) -{ - bool is_open = true; - - ImGuiFullscreen::BeginLayout(); - - ImGui::SetNextWindowSize(LayoutScale(500.0f, 0.0f)); - ImGui::SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f)); - ImGui::OpenPopup("ReportError"); - - ImGui::PushFont(g_large_font); - ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, LayoutScale(10.0f)); - ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, LayoutScale(10.0f, 10.0f)); - - if (ImGui::BeginPopupModal("ReportError", &is_open, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize)) - { - ImGui::SetCursorPos(LayoutScale(LAYOUT_MENU_BUTTON_X_PADDING, LAYOUT_MENU_BUTTON_Y_PADDING)); - ImGui::TextWrapped("%s", message); - ImGui::GetCurrentWindow()->DC.CursorPos.y += LayoutScale(5.0f); - - BeginMenuButtons(); - - if (ActiveButton(FSUI_ICONSTR(ICON_FA_WINDOW_CLOSE, "Close"), false)) - { - ImGui::CloseCurrentPopup(); - is_open = false; - } - EndMenuButtons(); - - ImGui::EndPopup(); - } - - ImGui::PopStyleVar(2); - ImGui::PopFont(); - - ImGuiFullscreen::EndLayout(); - return !is_open; -} - -bool FullscreenUI::DrawConfirmWindow(const char* message, bool* result) -{ - bool is_open = true; - - ImGuiFullscreen::BeginLayout(); - - ImGui::SetNextWindowSize(LayoutScale(500.0f, 0.0f)); - ImGui::SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f)); - ImGui::OpenPopup("ConfirmMessage"); - - ImGui::PushFont(g_large_font); - ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, LayoutScale(10.0f)); - ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, LayoutScale(10.0f, 10.0f)); - - if (ImGui::BeginPopupModal("ConfirmMessage", &is_open, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize)) - { - ImGui::SetCursorPos(LayoutScale(LAYOUT_MENU_BUTTON_X_PADDING, LAYOUT_MENU_BUTTON_Y_PADDING)); - ImGui::TextWrapped("%s", message); - ImGui::GetCurrentWindow()->DC.CursorPos.y += LayoutScale(5.0f); - - BeginMenuButtons(); - - bool done = false; - - if (ActiveButton(FSUI_ICONSTR(ICON_FA_CHECK, "Yes"), false)) - { - *result = true; - done = true; - } - - if (ActiveButton(FSUI_ICONSTR(ICON_FA_TIMES, "No"), false)) - { - *result = false; - done = true; - } - if (done) - { - ImGui::CloseCurrentPopup(); - is_open = false; - } - - EndMenuButtons(); - - ImGui::EndPopup(); - } - - ImGui::PopStyleVar(2); - ImGui::PopFont(); - - ImGuiFullscreen::EndLayout(); - return !is_open; -} - void FullscreenUI::OpenAchievementsWindow() { if (!Achievements::IsActive()) diff --git a/src/core/fullscreen_ui.h b/src/core/fullscreen_ui.h index 56e882a45..40afc70cf 100644 --- a/src/core/fullscreen_ui.h +++ b/src/core/fullscreen_ui.h @@ -1,11 +1,15 @@ -// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin +// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) #pragma once + #include "common/progress_callback.h" #include "common/types.h" + +#include #include #include +#include class SmallStringBase; @@ -37,10 +41,6 @@ void Render(); void InvalidateCoverCache(); void TimeToPrintableString(SmallStringBase* str, time_t t); -// Returns true if the message has been dismissed. -bool DrawErrorWindow(const char* message); -bool DrawConfirmWindow(const char* message, bool* result); - class ProgressCallback final : public BaseProgressCallback { public: diff --git a/src/core/system.cpp b/src/core/system.cpp index f5b64e2cb..36dffe258 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -1133,9 +1133,13 @@ bool System::LoadState(const char* filename) if (!IsValid()) return false; - if (Achievements::IsHardcoreModeActive() && - !Achievements::ConfirmHardcoreModeDisable(TRANSLATE("Achievements", "Loading state"))) + if (Achievements::IsHardcoreModeActive()) { + Achievements::ConfirmHardcoreModeDisableAsync(TRANSLATE("Achievements", "Loading state"), + [filename = std::string(filename)](bool approved) { + if (approved) + LoadState(filename.c_str()); + }); return false; } @@ -2699,8 +2703,14 @@ void System::SetRewindState(bool enabled) return; } - if (Achievements::IsHardcoreModeActive() && !Achievements::ConfirmHardcoreModeDisable("Rewinding")) + if (Achievements::IsHardcoreModeActive() && enabled) + { + Achievements::ConfirmHardcoreModeDisableAsync("Rewinding", [](bool approved) { + if (approved) + SetRewindState(true); + }); return; + } System::SetRewinding(enabled); UpdateSpeedLimiterState(); @@ -2711,8 +2721,14 @@ void System::DoFrameStep() if (!IsValid()) return; - if (Achievements::IsHardcoreModeActive() && !Achievements::ConfirmHardcoreModeDisable("Frame stepping")) + if (Achievements::IsHardcoreModeActive()) + { + Achievements::ConfirmHardcoreModeDisableAsync("Frame stepping", [](bool approved) { + if (approved) + DoFrameStep(); + }); return; + } s_frame_step_request = true; PauseSystem(false); @@ -2723,8 +2739,11 @@ void System::DoToggleCheats() if (!System::IsValid()) return; - if (Achievements::IsHardcoreModeActive() && !Achievements::ConfirmHardcoreModeDisable("Toggling cheats")) + if (Achievements::IsHardcoreModeActive()) + { + Achievements::ConfirmHardcoreModeDisableAsync("Toggling cheats", [](bool approved) { DoToggleCheats(); }); return; + } CheatList* cl = GetCheatList(); if (!cl) diff --git a/src/util/imgui_fullscreen.h b/src/util/imgui_fullscreen.h index bcd1dc42d..0a6843cb1 100644 --- a/src/util/imgui_fullscreen.h +++ b/src/util/imgui_fullscreen.h @@ -1,11 +1,14 @@ -// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin +// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) #pragma once -#include "IconsFontAwesome5.h" + #include "common/types.h" + +#include "IconsFontAwesome5.h" #include "imgui.h" #include "imgui_internal.h" + #include #include #include