mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-04 05:51:27 +12:00
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:
parent
c8620070b9
commit
c214f45e14
13 changed files with 206 additions and 42 deletions
|
@ -16,10 +16,12 @@
|
|||
#include "Emu/Io/pad_config.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Emu/system_config.h"
|
||||
#include "Emu/RSX/Overlays/overlay_message.h"
|
||||
#include "Utilities/Thread.h"
|
||||
#include "util/atomic.hpp"
|
||||
|
||||
LOG_CHANNEL(input_log, "Input");
|
||||
LOG_CHANNEL(sys_log, "SYS");
|
||||
|
||||
extern bool is_input_allowed();
|
||||
|
||||
|
@ -33,6 +35,11 @@ namespace pad
|
|||
atomic_t<bool> g_enabled{true};
|
||||
}
|
||||
|
||||
namespace rsx
|
||||
{
|
||||
void set_native_ui_flip();
|
||||
}
|
||||
|
||||
struct pad_setting
|
||||
{
|
||||
u32 port_status = 0;
|
||||
|
@ -272,15 +279,22 @@ void pad_thread::operator()()
|
|||
{
|
||||
while (thread_ctrl::state() != thread_state::aborting)
|
||||
{
|
||||
if (!pad::g_enabled || Emu.IsPaused() || !is_input_allowed())
|
||||
if (!pad::g_enabled || !is_input_allowed())
|
||||
{
|
||||
thread_ctrl::wait_for(10'000);
|
||||
thread_ctrl::wait_for(30'000);
|
||||
continue;
|
||||
}
|
||||
|
||||
handler->process();
|
||||
|
||||
thread_ctrl::wait_for(g_cfg.io.pad_sleep);
|
||||
u64 pad_sleep = g_cfg.io.pad_sleep;
|
||||
|
||||
if (Emu.IsPaused())
|
||||
{
|
||||
pad_sleep = std::max<u64>(pad_sleep, 30'000);
|
||||
}
|
||||
|
||||
thread_ctrl::wait_for(pad_sleep);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
@ -290,9 +304,11 @@ void pad_thread::operator()()
|
|||
|
||||
while (thread_ctrl::state() != thread_state::aborting)
|
||||
{
|
||||
if (!pad::g_enabled || Emu.IsPaused() || !is_input_allowed())
|
||||
if (!pad::g_enabled || !is_input_allowed())
|
||||
{
|
||||
thread_ctrl::wait_for(10000);
|
||||
m_resume_emulation_flag = false;
|
||||
m_mask_start_press_to_unpause = 0;
|
||||
thread_ctrl::wait_for(30'000);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -353,7 +369,7 @@ void pad_thread::operator()()
|
|||
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
|
||||
continue;
|
||||
|
||||
for (auto& button : pad->m_buttons)
|
||||
for (const auto& button : pad->m_buttons)
|
||||
{
|
||||
if (button.m_pressed && (
|
||||
button.m_outKeyCode == CELL_PAD_CTRL_CROSS ||
|
||||
|
@ -375,7 +391,81 @@ void pad_thread::operator()()
|
|||
}
|
||||
}
|
||||
|
||||
thread_ctrl::wait_for(g_cfg.io.pad_sleep);
|
||||
if (m_resume_emulation_flag)
|
||||
{
|
||||
m_resume_emulation_flag = false;
|
||||
|
||||
Emu.BlockingCallFromMainThread([]()
|
||||
{
|
||||
Emu.Resume();
|
||||
});
|
||||
}
|
||||
|
||||
u64 pad_sleep = g_cfg.io.pad_sleep;
|
||||
|
||||
if (Emu.IsPaused())
|
||||
{
|
||||
pad_sleep = std::max<u64>(pad_sleep, 30'000);
|
||||
|
||||
u64 timestamp = get_system_time();
|
||||
u32 pressed_mask = 0;
|
||||
|
||||
for (usz i = 0; i < m_pads.size(); i++)
|
||||
{
|
||||
const auto& pad = m_pads[i];
|
||||
|
||||
if (!(pad->m_port_status & CELL_PAD_STATUS_CONNECTED))
|
||||
continue;
|
||||
|
||||
for (const auto& button : pad->m_buttons)
|
||||
{
|
||||
if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL1 && button.m_outKeyCode == CELL_PAD_CTRL_START && button.m_pressed)
|
||||
{
|
||||
pressed_mask |= 1u << i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_mask_start_press_to_unpause &= pressed_mask;
|
||||
|
||||
if (!pressed_mask || timestamp - m_track_start_press_begin_timestamp >= 1'000'000)
|
||||
{
|
||||
m_track_start_press_begin_timestamp = timestamp;
|
||||
|
||||
if (std::exchange(m_mask_start_press_to_unpause, u32{umax}))
|
||||
{
|
||||
m_mask_start_press_to_unpause = 0;
|
||||
m_track_start_press_begin_timestamp = 0;
|
||||
|
||||
sys_log.success("Unpausing emulation using the START button in a few seconds...");
|
||||
rsx::overlays::queue_message(localized_string_id::EMULATION_RESUMING, 2'000'000);
|
||||
|
||||
m_resume_emulation_flag = true;
|
||||
|
||||
for (u32 i = 0; i < 40; i++)
|
||||
{
|
||||
if (!Emu.IsPaused())
|
||||
{
|
||||
// Abort if emulation has been resumed by other means
|
||||
m_resume_emulation_flag = false;
|
||||
break;
|
||||
}
|
||||
|
||||
thread_ctrl::wait_for(50'000);
|
||||
rsx::set_native_ui_flip();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reset unpause control if caught a state of unpaused emulation
|
||||
m_mask_start_press_to_unpause = 0;
|
||||
m_track_start_press_begin_timestamp = 0;
|
||||
}
|
||||
|
||||
thread_ctrl::wait_for(pad_sleep);
|
||||
}
|
||||
|
||||
stop_threads();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue