Shortcuts: Allow "Run Single Frame" to auto-repeat after being held for over half a second

This commit is contained in:
Sour 2019-01-13 14:10:46 -05:00
parent e090f01642
commit 8027cd0c26
4 changed files with 69 additions and 30 deletions

View file

@ -785,7 +785,13 @@ void Console::Run()
_runLock.Acquire();
}
if(_pauseOnNextFrameRequested) {
//Used by "Run Single Frame" option
_settings->SetFlags(EmulationFlags::Paused);
_pauseOnNextFrameRequested = false;
}
bool pausedRequired = _settings->NeedsPause();
if(pausedRequired && !_stop && !_settings->CheckFlag(EmulationFlags::DebuggerWindowEnabled)) {
_notificationManager->SendNotification(ConsoleNotificationType::GamePaused);
@ -914,6 +920,11 @@ bool Console::IsPaused()
}
}
void Console::PauseOnNextFrame()
{
_pauseOnNextFrameRequested = true;
}
void Console::UpdateNesModel(bool sendNotification)
{
bool configChanged = false;

View file

@ -90,6 +90,7 @@ private:
bool _running = false;
int32_t _stopCode = 0;
bool _pauseOnNextFrameRequested = false;
bool _resetRunTimers = false;
bool _disableOcNextFrame = false;
@ -206,6 +207,7 @@ public:
bool IsExecutionStopped();
bool IsPaused();
void PauseOnNextFrame();
void SetNextFrameOverclockStatus(bool disabled);

View file

@ -20,6 +20,7 @@ ShortcutKeyHandler::ShortcutKeyHandler(shared_ptr<Console> console)
_keySetIndex = 0;
_isKeyUp = false;
_keyboardMode = false;
_repeatStarted = false;
_stopThread = false;
_thread = std::thread([=]() {
@ -96,6 +97,25 @@ bool ShortcutKeyHandler::DetectKeyRelease(EmulatorShortcut shortcut)
return false;
}
void ShortcutKeyHandler::ProcessRunSingleFrame()
{
EmulationSettings* settings = _console->GetSettings();
if(!_runSingleFrameRepeatTimer) {
_runSingleFrameRepeatTimer.reset(new Timer());
}
_runSingleFrameRepeatTimer->Reset();
if(settings->CheckFlag(EmulationFlags::DebuggerWindowEnabled)) {
shared_ptr<Debugger> debugger = _console->GetDebugger(false);
if(debugger) {
debugger->BreakOnScanline(241);
}
} else {
_console->PauseOnNextFrame();
settings->ClearFlags(EmulationFlags::Paused);
}
}
void ShortcutKeyHandler::CheckMappedKeys()
{
EmulationSettings* settings = _console->GetSettings();
@ -185,22 +205,12 @@ void ShortcutKeyHandler::CheckMappedKeys()
}
if(DetectKeyPress(EmulatorShortcut::RunSingleFrame)) {
if(settings->CheckFlag(EmulationFlags::DebuggerWindowEnabled)) {
shared_ptr<Debugger> debugger = _console->GetDebugger(false);
if(debugger) {
debugger->BreakOnScanline(241);
}
} else {
if(settings->CheckFlag(EmulationFlags::Paused)) {
settings->ClearFlags(EmulationFlags::Paused);
_console->Pause();
std::this_thread::sleep_for(std::chrono::duration<int, std::milli>(50));
settings->SetFlags(EmulationFlags::Paused);
_console->Resume();
} else {
settings->SetFlags(EmulationFlags::Paused);
}
}
ProcessRunSingleFrame();
}
if(DetectKeyRelease(EmulatorShortcut::RunSingleFrame)) {
_runSingleFrameRepeatTimer.reset();
_repeatStarted = false;
}
if(!isNetplayClient && !MovieManager::Recording()) {
@ -239,26 +249,36 @@ void ShortcutKeyHandler::ProcessKeys()
_pressedKeys = KeyManager::GetPressedKeys();
_isKeyUp = _pressedKeys.size() < _lastPressedKeys.size();
bool noChange = false;
if(_pressedKeys.size() == _lastPressedKeys.size()) {
bool noChange = true;
noChange = true;
for(size_t i = 0; i < _pressedKeys.size(); i++) {
if(_pressedKeys[i] != _lastPressedKeys[i]) {
noChange = false;
break;
}
}
if(noChange) {
//Same keys as before, nothing to do
return;
}
if(!noChange) {
//Only run this if the keys have changed
for(int i = 0; i < 2; i++) {
_keysDown[i].clear();
_keySetIndex = i;
CheckMappedKeys();
_prevKeysDown[i] = _keysDown[i];
}
_lastPressedKeys = _pressedKeys;
}
if(_runSingleFrameRepeatTimer) {
double elapsedMs = _runSingleFrameRepeatTimer->GetElapsedMS();
if(_repeatStarted && elapsedMs >= 50 || !_repeatStarted && elapsedMs >= 500) {
//Over 500ms has elapsed since the key was first pressed, or over 50ms since repeat mode started (20fps)
//In this case, run another frame and pause again.
_repeatStarted = true;
ProcessRunSingleFrame();
}
}
for(int i = 0; i < 2; i++) {
_keysDown[i].clear();
_keySetIndex = i;
CheckMappedKeys();
_prevKeysDown[i] = _keysDown[i];
}
_lastPressedKeys = _pressedKeys;
}

View file

@ -3,6 +3,7 @@
#include <thread>
#include <unordered_set>
#include "../Utilities/SimpleLock.h"
#include "../Utilities/Timer.h"
#include "EmulationSettings.h"
class Console;
@ -22,6 +23,9 @@ private:
bool _isKeyUp;
bool _keyboardMode;
shared_ptr<Timer> _runSingleFrameRepeatTimer;
bool _repeatStarted;
std::unordered_set<uint32_t> _keysDown[2];
std::unordered_set<uint32_t> _prevKeysDown[2];
@ -34,6 +38,8 @@ private:
bool DetectKeyPress(EmulatorShortcut key);
bool DetectKeyRelease(EmulatorShortcut key);
void ProcessRunSingleFrame();
public:
ShortcutKeyHandler(shared_ptr<Console> console);
~ShortcutKeyHandler();