Added a 'winregistryvalue' find rule and a %RUNINBACKGROUND% variable.

This commit is contained in:
Leon Styhre 2021-11-22 20:03:05 +01:00
parent 7ebf895613
commit 7c07c0d5cf
3 changed files with 89 additions and 20 deletions

View file

@ -818,10 +818,24 @@ void FileData::launchGame(Window* window)
const std::string baseName = Utils::FileSystem::getStem(getPath()); const std::string baseName = Utils::FileSystem::getStem(getPath());
const std::string romRaw = Utils::FileSystem::getPreferredPath(getPath()); const std::string romRaw = Utils::FileSystem::getPreferredPath(getPath());
const std::string esPath = Utils::FileSystem::getExePath(); const std::string esPath = Utils::FileSystem::getExePath();
bool runInBackground = false;
#if defined(_WIN64) // In addition to the global RunInBackground setting it's possible to define this flag
bool hideWindow = false; // per launch command in es_systems.xml.
#endif size_t inBackgroundPos = command.find("%RUNINBACKGROUND%");
if (inBackgroundPos != std::string::npos) {
runInBackground = true;
command = Utils::String::replace(command, "%RUNINBACKGROUND%", "");
// Trim any leading whitespaces as they could cause the script execution to fail.
command.erase(command.begin(), std::find_if(command.begin(), command.end(), [](char c) {
return !std::isspace(static_cast<unsigned char>(c));
}));
}
// The global setting always applies.
if (Settings::getInstance()->getBool("RunInBackground"))
runInBackground = true;
std::string coreEntry; std::string coreEntry;
std::string coreName; std::string coreName;
@ -831,10 +845,14 @@ void FileData::launchGame(Window* window)
std::vector<std::string> emulatorCorePaths; std::vector<std::string> emulatorCorePaths;
#if defined(_WIN64) #if defined(_WIN64)
bool hideWindow = false;
// If the %HIDEWINDOW% variable is defined, we pass a flag to launchGameWindows() to // If the %HIDEWINDOW% variable is defined, we pass a flag to launchGameWindows() to
// hide the window. This is intended primarily for hiding console windows when launching // hide the window. This is intended primarily for hiding console windows when launching
// scripts (used for example by Steam games and source ports). // scripts (used for example by Steam games and source ports).
if (command.substr(0, 12) == "%HIDEWINDOW%") { size_t hideWindowPos = command.find("%HIDEWINDOW%");
if (hideWindowPos != std::string::npos) {
hideWindow = true; hideWindow = true;
command = Utils::String::replace(command, "%HIDEWINDOW%", ""); command = Utils::String::replace(command, "%HIDEWINDOW%", "");
// Trim any leading whitespaces as they could cause the script execution to fail. // Trim any leading whitespaces as they could cause the script execution to fail.
@ -1059,10 +1077,9 @@ void FileData::launchGame(Window* window)
// from the game. // from the game.
#if defined(_WIN64) #if defined(_WIN64)
if (!(Settings::getInstance()->getBool("LaunchWorkaround") || if (!(Settings::getInstance()->getBool("LaunchWorkaround") || runInBackground))
ViewController::get()->runInBackground(mSystem)))
#else #else
if (!ViewController::get()->runInBackground(mSystem)) if (!runInBackground)
#endif #endif
Renderer::swapBuffers(); Renderer::swapBuffers();
@ -1077,10 +1094,10 @@ void FileData::launchGame(Window* window)
// Possibly keep ES-DE running in the background while the game is launched. // Possibly keep ES-DE running in the background while the game is launched.
#if defined(_WIN64) #if defined(_WIN64)
returnValue = launchGameWindows(Utils::String::stringToWideString(command), returnValue =
ViewController::get()->runInBackground(mSystem), hideWindow); launchGameWindows(Utils::String::stringToWideString(command), runInBackground, hideWindow);
#else #else
returnValue = launchGameUnix(command, ViewController::get()->runInBackground(mSystem)); returnValue = launchGameUnix(command, runInBackground);
#endif #endif
// Notify the user in case of a failed game launch using a popup window. // Notify the user in case of a failed game launch using a popup window.
if (returnValue != 0) { if (returnValue != 0) {
@ -1095,10 +1112,10 @@ void FileData::launchGame(Window* window)
// Stop showing the game launch notification. // Stop showing the game launch notification.
window->stopInfoPopup(); window->stopInfoPopup();
#if defined(_WIN64) #if defined(_WIN64)
// For some game systems or if the "RunInBackground" setting has been enabled, keep // If the RunInBackground setting has been enabled or if the %RUNINBACKGROUND% variable has
// ES-DE running while the game is launched. This pauses any video and keeps the // been set for the specific launch command, then block the video player, stop scrolling
// screensaver from getting activated. // game names and descriptions and keep the screensaver from getting activated.
if (ViewController::get()->runInBackground(mSystem)) if (runInBackground)
window->setLaunchedGame(); window->setLaunchedGame();
else else
// Normalize deltaTime so that the screensaver does not start immediately // Normalize deltaTime so that the screensaver does not start immediately
@ -1106,8 +1123,9 @@ void FileData::launchGame(Window* window)
window->normalizeNextUpdate(); window->normalizeNextUpdate();
#else #else
// For some game systems we need to keep ES-DE running while the game is launched. // For some game systems we need to keep ES-DE running while the game is launched.
// This pauses any video and keeps the screensaver from getting activated. // This blocks the video player, stops the scrolling of game names and descriptions and
if (ViewController::get()->runInBackground(mSystem)) // keeps the screensaver from getting activated.
if (runInBackground)
window->setLaunchedGame(); window->setLaunchedGame();
// Normalize deltaTime so that the screensaver does not start immediately // Normalize deltaTime so that the screensaver does not start immediately
// when returning from the game. // when returning from the game.
@ -1119,7 +1137,7 @@ void FileData::launchGame(Window* window)
// Unless we're running in the background while the game is launched, re-enable the text // Unless we're running in the background while the game is launched, re-enable the text
// scrolling that was disabled in ViewController. // scrolling that was disabled in ViewController.
if (!ViewController::get()->runInBackground(mSystem)) if (!runInBackground)
window->setAllowTextScrolling(true); window->setAllowTextScrolling(true);
// Update number of times the game has been launched. // Update number of times the game has been launched.
@ -1159,6 +1177,7 @@ const std::string FileData::findEmulatorPath(std::string& command)
#if defined(_WIN64) #if defined(_WIN64)
std::vector<std::string> emulatorWinRegistryPaths; std::vector<std::string> emulatorWinRegistryPaths;
std::vector<std::string> emulatorWinRegistryValues;
#endif #endif
std::vector<std::string> emulatorSystemPaths; std::vector<std::string> emulatorSystemPaths;
std::vector<std::string> emulatorStaticPaths; std::vector<std::string> emulatorStaticPaths;
@ -1175,6 +1194,8 @@ const std::string FileData::findEmulatorPath(std::string& command)
#if defined(_WIN64) #if defined(_WIN64)
emulatorWinRegistryPaths = emulatorWinRegistryPaths =
SystemData::sFindRules.get()->mEmulators[emulatorEntry].winRegistryPaths; SystemData::sFindRules.get()->mEmulators[emulatorEntry].winRegistryPaths;
emulatorWinRegistryValues =
SystemData::sFindRules.get()->mEmulators[emulatorEntry].winRegistryValues;
#endif #endif
emulatorSystemPaths = SystemData::sFindRules.get()->mEmulators[emulatorEntry].systemPaths; emulatorSystemPaths = SystemData::sFindRules.get()->mEmulators[emulatorEntry].systemPaths;
emulatorStaticPaths = SystemData::sFindRules.get()->mEmulators[emulatorEntry].staticPaths; emulatorStaticPaths = SystemData::sFindRules.get()->mEmulators[emulatorEntry].staticPaths;
@ -1206,7 +1227,7 @@ const std::string FileData::findEmulatorPath(std::string& command)
KEY_QUERY_VALUE, &registryKey); KEY_QUERY_VALUE, &registryKey);
} }
// If the key exists, then try to retrieve the value. // If the key exists, then try to retrieve its default value.
if (keyStatus == ERROR_SUCCESS) { if (keyStatus == ERROR_SUCCESS) {
pathStatus = RegGetValue(registryKey, nullptr, nullptr, RRF_RT_REG_SZ, nullptr, pathStatus = RegGetValue(registryKey, nullptr, nullptr, RRF_RT_REG_SZ, nullptr,
&registryPath, &pathSize); &registryPath, &pathSize);
@ -1228,6 +1249,51 @@ const std::string FileData::findEmulatorPath(std::string& command)
} }
RegCloseKey(registryKey); RegCloseKey(registryKey);
} }
for (std::string value : emulatorWinRegistryValues) {
// Search for the defined value in the Windows Registry.
std::string registryValueKey =
Utils::String::replace(Utils::FileSystem::getParent(value), "/", "\\");
std::string registryValue = Utils::FileSystem::getFileName(value);
HKEY registryKey;
LSTATUS keyStatus = -1;
LSTATUS pathStatus = -1;
char path[1024]{};
DWORD pathSize = 1024;
// First look in HKEY_CURRENT_USER.
keyStatus = RegOpenKeyEx(HKEY_CURRENT_USER, registryValueKey.c_str(), 0, KEY_QUERY_VALUE,
&registryKey);
// If not found, then try in HKEY_LOCAL_MACHINE.
if (keyStatus != ERROR_SUCCESS) {
keyStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, registryValueKey.c_str(), 0,
KEY_QUERY_VALUE, &registryKey);
}
// If the key exists, then try to retrieve the defined value.
if (keyStatus == ERROR_SUCCESS) {
pathStatus =
RegGetValue(registryKey, nullptr, reinterpret_cast<LPCSTR>(registryValue.c_str()),
RRF_RT_REG_SZ, nullptr, &path, &pathSize);
}
else {
RegCloseKey(registryKey);
continue;
}
// That a value was found does not guarantee that the emulator binary actually exists,
// so check for that as well.
if (pathStatus == ERROR_SUCCESS) {
if (Utils::FileSystem::isRegularFile(path) || Utils::FileSystem::isSymlink(path)) {
command.replace(0, endPos + 1, path);
RegCloseKey(registryKey);
return path;
}
}
RegCloseKey(registryKey);
}
#endif #endif
for (std::string path : emulatorSystemPaths) { for (std::string path : emulatorSystemPaths) {

View file

@ -112,8 +112,8 @@ void FindRules::loadFindRules()
continue; continue;
} }
#if defined(_WIN64) #if defined(_WIN64)
if (ruleType != "winregistrypath" && ruleType != "systempath" && if (ruleType != "winregistrypath" && ruleType != "winregistryvalue" &&
ruleType != "staticpath") { ruleType != "systempath" && ruleType != "staticpath") {
#else #else
if (ruleType != "systempath" && ruleType != "staticpath") { if (ruleType != "systempath" && ruleType != "staticpath") {
#endif #endif
@ -131,6 +131,8 @@ void FindRules::loadFindRules()
#if defined(_WIN64) #if defined(_WIN64)
else if (ruleType == "winregistrypath") else if (ruleType == "winregistrypath")
emulatorRules.winRegistryPaths.push_back(entryValue); emulatorRules.winRegistryPaths.push_back(entryValue);
else if (ruleType == "winregistryvalue")
emulatorRules.winRegistryValues.push_back(entryValue);
#endif #endif
} }
} }

View file

@ -42,6 +42,7 @@ private:
struct EmulatorRules { struct EmulatorRules {
#if defined(_WIN64) #if defined(_WIN64)
std::vector<std::string> winRegistryPaths; std::vector<std::string> winRegistryPaths;
std::vector<std::string> winRegistryValues;
#endif #endif
std::vector<std::string> systemPaths; std::vector<std::string> systemPaths;
std::vector<std::string> staticPaths; std::vector<std::string> staticPaths;