diff options
-rw-r--r-- | scripts/src/emu.lua | 2 | ||||
-rw-r--r-- | src/emu/clifront.cpp | 1 | ||||
-rw-r--r-- | src/emu/emuopts.cpp | 418 | ||||
-rw-r--r-- | src/emu/emuopts.h | 56 | ||||
-rw-r--r-- | src/emu/info.cpp | 1 | ||||
-rw-r--r-- | src/emu/mame.cpp | 1 | ||||
-rw-r--r-- | src/emu/mameopts.cpp | 426 | ||||
-rw-r--r-- | src/emu/mameopts.h | 78 | ||||
-rw-r--r-- | src/emu/ui/miscmenu.cpp | 1 | ||||
-rw-r--r-- | src/emu/ui/optsmenu.cpp | 1 | ||||
-rw-r--r-- | src/emu/ui/slotopt.cpp | 1 | ||||
-rw-r--r-- | src/emu/ui/ui.cpp | 1 |
12 files changed, 514 insertions, 473 deletions
diff --git a/scripts/src/emu.lua b/scripts/src/emu.lua index b0dc5eee8d6..792b422785e 100644 --- a/scripts/src/emu.lua +++ b/scripts/src/emu.lua @@ -154,6 +154,8 @@ files { MAME_DIR .. "src/emu/language.h", MAME_DIR .. "src/emu/mame.cpp", MAME_DIR .. "src/emu/mame.h", + MAME_DIR .. "src/emu/mameopts.cpp", + MAME_DIR .. "src/emu/mameopts.h", MAME_DIR .. "src/emu/machine.cpp", MAME_DIR .. "src/emu/machine.h", MAME_DIR .. "src/emu/mconfig.cpp", diff --git a/src/emu/clifront.cpp b/src/emu/clifront.cpp index 49097f2c016..bbb5a800b00 100644 --- a/src/emu/clifront.cpp +++ b/src/emu/clifront.cpp @@ -11,6 +11,7 @@ #include "emu.h" #include "chd.h" #include "emuopts.h" +#include "mameopts.h" #include "jedparse.h" #include "audit.h" #include "info.h" diff --git a/src/emu/emuopts.cpp b/src/emu/emuopts.cpp index 6e8f267d117..9cf84a3a6eb 100644 --- a/src/emu/emuopts.cpp +++ b/src/emu/emuopts.cpp @@ -11,11 +11,6 @@ #include "emu.h" #include "emuopts.h" #include "drivenum.h" -#include "softlist.h" - -#include <ctype.h> - - //************************************************************************** // CORE EMULATOR OPTIONS @@ -283,416 +278,3 @@ void emu_options::update_cached_options() m_sleep = bool_value(OPTION_SLEEP); m_refresh_speed = bool_value(OPTION_REFRESHSPEED); } - - - - -int mame_options::m_slot_options = 0; -int mame_options::m_device_options = 0; - -//------------------------------------------------- -// add_slot_options - add all of the slot -// options for the configured system -//------------------------------------------------- - -bool mame_options::add_slot_options(emu_options &options, const software_part *swpart) -{ - // look up the system configured by name; if no match, do nothing - const game_driver *cursystem = options.system(); - if (cursystem == nullptr) - return false; - - // create the configuration - machine_config config(*cursystem, options); - - // iterate through all slot devices - int starting_count = options.options_count(); - for (const device_slot_interface &slot : slot_interface_iterator(config.root_device())) - { - // skip fixed slots - if (slot.fixed()) - continue; - - // retrieve info about the device instance - const char *name = slot.device().tag() + 1; - if (!options.exists(name)) - { - // first device? add the header as to be pretty - if (m_slot_options++ == 0) - options.add_entry(nullptr, "SLOT DEVICES", OPTION_HEADER | OPTION_FLAG_DEVICE); - - // add the option - options.add_entry(name, nullptr, OPTION_STRING | OPTION_FLAG_DEVICE, slot.default_option(), true); - } - - // allow software lists to supply their own defaults - if (swpart != nullptr) - { - std::string featurename = std::string(name).append("_default"); - const char *value = swpart->feature(featurename.c_str()); - if (value != nullptr && (*value == '\0' || slot.option(value) != nullptr)) - { - // set priority above INIs but below actual command line - std::string error; - options.set_value(name, value, OPTION_PRIORITY_SUBCMD, error); - } - } - } - return (options.options_count() != starting_count); -} - - -//------------------------------------------------- -// update_slot_options - update slot values -// depending of image mounted -//------------------------------------------------- - -void mame_options::update_slot_options(emu_options &options, const software_part *swpart) -{ - // look up the system configured by name; if no match, do nothing - const game_driver *cursystem = options.system(); - if (cursystem == nullptr) - return; - machine_config config(*cursystem, options); - - // iterate through all slot devices - for (device_slot_interface &slot : slot_interface_iterator(config.root_device())) - { - // retrieve info about the device instance - const char *name = slot.device().tag() + 1; - if (options.exists(name) && !slot.option_list().empty()) - { - std::string defvalue = slot.get_default_card_software(); - if (defvalue.empty()) - { - // keep any non-default setting - if (options.priority(name) > OPTION_PRIORITY_DEFAULT) - continue; - - // reinstate the actual default value as configured - if (slot.default_option() != nullptr) - defvalue.assign(slot.default_option()); - } - - // set the value and hide the option if not selectable - options.set_default_value(name, defvalue.c_str()); - const device_slot_option *option = slot.option(defvalue.c_str()); - options.set_flag(name, ~OPTION_FLAG_INTERNAL, (option != nullptr && !option->selectable()) ? OPTION_FLAG_INTERNAL : 0); - } - } - while (add_slot_options(options,swpart)) {} - add_device_options(options); -} - - -//------------------------------------------------- -// add_device_options - add all of the device -// options for the configured system -//------------------------------------------------- - -void mame_options::add_device_options(emu_options &options) -{ - // look up the system configured by name; if no match, do nothing - const game_driver *cursystem = options.system(); - if (cursystem == nullptr) - return; - machine_config config(*cursystem, options); - - // iterate through all image devices - for (const device_image_interface &image : image_interface_iterator(config.root_device())) - { - if (!image.user_loadable()) - continue; - - // retrieve info about the device instance - std::ostringstream option_name; - util::stream_format(option_name, "%s;%s", image.instance_name(), image.brief_instance_name()); - if (strcmp(image.device_typename(image.image_type()), image.instance_name()) == 0) - util::stream_format(option_name, ";%s1;%s1", image.instance_name(), image.brief_instance_name()); - - // add the option - if (!options.exists(image.instance_name())) - { - // first device? add the header as to be pretty - if (m_device_options++ == 0) - options.add_entry(nullptr, "IMAGE DEVICES", OPTION_HEADER | OPTION_FLAG_DEVICE); - - // add the option - options.add_entry(option_name.str().c_str(), nullptr, OPTION_STRING | OPTION_FLAG_DEVICE, nullptr, true); - } - } -} - - -//------------------------------------------------- -// remove_device_options - remove device options -//------------------------------------------------- - -void mame_options::remove_device_options(emu_options &options) -{ - // iterate through options and remove interesting ones - core_options::entry *nextentry; - for (auto *curentry = options.first(); curentry != nullptr; curentry = nextentry) - { - // pre-fetch the next entry in case we delete this one - nextentry = curentry->next(); - - // if this is a device option, nuke it - if ((curentry->flags() & OPTION_FLAG_DEVICE) != 0) - options.remove_entry(*curentry); - } - - // take also care of ramsize options - options.set_default_value(OPTION_RAMSIZE, ""); - - // reset counters - m_slot_options = 0; - m_device_options = 0; -} - - -//------------------------------------------------- -// parse_slot_devices - parse the command line -// and update slot and image devices -//------------------------------------------------- - -bool mame_options::parse_slot_devices(emu_options &options, int argc, char *argv[], std::string &error_string, const char *name, const char *value, const software_part *swpart) -{ - // an initial parse to capture the initial set of values - bool result; - - options.parse_command_line(argc, argv, OPTION_PRIORITY_CMDLINE, error_string); - - // keep adding slot options until we stop seeing new stuff - while (add_slot_options(options,swpart)) - options.parse_command_line(argc, argv, OPTION_PRIORITY_CMDLINE, error_string); - - // add device options and reparse - add_device_options(options); - if (name != nullptr && options.exists(name)) - options.set_value(name, value, OPTION_PRIORITY_SUBCMD, error_string); - options.parse_command_line(argc, argv, OPTION_PRIORITY_CMDLINE, error_string); - - int num; - do { - num = options.options_count(); - update_slot_options(options,swpart); - result = options.parse_command_line(argc, argv, OPTION_PRIORITY_CMDLINE, error_string); - } while (num != options.options_count()); - - options.update_cached_options(); - - return result; -} - - -//------------------------------------------------- -// parse_command_line - parse the command line -// and update the devices -//------------------------------------------------- - -bool mame_options::parse_command_line(emu_options &options, int argc, char *argv[], std::string &error_string) -{ - // parse as normal - options.parse_command_line(argc, argv, OPTION_PRIORITY_CMDLINE, error_string); - bool result = parse_slot_devices(options,argc, argv, error_string); - options.update_cached_options(); - return result; -} - - -//------------------------------------------------- -// parse_standard_inis - parse the standard set -// of INI files -//------------------------------------------------- - -void mame_options::parse_standard_inis(emu_options &options, std::string &error_string, const game_driver *driver) -{ - // start with an empty string - error_string.clear(); - - // parse the INI file defined by the platform (e.g., "mame.ini") - // we do this twice so that the first file can change the INI path - parse_one_ini(options,emulator_info::get_configname(), OPTION_PRIORITY_MAME_INI); - parse_one_ini(options,emulator_info::get_configname(), OPTION_PRIORITY_MAME_INI, &error_string); - - // debug mode: parse "debug.ini" as well - if (options.debug()) - parse_one_ini(options,"debug", OPTION_PRIORITY_DEBUG_INI, &error_string); - - // if we have a valid system driver, parse system-specific INI files - const game_driver *cursystem = (driver == nullptr) ? options.system() : driver; - if (cursystem == nullptr) - return; - - // parse "vertical.ini" or "horizont.ini" - if (cursystem->flags & ORIENTATION_SWAP_XY) - parse_one_ini(options,"vertical", OPTION_PRIORITY_ORIENTATION_INI, &error_string); - else - parse_one_ini(options,"horizont", OPTION_PRIORITY_ORIENTATION_INI, &error_string); - - if (cursystem->flags & MACHINE_TYPE_ARCADE) - parse_one_ini(options,"arcade", OPTION_PRIORITY_SYSTYPE_INI, &error_string); - else if (cursystem->flags & MACHINE_TYPE_CONSOLE) - parse_one_ini(options,"console", OPTION_PRIORITY_SYSTYPE_INI, &error_string); - else if (cursystem->flags & MACHINE_TYPE_COMPUTER) - parse_one_ini(options,"computer", OPTION_PRIORITY_SYSTYPE_INI, &error_string); - else if (cursystem->flags & MACHINE_TYPE_OTHER) - parse_one_ini(options,"othersys", OPTION_PRIORITY_SYSTYPE_INI, &error_string); - - machine_config config(*cursystem, options); - for (const screen_device &device : screen_device_iterator(config.root_device())) - { - // parse "raster.ini" for raster games - if (device.screen_type() == SCREEN_TYPE_RASTER) - { - parse_one_ini(options,"raster", OPTION_PRIORITY_SCREEN_INI, &error_string); - break; - } - // parse "vector.ini" for vector games - if (device.screen_type() == SCREEN_TYPE_VECTOR) - { - parse_one_ini(options,"vector", OPTION_PRIORITY_SCREEN_INI, &error_string); - break; - } - // parse "lcd.ini" for lcd games - if (device.screen_type() == SCREEN_TYPE_LCD) - { - parse_one_ini(options,"lcd", OPTION_PRIORITY_SCREEN_INI, &error_string); - break; - } - } - - // next parse "source/<sourcefile>.ini"; if that doesn't exist, try <sourcefile>.ini - std::string sourcename = core_filename_extract_base(cursystem->source_file, true).insert(0, "source" PATH_SEPARATOR); - if (!parse_one_ini(options,sourcename.c_str(), OPTION_PRIORITY_SOURCE_INI, &error_string)) - { - sourcename = core_filename_extract_base(cursystem->source_file, true); - parse_one_ini(options,sourcename.c_str(), OPTION_PRIORITY_SOURCE_INI, &error_string); - } - - // then parse the grandparent, parent, and system-specific INIs - int parent = driver_list::clone(*cursystem); - int gparent = (parent != -1) ? driver_list::clone(parent) : -1; - if (gparent != -1) - parse_one_ini(options,driver_list::driver(gparent).name, OPTION_PRIORITY_GPARENT_INI, &error_string); - if (parent != -1) - parse_one_ini(options,driver_list::driver(parent).name, OPTION_PRIORITY_PARENT_INI, &error_string); - parse_one_ini(options,cursystem->name, OPTION_PRIORITY_DRIVER_INI, &error_string); - - // Re-evaluate slot options after loading ini files - update_slot_options(options); - - options.update_cached_options(); -} - -//------------------------------------------------- -// set_system_name - set a new system name -//------------------------------------------------- - -void mame_options::set_system_name(emu_options &options, const char *name) -{ - // remember the original system name - std::string old_system_name(options.system_name()); - bool new_system = old_system_name.compare(name) != 0; - - // if the system name changed, fix up the device options - if (new_system) - { - // first set the new name - std::string error; - options.set_value(OPTION_SYSTEMNAME, name, OPTION_PRIORITY_CMDLINE, error); - assert(error.empty()); - - // remove any existing device options - remove_device_options(options); - } - else - { - // revert device options set for the old software - options.revert(OPTION_PRIORITY_SUBCMD, OPTION_PRIORITY_SUBCMD); - } - - // get the new system - const game_driver *cursystem = options.system(); - if (cursystem == nullptr) - return; - - if (*options.software_name() != 0) - { - std::string sw_load(options.software_name()); - std::string sw_list, sw_name, sw_part, sw_instance, error_string; - int left = sw_load.find_first_of(':'); - int middle = sw_load.find_first_of(':', left + 1); - int right = sw_load.find_last_of(':'); - - sw_list = sw_load.substr(0, left - 1); - sw_name = sw_load.substr(left + 1, middle - left - 1); - sw_part = sw_load.substr(middle + 1, right - middle - 1); - sw_instance = sw_load.substr(right + 1); - sw_load.assign(sw_load.substr(0, right)); - - // look up the software part - machine_config config(*cursystem, options); - software_list_device *swlist = software_list_device::find_by_name(config, sw_list.c_str()); - software_info *swinfo = swlist != nullptr ? swlist->find(sw_name.c_str()) : nullptr; - software_part *swpart = swinfo != nullptr ? swinfo->find_part(sw_part.c_str()) : nullptr; - - // then add the options - if (new_system) - { - while (add_slot_options(options,swpart)) {} - add_device_options(options); - } - - options.set_value(OPTION_SOFTWARENAME, sw_name.c_str(), OPTION_PRIORITY_CMDLINE, error_string); - if (options.exists(sw_instance.c_str())) - options.set_value(sw_instance.c_str(), sw_load.c_str(), OPTION_PRIORITY_SUBCMD, error_string); - - int num; - do { - num = options.options_count(); - update_slot_options(options,swpart); - } while (num != options.options_count()); - } - else if (new_system) - { - // add the options afresh - while (add_slot_options(options)) {} - add_device_options(options); - int num; - do { - num = options.options_count(); - update_slot_options(options); - } while (num != options.options_count()); - } -} - -//------------------------------------------------- -// parse_one_ini - parse a single INI file -//------------------------------------------------- - -bool mame_options::parse_one_ini(emu_options &options, const char *basename, int priority, std::string *error_string) -{ - // don't parse if it has been disabled - if (!options.read_config()) - return false; - - // open the file; if we fail, that's ok - emu_file file(options.ini_path(), OPEN_FLAG_READ); - osd_file::error filerr = file.open(basename, ".ini"); - if (filerr != osd_file::error::NONE) - return false; - - // parse the file - osd_printf_verbose("Parsing %s.ini\n", basename); - std::string error; - bool result = options.parse_ini_file((util::core_file&)file, priority, OPTION_PRIORITY_DRIVER_INI, error); - - // append errors if requested - if (!error.empty() && error_string) - error_string->append(string_format("While parsing %s:\n%s\n", file.fullpath(), error)); - - return result; -} - diff --git a/src/emu/emuopts.h b/src/emu/emuopts.h index ccf1738a8c4..891355a4eeb 100644 --- a/src/emu/emuopts.h +++ b/src/emu/emuopts.h @@ -15,30 +15,7 @@ #include "options.h" -//************************************************************************** -// CONSTANTS -//************************************************************************** - -// option priorities -enum -{ - // command-line options are HIGH priority - OPTION_PRIORITY_SUBCMD = OPTION_PRIORITY_HIGH, - OPTION_PRIORITY_CMDLINE, - - // INI-based options are NORMAL priority, in increasing order: - OPTION_PRIORITY_MAME_INI = OPTION_PRIORITY_NORMAL + 1, - OPTION_PRIORITY_DEBUG_INI, - OPTION_PRIORITY_ORIENTATION_INI, - OPTION_PRIORITY_SYSTYPE_INI, - OPTION_PRIORITY_SCREEN_INI, - OPTION_PRIORITY_SOURCE_INI, - OPTION_PRIORITY_GPARENT_INI, - OPTION_PRIORITY_PARENT_INI, - OPTION_PRIORITY_DRIVER_INI, - OPTION_PRIORITY_INI, -}; - +#define OPTION_PRIORITY_CMDLINE OPTION_PRIORITY_HIGH + 1 // core options #define OPTION_SYSTEMNAME core_options::unadorned(0) #define OPTION_SOFTWARENAME core_options::unadorned(1) @@ -214,37 +191,6 @@ enum // TYPE DEFINITIONS //************************************************************************** -// forward references -struct game_driver; -class software_part; - -class mame_options -{ - static const UINT32 OPTION_FLAG_DEVICE = 0x80000000; - -public: - // parsing wrappers - static bool parse_command_line(emu_options &options, int argc, char *argv[], std::string &error_string); - static void parse_standard_inis(emu_options &options, std::string &error_string, const game_driver *driver = nullptr); - static bool parse_slot_devices(emu_options &options, int argc, char *argv[], std::string &error_string, const char *name = nullptr, const char *value = nullptr, const software_part *swpart = nullptr); - // FIXME: Couriersud: This should be in image_device_exit - static void remove_device_options(emu_options &options); - - static void set_system_name(emu_options &options, const char *name); - static bool add_slot_options(emu_options &options, const software_part *swpart = nullptr); -private: - // device-specific option handling - static void add_device_options(emu_options &options); - static void update_slot_options(emu_options &options, const software_part *swpart = nullptr); - - // INI parsing helper - static bool parse_one_ini(emu_options &options, const char *basename, int priority, std::string *error_string = nullptr); - - static int m_slot_options; - static int m_device_options; - -}; - class emu_options : public core_options { public: diff --git a/src/emu/info.cpp b/src/emu/info.cpp index 9169796f04d..37d0b3f892b 100644 --- a/src/emu/info.cpp +++ b/src/emu/info.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "emuopts.h" +#include "mameopts.h" #include "machine/ram.h" #include "sound/samples.h" #include "info.h" diff --git a/src/emu/mame.cpp b/src/emu/mame.cpp index 3ba16963bb7..d5eacf786b5 100644 --- a/src/emu/mame.cpp +++ b/src/emu/mame.cpp @@ -72,6 +72,7 @@ #include "emu.h" #include "emuopts.h" +#include "mameopts.h" #include "osdepend.h" #include "validity.h" #include "luaengine.h" diff --git a/src/emu/mameopts.cpp b/src/emu/mameopts.cpp new file mode 100644 index 00000000000..a0754f4cfd5 --- /dev/null +++ b/src/emu/mameopts.cpp @@ -0,0 +1,426 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + mameopts.c + + Options file and command line management. + +***************************************************************************/ + +#include "emu.h" +#include "mameopts.h" +#include "drivenum.h" +#include "softlist.h" + +#include <ctype.h> + +int mame_options::m_slot_options = 0; +int mame_options::m_device_options = 0; + +//------------------------------------------------- +// add_slot_options - add all of the slot +// options for the configured system +//------------------------------------------------- + +bool mame_options::add_slot_options(emu_options &options, const software_part *swpart) +{ + // look up the system configured by name; if no match, do nothing + const game_driver *cursystem = options.system(); + if (cursystem == nullptr) + return false; + + // create the configuration + machine_config config(*cursystem, options); + + // iterate through all slot devices + int starting_count = options.options_count(); + for (const device_slot_interface &slot : slot_interface_iterator(config.root_device())) + { + // skip fixed slots + if (slot.fixed()) + continue; + + // retrieve info about the device instance + const char *name = slot.device().tag() + 1; + if (!options.exists(name)) + { + // first device? add the header as to be pretty + if (m_slot_options++ == 0) + options.add_entry(nullptr, "SLOT DEVICES", OPTION_HEADER | OPTION_FLAG_DEVICE); + + // add the option + options.add_entry(name, nullptr, OPTION_STRING | OPTION_FLAG_DEVICE, slot.default_option(), true); + } + + // allow software lists to supply their own defaults + if (swpart != nullptr) + { + std::string featurename = std::string(name).append("_default"); + const char *value = swpart->feature(featurename.c_str()); + if (value != nullptr && (*value == '\0' || slot.option(value) != nullptr)) + { + // set priority above INIs but below actual command line + std::string error; + options.set_value(name, value, OPTION_PRIORITY_SUBCMD, error); + } + } + } + return (options.options_count() != starting_count); +} + + +//------------------------------------------------- +// update_slot_options - update slot values +// depending of image mounted +//------------------------------------------------- + +void mame_options::update_slot_options(emu_options &options, const software_part *swpart) +{ + // look up the system configured by name; if no match, do nothing + const game_driver *cursystem = options.system(); + if (cursystem == nullptr) + return; + machine_config config(*cursystem, options); + + // iterate through all slot devices + for (device_slot_interface &slot : slot_interface_iterator(config.root_device())) + { + // retrieve info about the device instance + const char *name = slot.device().tag() + 1; + if (options.exists(name) && !slot.option_list().empty()) + { + std::string defvalue = slot.get_default_card_software(); + if (defvalue.empty()) + { + // keep any non-default setting + if (options.priority(name) > OPTION_PRIORITY_DEFAULT) + continue; + + // reinstate the actual default value as configured + if (slot.default_option() != nullptr) + defvalue.assign(slot.default_option()); + } + + // set the value and hide the option if not selectable + options.set_default_value(name, defvalue.c_str()); + const device_slot_option *option = slot.option(defvalue.c_str()); + options.set_flag(name, ~OPTION_FLAG_INTERNAL, (option != nullptr && !option->selectable()) ? OPTION_FLAG_INTERNAL : 0); + } + } + while (add_slot_options(options,swpart)) {} + add_device_options(options); +} + + +//------------------------------------------------- +// add_device_options - add all of the device +// options for the configured system +//------------------------------------------------- + +void mame_options::add_device_options(emu_options &options) +{ + // look up the system configured by name; if no match, do nothing + const game_driver *cursystem = options.system(); + if (cursystem == nullptr) + return; + machine_config config(*cursystem, options); + + // iterate through all image devices + for (const device_image_interface &image : image_interface_iterator(config.root_device())) + { + if (!image.user_loadable()) + continue; + + // retrieve info about the device instance + std::ostringstream option_name; + util::stream_format(option_name, "%s;%s", image.instance_name(), image.brief_instance_name()); + if (strcmp(image.device_typename(image.image_type()), image.instance_name()) == 0) + util::stream_format(option_name, ";%s1;%s1", image.instance_name(), image.brief_instance_name()); + + // add the option + if (!options.exists(image.instance_name())) + { + // first device? add the header as to be pretty + if (m_device_options++ == 0) + options.add_entry(nullptr, "IMAGE DEVICES", OPTION_HEADER | OPTION_FLAG_DEVICE); + + // add the option + options.add_entry(option_name.str().c_str(), nullptr, OPTION_STRING | OPTION_FLAG_DEVICE, nullptr, true); + } + } +} + + +//------------------------------------------------- +// remove_device_options - remove device options +//------------------------------------------------- + +void mame_options::remove_device_options(emu_options &options) +{ + // iterate through options and remove interesting ones + core_options::entry *nextentry; + for (auto *curentry = options.first(); curentry != nullptr; curentry = nextentry) + { + // pre-fetch the next entry in case we delete this one + nextentry = curentry->next(); + + // if this is a device option, nuke it + if ((curentry->flags() & OPTION_FLAG_DEVICE) != 0) + options.remove_entry(*curentry); + } + + // take also care of ramsize options + options.set_default_value(OPTION_RAMSIZE, ""); + + // reset counters + m_slot_options = 0; + m_device_options = 0; +} + + +//------------------------------------------------- +// parse_slot_devices - parse the command line +// and update slot and image devices +//------------------------------------------------- + +bool mame_options::parse_slot_devices(emu_options &options, int argc, char *argv[], std::string &error_string, const char *name, const char *value, const software_part *swpart) +{ + // an initial parse to capture the initial set of values + bool result; + + options.parse_command_line(argc, argv, OPTION_PRIORITY_CMDLINE, error_string); + + // keep adding slot options until we stop seeing new stuff + while (add_slot_options(options,swpart)) + options.parse_command_line(argc, argv, OPTION_PRIORITY_CMDLINE, error_string); + + // add device options and reparse + add_device_options(options); + if (name != nullptr && options.exists(name)) + options.set_value(name, value, OPTION_PRIORITY_SUBCMD, error_string); + options.parse_command_line(argc, argv, OPTION_PRIORITY_CMDLINE, error_string); + + int num; + do { + num = options.options_count(); + update_slot_options(options,swpart); + result = options.parse_command_line(argc, argv, OPTION_PRIORITY_CMDLINE, error_string); + } while (num != options.options_count()); + + options.update_cached_options(); + + return result; +} + + +//------------------------------------------------- +// parse_command_line - parse the command line +// and update the devices +//------------------------------------------------- + +bool mame_options::parse_command_line(emu_options &options, int argc, char *argv[], std::string &error_string) +{ + // parse as normal + options.parse_command_line(argc, argv, OPTION_PRIORITY_CMDLINE, error_string); + bool result = parse_slot_devices(options,argc, argv, error_string); + options.update_cached_options(); + return result; +} + + +//------------------------------------------------- +// parse_standard_inis - parse the standard set +// of INI files +//------------------------------------------------- + +void mame_options::parse_standard_inis(emu_options &options, std::string &error_string, const game_driver *driver) +{ + // start with an empty string + error_string.clear(); + + // parse the INI file defined by the platform (e.g., "mame.ini") + // we do this twice so that the first file can change the INI path + parse_one_ini(options,emulator_info::get_configname(), OPTION_PRIORITY_MAME_INI); + parse_one_ini(options,emulator_info::get_configname(), OPTION_PRIORITY_MAME_INI, &error_string); + + // debug mode: parse "debug.ini" as well + if (options.debug()) + parse_one_ini(options,"debug", OPTION_PRIORITY_DEBUG_INI, &error_string); + + // if we have a valid system driver, parse system-specific INI files + const game_driver *cursystem = (driver == nullptr) ? options.system() : driver; + if (cursystem == nullptr) + return; + + // parse "vertical.ini" or "horizont.ini" + if (cursystem->flags & ORIENTATION_SWAP_XY) + parse_one_ini(options,"vertical", OPTION_PRIORITY_ORIENTATION_INI, &error_string); + else + parse_one_ini(options,"horizont", OPTION_PRIORITY_ORIENTATION_INI, &error_string); + + if (cursystem->flags & MACHINE_TYPE_ARCADE) + parse_one_ini(options,"arcade", OPTION_PRIORITY_SYSTYPE_INI, &error_string); + else if (cursystem->flags & MACHINE_TYPE_CONSOLE) + parse_one_ini(options,"console", OPTION_PRIORITY_SYSTYPE_INI, &error_string); + else if (cursystem->flags & MACHINE_TYPE_COMPUTER) + parse_one_ini(options,"computer", OPTION_PRIORITY_SYSTYPE_INI, &error_string); + else if (cursystem->flags & MACHINE_TYPE_OTHER) + parse_one_ini(options,"othersys", OPTION_PRIORITY_SYSTYPE_INI, &error_string); + + machine_config config(*cursystem, options); + for (const screen_device &device : screen_device_iterator(config.root_device())) + { + // parse "raster.ini" for raster games + if (device.screen_type() == SCREEN_TYPE_RASTER) + { + parse_one_ini(options,"raster", OPTION_PRIORITY_SCREEN_INI, &error_string); + break; + } + // parse "vector.ini" for vector games + if (device.screen_type() == SCREEN_TYPE_VECTOR) + { + parse_one_ini(options,"vector", OPTION_PRIORITY_SCREEN_INI, &error_string); + break; + } + // parse "lcd.ini" for lcd games + if (device.screen_type() == SCREEN_TYPE_LCD) + { + parse_one_ini(options,"lcd", OPTION_PRIORITY_SCREEN_INI, &error_string); + break; + } + } + + // next parse "source/<sourcefile>.ini"; if that doesn't exist, try <sourcefile>.ini + std::string sourcename = core_filename_extract_base(cursystem->source_file, true).insert(0, "source" PATH_SEPARATOR); + if (!parse_one_ini(options,sourcename.c_str(), OPTION_PRIORITY_SOURCE_INI, &error_string)) + { + sourcename = core_filename_extract_base(cursystem->source_file, true); + parse_one_ini(options,sourcename.c_str(), OPTION_PRIORITY_SOURCE_INI, &error_string); + } + + // then parse the grandparent, parent, and system-specific INIs + int parent = driver_list::clone(*cursystem); + int gparent = (parent != -1) ? driver_list::clone(parent) : -1; + if (gparent != -1) + parse_one_ini(options,driver_list::driver(gparent).name, OPTION_PRIORITY_GPARENT_INI, &error_string); + if (parent != -1) + parse_one_ini(options,driver_list::driver(parent).name, OPTION_PRIORITY_PARENT_INI, &error_string); + parse_one_ini(options,cursystem->name, OPTION_PRIORITY_DRIVER_INI, &error_string); + + // Re-evaluate slot options after loading ini files + update_slot_options(options); + + options.update_cached_options(); +} + +//------------------------------------------------- +// set_system_name - set a new system name +//------------------------------------------------- + +void mame_options::set_system_name(emu_options &options, const char *name) +{ + // remember the original system name + std::string old_system_name(options.system_name()); + bool new_system = old_system_name.compare(name) != 0; + + // if the system name changed, fix up the device options + if (new_system) + { + // first set the new name + std::string error; + options.set_value(OPTION_SYSTEMNAME, name, OPTION_PRIORITY_CMDLINE, error); + assert(error.empty()); + + // remove any existing device options + remove_device_options(options); + } + else + { + // revert device options set for the old software + options.revert(OPTION_PRIORITY_SUBCMD, OPTION_PRIORITY_SUBCMD); + } + + // get the new system + const game_driver *cursystem = options.system(); + if (cursystem == nullptr) + return; + + if (*options.software_name() != 0) + { + std::string sw_load(options.software_name()); + std::string sw_list, sw_name, sw_part, sw_instance, error_string; + int left = sw_load.find_first_of(':'); + int middle = sw_load.find_first_of(':', left + 1); + int right = sw_load.find_last_of(':'); + + sw_list = sw_load.substr(0, left - 1); + sw_name = sw_load.substr(left + 1, middle - left - 1); + sw_part = sw_load.substr(middle + 1, right - middle - 1); + sw_instance = sw_load.substr(right + 1); + sw_load.assign(sw_load.substr(0, right)); + + // look up the software part + machine_config config(*cursystem, options); + software_list_device *swlist = software_list_device::find_by_name(config, sw_list.c_str()); + software_info *swinfo = swlist != nullptr ? swlist->find(sw_name.c_str()) : nullptr; + software_part *swpart = swinfo != nullptr ? swinfo->find_part(sw_part.c_str()) : nullptr; + + // then add the options + if (new_system) + { + while (add_slot_options(options,swpart)) {} + add_device_options(options); + } + + options.set_value(OPTION_SOFTWARENAME, sw_name.c_str(), OPTION_PRIORITY_CMDLINE, error_string); + if (options.exists(sw_instance.c_str())) + options.set_value(sw_instance.c_str(), sw_load.c_str(), OPTION_PRIORITY_SUBCMD, error_string); + + int num; + do { + num = options.options_count(); + update_slot_options(options,swpart); + } while (num != options.options_count()); + } + else if (new_system) + { + // add the options afresh + while (add_slot_options(options)) {} + add_device_options(options); + int num; + do { + num = options.options_count(); + update_slot_options(options); + } while (num != options.options_count()); + } +} + +//------------------------------------------------- +// parse_one_ini - parse a single INI file +//------------------------------------------------- + +bool mame_options::parse_one_ini(emu_options &options, const char *basename, int priority, std::string *error_string) +{ + // don't parse if it has been disabled + if (!options.read_config()) + return false; + + // open the file; if we fail, that's ok + emu_file file(options.ini_path(), OPEN_FLAG_READ); + osd_file::error filerr = file.open(basename, ".ini"); + if (filerr != osd_file::error::NONE) + return false; + + // parse the file + osd_printf_verbose("Parsing %s.ini\n", basename); + std::string error; + bool result = options.parse_ini_file((util::core_file&)file, priority, OPTION_PRIORITY_DRIVER_INI, error); + + // append errors if requested + if (!error.empty() && error_string) + error_string->append(string_format("While parsing %s:\n%s\n", file.fullpath(), error)); + + return result; +} + diff --git a/src/emu/mameopts.h b/src/emu/mameopts.h new file mode 100644 index 00000000000..50b1ae5b776 --- /dev/null +++ b/src/emu/mameopts.h @@ -0,0 +1,78 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + mameopts.h + + Options file and command line management. + +***************************************************************************/ + +#pragma once + +#ifndef __MAMEOPTS_H__ +#define __MAMEOPTS_H__ + +#include "emuopts.h" + +//************************************************************************** +// CONSTANTS +//************************************************************************** +#undef OPTION_PRIORITY_CMDLINE + +// option priorities +enum +{ + // command-line options are HIGH priority + OPTION_PRIORITY_SUBCMD = OPTION_PRIORITY_HIGH, + OPTION_PRIORITY_CMDLINE, + + // INI-based options are NORMAL priority, in increasing order: + OPTION_PRIORITY_MAME_INI = OPTION_PRIORITY_NORMAL + 1, + OPTION_PRIORITY_DEBUG_INI, + OPTION_PRIORITY_ORIENTATION_INI, + OPTION_PRIORITY_SYSTYPE_INI, + OPTION_PRIORITY_SCREEN_INI, + OPTION_PRIORITY_SOURCE_INI, + OPTION_PRIORITY_GPARENT_INI, + OPTION_PRIORITY_PARENT_INI, + OPTION_PRIORITY_DRIVER_INI, + OPTION_PRIORITY_INI, +}; + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// forward references +struct game_driver; +class software_part; + +class mame_options +{ + static const UINT32 OPTION_FLAG_DEVICE = 0x80000000; + +public: + // parsing wrappers + static bool parse_command_line(emu_options &options, int argc, char *argv[], std::string &error_string); + static void parse_standard_inis(emu_options &options, std::string &error_string, const game_driver *driver = nullptr); + static bool parse_slot_devices(emu_options &options, int argc, char *argv[], std::string &error_string, const char *name = nullptr, const char *value = nullptr, const software_part *swpart = nullptr); + // FIXME: Couriersud: This should be in image_device_exit + static void remove_device_options(emu_options &options); + + static void set_system_name(emu_options &options, const char *name); + static bool add_slot_options(emu_options &options, const software_part *swpart = nullptr); +private: + // device-specific option handling + static void add_device_options(emu_options &options); + static void update_slot_options(emu_options &options, const software_part *swpart = nullptr); + + // INI parsing helper + static bool parse_one_ini(emu_options &options, const char *basename, int priority, std::string *error_string = nullptr); + + static int m_slot_options; + static int m_device_options; + +}; + +#endif /* __MAMEOPTS_H__ */ diff --git a/src/emu/ui/miscmenu.cpp b/src/emu/ui/miscmenu.cpp index 4a000595de4..24064f57e63 100644 --- a/src/emu/ui/miscmenu.cpp +++ b/src/emu/ui/miscmenu.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "osdnet.h" +#include "mameopts.h" #include "uiinput.h" #include "ui/ui.h" diff --git a/src/emu/ui/optsmenu.cpp b/src/emu/ui/optsmenu.cpp index ce84df18f67..d11cfe37143 100644 --- a/src/emu/ui/optsmenu.cpp +++ b/src/emu/ui/optsmenu.cpp @@ -9,6 +9,7 @@ *********************************************************************/ #include "emu.h" +#include "mameopts.h" #include "ui/ui.h" #include "ui/menu.h" #include "ui/submenu.h" diff --git a/src/emu/ui/slotopt.cpp b/src/emu/ui/slotopt.cpp index 470647ea063..9b6afa92132 100644 --- a/src/emu/ui/slotopt.cpp +++ b/src/emu/ui/slotopt.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "emuopts.h" +#include "mameopts.h" #include "ui/ui.h" #include "ui/menu.h" #include "ui/slotopt.h" diff --git a/src/emu/ui/ui.cpp b/src/emu/ui/ui.cpp index 481568123a5..65d1711a4e0 100644 --- a/src/emu/ui/ui.cpp +++ b/src/emu/ui/ui.cpp @@ -10,6 +10,7 @@ #include "emu.h" #include "emuopts.h" +#include "mameopts.h" #include "video/vector.h" #include "machine/laserdsc.h" #include "render.h" |