UI: Keep emulation paused when using reset/power cycle, prevent game from running when debugger is opened while paused

This commit is contained in:
Sour 2022-05-29 12:17:51 -04:00
parent 6e9d711794
commit eb80802d3a
12 changed files with 58 additions and 10 deletions

View file

@ -102,6 +102,11 @@ Debugger::Debugger(Emulator* emu, IConsole* console)
RefreshCodeCache();
if(_emu->IsPaused()) {
//Break on the current instruction if emulation was already paused
Step(_mainCpuType, 1, StepType::Step);
}
_executionStopped = false;
#ifdef _DEBUG

View file

@ -33,6 +33,8 @@ void PceConsole::Stop()
void PceConsole::Reset()
{
//The PC Engine has no reset button, behave like power cycle
_emu->ReloadRom(true);
}
void PceConsole::OnBeforeRun()

View file

@ -313,6 +313,8 @@ void Emulator::Reset()
_console->Reset();
GetControlManager()->UpdateInputState();
_videoRenderer->ClearFrame();
_notificationManager->SendNotification(ConsoleNotificationType::GameReset);
ProcessEvent(EventType::Reset);
@ -473,7 +475,6 @@ bool Emulator::LoadRom(VirtualFile romFile, VirtualFile patchFile, bool stopRom,
_threadPaused = true;
_notificationManager->SendNotification(ConsoleNotificationType::GameLoaded, (void*)forPowerCycle);
_threadPaused = false;
_paused = false;
if(!forPowerCycle && !_audioPlayerHud) {
string modelName = _console->GetRegion() == ConsoleRegion::Pal ? "PAL" : "NTSC";
@ -671,9 +672,15 @@ void Emulator::WaitForPauseEnd()
PlatformUtilities::EnableScreensaver();
PlatformUtilities::RestoreTimerResolution();
while(_paused && !_stopFlag && !_debugger) {
//Sleep until emulation is resumed
std::this_thread::sleep_for(std::chrono::duration<int, std::milli>(30));
if(_systemActionManager->IsResetPending()) {
//Reset/power cycle was pressed, stop waiting and process it now
break;
}
}
PlatformUtilities::DisableScreensaver();

View file

@ -10,6 +10,7 @@ class IRenderingDevice
public:
virtual ~IRenderingDevice() {}
virtual void UpdateFrame(RenderedFrame& frame) = 0;
virtual void ClearFrame() = 0;
virtual void Render(uint32_t* hudBuffer, uint32_t width, uint32_t height) = 0;
virtual void Reset() = 0;
virtual void SetFullscreenMode(bool fullscreen, void* windowHandle, uint32_t monitorWidth, uint32_t monitorHeight) = 0;

View file

@ -63,6 +63,11 @@ public:
return false;
}
bool IsResetPending()
{
return _needReset || _needPowerCycle;
}
bool IsResetPressed()
{
return IsPressed(SystemActionManager::Buttons::ResetButton);

View file

@ -210,6 +210,8 @@ void VideoDecoder::StartThread()
_frameCount = 0;
_waitForFrame.Reset();
_emu->GetVideoRenderer()->ClearFrame();
_decodeThread.reset(new thread(&VideoDecoder::DecodeThread, this));
}
#endif
@ -227,13 +229,7 @@ void VideoDecoder::StopThread()
_decodeThread.reset();
//Clear whole screen
if(_frameCount > 0) {
vector<uint16_t> outputBuffer(512 * 478, 0);
_frame.FrameBuffer = outputBuffer.data();
memset(_frame.FrameBuffer, 0, 512 * 478 * 2);
DecodeFrame();
_frame.FrameBuffer = nullptr;
}
_emu->GetVideoRenderer()->ClearFrame();
}
#endif
}

View file

@ -123,6 +123,13 @@ void VideoRenderer::UpdateFrame(RenderedFrame& frame)
}
}
void VideoRenderer::ClearFrame()
{
if(_renderer) {
_renderer->ClearFrame();
}
}
void VideoRenderer::RegisterRenderingDevice(IRenderingDevice *renderer)
{
_renderer = renderer;

View file

@ -53,6 +53,7 @@ public:
void StopThread();
void UpdateFrame(RenderedFrame& frame);
void ClearFrame();
void RegisterRenderingDevice(IRenderingDevice *renderer);
void UnregisterRenderingDevice(IRenderingDevice *renderer);

View file

@ -129,9 +129,20 @@ void SdlRenderer::SetScreenSize(uint32_t width, uint32_t height)
}
}
void SdlRenderer::ClearFrame()
{
auto lock = _frameLock.AcquireSafe();
if(_frameBuffer == nullptr) {
return;
}
memset(_frameBuffer, 0, _requiredWidth * _requiredHeight * _bytesPerPixel);
_frameChanged = true;
}
void SdlRenderer::UpdateFrame(RenderedFrame& frame)
{
_frameLock.Acquire();
auto lock = _frameLock.AcquireSafe();
if(_frameBuffer == nullptr || _requiredWidth != frame.Width || _requiredHeight != frame.Height) {
_requiredWidth = frame.Width;
_requiredHeight = frame.Height;
@ -143,7 +154,6 @@ void SdlRenderer::UpdateFrame(RenderedFrame& frame)
memcpy(_frameBuffer, frame.FrameBuffer, frame.Width * frame.Height *_bytesPerPixel);
_frameChanged = true;
_frameLock.Release();
}
void SdlRenderer::Render(uint32_t* hudBuffer, uint32_t width, uint32_t height)

View file

@ -48,6 +48,7 @@ public:
SdlRenderer(Emulator* emu, void* windowHandle, bool registerAsMessageManager);
virtual ~SdlRenderer();
void ClearFrame() override;
void UpdateFrame(RenderedFrame& frame) override;
void Render(uint32_t* hudBuffer, uint32_t width, uint32_t height) override;
void Reset() override;

View file

@ -357,6 +357,18 @@ ID3D11ShaderResourceView* Renderer::GetShaderResourceView(ID3D11Texture2D* textu
return shaderResourceView;
}
void Renderer::ClearFrame()
{
//Clear current output and display black frame
auto lock = _textureLock.AcquireSafe();
if(_textureBuffer[0]) {
//_textureBuffer[0] may be null if directx failed to initialize properly
memset(_textureBuffer[0], 0, _emuFrameWidth * _emuFrameHeight * sizeof(uint32_t));
_needFlip = true;
_frameChanged = true;
}
}
void Renderer::UpdateFrame(RenderedFrame& frame)
{
SetScreenSize(frame.Width, frame.Height);

View file

@ -83,6 +83,7 @@ public:
void Reset();
void Render(uint32_t* hudBuffer, uint32_t hudWidth, uint32_t hudHeight);
void ClearFrame();
void UpdateFrame(RenderedFrame& frame);
};