diff options
author | Nathan Woods <npwoods@mess.org> | 2017-04-02 18:57:02 -0400 |
---|---|---|
committer | Vas Crabb <cuavas@users.noreply.github.com> | 2017-04-06 11:20:45 +1000 |
commit | fbb7d927d3a58de18850ad3079621e0a78e5e6bd (patch) | |
tree | 81616193556f6466a00d2c05142d1ba89b9cc693 /src/frontend | |
parent | 694a7812155927f89df046b585836ce872929e72 (diff) |
Refactoring in response to MT#6531
Prior to this change, options for images and slots were stored in the emu_options collection. Anything that might restart the emulation (such as slot changes and images that reset on load) had to manipulate the emu_options structure directly. The dynamic nature of images and slots meant that some elaborate conventions for setting up this collection had to be understood by clients.
After this change, emu_options has two new members (image_options and slot_options) that expose image and slot selections via an std::map. Anything that changes images or slots in a fashion that needs to persist across sessions needs to modify these data structures. Additionally, some of the hairly logic (e.g. - get_default_card_software) now records its data here rather than trying to subvert the core_options system.
This is how MT#6531 was fixed; now when diimage.cpp sees an image that resets on load, it just modifies the image_options structure and forces a reset. This allowed some further cleanups to happen within diimage.
This should be considered a very risky change, and scrutiny/feedback is welcome. In particular, there seems to be functionality surrounding device bioses that I'm not 100% sure how it works; the syntax seems to imply that it only works on slot devices.
Diffstat (limited to 'src/frontend')
-rw-r--r-- | src/frontend/mame/mame.cpp | 5 | ||||
-rw-r--r-- | src/frontend/mame/mameopts.cpp | 57 | ||||
-rw-r--r-- | src/frontend/mame/mameopts.h | 15 | ||||
-rw-r--r-- | src/frontend/mame/ui/imgcntrl.cpp | 1 | ||||
-rw-r--r-- | src/frontend/mame/ui/info.cpp | 3 | ||||
-rw-r--r-- | src/frontend/mame/ui/miscmenu.cpp | 6 | ||||
-rw-r--r-- | src/frontend/mame/ui/slotopt.cpp | 11 |
7 files changed, 67 insertions, 31 deletions
diff --git a/src/frontend/mame/mame.cpp b/src/frontend/mame/mame.cpp index feb5fb770d4..0a954906c35 100644 --- a/src/frontend/mame/mame.cpp +++ b/src/frontend/mame/mame.cpp @@ -216,6 +216,11 @@ int mame_machine_manager::execute() valid.check_shared_source(*system); } + // reevaluate slot options until nothing changes + while (mame_options::reevaluate_slot_options(m_options)) + { + } + // create the machine configuration machine_config config(*system, m_options); diff --git a/src/frontend/mame/mameopts.cpp b/src/frontend/mame/mameopts.cpp index e724146e942..8d69b3f2ff4 100644 --- a/src/frontend/mame/mameopts.cpp +++ b/src/frontend/mame/mameopts.cpp @@ -27,7 +27,7 @@ int mame_options::m_device_options = 0; // options for the configured system //------------------------------------------------- -bool mame_options::add_slot_options(emu_options &options, std::function<void(emu_options &options, const std::string &)> value_specifier) +bool mame_options::add_slot_options(emu_options &options, value_specifier_func value_specifier) { // look up the system configured by name; if no match, do nothing const game_driver *cursystem = system(options); @@ -58,7 +58,11 @@ bool mame_options::add_slot_options(emu_options &options, std::function<void(emu // allow opportunity to specify this value if (value_specifier) - value_specifier(options, name); + { + std::string value = value_specifier(name); + if (value != value_specifier_invalid_value()) + options.slot_options()[name] = parse_slot_option(std::move(value)); + } } } return (options.options_count() != starting_count); @@ -112,7 +116,7 @@ void mame_options::update_slot_options(emu_options &options, const software_part // options for the configured system //------------------------------------------------- -void mame_options::add_device_options(emu_options &options, std::function<void(emu_options &options, const std::string &)> value_specifier) +void mame_options::add_device_options(emu_options &options, value_specifier_func value_specifier) { // look up the system configured by name; if no match, do nothing const game_driver *cursystem = system(options); @@ -121,7 +125,7 @@ void mame_options::add_device_options(emu_options &options, std::function<void(e machine_config config(*cursystem, options); // iterate through all image devices - for (const device_image_interface &image : image_interface_iterator(config.root_device())) + for (device_image_interface &image : image_interface_iterator(config.root_device())) { if (!image.user_loadable()) continue; @@ -139,7 +143,11 @@ void mame_options::add_device_options(emu_options &options, std::function<void(e // allow opportunity to specify this value if (value_specifier) - value_specifier(options, image.instance_name()); + { + std::string value = value_specifier(image.instance_name()); + if (value != value_specifier_invalid_value()) + options.image_options()[image.instance_name()] = std::move(value); + } } } } @@ -191,7 +199,7 @@ void mame_options::remove_device_options(emu_options &options) // and update slot and image devices //------------------------------------------------- -void mame_options::parse_slot_devices(emu_options &options, std::function<void(emu_options &options, const std::string &)> value_specifier) +void mame_options::parse_slot_devices(emu_options &options, value_specifier_func value_specifier) { bool still_adding = true; while (still_adding) @@ -248,12 +256,12 @@ bool mame_options::reevaluate_slot_options(emu_options &options) std::string default_card_software = slot.get_default_card_software(); if (!default_card_software.empty()) { - std::string old_value = options.value(name); - - options.set_default_value(name, default_card_software.c_str()); - - if (strcmp(old_value.c_str(), options.value(name))) + // we have default card software - is this resulting in the slot option being mutated? + if (options.slot_options()[name].default_card_software() != default_card_software) + { + options.slot_options()[name].set_default_card_software(std::move(default_card_software)); result = true; + } } } } @@ -277,7 +285,7 @@ bool mame_options::parse_command_line(emu_options &options, std::vector<std::str // assemble a "value specifier" that will be used to specify options set up as a consequence // of slot and device setup - auto value_specifier = [&softlist_opts, &args, &error_string](emu_options &options, const std::string &arg) + auto value_specifier = [&options, &softlist_opts, &args, &error_string](const std::string &arg) { // first find within the command line std::string arg_value; @@ -295,8 +303,9 @@ bool mame_options::parse_command_line(emu_options &options, std::vector<std::str } // did we find something? - if (success) - options.set_value(arg.c_str(), arg_value.c_str(), OPTION_PRIORITY_MAXIMUM, error_string); + return success + ? arg_value + : value_specifier_invalid_value(); }; // parse the slot devices @@ -512,9 +521,6 @@ void mame_options::parse_standard_inis(emu_options &options, std::string &error_ 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); } @@ -642,3 +648,20 @@ bool mame_options::parse_one_ini(emu_options &options, const char *basename, int return result; } + + +//------------------------------------------------- +// parse_slot_option - parses a slot option (the +// ',bios=XYZ' syntax) +//------------------------------------------------- + +slot_option mame_options::parse_slot_option(std::string &&text) +{ + slot_option result; + const char *bios_arg = ",bios="; + + size_t pos = text.find(bios_arg); + return pos != std::string::npos + ? slot_option(text.substr(0, pos), text.substr(pos + strlen(bios_arg))) + : slot_option(std::move(text)); +} diff --git a/src/frontend/mame/mameopts.h b/src/frontend/mame/mameopts.h index 8c1e2497327..b64b45202a3 100644 --- a/src/frontend/mame/mameopts.h +++ b/src/frontend/mame/mameopts.h @@ -53,6 +53,8 @@ class mame_options static const uint32_t OPTION_FLAG_DEVICE = 0x80000000; public: + typedef std::function<std::string (const std::string &)> value_specifier_func; + // parsing wrappers static bool parse_command_line(emu_options &options, std::vector<std::string> &args, std::string &error_string); static void parse_standard_inis(emu_options &options, std::string &error_string, const game_driver *driver = nullptr); @@ -61,15 +63,16 @@ public: static const game_driver *system(const emu_options &options); static void set_system_name(emu_options &options, const char *name); - static bool add_slot_options(emu_options &options, std::function<void(emu_options &options, const std::string &)> value_specifier = nullptr); + static bool add_slot_options(emu_options &options, value_specifier_func value_specifier = nullptr); + static bool reevaluate_slot_options(emu_options &options); private: // device-specific option handling - static void add_device_options(emu_options &options, std::function<void(emu_options &options, const std::string &)> value_specifier = nullptr); + static void add_device_options(emu_options &options, value_specifier_func value_specifier = nullptr); static void update_slot_options(emu_options &options, const software_part *swpart = nullptr); - static void parse_slot_devices(emu_options &options, std::function<void(emu_options &options, const std::string &)> value_specifier); + static void parse_slot_devices(emu_options &options, value_specifier_func value_specifier); static std::string get_full_option_name(const device_image_interface &image); - static bool reevaluate_slot_options(emu_options &options); + static slot_option parse_slot_option(std::string &&text); // INI parsing helper static bool parse_one_ini(emu_options &options, const char *basename, int priority, std::string *error_string = nullptr); @@ -77,6 +80,10 @@ private: // softlist handling static std::map<std::string, std::string> evaluate_initial_softlist_options(emu_options &options); + // represents an "invalid" value (an empty string is valid so we can't use that; what I + // really want to return is std::optional<std::string> but C++17 isn't here yet) + static std::string value_specifier_invalid_value() { return std::string("\x01\x02\x03"); } + static int m_slot_options; static int m_device_options; }; diff --git a/src/frontend/mame/ui/imgcntrl.cpp b/src/frontend/mame/ui/imgcntrl.cpp index 1c25db2cac4..18ee2358852 100644 --- a/src/frontend/mame/ui/imgcntrl.cpp +++ b/src/frontend/mame/ui/imgcntrl.cpp @@ -158,7 +158,6 @@ void menu_control_device_image::load_software_part() void menu_control_device_image::hook_load(const std::string &name) { - if (m_image.is_reset_on_load()) m_image.set_init_phase(); m_image.load(name); stack_pop(); } diff --git a/src/frontend/mame/ui/info.cpp b/src/frontend/mame/ui/info.cpp index e1eca68ada8..670042de0f5 100644 --- a/src/frontend/mame/ui/info.cpp +++ b/src/frontend/mame/ui/info.cpp @@ -15,6 +15,7 @@ #include "drivenum.h" #include "softlist.h" +#include "emuopts.h" namespace ui { //------------------------------------------------- @@ -322,7 +323,7 @@ std::string machine_info::mandatory_images() // make sure that any required image has a mounted file for (device_image_interface &image : image_interface_iterator(m_machine.root_device())) { - if (image.filename() == nullptr && image.must_be_loaded()) + if (image.must_be_loaded() && m_machine.options().image_options().count(image.instance_name()) == 0) buf << "\"" << image.instance_name() << "\", "; } return buf.str(); diff --git a/src/frontend/mame/ui/miscmenu.cpp b/src/frontend/mame/ui/miscmenu.cpp index 23d9a346a7b..3ec2bf78cd3 100644 --- a/src/frontend/mame/ui/miscmenu.cpp +++ b/src/frontend/mame/ui/miscmenu.cpp @@ -131,10 +131,8 @@ void menu_bios_selection::handle() machine().options().set_value("bios", val-1, OPTION_PRIORITY_CMDLINE, error); assert(error.empty()); } else { - std::string error; - std::string value = string_format("%s,bios=%d", machine().options().main_value(dev->owner()->tag()+1), val-1); - machine().options().set_value(dev->owner()->tag()+1, value.c_str(), OPTION_PRIORITY_CMDLINE, error); - assert(error.empty()); + const char *slot_option_name = dev->owner()->tag() + 1; + machine().options().slot_options()[slot_option_name].set_bios(string_format("%d", val - 1)); } reset(reset_options::REMEMBER_REF); } diff --git a/src/frontend/mame/ui/slotopt.cpp b/src/frontend/mame/ui/slotopt.cpp index 06ca10cccda..42ec9e1a896 100644 --- a/src/frontend/mame/ui/slotopt.cpp +++ b/src/frontend/mame/ui/slotopt.cpp @@ -25,14 +25,17 @@ namespace ui { device_slot_option *menu_slot_devices::slot_get_current_option(device_slot_interface &slot) { std::string current; - if (slot.fixed()) + + const char *slot_option_name = slot.device().tag() + 1; + if (!slot.fixed() && machine().options().slot_options().count(slot_option_name) > 0) { - if (slot.default_option() == nullptr) return nullptr; - current.assign(slot.default_option()); + current = machine().options().slot_options()[slot_option_name].value(); } else { - current = machine().options().main_value(slot.device().tag() + 1); + if (slot.default_option() == nullptr) + return nullptr; + current.assign(slot.default_option()); } return slot.option(current.c_str()); |