mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-22 06:05:38 +00:00
Added support for selecting alternative emulators per game.
Also made some changes to the system-wide alternative emulators logic.
This commit is contained in:
parent
69ad5cc56f
commit
5942b2815e
|
@ -748,36 +748,41 @@ void FileData::launchGame(Window* window)
|
||||||
LOG(LogInfo) << "Launching game \"" << this->metadata.get("name") << "\"...";
|
LOG(LogInfo) << "Launching game \"" << this->metadata.get("name") << "\"...";
|
||||||
|
|
||||||
std::string command = "";
|
std::string command = "";
|
||||||
|
std::string alternativeEmulator = getSystem()->getAlternativeEmulator();
|
||||||
|
|
||||||
// Check if there is a launch command override for the game
|
// Check if there is a game-specific alternative emulator configured.
|
||||||
// and the corresponding option to use it has been set.
|
// This takes precedence over any system-wide alternative emulator configuration.
|
||||||
if (Settings::getInstance()->getBool("LaunchCommandOverride") &&
|
if (Settings::getInstance()->getBool("AlternativeEmulatorPerGame") &&
|
||||||
!metadata.get("launchcommand").empty()) {
|
!metadata.get("altemulator").empty()) {
|
||||||
command = metadata.get("launchcommand");
|
command = getSystem()->getLaunchCommandFromLabel(metadata.get("altemulator"));
|
||||||
|
if (command == "") {
|
||||||
|
LOG(LogWarning) << "Invalid alternative emulator \"" << metadata.get("altemulator")
|
||||||
|
<< "\" configured for game";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG(LogDebug) << "FileData::launchGame(): Using alternative emulator \""
|
||||||
|
<< metadata.get("altemulator") << "\" as configured for the game";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
std::string alternativeEmulator = getSystem()->getAlternativeEmulator();
|
|
||||||
for (auto launchCommand : mEnvData->mLaunchCommands) {
|
|
||||||
if (launchCommand.second == alternativeEmulator) {
|
|
||||||
command = launchCommand.first;
|
|
||||||
LOG(LogDebug) << "FileData::launchGame(): Using alternative emulator \""
|
|
||||||
<< alternativeEmulator << "\""
|
|
||||||
<< " for system \"" << this->getSystem()->getName() << "\"";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!alternativeEmulator.empty() && command.empty()) {
|
|
||||||
LOG(LogWarning) << "The alternative emulator configured for system \""
|
|
||||||
<< getSystem()->getName()
|
|
||||||
<< "\" is invalid, falling back to the default command \""
|
|
||||||
<< getSystem()->getSystemEnvData()->mLaunchCommands.front().first
|
|
||||||
<< "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command.empty())
|
// Check if there is a system-wide alternative emulator configured.
|
||||||
command = mEnvData->mLaunchCommands.front().first;
|
if (command == "" && alternativeEmulator != "") {
|
||||||
|
command = getSystem()->getLaunchCommandFromLabel(alternativeEmulator);
|
||||||
|
if (command == "") {
|
||||||
|
LOG(LogWarning) << "Invalid alternative emulator \""
|
||||||
|
<< alternativeEmulator.substr(9, alternativeEmulator.length() - 9)
|
||||||
|
<< "\" configured for system \"" << getSystem()->getName() << "\"";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG(LogDebug) << "FileData::launchGame(): Using alternative emulator \""
|
||||||
|
<< getSystem()->getAlternativeEmulator() << "\""
|
||||||
|
<< " as configured for system \"" << this->getSystem()->getName() << "\"";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (command.empty())
|
||||||
|
command = mEnvData->mLaunchCommands.front().first;
|
||||||
|
|
||||||
std::string commandRaw = command;
|
std::string commandRaw = command;
|
||||||
|
|
||||||
const std::string romPath = Utils::FileSystem::getEscapedPath(getPath());
|
const std::string romPath = Utils::FileSystem::getEscapedPath(getPath());
|
||||||
|
|
|
@ -132,7 +132,7 @@ void parseGamelist(SystemData* system)
|
||||||
<< "\" has a valid alternativeEmulator entry: \"" << label << "\"";
|
<< "\" has a valid alternativeEmulator entry: \"" << label << "\"";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
system->setAlternativeEmulator("<INVALID>");
|
system->setAlternativeEmulator("<INVALID>" + label);
|
||||||
LOG(LogWarning) << "System \"" << system->getName()
|
LOG(LogWarning) << "System \"" << system->getName()
|
||||||
<< "\" has an invalid alternativeEmulator entry that does "
|
<< "\" has an invalid alternativeEmulator entry that does "
|
||||||
"not match any command tag in es_systems.xml: \""
|
"not match any command tag in es_systems.xml: \""
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#include <pugixml.hpp>
|
#include <pugixml.hpp>
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
// The statistic entries must be placed at the bottom or otherwise there will be problems with
|
||||||
|
// saving the values in GuiMetaDataEd.
|
||||||
MetaDataDecl gameDecls[] = {
|
MetaDataDecl gameDecls[] = {
|
||||||
// key, type, default, statistic, name in GuiMetaDataEd, prompt in GuiMetaDataEd, shouldScrape
|
// key, type, default, statistic, name in GuiMetaDataEd, prompt in GuiMetaDataEd, shouldScrape
|
||||||
{"name", MD_STRING, "", false, "name", "enter name", true},
|
{"name", MD_STRING, "", false, "name", "enter name", true},
|
||||||
|
@ -34,9 +36,8 @@ MetaDataDecl gameDecls[] = {
|
||||||
{"nogamecount", MD_BOOL, "false", false, "exclude from game counter", "enter don't count as game off/on", false},
|
{"nogamecount", MD_BOOL, "false", false, "exclude from game counter", "enter don't count as game off/on", false},
|
||||||
{"nomultiscrape", MD_BOOL, "false", false, "exclude from multi-scraper", "enter no multi-scrape off/on", false},
|
{"nomultiscrape", MD_BOOL, "false", false, "exclude from multi-scraper", "enter no multi-scrape off/on", false},
|
||||||
{"hidemetadata", MD_BOOL, "false", false, "hide metadata fields", "enter hide metadata off/on", false},
|
{"hidemetadata", MD_BOOL, "false", false, "hide metadata fields", "enter hide metadata off/on", false},
|
||||||
{"launchcommand", MD_LAUNCHCOMMAND, "", false, "launch command", "enter game launch command "
|
|
||||||
"(emulator override)", false},
|
|
||||||
{"playcount", MD_INT, "0", false, "times played", "enter number of times played", false},
|
{"playcount", MD_INT, "0", false, "times played", "enter number of times played", false},
|
||||||
|
{"altemulator", MD_ALT_EMULATOR, "", false, "alternative emulator", "select alternative emulator", false},
|
||||||
{"lastplayed", MD_TIME, "0", true, "last played", "enter last played date", false}
|
{"lastplayed", MD_TIME, "0", true, "last played", "enter last played date", false}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ enum MetaDataType {
|
||||||
|
|
||||||
// Specialized types.
|
// Specialized types.
|
||||||
MD_MULTILINE_STRING,
|
MD_MULTILINE_STRING,
|
||||||
MD_LAUNCHCOMMAND,
|
MD_ALT_EMULATOR,
|
||||||
MD_PATH,
|
MD_PATH,
|
||||||
MD_RATING,
|
MD_RATING,
|
||||||
MD_DATE,
|
MD_DATE,
|
||||||
|
|
|
@ -501,10 +501,9 @@ bool SystemData::loadConfig()
|
||||||
}
|
}
|
||||||
else if (!commands.empty() && commands.back().second == "") {
|
else if (!commands.empty() && commands.back().second == "") {
|
||||||
// There are more than one command tags and the first tag did not have a label.
|
// There are more than one command tags and the first tag did not have a label.
|
||||||
LOG(LogError)
|
LOG(LogError) << "Missing mandatory label attribute for alternative emulator "
|
||||||
<< "Missing mandatory label attribute for alternative emulator "
|
"entry, only the first command tag will be processed for system \""
|
||||||
"entry, only the first command tag will be processed for system \""
|
<< name << "\"";
|
||||||
<< name << "\"";
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
commands.push_back(
|
commands.push_back(
|
||||||
|
@ -615,6 +614,18 @@ bool SystemData::loadConfig()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string SystemData::getLaunchCommandFromLabel(const std::string& label)
|
||||||
|
{
|
||||||
|
auto commandIter = std::find_if(
|
||||||
|
mEnvData->mLaunchCommands.cbegin(), mEnvData->mLaunchCommands.cend(),
|
||||||
|
[label](std::pair<std::string, std::string> command) { return (command.second == label); });
|
||||||
|
|
||||||
|
if (commandIter != mEnvData->mLaunchCommands.cend())
|
||||||
|
return (*commandIter).first;
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
void SystemData::deleteSystems()
|
void SystemData::deleteSystems()
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < sSystemVector.size(); i++)
|
for (unsigned int i = 0; i < sSystemVector.size(); i++)
|
||||||
|
|
|
@ -99,6 +99,7 @@ public:
|
||||||
|
|
||||||
std::string getAlternativeEmulator() { return mAlternativeEmulator; }
|
std::string getAlternativeEmulator() { return mAlternativeEmulator; }
|
||||||
void setAlternativeEmulator(const std::string& command) { mAlternativeEmulator = command; }
|
void setAlternativeEmulator(const std::string& command) { mAlternativeEmulator = command; }
|
||||||
|
std::string getLaunchCommandFromLabel(const std::string& label);
|
||||||
|
|
||||||
static void deleteSystems();
|
static void deleteSystems();
|
||||||
// Loads the systems configuration file at getConfigPath() and creates the systems.
|
// Loads the systems configuration file at getConfigPath() and creates the systems.
|
||||||
|
|
|
@ -30,7 +30,7 @@ GuiAlternativeEmulators::GuiAlternativeEmulators(Window* window)
|
||||||
|
|
||||||
// Only include systems that have at least two command entries, unless the system
|
// Only include systems that have at least two command entries, unless the system
|
||||||
// has an invalid entry.
|
// has an invalid entry.
|
||||||
if ((*it)->getAlternativeEmulator() != "<INVALID>" &&
|
if ((*it)->getAlternativeEmulator().substr(0, 9) != "<INVALID>" &&
|
||||||
(*it)->getSystemEnvData()->mLaunchCommands.size() < 2)
|
(*it)->getSystemEnvData()->mLaunchCommands.size() < 2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ GuiAlternativeEmulators::GuiAlternativeEmulators(Window* window)
|
||||||
bool invalidEntry = false;
|
bool invalidEntry = false;
|
||||||
|
|
||||||
if (label.empty()) {
|
if (label.empty()) {
|
||||||
label = "<INVALID ENTRY>";
|
label = ViewController::EXCLAMATION_CHAR + " INVALID ENTRY";
|
||||||
invalidEntry = true;
|
invalidEntry = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,11 @@ GuiAlternativeEmulators::GuiAlternativeEmulators(Window* window)
|
||||||
labelText->setSize(labelSizeX, labelText->getSize().y);
|
labelText->setSize(labelSizeX, labelText->getSize().y);
|
||||||
|
|
||||||
row.addElement(labelText, false);
|
row.addElement(labelText, false);
|
||||||
row.makeAcceptInputHandler([this, it] { selectorWindow(*it); });
|
row.makeAcceptInputHandler([this, it, labelText] {
|
||||||
|
if (labelText->getValue() == "<REMOVED ENTRY>")
|
||||||
|
return;
|
||||||
|
selectorWindow(*it);
|
||||||
|
});
|
||||||
|
|
||||||
mMenu.addRow(row);
|
mMenu.addRow(row);
|
||||||
mHasSystems = true;
|
mHasSystems = true;
|
||||||
|
@ -104,9 +108,9 @@ GuiAlternativeEmulators::GuiAlternativeEmulators(Window* window)
|
||||||
// es_systems.xml.
|
// es_systems.xml.
|
||||||
if (!mHasSystems) {
|
if (!mHasSystems) {
|
||||||
ComponentListRow row;
|
ComponentListRow row;
|
||||||
std::shared_ptr<TextComponent> systemText =
|
std::shared_ptr<TextComponent> systemText = std::make_shared<TextComponent>(
|
||||||
std::make_shared<TextComponent>(mWindow, "<NO ALTERNATIVE EMULATORS DEFINED>",
|
mWindow, ViewController::EXCLAMATION_CHAR + " NO ALTERNATIVE EMULATORS DEFINED",
|
||||||
Font::get(FONT_SIZE_MEDIUM), 0x777777FF, ALIGN_CENTER);
|
Font::get(FONT_SIZE_MEDIUM), 0x777777FF, ALIGN_CENTER);
|
||||||
row.addElement(systemText, true);
|
row.addElement(systemText, true);
|
||||||
mMenu.addRow(row);
|
mMenu.addRow(row);
|
||||||
}
|
}
|
||||||
|
@ -150,13 +154,16 @@ void GuiAlternativeEmulators::selectorWindow(SystemData* system)
|
||||||
ComponentListRow row;
|
ComponentListRow row;
|
||||||
|
|
||||||
if (entry.second == "")
|
if (entry.second == "")
|
||||||
label = "<REMOVE INVALID ENTRY>";
|
label = "<CLEAR INVALID ENTRY>";
|
||||||
else
|
else
|
||||||
label = entry.second;
|
label = entry.second;
|
||||||
|
|
||||||
std::shared_ptr<TextComponent> labelText = std::make_shared<TextComponent>(
|
std::shared_ptr<TextComponent> labelText = std::make_shared<TextComponent>(
|
||||||
mWindow, label, Font::get(FONT_SIZE_MEDIUM), 0x777777FF, ALIGN_CENTER);
|
mWindow, label, Font::get(FONT_SIZE_MEDIUM), 0x777777FF, ALIGN_CENTER);
|
||||||
|
|
||||||
|
if (system->getSystemEnvData()->mLaunchCommands.front().second == label)
|
||||||
|
labelText->setValue(labelText->getValue().append(" [DEFAULT]"));
|
||||||
|
|
||||||
row.addElement(labelText, true);
|
row.addElement(labelText, true);
|
||||||
row.makeAcceptInputHandler([this, s, system, labelText, entry, selectedLabel] {
|
row.makeAcceptInputHandler([this, s, system, labelText, entry, selectedLabel] {
|
||||||
if (entry.second != selectedLabel) {
|
if (entry.second != selectedLabel) {
|
||||||
|
@ -165,9 +172,25 @@ void GuiAlternativeEmulators::selectorWindow(SystemData* system)
|
||||||
else
|
else
|
||||||
system->setAlternativeEmulator(entry.second);
|
system->setAlternativeEmulator(entry.second);
|
||||||
updateGamelist(system, true);
|
updateGamelist(system, true);
|
||||||
updateMenu(
|
|
||||||
system->getName(), labelText->getValue(),
|
if (entry.second == system->getSystemEnvData()->mLaunchCommands.front().second) {
|
||||||
(entry.second == system->getSystemEnvData()->mLaunchCommands.front().second));
|
if (system->getSystemEnvData()->mLaunchCommands.front().second == "") {
|
||||||
|
updateMenu(system->getName(), "<REMOVED ENTRY>",
|
||||||
|
(entry.second ==
|
||||||
|
system->getSystemEnvData()->mLaunchCommands.front().second));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
updateMenu(system->getName(),
|
||||||
|
system->getSystemEnvData()->mLaunchCommands.front().second,
|
||||||
|
(entry.second ==
|
||||||
|
system->getSystemEnvData()->mLaunchCommands.front().second));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
updateMenu(system->getName(), labelText->getValue(),
|
||||||
|
(entry.second ==
|
||||||
|
system->getSystemEnvData()->mLaunchCommands.front().second));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
delete s;
|
delete s;
|
||||||
});
|
});
|
||||||
|
|
|
@ -1021,16 +1021,17 @@ void GuiMenu::openOtherOptions()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Allow overriding of the launch command per game (the option to disable this is
|
// Whether to enable alternative emulators per game (the option to disable this is intended
|
||||||
// intended primarily for testing purposes).
|
// primarily for testing purposes).
|
||||||
auto launchcommand_override = std::make_shared<SwitchComponent>(mWindow);
|
auto alternativeEmulatorPerGame = std::make_shared<SwitchComponent>(mWindow);
|
||||||
launchcommand_override->setState(Settings::getInstance()->getBool("LaunchCommandOverride"));
|
alternativeEmulatorPerGame->setState(
|
||||||
s->addWithLabel("PER GAME LAUNCH COMMAND OVERRIDE", launchcommand_override);
|
Settings::getInstance()->getBool("AlternativeEmulatorPerGame"));
|
||||||
s->addSaveFunc([launchcommand_override, s] {
|
s->addWithLabel("ENABLE ALTERNATIVE EMULATORS PER GAME", alternativeEmulatorPerGame);
|
||||||
if (launchcommand_override->getState() !=
|
s->addSaveFunc([alternativeEmulatorPerGame, s] {
|
||||||
Settings::getInstance()->getBool("LaunchCommandOverride")) {
|
if (alternativeEmulatorPerGame->getState() !=
|
||||||
Settings::getInstance()->setBool("LaunchCommandOverride",
|
Settings::getInstance()->getBool("AlternativeEmulatorPerGame")) {
|
||||||
launchcommand_override->getState());
|
Settings::getInstance()->setBool("AlternativeEmulatorPerGame",
|
||||||
|
alternativeEmulatorPerGame->getState());
|
||||||
s->setNeedsSaving();
|
s->setNeedsSaving();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -49,6 +49,7 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window,
|
||||||
, mClearGameFunc(clearGameFunc)
|
, mClearGameFunc(clearGameFunc)
|
||||||
, mDeleteGameFunc(deleteGameFunc)
|
, mDeleteGameFunc(deleteGameFunc)
|
||||||
, mMediaFilesUpdated(false)
|
, mMediaFilesUpdated(false)
|
||||||
|
, mInvalidEmulatorEntry(false)
|
||||||
{
|
{
|
||||||
addChild(&mBackground);
|
addChild(&mBackground);
|
||||||
addChild(&mGrid);
|
addChild(&mGrid);
|
||||||
|
@ -99,9 +100,9 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window,
|
||||||
if (iter->isStatistic)
|
if (iter->isStatistic)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Don't show the launch command override entry if this option has been disabled.
|
// Don't show the alternative emulator entry if the corresponding option has been disabled.
|
||||||
if (!Settings::getInstance()->getBool("LaunchCommandOverride") &&
|
if (!Settings::getInstance()->getBool("AlternativeEmulatorPerGame") &&
|
||||||
iter->type == MD_LAUNCHCOMMAND) {
|
iter->type == MD_ALT_EMULATOR) {
|
||||||
ed = std::make_shared<TextComponent>(
|
ed = std::make_shared<TextComponent>(
|
||||||
window, "", Font::get(FONT_SIZE_SMALL, FONT_PATH_LIGHT), 0x777777FF, ALIGN_RIGHT);
|
window, "", Font::get(FONT_SIZE_SMALL, FONT_PATH_LIGHT), 0x777777FF, ALIGN_RIGHT);
|
||||||
assert(ed);
|
assert(ed);
|
||||||
|
@ -170,7 +171,9 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window,
|
||||||
std::placeholders::_2);
|
std::placeholders::_2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MD_LAUNCHCOMMAND: {
|
case MD_ALT_EMULATOR: {
|
||||||
|
mInvalidEmulatorEntry = false;
|
||||||
|
|
||||||
ed = std::make_shared<TextComponent>(window, "",
|
ed = std::make_shared<TextComponent>(window, "",
|
||||||
Font::get(FONT_SIZE_SMALL, FONT_PATH_LIGHT),
|
Font::get(FONT_SIZE_SMALL, FONT_PATH_LIGHT),
|
||||||
0x777777FF, ALIGN_RIGHT);
|
0x777777FF, ALIGN_RIGHT);
|
||||||
|
@ -189,44 +192,124 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window,
|
||||||
const std::string title = iter->displayPrompt;
|
const std::string title = iter->displayPrompt;
|
||||||
|
|
||||||
// OK callback (apply new value to ed).
|
// OK callback (apply new value to ed).
|
||||||
auto updateVal = [ed, originalValue](const std::string& newVal) {
|
auto updateVal = [this, ed, originalValue](const std::string& newVal) {
|
||||||
ed->setValue(newVal);
|
ed->setValue(newVal);
|
||||||
if (newVal == originalValue)
|
if (newVal == originalValue) {
|
||||||
ed->setColor(DEFAULT_TEXTCOLOR);
|
ed->setColor(DEFAULT_TEXTCOLOR);
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
ed->setColor(TEXTCOLOR_USERMARKED);
|
ed->setColor(TEXTCOLOR_USERMARKED);
|
||||||
|
mInvalidEmulatorEntry = false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string staticTextString = "Default value from es_systems.xml:";
|
if (originalValue != "" &&
|
||||||
std::string defaultLaunchCommand;
|
scraperParams.system->getLaunchCommandFromLabel(originalValue) == "") {
|
||||||
|
|
||||||
std::string alternativeEmulator = scraperParams.system->getAlternativeEmulator();
|
|
||||||
for (auto launchCommand :
|
|
||||||
scraperParams.system->getSystemEnvData()->mLaunchCommands) {
|
|
||||||
if (launchCommand.second == alternativeEmulator) {
|
|
||||||
defaultLaunchCommand = launchCommand.first;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!alternativeEmulator.empty() && defaultLaunchCommand.empty()) {
|
|
||||||
LOG(LogWarning)
|
LOG(LogWarning)
|
||||||
<< "The alternative emulator defined for system \""
|
<< "GuiMetaDataEd: Invalid alternative emulator \"" << originalValue
|
||||||
<< scraperParams.system->getName()
|
<< "\" configured for game \"" << mScraperParams.game->getName() << "\"";
|
||||||
<< "\" is invalid, falling back to the default command \""
|
mInvalidEmulatorEntry = true;
|
||||||
<< scraperParams.system->getSystemEnvData()->mLaunchCommands.front().first
|
|
||||||
<< "\"";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defaultLaunchCommand.empty())
|
if (scraperParams.system->getSystemEnvData()->mLaunchCommands.size() == 1) {
|
||||||
defaultLaunchCommand =
|
lbl->setOpacity(DISABLED_OPACITY);
|
||||||
scraperParams.system->getSystemEnvData()->mLaunchCommands.front().first;
|
bracket->setOpacity(DISABLED_OPACITY);
|
||||||
|
}
|
||||||
|
|
||||||
row.makeAcceptInputHandler([this, title, staticTextString, defaultLaunchCommand, ed,
|
if (mInvalidEmulatorEntry ||
|
||||||
updateVal, multiLine] {
|
scraperParams.system->getSystemEnvData()->mLaunchCommands.size() > 1) {
|
||||||
mWindow->pushGui(new GuiComplexTextEditPopup(
|
row.makeAcceptInputHandler([this, title, scraperParams, ed, updateVal] {
|
||||||
mWindow, getHelpStyle(), title, staticTextString, defaultLaunchCommand,
|
auto s = new GuiSettings(mWindow, title);
|
||||||
ed->getValue(), updateVal, multiLine, "APPLY", "APPLY CHANGES?"));
|
|
||||||
});
|
if (!mInvalidEmulatorEntry && ed->getValue() == "" &&
|
||||||
|
scraperParams.system->getSystemEnvData()->mLaunchCommands.size() == 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::vector<std::pair<std::string, std::string>> launchCommands =
|
||||||
|
scraperParams.system->getSystemEnvData()->mLaunchCommands;
|
||||||
|
|
||||||
|
if (ed->getValue() != "" && mInvalidEmulatorEntry)
|
||||||
|
launchCommands.push_back(std::make_pair("", "<CLEAR INVALID ENTRY>"));
|
||||||
|
else if (ed->getValue() != "")
|
||||||
|
launchCommands.push_back(std::make_pair("", "<CLEAR ENTRY>"));
|
||||||
|
|
||||||
|
for (auto entry : launchCommands) {
|
||||||
|
std::string selectedLabel = ed->getValue();
|
||||||
|
std::string label;
|
||||||
|
ComponentListRow row;
|
||||||
|
|
||||||
|
if (entry.second == "")
|
||||||
|
continue;
|
||||||
|
else
|
||||||
|
label = entry.second;
|
||||||
|
|
||||||
|
std::shared_ptr<TextComponent> labelText =
|
||||||
|
std::make_shared<TextComponent>(mWindow, label,
|
||||||
|
Font::get(FONT_SIZE_MEDIUM),
|
||||||
|
0x777777FF, ALIGN_CENTER);
|
||||||
|
|
||||||
|
if (scraperParams.system->getAlternativeEmulator() == "" &&
|
||||||
|
scraperParams.system->getSystemEnvData()
|
||||||
|
->mLaunchCommands.front()
|
||||||
|
.second == label)
|
||||||
|
labelText->setValue(labelText->getValue().append(" [SYSTEM-WIDE]"));
|
||||||
|
|
||||||
|
if (scraperParams.system->getAlternativeEmulator() == label)
|
||||||
|
labelText->setValue(labelText->getValue().append(" [SYSTEM-WIDE]"));
|
||||||
|
|
||||||
|
row.addElement(labelText, true);
|
||||||
|
row.makeAcceptInputHandler(
|
||||||
|
[this, s, updateVal, entry, selectedLabel, launchCommands] {
|
||||||
|
if (entry.second == launchCommands.back().second &&
|
||||||
|
launchCommands.back().first == "") {
|
||||||
|
updateVal("");
|
||||||
|
}
|
||||||
|
else if (entry.second != selectedLabel) {
|
||||||
|
updateVal(entry.second);
|
||||||
|
}
|
||||||
|
mInvalidEmulatorEntry = false;
|
||||||
|
delete s;
|
||||||
|
});
|
||||||
|
|
||||||
|
// This transparent bracket is only added to generate the correct help
|
||||||
|
// prompts.
|
||||||
|
auto bracket = std::make_shared<ImageComponent>(mWindow);
|
||||||
|
bracket->setImage(":/graphics/arrow.svg");
|
||||||
|
bracket->setOpacity(0);
|
||||||
|
bracket->setSize(bracket->getSize() / 3.0f);
|
||||||
|
row.addElement(bracket, false);
|
||||||
|
|
||||||
|
// Select the row that corresponds to the selected label.
|
||||||
|
if (selectedLabel == label)
|
||||||
|
s->addRow(row, true);
|
||||||
|
else
|
||||||
|
s->addRow(row, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adjust the width depending on the aspect ratio of the screen, to make the
|
||||||
|
// screen look somewhat coherent regardless of screen type. The 1.778 aspect
|
||||||
|
// ratio value is the 16:9 reference.
|
||||||
|
float aspectValue = 1.778f / Renderer::getScreenAspectRatio();
|
||||||
|
|
||||||
|
float maxWidthModifier = glm::clamp(0.70f * aspectValue, 0.50f, 0.92f);
|
||||||
|
float maxWidth =
|
||||||
|
static_cast<float>(Renderer::getScreenWidth()) * maxWidthModifier;
|
||||||
|
|
||||||
|
s->setMenuSize(glm::vec2{maxWidth, s->getMenuSize().y});
|
||||||
|
|
||||||
|
auto menuSize = s->getMenuSize();
|
||||||
|
auto menuPos = s->getMenuPosition();
|
||||||
|
|
||||||
|
s->setMenuPosition(glm::vec3{(s->getSize().x - menuSize.x) / 2.0f,
|
||||||
|
(s->getSize().y - menuSize.y) / 3.0f,
|
||||||
|
menuPos.z});
|
||||||
|
mWindow->pushGui(s);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lbl->setOpacity(DISABLED_OPACITY);
|
||||||
|
bracket->setOpacity(DISABLED_OPACITY);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MD_MULTILINE_STRING:
|
case MD_MULTILINE_STRING:
|
||||||
|
@ -292,7 +375,12 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window,
|
||||||
|
|
||||||
assert(ed);
|
assert(ed);
|
||||||
mList->addRow(row);
|
mList->addRow(row);
|
||||||
ed->setValue(mMetaData->get(iter->key));
|
|
||||||
|
if (iter->type == MD_ALT_EMULATOR && mInvalidEmulatorEntry == true)
|
||||||
|
ed->setValue(ViewController::EXCLAMATION_CHAR + " INVALID ENTRY ");
|
||||||
|
else
|
||||||
|
ed->setValue(mMetaData->get(iter->key));
|
||||||
|
|
||||||
mEditors.push_back(ed);
|
mEditors.push_back(ed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,6 +523,9 @@ void GuiMetaDataEd::save()
|
||||||
if (mMetaDataDecl.at(i).isStatistic)
|
if (mMetaDataDecl.at(i).isStatistic)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (mMetaDataDecl.at(i).key == "altemulator" && mInvalidEmulatorEntry == true)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!showHiddenGames && mMetaDataDecl.at(i).key == "hidden" &&
|
if (!showHiddenGames && mMetaDataDecl.at(i).key == "hidden" &&
|
||||||
mEditors.at(i)->getValue() != mMetaData->get("hidden"))
|
mEditors.at(i)->getValue() != mMetaData->get("hidden"))
|
||||||
hideGameWhileHidden = true;
|
hideGameWhileHidden = true;
|
||||||
|
@ -576,6 +667,9 @@ void GuiMetaDataEd::close()
|
||||||
std::string mMetaDataValue = mMetaData->get(key);
|
std::string mMetaDataValue = mMetaData->get(key);
|
||||||
std::string mEditorsValue = mEditors.at(i)->getValue();
|
std::string mEditorsValue = mEditors.at(i)->getValue();
|
||||||
|
|
||||||
|
if (key == "altemulator" && mInvalidEmulatorEntry == true)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (mMetaDataValue != mEditorsValue) {
|
if (mMetaDataValue != mEditorsValue) {
|
||||||
metadataUpdated = true;
|
metadataUpdated = true;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "MetaData.h"
|
#include "MetaData.h"
|
||||||
#include "components/ComponentGrid.h"
|
#include "components/ComponentGrid.h"
|
||||||
#include "components/NinePatchComponent.h"
|
#include "components/NinePatchComponent.h"
|
||||||
|
#include "guis/GuiSettings.h"
|
||||||
#include "scrapers/Scraper.h"
|
#include "scrapers/Scraper.h"
|
||||||
|
|
||||||
class ComponentList;
|
class ComponentList;
|
||||||
|
@ -64,6 +65,7 @@ private:
|
||||||
std::function<void()> mDeleteGameFunc;
|
std::function<void()> mDeleteGameFunc;
|
||||||
|
|
||||||
bool mMediaFilesUpdated;
|
bool mMediaFilesUpdated;
|
||||||
|
bool mInvalidEmulatorEntry;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ES_APP_GUIS_GUI_META_DATA_ED_H
|
#endif // ES_APP_GUIS_GUI_META_DATA_ED_H
|
||||||
|
|
|
@ -617,7 +617,7 @@ int main(int argc, char* argv[])
|
||||||
// which means that a label is present in the gamelist.xml file which is not matching
|
// which means that a label is present in the gamelist.xml file which is not matching
|
||||||
// any command tag in es_systems.xml.
|
// any command tag in es_systems.xml.
|
||||||
for (auto system : SystemData::sSystemVector) {
|
for (auto system : SystemData::sSystemVector) {
|
||||||
if (system->getAlternativeEmulator() == "<INVALID>") {
|
if (system->getAlternativeEmulator().substr(0, 9) == "<INVALID>") {
|
||||||
ViewController::get()->invalidAlternativeEmulatorDialog();
|
ViewController::get()->invalidAlternativeEmulatorDialog();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -205,7 +205,7 @@ void ViewController::invalidAlternativeEmulatorDialog()
|
||||||
"WITH NO MATCHING ENTRY IN THE SYSTEMS\n"
|
"WITH NO MATCHING ENTRY IN THE SYSTEMS\n"
|
||||||
"CONFIGURATION FILE, PLEASE REVIEW YOUR\n"
|
"CONFIGURATION FILE, PLEASE REVIEW YOUR\n"
|
||||||
"SETUP USING THE 'ALTERNATIVE EMULATORS'\n"
|
"SETUP USING THE 'ALTERNATIVE EMULATORS'\n"
|
||||||
"ENTRY UNDER THE 'OTHER SETTINGS' MENU"));
|
"INTERFACE IN THE 'OTHER SETTINGS' MENU"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewController::goToStart()
|
void ViewController::goToStart()
|
||||||
|
|
|
@ -240,7 +240,7 @@ void Settings::setDefaults()
|
||||||
mBoolMap["VideoHardwareDecoding"] = {false, false};
|
mBoolMap["VideoHardwareDecoding"] = {false, false};
|
||||||
#endif
|
#endif
|
||||||
mBoolMap["VideoUpscaleFrameRate"] = {false, false};
|
mBoolMap["VideoUpscaleFrameRate"] = {false, false};
|
||||||
mBoolMap["LaunchCommandOverride"] = {true, true};
|
mBoolMap["AlternativeEmulatorPerGame"] = {true, true};
|
||||||
mBoolMap["ShowHiddenFiles"] = {true, true};
|
mBoolMap["ShowHiddenFiles"] = {true, true};
|
||||||
mBoolMap["ShowHiddenGames"] = {true, true};
|
mBoolMap["ShowHiddenGames"] = {true, true};
|
||||||
mBoolMap["CustomEventScripts"] = {false, false};
|
mBoolMap["CustomEventScripts"] = {false, false};
|
||||||
|
|
Loading…
Reference in a new issue