summaryrefslogtreecommitdiffstatshomepage
path: root/src/frontend
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2020-09-02 17:29:21 +1000
committer Vas Crabb <vas@vastheman.com>2020-09-02 17:41:34 +1000
commit9445f1d8311db820dc0984e85c9c1450ce1807cd (patch)
tree43ecc4e298615b8b8388dbe9df4440b53f461b32 /src/frontend
parent654b118ff985a4011bc0caf5ce8160fa80c4b9bf (diff)
frontend: Added option to skip repeated imperfect emulation warnings.
The option is called skip_warnings, and it must be set in ui.ini (it can be set using the internal UI). Red warnings cannot be skipped; yellow warning can be skipped under certain circumstances. For a yellow warning to be skipped, the system must have been launched in a way that allows warnings to be displayed, in a configuration with the same set of devices flagged with unemulated/imperfect features, within the last seven days, and the warning must have been displayed within the past 14 days. Also fixed a bug with display of the MACHINE_NO_COCKTAIL flag in the internal UI, and increased the size of XML integer attributes to 64 bits.
Diffstat (limited to 'src/frontend')
-rw-r--r--src/frontend/mame/infoxml.cpp475
-rw-r--r--src/frontend/mame/infoxml.h2
-rw-r--r--src/frontend/mame/ui/filemngr.h7
-rw-r--r--src/frontend/mame/ui/info.cpp26
-rw-r--r--src/frontend/mame/ui/info.h4
-rw-r--r--src/frontend/mame/ui/moptions.cpp5
-rw-r--r--src/frontend/mame/ui/moptions.h2
-rw-r--r--src/frontend/mame/ui/selgame.cpp3
-rw-r--r--src/frontend/mame/ui/submenu.cpp3
-rw-r--r--src/frontend/mame/ui/ui.cpp202
-rw-r--r--src/frontend/mame/ui/ui.h20
11 files changed, 492 insertions, 257 deletions
diff --git a/src/frontend/mame/infoxml.cpp b/src/frontend/mame/infoxml.cpp
index 926feffbc08..59b3a637aee 100644
--- a/src/frontend/mame/infoxml.cpp
+++ b/src/frontend/mame/infoxml.cpp
@@ -25,234 +25,282 @@
#include "xmlfile.h"
+#include <algorithm>
#include <cctype>
#include <cstring>
-#include <unordered_set>
-#include <queue>
#include <future>
+#include <queue>
+#include <type_traits>
+#include <unordered_set>
+#include <utility>
#define XML_ROOT "mame"
#define XML_TOP "machine"
+namespace {
+
//**************************************************************************
// ANONYMOUS NAMESPACE PROTOTYPES
//**************************************************************************
-namespace
+class device_type_compare
{
- class device_type_compare
- {
- public:
- bool operator()(const std::add_pointer_t<device_type> &lhs, const std::add_pointer_t<device_type> &rhs) const;
- };
-
- typedef std::set<std::add_pointer_t<device_type>, device_type_compare> device_type_set;
-
- std::string normalize_string(const char *string);
-
- // internal helper
- void output_header(std::ostream &out, bool dtd);
- void output_footer(std::ostream &out);
-
- void output_one(std::ostream &out, driver_enumerator &drivlist, const game_driver &driver, device_type_set *devtypes);
- void output_sampleof(std::ostream &out, device_t &device);
- void output_bios(std::ostream &out, device_t const &device);
- void output_rom(std::ostream &out, driver_enumerator *drivlist, const game_driver *driver, device_t &device);
- void output_device_refs(std::ostream &out, device_t &root);
- void output_sample(std::ostream &out, device_t &device);
- void output_chips(std::ostream &out, device_t &device, const char *root_tag);
- void output_display(std::ostream &out, device_t &device, machine_flags::type const *flags, const char *root_tag);
- void output_sound(std::ostream &out, device_t &device);
- void output_ioport_condition(std::ostream &out, const ioport_condition &condition, unsigned indent);
- void output_input(std::ostream &out, const ioport_list &portlist);
- void output_switches(std::ostream &out, const ioport_list &portlist, const char *root_tag, int type, const char *outertag, const char *loctag, const char *innertag);
- void output_ports(std::ostream &out, const ioport_list &portlist);
- void output_adjusters(std::ostream &out, const ioport_list &portlist);
- void output_driver(std::ostream &out, game_driver const &driver, device_t::feature_type unemulated, device_t::feature_type imperfect);
- void output_features(std::ostream &out, device_type type, device_t::feature_type unemulated, device_t::feature_type imperfect);
- void output_images(std::ostream &out, device_t &device, const char *root_tag);
- void output_slots(std::ostream &out, machine_config &config, device_t &device, const char *root_tag, device_type_set *devtypes);
- void output_software_lists(std::ostream &out, device_t &root, const char *root_tag);
- void output_ramoptions(std::ostream &out, device_t &root);
-
- void output_one_device(std::ostream &out, machine_config &config, device_t &device, const char *devtag);
- void output_devices(std::ostream &out, emu_options &lookup_options, device_type_set const *filter);
-
- const char *get_merge_name(driver_enumerator &drivlist, const game_driver &driver, util::hash_collection const &romhashes);
+public:
+ bool operator()(const std::add_pointer_t<device_type> &lhs, const std::add_pointer_t<device_type> &rhs) const;
};
+typedef std::set<std::add_pointer_t<device_type>, device_type_compare> device_type_set;
+
+std::string normalize_string(const char *string);
+
+// internal helper
+void output_header(std::ostream &out, bool dtd);
+void output_footer(std::ostream &out);
+
+void output_one(std::ostream &out, driver_enumerator &drivlist, const game_driver &driver, device_type_set *devtypes);
+void output_sampleof(std::ostream &out, device_t &device);
+void output_bios(std::ostream &out, device_t const &device);
+void output_rom(std::ostream &out, driver_enumerator *drivlist, const game_driver *driver, device_t &device);
+void output_device_refs(std::ostream &out, device_t &root);
+void output_sample(std::ostream &out, device_t &device);
+void output_chips(std::ostream &out, device_t &device, const char *root_tag);
+void output_display(std::ostream &out, device_t &device, machine_flags::type const *flags, const char *root_tag);
+void output_sound(std::ostream &out, device_t &device);
+void output_ioport_condition(std::ostream &out, const ioport_condition &condition, unsigned indent);
+void output_input(std::ostream &out, const ioport_list &portlist);
+void output_switches(std::ostream &out, const ioport_list &portlist, const char *root_tag, int type, const char *outertag, const char *loctag, const char *innertag);
+void output_ports(std::ostream &out, const ioport_list &portlist);
+void output_adjusters(std::ostream &out, const ioport_list &portlist);
+void output_driver(std::ostream &out, game_driver const &driver, device_t::feature_type unemulated, device_t::feature_type imperfect);
+void output_features(std::ostream &out, device_type type, device_t::feature_type unemulated, device_t::feature_type imperfect);
+void output_images(std::ostream &out, device_t &device, const char *root_tag);
+void output_slots(std::ostream &out, machine_config &config, device_t &device, const char *root_tag, device_type_set *devtypes);
+void output_software_lists(std::ostream &out, device_t &root, const char *root_tag);
+void output_ramoptions(std::ostream &out, device_t &root);
+
+void output_one_device(std::ostream &out, machine_config &config, device_t &device, const char *devtag);
+void output_devices(std::ostream &out, emu_options &lookup_options, device_type_set const *filter);
+
+const char *get_merge_name(driver_enumerator &drivlist, const game_driver &driver, util::hash_collection const &romhashes);
+
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
// DTD string describing the data
-static const char s_dtd_string[] =
-"<!DOCTYPE __XML_ROOT__ [\n"
-"<!ELEMENT __XML_ROOT__ (__XML_TOP__+)>\n"
-"\t<!ATTLIST __XML_ROOT__ build CDATA #IMPLIED>\n"
-"\t<!ATTLIST __XML_ROOT__ debug (yes|no) \"no\">\n"
-"\t<!ATTLIST __XML_ROOT__ mameconfig CDATA #REQUIRED>\n"
-"\t<!ELEMENT __XML_TOP__ (description, year?, manufacturer?, biosset*, rom*, disk*, device_ref*, sample*, chip*, display*, sound?, input?, dipswitch*, configuration*, port*, adjuster*, driver?, feature*, device*, slot*, softwarelist*, ramoption*)>\n"
-"\t\t<!ATTLIST __XML_TOP__ name CDATA #REQUIRED>\n"
-"\t\t<!ATTLIST __XML_TOP__ sourcefile CDATA #IMPLIED>\n"
-"\t\t<!ATTLIST __XML_TOP__ isbios (yes|no) \"no\">\n"
-"\t\t<!ATTLIST __XML_TOP__ isdevice (yes|no) \"no\">\n"
-"\t\t<!ATTLIST __XML_TOP__ ismechanical (yes|no) \"no\">\n"
-"\t\t<!ATTLIST __XML_TOP__ runnable (yes|no) \"yes\">\n"
-"\t\t<!ATTLIST __XML_TOP__ cloneof CDATA #IMPLIED>\n"
-"\t\t<!ATTLIST __XML_TOP__ romof CDATA #IMPLIED>\n"
-"\t\t<!ATTLIST __XML_TOP__ sampleof CDATA #IMPLIED>\n"
-"\t\t<!ELEMENT description (#PCDATA)>\n"
-"\t\t<!ELEMENT year (#PCDATA)>\n"
-"\t\t<!ELEMENT manufacturer (#PCDATA)>\n"
-"\t\t<!ELEMENT biosset EMPTY>\n"
-"\t\t\t<!ATTLIST biosset name CDATA #REQUIRED>\n"
-"\t\t\t<!ATTLIST biosset description CDATA #REQUIRED>\n"
-"\t\t\t<!ATTLIST biosset default (yes|no) \"no\">\n"
-"\t\t<!ELEMENT rom EMPTY>\n"
-"\t\t\t<!ATTLIST rom name CDATA #REQUIRED>\n"
-"\t\t\t<!ATTLIST rom bios CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST rom size CDATA #REQUIRED>\n"
-"\t\t\t<!ATTLIST rom crc CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST rom sha1 CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST rom merge CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST rom region CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST rom offset CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST rom status (baddump|nodump|good) \"good\">\n"
-"\t\t\t<!ATTLIST rom optional (yes|no) \"no\">\n"
-"\t\t<!ELEMENT disk EMPTY>\n"
-"\t\t\t<!ATTLIST disk name CDATA #REQUIRED>\n"
-"\t\t\t<!ATTLIST disk sha1 CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST disk merge CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST disk region CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST disk index CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST disk writable (yes|no) \"no\">\n"
-"\t\t\t<!ATTLIST disk status (baddump|nodump|good) \"good\">\n"
-"\t\t\t<!ATTLIST disk optional (yes|no) \"no\">\n"
-"\t\t<!ELEMENT device_ref EMPTY>\n"
-"\t\t\t<!ATTLIST device_ref name CDATA #REQUIRED>\n"
-"\t\t<!ELEMENT sample EMPTY>\n"
-"\t\t\t<!ATTLIST sample name CDATA #REQUIRED>\n"
-"\t\t<!ELEMENT chip EMPTY>\n"
-"\t\t\t<!ATTLIST chip name CDATA #REQUIRED>\n"
-"\t\t\t<!ATTLIST chip tag CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST chip type (cpu|audio) #REQUIRED>\n"
-"\t\t\t<!ATTLIST chip clock CDATA #IMPLIED>\n"
-"\t\t<!ELEMENT display EMPTY>\n"
-"\t\t\t<!ATTLIST display tag CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST display type (raster|vector|lcd|svg|unknown) #REQUIRED>\n"
-"\t\t\t<!ATTLIST display rotate (0|90|180|270) #IMPLIED>\n"
-"\t\t\t<!ATTLIST display flipx (yes|no) \"no\">\n"
-"\t\t\t<!ATTLIST display width CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST display height CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST display refresh CDATA #REQUIRED>\n"
-"\t\t\t<!ATTLIST display pixclock CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST display htotal CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST display hbend CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST display hbstart CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST display vtotal CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST display vbend CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST display vbstart CDATA #IMPLIED>\n"
-"\t\t<!ELEMENT sound EMPTY>\n"
-"\t\t\t<!ATTLIST sound channels CDATA #REQUIRED>\n"
-"\t\t<!ELEMENT condition EMPTY>\n"
-"\t\t\t<!ATTLIST condition tag CDATA #REQUIRED>\n"
-"\t\t\t<!ATTLIST condition mask CDATA #REQUIRED>\n"
-"\t\t\t<!ATTLIST condition relation (eq|ne|gt|le|lt|ge) #REQUIRED>\n"
-"\t\t\t<!ATTLIST condition value CDATA #REQUIRED>\n"
-"\t\t<!ELEMENT input (control*)>\n"
-"\t\t\t<!ATTLIST input service (yes|no) \"no\">\n"
-"\t\t\t<!ATTLIST input tilt (yes|no) \"no\">\n"
-"\t\t\t<!ATTLIST input players CDATA #REQUIRED>\n"
-"\t\t\t<!ATTLIST input coins CDATA #IMPLIED>\n"
-"\t\t\t<!ELEMENT control EMPTY>\n"
-"\t\t\t\t<!ATTLIST control type CDATA #REQUIRED>\n"
-"\t\t\t\t<!ATTLIST control player CDATA #IMPLIED>\n"
-"\t\t\t\t<!ATTLIST control buttons CDATA #IMPLIED>\n"
-"\t\t\t\t<!ATTLIST control reqbuttons CDATA #IMPLIED>\n"
-"\t\t\t\t<!ATTLIST control minimum CDATA #IMPLIED>\n"
-"\t\t\t\t<!ATTLIST control maximum CDATA #IMPLIED>\n"
-"\t\t\t\t<!ATTLIST control sensitivity CDATA #IMPLIED>\n"
-"\t\t\t\t<!ATTLIST control keydelta CDATA #IMPLIED>\n"
-"\t\t\t\t<!ATTLIST control reverse (yes|no) \"no\">\n"
-"\t\t\t\t<!ATTLIST control ways CDATA #IMPLIED>\n"
-"\t\t\t\t<!ATTLIST control ways2 CDATA #IMPLIED>\n"
-"\t\t\t\t<!ATTLIST control ways3 CDATA #IMPLIED>\n"
-"\t\t<!ELEMENT dipswitch (condition?, diplocation*, dipvalue*)>\n"
-"\t\t\t<!ATTLIST dipswitch name CDATA #REQUIRED>\n"
-"\t\t\t<!ATTLIST dipswitch tag CDATA #REQUIRED>\n"
-"\t\t\t<!ATTLIST dipswitch mask CDATA #REQUIRED>\n"
-"\t\t\t<!ELEMENT diplocation EMPTY>\n"
-"\t\t\t\t<!ATTLIST diplocation name CDATA #REQUIRED>\n"
-"\t\t\t\t<!ATTLIST diplocation number CDATA #REQUIRED>\n"
-"\t\t\t\t<!ATTLIST diplocation inverted (yes|no) \"no\">\n"
-"\t\t\t<!ELEMENT dipvalue (condition?)>\n"
-"\t\t\t\t<!ATTLIST dipvalue name CDATA #REQUIRED>\n"
-"\t\t\t\t<!ATTLIST dipvalue value CDATA #REQUIRED>\n"
-"\t\t\t\t<!ATTLIST dipvalue default (yes|no) \"no\">\n"
-"\t\t<!ELEMENT configuration (condition?, conflocation*, confsetting*)>\n"
-"\t\t\t<!ATTLIST configuration name CDATA #REQUIRED>\n"
-"\t\t\t<!ATTLIST configuration tag CDATA #REQUIRED>\n"
-"\t\t\t<!ATTLIST configuration mask CDATA #REQUIRED>\n"
-"\t\t\t<!ELEMENT conflocation EMPTY>\n"
-"\t\t\t\t<!ATTLIST conflocation name CDATA #REQUIRED>\n"
-"\t\t\t\t<!ATTLIST conflocation number CDATA #REQUIRED>\n"
-"\t\t\t\t<!ATTLIST conflocation inverted (yes|no) \"no\">\n"
-"\t\t\t<!ELEMENT confsetting (condition?)>\n"
-"\t\t\t\t<!ATTLIST confsetting name CDATA #REQUIRED>\n"
-"\t\t\t\t<!ATTLIST confsetting value CDATA #REQUIRED>\n"
-"\t\t\t\t<!ATTLIST confsetting default (yes|no) \"no\">\n"
-"\t\t<!ELEMENT port (analog*)>\n"
-"\t\t\t<!ATTLIST port tag CDATA #REQUIRED>\n"
-"\t\t\t<!ELEMENT analog EMPTY>\n"
-"\t\t\t\t<!ATTLIST analog mask CDATA #REQUIRED>\n"
-"\t\t<!ELEMENT adjuster (condition?)>\n"
-"\t\t\t<!ATTLIST adjuster name CDATA #REQUIRED>\n"
-"\t\t\t<!ATTLIST adjuster default CDATA #REQUIRED>\n"
-"\t\t<!ELEMENT driver EMPTY>\n"
-"\t\t\t<!ATTLIST driver status (good|imperfect|preliminary) #REQUIRED>\n"
-"\t\t\t<!ATTLIST driver emulation (good|imperfect|preliminary) #REQUIRED>\n"
-"\t\t\t<!ATTLIST driver cocktail (good|imperfect|preliminary) #IMPLIED>\n"
-"\t\t\t<!ATTLIST driver savestate (supported|unsupported) #REQUIRED>\n"
-"\t\t<!ELEMENT feature EMPTY>\n"
-"\t\t\t<!ATTLIST feature type (protection|timing|graphics|palette|sound|capture|camera|microphone|controls|keyboard|mouse|media|disk|printer|tape|punch|drum|rom|comms|lan|wan) #REQUIRED>\n"
-"\t\t\t<!ATTLIST feature status (unemulated|imperfect) #IMPLIED>\n"
-"\t\t\t<!ATTLIST feature overall (unemulated|imperfect) #IMPLIED>\n"
-"\t\t<!ELEMENT device (instance?, extension*)>\n"
-"\t\t\t<!ATTLIST device type CDATA #REQUIRED>\n"
-"\t\t\t<!ATTLIST device tag CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST device fixed_image CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST device mandatory CDATA #IMPLIED>\n"
-"\t\t\t<!ATTLIST device interface CDATA #IMPLIED>\n"
-"\t\t\t<!ELEMENT instance EMPTY>\n"
-"\t\t\t\t<!ATTLIST instance name CDATA #REQUIRED>\n"
-"\t\t\t\t<!ATTLIST instance briefname CDATA #REQUIRED>\n"
-"\t\t\t<!ELEMENT extension EMPTY>\n"
-"\t\t\t\t<!ATTLIST extension name CDATA #REQUIRED>\n"
-"\t\t<!ELEMENT slot (slotoption*)>\n"
-"\t\t\t<!ATTLIST slot name CDATA #REQUIRED>\n"
-"\t\t\t<!ELEMENT slotoption EMPTY>\n"
-"\t\t\t\t<!ATTLIST slotoption name CDATA #REQUIRED>\n"
-"\t\t\t\t<!ATTLIST slotoption devname CDATA #REQUIRED>\n"
-"\t\t\t\t<!ATTLIST slotoption default (yes|no) \"no\">\n"
-"\t\t<!ELEMENT softwarelist EMPTY>\n"
-"\t\t\t<!ATTLIST softwarelist tag CDATA #REQUIRED>\n"
-"\t\t\t<!ATTLIST softwarelist name CDATA #REQUIRED>\n"
-"\t\t\t<!ATTLIST softwarelist status (original|compatible) #REQUIRED>\n"
-"\t\t\t<!ATTLIST softwarelist filter CDATA #IMPLIED>\n"
-"\t\t<!ELEMENT ramoption (#PCDATA)>\n"
-"\t\t\t<!ATTLIST ramoption name CDATA #REQUIRED>\n"
-"\t\t\t<!ATTLIST ramoption default CDATA #IMPLIED>\n"
-"]>";
+constexpr char f_dtd_string[] =
+ "<!DOCTYPE __XML_ROOT__ [\n"
+ "<!ELEMENT __XML_ROOT__ (__XML_TOP__+)>\n"
+ "\t<!ATTLIST __XML_ROOT__ build CDATA #IMPLIED>\n"
+ "\t<!ATTLIST __XML_ROOT__ debug (yes|no) \"no\">\n"
+ "\t<!ATTLIST __XML_ROOT__ mameconfig CDATA #REQUIRED>\n"
+ "\t<!ELEMENT __XML_TOP__ (description, year?, manufacturer?, biosset*, rom*, disk*, device_ref*, sample*, chip*, display*, sound?, input?, dipswitch*, configuration*, port*, adjuster*, driver?, feature*, device*, slot*, softwarelist*, ramoption*)>\n"
+ "\t\t<!ATTLIST __XML_TOP__ name CDATA #REQUIRED>\n"
+ "\t\t<!ATTLIST __XML_TOP__ sourcefile CDATA #IMPLIED>\n"
+ "\t\t<!ATTLIST __XML_TOP__ isbios (yes|no) \"no\">\n"
+ "\t\t<!ATTLIST __XML_TOP__ isdevice (yes|no) \"no\">\n"
+ "\t\t<!ATTLIST __XML_TOP__ ismechanical (yes|no) \"no\">\n"
+ "\t\t<!ATTLIST __XML_TOP__ runnable (yes|no) \"yes\">\n"
+ "\t\t<!ATTLIST __XML_TOP__ cloneof CDATA #IMPLIED>\n"
+ "\t\t<!ATTLIST __XML_TOP__ romof CDATA #IMPLIED>\n"
+ "\t\t<!ATTLIST __XML_TOP__ sampleof CDATA #IMPLIED>\n"
+ "\t\t<!ELEMENT description (#PCDATA)>\n"
+ "\t\t<!ELEMENT year (#PCDATA)>\n"
+ "\t\t<!ELEMENT manufacturer (#PCDATA)>\n"
+ "\t\t<!ELEMENT biosset EMPTY>\n"
+ "\t\t\t<!ATTLIST biosset name CDATA #REQUIRED>\n"
+ "\t\t\t<!ATTLIST biosset description CDATA #REQUIRED>\n"
+ "\t\t\t<!ATTLIST biosset default (yes|no) \"no\">\n"
+ "\t\t<!ELEMENT rom EMPTY>\n"
+ "\t\t\t<!ATTLIST rom name CDATA #REQUIRED>\n"
+ "\t\t\t<!ATTLIST rom bios CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST rom size CDATA #REQUIRED>\n"
+ "\t\t\t<!ATTLIST rom crc CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST rom sha1 CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST rom merge CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST rom region CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST rom offset CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST rom status (baddump|nodump|good) \"good\">\n"
+ "\t\t\t<!ATTLIST rom optional (yes|no) \"no\">\n"
+ "\t\t<!ELEMENT disk EMPTY>\n"
+ "\t\t\t<!ATTLIST disk name CDATA #REQUIRED>\n"
+ "\t\t\t<!ATTLIST disk sha1 CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST disk merge CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST disk region CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST disk index CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST disk writable (yes|no) \"no\">\n"
+ "\t\t\t<!ATTLIST disk status (baddump|nodump|good) \"good\">\n"
+ "\t\t\t<!ATTLIST disk optional (yes|no) \"no\">\n"
+ "\t\t<!ELEMENT device_ref EMPTY>\n"
+ "\t\t\t<!ATTLIST device_ref name CDATA #REQUIRED>\n"
+ "\t\t<!ELEMENT sample EMPTY>\n"
+ "\t\t\t<!ATTLIST sample name CDATA #REQUIRED>\n"
+ "\t\t<!ELEMENT chip EMPTY>\n"
+ "\t\t\t<!ATTLIST chip name CDATA #REQUIRED>\n"
+ "\t\t\t<!ATTLIST chip tag CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST chip type (cpu|audio) #REQUIRED>\n"
+ "\t\t\t<!ATTLIST chip clock CDATA #IMPLIED>\n"
+ "\t\t<!ELEMENT display EMPTY>\n"
+ "\t\t\t<!ATTLIST display tag CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST display type (raster|vector|lcd|svg|unknown) #REQUIRED>\n"
+ "\t\t\t<!ATTLIST display rotate (0|90|180|270) #IMPLIED>\n"
+ "\t\t\t<!ATTLIST display flipx (yes|no) \"no\">\n"
+ "\t\t\t<!ATTLIST display width CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST display height CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST display refresh CDATA #REQUIRED>\n"
+ "\t\t\t<!ATTLIST display pixclock CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST display htotal CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST display hbend CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST display hbstart CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST display vtotal CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST display vbend CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST display vbstart CDATA #IMPLIED>\n"
+ "\t\t<!ELEMENT sound EMPTY>\n"
+ "\t\t\t<!ATTLIST sound channels CDATA #REQUIRED>\n"
+ "\t\t<!ELEMENT condition EMPTY>\n"
+ "\t\t\t<!ATTLIST condition tag CDATA #REQUIRED>\n"
+ "\t\t\t<!ATTLIST condition mask CDATA #REQUIRED>\n"
+ "\t\t\t<!ATTLIST condition relation (eq|ne|gt|le|lt|ge) #REQUIRED>\n"
+ "\t\t\t<!ATTLIST condition value CDATA #REQUIRED>\n"
+ "\t\t<!ELEMENT input (control*)>\n"
+ "\t\t\t<!ATTLIST input service (yes|no) \"no\">\n"
+ "\t\t\t<!ATTLIST input tilt (yes|no) \"no\">\n"
+ "\t\t\t<!ATTLIST input players CDATA #REQUIRED>\n"
+ "\t\t\t<!ATTLIST input coins CDATA #IMPLIED>\n"
+ "\t\t\t<!ELEMENT control EMPTY>\n"
+ "\t\t\t\t<!ATTLIST control type CDATA #REQUIRED>\n"
+ "\t\t\t\t<!ATTLIST control player CDATA #IMPLIED>\n"
+ "\t\t\t\t<!ATTLIST control buttons CDATA #IMPLIED>\n"
+ "\t\t\t\t<!ATTLIST control reqbuttons CDATA #IMPLIED>\n"
+ "\t\t\t\t<!ATTLIST control minimum CDATA #IMPLIED>\n"
+ "\t\t\t\t<!ATTLIST control maximum CDATA #IMPLIED>\n"
+ "\t\t\t\t<!ATTLIST control sensitivity CDATA #IMPLIED>\n"
+ "\t\t\t\t<!ATTLIST control keydelta CDATA #IMPLIED>\n"
+ "\t\t\t\t<!ATTLIST control reverse (yes|no) \"no\">\n"
+ "\t\t\t\t<!ATTLIST control ways CDATA #IMPLIED>\n"
+ "\t\t\t\t<!ATTLIST control ways2 CDATA #IMPLIED>\n"
+ "\t\t\t\t<!ATTLIST control ways3 CDATA #IMPLIED>\n"
+ "\t\t<!ELEMENT dipswitch (condition?, diplocation*, dipvalue*)>\n"
+ "\t\t\t<!ATTLIST dipswitch name CDATA #REQUIRED>\n"
+ "\t\t\t<!ATTLIST dipswitch tag CDATA #REQUIRED>\n"
+ "\t\t\t<!ATTLIST dipswitch mask CDATA #REQUIRED>\n"
+ "\t\t\t<!ELEMENT diplocation EMPTY>\n"
+ "\t\t\t\t<!ATTLIST diplocation name CDATA #REQUIRED>\n"
+ "\t\t\t\t<!ATTLIST diplocation number CDATA #REQUIRED>\n"
+ "\t\t\t\t<!ATTLIST diplocation inverted (yes|no) \"no\">\n"
+ "\t\t\t<!ELEMENT dipvalue (condition?)>\n"
+ "\t\t\t\t<!ATTLIST dipvalue name CDATA #REQUIRED>\n"
+ "\t\t\t\t<!ATTLIST dipvalue value CDATA #REQUIRED>\n"
+ "\t\t\t\t<!ATTLIST dipvalue default (yes|no) \"no\">\n"
+ "\t\t<!ELEMENT configuration (condition?, conflocation*, confsetting*)>\n"
+ "\t\t\t<!ATTLIST configuration name CDATA #REQUIRED>\n"
+ "\t\t\t<!ATTLIST configuration tag CDATA #REQUIRED>\n"
+ "\t\t\t<!ATTLIST configuration mask CDATA #REQUIRED>\n"
+ "\t\t\t<!ELEMENT conflocation EMPTY>\n"
+ "\t\t\t\t<!ATTLIST conflocation name CDATA #REQUIRED>\n"
+ "\t\t\t\t<!ATTLIST conflocation number CDATA #REQUIRED>\n"
+ "\t\t\t\t<!ATTLIST conflocation inverted (yes|no) \"no\">\n"
+ "\t\t\t<!ELEMENT confsetting (condition?)>\n"
+ "\t\t\t\t<!ATTLIST confsetting name CDATA #REQUIRED>\n"
+ "\t\t\t\t<!ATTLIST confsetting value CDATA #REQUIRED>\n"
+ "\t\t\t\t<!ATTLIST confsetting default (yes|no) \"no\">\n"
+ "\t\t<!ELEMENT port (analog*)>\n"
+ "\t\t\t<!ATTLIST port tag CDATA #REQUIRED>\n"
+ "\t\t\t<!ELEMENT analog EMPTY>\n"
+ "\t\t\t\t<!ATTLIST analog mask CDATA #REQUIRED>\n"
+ "\t\t<!ELEMENT adjuster (condition?)>\n"
+ "\t\t\t<!ATTLIST adjuster name CDATA #REQUIRED>\n"
+ "\t\t\t<!ATTLIST adjuster default CDATA #REQUIRED>\n"
+ "\t\t<!ELEMENT driver EMPTY>\n"
+ "\t\t\t<!ATTLIST driver status (good|imperfect|preliminary) #REQUIRED>\n"
+ "\t\t\t<!ATTLIST driver emulation (good|imperfect|preliminary) #REQUIRED>\n"
+ "\t\t\t<!ATTLIST driver cocktail (good|imperfect|preliminary) #IMPLIED>\n"
+ "\t\t\t<!ATTLIST driver savestate (supported|unsupported) #REQUIRED>\n"
+ "\t\t<!ELEMENT feature EMPTY>\n"
+ "\t\t\t<!ATTLIST feature type (protection|timing|graphics|palette|sound|capture|camera|microphone|controls|keyboard|mouse|media|disk|printer|tape|punch|drum|rom|comms|lan|wan) #REQUIRED>\n"
+ "\t\t\t<!ATTLIST feature status (unemulated|imperfect) #IMPLIED>\n"
+ "\t\t\t<!ATTLIST feature overall (unemulated|imperfect) #IMPLIED>\n"
+ "\t\t<!ELEMENT device (instance?, extension*)>\n"
+ "\t\t\t<!ATTLIST device type CDATA #REQUIRED>\n"
+ "\t\t\t<!ATTLIST device tag CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST device fixed_image CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST device mandatory CDATA #IMPLIED>\n"
+ "\t\t\t<!ATTLIST device interface CDATA #IMPLIED>\n"
+ "\t\t\t<!ELEMENT instance EMPTY>\n"
+ "\t\t\t\t<!ATTLIST instance name CDATA #REQUIRED>\n"
+ "\t\t\t\t<!ATTLIST instance briefname CDATA #REQUIRED>\n"
+ "\t\t\t<!ELEMENT extension EMPTY>\n"
+ "\t\t\t\t<!ATTLIST extension name CDATA #REQUIRED>\n"
+ "\t\t<!ELEMENT slot (slotoption*)>\n"
+ "\t\t\t<!ATTLIST slot name CDATA #REQUIRED>\n"
+ "\t\t\t<!ELEMENT slotoption EMPTY>\n"
+ "\t\t\t\t<!ATTLIST slotoption name CDATA #REQUIRED>\n"
+ "\t\t\t\t<!ATTLIST slotoption devname CDATA #REQUIRED>\n"
+ "\t\t\t\t<!ATTLIST slotoption default (yes|no) \"no\">\n"
+ "\t\t<!ELEMENT softwarelist EMPTY>\n"
+ "\t\t\t<!ATTLIST softwarelist tag CDATA #REQUIRED>\n"
+ "\t\t\t<!ATTLIST softwarelist name CDATA #REQUIRED>\n"
+ "\t\t\t<!ATTLIST softwarelist status (original|compatible) #REQUIRED>\n"
+ "\t\t\t<!ATTLIST softwarelist filter CDATA #IMPLIED>\n"
+ "\t\t<!ELEMENT ramoption (#PCDATA)>\n"
+ "\t\t\t<!ATTLIST ramoption name CDATA #REQUIRED>\n"
+ "\t\t\t<!ATTLIST ramoption default CDATA #IMPLIED>\n"
+ "]>";
+
+
+// XML feature names
+constexpr std::pair<device_t::feature_type, char const *> f_feature_names[] = {
+ { device_t::feature::PROTECTION, "protection" },
+ { device_t::feature::TIMING, "timing" },
+ { device_t::feature::GRAPHICS, "graphics" },
+ { device_t::feature::PALETTE, "palette" },
+ { device_t::feature::SOUND, "sound" },
+ { device_t::feature::CAPTURE, "capture" },
+ { device_t::feature::CAMERA, "camera" },
+ { device_t::feature::MICROPHONE, "microphone" },
+ { device_t::feature::CONTROLS, "controls" },
+ { device_t::feature::KEYBOARD, "keyboard" },
+ { device_t::feature::MOUSE, "mouse" },
+ { device_t::feature::MEDIA, "media" },
+ { device_t::feature::DISK, "disk" },
+ { device_t::feature::PRINTER, "printer" },
+ { device_t::feature::TAPE, "tape" },
+ { device_t::feature::PUNCH, "punch" },
+ { device_t::feature::DRUM, "drum" },
+ { device_t::feature::ROM, "rom" },
+ { device_t::feature::COMMS, "comms" },
+ { device_t::feature::LAN, "lan" },
+ { device_t::feature::WAN, "wan" } };
+
+} // anonymous namespace
//**************************************************************************
// INFO XML CREATOR
//**************************************************************************
+
+//-------------------------------------------------
+// get_feature_name - get XML name for feature
+//-------------------------------------------------
+
+char const *info_xml_creator::feature_name(device_t::feature_type feature)
+{
+ auto const found = std::lower_bound(
+ std::begin(f_feature_names),
+ std::end(f_feature_names),
+ std::underlying_type_t<device_t::feature_type>(feature),
+ [] (auto const &a, auto const &b)
+ {
+ return std::underlying_type_t<device_t::feature_type>(a.first) < b;
+ });
+ return ((std::end(f_feature_names) != found) && (found->first == feature)) ? found->second : nullptr;
+}
+
+
//-------------------------------------------------
// info_xml_creator - constructor
//-------------------------------------------------
@@ -478,7 +526,7 @@ void output_header(std::ostream &out, bool dtd)
{
// output the DTD
out << "<?xml version=\"1.0\"?>\n";
- std::string dtd(s_dtd_string);
+ std::string dtd(f_dtd_string);
strreplace(dtd, "__XML_ROOT__", XML_ROOT);
strreplace(dtd, "__XML_TOP__", XML_TOP);
@@ -1771,31 +1819,8 @@ void output_driver(std::ostream &out, game_driver const &driver, device_t::featu
void output_features(std::ostream &out, device_type type, device_t::feature_type unemulated, device_t::feature_type imperfect)
{
- static constexpr std::pair<device_t::feature_type, char const *> features[] = {
- { device_t::feature::PROTECTION, "protection" },
- { device_t::feature::TIMING, "timing" },
- { device_t::feature::GRAPHICS, "graphics" },
- { device_t::feature::PALETTE, "palette" },
- { device_t::feature::SOUND, "sound" },
- { device_t::feature::CAPTURE, "capture" },
- { device_t::feature::CAMERA, "camera" },
- { device_t::feature::MICROPHONE, "microphone" },
- { device_t::feature::CONTROLS, "controls" },
- { device_t::feature::KEYBOARD, "keyboard" },
- { device_t::feature::MOUSE, "mouse" },
- { device_t::feature::MEDIA, "media" },
- { device_t::feature::DISK, "disk" },
- { device_t::feature::PRINTER, "printer" },
- { device_t::feature::TAPE, "tape" },
- { device_t::feature::PUNCH, "punch" },
- { device_t::feature::DRUM, "drum" },
- { device_t::feature::ROM, "rom" },
- { device_t::feature::COMMS, "comms" },
- { device_t::feature::LAN, "lan" },
- { device_t::feature::WAN, "wan" } };
-
device_t::feature_type const flags(type.unemulated_features() | type.imperfect_features() | unemulated | imperfect);
- for (auto const &feature : features)
+ for (auto const &feature : f_feature_names)
{
if (flags & feature.first)
{
diff --git a/src/frontend/mame/infoxml.h b/src/frontend/mame/infoxml.h
index 690610d1e70..00a614bcd3a 100644
--- a/src/frontend/mame/infoxml.h
+++ b/src/frontend/mame/infoxml.h
@@ -34,6 +34,8 @@ public:
void output(std::ostream &out, const std::vector<std::string> &patterns);
void output(std::ostream &out, const std::function<bool(const char *shortname, bool &done)> &filter = { }, bool include_devices = true);
+ static char const *feature_name(device_t::feature_type feature);
+
private:
// internal state
emu_options m_lookup_options;
diff --git a/src/frontend/mame/ui/filemngr.h b/src/frontend/mame/ui/filemngr.h
index 68da54f1d05..d656bb9e692 100644
--- a/src/frontend/mame/ui/filemngr.h
+++ b/src/frontend/mame/ui/filemngr.h
@@ -7,13 +7,16 @@
MESS's clunky built-in file manager
***************************************************************************/
+#ifndef MAME_FRONTEND_UI_FILEMNGR_H
+#define MAME_FRONTEND_UI_FILEMNGR_H
#pragma once
-#ifndef MAME_FRONTEND_UI_FILEMNGR_H
-#define MAME_FRONTEND_UI_FILEMNGR_H
+#include "ui/menu.h"
+
namespace ui {
+
class menu_file_manager : public menu
{
public:
diff --git a/src/frontend/mame/ui/info.cpp b/src/frontend/mame/ui/info.cpp
index ec0c6e72700..5b6450412c6 100644
--- a/src/frontend/mame/ui/info.cpp
+++ b/src/frontend/mame/ui/info.cpp
@@ -139,13 +139,35 @@ machine_static_info::machine_static_info(const ui_options &options, machine_conf
//-------------------------------------------------
+// has_warnings - returns true if the system has
+// issues that warrant a yellow/red message
+//-------------------------------------------------
+
+bool machine_static_info::has_warnings() const
+{
+ return (machine_flags() & (MACHINE_ERRORS | MACHINE_WARNINGS)) || unemulated_features() || imperfect_features();
+}
+
+
+//-------------------------------------------------
+// has_severe_warnings - returns true if the
+// system has issues that warrant a red message
+//-------------------------------------------------
+
+bool machine_static_info::has_severe_warnings() const
+{
+ return (machine_flags() & MACHINE_ERRORS) || ((unemulated_features() | imperfect_features()) & device_t::feature::PROTECTION);
+}
+
+
+//-------------------------------------------------
// status_color - returns suitable colour for
// driver status box
//-------------------------------------------------
rgb_t machine_static_info::status_color() const
{
- if ((machine_flags() & MACHINE_ERRORS) || ((unemulated_features() | imperfect_features()) & device_t::feature::PROTECTION))
+ if (has_severe_warnings())
return UI_RED_COLOR;
else if ((machine_flags() & MACHINE_WARNINGS & ~::machine_flags::REQUIRES_ARTWORK) || unemulated_features() || imperfect_features())
return UI_YELLOW_COLOR;
@@ -161,7 +183,7 @@ rgb_t machine_static_info::status_color() const
rgb_t machine_static_info::warnings_color() const
{
- if ((machine_flags() & MACHINE_ERRORS) || ((unemulated_features() | imperfect_features()) & device_t::feature::PROTECTION))
+ if (has_severe_warnings())
return UI_RED_COLOR;
else if ((machine_flags() & MACHINE_WARNINGS) || unemulated_features() || imperfect_features())
return UI_YELLOW_COLOR;
diff --git a/src/frontend/mame/ui/info.h b/src/frontend/mame/ui/info.h
index 0e6fd7815cd..7acb64c2a38 100644
--- a/src/frontend/mame/ui/info.h
+++ b/src/frontend/mame/ui/info.h
@@ -38,7 +38,9 @@ public:
bool has_test_switch() const { return m_has_test_switch; }
bool has_analog() const { return m_has_analog; }
- // message colour
+ // warning severity indications
+ bool has_warnings() const;
+ bool has_severe_warnings() const;
rgb_t status_color() const;
rgb_t warnings_color() const;
diff --git a/src/frontend/mame/ui/moptions.cpp b/src/frontend/mame/ui/moptions.cpp
index b4da221e18e..911baa66fdf 100644
--- a/src/frontend/mame/ui/moptions.cpp
+++ b/src/frontend/mame/ui/moptions.cpp
@@ -44,8 +44,9 @@ const options_entry ui_options::s_option_entries[] =
// misc options
{ nullptr, nullptr, OPTION_HEADER, "UI MISC OPTIONS" },
- { OPTION_REMEMBER_LAST, "1", OPTION_BOOLEAN, "reselect in main menu last played game" },
- { OPTION_ENLARGE_SNAPS, "1", OPTION_BOOLEAN, "enlarge arts (snapshot, title, etc...) in right panel (keeping aspect ratio)" },
+ { OPTION_SKIP_WARNINGS, "0", OPTION_BOOLEAN, "display fewer repeated warnings about imperfect emulation" },
+ { OPTION_REMEMBER_LAST, "1", OPTION_BOOLEAN, "initially select last used system in main menu" },
+ { OPTION_ENLARGE_SNAPS, "1", OPTION_BOOLEAN, "enlarge artwork (snapshot, title, etc.) in right panel (keeping aspect ratio)" },
{ OPTION_FORCED4X3, "1", OPTION_BOOLEAN, "force the appearance of the snapshot in the list software to 4:3" },
{ OPTION_USE_BACKGROUND, "1", OPTION_BOOLEAN, "enable background image in main view" },
{ OPTION_SKIP_BIOS_MENU, "0", OPTION_BOOLEAN, "skip bios submenu, start with configured or default" },
diff --git a/src/frontend/mame/ui/moptions.h b/src/frontend/mame/ui/moptions.h
index ddfa3971c3b..67ce3eb63f9 100644
--- a/src/frontend/mame/ui/moptions.h
+++ b/src/frontend/mame/ui/moptions.h
@@ -38,6 +38,7 @@
#define OPTION_UI_PATH "ui_path"
// core misc options
+#define OPTION_SKIP_WARNINGS "skip_warnings"
#define OPTION_REMEMBER_LAST "remember_last"
#define OPTION_ENLARGE_SNAPS "enlarge_snaps"
#define OPTION_FORCED4X3 "forced4x3"
@@ -102,6 +103,7 @@ public:
const char *ui_path() const { return value(OPTION_UI_PATH); }
// Misc options
+ bool skip_warnings() const { return bool_value(OPTION_SKIP_WARNINGS); }
bool remember_last() const { return bool_value(OPTION_REMEMBER_LAST); }
bool enlarge_snaps() const { return bool_value(OPTION_ENLARGE_SNAPS); }
bool forced_4x3_snapshot() const { return bool_value(OPTION_FORCED4X3); }
diff --git a/src/frontend/mame/ui/selgame.cpp b/src/frontend/mame/ui/selgame.cpp
index 1f7603b4f31..6944031e344 100644
--- a/src/frontend/mame/ui/selgame.cpp
+++ b/src/frontend/mame/ui/selgame.cpp
@@ -1159,7 +1159,8 @@ void menu_select_game::general_info(const game_driver *driver, std::string &buff
str << ((flags.machine_flags() & machine_flags::MECHANICAL) ? _("Mechanical Machine\tYes\n") : _("Mechanical Machine\tNo\n"));
str << ((flags.machine_flags() & machine_flags::REQUIRES_ARTWORK) ? _("Requires Artwork\tYes\n") : _("Requires Artwork\tNo\n"));
str << ((flags.machine_flags() & machine_flags::CLICKABLE_ARTWORK) ? _("Requires Clickable Artwork\tYes\n") : _("Requires Clickable Artwork\tNo\n"));
- str << ((flags.machine_flags() & machine_flags::NO_COCKTAIL) ? _("Support Cocktail\tYes\n") : _("Support Cocktail\tNo\n"));
+ if (flags.machine_flags() & machine_flags::NO_COCKTAIL)
+ str << _("Support Cocktail\tNo\n");
str << ((flags.machine_flags() & machine_flags::IS_BIOS_ROOT) ? _("Driver is BIOS\tYes\n") : _("Driver is BIOS\tNo\n"));
str << ((flags.machine_flags() & machine_flags::SUPPORTS_SAVE) ? _("Support Save\tYes\n") : _("Support Save\tNo\n"));
str << ((flags.machine_flags() & ORIENTATION_SWAP_XY) ? _("Screen Orientation\tVertical\n") : _("Screen Orientation\tHorizontal\n"));
diff --git a/src/frontend/mame/ui/submenu.cpp b/src/frontend/mame/ui/submenu.cpp
index 207ac56d057..cb1d3e38089 100644
--- a/src/frontend/mame/ui/submenu.cpp
+++ b/src/frontend/mame/ui/submenu.cpp
@@ -20,7 +20,8 @@
namespace ui {
std::vector<submenu::option> const submenu::misc_options = {
{ submenu::option_type::HEAD, __("Miscellaneous Options") },
- { submenu::option_type::UI, __("Re-select last machine played"), OPTION_REMEMBER_LAST },
+ { submenu::option_type::UI, __("Skip imperfect emulation warnings"), OPTION_SKIP_WARNINGS },
+ { submenu::option_type::UI, __("Re-select last machine launched"), OPTION_REMEMBER_LAST },
{ submenu::option_type::UI, __("Enlarge images in the right panel"), OPTION_ENLARGE_SNAPS },
{ submenu::option_type::EMU, __("Cheats"), OPTION_CHEAT },
{ submenu::option_type::EMU, __("Show mouse pointer"), OPTION_UI_MOUSE },
diff --git a/src/frontend/mame/ui/ui.cpp b/src/frontend/mame/ui/ui.cpp
index 08fd5a75ce8..40a5651430d 100644
--- a/src/frontend/mame/ui/ui.cpp
+++ b/src/frontend/mame/ui/ui.cpp
@@ -9,29 +9,39 @@
*********************************************************************/
#include "emu.h"
+#include "ui/ui.h"
+
+#include "luaengine.h"
+#include "infoxml.h"
#include "mame.h"
+#include "ui/filemngr.h"
+#include "ui/info.h"
+#include "ui/mainmenu.h"
+#include "ui/menu.h"
+#include "ui/sliders.h"
+#include "ui/state.h"
+#include "ui/viewgfx.h"
+
+#include "imagedev/cassette.h"
+#include "machine/laserdsc.h"
+#include "video/vector.h"
+
+#include "config.h"
#include "emuopts.h"
#include "mameopts.h"
-#include "video/vector.h"
-#include "machine/laserdsc.h"
#include "drivenum.h"
#include "natkeyboard.h"
#include "render.h"
-#include "luaengine.h"
#include "cheat.h"
#include "rendfont.h"
+#include "romload.h"
#include "uiinput.h"
-#include "ui/ui.h"
-#include "ui/info.h"
-#include "ui/menu.h"
-#include "ui/mainmenu.h"
-#include "ui/filemngr.h"
-#include "ui/sliders.h"
-#include "ui/state.h"
-#include "ui/viewgfx.h"
-#include "imagedev/cassette.h"
+
#include "../osd/modules/lib/osdobj_common.h"
+#include <chrono>
+#include <type_traits>
+
/***************************************************************************
CONSTANTS
@@ -168,6 +178,11 @@ mame_ui_manager::mame_ui_manager(running_machine &machine)
, m_mouse_show(false)
, m_target_font_height(0)
, m_has_warnings(false)
+ , m_machine_info()
+ , m_unemulated_features()
+ , m_imperfect_features()
+ , m_last_launch_time(std::time_t(-1))
+ , m_last_warning_time(std::time_t(-1))
{ }
mame_ui_manager::~mame_ui_manager()
@@ -177,6 +192,7 @@ mame_ui_manager::~mame_ui_manager()
void mame_ui_manager::init()
{
load_ui_options();
+
// initialize the other UI bits
ui::menu::init(machine(), options());
ui_gfx_init(machine());
@@ -192,8 +208,12 @@ void mame_ui_manager::init()
m_non_char_keys_down = std::make_unique<uint8_t[]>((ARRAY_LENGTH(non_char_keys) + 7) / 8);
m_mouse_show = machine().system().flags & machine_flags::CLICKABLE_ARTWORK ? true : false;
- // request a callback upon exiting
+ // request notification callbacks
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));
// create mouse bitmap
uint32_t *dst = &m_mouse_bitmap.pix32(0);
@@ -233,6 +253,78 @@ 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)
+{
+ // make sure it's relevant and there's data available
+ if (config_type::GAME == cfg_type)
+ {
+ m_unemulated_features.clear();
+ m_imperfect_features.clear();
+ if (!parentnode)
+ {
+ m_last_launch_time = std::time_t(-1);
+ m_last_warning_time = std::time_t(-1);
+ }
+ else
+ {
+ m_last_launch_time = std::time_t(parentnode->get_attribute_int("launched", -1));
+ m_last_warning_time = std::time_t(parentnode->get_attribute_int("warned", -1));
+ for (util::xml::data_node const *node = parentnode->get_first_child(); node; node = node->get_next_sibling())
+ {
+ if (!std::strcmp(node->get_name(), "feature"))
+ {
+ char const *const device = node->get_attribute_string("device", nullptr);
+ char const *const feature = node->get_attribute_string("type", nullptr);
+ char const *const status = node->get_attribute_string("status", nullptr);
+ if (device && *device && feature && *feature && status && *status)
+ {
+ if (!std::strcmp(status, "unemulated"))
+ m_unemulated_features.emplace(device, feature);
+ else if (!std::strcmp(status, "imperfect"))
+ m_imperfect_features.emplace(device, feature);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+//-------------------------------------------------
+// config_save - save configuration data
+//-------------------------------------------------
+
+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))
+ {
+ parentnode->set_attribute_int("launched", static_cast<long long>(m_last_launch_time));
+ parentnode->set_attribute_int("warned", static_cast<long long>(m_last_warning_time));
+
+ for (auto const &feature : m_unemulated_features)
+ {
+ util::xml::data_node *const feature_node = parentnode->add_child("feature", nullptr);
+ feature_node->set_attribute("device", feature.first.c_str());
+ feature_node->set_attribute("type", feature.second.c_str());
+ feature_node->set_attribute("status", "unemulated");
+ }
+
+ for (auto const &feature : m_imperfect_features)
+ {
+ util::xml::data_node *const feature_node = parentnode->add_child("feature", nullptr);
+ feature_node->set_attribute("device", feature.first.c_str());
+ feature_node->set_attribute("type", feature.second.c_str());
+ feature_node->set_attribute("status", "imperfect");
+ }
+ }
+}
+
+
+//-------------------------------------------------
// initialize - initialize ui lists
//-------------------------------------------------
@@ -335,7 +427,7 @@ void mame_ui_manager::display_startup_screens(bool first_time)
messagebox_text = machine_info().game_info_string();
if (!messagebox_text.empty())
{
- messagebox_text.append("\n\nPress any key to continue");
+ messagebox_text.append(_("\n\nPress any key to continue"));
set_handler(ui_callback_type::MODAL, std::bind(&mame_ui_manager::handler_messagebox_anykey, this, _1));
}
break;
@@ -343,11 +435,75 @@ void mame_ui_manager::display_startup_screens(bool first_time)
case 1:
messagebox_text = machine_info().warnings_string();
m_has_warnings = !messagebox_text.empty();
- if (m_has_warnings && show_warnings)
+ if (show_warnings)
{
- messagebox_text.append("\n\nPress any key to continue");
- set_handler(ui_callback_type::MODAL, std::bind(&mame_ui_manager::handler_messagebox_anykey, this, _1));
- messagebox_backcolor = machine_info().warnings_color();
+ bool need_warning = m_has_warnings;
+ if (machine_info().has_severe_warnings() || !m_has_warnings)
+ {
+ // critical warnings - no need to persist stuff
+ m_unemulated_features.clear();
+ m_imperfect_features.clear();
+ m_last_launch_time = std::time_t(-1);
+ m_last_warning_time = std::time_t(-1);
+ }
+ else
+ {
+ // non-critical warnings - map current unemulated/imperfect features
+ device_feature_set unemulated_features, imperfect_features;
+ for (device_t &device : device_iterator(machine().root_device()))
+ {
+ device_t::feature_type unemulated = device.type().unemulated_features();
+ for (std::underlying_type_t<device_t::feature_type> feature = 1U; unemulated; feature <<= 1)
+ {
+ if (unemulated & feature)
+ {
+ char const *const name = info_xml_creator::feature_name(device_t::feature_type(feature));
+ if (name)
+ unemulated_features.emplace(device.type().shortname(), name);
+ unemulated &= device_t::feature_type(~feature);
+ }
+ }
+ device_t::feature_type imperfect = device.type().imperfect_features();
+ for (std::underlying_type_t<device_t::feature_type> feature = 1U; imperfect; feature <<= 1)
+ {
+ if (imperfect & feature)
+ {
+ char const *const name = info_xml_creator::feature_name(device_t::feature_type(feature));
+ if (name)
+ imperfect_features.emplace(device.type().shortname(), name);
+ imperfect &= device_t::feature_type(~feature);
+ }
+ }
+ }
+
+ // machine flags can cause warnings, too
+ if (machine_info().machine_flags() & machine_flags::NO_COCKTAIL)
+ unemulated_features.emplace(machine().root_device().type().shortname(), "cocktail");
+
+ // if the warnings match what was shown sufficiently recently, it's skippable
+ if ((unemulated_features != m_unemulated_features) || (imperfect_features != m_imperfect_features))
+ {
+ m_last_launch_time = std::time_t(-1);
+ }
+ else if (!machine().rom_load().warnings() && (std::time_t(-1) != m_last_launch_time) && (std::time_t(-1) != m_last_warning_time) && options().skip_warnings())
+ {
+ auto const now = std::chrono::system_clock::now();
+ if (((std::chrono::system_clock::from_time_t(m_last_launch_time) + std::chrono::hours(7 * 24)) >= now) && ((std::chrono::system_clock::from_time_t(m_last_warning_time) + std::chrono::hours(14 * 24)) >= now))
+ need_warning = false;
+ }
+
+ // update the information to save out
+ m_unemulated_features = std::move(unemulated_features);
+ m_imperfect_features = std::move(imperfect_features);
+ if (need_warning)
+ m_last_warning_time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
+ }
+ if (need_warning)
+ {
+ messagebox_text.append(_("\n\nPress any key to continue"));
+ set_handler(ui_callback_type::MODAL, std::bind(&mame_ui_manager::handler_messagebox_anykey, this, _1));
+ messagebox_backcolor = machine_info().warnings_color();
+ }
}
break;
@@ -359,8 +515,8 @@ void mame_ui_manager::display_startup_screens(bool first_time)
warning << _("This driver requires images to be loaded in the following device(s): ");
output_joined_collection(mandatory_images,
- [&warning](const std::reference_wrapper<const std::string> &img) { warning << "\"" << img.get() << "\""; },
- [&warning]() { warning << ","; });
+ [&warning](const std::reference_wrapper<const std::string> &img) { warning << "\"" << img.get() << "\""; },
+ [&warning]() { warning << ","; });
ui::menu_file_manager::force_file_manager(*this, machine().render().ui_container(), warning.str().c_str());
}
@@ -382,6 +538,10 @@ void mame_ui_manager::display_startup_screens(bool first_time)
machine().video().frame_update();
}
+ // update last launch time if this was a run that was eligible for emulation warnings
+ if (m_has_warnings && show_warnings && !machine().scheduled_event_pending())
+ m_last_launch_time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
+
// if we're the empty driver, force the menus on
if (ui::menu::stack_has_special_main_menu(machine()))
show_menu();
@@ -2107,7 +2267,7 @@ void mame_ui_manager::load_ui_options()
{
try
{
- options().parse_ini_file((util::core_file&)file, OPTION_PRIORITY_MAME_INI, OPTION_PRIORITY_MAME_INI < OPTION_PRIORITY_DRIVER_INI, true);
+ options().parse_ini_file((util::core_file &)file, OPTION_PRIORITY_MAME_INI, OPTION_PRIORITY_MAME_INI < OPTION_PRIORITY_DRIVER_INI, true);
}
catch (options_exception &)
{
diff --git a/src/frontend/mame/ui/ui.h b/src/frontend/mame/ui/ui.h
index d62b8b15d1a..8c0504464d3 100644
--- a/src/frontend/mame/ui/ui.h
+++ b/src/frontend/mame/ui/ui.h
@@ -21,14 +21,21 @@
#include "ui/slider.h"
#include "ui/text.h"
+#include <ctime>
#include <functional>
+#include <set>
+#include <utility>
#include <vector>
+
namespace ui {
+
class menu_item;
class machine_info;
+
} // namespace ui
+
/***************************************************************************
CONSTANTS
***************************************************************************/
@@ -260,9 +267,12 @@ public:
virtual void menu_reset() override;
private:
+ using handler_callback_func = std::function<uint32_t (render_container &)>;
+ using device_feature_set = std::set<std::pair<std::string, std::string> >;
+
// instance variables
render_font * m_font;
- std::function<uint32_t (render_container &)> m_handler_callback;
+ handler_callback_func m_handler_callback;
ui_callback_type m_handler_callback_type;
uint32_t m_handler_param;
bool m_single_step;
@@ -270,7 +280,7 @@ private:
osd_ticks_t m_showfps_end;
bool m_show_profiler;
osd_ticks_t m_popup_text_end;
- std::unique_ptr<uint8_t[]> m_non_char_keys_down;
+ std::unique_ptr<uint8_t []> m_non_char_keys_down;
bitmap_argb32 m_mouse_bitmap;
render_texture * m_mouse_arrow_texture;
bool m_mouse_show;
@@ -280,6 +290,10 @@ private:
bool m_has_warnings;
std::unique_ptr<ui::machine_info> m_machine_info;
+ device_feature_set m_unemulated_features;
+ device_feature_set m_imperfect_features;
+ std::time_t m_last_launch_time;
+ std::time_t m_last_warning_time;
// static variables
static std::string messagebox_text;
@@ -298,6 +312,8 @@ private:
// private methods
void exit();
+ void config_load(config_type cfg_type, util::xml::data_node const *parentnode);
+ void config_save(config_type cfg_type, util::xml::data_node *parentnode);
std::unique_ptr<slider_state> slider_alloc(int id, const char *title, int32_t minval, int32_t defval, int32_t maxval, int32_t incval, void *arg);
// slider controls