summaryrefslogtreecommitdiffstatshomepage
path: root/src/frontend
diff options
context:
space:
mode:
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
commitfbb7d927d3a58de18850ad3079621e0a78e5e6bd (patch)
tree81616193556f6466a00d2c05142d1ba89b9cc693 /src/frontend
parent694a7812155927f89df046b585836ce872929e72 (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.cpp5
-rw-r--r--src/frontend/mame/mameopts.cpp57
-rw-r--r--src/frontend/mame/mameopts.h15
-rw-r--r--src/frontend/mame/ui/imgcntrl.cpp1
-rw-r--r--src/frontend/mame/ui/info.cpp3
-rw-r--r--src/frontend/mame/ui/miscmenu.cpp6
-rw-r--r--src/frontend/mame/ui/slotopt.cpp11
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());