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