(Windows) Added a menu option to run ES in the background while a game is launched.

Suspending ES while launching a game has proven unreliable on Windows, but on some installations it works so it makes sense to let the user select it. It makes for a better and more seamless experience if it works as intended.
This commit is contained in:
Leon Styhre 2020-07-19 22:08:14 +02:00
parent 34da214a8d
commit 0a410863cb
6 changed files with 61 additions and 36 deletions

View file

@ -26,10 +26,6 @@
#include <assert.h> #include <assert.h>
#ifdef _WIN64
#include <SDL2/SDL_timer.h>
#endif
FileData::FileData( FileData::FileData(
FileType type, FileType type,
const std::string& path, const std::string& path,
@ -549,14 +545,13 @@ void FileData::launchGame(Window* window)
Utils::String::toUpper(std::to_string(returnValue) + ")"), 6000); Utils::String::toUpper(std::to_string(returnValue) + ")"), 6000);
window->setInfoPopup(s); window->setInfoPopup(s);
} }
// This code is only needed for Windows, where we need to keep ES running while
// the game/emulator is in use. It's basically used to pause any playing game video.
#ifdef _WIN64 #ifdef _WIN64
// This code is only needed for Windows, where we may need to keep ES running while
// the game/emulator is in use. It's basically used to pause any playing game video
// and to keep the screensaver from activating.
else { else {
window->setLaunchedGame(); if (Settings::getInstance()->getBool("RunInBackground"))
// Temporary hack to stop the user from sending any input to ES while window->setLaunchedGame();
// the game is launching.
SDL_Delay(3000);
} }
#endif #endif

View file

@ -56,6 +56,12 @@ public:
void apply(float t) override void apply(float t) override
{ {
// TEMPORARY - disabled the launch animations as they don't work properly and more
// work is needed to fix them. This has been done in LaunchAnimation.h instead of in
// ViewController as not calling the animation leads to input not being properly
// consumed. This also needs to be fixed later on.
return;
cameraOut = Transform4x4f::Identity(); cameraOut = Transform4x4f::Identity();
float zoom = Math::lerp(1.0, 4.25f, t*t); float zoom = Math::lerp(1.0, 4.25f, t*t);

View file

@ -601,6 +601,13 @@ void GuiMenu::openOtherSettings()
s->addWithLabel("HIDE TASKBAR (REQUIRES RESTART)", hide_taskbar); s->addWithLabel("HIDE TASKBAR (REQUIRES RESTART)", hide_taskbar);
s->addSaveFunc([hide_taskbar] { Settings::getInstance()-> s->addSaveFunc([hide_taskbar] { Settings::getInstance()->
setBool("HideTaskbar", hide_taskbar->getState()); }); setBool("HideTaskbar", hide_taskbar->getState()); });
// Run ES in the background when a game has been launched.
auto run_in_background = std::make_shared<SwitchComponent>(mWindow);
run_in_background->setState(Settings::getInstance()->getBool("RunInBackground"));
s->addWithLabel("RUN IN BACKGROUND (WHILE GAME IS LAUNCHED)", run_in_background);
s->addSaveFunc([run_in_background] { Settings::getInstance()->
setBool("RunInBackground", run_in_background->getState()); });
#endif #endif
// Allow overriding of the launch command per game (the option to disable this is // Allow overriding of the launch command per game (the option to disable this is

View file

@ -264,13 +264,21 @@ void ViewController::launch(FileData* game, Vector3f center)
// Let launch sound play to the end before launching game. // Let launch sound play to the end before launching game.
while (NavigationSounds::getInstance()->isPlayingThemeNavigationSound(LAUNCHSOUND)); while (NavigationSounds::getInstance()->isPlayingThemeNavigationSound(LAUNCHSOUND));
game->launchGame(mWindow);
mLockInput = false;
this->onFileChanged(game, FILE_METADATA_CHANGED);
// TEMPORARY - disabled the launch animations as they don't work properly and more // TEMPORARY - disabled the launch animations as they don't work properly and more
// work is needed to fix them. // work is needed to fix them. This has been done in LaunchAnimation.h instead of here,
// // as not calling the animation leads to input not being properly consumed. This also
// needs to be fixed later on.
setAnimation(new LaunchAnimation(mCamera, mFadeOpacity, center, 1500), 0,
[this, origCamera, center, game] {
game->launchGame(mWindow);
mCamera = origCamera;
setAnimation(new LaunchAnimation(mCamera, mFadeOpacity, center, 600), 0, [this] {
mLockInput = false; }, true);
this->onFileChanged(game, FILE_METADATA_CHANGED);
if (mCurrentView)
mCurrentView->onShow();
});
// if (transition_style == "fade") { // if (transition_style == "fade") {
// // Fade out, launch game, fade back in. // // Fade out, launch game, fade back in.
// auto fadeFunc = [this](float t) { // auto fadeFunc = [this](float t) {
@ -409,20 +417,22 @@ std::shared_ptr<SystemView> ViewController::getSystemListView()
return mSystemListView; return mSystemListView;
} }
bool ViewController::input(InputConfig* config, Input input) bool ViewController::input(InputConfig* config, Input input)
{ {
if (mLockInput) if (mLockInput)
return true; return true;
// This code is only needed for Windows, where we need to keep ES running while
// the game/emulator is in use. It's basically used to pause any playing game video.
#ifdef _WIN64 #ifdef _WIN64
// If we have previously launched a game and there is now input registered, it means // This code is only needed for Windows, where we may need to keep ES running while
// the user is back in ES, so unset the flag to indicate that a game has been launched // the game/emulator is in use. It's basically used to pause any playing game video
// and update all the GUI components to reflect this. // and to keep the screensaver from activating.
if (mWindow->getGameLaunchedState()) { if (Settings::getInstance()->getBool("RunInBackground")) {
mWindow->unsetLaunchedGame(); // If we have previously launched a game and there is now input registered, it means
// the user is back in ES, so unset the flag to indicate that a game has been launched
// and update all the GUI components to reflect this.
bool testbool = mWindow->getGameLaunchedState();
if (mWindow->getGameLaunchedState())
mWindow->unsetLaunchedGame();
} }
#endif #endif
@ -550,12 +560,15 @@ void ViewController::reloadGameListView(IGameListView* view, bool reloadTheme)
} }
} }
// This code is only needed for Windows, where we need to keep ES running while
// the game/emulator is in use. It's basically used to pause any playing game video.
#ifdef _WIN64 #ifdef _WIN64
// If a game has been launched, then update all the GUI components to reflect this. // This code is only needed for Windows, where we may need to keep ES running while
if (mWindow->getGameLaunchedState()) // the game/emulator is in use. It's basically used to pause any playing game video
mWindow->setLaunchedGame(); // and to keep the screensaver from activating.
if (Settings::getInstance()->getBool("RunInBackground")) {
// If a game has been launched, then update all the GUI components to reflect this.
if (mWindow->getGameLaunchedState())
mWindow->setLaunchedGame();
}
#endif #endif
// Redisplay the current view. // Redisplay the current view.

View file

@ -11,6 +11,7 @@
#include "AudioManager.h" #include "AudioManager.h"
#include "Log.h" #include "Log.h"
#include "MameNames.h" #include "MameNames.h"
#include "Settings.h"
#if defined(__linux__) || defined(_WIN64) #if defined(__linux__) || defined(_WIN64)
#include <SDL2/SDL_events.h> #include <SDL2/SDL_events.h>
@ -138,13 +139,15 @@ int launchEmulatorWindows(const std::wstring& cmd_utf16)
&pi); // Pointer to the PROCESS_INFORMATION structure. &pi); // Pointer to the PROCESS_INFORMATION structure.
// Unfortunately suspending ES and resuming when the emulator process has exited // Unfortunately suspending ES and resuming when the emulator process has exited
// doesn't work reliably on Windows, so we need to keep ES running. Maybe there is // doesn't work reliably on Windows, so we may need to keep ES running in the
// some workaround for this. Possibly it's just SDL that is glitchy or it's actually // background while the game is launched. I'm not sure if there is a workaround
// something OS-specific. Keeping the code here just in case it could be reactivated. // for this, but on some Windows installations it seems to work fine so we'll let
// For sure it would simplify things, like not having to pause playing videos. // the user choose via a menu option.
// // Wait for the child process to exit. if (!Settings::getInstance()->getBool("RunInBackground")) {
// WaitForSingleObject(pi.hThread, INFINITE); // Wait for the child process to exit.
// WaitForSingleObject(pi.hProcess, INFINITE); WaitForSingleObject(pi.hThread, INFINITE);
WaitForSingleObject(pi.hProcess, INFINITE);
}
// If the return value is false, then something failed. // If the return value is false, then something failed.
if (!processReturnValue) { if (!processReturnValue) {

View file

@ -187,6 +187,7 @@ void Settings::setDefaults()
mStringMap["SaveGamelistsMode"] = "always"; mStringMap["SaveGamelistsMode"] = "always";
#ifdef _WIN64 #ifdef _WIN64
mBoolMap["HideTaskbar"] = false; mBoolMap["HideTaskbar"] = false;
mBoolMap["RunInBackground"] = true;
#endif #endif
mStringMap["MediaDirectory"] = ""; mStringMap["MediaDirectory"] = "";
mBoolMap["LaunchCommandOverride"] = true; mBoolMap["LaunchCommandOverride"] = true;