mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-25 07:35: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,35 +748,40 @@ void FileData::launchGame(Window* window)
|
|||
LOG(LogInfo) << "Launching game \"" << this->metadata.get("name") << "\"...";
|
||||
|
||||
std::string command = "";
|
||||
std::string alternativeEmulator = getSystem()->getAlternativeEmulator();
|
||||
|
||||
// Check if there is a launch command override for the game
|
||||
// and the corresponding option to use it has been set.
|
||||
if (Settings::getInstance()->getBool("LaunchCommandOverride") &&
|
||||
!metadata.get("launchcommand").empty()) {
|
||||
command = metadata.get("launchcommand");
|
||||
// Check if there is a game-specific alternative emulator configured.
|
||||
// This takes precedence over any system-wide alternative emulator configuration.
|
||||
if (Settings::getInstance()->getBool("AlternativeEmulatorPerGame") &&
|
||||
!metadata.get("altemulator").empty()) {
|
||||
command = getSystem()->getLaunchCommandFromLabel(metadata.get("altemulator"));
|
||||
if (command == "") {
|
||||
LOG(LogWarning) << "Invalid alternative emulator \"" << metadata.get("altemulator")
|
||||
<< "\" configured for 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;
|
||||
<< metadata.get("altemulator") << "\" as configured for the game";
|
||||
}
|
||||
}
|
||||
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
|
||||
<< "\"";
|
||||
|
||||
// Check if there is a system-wide alternative emulator configured.
|
||||
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;
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ void parseGamelist(SystemData* system)
|
|||
<< "\" has a valid alternativeEmulator entry: \"" << label << "\"";
|
||||
}
|
||||
else {
|
||||
system->setAlternativeEmulator("<INVALID>");
|
||||
system->setAlternativeEmulator("<INVALID>" + label);
|
||||
LOG(LogWarning) << "System \"" << system->getName()
|
||||
<< "\" has an invalid alternativeEmulator entry that does "
|
||||
"not match any command tag in es_systems.xml: \""
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include <pugixml.hpp>
|
||||
|
||||
// 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[] = {
|
||||
// key, type, default, statistic, name in GuiMetaDataEd, prompt in GuiMetaDataEd, shouldScrape
|
||||
{"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},
|
||||
{"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},
|
||||
{"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},
|
||||
{"altemulator", MD_ALT_EMULATOR, "", false, "alternative emulator", "select alternative emulator", false},
|
||||
{"lastplayed", MD_TIME, "0", true, "last played", "enter last played date", false}
|
||||
};
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ enum MetaDataType {
|
|||
|
||||
// Specialized types.
|
||||
MD_MULTILINE_STRING,
|
||||
MD_LAUNCHCOMMAND,
|
||||
MD_ALT_EMULATOR,
|
||||
MD_PATH,
|
||||
MD_RATING,
|
||||
MD_DATE,
|
||||
|
|
|
@ -501,8 +501,7 @@ bool SystemData::loadConfig()
|
|||
}
|
||||
else if (!commands.empty() && commands.back().second == "") {
|
||||
// There are more than one command tags and the first tag did not have a label.
|
||||
LOG(LogError)
|
||||
<< "Missing mandatory label attribute for alternative emulator "
|
||||
LOG(LogError) << "Missing mandatory label attribute for alternative emulator "
|
||||
"entry, only the first command tag will be processed for system \""
|
||||
<< name << "\"";
|
||||
break;
|
||||
|
@ -615,6 +614,18 @@ bool SystemData::loadConfig()
|
|||
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()
|
||||
{
|
||||
for (unsigned int i = 0; i < sSystemVector.size(); i++)
|
||||
|
|
|
@ -99,6 +99,7 @@ public:
|
|||
|
||||
std::string getAlternativeEmulator() { return mAlternativeEmulator; }
|
||||
void setAlternativeEmulator(const std::string& command) { mAlternativeEmulator = command; }
|
||||
std::string getLaunchCommandFromLabel(const std::string& label);
|
||||
|
||||
static void deleteSystems();
|
||||
// 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
|
||||
// has an invalid entry.
|
||||
if ((*it)->getAlternativeEmulator() != "<INVALID>" &&
|
||||
if ((*it)->getAlternativeEmulator().substr(0, 9) != "<INVALID>" &&
|
||||
(*it)->getSystemEnvData()->mLaunchCommands.size() < 2)
|
||||
continue;
|
||||
|
||||
|
@ -68,7 +68,7 @@ GuiAlternativeEmulators::GuiAlternativeEmulators(Window* window)
|
|||
bool invalidEntry = false;
|
||||
|
||||
if (label.empty()) {
|
||||
label = "<INVALID ENTRY>";
|
||||
label = ViewController::EXCLAMATION_CHAR + " INVALID ENTRY";
|
||||
invalidEntry = true;
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,11 @@ GuiAlternativeEmulators::GuiAlternativeEmulators(Window* window)
|
|||
labelText->setSize(labelSizeX, labelText->getSize().y);
|
||||
|
||||
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);
|
||||
mHasSystems = true;
|
||||
|
@ -104,8 +108,8 @@ GuiAlternativeEmulators::GuiAlternativeEmulators(Window* window)
|
|||
// es_systems.xml.
|
||||
if (!mHasSystems) {
|
||||
ComponentListRow row;
|
||||
std::shared_ptr<TextComponent> systemText =
|
||||
std::make_shared<TextComponent>(mWindow, "<NO ALTERNATIVE EMULATORS DEFINED>",
|
||||
std::shared_ptr<TextComponent> systemText = std::make_shared<TextComponent>(
|
||||
mWindow, ViewController::EXCLAMATION_CHAR + " NO ALTERNATIVE EMULATORS DEFINED",
|
||||
Font::get(FONT_SIZE_MEDIUM), 0x777777FF, ALIGN_CENTER);
|
||||
row.addElement(systemText, true);
|
||||
mMenu.addRow(row);
|
||||
|
@ -150,13 +154,16 @@ void GuiAlternativeEmulators::selectorWindow(SystemData* system)
|
|||
ComponentListRow row;
|
||||
|
||||
if (entry.second == "")
|
||||
label = "<REMOVE INVALID ENTRY>";
|
||||
label = "<CLEAR INVALID ENTRY>";
|
||||
else
|
||||
label = entry.second;
|
||||
|
||||
std::shared_ptr<TextComponent> labelText = std::make_shared<TextComponent>(
|
||||
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.makeAcceptInputHandler([this, s, system, labelText, entry, selectedLabel] {
|
||||
if (entry.second != selectedLabel) {
|
||||
|
@ -165,9 +172,25 @@ void GuiAlternativeEmulators::selectorWindow(SystemData* system)
|
|||
else
|
||||
system->setAlternativeEmulator(entry.second);
|
||||
updateGamelist(system, true);
|
||||
updateMenu(
|
||||
system->getName(), labelText->getValue(),
|
||||
(entry.second == system->getSystemEnvData()->mLaunchCommands.front().second));
|
||||
|
||||
if (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;
|
||||
});
|
||||
|
|
|
@ -1021,16 +1021,17 @@ void GuiMenu::openOtherOptions()
|
|||
}
|
||||
});
|
||||
|
||||
// Allow overriding of the launch command per game (the option to disable this is
|
||||
// intended primarily for testing purposes).
|
||||
auto launchcommand_override = std::make_shared<SwitchComponent>(mWindow);
|
||||
launchcommand_override->setState(Settings::getInstance()->getBool("LaunchCommandOverride"));
|
||||
s->addWithLabel("PER GAME LAUNCH COMMAND OVERRIDE", launchcommand_override);
|
||||
s->addSaveFunc([launchcommand_override, s] {
|
||||
if (launchcommand_override->getState() !=
|
||||
Settings::getInstance()->getBool("LaunchCommandOverride")) {
|
||||
Settings::getInstance()->setBool("LaunchCommandOverride",
|
||||
launchcommand_override->getState());
|
||||
// Whether to enable alternative emulators per game (the option to disable this is intended
|
||||
// primarily for testing purposes).
|
||||
auto alternativeEmulatorPerGame = std::make_shared<SwitchComponent>(mWindow);
|
||||
alternativeEmulatorPerGame->setState(
|
||||
Settings::getInstance()->getBool("AlternativeEmulatorPerGame"));
|
||||
s->addWithLabel("ENABLE ALTERNATIVE EMULATORS PER GAME", alternativeEmulatorPerGame);
|
||||
s->addSaveFunc([alternativeEmulatorPerGame, s] {
|
||||
if (alternativeEmulatorPerGame->getState() !=
|
||||
Settings::getInstance()->getBool("AlternativeEmulatorPerGame")) {
|
||||
Settings::getInstance()->setBool("AlternativeEmulatorPerGame",
|
||||
alternativeEmulatorPerGame->getState());
|
||||
s->setNeedsSaving();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -49,6 +49,7 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window,
|
|||
, mClearGameFunc(clearGameFunc)
|
||||
, mDeleteGameFunc(deleteGameFunc)
|
||||
, mMediaFilesUpdated(false)
|
||||
, mInvalidEmulatorEntry(false)
|
||||
{
|
||||
addChild(&mBackground);
|
||||
addChild(&mGrid);
|
||||
|
@ -99,9 +100,9 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window,
|
|||
if (iter->isStatistic)
|
||||
continue;
|
||||
|
||||
// Don't show the launch command override entry if this option has been disabled.
|
||||
if (!Settings::getInstance()->getBool("LaunchCommandOverride") &&
|
||||
iter->type == MD_LAUNCHCOMMAND) {
|
||||
// Don't show the alternative emulator entry if the corresponding option has been disabled.
|
||||
if (!Settings::getInstance()->getBool("AlternativeEmulatorPerGame") &&
|
||||
iter->type == MD_ALT_EMULATOR) {
|
||||
ed = std::make_shared<TextComponent>(
|
||||
window, "", Font::get(FONT_SIZE_SMALL, FONT_PATH_LIGHT), 0x777777FF, ALIGN_RIGHT);
|
||||
assert(ed);
|
||||
|
@ -170,7 +171,9 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window,
|
|||
std::placeholders::_2);
|
||||
break;
|
||||
}
|
||||
case MD_LAUNCHCOMMAND: {
|
||||
case MD_ALT_EMULATOR: {
|
||||
mInvalidEmulatorEntry = false;
|
||||
|
||||
ed = std::make_shared<TextComponent>(window, "",
|
||||
Font::get(FONT_SIZE_SMALL, FONT_PATH_LIGHT),
|
||||
0x777777FF, ALIGN_RIGHT);
|
||||
|
@ -189,44 +192,124 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window,
|
|||
const std::string title = iter->displayPrompt;
|
||||
|
||||
// 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);
|
||||
if (newVal == originalValue)
|
||||
if (newVal == originalValue) {
|
||||
ed->setColor(DEFAULT_TEXTCOLOR);
|
||||
else
|
||||
}
|
||||
else {
|
||||
ed->setColor(TEXTCOLOR_USERMARKED);
|
||||
mInvalidEmulatorEntry = false;
|
||||
}
|
||||
};
|
||||
|
||||
std::string staticTextString = "Default value from es_systems.xml:";
|
||||
std::string defaultLaunchCommand;
|
||||
|
||||
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()) {
|
||||
if (originalValue != "" &&
|
||||
scraperParams.system->getLaunchCommandFromLabel(originalValue) == "") {
|
||||
LOG(LogWarning)
|
||||
<< "The alternative emulator defined for system \""
|
||||
<< scraperParams.system->getName()
|
||||
<< "\" is invalid, falling back to the default command \""
|
||||
<< scraperParams.system->getSystemEnvData()->mLaunchCommands.front().first
|
||||
<< "\"";
|
||||
<< "GuiMetaDataEd: Invalid alternative emulator \"" << originalValue
|
||||
<< "\" configured for game \"" << mScraperParams.game->getName() << "\"";
|
||||
mInvalidEmulatorEntry = true;
|
||||
}
|
||||
|
||||
if (defaultLaunchCommand.empty())
|
||||
defaultLaunchCommand =
|
||||
scraperParams.system->getSystemEnvData()->mLaunchCommands.front().first;
|
||||
if (scraperParams.system->getSystemEnvData()->mLaunchCommands.size() == 1) {
|
||||
lbl->setOpacity(DISABLED_OPACITY);
|
||||
bracket->setOpacity(DISABLED_OPACITY);
|
||||
}
|
||||
|
||||
row.makeAcceptInputHandler([this, title, staticTextString, defaultLaunchCommand, ed,
|
||||
updateVal, multiLine] {
|
||||
mWindow->pushGui(new GuiComplexTextEditPopup(
|
||||
mWindow, getHelpStyle(), title, staticTextString, defaultLaunchCommand,
|
||||
ed->getValue(), updateVal, multiLine, "APPLY", "APPLY CHANGES?"));
|
||||
if (mInvalidEmulatorEntry ||
|
||||
scraperParams.system->getSystemEnvData()->mLaunchCommands.size() > 1) {
|
||||
row.makeAcceptInputHandler([this, title, scraperParams, ed, updateVal] {
|
||||
auto s = new GuiSettings(mWindow, title);
|
||||
|
||||
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;
|
||||
}
|
||||
case MD_MULTILINE_STRING:
|
||||
|
@ -292,7 +375,12 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window,
|
|||
|
||||
assert(ed);
|
||||
mList->addRow(row);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -435,6 +523,9 @@ void GuiMetaDataEd::save()
|
|||
if (mMetaDataDecl.at(i).isStatistic)
|
||||
continue;
|
||||
|
||||
if (mMetaDataDecl.at(i).key == "altemulator" && mInvalidEmulatorEntry == true)
|
||||
continue;
|
||||
|
||||
if (!showHiddenGames && mMetaDataDecl.at(i).key == "hidden" &&
|
||||
mEditors.at(i)->getValue() != mMetaData->get("hidden"))
|
||||
hideGameWhileHidden = true;
|
||||
|
@ -576,6 +667,9 @@ void GuiMetaDataEd::close()
|
|||
std::string mMetaDataValue = mMetaData->get(key);
|
||||
std::string mEditorsValue = mEditors.at(i)->getValue();
|
||||
|
||||
if (key == "altemulator" && mInvalidEmulatorEntry == true)
|
||||
continue;
|
||||
|
||||
if (mMetaDataValue != mEditorsValue) {
|
||||
metadataUpdated = true;
|
||||
break;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "MetaData.h"
|
||||
#include "components/ComponentGrid.h"
|
||||
#include "components/NinePatchComponent.h"
|
||||
#include "guis/GuiSettings.h"
|
||||
#include "scrapers/Scraper.h"
|
||||
|
||||
class ComponentList;
|
||||
|
@ -64,6 +65,7 @@ private:
|
|||
std::function<void()> mDeleteGameFunc;
|
||||
|
||||
bool mMediaFilesUpdated;
|
||||
bool mInvalidEmulatorEntry;
|
||||
};
|
||||
|
||||
#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
|
||||
// any command tag in es_systems.xml.
|
||||
for (auto system : SystemData::sSystemVector) {
|
||||
if (system->getAlternativeEmulator() == "<INVALID>") {
|
||||
if (system->getAlternativeEmulator().substr(0, 9) == "<INVALID>") {
|
||||
ViewController::get()->invalidAlternativeEmulatorDialog();
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -205,7 +205,7 @@ void ViewController::invalidAlternativeEmulatorDialog()
|
|||
"WITH NO MATCHING ENTRY IN THE SYSTEMS\n"
|
||||
"CONFIGURATION FILE, PLEASE REVIEW YOUR\n"
|
||||
"SETUP USING THE 'ALTERNATIVE EMULATORS'\n"
|
||||
"ENTRY UNDER THE 'OTHER SETTINGS' MENU"));
|
||||
"INTERFACE IN THE 'OTHER SETTINGS' MENU"));
|
||||
}
|
||||
|
||||
void ViewController::goToStart()
|
||||
|
|
|
@ -240,7 +240,7 @@ void Settings::setDefaults()
|
|||
mBoolMap["VideoHardwareDecoding"] = {false, false};
|
||||
#endif
|
||||
mBoolMap["VideoUpscaleFrameRate"] = {false, false};
|
||||
mBoolMap["LaunchCommandOverride"] = {true, true};
|
||||
mBoolMap["AlternativeEmulatorPerGame"] = {true, true};
|
||||
mBoolMap["ShowHiddenFiles"] = {true, true};
|
||||
mBoolMap["ShowHiddenGames"] = {true, true};
|
||||
mBoolMap["CustomEventScripts"] = {false, false};
|
||||
|
|
Loading…
Reference in a new issue