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.
This commit is contained in:
Vas Crabb 2022-06-16 03:32:46 +10:00
parent d345b7ec2c
commit 1964365f34
24 changed files with 1608 additions and 1330 deletions

View File

@ -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"),
}

View File

@ -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<TYPE>(value) + 1); } \
inline TYPE &operator--(TYPE &value) { return value = TYPE(std::underlying_type_t<TYPE>(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<TYPE>(value)); } \
constexpr TYPE operator&(TYPE a, TYPE b) { return TYPE(std::underlying_type_t<TYPE>(a) & std::underlying_type_t<TYPE>(b)); } \
constexpr TYPE operator|(TYPE a, TYPE b) { return TYPE(std::underlying_type_t<TYPE>(a) | std::underlying_type_t<TYPE>(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

View File

@ -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)

View File

@ -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 <algorithm>
#include <array>
#include <cassert>
@ -27,468 +31,17 @@
#include <utility>
//**************************************************************************
// 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<std::tuple_size<decltype(m_code)>::value>()) { }
template <typename... T> input_seq(input_code code_0, T... code_n) noexcept : input_seq(std::make_index_sequence<std::tuple_size<decltype(m_code)>::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<decltype(m_code)>::value; }
int length() const noexcept;
bool is_valid() const noexcept;
constexpr bool is_default() const noexcept { return m_code[0] == default_code; }
// setters
template <typename... T> void set(input_code code_0, T... code_n) noexcept
{
static_assert(sizeof...(T) < std::tuple_size<decltype(m_code)>::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 <size_t... N, typename... T> input_seq(std::integer_sequence<size_t, N...>, T... code) noexcept : m_code({ code..., get_end_code(N)... }) { }
template <size_t... N> input_seq(std::integer_sequence<size_t, N...>) noexcept : m_code({ get_end_code(N)... }) { }
template <unsigned N> void set() noexcept
{
std::fill(std::next(m_code.begin(), N), m_code.end(), end_code);
}
template <unsigned N, typename... T> void set(input_code code_0, T... code_n) noexcept
{
m_code[N] = code_0;
set<N + 1>(code_n...);
}
// internal state
std::array<input_code, 16> 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

View File

@ -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);
}

View File

@ -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); }

View File

@ -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);

View File

@ -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 &timeslice_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<emu_timer> 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)
prevtimer->m_next = &timer;
else
m_timer_list = &timer;
timer.m_prev = prevtimer;
timer.m_next = nullptr;
}
// need to insert after the last one
if (prevtimer != nullptr)
prevtimer->m_next = &timer;
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());
}
}
}

View File

@ -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<emu_timer> m_timer_allocator; // allocator for timers
// other internal states

View File

@ -9,21 +9,22 @@
***************************************************************************/
#include "emu.h"
#include "speaker.h"
#include "emuopts.h"
#include "osdepend.h"
#include "config.h"
#include "wavwrite.h"
#include <vector>
//**************************************************************************
// 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);

View File

@ -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));

View File

@ -13,7 +13,11 @@
#pragma once
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <string_view>
#include <type_traits>
namespace util {
@ -34,6 +38,24 @@ enum class endianness
#endif
};
// helper for accessing data adjusted for endianness
template <typename In, typename Out, endianness Endian>
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<Out *>(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 <typename T, typename U>
auto big_endian_cast(U *ptr)
{
using requested_const = std::conditional_t<std::is_const_v<U>, std::add_const_t<T>, T>;
using requested_cv = std::conditional_t<std::is_volatile_v<U>, std::add_volatile<requested_const>, requested_const>;
return endian_cast<U, requested_cv, endianness::big>(ptr);
}
template <typename T, typename U>
auto little_endian_cast(U *ptr)
{
using requested_const = std::conditional_t<std::is_const_v<U>, std::add_const_t<T>, T>;
using requested_cv = std::conditional_t<std::is_volatile_v<U>, std::add_volatile<requested_const>, requested_const>;
return endian_cast<U, requested_cv, endianness::little>(ptr);
}
// read/write a byte to a 16-bit space
template <typename T> constexpr T BYTE_XOR_BE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(1,0); }
template <typename T> constexpr T BYTE_XOR_LE(T a) { return a ^ NATIVE_ENDIAN_VALUE_LE_BE(0,1); }

View File

@ -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<const uint16_t>(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<const uint16_t>(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);
}

View File

@ -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 <cassert>
//**************************************************************************
// 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

View File

@ -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 <string_view>
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

View File

@ -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

View File

@ -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 <algorithm>
#include <array>
#include <cassert>
#include <utility>
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<std::tuple_size<decltype(m_code)>::value>())
{
}
template <typename... T>
input_seq(input_code code_0, T... code_n) noexcept :
input_seq(std::make_index_sequence<std::tuple_size<decltype(m_code)>::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<decltype(m_code)>::value; }
int length() const noexcept;
bool is_valid() const noexcept;
constexpr bool is_default() const noexcept { return m_code[0] == default_code; }
// setters
template <typename... T> void set(input_code code_0, T... code_n) noexcept
{
static_assert(sizeof...(T) < std::tuple_size<decltype(m_code)>::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 <size_t... N, typename... T>
input_seq(std::integer_sequence<size_t, N...>, T... code) noexcept : m_code({ code..., get_end_code(N)... })
{
}
template <size_t... N>
input_seq(std::integer_sequence<size_t, N...>) noexcept : m_code({ get_end_code(N)... })
{
}
template <unsigned N> void set() noexcept
{
std::fill(std::next(m_code.begin(), N), m_code.end(), end_code);
}
template <unsigned N, typename... T> void set(input_code code_0, T... code_n) noexcept
{
m_code[N] = code_0;
set<N + 1>(code_n...);
}
// internal state
std::array<input_code, 16> m_code;
};
} // namespace osd
#endif // MAME_OSD_INTERFACE_INPUTSEQ_H

View File

@ -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();
}

View File

@ -14,7 +14,7 @@
#include "input_module.h"
#include "inputdev.h"
#include "interface/inputman.h"
#include <algorithm>
#include <chrono>
@ -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<TActual>(machine, std::move(name), std::move(id), module, std::forward<TArgs>(args)...);
return add_device(machine, std::move(devinfo));
return add_device(machine.input(), std::move(devinfo));
}
template <typename TActual>
TActual &add_device(running_machine &machine, std::unique_ptr<TActual> &&devinfo)
TActual &add_device(osd::input_manager &manager, std::unique_ptr<TActual> &&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<TActual *>(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<std::chrono::milliseconds>(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);
}
}

View File

@ -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()

View File

@ -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<int16_t>(rawinput.data.mouse.usButtonData) * INPUT_RELATIVE_PER_PIXEL;
mouse.lZ += static_cast<int16_t>(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<int16_t>(rawinput.data.mouse.usButtonData) * INPUT_RELATIVE_PER_PIXEL;
lightgun.lZ += static_cast<int16_t>(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;

View File

@ -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:

View File

@ -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<win_window_info>(osd_common_t::s_window_list.front())->platform_window(), &window_pos);

View File

@ -71,6 +71,7 @@ using s64 = std::int64_t;
} // namespace OSD
/***************************************************************************
FUNDAMENTAL MACROS
***************************************************************************/
@ -111,4 +112,25 @@ using ssize_t = std::make_signed_t<size_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<TYPE>(value) + 1); } \
inline TYPE &operator--(TYPE &value) { return value = TYPE(std::underlying_type_t<TYPE>(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<TYPE>(value)); } \
constexpr TYPE operator&(TYPE a, TYPE b) { return TYPE(std::underlying_type_t<TYPE>(a) & std::underlying_type_t<TYPE>(b)); } \
constexpr TYPE operator|(TYPE a, TYPE b) { return TYPE(std::underlying_type_t<TYPE>(a) | std::underlying_type_t<TYPE>(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