diff --git a/include/dusk/audio/DuskAudioSystem.h b/include/dusk/audio/DuskAudioSystem.h index 724776f5f1..8cdd757c82 100644 --- a/include/dusk/audio/DuskAudioSystem.h +++ b/include/dusk/audio/DuskAudioSystem.h @@ -12,6 +12,8 @@ namespace dusk::audio { void SetMasterVolume(f32 value); + void SetPaused(bool paused); + u32 GetResetCount(int channelIdx); f32 VolumeFromU16(u16 value); diff --git a/include/dusk/game_clock.h b/include/dusk/game_clock.h index 6e7ea500eb..4a394b5c2e 100644 --- a/include/dusk/game_clock.h +++ b/include/dusk/game_clock.h @@ -8,6 +8,7 @@ namespace game_clock { void ensure_initialized(); void reset_accumulator(); +void reset_frame_timer(); constexpr float sim_pace() { return 1.0f / 30.0f; } constexpr float period_for_original_frames(float frame_count) { return frame_count * sim_pace(); } diff --git a/include/dusk/main.h b/include/dusk/main.h index a9194e2aba..2152a6d564 100644 --- a/include/dusk/main.h +++ b/include/dusk/main.h @@ -5,6 +5,7 @@ namespace dusk { extern bool IsRunning; extern bool IsShuttingDown; extern bool IsGameLaunched; + extern bool IsFocusPaused; } #endif // DUSK_MAIN_H diff --git a/include/dusk/settings.h b/include/dusk/settings.h index bcec0afcd2..753649df2e 100644 --- a/include/dusk/settings.h +++ b/include/dusk/settings.h @@ -68,6 +68,7 @@ struct UserSettings { ConfigVar enableMirrorMode; ConfigVar invertCameraXAxis; ConfigVar disableMainHUD; + ConfigVar pauseOnFocusLost; // Graphics ConfigVar bloomMode; diff --git a/src/dusk/audio/DuskAudioSystem.cpp b/src/dusk/audio/DuskAudioSystem.cpp index c818e46738..3577d3c9c7 100644 --- a/src/dusk/audio/DuskAudioSystem.cpp +++ b/src/dusk/audio/DuskAudioSystem.cpp @@ -77,6 +77,14 @@ void dusk::audio::SetMasterVolume(const f32 value) { MasterVolume = value; } +void dusk::audio::SetPaused(const bool paused) { + if (paused) { + SDL_PauseAudioStreamDevice(PlaybackStream); + } else { + SDL_ResumeAudioStreamDevice(PlaybackStream); + } +} + void dusk::audio::SetEnableReverb(const bool value) { JASCriticalSection section; diff --git a/src/dusk/game_clock.cpp b/src/dusk/game_clock.cpp index 176c43c3b7..8eedf44da3 100644 --- a/src/dusk/game_clock.cpp +++ b/src/dusk/game_clock.cpp @@ -29,6 +29,11 @@ void reset_accumulator() { s_sim_accumulator = 0.0f; } +void reset_frame_timer() { + s_previous_sample = clock::now(); + s_sim_accumulator = 0.0f; +} + MainLoopPacer advance_main_loop() { ensure_initialized(); diff --git a/src/dusk/imgui/ImGuiMenuGame.cpp b/src/dusk/imgui/ImGuiMenuGame.cpp index f9c7634a5c..d1ff216b3c 100644 --- a/src/dusk/imgui/ImGuiMenuGame.cpp +++ b/src/dusk/imgui/ImGuiMenuGame.cpp @@ -194,6 +194,9 @@ namespace dusk { #if DUSK_ENABLE_SENTRY_NATIVE config::ImGuiCheckbox("Enable Crash Reporting", getSettings().backend.enableCrashReporting); #endif + if (!IsMobile) { + config::ImGuiCheckbox("Pause on Focus Lost", getSettings().game.pauseOnFocusLost); + } ImGui::EndMenu(); } diff --git a/src/dusk/settings.cpp b/src/dusk/settings.cpp index fa87846f68..441ae4a1c3 100644 --- a/src/dusk/settings.cpp +++ b/src/dusk/settings.cpp @@ -42,6 +42,7 @@ UserSettings g_userSettings = { .enableMirrorMode {"game.enableMirrorMode", false}, .invertCameraXAxis {"game.invertCameraXAxis", false}, .disableMainHUD {"game.disableMainHUD", false}, + .pauseOnFocusLost {"game.pauseOnFocusLost", false}, // Graphics .bloomMode {"game.bloomMode", BloomMode::Classic}, @@ -136,6 +137,7 @@ void registerSettings() { Register(g_userSettings.game.enableMirrorMode); Register(g_userSettings.game.invertCameraXAxis); Register(g_userSettings.game.disableMainHUD); + Register(g_userSettings.game.pauseOnFocusLost); Register(g_userSettings.game.bloomMode); Register(g_userSettings.game.bloomMultiplier); Register(g_userSettings.game.enableWaterRefraction); diff --git a/src/m_Do/m_Do_main.cpp b/src/m_Do/m_Do_main.cpp index 0249269f32..ab1990b178 100644 --- a/src/m_Do/m_Do_main.cpp +++ b/src/m_Do/m_Do_main.cpp @@ -68,6 +68,7 @@ #include "cxxopts.hpp" #include "dusk/audio/DuskAudioSystem.h" #include "dusk/config.hpp" +#include "dusk/settings.h" #include "dusk/imgui/ImGuiConsole.hpp" #include "tracy/Tracy.hpp" @@ -92,6 +93,7 @@ const int audioHeapSize = 0x14D800; bool dusk::IsRunning = true; bool dusk::IsShuttingDown = false; bool dusk::IsGameLaunched = false; +bool dusk::IsFocusPaused = false; #endif s32 LOAD_COPYDATE(void*) { @@ -208,6 +210,16 @@ void main01(void) { goto eventsDone; case AURORA_SDL_EVENT: dusk::g_imguiConsole.HandleSDLEvent(event->sdl); + if (event->sdl.type == SDL_EVENT_WINDOW_FOCUS_LOST && + dusk::getSettings().game.pauseOnFocusLost) { + dusk::IsFocusPaused = true; + dusk::audio::SetPaused(true); + } else if (event->sdl.type == SDL_EVENT_WINDOW_FOCUS_GAINED && + dusk::IsFocusPaused) { + dusk::IsFocusPaused = false; + dusk::audio::SetPaused(false); + dusk::game_clock::reset_frame_timer(); + } break; case AURORA_DISPLAY_SCALE_CHANGED: dusk::ImGuiEngine_Initialize(event->windowSize.scale); @@ -221,6 +233,11 @@ void main01(void) { eventsDone:; + if (dusk::IsFocusPaused) { + std::this_thread::sleep_for(std::chrono::milliseconds(16)); + continue; + } + const dusk::game_clock::MainLoopPacer pacing = dusk::game_clock::advance_main_loop(); VIWaitForRetrace();