diff --git a/CHANGES b/CHANGES index 60e577875..4b991547a 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,7 @@ Features: - Remappable controls for tilt and gyroscope sensors - Status messages for actions taken while a game is running (e.g. save/load state) - Memory inspector + - Screensaver can now be suspended while a game is running Bugfixes: - GBA: Fix timers not updating timing when writing to only the reload register - All: Fix sanitize-deb script not cleaning up after itself diff --git a/src/gba/supervisor/config.c b/src/gba/supervisor/config.c index 437f0e104..b497218ab 100644 --- a/src/gba/supervisor/config.c +++ b/src/gba/supervisor/config.c @@ -204,6 +204,9 @@ void GBAConfigMap(const struct GBAConfig* config, struct GBAOptions* opts) { if (_lookupIntValue(config, "resampleVideo", &fakeBool)) { opts->resampleVideo = fakeBool; } + if (_lookupIntValue(config, "suspendScreensaver", &fakeBool)) { + opts->suspendScreensaver = fakeBool; + } if (_lookupIntValue(config, "mute", &fakeBool)) { opts->mute = fakeBool; } @@ -251,6 +254,7 @@ void GBAConfigLoadDefaults(struct GBAConfig* config, const struct GBAOptions* op ConfigurationSetIntValue(&config->defaultsTable, 0, "mute", opts->mute); ConfigurationSetIntValue(&config->defaultsTable, 0, "lockAspectRatio", opts->lockAspectRatio); ConfigurationSetIntValue(&config->defaultsTable, 0, "resampleVideo", opts->resampleVideo); + ConfigurationSetIntValue(&config->defaultsTable, 0, "suspendScreensaver", opts->suspendScreensaver); switch (opts->idleOptimization) { case IDLE_LOOP_IGNORE: diff --git a/src/gba/supervisor/config.h b/src/gba/supervisor/config.h index fd3eaba82..86c5a93cc 100644 --- a/src/gba/supervisor/config.h +++ b/src/gba/supervisor/config.h @@ -35,6 +35,7 @@ struct GBAOptions { int height; bool lockAspectRatio; bool resampleVideo; + bool suspendScreensaver; int volume; bool mute; diff --git a/src/platform/qt/ConfigController.cpp b/src/platform/qt/ConfigController.cpp index 559c9fc6c..ba4978bac 100644 --- a/src/platform/qt/ConfigController.cpp +++ b/src/platform/qt/ConfigController.cpp @@ -114,6 +114,7 @@ ConfigController::ConfigController(QObject* parent) m_opts.rewindBufferInterval = 0; m_opts.rewindBufferCapacity = 0; m_opts.useBios = true; + m_opts.suspendScreensaver = true; GBAConfigLoadDefaults(&m_config, &m_opts); GBAConfigLoad(&m_config); GBAConfigMap(&m_config, &m_opts); diff --git a/src/platform/qt/InputController.cpp b/src/platform/qt/InputController.cpp index 2c378b586..9cb20f999 100644 --- a/src/platform/qt/InputController.cpp +++ b/src/platform/qt/InputController.cpp @@ -469,3 +469,17 @@ void InputController::clearPendingEvent(GBAKey key) { bool InputController::hasPendingEvent(GBAKey key) const { return m_pendingEvents.contains(key); } + +#if defined(BUILD_SDL) && SDL_VERSION_ATLEAST(2, 0, 0) +void InputController::suspendScreensaver() { + GBASDLSuspendScreensaver(&s_sdlEvents); +} + +void InputController::resumeScreensaver() { + GBASDLResumeScreensaver(&s_sdlEvents); +} + +void InputController::setScreensaverSuspendable(bool suspendable) { + GBASDLSetScreensaverSuspendable(&s_sdlEvents, suspendable); +} +#endif diff --git a/src/platform/qt/InputController.h b/src/platform/qt/InputController.h index ab8fb12d8..05493db8e 100644 --- a/src/platform/qt/InputController.h +++ b/src/platform/qt/InputController.h @@ -80,6 +80,13 @@ public: public slots: void testGamepad(int type); +#if defined(BUILD_SDL) && SDL_VERSION_ATLEAST(2, 0, 0) + // TODO: Move these to somewhere that makes sense + void suspendScreensaver(); + void resumeScreensaver(); + void setScreensaverSuspendable(bool); +#endif + private: void postPendingEvent(GBAKey); void clearPendingEvent(GBAKey); diff --git a/src/platform/qt/SettingsView.cpp b/src/platform/qt/SettingsView.cpp index 44aa13a20..e18e4a686 100644 --- a/src/platform/qt/SettingsView.cpp +++ b/src/platform/qt/SettingsView.cpp @@ -34,6 +34,7 @@ SettingsView::SettingsView(ConfigController* controller, QWidget* parent) loadSetting("rewindBufferCapacity", m_ui.rewindCapacity); loadSetting("resampleVideo", m_ui.resampleVideo); loadSetting("allowOpposingDirections", m_ui.allowOpposingDirections); + loadSetting("suspendScreensaver", m_ui.suspendScreensaver); QString idleOptimization = loadSetting("idleOptimization"); if (idleOptimization == "ignore") { @@ -87,6 +88,7 @@ void SettingsView::updateConfig() { saveSetting("rewindBufferCapacity", m_ui.rewindCapacity); saveSetting("resampleVideo", m_ui.resampleVideo); saveSetting("allowOpposingDirections", m_ui.allowOpposingDirections); + saveSetting("suspendScreensaver", m_ui.suspendScreensaver); switch (m_ui.idleOptimization->currentIndex() + IDLE_LOOP_IGNORE) { case IDLE_LOOP_IGNORE: diff --git a/src/platform/qt/SettingsView.ui b/src/platform/qt/SettingsView.ui index b7e371dea..3d9b1d22f 100644 --- a/src/platform/qt/SettingsView.ui +++ b/src/platform/qt/SettingsView.ui @@ -6,8 +6,8 @@ 0 0 - 374 - 608 + 656 + 366 @@ -21,21 +21,21 @@ - - - QFormLayout::ExpandingFieldsGrow - - - - - BIOS file: + + + + + QFormLayout::ExpandingFieldsGrow - - - - - - + + + + Audio driver: + + + + + 0 @@ -44,346 +44,371 @@ - - + + - Browse + Audio buffer: - - - - - - Skip BIOS intro - - - - - - - Use BIOS file - - - true - - - - - - - Qt::Horizontal - - - - - - - Audio driver: - - - - - - - - 0 - 0 - - - - - - - - Audio buffer: - - - - - - - - - true - - - 2048 - - - 2 - + + - - 512 - + + + true + + + 2048 + + + 2 + + + + 512 + + + + + 1024 + + + + + 2048 + + + + + 4096 + + + - - 1024 - + + + samples + + - - - 2048 - - - - - 4096 - - - + - - + + - samples + Volume: - - - - - - Volume: - - - - - - - - - 256 - - - 16 - - - 256 - + + + + + + 256 + + + 16 + + + 256 + + + Qt::Horizontal + + + + + + + Mute + + + + + + + Qt::Horizontal - - + + - Mute + Sync: + + + + + + + + + Video + + + + + + + Audio + + + + + + + + + Frameskip: + + + + + + + + + Skip every + + + + + + + + + + frames + + + + + + + + + FPS target: + + + + + + + + + 240 + + + 60 + + + + + + + frames per second + + + + + + + + + Qt::Horizontal + + + + + + + Lock aspect ratio + + + + + + + Resample video + + + + + + + Suspend screensaver + + + true - - + + - Qt::Horizontal + Qt::Vertical - - - - Sync: - - - - - - - + + + + - Video + BIOS file: - - + + + + + + + 0 + 0 + + + + + + + + Browse + + + + + + + - Audio + Skip BIOS intro + + + + Use BIOS file + + + true + + + + + + + Qt::Horizontal + + + + + + + Enable rewind + + + + + + + Rewind interval: + + + + + + + + + Every + + + + + + + + + + frames + + + + + + + + + Rewind length: + + + + + + + + + + + + intervals + + + + + + + + + Qt::Horizontal + + + + + + + Allow opposing input directions + + + + + + + Idle loops + + + + + + + + Run all + + + + + Remove known + + + + + Detect and remove + + + + - - - - Frameskip: - - - - - - - - - Skip every - - - - - - - - - - frames - - - - - - - - - FPS target: - - - - - - - - - 240 - - - 60 - - - - - - - frames per second - - - - - - - - - Lock aspect ratio - - - - - - - Resample video - - - - - - - Qt::Horizontal - - - - - - - Enable rewind - - - - - - - Rewind interval: - - - - - - - - - Every - - - - - - - - - - frames - - - - - - - - - Rewind length: - - - - - - - - - - - - intervals - - - - - - - - - Allow opposing input directions - - - - - - - Qt::Horizontal - - - - - - - Idle loops - - - - - - - - Run all - - - - - Remove known - - - - - Detect and remove - - - - diff --git a/src/platform/qt/Window.cpp b/src/platform/qt/Window.cpp index 04d4163f4..0cd569ee8 100644 --- a/src/platform/qt/Window.cpp +++ b/src/platform/qt/Window.cpp @@ -89,8 +89,10 @@ Window::Window(ConfigController* config, int playerId, QWidget* parent) } connect(m_controller, SIGNAL(gameStarted(GBAThread*)), this, SLOT(gameStarted(GBAThread*))); + connect(m_controller, SIGNAL(gameStarted(GBAThread*)), &m_inputController, SLOT(suspendScreensaver())); connect(m_controller, SIGNAL(gameStopped(GBAThread*)), m_display, SLOT(stopDrawing())); connect(m_controller, SIGNAL(gameStopped(GBAThread*)), this, SLOT(gameStopped())); + connect(m_controller, SIGNAL(gameStopped(GBAThread*)), &m_inputController, SLOT(resumeScreensaver())); connect(m_controller, SIGNAL(stateLoaded(GBAThread*)), m_display, SLOT(forceDraw())); connect(m_controller, SIGNAL(rewound(GBAThread*)), m_display, SLOT(forceDraw())); connect(m_controller, SIGNAL(gamePaused(GBAThread*)), m_display, SLOT(pauseDrawing())); @@ -102,7 +104,9 @@ Window::Window(ConfigController* config, int playerId, QWidget* parent) } }); #endif + connect(m_controller, SIGNAL(gamePaused(GBAThread*)), &m_inputController, SLOT(resumeScreensaver())); connect(m_controller, SIGNAL(gameUnpaused(GBAThread*)), m_display, SLOT(unpauseDrawing())); + connect(m_controller, SIGNAL(gameUnpaused(GBAThread*)), &m_inputController, SLOT(suspendScreensaver())); connect(m_controller, SIGNAL(postLog(int, const QString&)), m_logView, SLOT(postLog(int, const QString&))); connect(m_controller, SIGNAL(frameAvailable(const uint32_t*)), this, SLOT(recordFrame())); connect(m_controller, SIGNAL(frameAvailable(const uint32_t*)), m_display, SLOT(framePosted(const uint32_t*))); @@ -192,6 +196,8 @@ void Window::loadConfig() { enterFullScreen(); } + m_inputController.setScreensaverSuspendable(opts->suspendScreensaver); + m_mruFiles = m_config->getMRU(); updateMRU(); diff --git a/src/platform/sdl/main.c b/src/platform/sdl/main.c index ac060f2e0..d192a97ae 100644 --- a/src/platform/sdl/main.c +++ b/src/platform/sdl/main.c @@ -117,6 +117,11 @@ int main(int argc, char** argv) { GBASDLPlayerLoadConfig(&renderer.player, GBAConfigGetInput(&config)); context.overrides = GBAConfigGetOverrides(&config); +#if SDL_VERSION_ATLEAST(2, 0, 0) + GBASDLSetScreensaverSuspendable(&renderer.events, opts.suspendScreensaver); + GBASDLSuspendScreensaver(&renderer.events); +#endif + int didFail = 0; if (GBAThreadStart(&context)) { renderer.runloop(&context, &renderer); @@ -126,6 +131,11 @@ int main(int argc, char** argv) { printf("Could not run game. Are you sure the file exists and is a Game Boy Advance game?\n"); } +#if SDL_VERSION_ATLEAST(2, 0, 0) + GBASDLResumeScreensaver(&renderer.events); + GBASDLSetScreensaverSuspendable(&renderer.events, false); +#endif + if (GBAThreadHasCrashed(&context)) { didFail = 1; printf("The game crashed!\n"); diff --git a/src/platform/sdl/sdl-events.c b/src/platform/sdl/sdl-events.c index c14ec665c..99e2e0bc1 100644 --- a/src/platform/sdl/sdl-events.c +++ b/src/platform/sdl/sdl-events.c @@ -32,7 +32,7 @@ static void _GBASDLRotationSample(struct GBARotationSource* source); bool GBASDLInitEvents(struct GBASDLEvents* context) { int subsystem = SDL_INIT_JOYSTICK; #if SDL_VERSION_ATLEAST(2, 0, 0) - subsystem |= SDL_INIT_HAPTIC; + subsystem |= SDL_INIT_HAPTIC | SDL_INIT_VIDEO; #endif if (SDL_InitSubSystem(subsystem) < 0) { return false; @@ -68,6 +68,8 @@ bool GBASDLInitEvents(struct GBASDLEvents* context) { #if !SDL_VERSION_ATLEAST(2, 0, 0) SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); +#else + context->screensaverSuspendDepth = 0; #endif return true; } @@ -582,3 +584,33 @@ static void _GBASDLRotationSample(struct GBARotationSource* source) { CircleBufferWrite32(&rotation->zHistory, theta.i); rotation->zDelta += theta.f - oldZ; } + +#if SDL_VERSION_ATLEAST(2, 0, 0) +void GBASDLSuspendScreensaver(struct GBASDLEvents* events) { + if (events->screensaverSuspendDepth == 0 && events->screensaverSuspendable) { + SDL_DisableScreenSaver(); + } + ++events->screensaverSuspendDepth; +} + +void GBASDLResumeScreensaver(struct GBASDLEvents* events) { + --events->screensaverSuspendDepth; + if (events->screensaverSuspendDepth == 0 && events->screensaverSuspendable) { + SDL_EnableScreenSaver(); + } +} + +void GBASDLSetScreensaverSuspendable(struct GBASDLEvents* events, bool suspendable) { + bool wasSuspendable = events->screensaverSuspendable; + events->screensaverSuspendable = suspendable; + if (events->screensaverSuspendDepth > 0) { + if (suspendable && !wasSuspendable) { + SDL_DisableScreenSaver(); + } else if (!suspendable && wasSuspendable) { + SDL_EnableScreenSaver(); + } + } else { + SDL_EnableScreenSaver(); + } +} +#endif diff --git a/src/platform/sdl/sdl-events.h b/src/platform/sdl/sdl-events.h index fbddda439..247c38f0f 100644 --- a/src/platform/sdl/sdl-events.h +++ b/src/platform/sdl/sdl-events.h @@ -29,6 +29,8 @@ struct GBASDLEvents { size_t joysticksClaimed[MAX_PLAYERS]; #if SDL_VERSION_ATLEAST(2, 0, 0) SDL_Haptic** haptic; + int screensaverSuspendDepth; + bool screensaverSuspendable; #endif }; @@ -82,4 +84,10 @@ void GBASDLPlayerSaveConfig(const struct GBASDLPlayer*, struct Configuration*); void GBASDLHandleEvent(struct GBAThread* context, struct GBASDLPlayer* sdlContext, const union SDL_Event* event); +#if SDL_VERSION_ATLEAST(2, 0, 0) +void GBASDLSuspendScreensaver(struct GBASDLEvents*); +void GBASDLResumeScreensaver(struct GBASDLEvents*); +void GBASDLSetScreensaverSuspendable(struct GBASDLEvents*, bool suspendable); +#endif + #endif