summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--scripts/src/emu.lua2
-rw-r--r--src/emu/clifront.cpp1
-rw-r--r--src/emu/emuopts.cpp418
-rw-r--r--src/emu/emuopts.h56
-rw-r--r--src/emu/info.cpp1
-rw-r--r--src/emu/mame.cpp1
-rw-r--r--src/emu/mameopts.cpp426
-rw-r--r--src/emu/mameopts.h78
-rw-r--r--src/emu/ui/miscmenu.cpp1
-rw-r--r--src/emu/ui/optsmenu.cpp1
-rw-r--r--src/emu/ui/slotopt.cpp1
-rw-r--r--src/emu/ui/ui.cpp1
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"