summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2021-07-15 04:09:18 +1000
committer Vas Crabb <cuavas@users.noreply.github.com>2021-07-15 13:54:40 +1000
commit37157461313b13a691722b83c87df8d2315457da (patch)
tree8034c6f33776f5a8bfc8f6c69af879975061bd0a
parent66554d3b84f5fec60dcf5d896283a1a04487c0e0 (diff)
API cleanups and miscellaneous fixes.
emu/ioport.cpp: Allow controller files to override input sequences for inputs that don't use defaults, and to override the toggle setting for digital inputs. emu/config.cpp: Expose configuration level (mostly matters for controller files), improved verbose diagnostic messages, and moved a few things out of the global and preprocessor namespaces. docs: Added documentation for some controller configuration file features. The device mapping feature documentation will be merged in at some point. util/unicode.cpp, emu/input.cpp: API cleanups.
-rw-r--r--docs/source/advanced/ctrlr_config.rst229
-rw-r--r--docs/source/advanced/index.rst19
-rw-r--r--docs/source/commandline/commandline-all.rst16
-rw-r--r--src/devices/machine/laserdsc.cpp23
-rw-r--r--src/devices/machine/laserdsc.h2
-rw-r--r--src/emu/bookkeeping.cpp48
-rw-r--r--src/emu/bookkeeping.h2
-rw-r--r--src/emu/config.cpp174
-rw-r--r--src/emu/config.h60
-rw-r--r--src/emu/crsshair.cpp48
-rw-r--r--src/emu/crsshair.h2
-rw-r--r--src/emu/emufwd.h3
-rw-r--r--src/emu/image.cpp13
-rw-r--r--src/emu/image.h2
-rw-r--r--src/emu/input.cpp13
-rw-r--r--src/emu/input.h2
-rw-r--r--src/emu/ioport.cpp464
-rw-r--r--src/emu/ioport.h103
-rw-r--r--src/emu/network.cpp15
-rw-r--r--src/emu/network.h2
-rw-r--r--src/emu/render.cpp15
-rw-r--r--src/emu/render.h2
-rw-r--r--src/emu/rendlay.cpp2
-rw-r--r--src/emu/sound.cpp46
-rw-r--r--src/emu/sound.h2
-rw-r--r--src/emu/validity.cpp29
-rw-r--r--src/emu/validity.h6
-rw-r--r--src/frontend/mame/infoxml.cpp4
-rw-r--r--src/frontend/mame/luaengine_input.cpp2
-rw-r--r--src/frontend/mame/ui/devopt.cpp4
-rw-r--r--src/frontend/mame/ui/ui.cpp10
-rw-r--r--src/frontend/mame/ui/ui.h2
-rw-r--r--src/lib/util/unicode.cpp32
-rw-r--r--src/lib/util/unicode.h3
-rw-r--r--src/osd/modules/debugger/debugosx.mm12
-rw-r--r--src/osd/modules/debugger/debugqt.cpp20
36 files changed, 868 insertions, 563 deletions
diff --git a/docs/source/advanced/ctrlr_config.rst b/docs/source/advanced/ctrlr_config.rst
new file mode 100644
index 00000000000..f05a3d164b7
--- /dev/null
+++ b/docs/source/advanced/ctrlr_config.rst
@@ -0,0 +1,229 @@
+.. _ctrlrcfg:
+
+Controller Configuration Files
+==============================
+
+.. contents:: :local:
+
+
+.. _ctrlrcfg-intro:
+
+Introduction
+------------
+
+Controller configuration files can be used to modify MAME’s default input
+settings. Controller configuration files may be supplied with an input device
+to provide more suitable defaults, or used as profiles that can be selected for
+different situations. MAME includes a few sample controller configuration files
+in the **ctrlr** folder, designed to provide useful defaults for certain
+arcade-style controllers.
+
+Controller configuration files are an XML application, using the ``.cfg``
+filename extension. MAME searches for controller configuration files in the
+directories specified using the ``ctrlrpath`` option. A controller
+configuration file is selected by setting the ``ctrlr`` option to its filename,
+excluding the ``.cfg`` extension (e.g. set the ``ctrlr`` option to
+``scorpionxg`` to use **scorpionxg.cfg**). It is an error if the specified
+controller configuration file does not exist, or if it contains no sections
+applicable to the emulated system.
+
+Controller configuration files use implementation-dependent input tokens. The
+values available and their precise meanings depend on the exact version of MAME
+used, the input devices connected, the selected input provider modules
+(``keyboardprovider``, ``mouseprovider``, ``lightgunprovider`` and
+``joystickprovider`` options), and possibly other settings.
+
+
+.. _ctrlrcfg-structure:
+
+Basic structure
+---------------
+
+Controller configuration files follow a similar format to the system
+configuration files that MAME uses to save things like input settings and
+bookkeeping data. This example shows the overall structure of a controller
+configuration file:
+
+.. code-block:: XML
+
+ <?xml version="1.0"?>
+ <mameconfig version="10">
+ <system name="default">
+ <input>
+ <!-- settings affecting all emulated systems go here -->
+ </input>
+ </system>
+ <system name="neogeo">
+ <input>
+ <!-- settings affecting neogeo and clones go here -->
+ </input>
+ </system>
+ <system name="intellec4.cpp">
+ <input>
+ <!-- settings affecting all systems defined in intellec4.cpp go here -->
+ </input>
+ </system>
+ </mameconfig>
+
+The root of a controller configuration file must be a ``mameconfig`` element,
+with a ``version`` attribute specifying the configuration format version
+(currently ``10`` – MAME will not load a file using a different version). The
+``mameconfig`` element contains one or more ``system`` elements, each of which
+has a ``name`` attribute specifying the system(s) it applies to. Each
+``system`` element contains an ``input`` element which holds the actual
+``remap`` and ``port`` configuration elements, which will be described later.
+
+When launching an emulated system, MAME will apply configuration from ``system``
+elements where the value of the ``name`` attribute meets one of the following
+criteria:
+
+* If the ``name`` attribute has the value ``default``, it will always be applied
+ (including for the system/software selection menus).
+* If the value of the ``name`` attribute matches the system’s short name, the
+ short name of its parent system, or the short name of its BIOS system (if
+ applicable).
+* If the value of the ``name`` attribute matches the name of the source file
+ where the system is defined.
+
+For example, for the game “DaeJeon! SanJeon SuJeon (AJTUE 990412 V1.000)”,
+``system`` elements will be applied if their ``name`` attribute has the value
+``default`` (applies to all systems), ``sanjeon`` (short name of the system
+itself), ``sasissu`` (short name of the parent system), ``stvbios`` (short
+name of the BIOS system), or ``stv.cpp`` (source file where the system is
+defined).
+
+As another example, a ``system`` element whose ``name`` attribute has the value
+``zac2650.cpp`` will be applied for the systems “The Invaders”, “Super Invader
+Attack (bootleg of The Invaders)”, and “Dodgem”.
+
+Applicable ``system`` elements are applied in the order they appear in the
+controller configuration file. Settings from elements that appear later in the
+file may modify or override settings from elements that appear earlier. Within
+a ``system`` element, ``remap`` elements are applied before ``port`` elements.
+
+
+.. _ctrlrcfg-substitute:
+
+Substituting default controls
+-----------------------------
+
+You can use a ``remap`` element to substitute one host input for another in
+MAME’s default input configuration. For example, this substitutes keys on the
+numeric keypad for the cursor direction keys:
+
+.. code-block:: XML
+
+ <input>
+ <remap origcode="KEYCODE_UP" newcode="KEYCODE_8PAD" />
+ <remap origcode="KEYCODE_DOWN" newcode="KEYCODE_2PAD" />
+ <remap origcode="KEYCODE_LEFT" newcode="KEYCODE_4PAD" />
+ <remap origcode="KEYCODE_RIGHT" newcode="KEYCODE_6PAD" />
+ </input>
+
+The ``origcode`` attribute specifies the token for the host input to be
+substituted, and the ``newcode`` attribute specifies the token for the
+replacement host input. In this case, assignments using the cursor up, down,
+left and right arrows will be replaced with the numeric 8, 2, 4 and 6 keys on
+the numeric keypad, respectively.
+
+Note that substitutions specified using ``remap`` elements only apply to inputs
+that use MAME’s default assignment for the control type. That is, they only
+apply to default assignments for control types set in the “Inputs (general)”
+menu. They *do not* apply to default input assignments set in driver/device I/O
+port definitions (using the ``PORT_CODE`` macro).
+
+MAME applies ``remap`` elements found inside any applicable ``system`` element.
+
+
+.. _ctrlrcfg-typeoverride:
+
+Overriding defaults by control type
+-----------------------------------
+
+Use ``port`` elements with ``type`` attributes but without ``tag`` attributes to
+override the default host input assignments for a controls:
+
+.. code-block:: XML
+
+ <input>
+ <port type="UI_CONFIGURE">
+ <newseq type="standard">KEYCODE_TAB OR KEYCODE_1 KEYCODE_5</newseq>
+ </port>
+ <port type="UI_CANCEL">
+ <newseq type="standard">KEYCODE_ESC OR KEYCODE_2 KEYCODE_6</newseq>
+ </port>
+
+ <port type="P1_BUTTON1">
+ <newseq type="standard">KEYCODE_C OR JOYCODE_1_BUTTON1</newseq>
+ </port>
+ <port type="P1_BUTTON2">
+ <newseq type="standard">KEYCODE_LSHIFT OR JOYCODE_1_BUTTON2</newseq>
+ </port>
+ <port type="P1_BUTTON3">
+ <newseq type="standard">KEYCODE_Z OR JOYCODE_1_BUTTON3</newseq>
+ </port>
+ <port type="P1_BUTTON4">
+ <newseq type="standard">KEYCODE_X OR JOYCODE_1_BUTTON4</newseq>
+ </port>
+ </input>
+
+This sets the following default input assignments:
+
+Config Menu (User Interface)
+ Tab key, or 1 and 2 keys pressed simultaneously
+UI Cancel (User Interface)
+ Escape key, or 2 and 6 keys pressed simultaneously
+P1 Button 1 (Player 1 Controls)
+ C key, or joystick 1 button 1
+P1 Button 2 (Player 1 Controls)
+ Left Shift key, or joystick 1 button 2
+P1 Button 3 (Player 1 Controls)
+ Z key, or joystick 1 button 3
+P1 Button 4 (Player 1 Controls)
+ X key, or joystick 1 button 4
+
+Note that this will only apply for inputs that use MAME’s default assignment for
+the control type. That is, ``port`` elements without ``tag`` attributes only
+override default assignments for control types set in the “Inputs (general)”
+menu. They *do not* override default input assignments set in driver/device I/O
+port definitions (using the ``PORT_CODE`` macro).
+
+MAME applies ``port`` elements without ``tag`` attributes found inside any
+applicable ``system`` element.
+
+
+.. _ctrlrcfg-ctrloverride:
+
+Overriding defaults for specific controls
+-----------------------------------------
+
+Use ``port`` elements with ``tag``, ``type``, ``mask`` and ``defvalue``
+attributes to override defaults for specific controls. These ``port`` elements
+should only occur inside ``system`` elements that apply to particular systems or
+source files (i.e. they should not occur inside ``system`` elements where the
+``name`` attribute has the value ``default``). The default host input
+assignments can be overridden, as well as the toggle setting for digital
+controls.
+
+The ``tag``, ``type``, ``mask`` and ``defvalue`` are used to identify the
+affected input. You can find out the values to use for a particular input by
+changing its assigned host input, exiting MAME, and checking the values in the
+system configuration file. Note that these values are not guaranteed to be
+stable, and may change between MAME versions.
+
+Here’s an example that overrides defaults for 280-ZZZAP:
+
+.. code-block:: XML
+
+ <system name="280zzzap">
+ <input>
+ <port tag=":IN0" type="P1_BUTTON2" mask="16" defvalue="0" toggle="no" />
+ <port tag=":IN1" type="P1_PADDLE" mask="255" defvalue="127">
+ <newseq type="increment">KEYCODE_K</newseq>
+ <newseq type="decrement">KEYCODE_J</newseq>
+ </port>
+ </input>
+ </system>
+
+This sets the host inputs to steer left and right to the K and J keys,
+respectively, and disables the toggle setting for the gear shift input.
diff --git a/docs/source/advanced/index.rst b/docs/source/advanced/index.rst
index 187ddac7267..9c73762697c 100644
--- a/docs/source/advanced/index.rst
+++ b/docs/source/advanced/index.rst
@@ -2,13 +2,14 @@ Advanced configuration
----------------------
.. toctree::
- :titlesonly:
+ :titlesonly:
- multiconfig
- paths
- shiftertoggle
- bgfx
- hlsl
- glsl
- devicemap
- linux-lightguns
+ multiconfig
+ paths
+ shiftertoggle
+ bgfx
+ hlsl
+ glsl
+ ctrlr_config
+ devicemap
+ linux-lightguns
diff --git a/docs/source/commandline/commandline-all.rst b/docs/source/commandline/commandline-all.rst
index 7979d98b3a8..de46760271a 100644
--- a/docs/source/commandline/commandline-all.rst
+++ b/docs/source/commandline/commandline-all.rst
@@ -32,7 +32,6 @@ patterns to avoid having your shell try to expand them against filenames (e.g.
.. _mame-commandline-paths:
-
File Names and Directory Paths
------------------------------
@@ -1087,7 +1086,7 @@ Core Search Path Options
.. _mame-commandline-artpath:
-**-artpath** *<path>* *<path>*
+**-artpath** *<path>*
Specifies one or more paths within which to find external layout and artwork
files. Multiple paths can be specified by separating them with semicolons.
@@ -1104,8 +1103,9 @@ Core Search Path Options
**-ctrlrpath** *<path>*
- Specifies one or more paths within which to find default input configuration
+ Specifies one or more paths within which to find controller configuration
files. Multiple paths can be specified by separating them with semicolons.
+ Used in conjunction with the ``-ctrlr`` option.
The default is ``ctrlr`` (that is, a directory ``ctrlr`` in the current
working directory).
@@ -2942,11 +2942,13 @@ Core Input Options
**-ctrlr** *<controller>*
- Enables support for special controllers. Configuration files are loaded from
- the ctrlrpath. They are in the same format as the .cfg files that are
- saved, but only control configuration data is read from the file.
+ Specifies a controller configuration file, typically used to set more
+ suitable default input assignments for special controllers. Directories
+ specified using the ``ctrlrpath`` option are searched. Controller
+ configuration files use a similar format to ``.cfg`` used to save system
+ settings. See :ref:`ctrlrcfg` for more details.
- The default is ``NULL`` (no controller file).
+ The default is ``NULL`` (no controller configuration file).
Example:
.. code-block:: bash
diff --git a/src/devices/machine/laserdsc.cpp b/src/devices/machine/laserdsc.cpp
index 2bfd423305d..92fad4019fd 100644
--- a/src/devices/machine/laserdsc.cpp
+++ b/src/devices/machine/laserdsc.cpp
@@ -223,7 +223,10 @@ void laserdisc_device::device_start()
init_audio();
// register callbacks
- machine().configuration().config_register("laserdisc", config_load_delegate(&laserdisc_device::config_load, this), config_save_delegate(&laserdisc_device::config_save, this));
+ machine().configuration().config_register(
+ "laserdisc",
+ configuration_manager::load_delegate(&laserdisc_device::config_load, this),
+ configuration_manager::save_delegate(&laserdisc_device::config_save, this));
}
@@ -1040,20 +1043,16 @@ void laserdisc_device::process_track_data()
// configuration file
//-------------------------------------------------
-void laserdisc_device::config_load(config_type cfg_type, util::xml::data_node const *parentnode)
+void laserdisc_device::config_load(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode)
{
- // we only care about game files
- if (cfg_type != config_type::GAME)
- return;
-
- // might not have any data
- if (parentnode == nullptr)
+ // we only care system-specific configuration
+ if ((cfg_type != config_type::SYSTEM) || !parentnode)
return;
// iterate over overlay nodes
for (util::xml::data_node const *ldnode = parentnode->get_child("device"); ldnode != nullptr; ldnode = ldnode->get_next_sibling("device"))
{
- const char *devtag = ldnode->get_attribute_string("tag", "");
+ char const *const devtag = ldnode->get_attribute_string("tag", "");
if (strcmp(devtag, tag()) == 0)
{
// handle the overlay node
@@ -1078,13 +1077,13 @@ void laserdisc_device::config_load(config_type cfg_type, util::xml::data_node co
void laserdisc_device::config_save(config_type cfg_type, util::xml::data_node *parentnode)
{
- // we only care about game files
- if (cfg_type != config_type::GAME)
+ // we only save system-specific configuration
+ if (cfg_type != config_type::SYSTEM)
return;
// create a node
util::xml::data_node *const ldnode = parentnode->add_child("device", nullptr);
- if (ldnode != nullptr)
+ if (ldnode)
{
// output the basics
ldnode->set_attribute("tag", tag());
diff --git a/src/devices/machine/laserdsc.h b/src/devices/machine/laserdsc.h
index d55b5980a54..5fcc317a761 100644
--- a/src/devices/machine/laserdsc.h
+++ b/src/devices/machine/laserdsc.h
@@ -260,7 +260,7 @@ private:
void read_track_data();
static void *read_async_static(void *param, int threadid);
void process_track_data();
- void config_load(config_type cfg_type, util::xml::data_node const *parentnode);
+ void config_load(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode);
void config_save(config_type cfg_type, util::xml::data_node *parentnode);
// configuration
diff --git a/src/emu/bookkeeping.cpp b/src/emu/bookkeeping.cpp
index a26cf771c7e..4ae4c1ecf2b 100644
--- a/src/emu/bookkeeping.cpp
+++ b/src/emu/bookkeeping.cpp
@@ -39,7 +39,9 @@ bookkeeping_manager::bookkeeping_manager(running_machine &machine)
machine.save().save_item(NAME(m_dispensed_tickets));
// register for configuration
- machine.configuration().config_register("counters", config_load_delegate(&bookkeeping_manager::config_load, this), config_save_delegate(&bookkeeping_manager::config_save, this));
+ machine.configuration().config_register("counters",
+ configuration_manager::load_delegate(&bookkeeping_manager::config_load, this),
+ configuration_manager::save_delegate(&bookkeeping_manager::config_save, this));
}
@@ -80,36 +82,30 @@ void bookkeeping_manager::increment_dispensed_tickets(int delta)
and tickets
-------------------------------------------------*/
-void bookkeeping_manager::config_load(config_type cfg_type, util::xml::data_node const *parentnode)
+void bookkeeping_manager::config_load(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode)
{
- util::xml::data_node const *coinnode, *ticketnode;
-
- /* on init, reset the counters */
+ // on init, reset the counters
if (cfg_type == config_type::INIT)
{
memset(m_coin_count, 0, sizeof(m_coin_count));
m_dispensed_tickets = 0;
}
- /* only care about game-specific data */
- if (cfg_type != config_type::GAME)
- return;
-
- /* might not have any data */
- if (parentnode == nullptr)
+ // only care about system-specific data
+ if ((cfg_type != config_type::SYSTEM) || !parentnode)
return;
- /* iterate over coins nodes */
- for (coinnode = parentnode->get_child("coins"); coinnode; coinnode = coinnode->get_next_sibling("coins"))
+ // iterate over coins nodes
+ for (util::xml::data_node const *coinnode = parentnode->get_child("coins"); coinnode; coinnode = coinnode->get_next_sibling("coins"))
{
int index = coinnode->get_attribute_int("index", -1);
if (index >= 0 && index < COIN_COUNTERS)
m_coin_count[index] = coinnode->get_attribute_int("number", 0);
}
- /* get the single tickets node */
- ticketnode = parentnode->get_child("tickets");
- if (ticketnode != nullptr)
+ // get the single tickets node
+ util::xml::data_node const *const ticketnode = parentnode->get_child("tickets");
+ if (ticketnode)
m_dispensed_tickets = ticketnode->get_attribute_int("number", 0);
}
@@ -121,19 +117,17 @@ void bookkeeping_manager::config_load(config_type cfg_type, util::xml::data_node
void bookkeeping_manager::config_save(config_type cfg_type, util::xml::data_node *parentnode)
{
- int i;
-
- /* only care about game-specific data */
- if (cfg_type != config_type::GAME)
+ // only save system-specific data
+ if (cfg_type != config_type::SYSTEM)
return;
- /* iterate over coin counters */
- for (i = 0; i < COIN_COUNTERS; i++)
+ // iterate over coin counters
+ for (int i = 0; i < COIN_COUNTERS; i++)
{
if (m_coin_count[i] != 0)
{
- util::xml::data_node *coinnode = parentnode->add_child("coins", nullptr);
- if (coinnode != nullptr)
+ util::xml::data_node *const coinnode = parentnode->add_child("coins", nullptr);
+ if (coinnode)
{
coinnode->set_attribute_int("index", i);
coinnode->set_attribute_int("number", m_coin_count[i]);
@@ -141,11 +135,11 @@ void bookkeeping_manager::config_save(config_type cfg_type, util::xml::data_node
}
}
- /* output tickets */
+ // output tickets
if (m_dispensed_tickets != 0)
{
- util::xml::data_node *tickets = parentnode->add_child("tickets", nullptr);
- if (tickets != nullptr)
+ util::xml::data_node *const tickets = parentnode->add_child("tickets", nullptr);
+ if (tickets)
tickets->set_attribute_int("number", m_dispensed_tickets);
}
}
diff --git a/src/emu/bookkeeping.h b/src/emu/bookkeeping.h
index 760789fd536..0d09c497b36 100644
--- a/src/emu/bookkeeping.h
+++ b/src/emu/bookkeeping.h
@@ -57,7 +57,7 @@ public:
// getters
running_machine &machine() const { return m_machine; }
private:
- void config_load(config_type cfg_type, util::xml::data_node const *parentnode);
+ void config_load(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode);
void config_save(config_type cfg_type, util::xml::data_node *parentnode);
// internal state
diff --git a/src/emu/config.cpp b/src/emu/config.cpp
index 42126dcad88..46bec43c1dd 100644
--- a/src/emu/config.cpp
+++ b/src/emu/config.cpp
@@ -39,14 +39,14 @@ configuration_manager::configuration_manager(running_machine &machine)
*
*************************************/
-void configuration_manager::config_register(const char* nodename, config_load_delegate load, config_save_delegate save)
+void configuration_manager::config_register(const char *nodename, load_delegate load, save_delegate save)
{
config_element element;
element.name = nodename;
element.load = std::move(load);
element.save = std::move(save);
- m_typelist.push_back(element);
+ m_typelist.emplace_back(std::move(element));
}
@@ -57,72 +57,69 @@ void configuration_manager::config_register(const char* nodename, config_load_de
*
*************************************/
-int configuration_manager::load_settings()
+bool configuration_manager::load_settings()
{
- const char *controller = machine().options().ctrlr();
- int loaded = 0;
-
- /* loop over all registrants and call their init function */
+ // loop over all registrants and call their init function
for (const auto &type : m_typelist)
- type.load(config_type::INIT, nullptr);
+ type.load(config_type::INIT, config_level::DEFAULT, nullptr);
- /* now load the controller file */
- if (controller[0] != 0)
+ // now load the controller file
+ const char *controller = machine().options().ctrlr();
+ if (controller && *controller)
{
- /* open the config file */
+ // open the config file
emu_file file(machine().options().ctrlr_path(), OPEN_FLAG_READ);
- osd_printf_verbose("Attempting to parse: %s.cfg\n",controller);
+ osd_printf_verbose("Attempting to parse: %s.cfg\n", controller);
osd_file::error filerr = file.open(std::string(controller) + ".cfg");
if (filerr != osd_file::error::NONE)
- throw emu_fatalerror("Could not load controller file %s.cfg", controller);
+ throw emu_fatalerror("Could not open controller file %s.cfg", controller);
- /* load the XML */
+ // load the XML
if (!load_xml(file, config_type::CONTROLLER))
throw emu_fatalerror("Could not load controller file %s.cfg", controller);
}
- /* next load the defaults file */
+ // next load the defaults file
emu_file file(machine().options().cfg_directory(), OPEN_FLAG_READ);
osd_file::error filerr = file.open("default.cfg");
osd_printf_verbose("Attempting to parse: default.cfg\n");
if (filerr == osd_file::error::NONE)
load_xml(file, config_type::DEFAULT);
- /* finally, load the game-specific file */
+ // finally, load the game-specific file
filerr = file.open(machine().basename() + ".cfg");
osd_printf_verbose("Attempting to parse: %s.cfg\n",machine().basename());
- if (filerr == osd_file::error::NONE)
- loaded = load_xml(file, config_type::GAME);
+ const bool loaded = (osd_file::error::NONE == filerr) && load_xml(file, config_type::SYSTEM);
- /* loop over all registrants and call their final function */
+ // loop over all registrants and call their final function
for (const auto &type : m_typelist)
- type.load(config_type::FINAL, nullptr);
+ type.load(config_type::FINAL, config_level::DEFAULT, nullptr);
- /* if we didn't find a saved config, return 0 so the main core knows that it */
- /* is the first time the game is run and it should display the disclaimer. */
+ // if we didn't find a saved config, return false so the main core knows that it
+ // is the first time the game is run and it should display the disclaimer.
return loaded;
}
void configuration_manager::save_settings()
{
- /* loop over all registrants and call their init function */
+ // loop over all registrants and call their init function
for (const auto &type : m_typelist)
type.save(config_type::INIT, nullptr);
- /* save the defaults file */
+ // save the defaults file
emu_file file(machine().options().cfg_directory(), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS);
osd_file::error filerr = file.open("default.cfg");
if (filerr == osd_file::error::NONE)
save_xml(file, config_type::DEFAULT);
- /* finally, save the game-specific file */
+ // finally, save the system-specific file
filerr = file.open(machine().basename() + ".cfg");
if (filerr == osd_file::error::NONE)
- save_xml(file, config_type::GAME);
+ save_xml(file, config_type::SYSTEM);
- /* loop over all registrants and call their final function */
+ // loop over all registrants and call their final function
for (const auto &type : m_typelist)
type.save(config_type::FINAL, nullptr);
}
@@ -135,24 +132,33 @@ void configuration_manager::save_settings()
*
*************************************/
-int configuration_manager::load_xml(emu_file &file, config_type which_type)
+bool configuration_manager::load_xml(emu_file &file, config_type which_type)
{
- /* read the file */
+ // read the file
util::xml::file::ptr const root(util::xml::file::read(file, nullptr));
if (!root)
- return 0;
+ {
+ osd_printf_verbose("Error parsing XML configuration file %s\n", file.filename());
+ return false;
+ }
- /* find the config node */
+ // find the config node
util::xml::data_node const *const confignode = root->get_child("mameconfig");
if (!confignode)
- return 0;
+ {
+ osd_printf_verbose("Could not find root mameconfig element in configuration file %s\n", file.filename());
+ return false;
+ }
- /* validate the config data version */
+ // validate the config data version
int const version = confignode->get_attribute_int("version", 0);
if (version != CONFIG_VERSION)
- return 0;
+ {
+ osd_printf_verbose("Configuration file %s has unsupported version %d\n", file.filename(), version);
+ return false;
+ }
- /* strip off all the path crap from the source filename */
+ // strip off all the path crap from the source filename
const char *srcfile = strrchr(machine().system().type.source(), '/');
if (!srcfile)
srcfile = strrchr(machine().system().type.source(), '\\');
@@ -163,38 +169,67 @@ int configuration_manager::load_xml(emu_file &file, config_type which_type)
else
srcfile++;
- /* loop over all system nodes in the file */
+ // loop over all system nodes in the file
int count = 0;
for (util::xml::data_node const *systemnode = confignode->get_child("system"); systemnode; systemnode = systemnode->get_next_sibling("system"))
{
- /* look up the name of the system here; skip if none */
+ // look up the name of the system here; skip if none
const char *name = systemnode->get_attribute_string("name", "");
- /* based on the file type, determine whether we have a match */
+ // based on the file type, determine whether we have a match
+ config_level level = config_level::DEFAULT;
switch (which_type)
{
- case config_type::GAME:
- /* only match on the specific game name */
- if (strcmp(name, machine().system().name) != 0)
+ case config_type::SYSTEM:
+ // only match on the specific system name
+ if (strcmp(name, machine().system().name))
+ {
+ osd_printf_verbose("Ignoring configuration for system %s in system configuration file %s\n", name, file.filename());
continue;
+ }
+ level = config_level::SYSTEM;
break;
case config_type::DEFAULT:
- /* only match on default */
- if (strcmp(name, "default") != 0)
+ // only match on default
+ if (strcmp(name, "default"))
+ {
+ osd_printf_verbose("Ignoring configuration for system %s in default configuration file %s\n", name, file.filename());
continue;
+ }
+ level = config_level::DEFAULT;
break;
case config_type::CONTROLLER:
{
+ // match on: default, system name, source file name, parent name, grandparent name
int clone_of;
- /* match on: default, game name, source file name, parent name, grandparent name */
- if (strcmp(name, "default") != 0 &&
- strcmp(name, machine().system().name) != 0 &&
- strcmp(name, srcfile) != 0 &&
- ((clone_of = driver_list::clone(machine().system())) == -1 || strcmp(name, driver_list::driver(clone_of).name) != 0) &&
- (clone_of == -1 || ((clone_of = driver_list::clone(clone_of)) == -1) || strcmp(name, driver_list::driver(clone_of).name) != 0))
+ if (!strcmp(name, "default"))
+ {
+ osd_printf_verbose("Applying default configuration from controller configuration file %s\n", file.filename());
+ level = config_level::DEFAULT;
+ }
+ else if (!strcmp(name, machine().system().name))
+ {
+ osd_printf_verbose("Applying configuration for system %s from controller configuration file %s\n", name, file.filename());
+ level = config_level::SYSTEM;
+ }
+ else if (!strcmp(name, srcfile))
+ {
+ osd_printf_verbose("Applying configuration for source file %s from controller configuration file %s\n", name, file.filename());
+ level = config_level::SOURCE;
+ }
+ else if (
+ ((clone_of = driver_list::clone(machine().system())) != -1 && !strcmp(name, driver_list::driver(clone_of).name)) ||
+ (clone_of != -1 && ((clone_of = driver_list::clone(clone_of)) != -1) && !strcmp(name, driver_list::driver(clone_of).name)))
+ {
+ osd_printf_verbose("Applying configuration for parent/BIOS %s from controller configuration file %s\n", name, file.filename());
+ level = (driver_list::driver(clone_of).flags & MACHINE_IS_BIOS_ROOT) ? config_level::BIOS : config_level::PARENT;
+ }
+ else
+ {
continue;
+ }
break;
}
@@ -202,21 +237,18 @@ int configuration_manager::load_xml(emu_file &file, config_type which_type)
break;
}
- /* log that we are processing this entry */
+ // log that we are processing this entry
if (DEBUG_CONFIG)
osd_printf_debug("Entry: %s -- processing\n", name);
- /* loop over all registrants and call their load function */
+ // loop over all registrants and call their load function
for (const auto &type : m_typelist)
- type.load(which_type, systemnode->get_child(type.name.c_str()));
+ type.load(which_type, level, systemnode->get_child(type.name.c_str()));
count++;
}
- /* error if this isn't a valid game match */
- if (count == 0)
- return 0;
-
- return 1;
+ // error if this isn't a valid match
+ return count != 0;
}
@@ -227,43 +259,41 @@ int configuration_manager::load_xml(emu_file &file, config_type which_type)
*
*************************************/
-int configuration_manager::save_xml(emu_file &file, config_type which_type)
+bool configuration_manager::save_xml(emu_file &file, config_type which_type)
{
+ // if we cant't create a root node, bail
util::xml::file::ptr root(util::xml::file::create());
-
- /* if we don't have a root, bail */
if (!root)
- return 0;
+ return false;
- /* create a config node */
+ // create a config node
util::xml::data_node *const confignode = root->add_child("mameconfig", nullptr);
if (!confignode)
- return 0;
+ return false;
confignode->set_attribute_int("version", CONFIG_VERSION);
- /* create a system node */
+ // create a system node
util::xml::data_node *const systemnode = confignode->add_child("system", nullptr);
if (!systemnode)
- return 0;
+ return false;
systemnode->set_attribute("name", (which_type == config_type::DEFAULT) ? "default" : machine().system().name);
- /* create the input node and write it out */
- /* loop over all registrants and call their save function */
+ // loop over all registrants and call their save function
for (const auto &type : m_typelist)
{
util::xml::data_node *const curnode = systemnode->add_child(type.name.c_str(), nullptr);
if (!curnode)
- return 0;
+ return false;
type.save(which_type, curnode);
- /* if nothing was added, just nuke the node */
+ // if nothing was added, just nuke the node
if (!curnode->get_value() && !curnode->get_first_child() && !curnode->count_attributes())
curnode->delete_node();
}
- /* flush the file */
+ // flush the file
root->write(file);
- /* free and get out of here */
- return 1;
+ // free and get out of here
+ return true;
}
diff --git a/src/emu/config.h b/src/emu/config.h
index 59742466e5d..2a273ba248f 100644
--- a/src/emu/config.h
+++ b/src/emu/config.h
@@ -15,60 +15,58 @@
#include "xmlfile.h"
-/*************************************
- *
- * Constants
- *
- *************************************/
-#define CONFIG_VERSION 10
-
-enum class config_type
+enum class config_type : int
{
- INIT = 0, // opportunity to initialize things first
+ INIT, // opportunity to initialize things first
CONTROLLER, // loading from controller file
DEFAULT, // loading from default.cfg
- GAME, // loading from game.cfg
+ SYSTEM, // loading from system.cfg
FINAL // opportunity to finish initialization
};
-/*************************************
- *
- * Type definitions
- *
- *************************************/
-
-typedef delegate<void (config_type, util::xml::data_node const *)> config_load_delegate;
-typedef delegate<void (config_type, util::xml::data_node *)> config_save_delegate;
+enum class config_level : int
+{
+ DEFAULT,
+ SOURCE,
+ BIOS,
+ PARENT,
+ SYSTEM
+};
-// ======================> configuration_manager
class configuration_manager
{
- struct config_element
- {
- std::string name; // node name
- config_load_delegate load; // load callback
- config_save_delegate save; // save callback
- };
-
public:
+ typedef delegate<void (config_type, config_level, util::xml::data_node const *)> load_delegate;
+ typedef delegate<void (config_type, util::xml::data_node *)> save_delegate;
+
+ static inline constexpr int CONFIG_VERSION = 10;
+
// construction/destruction
configuration_manager(running_machine &machine);
- void config_register(const char* nodename, config_load_delegate load, config_save_delegate save);
- int load_settings();
+ void config_register(const char *nodename, load_delegate load, save_delegate save);
+ bool load_settings();
void save_settings();
// getters
running_machine &machine() const { return m_machine; }
+
private:
- int load_xml(emu_file &file, config_type which_type);
- int save_xml(emu_file &file, config_type which_type);
+ struct config_element
+ {
+ std::string name; // node name
+ load_delegate load; // load callback
+ save_delegate save; // save callback
+ };
+
+ bool load_xml(emu_file &file, config_type which_type);
+ bool save_xml(emu_file &file, config_type which_type);
// internal state
running_machine & m_machine; // reference to our machine
std::vector<config_element> m_typelist;
};
-#endif /* MAME_EMU_CONFIG_H */
+#endif // MAME_EMU_CONFIG_H
diff --git a/src/emu/crsshair.cpp b/src/emu/crsshair.cpp
index c8b50afbf4c..43eac50587b 100644
--- a/src/emu/crsshair.cpp
+++ b/src/emu/crsshair.cpp
@@ -248,8 +248,8 @@ void render_crosshair::update_position()
{
// read all the lightgun values
bool gotx = false, goty = false;
- for (auto &port : m_machine.ioport().ports())
- for (ioport_field &field : port.second->fields())
+ for (auto const &port : m_machine.ioport().ports())
+ for (ioport_field const &field : port.second->fields())
if (field.player() == m_player && field.crosshair_axis() != CROSSHAIR_AXIS_NONE && field.enabled())
{
// handle X axis
@@ -357,7 +357,7 @@ crosshair_manager::crosshair_manager(running_machine &machine)
/* determine who needs crosshairs */
for (auto &port : machine.ioport().ports())
- for (ioport_field &field : port.second->fields())
+ for (ioport_field const &field : port.second->fields())
if (field.crosshair_axis() != CROSSHAIR_AXIS_NONE)
{
int player = field.player();
@@ -374,7 +374,11 @@ crosshair_manager::crosshair_manager(running_machine &machine)
/* register callbacks for when we load/save configurations */
if (m_usage)
- machine.configuration().config_register("crosshairs", config_load_delegate(&crosshair_manager::config_load, this), config_save_delegate(&crosshair_manager::config_save, this));
+ {
+ machine.configuration().config_register("crosshairs",
+ configuration_manager::load_delegate(&crosshair_manager::config_load, this),
+ configuration_manager::save_delegate(&crosshair_manager::config_save, this));
+ }
/* register the animation callback */
screen_device *first_screen = screen_device_enumerator(machine.root_device()).first();
@@ -445,19 +449,15 @@ void crosshair_manager::render(screen_device &screen)
configuration file
-------------------------------------------------*/
-void crosshair_manager::config_load(config_type cfg_type, util::xml::data_node const *parentnode)
+void crosshair_manager::config_load(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode)
{
- /* Note: crosshair_load() is only registered if croshairs are used */
+ // Note: crosshair_load() is only registered if croshairs are used
- /* we only care about game files */
- if (cfg_type != config_type::GAME)
+ // we only care about system-specific configuration
+ if ((cfg_type != config_type::SYSTEM) || !parentnode)
return;
- /* might not have any data */
- if (parentnode == nullptr)
- return;
-
- /* loop and get player crosshair info */
+ // loop and get player crosshair info
for (util::xml::data_node const *crosshairnode = parentnode->get_child("crosshair"); crosshairnode; crosshairnode = crosshairnode->get_next_sibling("crosshair"))
{
int const player = crosshairnode->get_attribute_int("player", -1);
@@ -474,8 +474,7 @@ void crosshair_manager::config_load(config_type cfg_type, util::xml::data_node c
if (mode >= CROSSHAIR_VISIBILITY_OFF && mode <= CROSSHAIR_VISIBILITY_AUTO)
{
crosshair.set_mode(u8(mode));
- /* set visibility as specified by mode */
- /* auto mode starts with visibility off */
+ // set visibility as specified by mode - auto mode starts with visibility off
crosshair.set_visible(mode == CROSSHAIR_VISIBILITY_ON);
}
@@ -485,7 +484,7 @@ void crosshair_manager::config_load(config_type cfg_type, util::xml::data_node c
}
}
- /* get, check, and store auto visibility time */
+ // get, check, and store auto visibility time
util::xml::data_node const *crosshairnode = parentnode->get_child("autotime");
if (crosshairnode)
{
@@ -503,10 +502,10 @@ void crosshair_manager::config_load(config_type cfg_type, util::xml::data_node c
void crosshair_manager::config_save(config_type cfg_type, util::xml::data_node *parentnode)
{
- /* Note: crosshair_save() is only registered if crosshairs are used */
+ // Note: crosshair_save() is only registered if crosshairs are used
- /* we only care about game files */
- if (cfg_type != config_type::GAME)
+ // we only create system-specific configuration
+ if (cfg_type != config_type::SYSTEM)
return;
for (int player = 0; player < MAX_PLAYERS; player++)
@@ -515,7 +514,7 @@ void crosshair_manager::config_save(config_type cfg_type, util::xml::data_node *
if (crosshair.is_used())
{
- /* create a node */
+ // create a node
util::xml::data_node *const crosshairnode = parentnode->add_child("crosshair", nullptr);
if (crosshairnode != nullptr)
@@ -537,20 +536,19 @@ void crosshair_manager::config_save(config_type cfg_type, util::xml::data_node *
changed = true;
}
- /* if nothing changed, kill the node */
+ // if nothing changed, kill the node
if (!changed)
crosshairnode->delete_node();
}
}
}
- /* always store autotime so that it stays at the user value if it is needed */
+ // always store autotime so that it stays at the user value if it is needed
if (m_auto_time != CROSSHAIR_VISIBILITY_AUTOTIME_DEFAULT)
{
- /* create a node */
+ // create a node
util::xml::data_node *const crosshairnode = parentnode->add_child("autotime", nullptr);
-
- if (crosshairnode != nullptr)
+ if (crosshairnode)
crosshairnode->set_attribute_int("val", m_auto_time);
}
diff --git a/src/emu/crsshair.h b/src/emu/crsshair.h
index c2fbbf97ea5..dd927ec3637 100644
--- a/src/emu/crsshair.h
+++ b/src/emu/crsshair.h
@@ -118,7 +118,7 @@ private:
void exit();
void animate(screen_device &device, bool vblank_state);
- void config_load(config_type cfg_type, util::xml::data_node const *parentnode);
+ void config_load(config_type cfg_type, config_level cfg_lvl, util::xml::data_node const *parentnode);
void config_save(config_type cfg_type, util::xml::data_node *parentnode);
// internal state
diff --git a/src/emu/emufwd.h b/src/emu/emufwd.h
index 7a8c15da8de..b3969a8fc99 100644
--- a/src/emu/emufwd.h
+++ b/src/emu/emufwd.h
@@ -69,7 +69,8 @@ class address_map_entry;
class bookkeeping_manager;
// declared in config.h
-enum class config_type;
+enum class config_type : int;
+enum class config_level : int;
class configuration_manager;
// declared in crsshair.h
diff --git a/src/emu/image.cpp b/src/emu/image.cpp
index 23cd76c91cd..c80d9bafde7 100644
--- a/src/emu/image.cpp
+++ b/src/emu/image.cpp
@@ -86,7 +86,10 @@ image_manager::image_manager(running_machine &machine)
}
}
- machine.configuration().config_register("image_directories", config_load_delegate(&image_manager::config_load, this), config_save_delegate(&image_manager::config_save, this));
+ machine.configuration().config_register(
+ "image_directories",
+ configuration_manager::load_delegate(&image_manager::config_load, this),
+ configuration_manager::save_delegate(&image_manager::config_save, this));
}
//-------------------------------------------------
@@ -105,9 +108,9 @@ void image_manager::unload_all()
}
}
-void image_manager::config_load(config_type cfg_type, util::xml::data_node const *parentnode)
+void image_manager::config_load(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode)
{
- if ((cfg_type == config_type::GAME) && (parentnode != nullptr))
+ if ((cfg_type == config_type::SYSTEM) && parentnode)
{
for (util::xml::data_node const *node = parentnode->get_child("device"); node; node = node->get_next_sibling("device"))
{
@@ -136,8 +139,8 @@ void image_manager::config_load(config_type cfg_type, util::xml::data_node const
void image_manager::config_save(config_type cfg_type, util::xml::data_node *parentnode)
{
- /* only care about game-specific data */
- if (cfg_type == config_type::GAME)
+ // only save system-specific data
+ if (cfg_type == config_type::SYSTEM)
{
for (device_image_interface &image : image_interface_enumerator(machine().root_device()))
{
diff --git a/src/emu/image.h b/src/emu/image.h
index c7ad11eea66..daf48b1f21d 100644
--- a/src/emu/image.h
+++ b/src/emu/image.h
@@ -30,7 +30,7 @@ public:
std::string setup_working_directory();
private:
- void config_load(config_type cfg_type, util::xml::data_node const *parentnode);
+ void config_load(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode);
void config_save(config_type cfg_type, util::xml::data_node *parentnode);
void options_extract();
diff --git a/src/emu/input.cpp b/src/emu/input.cpp
index 25ecd238d05..1221bf79f66 100644
--- a/src/emu/input.cpp
+++ b/src/emu/input.cpp
@@ -1313,15 +1313,12 @@ void input_manager::seq_from_tokens(input_seq &seq, std::string_view string)
// controller based on device map table
//-------------------------------------------------
-bool input_manager::map_device_to_controller(const devicemap_table_type *devicemap_table)
+bool input_manager::map_device_to_controller(const devicemap_table_type &devicemap_table)
{
- if (nullptr == devicemap_table)
- return true;
-
- for (devicemap_table_type::const_iterator it = devicemap_table->begin(); it != devicemap_table->end(); it++)
+ for (const auto &it : devicemap_table)
{
- std::string_view deviceid = it->first;
- std::string_view controllername = it->second;
+ std::string_view deviceid = it.first;
+ std::string_view controllername = it.second;
// tokenize the controller name into device class and index (i.e. controller name should be of the form "GUNCODE_1")
std::string token[2];
@@ -1360,7 +1357,7 @@ bool input_manager::map_device_to_controller(const devicemap_table_type *devicem
for (int devnum = 0; devnum <= input_devclass->maxindex(); devnum++)
{
input_device *device = input_devclass->device(devnum);
- if (device != nullptr && device->match_device_id(deviceid))
+ if (device && device->match_device_id(deviceid))
{
// remap devindex
input_devclass->remap_device_index(device->devindex(), devindex);
diff --git a/src/emu/input.h b/src/emu/input.h
index df7939489b9..f45f33d312a 100644
--- a/src/emu/input.h
+++ b/src/emu/input.h
@@ -526,7 +526,7 @@ public:
void seq_from_tokens(input_seq &seq, std::string_view _token);
// misc
- bool map_device_to_controller(const devicemap_table_type *devicemap_table = nullptr);
+ bool map_device_to_controller(const devicemap_table_type &devicemap_table);
private:
// internal helpers
diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp
index 02713356bf7..74eda9ddb95 100644
--- a/src/emu/ioport.cpp
+++ b/src/emu/ioport.cpp
@@ -422,8 +422,7 @@ void input_type_entry::restore_default_seq() noexcept
//-------------------------------------------------
digital_joystick::digital_joystick(int player, int number)
- : m_next(nullptr),
- m_player(player),
+ : m_player(player),
m_number(number),
m_current(0),
m_current4way(0),
@@ -529,7 +528,7 @@ bool ioport_condition::eval() const
return true;
// otherwise, read the referenced port and switch off the condition type
- ioport_value condvalue = m_port->read();
+ ioport_value const condvalue = m_port->read();
switch (m_condition)
{
case ALWAYS: return true;
@@ -565,8 +564,7 @@ void ioport_condition::initialize(device_t &device)
//-------------------------------------------------
ioport_setting::ioport_setting(ioport_field &field, ioport_value _value, const char *_name)
- : m_next(nullptr),
- m_field(field),
+ : m_field(field),
m_value(_value),
m_name(_name)
{
@@ -583,8 +581,7 @@ ioport_setting::ioport_setting(ioport_field &field, ioport_value _value, const c
//-------------------------------------------------
ioport_diplocation::ioport_diplocation(const char *name, u8 swnum, bool invert)
- : m_next(nullptr),
- m_name(name),
+ : m_name(name),
m_number(swnum),
m_invert(invert)
{
@@ -926,7 +923,7 @@ void ioport_field::set_user_settings(const user_settings &settings) noexcept
if (!m_settinglist.empty() || m_type == IPT_ADJUSTER)
m_live->value = settings.value;
- if (m_live->analog != nullptr)
+ if (m_live->analog)
{
// if there's analog data, extract the analog settings
m_live->analog->m_sensitivity = settings.sensitivity;
@@ -953,7 +950,7 @@ const char *ioport_field::setting_name() const
assert(!m_settinglist.empty());
// scan the list of settings looking for a match on the current value
- for (ioport_setting &setting : m_settinglist)
+ for (ioport_setting const &setting : m_settinglist)
if (setting.enabled())
if (setting.value() == m_live->value)
return setting.name();
@@ -973,7 +970,7 @@ bool ioport_field::has_previous_setting() const
assert(!m_settinglist.empty());
// scan the list of settings looking for a match on the current value
- for (ioport_setting &setting : m_settinglist)
+ for (ioport_setting const &setting : m_settinglist)
if (setting.enabled())
return (setting.value() != m_live->value);
@@ -992,30 +989,32 @@ void ioport_field::select_previous_setting()
assert(!m_settinglist.empty());
// scan the list of settings looking for a match on the current value
- ioport_setting *prevsetting = nullptr;
+ auto prevsetting = m_settinglist.end();
bool found_match = false;
- for (ioport_setting &setting : m_settinglist)
- if (setting.enabled())
+ for (auto setting = m_settinglist.begin(); m_settinglist.end() != setting; ++setting)
+ {
+ if (setting->enabled())
{
- if (setting.value() == m_live->value)
+ if (setting->value() == m_live->value)
{
found_match = true;
- if (prevsetting != nullptr)
+ if (m_settinglist.end() != prevsetting)
break;
}
- prevsetting = &setting;
+ prevsetting = setting;
}
+ }
// if we didn't find a matching value, select the first
if (!found_match)
{
- for (prevsetting = m_settinglist.first(); prevsetting != nullptr; prevsetting = prevsetting->next())
- if (prevsetting->enabled())
- break;
+ prevsetting = m_settinglist.begin();
+ while ((m_settinglist.end() != prevsetting) && !prevsetting->enabled())
+ ++prevsetting;
}
// update the value to the previous one
- if (prevsetting != nullptr)
+ if (m_settinglist.end() != prevsetting)
m_live->value = prevsetting->value();
}
@@ -1032,7 +1031,8 @@ bool ioport_field::has_next_setting() const
// scan the list of settings looking for a match on the current value
bool found = false;
- for (ioport_setting &setting : m_settinglist)
+ for (ioport_setting const &setting : m_settinglist)
+ {
if (setting.enabled())
{
if (found)
@@ -1040,7 +1040,7 @@ bool ioport_field::has_next_setting() const
if (setting.value() == m_live->value)
found = true;
}
-
+ }
return false;
}
@@ -1056,27 +1056,29 @@ void ioport_field::select_next_setting()
assert(!m_settinglist.empty());
// scan the list of settings looking for a match on the current value
- ioport_setting *nextsetting = nullptr;
- ioport_setting *setting;
- for (setting = m_settinglist.first(); setting != nullptr; setting = setting->next())
- if (setting->enabled())
- if (setting->value() == m_live->value)
- break;
+ auto setting = m_settinglist.begin();
+ while ((m_settinglist.end() != setting) && (!setting->enabled() || (setting->value() != m_live->value)))
+ ++setting;
// if we found one, scan forward for the next valid one
- if (setting != nullptr)
- for (nextsetting = setting->next(); nextsetting != nullptr; nextsetting = nextsetting->next())
- if (nextsetting->enabled())
- break;
+ auto nextsetting = setting;
+ if (m_settinglist.end() != nextsetting)
+ {
+ ++nextsetting;
+ while ((m_settinglist.end() != nextsetting) && !nextsetting->enabled())
+ ++nextsetting;
+ }
// if we hit the end, search from the beginning
- if (nextsetting == nullptr)
- for (nextsetting = m_settinglist.first(); nextsetting != nullptr; nextsetting = nextsetting->next())
- if (nextsetting->enabled())
- break;
+ if (m_settinglist.end() == nextsetting)
+ {
+ nextsetting = m_settinglist.begin();
+ while ((m_settinglist.end() != nextsetting) && !nextsetting->enabled())
+ ++nextsetting;
+ }
// update the value to the previous one
- if (nextsetting != nullptr)
+ if (m_settinglist.end() != nextsetting)
m_live->value = nextsetting->value();
}
@@ -1142,7 +1144,7 @@ void ioport_field::frame_update(ioport_value &result)
// toggle controls: flip the toggle state or advance to the next setting
if (m_live->toggle)
{
- if (m_settinglist.count() == 0)
+ if (m_settinglist.empty())
m_live->value ^= m_mask;
else
select_next_setting();
@@ -1199,7 +1201,7 @@ void ioport_field::frame_update(ioport_value &result)
// position
//-------------------------------------------------
-float ioport_field::crosshair_read()
+float ioport_field::crosshair_read() const
{
float value = m_live->analog->crosshair_read();
@@ -1227,10 +1229,10 @@ float ioport_field::crosshair_read()
void ioport_field::expand_diplocation(const char *location, std::string &errorbuf)
{
// if nothing present, bail
- if (location == nullptr)
+ if (!location)
return;
- m_diploclist.reset();
+ m_diploclist.clear();
// parse the string
std::string name; // Don't move this variable inside the loop, lastname's lifetime depends on it being outside
@@ -1245,23 +1247,21 @@ void ioport_field::expand_diplocation(const char *location, std::string &errorbu
comma = curentry + strlen(curentry);
// extract it to tempbuf
- std::string tempstr;
- tempstr.assign(curentry, comma - curentry);
+ std::string tempstr(curentry, comma - curentry);
// first extract the switch name if present
const char *number = tempstr.c_str();
const char *colon = strchr(tempstr.c_str(), ':');
- // allocate and copy the name if it is present
if (colon != nullptr)
{
+ // allocate and copy the name if it is present
lastname = name.assign(number, colon - number).c_str();
number = colon + 1;
}
-
- // otherwise, just copy the last name
else
{
+ // otherwise, just copy the last name
if (lastname == nullptr)
{
errorbuf.append(string_format("Switch location '%s' missing switch name!\n", location));
@@ -1284,7 +1284,7 @@ void ioport_field::expand_diplocation(const char *location, std::string &errorbu
errorbuf.append(string_format("Switch location '%s' has invalid format!\n", location));
// allocate a new entry
- m_diploclist.append(*new ioport_diplocation(name.c_str(), swnum, invert));
+ m_diploclist.emplace_back(name.c_str(), swnum, invert);
entries++;
// advance to the next item
@@ -1492,7 +1492,7 @@ void ioport_port::frame_update()
m_live->digital = 0;
// now loop back and modify based on the inputs
- for (ioport_field &field : fields())
+ for (ioport_field &field : m_fieldlist)
field.frame_update(m_live->digital);
}
@@ -1620,15 +1620,15 @@ ioport_port_live::ioport_port_live(ioport_port &port)
// allocate analog state if it's analog
analog_field *analog = nullptr;
if (field.is_analog())
- analog = &analoglist.append(*new analog_field(field));
+ analog = &analoglist.emplace_back(field);
// allocate a dynamic field for reading
if (field.has_dynamic_read())
- readlist.append(*new dynamic_field(field));
+ readlist.emplace_back(field);
// allocate a dynamic field for writing
if (field.has_dynamic_write())
- writelist.append(*new dynamic_field(field));
+ writelist.emplace_back(field);
// let the field initialize its live state
field.init_live_state(analog);
@@ -1726,7 +1726,7 @@ time_t ioport_manager::initialize()
const char *joystick_map_default = machine().options().joystick_map();
if (joystick_map_default[0] == 0 || strcmp(joystick_map_default, "auto") == 0)
for (auto &port : m_portlist)
- for (ioport_field &field : port.second->fields())
+ for (ioport_field const &field : port.second->fields())
if (field.live().joystick != nullptr && field.rotated())
{
input_class_joystick &devclass = downcast<input_class_joystick &>(machine().input().device_class(DEVICE_CLASS_JOYSTICK));
@@ -1735,7 +1735,10 @@ time_t ioport_manager::initialize()
}
// register callbacks for when we load configurations
- machine().configuration().config_register("input", config_load_delegate(&ioport_manager::load_config, this), config_save_delegate(&ioport_manager::save_config, this));
+ machine().configuration().config_register(
+ "input",
+ configuration_manager::load_delegate(&ioport_manager::load_config, this),
+ configuration_manager::save_delegate(&ioport_manager::save_config, this));
// open playback and record files if specified
time_t basetime = playback_init();
@@ -1800,7 +1803,7 @@ void ioport_manager::init_autoselect_devices(int type1, int type2, int type3, co
// only scan the list if we haven't already enabled this class of control
if (!autoenable_class->enabled())
for (auto &port : m_portlist)
- for (ioport_field &field : port.second->fields())
+ for (ioport_field const &field : port.second->fields())
// if this port type is in use, apply the autoselect criteria
if ((type1 != 0 && field.type() == type1) || (type2 != 0 && field.type() == type2) || (type3 != 0 && field.type() == type3))
@@ -1921,7 +1924,7 @@ bool ioport_manager::type_pressed(ioport_type type, int player)
bool ioport_manager::type_class_present(ioport_type_class inputclass) const noexcept
{
for (auto &port : m_portlist)
- for (ioport_field &field : port.second->fields())
+ for (ioport_field const &field : port.second->fields())
if (field.type_class() == inputclass)
return true;
return false;
@@ -1937,7 +1940,7 @@ int ioport_manager::count_players() const noexcept
{
int max_player = 0;
for (auto &port : m_portlist)
- for (ioport_field &field : port.second->fields())
+ for (ioport_field const &field : port.second->fields())
if (field.type_class() == INPUT_CLASS_CONTROLLER && max_player <= field.player() + 1)
max_player = field.player() + 1;
@@ -1958,7 +1961,7 @@ digital_joystick &ioport_manager::digjoystick(int player, int number)
return joystick;
// create a new one
- return m_joystick_list.append(*new digital_joystick(player, number));
+ return m_joystick_list.emplace_back(player, number);
}
@@ -2045,7 +2048,7 @@ s32 ioport_manager::frame_interpolate(s32 oldval, s32 newval)
// data from the XML nodes
//-------------------------------------------------
-void ioport_manager::load_config(config_type cfg_type, util::xml::data_node const *parentnode)
+void ioport_manager::load_config(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode)
{
// in the completion phase, we finish the initialization with the final ports
if (cfg_type == config_type::FINAL)
@@ -2062,24 +2065,20 @@ void ioport_manager::load_config(config_type cfg_type, util::xml::data_node cons
if (cfg_type == config_type::CONTROLLER)
{
// iterate over all the remap nodes
- load_remap_table(parentnode);
+ load_remap_table(*parentnode);
- std::unique_ptr<devicemap_table_type> devicemap_table = std::make_unique<devicemap_table_type>();
+ devicemap_table_type devicemap_table;
for (util::xml::data_node const *mapdevice_node = parentnode->get_child("mapdevice"); mapdevice_node != nullptr; mapdevice_node = mapdevice_node->get_next_sibling("mapdevice"))
{
- const char *devicename = mapdevice_node->get_attribute_string("device", nullptr);
- const char *controllername = mapdevice_node->get_attribute_string("controller", nullptr);
- if (devicename != nullptr && controllername != nullptr)
- {
- devicemap_table->insert(std::make_pair(std::string(devicename), std::string(controllername)));
- }
+ char const *const devicename = mapdevice_node->get_attribute_string("device", nullptr);
+ char const *const controllername = mapdevice_node->get_attribute_string("controller", nullptr);
+ if (devicename && controllername)
+ devicemap_table.emplace(devicename, controllername);
}
// map device to controller if we have a device map
- if (!devicemap_table->empty())
- {
- machine().input().map_device_to_controller(devicemap_table.get());
- }
+ if (!devicemap_table.empty())
+ machine().input().map_device_to_controller(devicemap_table);
}
// iterate over all the port nodes
@@ -2099,20 +2098,22 @@ void ioport_manager::load_config(config_type cfg_type, util::xml::data_node cons
{
// with a valid type, parse out the new sequence
input_seq_type seqtype = token_to_seq_type(seqnode->get_attribute_string("type", ""));
- if (seqtype != -1 && seqnode->get_value() != nullptr)
+ if ((seqtype != -1) && seqnode->get_value())
{
- if (strcmp(seqnode->get_value(), "NONE") == 0)
+ if (!strcmp(seqnode->get_value(), "NONE"))
newseq[seqtype].reset();
else
machine().input().seq_from_tokens(newseq[seqtype], seqnode->get_value());
}
}
- // if we're loading default ports, apply to the defaults
- if (cfg_type != config_type::GAME)
- load_default_config(portnode, type, player, newseq);
+ // load into the appropriate place for the config type/level
+ if (config_type::SYSTEM == cfg_type)
+ load_system_config(*portnode, type, player, newseq);
+ else if ((config_type::CONTROLLER == cfg_type) && (config_level::DEFAULT != cfg_level))
+ load_controller_config(*portnode, type, player, newseq);
else
- load_game_config(portnode, type, player, newseq);
+ load_default_config(type, player, newseq);
}
// after applying the controller config, push that back into the backup, since that is
@@ -2123,7 +2124,7 @@ void ioport_manager::load_config(config_type cfg_type, util::xml::data_node cons
entry.defseq(seqtype) = entry.seq(seqtype);
// load keyboard enable/disable state
- if (cfg_type == config_type::GAME)
+ if (cfg_type == config_type::SYSTEM)
{
std::vector<bool> kbd_enable_set;
bool keyboard_enabled = false, missing_enabled = false;
@@ -2191,11 +2192,11 @@ void ioport_manager::load_config(config_type cfg_type, util::xml::data_node cons
// global remapping table
//-------------------------------------------------
-void ioport_manager::load_remap_table(util::xml::data_node const *parentnode)
+void ioport_manager::load_remap_table(util::xml::data_node const &parentnode)
{
// count items first so we can allocate
int count = 0;
- for (util::xml::data_node const *remapnode = parentnode->get_child("remap"); remapnode != nullptr; remapnode = remapnode->get_next_sibling("remap"))
+ for (util::xml::data_node const *remapnode = parentnode.get_child("remap"); remapnode != nullptr; remapnode = remapnode->get_next_sibling("remap"))
count++;
// if we have some, deal with them
@@ -2207,7 +2208,7 @@ void ioport_manager::load_remap_table(util::xml::data_node const *parentnode)
// build up the remap table
count = 0;
- for (util::xml::data_node const *remapnode = parentnode->get_child("remap"); remapnode != nullptr; remapnode = remapnode->get_next_sibling("remap"))
+ for (util::xml::data_node const *remapnode = parentnode.get_child("remap"); remapnode != nullptr; remapnode = remapnode->get_next_sibling("remap"))
{
input_code origcode = machine().input().code_from_token(remapnode->get_attribute_string("origcode", ""));
input_code newcode = machine().input().code_from_token(remapnode->get_attribute_string("newcode", ""));
@@ -2228,14 +2229,15 @@ void ioport_manager::load_remap_table(util::xml::data_node const *parentnode)
//-------------------------------------------------
-// load_default_config - apply configuration
-// data to the default mappings
+// load_default_config - apply input settings
+// to defaults for all systems
//-------------------------------------------------
-bool ioport_manager::load_default_config(util::xml::data_node const *portnode, int type, int player, const input_seq *newseq)
+bool ioport_manager::load_default_config(int type, int player, const input_seq (&newseq)[SEQ_TYPE_TOTAL])
{
// find a matching port in the list
for (input_type_entry &entry : m_typelist)
+ {
if (entry.type() == type && entry.player() == player)
{
for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype)
@@ -2243,116 +2245,197 @@ bool ioport_manager::load_default_config(util::xml::data_node const *portnode, i
entry.set_seq(seqtype, newseq[seqtype]);
return true;
}
-
+ }
return false;
}
//-------------------------------------------------
-// load_game_config - apply configuration
-// data to the current set of input ports
+// load_controller_config - apply controler
+// profile settings to defaults
//-------------------------------------------------
-void ioport_manager::load_game_config(util::xml::data_node const *portnode, int type, int player, const input_seq *newseq)
+bool ioport_manager::load_controller_config(util::xml::data_node const &portnode, int type, int player, const input_seq (&newseq)[SEQ_TYPE_TOTAL])
{
- // read the mask and defvalue attributes
- ioport_value mask = portnode->get_attribute_int("mask", 0);
- ioport_value defvalue = portnode->get_attribute_int("defvalue", 0);
+ // without a tag, apply to the defaults for all systems
+ char const *const tag = portnode.get_attribute_string("tag", nullptr);
+ if (!tag)
+ return load_default_config(type, player, newseq);
- auto const apply =
- [portnode, type, player, newseq, mask, defvalue] (ioport_port &port) -> bool
+ // ensure the port actually exists
+ auto const port(m_portlist.find(tag));
+ if (m_portlist.end() == port)
+ return false;
+ ioport_value const mask = portnode.get_attribute_int("mask", 0);
+ if (!mask)
+ return false;
+
+ // find the matching field
+ ioport_value const defvalue = portnode.get_attribute_int("defvalue", 0);
+ for (ioport_field &field : port->second->fields())
+ {
+ // find the matching mask and default value
+ if (field.type() == type && field.player() == player &&
+ field.mask() == mask && (field.defvalue() & mask) == (defvalue & mask))
{
- for (ioport_field &field : port.fields())
+ // if a sequence was specified, override the developer-specified default for the field
+ for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype)
{
- // find the matching mask and default value
- if (field.type() == type && field.player() == player &&
- field.mask() == mask && (field.defvalue() & mask) == (defvalue & mask))
- {
- // if a sequence was specified, copy it in
- for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype)
- if (newseq[seqtype][0] != INPUT_CODE_INVALID)
- field.live().seq[seqtype] = newseq[seqtype];
+ if (newseq[seqtype][0] != INPUT_CODE_INVALID)
+ field.set_defseq(seqtype, newseq[seqtype]);
+ }
- // fetch configurable attributes
- if (!field.live().analog)
- {
- // for non-analog fields
+ // fetch configurable attributes
+ if (!field.live().analog)
+ {
+ // for non-analog fields
- // fetch the value
- field.live().value = portnode->get_attribute_int("value", field.defvalue());
+ // can't practically set value here
- // fetch yes/no for toggle setting
- char const *const togstring = portnode->get_attribute_string("toggle", nullptr);
- if (togstring)
- field.live().toggle = !strcmp(togstring, "yes");
- }
- else
- {
- // for analog fields
+ // fetch yes/no for toggle setting
+ char const *const togstring = portnode.get_attribute_string("toggle", nullptr);
+ if (togstring && !strcmp(togstring, "yes"))
+ {
+ field.live().toggle = true;
+ field.m_flags |= ioport_field::FIELD_FLAG_TOGGLE;
+ }
+ else if (togstring && !strcmp(togstring, "no"))
+ {
+ field.live().toggle = false;
+ field.m_flags &= ~ioport_field::FIELD_FLAG_TOGGLE;
+ }
+ }
+ else
+ {
+ // for analog fields
- // get base attributes
- field.live().analog->m_delta = portnode->get_attribute_int("keydelta", field.delta());
- field.live().analog->m_centerdelta = portnode->get_attribute_int("centerdelta", field.centerdelta());
- field.live().analog->m_sensitivity = portnode->get_attribute_int("sensitivity", field.sensitivity());
+#if 0 // changing this stuff causes issues because of the way it's tied up with the analog_field object
+ // get base attributes
+ field.live().analog->m_delta = field.m_delta = portnode.get_attribute_int("keydelta", field.delta());
+ field.live().analog->m_centerdelta = field.m_centerdelta = portnode.get_attribute_int("centerdelta", field.centerdelta());
+ field.live().analog->m_sensitivity = field.m_sensitivity = portnode.get_attribute_int("sensitivity", field.sensitivity());
- // fetch yes/no for reverse setting
- const char *revstring = portnode->get_attribute_string("reverse", nullptr);
- if (revstring)
- field.live().analog->m_reverse = !strcmp(revstring, "yes");
- }
- return true;
+ // fetch yes/no for reverse setting
+ char const *const revstring = portnode.get_attribute_string("reverse", nullptr);
+ if (revstring && !strcmp(revstring, "yes"))
+ {
+ field.live().analog->m_reverse = true;
+ field.m_flags |= ioport_field::ANALOG_FLAG_REVERSE;
+ }
+ else if (revstring && !strcmp(revstring, "no"))
+ {
+ field.live().analog->m_reverse = false;
+ field.m_flags &= ~ioport_field::ANALOG_FLAG_REVERSE;
}
+#endif
}
- return false;
- };
+
+ // successfully applied
+ return true;
+ }
+ }
+
+ // no matching field
+ return false;
+}
+
+
+//-------------------------------------------------
+// load_system_config - apply saved input
+// configuration for the current system
+//-------------------------------------------------
+
+void ioport_manager::load_system_config(util::xml::data_node const &portnode, int type, int player, const input_seq (&newseq)[SEQ_TYPE_TOTAL])
+{
+ // system-specific configuration should always apply by port/field
+ char const *const tag = portnode.get_attribute_string("tag", nullptr);
+ ioport_value const mask = portnode.get_attribute_int("mask", 0);
+ ioport_value const defvalue = portnode.get_attribute_int("defvalue", 0);
+ if (!tag || !mask)
+ return;
// find the port we want
- char const *const tag = portnode->get_attribute_string("tag", nullptr);
- if (tag)
+ auto const port(m_portlist.find(tag));
+ if (m_portlist.end() != port)
{
- auto const port(m_portlist.find(tag));
- if (m_portlist.end() != port)
+ for (ioport_field &field : port->second->fields())
{
- apply(*port->second);
+ // find the matching mask and default value
+ if (field.type() == type && field.player() == player &&
+ field.mask() == mask && (field.defvalue() & mask) == (defvalue & mask))
+ {
+ // if a sequence was specified, copy it in
+ for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype)
+ {
+ if (newseq[seqtype][0] != INPUT_CODE_INVALID)
+ field.live().seq[seqtype] = newseq[seqtype];
+ }
+
+ // fetch configurable attributes
+ if (!field.live().analog)
+ {
+ // for non-analog fields
+
+ // fetch the value
+ field.live().value = portnode.get_attribute_int("value", field.defvalue());
+
+ // fetch yes/no for toggle setting
+ char const *const togstring = portnode.get_attribute_string("toggle", nullptr);
+ if (togstring && !strcmp(togstring, "yes"))
+ field.live().toggle = true;
+ else if (togstring && !strcmp(togstring, "no"))
+ field.live().toggle = false;
+ }
+ else
+ {
+ // for analog fields
+
+ // get base attributes
+ field.live().analog->m_delta = portnode.get_attribute_int("keydelta", field.delta());
+ field.live().analog->m_centerdelta = portnode.get_attribute_int("centerdelta", field.centerdelta());
+ field.live().analog->m_sensitivity = portnode.get_attribute_int("sensitivity", field.sensitivity());
+
+ // fetch yes/no for reverse setting
+ char const *const revstring = portnode.get_attribute_string("reverse", nullptr);
+ if (revstring && !strcmp(revstring, "yes"))
+ field.live().analog->m_reverse = true;
+ else if (revstring && !strcmp(revstring, "no"))
+ field.live().analog->m_reverse = false;
+ }
+ break;
+ }
}
- else
+ }
+ else
+ {
+ // see if this belongs to a slot card that isn't inserted
+ std::string_view parent_tag(tag);
+ auto pos(parent_tag.rfind(':'));
+ if (pos && (std::string_view::npos != pos))
{
- // see if this belongs to a slot card that isn't inserted
- std::string_view parent_tag(tag);
- auto pos(parent_tag.rfind(':'));
- if (pos && (std::string_view::npos != pos))
+ parent_tag = parent_tag.substr(0, pos);
+ if (!machine().root_device().subdevice(parent_tag))
{
- parent_tag = parent_tag.substr(0, pos);
- if (!machine().root_device().subdevice(parent_tag))
+ for (pos = parent_tag.rfind(':'); pos && (std::string_view::npos != pos); pos = parent_tag.rfind(':'))
{
- for (pos = parent_tag.rfind(':'); pos && (std::string_view::npos != pos); pos = parent_tag.rfind(':'))
+ std::string_view const child_tag(parent_tag.substr(pos + 1));
+ parent_tag = parent_tag.substr(0, pos);
+ device_t const *const parent_device(machine().root_device().subdevice(parent_tag));
+ if (parent_device)
{
- std::string_view const child_tag(parent_tag.substr(pos + 1));
- parent_tag = parent_tag.substr(0, pos);
- device_t const *const parent_device(machine().root_device().subdevice(parent_tag));
- if (parent_device)
+ device_slot_interface const *slot;
+ if (parent_device->interface(slot) && (slot->option_list().find(std::string(child_tag)) != slot->option_list().end()))
{
- device_slot_interface const *slot;
- if (parent_device->interface(slot) && (slot->option_list().find(std::string(child_tag)) != slot->option_list().end()))
- {
- if (!m_deselected_card_config)
- m_deselected_card_config = util::xml::file::create().release();
- portnode->copy_into(*m_deselected_card_config);
- }
- break;
+ if (!m_deselected_card_config)
+ m_deselected_card_config = util::xml::file::create().release();
+ portnode.copy_into(*m_deselected_card_config);
}
+ break;
}
}
}
}
}
- else
- {
- // if no tag, search them all
- for (auto &port : m_portlist)
- if (apply(*port.second))
- break;
- }
}
@@ -2369,13 +2452,13 @@ void ioport_manager::load_game_config(util::xml::data_node const *portnode, int
void ioport_manager::save_config(config_type cfg_type, util::xml::data_node *parentnode)
{
// if no parentnode, ignore
- if (parentnode == nullptr)
+ if (!parentnode)
return;
// default ports save differently
if (cfg_type == config_type::DEFAULT)
save_default_inputs(*parentnode);
- else
+ else if (cfg_type == config_type::SYSTEM)
save_game_inputs(*parentnode);
}
@@ -2481,7 +2564,7 @@ void ioport_manager::save_game_inputs(util::xml::data_node &parentnode)
// iterate over ports
for (auto &port : m_portlist)
- for (ioport_field &field : port.second->fields())
+ for (ioport_field const &field : port.second->fields())
if (save_this_input_field_type(field.type()))
{
// determine if we changed
@@ -2489,16 +2572,15 @@ void ioport_manager::save_game_inputs(util::xml::data_node &parentnode)
for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype)
changed |= (field.seq(seqtype) != field.defseq(seqtype));
- // non-analog changes
if (!field.is_analog())
{
+ // non-analog changes
changed |= ((field.live().value & field.mask()) != (field.defvalue() & field.mask()));
changed |= (field.live().toggle != field.toggle());
}
-
- // analog changes
else
{
+ // analog changes
changed |= (field.live().analog->m_delta != field.delta());
changed |= (field.live().analog->m_centerdelta != field.centerdelta());
changed |= (field.live().analog->m_sensitivity != field.sensitivity());
@@ -2510,7 +2592,7 @@ void ioport_manager::save_game_inputs(util::xml::data_node &parentnode)
{
// add a new port node
util::xml::data_node *const portnode = parentnode.add_child("port", nullptr);
- if (portnode != nullptr)
+ if (portnode)
{
// add the identifying information and attributes
portnode->set_attribute("tag", port.second->tag());
@@ -2523,18 +2605,17 @@ void ioport_manager::save_game_inputs(util::xml::data_node &parentnode)
if (field.seq(seqtype) != field.defseq(seqtype))
save_sequence(*portnode, seqtype, field.type(), field.seq(seqtype));
- // write out non-analog changes
if (!field.is_analog())
{
+ // write out non-analog changes
if ((field.live().value & field.mask()) != (field.defvalue() & field.mask()))
portnode->set_attribute_int("value", field.live().value & field.mask());
if (field.live().toggle != field.toggle())
portnode->set_attribute("toggle", field.live().toggle ? "yes" : "no");
}
-
- // write out analog changes
else
{
+ // write out analog changes
if (field.live().analog->m_delta != field.delta())
portnode->set_attribute_int("keydelta", field.live().analog->m_delta);
if (field.live().analog->m_centerdelta != field.centerdelta())
@@ -3190,12 +3271,11 @@ ioport_configurer& ioport_configurer::field_add_code(input_seq_type which, input
ioport_configurer& ioport_configurer::setting_alloc(ioport_value value, const char *name)
{
// make sure we have a field
- if (m_curfield == nullptr)
+ if (!m_curfield)
throw emu_fatalerror("alloc_setting called with no active field (value=%X name=%s)\n", value, name);
- m_cursetting = new ioport_setting(*m_curfield, value & m_curfield->mask(), string_from_token(name));
// append a new setting
- m_curfield->m_settinglist.append(*m_cursetting);
+ m_cursetting = &m_curfield->m_settinglist.emplace_back(*m_curfield, value & m_curfield->mask(), string_from_token(name));
return *this;
}
@@ -3207,7 +3287,7 @@ ioport_configurer& ioport_configurer::setting_alloc(ioport_value value, const ch
ioport_configurer& ioport_configurer::set_condition(ioport_condition::condition_t condition, const char *tag, ioport_value mask, ioport_value value)
{
- ioport_condition &target = (m_cursetting != nullptr) ? m_cursetting->condition() : m_curfield->condition();
+ ioport_condition &target = m_cursetting ? m_cursetting->condition() : m_curfield->condition();
target.set(condition, tag, mask, value);
return *this;
}
@@ -3245,8 +3325,7 @@ ioport_configurer& ioport_configurer::onoff_alloc(const char *name, ioport_value
//-------------------------------------------------
dynamic_field::dynamic_field(ioport_field &field)
- : m_next(nullptr),
- m_field(field),
+ : m_field(field),
m_shift(0),
m_oldval(field.defvalue())
{
@@ -3265,15 +3344,15 @@ dynamic_field::dynamic_field(ioport_field &field)
void dynamic_field::read(ioport_value &result)
{
// skip if not enabled
- if (!m_field.enabled())
- return;
-
- // call the callback to read a new value
- ioport_value newval = m_field.m_read();
- m_oldval = newval;
+ if (m_field.enabled())
+ {
+ // call the callback to read a new value
+ ioport_value newval = m_field.m_read();
+ m_oldval = newval;
- // merge in the bits (don't invert yet, as all digitals are inverted together)
- result = (result & ~m_field.mask()) | ((newval << m_shift) & m_field.mask());
+ // merge in the bits (don't invert yet, as all digitals are inverted together)
+ result = (result & ~m_field.mask()) | ((newval << m_shift) & m_field.mask());
+ }
}
@@ -3285,15 +3364,15 @@ void dynamic_field::read(ioport_value &result)
void dynamic_field::write(ioport_value newval)
{
// skip if not enabled
- if (!m_field.enabled())
- return;
-
- // if the bits have changed, call the handler
- newval = (newval & m_field.mask()) >> m_shift;
- if (m_oldval != newval)
+ if (m_field.enabled())
{
- m_field.m_write(m_field, m_field.m_write_param, m_oldval, newval);
- m_oldval = newval;
+ // if the bits have changed, call the handler
+ newval = (newval & m_field.mask()) >> m_shift;
+ if (m_oldval != newval)
+ {
+ m_field.m_write(m_field, m_field.m_write_param, m_oldval, newval);
+ m_oldval = newval;
+ }
}
}
@@ -3303,8 +3382,7 @@ void dynamic_field::write(ioport_value newval)
//-------------------------------------------------
analog_field::analog_field(ioport_field &field)
- : m_next(nullptr),
- m_field(field),
+ : m_field(field),
m_shift(0),
m_adjdefvalue(field.defvalue() & field.mask()),
m_adjmin(field.minval() & field.mask()),
diff --git a/src/emu/ioport.h b/src/emu/ioport.h
index bc42a439a21..11dcf006be9 100644
--- a/src/emu/ioport.h
+++ b/src/emu/ioport.h
@@ -20,8 +20,9 @@
#include <array>
#include <cstdint>
#include <cstring>
-#include <vector>
#include <ctime>
+#include <list>
+#include <vector>
//**************************************************************************
@@ -32,19 +33,19 @@
typedef u32 ioport_value;
// active high/low values for input ports
-const ioport_value IP_ACTIVE_HIGH = 0x00000000;
-const ioport_value IP_ACTIVE_LOW = 0xffffffff;
+constexpr ioport_value IP_ACTIVE_HIGH = 0x00000000;
+constexpr ioport_value IP_ACTIVE_LOW = 0xffffffff;
// maximum number of players supported
-const int MAX_PLAYERS = 10;
+constexpr int MAX_PLAYERS = 10;
// unicode constants
-const char32_t UCHAR_PRIVATE = 0x100000;
-const char32_t UCHAR_SHIFT_1 = UCHAR_PRIVATE + 0;
-const char32_t UCHAR_SHIFT_2 = UCHAR_PRIVATE + 1;
-const char32_t UCHAR_SHIFT_BEGIN = UCHAR_SHIFT_1;
-const char32_t UCHAR_SHIFT_END = UCHAR_SHIFT_2;
-const char32_t UCHAR_MAMEKEY_BEGIN = UCHAR_PRIVATE + 2;
+constexpr char32_t UCHAR_PRIVATE = 0x100000;
+constexpr char32_t UCHAR_SHIFT_1 = UCHAR_PRIVATE + 0;
+constexpr char32_t UCHAR_SHIFT_2 = UCHAR_PRIVATE + 1;
+constexpr char32_t UCHAR_SHIFT_BEGIN = UCHAR_SHIFT_1;
+constexpr char32_t UCHAR_SHIFT_END = UCHAR_SHIFT_2;
+constexpr char32_t UCHAR_MAMEKEY_BEGIN = UCHAR_PRIVATE + 2;
// sequence types for input_port_seq() call
@@ -825,7 +826,6 @@ private:
class digital_joystick
{
DISABLE_COPYING(digital_joystick);
- friend class simple_list<digital_joystick>;
public:
// directions
@@ -848,7 +848,6 @@ public:
digital_joystick(int player, int number);
// getters
- digital_joystick *next() const noexcept { return m_next; }
int player() const noexcept { return m_player; }
int number() const noexcept { return m_number; }
u8 current() const noexcept { return m_current; }
@@ -862,7 +861,6 @@ public:
private:
// internal state
- digital_joystick * m_next; // next joystick in the list
int m_player; // player number represented
int m_number; // joystick number represented
std::forward_list<std::reference_wrapper<ioport_field> > m_field[JOYDIR_COUNT]; // potential input fields for each direction
@@ -933,15 +931,11 @@ private:
// a single setting for a configuration or DIP switch
class ioport_setting
{
- DISABLE_COPYING(ioport_setting);
- friend class simple_list<ioport_setting>;
-
public:
// construction/destruction
ioport_setting(ioport_field &field, ioport_value value, const char *name);
// getters
- ioport_setting *next() const { return m_next; }
ioport_field &field() const { return m_field; }
device_t &device() const;
running_machine &machine() const;
@@ -951,15 +945,14 @@ public:
const char *name() const { return m_name; }
// helpers
- bool enabled() { return m_condition.eval(); }
+ bool enabled() const { return m_condition.eval(); }
private:
// internal state
- ioport_setting * m_next; // pointer to next setting in sequence
- ioport_field & m_field; // pointer back to the field that owns us
- ioport_value m_value; // value of the bits in this setting
- const char * m_name; // user-friendly name to display
- ioport_condition m_condition; // condition under which this setting is valid
+ ioport_field & m_field; // pointer back to the field that owns us
+ ioport_value m_value; // value of the bits in this setting
+ const char * m_name; // user-friendly name to display
+ ioport_condition m_condition; // condition under which this setting is valid
};
@@ -968,24 +961,19 @@ private:
// a mapping from a bit to a physical DIP switch description
class ioport_diplocation
{
- DISABLE_COPYING(ioport_diplocation);
- friend class simple_list<ioport_diplocation>;
-
public:
// construction/destruction
ioport_diplocation(const char *name, u8 swnum, bool invert);
// getters
- ioport_diplocation *next() const { return m_next; }
const char *name() const { return m_name.c_str(); }
u8 number() const { return m_number; }
bool inverted() const { return m_invert; }
private:
- ioport_diplocation * m_next; // pointer to the next bit
- std::string m_name; // name of the physical DIP switch
- u8 m_number; // physical switch number
- bool m_invert; // is this an active-high DIP?
+ std::string m_name; // name of the physical DIP switch
+ u8 m_number; // physical switch number
+ bool m_invert; // is this an active-high DIP?
};
@@ -996,18 +984,19 @@ class ioport_field
{
DISABLE_COPYING(ioport_field);
friend class simple_list<ioport_field>;
+ friend class ioport_manager;
friend class ioport_configurer;
friend class dynamic_field;
// flags for ioport_fields
- static const int FIELD_FLAG_OPTIONAL = 0x0001; // set if this field is not required but recognized by hw
- static const int FIELD_FLAG_COCKTAIL = 0x0002; // set if this field is relevant only for cocktail cabinets
- static const int FIELD_FLAG_TOGGLE = 0x0004; // set if this field should behave as a toggle
- static const int FIELD_FLAG_ROTATED = 0x0008; // set if this field represents a rotated control
- static const int ANALOG_FLAG_REVERSE = 0x0010; // analog only: reverse the sense of the axis
- static const int ANALOG_FLAG_RESET = 0x0020; // analog only: always preload in->default for relative axes, returning only deltas
- static const int ANALOG_FLAG_WRAPS = 0x0040; // analog only: positional count wraps around
- static const int ANALOG_FLAG_INVERT = 0x0080; // analog only: bitwise invert bits
+ static inline constexpr u32 FIELD_FLAG_OPTIONAL = 0x0001; // set if this field is not required but recognized by hw
+ static inline constexpr u32 FIELD_FLAG_COCKTAIL = 0x0002; // set if this field is relevant only for cocktail cabinets
+ static inline constexpr u32 FIELD_FLAG_TOGGLE = 0x0004; // set if this field should behave as a toggle
+ static inline constexpr u32 FIELD_FLAG_ROTATED = 0x0008; // set if this field represents a rotated control
+ static inline constexpr u32 ANALOG_FLAG_REVERSE = 0x0010; // analog only: reverse the sense of the axis
+ static inline constexpr u32 ANALOG_FLAG_RESET = 0x0020; // analog only: always preload in->default for relative axes, returning only deltas
+ static inline constexpr u32 ANALOG_FLAG_WRAPS = 0x0040; // analog only: positional count wraps around
+ static inline constexpr u32 ANALOG_FLAG_INVERT = 0x0080; // analog only: bitwise invert bits
public:
// construction/destruction
@@ -1021,8 +1010,8 @@ public:
ioport_manager &manager() const;
running_machine &machine() const;
int modcount() const { return m_modcount; }
- const simple_list<ioport_setting> &settings() const { return m_settinglist; }
- const simple_list<ioport_diplocation> &diplocations() const { return m_diploclist; }
+ const std::vector<ioport_setting> &settings() const { return m_settinglist; }
+ const std::vector<ioport_diplocation> &diplocations() const { return m_diploclist; }
ioport_value mask() const { return m_mask; }
ioport_value defvalue() const { return m_defvalue; }
@@ -1087,7 +1076,7 @@ public:
void select_previous_setting();
bool has_next_setting() const;
void select_next_setting();
- float crosshair_read();
+ float crosshair_read() const;
void init_live_state(analog_field *analog);
void frame_update(ioport_value &result);
void reduce_mask(ioport_value bits_to_remove) { m_mask &= ~bits_to_remove; }
@@ -1112,10 +1101,10 @@ private:
// internal state
ioport_field * m_next; // pointer to next field in sequence
ioport_port & m_port; // reference to the port that owns us
- std::unique_ptr<ioport_field_live> m_live; // live state of field (nullptr if not live)
+ std::unique_ptr<ioport_field_live> m_live; // live state of field (nullptr if not live)
int m_modcount; // modification count
- simple_list<ioport_setting> m_settinglist; // list of input_setting_configs
- simple_list<ioport_diplocation> m_diploclist; // list of locations for various bits
+ std::vector<ioport_setting> m_settinglist; // list of input_setting_configs
+ std::vector<ioport_diplocation> m_diploclist; // list of locations for various bits
// generally-applicable data
ioport_value m_mask; // mask of bits belonging to the field
@@ -1246,7 +1235,6 @@ private:
// live analog field information
class analog_field
{
- friend class simple_list<analog_field>;
friend class ioport_manager;
friend void ioport_field::set_user_settings(const ioport_field::user_settings &settings) noexcept;
@@ -1255,7 +1243,6 @@ public:
analog_field(ioport_field &field);
// getters
- analog_field *next() const noexcept { return m_next; }
ioport_manager &manager() const noexcept { return m_field.manager(); }
ioport_field &field() const noexcept { return m_field; }
s32 sensitivity() const noexcept { return m_sensitivity; }
@@ -1279,7 +1266,6 @@ private:
s32 apply_inverse_sensitivity(s32 value) const;
// internal state
- analog_field * m_next; // link to the next analog state for this port
ioport_field & m_field; // pointer to the input field referenced
// adjusted values (right-justified and tweaked)
@@ -1329,14 +1315,11 @@ private:
// live device field information
class dynamic_field
{
- friend class simple_list<dynamic_field>;
-
public:
// construction/destruction
dynamic_field(ioport_field &field);
// getters
- dynamic_field *next() const { return m_next; }
ioport_field &field() const { return m_field; }
// read/write
@@ -1345,7 +1328,6 @@ public:
private:
// internal state
- dynamic_field * m_next; // linked list of info for this port
ioport_field & m_field; // reference to the input field
u8 m_shift; // shift to apply to the final result
ioport_value m_oldval; // last value
@@ -1361,9 +1343,9 @@ struct ioport_port_live
ioport_port_live(ioport_port &port);
// public state
- simple_list<analog_field> analoglist; // list of analog port info
- simple_list<dynamic_field> readlist; // list of dynamic read fields
- simple_list<dynamic_field> writelist; // list of dynamic write fields
+ std::list<analog_field> analoglist; // list of analog port info
+ std::vector<dynamic_field> readlist; // list of dynamic read fields
+ std::vector<dynamic_field> writelist; // list of dynamic write fields
ioport_value defvalue; // combined default value across the port
ioport_value digital; // current value from all digital inputs
ioport_value outputvalue; // current value for outputs
@@ -1420,10 +1402,11 @@ private:
input_seq_type token_to_seq_type(const char *string);
static const char *const seqtypestrings[];
- void load_config(config_type cfg_type, util::xml::data_node const *parentnode);
- void load_remap_table(util::xml::data_node const *parentnode);
- bool load_default_config(util::xml::data_node const *portnode, int type, int player, const input_seq *newseq);
- void load_game_config(util::xml::data_node const *portnode, int type, int player, const input_seq *newseq);
+ void load_config(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode);
+ void load_remap_table(util::xml::data_node const &parentnode);
+ bool load_default_config(int type, int player, const input_seq (&newseq)[SEQ_TYPE_TOTAL]);
+ bool load_controller_config(util::xml::data_node const &portnode, int type, int player, const input_seq (&newseq)[SEQ_TYPE_TOTAL]);
+ void load_system_config(util::xml::data_node const &portnode, int type, int player, const input_seq (&newseq)[SEQ_TYPE_TOTAL]);
void save_config(config_type cfg_type, util::xml::data_node *parentnode);
void save_sequence(util::xml::data_node &parentnode, input_seq_type type, ioport_type porttype, const input_seq &seq);
@@ -1457,7 +1440,7 @@ private:
input_type_entry * m_type_to_entry[IPT_COUNT][MAX_PLAYERS]; // map from type/player to type state
// specific special global input states
- simple_list<digital_joystick> m_joystick_list; // list of digital joysticks
+ std::list<digital_joystick> m_joystick_list; // list of digital joysticks
// frame time tracking
attotime m_last_frame_time; // time of the last frame callback
diff --git a/src/emu/network.cpp b/src/emu/network.cpp
index 92ac826e9d8..68c9f93c196 100644
--- a/src/emu/network.cpp
+++ b/src/emu/network.cpp
@@ -26,7 +26,10 @@
network_manager::network_manager(running_machine &machine)
: m_machine(machine)
{
- machine.configuration().config_register("network", config_load_delegate(&network_manager::config_load, this), config_save_delegate(&network_manager::config_save, this));
+ machine.configuration().config_register(
+ "network",
+ configuration_manager::load_delegate(&network_manager::config_load, this),
+ configuration_manager::save_delegate(&network_manager::config_save, this));
}
//-------------------------------------------------
@@ -34,9 +37,9 @@ network_manager::network_manager(running_machine &machine)
// configuration file
//-------------------------------------------------
-void network_manager::config_load(config_type cfg_type, util::xml::data_node const *parentnode)
+void network_manager::config_load(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode)
{
- if ((cfg_type == config_type::GAME) && (parentnode != nullptr))
+ if ((cfg_type == config_type::SYSTEM) && parentnode)
{
for (util::xml::data_node const *node = parentnode->get_child("device"); node; node = node->get_next_sibling("device"))
{
@@ -71,13 +74,13 @@ void network_manager::config_load(config_type cfg_type, util::xml::data_node con
void network_manager::config_save(config_type cfg_type, util::xml::data_node *parentnode)
{
- /* only care about game-specific data */
- if (cfg_type == config_type::GAME)
+ // only save about system-specific data
+ if (cfg_type == config_type::SYSTEM)
{
for (device_network_interface &network : network_interface_enumerator(machine().root_device()))
{
util::xml::data_node *const node = parentnode->add_child("device", nullptr);
- if (node != nullptr)
+ if (node)
{
node->set_attribute("tag", network.device().tag());
node->set_attribute_int("interface", network.get_interface());
diff --git a/src/emu/network.h b/src/emu/network.h
index 5ac8e4f2d37..fff7d68a120 100644
--- a/src/emu/network.h
+++ b/src/emu/network.h
@@ -23,7 +23,7 @@ public:
// getters
running_machine &machine() const { return m_machine; }
private:
- void config_load(config_type cfg_type, util::xml::data_node const *parentnode);
+ void config_load(config_type cfg_type, config_level cfg_lvl, util::xml::data_node const *parentnode);
void config_save(config_type cfg_type, util::xml::data_node *parentnode);
// internal state
diff --git a/src/emu/render.cpp b/src/emu/render.cpp
index 9862b0e35db..236a1d56330 100644
--- a/src/emu/render.cpp
+++ b/src/emu/render.cpp
@@ -3057,7 +3057,10 @@ render_manager::render_manager(running_machine &machine)
, m_ui_container(new render_container(*this))
{
// register callbacks
- machine.configuration().config_register("video", config_load_delegate(&render_manager::config_load, this), config_save_delegate(&render_manager::config_save, this));
+ machine.configuration().config_register(
+ "video",
+ configuration_manager::load_delegate(&render_manager::config_load, this),
+ configuration_manager::save_delegate(&render_manager::config_save, this));
// create one container per screen
for (screen_device &screen : screen_device_enumerator(machine.root_device()))
@@ -3312,10 +3315,10 @@ void render_manager::container_free(render_container *container)
// configuration file
//-------------------------------------------------
-void render_manager::config_load(config_type cfg_type, util::xml::data_node const *parentnode)
+void render_manager::config_load(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode)
{
- // we only care about game files with matching nodes
- if ((cfg_type != config_type::GAME) || !parentnode)
+ // we only care about system-specific configuration with matching nodes
+ if ((cfg_type != config_type::SYSTEM) || !parentnode)
return;
// check the UI target
@@ -3368,8 +3371,8 @@ void render_manager::config_load(config_type cfg_type, util::xml::data_node cons
void render_manager::config_save(config_type cfg_type, util::xml::data_node *parentnode)
{
- // we only care about game files
- if (cfg_type != config_type::GAME)
+ // we only save system-specific configuration
+ if (cfg_type != config_type::SYSTEM)
return;
// write out the interface target
diff --git a/src/emu/render.h b/src/emu/render.h
index 15200967d8a..5833a036077 100644
--- a/src/emu/render.h
+++ b/src/emu/render.h
@@ -701,7 +701,7 @@ private:
void container_free(render_container *container);
// config callbacks
- void config_load(config_type cfg_type, util::xml::data_node const *parentnode);
+ void config_load(config_type cfg_type, config_level cfg_lvl, util::xml::data_node const *parentnode);
void config_save(config_type cfg_type, util::xml::data_node *parentnode);
// internal state
diff --git a/src/emu/rendlay.cpp b/src/emu/rendlay.cpp
index 00322df4203..13b2d6e16c1 100644
--- a/src/emu/rendlay.cpp
+++ b/src/emu/rendlay.cpp
@@ -4659,7 +4659,7 @@ void layout_view::item::resolve_tags()
if (m_input_port)
{
// if there's a matching unconditional field, cache it
- for (ioport_field &field : m_input_port->fields())
+ for (ioport_field const &field : m_input_port->fields())
{
if (field.mask() & m_input_mask)
{
diff --git a/src/emu/sound.cpp b/src/emu/sound.cpp
index 9e970b8fd52..8260762d1f8 100644
--- a/src/emu/sound.cpp
+++ b/src/emu/sound.cpp
@@ -1090,7 +1090,10 @@ sound_manager::sound_manager(running_machine &machine) :
#endif
// register callbacks
- machine.configuration().config_register("mixer", config_load_delegate(&sound_manager::config_load, this), config_save_delegate(&sound_manager::config_save, this));
+ machine.configuration().config_register(
+ "mixer",
+ configuration_manager::load_delegate(&sound_manager::config_load, this),
+ configuration_manager::save_delegate(&sound_manager::config_save, this));
machine.add_notifier(MACHINE_NOTIFY_PAUSE, machine_notify_delegate(&sound_manager::pause, this));
machine.add_notifier(MACHINE_NOTIFY_RESUME, machine_notify_delegate(&sound_manager::resume, this));
machine.add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(&sound_manager::reset, this));
@@ -1356,14 +1359,10 @@ void sound_manager::resume()
// configuration file
//-------------------------------------------------
-void sound_manager::config_load(config_type cfg_type, util::xml::data_node const *parentnode)
+void sound_manager::config_load(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode)
{
- // we only care about game files
- if (cfg_type != config_type::GAME)
- return;
-
- // might not have any data
- if (parentnode == nullptr)
+ // we only care system-specific configuration
+ if ((cfg_type != config_type::SYSTEM) || !parentnode)
return;
// iterate over channel nodes
@@ -1388,29 +1387,28 @@ void sound_manager::config_load(config_type cfg_type, util::xml::data_node const
void sound_manager::config_save(config_type cfg_type, util::xml::data_node *parentnode)
{
- // we only care about game files
- if (cfg_type != config_type::GAME)
+ // we only save system-specific configuration
+ if (cfg_type != config_type::SYSTEM)
return;
// iterate over mixer channels
- if (parentnode != nullptr)
- for (int mixernum = 0; ; mixernum++)
- {
- mixer_input info;
- if (!indexed_mixer_input(mixernum, info))
- break;
- float newvol = info.stream->input(info.inputnum).user_gain();
+ for (int mixernum = 0; ; mixernum++)
+ {
+ mixer_input info;
+ if (!indexed_mixer_input(mixernum, info))
+ break;
- if (newvol != 1.0f)
+ float const newvol = info.stream->input(info.inputnum).user_gain();
+ if (newvol != 1.0f)
+ {
+ util::xml::data_node *const channelnode = parentnode->add_child("channel", nullptr);
+ if (channelnode)
{
- util::xml::data_node *const channelnode = parentnode->add_child("channel", nullptr);
- if (channelnode != nullptr)
- {
- channelnode->set_attribute_int("index", mixernum);
- channelnode->set_attribute_float("newvol", newvol);
- }
+ channelnode->set_attribute_int("index", mixernum);
+ channelnode->set_attribute_float("newvol", newvol);
}
}
+ }
}
diff --git a/src/emu/sound.h b/src/emu/sound.h
index 84c304dab68..2eccb3cdcc9 100644
--- a/src/emu/sound.h
+++ b/src/emu/sound.h
@@ -808,7 +808,7 @@ private:
void resume();
// handle configuration load/save
- void config_load(config_type cfg_type, util::xml::data_node const *parentnode);
+ void config_load(config_type cfg_type, config_level cfg_lvl, util::xml::data_node const *parentnode);
void config_save(config_type cfg_type, util::xml::data_node *parentnode);
// helper to adjust scale factor toward a goal
diff --git a/src/emu/validity.cpp b/src/emu/validity.cpp
index de5321f5347..9bd9edb1ff0 100644
--- a/src/emu/validity.cpp
+++ b/src/emu/validity.cpp
@@ -1706,7 +1706,7 @@ void validity_checker::validate_roms(device_t &root)
// analog input field
//-------------------------------------------------
-void validity_checker::validate_analog_input_field(ioport_field &field)
+void validity_checker::validate_analog_input_field(const ioport_field &field)
{
// analog ports must have a valid sensitivity
if (field.sensitivity() == 0)
@@ -1787,7 +1787,7 @@ void validity_checker::validate_analog_input_field(ioport_field &field)
// setting
//-------------------------------------------------
-void validity_checker::validate_dip_settings(ioport_field &field)
+void validity_checker::validate_dip_settings(const ioport_field &field)
{
const char *demo_sounds = ioport_string_from_index(INPUT_STRING_Demo_Sounds);
const char *flipscreen = ioport_string_from_index(INPUT_STRING_Flip_Screen);
@@ -1795,30 +1795,31 @@ void validity_checker::validate_dip_settings(ioport_field &field)
bool coin_error = false;
// iterate through the settings
- for (ioport_setting &setting : field.settings())
+ for (auto setting = field.settings().begin(); field.settings().end() != setting; ++setting)
{
// note any coinage strings
- int strindex = get_defstr_index(setting.name());
+ int strindex = get_defstr_index(setting->name());
if (strindex >= __input_string_coinage_start && strindex <= __input_string_coinage_end)
coin_list[strindex - __input_string_coinage_start] = 1;
// make sure demo sounds default to on
- if (field.name() == demo_sounds && strindex == INPUT_STRING_On && field.defvalue() != setting.value())
+ if (field.name() == demo_sounds && strindex == INPUT_STRING_On && field.defvalue() != setting->value())
osd_printf_error("Demo Sounds must default to On\n");
// check for bad demo sounds options
if (field.name() == demo_sounds && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No))
- osd_printf_error("Demo Sounds option must be Off/On, not %s\n", setting.name());
+ osd_printf_error("Demo Sounds option must be Off/On, not %s\n", setting->name());
// check for bad flip screen options
if (field.name() == flipscreen && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No))
- osd_printf_error("Flip Screen option must be Off/On, not %s\n", setting.name());
+ osd_printf_error("Flip Screen option must be Off/On, not %s\n", setting->name());
// if we have a neighbor, compare ourselves to him
- if (setting.next() != nullptr)
+ auto const nextsetting = std::next(setting);
+ if (field.settings().end() != nextsetting)
{
// check for inverted off/on dispswitch order
- int next_strindex = get_defstr_index(setting.next()->name(), true);
+ int next_strindex = get_defstr_index(nextsetting->name(), true);
if (strindex == INPUT_STRING_On && next_strindex == INPUT_STRING_Off)
osd_printf_error("%s option must have Off/On options in the order: Off, On\n", field.name());
@@ -1832,9 +1833,9 @@ void validity_checker::validate_dip_settings(ioport_field &field)
// check for proper coin ordering
else if (strindex >= __input_string_coinage_start && strindex <= __input_string_coinage_end && next_strindex >= __input_string_coinage_start && next_strindex <= __input_string_coinage_end &&
- strindex >= next_strindex && setting.condition() == setting.next()->condition())
+ strindex >= next_strindex && setting->condition() == nextsetting->condition())
{
- osd_printf_error("%s option has unsorted coinage %s > %s\n", field.name(), setting.name(), setting.next()->name());
+ osd_printf_error("%s option has unsorted coinage %s > %s\n", field.name(), setting->name(), nextsetting->name());
coin_error = true;
}
}
@@ -1856,7 +1857,7 @@ void validity_checker::validate_dip_settings(ioport_field &field)
// stored within an ioport field or setting
//-------------------------------------------------
-void validity_checker::validate_condition(ioport_condition &condition, device_t &device)
+void validity_checker::validate_condition(const ioport_condition &condition, device_t &device)
{
// resolve the tag, then find a matching port
if (m_ioport_set.find(device.subtag(condition.tag())) == m_ioport_set.end())
@@ -1916,7 +1917,7 @@ void validity_checker::validate_inputs(device_t &root)
}
// iterate through the fields on this port
- for (ioport_field &field : port.second->fields())
+ for (ioport_field const &field : port.second->fields())
{
// verify analog inputs
if (field.is_analog())
@@ -1973,7 +1974,7 @@ void validity_checker::validate_inputs(device_t &root)
validate_condition(field.condition(), device);
// verify conditions on the settings
- for (ioport_setting &setting : field.settings())
+ for (ioport_setting const &setting : field.settings())
if (!setting.condition().none())
validate_condition(setting.condition(), device);
diff --git a/src/emu/validity.h b/src/emu/validity.h
index 594e55a6e9f..bdb30b409e4 100644
--- a/src/emu/validity.h
+++ b/src/emu/validity.h
@@ -74,9 +74,9 @@ private:
void validate_rgb();
void validate_driver(device_t &root);
void validate_roms(device_t &root);
- void validate_analog_input_field(ioport_field &field);
- void validate_dip_settings(ioport_field &field);
- void validate_condition(ioport_condition &condition, device_t &device);
+ void validate_analog_input_field(const ioport_field &field);
+ void validate_dip_settings(const ioport_field &field);
+ void validate_condition(const ioport_condition &condition, device_t &device);
void validate_inputs(device_t &root);
void validate_devices(machine_config &config);
void validate_device_types();
diff --git a/src/frontend/mame/infoxml.cpp b/src/frontend/mame/infoxml.cpp
index d16aa3eef8c..276a2d308ef 100644
--- a/src/frontend/mame/infoxml.cpp
+++ b/src/frontend/mame/infoxml.cpp
@@ -548,7 +548,7 @@ void output_header(std::ostream &out, bool dtd)
"\" mameconfig=\"%d\">\n",
XML_ROOT,
normalize_string(emulator_info::get_build_version()),
- CONFIG_VERSION);
+ configuration_manager::CONFIG_VERSION);
}
@@ -1269,7 +1269,7 @@ void output_input(std::ostream &out, const ioport_list &portlist)
{
int ctrl_type = CTRL_DIGITAL_BUTTONS;
bool ctrl_analog = false;
- for (ioport_field &field : port.second->fields())
+ for (ioport_field const &field : port.second->fields())
{
// track the highest player number
if (nplayer < field.player() + 1)
diff --git a/src/frontend/mame/luaengine_input.cpp b/src/frontend/mame/luaengine_input.cpp
index 8b76e10cac5..71fb4d34210 100644
--- a/src/frontend/mame/luaengine_input.cpp
+++ b/src/frontend/mame/luaengine_input.cpp
@@ -334,7 +334,7 @@ void lua_engine::initialize_input(sol::table &emu)
[this] (ioport_field &f)
{
sol::table result = sol().create_table();
- for (ioport_setting &setting : f.settings())
+ for (ioport_setting const &setting : f.settings())
if (setting.enabled())
result[setting.value()] = setting.name();
return result;
diff --git a/src/frontend/mame/ui/devopt.cpp b/src/frontend/mame/ui/devopt.cpp
index f5e73f290e0..178f0af8d96 100644
--- a/src/frontend/mame/ui/devopt.cpp
+++ b/src/frontend/mame/ui/devopt.cpp
@@ -221,7 +221,7 @@ void menu_device_config::populate(float &customtop, float &custombottom)
{
dips++;
bool def(false);
- for (ioport_setting &setting : field.settings())
+ for (ioport_setting const &setting : field.settings())
{
if (setting.value() == field.defvalue())
{
@@ -237,7 +237,7 @@ void menu_device_config::populate(float &customtop, float &custombottom)
{
confs++;
bool def(false);
- for (ioport_setting &setting : field.settings())
+ for (ioport_setting const &setting : field.settings())
{
if (setting.value() == field.defvalue())
{
diff --git a/src/frontend/mame/ui/ui.cpp b/src/frontend/mame/ui/ui.cpp
index bbc9c1aa6cd..9f176cca141 100644
--- a/src/frontend/mame/ui/ui.cpp
+++ b/src/frontend/mame/ui/ui.cpp
@@ -218,8 +218,8 @@ void mame_ui_manager::init()
machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(&mame_ui_manager::exit, this));
machine().configuration().config_register(
"ui_warnings",
- config_load_delegate(&mame_ui_manager::config_load, this),
- config_save_delegate(&mame_ui_manager::config_save, this));
+ configuration_manager::load_delegate(&mame_ui_manager::config_load, this),
+ configuration_manager::save_delegate(&mame_ui_manager::config_save, this));
// create mouse bitmap
uint32_t *dst = &m_mouse_bitmap.pix(0);
@@ -258,10 +258,10 @@ void mame_ui_manager::exit()
// config_load - load configuration data
//-------------------------------------------------
-void mame_ui_manager::config_load(config_type cfg_type, util::xml::data_node const *parentnode)
+void mame_ui_manager::config_load(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode)
{
// make sure it's relevant and there's data available
- if (config_type::GAME == cfg_type)
+ if (config_type::SYSTEM == cfg_type)
{
m_unemulated_features.clear();
m_imperfect_features.clear();
@@ -302,7 +302,7 @@ void mame_ui_manager::config_load(config_type cfg_type, util::xml::data_node con
void mame_ui_manager::config_save(config_type cfg_type, util::xml::data_node *parentnode)
{
// only save system-level configuration when times are valid
- if ((config_type::GAME == cfg_type) && (std::time_t(-1) != m_last_launch_time) && (std::time_t(-1) != m_last_warning_time))
+ if ((config_type::SYSTEM == cfg_type) && (std::time_t(-1) != m_last_launch_time) && (std::time_t(-1) != m_last_warning_time))
{
parentnode->set_attribute_int("launched", static_cast<long long>(m_last_launch_time));
parentnode->set_attribute_int("warned", static_cast<long long>(m_last_warning_time));
diff --git a/src/frontend/mame/ui/ui.h b/src/frontend/mame/ui/ui.h
index aa169df9fd7..e9df57b3b2d 100644
--- a/src/frontend/mame/ui/ui.h
+++ b/src/frontend/mame/ui/ui.h
@@ -257,7 +257,7 @@ private:
// private methods
void exit();
- void config_load(config_type cfg_type, util::xml::data_node const *parentnode);
+ void config_load(config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode);
void config_save(config_type cfg_type, util::xml::data_node *parentnode);
template <typename... Params> void slider_alloc(Params &&...args) { m_sliders.push_back(std::make_unique<slider_state>(std::forward<Params>(args)...)); }
diff --git a/src/lib/util/unicode.cpp b/src/lib/util/unicode.cpp
index c4ee6c56cde..a375224fd1e 100644
--- a/src/lib/util/unicode.cpp
+++ b/src/lib/util/unicode.cpp
@@ -281,18 +281,21 @@ int uchar_from_utf16f(char32_t *uchar, const char16_t *utf16char, size_t count)
// into a Unicode string
//-------------------------------------------------
-std::u32string ustr_from_utf8(const std::string &utf8str)
+std::u32string ustr_from_utf8(std::string_view utf8str)
{
std::u32string result;
- char const *utf8char(utf8str.c_str());
- size_t remaining(utf8str.length());
- while (remaining)
+ if (!utf8str.empty())
{
- char32_t ch;
- int const consumed(uchar_from_utf8(&ch, utf8char, remaining));
- result.append(1, (consumed > 0) ? ch : char32_t(0x00fffdU));
- utf8char += (consumed > 0) ? consumed : 1;
- remaining -= (consumed > 0) ? consumed : 1;
+ char const *utf8char(&utf8str[0]);
+ auto remaining(utf8str.length());
+ while (remaining)
+ {
+ char32_t ch;
+ int const consumed(uchar_from_utf8(&ch, utf8char, remaining));
+ result.append(1, (consumed > 0) ? ch : char32_t(0x00fffdU));
+ utf8char += (consumed > 0) ? consumed : 1;
+ remaining -= (consumed > 0) ? consumed : 1;
+ }
}
return result;
}
@@ -485,17 +488,6 @@ std::string utf8_from_wstring(const std::wstring &string)
// unicode
//-------------------------------------------------
-std::string normalize_unicode(const std::string &s, unicode_normalization_form normalization_form, bool fold_case)
-{
- return internal_normalize_unicode(s.c_str(), s.length(), normalization_form, fold_case, false);
-}
-
-
-//-------------------------------------------------
-// normalize_unicode - uses utf8proc to normalize
-// unicode
-//-------------------------------------------------
-
std::string normalize_unicode(const char *s, unicode_normalization_form normalization_form, bool fold_case)
{
return internal_normalize_unicode(s, 0, normalization_form, fold_case, true);
diff --git a/src/lib/util/unicode.h b/src/lib/util/unicode.h
index e2788b5e2ab..d6f577289c4 100644
--- a/src/lib/util/unicode.h
+++ b/src/lib/util/unicode.h
@@ -59,7 +59,7 @@ int uchar_from_utf8(char32_t *uchar, const char *utf8char, size_t count);
int uchar_from_utf8(char32_t *uchar, std::string_view utf8str);
int uchar_from_utf16(char32_t *uchar, const char16_t *utf16char, size_t count);
int uchar_from_utf16f(char32_t *uchar, const char16_t *utf16char, size_t count);
-std::u32string ustr_from_utf8(const std::string &utf8str);
+std::u32string ustr_from_utf8(std::string_view utf8str);
// converting 32-bit Unicode chars to strings
int utf8_from_uchar(char *utf8string, size_t count, char32_t uchar);
@@ -72,7 +72,6 @@ std::wstring wstring_from_utf8(const std::string &utf8string);
std::string utf8_from_wstring(const std::wstring &string);
// unicode normalization
-std::string normalize_unicode(const std::string &s, unicode_normalization_form normalization_form, bool fold_case = false);
std::string normalize_unicode(const char *s, unicode_normalization_form normalization_form, bool fold_case = false);
std::string normalize_unicode(std::string_view s, unicode_normalization_form normalization_form, bool fold_case = false);
diff --git a/src/osd/modules/debugger/debugosx.mm b/src/osd/modules/debugger/debugosx.mm
index 629f3e15707..66797e38453 100644
--- a/src/osd/modules/debugger/debugosx.mm
+++ b/src/osd/modules/debugger/debugosx.mm
@@ -71,7 +71,7 @@ public:
private:
void create_console();
void build_menus();
- void config_load(config_type cfgtype, util::xml::data_node const *parentnode);
+ void config_load(config_type cfgtype, config_level cfglevel, util::xml::data_node const *parentnode);
void config_save(config_type cfgtype, util::xml::data_node *parentnode);
running_machine *m_machine;
@@ -129,8 +129,8 @@ void debugger_osx::init_debugger(running_machine &machine)
m_machine = &machine;
machine.configuration().config_register(
"debugger",
- config_load_delegate(&debugger_osx::config_load, this),
- config_save_delegate(&debugger_osx::config_save, this));
+ configuration_manager::load_delegate(&debugger_osx::config_load, this),
+ configuration_manager::save_delegate(&debugger_osx::config_save, this));
}
@@ -305,9 +305,9 @@ void debugger_osx::build_menus()
// restore state based on configuration XML
//============================================================
-void debugger_osx::config_load(config_type cfgtype, util::xml::data_node const *parentnode)
+void debugger_osx::config_load(config_type cfgtype, config_level cfglevel, util::xml::data_node const *parentnode)
{
- if ((config_type::GAME == cfgtype) && parentnode)
+ if ((config_type::SYSTEM == cfgtype) && parentnode)
{
if (m_console)
{
@@ -331,7 +331,7 @@ void debugger_osx::config_load(config_type cfgtype, util::xml::data_node const *
void debugger_osx::config_save(config_type cfgtype, util::xml::data_node *parentnode)
{
- if ((config_type::GAME == cfgtype) && m_console)
+ if ((config_type::SYSTEM == cfgtype) && m_console)
{
NSAutoreleasePool *const pool = [[NSAutoreleasePool alloc] init];
NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:[NSValue valueWithPointer:m_machine],
diff --git a/src/osd/modules/debugger/debugqt.cpp b/src/osd/modules/debugger/debugqt.cpp
index c8845d42448..6731dc63e21 100644
--- a/src/osd/modules/debugger/debugqt.cpp
+++ b/src/osd/modules/debugger/debugqt.cpp
@@ -79,21 +79,17 @@ MainWindow *mainQtWindow = nullptr;
std::vector<std::unique_ptr<WindowQtConfig> > xmlConfigurations;
-void xml_configuration_load(running_machine &machine, config_type cfg_type, util::xml::data_node const *parentnode)
+void xml_configuration_load(running_machine &machine, config_type cfg_type, config_level cfg_level, util::xml::data_node const *parentnode)
{
- // We only care about game files
- if (cfg_type != config_type::GAME)
- return;
-
- // Might not have any data
- if (!parentnode)
+ // We only care about system configuration files
+ if ((cfg_type != config_type::SYSTEM) || !parentnode)
return;
xmlConfigurations.clear();
// Configuration load
util::xml::data_node const *wnode = nullptr;
- for (wnode = parentnode->get_child("window"); wnode != nullptr; wnode = wnode->get_next_sibling("window"))
+ for (wnode = parentnode->get_child("window"); wnode; wnode = wnode->get_next_sibling("window"))
{
WindowQtConfig::WindowType type = (WindowQtConfig::WindowType)wnode->get_attribute_int("type", WindowQtConfig::WIN_TYPE_UNKNOWN);
switch (type)
@@ -114,8 +110,8 @@ void xml_configuration_load(running_machine &machine, config_type cfg_type, util
void xml_configuration_save(running_machine &machine, config_type cfg_type, util::xml::data_node *parentnode)
{
- // We only write to game configurations
- if (cfg_type != config_type::GAME)
+ // We only save system configuration
+ if (cfg_type != config_type::SYSTEM)
return;
for (int i = 0; i < xmlConfigurations.size(); i++)
@@ -269,8 +265,8 @@ void debug_qt::init_debugger(running_machine &machine)
m_machine = &machine;
// Setup the configuration XML saving and loading
machine.configuration().config_register("debugger",
- config_load_delegate(&xml_configuration_load, &machine),
- config_save_delegate(&xml_configuration_save, &machine));
+ configuration_manager::load_delegate(&xml_configuration_load, &machine),
+ configuration_manager::save_delegate(&xml_configuration_save, &machine));
}