Savestates/rsx/IO: Resume emulation on long START press, enable "Start Paused" by defaut (#12881)

* Savestates: Enable "Start Paused" by default
* Emu/rsx/IO: Resume emulation on long START press
* rsx: fix missing graphics with savestates' "Start Paused" setting
* rsx/overlays: Add simple reference counting for messages to hide them manually
* Move some code in Emulator::Pause() so thread pausing is the first thing done by this function
This commit is contained in:
Elad Ashkenazi 2022-10-29 20:53:00 +03:00 committed by GitHub
parent c8620070b9
commit c214f45e14
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 206 additions and 42 deletions

View file

@ -26,6 +26,7 @@
#include "Emu/title.h"
#include "Emu/IdManager.h"
#include "Emu/RSX/Capture/rsx_replay.h"
#include "Emu/RSX/Overlays/overlay_message.h"
#include "Loader/PSF.h"
#include "Loader/TAR.h"
@ -101,6 +102,11 @@ namespace atomic_wait
extern void parse_hashtable(bool(*cb)(u64 id, u32 refs, u64 ptr, u32 max_coll));
}
namespace rsx
{
void set_native_ui_flip();
}
template<>
void fmt_class_string<game_boot_result>::format(std::string& out, u64 arg)
{
@ -2050,8 +2056,53 @@ bool Emulator::Pause(bool freeze_emulation)
// Signal profilers to print results (if enabled)
cpu_thread::flush_profilers();
auto on_select = [](u32, cpu_thread& cpu)
{
cpu.state += cpu_flag::dbg_global_pause;
};
idm::select<named_thread<ppu_thread>>(on_select);
idm::select<named_thread<spu_thread>>(on_select);
if (auto rsx = g_fxo->try_get<rsx::thread>())
{
rsx->state += cpu_flag::dbg_global_pause;
}
GetCallbacks().on_pause();
BlockingCallFromMainThread([this]()
{
if (IsStopped())
{
return;
}
auto msg_ref = std::make_shared<atomic_t<u32>>(1);
// No timeout
rsx::overlays::queue_message(localized_string_id::EMULATION_PAUSED_RESUME_WITH_START, -1, msg_ref);
m_pause_msgs_refs.emplace_back(msg_ref);
auto refresh_l = [this, msg_ref]()
{
while (*msg_ref && IsPaused())
{
// Refresh Native UI
rsx::set_native_ui_flip();
thread_ctrl::wait_for(33'000);
}
};
struct thread_t
{
std::unique_ptr<named_thread<decltype(refresh_l)>> m_thread;
};
g_fxo->get<thread_t>().m_thread.reset();
g_fxo->get<thread_t>().m_thread = std::make_unique<named_thread<decltype(refresh_l)>>("Pause Message Thread"sv, std::move(refresh_l));
});
static atomic_t<u32> pause_mark = 0;
if (freeze_emulation)
@ -2069,19 +2120,6 @@ bool Emulator::Pause(bool freeze_emulation)
sys_log.error("Emulator::Pause() error: concurrent access");
}
auto on_select = [](u32, cpu_thread& cpu)
{
cpu.state += cpu_flag::dbg_global_pause;
};
idm::select<named_thread<ppu_thread>>(on_select);
idm::select<named_thread<spu_thread>>(on_select);
if (auto rsx = g_fxo->try_get<rsx::thread>())
{
rsx->state += cpu_flag::dbg_global_pause;
}
// Always Enable display sleep, not only if it was prevented.
enable_display_sleep();
@ -2167,6 +2205,17 @@ void Emulator::Resume()
sys_log.success("Emulation has been resumed!");
BlockingCallFromMainThread([this]()
{
for (auto& ref : m_pause_msgs_refs)
{
// Delete the message queued on pause
*ref = 0;
}
m_pause_msgs_refs.clear();
});
if (g_cfg.misc.prevent_display_sleep)
{
disable_display_sleep();