summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/ioport.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/ioport.h')
-rw-r--r--src/emu/ioport.h973
1 files changed, 312 insertions, 661 deletions
diff --git a/src/emu/ioport.h b/src/emu/ioport.h
index df7d2ad026b..8e8009ffce6 100644
--- a/src/emu/ioport.h
+++ b/src/emu/ioport.h
@@ -17,44 +17,42 @@
#ifndef MAME_EMU_IOPORT_H
#define MAME_EMU_IOPORT_H
+#include "inpttype.h"
+
+#include "ioprocs.h"
+
+#include <array>
#include <cstdint>
#include <cstring>
-#include <time.h>
+#include <ctime>
+#include <functional>
+#include <iosfwd>
+#include <initializer_list>
+#include <list>
+#include <memory>
+#include <string_view>
+#include <vector>
//**************************************************************************
// CONSTANTS
//**************************************************************************
-// input ports support up to 32 bits each
-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;
-
-
-// sequence types for input_port_seq() call
-enum input_seq_type
-{
- SEQ_TYPE_INVALID = -1,
- SEQ_TYPE_STANDARD = 0,
- SEQ_TYPE_INCREMENT,
- SEQ_TYPE_DECREMENT,
- SEQ_TYPE_TOTAL
-};
-DECLARE_ENUM_INCDEC_OPERATORS(input_seq_type)
+constexpr char32_t UCHAR_INVALID = 0xffff;
+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_SHIFT_END + 1;
// crosshair types
@@ -86,326 +84,6 @@ enum ioport_group
};
-// various input port types
-enum ioport_type
-{
- // pseudo-port types
- IPT_INVALID = 0,
- IPT_UNUSED,
- IPT_END,
- IPT_UNKNOWN,
- IPT_PORT,
- IPT_DIPSWITCH,
- IPT_CONFIG,
-
- // start buttons
- IPT_START1,
- IPT_START2,
- IPT_START3,
- IPT_START4,
- IPT_START5,
- IPT_START6,
- IPT_START7,
- IPT_START8,
- IPT_START9,
- IPT_START10,
-
- // coin slots
- IPT_COIN1,
- IPT_COIN2,
- IPT_COIN3,
- IPT_COIN4,
- IPT_COIN5,
- IPT_COIN6,
- IPT_COIN7,
- IPT_COIN8,
- IPT_COIN9,
- IPT_COIN10,
- IPT_COIN11,
- IPT_COIN12,
- IPT_BILL1,
-
- // service coin
- IPT_SERVICE1,
- IPT_SERVICE2,
- IPT_SERVICE3,
- IPT_SERVICE4,
-
- // tilt inputs
- IPT_TILT1,
- IPT_TILT2,
- IPT_TILT3,
- IPT_TILT4,
-
- // misc other digital inputs
- IPT_POWER_ON,
- IPT_POWER_OFF,
- IPT_SERVICE,
- IPT_TILT,
- IPT_INTERLOCK,
- IPT_MEMORY_RESET,
- IPT_VOLUME_UP,
- IPT_VOLUME_DOWN,
- IPT_START, // use the numbered start button(s) for coin-ops
- IPT_SELECT,
- IPT_KEYPAD,
- IPT_KEYBOARD,
-
- // digital joystick inputs
- IPT_DIGITAL_JOYSTICK_FIRST,
-
- // use IPT_JOYSTICK for panels where the player has one single joystick
- IPT_JOYSTICK_UP,
- IPT_JOYSTICK_DOWN,
- IPT_JOYSTICK_LEFT,
- IPT_JOYSTICK_RIGHT,
-
- // use IPT_JOYSTICKLEFT and IPT_JOYSTICKRIGHT for dual joystick panels
- IPT_JOYSTICKRIGHT_UP,
- IPT_JOYSTICKRIGHT_DOWN,
- IPT_JOYSTICKRIGHT_LEFT,
- IPT_JOYSTICKRIGHT_RIGHT,
- IPT_JOYSTICKLEFT_UP,
- IPT_JOYSTICKLEFT_DOWN,
- IPT_JOYSTICKLEFT_LEFT,
- IPT_JOYSTICKLEFT_RIGHT,
-
- IPT_DIGITAL_JOYSTICK_LAST,
-
- // action buttons
- IPT_BUTTON1,
- IPT_BUTTON2,
- IPT_BUTTON3,
- IPT_BUTTON4,
- IPT_BUTTON5,
- IPT_BUTTON6,
- IPT_BUTTON7,
- IPT_BUTTON8,
- IPT_BUTTON9,
- IPT_BUTTON10,
- IPT_BUTTON11,
- IPT_BUTTON12,
- IPT_BUTTON13,
- IPT_BUTTON14,
- IPT_BUTTON15,
- IPT_BUTTON16,
-
- // mahjong inputs
- IPT_MAHJONG_FIRST,
-
- IPT_MAHJONG_A,
- IPT_MAHJONG_B,
- IPT_MAHJONG_C,
- IPT_MAHJONG_D,
- IPT_MAHJONG_E,
- IPT_MAHJONG_F,
- IPT_MAHJONG_G,
- IPT_MAHJONG_H,
- IPT_MAHJONG_I,
- IPT_MAHJONG_J,
- IPT_MAHJONG_K,
- IPT_MAHJONG_L,
- IPT_MAHJONG_M,
- IPT_MAHJONG_N,
- IPT_MAHJONG_O,
- IPT_MAHJONG_P,
- IPT_MAHJONG_Q,
- IPT_MAHJONG_KAN,
- IPT_MAHJONG_PON,
- IPT_MAHJONG_CHI,
- IPT_MAHJONG_REACH,
- IPT_MAHJONG_RON,
- IPT_MAHJONG_BET,
- IPT_MAHJONG_LAST_CHANCE,
- IPT_MAHJONG_SCORE,
- IPT_MAHJONG_DOUBLE_UP,
- IPT_MAHJONG_FLIP_FLOP,
- IPT_MAHJONG_BIG,
- IPT_MAHJONG_SMALL,
-
- IPT_MAHJONG_LAST,
-
- // hanafuda inputs
- IPT_HANAFUDA_FIRST,
-
- IPT_HANAFUDA_A,
- IPT_HANAFUDA_B,
- IPT_HANAFUDA_C,
- IPT_HANAFUDA_D,
- IPT_HANAFUDA_E,
- IPT_HANAFUDA_F,
- IPT_HANAFUDA_G,
- IPT_HANAFUDA_H,
- IPT_HANAFUDA_YES,
- IPT_HANAFUDA_NO,
-
- IPT_HANAFUDA_LAST,
-
- // gambling inputs
- IPT_GAMBLING_FIRST,
-
- IPT_GAMBLE_KEYIN, // attendant
- IPT_GAMBLE_KEYOUT, // attendant
- IPT_GAMBLE_SERVICE, // attendant
- IPT_GAMBLE_BOOK, // attendant
- IPT_GAMBLE_DOOR, // attendant
- // IPT_GAMBLE_DOOR2, // many gambling games have several doors.
- // IPT_GAMBLE_DOOR3,
- // IPT_GAMBLE_DOOR4,
- // IPT_GAMBLE_DOOR5,
-
- IPT_GAMBLE_HIGH, // player
- IPT_GAMBLE_LOW, // player
- IPT_GAMBLE_HALF, // player
- IPT_GAMBLE_DEAL, // player
- IPT_GAMBLE_D_UP, // player
- IPT_GAMBLE_TAKE, // player
- IPT_GAMBLE_STAND, // player
- IPT_GAMBLE_BET, // player
- IPT_GAMBLE_PAYOUT, // player
-
- // poker-specific inputs
- IPT_POKER_HOLD1,
- IPT_POKER_HOLD2,
- IPT_POKER_HOLD3,
- IPT_POKER_HOLD4,
- IPT_POKER_HOLD5,
- IPT_POKER_CANCEL,
- IPT_POKER_BET,
-
- // slot-specific inputs
- IPT_SLOT_STOP1,
- IPT_SLOT_STOP2,
- IPT_SLOT_STOP3,
- IPT_SLOT_STOP4,
- IPT_SLOT_STOP_ALL,
-
- IPT_GAMBLING_LAST,
-
- // analog inputs
- IPT_ANALOG_FIRST,
-
- IPT_ANALOG_ABSOLUTE_FIRST,
-
- IPT_AD_STICK_X, // absolute // autocenter
- IPT_AD_STICK_Y, // absolute // autocenter
- IPT_AD_STICK_Z, // absolute // autocenter
- IPT_PADDLE, // absolute // autocenter
- IPT_PADDLE_V, // absolute // autocenter
- IPT_PEDAL, // absolute // autocenter
- IPT_PEDAL2, // absolute // autocenter
- IPT_PEDAL3, // absolute // autocenter
- IPT_LIGHTGUN_X, // absolute
- IPT_LIGHTGUN_Y, // absolute
- IPT_POSITIONAL, // absolute // autocenter if not wraps
- IPT_POSITIONAL_V, // absolute // autocenter if not wraps
-
- IPT_ANALOG_ABSOLUTE_LAST,
-
- IPT_DIAL, // relative
- IPT_DIAL_V, // relative
- IPT_TRACKBALL_X, // relative
- IPT_TRACKBALL_Y, // relative
- IPT_MOUSE_X, // relative
- IPT_MOUSE_Y, // relative
-
- IPT_ANALOG_LAST,
-
- // analog adjuster support
- IPT_ADJUSTER,
-
- // the following are special codes for user interface handling - not to be used by drivers!
- IPT_UI_FIRST,
-
- IPT_UI_CONFIGURE,
- IPT_UI_ON_SCREEN_DISPLAY,
- IPT_UI_DEBUG_BREAK,
- IPT_UI_PAUSE,
- IPT_UI_PAUSE_SINGLE,
- IPT_UI_REWIND_SINGLE,
- IPT_UI_RESET_MACHINE,
- IPT_UI_SOFT_RESET,
- IPT_UI_SHOW_GFX,
- IPT_UI_FRAMESKIP_DEC,
- IPT_UI_FRAMESKIP_INC,
- IPT_UI_THROTTLE,
- IPT_UI_FAST_FORWARD,
- IPT_UI_SHOW_FPS,
- IPT_UI_SNAPSHOT,
- IPT_UI_TIMECODE,
- IPT_UI_RECORD_MNG,
- IPT_UI_RECORD_AVI,
- IPT_UI_TOGGLE_CHEAT,
- IPT_UI_UP,
- IPT_UI_DOWN,
- IPT_UI_LEFT,
- IPT_UI_RIGHT,
- IPT_UI_HOME,
- IPT_UI_END,
- IPT_UI_PAGE_UP,
- IPT_UI_PAGE_DOWN,
- IPT_UI_FOCUS_NEXT,
- IPT_UI_FOCUS_PREV,
- IPT_UI_SELECT,
- IPT_UI_CANCEL,
- IPT_UI_DISPLAY_COMMENT,
- IPT_UI_CLEAR,
- IPT_UI_ZOOM_IN,
- IPT_UI_ZOOM_OUT,
- IPT_UI_PREV_GROUP,
- IPT_UI_NEXT_GROUP,
- IPT_UI_ROTATE,
- IPT_UI_SHOW_PROFILER,
- IPT_UI_TOGGLE_UI,
- IPT_UI_TOGGLE_DEBUG,
- IPT_UI_PASTE,
- IPT_UI_SAVE_STATE,
- IPT_UI_LOAD_STATE,
- IPT_UI_TAPE_START,
- IPT_UI_TAPE_STOP,
- IPT_UI_DATS,
- IPT_UI_FAVORITES,
- IPT_UI_EXPORT,
- IPT_UI_AUDIT_FAST,
- IPT_UI_AUDIT_ALL,
- IPT_UI_TOGGLE_AUTOFIRE,
-
- // additional OSD-specified UI port types (up to 16)
- IPT_OSD_1,
- IPT_OSD_2,
- IPT_OSD_3,
- IPT_OSD_4,
- IPT_OSD_5,
- IPT_OSD_6,
- IPT_OSD_7,
- IPT_OSD_8,
- IPT_OSD_9,
- IPT_OSD_10,
- IPT_OSD_11,
- IPT_OSD_12,
- IPT_OSD_13,
- IPT_OSD_14,
- IPT_OSD_15,
- IPT_OSD_16,
-
- IPT_UI_LAST,
-
- IPT_OTHER, // not mapped to standard defaults
-
- IPT_SPECIAL, // uninterpreted characters
- IPT_CUSTOM, // handled by custom code
- IPT_OUTPUT,
-
- IPT_COUNT
-};
-DECLARE_ENUM_INCDEC_OPERATORS(ioport_type)
-// aliases for some types
-#define IPT_PADDLE_H IPT_PADDLE
-#define IPT_PEDAL1 IPT_PEDAL
-#define IPT_POSITIONAL_H IPT_POSITIONAL
-#define IPT_DIAL_H IPT_DIAL
-
-
// input type classes
enum ioport_type_class
{
@@ -452,13 +130,13 @@ enum
INPUT_STRING_3C_1C, // 0.333333
INPUT_STRING_8C_3C, // 0.375000
// INPUT_STRING_10C_4C, // 0.400000
-// INPUT_STRING_5C_2C, // 0.400000
// INPUT_STRING_7C_3C, // 0.428571
// INPUT_STRING_9C_4C, // 0.444444
// INPUT_STRING_10C_5C, // 0.500000
// INPUT_STRING_8C_4C, // 0.500000
// INPUT_STRING_6C_3C, // 0.500000
INPUT_STRING_4C_2C, // 0.500000
+ INPUT_STRING_5C_2C, // 0.500000
INPUT_STRING_2C_1C, // 0.500000
// INPUT_STRING_9C_5C, // 0.555556
// INPUT_STRING_7C_4C, // 0.571429
@@ -496,6 +174,7 @@ enum
// INPUT_STRING_6C_7C, // 1.166667
// INPUT_STRING_5C_6C, // 1.200000
// INPUT_STRING_8C_10C, // 1.250000
+ INPUT_STRING_3C_5C, // 1.250000
INPUT_STRING_4C_5C, // 1.250000
// INPUT_STRING_7C_9C, // 1.285714
// INPUT_STRING_6C_8C, // 1.333333
@@ -650,7 +329,7 @@ enum
//**************************************************************************
// 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
typedef device_delegate<ioport_value ()> ioport_field_read_delegate;
@@ -658,116 +337,6 @@ typedef device_delegate<void (ioport_field &, u32, ioport_value, ioport_value)>
typedef device_delegate<float (float)> ioport_field_crossmap_delegate;
-// ======================> inp_header
-
-// header at the front of INP files
-class inp_header
-{
-public:
- // parameters
- static constexpr unsigned MAJVERSION = 3;
- static constexpr unsigned MINVERSION = 0;
-
- bool read(emu_file &f)
- {
- return f.read(m_data, sizeof(m_data)) == sizeof(m_data);
- }
- bool write(emu_file &f) const
- {
- return f.write(m_data, sizeof(m_data)) == sizeof(m_data);
- }
-
- bool check_magic() const
- {
- return 0 == std::memcmp(MAGIC, m_data + OFFS_MAGIC, OFFS_BASETIME - OFFS_MAGIC);
- }
- u64 get_basetime() const
- {
- return
- (u64(m_data[OFFS_BASETIME + 0]) << (0 * 8)) |
- (u64(m_data[OFFS_BASETIME + 1]) << (1 * 8)) |
- (u64(m_data[OFFS_BASETIME + 2]) << (2 * 8)) |
- (u64(m_data[OFFS_BASETIME + 3]) << (3 * 8)) |
- (u64(m_data[OFFS_BASETIME + 4]) << (4 * 8)) |
- (u64(m_data[OFFS_BASETIME + 5]) << (5 * 8)) |
- (u64(m_data[OFFS_BASETIME + 6]) << (6 * 8)) |
- (u64(m_data[OFFS_BASETIME + 7]) << (7 * 8));
- }
- unsigned get_majversion() const
- {
- return m_data[OFFS_MAJVERSION];
- }
- unsigned get_minversion() const
- {
- return m_data[OFFS_MINVERSION];
- }
- std::string get_sysname() const
- {
- return get_string<OFFS_SYSNAME, OFFS_APPDESC>();
- }
- std::string get_appdesc() const
- {
- return get_string<OFFS_APPDESC, OFFS_END>();
- }
-
- void set_magic()
- {
- std::memcpy(m_data + OFFS_MAGIC, MAGIC, OFFS_BASETIME - OFFS_MAGIC);
- }
- void set_basetime(u64 time)
- {
- m_data[OFFS_BASETIME + 0] = u8((time >> (0 * 8)) & 0x00ff);
- m_data[OFFS_BASETIME + 1] = u8((time >> (1 * 8)) & 0x00ff);
- m_data[OFFS_BASETIME + 2] = u8((time >> (2 * 8)) & 0x00ff);
- m_data[OFFS_BASETIME + 3] = u8((time >> (3 * 8)) & 0x00ff);
- m_data[OFFS_BASETIME + 4] = u8((time >> (4 * 8)) & 0x00ff);
- m_data[OFFS_BASETIME + 5] = u8((time >> (5 * 8)) & 0x00ff);
- m_data[OFFS_BASETIME + 6] = u8((time >> (6 * 8)) & 0x00ff);
- m_data[OFFS_BASETIME + 7] = u8((time >> (7 * 8)) & 0x00ff);
- }
- void set_version()
- {
- m_data[OFFS_MAJVERSION] = MAJVERSION;
- m_data[OFFS_MINVERSION] = MINVERSION;
- }
- void set_sysname(std::string const &name)
- {
- set_string<OFFS_SYSNAME, OFFS_APPDESC>(name);
- }
- void set_appdesc(std::string const &desc)
- {
- set_string<OFFS_APPDESC, OFFS_END>(desc);
- }
-
-private:
- template <std::size_t BEGIN, std::size_t END> void set_string(std::string const &str)
- {
- std::size_t const used = (std::min<std::size_t>)(str.size() + 1, END - BEGIN);
- std::memcpy(m_data + BEGIN, str.c_str(), used);
- if ((END - BEGIN) > used)
- std::memset(m_data + BEGIN + used, 0, (END - BEGIN) - used);
- }
- template <std::size_t BEGIN, std::size_t END> std::string get_string() const
- {
- char const *const begin = reinterpret_cast<char const *>(m_data + BEGIN);
- return std::string(begin, std::find(begin, reinterpret_cast<char const *>(m_data + END), '\0'));
- }
-
- static constexpr std::size_t OFFS_MAGIC = 0x00; // 0x08 bytes
- static constexpr std::size_t OFFS_BASETIME = 0x08; // 0x08 bytes (little-endian binary integer)
- static constexpr std::size_t OFFS_MAJVERSION = 0x10; // 0x01 bytes (binary integer)
- static constexpr std::size_t OFFS_MINVERSION = 0x11; // 0x01 bytes (binary integer)
- // 0x02 bytes reserved
- static constexpr std::size_t OFFS_SYSNAME = 0x14; // 0x0c bytes (ASCII)
- static constexpr std::size_t OFFS_APPDESC = 0x20; // 0x20 bytes (ASCII)
- static constexpr std::size_t OFFS_END = 0x40;
-
- static u8 const MAGIC[OFFS_BASETIME - OFFS_MAGIC];
-
- u8 m_data[OFFS_END];
-};
-
-
// ======================> input_device_default
// device defined default input settings
@@ -784,38 +353,39 @@ struct input_device_default
// describes a fundamental input type, including default input sequences
class input_type_entry
{
- friend class simple_list<input_type_entry>;
- friend class ioport_manager;
-
public:
// construction/destruction
- input_type_entry(ioport_type type, ioport_group group, int player, const char *token, const char *name, input_seq standard);
- input_type_entry(ioport_type type, ioport_group group, int player, const char *token, const char *name, input_seq standard, input_seq decrement, input_seq increment);
+ input_type_entry(ioport_type type, ioport_group group, int player, const char *token, const char *name, input_seq standard) noexcept;
+ input_type_entry(ioport_type type, ioport_group group, int player, const char *token, const char *name, input_seq standard, input_seq decrement, input_seq increment) noexcept;
// getters
- input_type_entry *next() const { return m_next; }
- ioport_type type() const { return m_type; }
- ioport_group group() const { return m_group; }
- u8 player() const { return m_player; }
- const char *token() const { return m_token; }
- const char *name() const { return m_name; }
- input_seq &defseq(input_seq_type seqtype = SEQ_TYPE_STANDARD) { return m_defseq[seqtype]; }
- const input_seq &seq(input_seq_type seqtype = SEQ_TYPE_STANDARD) const { return m_seq[seqtype]; }
- void restore_default_seq();
+ ioport_type type() const noexcept { return m_type; }
+ ioport_group group() const noexcept { return m_group; }
+ u8 player() const noexcept { return m_player; }
+ const char *token() const noexcept { return m_token; }
+ std::string name() const;
+ input_seq &defseq(input_seq_type seqtype = SEQ_TYPE_STANDARD) noexcept { return m_defseq[seqtype]; }
+ const input_seq &defseq(input_seq_type seqtype = SEQ_TYPE_STANDARD) const noexcept { return m_defseq[seqtype]; }
+ const input_seq &seq(input_seq_type seqtype = SEQ_TYPE_STANDARD) const noexcept { return m_seq[seqtype]; }
+ const std::string &cfg(input_seq_type seqtype = SEQ_TYPE_STANDARD) const noexcept { return m_cfg[seqtype]; }
// setters
- void configure_osd(const char *token, const char *name);
+ void restore_default_seq() noexcept;
+ void set_seq(input_seq_type seqtype, const input_seq &seq) noexcept { m_seq[seqtype] = seq; }
+ template <typename... T> void set_cfg(input_seq_type seqtype, T &&... cfg) { m_cfg[seqtype].assign(std::forward<T>(cfg)...); }
+ void replace_code(input_code oldcode, input_code newcode) noexcept;
+ void configure_osd(const char *token, const char *name) noexcept;
private:
// internal state
- input_type_entry * m_next; // next description in the list
- ioport_type m_type; // IPT_* for this entry
- ioport_group m_group; // which group the port belongs to
- u8 m_player; // player number (0 is player 1)
- const char * m_token; // token used to store settings
- const char * m_name; // user-friendly name
- input_seq m_defseq[SEQ_TYPE_TOTAL];// default input sequence
- input_seq m_seq[SEQ_TYPE_TOTAL];// currently configured sequences
+ ioport_type m_type; // IPT_* for this entry
+ ioport_group m_group; // which group the port belongs to
+ u8 m_player; // player number (0 is player 1)
+ const char * m_token; // token used to store settings
+ const char * m_name; // user-friendly name
+ std::array<input_seq, SEQ_TYPE_TOTAL> m_defseq; // default input sequence
+ std::array<input_seq, SEQ_TYPE_TOTAL> m_seq; // currently configured sequences
+ std::array<std::string, SEQ_TYPE_TOTAL> m_cfg; // configuration strings
};
@@ -825,7 +395,6 @@ private:
class digital_joystick
{
DISABLE_COPYING(digital_joystick);
- friend class simple_list<digital_joystick>;
public:
// directions
@@ -848,11 +417,10 @@ public:
digital_joystick(int player, int number);
// getters
- digital_joystick *next() const { return m_next; }
- int player() const { return m_player; }
- int number() const { return m_number; }
- u8 current() const { return m_current; }
- u8 current4way() const { return m_current4way; }
+ int player() const noexcept { return m_player; }
+ int number() const noexcept { return m_number; }
+ u8 current() const noexcept { return m_current; }
+ u8 current4way() const noexcept { return m_current4way; }
// configuration
direction_t add_axis(ioport_field &field);
@@ -862,10 +430,9 @@ 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
- simple_list<simple_list_wrapper<ioport_field> > m_field[JOYDIR_COUNT]; // potential input fields for each direction
+ std::forward_list<std::reference_wrapper<ioport_field> > m_field[JOYDIR_COUNT]; // potential input fields for each direction
u8 m_current; // current value
u8 m_current4way; // current 4-way value
u8 m_previous; // previous value
@@ -907,11 +474,12 @@ public:
bool none() const { return (m_condition == ALWAYS); }
// configuration
- void reset() { set(ALWAYS, nullptr, 0, 0); }
+ void reset() { set(ALWAYS, "", 0, 0); }
void set(condition_t condition, const char *tag, ioport_value mask, ioport_value value)
{
m_condition = condition;
m_tag = tag;
+ m_port = nullptr;
m_mask = mask;
m_value = value;
}
@@ -921,7 +489,7 @@ public:
private:
// internal state
condition_t m_condition; // condition to use
- const char * m_tag; // tag of port whose condition is to be tested
+ const char * m_tag; // tag of port whose condition is to be tested (must never be nullptr)
ioport_port * m_port; // reference to the port to be tested
ioport_value m_mask; // mask to apply to the port
ioport_value m_value; // value to compare against
@@ -933,15 +501,11 @@ private:
// a single setting for a configuration or DIP switch
class ioport_setting
{
- DISABLE_COPYING(ioport_setting);
- friend class simple_list<ioport_setting>;
-
public:
// construction/destruction
ioport_setting(ioport_field &field, ioport_value value, const char *name);
// getters
- ioport_setting *next() const { return m_next; }
ioport_field &field() const { return m_field; }
device_t &device() const;
running_machine &machine() const;
@@ -951,15 +515,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 +531,19 @@ private:
// a mapping from a bit to a physical DIP switch description
class ioport_diplocation
{
- DISABLE_COPYING(ioport_diplocation);
- friend class simple_list<ioport_diplocation>;
-
public:
// construction/destruction
- ioport_diplocation(const char *name, u8 swnum, bool invert);
+ ioport_diplocation(std::string_view 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 +554,19 @@ class ioport_field
{
DISABLE_COPYING(ioport_field);
friend class simple_list<ioport_field>;
+ friend class ioport_manager;
friend class ioport_configurer;
friend class dynamic_field;
// flags for ioport_fields
- static const int FIELD_FLAG_OPTIONAL = 0x0001; // set if this field is not required but recognized by hw
- static const int FIELD_FLAG_COCKTAIL = 0x0002; // set if this field is relevant only for cocktail cabinets
- static const int FIELD_FLAG_TOGGLE = 0x0004; // set if this field should behave as a toggle
- static const int FIELD_FLAG_ROTATED = 0x0008; // set if this field represents a rotated control
- static const int ANALOG_FLAG_REVERSE = 0x0010; // analog only: reverse the sense of the axis
- static const int ANALOG_FLAG_RESET = 0x0020; // analog only: always preload in->default for relative axes, returning only deltas
- static const int ANALOG_FLAG_WRAPS = 0x0040; // analog only: positional count wraps around
- static const int ANALOG_FLAG_INVERT = 0x0080; // analog only: bitwise invert bits
+ static inline constexpr u32 FIELD_FLAG_OPTIONAL = 0x0001; // set if this field is not required but recognized by hw
+ static inline constexpr u32 FIELD_FLAG_COCKTAIL = 0x0002; // set if this field is relevant only for cocktail cabinets
+ static inline constexpr u32 FIELD_FLAG_TOGGLE = 0x0004; // set if this field should behave as a toggle
+ static inline constexpr u32 FIELD_FLAG_ROTATED = 0x0008; // set if this field represents a rotated control
+ static inline constexpr u32 ANALOG_FLAG_REVERSE = 0x0010; // analog only: reverse the sense of the axis
+ static inline constexpr u32 ANALOG_FLAG_RESET = 0x0020; // analog only: always preload in->default for relative axes, returning only deltas
+ static inline constexpr u32 ANALOG_FLAG_WRAPS = 0x0040; // analog only: positional count wraps around
+ static inline constexpr u32 ANALOG_FLAG_INVERT = 0x0080; // analog only: bitwise invert bits
public:
// construction/destruction
@@ -1021,8 +580,8 @@ public:
ioport_manager &manager() const;
running_machine &machine() const;
int modcount() const { return m_modcount; }
- const simple_list<ioport_setting> &settings() const { return m_settinglist; }
- const simple_list<ioport_diplocation> &diplocations() const { return m_diploclist; }
+ const std::vector<ioport_setting> &settings() const { return m_settinglist; }
+ const std::vector<ioport_diplocation> &diplocations() const { return m_diploclist; }
ioport_value mask() const { return m_mask; }
ioport_value defvalue() const { return m_defvalue; }
@@ -1032,6 +591,7 @@ public:
u8 player() const { return m_player; }
bool digital_value() const { return m_digital_value; }
void set_value(ioport_value value);
+ void clear_value();
bool optional() const { return ((m_flags & FIELD_FLAG_OPTIONAL) != 0); }
bool cocktail() const { return ((m_flags & FIELD_FLAG_COCKTAIL) != 0); }
@@ -1042,42 +602,43 @@ public:
bool analog_wraps() const { return ((m_flags & ANALOG_FLAG_WRAPS) != 0); }
bool analog_invert() const { return ((m_flags & ANALOG_FLAG_INVERT) != 0); }
- u8 impulse() const { return m_impulse; }
- const char *name() const;
- const char *specific_name() const { return m_name; }
- const input_seq &seq(input_seq_type seqtype = SEQ_TYPE_STANDARD) const;
- const input_seq &defseq(input_seq_type seqtype = SEQ_TYPE_STANDARD) const;
- const input_seq &defseq_unresolved(input_seq_type seqtype = SEQ_TYPE_STANDARD) const { return m_seq[seqtype]; }
- void set_defseq(const input_seq &newseq) { set_defseq(SEQ_TYPE_STANDARD, newseq); }
+ u8 impulse() const noexcept { return m_impulse; }
+ std::string name() const;
+ const char *specific_name() const noexcept { return m_name; }
+ const input_seq &seq(input_seq_type seqtype = SEQ_TYPE_STANDARD) const noexcept;
+ const input_seq &defseq(input_seq_type seqtype = SEQ_TYPE_STANDARD) const noexcept;
+ const input_seq &defseq_unresolved(input_seq_type seqtype = SEQ_TYPE_STANDARD) const noexcept { return m_seq[seqtype]; }
+ void set_defseq(const input_seq &newseq) noexcept { set_defseq(SEQ_TYPE_STANDARD, newseq); }
void set_defseq(input_seq_type seqtype, const input_seq &newseq);
bool has_dynamic_read() const { return !m_read.isnull(); }
bool has_dynamic_write() const { return !m_write.isnull(); }
- ioport_value minval() const { return m_min; }
- ioport_value maxval() const { return m_max; }
- s32 sensitivity() const { return m_sensitivity; }
- s32 delta() const { return m_delta; }
- s32 centerdelta() const { return m_centerdelta; }
- crosshair_axis_t crosshair_axis() const { return m_crosshair_axis; }
- double crosshair_scale() const { return m_crosshair_scale; }
- double crosshair_offset() const { return m_crosshair_offset; }
- u16 full_turn_count() const { return m_full_turn_count; }
- const ioport_value *remap_table() const { return m_remap_table; }
-
- u8 way() const { return m_way; }
+ ioport_value minval() const noexcept { return m_min; }
+ ioport_value maxval() const noexcept { return m_max; }
+ s32 sensitivity() const noexcept { return m_sensitivity; }
+ s32 delta() const noexcept { return m_delta; }
+ s32 centerdelta() const noexcept { return m_centerdelta; }
+ crosshair_axis_t crosshair_axis() const noexcept { return m_crosshair_axis; }
+ float crosshair_scale() const noexcept { return m_crosshair_scale; }
+ float crosshair_offset() const noexcept { return m_crosshair_offset; }
+ float crosshair_altaxis() const noexcept { return m_crosshair_altaxis; }
+ u16 full_turn_count() const noexcept { return m_full_turn_count; }
+ const ioport_value *remap_table() const noexcept { return m_remap_table; }
+
+ u8 way() const noexcept { return m_way; }
std::vector<char32_t> keyboard_codes(int which) const;
std::string key_name(int which) const;
ioport_field_live &live() const { assert(m_live != nullptr); return *m_live; }
// setters
- void set_crosshair_scale(double scale) { m_crosshair_scale = scale; }
- void set_crosshair_offset(double offset) { m_crosshair_offset = offset; }
+ void set_crosshair_scale(float scale) { m_crosshair_scale = scale; }
+ void set_crosshair_offset(float offset) { m_crosshair_offset = offset; }
void set_player(u8 player) { m_player = player; }
// derived getters
- ioport_type_class type_class() const;
- bool is_analog() const { return (m_type > IPT_ANALOG_FIRST && m_type < IPT_ANALOG_LAST); }
- bool is_digital_joystick() const { return (m_type > IPT_DIGITAL_JOYSTICK_FIRST && m_type < IPT_DIGITAL_JOYSTICK_LAST); }
+ ioport_type_class type_class() const noexcept;
+ bool is_analog() const noexcept { return (m_type > IPT_ANALOG_FIRST && m_type < IPT_ANALOG_LAST); }
+ bool is_digital_joystick() const noexcept { return (m_type > IPT_DIGITAL_JOYSTICK_FIRST && m_type < IPT_DIGITAL_JOYSTICK_LAST); }
// additional operations
bool enabled() const { return m_condition.eval(); }
@@ -1086,7 +647,7 @@ public:
void select_previous_setting();
bool has_next_setting() const;
void select_next_setting();
- void crosshair_position(float &x, float &y, bool &gotx, bool &goty);
+ 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; }
@@ -1094,28 +655,28 @@ public:
// user-controllable settings for a field
struct user_settings
{
- ioport_value value; // for DIP switches
- bool autofire; // for autofire settings
+ ioport_value value = 0; // for DIP switches
input_seq seq[SEQ_TYPE_TOTAL]; // sequences of all types
- s32 sensitivity; // for analog controls
- s32 delta; // for analog controls
- s32 centerdelta; // for analog controls
- bool reverse; // for analog controls
- bool toggle; // for non-analog controls
+ std::string cfg[SEQ_TYPE_TOTAL]; // configuration strings of all types
+ s32 sensitivity = 0; // for analog controls
+ s32 delta = 0; // for analog controls
+ s32 centerdelta = 0; // for analog controls
+ bool reverse = false; // for analog controls
+ bool toggle = false; // for non-analog controls
};
- void get_user_settings(user_settings &settings);
+ void get_user_settings(user_settings &settings) const;
void set_user_settings(const user_settings &settings);
private:
- void expand_diplocation(const char *location, std::string &errorbuf);
+ void expand_diplocation(const char *location, std::ostream &errorbuf);
// internal state
ioport_field * m_next; // pointer to next field in sequence
ioport_port & m_port; // reference to the port that owns us
- std::unique_ptr<ioport_field_live> m_live; // live state of field (nullptr if not live)
+ std::unique_ptr<ioport_field_live> m_live; // live state of field (nullptr if not live)
int m_modcount; // modification count
- simple_list<ioport_setting> m_settinglist; // list of input_setting_configs
- simple_list<ioport_diplocation> m_diploclist; // list of locations for various bits
+ std::vector<ioport_setting> m_settinglist; // list of input_setting_configs
+ std::vector<ioport_diplocation> m_diploclist; // list of locations for various bits
// generally-applicable data
ioport_value m_mask; // mask of bits belonging to the field
@@ -1141,9 +702,9 @@ private:
s32 m_delta; // delta to apply each frame a digital inc/dec key is pressed
s32 m_centerdelta; // delta to apply each frame no digital inputs are pressed
crosshair_axis_t m_crosshair_axis; // crosshair axis
- double m_crosshair_scale; // crosshair scale
- double m_crosshair_offset; // crosshair offset
- double m_crosshair_altaxis;// crosshair alternate axis value
+ float m_crosshair_scale; // crosshair scale
+ float m_crosshair_offset; // crosshair offset
+ float m_crosshair_altaxis;// crosshair alternate axis value
ioport_field_crossmap_delegate m_crosshair_mapper; // crosshair mapping function
u16 m_full_turn_count; // number of optical counts for 1 full turn of the original control
const ioport_value * m_remap_table; // pointer to an array that remaps the port value
@@ -1171,10 +732,9 @@ struct ioport_field_live
bool last; // were we pressed last time?
bool toggle; // current toggle setting
digital_joystick::direction_t joydir; // digital joystick direction index
- bool autofire; // autofire
- int autopressed; // autofire status
bool lockout; // user lockout
std::string name; // overridden name
+ std::string cfg[SEQ_TYPE_TOTAL];// configuration strings
};
@@ -1188,7 +748,7 @@ class ioport_list : public std::map<std::string, std::unique_ptr<ioport_port>>
public:
ioport_list() { }
- void append(device_t &device, std::string &errorbuf);
+ void append(device_t &device, std::ostream &errorbuf);
};
@@ -1223,13 +783,13 @@ public:
// other operations
ioport_field *field(ioport_value mask) const;
- void collapse_fields(std::string &errorbuf);
+ void collapse_fields(std::ostream &errorbuf);
void frame_update();
void init_live_state();
void update_defvalue(bool flush_defaults);
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
ioport_port * m_next; // pointer to next port
@@ -1248,7 +808,6 @@ private:
// live analog field information
class analog_field
{
- friend class simple_list<analog_field>;
friend class ioport_manager;
friend void ioport_field::set_user_settings(const ioport_field::user_settings &settings);
@@ -1257,19 +816,22 @@ public:
analog_field(ioport_field &field);
// getters
- analog_field *next() const { return m_next; }
- ioport_manager &manager() const { return m_field.manager(); }
- ioport_field &field() const { return m_field; }
- s32 sensitivity() const { return m_sensitivity; }
- bool reverse() const { return m_reverse; }
- s32 delta() const { return m_delta; }
- s32 centerdelta() const { return m_centerdelta; }
+ ioport_manager &manager() const noexcept { return m_field.manager(); }
+ ioport_field &field() const noexcept { return m_field; }
+ s32 sensitivity() const noexcept { return m_sensitivity; }
+ bool reverse() const noexcept { return m_reverse; }
+ s32 delta() const noexcept { return m_delta; }
+ s32 centerdelta() const noexcept { return m_centerdelta; }
// readers
void read(ioport_value &value);
float crosshair_read();
void frame_update(running_machine &machine);
+ // programmatic override (for script bindings)
+ void set_value(s32 value);
+ void clear_value();
+
private:
// helpers
s32 apply_min_max(s32 value) const;
@@ -1278,14 +840,14 @@ 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)
- u8 m_shift; // shift to align final value in the port
- s32 m_adjdefvalue; // adjusted default value from the config
+ u8 const m_shift; // shift to align final value in the port
+ s32 const m_adjdefvalue; // adjusted default value from the config
s32 m_adjmin; // adjusted minimum value from the config
s32 m_adjmax; // adjusted maximum value from the config
+ s32 m_adjoverride; // programmatically set adjusted value
// live values of configurable parameters
s32 m_sensitivity; // current live sensitivity (100=normal)
@@ -1318,6 +880,7 @@ private:
bool m_single_scale; // scale joystick differently if default is between min/max
bool m_interpolate; // should we do linear interpolation for mid-frame reads?
bool m_lastdigital; // was the last modification caused by a digital form?
+ bool m_use_adjoverride; // override what will be read from the field
};
@@ -1326,14 +889,11 @@ private:
// live device field information
class dynamic_field
{
- friend class simple_list<dynamic_field>;
-
public:
// construction/destruction
dynamic_field(ioport_field &field);
// getters
- dynamic_field *next() const { return m_next; }
ioport_field &field() const { return m_field; }
// read/write
@@ -1342,7 +902,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
@@ -1358,9 +917,9 @@ struct ioport_port_live
ioport_port_live(ioport_port &port);
// public state
- simple_list<analog_field> analoglist; // list of analog port info
- simple_list<dynamic_field> readlist; // list of dynamic read fields
- simple_list<dynamic_field> writelist; // list of dynamic write fields
+ std::list<analog_field> analoglist; // list of analog port info
+ std::vector<dynamic_field> readlist; // list of dynamic read fields
+ std::vector<dynamic_field> writelist; // list of dynamic write fields
ioport_value defvalue; // combined default value across the port
ioport_value digital; // current value from all digital inputs
ioport_value outputvalue; // current value for outputs
@@ -1383,104 +942,91 @@ public:
~ioport_manager();
// getters
- running_machine &machine() const { return m_machine; }
- const ioport_list &ports() const { return m_portlist; }
- bool safe_to_read() const { return m_safe_to_read; }
- natural_keyboard &natkeyboard() { assert(m_natkeyboard != nullptr); return *m_natkeyboard; }
+ running_machine &machine() const noexcept { return m_machine; }
+ const ioport_list &ports() const noexcept { return m_portlist; }
+ bool safe_to_read() const noexcept { return m_safe_to_read; }
// type helpers
- const simple_list<input_type_entry> &types() const { return m_typelist; }
+ const std::vector<input_type_entry> &types() const noexcept { return m_typelist; }
bool type_pressed(ioport_type type, int player = 0);
- const char *type_name(ioport_type type, u8 player);
- ioport_group type_group(ioport_type type, int player);
- const input_seq &type_seq(ioport_type type, int player = 0, input_seq_type seqtype = SEQ_TYPE_STANDARD);
- void set_type_seq(ioport_type type, int player, input_seq_type seqtype, const input_seq &newseq);
- static bool type_is_analog(ioport_type type) { return (type > IPT_ANALOG_FIRST && type < IPT_ANALOG_LAST); }
- bool type_class_present(ioport_type_class inputclass);
+ std::string type_name(ioport_type type, u8 player) const;
+ ioport_group type_group(ioport_type type, int player) const noexcept;
+ const input_seq &type_seq(ioport_type type, int player = 0, input_seq_type seqtype = SEQ_TYPE_STANDARD) const noexcept;
+ void set_type_seq(ioport_type type, int player, input_seq_type seqtype, const input_seq &newseq) noexcept;
+ static constexpr bool type_is_analog(ioport_type type) noexcept { return (type > IPT_ANALOG_FIRST && type < IPT_ANALOG_LAST); }
+ bool type_class_present(ioport_type_class inputclass) const noexcept;
// other helpers
digital_joystick &digjoystick(int player, int joysticknum);
- int count_players() const;
- bool crosshair_position(int player, float &x, float &y);
+ int count_players() const noexcept;
s32 frame_interpolate(s32 oldval, s32 newval);
ioport_type token_to_input_type(const char *string, int &player) const;
std::string input_type_to_token(ioport_type type, int player);
- // autofire
- bool get_autofire_toggle() { return m_autofire_toggle; }
- void set_autofire_toggle(bool toggle) { m_autofire_toggle = toggle; }
- int get_autofire_delay() { return m_autofire_delay; }
- void set_autofire_delay(int delay) { m_autofire_delay = delay; }
-
private:
// internal helpers
void init_port_types();
- void init_autoselect_devices(int type1, int type2, int type3, const char *option, const char *ananame);
+ void init_autoselect_devices(std::initializer_list<ioport_type> types, std::string_view option, std::string_view ananame);
void frame_update_callback();
void frame_update();
- ioport_port *port(const char *tag) const { if (tag) { auto search = m_portlist.find(tag); if (search != m_portlist.end()) return search->second.get(); else return nullptr; } else return nullptr; }
+ ioport_port *port(const std::string &tag) const { auto search = m_portlist.find(tag); if (search != m_portlist.end()) return search->second.get(); else return nullptr; }
void exit();
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);
- bool 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 std::pair<input_seq, char const *> (&newseq)[SEQ_TYPE_TOTAL]);
+ bool load_controller_config(util::xml::data_node const &portnode, int type, int player, const std::pair<input_seq, char const *> (&newseq)[SEQ_TYPE_TOTAL]);
+ void load_system_config(util::xml::data_node const &portnode, int type, int player, const std::pair<input_seq, char const *> (&newseq)[SEQ_TYPE_TOTAL]);
+ void apply_device_defaults();
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);
bool save_this_input_field_type(ioport_type type);
void save_default_inputs(util::xml::data_node &parentnode);
void save_game_inputs(util::xml::data_node &parentnode);
- template<typename _Type> _Type playback_read(_Type &result);
+ template<typename Type> Type playback_read(Type &result);
time_t playback_init();
void playback_end(const char *message = nullptr);
void playback_frame(const attotime &curtime);
void playback_port(ioport_port &port);
- template<typename _Type> void record_write(_Type value);
+ template<typename Type> void record_write(Type value);
void record_init();
void record_end(const char *message = nullptr);
void record_frame(const attotime &curtime);
void record_port(ioport_port &port);
- template<typename _Type> void timecode_write(_Type value);
- void timecode_init();
- void timecode_end(const char *message = nullptr);
-
// internal state
running_machine & m_machine; // reference to owning machine
bool m_safe_to_read; // clear at start; set after state is loaded
ioport_list m_portlist; // list of input port configurations
// types
- simple_list<input_type_entry> m_typelist; // list of live type states
+ std::vector<input_type_entry> m_typelist; // list of live type states
input_type_entry * m_type_to_entry[IPT_COUNT][MAX_PLAYERS]; // map from type/player to type state
// specific special global input states
- simple_list<digital_joystick> m_joystick_list; // list of digital joysticks
- std::unique_ptr<natural_keyboard> m_natkeyboard; // natural keyboard support
+ std::list<digital_joystick> m_joystick_list; // list of digital joysticks
// frame time tracking
attotime m_last_frame_time; // time of the last frame callback
attoseconds_t m_last_delta_nsec; // nanoseconds that passed since the previous callback
// playback/record information
- emu_file m_record_file; // recording file (nullptr if not recording)
- emu_file m_playback_file; // playback file (nullptr if not recording)
+ std::unique_ptr<emu_file> m_record_file; // recording file (nullptr if not recording)
+ std::unique_ptr<emu_file> m_playback_file; // playback file (nullptr if not recording)
+ util::write_stream::ptr m_record_stream; // recording stream (nullptr if not recording)
+ util::read_stream::ptr m_playback_stream; // playback stream (nullptr if not recording)
u64 m_playback_accumulated_speed; // accumulated speed during playback
u32 m_playback_accumulated_frames; // accumulated frames during playback
- emu_file m_timecode_file; // timecode/frames playback file (nullptr if not recording)
- int m_timecode_count;
- attotime m_timecode_last_time;
- // autofire
- bool m_autofire_toggle; // autofire toggle
- int m_autofire_delay; // autofire delay
+ // storage for inactive configuration
+ std::unique_ptr<util::xml::file> m_deselected_card_config;
+ bool m_applied_device_defaults;
};
@@ -1491,7 +1037,7 @@ class ioport_configurer
{
public:
// 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 const char *string_from_token(const char *string);
@@ -1512,6 +1058,7 @@ public:
ioport_configurer& field_set_toggle() { m_curfield->m_flags |= ioport_field::FIELD_FLAG_TOGGLE; return *this; }
ioport_configurer& field_set_impulse(u8 impulse) { m_curfield->m_impulse = impulse; return *this; }
ioport_configurer& field_set_analog_reverse() { m_curfield->m_flags |= ioport_field::ANALOG_FLAG_REVERSE; return *this; }
+ [[deprecated("PORT_RESET is deprecated; manage counter state explicitly")]]
ioport_configurer& field_set_analog_reset() { m_curfield->m_flags |= ioport_field::ANALOG_FLAG_RESET; return *this; }
ioport_configurer& field_set_optional() { m_curfield->m_flags |= ioport_field::FIELD_FLAG_OPTIONAL; return *this; }
ioport_configurer& field_set_min_max(ioport_value minval, ioport_value maxval) { m_curfield->m_min = minval; m_curfield->m_max = maxval; return *this; }
@@ -1527,6 +1074,7 @@ public:
ioport_configurer& field_set_dynamic_read(ioport_field_read_delegate delegate) { m_curfield->m_read = delegate; return *this; }
ioport_configurer& field_set_dynamic_write(ioport_field_write_delegate delegate, u32 param = 0) { m_curfield->m_write = delegate; m_curfield->m_write_param = param; return *this; }
ioport_configurer& field_set_diplocation(const char *location) { m_curfield->expand_diplocation(location, m_errorbuf); return *this; }
+ ioport_configurer& field_set_gm_note(u8 note);
// setting helpers
ioport_configurer& setting_alloc(ioport_value value, const char *name);
@@ -1539,11 +1087,12 @@ private:
// internal state
device_t & m_owner;
ioport_list & m_portlist;
- std::string & m_errorbuf;
+ std::ostream & m_errorbuf;
ioport_port * m_curport;
ioport_field * m_curfield;
ioport_setting * m_cursetting;
+ int m_curshift;
};
@@ -1554,10 +1103,6 @@ private:
#define UCHAR_MAMEKEY(code) (UCHAR_MAMEKEY_BEGIN + ITEM_ID_##code)
-// macro for a read callback function (PORT_CUSTOM)
-#define CUSTOM_INPUT_MEMBER(name) ioport_value name()
-#define DECLARE_CUSTOM_INPUT_MEMBER(name) ioport_value name()
-
// macro for port write callback functions (PORT_CHANGED)
#define INPUT_CHANGED_MEMBER(name) void name(ioport_field &field, u32 param, ioport_value oldval, ioport_value newval)
#define DECLARE_INPUT_CHANGED_MEMBER(name) void name(ioport_field &field, u32 param, ioport_value oldval, ioport_value newval)
@@ -1583,7 +1128,7 @@ private:
// start of table
#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);
// end of table
@@ -1592,7 +1137,7 @@ ATTR_COLD void INPUT_PORTS_NAME(_name)(device_t &owner, ioport_list &portlist, s
// aliasing
#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
#define PORT_INCLUDE(_name) \
@@ -1662,6 +1207,9 @@ ATTR_COLD void INPUT_PORTS_NAME(_name)(device_t &owner, ioport_list &portlist, s
#define PORT_OPTIONAL \
configurer.field_set_optional();
+#define PORT_GM_NOTE(_id) \
+ configurer.field_set_gm_note(_id);
+
// analog settings
// if this macro is not used, the minimum defaults to 0 and maximum defaults to the mask value
#define PORT_MINMAX(_min, _max) \
@@ -1679,11 +1227,10 @@ ATTR_COLD void INPUT_PORTS_NAME(_name)(device_t &owner, ioport_list &portlist, s
#define PORT_CROSSHAIR(axis, scale, offset, altaxis) \
configurer.field_set_crosshair(CROSSHAIR_AXIS_##axis, altaxis, scale, offset);
-#define PORT_CROSSHAIR_MAPPER(_callback) \
- configurer.field_set_crossmapper(ioport_field_crossmap_delegate(_callback, #_callback, DEVICE_SELF, (device_t *)nullptr));
-
-#define PORT_CROSSHAIR_MAPPER_MEMBER(_device, _class, _member) \
- configurer.field_set_crossmapper(ioport_field_crossmap_delegate(&_class::_member, #_class "::" #_member, _device, (_class *)nullptr));
+#define PORT_CROSSHAIR_MAPPER_MEMBER_IMPL(_device, _funcptr, _name) \
+ configurer.field_set_crossmapper(ioport_field_crossmap_delegate(owner, _device, _funcptr, _name));
+#define PORT_CROSSHAIR_MAPPER_DEVICE_MEMBER(...) PORT_CROSSHAIR_MAPPER_MEMBER_IMPL(__VA_ARGS__)
+#define PORT_CROSSHAIR_MAPPER_MEMBER(...) PORT_CROSSHAIR_MAPPER_MEMBER_IMPL(DEVICE_SELF, __VA_ARGS__)
// how many optical counts for 1 full turn of the control
#define PORT_FULL_TURN_COUNT(_count) \
@@ -1709,28 +1256,41 @@ ATTR_COLD void INPUT_PORTS_NAME(_name)(device_t &owner, ioport_list &portlist, s
configurer.field_set_analog_invert();
// read callbacks
-#define PORT_CUSTOM_MEMBER(_class, _member) \
- configurer.field_set_dynamic_read(ioport_field_read_delegate(&_class::_member, #_class "::" #_member, DEVICE_SELF, (_class *)nullptr));
-#define PORT_CUSTOM_DEVICE_MEMBER(_device, _class, _member) \
- configurer.field_set_dynamic_read(ioport_field_read_delegate(&_class::_member, #_class "::" #_member, _device, (_class *)nullptr));
+#define PORT_CUSTOM_MEMBER_IMPL(_device, _funcptr, _name) \
+ configurer.field_set_dynamic_read(ioport_field_read_delegate(owner, _device, _funcptr, _name));
+#define PORT_CUSTOM_DEVICE_MEMBER(...) PORT_CUSTOM_MEMBER_IMPL(__VA_ARGS__)
+#define PORT_CUSTOM_MEMBER(...) PORT_CUSTOM_MEMBER_IMPL(DEVICE_SELF, __VA_ARGS__);
// write callbacks
-#define PORT_CHANGED_MEMBER(_device, _class, _member, _param) \
- configurer.field_set_dynamic_write(ioport_field_write_delegate(&_class::_member, #_class "::" #_member, _device, (_class *)nullptr), (_param));
+#define PORT_CHANGED_MEMBER_IMPL(_device, _funcptr, _name, _param) \
+ configurer.field_set_dynamic_write(ioport_field_write_delegate(owner, _device, _funcptr, _name), (_param));
+#define PORT_CHANGED_MEMBER(...) PORT_CHANGED_MEMBER_IMPL(__VA_ARGS__)
// input device handler
-#define PORT_READ_LINE_MEMBER(_class, _member) \
- configurer.field_set_dynamic_read(ioport_field_read_delegate([](_class &device)->ioport_value { return (device._member() & 1) ? ~ioport_value(0) : 0; } , #_class "::" #_member, DEVICE_SELF, (_class *)nullptr));
-#define PORT_READ_LINE_DEVICE_MEMBER(_device, _class, _member) \
- configurer.field_set_dynamic_read(ioport_field_read_delegate([](_class &device)->ioport_value { return (device._member() & 1) ? ~ioport_value(0) : 0; } , #_class "::" #_member, _device, (_class *)nullptr));
+#define PORT_READ_LINE_MEMBER_IMPL(_device, _funcptr, _name) \
+ configurer.field_set_dynamic_read( \
+ ioport_field_read_delegate( \
+ owner, \
+ _device, \
+ static_cast<ioport_value (*)(emu::detail::rw_delegate_device_class_t<decltype(_funcptr)> &)>( \
+ [] (auto &device) -> ioport_value { return (std::invoke(_funcptr, device) & 1) ? ~ioport_value(0) : 0; }), \
+ _name));
+#define PORT_READ_LINE_DEVICE_MEMBER(...) PORT_READ_LINE_MEMBER_IMPL(__VA_ARGS__)
+#define PORT_READ_LINE_MEMBER(...) PORT_READ_LINE_MEMBER_IMPL(DEVICE_SELF, __VA_ARGS__)
// output device handler
-#define PORT_WRITE_LINE_MEMBER(_class, _member) \
- configurer.field_set_dynamic_write(ioport_field_write_delegate([](_class &device, ioport_field &field, u32 param, ioport_value oldval, ioport_value newval) { device._member(newval); }, #_class "::" #_member, DEVICE_SELF, (_class *)nullptr));
-#define PORT_WRITE_LINE_DEVICE_MEMBER(_device, _class, _member) \
- configurer.field_set_dynamic_write(ioport_field_write_delegate([](_class &device, ioport_field &field, u32 param, ioport_value oldval, ioport_value newval) { device._member(newval); }, #_class "::" #_member, _device, (_class *)nullptr));
-
-// dip switch definition
+#define PORT_WRITE_LINE_MEMBER_IMPL(_device, _funcptr, _name) \
+ configurer.field_set_dynamic_write( \
+ ioport_field_write_delegate( \
+ owner, \
+ _device, \
+ static_cast<void (*)(emu::detail::rw_delegate_device_class_t<decltype(_funcptr)> &, ioport_field &, u32, ioport_value, ioport_value)>( \
+ [] (auto &device, ioport_field &field, u32 param, ioport_value oldval, ioport_value newval) { std::invoke(_funcptr, device, newval); }), \
+ _name));
+#define PORT_WRITE_LINE_DEVICE_MEMBER(...) PORT_WRITE_LINE_MEMBER_IMPL(__VA_ARGS__)
+#define PORT_WRITE_LINE_MEMBER(...) PORT_WRITE_LINE_MEMBER_IMPL(DEVICE_SELF, __VA_ARGS__)
+
+// DIP switch definition
#define PORT_DIPNAME(_mask, _default, _name) \
configurer.field_alloc(IPT_DIPSWITCH, (_default), (_mask), (_name));
#define PORT_DIPSETTING(_default, _name) \
@@ -1739,7 +1299,7 @@ ATTR_COLD void INPUT_PORTS_NAME(_name)(device_t &owner, ioport_list &portlist, s
// note that these are specified LSB-first
#define PORT_DIPLOCATION(_location) \
configurer.field_set_diplocation(_location);
-// conditionals for dip switch settings
+// conditionals for DIP switch settings
#define PORT_CONDITION(_tag, _mask, _condition, _value) \
configurer.set_condition(ioport_condition::_condition, _tag, _mask, _value);
// analog adjuster definition
@@ -1756,6 +1316,103 @@ ATTR_COLD void INPUT_PORTS_NAME(_name)(device_t &owner, ioport_list &portlist, s
#define PORT_CHAR(...) \
configurer.field_add_char({ __VA_ARGS__ });
+// General-midi derived piano notes
+#define PORT_GM_A0 PORT_GM_NOTE( 21) // Start of 88-key keyboard
+#define PORT_GM_AS0 PORT_GM_NOTE( 22)
+#define PORT_GM_B0 PORT_GM_NOTE( 23)
+
+#define PORT_GM_C1 PORT_GM_NOTE( 24)
+#define PORT_GM_CS1 PORT_GM_NOTE( 25)
+#define PORT_GM_D1 PORT_GM_NOTE( 26)
+#define PORT_GM_DS1 PORT_GM_NOTE( 27)
+#define PORT_GM_E1 PORT_GM_NOTE( 28) // Start of 76-key keyboard
+#define PORT_GM_F1 PORT_GM_NOTE( 29)
+#define PORT_GM_FS1 PORT_GM_NOTE( 30)
+#define PORT_GM_G1 PORT_GM_NOTE( 31)
+#define PORT_GM_GS1 PORT_GM_NOTE( 32)
+#define PORT_GM_A1 PORT_GM_NOTE( 33)
+#define PORT_GM_AS1 PORT_GM_NOTE( 34)
+#define PORT_GM_B1 PORT_GM_NOTE( 35)
+
+#define PORT_GM_C2 PORT_GM_NOTE( 36) // Start of 49 and 61-key keyboards
+#define PORT_GM_CS2 PORT_GM_NOTE( 37)
+#define PORT_GM_D2 PORT_GM_NOTE( 38)
+#define PORT_GM_DS2 PORT_GM_NOTE( 39)
+#define PORT_GM_E2 PORT_GM_NOTE( 40)
+#define PORT_GM_F2 PORT_GM_NOTE( 41)
+#define PORT_GM_FS2 PORT_GM_NOTE( 42)
+#define PORT_GM_G2 PORT_GM_NOTE( 43)
+#define PORT_GM_GS2 PORT_GM_NOTE( 44)
+#define PORT_GM_A2 PORT_GM_NOTE( 45)
+#define PORT_GM_AS2 PORT_GM_NOTE( 46)
+#define PORT_GM_B2 PORT_GM_NOTE( 47)
+
+#define PORT_GM_C3 PORT_GM_NOTE( 48)
+#define PORT_GM_CS3 PORT_GM_NOTE( 49)
+#define PORT_GM_D3 PORT_GM_NOTE( 50)
+#define PORT_GM_DS3 PORT_GM_NOTE( 51)
+#define PORT_GM_E3 PORT_GM_NOTE( 52)
+#define PORT_GM_F3 PORT_GM_NOTE( 53)
+#define PORT_GM_FS3 PORT_GM_NOTE( 54)
+#define PORT_GM_G3 PORT_GM_NOTE( 55)
+#define PORT_GM_GS3 PORT_GM_NOTE( 56)
+#define PORT_GM_A3 PORT_GM_NOTE( 57)
+#define PORT_GM_AS3 PORT_GM_NOTE( 58)
+#define PORT_GM_B3 PORT_GM_NOTE( 59)
+
+#define PORT_GM_C4 PORT_GM_NOTE( 60) // Middle C
+#define PORT_GM_CS4 PORT_GM_NOTE( 61)
+#define PORT_GM_D4 PORT_GM_NOTE( 62)
+#define PORT_GM_DS4 PORT_GM_NOTE( 63)
+#define PORT_GM_E4 PORT_GM_NOTE( 64)
+#define PORT_GM_F4 PORT_GM_NOTE( 65)
+#define PORT_GM_FS4 PORT_GM_NOTE( 66)
+#define PORT_GM_G4 PORT_GM_NOTE( 67)
+#define PORT_GM_GS4 PORT_GM_NOTE( 68)
+#define PORT_GM_A4 PORT_GM_NOTE( 69)
+#define PORT_GM_AS4 PORT_GM_NOTE( 70)
+#define PORT_GM_B4 PORT_GM_NOTE( 71)
+
+#define PORT_GM_C5 PORT_GM_NOTE( 72)
+#define PORT_GM_CS5 PORT_GM_NOTE( 73)
+#define PORT_GM_D5 PORT_GM_NOTE( 74)
+#define PORT_GM_DS5 PORT_GM_NOTE( 75)
+#define PORT_GM_E5 PORT_GM_NOTE( 76)
+#define PORT_GM_F5 PORT_GM_NOTE( 77)
+#define PORT_GM_FS5 PORT_GM_NOTE( 78)
+#define PORT_GM_G5 PORT_GM_NOTE( 79)
+#define PORT_GM_GS5 PORT_GM_NOTE( 80)
+#define PORT_GM_A5 PORT_GM_NOTE( 81)
+#define PORT_GM_AS5 PORT_GM_NOTE( 82)
+#define PORT_GM_B5 PORT_GM_NOTE( 83)
+
+#define PORT_GM_C6 PORT_GM_NOTE( 84) // End of 49-key keyboard
+#define PORT_GM_CS6 PORT_GM_NOTE( 85)
+#define PORT_GM_D6 PORT_GM_NOTE( 86)
+#define PORT_GM_DS6 PORT_GM_NOTE( 87)
+#define PORT_GM_E6 PORT_GM_NOTE( 88)
+#define PORT_GM_F6 PORT_GM_NOTE( 89)
+#define PORT_GM_FS6 PORT_GM_NOTE( 90)
+#define PORT_GM_G6 PORT_GM_NOTE( 91)
+#define PORT_GM_GS6 PORT_GM_NOTE( 92)
+#define PORT_GM_A6 PORT_GM_NOTE( 93)
+#define PORT_GM_AS6 PORT_GM_NOTE( 94)
+#define PORT_GM_B6 PORT_GM_NOTE( 95)
+
+#define PORT_GM_C7 PORT_GM_NOTE( 96) // End of 61-key keyboard
+#define PORT_GM_CS7 PORT_GM_NOTE( 97)
+#define PORT_GM_D7 PORT_GM_NOTE( 98)
+#define PORT_GM_DS7 PORT_GM_NOTE( 99)
+#define PORT_GM_E7 PORT_GM_NOTE(100)
+#define PORT_GM_F7 PORT_GM_NOTE(101)
+#define PORT_GM_FS7 PORT_GM_NOTE(102)
+#define PORT_GM_G7 PORT_GM_NOTE(103) // End of 76-key keyboard
+#define PORT_GM_GS7 PORT_GM_NOTE(104)
+#define PORT_GM_A7 PORT_GM_NOTE(105)
+#define PORT_GM_AS7 PORT_GM_NOTE(106)
+#define PORT_GM_B7 PORT_GM_NOTE(107)
+
+#define PORT_GM_C8 PORT_GM_NOTE(108) // End of 88-key keyboard
// name of table
#define DEVICE_INPUT_DEFAULTS_NAME(_name) device_iptdef_##_name
@@ -1799,12 +1456,6 @@ ATTR_COLD void INPUT_PORTS_NAME(_name)(device_t &owner, ioport_list &portlist, s
#define PORT_SERVICE_NO_TOGGLE(_mask, _default) \
PORT_BIT( _mask, _mask & _default, IPT_SERVICE ) PORT_NAME( DEF_STR( Service_Mode ))
-#define PORT_VBLANK(_screen) \
- PORT_READ_LINE_DEVICE_MEMBER(_screen, screen_device, vblank)
-
-#define PORT_HBLANK(_screen) \
- PORT_READ_LINE_DEVICE_MEMBER(_screen, screen_device, hblank)
-
//**************************************************************************
// INLINE FUNCTIONS
//**************************************************************************