From 1964365f34499ae5785c7b8f13836caa05156dfa Mon Sep 17 00:00:00 2001 From: Vas Crabb Date: Thu, 16 Jun 2022 03:32:46 +1000 Subject: Optimisation, and baby steps towards untangling stuff: Optimised the scheduler's handling of unscheduled timers - gives a 50% performance improvement in some timer-heavy drivers. Added better endianness swizzling helpers. Got rid of some of the OSD input modules' dependence on concrete input classes from emu. --- scripts/src/osd/modules.lua | 5 + src/emu/emucore.h | 21 - src/emu/input.cpp | 209 +------ src/emu/input.h | 924 +------------------------------ src/emu/inputdev.cpp | 32 +- src/emu/inputdev.h | 24 +- src/emu/ioport.cpp | 28 +- src/emu/schedule.cpp | 169 ++++-- src/emu/schedule.h | 18 +- src/emu/sound.cpp | 15 +- src/frontend/mame/ui/inputdevices.cpp | 4 +- src/lib/util/endianness.h | 40 +- src/mame/drivers/plygonet.cpp | 12 +- src/osd/interface/inputcode.h | 872 +++++++++++++++++++++++++++++ src/osd/interface/inputman.h | 77 +++ src/osd/interface/inputseq.cpp | 210 +++++++ src/osd/interface/inputseq.h | 107 ++++ src/osd/modules/input/input_common.cpp | 45 ++ src/osd/modules/input/input_common.h | 74 +-- src/osd/modules/input/input_dinput.cpp | 6 +- src/osd/modules/input/input_rawinput.cpp | 12 +- src/osd/modules/input/input_sdl.cpp | 8 +- src/osd/modules/input/input_win32.cpp | 4 +- src/osd/osdcomm.h | 22 + 24 files changed, 1608 insertions(+), 1330 deletions(-) create mode 100644 src/osd/interface/inputcode.h create mode 100644 src/osd/interface/inputman.h create mode 100644 src/osd/interface/inputseq.cpp create mode 100644 src/osd/interface/inputseq.h diff --git a/scripts/src/osd/modules.lua b/scripts/src/osd/modules.lua index e431bb93d22..3a44a1c7d05 100644 --- a/scripts/src/osd/modules.lua +++ b/scripts/src/osd/modules.lua @@ -54,6 +54,10 @@ function osdmodulesbuild() MAME_DIR .. "src/osd/osdnet.h", MAME_DIR .. "src/osd/watchdog.cpp", MAME_DIR .. "src/osd/watchdog.h", + MAME_DIR .. "src/osd/interface/inputcode.h", + MAME_DIR .. "src/osd/interface/inputman.h", + MAME_DIR .. "src/osd/interface/inputseq.cpp", + MAME_DIR .. "src/osd/interface/inputseq.h", MAME_DIR .. "src/osd/modules/debugger/debug_module.h", MAME_DIR .. "src/osd/modules/font/font_module.h", MAME_DIR .. "src/osd/modules/midi/midi_module.h", @@ -119,6 +123,7 @@ function osdmodulesbuild() MAME_DIR .. "src/osd/modules/monitor/monitor_mac.cpp", } includedirs { + MAME_DIR .. "src/osd", ext_includedir("asio"), } diff --git a/src/emu/emucore.h b/src/emu/emucore.h index 8074fb0fe73..8e96e4b3778 100644 --- a/src/emu/emucore.h +++ b/src/emu/emucore.h @@ -242,27 +242,6 @@ constexpr int ROT270 = ORIENTATION_SWAP_XY | ORIENTATION_FLIP_Y; // COMMON MACROS //************************************************************************** -// macro for defining a copy constructor and assignment operator to prevent copying -#define DISABLE_COPYING(TYPE) \ - TYPE(const TYPE &) = delete; \ - TYPE &operator=(const TYPE &) = delete - -// macro for declaring enumeration operators that increment/decrement like plain old C -#define DECLARE_ENUM_INCDEC_OPERATORS(TYPE) \ -inline TYPE &operator++(TYPE &value) { return value = TYPE(std::underlying_type_t(value) + 1); } \ -inline TYPE &operator--(TYPE &value) { return value = TYPE(std::underlying_type_t(value) - 1); } \ -inline TYPE operator++(TYPE &value, int) { TYPE const old(value); ++value; return old; } \ -inline TYPE operator--(TYPE &value, int) { TYPE const old(value); --value; return old; } - -// macro for declaring bitwise operators for an enumerated type -#define DECLARE_ENUM_BITWISE_OPERATORS(TYPE) \ -constexpr TYPE operator~(TYPE value) { return TYPE(~std::underlying_type_t(value)); } \ -constexpr TYPE operator&(TYPE a, TYPE b) { return TYPE(std::underlying_type_t(a) & std::underlying_type_t(b)); } \ -constexpr TYPE operator|(TYPE a, TYPE b) { return TYPE(std::underlying_type_t(a) | std::underlying_type_t(b)); } \ -inline TYPE &operator&=(TYPE &a, TYPE b) { return a = a & b; } \ -inline TYPE &operator|=(TYPE &a, TYPE b) { return a = a | b; } - - // this macro passes an item followed by a string version of itself as two consecutive parameters #define NAME(x) x, #x diff --git a/src/emu/input.cpp b/src/emu/input.cpp index 169f76aabe3..6368c4ee4a9 100644 --- a/src/emu/input.cpp +++ b/src/emu/input.cpp @@ -24,21 +24,6 @@ -//************************************************************************** -// CONSTANTS -//************************************************************************** - -// additional expanded input codes for sequences -constexpr input_code input_seq::end_code; -constexpr input_code input_seq::default_code; -constexpr input_code input_seq::not_code; -constexpr input_code input_seq::or_code; - -// constant sequences -const input_seq input_seq::empty_seq; - - - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** @@ -369,187 +354,6 @@ static const code_string_table itemid_token_table[] = -//************************************************************************** -// INPUT SEQ -//************************************************************************** - -//------------------------------------------------- -// operator+= - append a code to the end of an -// input sequence -//------------------------------------------------- - -input_seq &input_seq::operator+=(input_code code) noexcept -{ - // if not enough room, return false - const int curlength = length(); - if (curlength < m_code.size()) - { - m_code[curlength] = code; - if ((curlength + 1) < m_code.size()) - m_code[curlength + 1] = end_code; - } - return *this; -} - - -//------------------------------------------------- -// operator|= - append a code to a sequence; if -// the sequence is non-empty, insert an OR -// before the new code -//------------------------------------------------- - -input_seq &input_seq::operator|=(input_code code) noexcept -{ - // overwrite end/default with the new code - if (m_code[0] == default_code) - { - m_code[0] = code; - m_code[1] = end_code; - } - else - { - // otherwise, append an OR token and then the new code - const int curlength = length(); - if ((curlength + 1) < m_code.size()) - { - m_code[curlength] = or_code; - m_code[curlength + 1] = code; - if ((curlength + 2) < m_code.size()) - m_code[curlength + 2] = end_code; - } - } - return *this; -} - - -//------------------------------------------------- -// length - return the length of the sequence -//------------------------------------------------- - -int input_seq::length() const noexcept -{ - // find the end token; error if none found - for (int seqnum = 0; seqnum < m_code.size(); seqnum++) - if (m_code[seqnum] == end_code) - return seqnum; - return m_code.size(); -} - - -//------------------------------------------------- -// is_valid - return true if a given sequence is -// valid -//------------------------------------------------- - -bool input_seq::is_valid() const noexcept -{ - // "default" can only be of length 1 - if (m_code[0] == default_code) - return m_code[1] == end_code; - - // scan the sequence for valid codes - input_item_class lastclass = ITEM_CLASS_INVALID; - input_code lastcode = INPUT_CODE_INVALID; - decltype(m_code) positive_codes; - decltype(m_code) negative_codes; - auto positive_codes_end = positive_codes.begin(); - auto negative_codes_end = negative_codes.begin(); - for (input_code code : m_code) - { - // invalid codes are never permitted - if (code == INPUT_CODE_INVALID) - return false; - - // if we hit an OR or the end, validate the previous chunk - if (code == or_code || code == end_code) - { - // must be at least one positive code - if (positive_codes.begin() == positive_codes_end) - return false; - - // last code must not have been an internal code - if (lastcode.internal()) - return false; - - // if this is the end, we're OK - if (code == end_code) - return true; - - // reset the state for the next chunk - positive_codes_end = positive_codes.begin(); - negative_codes_end = negative_codes.begin(); - lastclass = ITEM_CLASS_INVALID; - } - else if (code == not_code) - { - // if we hit a NOT, make sure we don't have a double - if (lastcode == not_code) - return false; - } - else - { - // track positive codes, and don't allow positive and negative for the same code - if (lastcode != not_code) - { - *positive_codes_end++ = code; - if (std::find(negative_codes.begin(), negative_codes_end, code) != negative_codes_end) - return false; - } - else - { - *negative_codes_end++ = code; - if (std::find(positive_codes.begin(), positive_codes_end, code) != positive_codes_end) - return false; - } - - // non-switch items can't have a NOT - input_item_class itemclass = code.item_class(); - if (itemclass != ITEM_CLASS_SWITCH && lastcode == not_code) - return false; - - // absolute/relative items must all be the same class - if ((lastclass == ITEM_CLASS_ABSOLUTE && itemclass != ITEM_CLASS_ABSOLUTE) || - (lastclass == ITEM_CLASS_RELATIVE && itemclass != ITEM_CLASS_RELATIVE)) - return false; - } - - // remember the last code - lastcode = code; - } - - // if we got here, we were missing an END token; fail - return false; -} - - -//------------------------------------------------- -// backspace - "backspace" over the last entry in -// a sequence -//------------------------------------------------- - -void input_seq::backspace() noexcept -{ - // if we have at least one entry, remove it - const int curlength = length(); - if (curlength > 0) - m_code[curlength - 1] = end_code; -} - - -//------------------------------------------------- -// replace - replace all instances of oldcode -// with newcode in a sequence -//------------------------------------------------- - -void input_seq::replace(input_code oldcode, input_code newcode) noexcept -{ - for (input_code &elem : m_code) - if (elem == oldcode) - elem = newcode; -} - - - //************************************************************************** // INPUT MANAGER //************************************************************************** @@ -588,6 +392,17 @@ input_manager::~input_manager() } +//------------------------------------------------- +// add_device - add a representation of a host +// input device +//------------------------------------------------- + +osd::input_device &input_manager::add_device(input_device_class devclass, std::string_view name, std::string_view id, void *internal) +{ + return device_class(devclass).add_device(name, id, internal); +} + + //------------------------------------------------- // code_value - return the value of a given // input code @@ -1127,7 +942,7 @@ s32 input_manager::seq_axis_value(const input_seq &seq, input_item_class &itemcl // saturate mixed absolute values if (itemclass == ITEM_CLASS_ABSOLUTE) - result = std::clamp(result, INPUT_ABSOLUTE_MIN, INPUT_ABSOLUTE_MAX); + result = std::clamp(result, osd::INPUT_ABSOLUTE_MIN, osd::INPUT_ABSOLUTE_MAX); // if the caller wants to know the type, provide it if (result == 0) diff --git a/src/emu/input.h b/src/emu/input.h index 7bc03c13831..1b6b1caca93 100644 --- a/src/emu/input.h +++ b/src/emu/input.h @@ -17,6 +17,10 @@ #ifndef MAME_EMU_INPUT_H #define MAME_EMU_INPUT_H +#include "interface/inputcode.h" +#include "interface/inputman.h" +#include "interface/inputseq.h" + #include #include #include @@ -27,468 +31,17 @@ #include -//************************************************************************** -// CONSTANTS -//************************************************************************** - -// maximum number of axis/buttons/hats with ITEM_IDs for use by osd layer -constexpr int INPUT_MAX_AXIS = 8; -constexpr int INPUT_MAX_BUTTONS = 32; -constexpr int INPUT_MAX_HATS = 4; -constexpr int INPUT_MAX_ADD_SWITCH = 16; -constexpr int INPUT_MAX_ADD_ABSOLUTE = 16; -constexpr int INPUT_MAX_ADD_RELATIVE = 16; - - -// device classes -enum input_device_class -{ - DEVICE_CLASS_INVALID, - DEVICE_CLASS_FIRST_VALID, - DEVICE_CLASS_KEYBOARD = DEVICE_CLASS_FIRST_VALID, - DEVICE_CLASS_MOUSE, - DEVICE_CLASS_LIGHTGUN, - DEVICE_CLASS_JOYSTICK, - DEVICE_CLASS_LAST_VALID = DEVICE_CLASS_JOYSTICK, - DEVICE_CLASS_INTERNAL, - DEVICE_CLASS_MAXIMUM -}; -DECLARE_ENUM_INCDEC_OPERATORS(input_device_class) - - -// device index -constexpr int DEVICE_INDEX_MAXIMUM = 0xff; - - -// input item classes -enum input_item_class -{ - ITEM_CLASS_INVALID, - ITEM_CLASS_SWITCH, - ITEM_CLASS_ABSOLUTE, - ITEM_CLASS_RELATIVE, - ITEM_CLASS_MAXIMUM -}; - - -// input item modifiers -enum input_item_modifier -{ - ITEM_MODIFIER_NONE, - ITEM_MODIFIER_REVERSE, - ITEM_MODIFIER_POS, - ITEM_MODIFIER_NEG, - ITEM_MODIFIER_LEFT, - ITEM_MODIFIER_RIGHT, - ITEM_MODIFIER_UP, - ITEM_MODIFIER_DOWN, - ITEM_MODIFIER_MAXIMUM -}; - - -// standard item IDs -enum input_item_id -{ - ITEM_ID_INVALID, - ITEM_ID_FIRST_VALID, - - // standard keyboard IDs - ITEM_ID_A = ITEM_ID_FIRST_VALID, - ITEM_ID_B, - ITEM_ID_C, - ITEM_ID_D, - ITEM_ID_E, - ITEM_ID_F, - ITEM_ID_G, - ITEM_ID_H, - ITEM_ID_I, - ITEM_ID_J, - ITEM_ID_K, - ITEM_ID_L, - ITEM_ID_M, - ITEM_ID_N, - ITEM_ID_O, - ITEM_ID_P, - ITEM_ID_Q, - ITEM_ID_R, - ITEM_ID_S, - ITEM_ID_T, - ITEM_ID_U, - ITEM_ID_V, - ITEM_ID_W, - ITEM_ID_X, - ITEM_ID_Y, - ITEM_ID_Z, - ITEM_ID_0, - ITEM_ID_1, - ITEM_ID_2, - ITEM_ID_3, - ITEM_ID_4, - ITEM_ID_5, - ITEM_ID_6, - ITEM_ID_7, - ITEM_ID_8, - ITEM_ID_9, - ITEM_ID_F1, - ITEM_ID_F2, - ITEM_ID_F3, - ITEM_ID_F4, - ITEM_ID_F5, - ITEM_ID_F6, - ITEM_ID_F7, - ITEM_ID_F8, - ITEM_ID_F9, - ITEM_ID_F10, - ITEM_ID_F11, - ITEM_ID_F12, - ITEM_ID_F13, - ITEM_ID_F14, - ITEM_ID_F15, - ITEM_ID_F16, - ITEM_ID_F17, - ITEM_ID_F18, - ITEM_ID_F19, - ITEM_ID_F20, - ITEM_ID_ESC, - ITEM_ID_TILDE, - ITEM_ID_MINUS, - ITEM_ID_EQUALS, - ITEM_ID_BACKSPACE, - ITEM_ID_TAB, - ITEM_ID_OPENBRACE, - ITEM_ID_CLOSEBRACE, - ITEM_ID_ENTER, - ITEM_ID_COLON, - ITEM_ID_QUOTE, - ITEM_ID_BACKSLASH, - ITEM_ID_BACKSLASH2, - ITEM_ID_COMMA, - ITEM_ID_STOP, - ITEM_ID_SLASH, - ITEM_ID_SPACE, - ITEM_ID_INSERT, - ITEM_ID_DEL, - ITEM_ID_HOME, - ITEM_ID_END, - ITEM_ID_PGUP, - ITEM_ID_PGDN, - ITEM_ID_LEFT, - ITEM_ID_RIGHT, - ITEM_ID_UP, - ITEM_ID_DOWN, - ITEM_ID_0_PAD, - ITEM_ID_1_PAD, - ITEM_ID_2_PAD, - ITEM_ID_3_PAD, - ITEM_ID_4_PAD, - ITEM_ID_5_PAD, - ITEM_ID_6_PAD, - ITEM_ID_7_PAD, - ITEM_ID_8_PAD, - ITEM_ID_9_PAD, - ITEM_ID_SLASH_PAD, - ITEM_ID_ASTERISK, - ITEM_ID_MINUS_PAD, - ITEM_ID_PLUS_PAD, - ITEM_ID_DEL_PAD, - ITEM_ID_ENTER_PAD, - ITEM_ID_BS_PAD, - ITEM_ID_TAB_PAD, - ITEM_ID_00_PAD, - ITEM_ID_000_PAD, - ITEM_ID_COMMA_PAD, - ITEM_ID_EQUALS_PAD, - ITEM_ID_PRTSCR, - ITEM_ID_PAUSE, - ITEM_ID_LSHIFT, - ITEM_ID_RSHIFT, - ITEM_ID_LCONTROL, - ITEM_ID_RCONTROL, - ITEM_ID_LALT, - ITEM_ID_RALT, - ITEM_ID_SCRLOCK, - ITEM_ID_NUMLOCK, - ITEM_ID_CAPSLOCK, - ITEM_ID_LWIN, - ITEM_ID_RWIN, - ITEM_ID_MENU, - ITEM_ID_CANCEL, - - // standard mouse/joystick/gun IDs - ITEM_ID_XAXIS, - ITEM_ID_YAXIS, - ITEM_ID_ZAXIS, - ITEM_ID_RXAXIS, - ITEM_ID_RYAXIS, - ITEM_ID_RZAXIS, - ITEM_ID_SLIDER1, - ITEM_ID_SLIDER2, - ITEM_ID_BUTTON1, - ITEM_ID_BUTTON2, - ITEM_ID_BUTTON3, - ITEM_ID_BUTTON4, - ITEM_ID_BUTTON5, - ITEM_ID_BUTTON6, - ITEM_ID_BUTTON7, - ITEM_ID_BUTTON8, - ITEM_ID_BUTTON9, - ITEM_ID_BUTTON10, - ITEM_ID_BUTTON11, - ITEM_ID_BUTTON12, - ITEM_ID_BUTTON13, - ITEM_ID_BUTTON14, - ITEM_ID_BUTTON15, - ITEM_ID_BUTTON16, - ITEM_ID_BUTTON17, - ITEM_ID_BUTTON18, - ITEM_ID_BUTTON19, - ITEM_ID_BUTTON20, - ITEM_ID_BUTTON21, - ITEM_ID_BUTTON22, - ITEM_ID_BUTTON23, - ITEM_ID_BUTTON24, - ITEM_ID_BUTTON25, - ITEM_ID_BUTTON26, - ITEM_ID_BUTTON27, - ITEM_ID_BUTTON28, - ITEM_ID_BUTTON29, - ITEM_ID_BUTTON30, - ITEM_ID_BUTTON31, - ITEM_ID_BUTTON32, - ITEM_ID_START, - ITEM_ID_SELECT, - - // Hats - ITEM_ID_HAT1UP, - ITEM_ID_HAT1DOWN, - ITEM_ID_HAT1LEFT, - ITEM_ID_HAT1RIGHT, - ITEM_ID_HAT2UP, - ITEM_ID_HAT2DOWN, - ITEM_ID_HAT2LEFT, - ITEM_ID_HAT2RIGHT, - ITEM_ID_HAT3UP, - ITEM_ID_HAT3DOWN, - ITEM_ID_HAT3LEFT, - ITEM_ID_HAT3RIGHT, - ITEM_ID_HAT4UP, - ITEM_ID_HAT4DOWN, - ITEM_ID_HAT4LEFT, - ITEM_ID_HAT4RIGHT, - - // Additional IDs - ITEM_ID_ADD_SWITCH1, - ITEM_ID_ADD_SWITCH2, - ITEM_ID_ADD_SWITCH3, - ITEM_ID_ADD_SWITCH4, - ITEM_ID_ADD_SWITCH5, - ITEM_ID_ADD_SWITCH6, - ITEM_ID_ADD_SWITCH7, - ITEM_ID_ADD_SWITCH8, - ITEM_ID_ADD_SWITCH9, - ITEM_ID_ADD_SWITCH10, - ITEM_ID_ADD_SWITCH11, - ITEM_ID_ADD_SWITCH12, - ITEM_ID_ADD_SWITCH13, - ITEM_ID_ADD_SWITCH14, - ITEM_ID_ADD_SWITCH15, - ITEM_ID_ADD_SWITCH16, - - ITEM_ID_ADD_ABSOLUTE1, - ITEM_ID_ADD_ABSOLUTE2, - ITEM_ID_ADD_ABSOLUTE3, - ITEM_ID_ADD_ABSOLUTE4, - ITEM_ID_ADD_ABSOLUTE5, - ITEM_ID_ADD_ABSOLUTE6, - ITEM_ID_ADD_ABSOLUTE7, - ITEM_ID_ADD_ABSOLUTE8, - ITEM_ID_ADD_ABSOLUTE9, - ITEM_ID_ADD_ABSOLUTE10, - ITEM_ID_ADD_ABSOLUTE11, - ITEM_ID_ADD_ABSOLUTE12, - ITEM_ID_ADD_ABSOLUTE13, - ITEM_ID_ADD_ABSOLUTE14, - ITEM_ID_ADD_ABSOLUTE15, - ITEM_ID_ADD_ABSOLUTE16, - - ITEM_ID_ADD_RELATIVE1, - ITEM_ID_ADD_RELATIVE2, - ITEM_ID_ADD_RELATIVE3, - ITEM_ID_ADD_RELATIVE4, - ITEM_ID_ADD_RELATIVE5, - ITEM_ID_ADD_RELATIVE6, - ITEM_ID_ADD_RELATIVE7, - ITEM_ID_ADD_RELATIVE8, - ITEM_ID_ADD_RELATIVE9, - ITEM_ID_ADD_RELATIVE10, - ITEM_ID_ADD_RELATIVE11, - ITEM_ID_ADD_RELATIVE12, - ITEM_ID_ADD_RELATIVE13, - ITEM_ID_ADD_RELATIVE14, - ITEM_ID_ADD_RELATIVE15, - ITEM_ID_ADD_RELATIVE16, - - // generic other IDs - ITEM_ID_OTHER_SWITCH, - ITEM_ID_OTHER_AXIS_ABSOLUTE, - ITEM_ID_OTHER_AXIS_RELATIVE, - ITEM_ID_MAXIMUM, - - // internal codes for sequences - ITEM_ID_SEQ_END, - ITEM_ID_SEQ_DEFAULT, - ITEM_ID_SEQ_NOT, - ITEM_ID_SEQ_OR, - - // absolute maximum ID - ITEM_ID_ABSOLUTE_MAXIMUM = 0xfff -}; -DECLARE_ENUM_INCDEC_OPERATORS(input_item_id) - - - //************************************************************************** // TYPE DEFINITIONS //************************************************************************** -// ======================> input_code - -// a combined code that describes a particular input on a particular device -class input_code -{ -public: - // construction/destruction - constexpr input_code( - input_device_class devclass = DEVICE_CLASS_INVALID, - int devindex = 0, - input_item_class itemclass = ITEM_CLASS_INVALID, - input_item_modifier modifier = ITEM_MODIFIER_NONE, - input_item_id itemid = ITEM_ID_INVALID) noexcept - : m_internal(((devclass & 0xf) << 28) | ((devindex & 0xff) << 20) | ((itemclass & 0xf) << 16) | ((modifier & 0xf) << 12) | (itemid & 0xfff)) - { - assert(devclass >= 0 && devclass < DEVICE_CLASS_MAXIMUM); - assert(devindex >= 0 && devindex < DEVICE_INDEX_MAXIMUM); - assert(itemclass >= 0 && itemclass < ITEM_CLASS_MAXIMUM); - assert(modifier >= 0 && modifier < ITEM_MODIFIER_MAXIMUM); - assert(itemid >= 0 && itemid < ITEM_ID_ABSOLUTE_MAXIMUM); - } - constexpr input_code(const input_code &src) noexcept = default; - - // operators - constexpr bool operator==(const input_code &rhs) const noexcept { return m_internal == rhs.m_internal; } - constexpr bool operator!=(const input_code &rhs) const noexcept { return m_internal != rhs.m_internal; } - constexpr bool operator<(const input_code &rhs) const noexcept { return m_internal < rhs.m_internal; } - - // getters - constexpr bool internal() const noexcept { return device_class() == DEVICE_CLASS_INTERNAL; } - constexpr input_device_class device_class() const noexcept { return input_device_class((m_internal >> 28) & 0xf); } - constexpr int device_index() const noexcept { return ((m_internal >> 20) & 0xff); } - constexpr input_item_class item_class() const noexcept { return input_item_class((m_internal >> 16) & 0xf); } - constexpr input_item_modifier item_modifier() const noexcept { return input_item_modifier((m_internal >> 12) & 0xf); } - constexpr input_item_id item_id() const noexcept { return input_item_id(m_internal & 0xfff); } - - // setters - void set_device_class(input_device_class devclass) noexcept - { - assert(devclass >= 0 && devclass <= 0xf); - m_internal = (m_internal & ~(0xf << 28)) | ((devclass & 0xf) << 28); - } - void set_device_index(int devindex) noexcept - { - assert(devindex >= 0 && devindex <= 0xff); - m_internal = (m_internal & ~(0xff << 20)) | ((devindex & 0xff) << 20); - } - void set_item_class(input_item_class itemclass) noexcept - { - assert(itemclass >= 0 && itemclass <= 0xf); - m_internal = (m_internal & ~(0xf << 16)) | ((itemclass & 0xf) << 16); - } - void set_item_modifier(input_item_modifier modifier) noexcept - { - assert(modifier >= 0 && modifier <= 0xf); - m_internal = (m_internal & ~(0xf << 12)) | ((modifier & 0xf) << 12); - } - void set_item_id(input_item_id itemid) noexcept - { - assert(itemid >= 0 && itemid <= 0xfff); - m_internal = (m_internal & ~0xfff) | (itemid & 0xfff); - } - -private: - u32 m_internal; -}; - - -// ======================> input_seq - -// a sequence of input_codes, supporting AND/OR and inversion -class input_seq -{ -public: - // construction/destruction - input_seq() noexcept : input_seq(std::make_index_sequence::value>()) { } - template input_seq(input_code code_0, T... code_n) noexcept : input_seq(std::make_index_sequence::value - sizeof...(T) - 1>(), code_0, code_n...) { } - constexpr input_seq(const input_seq &rhs) noexcept = default; - - // operators - bool operator==(const input_seq &rhs) const noexcept { return m_code == rhs.m_code; } - bool operator!=(const input_seq &rhs) const noexcept { return m_code != rhs.m_code; } - constexpr input_code operator[](int index) const noexcept { return (index >= 0 && index < m_code.size()) ? m_code[index] : end_code; } - input_seq &operator+=(input_code code) noexcept; - input_seq &operator|=(input_code code) noexcept; - - // getters - constexpr bool empty() const noexcept { return m_code[0] == end_code; } - constexpr int max_size() const noexcept { return std::tuple_size::value; } - int length() const noexcept; - bool is_valid() const noexcept; - constexpr bool is_default() const noexcept { return m_code[0] == default_code; } - - // setters - template void set(input_code code_0, T... code_n) noexcept - { - static_assert(sizeof...(T) < std::tuple_size::value, "too many codes for input_seq"); - set<0>(code_0, code_n...); - } - void reset() noexcept { set(end_code); } - void set_default() noexcept { set(default_code); } - void backspace() noexcept; - void replace(input_code oldcode, input_code newcode) noexcept; - - // constant codes used in sequences - static constexpr input_code end_code { DEVICE_CLASS_INTERNAL, 0, ITEM_CLASS_INVALID, ITEM_MODIFIER_NONE, ITEM_ID_SEQ_END }; - static constexpr input_code default_code { DEVICE_CLASS_INTERNAL, 0, ITEM_CLASS_INVALID, ITEM_MODIFIER_NONE, ITEM_ID_SEQ_DEFAULT }; - static constexpr input_code not_code { DEVICE_CLASS_INTERNAL, 0, ITEM_CLASS_INVALID, ITEM_MODIFIER_NONE, ITEM_ID_SEQ_NOT }; - static constexpr input_code or_code { DEVICE_CLASS_INTERNAL, 0, ITEM_CLASS_INVALID, ITEM_MODIFIER_NONE, ITEM_ID_SEQ_OR }; - - // constant sequences - static const input_seq empty_seq; - -private: - static constexpr input_code get_end_code(size_t) noexcept { return end_code; } - - template input_seq(std::integer_sequence, T... code) noexcept : m_code({ code..., get_end_code(N)... }) { } - template input_seq(std::integer_sequence) noexcept : m_code({ get_end_code(N)... }) { } - - template void set() noexcept - { - std::fill(std::next(m_code.begin(), N), m_code.end(), end_code); - } - template void set(input_code code_0, T... code_n) noexcept - { - m_code[N] = code_0; - set(code_n...); - } - - // internal state - std::array m_code; -}; +using osd::input_seq; // too much trouble to qualify this everywhere // ======================> input_manager // global machine-level information about devices -class input_manager +class input_manager : public osd::input_manager { public: // controller alias table typedef @@ -498,6 +51,9 @@ public: input_manager(running_machine &machine); ~input_manager(); + // OSD interface + virtual osd::input_device &add_device(input_device_class devclass, std::string_view name, std::string_view id, void *internal) override; + // getters running_machine &machine() const { return m_machine; } input_class &device_class(input_device_class devclass) { assert(devclass >= DEVICE_CLASS_FIRST_VALID && devclass <= DEVICE_CLASS_LAST_VALID); return *m_class[devclass]; } @@ -542,466 +98,4 @@ private: }; - -//************************************************************************** -// MACROS -//************************************************************************** - -// invalid codes -#define INPUT_CODE_INVALID input_code() - -// keyboard codes -#define KEYCODE_A_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_A) -#define KEYCODE_B_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_B) -#define KEYCODE_C_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_C) -#define KEYCODE_D_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_D) -#define KEYCODE_E_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_E) -#define KEYCODE_F_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F) -#define KEYCODE_G_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_G) -#define KEYCODE_H_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_H) -#define KEYCODE_I_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_I) -#define KEYCODE_J_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_J) -#define KEYCODE_K_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_K) -#define KEYCODE_L_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_L) -#define KEYCODE_M_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_M) -#define KEYCODE_N_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_N) -#define KEYCODE_O_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_O) -#define KEYCODE_P_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_P) -#define KEYCODE_Q_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_Q) -#define KEYCODE_R_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_R) -#define KEYCODE_S_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_S) -#define KEYCODE_T_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_T) -#define KEYCODE_U_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_U) -#define KEYCODE_V_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_V) -#define KEYCODE_W_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_W) -#define KEYCODE_X_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_X) -#define KEYCODE_Y_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_Y) -#define KEYCODE_Z_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_Z) -#define KEYCODE_0_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_0) -#define KEYCODE_1_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_1) -#define KEYCODE_2_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_2) -#define KEYCODE_3_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_3) -#define KEYCODE_4_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_4) -#define KEYCODE_5_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_5) -#define KEYCODE_6_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_6) -#define KEYCODE_7_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_7) -#define KEYCODE_8_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_8) -#define KEYCODE_9_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_9) -#define KEYCODE_F1_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F1) -#define KEYCODE_F2_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F2) -#define KEYCODE_F3_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F3) -#define KEYCODE_F4_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F4) -#define KEYCODE_F5_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F5) -#define KEYCODE_F6_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F6) -#define KEYCODE_F7_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F7) -#define KEYCODE_F8_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F8) -#define KEYCODE_F9_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F9) -#define KEYCODE_F10_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F10) -#define KEYCODE_F11_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F11) -#define KEYCODE_F12_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F12) -#define KEYCODE_F13_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F13) -#define KEYCODE_F14_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F14) -#define KEYCODE_F15_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F15) -#define KEYCODE_F16_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F16) -#define KEYCODE_F17_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F17) -#define KEYCODE_F18_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F18) -#define KEYCODE_F19_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F19) -#define KEYCODE_F20_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F20) -#define KEYCODE_ESC_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_ESC) -#define KEYCODE_TILDE_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_TILDE) -#define KEYCODE_MINUS_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_MINUS) -#define KEYCODE_EQUALS_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_EQUALS) -#define KEYCODE_BACKSPACE_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BACKSPACE) -#define KEYCODE_TAB_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_TAB) -#define KEYCODE_OPENBRACE_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_OPENBRACE) -#define KEYCODE_CLOSEBRACE_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_CLOSEBRACE) -#define KEYCODE_ENTER_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_ENTER) -#define KEYCODE_COLON_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_COLON) -#define KEYCODE_QUOTE_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_QUOTE) -#define KEYCODE_BACKSLASH_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BACKSLASH) -#define KEYCODE_BACKSLASH2_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BACKSLASH2) -#define KEYCODE_COMMA_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_COMMA) -#define KEYCODE_STOP_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_STOP) -#define KEYCODE_SLASH_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_SLASH) -#define KEYCODE_SPACE_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_SPACE) -#define KEYCODE_INSERT_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_INSERT) -#define KEYCODE_DEL_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_DEL) -#define KEYCODE_HOME_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_HOME) -#define KEYCODE_END_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_END) -#define KEYCODE_PGUP_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_PGUP) -#define KEYCODE_PGDN_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_PGDN) -#define KEYCODE_LEFT_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_LEFT) -#define KEYCODE_RIGHT_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_RIGHT) -#define KEYCODE_UP_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_UP) -#define KEYCODE_DOWN_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_DOWN) -#define KEYCODE_0_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_0_PAD) -#define KEYCODE_1_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_1_PAD) -#define KEYCODE_2_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_2_PAD) -#define KEYCODE_3_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_3_PAD) -#define KEYCODE_4_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_4_PAD) -#define KEYCODE_5_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_5_PAD) -#define KEYCODE_6_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_6_PAD) -#define KEYCODE_7_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_7_PAD) -#define KEYCODE_8_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_8_PAD) -#define KEYCODE_9_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_9_PAD) -#define KEYCODE_SLASH_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_SLASH_PAD) -#define KEYCODE_ASTERISK_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_ASTERISK) -#define KEYCODE_MINUS_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_MINUS_PAD) -#define KEYCODE_PLUS_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_PLUS_PAD) -#define KEYCODE_DEL_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_DEL_PAD) -#define KEYCODE_ENTER_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_ENTER_PAD) -#define KEYCODE_BS_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BS_PAD) -#define KEYCODE_TAB_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_TAB_PAD) -#define KEYCODE_00_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_00_PAD) -#define KEYCODE_000_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_000_PAD) -#define KEYCODE_COMMA_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_COMMA_PAD) -#define KEYCODE_EQUALS_PAD_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_EQUALS_PAD) -#define KEYCODE_PRTSCR_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_PRTSCR) -#define KEYCODE_PAUSE_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_PAUSE) -#define KEYCODE_LSHIFT_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_LSHIFT) -#define KEYCODE_RSHIFT_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_RSHIFT) -#define KEYCODE_LCONTROL_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_LCONTROL) -#define KEYCODE_RCONTROL_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_RCONTROL) -#define KEYCODE_LALT_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_LALT) -#define KEYCODE_RALT_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_RALT) -#define KEYCODE_SCRLOCK_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_SCRLOCK) -#define KEYCODE_NUMLOCK_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_NUMLOCK) -#define KEYCODE_CAPSLOCK_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_CAPSLOCK) -#define KEYCODE_LWIN_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_LWIN) -#define KEYCODE_RWIN_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_RWIN) -#define KEYCODE_MENU_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_MENU) -#define KEYCODE_CANCEL_INDEXED(n) input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_CANCEL) - -#define KEYCODE_A KEYCODE_A_INDEXED(0) -#define KEYCODE_B KEYCODE_B_INDEXED(0) -#define KEYCODE_C KEYCODE_C_INDEXED(0) -#define KEYCODE_D KEYCODE_D_INDEXED(0) -#define KEYCODE_E KEYCODE_E_INDEXED(0) -#define KEYCODE_F KEYCODE_F_INDEXED(0) -#define KEYCODE_G KEYCODE_G_INDEXED(0) -#define KEYCODE_H KEYCODE_H_INDEXED(0) -#define KEYCODE_I KEYCODE_I_INDEXED(0) -#define KEYCODE_J KEYCODE_J_INDEXED(0) -#define KEYCODE_K KEYCODE_K_INDEXED(0) -#define KEYCODE_L KEYCODE_L_INDEXED(0) -#define KEYCODE_M KEYCODE_M_INDEXED(0) -#define KEYCODE_N KEYCODE_N_INDEXED(0) -#define KEYCODE_O KEYCODE_O_INDEXED(0) -#define KEYCODE_P KEYCODE_P_INDEXED(0) -#define KEYCODE_Q KEYCODE_Q_INDEXED(0) -#define KEYCODE_R KEYCODE_R_INDEXED(0) -#define KEYCODE_S KEYCODE_S_INDEXED(0) -#define KEYCODE_T KEYCODE_T_INDEXED(0) -#define KEYCODE_U KEYCODE_U_INDEXED(0) -#define KEYCODE_V KEYCODE_V_INDEXED(0) -#define KEYCODE_W KEYCODE_W_INDEXED(0) -#define KEYCODE_X KEYCODE_X_INDEXED(0) -#define KEYCODE_Y KEYCODE_Y_INDEXED(0) -#define KEYCODE_Z KEYCODE_Z_INDEXED(0) -#define KEYCODE_0 KEYCODE_0_INDEXED(0) -#define KEYCODE_1 KEYCODE_1_INDEXED(0) -#define KEYCODE_2 KEYCODE_2_INDEXED(0) -#define KEYCODE_3 KEYCODE_3_INDEXED(0) -#define KEYCODE_4 KEYCODE_4_INDEXED(0) -#define KEYCODE_5 KEYCODE_5_INDEXED(0) -#define KEYCODE_6 KEYCODE_6_INDEXED(0) -#define KEYCODE_7 KEYCODE_7_INDEXED(0) -#define KEYCODE_8 KEYCODE_8_INDEXED(0) -#define KEYCODE_9 KEYCODE_9_INDEXED(0) -#define KEYCODE_F1 KEYCODE_F1_INDEXED(0) -#define KEYCODE_F2 KEYCODE_F2_INDEXED(0) -#define KEYCODE_F3 KEYCODE_F3_INDEXED(0) -#define KEYCODE_F4 KEYCODE_F4_INDEXED(0) -#define KEYCODE_F5 KEYCODE_F5_INDEXED(0) -#define KEYCODE_F6 KEYCODE_F6_INDEXED(0) -#define KEYCODE_F7 KEYCODE_F7_INDEXED(0) -#define KEYCODE_F8 KEYCODE_F8_INDEXED(0) -#define KEYCODE_F9 KEYCODE_F9_INDEXED(0) -#define KEYCODE_F10 KEYCODE_F10_INDEXED(0) -#define KEYCODE_F11 KEYCODE_F11_INDEXED(0) -#define KEYCODE_F12 KEYCODE_F12_INDEXED(0) -#define KEYCODE_F13 KEYCODE_F13_INDEXED(0) -#define KEYCODE_F14 KEYCODE_F14_INDEXED(0) -#define KEYCODE_F15 KEYCODE_F15_INDEXED(0) -#define KEYCODE_F16 KEYCODE_F16_INDEXED(0) -#define KEYCODE_F17 KEYCODE_F17_INDEXED(0) -#define KEYCODE_F18 KEYCODE_F18_INDEXED(0) -#define KEYCODE_F19 KEYCODE_F19_INDEXED(0) -#define KEYCODE_F20 KEYCODE_F20_INDEXED(0) -#define KEYCODE_ESC KEYCODE_ESC_INDEXED(0) -#define KEYCODE_TILDE KEYCODE_TILDE_INDEXED(0) -#define KEYCODE_MINUS KEYCODE_MINUS_INDEXED(0) -#define KEYCODE_EQUALS KEYCODE_EQUALS_INDEXED(0) -#define KEYCODE_BACKSPACE KEYCODE_BACKSPACE_INDEXED(0) -#define KEYCODE_TAB KEYCODE_TAB_INDEXED(0) -#define KEYCODE_OPENBRACE KEYCODE_OPENBRACE_INDEXED(0) -#define KEYCODE_CLOSEBRACE KEYCODE_CLOSEBRACE_INDEXED(0) -#define KEYCODE_ENTER KEYCODE_ENTER_INDEXED(0) -#define KEYCODE_COLON KEYCODE_COLON_INDEXED(0) -#define KEYCODE_QUOTE KEYCODE_QUOTE_INDEXED(0) -#define KEYCODE_BACKSLASH KEYCODE_BACKSLASH_INDEXED(0) -#define KEYCODE_BACKSLASH2 KEYCODE_BACKSLASH2_INDEXED(0) -#define KEYCODE_COMMA KEYCODE_COMMA_INDEXED(0) -#define KEYCODE_STOP KEYCODE_STOP_INDEXED(0) -#define KEYCODE_SLASH KEYCODE_SLASH_INDEXED(0) -#define KEYCODE_SPACE KEYCODE_SPACE_INDEXED(0) -#define KEYCODE_INSERT KEYCODE_INSERT_INDEXED(0) -#define KEYCODE_DEL KEYCODE_DEL_INDEXED(0) -#define KEYCODE_HOME KEYCODE_HOME_INDEXED(0) -#define KEYCODE_END KEYCODE_END_INDEXED(0) -#define KEYCODE_PGUP KEYCODE_PGUP_INDEXED(0) -#define KEYCODE_PGDN KEYCODE_PGDN_INDEXED(0) -#define KEYCODE_LEFT KEYCODE_LEFT_INDEXED(0) -#define KEYCODE_RIGHT KEYCODE_RIGHT_INDEXED(0) -#define KEYCODE_UP KEYCODE_UP_INDEXED(0) -#define KEYCODE_DOWN KEYCODE_DOWN_INDEXED(0) -#define KEYCODE_0_PAD KEYCODE_0_PAD_INDEXED(0) -#define KEYCODE_1_PAD KEYCODE_1_PAD_INDEXED(0) -#define KEYCODE_2_PAD KEYCODE_2_PAD_INDEXED(0) -#define KEYCODE_3_PAD KEYCODE_3_PAD_INDEXED(0) -#define KEYCODE_4_PAD KEYCODE_4_PAD_INDEXED(0) -#define KEYCODE_5_PAD KEYCODE_5_PAD_INDEXED(0) -#define KEYCODE_6_PAD KEYCODE_6_PAD_INDEXED(0) -#define KEYCODE_7_PAD KEYCODE_7_PAD_INDEXED(0) -#define KEYCODE_8_PAD KEYCODE_8_PAD_INDEXED(0) -#define KEYCODE_9_PAD KEYCODE_9_PAD_INDEXED(0) -#define KEYCODE_SLASH_PAD KEYCODE_SLASH_PAD_INDEXED(0) -#define KEYCODE_ASTERISK KEYCODE_ASTERISK_INDEXED(0) -#define KEYCODE_MINUS_PAD KEYCODE_MINUS_PAD_INDEXED(0) -#define KEYCODE_PLUS_PAD KEYCODE_PLUS_PAD_INDEXED(0) -#define KEYCODE_DEL_PAD KEYCODE_DEL_PAD_INDEXED(0) -#define KEYCODE_ENTER_PAD KEYCODE_ENTER_PAD_INDEXED(0) -#define KEYCODE_BS_PAD KEYCODE_BS_PAD_INDEXED(0) -#define KEYCODE_TAB_PAD KEYCODE_TAB_PAD_INDEXED(0) -#define KEYCODE_00_PAD KEYCODE_00_PAD_INDEXED(0) -#define KEYCODE_000_PAD KEYCODE_000_PAD_INDEXED(0) -#define KEYCODE_COMMA_PAD KEYCODE_COMMA_PAD_INDEXED(0) -#define KEYCODE_EQUALS_PAD KEYCODE_EQUALS_PAD_INDEXED(0) -#define KEYCODE_PRTSCR KEYCODE_PRTSCR_INDEXED(0) -#define KEYCODE_PAUSE KEYCODE_PAUSE_INDEXED(0) -#define KEYCODE_LSHIFT KEYCODE_LSHIFT_INDEXED(0) -#define KEYCODE_RSHIFT KEYCODE_RSHIFT_INDEXED(0) -#define KEYCODE_LCONTROL KEYCODE_LCONTROL_INDEXED(0) -#define KEYCODE_RCONTROL KEYCODE_RCONTROL_INDEXED(0) -#define KEYCODE_LALT KEYCODE_LALT_INDEXED(0) -#define KEYCODE_RALT KEYCODE_RALT_INDEXED(0) -#define KEYCODE_SCRLOCK KEYCODE_SCRLOCK_INDEXED(0) -#define KEYCODE_NUMLOCK KEYCODE_NUMLOCK_INDEXED(0) -#define KEYCODE_CAPSLOCK KEYCODE_CAPSLOCK_INDEXED(0) -#define KEYCODE_LWIN KEYCODE_LWIN_INDEXED(0) -#define KEYCODE_RWIN KEYCODE_RWIN_INDEXED(0) -#define KEYCODE_MENU KEYCODE_MENU_INDEXED(0) -#define KEYCODE_CANCEL KEYCODE_CANCEL_INDEXED(0) - -// mouse axes as relative devices -#define MOUSECODE_X_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_RELATIVE, ITEM_MODIFIER_NONE, ITEM_ID_XAXIS) -#define MOUSECODE_Y_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_RELATIVE, ITEM_MODIFIER_NONE, ITEM_ID_YAXIS) -#define MOUSECODE_Z_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_RELATIVE, ITEM_MODIFIER_NONE, ITEM_ID_ZAXIS) - -#define MOUSECODE_X MOUSECODE_X_INDEXED(0) -#define MOUSECODE_Y MOUSECODE_Y_INDEXED(0) -#define MOUSECODE_Z MOUSECODE_Z_INDEXED(0) - -// mouse axes as switches in +/- direction -#define MOUSECODE_X_POS_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, ITEM_ID_XAXIS) -#define MOUSECODE_X_NEG_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, ITEM_ID_XAXIS) -#define MOUSECODE_Y_POS_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, ITEM_ID_YAXIS) -#define MOUSECODE_Y_NEG_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, ITEM_ID_YAXIS) -#define MOUSECODE_Z_POS_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, ITEM_ID_ZAXIS) -#define MOUSECODE_Z_NEG_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, ITEM_ID_ZAXIS) - -#define MOUSECODE_X_POS_SWITCH MOUSECODE_X_POS_SWITCH_INDEXED(0) -#define MOUSECODE_X_NEG_SWITCH MOUSECODE_X_NEG_SWITCH_INDEXED(0) -#define MOUSECODE_Y_POS_SWITCH MOUSECODE_Y_POS_SWITCH_INDEXED(0) -#define MOUSECODE_Y_NEG_SWITCH MOUSECODE_Y_NEG_SWITCH_INDEXED(0) -#define MOUSECODE_Z_POS_SWITCH MOUSECODE_Z_POS_SWITCH_INDEXED(0) -#define MOUSECODE_Z_NEG_SWITCH MOUSECODE_Z_NEG_SWITCH_INDEXED(0) - -// mouse buttons -#define MOUSECODE_BUTTON1_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON1) -#define MOUSECODE_BUTTON2_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON2) -#define MOUSECODE_BUTTON3_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON3) -#define MOUSECODE_BUTTON4_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON4) -#define MOUSECODE_BUTTON5_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON5) -#define MOUSECODE_BUTTON6_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON6) -#define MOUSECODE_BUTTON7_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON7) -#define MOUSECODE_BUTTON8_INDEXED(n) input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON8) - -#define MOUSECODE_BUTTON1 MOUSECODE_BUTTON1_INDEXED(0) -#define MOUSECODE_BUTTON2 MOUSECODE_BUTTON2_INDEXED(0) -#define MOUSECODE_BUTTON3 MOUSECODE_BUTTON3_INDEXED(0) -#define MOUSECODE_BUTTON4 MOUSECODE_BUTTON4_INDEXED(0) -#define MOUSECODE_BUTTON5 MOUSECODE_BUTTON5_INDEXED(0) -#define MOUSECODE_BUTTON6 MOUSECODE_BUTTON6_INDEXED(0) -#define MOUSECODE_BUTTON7 MOUSECODE_BUTTON7_INDEXED(0) -#define MOUSECODE_BUTTON8 MOUSECODE_BUTTON8_INDEXED(0) - -// gun axes as absolute devices -#define GUNCODE_X_INDEXED(n) input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_XAXIS) -#define GUNCODE_Y_INDEXED(n) input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_YAXIS) - -#define GUNCODE_X GUNCODE_X_INDEXED(0) -#define GUNCODE_Y GUNCODE_Y_INDEXED(0) - -// gun buttons -#define GUNCODE_BUTTON1_INDEXED(n) input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON1) -#define GUNCODE_BUTTON2_INDEXED(n) input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON2) -#define GUNCODE_BUTTON3_INDEXED(n) input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON3) -#define GUNCODE_BUTTON4_INDEXED(n) input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON4) -#define GUNCODE_BUTTON5_INDEXED(n) input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON5) -#define GUNCODE_BUTTON6_INDEXED(n) input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON6) -#define GUNCODE_BUTTON7_INDEXED(n) input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON7) -#define GUNCODE_BUTTON8_INDEXED(n) input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON8) - -#define GUNCODE_BUTTON1 GUNCODE_BUTTON1_INDEXED(0) -#define GUNCODE_BUTTON2 GUNCODE_BUTTON2_INDEXED(0) -#define GUNCODE_BUTTON3 GUNCODE_BUTTON3_INDEXED(0) -#define GUNCODE_BUTTON4 GUNCODE_BUTTON4_INDEXED(0) -#define GUNCODE_BUTTON5 GUNCODE_BUTTON5_INDEXED(0) -#define GUNCODE_BUTTON6 GUNCODE_BUTTON6_INDEXED(0) -#define GUNCODE_BUTTON7 GUNCODE_BUTTON7_INDEXED(0) -#define GUNCODE_BUTTON8 GUNCODE_BUTTON8_INDEXED(0) - -// joystick axes as absolute devices -#define JOYCODE_X_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_XAXIS) -#define JOYCODE_Y_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_YAXIS) -#define JOYCODE_Z_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_ZAXIS) -#define JOYCODE_U_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_RXAXIS) -#define JOYCODE_V_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_RYAXIS) -#define JOYCODE_W_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_RZAXIS) - -#define JOYCODE_X JOYCODE_X_INDEXED(0) -#define JOYCODE_Y JOYCODE_Y_INDEXED(0) -#define JOYCODE_Z JOYCODE_Z_INDEXED(0) -#define JOYCODE_U JOYCODE_U_INDEXED(0) -#define JOYCODE_V JOYCODE_V_INDEXED(0) -#define JOYCODE_W JOYCODE_W_INDEXED(0) - -// joystick axes as absolute half-axes -#define JOYCODE_X_POS_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_POS, ITEM_ID_XAXIS) -#define JOYCODE_X_NEG_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, ITEM_ID_XAXIS) -#define JOYCODE_Y_POS_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_POS, ITEM_ID_YAXIS) -#define JOYCODE_Y_NEG_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, ITEM_ID_YAXIS) -#define JOYCODE_Z_POS_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_POS, ITEM_ID_ZAXIS) -#define JOYCODE_Z_NEG_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, ITEM_ID_ZAXIS) -#define JOYCODE_U_POS_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_POS, ITEM_ID_RXAXIS) -#define JOYCODE_U_NEG_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, ITEM_ID_RXAXIS) -#define JOYCODE_V_POS_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_POS, ITEM_ID_RYAXIS) -#define JOYCODE_V_NEG_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, ITEM_ID_RYAXIS) -#define JOYCODE_W_POS_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_POS, ITEM_ID_RZAXIS) -#define JOYCODE_W_NEG_ABSOLUTE_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, ITEM_ID_RZAXIS) - -#define JOYCODE_X_POS_ABSOLUTE JOYCODE_X_POS_ABSOLUTE_INDEXED(0) -#define JOYCODE_X_NEG_ABSOLUTE JOYCODE_X_NEG_ABSOLUTE_INDEXED(0) -#define JOYCODE_Y_POS_ABSOLUTE JOYCODE_Y_POS_ABSOLUTE_INDEXED(0) -#define JOYCODE_Y_NEG_ABSOLUTE JOYCODE_Y_NEG_ABSOLUTE_INDEXED(0) -#define JOYCODE_Z_POS_ABSOLUTE JOYCODE_Z_POS_ABSOLUTE_INDEXED(0) -#define JOYCODE_Z_NEG_ABSOLUTE JOYCODE_Z_NEG_ABSOLUTE_INDEXED(0) -#define JOYCODE_U_POS_ABSOLUTE JOYCODE_U_POS_ABSOLUTE_INDEXED(0) -#define JOYCODE_U_NEG_ABSOLUTE JOYCODE_U_NEG_ABSOLUTE_INDEXED(0) -#define JOYCODE_V_POS_ABSOLUTE JOYCODE_V_POS_ABSOLUTE_INDEXED(0) -#define JOYCODE_V_NEG_ABSOLUTE JOYCODE_V_NEG_ABSOLUTE_INDEXED(0) -#define JOYCODE_W_POS_ABSOLUTE JOYCODE_W_POS_ABSOLUTE_INDEXED(0) -#define JOYCODE_W_NEG_ABSOLUTE JOYCODE_W_NEG_ABSOLUTE_INDEXED(0) - -// joystick axes as switches; X/Y are specially handled for left/right/up/down mapping -#define JOYCODE_X_LEFT_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_LEFT, ITEM_ID_XAXIS) -#define JOYCODE_X_RIGHT_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_RIGHT, ITEM_ID_XAXIS) -#define JOYCODE_Y_UP_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_UP, ITEM_ID_YAXIS) -#define JOYCODE_Y_DOWN_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_DOWN, ITEM_ID_YAXIS) -#define JOYCODE_Z_POS_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, ITEM_ID_ZAXIS) -#define JOYCODE_Z_NEG_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, ITEM_ID_ZAXIS) -#define JOYCODE_U_POS_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, ITEM_ID_RXAXIS) -#define JOYCODE_U_NEG_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, ITEM_ID_RXAXIS) -#define JOYCODE_V_POS_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, ITEM_ID_RYAXIS) -#define JOYCODE_V_NEG_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, ITEM_ID_RYAXIS) -#define JOYCODE_W_POS_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, ITEM_ID_RZAXIS) -#define JOYCODE_W_NEG_SWITCH_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, ITEM_ID_RZAXIS) - -#define JOYCODE_X_LEFT_SWITCH JOYCODE_X_LEFT_SWITCH_INDEXED(0) -#define JOYCODE_X_RIGHT_SWITCH JOYCODE_X_RIGHT_SWITCH_INDEXED(0) -#define JOYCODE_Y_UP_SWITCH JOYCODE_Y_UP_SWITCH_INDEXED(0) -#define JOYCODE_Y_DOWN_SWITCH JOYCODE_Y_DOWN_SWITCH_INDEXED(0) -#define JOYCODE_Z_POS_SWITCH JOYCODE_Z_POS_SWITCH_INDEXED(0) -#define JOYCODE_Z_NEG_SWITCH JOYCODE_Z_NEG_SWITCH_INDEXED(0) -#define JOYCODE_U_POS_SWITCH JOYCODE_U_POS_SWITCH_INDEXED(0) -#define JOYCODE_U_NEG_SWITCH JOYCODE_U_NEG_SWITCH_INDEXED(0) -#define JOYCODE_V_POS_SWITCH JOYCODE_V_POS_SWITCH_INDEXED(0) -#define JOYCODE_V_NEG_SWITCH JOYCODE_V_NEG_SWITCH_INDEXED(0) -#define JOYCODE_W_POS_SWITCH JOYCODE_W_POS_SWITCH_INDEXED(0) -#define JOYCODE_W_NEG_SWITCH JOYCODE_W_NEG_SWITCH_INDEXED(0) - -// joystick buttons -#define JOYCODE_BUTTON1_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON1) -#define JOYCODE_BUTTON2_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON2) -#define JOYCODE_BUTTON3_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON3) -#define JOYCODE_BUTTON4_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON4) -#define JOYCODE_BUTTON5_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON5) -#define JOYCODE_BUTTON6_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON6) -#define JOYCODE_BUTTON7_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON7) -#define JOYCODE_BUTTON8_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON8) -#define JOYCODE_BUTTON9_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON9) -#define JOYCODE_BUTTON10_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON10) -#define JOYCODE_BUTTON11_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON11) -#define JOYCODE_BUTTON12_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON12) -#define JOYCODE_BUTTON13_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON13) -#define JOYCODE_BUTTON14_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON14) -#define JOYCODE_BUTTON15_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON15) -#define JOYCODE_BUTTON16_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON16) -#define JOYCODE_BUTTON17_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON17) -#define JOYCODE_BUTTON18_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON18) -#define JOYCODE_BUTTON19_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON19) -#define JOYCODE_BUTTON20_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON20) -#define JOYCODE_BUTTON21_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON21) -#define JOYCODE_BUTTON22_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON22) -#define JOYCODE_BUTTON23_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON23) -#define JOYCODE_BUTTON24_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON24) -#define JOYCODE_BUTTON25_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON25) -#define JOYCODE_BUTTON26_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON26) -#define JOYCODE_BUTTON27_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON27) -#define JOYCODE_BUTTON28_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON28) -#define JOYCODE_BUTTON29_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON29) -#define JOYCODE_BUTTON30_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON30) -#define JOYCODE_BUTTON31_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON31) -#define JOYCODE_BUTTON32_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON32) -#define JOYCODE_START_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_START) -#define JOYCODE_SELECT_INDEXED(n) input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_SELECT) - -#define JOYCODE_BUTTON1 JOYCODE_BUTTON1_INDEXED(0) -#define JOYCODE_BUTTON2 JOYCODE_BUTTON2_INDEXED(0) -#define JOYCODE_BUTTON3 JOYCODE_BUTTON3_INDEXED(0) -#define JOYCODE_BUTTON4 JOYCODE_BUTTON4_INDEXED(0) -#define JOYCODE_BUTTON5 JOYCODE_BUTTON5_INDEXED(0) -#define JOYCODE_BUTTON6 JOYCODE_BUTTON6_INDEXED(0) -#define JOYCODE_BUTTON7 JOYCODE_BUTTON7_INDEXED(0) -#define JOYCODE_BUTTON8 JOYCODE_BUTTON8_INDEXED(0) -#define JOYCODE_BUTTON9 JOYCODE_BUTTON9_INDEXED(0) -#define JOYCODE_BUTTON10 JOYCODE_BUTTON10_INDEXED(0) -#define JOYCODE_BUTTON11 JOYCODE_BUTTON11_INDEXED(0) -#define JOYCODE_BUTTON12 JOYCODE_BUTTON12_INDEXED(0) -#define JOYCODE_BUTTON13 JOYCODE_BUTTON13_INDEXED(0) -#define JOYCODE_BUTTON14 JOYCODE_BUTTON14_INDEXED(0) -#define JOYCODE_BUTTON15 JOYCODE_BUTTON15_INDEXED(0) -#define JOYCODE_BUTTON16 JOYCODE_BUTTON16_INDEXED(0) -#define JOYCODE_BUTTON17 JOYCODE_BUTTON17_INDEXED(0) -#define JOYCODE_BUTTON18 JOYCODE_BUTTON18_INDEXED(0) -#define JOYCODE_BUTTON19 JOYCODE_BUTTON19_INDEXED(0) -#define JOYCODE_BUTTON20 JOYCODE_BUTTON20_INDEXED(0) -#define JOYCODE_BUTTON21 JOYCODE_BUTTON21_INDEXED(0) -#define JOYCODE_BUTTON22 JOYCODE_BUTTON22_INDEXED(0) -#define JOYCODE_BUTTON23 JOYCODE_BUTTON23_INDEXED(0) -#define JOYCODE_BUTTON24 JOYCODE_BUTTON24_INDEXED(0) -#define JOYCODE_BUTTON25 JOYCODE_BUTTON25_INDEXED(0) -#define JOYCODE_BUTTON26 JOYCODE_BUTTON26_INDEXED(0) -#define JOYCODE_BUTTON27 JOYCODE_BUTTON27_INDEXED(0) -#define JOYCODE_BUTTON28 JOYCODE_BUTTON28_INDEXED(0) -#define JOYCODE_BUTTON29 JOYCODE_BUTTON29_INDEXED(0) -#define JOYCODE_BUTTON30 JOYCODE_BUTTON30_INDEXED(0) -#define JOYCODE_BUTTON31 JOYCODE_BUTTON31_INDEXED(0) -#define JOYCODE_BUTTON32 JOYCODE_BUTTON32_INDEXED(0) -#define JOYCODE_START JOYCODE_START_INDEXED(0) -#define JOYCODE_SELECT JOYCODE_SELECT_INDEXED(0) - - - #endif // MAME_EMU_INPUT_H diff --git a/src/emu/inputdev.cpp b/src/emu/inputdev.cpp index 436f83cf0df..dacffbc2e56 100644 --- a/src/emu/inputdev.cpp +++ b/src/emu/inputdev.cpp @@ -233,8 +233,8 @@ std::string joystick_map::to_string() const u8 joystick_map::update(s32 xaxisval, s32 yaxisval) { // now map the X and Y axes to a 9x9 grid using the raw values - xaxisval = ((xaxisval - INPUT_ABSOLUTE_MIN) * 9) / (INPUT_ABSOLUTE_MAX - INPUT_ABSOLUTE_MIN + 1); - yaxisval = ((yaxisval - INPUT_ABSOLUTE_MIN) * 9) / (INPUT_ABSOLUTE_MAX - INPUT_ABSOLUTE_MIN + 1); + xaxisval = ((xaxisval - osd::INPUT_ABSOLUTE_MIN) * 9) / (osd::INPUT_ABSOLUTE_MAX - osd::INPUT_ABSOLUTE_MIN + 1); + yaxisval = ((yaxisval - osd::INPUT_ABSOLUTE_MIN) * 9) / (osd::INPUT_ABSOLUTE_MAX - osd::INPUT_ABSOLUTE_MIN + 1); u8 mapval = m_map[yaxisval][xaxisval]; // handle stickiness @@ -412,8 +412,8 @@ input_device_lightgun::input_device_lightgun(input_manager &manager, std::string input_device_joystick::input_device_joystick(input_manager &manager, std::string_view _name, std::string_view _id, void *_internal) : input_device(manager, _name, _id, _internal), - m_joystick_deadzone(s32(manager.machine().options().joystick_deadzone() * INPUT_ABSOLUTE_MAX)), - m_joystick_saturation(s32(manager.machine().options().joystick_saturation() * INPUT_ABSOLUTE_MAX)) + m_joystick_deadzone(s32(manager.machine().options().joystick_deadzone() * osd::INPUT_ABSOLUTE_MAX)), + m_joystick_saturation(s32(manager.machine().options().joystick_saturation() * osd::INPUT_ABSOLUTE_MAX)) { // get the default joystick map const char *mapstring = machine().options().joystick_map(); @@ -453,11 +453,11 @@ s32 input_device_joystick::adjust_absolute_value(s32 result) const // if saturated, return the max else if (result > m_joystick_saturation) - result = INPUT_ABSOLUTE_MAX; + result = osd::INPUT_ABSOLUTE_MAX; // otherwise, scale else - result = s64(result - m_joystick_deadzone) * s64(INPUT_ABSOLUTE_MAX) / s64(m_joystick_saturation - m_joystick_deadzone); + result = s64(result - m_joystick_deadzone) * s64(osd::INPUT_ABSOLUTE_MAX) / s64(m_joystick_saturation - m_joystick_deadzone); // re-apply sign and return return negative ? -result : result; @@ -708,8 +708,8 @@ input_device_item::~input_device_item() bool input_device_item::check_axis(input_item_modifier modifier, s32 memory) { - // use INVALID_AXIS_VALUE as a short-circuit - return (memory != INVALID_AXIS_VALUE) && item_check_axis(modifier, memory); + // use osd::INVALID_AXIS_VALUE as a short-circuit + return (memory != osd::INVALID_AXIS_VALUE) && item_check_axis(modifier, memory); } @@ -894,7 +894,7 @@ bool input_device_relative_item::item_check_axis(input_item_modifier modifier, s const s32 curval = read_as_relative(modifier); // for relative axes, look for ~20 pixels movement - return std::abs(curval - memory) > (20 * INPUT_RELATIVE_PER_PIXEL); + return std::abs(curval - memory) > (20 * osd::INPUT_RELATIVE_PER_PIXEL); } @@ -922,7 +922,7 @@ s32 input_device_absolute_item::read_as_switch(input_item_modifier modifier) { // start with the current value s32 result = m_device.adjust_absolute(update_value()); - assert(result >= INPUT_ABSOLUTE_MIN && result <= INPUT_ABSOLUTE_MAX); + assert(result >= osd::INPUT_ABSOLUTE_MIN && result <= osd::INPUT_ABSOLUTE_MAX); // left/right/up/down: if this is a joystick, fetch the paired X/Y axis values and convert if (m_device.devclass() == DEVICE_CLASS_JOYSTICK && modifier >= ITEM_MODIFIER_LEFT && modifier <= ITEM_MODIFIER_DOWN) @@ -977,7 +977,7 @@ s32 input_device_absolute_item::read_as_absolute(input_item_modifier modifier) { // start with the current value s32 result = m_device.adjust_absolute(update_value()); - assert(result >= INPUT_ABSOLUTE_MIN && result <= INPUT_ABSOLUTE_MAX); + assert(result >= osd::INPUT_ABSOLUTE_MIN && result <= osd::INPUT_ABSOLUTE_MAX); // if we're doing a lightgun reload hack, override the value if (m_device.devclass() == DEVICE_CLASS_LIGHTGUN && m_device.lightgun_reload_button()) @@ -985,16 +985,16 @@ s32 input_device_absolute_item::read_as_absolute(input_item_modifier modifier) // if it is pressed, return (min,max) input_device_item *button2_item = m_device.item(ITEM_ID_BUTTON2); if (button2_item != nullptr && button2_item->update_value()) - result = (m_itemid == ITEM_ID_XAXIS) ? INPUT_ABSOLUTE_MIN : INPUT_ABSOLUTE_MAX; + result = (m_itemid == ITEM_ID_XAXIS) ? osd::INPUT_ABSOLUTE_MIN : osd::INPUT_ABSOLUTE_MAX; } // positive/negative: scale to full axis if (modifier == ITEM_MODIFIER_REVERSE) result = -result; else if (modifier == ITEM_MODIFIER_POS) - result = std::max(result, 0) * 2 + INPUT_ABSOLUTE_MIN; + result = std::max(result, 0) * 2 + osd::INPUT_ABSOLUTE_MIN; else if (modifier == ITEM_MODIFIER_NEG) - result = std::max(-result, 0) * 2 + INPUT_ABSOLUTE_MIN; + result = std::max(-result, 0) * 2 + osd::INPUT_ABSOLUTE_MIN; return result; } @@ -1010,9 +1010,9 @@ bool input_device_absolute_item::item_check_axis(input_item_modifier modifier, s // so the selection will not be affected by a gun going out of range const s32 curval = read_as_absolute(modifier); if (m_device.devclass() == DEVICE_CLASS_LIGHTGUN && - (curval == INPUT_ABSOLUTE_MAX || curval == INPUT_ABSOLUTE_MIN)) + (curval == osd::INPUT_ABSOLUTE_MAX || curval == osd::INPUT_ABSOLUTE_MIN)) return false; // for absolute axes, look for 25% of maximum - return std::abs(curval - memory) > ((INPUT_ABSOLUTE_MAX - INPUT_ABSOLUTE_MIN) / 4); + return std::abs(curval - memory) > ((osd::INPUT_ABSOLUTE_MAX - osd::INPUT_ABSOLUTE_MIN) / 4); } diff --git a/src/emu/inputdev.h b/src/emu/inputdev.h index 1b6dabc9bab..78f2b6eeb95 100644 --- a/src/emu/inputdev.h +++ b/src/emu/inputdev.h @@ -13,29 +13,13 @@ #pragma once - -//************************************************************************** -// CONSTANTS -//************************************************************************** - -// relative devices return ~512 units per onscreen pixel -constexpr s32 INPUT_RELATIVE_PER_PIXEL = 512; - -// absolute devices return values between -65536 and +65536 -constexpr s32 INPUT_ABSOLUTE_MIN = -65536; -constexpr s32 INPUT_ABSOLUTE_MAX = 65536; - -// invalid memory value for axis polling -constexpr s32 INVALID_AXIS_VALUE = 0x7fffffff; +#include "interface/inputman.h" //************************************************************************** // TYPE DEFINITIONS //************************************************************************** -// callback for getting the value of an item on a device -typedef s32 (*item_get_state_func)(void *device_internal, void *item_internal); - // ======================> joystick_map // a 9x9 joystick map @@ -88,6 +72,8 @@ private: class input_device_item { public: + using item_get_state_func = osd::input_device::item_get_state_func; + virtual ~input_device_item(); // getters @@ -133,7 +119,7 @@ protected: // ======================> input_device // a logical device of a given class that can provide input -class input_device +class input_device : public osd::input_device { friend class input_class; @@ -159,7 +145,7 @@ public: void set_devindex(int devindex) { m_devindex = devindex; } // item management - input_item_id add_item(std::string_view name, input_item_id itemid, item_get_state_func getstate, void *internal = nullptr); + virtual input_item_id add_item(std::string_view name, input_item_id itemid, item_get_state_func getstate, void *internal) override; // helpers s32 adjust_absolute(s32 value) const { return adjust_absolute_value(value); } diff --git a/src/emu/ioport.cpp b/src/emu/ioport.cpp index 5999a75abe5..1a16accd94c 100644 --- a/src/emu/ioport.cpp +++ b/src/emu/ioport.cpp @@ -3468,8 +3468,8 @@ analog_field::analog_field(ioport_field &field) m_accum(0), m_previous(0), m_previousanalog(0), - m_minimum(INPUT_ABSOLUTE_MIN), - m_maximum(INPUT_ABSOLUTE_MAX), + m_minimum(osd::INPUT_ABSOLUTE_MIN), + m_maximum(osd::INPUT_ABSOLUTE_MAX), m_center(0), m_reverse_val(0), m_scalepos(0), @@ -3512,7 +3512,7 @@ analog_field::analog_field(ioport_field &field) case IPT_PEDAL: case IPT_PEDAL2: case IPT_PEDAL3: - m_center = INPUT_ABSOLUTE_MIN; + m_center = osd::INPUT_ABSOLUTE_MIN; m_accum = apply_inverse_sensitivity(m_center); m_absolute = true; m_autocenter = true; @@ -3531,7 +3531,7 @@ analog_field::analog_field(ioport_field &field) // set each position to be 512 units case IPT_POSITIONAL: case IPT_POSITIONAL_V: - m_positionalscale = compute_scale(field.maxval(), INPUT_ABSOLUTE_MAX - INPUT_ABSOLUTE_MIN); + m_positionalscale = compute_scale(field.maxval(), osd::INPUT_ABSOLUTE_MAX - osd::INPUT_ABSOLUTE_MIN); m_adjmin = 0; m_adjmax = field.maxval() - 1; m_wraps = field.analog_wraps(); @@ -3567,8 +3567,8 @@ analog_field::analog_field(ioport_field &field) if (!m_single_scale) { // unsigned - m_scalepos = compute_scale(m_adjmax - m_adjdefvalue, INPUT_ABSOLUTE_MAX - 0); - m_scaleneg = compute_scale(m_adjdefvalue - m_adjmin, 0 - INPUT_ABSOLUTE_MIN); + m_scalepos = compute_scale(m_adjmax - m_adjdefvalue, osd::INPUT_ABSOLUTE_MAX - 0); + m_scaleneg = compute_scale(m_adjdefvalue - m_adjmin, 0 - osd::INPUT_ABSOLUTE_MIN); if (m_adjmin > m_adjmax) m_scaleneg = -m_scaleneg; @@ -3579,7 +3579,7 @@ analog_field::analog_field(ioport_field &field) else { // single axis that increases from default - m_scalepos = compute_scale(m_adjmax - m_adjmin, INPUT_ABSOLUTE_MAX - INPUT_ABSOLUTE_MIN); + m_scalepos = compute_scale(m_adjmax - m_adjmin, osd::INPUT_ABSOLUTE_MAX - osd::INPUT_ABSOLUTE_MIN); // make the scaling the same for easier coding when we need to scale m_scaleneg = m_scalepos; @@ -3603,11 +3603,11 @@ analog_field::analog_field(ioport_field &field) if (m_wraps) m_adjmax++; - m_minimum = (m_adjmin - m_adjdefvalue) * INPUT_RELATIVE_PER_PIXEL; - m_maximum = (m_adjmax - m_adjdefvalue) * INPUT_RELATIVE_PER_PIXEL; + m_minimum = (m_adjmin - m_adjdefvalue) * osd::INPUT_RELATIVE_PER_PIXEL; + m_maximum = (m_adjmax - m_adjdefvalue) * osd::INPUT_RELATIVE_PER_PIXEL; // make the scaling the same for easier coding when we need to scale - m_scaleneg = m_scalepos = compute_scale(1, INPUT_RELATIVE_PER_PIXEL); + m_scaleneg = m_scalepos = compute_scale(1, osd::INPUT_RELATIVE_PER_PIXEL); if (m_field.analog_reset()) // delta values reverse from center @@ -3620,11 +3620,11 @@ analog_field::analog_field(ioport_field &field) // relative controls reverse from 1 past their max range if (m_wraps) { - // FIXME: positional needs -1, using INPUT_RELATIVE_PER_PIXEL skips a position (and reads outside the table array) + // FIXME: positional needs -1, using osd::INPUT_RELATIVE_PER_PIXEL skips a position (and reads outside the table array) if(field.type() == IPT_POSITIONAL || field.type() == IPT_POSITIONAL_V) m_reverse_val --; else - m_reverse_val -= INPUT_RELATIVE_PER_PIXEL; + m_reverse_val -= osd::INPUT_RELATIVE_PER_PIXEL; } } } @@ -3697,7 +3697,7 @@ s32 analog_field::apply_settings(s32 value) const else if (m_single_scale) // it's a pedal or the default value is equal to min/max // so we need to adjust the center to the minimum - value -= INPUT_ABSOLUTE_MIN; + value -= osd::INPUT_ABSOLUTE_MIN; // map differently for positive and negative values if (value >= 0) @@ -3802,7 +3802,7 @@ void analog_field::frame_update(running_machine &machine) // if port is positional, we will take the full analog control and divide it // into positions, that way as the control is moved full scale, // it moves through all the positions - rawvalue = apply_scale(rawvalue - INPUT_ABSOLUTE_MIN, m_positionalscale) * INPUT_RELATIVE_PER_PIXEL + m_minimum; + rawvalue = apply_scale(rawvalue - osd::INPUT_ABSOLUTE_MIN, m_positionalscale) * osd::INPUT_RELATIVE_PER_PIXEL + m_minimum; // clamp the high value so it does not roll over rawvalue = std::min(rawvalue, m_maximum); diff --git a/src/emu/schedule.cpp b/src/emu/schedule.cpp index cc69a542914..462fd5bb6a0 100644 --- a/src/emu/schedule.cpp +++ b/src/emu/schedule.cpp @@ -72,19 +72,24 @@ emu_timer::~emu_timer() // re-allocated as a non-device timer //------------------------------------------------- -emu_timer &emu_timer::init(running_machine &machine, timer_expired_delegate &&callback, bool temporary) +emu_timer &emu_timer::init( + running_machine &machine, + timer_expired_delegate &&callback, + attotime start_delay, + int param, + bool temporary) { // ensure the entire timer state is clean m_machine = &machine; m_next = nullptr; m_prev = nullptr; m_callback = std::move(callback); - m_param = 0; - m_enabled = false; + m_param = param; m_temporary = temporary; m_period = attotime::never; - m_start = machine.time(); - m_expire = attotime::never; + m_start = machine.scheduler().time(); + m_expire = m_start + start_delay; + m_enabled = !m_expire.is_never(); // if we're not temporary, register ourselves with the save state system if (!m_temporary) @@ -202,6 +207,7 @@ void emu_timer::register_save() int index = 0; std::string name = m_callback.name() ? m_callback.name() : "unnamed"; for (emu_timer *curtimer = machine().scheduler().first_timer(); curtimer != nullptr; curtimer = curtimer->next()) + { if (!curtimer->m_temporary) { if (curtimer->m_callback.name() != nullptr && m_callback.name() != nullptr && strcmp(curtimer->m_callback.name(), m_callback.name()) == 0) @@ -209,6 +215,16 @@ void emu_timer::register_save() else if (curtimer->m_callback.name() == nullptr && m_callback.name() == nullptr) index++; } + } + for (emu_timer *curtimer = machine().scheduler().m_inactive_timers; curtimer != nullptr; curtimer = curtimer->next()) + { + assert(!curtimer->m_temporary); + + if (curtimer->m_callback.name() != nullptr && m_callback.name() != nullptr && strcmp(curtimer->m_callback.name(), m_callback.name()) == 0) + index++; + else if (curtimer->m_callback.name() == nullptr && m_callback.name() == nullptr) + index++; + } // save the bits machine().save().save_item(nullptr, "timer", name.c_str(), index, NAME(m_param)); @@ -267,6 +283,7 @@ device_scheduler::device_scheduler(running_machine &machine) : m_execute_list(nullptr), m_basetime(attotime::zero), m_timer_list(nullptr), + m_inactive_timers(nullptr), m_callback_timer(nullptr), m_callback_timer_modified(false), m_callback_timer_expire_time(attotime::zero), @@ -274,8 +291,13 @@ device_scheduler::device_scheduler(running_machine &machine) : m_quantum_minimum(ATTOSECONDS_IN_NSEC(1) / 1000) { // append a single never-expiring timer so there is always one in the list - m_timer_list = &m_timer_allocator.alloc()->init(machine, timer_expired_delegate(), true); - m_timer_list->adjust(attotime::never); + // need to subvert it because it would naturally be inserted in the inactive list + m_timer_list = &timer_list_remove(m_timer_allocator.alloc()->init(machine, timer_expired_delegate(), attotime::never, 0, true)); + + assert(m_timer_list); + assert(!m_timer_list->m_prev); + assert(!m_timer_list->m_next); + assert(!m_inactive_timers); // register global states machine.save().save_item(NAME(m_basetime)); @@ -291,7 +313,9 @@ device_scheduler::device_scheduler(running_machine &machine) : device_scheduler::~device_scheduler() { // remove all timers - while (m_timer_list != nullptr) + while (m_inactive_timers) + m_timer_allocator.reclaim(m_inactive_timers->release()); + while (m_timer_list) m_timer_allocator.reclaim(m_timer_list->release()); } @@ -536,19 +560,7 @@ void device_scheduler::boost_interleave(const attotime ×lice_time, const at emu_timer *device_scheduler::timer_alloc(timer_expired_delegate callback) { - return &m_timer_allocator.alloc()->init(machine(), std::move(callback), false); -} - - -//------------------------------------------------- -// timer_set - allocate an anonymous non-device -// timer and set it to go off after the given -// amount of time -//------------------------------------------------- - -void device_scheduler::timer_set(const attotime &duration, timer_expired_delegate callback, int param) -{ - m_timer_allocator.alloc()->init(machine(), std::move(callback), true).adjust(duration, param); + return &m_timer_allocator.alloc()->init(machine(), std::move(callback), attotime::never, 0, false); } @@ -597,19 +609,36 @@ void device_scheduler::postload() { // remove all timers and make a private list of permanent ones simple_list private_list; - while (m_timer_list != nullptr) + while (m_inactive_timers) + { + emu_timer &timer = *m_inactive_timers; + assert(!timer.m_temporary); + + private_list.append(timer_list_remove(timer)); + } + while (m_timer_list->m_next) { emu_timer &timer = *m_timer_list; - // temporary timers go away entirely (except our special never-expiring one) if (timer.m_temporary && !timer.expire().is_never()) - m_timer_allocator.reclaim(timer.release()); + { + assert(!timer.expire().is_never()); - // permanent ones get added to our private list + // temporary timers go away entirely (except our special never-expiring one) + m_timer_allocator.reclaim(timer.release()); + } else + { + // permanent ones get added to our private list private_list.append(timer_list_remove(timer)); + } } + // special dummy timer + assert(!m_timer_list->m_enabled); + assert(m_timer_list->m_temporary); + assert(m_timer_list->m_expire.is_never()); + // now re-insert them; this effectively re-sorts them by time emu_timer *timer; while ((timer = private_list.detach_head()) != nullptr) @@ -729,38 +758,50 @@ void device_scheduler::rebuild_execute_list() inline emu_timer &device_scheduler::timer_list_insert(emu_timer &timer) { - // disabled timers sort to the end - const attotime expire = timer.m_enabled ? timer.m_expire : attotime::never; - - // loop over the timer list - emu_timer *prevtimer = nullptr; - for (emu_timer *curtimer = m_timer_list; curtimer != nullptr; prevtimer = curtimer, curtimer = curtimer->next()) + // disabled timers never expire + if (!timer.m_expire.is_never() && timer.m_enabled) { - // if the current list entry expires after us, we should be inserted before it - if (curtimer->m_expire > expire) + // loop over the timer list + emu_timer *prevtimer = nullptr; + for (emu_timer *curtimer = m_timer_list; curtimer; prevtimer = curtimer, curtimer = curtimer->next()) { - // link the new guy in before the current list entry - timer.m_prev = prevtimer; - timer.m_next = curtimer; + // if the current list entry expires after us, we should be inserted before it + if (curtimer->m_expire > timer.m_expire) + { + // link the new guy in before the current list entry + timer.m_prev = prevtimer; + timer.m_next = curtimer; - if (prevtimer != nullptr) - prevtimer->m_next = &timer; - else - m_timer_list = &timer; + if (prevtimer) + prevtimer->m_next = &timer; + else + m_timer_list = &timer; - curtimer->m_prev = &timer; - return timer; + curtimer->m_prev = &timer; + return timer; + } } - } - // need to insert after the last one - if (prevtimer != nullptr) - prevtimer->m_next = &timer; + // need to insert after the last one + if (prevtimer) + prevtimer->m_next = &timer; + else + m_timer_list = &timer; + + timer.m_prev = prevtimer; + timer.m_next = nullptr; + } else - m_timer_list = &timer; + { + // keep inactive timers in a separate list + if (m_inactive_timers) + m_inactive_timers->m_prev = &timer; - timer.m_prev = prevtimer; - timer.m_next = nullptr; + timer.m_next = m_inactive_timers; + timer.m_prev = nullptr; + + m_inactive_timers = &timer; + } return timer; } @@ -773,12 +814,21 @@ inline emu_timer &device_scheduler::timer_list_insert(emu_timer &timer) inline emu_timer &device_scheduler::timer_list_remove(emu_timer &timer) { // remove it from the list - if (timer.m_prev != nullptr) + if (timer.m_prev) + { timer.m_prev->m_next = timer.m_next; - else + } + else if (&timer == m_timer_list) + { m_timer_list = timer.m_next; + } + else + { + assert(&timer == m_inactive_timers); + m_inactive_timers = timer.m_next; + } - if (timer.m_next != nullptr) + if (timer.m_next) timer.m_next->m_prev = timer.m_prev; return timer; @@ -824,13 +874,16 @@ inline void device_scheduler::execute_timers() // reset or remove the timer, but only if it wasn't modified during the callback if (!m_callback_timer_modified) { - // if the timer is temporary, remove it now - if (timer.m_temporary) - m_timer_allocator.reclaim(timer.release()); - - // otherwise, reschedule it - else + if (!timer.m_temporary) + { + // if the timer is not temporary, reschedule it timer.schedule_next_period(); + } + else + { + // otherwise, remove it now + m_timer_allocator.reclaim(timer.release()); + } } } diff --git a/src/emu/schedule.h b/src/emu/schedule.h index dbaca005572..02c1024ffe8 100644 --- a/src/emu/schedule.h +++ b/src/emu/schedule.h @@ -45,7 +45,12 @@ class emu_timer ~emu_timer(); // allocation and re-use - emu_timer &init(running_machine &machine, timer_expired_delegate &&callback, bool temporary) ATTR_HOT; + emu_timer &init( + running_machine &machine, + timer_expired_delegate &&callback, + attotime start_delay, + int param, + bool temporary) ATTR_HOT; emu_timer &release(); public: @@ -119,9 +124,15 @@ public: // timers, specified by callback/name emu_timer *timer_alloc(timer_expired_delegate callback); [[deprecated("timer_set is deprecated; please avoid anonymous timers. Use TIMER_CALLBACK_MEMBER and an allocated emu_timer instead.")]] - void timer_set(const attotime &duration, timer_expired_delegate callback, int param = 0); + void timer_set(const attotime &duration, timer_expired_delegate callback, int param = 0) + { + emu_timer &timer = m_timer_allocator.alloc()->init(machine(), std::move(callback), duration, param, true); + assert(!timer.m_expire.is_never()); // this is not handled + } void synchronize(timer_expired_delegate callback = timer_expired_delegate(), int param = 0) - { m_timer_allocator.alloc()->init(machine(), std::move(callback), true).adjust(attotime::zero, param); } + { + m_timer_allocator.alloc()->init(machine(), std::move(callback), attotime::zero, param, true); + } // debugging void dump_timers() const; @@ -154,6 +165,7 @@ private: // list of active timers emu_timer * m_timer_list; // head of the active list + emu_timer * m_inactive_timers; // head of the inactive timer list fixed_allocator m_timer_allocator; // allocator for timers // other internal states diff --git a/src/emu/sound.cpp b/src/emu/sound.cpp index c1932099be6..b74ff652b65 100644 --- a/src/emu/sound.cpp +++ b/src/emu/sound.cpp @@ -9,21 +9,22 @@ ***************************************************************************/ #include "emu.h" + #include "speaker.h" #include "emuopts.h" #include "osdepend.h" #include "config.h" #include "wavwrite.h" -#include //************************************************************************** // DEBUGGING //************************************************************************** -#define VERBOSE (0) +//#define VERBOSE 1 +#define LOG_OUTPUT_FUNC osd_printf_debug -#define VPRINTF(x) do { if (VERBOSE) osd_printf_debug x; } while (0) +#include "logmacro.h" #define LOG_OUTPUT_WAV (0) @@ -651,8 +652,8 @@ void sound_stream::set_sample_rate(u32 new_rate) void sound_stream::set_input(int index, sound_stream *input_stream, int output_index, float gain) { - VPRINTF(("stream_set_input(%p, '%s', %d, %p, %d, %f)\n", (void *)this, m_device.tag(), - index, (void *)input_stream, output_index, (double) gain)); + LOG("stream_set_input(%p, '%s', %d, %p, %d, %f)\n", (void *)this, m_device.tag(), + index, (void *)input_stream, output_index, gain); // make sure it's a valid input if (index >= m_input.size()) @@ -1100,7 +1101,7 @@ sound_manager::sound_manager(running_machine &machine) : // count the mixers #if VERBOSE mixer_interface_enumerator iter(machine.root_device()); - VPRINTF(("total mixers = %d\n", iter.count())); + LOG("total mixers = %d\n", iter.count()); #endif // register callbacks @@ -1472,7 +1473,7 @@ stream_buffer::sample_t sound_manager::adjust_toward_compressor_scale(stream_buf void sound_manager::update(int param) { - VPRINTF(("sound_update\n")); + LOG("sound_update\n"); g_profiler.start(PROFILER_SOUND); diff --git a/src/frontend/mame/ui/inputdevices.cpp b/src/frontend/mame/ui/inputdevices.cpp index e1e39f0467f..6dba1d49f92 100644 --- a/src/frontend/mame/ui/inputdevices.cpp +++ b/src/frontend/mame/ui/inputdevices.cpp @@ -58,12 +58,12 @@ protected: s32 const value = (input.itemclass() == ITEM_CLASS_ABSOLUTE) ? input.read_as_absolute(ITEM_MODIFIER_NONE) : input.read_as_relative(ITEM_MODIFIER_NONE); if (0 < value) { - float const fillright = indcentre + (float(value) / float(INPUT_ABSOLUTE_MAX) * (indright - indcentre)); + float const fillright = indcentre + (float(value) / float(osd::INPUT_ABSOLUTE_MAX) * (indright - indcentre)); container().add_rect(indcentre, indtop, (std::min)(fillright, indright), indbottom, fgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } else if (0 > value) { - float const fillleft = indcentre - (float(value) / float(INPUT_ABSOLUTE_MIN) * (indcentre - indleft)); + float const fillleft = indcentre - (float(value) / float(osd::INPUT_ABSOLUTE_MIN) * (indcentre - indleft)); container().add_rect((std::max)(fillleft, indleft), indtop, indcentre, indbottom, fgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); } container().add_line(indleft, indtop, indright, indtop, UI_LINE_WIDTH, fgcolor, PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA)); diff --git a/src/lib/util/endianness.h b/src/lib/util/endianness.h index cef615fcb87..d983afe8c6b 100644 --- a/src/lib/util/endianness.h +++ b/src/lib/util/endianness.h @@ -13,7 +13,11 @@ #pragma once +#include +#include +#include #include +#include namespace util { @@ -34,6 +38,24 @@ enum class endianness #endif }; +// helper for accessing data adjusted for endianness +template +class endian_cast +{ +private: + static inline constexpr std::ptrdiff_t SWIZZLE = (sizeof(In) / sizeof(Out)) - 1; + + static_assert(!(sizeof(In) % sizeof(Out)), "input size must be a multiple of output size"); + static_assert(!((sizeof(In) / sizeof(Out)) & SWIZZLE), "ratio of input size to output size must be a power of two"); + + Out *m_ptr; + +public: + constexpr endian_cast(In *ptr) noexcept : m_ptr(reinterpret_cast(ptr)) { } + + constexpr Out &operator[](std::ptrdiff_t i) const noexcept { return m_ptr[i ^ ((Endian != endianness::native) ? SWIZZLE : 0)]; } +}; + //************************************************************************** // MACROS AND INLINE FUNCTIONS @@ -42,11 +64,27 @@ enum class endianness constexpr std::string_view endian_to_string_view(endianness e) { using namespace std::literals; return e == endianness::little ? "little"sv : "big"sv; } // endian-based value: first value is if native endianness is little-endian, second is if native is big-endian -#define NATIVE_ENDIAN_VALUE_LE_BE(leval,beval) ((util::endianness::native == util::endianness::little) ? (leval) : (beval)) +#define NATIVE_ENDIAN_VALUE_LE_BE(leval, beval) ((util::endianness::native == util::endianness::little) ? (leval) : (beval)) // inline functions for accessing bytes and words within larger chunks +template +auto big_endian_cast(U *ptr) +{ + using requested_const = std::conditional_t, std::add_const_t, T>; + using requested_cv = std::conditional_t, std::add_volatile, requested_const>; + return endian_cast(ptr); +} + +template +auto little_endian_cast(U *ptr) +{ + using requested_const = std::conditional_t, std::add_const_t, T>; + using requested_cv = std::conditional_t, std::add_volatile, requested_const>; + return endian_cast(ptr); +} + // read/write a byte to a 16-bit space template constexpr T BYTE_XOR_BE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0); } template constexpr T BYTE_XOR_LE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(0,1); } diff --git a/src/mame/drivers/plygonet.cpp b/src/mame/drivers/plygonet.cpp index f4a28cffced..5134048f050 100644 --- a/src/mame/drivers/plygonet.cpp +++ b/src/mame/drivers/plygonet.cpp @@ -704,18 +704,18 @@ GFXDECODE_END TILE_GET_INFO_MEMBER(polygonet_state::ttl_get_tile_info) { - const uint16_t *ttl_vram = (uint16_t *)&m_ttl_vram[0]; - const int code = ttl_vram[BYTE_XOR_BE(tile_index)] & 0xfff; - const int attr = ttl_vram[BYTE_XOR_BE(tile_index)] >> 12; // Is the palette in all 4 bits? + const auto ttl_vram = util::big_endian_cast(m_ttl_vram.target()); + const int code = ttl_vram[tile_index] & 0xfff; + const int attr = ttl_vram[tile_index] >> 12; // Is the palette in all 4 bits? tileinfo.set(m_ttl_gfx_index, code, attr, 0); } TILE_GET_INFO_MEMBER(polygonet_state::roz_get_tile_info) { - const uint16_t *roz_vram = (uint16_t *)&m_roz_vram[0]; - const int code = roz_vram[BYTE_XOR_BE(tile_index)] & 0x3ff; - const int attr = (roz_vram[BYTE_XOR_BE(tile_index)] >> 12) + 16; // ROZ base palette is palette index 16 onward + const auto roz_vram = util::big_endian_cast(m_roz_vram.target()); + const int code = roz_vram[tile_index] & 0x3ff; + const int attr = (roz_vram[tile_index] >> 12) + 16; // ROZ base palette is palette index 16 onward tileinfo.set(0, code, attr, 0); } diff --git a/src/osd/interface/inputcode.h b/src/osd/interface/inputcode.h new file mode 100644 index 00000000000..1d5b1156ae5 --- /dev/null +++ b/src/osd/interface/inputcode.h @@ -0,0 +1,872 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + inputcode.h + + Codes for representing host inputs + +***************************************************************************/ +#ifndef MAME_OSD_INTERFACE_INPUTCODE_H +#define MAME_OSD_INTERFACE_INPUTCODE_H + +#pragma once + +#include "osdcomm.h" + +#include + + +//************************************************************************** +// CONSTANTS +//************************************************************************** + +// maximum number of axis/buttons/hats with ITEM_IDs for use by osd layer +constexpr int INPUT_MAX_AXIS = 8; +constexpr int INPUT_MAX_BUTTONS = 32; +constexpr int INPUT_MAX_HATS = 4; +constexpr int INPUT_MAX_ADD_SWITCH = 16; +constexpr int INPUT_MAX_ADD_ABSOLUTE = 16; +constexpr int INPUT_MAX_ADD_RELATIVE = 16; + + +// device classes +enum input_device_class +{ + DEVICE_CLASS_INVALID, + DEVICE_CLASS_FIRST_VALID, + DEVICE_CLASS_KEYBOARD = DEVICE_CLASS_FIRST_VALID, + DEVICE_CLASS_MOUSE, + DEVICE_CLASS_LIGHTGUN, + DEVICE_CLASS_JOYSTICK, + DEVICE_CLASS_LAST_VALID = DEVICE_CLASS_JOYSTICK, + DEVICE_CLASS_INTERNAL, + DEVICE_CLASS_MAXIMUM +}; +DECLARE_ENUM_INCDEC_OPERATORS(input_device_class) + + +// device index +constexpr int DEVICE_INDEX_MAXIMUM = 0xff; + + +// input item classes +enum input_item_class +{ + ITEM_CLASS_INVALID, + ITEM_CLASS_SWITCH, + ITEM_CLASS_ABSOLUTE, + ITEM_CLASS_RELATIVE, + ITEM_CLASS_MAXIMUM +}; + + +// input item modifiers +enum input_item_modifier +{ + ITEM_MODIFIER_NONE, + ITEM_MODIFIER_REVERSE, + ITEM_MODIFIER_POS, + ITEM_MODIFIER_NEG, + ITEM_MODIFIER_LEFT, + ITEM_MODIFIER_RIGHT, + ITEM_MODIFIER_UP, + ITEM_MODIFIER_DOWN, + ITEM_MODIFIER_MAXIMUM +}; + + +// standard item IDs +enum input_item_id +{ + ITEM_ID_INVALID, + ITEM_ID_FIRST_VALID, + + // standard keyboard IDs + ITEM_ID_A = ITEM_ID_FIRST_VALID, + ITEM_ID_B, + ITEM_ID_C, + ITEM_ID_D, + ITEM_ID_E, + ITEM_ID_F, + ITEM_ID_G, + ITEM_ID_H, + ITEM_ID_I, + ITEM_ID_J, + ITEM_ID_K, + ITEM_ID_L, + ITEM_ID_M, + ITEM_ID_N, + ITEM_ID_O, + ITEM_ID_P, + ITEM_ID_Q, + ITEM_ID_R, + ITEM_ID_S, + ITEM_ID_T, + ITEM_ID_U, + ITEM_ID_V, + ITEM_ID_W, + ITEM_ID_X, + ITEM_ID_Y, + ITEM_ID_Z, + ITEM_ID_0, + ITEM_ID_1, + ITEM_ID_2, + ITEM_ID_3, + ITEM_ID_4, + ITEM_ID_5, + ITEM_ID_6, + ITEM_ID_7, + ITEM_ID_8, + ITEM_ID_9, + ITEM_ID_F1, + ITEM_ID_F2, + ITEM_ID_F3, + ITEM_ID_F4, + ITEM_ID_F5, + ITEM_ID_F6, + ITEM_ID_F7, + ITEM_ID_F8, + ITEM_ID_F9, + ITEM_ID_F10, + ITEM_ID_F11, + ITEM_ID_F12, + ITEM_ID_F13, + ITEM_ID_F14, + ITEM_ID_F15, + ITEM_ID_F16, + ITEM_ID_F17, + ITEM_ID_F18, + ITEM_ID_F19, + ITEM_ID_F20, + ITEM_ID_ESC, + ITEM_ID_TILDE, + ITEM_ID_MINUS, + ITEM_ID_EQUALS, + ITEM_ID_BACKSPACE, + ITEM_ID_TAB, + ITEM_ID_OPENBRACE, + ITEM_ID_CLOSEBRACE, + ITEM_ID_ENTER, + ITEM_ID_COLON, + ITEM_ID_QUOTE, + ITEM_ID_BACKSLASH, + ITEM_ID_BACKSLASH2, + ITEM_ID_COMMA, + ITEM_ID_STOP, + ITEM_ID_SLASH, + ITEM_ID_SPACE, + ITEM_ID_INSERT, + ITEM_ID_DEL, + ITEM_ID_HOME, + ITEM_ID_END, + ITEM_ID_PGUP, + ITEM_ID_PGDN, + ITEM_ID_LEFT, + ITEM_ID_RIGHT, + ITEM_ID_UP, + ITEM_ID_DOWN, + ITEM_ID_0_PAD, + ITEM_ID_1_PAD, + ITEM_ID_2_PAD, + ITEM_ID_3_PAD, + ITEM_ID_4_PAD, + ITEM_ID_5_PAD, + ITEM_ID_6_PAD, + ITEM_ID_7_PAD, + ITEM_ID_8_PAD, + ITEM_ID_9_PAD, + ITEM_ID_SLASH_PAD, + ITEM_ID_ASTERISK, + ITEM_ID_MINUS_PAD, + ITEM_ID_PLUS_PAD, + ITEM_ID_DEL_PAD, + ITEM_ID_ENTER_PAD, + ITEM_ID_BS_PAD, + ITEM_ID_TAB_PAD, + ITEM_ID_00_PAD, + ITEM_ID_000_PAD, + ITEM_ID_COMMA_PAD, + ITEM_ID_EQUALS_PAD, + ITEM_ID_PRTSCR, + ITEM_ID_PAUSE, + ITEM_ID_LSHIFT, + ITEM_ID_RSHIFT, + ITEM_ID_LCONTROL, + ITEM_ID_RCONTROL, + ITEM_ID_LALT, + ITEM_ID_RALT, + ITEM_ID_SCRLOCK, + ITEM_ID_NUMLOCK, + ITEM_ID_CAPSLOCK, + ITEM_ID_LWIN, + ITEM_ID_RWIN, + ITEM_ID_MENU, + ITEM_ID_CANCEL, + + // standard mouse/joystick/gun IDs + ITEM_ID_XAXIS, + ITEM_ID_YAXIS, + ITEM_ID_ZAXIS, + ITEM_ID_RXAXIS, + ITEM_ID_RYAXIS, + ITEM_ID_RZAXIS, + ITEM_ID_SLIDER1, + ITEM_ID_SLIDER2, + ITEM_ID_BUTTON1, + ITEM_ID_BUTTON2, + ITEM_ID_BUTTON3, + ITEM_ID_BUTTON4, + ITEM_ID_BUTTON5, + ITEM_ID_BUTTON6, + ITEM_ID_BUTTON7, + ITEM_ID_BUTTON8, + ITEM_ID_BUTTON9, + ITEM_ID_BUTTON10, + ITEM_ID_BUTTON11, + ITEM_ID_BUTTON12, + ITEM_ID_BUTTON13, + ITEM_ID_BUTTON14, + ITEM_ID_BUTTON15, + ITEM_ID_BUTTON16, + ITEM_ID_BUTTON17, + ITEM_ID_BUTTON18, + ITEM_ID_BUTTON19, + ITEM_ID_BUTTON20, + ITEM_ID_BUTTON21, + ITEM_ID_BUTTON22, + ITEM_ID_BUTTON23, + ITEM_ID_BUTTON24, + ITEM_ID_BUTTON25, + ITEM_ID_BUTTON26, + ITEM_ID_BUTTON27, + ITEM_ID_BUTTON28, + ITEM_ID_BUTTON29, + ITEM_ID_BUTTON30, + ITEM_ID_BUTTON31, + ITEM_ID_BUTTON32, + ITEM_ID_START, + ITEM_ID_SELECT, + + // Hats + ITEM_ID_HAT1UP, + ITEM_ID_HAT1DOWN, + ITEM_ID_HAT1LEFT, + ITEM_ID_HAT1RIGHT, + ITEM_ID_HAT2UP, + ITEM_ID_HAT2DOWN, + ITEM_ID_HAT2LEFT, + ITEM_ID_HAT2RIGHT, + ITEM_ID_HAT3UP, + ITEM_ID_HAT3DOWN, + ITEM_ID_HAT3LEFT, + ITEM_ID_HAT3RIGHT, + ITEM_ID_HAT4UP, + ITEM_ID_HAT4DOWN, + ITEM_ID_HAT4LEFT, + ITEM_ID_HAT4RIGHT, + + // Additional IDs + ITEM_ID_ADD_SWITCH1, + ITEM_ID_ADD_SWITCH2, + ITEM_ID_ADD_SWITCH3, + ITEM_ID_ADD_SWITCH4, + ITEM_ID_ADD_SWITCH5, + ITEM_ID_ADD_SWITCH6, + ITEM_ID_ADD_SWITCH7, + ITEM_ID_ADD_SWITCH8, + ITEM_ID_ADD_SWITCH9, + ITEM_ID_ADD_SWITCH10, + ITEM_ID_ADD_SWITCH11, + ITEM_ID_ADD_SWITCH12, + ITEM_ID_ADD_SWITCH13, + ITEM_ID_ADD_SWITCH14, + ITEM_ID_ADD_SWITCH15, + ITEM_ID_ADD_SWITCH16, + + ITEM_ID_ADD_ABSOLUTE1, + ITEM_ID_ADD_ABSOLUTE2, + ITEM_ID_ADD_ABSOLUTE3, + ITEM_ID_ADD_ABSOLUTE4, + ITEM_ID_ADD_ABSOLUTE5, + ITEM_ID_ADD_ABSOLUTE6, + ITEM_ID_ADD_ABSOLUTE7, + ITEM_ID_ADD_ABSOLUTE8, + ITEM_ID_ADD_ABSOLUTE9, + ITEM_ID_ADD_ABSOLUTE10, + ITEM_ID_ADD_ABSOLUTE11, + ITEM_ID_ADD_ABSOLUTE12, + ITEM_ID_ADD_ABSOLUTE13, + ITEM_ID_ADD_ABSOLUTE14, + ITEM_ID_ADD_ABSOLUTE15, + ITEM_ID_ADD_ABSOLUTE16, + + ITEM_ID_ADD_RELATIVE1, + ITEM_ID_ADD_RELATIVE2, + ITEM_ID_ADD_RELATIVE3, + ITEM_ID_ADD_RELATIVE4, + ITEM_ID_ADD_RELATIVE5, + ITEM_ID_ADD_RELATIVE6, + ITEM_ID_ADD_RELATIVE7, + ITEM_ID_ADD_RELATIVE8, + ITEM_ID_ADD_RELATIVE9, + ITEM_ID_ADD_RELATIVE10, + ITEM_ID_ADD_RELATIVE11, + ITEM_ID_ADD_RELATIVE12, + ITEM_ID_ADD_RELATIVE13, + ITEM_ID_ADD_RELATIVE14, + ITEM_ID_ADD_RELATIVE15, + ITEM_ID_ADD_RELATIVE16, + + // generic other IDs + ITEM_ID_OTHER_SWITCH, + ITEM_ID_OTHER_AXIS_ABSOLUTE, + ITEM_ID_OTHER_AXIS_RELATIVE, + ITEM_ID_MAXIMUM, + + // internal codes for sequences + ITEM_ID_SEQ_END, + ITEM_ID_SEQ_DEFAULT, + ITEM_ID_SEQ_NOT, + ITEM_ID_SEQ_OR, + + // absolute maximum ID + ITEM_ID_ABSOLUTE_MAXIMUM = 0xfff +}; +DECLARE_ENUM_INCDEC_OPERATORS(input_item_id) + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// a combined code that describes a particular input on a particular device + +class input_code +{ +public: + // construction/destruction + constexpr input_code( + input_device_class devclass = DEVICE_CLASS_INVALID, + int devindex = 0, + input_item_class itemclass = ITEM_CLASS_INVALID, + input_item_modifier modifier = ITEM_MODIFIER_NONE, + input_item_id itemid = ITEM_ID_INVALID) noexcept + : m_internal(((devclass & 0xf) << 28) | ((devindex & 0xff) << 20) | ((itemclass & 0xf) << 16) | ((modifier & 0xf) << 12) | (itemid & 0xfff)) + { + assert(devclass >= 0 && devclass < DEVICE_CLASS_MAXIMUM); + assert(devindex >= 0 && devindex < DEVICE_INDEX_MAXIMUM); + assert(itemclass >= 0 && itemclass < ITEM_CLASS_MAXIMUM); + assert(modifier >= 0 && modifier < ITEM_MODIFIER_MAXIMUM); + assert(itemid >= 0 && itemid < ITEM_ID_ABSOLUTE_MAXIMUM); + } + constexpr input_code(const input_code &src) noexcept = default; + + // operators + constexpr bool operator==(const input_code &rhs) const noexcept { return m_internal == rhs.m_internal; } + constexpr bool operator!=(const input_code &rhs) const noexcept { return m_internal != rhs.m_internal; } + constexpr bool operator<(const input_code &rhs) const noexcept { return m_internal < rhs.m_internal; } + + // getters + constexpr bool internal() const noexcept { return device_class() == DEVICE_CLASS_INTERNAL; } + constexpr input_device_class device_class() const noexcept { return input_device_class((m_internal >> 28) & 0xf); } + constexpr int device_index() const noexcept { return ((m_internal >> 20) & 0xff); } + constexpr input_item_class item_class() const noexcept { return input_item_class((m_internal >> 16) & 0xf); } + constexpr input_item_modifier item_modifier() const noexcept { return input_item_modifier((m_internal >> 12) & 0xf); } + constexpr input_item_id item_id() const noexcept { return input_item_id(m_internal & 0xfff); } + + // setters + void set_device_class(input_device_class devclass) noexcept + { + assert(devclass >= 0 && devclass <= 0xf); + m_internal = (m_internal & ~(0xf << 28)) | ((devclass & 0xf) << 28); + } + void set_device_index(int devindex) noexcept + { + assert(devindex >= 0 && devindex <= 0xff); + m_internal = (m_internal & ~(0xff << 20)) | ((devindex & 0xff) << 20); + } + void set_item_class(input_item_class itemclass) noexcept + { + assert(itemclass >= 0 && itemclass <= 0xf); + m_internal = (m_internal & ~(0xf << 16)) | ((itemclass & 0xf) << 16); + } + void set_item_modifier(input_item_modifier modifier) noexcept + { + assert(modifier >= 0 && modifier <= 0xf); + m_internal = (m_internal & ~(0xf << 12)) | ((modifier & 0xf) << 12); + } + void set_item_id(input_item_id itemid) noexcept + { + assert(itemid >= 0 && itemid <= 0xfff); + m_internal = (m_internal & ~0xfff) | (itemid & 0xfff); + } + +private: + osd::u32 m_internal; +}; + + + +//************************************************************************** +// MACROS +//************************************************************************** + +// invalid codes +#define INPUT_CODE_INVALID input_code() + +// keyboard codes +constexpr input_code KEYCODE_A_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_A); } +constexpr input_code KEYCODE_B_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_B); } +constexpr input_code KEYCODE_C_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_C); } +constexpr input_code KEYCODE_D_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_D); } +constexpr input_code KEYCODE_E_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_E); } +constexpr input_code KEYCODE_F_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F); } +constexpr input_code KEYCODE_G_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_G); } +constexpr input_code KEYCODE_H_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_H); } +constexpr input_code KEYCODE_I_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_I); } +constexpr input_code KEYCODE_J_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_J); } +constexpr input_code KEYCODE_K_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_K); } +constexpr input_code KEYCODE_L_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_L); } +constexpr input_code KEYCODE_M_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_M); } +constexpr input_code KEYCODE_N_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_N); } +constexpr input_code KEYCODE_O_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_O); } +constexpr input_code KEYCODE_P_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_P); } +constexpr input_code KEYCODE_Q_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_Q); } +constexpr input_code KEYCODE_R_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_R); } +constexpr input_code KEYCODE_S_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_S); } +constexpr input_code KEYCODE_T_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_T); } +constexpr input_code KEYCODE_U_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_U); } +constexpr input_code KEYCODE_V_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_V); } +constexpr input_code KEYCODE_W_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_W); } +constexpr input_code KEYCODE_X_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_X); } +constexpr input_code KEYCODE_Y_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_Y); } +constexpr input_code KEYCODE_Z_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_Z); } +constexpr input_code KEYCODE_0_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_0); } +constexpr input_code KEYCODE_1_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_1); } +constexpr input_code KEYCODE_2_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_2); } +constexpr input_code KEYCODE_3_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_3); } +constexpr input_code KEYCODE_4_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_4); } +constexpr input_code KEYCODE_5_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_5); } +constexpr input_code KEYCODE_6_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_6); } +constexpr input_code KEYCODE_7_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_7); } +constexpr input_code KEYCODE_8_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_8); } +constexpr input_code KEYCODE_9_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_9); } +constexpr input_code KEYCODE_F1_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F1); } +constexpr input_code KEYCODE_F2_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F2); } +constexpr input_code KEYCODE_F3_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F3); } +constexpr input_code KEYCODE_F4_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F4); } +constexpr input_code KEYCODE_F5_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F5); } +constexpr input_code KEYCODE_F6_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F6); } +constexpr input_code KEYCODE_F7_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F7); } +constexpr input_code KEYCODE_F8_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F8); } +constexpr input_code KEYCODE_F9_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F9); } +constexpr input_code KEYCODE_F10_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F10); } +constexpr input_code KEYCODE_F11_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F11); } +constexpr input_code KEYCODE_F12_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F12); } +constexpr input_code KEYCODE_F13_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F13); } +constexpr input_code KEYCODE_F14_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F14); } +constexpr input_code KEYCODE_F15_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F15); } +constexpr input_code KEYCODE_F16_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F16); } +constexpr input_code KEYCODE_F17_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F17); } +constexpr input_code KEYCODE_F18_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F18); } +constexpr input_code KEYCODE_F19_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F19); } +constexpr input_code KEYCODE_F20_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_F20); } +constexpr input_code KEYCODE_ESC_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_ESC); } +constexpr input_code KEYCODE_TILDE_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_TILDE); } +constexpr input_code KEYCODE_MINUS_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_MINUS); } +constexpr input_code KEYCODE_EQUALS_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_EQUALS); } +constexpr input_code KEYCODE_BACKSPACE_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BACKSPACE); } +constexpr input_code KEYCODE_TAB_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_TAB); } +constexpr input_code KEYCODE_OPENBRACE_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_OPENBRACE); } +constexpr input_code KEYCODE_CLOSEBRACE_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_CLOSEBRACE); } +constexpr input_code KEYCODE_ENTER_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_ENTER); } +constexpr input_code KEYCODE_COLON_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_COLON); } +constexpr input_code KEYCODE_QUOTE_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_QUOTE); } +constexpr input_code KEYCODE_BACKSLASH_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BACKSLASH); } +constexpr input_code KEYCODE_BACKSLASH2_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BACKSLASH2); } +constexpr input_code KEYCODE_COMMA_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_COMMA); } +constexpr input_code KEYCODE_STOP_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_STOP); } +constexpr input_code KEYCODE_SLASH_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_SLASH); } +constexpr input_code KEYCODE_SPACE_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_SPACE); } +constexpr input_code KEYCODE_INSERT_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_INSERT); } +constexpr input_code KEYCODE_DEL_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_DEL); } +constexpr input_code KEYCODE_HOME_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_HOME); } +constexpr input_code KEYCODE_END_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_END); } +constexpr input_code KEYCODE_PGUP_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_PGUP); } +constexpr input_code KEYCODE_PGDN_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_PGDN); } +constexpr input_code KEYCODE_LEFT_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_LEFT); } +constexpr input_code KEYCODE_RIGHT_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_RIGHT); } +constexpr input_code KEYCODE_UP_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_UP); } +constexpr input_code KEYCODE_DOWN_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_DOWN); } +constexpr input_code KEYCODE_0_PAD_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_0_PAD); } +constexpr input_code KEYCODE_1_PAD_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_1_PAD); } +constexpr input_code KEYCODE_2_PAD_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_2_PAD); } +constexpr input_code KEYCODE_3_PAD_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_3_PAD); } +constexpr input_code KEYCODE_4_PAD_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_4_PAD); } +constexpr input_code KEYCODE_5_PAD_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_5_PAD); } +constexpr input_code KEYCODE_6_PAD_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_6_PAD); } +constexpr input_code KEYCODE_7_PAD_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_7_PAD); } +constexpr input_code KEYCODE_8_PAD_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_8_PAD); } +constexpr input_code KEYCODE_9_PAD_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_9_PAD); } +constexpr input_code KEYCODE_SLASH_PAD_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_SLASH_PAD); } +constexpr input_code KEYCODE_ASTERISK_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_ASTERISK); } +constexpr input_code KEYCODE_MINUS_PAD_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_MINUS_PAD); } +constexpr input_code KEYCODE_PLUS_PAD_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_PLUS_PAD); } +constexpr input_code KEYCODE_DEL_PAD_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_DEL_PAD); } +constexpr input_code KEYCODE_ENTER_PAD_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_ENTER_PAD); } +constexpr input_code KEYCODE_BS_PAD_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BS_PAD); } +constexpr input_code KEYCODE_TAB_PAD_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_TAB_PAD); } +constexpr input_code KEYCODE_00_PAD_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_00_PAD); } +constexpr input_code KEYCODE_000_PAD_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_000_PAD); } +constexpr input_code KEYCODE_COMMA_PAD_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_COMMA_PAD); } +constexpr input_code KEYCODE_EQUALS_PAD_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_EQUALS_PAD); } +constexpr input_code KEYCODE_PRTSCR_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_PRTSCR); } +constexpr input_code KEYCODE_PAUSE_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_PAUSE); } +constexpr input_code KEYCODE_LSHIFT_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_LSHIFT); } +constexpr input_code KEYCODE_RSHIFT_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_RSHIFT); } +constexpr input_code KEYCODE_LCONTROL_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_LCONTROL); } +constexpr input_code KEYCODE_RCONTROL_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_RCONTROL); } +constexpr input_code KEYCODE_LALT_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_LALT); } +constexpr input_code KEYCODE_RALT_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_RALT); } +constexpr input_code KEYCODE_SCRLOCK_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_SCRLOCK); } +constexpr input_code KEYCODE_NUMLOCK_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_NUMLOCK); } +constexpr input_code KEYCODE_CAPSLOCK_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_CAPSLOCK); } +constexpr input_code KEYCODE_LWIN_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_LWIN); } +constexpr input_code KEYCODE_RWIN_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_RWIN); } +constexpr input_code KEYCODE_MENU_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_MENU); } +constexpr input_code KEYCODE_CANCEL_INDEXED(int n) { return input_code(DEVICE_CLASS_KEYBOARD, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_CANCEL); } + +#define KEYCODE_A KEYCODE_A_INDEXED(0) +#define KEYCODE_B KEYCODE_B_INDEXED(0) +#define KEYCODE_C KEYCODE_C_INDEXED(0) +#define KEYCODE_D KEYCODE_D_INDEXED(0) +#define KEYCODE_E KEYCODE_E_INDEXED(0) +#define KEYCODE_F KEYCODE_F_INDEXED(0) +#define KEYCODE_G KEYCODE_G_INDEXED(0) +#define KEYCODE_H KEYCODE_H_INDEXED(0) +#define KEYCODE_I KEYCODE_I_INDEXED(0) +#define KEYCODE_J KEYCODE_J_INDEXED(0) +#define KEYCODE_K KEYCODE_K_INDEXED(0) +#define KEYCODE_L KEYCODE_L_INDEXED(0) +#define KEYCODE_M KEYCODE_M_INDEXED(0) +#define KEYCODE_N KEYCODE_N_INDEXED(0) +#define KEYCODE_O KEYCODE_O_INDEXED(0) +#define KEYCODE_P KEYCODE_P_INDEXED(0) +#define KEYCODE_Q KEYCODE_Q_INDEXED(0) +#define KEYCODE_R KEYCODE_R_INDEXED(0) +#define KEYCODE_S KEYCODE_S_INDEXED(0) +#define KEYCODE_T KEYCODE_T_INDEXED(0) +#define KEYCODE_U KEYCODE_U_INDEXED(0) +#define KEYCODE_V KEYCODE_V_INDEXED(0) +#define KEYCODE_W KEYCODE_W_INDEXED(0) +#define KEYCODE_X KEYCODE_X_INDEXED(0) +#define KEYCODE_Y KEYCODE_Y_INDEXED(0) +#define KEYCODE_Z KEYCODE_Z_INDEXED(0) +#define KEYCODE_0 KEYCODE_0_INDEXED(0) +#define KEYCODE_1 KEYCODE_1_INDEXED(0) +#define KEYCODE_2 KEYCODE_2_INDEXED(0) +#define KEYCODE_3 KEYCODE_3_INDEXED(0) +#define KEYCODE_4 KEYCODE_4_INDEXED(0) +#define KEYCODE_5 KEYCODE_5_INDEXED(0) +#define KEYCODE_6 KEYCODE_6_INDEXED(0) +#define KEYCODE_7 KEYCODE_7_INDEXED(0) +#define KEYCODE_8 KEYCODE_8_INDEXED(0) +#define KEYCODE_9 KEYCODE_9_INDEXED(0) +#define KEYCODE_F1 KEYCODE_F1_INDEXED(0) +#define KEYCODE_F2 KEYCODE_F2_INDEXED(0) +#define KEYCODE_F3 KEYCODE_F3_INDEXED(0) +#define KEYCODE_F4 KEYCODE_F4_INDEXED(0) +#define KEYCODE_F5 KEYCODE_F5_INDEXED(0) +#define KEYCODE_F6 KEYCODE_F6_INDEXED(0) +#define KEYCODE_F7 KEYCODE_F7_INDEXED(0) +#define KEYCODE_F8 KEYCODE_F8_INDEXED(0) +#define KEYCODE_F9 KEYCODE_F9_INDEXED(0) +#define KEYCODE_F10 KEYCODE_F10_INDEXED(0) +#define KEYCODE_F11 KEYCODE_F11_INDEXED(0) +#define KEYCODE_F12 KEYCODE_F12_INDEXED(0) +#define KEYCODE_F13 KEYCODE_F13_INDEXED(0) +#define KEYCODE_F14 KEYCODE_F14_INDEXED(0) +#define KEYCODE_F15 KEYCODE_F15_INDEXED(0) +#define KEYCODE_F16 KEYCODE_F16_INDEXED(0) +#define KEYCODE_F17 KEYCODE_F17_INDEXED(0) +#define KEYCODE_F18 KEYCODE_F18_INDEXED(0) +#define KEYCODE_F19 KEYCODE_F19_INDEXED(0) +#define KEYCODE_F20 KEYCODE_F20_INDEXED(0) +#define KEYCODE_ESC KEYCODE_ESC_INDEXED(0) +#define KEYCODE_TILDE KEYCODE_TILDE_INDEXED(0) +#define KEYCODE_MINUS KEYCODE_MINUS_INDEXED(0) +#define KEYCODE_EQUALS KEYCODE_EQUALS_INDEXED(0) +#define KEYCODE_BACKSPACE KEYCODE_BACKSPACE_INDEXED(0) +#define KEYCODE_TAB KEYCODE_TAB_INDEXED(0) +#define KEYCODE_OPENBRACE KEYCODE_OPENBRACE_INDEXED(0) +#define KEYCODE_CLOSEBRACE KEYCODE_CLOSEBRACE_INDEXED(0) +#define KEYCODE_ENTER KEYCODE_ENTER_INDEXED(0) +#define KEYCODE_COLON KEYCODE_COLON_INDEXED(0) +#define KEYCODE_QUOTE KEYCODE_QUOTE_INDEXED(0) +#define KEYCODE_BACKSLASH KEYCODE_BACKSLASH_INDEXED(0) +#define KEYCODE_BACKSLASH2 KEYCODE_BACKSLASH2_INDEXED(0) +#define KEYCODE_COMMA KEYCODE_COMMA_INDEXED(0) +#define KEYCODE_STOP KEYCODE_STOP_INDEXED(0) +#define KEYCODE_SLASH KEYCODE_SLASH_INDEXED(0) +#define KEYCODE_SPACE KEYCODE_SPACE_INDEXED(0) +#define KEYCODE_INSERT KEYCODE_INSERT_INDEXED(0) +#define KEYCODE_DEL KEYCODE_DEL_INDEXED(0) +#define KEYCODE_HOME KEYCODE_HOME_INDEXED(0) +#define KEYCODE_END KEYCODE_END_INDEXED(0) +#define KEYCODE_PGUP KEYCODE_PGUP_INDEXED(0) +#define KEYCODE_PGDN KEYCODE_PGDN_INDEXED(0) +#define KEYCODE_LEFT KEYCODE_LEFT_INDEXED(0) +#define KEYCODE_RIGHT KEYCODE_RIGHT_INDEXED(0) +#define KEYCODE_UP KEYCODE_UP_INDEXED(0) +#define KEYCODE_DOWN KEYCODE_DOWN_INDEXED(0) +#define KEYCODE_0_PAD KEYCODE_0_PAD_INDEXED(0) +#define KEYCODE_1_PAD KEYCODE_1_PAD_INDEXED(0) +#define KEYCODE_2_PAD KEYCODE_2_PAD_INDEXED(0) +#define KEYCODE_3_PAD KEYCODE_3_PAD_INDEXED(0) +#define KEYCODE_4_PAD KEYCODE_4_PAD_INDEXED(0) +#define KEYCODE_5_PAD KEYCODE_5_PAD_INDEXED(0) +#define KEYCODE_6_PAD KEYCODE_6_PAD_INDEXED(0) +#define KEYCODE_7_PAD KEYCODE_7_PAD_INDEXED(0) +#define KEYCODE_8_PAD KEYCODE_8_PAD_INDEXED(0) +#define KEYCODE_9_PAD KEYCODE_9_PAD_INDEXED(0) +#define KEYCODE_SLASH_PAD KEYCODE_SLASH_PAD_INDEXED(0) +#define KEYCODE_ASTERISK KEYCODE_ASTERISK_INDEXED(0) +#define KEYCODE_MINUS_PAD KEYCODE_MINUS_PAD_INDEXED(0) +#define KEYCODE_PLUS_PAD KEYCODE_PLUS_PAD_INDEXED(0) +#define KEYCODE_DEL_PAD KEYCODE_DEL_PAD_INDEXED(0) +#define KEYCODE_ENTER_PAD KEYCODE_ENTER_PAD_INDEXED(0) +#define KEYCODE_BS_PAD KEYCODE_BS_PAD_INDEXED(0) +#define KEYCODE_TAB_PAD KEYCODE_TAB_PAD_INDEXED(0) +#define KEYCODE_00_PAD KEYCODE_00_PAD_INDEXED(0) +#define KEYCODE_000_PAD KEYCODE_000_PAD_INDEXED(0) +#define KEYCODE_COMMA_PAD KEYCODE_COMMA_PAD_INDEXED(0) +#define KEYCODE_EQUALS_PAD KEYCODE_EQUALS_PAD_INDEXED(0) +#define KEYCODE_PRTSCR KEYCODE_PRTSCR_INDEXED(0) +#define KEYCODE_PAUSE KEYCODE_PAUSE_INDEXED(0) +#define KEYCODE_LSHIFT KEYCODE_LSHIFT_INDEXED(0) +#define KEYCODE_RSHIFT KEYCODE_RSHIFT_INDEXED(0) +#define KEYCODE_LCONTROL KEYCODE_LCONTROL_INDEXED(0) +#define KEYCODE_RCONTROL KEYCODE_RCONTROL_INDEXED(0) +#define KEYCODE_LALT KEYCODE_LALT_INDEXED(0) +#define KEYCODE_RALT KEYCODE_RALT_INDEXED(0) +#define KEYCODE_SCRLOCK KEYCODE_SCRLOCK_INDEXED(0) +#define KEYCODE_NUMLOCK KEYCODE_NUMLOCK_INDEXED(0) +#define KEYCODE_CAPSLOCK KEYCODE_CAPSLOCK_INDEXED(0) +#define KEYCODE_LWIN KEYCODE_LWIN_INDEXED(0) +#define KEYCODE_RWIN KEYCODE_RWIN_INDEXED(0) +#define KEYCODE_MENU KEYCODE_MENU_INDEXED(0) +#define KEYCODE_CANCEL KEYCODE_CANCEL_INDEXED(0) + +// mouse axes as relative devices +constexpr input_code MOUSECODE_X_INDEXED(int n) { return input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_RELATIVE, ITEM_MODIFIER_NONE, ITEM_ID_XAXIS); } +constexpr input_code MOUSECODE_Y_INDEXED(int n) { return input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_RELATIVE, ITEM_MODIFIER_NONE, ITEM_ID_YAXIS); } +constexpr input_code MOUSECODE_Z_INDEXED(int n) { return input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_RELATIVE, ITEM_MODIFIER_NONE, ITEM_ID_ZAXIS); } + +#define MOUSECODE_X MOUSECODE_X_INDEXED(0) +#define MOUSECODE_Y MOUSECODE_Y_INDEXED(0) +#define MOUSECODE_Z MOUSECODE_Z_INDEXED(0) + +// mouse axes as switches in +/- direction +constexpr input_code MOUSECODE_X_POS_SWITCH_INDEXED(int n) { return input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, ITEM_ID_XAXIS); } +constexpr input_code MOUSECODE_X_NEG_SWITCH_INDEXED(int n) { return input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, ITEM_ID_XAXIS); } +constexpr input_code MOUSECODE_Y_POS_SWITCH_INDEXED(int n) { return input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, ITEM_ID_YAXIS); } +constexpr input_code MOUSECODE_Y_NEG_SWITCH_INDEXED(int n) { return input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, ITEM_ID_YAXIS); } +constexpr input_code MOUSECODE_Z_POS_SWITCH_INDEXED(int n) { return input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, ITEM_ID_ZAXIS); } +constexpr input_code MOUSECODE_Z_NEG_SWITCH_INDEXED(int n) { return input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, ITEM_ID_ZAXIS); } + +#define MOUSECODE_X_POS_SWITCH MOUSECODE_X_POS_SWITCH_INDEXED(0) +#define MOUSECODE_X_NEG_SWITCH MOUSECODE_X_NEG_SWITCH_INDEXED(0) +#define MOUSECODE_Y_POS_SWITCH MOUSECODE_Y_POS_SWITCH_INDEXED(0) +#define MOUSECODE_Y_NEG_SWITCH MOUSECODE_Y_NEG_SWITCH_INDEXED(0) +#define MOUSECODE_Z_POS_SWITCH MOUSECODE_Z_POS_SWITCH_INDEXED(0) +#define MOUSECODE_Z_NEG_SWITCH MOUSECODE_Z_NEG_SWITCH_INDEXED(0) + +// mouse buttons +constexpr input_code MOUSECODE_BUTTON1_INDEXED(int n) { return input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON1); } +constexpr input_code MOUSECODE_BUTTON2_INDEXED(int n) { return input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON2); } +constexpr input_code MOUSECODE_BUTTON3_INDEXED(int n) { return input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON3); } +constexpr input_code MOUSECODE_BUTTON4_INDEXED(int n) { return input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON4); } +constexpr input_code MOUSECODE_BUTTON5_INDEXED(int n) { return input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON5); } +constexpr input_code MOUSECODE_BUTTON6_INDEXED(int n) { return input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON6); } +constexpr input_code MOUSECODE_BUTTON7_INDEXED(int n) { return input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON7); } +constexpr input_code MOUSECODE_BUTTON8_INDEXED(int n) { return input_code(DEVICE_CLASS_MOUSE, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON8); } + +#define MOUSECODE_BUTTON1 MOUSECODE_BUTTON1_INDEXED(0) +#define MOUSECODE_BUTTON2 MOUSECODE_BUTTON2_INDEXED(0) +#define MOUSECODE_BUTTON3 MOUSECODE_BUTTON3_INDEXED(0) +#define MOUSECODE_BUTTON4 MOUSECODE_BUTTON4_INDEXED(0) +#define MOUSECODE_BUTTON5 MOUSECODE_BUTTON5_INDEXED(0) +#define MOUSECODE_BUTTON6 MOUSECODE_BUTTON6_INDEXED(0) +#define MOUSECODE_BUTTON7 MOUSECODE_BUTTON7_INDEXED(0) +#define MOUSECODE_BUTTON8 MOUSECODE_BUTTON8_INDEXED(0) + +// gun axes as absolute devices +constexpr input_code GUNCODE_X_INDEXED(int n) { return input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_XAXIS); } +constexpr input_code GUNCODE_Y_INDEXED(int n) { return input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_YAXIS); } + +#define GUNCODE_X GUNCODE_X_INDEXED(0) +#define GUNCODE_Y GUNCODE_Y_INDEXED(0) + +// gun buttons +constexpr input_code GUNCODE_BUTTON1_INDEXED(int n) { return input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON1); } +constexpr input_code GUNCODE_BUTTON2_INDEXED(int n) { return input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON2); } +constexpr input_code GUNCODE_BUTTON3_INDEXED(int n) { return input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON3); } +constexpr input_code GUNCODE_BUTTON4_INDEXED(int n) { return input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON4); } +constexpr input_code GUNCODE_BUTTON5_INDEXED(int n) { return input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON5); } +constexpr input_code GUNCODE_BUTTON6_INDEXED(int n) { return input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON6); } +constexpr input_code GUNCODE_BUTTON7_INDEXED(int n) { return input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON7); } +constexpr input_code GUNCODE_BUTTON8_INDEXED(int n) { return input_code(DEVICE_CLASS_LIGHTGUN, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON8); } + +#define GUNCODE_BUTTON1 GUNCODE_BUTTON1_INDEXED(0) +#define GUNCODE_BUTTON2 GUNCODE_BUTTON2_INDEXED(0) +#define GUNCODE_BUTTON3 GUNCODE_BUTTON3_INDEXED(0) +#define GUNCODE_BUTTON4 GUNCODE_BUTTON4_INDEXED(0) +#define GUNCODE_BUTTON5 GUNCODE_BUTTON5_INDEXED(0) +#define GUNCODE_BUTTON6 GUNCODE_BUTTON6_INDEXED(0) +#define GUNCODE_BUTTON7 GUNCODE_BUTTON7_INDEXED(0) +#define GUNCODE_BUTTON8 GUNCODE_BUTTON8_INDEXED(0) + +// joystick axes as absolute devices +constexpr input_code JOYCODE_X_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_XAXIS); } +constexpr input_code JOYCODE_Y_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_YAXIS); } +constexpr input_code JOYCODE_Z_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_ZAXIS); } +constexpr input_code JOYCODE_U_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_RXAXIS); } +constexpr input_code JOYCODE_V_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_RYAXIS); } +constexpr input_code JOYCODE_W_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NONE, ITEM_ID_RZAXIS); } + +#define JOYCODE_X JOYCODE_X_INDEXED(0) +#define JOYCODE_Y JOYCODE_Y_INDEXED(0) +#define JOYCODE_Z JOYCODE_Z_INDEXED(0) +#define JOYCODE_U JOYCODE_U_INDEXED(0) +#define JOYCODE_V JOYCODE_V_INDEXED(0) +#define JOYCODE_W JOYCODE_W_INDEXED(0) + +// joystick axes as absolute half-axes +constexpr input_code JOYCODE_X_POS_ABSOLUTE_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_POS, ITEM_ID_XAXIS); } +constexpr input_code JOYCODE_X_NEG_ABSOLUTE_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, ITEM_ID_XAXIS); } +constexpr input_code JOYCODE_Y_POS_ABSOLUTE_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_POS, ITEM_ID_YAXIS); } +constexpr input_code JOYCODE_Y_NEG_ABSOLUTE_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, ITEM_ID_YAXIS); } +constexpr input_code JOYCODE_Z_POS_ABSOLUTE_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_POS, ITEM_ID_ZAXIS); } +constexpr input_code JOYCODE_Z_NEG_ABSOLUTE_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, ITEM_ID_ZAXIS); } +constexpr input_code JOYCODE_U_POS_ABSOLUTE_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_POS, ITEM_ID_RXAXIS); } +constexpr input_code JOYCODE_U_NEG_ABSOLUTE_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, ITEM_ID_RXAXIS); } +constexpr input_code JOYCODE_V_POS_ABSOLUTE_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_POS, ITEM_ID_RYAXIS); } +constexpr input_code JOYCODE_V_NEG_ABSOLUTE_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, ITEM_ID_RYAXIS); } +constexpr input_code JOYCODE_W_POS_ABSOLUTE_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_POS, ITEM_ID_RZAXIS); } +constexpr input_code JOYCODE_W_NEG_ABSOLUTE_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_ABSOLUTE, ITEM_MODIFIER_NEG, ITEM_ID_RZAXIS); } + +#define JOYCODE_X_POS_ABSOLUTE JOYCODE_X_POS_ABSOLUTE_INDEXED(0) +#define JOYCODE_X_NEG_ABSOLUTE JOYCODE_X_NEG_ABSOLUTE_INDEXED(0) +#define JOYCODE_Y_POS_ABSOLUTE JOYCODE_Y_POS_ABSOLUTE_INDEXED(0) +#define JOYCODE_Y_NEG_ABSOLUTE JOYCODE_Y_NEG_ABSOLUTE_INDEXED(0) +#define JOYCODE_Z_POS_ABSOLUTE JOYCODE_Z_POS_ABSOLUTE_INDEXED(0) +#define JOYCODE_Z_NEG_ABSOLUTE JOYCODE_Z_NEG_ABSOLUTE_INDEXED(0) +#define JOYCODE_U_POS_ABSOLUTE JOYCODE_U_POS_ABSOLUTE_INDEXED(0) +#define JOYCODE_U_NEG_ABSOLUTE JOYCODE_U_NEG_ABSOLUTE_INDEXED(0) +#define JOYCODE_V_POS_ABSOLUTE JOYCODE_V_POS_ABSOLUTE_INDEXED(0) +#define JOYCODE_V_NEG_ABSOLUTE JOYCODE_V_NEG_ABSOLUTE_INDEXED(0) +#define JOYCODE_W_POS_ABSOLUTE JOYCODE_W_POS_ABSOLUTE_INDEXED(0) +#define JOYCODE_W_NEG_ABSOLUTE JOYCODE_W_NEG_ABSOLUTE_INDEXED(0) + +// joystick axes as switches; X/Y are specially handled for left/right/up/down mapping +constexpr input_code JOYCODE_X_LEFT_SWITCH_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_LEFT, ITEM_ID_XAXIS); } +constexpr input_code JOYCODE_X_RIGHT_SWITCH_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_RIGHT, ITEM_ID_XAXIS); } +constexpr input_code JOYCODE_Y_UP_SWITCH_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_UP, ITEM_ID_YAXIS); } +constexpr input_code JOYCODE_Y_DOWN_SWITCH_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_DOWN, ITEM_ID_YAXIS); } +constexpr input_code JOYCODE_Z_POS_SWITCH_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, ITEM_ID_ZAXIS); } +constexpr input_code JOYCODE_Z_NEG_SWITCH_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, ITEM_ID_ZAXIS); } +constexpr input_code JOYCODE_U_POS_SWITCH_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, ITEM_ID_RXAXIS); } +constexpr input_code JOYCODE_U_NEG_SWITCH_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, ITEM_ID_RXAXIS); } +constexpr input_code JOYCODE_V_POS_SWITCH_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, ITEM_ID_RYAXIS); } +constexpr input_code JOYCODE_V_NEG_SWITCH_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, ITEM_ID_RYAXIS); } +constexpr input_code JOYCODE_W_POS_SWITCH_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_POS, ITEM_ID_RZAXIS); } +constexpr input_code JOYCODE_W_NEG_SWITCH_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NEG, ITEM_ID_RZAXIS); } + +#define JOYCODE_X_LEFT_SWITCH JOYCODE_X_LEFT_SWITCH_INDEXED(0) +#define JOYCODE_X_RIGHT_SWITCH JOYCODE_X_RIGHT_SWITCH_INDEXED(0) +#define JOYCODE_Y_UP_SWITCH JOYCODE_Y_UP_SWITCH_INDEXED(0) +#define JOYCODE_Y_DOWN_SWITCH JOYCODE_Y_DOWN_SWITCH_INDEXED(0) +#define JOYCODE_Z_POS_SWITCH JOYCODE_Z_POS_SWITCH_INDEXED(0) +#define JOYCODE_Z_NEG_SWITCH JOYCODE_Z_NEG_SWITCH_INDEXED(0) +#define JOYCODE_U_POS_SWITCH JOYCODE_U_POS_SWITCH_INDEXED(0) +#define JOYCODE_U_NEG_SWITCH JOYCODE_U_NEG_SWITCH_INDEXED(0) +#define JOYCODE_V_POS_SWITCH JOYCODE_V_POS_SWITCH_INDEXED(0) +#define JOYCODE_V_NEG_SWITCH JOYCODE_V_NEG_SWITCH_INDEXED(0) +#define JOYCODE_W_POS_SWITCH JOYCODE_W_POS_SWITCH_INDEXED(0) +#define JOYCODE_W_NEG_SWITCH JOYCODE_W_NEG_SWITCH_INDEXED(0) + +// joystick buttons +constexpr input_code JOYCODE_BUTTON1_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON1); } +constexpr input_code JOYCODE_BUTTON2_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON2); } +constexpr input_code JOYCODE_BUTTON3_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON3); } +constexpr input_code JOYCODE_BUTTON4_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON4); } +constexpr input_code JOYCODE_BUTTON5_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON5); } +constexpr input_code JOYCODE_BUTTON6_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON6); } +constexpr input_code JOYCODE_BUTTON7_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON7); } +constexpr input_code JOYCODE_BUTTON8_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON8); } +constexpr input_code JOYCODE_BUTTON9_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON9); } +constexpr input_code JOYCODE_BUTTON10_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON10); } +constexpr input_code JOYCODE_BUTTON11_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON11); } +constexpr input_code JOYCODE_BUTTON12_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON12); } +constexpr input_code JOYCODE_BUTTON13_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON13); } +constexpr input_code JOYCODE_BUTTON14_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON14); } +constexpr input_code JOYCODE_BUTTON15_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON15); } +constexpr input_code JOYCODE_BUTTON16_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON16); } +constexpr input_code JOYCODE_BUTTON17_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON17); } +constexpr input_code JOYCODE_BUTTON18_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON18); } +constexpr input_code JOYCODE_BUTTON19_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON19); } +constexpr input_code JOYCODE_BUTTON20_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON20); } +constexpr input_code JOYCODE_BUTTON21_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON21); } +constexpr input_code JOYCODE_BUTTON22_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON22); } +constexpr input_code JOYCODE_BUTTON23_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON23); } +constexpr input_code JOYCODE_BUTTON24_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON24); } +constexpr input_code JOYCODE_BUTTON25_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON25); } +constexpr input_code JOYCODE_BUTTON26_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON26); } +constexpr input_code JOYCODE_BUTTON27_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON27); } +constexpr input_code JOYCODE_BUTTON28_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON28); } +constexpr input_code JOYCODE_BUTTON29_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON29); } +constexpr input_code JOYCODE_BUTTON30_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON30); } +constexpr input_code JOYCODE_BUTTON31_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON31); } +constexpr input_code JOYCODE_BUTTON32_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_BUTTON32); } +constexpr input_code JOYCODE_START_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_START); } +constexpr input_code JOYCODE_SELECT_INDEXED(int n) { return input_code(DEVICE_CLASS_JOYSTICK, n, ITEM_CLASS_SWITCH, ITEM_MODIFIER_NONE, ITEM_ID_SELECT); } + +#define JOYCODE_BUTTON1 JOYCODE_BUTTON1_INDEXED(0) +#define JOYCODE_BUTTON2 JOYCODE_BUTTON2_INDEXED(0) +#define JOYCODE_BUTTON3 JOYCODE_BUTTON3_INDEXED(0) +#define JOYCODE_BUTTON4 JOYCODE_BUTTON4_INDEXED(0) +#define JOYCODE_BUTTON5 JOYCODE_BUTTON5_INDEXED(0) +#define JOYCODE_BUTTON6 JOYCODE_BUTTON6_INDEXED(0) +#define JOYCODE_BUTTON7 JOYCODE_BUTTON7_INDEXED(0) +#define JOYCODE_BUTTON8 JOYCODE_BUTTON8_INDEXED(0) +#define JOYCODE_BUTTON9 JOYCODE_BUTTON9_INDEXED(0) +#define JOYCODE_BUTTON10 JOYCODE_BUTTON10_INDEXED(0) +#define JOYCODE_BUTTON11 JOYCODE_BUTTON11_INDEXED(0) +#define JOYCODE_BUTTON12 JOYCODE_BUTTON12_INDEXED(0) +#define JOYCODE_BUTTON13 JOYCODE_BUTTON13_INDEXED(0) +#define JOYCODE_BUTTON14 JOYCODE_BUTTON14_INDEXED(0) +#define JOYCODE_BUTTON15 JOYCODE_BUTTON15_INDEXED(0) +#define JOYCODE_BUTTON16 JOYCODE_BUTTON16_INDEXED(0) +#define JOYCODE_BUTTON17 JOYCODE_BUTTON17_INDEXED(0) +#define JOYCODE_BUTTON18 JOYCODE_BUTTON18_INDEXED(0) +#define JOYCODE_BUTTON19 JOYCODE_BUTTON19_INDEXED(0) +#define JOYCODE_BUTTON20 JOYCODE_BUTTON20_INDEXED(0) +#define JOYCODE_BUTTON21 JOYCODE_BUTTON21_INDEXED(0) +#define JOYCODE_BUTTON22 JOYCODE_BUTTON22_INDEXED(0) +#define JOYCODE_BUTTON23 JOYCODE_BUTTON23_INDEXED(0) +#define JOYCODE_BUTTON24 JOYCODE_BUTTON24_INDEXED(0) +#define JOYCODE_BUTTON25 JOYCODE_BUTTON25_INDEXED(0) +#define JOYCODE_BUTTON26 JOYCODE_BUTTON26_INDEXED(0) +#define JOYCODE_BUTTON27 JOYCODE_BUTTON27_INDEXED(0) +#define JOYCODE_BUTTON28 JOYCODE_BUTTON28_INDEXED(0) +#define JOYCODE_BUTTON29 JOYCODE_BUTTON29_INDEXED(0) +#define JOYCODE_BUTTON30 JOYCODE_BUTTON30_INDEXED(0) +#define JOYCODE_BUTTON31 JOYCODE_BUTTON31_INDEXED(0) +#define JOYCODE_BUTTON32 JOYCODE_BUTTON32_INDEXED(0) +#define JOYCODE_START JOYCODE_START_INDEXED(0) +#define JOYCODE_SELECT JOYCODE_SELECT_INDEXED(0) + + +#endif // MAME_OSD_INTERFACE_INPUTCODE_H diff --git a/src/osd/interface/inputman.h b/src/osd/interface/inputman.h new file mode 100644 index 00000000000..223c9a6926d --- /dev/null +++ b/src/osd/interface/inputman.h @@ -0,0 +1,77 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + inputman.h + + OSD interface to the input manager. + +***************************************************************************/ +#ifndef MAME_OSD_INTERFACE_INPUTMAN_H +#define MAME_OSD_INTERFACE_INPUTMAN_H + +#pragma once + +#include "inputcode.h" + +#include + + +namespace osd { + +//************************************************************************** +// CONSTANTS +//************************************************************************** + +// relative devices return ~512 units per on-screen pixel +constexpr s32 INPUT_RELATIVE_PER_PIXEL = 512; + +// absolute devices return values between -65536 and +65536 +constexpr s32 INPUT_ABSOLUTE_MIN = -65'536; +constexpr s32 INPUT_ABSOLUTE_MAX = 65'536; + +// invalid memory value for axis polling +constexpr s32 INVALID_AXIS_VALUE = 0x7fff'ffff; + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// base for application representation of host input device + +class input_device +{ +public: + // callback for getting the value of an individual input on a device + typedef s32 (*item_get_state_func)(void *device_internal, void *item_internal); + + virtual ~input_device() = default; + + virtual input_item_id add_item( + std::string_view name, + input_item_id itemid, + item_get_state_func getstate, + void *internal = nullptr) = 0; +}; + + +// base for application input manager + +class input_manager +{ +public: + virtual ~input_manager() = default; + + virtual input_device &add_device( + input_device_class devclass, + std::string_view name, + std::string_view id, + void *internal = nullptr) = 0; +}; + + +} // namespace osd + +#endif // MAME_OSD_INTERFACE_INPUTMAN_H diff --git a/src/osd/interface/inputseq.cpp b/src/osd/interface/inputseq.cpp new file mode 100644 index 00000000000..da1f2b98b26 --- /dev/null +++ b/src/osd/interface/inputseq.cpp @@ -0,0 +1,210 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + inputseq.cpp + + A combination of hosts inputs that can be assigned to a control. + +***************************************************************************/ + +#include "inputseq.h" + + +namespace osd { + +//************************************************************************** +// CONSTANTS +//************************************************************************** + +// additional expanded input codes for sequences +constexpr input_code input_seq::end_code; +constexpr input_code input_seq::default_code; +constexpr input_code input_seq::not_code; +constexpr input_code input_seq::or_code; + +// constant sequences +const input_seq input_seq::empty_seq; + + + +//************************************************************************** +// INPUT SEQ +//************************************************************************** + +//------------------------------------------------- +// operator+= - append a code to the end of an +// input sequence +//------------------------------------------------- + +input_seq &input_seq::operator+=(input_code code) noexcept +{ + // if not enough room, return false + const int curlength = length(); + if (curlength < m_code.size()) + { + m_code[curlength] = code; + if ((curlength + 1) < m_code.size()) + m_code[curlength + 1] = end_code; + } + return *this; +} + + +//------------------------------------------------- +// operator|= - append a code to a sequence; if +// the sequence is non-empty, insert an OR +// before the new code +//------------------------------------------------- + +input_seq &input_seq::operator|=(input_code code) noexcept +{ + // overwrite end/default with the new code + if (m_code[0] == default_code) + { + m_code[0] = code; + m_code[1] = end_code; + } + else + { + // otherwise, append an OR token and then the new code + const int curlength = length(); + if ((curlength + 1) < m_code.size()) + { + m_code[curlength] = or_code; + m_code[curlength + 1] = code; + if ((curlength + 2) < m_code.size()) + m_code[curlength + 2] = end_code; + } + } + return *this; +} + + +//------------------------------------------------- +// length - return the length of the sequence +//------------------------------------------------- + +int input_seq::length() const noexcept +{ + // find the end token; error if none found + for (int seqnum = 0; seqnum < m_code.size(); seqnum++) + if (m_code[seqnum] == end_code) + return seqnum; + return m_code.size(); +} + + +//------------------------------------------------- +// is_valid - return true if a given sequence is +// valid +//------------------------------------------------- + +bool input_seq::is_valid() const noexcept +{ + // "default" can only be of length 1 + if (m_code[0] == default_code) + return m_code[1] == end_code; + + // scan the sequence for valid codes + input_item_class lastclass = ITEM_CLASS_INVALID; + input_code lastcode = INPUT_CODE_INVALID; + decltype(m_code) positive_codes; + decltype(m_code) negative_codes; + auto positive_codes_end = positive_codes.begin(); + auto negative_codes_end = negative_codes.begin(); + for (input_code code : m_code) + { + // invalid codes are never permitted + if (code == INPUT_CODE_INVALID) + return false; + + // if we hit an OR or the end, validate the previous chunk + if (code == or_code || code == end_code) + { + // must be at least one positive code + if (positive_codes.begin() == positive_codes_end) + return false; + + // last code must not have been an internal code + if (lastcode.internal()) + return false; + + // if this is the end, we're ok + if (code == end_code) + return true; + + // reset the state for the next chunk + positive_codes_end = positive_codes.begin(); + negative_codes_end = negative_codes.begin(); + lastclass = ITEM_CLASS_INVALID; + } + else if (code == not_code) + { + // if we hit a NOT, make sure we don't have a double + if (lastcode == not_code) + return false; + } + else + { + // track positive codes, and don't allow positive and negative for the same code + if (lastcode != not_code) + { + *positive_codes_end++ = code; + if (std::find(negative_codes.begin(), negative_codes_end, code) != negative_codes_end) + return false; + } + else + { + *negative_codes_end++ = code; + if (std::find(positive_codes.begin(), positive_codes_end, code) != positive_codes_end) + return false; + } + + // non-switch items can't have a NOT + input_item_class itemclass = code.item_class(); + if (itemclass != ITEM_CLASS_SWITCH && lastcode == not_code) + return false; + + // absolute/relative items must all be the same class + if ((lastclass == ITEM_CLASS_ABSOLUTE && itemclass != ITEM_CLASS_ABSOLUTE) || + (lastclass == ITEM_CLASS_RELATIVE && itemclass != ITEM_CLASS_RELATIVE)) + return false; + } + + // remember the last code + lastcode = code; + } + + // if we got here, we were missing an END token; fail + return false; +} + + +//------------------------------------------------- +// backspace - "backspace" over the last entry in +// a sequence +//------------------------------------------------- + +void input_seq::backspace() noexcept +{ + // if we have at least one entry, remove it + const int curlength = length(); + if (curlength > 0) + m_code[curlength - 1] = end_code; +} + + +//------------------------------------------------- +// replace - replace all instances of oldcode +// with newcode in a sequence +//------------------------------------------------- + +void input_seq::replace(input_code oldcode, input_code newcode) noexcept +{ + for (input_code &elem : m_code) + if (elem == oldcode) + elem = newcode; +} + +} // namespace osd diff --git a/src/osd/interface/inputseq.h b/src/osd/interface/inputseq.h new file mode 100644 index 00000000000..62704462d47 --- /dev/null +++ b/src/osd/interface/inputseq.h @@ -0,0 +1,107 @@ +// license:BSD-3-Clause +// copyright-holders:Aaron Giles +/*************************************************************************** + + inputseq.h + + A combination of hosts inputs that can be assigned to a control. + +***************************************************************************/ +#ifndef MAME_OSD_INTERFACE_INPUTSEQ_H +#define MAME_OSD_INTERFACE_INPUTSEQ_H + +#pragma once + +#include "inputcode.h" + +#include +#include +#include +#include + + +namespace osd { + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// a combination of input_codes, supporting AND/OR and inversion + +class input_seq +{ +public: + // construction/destruction + input_seq() noexcept : input_seq(std::make_index_sequence::value>()) + { + } + template + input_seq(input_code code_0, T... code_n) noexcept : + input_seq(std::make_index_sequence::value - sizeof...(T) - 1>(), code_0, code_n...) + { + } + constexpr input_seq(const input_seq &rhs) noexcept = default; + + // operators + bool operator==(const input_seq &rhs) const noexcept { return m_code == rhs.m_code; } + bool operator!=(const input_seq &rhs) const noexcept { return m_code != rhs.m_code; } + constexpr input_code operator[](int index) const noexcept { return (index >= 0 && index < m_code.size()) ? m_code[index] : end_code; } + input_seq &operator+=(input_code code) noexcept; + input_seq &operator|=(input_code code) noexcept; + + // getters + constexpr bool empty() const noexcept { return m_code[0] == end_code; } + constexpr int max_size() const noexcept { return std::tuple_size::value; } + int length() const noexcept; + bool is_valid() const noexcept; + constexpr bool is_default() const noexcept { return m_code[0] == default_code; } + + // setters + template void set(input_code code_0, T... code_n) noexcept + { + static_assert(sizeof...(T) < std::tuple_size::value, "too many codes for input_seq"); + set<0>(code_0, code_n...); + } + void reset() noexcept { set(end_code); } + void set_default() noexcept { set(default_code); } + void backspace() noexcept; + void replace(input_code oldcode, input_code newcode) noexcept; + + // constant codes used in sequences + static constexpr input_code end_code { DEVICE_CLASS_INTERNAL, 0, ITEM_CLASS_INVALID, ITEM_MODIFIER_NONE, ITEM_ID_SEQ_END }; + static constexpr input_code default_code { DEVICE_CLASS_INTERNAL, 0, ITEM_CLASS_INVALID, ITEM_MODIFIER_NONE, ITEM_ID_SEQ_DEFAULT }; + static constexpr input_code not_code { DEVICE_CLASS_INTERNAL, 0, ITEM_CLASS_INVALID, ITEM_MODIFIER_NONE, ITEM_ID_SEQ_NOT }; + static constexpr input_code or_code { DEVICE_CLASS_INTERNAL, 0, ITEM_CLASS_INVALID, ITEM_MODIFIER_NONE, ITEM_ID_SEQ_OR }; + + // constant sequences + static const input_seq empty_seq; + +private: + static constexpr input_code get_end_code(size_t) noexcept { return end_code; } + + template + input_seq(std::integer_sequence, T... code) noexcept : m_code({ code..., get_end_code(N)... }) + { + } + template + input_seq(std::integer_sequence) noexcept : m_code({ get_end_code(N)... }) + { + } + + template void set() noexcept + { + std::fill(std::next(m_code.begin(), N), m_code.end(), end_code); + } + template void set(input_code code_0, T... code_n) noexcept + { + m_code[N] = code_0; + set(code_n...); + } + + // internal state + std::array m_code; +}; + +} // namespace osd + +#endif // MAME_OSD_INTERFACE_INPUTSEQ_H diff --git a/src/osd/modules/input/input_common.cpp b/src/osd/modules/input/input_common.cpp index bb596295ea9..7127a7878fa 100644 --- a/src/osd/modules/input/input_common.cpp +++ b/src/osd/modules/input/input_common.cpp @@ -14,6 +14,8 @@ #include "emu.h" #include "input_common.h" +#include "inputdev.h" // FIXME: still using concrete input device class in input_module_base::poll + // winnt.h defines this #ifdef DELETE #undef DELETE @@ -277,3 +279,46 @@ int input_module_base::init(const osd_options &options) return 0; } + +void input_module_base::poll(running_machine &machine) +{ + // ignore if not enabled + if (m_input_enabled) + { + // grab the current time + m_last_poll = m_clock.now(); + + before_poll(machine); + + // track if mouse/lightgun is enabled, for mouse hiding purposes + m_mouse_enabled = machine.input().device_class(DEVICE_CLASS_MOUSE).enabled(); + m_lightgun_enabled = machine.input().device_class(DEVICE_CLASS_LIGHTGUN).enabled(); + } + + // poll all of the devices + if (should_poll_devices(machine)) + { + m_devicelist.poll_devices(); + } + else + { + m_devicelist.reset_devices(); + } +} + +void input_module_base::pause() +{ + // keep track of the paused state + m_input_paused = true; +} + +void input_module_base::resume() +{ + // keep track of the paused state + m_input_paused = false; +} + +void input_module_base::exit() +{ + devicelist().free_all_devices(); +} diff --git a/src/osd/modules/input/input_common.h b/src/osd/modules/input/input_common.h index c030d8f17b2..e220445c266 100644 --- a/src/osd/modules/input/input_common.h +++ b/src/osd/modules/input/input_common.h @@ -14,7 +14,7 @@ #include "input_module.h" -#include "inputdev.h" +#include "interface/inputman.h" #include #include @@ -204,7 +204,7 @@ class device_info private: const std::string m_name; const std::string m_id; - input_device * m_device; + osd::input_device * m_device; running_machine & m_machine; input_module & m_module; input_device_class m_deviceclass; @@ -228,7 +228,7 @@ public: running_machine & machine() const { return m_machine; } const std::string & name() const { return m_name; } const std::string & id() const { return m_id; } - input_device * device() const { return m_device; } + osd::input_device * device() const { return m_device; } input_module & module() const { return m_module; } input_device_class deviceclass() const { return m_deviceclass; } @@ -255,8 +255,8 @@ protected: virtual void process_event(TEvent &ev) = 0; public: - event_based_device(running_machine &machine, std::string &&name, std::string &&id, input_device_class deviceclass, input_module &module) - : device_info(machine, std::move(name), std::move(id), deviceclass, module) + event_based_device(running_machine &machine, std::string &&name, std::string &&id, input_device_class deviceclass, input_module &module) : + device_info(machine, std::move(name), std::move(id), deviceclass, module) { } @@ -338,14 +338,14 @@ public: // allocate the device object auto devinfo = std::make_unique(machine, std::move(name), std::move(id), module, std::forward(args)...); - return add_device(machine, std::move(devinfo)); + return add_device(machine.input(), std::move(devinfo)); } template - TActual &add_device(running_machine &machine, std::unique_ptr &&devinfo) + TActual &add_device(osd::input_manager &manager, std::unique_ptr &&devinfo) { // Add the device to the machine - devinfo->m_device = &machine.input().device_class(devinfo->deviceclass()).add_device(devinfo->name(), devinfo->id(), devinfo.get()); + devinfo->m_device = &manager.add_device(devinfo->deviceclass(), devinfo->name(), devinfo->id(), devinfo.get()); // append us to the list return *static_cast(m_list.emplace_back(std::move(devinfo)).get()); @@ -453,9 +453,9 @@ public: bool mouse_enabled() const { return m_mouse_enabled; } bool lightgun_enabled() const { return m_lightgun_enabled; } - int init(const osd_options &options) override; + virtual int init(const osd_options &options) override; - void poll_if_necessary(running_machine &machine) override + virtual void poll_if_necessary(running_machine &machine) override { auto elapsed = std::chrono::duration_cast(m_clock.now() - m_last_poll); if (elapsed.count() >= MIN_POLLING_INTERVAL) @@ -464,51 +464,13 @@ public: } } - virtual void poll(running_machine &machine) - { - // ignore if not enabled - if (m_input_enabled) - { - // grab the current time - m_last_poll = m_clock.now(); - - before_poll(machine); - - // track if mouse/lightgun is enabled, for mouse hiding purposes - m_mouse_enabled = machine.input().device_class(DEVICE_CLASS_MOUSE).enabled(); - m_lightgun_enabled = machine.input().device_class(DEVICE_CLASS_LIGHTGUN).enabled(); - } - - // poll all of the devices - if (should_poll_devices(machine)) - { - m_devicelist.poll_devices(); - } - else - { - m_devicelist.reset_devices(); - } - } - - virtual void pause() override - { - // keep track of the paused state - m_input_paused = true; - } - - virtual void resume() override - { - // keep track of the paused state - m_input_paused = false; - } - - virtual void exit() override - { - devicelist().free_all_devices(); - } + virtual void pause() override; + virtual void resume() override; + virtual void exit() override; protected: virtual int init_internal() { return 0; } + virtual void poll(running_machine &machine); virtual bool should_poll_devices(running_machine &machine) = 0; virtual void before_poll(running_machine &machine) { } }; @@ -571,14 +533,14 @@ inline int32_t normalize_absolute_axis(double raw, double rawmin, double rawmax) if (raw >= center) { // above center - double result = (raw - center) * INPUT_ABSOLUTE_MAX / (rawmax - center); - return std::min(result, (double)INPUT_ABSOLUTE_MAX); + double result = (raw - center) * osd::INPUT_ABSOLUTE_MAX / (rawmax - center); + return std::min(result, (double)osd::INPUT_ABSOLUTE_MAX); } else { // below center - double result = -((center - raw) * (double)-INPUT_ABSOLUTE_MIN / (center - rawmin)); - return std::max(result, (double)INPUT_ABSOLUTE_MIN); + double result = -((center - raw) * (double)-osd::INPUT_ABSOLUTE_MIN / (center - rawmin)); + return std::max(result, (double)osd::INPUT_ABSOLUTE_MIN); } } diff --git a/src/osd/modules/input/input_dinput.cpp b/src/osd/modules/input/input_dinput.cpp index fa273e5fdb1..77467f80d59 100644 --- a/src/osd/modules/input/input_dinput.cpp +++ b/src/osd/modules/input/input_dinput.cpp @@ -389,9 +389,9 @@ void dinput_mouse_device::poll() dinput_device::poll_dinput(&mouse); // scale the axis data - mouse.lX *= INPUT_RELATIVE_PER_PIXEL; - mouse.lY *= INPUT_RELATIVE_PER_PIXEL; - mouse.lZ *= INPUT_RELATIVE_PER_PIXEL; + mouse.lX *= osd::INPUT_RELATIVE_PER_PIXEL; + mouse.lY *= osd::INPUT_RELATIVE_PER_PIXEL; + mouse.lZ *= osd::INPUT_RELATIVE_PER_PIXEL; } void dinput_mouse_device::reset() diff --git a/src/osd/modules/input/input_rawinput.cpp b/src/osd/modules/input/input_rawinput.cpp index 8547a967dab..94018f9c404 100644 --- a/src/osd/modules/input/input_rawinput.cpp +++ b/src/osd/modules/input/input_rawinput.cpp @@ -347,12 +347,12 @@ public: if (rawinput.data.mouse.usFlags == MOUSE_MOVE_RELATIVE) { - mouse.lX += rawinput.data.mouse.lLastX * INPUT_RELATIVE_PER_PIXEL; - mouse.lY += rawinput.data.mouse.lLastY * INPUT_RELATIVE_PER_PIXEL; + mouse.lX += rawinput.data.mouse.lLastX * osd::INPUT_RELATIVE_PER_PIXEL; + mouse.lY += rawinput.data.mouse.lLastY * osd::INPUT_RELATIVE_PER_PIXEL; // update zaxis if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_WHEEL) - mouse.lZ += static_cast(rawinput.data.mouse.usButtonData) * INPUT_RELATIVE_PER_PIXEL; + mouse.lZ += static_cast(rawinput.data.mouse.usButtonData) * osd::INPUT_RELATIVE_PER_PIXEL; // update the button states; always update the corresponding mouse buttons if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) mouse.rgbButtons[0] = 0x80; @@ -405,12 +405,12 @@ public: { // update the X/Y positions - lightgun.lX = normalize_absolute_axis(rawinput.data.mouse.lLastX, 0, INPUT_ABSOLUTE_MAX); - lightgun.lY = normalize_absolute_axis(rawinput.data.mouse.lLastY, 0, INPUT_ABSOLUTE_MAX); + lightgun.lX = normalize_absolute_axis(rawinput.data.mouse.lLastX, 0, osd::INPUT_ABSOLUTE_MAX); + lightgun.lY = normalize_absolute_axis(rawinput.data.mouse.lLastY, 0, osd::INPUT_ABSOLUTE_MAX); // update zaxis if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_WHEEL) - lightgun.lZ += static_cast(rawinput.data.mouse.usButtonData) * INPUT_RELATIVE_PER_PIXEL; + lightgun.lZ += static_cast(rawinput.data.mouse.usButtonData) * osd::INPUT_RELATIVE_PER_PIXEL; // update the button states; always update the corresponding mouse buttons if (rawinput.data.mouse.usButtonFlags & RI_MOUSE_BUTTON_1_DOWN) lightgun.rgbButtons[0] = 0x80; diff --git a/src/osd/modules/input/input_sdl.cpp b/src/osd/modules/input/input_sdl.cpp index 73d722525fa..76f8c494f70 100644 --- a/src/osd/modules/input/input_sdl.cpp +++ b/src/osd/modules/input/input_sdl.cpp @@ -526,8 +526,8 @@ public: switch (sdlevent.type) { case SDL_MOUSEMOTION: - mouse.lX += sdlevent.motion.xrel * INPUT_RELATIVE_PER_PIXEL; - mouse.lY += sdlevent.motion.yrel * INPUT_RELATIVE_PER_PIXEL; + mouse.lX += sdlevent.motion.xrel * osd::INPUT_RELATIVE_PER_PIXEL; + mouse.lY += sdlevent.motion.yrel * osd::INPUT_RELATIVE_PER_PIXEL; { int cx = -1, cy = -1; @@ -676,8 +676,8 @@ public: case SDL_JOYBALLMOTION: //printf("Ball %d %d\n", sdlevent.jball.xrel, sdlevent.jball.yrel); - joystick.balls[sdlevent.jball.ball * 2] = sdlevent.jball.xrel * INPUT_RELATIVE_PER_PIXEL; - joystick.balls[sdlevent.jball.ball * 2 + 1] = sdlevent.jball.yrel * INPUT_RELATIVE_PER_PIXEL; + joystick.balls[sdlevent.jball.ball * 2] = sdlevent.jball.xrel * osd::INPUT_RELATIVE_PER_PIXEL; + joystick.balls[sdlevent.jball.ball * 2 + 1] = sdlevent.jball.yrel * osd::INPUT_RELATIVE_PER_PIXEL; break; case SDL_JOYHATMOTION: diff --git a/src/osd/modules/input/input_win32.cpp b/src/osd/modules/input/input_win32.cpp index 17128d7c0d6..459e624fcfa 100644 --- a/src/osd/modules/input/input_win32.cpp +++ b/src/osd/modules/input/input_win32.cpp @@ -149,8 +149,8 @@ public: if (!(cursor_info.flags & CURSOR_SHOWING)) { // We measure the position change from the previously set center position - mouse.lX = (cursor_info.ptScreenPos.x - win32_mouse.last_point.x) * INPUT_RELATIVE_PER_PIXEL; - mouse.lY = (cursor_info.ptScreenPos.y - win32_mouse.last_point.y) * INPUT_RELATIVE_PER_PIXEL; + mouse.lX = (cursor_info.ptScreenPos.x - win32_mouse.last_point.x) * osd::INPUT_RELATIVE_PER_PIXEL; + mouse.lY = (cursor_info.ptScreenPos.y - win32_mouse.last_point.y) * osd::INPUT_RELATIVE_PER_PIXEL; RECT window_pos = {0}; GetWindowRect(std::static_pointer_cast(osd_common_t::s_window_list.front())->platform_window(), &window_pos); diff --git a/src/osd/osdcomm.h b/src/osd/osdcomm.h index 0b372e4e61e..516dd3e681a 100644 --- a/src/osd/osdcomm.h +++ b/src/osd/osdcomm.h @@ -71,6 +71,7 @@ using s64 = std::int64_t; } // namespace OSD + /*************************************************************************** FUNDAMENTAL MACROS ***************************************************************************/ @@ -111,4 +112,25 @@ using ssize_t = std::make_signed_t; #endif #endif + +// macro for defining a copy constructor and assignment operator to prevent copying +#define DISABLE_COPYING(TYPE) \ + TYPE(const TYPE &) = delete; \ + TYPE &operator=(const TYPE &) = delete + +// macro for declaring enumeration operators that increment/decrement like plain old C +#define DECLARE_ENUM_INCDEC_OPERATORS(TYPE) \ +inline TYPE &operator++(TYPE &value) { return value = TYPE(std::underlying_type_t(value) + 1); } \ +inline TYPE &operator--(TYPE &value) { return value = TYPE(std::underlying_type_t(value) - 1); } \ +inline TYPE operator++(TYPE &value, int) { TYPE const old(value); ++value; return old; } \ +inline TYPE operator--(TYPE &value, int) { TYPE const old(value); --value; return old; } + +// macro for declaring bitwise operators for an enumerated type +#define DECLARE_ENUM_BITWISE_OPERATORS(TYPE) \ +constexpr TYPE operator~(TYPE value) { return TYPE(~std::underlying_type_t(value)); } \ +constexpr TYPE operator&(TYPE a, TYPE b) { return TYPE(std::underlying_type_t(a) & std::underlying_type_t(b)); } \ +constexpr TYPE operator|(TYPE a, TYPE b) { return TYPE(std::underlying_type_t(a) | std::underlying_type_t(b)); } \ +inline TYPE &operator&=(TYPE &a, TYPE b) { return a = a & b; } \ +inline TYPE &operator|=(TYPE &a, TYPE b) { return a = a | b; } + #endif // MAME_OSD_OSDCOMM_H -- cgit v1.2.3