diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index c81df9236..a04b3a29e 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -989,7 +989,12 @@ void FileData::launchGame(Window* window) // swapBuffers() is called here to turn the screen black to eliminate some potential // flickering and to avoid showing the game launch message briefly when returning // from the game. + #if defined(_WIN64) + if (!(Settings::getInstance()->getBool("LaunchWorkaround") || + ViewController::get()->runInBackground(mSystem))) + #else if (!ViewController::get()->runInBackground(mSystem)) + #endif Renderer::swapBuffers(); Scripting::fireEvent("game-start", romPath, getSourceFileData()->metadata.get("name")); diff --git a/es-app/src/guis/GuiMenu.cpp b/es-app/src/guis/GuiMenu.cpp index 555b6357e..808d2add4 100644 --- a/es-app/src/guis/GuiMenu.cpp +++ b/es-app/src/guis/GuiMenu.cpp @@ -1046,6 +1046,27 @@ void GuiMenu::openOtherOptions() } }); + #if defined(_WIN64) + // Workaround for launching games on AMD and Intel graphics drivers. + auto launch_workaround = std::make_shared(mWindow); + launch_workaround->setState(Settings::getInstance()->getBool("LaunchWorkaround")); + s->addWithLabel("AMD AND INTEL GPU GAME LAUNCH WORKAROUND", launch_workaround); + s->addSaveFunc([launch_workaround, s] { + if (launch_workaround->getState() != Settings::getInstance()->getBool("LaunchWorkaround")) { + Settings::getInstance()->setBool("LaunchWorkaround", launch_workaround->getState()); + s->setNeedsSaving(); + } + }); + + // If the RunInBackground setting is enabled, then disable this option. + if (Settings::getInstance()->getBool("RunInBackground")) { + launch_workaround->setEnabled(false); + launch_workaround->setOpacity(DISABLED_OPACITY); + launch_workaround->getParent()->getChild(launch_workaround-> + getChildIndex() - 1)->setOpacity(DISABLED_OPACITY); + } + #endif + // Whether to upscale the video frame rate to 60 FPS. auto video_upscale_frame_rate = std::make_shared(mWindow); video_upscale_frame_rate->setState(Settings::getInstance()->getBool("VideoUpscaleFrameRate")); @@ -1180,6 +1201,25 @@ void GuiMenu::openOtherOptions() }); #endif + #if defined(_WIN64) + // Switch callback. + auto launchWorkAroundToggleFunc = [launch_workaround]() { + if (launch_workaround->getEnabled()) { + launch_workaround->setEnabled(false); + launch_workaround->setOpacity(DISABLED_OPACITY); + launch_workaround->getParent()->getChild(launch_workaround-> + getChildIndex() - 1)->setOpacity(DISABLED_OPACITY); + } + else { + launch_workaround->setEnabled(true); + launch_workaround->setOpacity(255); + launch_workaround->getParent()->getChild(launch_workaround-> + getChildIndex() - 1)->setOpacity(255); + } + }; + run_in_background->setCallback(launchWorkAroundToggleFunc); + #endif + mWindow->pushGui(s); } diff --git a/es-core/src/Platform.cpp b/es-core/src/Platform.cpp index 658f1bf98..4e509cf1e 100644 --- a/es-core/src/Platform.cpp +++ b/es-core/src/Platform.cpp @@ -151,15 +151,16 @@ int launchGameWindows(const std::wstring& cmd_utf16, bool runInBackground) &si, // Pointer to the STARTUPINFOW structure. &pi); // Pointer to the PROCESS_INFORMATION structure. - // Unfortunately suspending ES-DE and resuming when the game/emulator process has exited - // doesn't work reliably on Windows, so we may need to keep ES-DE running in the background - // while the game is launched. I'm not sure if there is a workaround for this, but on most - // Windows installations it seems to work fine so we'll let the user choose via a menu option. - // Possibly the issue is specific to Windows 8. - // Running in the background is also required for Steam games as ES-DE would otherwise - // wait forever for Steam to exit unless it was already running when the game was launched. if (!runInBackground) { - // Wait for the child process to exit. + if (Settings::getInstance()->getBool("LaunchWorkaround")) { + // Ugly hack to make the emulator window render correctly with some graphics drivers + // (probably only those from AMD and Intel as Nvidia seems to work fine without this). + // Unfortunately this turns the screen white as the emulator is starting. + // This definitely needs a proper solution some time in the future. + SDL_HideWindow(Renderer::getSDLWindow()); + SDL_ShowWindow(Renderer::getSDLWindow()); + } + WaitForSingleObject(pi.hThread, INFINITE); WaitForSingleObject(pi.hProcess, INFINITE); } diff --git a/es-core/src/Settings.cpp b/es-core/src/Settings.cpp index 2bc82f9c4..4625f1c05 100644 --- a/es-core/src/Settings.cpp +++ b/es-core/src/Settings.cpp @@ -246,6 +246,9 @@ void Settings::setDefaults() mBoolMap["HideTaskbar"] = { false, false }; #endif mBoolMap["RunInBackground"] = { false, false }; + #if defined(_WIN64) + mBoolMap["LaunchWorkaround"] = { true, true }; + #endif mStringMap["MediaDirectory"] = { "", "" }; mBoolMap["VideoUpscaleFrameRate"] = { false, false }; mBoolMap["LaunchCommandOverride"] = { true, true };