Added pause/resume functionality
This commit is contained in:
parent
20aee963c9
commit
99e2e1bf0b
7 changed files with 101 additions and 68 deletions
|
@ -96,6 +96,13 @@ void Console::Run()
|
|||
|
||||
WaitForLock();
|
||||
|
||||
if(_paused && !_stopFlag && !_debugger) {
|
||||
WaitForPauseEnd();
|
||||
if(_stopFlag) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
frameLimiter.ProcessFrame();
|
||||
frameLimiter.WaitForNextFrame();
|
||||
|
||||
|
@ -189,6 +196,7 @@ void Console::LoadRom(VirtualFile romFile, VirtualFile patchFile)
|
|||
//GetDebugger();
|
||||
//}
|
||||
|
||||
_paused = false;
|
||||
_notificationManager->SendNotification(ConsoleNotificationType::GameLoaded);
|
||||
}
|
||||
}
|
||||
|
@ -215,6 +223,56 @@ double Console::GetFrameDelay()
|
|||
return frameDelay;
|
||||
}
|
||||
|
||||
void Console::Pause()
|
||||
{
|
||||
shared_ptr<Debugger> debugger = _debugger;
|
||||
if(debugger) {
|
||||
debugger->Step(1);
|
||||
} else {
|
||||
_paused = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Console::Resume()
|
||||
{
|
||||
shared_ptr<Debugger> debugger = _debugger;
|
||||
if(debugger) {
|
||||
debugger->Run();
|
||||
} else {
|
||||
_paused = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Console::IsPaused()
|
||||
{
|
||||
shared_ptr<Debugger> debugger = _debugger;
|
||||
if(debugger) {
|
||||
return debugger->IsExecutionStopped();
|
||||
} else {
|
||||
return _paused;
|
||||
}
|
||||
}
|
||||
|
||||
void Console::WaitForPauseEnd()
|
||||
{
|
||||
_notificationManager->SendNotification(ConsoleNotificationType::GamePaused);
|
||||
|
||||
//Prevent audio from looping endlessly while game is paused
|
||||
_soundMixer->StopAudio();
|
||||
_runLock.Release();
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
PlatformUtilities::DisableScreensaver();
|
||||
_runLock.Acquire();
|
||||
_notificationManager->SendNotification(ConsoleNotificationType::GameResumed);
|
||||
}
|
||||
|
||||
ConsoleLock Console::AcquireLock()
|
||||
{
|
||||
return ConsoleLock(this);
|
||||
|
|
|
@ -56,9 +56,11 @@ private:
|
|||
|
||||
SimpleLock _debuggerLock;
|
||||
atomic<bool> _stopFlag;
|
||||
atomic<bool> _paused;
|
||||
|
||||
double GetFrameDelay();
|
||||
void WaitForLock();
|
||||
void WaitForPauseEnd();
|
||||
|
||||
public:
|
||||
~Console();
|
||||
|
@ -69,6 +71,10 @@ public:
|
|||
void Run();
|
||||
void Stop();
|
||||
|
||||
void Pause();
|
||||
void Resume();
|
||||
bool IsPaused();
|
||||
|
||||
void LoadRom(VirtualFile romFile, VirtualFile patchFile);
|
||||
RomInfo GetRomInfo();
|
||||
|
||||
|
|
|
@ -109,18 +109,29 @@ extern "C" {
|
|||
|
||||
DllExport void __stdcall Run()
|
||||
{
|
||||
if(_console) {
|
||||
_console->Run();
|
||||
}
|
||||
_console->Run();
|
||||
}
|
||||
|
||||
DllExport void __stdcall Stop()
|
||||
{
|
||||
if(_console) {
|
||||
_console->Stop();
|
||||
}
|
||||
_console->Stop();
|
||||
}
|
||||
|
||||
|
||||
DllExport void __stdcall Pause()
|
||||
{
|
||||
_console->Pause();
|
||||
}
|
||||
|
||||
DllExport void __stdcall Resume()
|
||||
{
|
||||
_console->Resume();
|
||||
}
|
||||
|
||||
DllExport void __stdcall IsPaused()
|
||||
{
|
||||
_console->IsPaused();
|
||||
}
|
||||
|
||||
DllExport void __stdcall Release()
|
||||
{
|
||||
_console->Stop();
|
||||
|
|
|
@ -64,7 +64,7 @@ namespace Mesen.GUI.Emulation
|
|||
//TODO bool restoreFullscreen = _frmFullscreenRenderer != null;
|
||||
|
||||
switch(shortcut) {
|
||||
case EmulatorShortcut.Pause: PauseEmu(); break;
|
||||
case EmulatorShortcut.Pause: TogglePause(); break;
|
||||
case EmulatorShortcut.Reset: ResetEmu(); break;
|
||||
case EmulatorShortcut.PowerCycle: PowerCycleEmu(); break;
|
||||
case EmulatorShortcut.PowerOff: Task.Run(() => EmuApi.Stop()); break;
|
||||
|
@ -264,9 +264,13 @@ namespace Mesen.GUI.Emulation
|
|||
ConfigManager.ApplyChanges();
|
||||
}
|
||||
|
||||
private void PauseEmu()
|
||||
private void TogglePause()
|
||||
{
|
||||
//TODO
|
||||
if(EmuApi.IsPaused()) {
|
||||
EmuApi.Resume();
|
||||
} else {
|
||||
EmuApi.Pause();
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetEmu()
|
||||
|
|
|
@ -29,6 +29,10 @@ namespace Mesen.GUI
|
|||
[DllImport(DllPath)] public static extern void Run();
|
||||
[DllImport(DllPath)] public static extern void Stop();
|
||||
|
||||
[DllImport(DllPath)] public static extern void Pause();
|
||||
[DllImport(DllPath)] public static extern void Resume();
|
||||
[DllImport(DllPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool IsPaused();
|
||||
|
||||
[DllImport(DllPath)] public static extern void TakeScreenshot();
|
||||
|
||||
[DllImport(DllPath)] public static extern void LoadRom(
|
||||
|
|
|
@ -536,64 +536,16 @@ void Renderer::DrawScreen()
|
|||
_spriteBatch->Draw(_pTextureSrv, destRect);
|
||||
}
|
||||
|
||||
void Renderer::DrawPauseScreen(bool disableOverlay)
|
||||
void Renderer::DrawPauseScreen()
|
||||
{
|
||||
if(disableOverlay) {
|
||||
const static XMVECTORF32 transparentBlue = { { { 0.415686309f, 0.352941185f, 0.803921640f, 0.66f } } };
|
||||
DrawString("I", 15, 15, transparentBlue, 2.0f, _font.get());
|
||||
DrawString("I", 32, 15, transparentBlue, 2.0f, _font.get());
|
||||
} else {
|
||||
RECT destRect;
|
||||
destRect.left = 0;
|
||||
destRect.top = 0;
|
||||
destRect.right = _realScreenWidth;
|
||||
destRect.bottom = _realScreenHeight;
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE dd;
|
||||
HRESULT hr = _pDeviceContext->Map(_overlayTexture, 0, D3D11_MAP_WRITE_DISCARD, 0, &dd);
|
||||
if(FAILED(hr)) {
|
||||
MessageManager::Log("(DrawPauseScreen) DeviceContext::Map() failed - Error:" + std::to_string(hr));
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t* surfacePointer = (uint8_t*)dd.pData;
|
||||
for(uint32_t i = 0, len = 8; i < len; i++) {
|
||||
//Gray transparent overlay
|
||||
for(int j = 0; j < 8; j++) {
|
||||
((uint32_t*)surfacePointer)[j] = 0xAA222222;
|
||||
}
|
||||
surfacePointer += dd.RowPitch;
|
||||
}
|
||||
_pDeviceContext->Unmap(_overlayTexture, 0);
|
||||
|
||||
_spriteBatch->Draw(_pOverlaySrv, destRect);
|
||||
|
||||
XMVECTOR stringDimensions = _largeFont->MeasureString(L"PAUSE");
|
||||
float x = (float)_screenWidth / 2 - stringDimensions.m128_f32[0] / 2;
|
||||
float y = (float)_screenHeight / 2 - stringDimensions.m128_f32[1] / 2 - 8;
|
||||
DrawString("PAUSE", x, y, Colors::AntiqueWhite, 1.0f, _largeFont.get());
|
||||
|
||||
//TODO
|
||||
/*string utf8Message = _console->GetSettings()->GetPauseScreenMessage();
|
||||
if(utf8Message.size() > 0) {
|
||||
std::wstring message = utf8::utf8::decode(utf8Message);
|
||||
float width = MeasureString(message);
|
||||
DrawString(message, (float)_screenWidth - width - 20, (float)_screenHeight - 40, Colors::AntiqueWhite, 1.0f, _font.get());
|
||||
}*/
|
||||
}
|
||||
const static XMVECTORF32 transparentBlue = { { { 1.0f, 0.6f, 0.0f, 0.66f } } };
|
||||
DrawString("I", 15, 15, transparentBlue, 2.0f, _font.get());
|
||||
DrawString("I", 32, 15, transparentBlue, 2.0f, _font.get());
|
||||
}
|
||||
|
||||
void Renderer::Render()
|
||||
{
|
||||
//TODO
|
||||
/*bool paused = _console->IsPaused() && _console->IsRunning();
|
||||
bool disableOverlay = _console->GetSettings()->CheckFlag(EmulationFlags::HidePauseOverlay);
|
||||
shared_ptr<Debugger> debugger = _console->GetDebugger(false);
|
||||
if(debugger && debugger->IsExecutionStopped()) {
|
||||
paused = debugger->IsPauseIconShown();
|
||||
disableOverlay = true;
|
||||
}*/
|
||||
bool paused = false;
|
||||
bool paused = _console->IsPaused();
|
||||
|
||||
if(_noUpdateCount > 10 || _frameChanged || paused || IsMessageShown()) {
|
||||
_noUpdateCount = 0;
|
||||
|
@ -620,12 +572,10 @@ void Renderer::Render()
|
|||
//Draw screen
|
||||
DrawScreen();
|
||||
|
||||
//TODO
|
||||
/*
|
||||
if(paused) {
|
||||
DrawPauseScreen(disableOverlay);
|
||||
DrawPauseScreen();
|
||||
}
|
||||
*/
|
||||
|
||||
if(_console->IsRunning()) {
|
||||
DrawCounters();
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ private:
|
|||
ID3D11Texture2D* CreateTexture(uint32_t width, uint32_t height);
|
||||
ID3D11ShaderResourceView* GetShaderResourceView(ID3D11Texture2D* texture);
|
||||
void DrawScreen();
|
||||
void DrawPauseScreen(bool disableOverlay);
|
||||
void DrawPauseScreen();
|
||||
|
||||
void DrawString(string message, float x, float y, DirectX::FXMVECTOR color, float scale, SpriteFont* font = nullptr);
|
||||
void DrawString(std::wstring message, float x, float y, DirectX::FXMVECTOR color, float scale, SpriteFont* font = nullptr);
|
||||
|
|
Loading…
Add table
Reference in a new issue