Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Achievements: Use big picture to confirm HC mode disable #10323

Merged
merged 2 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 24 additions & 38 deletions pcsx2-qt/QtHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -391,48 +391,14 @@ void EmuThread::run()

// Main CPU thread loop.
while (!m_shutdown_flag.load())
{
if (!VMManager::HasValidVM())
{
m_event_loop->exec();
continue;
}

executeVM();
}

// Teardown in reverse order.
stopBackgroundControllerPollTimer();
destroyBackgroundControllerPollTimer();
VMManager::Internal::CPUThreadShutdown();

// Move back to the UI thread, since we're no longer running.
moveToThread(m_ui_thread);
deleteLater();
}

void EmuThread::destroyVM()
{
m_last_speed = 0.0f;
m_last_game_fps = 0.0f;
m_last_video_fps = 0.0f;
m_last_internal_width = 0;
m_last_internal_height = 0;
m_was_paused_by_focus_loss = false;
VMManager::Shutdown(m_save_state_on_shutdown);
m_save_state_on_shutdown = false;
}

void EmuThread::executeVM()
{
for (;;)
{
switch (VMManager::GetState())
{
case VMState::Initializing:
pxFailRel("Shouldn't be in the starting state state");
pxFailRel("Shouldn't be in the starting state");
continue;

case VMState::Shutdown:
case VMState::Paused:
m_event_loop->exec();
continue;
Expand All @@ -448,13 +414,33 @@ void EmuThread::executeVM()

case VMState::Stopping:
destroyVM();
m_event_loop->processEvents(QEventLoop::AllEvents);
return;
continue;

default:
continue;
}
}

// Teardown in reverse order.
stopBackgroundControllerPollTimer();
destroyBackgroundControllerPollTimer();
VMManager::Internal::CPUThreadShutdown();

// Move back to the UI thread, since we're no longer running.
moveToThread(m_ui_thread);
deleteLater();
}

void EmuThread::destroyVM()
{
m_last_speed = 0.0f;
m_last_game_fps = 0.0f;
m_last_video_fps = 0.0f;
m_last_internal_width = 0;
m_last_internal_height = 0;
m_was_paused_by_focus_loss = false;
VMManager::Shutdown(m_save_state_on_shutdown);
m_save_state_on_shutdown = false;
}

void EmuThread::createBackgroundControllerPollTimer()
Expand Down
1 change: 0 additions & 1 deletion pcsx2-qt/QtHost.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,6 @@ public Q_SLOTS:
static constexpr u32 FULLSCREEN_UI_CONTROLLER_POLLING_INTERVAL = 8;

void destroyVM();
void executeVM();

void createBackgroundControllerPollTimer();
void destroyBackgroundControllerPollTimer();
Expand Down
37 changes: 37 additions & 0 deletions pcsx2/Achievements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1825,6 +1825,43 @@ bool Achievements::ConfirmHardcoreModeDisable(const char* trigger)
return true;
}

void Achievements::ConfirmHardcoreModeDisableAsync(const char* trigger, std::function<void(bool)> 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()
{
if (FullscreenUI::IsAchievementsWindowOpen() || FullscreenUI::IsLeaderboardsWindowOpen())
Expand Down
2 changes: 2 additions & 0 deletions pcsx2/Achievements.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include "Config.h"

#include <functional>
#include <mutex>
#include <string>
#include <utility>
Expand Down Expand Up @@ -83,6 +84,7 @@ namespace Achievements

/// Prompts the user to disable hardcore mode, if they agree, returns true.
bool ConfirmHardcoreModeDisable(const char* trigger);
void ConfirmHardcoreModeDisableAsync(const char* trigger, std::function<void(bool)> callback);

/// Returns true if hardcore mode is active, and functionality should be restricted.
bool IsHardcoreModeActive();
Expand Down
35 changes: 31 additions & 4 deletions pcsx2/Hotkeys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "common/Assertions.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/Timer.h"

static s32 s_current_save_slot = 1;
static std::optional<LimiterModeType> s_limiter_mode_prior_to_hold_interaction;
Expand Down Expand Up @@ -141,25 +142,51 @@ static void HotkeySaveStateSlot(s32 slot)
VMManager::SaveStateToSlot(slot);
}

static bool CanPause()
{
static constexpr const float PAUSE_INTERVAL = 3.0f;
static Common::Timer::Value s_last_pause_time = 0;

if (!Achievements::IsHardcoreModeActive() || VMManager::GetState() == VMState::Paused)
return true;

const Common::Timer::Value time = Common::Timer::GetCurrentValue();
const float delta = static_cast<float>(Common::Timer::ConvertValueToSeconds(time - s_last_pause_time));
if (delta < PAUSE_INTERVAL)
{
Host::AddIconOSDMessage(
"PauseCooldown", ICON_FA_CLOCK,
fmt::format(TRANSLATE_FS("Hotkeys", "You cannot pause until another {:.1f} seconds have passed."),
PAUSE_INTERVAL - delta),
Host::OSD_QUICK_DURATION);
return false;
}

Host::RemoveKeyedOSDMessage("PauseCooldown");
s_last_pause_time = time;

return true;
}

BEGIN_HOTKEY_LIST(g_common_hotkeys)
DEFINE_HOTKEY("OpenPauseMenu", TRANSLATE_NOOP("Hotkeys", "System"), TRANSLATE_NOOP("Hotkeys", "Open Pause Menu"),
[](s32 pressed) {
if (!pressed && VMManager::HasValidVM())
if (!pressed && VMManager::HasValidVM() && CanPause())
FullscreenUI::OpenPauseMenu();
})
DEFINE_HOTKEY("OpenAchievementsList", TRANSLATE_NOOP("Hotkeys", "System"),
TRANSLATE_NOOP("Hotkeys", "Open Achievements List"), [](s32 pressed) {
if (!pressed)
if (!pressed && CanPause())
FullscreenUI::OpenAchievementsWindow();
})
DEFINE_HOTKEY("OpenLeaderboardsList", TRANSLATE_NOOP("Hotkeys", "System"),
TRANSLATE_NOOP("Hotkeys", "Open Leaderboards List"), [](s32 pressed) {
if (!pressed)
if (!pressed && CanPause())
FullscreenUI::OpenLeaderboardsWindow();
})
DEFINE_HOTKEY(
"TogglePause", TRANSLATE_NOOP("Hotkeys", "System"), TRANSLATE_NOOP("Hotkeys", "Toggle Pause"), [](s32 pressed) {
if (!pressed && VMManager::HasValidVM())
if (!pressed && VMManager::HasValidVM() && CanPause())
VMManager::SetPaused(VMManager::GetState() != VMState::Paused);
})
DEFINE_HOTKEY("ToggleFullscreen", TRANSLATE_NOOP("Hotkeys", "System"), TRANSLATE_NOOP("Hotkeys", "Toggle Fullscreen"),
Expand Down
19 changes: 13 additions & 6 deletions pcsx2/ImGui/FullscreenUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -855,17 +855,12 @@ void FullscreenUI::DoStartPath(const std::string& path, std::optional<s32> state
params.fast_boot = fast_boot;

// switch to nothing, we'll get brought back if init fails
const MainWindowType prev_window = s_current_main_window;
s_current_main_window = MainWindowType::None;

Host::RunOnCPUThread([params = std::move(params), prev_window]() {
Host::RunOnCPUThread([params = std::move(params)]() {
if (VMManager::HasValidVM())
return;

if (VMManager::Initialize(std::move(params)))
VMManager::SetState(VMState::Running);
else
s_current_main_window = prev_window;
});
}

Expand Down Expand Up @@ -5514,6 +5509,18 @@ void FullscreenUI::DrawGameListWindow()
default:
break;
}

if (VMManager::GetState() != VMState::Shutdown)
{
// Dummy window to prevent interacting with the game list while loading.
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(1.0f, 1.0f, 1.0f, 1.0f));
ImGui::SetNextWindowSize(ImGui::GetIO().DisplaySize);
ImGui::SetNextWindowPos(ImVec2(0, 0));
ImGui::SetNextWindowBgAlpha(0.25f);
ImGui::Begin("##dummy", nullptr, ImGuiWindowFlags_NoDecoration);
ImGui::End();
ImGui::PopStyleColor();
}
}

void FullscreenUI::DrawGameList(const ImVec2& heading_size)
Expand Down
Loading