mirror of
https://github.com/holub/mame
synced 2025-07-01 16:19:38 +03:00
emu/ioport.cpp: Improved validation of DIP switch locations.
* Treat an empty switch name as an error. * Treat a non-positive switch number as an error. * Also allocate fewer temporary strings.
This commit is contained in:
parent
1228725b7a
commit
fc41ef0c9a
@ -32,6 +32,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -420,16 +421,13 @@ u8 const inp_header::MAGIC[inp_header::OFFS_BASETIME - inp_header::OFFS_MAGIC] =
|
|||||||
// to the current list
|
// to the current list
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void ioport_list::append(device_t &device, std::string &errorbuf)
|
void ioport_list::append(device_t &device, std::ostream &errorbuf)
|
||||||
{
|
{
|
||||||
// no constructor, no list
|
// no constructor, no list
|
||||||
ioport_constructor constructor = device.input_ports();
|
ioport_constructor constructor = device.input_ports();
|
||||||
if (constructor == nullptr)
|
if (!constructor)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// reset error buffer
|
|
||||||
errorbuf.clear();
|
|
||||||
|
|
||||||
// detokenize into the list
|
// detokenize into the list
|
||||||
(*constructor)(device, *this, errorbuf);
|
(*constructor)(device, *this, errorbuf);
|
||||||
|
|
||||||
@ -692,7 +690,7 @@ ioport_setting::ioport_setting(ioport_field &field, ioport_value _value, const c
|
|||||||
// ioport_diplocation - constructor
|
// ioport_diplocation - constructor
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
ioport_diplocation::ioport_diplocation(const char *name, u8 swnum, bool invert) :
|
ioport_diplocation::ioport_diplocation(std::string_view name, u8 swnum, bool invert) :
|
||||||
m_name(name),
|
m_name(name),
|
||||||
m_number(swnum),
|
m_number(swnum),
|
||||||
m_invert(invert)
|
m_invert(invert)
|
||||||
@ -1359,7 +1357,7 @@ float ioport_field::crosshair_read() const
|
|||||||
// descriptions
|
// descriptions
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void ioport_field::expand_diplocation(const char *location, std::string &errorbuf)
|
void ioport_field::expand_diplocation(const char *location, std::ostream &errorbuf)
|
||||||
{
|
{
|
||||||
// if nothing present, bail
|
// if nothing present, bail
|
||||||
if (!location)
|
if (!location)
|
||||||
@ -1368,70 +1366,76 @@ void ioport_field::expand_diplocation(const char *location, std::string &errorbu
|
|||||||
m_diploclist.clear();
|
m_diploclist.clear();
|
||||||
|
|
||||||
// parse the string
|
// parse the string
|
||||||
std::string name; // Don't move this variable inside the loop, lastname's lifetime depends on it being outside
|
std::string_view lastname;
|
||||||
const char *lastname = nullptr;
|
|
||||||
const char *curentry = location;
|
const char *curentry = location;
|
||||||
int entries = 0;
|
int entries = 0;
|
||||||
while (*curentry != 0)
|
while (*curentry)
|
||||||
{
|
{
|
||||||
// find the end of this entry
|
// find the end of this entry
|
||||||
const char *comma = strchr(curentry, ',');
|
const char *comma = strchr(curentry, ',');
|
||||||
if (comma == nullptr)
|
if (!comma)
|
||||||
comma = curentry + strlen(curentry);
|
comma = curentry + strlen(curentry);
|
||||||
|
|
||||||
// extract it to tempbuf
|
// extract it to tempbuf
|
||||||
std::string tempstr(curentry, comma - curentry);
|
std::string_view tempstr(curentry, comma - curentry);
|
||||||
|
|
||||||
// first extract the switch name if present
|
// first extract the switch name if present
|
||||||
const char *number = tempstr.c_str();
|
std::string_view::size_type number = 0;
|
||||||
const char *colon = strchr(tempstr.c_str(), ':');
|
std::string_view::size_type const colon = tempstr.find(':');
|
||||||
|
|
||||||
if (colon != nullptr)
|
std::string_view name;
|
||||||
|
if (colon != std::string_view::npos)
|
||||||
{
|
{
|
||||||
// allocate and copy the name if it is present
|
// allocate and copy the name if it is present
|
||||||
lastname = name.assign(number, colon - number).c_str();
|
lastname = tempstr.substr(0, colon);
|
||||||
number = colon + 1;
|
number = colon + 1;
|
||||||
|
if (lastname.empty())
|
||||||
|
{
|
||||||
|
util::stream_format(errorbuf, "Switch location '%s' has empty switch name!\n", location);
|
||||||
|
lastname = "UNK";
|
||||||
|
}
|
||||||
|
name = lastname;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// otherwise, just copy the last name
|
// otherwise, just copy the last name
|
||||||
if (lastname == nullptr)
|
if (lastname.empty())
|
||||||
{
|
{
|
||||||
errorbuf.append(string_format("Switch location '%s' missing switch name!\n", location));
|
util::stream_format(errorbuf, "Switch location '%s' missing switch name!\n", location);
|
||||||
lastname = (char *)"UNK";
|
lastname = "UNK";
|
||||||
}
|
}
|
||||||
name.assign(lastname);
|
name = lastname;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the number is preceded by a '!' it's active high
|
// if the number is preceded by a '!' it's active high
|
||||||
bool invert = false;
|
bool const invert = tempstr[number] == '!';
|
||||||
if (*number == '!')
|
if (invert)
|
||||||
{
|
++number;
|
||||||
invert = true;
|
|
||||||
number++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// now scan the switch number
|
// now scan the switch number
|
||||||
int swnum = -1;
|
int swnum = -1;
|
||||||
if (sscanf(number, "%d", &swnum) != 1)
|
if (sscanf(&tempstr[number], "%d", &swnum) != 1)
|
||||||
errorbuf.append(string_format("Switch location '%s' has invalid format!\n", location));
|
util::stream_format(errorbuf, "Switch location '%s' has invalid format!\n", location);
|
||||||
|
else if (0 >= swnum)
|
||||||
|
util::stream_format(errorbuf, "Switch location '%s' has switch number that is not positive!\n", location);
|
||||||
|
|
||||||
// allocate a new entry
|
// allocate a new entry
|
||||||
m_diploclist.emplace_back(name.c_str(), swnum, invert);
|
if (0 < swnum)
|
||||||
|
m_diploclist.emplace_back(name, swnum, invert);
|
||||||
entries++;
|
entries++;
|
||||||
|
|
||||||
// advance to the next item
|
// advance to the next item
|
||||||
curentry = comma;
|
curentry = comma;
|
||||||
if (*curentry != 0)
|
if (*curentry)
|
||||||
curentry++;
|
curentry++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// then verify the number of bits in the mask matches
|
// then verify the number of bits in the mask matches
|
||||||
int const bits = population_count_32(m_mask);
|
int const bits = population_count_32(m_mask);
|
||||||
if (bits > entries)
|
if (bits > entries)
|
||||||
errorbuf.append(string_format("Switch location '%s' does not describe enough bits for mask %X\n", location, m_mask));
|
util::stream_format(errorbuf, "Switch location '%s' does not describe enough bits for mask %X\n", location, m_mask);
|
||||||
else if (bits < entries)
|
else if (bits < entries)
|
||||||
errorbuf.append(string_format("Switch location '%s' describes too many bits for mask %X\n", location, m_mask));
|
util::stream_format(errorbuf, "Switch location '%s' describes too many bits for mask %X\n", location, m_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1638,7 +1642,7 @@ void ioport_port::frame_update()
|
|||||||
// wholly overlapped by other fields
|
// wholly overlapped by other fields
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void ioport_port::collapse_fields(std::string &errorbuf)
|
void ioport_port::collapse_fields(std::ostream &errorbuf)
|
||||||
{
|
{
|
||||||
ioport_value maskbits = 0;
|
ioport_value maskbits = 0;
|
||||||
int lastmodcount = -1;
|
int lastmodcount = -1;
|
||||||
@ -1667,13 +1671,13 @@ void ioport_port::collapse_fields(std::string &errorbuf)
|
|||||||
// for errors
|
// for errors
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void ioport_port::insert_field(ioport_field &newfield, ioport_value &disallowedbits, std::string &errorbuf)
|
void ioport_port::insert_field(ioport_field &newfield, ioport_value &disallowedbits, std::ostream &errorbuf)
|
||||||
{
|
{
|
||||||
// verify against the disallowed bits, but only if we are condition-free
|
// verify against the disallowed bits, but only if we are condition-free
|
||||||
if (newfield.condition().none())
|
if (newfield.condition().none())
|
||||||
{
|
{
|
||||||
if ((newfield.mask() & disallowedbits) != 0)
|
if ((newfield.mask() & disallowedbits) != 0)
|
||||||
errorbuf.append(string_format("INPUT_TOKEN_FIELD specifies duplicate port bits (port=%s mask=%X)\n", tag(), newfield.mask()));
|
util::stream_format(errorbuf, "INPUT_TOKEN_FIELD specifies duplicate port bits (port=%s mask=%X)\n", tag(), newfield.mask());
|
||||||
disallowedbits |= newfield.mask();
|
disallowedbits |= newfield.mask();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1812,12 +1816,17 @@ time_t ioport_manager::initialize()
|
|||||||
|
|
||||||
// if we have a token list, proceed
|
// if we have a token list, proceed
|
||||||
device_enumerator iter(machine().root_device());
|
device_enumerator iter(machine().root_device());
|
||||||
for (device_t &device : iter)
|
|
||||||
{
|
{
|
||||||
std::string errors;
|
std::ostringstream errors;
|
||||||
m_portlist.append(device, errors);
|
for (device_t &device : iter)
|
||||||
if (!errors.empty())
|
{
|
||||||
osd_printf_error("Input port errors:\n%s", errors);
|
m_portlist.append(device, errors);
|
||||||
|
if (errors.tellp())
|
||||||
|
{
|
||||||
|
osd_printf_error("Input port errors:\n%s", std::move(errors).str());
|
||||||
|
errors.str("");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// renumber player numbers for controller ports
|
// renumber player numbers for controller ports
|
||||||
@ -3274,7 +3283,7 @@ void ioport_manager::record_port(ioport_port &port)
|
|||||||
// ioport_configurer - constructor
|
// ioport_configurer - constructor
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
ioport_configurer::ioport_configurer(device_t &owner, ioport_list &portlist, std::string &errorbuf) :
|
ioport_configurer::ioport_configurer(device_t &owner, ioport_list &portlist, std::ostream &errorbuf) :
|
||||||
m_owner(owner),
|
m_owner(owner),
|
||||||
m_portlist(portlist),
|
m_portlist(portlist),
|
||||||
m_errorbuf(errorbuf),
|
m_errorbuf(errorbuf),
|
||||||
|
@ -25,9 +25,11 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
#include <iosfwd>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
@ -325,7 +327,7 @@ enum
|
|||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
||||||
// constructor function pointer
|
// constructor function pointer
|
||||||
typedef void(*ioport_constructor)(device_t &owner, ioport_list &portlist, std::string &errorbuf);
|
typedef void(*ioport_constructor)(device_t &owner, ioport_list &portlist, std::ostream &errorbuf);
|
||||||
|
|
||||||
// I/O port callback function delegates
|
// I/O port callback function delegates
|
||||||
typedef device_delegate<ioport_value ()> ioport_field_read_delegate;
|
typedef device_delegate<ioport_value ()> ioport_field_read_delegate;
|
||||||
@ -529,7 +531,7 @@ class ioport_diplocation
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// construction/destruction
|
// construction/destruction
|
||||||
ioport_diplocation(const char *name, u8 swnum, bool invert);
|
ioport_diplocation(std::string_view name, u8 swnum, bool invert);
|
||||||
|
|
||||||
// getters
|
// getters
|
||||||
const char *name() const { return m_name.c_str(); }
|
const char *name() const { return m_name.c_str(); }
|
||||||
@ -664,7 +666,7 @@ public:
|
|||||||
void set_user_settings(const user_settings &settings);
|
void set_user_settings(const user_settings &settings);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void expand_diplocation(const char *location, std::string &errorbuf);
|
void expand_diplocation(const char *location, std::ostream &errorbuf);
|
||||||
|
|
||||||
// internal state
|
// internal state
|
||||||
ioport_field * m_next; // pointer to next field in sequence
|
ioport_field * m_next; // pointer to next field in sequence
|
||||||
@ -744,7 +746,7 @@ class ioport_list : public std::map<std::string, std::unique_ptr<ioport_port>>
|
|||||||
public:
|
public:
|
||||||
ioport_list() { }
|
ioport_list() { }
|
||||||
|
|
||||||
void append(device_t &device, std::string &errorbuf);
|
void append(device_t &device, std::ostream &errorbuf);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -779,13 +781,13 @@ public:
|
|||||||
|
|
||||||
// other operations
|
// other operations
|
||||||
ioport_field *field(ioport_value mask) const;
|
ioport_field *field(ioport_value mask) const;
|
||||||
void collapse_fields(std::string &errorbuf);
|
void collapse_fields(std::ostream &errorbuf);
|
||||||
void frame_update();
|
void frame_update();
|
||||||
void init_live_state();
|
void init_live_state();
|
||||||
void update_defvalue(bool flush_defaults);
|
void update_defvalue(bool flush_defaults);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void insert_field(ioport_field &newfield, ioport_value &disallowedbits, std::string &errorbuf);
|
void insert_field(ioport_field &newfield, ioport_value &disallowedbits, std::ostream &errorbuf);
|
||||||
|
|
||||||
// internal state
|
// internal state
|
||||||
ioport_port * m_next; // pointer to next port
|
ioport_port * m_next; // pointer to next port
|
||||||
@ -1033,7 +1035,7 @@ class ioport_configurer
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// construction/destruction
|
// construction/destruction
|
||||||
ioport_configurer(device_t &owner, ioport_list &portlist, std::string &errorbuf);
|
ioport_configurer(device_t &owner, ioport_list &portlist, std::ostream &errorbuf);
|
||||||
|
|
||||||
// static helpers
|
// static helpers
|
||||||
static const char *string_from_token(const char *string);
|
static const char *string_from_token(const char *string);
|
||||||
@ -1083,7 +1085,7 @@ private:
|
|||||||
// internal state
|
// internal state
|
||||||
device_t & m_owner;
|
device_t & m_owner;
|
||||||
ioport_list & m_portlist;
|
ioport_list & m_portlist;
|
||||||
std::string & m_errorbuf;
|
std::ostream & m_errorbuf;
|
||||||
|
|
||||||
ioport_port * m_curport;
|
ioport_port * m_curport;
|
||||||
ioport_field * m_curfield;
|
ioport_field * m_curfield;
|
||||||
@ -1123,7 +1125,7 @@ private:
|
|||||||
|
|
||||||
// start of table
|
// start of table
|
||||||
#define INPUT_PORTS_START(_name) \
|
#define INPUT_PORTS_START(_name) \
|
||||||
ATTR_COLD void INPUT_PORTS_NAME(_name)(device_t &owner, ioport_list &portlist, std::string &errorbuf) \
|
ATTR_COLD void INPUT_PORTS_NAME(_name)(device_t &owner, ioport_list &portlist, std::ostream &errorbuf) \
|
||||||
{ \
|
{ \
|
||||||
ioport_configurer configurer(owner, portlist, errorbuf);
|
ioport_configurer configurer(owner, portlist, errorbuf);
|
||||||
// end of table
|
// end of table
|
||||||
@ -1132,7 +1134,7 @@ ATTR_COLD void INPUT_PORTS_NAME(_name)(device_t &owner, ioport_list &portlist, s
|
|||||||
|
|
||||||
// aliasing
|
// aliasing
|
||||||
#define INPUT_PORTS_EXTERN(_name) \
|
#define INPUT_PORTS_EXTERN(_name) \
|
||||||
extern void INPUT_PORTS_NAME(_name)(device_t &owner, ioport_list &portlist, std::string &errorbuf)
|
extern void INPUT_PORTS_NAME(_name)(device_t &owner, ioport_list &portlist, std::ostream &errorbuf)
|
||||||
|
|
||||||
// including
|
// including
|
||||||
#define PORT_INCLUDE(_name) \
|
#define PORT_INCLUDE(_name) \
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "unicode.h"
|
#include "unicode.h"
|
||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
#include <sstream>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
|
|
||||||
@ -2495,12 +2496,13 @@ void validity_checker::validate_inputs(device_t &root)
|
|||||||
|
|
||||||
// allocate the input ports
|
// allocate the input ports
|
||||||
ioport_list portlist;
|
ioport_list portlist;
|
||||||
std::string errorbuf;
|
{
|
||||||
portlist.append(device, errorbuf);
|
// report any errors during construction
|
||||||
|
std::ostringstream errorbuf;
|
||||||
// report any errors during construction
|
portlist.append(device, errorbuf);
|
||||||
if (!errorbuf.empty())
|
if (errorbuf.tellp())
|
||||||
osd_printf_error("I/O port error during construction:\n%s\n", errorbuf);
|
osd_printf_error("I/O port error during construction:\n%s\n", std::move(errorbuf).str());
|
||||||
|
}
|
||||||
|
|
||||||
// do a first pass over ports to add their names and find duplicates
|
// do a first pass over ports to add their names and find duplicates
|
||||||
for (auto &port : portlist)
|
for (auto &port : portlist)
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include <future>
|
#include <future>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <sstream>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -696,17 +697,19 @@ void output_one(std::ostream &out, driver_enumerator &drivlist, const game_drive
|
|||||||
|
|
||||||
// allocate input ports and build overall emulation status
|
// allocate input ports and build overall emulation status
|
||||||
ioport_list portlist;
|
ioport_list portlist;
|
||||||
std::string errors;
|
|
||||||
device_t::feature_type overall_unemulated(driver.type.unemulated_features());
|
device_t::feature_type overall_unemulated(driver.type.unemulated_features());
|
||||||
device_t::feature_type overall_imperfect(driver.type.imperfect_features());
|
device_t::feature_type overall_imperfect(driver.type.imperfect_features());
|
||||||
for (device_t &device : iter)
|
|
||||||
{
|
{
|
||||||
portlist.append(device, errors);
|
std::ostringstream errors;
|
||||||
overall_unemulated |= device.type().unemulated_features();
|
for (device_t &device : iter)
|
||||||
overall_imperfect |= device.type().imperfect_features();
|
{
|
||||||
|
portlist.append(device, errors);
|
||||||
|
overall_unemulated |= device.type().unemulated_features();
|
||||||
|
overall_imperfect |= device.type().imperfect_features();
|
||||||
|
|
||||||
if (devtypes && device.owner())
|
if (devtypes && device.owner())
|
||||||
devtypes->insert(&device.type());
|
devtypes->insert(&device.type());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// renumber player numbers for controller ports
|
// renumber player numbers for controller ports
|
||||||
@ -815,24 +818,30 @@ void output_one_device(std::ostream &out, machine_config &config, device_t &devi
|
|||||||
|
|
||||||
// generate input list and build overall emulation status
|
// generate input list and build overall emulation status
|
||||||
ioport_list portlist;
|
ioport_list portlist;
|
||||||
std::string errors;
|
|
||||||
device_t::feature_type overall_unemulated(device.type().unemulated_features());
|
device_t::feature_type overall_unemulated(device.type().unemulated_features());
|
||||||
device_t::feature_type overall_imperfect(device.type().imperfect_features());
|
device_t::feature_type overall_imperfect(device.type().imperfect_features());
|
||||||
for (device_t &dev : device_enumerator(device))
|
|
||||||
{
|
{
|
||||||
portlist.append(dev, errors);
|
std::ostringstream errors;
|
||||||
overall_unemulated |= dev.type().unemulated_features();
|
for (device_t &dev : device_enumerator(device))
|
||||||
overall_imperfect |= dev.type().imperfect_features();
|
{
|
||||||
|
portlist.append(dev, errors);
|
||||||
|
overall_unemulated |= dev.type().unemulated_features();
|
||||||
|
overall_imperfect |= dev.type().imperfect_features();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the device adds player inputs (other than dsw and configs) to the system
|
// check if the device adds player inputs (other than dsw and configs) to the system
|
||||||
for (auto &port : portlist)
|
for (auto &port : portlist)
|
||||||
|
{
|
||||||
for (ioport_field const &field : port.second->fields())
|
for (ioport_field const &field : port.second->fields())
|
||||||
|
{
|
||||||
if (field.type() >= IPT_START1 && field.type() < IPT_UI_FIRST)
|
if (field.type() >= IPT_START1 && field.type() < IPT_UI_FIRST)
|
||||||
{
|
{
|
||||||
has_input = true;
|
has_input = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// start to output info
|
// start to output info
|
||||||
util::stream_format(out, "\t<%s name=\"%s\"", XML_TOP, normalize_string(device.shortname()));
|
util::stream_format(out, "\t<%s name=\"%s\"", XML_TOP, normalize_string(device.shortname()));
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "util/unicode.h"
|
#include "util/unicode.h"
|
||||||
|
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
|
||||||
namespace ui {
|
namespace ui {
|
||||||
@ -235,11 +236,13 @@ void menu_device_config::populate_text(std::optional<text_layout> &layout, float
|
|||||||
|
|
||||||
int input = 0, input_mj = 0, input_hana = 0, input_gamble = 0, input_analog = 0, input_adjust = 0;
|
int input = 0, input_mj = 0, input_hana = 0, input_gamble = 0, input_analog = 0, input_adjust = 0;
|
||||||
int input_keypad = 0, input_keyboard = 0, dips = 0, confs = 0;
|
int input_keypad = 0, input_keyboard = 0, dips = 0, confs = 0;
|
||||||
std::string errors;
|
|
||||||
std::ostringstream dips_opt, confs_opt;
|
std::ostringstream dips_opt, confs_opt;
|
||||||
ioport_list portlist;
|
ioport_list portlist;
|
||||||
for (device_t &iptdev : device_enumerator(*dev))
|
{
|
||||||
portlist.append(iptdev, errors);
|
std::ostringstream errors;
|
||||||
|
for (device_t &iptdev : device_enumerator(*dev))
|
||||||
|
portlist.append(iptdev, errors);
|
||||||
|
}
|
||||||
|
|
||||||
// check if the device adds inputs to the system
|
// check if the device adds inputs to the system
|
||||||
for (auto &port : portlist)
|
for (auto &port : portlist)
|
||||||
|
@ -230,7 +230,7 @@ machine_static_info::machine_static_info(const ui_options &options, machine_conf
|
|||||||
, m_has_analog(false)
|
, m_has_analog(false)
|
||||||
{
|
{
|
||||||
ioport_list local_ports;
|
ioport_list local_ports;
|
||||||
std::string sink;
|
std::ostringstream sink;
|
||||||
for (device_t &device : device_enumerator(config.root_device()))
|
for (device_t &device : device_enumerator(config.root_device()))
|
||||||
{
|
{
|
||||||
// the "no sound hardware" warning doesn't make sense when you plug in a sound card
|
// the "no sound hardware" warning doesn't make sense when you plug in a sound card
|
||||||
|
Loading…
Reference in New Issue
Block a user