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.
This commit is contained in:
parent
66554d3b84
commit
3715746131
229
docs/source/advanced/ctrlr_config.rst
Normal file
229
docs/source/advanced/ctrlr_config.rst
Normal file
@ -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.
|
@ -2,13 +2,14 @@ Advanced configuration
|
|||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:titlesonly:
|
:titlesonly:
|
||||||
|
|
||||||
multiconfig
|
multiconfig
|
||||||
paths
|
paths
|
||||||
shiftertoggle
|
shiftertoggle
|
||||||
bgfx
|
bgfx
|
||||||
hlsl
|
hlsl
|
||||||
glsl
|
glsl
|
||||||
devicemap
|
ctrlr_config
|
||||||
linux-lightguns
|
devicemap
|
||||||
|
linux-lightguns
|
||||||
|
@ -32,7 +32,6 @@ patterns to avoid having your shell try to expand them against filenames (e.g.
|
|||||||
|
|
||||||
.. _mame-commandline-paths:
|
.. _mame-commandline-paths:
|
||||||
|
|
||||||
|
|
||||||
File Names and Directory Paths
|
File Names and Directory Paths
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
@ -1087,7 +1086,7 @@ Core Search Path Options
|
|||||||
|
|
||||||
.. _mame-commandline-artpath:
|
.. _mame-commandline-artpath:
|
||||||
|
|
||||||
**-artpath** *<path>* *<path>*
|
**-artpath** *<path>*
|
||||||
|
|
||||||
Specifies one or more paths within which to find external layout and artwork
|
Specifies one or more paths within which to find external layout and artwork
|
||||||
files. Multiple paths can be specified by separating them with semicolons.
|
files. Multiple paths can be specified by separating them with semicolons.
|
||||||
@ -1104,8 +1103,9 @@ Core Search Path Options
|
|||||||
|
|
||||||
**-ctrlrpath** *<path>*
|
**-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.
|
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
|
The default is ``ctrlr`` (that is, a directory ``ctrlr`` in the current
|
||||||
working directory).
|
working directory).
|
||||||
@ -2942,11 +2942,13 @@ Core Input Options
|
|||||||
|
|
||||||
**-ctrlr** *<controller>*
|
**-ctrlr** *<controller>*
|
||||||
|
|
||||||
Enables support for special controllers. Configuration files are loaded from
|
Specifies a controller configuration file, typically used to set more
|
||||||
the ctrlrpath. They are in the same format as the .cfg files that are
|
suitable default input assignments for special controllers. Directories
|
||||||
saved, but only control configuration data is read from the file.
|
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:
|
Example:
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
@ -223,7 +223,10 @@ void laserdisc_device::device_start()
|
|||||||
init_audio();
|
init_audio();
|
||||||
|
|
||||||
// register callbacks
|
// 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
|
// 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
|
// we only care system-specific configuration
|
||||||
if (cfg_type != config_type::GAME)
|
if ((cfg_type != config_type::SYSTEM) || !parentnode)
|
||||||
return;
|
|
||||||
|
|
||||||
// might not have any data
|
|
||||||
if (parentnode == nullptr)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// iterate over overlay nodes
|
// iterate over overlay nodes
|
||||||
for (util::xml::data_node const *ldnode = parentnode->get_child("device"); ldnode != nullptr; ldnode = ldnode->get_next_sibling("device"))
|
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)
|
if (strcmp(devtag, tag()) == 0)
|
||||||
{
|
{
|
||||||
// handle the overlay node
|
// 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)
|
void laserdisc_device::config_save(config_type cfg_type, util::xml::data_node *parentnode)
|
||||||
{
|
{
|
||||||
// we only care about game files
|
// we only save system-specific configuration
|
||||||
if (cfg_type != config_type::GAME)
|
if (cfg_type != config_type::SYSTEM)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// create a node
|
// create a node
|
||||||
util::xml::data_node *const ldnode = parentnode->add_child("device", nullptr);
|
util::xml::data_node *const ldnode = parentnode->add_child("device", nullptr);
|
||||||
if (ldnode != nullptr)
|
if (ldnode)
|
||||||
{
|
{
|
||||||
// output the basics
|
// output the basics
|
||||||
ldnode->set_attribute("tag", tag());
|
ldnode->set_attribute("tag", tag());
|
||||||
|
@ -260,7 +260,7 @@ private:
|
|||||||
void read_track_data();
|
void read_track_data();
|
||||||
static void *read_async_static(void *param, int threadid);
|
static void *read_async_static(void *param, int threadid);
|
||||||
void process_track_data();
|
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);
|
void config_save(config_type cfg_type, util::xml::data_node *parentnode);
|
||||||
|
|
||||||
// configuration
|
// configuration
|
||||||
|
@ -39,7 +39,9 @@ bookkeeping_manager::bookkeeping_manager(running_machine &machine)
|
|||||||
machine.save().save_item(NAME(m_dispensed_tickets));
|
machine.save().save_item(NAME(m_dispensed_tickets));
|
||||||
|
|
||||||
// register for configuration
|
// 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
|
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)
|
if (cfg_type == config_type::INIT)
|
||||||
{
|
{
|
||||||
memset(m_coin_count, 0, sizeof(m_coin_count));
|
memset(m_coin_count, 0, sizeof(m_coin_count));
|
||||||
m_dispensed_tickets = 0;
|
m_dispensed_tickets = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* only care about game-specific data */
|
// only care about system-specific data
|
||||||
if (cfg_type != config_type::GAME)
|
if ((cfg_type != config_type::SYSTEM) || !parentnode)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* might not have any data */
|
// iterate over coins nodes
|
||||||
if (parentnode == nullptr)
|
for (util::xml::data_node const *coinnode = parentnode->get_child("coins"); coinnode; coinnode = coinnode->get_next_sibling("coins"))
|
||||||
return;
|
|
||||||
|
|
||||||
/* iterate over coins nodes */
|
|
||||||
for (coinnode = parentnode->get_child("coins"); coinnode; coinnode = coinnode->get_next_sibling("coins"))
|
|
||||||
{
|
{
|
||||||
int index = coinnode->get_attribute_int("index", -1);
|
int index = coinnode->get_attribute_int("index", -1);
|
||||||
if (index >= 0 && index < COIN_COUNTERS)
|
if (index >= 0 && index < COIN_COUNTERS)
|
||||||
m_coin_count[index] = coinnode->get_attribute_int("number", 0);
|
m_coin_count[index] = coinnode->get_attribute_int("number", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the single tickets node */
|
// get the single tickets node
|
||||||
ticketnode = parentnode->get_child("tickets");
|
util::xml::data_node const *const ticketnode = parentnode->get_child("tickets");
|
||||||
if (ticketnode != nullptr)
|
if (ticketnode)
|
||||||
m_dispensed_tickets = ticketnode->get_attribute_int("number", 0);
|
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)
|
void bookkeeping_manager::config_save(config_type cfg_type, util::xml::data_node *parentnode)
|
||||||
{
|
{
|
||||||
int i;
|
// only save system-specific data
|
||||||
|
if (cfg_type != config_type::SYSTEM)
|
||||||
/* only care about game-specific data */
|
|
||||||
if (cfg_type != config_type::GAME)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* iterate over coin counters */
|
// iterate over coin counters
|
||||||
for (i = 0; i < COIN_COUNTERS; i++)
|
for (int i = 0; i < COIN_COUNTERS; i++)
|
||||||
{
|
{
|
||||||
if (m_coin_count[i] != 0)
|
if (m_coin_count[i] != 0)
|
||||||
{
|
{
|
||||||
util::xml::data_node *coinnode = parentnode->add_child("coins", nullptr);
|
util::xml::data_node *const coinnode = parentnode->add_child("coins", nullptr);
|
||||||
if (coinnode != nullptr)
|
if (coinnode)
|
||||||
{
|
{
|
||||||
coinnode->set_attribute_int("index", i);
|
coinnode->set_attribute_int("index", i);
|
||||||
coinnode->set_attribute_int("number", m_coin_count[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)
|
if (m_dispensed_tickets != 0)
|
||||||
{
|
{
|
||||||
util::xml::data_node *tickets = parentnode->add_child("tickets", nullptr);
|
util::xml::data_node *const tickets = parentnode->add_child("tickets", nullptr);
|
||||||
if (tickets != nullptr)
|
if (tickets)
|
||||||
tickets->set_attribute_int("number", m_dispensed_tickets);
|
tickets->set_attribute_int("number", m_dispensed_tickets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ public:
|
|||||||
// getters
|
// getters
|
||||||
running_machine &machine() const { return m_machine; }
|
running_machine &machine() const { return m_machine; }
|
||||||
private:
|
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 config_save(config_type cfg_type, util::xml::data_node *parentnode);
|
||||||
|
|
||||||
// internal state
|
// internal state
|
||||||
|
@ -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;
|
config_element element;
|
||||||
element.name = nodename;
|
element.name = nodename;
|
||||||
element.load = std::move(load);
|
element.load = std::move(load);
|
||||||
element.save = std::move(save);
|
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();
|
// loop over all registrants and call their init function
|
||||||
int loaded = 0;
|
|
||||||
|
|
||||||
/* loop over all registrants and call their init function */
|
|
||||||
for (const auto &type : m_typelist)
|
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 */
|
// now load the controller file
|
||||||
if (controller[0] != 0)
|
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);
|
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");
|
osd_file::error filerr = file.open(std::string(controller) + ".cfg");
|
||||||
|
|
||||||
if (filerr != osd_file::error::NONE)
|
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))
|
if (!load_xml(file, config_type::CONTROLLER))
|
||||||
throw emu_fatalerror("Could not load controller file %s.cfg", 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);
|
emu_file file(machine().options().cfg_directory(), OPEN_FLAG_READ);
|
||||||
osd_file::error filerr = file.open("default.cfg");
|
osd_file::error filerr = file.open("default.cfg");
|
||||||
osd_printf_verbose("Attempting to parse: default.cfg\n");
|
osd_printf_verbose("Attempting to parse: default.cfg\n");
|
||||||
if (filerr == osd_file::error::NONE)
|
if (filerr == osd_file::error::NONE)
|
||||||
load_xml(file, config_type::DEFAULT);
|
load_xml(file, config_type::DEFAULT);
|
||||||
|
|
||||||
/* finally, load the game-specific file */
|
// finally, load the game-specific file
|
||||||
filerr = file.open(machine().basename() + ".cfg");
|
filerr = file.open(machine().basename() + ".cfg");
|
||||||
osd_printf_verbose("Attempting to parse: %s.cfg\n",machine().basename());
|
osd_printf_verbose("Attempting to parse: %s.cfg\n",machine().basename());
|
||||||
if (filerr == osd_file::error::NONE)
|
const bool loaded = (osd_file::error::NONE == filerr) && load_xml(file, config_type::SYSTEM);
|
||||||
loaded = load_xml(file, config_type::GAME);
|
|
||||||
|
|
||||||
/* loop over all registrants and call their final function */
|
// loop over all registrants and call their final function
|
||||||
for (const auto &type : m_typelist)
|
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 */
|
// 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. */
|
// is the first time the game is run and it should display the disclaimer.
|
||||||
return loaded;
|
return loaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void configuration_manager::save_settings()
|
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)
|
for (const auto &type : m_typelist)
|
||||||
type.save(config_type::INIT, nullptr);
|
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);
|
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");
|
osd_file::error filerr = file.open("default.cfg");
|
||||||
if (filerr == osd_file::error::NONE)
|
if (filerr == osd_file::error::NONE)
|
||||||
save_xml(file, config_type::DEFAULT);
|
save_xml(file, config_type::DEFAULT);
|
||||||
|
|
||||||
/* finally, save the game-specific file */
|
// finally, save the system-specific file
|
||||||
filerr = file.open(machine().basename() + ".cfg");
|
filerr = file.open(machine().basename() + ".cfg");
|
||||||
if (filerr == osd_file::error::NONE)
|
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)
|
for (const auto &type : m_typelist)
|
||||||
type.save(config_type::FINAL, nullptr);
|
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));
|
util::xml::file::ptr const root(util::xml::file::read(file, nullptr));
|
||||||
if (!root)
|
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");
|
util::xml::data_node const *const confignode = root->get_child("mameconfig");
|
||||||
if (!confignode)
|
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);
|
int const version = confignode->get_attribute_int("version", 0);
|
||||||
if (version != CONFIG_VERSION)
|
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(), '/');
|
const char *srcfile = strrchr(machine().system().type.source(), '/');
|
||||||
if (!srcfile)
|
if (!srcfile)
|
||||||
srcfile = strrchr(machine().system().type.source(), '\\');
|
srcfile = strrchr(machine().system().type.source(), '\\');
|
||||||
@ -163,38 +169,67 @@ int configuration_manager::load_xml(emu_file &file, config_type which_type)
|
|||||||
else
|
else
|
||||||
srcfile++;
|
srcfile++;
|
||||||
|
|
||||||
/* loop over all system nodes in the file */
|
// loop over all system nodes in the file
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (util::xml::data_node const *systemnode = confignode->get_child("system"); systemnode; systemnode = systemnode->get_next_sibling("system"))
|
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", "");
|
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)
|
switch (which_type)
|
||||||
{
|
{
|
||||||
case config_type::GAME:
|
case config_type::SYSTEM:
|
||||||
/* only match on the specific game name */
|
// only match on the specific system name
|
||||||
if (strcmp(name, machine().system().name) != 0)
|
if (strcmp(name, machine().system().name))
|
||||||
|
{
|
||||||
|
osd_printf_verbose("Ignoring configuration for system %s in system configuration file %s\n", name, file.filename());
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
level = config_level::SYSTEM;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case config_type::DEFAULT:
|
case config_type::DEFAULT:
|
||||||
/* only match on default */
|
// only match on default
|
||||||
if (strcmp(name, "default") != 0)
|
if (strcmp(name, "default"))
|
||||||
|
{
|
||||||
|
osd_printf_verbose("Ignoring configuration for system %s in default configuration file %s\n", name, file.filename());
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
level = config_level::DEFAULT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case config_type::CONTROLLER:
|
case config_type::CONTROLLER:
|
||||||
{
|
{
|
||||||
|
// match on: default, system name, source file name, parent name, grandparent name
|
||||||
int clone_of;
|
int clone_of;
|
||||||
/* match on: default, game name, source file name, parent name, grandparent name */
|
if (!strcmp(name, "default"))
|
||||||
if (strcmp(name, "default") != 0 &&
|
{
|
||||||
strcmp(name, machine().system().name) != 0 &&
|
osd_printf_verbose("Applying default configuration from controller configuration file %s\n", file.filename());
|
||||||
strcmp(name, srcfile) != 0 &&
|
level = config_level::DEFAULT;
|
||||||
((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))
|
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;
|
continue;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,21 +237,18 @@ int configuration_manager::load_xml(emu_file &file, config_type which_type)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* log that we are processing this entry */
|
// log that we are processing this entry
|
||||||
if (DEBUG_CONFIG)
|
if (DEBUG_CONFIG)
|
||||||
osd_printf_debug("Entry: %s -- processing\n", name);
|
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)
|
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++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* error if this isn't a valid game match */
|
// error if this isn't a valid match
|
||||||
if (count == 0)
|
return count != 0;
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -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());
|
util::xml::file::ptr root(util::xml::file::create());
|
||||||
|
|
||||||
/* if we don't have a root, bail */
|
|
||||||
if (!root)
|
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);
|
util::xml::data_node *const confignode = root->add_child("mameconfig", nullptr);
|
||||||
if (!confignode)
|
if (!confignode)
|
||||||
return 0;
|
return false;
|
||||||
confignode->set_attribute_int("version", CONFIG_VERSION);
|
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);
|
util::xml::data_node *const systemnode = confignode->add_child("system", nullptr);
|
||||||
if (!systemnode)
|
if (!systemnode)
|
||||||
return 0;
|
return false;
|
||||||
systemnode->set_attribute("name", (which_type == config_type::DEFAULT) ? "default" : machine().system().name);
|
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)
|
for (const auto &type : m_typelist)
|
||||||
{
|
{
|
||||||
util::xml::data_node *const curnode = systemnode->add_child(type.name.c_str(), nullptr);
|
util::xml::data_node *const curnode = systemnode->add_child(type.name.c_str(), nullptr);
|
||||||
if (!curnode)
|
if (!curnode)
|
||||||
return 0;
|
return false;
|
||||||
type.save(which_type, curnode);
|
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())
|
if (!curnode->get_value() && !curnode->get_first_child() && !curnode->count_attributes())
|
||||||
curnode->delete_node();
|
curnode->delete_node();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* flush the file */
|
// flush the file
|
||||||
root->write(file);
|
root->write(file);
|
||||||
|
|
||||||
/* free and get out of here */
|
// free and get out of here
|
||||||
return 1;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -15,60 +15,58 @@
|
|||||||
|
|
||||||
#include "xmlfile.h"
|
#include "xmlfile.h"
|
||||||
|
|
||||||
/*************************************
|
|
||||||
*
|
|
||||||
* Constants
|
|
||||||
*
|
|
||||||
*************************************/
|
|
||||||
|
|
||||||
#define CONFIG_VERSION 10
|
enum class config_type : int
|
||||||
|
|
||||||
enum class config_type
|
|
||||||
{
|
{
|
||||||
INIT = 0, // opportunity to initialize things first
|
INIT, // opportunity to initialize things first
|
||||||
CONTROLLER, // loading from controller file
|
CONTROLLER, // loading from controller file
|
||||||
DEFAULT, // loading from default.cfg
|
DEFAULT, // loading from default.cfg
|
||||||
GAME, // loading from game.cfg
|
SYSTEM, // loading from system.cfg
|
||||||
FINAL // opportunity to finish initialization
|
FINAL // opportunity to finish initialization
|
||||||
};
|
};
|
||||||
|
|
||||||
/*************************************
|
enum class config_level : int
|
||||||
*
|
{
|
||||||
* Type definitions
|
DEFAULT,
|
||||||
*
|
SOURCE,
|
||||||
*************************************/
|
BIOS,
|
||||||
|
PARENT,
|
||||||
|
SYSTEM
|
||||||
|
};
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
// ======================> configuration_manager
|
|
||||||
|
|
||||||
class 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:
|
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
|
// construction/destruction
|
||||||
configuration_manager(running_machine &machine);
|
configuration_manager(running_machine &machine);
|
||||||
|
|
||||||
void config_register(const char* nodename, config_load_delegate load, config_save_delegate save);
|
void config_register(const char *nodename, load_delegate load, save_delegate save);
|
||||||
int load_settings();
|
bool load_settings();
|
||||||
void save_settings();
|
void save_settings();
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
running_machine &machine() const { return m_machine; }
|
running_machine &machine() const { return m_machine; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int load_xml(emu_file &file, config_type which_type);
|
struct config_element
|
||||||
int save_xml(emu_file &file, config_type which_type);
|
{
|
||||||
|
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
|
// internal state
|
||||||
running_machine & m_machine; // reference to our machine
|
running_machine & m_machine; // reference to our machine
|
||||||
std::vector<config_element> m_typelist;
|
std::vector<config_element> m_typelist;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MAME_EMU_CONFIG_H */
|
#endif // MAME_EMU_CONFIG_H
|
||||||
|
@ -248,8 +248,8 @@ void render_crosshair::update_position()
|
|||||||
{
|
{
|
||||||
// read all the lightgun values
|
// read all the lightgun values
|
||||||
bool gotx = false, goty = false;
|
bool gotx = false, goty = false;
|
||||||
for (auto &port : m_machine.ioport().ports())
|
for (auto const &port : m_machine.ioport().ports())
|
||||||
for (ioport_field &field : port.second->fields())
|
for (ioport_field const &field : port.second->fields())
|
||||||
if (field.player() == m_player && field.crosshair_axis() != CROSSHAIR_AXIS_NONE && field.enabled())
|
if (field.player() == m_player && field.crosshair_axis() != CROSSHAIR_AXIS_NONE && field.enabled())
|
||||||
{
|
{
|
||||||
// handle X axis
|
// handle X axis
|
||||||
@ -357,7 +357,7 @@ crosshair_manager::crosshair_manager(running_machine &machine)
|
|||||||
|
|
||||||
/* determine who needs crosshairs */
|
/* determine who needs crosshairs */
|
||||||
for (auto &port : machine.ioport().ports())
|
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)
|
if (field.crosshair_axis() != CROSSHAIR_AXIS_NONE)
|
||||||
{
|
{
|
||||||
int player = field.player();
|
int player = field.player();
|
||||||
@ -374,7 +374,11 @@ crosshair_manager::crosshair_manager(running_machine &machine)
|
|||||||
|
|
||||||
/* register callbacks for when we load/save configurations */
|
/* register callbacks for when we load/save configurations */
|
||||||
if (m_usage)
|
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 */
|
/* register the animation callback */
|
||||||
screen_device *first_screen = screen_device_enumerator(machine.root_device()).first();
|
screen_device *first_screen = screen_device_enumerator(machine.root_device()).first();
|
||||||
@ -445,19 +449,15 @@ void crosshair_manager::render(screen_device &screen)
|
|||||||
configuration file
|
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 */
|
// we only care about system-specific configuration
|
||||||
if (cfg_type != config_type::GAME)
|
if ((cfg_type != config_type::SYSTEM) || !parentnode)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* might not have any data */
|
// loop and get player crosshair info
|
||||||
if (parentnode == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* loop and get player crosshair info */
|
|
||||||
for (util::xml::data_node const *crosshairnode = parentnode->get_child("crosshair"); crosshairnode; crosshairnode = crosshairnode->get_next_sibling("crosshair"))
|
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);
|
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)
|
if (mode >= CROSSHAIR_VISIBILITY_OFF && mode <= CROSSHAIR_VISIBILITY_AUTO)
|
||||||
{
|
{
|
||||||
crosshair.set_mode(u8(mode));
|
crosshair.set_mode(u8(mode));
|
||||||
/* set visibility as specified by mode */
|
// set visibility as specified by mode - auto mode starts with visibility off
|
||||||
/* auto mode starts with visibility off */
|
|
||||||
crosshair.set_visible(mode == CROSSHAIR_VISIBILITY_ON);
|
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");
|
util::xml::data_node const *crosshairnode = parentnode->get_child("autotime");
|
||||||
if (crosshairnode)
|
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)
|
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 */
|
// we only create system-specific configuration
|
||||||
if (cfg_type != config_type::GAME)
|
if (cfg_type != config_type::SYSTEM)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int player = 0; player < MAX_PLAYERS; player++)
|
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())
|
if (crosshair.is_used())
|
||||||
{
|
{
|
||||||
/* create a node */
|
// create a node
|
||||||
util::xml::data_node *const crosshairnode = parentnode->add_child("crosshair", nullptr);
|
util::xml::data_node *const crosshairnode = parentnode->add_child("crosshair", nullptr);
|
||||||
|
|
||||||
if (crosshairnode != nullptr)
|
if (crosshairnode != nullptr)
|
||||||
@ -537,20 +536,19 @@ void crosshair_manager::config_save(config_type cfg_type, util::xml::data_node *
|
|||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if nothing changed, kill the node */
|
// if nothing changed, kill the node
|
||||||
if (!changed)
|
if (!changed)
|
||||||
crosshairnode->delete_node();
|
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)
|
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);
|
util::xml::data_node *const crosshairnode = parentnode->add_child("autotime", nullptr);
|
||||||
|
if (crosshairnode)
|
||||||
if (crosshairnode != nullptr)
|
|
||||||
crosshairnode->set_attribute_int("val", m_auto_time);
|
crosshairnode->set_attribute_int("val", m_auto_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ private:
|
|||||||
void exit();
|
void exit();
|
||||||
void animate(screen_device &device, bool vblank_state);
|
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);
|
void config_save(config_type cfg_type, util::xml::data_node *parentnode);
|
||||||
|
|
||||||
// internal state
|
// internal state
|
||||||
|
@ -69,7 +69,8 @@ class address_map_entry;
|
|||||||
class bookkeeping_manager;
|
class bookkeeping_manager;
|
||||||
|
|
||||||
// declared in config.h
|
// declared in config.h
|
||||||
enum class config_type;
|
enum class config_type : int;
|
||||||
|
enum class config_level : int;
|
||||||
class configuration_manager;
|
class configuration_manager;
|
||||||
|
|
||||||
// declared in crsshair.h
|
// declared in crsshair.h
|
||||||
|
@ -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"))
|
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)
|
void image_manager::config_save(config_type cfg_type, util::xml::data_node *parentnode)
|
||||||
{
|
{
|
||||||
/* only care about game-specific data */
|
// only save system-specific data
|
||||||
if (cfg_type == config_type::GAME)
|
if (cfg_type == config_type::SYSTEM)
|
||||||
{
|
{
|
||||||
for (device_image_interface &image : image_interface_enumerator(machine().root_device()))
|
for (device_image_interface &image : image_interface_enumerator(machine().root_device()))
|
||||||
{
|
{
|
||||||
|
@ -30,7 +30,7 @@ public:
|
|||||||
std::string setup_working_directory();
|
std::string setup_working_directory();
|
||||||
|
|
||||||
private:
|
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 config_save(config_type cfg_type, util::xml::data_node *parentnode);
|
||||||
|
|
||||||
void options_extract();
|
void options_extract();
|
||||||
|
@ -1313,15 +1313,12 @@ void input_manager::seq_from_tokens(input_seq &seq, std::string_view string)
|
|||||||
// controller based on device map table
|
// 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)
|
for (const auto &it : devicemap_table)
|
||||||
return true;
|
|
||||||
|
|
||||||
for (devicemap_table_type::const_iterator it = devicemap_table->begin(); it != devicemap_table->end(); it++)
|
|
||||||
{
|
{
|
||||||
std::string_view deviceid = it->first;
|
std::string_view deviceid = it.first;
|
||||||
std::string_view controllername = it->second;
|
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")
|
// tokenize the controller name into device class and index (i.e. controller name should be of the form "GUNCODE_1")
|
||||||
std::string token[2];
|
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++)
|
for (int devnum = 0; devnum <= input_devclass->maxindex(); devnum++)
|
||||||
{
|
{
|
||||||
input_device *device = input_devclass->device(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
|
// remap devindex
|
||||||
input_devclass->remap_device_index(device->devindex(), devindex);
|
input_devclass->remap_device_index(device->devindex(), devindex);
|
||||||
|
@ -526,7 +526,7 @@ public:
|
|||||||
void seq_from_tokens(input_seq &seq, std::string_view _token);
|
void seq_from_tokens(input_seq &seq, std::string_view _token);
|
||||||
|
|
||||||
// misc
|
// 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:
|
private:
|
||||||
// internal helpers
|
// internal helpers
|
||||||
|
@ -422,8 +422,7 @@ void input_type_entry::restore_default_seq() noexcept
|
|||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
digital_joystick::digital_joystick(int player, int number)
|
digital_joystick::digital_joystick(int player, int number)
|
||||||
: m_next(nullptr),
|
: m_player(player),
|
||||||
m_player(player),
|
|
||||||
m_number(number),
|
m_number(number),
|
||||||
m_current(0),
|
m_current(0),
|
||||||
m_current4way(0),
|
m_current4way(0),
|
||||||
@ -529,7 +528,7 @@ bool ioport_condition::eval() const
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
// otherwise, read the referenced port and switch off the condition type
|
// 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)
|
switch (m_condition)
|
||||||
{
|
{
|
||||||
case ALWAYS: return true;
|
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)
|
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_value(_value),
|
||||||
m_name(_name)
|
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)
|
ioport_diplocation::ioport_diplocation(const char *name, u8 swnum, bool invert)
|
||||||
: m_next(nullptr),
|
: m_name(name),
|
||||||
m_name(name),
|
|
||||||
m_number(swnum),
|
m_number(swnum),
|
||||||
m_invert(invert)
|
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)
|
if (!m_settinglist.empty() || m_type == IPT_ADJUSTER)
|
||||||
m_live->value = settings.value;
|
m_live->value = settings.value;
|
||||||
|
|
||||||
if (m_live->analog != nullptr)
|
if (m_live->analog)
|
||||||
{
|
{
|
||||||
// if there's analog data, extract the analog settings
|
// if there's analog data, extract the analog settings
|
||||||
m_live->analog->m_sensitivity = settings.sensitivity;
|
m_live->analog->m_sensitivity = settings.sensitivity;
|
||||||
@ -953,7 +950,7 @@ const char *ioport_field::setting_name() const
|
|||||||
assert(!m_settinglist.empty());
|
assert(!m_settinglist.empty());
|
||||||
|
|
||||||
// scan the list of settings looking for a match on the current value
|
// 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.enabled())
|
||||||
if (setting.value() == m_live->value)
|
if (setting.value() == m_live->value)
|
||||||
return setting.name();
|
return setting.name();
|
||||||
@ -973,7 +970,7 @@ bool ioport_field::has_previous_setting() const
|
|||||||
assert(!m_settinglist.empty());
|
assert(!m_settinglist.empty());
|
||||||
|
|
||||||
// scan the list of settings looking for a match on the current value
|
// 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.enabled())
|
||||||
return (setting.value() != m_live->value);
|
return (setting.value() != m_live->value);
|
||||||
|
|
||||||
@ -992,30 +989,32 @@ void ioport_field::select_previous_setting()
|
|||||||
assert(!m_settinglist.empty());
|
assert(!m_settinglist.empty());
|
||||||
|
|
||||||
// scan the list of settings looking for a match on the current value
|
// 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;
|
bool found_match = false;
|
||||||
for (ioport_setting &setting : m_settinglist)
|
for (auto setting = m_settinglist.begin(); m_settinglist.end() != setting; ++setting)
|
||||||
if (setting.enabled())
|
{
|
||||||
|
if (setting->enabled())
|
||||||
{
|
{
|
||||||
if (setting.value() == m_live->value)
|
if (setting->value() == m_live->value)
|
||||||
{
|
{
|
||||||
found_match = true;
|
found_match = true;
|
||||||
if (prevsetting != nullptr)
|
if (m_settinglist.end() != prevsetting)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
prevsetting = &setting;
|
prevsetting = setting;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if we didn't find a matching value, select the first
|
// if we didn't find a matching value, select the first
|
||||||
if (!found_match)
|
if (!found_match)
|
||||||
{
|
{
|
||||||
for (prevsetting = m_settinglist.first(); prevsetting != nullptr; prevsetting = prevsetting->next())
|
prevsetting = m_settinglist.begin();
|
||||||
if (prevsetting->enabled())
|
while ((m_settinglist.end() != prevsetting) && !prevsetting->enabled())
|
||||||
break;
|
++prevsetting;
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the value to the previous one
|
// update the value to the previous one
|
||||||
if (prevsetting != nullptr)
|
if (m_settinglist.end() != prevsetting)
|
||||||
m_live->value = prevsetting->value();
|
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
|
// scan the list of settings looking for a match on the current value
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (ioport_setting &setting : m_settinglist)
|
for (ioport_setting const &setting : m_settinglist)
|
||||||
|
{
|
||||||
if (setting.enabled())
|
if (setting.enabled())
|
||||||
{
|
{
|
||||||
if (found)
|
if (found)
|
||||||
@ -1040,7 +1040,7 @@ bool ioport_field::has_next_setting() const
|
|||||||
if (setting.value() == m_live->value)
|
if (setting.value() == m_live->value)
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1056,27 +1056,29 @@ void ioport_field::select_next_setting()
|
|||||||
assert(!m_settinglist.empty());
|
assert(!m_settinglist.empty());
|
||||||
|
|
||||||
// scan the list of settings looking for a match on the current value
|
// scan the list of settings looking for a match on the current value
|
||||||
ioport_setting *nextsetting = nullptr;
|
auto setting = m_settinglist.begin();
|
||||||
ioport_setting *setting;
|
while ((m_settinglist.end() != setting) && (!setting->enabled() || (setting->value() != m_live->value)))
|
||||||
for (setting = m_settinglist.first(); setting != nullptr; setting = setting->next())
|
++setting;
|
||||||
if (setting->enabled())
|
|
||||||
if (setting->value() == m_live->value)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// if we found one, scan forward for the next valid one
|
// if we found one, scan forward for the next valid one
|
||||||
if (setting != nullptr)
|
auto nextsetting = setting;
|
||||||
for (nextsetting = setting->next(); nextsetting != nullptr; nextsetting = nextsetting->next())
|
if (m_settinglist.end() != nextsetting)
|
||||||
if (nextsetting->enabled())
|
{
|
||||||
break;
|
++nextsetting;
|
||||||
|
while ((m_settinglist.end() != nextsetting) && !nextsetting->enabled())
|
||||||
|
++nextsetting;
|
||||||
|
}
|
||||||
|
|
||||||
// if we hit the end, search from the beginning
|
// if we hit the end, search from the beginning
|
||||||
if (nextsetting == nullptr)
|
if (m_settinglist.end() == nextsetting)
|
||||||
for (nextsetting = m_settinglist.first(); nextsetting != nullptr; nextsetting = nextsetting->next())
|
{
|
||||||
if (nextsetting->enabled())
|
nextsetting = m_settinglist.begin();
|
||||||
break;
|
while ((m_settinglist.end() != nextsetting) && !nextsetting->enabled())
|
||||||
|
++nextsetting;
|
||||||
|
}
|
||||||
|
|
||||||
// update the value to the previous one
|
// update the value to the previous one
|
||||||
if (nextsetting != nullptr)
|
if (m_settinglist.end() != nextsetting)
|
||||||
m_live->value = nextsetting->value();
|
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
|
// toggle controls: flip the toggle state or advance to the next setting
|
||||||
if (m_live->toggle)
|
if (m_live->toggle)
|
||||||
{
|
{
|
||||||
if (m_settinglist.count() == 0)
|
if (m_settinglist.empty())
|
||||||
m_live->value ^= m_mask;
|
m_live->value ^= m_mask;
|
||||||
else
|
else
|
||||||
select_next_setting();
|
select_next_setting();
|
||||||
@ -1199,7 +1201,7 @@ void ioport_field::frame_update(ioport_value &result)
|
|||||||
// position
|
// position
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
float ioport_field::crosshair_read()
|
float ioport_field::crosshair_read() const
|
||||||
{
|
{
|
||||||
float value = m_live->analog->crosshair_read();
|
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)
|
void ioport_field::expand_diplocation(const char *location, std::string &errorbuf)
|
||||||
{
|
{
|
||||||
// if nothing present, bail
|
// if nothing present, bail
|
||||||
if (location == nullptr)
|
if (!location)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_diploclist.reset();
|
m_diploclist.clear();
|
||||||
|
|
||||||
// parse the string
|
// parse the string
|
||||||
std::string name; // Don't move this variable inside the loop, lastname's lifetime depends on it being outside
|
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);
|
comma = curentry + strlen(curentry);
|
||||||
|
|
||||||
// extract it to tempbuf
|
// extract it to tempbuf
|
||||||
std::string tempstr;
|
std::string tempstr(curentry, comma - curentry);
|
||||||
tempstr.assign(curentry, comma - curentry);
|
|
||||||
|
|
||||||
// first extract the switch name if present
|
// first extract the switch name if present
|
||||||
const char *number = tempstr.c_str();
|
const char *number = tempstr.c_str();
|
||||||
const char *colon = strchr(tempstr.c_str(), ':');
|
const char *colon = strchr(tempstr.c_str(), ':');
|
||||||
|
|
||||||
// allocate and copy the name if it is present
|
|
||||||
if (colon != nullptr)
|
if (colon != nullptr)
|
||||||
{
|
{
|
||||||
|
// allocate and copy the name if it is present
|
||||||
lastname = name.assign(number, colon - number).c_str();
|
lastname = name.assign(number, colon - number).c_str();
|
||||||
number = colon + 1;
|
number = colon + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, just copy the last name
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// otherwise, just copy the last name
|
||||||
if (lastname == nullptr)
|
if (lastname == nullptr)
|
||||||
{
|
{
|
||||||
errorbuf.append(string_format("Switch location '%s' missing switch name!\n", location));
|
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));
|
errorbuf.append(string_format("Switch location '%s' has invalid format!\n", location));
|
||||||
|
|
||||||
// allocate a new entry
|
// 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++;
|
entries++;
|
||||||
|
|
||||||
// advance to the next item
|
// advance to the next item
|
||||||
@ -1492,7 +1492,7 @@ void ioport_port::frame_update()
|
|||||||
m_live->digital = 0;
|
m_live->digital = 0;
|
||||||
|
|
||||||
// now loop back and modify based on the inputs
|
// 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);
|
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
|
// allocate analog state if it's analog
|
||||||
analog_field *analog = nullptr;
|
analog_field *analog = nullptr;
|
||||||
if (field.is_analog())
|
if (field.is_analog())
|
||||||
analog = &analoglist.append(*new analog_field(field));
|
analog = &analoglist.emplace_back(field);
|
||||||
|
|
||||||
// allocate a dynamic field for reading
|
// allocate a dynamic field for reading
|
||||||
if (field.has_dynamic_read())
|
if (field.has_dynamic_read())
|
||||||
readlist.append(*new dynamic_field(field));
|
readlist.emplace_back(field);
|
||||||
|
|
||||||
// allocate a dynamic field for writing
|
// allocate a dynamic field for writing
|
||||||
if (field.has_dynamic_write())
|
if (field.has_dynamic_write())
|
||||||
writelist.append(*new dynamic_field(field));
|
writelist.emplace_back(field);
|
||||||
|
|
||||||
// let the field initialize its live state
|
// let the field initialize its live state
|
||||||
field.init_live_state(analog);
|
field.init_live_state(analog);
|
||||||
@ -1726,7 +1726,7 @@ time_t ioport_manager::initialize()
|
|||||||
const char *joystick_map_default = machine().options().joystick_map();
|
const char *joystick_map_default = machine().options().joystick_map();
|
||||||
if (joystick_map_default[0] == 0 || strcmp(joystick_map_default, "auto") == 0)
|
if (joystick_map_default[0] == 0 || strcmp(joystick_map_default, "auto") == 0)
|
||||||
for (auto &port : m_portlist)
|
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())
|
if (field.live().joystick != nullptr && field.rotated())
|
||||||
{
|
{
|
||||||
input_class_joystick &devclass = downcast<input_class_joystick &>(machine().input().device_class(DEVICE_CLASS_JOYSTICK));
|
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
|
// 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
|
// open playback and record files if specified
|
||||||
time_t basetime = playback_init();
|
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
|
// only scan the list if we haven't already enabled this class of control
|
||||||
if (!autoenable_class->enabled())
|
if (!autoenable_class->enabled())
|
||||||
for (auto &port : m_portlist)
|
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 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))
|
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
|
bool ioport_manager::type_class_present(ioport_type_class inputclass) const noexcept
|
||||||
{
|
{
|
||||||
for (auto &port : m_portlist)
|
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)
|
if (field.type_class() == inputclass)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
@ -1937,7 +1940,7 @@ int ioport_manager::count_players() const noexcept
|
|||||||
{
|
{
|
||||||
int max_player = 0;
|
int max_player = 0;
|
||||||
for (auto &port : m_portlist)
|
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)
|
if (field.type_class() == INPUT_CLASS_CONTROLLER && max_player <= field.player() + 1)
|
||||||
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;
|
return joystick;
|
||||||
|
|
||||||
// create a new one
|
// 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
|
// 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
|
// in the completion phase, we finish the initialization with the final ports
|
||||||
if (cfg_type == config_type::FINAL)
|
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)
|
if (cfg_type == config_type::CONTROLLER)
|
||||||
{
|
{
|
||||||
// iterate over all the remap nodes
|
// 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"))
|
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);
|
char const *const devicename = mapdevice_node->get_attribute_string("device", nullptr);
|
||||||
const char *controllername = mapdevice_node->get_attribute_string("controller", nullptr);
|
char const *const controllername = mapdevice_node->get_attribute_string("controller", nullptr);
|
||||||
if (devicename != nullptr && controllername != nullptr)
|
if (devicename && controllername)
|
||||||
{
|
devicemap_table.emplace(devicename, controllername);
|
||||||
devicemap_table->insert(std::make_pair(std::string(devicename), std::string(controllername)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// map device to controller if we have a device map
|
// map device to controller if we have a device map
|
||||||
if (!devicemap_table->empty())
|
if (!devicemap_table.empty())
|
||||||
{
|
machine().input().map_device_to_controller(devicemap_table);
|
||||||
machine().input().map_device_to_controller(devicemap_table.get());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// iterate over all the port nodes
|
// 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
|
// with a valid type, parse out the new sequence
|
||||||
input_seq_type seqtype = token_to_seq_type(seqnode->get_attribute_string("type", ""));
|
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();
|
newseq[seqtype].reset();
|
||||||
else
|
else
|
||||||
machine().input().seq_from_tokens(newseq[seqtype], seqnode->get_value());
|
machine().input().seq_from_tokens(newseq[seqtype], seqnode->get_value());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we're loading default ports, apply to the defaults
|
// load into the appropriate place for the config type/level
|
||||||
if (cfg_type != config_type::GAME)
|
if (config_type::SYSTEM == cfg_type)
|
||||||
load_default_config(portnode, type, player, newseq);
|
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
|
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
|
// 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);
|
entry.defseq(seqtype) = entry.seq(seqtype);
|
||||||
|
|
||||||
// load keyboard enable/disable state
|
// load keyboard enable/disable state
|
||||||
if (cfg_type == config_type::GAME)
|
if (cfg_type == config_type::SYSTEM)
|
||||||
{
|
{
|
||||||
std::vector<bool> kbd_enable_set;
|
std::vector<bool> kbd_enable_set;
|
||||||
bool keyboard_enabled = false, missing_enabled = false;
|
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
|
// 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
|
// count items first so we can allocate
|
||||||
int count = 0;
|
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++;
|
count++;
|
||||||
|
|
||||||
// if we have some, deal with them
|
// 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
|
// build up the remap table
|
||||||
count = 0;
|
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 origcode = machine().input().code_from_token(remapnode->get_attribute_string("origcode", ""));
|
||||||
input_code newcode = machine().input().code_from_token(remapnode->get_attribute_string("newcode", ""));
|
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
|
// load_default_config - apply input settings
|
||||||
// data to the default mappings
|
// 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
|
// find a matching port in the list
|
||||||
for (input_type_entry &entry : m_typelist)
|
for (input_type_entry &entry : m_typelist)
|
||||||
|
{
|
||||||
if (entry.type() == type && entry.player() == player)
|
if (entry.type() == type && entry.player() == player)
|
||||||
{
|
{
|
||||||
for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype)
|
for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype)
|
||||||
@ -2243,115 +2245,196 @@ bool ioport_manager::load_default_config(util::xml::data_node const *portnode, i
|
|||||||
entry.set_seq(seqtype, newseq[seqtype]);
|
entry.set_seq(seqtype, newseq[seqtype]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// load_game_config - apply configuration
|
// load_controller_config - apply controler
|
||||||
// data to the current set of input ports
|
// 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
|
// without a tag, apply to the defaults for all systems
|
||||||
ioport_value mask = portnode->get_attribute_int("mask", 0);
|
char const *const tag = portnode.get_attribute_string("tag", nullptr);
|
||||||
ioport_value defvalue = portnode->get_attribute_int("defvalue", 0);
|
if (!tag)
|
||||||
|
return load_default_config(type, player, newseq);
|
||||||
|
|
||||||
auto const apply =
|
// ensure the port actually exists
|
||||||
[portnode, type, player, newseq, mask, defvalue] (ioport_port &port) -> bool
|
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 (newseq[seqtype][0] != INPUT_CODE_INVALID)
|
||||||
if (field.type() == type && field.player() == player &&
|
field.set_defseq(seqtype, newseq[seqtype]);
|
||||||
field.mask() == mask && (field.defvalue() & mask) == (defvalue & mask))
|
}
|
||||||
|
|
||||||
|
// fetch configurable attributes
|
||||||
|
if (!field.live().analog)
|
||||||
|
{
|
||||||
|
// for non-analog fields
|
||||||
|
|
||||||
|
// can't practically set value here
|
||||||
|
|
||||||
|
// fetch yes/no for toggle setting
|
||||||
|
char const *const togstring = portnode.get_attribute_string("toggle", nullptr);
|
||||||
|
if (togstring && !strcmp(togstring, "yes"))
|
||||||
{
|
{
|
||||||
// if a sequence was specified, copy it in
|
field.live().toggle = true;
|
||||||
for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype)
|
field.m_flags |= ioport_field::FIELD_FLAG_TOGGLE;
|
||||||
if (newseq[seqtype][0] != INPUT_CODE_INVALID)
|
}
|
||||||
field.live().seq[seqtype] = newseq[seqtype];
|
else if (togstring && !strcmp(togstring, "no"))
|
||||||
|
{
|
||||||
// fetch configurable attributes
|
field.live().toggle = false;
|
||||||
if (!field.live().analog)
|
field.m_flags &= ~ioport_field::FIELD_FLAG_TOGGLE;
|
||||||
{
|
|
||||||
// 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)
|
|
||||||
field.live().toggle = !strcmp(togstring, "yes");
|
|
||||||
}
|
|
||||||
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
|
|
||||||
const char *revstring = portnode->get_attribute_string("reverse", nullptr);
|
|
||||||
if (revstring)
|
|
||||||
field.live().analog->m_reverse = !strcmp(revstring, "yes");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
else
|
||||||
};
|
{
|
||||||
|
// for analog fields
|
||||||
|
|
||||||
|
#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
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
// find the port we want
|
||||||
char const *const tag = portnode->get_attribute_string("tag", nullptr);
|
auto const port(m_portlist.find(tag));
|
||||||
if (tag)
|
if (m_portlist.end() != port)
|
||||||
{
|
{
|
||||||
auto const port(m_portlist.find(tag));
|
for (ioport_field &field : port->second->fields())
|
||||||
if (m_portlist.end() != port)
|
|
||||||
{
|
{
|
||||||
apply(*port->second);
|
// find the matching mask and default value
|
||||||
}
|
if (field.type() == type && field.player() == player &&
|
||||||
else
|
field.mask() == mask && (field.defvalue() & mask) == (defvalue & mask))
|
||||||
{
|
|
||||||
// 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 a sequence was specified, copy it in
|
||||||
if (!machine().root_device().subdevice(parent_tag))
|
for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype)
|
||||||
{
|
{
|
||||||
for (pos = parent_tag.rfind(':'); pos && (std::string_view::npos != pos); pos = parent_tag.rfind(':'))
|
if (newseq[seqtype][0] != INPUT_CODE_INVALID)
|
||||||
{
|
field.live().seq[seqtype] = newseq[seqtype];
|
||||||
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()))
|
|
||||||
{
|
|
||||||
if (!m_deselected_card_config)
|
|
||||||
m_deselected_card_config = util::xml::file::create().release();
|
|
||||||
portnode->copy_into(*m_deselected_card_config);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
{
|
{
|
||||||
// if no tag, search them all
|
// see if this belongs to a slot card that isn't inserted
|
||||||
for (auto &port : m_portlist)
|
std::string_view parent_tag(tag);
|
||||||
if (apply(*port.second))
|
auto pos(parent_tag.rfind(':'));
|
||||||
break;
|
if (pos && (std::string_view::npos != pos))
|
||||||
|
{
|
||||||
|
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(':'))
|
||||||
|
{
|
||||||
|
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()))
|
||||||
|
{
|
||||||
|
if (!m_deselected_card_config)
|
||||||
|
m_deselected_card_config = util::xml::file::create().release();
|
||||||
|
portnode.copy_into(*m_deselected_card_config);
|
||||||
|
}
|
||||||
|
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)
|
void ioport_manager::save_config(config_type cfg_type, util::xml::data_node *parentnode)
|
||||||
{
|
{
|
||||||
// if no parentnode, ignore
|
// if no parentnode, ignore
|
||||||
if (parentnode == nullptr)
|
if (!parentnode)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// default ports save differently
|
// default ports save differently
|
||||||
if (cfg_type == config_type::DEFAULT)
|
if (cfg_type == config_type::DEFAULT)
|
||||||
save_default_inputs(*parentnode);
|
save_default_inputs(*parentnode);
|
||||||
else
|
else if (cfg_type == config_type::SYSTEM)
|
||||||
save_game_inputs(*parentnode);
|
save_game_inputs(*parentnode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2481,7 +2564,7 @@ void ioport_manager::save_game_inputs(util::xml::data_node &parentnode)
|
|||||||
|
|
||||||
// iterate over ports
|
// iterate over ports
|
||||||
for (auto &port : m_portlist)
|
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()))
|
if (save_this_input_field_type(field.type()))
|
||||||
{
|
{
|
||||||
// determine if we changed
|
// 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)
|
for (input_seq_type seqtype = SEQ_TYPE_STANDARD; seqtype < SEQ_TYPE_TOTAL; ++seqtype)
|
||||||
changed |= (field.seq(seqtype) != field.defseq(seqtype));
|
changed |= (field.seq(seqtype) != field.defseq(seqtype));
|
||||||
|
|
||||||
// non-analog changes
|
|
||||||
if (!field.is_analog())
|
if (!field.is_analog())
|
||||||
{
|
{
|
||||||
|
// non-analog changes
|
||||||
changed |= ((field.live().value & field.mask()) != (field.defvalue() & field.mask()));
|
changed |= ((field.live().value & field.mask()) != (field.defvalue() & field.mask()));
|
||||||
changed |= (field.live().toggle != field.toggle());
|
changed |= (field.live().toggle != field.toggle());
|
||||||
}
|
}
|
||||||
|
|
||||||
// analog changes
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// analog changes
|
||||||
changed |= (field.live().analog->m_delta != field.delta());
|
changed |= (field.live().analog->m_delta != field.delta());
|
||||||
changed |= (field.live().analog->m_centerdelta != field.centerdelta());
|
changed |= (field.live().analog->m_centerdelta != field.centerdelta());
|
||||||
changed |= (field.live().analog->m_sensitivity != field.sensitivity());
|
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
|
// add a new port node
|
||||||
util::xml::data_node *const portnode = parentnode.add_child("port", nullptr);
|
util::xml::data_node *const portnode = parentnode.add_child("port", nullptr);
|
||||||
if (portnode != nullptr)
|
if (portnode)
|
||||||
{
|
{
|
||||||
// add the identifying information and attributes
|
// add the identifying information and attributes
|
||||||
portnode->set_attribute("tag", port.second->tag());
|
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))
|
if (field.seq(seqtype) != field.defseq(seqtype))
|
||||||
save_sequence(*portnode, seqtype, field.type(), field.seq(seqtype));
|
save_sequence(*portnode, seqtype, field.type(), field.seq(seqtype));
|
||||||
|
|
||||||
// write out non-analog changes
|
|
||||||
if (!field.is_analog())
|
if (!field.is_analog())
|
||||||
{
|
{
|
||||||
|
// write out non-analog changes
|
||||||
if ((field.live().value & field.mask()) != (field.defvalue() & field.mask()))
|
if ((field.live().value & field.mask()) != (field.defvalue() & field.mask()))
|
||||||
portnode->set_attribute_int("value", field.live().value & field.mask());
|
portnode->set_attribute_int("value", field.live().value & field.mask());
|
||||||
if (field.live().toggle != field.toggle())
|
if (field.live().toggle != field.toggle())
|
||||||
portnode->set_attribute("toggle", field.live().toggle ? "yes" : "no");
|
portnode->set_attribute("toggle", field.live().toggle ? "yes" : "no");
|
||||||
}
|
}
|
||||||
|
|
||||||
// write out analog changes
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// write out analog changes
|
||||||
if (field.live().analog->m_delta != field.delta())
|
if (field.live().analog->m_delta != field.delta())
|
||||||
portnode->set_attribute_int("keydelta", field.live().analog->m_delta);
|
portnode->set_attribute_int("keydelta", field.live().analog->m_delta);
|
||||||
if (field.live().analog->m_centerdelta != field.centerdelta())
|
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)
|
ioport_configurer& ioport_configurer::setting_alloc(ioport_value value, const char *name)
|
||||||
{
|
{
|
||||||
// make sure we have a field
|
// 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);
|
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
|
// 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;
|
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_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);
|
target.set(condition, tag, mask, value);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -3245,8 +3325,7 @@ ioport_configurer& ioport_configurer::onoff_alloc(const char *name, ioport_value
|
|||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
dynamic_field::dynamic_field(ioport_field &field)
|
dynamic_field::dynamic_field(ioport_field &field)
|
||||||
: m_next(nullptr),
|
: m_field(field),
|
||||||
m_field(field),
|
|
||||||
m_shift(0),
|
m_shift(0),
|
||||||
m_oldval(field.defvalue())
|
m_oldval(field.defvalue())
|
||||||
{
|
{
|
||||||
@ -3265,15 +3344,15 @@ dynamic_field::dynamic_field(ioport_field &field)
|
|||||||
void dynamic_field::read(ioport_value &result)
|
void dynamic_field::read(ioport_value &result)
|
||||||
{
|
{
|
||||||
// skip if not enabled
|
// skip if not enabled
|
||||||
if (!m_field.enabled())
|
if (m_field.enabled())
|
||||||
return;
|
{
|
||||||
|
// call the callback to read a new value
|
||||||
|
ioport_value newval = m_field.m_read();
|
||||||
|
m_oldval = newval;
|
||||||
|
|
||||||
// call the callback to read a new value
|
// merge in the bits (don't invert yet, as all digitals are inverted together)
|
||||||
ioport_value newval = m_field.m_read();
|
result = (result & ~m_field.mask()) | ((newval << m_shift) & m_field.mask());
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3285,15 +3364,15 @@ void dynamic_field::read(ioport_value &result)
|
|||||||
void dynamic_field::write(ioport_value newval)
|
void dynamic_field::write(ioport_value newval)
|
||||||
{
|
{
|
||||||
// skip if not enabled
|
// skip if not enabled
|
||||||
if (!m_field.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)
|
|
||||||
{
|
{
|
||||||
m_field.m_write(m_field, m_field.m_write_param, m_oldval, newval);
|
// if the bits have changed, call the handler
|
||||||
m_oldval = newval;
|
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)
|
analog_field::analog_field(ioport_field &field)
|
||||||
: m_next(nullptr),
|
: m_field(field),
|
||||||
m_field(field),
|
|
||||||
m_shift(0),
|
m_shift(0),
|
||||||
m_adjdefvalue(field.defvalue() & field.mask()),
|
m_adjdefvalue(field.defvalue() & field.mask()),
|
||||||
m_adjmin(field.minval() & field.mask()),
|
m_adjmin(field.minval() & field.mask()),
|
||||||
|
103
src/emu/ioport.h
103
src/emu/ioport.h
@ -20,8 +20,9 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <vector>
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
@ -32,19 +33,19 @@
|
|||||||
typedef u32 ioport_value;
|
typedef u32 ioport_value;
|
||||||
|
|
||||||
// active high/low values for input ports
|
// active high/low values for input ports
|
||||||
const ioport_value IP_ACTIVE_HIGH = 0x00000000;
|
constexpr ioport_value IP_ACTIVE_HIGH = 0x00000000;
|
||||||
const ioport_value IP_ACTIVE_LOW = 0xffffffff;
|
constexpr ioport_value IP_ACTIVE_LOW = 0xffffffff;
|
||||||
|
|
||||||
// maximum number of players supported
|
// maximum number of players supported
|
||||||
const int MAX_PLAYERS = 10;
|
constexpr int MAX_PLAYERS = 10;
|
||||||
|
|
||||||
// unicode constants
|
// unicode constants
|
||||||
const char32_t UCHAR_PRIVATE = 0x100000;
|
constexpr char32_t UCHAR_PRIVATE = 0x100000;
|
||||||
const char32_t UCHAR_SHIFT_1 = UCHAR_PRIVATE + 0;
|
constexpr char32_t UCHAR_SHIFT_1 = UCHAR_PRIVATE + 0;
|
||||||
const char32_t UCHAR_SHIFT_2 = UCHAR_PRIVATE + 1;
|
constexpr char32_t UCHAR_SHIFT_2 = UCHAR_PRIVATE + 1;
|
||||||
const char32_t UCHAR_SHIFT_BEGIN = UCHAR_SHIFT_1;
|
constexpr char32_t UCHAR_SHIFT_BEGIN = UCHAR_SHIFT_1;
|
||||||
const char32_t UCHAR_SHIFT_END = UCHAR_SHIFT_2;
|
constexpr char32_t UCHAR_SHIFT_END = UCHAR_SHIFT_2;
|
||||||
const char32_t UCHAR_MAMEKEY_BEGIN = UCHAR_PRIVATE + 2;
|
constexpr char32_t UCHAR_MAMEKEY_BEGIN = UCHAR_PRIVATE + 2;
|
||||||
|
|
||||||
|
|
||||||
// sequence types for input_port_seq() call
|
// sequence types for input_port_seq() call
|
||||||
@ -825,7 +826,6 @@ private:
|
|||||||
class digital_joystick
|
class digital_joystick
|
||||||
{
|
{
|
||||||
DISABLE_COPYING(digital_joystick);
|
DISABLE_COPYING(digital_joystick);
|
||||||
friend class simple_list<digital_joystick>;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// directions
|
// directions
|
||||||
@ -848,7 +848,6 @@ public:
|
|||||||
digital_joystick(int player, int number);
|
digital_joystick(int player, int number);
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
digital_joystick *next() const noexcept { return m_next; }
|
|
||||||
int player() const noexcept { return m_player; }
|
int player() const noexcept { return m_player; }
|
||||||
int number() const noexcept { return m_number; }
|
int number() const noexcept { return m_number; }
|
||||||
u8 current() const noexcept { return m_current; }
|
u8 current() const noexcept { return m_current; }
|
||||||
@ -862,7 +861,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// internal state
|
// internal state
|
||||||
digital_joystick * m_next; // next joystick in the list
|
|
||||||
int m_player; // player number represented
|
int m_player; // player number represented
|
||||||
int m_number; // joystick 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
|
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
|
// a single setting for a configuration or DIP switch
|
||||||
class ioport_setting
|
class ioport_setting
|
||||||
{
|
{
|
||||||
DISABLE_COPYING(ioport_setting);
|
|
||||||
friend class simple_list<ioport_setting>;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// construction/destruction
|
// construction/destruction
|
||||||
ioport_setting(ioport_field &field, ioport_value value, const char *name);
|
ioport_setting(ioport_field &field, ioport_value value, const char *name);
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
ioport_setting *next() const { return m_next; }
|
|
||||||
ioport_field &field() const { return m_field; }
|
ioport_field &field() const { return m_field; }
|
||||||
device_t &device() const;
|
device_t &device() const;
|
||||||
running_machine &machine() const;
|
running_machine &machine() const;
|
||||||
@ -951,15 +945,14 @@ public:
|
|||||||
const char *name() const { return m_name; }
|
const char *name() const { return m_name; }
|
||||||
|
|
||||||
// helpers
|
// helpers
|
||||||
bool enabled() { return m_condition.eval(); }
|
bool enabled() const { return m_condition.eval(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// internal state
|
// 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_field & m_field; // pointer back to the field that owns us
|
ioport_value m_value; // value of the bits in this setting
|
||||||
ioport_value m_value; // value of the bits in this setting
|
const char * m_name; // user-friendly name to display
|
||||||
const char * m_name; // user-friendly name to display
|
ioport_condition m_condition; // condition under which this setting is valid
|
||||||
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
|
// a mapping from a bit to a physical DIP switch description
|
||||||
class ioport_diplocation
|
class ioport_diplocation
|
||||||
{
|
{
|
||||||
DISABLE_COPYING(ioport_diplocation);
|
|
||||||
friend class simple_list<ioport_diplocation>;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// construction/destruction
|
// construction/destruction
|
||||||
ioport_diplocation(const char *name, u8 swnum, bool invert);
|
ioport_diplocation(const char *name, u8 swnum, bool invert);
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
ioport_diplocation *next() const { return m_next; }
|
|
||||||
const char *name() const { return m_name.c_str(); }
|
const char *name() const { return m_name.c_str(); }
|
||||||
u8 number() const { return m_number; }
|
u8 number() const { return m_number; }
|
||||||
bool inverted() const { return m_invert; }
|
bool inverted() const { return m_invert; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ioport_diplocation * m_next; // pointer to the next bit
|
std::string m_name; // name of the physical DIP switch
|
||||||
std::string m_name; // name of the physical DIP switch
|
u8 m_number; // physical switch number
|
||||||
u8 m_number; // physical switch number
|
bool m_invert; // is this an active-high DIP?
|
||||||
bool m_invert; // is this an active-high DIP?
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -996,18 +984,19 @@ class ioport_field
|
|||||||
{
|
{
|
||||||
DISABLE_COPYING(ioport_field);
|
DISABLE_COPYING(ioport_field);
|
||||||
friend class simple_list<ioport_field>;
|
friend class simple_list<ioport_field>;
|
||||||
|
friend class ioport_manager;
|
||||||
friend class ioport_configurer;
|
friend class ioport_configurer;
|
||||||
friend class dynamic_field;
|
friend class dynamic_field;
|
||||||
|
|
||||||
// flags for ioport_fields
|
// flags for ioport_fields
|
||||||
static const int FIELD_FLAG_OPTIONAL = 0x0001; // set if this field is not required but recognized by hw
|
static inline constexpr u32 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 inline constexpr u32 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 inline constexpr u32 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 inline constexpr u32 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 inline constexpr u32 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 inline constexpr u32 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 inline constexpr u32 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 ANALOG_FLAG_INVERT = 0x0080; // analog only: bitwise invert bits
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// construction/destruction
|
// construction/destruction
|
||||||
@ -1021,8 +1010,8 @@ public:
|
|||||||
ioport_manager &manager() const;
|
ioport_manager &manager() const;
|
||||||
running_machine &machine() const;
|
running_machine &machine() const;
|
||||||
int modcount() const { return m_modcount; }
|
int modcount() const { return m_modcount; }
|
||||||
const simple_list<ioport_setting> &settings() const { return m_settinglist; }
|
const std::vector<ioport_setting> &settings() const { return m_settinglist; }
|
||||||
const simple_list<ioport_diplocation> &diplocations() const { return m_diploclist; }
|
const std::vector<ioport_diplocation> &diplocations() const { return m_diploclist; }
|
||||||
|
|
||||||
ioport_value mask() const { return m_mask; }
|
ioport_value mask() const { return m_mask; }
|
||||||
ioport_value defvalue() const { return m_defvalue; }
|
ioport_value defvalue() const { return m_defvalue; }
|
||||||
@ -1087,7 +1076,7 @@ public:
|
|||||||
void select_previous_setting();
|
void select_previous_setting();
|
||||||
bool has_next_setting() const;
|
bool has_next_setting() const;
|
||||||
void select_next_setting();
|
void select_next_setting();
|
||||||
float crosshair_read();
|
float crosshair_read() const;
|
||||||
void init_live_state(analog_field *analog);
|
void init_live_state(analog_field *analog);
|
||||||
void frame_update(ioport_value &result);
|
void frame_update(ioport_value &result);
|
||||||
void reduce_mask(ioport_value bits_to_remove) { m_mask &= ~bits_to_remove; }
|
void reduce_mask(ioport_value bits_to_remove) { m_mask &= ~bits_to_remove; }
|
||||||
@ -1112,10 +1101,10 @@ private:
|
|||||||
// internal state
|
// internal state
|
||||||
ioport_field * m_next; // pointer to next field in sequence
|
ioport_field * m_next; // pointer to next field in sequence
|
||||||
ioport_port & m_port; // reference to the port that owns us
|
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
|
int m_modcount; // modification count
|
||||||
simple_list<ioport_setting> m_settinglist; // list of input_setting_configs
|
std::vector<ioport_setting> m_settinglist; // list of input_setting_configs
|
||||||
simple_list<ioport_diplocation> m_diploclist; // list of locations for various bits
|
std::vector<ioport_diplocation> m_diploclist; // list of locations for various bits
|
||||||
|
|
||||||
// generally-applicable data
|
// generally-applicable data
|
||||||
ioport_value m_mask; // mask of bits belonging to the field
|
ioport_value m_mask; // mask of bits belonging to the field
|
||||||
@ -1246,7 +1235,6 @@ private:
|
|||||||
// live analog field information
|
// live analog field information
|
||||||
class analog_field
|
class analog_field
|
||||||
{
|
{
|
||||||
friend class simple_list<analog_field>;
|
|
||||||
friend class ioport_manager;
|
friend class ioport_manager;
|
||||||
friend void ioport_field::set_user_settings(const ioport_field::user_settings &settings) noexcept;
|
friend void ioport_field::set_user_settings(const ioport_field::user_settings &settings) noexcept;
|
||||||
|
|
||||||
@ -1255,7 +1243,6 @@ public:
|
|||||||
analog_field(ioport_field &field);
|
analog_field(ioport_field &field);
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
analog_field *next() const noexcept { return m_next; }
|
|
||||||
ioport_manager &manager() const noexcept { return m_field.manager(); }
|
ioport_manager &manager() const noexcept { return m_field.manager(); }
|
||||||
ioport_field &field() const noexcept { return m_field; }
|
ioport_field &field() const noexcept { return m_field; }
|
||||||
s32 sensitivity() const noexcept { return m_sensitivity; }
|
s32 sensitivity() const noexcept { return m_sensitivity; }
|
||||||
@ -1279,7 +1266,6 @@ private:
|
|||||||
s32 apply_inverse_sensitivity(s32 value) const;
|
s32 apply_inverse_sensitivity(s32 value) const;
|
||||||
|
|
||||||
// internal state
|
// 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
|
ioport_field & m_field; // pointer to the input field referenced
|
||||||
|
|
||||||
// adjusted values (right-justified and tweaked)
|
// adjusted values (right-justified and tweaked)
|
||||||
@ -1329,14 +1315,11 @@ private:
|
|||||||
// live device field information
|
// live device field information
|
||||||
class dynamic_field
|
class dynamic_field
|
||||||
{
|
{
|
||||||
friend class simple_list<dynamic_field>;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// construction/destruction
|
// construction/destruction
|
||||||
dynamic_field(ioport_field &field);
|
dynamic_field(ioport_field &field);
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
dynamic_field *next() const { return m_next; }
|
|
||||||
ioport_field &field() const { return m_field; }
|
ioport_field &field() const { return m_field; }
|
||||||
|
|
||||||
// read/write
|
// read/write
|
||||||
@ -1345,7 +1328,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// internal state
|
// internal state
|
||||||
dynamic_field * m_next; // linked list of info for this port
|
|
||||||
ioport_field & m_field; // reference to the input field
|
ioport_field & m_field; // reference to the input field
|
||||||
u8 m_shift; // shift to apply to the final result
|
u8 m_shift; // shift to apply to the final result
|
||||||
ioport_value m_oldval; // last value
|
ioport_value m_oldval; // last value
|
||||||
@ -1361,9 +1343,9 @@ struct ioport_port_live
|
|||||||
ioport_port_live(ioport_port &port);
|
ioport_port_live(ioport_port &port);
|
||||||
|
|
||||||
// public state
|
// public state
|
||||||
simple_list<analog_field> analoglist; // list of analog port info
|
std::list<analog_field> analoglist; // list of analog port info
|
||||||
simple_list<dynamic_field> readlist; // list of dynamic read fields
|
std::vector<dynamic_field> readlist; // list of dynamic read fields
|
||||||
simple_list<dynamic_field> writelist; // list of dynamic write fields
|
std::vector<dynamic_field> writelist; // list of dynamic write fields
|
||||||
ioport_value defvalue; // combined default value across the port
|
ioport_value defvalue; // combined default value across the port
|
||||||
ioport_value digital; // current value from all digital inputs
|
ioport_value digital; // current value from all digital inputs
|
||||||
ioport_value outputvalue; // current value for outputs
|
ioport_value outputvalue; // current value for outputs
|
||||||
@ -1420,10 +1402,11 @@ private:
|
|||||||
input_seq_type token_to_seq_type(const char *string);
|
input_seq_type token_to_seq_type(const char *string);
|
||||||
static const char *const seqtypestrings[];
|
static const char *const seqtypestrings[];
|
||||||
|
|
||||||
void load_config(config_type cfg_type, util::xml::data_node const *parentnode);
|
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);
|
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);
|
bool load_default_config(int type, int player, const input_seq (&newseq)[SEQ_TYPE_TOTAL]);
|
||||||
void load_game_config(util::xml::data_node const *portnode, int type, int player, const input_seq *newseq);
|
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_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);
|
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
|
input_type_entry * m_type_to_entry[IPT_COUNT][MAX_PLAYERS]; // map from type/player to type state
|
||||||
|
|
||||||
// specific special global input states
|
// 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
|
// frame time tracking
|
||||||
attotime m_last_frame_time; // time of the last frame callback
|
attotime m_last_frame_time; // time of the last frame callback
|
||||||
|
@ -26,7 +26,10 @@
|
|||||||
network_manager::network_manager(running_machine &machine)
|
network_manager::network_manager(running_machine &machine)
|
||||||
: m_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
|
// 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"))
|
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)
|
void network_manager::config_save(config_type cfg_type, util::xml::data_node *parentnode)
|
||||||
{
|
{
|
||||||
/* only care about game-specific data */
|
// only save about system-specific data
|
||||||
if (cfg_type == config_type::GAME)
|
if (cfg_type == config_type::SYSTEM)
|
||||||
{
|
{
|
||||||
for (device_network_interface &network : network_interface_enumerator(machine().root_device()))
|
for (device_network_interface &network : network_interface_enumerator(machine().root_device()))
|
||||||
{
|
{
|
||||||
util::xml::data_node *const node = parentnode->add_child("device", nullptr);
|
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("tag", network.device().tag());
|
||||||
node->set_attribute_int("interface", network.get_interface());
|
node->set_attribute_int("interface", network.get_interface());
|
||||||
|
@ -23,7 +23,7 @@ public:
|
|||||||
// getters
|
// getters
|
||||||
running_machine &machine() const { return m_machine; }
|
running_machine &machine() const { return m_machine; }
|
||||||
private:
|
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);
|
void config_save(config_type cfg_type, util::xml::data_node *parentnode);
|
||||||
|
|
||||||
// internal state
|
// internal state
|
||||||
|
@ -3057,7 +3057,10 @@ render_manager::render_manager(running_machine &machine)
|
|||||||
, m_ui_container(new render_container(*this))
|
, m_ui_container(new render_container(*this))
|
||||||
{
|
{
|
||||||
// register callbacks
|
// 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
|
// create one container per screen
|
||||||
for (screen_device &screen : screen_device_enumerator(machine.root_device()))
|
for (screen_device &screen : screen_device_enumerator(machine.root_device()))
|
||||||
@ -3312,10 +3315,10 @@ void render_manager::container_free(render_container *container)
|
|||||||
// configuration file
|
// 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
|
// we only care about system-specific configuration with matching nodes
|
||||||
if ((cfg_type != config_type::GAME) || !parentnode)
|
if ((cfg_type != config_type::SYSTEM) || !parentnode)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// check the UI target
|
// 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)
|
void render_manager::config_save(config_type cfg_type, util::xml::data_node *parentnode)
|
||||||
{
|
{
|
||||||
// we only care about game files
|
// we only save system-specific configuration
|
||||||
if (cfg_type != config_type::GAME)
|
if (cfg_type != config_type::SYSTEM)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// write out the interface target
|
// write out the interface target
|
||||||
|
@ -701,7 +701,7 @@ private:
|
|||||||
void container_free(render_container *container);
|
void container_free(render_container *container);
|
||||||
|
|
||||||
// config callbacks
|
// 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);
|
void config_save(config_type cfg_type, util::xml::data_node *parentnode);
|
||||||
|
|
||||||
// internal state
|
// internal state
|
||||||
|
@ -4659,7 +4659,7 @@ void layout_view::item::resolve_tags()
|
|||||||
if (m_input_port)
|
if (m_input_port)
|
||||||
{
|
{
|
||||||
// if there's a matching unconditional field, cache it
|
// 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)
|
if (field.mask() & m_input_mask)
|
||||||
{
|
{
|
||||||
|
@ -1090,7 +1090,10 @@ sound_manager::sound_manager(running_machine &machine) :
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// register callbacks
|
// 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_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_RESUME, machine_notify_delegate(&sound_manager::resume, this));
|
||||||
machine.add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(&sound_manager::reset, this));
|
machine.add_notifier(MACHINE_NOTIFY_RESET, machine_notify_delegate(&sound_manager::reset, this));
|
||||||
@ -1356,14 +1359,10 @@ void sound_manager::resume()
|
|||||||
// configuration file
|
// 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
|
// we only care system-specific configuration
|
||||||
if (cfg_type != config_type::GAME)
|
if ((cfg_type != config_type::SYSTEM) || !parentnode)
|
||||||
return;
|
|
||||||
|
|
||||||
// might not have any data
|
|
||||||
if (parentnode == nullptr)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// iterate over channel nodes
|
// 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)
|
void sound_manager::config_save(config_type cfg_type, util::xml::data_node *parentnode)
|
||||||
{
|
{
|
||||||
// we only care about game files
|
// we only save system-specific configuration
|
||||||
if (cfg_type != config_type::GAME)
|
if (cfg_type != config_type::SYSTEM)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// iterate over mixer channels
|
// iterate over mixer channels
|
||||||
if (parentnode != nullptr)
|
for (int mixernum = 0; ; mixernum++)
|
||||||
for (int mixernum = 0; ; mixernum++)
|
{
|
||||||
{
|
mixer_input info;
|
||||||
mixer_input info;
|
if (!indexed_mixer_input(mixernum, info))
|
||||||
if (!indexed_mixer_input(mixernum, info))
|
break;
|
||||||
break;
|
|
||||||
float newvol = info.stream->input(info.inputnum).user_gain();
|
|
||||||
|
|
||||||
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);
|
channelnode->set_attribute_int("index", mixernum);
|
||||||
if (channelnode != nullptr)
|
channelnode->set_attribute_float("newvol", newvol);
|
||||||
{
|
|
||||||
channelnode->set_attribute_int("index", mixernum);
|
|
||||||
channelnode->set_attribute_float("newvol", newvol);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -808,7 +808,7 @@ private:
|
|||||||
void resume();
|
void resume();
|
||||||
|
|
||||||
// handle configuration load/save
|
// 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);
|
void config_save(config_type cfg_type, util::xml::data_node *parentnode);
|
||||||
|
|
||||||
// helper to adjust scale factor toward a goal
|
// helper to adjust scale factor toward a goal
|
||||||
|
@ -1706,7 +1706,7 @@ void validity_checker::validate_roms(device_t &root)
|
|||||||
// analog input field
|
// 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
|
// analog ports must have a valid sensitivity
|
||||||
if (field.sensitivity() == 0)
|
if (field.sensitivity() == 0)
|
||||||
@ -1787,7 +1787,7 @@ void validity_checker::validate_analog_input_field(ioport_field &field)
|
|||||||
// setting
|
// 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 *demo_sounds = ioport_string_from_index(INPUT_STRING_Demo_Sounds);
|
||||||
const char *flipscreen = ioport_string_from_index(INPUT_STRING_Flip_Screen);
|
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;
|
bool coin_error = false;
|
||||||
|
|
||||||
// iterate through the settings
|
// 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
|
// 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)
|
if (strindex >= __input_string_coinage_start && strindex <= __input_string_coinage_end)
|
||||||
coin_list[strindex - __input_string_coinage_start] = 1;
|
coin_list[strindex - __input_string_coinage_start] = 1;
|
||||||
|
|
||||||
// make sure demo sounds default to on
|
// 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");
|
osd_printf_error("Demo Sounds must default to On\n");
|
||||||
|
|
||||||
// check for bad demo sounds options
|
// check for bad demo sounds options
|
||||||
if (field.name() == demo_sounds && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No))
|
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
|
// check for bad flip screen options
|
||||||
if (field.name() == flipscreen && (strindex == INPUT_STRING_Yes || strindex == INPUT_STRING_No))
|
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 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
|
// 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)
|
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());
|
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
|
// 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 &&
|
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;
|
coin_error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1856,7 +1857,7 @@ void validity_checker::validate_dip_settings(ioport_field &field)
|
|||||||
// stored within an ioport field or setting
|
// 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
|
// resolve the tag, then find a matching port
|
||||||
if (m_ioport_set.find(device.subtag(condition.tag())) == m_ioport_set.end())
|
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
|
// 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
|
// verify analog inputs
|
||||||
if (field.is_analog())
|
if (field.is_analog())
|
||||||
@ -1973,7 +1974,7 @@ void validity_checker::validate_inputs(device_t &root)
|
|||||||
validate_condition(field.condition(), device);
|
validate_condition(field.condition(), device);
|
||||||
|
|
||||||
// verify conditions on the settings
|
// verify conditions on the settings
|
||||||
for (ioport_setting &setting : field.settings())
|
for (ioport_setting const &setting : field.settings())
|
||||||
if (!setting.condition().none())
|
if (!setting.condition().none())
|
||||||
validate_condition(setting.condition(), device);
|
validate_condition(setting.condition(), device);
|
||||||
|
|
||||||
|
@ -74,9 +74,9 @@ private:
|
|||||||
void validate_rgb();
|
void validate_rgb();
|
||||||
void validate_driver(device_t &root);
|
void validate_driver(device_t &root);
|
||||||
void validate_roms(device_t &root);
|
void validate_roms(device_t &root);
|
||||||
void validate_analog_input_field(ioport_field &field);
|
void validate_analog_input_field(const ioport_field &field);
|
||||||
void validate_dip_settings(ioport_field &field);
|
void validate_dip_settings(const ioport_field &field);
|
||||||
void validate_condition(ioport_condition &condition, device_t &device);
|
void validate_condition(const ioport_condition &condition, device_t &device);
|
||||||
void validate_inputs(device_t &root);
|
void validate_inputs(device_t &root);
|
||||||
void validate_devices(machine_config &config);
|
void validate_devices(machine_config &config);
|
||||||
void validate_device_types();
|
void validate_device_types();
|
||||||
|
@ -548,7 +548,7 @@ void output_header(std::ostream &out, bool dtd)
|
|||||||
"\" mameconfig=\"%d\">\n",
|
"\" mameconfig=\"%d\">\n",
|
||||||
XML_ROOT,
|
XML_ROOT,
|
||||||
normalize_string(emulator_info::get_build_version()),
|
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;
|
int ctrl_type = CTRL_DIGITAL_BUTTONS;
|
||||||
bool ctrl_analog = false;
|
bool ctrl_analog = false;
|
||||||
for (ioport_field &field : port.second->fields())
|
for (ioport_field const &field : port.second->fields())
|
||||||
{
|
{
|
||||||
// track the highest player number
|
// track the highest player number
|
||||||
if (nplayer < field.player() + 1)
|
if (nplayer < field.player() + 1)
|
||||||
|
@ -334,7 +334,7 @@ void lua_engine::initialize_input(sol::table &emu)
|
|||||||
[this] (ioport_field &f)
|
[this] (ioport_field &f)
|
||||||
{
|
{
|
||||||
sol::table result = sol().create_table();
|
sol::table result = sol().create_table();
|
||||||
for (ioport_setting &setting : f.settings())
|
for (ioport_setting const &setting : f.settings())
|
||||||
if (setting.enabled())
|
if (setting.enabled())
|
||||||
result[setting.value()] = setting.name();
|
result[setting.value()] = setting.name();
|
||||||
return result;
|
return result;
|
||||||
|
@ -221,7 +221,7 @@ void menu_device_config::populate(float &customtop, float &custombottom)
|
|||||||
{
|
{
|
||||||
dips++;
|
dips++;
|
||||||
bool def(false);
|
bool def(false);
|
||||||
for (ioport_setting &setting : field.settings())
|
for (ioport_setting const &setting : field.settings())
|
||||||
{
|
{
|
||||||
if (setting.value() == field.defvalue())
|
if (setting.value() == field.defvalue())
|
||||||
{
|
{
|
||||||
@ -237,7 +237,7 @@ void menu_device_config::populate(float &customtop, float &custombottom)
|
|||||||
{
|
{
|
||||||
confs++;
|
confs++;
|
||||||
bool def(false);
|
bool def(false);
|
||||||
for (ioport_setting &setting : field.settings())
|
for (ioport_setting const &setting : field.settings())
|
||||||
{
|
{
|
||||||
if (setting.value() == field.defvalue())
|
if (setting.value() == field.defvalue())
|
||||||
{
|
{
|
||||||
|
@ -218,8 +218,8 @@ void mame_ui_manager::init()
|
|||||||
machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(&mame_ui_manager::exit, this));
|
machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(&mame_ui_manager::exit, this));
|
||||||
machine().configuration().config_register(
|
machine().configuration().config_register(
|
||||||
"ui_warnings",
|
"ui_warnings",
|
||||||
config_load_delegate(&mame_ui_manager::config_load, this),
|
configuration_manager::load_delegate(&mame_ui_manager::config_load, this),
|
||||||
config_save_delegate(&mame_ui_manager::config_save, this));
|
configuration_manager::save_delegate(&mame_ui_manager::config_save, this));
|
||||||
|
|
||||||
// create mouse bitmap
|
// create mouse bitmap
|
||||||
uint32_t *dst = &m_mouse_bitmap.pix(0);
|
uint32_t *dst = &m_mouse_bitmap.pix(0);
|
||||||
@ -258,10 +258,10 @@ void mame_ui_manager::exit()
|
|||||||
// config_load - load configuration data
|
// 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
|
// 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_unemulated_features.clear();
|
||||||
m_imperfect_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)
|
void mame_ui_manager::config_save(config_type cfg_type, util::xml::data_node *parentnode)
|
||||||
{
|
{
|
||||||
// only save system-level configuration when times are valid
|
// 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("launched", static_cast<long long>(m_last_launch_time));
|
||||||
parentnode->set_attribute_int("warned", static_cast<long long>(m_last_warning_time));
|
parentnode->set_attribute_int("warned", static_cast<long long>(m_last_warning_time));
|
||||||
|
@ -257,7 +257,7 @@ private:
|
|||||||
|
|
||||||
// private methods
|
// private methods
|
||||||
void exit();
|
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);
|
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)...)); }
|
template <typename... Params> void slider_alloc(Params &&...args) { m_sliders.push_back(std::make_unique<slider_state>(std::forward<Params>(args)...)); }
|
||||||
|
|
||||||
|
@ -281,18 +281,21 @@ int uchar_from_utf16f(char32_t *uchar, const char16_t *utf16char, size_t count)
|
|||||||
// into a Unicode string
|
// 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;
|
std::u32string result;
|
||||||
char const *utf8char(utf8str.c_str());
|
if (!utf8str.empty())
|
||||||
size_t remaining(utf8str.length());
|
|
||||||
while (remaining)
|
|
||||||
{
|
{
|
||||||
char32_t ch;
|
char const *utf8char(&utf8str[0]);
|
||||||
int const consumed(uchar_from_utf8(&ch, utf8char, remaining));
|
auto remaining(utf8str.length());
|
||||||
result.append(1, (consumed > 0) ? ch : char32_t(0x00fffdU));
|
while (remaining)
|
||||||
utf8char += (consumed > 0) ? consumed : 1;
|
{
|
||||||
remaining -= (consumed > 0) ? consumed : 1;
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
@ -480,17 +483,6 @@ std::string utf8_from_wstring(const std::wstring &string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// normalize_unicode - uses utf8proc to normalize
|
|
||||||
// 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
|
// normalize_unicode - uses utf8proc to normalize
|
||||||
// unicode
|
// unicode
|
||||||
|
@ -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_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_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);
|
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
|
// converting 32-bit Unicode chars to strings
|
||||||
int utf8_from_uchar(char *utf8string, size_t count, char32_t uchar);
|
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);
|
std::string utf8_from_wstring(const std::wstring &string);
|
||||||
|
|
||||||
// unicode normalization
|
// 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(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);
|
std::string normalize_unicode(std::string_view s, unicode_normalization_form normalization_form, bool fold_case = false);
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
void create_console();
|
void create_console();
|
||||||
void build_menus();
|
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);
|
void config_save(config_type cfgtype, util::xml::data_node *parentnode);
|
||||||
|
|
||||||
running_machine *m_machine;
|
running_machine *m_machine;
|
||||||
@ -129,8 +129,8 @@ void debugger_osx::init_debugger(running_machine &machine)
|
|||||||
m_machine = &machine;
|
m_machine = &machine;
|
||||||
machine.configuration().config_register(
|
machine.configuration().config_register(
|
||||||
"debugger",
|
"debugger",
|
||||||
config_load_delegate(&debugger_osx::config_load, this),
|
configuration_manager::load_delegate(&debugger_osx::config_load, this),
|
||||||
config_save_delegate(&debugger_osx::config_save, 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
|
// 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)
|
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)
|
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];
|
NSAutoreleasePool *const pool = [[NSAutoreleasePool alloc] init];
|
||||||
NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:[NSValue valueWithPointer:m_machine],
|
NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:[NSValue valueWithPointer:m_machine],
|
||||||
|
@ -79,21 +79,17 @@ MainWindow *mainQtWindow = nullptr;
|
|||||||
std::vector<std::unique_ptr<WindowQtConfig> > xmlConfigurations;
|
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
|
// We only care about system configuration files
|
||||||
if (cfg_type != config_type::GAME)
|
if ((cfg_type != config_type::SYSTEM) || !parentnode)
|
||||||
return;
|
|
||||||
|
|
||||||
// Might not have any data
|
|
||||||
if (!parentnode)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
xmlConfigurations.clear();
|
xmlConfigurations.clear();
|
||||||
|
|
||||||
// Configuration load
|
// Configuration load
|
||||||
util::xml::data_node const *wnode = nullptr;
|
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);
|
WindowQtConfig::WindowType type = (WindowQtConfig::WindowType)wnode->get_attribute_int("type", WindowQtConfig::WIN_TYPE_UNKNOWN);
|
||||||
switch (type)
|
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)
|
void xml_configuration_save(running_machine &machine, config_type cfg_type, util::xml::data_node *parentnode)
|
||||||
{
|
{
|
||||||
// We only write to game configurations
|
// We only save system configuration
|
||||||
if (cfg_type != config_type::GAME)
|
if (cfg_type != config_type::SYSTEM)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (int i = 0; i < xmlConfigurations.size(); i++)
|
for (int i = 0; i < xmlConfigurations.size(); i++)
|
||||||
@ -269,8 +265,8 @@ void debug_qt::init_debugger(running_machine &machine)
|
|||||||
m_machine = &machine;
|
m_machine = &machine;
|
||||||
// Setup the configuration XML saving and loading
|
// Setup the configuration XML saving and loading
|
||||||
machine.configuration().config_register("debugger",
|
machine.configuration().config_register("debugger",
|
||||||
config_load_delegate(&xml_configuration_load, &machine),
|
configuration_manager::load_delegate(&xml_configuration_load, &machine),
|
||||||
config_save_delegate(&xml_configuration_save, &machine));
|
configuration_manager::save_delegate(&xml_configuration_save, &machine));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user