mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-01-17 22:55:38 +00:00
Added proper game launch function for Unix.
This commit is contained in:
parent
8fcb56cfb3
commit
6c79224eea
|
@ -466,7 +466,7 @@ void FileData::launchGame(Window* window)
|
|||
#endif
|
||||
|
||||
Scripting::fireEvent("game-start", rom, basename);
|
||||
int exitCode = 0;
|
||||
int returnValue = 0;
|
||||
|
||||
if (command.find("%EMUPATH%") != std::string::npos) {
|
||||
// Extract the emulator executable from the launch command string. This could either be
|
||||
|
@ -530,24 +530,28 @@ void FileData::launchGame(Window* window)
|
|||
|
||||
#ifdef _WIN64
|
||||
LOG(LogInfo) << Utils::String::wideStringToString(commandWide);
|
||||
exitCode = launchEmulatorWindows(commandWide);
|
||||
returnValue = launchEmulatorWindows(commandWide);
|
||||
#else
|
||||
LOG(LogInfo) << command;
|
||||
exitCode = launchEmulatorUnix(command);
|
||||
returnValue = launchEmulatorUnix(command);
|
||||
#endif
|
||||
|
||||
// Notify the user in case of a failed game launch using a popup window.
|
||||
if (exitCode != 0) {
|
||||
LOG(LogWarning) << "...launch terminated with nonzero exit code " << exitCode << "!";
|
||||
if (returnValue != 0) {
|
||||
LOG(LogWarning) << "...launch terminated with nonzero return value " << returnValue << "!";
|
||||
|
||||
GuiInfoPopup* s = new GuiInfoPopup(window, "ERROR LAUNCHING GAME '" +
|
||||
Utils::String::toUpper(metadata.get("name")) + "' (EXIT CODE " +
|
||||
Utils::String::toUpper(std::to_string(exitCode) + ")"), 4000);
|
||||
Utils::String::toUpper(metadata.get("name")) + "' (ERROR CODE " +
|
||||
Utils::String::toUpper(std::to_string(returnValue) + ")"), 6000);
|
||||
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
|
||||
else {
|
||||
window->setLaunchedGame();
|
||||
}
|
||||
#endif
|
||||
|
||||
Scripting::fireEvent("game-end");
|
||||
|
||||
|
|
|
@ -56,6 +56,8 @@ public:
|
|||
|
||||
void apply(float t) override
|
||||
{
|
||||
// TEMPORARY, disabled as it causes flicker when launching games.
|
||||
return;
|
||||
cameraOut = Transform4x4f::Identity();
|
||||
|
||||
float zoom = Math::lerp(1.0, 4.25f, t*t);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//
|
||||
// MoveCameraAnimation.h
|
||||
//
|
||||
// Animation to play when moving the camera.
|
||||
// Animation to play when moving the camera, used by the slide transition style.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
|
|
@ -408,12 +408,16 @@ bool ViewController::input(InputConfig* config, Input input)
|
|||
if (mLockInput)
|
||||
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
|
||||
// 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.
|
||||
if (mWindow->getGameLaunchedState()) {
|
||||
mWindow->unsetLaunchedGame();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Open menu.
|
||||
if (!(UIModeController::getInstance()->isUIModeKid() &&
|
||||
|
@ -539,9 +543,13 @@ 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
|
||||
// If a game has been launched, then update all the GUI components to reflect this.
|
||||
if (mWindow->getGameLaunchedState())
|
||||
mWindow->setLaunchedGame();
|
||||
#endif
|
||||
|
||||
// Redisplay the current view.
|
||||
if (mCurrentView)
|
||||
|
|
|
@ -68,10 +68,49 @@ int runSystemCommand(const std::wstring& cmd_utf16)
|
|||
|
||||
int launchEmulatorUnix(const std::string& cmd_utf8)
|
||||
{
|
||||
// TODO, replace with proper child process execution.
|
||||
#ifdef __unix__
|
||||
return system(cmd_utf8.c_str());
|
||||
#else
|
||||
std::string command = std::string(cmd_utf8) + " 2>&1";
|
||||
|
||||
FILE* commandPipe;
|
||||
std::array<char, 128> buffer;
|
||||
std::string commandOutput;
|
||||
int returnValue;
|
||||
|
||||
if (!(commandPipe = (FILE*)popen(command.c_str(), "r"))) {
|
||||
LOG(LogError) << "Error - couldn't open pipe to command.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (fgets(buffer.data(), buffer.size(), commandPipe) != nullptr) {
|
||||
commandOutput += buffer.data();
|
||||
}
|
||||
|
||||
returnValue = pclose(commandPipe);
|
||||
// We need to shift the return value as it contains some flags (which we don't need).
|
||||
returnValue >>= 8;
|
||||
|
||||
// Remove any trailing newline from the command output.
|
||||
if (commandOutput.size()) {
|
||||
if (commandOutput.back() == '\n')
|
||||
commandOutput.pop_back();
|
||||
}
|
||||
|
||||
if (returnValue) {
|
||||
LOG(LogError) << "Error - launchEmulatorUnix - return value " <<
|
||||
std::to_string(returnValue) + ":";
|
||||
if (commandOutput.size())
|
||||
LOG(LogError) << commandOutput;
|
||||
else
|
||||
LOG(LogError) << "No error output provided by emulator.";
|
||||
}
|
||||
else if (commandOutput.size()) {
|
||||
LOG(LogDebug) << "Platform::launchEmulatorUnix():";
|
||||
LOG(LogDebug) << "Output from launched game:\n" << commandOutput;
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
|
||||
#else // __unix__
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
@ -98,6 +137,15 @@ int launchEmulatorWindows(const std::wstring& cmd_utf16)
|
|||
&si, // Pointer to the STARTUPINFOW structure.
|
||||
&pi); // Pointer to the PROCESS_INFORMATION structure.
|
||||
|
||||
// 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
|
||||
// some workaround for this. Possibly it's just SDL that is glitchy or it's actually
|
||||
// something OS-specific. Keeping the code here just in case it could be reactivated.
|
||||
// For sure it would simplify things, like not having to pause playing videos.
|
||||
// // Wait for the child process to exit.
|
||||
// WaitForSingleObject(pi.hThread, INFINITE);
|
||||
// WaitForSingleObject(pi.hProcess, INFINITE);
|
||||
|
||||
// If the return value is false, then something failed.
|
||||
if (!processReturnValue) {
|
||||
LPWSTR pBuffer = nullptr;
|
||||
|
@ -110,10 +158,14 @@ int launchEmulatorWindows(const std::wstring& cmd_utf16)
|
|||
|
||||
std::string errorMessage = Utils::String::wideStringToString(pBuffer);
|
||||
// Remove trailing newline from the error message.
|
||||
if (errorMessage.back() == '\n');
|
||||
errorMessage.pop_back();
|
||||
if (errorMessage.back() == '\r');
|
||||
errorMessage.pop_back();
|
||||
if (errorMessage.size()) {
|
||||
if (errorMessage.back() == '\n')
|
||||
errorMessage.pop_back();
|
||||
if (errorMessage.size()) {
|
||||
if (errorMessage.back() == '\r')
|
||||
errorMessage.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
LOG(LogError) << "Error - launchEmulatorWindows - system error code " <<
|
||||
errorCode << ": " << errorMessage;
|
||||
|
@ -124,6 +176,7 @@ int launchEmulatorWindows(const std::wstring& cmd_utf16)
|
|||
CloseHandle(pi.hThread);
|
||||
|
||||
return errorCode;
|
||||
|
||||
#else // _WIN64
|
||||
return 0;
|
||||
#endif
|
||||
|
|
|
@ -27,6 +27,7 @@ Window::Window()
|
|||
mTimeSinceLastInput(0),
|
||||
mScreenSaver(nullptr),
|
||||
mRenderScreenSaver(false),
|
||||
mGameLaunchedState(false),
|
||||
mInfoPopup(nullptr)
|
||||
{
|
||||
mHelp = new HelpComponent(this);
|
||||
|
|
Loading…
Reference in a new issue